aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/80211.tmpl495
-rw-r--r--Documentation/DocBook/Makefile2
-rw-r--r--Documentation/DocBook/mac80211.tmpl337
-rw-r--r--Documentation/feature-removal-schedule.txt9
-rw-r--r--Documentation/networking/bonding.txt8
-rw-r--r--Documentation/networking/can.txt12
-rw-r--r--Documentation/networking/dccp.txt29
-rw-r--r--Documentation/networking/ip-sysctl.txt27
-rw-r--r--Documentation/networking/phonet.txt56
-rw-r--r--Documentation/networking/timestamping.txt22
-rw-r--r--MAINTAINERS62
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c2
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c2
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c54
-rw-r--r--arch/s390/include/asm/qdio.h13
-rw-r--r--drivers/atm/Makefile2
-rw-r--r--drivers/atm/firestream.c4
-rw-r--r--drivers/atm/horizon.c6
-rw-r--r--drivers/atm/idt77252.c6
-rw-r--r--drivers/atm/iphase.c2
-rw-r--r--drivers/bluetooth/btmrvl_main.c4
-rw-r--r--drivers/bluetooth/btsdio.c8
-rw-r--r--drivers/bluetooth/btusb.c6
-rw-r--r--drivers/bluetooth/hci_ldisc.c2
-rw-r--r--drivers/firewire/net.c13
-rw-r--r--drivers/ieee1394/eth1394.c16
-rw-r--r--drivers/infiniband/hw/mlx4/Kconfig1
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c4
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c4
-rw-r--r--drivers/isdn/capi/capidrv.c17
-rw-r--r--drivers/isdn/capi/kcapi.c19
-rw-r--r--drivers/isdn/divert/isdn_divert.c6
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c400
-rw-r--r--drivers/isdn/gigaset/common.c26
-rw-r--r--drivers/isdn/gigaset/gigaset.h3
-rw-r--r--drivers/isdn/gigaset/i4l.c2
-rw-r--r--drivers/isdn/gigaset/isocdata.c8
-rw-r--r--drivers/isdn/hardware/eicon/debug.c2
-rw-r--r--drivers/isdn/hardware/eicon/debuglib.h2
-rw-r--r--drivers/isdn/hisax/hfc_sx.c13
-rw-r--r--drivers/isdn/i4l/isdn_tty.c15
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c1
-rw-r--r--drivers/isdn/mISDN/l1oip_core.c2
-rw-r--r--drivers/isdn/mISDN/stack.c7
-rw-r--r--drivers/isdn/pcbit/edss1.c2
-rw-r--r--drivers/isdn/pcbit/edss1.h2
-rw-r--r--drivers/net/3c503.c8
-rw-r--r--drivers/net/3c515.c6
-rw-r--r--drivers/net/3c523.c4
-rw-r--r--drivers/net/3c527.c2
-rw-r--r--drivers/net/3c59x.c2
-rw-r--r--drivers/net/8139cp.c4
-rw-r--r--drivers/net/Kconfig51
-rw-r--r--drivers/net/Makefile3
-rw-r--r--drivers/net/acenic.c2
-rw-r--r--drivers/net/amd8111e.c20
-rw-r--r--drivers/net/amd8111e.h1
-rw-r--r--drivers/net/appletalk/ipddp.c10
-rw-r--r--drivers/net/appletalk/ltpc.c2
-rw-r--r--drivers/net/arm/am79c961a.c35
-rw-r--r--drivers/net/arm/am79c961a.h1
-rw-r--r--drivers/net/arm/ep93xx_eth.c39
-rw-r--r--drivers/net/arm/ether1.c34
-rw-r--r--drivers/net/arm/ether1.h1
-rw-r--r--drivers/net/arm/ether3.c33
-rw-r--r--drivers/net/arm/ether3.h1
-rw-r--r--drivers/net/atarilance.c24
-rw-r--r--drivers/net/atl1c/atl1c.h1
-rw-r--r--drivers/net/atl1c/atl1c_hw.c2
-rw-r--r--drivers/net/atl1c/atl1c_main.c10
-rw-r--r--drivers/net/atl1e/atl1e_main.c6
-rw-r--r--drivers/net/atlx/atl1.c10
-rw-r--r--drivers/net/atlx/atl2.c12
-rw-r--r--drivers/net/atp.c2
-rw-r--r--drivers/net/au1000_eth.c313
-rw-r--r--drivers/net/au1000_eth.h42
-rw-r--r--drivers/net/ax88796.c1
-rw-r--r--drivers/net/b44.c21
-rw-r--r--drivers/net/bcm63xx_enet.c62
-rw-r--r--drivers/net/bcm63xx_enet.h1
-rw-r--r--drivers/net/benet/be.h100
-rw-r--r--drivers/net/benet/be_cmds.c103
-rw-r--r--drivers/net/benet/be_cmds.h65
-rw-r--r--drivers/net/benet/be_ethtool.c177
-rw-r--r--drivers/net/benet/be_main.c644
-rw-r--r--drivers/net/bfin_mac.c10
-rw-r--r--drivers/net/bmac.c9
-rw-r--r--drivers/net/bna/Makefile11
-rw-r--r--drivers/net/bna/bfa_cee.c291
-rw-r--r--drivers/net/bna/bfa_cee.h64
-rw-r--r--drivers/net/bna/bfa_defs.h243
-rw-r--r--drivers/net/bna/bfa_defs_cna.h223
-rw-r--r--drivers/net/bna/bfa_defs_mfg_comm.h244
-rw-r--r--drivers/net/bna/bfa_defs_status.h216
-rw-r--r--drivers/net/bna/bfa_ioc.c1732
-rw-r--r--drivers/net/bna/bfa_ioc.h300
-rw-r--r--drivers/net/bna/bfa_ioc_ct.c392
-rw-r--r--drivers/net/bna/bfa_sm.h88
-rw-r--r--drivers/net/bna/bfa_wc.h69
-rw-r--r--drivers/net/bna/bfi.h392
-rw-r--r--drivers/net/bna/bfi_cna.h199
-rw-r--r--drivers/net/bna/bfi_ctreg.h637
-rw-r--r--drivers/net/bna/bfi_ll.h438
-rw-r--r--drivers/net/bna/bna.h550
-rw-r--r--drivers/net/bna/bna_ctrl.c3261
-rw-r--r--drivers/net/bna/bna_hw.h1490
-rw-r--r--drivers/net/bna/bna_txrx.c4172
-rw-r--r--drivers/net/bna/bna_types.h1128
-rw-r--r--drivers/net/bna/bnad.c3264
-rw-r--r--drivers/net/bna/bnad.h332
-rw-r--r--drivers/net/bna/bnad_ethtool.c1277
-rw-r--r--drivers/net/bna/cna.h81
-rw-r--r--drivers/net/bna/cna_fwimg.c64
-rw-r--r--drivers/net/bnx2.c253
-rw-r--r--drivers/net/bnx2.h25
-rw-r--r--drivers/net/bnx2x/bnx2x.h710
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c1017
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.h593
-rw-r--r--drivers/net/bnx2x/bnx2x_dump.h35
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c432
-rw-r--r--drivers/net/bnx2x/bnx2x_fw_defs.h819
-rw-r--r--drivers/net/bnx2x/bnx2x_fw_file_hdr.h1
-rw-r--r--drivers/net/bnx2x/bnx2x_hsi.h1778
-rw-r--r--drivers/net/bnx2x/bnx2x_init.h44
-rw-r--r--drivers/net/bnx2x/bnx2x_init_ops.h366
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c8871
-rw-r--r--drivers/net/bnx2x/bnx2x_link.h242
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c6024
-rw-r--r--drivers/net/bnx2x/bnx2x_reg.h938
-rw-r--r--drivers/net/bnx2x/bnx2x_stats.c305
-rw-r--r--drivers/net/bnx2x/bnx2x_stats.h8
-rw-r--r--drivers/net/bonding/bond_3ad.c276
-rw-r--r--drivers/net/bonding/bond_main.c181
-rw-r--r--drivers/net/bonding/bond_sysfs.c52
-rw-r--r--drivers/net/bonding/bonding.h34
-rw-r--r--drivers/net/bsd_comp.c2
-rw-r--r--drivers/net/can/mcp251x.c103
-rw-r--r--drivers/net/can/mscan/mpc5xxx_can.c8
-rw-r--r--drivers/net/cassini.c6
-rw-r--r--drivers/net/chelsio/sge.c6
-rw-r--r--drivers/net/chelsio/subr.c2
-rw-r--r--drivers/net/chelsio/vsc7326.c2
-rw-r--r--drivers/net/cnic.c955
-rw-r--r--drivers/net/cnic.h118
-rw-r--r--drivers/net/cnic_defs.h456
-rw-r--r--drivers/net/cnic_if.h23
-rw-r--r--drivers/net/cpmac.c39
-rw-r--r--drivers/net/cxgb3/adapter.h3
-rw-r--r--drivers/net/cxgb3/common.h18
-rw-r--r--drivers/net/cxgb3/cxgb3_defs.h3
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c29
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c11
-rw-r--r--drivers/net/cxgb3/mc5.c38
-rw-r--r--drivers/net/cxgb3/regs.h4
-rw-r--r--drivers/net/cxgb3/sge.c45
-rw-r--r--drivers/net/cxgb3/t3_hw.c204
-rw-r--r--drivers/net/cxgb4/cxgb4.h17
-rw-r--r--drivers/net/cxgb4/cxgb4_main.c167
-rw-r--r--drivers/net/cxgb4/cxgb4_uld.h6
-rw-r--r--drivers/net/cxgb4/l2t.c34
-rw-r--r--drivers/net/cxgb4/l2t.h3
-rw-r--r--drivers/net/cxgb4/sge.c19
-rw-r--r--drivers/net/cxgb4/t4_hw.c332
-rw-r--r--drivers/net/cxgb4/t4_hw.h1
-rw-r--r--drivers/net/cxgb4/t4fw_api.h5
-rw-r--r--drivers/net/cxgb4vf/cxgb4vf_main.c5
-rw-r--r--drivers/net/cxgb4vf/sge.c3
-rw-r--r--drivers/net/cxgb4vf/t4vf_common.h26
-rw-r--r--drivers/net/de620.c2
-rw-r--r--drivers/net/declance.c2
-rw-r--r--drivers/net/defxx.c66
-rw-r--r--drivers/net/dl2k.c2
-rw-r--r--drivers/net/dm9000.c2
-rw-r--r--drivers/net/dnet.c18
-rw-r--r--drivers/net/dummy.c58
-rw-r--r--drivers/net/e100.c4
-rw-r--r--drivers/net/e1000/e1000.h3
-rw-r--r--drivers/net/e1000/e1000_main.c245
-rw-r--r--drivers/net/e1000e/82571.c6
-rw-r--r--drivers/net/e1000e/defines.h2
-rw-r--r--drivers/net/e1000e/e1000.h29
-rw-r--r--drivers/net/e1000e/es2lan.c1
-rw-r--r--drivers/net/e1000e/ethtool.c23
-rw-r--r--drivers/net/e1000e/ich8lan.c2
-rw-r--r--drivers/net/e1000e/netdev.c149
-rw-r--r--drivers/net/e1000e/param.c2
-rw-r--r--drivers/net/eepro.c8
-rw-r--r--drivers/net/ehea/ehea.h2
-rw-r--r--drivers/net/ehea/ehea_main.c53
-rw-r--r--drivers/net/enic/enic.h27
-rw-r--r--drivers/net/enic/enic_main.c415
-rw-r--r--drivers/net/enic/enic_res.c32
-rw-r--r--drivers/net/enic/enic_res.h2
-rw-r--r--drivers/net/enic/vnic_dev.c133
-rw-r--r--drivers/net/enic/vnic_dev.h19
-rw-r--r--drivers/net/enic/vnic_devcmd.h12
-rw-r--r--drivers/net/enic/vnic_enet.h2
-rw-r--r--drivers/net/enic/vnic_intr.c5
-rw-r--r--drivers/net/enic/vnic_resource.h13
-rw-r--r--drivers/net/enic/vnic_rq.c8
-rw-r--r--drivers/net/enic/vnic_rq.h6
-rw-r--r--drivers/net/enic/vnic_rss.h5
-rw-r--r--drivers/net/enic/vnic_vic.c7
-rw-r--r--drivers/net/enic/vnic_wq.c8
-rw-r--r--drivers/net/enic/vnic_wq.h4
-rw-r--r--drivers/net/epic100.c2
-rw-r--r--drivers/net/eth16i.c16
-rw-r--r--drivers/net/ethoc.c6
-rw-r--r--drivers/net/fealnx.c4
-rw-r--r--drivers/net/fec_mpc52xx.c6
-rw-r--r--drivers/net/forcedeth.c19
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c3
-rw-r--r--drivers/net/fsl_pq_mdio.c4
-rw-r--r--drivers/net/gianfar.c26
-rw-r--r--drivers/net/gianfar_ethtool.c6
-rw-r--r--drivers/net/greth.c6
-rw-r--r--drivers/net/hamachi.c2
-rw-r--r--drivers/net/hamradio/bpqether.c2
-rw-r--r--drivers/net/hamradio/hdlcdrv.c2
-rw-r--r--drivers/net/hamradio/scc.c3
-rw-r--r--drivers/net/hp.c8
-rw-r--r--drivers/net/hp100.c6
-rw-r--r--drivers/net/hydra.c13
-rw-r--r--drivers/net/ibm_newemac/core.c6
-rw-r--r--drivers/net/ibm_newemac/core.h6
-rw-r--r--drivers/net/ibmlana.c2
-rw-r--r--drivers/net/ibmveth.c999
-rw-r--r--drivers/net/ibmveth.h59
-rw-r--r--drivers/net/igb/e1000_82575.c18
-rw-r--r--drivers/net/igb/e1000_defines.h31
-rw-r--r--drivers/net/igb/e1000_hw.h2
-rw-r--r--drivers/net/igb/e1000_phy.c206
-rw-r--r--drivers/net/igb/e1000_phy.h2
-rw-r--r--drivers/net/igb/igb.h11
-rw-r--r--drivers/net/igb/igb_ethtool.c52
-rw-r--r--drivers/net/igb/igb_main.c164
-rw-r--r--drivers/net/igbvf/ethtool.c2
-rw-r--r--drivers/net/igbvf/netdev.c11
-rw-r--r--drivers/net/ioc3-eth.c2
-rw-r--r--drivers/net/ipg.c6
-rw-r--r--drivers/net/irda/donauboe.c4
-rw-r--r--drivers/net/irda/irda-usb.c10
-rw-r--r--drivers/net/irda/mcs7780.c2
-rw-r--r--drivers/net/irda/nsc-ircc.c2
-rw-r--r--drivers/net/irda/sir_dev.c2
-rw-r--r--drivers/net/irda/smsc-ircc2.c2
-rw-r--r--drivers/net/irda/stir4200.c2
-rw-r--r--drivers/net/irda/via-ircc.c3
-rw-r--r--drivers/net/irda/via-ircc.h2
-rw-r--r--drivers/net/irda/vlsi_ir.h2
-rw-r--r--drivers/net/iseries_veth.c2
-rw-r--r--drivers/net/ixgb/ixgb_ee.c32
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c2
-rw-r--r--drivers/net/ixgb/ixgb_hw.c14
-rw-r--r--drivers/net/ixgb/ixgb_main.c12
-rw-r--r--drivers/net/ixgbe/ixgbe.h39
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c234
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c50
-rw-r--r--drivers/net/ixgbe/ixgbe_common.h1
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb.c219
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb.h18
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.c67
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.h15
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c69
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.h18
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c428
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c13
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.h1
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c1972
-rw-r--r--drivers/net/ixgbe/ixgbe_mbx.c21
-rw-r--r--drivers/net/ixgbe/ixgbe_mbx.h5
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.c19
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.h10
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h2
-rw-r--r--drivers/net/ixgbevf/ethtool.c153
-rw-r--r--drivers/net/ixgbevf/ixgbevf.h1
-rw-r--r--drivers/net/ixgbevf/ixgbevf_main.c36
-rw-r--r--drivers/net/ixgbevf/mbx.c2
-rw-r--r--drivers/net/ixgbevf/mbx.h2
-rw-r--r--drivers/net/ixgbevf/vf.c2
-rw-r--r--drivers/net/ixgbevf/vf.h2
-rw-r--r--drivers/net/jme.c167
-rw-r--r--drivers/net/jme.h6
-rw-r--r--drivers/net/ll_temac_main.c4
-rw-r--r--drivers/net/loopback.c28
-rw-r--r--drivers/net/lp486e.c2
-rw-r--r--drivers/net/mac8390.c48
-rw-r--r--drivers/net/macb.c2
-rw-r--r--drivers/net/macvlan.c4
-rw-r--r--drivers/net/macvtap.c99
-rw-r--r--drivers/net/meth.c2
-rw-r--r--drivers/net/mlx4/Makefile2
-rw-r--r--drivers/net/mlx4/alloc.c17
-rw-r--r--drivers/net/mlx4/en_ethtool.c173
-rw-r--r--drivers/net/mlx4/en_main.c24
-rw-r--r--drivers/net/mlx4/en_netdev.c31
-rw-r--r--drivers/net/mlx4/en_port.c32
-rw-r--r--drivers/net/mlx4/en_port.h14
-rw-r--r--drivers/net/mlx4/en_rx.c104
-rw-r--r--drivers/net/mlx4/en_selftest.c179
-rw-r--r--drivers/net/mlx4/en_tx.c24
-rw-r--r--drivers/net/mlx4/eq.c44
-rw-r--r--drivers/net/mlx4/fw.c15
-rw-r--r--drivers/net/mlx4/fw.h6
-rw-r--r--drivers/net/mlx4/main.c6
-rw-r--r--drivers/net/mlx4/mlx4_en.h39
-rw-r--r--drivers/net/mlx4/profile.c2
-rw-r--r--drivers/net/mv643xx_eth.c3
-rw-r--r--drivers/net/myri10ge/myri10ge.c49
-rw-r--r--drivers/net/myri_sbus.c2
-rw-r--r--drivers/net/natsemi.c2
-rw-r--r--drivers/net/netconsole.c9
-rw-r--r--drivers/net/netxen/netxen_nic.h23
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c43
-rw-r--r--drivers/net/netxen/netxen_nic_init.c14
-rw-r--r--drivers/net/netxen/netxen_nic_main.c49
-rw-r--r--drivers/net/niu.c133
-rw-r--r--drivers/net/ns83820.c55
-rw-r--r--drivers/net/pasemi_mac.c2
-rw-r--r--drivers/net/pasemi_mac_ethtool.c16
-rw-r--r--drivers/net/pch_gbe/Makefile4
-rw-r--r--drivers/net/pch_gbe/pch_gbe.h659
-rw-r--r--drivers/net/pch_gbe/pch_gbe_api.c245
-rw-r--r--drivers/net/pch_gbe/pch_gbe_api.h36
-rw-r--r--drivers/net/pch_gbe/pch_gbe_ethtool.c585
-rw-r--r--drivers/net/pch_gbe/pch_gbe_main.c2477
-rw-r--r--drivers/net/pch_gbe/pch_gbe_param.c499
-rw-r--r--drivers/net/pch_gbe/pch_gbe_phy.c274
-rw-r--r--drivers/net/pch_gbe/pch_gbe_phy.h37
-rw-r--r--drivers/net/pci-skeleton.c2
-rw-r--r--drivers/net/pcmcia/3c574_cs.c88
-rw-r--r--drivers/net/pcmcia/3c589_cs.c17
-rw-r--r--drivers/net/pcmcia/axnet_cs.c187
-rw-r--r--drivers/net/pcmcia/com20020_cs.c32
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c60
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c26
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c56
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c106
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c105
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c104
-rw-r--r--drivers/net/pcnet32.c4
-rw-r--r--drivers/net/phy/Kconfig1
-rw-r--r--drivers/net/phy/bcm63xx.c2
-rw-r--r--drivers/net/phy/broadcom.c2
-rw-r--r--drivers/net/phy/cicada.c2
-rw-r--r--drivers/net/phy/davicom.c2
-rw-r--r--drivers/net/phy/et1011c.c2
-rw-r--r--drivers/net/phy/icplus.c2
-rw-r--r--drivers/net/phy/lxt.c2
-rw-r--r--drivers/net/phy/marvell.c33
-rw-r--r--drivers/net/phy/micrel.c2
-rw-r--r--drivers/net/phy/national.c2
-rw-r--r--drivers/net/phy/qsemi.c2
-rw-r--r--drivers/net/phy/realtek.c2
-rw-r--r--drivers/net/phy/smsc.c2
-rw-r--r--drivers/net/phy/ste10Xp.c2
-rw-r--r--drivers/net/phy/vitesse.c2
-rw-r--r--drivers/net/plip.c9
-rw-r--r--drivers/net/ppp_generic.c46
-rw-r--r--drivers/net/pppoe.c2
-rw-r--r--drivers/net/pppox.c4
-rw-r--r--drivers/net/pptp.c726
-rw-r--r--drivers/net/ps3_gelic_net.c4
-rw-r--r--drivers/net/ps3_gelic_wireless.c6
-rw-r--r--drivers/net/pxa168_eth.c4
-rw-r--r--drivers/net/qla3xxx.c4
-rw-r--r--drivers/net/qlcnic/qlcnic.h179
-rw-r--r--drivers/net/qlcnic/qlcnic_ctx.c411
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c226
-rw-r--r--drivers/net/qlcnic/qlcnic_hdr.h47
-rw-r--r--drivers/net/qlcnic/qlcnic_hw.c131
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c332
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c1310
-rw-r--r--drivers/net/qlge/qlge_main.c36
-rw-r--r--drivers/net/r6040.c92
-rw-r--r--drivers/net/r8169.c400
-rw-r--r--drivers/net/rrunner.c2
-rw-r--r--drivers/net/s2io.c39
-rw-r--r--drivers/net/s2io.h9
-rw-r--r--drivers/net/sb1250-mac.c2
-rw-r--r--drivers/net/sc92031.c11
-rw-r--r--drivers/net/sfc/Makefile7
-rw-r--r--drivers/net/sfc/efx.c353
-rw-r--r--drivers/net/sfc/efx.h46
-rw-r--r--drivers/net/sfc/ethtool.c181
-rw-r--r--drivers/net/sfc/falcon.c136
-rw-r--r--drivers/net/sfc/falcon_boards.c203
-rw-r--r--drivers/net/sfc/falcon_gmac.c230
-rw-r--r--drivers/net/sfc/falcon_xmac.c2
-rw-r--r--drivers/net/sfc/filter.c454
-rw-r--r--drivers/net/sfc/filter.h189
-rw-r--r--drivers/net/sfc/mac.h2
-rw-r--r--drivers/net/sfc/mcdi.c4
-rw-r--r--drivers/net/sfc/mcdi.h2
-rw-r--r--drivers/net/sfc/mcdi_phy.c3
-rw-r--r--drivers/net/sfc/mdio_10g.c30
-rw-r--r--drivers/net/sfc/net_driver.h117
-rw-r--r--drivers/net/sfc/nic.c199
-rw-r--r--drivers/net/sfc/phy.h18
-rw-r--r--drivers/net/sfc/regs.h14
-rw-r--r--drivers/net/sfc/rx.c73
-rw-r--r--drivers/net/sfc/selftest.c17
-rw-r--r--drivers/net/sfc/siena.c6
-rw-r--r--drivers/net/sfc/tenxpress.c424
-rw-r--r--drivers/net/sfc/tx.c78
-rw-r--r--drivers/net/sfc/txc43128_phy.c560
-rw-r--r--drivers/net/sfc/workarounds.h9
-rw-r--r--drivers/net/sh_eth.c4
-rw-r--r--drivers/net/sis900.c8
-rw-r--r--drivers/net/skfp/cfm.c10
-rw-r--r--drivers/net/skfp/drvfbi.c16
-rw-r--r--drivers/net/skfp/ess.c46
-rw-r--r--drivers/net/skfp/fplustm.c24
-rw-r--r--drivers/net/skfp/hwmtm.c30
-rw-r--r--drivers/net/skfp/hwt.c4
-rw-r--r--drivers/net/skfp/pcmplc.c22
-rw-r--r--drivers/net/skfp/pmf.c62
-rw-r--r--drivers/net/skfp/queue.c2
-rw-r--r--drivers/net/skfp/skfddi.c116
-rw-r--r--drivers/net/skfp/smt.c78
-rw-r--r--drivers/net/skfp/smtdef.c4
-rw-r--r--drivers/net/skfp/smtinit.c2
-rw-r--r--drivers/net/skfp/srf.c2
-rw-r--r--drivers/net/skge.c5
-rw-r--r--drivers/net/sky2.c5
-rw-r--r--drivers/net/slip.c93
-rw-r--r--drivers/net/slip.h9
-rw-r--r--drivers/net/smsc911x.c2
-rw-r--r--drivers/net/spider_net.c4
-rw-r--r--drivers/net/starfire.c10
-rw-r--r--drivers/net/stmmac/Kconfig5
-rw-r--r--drivers/net/stmmac/common.h61
-rw-r--r--drivers/net/stmmac/dwmac100.h2
-rw-r--r--drivers/net/stmmac/dwmac1000.h4
-rw-r--r--drivers/net/stmmac/dwmac1000_core.c36
-rw-r--r--drivers/net/stmmac/dwmac1000_dma.c20
-rw-r--r--drivers/net/stmmac/dwmac100_core.c31
-rw-r--r--drivers/net/stmmac/dwmac100_dma.c20
-rw-r--r--drivers/net/stmmac/dwmac_dma.h16
-rw-r--r--drivers/net/stmmac/dwmac_lib.c22
-rw-r--r--drivers/net/stmmac/enh_desc.c6
-rw-r--r--drivers/net/stmmac/norm_desc.c21
-rw-r--r--drivers/net/stmmac/stmmac.h13
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c63
-rw-r--r--drivers/net/stmmac/stmmac_main.c216
-rw-r--r--drivers/net/stmmac/stmmac_mdio.c26
-rw-r--r--drivers/net/sun3lance.c4
-rw-r--r--drivers/net/sunbmac.c2
-rw-r--r--drivers/net/sundance.c275
-rw-r--r--drivers/net/sungem.c211
-rw-r--r--drivers/net/sungem_phy.c5
-rw-r--r--drivers/net/sunhme.c10
-rw-r--r--drivers/net/sunlance.c2
-rw-r--r--drivers/net/sunqe.c2
-rw-r--r--drivers/net/sunvnet.c50
-rw-r--r--drivers/net/tc35815.c2
-rw-r--r--drivers/net/tehuti.c34
-rw-r--r--drivers/net/tehuti.h1
-rw-r--r--drivers/net/tg3.c734
-rw-r--r--drivers/net/tg3.h73
-rw-r--r--drivers/net/tlan.c10
-rw-r--r--drivers/net/tlan.h8
-rw-r--r--drivers/net/tokenring/proteon.c2
-rw-r--r--drivers/net/tokenring/smctr.c500
-rw-r--r--drivers/net/tokenring/tms380tr.c64
-rw-r--r--drivers/net/tokenring/tmspci.c10
-rw-r--r--drivers/net/tsi108_eth.c2
-rw-r--r--drivers/net/tulip/Kconfig4
-rw-r--r--drivers/net/tulip/de2104x.c3
-rw-r--r--drivers/net/tulip/de4x5.c57
-rw-r--r--drivers/net/tulip/dmfe.c2
-rw-r--r--drivers/net/tulip/interrupt.c77
-rw-r--r--drivers/net/tulip/tulip.h3
-rw-r--r--drivers/net/tulip/tulip_core.c10
-rw-r--r--drivers/net/tulip/uli526x.c4
-rw-r--r--drivers/net/tulip/winbond-840.c2
-rw-r--r--drivers/net/tulip/xircom_cb.c15
-rw-r--r--drivers/net/typhoon.c50
-rw-r--r--drivers/net/usb/Kconfig8
-rw-r--r--drivers/net/usb/Makefile1
-rw-r--r--drivers/net/usb/cx82310_eth.c346
-rw-r--r--drivers/net/usb/hso.c9
-rw-r--r--drivers/net/usb/kaweth.c9
-rw-r--r--drivers/net/usb/sierra_net.c4
-rw-r--r--drivers/net/usb/smsc95xx.c4
-rw-r--r--drivers/net/veth.c2
-rw-r--r--drivers/net/via-velocity.c86
-rw-r--r--drivers/net/via-velocity.h16
-rw-r--r--drivers/net/virtio_net.c14
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c23
-rw-r--r--drivers/net/vmxnet3/vmxnet3_int.h17
-rw-r--r--drivers/net/vxge/vxge-main.c38
-rw-r--r--drivers/net/vxge/vxge-main.h1
-rw-r--r--drivers/net/wan/c101.c2
-rw-r--r--drivers/net/wan/cycx_drv.c14
-rw-r--r--drivers/net/wan/cycx_main.c6
-rw-r--r--drivers/net/wan/dlci.c42
-rw-r--r--drivers/net/wan/hdlc_cisco.c4
-rw-r--r--drivers/net/wan/lapbether.c2
-rw-r--r--drivers/net/wan/lmc/lmc_main.c6
-rw-r--r--drivers/net/wan/n2.c6
-rw-r--r--drivers/net/wan/pc300_drv.c20
-rw-r--r--drivers/net/wan/pc300_tty.c2
-rw-r--r--drivers/net/wan/pci200syn.c2
-rw-r--r--drivers/net/wan/sdla.c108
-rw-r--r--drivers/net/wan/x25_asy.c2
-rw-r--r--drivers/net/wan/z85230.c4
-rw-r--r--drivers/net/wd.c8
-rw-r--r--drivers/net/wimax/i2400m/control.c18
-rw-r--r--drivers/net/wimax/i2400m/driver.c2
-rw-r--r--drivers/net/wimax/i2400m/i2400m-sdio.h1
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h9
-rw-r--r--drivers/net/wimax/i2400m/rx.c2
-rw-r--r--drivers/net/wimax/i2400m/sdio-rx.c2
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/airo.c24
-rw-r--r--drivers/net/wireless/at76c50x-usb.c10
-rw-r--r--drivers/net/wireless/ath/Kconfig1
-rw-r--r--drivers/net/wireless/ath/Makefile4
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c31
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c2
-rw-r--r--drivers/net/wireless/ath/ath.h56
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c47
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.h5
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h31
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c23
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c2373
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h33
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c121
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h15
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c8
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c297
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c26
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c99
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h73
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c34
-rw-r--r--drivers/net/wireless/ath/ath5k/rfbuffer.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig8
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile5
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c655
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c50
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c89
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c55
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c36
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h1784
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c37
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c164
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h86
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c28
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c152
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h11
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c290
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c171
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h33
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c28
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c40
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h42
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c134
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c74
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c51
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h22
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c418
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h116
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c76
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c310
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c200
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h37
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c602
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h48
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c63
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c74
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c184
-rw-r--r--drivers/net/wireless/ath/carl9170/Kconfig41
-rw-r--r--drivers/net/wireless/ath/carl9170/Makefile4
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h628
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.c188
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.h168
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.c902
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.h134
-rw-r--r--drivers/net/wireless/ath/carl9170/eeprom.h216
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c402
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h284
-rw-r--r--drivers/net/wireless/ath/carl9170/fwdesc.h241
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h739
-rw-r--r--drivers/net/wireless/ath/carl9170/led.c190
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c604
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c1891
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c1810
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.h564
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c938
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c1335
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c1136
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h7
-rw-r--r--drivers/net/wireless/ath/carl9170/wlan.h420
-rw-r--r--drivers/net/wireless/ath/debug.c29
-rw-r--r--drivers/net/wireless/ath/debug.h12
-rw-r--r--drivers/net/wireless/ath/hw.c59
-rw-r--r--drivers/net/wireless/ath/key.c568
-rw-r--r--drivers/net/wireless/ath/reg.h34
-rw-r--r--drivers/net/wireless/b43/Makefile2
-rw-r--r--drivers/net/wireless/b43/b43.h3
-rw-r--r--drivers/net/wireless/b43/main.c30
-rw-r--r--drivers/net/wireless/b43/phy_common.c6
-rw-r--r--drivers/net/wireless/b43/phy_common.h5
-rw-r--r--drivers/net/wireless/b43/phy_n.c211
-rw-r--r--drivers/net/wireless/b43/phy_n.h218
-rw-r--r--drivers/net/wireless/b43/radio_2055.c1332
-rw-r--r--drivers/net/wireless/b43/radio_2055.h254
-rw-r--r--drivers/net/wireless/b43/radio_2056.c43
-rw-r--r--drivers/net/wireless/b43/radio_2056.h42
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c1311
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h59
-rw-r--r--drivers/net/wireless/b43legacy/main.c5
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c2
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c10
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c20
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig10
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c119
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c191
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c134
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c245
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c754
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c58
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.h (renamed from drivers/net/wireless/iwlwifi/iwl-calib.h)4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c515
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c454
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c157
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ict.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c1121
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c404
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c716
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.c699
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.h129
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c208
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c118
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c890
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h96
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h585
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c1451
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h261
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c209
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h257
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c393
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c642
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h93
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c441
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c759
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c81
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c434
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c7
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c7
-rw-r--r--drivers/net/wireless/libertas/cfg.c72
-rw-r--r--drivers/net/wireless/libertas/decl.h13
-rw-r--r--drivers/net/wireless/libertas/if_cs.c129
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c161
-rw-r--r--drivers/net/wireless/libertas/if_sdio.h4
-rw-r--r--drivers/net/wireless/libertas/if_spi.c150
-rw-r--r--drivers/net/wireless/libertas/if_spi.h5
-rw-r--r--drivers/net/wireless/libertas/if_usb.c64
-rw-r--r--drivers/net/wireless/libertas/if_usb.h1
-rw-r--r--drivers/net/wireless/libertas/main.c105
-rw-r--r--drivers/net/wireless/libertas/mesh.c2
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c57
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c31
-rw-r--r--drivers/net/wireless/orinoco/hw.c9
-rw-r--r--drivers/net/wireless/orinoco/wext.c11
-rw-r--r--drivers/net/wireless/p54/Kconfig18
-rw-r--r--drivers/net/wireless/p54/eeprom.c25
-rw-r--r--drivers/net/wireless/p54/fwio.c6
-rw-r--r--drivers/net/wireless/p54/main.c9
-rw-r--r--drivers/net/wireless/p54/p54spi.c9
-rw-r--r--drivers/net/wireless/p54/p54spi_eeprom.h2
-rw-r--r--drivers/net/wireless/p54/p54usb.c15
-rw-r--r--drivers/net/wireless/p54/txrx.c25
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c2
-rw-r--r--drivers/net/wireless/ray_cs.c44
-rw-r--r--drivers/net/wireless/rndis_wlan.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c149
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c156
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c78
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h109
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c625
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h28
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c400
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c159
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h70
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c24
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c17
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c13
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c194
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c25
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h14
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c24
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c138
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h56
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c320
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c123
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c96
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c15
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c9
-rw-r--r--drivers/net/wireless/wl1251/Kconfig33
-rw-r--r--drivers/net/wireless/wl1251/Makefile6
-rw-r--r--drivers/net/wireless/wl1251/acx.c (renamed from drivers/net/wireless/wl12xx/wl1251_acx.c)10
-rw-r--r--drivers/net/wireless/wl1251/acx.h (renamed from drivers/net/wireless/wl12xx/wl1251_acx.h)12
-rw-r--r--drivers/net/wireless/wl1251/boot.c (renamed from drivers/net/wireless/wl12xx/wl1251_boot.c)16
-rw-r--r--drivers/net/wireless/wl1251/boot.h (renamed from drivers/net/wireless/wl12xx/wl1251_boot.h)2
-rw-r--r--drivers/net/wireless/wl1251/cmd.c (renamed from drivers/net/wireless/wl12xx/wl1251_cmd.c)12
-rw-r--r--drivers/net/wireless/wl1251/cmd.h (renamed from drivers/net/wireless/wl12xx/wl1251_cmd.h)8
-rw-r--r--drivers/net/wireless/wl1251/debugfs.c (renamed from drivers/net/wireless/wl12xx/wl1251_debugfs.c)8
-rw-r--r--drivers/net/wireless/wl1251/debugfs.h (renamed from drivers/net/wireless/wl12xx/wl1251_debugfs.h)2
-rw-r--r--drivers/net/wireless/wl1251/event.c (renamed from drivers/net/wireless/wl12xx/wl1251_event.c)41
-rw-r--r--drivers/net/wireless/wl1251/event.h (renamed from drivers/net/wireless/wl12xx/wl1251_event.h)3
-rw-r--r--drivers/net/wireless/wl1251/init.c (renamed from drivers/net/wireless/wl12xx/wl1251_init.c)10
-rw-r--r--drivers/net/wireless/wl1251/init.h (renamed from drivers/net/wireless/wl12xx/wl1251_init.h)2
-rw-r--r--drivers/net/wireless/wl1251/io.c (renamed from drivers/net/wireless/wl12xx/wl1251_io.c)6
-rw-r--r--drivers/net/wireless/wl1251/io.h (renamed from drivers/net/wireless/wl12xx/wl1251_io.h)0
-rw-r--r--drivers/net/wireless/wl1251/main.c (renamed from drivers/net/wireless/wl12xx/wl1251_main.c)75
-rw-r--r--drivers/net/wireless/wl1251/ps.c (renamed from drivers/net/wireless/wl12xx/wl1251_ps.c)10
-rw-r--r--drivers/net/wireless/wl1251/ps.h (renamed from drivers/net/wireless/wl12xx/wl1251_ps.h)10
-rw-r--r--drivers/net/wireless/wl1251/reg.h (renamed from drivers/net/wireless/wl12xx/wl1251_reg.h)2
-rw-r--r--drivers/net/wireless/wl1251/rx.c (renamed from drivers/net/wireless/wl12xx/wl1251_rx.c)12
-rw-r--r--drivers/net/wireless/wl1251/rx.h (renamed from drivers/net/wireless/wl12xx/wl1251_rx.h)2
-rw-r--r--drivers/net/wireless/wl1251/sdio.c (renamed from drivers/net/wireless/wl12xx/wl1251_sdio.c)4
-rw-r--r--drivers/net/wireless/wl1251/spi.c (renamed from drivers/net/wireless/wl12xx/wl1251_spi.c)10
-rw-r--r--drivers/net/wireless/wl1251/spi.h (renamed from drivers/net/wireless/wl12xx/wl1251_spi.h)8
-rw-r--r--drivers/net/wireless/wl1251/tx.c (renamed from drivers/net/wireless/wl12xx/wl1251_tx.c)34
-rw-r--r--drivers/net/wireless/wl1251/tx.h (renamed from drivers/net/wireless/wl12xx/wl1251_tx.h)4
-rw-r--r--drivers/net/wireless/wl1251/wl1251.h (renamed from drivers/net/wireless/wl12xx/wl1251.h)7
-rw-r--r--drivers/net/wireless/wl1251/wl12xx_80211.h156
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig39
-rw-r--r--drivers/net/wireless/wl12xx/Makefile12
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h32
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c36
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h31
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c67
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.h1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c143
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h73
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h78
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c15
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c39
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_io.h9
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c416
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c20
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c67
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_scan.c83
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_scan.h6
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c98
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c151
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_testmode.c14
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c109
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h17
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_platform_data.c28
-rw-r--r--drivers/net/wireless/wl3501_cs.c11
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c5
-rw-r--r--drivers/net/xen-netfront.c14
-rw-r--r--drivers/net/xilinx_emaclite.c15
-rw-r--r--drivers/net/yellowfin.c2
-rw-r--r--drivers/s390/cio/qdio.h29
-rw-r--r--drivers/s390/cio/qdio_debug.c33
-rw-r--r--drivers/s390/cio/qdio_main.c138
-rw-r--r--drivers/s390/cio/qdio_setup.c1
-rw-r--r--drivers/s390/cio/qdio_thinint.c66
-rw-r--r--drivers/s390/net/Kconfig2
-rw-r--r--drivers/s390/net/ctcm_mpc.c2
-rw-r--r--drivers/s390/net/qeth_core.h17
-rw-r--r--drivers/s390/net/qeth_core_main.c26
-rw-r--r--drivers/s390/net/qeth_l2_main.c175
-rw-r--r--drivers/s390/net/qeth_l3_main.c218
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c6
-rw-r--r--drivers/scsi/bnx2i/57xx_iscsi_constants.h2
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h2
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c3
-rw-r--r--drivers/usb/atm/cxacru.c18
-rw-r--r--drivers/vhost/net.c2
-rw-r--r--drivers/vhost/vhost.c51
-rw-r--r--drivers/vhost/vhost.h18
-rw-r--r--firmware/Makefile14
-rw-r--r--firmware/WHENCE15
-rw-r--r--firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex5908
-rw-r--r--firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex5815
-rw-r--r--firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex6081
-rw-r--r--firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex6488
-rw-r--r--firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex424
-rw-r--r--firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex366
-rw-r--r--firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex462
-rw-r--r--firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex392
-rw-r--r--firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex499
-rw-r--r--firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex425
-rw-r--r--firmware/bnx2x-e1-5.2.13.0.fw.ihex10191
-rw-r--r--firmware/bnx2x-e1h-5.2.13.0.fw.ihex12849
-rw-r--r--firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex9476
-rw-r--r--firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex13178
-rw-r--r--firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex15442
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/atmdev.h2
-rw-r--r--include/linux/can/platform/mcp251x.h4
-rw-r--r--include/linux/dccp.h6
-rw-r--r--include/linux/etherdevice.h22
-rw-r--r--include/linux/ethtool.h190
-rw-r--r--include/linux/ieee80211.h71
-rw-r--r--include/linux/if.h2
-rw-r--r--include/linux/if_bonding.h3
-rw-r--r--include/linux/if_ether.h2
-rw-r--r--include/linux/if_macvlan.h9
-rw-r--r--include/linux/if_pppox.h52
-rw-r--r--include/linux/if_vlan.h31
-rw-r--r--include/linux/in.h19
-rw-r--r--include/linux/in6.h4
-rw-r--r--include/linux/inetdevice.h21
-rw-r--r--include/linux/ip_vs.h15
-rw-r--r--include/linux/ipv6.h4
-rw-r--r--include/linux/mlx4/cmd.h1
-rw-r--r--include/linux/mlx4/device.h7
-rw-r--r--include/linux/mmc/sdio_ids.h1
-rw-r--r--include/linux/mroute.h1
-rw-r--r--include/linux/netdevice.h120
-rw-r--r--include/linux/netfilter/nf_conntrack_common.h6
-rw-r--r--include/linux/netfilter/nf_conntrack_sip.h1
-rw-r--r--include/linux/netfilter/nfnetlink_conntrack.h1
-rw-r--r--include/linux/netfilter/x_tables.h5
-rw-r--r--include/linux/netfilter/xt_TPROXY.h13
-rw-r--r--include/linux/netfilter_arp/arp_tables.h68
-rw-r--r--include/linux/netfilter_bridge/Kbuild2
-rw-r--r--include/linux/netfilter_ipv4/ip_tables.h107
-rw-r--r--include/linux/netfilter_ipv6/ip6_tables.h110
-rw-r--r--include/linux/netpoll.h9
-rw-r--r--include/linux/nl80211.h210
-rw-r--r--include/linux/pci_ids.h3
-rw-r--r--include/linux/phonet.h5
-rw-r--r--include/linux/phy.h4
-rw-r--r--include/linux/pkt_cls.h1
-rw-r--r--include/linux/rds.h115
-rw-r--r--include/linux/rtnetlink.h30
-rw-r--r--include/linux/skbuff.h117
-rw-r--r--include/linux/socket.h1
-rw-r--r--include/linux/ssb/ssb_regs.h1
-rw-r--r--include/linux/stmmac.h6
-rw-r--r--include/linux/tc_act/Kbuild1
-rw-r--r--include/linux/tc_act/tc_csum.h32
-rw-r--r--include/linux/tc_ematch/tc_em_meta.h1
-rw-r--r--include/linux/tcp.h1
-rw-r--r--include/linux/tipc.h30
-rw-r--r--include/linux/wireless.h2
-rw-r--r--include/linux/wl12xx.h (renamed from include/linux/spi/wl12xx.h)23
-rw-r--r--include/net/9p/client.h3
-rw-r--r--include/net/addrconf.h65
-rw-r--r--include/net/arp.h2
-rw-r--r--include/net/bluetooth/bluetooth.h2
-rw-r--r--include/net/bluetooth/hci.h2
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--include/net/bluetooth/l2cap.h2
-rw-r--r--include/net/bluetooth/rfcomm.h5
-rw-r--r--include/net/cfg80211.h296
-rw-r--r--include/net/dst.h33
-rw-r--r--include/net/dst_ops.h37
-rw-r--r--include/net/fib_rules.h3
-rw-r--r--include/net/flow.h1
-rw-r--r--include/net/genetlink.h18
-rw-r--r--include/net/gre.h18
-rw-r--r--include/net/inet_connection_sock.h1
-rw-r--r--include/net/inet_ecn.h2
-rw-r--r--include/net/inet_hashtables.h2
-rw-r--r--include/net/ip.h6
-rw-r--r--include/net/ip_fib.h17
-rw-r--r--include/net/ip_vs.h180
-rw-r--r--include/net/ipip.h12
-rw-r--r--include/net/ipv6.h35
-rw-r--r--include/net/irda/irlan_common.h1
-rw-r--r--include/net/irda/irlan_event.h2
-rw-r--r--include/net/irda/irlap.h2
-rw-r--r--include/net/irda/irlmp.h2
-rw-r--r--include/net/irda/irttp.h2
-rw-r--r--include/net/mac80211.h195
-rw-r--r--include/net/neighbour.h47
-rw-r--r--include/net/net_namespace.h17
-rw-r--r--include/net/netfilter/ipv6/nf_defrag_ipv6.h6
-rw-r--r--include/net/netfilter/nf_conntrack_expect.h12
-rw-r--r--include/net/netfilter/nf_nat_protocol.h3
-rw-r--r--include/net/netfilter/nf_tproxy_core.h192
-rw-r--r--include/net/netfilter/xt_log.h54
-rw-r--r--include/net/netns/xfrm.h9
-rw-r--r--include/net/phonet/pep.h26
-rw-r--r--include/net/phonet/phonet.h5
-rw-r--r--include/net/phonet/pn_dev.h1
-rw-r--r--include/net/raw.h5
-rw-r--r--include/net/rtnetlink.h1
-rw-r--r--include/net/sch_generic.h5
-rw-r--r--include/net/sctp/sctp.h60
-rw-r--r--include/net/sctp/sm.h10
-rw-r--r--include/net/sctp/structs.h2
-rw-r--r--include/net/sctp/tsnmap.h2
-rw-r--r--include/net/sock.h14
-rw-r--r--include/net/tc_act/tc_csum.h15
-rw-r--r--include/net/tcp.h11
-rw-r--r--include/net/tipc/tipc.h71
-rw-r--r--include/net/tipc/tipc_msg.h10
-rw-r--r--include/net/tipc/tipc_port.h2
-rw-r--r--include/net/udp.h3
-rw-r--r--include/net/xfrm.h3
-rw-r--r--net/802/fc.c2
-rw-r--r--net/802/fddi.c12
-rw-r--r--net/802/hippi.c2
-rw-r--r--net/802/tr.c2
-rw-r--r--net/8021q/vlan.c93
-rw-r--r--net/8021q/vlan.h17
-rw-r--r--net/8021q/vlan_core.c121
-rw-r--r--net/8021q/vlan_dev.c10
-rw-r--r--net/9p/client.c55
-rw-r--r--net/9p/trans_fd.c2
-rw-r--r--net/atm/clip.c4
-rw-r--r--net/atm/common.c2
-rw-r--r--net/atm/lec.c1
-rw-r--r--net/ax25/af_ax25.c2
-rw-r--r--net/ax25/ax25_route.c4
-rw-r--r--net/bluetooth/af_bluetooth.c114
-rw-r--r--net/bluetooth/cmtp/core.c6
-rw-r--r--net/bluetooth/hci_core.c1
-rw-r--r--net/bluetooth/hci_sysfs.c21
-rw-r--r--net/bluetooth/hidp/core.c8
-rw-r--r--net/bluetooth/l2cap.c60
-rw-r--r--net/bluetooth/lib.c4
-rw-r--r--net/bluetooth/rfcomm/core.c43
-rw-r--r--net/bluetooth/rfcomm/sock.c104
-rw-r--r--net/bluetooth/rfcomm/tty.c4
-rw-r--r--net/bridge/br_device.c8
-rw-r--r--net/bridge/br_if.c29
-rw-r--r--net/bridge/br_input.c4
-rw-r--r--net/bridge/br_netfilter.c134
-rw-r--r--net/bridge/netfilter/ebt_vlan.c25
-rw-r--r--net/bridge/netfilter/ebtables.c15
-rw-r--r--net/caif/caif_dev.c24
-rw-r--r--net/caif/caif_socket.c27
-rw-r--r--net/caif/cfcnfg.c49
-rw-r--r--net/caif/cfctrl.c59
-rw-r--r--net/caif/cfdbgl.c4
-rw-r--r--net/caif/cfdgml.c11
-rw-r--r--net/caif/cffrml.c14
-rw-r--r--net/caif/cfmuxl.c14
-rw-r--r--net/caif/cfpkt_skbuff.c48
-rw-r--r--net/caif/cfrfml.c12
-rw-r--r--net/caif/cfserl.c4
-rw-r--r--net/caif/cfsrvl.c17
-rw-r--r--net/caif/cfutill.c12
-rw-r--r--net/caif/cfveil.c11
-rw-r--r--net/caif/cfvidl.c6
-rw-r--r--net/caif/chnl_net.c47
-rw-r--r--net/can/raw.c37
-rw-r--r--net/core/datagram.c5
-rw-r--r--net/core/dev.c597
-rw-r--r--net/core/dst.c39
-rw-r--r--net/core/ethtool.c91
-rw-r--r--net/core/fib_rules.c16
-rw-r--r--net/core/filter.c10
-rw-r--r--net/core/flow.c82
-rw-r--r--net/core/gen_estimator.c4
-rw-r--r--net/core/iovec.c6
-rw-r--r--net/core/neighbour.c486
-rw-r--r--net/core/net-sysfs.c39
-rw-r--r--net/core/net-sysfs.h4
-rw-r--r--net/core/netpoll.c6
-rw-r--r--net/core/pktgen.c12
-rw-r--r--net/core/rtnetlink.c39
-rw-r--r--net/core/skbuff.c105
-rw-r--r--net/core/sock.c4
-rw-r--r--net/core/utils.c15
-rw-r--r--net/dccp/ccid.h52
-rw-r--r--net/dccp/ccids/Kconfig31
-rw-r--r--net/dccp/ccids/ccid2.c289
-rw-r--r--net/dccp/ccids/ccid2.h35
-rw-r--r--net/dccp/ccids/ccid3.c256
-rw-r--r--net/dccp/ccids/ccid3.h51
-rw-r--r--net/dccp/ccids/lib/loss_interval.c2
-rw-r--r--net/dccp/ccids/lib/packet_history.c39
-rw-r--r--net/dccp/ccids/lib/packet_history.h22
-rw-r--r--net/dccp/ccids/lib/tfrc.h1
-rw-r--r--net/dccp/ccids/lib/tfrc_equation.c14
-rw-r--r--net/dccp/dccp.h46
-rw-r--r--net/dccp/feat.c10
-rw-r--r--net/dccp/feat.h1
-rw-r--r--net/dccp/input.c20
-rw-r--r--net/dccp/ipv4.c10
-rw-r--r--net/dccp/ipv6.c10
-rw-r--r--net/dccp/minisocks.c30
-rw-r--r--net/dccp/options.c31
-rw-r--r--net/dccp/output.c20
-rw-r--r--net/dccp/proto.c50
-rw-r--r--net/decnet/dn_neigh.c13
-rw-r--r--net/decnet/dn_nsp_out.c8
-rw-r--r--net/decnet/dn_route.c3
-rw-r--r--net/econet/af_econet.c6
-rw-r--r--net/ethernet/eth.c8
-rw-r--r--net/ipv4/Kconfig8
-rw-r--r--net/ipv4/Makefile1
-rw-r--r--net/ipv4/af_inet.c8
-rw-r--r--net/ipv4/arp.c245
-rw-r--r--net/ipv4/datagram.c2
-rw-r--r--net/ipv4/devinet.c11
-rw-r--r--net/ipv4/fib_frontend.c192
-rw-r--r--net/ipv4/fib_hash.c291
-rw-r--r--net/ipv4/fib_lookup.h11
-rw-r--r--net/ipv4/fib_rules.c13
-rw-r--r--net/ipv4/fib_semantics.c297
-rw-r--r--net/ipv4/fib_trie.c84
-rw-r--r--net/ipv4/gre.c151
-rw-r--r--net/ipv4/icmp.c4
-rw-r--r--net/ipv4/igmp.c22
-rw-r--r--net/ipv4/inet_diag.c2
-rw-r--r--net/ipv4/inet_hashtables.c28
-rw-r--r--net/ipv4/ip_fragment.c6
-rw-r--r--net/ipv4/ip_gre.c237
-rw-r--r--net/ipv4/ip_options.c3
-rw-r--r--net/ipv4/ip_output.c24
-rw-r--r--net/ipv4/ipip.c212
-rw-r--r--net/ipv4/ipmr.c428
-rw-r--r--net/ipv4/netfilter/Kconfig4
-rw-r--r--net/ipv4/netfilter/arp_tables.c64
-rw-r--r--net/ipv4/netfilter/arpt_mangle.c2
-rw-r--r--net/ipv4/netfilter/ip_tables.c84
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c31
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c145
-rw-r--r--net/ipv4/netfilter/nf_nat_amanda.c9
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c51
-rw-r--r--net/ipv4/netfilter/nf_nat_ftp.c9
-rw-r--r--net/ipv4/netfilter/nf_nat_h323.c53
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c76
-rw-r--r--net/ipv4/netfilter/nf_nat_irc.c9
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c17
-rw-r--r--net/ipv4/netfilter/nf_nat_sip.c27
-rw-r--r--net/ipv4/protocol.c31
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/route.c190
-rw-r--r--net/ipv4/tcp.c11
-rw-r--r--net/ipv4/tcp_input.c55
-rw-r--r--net/ipv4/tcp_ipv4.c12
-rw-r--r--net/ipv4/tcp_minisocks.c2
-rw-r--r--net/ipv4/tcp_output.c31
-rw-r--r--net/ipv4/tcp_timer.c50
-rw-r--r--net/ipv4/tcp_westwood.c2
-rw-r--r--net/ipv4/tunnel4.c19
-rw-r--r--net/ipv4/udp.c4
-rw-r--r--net/ipv4/xfrm4_policy.c4
-rw-r--r--net/ipv4/xfrm4_tunnel.c4
-rw-r--r--net/ipv6/addrconf.c8
-rw-r--r--net/ipv6/addrlabel.c5
-rw-r--r--net/ipv6/af_inet6.c9
-rw-r--r--net/ipv6/datagram.c19
-rw-r--r--net/ipv6/exthdrs_core.c4
-rw-r--r--net/ipv6/fib6_rules.c3
-rw-r--r--net/ipv6/ip6_fib.c9
-rw-r--r--net/ipv6/ip6_output.c6
-rw-r--r--net/ipv6/ip6_tunnel.c157
-rw-r--r--net/ipv6/ip6mr.c1
-rw-r--r--net/ipv6/ipv6_sockglue.c23
-rw-r--r--net/ipv6/ndisc.c36
-rw-r--r--net/ipv6/netfilter/Kconfig4
-rw-r--r--net/ipv6/netfilter/Makefile5
-rw-r--r--net/ipv6/netfilter/ip6_tables.c98
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c157
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c78
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c16
-rw-r--r--net/ipv6/netfilter/nf_defrag_ipv6_hooks.c131
-rw-r--r--net/ipv6/protocol.c32
-rw-r--r--net/ipv6/raw.c12
-rw-r--r--net/ipv6/reassembly.c2
-rw-r--r--net/ipv6/route.c50
-rw-r--r--net/ipv6/sit.c165
-rw-r--r--net/ipv6/tcp_ipv6.c14
-rw-r--r--net/ipv6/tunnel6.c17
-rw-r--r--net/ipv6/udp.c16
-rw-r--r--net/ipv6/xfrm6_policy.c10
-rw-r--r--net/ipv6/xfrm6_tunnel.c8
-rw-r--r--net/irda/af_irda.c380
-rw-r--r--net/irda/discovery.c2
-rw-r--r--net/irda/ircomm/ircomm_tty.c4
-rw-r--r--net/irda/iriap.c3
-rw-r--r--net/irda/irlan/irlan_eth.c32
-rw-r--r--net/irda/irlan/irlan_event.c2
-rw-r--r--net/irda/irlmp.c2
-rw-r--r--net/irda/irlmp_frame.c2
-rw-r--r--net/irda/irnet/irnet.h2
-rw-r--r--net/irda/irnet/irnet_irda.c22
-rw-r--r--net/irda/irnet/irnet_ppp.c69
-rw-r--r--net/irda/irnet/irnet_ppp.h3
-rw-r--r--net/irda/parameters.c4
-rw-r--r--net/key/af_key.c4
-rw-r--r--net/l2tp/l2tp_eth.c1
-rw-r--r--net/l2tp/l2tp_ip.c4
-rw-r--r--net/l2tp/l2tp_ppp.c2
-rw-r--r--net/mac80211/aes_ccm.c6
-rw-r--r--net/mac80211/aes_cmac.c6
-rw-r--r--net/mac80211/agg-rx.c30
-rw-r--r--net/mac80211/agg-tx.c14
-rw-r--r--net/mac80211/cfg.c244
-rw-r--r--net/mac80211/chan.c2
-rw-r--r--net/mac80211/debugfs.c7
-rw-r--r--net/mac80211/debugfs_key.c55
-rw-r--r--net/mac80211/debugfs_netdev.c3
-rw-r--r--net/mac80211/debugfs_sta.c5
-rw-r--r--net/mac80211/driver-ops.h14
-rw-r--r--net/mac80211/driver-trace.h42
-rw-r--r--net/mac80211/ht.c47
-rw-r--r--net/mac80211/ibss.c77
-rw-r--r--net/mac80211/ieee80211_i.h133
-rw-r--r--net/mac80211/iface.c460
-rw-r--r--net/mac80211/key.c168
-rw-r--r--net/mac80211/key.h13
-rw-r--r--net/mac80211/main.c194
-rw-r--r--net/mac80211/mesh_plink.c17
-rw-r--r--net/mac80211/mlme.c173
-rw-r--r--net/mac80211/offchannel.c26
-rw-r--r--net/mac80211/pm.c2
-rw-r--r--net/mac80211/rate.c11
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c7
-rw-r--r--net/mac80211/rc80211_pid_debugfs.c2
-rw-r--r--net/mac80211/rx.c819
-rw-r--r--net/mac80211/scan.c179
-rw-r--r--net/mac80211/sta_info.c52
-rw-r--r--net/mac80211/sta_info.h24
-rw-r--r--net/mac80211/status.c14
-rw-r--r--net/mac80211/tx.c73
-rw-r--r--net/mac80211/util.c102
-rw-r--r--net/mac80211/wep.c10
-rw-r--r--net/mac80211/work.c39
-rw-r--r--net/mac80211/wpa.c34
-rw-r--r--net/netfilter/core.c6
-rw-r--r--net/netfilter/ipvs/Kconfig20
-rw-r--r--net/netfilter/ipvs/Makefile10
-rw-r--r--net/netfilter/ipvs/ip_vs_app.c6
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c286
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c819
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c392
-rw-r--r--net/netfilter/ipvs/ip_vs_ftp.c194
-rw-r--r--net/netfilter/ipvs/ip_vs_nfct.c292
-rw-r--r--net/netfilter/ipvs/ip_vs_pe.c147
-rw-r--r--net/netfilter/ipvs/ip_vs_pe_sip.c169
-rw-r--r--net/netfilter/ipvs/ip_vs_proto.c8
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_ah_esp.c99
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_sctp.c27
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_tcp.c52
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_udp.c51
-rw-r--r--net/netfilter/ipvs/ip_vs_sched.c47
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c46
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c696
-rw-r--r--net/netfilter/nf_conntrack_core.c131
-rw-r--r--net/netfilter/nf_conntrack_expect.c68
-rw-r--r--net/netfilter/nf_conntrack_netlink.c77
-rw-r--r--net/netfilter/nf_conntrack_sip.c42
-rw-r--r--net/netfilter/nf_tproxy_core.c35
-rw-r--r--net/netfilter/x_tables.c12
-rw-r--r--net/netfilter/xt_TPROXY.c366
-rw-r--r--net/netfilter/xt_hashlimit.c15
-rw-r--r--net/netfilter/xt_ipvs.c1
-rw-r--r--net/netfilter/xt_socket.c167
-rw-r--r--net/netlink/genetlink.c14
-rw-r--r--net/packet/af_packet.c4
-rw-r--r--net/phonet/Kconfig12
-rw-r--r--net/phonet/af_phonet.c17
-rw-r--r--net/phonet/datagram.c13
-rw-r--r--net/phonet/pep.c388
-rw-r--r--net/phonet/pn_dev.c5
-rw-r--r--net/phonet/socket.c289
-rw-r--r--net/rds/af_rds.c26
-rw-r--r--net/rds/bind.c82
-rw-r--r--net/rds/cong.c8
-rw-r--r--net/rds/connection.c159
-rw-r--r--net/rds/ib.c200
-rw-r--r--net/rds/ib.h104
-rw-r--r--net/rds/ib_cm.c184
-rw-r--r--net/rds/ib_rdma.c318
-rw-r--r--net/rds/ib_recv.c549
-rw-r--r--net/rds/ib_send.c682
-rw-r--r--net/rds/ib_stats.c2
-rw-r--r--net/rds/ib_sysctl.c19
-rw-r--r--net/rds/info.c12
-rw-r--r--net/rds/iw.c8
-rw-r--r--net/rds/iw.h15
-rw-r--r--net/rds/iw_cm.c14
-rw-r--r--net/rds/iw_rdma.c8
-rw-r--r--net/rds/iw_recv.c24
-rw-r--r--net/rds/iw_send.c93
-rw-r--r--net/rds/iw_sysctl.c6
-rw-r--r--net/rds/loop.c31
-rw-r--r--net/rds/message.c142
-rw-r--r--net/rds/page.c8
-rw-r--r--net/rds/rdma.c339
-rw-r--r--net/rds/rdma.h85
-rw-r--r--net/rds/rdma_transport.c44
-rw-r--r--net/rds/rdma_transport.h4
-rw-r--r--net/rds/rds.h192
-rw-r--r--net/rds/recv.c12
-rw-r--r--net/rds/send.c548
-rw-r--r--net/rds/stats.c6
-rw-r--r--net/rds/sysctl.c4
-rw-r--r--net/rds/tcp.c12
-rw-r--r--net/rds/tcp.h9
-rw-r--r--net/rds/tcp_connect.c2
-rw-r--r--net/rds/tcp_listen.c6
-rw-r--r--net/rds/tcp_recv.c17
-rw-r--r--net/rds/tcp_send.c68
-rw-r--r--net/rds/threads.c69
-rw-r--r--net/rds/transport.c19
-rw-r--r--net/rds/xlist.h80
-rw-r--r--net/rfkill/input.c2
-rw-r--r--net/rose/rose_link.c4
-rw-r--r--net/sched/Kconfig10
-rw-r--r--net/sched/Makefile1
-rw-r--r--net/sched/act_csum.c595
-rw-r--r--net/sched/act_ipt.c14
-rw-r--r--net/sched/cls_flow.c74
-rw-r--r--net/sched/em_meta.c6
-rw-r--r--net/sched/sch_api.c44
-rw-r--r--net/sched/sch_atm.c5
-rw-r--r--net/sched/sch_cbq.c12
-rw-r--r--net/sched/sch_drr.c4
-rw-r--r--net/sched/sch_dsmark.c6
-rw-r--r--net/sched/sch_fifo.c3
-rw-r--r--net/sched/sch_generic.c24
-rw-r--r--net/sched/sch_hfsc.c8
-rw-r--r--net/sched/sch_htb.c12
-rw-r--r--net/sched/sch_mq.c2
-rw-r--r--net/sched/sch_multiq.c3
-rw-r--r--net/sched/sch_netem.c3
-rw-r--r--net/sched/sch_prio.c2
-rw-r--r--net/sched/sch_sfq.c33
-rw-r--r--net/sched/sch_teql.c8
-rw-r--r--net/sctp/associola.c2
-rw-r--r--net/sctp/chunk.c2
-rw-r--r--net/sctp/inqueue.c2
-rw-r--r--net/sctp/ipv6.c4
-rw-r--r--net/sctp/objcnt.c5
-rw-r--r--net/sctp/output.c2
-rw-r--r--net/sctp/outqueue.c34
-rw-r--r--net/sctp/probe.c4
-rw-r--r--net/sctp/protocol.c19
-rw-r--r--net/sctp/sm_make_chunk.c2
-rw-r--r--net/sctp/sm_sideeffect.c21
-rw-r--r--net/sctp/sm_statefuns.c20
-rw-r--r--net/sctp/sm_statetable.c42
-rw-r--r--net/sctp/socket.c85
-rw-r--r--net/sctp/transport.c9
-rw-r--r--net/socket.c37
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c2
-rw-r--r--net/sunrpc/auth_gss/gss_generic_token.c44
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seqnum.c2
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c2
-rw-r--r--net/sunrpc/sched.c2
-rw-r--r--net/tipc/addr.c7
-rw-r--r--net/tipc/bcast.c51
-rw-r--r--net/tipc/bcast.h3
-rw-r--r--net/tipc/bearer.c42
-rw-r--r--net/tipc/cluster.c21
-rw-r--r--net/tipc/cluster.h2
-rw-r--r--net/tipc/config.c148
-rw-r--r--net/tipc/config.h6
-rw-r--r--net/tipc/core.c38
-rw-r--r--net/tipc/core.h9
-rw-r--r--net/tipc/dbg.c17
-rw-r--r--net/tipc/dbg.h3
-rw-r--r--net/tipc/discover.c44
-rw-r--r--net/tipc/discover.h5
-rw-r--r--net/tipc/eth_media.c48
-rw-r--r--net/tipc/link.c188
-rw-r--r--net/tipc/link.h24
-rw-r--r--net/tipc/msg.c2
-rw-r--r--net/tipc/msg.h6
-rw-r--r--net/tipc/name_distr.c2
-rw-r--r--net/tipc/name_table.c67
-rw-r--r--net/tipc/net.c10
-rw-r--r--net/tipc/node.c73
-rw-r--r--net/tipc/node.h3
-rw-r--r--net/tipc/port.c295
-rw-r--r--net/tipc/port.h4
-rw-r--r--net/tipc/ref.c17
-rw-r--r--net/tipc/ref.h1
-rw-r--r--net/tipc/socket.c83
-rw-r--r--net/tipc/subscr.c77
-rw-r--r--net/tipc/subscr.h2
-rw-r--r--net/tipc/zone.c11
-rw-r--r--net/tipc/zone.h1
-rw-r--r--net/unix/af_unix.c10
-rw-r--r--net/wireless/core.c66
-rw-r--r--net/wireless/core.h34
-rw-r--r--net/wireless/ibss.c21
-rw-r--r--net/wireless/mlme.c225
-rw-r--r--net/wireless/nl80211.c2189
-rw-r--r--net/wireless/nl80211.h14
-rw-r--r--net/wireless/radiotap.c61
-rw-r--r--net/wireless/reg.c22
-rw-r--r--net/wireless/scan.c12
-rw-r--r--net/wireless/sme.c11
-rw-r--r--net/wireless/sysfs.c18
-rw-r--r--net/wireless/util.c40
-rw-r--r--net/wireless/wext-compat.c42
-rw-r--r--net/wireless/wext-core.c2
-rw-r--r--net/wireless/wext-sme.c2
-rw-r--r--net/x25/af_x25.c34
-rw-r--r--net/xfrm/xfrm_policy.c7
1341 files changed, 156508 insertions, 83259 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
new file mode 100644
index 000000000000..19a1210c2530
--- /dev/null
+++ b/Documentation/DocBook/80211.tmpl
@@ -0,0 +1,495 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE set PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
+<set>
+ <setinfo>
+ <title>The 802.11 subsystems &ndash; for kernel developers</title>
+ <subtitle>
+ Explaining wireless 802.11 networking in the Linux kernel
+ </subtitle>
+
+ <copyright>
+ <year>2007-2009</year>
+ <holder>Johannes Berg</holder>
+ </copyright>
+
+ <authorgroup>
+ <author>
+ <firstname>Johannes</firstname>
+ <surname>Berg</surname>
+ <affiliation>
+ <address><email>johannes@sipsolutions.net</email></address>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <legalnotice>
+ <para>
+ This documentation 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.
+ </para>
+ <para>
+ This documentation 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.
+ </para>
+ <para>
+ You should have received a copy of the GNU General Public
+ License along with this documentation; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ MA 02111-1307 USA
+ </para>
+ <para>
+ For more details see the file COPYING in the source
+ distribution of Linux.
+ </para>
+ </legalnotice>
+
+ <abstract>
+ <para>
+ These books attempt to give a description of the
+ various subsystems that play a role in 802.11 wireless
+ networking in Linux. Since these books are for kernel
+ developers they attempts to document the structures
+ and functions used in the kernel as well as giving a
+ higher-level overview.
+ </para>
+ <para>
+ The reader is expected to be familiar with the 802.11
+ standard as published by the IEEE in 802.11-2007 (or
+ possibly later versions). References to this standard
+ will be given as "802.11-2007 8.1.5".
+ </para>
+ </abstract>
+ </setinfo>
+ <book id="cfg80211-developers-guide">
+ <bookinfo>
+ <title>The cfg80211 subsystem</title>
+
+ <abstract>
+!Pinclude/net/cfg80211.h Introduction
+ </abstract>
+ </bookinfo>
+ <chapter>
+ <title>Device registration</title>
+!Pinclude/net/cfg80211.h Device registration
+!Finclude/net/cfg80211.h ieee80211_band
+!Finclude/net/cfg80211.h ieee80211_channel_flags
+!Finclude/net/cfg80211.h ieee80211_channel
+!Finclude/net/cfg80211.h ieee80211_rate_flags
+!Finclude/net/cfg80211.h ieee80211_rate
+!Finclude/net/cfg80211.h ieee80211_sta_ht_cap
+!Finclude/net/cfg80211.h ieee80211_supported_band
+!Finclude/net/cfg80211.h cfg80211_signal_type
+!Finclude/net/cfg80211.h wiphy_params_flags
+!Finclude/net/cfg80211.h wiphy_flags
+!Finclude/net/cfg80211.h wiphy
+!Finclude/net/cfg80211.h wireless_dev
+!Finclude/net/cfg80211.h wiphy_new
+!Finclude/net/cfg80211.h wiphy_register
+!Finclude/net/cfg80211.h wiphy_unregister
+!Finclude/net/cfg80211.h wiphy_free
+
+!Finclude/net/cfg80211.h wiphy_name
+!Finclude/net/cfg80211.h wiphy_dev
+!Finclude/net/cfg80211.h wiphy_priv
+!Finclude/net/cfg80211.h priv_to_wiphy
+!Finclude/net/cfg80211.h set_wiphy_dev
+!Finclude/net/cfg80211.h wdev_priv
+ </chapter>
+ <chapter>
+ <title>Actions and configuration</title>
+!Pinclude/net/cfg80211.h Actions and configuration
+!Finclude/net/cfg80211.h cfg80211_ops
+!Finclude/net/cfg80211.h vif_params
+!Finclude/net/cfg80211.h key_params
+!Finclude/net/cfg80211.h survey_info_flags
+!Finclude/net/cfg80211.h survey_info
+!Finclude/net/cfg80211.h beacon_parameters
+!Finclude/net/cfg80211.h plink_actions
+!Finclude/net/cfg80211.h station_parameters
+!Finclude/net/cfg80211.h station_info_flags
+!Finclude/net/cfg80211.h rate_info_flags
+!Finclude/net/cfg80211.h rate_info
+!Finclude/net/cfg80211.h station_info
+!Finclude/net/cfg80211.h monitor_flags
+!Finclude/net/cfg80211.h mpath_info_flags
+!Finclude/net/cfg80211.h mpath_info
+!Finclude/net/cfg80211.h bss_parameters
+!Finclude/net/cfg80211.h ieee80211_txq_params
+!Finclude/net/cfg80211.h cfg80211_crypto_settings
+!Finclude/net/cfg80211.h cfg80211_auth_request
+!Finclude/net/cfg80211.h cfg80211_assoc_request
+!Finclude/net/cfg80211.h cfg80211_deauth_request
+!Finclude/net/cfg80211.h cfg80211_disassoc_request
+!Finclude/net/cfg80211.h cfg80211_ibss_params
+!Finclude/net/cfg80211.h cfg80211_connect_params
+!Finclude/net/cfg80211.h cfg80211_pmksa
+!Finclude/net/cfg80211.h cfg80211_send_rx_auth
+!Finclude/net/cfg80211.h cfg80211_send_auth_timeout
+!Finclude/net/cfg80211.h __cfg80211_auth_canceled
+!Finclude/net/cfg80211.h cfg80211_send_rx_assoc
+!Finclude/net/cfg80211.h cfg80211_send_assoc_timeout
+!Finclude/net/cfg80211.h cfg80211_send_deauth
+!Finclude/net/cfg80211.h __cfg80211_send_deauth
+!Finclude/net/cfg80211.h cfg80211_send_disassoc
+!Finclude/net/cfg80211.h __cfg80211_send_disassoc
+!Finclude/net/cfg80211.h cfg80211_ibss_joined
+!Finclude/net/cfg80211.h cfg80211_connect_result
+!Finclude/net/cfg80211.h cfg80211_roamed
+!Finclude/net/cfg80211.h cfg80211_disconnected
+!Finclude/net/cfg80211.h cfg80211_ready_on_channel
+!Finclude/net/cfg80211.h cfg80211_remain_on_channel_expired
+!Finclude/net/cfg80211.h cfg80211_new_sta
+!Finclude/net/cfg80211.h cfg80211_rx_mgmt
+!Finclude/net/cfg80211.h cfg80211_mgmt_tx_status
+!Finclude/net/cfg80211.h cfg80211_cqm_rssi_notify
+!Finclude/net/cfg80211.h cfg80211_michael_mic_failure
+ </chapter>
+ <chapter>
+ <title>Scanning and BSS list handling</title>
+!Pinclude/net/cfg80211.h Scanning and BSS list handling
+!Finclude/net/cfg80211.h cfg80211_ssid
+!Finclude/net/cfg80211.h cfg80211_scan_request
+!Finclude/net/cfg80211.h cfg80211_scan_done
+!Finclude/net/cfg80211.h cfg80211_bss
+!Finclude/net/cfg80211.h cfg80211_inform_bss_frame
+!Finclude/net/cfg80211.h cfg80211_inform_bss
+!Finclude/net/cfg80211.h cfg80211_unlink_bss
+!Finclude/net/cfg80211.h cfg80211_find_ie
+!Finclude/net/cfg80211.h ieee80211_bss_get_ie
+ </chapter>
+ <chapter>
+ <title>Utility functions</title>
+!Pinclude/net/cfg80211.h Utility functions
+!Finclude/net/cfg80211.h ieee80211_channel_to_frequency
+!Finclude/net/cfg80211.h ieee80211_frequency_to_channel
+!Finclude/net/cfg80211.h ieee80211_get_channel
+!Finclude/net/cfg80211.h ieee80211_get_response_rate
+!Finclude/net/cfg80211.h ieee80211_hdrlen
+!Finclude/net/cfg80211.h ieee80211_get_hdrlen_from_skb
+!Finclude/net/cfg80211.h ieee80211_radiotap_iterator
+ </chapter>
+ <chapter>
+ <title>Data path helpers</title>
+!Pinclude/net/cfg80211.h Data path helpers
+!Finclude/net/cfg80211.h ieee80211_data_to_8023
+!Finclude/net/cfg80211.h ieee80211_data_from_8023
+!Finclude/net/cfg80211.h ieee80211_amsdu_to_8023s
+!Finclude/net/cfg80211.h cfg80211_classify8021d
+ </chapter>
+ <chapter>
+ <title>Regulatory enforcement infrastructure</title>
+!Pinclude/net/cfg80211.h Regulatory enforcement infrastructure
+!Finclude/net/cfg80211.h regulatory_hint
+!Finclude/net/cfg80211.h wiphy_apply_custom_regulatory
+!Finclude/net/cfg80211.h freq_reg_info
+ </chapter>
+ <chapter>
+ <title>RFkill integration</title>
+!Pinclude/net/cfg80211.h RFkill integration
+!Finclude/net/cfg80211.h wiphy_rfkill_set_hw_state
+!Finclude/net/cfg80211.h wiphy_rfkill_start_polling
+!Finclude/net/cfg80211.h wiphy_rfkill_stop_polling
+ </chapter>
+ <chapter>
+ <title>Test mode</title>
+!Pinclude/net/cfg80211.h Test mode
+!Finclude/net/cfg80211.h cfg80211_testmode_alloc_reply_skb
+!Finclude/net/cfg80211.h cfg80211_testmode_reply
+!Finclude/net/cfg80211.h cfg80211_testmode_alloc_event_skb
+!Finclude/net/cfg80211.h cfg80211_testmode_event
+ </chapter>
+ </book>
+ <book id="mac80211-developers-guide">
+ <bookinfo>
+ <title>The mac80211 subsystem</title>
+ <abstract>
+!Pinclude/net/mac80211.h Introduction
+!Pinclude/net/mac80211.h Warning
+ </abstract>
+ </bookinfo>
+
+ <toc></toc>
+
+ <!--
+ Generally, this document shall be ordered by increasing complexity.
+ It is important to note that readers should be able to read only
+ the first few sections to get a working driver and only advanced
+ usage should require reading the full document.
+ -->
+
+ <part>
+ <title>The basic mac80211 driver interface</title>
+ <partintro>
+ <para>
+ You should read and understand the information contained
+ within this part of the book while implementing a driver.
+ In some chapters, advanced usage is noted, that may be
+ skipped at first.
+ </para>
+ <para>
+ This part of the book only covers station and monitor mode
+ functionality, additional information required to implement
+ the other modes is covered in the second part of the book.
+ </para>
+ </partintro>
+
+ <chapter id="basics">
+ <title>Basic hardware handling</title>
+ <para>TBD</para>
+ <para>
+ This chapter shall contain information on getting a hw
+ struct allocated and registered with mac80211.
+ </para>
+ <para>
+ Since it is required to allocate rates/modes before registering
+ a hw struct, this chapter shall also contain information on setting
+ up the rate/mode structs.
+ </para>
+ <para>
+ Additionally, some discussion about the callbacks and
+ the general programming model should be in here, including
+ the definition of ieee80211_ops which will be referred to
+ a lot.
+ </para>
+ <para>
+ Finally, a discussion of hardware capabilities should be done
+ with references to other parts of the book.
+ </para>
+ <!-- intentionally multiple !F lines to get proper order -->
+!Finclude/net/mac80211.h ieee80211_hw
+!Finclude/net/mac80211.h ieee80211_hw_flags
+!Finclude/net/mac80211.h SET_IEEE80211_DEV
+!Finclude/net/mac80211.h SET_IEEE80211_PERM_ADDR
+!Finclude/net/mac80211.h ieee80211_ops
+!Finclude/net/mac80211.h ieee80211_alloc_hw
+!Finclude/net/mac80211.h ieee80211_register_hw
+!Finclude/net/mac80211.h ieee80211_get_tx_led_name
+!Finclude/net/mac80211.h ieee80211_get_rx_led_name
+!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
+!Finclude/net/mac80211.h ieee80211_get_radio_led_name
+!Finclude/net/mac80211.h ieee80211_unregister_hw
+!Finclude/net/mac80211.h ieee80211_free_hw
+ </chapter>
+
+ <chapter id="phy-handling">
+ <title>PHY configuration</title>
+ <para>TBD</para>
+ <para>
+ This chapter should describe PHY handling including
+ start/stop callbacks and the various structures used.
+ </para>
+!Finclude/net/mac80211.h ieee80211_conf
+!Finclude/net/mac80211.h ieee80211_conf_flags
+ </chapter>
+
+ <chapter id="iface-handling">
+ <title>Virtual interfaces</title>
+ <para>TBD</para>
+ <para>
+ This chapter should describe virtual interface basics
+ that are relevant to the driver (VLANs, MGMT etc are not.)
+ It should explain the use of the add_iface/remove_iface
+ callbacks as well as the interface configuration callbacks.
+ </para>
+ <para>Things related to AP mode should be discussed there.</para>
+ <para>
+ Things related to supporting multiple interfaces should be
+ in the appropriate chapter, a BIG FAT note should be here about
+ this though and the recommendation to allow only a single
+ interface in STA mode at first!
+ </para>
+!Finclude/net/mac80211.h ieee80211_vif
+ </chapter>
+
+ <chapter id="rx-tx">
+ <title>Receive and transmit processing</title>
+ <sect1>
+ <title>what should be here</title>
+ <para>TBD</para>
+ <para>
+ This should describe the receive and transmit
+ paths in mac80211/the drivers as well as
+ transmit status handling.
+ </para>
+ </sect1>
+ <sect1>
+ <title>Frame format</title>
+!Pinclude/net/mac80211.h Frame format
+ </sect1>
+ <sect1>
+ <title>Packet alignment</title>
+!Pnet/mac80211/rx.c Packet alignment
+ </sect1>
+ <sect1>
+ <title>Calling into mac80211 from interrupts</title>
+!Pinclude/net/mac80211.h Calling mac80211 from interrupts
+ </sect1>
+ <sect1>
+ <title>functions/definitions</title>
+!Finclude/net/mac80211.h ieee80211_rx_status
+!Finclude/net/mac80211.h mac80211_rx_flags
+!Finclude/net/mac80211.h ieee80211_tx_info
+!Finclude/net/mac80211.h ieee80211_rx
+!Finclude/net/mac80211.h ieee80211_rx_irqsafe
+!Finclude/net/mac80211.h ieee80211_tx_status
+!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe
+!Finclude/net/mac80211.h ieee80211_rts_get
+!Finclude/net/mac80211.h ieee80211_rts_duration
+!Finclude/net/mac80211.h ieee80211_ctstoself_get
+!Finclude/net/mac80211.h ieee80211_ctstoself_duration
+!Finclude/net/mac80211.h ieee80211_generic_frame_duration
+!Finclude/net/mac80211.h ieee80211_wake_queue
+!Finclude/net/mac80211.h ieee80211_stop_queue
+!Finclude/net/mac80211.h ieee80211_wake_queues
+!Finclude/net/mac80211.h ieee80211_stop_queues
+ </sect1>
+ </chapter>
+
+ <chapter id="filters">
+ <title>Frame filtering</title>
+!Pinclude/net/mac80211.h Frame filtering
+!Finclude/net/mac80211.h ieee80211_filter_flags
+ </chapter>
+ </part>
+
+ <part id="advanced">
+ <title>Advanced driver interface</title>
+ <partintro>
+ <para>
+ Information contained within this part of the book is
+ of interest only for advanced interaction of mac80211
+ with drivers to exploit more hardware capabilities and
+ improve performance.
+ </para>
+ </partintro>
+
+ <chapter id="hardware-crypto-offload">
+ <title>Hardware crypto acceleration</title>
+!Pinclude/net/mac80211.h Hardware crypto acceleration
+ <!-- intentionally multiple !F lines to get proper order -->
+!Finclude/net/mac80211.h set_key_cmd
+!Finclude/net/mac80211.h ieee80211_key_conf
+!Finclude/net/mac80211.h ieee80211_key_flags
+ </chapter>
+
+ <chapter id="powersave">
+ <title>Powersave support</title>
+!Pinclude/net/mac80211.h Powersave support
+ </chapter>
+
+ <chapter id="beacon-filter">
+ <title>Beacon filter support</title>
+!Pinclude/net/mac80211.h Beacon filter support
+!Finclude/net/mac80211.h ieee80211_beacon_loss
+ </chapter>
+
+ <chapter id="qos">
+ <title>Multiple queues and QoS support</title>
+ <para>TBD</para>
+!Finclude/net/mac80211.h ieee80211_tx_queue_params
+ </chapter>
+
+ <chapter id="AP">
+ <title>Access point mode support</title>
+ <para>TBD</para>
+ <para>Some parts of the if_conf should be discussed here instead</para>
+ <para>
+ Insert notes about VLAN interfaces with hw crypto here or
+ in the hw crypto chapter.
+ </para>
+!Finclude/net/mac80211.h ieee80211_get_buffered_bc
+!Finclude/net/mac80211.h ieee80211_beacon_get
+ </chapter>
+
+ <chapter id="multi-iface">
+ <title>Supporting multiple virtual interfaces</title>
+ <para>TBD</para>
+ <para>
+ Note: WDS with identical MAC address should almost always be OK
+ </para>
+ <para>
+ Insert notes about having multiple virtual interfaces with
+ different MAC addresses here, note which configurations are
+ supported by mac80211, add notes about supporting hw crypto
+ with it.
+ </para>
+ </chapter>
+
+ <chapter id="hardware-scan-offload">
+ <title>Hardware scan offload</title>
+ <para>TBD</para>
+!Finclude/net/mac80211.h ieee80211_scan_completed
+ </chapter>
+ </part>
+
+ <part id="rate-control">
+ <title>Rate control interface</title>
+ <partintro>
+ <para>TBD</para>
+ <para>
+ This part of the book describes the rate control algorithm
+ interface and how it relates to mac80211 and drivers.
+ </para>
+ </partintro>
+ <chapter id="dummy">
+ <title>dummy chapter</title>
+ <para>TBD</para>
+ </chapter>
+ </part>
+
+ <part id="internal">
+ <title>Internals</title>
+ <partintro>
+ <para>TBD</para>
+ <para>
+ This part of the book describes mac80211 internals.
+ </para>
+ </partintro>
+
+ <chapter id="key-handling">
+ <title>Key handling</title>
+ <sect1>
+ <title>Key handling basics</title>
+!Pnet/mac80211/key.c Key handling basics
+ </sect1>
+ <sect1>
+ <title>MORE TBD</title>
+ <para>TBD</para>
+ </sect1>
+ </chapter>
+
+ <chapter id="rx-processing">
+ <title>Receive processing</title>
+ <para>TBD</para>
+ </chapter>
+
+ <chapter id="tx-processing">
+ <title>Transmit processing</title>
+ <para>TBD</para>
+ </chapter>
+
+ <chapter id="sta-info">
+ <title>Station info handling</title>
+ <sect1>
+ <title>Programming information</title>
+!Fnet/mac80211/sta_info.h sta_info
+!Fnet/mac80211/sta_info.h ieee80211_sta_info_flags
+ </sect1>
+ <sect1>
+ <title>STA information lifetime rules</title>
+!Pnet/mac80211/sta_info.c STA information lifetime rules
+ </sect1>
+ </chapter>
+
+ <chapter id="synchronisation">
+ <title>Synchronisation</title>
+ <para>TBD</para>
+ <para>Locking, lots of RCU</para>
+ </chapter>
+ </part>
+ </book>
+</set>
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 34929f24c284..8b6e00a71034 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -12,7 +12,7 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
- mac80211.xml debugobjects.xml sh.xml regulator.xml \
+ 80211.xml debugobjects.xml sh.xml regulator.xml \
alsa-driver-api.xml writing-an-alsa-driver.xml \
tracepoint.xml media.xml drm.xml
diff --git a/Documentation/DocBook/mac80211.tmpl b/Documentation/DocBook/mac80211.tmpl
deleted file mode 100644
index affb15a344a1..000000000000
--- a/Documentation/DocBook/mac80211.tmpl
+++ /dev/null
@@ -1,337 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="mac80211-developers-guide">
- <bookinfo>
- <title>The mac80211 subsystem for kernel developers</title>
-
- <authorgroup>
- <author>
- <firstname>Johannes</firstname>
- <surname>Berg</surname>
- <affiliation>
- <address><email>johannes@sipsolutions.net</email></address>
- </affiliation>
- </author>
- </authorgroup>
-
- <copyright>
- <year>2007-2009</year>
- <holder>Johannes Berg</holder>
- </copyright>
-
- <legalnotice>
- <para>
- This documentation 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.
- </para>
-
- <para>
- This documentation 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.
- </para>
-
- <para>
- You should have received a copy of the GNU General Public
- License along with this documentation; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- </para>
-
- <para>
- For more details see the file COPYING in the source
- distribution of Linux.
- </para>
- </legalnotice>
-
- <abstract>
-!Pinclude/net/mac80211.h Introduction
-!Pinclude/net/mac80211.h Warning
- </abstract>
- </bookinfo>
-
- <toc></toc>
-
-<!--
-Generally, this document shall be ordered by increasing complexity.
-It is important to note that readers should be able to read only
-the first few sections to get a working driver and only advanced
-usage should require reading the full document.
--->
-
- <part>
- <title>The basic mac80211 driver interface</title>
- <partintro>
- <para>
- You should read and understand the information contained
- within this part of the book while implementing a driver.
- In some chapters, advanced usage is noted, that may be
- skipped at first.
- </para>
- <para>
- This part of the book only covers station and monitor mode
- functionality, additional information required to implement
- the other modes is covered in the second part of the book.
- </para>
- </partintro>
-
- <chapter id="basics">
- <title>Basic hardware handling</title>
- <para>TBD</para>
- <para>
- This chapter shall contain information on getting a hw
- struct allocated and registered with mac80211.
- </para>
- <para>
- Since it is required to allocate rates/modes before registering
- a hw struct, this chapter shall also contain information on setting
- up the rate/mode structs.
- </para>
- <para>
- Additionally, some discussion about the callbacks and
- the general programming model should be in here, including
- the definition of ieee80211_ops which will be referred to
- a lot.
- </para>
- <para>
- Finally, a discussion of hardware capabilities should be done
- with references to other parts of the book.
- </para>
-<!-- intentionally multiple !F lines to get proper order -->
-!Finclude/net/mac80211.h ieee80211_hw
-!Finclude/net/mac80211.h ieee80211_hw_flags
-!Finclude/net/mac80211.h SET_IEEE80211_DEV
-!Finclude/net/mac80211.h SET_IEEE80211_PERM_ADDR
-!Finclude/net/mac80211.h ieee80211_ops
-!Finclude/net/mac80211.h ieee80211_alloc_hw
-!Finclude/net/mac80211.h ieee80211_register_hw
-!Finclude/net/mac80211.h ieee80211_get_tx_led_name
-!Finclude/net/mac80211.h ieee80211_get_rx_led_name
-!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
-!Finclude/net/mac80211.h ieee80211_get_radio_led_name
-!Finclude/net/mac80211.h ieee80211_unregister_hw
-!Finclude/net/mac80211.h ieee80211_free_hw
- </chapter>
-
- <chapter id="phy-handling">
- <title>PHY configuration</title>
- <para>TBD</para>
- <para>
- This chapter should describe PHY handling including
- start/stop callbacks and the various structures used.
- </para>
-!Finclude/net/mac80211.h ieee80211_conf
-!Finclude/net/mac80211.h ieee80211_conf_flags
- </chapter>
-
- <chapter id="iface-handling">
- <title>Virtual interfaces</title>
- <para>TBD</para>
- <para>
- This chapter should describe virtual interface basics
- that are relevant to the driver (VLANs, MGMT etc are not.)
- It should explain the use of the add_iface/remove_iface
- callbacks as well as the interface configuration callbacks.
- </para>
- <para>Things related to AP mode should be discussed there.</para>
- <para>
- Things related to supporting multiple interfaces should be
- in the appropriate chapter, a BIG FAT note should be here about
- this though and the recommendation to allow only a single
- interface in STA mode at first!
- </para>
-!Finclude/net/mac80211.h ieee80211_vif
- </chapter>
-
- <chapter id="rx-tx">
- <title>Receive and transmit processing</title>
- <sect1>
- <title>what should be here</title>
- <para>TBD</para>
- <para>
- This should describe the receive and transmit
- paths in mac80211/the drivers as well as
- transmit status handling.
- </para>
- </sect1>
- <sect1>
- <title>Frame format</title>
-!Pinclude/net/mac80211.h Frame format
- </sect1>
- <sect1>
- <title>Packet alignment</title>
-!Pnet/mac80211/rx.c Packet alignment
- </sect1>
- <sect1>
- <title>Calling into mac80211 from interrupts</title>
-!Pinclude/net/mac80211.h Calling mac80211 from interrupts
- </sect1>
- <sect1>
- <title>functions/definitions</title>
-!Finclude/net/mac80211.h ieee80211_rx_status
-!Finclude/net/mac80211.h mac80211_rx_flags
-!Finclude/net/mac80211.h ieee80211_tx_info
-!Finclude/net/mac80211.h ieee80211_rx
-!Finclude/net/mac80211.h ieee80211_rx_irqsafe
-!Finclude/net/mac80211.h ieee80211_tx_status
-!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe
-!Finclude/net/mac80211.h ieee80211_rts_get
-!Finclude/net/mac80211.h ieee80211_rts_duration
-!Finclude/net/mac80211.h ieee80211_ctstoself_get
-!Finclude/net/mac80211.h ieee80211_ctstoself_duration
-!Finclude/net/mac80211.h ieee80211_generic_frame_duration
-!Finclude/net/mac80211.h ieee80211_wake_queue
-!Finclude/net/mac80211.h ieee80211_stop_queue
-!Finclude/net/mac80211.h ieee80211_wake_queues
-!Finclude/net/mac80211.h ieee80211_stop_queues
- </sect1>
- </chapter>
-
- <chapter id="filters">
- <title>Frame filtering</title>
-!Pinclude/net/mac80211.h Frame filtering
-!Finclude/net/mac80211.h ieee80211_filter_flags
- </chapter>
- </part>
-
- <part id="advanced">
- <title>Advanced driver interface</title>
- <partintro>
- <para>
- Information contained within this part of the book is
- of interest only for advanced interaction of mac80211
- with drivers to exploit more hardware capabilities and
- improve performance.
- </para>
- </partintro>
-
- <chapter id="hardware-crypto-offload">
- <title>Hardware crypto acceleration</title>
-!Pinclude/net/mac80211.h Hardware crypto acceleration
-<!-- intentionally multiple !F lines to get proper order -->
-!Finclude/net/mac80211.h set_key_cmd
-!Finclude/net/mac80211.h ieee80211_key_conf
-!Finclude/net/mac80211.h ieee80211_key_alg
-!Finclude/net/mac80211.h ieee80211_key_flags
- </chapter>
-
- <chapter id="powersave">
- <title>Powersave support</title>
-!Pinclude/net/mac80211.h Powersave support
- </chapter>
-
- <chapter id="beacon-filter">
- <title>Beacon filter support</title>
-!Pinclude/net/mac80211.h Beacon filter support
-!Finclude/net/mac80211.h ieee80211_beacon_loss
- </chapter>
-
- <chapter id="qos">
- <title>Multiple queues and QoS support</title>
- <para>TBD</para>
-!Finclude/net/mac80211.h ieee80211_tx_queue_params
- </chapter>
-
- <chapter id="AP">
- <title>Access point mode support</title>
- <para>TBD</para>
- <para>Some parts of the if_conf should be discussed here instead</para>
- <para>
- Insert notes about VLAN interfaces with hw crypto here or
- in the hw crypto chapter.
- </para>
-!Finclude/net/mac80211.h ieee80211_get_buffered_bc
-!Finclude/net/mac80211.h ieee80211_beacon_get
- </chapter>
-
- <chapter id="multi-iface">
- <title>Supporting multiple virtual interfaces</title>
- <para>TBD</para>
- <para>
- Note: WDS with identical MAC address should almost always be OK
- </para>
- <para>
- Insert notes about having multiple virtual interfaces with
- different MAC addresses here, note which configurations are
- supported by mac80211, add notes about supporting hw crypto
- with it.
- </para>
- </chapter>
-
- <chapter id="hardware-scan-offload">
- <title>Hardware scan offload</title>
- <para>TBD</para>
-!Finclude/net/mac80211.h ieee80211_scan_completed
- </chapter>
- </part>
-
- <part id="rate-control">
- <title>Rate control interface</title>
- <partintro>
- <para>TBD</para>
- <para>
- This part of the book describes the rate control algorithm
- interface and how it relates to mac80211 and drivers.
- </para>
- </partintro>
- <chapter id="dummy">
- <title>dummy chapter</title>
- <para>TBD</para>
- </chapter>
- </part>
-
- <part id="internal">
- <title>Internals</title>
- <partintro>
- <para>TBD</para>
- <para>
- This part of the book describes mac80211 internals.
- </para>
- </partintro>
-
- <chapter id="key-handling">
- <title>Key handling</title>
- <sect1>
- <title>Key handling basics</title>
-!Pnet/mac80211/key.c Key handling basics
- </sect1>
- <sect1>
- <title>MORE TBD</title>
- <para>TBD</para>
- </sect1>
- </chapter>
-
- <chapter id="rx-processing">
- <title>Receive processing</title>
- <para>TBD</para>
- </chapter>
-
- <chapter id="tx-processing">
- <title>Transmit processing</title>
- <para>TBD</para>
- </chapter>
-
- <chapter id="sta-info">
- <title>Station info handling</title>
- <sect1>
- <title>Programming information</title>
-!Fnet/mac80211/sta_info.h sta_info
-!Fnet/mac80211/sta_info.h ieee80211_sta_info_flags
- </sect1>
- <sect1>
- <title>STA information lifetime rules</title>
-!Pnet/mac80211/sta_info.c STA information lifetime rules
- </sect1>
- </chapter>
-
- <chapter id="synchronisation">
- <title>Synchronisation</title>
- <para>TBD</para>
- <para>Locking, lots of RCU</para>
- </chapter>
- </part>
-</book>
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 5e2bc4ab897a..9961f1564d22 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -536,3 +536,12 @@ Who: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
----------------------------
+What: iwlwifi disable_hw_scan module parameters
+When: 2.6.40
+Why: Hareware scan is the prefer method for iwlwifi devices for
+ scanning operation. Remove software scan support for all the
+ iwlwifi devices.
+
+Who: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+
+----------------------------
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index d2b62b71b617..5dc638791d97 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -765,6 +765,14 @@ xmit_hash_policy
does not exist, and the layer2 policy is the only policy. The
layer2+3 value was added for bonding version 3.2.2.
+resend_igmp
+
+ Specifies the number of IGMP membership reports to be issued after
+ a failover event. One membership report is issued immediately after
+ the failover, subsequent packets are sent in each 200ms interval.
+
+ The valid range is 0 - 255; the default value is 1. This option
+ was added for bonding version 3.7.0.
3. Configuring Bonding Devices
==============================
diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt
index cd79735013f9..5b04b67ddca2 100644
--- a/Documentation/networking/can.txt
+++ b/Documentation/networking/can.txt
@@ -22,6 +22,7 @@ This file contains
4.1.2 RAW socket option CAN_RAW_ERR_FILTER
4.1.3 RAW socket option CAN_RAW_LOOPBACK
4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS
+ 4.1.5 RAW socket returned message flags
4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
4.3 connected transport protocols (SOCK_SEQPACKET)
4.4 unconnected transport protocols (SOCK_DGRAM)
@@ -471,6 +472,17 @@ solution for a couple of reasons:
setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
&recv_own_msgs, sizeof(recv_own_msgs));
+ 4.1.5 RAW socket returned message flags
+
+ When using recvmsg() call, the msg->msg_flags may contain following flags:
+
+ MSG_DONTROUTE: set when the received frame was created on the local host.
+
+ MSG_CONFIRM: set when the frame was sent via the socket it is received on.
+ This flag can be interpreted as a 'transmission confirmation' when the
+ CAN driver supports the echo of frames on driver level, see 3.2 and 6.2.
+ In order to receive such messages, CAN_RAW_RECV_OWN_MSGS must be set.
+
4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
4.3 connected transport protocols (SOCK_SEQPACKET)
4.4 unconnected transport protocols (SOCK_DGRAM)
diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt
index a62fdf7a6bff..271d524a4c8d 100644
--- a/Documentation/networking/dccp.txt
+++ b/Documentation/networking/dccp.txt
@@ -1,18 +1,20 @@
DCCP protocol
-============
+=============
Contents
========
-
- Introduction
- Missing features
- Socket options
+- Sysctl variables
+- IOCTLs
+- Other tunables
- Notes
+
Introduction
============
-
Datagram Congestion Control Protocol (DCCP) is an unreliable, connection
oriented protocol designed to solve issues present in UDP and TCP, particularly
for real-time and multimedia (streaming) traffic.
@@ -29,9 +31,9 @@ It has a base protocol and pluggable congestion control IDs (CCIDs).
DCCP is a Proposed Standard (RFC 2026), and the homepage for DCCP as a protocol
is at http://www.ietf.org/html.charters/dccp-charter.html
+
Missing features
================
-
The Linux DCCP implementation does not currently support all the features that are
specified in RFCs 4340...42.
@@ -45,7 +47,6 @@ http://linux-net.osdl.org/index.php/DCCP_Testing#Experimental_DCCP_source_tree
Socket options
==============
-
DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of
service codes (RFC 4340, sec. 8.1.2); if this socket option is not set,
the socket will fall back to 0 (which means that no meaningful service code
@@ -112,6 +113,7 @@ DCCP_SOCKOPT_CCID_TX_INFO
On unidirectional connections it is useful to close the unused half-connection
via shutdown (SHUT_WR or SHUT_RD): this will reduce per-packet processing costs.
+
Sysctl variables
================
Several DCCP default parameters can be managed by the following sysctls
@@ -155,15 +157,30 @@ sync_ratelimit = 125 ms
sequence-invalid packets on the same socket (RFC 4340, 7.5.4). The unit
of this parameter is milliseconds; a value of 0 disables rate-limiting.
+
IOCTLS
======
FIONREAD
Works as in udp(7): returns in the `int' argument pointer the size of
the next pending datagram in bytes, or 0 when no datagram is pending.
+
+Other tunables
+==============
+Per-route rto_min support
+ CCID-2 supports the RTAX_RTO_MIN per-route setting for the minimum value
+ of the RTO timer. This setting can be modified via the 'rto_min' option
+ of iproute2; for example:
+ > ip route change 10.0.0.0/24 rto_min 250j dev wlan0
+ > ip route add 10.0.0.254/32 rto_min 800j dev wlan0
+ > ip route show dev wlan0
+ CCID-3 also supports the rto_min setting: it is used to define the lower
+ bound for the expiry of the nofeedback timer. This can be useful on LANs
+ with very low RTTs (e.g., loopback, Gbit ethernet).
+
+
Notes
=====
-
DCCP does not travel through NAT successfully at present on many boxes. This is
because the checksum covers the pseudo-header as per TCP and UDP. Linux NAT
support for DCCP has been added.
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index f350c69b2bb4..c7165f4cb792 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1014,6 +1014,12 @@ conf/interface/*:
accept_ra - BOOLEAN
Accept Router Advertisements; autoconfigure using them.
+ Possible values are:
+ 0 Do not accept Router Advertisements.
+ 1 Accept Router Advertisements if forwarding is disabled.
+ 2 Overrule forwarding behaviour. Accept Router Advertisements
+ even if forwarding is enabled.
+
Functional default: enabled if local forwarding is disabled.
disabled if local forwarding is enabled.
@@ -1075,7 +1081,12 @@ forwarding - BOOLEAN
Note: It is recommended to have the same setting on all
interfaces; mixed router/host scenarios are rather uncommon.
- FALSE:
+ Possible values are:
+ 0 Forwarding disabled
+ 1 Forwarding enabled
+ 2 Forwarding enabled (Hybrid Mode)
+
+ FALSE (0):
By default, Host behaviour is assumed. This means:
@@ -1085,18 +1096,24 @@ forwarding - BOOLEAN
Advertisements (and do autoconfiguration).
4. If accept_redirects is TRUE (default), accept Redirects.
- TRUE:
+ TRUE (1):
If local forwarding is enabled, Router behaviour is assumed.
This means exactly the reverse from the above:
1. IsRouter flag is set in Neighbour Advertisements.
2. Router Solicitations are not sent.
- 3. Router Advertisements are ignored.
+ 3. Router Advertisements are ignored unless accept_ra is 2.
4. Redirects are ignored.
- Default: FALSE if global forwarding is disabled (default),
- otherwise TRUE.
+ TRUE (2):
+
+ Hybrid mode. Same behaviour as TRUE, except for:
+
+ 2. Router Solicitations are being sent when necessary.
+
+ Default: 0 (disabled) if global forwarding is disabled (default),
+ otherwise 1 (enabled).
hop_limit - INTEGER
Default Hop Limit to set.
diff --git a/Documentation/networking/phonet.txt b/Documentation/networking/phonet.txt
index 6e8ce09f9c73..24ad2adba6e5 100644
--- a/Documentation/networking/phonet.txt
+++ b/Documentation/networking/phonet.txt
@@ -112,6 +112,22 @@ However, connect() and getpeername() are not supported, as they did
not seem useful with Phonet usages (could be added easily).
+Resource subscription
+---------------------
+
+A Phonet datagram socket can be subscribed to any number of 8-bits
+Phonet resources, as follow:
+
+ uint32_t res = 0xXX;
+ ioctl(fd, SIOCPNADDRESOURCE, &res);
+
+Subscription is similarly cancelled using the SIOCPNDELRESOURCE I/O
+control request, or when the socket is closed.
+
+Note that no more than one socket can be subcribed to any given
+resource at a time. If not, ioctl() will return EBUSY.
+
+
Phonet Pipe protocol
--------------------
@@ -166,6 +182,46 @@ The pipe protocol provides two socket options at the SOL_PNPIPE level:
or zero if encapsulation is off.
+Phonet Pipe-controller Implementation
+-------------------------------------
+
+Phonet Pipe-controller is enabled by selecting the CONFIG_PHONET_PIPECTRLR Kconfig
+option. It is useful when communicating with those Nokia Modems which do not
+implement Pipe controller in them e.g. Nokia Slim Modem used in ST-Ericsson
+U8500 platform.
+
+The implementation is based on the Data Connection Establishment Sequence
+depicted in 'Nokia Wireless Modem API - Wireless_modem_user_guide.pdf'
+document.
+
+It allows a phonet sequenced socket (host-pep) to initiate a Pipe connection
+between itself and a remote pipe-end point (e.g. modem).
+
+The implementation adds socket options at SOL_PNPIPE level:
+
+ PNPIPE_PIPE_HANDLE
+ It accepts an integer argument for setting value of pipe handle.
+
+ PNPIPE_ENABLE accepts one integer value (int). If set to zero, the pipe
+ is disabled. If the value is non-zero, the pipe is enabled. If the pipe
+ is not (yet) connected, ENOTCONN is error is returned.
+
+The implementation also adds socket 'connect'. On calling the 'connect', pipe
+will be created between the source socket and the destination, and the pipe
+state will be set to PIPE_DISABLED.
+
+After a pipe has been created and enabled successfully, the Pipe data can be
+exchanged between the host-pep and remote-pep (modem).
+
+User-space would typically follow below sequence with Pipe controller:-
+-socket
+-bind
+-setsockopt for PNPIPE_PIPE_HANDLE
+-connect
+-setsockopt for PNPIPE_ENCAP_IP
+-setsockopt for PNPIPE_ENABLE
+
+
Authors
-------
diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt
index e8c8f4f06c67..98097d8cb910 100644
--- a/Documentation/networking/timestamping.txt
+++ b/Documentation/networking/timestamping.txt
@@ -172,15 +172,19 @@ struct skb_shared_hwtstamps {
};
Time stamps for outgoing packets are to be generated as follows:
-- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero.
- If yes, then the driver is expected to do hardware time stamping.
+- In hard_start_xmit(), check if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+ is set no-zero. If yes, then the driver is expected to do hardware time
+ stamping.
- If this is possible for the skb and requested, then declare
- that the driver is doing the time stamping by setting the field
- skb_tx(skb)->in_progress non-zero. You might want to keep a pointer
- to the associated skb for the next step and not free the skb. A driver
- not supporting hardware time stamping doesn't do that. A driver must
- never touch sk_buff::tstamp! It is used to store software generated
- time stamps by the network subsystem.
+ that the driver is doing the time stamping by setting the flag
+ SKBTX_IN_PROGRESS in skb_shinfo(skb)->tx_flags , e.g. with
+
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
+ You might want to keep a pointer to the associated skb for the next step
+ and not free the skb. A driver not supporting hardware time stamping doesn't
+ do that. A driver must never touch sk_buff::tstamp! It is used to store
+ software generated time stamps by the network subsystem.
- As soon as the driver has sent the packet and/or obtained a
hardware time stamp for it, it passes the time stamp back by
calling skb_hwtstamp_tx() with the original skb, the raw
@@ -191,6 +195,6 @@ Time stamps for outgoing packets are to be generated as follows:
this would occur at a later time in the processing pipeline than other
software time stamping and therefore could lead to unexpected deltas
between time stamps.
-- If the driver did not call set skb_tx(skb)->in_progress, then
+- If the driver did not set the SKBTX_IN_PROGRESS flag (see above), then
dev_hard_start_xmit() checks whether software time stamping
is wanted as fallback and potentially generates the time stamp.
diff --git a/MAINTAINERS b/MAINTAINERS
index 9a0432de9141..494e1a07366a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1151,6 +1151,13 @@ W: http://wireless.kernel.org/en/users/Drivers/ar9170
S: Maintained
F: drivers/net/wireless/ath/ar9170/
+CARL9170 LINUX COMMUNITY WIRELESS DRIVER
+M: Christian Lamparter <chunkeey@googlemail.com>
+L: linux-wireless@vger.kernel.org
+W: http://wireless.kernel.org/en/users/Drivers/carl9170
+S: Maintained
+F: drivers/net/wireless/ath/carl9170/
+
ATK0110 HWMON DRIVER
M: Luca Tettamanti <kronos.it@gmail.com>
L: lm-sensors@lm-sensors.org
@@ -1375,16 +1382,19 @@ F: drivers/mtd/devices/block2mtd.c
BLUETOOTH DRIVERS
M: Marcel Holtmann <marcel@holtmann.org>
+M: Gustavo F. Padovan <padovan@profusion.mobi>
L: linux-bluetooth@vger.kernel.org
W: http://www.bluez.org/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git
S: Maintained
F: drivers/bluetooth/
BLUETOOTH SUBSYSTEM
M: Marcel Holtmann <marcel@holtmann.org>
+M: Gustavo F. Padovan <padovan@profusion.mobi>
L: linux-bluetooth@vger.kernel.org
W: http://www.bluez.org/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git
S: Maintained
F: net/bluetooth/
F: include/net/bluetooth/
@@ -1429,6 +1439,13 @@ L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/bfa/
+BROCADE BNA 10 GIGABIT ETHERNET DRIVER
+M: Rasesh Mody <rmody@brocade.com>
+M: Debashis Dutt <ddutt@brocade.com>
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/bna/
+
BSG (block layer generic sg v4 driver)
M: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
L: linux-scsi@vger.kernel.org
@@ -1586,9 +1603,9 @@ S: Supported
F: scripts/checkpatch.pl
CISCO VIC ETHERNET NIC DRIVER
-M: Scott Feldman <scofeldm@cisco.com>
M: Vasanthy Kolluri <vkolluri@cisco.com>
M: Roopa Prabhu <roprabhu@cisco.com>
+M: David Wang <dwang2@cisco.com>
S: Supported
F: drivers/net/enic/
@@ -2922,6 +2939,12 @@ M: Brian King <brking@us.ibm.com>
S: Supported
F: drivers/scsi/ipr.*
+IBM Power Virtual Ethernet Device Driver
+M: Santiago Leon <santil@linux.vnet.ibm.com>
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/ibmveth.*
+
IBM ServeRAID RAID DRIVER
P: Jack Hammer
M: Dave Jeffery <ipslinux@adaptec.com>
@@ -4392,13 +4415,12 @@ F: Documentation/filesystems/dlmfs.txt
F: fs/ocfs2/
ORINOCO DRIVER
-M: Pavel Roskin <proski@gnu.org>
-M: David Gibson <hermes@gibson.dropbear.id.au>
L: linux-wireless@vger.kernel.org
L: orinoco-users@lists.sourceforge.net
L: orinoco-devel@lists.sourceforge.net
+W: http://linuxwireless.org/en/users/Drivers/orinoco
W: http://www.nongnu.org/orinoco/
-S: Maintained
+S: Orphan
F: drivers/net/wireless/orinoco/
OSD LIBRARY and FILESYSTEM
@@ -4586,6 +4608,14 @@ L: linux-abi-devel@lists.sourceforge.net
S: Maintained
F: include/linux/personality.h
+PHONET PROTOCOL
+M: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
+S: Supported
+F: Documentation/networking/phonet.txt
+F: include/linux/phonet.h
+F: include/net/phonet/
+F: net/phonet/
+
PHRAM MTD DRIVER
M: Joern Engel <joern@lazybastard.org>
L: linux-mtd@lists.infradead.org
@@ -6489,21 +6519,21 @@ S: Maintained
F: drivers/input/misc/wistron_btns.c
WL1251 WIRELESS DRIVER
-M: Kalle Valo <kalle.valo@iki.fi>
+M: Kalle Valo <kvalo@adurom.com>
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
S: Maintained
-F: drivers/net/wireless/wl12xx/*
-X: drivers/net/wireless/wl12xx/wl1271*
+F: drivers/net/wireless/wl1251/*
WL1271 WIRELESS DRIVER
M: Luciano Coelho <luciano.coelho@nokia.com>
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
S: Maintained
F: drivers/net/wireless/wl12xx/wl1271*
+F: include/linux/wl12xx.h
WL3501 WIRELESS PCMCIA CARD DRIVER
M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
@@ -6650,6 +6680,20 @@ M: "Maciej W. Rozycki" <macro@linux-mips.org>
S: Maintained
F: drivers/serial/zs.*
+GRE DEMULTIPLEXER DRIVER
+M: Dmitry Kozlov <xeb@mail.ru>
+L: netdev@vger.kernel.org
+S: Maintained
+F: net/ipv4/gre.c
+F: include/net/gre.h
+
+PPTP DRIVER
+M: Dmitry Kozlov <xeb@mail.ru>
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/pptp.c
+W: http://sourceforge.net/projects/accel-pptp
+
THE REST
M: Linus Torvalds <torvalds@linux-foundation.org>
L: linux-kernel@vger.kernel.org
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index b7d6df4e3cf9..41d6f549070c 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -25,7 +25,7 @@
#include <linux/spi/ads7846.h>
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/leds.h>
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 9a5eb87425fc..ce28a851dcd3 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -14,7 +14,7 @@
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
#include <linux/i2c.h>
#include <linux/i2c/twl.h>
#include <linux/clk.h>
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 6b3984964cc5..189a6d1600b2 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -16,6 +16,8 @@
#include <linux/gpio.h>
#include <linux/i2c/twl.h>
#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/wl12xx.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -27,6 +29,9 @@
#include "mux.h"
#include "hsmmc.h"
+#define OMAP_ZOOM_WLAN_PMENA_GPIO (101)
+#define OMAP_ZOOM_WLAN_IRQ_GPIO (162)
+
/* Zoom2 has Qwerty keyboard*/
static int board_keymap[] = {
KEY(0, 0, KEY_E),
@@ -106,6 +111,11 @@ static struct regulator_consumer_supply zoom_vmmc2_supply = {
.supply = "vmmc",
};
+static struct regulator_consumer_supply zoom_vmmc3_supply = {
+ .supply = "vmmc",
+ .dev_name = "mmci-omap-hs.2",
+};
+
/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
static struct regulator_init_data zoom_vmmc1 = {
.constraints = {
@@ -151,6 +161,38 @@ static struct regulator_init_data zoom_vsim = {
.consumer_supplies = &zoom_vsim_supply,
};
+static struct regulator_init_data zoom_vmmc3 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &zoom_vmmc3_supply,
+};
+
+static struct fixed_voltage_config zoom_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = OMAP_ZOOM_WLAN_PMENA_GPIO,
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &zoom_vmmc3,
+};
+
+static struct platform_device omap_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &zoom_vwlan,
+ },
+};
+
+struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO),
+ /* ZOOM ref clock is 26 MHz */
+ .board_ref_clock = 1,
+};
+
static struct omap2_hsmmc_info mmc[] __initdata = {
{
.name = "external",
@@ -168,6 +210,14 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
.nonremovable = true,
.power_saving = true,
},
+ {
+ .name = "wl1271",
+ .mmc = 3,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .nonremovable = true,
+ },
{} /* Terminator */
};
@@ -279,7 +329,11 @@ static void enable_board_wakeup_source(void)
void __init zoom_peripherals_init(void)
{
+ if (wl12xx_set_platform_data(&omap_zoom_wlan_data))
+ pr_err("error setting wl12xx data\n");
+
omap_i2c_init();
+ platform_device_register(&omap_vwlan_device);
usb_musb_init(&musb_board_data);
enable_board_wakeup_source();
}
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index 2ba630276295..46e96bc1f5a1 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -360,6 +360,7 @@ struct qdio_initialize {
unsigned int no_output_qs;
qdio_handler_t *input_handler;
qdio_handler_t *output_handler;
+ void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
unsigned long int_parm;
void **input_sbal_addr_array;
void **output_sbal_addr_array;
@@ -377,11 +378,13 @@ struct qdio_initialize {
extern int qdio_allocate(struct qdio_initialize *);
extern int qdio_establish(struct qdio_initialize *);
extern int qdio_activate(struct ccw_device *);
-
-extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
- int q_nr, unsigned int bufnr, unsigned int count);
-extern int qdio_shutdown(struct ccw_device*, int);
+extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int,
+ unsigned int);
+extern int qdio_start_irq(struct ccw_device *, int);
+extern int qdio_stop_irq(struct ccw_device *, int);
+extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *);
+extern int qdio_shutdown(struct ccw_device *, int);
extern int qdio_free(struct ccw_device *);
-extern int qdio_get_ssqd_desc(struct ccw_device *dev, struct qdio_ssqd_desc*);
+extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *);
#endif /* __QDIO_H__ */
diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile
index 62c3cc1075ae..c6c9ee9f5da2 100644
--- a/drivers/atm/Makefile
+++ b/drivers/atm/Makefile
@@ -2,7 +2,7 @@
# Makefile for the Linux network (ATM) device drivers.
#
-fore_200e-objs := fore200e.o
+fore_200e-y := fore200e.o
obj-$(CONFIG_ATM_ZATM) += zatm.o uPD98402.o
obj-$(CONFIG_ATM_NICSTAR) += nicstar.o
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 8717809787fb..5d86bb803e94 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -444,8 +444,8 @@ static inline void fs_kfree_skb (struct sk_buff * skb)
#define ROUND_NEAREST 3
/********** make rate (not quite as much fun as Horizon) **********/
-static unsigned int make_rate (unsigned int rate, int r,
- u16 * bits, unsigned int * actual)
+static int make_rate(unsigned int rate, int r,
+ u16 *bits, unsigned int *actual)
{
unsigned char exp = -1; /* hush gcc */
unsigned int man = -1; /* hush gcc */
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 54720baa7363..a95790452a68 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -1645,10 +1645,8 @@ static int hrz_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) {
unsigned short d = 0;
char * s = skb->data;
if (*s++ == 'D') {
- for (i = 0; i < 4; ++i) {
- d = (d<<4) | ((*s <= '9') ? (*s - '0') : (*s - 'a' + 10));
- ++s;
- }
+ for (i = 0; i < 4; ++i)
+ d = (d << 4) | hex_to_bin(*s++);
PRINTK (KERN_INFO, "debug bitmap is now %hx", debug = d);
}
}
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index 1679cbf0c584..bce57328ddde 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -3152,7 +3152,7 @@ deinit_card(struct idt77252_dev *card)
}
-static int __devinit
+static void __devinit
init_sram(struct idt77252_dev *card)
{
int i;
@@ -3298,7 +3298,6 @@ init_sram(struct idt77252_dev *card)
SAR_REG_RXFD);
IPRINTK("%s: SRAM initialization complete.\n", card->name);
- return 0;
}
static int __devinit
@@ -3410,8 +3409,7 @@ init_card(struct atm_dev *dev)
writel(readl(SAR_REG_CFG) | conf, SAR_REG_CFG);
- if (init_sram(card) < 0)
- return -1;
+ init_sram(card);
/********************************************************************/
/* A L L O C R A M A N D S E T V A R I O U S T H I N G S */
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index 8cb0347dec28..9309d4724e13 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -220,7 +220,7 @@ static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) {
while (!desc_num || (dev->desc_tbl[desc_num -1]).timestamp) {
dev->ffL.tcq_rd += 2;
if (dev->ffL.tcq_rd > dev->ffL.tcq_ed)
- dev->ffL.tcq_rd = dev->ffL.tcq_st;
+ dev->ffL.tcq_rd = dev->ffL.tcq_st;
if (dev->ffL.tcq_rd == dev->host_tcq_wr)
return 0xFFFF;
desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd);
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 0d32ec82e9bf..548d1d9e4dda 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -117,8 +117,8 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
(event->data[2] == MODULE_ALREADY_UP)) ?
"Bring-up succeed" : "Bring-up failed");
- if (event->length > 3)
- priv->btmrvl_dev.dev_type = event->data[3];
+ if (event->length > 3 && event->data[3])
+ priv->btmrvl_dev.dev_type = HCI_AMP;
else
priv->btmrvl_dev.dev_type = HCI_BREDR;
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
index 76e5127884f0..792e32d29a1d 100644
--- a/drivers/bluetooth/btsdio.c
+++ b/drivers/bluetooth/btsdio.c
@@ -46,6 +46,9 @@ static const struct sdio_device_id btsdio_table[] = {
/* Generic Bluetooth Type-B SDIO device */
{ SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) },
+ /* Generic Bluetooth AMP controller */
+ { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_AMP) },
+
{ } /* Terminating entry */
};
@@ -329,6 +332,11 @@ static int btsdio_probe(struct sdio_func *func,
hdev->bus = HCI_SDIO;
hdev->driver_data = data;
+ if (id->class == SDIO_CLASS_BT_AMP)
+ hdev->dev_type = HCI_AMP;
+ else
+ hdev->dev_type = HCI_BREDR;
+
data->hdev = hdev;
SET_HCIDEV_DEV(hdev, &func->dev);
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index d22ce3cc611e..d120a5c1c093 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -59,9 +59,15 @@ static struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
+ /* Apple MacBookPro 7,1 */
+ { USB_DEVICE(0x05ac, 0x8213) },
+
/* Apple iMac11,1 */
{ USB_DEVICE(0x05ac, 0x8215) },
+ /* Apple MacBookPro6,2 */
+ { USB_DEVICE(0x05ac, 0x8218) },
+
/* AVM BlueFRITZ! USB v2.0 */
{ USB_DEVICE(0x057c, 0x3800) },
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 17361bad46dd..720148294e64 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -101,7 +101,7 @@ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
break;
case HCI_SCODATA_PKT:
- hdev->stat.cmd_tx++;
+ hdev->stat.sco_tx++;
break;
}
}
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 33f8421c71cc..18fdd9703b48 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -8,7 +8,6 @@
#include <linux/bug.h>
#include <linux/device.h>
-#include <linux/ethtool.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/highmem.h>
@@ -1361,17 +1360,6 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu)
return 0;
}
-static void fwnet_get_drvinfo(struct net_device *net,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, KBUILD_MODNAME);
- strcpy(info->bus_info, "ieee1394");
-}
-
-static const struct ethtool_ops fwnet_ethtool_ops = {
- .get_drvinfo = fwnet_get_drvinfo,
-};
-
static const struct net_device_ops fwnet_netdev_ops = {
.ndo_open = fwnet_open,
.ndo_stop = fwnet_stop,
@@ -1390,7 +1378,6 @@ static void fwnet_init_dev(struct net_device *net)
net->hard_header_len = FWNET_HLEN;
net->type = ARPHRD_IEEE1394;
net->tx_queue_len = 10;
- SET_ETHTOOL_OPS(net, &fwnet_ethtool_ops);
}
/* caller must hold fwnet_device_mutex */
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index bc289e367e30..63403822330e 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -58,7 +58,6 @@
#include <linux/tcp.h>
#include <linux/skbuff.h>
#include <linux/bitops.h>
-#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
#include <asm/unaligned.h>
@@ -173,8 +172,6 @@ static netdev_tx_t ether1394_tx(struct sk_buff *skb,
struct net_device *dev);
static void ether1394_iso(struct hpsb_iso *iso);
-static const struct ethtool_ops ethtool_ops;
-
static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
quadlet_t *data, u64 addr, size_t len, u16 flags);
static void ether1394_add_host(struct hpsb_host *host);
@@ -525,8 +522,6 @@ static void ether1394_init_dev(struct net_device *dev)
dev->header_ops = &ether1394_header_ops;
dev->netdev_ops = &ether1394_netdev_ops;
- SET_ETHTOOL_OPS(dev, &ethtool_ops);
-
dev->watchdog_timeo = ETHER1394_TIMEOUT;
dev->flags = IFF_BROADCAST | IFF_MULTICAST;
dev->features = NETIF_F_HIGHDMA;
@@ -1695,17 +1690,6 @@ fail:
return NETDEV_TX_OK;
}
-static void ether1394_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, driver_name);
- strcpy(info->bus_info, "ieee1394"); /* FIXME provide more detail? */
-}
-
-static const struct ethtool_ops ethtool_ops = {
- .get_drvinfo = ether1394_get_drvinfo
-};
-
static int __init ether1394_init_module(void)
{
int err;
diff --git a/drivers/infiniband/hw/mlx4/Kconfig b/drivers/infiniband/hw/mlx4/Kconfig
index 4175a4bd0c78..bd995b2b50d8 100644
--- a/drivers/infiniband/hw/mlx4/Kconfig
+++ b/drivers/infiniband/hw/mlx4/Kconfig
@@ -1,5 +1,6 @@
config MLX4_INFINIBAND
tristate "Mellanox ConnectX HCA support"
+ depends on NETDEVICES && NETDEV_10000 && PCI
select MLX4_CORE
---help---
This driver provides low-level InfiniBand support for
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 61e0efd4ccfb..6220d9d75b58 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -2701,7 +2701,7 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt)
nesibdev = nesvnic->nesibdev;
nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n",
- atomic_read(&nesvnic->netdev->refcnt));
+ netdev_refcnt_read(nesvnic->netdev));
if (nesqp->active_conn) {
@@ -2791,7 +2791,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
atomic_inc(&cm_accepts);
nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n",
- atomic_read(&nesvnic->netdev->refcnt));
+ netdev_refcnt_read(nesvnic->netdev));
/* allocate the ietf frame and space for private data */
nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev,
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 9046e6675686..546fc22405fe 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -785,7 +785,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev,
nes_debug(NES_DBG_PD, "nesvnic=%p, netdev=%p %s, ibdev=%p, context=%p, netdev refcnt=%u\n",
nesvnic, nesdev->netdev[0], nesdev->netdev[0]->name, ibdev, context,
- atomic_read(&nesvnic->netdev->refcnt));
+ netdev_refcnt_read(nesvnic->netdev));
err = nes_alloc_resource(nesadapter, nesadapter->allocated_pds,
nesadapter->max_pd, &pd_num, &nesadapter->next_pd);
@@ -1416,7 +1416,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
/* update the QP table */
nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp;
nes_debug(NES_DBG_QP, "netdev refcnt=%u\n",
- atomic_read(&nesvnic->netdev->refcnt));
+ netdev_refcnt_read(nesvnic->netdev));
return &nesqp->ibqp;
}
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 2978bdaa6b88..e54e79d4e2c1 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -1515,8 +1515,13 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep)
while (*s) {
int digit1 = 0;
int digit2 = 0;
- if (!isdigit(*s)) return -3;
- while (isdigit(*s)) { digit1 = digit1*10 + (*s - '0'); s++; }
+ char *endp;
+
+ digit1 = simple_strtoul(s, &endp, 10);
+ if (s == endp)
+ return -3;
+ s = endp;
+
if (digit1 <= 0 || digit1 > 30) return -4;
if (*s == 0 || *s == ',' || *s == ' ') {
bmask |= (1 << digit1);
@@ -1526,8 +1531,12 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep)
}
if (*s != '-') return -5;
s++;
- if (!isdigit(*s)) return -3;
- while (isdigit(*s)) { digit2 = digit2*10 + (*s - '0'); s++; }
+
+ digit2 = simple_strtoul(s, &endp, 10);
+ if (s == endp)
+ return -3;
+ s = endp;
+
if (digit2 <= 0 || digit2 > 30) return -4;
if (*s == 0 || *s == ',' || *s == ' ') {
if (digit1 > digit2)
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index b054494df846..3acf94cc5acd 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -98,6 +98,16 @@ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
return capi_controller[contr - 1];
}
+static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
+{
+ lockdep_assert_held(&capi_controller_lock);
+
+ if (applid - 1 >= CAPI_MAXAPPL)
+ return NULL;
+
+ return capi_applications[applid - 1];
+}
+
static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
{
if (applid - 1 >= CAPI_MAXAPPL)
@@ -185,10 +195,9 @@ static void notify_up(u32 contr)
ctr->state = CAPI_CTR_RUNNING;
for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
- ap = get_capi_appl_by_nr(applid);
- if (!ap)
- continue;
- register_appl(ctr, applid, &ap->rparam);
+ ap = __get_capi_appl_by_nr(applid);
+ if (ap)
+ register_appl(ctr, applid, &ap->rparam);
}
wake_up_interruptible_all(&ctr->state_wait_queue);
@@ -215,7 +224,7 @@ static void ctr_down(struct capi_ctr *ctr, int new_state)
memset(ctr->serial, 0, sizeof(ctr->serial));
for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
- ap = get_capi_appl_by_nr(applid);
+ ap = __get_capi_appl_by_nr(applid);
if (ap)
capi_ctr_put(ctr);
}
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 70cf6bac7a5a..48e6d220f62c 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -77,7 +77,7 @@ static void deflect_timer_expire(ulong arg)
case DEFLECT_ALERT:
cs->ics.command = ISDN_CMD_REDIR; /* protocol */
- strcpy(cs->ics.parm.setup.phone,cs->deflect_dest);
+ strlcpy(cs->ics.parm.setup.phone, cs->deflect_dest, sizeof(cs->ics.parm.setup.phone));
strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed");
divert_if.ll_cmd(&cs->ics);
spin_lock_irqsave(&divert_lock, flags);
@@ -251,7 +251,7 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr)
case 2: /* redir */
del_timer(&cs->timer);
- strcpy(cs->ics.parm.setup.phone, to_nr);
+ strlcpy(cs->ics.parm.setup.phone, to_nr, sizeof(cs->ics.parm.setup.phone));
strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual");
ic.command = ISDN_CMD_REDIR;
if ((i = divert_if.ll_cmd(&ic)))
@@ -480,7 +480,7 @@ static int isdn_divert_icall(isdn_ctrl *ic)
if (!cs->timer.expires)
{ strcpy(ic->parm.setup.eazmsn,"Testtext direct");
ic->parm.setup.screen = dv->rule.screen;
- strcpy(ic->parm.setup.phone,dv->rule.to_nr);
+ strlcpy(ic->parm.setup.phone, dv->rule.to_nr, sizeof(ic->parm.setup.phone));
cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
retval = 5;
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 707d9c94cf9e..178942a2ee61 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -109,6 +109,9 @@ struct bas_cardstate {
struct urb *urb_int_in; /* URB for interrupt pipe */
unsigned char *int_in_buf;
+ struct work_struct int_in_wq; /* for usb_clear_halt() */
+ struct timer_list timer_int_in; /* int read retry delay */
+ int retry_int_in;
spinlock_t lock; /* locks all following */
int basstate; /* bitmap (BS_*) */
@@ -169,7 +172,7 @@ static char *get_usb_rcmsg(int rc)
case -EAGAIN:
return "start frame too early or too much scheduled";
case -EFBIG:
- return "too many isochronous frames requested";
+ return "too many isoc frames requested";
case -EPIPE:
return "endpoint stalled";
case -EMSGSIZE:
@@ -200,13 +203,13 @@ static char *get_usb_statmsg(int status)
case -ENOENT:
return "unlinked (sync)";
case -EINPROGRESS:
- return "pending";
+ return "URB still pending";
case -EPROTO:
- return "bit stuffing error, timeout, or unknown USB error";
+ return "bitstuff error, timeout, or unknown USB error";
case -EILSEQ:
return "CRC mismatch, timeout, or unknown USB error";
case -ETIME:
- return "timed out";
+ return "USB response timeout";
case -EPIPE:
return "endpoint stalled";
case -ECOMM:
@@ -214,15 +217,15 @@ static char *get_usb_statmsg(int status)
case -ENOSR:
return "OUT buffer underrun";
case -EOVERFLOW:
- return "too much data";
+ return "endpoint babble";
case -EREMOTEIO:
- return "short packet detected";
+ return "short packet";
case -ENODEV:
return "device removed";
case -EXDEV:
- return "partial isochronous transfer";
+ return "partial isoc transfer";
case -EINVAL:
- return "invalid argument";
+ return "ISO madness";
case -ECONNRESET:
return "unlinked (async)";
case -ESHUTDOWN:
@@ -350,7 +353,7 @@ static inline void error_hangup(struct bc_state *bcs)
* reset Gigaset device because of an unrecoverable error
* This function may be called from any context, and takes care of
* scheduling the necessary actions for execution outside of interrupt context.
- * cs->lock must not be held.
+ * cs->hw.bas->lock must not be held.
* argument:
* controller state structure
*/
@@ -358,7 +361,9 @@ static inline void error_reset(struct cardstate *cs)
{
/* reset interrupt pipe to recover (ignore errors) */
update_basstate(cs->hw.bas, BS_RESETTING, 0);
- req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT);
+ if (req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT))
+ /* submission failed, escalate to USB port reset */
+ usb_queue_reset_device(cs->hw.bas->interface);
}
/* check_pending
@@ -438,23 +443,27 @@ static void cmd_in_timeout(unsigned long data)
return;
}
- if (ucs->retry_cmd_in++ < BAS_RETRY) {
- dev_notice(cs->dev, "control read: timeout, retry %d\n",
- ucs->retry_cmd_in);
- rc = atread_submit(cs, BAS_TIMEOUT);
- if (rc >= 0 || rc == -ENODEV)
- /* resubmitted or disconnected */
- /* - bypass regular exit block */
- return;
- } else {
+ if (ucs->retry_cmd_in++ >= BAS_RETRY) {
dev_err(cs->dev,
"control read: timeout, giving up after %d tries\n",
ucs->retry_cmd_in);
+ kfree(ucs->rcvbuf);
+ ucs->rcvbuf = NULL;
+ ucs->rcvbuf_size = 0;
+ error_reset(cs);
+ return;
+ }
+
+ gig_dbg(DEBUG_USBREQ, "%s: timeout, retry %d",
+ __func__, ucs->retry_cmd_in);
+ rc = atread_submit(cs, BAS_TIMEOUT);
+ if (rc < 0) {
+ kfree(ucs->rcvbuf);
+ ucs->rcvbuf = NULL;
+ ucs->rcvbuf_size = 0;
+ if (rc != -ENODEV)
+ error_reset(cs);
}
- kfree(ucs->rcvbuf);
- ucs->rcvbuf = NULL;
- ucs->rcvbuf_size = 0;
- error_reset(cs);
}
/* read_ctrl_callback
@@ -470,18 +479,11 @@ static void read_ctrl_callback(struct urb *urb)
struct cardstate *cs = inbuf->cs;
struct bas_cardstate *ucs = cs->hw.bas;
int status = urb->status;
- int have_data = 0;
unsigned numbytes;
int rc;
update_basstate(ucs, 0, BS_ATRDPEND);
wake_up(&ucs->waitqueue);
-
- if (!ucs->rcvbuf_size) {
- dev_warn(cs->dev, "%s: no receive in progress\n", __func__);
- return;
- }
-
del_timer(&ucs->timer_cmd_in);
switch (status) {
@@ -495,19 +497,10 @@ static void read_ctrl_callback(struct urb *urb)
numbytes = ucs->rcvbuf_size;
}
- /* copy received bytes to inbuf */
- have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes);
-
- if (unlikely(numbytes < ucs->rcvbuf_size)) {
- /* incomplete - resubmit for remaining bytes */
- ucs->rcvbuf_size -= numbytes;
- ucs->retry_cmd_in = 0;
- rc = atread_submit(cs, BAS_TIMEOUT);
- if (rc >= 0 || rc == -ENODEV)
- /* resubmitted or disconnected */
- /* - bypass regular exit block */
- return;
- error_reset(cs);
+ /* copy received bytes to inbuf, notify event layer */
+ if (gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes)) {
+ gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
+ gigaset_schedule_event(cs);
}
break;
@@ -516,37 +509,32 @@ static void read_ctrl_callback(struct urb *urb)
case -EINPROGRESS: /* pending */
case -ENODEV: /* device removed */
case -ESHUTDOWN: /* device shut down */
- /* no action necessary */
+ /* no further action necessary */
gig_dbg(DEBUG_USBREQ, "%s: %s",
__func__, get_usb_statmsg(status));
break;
- default: /* severe trouble */
- dev_warn(cs->dev, "control read: %s\n",
- get_usb_statmsg(status));
+ default: /* other errors: retry */
if (ucs->retry_cmd_in++ < BAS_RETRY) {
- dev_notice(cs->dev, "control read: retry %d\n",
- ucs->retry_cmd_in);
+ gig_dbg(DEBUG_USBREQ, "%s: %s, retry %d", __func__,
+ get_usb_statmsg(status), ucs->retry_cmd_in);
rc = atread_submit(cs, BAS_TIMEOUT);
- if (rc >= 0 || rc == -ENODEV)
- /* resubmitted or disconnected */
- /* - bypass regular exit block */
+ if (rc >= 0)
+ /* successfully resubmitted, skip freeing */
return;
- } else {
- dev_err(cs->dev,
- "control read: giving up after %d tries\n",
- ucs->retry_cmd_in);
+ if (rc == -ENODEV)
+ /* disconnect, no further action necessary */
+ break;
}
+ dev_err(cs->dev, "control read: %s, giving up after %d tries\n",
+ get_usb_statmsg(status), ucs->retry_cmd_in);
error_reset(cs);
}
+ /* read finished, free buffer */
kfree(ucs->rcvbuf);
ucs->rcvbuf = NULL;
ucs->rcvbuf_size = 0;
- if (have_data) {
- gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
- gigaset_schedule_event(cs);
- }
}
/* atread_submit
@@ -605,14 +593,67 @@ static int atread_submit(struct cardstate *cs, int timeout)
if (timeout > 0) {
gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout);
- ucs->timer_cmd_in.expires = jiffies + timeout * HZ / 10;
- ucs->timer_cmd_in.data = (unsigned long) cs;
- ucs->timer_cmd_in.function = cmd_in_timeout;
- add_timer(&ucs->timer_cmd_in);
+ mod_timer(&ucs->timer_cmd_in, jiffies + timeout * HZ / 10);
}
return 0;
}
+/* int_in_work
+ * workqueue routine to clear halt on interrupt in endpoint
+ */
+
+static void int_in_work(struct work_struct *work)
+{
+ struct bas_cardstate *ucs =
+ container_of(work, struct bas_cardstate, int_in_wq);
+ struct urb *urb = ucs->urb_int_in;
+ struct cardstate *cs = urb->context;
+ int rc;
+
+ /* clear halt condition */
+ rc = usb_clear_halt(ucs->udev, urb->pipe);
+ gig_dbg(DEBUG_USBREQ, "clear_halt: %s", get_usb_rcmsg(rc));
+ if (rc == 0)
+ /* success, resubmit interrupt read URB */
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
+ if (rc != 0 && rc != -ENODEV) {
+ dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc));
+ rc = usb_lock_device_for_reset(ucs->udev, ucs->interface);
+ if (rc == 0) {
+ rc = usb_reset_device(ucs->udev);
+ usb_unlock_device(ucs->udev);
+ }
+ }
+ ucs->retry_int_in = 0;
+}
+
+/* int_in_resubmit
+ * timer routine for interrupt read delayed resubmit
+ * argument:
+ * controller state structure
+ */
+static void int_in_resubmit(unsigned long data)
+{
+ struct cardstate *cs = (struct cardstate *) data;
+ struct bas_cardstate *ucs = cs->hw.bas;
+ int rc;
+
+ if (ucs->retry_int_in++ >= BAS_RETRY) {
+ dev_err(cs->dev, "interrupt read: giving up after %d tries\n",
+ ucs->retry_int_in);
+ usb_queue_reset_device(ucs->interface);
+ return;
+ }
+
+ gig_dbg(DEBUG_USBREQ, "%s: retry %d", __func__, ucs->retry_int_in);
+ rc = usb_submit_urb(ucs->urb_int_in, GFP_ATOMIC);
+ if (rc != 0 && rc != -ENODEV) {
+ dev_err(cs->dev, "could not resubmit interrupt URB: %s\n",
+ get_usb_rcmsg(rc));
+ usb_queue_reset_device(ucs->interface);
+ }
+}
+
/* read_int_callback
* USB completion handler for interrupt pipe input
* called by the USB subsystem in interrupt context
@@ -633,19 +674,29 @@ static void read_int_callback(struct urb *urb)
switch (status) {
case 0: /* success */
+ ucs->retry_int_in = 0;
break;
+ case -EPIPE: /* endpoint stalled */
+ schedule_work(&ucs->int_in_wq);
+ /* fall through */
case -ENOENT: /* cancelled */
case -ECONNRESET: /* cancelled (async) */
case -EINPROGRESS: /* pending */
- /* ignore silently */
+ case -ENODEV: /* device removed */
+ case -ESHUTDOWN: /* device shut down */
+ /* no further action necessary */
gig_dbg(DEBUG_USBREQ, "%s: %s",
__func__, get_usb_statmsg(status));
return;
- case -ENODEV: /* device removed */
- case -ESHUTDOWN: /* device shut down */
- gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__);
+ case -EPROTO: /* protocol error or unplug */
+ case -EILSEQ:
+ case -ETIME:
+ /* resubmit after delay */
+ gig_dbg(DEBUG_USBREQ, "%s: %s",
+ __func__, get_usb_statmsg(status));
+ mod_timer(&ucs->timer_int_in, jiffies + HZ / 10);
return;
- default: /* severe trouble */
+ default: /* other errors: just resubmit */
dev_warn(cs->dev, "interrupt read: %s\n",
get_usb_statmsg(status));
goto resubmit;
@@ -723,6 +774,13 @@ static void read_int_callback(struct urb *urb)
break;
}
spin_lock_irqsave(&cs->lock, flags);
+ if (ucs->basstate & BS_ATRDPEND) {
+ spin_unlock_irqrestore(&cs->lock, flags);
+ dev_warn(cs->dev,
+ "HD_RECEIVEATDATA_ACK(%d) during HD_READ_ATMESSAGE(%d) ignored\n",
+ l, ucs->rcvbuf_size);
+ break;
+ }
if (ucs->rcvbuf_size) {
/* throw away previous buffer - we have no queue */
dev_err(cs->dev,
@@ -735,7 +793,6 @@ static void read_int_callback(struct urb *urb)
if (ucs->rcvbuf == NULL) {
spin_unlock_irqrestore(&cs->lock, flags);
dev_err(cs->dev, "out of memory receiving AT data\n");
- error_reset(cs);
break;
}
ucs->rcvbuf_size = l;
@@ -745,13 +802,10 @@ static void read_int_callback(struct urb *urb)
kfree(ucs->rcvbuf);
ucs->rcvbuf = NULL;
ucs->rcvbuf_size = 0;
- if (rc != -ENODEV) {
- spin_unlock_irqrestore(&cs->lock, flags);
- error_reset(cs);
- break;
- }
}
spin_unlock_irqrestore(&cs->lock, flags);
+ if (rc < 0 && rc != -ENODEV)
+ error_reset(cs);
break;
case HD_RESET_INTERRUPT_PIPE_ACK:
@@ -818,6 +872,7 @@ static void read_iso_callback(struct urb *urb)
tasklet_hi_schedule(&ubc->rcvd_tasklet);
} else {
/* tasklet still busy, drop data and resubmit URB */
+ gig_dbg(DEBUG_ISO, "%s: overrun", __func__);
ubc->loststatus = status;
for (i = 0; i < BAS_NUMFRAMES; i++) {
ubc->isoinlost += urb->iso_frame_desc[i].actual_length;
@@ -833,13 +888,11 @@ static void read_iso_callback(struct urb *urb)
urb->dev = bcs->cs->hw.bas->udev;
urb->transfer_flags = URB_ISO_ASAP;
urb->number_of_packets = BAS_NUMFRAMES;
- gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit",
- __func__);
rc = usb_submit_urb(urb, GFP_ATOMIC);
if (unlikely(rc != 0 && rc != -ENODEV)) {
dev_err(bcs->cs->dev,
- "could not resubmit isochronous read "
- "URB: %s\n", get_usb_rcmsg(rc));
+ "could not resubmit isoc read URB: %s\n",
+ get_usb_rcmsg(rc));
dump_urb(DEBUG_ISO, "isoc read", urb);
error_hangup(bcs);
}
@@ -1081,7 +1134,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
gig_dbg(DEBUG_ISO, "%s: disconnected", __func__);
else
dev_err(ucx->bcs->cs->dev,
- "could not submit isochronous write URB: %s\n",
+ "could not submit isoc write URB: %s\n",
get_usb_rcmsg(rc));
return rc;
}
@@ -1126,7 +1179,7 @@ static void write_iso_tasklet(unsigned long data)
ubc->isooutovfl = NULL;
spin_unlock_irqrestore(&ubc->isooutlock, flags);
if (ovfl) {
- dev_err(cs->dev, "isochronous write buffer underrun\n");
+ dev_err(cs->dev, "isoc write underrun\n");
error_hangup(bcs);
break;
}
@@ -1151,7 +1204,7 @@ static void write_iso_tasklet(unsigned long data)
if (next) {
/* couldn't put it back */
dev_err(cs->dev,
- "losing isochronous write URB\n");
+ "losing isoc write URB\n");
error_hangup(bcs);
}
}
@@ -1178,10 +1231,10 @@ static void write_iso_tasklet(unsigned long data)
if (ifd->status ||
ifd->actual_length != ifd->length) {
dev_warn(cs->dev,
- "isochronous write: frame %d: %s, "
- "only %d of %d bytes sent\n",
- i, get_usb_statmsg(ifd->status),
- ifd->actual_length, ifd->length);
+ "isoc write: frame %d[%d/%d]: %s\n",
+ i, ifd->actual_length,
+ ifd->length,
+ get_usb_statmsg(ifd->status));
offset = (ifd->offset +
ifd->actual_length)
% BAS_OUTBUFSIZE;
@@ -1190,11 +1243,11 @@ static void write_iso_tasklet(unsigned long data)
}
break;
case -EPIPE: /* stall - probably underrun */
- dev_err(cs->dev, "isochronous write stalled\n");
+ dev_err(cs->dev, "isoc write: stalled\n");
error_hangup(bcs);
break;
- default: /* severe trouble */
- dev_warn(cs->dev, "isochronous write: %s\n",
+ default: /* other errors */
+ dev_warn(cs->dev, "isoc write: %s\n",
get_usb_statmsg(status));
}
@@ -1250,6 +1303,7 @@ static void read_iso_tasklet(unsigned long data)
struct cardstate *cs = bcs->cs;
struct urb *urb;
int status;
+ struct usb_iso_packet_descriptor *ifd;
char *rcvbuf;
unsigned long flags;
int totleft, numbytes, offset, frame, rc;
@@ -1267,8 +1321,7 @@ static void read_iso_tasklet(unsigned long data)
ubc->isoindone = NULL;
if (unlikely(ubc->loststatus != -EINPROGRESS)) {
dev_warn(cs->dev,
- "isochronous read overrun, "
- "dropped URB with status: %s, %d bytes lost\n",
+ "isoc read overrun, URB dropped (status: %s, %d bytes)\n",
get_usb_statmsg(ubc->loststatus),
ubc->isoinlost);
ubc->loststatus = -EINPROGRESS;
@@ -1298,11 +1351,11 @@ static void read_iso_tasklet(unsigned long data)
__func__, get_usb_statmsg(status));
continue; /* -> skip */
case -EPIPE:
- dev_err(cs->dev, "isochronous read stalled\n");
+ dev_err(cs->dev, "isoc read: stalled\n");
error_hangup(bcs);
continue; /* -> skip */
- default: /* severe trouble */
- dev_warn(cs->dev, "isochronous read: %s\n",
+ default: /* other error */
+ dev_warn(cs->dev, "isoc read: %s\n",
get_usb_statmsg(status));
goto error;
}
@@ -1310,40 +1363,52 @@ static void read_iso_tasklet(unsigned long data)
rcvbuf = urb->transfer_buffer;
totleft = urb->actual_length;
for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) {
- numbytes = urb->iso_frame_desc[frame].actual_length;
- if (unlikely(urb->iso_frame_desc[frame].status))
+ ifd = &urb->iso_frame_desc[frame];
+ numbytes = ifd->actual_length;
+ switch (ifd->status) {
+ case 0: /* success */
+ break;
+ case -EPROTO: /* protocol error or unplug */
+ case -EILSEQ:
+ case -ETIME:
+ /* probably just disconnected, ignore */
+ gig_dbg(DEBUG_ISO,
+ "isoc read: frame %d[%d]: %s\n",
+ frame, numbytes,
+ get_usb_statmsg(ifd->status));
+ break;
+ default: /* other error */
+ /* report, assume transferred bytes are ok */
dev_warn(cs->dev,
- "isochronous read: frame %d[%d]: %s\n",
+ "isoc read: frame %d[%d]: %s\n",
frame, numbytes,
- get_usb_statmsg(
- urb->iso_frame_desc[frame].status));
+ get_usb_statmsg(ifd->status));
+ }
if (unlikely(numbytes > BAS_MAXFRAME))
dev_warn(cs->dev,
- "isochronous read: frame %d: "
- "numbytes (%d) > BAS_MAXFRAME\n",
- frame, numbytes);
+ "isoc read: frame %d[%d]: %s\n",
+ frame, numbytes,
+ "exceeds max frame size");
if (unlikely(numbytes > totleft)) {
dev_warn(cs->dev,
- "isochronous read: frame %d: "
- "numbytes (%d) > totleft (%d)\n",
- frame, numbytes, totleft);
+ "isoc read: frame %d[%d]: %s\n",
+ frame, numbytes,
+ "exceeds total transfer length");
numbytes = totleft;
}
- offset = urb->iso_frame_desc[frame].offset;
+ offset = ifd->offset;
if (unlikely(offset + numbytes > BAS_INBUFSIZE)) {
dev_warn(cs->dev,
- "isochronous read: frame %d: "
- "offset (%d) + numbytes (%d) "
- "> BAS_INBUFSIZE\n",
- frame, offset, numbytes);
+ "isoc read: frame %d[%d]: %s\n",
+ frame, numbytes,
+ "exceeds end of buffer");
numbytes = BAS_INBUFSIZE - offset;
}
gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs);
totleft -= numbytes;
}
if (unlikely(totleft > 0))
- dev_warn(cs->dev,
- "isochronous read: %d data bytes missing\n",
+ dev_warn(cs->dev, "isoc read: %d data bytes missing\n",
totleft);
error:
@@ -1359,9 +1424,9 @@ error:
rc = usb_submit_urb(urb, GFP_ATOMIC);
if (unlikely(rc != 0 && rc != -ENODEV)) {
dev_err(cs->dev,
- "could not resubmit isochronous read URB: %s\n",
+ "could not resubmit isoc read URB: %s\n",
get_usb_rcmsg(rc));
- dump_urb(DEBUG_ISO, "resubmit iso read", urb);
+ dump_urb(DEBUG_ISO, "resubmit isoc read", urb);
error_hangup(bcs);
}
}
@@ -1373,12 +1438,12 @@ error:
/* req_timeout
* timeout routine for control output request
* argument:
- * B channel control structure
+ * controller state structure
*/
static void req_timeout(unsigned long data)
{
- struct bc_state *bcs = (struct bc_state *) data;
- struct bas_cardstate *ucs = bcs->cs->hw.bas;
+ struct cardstate *cs = (struct cardstate *) data;
+ struct bas_cardstate *ucs = cs->hw.bas;
int pending;
unsigned long flags;
@@ -1395,38 +1460,44 @@ static void req_timeout(unsigned long data)
break;
case HD_OPEN_ATCHANNEL:
- dev_err(bcs->cs->dev, "timeout opening AT channel\n");
- error_reset(bcs->cs);
+ dev_err(cs->dev, "timeout opening AT channel\n");
+ error_reset(cs);
break;
- case HD_OPEN_B2CHANNEL:
case HD_OPEN_B1CHANNEL:
- dev_err(bcs->cs->dev, "timeout opening channel %d\n",
- bcs->channel + 1);
- error_hangup(bcs);
+ dev_err(cs->dev, "timeout opening channel 1\n");
+ error_hangup(&cs->bcs[0]);
+ break;
+
+ case HD_OPEN_B2CHANNEL:
+ dev_err(cs->dev, "timeout opening channel 2\n");
+ error_hangup(&cs->bcs[1]);
break;
case HD_CLOSE_ATCHANNEL:
- dev_err(bcs->cs->dev, "timeout closing AT channel\n");
- error_reset(bcs->cs);
+ dev_err(cs->dev, "timeout closing AT channel\n");
+ error_reset(cs);
break;
- case HD_CLOSE_B2CHANNEL:
case HD_CLOSE_B1CHANNEL:
- dev_err(bcs->cs->dev, "timeout closing channel %d\n",
- bcs->channel + 1);
- error_reset(bcs->cs);
+ dev_err(cs->dev, "timeout closing channel 1\n");
+ error_reset(cs);
+ break;
+
+ case HD_CLOSE_B2CHANNEL:
+ dev_err(cs->dev, "timeout closing channel 2\n");
+ error_reset(cs);
break;
case HD_RESET_INTERRUPT_PIPE:
/* error recovery escalation */
- dev_err(bcs->cs->dev,
+ dev_err(cs->dev,
"reset interrupt pipe timeout, attempting USB reset\n");
- usb_queue_reset_device(bcs->cs->hw.bas->interface);
+ usb_queue_reset_device(ucs->interface);
break;
default:
- dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n",
+ dev_warn(cs->dev, "request 0x%02x timed out, clearing\n",
pending);
}
@@ -1557,10 +1628,7 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout)
if (timeout > 0) {
gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout);
- ucs->timer_ctrl.expires = jiffies + timeout * HZ / 10;
- ucs->timer_ctrl.data = (unsigned long) bcs;
- ucs->timer_ctrl.function = req_timeout;
- add_timer(&ucs->timer_ctrl);
+ mod_timer(&ucs->timer_ctrl, jiffies + timeout * HZ / 10);
}
spin_unlock_irqrestore(&ucs->lock, flags);
@@ -1590,21 +1658,20 @@ static int gigaset_init_bchannel(struct bc_state *bcs)
if (cs->hw.bas->basstate & BS_SUSPEND) {
dev_notice(cs->dev,
- "not starting isochronous I/O, "
- "suspend in progress\n");
+ "not starting isoc I/O, suspend in progress\n");
spin_unlock_irqrestore(&cs->lock, flags);
return -EHOSTUNREACH;
}
ret = starturbs(bcs);
if (ret < 0) {
+ spin_unlock_irqrestore(&cs->lock, flags);
dev_err(cs->dev,
- "could not start isochronous I/O for channel B%d: %s\n",
+ "could not start isoc I/O for channel B%d: %s\n",
bcs->channel + 1,
ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret));
if (ret != -ENODEV)
error_hangup(bcs);
- spin_unlock_irqrestore(&cs->lock, flags);
return ret;
}
@@ -1614,11 +1681,11 @@ static int gigaset_init_bchannel(struct bc_state *bcs)
dev_err(cs->dev, "could not open channel B%d\n",
bcs->channel + 1);
stopurbs(bcs->hw.bas);
- if (ret != -ENODEV)
- error_hangup(bcs);
}
spin_unlock_irqrestore(&cs->lock, flags);
+ if (ret < 0 && ret != -ENODEV)
+ error_hangup(bcs);
return ret;
}
@@ -1826,10 +1893,7 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
if (!(update_basstate(ucs, BS_ATTIMER, BS_ATREADY) & BS_ATTIMER)) {
gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs",
ATRDY_TIMEOUT);
- ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10;
- ucs->timer_atrdy.data = (unsigned long) cs;
- ucs->timer_atrdy.function = atrdy_timeout;
- add_timer(&ucs->timer_atrdy);
+ mod_timer(&ucs->timer_atrdy, jiffies + ATRDY_TIMEOUT * HZ / 10);
}
return 0;
}
@@ -1914,6 +1978,28 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
* The next command will reopen the AT channel automatically.
*/
if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) {
+ /* If an HD_RECEIVEATDATA_ACK message remains unhandled
+ * because of an error, the base never sends another one.
+ * The response channel is thus effectively blocked.
+ * Closing and reopening the AT channel does *not* clear
+ * this condition.
+ * As a stopgap measure, submit a zero-length AT read
+ * before closing the AT channel. This has the undocumented
+ * effect of triggering a new HD_RECEIVEATDATA_ACK message
+ * from the base if necessary.
+ * The subsequent AT channel close then discards any pending
+ * messages.
+ */
+ spin_lock_irqsave(&cs->lock, flags);
+ if (!(cs->hw.bas->basstate & BS_ATRDPEND)) {
+ kfree(cs->hw.bas->rcvbuf);
+ cs->hw.bas->rcvbuf = NULL;
+ cs->hw.bas->rcvbuf_size = 0;
+ cs->hw.bas->retry_cmd_in = 0;
+ atread_submit(cs, 0);
+ }
+ spin_unlock_irqrestore(&cs->lock, flags);
+
rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
if (cb->wake_tasklet)
tasklet_schedule(cb->wake_tasklet);
@@ -2010,7 +2096,7 @@ static int gigaset_freebcshw(struct bc_state *bcs)
/* kill URBs and tasklets before freeing - better safe than sorry */
ubc->running = 0;
- gig_dbg(DEBUG_INIT, "%s: killing iso URBs", __func__);
+ gig_dbg(DEBUG_INIT, "%s: killing isoc URBs", __func__);
for (i = 0; i < BAS_OUTURBS; ++i) {
usb_kill_urb(ubc->isoouturbs[i].urb);
usb_free_urb(ubc->isoouturbs[i].urb);
@@ -2131,10 +2217,12 @@ static int gigaset_initcshw(struct cardstate *cs)
ucs->pending = 0;
ucs->basstate = 0;
- init_timer(&ucs->timer_ctrl);
- init_timer(&ucs->timer_atrdy);
- init_timer(&ucs->timer_cmd_in);
+ setup_timer(&ucs->timer_ctrl, req_timeout, (unsigned long) cs);
+ setup_timer(&ucs->timer_atrdy, atrdy_timeout, (unsigned long) cs);
+ setup_timer(&ucs->timer_cmd_in, cmd_in_timeout, (unsigned long) cs);
+ setup_timer(&ucs->timer_int_in, int_in_resubmit, (unsigned long) cs);
init_waitqueue_head(&ucs->waitqueue);
+ INIT_WORK(&ucs->int_in_wq, int_in_work);
return 1;
}
@@ -2282,6 +2370,7 @@ static int gigaset_probe(struct usb_interface *interface,
get_usb_rcmsg(rc));
goto error;
}
+ ucs->retry_int_in = 0;
/* tell the device that the driver is ready */
rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0);
@@ -2334,10 +2423,12 @@ static void gigaset_disconnect(struct usb_interface *interface)
/* stop driver (common part) */
gigaset_stop(cs);
- /* stop timers and URBs, free ressources */
+ /* stop delayed work and URBs, free ressources */
del_timer_sync(&ucs->timer_ctrl);
del_timer_sync(&ucs->timer_atrdy);
del_timer_sync(&ucs->timer_cmd_in);
+ del_timer_sync(&ucs->timer_int_in);
+ cancel_work_sync(&ucs->int_in_wq);
freeurbs(cs);
usb_set_intfdata(interface, NULL);
kfree(ucs->rcvbuf);
@@ -2400,10 +2491,14 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
/* in case of timeout, proceed anyway */
}
- /* kill all URBs and timers that might still be pending */
+ /* kill all URBs and delayed work that might still be pending */
usb_kill_urb(ucs->urb_ctrl);
usb_kill_urb(ucs->urb_int_in);
del_timer_sync(&ucs->timer_ctrl);
+ del_timer_sync(&ucs->timer_atrdy);
+ del_timer_sync(&ucs->timer_cmd_in);
+ del_timer_sync(&ucs->timer_int_in);
+ cancel_work_sync(&ucs->int_in_wq);
gig_dbg(DEBUG_SUSPEND, "suspend complete");
return 0;
@@ -2425,6 +2520,7 @@ static int gigaset_resume(struct usb_interface *intf)
get_usb_rcmsg(rc));
return rc;
}
+ ucs->retry_int_in = 0;
/* clear suspend flag to reallow activity */
update_basstate(ucs, 0, BS_SUSPEND);
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 3ca561eccd9f..db621db67f61 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -1026,32 +1026,6 @@ struct cardstate *gigaset_get_cs_by_id(int id)
return ret;
}
-void gigaset_debugdrivers(void)
-{
- unsigned long flags;
- static struct cardstate *cs;
- struct gigaset_driver *drv;
- unsigned i;
-
- spin_lock_irqsave(&driver_lock, flags);
- list_for_each_entry(drv, &drivers, list) {
- gig_dbg(DEBUG_DRIVER, "driver %p", drv);
- spin_lock(&drv->lock);
- for (i = 0; i < drv->minors; ++i) {
- gig_dbg(DEBUG_DRIVER, " index %u", i);
- cs = drv->cs + i;
- gig_dbg(DEBUG_DRIVER, " cardstate %p", cs);
- gig_dbg(DEBUG_DRIVER, " flags 0x%02x", cs->flags);
- gig_dbg(DEBUG_DRIVER, " minor_index %u",
- cs->minor_index);
- gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver);
- gig_dbg(DEBUG_DRIVER, " i4l id %d", cs->myid);
- }
- spin_unlock(&drv->lock);
- }
- spin_unlock_irqrestore(&driver_lock, flags);
-}
-
static struct cardstate *gigaset_get_cs_by_minor(unsigned minor)
{
unsigned long flags;
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index a69512fb1195..6dd360734cfd 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -70,7 +70,6 @@ enum debuglevel {
DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */
DEBUG_LLDATA = 0x00100, /* sent/received LL data */
DEBUG_EVENT = 0x00200, /* event processing */
- DEBUG_DRIVER = 0x00400, /* driver structure */
DEBUG_HDLC = 0x00800, /* M10x HDLC processing */
DEBUG_CHANNEL = 0x01000, /* channel allocation/deallocation */
DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */
@@ -727,7 +726,7 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
/* Deallocate driver structure. */
void gigaset_freedriver(struct gigaset_driver *drv);
-void gigaset_debugdrivers(void);
+
struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty);
struct cardstate *gigaset_get_cs_by_id(int id);
void gigaset_blockdriver(struct gigaset_driver *drv);
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 34bca37d65b9..9bec8b969964 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -201,8 +201,6 @@ static int command_from_LL(isdn_ctrl *cntrl)
int i;
size_t l;
- gigaset_debugdrivers();
-
gig_dbg(DEBUG_CMD, "driver: %d, command: %d, arg: 0x%lx",
cntrl->driver, cntrl->command, cntrl->arg);
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index 2dfd346fc889..f39ccdf87a17 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -842,13 +842,14 @@ static inline void trans_receive(unsigned char *src, unsigned count,
if (unlikely(bcs->ignore)) {
bcs->ignore--;
- hdlc_flush(bcs);
return;
}
skb = bcs->rx_skb;
- if (skb == NULL)
+ if (skb == NULL) {
skb = gigaset_new_rx_skb(bcs);
- bcs->hw.bas->goodbytes += skb->len;
+ if (skb == NULL)
+ return;
+ }
dobytes = bcs->rx_bufsize - skb->len;
while (count > 0) {
dst = skb_put(skb, count < dobytes ? count : dobytes);
@@ -860,6 +861,7 @@ static inline void trans_receive(unsigned char *src, unsigned count,
if (dobytes == 0) {
dump_bytes(DEBUG_STREAM_DUMP,
"rcv data", skb->data, skb->len);
+ bcs->hw.bas->goodbytes += skb->len;
gigaset_skb_rcvd(bcs, skb);
skb = gigaset_new_rx_skb(bcs);
if (skb == NULL)
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c
index 33ce89eed65b..362640120886 100644
--- a/drivers/isdn/hardware/eicon/debug.c
+++ b/drivers/isdn/hardware/eicon/debug.c
@@ -862,7 +862,7 @@ 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;
- char tmp[256];
+ char tmp[128];
diva_dbg_entry_head_t* pmsg = NULL;
int len;
word size;
diff --git a/drivers/isdn/hardware/eicon/debuglib.h b/drivers/isdn/hardware/eicon/debuglib.h
index 8ea587783e14..02eed6b4354c 100644
--- a/drivers/isdn/hardware/eicon/debuglib.h
+++ b/drivers/isdn/hardware/eicon/debuglib.h
@@ -249,7 +249,7 @@ typedef struct _DbgHandle_
} regTime ; /* timestamp for registration */
void *pIrp ; /* ptr to pending i/o request */
unsigned long dbgMask ; /* current debug mask */
- char drvName[16] ; /* ASCII name of registered driver */
+ char drvName[128] ; /* ASCII name of registered driver */
char drvTag[64] ; /* revision string */
DbgEnd dbg_end ; /* function for debug closing */
DbgLog dbg_prt ; /* function for debug appending */
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index be5faf4aa868..5aa138eb0b3c 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -234,13 +234,14 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max)
count++;
if (count > trans_max)
count = trans_max; /* limit length */
- if ((skb = dev_alloc_skb(count))) {
- dst = skb_put(skb, count);
- while (count--)
+ skb = dev_alloc_skb(count);
+ if (skb) {
+ dst = skb_put(skb, count);
+ while (count--)
*dst++ = Read_hfc(cs, HFCSX_FIF_DRD);
- return(skb);
- }
- else return(NULL); /* no memory */
+ return skb;
+ } else
+ return NULL; /* no memory */
}
do {
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 51dc60da333b..c463162843ba 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -14,7 +14,7 @@
#include <linux/isdn.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include "isdn_common.h"
#include "isdn_tty.h"
#ifdef CONFIG_ISDN_AUDIO
@@ -28,6 +28,7 @@
/* Prototypes */
+static DEFINE_MUTEX(modem_info_mutex);
static int isdn_tty_edit_at(const char *, int, modem_info *);
static void isdn_tty_check_esc(const u_char *, u_char, int, int *, u_long *);
static void isdn_tty_modem_reset_regs(modem_info *, int);
@@ -1354,14 +1355,14 @@ isdn_tty_tiocmget(struct tty_struct *tty, struct file *file)
if (tty->flags & (1 << TTY_IO_ERROR))
return -EIO;
- lock_kernel();
+ mutex_lock(&modem_info_mutex);
#ifdef ISDN_DEBUG_MODEM_IOCTL
printk(KERN_DEBUG "ttyI%d ioctl TIOCMGET\n", info->line);
#endif
control = info->mcr;
status = info->msr;
- unlock_kernel();
+ mutex_unlock(&modem_info_mutex);
return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
| ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
@@ -1385,7 +1386,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, struct file *file,
printk(KERN_DEBUG "ttyI%d ioctl TIOCMxxx: %x %x\n", info->line, set, clear);
#endif
- lock_kernel();
+ mutex_lock(&modem_info_mutex);
if (set & TIOCM_RTS)
info->mcr |= UART_MCR_RTS;
if (set & TIOCM_DTR) {
@@ -1407,7 +1408,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, struct file *file,
isdn_tty_modem_hup(info, 1);
}
}
- unlock_kernel();
+ mutex_unlock(&modem_info_mutex);
return 0;
}
@@ -3515,7 +3516,7 @@ isdn_tty_parse_at(modem_info * info)
{
atemu *m = &info->emu;
char *p;
- char ds[40];
+ char ds[ISDN_MSNLEN];
#ifdef ISDN_DEBUG_AT
printk(KERN_DEBUG "AT: '%s'\n", m->mdmcmd);
@@ -3594,7 +3595,7 @@ isdn_tty_parse_at(modem_info * info)
break;
case '3':
p++;
- sprintf(ds, "\r\n%d", info->emu.charge);
+ snprintf(ds, sizeof(ds), "\r\n%d", info->emu.charge);
isdn_tty_at_cout(ds, info);
break;
default:;
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index 713ef2b805a2..76d9e673b4e1 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -1237,6 +1237,7 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
if (dsp->cmx_delay)
dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
& CMX_BUFF_MASK;
+ else
dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
& CMX_BUFF_MASK;
} else {
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
index 22f38e48ac4e..5b59796ed250 100644
--- a/drivers/isdn/mISDN/l1oip_core.c
+++ b/drivers/isdn/mISDN/l1oip_core.c
@@ -972,7 +972,7 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
if (debug & DEBUG_L1OIP_SOCKET)
printk(KERN_DEBUG "%s: got new ip address from user "
"space.\n", __func__);
- l1oip_socket_open(hc);
+ l1oip_socket_open(hc);
break;
case MISDN_CTRL_UNSETPEER:
if (debug & DEBUG_L1OIP_SOCKET)
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
index b159bd59e64e..a5b632e67552 100644
--- a/drivers/isdn/mISDN/stack.c
+++ b/drivers/isdn/mISDN/stack.c
@@ -18,7 +18,6 @@
#include <linux/slab.h>
#include <linux/mISDNif.h>
#include <linux/kthread.h>
-#include <linux/smp_lock.h>
#include "core.h"
static u_int *debug;
@@ -205,13 +204,7 @@ mISDNStackd(void *data)
struct mISDNstack *st = data;
int err = 0;
-#ifdef CONFIG_SMP
- lock_kernel();
-#endif
sigfillset(&current->blocked);
-#ifdef CONFIG_SMP
- unlock_kernel();
-#endif
if (*debug & DEBUG_MSG_THREAD)
printk(KERN_DEBUG "mISDNStackd %s started\n",
dev_name(&st->dev->dev));
diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c
index d5920ae22d73..80c9c16fd5ef 100644
--- a/drivers/isdn/pcbit/edss1.c
+++ b/drivers/isdn/pcbit/edss1.c
@@ -33,7 +33,7 @@
#include "callbacks.h"
-char * isdn_state_table[] = {
+const char * const isdn_state_table[] = {
"Closed",
"Call initiated",
"Overlap sending",
diff --git a/drivers/isdn/pcbit/edss1.h b/drivers/isdn/pcbit/edss1.h
index 0b64f97015d8..39f8346e28c5 100644
--- a/drivers/isdn/pcbit/edss1.h
+++ b/drivers/isdn/pcbit/edss1.h
@@ -90,7 +90,7 @@ struct fsm_timer_entry {
unsigned long timeout; /* in seconds */
};
-extern char * isdn_state_table[];
+extern const char * const isdn_state_table[];
void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *,
unsigned short event, struct callb_data *);
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index baac246561b9..4777a1cbcd8d 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -337,10 +337,10 @@ el2_probe1(struct net_device *dev, int ioaddr)
/* Finish setting the board's parameters. */
ei_status.stop_page = EL2_MB1_STOP_PG;
ei_status.word16 = wordlength;
- ei_status.reset_8390 = &el2_reset_8390;
- ei_status.get_8390_hdr = &el2_get_8390_hdr;
- ei_status.block_input = &el2_block_input;
- ei_status.block_output = &el2_block_output;
+ ei_status.reset_8390 = el2_reset_8390;
+ ei_status.get_8390_hdr = el2_get_8390_hdr;
+ ei_status.block_input = el2_block_input;
+ ei_status.block_output = el2_block_output;
if (dev->irq == 2)
dev->irq = 9;
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index 3bba835f1a21..cdf7226a7c43 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -662,7 +662,9 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
pr_warning(" *** Warning: this IRQ is unlikely to work! ***\n");
{
- char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
+ static const char * const ram_split[] = {
+ "5:3", "3:1", "1:1", "3:5"
+ };
__u32 config;
EL3WINDOW(3);
vp->available_media = inw(ioaddr + Wn3_Options);
@@ -734,7 +736,7 @@ static int corkscrew_open(struct net_device *dev)
init_timer(&vp->timer);
vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
vp->timer.data = (unsigned long) dev;
- vp->timer.function = &corkscrew_timer; /* timer handler */
+ vp->timer.function = corkscrew_timer; /* timer handler */
add_timer(&vp->timer);
} else
dev->if_port = vp->default_media;
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index a7b0e5e43a52..de579d043169 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -287,7 +287,7 @@ static int elmc_open(struct net_device *dev)
elmc_id_attn586(); /* disable interrupts */
- ret = request_irq(dev->irq, elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+ ret = request_irq(dev->irq, elmc_interrupt, IRQF_SHARED,
dev->name, dev);
if (ret) {
pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq);
@@ -463,7 +463,7 @@ static int __init do_elmc_probe(struct net_device *dev)
/* we didn't find any 3c523 in the slots we checked for */
if (slot == MCA_NOTFOUND)
- return ((base_addr || irq) ? -ENXIO : -ENODEV);
+ return (base_addr || irq) ? -ENXIO : -ENODEV;
mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC");
mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index eca55c52bdfd..013b7c396663 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -443,7 +443,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
* Grab the IRQ
*/
- err = request_irq(dev->irq, mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev);
+ err = request_irq(dev->irq, mc32_interrupt, IRQF_SHARED, DRV_NAME, dev);
if (err) {
release_region(dev->base_addr, MC32_IO_EXTENT);
pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 179871d9e71f..e1da258bbfb7 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1742,7 +1742,7 @@ vortex_open(struct net_device *dev)
/* Use the now-standard shared IRQ implementation. */
if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
- &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
+ boomerang_interrupt : vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
goto err;
}
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 4a4f6b81e32d..ac422cd332ea 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -561,7 +561,7 @@ rx_status_loop:
if (cp_rx_csum_ok(status))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb_put(skb, len);
@@ -754,7 +754,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
}
#if CP_VLAN_TAG_USED
- if (cp->vlgrp && vlan_tx_tag_present(skb))
+ if (vlan_tx_tag_present(skb))
vlan_tag = TxVlanTag | swab16(vlan_tx_tag_get(skb));
#endif
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 77efe462b921..7ca1fc8a3a76 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -180,6 +180,13 @@ config NET_SB1000
source "drivers/net/arcnet/Kconfig"
+config MII
+ tristate "Generic Media Independent Interface device support"
+ help
+ Most ethernet controllers have MII transceiver either as an external
+ or internal device. It is safe to say Y or M here even if your
+ ethernet card lacks MII.
+
source "drivers/net/phy/Kconfig"
#
@@ -215,13 +222,6 @@ menuconfig NET_ETHERNET
if NET_ETHERNET
-config MII
- tristate "Generic Media Independent Interface device support"
- help
- Most ethernet controllers have MII transceiver either as an external
- or internal device. It is safe to say Y or M here even if your
- ethernet card lack MII.
-
config MACB
tristate "Atmel MACB support"
depends on HAVE_NET_MACB
@@ -2518,6 +2518,18 @@ config S6GMAC
source "drivers/net/stmmac/Kconfig"
+config PCH_GBE
+ tristate "PCH Gigabit Ethernet"
+ depends on PCI
+ ---help---
+ This is a gigabit ethernet driver for Topcliff PCH.
+ Topcliff PCH is the platform controller hub that is used in Intel's
+ general embedded platform.
+ Topcliff PCH has Gigabit Ethernet interface.
+ Using this interface, it is able to access system devices connected
+ to Gigabit Ethernet.
+ This driver enables Gigabit Ethernet function.
+
endif # NETDEV_1000
#
@@ -2872,6 +2884,20 @@ config QLGE
To compile this driver as a module, choose M here: the module
will be called qlge.
+config BNA
+ tristate "Brocade 1010/1020 10Gb Ethernet Driver support"
+ depends on PCI
+ ---help---
+ This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet
+ cards.
+ To compile this driver as a module, choose M here: the module
+ will be called bna.
+
+ For general information and support, go to the Brocade support
+ website at:
+
+ <http://support.brocade.com>
+
source "drivers/net/sfc/Kconfig"
source "drivers/net/benet/Kconfig"
@@ -3205,6 +3231,17 @@ config PPPOE
which contains instruction on how to use this driver (under
the heading "Kernel mode PPPoE").
+config PPTP
+ tristate "PPP over IPv4 (PPTP) (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && PPP && NET_IPGRE_DEMUX
+ help
+ Support for PPP over IPv4.(Point-to-Point Tunneling Protocol)
+
+ This driver requires pppd plugin to work in client mode or
+ modified pptpd (poptop) to work in server mode.
+ See http://accel-pptp.sourceforge.net/ for information how to
+ utilize this module.
+
config PPPOATM
tristate "PPP over ATM"
depends on ATM && PPP
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 3e8f150c4b14..b8bf93d4a132 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_ENIC) += enic/
obj-$(CONFIG_JME) += jme.o
obj-$(CONFIG_BE2NET) += benet/
obj-$(CONFIG_VMXNET3) += vmxnet3/
+obj-$(CONFIG_BNA) += bna/
gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o \
@@ -162,6 +163,7 @@ obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
obj-$(CONFIG_PPPOL2TP) += pppox.o
+obj-$(CONFIG_PPTP) += pppox.o pptp.o
obj-$(CONFIG_SLIP) += slip.o
obj-$(CONFIG_SLHC) += slhc.o
@@ -296,3 +298,4 @@ obj-$(CONFIG_WIMAX) += wimax/
obj-$(CONFIG_CAIF) += caif/
obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
+obj-$(CONFIG_PCH_GBE) += pch_gbe/
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index b9a591604e5b..41d9911202d0 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -2033,7 +2033,7 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
skb->csum = htons(csum);
skb->ip_summed = CHECKSUM_COMPLETE;
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
/* send it up */
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 585c25f4b60c..2ca880b4c0db 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -396,7 +396,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod)
event_count = coal_conf->rx_event_count;
if( timeout > MAX_TIMEOUT ||
event_count > MAX_EVENT_COUNT )
- return -EINVAL;
+ return -EINVAL;
timeout = timeout * DELAY_TIMER_CONV;
writel(VAL0|STINTEN, mmio+INTEN0);
@@ -409,7 +409,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod)
event_count = coal_conf->tx_event_count;
if( timeout > MAX_TIMEOUT ||
event_count > MAX_EVENT_COUNT )
- return -EINVAL;
+ return -EINVAL;
timeout = timeout * DELAY_TIMER_CONV;
@@ -903,18 +903,18 @@ static int amd8111e_read_mib(void __iomem *mmio, u8 MIB_COUNTER)
}
/*
-This function reads the mib registers and returns the hardware statistics. It updates previous internal driver statistics with new values.
-*/
-static struct net_device_stats *amd8111e_get_stats(struct net_device * dev)
+ * This function reads the mib registers and returns the hardware statistics.
+ * It updates previous internal driver statistics with new values.
+ */
+static struct net_device_stats *amd8111e_get_stats(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
void __iomem *mmio = lp->mmio;
unsigned long flags;
- /* struct net_device_stats *prev_stats = &lp->prev_stats; */
- struct net_device_stats* new_stats = &lp->stats;
+ struct net_device_stats *new_stats = &dev->stats;
- if(!lp->opened)
- return &lp->stats;
+ if (!lp->opened)
+ return new_stats;
spin_lock_irqsave (&lp->lock, flags);
/* stats.rx_packets */
@@ -1315,7 +1315,7 @@ static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb,
lp->tx_ring[tx_index].tx_flags = 0;
#if AMD8111E_VLAN_TAG_USED
- if((lp->vlgrp != NULL) && vlan_tx_tag_present(skb)){
+ if (vlan_tx_tag_present(skb)) {
lp->tx_ring[tx_index].tag_ctrl_cmd |=
cpu_to_le16(TCC_VLAN_INSERT);
lp->tx_ring[tx_index].tag_ctrl_info =
diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h
index ac36eb6981e3..b5926af03a7e 100644
--- a/drivers/net/amd8111e.h
+++ b/drivers/net/amd8111e.h
@@ -787,7 +787,6 @@ struct amd8111e_priv{
struct vlan_group *vlgrp;
#endif
char opened;
- struct net_device_stats stats;
unsigned int drv_rx_errors;
struct amd8111e_coalesce_conf coal_conf;
diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c
index 0362c8d31a08..10d0dba572c2 100644
--- a/drivers/net/appletalk/ipddp.c
+++ b/drivers/net/appletalk/ipddp.c
@@ -244,7 +244,7 @@ static int ipddp_delete(struct ipddp_route *rt)
}
spin_unlock_bh(&ipddp_route_lock);
- return (-ENOENT);
+ return -ENOENT;
}
/*
@@ -259,10 +259,10 @@ static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt)
if(f->ip == rt->ip &&
f->at.s_net == rt->at.s_net &&
f->at.s_node == rt->at.s_node)
- return (f);
+ return f;
}
- return (NULL);
+ return NULL;
}
static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -279,7 +279,7 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
switch(cmd)
{
case SIOCADDIPDDPRT:
- return (ipddp_create(&rcp));
+ return ipddp_create(&rcp);
case SIOCFINDIPDDPRT:
spin_lock_bh(&ipddp_route_lock);
@@ -297,7 +297,7 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -ENOENT;
case SIOCDELIPDDPRT:
- return (ipddp_delete(&rcp));
+ return ipddp_delete(&rcp);
default:
return -EINVAL;
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index adc07551739e..e69eead12ec7 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -727,7 +727,7 @@ static int sendup_buffer (struct net_device *dev)
if (ltc->command != LT_RCVLAP) {
printk("unknown command 0x%02x from ltpc card\n",ltc->command);
- return(-1);
+ return -1;
}
dnode = ltc->dnode;
snode = ltc->snode;
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 8c496fb1ac9e..62f21106efec 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -300,8 +300,6 @@ am79c961_open(struct net_device *dev)
struct dev_priv *priv = netdev_priv(dev);
int ret;
- memset (&priv->stats, 0, sizeof (priv->stats));
-
ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev);
if (ret)
return ret;
@@ -347,8 +345,7 @@ am79c961_close(struct net_device *dev)
*/
static struct net_device_stats *am79c961_getstats (struct net_device *dev)
{
- struct dev_priv *priv = netdev_priv(dev);
- return &priv->stats;
+ return &dev->stats;
}
static void am79c961_mc_hash(char *addr, unsigned short *hash)
@@ -510,14 +507,14 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv)
if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) {
am_writeword (dev, hdraddr + 2, RMD_OWN);
- priv->stats.rx_errors ++;
+ dev->stats.rx_errors++;
if (status & RMD_ERR) {
if (status & RMD_FRAM)
- priv->stats.rx_frame_errors ++;
+ dev->stats.rx_frame_errors++;
if (status & RMD_CRC)
- priv->stats.rx_crc_errors ++;
+ dev->stats.rx_crc_errors++;
} else if (status & RMD_STP)
- priv->stats.rx_length_errors ++;
+ dev->stats.rx_length_errors++;
continue;
}
@@ -531,12 +528,12 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv)
am_writeword(dev, hdraddr + 2, RMD_OWN);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- priv->stats.rx_bytes += len;
- priv->stats.rx_packets ++;
+ dev->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
} else {
am_writeword (dev, hdraddr + 2, RMD_OWN);
printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name);
- priv->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
break;
}
} while (1);
@@ -565,7 +562,7 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv)
if (status & TMD_ERR) {
u_int status2;
- priv->stats.tx_errors ++;
+ dev->stats.tx_errors++;
status2 = am_readword (dev, hdraddr + 6);
@@ -575,18 +572,18 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv)
am_writeword (dev, hdraddr + 6, 0);
if (status2 & TST_RTRY)
- priv->stats.collisions += 16;
+ dev->stats.collisions += 16;
if (status2 & TST_LCOL)
- priv->stats.tx_window_errors ++;
+ dev->stats.tx_window_errors++;
if (status2 & TST_LCAR)
- priv->stats.tx_carrier_errors ++;
+ dev->stats.tx_carrier_errors++;
if (status2 & TST_UFLO)
- priv->stats.tx_fifo_errors ++;
+ dev->stats.tx_fifo_errors++;
continue;
}
- priv->stats.tx_packets ++;
+ dev->stats.tx_packets++;
len = am_readword (dev, hdraddr + 4);
- priv->stats.tx_bytes += -len;
+ dev->stats.tx_bytes += -len;
} while (priv->txtail != priv->txhead);
netif_wake_queue(dev);
@@ -616,7 +613,7 @@ am79c961_interrupt(int irq, void *dev_id)
}
if (status & CSR0_MISS) {
handled = 1;
- priv->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
}
if (status & CSR0_CERR) {
handled = 1;
diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h
index 483009fe6ec2..fd634d32756b 100644
--- a/drivers/net/arm/am79c961a.h
+++ b/drivers/net/arm/am79c961a.h
@@ -130,7 +130,6 @@
#define ISALED0_LNKST 0x8000
struct dev_priv {
- struct net_device_stats stats;
unsigned long rxbuffer[RX_BUFFERS];
unsigned long txbuffer[TX_BUFFERS];
unsigned char txhead;
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 4a5ec9470aa1..5a77001b6d10 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -175,8 +175,6 @@ struct ep93xx_priv
struct net_device *dev;
struct napi_struct napi;
- struct net_device_stats stats;
-
struct mii_if_info mii;
u8 mdc_divisor;
};
@@ -230,12 +228,6 @@ static void ep93xx_mdio_write(struct net_device *dev, int phy_id, int reg, int d
pr_info("mdio write timed out\n");
}
-static struct net_device_stats *ep93xx_get_stats(struct net_device *dev)
-{
- struct ep93xx_priv *ep = netdev_priv(dev);
- return &(ep->stats);
-}
-
static int ep93xx_rx(struct net_device *dev, int processed, int budget)
{
struct ep93xx_priv *ep = netdev_priv(dev);
@@ -267,15 +259,15 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
pr_crit("entry mismatch %.8x %.8x\n", rstat0, rstat1);
if (!(rstat0 & RSTAT0_RWE)) {
- ep->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (rstat0 & RSTAT0_OE)
- ep->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
if (rstat0 & RSTAT0_FE)
- ep->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (rstat0 & (RSTAT0_RUNT | RSTAT0_EDATA))
- ep->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (rstat0 & RSTAT0_CRCE)
- ep->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
goto err;
}
@@ -300,10 +292,10 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
netif_receive_skb(skb);
- ep->stats.rx_packets++;
- ep->stats.rx_bytes += length;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += length;
} else {
- ep->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
err:
@@ -359,7 +351,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
int entry;
if (unlikely(skb->len > MAX_PKT_SIZE)) {
- ep->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -415,17 +407,17 @@ static void ep93xx_tx_complete(struct net_device *dev)
if (tstat0 & TSTAT0_TXWE) {
int length = ep->descs->tdesc[entry].tdesc1 & 0xfff;
- ep->stats.tx_packets++;
- ep->stats.tx_bytes += length;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += length;
} else {
- ep->stats.tx_errors++;
+ dev->stats.tx_errors++;
}
if (tstat0 & TSTAT0_OW)
- ep->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
if (tstat0 & TSTAT0_TXU)
- ep->stats.tx_fifo_errors++;
- ep->stats.collisions += (tstat0 >> 16) & 0x1f;
+ dev->stats.tx_fifo_errors++;
+ dev->stats.collisions += (tstat0 >> 16) & 0x1f;
ep->tx_clean_pointer = (entry + 1) & (TX_QUEUE_ENTRIES - 1);
if (ep->tx_pending == TX_QUEUE_ENTRIES)
@@ -758,7 +750,6 @@ static const struct net_device_ops ep93xx_netdev_ops = {
.ndo_open = ep93xx_open,
.ndo_stop = ep93xx_close,
.ndo_start_xmit = ep93xx_xmit,
- .ndo_get_stats = ep93xx_get_stats,
.ndo_do_ioctl = ep93xx_ioctl,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = eth_change_mtu,
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c
index b17ab5153f51..b00781c02d5d 100644
--- a/drivers/net/arm/ether1.c
+++ b/drivers/net/arm/ether1.c
@@ -68,7 +68,6 @@ static int ether1_open(struct net_device *dev);
static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t ether1_interrupt(int irq, void *dev_id);
static int ether1_close(struct net_device *dev);
-static struct net_device_stats *ether1_getstats(struct net_device *dev);
static void ether1_setmulticastlist(struct net_device *dev);
static void ether1_timeout(struct net_device *dev);
@@ -649,8 +648,6 @@ ether1_open (struct net_device *dev)
if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev))
return -EAGAIN;
- memset (&priv(dev)->stats, 0, sizeof (struct net_device_stats));
-
if (ether1_init_for_open (dev)) {
free_irq (dev->irq, dev);
return -EAGAIN;
@@ -673,7 +670,7 @@ ether1_timeout(struct net_device *dev)
if (ether1_init_for_open (dev))
printk (KERN_ERR "%s: unable to restart interface\n", dev->name);
- priv(dev)->stats.tx_errors++;
+ dev->stats.tx_errors++;
netif_wake_queue(dev);
}
@@ -802,21 +799,21 @@ again:
while (nop.nop_status & STAT_COMPLETE) {
if (nop.nop_status & STAT_OK) {
- priv(dev)->stats.tx_packets ++;
- priv(dev)->stats.collisions += (nop.nop_status & STAT_COLLISIONS);
+ dev->stats.tx_packets++;
+ dev->stats.collisions += (nop.nop_status & STAT_COLLISIONS);
} else {
- priv(dev)->stats.tx_errors ++;
+ dev->stats.tx_errors++;
if (nop.nop_status & STAT_COLLAFTERTX)
- priv(dev)->stats.collisions ++;
+ dev->stats.collisions++;
if (nop.nop_status & STAT_NOCARRIER)
- priv(dev)->stats.tx_carrier_errors ++;
+ dev->stats.tx_carrier_errors++;
if (nop.nop_status & STAT_TXLOSTCTS)
printk (KERN_WARNING "%s: cts lost\n", dev->name);
if (nop.nop_status & STAT_TXSLOWDMA)
- priv(dev)->stats.tx_fifo_errors ++;
+ dev->stats.tx_fifo_errors++;
if (nop.nop_status & STAT_COLLEXCESSIVE)
- priv(dev)->stats.collisions += 16;
+ dev->stats.collisions += 16;
}
if (nop.nop_link == caddr) {
@@ -879,13 +876,13 @@ ether1_recv_done (struct net_device *dev)
skb->protocol = eth_type_trans (skb, dev);
netif_rx (skb);
- priv(dev)->stats.rx_packets ++;
+ dev->stats.rx_packets++;
} else
- priv(dev)->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
} else {
printk(KERN_WARNING "%s: %s\n", dev->name,
(rbd.rbd_status & RBD_EOF) ? "oversized packet" : "acnt not valid");
- priv(dev)->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
}
nexttail = ether1_readw(dev, priv(dev)->rx_tail, rfd_t, rfd_link, NORMALIRQS);
@@ -939,7 +936,7 @@ ether1_interrupt (int irq, void *dev_id)
printk (KERN_WARNING "%s: RU went not ready: RU suspended\n", dev->name);
ether1_writew(dev, SCB_CMDRXRESUME, SCB_ADDR, scb_t, scb_command, NORMALIRQS);
writeb(CTRL_CA, REG_CONTROL);
- priv(dev)->stats.rx_dropped ++; /* we suspended due to lack of buffer space */
+ dev->stats.rx_dropped++; /* we suspended due to lack of buffer space */
} else
printk(KERN_WARNING "%s: RU went not ready: %04X\n", dev->name,
ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS));
@@ -962,12 +959,6 @@ ether1_close (struct net_device *dev)
return 0;
}
-static struct net_device_stats *
-ether1_getstats (struct net_device *dev)
-{
- return &priv(dev)->stats;
-}
-
/*
* Set or clear the multicast filter for this adaptor.
* num_addrs == -1 Promiscuous mode, receive all packets.
@@ -994,7 +985,6 @@ static const struct net_device_ops ether1_netdev_ops = {
.ndo_open = ether1_open,
.ndo_stop = ether1_close,
.ndo_start_xmit = ether1_sendpacket,
- .ndo_get_stats = ether1_getstats,
.ndo_set_multicast_list = ether1_setmulticastlist,
.ndo_tx_timeout = ether1_timeout,
.ndo_validate_addr = eth_validate_addr,
diff --git a/drivers/net/arm/ether1.h b/drivers/net/arm/ether1.h
index c8a4b2389d85..3a5830ab3dc7 100644
--- a/drivers/net/arm/ether1.h
+++ b/drivers/net/arm/ether1.h
@@ -38,7 +38,6 @@
struct ether1_priv {
void __iomem *base;
- struct net_device_stats stats;
unsigned int tx_link;
unsigned int tx_head;
volatile unsigned int tx_tail;
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index 1361b7367c28..44a8746f4014 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -81,7 +81,6 @@ static int ether3_open (struct net_device *dev);
static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev);
static irqreturn_t ether3_interrupt (int irq, void *dev_id);
static int ether3_close (struct net_device *dev);
-static struct net_device_stats *ether3_getstats (struct net_device *dev);
static void ether3_setmulticastlist (struct net_device *dev);
static void ether3_timeout(struct net_device *dev);
@@ -323,8 +322,6 @@ ether3_init_for_open(struct net_device *dev)
{
int i;
- memset(&priv(dev)->stats, 0, sizeof(struct net_device_stats));
-
/* Reset the chip */
ether3_outw(CFG2_RESET, REG_CONFIG2);
udelay(4);
@@ -442,15 +439,6 @@ ether3_close(struct net_device *dev)
}
/*
- * Get the current statistics. This may be called with the card open or
- * closed.
- */
-static struct net_device_stats *ether3_getstats(struct net_device *dev)
-{
- return &priv(dev)->stats;
-}
-
-/*
* Set or clear promiscuous/multicast mode filter for this adaptor.
*
* We don't attempt any packet filtering. The card may have a SEEQ 8004
@@ -490,7 +478,7 @@ static void ether3_timeout(struct net_device *dev)
local_irq_restore(flags);
priv(dev)->regs.config2 |= CFG2_CTRLO;
- priv(dev)->stats.tx_errors += 1;
+ dev->stats.tx_errors += 1;
ether3_outw(priv(dev)->regs.config2, REG_CONFIG2);
priv(dev)->tx_head = priv(dev)->tx_tail = 0;
@@ -509,7 +497,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
if (priv(dev)->broken) {
dev_kfree_skb(skb);
- priv(dev)->stats.tx_dropped ++;
+ dev->stats.tx_dropped++;
netif_start_queue(dev);
return NETDEV_TX_OK;
}
@@ -673,7 +661,7 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
} else
goto dropping;
} else {
- struct net_device_stats *stats = &priv(dev)->stats;
+ struct net_device_stats *stats = &dev->stats;
ether3_outw(next_ptr >> 8, REG_RECVEND);
if (status & RXSTAT_OVERSIZE) stats->rx_over_errors ++;
if (status & RXSTAT_CRCERROR) stats->rx_crc_errors ++;
@@ -685,14 +673,14 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
while (-- maxcnt);
done:
- priv(dev)->stats.rx_packets += received;
+ dev->stats.rx_packets += received;
priv(dev)->rx_head = next_ptr;
/*
* If rx went off line, then that means that the buffer may be full. We
* have dropped at least one packet.
*/
if (!(ether3_inw(REG_STATUS) & STAT_RXON)) {
- priv(dev)->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
ether3_outw(next_ptr, REG_RECVPTR);
ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND);
}
@@ -710,7 +698,7 @@ dropping:{
last_warned = jiffies;
printk("%s: memory squeeze, dropping packet.\n", dev->name);
}
- priv(dev)->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
goto done;
}
}
@@ -743,13 +731,13 @@ static void ether3_tx(struct net_device *dev)
* Update errors
*/
if (!(status & (TXSTAT_BABBLED | TXSTAT_16COLLISIONS)))
- priv(dev)->stats.tx_packets++;
+ dev->stats.tx_packets++;
else {
- priv(dev)->stats.tx_errors ++;
+ dev->stats.tx_errors++;
if (status & TXSTAT_16COLLISIONS)
- priv(dev)->stats.collisions += 16;
+ dev->stats.collisions += 16;
if (status & TXSTAT_BABBLED)
- priv(dev)->stats.tx_fifo_errors ++;
+ dev->stats.tx_fifo_errors++;
}
tx_tail = (tx_tail + 1) & 15;
@@ -773,7 +761,6 @@ static const struct net_device_ops ether3_netdev_ops = {
.ndo_open = ether3_open,
.ndo_stop = ether3_close,
.ndo_start_xmit = ether3_sendpacket,
- .ndo_get_stats = ether3_getstats,
.ndo_set_multicast_list = ether3_setmulticastlist,
.ndo_tx_timeout = ether3_timeout,
.ndo_validate_addr = eth_validate_addr,
diff --git a/drivers/net/arm/ether3.h b/drivers/net/arm/ether3.h
index 1921a3a07da7..2db63b08bdf3 100644
--- a/drivers/net/arm/ether3.h
+++ b/drivers/net/arm/ether3.h
@@ -164,7 +164,6 @@ struct dev_priv {
unsigned char tx_head; /* buffer nr to insert next packet */
unsigned char tx_tail; /* buffer nr of transmitting packet */
unsigned int rx_head; /* address to fetch next packet from */
- struct net_device_stats stats;
struct timer_list timer;
int broken; /* 0 = ok, 1 = something went wrong */
};
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index b57d7dee389a..3134e5326231 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -362,7 +362,7 @@ static void *slow_memcpy( void *dst, const void *src, size_t len )
*cto++ = *cfrom++;
MFPDELAY();
}
- return( dst );
+ return dst;
}
@@ -449,7 +449,7 @@ static noinline int __init addr_accessible(volatile void *regp, int wordflag,
vbr[2] = save_berr;
local_irq_restore(flags);
- return( ret );
+ return ret;
}
static const struct net_device_ops lance_netdev_ops = {
@@ -526,7 +526,7 @@ static unsigned long __init lance_probe1( struct net_device *dev,
goto probe_ok;
probe_fail:
- return( 0 );
+ return 0;
probe_ok:
lp = netdev_priv(dev);
@@ -556,7 +556,7 @@ static unsigned long __init lance_probe1( struct net_device *dev,
if (request_irq(IRQ_AUTO_5, lance_interrupt, IRQ_TYPE_PRIO,
"PAM/Riebl-ST Ethernet", dev)) {
printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 );
- return( 0 );
+ return 0;
}
dev->irq = (unsigned short)IRQ_AUTO_5;
}
@@ -568,12 +568,12 @@ static unsigned long __init lance_probe1( struct net_device *dev,
unsigned long irq = atari_register_vme_int();
if (!irq) {
printk( "Lance: request for VME interrupt failed\n" );
- return( 0 );
+ return 0;
}
if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
"Riebl-VME Ethernet", dev)) {
printk( "Lance: request for irq %ld failed\n", irq );
- return( 0 );
+ return 0;
}
dev->irq = irq;
}
@@ -637,7 +637,7 @@ static unsigned long __init lance_probe1( struct net_device *dev,
/* XXX MSch */
dev->watchdog_timeo = TX_TIMEOUT;
- return( 1 );
+ return 1;
}
@@ -666,7 +666,7 @@ static int lance_open( struct net_device *dev )
DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
dev->name, i, DREG ));
DREG = CSR0_STOP;
- return( -EIO );
+ return -EIO;
}
DREG = CSR0_IDON;
DREG = CSR0_STRT;
@@ -676,7 +676,7 @@ static int lance_open( struct net_device *dev )
DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
- return( 0 );
+ return 0;
}
@@ -1126,13 +1126,13 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
int i;
if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL)
- return( -EOPNOTSUPP );
+ return -EOPNOTSUPP;
if (netif_running(dev)) {
/* Only possible while card isn't started */
DPRINTK( 1, ( "%s: hwaddr can be set only while card isn't open.\n",
dev->name ));
- return( -EIO );
+ return -EIO;
}
memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len );
@@ -1142,7 +1142,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
/* set also the magic for future sessions */
*RIEBL_MAGIC_ADDR = RIEBL_MAGIC;
- return( 0 );
+ return 0;
}
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h
index 52abbbdf8a08..ef4115b897bf 100644
--- a/drivers/net/atl1c/atl1c.h
+++ b/drivers/net/atl1c/atl1c.h
@@ -559,7 +559,6 @@ struct atl1c_adapter {
struct napi_struct napi;
struct atl1c_hw hw;
struct atl1c_hw_stats hw_stats;
- struct net_device_stats net_stats;
struct mii_if_info mii; /* MII interface info */
u16 rx_buffer_len;
diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c
index d8501f060957..919080b2c3a5 100644
--- a/drivers/net/atl1c/atl1c_hw.c
+++ b/drivers/net/atl1c/atl1c_hw.c
@@ -480,7 +480,7 @@ int atl1c_phy_reset(struct atl1c_hw *hw)
atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x929D);
}
if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b2
- || hw->nic_type == athr_l2c || hw->nic_type == athr_l2c) {
+ || hw->nic_type == athr_l2c) {
atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29);
atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD);
}
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index c7b8ef507ebd..99ffcf667d1f 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -1562,7 +1562,7 @@ static struct net_device_stats *atl1c_get_stats(struct net_device *netdev)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw_stats *hw_stats = &adapter->hw_stats;
- struct net_device_stats *net_stats = &adapter->net_stats;
+ struct net_device_stats *net_stats = &netdev->stats;
atl1c_update_hw_stats(adapter);
net_stats->rx_packets = hw_stats->rx_ok;
@@ -1590,7 +1590,7 @@ static struct net_device_stats *atl1c_get_stats(struct net_device *netdev)
net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
net_stats->tx_window_errors = hw_stats->tx_late_col;
- return &adapter->net_stats;
+ return net_stats;
}
static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter)
@@ -1700,7 +1700,7 @@ static irqreturn_t atl1c_intr(int irq, void *data)
/* link event */
if (status & (ISR_GPHY | ISR_MANUAL)) {
- adapter->net_stats.tx_carrier_errors++;
+ netdev->stats.tx_carrier_errors++;
atl1c_link_chg_event(adapter);
break;
}
@@ -1719,7 +1719,7 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter,
* cannot figure out if the packet is fragmented or not,
* so we tell the KERNEL CHECKSUM_NONE
*/
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid)
@@ -2243,7 +2243,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
return NETDEV_TX_OK;
}
- if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+ if (unlikely(vlan_tx_tag_present(skb))) {
u16 vlan = vlan_tx_tag_get(skb);
__le16 tag;
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 1acea5774e89..ef6349bf3b33 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -1331,7 +1331,7 @@ static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter,
u16 pkt_flags;
u16 err_flags;
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
pkt_flags = prrs->pkt_flag;
err_flags = prrs->err_flag;
if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) &&
@@ -1814,7 +1814,7 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb,
tpd = atl1e_get_tpd(adapter);
- if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+ if (unlikely(vlan_tx_tag_present(skb))) {
u16 vlan_tag = vlan_tx_tag_get(skb);
u16 atl1e_vlan_tag;
@@ -2316,7 +2316,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
netif_napi_add(netdev, &adapter->napi, atl1e_clean, 64);
init_timer(&adapter->phy_config_timer);
- adapter->phy_config_timer.function = &atl1e_phy_config;
+ adapter->phy_config_timer.function = atl1e_phy_config;
adapter->phy_config_timer.data = (unsigned long) adapter;
/* get user settings */
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index c73be2848319..dbd27b8e66bd 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1811,7 +1811,7 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
* the higher layers and let it be sorted out there.
*/
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
@@ -2100,9 +2100,9 @@ static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
{
u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
u16 next_to_use = atomic_read(&tpd_ring->next_to_use);
- return ((next_to_clean > next_to_use) ?
+ return (next_to_clean > next_to_use) ?
next_to_clean - next_to_use - 1 :
- tpd_ring->count + next_to_clean - next_to_use - 1);
+ tpd_ring->count + next_to_clean - next_to_use - 1;
}
static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
@@ -2408,7 +2408,7 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
(u16) atomic_read(&tpd_ring->next_to_use));
memset(ptpd, 0, sizeof(struct tx_packet_desc));
- if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
vlan_tag = vlan_tx_tag_get(skb);
vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
((vlan_tag >> 9) & 0x8);
@@ -3043,7 +3043,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
netif_carrier_off(netdev);
netif_stop_queue(netdev);
- setup_timer(&adapter->phy_config_timer, &atl1_phy_config,
+ setup_timer(&adapter->phy_config_timer, atl1_phy_config,
(unsigned long)adapter);
adapter->phy_timer_pending = false;
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index 8da87383fb39..35b14bec1207 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -51,10 +51,10 @@
#define ATL2_DRV_VERSION "2.2.3"
-static char atl2_driver_name[] = "atl2";
+static const char atl2_driver_name[] = "atl2";
static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver";
-static char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation.";
-static char atl2_driver_version[] = ATL2_DRV_VERSION;
+static const char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation.";
+static const char atl2_driver_version[] = ATL2_DRV_VERSION;
MODULE_AUTHOR("Atheros Corporation <xiong.huang@atheros.com>, Chris Snook <csnook@redhat.com>");
MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver");
@@ -870,7 +870,7 @@ static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb,
offset = ((u32)(skb->len-copy_len + 3) & ~3);
}
#ifdef NETIF_F_HW_VLAN_TX
- if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
u16 vlan_tag = vlan_tx_tag_get(skb);
vlan_tag = (vlan_tag << 4) |
(vlan_tag >> 13) |
@@ -1444,11 +1444,11 @@ static int __devinit atl2_probe(struct pci_dev *pdev,
atl2_check_options(adapter);
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &atl2_watchdog;
+ adapter->watchdog_timer.function = atl2_watchdog;
adapter->watchdog_timer.data = (unsigned long) adapter;
init_timer(&adapter->phy_config_timer);
- adapter->phy_config_timer.function = &atl2_phy_config;
+ adapter->phy_config_timer.function = atl2_phy_config;
adapter->phy_config_timer.data = (unsigned long) adapter;
INIT_WORK(&adapter->reset_task, atl2_reset_task);
diff --git a/drivers/net/atp.c b/drivers/net/atp.c
index bd2f9d331dac..dfd96b20547f 100644
--- a/drivers/net/atp.c
+++ b/drivers/net/atp.c
@@ -445,7 +445,7 @@ static int net_open(struct net_device *dev)
init_timer(&lp->timer);
lp->timer.expires = jiffies + TIMED_CHECKER;
lp->timer.data = (unsigned long)dev;
- lp->timer.function = &atp_timed_checker; /* timer handler */
+ lp->timer.function = atp_timed_checker; /* timer handler */
add_timer(&lp->timer);
netif_start_queue(dev);
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 15ae6df2ff00..43489f89c142 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -13,7 +13,7 @@
* converted to use linux-2.6.x's PHY framework
*
* Author: MontaVista Software, Inc.
- * ppopov@mvista.com or source@mvista.com
+ * ppopov@mvista.com or source@mvista.com
*
* ########################################################################
*
@@ -34,6 +34,8 @@
*
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/capability.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
@@ -56,11 +58,11 @@
#include <linux/crc32.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <linux/io.h>
-#include <asm/cpu.h>
#include <asm/mipsregs.h>
#include <asm/irq.h>
-#include <asm/io.h>
#include <asm/processor.h>
#include <au1000.h>
@@ -152,11 +154,11 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
spin_lock_irqsave(&aup->lock, flags);
- if(force_reset || (!aup->mac_enabled)) {
- *aup->enable = MAC_EN_CLOCK_ENABLE;
+ if (force_reset || (!aup->mac_enabled)) {
+ writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
au_sync_delay(2);
- *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
- | MAC_EN_CLOCK_ENABLE);
+ writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
+ | MAC_EN_CLOCK_ENABLE), &aup->enable);
au_sync_delay(2);
aup->mac_enabled = 1;
@@ -171,12 +173,12 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
{
struct au1000_private *aup = netdev_priv(dev);
- volatile u32 *const mii_control_reg = &aup->mac->mii_control;
- volatile u32 *const mii_data_reg = &aup->mac->mii_data;
+ u32 *const mii_control_reg = &aup->mac->mii_control;
+ u32 *const mii_data_reg = &aup->mac->mii_data;
u32 timedout = 20;
u32 mii_control;
- while (*mii_control_reg & MAC_MII_BUSY) {
+ while (readl(mii_control_reg) & MAC_MII_BUSY) {
mdelay(1);
if (--timedout == 0) {
netdev_err(dev, "read_MII busy timeout!!\n");
@@ -187,29 +189,29 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
mii_control = MAC_SET_MII_SELECT_REG(reg) |
MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_READ;
- *mii_control_reg = mii_control;
+ writel(mii_control, mii_control_reg);
timedout = 20;
- while (*mii_control_reg & MAC_MII_BUSY) {
+ while (readl(mii_control_reg) & MAC_MII_BUSY) {
mdelay(1);
if (--timedout == 0) {
netdev_err(dev, "mdio_read busy timeout!!\n");
return -1;
}
}
- return (int)*mii_data_reg;
+ return readl(mii_data_reg);
}
static void au1000_mdio_write(struct net_device *dev, int phy_addr,
int reg, u16 value)
{
struct au1000_private *aup = netdev_priv(dev);
- volatile u32 *const mii_control_reg = &aup->mac->mii_control;
- volatile u32 *const mii_data_reg = &aup->mac->mii_data;
+ u32 *const mii_control_reg = &aup->mac->mii_control;
+ u32 *const mii_data_reg = &aup->mac->mii_data;
u32 timedout = 20;
u32 mii_control;
- while (*mii_control_reg & MAC_MII_BUSY) {
+ while (readl(mii_control_reg) & MAC_MII_BUSY) {
mdelay(1);
if (--timedout == 0) {
netdev_err(dev, "mdio_write busy timeout!!\n");
@@ -220,18 +222,22 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr,
mii_control = MAC_SET_MII_SELECT_REG(reg) |
MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_WRITE;
- *mii_data_reg = value;
- *mii_control_reg = mii_control;
+ writel(value, mii_data_reg);
+ writel(mii_control, mii_control_reg);
}
static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
{
/* WARNING: bus->phy_map[phy_addr].attached_dev == dev does
- * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */
+ * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus)
+ */
struct net_device *const dev = bus->priv;
- au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
- * mii_bus is enabled */
+ /* make sure the MAC associated with this
+ * mii_bus is enabled
+ */
+ au1000_enable_mac(dev, 0);
+
return au1000_mdio_read(dev, phy_addr, regnum);
}
@@ -240,8 +246,11 @@ static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
{
struct net_device *const dev = bus->priv;
- au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
- * mii_bus is enabled */
+ /* make sure the MAC associated with this
+ * mii_bus is enabled
+ */
+ au1000_enable_mac(dev, 0);
+
au1000_mdio_write(dev, phy_addr, regnum, value);
return 0;
}
@@ -250,28 +259,37 @@ static int au1000_mdiobus_reset(struct mii_bus *bus)
{
struct net_device *const dev = bus->priv;
- au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
- * mii_bus is enabled */
+ /* make sure the MAC associated with this
+ * mii_bus is enabled
+ */
+ au1000_enable_mac(dev, 0);
+
return 0;
}
static void au1000_hard_stop(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
+ u32 reg;
netif_dbg(aup, drv, dev, "hard stop\n");
- aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
+ reg = readl(&aup->mac->control);
+ reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
+ writel(reg, &aup->mac->control);
au_sync_delay(10);
}
static void au1000_enable_rx_tx(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
+ u32 reg;
netif_dbg(aup, hw, dev, "enable_rx_tx\n");
- aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+ reg = readl(&aup->mac->control);
+ reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+ writel(reg, &aup->mac->control);
au_sync_delay(10);
}
@@ -281,6 +299,7 @@ au1000_adjust_link(struct net_device *dev)
struct au1000_private *aup = netdev_priv(dev);
struct phy_device *phydev = aup->phy_dev;
unsigned long flags;
+ u32 reg;
int status_change = 0;
@@ -312,14 +331,15 @@ au1000_adjust_link(struct net_device *dev)
/* switching duplex mode requires to disable rx and tx! */
au1000_hard_stop(dev);
- if (DUPLEX_FULL == phydev->duplex)
- aup->mac->control = ((aup->mac->control
- | MAC_FULL_DUPLEX)
- & ~MAC_DISABLE_RX_OWN);
- else
- aup->mac->control = ((aup->mac->control
- & ~MAC_FULL_DUPLEX)
- | MAC_DISABLE_RX_OWN);
+ reg = readl(&aup->mac->control);
+ if (DUPLEX_FULL == phydev->duplex) {
+ reg |= MAC_FULL_DUPLEX;
+ reg &= ~MAC_DISABLE_RX_OWN;
+ } else {
+ reg &= ~MAC_FULL_DUPLEX;
+ reg |= MAC_DISABLE_RX_OWN;
+ }
+ writel(reg, &aup->mac->control);
au_sync_delay(1);
au1000_enable_rx_tx(dev);
@@ -353,10 +373,11 @@ au1000_adjust_link(struct net_device *dev)
}
}
-static int au1000_mii_probe (struct net_device *dev)
+static int au1000_mii_probe(struct net_device *dev)
{
struct au1000_private *const aup = netdev_priv(dev);
struct phy_device *phydev = NULL;
+ int phy_addr;
if (aup->phy_static_config) {
BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
@@ -366,42 +387,46 @@ static int au1000_mii_probe (struct net_device *dev)
else
netdev_info(dev, "using PHY-less setup\n");
return 0;
- } else {
- int phy_addr;
-
- /* find the first (lowest address) PHY on the current MAC's MII bus */
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
- if (aup->mii_bus->phy_map[phy_addr]) {
- phydev = aup->mii_bus->phy_map[phy_addr];
- if (!aup->phy_search_highest_addr)
- break; /* break out with first one found */
- }
-
- if (aup->phy1_search_mac0) {
- /* try harder to find a PHY */
- if (!phydev && (aup->mac_id == 1)) {
- /* no PHY found, maybe we have a dual PHY? */
- dev_info(&dev->dev, ": no PHY found on MAC1, "
- "let's see if it's attached to MAC0...\n");
-
- /* find the first (lowest address) non-attached PHY on
- * the MAC0 MII bus */
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
- struct phy_device *const tmp_phydev =
- aup->mii_bus->phy_map[phy_addr];
-
- if (aup->mac_id == 1)
- break;
-
- if (!tmp_phydev)
- continue; /* no PHY here... */
+ }
- if (tmp_phydev->attached_dev)
- continue; /* already claimed by MAC0 */
+ /* find the first (lowest address) PHY
+ * on the current MAC's MII bus
+ */
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
+ if (aup->mii_bus->phy_map[phy_addr]) {
+ phydev = aup->mii_bus->phy_map[phy_addr];
+ if (!aup->phy_search_highest_addr)
+ /* break out with first one found */
+ break;
+ }
- phydev = tmp_phydev;
- break; /* found it */
- }
+ if (aup->phy1_search_mac0) {
+ /* try harder to find a PHY */
+ if (!phydev && (aup->mac_id == 1)) {
+ /* no PHY found, maybe we have a dual PHY? */
+ dev_info(&dev->dev, ": no PHY found on MAC1, "
+ "let's see if it's attached to MAC0...\n");
+
+ /* find the first (lowest address) non-attached
+ * PHY on the MAC0 MII bus
+ */
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+ struct phy_device *const tmp_phydev =
+ aup->mii_bus->phy_map[phy_addr];
+
+ if (aup->mac_id == 1)
+ break;
+
+ /* no PHY here... */
+ if (!tmp_phydev)
+ continue;
+
+ /* already claimed by MAC0 */
+ if (tmp_phydev->attached_dev)
+ continue;
+
+ phydev = tmp_phydev;
+ break; /* found it */
}
}
}
@@ -452,20 +477,20 @@ static int au1000_mii_probe (struct net_device *dev)
* has the virtual and dma address of a buffer suitable for
* both, receive and transmit operations.
*/
-static db_dest_t *au1000_GetFreeDB(struct au1000_private *aup)
+static struct db_dest *au1000_GetFreeDB(struct au1000_private *aup)
{
- db_dest_t *pDB;
+ struct db_dest *pDB;
pDB = aup->pDBfree;
- if (pDB) {
+ if (pDB)
aup->pDBfree = pDB->pnext;
- }
+
return pDB;
}
-void au1000_ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
+void au1000_ReleaseDB(struct au1000_private *aup, struct db_dest *pDB)
{
- db_dest_t *pDBfree = aup->pDBfree;
+ struct db_dest *pDBfree = aup->pDBfree;
if (pDBfree)
pDBfree->pnext = pDB;
aup->pDBfree = pDB;
@@ -478,9 +503,9 @@ static void au1000_reset_mac_unlocked(struct net_device *dev)
au1000_hard_stop(dev);
- *aup->enable = MAC_EN_CLOCK_ENABLE;
+ writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
au_sync_delay(2);
- *aup->enable = 0;
+ writel(0, &aup->enable);
au_sync_delay(2);
aup->tx_full = 0;
@@ -507,7 +532,7 @@ static void au1000_reset_mac(struct net_device *dev)
spin_lock_irqsave(&aup->lock, flags);
- au1000_reset_mac_unlocked (dev);
+ au1000_reset_mac_unlocked(dev);
spin_unlock_irqrestore(&aup->lock, flags);
}
@@ -524,11 +549,13 @@ au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
for (i = 0; i < NUM_RX_DMA; i++) {
aup->rx_dma_ring[i] =
- (volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i);
+ (struct rx_dma *)
+ (rx_base + sizeof(struct rx_dma)*i);
}
for (i = 0; i < NUM_TX_DMA; i++) {
aup->tx_dma_ring[i] =
- (volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i);
+ (struct tx_dma *)
+ (tx_base + sizeof(struct tx_dma)*i);
}
}
@@ -616,18 +643,21 @@ static int au1000_init(struct net_device *dev)
spin_lock_irqsave(&aup->lock, flags);
- aup->mac->control = 0;
+ writel(0, &aup->mac->control);
aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2;
aup->tx_tail = aup->tx_head;
aup->rx_head = (aup->rx_dma_ring[0]->buff_stat & 0xC) >> 2;
- aup->mac->mac_addr_high = dev->dev_addr[5]<<8 | dev->dev_addr[4];
- aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
- dev->dev_addr[1]<<8 | dev->dev_addr[0];
+ writel(dev->dev_addr[5]<<8 | dev->dev_addr[4],
+ &aup->mac->mac_addr_high);
+ writel(dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
+ dev->dev_addr[1]<<8 | dev->dev_addr[0],
+ &aup->mac->mac_addr_low);
- for (i = 0; i < NUM_RX_DMA; i++) {
+
+ for (i = 0; i < NUM_RX_DMA; i++)
aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
- }
+
au_sync();
control = MAC_RX_ENABLE | MAC_TX_ENABLE;
@@ -643,8 +673,8 @@ static int au1000_init(struct net_device *dev)
control |= MAC_FULL_DUPLEX;
}
- aup->mac->control = control;
- aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
+ writel(control, &aup->mac->control);
+ writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */
au_sync();
spin_unlock_irqrestore(&aup->lock, flags);
@@ -681,9 +711,9 @@ static int au1000_rx(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
struct sk_buff *skb;
- volatile rx_dma_t *prxd;
+ struct rx_dma *prxd;
u32 buff_stat, status;
- db_dest_t *pDB;
+ struct db_dest *pDB;
u32 frmlen;
netif_dbg(aup, rx_status, dev, "au1000_rx head %d\n", aup->rx_head);
@@ -713,24 +743,26 @@ static int au1000_rx(struct net_device *dev)
netif_rx(skb); /* pass the packet to upper layers */
} else {
if (au1000_debug > 4) {
+ pr_err("rx_error(s):");
if (status & RX_MISSED_FRAME)
- printk("rx miss\n");
+ pr_cont(" miss");
if (status & RX_WDOG_TIMER)
- printk("rx wdog\n");
+ pr_cont(" wdog");
if (status & RX_RUNT)
- printk("rx runt\n");
+ pr_cont(" runt");
if (status & RX_OVERLEN)
- printk("rx overlen\n");
+ pr_cont(" overlen");
if (status & RX_COLL)
- printk("rx coll\n");
+ pr_cont(" coll");
if (status & RX_MII_ERROR)
- printk("rx mii error\n");
+ pr_cont(" mii error");
if (status & RX_CRC_ERROR)
- printk("rx crc error\n");
+ pr_cont(" crc error");
if (status & RX_LEN_ERROR)
- printk("rx len error\n");
+ pr_cont(" len error");
if (status & RX_U_CNTRL_FRAME)
- printk("rx u control frame\n");
+ pr_cont(" u control frame");
+ pr_cont("\n");
}
}
prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
@@ -753,7 +785,8 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status)
if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
/* any other tx errors are only valid
- * in half duplex mode */
+ * in half duplex mode
+ */
ps->tx_errors++;
ps->tx_aborted_errors++;
}
@@ -774,7 +807,7 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status)
static void au1000_tx_ack(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
- volatile tx_dma_t *ptxd;
+ struct tx_dma *ptxd;
ptxd = aup->tx_dma_ring[aup->tx_tail];
@@ -854,7 +887,7 @@ static int au1000_close(struct net_device *dev)
spin_lock_irqsave(&aup->lock, flags);
- au1000_reset_mac_unlocked (dev);
+ au1000_reset_mac_unlocked(dev);
/* stop the device */
netif_stop_queue(dev);
@@ -873,9 +906,9 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
struct net_device_stats *ps = &dev->stats;
- volatile tx_dma_t *ptxd;
+ struct tx_dma *ptxd;
u32 buff_stat;
- db_dest_t *pDB;
+ struct db_dest *pDB;
int i;
netif_dbg(aup, tx_queued, dev, "tx: aup %x len=%d, data=%p, head %d\n",
@@ -902,9 +935,9 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
pDB = aup->tx_db_inuse[aup->tx_head];
skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
if (skb->len < ETH_ZLEN) {
- for (i = skb->len; i < ETH_ZLEN; i++) {
+ for (i = skb->len; i < ETH_ZLEN; i++)
((char *)pDB->vaddr)[i] = 0;
- }
+
ptxd->len = ETH_ZLEN;
} else
ptxd->len = skb->len;
@@ -935,15 +968,16 @@ static void au1000_tx_timeout(struct net_device *dev)
static void au1000_multicast_list(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
+ u32 reg;
- netif_dbg(aup, drv, dev, "au1000_multicast_list: flags=%x\n", dev->flags);
-
+ netif_dbg(aup, drv, dev, "%s: flags=%x\n", __func__, dev->flags);
+ reg = readl(&aup->mac->control);
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
- aup->mac->control |= MAC_PROMISCUOUS;
+ reg |= MAC_PROMISCUOUS;
} else if ((dev->flags & IFF_ALLMULTI) ||
netdev_mc_count(dev) > MULTICAST_FILTER_LIMIT) {
- aup->mac->control |= MAC_PASS_ALL_MULTI;
- aup->mac->control &= ~MAC_PROMISCUOUS;
+ reg |= MAC_PASS_ALL_MULTI;
+ reg &= ~MAC_PROMISCUOUS;
netdev_info(dev, "Pass all multicast\n");
} else {
struct netdev_hw_addr *ha;
@@ -953,11 +987,12 @@ static void au1000_multicast_list(struct net_device *dev)
netdev_for_each_mc_addr(ha, dev)
set_bit(ether_crc(ETH_ALEN, ha->addr)>>26,
(long *)mc_filter);
- aup->mac->multi_hash_high = mc_filter[1];
- aup->mac->multi_hash_low = mc_filter[0];
- aup->mac->control &= ~MAC_PROMISCUOUS;
- aup->mac->control |= MAC_HASH_MODE;
+ writel(mc_filter[1], &aup->mac->multi_hash_high);
+ writel(mc_filter[0], &aup->mac->multi_hash_low);
+ reg &= ~MAC_PROMISCUOUS;
+ reg |= MAC_HASH_MODE;
}
+ writel(reg, &aup->mac->control);
}
static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -991,7 +1026,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
struct au1000_private *aup = NULL;
struct au1000_eth_platform_data *pd;
struct net_device *dev = NULL;
- db_dest_t *pDB, *pDBfree;
+ struct db_dest *pDB, *pDBfree;
int irq, i, err = 0;
struct resource *base, *macen;
@@ -1016,13 +1051,15 @@ static int __devinit au1000_probe(struct platform_device *pdev)
goto out;
}
- if (!request_mem_region(base->start, resource_size(base), pdev->name)) {
+ if (!request_mem_region(base->start, resource_size(base),
+ pdev->name)) {
dev_err(&pdev->dev, "failed to request memory region for base registers\n");
err = -ENXIO;
goto out;
}
- if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) {
+ if (!request_mem_region(macen->start, resource_size(macen),
+ pdev->name)) {
dev_err(&pdev->dev, "failed to request memory region for MAC enable register\n");
err = -ENXIO;
goto err_request;
@@ -1040,10 +1077,12 @@ static int __devinit au1000_probe(struct platform_device *pdev)
aup = netdev_priv(dev);
spin_lock_init(&aup->lock);
- aup->msg_enable = (au1000_debug < 4 ? AU1000_DEF_MSG_ENABLE : au1000_debug);
+ aup->msg_enable = (au1000_debug < 4 ?
+ AU1000_DEF_MSG_ENABLE : au1000_debug);
- /* Allocate the data buffers */
- /* Snooping works fine with eth on all au1xxx */
+ /* Allocate the data buffers
+ * Snooping works fine with eth on all au1xxx
+ */
aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
(NUM_TX_BUFFS + NUM_RX_BUFFS),
&aup->dma_addr, 0);
@@ -1054,15 +1093,17 @@ static int __devinit au1000_probe(struct platform_device *pdev)
}
/* aup->mac is the base address of the MAC's registers */
- aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base));
+ aup->mac = (struct mac_reg *)
+ ioremap_nocache(base->start, resource_size(base));
if (!aup->mac) {
dev_err(&pdev->dev, "failed to ioremap MAC registers\n");
err = -ENXIO;
goto err_remap1;
}
- /* Setup some variables for quick register address access */
- aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen));
+ /* Setup some variables for quick register address access */
+ aup->enable = (u32 *)ioremap_nocache(macen->start,
+ resource_size(macen));
if (!aup->enable) {
dev_err(&pdev->dev, "failed to ioremap MAC enable register\n");
err = -ENXIO;
@@ -1078,12 +1119,13 @@ static int __devinit au1000_probe(struct platform_device *pdev)
/* set a random MAC now in case platform_data doesn't provide one */
random_ether_addr(dev->dev_addr);
- *aup->enable = 0;
+ writel(0, &aup->enable);
aup->mac_enabled = 0;
pd = pdev->dev.platform_data;
if (!pd) {
- dev_info(&pdev->dev, "no platform_data passed, PHY search on MAC0\n");
+ dev_info(&pdev->dev, "no platform_data passed,"
+ " PHY search on MAC0\n");
aup->phy1_search_mac0 = 1;
} else {
if (is_valid_ether_addr(pd->mac))
@@ -1098,8 +1140,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
}
if (aup->phy_busid && aup->phy_busid > 0) {
- dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII"
- "bus not supported yet\n");
+ dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII bus not supported yet\n");
err = -ENODEV;
goto err_mdiobus_alloc;
}
@@ -1151,17 +1192,17 @@ static int __devinit au1000_probe(struct platform_device *pdev)
for (i = 0; i < NUM_RX_DMA; i++) {
pDB = au1000_GetFreeDB(aup);
- if (!pDB) {
+ if (!pDB)
goto err_out;
- }
+
aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
aup->rx_db_inuse[i] = pDB;
}
for (i = 0; i < NUM_TX_DMA; i++) {
pDB = au1000_GetFreeDB(aup);
- if (!pDB) {
+ if (!pDB)
goto err_out;
- }
+
aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
aup->tx_dma_ring[i]->len = 0;
aup->tx_db_inuse[i] = pDB;
@@ -1188,7 +1229,8 @@ static int __devinit au1000_probe(struct platform_device *pdev)
netdev_info(dev, "Au1xx0 Ethernet found at 0x%lx, irq %d\n",
(unsigned long)base->start, irq);
if (version_printed++ == 0)
- printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+ pr_info("%s version %s %s\n",
+ DRV_NAME, DRV_VERSION, DRV_AUTHOR);
return 0;
@@ -1197,7 +1239,8 @@ err_out:
mdiobus_unregister(aup->mii_bus);
/* here we should have a valid dev plus aup-> register addresses
- * so we can reset the mac properly.*/
+ * so we can reset the mac properly.
+ */
au1000_reset_mac(dev);
for (i = 0; i < NUM_RX_DMA; i++) {
diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
index d06ec008fbf1..6229c774552c 100644
--- a/drivers/net/au1000_eth.h
+++ b/drivers/net/au1000_eth.h
@@ -44,34 +44,34 @@
* Data Buffer Descriptor. Data buffers must be aligned on 32 byte
* boundary for both, receive and transmit.
*/
-typedef struct db_dest {
+struct db_dest {
struct db_dest *pnext;
- volatile u32 *vaddr;
+ u32 *vaddr;
dma_addr_t dma_addr;
-} db_dest_t;
+};
/*
* The transmit and receive descriptors are memory
* mapped registers.
*/
-typedef struct tx_dma {
+struct tx_dma {
u32 status;
u32 buff_stat;
u32 len;
u32 pad;
-} tx_dma_t;
+};
-typedef struct rx_dma {
+struct rx_dma {
u32 status;
u32 buff_stat;
u32 pad[2];
-} rx_dma_t;
+};
/*
* MAC control registers, memory mapped.
*/
-typedef struct mac_reg {
+struct mac_reg {
u32 control;
u32 mac_addr_high;
u32 mac_addr_low;
@@ -82,16 +82,16 @@ typedef struct mac_reg {
u32 flow_control;
u32 vlan1_tag;
u32 vlan2_tag;
-} mac_reg_t;
+};
struct au1000_private {
- db_dest_t *pDBfree;
- db_dest_t db[NUM_RX_BUFFS+NUM_TX_BUFFS];
- volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA];
- volatile tx_dma_t *tx_dma_ring[NUM_TX_DMA];
- db_dest_t *rx_db_inuse[NUM_RX_DMA];
- db_dest_t *tx_db_inuse[NUM_TX_DMA];
+ struct db_dest *pDBfree;
+ struct db_dest db[NUM_RX_BUFFS+NUM_TX_BUFFS];
+ struct rx_dma *rx_dma_ring[NUM_RX_DMA];
+ struct tx_dma *tx_dma_ring[NUM_TX_DMA];
+ struct db_dest *rx_db_inuse[NUM_RX_DMA];
+ struct db_dest *tx_db_inuse[NUM_TX_DMA];
u32 rx_head;
u32 tx_head;
u32 tx_tail;
@@ -99,7 +99,9 @@ struct au1000_private {
int mac_id;
- int mac_enabled; /* whether MAC is currently enabled and running (req. for mdio) */
+ int mac_enabled; /* whether MAC is currently enabled and running
+ * (req. for mdio)
+ */
int old_link; /* used by au1000_adjust_link */
int old_speed;
@@ -117,9 +119,11 @@ struct au1000_private {
int phy_busid;
int phy_irq;
- /* These variables are just for quick access to certain regs addresses. */
- volatile mac_reg_t *mac; /* mac registers */
- volatile u32 *enable; /* address of MAC Enable Register */
+ /* These variables are just for quick access
+ * to certain regs addresses.
+ */
+ struct mac_reg *mac; /* mac registers */
+ u32 *enable; /* address of MAC Enable Register */
u32 vaddr; /* virtual address of rx/tx buffers */
dma_addr_t dma_addr; /* dma address of rx/tx buffers */
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 20e946b1e744..b6da4cf3694b 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -864,6 +864,7 @@ static int ax_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (res == NULL) {
dev_err(&pdev->dev, "no IRQ specified\n");
+ ret = -ENXIO;
goto exit_mem;
}
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index efeffdf9e5fa..c6e86315b3f8 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -818,7 +818,7 @@ static int b44_rx(struct b44 *bp, int budget)
copy_skb->data, len);
skb = copy_skb;
}
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, bp->dev);
netif_receive_skb(skb);
received++;
@@ -2296,18 +2296,27 @@ static int b44_resume(struct ssb_device *sdev)
if (!netif_running(dev))
return 0;
+ spin_lock_irq(&bp->lock);
+ b44_init_rings(bp);
+ b44_init_hw(bp, B44_FULL_RESET);
+ spin_unlock_irq(&bp->lock);
+
+ /*
+ * As a shared interrupt, the handler can be called immediately. To be
+ * able to check the interrupt status the hardware must already be
+ * powered back on (b44_init_hw).
+ */
rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev);
if (rc) {
netdev_err(dev, "request_irq failed\n");
+ spin_lock_irq(&bp->lock);
+ b44_halt(bp);
+ b44_free_rings(bp);
+ spin_unlock_irq(&bp->lock);
return rc;
}
- spin_lock_irq(&bp->lock);
-
- b44_init_rings(bp);
- b44_init_hw(bp, B44_FULL_RESET);
netif_device_attach(bp->dev);
- spin_unlock_irq(&bp->lock);
b44_enable_ints(bp);
netif_wake_queue(dev);
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index 0d2c5da08937..ecfef240a303 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -293,22 +293,22 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget)
/* if the packet does not have start of packet _and_
* end of packet flag set, then just recycle it */
if ((len_stat & DMADESC_ESOP_MASK) != DMADESC_ESOP_MASK) {
- priv->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
continue;
}
/* recycle packet if it's marked as bad */
if (unlikely(len_stat & DMADESC_ERR_MASK)) {
- priv->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (len_stat & DMADESC_OVSIZE_MASK)
- priv->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (len_stat & DMADESC_CRC_MASK)
- priv->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if (len_stat & DMADESC_UNDER_MASK)
- priv->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (len_stat & DMADESC_OV_MASK)
- priv->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
continue;
}
@@ -324,7 +324,7 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget)
nskb = netdev_alloc_skb_ip_align(dev, len);
if (!nskb) {
/* forget packet, just rearm desc */
- priv->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
continue;
}
@@ -342,8 +342,8 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget)
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, dev);
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
netif_receive_skb(skb);
} while (--budget > 0);
@@ -403,7 +403,7 @@ static int bcm_enet_tx_reclaim(struct net_device *dev, int force)
spin_unlock(&priv->tx_lock);
if (desc->len_stat & DMADESC_UNDER_MASK)
- priv->stats.tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb(skb);
released++;
@@ -563,8 +563,8 @@ static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!priv->tx_desc_count)
netif_stop_queue(dev);
- priv->stats.tx_bytes += skb->len;
- priv->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
ret = NETDEV_TX_OK;
out_unlock:
@@ -798,7 +798,7 @@ static int bcm_enet_open(struct net_device *dev)
snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
priv->mac_id ? "1" : "0", priv->phy_id);
- phydev = phy_connect(dev, phy_id, &bcm_enet_adjust_phy_link, 0,
+ phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0,
PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev)) {
@@ -1141,17 +1141,6 @@ static int bcm_enet_stop(struct net_device *dev)
}
/*
- * core request to return device rx/tx stats
- */
-static struct net_device_stats *bcm_enet_get_stats(struct net_device *dev)
-{
- struct bcm_enet_priv *priv;
-
- priv = netdev_priv(dev);
- return &priv->stats;
-}
-
-/*
* ethtool callbacks
*/
struct bcm_enet_stats {
@@ -1163,16 +1152,18 @@ struct bcm_enet_stats {
#define GEN_STAT(m) sizeof(((struct bcm_enet_priv *)0)->m), \
offsetof(struct bcm_enet_priv, m)
+#define DEV_STAT(m) sizeof(((struct net_device_stats *)0)->m), \
+ offsetof(struct net_device_stats, m)
static const struct bcm_enet_stats bcm_enet_gstrings_stats[] = {
- { "rx_packets", GEN_STAT(stats.rx_packets), -1 },
- { "tx_packets", GEN_STAT(stats.tx_packets), -1 },
- { "rx_bytes", GEN_STAT(stats.rx_bytes), -1 },
- { "tx_bytes", GEN_STAT(stats.tx_bytes), -1 },
- { "rx_errors", GEN_STAT(stats.rx_errors), -1 },
- { "tx_errors", GEN_STAT(stats.tx_errors), -1 },
- { "rx_dropped", GEN_STAT(stats.rx_dropped), -1 },
- { "tx_dropped", GEN_STAT(stats.tx_dropped), -1 },
+ { "rx_packets", DEV_STAT(rx_packets), -1 },
+ { "tx_packets", DEV_STAT(tx_packets), -1 },
+ { "rx_bytes", DEV_STAT(rx_bytes), -1 },
+ { "tx_bytes", DEV_STAT(tx_bytes), -1 },
+ { "rx_errors", DEV_STAT(rx_errors), -1 },
+ { "tx_errors", DEV_STAT(tx_errors), -1 },
+ { "rx_dropped", DEV_STAT(rx_dropped), -1 },
+ { "tx_dropped", DEV_STAT(tx_dropped), -1 },
{ "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETH_MIB_RX_GD_OCTETS},
{ "rx_good_pkts", GEN_STAT(mib.rx_gd_pkts), ETH_MIB_RX_GD_PKTS },
@@ -1328,7 +1319,11 @@ static void bcm_enet_get_ethtool_stats(struct net_device *netdev,
char *p;
s = &bcm_enet_gstrings_stats[i];
- p = (char *)priv + s->stat_offset;
+ if (s->mib_reg == -1)
+ p = (char *)&netdev->stats;
+ else
+ p = (char *)priv;
+ p += s->stat_offset;
data[i] = (s->sizeof_stat == sizeof(u64)) ?
*(u64 *)p : *(u32 *)p;
}
@@ -1605,7 +1600,6 @@ static const struct net_device_ops bcm_enet_ops = {
.ndo_open = bcm_enet_open,
.ndo_stop = bcm_enet_stop,
.ndo_start_xmit = bcm_enet_start_xmit,
- .ndo_get_stats = bcm_enet_get_stats,
.ndo_set_mac_address = bcm_enet_set_mac_address,
.ndo_set_multicast_list = bcm_enet_set_multicast_list,
.ndo_do_ioctl = bcm_enet_ioctl,
diff --git a/drivers/net/bcm63xx_enet.h b/drivers/net/bcm63xx_enet.h
index bd3684d42d74..0e3048b788c2 100644
--- a/drivers/net/bcm63xx_enet.h
+++ b/drivers/net/bcm63xx_enet.h
@@ -274,7 +274,6 @@ struct bcm_enet_priv {
int pause_tx;
/* stats */
- struct net_device_stats stats;
struct bcm_enet_mib_counters mib;
/* after mib interrupt, mib registers update is done in this
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 53306bf3f401..4594a28b1f66 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -78,6 +78,8 @@ static inline char *nic_name(struct pci_dev *pdev)
#define MCC_Q_LEN 128 /* total size not to exceed 8 pages */
#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 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)
@@ -157,10 +159,9 @@ struct be_mcc_obj {
bool rearm_cq;
};
-struct be_drvr_stats {
+struct be_tx_stats {
u32 be_tx_reqs; /* number of TX requests initiated */
u32 be_tx_stops; /* number of times TX Q was stopped */
- u32 be_fwd_reqs; /* number of send reqs through forwarding i/f */
u32 be_tx_wrbs; /* number of tx WRBs used */
u32 be_tx_events; /* number of tx completion events */
u32 be_tx_compl; /* number of tx completion entries processed */
@@ -169,35 +170,6 @@ struct be_drvr_stats {
u64 be_tx_bytes_prev;
u64 be_tx_pkts;
u32 be_tx_rate;
-
- u32 cache_barrier[16];
-
- u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */
- u32 be_rx_polls; /* number of times NAPI called poll function */
- u32 be_rx_events; /* number of ucast rx completion events */
- u32 be_rx_compl; /* number of rx completion entries processed */
- ulong be_rx_jiffies;
- u64 be_rx_bytes;
- u64 be_rx_bytes_prev;
- u64 be_rx_pkts;
- u32 be_rx_rate;
- u32 be_rx_mcast_pkt;
- /* number of non ether type II frames dropped where
- * frame len > length field of Mac Hdr */
- u32 be_802_3_dropped_frames;
- /* number of non ether type II frames malformed where
- * in frame len < length field of Mac Hdr */
- u32 be_802_3_malformed_frames;
- u32 be_rxcp_err; /* Num rx completion entries w/ err set. */
- ulong rx_fps_jiffies; /* jiffies at last FPS calc */
- u32 be_rx_frags;
- u32 be_prev_rx_frags;
- u32 be_rx_fps; /* Rx frags per second */
-};
-
-struct be_stats_obj {
- struct be_drvr_stats drvr_stats;
- struct be_dma_mem cmd;
};
struct be_tx_obj {
@@ -215,10 +187,34 @@ struct be_rx_page_info {
bool last_page_user;
};
+struct be_rx_stats {
+ u32 rx_post_fail;/* number of ethrx buffer alloc failures */
+ u32 rx_polls; /* number of times NAPI called poll function */
+ u32 rx_events; /* number of ucast rx completion events */
+ u32 rx_compl; /* number of rx completion entries processed */
+ ulong rx_jiffies;
+ u64 rx_bytes;
+ u64 rx_bytes_prev;
+ u64 rx_pkts;
+ u32 rx_rate;
+ u32 rx_mcast_pkts;
+ u32 rxcp_err; /* Num rx completion entries w/ err set. */
+ ulong rx_fps_jiffies; /* jiffies at last FPS calc */
+ u32 rx_frags;
+ u32 prev_rx_frags;
+ u32 rx_fps; /* Rx frags per second */
+};
+
struct be_rx_obj {
+ struct be_adapter *adapter;
struct be_queue_info q;
struct be_queue_info cq;
struct be_rx_page_info page_info_tbl[RX_Q_LEN];
+ struct be_eq_obj rx_eq;
+ struct be_rx_stats stats;
+ u8 rss_id;
+ bool rx_post_starved; /* Zero rx frags have been posted to BE */
+ u32 cache_line_barrier[16];
};
struct be_vf_cfg {
@@ -229,7 +225,6 @@ struct be_vf_cfg {
u32 vf_tx_rate;
};
-#define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */
#define BE_INVALID_PMAC_ID 0xffffffff
struct be_adapter {
struct pci_dev *pdev;
@@ -249,29 +244,31 @@ struct be_adapter {
spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
spinlock_t mcc_cq_lock;
- struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS];
+ struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
bool msix_enabled;
bool isr_registered;
/* TX Rings */
struct be_eq_obj tx_eq;
struct be_tx_obj tx_obj;
+ struct be_tx_stats tx_stats;
u32 cache_line_break[8];
/* Rx rings */
- struct be_eq_obj rx_eq;
- struct be_rx_obj rx_obj;
+ struct be_rx_obj rx_obj[MAX_RSS_QS + 1]; /* one default non-rss Q */
+ u32 num_rx_qs;
u32 big_page_size; /* Compounded page size shared by rx wrbs */
- bool rx_post_starved; /* Zero rx frags have been posted to BE */
struct vlan_group *vlan_grp;
u16 vlans_added;
u16 max_vlans; /* Number of vlans supported */
- u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
+ u8 vlan_tag[VLAN_N_VID];
+ u8 vlan_prio_bmap; /* Available Priority BitMap */
+ u16 recommended_prio; /* Recommended Priority */
struct be_dma_mem mc_cmd_mem;
- struct be_stats_obj stats;
+ struct be_dma_mem stats_cmd;
/* Work queue used to perform periodic tasks like getting statistics */
struct delayed_work work;
@@ -287,6 +284,7 @@ struct be_adapter {
bool promiscuous;
bool wol;
u32 function_mode;
+ u32 function_caps;
u32 rx_fc; /* Rx flow control */
u32 tx_fc; /* Tx flow control */
bool ue_detected;
@@ -313,10 +311,20 @@ struct be_adapter {
extern const struct ethtool_ops be_ethtool_ops;
-#define drvr_stats(adapter) (&adapter->stats.drvr_stats)
+#define tx_stats(adapter) (&adapter->tx_stats)
+#define rx_stats(rxo) (&rxo->stats)
#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
+#define for_all_rx_queues(adapter, rxo, i) \
+ for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \
+ i++, rxo++)
+
+/* Just skip the first default non-rss queue */
+#define for_all_rss_queues(adapter, rxo, i) \
+ for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\
+ i++, rxo++)
+
#define PAGE_SHIFT_4K 12
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
@@ -414,6 +422,20 @@ static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
adapter->is_virtfn = (data != 0xAA);
}
+static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
+{
+ u32 addr;
+
+ addr = jhash(adapter->netdev->dev_addr, ETH_ALEN, 0);
+
+ mac[5] = (u8)(addr & 0xFF);
+ mac[4] = (u8)((addr >> 8) & 0xFF);
+ mac[3] = (u8)((addr >> 16) & 0xFF);
+ mac[2] = 0xC9;
+ mac[1] = 0x00;
+ mac[0] = 0x00;
+}
+
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);
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 34abcc9403d6..1e7f305ed00b 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -71,7 +71,7 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
if (compl_status == MCC_STATUS_SUCCESS) {
if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
struct be_cmd_resp_get_stats *resp =
- adapter->stats.cmd.va;
+ adapter->stats_cmd.va;
be_dws_le_to_cpu(&resp->hw_stats,
sizeof(resp->hw_stats));
netdev_stats_update(adapter);
@@ -96,11 +96,62 @@ static void be_async_link_state_process(struct be_adapter *adapter,
evt->port_link_status == ASYNC_EVENT_LINK_UP);
}
+/* Grp5 CoS Priority evt */
+static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
+ struct be_async_event_grp5_cos_priority *evt)
+{
+ if (evt->valid) {
+ adapter->vlan_prio_bmap = evt->available_priority_bmap;
+ adapter->recommended_prio =
+ evt->reco_default_priority << VLAN_PRIO_SHIFT;
+ }
+}
+
+/* Grp5 QOS Speed evt */
+static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
+ struct be_async_event_grp5_qos_link_speed *evt)
+{
+ if (evt->physical_port == adapter->port_num) {
+ /* qos_link_speed is in units of 10 Mbps */
+ adapter->link_speed = evt->qos_link_speed * 10;
+ }
+}
+
+static void be_async_grp5_evt_process(struct be_adapter *adapter,
+ u32 trailer, struct be_mcc_compl *evt)
+{
+ u8 event_type = 0;
+
+ event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
+ ASYNC_TRAILER_EVENT_TYPE_MASK;
+
+ switch (event_type) {
+ case ASYNC_EVENT_COS_PRIORITY:
+ be_async_grp5_cos_priority_process(adapter,
+ (struct be_async_event_grp5_cos_priority *)evt);
+ break;
+ case ASYNC_EVENT_QOS_SPEED:
+ be_async_grp5_qos_speed_process(adapter,
+ (struct be_async_event_grp5_qos_link_speed *)evt);
+ break;
+ default:
+ dev_warn(&adapter->pdev->dev, "Unknown grp5 event!\n");
+ break;
+ }
+}
+
static inline bool is_link_state_evt(u32 trailer)
{
+ return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
+ ASYNC_TRAILER_EVENT_CODE_MASK) ==
+ ASYNC_EVENT_CODE_LINK_STATE;
+}
+
+static inline bool is_grp5_evt(u32 trailer)
+{
return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
ASYNC_TRAILER_EVENT_CODE_MASK) ==
- ASYNC_EVENT_CODE_LINK_STATE);
+ ASYNC_EVENT_CODE_GRP_5);
}
static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
@@ -143,6 +194,9 @@ int be_process_mcc(struct be_adapter *adapter, int *status)
if (is_link_state_evt(compl->flags))
be_async_link_state_process(adapter,
(struct be_async_event_link_state *) compl);
+ else if (is_grp5_evt(compl->flags))
+ be_async_grp5_evt_process(adapter,
+ compl->flags, compl);
} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
*status = be_mcc_compl_process(adapter, compl);
atomic_dec(&mcc_obj->q.used);
@@ -677,10 +731,10 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
ctxt = &req->context;
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
- OPCODE_COMMON_MCC_CREATE);
+ OPCODE_COMMON_MCC_CREATE_EXT);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
- OPCODE_COMMON_MCC_CREATE, sizeof(*req));
+ OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req));
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
@@ -688,7 +742,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
be_encoded_q_len(mccq->len));
AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
-
+ /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
+ req->async_event_bitmap[0] |= 0x00000022;
be_dws_cpu_to_le(ctxt, sizeof(req->context));
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
@@ -754,7 +809,7 @@ int be_cmd_txq_create(struct be_adapter *adapter,
/* Uses mbox */
int be_cmd_rxq_create(struct be_adapter *adapter,
struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
- u16 max_frame_size, u32 if_id, u32 rss)
+ u16 max_frame_size, u32 if_id, u32 rss, u8 *rss_id)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_eth_rx_create *req;
@@ -785,6 +840,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb);
rxq->id = le16_to_cpu(resp->id);
rxq->created = true;
+ *rss_id = resp->rss_id;
}
spin_unlock(&adapter->mbox_lock);
@@ -1259,7 +1315,8 @@ err:
}
/* Uses mbox */
-int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode)
+int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
+ u32 *mode, u32 *caps)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_query_fw_cfg *req;
@@ -1281,6 +1338,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode)
struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
*port_num = le32_to_cpu(resp->phys_port);
*mode = le32_to_cpu(resp->function_mode);
+ *caps = le32_to_cpu(resp->function_caps);
}
spin_unlock(&adapter->mbox_lock);
@@ -1311,6 +1369,37 @@ int be_cmd_reset_function(struct be_adapter *adapter)
return status;
}
+int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size)
+{
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_rss_config *req;
+ u32 myhash[10];
+ int status;
+
+ spin_lock(&adapter->mbox_lock);
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+ OPCODE_ETH_RSS_CONFIG);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
+ OPCODE_ETH_RSS_CONFIG, sizeof(*req));
+
+ req->if_id = cpu_to_le32(adapter->if_handle);
+ req->enable_rss = cpu_to_le16(RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4);
+ req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1);
+ memcpy(req->cpu_table, rsstable, table_size);
+ memcpy(req->hash, myhash, sizeof(myhash));
+ be_dws_cpu_to_le(req->hash, sizeof(req->hash));
+
+ status = be_mbox_notify_wait(adapter);
+
+ spin_unlock(&adapter->mbox_lock);
+ return status;
+}
+
/* Uses sync mcc */
int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num,
u8 bcn, u8 sts, u8 state)
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index ad1e6fac60c5..c7f6cdfe1c73 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -82,7 +82,12 @@ struct be_mcc_compl {
*/
#define ASYNC_TRAILER_EVENT_CODE_SHIFT 8 /* bits 8 - 15 */
#define ASYNC_TRAILER_EVENT_CODE_MASK 0xFF
+#define ASYNC_TRAILER_EVENT_TYPE_SHIFT 16
+#define ASYNC_TRAILER_EVENT_TYPE_MASK 0xFF
#define ASYNC_EVENT_CODE_LINK_STATE 0x1
+#define ASYNC_EVENT_CODE_GRP_5 0x5
+#define ASYNC_EVENT_QOS_SPEED 0x1
+#define ASYNC_EVENT_COS_PRIORITY 0x2
struct be_async_event_trailer {
u32 code;
};
@@ -105,6 +110,30 @@ struct be_async_event_link_state {
struct be_async_event_trailer trailer;
} __packed;
+/* When the event code of an async trailer is GRP-5 and event_type is QOS_SPEED
+ * the mcc_compl must be interpreted as follows
+ */
+struct be_async_event_grp5_qos_link_speed {
+ u8 physical_port;
+ u8 rsvd[5];
+ u16 qos_link_speed;
+ u32 event_tag;
+ struct be_async_event_trailer trailer;
+} __packed;
+
+/* When the event code of an async trailer is GRP5 and event type is
+ * CoS-Priority, the mcc_compl must be interpreted as follows
+ */
+struct be_async_event_grp5_cos_priority {
+ u8 physical_port;
+ u8 available_priority_bmap;
+ u8 reco_default_priority;
+ u8 valid;
+ u8 rsvd0;
+ u8 event_tag;
+ struct be_async_event_trailer trailer;
+} __packed;
+
struct be_mcc_mailbox {
struct be_mcc_wrb wrb;
struct be_mcc_compl compl;
@@ -123,8 +152,9 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_WRITE_FLASHROM 7
#define OPCODE_COMMON_CQ_CREATE 12
#define OPCODE_COMMON_EQ_CREATE 13
-#define OPCODE_COMMON_MCC_CREATE 21
+#define OPCODE_COMMON_MCC_CREATE 21
#define OPCODE_COMMON_SET_QOS 28
+#define OPCODE_COMMON_MCC_CREATE_EXT 90
#define OPCODE_COMMON_SEEPROM_READ 30
#define OPCODE_COMMON_NTWK_RX_FILTER 34
#define OPCODE_COMMON_GET_FW_VERSION 35
@@ -147,6 +177,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_READ_TRANSRECV_DATA 73
#define OPCODE_COMMON_GET_PHY_DETAILS 102
+#define OPCODE_ETH_RSS_CONFIG 1
#define OPCODE_ETH_ACPI_CONFIG 2
#define OPCODE_ETH_PROMISCUOUS 3
#define OPCODE_ETH_GET_STATISTICS 4
@@ -337,6 +368,7 @@ struct be_cmd_req_mcc_create {
struct be_cmd_req_hdr hdr;
u16 num_pages;
u16 rsvd0;
+ u32 async_event_bitmap[1];
u8 context[sizeof(struct amap_mcc_context) / 8];
struct phys_addr pages[8];
} __packed;
@@ -409,7 +441,7 @@ struct be_cmd_req_eth_rx_create {
struct be_cmd_resp_eth_rx_create {
struct be_cmd_resp_hdr hdr;
u16 id;
- u8 cpu_id;
+ u8 rss_id;
u8 rsvd0;
} __packed;
@@ -739,9 +771,10 @@ struct be_cmd_resp_modify_eq_delay {
} __packed;
/******************** Get FW Config *******************/
+#define BE_FUNCTION_CAPS_RSS 0x2
struct be_cmd_req_query_fw_cfg {
struct be_cmd_req_hdr hdr;
- u32 rsvd[30];
+ u32 rsvd[31];
};
struct be_cmd_resp_query_fw_cfg {
@@ -751,6 +784,26 @@ struct be_cmd_resp_query_fw_cfg {
u32 phys_port;
u32 function_mode;
u32 rsvd[26];
+ u32 function_caps;
+};
+
+/******************** RSS Config *******************/
+/* RSS types */
+#define RSS_ENABLE_NONE 0x0
+#define RSS_ENABLE_IPV4 0x1
+#define RSS_ENABLE_TCP_IPV4 0x2
+#define RSS_ENABLE_IPV6 0x4
+#define RSS_ENABLE_TCP_IPV6 0x8
+
+struct be_cmd_req_rss_config {
+ struct be_cmd_req_hdr hdr;
+ u32 if_id;
+ u16 enable_rss;
+ u16 cpu_table_size_log2;
+ u32 hash[10];
+ u8 cpu_table[128];
+ u8 flush;
+ u8 rsvd0[3];
};
/******************** Port Beacon ***************************/
@@ -937,7 +990,7 @@ extern int be_cmd_txq_create(struct be_adapter *adapter,
extern int be_cmd_rxq_create(struct be_adapter *adapter,
struct be_queue_info *rxq, u16 cq_id,
u16 frag_size, u16 max_frame_size, u32 if_id,
- u32 rss);
+ u32 rss, u8 *rss_id);
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,
@@ -960,8 +1013,10 @@ extern int be_cmd_set_flow_control(struct be_adapter *adapter,
extern int be_cmd_get_flow_control(struct be_adapter *adapter,
u32 *tx_fc, u32 *rx_fc);
extern int be_cmd_query_fw_cfg(struct be_adapter *adapter,
- u32 *port_num, u32 *cap);
+ u32 *port_num, u32 *function_mode, u32 *function_caps);
extern int be_cmd_reset_function(struct be_adapter *adapter);
+extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
+ u16 table_size);
extern int be_process_mcc(struct be_adapter *adapter, int *status);
extern int be_cmd_set_beacon_state(struct be_adapter *adapter,
u8 port_num, u8 beacon, u8 status, u8 state);
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 13f0abbc5205..0f46366ecc48 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -26,14 +26,16 @@ struct be_ethtool_stat {
int offset;
};
-enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT, ERXSTAT};
+enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT};
#define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
offsetof(_struct, field)
#define NETSTAT_INFO(field) #field, NETSTAT,\
FIELDINFO(struct net_device_stats,\
field)
-#define DRVSTAT_INFO(field) #field, DRVSTAT,\
- FIELDINFO(struct be_drvr_stats, field)
+#define DRVSTAT_TX_INFO(field) #field, DRVSTAT_TX,\
+ FIELDINFO(struct be_tx_stats, field)
+#define DRVSTAT_RX_INFO(field) #field, DRVSTAT_RX,\
+ FIELDINFO(struct be_rx_stats, field)
#define MISCSTAT_INFO(field) #field, MISCSTAT,\
FIELDINFO(struct be_rxf_stats, field)
#define PORTSTAT_INFO(field) #field, PORTSTAT,\
@@ -51,21 +53,12 @@ static const struct be_ethtool_stat et_stats[] = {
{NETSTAT_INFO(tx_errors)},
{NETSTAT_INFO(rx_dropped)},
{NETSTAT_INFO(tx_dropped)},
- {DRVSTAT_INFO(be_tx_reqs)},
- {DRVSTAT_INFO(be_tx_stops)},
- {DRVSTAT_INFO(be_fwd_reqs)},
- {DRVSTAT_INFO(be_tx_wrbs)},
- {DRVSTAT_INFO(be_rx_polls)},
- {DRVSTAT_INFO(be_tx_events)},
- {DRVSTAT_INFO(be_rx_events)},
- {DRVSTAT_INFO(be_tx_compl)},
- {DRVSTAT_INFO(be_rx_compl)},
- {DRVSTAT_INFO(be_rx_mcast_pkt)},
- {DRVSTAT_INFO(be_ethrx_post_fail)},
- {DRVSTAT_INFO(be_802_3_dropped_frames)},
- {DRVSTAT_INFO(be_802_3_malformed_frames)},
- {DRVSTAT_INFO(be_tx_rate)},
- {DRVSTAT_INFO(be_rx_rate)},
+ {DRVSTAT_TX_INFO(be_tx_rate)},
+ {DRVSTAT_TX_INFO(be_tx_reqs)},
+ {DRVSTAT_TX_INFO(be_tx_wrbs)},
+ {DRVSTAT_TX_INFO(be_tx_stops)},
+ {DRVSTAT_TX_INFO(be_tx_events)},
+ {DRVSTAT_TX_INFO(be_tx_compl)},
{PORTSTAT_INFO(rx_unicast_frames)},
{PORTSTAT_INFO(rx_multicast_frames)},
{PORTSTAT_INFO(rx_broadcast_frames)},
@@ -91,6 +84,9 @@ static const struct be_ethtool_stat et_stats[] = {
{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)},
@@ -103,11 +99,24 @@ static const struct be_ethtool_stat et_stats[] = {
{MISCSTAT_INFO(rx_drops_too_many_frags)},
{MISCSTAT_INFO(rx_drops_invalid_ring)},
{MISCSTAT_INFO(forwarded_packets)},
- {MISCSTAT_INFO(rx_drops_mtu)},
- {ERXSTAT_INFO(rx_drops_no_fragments)},
+ {MISCSTAT_INFO(rx_drops_mtu)}
};
#define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
+/* Stats related to multi RX queues */
+static const struct be_ethtool_stat et_rx_stats[] = {
+ {DRVSTAT_RX_INFO(rx_bytes)},
+ {DRVSTAT_RX_INFO(rx_pkts)},
+ {DRVSTAT_RX_INFO(rx_rate)},
+ {DRVSTAT_RX_INFO(rx_polls)},
+ {DRVSTAT_RX_INFO(rx_events)},
+ {DRVSTAT_RX_INFO(rx_compl)},
+ {DRVSTAT_RX_INFO(rx_mcast_pkts)},
+ {DRVSTAT_RX_INFO(rx_post_fail)},
+ {ERXSTAT_INFO(rx_drops_no_fragments)}
+};
+#define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats))
+
static const char et_self_tests[][ETH_GSTRING_LEN] = {
"MAC Loopback test",
"PHY Loopback test",
@@ -140,7 +149,7 @@ static int
be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
{
struct be_adapter *adapter = netdev_priv(netdev);
- struct be_eq_obj *rx_eq = &adapter->rx_eq;
+ struct be_eq_obj *rx_eq = &adapter->rx_obj[0].rx_eq;
struct be_eq_obj *tx_eq = &adapter->tx_eq;
coalesce->rx_coalesce_usecs = rx_eq->cur_eqd;
@@ -164,25 +173,49 @@ static int
be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
{
struct be_adapter *adapter = netdev_priv(netdev);
- struct be_eq_obj *rx_eq = &adapter->rx_eq;
+ 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;
+ int status = 0, i;
if (coalesce->use_adaptive_tx_coalesce == 1)
return -EINVAL;
- /* if AIC is being turned on now, start with an EQD of 0 */
- if (rx_eq->enable_aic == 0 &&
- coalesce->use_adaptive_rx_coalesce == 1) {
- rx_eq->cur_eqd = 0;
+ for_all_rx_queues(adapter, rxo, i) {
+ rx_eq = &rxo->rx_eq;
+
+ if (!rx_eq->enable_aic && coalesce->use_adaptive_rx_coalesce)
+ rx_eq->cur_eqd = 0;
+ rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce;
+
+ rx_max = coalesce->rx_coalesce_usecs_high;
+ rx_min = coalesce->rx_coalesce_usecs_low;
+ rx_cur = coalesce->rx_coalesce_usecs;
+
+ if (rx_eq->enable_aic) {
+ if (rx_max > BE_MAX_EQD)
+ rx_max = BE_MAX_EQD;
+ if (rx_min > rx_max)
+ rx_min = rx_max;
+ rx_eq->max_eqd = rx_max;
+ rx_eq->min_eqd = rx_min;
+ if (rx_eq->cur_eqd > rx_max)
+ rx_eq->cur_eqd = rx_max;
+ if (rx_eq->cur_eqd < rx_min)
+ rx_eq->cur_eqd = rx_min;
+ } else {
+ if (rx_cur > BE_MAX_EQD)
+ rx_cur = BE_MAX_EQD;
+ if (rx_eq->cur_eqd != rx_cur) {
+ status = be_cmd_modify_eqd(adapter, rx_eq->q.id,
+ rx_cur);
+ if (!status)
+ rx_eq->cur_eqd = rx_cur;
+ }
+ }
}
- rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce;
-
- rx_max = coalesce->rx_coalesce_usecs_high;
- rx_min = coalesce->rx_coalesce_usecs_low;
- rx_cur = coalesce->rx_coalesce_usecs;
tx_max = coalesce->tx_coalesce_usecs_high;
tx_min = coalesce->tx_coalesce_usecs_low;
@@ -196,27 +229,6 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
tx_eq->cur_eqd = tx_cur;
}
- if (rx_eq->enable_aic) {
- if (rx_max > BE_MAX_EQD)
- rx_max = BE_MAX_EQD;
- if (rx_min > rx_max)
- rx_min = rx_max;
- rx_eq->max_eqd = rx_max;
- rx_eq->min_eqd = rx_min;
- if (rx_eq->cur_eqd > rx_max)
- rx_eq->cur_eqd = rx_max;
- if (rx_eq->cur_eqd < rx_min)
- rx_eq->cur_eqd = rx_min;
- } else {
- if (rx_cur > BE_MAX_EQD)
- rx_cur = BE_MAX_EQD;
- if (rx_eq->cur_eqd != rx_cur) {
- status = be_cmd_modify_eqd(adapter, rx_eq->q.id,
- rx_cur);
- if (!status)
- rx_eq->cur_eqd = rx_cur;
- }
- }
return 0;
}
@@ -244,32 +256,25 @@ be_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, uint64_t *data)
{
struct be_adapter *adapter = netdev_priv(netdev);
- struct be_drvr_stats *drvr_stats = &adapter->stats.drvr_stats;
- 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 net_device_stats *net_stats = &netdev->stats;
+ 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;
+ int i, j;
for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
switch (et_stats[i].type) {
case NETSTAT:
- p = net_stats;
+ p = &netdev->stats;
break;
- case DRVSTAT:
- p = drvr_stats;
+ case DRVSTAT_TX:
+ p = &adapter->tx_stats;
break;
case PORTSTAT:
- p = port_stats;
+ p = &hw_stats->rxf.port[adapter->port_num];
break;
case MISCSTAT:
- p = rxf_stats;
- break;
- case ERXSTAT: /* Currently only one ERX stat is provided */
- p = (u32 *)erx_stats + adapter->rx_obj.q.id;
+ p = &hw_stats->rxf;
break;
}
@@ -277,19 +282,44 @@ be_get_ethtool_stats(struct net_device *netdev,
data[i] = (et_stats[i].size == sizeof(u64)) ?
*(u64 *)p: *(u32 *)p;
}
+
+ for_all_rx_queues(adapter, rxo, j) {
+ for (i = 0; i < ETHTOOL_RXSTATS_NUM; i++) {
+ switch (et_rx_stats[i].type) {
+ case DRVSTAT_RX:
+ p = (u8 *)&rxo->stats + et_rx_stats[i].offset;
+ break;
+ case ERXSTAT:
+ p = (u32 *)erx_stats + rxo->q.id;
+ break;
+ }
+ data[ETHTOOL_STATS_NUM + j * ETHTOOL_RXSTATS_NUM + i] =
+ (et_rx_stats[i].size == sizeof(u64)) ?
+ *(u64 *)p: *(u32 *)p;
+ }
+ }
}
static void
be_get_stat_strings(struct net_device *netdev, uint32_t stringset,
uint8_t *data)
{
- int i;
+ struct be_adapter *adapter = netdev_priv(netdev);
+ int i, j;
+
switch (stringset) {
case ETH_SS_STATS:
for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN);
data += ETH_GSTRING_LEN;
}
+ for (i = 0; i < adapter->num_rx_qs; i++) {
+ for (j = 0; j < ETHTOOL_RXSTATS_NUM; j++) {
+ sprintf(data, "rxq%d: %s", i,
+ et_rx_stats[j].desc);
+ data += ETH_GSTRING_LEN;
+ }
+ }
break;
case ETH_SS_TEST:
for (i = 0; i < ETHTOOL_TESTS_NUM; i++) {
@@ -302,11 +332,14 @@ be_get_stat_strings(struct net_device *netdev, uint32_t stringset,
static int be_get_sset_count(struct net_device *netdev, int stringset)
{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
switch (stringset) {
case ETH_SS_TEST:
return ETHTOOL_TESTS_NUM;
case ETH_SS_STATS:
- return ETHTOOL_STATS_NUM;
+ return ETHTOOL_STATS_NUM +
+ adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM;
default:
return -EINVAL;
}
@@ -421,10 +454,10 @@ be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
{
struct be_adapter *adapter = netdev_priv(netdev);
- ring->rx_max_pending = adapter->rx_obj.q.len;
+ ring->rx_max_pending = adapter->rx_obj[0].q.len;
ring->tx_max_pending = adapter->tx_obj.q.len;
- ring->rx_pending = atomic_read(&adapter->rx_obj.q.used);
+ ring->rx_pending = atomic_read(&adapter->rx_obj[0].q.used);
ring->tx_pending = atomic_read(&adapter->tx_obj.q.used);
}
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 6eda7a022256..45b1f6635282 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -32,6 +32,10 @@ module_param(num_vfs, uint, S_IRUGO);
MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize");
+static bool multi_rxq = true;
+module_param(multi_rxq, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(multi_rxq, "Multi Rx Queue support. Enabled by default");
+
static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
@@ -111,6 +115,11 @@ 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;
@@ -236,18 +245,27 @@ netdev_addr:
void netdev_stats_update(struct be_adapter *adapter)
{
- struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va);
+ 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 net_device_stats *dev_stats = &adapter->netdev->stats;
struct be_erx_stats *erx_stats = &hw_stats->erx;
+ struct be_rx_obj *rxo;
+ int i;
+
+ memset(dev_stats, 0, sizeof(*dev_stats));
+ for_all_rx_queues(adapter, rxo, i) {
+ dev_stats->rx_packets += rx_stats(rxo)->rx_pkts;
+ 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];
+ }
- dev_stats->rx_packets = drvr_stats(adapter)->be_rx_pkts;
- dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts;
- dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes;
- dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes;
- dev_stats->multicast = drvr_stats(adapter)->be_rx_mcast_pkt;
+ 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 +
@@ -264,18 +282,11 @@ void netdev_stats_update(struct be_adapter *adapter)
port_stats->rx_ip_checksum_errs +
port_stats->rx_udp_checksum_errs;
- /* no space in linux buffers: best possible approximation */
- dev_stats->rx_dropped =
- erx_stats->rx_drops_no_fragments[adapter->rx_obj.q.id];
-
/* 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;
- /* receive ring buffer overflow */
- dev_stats->rx_over_errors = 0;
-
dev_stats->rx_crc_errors = port_stats->rx_crc_errors;
/* frame alignment errors */
@@ -286,23 +297,6 @@ void netdev_stats_update(struct be_adapter *adapter)
dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow +
port_stats->rx_input_fifo_overflow +
rxf_stats->rx_drops_no_pbuf;
- /* receiver missed packetd */
- dev_stats->rx_missed_errors = 0;
-
- /* packet transmit problems */
- dev_stats->tx_errors = 0;
-
- /* no space available in linux */
- dev_stats->tx_dropped = 0;
-
- dev_stats->collisions = 0;
-
- /* detailed tx_errors */
- dev_stats->tx_aborted_errors = 0;
- dev_stats->tx_carrier_errors = 0;
- dev_stats->tx_fifo_errors = 0;
- dev_stats->tx_heartbeat_errors = 0;
- dev_stats->tx_window_errors = 0;
}
void be_link_status_update(struct be_adapter *adapter, bool link_up)
@@ -326,10 +320,10 @@ void be_link_status_update(struct be_adapter *adapter, bool link_up)
}
/* Update the EQ delay n BE based on the RX frags consumed / sec */
-static void be_rx_eqd_update(struct be_adapter *adapter)
+static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo)
{
- struct be_eq_obj *rx_eq = &adapter->rx_eq;
- struct be_drvr_stats *stats = &adapter->stats.drvr_stats;
+ struct be_eq_obj *rx_eq = &rxo->rx_eq;
+ struct be_rx_stats *stats = &rxo->stats;
ulong now = jiffies;
u32 eqd;
@@ -346,12 +340,12 @@ static void be_rx_eqd_update(struct be_adapter *adapter)
if ((now - stats->rx_fps_jiffies) < HZ)
return;
- stats->be_rx_fps = (stats->be_rx_frags - stats->be_prev_rx_frags) /
+ stats->rx_fps = (stats->rx_frags - stats->prev_rx_frags) /
((now - stats->rx_fps_jiffies) / HZ);
stats->rx_fps_jiffies = now;
- stats->be_prev_rx_frags = stats->be_rx_frags;
- eqd = stats->be_rx_fps / 110000;
+ stats->prev_rx_frags = stats->rx_frags;
+ eqd = stats->rx_fps / 110000;
eqd = eqd << 3;
if (eqd > rx_eq->max_eqd)
eqd = rx_eq->max_eqd;
@@ -365,11 +359,6 @@ static void be_rx_eqd_update(struct be_adapter *adapter)
rx_eq->cur_eqd = eqd;
}
-static struct net_device_stats *be_get_stats(struct net_device *dev)
-{
- return &dev->stats;
-}
-
static u32 be_calc_rate(u64 bytes, unsigned long ticks)
{
u64 rate = bytes;
@@ -383,7 +372,7 @@ static u32 be_calc_rate(u64 bytes, unsigned long ticks)
static void be_tx_rate_update(struct be_adapter *adapter)
{
- struct be_drvr_stats *stats = drvr_stats(adapter);
+ struct be_tx_stats *stats = tx_stats(adapter);
ulong now = jiffies;
/* Wrapped around? */
@@ -405,7 +394,7 @@ static void be_tx_rate_update(struct be_adapter *adapter)
static void be_tx_stats_update(struct be_adapter *adapter,
u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped)
{
- struct be_drvr_stats *stats = drvr_stats(adapter);
+ struct be_tx_stats *stats = tx_stats(adapter);
stats->be_tx_reqs++;
stats->be_tx_wrbs += wrb_cnt;
stats->be_tx_bytes += copied;
@@ -440,9 +429,12 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len)
wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK;
}
-static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
- bool vlan, u32 wrb_cnt, u32 len)
+static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
+ struct sk_buff *skb, u32 wrb_cnt, u32 len)
{
+ u8 vlan_prio = 0;
+ u16 vlan_tag = 0;
+
memset(hdr, 0, sizeof(*hdr));
AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
@@ -460,10 +452,15 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
}
- if (vlan && vlan_tx_tag_present(skb)) {
+ if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
- AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag,
- hdr, vlan_tx_tag_get(skb));
+ vlan_tag = vlan_tx_tag_get(skb);
+ vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
+ /* If vlan priority provided by OS is NOT in available bmap */
+ if (!(adapter->vlan_prio_bmap & (1 << vlan_prio)))
+ vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) |
+ adapter->recommended_prio;
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag);
}
AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1);
@@ -543,8 +540,7 @@ static int make_tx_wrbs(struct be_adapter *adapter,
queue_head_inc(txq);
}
- wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false,
- wrb_cnt, copied);
+ wrb_fill_hdr(adapter, hdr, first_skb, wrb_cnt, copied);
be_dws_cpu_to_le(hdr, sizeof(*hdr));
return copied;
@@ -637,7 +633,7 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
if (adapter->vlans_added <= adapter->max_vlans) {
/* Construct VLAN Table to give to HW */
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
if (adapter->vlan_tag[i]) {
vtag[ntags] = cpu_to_le16(i);
ntags++;
@@ -656,14 +652,8 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp)
{
struct be_adapter *adapter = netdev_priv(netdev);
- struct be_eq_obj *rx_eq = &adapter->rx_eq;
- struct be_eq_obj *tx_eq = &adapter->tx_eq;
- be_eq_notify(adapter, rx_eq->q.id, false, false, 0);
- be_eq_notify(adapter, tx_eq->q.id, false, false, 0);
adapter->vlan_grp = grp;
- be_eq_notify(adapter, rx_eq->q.id, true, false, 0);
- be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
}
static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
@@ -825,40 +815,38 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
return status;
}
-static void be_rx_rate_update(struct be_adapter *adapter)
+static void be_rx_rate_update(struct be_rx_obj *rxo)
{
- struct be_drvr_stats *stats = drvr_stats(adapter);
+ struct be_rx_stats *stats = &rxo->stats;
ulong now = jiffies;
/* Wrapped around */
- if (time_before(now, stats->be_rx_jiffies)) {
- stats->be_rx_jiffies = now;
+ if (time_before(now, stats->rx_jiffies)) {
+ stats->rx_jiffies = now;
return;
}
/* Update the rate once in two seconds */
- if ((now - stats->be_rx_jiffies) < 2 * HZ)
+ if ((now - stats->rx_jiffies) < 2 * HZ)
return;
- stats->be_rx_rate = be_calc_rate(stats->be_rx_bytes
- - stats->be_rx_bytes_prev,
- now - stats->be_rx_jiffies);
- stats->be_rx_jiffies = now;
- stats->be_rx_bytes_prev = stats->be_rx_bytes;
+ stats->rx_rate = be_calc_rate(stats->rx_bytes - stats->rx_bytes_prev,
+ now - stats->rx_jiffies);
+ stats->rx_jiffies = now;
+ stats->rx_bytes_prev = stats->rx_bytes;
}
-static void be_rx_stats_update(struct be_adapter *adapter,
+static void be_rx_stats_update(struct be_rx_obj *rxo,
u32 pktsize, u16 numfrags, u8 pkt_type)
{
- struct be_drvr_stats *stats = drvr_stats(adapter);
-
- stats->be_rx_compl++;
- stats->be_rx_frags += numfrags;
- stats->be_rx_bytes += pktsize;
- stats->be_rx_pkts++;
+ struct be_rx_stats *stats = &rxo->stats;
+ stats->rx_compl++;
+ stats->rx_frags += numfrags;
+ stats->rx_bytes += pktsize;
+ stats->rx_pkts++;
if (pkt_type == BE_MULTICAST_PACKET)
- stats->be_rx_mcast_pkt++;
+ stats->rx_mcast_pkts++;
}
static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
@@ -878,12 +866,14 @@ static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
}
static struct be_rx_page_info *
-get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
+get_rx_page_info(struct be_adapter *adapter,
+ struct be_rx_obj *rxo,
+ u16 frag_idx)
{
struct be_rx_page_info *rx_page_info;
- struct be_queue_info *rxq = &adapter->rx_obj.q;
+ struct be_queue_info *rxq = &rxo->q;
- rx_page_info = &adapter->rx_obj.page_info_tbl[frag_idx];
+ rx_page_info = &rxo->page_info_tbl[frag_idx];
BUG_ON(!rx_page_info->page);
if (rx_page_info->last_page_user) {
@@ -898,9 +888,10 @@ get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
/* Throwaway the data in the Rx completion */
static void be_rx_compl_discard(struct be_adapter *adapter,
- struct be_eth_rx_compl *rxcp)
+ struct be_rx_obj *rxo,
+ struct be_eth_rx_compl *rxcp)
{
- struct be_queue_info *rxq = &adapter->rx_obj.q;
+ struct be_queue_info *rxq = &rxo->q;
struct be_rx_page_info *page_info;
u16 rxq_idx, i, num_rcvd;
@@ -908,7 +899,7 @@ static void be_rx_compl_discard(struct be_adapter *adapter,
num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
for (i = 0; i < num_rcvd; i++) {
- page_info = get_rx_page_info(adapter, rxq_idx);
+ page_info = get_rx_page_info(adapter, rxo, rxq_idx);
put_page(page_info->page);
memset(page_info, 0, sizeof(*page_info));
index_inc(&rxq_idx, rxq->len);
@@ -919,11 +910,11 @@ static void be_rx_compl_discard(struct be_adapter *adapter,
* skb_fill_rx_data forms a complete skb for an ether frame
* indicated by rxcp.
*/
-static void skb_fill_rx_data(struct be_adapter *adapter,
+static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo,
struct sk_buff *skb, struct be_eth_rx_compl *rxcp,
u16 num_rcvd)
{
- struct be_queue_info *rxq = &adapter->rx_obj.q;
+ struct be_queue_info *rxq = &rxo->q;
struct be_rx_page_info *page_info;
u16 rxq_idx, i, j;
u32 pktsize, hdr_len, curr_frag_len, size;
@@ -934,7 +925,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp);
- page_info = get_rx_page_info(adapter, rxq_idx);
+ page_info = get_rx_page_info(adapter, rxo, rxq_idx);
start = page_address(page_info->page) + page_info->page_offset;
prefetch(start);
@@ -972,7 +963,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
for (i = 1, j = 0; i < num_rcvd; i++) {
size -= curr_frag_len;
index_inc(&rxq_idx, rxq->len);
- page_info = get_rx_page_info(adapter, rxq_idx);
+ page_info = get_rx_page_info(adapter, rxo, rxq_idx);
curr_frag_len = min(size, rx_frag_size);
@@ -998,11 +989,12 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
BUG_ON(j > MAX_SKB_FRAGS);
done:
- be_rx_stats_update(adapter, pktsize, num_rcvd, pkt_type);
+ be_rx_stats_update(rxo, pktsize, num_rcvd, pkt_type);
}
/* Process the RX completion indicated by rxcp when GRO is disabled */
static void be_rx_compl_process(struct be_adapter *adapter,
+ struct be_rx_obj *rxo,
struct be_eth_rx_compl *rxcp)
{
struct sk_buff *skb;
@@ -1019,14 +1011,14 @@ static void be_rx_compl_process(struct be_adapter *adapter,
if (unlikely(!skb)) {
if (net_ratelimit())
dev_warn(&adapter->pdev->dev, "skb alloc failed\n");
- be_rx_compl_discard(adapter, rxcp);
+ be_rx_compl_discard(adapter, rxo, rxcp);
return;
}
- skb_fill_rx_data(adapter, skb, rxcp, num_rcvd);
+ skb_fill_rx_data(adapter, rxo, skb, rxcp, num_rcvd);
if (do_pkt_csum(rxcp, adapter->rx_csum))
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
else
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1056,12 +1048,13 @@ static void be_rx_compl_process(struct be_adapter *adapter,
/* Process the RX completion indicated by rxcp when GRO is enabled */
static void be_rx_compl_process_gro(struct be_adapter *adapter,
- struct be_eth_rx_compl *rxcp)
+ struct be_rx_obj *rxo,
+ struct be_eth_rx_compl *rxcp)
{
struct be_rx_page_info *page_info;
struct sk_buff *skb = NULL;
- struct be_queue_info *rxq = &adapter->rx_obj.q;
- struct be_eq_obj *eq_obj = &adapter->rx_eq;
+ struct be_queue_info *rxq = &rxo->q;
+ struct be_eq_obj *eq_obj = &rxo->rx_eq;
u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
u16 i, rxq_idx = 0, vid, j;
u8 vtm;
@@ -1085,13 +1078,13 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
skb = napi_get_frags(&eq_obj->napi);
if (!skb) {
- be_rx_compl_discard(adapter, rxcp);
+ be_rx_compl_discard(adapter, rxo, rxcp);
return;
}
remaining = pkt_size;
for (i = 0, j = -1; i < num_rcvd; i++) {
- page_info = get_rx_page_info(adapter, rxq_idx);
+ page_info = get_rx_page_info(adapter, rxo, rxq_idx);
curr_frag_len = min(remaining, rx_frag_size);
@@ -1132,12 +1125,12 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid);
}
- be_rx_stats_update(adapter, pkt_size, num_rcvd, pkt_type);
+ be_rx_stats_update(rxo, pkt_size, num_rcvd, pkt_type);
}
-static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
+static struct be_eth_rx_compl *be_rx_compl_get(struct be_rx_obj *rxo)
{
- struct be_eth_rx_compl *rxcp = queue_tail_node(&adapter->rx_obj.cq);
+ struct be_eth_rx_compl *rxcp = queue_tail_node(&rxo->cq);
if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0)
return NULL;
@@ -1145,7 +1138,7 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
rmb();
be_dws_le_to_cpu(rxcp, sizeof(*rxcp));
- queue_tail_inc(&adapter->rx_obj.cq);
+ queue_tail_inc(&rxo->cq);
return rxcp;
}
@@ -1171,22 +1164,23 @@ static inline struct page *be_alloc_pages(u32 size)
* Allocate a page, split it to fragments of size rx_frag_size and post as
* receive buffers to BE
*/
-static void be_post_rx_frags(struct be_adapter *adapter)
+static void be_post_rx_frags(struct be_rx_obj *rxo)
{
- struct be_rx_page_info *page_info_tbl = adapter->rx_obj.page_info_tbl;
+ struct be_adapter *adapter = rxo->adapter;
+ struct be_rx_page_info *page_info_tbl = rxo->page_info_tbl;
struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL;
- struct be_queue_info *rxq = &adapter->rx_obj.q;
+ struct be_queue_info *rxq = &rxo->q;
struct page *pagep = NULL;
struct be_eth_rx_d *rxd;
u64 page_dmaaddr = 0, frag_dmaaddr;
u32 posted, page_offset = 0;
- page_info = &page_info_tbl[rxq->head];
+ page_info = &rxo->page_info_tbl[rxq->head];
for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) {
if (!pagep) {
pagep = be_alloc_pages(adapter->big_page_size);
if (unlikely(!pagep)) {
- drvr_stats(adapter)->be_ethrx_post_fail++;
+ rxo->stats.rx_post_fail++;
break;
}
page_dmaaddr = pci_map_page(adapter->pdev, pagep, 0,
@@ -1225,7 +1219,7 @@ static void be_post_rx_frags(struct be_adapter *adapter)
be_rxq_notify(adapter, rxq->id, posted);
} else if (atomic_read(&rxq->used) == 0) {
/* Let be_worker replenish when memory is available */
- adapter->rx_post_starved = true;
+ rxo->rx_post_starved = true;
}
}
@@ -1328,17 +1322,17 @@ static void be_eq_clean(struct be_adapter *adapter,
be_eq_notify(adapter, eq_obj->q.id, false, true, num);
}
-static void be_rx_q_clean(struct be_adapter *adapter)
+static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo)
{
struct be_rx_page_info *page_info;
- struct be_queue_info *rxq = &adapter->rx_obj.q;
- struct be_queue_info *rx_cq = &adapter->rx_obj.cq;
+ struct be_queue_info *rxq = &rxo->q;
+ struct be_queue_info *rx_cq = &rxo->cq;
struct be_eth_rx_compl *rxcp;
u16 tail;
/* First cleanup pending rx completions */
- while ((rxcp = be_rx_compl_get(adapter)) != NULL) {
- be_rx_compl_discard(adapter, rxcp);
+ while ((rxcp = be_rx_compl_get(rxo)) != NULL) {
+ be_rx_compl_discard(adapter, rxo, rxcp);
be_rx_compl_reset(rxcp);
be_cq_notify(adapter, rx_cq->id, true, 1);
}
@@ -1346,7 +1340,7 @@ static void be_rx_q_clean(struct be_adapter *adapter)
/* Then free posted rx buffer that were not used */
tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len;
for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) {
- page_info = get_rx_page_info(adapter, tail);
+ page_info = get_rx_page_info(adapter, rxo, tail);
put_page(page_info->page);
memset(page_info, 0, sizeof(*page_info));
}
@@ -1524,92 +1518,101 @@ tx_eq_free:
static void be_rx_queues_destroy(struct be_adapter *adapter)
{
struct be_queue_info *q;
-
- q = &adapter->rx_obj.q;
- if (q->created) {
- be_cmd_q_destroy(adapter, q, QTYPE_RXQ);
-
- /* After the rxq is invalidated, wait for a grace time
- * of 1ms for all dma to end and the flush compl to arrive
- */
- mdelay(1);
- be_rx_q_clean(adapter);
+ struct be_rx_obj *rxo;
+ int i;
+
+ for_all_rx_queues(adapter, rxo, i) {
+ q = &rxo->q;
+ if (q->created) {
+ be_cmd_q_destroy(adapter, q, QTYPE_RXQ);
+ /* After the rxq is invalidated, wait for a grace time
+ * of 1ms for all dma to end and the flush compl to
+ * arrive
+ */
+ mdelay(1);
+ be_rx_q_clean(adapter, rxo);
+ }
+ be_queue_free(adapter, q);
+
+ q = &rxo->cq;
+ if (q->created)
+ be_cmd_q_destroy(adapter, q, QTYPE_CQ);
+ be_queue_free(adapter, q);
+
+ /* Clear any residual events */
+ q = &rxo->rx_eq.q;
+ if (q->created) {
+ be_eq_clean(adapter, &rxo->rx_eq);
+ be_cmd_q_destroy(adapter, q, QTYPE_EQ);
+ }
+ be_queue_free(adapter, q);
}
- be_queue_free(adapter, q);
-
- q = &adapter->rx_obj.cq;
- if (q->created)
- be_cmd_q_destroy(adapter, q, QTYPE_CQ);
- be_queue_free(adapter, q);
-
- /* Clear any residual events */
- be_eq_clean(adapter, &adapter->rx_eq);
-
- q = &adapter->rx_eq.q;
- if (q->created)
- be_cmd_q_destroy(adapter, q, QTYPE_EQ);
- be_queue_free(adapter, q);
}
static int be_rx_queues_create(struct be_adapter *adapter)
{
struct be_queue_info *eq, *q, *cq;
- int rc;
+ struct be_rx_obj *rxo;
+ int rc, i;
adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
- adapter->rx_eq.max_eqd = BE_MAX_EQD;
- adapter->rx_eq.min_eqd = 0;
- adapter->rx_eq.cur_eqd = 0;
- adapter->rx_eq.enable_aic = true;
-
- /* Alloc Rx Event queue */
- eq = &adapter->rx_eq.q;
- rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN,
- sizeof(struct be_eq_entry));
- if (rc)
- return rc;
-
- /* Ask BE to create Rx Event queue */
- rc = be_cmd_eq_create(adapter, eq, adapter->rx_eq.cur_eqd);
- if (rc)
- goto rx_eq_free;
-
- /* Alloc RX eth compl queue */
- cq = &adapter->rx_obj.cq;
- rc = be_queue_alloc(adapter, cq, RX_CQ_LEN,
- sizeof(struct be_eth_rx_compl));
- if (rc)
- goto rx_eq_destroy;
-
- /* Ask BE to create Rx eth compl queue */
- rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3);
- if (rc)
- goto rx_cq_free;
-
- /* Alloc RX eth queue */
- q = &adapter->rx_obj.q;
- rc = be_queue_alloc(adapter, q, RX_Q_LEN, sizeof(struct be_eth_rx_d));
- if (rc)
- goto rx_cq_destroy;
-
- /* Ask BE to create Rx eth queue */
- rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size,
- BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, false);
- if (rc)
- goto rx_q_free;
+ for_all_rx_queues(adapter, rxo, i) {
+ rxo->adapter = adapter;
+ rxo->rx_eq.max_eqd = BE_MAX_EQD;
+ rxo->rx_eq.enable_aic = true;
+
+ /* EQ */
+ eq = &rxo->rx_eq.q;
+ rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN,
+ sizeof(struct be_eq_entry));
+ if (rc)
+ goto err;
+
+ rc = be_cmd_eq_create(adapter, eq, rxo->rx_eq.cur_eqd);
+ if (rc)
+ goto err;
+
+ /* CQ */
+ cq = &rxo->cq;
+ rc = be_queue_alloc(adapter, cq, RX_CQ_LEN,
+ sizeof(struct be_eth_rx_compl));
+ if (rc)
+ goto err;
+
+ rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3);
+ if (rc)
+ goto err;
+
+ /* Rx Q */
+ q = &rxo->q;
+ rc = be_queue_alloc(adapter, q, RX_Q_LEN,
+ sizeof(struct be_eth_rx_d));
+ if (rc)
+ goto err;
+
+ rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size,
+ BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle,
+ (i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id);
+ if (rc)
+ goto err;
+ }
+
+ if (be_multi_rxq(adapter)) {
+ u8 rsstable[MAX_RSS_QS];
+
+ for_all_rss_queues(adapter, rxo, i)
+ rsstable[i] = rxo->rss_id;
+
+ rc = be_cmd_rss_config(adapter, rsstable,
+ adapter->num_rx_qs - 1);
+ if (rc)
+ goto err;
+ }
return 0;
-rx_q_free:
- be_queue_free(adapter, q);
-rx_cq_destroy:
- be_cmd_q_destroy(adapter, cq, QTYPE_CQ);
-rx_cq_free:
- be_queue_free(adapter, cq);
-rx_eq_destroy:
- be_cmd_q_destroy(adapter, eq, QTYPE_EQ);
-rx_eq_free:
- be_queue_free(adapter, eq);
- return rc;
+err:
+ be_rx_queues_destroy(adapter);
+ return -1;
}
/* There are 8 evt ids per func. Retruns the evt id's bit number */
@@ -1621,24 +1624,31 @@ static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
static irqreturn_t be_intx(int irq, void *dev)
{
struct be_adapter *adapter = dev;
- int isr;
+ struct be_rx_obj *rxo;
+ int isr, i;
isr = ioread32(adapter->csr + CEV_ISR0_OFFSET +
(adapter->tx_eq.q.id/ 8) * CEV_ISR_SIZE);
if (!isr)
return IRQ_NONE;
- event_handle(adapter, &adapter->tx_eq);
- event_handle(adapter, &adapter->rx_eq);
+ if ((1 << be_evt_bit_get(adapter, adapter->tx_eq.q.id) & isr))
+ event_handle(adapter, &adapter->tx_eq);
+
+ for_all_rx_queues(adapter, rxo, i) {
+ if ((1 << be_evt_bit_get(adapter, rxo->rx_eq.q.id) & isr))
+ event_handle(adapter, &rxo->rx_eq);
+ }
return IRQ_HANDLED;
}
static irqreturn_t be_msix_rx(int irq, void *dev)
{
- struct be_adapter *adapter = dev;
+ struct be_rx_obj *rxo = dev;
+ struct be_adapter *adapter = rxo->adapter;
- event_handle(adapter, &adapter->rx_eq);
+ event_handle(adapter, &rxo->rx_eq);
return IRQ_HANDLED;
}
@@ -1652,14 +1662,14 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev)
return IRQ_HANDLED;
}
-static inline bool do_gro(struct be_adapter *adapter,
+static inline bool do_gro(struct be_adapter *adapter, struct be_rx_obj *rxo,
struct be_eth_rx_compl *rxcp)
{
int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp);
int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
if (err)
- drvr_stats(adapter)->be_rxcp_err++;
+ rxo->stats.rxcp_err++;
return (tcp_frame && !err) ? true : false;
}
@@ -1667,29 +1677,29 @@ static inline bool do_gro(struct be_adapter *adapter,
int be_poll_rx(struct napi_struct *napi, int budget)
{
struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi);
- struct be_adapter *adapter =
- container_of(rx_eq, struct be_adapter, rx_eq);
- struct be_queue_info *rx_cq = &adapter->rx_obj.cq;
+ struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq);
+ struct be_adapter *adapter = rxo->adapter;
+ struct be_queue_info *rx_cq = &rxo->cq;
struct be_eth_rx_compl *rxcp;
u32 work_done;
- adapter->stats.drvr_stats.be_rx_polls++;
+ rxo->stats.rx_polls++;
for (work_done = 0; work_done < budget; work_done++) {
- rxcp = be_rx_compl_get(adapter);
+ rxcp = be_rx_compl_get(rxo);
if (!rxcp)
break;
- if (do_gro(adapter, rxcp))
- be_rx_compl_process_gro(adapter, rxcp);
+ if (do_gro(adapter, rxo, rxcp))
+ be_rx_compl_process_gro(adapter, rxo, rxcp);
else
- be_rx_compl_process(adapter, rxcp);
+ be_rx_compl_process(adapter, rxo, rxcp);
be_rx_compl_reset(rxcp);
}
/* Refill the queue */
- if (atomic_read(&adapter->rx_obj.q.used) < RX_FRAGS_REFILL_WM)
- be_post_rx_frags(adapter);
+ if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM)
+ be_post_rx_frags(rxo);
/* All consumed */
if (work_done < budget) {
@@ -1743,8 +1753,8 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
netif_wake_queue(adapter->netdev);
}
- drvr_stats(adapter)->be_tx_events++;
- drvr_stats(adapter)->be_tx_compl += tx_compl;
+ tx_stats(adapter)->be_tx_events++;
+ tx_stats(adapter)->be_tx_compl += tx_compl;
}
return 1;
@@ -1793,20 +1803,24 @@ static void be_worker(struct work_struct *work)
{
struct be_adapter *adapter =
container_of(work, struct be_adapter, work.work);
+ struct be_rx_obj *rxo;
+ int i;
if (!adapter->stats_ioctl_sent)
- be_cmd_get_stats(adapter, &adapter->stats.cmd);
-
- /* Set EQ delay */
- be_rx_eqd_update(adapter);
+ be_cmd_get_stats(adapter, &adapter->stats_cmd);
be_tx_rate_update(adapter);
- be_rx_rate_update(adapter);
- if (adapter->rx_post_starved) {
- adapter->rx_post_starved = false;
- be_post_rx_frags(adapter);
+ for_all_rx_queues(adapter, rxo, i) {
+ be_rx_rate_update(rxo);
+ be_rx_eqd_update(adapter, rxo);
+
+ if (rxo->rx_post_starved) {
+ rxo->rx_post_starved = false;
+ be_post_rx_frags(rxo);
+ }
}
+
if (!adapter->ue_detected)
be_detect_dump_ue(adapter);
@@ -1821,17 +1835,45 @@ static void be_msix_disable(struct be_adapter *adapter)
}
}
+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;
+ }
+}
+
static void be_msix_enable(struct be_adapter *adapter)
{
+#define BE_MIN_MSIX_VECTORS (1 + 1) /* Rx + Tx */
int i, status;
- for (i = 0; i < BE_NUM_MSIX_VECTORS; i++)
+ adapter->num_rx_qs = be_num_rxqs_get(adapter);
+
+ for (i = 0; i < (adapter->num_rx_qs + 1); i++)
adapter->msix_entries[i].entry = i;
status = pci_enable_msix(adapter->pdev, adapter->msix_entries,
- BE_NUM_MSIX_VECTORS);
- if (status == 0)
- adapter->msix_enabled = true;
+ adapter->num_rx_qs + 1);
+ if (status == 0) {
+ goto done;
+ } else if (status >= BE_MIN_MSIX_VECTORS) {
+ 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);
+ goto done;
+ }
+ }
+ return;
+done:
+ adapter->msix_enabled = true;
}
static void be_sriov_enable(struct be_adapter *adapter)
@@ -1865,38 +1907,50 @@ static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id)
static int be_request_irq(struct be_adapter *adapter,
struct be_eq_obj *eq_obj,
- void *handler, char *desc)
+ void *handler, char *desc, void *context)
{
struct net_device *netdev = adapter->netdev;
int vec;
sprintf(eq_obj->desc, "%s-%s", netdev->name, desc);
vec = be_msix_vec_get(adapter, eq_obj->q.id);
- return request_irq(vec, handler, 0, eq_obj->desc, adapter);
+ return request_irq(vec, handler, 0, eq_obj->desc, context);
}
-static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj)
+static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj,
+ void *context)
{
int vec = be_msix_vec_get(adapter, eq_obj->q.id);
- free_irq(vec, adapter);
+ free_irq(vec, context);
}
static int be_msix_register(struct be_adapter *adapter)
{
- int status;
+ struct be_rx_obj *rxo;
+ int status, i;
+ char qname[10];
- status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx");
+ status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx",
+ adapter);
if (status)
goto err;
- status = be_request_irq(adapter, &adapter->rx_eq, be_msix_rx, "rx");
- if (status)
- goto free_tx_irq;
+ for_all_rx_queues(adapter, rxo, i) {
+ sprintf(qname, "rxq%d", i);
+ status = be_request_irq(adapter, &rxo->rx_eq, be_msix_rx,
+ qname, rxo);
+ if (status)
+ goto err_msix;
+ }
return 0;
-free_tx_irq:
- be_free_irq(adapter, &adapter->tx_eq);
+err_msix:
+ be_free_irq(adapter, &adapter->tx_eq, adapter);
+
+ for (i--, rxo = &adapter->rx_obj[i]; i >= 0; i--, rxo--)
+ be_free_irq(adapter, &rxo->rx_eq, rxo);
+
err:
dev_warn(&adapter->pdev->dev,
"MSIX Request IRQ failed - err %d\n", status);
@@ -1936,6 +1990,8 @@ done:
static void be_irq_unregister(struct be_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
+ struct be_rx_obj *rxo;
+ int i;
if (!adapter->isr_registered)
return;
@@ -1947,8 +2003,11 @@ static void be_irq_unregister(struct be_adapter *adapter)
}
/* MSIx */
- be_free_irq(adapter, &adapter->tx_eq);
- be_free_irq(adapter, &adapter->rx_eq);
+ be_free_irq(adapter, &adapter->tx_eq, adapter);
+
+ for_all_rx_queues(adapter, rxo, i)
+ be_free_irq(adapter, &rxo->rx_eq, rxo);
+
done:
adapter->isr_registered = false;
}
@@ -1956,9 +2015,9 @@ done:
static int be_close(struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(netdev);
- struct be_eq_obj *rx_eq = &adapter->rx_eq;
+ struct be_rx_obj *rxo;
struct be_eq_obj *tx_eq = &adapter->tx_eq;
- int vec;
+ int vec, i;
cancel_delayed_work_sync(&adapter->work);
@@ -1973,14 +2032,19 @@ static int be_close(struct net_device *netdev)
if (adapter->msix_enabled) {
vec = be_msix_vec_get(adapter, tx_eq->q.id);
synchronize_irq(vec);
- vec = be_msix_vec_get(adapter, rx_eq->q.id);
- synchronize_irq(vec);
+
+ for_all_rx_queues(adapter, rxo, i) {
+ vec = be_msix_vec_get(adapter, rxo->rx_eq.q.id);
+ synchronize_irq(vec);
+ }
} else {
synchronize_irq(netdev->irq);
}
be_irq_unregister(adapter);
- napi_disable(&rx_eq->napi);
+ for_all_rx_queues(adapter, rxo, i)
+ napi_disable(&rxo->rx_eq.napi);
+
napi_disable(&tx_eq->napi);
/* Wait for all pending tx completions to arrive so that
@@ -1994,17 +2058,17 @@ static int be_close(struct net_device *netdev)
static int be_open(struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(netdev);
- struct be_eq_obj *rx_eq = &adapter->rx_eq;
struct be_eq_obj *tx_eq = &adapter->tx_eq;
+ struct be_rx_obj *rxo;
bool link_up;
- int status;
+ int status, i;
u8 mac_speed;
u16 link_speed;
- /* First time posting */
- be_post_rx_frags(adapter);
-
- napi_enable(&rx_eq->napi);
+ for_all_rx_queues(adapter, rxo, i) {
+ be_post_rx_frags(rxo);
+ napi_enable(&rxo->rx_eq.napi);
+ }
napi_enable(&tx_eq->napi);
be_irq_register(adapter);
@@ -2012,12 +2076,12 @@ static int be_open(struct net_device *netdev)
be_intr_set(adapter, true);
/* The evt queues are created in unarmed state; arm them */
- be_eq_notify(adapter, rx_eq->q.id, true, false, 0);
+ for_all_rx_queues(adapter, rxo, i) {
+ be_eq_notify(adapter, rxo->rx_eq.q.id, true, false, 0);
+ be_cq_notify(adapter, rxo->cq.id, true, 0);
+ }
be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
- /* Rx compl queue may be in unarmed state; rearm it */
- be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0);
-
/* Now that interrupts are on we can process async mcc */
be_async_mcc_enable(adapter);
@@ -2084,6 +2148,47 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable)
return status;
}
+/*
+ * Generate a seed MAC address from the PF MAC Address using jhash.
+ * MAC Address for VFs are assigned incrementally starting from the seed.
+ * These addresses are programmed in the ASIC by the PF and the VF driver
+ * queries for the MAC address during its probe.
+ */
+static inline int be_vf_eth_addr_config(struct be_adapter *adapter)
+{
+ u32 vf = 0;
+ int status = 0;
+ u8 mac[ETH_ALEN];
+
+ be_vf_eth_addr_generate(adapter, mac);
+
+ for (vf = 0; vf < num_vfs; vf++) {
+ status = be_cmd_pmac_add(adapter, mac,
+ adapter->vf_cfg[vf].vf_if_handle,
+ &adapter->vf_cfg[vf].vf_pmac_id);
+ if (status)
+ dev_err(&adapter->pdev->dev,
+ "Mac address add failed for VF %d\n", vf);
+ else
+ memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN);
+
+ mac[5] += 1;
+ }
+ return status;
+}
+
+static inline void be_vf_eth_addr_rem(struct be_adapter *adapter)
+{
+ u32 vf;
+
+ for (vf = 0; vf < num_vfs; vf++) {
+ if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID)
+ be_cmd_pmac_del(adapter,
+ adapter->vf_cfg[vf].vf_if_handle,
+ adapter->vf_cfg[vf].vf_pmac_id);
+ }
+}
+
static int be_setup(struct be_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
@@ -2098,6 +2203,11 @@ static int be_setup(struct be_adapter *adapter)
BE_IF_FLAGS_PROMISCUOUS |
BE_IF_FLAGS_PASS_L3L4_ERRORS;
en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS;
+
+ if (be_multi_rxq(adapter)) {
+ cap_flags |= BE_IF_FLAGS_RSS;
+ en_flags |= BE_IF_FLAGS_RSS;
+ }
}
status = be_cmd_if_create(adapter, cap_flags, en_flags,
@@ -2143,10 +2253,20 @@ static int be_setup(struct be_adapter *adapter)
if (status != 0)
goto rx_qs_destroy;
+ if (be_physfn(adapter)) {
+ status = be_vf_eth_addr_config(adapter);
+ if (status)
+ goto mcc_q_destroy;
+ }
+
adapter->link_speed = -1;
return 0;
+mcc_q_destroy:
+ if (be_physfn(adapter))
+ be_vf_eth_addr_rem(adapter);
+ be_mcc_queues_destroy(adapter);
rx_qs_destroy:
be_rx_queues_destroy(adapter);
tx_qs_destroy:
@@ -2163,6 +2283,9 @@ do_none:
static int be_clear(struct be_adapter *adapter)
{
+ if (be_physfn(adapter))
+ be_vf_eth_addr_rem(adapter);
+
be_mcc_queues_destroy(adapter);
be_rx_queues_destroy(adapter);
be_tx_queues_destroy(adapter);
@@ -2390,7 +2513,6 @@ static struct net_device_ops be_netdev_ops = {
.ndo_open = be_open,
.ndo_stop = be_close,
.ndo_start_xmit = be_xmit,
- .ndo_get_stats = be_get_stats,
.ndo_set_rx_mode = be_set_multicast_list,
.ndo_set_mac_address = be_mac_addr_set,
.ndo_change_mtu = be_change_mtu,
@@ -2407,6 +2529,8 @@ static struct net_device_ops be_netdev_ops = {
static void be_netdev_init(struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(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_HW_CSUM |
@@ -2428,8 +2552,10 @@ static void be_netdev_init(struct net_device *netdev)
SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
- netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx,
- BE_NAPI_WEIGHT);
+ for_all_rx_queues(adapter, rxo, i)
+ netif_napi_add(netdev, &rxo->rx_eq.napi, be_poll_rx,
+ BE_NAPI_WEIGHT);
+
netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc,
BE_NAPI_WEIGHT);
@@ -2563,8 +2689,7 @@ done:
static void be_stats_cleanup(struct be_adapter *adapter)
{
- struct be_stats_obj *stats = &adapter->stats;
- struct be_dma_mem *cmd = &stats->cmd;
+ struct be_dma_mem *cmd = &adapter->stats_cmd;
if (cmd->va)
pci_free_consistent(adapter->pdev, cmd->size,
@@ -2573,8 +2698,7 @@ static void be_stats_cleanup(struct be_adapter *adapter)
static int be_stats_init(struct be_adapter *adapter)
{
- struct be_stats_obj *stats = &adapter->stats;
- struct be_dma_mem *cmd = &stats->cmd;
+ struct be_dma_mem *cmd = &adapter->stats_cmd;
cmd->size = sizeof(struct be_cmd_req_get_stats);
cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma);
@@ -2619,8 +2743,8 @@ static int be_get_config(struct be_adapter *adapter)
if (status)
return status;
- status = be_cmd_query_fw_cfg(adapter,
- &adapter->port_num, &adapter->function_mode);
+ status = be_cmd_query_fw_cfg(adapter, &adapter->port_num,
+ &adapter->function_mode, &adapter->function_caps);
if (status)
return status;
@@ -2655,7 +2779,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
struct be_adapter *adapter;
struct net_device *netdev;
-
status = pci_enable_device(pdev);
if (status)
goto do_none;
@@ -2688,11 +2811,8 @@ static int __devinit be_probe(struct pci_dev *pdev,
adapter->pdev = pdev;
pci_set_drvdata(pdev, adapter);
adapter->netdev = netdev;
- be_netdev_init(netdev);
SET_NETDEV_DEV(netdev, &pdev->dev);
- be_msix_enable(adapter);
-
status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (!status) {
netdev->features |= NETIF_F_HIGHDMA;
@@ -2736,12 +2856,15 @@ static int __devinit be_probe(struct pci_dev *pdev,
if (status)
goto stats_clean;
+ be_msix_enable(adapter);
+
INIT_DELAYED_WORK(&adapter->work, be_worker);
status = be_setup(adapter);
if (status)
- goto stats_clean;
+ goto msix_disable;
+ be_netdev_init(netdev);
status = register_netdev(netdev);
if (status != 0)
goto unsetup;
@@ -2751,12 +2874,13 @@ static int __devinit be_probe(struct pci_dev *pdev,
unsetup:
be_clear(adapter);
+msix_disable:
+ be_msix_disable(adapter);
stats_clean:
be_stats_cleanup(adapter);
ctrl_clean:
be_ctrl_cleanup(adapter);
free_netdev:
- be_msix_disable(adapter);
be_sriov_disable(adapter);
free_netdev(adapter->netdev);
pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 03d063554b7f..f7233191162b 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -804,15 +804,14 @@ static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompa
static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
{
struct bfin_mac_local *lp = netdev_priv(netdev);
- union skb_shared_tx *shtx = skb_tx(skb);
- if (shtx->hardware) {
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
int timeout_cnt = MAX_TIMEOUT_CNT;
/* When doing time stamping, keep the connection to the socket
* a while longer
*/
- shtx->in_progress = 1;
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
/*
* The timestamping is done at the EMAC module's MII/RMII interface
@@ -992,7 +991,6 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
struct bfin_mac_local *lp = netdev_priv(dev);
u16 *data;
u32 data_align = (unsigned long)(skb->data) & 0x3;
- union skb_shared_tx *shtx = skb_tx(skb);
current_tx_ptr->skb = skb;
@@ -1006,7 +1004,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
* of this field are the length of the packet payload in bytes and the higher
* 4 bits are the timestamping enable field.
*/
- if (shtx->hardware)
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
*data |= 0x1000;
current_tx_ptr->desc_a.start_addr = (u32)data;
@@ -1016,7 +1014,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
} else {
*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
/* enable timestamping for the sent packet */
- if (shtx->hardware)
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
*((u16 *)(current_tx_ptr->packet)) |= 0x1000;
memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
skb->len);
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 959add2410bf..a1b8c8b8010b 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1233,15 +1233,8 @@ static void bmac_reset_and_enable(struct net_device *dev)
}
spin_unlock_irqrestore(&bp->lock, flags);
}
-static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- struct bmac_data *bp = netdev_priv(dev);
- strcpy(info->driver, "bmac");
- strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev));
-}
static const struct ethtool_ops bmac_ethtool_ops = {
- .get_drvinfo = bmac_get_drvinfo,
.get_link = ethtool_op_get_link,
};
@@ -1588,7 +1581,7 @@ bmac_proc_info(char *buffer, char **start, off_t offset, int length)
int i;
if (bmac_devs == NULL)
- return (-ENOSYS);
+ return -ENOSYS;
len += sprintf(buffer, "BMAC counters & registers\n");
diff --git a/drivers/net/bna/Makefile b/drivers/net/bna/Makefile
new file mode 100644
index 000000000000..a5d604de7fea
--- /dev/null
+++ b/drivers/net/bna/Makefile
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+# All rights reserved.
+#
+
+obj-$(CONFIG_BNA) += bna.o
+
+bna-objs := bnad.o bnad_ethtool.o bna_ctrl.o bna_txrx.o
+bna-objs += bfa_ioc.o bfa_ioc_ct.o bfa_cee.o cna_fwimg.o
+
+EXTRA_CFLAGS := -Idrivers/net/bna
diff --git a/drivers/net/bna/bfa_cee.c b/drivers/net/bna/bfa_cee.c
new file mode 100644
index 000000000000..f7b789a3b217
--- /dev/null
+++ b/drivers/net/bna/bfa_cee.c
@@ -0,0 +1,291 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#include "bfa_defs_cna.h"
+#include "cna.h"
+#include "bfa_cee.h"
+#include "bfi_cna.h"
+#include "bfa_ioc.h"
+
+#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
+#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
+
+static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg);
+static void bfa_cee_format_cee_cfg(void *buffer);
+
+static void
+bfa_cee_format_cee_cfg(void *buffer)
+{
+ struct bfa_cee_attr *cee_cfg = buffer;
+ bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote);
+}
+
+static void
+bfa_cee_stats_swap(struct bfa_cee_stats *stats)
+{
+ u32 *buffer = (u32 *)stats;
+ int i;
+
+ for (i = 0; i < (sizeof(struct bfa_cee_stats) / sizeof(u32));
+ i++) {
+ buffer[i] = ntohl(buffer[i]);
+ }
+}
+
+static void
+bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg)
+{
+ lldp_cfg->time_to_live =
+ ntohs(lldp_cfg->time_to_live);
+ lldp_cfg->enabled_system_cap =
+ ntohs(lldp_cfg->enabled_system_cap);
+}
+
+/**
+ * bfa_cee_attr_meminfo()
+ *
+ * @brief Returns the size of the DMA memory needed by CEE attributes
+ *
+ * @param[in] void
+ *
+ * @return Size of DMA region
+ */
+static u32
+bfa_cee_attr_meminfo(void)
+{
+ return roundup(sizeof(struct bfa_cee_attr), BFA_DMA_ALIGN_SZ);
+}
+/**
+ * bfa_cee_stats_meminfo()
+ *
+ * @brief Returns the size of the DMA memory needed by CEE stats
+ *
+ * @param[in] void
+ *
+ * @return Size of DMA region
+ */
+static u32
+bfa_cee_stats_meminfo(void)
+{
+ return roundup(sizeof(struct bfa_cee_stats), BFA_DMA_ALIGN_SZ);
+}
+
+/**
+ * bfa_cee_get_attr_isr()
+ *
+ * @brief CEE ISR for get-attributes responses from f/w
+ *
+ * @param[in] cee - Pointer to the CEE module
+ * status - Return status from the f/w
+ *
+ * @return void
+ */
+static void
+bfa_cee_get_attr_isr(struct bfa_cee *cee, enum bfa_status status)
+{
+ cee->get_attr_status = status;
+ if (status == BFA_STATUS_OK) {
+ memcpy(cee->attr, cee->attr_dma.kva,
+ sizeof(struct bfa_cee_attr));
+ bfa_cee_format_cee_cfg(cee->attr);
+ }
+ cee->get_attr_pending = false;
+ if (cee->cbfn.get_attr_cbfn)
+ cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
+}
+
+/**
+ * bfa_cee_get_attr_isr()
+ *
+ * @brief CEE ISR for get-stats responses from f/w
+ *
+ * @param[in] cee - Pointer to the CEE module
+ * status - Return status from the f/w
+ *
+ * @return void
+ */
+static void
+bfa_cee_get_stats_isr(struct bfa_cee *cee, enum bfa_status status)
+{
+ cee->get_stats_status = status;
+ if (status == BFA_STATUS_OK) {
+ memcpy(cee->stats, cee->stats_dma.kva,
+ sizeof(struct bfa_cee_stats));
+ bfa_cee_stats_swap(cee->stats);
+ }
+ cee->get_stats_pending = false;
+ if (cee->cbfn.get_stats_cbfn)
+ cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
+}
+
+/**
+ * bfa_cee_get_attr_isr()
+ *
+ * @brief CEE ISR for reset-stats responses from f/w
+ *
+ * @param[in] cee - Pointer to the CEE module
+ * status - Return status from the f/w
+ *
+ * @return void
+ */
+static void
+bfa_cee_reset_stats_isr(struct bfa_cee *cee, enum bfa_status status)
+{
+ cee->reset_stats_status = status;
+ cee->reset_stats_pending = false;
+ if (cee->cbfn.reset_stats_cbfn)
+ cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
+}
+/**
+ * bfa_nw_cee_meminfo()
+ *
+ * @brief Returns the size of the DMA memory needed by CEE module
+ *
+ * @param[in] void
+ *
+ * @return Size of DMA region
+ */
+u32
+bfa_nw_cee_meminfo(void)
+{
+ return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo();
+}
+
+/**
+ * bfa_nw_cee_mem_claim()
+ *
+ * @brief Initialized CEE DMA Memory
+ *
+ * @param[in] cee CEE module pointer
+ * dma_kva Kernel Virtual Address of CEE DMA Memory
+ * dma_pa Physical Address of CEE DMA Memory
+ *
+ * @return void
+ */
+void
+bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa)
+{
+ cee->attr_dma.kva = dma_kva;
+ cee->attr_dma.pa = dma_pa;
+ cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo();
+ cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo();
+ cee->attr = (struct bfa_cee_attr *) dma_kva;
+ cee->stats = (struct bfa_cee_stats *)
+ (dma_kva + bfa_cee_attr_meminfo());
+}
+
+/**
+ * bfa_cee_isrs()
+ *
+ * @brief Handles Mail-box interrupts for CEE module.
+ *
+ * @param[in] Pointer to the CEE module data structure.
+ *
+ * @return void
+ */
+
+static void
+bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m)
+{
+ union bfi_cee_i2h_msg_u *msg;
+ struct bfi_cee_get_rsp *get_rsp;
+ struct bfa_cee *cee = (struct bfa_cee *) cbarg;
+ msg = (union bfi_cee_i2h_msg_u *) m;
+ get_rsp = (struct bfi_cee_get_rsp *) m;
+ switch (msg->mh.msg_id) {
+ case BFI_CEE_I2H_GET_CFG_RSP:
+ bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
+ break;
+ case BFI_CEE_I2H_GET_STATS_RSP:
+ bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
+ break;
+ case BFI_CEE_I2H_RESET_STATS_RSP:
+ bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
+ break;
+ default:
+ BUG_ON(1);
+ }
+}
+
+/**
+ * bfa_cee_hbfail()
+ *
+ * @brief CEE module heart-beat failure handler.
+ *
+ * @param[in] Pointer to the CEE module data structure.
+ *
+ * @return void
+ */
+
+static void
+bfa_cee_hbfail(void *arg)
+{
+ struct bfa_cee *cee;
+ cee = (struct bfa_cee *) arg;
+
+ if (cee->get_attr_pending == true) {
+ cee->get_attr_status = BFA_STATUS_FAILED;
+ cee->get_attr_pending = false;
+ if (cee->cbfn.get_attr_cbfn) {
+ cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg,
+ BFA_STATUS_FAILED);
+ }
+ }
+ if (cee->get_stats_pending == true) {
+ cee->get_stats_status = BFA_STATUS_FAILED;
+ cee->get_stats_pending = false;
+ if (cee->cbfn.get_stats_cbfn) {
+ cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg,
+ BFA_STATUS_FAILED);
+ }
+ }
+ if (cee->reset_stats_pending == true) {
+ cee->reset_stats_status = BFA_STATUS_FAILED;
+ cee->reset_stats_pending = false;
+ if (cee->cbfn.reset_stats_cbfn) {
+ cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg,
+ BFA_STATUS_FAILED);
+ }
+ }
+}
+
+/**
+ * bfa_nw_cee_attach()
+ *
+ * @brief CEE module-attach API
+ *
+ * @param[in] cee - Pointer to the CEE module data structure
+ * ioc - Pointer to the ioc module data structure
+ * dev - Pointer to the device driver module data structure
+ * The device driver specific mbox ISR functions have
+ * this pointer as one of the parameters.
+ *
+ * @return void
+ */
+void
+bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc,
+ void *dev)
+{
+ BUG_ON(!(cee != NULL));
+ cee->dev = dev;
+ cee->ioc = ioc;
+
+ bfa_nw_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
+ bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee);
+ bfa_nw_ioc_hbfail_register(cee->ioc, &cee->hbfail);
+}
diff --git a/drivers/net/bna/bfa_cee.h b/drivers/net/bna/bfa_cee.h
new file mode 100644
index 000000000000..20543d15b64f
--- /dev/null
+++ b/drivers/net/bna/bfa_cee.h
@@ -0,0 +1,64 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFA_CEE_H__
+#define __BFA_CEE_H__
+
+#include "bfa_defs_cna.h"
+#include "bfa_ioc.h"
+
+typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, enum bfa_status status);
+typedef void (*bfa_cee_get_stats_cbfn_t) (void *dev, enum bfa_status status);
+typedef void (*bfa_cee_reset_stats_cbfn_t) (void *dev, enum bfa_status status);
+typedef void (*bfa_cee_hbfail_cbfn_t) (void *dev, enum bfa_status status);
+
+struct bfa_cee_cbfn {
+ bfa_cee_get_attr_cbfn_t get_attr_cbfn;
+ void *get_attr_cbarg;
+ bfa_cee_get_stats_cbfn_t get_stats_cbfn;
+ void *get_stats_cbarg;
+ bfa_cee_reset_stats_cbfn_t reset_stats_cbfn;
+ void *reset_stats_cbarg;
+};
+
+struct bfa_cee {
+ void *dev;
+ bool get_attr_pending;
+ bool get_stats_pending;
+ bool reset_stats_pending;
+ enum bfa_status get_attr_status;
+ enum bfa_status get_stats_status;
+ enum bfa_status reset_stats_status;
+ struct bfa_cee_cbfn cbfn;
+ struct bfa_ioc_hbfail_notify hbfail;
+ struct bfa_cee_attr *attr;
+ struct bfa_cee_stats *stats;
+ struct bfa_dma attr_dma;
+ struct bfa_dma stats_dma;
+ struct bfa_ioc *ioc;
+ struct bfa_mbox_cmd get_cfg_mb;
+ struct bfa_mbox_cmd get_stats_mb;
+ struct bfa_mbox_cmd reset_stats_mb;
+};
+
+u32 bfa_nw_cee_meminfo(void);
+void bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva,
+ u64 dma_pa);
+void bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, void *dev);
+
+#endif /* __BFA_CEE_H__ */
diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h
new file mode 100644
index 000000000000..29c1b8de2c2d
--- /dev/null
+++ b/drivers/net/bna/bfa_defs.h
@@ -0,0 +1,243 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFA_DEFS_H__
+#define __BFA_DEFS_H__
+
+#include "cna.h"
+#include "bfa_defs_status.h"
+#include "bfa_defs_mfg_comm.h"
+
+#define BFA_STRING_32 32
+#define BFA_VERSION_LEN 64
+
+/**
+ * ---------------------- adapter definitions ------------
+ */
+
+/**
+ * BFA adapter level attributes.
+ */
+enum {
+ BFA_ADAPTER_SERIAL_NUM_LEN = STRSZ(BFA_MFG_SERIALNUM_SIZE),
+ /*
+ *!< adapter serial num length
+ */
+ BFA_ADAPTER_MODEL_NAME_LEN = 16, /*!< model name length */
+ BFA_ADAPTER_MODEL_DESCR_LEN = 128, /*!< model description length */
+ BFA_ADAPTER_MFG_NAME_LEN = 8, /*!< manufacturer name length */
+ BFA_ADAPTER_SYM_NAME_LEN = 64, /*!< adapter symbolic name length */
+ BFA_ADAPTER_OS_TYPE_LEN = 64, /*!< adapter os type length */
+};
+
+struct bfa_adapter_attr {
+ char manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
+ char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
+ u32 card_type;
+ char model[BFA_ADAPTER_MODEL_NAME_LEN];
+ char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
+ u64 pwwn;
+ char node_symname[FC_SYMNAME_MAX];
+ char hw_ver[BFA_VERSION_LEN];
+ char fw_ver[BFA_VERSION_LEN];
+ char optrom_ver[BFA_VERSION_LEN];
+ char os_type[BFA_ADAPTER_OS_TYPE_LEN];
+ struct bfa_mfg_vpd vpd;
+ struct mac mac;
+
+ u8 nports;
+ u8 max_speed;
+ u8 prototype;
+ char asic_rev;
+
+ u8 pcie_gen;
+ u8 pcie_lanes_orig;
+ u8 pcie_lanes;
+ u8 cna_capable;
+
+ u8 is_mezz;
+ u8 trunk_capable;
+};
+
+/**
+ * ---------------------- IOC definitions ------------
+ */
+
+enum {
+ BFA_IOC_DRIVER_LEN = 16,
+ BFA_IOC_CHIP_REV_LEN = 8,
+};
+
+/**
+ * Driver and firmware versions.
+ */
+struct bfa_ioc_driver_attr {
+ char driver[BFA_IOC_DRIVER_LEN]; /*!< driver name */
+ char driver_ver[BFA_VERSION_LEN]; /*!< driver version */
+ char fw_ver[BFA_VERSION_LEN]; /*!< firmware version */
+ char bios_ver[BFA_VERSION_LEN]; /*!< bios version */
+ char efi_ver[BFA_VERSION_LEN]; /*!< EFI version */
+ char ob_ver[BFA_VERSION_LEN]; /*!< openboot version */
+};
+
+/**
+ * IOC PCI device attributes
+ */
+struct bfa_ioc_pci_attr {
+ u16 vendor_id; /*!< PCI vendor ID */
+ u16 device_id; /*!< PCI device ID */
+ u16 ssid; /*!< subsystem ID */
+ u16 ssvid; /*!< subsystem vendor ID */
+ u32 pcifn; /*!< PCI device function */
+ u32 rsvd; /* padding */
+ char chip_rev[BFA_IOC_CHIP_REV_LEN]; /*!< chip revision */
+};
+
+/**
+ * IOC states
+ */
+enum bfa_ioc_state {
+ BFA_IOC_RESET = 1, /*!< IOC is in reset state */
+ BFA_IOC_SEMWAIT = 2, /*!< Waiting for IOC h/w semaphore */
+ BFA_IOC_HWINIT = 3, /*!< IOC h/w is being initialized */
+ BFA_IOC_GETATTR = 4, /*!< IOC is being configured */
+ BFA_IOC_OPERATIONAL = 5, /*!< IOC is operational */
+ BFA_IOC_INITFAIL = 6, /*!< IOC hardware failure */
+ BFA_IOC_HBFAIL = 7, /*!< IOC heart-beat failure */
+ BFA_IOC_DISABLING = 8, /*!< IOC is being disabled */
+ BFA_IOC_DISABLED = 9, /*!< IOC is disabled */
+ BFA_IOC_FWMISMATCH = 10, /*!< IOC f/w different from drivers */
+};
+
+/**
+ * IOC firmware stats
+ */
+struct bfa_fw_ioc_stats {
+ u32 enable_reqs;
+ u32 disable_reqs;
+ u32 get_attr_reqs;
+ u32 dbg_sync;
+ u32 dbg_dump;
+ u32 unknown_reqs;
+};
+
+/**
+ * IOC driver stats
+ */
+struct bfa_ioc_drv_stats {
+ u32 ioc_isrs;
+ u32 ioc_enables;
+ u32 ioc_disables;
+ u32 ioc_hbfails;
+ u32 ioc_boots;
+ u32 stats_tmos;
+ u32 hb_count;
+ u32 disable_reqs;
+ u32 enable_reqs;
+ u32 disable_replies;
+ u32 enable_replies;
+};
+
+/**
+ * IOC statistics
+ */
+struct bfa_ioc_stats {
+ struct bfa_ioc_drv_stats drv_stats; /*!< driver IOC stats */
+ struct bfa_fw_ioc_stats fw_stats; /*!< firmware IOC stats */
+};
+
+enum bfa_ioc_type {
+ BFA_IOC_TYPE_FC = 1,
+ BFA_IOC_TYPE_FCoE = 2,
+ BFA_IOC_TYPE_LL = 3,
+};
+
+/**
+ * IOC attributes returned in queries
+ */
+struct bfa_ioc_attr {
+ enum bfa_ioc_type ioc_type;
+ enum bfa_ioc_state state; /*!< IOC state */
+ struct bfa_adapter_attr adapter_attr; /*!< HBA attributes */
+ struct bfa_ioc_driver_attr driver_attr; /*!< driver attr */
+ struct bfa_ioc_pci_attr pci_attr;
+ u8 port_id; /*!< port number */
+ u8 rsvd[7]; /*!< 64bit align */
+};
+
+/**
+ * ---------------------- mfg definitions ------------
+ */
+
+/**
+ * Checksum size
+ */
+#define BFA_MFG_CHKSUM_SIZE 16
+
+#define BFA_MFG_PARTNUM_SIZE 14
+#define BFA_MFG_SUPPLIER_ID_SIZE 10
+#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20
+#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20
+#define BFA_MFG_SUPPLIER_REVISION_SIZE 4
+
+#pragma pack(1)
+
+/**
+ * @brief BFA adapter manufacturing block definition.
+ *
+ * All numerical fields are in big-endian format.
+ */
+struct bfa_mfg_block {
+ u8 version; /*!< manufacturing block version */
+ u8 mfg_sig[3]; /*!< characters 'M', 'F', 'G' */
+ u16 mfgsize; /*!< mfg block size */
+ u16 u16_chksum; /*!< old u16 checksum */
+ char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)];
+ char brcd_partnum[STRSZ(BFA_MFG_PARTNUM_SIZE)];
+ u8 mfg_day; /*!< manufacturing day */
+ u8 mfg_month; /*!< manufacturing month */
+ u16 mfg_year; /*!< manufacturing year */
+ u64 mfg_wwn; /*!< wwn base for this adapter */
+ u8 num_wwn; /*!< number of wwns assigned */
+ u8 mfg_speeds; /*!< speeds allowed for this adapter */
+ u8 rsv[2];
+ char supplier_id[STRSZ(BFA_MFG_SUPPLIER_ID_SIZE)];
+ char supplier_partnum[STRSZ(BFA_MFG_SUPPLIER_PARTNUM_SIZE)];
+ char
+ supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)];
+ char
+ supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)];
+ mac_t mfg_mac; /*!< mac address */
+ u8 num_mac; /*!< number of mac addresses */
+ u8 rsv2;
+ u32 mfg_type; /*!< card type */
+ u8 rsv3[108];
+ u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /*!< md5 checksum */
+};
+
+#pragma pack()
+
+/**
+ * ---------------------- pci definitions ------------
+ */
+
+#define bfa_asic_id_ct(devid) \
+ ((devid) == PCI_DEVICE_ID_BROCADE_CT || \
+ (devid) == PCI_DEVICE_ID_BROCADE_CT_FC)
+
+#endif /* __BFA_DEFS_H__ */
diff --git a/drivers/net/bna/bfa_defs_cna.h b/drivers/net/bna/bfa_defs_cna.h
new file mode 100644
index 000000000000..7e0a9187bdd5
--- /dev/null
+++ b/drivers/net/bna/bfa_defs_cna.h
@@ -0,0 +1,223 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFA_DEFS_CNA_H__
+#define __BFA_DEFS_CNA_H__
+
+#include "bfa_defs.h"
+
+/**
+ * @brief
+ * FC physical port statistics.
+ */
+struct bfa_port_fc_stats {
+ u64 secs_reset; /*!< Seconds since stats is reset */
+ u64 tx_frames; /*!< Tx frames */
+ u64 tx_words; /*!< Tx words */
+ u64 tx_lip; /*!< Tx LIP */
+ u64 tx_nos; /*!< Tx NOS */
+ u64 tx_ols; /*!< Tx OLS */
+ u64 tx_lr; /*!< Tx LR */
+ u64 tx_lrr; /*!< Tx LRR */
+ u64 rx_frames; /*!< Rx frames */
+ u64 rx_words; /*!< Rx words */
+ u64 lip_count; /*!< Rx LIP */
+ u64 nos_count; /*!< Rx NOS */
+ u64 ols_count; /*!< Rx OLS */
+ u64 lr_count; /*!< Rx LR */
+ u64 lrr_count; /*!< Rx LRR */
+ u64 invalid_crcs; /*!< Rx CRC err frames */
+ u64 invalid_crc_gd_eof; /*!< Rx CRC err good EOF frames */
+ u64 undersized_frm; /*!< Rx undersized frames */
+ u64 oversized_frm; /*!< Rx oversized frames */
+ u64 bad_eof_frm; /*!< Rx frames with bad EOF */
+ u64 error_frames; /*!< Errored frames */
+ u64 dropped_frames; /*!< Dropped frames */
+ u64 link_failures; /*!< Link Failure (LF) count */
+ u64 loss_of_syncs; /*!< Loss of sync count */
+ u64 loss_of_signals; /*!< Loss of signal count */
+ u64 primseq_errs; /*!< Primitive sequence protocol err. */
+ u64 bad_os_count; /*!< Invalid ordered sets */
+ u64 err_enc_out; /*!< Encoding err nonframe_8b10b */
+ u64 err_enc; /*!< Encoding err frame_8b10b */
+};
+
+/**
+ * @brief
+ * Eth Physical Port statistics.
+ */
+struct bfa_port_eth_stats {
+ u64 secs_reset; /*!< Seconds since stats is reset */
+ u64 frame_64; /*!< Frames 64 bytes */
+ u64 frame_65_127; /*!< Frames 65-127 bytes */
+ u64 frame_128_255; /*!< Frames 128-255 bytes */
+ u64 frame_256_511; /*!< Frames 256-511 bytes */
+ u64 frame_512_1023; /*!< Frames 512-1023 bytes */
+ u64 frame_1024_1518; /*!< Frames 1024-1518 bytes */
+ u64 frame_1519_1522; /*!< Frames 1519-1522 bytes */
+ u64 tx_bytes; /*!< Tx bytes */
+ u64 tx_packets; /*!< Tx packets */
+ u64 tx_mcast_packets; /*!< Tx multicast packets */
+ u64 tx_bcast_packets; /*!< Tx broadcast packets */
+ u64 tx_control_frame; /*!< Tx control frame */
+ u64 tx_drop; /*!< Tx drops */
+ u64 tx_jabber; /*!< Tx jabber */
+ u64 tx_fcs_error; /*!< Tx FCS errors */
+ u64 tx_fragments; /*!< Tx fragments */
+ u64 rx_bytes; /*!< Rx bytes */
+ u64 rx_packets; /*!< Rx packets */
+ u64 rx_mcast_packets; /*!< Rx multicast packets */
+ u64 rx_bcast_packets; /*!< Rx broadcast packets */
+ u64 rx_control_frames; /*!< Rx control frames */
+ u64 rx_unknown_opcode; /*!< Rx unknown opcode */
+ u64 rx_drop; /*!< Rx drops */
+ u64 rx_jabber; /*!< Rx jabber */
+ u64 rx_fcs_error; /*!< Rx FCS errors */
+ u64 rx_alignment_error; /*!< Rx alignment errors */
+ u64 rx_frame_length_error; /*!< Rx frame len errors */
+ u64 rx_code_error; /*!< Rx code errors */
+ u64 rx_fragments; /*!< Rx fragments */
+ u64 rx_pause; /*!< Rx pause */
+ u64 rx_zero_pause; /*!< Rx zero pause */
+ u64 tx_pause; /*!< Tx pause */
+ u64 tx_zero_pause; /*!< Tx zero pause */
+ u64 rx_fcoe_pause; /*!< Rx FCoE pause */
+ u64 rx_fcoe_zero_pause; /*!< Rx FCoE zero pause */
+ u64 tx_fcoe_pause; /*!< Tx FCoE pause */
+ u64 tx_fcoe_zero_pause; /*!< Tx FCoE zero pause */
+};
+
+/**
+ * @brief
+ * Port statistics.
+ */
+union bfa_port_stats_u {
+ struct bfa_port_fc_stats fc;
+ struct bfa_port_eth_stats eth;
+};
+
+#pragma pack(1)
+
+#define BFA_CEE_LLDP_MAX_STRING_LEN (128)
+#define BFA_CEE_DCBX_MAX_PRIORITY (8)
+#define BFA_CEE_DCBX_MAX_PGID (8)
+
+#define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001
+#define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002
+#define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004
+#define BFA_CEE_LLDP_SYS_CAP_WLAN_AP 0x0008
+#define BFA_CEE_LLDP_SYS_CAP_ROUTER 0x0010
+#define BFA_CEE_LLDP_SYS_CAP_TELEPHONE 0x0020
+#define BFA_CEE_LLDP_SYS_CAP_DOCSIS_CD 0x0040
+#define BFA_CEE_LLDP_SYS_CAP_STATION 0x0080
+#define BFA_CEE_LLDP_SYS_CAP_CVLAN 0x0100
+#define BFA_CEE_LLDP_SYS_CAP_SVLAN 0x0200
+#define BFA_CEE_LLDP_SYS_CAP_TPMR 0x0400
+
+/* LLDP string type */
+struct bfa_cee_lldp_str {
+ u8 sub_type;
+ u8 len;
+ u8 rsvd[2];
+ u8 value[BFA_CEE_LLDP_MAX_STRING_LEN];
+};
+
+/* LLDP paramters */
+struct bfa_cee_lldp_cfg {
+ struct bfa_cee_lldp_str chassis_id;
+ struct bfa_cee_lldp_str port_id;
+ struct bfa_cee_lldp_str port_desc;
+ struct bfa_cee_lldp_str sys_name;
+ struct bfa_cee_lldp_str sys_desc;
+ struct bfa_cee_lldp_str mgmt_addr;
+ u16 time_to_live;
+ u16 enabled_system_cap;
+};
+
+enum bfa_cee_dcbx_version {
+ DCBX_PROTOCOL_PRECEE = 1,
+ DCBX_PROTOCOL_CEE = 2,
+};
+
+enum bfa_cee_lls {
+ /* LLS is down because the TLV not sent by the peer */
+ CEE_LLS_DOWN_NO_TLV = 0,
+ /* LLS is down as advertised by the peer */
+ CEE_LLS_DOWN = 1,
+ CEE_LLS_UP = 2,
+};
+
+/* CEE/DCBX parameters */
+struct bfa_cee_dcbx_cfg {
+ u8 pgid[BFA_CEE_DCBX_MAX_PRIORITY];
+ u8 pg_percentage[BFA_CEE_DCBX_MAX_PGID];
+ u8 pfc_primap; /* bitmap of priorties with PFC enabled */
+ u8 fcoe_primap; /* bitmap of priorities used for FcoE traffic */
+ u8 iscsi_primap; /* bitmap of priorities used for iSCSI traffic */
+ u8 dcbx_version; /* operating version:CEE or preCEE */
+ u8 lls_fcoe; /* FCoE Logical Link Status */
+ u8 lls_lan; /* LAN Logical Link Status */
+ u8 rsvd[2];
+};
+
+/* CEE status */
+/* Making this to tri-state for the benefit of port list command */
+enum bfa_cee_status {
+ CEE_UP = 0,
+ CEE_PHY_UP = 1,
+ CEE_LOOPBACK = 2,
+ CEE_PHY_DOWN = 3,
+};
+
+/* CEE Query */
+struct bfa_cee_attr {
+ u8 cee_status;
+ u8 error_reason;
+ struct bfa_cee_lldp_cfg lldp_remote;
+ struct bfa_cee_dcbx_cfg dcbx_remote;
+ mac_t src_mac;
+ u8 link_speed;
+ u8 nw_priority;
+ u8 filler[2];
+};
+
+/* LLDP/DCBX/CEE Statistics */
+struct bfa_cee_stats {
+ u32 lldp_tx_frames; /*!< LLDP Tx Frames */
+ u32 lldp_rx_frames; /*!< LLDP Rx Frames */
+ u32 lldp_rx_frames_invalid; /*!< LLDP Rx Frames invalid */
+ u32 lldp_rx_frames_new; /*!< LLDP Rx Frames new */
+ u32 lldp_tlvs_unrecognized; /*!< LLDP Rx unrecognized TLVs */
+ u32 lldp_rx_shutdown_tlvs; /*!< LLDP Rx shutdown TLVs */
+ u32 lldp_info_aged_out; /*!< LLDP remote info aged out */
+ u32 dcbx_phylink_ups; /*!< DCBX phy link ups */
+ u32 dcbx_phylink_downs; /*!< DCBX phy link downs */
+ u32 dcbx_rx_tlvs; /*!< DCBX Rx TLVs */
+ u32 dcbx_rx_tlvs_invalid; /*!< DCBX Rx TLVs invalid */
+ u32 dcbx_control_tlv_error; /*!< DCBX control TLV errors */
+ u32 dcbx_feature_tlv_error; /*!< DCBX feature TLV errors */
+ u32 dcbx_cee_cfg_new; /*!< DCBX new CEE cfg rcvd */
+ u32 cee_status_down; /*!< CEE status down */
+ u32 cee_status_up; /*!< CEE status up */
+ u32 cee_hw_cfg_changed; /*!< CEE hw cfg changed */
+ u32 cee_rx_invalid_cfg; /*!< CEE invalid cfg */
+};
+
+#pragma pack()
+
+#endif /* __BFA_DEFS_CNA_H__ */
diff --git a/drivers/net/bna/bfa_defs_mfg_comm.h b/drivers/net/bna/bfa_defs_mfg_comm.h
new file mode 100644
index 000000000000..987978fcb3fe
--- /dev/null
+++ b/drivers/net/bna/bfa_defs_mfg_comm.h
@@ -0,0 +1,244 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BFA_DEFS_MFG_COMM_H__
+#define __BFA_DEFS_MFG_COMM_H__
+
+#include "cna.h"
+
+/**
+ * Manufacturing block version
+ */
+#define BFA_MFG_VERSION 2
+#define BFA_MFG_VERSION_UNINIT 0xFF
+
+/**
+ * Manufacturing block encrypted version
+ */
+#define BFA_MFG_ENC_VER 2
+
+/**
+ * Manufacturing block version 1 length
+ */
+#define BFA_MFG_VER1_LEN 128
+
+/**
+ * Manufacturing block header length
+ */
+#define BFA_MFG_HDR_LEN 4
+
+#define BFA_MFG_SERIALNUM_SIZE 11
+#define STRSZ(_n) (((_n) + 4) & ~3)
+
+/**
+ * Manufacturing card type
+ */
+enum {
+ BFA_MFG_TYPE_CB_MAX = 825, /*!< Crossbow card type max */
+ BFA_MFG_TYPE_FC8P2 = 825, /*!< 8G 2port FC card */
+ BFA_MFG_TYPE_FC8P1 = 815, /*!< 8G 1port FC card */
+ BFA_MFG_TYPE_FC4P2 = 425, /*!< 4G 2port FC card */
+ BFA_MFG_TYPE_FC4P1 = 415, /*!< 4G 1port FC card */
+ BFA_MFG_TYPE_CNA10P2 = 1020, /*!< 10G 2port CNA card */
+ BFA_MFG_TYPE_CNA10P1 = 1010, /*!< 10G 1port CNA card */
+ BFA_MFG_TYPE_JAYHAWK = 804, /*!< Jayhawk mezz card */
+ BFA_MFG_TYPE_WANCHESE = 1007, /*!< Wanchese mezz card */
+ BFA_MFG_TYPE_ASTRA = 807, /*!< Astra mezz card */
+ BFA_MFG_TYPE_LIGHTNING_P0 = 902, /*!< Lightning mezz card - old */
+ BFA_MFG_TYPE_LIGHTNING = 1741, /*!< Lightning mezz card */
+ BFA_MFG_TYPE_INVALID = 0, /*!< Invalid card type */
+};
+
+#pragma pack(1)
+
+/**
+ * Check if 1-port card
+ */
+#define bfa_mfg_is_1port(type) (( \
+ (type) == BFA_MFG_TYPE_FC8P1 || \
+ (type) == BFA_MFG_TYPE_FC4P1 || \
+ (type) == BFA_MFG_TYPE_CNA10P1))
+
+/**
+ * Check if Mezz card
+ */
+#define bfa_mfg_is_mezz(type) (( \
+ (type) == BFA_MFG_TYPE_JAYHAWK || \
+ (type) == BFA_MFG_TYPE_WANCHESE || \
+ (type) == BFA_MFG_TYPE_ASTRA || \
+ (type) == BFA_MFG_TYPE_LIGHTNING_P0 || \
+ (type) == BFA_MFG_TYPE_LIGHTNING))
+
+/**
+ * Check if card type valid
+ */
+#define bfa_mfg_is_card_type_valid(type) (( \
+ (type) == BFA_MFG_TYPE_FC8P2 || \
+ (type) == BFA_MFG_TYPE_FC8P1 || \
+ (type) == BFA_MFG_TYPE_FC4P2 || \
+ (type) == BFA_MFG_TYPE_FC4P1 || \
+ (type) == BFA_MFG_TYPE_CNA10P2 || \
+ (type) == BFA_MFG_TYPE_CNA10P1 || \
+ bfa_mfg_is_mezz(type)))
+
+/**
+ * Check if the card having old wwn/mac handling
+ */
+#define bfa_mfg_is_old_wwn_mac_model(type) (( \
+ (type) == BFA_MFG_TYPE_FC8P2 || \
+ (type) == BFA_MFG_TYPE_FC8P1 || \
+ (type) == BFA_MFG_TYPE_FC4P2 || \
+ (type) == BFA_MFG_TYPE_FC4P1 || \
+ (type) == BFA_MFG_TYPE_CNA10P2 || \
+ (type) == BFA_MFG_TYPE_CNA10P1 || \
+ (type) == BFA_MFG_TYPE_JAYHAWK || \
+ (type) == BFA_MFG_TYPE_WANCHESE))
+
+#define bfa_mfg_increment_wwn_mac(m, i) \
+do { \
+ u32 t = ((m)[0] << 16) | ((m)[1] << 8) | (m)[2]; \
+ t += (i); \
+ (m)[0] = (t >> 16) & 0xFF; \
+ (m)[1] = (t >> 8) & 0xFF; \
+ (m)[2] = t & 0xFF; \
+} while (0)
+
+#define bfa_mfg_adapter_prop_init_flash(card_type, prop) \
+do { \
+ switch ((card_type)) { \
+ case BFA_MFG_TYPE_FC8P2: \
+ case BFA_MFG_TYPE_JAYHAWK: \
+ case BFA_MFG_TYPE_ASTRA: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \
+ BFI_ADAPTER_SETP(SPEED, 8); \
+ break; \
+ case BFA_MFG_TYPE_FC8P1: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 1) | \
+ BFI_ADAPTER_SETP(SPEED, 8); \
+ break; \
+ case BFA_MFG_TYPE_FC4P2: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \
+ BFI_ADAPTER_SETP(SPEED, 4); \
+ break; \
+ case BFA_MFG_TYPE_FC4P1: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 1) | \
+ BFI_ADAPTER_SETP(SPEED, 4); \
+ break; \
+ case BFA_MFG_TYPE_CNA10P2: \
+ case BFA_MFG_TYPE_WANCHESE: \
+ case BFA_MFG_TYPE_LIGHTNING_P0: \
+ case BFA_MFG_TYPE_LIGHTNING: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 2); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 10); \
+ break; \
+ case BFA_MFG_TYPE_CNA10P1: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 1); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 10); \
+ break; \
+ default: \
+ (prop) = BFI_ADAPTER_UNSUPP; \
+ } \
+} while (0)
+
+enum {
+ CB_GPIO_TTV = (1), /*!< TTV debug capable cards */
+ CB_GPIO_FC8P2 = (2), /*!< 8G 2port FC card */
+ CB_GPIO_FC8P1 = (3), /*!< 8G 1port FC card */
+ CB_GPIO_FC4P2 = (4), /*!< 4G 2port FC card */
+ CB_GPIO_FC4P1 = (5), /*!< 4G 1port FC card */
+ CB_GPIO_DFLY = (6), /*!< 8G 2port FC mezzanine card */
+ CB_GPIO_PROTO = (1 << 7) /*!< 8G 2port FC prototypes */
+};
+
+#define bfa_mfg_adapter_prop_init_gpio(gpio, card_type, prop) \
+do { \
+ if ((gpio) & CB_GPIO_PROTO) { \
+ (prop) |= BFI_ADAPTER_PROTO; \
+ (gpio) &= ~CB_GPIO_PROTO; \
+ } \
+ switch ((gpio)) { \
+ case CB_GPIO_TTV: \
+ (prop) |= BFI_ADAPTER_TTV; \
+ case CB_GPIO_DFLY: \
+ case CB_GPIO_FC8P2: \
+ (prop) |= BFI_ADAPTER_SETP(NPORTS, 2); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 8); \
+ (card_type) = BFA_MFG_TYPE_FC8P2; \
+ break; \
+ case CB_GPIO_FC8P1: \
+ (prop) |= BFI_ADAPTER_SETP(NPORTS, 1); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 8); \
+ (card_type) = BFA_MFG_TYPE_FC8P1; \
+ break; \
+ case CB_GPIO_FC4P2: \
+ (prop) |= BFI_ADAPTER_SETP(NPORTS, 2); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 4); \
+ (card_type) = BFA_MFG_TYPE_FC4P2; \
+ break; \
+ case CB_GPIO_FC4P1: \
+ (prop) |= BFI_ADAPTER_SETP(NPORTS, 1); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 4); \
+ (card_type) = BFA_MFG_TYPE_FC4P1; \
+ break; \
+ default: \
+ (prop) |= BFI_ADAPTER_UNSUPP; \
+ (card_type) = BFA_MFG_TYPE_INVALID; \
+ } \
+} while (0)
+
+/**
+ * VPD data length
+ */
+#define BFA_MFG_VPD_LEN 512
+#define BFA_MFG_VPD_LEN_INVALID 0
+
+#define BFA_MFG_VPD_PCI_HDR_OFF 137
+#define BFA_MFG_VPD_PCI_VER_MASK 0x07 /*!< version mask 3 bits */
+#define BFA_MFG_VPD_PCI_VDR_MASK 0xf8 /*!< vendor mask 5 bits */
+
+/**
+ * VPD vendor tag
+ */
+enum {
+ BFA_MFG_VPD_UNKNOWN = 0, /*!< vendor unknown */
+ BFA_MFG_VPD_IBM = 1, /*!< vendor IBM */
+ BFA_MFG_VPD_HP = 2, /*!< vendor HP */
+ BFA_MFG_VPD_DELL = 3, /*!< vendor DELL */
+ BFA_MFG_VPD_PCI_IBM = 0x08, /*!< PCI VPD IBM */
+ BFA_MFG_VPD_PCI_HP = 0x10, /*!< PCI VPD HP */
+ BFA_MFG_VPD_PCI_DELL = 0x20, /*!< PCI VPD DELL */
+ BFA_MFG_VPD_PCI_BRCD = 0xf8, /*!< PCI VPD Brocade */
+};
+
+/**
+ * @brief BFA adapter flash vpd data definition.
+ *
+ * All numerical fields are in big-endian format.
+ */
+struct bfa_mfg_vpd {
+ u8 version; /*!< vpd data version */
+ u8 vpd_sig[3]; /*!< characters 'V', 'P', 'D' */
+ u8 chksum; /*!< u8 checksum */
+ u8 vendor; /*!< vendor */
+ u8 len; /*!< vpd data length excluding header */
+ u8 rsv;
+ u8 data[BFA_MFG_VPD_LEN]; /*!< vpd data */
+};
+
+#pragma pack()
+
+#endif /* __BFA_DEFS_MFG_H__ */
diff --git a/drivers/net/bna/bfa_defs_status.h b/drivers/net/bna/bfa_defs_status.h
new file mode 100644
index 000000000000..af951126375c
--- /dev/null
+++ b/drivers/net/bna/bfa_defs_status.h
@@ -0,0 +1,216 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BFA_DEFS_STATUS_H__
+#define __BFA_DEFS_STATUS_H__
+
+/**
+ * API status return values
+ *
+ * NOTE: The error msgs are auto generated from the comments. Only singe line
+ * comments are supported
+ */
+enum bfa_status {
+ BFA_STATUS_OK = 0,
+ BFA_STATUS_FAILED = 1,
+ BFA_STATUS_EINVAL = 2,
+ BFA_STATUS_ENOMEM = 3,
+ BFA_STATUS_ENOSYS = 4,
+ BFA_STATUS_ETIMER = 5,
+ BFA_STATUS_EPROTOCOL = 6,
+ BFA_STATUS_ENOFCPORTS = 7,
+ BFA_STATUS_NOFLASH = 8,
+ BFA_STATUS_BADFLASH = 9,
+ BFA_STATUS_SFP_UNSUPP = 10,
+ BFA_STATUS_UNKNOWN_VFID = 11,
+ BFA_STATUS_DATACORRUPTED = 12,
+ BFA_STATUS_DEVBUSY = 13,
+ BFA_STATUS_ABORTED = 14,
+ BFA_STATUS_NODEV = 15,
+ BFA_STATUS_HDMA_FAILED = 16,
+ BFA_STATUS_FLASH_BAD_LEN = 17,
+ BFA_STATUS_UNKNOWN_LWWN = 18,
+ BFA_STATUS_UNKNOWN_RWWN = 19,
+ BFA_STATUS_FCPT_LS_RJT = 20,
+ BFA_STATUS_VPORT_EXISTS = 21,
+ BFA_STATUS_VPORT_MAX = 22,
+ BFA_STATUS_UNSUPP_SPEED = 23,
+ BFA_STATUS_INVLD_DFSZ = 24,
+ BFA_STATUS_CNFG_FAILED = 25,
+ BFA_STATUS_CMD_NOTSUPP = 26,
+ BFA_STATUS_NO_ADAPTER = 27,
+ BFA_STATUS_LINKDOWN = 28,
+ BFA_STATUS_FABRIC_RJT = 29,
+ BFA_STATUS_UNKNOWN_VWWN = 30,
+ BFA_STATUS_NSLOGIN_FAILED = 31,
+ BFA_STATUS_NO_RPORTS = 32,
+ BFA_STATUS_NSQUERY_FAILED = 33,
+ BFA_STATUS_PORT_OFFLINE = 34,
+ BFA_STATUS_RPORT_OFFLINE = 35,
+ BFA_STATUS_TGTOPEN_FAILED = 36,
+ BFA_STATUS_BAD_LUNS = 37,
+ BFA_STATUS_IO_FAILURE = 38,
+ BFA_STATUS_NO_FABRIC = 39,
+ BFA_STATUS_EBADF = 40,
+ BFA_STATUS_EINTR = 41,
+ BFA_STATUS_EIO = 42,
+ BFA_STATUS_ENOTTY = 43,
+ BFA_STATUS_ENXIO = 44,
+ BFA_STATUS_EFOPEN = 45,
+ BFA_STATUS_VPORT_WWN_BP = 46,
+ BFA_STATUS_PORT_NOT_DISABLED = 47,
+ BFA_STATUS_BADFRMHDR = 48,
+ BFA_STATUS_BADFRMSZ = 49,
+ BFA_STATUS_MISSINGFRM = 50,
+ BFA_STATUS_LINKTIMEOUT = 51,
+ BFA_STATUS_NO_FCPIM_NEXUS = 52,
+ BFA_STATUS_CHECKSUM_FAIL = 53,
+ BFA_STATUS_GZME_FAILED = 54,
+ BFA_STATUS_SCSISTART_REQD = 55,
+ BFA_STATUS_IOC_FAILURE = 56,
+ BFA_STATUS_INVALID_WWN = 57,
+ BFA_STATUS_MISMATCH = 58,
+ BFA_STATUS_IOC_ENABLED = 59,
+ BFA_STATUS_ADAPTER_ENABLED = 60,
+ BFA_STATUS_IOC_NON_OP = 61,
+ BFA_STATUS_ADDR_MAP_FAILURE = 62,
+ BFA_STATUS_SAME_NAME = 63,
+ BFA_STATUS_PENDING = 64,
+ BFA_STATUS_8G_SPD = 65,
+ BFA_STATUS_4G_SPD = 66,
+ BFA_STATUS_AD_IS_ENABLE = 67,
+ BFA_STATUS_EINVAL_TOV = 68,
+ BFA_STATUS_EINVAL_QDEPTH = 69,
+ BFA_STATUS_VERSION_FAIL = 70,
+ BFA_STATUS_DIAG_BUSY = 71,
+ BFA_STATUS_BEACON_ON = 72,
+ BFA_STATUS_BEACON_OFF = 73,
+ BFA_STATUS_LBEACON_ON = 74,
+ BFA_STATUS_LBEACON_OFF = 75,
+ BFA_STATUS_PORT_NOT_INITED = 76,
+ BFA_STATUS_RPSC_ENABLED = 77,
+ BFA_STATUS_ENOFSAVE = 78,
+ BFA_STATUS_BAD_FILE = 79,
+ BFA_STATUS_RLIM_EN = 80,
+ BFA_STATUS_RLIM_DIS = 81,
+ BFA_STATUS_IOC_DISABLED = 82,
+ BFA_STATUS_ADAPTER_DISABLED = 83,
+ BFA_STATUS_BIOS_DISABLED = 84,
+ BFA_STATUS_AUTH_ENABLED = 85,
+ BFA_STATUS_AUTH_DISABLED = 86,
+ BFA_STATUS_ERROR_TRL_ENABLED = 87,
+ BFA_STATUS_ERROR_QOS_ENABLED = 88,
+ BFA_STATUS_NO_SFP_DEV = 89,
+ BFA_STATUS_MEMTEST_FAILED = 90,
+ BFA_STATUS_INVALID_DEVID = 91,
+ BFA_STATUS_QOS_ENABLED = 92,
+ BFA_STATUS_QOS_DISABLED = 93,
+ BFA_STATUS_INCORRECT_DRV_CONFIG = 94,
+ BFA_STATUS_REG_FAIL = 95,
+ BFA_STATUS_IM_INV_CODE = 96,
+ BFA_STATUS_IM_INV_VLAN = 97,
+ BFA_STATUS_IM_INV_ADAPT_NAME = 98,
+ BFA_STATUS_IM_LOW_RESOURCES = 99,
+ BFA_STATUS_IM_VLANID_IS_PVID = 100,
+ BFA_STATUS_IM_VLANID_EXISTS = 101,
+ BFA_STATUS_IM_FW_UPDATE_FAIL = 102,
+ BFA_STATUS_PORTLOG_ENABLED = 103,
+ BFA_STATUS_PORTLOG_DISABLED = 104,
+ BFA_STATUS_FILE_NOT_FOUND = 105,
+ BFA_STATUS_QOS_FC_ONLY = 106,
+ BFA_STATUS_RLIM_FC_ONLY = 107,
+ BFA_STATUS_CT_SPD = 108,
+ BFA_STATUS_LEDTEST_OP = 109,
+ BFA_STATUS_CEE_NOT_DN = 110,
+ BFA_STATUS_10G_SPD = 111,
+ BFA_STATUS_IM_INV_TEAM_NAME = 112,
+ BFA_STATUS_IM_DUP_TEAM_NAME = 113,
+ BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114,
+ BFA_STATUS_IM_ADAPT_HAS_VLANS = 115,
+ BFA_STATUS_IM_PVID_MISMATCH = 116,
+ BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117,
+ BFA_STATUS_IM_MTU_MISMATCH = 118,
+ BFA_STATUS_IM_RSS_MISMATCH = 119,
+ BFA_STATUS_IM_HDS_MISMATCH = 120,
+ BFA_STATUS_IM_OFFLOAD_MISMATCH = 121,
+ BFA_STATUS_IM_PORT_PARAMS = 122,
+ BFA_STATUS_IM_PORT_NOT_IN_TEAM = 123,
+ BFA_STATUS_IM_CANNOT_REM_PRI = 124,
+ BFA_STATUS_IM_MAX_PORTS_REACHED = 125,
+ BFA_STATUS_IM_LAST_PORT_DELETE = 126,
+ BFA_STATUS_IM_NO_DRIVER = 127,
+ BFA_STATUS_IM_MAX_VLANS_REACHED = 128,
+ BFA_STATUS_TOMCAT_SPD_NOT_ALLOWED = 129,
+ BFA_STATUS_NO_MINPORT_DRIVER = 130,
+ BFA_STATUS_CARD_TYPE_MISMATCH = 131,
+ BFA_STATUS_BAD_ASICBLK = 132,
+ BFA_STATUS_NO_DRIVER = 133,
+ BFA_STATUS_INVALID_MAC = 134,
+ BFA_STATUS_IM_NO_VLAN = 135,
+ BFA_STATUS_IM_ETH_LB_FAILED = 136,
+ BFA_STATUS_IM_PVID_REMOVE = 137,
+ BFA_STATUS_IM_PVID_EDIT = 138,
+ BFA_STATUS_CNA_NO_BOOT = 139,
+ BFA_STATUS_IM_PVID_NON_ZERO = 140,
+ BFA_STATUS_IM_INETCFG_LOCK_FAILED = 141,
+ BFA_STATUS_IM_GET_INETCFG_FAILED = 142,
+ BFA_STATUS_IM_NOT_BOUND = 143,
+ BFA_STATUS_INSUFFICIENT_PERMS = 144,
+ BFA_STATUS_IM_INV_VLAN_NAME = 145,
+ BFA_STATUS_CMD_NOTSUPP_CNA = 146,
+ BFA_STATUS_IM_PASSTHRU_EDIT = 147,
+ BFA_STATUS_IM_BIND_FAILED = 148,
+ BFA_STATUS_IM_UNBIND_FAILED = 149,
+ BFA_STATUS_IM_PORT_IN_TEAM = 150,
+ BFA_STATUS_IM_VLAN_NOT_FOUND = 151,
+ BFA_STATUS_IM_TEAM_NOT_FOUND = 152,
+ BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153,
+ BFA_STATUS_PBC = 154,
+ BFA_STATUS_DEVID_MISSING = 155,
+ BFA_STATUS_BAD_FWCFG = 156,
+ BFA_STATUS_CREATE_FILE = 157,
+ BFA_STATUS_INVALID_VENDOR = 158,
+ BFA_STATUS_SFP_NOT_READY = 159,
+ BFA_STATUS_FLASH_UNINIT = 160,
+ BFA_STATUS_FLASH_EMPTY = 161,
+ BFA_STATUS_FLASH_CKFAIL = 162,
+ BFA_STATUS_TRUNK_UNSUPP = 163,
+ BFA_STATUS_TRUNK_ENABLED = 164,
+ BFA_STATUS_TRUNK_DISABLED = 165,
+ BFA_STATUS_TRUNK_ERROR_TRL_ENABLED = 166,
+ BFA_STATUS_BOOT_CODE_UPDATED = 167,
+ BFA_STATUS_BOOT_VERSION = 168,
+ BFA_STATUS_CARDTYPE_MISSING = 169,
+ BFA_STATUS_INVALID_CARDTYPE = 170,
+ BFA_STATUS_NO_TOPOLOGY_FOR_CNA = 171,
+ BFA_STATUS_IM_VLAN_OVER_TEAM_DELETE_FAILED = 172,
+ BFA_STATUS_ETHBOOT_ENABLED = 173,
+ BFA_STATUS_ETHBOOT_DISABLED = 174,
+ BFA_STATUS_IOPROFILE_OFF = 175,
+ BFA_STATUS_NO_PORT_INSTANCE = 176,
+ BFA_STATUS_BOOT_CODE_TIMEDOUT = 177,
+ BFA_STATUS_NO_VPORT_LOCK = 178,
+ BFA_STATUS_VPORT_NO_CNFG = 179,
+ BFA_STATUS_MAX_VAL
+};
+
+enum bfa_eproto_status {
+ BFA_EPROTO_BAD_ACCEPT = 0,
+ BFA_EPROTO_UNKNOWN_RSP = 1
+};
+
+#endif /* __BFA_DEFS_STATUS_H__ */
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
new file mode 100644
index 000000000000..e94e5aa97515
--- /dev/null
+++ b/drivers/net/bna/bfa_ioc.c
@@ -0,0 +1,1732 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#include "bfa_ioc.h"
+#include "cna.h"
+#include "bfi.h"
+#include "bfi_ctreg.h"
+#include "bfa_defs.h"
+
+/**
+ * IOC local definitions
+ */
+
+#define bfa_ioc_timer_start(__ioc) \
+ mod_timer(&(__ioc)->ioc_timer, jiffies + \
+ msecs_to_jiffies(BFA_IOC_TOV))
+#define bfa_ioc_timer_stop(__ioc) del_timer(&(__ioc)->ioc_timer)
+
+#define bfa_ioc_recovery_timer_start(__ioc) \
+ mod_timer(&(__ioc)->ioc_timer, jiffies + \
+ msecs_to_jiffies(BFA_IOC_TOV_RECOVER))
+
+#define bfa_sem_timer_start(__ioc) \
+ mod_timer(&(__ioc)->sem_timer, jiffies + \
+ msecs_to_jiffies(BFA_IOC_HWSEM_TOV))
+#define bfa_sem_timer_stop(__ioc) del_timer(&(__ioc)->sem_timer)
+
+#define bfa_hb_timer_start(__ioc) \
+ mod_timer(&(__ioc)->hb_timer, jiffies + \
+ msecs_to_jiffies(BFA_IOC_HB_TOV))
+#define bfa_hb_timer_stop(__ioc) del_timer(&(__ioc)->hb_timer)
+
+/**
+ * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
+ */
+
+#define bfa_ioc_firmware_lock(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
+#define bfa_ioc_firmware_unlock(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
+#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
+#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
+#define bfa_ioc_notify_hbfail(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
+
+#define bfa_ioc_is_optrom(__ioc) \
+ (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ)
+
+#define bfa_ioc_mbox_cmd_pending(__ioc) \
+ (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
+ readl((__ioc)->ioc_regs.hfn_mbox_cmd))
+
+static bool bfa_nw_auto_recover = true;
+
+/*
+ * forward declarations
+ */
+static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc);
+static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc);
+static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force);
+static void bfa_ioc_send_enable(struct bfa_ioc *ioc);
+static void bfa_ioc_send_disable(struct bfa_ioc *ioc);
+static void bfa_ioc_send_getattr(struct bfa_ioc *ioc);
+static void bfa_ioc_hb_monitor(struct bfa_ioc *ioc);
+static void bfa_ioc_hb_stop(struct bfa_ioc *ioc);
+static void bfa_ioc_reset(struct bfa_ioc *ioc, bool force);
+static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc);
+static void bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc);
+static void bfa_ioc_recover(struct bfa_ioc *ioc);
+static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc);
+static void bfa_ioc_disable_comp(struct bfa_ioc *ioc);
+static void bfa_ioc_lpu_stop(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,
+ char *fw_ver);
+static void bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc,
+ char *chip_rev);
+static void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc,
+ char *optrom_ver);
+static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc,
+ char *manufacturer);
+static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model);
+static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc);
+static mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc);
+
+/**
+ * IOC state machine events
+ */
+enum ioc_event {
+ IOC_E_ENABLE = 1, /*!< IOC enable request */
+ IOC_E_DISABLE = 2, /*!< IOC disable request */
+ IOC_E_TIMEOUT = 3, /*!< f/w response timeout */
+ IOC_E_FWREADY = 4, /*!< f/w initialization done */
+ IOC_E_FWRSP_GETATTR = 5, /*!< IOC get attribute response */
+ IOC_E_FWRSP_ENABLE = 6, /*!< enable f/w response */
+ IOC_E_FWRSP_DISABLE = 7, /*!< disable f/w response */
+ IOC_E_HBFAIL = 8, /*!< heartbeat failure */
+ IOC_E_HWERROR = 9, /*!< hardware error interrupt */
+ IOC_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */
+ IOC_E_DETACH = 11, /*!< driver detach cleanup */
+};
+
+bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event);
+
+static struct bfa_sm_table ioc_sm_table[] = {
+ {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
+ {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH},
+ {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH},
+ {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT},
+ {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT},
+ {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT},
+ {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
+ {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
+ {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL},
+ {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL},
+ {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
+ {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
+};
+
+/**
+ * Reset entry actions -- initialize state machine
+ */
+static void
+bfa_ioc_sm_reset_entry(struct bfa_ioc *ioc)
+{
+ ioc->retry_count = 0;
+ ioc->auto_recover = bfa_nw_auto_recover;
+}
+
+/**
+ * Beginning state. IOC is in reset state.
+ */
+static void
+bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_ENABLE:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_disable_comp(ioc);
+ break;
+
+ case IOC_E_DETACH:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Semaphore should be acquired for version check.
+ */
+static void
+bfa_ioc_sm_fwcheck_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_hw_sem_get(ioc);
+}
+
+/**
+ * Awaiting h/w semaphore to continue with version check.
+ */
+static void
+bfa_ioc_sm_fwcheck(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_SEMLOCKED:
+ if (bfa_ioc_firmware_lock(ioc)) {
+ ioc->retry_count = 0;
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
+ } else {
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch);
+ }
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_disable_comp(ioc);
+ /* fall through */
+
+ case IOC_E_DETACH:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ case IOC_E_FWREADY:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Notify enable completion callback and generate mismatch AEN.
+ */
+static void
+bfa_ioc_sm_mismatch_entry(struct bfa_ioc *ioc)
+{
+ /**
+ * Provide enable completion callback and AEN notification only once.
+ */
+ if (ioc->retry_count == 0)
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ ioc->retry_count++;
+ bfa_ioc_timer_start(ioc);
+}
+
+/**
+ * Awaiting firmware version match.
+ */
+static void
+bfa_ioc_sm_mismatch(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_disable_comp(ioc);
+ /* fall through */
+
+ case IOC_E_DETACH:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ case IOC_E_FWREADY:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Request for semaphore.
+ */
+static void
+bfa_ioc_sm_semwait_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_hw_sem_get(ioc);
+}
+
+/**
+ * Awaiting semaphore for h/w initialzation.
+ */
+static void
+bfa_ioc_sm_semwait(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_SEMLOCKED:
+ ioc->retry_count = 0;
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_hwinit_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_reset(ioc, false);
+}
+
+/**
+ * @brief
+ * Hardware is being initialized. Interrupts are enabled.
+ * Holding hardware semaphore lock.
+ */
+static void
+bfa_ioc_sm_hwinit(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_FWREADY:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /* fall through */
+
+ case IOC_E_TIMEOUT:
+ ioc->retry_count++;
+ if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_reset(ioc, true);
+ break;
+ }
+
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_send_enable(ioc);
+}
+
+/**
+ * Host IOC function is being enabled, awaiting response from firmware.
+ * Semaphore is acquired.
+ */
+static void
+bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_FWRSP_ENABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /* fall through */
+
+ case IOC_E_TIMEOUT:
+ ioc->retry_count++;
+ if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
+ writel(BFI_IOC_UNINIT,
+ ioc->ioc_regs.ioc_fwstate);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
+ break;
+ }
+
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_FWREADY:
+ bfa_ioc_send_enable(ioc);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_send_getattr(ioc);
+}
+
+/**
+ * @brief
+ * IOC configuration in progress. Timer is active.
+ */
+static void
+bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_FWRSP_GETATTR:
+ bfa_ioc_timer_stop(ioc);
+ bfa_ioc_check_attr_wwns(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /* fall through */
+
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_op_entry(struct bfa_ioc *ioc)
+{
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
+ bfa_ioc_hb_monitor(ioc);
+}
+
+static void
+bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_ENABLE:
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_hb_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
+ break;
+
+ case IOC_E_HWERROR:
+ case IOC_E_FWREADY:
+ /**
+ * Hard error or IOC recovery by other function.
+ * Treat it same as heartbeat failure.
+ */
+ bfa_ioc_hb_stop(ioc);
+ /* !!! fall through !!! */
+
+ case IOC_E_HBFAIL:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_send_disable(ioc);
+}
+
+/**
+ * IOC is being disabled
+ */
+static void
+bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_FWRSP_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /*
+ * !!! fall through !!!
+ */
+
+ case IOC_E_TIMEOUT:
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * IOC disable completion entry.
+ */
+static void
+bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_disable_comp(ioc);
+}
+
+static void
+bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_ENABLE:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ break;
+
+ case IOC_E_DISABLE:
+ ioc->cbfn->disable_cbfn(ioc->bfa);
+ break;
+
+ case IOC_E_FWREADY:
+ break;
+
+ case IOC_E_DETACH:
+ bfa_ioc_firmware_unlock(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_initfail_entry(struct bfa_ioc *ioc)
+{
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_ioc_timer_start(ioc);
+}
+
+/**
+ * @brief
+ * Hardware initialization failed.
+ */
+static void
+bfa_ioc_sm_initfail(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_DETACH:
+ bfa_ioc_timer_stop(ioc);
+ bfa_ioc_firmware_unlock(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_hbfail_entry(struct bfa_ioc *ioc)
+{
+ struct list_head *qe;
+ struct bfa_ioc_hbfail_notify *notify;
+
+ /**
+ * Mark IOC as failed in hardware and stop firmware.
+ */
+ bfa_ioc_lpu_stop(ioc);
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+
+ /**
+ * Notify other functions on HB failure.
+ */
+ bfa_ioc_notify_hbfail(ioc);
+
+ /**
+ * Notify driver and common modules registered for notification.
+ */
+ ioc->cbfn->hbfail_cbfn(ioc->bfa);
+ list_for_each(qe, &ioc->hb_notify_q) {
+ notify = (struct bfa_ioc_hbfail_notify *) qe;
+ notify->cbfn(notify->cbarg);
+ }
+
+ /**
+ * Flush any queued up mailbox requests.
+ */
+ bfa_ioc_mbox_hbfail(ioc);
+
+ /**
+ * Trigger auto-recovery after a delay.
+ */
+ if (ioc->auto_recover)
+ mod_timer(&ioc->ioc_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_TOV_RECOVER));
+}
+
+/**
+ * @brief
+ * IOC heartbeat failure.
+ */
+static void
+bfa_ioc_sm_hbfail(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+
+ case IOC_E_ENABLE:
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ break;
+
+ case IOC_E_DISABLE:
+ if (ioc->auto_recover)
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ break;
+
+ case IOC_E_FWREADY:
+ /**
+ * Recovery is already initiated by other function.
+ */
+ break;
+
+ case IOC_E_HWERROR:
+ /*
+ * HB failure notification, ignore.
+ */
+ break;
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * BFA IOC private functions
+ */
+
+static void
+bfa_ioc_disable_comp(struct bfa_ioc *ioc)
+{
+ struct list_head *qe;
+ struct bfa_ioc_hbfail_notify *notify;
+
+ ioc->cbfn->disable_cbfn(ioc->bfa);
+
+ /**
+ * Notify common modules registered for notification.
+ */
+ list_for_each(qe, &ioc->hb_notify_q) {
+ notify = (struct bfa_ioc_hbfail_notify *) qe;
+ notify->cbfn(notify->cbarg);
+ }
+}
+
+void
+bfa_nw_ioc_sem_timeout(void *ioc_arg)
+{
+ struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg;
+
+ bfa_ioc_hw_sem_get(ioc);
+}
+
+bool
+bfa_nw_ioc_sem_get(void __iomem *sem_reg)
+{
+ u32 r32;
+ int cnt = 0;
+#define BFA_SEM_SPINCNT 3000
+
+ r32 = readl(sem_reg);
+
+ while (r32 && (cnt < BFA_SEM_SPINCNT)) {
+ cnt++;
+ udelay(2);
+ r32 = readl(sem_reg);
+ }
+
+ if (r32 == 0)
+ return true;
+
+ BUG_ON(!(cnt < BFA_SEM_SPINCNT));
+ return false;
+}
+
+void
+bfa_nw_ioc_sem_release(void __iomem *sem_reg)
+{
+ writel(1, sem_reg);
+}
+
+static void
+bfa_ioc_hw_sem_get(struct bfa_ioc *ioc)
+{
+ u32 r32;
+
+ /**
+ * First read to the semaphore register will return 0, subsequent reads
+ * will return 1. Semaphore is released by writing 1 to the register
+ */
+ r32 = readl(ioc->ioc_regs.ioc_sem_reg);
+ if (r32 == 0) {
+ bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED);
+ return;
+ }
+
+ mod_timer(&ioc->sem_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_HWSEM_TOV));
+}
+
+void
+bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc)
+{
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+}
+
+static void
+bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc)
+{
+ del_timer(&ioc->sem_timer);
+}
+
+/**
+ * @brief
+ * Initialize LPU local memory (aka secondary memory / SRAM)
+ */
+static void
+bfa_ioc_lmem_init(struct bfa_ioc *ioc)
+{
+ u32 pss_ctl;
+ int i;
+#define PSS_LMEM_INIT_TIME 10000
+
+ pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
+ pss_ctl &= ~__PSS_LMEM_RESET;
+ pss_ctl |= __PSS_LMEM_INIT_EN;
+
+ /*
+ * i2c workaround 12.5khz clock
+ */
+ pss_ctl |= __PSS_I2C_CLK_DIV(3UL);
+ writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
+
+ /**
+ * wait for memory initialization to be complete
+ */
+ i = 0;
+ do {
+ pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
+ i++;
+ } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
+
+ /**
+ * If memory initialization is not successful, IOC timeout will catch
+ * such failures.
+ */
+ BUG_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE));
+
+ pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
+ writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
+}
+
+static void
+bfa_ioc_lpu_start(struct bfa_ioc *ioc)
+{
+ u32 pss_ctl;
+
+ /**
+ * Take processor out of reset.
+ */
+ pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
+ pss_ctl &= ~__PSS_LPU0_RESET;
+
+ writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
+}
+
+static void
+bfa_ioc_lpu_stop(struct bfa_ioc *ioc)
+{
+ u32 pss_ctl;
+
+ /**
+ * Put processors in reset.
+ */
+ pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
+ pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
+
+ writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
+}
+
+/**
+ * Get driver and firmware versions.
+ */
+void
+bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
+{
+ u32 pgnum, pgoff;
+ 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));
+ i++) {
+ fwsig[i] =
+ swab32(readl((loff) + (ioc->ioc_regs.smem_page_start)));
+ loff += sizeof(u32);
+ }
+}
+
+/**
+ * Returns TRUE if same.
+ */
+bool
+bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
+{
+ struct bfi_ioc_image_hdr *drv_fwhdr;
+ int i;
+
+ drv_fwhdr = (struct bfi_ioc_image_hdr *)
+ bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
+
+ for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
+ if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i])
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Return true if current running version is valid. Firmware signature and
+ * execution context (driver/bios) must match.
+ */
+static bool
+bfa_ioc_fwver_valid(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_image_hdr fwhdr, *drv_fwhdr;
+
+ /**
+ * If bios/efi boot (flash based) -- return true
+ */
+ if (bfa_ioc_is_optrom(ioc))
+ return true;
+
+ bfa_nw_ioc_fwver_get(ioc, &fwhdr);
+ drv_fwhdr = (struct bfi_ioc_image_hdr *)
+ bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
+
+ if (fwhdr.signature != drv_fwhdr->signature)
+ return false;
+
+ if (fwhdr.exec != drv_fwhdr->exec)
+ return false;
+
+ return bfa_nw_ioc_fwver_cmp(ioc, &fwhdr);
+}
+
+/**
+ * Conditionally flush any pending message from firmware at start.
+ */
+static void
+bfa_ioc_msgflush(struct bfa_ioc *ioc)
+{
+ u32 r32;
+
+ r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
+ if (r32)
+ writel(1, ioc->ioc_regs.lpu_mbox_cmd);
+}
+
+/**
+ * @img ioc_init_logic.jpg
+ */
+static void
+bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
+{
+ enum bfi_ioc_state ioc_fwstate;
+ bool fwvalid;
+
+ ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+ if (force)
+ ioc_fwstate = BFI_IOC_UNINIT;
+
+ /**
+ * check if firmware is valid
+ */
+ fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
+ false : bfa_ioc_fwver_valid(ioc);
+
+ if (!fwvalid) {
+ bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
+ return;
+ }
+
+ /**
+ * If hardware initialization is in progress (initialized by other IOC),
+ * just wait for an initialization completion interrupt.
+ */
+ if (ioc_fwstate == BFI_IOC_INITING) {
+ ioc->cbfn->reset_cbfn(ioc->bfa);
+ return;
+ }
+
+ /**
+ * If IOC function is disabled and firmware version is same,
+ * just re-enable IOC.
+ *
+ * If option rom, IOC must not be in operational state. With
+ * convergence, IOC will be in operational state when 2nd driver
+ * is loaded.
+ */
+ if (ioc_fwstate == BFI_IOC_DISABLED ||
+ (!bfa_ioc_is_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) {
+ /**
+ * When using MSI-X any pending firmware ready event should
+ * be flushed. Otherwise MSI-X interrupts are not delivered.
+ */
+ bfa_ioc_msgflush(ioc);
+ ioc->cbfn->reset_cbfn(ioc->bfa);
+ bfa_fsm_send_event(ioc, IOC_E_FWREADY);
+ return;
+ }
+
+ /**
+ * Initialize the h/w for any other states.
+ */
+ bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
+}
+
+void
+bfa_nw_ioc_timeout(void *ioc_arg)
+{
+ struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg;
+
+ bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
+}
+
+static void
+bfa_ioc_mbox_send(struct bfa_ioc *ioc, void *ioc_msg, int len)
+{
+ u32 *msgp = (u32 *) ioc_msg;
+ u32 i;
+
+ BUG_ON(!(len <= BFI_IOC_MSGLEN_MAX));
+
+ /*
+ * first write msg to mailbox registers
+ */
+ for (i = 0; i < len / sizeof(u32); i++)
+ writel(cpu_to_le32(msgp[i]),
+ ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
+
+ for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
+ writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
+
+ /*
+ * write 1 to mailbox CMD to trigger LPU event
+ */
+ writel(1, ioc->ioc_regs.hfn_mbox_cmd);
+ (void) readl(ioc->ioc_regs.hfn_mbox_cmd);
+}
+
+static void
+bfa_ioc_send_enable(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_ctrl_req enable_req;
+ struct timeval tv;
+
+ bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
+ bfa_ioc_portid(ioc));
+ enable_req.ioc_class = ioc->ioc_mc;
+ do_gettimeofday(&tv);
+ enable_req.tv_sec = ntohl(tv.tv_sec);
+ bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req));
+}
+
+static void
+bfa_ioc_send_disable(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_ctrl_req disable_req;
+
+ bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
+ bfa_ioc_portid(ioc));
+ bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req));
+}
+
+static void
+bfa_ioc_send_getattr(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_getattr_req attr_req;
+
+ bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
+ bfa_ioc_portid(ioc));
+ bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
+ bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
+}
+
+void
+bfa_nw_ioc_hb_check(void *cbarg)
+{
+ struct bfa_ioc *ioc = cbarg;
+ u32 hb_count;
+
+ hb_count = readl(ioc->ioc_regs.heartbeat);
+ if (ioc->hb_count == hb_count) {
+ pr_crit("Firmware heartbeat failure at %d", hb_count);
+ bfa_ioc_recover(ioc);
+ return;
+ } else {
+ ioc->hb_count = hb_count;
+ }
+
+ bfa_ioc_mbox_poll(ioc);
+ mod_timer(&ioc->hb_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_HB_TOV));
+}
+
+static void
+bfa_ioc_hb_monitor(struct bfa_ioc *ioc)
+{
+ ioc->hb_count = readl(ioc->ioc_regs.heartbeat);
+ mod_timer(&ioc->hb_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_HB_TOV));
+}
+
+static void
+bfa_ioc_hb_stop(struct bfa_ioc *ioc)
+{
+ del_timer(&ioc->hb_timer);
+}
+
+/**
+ * @brief
+ * Initiate a full firmware download.
+ */
+static void
+bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
+ u32 boot_param)
+{
+ u32 *fwimg;
+ u32 pgnum, pgoff;
+ u32 loff = 0;
+ u32 chunkno = 0;
+ u32 i;
+
+ /**
+ * Initialize LMEM first before code download
+ */
+ bfa_ioc_lmem_init(ioc);
+
+ /**
+ * Flash based firmware boot
+ */
+ if (bfa_ioc_is_optrom(ioc))
+ boot_type = BFI_BOOT_TYPE_FLASH;
+ 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);
+
+ for (i = 0; i < bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) {
+ if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
+ chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
+ fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc),
+ BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
+ }
+
+ /**
+ * write smem
+ */
+ writel((swab32(fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)])),
+ ((ioc->ioc_regs.smem_page_start) + (loff)));
+
+ loff += sizeof(u32);
+
+ /**
+ * handle page offset wrap around
+ */
+ loff = PSS_SMEM_PGOFF(loff);
+ if (loff == 0) {
+ pgnum++;
+ writel(pgnum,
+ ioc->ioc_regs.host_page_num_fn);
+ }
+ }
+
+ writel(bfa_ioc_smem_pgnum(ioc, 0),
+ ioc->ioc_regs.host_page_num_fn);
+
+ /*
+ * Set boot type and boot param at the end.
+ */
+ writel((swab32(swab32(boot_type))), ((ioc->ioc_regs.smem_page_start)
+ + (BFI_BOOT_TYPE_OFF)));
+ writel((swab32(swab32(boot_param))), ((ioc->ioc_regs.smem_page_start)
+ + (BFI_BOOT_PARAM_OFF)));
+}
+
+static void
+bfa_ioc_reset(struct bfa_ioc *ioc, bool force)
+{
+ bfa_ioc_hwinit(ioc, force);
+}
+
+/**
+ * @brief
+ * Update BFA configuration from firmware configuration.
+ */
+static void
+bfa_ioc_getattr_reply(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_attr *attr = ioc->attr;
+
+ attr->adapter_prop = ntohl(attr->adapter_prop);
+ attr->card_type = ntohl(attr->card_type);
+ attr->maxfrsize = ntohs(attr->maxfrsize);
+
+ bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
+}
+
+/**
+ * Attach time initialization of mbox logic.
+ */
+static void
+bfa_ioc_mbox_attach(struct bfa_ioc *ioc)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+ int mc;
+
+ INIT_LIST_HEAD(&mod->cmd_q);
+ for (mc = 0; mc < BFI_MC_MAX; mc++) {
+ mod->mbhdlr[mc].cbfn = NULL;
+ mod->mbhdlr[mc].cbarg = ioc->bfa;
+ }
+}
+
+/**
+ * Mbox poll timer -- restarts any pending mailbox requests.
+ */
+static void
+bfa_ioc_mbox_poll(struct bfa_ioc *ioc)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+ struct bfa_mbox_cmd *cmd;
+ u32 stat;
+
+ /**
+ * If no command pending, do nothing
+ */
+ if (list_empty(&mod->cmd_q))
+ return;
+
+ /**
+ * If previous command is not yet fetched by firmware, do nothing
+ */
+ stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
+ if (stat)
+ return;
+
+ /**
+ * Enqueue command to firmware.
+ */
+ bfa_q_deq(&mod->cmd_q, &cmd);
+ bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
+}
+
+/**
+ * Cleanup any pending requests.
+ */
+static void
+bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+ struct bfa_mbox_cmd *cmd;
+
+ while (!list_empty(&mod->cmd_q))
+ bfa_q_deq(&mod->cmd_q, &cmd);
+}
+
+/**
+ * IOC public
+ */
+static enum bfa_status
+bfa_ioc_pll_init(struct bfa_ioc *ioc)
+{
+ /*
+ * Hold semaphore so that nobody can access the chip during init.
+ */
+ bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
+
+ bfa_ioc_pll_init_asic(ioc);
+
+ ioc->pllinit = true;
+ /*
+ * release semaphore.
+ */
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
+ return BFA_STATUS_OK;
+}
+
+/**
+ * Interface used by diag module to do firmware boot with memory test
+ * as the entry vector.
+ */
+static void
+bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param)
+{
+ void __iomem *rb;
+
+ bfa_ioc_stats(ioc, ioc_boots);
+
+ if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
+ return;
+
+ /**
+ * Initialize IOC state of all functions on a chip reset.
+ */
+ rb = ioc->pcidev.pci_bar_kva;
+ if (boot_param == BFI_BOOT_TYPE_MEMTEST) {
+ writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG));
+ writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG));
+ } else {
+ writel(BFI_IOC_INITING, (rb + BFA_IOC0_STATE_REG));
+ writel(BFI_IOC_INITING, (rb + BFA_IOC1_STATE_REG));
+ }
+
+ bfa_ioc_msgflush(ioc);
+ bfa_ioc_download_fw(ioc, boot_type, boot_param);
+
+ /**
+ * Enable interrupts just before starting LPU
+ */
+ ioc->cbfn->reset_cbfn(ioc->bfa);
+ bfa_ioc_lpu_start(ioc);
+}
+
+/**
+ * Enable/disable IOC failure auto recovery.
+ */
+void
+bfa_nw_ioc_auto_recover(bool auto_recover)
+{
+ bfa_nw_auto_recover = auto_recover;
+}
+
+static void
+bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg)
+{
+ u32 *msgp = mbmsg;
+ u32 r32;
+ int i;
+
+ /**
+ * read the MBOX msg
+ */
+ for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
+ i++) {
+ r32 = readl(ioc->ioc_regs.lpu_mbox +
+ i * sizeof(u32));
+ msgp[i] = htonl(r32);
+ }
+
+ /**
+ * turn off mailbox interrupt by clearing mailbox status
+ */
+ writel(1, ioc->ioc_regs.lpu_mbox_cmd);
+ readl(ioc->ioc_regs.lpu_mbox_cmd);
+}
+
+static void
+bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m)
+{
+ union bfi_ioc_i2h_msg_u *msg;
+
+ msg = (union bfi_ioc_i2h_msg_u *) m;
+
+ bfa_ioc_stats(ioc, ioc_isrs);
+
+ switch (msg->mh.msg_id) {
+ case BFI_IOC_I2H_HBEAT:
+ break;
+
+ case BFI_IOC_I2H_READY_EVENT:
+ bfa_fsm_send_event(ioc, IOC_E_FWREADY);
+ break;
+
+ case BFI_IOC_I2H_ENABLE_REPLY:
+ bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE);
+ break;
+
+ case BFI_IOC_I2H_DISABLE_REPLY:
+ bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE);
+ break;
+
+ case BFI_IOC_I2H_GETATTR_REPLY:
+ bfa_ioc_getattr_reply(ioc);
+ break;
+
+ default:
+ BUG_ON(1);
+ }
+}
+
+/**
+ * IOC attach time initialization and setup.
+ *
+ * @param[in] ioc memory for IOC
+ * @param[in] bfa driver instance structure
+ */
+void
+bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn)
+{
+ ioc->bfa = bfa;
+ ioc->cbfn = cbfn;
+ ioc->fcmode = false;
+ ioc->pllinit = false;
+ ioc->dbg_fwsave_once = true;
+
+ bfa_ioc_mbox_attach(ioc);
+ INIT_LIST_HEAD(&ioc->hb_notify_q);
+
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+}
+
+/**
+ * Driver detach time IOC cleanup.
+ */
+void
+bfa_nw_ioc_detach(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_DETACH);
+}
+
+/**
+ * Setup IOC PCI properties.
+ *
+ * @param[in] pcidev PCI device information for this IOC
+ */
+void
+bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
+ enum bfi_mclass mc)
+{
+ ioc->ioc_mc = mc;
+ ioc->pcidev = *pcidev;
+ ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id);
+ ioc->cna = ioc->ctdev && !ioc->fcmode;
+
+ bfa_nw_ioc_set_ct_hwif(ioc);
+
+ bfa_ioc_map_port(ioc);
+ bfa_ioc_reg_init(ioc);
+}
+
+/**
+ * Initialize IOC dma memory
+ *
+ * @param[in] dm_kva kernel virtual address of IOC dma memory
+ * @param[in] dm_pa physical address of IOC dma memory
+ */
+void
+bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa)
+{
+ /**
+ * dma memory for firmware attribute
+ */
+ ioc->attr_dma.kva = dm_kva;
+ ioc->attr_dma.pa = dm_pa;
+ ioc->attr = (struct bfi_ioc_attr *) dm_kva;
+}
+
+/**
+ * Return size of dma memory required.
+ */
+u32
+bfa_nw_ioc_meminfo(void)
+{
+ return roundup(sizeof(struct bfi_ioc_attr), BFA_DMA_ALIGN_SZ);
+}
+
+void
+bfa_nw_ioc_enable(struct bfa_ioc *ioc)
+{
+ bfa_ioc_stats(ioc, ioc_enables);
+ ioc->dbg_fwsave_once = true;
+
+ bfa_fsm_send_event(ioc, IOC_E_ENABLE);
+}
+
+void
+bfa_nw_ioc_disable(struct bfa_ioc *ioc)
+{
+ bfa_ioc_stats(ioc, ioc_disables);
+ bfa_fsm_send_event(ioc, IOC_E_DISABLE);
+}
+
+static u32
+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
+ */
+void
+bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
+ bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+
+ mod->mbhdlr[mc].cbfn = cbfn;
+ mod->mbhdlr[mc].cbarg = cbarg;
+}
+
+/**
+ * Queue a mailbox command request to firmware. Waits if mailbox is busy.
+ * Responsibility of caller to serialize
+ *
+ * @param[in] ioc IOC instance
+ * @param[i] cmd Mailbox command
+ */
+void
+bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+ u32 stat;
+
+ /**
+ * If a previous command is pending, queue new command
+ */
+ if (!list_empty(&mod->cmd_q)) {
+ list_add_tail(&cmd->qe, &mod->cmd_q);
+ return;
+ }
+
+ /**
+ * If mailbox is busy, queue command for poll timer
+ */
+ stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
+ if (stat) {
+ list_add_tail(&cmd->qe, &mod->cmd_q);
+ return;
+ }
+
+ /**
+ * mailbox is free -- queue command to firmware
+ */
+ bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
+}
+
+/**
+ * Handle mailbox interrupts
+ */
+void
+bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+ struct bfi_mbmsg m;
+ int mc;
+
+ bfa_ioc_msgget(ioc, &m);
+
+ /**
+ * Treat IOC message class as special.
+ */
+ mc = m.mh.msg_class;
+ if (mc == BFI_MC_IOC) {
+ bfa_ioc_isr(ioc, &m);
+ return;
+ }
+
+ if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
+ return;
+
+ mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
+}
+
+void
+bfa_nw_ioc_error_isr(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_HWERROR);
+}
+
+/**
+ * Add to IOC heartbeat failure notification queue. To be used by common
+ * modules such as cee, port, diag.
+ */
+void
+bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc,
+ struct bfa_ioc_hbfail_notify *notify)
+{
+ list_add_tail(&notify->qe, &ioc->hb_notify_q);
+}
+
+#define BFA_MFG_NAME "Brocade"
+static void
+bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc,
+ struct bfa_adapter_attr *ad_attr)
+{
+ struct bfi_ioc_attr *ioc_attr;
+
+ ioc_attr = ioc->attr;
+
+ bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
+ bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
+ bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
+ bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
+ memcpy(&ad_attr->vpd, &ioc_attr->vpd,
+ sizeof(struct bfa_mfg_vpd));
+
+ ad_attr->nports = bfa_ioc_get_nports(ioc);
+ ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
+
+ bfa_ioc_get_adapter_model(ioc, ad_attr->model);
+ /* For now, model descr uses same model string */
+ bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
+
+ ad_attr->card_type = ioc_attr->card_type;
+ ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type);
+
+ if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
+ ad_attr->prototype = 1;
+ else
+ ad_attr->prototype = 0;
+
+ ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
+ ad_attr->mac = bfa_nw_ioc_get_mac(ioc);
+
+ ad_attr->pcie_gen = ioc_attr->pcie_gen;
+ ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
+ ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
+ ad_attr->asic_rev = ioc_attr->asic_rev;
+
+ bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
+
+ ad_attr->cna_capable = ioc->cna;
+ ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna;
+}
+
+static enum bfa_ioc_type
+bfa_ioc_get_type(struct bfa_ioc *ioc)
+{
+ if (!ioc->ctdev || ioc->fcmode)
+ return BFA_IOC_TYPE_FC;
+ else if (ioc->ioc_mc == BFI_MC_IOCFC)
+ return BFA_IOC_TYPE_FCoE;
+ else if (ioc->ioc_mc == BFI_MC_LL)
+ return BFA_IOC_TYPE_LL;
+ else {
+ BUG_ON(!(ioc->ioc_mc == BFI_MC_LL));
+ return BFA_IOC_TYPE_LL;
+ }
+}
+
+static void
+bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num)
+{
+ memset(serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
+ memcpy(serial_num,
+ (void *)ioc->attr->brcd_serialnum,
+ BFA_ADAPTER_SERIAL_NUM_LEN);
+}
+
+static void
+bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, char *fw_ver)
+{
+ memset(fw_ver, 0, BFA_VERSION_LEN);
+ memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
+}
+
+static void
+bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev)
+{
+ BUG_ON(!(chip_rev));
+
+ memset(chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
+
+ chip_rev[0] = 'R';
+ chip_rev[1] = 'e';
+ chip_rev[2] = 'v';
+ chip_rev[3] = '-';
+ chip_rev[4] = ioc->attr->asic_rev;
+ chip_rev[5] = '\0';
+}
+
+static void
+bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver)
+{
+ memset(optrom_ver, 0, BFA_VERSION_LEN);
+ memcpy(optrom_ver, ioc->attr->optrom_version,
+ BFA_VERSION_LEN);
+}
+
+static void
+bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer)
+{
+ memset(manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
+ memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
+}
+
+static void
+bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model)
+{
+ struct bfi_ioc_attr *ioc_attr;
+
+ BUG_ON(!(model));
+ memset(model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
+
+ ioc_attr = ioc->attr;
+
+ /**
+ * model name
+ */
+ snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
+ BFA_MFG_NAME, ioc_attr->card_type);
+}
+
+static enum bfa_ioc_state
+bfa_ioc_get_state(struct bfa_ioc *ioc)
+{
+ return bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+}
+
+void
+bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr)
+{
+ memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr));
+
+ ioc_attr->state = bfa_ioc_get_state(ioc);
+ ioc_attr->port_id = ioc->port_id;
+
+ ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
+
+ bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
+
+ ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
+ ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
+ bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
+}
+
+/**
+ * WWN public
+ */
+static u64
+bfa_ioc_get_pwwn(struct bfa_ioc *ioc)
+{
+ return ioc->attr->pwwn;
+}
+
+mac_t
+bfa_nw_ioc_get_mac(struct bfa_ioc *ioc)
+{
+ /*
+ * Currently mfg mac is used as FCoE enode mac (not configured by PBC)
+ */
+ if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE)
+ return bfa_ioc_get_mfg_mac(ioc);
+ else
+ return ioc->attr->mac;
+}
+
+static mac_t
+bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc)
+{
+ mac_t m;
+
+ m = ioc->attr->mfg_mac;
+ if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type))
+ m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
+ else
+ bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]),
+ bfa_ioc_pcifn(ioc));
+
+ return m;
+}
+
+/**
+ * Firmware failure detected. Start recovery actions.
+ */
+static void
+bfa_ioc_recover(struct bfa_ioc *ioc)
+{
+ bfa_ioc_stats(ioc, ioc_hbfails);
+ bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
+}
+
+static void
+bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc)
+{
+ if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
+ return;
+
+}
diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h
new file mode 100644
index 000000000000..a73d84ec808c
--- /dev/null
+++ b/drivers/net/bna/bfa_ioc.h
@@ -0,0 +1,300 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFA_IOC_H__
+#define __BFA_IOC_H__
+
+#include "bfa_sm.h"
+#include "bfi.h"
+#include "cna.h"
+
+#define BFA_IOC_TOV 3000 /* msecs */
+#define BFA_IOC_HWSEM_TOV 500 /* msecs */
+#define BFA_IOC_HB_TOV 500 /* msecs */
+#define BFA_IOC_HWINIT_MAX 2
+#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV
+
+/**
+ * Generic Scatter Gather Element used by driver
+ */
+struct bfa_sge {
+ u32 sg_len;
+ void *sg_addr;
+};
+
+/**
+ * PCI device information required by IOC
+ */
+struct bfa_pcidev {
+ int pci_slot;
+ u8 pci_func;
+ u16 device_id;
+ void __iomem *pci_bar_kva;
+};
+
+/**
+ * Structure used to remember the DMA-able memory block's KVA and Physical
+ * Address
+ */
+struct bfa_dma {
+ void *kva; /* ! Kernel virtual address */
+ u64 pa; /* ! Physical address */
+};
+
+#define BFA_DMA_ALIGN_SZ 256
+
+/**
+ * smem size for Crossbow and Catapult
+ */
+#define BFI_SMEM_CB_SIZE 0x200000U /* ! 2MB for crossbow */
+#define BFI_SMEM_CT_SIZE 0x280000U /* ! 2.5MB for catapult */
+
+/**
+ * @brief BFA dma address assignment macro
+ */
+#define bfa_dma_addr_set(dma_addr, pa) \
+ __bfa_dma_addr_set(&dma_addr, (u64)pa)
+
+static inline void
+__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
+{
+ dma_addr->a32.addr_lo = (u32) pa;
+ dma_addr->a32.addr_hi = (u32) (upper_32_bits(pa));
+}
+
+/**
+ * @brief BFA dma address assignment macro. (big endian format)
+ */
+#define bfa_dma_be_addr_set(dma_addr, pa) \
+ __bfa_dma_be_addr_set(&dma_addr, (u64)pa)
+static inline void
+__bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa)
+{
+ dma_addr->a32.addr_lo = (u32) htonl(pa);
+ dma_addr->a32.addr_hi = (u32) htonl(upper_32_bits(pa));
+}
+
+struct bfa_ioc_regs {
+ void __iomem *hfn_mbox_cmd;
+ void __iomem *hfn_mbox;
+ void __iomem *lpu_mbox_cmd;
+ void __iomem *lpu_mbox;
+ void __iomem *pss_ctl_reg;
+ void __iomem *pss_err_status_reg;
+ void __iomem *app_pll_fast_ctl_reg;
+ void __iomem *app_pll_slow_ctl_reg;
+ void __iomem *ioc_sem_reg;
+ void __iomem *ioc_usage_sem_reg;
+ void __iomem *ioc_init_sem_reg;
+ void __iomem *ioc_usage_reg;
+ void __iomem *host_page_num_fn;
+ void __iomem *heartbeat;
+ void __iomem *ioc_fwstate;
+ void __iomem *ll_halt;
+ void __iomem *err_set;
+ void __iomem *shirq_isr_next;
+ void __iomem *shirq_msk_next;
+ void __iomem *smem_page_start;
+ u32 smem_pg0;
+};
+
+/**
+ * IOC Mailbox structures
+ */
+struct bfa_mbox_cmd {
+ struct list_head qe;
+ u32 msg[BFI_IOC_MSGSZ];
+};
+
+/**
+ * IOC mailbox module
+ */
+typedef void (*bfa_ioc_mbox_mcfunc_t)(void *cbarg, struct bfi_mbmsg *m);
+struct bfa_ioc_mbox_mod {
+ struct list_head cmd_q; /*!< pending mbox queue */
+ int nmclass; /*!< number of handlers */
+ struct {
+ bfa_ioc_mbox_mcfunc_t cbfn; /*!< message handlers */
+ void *cbarg;
+ } mbhdlr[BFI_MC_MAX];
+};
+
+/**
+ * IOC callback function interfaces
+ */
+typedef void (*bfa_ioc_enable_cbfn_t)(void *bfa, enum bfa_status status);
+typedef void (*bfa_ioc_disable_cbfn_t)(void *bfa);
+typedef void (*bfa_ioc_hbfail_cbfn_t)(void *bfa);
+typedef void (*bfa_ioc_reset_cbfn_t)(void *bfa);
+struct bfa_ioc_cbfn {
+ bfa_ioc_enable_cbfn_t enable_cbfn;
+ bfa_ioc_disable_cbfn_t disable_cbfn;
+ bfa_ioc_hbfail_cbfn_t hbfail_cbfn;
+ bfa_ioc_reset_cbfn_t reset_cbfn;
+};
+
+/**
+ * Heartbeat failure notification queue element.
+ */
+struct bfa_ioc_hbfail_notify {
+ struct list_head qe;
+ bfa_ioc_hbfail_cbfn_t cbfn;
+ void *cbarg;
+};
+
+/**
+ * Initialize a heartbeat failure notification structure
+ */
+#define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do { \
+ (__notify)->cbfn = (__cbfn); \
+ (__notify)->cbarg = (__cbarg); \
+} while (0)
+
+struct bfa_ioc {
+ bfa_fsm_t fsm;
+ struct bfa *bfa;
+ struct bfa_pcidev pcidev;
+ struct bfa_timer_mod *timer_mod;
+ struct timer_list ioc_timer;
+ struct timer_list sem_timer;
+ struct timer_list hb_timer;
+ u32 hb_count;
+ u32 retry_count;
+ struct list_head hb_notify_q;
+ void *dbg_fwsave;
+ int dbg_fwsave_len;
+ bool dbg_fwsave_once;
+ enum bfi_mclass ioc_mc;
+ struct bfa_ioc_regs ioc_regs;
+ struct bfa_ioc_drv_stats stats;
+ bool auto_recover;
+ bool fcmode;
+ bool ctdev;
+ bool cna;
+ bool pllinit;
+ bool stats_busy; /*!< outstanding stats */
+ u8 port_id;
+
+ struct bfa_dma attr_dma;
+ struct bfi_ioc_attr *attr;
+ struct bfa_ioc_cbfn *cbfn;
+ struct bfa_ioc_mbox_mod mbox_mod;
+ struct bfa_ioc_hwif *ioc_hwif;
+};
+
+struct bfa_ioc_hwif {
+ enum bfa_status (*ioc_pll_init) (void __iomem *rb, bool fcmode);
+ bool (*ioc_firmware_lock) (struct bfa_ioc *ioc);
+ void (*ioc_firmware_unlock) (struct bfa_ioc *ioc);
+ void (*ioc_reg_init) (struct bfa_ioc *ioc);
+ void (*ioc_map_port) (struct bfa_ioc *ioc);
+ void (*ioc_isr_mode_set) (struct bfa_ioc *ioc,
+ bool msix);
+ void (*ioc_notify_hbfail) (struct bfa_ioc *ioc);
+ void (*ioc_ownership_reset) (struct bfa_ioc *ioc);
+};
+
+#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
+#define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id)
+#define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva)
+#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
+#define bfa_ioc_fetch_stats(__ioc, __stats) \
+ (((__stats)->drv_stats) = (__ioc)->stats)
+#define bfa_ioc_clr_stats(__ioc) \
+ memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats))
+#define bfa_ioc_maxfrsize(__ioc) ((__ioc)->attr->maxfrsize)
+#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit)
+#define bfa_ioc_speed_sup(__ioc) \
+ BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
+#define bfa_ioc_get_nports(__ioc) \
+ BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
+
+#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
+#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
+#define BFA_IOC_FWIMG_TYPE(__ioc) \
+ (((__ioc)->ctdev) ? \
+ (((__ioc)->fcmode) ? BFI_IMAGE_CT_FC : BFI_IMAGE_CT_CNA) : \
+ BFI_IMAGE_CB_FC)
+#define BFA_IOC_FW_SMEM_SIZE(__ioc) \
+ (((__ioc)->ctdev) ? BFI_SMEM_CT_SIZE : BFI_SMEM_CB_SIZE)
+#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
+
+/**
+ * IOC mailbox interface
+ */
+void bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd);
+void bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc);
+void bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
+ bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg);
+
+/**
+ * IOC interfaces
+ */
+
+#define bfa_ioc_pll_init_asic(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_pll_init((__ioc)->pcidev.pci_bar_kva, \
+ (__ioc)->fcmode))
+
+#define bfa_ioc_isr_mode_set(__ioc, __msix) \
+ ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
+#define bfa_ioc_ownership_reset(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
+
+void bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc);
+
+void bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa,
+ struct bfa_ioc_cbfn *cbfn);
+void bfa_nw_ioc_auto_recover(bool auto_recover);
+void bfa_nw_ioc_detach(struct bfa_ioc *ioc);
+void bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
+ enum bfi_mclass mc);
+u32 bfa_nw_ioc_meminfo(void);
+void bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa);
+void bfa_nw_ioc_enable(struct bfa_ioc *ioc);
+void bfa_nw_ioc_disable(struct bfa_ioc *ioc);
+
+void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc);
+
+void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr);
+void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc,
+ struct bfa_ioc_hbfail_notify *notify);
+bool bfa_nw_ioc_sem_get(void __iomem *sem_reg);
+void bfa_nw_ioc_sem_release(void __iomem *sem_reg);
+void bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc);
+void bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc,
+ struct bfi_ioc_image_hdr *fwhdr);
+bool bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc,
+ struct bfi_ioc_image_hdr *fwhdr);
+mac_t bfa_nw_ioc_get_mac(struct bfa_ioc *ioc);
+
+/*
+ * Timeout APIs
+ */
+void bfa_nw_ioc_timeout(void *ioc);
+void bfa_nw_ioc_hb_check(void *ioc);
+void bfa_nw_ioc_sem_timeout(void *ioc);
+
+/*
+ * F/W Image Size & Chunk
+ */
+u32 *bfa_cb_image_get_chunk(int type, u32 off);
+u32 bfa_cb_image_get_size(int type);
+
+#endif /* __BFA_IOC_H__ */
diff --git a/drivers/net/bna/bfa_ioc_ct.c b/drivers/net/bna/bfa_ioc_ct.c
new file mode 100644
index 000000000000..121cfd6d48b1
--- /dev/null
+++ b/drivers/net/bna/bfa_ioc_ct.c
@@ -0,0 +1,392 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#include "bfa_ioc.h"
+#include "cna.h"
+#include "bfi.h"
+#include "bfi_ctreg.h"
+#include "bfa_defs.h"
+
+/*
+ * forward declarations
+ */
+static bool bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_reg_init(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_map_port(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix);
+static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc);
+static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode);
+
+static struct bfa_ioc_hwif nw_hwif_ct;
+
+/**
+ * Called from bfa_ioc_attach() to map asic specific calls.
+ */
+void
+bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc)
+{
+ nw_hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init;
+ nw_hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock;
+ nw_hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock;
+ nw_hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init;
+ nw_hwif_ct.ioc_map_port = bfa_ioc_ct_map_port;
+ nw_hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
+ nw_hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail;
+ nw_hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
+
+ ioc->ioc_hwif = &nw_hwif_ct;
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bool
+bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc)
+{
+ enum bfi_ioc_state ioc_fwstate;
+ u32 usecnt;
+ struct bfi_ioc_image_hdr fwhdr;
+
+ /**
+ * Firmware match check is relevant only for CNA.
+ */
+ if (!ioc->cna)
+ return true;
+
+ /**
+ * If bios boot (flash based) -- do not increment usage count
+ */
+ if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) <
+ BFA_IOC_FWIMG_MINSZ)
+ return true;
+
+ bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
+
+ /**
+ * If usage count is 0, always return TRUE.
+ */
+ if (usecnt == 0) {
+ writel(1, ioc->ioc_regs.ioc_usage_reg);
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ return true;
+ }
+
+ ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+ /**
+ * Use count cannot be non-zero and chip in uninitialized state.
+ */
+ BUG_ON(!(ioc_fwstate != BFI_IOC_UNINIT));
+
+ /**
+ * Check if another driver with a different firmware is active
+ */
+ bfa_nw_ioc_fwver_get(ioc, &fwhdr);
+ if (!bfa_nw_ioc_fwver_cmp(ioc, &fwhdr)) {
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ return false;
+ }
+
+ /**
+ * Same firmware version. Increment the reference count.
+ */
+ usecnt++;
+ writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ return true;
+}
+
+static void
+bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc)
+{
+ u32 usecnt;
+
+ /**
+ * Firmware lock is relevant only for CNA.
+ */
+ if (!ioc->cna)
+ return;
+
+ /**
+ * If bios boot (flash based) -- do not decrement usage count
+ */
+ if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) <
+ BFA_IOC_FWIMG_MINSZ)
+ return;
+
+ /**
+ * decrement usage count
+ */
+ bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
+ BUG_ON(!(usecnt > 0));
+
+ usecnt--;
+ writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
+
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+}
+
+/**
+ * Notify other functions on HB failure.
+ */
+static void
+bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc)
+{
+ if (ioc->cna) {
+ writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
+ /* Wait for halt to take effect */
+ readl(ioc->ioc_regs.ll_halt);
+ } else {
+ writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
+ readl(ioc->ioc_regs.err_set);
+ }
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+ { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
+ { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
+ { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
+ { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 0
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
+ { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
+ { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
+ { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
+ { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 1
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
+ { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
+ { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
+ { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
+ { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+static void
+bfa_ioc_ct_reg_init(struct bfa_ioc *ioc)
+{
+ void __iomem *rb;
+ int pcifn = bfa_ioc_pcifn(ioc);
+
+ rb = bfa_ioc_bar0(ioc);
+
+ ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+ ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+ ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+ if (ioc->port_id == 0) {
+ ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+ ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
+ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
+ ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
+ } else {
+ ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+ ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
+ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
+ ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
+ }
+
+ /*
+ * PSS control registers
+ */
+ ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+ ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
+ ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
+ ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
+
+ /*
+ * IOC semaphore registers and serialization
+ */
+ ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+ ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
+ ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
+ ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
+
+ /**
+ * sram memory access
+ */
+ ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+ ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
+
+ /*
+ * err set reg : for notification of hb failure in fcmode
+ */
+ ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+
+#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
+static void
+bfa_ioc_ct_map_port(struct bfa_ioc *ioc)
+{
+ void __iomem *rb = ioc->pcidev.pci_bar_kva;
+ u32 r32;
+
+ /**
+ * For catapult, base port id on personality register and IOC type
+ */
+ r32 = readl(rb + FNC_PERS_REG);
+ r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
+ ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
+
+}
+
+/**
+ * Set interrupt mode for a function: INTX or MSIX
+ */
+static void
+bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix)
+{
+ void __iomem *rb = ioc->pcidev.pci_bar_kva;
+ u32 r32, mode;
+
+ r32 = readl(rb + FNC_PERS_REG);
+
+ mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
+ __F0_INTX_STATUS;
+
+ /**
+ * If already in desired mode, do not change anything
+ */
+ if (!msix && mode)
+ return;
+
+ if (msix)
+ mode = __F0_INTX_STATUS_MSIX;
+ else
+ mode = __F0_INTX_STATUS_INTA;
+
+ r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+ r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+
+ writel(r32, rb + FNC_PERS_REG);
+}
+
+/**
+ * Cleanup hw semaphore and usecnt registers
+ */
+static void
+bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc)
+{
+ if (ioc->cna) {
+ bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(0, ioc->ioc_regs.ioc_usage_reg);
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ }
+
+ /*
+ * Read the hw sem reg to make sure that it is locked
+ * before we clear it. If it is not locked, writing 1
+ * will lock it instead of clearing it.
+ */
+ readl(ioc->ioc_regs.ioc_sem_reg);
+ bfa_nw_ioc_hw_sem_release(ioc);
+}
+
+static enum bfa_status
+bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode)
+{
+ u32 pll_sclk, pll_fclk, r32;
+
+ pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
+ __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
+ __APP_PLL_312_JITLMT0_1(3U) |
+ __APP_PLL_312_CNTLMT0_1(1U);
+ pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
+ __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
+ __APP_PLL_425_JITLMT0_1(3U) |
+ __APP_PLL_425_CNTLMT0_1(1U);
+ if (fcmode) {
+ writel(0, (rb + OP_MODE));
+ writel(__APP_EMS_CMLCKSEL |
+ __APP_EMS_REFCKBUFEN2 |
+ __APP_EMS_CHANNEL_SEL,
+ (rb + ETH_MAC_SER_REG));
+ } else {
+ writel(__GLOBAL_FCOE_MODE, (rb + OP_MODE));
+ writel(__APP_EMS_REFCKBUFEN1,
+ (rb + ETH_MAC_SER_REG));
+ }
+ writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG));
+ writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG));
+ writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
+ writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
+ writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
+ writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
+ writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
+ writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
+ writel(pll_sclk |
+ __APP_PLL_312_LOGIC_SOFT_RESET,
+ rb + APP_PLL_312_CTL_REG);
+ writel(pll_fclk |
+ __APP_PLL_425_LOGIC_SOFT_RESET,
+ rb + APP_PLL_425_CTL_REG);
+ writel(pll_sclk |
+ __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE,
+ rb + APP_PLL_312_CTL_REG);
+ writel(pll_fclk |
+ __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE,
+ rb + APP_PLL_425_CTL_REG);
+ readl(rb + HOSTFN0_INT_MSK);
+ udelay(2000);
+ writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
+ writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
+ writel(pll_sclk |
+ __APP_PLL_312_ENABLE,
+ rb + APP_PLL_312_CTL_REG);
+ writel(pll_fclk |
+ __APP_PLL_425_ENABLE,
+ rb + APP_PLL_425_CTL_REG);
+ if (!fcmode) {
+ writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0));
+ writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1));
+ }
+ r32 = readl((rb + PSS_CTL_REG));
+ r32 &= ~__PSS_LMEM_RESET;
+ writel(r32, (rb + PSS_CTL_REG));
+ udelay(1000);
+ if (!fcmode) {
+ writel(0, (rb + PMM_1T_RESET_REG_P0));
+ writel(0, (rb + PMM_1T_RESET_REG_P1));
+ }
+
+ writel(__EDRAM_BISTR_START, (rb + MBIST_CTL_REG));
+ udelay(1000);
+ r32 = readl((rb + MBIST_STAT_REG));
+ writel(0, (rb + MBIST_CTL_REG));
+ return BFA_STATUS_OK;
+}
diff --git a/drivers/net/bna/bfa_sm.h b/drivers/net/bna/bfa_sm.h
new file mode 100644
index 000000000000..46462c49b6f9
--- /dev/null
+++ b/drivers/net/bna/bfa_sm.h
@@ -0,0 +1,88 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+/**
+ * @file bfasm.h State machine defines
+ */
+
+#ifndef __BFA_SM_H__
+#define __BFA_SM_H__
+
+#include "cna.h"
+
+typedef void (*bfa_sm_t)(void *sm, int event);
+
+/**
+ * oc - object class eg. bfa_ioc
+ * st - state, eg. reset
+ * otype - object type, eg. struct bfa_ioc
+ * etype - object type, eg. enum ioc_event
+ */
+#define bfa_sm_state_decl(oc, st, otype, etype) \
+ static void oc ## _sm_ ## st(otype * fsm, etype event)
+
+#define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state))
+#define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event)))
+#define bfa_sm_get_state(_sm) ((_sm)->sm)
+#define bfa_sm_cmp_state(_sm, _state) ((_sm)->sm == (bfa_sm_t)(_state))
+
+/**
+ * For converting from state machine function to state encoding.
+ */
+struct bfa_sm_table {
+ bfa_sm_t sm; /*!< state machine function */
+ int state; /*!< state machine encoding */
+ char *name; /*!< state name for display */
+};
+#define BFA_SM(_sm) ((bfa_sm_t)(_sm))
+
+/**
+ * State machine with entry actions.
+ */
+typedef void (*bfa_fsm_t)(void *fsm, int event);
+
+/**
+ * oc - object class eg. bfa_ioc
+ * st - state, eg. reset
+ * otype - object type, eg. struct bfa_ioc
+ * etype - object type, eg. enum ioc_event
+ */
+#define bfa_fsm_state_decl(oc, st, otype, etype) \
+ static void oc ## _sm_ ## st(otype * fsm, etype event); \
+ static void oc ## _sm_ ## st ## _entry(otype * fsm)
+
+#define bfa_fsm_set_state(_fsm, _state) do { \
+ (_fsm)->fsm = (bfa_fsm_t)(_state); \
+ _state ## _entry(_fsm); \
+} while (0)
+
+#define bfa_fsm_send_event(_fsm, _event) ((_fsm)->fsm((_fsm), (_event)))
+#define bfa_fsm_get_state(_fsm) ((_fsm)->fsm)
+#define bfa_fsm_cmp_state(_fsm, _state) \
+ ((_fsm)->fsm == (bfa_fsm_t)(_state))
+
+static inline int
+bfa_sm_to_state(const struct bfa_sm_table *smt, bfa_sm_t sm)
+{
+ int i = 0;
+
+ while (smt[i].sm && smt[i].sm != sm)
+ i++;
+ return smt[i].state;
+}
+#endif
diff --git a/drivers/net/bna/bfa_wc.h b/drivers/net/bna/bfa_wc.h
new file mode 100644
index 000000000000..d0e4caee67b0
--- /dev/null
+++ b/drivers/net/bna/bfa_wc.h
@@ -0,0 +1,69 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+/**
+ * @file bfa_wc.h Generic wait counter.
+ */
+
+#ifndef __BFA_WC_H__
+#define __BFA_WC_H__
+
+typedef void (*bfa_wc_resume_t) (void *cbarg);
+
+struct bfa_wc {
+ bfa_wc_resume_t wc_resume;
+ void *wc_cbarg;
+ int wc_count;
+};
+
+static inline void
+bfa_wc_up(struct bfa_wc *wc)
+{
+ wc->wc_count++;
+}
+
+static inline void
+bfa_wc_down(struct bfa_wc *wc)
+{
+ wc->wc_count--;
+ if (wc->wc_count == 0)
+ wc->wc_resume(wc->wc_cbarg);
+}
+
+/**
+ * Initialize a waiting counter.
+ */
+static inline void
+bfa_wc_init(struct bfa_wc *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg)
+{
+ wc->wc_resume = wc_resume;
+ wc->wc_cbarg = wc_cbarg;
+ wc->wc_count = 0;
+ bfa_wc_up(wc);
+}
+
+/**
+ * Wait for counter to reach zero
+ */
+static inline void
+bfa_wc_wait(struct bfa_wc *wc)
+{
+ bfa_wc_down(wc);
+}
+
+#endif
diff --git a/drivers/net/bna/bfi.h b/drivers/net/bna/bfi.h
new file mode 100644
index 000000000000..a97396811050
--- /dev/null
+++ b/drivers/net/bna/bfi.h
@@ -0,0 +1,392 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFI_H__
+#define __BFI_H__
+
+#include "bfa_defs.h"
+
+#pragma pack(1)
+
+/**
+ * BFI FW image type
+ */
+#define BFI_FLASH_CHUNK_SZ 256 /*!< Flash chunk size */
+#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32))
+enum {
+ BFI_IMAGE_CB_FC,
+ BFI_IMAGE_CT_FC,
+ BFI_IMAGE_CT_CNA,
+ BFI_IMAGE_MAX,
+};
+
+/**
+ * Msg header common to all msgs
+ */
+struct bfi_mhdr {
+ u8 msg_class; /*!< @ref enum bfi_mclass */
+ u8 msg_id; /*!< msg opcode with in the class */
+ union {
+ struct {
+ u8 rsvd;
+ u8 lpu_id; /*!< msg destination */
+ } h2i;
+ u16 i2htok; /*!< token in msgs to host */
+ } mtag;
+};
+
+#define bfi_h2i_set(_mh, _mc, _op, _lpuid) do { \
+ (_mh).msg_class = (_mc); \
+ (_mh).msg_id = (_op); \
+ (_mh).mtag.h2i.lpu_id = (_lpuid); \
+} while (0)
+
+#define bfi_i2h_set(_mh, _mc, _op, _i2htok) do { \
+ (_mh).msg_class = (_mc); \
+ (_mh).msg_id = (_op); \
+ (_mh).mtag.i2htok = (_i2htok); \
+} while (0)
+
+/*
+ * Message opcodes: 0-127 to firmware, 128-255 to host
+ */
+#define BFI_I2H_OPCODE_BASE 128
+#define BFA_I2HM(_x) ((_x) + BFI_I2H_OPCODE_BASE)
+
+/**
+ ****************************************************************************
+ *
+ * Scatter Gather Element and Page definition
+ *
+ ****************************************************************************
+ */
+
+#define BFI_SGE_INLINE 1
+#define BFI_SGE_INLINE_MAX (BFI_SGE_INLINE + 1)
+
+/**
+ * SG Flags
+ */
+enum {
+ BFI_SGE_DATA = 0, /*!< data address, not last */
+ BFI_SGE_DATA_CPL = 1, /*!< data addr, last in current page */
+ BFI_SGE_DATA_LAST = 3, /*!< data address, last */
+ BFI_SGE_LINK = 2, /*!< link address */
+ BFI_SGE_PGDLEN = 2, /*!< cumulative data length for page */
+};
+
+/**
+ * DMA addresses
+ */
+union bfi_addr_u {
+ struct {
+ u32 addr_lo;
+ u32 addr_hi;
+ } a32;
+};
+
+/**
+ * Scatter Gather Element
+ */
+struct bfi_sge {
+#ifdef __BIGENDIAN
+ u32 flags:2,
+ rsvd:2,
+ sg_len:28;
+#else
+ u32 sg_len:28,
+ rsvd:2,
+ flags:2;
+#endif
+ union bfi_addr_u sga;
+};
+
+/**
+ * Scatter Gather Page
+ */
+#define BFI_SGPG_DATA_SGES 7
+#define BFI_SGPG_SGES_MAX (BFI_SGPG_DATA_SGES + 1)
+#define BFI_SGPG_RSVD_WD_LEN 8
+struct bfi_sgpg {
+ struct bfi_sge sges[BFI_SGPG_SGES_MAX];
+ u32 rsvd[BFI_SGPG_RSVD_WD_LEN];
+};
+
+/*
+ * Large Message structure - 128 Bytes size Msgs
+ */
+#define BFI_LMSG_SZ 128
+#define BFI_LMSG_PL_WSZ \
+ ((BFI_LMSG_SZ - sizeof(struct bfi_mhdr)) / 4)
+
+struct bfi_msg {
+ struct bfi_mhdr mhdr;
+ u32 pl[BFI_LMSG_PL_WSZ];
+};
+
+/**
+ * Mailbox message structure
+ */
+#define BFI_MBMSG_SZ 7
+struct bfi_mbmsg {
+ struct bfi_mhdr mh;
+ u32 pl[BFI_MBMSG_SZ];
+};
+
+/**
+ * Message Classes
+ */
+enum bfi_mclass {
+ BFI_MC_IOC = 1, /*!< IO Controller (IOC) */
+ BFI_MC_DIAG = 2, /*!< Diagnostic Msgs */
+ BFI_MC_FLASH = 3, /*!< Flash message class */
+ BFI_MC_CEE = 4, /*!< CEE */
+ BFI_MC_FCPORT = 5, /*!< FC port */
+ BFI_MC_IOCFC = 6, /*!< FC - IO Controller (IOC) */
+ BFI_MC_LL = 7, /*!< Link Layer */
+ BFI_MC_UF = 8, /*!< Unsolicited frame receive */
+ BFI_MC_FCXP = 9, /*!< FC Transport */
+ BFI_MC_LPS = 10, /*!< lport fc login services */
+ BFI_MC_RPORT = 11, /*!< Remote port */
+ BFI_MC_ITNIM = 12, /*!< I-T nexus (Initiator mode) */
+ BFI_MC_IOIM_READ = 13, /*!< read IO (Initiator mode) */
+ BFI_MC_IOIM_WRITE = 14, /*!< write IO (Initiator mode) */
+ BFI_MC_IOIM_IO = 15, /*!< IO (Initiator mode) */
+ BFI_MC_IOIM = 16, /*!< IO (Initiator mode) */
+ BFI_MC_IOIM_IOCOM = 17, /*!< good IO completion */
+ BFI_MC_TSKIM = 18, /*!< Initiator Task management */
+ BFI_MC_SBOOT = 19, /*!< SAN boot services */
+ BFI_MC_IPFC = 20, /*!< IP over FC Msgs */
+ BFI_MC_PORT = 21, /*!< Physical port */
+ BFI_MC_SFP = 22, /*!< SFP module */
+ BFI_MC_MSGQ = 23, /*!< MSGQ */
+ BFI_MC_ENET = 24, /*!< ENET commands/responses */
+ BFI_MC_MAX = 32
+};
+
+#define BFI_IOC_MAX_CQS 4
+#define BFI_IOC_MAX_CQS_ASIC 8
+#define BFI_IOC_MSGLEN_MAX 32 /* 32 bytes */
+
+#define BFI_BOOT_TYPE_OFF 8
+#define BFI_BOOT_PARAM_OFF 12
+
+#define BFI_BOOT_TYPE_NORMAL 0 /* param is device id */
+#define BFI_BOOT_TYPE_FLASH 1
+#define BFI_BOOT_TYPE_MEMTEST 2
+
+#define BFI_BOOT_MEMTEST_RES_ADDR 0x900
+#define BFI_BOOT_MEMTEST_RES_SIG 0xA0A1A2A3
+
+/**
+ *----------------------------------------------------------------------
+ * IOC
+ *----------------------------------------------------------------------
+ */
+
+enum bfi_ioc_h2i_msgs {
+ BFI_IOC_H2I_ENABLE_REQ = 1,
+ BFI_IOC_H2I_DISABLE_REQ = 2,
+ BFI_IOC_H2I_GETATTR_REQ = 3,
+ BFI_IOC_H2I_DBG_SYNC = 4,
+ BFI_IOC_H2I_DBG_DUMP = 5,
+};
+
+enum bfi_ioc_i2h_msgs {
+ BFI_IOC_I2H_ENABLE_REPLY = BFA_I2HM(1),
+ BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2),
+ BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3),
+ BFI_IOC_I2H_READY_EVENT = BFA_I2HM(4),
+ BFI_IOC_I2H_HBEAT = BFA_I2HM(5),
+};
+
+/**
+ * BFI_IOC_H2I_GETATTR_REQ message
+ */
+struct bfi_ioc_getattr_req {
+ struct bfi_mhdr mh;
+ union bfi_addr_u attr_addr;
+};
+
+struct bfi_ioc_attr {
+ u64 mfg_pwwn; /*!< Mfg port wwn */
+ u64 mfg_nwwn; /*!< Mfg node wwn */
+ mac_t mfg_mac; /*!< Mfg mac */
+ u16 rsvd_a;
+ u64 pwwn;
+ u64 nwwn;
+ mac_t mac; /*!< PBC or Mfg mac */
+ u16 rsvd_b;
+ mac_t fcoe_mac;
+ u16 rsvd_c;
+ char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)];
+ u8 pcie_gen;
+ u8 pcie_lanes_orig;
+ u8 pcie_lanes;
+ u8 rx_bbcredit; /*!< receive buffer credits */
+ u32 adapter_prop; /*!< adapter properties */
+ u16 maxfrsize; /*!< max receive frame size */
+ char asic_rev;
+ u8 rsvd_d;
+ char fw_version[BFA_VERSION_LEN];
+ char optrom_version[BFA_VERSION_LEN];
+ struct bfa_mfg_vpd vpd;
+ u32 card_type; /*!< card type */
+};
+
+/**
+ * BFI_IOC_I2H_GETATTR_REPLY message
+ */
+struct bfi_ioc_getattr_reply {
+ struct bfi_mhdr mh; /*!< Common msg header */
+ u8 status; /*!< cfg reply status */
+ u8 rsvd[3];
+};
+
+/**
+ * Firmware memory page offsets
+ */
+#define BFI_IOC_SMEM_PG0_CB (0x40)
+#define BFI_IOC_SMEM_PG0_CT (0x180)
+
+/**
+ * Firmware statistic offset
+ */
+#define BFI_IOC_FWSTATS_OFF (0x6B40)
+#define BFI_IOC_FWSTATS_SZ (4096)
+
+/**
+ * Firmware trace offset
+ */
+#define BFI_IOC_TRC_OFF (0x4b00)
+#define BFI_IOC_TRC_ENTS 256
+
+#define BFI_IOC_FW_SIGNATURE (0xbfadbfad)
+#define BFI_IOC_MD5SUM_SZ 4
+struct bfi_ioc_image_hdr {
+ u32 signature; /*!< constant signature */
+ u32 rsvd_a;
+ u32 exec; /*!< exec vector */
+ u32 param; /*!< parameters */
+ u32 rsvd_b[4];
+ u32 md5sum[BFI_IOC_MD5SUM_SZ];
+};
+
+/**
+ * BFI_IOC_I2H_READY_EVENT message
+ */
+struct bfi_ioc_rdy_event {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 init_status; /*!< init event status */
+ u8 rsvd[3];
+};
+
+struct bfi_ioc_hbeat {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u32 hb_count; /*!< current heart beat count */
+};
+
+/**
+ * IOC hardware/firmware state
+ */
+enum bfi_ioc_state {
+ BFI_IOC_UNINIT = 0, /*!< not initialized */
+ BFI_IOC_INITING = 1, /*!< h/w is being initialized */
+ BFI_IOC_HWINIT = 2, /*!< h/w is initialized */
+ BFI_IOC_CFG = 3, /*!< IOC configuration in progress */
+ BFI_IOC_OP = 4, /*!< IOC is operational */
+ BFI_IOC_DISABLING = 5, /*!< IOC is being disabled */
+ BFI_IOC_DISABLED = 6, /*!< IOC is disabled */
+ BFI_IOC_CFG_DISABLED = 7, /*!< IOC is being disabled;transient */
+ BFI_IOC_FAIL = 8, /*!< IOC heart-beat failure */
+ BFI_IOC_MEMTEST = 9, /*!< IOC is doing memtest */
+};
+
+#define BFI_IOC_ENDIAN_SIG 0x12345678
+
+enum {
+ BFI_ADAPTER_TYPE_FC = 0x01, /*!< FC adapters */
+ BFI_ADAPTER_TYPE_MK = 0x0f0000, /*!< adapter type mask */
+ BFI_ADAPTER_TYPE_SH = 16, /*!< adapter type shift */
+ BFI_ADAPTER_NPORTS_MK = 0xff00, /*!< number of ports mask */
+ BFI_ADAPTER_NPORTS_SH = 8, /*!< number of ports shift */
+ BFI_ADAPTER_SPEED_MK = 0xff, /*!< adapter speed mask */
+ BFI_ADAPTER_SPEED_SH = 0, /*!< adapter speed shift */
+ BFI_ADAPTER_PROTO = 0x100000, /*!< prototype adapaters */
+ BFI_ADAPTER_TTV = 0x200000, /*!< TTV debug capable */
+ BFI_ADAPTER_UNSUPP = 0x400000, /*!< unknown adapter type */
+};
+
+#define BFI_ADAPTER_GETP(__prop, __adap_prop) \
+ (((__adap_prop) & BFI_ADAPTER_ ## __prop ## _MK) >> \
+ BFI_ADAPTER_ ## __prop ## _SH)
+#define BFI_ADAPTER_SETP(__prop, __val) \
+ ((__val) << BFI_ADAPTER_ ## __prop ## _SH)
+#define BFI_ADAPTER_IS_PROTO(__adap_type) \
+ ((__adap_type) & BFI_ADAPTER_PROTO)
+#define BFI_ADAPTER_IS_TTV(__adap_type) \
+ ((__adap_type) & BFI_ADAPTER_TTV)
+#define BFI_ADAPTER_IS_UNSUPP(__adap_type) \
+ ((__adap_type) & BFI_ADAPTER_UNSUPP)
+#define BFI_ADAPTER_IS_SPECIAL(__adap_type) \
+ ((__adap_type) & (BFI_ADAPTER_TTV | BFI_ADAPTER_PROTO | \
+ BFI_ADAPTER_UNSUPP))
+
+/**
+ * BFI_IOC_H2I_ENABLE_REQ & BFI_IOC_H2I_DISABLE_REQ messages
+ */
+struct bfi_ioc_ctrl_req {
+ struct bfi_mhdr mh;
+ u8 ioc_class;
+ u8 rsvd[3];
+ u32 tv_sec;
+};
+
+/**
+ * BFI_IOC_I2H_ENABLE_REPLY & BFI_IOC_I2H_DISABLE_REPLY messages
+ */
+struct bfi_ioc_ctrl_reply {
+ struct bfi_mhdr mh; /*!< Common msg header */
+ u8 status; /*!< enable/disable status */
+ u8 rsvd[3];
+};
+
+#define BFI_IOC_MSGSZ 8
+/**
+ * H2I Messages
+ */
+union bfi_ioc_h2i_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_ioc_ctrl_req enable_req;
+ struct bfi_ioc_ctrl_req disable_req;
+ struct bfi_ioc_getattr_req getattr_req;
+ u32 mboxmsg[BFI_IOC_MSGSZ];
+};
+
+/**
+ * I2H Messages
+ */
+union bfi_ioc_i2h_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_ioc_rdy_event rdy_event;
+ u32 mboxmsg[BFI_IOC_MSGSZ];
+};
+
+#pragma pack()
+
+#endif /* __BFI_H__ */
diff --git a/drivers/net/bna/bfi_cna.h b/drivers/net/bna/bfi_cna.h
new file mode 100644
index 000000000000..4eecabea397b
--- /dev/null
+++ b/drivers/net/bna/bfi_cna.h
@@ -0,0 +1,199 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BFI_CNA_H__
+#define __BFI_CNA_H__
+
+#include "bfi.h"
+#include "bfa_defs_cna.h"
+
+#pragma pack(1)
+
+enum bfi_port_h2i {
+ BFI_PORT_H2I_ENABLE_REQ = (1),
+ BFI_PORT_H2I_DISABLE_REQ = (2),
+ BFI_PORT_H2I_GET_STATS_REQ = (3),
+ BFI_PORT_H2I_CLEAR_STATS_REQ = (4),
+};
+
+enum bfi_port_i2h {
+ BFI_PORT_I2H_ENABLE_RSP = BFA_I2HM(1),
+ BFI_PORT_I2H_DISABLE_RSP = BFA_I2HM(2),
+ BFI_PORT_I2H_GET_STATS_RSP = BFA_I2HM(3),
+ BFI_PORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4),
+};
+
+/**
+ * Generic REQ type
+ */
+struct bfi_port_generic_req {
+ struct bfi_mhdr mh; /*!< msg header */
+ u32 msgtag; /*!< msgtag for reply */
+ u32 rsvd;
+};
+
+/**
+ * Generic RSP type
+ */
+struct bfi_port_generic_rsp {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 status; /*!< port enable status */
+ u8 rsvd[3];
+ u32 msgtag; /*!< msgtag for reply */
+};
+
+/**
+ * @todo
+ * BFI_PORT_H2I_ENABLE_REQ
+ */
+
+/**
+ * @todo
+ * BFI_PORT_I2H_ENABLE_RSP
+ */
+
+/**
+ * BFI_PORT_H2I_DISABLE_REQ
+ */
+
+/**
+ * BFI_PORT_I2H_DISABLE_RSP
+ */
+
+/**
+ * BFI_PORT_H2I_GET_STATS_REQ
+ */
+struct bfi_port_get_stats_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ union bfi_addr_u dma_addr;
+};
+
+/**
+ * BFI_PORT_I2H_GET_STATS_RSP
+ */
+
+/**
+ * BFI_PORT_H2I_CLEAR_STATS_REQ
+ */
+
+/**
+ * BFI_PORT_I2H_CLEAR_STATS_RSP
+ */
+
+union bfi_port_h2i_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_port_generic_req enable_req;
+ struct bfi_port_generic_req disable_req;
+ struct bfi_port_get_stats_req getstats_req;
+ struct bfi_port_generic_req clearstats_req;
+};
+
+union bfi_port_i2h_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_port_generic_rsp enable_rsp;
+ struct bfi_port_generic_rsp disable_rsp;
+ struct bfi_port_generic_rsp getstats_rsp;
+ struct bfi_port_generic_rsp clearstats_rsp;
+};
+
+/* @brief Mailbox commands from host to (DCBX/LLDP) firmware */
+enum bfi_cee_h2i_msgs {
+ BFI_CEE_H2I_GET_CFG_REQ = 1,
+ BFI_CEE_H2I_RESET_STATS = 2,
+ BFI_CEE_H2I_GET_STATS_REQ = 3,
+};
+
+/* @brief Mailbox reply and AEN messages from DCBX/LLDP firmware to host */
+enum bfi_cee_i2h_msgs {
+ BFI_CEE_I2H_GET_CFG_RSP = BFA_I2HM(1),
+ BFI_CEE_I2H_RESET_STATS_RSP = BFA_I2HM(2),
+ BFI_CEE_I2H_GET_STATS_RSP = BFA_I2HM(3),
+};
+
+/* Data structures */
+
+/*
+ * @brief H2I command structure for resetting the stats.
+ * BFI_CEE_H2I_RESET_STATS
+ */
+struct bfi_lldp_reset_stats {
+ struct bfi_mhdr mh;
+};
+
+/*
+ * @brief H2I command structure for resetting the stats.
+ * BFI_CEE_H2I_RESET_STATS
+ */
+struct bfi_cee_reset_stats {
+ struct bfi_mhdr mh;
+};
+
+/*
+ * @brief get configuration command from host
+ * BFI_CEE_H2I_GET_CFG_REQ
+ */
+struct bfi_cee_get_req {
+ struct bfi_mhdr mh;
+ union bfi_addr_u dma_addr;
+};
+
+/*
+ * @brief reply message from firmware
+ * BFI_CEE_I2H_GET_CFG_RSP
+ */
+struct bfi_cee_get_rsp {
+ struct bfi_mhdr mh;
+ u8 cmd_status;
+ u8 rsvd[3];
+};
+
+/*
+ * @brief get configuration command from host
+ * BFI_CEE_H2I_GET_STATS_REQ
+ */
+struct bfi_cee_stats_req {
+ struct bfi_mhdr mh;
+ union bfi_addr_u dma_addr;
+};
+
+/*
+ * @brief reply message from firmware
+ * BFI_CEE_I2H_GET_STATS_RSP
+ */
+struct bfi_cee_stats_rsp {
+ struct bfi_mhdr mh;
+ u8 cmd_status;
+ u8 rsvd[3];
+};
+
+/* @brief mailbox command structures from host to firmware */
+union bfi_cee_h2i_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_cee_get_req get_req;
+ struct bfi_cee_stats_req stats_req;
+};
+
+/* @brief mailbox message structures from firmware to host */
+union bfi_cee_i2h_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_cee_get_rsp get_rsp;
+ struct bfi_cee_stats_rsp stats_rsp;
+};
+
+#pragma pack()
+
+#endif /* __BFI_CNA_H__ */
diff --git a/drivers/net/bna/bfi_ctreg.h b/drivers/net/bna/bfi_ctreg.h
new file mode 100644
index 000000000000..404ea351d4a1
--- /dev/null
+++ b/drivers/net/bna/bfi_ctreg.h
@@ -0,0 +1,637 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+/*
+ * bfi_ctreg.h catapult host block register definitions
+ *
+ * !!! Do not edit. Auto generated. !!!
+ */
+
+#ifndef __BFI_CTREG_H__
+#define __BFI_CTREG_H__
+
+#define HOSTFN0_LPU_MBOX0_0 0x00019200
+#define HOSTFN1_LPU_MBOX0_8 0x00019260
+#define LPU_HOSTFN0_MBOX0_0 0x00019280
+#define LPU_HOSTFN1_MBOX0_8 0x000192e0
+#define HOSTFN2_LPU_MBOX0_0 0x00019400
+#define HOSTFN3_LPU_MBOX0_8 0x00019460
+#define LPU_HOSTFN2_MBOX0_0 0x00019480
+#define LPU_HOSTFN3_MBOX0_8 0x000194e0
+#define HOSTFN0_INT_STATUS 0x00014000
+#define __HOSTFN0_HALT_OCCURRED 0x01000000
+#define __HOSTFN0_INT_STATUS_LVL_MK 0x00f00000
+#define __HOSTFN0_INT_STATUS_LVL_SH 20
+#define __HOSTFN0_INT_STATUS_LVL(_v) ((_v) << __HOSTFN0_INT_STATUS_LVL_SH)
+#define __HOSTFN0_INT_STATUS_P_MK 0x000f0000
+#define __HOSTFN0_INT_STATUS_P_SH 16
+#define __HOSTFN0_INT_STATUS_P(_v) ((_v) << __HOSTFN0_INT_STATUS_P_SH)
+#define __HOSTFN0_INT_STATUS_F 0x0000ffff
+#define HOSTFN0_INT_MSK 0x00014004
+#define HOST_PAGE_NUM_FN0 0x00014008
+#define __HOST_PAGE_NUM_FN 0x000001ff
+#define HOST_MSIX_ERR_INDEX_FN0 0x0001400c
+#define __MSIX_ERR_INDEX_FN 0x000001ff
+#define HOSTFN1_INT_STATUS 0x00014100
+#define __HOSTFN1_HALT_OCCURRED 0x01000000
+#define __HOSTFN1_INT_STATUS_LVL_MK 0x00f00000
+#define __HOSTFN1_INT_STATUS_LVL_SH 20
+#define __HOSTFN1_INT_STATUS_LVL(_v) ((_v) << __HOSTFN1_INT_STATUS_LVL_SH)
+#define __HOSTFN1_INT_STATUS_P_MK 0x000f0000
+#define __HOSTFN1_INT_STATUS_P_SH 16
+#define __HOSTFN1_INT_STATUS_P(_v) ((_v) << __HOSTFN1_INT_STATUS_P_SH)
+#define __HOSTFN1_INT_STATUS_F 0x0000ffff
+#define HOSTFN1_INT_MSK 0x00014104
+#define HOST_PAGE_NUM_FN1 0x00014108
+#define HOST_MSIX_ERR_INDEX_FN1 0x0001410c
+#define APP_PLL_425_CTL_REG 0x00014204
+#define __P_425_PLL_LOCK 0x80000000
+#define __APP_PLL_425_SRAM_USE_100MHZ 0x00100000
+#define __APP_PLL_425_RESET_TIMER_MK 0x000e0000
+#define __APP_PLL_425_RESET_TIMER_SH 17
+#define __APP_PLL_425_RESET_TIMER(_v) ((_v) << __APP_PLL_425_RESET_TIMER_SH)
+#define __APP_PLL_425_LOGIC_SOFT_RESET 0x00010000
+#define __APP_PLL_425_CNTLMT0_1_MK 0x0000c000
+#define __APP_PLL_425_CNTLMT0_1_SH 14
+#define __APP_PLL_425_CNTLMT0_1(_v) ((_v) << __APP_PLL_425_CNTLMT0_1_SH)
+#define __APP_PLL_425_JITLMT0_1_MK 0x00003000
+#define __APP_PLL_425_JITLMT0_1_SH 12
+#define __APP_PLL_425_JITLMT0_1(_v) ((_v) << __APP_PLL_425_JITLMT0_1_SH)
+#define __APP_PLL_425_HREF 0x00000800
+#define __APP_PLL_425_HDIV 0x00000400
+#define __APP_PLL_425_P0_1_MK 0x00000300
+#define __APP_PLL_425_P0_1_SH 8
+#define __APP_PLL_425_P0_1(_v) ((_v) << __APP_PLL_425_P0_1_SH)
+#define __APP_PLL_425_Z0_2_MK 0x000000e0
+#define __APP_PLL_425_Z0_2_SH 5
+#define __APP_PLL_425_Z0_2(_v) ((_v) << __APP_PLL_425_Z0_2_SH)
+#define __APP_PLL_425_RSEL200500 0x00000010
+#define __APP_PLL_425_ENARST 0x00000008
+#define __APP_PLL_425_BYPASS 0x00000004
+#define __APP_PLL_425_LRESETN 0x00000002
+#define __APP_PLL_425_ENABLE 0x00000001
+#define APP_PLL_312_CTL_REG 0x00014208
+#define __P_312_PLL_LOCK 0x80000000
+#define __ENABLE_MAC_AHB_1 0x00800000
+#define __ENABLE_MAC_AHB_0 0x00400000
+#define __ENABLE_MAC_1 0x00200000
+#define __ENABLE_MAC_0 0x00100000
+#define __APP_PLL_312_RESET_TIMER_MK 0x000e0000
+#define __APP_PLL_312_RESET_TIMER_SH 17
+#define __APP_PLL_312_RESET_TIMER(_v) ((_v) << __APP_PLL_312_RESET_TIMER_SH)
+#define __APP_PLL_312_LOGIC_SOFT_RESET 0x00010000
+#define __APP_PLL_312_CNTLMT0_1_MK 0x0000c000
+#define __APP_PLL_312_CNTLMT0_1_SH 14
+#define __APP_PLL_312_CNTLMT0_1(_v) ((_v) << __APP_PLL_312_CNTLMT0_1_SH)
+#define __APP_PLL_312_JITLMT0_1_MK 0x00003000
+#define __APP_PLL_312_JITLMT0_1_SH 12
+#define __APP_PLL_312_JITLMT0_1(_v) ((_v) << __APP_PLL_312_JITLMT0_1_SH)
+#define __APP_PLL_312_HREF 0x00000800
+#define __APP_PLL_312_HDIV 0x00000400
+#define __APP_PLL_312_P0_1_MK 0x00000300
+#define __APP_PLL_312_P0_1_SH 8
+#define __APP_PLL_312_P0_1(_v) ((_v) << __APP_PLL_312_P0_1_SH)
+#define __APP_PLL_312_Z0_2_MK 0x000000e0
+#define __APP_PLL_312_Z0_2_SH 5
+#define __APP_PLL_312_Z0_2(_v) ((_v) << __APP_PLL_312_Z0_2_SH)
+#define __APP_PLL_312_RSEL200500 0x00000010
+#define __APP_PLL_312_ENARST 0x00000008
+#define __APP_PLL_312_BYPASS 0x00000004
+#define __APP_PLL_312_LRESETN 0x00000002
+#define __APP_PLL_312_ENABLE 0x00000001
+#define MBIST_CTL_REG 0x00014220
+#define __EDRAM_BISTR_START 0x00000004
+#define __MBIST_RESET 0x00000002
+#define __MBIST_START 0x00000001
+#define MBIST_STAT_REG 0x00014224
+#define __EDRAM_BISTR_STATUS 0x00000008
+#define __EDRAM_BISTR_DONE 0x00000004
+#define __MEM_BIT_STATUS 0x00000002
+#define __MBIST_DONE 0x00000001
+#define HOST_SEM0_REG 0x00014230
+#define __HOST_SEMAPHORE 0x00000001
+#define HOST_SEM1_REG 0x00014234
+#define HOST_SEM2_REG 0x00014238
+#define HOST_SEM3_REG 0x0001423c
+#define HOST_SEM0_INFO_REG 0x00014240
+#define HOST_SEM1_INFO_REG 0x00014244
+#define HOST_SEM2_INFO_REG 0x00014248
+#define HOST_SEM3_INFO_REG 0x0001424c
+#define ETH_MAC_SER_REG 0x00014288
+#define __APP_EMS_CKBUFAMPIN 0x00000020
+#define __APP_EMS_REFCLKSEL 0x00000010
+#define __APP_EMS_CMLCKSEL 0x00000008
+#define __APP_EMS_REFCKBUFEN2 0x00000004
+#define __APP_EMS_REFCKBUFEN1 0x00000002
+#define __APP_EMS_CHANNEL_SEL 0x00000001
+#define HOSTFN2_INT_STATUS 0x00014300
+#define __HOSTFN2_HALT_OCCURRED 0x01000000
+#define __HOSTFN2_INT_STATUS_LVL_MK 0x00f00000
+#define __HOSTFN2_INT_STATUS_LVL_SH 20
+#define __HOSTFN2_INT_STATUS_LVL(_v) ((_v) << __HOSTFN2_INT_STATUS_LVL_SH)
+#define __HOSTFN2_INT_STATUS_P_MK 0x000f0000
+#define __HOSTFN2_INT_STATUS_P_SH 16
+#define __HOSTFN2_INT_STATUS_P(_v) ((_v) << __HOSTFN2_INT_STATUS_P_SH)
+#define __HOSTFN2_INT_STATUS_F 0x0000ffff
+#define HOSTFN2_INT_MSK 0x00014304
+#define HOST_PAGE_NUM_FN2 0x00014308
+#define HOST_MSIX_ERR_INDEX_FN2 0x0001430c
+#define HOSTFN3_INT_STATUS 0x00014400
+#define __HALT_OCCURRED 0x01000000
+#define __HOSTFN3_INT_STATUS_LVL_MK 0x00f00000
+#define __HOSTFN3_INT_STATUS_LVL_SH 20
+#define __HOSTFN3_INT_STATUS_LVL(_v) ((_v) << __HOSTFN3_INT_STATUS_LVL_SH)
+#define __HOSTFN3_INT_STATUS_P_MK 0x000f0000
+#define __HOSTFN3_INT_STATUS_P_SH 16
+#define __HOSTFN3_INT_STATUS_P(_v) ((_v) << __HOSTFN3_INT_STATUS_P_SH)
+#define __HOSTFN3_INT_STATUS_F 0x0000ffff
+#define HOSTFN3_INT_MSK 0x00014404
+#define HOST_PAGE_NUM_FN3 0x00014408
+#define HOST_MSIX_ERR_INDEX_FN3 0x0001440c
+#define FNC_ID_REG 0x00014600
+#define __FUNCTION_NUMBER 0x00000007
+#define FNC_PERS_REG 0x00014604
+#define __F3_FUNCTION_ACTIVE 0x80000000
+#define __F3_FUNCTION_MODE 0x40000000
+#define __F3_PORT_MAP_MK 0x30000000
+#define __F3_PORT_MAP_SH 28
+#define __F3_PORT_MAP(_v) ((_v) << __F3_PORT_MAP_SH)
+#define __F3_VM_MODE 0x08000000
+#define __F3_INTX_STATUS_MK 0x07000000
+#define __F3_INTX_STATUS_SH 24
+#define __F3_INTX_STATUS(_v) ((_v) << __F3_INTX_STATUS_SH)
+#define __F2_FUNCTION_ACTIVE 0x00800000
+#define __F2_FUNCTION_MODE 0x00400000
+#define __F2_PORT_MAP_MK 0x00300000
+#define __F2_PORT_MAP_SH 20
+#define __F2_PORT_MAP(_v) ((_v) << __F2_PORT_MAP_SH)
+#define __F2_VM_MODE 0x00080000
+#define __F2_INTX_STATUS_MK 0x00070000
+#define __F2_INTX_STATUS_SH 16
+#define __F2_INTX_STATUS(_v) ((_v) << __F2_INTX_STATUS_SH)
+#define __F1_FUNCTION_ACTIVE 0x00008000
+#define __F1_FUNCTION_MODE 0x00004000
+#define __F1_PORT_MAP_MK 0x00003000
+#define __F1_PORT_MAP_SH 12
+#define __F1_PORT_MAP(_v) ((_v) << __F1_PORT_MAP_SH)
+#define __F1_VM_MODE 0x00000800
+#define __F1_INTX_STATUS_MK 0x00000700
+#define __F1_INTX_STATUS_SH 8
+#define __F1_INTX_STATUS(_v) ((_v) << __F1_INTX_STATUS_SH)
+#define __F0_FUNCTION_ACTIVE 0x00000080
+#define __F0_FUNCTION_MODE 0x00000040
+#define __F0_PORT_MAP_MK 0x00000030
+#define __F0_PORT_MAP_SH 4
+#define __F0_PORT_MAP(_v) ((_v) << __F0_PORT_MAP_SH)
+#define __F0_VM_MODE 0x00000008
+#define __F0_INTX_STATUS 0x00000007
+enum {
+ __F0_INTX_STATUS_MSIX = 0x0,
+ __F0_INTX_STATUS_INTA = 0x1,
+ __F0_INTX_STATUS_INTB = 0x2,
+ __F0_INTX_STATUS_INTC = 0x3,
+ __F0_INTX_STATUS_INTD = 0x4,
+};
+#define OP_MODE 0x0001460c
+#define __APP_ETH_CLK_LOWSPEED 0x00000004
+#define __GLOBAL_CORECLK_HALFSPEED 0x00000002
+#define __GLOBAL_FCOE_MODE 0x00000001
+#define HOST_SEM4_REG 0x00014610
+#define HOST_SEM5_REG 0x00014614
+#define HOST_SEM6_REG 0x00014618
+#define HOST_SEM7_REG 0x0001461c
+#define HOST_SEM4_INFO_REG 0x00014620
+#define HOST_SEM5_INFO_REG 0x00014624
+#define HOST_SEM6_INFO_REG 0x00014628
+#define HOST_SEM7_INFO_REG 0x0001462c
+#define HOSTFN0_LPU0_MBOX0_CMD_STAT 0x00019000
+#define __HOSTFN0_LPU0_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN0_LPU0_MBOX0_INFO_SH 1
+#define __HOSTFN0_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU0_MBOX0_INFO_SH)
+#define __HOSTFN0_LPU0_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN0_LPU1_MBOX0_CMD_STAT 0x00019004
+#define __HOSTFN0_LPU1_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN0_LPU1_MBOX0_INFO_SH 1
+#define __HOSTFN0_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU1_MBOX0_INFO_SH)
+#define __HOSTFN0_LPU1_MBOX0_CMD_STATUS 0x00000001
+#define LPU0_HOSTFN0_MBOX0_CMD_STAT 0x00019008
+#define __LPU0_HOSTFN0_MBOX0_INFO_MK 0xfffffffe
+#define __LPU0_HOSTFN0_MBOX0_INFO_SH 1
+#define __LPU0_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN0_MBOX0_INFO_SH)
+#define __LPU0_HOSTFN0_MBOX0_CMD_STATUS 0x00000001
+#define LPU1_HOSTFN0_MBOX0_CMD_STAT 0x0001900c
+#define __LPU1_HOSTFN0_MBOX0_INFO_MK 0xfffffffe
+#define __LPU1_HOSTFN0_MBOX0_INFO_SH 1
+#define __LPU1_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN0_MBOX0_INFO_SH)
+#define __LPU1_HOSTFN0_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN1_LPU0_MBOX0_CMD_STAT 0x00019010
+#define __HOSTFN1_LPU0_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN1_LPU0_MBOX0_INFO_SH 1
+#define __HOSTFN1_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU0_MBOX0_INFO_SH)
+#define __HOSTFN1_LPU0_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN1_LPU1_MBOX0_CMD_STAT 0x00019014
+#define __HOSTFN1_LPU1_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN1_LPU1_MBOX0_INFO_SH 1
+#define __HOSTFN1_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU1_MBOX0_INFO_SH)
+#define __HOSTFN1_LPU1_MBOX0_CMD_STATUS 0x00000001
+#define LPU0_HOSTFN1_MBOX0_CMD_STAT 0x00019018
+#define __LPU0_HOSTFN1_MBOX0_INFO_MK 0xfffffffe
+#define __LPU0_HOSTFN1_MBOX0_INFO_SH 1
+#define __LPU0_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN1_MBOX0_INFO_SH)
+#define __LPU0_HOSTFN1_MBOX0_CMD_STATUS 0x00000001
+#define LPU1_HOSTFN1_MBOX0_CMD_STAT 0x0001901c
+#define __LPU1_HOSTFN1_MBOX0_INFO_MK 0xfffffffe
+#define __LPU1_HOSTFN1_MBOX0_INFO_SH 1
+#define __LPU1_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN1_MBOX0_INFO_SH)
+#define __LPU1_HOSTFN1_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN2_LPU0_MBOX0_CMD_STAT 0x00019150
+#define __HOSTFN2_LPU0_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN2_LPU0_MBOX0_INFO_SH 1
+#define __HOSTFN2_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU0_MBOX0_INFO_SH)
+#define __HOSTFN2_LPU0_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN2_LPU1_MBOX0_CMD_STAT 0x00019154
+#define __HOSTFN2_LPU1_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN2_LPU1_MBOX0_INFO_SH 1
+#define __HOSTFN2_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU1_MBOX0_INFO_SH)
+#define __HOSTFN2_LPU1_MBOX0BOX0_CMD_STATUS 0x00000001
+#define LPU0_HOSTFN2_MBOX0_CMD_STAT 0x00019158
+#define __LPU0_HOSTFN2_MBOX0_INFO_MK 0xfffffffe
+#define __LPU0_HOSTFN2_MBOX0_INFO_SH 1
+#define __LPU0_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN2_MBOX0_INFO_SH)
+#define __LPU0_HOSTFN2_MBOX0_CMD_STATUS 0x00000001
+#define LPU1_HOSTFN2_MBOX0_CMD_STAT 0x0001915c
+#define __LPU1_HOSTFN2_MBOX0_INFO_MK 0xfffffffe
+#define __LPU1_HOSTFN2_MBOX0_INFO_SH 1
+#define __LPU1_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN2_MBOX0_INFO_SH)
+#define __LPU1_HOSTFN2_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN3_LPU0_MBOX0_CMD_STAT 0x00019160
+#define __HOSTFN3_LPU0_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN3_LPU0_MBOX0_INFO_SH 1
+#define __HOSTFN3_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU0_MBOX0_INFO_SH)
+#define __HOSTFN3_LPU0_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN3_LPU1_MBOX0_CMD_STAT 0x00019164
+#define __HOSTFN3_LPU1_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN3_LPU1_MBOX0_INFO_SH 1
+#define __HOSTFN3_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU1_MBOX0_INFO_SH)
+#define __HOSTFN3_LPU1_MBOX0_CMD_STATUS 0x00000001
+#define LPU0_HOSTFN3_MBOX0_CMD_STAT 0x00019168
+#define __LPU0_HOSTFN3_MBOX0_INFO_MK 0xfffffffe
+#define __LPU0_HOSTFN3_MBOX0_INFO_SH 1
+#define __LPU0_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN3_MBOX0_INFO_SH)
+#define __LPU0_HOSTFN3_MBOX0_CMD_STATUS 0x00000001
+#define LPU1_HOSTFN3_MBOX0_CMD_STAT 0x0001916c
+#define __LPU1_HOSTFN3_MBOX0_INFO_MK 0xfffffffe
+#define __LPU1_HOSTFN3_MBOX0_INFO_SH 1
+#define __LPU1_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN3_MBOX0_INFO_SH)
+#define __LPU1_HOSTFN3_MBOX0_CMD_STATUS 0x00000001
+#define FW_INIT_HALT_P0 0x000191ac
+#define __FW_INIT_HALT_P 0x00000001
+#define FW_INIT_HALT_P1 0x000191bc
+#define CPE_PI_PTR_Q0 0x00038000
+#define __CPE_PI_UNUSED_MK 0xffff0000
+#define __CPE_PI_UNUSED_SH 16
+#define __CPE_PI_UNUSED(_v) ((_v) << __CPE_PI_UNUSED_SH)
+#define __CPE_PI_PTR 0x0000ffff
+#define CPE_PI_PTR_Q1 0x00038040
+#define CPE_CI_PTR_Q0 0x00038004
+#define __CPE_CI_UNUSED_MK 0xffff0000
+#define __CPE_CI_UNUSED_SH 16
+#define __CPE_CI_UNUSED(_v) ((_v) << __CPE_CI_UNUSED_SH)
+#define __CPE_CI_PTR 0x0000ffff
+#define CPE_CI_PTR_Q1 0x00038044
+#define CPE_DEPTH_Q0 0x00038008
+#define __CPE_DEPTH_UNUSED_MK 0xf8000000
+#define __CPE_DEPTH_UNUSED_SH 27
+#define __CPE_DEPTH_UNUSED(_v) ((_v) << __CPE_DEPTH_UNUSED_SH)
+#define __CPE_MSIX_VEC_INDEX_MK 0x07ff0000
+#define __CPE_MSIX_VEC_INDEX_SH 16
+#define __CPE_MSIX_VEC_INDEX(_v) ((_v) << __CPE_MSIX_VEC_INDEX_SH)
+#define __CPE_DEPTH 0x0000ffff
+#define CPE_DEPTH_Q1 0x00038048
+#define CPE_QCTRL_Q0 0x0003800c
+#define __CPE_CTRL_UNUSED30_MK 0xfc000000
+#define __CPE_CTRL_UNUSED30_SH 26
+#define __CPE_CTRL_UNUSED30(_v) ((_v) << __CPE_CTRL_UNUSED30_SH)
+#define __CPE_FUNC_INT_CTRL_MK 0x03000000
+#define __CPE_FUNC_INT_CTRL_SH 24
+#define __CPE_FUNC_INT_CTRL(_v) ((_v) << __CPE_FUNC_INT_CTRL_SH)
+enum {
+ __CPE_FUNC_INT_CTRL_DISABLE = 0x0,
+ __CPE_FUNC_INT_CTRL_F2NF = 0x1,
+ __CPE_FUNC_INT_CTRL_3QUART = 0x2,
+ __CPE_FUNC_INT_CTRL_HALF = 0x3,
+};
+#define __CPE_CTRL_UNUSED20_MK 0x00f00000
+#define __CPE_CTRL_UNUSED20_SH 20
+#define __CPE_CTRL_UNUSED20(_v) ((_v) << __CPE_CTRL_UNUSED20_SH)
+#define __CPE_SCI_TH_MK 0x000f0000
+#define __CPE_SCI_TH_SH 16
+#define __CPE_SCI_TH(_v) ((_v) << __CPE_SCI_TH_SH)
+#define __CPE_CTRL_UNUSED10_MK 0x0000c000
+#define __CPE_CTRL_UNUSED10_SH 14
+#define __CPE_CTRL_UNUSED10(_v) ((_v) << __CPE_CTRL_UNUSED10_SH)
+#define __CPE_ACK_PENDING 0x00002000
+#define __CPE_CTRL_UNUSED40_MK 0x00001c00
+#define __CPE_CTRL_UNUSED40_SH 10
+#define __CPE_CTRL_UNUSED40(_v) ((_v) << __CPE_CTRL_UNUSED40_SH)
+#define __CPE_PCIEID_MK 0x00000300
+#define __CPE_PCIEID_SH 8
+#define __CPE_PCIEID(_v) ((_v) << __CPE_PCIEID_SH)
+#define __CPE_CTRL_UNUSED00_MK 0x000000fe
+#define __CPE_CTRL_UNUSED00_SH 1
+#define __CPE_CTRL_UNUSED00(_v) ((_v) << __CPE_CTRL_UNUSED00_SH)
+#define __CPE_ESIZE 0x00000001
+#define CPE_QCTRL_Q1 0x0003804c
+#define __CPE_CTRL_UNUSED31_MK 0xfc000000
+#define __CPE_CTRL_UNUSED31_SH 26
+#define __CPE_CTRL_UNUSED31(_v) ((_v) << __CPE_CTRL_UNUSED31_SH)
+#define __CPE_CTRL_UNUSED21_MK 0x00f00000
+#define __CPE_CTRL_UNUSED21_SH 20
+#define __CPE_CTRL_UNUSED21(_v) ((_v) << __CPE_CTRL_UNUSED21_SH)
+#define __CPE_CTRL_UNUSED11_MK 0x0000c000
+#define __CPE_CTRL_UNUSED11_SH 14
+#define __CPE_CTRL_UNUSED11(_v) ((_v) << __CPE_CTRL_UNUSED11_SH)
+#define __CPE_CTRL_UNUSED41_MK 0x00001c00
+#define __CPE_CTRL_UNUSED41_SH 10
+#define __CPE_CTRL_UNUSED41(_v) ((_v) << __CPE_CTRL_UNUSED41_SH)
+#define __CPE_CTRL_UNUSED01_MK 0x000000fe
+#define __CPE_CTRL_UNUSED01_SH 1
+#define __CPE_CTRL_UNUSED01(_v) ((_v) << __CPE_CTRL_UNUSED01_SH)
+#define RME_PI_PTR_Q0 0x00038020
+#define __LATENCY_TIME_STAMP_MK 0xffff0000
+#define __LATENCY_TIME_STAMP_SH 16
+#define __LATENCY_TIME_STAMP(_v) ((_v) << __LATENCY_TIME_STAMP_SH)
+#define __RME_PI_PTR 0x0000ffff
+#define RME_PI_PTR_Q1 0x00038060
+#define RME_CI_PTR_Q0 0x00038024
+#define __DELAY_TIME_STAMP_MK 0xffff0000
+#define __DELAY_TIME_STAMP_SH 16
+#define __DELAY_TIME_STAMP(_v) ((_v) << __DELAY_TIME_STAMP_SH)
+#define __RME_CI_PTR 0x0000ffff
+#define RME_CI_PTR_Q1 0x00038064
+#define RME_DEPTH_Q0 0x00038028
+#define __RME_DEPTH_UNUSED_MK 0xf8000000
+#define __RME_DEPTH_UNUSED_SH 27
+#define __RME_DEPTH_UNUSED(_v) ((_v) << __RME_DEPTH_UNUSED_SH)
+#define __RME_MSIX_VEC_INDEX_MK 0x07ff0000
+#define __RME_MSIX_VEC_INDEX_SH 16
+#define __RME_MSIX_VEC_INDEX(_v) ((_v) << __RME_MSIX_VEC_INDEX_SH)
+#define __RME_DEPTH 0x0000ffff
+#define RME_DEPTH_Q1 0x00038068
+#define RME_QCTRL_Q0 0x0003802c
+#define __RME_INT_LATENCY_TIMER_MK 0xff000000
+#define __RME_INT_LATENCY_TIMER_SH 24
+#define __RME_INT_LATENCY_TIMER(_v) ((_v) << __RME_INT_LATENCY_TIMER_SH)
+#define __RME_INT_DELAY_TIMER_MK 0x00ff0000
+#define __RME_INT_DELAY_TIMER_SH 16
+#define __RME_INT_DELAY_TIMER(_v) ((_v) << __RME_INT_DELAY_TIMER_SH)
+#define __RME_INT_DELAY_DISABLE 0x00008000
+#define __RME_DLY_DELAY_DISABLE 0x00004000
+#define __RME_ACK_PENDING 0x00002000
+#define __RME_FULL_INTERRUPT_DISABLE 0x00001000
+#define __RME_CTRL_UNUSED10_MK 0x00000c00
+#define __RME_CTRL_UNUSED10_SH 10
+#define __RME_CTRL_UNUSED10(_v) ((_v) << __RME_CTRL_UNUSED10_SH)
+#define __RME_PCIEID_MK 0x00000300
+#define __RME_PCIEID_SH 8
+#define __RME_PCIEID(_v) ((_v) << __RME_PCIEID_SH)
+#define __RME_CTRL_UNUSED00_MK 0x000000fe
+#define __RME_CTRL_UNUSED00_SH 1
+#define __RME_CTRL_UNUSED00(_v) ((_v) << __RME_CTRL_UNUSED00_SH)
+#define __RME_ESIZE 0x00000001
+#define RME_QCTRL_Q1 0x0003806c
+#define __RME_CTRL_UNUSED11_MK 0x00000c00
+#define __RME_CTRL_UNUSED11_SH 10
+#define __RME_CTRL_UNUSED11(_v) ((_v) << __RME_CTRL_UNUSED11_SH)
+#define __RME_CTRL_UNUSED01_MK 0x000000fe
+#define __RME_CTRL_UNUSED01_SH 1
+#define __RME_CTRL_UNUSED01(_v) ((_v) << __RME_CTRL_UNUSED01_SH)
+#define PSS_CTL_REG 0x00018800
+#define __PSS_I2C_CLK_DIV_MK 0x007f0000
+#define __PSS_I2C_CLK_DIV_SH 16
+#define __PSS_I2C_CLK_DIV(_v) ((_v) << __PSS_I2C_CLK_DIV_SH)
+#define __PSS_LMEM_INIT_DONE 0x00001000
+#define __PSS_LMEM_RESET 0x00000200
+#define __PSS_LMEM_INIT_EN 0x00000100
+#define __PSS_LPU1_RESET 0x00000002
+#define __PSS_LPU0_RESET 0x00000001
+#define PSS_ERR_STATUS_REG 0x00018810
+#define __PSS_LPU1_TCM_READ_ERR 0x00200000
+#define __PSS_LPU0_TCM_READ_ERR 0x00100000
+#define __PSS_LMEM5_CORR_ERR 0x00080000
+#define __PSS_LMEM4_CORR_ERR 0x00040000
+#define __PSS_LMEM3_CORR_ERR 0x00020000
+#define __PSS_LMEM2_CORR_ERR 0x00010000
+#define __PSS_LMEM1_CORR_ERR 0x00008000
+#define __PSS_LMEM0_CORR_ERR 0x00004000
+#define __PSS_LMEM5_UNCORR_ERR 0x00002000
+#define __PSS_LMEM4_UNCORR_ERR 0x00001000
+#define __PSS_LMEM3_UNCORR_ERR 0x00000800
+#define __PSS_LMEM2_UNCORR_ERR 0x00000400
+#define __PSS_LMEM1_UNCORR_ERR 0x00000200
+#define __PSS_LMEM0_UNCORR_ERR 0x00000100
+#define __PSS_BAL_PERR 0x00000080
+#define __PSS_DIP_IF_ERR 0x00000040
+#define __PSS_IOH_IF_ERR 0x00000020
+#define __PSS_TDS_IF_ERR 0x00000010
+#define __PSS_RDS_IF_ERR 0x00000008
+#define __PSS_SGM_IF_ERR 0x00000004
+#define __PSS_LPU1_RAM_ERR 0x00000002
+#define __PSS_LPU0_RAM_ERR 0x00000001
+#define ERR_SET_REG 0x00018818
+#define __PSS_ERR_STATUS_SET 0x003fffff
+#define PMM_1T_RESET_REG_P0 0x0002381c
+#define __PMM_1T_RESET_P 0x00000001
+#define PMM_1T_RESET_REG_P1 0x00023c1c
+#define HQM_QSET0_RXQ_DRBL_P0 0x00038000
+#define __RXQ0_ADD_VECTORS_P 0x80000000
+#define __RXQ0_STOP_P 0x40000000
+#define __RXQ0_PRD_PTR_P 0x0000ffff
+#define HQM_QSET1_RXQ_DRBL_P0 0x00038080
+#define __RXQ1_ADD_VECTORS_P 0x80000000
+#define __RXQ1_STOP_P 0x40000000
+#define __RXQ1_PRD_PTR_P 0x0000ffff
+#define HQM_QSET0_RXQ_DRBL_P1 0x0003c000
+#define HQM_QSET1_RXQ_DRBL_P1 0x0003c080
+#define HQM_QSET0_TXQ_DRBL_P0 0x00038020
+#define __TXQ0_ADD_VECTORS_P 0x80000000
+#define __TXQ0_STOP_P 0x40000000
+#define __TXQ0_PRD_PTR_P 0x0000ffff
+#define HQM_QSET1_TXQ_DRBL_P0 0x000380a0
+#define __TXQ1_ADD_VECTORS_P 0x80000000
+#define __TXQ1_STOP_P 0x40000000
+#define __TXQ1_PRD_PTR_P 0x0000ffff
+#define HQM_QSET0_TXQ_DRBL_P1 0x0003c020
+#define HQM_QSET1_TXQ_DRBL_P1 0x0003c0a0
+#define HQM_QSET0_IB_DRBL_1_P0 0x00038040
+#define __IB1_0_ACK_P 0x80000000
+#define __IB1_0_DISABLE_P 0x40000000
+#define __IB1_0_COALESCING_CFG_P_MK 0x00ff0000
+#define __IB1_0_COALESCING_CFG_P_SH 16
+#define __IB1_0_COALESCING_CFG_P(_v) ((_v) << __IB1_0_COALESCING_CFG_P_SH)
+#define __IB1_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff
+#define HQM_QSET1_IB_DRBL_1_P0 0x000380c0
+#define __IB1_1_ACK_P 0x80000000
+#define __IB1_1_DISABLE_P 0x40000000
+#define __IB1_1_COALESCING_CFG_P_MK 0x00ff0000
+#define __IB1_1_COALESCING_CFG_P_SH 16
+#define __IB1_1_COALESCING_CFG_P(_v) ((_v) << __IB1_1_COALESCING_CFG_P_SH)
+#define __IB1_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff
+#define HQM_QSET0_IB_DRBL_1_P1 0x0003c040
+#define HQM_QSET1_IB_DRBL_1_P1 0x0003c0c0
+#define HQM_QSET0_IB_DRBL_2_P0 0x00038060
+#define __IB2_0_ACK_P 0x80000000
+#define __IB2_0_DISABLE_P 0x40000000
+#define __IB2_0_COALESCING_CFG_P_MK 0x00ff0000
+#define __IB2_0_COALESCING_CFG_P_SH 16
+#define __IB2_0_COALESCING_CFG_P(_v) ((_v) << __IB2_0_COALESCING_CFG_P_SH)
+#define __IB2_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff
+#define HQM_QSET1_IB_DRBL_2_P0 0x000380e0
+#define __IB2_1_ACK_P 0x80000000
+#define __IB2_1_DISABLE_P 0x40000000
+#define __IB2_1_COALESCING_CFG_P_MK 0x00ff0000
+#define __IB2_1_COALESCING_CFG_P_SH 16
+#define __IB2_1_COALESCING_CFG_P(_v) ((_v) << __IB2_1_COALESCING_CFG_P_SH)
+#define __IB2_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff
+#define HQM_QSET0_IB_DRBL_2_P1 0x0003c060
+#define HQM_QSET1_IB_DRBL_2_P1 0x0003c0e0
+
+/*
+ * These definitions are either in error/missing in spec. Its auto-generated
+ * from hard coded values in regparse.pl.
+ */
+#define __EMPHPOST_AT_4G_MK_FIX 0x0000001c
+#define __EMPHPOST_AT_4G_SH_FIX 0x00000002
+#define __EMPHPRE_AT_4G_FIX 0x00000003
+#define __SFP_TXRATE_EN_FIX 0x00000100
+#define __SFP_RXRATE_EN_FIX 0x00000080
+
+/*
+ * These register definitions are auto-generated from hard coded values
+ * in regparse.pl.
+ */
+
+/*
+ * These register mapping definitions are auto-generated from mapping tables
+ * in regparse.pl.
+ */
+#define BFA_IOC0_HBEAT_REG HOST_SEM0_INFO_REG
+#define BFA_IOC0_STATE_REG HOST_SEM1_INFO_REG
+#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG
+#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG
+#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG
+
+#define CPE_DEPTH_Q(__n) \
+ (CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0))
+#define CPE_QCTRL_Q(__n) \
+ (CPE_QCTRL_Q0 + (__n) * (CPE_QCTRL_Q1 - CPE_QCTRL_Q0))
+#define CPE_PI_PTR_Q(__n) \
+ (CPE_PI_PTR_Q0 + (__n) * (CPE_PI_PTR_Q1 - CPE_PI_PTR_Q0))
+#define CPE_CI_PTR_Q(__n) \
+ (CPE_CI_PTR_Q0 + (__n) * (CPE_CI_PTR_Q1 - CPE_CI_PTR_Q0))
+#define RME_DEPTH_Q(__n) \
+ (RME_DEPTH_Q0 + (__n) * (RME_DEPTH_Q1 - RME_DEPTH_Q0))
+#define RME_QCTRL_Q(__n) \
+ (RME_QCTRL_Q0 + (__n) * (RME_QCTRL_Q1 - RME_QCTRL_Q0))
+#define RME_PI_PTR_Q(__n) \
+ (RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0))
+#define RME_CI_PTR_Q(__n) \
+ (RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0))
+#define HQM_QSET_RXQ_DRBL_P0(__n) (HQM_QSET0_RXQ_DRBL_P0 + (__n) \
+ * (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0))
+#define HQM_QSET_TXQ_DRBL_P0(__n) (HQM_QSET0_TXQ_DRBL_P0 + (__n) \
+ * (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0))
+#define HQM_QSET_IB_DRBL_1_P0(__n) (HQM_QSET0_IB_DRBL_1_P0 + (__n) \
+ * (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0))
+#define HQM_QSET_IB_DRBL_2_P0(__n) (HQM_QSET0_IB_DRBL_2_P0 + (__n) \
+ * (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0))
+#define HQM_QSET_RXQ_DRBL_P1(__n) (HQM_QSET0_RXQ_DRBL_P1 + (__n) \
+ * (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1))
+#define HQM_QSET_TXQ_DRBL_P1(__n) (HQM_QSET0_TXQ_DRBL_P1 + (__n) \
+ * (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1))
+#define HQM_QSET_IB_DRBL_1_P1(__n) (HQM_QSET0_IB_DRBL_1_P1 + (__n) \
+ * (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1))
+#define HQM_QSET_IB_DRBL_2_P1(__n) (HQM_QSET0_IB_DRBL_2_P1 + (__n) \
+ * (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1))
+
+#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
+#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
+#define CPE_Q_MASK(__q) ((__q) & 0x3)
+#define RME_Q_MASK(__q) ((__q) & 0x3)
+
+/*
+ * PCI MSI-X vector defines
+ */
+enum {
+ BFA_MSIX_CPE_Q0 = 0,
+ BFA_MSIX_CPE_Q1 = 1,
+ BFA_MSIX_CPE_Q2 = 2,
+ BFA_MSIX_CPE_Q3 = 3,
+ BFA_MSIX_RME_Q0 = 4,
+ BFA_MSIX_RME_Q1 = 5,
+ BFA_MSIX_RME_Q2 = 6,
+ BFA_MSIX_RME_Q3 = 7,
+ BFA_MSIX_LPU_ERR = 8,
+ BFA_MSIX_CT_MAX = 9,
+};
+
+/*
+ * And corresponding host interrupt status bit field defines
+ */
+#define __HFN_INT_CPE_Q0 0x00000001U
+#define __HFN_INT_CPE_Q1 0x00000002U
+#define __HFN_INT_CPE_Q2 0x00000004U
+#define __HFN_INT_CPE_Q3 0x00000008U
+#define __HFN_INT_CPE_Q4 0x00000010U
+#define __HFN_INT_CPE_Q5 0x00000020U
+#define __HFN_INT_CPE_Q6 0x00000040U
+#define __HFN_INT_CPE_Q7 0x00000080U
+#define __HFN_INT_RME_Q0 0x00000100U
+#define __HFN_INT_RME_Q1 0x00000200U
+#define __HFN_INT_RME_Q2 0x00000400U
+#define __HFN_INT_RME_Q3 0x00000800U
+#define __HFN_INT_RME_Q4 0x00001000U
+#define __HFN_INT_RME_Q5 0x00002000U
+#define __HFN_INT_RME_Q6 0x00004000U
+#define __HFN_INT_RME_Q7 0x00008000U
+#define __HFN_INT_ERR_EMC 0x00010000U
+#define __HFN_INT_ERR_LPU0 0x00020000U
+#define __HFN_INT_ERR_LPU1 0x00040000U
+#define __HFN_INT_ERR_PSS 0x00080000U
+#define __HFN_INT_MBOX_LPU0 0x00100000U
+#define __HFN_INT_MBOX_LPU1 0x00200000U
+#define __HFN_INT_MBOX1_LPU0 0x00400000U
+#define __HFN_INT_MBOX1_LPU1 0x00800000U
+#define __HFN_INT_LL_HALT 0x01000000U
+#define __HFN_INT_CPE_MASK 0x000000ffU
+#define __HFN_INT_RME_MASK 0x0000ff00U
+
+/*
+ * catapult memory map.
+ */
+#define LL_PGN_HQM0 0x0096
+#define LL_PGN_HQM1 0x0097
+#define PSS_SMEM_PAGE_START 0x8000
+#define PSS_SMEM_PGNUM(_pg0, _ma) ((_pg0) + ((_ma) >> 15))
+#define PSS_SMEM_PGOFF(_ma) ((_ma) & 0x7fff)
+
+/*
+ * End of catapult memory map
+ */
+
+#endif /* __BFI_CTREG_H__ */
diff --git a/drivers/net/bna/bfi_ll.h b/drivers/net/bna/bfi_ll.h
new file mode 100644
index 000000000000..bee4d054066a
--- /dev/null
+++ b/drivers/net/bna/bfi_ll.h
@@ -0,0 +1,438 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BFI_LL_H__
+#define __BFI_LL_H__
+
+#include "bfi.h"
+
+#pragma pack(1)
+
+/**
+ * @brief
+ * "enums" for all LL mailbox messages other than IOC
+ */
+enum {
+ BFI_LL_H2I_MAC_UCAST_SET_REQ = 1,
+ BFI_LL_H2I_MAC_UCAST_ADD_REQ = 2,
+ BFI_LL_H2I_MAC_UCAST_DEL_REQ = 3,
+
+ BFI_LL_H2I_MAC_MCAST_ADD_REQ = 4,
+ BFI_LL_H2I_MAC_MCAST_DEL_REQ = 5,
+ BFI_LL_H2I_MAC_MCAST_FILTER_REQ = 6,
+ BFI_LL_H2I_MAC_MCAST_DEL_ALL_REQ = 7,
+
+ BFI_LL_H2I_PORT_ADMIN_REQ = 8,
+ BFI_LL_H2I_STATS_GET_REQ = 9,
+ BFI_LL_H2I_STATS_CLEAR_REQ = 10,
+
+ BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ = 11,
+ BFI_LL_H2I_RXF_DEFAULT_SET_REQ = 12,
+
+ BFI_LL_H2I_TXQ_STOP_REQ = 13,
+ BFI_LL_H2I_RXQ_STOP_REQ = 14,
+
+ BFI_LL_H2I_DIAG_LOOPBACK_REQ = 15,
+
+ BFI_LL_H2I_SET_PAUSE_REQ = 16,
+ BFI_LL_H2I_MTU_INFO_REQ = 17,
+
+ BFI_LL_H2I_RX_REQ = 18,
+} ;
+
+enum {
+ BFI_LL_I2H_MAC_UCAST_SET_RSP = BFA_I2HM(1),
+ BFI_LL_I2H_MAC_UCAST_ADD_RSP = BFA_I2HM(2),
+ BFI_LL_I2H_MAC_UCAST_DEL_RSP = BFA_I2HM(3),
+
+ BFI_LL_I2H_MAC_MCAST_ADD_RSP = BFA_I2HM(4),
+ BFI_LL_I2H_MAC_MCAST_DEL_RSP = BFA_I2HM(5),
+ BFI_LL_I2H_MAC_MCAST_FILTER_RSP = BFA_I2HM(6),
+ BFI_LL_I2H_MAC_MCAST_DEL_ALL_RSP = BFA_I2HM(7),
+
+ BFI_LL_I2H_PORT_ADMIN_RSP = BFA_I2HM(8),
+ BFI_LL_I2H_STATS_GET_RSP = BFA_I2HM(9),
+ BFI_LL_I2H_STATS_CLEAR_RSP = BFA_I2HM(10),
+
+ BFI_LL_I2H_RXF_PROMISCUOUS_SET_RSP = BFA_I2HM(11),
+ BFI_LL_I2H_RXF_DEFAULT_SET_RSP = BFA_I2HM(12),
+
+ BFI_LL_I2H_TXQ_STOP_RSP = BFA_I2HM(13),
+ BFI_LL_I2H_RXQ_STOP_RSP = BFA_I2HM(14),
+
+ BFI_LL_I2H_DIAG_LOOPBACK_RSP = BFA_I2HM(15),
+
+ BFI_LL_I2H_SET_PAUSE_RSP = BFA_I2HM(16),
+
+ BFI_LL_I2H_MTU_INFO_RSP = BFA_I2HM(17),
+ BFI_LL_I2H_RX_RSP = BFA_I2HM(18),
+
+ BFI_LL_I2H_LINK_DOWN_AEN = BFA_I2HM(19),
+ BFI_LL_I2H_LINK_UP_AEN = BFA_I2HM(20),
+
+ BFI_LL_I2H_PORT_ENABLE_AEN = BFA_I2HM(21),
+ BFI_LL_I2H_PORT_DISABLE_AEN = BFA_I2HM(22),
+} ;
+
+/**
+ * @brief bfi_ll_mac_addr_req is used by:
+ * BFI_LL_H2I_MAC_UCAST_SET_REQ
+ * BFI_LL_H2I_MAC_UCAST_ADD_REQ
+ * BFI_LL_H2I_MAC_UCAST_DEL_REQ
+ * BFI_LL_H2I_MAC_MCAST_ADD_REQ
+ * BFI_LL_H2I_MAC_MCAST_DEL_REQ
+ */
+struct bfi_ll_mac_addr_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 rxf_id;
+ u8 rsvd1[3];
+ mac_t mac_addr;
+ u8 rsvd2[2];
+};
+
+/**
+ * @brief bfi_ll_mcast_filter_req is used by:
+ * BFI_LL_H2I_MAC_MCAST_FILTER_REQ
+ */
+struct bfi_ll_mcast_filter_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 rxf_id;
+ u8 enable;
+ u8 rsvd[2];
+};
+
+/**
+ * @brief bfi_ll_mcast_del_all is used by:
+ * BFI_LL_H2I_MAC_MCAST_DEL_ALL_REQ
+ */
+struct bfi_ll_mcast_del_all_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 rxf_id;
+ u8 rsvd[3];
+};
+
+/**
+ * @brief bfi_ll_q_stop_req is used by:
+ * BFI_LL_H2I_TXQ_STOP_REQ
+ * BFI_LL_H2I_RXQ_STOP_REQ
+ */
+struct bfi_ll_q_stop_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u32 q_id_mask[2]; /* !< bit-mask for queue ids */
+};
+
+/**
+ * @brief bfi_ll_stats_req is used by:
+ * BFI_LL_I2H_STATS_GET_REQ
+ * BFI_LL_I2H_STATS_CLEAR_REQ
+ */
+struct bfi_ll_stats_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u16 stats_mask; /* !< bit-mask for non-function statistics */
+ u8 rsvd[2];
+ u32 rxf_id_mask[2]; /* !< bit-mask for RxF Statistics */
+ u32 txf_id_mask[2]; /* !< bit-mask for TxF Statistics */
+ union bfi_addr_u host_buffer; /* !< where statistics are returned */
+};
+
+/**
+ * @brief defines for "stats_mask" above.
+ */
+#define BFI_LL_STATS_MAC (1 << 0) /* !< MAC Statistics */
+#define BFI_LL_STATS_BPC (1 << 1) /* !< Pause Stats from BPC */
+#define BFI_LL_STATS_RAD (1 << 2) /* !< Rx Admission Statistics */
+#define BFI_LL_STATS_RX_FC (1 << 3) /* !< Rx FC Stats from RxA */
+#define BFI_LL_STATS_TX_FC (1 << 4) /* !< Tx FC Stats from TxA */
+
+#define BFI_LL_STATS_ALL 0x1f
+
+/**
+ * @brief bfi_ll_port_admin_req
+ */
+struct bfi_ll_port_admin_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 up;
+ u8 rsvd[3];
+};
+
+/**
+ * @brief bfi_ll_rxf_req is used by:
+ * BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ
+ * BFI_LL_H2I_RXF_DEFAULT_SET_REQ
+ */
+struct bfi_ll_rxf_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 rxf_id;
+ u8 enable;
+ u8 rsvd[2];
+};
+
+/**
+ * @brief bfi_ll_rxf_multi_req is used by:
+ * BFI_LL_H2I_RX_REQ
+ */
+struct bfi_ll_rxf_multi_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u32 rxf_id_mask[2];
+ u8 enable;
+ u8 rsvd[3];
+};
+
+/**
+ * @brief enum for Loopback opmodes
+ */
+enum {
+ BFI_LL_DIAG_LB_OPMODE_EXT = 0,
+ BFI_LL_DIAG_LB_OPMODE_CBL = 1,
+};
+
+/**
+ * @brief bfi_ll_set_pause_req is used by:
+ * BFI_LL_H2I_SET_PAUSE_REQ
+ */
+struct bfi_ll_set_pause_req {
+ struct bfi_mhdr mh;
+ u8 tx_pause; /* 1 = enable, 0 = disable */
+ u8 rx_pause; /* 1 = enable, 0 = disable */
+ u8 rsvd[2];
+};
+
+/**
+ * @brief bfi_ll_mtu_info_req is used by:
+ * BFI_LL_H2I_MTU_INFO_REQ
+ */
+struct bfi_ll_mtu_info_req {
+ struct bfi_mhdr mh;
+ u16 mtu;
+ u8 rsvd[2];
+};
+
+/**
+ * @brief
+ * Response header format used by all responses
+ * For both responses and asynchronous notifications
+ */
+struct bfi_ll_rsp {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 error;
+ u8 rsvd[3];
+};
+
+/**
+ * @brief bfi_ll_cee_aen is used by:
+ * BFI_LL_I2H_LINK_DOWN_AEN
+ * BFI_LL_I2H_LINK_UP_AEN
+ */
+struct bfi_ll_aen {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u32 reason;
+ u8 cee_linkup;
+ u8 prio_map; /*!< LL priority bit-map */
+ u8 rsvd[2];
+};
+
+/**
+ * @brief
+ * The following error codes can be returned
+ * by the mbox commands
+ */
+enum {
+ BFI_LL_CMD_OK = 0,
+ BFI_LL_CMD_FAIL = 1,
+ BFI_LL_CMD_DUP_ENTRY = 2, /* !< Duplicate entry in CAM */
+ BFI_LL_CMD_CAM_FULL = 3, /* !< CAM is full */
+ BFI_LL_CMD_NOT_OWNER = 4, /* !< Not permitted, b'cos not owner */
+ BFI_LL_CMD_NOT_EXEC = 5, /* !< Was not sent to f/w at all */
+ BFI_LL_CMD_WAITING = 6, /* !< Waiting for completion (VMware) */
+ BFI_LL_CMD_PORT_DISABLED = 7, /* !< port in disabled state */
+} ;
+
+/* Statistics */
+#define BFI_LL_TXF_ID_MAX 64
+#define BFI_LL_RXF_ID_MAX 64
+
+/* TxF Frame Statistics */
+struct bfi_ll_stats_txf {
+ u64 ucast_octets;
+ u64 ucast;
+ u64 ucast_vlan;
+
+ u64 mcast_octets;
+ u64 mcast;
+ u64 mcast_vlan;
+
+ u64 bcast_octets;
+ u64 bcast;
+ u64 bcast_vlan;
+
+ u64 errors;
+ u64 filter_vlan; /* frames filtered due to VLAN */
+ u64 filter_mac_sa; /* frames filtered due to SA check */
+};
+
+/* RxF Frame Statistics */
+struct bfi_ll_stats_rxf {
+ u64 ucast_octets;
+ u64 ucast;
+ u64 ucast_vlan;
+
+ u64 mcast_octets;
+ u64 mcast;
+ u64 mcast_vlan;
+
+ u64 bcast_octets;
+ u64 bcast;
+ u64 bcast_vlan;
+ u64 frame_drops;
+};
+
+/* FC Tx Frame Statistics */
+struct bfi_ll_stats_fc_tx {
+ u64 txf_ucast_octets;
+ u64 txf_ucast;
+ u64 txf_ucast_vlan;
+
+ u64 txf_mcast_octets;
+ u64 txf_mcast;
+ u64 txf_mcast_vlan;
+
+ u64 txf_bcast_octets;
+ u64 txf_bcast;
+ u64 txf_bcast_vlan;
+
+ u64 txf_parity_errors;
+ u64 txf_timeout;
+ u64 txf_fid_parity_errors;
+};
+
+/* FC Rx Frame Statistics */
+struct bfi_ll_stats_fc_rx {
+ u64 rxf_ucast_octets;
+ u64 rxf_ucast;
+ u64 rxf_ucast_vlan;
+
+ u64 rxf_mcast_octets;
+ u64 rxf_mcast;
+ u64 rxf_mcast_vlan;
+
+ u64 rxf_bcast_octets;
+ u64 rxf_bcast;
+ u64 rxf_bcast_vlan;
+};
+
+/* RAD Frame Statistics */
+struct bfi_ll_stats_rad {
+ u64 rx_frames;
+ u64 rx_octets;
+ u64 rx_vlan_frames;
+
+ u64 rx_ucast;
+ u64 rx_ucast_octets;
+ u64 rx_ucast_vlan;
+
+ u64 rx_mcast;
+ u64 rx_mcast_octets;
+ u64 rx_mcast_vlan;
+
+ u64 rx_bcast;
+ u64 rx_bcast_octets;
+ u64 rx_bcast_vlan;
+
+ u64 rx_drops;
+};
+
+/* BPC Tx Registers */
+struct bfi_ll_stats_bpc {
+ /* transmit stats */
+ u64 tx_pause[8];
+ u64 tx_zero_pause[8]; /*!< Pause cancellation */
+ /*!<Pause initiation rather than retention */
+ u64 tx_first_pause[8];
+
+ /* receive stats */
+ u64 rx_pause[8];
+ u64 rx_zero_pause[8]; /*!< Pause cancellation */
+ /*!<Pause initiation rather than retention */
+ u64 rx_first_pause[8];
+};
+
+/* MAC Rx Statistics */
+struct bfi_ll_stats_mac {
+ u64 frame_64; /* both rx and tx counter */
+ u64 frame_65_127; /* both rx and tx counter */
+ u64 frame_128_255; /* both rx and tx counter */
+ u64 frame_256_511; /* both rx and tx counter */
+ u64 frame_512_1023; /* both rx and tx counter */
+ u64 frame_1024_1518; /* both rx and tx counter */
+ u64 frame_1519_1522; /* both rx and tx counter */
+
+ /* receive stats */
+ u64 rx_bytes;
+ u64 rx_packets;
+ u64 rx_fcs_error;
+ u64 rx_multicast;
+ u64 rx_broadcast;
+ u64 rx_control_frames;
+ u64 rx_pause;
+ u64 rx_unknown_opcode;
+ u64 rx_alignment_error;
+ u64 rx_frame_length_error;
+ u64 rx_code_error;
+ u64 rx_carrier_sense_error;
+ u64 rx_undersize;
+ u64 rx_oversize;
+ u64 rx_fragments;
+ u64 rx_jabber;
+ u64 rx_drop;
+
+ /* transmit stats */
+ u64 tx_bytes;
+ u64 tx_packets;
+ u64 tx_multicast;
+ u64 tx_broadcast;
+ u64 tx_pause;
+ u64 tx_deferral;
+ u64 tx_excessive_deferral;
+ u64 tx_single_collision;
+ u64 tx_muliple_collision;
+ u64 tx_late_collision;
+ u64 tx_excessive_collision;
+ u64 tx_total_collision;
+ u64 tx_pause_honored;
+ u64 tx_drop;
+ u64 tx_jabber;
+ u64 tx_fcs_error;
+ u64 tx_control_frame;
+ u64 tx_oversize;
+ u64 tx_undersize;
+ u64 tx_fragments;
+};
+
+/* Complete statistics */
+struct bfi_ll_stats {
+ struct bfi_ll_stats_mac mac_stats;
+ struct bfi_ll_stats_bpc bpc_stats;
+ struct bfi_ll_stats_rad rad_stats;
+ struct bfi_ll_stats_fc_rx fc_rx_stats;
+ struct bfi_ll_stats_fc_tx fc_tx_stats;
+ struct bfi_ll_stats_rxf rxf_stats[BFI_LL_RXF_ID_MAX];
+ struct bfi_ll_stats_txf txf_stats[BFI_LL_TXF_ID_MAX];
+};
+
+#pragma pack()
+
+#endif /* __BFI_LL_H__ */
diff --git a/drivers/net/bna/bna.h b/drivers/net/bna/bna.h
new file mode 100644
index 000000000000..df6676bbc84e
--- /dev/null
+++ b/drivers/net/bna/bna.h
@@ -0,0 +1,550 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#ifndef __BNA_H__
+#define __BNA_H__
+
+#include "bfa_wc.h"
+#include "bfa_ioc.h"
+#include "cna.h"
+#include "bfi_ll.h"
+#include "bna_types.h"
+
+extern const u32 bna_napi_dim_vector[][BNA_BIAS_T_MAX];
+
+/**
+ *
+ * Macros and constants
+ *
+ */
+
+#define BNA_IOC_TIMER_FREQ 200
+
+/* Log string size */
+#define BNA_MESSAGE_SIZE 256
+
+#define bna_device_timer(_dev) bfa_timer_beat(&((_dev)->timer_mod))
+
+/* MBOX API for PORT, TX, RX */
+#define bna_mbox_qe_fill(_qe, _cmd, _cmd_len, _cbfn, _cbarg) \
+do { \
+ memcpy(&((_qe)->cmd.msg[0]), (_cmd), (_cmd_len)); \
+ (_qe)->cbfn = (_cbfn); \
+ (_qe)->cbarg = (_cbarg); \
+} while (0)
+
+#define bna_is_small_rxq(rcb) ((rcb)->id == 1)
+
+#define BNA_MAC_IS_EQUAL(_mac1, _mac2) \
+ (!memcmp((_mac1), (_mac2), sizeof(mac_t)))
+
+#define BNA_POWER_OF_2(x) (((x) & ((x) - 1)) == 0)
+
+#define BNA_TO_POWER_OF_2(x) \
+do { \
+ int _shift = 0; \
+ while ((x) && (x) != 1) { \
+ (x) >>= 1; \
+ _shift++; \
+ } \
+ (x) <<= _shift; \
+} while (0)
+
+#define BNA_TO_POWER_OF_2_HIGH(x) \
+do { \
+ int n = 1; \
+ while (n < (x)) \
+ n <<= 1; \
+ (x) = n; \
+} while (0)
+
+/*
+ * input : _addr-> os dma addr in host endian format,
+ * output : _bna_dma_addr-> pointer to hw dma addr
+ */
+#define BNA_SET_DMA_ADDR(_addr, _bna_dma_addr) \
+do { \
+ u64 tmp_addr = \
+ cpu_to_be64((u64)(_addr)); \
+ (_bna_dma_addr)->msb = ((struct bna_dma_addr *)&tmp_addr)->msb; \
+ (_bna_dma_addr)->lsb = ((struct bna_dma_addr *)&tmp_addr)->lsb; \
+} while (0)
+
+/*
+ * input : _bna_dma_addr-> pointer to hw dma addr
+ * output : _addr-> os dma addr in host endian format
+ */
+#define BNA_GET_DMA_ADDR(_bna_dma_addr, _addr) \
+do { \
+ (_addr) = ((((u64)ntohl((_bna_dma_addr)->msb))) << 32) \
+ | ((ntohl((_bna_dma_addr)->lsb) & 0xffffffff)); \
+} while (0)
+
+#define containing_rec(addr, type, field) \
+ ((type *)((unsigned char *)(addr) - \
+ (unsigned char *)(&((type *)0)->field)))
+
+#define BNA_TXQ_WI_NEEDED(_vectors) (((_vectors) + 3) >> 2)
+
+/* TxQ element is 64 bytes */
+#define BNA_TXQ_PAGE_INDEX_MAX (PAGE_SIZE >> 6)
+#define BNA_TXQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 6)
+
+#define BNA_TXQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \
+{ \
+ unsigned int page_index; /* index within a page */ \
+ void *page_addr; \
+ page_index = (_qe_idx) & (BNA_TXQ_PAGE_INDEX_MAX - 1); \
+ (_qe_ptr_range) = (BNA_TXQ_PAGE_INDEX_MAX - page_index); \
+ page_addr = (_qpt_ptr)[((_qe_idx) >> BNA_TXQ_PAGE_INDEX_MAX_SHIFT)];\
+ (_qe_ptr) = &((struct bna_txq_entry *)(page_addr))[page_index]; \
+}
+
+/* RxQ element is 8 bytes */
+#define BNA_RXQ_PAGE_INDEX_MAX (PAGE_SIZE >> 3)
+#define BNA_RXQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 3)
+
+#define BNA_RXQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \
+{ \
+ unsigned int page_index; /* index within a page */ \
+ void *page_addr; \
+ page_index = (_qe_idx) & (BNA_RXQ_PAGE_INDEX_MAX - 1); \
+ (_qe_ptr_range) = (BNA_RXQ_PAGE_INDEX_MAX - page_index); \
+ page_addr = (_qpt_ptr)[((_qe_idx) >> \
+ BNA_RXQ_PAGE_INDEX_MAX_SHIFT)]; \
+ (_qe_ptr) = &((struct bna_rxq_entry *)(page_addr))[page_index]; \
+}
+
+/* CQ element is 16 bytes */
+#define BNA_CQ_PAGE_INDEX_MAX (PAGE_SIZE >> 4)
+#define BNA_CQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 4)
+
+#define BNA_CQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \
+{ \
+ unsigned int page_index; /* index within a page */ \
+ void *page_addr; \
+ \
+ page_index = (_qe_idx) & (BNA_CQ_PAGE_INDEX_MAX - 1); \
+ (_qe_ptr_range) = (BNA_CQ_PAGE_INDEX_MAX - page_index); \
+ page_addr = (_qpt_ptr)[((_qe_idx) >> \
+ BNA_CQ_PAGE_INDEX_MAX_SHIFT)]; \
+ (_qe_ptr) = &((struct bna_cq_entry *)(page_addr))[page_index];\
+}
+
+#define BNA_QE_INDX_2_PTR(_cast, _qe_idx, _q_base) \
+ (&((_cast *)(_q_base))[(_qe_idx)])
+
+#define BNA_QE_INDX_RANGE(_qe_idx, _q_depth) ((_q_depth) - (_qe_idx))
+
+#define BNA_QE_INDX_ADD(_qe_idx, _qe_num, _q_depth) \
+ ((_qe_idx) = ((_qe_idx) + (_qe_num)) & ((_q_depth) - 1))
+
+#define BNA_Q_INDEX_CHANGE(_old_idx, _updated_idx, _q_depth) \
+ (((_updated_idx) - (_old_idx)) & ((_q_depth) - 1))
+
+#define BNA_QE_FREE_CNT(_q_ptr, _q_depth) \
+ (((_q_ptr)->consumer_index - (_q_ptr)->producer_index - 1) & \
+ ((_q_depth) - 1))
+
+#define BNA_QE_IN_USE_CNT(_q_ptr, _q_depth) \
+ ((((_q_ptr)->producer_index - (_q_ptr)->consumer_index)) & \
+ (_q_depth - 1))
+
+#define BNA_Q_GET_CI(_q_ptr) ((_q_ptr)->q.consumer_index)
+
+#define BNA_Q_GET_PI(_q_ptr) ((_q_ptr)->q.producer_index)
+
+#define BNA_Q_PI_ADD(_q_ptr, _num) \
+ (_q_ptr)->q.producer_index = \
+ (((_q_ptr)->q.producer_index + (_num)) & \
+ ((_q_ptr)->q.q_depth - 1))
+
+#define BNA_Q_CI_ADD(_q_ptr, _num) \
+ (_q_ptr)->q.consumer_index = \
+ (((_q_ptr)->q.consumer_index + (_num)) \
+ & ((_q_ptr)->q.q_depth - 1))
+
+#define BNA_Q_FREE_COUNT(_q_ptr) \
+ (BNA_QE_FREE_CNT(&((_q_ptr)->q), (_q_ptr)->q.q_depth))
+
+#define BNA_Q_IN_USE_COUNT(_q_ptr) \
+ (BNA_QE_IN_USE_CNT(&(_q_ptr)->q, (_q_ptr)->q.q_depth))
+
+/* These macros build the data portion of the TxQ/RxQ doorbell */
+#define BNA_DOORBELL_Q_PRD_IDX(_pi) (0x80000000 | (_pi))
+#define BNA_DOORBELL_Q_STOP (0x40000000)
+
+/* These macros build the data portion of the IB doorbell */
+#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \
+ (0x80000000 | ((_timeout) << 16) | (_events))
+#define BNA_DOORBELL_IB_INT_DISABLE (0x40000000)
+
+/* Set the coalescing timer for the given ib */
+#define bna_ib_coalescing_timer_set(_i_dbell, _cls_timer) \
+ ((_i_dbell)->doorbell_ack = BNA_DOORBELL_IB_INT_ACK((_cls_timer), 0));
+
+/* Acks 'events' # of events for a given ib */
+#define bna_ib_ack(_i_dbell, _events) \
+ (writel(((_i_dbell)->doorbell_ack | (_events)), \
+ (_i_dbell)->doorbell_addr));
+
+#define bna_txq_prod_indx_doorbell(_tcb) \
+ (writel(BNA_DOORBELL_Q_PRD_IDX((_tcb)->producer_index), \
+ (_tcb)->q_dbell));
+
+#define bna_rxq_prod_indx_doorbell(_rcb) \
+ (writel(BNA_DOORBELL_Q_PRD_IDX((_rcb)->producer_index), \
+ (_rcb)->q_dbell));
+
+#define BNA_LARGE_PKT_SIZE 1000
+
+#define BNA_UPDATE_PKT_CNT(_pkt, _len) \
+do { \
+ if ((_len) > BNA_LARGE_PKT_SIZE) { \
+ (_pkt)->large_pkt_cnt++; \
+ } else { \
+ (_pkt)->small_pkt_cnt++; \
+ } \
+} while (0)
+
+#define call_rxf_stop_cbfn(rxf, status) \
+ if ((rxf)->stop_cbfn) { \
+ (*(rxf)->stop_cbfn)((rxf)->stop_cbarg, (status)); \
+ (rxf)->stop_cbfn = NULL; \
+ (rxf)->stop_cbarg = NULL; \
+ }
+
+#define call_rxf_start_cbfn(rxf, status) \
+ if ((rxf)->start_cbfn) { \
+ (*(rxf)->start_cbfn)((rxf)->start_cbarg, (status)); \
+ (rxf)->start_cbfn = NULL; \
+ (rxf)->start_cbarg = NULL; \
+ }
+
+#define call_rxf_cam_fltr_cbfn(rxf, status) \
+ if ((rxf)->cam_fltr_cbfn) { \
+ (*(rxf)->cam_fltr_cbfn)((rxf)->cam_fltr_cbarg, rxf->rx, \
+ (status)); \
+ (rxf)->cam_fltr_cbfn = NULL; \
+ (rxf)->cam_fltr_cbarg = NULL; \
+ }
+
+#define call_rxf_pause_cbfn(rxf, status) \
+ if ((rxf)->oper_state_cbfn) { \
+ (*(rxf)->oper_state_cbfn)((rxf)->oper_state_cbarg, rxf->rx,\
+ (status)); \
+ (rxf)->rxf_flags &= ~BNA_RXF_FL_OPERSTATE_CHANGED; \
+ (rxf)->oper_state_cbfn = NULL; \
+ (rxf)->oper_state_cbarg = NULL; \
+ }
+
+#define call_rxf_resume_cbfn(rxf, status) call_rxf_pause_cbfn(rxf, status)
+
+#define is_xxx_enable(mode, bitmask, xxx) ((bitmask & xxx) && (mode & xxx))
+
+#define is_xxx_disable(mode, bitmask, xxx) ((bitmask & xxx) && !(mode & xxx))
+
+#define xxx_enable(mode, bitmask, xxx) \
+do { \
+ bitmask |= xxx; \
+ mode |= xxx; \
+} while (0)
+
+#define xxx_disable(mode, bitmask, xxx) \
+do { \
+ bitmask |= xxx; \
+ mode &= ~xxx; \
+} while (0)
+
+#define xxx_inactive(mode, bitmask, xxx) \
+do { \
+ bitmask &= ~xxx; \
+ mode &= ~xxx; \
+} while (0)
+
+#define is_promisc_enable(mode, bitmask) \
+ is_xxx_enable(mode, bitmask, BNA_RXMODE_PROMISC)
+
+#define is_promisc_disable(mode, bitmask) \
+ is_xxx_disable(mode, bitmask, BNA_RXMODE_PROMISC)
+
+#define promisc_enable(mode, bitmask) \
+ xxx_enable(mode, bitmask, BNA_RXMODE_PROMISC)
+
+#define promisc_disable(mode, bitmask) \
+ xxx_disable(mode, bitmask, BNA_RXMODE_PROMISC)
+
+#define promisc_inactive(mode, bitmask) \
+ xxx_inactive(mode, bitmask, BNA_RXMODE_PROMISC)
+
+#define is_default_enable(mode, bitmask) \
+ is_xxx_enable(mode, bitmask, BNA_RXMODE_DEFAULT)
+
+#define is_default_disable(mode, bitmask) \
+ is_xxx_disable(mode, bitmask, BNA_RXMODE_DEFAULT)
+
+#define default_enable(mode, bitmask) \
+ xxx_enable(mode, bitmask, BNA_RXMODE_DEFAULT)
+
+#define default_disable(mode, bitmask) \
+ xxx_disable(mode, bitmask, BNA_RXMODE_DEFAULT)
+
+#define default_inactive(mode, bitmask) \
+ xxx_inactive(mode, bitmask, BNA_RXMODE_DEFAULT)
+
+#define is_allmulti_enable(mode, bitmask) \
+ is_xxx_enable(mode, bitmask, BNA_RXMODE_ALLMULTI)
+
+#define is_allmulti_disable(mode, bitmask) \
+ is_xxx_disable(mode, bitmask, BNA_RXMODE_ALLMULTI)
+
+#define allmulti_enable(mode, bitmask) \
+ xxx_enable(mode, bitmask, BNA_RXMODE_ALLMULTI)
+
+#define allmulti_disable(mode, bitmask) \
+ xxx_disable(mode, bitmask, BNA_RXMODE_ALLMULTI)
+
+#define allmulti_inactive(mode, bitmask) \
+ xxx_inactive(mode, bitmask, BNA_RXMODE_ALLMULTI)
+
+#define GET_RXQS(rxp, q0, q1) do { \
+ switch ((rxp)->type) { \
+ case BNA_RXP_SINGLE: \
+ (q0) = rxp->rxq.single.only; \
+ (q1) = NULL; \
+ break; \
+ case BNA_RXP_SLR: \
+ (q0) = rxp->rxq.slr.large; \
+ (q1) = rxp->rxq.slr.small; \
+ break; \
+ case BNA_RXP_HDS: \
+ (q0) = rxp->rxq.hds.data; \
+ (q1) = rxp->rxq.hds.hdr; \
+ break; \
+ } \
+} while (0)
+
+/**
+ *
+ * Function prototypes
+ *
+ */
+
+/**
+ * BNA
+ */
+
+/* APIs for BNAD */
+void bna_res_req(struct bna_res_info *res_info);
+void bna_init(struct bna *bna, struct bnad *bnad,
+ struct bfa_pcidev *pcidev,
+ struct bna_res_info *res_info);
+void bna_uninit(struct bna *bna);
+void bna_stats_get(struct bna *bna);
+void bna_get_perm_mac(struct bna *bna, u8 *mac);
+
+/* APIs for Rx */
+int bna_rit_mod_can_satisfy(struct bna_rit_mod *rit_mod, int seg_size);
+
+/* APIs for RxF */
+struct bna_mac *bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod);
+void bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod,
+ struct bna_mac *mac);
+struct bna_mac *bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod);
+void bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod,
+ struct bna_mac *mac);
+struct bna_rit_segment *
+bna_rit_mod_seg_get(struct bna_rit_mod *rit_mod, int seg_size);
+void bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod,
+ struct bna_rit_segment *seg);
+
+/**
+ * DEVICE
+ */
+
+/* APIs for BNAD */
+void bna_device_enable(struct bna_device *device);
+void bna_device_disable(struct bna_device *device,
+ enum bna_cleanup_type type);
+
+/**
+ * MBOX
+ */
+
+/* APIs for PORT, TX, RX */
+void bna_mbox_handler(struct bna *bna, u32 intr_status);
+void bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe);
+
+/**
+ * PORT
+ */
+
+/* API for RX */
+int bna_port_mtu_get(struct bna_port *port);
+void bna_llport_admin_up(struct bna_llport *llport);
+void bna_llport_admin_down(struct bna_llport *llport);
+
+/* API for BNAD */
+void bna_port_enable(struct bna_port *port);
+void bna_port_disable(struct bna_port *port, enum bna_cleanup_type type,
+ void (*cbfn)(void *, enum bna_cb_status));
+void bna_port_pause_config(struct bna_port *port,
+ struct bna_pause_config *pause_config,
+ void (*cbfn)(struct bnad *, enum bna_cb_status));
+void bna_port_mtu_set(struct bna_port *port, int mtu,
+ void (*cbfn)(struct bnad *, enum bna_cb_status));
+void bna_port_mac_get(struct bna_port *port, mac_t *mac);
+
+/* Callbacks for TX, RX */
+void bna_port_cb_tx_stopped(struct bna_port *port,
+ enum bna_cb_status status);
+void bna_port_cb_rx_stopped(struct bna_port *port,
+ enum bna_cb_status status);
+
+/**
+ * IB
+ */
+
+/* APIs for BNA */
+void bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna,
+ struct bna_res_info *res_info);
+void bna_ib_mod_uninit(struct bna_ib_mod *ib_mod);
+
+/**
+ * TX MODULE AND TX
+ */
+
+/* APIs for BNA */
+void bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna,
+ struct bna_res_info *res_info);
+void bna_tx_mod_uninit(struct bna_tx_mod *tx_mod);
+int bna_tx_state_get(struct bna_tx *tx);
+
+/* APIs for PORT */
+void bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type);
+void bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type);
+void bna_tx_mod_fail(struct bna_tx_mod *tx_mod);
+void bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio);
+void bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link);
+
+/* APIs for BNAD */
+void bna_tx_res_req(int num_txq, int txq_depth,
+ struct bna_res_info *res_info);
+struct bna_tx *bna_tx_create(struct bna *bna, struct bnad *bnad,
+ struct bna_tx_config *tx_cfg,
+ struct bna_tx_event_cbfn *tx_cbfn,
+ struct bna_res_info *res_info, void *priv);
+void bna_tx_destroy(struct bna_tx *tx);
+void bna_tx_enable(struct bna_tx *tx);
+void bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type,
+ void (*cbfn)(void *, struct bna_tx *,
+ enum bna_cb_status));
+void bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo);
+
+/**
+ * RX MODULE, RX, RXF
+ */
+
+/* Internal APIs */
+void rxf_cb_cam_fltr_mbox_cmd(void *arg, int status);
+void rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd,
+ const struct bna_mac *mac_addr);
+void __rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status);
+void bna_rxf_adv_init(struct bna_rxf *rxf,
+ struct bna_rx *rx,
+ struct bna_rx_config *q_config);
+int rxf_process_packet_filter_ucast(struct bna_rxf *rxf);
+int rxf_process_packet_filter_promisc(struct bna_rxf *rxf);
+int rxf_process_packet_filter_default(struct bna_rxf *rxf);
+int rxf_process_packet_filter_allmulti(struct bna_rxf *rxf);
+int rxf_clear_packet_filter_ucast(struct bna_rxf *rxf);
+int rxf_clear_packet_filter_promisc(struct bna_rxf *rxf);
+int rxf_clear_packet_filter_default(struct bna_rxf *rxf);
+int rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf);
+void rxf_reset_packet_filter_ucast(struct bna_rxf *rxf);
+void rxf_reset_packet_filter_promisc(struct bna_rxf *rxf);
+void rxf_reset_packet_filter_default(struct bna_rxf *rxf);
+void rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf);
+
+/* APIs for BNA */
+void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna,
+ struct bna_res_info *res_info);
+void bna_rx_mod_uninit(struct bna_rx_mod *rx_mod);
+int bna_rx_state_get(struct bna_rx *rx);
+int bna_rxf_state_get(struct bna_rxf *rxf);
+
+/* APIs for PORT */
+void bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type);
+void bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type);
+void bna_rx_mod_fail(struct bna_rx_mod *rx_mod);
+
+/* APIs for BNAD */
+void bna_rx_res_req(struct bna_rx_config *rx_config,
+ struct bna_res_info *res_info);
+struct bna_rx *bna_rx_create(struct bna *bna, struct bnad *bnad,
+ struct bna_rx_config *rx_cfg,
+ struct bna_rx_event_cbfn *rx_cbfn,
+ struct bna_res_info *res_info, void *priv);
+void bna_rx_destroy(struct bna_rx *rx);
+void bna_rx_enable(struct bna_rx *rx);
+void bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type,
+ void (*cbfn)(void *, struct bna_rx *,
+ enum bna_cb_status));
+void bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo);
+void bna_rx_dim_reconfig(struct bna *bna, const u32 vector[][BNA_BIAS_T_MAX]);
+void bna_rx_dim_update(struct bna_ccb *ccb);
+enum bna_cb_status
+bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+enum bna_cb_status
+bna_rx_mcast_add(struct bna_rx *rx, u8 *mcmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+enum bna_cb_status
+bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mcmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+enum bna_cb_status
+bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode rxmode,
+ enum bna_rxmode bitmask,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+void bna_rx_vlan_add(struct bna_rx *rx, int vlan_id);
+void bna_rx_vlan_del(struct bna_rx *rx, int vlan_id);
+void bna_rx_vlanfilter_enable(struct bna_rx *rx);
+void bna_rx_hds_enable(struct bna_rx *rx, struct bna_rxf_hds *hds_config,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+void bna_rx_hds_disable(struct bna_rx *rx,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+
+/**
+ * BNAD
+ */
+
+/* Callbacks for BNA */
+void bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status,
+ struct bna_stats *stats);
+
+/* Callbacks for DEVICE */
+void bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status);
+void bnad_cb_device_disabled(struct bnad *bnad, enum bna_cb_status status);
+void bnad_cb_device_enable_mbox_intr(struct bnad *bnad);
+void bnad_cb_device_disable_mbox_intr(struct bnad *bnad);
+
+/* Callbacks for port */
+void bnad_cb_port_link_status(struct bnad *bnad,
+ enum bna_link_status status);
+
+#endif /* __BNA_H__ */
diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c
new file mode 100644
index 000000000000..07b26598546e
--- /dev/null
+++ b/drivers/net/bna/bna_ctrl.c
@@ -0,0 +1,3261 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#include "bna.h"
+#include "bfa_sm.h"
+#include "bfa_wc.h"
+
+static void bna_device_cb_port_stopped(void *arg, enum bna_cb_status status);
+
+static void
+bna_port_cb_link_up(struct bna_port *port, struct bfi_ll_aen *aen,
+ int status)
+{
+ int i;
+ u8 prio_map;
+
+ port->llport.link_status = BNA_LINK_UP;
+ if (aen->cee_linkup)
+ port->llport.link_status = BNA_CEE_UP;
+
+ /* Compute the priority */
+ prio_map = aen->prio_map;
+ if (prio_map) {
+ for (i = 0; i < 8; i++) {
+ if ((prio_map >> i) & 0x1)
+ break;
+ }
+ port->priority = i;
+ } else
+ port->priority = 0;
+
+ /* Dispatch events */
+ bna_tx_mod_cee_link_status(&port->bna->tx_mod, aen->cee_linkup);
+ bna_tx_mod_prio_changed(&port->bna->tx_mod, port->priority);
+ port->link_cbfn(port->bna->bnad, port->llport.link_status);
+}
+
+static void
+bna_port_cb_link_down(struct bna_port *port, int status)
+{
+ port->llport.link_status = BNA_LINK_DOWN;
+
+ /* Dispatch events */
+ bna_tx_mod_cee_link_status(&port->bna->tx_mod, BNA_LINK_DOWN);
+ port->link_cbfn(port->bna->bnad, BNA_LINK_DOWN);
+}
+
+/**
+ * MBOX
+ */
+static int
+bna_is_aen(u8 msg_id)
+{
+ return msg_id == BFI_LL_I2H_LINK_DOWN_AEN ||
+ msg_id == BFI_LL_I2H_LINK_UP_AEN;
+}
+
+static void
+bna_mbox_aen_callback(struct bna *bna, struct bfi_mbmsg *msg)
+{
+ struct bfi_ll_aen *aen = (struct bfi_ll_aen *)(msg);
+
+ switch (aen->mh.msg_id) {
+ case BFI_LL_I2H_LINK_UP_AEN:
+ bna_port_cb_link_up(&bna->port, aen, aen->reason);
+ break;
+ case BFI_LL_I2H_LINK_DOWN_AEN:
+ bna_port_cb_link_down(&bna->port, aen->reason);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+bna_ll_isr(void *llarg, struct bfi_mbmsg *msg)
+{
+ struct bna *bna = (struct bna *)(llarg);
+ struct bfi_ll_rsp *mb_rsp = (struct bfi_ll_rsp *)(msg);
+ struct bfi_mhdr *cmd_h, *rsp_h;
+ struct bna_mbox_qe *mb_qe = NULL;
+ int to_post = 0;
+ u8 aen = 0;
+ char message[BNA_MESSAGE_SIZE];
+
+ aen = bna_is_aen(mb_rsp->mh.msg_id);
+
+ if (!aen) {
+ mb_qe = bfa_q_first(&bna->mbox_mod.posted_q);
+ cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]);
+ rsp_h = (struct bfi_mhdr *)(&mb_rsp->mh);
+
+ if ((BFA_I2HM(cmd_h->msg_id) == rsp_h->msg_id) &&
+ (cmd_h->mtag.i2htok == rsp_h->mtag.i2htok)) {
+ /* Remove the request from posted_q, update state */
+ list_del(&mb_qe->qe);
+ bna->mbox_mod.msg_pending--;
+ if (list_empty(&bna->mbox_mod.posted_q))
+ bna->mbox_mod.state = BNA_MBOX_FREE;
+ else
+ to_post = 1;
+
+ /* Dispatch the cbfn */
+ if (mb_qe->cbfn)
+ mb_qe->cbfn(mb_qe->cbarg, mb_rsp->error);
+
+ /* Post the next entry, if needed */
+ if (to_post) {
+ mb_qe = bfa_q_first(&bna->mbox_mod.posted_q);
+ bfa_nw_ioc_mbox_queue(&bna->device.ioc,
+ &mb_qe->cmd);
+ }
+ } else {
+ snprintf(message, BNA_MESSAGE_SIZE,
+ "No matching rsp for [%d:%d:%d]\n",
+ mb_rsp->mh.msg_class, mb_rsp->mh.msg_id,
+ mb_rsp->mh.mtag.i2htok);
+ pr_info("%s", message);
+ }
+
+ } else
+ bna_mbox_aen_callback(bna, msg);
+}
+
+static void
+bna_err_handler(struct bna *bna, u32 intr_status)
+{
+ u32 init_halt;
+
+ if (intr_status & __HALT_STATUS_BITS) {
+ init_halt = readl(bna->device.ioc.ioc_regs.ll_halt);
+ init_halt &= ~__FW_INIT_HALT_P;
+ writel(init_halt, bna->device.ioc.ioc_regs.ll_halt);
+ }
+
+ bfa_nw_ioc_error_isr(&bna->device.ioc);
+}
+
+void
+bna_mbox_handler(struct bna *bna, u32 intr_status)
+{
+ if (BNA_IS_ERR_INTR(intr_status)) {
+ bna_err_handler(bna, intr_status);
+ return;
+ }
+ if (BNA_IS_MBOX_INTR(intr_status))
+ bfa_nw_ioc_mbox_isr(&bna->device.ioc);
+}
+
+void
+bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe)
+{
+ struct bfi_mhdr *mh;
+
+ mh = (struct bfi_mhdr *)(&mbox_qe->cmd.msg[0]);
+
+ mh->mtag.i2htok = htons(bna->mbox_mod.msg_ctr);
+ bna->mbox_mod.msg_ctr++;
+ bna->mbox_mod.msg_pending++;
+ if (bna->mbox_mod.state == BNA_MBOX_FREE) {
+ list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q);
+ bfa_nw_ioc_mbox_queue(&bna->device.ioc, &mbox_qe->cmd);
+ bna->mbox_mod.state = BNA_MBOX_POSTED;
+ } else {
+ list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q);
+ }
+}
+
+static void
+bna_mbox_flush_q(struct bna *bna, struct list_head *q)
+{
+ struct bna_mbox_qe *mb_qe = NULL;
+ struct bfi_mhdr *cmd_h;
+ struct list_head *mb_q;
+ void (*cbfn)(void *arg, int status);
+ void *cbarg;
+
+ mb_q = &bna->mbox_mod.posted_q;
+
+ while (!list_empty(mb_q)) {
+ bfa_q_deq(mb_q, &mb_qe);
+ cbfn = mb_qe->cbfn;
+ cbarg = mb_qe->cbarg;
+ bfa_q_qe_init(mb_qe);
+ bna->mbox_mod.msg_pending--;
+
+ cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]);
+ if (cbfn)
+ cbfn(cbarg, BNA_CB_NOT_EXEC);
+ }
+
+ bna->mbox_mod.state = BNA_MBOX_FREE;
+}
+
+static void
+bna_mbox_mod_start(struct bna_mbox_mod *mbox_mod)
+{
+}
+
+static void
+bna_mbox_mod_stop(struct bna_mbox_mod *mbox_mod)
+{
+ bna_mbox_flush_q(mbox_mod->bna, &mbox_mod->posted_q);
+}
+
+static void
+bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna)
+{
+ bfa_nw_ioc_mbox_regisr(&bna->device.ioc, BFI_MC_LL, bna_ll_isr, bna);
+ mbox_mod->state = BNA_MBOX_FREE;
+ mbox_mod->msg_ctr = mbox_mod->msg_pending = 0;
+ INIT_LIST_HEAD(&mbox_mod->posted_q);
+ mbox_mod->bna = bna;
+}
+
+static void
+bna_mbox_mod_uninit(struct bna_mbox_mod *mbox_mod)
+{
+ mbox_mod->bna = NULL;
+}
+
+/**
+ * LLPORT
+ */
+#define call_llport_stop_cbfn(llport, status)\
+do {\
+ if ((llport)->stop_cbfn)\
+ (llport)->stop_cbfn(&(llport)->bna->port, status);\
+ (llport)->stop_cbfn = NULL;\
+} while (0)
+
+static void bna_fw_llport_up(struct bna_llport *llport);
+static void bna_fw_cb_llport_up(void *arg, int status);
+static void bna_fw_llport_down(struct bna_llport *llport);
+static void bna_fw_cb_llport_down(void *arg, int status);
+static void bna_llport_start(struct bna_llport *llport);
+static void bna_llport_stop(struct bna_llport *llport);
+static void bna_llport_fail(struct bna_llport *llport);
+
+enum bna_llport_event {
+ LLPORT_E_START = 1,
+ LLPORT_E_STOP = 2,
+ LLPORT_E_FAIL = 3,
+ LLPORT_E_UP = 4,
+ LLPORT_E_DOWN = 5,
+ LLPORT_E_FWRESP_UP = 6,
+ LLPORT_E_FWRESP_DOWN = 7
+};
+
+enum bna_llport_state {
+ BNA_LLPORT_STOPPED = 1,
+ BNA_LLPORT_DOWN = 2,
+ BNA_LLPORT_UP_RESP_WAIT = 3,
+ BNA_LLPORT_DOWN_RESP_WAIT = 4,
+ BNA_LLPORT_UP = 5,
+ BNA_LLPORT_LAST_RESP_WAIT = 6
+};
+
+bfa_fsm_state_decl(bna_llport, stopped, struct bna_llport,
+ enum bna_llport_event);
+bfa_fsm_state_decl(bna_llport, down, struct bna_llport,
+ enum bna_llport_event);
+bfa_fsm_state_decl(bna_llport, up_resp_wait, struct bna_llport,
+ enum bna_llport_event);
+bfa_fsm_state_decl(bna_llport, down_resp_wait, struct bna_llport,
+ enum bna_llport_event);
+bfa_fsm_state_decl(bna_llport, up, struct bna_llport,
+ enum bna_llport_event);
+bfa_fsm_state_decl(bna_llport, last_resp_wait, struct bna_llport,
+ enum bna_llport_event);
+
+static struct bfa_sm_table llport_sm_table[] = {
+ {BFA_SM(bna_llport_sm_stopped), BNA_LLPORT_STOPPED},
+ {BFA_SM(bna_llport_sm_down), BNA_LLPORT_DOWN},
+ {BFA_SM(bna_llport_sm_up_resp_wait), BNA_LLPORT_UP_RESP_WAIT},
+ {BFA_SM(bna_llport_sm_down_resp_wait), BNA_LLPORT_DOWN_RESP_WAIT},
+ {BFA_SM(bna_llport_sm_up), BNA_LLPORT_UP},
+ {BFA_SM(bna_llport_sm_last_resp_wait), BNA_LLPORT_LAST_RESP_WAIT}
+};
+
+static void
+bna_llport_sm_stopped_entry(struct bna_llport *llport)
+{
+ llport->bna->port.link_cbfn((llport)->bna->bnad, BNA_LINK_DOWN);
+ call_llport_stop_cbfn(llport, BNA_CB_SUCCESS);
+}
+
+static void
+bna_llport_sm_stopped(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_START:
+ bfa_fsm_set_state(llport, bna_llport_sm_down);
+ break;
+
+ case LLPORT_E_STOP:
+ call_llport_stop_cbfn(llport, BNA_CB_SUCCESS);
+ break;
+
+ case LLPORT_E_FAIL:
+ break;
+
+ case LLPORT_E_DOWN:
+ /* This event is received due to Rx objects failing */
+ /* No-op */
+ break;
+
+ case LLPORT_E_FWRESP_UP:
+ case LLPORT_E_FWRESP_DOWN:
+ /**
+ * These events are received due to flushing of mbox when
+ * device fails
+ */
+ /* No-op */
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_llport_sm_down_entry(struct bna_llport *llport)
+{
+ bnad_cb_port_link_status((llport)->bna->bnad, BNA_LINK_DOWN);
+}
+
+static void
+bna_llport_sm_down(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_STOP:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_UP:
+ bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait);
+ bna_fw_llport_up(llport);
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_llport_sm_up_resp_wait_entry(struct bna_llport *llport)
+{
+ /**
+ * NOTE: Do not call bna_fw_llport_up() here. That will over step
+ * mbox due to down_resp_wait -> up_resp_wait transition on event
+ * LLPORT_E_UP
+ */
+}
+
+static void
+bna_llport_sm_up_resp_wait(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_STOP:
+ bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait);
+ break;
+
+ case LLPORT_E_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_DOWN:
+ bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait);
+ break;
+
+ case LLPORT_E_FWRESP_UP:
+ bfa_fsm_set_state(llport, bna_llport_sm_up);
+ break;
+
+ case LLPORT_E_FWRESP_DOWN:
+ /* down_resp_wait -> up_resp_wait transition on LLPORT_E_UP */
+ bna_fw_llport_up(llport);
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_llport_sm_down_resp_wait_entry(struct bna_llport *llport)
+{
+ /**
+ * NOTE: Do not call bna_fw_llport_down() here. That will over step
+ * mbox due to up_resp_wait -> down_resp_wait transition on event
+ * LLPORT_E_DOWN
+ */
+}
+
+static void
+bna_llport_sm_down_resp_wait(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_STOP:
+ bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait);
+ break;
+
+ case LLPORT_E_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_UP:
+ bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait);
+ break;
+
+ case LLPORT_E_FWRESP_UP:
+ /* up_resp_wait->down_resp_wait transition on LLPORT_E_DOWN */
+ bna_fw_llport_down(llport);
+ break;
+
+ case LLPORT_E_FWRESP_DOWN:
+ bfa_fsm_set_state(llport, bna_llport_sm_down);
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_llport_sm_up_entry(struct bna_llport *llport)
+{
+}
+
+static void
+bna_llport_sm_up(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_STOP:
+ bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait);
+ bna_fw_llport_down(llport);
+ break;
+
+ case LLPORT_E_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_DOWN:
+ bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait);
+ bna_fw_llport_down(llport);
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_llport_sm_last_resp_wait_entry(struct bna_llport *llport)
+{
+}
+
+static void
+bna_llport_sm_last_resp_wait(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_DOWN:
+ /**
+ * This event is received due to Rx objects stopping in
+ * parallel to llport
+ */
+ /* No-op */
+ break;
+
+ case LLPORT_E_FWRESP_UP:
+ /* up_resp_wait->last_resp_wait transition on LLPORT_T_STOP */
+ bna_fw_llport_down(llport);
+ break;
+
+ case LLPORT_E_FWRESP_DOWN:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_fw_llport_admin_up(struct bna_llport *llport)
+{
+ struct bfi_ll_port_admin_req ll_req;
+
+ memset(&ll_req, 0, sizeof(ll_req));
+ ll_req.mh.msg_class = BFI_MC_LL;
+ ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ;
+ ll_req.mh.mtag.h2i.lpu_id = 0;
+
+ ll_req.up = BNA_STATUS_T_ENABLED;
+
+ bna_mbox_qe_fill(&llport->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_llport_up, llport);
+
+ bna_mbox_send(llport->bna, &llport->mbox_qe);
+}
+
+static void
+bna_fw_llport_up(struct bna_llport *llport)
+{
+ if (llport->type == BNA_PORT_T_REGULAR)
+ bna_fw_llport_admin_up(llport);
+}
+
+static void
+bna_fw_cb_llport_up(void *arg, int status)
+{
+ struct bna_llport *llport = (struct bna_llport *)arg;
+
+ bfa_q_qe_init(&llport->mbox_qe.qe);
+ bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP);
+}
+
+static void
+bna_fw_llport_admin_down(struct bna_llport *llport)
+{
+ struct bfi_ll_port_admin_req ll_req;
+
+ memset(&ll_req, 0, sizeof(ll_req));
+ ll_req.mh.msg_class = BFI_MC_LL;
+ ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ;
+ ll_req.mh.mtag.h2i.lpu_id = 0;
+
+ ll_req.up = BNA_STATUS_T_DISABLED;
+
+ bna_mbox_qe_fill(&llport->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_llport_down, llport);
+
+ bna_mbox_send(llport->bna, &llport->mbox_qe);
+}
+
+static void
+bna_fw_llport_down(struct bna_llport *llport)
+{
+ if (llport->type == BNA_PORT_T_REGULAR)
+ bna_fw_llport_admin_down(llport);
+}
+
+static void
+bna_fw_cb_llport_down(void *arg, int status)
+{
+ struct bna_llport *llport = (struct bna_llport *)arg;
+
+ bfa_q_qe_init(&llport->mbox_qe.qe);
+ bfa_fsm_send_event(llport, LLPORT_E_FWRESP_DOWN);
+}
+
+static void
+bna_port_cb_llport_stopped(struct bna_port *port,
+ enum bna_cb_status status)
+{
+ bfa_wc_down(&port->chld_stop_wc);
+}
+
+static void
+bna_llport_init(struct bna_llport *llport, struct bna *bna)
+{
+ llport->flags |= BNA_LLPORT_F_ENABLED;
+ llport->type = BNA_PORT_T_REGULAR;
+ llport->bna = bna;
+
+ llport->link_status = BNA_LINK_DOWN;
+
+ llport->admin_up_count = 0;
+
+ llport->stop_cbfn = NULL;
+
+ bfa_q_qe_init(&llport->mbox_qe.qe);
+
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+}
+
+static void
+bna_llport_uninit(struct bna_llport *llport)
+{
+ llport->flags &= ~BNA_LLPORT_F_ENABLED;
+
+ llport->bna = NULL;
+}
+
+static void
+bna_llport_start(struct bna_llport *llport)
+{
+ bfa_fsm_send_event(llport, LLPORT_E_START);
+}
+
+static void
+bna_llport_stop(struct bna_llport *llport)
+{
+ llport->stop_cbfn = bna_port_cb_llport_stopped;
+
+ bfa_fsm_send_event(llport, LLPORT_E_STOP);
+}
+
+static void
+bna_llport_fail(struct bna_llport *llport)
+{
+ bfa_fsm_send_event(llport, LLPORT_E_FAIL);
+}
+
+static int
+bna_llport_state_get(struct bna_llport *llport)
+{
+ return bfa_sm_to_state(llport_sm_table, llport->fsm);
+}
+
+void
+bna_llport_admin_up(struct bna_llport *llport)
+{
+ llport->admin_up_count++;
+
+ if (llport->admin_up_count == 1) {
+ llport->flags |= BNA_LLPORT_F_RX_ENABLED;
+ if (llport->flags & BNA_LLPORT_F_ENABLED)
+ bfa_fsm_send_event(llport, LLPORT_E_UP);
+ }
+}
+
+void
+bna_llport_admin_down(struct bna_llport *llport)
+{
+ llport->admin_up_count--;
+
+ if (llport->admin_up_count == 0) {
+ llport->flags &= ~BNA_LLPORT_F_RX_ENABLED;
+ if (llport->flags & BNA_LLPORT_F_ENABLED)
+ bfa_fsm_send_event(llport, LLPORT_E_DOWN);
+ }
+}
+
+/**
+ * PORT
+ */
+#define bna_port_chld_start(port)\
+do {\
+ enum bna_tx_type tx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;\
+ enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
+ bna_llport_start(&(port)->llport);\
+ bna_tx_mod_start(&(port)->bna->tx_mod, tx_type);\
+ bna_rx_mod_start(&(port)->bna->rx_mod, rx_type);\
+} while (0)
+
+#define bna_port_chld_stop(port)\
+do {\
+ enum bna_tx_type tx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;\
+ enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
+ bfa_wc_up(&(port)->chld_stop_wc);\
+ bfa_wc_up(&(port)->chld_stop_wc);\
+ bfa_wc_up(&(port)->chld_stop_wc);\
+ bna_llport_stop(&(port)->llport);\
+ bna_tx_mod_stop(&(port)->bna->tx_mod, tx_type);\
+ bna_rx_mod_stop(&(port)->bna->rx_mod, rx_type);\
+} while (0)
+
+#define bna_port_chld_fail(port)\
+do {\
+ bna_llport_fail(&(port)->llport);\
+ bna_tx_mod_fail(&(port)->bna->tx_mod);\
+ bna_rx_mod_fail(&(port)->bna->rx_mod);\
+} while (0)
+
+#define bna_port_rx_start(port)\
+do {\
+ enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
+ bna_rx_mod_start(&(port)->bna->rx_mod, rx_type);\
+} while (0)
+
+#define bna_port_rx_stop(port)\
+do {\
+ enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
+ bfa_wc_up(&(port)->chld_stop_wc);\
+ bna_rx_mod_stop(&(port)->bna->rx_mod, rx_type);\
+} while (0)
+
+#define call_port_stop_cbfn(port, status)\
+do {\
+ if ((port)->stop_cbfn)\
+ (port)->stop_cbfn((port)->stop_cbarg, status);\
+ (port)->stop_cbfn = NULL;\
+ (port)->stop_cbarg = NULL;\
+} while (0)
+
+#define call_port_pause_cbfn(port, status)\
+do {\
+ if ((port)->pause_cbfn)\
+ (port)->pause_cbfn((port)->bna->bnad, status);\
+ (port)->pause_cbfn = NULL;\
+} while (0)
+
+#define call_port_mtu_cbfn(port, status)\
+do {\
+ if ((port)->mtu_cbfn)\
+ (port)->mtu_cbfn((port)->bna->bnad, status);\
+ (port)->mtu_cbfn = NULL;\
+} while (0)
+
+static void bna_fw_pause_set(struct bna_port *port);
+static void bna_fw_cb_pause_set(void *arg, int status);
+static void bna_fw_mtu_set(struct bna_port *port);
+static void bna_fw_cb_mtu_set(void *arg, int status);
+
+enum bna_port_event {
+ PORT_E_START = 1,
+ PORT_E_STOP = 2,
+ PORT_E_FAIL = 3,
+ PORT_E_PAUSE_CFG = 4,
+ PORT_E_MTU_CFG = 5,
+ PORT_E_CHLD_STOPPED = 6,
+ PORT_E_FWRESP_PAUSE = 7,
+ PORT_E_FWRESP_MTU = 8
+};
+
+enum bna_port_state {
+ BNA_PORT_STOPPED = 1,
+ BNA_PORT_MTU_INIT_WAIT = 2,
+ BNA_PORT_PAUSE_INIT_WAIT = 3,
+ BNA_PORT_LAST_RESP_WAIT = 4,
+ BNA_PORT_STARTED = 5,
+ BNA_PORT_PAUSE_CFG_WAIT = 6,
+ BNA_PORT_RX_STOP_WAIT = 7,
+ BNA_PORT_MTU_CFG_WAIT = 8,
+ BNA_PORT_CHLD_STOP_WAIT = 9
+};
+
+bfa_fsm_state_decl(bna_port, stopped, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, mtu_init_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, pause_init_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, last_resp_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, started, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, pause_cfg_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, rx_stop_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, mtu_cfg_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, chld_stop_wait, struct bna_port,
+ enum bna_port_event);
+
+static struct bfa_sm_table port_sm_table[] = {
+ {BFA_SM(bna_port_sm_stopped), BNA_PORT_STOPPED},
+ {BFA_SM(bna_port_sm_mtu_init_wait), BNA_PORT_MTU_INIT_WAIT},
+ {BFA_SM(bna_port_sm_pause_init_wait), BNA_PORT_PAUSE_INIT_WAIT},
+ {BFA_SM(bna_port_sm_last_resp_wait), BNA_PORT_LAST_RESP_WAIT},
+ {BFA_SM(bna_port_sm_started), BNA_PORT_STARTED},
+ {BFA_SM(bna_port_sm_pause_cfg_wait), BNA_PORT_PAUSE_CFG_WAIT},
+ {BFA_SM(bna_port_sm_rx_stop_wait), BNA_PORT_RX_STOP_WAIT},
+ {BFA_SM(bna_port_sm_mtu_cfg_wait), BNA_PORT_MTU_CFG_WAIT},
+ {BFA_SM(bna_port_sm_chld_stop_wait), BNA_PORT_CHLD_STOP_WAIT}
+};
+
+static void
+bna_port_sm_stopped_entry(struct bna_port *port)
+{
+ call_port_pause_cbfn(port, BNA_CB_SUCCESS);
+ call_port_mtu_cbfn(port, BNA_CB_SUCCESS);
+ call_port_stop_cbfn(port, BNA_CB_SUCCESS);
+}
+
+static void
+bna_port_sm_stopped(struct bna_port *port, enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_START:
+ bfa_fsm_set_state(port, bna_port_sm_mtu_init_wait);
+ break;
+
+ case PORT_E_STOP:
+ call_port_stop_cbfn(port, BNA_CB_SUCCESS);
+ break;
+
+ case PORT_E_FAIL:
+ /* No-op */
+ break;
+
+ case PORT_E_PAUSE_CFG:
+ call_port_pause_cbfn(port, BNA_CB_SUCCESS);
+ break;
+
+ case PORT_E_MTU_CFG:
+ call_port_mtu_cbfn(port, BNA_CB_SUCCESS);
+ break;
+
+ case PORT_E_CHLD_STOPPED:
+ /**
+ * This event is received due to LLPort, Tx and Rx objects
+ * failing
+ */
+ /* No-op */
+ break;
+
+ case PORT_E_FWRESP_PAUSE:
+ case PORT_E_FWRESP_MTU:
+ /**
+ * These events are received due to flushing of mbox when
+ * device fails
+ */
+ /* No-op */
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_mtu_init_wait_entry(struct bna_port *port)
+{
+ bna_fw_mtu_set(port);
+}
+
+static void
+bna_port_sm_mtu_init_wait(struct bna_port *port, enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_STOP:
+ bfa_fsm_set_state(port, bna_port_sm_last_resp_wait);
+ break;
+
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ break;
+
+ case PORT_E_PAUSE_CFG:
+ /* No-op */
+ break;
+
+ case PORT_E_MTU_CFG:
+ port->flags |= BNA_PORT_F_MTU_CHANGED;
+ break;
+
+ case PORT_E_FWRESP_MTU:
+ if (port->flags & BNA_PORT_F_MTU_CHANGED) {
+ port->flags &= ~BNA_PORT_F_MTU_CHANGED;
+ bna_fw_mtu_set(port);
+ } else {
+ bfa_fsm_set_state(port, bna_port_sm_pause_init_wait);
+ }
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_pause_init_wait_entry(struct bna_port *port)
+{
+ bna_fw_pause_set(port);
+}
+
+static void
+bna_port_sm_pause_init_wait(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_STOP:
+ bfa_fsm_set_state(port, bna_port_sm_last_resp_wait);
+ break;
+
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ break;
+
+ case PORT_E_PAUSE_CFG:
+ port->flags |= BNA_PORT_F_PAUSE_CHANGED;
+ break;
+
+ case PORT_E_MTU_CFG:
+ port->flags |= BNA_PORT_F_MTU_CHANGED;
+ break;
+
+ case PORT_E_FWRESP_PAUSE:
+ if (port->flags & BNA_PORT_F_PAUSE_CHANGED) {
+ port->flags &= ~BNA_PORT_F_PAUSE_CHANGED;
+ bna_fw_pause_set(port);
+ } else if (port->flags & BNA_PORT_F_MTU_CHANGED) {
+ port->flags &= ~BNA_PORT_F_MTU_CHANGED;
+ bfa_fsm_set_state(port, bna_port_sm_mtu_init_wait);
+ } else {
+ bfa_fsm_set_state(port, bna_port_sm_started);
+ bna_port_chld_start(port);
+ }
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_last_resp_wait_entry(struct bna_port *port)
+{
+}
+
+static void
+bna_port_sm_last_resp_wait(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_FAIL:
+ case PORT_E_FWRESP_PAUSE:
+ case PORT_E_FWRESP_MTU:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_started_entry(struct bna_port *port)
+{
+ /**
+ * NOTE: Do not call bna_port_chld_start() here, since it will be
+ * inadvertently called during pause_cfg_wait->started transition
+ * as well
+ */
+ call_port_pause_cbfn(port, BNA_CB_SUCCESS);
+ call_port_mtu_cbfn(port, BNA_CB_SUCCESS);
+}
+
+static void
+bna_port_sm_started(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_STOP:
+ bfa_fsm_set_state(port, bna_port_sm_chld_stop_wait);
+ break;
+
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ bna_port_chld_fail(port);
+ break;
+
+ case PORT_E_PAUSE_CFG:
+ bfa_fsm_set_state(port, bna_port_sm_pause_cfg_wait);
+ break;
+
+ case PORT_E_MTU_CFG:
+ bfa_fsm_set_state(port, bna_port_sm_rx_stop_wait);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_pause_cfg_wait_entry(struct bna_port *port)
+{
+ bna_fw_pause_set(port);
+}
+
+static void
+bna_port_sm_pause_cfg_wait(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ bna_port_chld_fail(port);
+ break;
+
+ case PORT_E_FWRESP_PAUSE:
+ bfa_fsm_set_state(port, bna_port_sm_started);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_rx_stop_wait_entry(struct bna_port *port)
+{
+ bna_port_rx_stop(port);
+}
+
+static void
+bna_port_sm_rx_stop_wait(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ bna_port_chld_fail(port);
+ break;
+
+ case PORT_E_CHLD_STOPPED:
+ bfa_fsm_set_state(port, bna_port_sm_mtu_cfg_wait);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_mtu_cfg_wait_entry(struct bna_port *port)
+{
+ bna_fw_mtu_set(port);
+}
+
+static void
+bna_port_sm_mtu_cfg_wait(struct bna_port *port, enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ bna_port_chld_fail(port);
+ break;
+
+ case PORT_E_FWRESP_MTU:
+ bfa_fsm_set_state(port, bna_port_sm_started);
+ bna_port_rx_start(port);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_chld_stop_wait_entry(struct bna_port *port)
+{
+ bna_port_chld_stop(port);
+}
+
+static void
+bna_port_sm_chld_stop_wait(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ bna_port_chld_fail(port);
+ break;
+
+ case PORT_E_CHLD_STOPPED:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_fw_pause_set(struct bna_port *port)
+{
+ struct bfi_ll_set_pause_req ll_req;
+
+ memset(&ll_req, 0, sizeof(ll_req));
+ ll_req.mh.msg_class = BFI_MC_LL;
+ ll_req.mh.msg_id = BFI_LL_H2I_SET_PAUSE_REQ;
+ ll_req.mh.mtag.h2i.lpu_id = 0;
+
+ ll_req.tx_pause = port->pause_config.tx_pause;
+ ll_req.rx_pause = port->pause_config.rx_pause;
+
+ bna_mbox_qe_fill(&port->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_pause_set, port);
+
+ bna_mbox_send(port->bna, &port->mbox_qe);
+}
+
+static void
+bna_fw_cb_pause_set(void *arg, int status)
+{
+ struct bna_port *port = (struct bna_port *)arg;
+
+ bfa_q_qe_init(&port->mbox_qe.qe);
+ bfa_fsm_send_event(port, PORT_E_FWRESP_PAUSE);
+}
+
+void
+bna_fw_mtu_set(struct bna_port *port)
+{
+ struct bfi_ll_mtu_info_req ll_req;
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_MTU_INFO_REQ, 0);
+ ll_req.mtu = htons((u16)port->mtu);
+
+ bna_mbox_qe_fill(&port->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_mtu_set, port);
+ bna_mbox_send(port->bna, &port->mbox_qe);
+}
+
+void
+bna_fw_cb_mtu_set(void *arg, int status)
+{
+ struct bna_port *port = (struct bna_port *)arg;
+
+ bfa_q_qe_init(&port->mbox_qe.qe);
+ bfa_fsm_send_event(port, PORT_E_FWRESP_MTU);
+}
+
+static void
+bna_port_cb_chld_stopped(void *arg)
+{
+ struct bna_port *port = (struct bna_port *)arg;
+
+ bfa_fsm_send_event(port, PORT_E_CHLD_STOPPED);
+}
+
+static void
+bna_port_init(struct bna_port *port, struct bna *bna)
+{
+ port->bna = bna;
+ port->flags = 0;
+ port->mtu = 0;
+ port->type = BNA_PORT_T_REGULAR;
+
+ port->link_cbfn = bnad_cb_port_link_status;
+
+ port->chld_stop_wc.wc_resume = bna_port_cb_chld_stopped;
+ port->chld_stop_wc.wc_cbarg = port;
+ port->chld_stop_wc.wc_count = 0;
+
+ port->stop_cbfn = NULL;
+ port->stop_cbarg = NULL;
+
+ port->pause_cbfn = NULL;
+
+ port->mtu_cbfn = NULL;
+
+ bfa_q_qe_init(&port->mbox_qe.qe);
+
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+
+ bna_llport_init(&port->llport, bna);
+}
+
+static void
+bna_port_uninit(struct bna_port *port)
+{
+ bna_llport_uninit(&port->llport);
+
+ port->flags = 0;
+
+ port->bna = NULL;
+}
+
+static int
+bna_port_state_get(struct bna_port *port)
+{
+ return bfa_sm_to_state(port_sm_table, port->fsm);
+}
+
+static void
+bna_port_start(struct bna_port *port)
+{
+ port->flags |= BNA_PORT_F_DEVICE_READY;
+ if (port->flags & BNA_PORT_F_ENABLED)
+ bfa_fsm_send_event(port, PORT_E_START);
+}
+
+static void
+bna_port_stop(struct bna_port *port)
+{
+ port->stop_cbfn = bna_device_cb_port_stopped;
+ port->stop_cbarg = &port->bna->device;
+
+ port->flags &= ~BNA_PORT_F_DEVICE_READY;
+ bfa_fsm_send_event(port, PORT_E_STOP);
+}
+
+static void
+bna_port_fail(struct bna_port *port)
+{
+ port->flags &= ~BNA_PORT_F_DEVICE_READY;
+ bfa_fsm_send_event(port, PORT_E_FAIL);
+}
+
+void
+bna_port_cb_tx_stopped(struct bna_port *port, enum bna_cb_status status)
+{
+ bfa_wc_down(&port->chld_stop_wc);
+}
+
+void
+bna_port_cb_rx_stopped(struct bna_port *port, enum bna_cb_status status)
+{
+ bfa_wc_down(&port->chld_stop_wc);
+}
+
+int
+bna_port_mtu_get(struct bna_port *port)
+{
+ return port->mtu;
+}
+
+void
+bna_port_enable(struct bna_port *port)
+{
+ if (port->fsm != (bfa_sm_t)bna_port_sm_stopped)
+ return;
+
+ port->flags |= BNA_PORT_F_ENABLED;
+
+ if (port->flags & BNA_PORT_F_DEVICE_READY)
+ bfa_fsm_send_event(port, PORT_E_START);
+}
+
+void
+bna_port_disable(struct bna_port *port, enum bna_cleanup_type type,
+ void (*cbfn)(void *, enum bna_cb_status))
+{
+ if (type == BNA_SOFT_CLEANUP) {
+ (*cbfn)(port->bna->bnad, BNA_CB_SUCCESS);
+ return;
+ }
+
+ port->stop_cbfn = cbfn;
+ port->stop_cbarg = port->bna->bnad;
+
+ port->flags &= ~BNA_PORT_F_ENABLED;
+
+ bfa_fsm_send_event(port, PORT_E_STOP);
+}
+
+void
+bna_port_pause_config(struct bna_port *port,
+ struct bna_pause_config *pause_config,
+ void (*cbfn)(struct bnad *, enum bna_cb_status))
+{
+ port->pause_config = *pause_config;
+
+ port->pause_cbfn = cbfn;
+
+ bfa_fsm_send_event(port, PORT_E_PAUSE_CFG);
+}
+
+void
+bna_port_mtu_set(struct bna_port *port, int mtu,
+ void (*cbfn)(struct bnad *, enum bna_cb_status))
+{
+ port->mtu = mtu;
+
+ port->mtu_cbfn = cbfn;
+
+ bfa_fsm_send_event(port, PORT_E_MTU_CFG);
+}
+
+void
+bna_port_mac_get(struct bna_port *port, mac_t *mac)
+{
+ *mac = bfa_nw_ioc_get_mac(&port->bna->device.ioc);
+}
+
+/**
+ * DEVICE
+ */
+#define enable_mbox_intr(_device)\
+do {\
+ u32 intr_status;\
+ bna_intr_status_get((_device)->bna, intr_status);\
+ bnad_cb_device_enable_mbox_intr((_device)->bna->bnad);\
+ bna_mbox_intr_enable((_device)->bna);\
+} while (0)
+
+#define disable_mbox_intr(_device)\
+do {\
+ bna_mbox_intr_disable((_device)->bna);\
+ bnad_cb_device_disable_mbox_intr((_device)->bna->bnad);\
+} while (0)
+
+static const struct bna_chip_regs_offset reg_offset[] =
+{{HOST_PAGE_NUM_FN0, HOSTFN0_INT_STATUS,
+ HOSTFN0_INT_MASK, HOST_MSIX_ERR_INDEX_FN0},
+{HOST_PAGE_NUM_FN1, HOSTFN1_INT_STATUS,
+ HOSTFN1_INT_MASK, HOST_MSIX_ERR_INDEX_FN1},
+{HOST_PAGE_NUM_FN2, HOSTFN2_INT_STATUS,
+ HOSTFN2_INT_MASK, HOST_MSIX_ERR_INDEX_FN2},
+{HOST_PAGE_NUM_FN3, HOSTFN3_INT_STATUS,
+ HOSTFN3_INT_MASK, HOST_MSIX_ERR_INDEX_FN3},
+};
+
+enum bna_device_event {
+ DEVICE_E_ENABLE = 1,
+ DEVICE_E_DISABLE = 2,
+ DEVICE_E_IOC_READY = 3,
+ DEVICE_E_IOC_FAILED = 4,
+ DEVICE_E_IOC_DISABLED = 5,
+ DEVICE_E_IOC_RESET = 6,
+ DEVICE_E_PORT_STOPPED = 7,
+};
+
+enum bna_device_state {
+ BNA_DEVICE_STOPPED = 1,
+ BNA_DEVICE_IOC_READY_WAIT = 2,
+ BNA_DEVICE_READY = 3,
+ BNA_DEVICE_PORT_STOP_WAIT = 4,
+ BNA_DEVICE_IOC_DISABLE_WAIT = 5,
+ BNA_DEVICE_FAILED = 6
+};
+
+bfa_fsm_state_decl(bna_device, stopped, struct bna_device,
+ enum bna_device_event);
+bfa_fsm_state_decl(bna_device, ioc_ready_wait, struct bna_device,
+ enum bna_device_event);
+bfa_fsm_state_decl(bna_device, ready, struct bna_device,
+ enum bna_device_event);
+bfa_fsm_state_decl(bna_device, port_stop_wait, struct bna_device,
+ enum bna_device_event);
+bfa_fsm_state_decl(bna_device, ioc_disable_wait, struct bna_device,
+ enum bna_device_event);
+bfa_fsm_state_decl(bna_device, failed, struct bna_device,
+ enum bna_device_event);
+
+static struct bfa_sm_table device_sm_table[] = {
+ {BFA_SM(bna_device_sm_stopped), BNA_DEVICE_STOPPED},
+ {BFA_SM(bna_device_sm_ioc_ready_wait), BNA_DEVICE_IOC_READY_WAIT},
+ {BFA_SM(bna_device_sm_ready), BNA_DEVICE_READY},
+ {BFA_SM(bna_device_sm_port_stop_wait), BNA_DEVICE_PORT_STOP_WAIT},
+ {BFA_SM(bna_device_sm_ioc_disable_wait), BNA_DEVICE_IOC_DISABLE_WAIT},
+ {BFA_SM(bna_device_sm_failed), BNA_DEVICE_FAILED},
+};
+
+static void
+bna_device_sm_stopped_entry(struct bna_device *device)
+{
+ if (device->stop_cbfn)
+ device->stop_cbfn(device->stop_cbarg, BNA_CB_SUCCESS);
+
+ device->stop_cbfn = NULL;
+ device->stop_cbarg = NULL;
+}
+
+static void
+bna_device_sm_stopped(struct bna_device *device,
+ enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_ENABLE:
+ if (device->intr_type == BNA_INTR_T_MSIX)
+ bna_mbox_msix_idx_set(device);
+ bfa_nw_ioc_enable(&device->ioc);
+ bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait);
+ break;
+
+ case DEVICE_E_DISABLE:
+ bfa_fsm_set_state(device, bna_device_sm_stopped);
+ break;
+
+ case DEVICE_E_IOC_RESET:
+ enable_mbox_intr(device);
+ break;
+
+ case DEVICE_E_IOC_FAILED:
+ bfa_fsm_set_state(device, bna_device_sm_failed);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+static void
+bna_device_sm_ioc_ready_wait_entry(struct bna_device *device)
+{
+ /**
+ * Do not call bfa_ioc_enable() here. It must be called in the
+ * previous state due to failed -> ioc_ready_wait transition.
+ */
+}
+
+static void
+bna_device_sm_ioc_ready_wait(struct bna_device *device,
+ enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_DISABLE:
+ if (device->ready_cbfn)
+ device->ready_cbfn(device->ready_cbarg,
+ BNA_CB_INTERRUPT);
+ device->ready_cbfn = NULL;
+ device->ready_cbarg = NULL;
+ bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait);
+ break;
+
+ case DEVICE_E_IOC_READY:
+ bfa_fsm_set_state(device, bna_device_sm_ready);
+ break;
+
+ case DEVICE_E_IOC_FAILED:
+ bfa_fsm_set_state(device, bna_device_sm_failed);
+ break;
+
+ case DEVICE_E_IOC_RESET:
+ enable_mbox_intr(device);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+static void
+bna_device_sm_ready_entry(struct bna_device *device)
+{
+ bna_mbox_mod_start(&device->bna->mbox_mod);
+ bna_port_start(&device->bna->port);
+
+ if (device->ready_cbfn)
+ device->ready_cbfn(device->ready_cbarg,
+ BNA_CB_SUCCESS);
+ device->ready_cbfn = NULL;
+ device->ready_cbarg = NULL;
+}
+
+static void
+bna_device_sm_ready(struct bna_device *device, enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_DISABLE:
+ bfa_fsm_set_state(device, bna_device_sm_port_stop_wait);
+ break;
+
+ case DEVICE_E_IOC_FAILED:
+ bfa_fsm_set_state(device, bna_device_sm_failed);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+static void
+bna_device_sm_port_stop_wait_entry(struct bna_device *device)
+{
+ bna_port_stop(&device->bna->port);
+}
+
+static void
+bna_device_sm_port_stop_wait(struct bna_device *device,
+ enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_PORT_STOPPED:
+ bna_mbox_mod_stop(&device->bna->mbox_mod);
+ bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait);
+ break;
+
+ case DEVICE_E_IOC_FAILED:
+ disable_mbox_intr(device);
+ bna_port_fail(&device->bna->port);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+static void
+bna_device_sm_ioc_disable_wait_entry(struct bna_device *device)
+{
+ bfa_nw_ioc_disable(&device->ioc);
+}
+
+static void
+bna_device_sm_ioc_disable_wait(struct bna_device *device,
+ enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_IOC_DISABLED:
+ disable_mbox_intr(device);
+ bfa_fsm_set_state(device, bna_device_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+static void
+bna_device_sm_failed_entry(struct bna_device *device)
+{
+ disable_mbox_intr(device);
+ bna_port_fail(&device->bna->port);
+ bna_mbox_mod_stop(&device->bna->mbox_mod);
+
+ if (device->ready_cbfn)
+ device->ready_cbfn(device->ready_cbarg,
+ BNA_CB_FAIL);
+ device->ready_cbfn = NULL;
+ device->ready_cbarg = NULL;
+}
+
+static void
+bna_device_sm_failed(struct bna_device *device,
+ enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_DISABLE:
+ bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait);
+ break;
+
+ case DEVICE_E_IOC_RESET:
+ enable_mbox_intr(device);
+ bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+/* IOC callback functions */
+
+static void
+bna_device_cb_iocll_ready(void *dev, enum bfa_status error)
+{
+ struct bna_device *device = (struct bna_device *)dev;
+
+ if (error)
+ bfa_fsm_send_event(device, DEVICE_E_IOC_FAILED);
+ else
+ bfa_fsm_send_event(device, DEVICE_E_IOC_READY);
+}
+
+static void
+bna_device_cb_iocll_disabled(void *dev)
+{
+ struct bna_device *device = (struct bna_device *)dev;
+
+ bfa_fsm_send_event(device, DEVICE_E_IOC_DISABLED);
+}
+
+static void
+bna_device_cb_iocll_failed(void *dev)
+{
+ struct bna_device *device = (struct bna_device *)dev;
+
+ bfa_fsm_send_event(device, DEVICE_E_IOC_FAILED);
+}
+
+static void
+bna_device_cb_iocll_reset(void *dev)
+{
+ struct bna_device *device = (struct bna_device *)dev;
+
+ bfa_fsm_send_event(device, DEVICE_E_IOC_RESET);
+}
+
+static struct bfa_ioc_cbfn bfa_iocll_cbfn = {
+ bna_device_cb_iocll_ready,
+ bna_device_cb_iocll_disabled,
+ bna_device_cb_iocll_failed,
+ bna_device_cb_iocll_reset
+};
+
+/* device */
+static void
+bna_adv_device_init(struct bna_device *device, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ u8 *kva;
+ u64 dma;
+
+ device->bna = bna;
+
+ kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva;
+
+ /**
+ * Attach common modules (Diag, SFP, CEE, Port) and claim respective
+ * DMA memory.
+ */
+ BNA_GET_DMA_ADDR(
+ &res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma);
+ kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva;
+
+ bfa_nw_cee_attach(&bna->cee, &device->ioc, bna);
+ bfa_nw_cee_mem_claim(&bna->cee, kva, dma);
+ kva += bfa_nw_cee_meminfo();
+ dma += bfa_nw_cee_meminfo();
+
+}
+
+static void
+bna_device_init(struct bna_device *device, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ u64 dma;
+
+ device->bna = bna;
+
+ /**
+ * Attach IOC and claim:
+ * 1. DMA memory for IOC attributes
+ * 2. Kernel memory for FW trace
+ */
+ bfa_nw_ioc_attach(&device->ioc, device, &bfa_iocll_cbfn);
+ bfa_nw_ioc_pci_init(&device->ioc, &bna->pcidev, BFI_MC_LL);
+
+ BNA_GET_DMA_ADDR(
+ &res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].dma, dma);
+ bfa_nw_ioc_mem_claim(&device->ioc,
+ res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].kva,
+ dma);
+
+ bna_adv_device_init(device, bna, res_info);
+ /*
+ * Initialize mbox_mod only after IOC, so that mbox handler
+ * registration goes through
+ */
+ device->intr_type =
+ res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.intr_type;
+ device->vector =
+ res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.idl[0].vector;
+ bna_mbox_mod_init(&bna->mbox_mod, bna);
+
+ device->ready_cbfn = device->stop_cbfn = NULL;
+ device->ready_cbarg = device->stop_cbarg = NULL;
+
+ bfa_fsm_set_state(device, bna_device_sm_stopped);
+}
+
+static void
+bna_device_uninit(struct bna_device *device)
+{
+ bna_mbox_mod_uninit(&device->bna->mbox_mod);
+
+ bfa_nw_ioc_detach(&device->ioc);
+
+ device->bna = NULL;
+}
+
+static void
+bna_device_cb_port_stopped(void *arg, enum bna_cb_status status)
+{
+ struct bna_device *device = (struct bna_device *)arg;
+
+ bfa_fsm_send_event(device, DEVICE_E_PORT_STOPPED);
+}
+
+static int
+bna_device_status_get(struct bna_device *device)
+{
+ return device->fsm == (bfa_fsm_t)bna_device_sm_ready;
+}
+
+void
+bna_device_enable(struct bna_device *device)
+{
+ if (device->fsm != (bfa_fsm_t)bna_device_sm_stopped) {
+ bnad_cb_device_enabled(device->bna->bnad, BNA_CB_BUSY);
+ return;
+ }
+
+ device->ready_cbfn = bnad_cb_device_enabled;
+ device->ready_cbarg = device->bna->bnad;
+
+ bfa_fsm_send_event(device, DEVICE_E_ENABLE);
+}
+
+void
+bna_device_disable(struct bna_device *device, enum bna_cleanup_type type)
+{
+ if (type == BNA_SOFT_CLEANUP) {
+ bnad_cb_device_disabled(device->bna->bnad, BNA_CB_SUCCESS);
+ return;
+ }
+
+ device->stop_cbfn = bnad_cb_device_disabled;
+ device->stop_cbarg = device->bna->bnad;
+
+ bfa_fsm_send_event(device, DEVICE_E_DISABLE);
+}
+
+static int
+bna_device_state_get(struct bna_device *device)
+{
+ return bfa_sm_to_state(device_sm_table, device->fsm);
+}
+
+const u32 bna_napi_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = {
+ {12, 12},
+ {6, 10},
+ {5, 10},
+ {4, 8},
+ {3, 6},
+ {3, 6},
+ {2, 4},
+ {1, 2},
+};
+
+/* utils */
+
+static void
+bna_adv_res_req(struct bna_res_info *res_info)
+{
+ /* DMA memory for COMMON_MODULE */
+ res_info[BNA_RES_MEM_T_COM].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+ res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN(
+ bfa_nw_cee_meminfo(), PAGE_SIZE);
+
+ /* Virtual memory for retreiving fw_trc */
+ res_info[BNA_RES_MEM_T_FWTRC].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mem_type = BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.num = 0;
+ res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.len = 0;
+
+ /* DMA memory for retreiving stats */
+ res_info[BNA_RES_MEM_T_STATS].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.len =
+ ALIGN(BFI_HW_STATS_SIZE, PAGE_SIZE);
+
+ /* Virtual memory for soft stats */
+ res_info[BNA_RES_MEM_T_SWSTATS].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.mem_type = BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.len =
+ sizeof(struct bna_sw_stats);
+}
+
+static void
+bna_sw_stats_get(struct bna *bna, struct bna_sw_stats *sw_stats)
+{
+ struct bna_tx *tx;
+ struct bna_txq *txq;
+ struct bna_rx *rx;
+ struct bna_rxp *rxp;
+ struct list_head *qe;
+ struct list_head *txq_qe;
+ struct list_head *rxp_qe;
+ struct list_head *mac_qe;
+ int i;
+
+ sw_stats->device_state = bna_device_state_get(&bna->device);
+ sw_stats->port_state = bna_port_state_get(&bna->port);
+ sw_stats->port_flags = bna->port.flags;
+ sw_stats->llport_state = bna_llport_state_get(&bna->port.llport);
+ sw_stats->priority = bna->port.priority;
+
+ i = 0;
+ list_for_each(qe, &bna->tx_mod.tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ sw_stats->tx_stats[i].tx_state = bna_tx_state_get(tx);
+ sw_stats->tx_stats[i].tx_flags = tx->flags;
+
+ sw_stats->tx_stats[i].num_txqs = 0;
+ sw_stats->tx_stats[i].txq_bmap[0] = 0;
+ sw_stats->tx_stats[i].txq_bmap[1] = 0;
+ list_for_each(txq_qe, &tx->txq_q) {
+ txq = (struct bna_txq *)txq_qe;
+ if (txq->txq_id < 32)
+ sw_stats->tx_stats[i].txq_bmap[0] |=
+ ((u32)1 << txq->txq_id);
+ else
+ sw_stats->tx_stats[i].txq_bmap[1] |=
+ ((u32)
+ 1 << (txq->txq_id - 32));
+ sw_stats->tx_stats[i].num_txqs++;
+ }
+
+ sw_stats->tx_stats[i].txf_id = tx->txf.txf_id;
+
+ i++;
+ }
+ sw_stats->num_active_tx = i;
+
+ i = 0;
+ list_for_each(qe, &bna->rx_mod.rx_active_q) {
+ rx = (struct bna_rx *)qe;
+ sw_stats->rx_stats[i].rx_state = bna_rx_state_get(rx);
+ sw_stats->rx_stats[i].rx_flags = rx->rx_flags;
+
+ sw_stats->rx_stats[i].num_rxps = 0;
+ sw_stats->rx_stats[i].num_rxqs = 0;
+ sw_stats->rx_stats[i].rxq_bmap[0] = 0;
+ sw_stats->rx_stats[i].rxq_bmap[1] = 0;
+ sw_stats->rx_stats[i].cq_bmap[0] = 0;
+ sw_stats->rx_stats[i].cq_bmap[1] = 0;
+ list_for_each(rxp_qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)rxp_qe;
+
+ sw_stats->rx_stats[i].num_rxqs += 1;
+
+ if (rxp->type == BNA_RXP_SINGLE) {
+ if (rxp->rxq.single.only->rxq_id < 32) {
+ sw_stats->rx_stats[i].rxq_bmap[0] |=
+ ((u32)1 <<
+ rxp->rxq.single.only->rxq_id);
+ } else {
+ sw_stats->rx_stats[i].rxq_bmap[1] |=
+ ((u32)1 <<
+ (rxp->rxq.single.only->rxq_id - 32));
+ }
+ } else {
+ if (rxp->rxq.slr.large->rxq_id < 32) {
+ sw_stats->rx_stats[i].rxq_bmap[0] |=
+ ((u32)1 <<
+ rxp->rxq.slr.large->rxq_id);
+ } else {
+ sw_stats->rx_stats[i].rxq_bmap[1] |=
+ ((u32)1 <<
+ (rxp->rxq.slr.large->rxq_id - 32));
+ }
+
+ if (rxp->rxq.slr.small->rxq_id < 32) {
+ sw_stats->rx_stats[i].rxq_bmap[0] |=
+ ((u32)1 <<
+ rxp->rxq.slr.small->rxq_id);
+ } else {
+ sw_stats->rx_stats[i].rxq_bmap[1] |=
+ ((u32)1 <<
+ (rxp->rxq.slr.small->rxq_id - 32));
+ }
+ sw_stats->rx_stats[i].num_rxqs += 1;
+ }
+
+ if (rxp->cq.cq_id < 32)
+ sw_stats->rx_stats[i].cq_bmap[0] |=
+ (1 << rxp->cq.cq_id);
+ else
+ sw_stats->rx_stats[i].cq_bmap[1] |=
+ (1 << (rxp->cq.cq_id - 32));
+
+ sw_stats->rx_stats[i].num_rxps++;
+ }
+
+ sw_stats->rx_stats[i].rxf_id = rx->rxf.rxf_id;
+ sw_stats->rx_stats[i].rxf_state = bna_rxf_state_get(&rx->rxf);
+ sw_stats->rx_stats[i].rxf_oper_state = rx->rxf.rxf_oper_state;
+
+ sw_stats->rx_stats[i].num_active_ucast = 0;
+ if (rx->rxf.ucast_active_mac)
+ sw_stats->rx_stats[i].num_active_ucast++;
+ list_for_each(mac_qe, &rx->rxf.ucast_active_q)
+ sw_stats->rx_stats[i].num_active_ucast++;
+
+ sw_stats->rx_stats[i].num_active_mcast = 0;
+ list_for_each(mac_qe, &rx->rxf.mcast_active_q)
+ sw_stats->rx_stats[i].num_active_mcast++;
+
+ sw_stats->rx_stats[i].rxmode_active = rx->rxf.rxmode_active;
+ sw_stats->rx_stats[i].vlan_filter_status =
+ rx->rxf.vlan_filter_status;
+ memcpy(sw_stats->rx_stats[i].vlan_filter_table,
+ rx->rxf.vlan_filter_table,
+ sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32));
+
+ sw_stats->rx_stats[i].rss_status = rx->rxf.rss_status;
+ sw_stats->rx_stats[i].hds_status = rx->rxf.hds_status;
+
+ i++;
+ }
+ sw_stats->num_active_rx = i;
+}
+
+static void
+bna_fw_cb_stats_get(void *arg, int status)
+{
+ struct bna *bna = (struct bna *)arg;
+ u64 *p_stats;
+ int i, count;
+ int rxf_count, txf_count;
+ u64 rxf_bmap, txf_bmap;
+
+ bfa_q_qe_init(&bna->mbox_qe.qe);
+
+ if (status == 0) {
+ p_stats = (u64 *)bna->stats.hw_stats;
+ count = sizeof(struct bfi_ll_stats) / sizeof(u64);
+ for (i = 0; i < count; i++)
+ p_stats[i] = cpu_to_be64(p_stats[i]);
+
+ rxf_count = 0;
+ rxf_bmap = (u64)bna->stats.rxf_bmap[0] |
+ ((u64)bna->stats.rxf_bmap[1] << 32);
+ for (i = 0; i < BFI_LL_RXF_ID_MAX; i++)
+ if (rxf_bmap & ((u64)1 << i))
+ rxf_count++;
+
+ txf_count = 0;
+ txf_bmap = (u64)bna->stats.txf_bmap[0] |
+ ((u64)bna->stats.txf_bmap[1] << 32);
+ for (i = 0; i < BFI_LL_TXF_ID_MAX; i++)
+ if (txf_bmap & ((u64)1 << i))
+ txf_count++;
+
+ p_stats = (u64 *)&bna->stats.hw_stats->rxf_stats[0] +
+ ((rxf_count * sizeof(struct bfi_ll_stats_rxf) +
+ txf_count * sizeof(struct bfi_ll_stats_txf))/
+ sizeof(u64));
+
+ /* Populate the TXF stats from the firmware DMAed copy */
+ for (i = (BFI_LL_TXF_ID_MAX - 1); i >= 0; i--)
+ if (txf_bmap & ((u64)1 << i)) {
+ p_stats -= sizeof(struct bfi_ll_stats_txf)/
+ sizeof(u64);
+ memcpy(&bna->stats.hw_stats->txf_stats[i],
+ p_stats,
+ sizeof(struct bfi_ll_stats_txf));
+ }
+
+ /* Populate the RXF stats from the firmware DMAed copy */
+ for (i = (BFI_LL_RXF_ID_MAX - 1); i >= 0; i--)
+ if (rxf_bmap & ((u64)1 << i)) {
+ p_stats -= sizeof(struct bfi_ll_stats_rxf)/
+ sizeof(u64);
+ memcpy(&bna->stats.hw_stats->rxf_stats[i],
+ p_stats,
+ sizeof(struct bfi_ll_stats_rxf));
+ }
+
+ bna_sw_stats_get(bna, bna->stats.sw_stats);
+ bnad_cb_stats_get(bna->bnad, BNA_CB_SUCCESS, &bna->stats);
+ } else
+ bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats);
+}
+
+static void
+bna_fw_stats_get(struct bna *bna)
+{
+ struct bfi_ll_stats_req ll_req;
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_GET_REQ, 0);
+ ll_req.stats_mask = htons(BFI_LL_STATS_ALL);
+
+ ll_req.rxf_id_mask[0] = htonl(bna->rx_mod.rxf_bmap[0]);
+ ll_req.rxf_id_mask[1] = htonl(bna->rx_mod.rxf_bmap[1]);
+ ll_req.txf_id_mask[0] = htonl(bna->tx_mod.txf_bmap[0]);
+ ll_req.txf_id_mask[1] = htonl(bna->tx_mod.txf_bmap[1]);
+
+ ll_req.host_buffer.a32.addr_hi = bna->hw_stats_dma.msb;
+ ll_req.host_buffer.a32.addr_lo = bna->hw_stats_dma.lsb;
+
+ bna_mbox_qe_fill(&bna->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_stats_get, bna);
+ bna_mbox_send(bna, &bna->mbox_qe);
+
+ bna->stats.rxf_bmap[0] = bna->rx_mod.rxf_bmap[0];
+ bna->stats.rxf_bmap[1] = bna->rx_mod.rxf_bmap[1];
+ bna->stats.txf_bmap[0] = bna->tx_mod.txf_bmap[0];
+ bna->stats.txf_bmap[1] = bna->tx_mod.txf_bmap[1];
+}
+
+void
+bna_stats_get(struct bna *bna)
+{
+ if (bna_device_status_get(&bna->device))
+ bna_fw_stats_get(bna);
+ else
+ bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats);
+}
+
+/* IB */
+static void
+bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo)
+{
+ ib->ib_config.coalescing_timeo = coalescing_timeo;
+
+ if (ib->start_count)
+ ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK(
+ (u32)ib->ib_config.coalescing_timeo, 0);
+}
+
+/* RxF */
+void
+bna_rxf_adv_init(struct bna_rxf *rxf,
+ struct bna_rx *rx,
+ struct bna_rx_config *q_config)
+{
+ switch (q_config->rxp_type) {
+ case BNA_RXP_SINGLE:
+ /* No-op */
+ break;
+ case BNA_RXP_SLR:
+ rxf->ctrl_flags |= BNA_RXF_CF_SM_LG_RXQ;
+ break;
+ case BNA_RXP_HDS:
+ rxf->hds_cfg.hdr_type = q_config->hds_config.hdr_type;
+ rxf->hds_cfg.header_size =
+ q_config->hds_config.header_size;
+ rxf->forced_offset = 0;
+ break;
+ default:
+ break;
+ }
+
+ if (q_config->rss_status == BNA_STATUS_T_ENABLED) {
+ rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE;
+ rxf->rss_cfg.hash_type = q_config->rss_config.hash_type;
+ rxf->rss_cfg.hash_mask = q_config->rss_config.hash_mask;
+ memcpy(&rxf->rss_cfg.toeplitz_hash_key[0],
+ &q_config->rss_config.toeplitz_hash_key[0],
+ sizeof(rxf->rss_cfg.toeplitz_hash_key));
+ }
+}
+
+static void
+rxf_fltr_mbox_cmd(struct bna_rxf *rxf, u8 cmd, enum bna_status status)
+{
+ struct bfi_ll_rxf_req req;
+
+ bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0);
+
+ req.rxf_id = rxf->rxf_id;
+ req.enable = status;
+
+ bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req),
+ rxf_cb_cam_fltr_mbox_cmd, rxf);
+
+ bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
+}
+
+static void
+__rxf_default_function_config(struct bna_rxf *rxf, enum bna_status status)
+{
+ struct bna_rx_fndb_ram *rx_fndb_ram;
+ u32 ctrl_flags;
+ int i;
+
+ rx_fndb_ram = (struct bna_rx_fndb_ram *)
+ BNA_GET_MEM_BASE_ADDR(rxf->rx->bna->pcidev.pci_bar_kva,
+ RX_FNDB_RAM_BASE_OFFSET);
+
+ for (i = 0; i < BFI_MAX_RXF; i++) {
+ if (status == BNA_STATUS_T_ENABLED) {
+ if (i == rxf->rxf_id)
+ continue;
+
+ ctrl_flags =
+ readl(&rx_fndb_ram[i].control_flags);
+ ctrl_flags |= BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE;
+ writel(ctrl_flags,
+ &rx_fndb_ram[i].control_flags);
+ } else {
+ ctrl_flags =
+ readl(&rx_fndb_ram[i].control_flags);
+ ctrl_flags &= ~BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE;
+ writel(ctrl_flags,
+ &rx_fndb_ram[i].control_flags);
+ }
+ }
+}
+
+int
+rxf_process_packet_filter_ucast(struct bna_rxf *rxf)
+{
+ struct bna_mac *mac = NULL;
+ struct list_head *qe;
+
+ /* Add additional MAC entries */
+ if (!list_empty(&rxf->ucast_pending_add_q)) {
+ bfa_q_deq(&rxf->ucast_pending_add_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_ADD_REQ, mac);
+ list_add_tail(&mac->qe, &rxf->ucast_active_q);
+ return 1;
+ }
+
+ /* Delete MAC addresses previousely added */
+ if (!list_empty(&rxf->ucast_pending_del_q)) {
+ bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac);
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_process_packet_filter_promisc(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* Enable/disable promiscuous mode */
+ if (is_promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move promisc configuration from pending -> active */
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active |= BNA_RXMODE_PROMISC;
+
+ /* Disable VLAN filter to allow all VLANs */
+ __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
+ BNA_STATUS_T_ENABLED);
+ return 1;
+ } else if (is_promisc_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move promisc configuration from pending -> active */
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_process_packet_filter_default(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* Enable/disable default mode */
+ if (is_default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move default configuration from pending -> active */
+ default_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active |= BNA_RXMODE_DEFAULT;
+
+ /* Disable VLAN filter to allow all VLANs */
+ __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED);
+ /* Redirect all other RxF vlan filtering to this one */
+ __rxf_default_function_config(rxf, BNA_STATUS_T_ENABLED);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
+ BNA_STATUS_T_ENABLED);
+ return 1;
+ } else if (is_default_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move default configuration from pending -> active */
+ default_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
+ bna->rxf_default_id = BFI_MAX_RXF;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ /* Stop RxF vlan filter table redirection */
+ __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_process_packet_filter_allmulti(struct bna_rxf *rxf)
+{
+ /* Enable/disable allmulti mode */
+ if (is_allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move allmulti configuration from pending -> active */
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active |= BNA_RXMODE_ALLMULTI;
+
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
+ BNA_STATUS_T_ENABLED);
+ return 1;
+ } else if (is_allmulti_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move allmulti configuration from pending -> active */
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_clear_packet_filter_ucast(struct bna_rxf *rxf)
+{
+ struct bna_mac *mac = NULL;
+ struct list_head *qe;
+
+ /* 1. delete pending ucast entries */
+ if (!list_empty(&rxf->ucast_pending_del_q)) {
+ bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac);
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+ return 1;
+ }
+
+ /* 2. clear active ucast entries; move them to pending_add_q */
+ if (!list_empty(&rxf->ucast_active_q)) {
+ bfa_q_deq(&rxf->ucast_active_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac);
+ list_add_tail(&mac->qe, &rxf->ucast_pending_add_q);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_clear_packet_filter_promisc(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* 6. Execute pending promisc mode disable command */
+ if (is_promisc_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move promisc configuration from pending -> active */
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ /* 7. Clear active promisc mode; move it to pending enable */
+ if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
+ /* move promisc configuration from active -> pending */
+ promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_clear_packet_filter_default(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* 8. Execute pending default mode disable command */
+ if (is_default_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move default configuration from pending -> active */
+ default_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
+ bna->rxf_default_id = BFI_MAX_RXF;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ /* Stop RxF vlan filter table redirection */
+ __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ /* 9. Clear active default mode; move it to pending enable */
+ if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) {
+ /* move default configuration from active -> pending */
+ default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ /* Stop RxF vlan filter table redirection */
+ __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf)
+{
+ /* 10. Execute pending allmulti mode disable command */
+ if (is_allmulti_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move allmulti configuration from pending -> active */
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ /* 11. Clear active allmulti mode; move it to pending enable */
+ if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
+ /* move allmulti configuration from active -> pending */
+ allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+rxf_reset_packet_filter_ucast(struct bna_rxf *rxf)
+{
+ struct list_head *qe;
+ struct bna_mac *mac;
+
+ /* 1. Move active ucast entries to pending_add_q */
+ while (!list_empty(&rxf->ucast_active_q)) {
+ bfa_q_deq(&rxf->ucast_active_q, &qe);
+ bfa_q_qe_init(qe);
+ list_add_tail(qe, &rxf->ucast_pending_add_q);
+ }
+
+ /* 2. Throw away delete pending ucast entries */
+ while (!list_empty(&rxf->ucast_pending_del_q)) {
+ bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+ }
+}
+
+void
+rxf_reset_packet_filter_promisc(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* 6. Clear pending promisc mode disable */
+ if (is_promisc_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+ }
+
+ /* 7. Move promisc mode config from active -> pending */
+ if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
+ promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+ }
+
+}
+
+void
+rxf_reset_packet_filter_default(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* 8. Clear pending default mode disable */
+ if (is_default_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ default_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
+ bna->rxf_default_id = BFI_MAX_RXF;
+ }
+
+ /* 9. Move default mode config from active -> pending */
+ if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) {
+ default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
+ }
+}
+
+void
+rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf)
+{
+ /* 10. Clear pending allmulti mode disable */
+ if (is_allmulti_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+ }
+
+ /* 11. Move allmulti mode config from active -> pending */
+ if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
+ allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+ }
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+static int
+rxf_promisc_enable(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+ int ret = 0;
+
+ /* There can not be any pending disable command */
+
+ /* Do nothing if pending enable or already enabled */
+ if (is_promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask) ||
+ (rxf->rxmode_active & BNA_RXMODE_PROMISC)) {
+ /* Schedule enable */
+ } else {
+ /* Promisc mode should not be active in the system */
+ promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ bna->rxf_promisc_id = rxf->rxf_id;
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+static int
+rxf_promisc_disable(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+ int ret = 0;
+
+ /* There can not be any pending disable */
+
+ /* Turn off pending enable command , if any */
+ if (is_promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* Promisc mode should not be active */
+ /* system promisc state should be pending */
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ /* Remove the promisc state from the system */
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+
+ /* Schedule disable */
+ } else if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
+ /* Promisc mode should be active in the system */
+ promisc_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ ret = 1;
+
+ /* Do nothing if already disabled */
+ } else {
+ }
+
+ return ret;
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+static int
+rxf_default_enable(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+ int ret = 0;
+
+ /* There can not be any pending disable command */
+
+ /* Do nothing if pending enable or already enabled */
+ if (is_default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask) ||
+ (rxf->rxmode_active & BNA_RXMODE_DEFAULT)) {
+ /* Schedule enable */
+ } else {
+ /* Default mode should not be active in the system */
+ default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ bna->rxf_default_id = rxf->rxf_id;
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+static int
+rxf_default_disable(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+ int ret = 0;
+
+ /* There can not be any pending disable */
+
+ /* Turn off pending enable command , if any */
+ if (is_default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* Promisc mode should not be active */
+ /* system default state should be pending */
+ default_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ /* Remove the default state from the system */
+ bna->rxf_default_id = BFI_MAX_RXF;
+
+ /* Schedule disable */
+ } else if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) {
+ /* Default mode should be active in the system */
+ default_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ ret = 1;
+
+ /* Do nothing if already disabled */
+ } else {
+ }
+
+ return ret;
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+static int
+rxf_allmulti_enable(struct bna_rxf *rxf)
+{
+ int ret = 0;
+
+ /* There can not be any pending disable command */
+
+ /* Do nothing if pending enable or already enabled */
+ if (is_allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask) ||
+ (rxf->rxmode_active & BNA_RXMODE_ALLMULTI)) {
+ /* Schedule enable */
+ } else {
+ allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+static int
+rxf_allmulti_disable(struct bna_rxf *rxf)
+{
+ int ret = 0;
+
+ /* There can not be any pending disable */
+
+ /* Turn off pending enable command , if any */
+ if (is_allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* Allmulti mode should not be active */
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+
+ /* Schedule disable */
+ } else if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
+ allmulti_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/* RxF <- bnad */
+enum bna_cb_status
+bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode,
+ enum bna_rxmode bitmask,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ int need_hw_config = 0;
+
+ /* Error checks */
+
+ if (is_promisc_enable(new_mode, bitmask)) {
+ /* If promisc mode is already enabled elsewhere in the system */
+ if ((rx->bna->rxf_promisc_id != BFI_MAX_RXF) &&
+ (rx->bna->rxf_promisc_id != rxf->rxf_id))
+ goto err_return;
+
+ /* If default mode is already enabled in the system */
+ if (rx->bna->rxf_default_id != BFI_MAX_RXF)
+ goto err_return;
+
+ /* Trying to enable promiscuous and default mode together */
+ if (is_default_enable(new_mode, bitmask))
+ goto err_return;
+ }
+
+ if (is_default_enable(new_mode, bitmask)) {
+ /* If default mode is already enabled elsewhere in the system */
+ if ((rx->bna->rxf_default_id != BFI_MAX_RXF) &&
+ (rx->bna->rxf_default_id != rxf->rxf_id)) {
+ goto err_return;
+ }
+
+ /* If promiscuous mode is already enabled in the system */
+ if (rx->bna->rxf_promisc_id != BFI_MAX_RXF)
+ goto err_return;
+ }
+
+ /* Process the commands */
+
+ if (is_promisc_enable(new_mode, bitmask)) {
+ if (rxf_promisc_enable(rxf))
+ need_hw_config = 1;
+ } else if (is_promisc_disable(new_mode, bitmask)) {
+ if (rxf_promisc_disable(rxf))
+ need_hw_config = 1;
+ }
+
+ if (is_default_enable(new_mode, bitmask)) {
+ if (rxf_default_enable(rxf))
+ need_hw_config = 1;
+ } else if (is_default_disable(new_mode, bitmask)) {
+ if (rxf_default_disable(rxf))
+ need_hw_config = 1;
+ }
+
+ if (is_allmulti_enable(new_mode, bitmask)) {
+ if (rxf_allmulti_enable(rxf))
+ need_hw_config = 1;
+ } else if (is_allmulti_disable(new_mode, bitmask)) {
+ if (rxf_allmulti_disable(rxf))
+ need_hw_config = 1;
+ }
+
+ /* Trigger h/w if needed */
+
+ if (need_hw_config) {
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ } else if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+
+ return BNA_CB_SUCCESS;
+
+err_return:
+ return BNA_CB_FAIL;
+}
+
+void
+/* RxF <- bnad */
+bna_rx_vlanfilter_enable(struct bna_rx *rx)
+{
+ struct bna_rxf *rxf = &rx->rxf;
+
+ if (rxf->vlan_filter_status == BNA_STATUS_T_DISABLED) {
+ rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
+ rxf->vlan_filter_status = BNA_STATUS_T_ENABLED;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ }
+}
+
+/* Rx */
+
+/* Rx <- bnad */
+void
+bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo)
+{
+ struct bna_rxp *rxp;
+ struct list_head *qe;
+
+ list_for_each(qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe;
+ rxp->cq.ccb->rx_coalescing_timeo = coalescing_timeo;
+ bna_ib_coalescing_timeo_set(rxp->cq.ib, coalescing_timeo);
+ }
+}
+
+/* Rx <- bnad */
+void
+bna_rx_dim_reconfig(struct bna *bna, const u32 vector[][BNA_BIAS_T_MAX])
+{
+ int i, j;
+
+ for (i = 0; i < BNA_LOAD_T_MAX; i++)
+ for (j = 0; j < BNA_BIAS_T_MAX; j++)
+ bna->rx_mod.dim_vector[i][j] = vector[i][j];
+}
+
+/* Rx <- bnad */
+void
+bna_rx_dim_update(struct bna_ccb *ccb)
+{
+ struct bna *bna = ccb->cq->rx->bna;
+ u32 load, bias;
+ u32 pkt_rt, small_rt, large_rt;
+ u8 coalescing_timeo;
+
+ if ((ccb->pkt_rate.small_pkt_cnt == 0) &&
+ (ccb->pkt_rate.large_pkt_cnt == 0))
+ return;
+
+ /* Arrive at preconfigured coalescing timeo value based on pkt rate */
+
+ small_rt = ccb->pkt_rate.small_pkt_cnt;
+ large_rt = ccb->pkt_rate.large_pkt_cnt;
+
+ pkt_rt = small_rt + large_rt;
+
+ if (pkt_rt < BNA_PKT_RATE_10K)
+ load = BNA_LOAD_T_LOW_4;
+ else if (pkt_rt < BNA_PKT_RATE_20K)
+ load = BNA_LOAD_T_LOW_3;
+ else if (pkt_rt < BNA_PKT_RATE_30K)
+ load = BNA_LOAD_T_LOW_2;
+ else if (pkt_rt < BNA_PKT_RATE_40K)
+ load = BNA_LOAD_T_LOW_1;
+ else if (pkt_rt < BNA_PKT_RATE_50K)
+ load = BNA_LOAD_T_HIGH_1;
+ else if (pkt_rt < BNA_PKT_RATE_60K)
+ load = BNA_LOAD_T_HIGH_2;
+ else if (pkt_rt < BNA_PKT_RATE_80K)
+ load = BNA_LOAD_T_HIGH_3;
+ else
+ load = BNA_LOAD_T_HIGH_4;
+
+ if (small_rt > (large_rt << 1))
+ bias = 0;
+ else
+ bias = 1;
+
+ ccb->pkt_rate.small_pkt_cnt = 0;
+ ccb->pkt_rate.large_pkt_cnt = 0;
+
+ coalescing_timeo = bna->rx_mod.dim_vector[load][bias];
+ ccb->rx_coalescing_timeo = coalescing_timeo;
+
+ /* Set it to IB */
+ bna_ib_coalescing_timeo_set(ccb->cq->ib, coalescing_timeo);
+}
+
+/* Tx */
+/* TX <- bnad */
+void
+bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_coalescing_timeo_set(txq->ib, coalescing_timeo);
+ }
+}
+
+/*
+ * Private data
+ */
+
+struct bna_ritseg_pool_cfg {
+ u32 pool_size;
+ u32 pool_entry_size;
+};
+init_ritseg_pool(ritseg_pool_cfg);
+
+/*
+ * Private functions
+ */
+static void
+bna_ucam_mod_init(struct bna_ucam_mod *ucam_mod, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ int i;
+
+ ucam_mod->ucmac = (struct bna_mac *)
+ res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
+
+ INIT_LIST_HEAD(&ucam_mod->free_q);
+ for (i = 0; i < BFI_MAX_UCMAC; i++) {
+ bfa_q_qe_init(&ucam_mod->ucmac[i].qe);
+ list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->free_q);
+ }
+
+ ucam_mod->bna = bna;
+}
+
+static void
+bna_ucam_mod_uninit(struct bna_ucam_mod *ucam_mod)
+{
+ struct list_head *qe;
+ int i = 0;
+
+ list_for_each(qe, &ucam_mod->free_q)
+ i++;
+
+ ucam_mod->bna = NULL;
+}
+
+static void
+bna_mcam_mod_init(struct bna_mcam_mod *mcam_mod, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ int i;
+
+ mcam_mod->mcmac = (struct bna_mac *)
+ res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
+
+ INIT_LIST_HEAD(&mcam_mod->free_q);
+ for (i = 0; i < BFI_MAX_MCMAC; i++) {
+ bfa_q_qe_init(&mcam_mod->mcmac[i].qe);
+ list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->free_q);
+ }
+
+ mcam_mod->bna = bna;
+}
+
+static void
+bna_mcam_mod_uninit(struct bna_mcam_mod *mcam_mod)
+{
+ struct list_head *qe;
+ int i = 0;
+
+ list_for_each(qe, &mcam_mod->free_q)
+ i++;
+
+ mcam_mod->bna = NULL;
+}
+
+static void
+bna_rit_mod_init(struct bna_rit_mod *rit_mod,
+ struct bna_res_info *res_info)
+{
+ int i;
+ int j;
+ int count;
+ int offset;
+
+ rit_mod->rit = (struct bna_rit_entry *)
+ res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.mdl[0].kva;
+ rit_mod->rit_segment = (struct bna_rit_segment *)
+ res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.mdl[0].kva;
+
+ count = 0;
+ offset = 0;
+ for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
+ INIT_LIST_HEAD(&rit_mod->rit_seg_pool[i]);
+ for (j = 0; j < ritseg_pool_cfg[i].pool_size; j++) {
+ bfa_q_qe_init(&rit_mod->rit_segment[count].qe);
+ rit_mod->rit_segment[count].max_rit_size =
+ ritseg_pool_cfg[i].pool_entry_size;
+ rit_mod->rit_segment[count].rit_offset = offset;
+ rit_mod->rit_segment[count].rit =
+ &rit_mod->rit[offset];
+ list_add_tail(&rit_mod->rit_segment[count].qe,
+ &rit_mod->rit_seg_pool[i]);
+ count++;
+ offset += ritseg_pool_cfg[i].pool_entry_size;
+ }
+ }
+}
+
+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
+ */
+
+/* Called during probe(), before calling bna_init() */
+void
+bna_res_req(struct bna_res_info *res_info)
+{
+ bna_adv_res_req(res_info);
+
+ /* DMA memory for retrieving IOC attributes */
+ res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+ res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.len =
+ ALIGN(bfa_nw_ioc_meminfo(), PAGE_SIZE);
+
+ /* DMA memory for index segment of an IB */
+ res_info[BNA_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.len =
+ BFI_IBIDX_SIZE * BFI_IBIDX_MAX_SEGSIZE;
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.num = BFI_MAX_IB;
+
+ /* Virtual memory for IB objects - stored by IB module */
+ res_info[BNA_RES_MEM_T_IB_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.len =
+ BFI_MAX_IB * sizeof(struct bna_ib);
+
+ /* Virtual memory for intr objects - stored by IB module */
+ res_info[BNA_RES_MEM_T_INTR_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.len =
+ BFI_MAX_IB * sizeof(struct bna_intr);
+
+ /* Virtual memory for idx_seg objects - stored by IB module */
+ res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.len =
+ BFI_IBIDX_TOTAL_SEGS * sizeof(struct bna_ibidx_seg);
+
+ /* Virtual memory for Tx objects - stored by Tx module */
+ res_info[BNA_RES_MEM_T_TX_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.len =
+ BFI_MAX_TXQ * sizeof(struct bna_tx);
+
+ /* Virtual memory for TxQ - stored by Tx module */
+ res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.len =
+ BFI_MAX_TXQ * sizeof(struct bna_txq);
+
+ /* Virtual memory for Rx objects - stored by Rx module */
+ res_info[BNA_RES_MEM_T_RX_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.len =
+ BFI_MAX_RXQ * sizeof(struct bna_rx);
+
+ /* Virtual memory for RxPath - stored by Rx module */
+ res_info[BNA_RES_MEM_T_RXP_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.len =
+ BFI_MAX_RXQ * sizeof(struct bna_rxp);
+
+ /* Virtual memory for RxQ - stored by Rx module */
+ res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.len =
+ BFI_MAX_RXQ * sizeof(struct bna_rxq);
+
+ /* Virtual memory for Unicast MAC address - stored by ucam module */
+ res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.len =
+ BFI_MAX_UCMAC * sizeof(struct bna_mac);
+
+ /* Virtual memory for Multicast MAC address - stored by mcam module */
+ res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.len =
+ BFI_MAX_MCMAC * sizeof(struct bna_mac);
+
+ /* Virtual memory for RIT entries */
+ res_info[BNA_RES_MEM_T_RIT_ENTRY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.len =
+ BFI_MAX_RIT_SIZE * sizeof(struct bna_rit_entry);
+
+ /* Virtual memory for RIT segment table */
+ res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.len =
+ BFI_RIT_TOTAL_SEGS * sizeof(struct bna_rit_segment);
+
+ /* Interrupt resource for mailbox interrupt */
+ res_info[BNA_RES_INTR_T_MBOX].res_type = BNA_RES_T_INTR;
+ res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.intr_type =
+ BNA_INTR_T_MSIX;
+ res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.num = 1;
+}
+
+/* Called during probe() */
+void
+bna_init(struct bna *bna, struct bnad *bnad, struct bfa_pcidev *pcidev,
+ struct bna_res_info *res_info)
+{
+ bna->bnad = bnad;
+ bna->pcidev = *pcidev;
+
+ bna->stats.hw_stats = (struct bfi_ll_stats *)
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].kva;
+ bna->hw_stats_dma.msb =
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.msb;
+ bna->hw_stats_dma.lsb =
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.lsb;
+ bna->stats.sw_stats = (struct bna_sw_stats *)
+ res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.mdl[0].kva;
+
+ bna->regs.page_addr = bna->pcidev.pci_bar_kva +
+ reg_offset[bna->pcidev.pci_func].page_addr;
+ bna->regs.fn_int_status = bna->pcidev.pci_bar_kva +
+ reg_offset[bna->pcidev.pci_func].fn_int_status;
+ bna->regs.fn_int_mask = bna->pcidev.pci_bar_kva +
+ reg_offset[bna->pcidev.pci_func].fn_int_mask;
+
+ if (bna->pcidev.pci_func < 3)
+ bna->port_num = 0;
+ else
+ bna->port_num = 1;
+
+ /* Also initializes diag, cee, sfp, phy_port and mbox_mod */
+ bna_device_init(&bna->device, bna, res_info);
+
+ bna_port_init(&bna->port, bna);
+
+ bna_tx_mod_init(&bna->tx_mod, bna, res_info);
+
+ bna_rx_mod_init(&bna->rx_mod, bna, res_info);
+
+ bna_ib_mod_init(&bna->ib_mod, bna, res_info);
+
+ bna_rit_mod_init(&bna->rit_mod, res_info);
+
+ bna_ucam_mod_init(&bna->ucam_mod, bna, res_info);
+
+ bna_mcam_mod_init(&bna->mcam_mod, bna, res_info);
+
+ bna->rxf_default_id = BFI_MAX_RXF;
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+
+ /* Mbox q element for posting stat request to f/w */
+ bfa_q_qe_init(&bna->mbox_qe.qe);
+}
+
+void
+bna_uninit(struct bna *bna)
+{
+ bna_mcam_mod_uninit(&bna->mcam_mod);
+
+ bna_ucam_mod_uninit(&bna->ucam_mod);
+
+ bna_rit_mod_uninit(&bna->rit_mod);
+
+ bna_ib_mod_uninit(&bna->ib_mod);
+
+ bna_rx_mod_uninit(&bna->rx_mod);
+
+ bna_tx_mod_uninit(&bna->tx_mod);
+
+ bna_port_uninit(&bna->port);
+
+ bna_device_uninit(&bna->device);
+
+ bna->bnad = NULL;
+}
+
+struct bna_mac *
+bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod)
+{
+ struct list_head *qe;
+
+ if (list_empty(&ucam_mod->free_q))
+ return NULL;
+
+ bfa_q_deq(&ucam_mod->free_q, &qe);
+
+ return (struct bna_mac *)qe;
+}
+
+void
+bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod, struct bna_mac *mac)
+{
+ list_add_tail(&mac->qe, &ucam_mod->free_q);
+}
+
+struct bna_mac *
+bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod)
+{
+ struct list_head *qe;
+
+ if (list_empty(&mcam_mod->free_q))
+ return NULL;
+
+ bfa_q_deq(&mcam_mod->free_q, &qe);
+
+ return (struct bna_mac *)qe;
+}
+
+void
+bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod, struct bna_mac *mac)
+{
+ list_add_tail(&mac->qe, &mcam_mod->free_q);
+}
+
+/**
+ * Note: This should be called in the same locking context as the call to
+ * bna_rit_mod_seg_get()
+ */
+int
+bna_rit_mod_can_satisfy(struct bna_rit_mod *rit_mod, int seg_size)
+{
+ int i;
+
+ /* Select the pool for seg_size */
+ for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
+ if (seg_size <= ritseg_pool_cfg[i].pool_entry_size)
+ break;
+ }
+
+ if (i == BFI_RIT_SEG_TOTAL_POOLS)
+ return 0;
+
+ if (list_empty(&rit_mod->rit_seg_pool[i]))
+ return 0;
+
+ return 1;
+}
+
+struct bna_rit_segment *
+bna_rit_mod_seg_get(struct bna_rit_mod *rit_mod, int seg_size)
+{
+ struct bna_rit_segment *seg;
+ struct list_head *qe;
+ int i;
+
+ /* Select the pool for seg_size */
+ for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
+ if (seg_size <= ritseg_pool_cfg[i].pool_entry_size)
+ break;
+ }
+
+ if (i == BFI_RIT_SEG_TOTAL_POOLS)
+ return NULL;
+
+ if (list_empty(&rit_mod->rit_seg_pool[i]))
+ return NULL;
+
+ bfa_q_deq(&rit_mod->rit_seg_pool[i], &qe);
+ seg = (struct bna_rit_segment *)qe;
+ bfa_q_qe_init(&seg->qe);
+ seg->rit_size = seg_size;
+
+ return seg;
+}
+
+void
+bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod,
+ struct bna_rit_segment *seg)
+{
+ int i;
+
+ /* Select the pool for seg->max_rit_size */
+ for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
+ if (seg->max_rit_size == ritseg_pool_cfg[i].pool_entry_size)
+ break;
+ }
+
+ seg->rit_size = 0;
+ list_add_tail(&seg->qe, &rit_mod->rit_seg_pool[i]);
+}
diff --git a/drivers/net/bna/bna_hw.h b/drivers/net/bna/bna_hw.h
new file mode 100644
index 000000000000..806b224a4c63
--- /dev/null
+++ b/drivers/net/bna/bna_hw.h
@@ -0,0 +1,1490 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * File for interrupt macros and functions
+ */
+
+#ifndef __BNA_HW_H__
+#define __BNA_HW_H__
+
+#include "bfi_ctreg.h"
+
+/**
+ *
+ * SW imposed limits
+ *
+ */
+
+#ifndef BNA_BIOS_BUILD
+
+#define BFI_MAX_TXQ 64
+#define BFI_MAX_RXQ 64
+#define BFI_MAX_RXF 64
+#define BFI_MAX_IB 128
+#define BFI_MAX_RIT_SIZE 256
+#define BFI_RSS_RIT_SIZE 64
+#define BFI_NONRSS_RIT_SIZE 1
+#define BFI_MAX_UCMAC 256
+#define BFI_MAX_MCMAC 512
+#define BFI_IBIDX_SIZE 4
+#define BFI_MAX_VLAN 4095
+
+/**
+ * There are 2 free IB index pools:
+ * pool1: 120 segments of 1 index each
+ * pool8: 1 segment of 8 indexes
+ */
+#define BFI_IBIDX_POOL1_SIZE 116
+#define BFI_IBIDX_POOL1_ENTRY_SIZE 1
+#define BFI_IBIDX_POOL2_SIZE 2
+#define BFI_IBIDX_POOL2_ENTRY_SIZE 2
+#define BFI_IBIDX_POOL8_SIZE 1
+#define BFI_IBIDX_POOL8_ENTRY_SIZE 8
+#define BFI_IBIDX_TOTAL_POOLS 3
+#define BFI_IBIDX_TOTAL_SEGS 119 /* (POOL1 + POOL2 + POOL8)_SIZE */
+#define BFI_IBIDX_MAX_SEGSIZE 8
+#define init_ibidx_pool(name) \
+static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] = \
+{ \
+ { BFI_IBIDX_POOL1_SIZE, BFI_IBIDX_POOL1_ENTRY_SIZE }, \
+ { BFI_IBIDX_POOL2_SIZE, BFI_IBIDX_POOL2_ENTRY_SIZE }, \
+ { BFI_IBIDX_POOL8_SIZE, BFI_IBIDX_POOL8_ENTRY_SIZE } \
+}
+
+/**
+ * There are 2 free RIT segment pools:
+ * Pool1: 192 segments of 1 RIT entry each
+ * Pool2: 1 segment of 64 RIT entry
+ */
+#define BFI_RIT_SEG_POOL1_SIZE 192
+#define BFI_RIT_SEG_POOL1_ENTRY_SIZE 1
+#define BFI_RIT_SEG_POOLRSS_SIZE 1
+#define BFI_RIT_SEG_POOLRSS_ENTRY_SIZE 64
+#define BFI_RIT_SEG_TOTAL_POOLS 2
+#define BFI_RIT_TOTAL_SEGS 193 /* POOL1_SIZE + POOLRSS_SIZE */
+#define init_ritseg_pool(name) \
+static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \
+{ \
+ { BFI_RIT_SEG_POOL1_SIZE, BFI_RIT_SEG_POOL1_ENTRY_SIZE }, \
+ { BFI_RIT_SEG_POOLRSS_SIZE, BFI_RIT_SEG_POOLRSS_ENTRY_SIZE } \
+}
+
+#else /* BNA_BIOS_BUILD */
+
+#define BFI_MAX_TXQ 1
+#define BFI_MAX_RXQ 1
+#define BFI_MAX_RXF 1
+#define BFI_MAX_IB 2
+#define BFI_MAX_RIT_SIZE 2
+#define BFI_RSS_RIT_SIZE 64
+#define BFI_NONRSS_RIT_SIZE 1
+#define BFI_MAX_UCMAC 1
+#define BFI_MAX_MCMAC 8
+#define BFI_IBIDX_SIZE 4
+#define BFI_MAX_VLAN 4095
+/* There is one free pool: 2 segments of 1 index each */
+#define BFI_IBIDX_POOL1_SIZE 2
+#define BFI_IBIDX_POOL1_ENTRY_SIZE 1
+#define BFI_IBIDX_TOTAL_POOLS 1
+#define BFI_IBIDX_TOTAL_SEGS 2 /* POOL1_SIZE */
+#define BFI_IBIDX_MAX_SEGSIZE 1
+#define init_ibidx_pool(name) \
+static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] = \
+{ \
+ { BFI_IBIDX_POOL1_SIZE, BFI_IBIDX_POOL1_ENTRY_SIZE } \
+}
+
+#define BFI_RIT_SEG_POOL1_SIZE 1
+#define BFI_RIT_SEG_POOL1_ENTRY_SIZE 1
+#define BFI_RIT_SEG_TOTAL_POOLS 1
+#define BFI_RIT_TOTAL_SEGS 1 /* POOL1_SIZE */
+#define init_ritseg_pool(name) \
+static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \
+{ \
+ { BFI_RIT_SEG_POOL1_SIZE, BFI_RIT_SEG_POOL1_ENTRY_SIZE } \
+}
+
+#endif /* BNA_BIOS_BUILD */
+
+#define BFI_RSS_HASH_KEY_LEN 10
+
+#define BFI_COALESCING_TIMER_UNIT 5 /* 5us */
+#define BFI_MAX_COALESCING_TIMEO 0xFF /* in 5us units */
+#define BFI_MAX_INTERPKT_COUNT 0xFF
+#define BFI_MAX_INTERPKT_TIMEO 0xF /* in 0.5us units */
+#define BFI_TX_COALESCING_TIMEO 20 /* 20 * 5 = 100us */
+#define BFI_TX_INTERPKT_COUNT 32
+#define BFI_RX_COALESCING_TIMEO 12 /* 12 * 5 = 60us */
+#define BFI_RX_INTERPKT_COUNT 6 /* Pkt Cnt = 6 */
+#define BFI_RX_INTERPKT_TIMEO 3 /* 3 * 0.5 = 1.5us */
+
+#define BFI_TXQ_WI_SIZE 64 /* bytes */
+#define BFI_RXQ_WI_SIZE 8 /* bytes */
+#define BFI_CQ_WI_SIZE 16 /* bytes */
+#define BFI_TX_MAX_WRR_QUOTA 0xFFF
+
+#define BFI_TX_MAX_VECTORS_PER_WI 4
+#define BFI_TX_MAX_VECTORS_PER_PKT 0xFF
+#define BFI_TX_MAX_DATA_PER_VECTOR 0xFFFF
+#define BFI_TX_MAX_DATA_PER_PKT 0xFFFFFF
+
+/* Small Q buffer size */
+#define BFI_SMALL_RXBUF_SIZE 128
+
+/* Defined separately since BFA_FLASH_DMA_BUF_SZ is in bfa_flash.c */
+#define BFI_FLASH_DMA_BUF_SZ 0x010000 /* 64K DMA */
+#define BFI_HW_STATS_SIZE 0x4000 /* 16K DMA */
+
+/**
+ *
+ * HW register offsets, macros
+ *
+ */
+
+/* DMA Block Register Host Window Start Address */
+#define DMA_BLK_REG_ADDR 0x00013000
+
+/* DMA Block Internal Registers */
+#define DMA_CTRL_REG0 (DMA_BLK_REG_ADDR + 0x000)
+#define DMA_CTRL_REG1 (DMA_BLK_REG_ADDR + 0x004)
+#define DMA_ERR_INT_STATUS (DMA_BLK_REG_ADDR + 0x008)
+#define DMA_ERR_INT_ENABLE (DMA_BLK_REG_ADDR + 0x00c)
+#define DMA_ERR_INT_STATUS_SET (DMA_BLK_REG_ADDR + 0x010)
+
+/* APP Block Register Address Offset from BAR0 */
+#define APP_BLK_REG_ADDR 0x00014000
+
+/* Host Function Interrupt Mask Registers */
+#define HOSTFN0_INT_MASK (APP_BLK_REG_ADDR + 0x004)
+#define HOSTFN1_INT_MASK (APP_BLK_REG_ADDR + 0x104)
+#define HOSTFN2_INT_MASK (APP_BLK_REG_ADDR + 0x304)
+#define HOSTFN3_INT_MASK (APP_BLK_REG_ADDR + 0x404)
+
+/**
+ * Host Function PCIe Error Registers
+ * Duplicates "Correctable" & "Uncorrectable"
+ * registers in PCIe Config space.
+ */
+#define FN0_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x014)
+#define FN1_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x114)
+#define FN2_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x314)
+#define FN3_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x414)
+
+/* Host Function Error Type Status Registers */
+#define FN0_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x018)
+#define FN1_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x118)
+#define FN2_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x318)
+#define FN3_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x418)
+
+/* Host Function Error Type Mask Registers */
+#define FN0_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x01c)
+#define FN1_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x11c)
+#define FN2_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x31c)
+#define FN3_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x41c)
+
+/* Catapult Host Semaphore Status Registers (App block) */
+#define HOST_SEM_STS0_REG (APP_BLK_REG_ADDR + 0x630)
+#define HOST_SEM_STS1_REG (APP_BLK_REG_ADDR + 0x634)
+#define HOST_SEM_STS2_REG (APP_BLK_REG_ADDR + 0x638)
+#define HOST_SEM_STS3_REG (APP_BLK_REG_ADDR + 0x63c)
+#define HOST_SEM_STS4_REG (APP_BLK_REG_ADDR + 0x640)
+#define HOST_SEM_STS5_REG (APP_BLK_REG_ADDR + 0x644)
+#define HOST_SEM_STS6_REG (APP_BLK_REG_ADDR + 0x648)
+#define HOST_SEM_STS7_REG (APP_BLK_REG_ADDR + 0x64c)
+
+/* PCIe Misc Register */
+#define PCIE_MISC_REG (APP_BLK_REG_ADDR + 0x200)
+
+/* Temp Sensor Control Registers */
+#define TEMPSENSE_CNTL_REG (APP_BLK_REG_ADDR + 0x250)
+#define TEMPSENSE_STAT_REG (APP_BLK_REG_ADDR + 0x254)
+
+/* APP Block local error registers */
+#define APP_LOCAL_ERR_STAT (APP_BLK_REG_ADDR + 0x258)
+#define APP_LOCAL_ERR_MSK (APP_BLK_REG_ADDR + 0x25c)
+
+/* PCIe Link Error registers */
+#define PCIE_LNK_ERR_STAT (APP_BLK_REG_ADDR + 0x260)
+#define PCIE_LNK_ERR_MSK (APP_BLK_REG_ADDR + 0x264)
+
+/**
+ * FCoE/FIP Ethertype Register
+ * 31:16 -- Chip wide value for FIP type
+ * 15:0 -- Chip wide value for FCoE type
+ */
+#define FCOE_FIP_ETH_TYPE (APP_BLK_REG_ADDR + 0x280)
+
+/**
+ * Reserved Ethertype Register
+ * 31:16 -- Reserved
+ * 15:0 -- Other ethertype
+ */
+#define RESV_ETH_TYPE (APP_BLK_REG_ADDR + 0x284)
+
+/**
+ * Host Command Status Registers
+ * Each set consists of 3 registers :
+ * clear, set, cmd
+ * 16 such register sets in all
+ * See catapult_spec.pdf for detailed functionality
+ * Put each type in a single macro accessed by _num ?
+ */
+#define HOST_CMDSTS0_CLR_REG (APP_BLK_REG_ADDR + 0x500)
+#define HOST_CMDSTS0_SET_REG (APP_BLK_REG_ADDR + 0x504)
+#define HOST_CMDSTS0_REG (APP_BLK_REG_ADDR + 0x508)
+#define HOST_CMDSTS1_CLR_REG (APP_BLK_REG_ADDR + 0x510)
+#define HOST_CMDSTS1_SET_REG (APP_BLK_REG_ADDR + 0x514)
+#define HOST_CMDSTS1_REG (APP_BLK_REG_ADDR + 0x518)
+#define HOST_CMDSTS2_CLR_REG (APP_BLK_REG_ADDR + 0x520)
+#define HOST_CMDSTS2_SET_REG (APP_BLK_REG_ADDR + 0x524)
+#define HOST_CMDSTS2_REG (APP_BLK_REG_ADDR + 0x528)
+#define HOST_CMDSTS3_CLR_REG (APP_BLK_REG_ADDR + 0x530)
+#define HOST_CMDSTS3_SET_REG (APP_BLK_REG_ADDR + 0x534)
+#define HOST_CMDSTS3_REG (APP_BLK_REG_ADDR + 0x538)
+#define HOST_CMDSTS4_CLR_REG (APP_BLK_REG_ADDR + 0x540)
+#define HOST_CMDSTS4_SET_REG (APP_BLK_REG_ADDR + 0x544)
+#define HOST_CMDSTS4_REG (APP_BLK_REG_ADDR + 0x548)
+#define HOST_CMDSTS5_CLR_REG (APP_BLK_REG_ADDR + 0x550)
+#define HOST_CMDSTS5_SET_REG (APP_BLK_REG_ADDR + 0x554)
+#define HOST_CMDSTS5_REG (APP_BLK_REG_ADDR + 0x558)
+#define HOST_CMDSTS6_CLR_REG (APP_BLK_REG_ADDR + 0x560)
+#define HOST_CMDSTS6_SET_REG (APP_BLK_REG_ADDR + 0x564)
+#define HOST_CMDSTS6_REG (APP_BLK_REG_ADDR + 0x568)
+#define HOST_CMDSTS7_CLR_REG (APP_BLK_REG_ADDR + 0x570)
+#define HOST_CMDSTS7_SET_REG (APP_BLK_REG_ADDR + 0x574)
+#define HOST_CMDSTS7_REG (APP_BLK_REG_ADDR + 0x578)
+#define HOST_CMDSTS8_CLR_REG (APP_BLK_REG_ADDR + 0x580)
+#define HOST_CMDSTS8_SET_REG (APP_BLK_REG_ADDR + 0x584)
+#define HOST_CMDSTS8_REG (APP_BLK_REG_ADDR + 0x588)
+#define HOST_CMDSTS9_CLR_REG (APP_BLK_REG_ADDR + 0x590)
+#define HOST_CMDSTS9_SET_REG (APP_BLK_REG_ADDR + 0x594)
+#define HOST_CMDSTS9_REG (APP_BLK_REG_ADDR + 0x598)
+#define HOST_CMDSTS10_CLR_REG (APP_BLK_REG_ADDR + 0x5A0)
+#define HOST_CMDSTS10_SET_REG (APP_BLK_REG_ADDR + 0x5A4)
+#define HOST_CMDSTS10_REG (APP_BLK_REG_ADDR + 0x5A8)
+#define HOST_CMDSTS11_CLR_REG (APP_BLK_REG_ADDR + 0x5B0)
+#define HOST_CMDSTS11_SET_REG (APP_BLK_REG_ADDR + 0x5B4)
+#define HOST_CMDSTS11_REG (APP_BLK_REG_ADDR + 0x5B8)
+#define HOST_CMDSTS12_CLR_REG (APP_BLK_REG_ADDR + 0x5C0)
+#define HOST_CMDSTS12_SET_REG (APP_BLK_REG_ADDR + 0x5C4)
+#define HOST_CMDSTS12_REG (APP_BLK_REG_ADDR + 0x5C8)
+#define HOST_CMDSTS13_CLR_REG (APP_BLK_REG_ADDR + 0x5D0)
+#define HOST_CMDSTS13_SET_REG (APP_BLK_REG_ADDR + 0x5D4)
+#define HOST_CMDSTS13_REG (APP_BLK_REG_ADDR + 0x5D8)
+#define HOST_CMDSTS14_CLR_REG (APP_BLK_REG_ADDR + 0x5E0)
+#define HOST_CMDSTS14_SET_REG (APP_BLK_REG_ADDR + 0x5E4)
+#define HOST_CMDSTS14_REG (APP_BLK_REG_ADDR + 0x5E8)
+#define HOST_CMDSTS15_CLR_REG (APP_BLK_REG_ADDR + 0x5F0)
+#define HOST_CMDSTS15_SET_REG (APP_BLK_REG_ADDR + 0x5F4)
+#define HOST_CMDSTS15_REG (APP_BLK_REG_ADDR + 0x5F8)
+
+/**
+ * LPU0 Block Register Address Offset from BAR0
+ * Range 0x18000 - 0x18033
+ */
+#define LPU0_BLK_REG_ADDR 0x00018000
+
+/**
+ * LPU0 Registers
+ * Should they be directly used from host,
+ * except for diagnostics ?
+ * CTL_REG : Control register
+ * CMD_REG : Triggers exec. of cmd. in
+ * Mailbox memory
+ */
+#define LPU0_MBOX_CTL_REG (LPU0_BLK_REG_ADDR + 0x000)
+#define LPU0_MBOX_CMD_REG (LPU0_BLK_REG_ADDR + 0x004)
+#define LPU0_MBOX_LINK_0REG (LPU0_BLK_REG_ADDR + 0x008)
+#define LPU1_MBOX_LINK_0REG (LPU0_BLK_REG_ADDR + 0x00c)
+#define LPU0_MBOX_STATUS_0REG (LPU0_BLK_REG_ADDR + 0x010)
+#define LPU1_MBOX_STATUS_0REG (LPU0_BLK_REG_ADDR + 0x014)
+#define LPU0_ERR_STATUS_REG (LPU0_BLK_REG_ADDR + 0x018)
+#define LPU0_ERR_SET_REG (LPU0_BLK_REG_ADDR + 0x020)
+
+/**
+ * LPU1 Block Register Address Offset from BAR0
+ * Range 0x18400 - 0x18433
+ */
+#define LPU1_BLK_REG_ADDR 0x00018400
+
+/**
+ * LPU1 Registers
+ * Same as LPU0 registers above
+ */
+#define LPU1_MBOX_CTL_REG (LPU1_BLK_REG_ADDR + 0x000)
+#define LPU1_MBOX_CMD_REG (LPU1_BLK_REG_ADDR + 0x004)
+#define LPU0_MBOX_LINK_1REG (LPU1_BLK_REG_ADDR + 0x008)
+#define LPU1_MBOX_LINK_1REG (LPU1_BLK_REG_ADDR + 0x00c)
+#define LPU0_MBOX_STATUS_1REG (LPU1_BLK_REG_ADDR + 0x010)
+#define LPU1_MBOX_STATUS_1REG (LPU1_BLK_REG_ADDR + 0x014)
+#define LPU1_ERR_STATUS_REG (LPU1_BLK_REG_ADDR + 0x018)
+#define LPU1_ERR_SET_REG (LPU1_BLK_REG_ADDR + 0x020)
+
+/**
+ * PSS Block Register Address Offset from BAR0
+ * Range 0x18800 - 0x188DB
+ */
+#define PSS_BLK_REG_ADDR 0x00018800
+
+/**
+ * PSS Registers
+ * For details, see catapult_spec.pdf
+ * ERR_STATUS_REG : Indicates error in PSS module
+ * RAM_ERR_STATUS_REG : Indicates RAM module that detected error
+ */
+#define ERR_STATUS_SET (PSS_BLK_REG_ADDR + 0x018)
+#define PSS_RAM_ERR_STATUS_REG (PSS_BLK_REG_ADDR + 0x01C)
+
+/**
+ * PSS Semaphore Lock Registers, total 16
+ * First read when unlocked returns 0,
+ * and is set to 1, atomically.
+ * Subsequent reads returns 1.
+ * To clear set the value to 0.
+ * Range : 0x20 to 0x5c
+ */
+#define PSS_SEM_LOCK_REG(_num) \
+ (PSS_BLK_REG_ADDR + 0x020 + ((_num) << 2))
+
+/**
+ * PSS Semaphore Status Registers,
+ * corresponding to the lock registers above
+ */
+#define PSS_SEM_STATUS_REG(_num) \
+ (PSS_BLK_REG_ADDR + 0x060 + ((_num) << 2))
+
+/**
+ * Catapult CPQ Registers
+ * Defines for Mailbox Registers
+ * Used to send mailbox commands to firmware from
+ * host. The data part is written to the MBox
+ * memory, registers are used to indicate that
+ * a commnad is resident in memory.
+ *
+ * Note : LPU0<->LPU1 mailboxes are not listed here
+ */
+#define CPQ_BLK_REG_ADDR 0x00019000
+
+#define HOSTFN0_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x130)
+#define HOSTFN0_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x134)
+#define LPU0_HOSTFN0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x138)
+#define LPU1_HOSTFN0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x13C)
+
+#define HOSTFN1_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x140)
+#define HOSTFN1_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x144)
+#define LPU0_HOSTFN1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x148)
+#define LPU1_HOSTFN1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x14C)
+
+#define HOSTFN2_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x170)
+#define HOSTFN2_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x174)
+#define LPU0_HOSTFN2_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x178)
+#define LPU1_HOSTFN2_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x17C)
+
+#define HOSTFN3_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x180)
+#define HOSTFN3_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x184)
+#define LPU0_HOSTFN3_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x188)
+#define LPU1_HOSTFN3_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x18C)
+
+/* Host Function Force Parity Error Registers */
+#define HOSTFN0_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x120)
+#define HOSTFN1_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x124)
+#define HOSTFN2_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x128)
+#define HOSTFN3_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x12C)
+
+/* LL Port[0|1] Halt Mask Registers */
+#define LL_HALT_MSK_P0 (CPQ_BLK_REG_ADDR + 0x1A0)
+#define LL_HALT_MSK_P1 (CPQ_BLK_REG_ADDR + 0x1B0)
+
+/* LL Port[0|1] Error Mask Registers */
+#define LL_ERR_MSK_P0 (CPQ_BLK_REG_ADDR + 0x1D0)
+#define LL_ERR_MSK_P1 (CPQ_BLK_REG_ADDR + 0x1D4)
+
+/* EMC FLI (Flash Controller) Block Register Address Offset from BAR0 */
+#define FLI_BLK_REG_ADDR 0x0001D000
+
+/* EMC FLI Registers */
+#define FLI_CMD_REG (FLI_BLK_REG_ADDR + 0x000)
+#define FLI_ADDR_REG (FLI_BLK_REG_ADDR + 0x004)
+#define FLI_CTL_REG (FLI_BLK_REG_ADDR + 0x008)
+#define FLI_WRDATA_REG (FLI_BLK_REG_ADDR + 0x00C)
+#define FLI_RDDATA_REG (FLI_BLK_REG_ADDR + 0x010)
+#define FLI_DEV_STATUS_REG (FLI_BLK_REG_ADDR + 0x014)
+#define FLI_SIG_WD_REG (FLI_BLK_REG_ADDR + 0x018)
+
+/**
+ * RO register
+ * 31:16 -- Vendor Id
+ * 15:0 -- Device Id
+ */
+#define FLI_DEV_VENDOR_REG (FLI_BLK_REG_ADDR + 0x01C)
+#define FLI_ERR_STATUS_REG (FLI_BLK_REG_ADDR + 0x020)
+
+/**
+ * RAD (RxAdm) Block Register Address Offset from BAR0
+ * RAD0 Range : 0x20000 - 0x203FF
+ * RAD1 Range : 0x20400 - 0x207FF
+ */
+#define RAD0_BLK_REG_ADDR 0x00020000
+#define RAD1_BLK_REG_ADDR 0x00020400
+
+/* RAD0 Registers */
+#define RAD0_CTL_REG (RAD0_BLK_REG_ADDR + 0x000)
+#define RAD0_PE_PARM_REG (RAD0_BLK_REG_ADDR + 0x004)
+#define RAD0_BCN_REG (RAD0_BLK_REG_ADDR + 0x008)
+
+/* Default function ID register */
+#define RAD0_DEFAULT_REG (RAD0_BLK_REG_ADDR + 0x00C)
+
+/* Default promiscuous ID register */
+#define RAD0_PROMISC_REG (RAD0_BLK_REG_ADDR + 0x010)
+
+#define RAD0_BCNQ_REG (RAD0_BLK_REG_ADDR + 0x014)
+
+/*
+ * This register selects 1 of 8 PM Q's using
+ * VLAN pri, for non-BCN packets without a VLAN tag
+ */
+#define RAD0_DEFAULTQ_REG (RAD0_BLK_REG_ADDR + 0x018)
+
+#define RAD0_ERR_STS (RAD0_BLK_REG_ADDR + 0x01C)
+#define RAD0_SET_ERR_STS (RAD0_BLK_REG_ADDR + 0x020)
+#define RAD0_ERR_INT_EN (RAD0_BLK_REG_ADDR + 0x024)
+#define RAD0_FIRST_ERR (RAD0_BLK_REG_ADDR + 0x028)
+#define RAD0_FORCE_ERR (RAD0_BLK_REG_ADDR + 0x02C)
+
+#define RAD0_IF_RCVD (RAD0_BLK_REG_ADDR + 0x030)
+#define RAD0_IF_RCVD_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x034)
+#define RAD0_IF_RCVD_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x038)
+#define RAD0_IF_RCVD_VLAN (RAD0_BLK_REG_ADDR + 0x03C)
+#define RAD0_IF_RCVD_UCAST (RAD0_BLK_REG_ADDR + 0x040)
+#define RAD0_IF_RCVD_UCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x044)
+#define RAD0_IF_RCVD_UCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x048)
+#define RAD0_IF_RCVD_UCAST_VLAN (RAD0_BLK_REG_ADDR + 0x04C)
+#define RAD0_IF_RCVD_MCAST (RAD0_BLK_REG_ADDR + 0x050)
+#define RAD0_IF_RCVD_MCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x054)
+#define RAD0_IF_RCVD_MCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x058)
+#define RAD0_IF_RCVD_MCAST_VLAN (RAD0_BLK_REG_ADDR + 0x05C)
+#define RAD0_IF_RCVD_BCAST (RAD0_BLK_REG_ADDR + 0x060)
+#define RAD0_IF_RCVD_BCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x064)
+#define RAD0_IF_RCVD_BCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x068)
+#define RAD0_IF_RCVD_BCAST_VLAN (RAD0_BLK_REG_ADDR + 0x06C)
+#define RAD0_DROPPED_FRAMES (RAD0_BLK_REG_ADDR + 0x070)
+
+#define RAD0_MAC_MAN_1H (RAD0_BLK_REG_ADDR + 0x080)
+#define RAD0_MAC_MAN_1L (RAD0_BLK_REG_ADDR + 0x084)
+#define RAD0_MAC_MAN_2H (RAD0_BLK_REG_ADDR + 0x088)
+#define RAD0_MAC_MAN_2L (RAD0_BLK_REG_ADDR + 0x08C)
+#define RAD0_MAC_MAN_3H (RAD0_BLK_REG_ADDR + 0x090)
+#define RAD0_MAC_MAN_3L (RAD0_BLK_REG_ADDR + 0x094)
+#define RAD0_MAC_MAN_4H (RAD0_BLK_REG_ADDR + 0x098)
+#define RAD0_MAC_MAN_4L (RAD0_BLK_REG_ADDR + 0x09C)
+
+#define RAD0_LAST4_IP (RAD0_BLK_REG_ADDR + 0x100)
+
+/* RAD1 Registers */
+#define RAD1_CTL_REG (RAD1_BLK_REG_ADDR + 0x000)
+#define RAD1_PE_PARM_REG (RAD1_BLK_REG_ADDR + 0x004)
+#define RAD1_BCN_REG (RAD1_BLK_REG_ADDR + 0x008)
+
+/* Default function ID register */
+#define RAD1_DEFAULT_REG (RAD1_BLK_REG_ADDR + 0x00C)
+
+/* Promiscuous function ID register */
+#define RAD1_PROMISC_REG (RAD1_BLK_REG_ADDR + 0x010)
+
+#define RAD1_BCNQ_REG (RAD1_BLK_REG_ADDR + 0x014)
+
+/*
+ * This register selects 1 of 8 PM Q's using
+ * VLAN pri, for non-BCN packets without a VLAN tag
+ */
+#define RAD1_DEFAULTQ_REG (RAD1_BLK_REG_ADDR + 0x018)
+
+#define RAD1_ERR_STS (RAD1_BLK_REG_ADDR + 0x01C)
+#define RAD1_SET_ERR_STS (RAD1_BLK_REG_ADDR + 0x020)
+#define RAD1_ERR_INT_EN (RAD1_BLK_REG_ADDR + 0x024)
+
+/**
+ * TXA Block Register Address Offset from BAR0
+ * TXA0 Range : 0x21000 - 0x213FF
+ * TXA1 Range : 0x21400 - 0x217FF
+ */
+#define TXA0_BLK_REG_ADDR 0x00021000
+#define TXA1_BLK_REG_ADDR 0x00021400
+
+/* TXA Registers */
+#define TXA0_CTRL_REG (TXA0_BLK_REG_ADDR + 0x000)
+#define TXA1_CTRL_REG (TXA1_BLK_REG_ADDR + 0x000)
+
+/**
+ * TSO Sequence # Registers (RO)
+ * Total 8 (for 8 queues)
+ * Holds the last seq.# for TSO frames
+ * See catapult_spec.pdf for more details
+ */
+#define TXA0_TSO_TCP_SEQ_REG(_num) \
+ (TXA0_BLK_REG_ADDR + 0x020 + ((_num) << 2))
+
+#define TXA1_TSO_TCP_SEQ_REG(_num) \
+ (TXA1_BLK_REG_ADDR + 0x020 + ((_num) << 2))
+
+/**
+ * TSO IP ID # Registers (RO)
+ * Total 8 (for 8 queues)
+ * Holds the last IP ID for TSO frames
+ * See catapult_spec.pdf for more details
+ */
+#define TXA0_TSO_IP_INFO_REG(_num) \
+ (TXA0_BLK_REG_ADDR + 0x040 + ((_num) << 2))
+
+#define TXA1_TSO_IP_INFO_REG(_num) \
+ (TXA1_BLK_REG_ADDR + 0x040 + ((_num) << 2))
+
+/**
+ * RXA Block Register Address Offset from BAR0
+ * RXA0 Range : 0x21800 - 0x21BFF
+ * RXA1 Range : 0x21C00 - 0x21FFF
+ */
+#define RXA0_BLK_REG_ADDR 0x00021800
+#define RXA1_BLK_REG_ADDR 0x00021C00
+
+/* RXA Registers */
+#define RXA0_CTL_REG (RXA0_BLK_REG_ADDR + 0x040)
+#define RXA1_CTL_REG (RXA1_BLK_REG_ADDR + 0x040)
+
+/**
+ * PPLB Block Register Address Offset from BAR0
+ * PPLB0 Range : 0x22000 - 0x223FF
+ * PPLB1 Range : 0x22400 - 0x227FF
+ */
+#define PLB0_BLK_REG_ADDR 0x00022000
+#define PLB1_BLK_REG_ADDR 0x00022400
+
+/**
+ * PLB Registers
+ * Holds RL timer used time stamps in RLT tagged frames
+ */
+#define PLB0_ECM_TIMER_REG (PLB0_BLK_REG_ADDR + 0x05C)
+#define PLB1_ECM_TIMER_REG (PLB1_BLK_REG_ADDR + 0x05C)
+
+/* Controls the rate-limiter on each of the priority class */
+#define PLB0_RL_CTL (PLB0_BLK_REG_ADDR + 0x060)
+#define PLB1_RL_CTL (PLB1_BLK_REG_ADDR + 0x060)
+
+/**
+ * Max byte register, total 8, 0-7
+ * see catapult_spec.pdf for details
+ */
+#define PLB0_RL_MAX_BC(_num) \
+ (PLB0_BLK_REG_ADDR + 0x064 + ((_num) << 2))
+#define PLB1_RL_MAX_BC(_num) \
+ (PLB1_BLK_REG_ADDR + 0x064 + ((_num) << 2))
+
+/**
+ * RL Time Unit Register for priority 0-7
+ * 4 bits per priority
+ * (2^rl_unit)*1us is the actual time period
+ */
+#define PLB0_RL_TU_PRIO (PLB0_BLK_REG_ADDR + 0x084)
+#define PLB1_RL_TU_PRIO (PLB1_BLK_REG_ADDR + 0x084)
+
+/**
+ * RL byte count register,
+ * bytes transmitted in (rl_unit*1)us time period
+ * 1 per priority, 8 in all, 0-7.
+ */
+#define PLB0_RL_BYTE_CNT(_num) \
+ (PLB0_BLK_REG_ADDR + 0x088 + ((_num) << 2))
+#define PLB1_RL_BYTE_CNT(_num) \
+ (PLB1_BLK_REG_ADDR + 0x088 + ((_num) << 2))
+
+/**
+ * RL Min factor register
+ * 2 bits per priority,
+ * 4 factors possible: 1, 0.5, 0.25, 0
+ * 2'b00 - 0; 2'b01 - 0.25; 2'b10 - 0.5; 2'b11 - 1
+ */
+#define PLB0_RL_MIN_REG (PLB0_BLK_REG_ADDR + 0x0A8)
+#define PLB1_RL_MIN_REG (PLB1_BLK_REG_ADDR + 0x0A8)
+
+/**
+ * RL Max factor register
+ * 2 bits per priority,
+ * 4 factors possible: 1, 0.5, 0.25, 0
+ * 2'b00 - 0; 2'b01 - 0.25; 2'b10 - 0.5; 2'b11 - 1
+ */
+#define PLB0_RL_MAX_REG (PLB0_BLK_REG_ADDR + 0x0AC)
+#define PLB1_RL_MAX_REG (PLB1_BLK_REG_ADDR + 0x0AC)
+
+/* MAC SERDES Address Paging register */
+#define PLB0_EMS_ADD_REG (PLB0_BLK_REG_ADDR + 0xD0)
+#define PLB1_EMS_ADD_REG (PLB1_BLK_REG_ADDR + 0xD0)
+
+/* LL EMS Registers */
+#define LL_EMS0_BLK_REG_ADDR 0x00026800
+#define LL_EMS1_BLK_REG_ADDR 0x00026C00
+
+/**
+ * BPC Block Register Address Offset from BAR0
+ * BPC0 Range : 0x23000 - 0x233FF
+ * BPC1 Range : 0x23400 - 0x237FF
+ */
+#define BPC0_BLK_REG_ADDR 0x00023000
+#define BPC1_BLK_REG_ADDR 0x00023400
+
+/**
+ * PMM Block Register Address Offset from BAR0
+ * PMM0 Range : 0x23800 - 0x23BFF
+ * PMM1 Range : 0x23C00 - 0x23FFF
+ */
+#define PMM0_BLK_REG_ADDR 0x00023800
+#define PMM1_BLK_REG_ADDR 0x00023C00
+
+/**
+ * HQM Block Register Address Offset from BAR0
+ * HQM0 Range : 0x24000 - 0x243FF
+ * HQM1 Range : 0x24400 - 0x247FF
+ */
+#define HQM0_BLK_REG_ADDR 0x00024000
+#define HQM1_BLK_REG_ADDR 0x00024400
+
+/**
+ * HQM Control Register
+ * Controls some aspects of IB
+ * See catapult_spec.pdf for details
+ */
+#define HQM0_CTL_REG (HQM0_BLK_REG_ADDR + 0x000)
+#define HQM1_CTL_REG (HQM1_BLK_REG_ADDR + 0x000)
+
+/**
+ * HQM Stop Q Semaphore Registers.
+ * Only one Queue resource can be stopped at
+ * any given time. This register controls access
+ * to the single stop Q resource.
+ * See catapult_spec.pdf for details
+ */
+#define HQM0_RXQ_STOP_SEM (HQM0_BLK_REG_ADDR + 0x028)
+#define HQM0_TXQ_STOP_SEM (HQM0_BLK_REG_ADDR + 0x02C)
+#define HQM1_RXQ_STOP_SEM (HQM1_BLK_REG_ADDR + 0x028)
+#define HQM1_TXQ_STOP_SEM (HQM1_BLK_REG_ADDR + 0x02C)
+
+/**
+ * LUT Block Register Address Offset from BAR0
+ * LUT0 Range : 0x25800 - 0x25BFF
+ * LUT1 Range : 0x25C00 - 0x25FFF
+ */
+#define LUT0_BLK_REG_ADDR 0x00025800
+#define LUT1_BLK_REG_ADDR 0x00025C00
+
+/**
+ * LUT Registers
+ * See catapult_spec.pdf for details
+ */
+#define LUT0_ERR_STS (LUT0_BLK_REG_ADDR + 0x000)
+#define LUT1_ERR_STS (LUT1_BLK_REG_ADDR + 0x000)
+#define LUT0_SET_ERR_STS (LUT0_BLK_REG_ADDR + 0x004)
+#define LUT1_SET_ERR_STS (LUT1_BLK_REG_ADDR + 0x004)
+
+/**
+ * TRC (Debug/Trace) Register Offset from BAR0
+ * Range : 0x26000 -- 0x263FFF
+ */
+#define TRC_BLK_REG_ADDR 0x00026000
+
+/**
+ * TRC Registers
+ * See catapult_spec.pdf for details of each
+ */
+#define TRC_CTL_REG (TRC_BLK_REG_ADDR + 0x000)
+#define TRC_MODS_REG (TRC_BLK_REG_ADDR + 0x004)
+#define TRC_TRGC_REG (TRC_BLK_REG_ADDR + 0x008)
+#define TRC_CNT1_REG (TRC_BLK_REG_ADDR + 0x010)
+#define TRC_CNT2_REG (TRC_BLK_REG_ADDR + 0x014)
+#define TRC_NXTS_REG (TRC_BLK_REG_ADDR + 0x018)
+#define TRC_DIRR_REG (TRC_BLK_REG_ADDR + 0x01C)
+
+/**
+ * TRC Trigger match filters, total 10
+ * Determines the trigger condition
+ */
+#define TRC_TRGM_REG(_num) \
+ (TRC_BLK_REG_ADDR + 0x040 + ((_num) << 2))
+
+/**
+ * TRC Next State filters, total 10
+ * Determines the next state conditions
+ */
+#define TRC_NXTM_REG(_num) \
+ (TRC_BLK_REG_ADDR + 0x080 + ((_num) << 2))
+
+/**
+ * TRC Store Match filters, total 10
+ * Determines the store conditions
+ */
+#define TRC_STRM_REG(_num) \
+ (TRC_BLK_REG_ADDR + 0x0C0 + ((_num) << 2))
+
+/* DOORBELLS ACCESS */
+
+/**
+ * Catapult doorbells
+ * Each doorbell-queue set has
+ * 1 RxQ, 1 TxQ, 2 IBs in that order
+ * Size of each entry in 32 bytes, even though only 1 word
+ * is used. For Non-VM case each doorbell-q set is
+ * separated by 128 bytes, for VM case it is separated
+ * by 4K bytes
+ * Non VM case Range : 0x38000 - 0x39FFF
+ * VM case Range : 0x100000 - 0x11FFFF
+ * The range applies to both HQMs
+ */
+#define HQM_DOORBELL_BLK_BASE_ADDR 0x00038000
+#define HQM_DOORBELL_VM_BLK_BASE_ADDR 0x00100000
+
+/* MEMORY ACCESS */
+
+/**
+ * Catapult H/W Block Memory Access Address
+ * To the host a memory space of 32K (page) is visible
+ * at a time. The address range is from 0x08000 to 0x0FFFF
+ */
+#define HW_BLK_HOST_MEM_ADDR 0x08000
+
+/**
+ * Catapult LUT Memory Access Page Numbers
+ * Range : LUT0 0xa0-0xa1
+ * LUT1 0xa2-0xa3
+ */
+#define LUT0_MEM_BLK_BASE_PG_NUM 0x000000A0
+#define LUT1_MEM_BLK_BASE_PG_NUM 0x000000A2
+
+/**
+ * Catapult RxFn Database Memory Block Base Offset
+ *
+ * The Rx function database exists in LUT block.
+ * In PCIe space this is accessible as a 256x32
+ * bit block. Each entry in this database is 4
+ * (4 byte) words. Max. entries is 64.
+ * Address of an entry corresponding to a function
+ * = base_addr + (function_no. * 16)
+ */
+#define RX_FNDB_RAM_BASE_OFFSET 0x0000B400
+
+/**
+ * Catapult TxFn Database Memory Block Base Offset Address
+ *
+ * The Tx function database exists in LUT block.
+ * In PCIe space this is accessible as a 64x32
+ * bit block. Each entry in this database is 1
+ * (4 byte) word. Max. entries is 64.
+ * Address of an entry corresponding to a function
+ * = base_addr + (function_no. * 4)
+ */
+#define TX_FNDB_RAM_BASE_OFFSET 0x0000B800
+
+/**
+ * Catapult Unicast CAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Shared by both the LL & FCoE driver.
+ * Size is 256x48 bits; mapped to PCIe space
+ * 512x32 bit blocks. For each address, bits
+ * are written in the order : [47:32] and then
+ * [31:0].
+ */
+#define UCAST_CAM_BASE_OFFSET 0x0000A800
+
+/**
+ * Catapult Unicast RAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Shared by both the LL & FCoE driver.
+ * Size is 256x9 bits.
+ */
+#define UCAST_RAM_BASE_OFFSET 0x0000B000
+
+/**
+ * Catapult Mulicast CAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Shared by both the LL & FCoE driver.
+ * Size is 256x48 bits; mapped to PCIe space
+ * 512x32 bit blocks. For each address, bits
+ * are written in the order : [47:32] and then
+ * [31:0].
+ */
+#define MCAST_CAM_BASE_OFFSET 0x0000A000
+
+/**
+ * Catapult VLAN RAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Size is 4096x66 bits; mapped to PCIe space as
+ * 8192x32 bit blocks.
+ * All the 4K entries are within the address range
+ * 0x0000 to 0x8000, so in the first LUT page.
+ */
+#define VLAN_RAM_BASE_OFFSET 0x00000000
+
+/**
+ * Catapult Tx Stats RAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Size is 1024x33 bits;
+ * Each Tx function has 64 bytes of space
+ */
+#define TX_STATS_RAM_BASE_OFFSET 0x00009000
+
+/**
+ * Catapult Rx Stats RAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Size is 1024x33 bits;
+ * Each Rx function has 64 bytes of space
+ */
+#define RX_STATS_RAM_BASE_OFFSET 0x00008000
+
+/* Catapult RXA Memory Access Page Numbers */
+#define RXA0_MEM_BLK_BASE_PG_NUM 0x0000008C
+#define RXA1_MEM_BLK_BASE_PG_NUM 0x0000008D
+
+/**
+ * Catapult Multicast Vector Table Base Offset Address
+ *
+ * Exists in RxA memory space.
+ * Organized as 512x65 bit block.
+ * However for each entry 16 bytes allocated (power of 2)
+ * Total size 512*16 bytes.
+ * There are two logical divisions, 256 entries each :
+ * a) Entries 0x00 to 0xff (256) -- Approx. MVT
+ * Offset 0x000 to 0xFFF
+ * b) Entries 0x100 to 0x1ff (256) -- Exact MVT
+ * Offsets 0x1000 to 0x1FFF
+ */
+#define MCAST_APPROX_MVT_BASE_OFFSET 0x00000000
+#define MCAST_EXACT_MVT_BASE_OFFSET 0x00001000
+
+/**
+ * Catapult RxQ Translate Table (RIT) Base Offset Address
+ *
+ * Exists in RxA memory space
+ * Total no. of entries 64
+ * Each entry is 1 (4 byte) word.
+ * 31:12 -- Reserved
+ * 11:0 -- Two 6 bit RxQ Ids
+ */
+#define FUNCTION_TO_RXQ_TRANSLATE 0x00002000
+
+/* Catapult RxAdm (RAD) Memory Access Page Numbers */
+#define RAD0_MEM_BLK_BASE_PG_NUM 0x00000086
+#define RAD1_MEM_BLK_BASE_PG_NUM 0x00000087
+
+/**
+ * Catapult RSS Table Base Offset Address
+ *
+ * Exists in RAD memory space.
+ * Each entry is 352 bits, but alligned on
+ * 64 byte (512 bit) boundary. Accessed
+ * 4 byte words, the whole entry can be
+ * broken into 11 word accesses.
+ */
+#define RSS_TABLE_BASE_OFFSET 0x00000800
+
+/**
+ * Catapult CPQ Block Page Number
+ * This value is written to the page number registers
+ * to access the memory associated with the mailboxes.
+ */
+#define CPQ_BLK_PG_NUM 0x00000005
+
+/**
+ * Clarification :
+ * LL functions are 2 & 3; can HostFn0/HostFn1
+ * <-> LPU0/LPU1 memories be used ?
+ */
+/**
+ * Catapult HostFn0/HostFn1 to LPU0/LPU1 Mbox memory
+ * Per catapult_spec.pdf, the offset of the mbox
+ * memory is in the register space at an offset of 0x200
+ */
+#define CPQ_BLK_REG_MBOX_ADDR (CPQ_BLK_REG_ADDR + 0x200)
+
+#define HOSTFN_LPU_MBOX (CPQ_BLK_REG_MBOX_ADDR + 0x000)
+
+/* Catapult LPU0/LPU1 to HostFn0/HostFn1 Mbox memory */
+#define LPU_HOSTFN_MBOX (CPQ_BLK_REG_MBOX_ADDR + 0x080)
+
+/**
+ * Catapult HQM Block Page Number
+ * This is written to the page number register for
+ * the appropriate function to access the memory
+ * associated with HQM
+ */
+#define HQM0_BLK_PG_NUM 0x00000096
+#define HQM1_BLK_PG_NUM 0x00000097
+
+/**
+ * Note that TxQ and RxQ entries are interlaced
+ * the HQM memory, i.e RXQ0, TXQ0, RXQ1, TXQ1.. etc.
+ */
+
+#define HQM_RXTX_Q_RAM_BASE_OFFSET 0x00004000
+
+/**
+ * CQ Memory
+ * Exists in HQM Memory space
+ * Each entry is 16 (4 byte) words of which
+ * only 12 words are used for configuration
+ * Total 64 entries per HQM memory space
+ */
+#define HQM_CQ_RAM_BASE_OFFSET 0x00006000
+
+/**
+ * Interrupt Block (IB) Memory
+ * Exists in HQM Memory space
+ * Each entry is 8 (4 byte) words of which
+ * only 5 words are used for configuration
+ * Total 128 entries per HQM memory space
+ */
+#define HQM_IB_RAM_BASE_OFFSET 0x00001000
+
+/**
+ * Index Table (IT) Memory
+ * Exists in HQM Memory space
+ * Each entry is 1 (4 byte) word which
+ * is used for configuration
+ * Total 128 entries per HQM memory space
+ */
+#define HQM_INDX_TBL_RAM_BASE_OFFSET 0x00002000
+
+/**
+ * PSS Block Memory Page Number
+ * This is written to the appropriate page number
+ * register to access the CPU memory.
+ * Also known as the PSS secondary memory (SMEM).
+ * Range : 0x180 to 0x1CF
+ * See catapult_spec.pdf for details
+ */
+#define PSS_BLK_PG_NUM 0x00000180
+
+/**
+ * Offsets of different instances of PSS SMEM
+ * 2.5M of continuous 1T memory space : 2 blocks
+ * of 1M each (32 pages each, page=32KB) and 4 smaller
+ * blocks of 128K each (4 pages each, page=32KB)
+ * PSS_LMEM_INST0 is used for firmware download
+ */
+#define PSS_LMEM_INST0 0x00000000
+#define PSS_LMEM_INST1 0x00100000
+#define PSS_LMEM_INST2 0x00200000
+#define PSS_LMEM_INST3 0x00220000
+#define PSS_LMEM_INST4 0x00240000
+#define PSS_LMEM_INST5 0x00260000
+
+#define BNA_PCI_REG_CT_ADDRSZ (0x40000)
+
+#define BNA_GET_PAGE_NUM(_base_page, _offset) \
+ ((_base_page) + ((_offset) >> 15))
+
+#define BNA_GET_PAGE_OFFSET(_offset) \
+ ((_offset) & 0x7fff)
+
+#define BNA_GET_MEM_BASE_ADDR(_bar0, _base_offset) \
+ ((_bar0) + HW_BLK_HOST_MEM_ADDR \
+ + BNA_GET_PAGE_OFFSET((_base_offset)))
+
+#define BNA_GET_VLAN_MEM_ENTRY_ADDR(_bar0, _fn_id, _vlan_id)\
+ (_bar0 + (HW_BLK_HOST_MEM_ADDR) \
+ + (BNA_GET_PAGE_OFFSET(VLAN_RAM_BASE_OFFSET)) \
+ + (((_fn_id) & 0x3f) << 9) \
+ + (((_vlan_id) & 0xfe0) >> 3))
+
+/**
+ *
+ * Interrupt related bits, flags and macros
+ *
+ */
+
+#define __LPU02HOST_MBOX0_STATUS_BITS 0x00100000
+#define __LPU12HOST_MBOX0_STATUS_BITS 0x00200000
+#define __LPU02HOST_MBOX1_STATUS_BITS 0x00400000
+#define __LPU12HOST_MBOX1_STATUS_BITS 0x00800000
+
+#define __LPU02HOST_MBOX0_MASK_BITS 0x00100000
+#define __LPU12HOST_MBOX0_MASK_BITS 0x00200000
+#define __LPU02HOST_MBOX1_MASK_BITS 0x00400000
+#define __LPU12HOST_MBOX1_MASK_BITS 0x00800000
+
+#define __LPU2HOST_MBOX_MASK_BITS \
+ (__LPU02HOST_MBOX0_MASK_BITS | __LPU02HOST_MBOX1_MASK_BITS | \
+ __LPU12HOST_MBOX0_MASK_BITS | __LPU12HOST_MBOX1_MASK_BITS)
+
+#define __LPU2HOST_IB_STATUS_BITS 0x0000ffff
+
+#define BNA_IS_LPU0_MBOX_INTR(_intr_status) \
+ ((_intr_status) & (__LPU02HOST_MBOX0_STATUS_BITS | \
+ __LPU02HOST_MBOX1_STATUS_BITS))
+
+#define BNA_IS_LPU1_MBOX_INTR(_intr_status) \
+ ((_intr_status) & (__LPU12HOST_MBOX0_STATUS_BITS | \
+ __LPU12HOST_MBOX1_STATUS_BITS))
+
+#define BNA_IS_MBOX_INTR(_intr_status) \
+ ((_intr_status) & \
+ (__LPU02HOST_MBOX0_STATUS_BITS | \
+ __LPU02HOST_MBOX1_STATUS_BITS | \
+ __LPU12HOST_MBOX0_STATUS_BITS | \
+ __LPU12HOST_MBOX1_STATUS_BITS))
+
+#define __EMC_ERROR_STATUS_BITS 0x00010000
+#define __LPU0_ERROR_STATUS_BITS 0x00020000
+#define __LPU1_ERROR_STATUS_BITS 0x00040000
+#define __PSS_ERROR_STATUS_BITS 0x00080000
+
+#define __HALT_STATUS_BITS 0x01000000
+
+#define __EMC_ERROR_MASK_BITS 0x00010000
+#define __LPU0_ERROR_MASK_BITS 0x00020000
+#define __LPU1_ERROR_MASK_BITS 0x00040000
+#define __PSS_ERROR_MASK_BITS 0x00080000
+
+#define __HALT_MASK_BITS 0x01000000
+
+#define __ERROR_MASK_BITS \
+ (__EMC_ERROR_MASK_BITS | __LPU0_ERROR_MASK_BITS | \
+ __LPU1_ERROR_MASK_BITS | __PSS_ERROR_MASK_BITS | \
+ __HALT_MASK_BITS)
+
+#define BNA_IS_ERR_INTR(_intr_status) \
+ ((_intr_status) & \
+ (__EMC_ERROR_STATUS_BITS | \
+ __LPU0_ERROR_STATUS_BITS | \
+ __LPU1_ERROR_STATUS_BITS | \
+ __PSS_ERROR_STATUS_BITS | \
+ __HALT_STATUS_BITS))
+
+#define BNA_IS_MBOX_ERR_INTR(_intr_status) \
+ (BNA_IS_MBOX_INTR((_intr_status)) | \
+ BNA_IS_ERR_INTR((_intr_status)))
+
+#define BNA_IS_INTX_DATA_INTR(_intr_status) \
+ ((_intr_status) & __LPU2HOST_IB_STATUS_BITS)
+
+#define BNA_INTR_STATUS_MBOX_CLR(_intr_status) \
+do { \
+ (_intr_status) &= ~(__LPU02HOST_MBOX0_STATUS_BITS | \
+ __LPU02HOST_MBOX1_STATUS_BITS | \
+ __LPU12HOST_MBOX0_STATUS_BITS | \
+ __LPU12HOST_MBOX1_STATUS_BITS); \
+} while (0)
+
+#define BNA_INTR_STATUS_ERR_CLR(_intr_status) \
+do { \
+ (_intr_status) &= ~(__EMC_ERROR_STATUS_BITS | \
+ __LPU0_ERROR_STATUS_BITS | \
+ __LPU1_ERROR_STATUS_BITS | \
+ __PSS_ERROR_STATUS_BITS | \
+ __HALT_STATUS_BITS); \
+} while (0)
+
+#define bna_intx_disable(_bna, _cur_mask) \
+{ \
+ (_cur_mask) = readl((_bna)->regs.fn_int_mask);\
+ writel(0xffffffff, (_bna)->regs.fn_int_mask);\
+}
+
+#define bna_intx_enable(bna, new_mask) \
+ writel((new_mask), (bna)->regs.fn_int_mask)
+
+#define bna_mbox_intr_disable(bna) \
+ writel((readl((bna)->regs.fn_int_mask) | \
+ (__LPU2HOST_MBOX_MASK_BITS | __ERROR_MASK_BITS)), \
+ (bna)->regs.fn_int_mask)
+
+#define bna_mbox_intr_enable(bna) \
+ writel((readl((bna)->regs.fn_int_mask) & \
+ ~(__LPU2HOST_MBOX_MASK_BITS | __ERROR_MASK_BITS)), \
+ (bna)->regs.fn_int_mask)
+
+#define bna_intr_status_get(_bna, _status) \
+{ \
+ (_status) = readl((_bna)->regs.fn_int_status); \
+ if ((_status)) { \
+ writel((_status) & ~(__LPU02HOST_MBOX0_STATUS_BITS |\
+ __LPU02HOST_MBOX1_STATUS_BITS |\
+ __LPU12HOST_MBOX0_STATUS_BITS |\
+ __LPU12HOST_MBOX1_STATUS_BITS), \
+ (_bna)->regs.fn_int_status);\
+ } \
+}
+
+#define bna_intr_status_get_no_clr(_bna, _status) \
+ (_status) = readl((_bna)->regs.fn_int_status)
+
+#define bna_intr_mask_get(bna, mask) \
+ (*mask) = readl((bna)->regs.fn_int_mask)
+
+#define bna_intr_ack(bna, intr_bmap) \
+ writel((intr_bmap), (bna)->regs.fn_int_status)
+
+#define bna_ib_intx_disable(bna, ib_id) \
+ writel(readl((bna)->regs.fn_int_mask) | \
+ (1 << (ib_id)), \
+ (bna)->regs.fn_int_mask)
+
+#define bna_ib_intx_enable(bna, ib_id) \
+ writel(readl((bna)->regs.fn_int_mask) & \
+ ~(1 << (ib_id)), \
+ (bna)->regs.fn_int_mask)
+
+#define bna_mbox_msix_idx_set(_device) \
+do {\
+ writel(((_device)->vector & 0x000001FF), \
+ (_device)->bna->pcidev.pci_bar_kva + \
+ reg_offset[(_device)->bna->pcidev.pci_func].msix_idx);\
+} while (0)
+
+/**
+ *
+ * TxQ, RxQ, CQ related bits, offsets, macros
+ *
+ */
+
+#define BNA_Q_IDLE_STATE 0x00008001
+
+#define BNA_GET_DOORBELL_BASE_ADDR(_bar0) \
+ ((_bar0) + HQM_DOORBELL_BLK_BASE_ADDR)
+
+#define BNA_GET_DOORBELL_ENTRY_OFFSET(_entry) \
+ ((HQM_DOORBELL_BLK_BASE_ADDR) \
+ + (_entry << 7))
+
+#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \
+ (0x80000000 | ((_timeout) << 16) | (_events))
+
+#define BNA_DOORBELL_IB_INT_DISABLE (0x40000000)
+
+/* TxQ Entry Opcodes */
+#define BNA_TXQ_WI_SEND (0x402) /* Single Frame Transmission */
+#define BNA_TXQ_WI_SEND_LSO (0x403) /* Multi-Frame Transmission */
+#define BNA_TXQ_WI_EXTENSION (0x104) /* Extension WI */
+
+/* TxQ Entry Control Flags */
+#define BNA_TXQ_WI_CF_FCOE_CRC (1 << 8)
+#define BNA_TXQ_WI_CF_IPID_MODE (1 << 5)
+#define BNA_TXQ_WI_CF_INS_PRIO (1 << 4)
+#define BNA_TXQ_WI_CF_INS_VLAN (1 << 3)
+#define BNA_TXQ_WI_CF_UDP_CKSUM (1 << 2)
+#define BNA_TXQ_WI_CF_TCP_CKSUM (1 << 1)
+#define BNA_TXQ_WI_CF_IP_CKSUM (1 << 0)
+
+#define BNA_TXQ_WI_L4_HDR_N_OFFSET(_hdr_size, _offset) \
+ (((_hdr_size) << 10) | ((_offset) & 0x3FF))
+
+/*
+ * Completion Q defines
+ */
+/* CQ Entry Flags */
+#define BNA_CQ_EF_MAC_ERROR (1 << 0)
+#define BNA_CQ_EF_FCS_ERROR (1 << 1)
+#define BNA_CQ_EF_TOO_LONG (1 << 2)
+#define BNA_CQ_EF_FC_CRC_OK (1 << 3)
+
+#define BNA_CQ_EF_RSVD1 (1 << 4)
+#define BNA_CQ_EF_L4_CKSUM_OK (1 << 5)
+#define BNA_CQ_EF_L3_CKSUM_OK (1 << 6)
+#define BNA_CQ_EF_HDS_HEADER (1 << 7)
+
+#define BNA_CQ_EF_UDP (1 << 8)
+#define BNA_CQ_EF_TCP (1 << 9)
+#define BNA_CQ_EF_IP_OPTIONS (1 << 10)
+#define BNA_CQ_EF_IPV6 (1 << 11)
+
+#define BNA_CQ_EF_IPV4 (1 << 12)
+#define BNA_CQ_EF_VLAN (1 << 13)
+#define BNA_CQ_EF_RSS (1 << 14)
+#define BNA_CQ_EF_RSVD2 (1 << 15)
+
+#define BNA_CQ_EF_MCAST_MATCH (1 << 16)
+#define BNA_CQ_EF_MCAST (1 << 17)
+#define BNA_CQ_EF_BCAST (1 << 18)
+#define BNA_CQ_EF_REMOTE (1 << 19)
+
+#define BNA_CQ_EF_LOCAL (1 << 20)
+
+/**
+ *
+ * Data structures
+ *
+ */
+
+enum txf_flags {
+ BFI_TXF_CF_ENABLE = 1 << 0,
+ BFI_TXF_CF_VLAN_FILTER = 1 << 8,
+ BFI_TXF_CF_VLAN_ADMIT = 1 << 9,
+ BFI_TXF_CF_VLAN_INSERT = 1 << 10,
+ BFI_TXF_CF_RSVD1 = 1 << 11,
+ BFI_TXF_CF_MAC_SA_CHECK = 1 << 12,
+ BFI_TXF_CF_VLAN_WI_BASED = 1 << 13,
+ BFI_TXF_CF_VSWITCH_MCAST = 1 << 14,
+ BFI_TXF_CF_VSWITCH_UCAST = 1 << 15,
+ BFI_TXF_CF_RSVD2 = 0x7F << 1
+};
+
+enum ib_flags {
+ BFI_IB_CF_MASTER_ENABLE = (1 << 0),
+ BFI_IB_CF_MSIX_MODE = (1 << 1),
+ BFI_IB_CF_COALESCING_MODE = (1 << 2),
+ BFI_IB_CF_INTER_PKT_ENABLE = (1 << 3),
+ BFI_IB_CF_INT_ENABLE = (1 << 4),
+ BFI_IB_CF_INTER_PKT_DMA = (1 << 5),
+ BFI_IB_CF_ACK_PENDING = (1 << 6),
+ BFI_IB_CF_RESERVED1 = (1 << 7)
+};
+
+enum rss_hash_type {
+ BFI_RSS_T_V4_TCP = (1 << 11),
+ BFI_RSS_T_V4_IP = (1 << 10),
+ BFI_RSS_T_V6_TCP = (1 << 9),
+ BFI_RSS_T_V6_IP = (1 << 8)
+};
+enum hds_header_type {
+ BNA_HDS_T_V4_TCP = (1 << 11),
+ BNA_HDS_T_V4_UDP = (1 << 10),
+ BNA_HDS_T_V6_TCP = (1 << 9),
+ BNA_HDS_T_V6_UDP = (1 << 8),
+ BNA_HDS_FORCED = (1 << 7),
+};
+enum rxf_flags {
+ BNA_RXF_CF_SM_LG_RXQ = (1 << 15),
+ BNA_RXF_CF_DEFAULT_VLAN = (1 << 14),
+ BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE = (1 << 13),
+ BNA_RXF_CF_VLAN_STRIP = (1 << 12),
+ BNA_RXF_CF_RSS_ENABLE = (1 << 8)
+};
+struct bna_chip_regs_offset {
+ u32 page_addr;
+ u32 fn_int_status;
+ u32 fn_int_mask;
+ u32 msix_idx;
+};
+
+struct bna_chip_regs {
+ void __iomem *page_addr;
+ void __iomem *fn_int_status;
+ void __iomem *fn_int_mask;
+};
+
+struct bna_txq_mem {
+ u32 pg_tbl_addr_lo;
+ u32 pg_tbl_addr_hi;
+ u32 cur_q_entry_lo;
+ u32 cur_q_entry_hi;
+ u32 reserved1;
+ u32 reserved2;
+ u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */
+ /* 15:0 ->producer pointer (index?) */
+ u32 entry_n_pg_size; /* 31:16->entry size */
+ /* 15:0 ->page size */
+ u32 int_blk_n_cns_ptr; /* 31:24->Int Blk Id; */
+ /* 23:16->Int Blk Offset */
+ /* 15:0 ->consumer pointer(index?) */
+ u32 cns_ptr2_n_q_state; /* 31:16->cons. ptr 2; 15:0-> Q state */
+ u32 nxt_qid_n_fid_n_pri; /* 17:10->next */
+ /* QId;9:3->FID;2:0->Priority */
+ u32 wvc_n_cquota_n_rquota; /* 31:24->WI Vector Count; */
+ /* 23:12->Cfg Quota; */
+ /* 11:0 ->Run Quota */
+ u32 reserved3[4];
+};
+
+struct bna_rxq_mem {
+ u32 pg_tbl_addr_lo;
+ u32 pg_tbl_addr_hi;
+ u32 cur_q_entry_lo;
+ u32 cur_q_entry_hi;
+ u32 reserved1;
+ u32 reserved2;
+ u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */
+ /* 15:0 ->producer pointer (index?) */
+ u32 entry_n_pg_size; /* 31:16->entry size */
+ /* 15:0 ->page size */
+ u32 sg_n_cq_n_cns_ptr; /* 31:28->reserved; 27:24->sg count */
+ /* 23:16->CQ; */
+ /* 15:0->consumer pointer(index?) */
+ u32 buf_sz_n_q_state; /* 31:16->buffer size; 15:0-> Q state */
+ u32 next_qid; /* 17:10->next QId */
+ u32 reserved3;
+ u32 reserved4[4];
+};
+
+struct bna_rxtx_q_mem {
+ struct bna_rxq_mem rxq;
+ struct bna_txq_mem txq;
+};
+
+struct bna_cq_mem {
+ u32 pg_tbl_addr_lo;
+ u32 pg_tbl_addr_hi;
+ u32 cur_q_entry_lo;
+ u32 cur_q_entry_hi;
+
+ u32 reserved1;
+ u32 reserved2;
+ u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */
+ /* 15:0 ->producer pointer (index?) */
+ u32 entry_n_pg_size; /* 31:16->entry size */
+ /* 15:0 ->page size */
+ u32 int_blk_n_cns_ptr; /* 31:24->Int Blk Id; */
+ /* 23:16->Int Blk Offset */
+ /* 15:0 ->consumer pointer(index?) */
+ u32 q_state; /* 31:16->reserved; 15:0-> Q state */
+ u32 reserved3[2];
+ u32 reserved4[4];
+};
+
+struct bna_ib_blk_mem {
+ u32 host_addr_lo;
+ u32 host_addr_hi;
+ u32 clsc_n_ctrl_n_msix; /* 31:24->coalescing; */
+ /* 23:16->coalescing cfg; */
+ /* 15:8 ->control; */
+ /* 7:0 ->msix; */
+ u32 ipkt_n_ent_n_idxof;
+ u32 ipkt_cnt_cfg_n_unacked;
+
+ u32 reserved[3];
+};
+
+struct bna_idx_tbl_mem {
+ u32 idx; /* !< 31:16->res;15:0->idx; */
+};
+
+struct bna_doorbell_qset {
+ u32 rxq[0x20 >> 2];
+ u32 txq[0x20 >> 2];
+ u32 ib0[0x20 >> 2];
+ u32 ib1[0x20 >> 2];
+};
+
+struct bna_rx_fndb_ram {
+ u32 rss_prop;
+ u32 size_routing_props;
+ u32 rit_hds_mcastq;
+ u32 control_flags;
+};
+
+struct bna_tx_fndb_ram {
+ u32 vlan_n_ctrl_flags;
+};
+
+/**
+ * @brief
+ * Structure which maps to RxFn Indirection Table (RIT)
+ * Size : 1 word
+ * See catapult_spec.pdf, RxA for details
+ */
+struct bna_rit_mem {
+ u32 rxq_ids; /* !< 31:12->res;11:0->two 6 bit RxQ Ids */
+};
+
+/**
+ * @brief
+ * Structure which maps to RSS Table entry
+ * Size : 16 words
+ * See catapult_spec.pdf, RAD for details
+ */
+struct bna_rss_mem {
+ /*
+ * 31:12-> res
+ * 11:8 -> protocol type
+ * 7:0 -> hash index
+ */
+ u32 type_n_hash;
+ u32 hash_key[10]; /* !< 40 byte Toeplitz hash key */
+ u32 reserved[5];
+};
+
+/* TxQ Vector (a.k.a. Tx-Buffer Descriptor) */
+struct bna_dma_addr {
+ u32 msb;
+ u32 lsb;
+};
+
+struct bna_txq_wi_vector {
+ u16 reserved;
+ u16 length; /* Only 14 LSB are valid */
+ struct bna_dma_addr host_addr; /* Tx-Buf DMA addr */
+};
+
+typedef u16 bna_txq_wi_opcode_t;
+
+typedef u16 bna_txq_wi_ctrl_flag_t;
+
+/**
+ * TxQ Entry Structure
+ *
+ * BEWARE: Load values into this structure with correct endianess.
+ */
+struct bna_txq_entry {
+ union {
+ struct {
+ u8 reserved;
+ u8 num_vectors; /* number of vectors present */
+ bna_txq_wi_opcode_t opcode; /* Either */
+ /* BNA_TXQ_WI_SEND or */
+ /* BNA_TXQ_WI_SEND_LSO */
+ bna_txq_wi_ctrl_flag_t flags; /* OR of all the flags */
+ u16 l4_hdr_size_n_offset;
+ u16 vlan_tag;
+ u16 lso_mss; /* Only 14 LSB are valid */
+ u32 frame_length; /* Only 24 LSB are valid */
+ } wi;
+
+ struct {
+ u16 reserved;
+ bna_txq_wi_opcode_t opcode; /* Must be */
+ /* BNA_TXQ_WI_EXTENSION */
+ u32 reserved2[3]; /* Place holder for */
+ /* removed vector (12 bytes) */
+ } wi_ext;
+ } hdr;
+ struct bna_txq_wi_vector vector[4];
+};
+#define wi_hdr hdr.wi
+#define wi_ext_hdr hdr.wi_ext
+
+/* RxQ Entry Structure */
+struct bna_rxq_entry { /* Rx-Buffer */
+ struct bna_dma_addr host_addr; /* Rx-Buffer DMA address */
+};
+
+typedef u32 bna_cq_e_flag_t;
+
+/* CQ Entry Structure */
+struct bna_cq_entry {
+ bna_cq_e_flag_t flags;
+ u16 vlan_tag;
+ u16 length;
+ u32 rss_hash;
+ u8 valid;
+ u8 reserved1;
+ u8 reserved2;
+ u8 rxq_id;
+};
+
+#endif /* __BNA_HW_H__ */
diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c
new file mode 100644
index 000000000000..ad93fdb0f427
--- /dev/null
+++ b/drivers/net/bna/bna_txrx.c
@@ -0,0 +1,4172 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#include "bna.h"
+#include "bfa_sm.h"
+#include "bfi.h"
+
+/**
+ * IB
+ */
+#define bna_ib_find_free_ibidx(_mask, _pos)\
+do {\
+ (_pos) = 0;\
+ while (((_pos) < (BFI_IBIDX_MAX_SEGSIZE)) &&\
+ ((1 << (_pos)) & (_mask)))\
+ (_pos)++;\
+} while (0)
+
+#define bna_ib_count_ibidx(_mask, _count)\
+do {\
+ int pos = 0;\
+ (_count) = 0;\
+ while (pos < (BFI_IBIDX_MAX_SEGSIZE)) {\
+ if ((1 << pos) & (_mask))\
+ (_count) = pos + 1;\
+ pos++;\
+ } \
+} while (0)
+
+#define bna_ib_select_segpool(_count, _q_idx)\
+do {\
+ int i;\
+ (_q_idx) = -1;\
+ for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {\
+ if ((_count <= ibidx_pool[i].pool_entry_size)) {\
+ (_q_idx) = i;\
+ break;\
+ } \
+ } \
+} while (0)
+
+struct bna_ibidx_pool {
+ int pool_size;
+ int pool_entry_size;
+};
+init_ibidx_pool(ibidx_pool);
+
+static struct bna_intr *
+bna_intr_get(struct bna_ib_mod *ib_mod, enum bna_intr_type intr_type,
+ int vector)
+{
+ struct bna_intr *intr;
+ struct list_head *qe;
+
+ list_for_each(qe, &ib_mod->intr_active_q) {
+ intr = (struct bna_intr *)qe;
+
+ if ((intr->intr_type == intr_type) &&
+ (intr->vector == vector)) {
+ intr->ref_count++;
+ return intr;
+ }
+ }
+
+ if (list_empty(&ib_mod->intr_free_q))
+ return NULL;
+
+ bfa_q_deq(&ib_mod->intr_free_q, &intr);
+ bfa_q_qe_init(&intr->qe);
+
+ intr->ref_count = 1;
+ intr->intr_type = intr_type;
+ intr->vector = vector;
+
+ list_add_tail(&intr->qe, &ib_mod->intr_active_q);
+
+ return intr;
+}
+
+static void
+bna_intr_put(struct bna_ib_mod *ib_mod,
+ struct bna_intr *intr)
+{
+ intr->ref_count--;
+
+ if (intr->ref_count == 0) {
+ intr->ib = NULL;
+ list_del(&intr->qe);
+ bfa_q_qe_init(&intr->qe);
+ list_add_tail(&intr->qe, &ib_mod->intr_free_q);
+ }
+}
+
+void
+bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ int i;
+ int j;
+ int count;
+ u8 offset;
+ struct bna_doorbell_qset *qset;
+ unsigned long off;
+
+ ib_mod->bna = bna;
+
+ ib_mod->ib = (struct bna_ib *)
+ res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mdl[0].kva;
+ ib_mod->intr = (struct bna_intr *)
+ res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mdl[0].kva;
+ ib_mod->idx_seg = (struct bna_ibidx_seg *)
+ res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mdl[0].kva;
+
+ INIT_LIST_HEAD(&ib_mod->ib_free_q);
+ INIT_LIST_HEAD(&ib_mod->intr_free_q);
+ INIT_LIST_HEAD(&ib_mod->intr_active_q);
+
+ for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++)
+ INIT_LIST_HEAD(&ib_mod->ibidx_seg_pool[i]);
+
+ for (i = 0; i < BFI_MAX_IB; i++) {
+ ib_mod->ib[i].ib_id = i;
+
+ ib_mod->ib[i].ib_seg_host_addr_kva =
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].kva;
+ ib_mod->ib[i].ib_seg_host_addr.lsb =
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.lsb;
+ ib_mod->ib[i].ib_seg_host_addr.msb =
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.msb;
+
+ qset = (struct bna_doorbell_qset *)0;
+ off = (unsigned long)(&qset[i >> 1].ib0[(i & 0x1)
+ * (0x20 >> 2)]);
+ ib_mod->ib[i].door_bell.doorbell_addr = off +
+ BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva);
+
+ bfa_q_qe_init(&ib_mod->ib[i].qe);
+ list_add_tail(&ib_mod->ib[i].qe, &ib_mod->ib_free_q);
+
+ bfa_q_qe_init(&ib_mod->intr[i].qe);
+ list_add_tail(&ib_mod->intr[i].qe, &ib_mod->intr_free_q);
+ }
+
+ count = 0;
+ offset = 0;
+ for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {
+ for (j = 0; j < ibidx_pool[i].pool_size; j++) {
+ bfa_q_qe_init(&ib_mod->idx_seg[count]);
+ ib_mod->idx_seg[count].ib_seg_size =
+ ibidx_pool[i].pool_entry_size;
+ ib_mod->idx_seg[count].ib_idx_tbl_offset = offset;
+ list_add_tail(&ib_mod->idx_seg[count].qe,
+ &ib_mod->ibidx_seg_pool[i]);
+ count++;
+ offset += ibidx_pool[i].pool_entry_size;
+ }
+ }
+}
+
+void
+bna_ib_mod_uninit(struct bna_ib_mod *ib_mod)
+{
+ int i;
+ int j;
+ struct list_head *qe;
+
+ i = 0;
+ list_for_each(qe, &ib_mod->ib_free_q)
+ i++;
+
+ i = 0;
+ list_for_each(qe, &ib_mod->intr_free_q)
+ i++;
+
+ for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {
+ j = 0;
+ list_for_each(qe, &ib_mod->ibidx_seg_pool[i])
+ j++;
+ }
+
+ ib_mod->bna = NULL;
+}
+
+static struct bna_ib *
+bna_ib_get(struct bna_ib_mod *ib_mod,
+ enum bna_intr_type intr_type,
+ int vector)
+{
+ struct bna_ib *ib;
+ struct bna_intr *intr;
+
+ if (intr_type == BNA_INTR_T_INTX)
+ vector = (1 << vector);
+
+ intr = bna_intr_get(ib_mod, intr_type, vector);
+ if (intr == NULL)
+ return NULL;
+
+ if (intr->ib) {
+ if (intr->ib->ref_count == BFI_IBIDX_MAX_SEGSIZE) {
+ bna_intr_put(ib_mod, intr);
+ return NULL;
+ }
+ intr->ib->ref_count++;
+ return intr->ib;
+ }
+
+ if (list_empty(&ib_mod->ib_free_q)) {
+ bna_intr_put(ib_mod, intr);
+ return NULL;
+ }
+
+ bfa_q_deq(&ib_mod->ib_free_q, &ib);
+ bfa_q_qe_init(&ib->qe);
+
+ ib->ref_count = 1;
+ ib->start_count = 0;
+ ib->idx_mask = 0;
+
+ ib->intr = intr;
+ ib->idx_seg = NULL;
+ intr->ib = ib;
+
+ ib->bna = ib_mod->bna;
+
+ return ib;
+}
+
+static void
+bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib)
+{
+ bna_intr_put(ib_mod, ib->intr);
+
+ ib->ref_count--;
+
+ if (ib->ref_count == 0) {
+ ib->intr = NULL;
+ ib->bna = NULL;
+ list_add_tail(&ib->qe, &ib_mod->ib_free_q);
+ }
+}
+
+/* Returns index offset - starting from 0 */
+static int
+bna_ib_reserve_idx(struct bna_ib *ib)
+{
+ struct bna_ib_mod *ib_mod = &ib->bna->ib_mod;
+ struct bna_ibidx_seg *idx_seg;
+ int idx;
+ int num_idx;
+ int q_idx;
+
+ /* Find the first free index position */
+ bna_ib_find_free_ibidx(ib->idx_mask, idx);
+ if (idx == BFI_IBIDX_MAX_SEGSIZE)
+ return -1;
+
+ /*
+ * Calculate the total number of indexes held by this IB,
+ * including the index newly reserved above.
+ */
+ bna_ib_count_ibidx((ib->idx_mask | (1 << idx)), num_idx);
+
+ /* See if there is a free space in the index segment held by this IB */
+ if (ib->idx_seg && (num_idx <= ib->idx_seg->ib_seg_size)) {
+ ib->idx_mask |= (1 << idx);
+ return idx;
+ }
+
+ if (ib->start_count)
+ return -1;
+
+ /* Allocate a new segment */
+ bna_ib_select_segpool(num_idx, q_idx);
+ while (1) {
+ if (q_idx == BFI_IBIDX_TOTAL_POOLS)
+ return -1;
+ if (!list_empty(&ib_mod->ibidx_seg_pool[q_idx]))
+ break;
+ q_idx++;
+ }
+ bfa_q_deq(&ib_mod->ibidx_seg_pool[q_idx], &idx_seg);
+ bfa_q_qe_init(&idx_seg->qe);
+
+ /* Free the old segment */
+ if (ib->idx_seg) {
+ bna_ib_select_segpool(ib->idx_seg->ib_seg_size, q_idx);
+ list_add_tail(&ib->idx_seg->qe, &ib_mod->ibidx_seg_pool[q_idx]);
+ }
+
+ ib->idx_seg = idx_seg;
+
+ ib->idx_mask |= (1 << idx);
+
+ return idx;
+}
+
+static void
+bna_ib_release_idx(struct bna_ib *ib, int idx)
+{
+ struct bna_ib_mod *ib_mod = &ib->bna->ib_mod;
+ struct bna_ibidx_seg *idx_seg;
+ int num_idx;
+ int cur_q_idx;
+ int new_q_idx;
+
+ ib->idx_mask &= ~(1 << idx);
+
+ if (ib->start_count)
+ return;
+
+ bna_ib_count_ibidx(ib->idx_mask, num_idx);
+
+ /*
+ * Free the segment, if there are no more indexes in the segment
+ * held by this IB
+ */
+ if (!num_idx) {
+ bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx);
+ list_add_tail(&ib->idx_seg->qe,
+ &ib_mod->ibidx_seg_pool[cur_q_idx]);
+ ib->idx_seg = NULL;
+ return;
+ }
+
+ /* See if we can move to a smaller segment */
+ bna_ib_select_segpool(num_idx, new_q_idx);
+ bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx);
+ while (new_q_idx < cur_q_idx) {
+ if (!list_empty(&ib_mod->ibidx_seg_pool[new_q_idx]))
+ break;
+ new_q_idx++;
+ }
+ if (new_q_idx < cur_q_idx) {
+ /* Select the new smaller segment */
+ bfa_q_deq(&ib_mod->ibidx_seg_pool[new_q_idx], &idx_seg);
+ bfa_q_qe_init(&idx_seg->qe);
+ /* Free the old segment */
+ list_add_tail(&ib->idx_seg->qe,
+ &ib_mod->ibidx_seg_pool[cur_q_idx]);
+ ib->idx_seg = idx_seg;
+ }
+}
+
+static int
+bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config)
+{
+ if (ib->start_count)
+ return -1;
+
+ ib->ib_config.coalescing_timeo = ib_config->coalescing_timeo;
+ ib->ib_config.interpkt_timeo = ib_config->interpkt_timeo;
+ ib->ib_config.interpkt_count = ib_config->interpkt_count;
+ ib->ib_config.ctrl_flags = ib_config->ctrl_flags;
+
+ ib->ib_config.ctrl_flags |= BFI_IB_CF_MASTER_ENABLE;
+ if (ib->intr->intr_type == BNA_INTR_T_MSIX)
+ ib->ib_config.ctrl_flags |= BFI_IB_CF_MSIX_MODE;
+
+ return 0;
+}
+
+static void
+bna_ib_start(struct bna_ib *ib)
+{
+ struct bna_ib_blk_mem ib_cfg;
+ struct bna_ib_blk_mem *ib_mem;
+ u32 pg_num;
+ u32 intx_mask;
+ int i;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ ib->start_count++;
+
+ if (ib->start_count > 1)
+ return;
+
+ ib_cfg.host_addr_lo = (u32)(ib->ib_seg_host_addr.lsb);
+ ib_cfg.host_addr_hi = (u32)(ib->ib_seg_host_addr.msb);
+
+ ib_cfg.clsc_n_ctrl_n_msix = (((u32)
+ ib->ib_config.coalescing_timeo << 16) |
+ ((u32)ib->ib_config.ctrl_flags << 8) |
+ (ib->intr->vector));
+ ib_cfg.ipkt_n_ent_n_idxof =
+ ((u32)
+ (ib->ib_config.interpkt_timeo & 0xf) << 16) |
+ ((u32)ib->idx_seg->ib_seg_size << 8) |
+ (ib->idx_seg->ib_idx_tbl_offset);
+ ib_cfg.ipkt_cnt_cfg_n_unacked = ((u32)
+ ib->ib_config.interpkt_count << 24);
+
+ pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num,
+ HQM_IB_RAM_BASE_OFFSET);
+ writel(pg_num, ib->bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva,
+ HQM_IB_RAM_BASE_OFFSET);
+
+ ib_mem = (struct bna_ib_blk_mem *)0;
+ off = (unsigned long)&ib_mem[ib->ib_id].host_addr_lo;
+ writel(htonl(ib_cfg.host_addr_lo), base_addr + off);
+
+ off = (unsigned long)&ib_mem[ib->ib_id].host_addr_hi;
+ writel(htonl(ib_cfg.host_addr_hi), base_addr + off);
+
+ off = (unsigned long)&ib_mem[ib->ib_id].clsc_n_ctrl_n_msix;
+ writel(ib_cfg.clsc_n_ctrl_n_msix, base_addr + off);
+
+ off = (unsigned long)&ib_mem[ib->ib_id].ipkt_n_ent_n_idxof;
+ writel(ib_cfg.ipkt_n_ent_n_idxof, base_addr + off);
+
+ off = (unsigned long)&ib_mem[ib->ib_id].ipkt_cnt_cfg_n_unacked;
+ writel(ib_cfg.ipkt_cnt_cfg_n_unacked, base_addr + off);
+
+ ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK(
+ (u32)ib->ib_config.coalescing_timeo, 0);
+
+ pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num,
+ HQM_INDX_TBL_RAM_BASE_OFFSET);
+ writel(pg_num, ib->bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva,
+ HQM_INDX_TBL_RAM_BASE_OFFSET);
+ for (i = 0; i < ib->idx_seg->ib_seg_size; i++) {
+ off = (unsigned long)
+ ((ib->idx_seg->ib_idx_tbl_offset + i) * BFI_IBIDX_SIZE);
+ writel(0, base_addr + off);
+ }
+
+ if (ib->intr->intr_type == BNA_INTR_T_INTX) {
+ bna_intx_disable(ib->bna, intx_mask);
+ intx_mask &= ~(ib->intr->vector);
+ bna_intx_enable(ib->bna, intx_mask);
+ }
+}
+
+static void
+bna_ib_stop(struct bna_ib *ib)
+{
+ u32 intx_mask;
+
+ ib->start_count--;
+
+ if (ib->start_count == 0) {
+ writel(BNA_DOORBELL_IB_INT_DISABLE,
+ ib->door_bell.doorbell_addr);
+ if (ib->intr->intr_type == BNA_INTR_T_INTX) {
+ bna_intx_disable(ib->bna, intx_mask);
+ intx_mask |= (ib->intr->vector);
+ bna_intx_enable(ib->bna, intx_mask);
+ }
+ }
+}
+
+static void
+bna_ib_fail(struct bna_ib *ib)
+{
+ ib->start_count = 0;
+}
+
+/**
+ * RXF
+ */
+static void rxf_enable(struct bna_rxf *rxf);
+static void rxf_disable(struct bna_rxf *rxf);
+static void __rxf_config_set(struct bna_rxf *rxf);
+static void __rxf_rit_set(struct bna_rxf *rxf);
+static void __bna_rxf_stat_clr(struct bna_rxf *rxf);
+static int rxf_process_packet_filter(struct bna_rxf *rxf);
+static int rxf_clear_packet_filter(struct bna_rxf *rxf);
+static void rxf_reset_packet_filter(struct bna_rxf *rxf);
+static void rxf_cb_enabled(void *arg, int status);
+static void rxf_cb_disabled(void *arg, int status);
+static void bna_rxf_cb_stats_cleared(void *arg, int status);
+static void __rxf_enable(struct bna_rxf *rxf);
+static void __rxf_disable(struct bna_rxf *rxf);
+
+bfa_fsm_state_decl(bna_rxf, stopped, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, start_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, cam_fltr_mod_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, started, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, cam_fltr_clr_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, stop_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, pause_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, resume_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, stat_clr_wait, struct bna_rxf,
+ enum bna_rxf_event);
+
+static struct bfa_sm_table rxf_sm_table[] = {
+ {BFA_SM(bna_rxf_sm_stopped), BNA_RXF_STOPPED},
+ {BFA_SM(bna_rxf_sm_start_wait), BNA_RXF_START_WAIT},
+ {BFA_SM(bna_rxf_sm_cam_fltr_mod_wait), BNA_RXF_CAM_FLTR_MOD_WAIT},
+ {BFA_SM(bna_rxf_sm_started), BNA_RXF_STARTED},
+ {BFA_SM(bna_rxf_sm_cam_fltr_clr_wait), BNA_RXF_CAM_FLTR_CLR_WAIT},
+ {BFA_SM(bna_rxf_sm_stop_wait), BNA_RXF_STOP_WAIT},
+ {BFA_SM(bna_rxf_sm_pause_wait), BNA_RXF_PAUSE_WAIT},
+ {BFA_SM(bna_rxf_sm_resume_wait), BNA_RXF_RESUME_WAIT},
+ {BFA_SM(bna_rxf_sm_stat_clr_wait), BNA_RXF_STAT_CLR_WAIT}
+};
+
+static void
+bna_rxf_sm_stopped_entry(struct bna_rxf *rxf)
+{
+ call_rxf_stop_cbfn(rxf, BNA_CB_SUCCESS);
+}
+
+static void
+bna_rxf_sm_stopped(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_START:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_start_wait);
+ break;
+
+ case RXF_E_STOP:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_FAIL:
+ /* No-op */
+ break;
+
+ case RXF_E_CAM_FLTR_MOD:
+ call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
+ break;
+
+ case RXF_E_STARTED:
+ case RXF_E_STOPPED:
+ case RXF_E_CAM_FLTR_RESP:
+ /**
+ * These events are received due to flushing of mbox
+ * when device fails
+ */
+ /* No-op */
+ break;
+
+ case RXF_E_PAUSE:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
+ call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS);
+ break;
+
+ case RXF_E_RESUME:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
+ call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS);
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_start_wait_entry(struct bna_rxf *rxf)
+{
+ __rxf_config_set(rxf);
+ __rxf_rit_set(rxf);
+ rxf_enable(rxf);
+}
+
+static void
+bna_rxf_sm_start_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_STOP:
+ /**
+ * STOP is originated from bnad. When this happens,
+ * it can not be waiting for filter update
+ */
+ call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait);
+ break;
+
+ case RXF_E_FAIL:
+ call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
+ call_rxf_start_cbfn(rxf, BNA_CB_FAIL);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_CAM_FLTR_MOD:
+ /* No-op */
+ break;
+
+ case RXF_E_STARTED:
+ /**
+ * Force rxf_process_filter() to go through initial
+ * config
+ */
+ if ((rxf->ucast_active_mac != NULL) &&
+ (rxf->ucast_pending_set == 0))
+ rxf->ucast_pending_set = 1;
+
+ if (rxf->rss_status == BNA_STATUS_T_ENABLED)
+ rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING;
+
+ rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
+
+ bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait);
+ break;
+
+ case RXF_E_PAUSE:
+ case RXF_E_RESUME:
+ rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED;
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_cam_fltr_mod_wait_entry(struct bna_rxf *rxf)
+{
+ if (!rxf_process_packet_filter(rxf)) {
+ /* No more pending CAM entries to update */
+ bfa_fsm_set_state(rxf, bna_rxf_sm_started);
+ }
+}
+
+static void
+bna_rxf_sm_cam_fltr_mod_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_STOP:
+ /**
+ * STOP is originated from bnad. When this happens,
+ * it can not be waiting for filter update
+ */
+ call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait);
+ break;
+
+ case RXF_E_FAIL:
+ rxf_reset_packet_filter(rxf);
+ call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
+ call_rxf_start_cbfn(rxf, BNA_CB_FAIL);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_CAM_FLTR_MOD:
+ /* No-op */
+ break;
+
+ case RXF_E_CAM_FLTR_RESP:
+ if (!rxf_process_packet_filter(rxf)) {
+ /* No more pending CAM entries to update */
+ call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_started);
+ }
+ break;
+
+ case RXF_E_PAUSE:
+ case RXF_E_RESUME:
+ rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED;
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_started_entry(struct bna_rxf *rxf)
+{
+ call_rxf_start_cbfn(rxf, BNA_CB_SUCCESS);
+
+ if (rxf->rxf_flags & BNA_RXF_FL_OPERSTATE_CHANGED) {
+ if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
+ bfa_fsm_send_event(rxf, RXF_E_PAUSE);
+ else
+ bfa_fsm_send_event(rxf, RXF_E_RESUME);
+ }
+
+}
+
+static void
+bna_rxf_sm_started(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_STOP:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait);
+ /* Hack to get FSM start clearing CAM entries */
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP);
+ break;
+
+ case RXF_E_FAIL:
+ rxf_reset_packet_filter(rxf);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_CAM_FLTR_MOD:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait);
+ break;
+
+ case RXF_E_PAUSE:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_pause_wait);
+ break;
+
+ case RXF_E_RESUME:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_resume_wait);
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_cam_fltr_clr_wait_entry(struct bna_rxf *rxf)
+{
+ /**
+ * Note: Do not add rxf_clear_packet_filter here.
+ * It will overstep mbox when this transition happens:
+ * cam_fltr_mod_wait -> cam_fltr_clr_wait on RXF_E_STOP event
+ */
+}
+
+static void
+bna_rxf_sm_cam_fltr_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_FAIL:
+ /**
+ * FSM was in the process of stopping, initiated by
+ * bnad. When this happens, no one can be waiting for
+ * start or filter update
+ */
+ rxf_reset_packet_filter(rxf);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_CAM_FLTR_RESP:
+ if (!rxf_clear_packet_filter(rxf)) {
+ /* No more pending CAM entries to clear */
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait);
+ rxf_disable(rxf);
+ }
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_stop_wait_entry(struct bna_rxf *rxf)
+{
+ /**
+ * NOTE: Do not add rxf_disable here.
+ * It will overstep mbox when this transition happens:
+ * start_wait -> stop_wait on RXF_E_STOP event
+ */
+}
+
+static void
+bna_rxf_sm_stop_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_FAIL:
+ /**
+ * FSM was in the process of stopping, initiated by
+ * bnad. When this happens, no one can be waiting for
+ * start or filter update
+ */
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_STARTED:
+ /**
+ * This event is received due to abrupt transition from
+ * bna_rxf_sm_start_wait state on receiving
+ * RXF_E_STOP event
+ */
+ rxf_disable(rxf);
+ break;
+
+ case RXF_E_STOPPED:
+ /**
+ * FSM was in the process of stopping, initiated by
+ * bnad. When this happens, no one can be waiting for
+ * start or filter update
+ */
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stat_clr_wait);
+ break;
+
+ case RXF_E_PAUSE:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
+ break;
+
+ case RXF_E_RESUME:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_pause_wait_entry(struct bna_rxf *rxf)
+{
+ rxf->rxf_flags &=
+ ~(BNA_RXF_FL_OPERSTATE_CHANGED | BNA_RXF_FL_RXF_ENABLED);
+ __rxf_disable(rxf);
+}
+
+static void
+bna_rxf_sm_pause_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_FAIL:
+ /**
+ * FSM was in the process of disabling rxf, initiated by
+ * bnad.
+ */
+ call_rxf_pause_cbfn(rxf, BNA_CB_FAIL);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_STOPPED:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
+ call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_started);
+ break;
+
+ /*
+ * Since PAUSE/RESUME can only be sent by bnad, we don't expect
+ * any other event during these states
+ */
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_resume_wait_entry(struct bna_rxf *rxf)
+{
+ rxf->rxf_flags &= ~(BNA_RXF_FL_OPERSTATE_CHANGED);
+ rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED;
+ __rxf_enable(rxf);
+}
+
+static void
+bna_rxf_sm_resume_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_FAIL:
+ /**
+ * FSM was in the process of disabling rxf, initiated by
+ * bnad.
+ */
+ call_rxf_resume_cbfn(rxf, BNA_CB_FAIL);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_STARTED:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
+ call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_started);
+ break;
+
+ /*
+ * Since PAUSE/RESUME can only be sent by bnad, we don't expect
+ * any other event during these states
+ */
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_stat_clr_wait_entry(struct bna_rxf *rxf)
+{
+ __bna_rxf_stat_clr(rxf);
+}
+
+static void
+bna_rxf_sm_stat_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_FAIL:
+ case RXF_E_STAT_CLEARED:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+__rxf_enable(struct bna_rxf *rxf)
+{
+ struct bfi_ll_rxf_multi_req ll_req;
+ u32 bm[2] = {0, 0};
+
+ if (rxf->rxf_id < 32)
+ bm[0] = 1 << rxf->rxf_id;
+ else
+ bm[1] = 1 << (rxf->rxf_id - 32);
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0);
+ ll_req.rxf_id_mask[0] = htonl(bm[0]);
+ ll_req.rxf_id_mask[1] = htonl(bm[1]);
+ ll_req.enable = 1;
+
+ bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
+ rxf_cb_enabled, rxf);
+
+ bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
+}
+
+static void
+__rxf_disable(struct bna_rxf *rxf)
+{
+ struct bfi_ll_rxf_multi_req ll_req;
+ u32 bm[2] = {0, 0};
+
+ if (rxf->rxf_id < 32)
+ bm[0] = 1 << rxf->rxf_id;
+ else
+ bm[1] = 1 << (rxf->rxf_id - 32);
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0);
+ ll_req.rxf_id_mask[0] = htonl(bm[0]);
+ ll_req.rxf_id_mask[1] = htonl(bm[1]);
+ ll_req.enable = 0;
+
+ bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
+ rxf_cb_disabled, rxf);
+
+ bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
+}
+
+static void
+__rxf_config_set(struct bna_rxf *rxf)
+{
+ u32 i;
+ struct bna_rss_mem *rss_mem;
+ struct bna_rx_fndb_ram *rx_fndb_ram;
+ struct bna *bna = rxf->rx->bna;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
+ RSS_TABLE_BASE_OFFSET);
+
+ rss_mem = (struct bna_rss_mem *)0;
+
+ /* Configure RSS if required */
+ if (rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE) {
+ /* configure RSS Table */
+ writel(BNA_GET_PAGE_NUM(RAD0_MEM_BLK_BASE_PG_NUM +
+ bna->port_num, RSS_TABLE_BASE_OFFSET),
+ bna->regs.page_addr);
+
+ /* temporarily disable RSS, while hash value is written */
+ off = (unsigned long)&rss_mem[0].type_n_hash;
+ writel(0, base_addr + off);
+
+ for (i = 0; i < BFI_RSS_HASH_KEY_LEN; i++) {
+ off = (unsigned long)
+ &rss_mem[0].hash_key[(BFI_RSS_HASH_KEY_LEN - 1) - i];
+ writel(htonl(rxf->rss_cfg.toeplitz_hash_key[i]),
+ base_addr + off);
+ }
+
+ off = (unsigned long)&rss_mem[0].type_n_hash;
+ writel(rxf->rss_cfg.hash_type | rxf->rss_cfg.hash_mask,
+ base_addr + off);
+ }
+
+ /* Configure RxF */
+ writel(BNA_GET_PAGE_NUM(
+ LUT0_MEM_BLK_BASE_PG_NUM + (bna->port_num * 2),
+ RX_FNDB_RAM_BASE_OFFSET),
+ bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
+ RX_FNDB_RAM_BASE_OFFSET);
+
+ rx_fndb_ram = (struct bna_rx_fndb_ram *)0;
+
+ /* We always use RSS table 0 */
+ off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rss_prop;
+ writel(rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE,
+ base_addr + off);
+
+ /* small large buffer enable/disable */
+ off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].size_routing_props;
+ writel((rxf->ctrl_flags & BNA_RXF_CF_SM_LG_RXQ) | 0x80,
+ base_addr + off);
+
+ /* RIT offset, HDS forced offset, multicast RxQ Id */
+ off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rit_hds_mcastq;
+ writel((rxf->rit_segment->rit_offset << 16) |
+ (rxf->forced_offset << 8) |
+ (rxf->hds_cfg.hdr_type & BNA_HDS_FORCED) | rxf->mcast_rxq_id,
+ base_addr + off);
+
+ /*
+ * default vlan tag, default function enable, strip vlan bytes,
+ * HDS type, header size
+ */
+
+ off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].control_flags;
+ writel(((u32)rxf->default_vlan_tag << 16) |
+ (rxf->ctrl_flags &
+ (BNA_RXF_CF_DEFAULT_VLAN |
+ BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE |
+ BNA_RXF_CF_VLAN_STRIP)) |
+ (rxf->hds_cfg.hdr_type & ~BNA_HDS_FORCED) |
+ rxf->hds_cfg.header_size,
+ base_addr + off);
+}
+
+void
+__rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status)
+{
+ struct bna *bna = rxf->rx->bna;
+ int i;
+
+ writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
+ (bna->port_num * 2), VLAN_RAM_BASE_OFFSET),
+ bna->regs.page_addr);
+
+ if (status == BNA_STATUS_T_ENABLED) {
+ /* enable VLAN filtering on this function */
+ for (i = 0; i <= BFI_MAX_VLAN / 32; i++) {
+ writel(rxf->vlan_filter_table[i],
+ BNA_GET_VLAN_MEM_ENTRY_ADDR
+ (bna->pcidev.pci_bar_kva, rxf->rxf_id,
+ i * 32));
+ }
+ } else {
+ /* disable VLAN filtering on this function */
+ for (i = 0; i <= BFI_MAX_VLAN / 32; i++) {
+ writel(0xffffffff,
+ BNA_GET_VLAN_MEM_ENTRY_ADDR
+ (bna->pcidev.pci_bar_kva, rxf->rxf_id,
+ i * 32));
+ }
+ }
+}
+
+static void
+__rxf_rit_set(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+ struct bna_rit_mem *rit_mem;
+ int i;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
+ FUNCTION_TO_RXQ_TRANSLATE);
+
+ rit_mem = (struct bna_rit_mem *)0;
+
+ writel(BNA_GET_PAGE_NUM(RXA0_MEM_BLK_BASE_PG_NUM + bna->port_num,
+ FUNCTION_TO_RXQ_TRANSLATE),
+ bna->regs.page_addr);
+
+ for (i = 0; i < rxf->rit_segment->rit_size; i++) {
+ off = (unsigned long)&rit_mem[i + rxf->rit_segment->rit_offset];
+ writel(rxf->rit_segment->rit[i].large_rxq_id << 6 |
+ rxf->rit_segment->rit[i].small_rxq_id,
+ base_addr + off);
+ }
+}
+
+static void
+__bna_rxf_stat_clr(struct bna_rxf *rxf)
+{
+ struct bfi_ll_stats_req ll_req;
+ u32 bm[2] = {0, 0};
+
+ if (rxf->rxf_id < 32)
+ bm[0] = 1 << rxf->rxf_id;
+ else
+ bm[1] = 1 << (rxf->rxf_id - 32);
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0);
+ ll_req.stats_mask = 0;
+ ll_req.txf_id_mask[0] = 0;
+ ll_req.txf_id_mask[1] = 0;
+
+ ll_req.rxf_id_mask[0] = htonl(bm[0]);
+ ll_req.rxf_id_mask[1] = htonl(bm[1]);
+
+ bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_rxf_cb_stats_cleared, rxf);
+ bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
+}
+
+static void
+rxf_enable(struct bna_rxf *rxf)
+{
+ if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
+ bfa_fsm_send_event(rxf, RXF_E_STARTED);
+ else {
+ rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED;
+ __rxf_enable(rxf);
+ }
+}
+
+static void
+rxf_cb_enabled(void *arg, int status)
+{
+ struct bna_rxf *rxf = (struct bna_rxf *)arg;
+
+ bfa_q_qe_init(&rxf->mbox_qe.qe);
+ bfa_fsm_send_event(rxf, RXF_E_STARTED);
+}
+
+static void
+rxf_disable(struct bna_rxf *rxf)
+{
+ if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
+ bfa_fsm_send_event(rxf, RXF_E_STOPPED);
+ else
+ rxf->rxf_flags &= ~BNA_RXF_FL_RXF_ENABLED;
+ __rxf_disable(rxf);
+}
+
+static void
+rxf_cb_disabled(void *arg, int status)
+{
+ struct bna_rxf *rxf = (struct bna_rxf *)arg;
+
+ bfa_q_qe_init(&rxf->mbox_qe.qe);
+ bfa_fsm_send_event(rxf, RXF_E_STOPPED);
+}
+
+void
+rxf_cb_cam_fltr_mbox_cmd(void *arg, int status)
+{
+ struct bna_rxf *rxf = (struct bna_rxf *)arg;
+
+ bfa_q_qe_init(&rxf->mbox_qe.qe);
+
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP);
+}
+
+static void
+bna_rxf_cb_stats_cleared(void *arg, int status)
+{
+ struct bna_rxf *rxf = (struct bna_rxf *)arg;
+
+ bfa_q_qe_init(&rxf->mbox_qe.qe);
+ bfa_fsm_send_event(rxf, RXF_E_STAT_CLEARED);
+}
+
+void
+rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd,
+ const struct bna_mac *mac_addr)
+{
+ struct bfi_ll_mac_addr_req req;
+
+ bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0);
+
+ req.rxf_id = rxf->rxf_id;
+ memcpy(&req.mac_addr, (void *)&mac_addr->addr, ETH_ALEN);
+
+ bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req),
+ rxf_cb_cam_fltr_mbox_cmd, rxf);
+
+ bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
+}
+
+static int
+rxf_process_packet_filter_mcast(struct bna_rxf *rxf)
+{
+ struct bna_mac *mac = NULL;
+ struct list_head *qe;
+
+ /* Add multicast entries */
+ if (!list_empty(&rxf->mcast_pending_add_q)) {
+ bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_ADD_REQ, mac);
+ list_add_tail(&mac->qe, &rxf->mcast_active_q);
+ return 1;
+ }
+
+ /* Delete multicast entries previousely added */
+ if (!list_empty(&rxf->mcast_pending_del_q)) {
+ bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+rxf_process_packet_filter_vlan(struct bna_rxf *rxf)
+{
+ /* Apply the VLAN filter */
+ if (rxf->rxf_flags & BNA_RXF_FL_VLAN_CONFIG_PENDING) {
+ rxf->rxf_flags &= ~BNA_RXF_FL_VLAN_CONFIG_PENDING;
+ if (!(rxf->rxmode_active & BNA_RXMODE_PROMISC) &&
+ !(rxf->rxmode_active & BNA_RXMODE_DEFAULT))
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ }
+
+ /* Apply RSS configuration */
+ if (rxf->rxf_flags & BNA_RXF_FL_RSS_CONFIG_PENDING) {
+ rxf->rxf_flags &= ~BNA_RXF_FL_RSS_CONFIG_PENDING;
+ if (rxf->rss_status == BNA_STATUS_T_DISABLED) {
+ /* RSS is being disabled */
+ rxf->ctrl_flags &= ~BNA_RXF_CF_RSS_ENABLE;
+ __rxf_rit_set(rxf);
+ __rxf_config_set(rxf);
+ } else {
+ /* RSS is being enabled or reconfigured */
+ rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE;
+ __rxf_rit_set(rxf);
+ __rxf_config_set(rxf);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Processes pending ucast, mcast entry addition/deletion and issues mailbox
+ * command. Also processes pending filter configuration - promiscuous mode,
+ * default mode, allmutli mode and issues mailbox command or directly applies
+ * to h/w
+ */
+static int
+rxf_process_packet_filter(struct bna_rxf *rxf)
+{
+ /* Set the default MAC first */
+ if (rxf->ucast_pending_set > 0) {
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_SET_REQ,
+ rxf->ucast_active_mac);
+ rxf->ucast_pending_set--;
+ return 1;
+ }
+
+ if (rxf_process_packet_filter_ucast(rxf))
+ return 1;
+
+ if (rxf_process_packet_filter_mcast(rxf))
+ return 1;
+
+ if (rxf_process_packet_filter_promisc(rxf))
+ return 1;
+
+ if (rxf_process_packet_filter_default(rxf))
+ return 1;
+
+ if (rxf_process_packet_filter_allmulti(rxf))
+ return 1;
+
+ if (rxf_process_packet_filter_vlan(rxf))
+ return 1;
+
+ return 0;
+}
+
+static int
+rxf_clear_packet_filter_mcast(struct bna_rxf *rxf)
+{
+ struct bna_mac *mac = NULL;
+ struct list_head *qe;
+
+ /* 3. delete pending mcast entries */
+ if (!list_empty(&rxf->mcast_pending_del_q)) {
+ bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ return 1;
+ }
+
+ /* 4. clear active mcast entries; move them to pending_add_q */
+ if (!list_empty(&rxf->mcast_active_q)) {
+ bfa_q_deq(&rxf->mcast_active_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
+ list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * In the rxf stop path, processes pending ucast/mcast delete queue and issues
+ * the mailbox command. Moves the active ucast/mcast entries to pending add q,
+ * so that they are added to CAM again in the rxf start path. Moves the current
+ * filter settings - promiscuous, default, allmutli - to pending filter
+ * configuration
+ */
+static int
+rxf_clear_packet_filter(struct bna_rxf *rxf)
+{
+ if (rxf_clear_packet_filter_ucast(rxf))
+ return 1;
+
+ if (rxf_clear_packet_filter_mcast(rxf))
+ return 1;
+
+ /* 5. clear active default MAC in the CAM */
+ if (rxf->ucast_pending_set > 0)
+ rxf->ucast_pending_set = 0;
+
+ if (rxf_clear_packet_filter_promisc(rxf))
+ return 1;
+
+ if (rxf_clear_packet_filter_default(rxf))
+ return 1;
+
+ if (rxf_clear_packet_filter_allmulti(rxf))
+ return 1;
+
+ return 0;
+}
+
+static void
+rxf_reset_packet_filter_mcast(struct bna_rxf *rxf)
+{
+ struct list_head *qe;
+ struct bna_mac *mac;
+
+ /* 3. Move active mcast entries to pending_add_q */
+ while (!list_empty(&rxf->mcast_active_q)) {
+ bfa_q_deq(&rxf->mcast_active_q, &qe);
+ bfa_q_qe_init(qe);
+ list_add_tail(qe, &rxf->mcast_pending_add_q);
+ }
+
+ /* 4. Throw away delete pending mcast entries */
+ while (!list_empty(&rxf->mcast_pending_del_q)) {
+ bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ }
+}
+
+/**
+ * In the rxf fail path, throws away the ucast/mcast entries pending for
+ * deletion, moves all active ucast/mcast entries to pending queue so that
+ * they are added back to CAM in the rxf start path. Also moves the current
+ * filter configuration to pending filter configuration.
+ */
+static void
+rxf_reset_packet_filter(struct bna_rxf *rxf)
+{
+ rxf_reset_packet_filter_ucast(rxf);
+
+ rxf_reset_packet_filter_mcast(rxf);
+
+ /* 5. Turn off ucast set flag */
+ rxf->ucast_pending_set = 0;
+
+ rxf_reset_packet_filter_promisc(rxf);
+
+ rxf_reset_packet_filter_default(rxf);
+
+ rxf_reset_packet_filter_allmulti(rxf);
+}
+
+static void
+bna_rxf_init(struct bna_rxf *rxf,
+ struct bna_rx *rx,
+ struct bna_rx_config *q_config)
+{
+ struct list_head *qe;
+ struct bna_rxp *rxp;
+
+ /* rxf_id is initialized during rx_mod init */
+ rxf->rx = rx;
+
+ INIT_LIST_HEAD(&rxf->ucast_pending_add_q);
+ INIT_LIST_HEAD(&rxf->ucast_pending_del_q);
+ rxf->ucast_pending_set = 0;
+ INIT_LIST_HEAD(&rxf->ucast_active_q);
+ rxf->ucast_active_mac = NULL;
+
+ INIT_LIST_HEAD(&rxf->mcast_pending_add_q);
+ INIT_LIST_HEAD(&rxf->mcast_pending_del_q);
+ INIT_LIST_HEAD(&rxf->mcast_active_q);
+
+ bfa_q_qe_init(&rxf->mbox_qe.qe);
+
+ if (q_config->vlan_strip_status == BNA_STATUS_T_ENABLED)
+ rxf->ctrl_flags |= BNA_RXF_CF_VLAN_STRIP;
+
+ rxf->rxf_oper_state = (q_config->paused) ?
+ BNA_RXF_OPER_STATE_PAUSED : BNA_RXF_OPER_STATE_RUNNING;
+
+ bna_rxf_adv_init(rxf, rx, q_config);
+
+ rxf->rit_segment = bna_rit_mod_seg_get(&rxf->rx->bna->rit_mod,
+ q_config->num_paths);
+
+ list_for_each(qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe;
+ if (q_config->rxp_type == BNA_RXP_SINGLE)
+ rxf->mcast_rxq_id = rxp->rxq.single.only->rxq_id;
+ else
+ rxf->mcast_rxq_id = rxp->rxq.slr.large->rxq_id;
+ break;
+ }
+
+ rxf->vlan_filter_status = BNA_STATUS_T_DISABLED;
+ memset(rxf->vlan_filter_table, 0,
+ (sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32)));
+
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+}
+
+static void
+bna_rxf_uninit(struct bna_rxf *rxf)
+{
+ struct bna_mac *mac;
+
+ bna_rit_mod_seg_put(&rxf->rx->bna->rit_mod, rxf->rit_segment);
+ rxf->rit_segment = NULL;
+
+ rxf->ucast_pending_set = 0;
+
+ while (!list_empty(&rxf->ucast_pending_add_q)) {
+ bfa_q_deq(&rxf->ucast_pending_add_q, &mac);
+ bfa_q_qe_init(&mac->qe);
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+ }
+
+ if (rxf->ucast_active_mac) {
+ bfa_q_qe_init(&rxf->ucast_active_mac->qe);
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod,
+ rxf->ucast_active_mac);
+ rxf->ucast_active_mac = NULL;
+ }
+
+ while (!list_empty(&rxf->mcast_pending_add_q)) {
+ bfa_q_deq(&rxf->mcast_pending_add_q, &mac);
+ bfa_q_qe_init(&mac->qe);
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ }
+
+ rxf->rx = NULL;
+}
+
+static void
+bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status status)
+{
+ bfa_fsm_send_event(rx, RX_E_RXF_STARTED);
+ if (rx->rxf.rxf_id < 32)
+ rx->bna->rx_mod.rxf_bmap[0] |= ((u32)1 << rx->rxf.rxf_id);
+ else
+ rx->bna->rx_mod.rxf_bmap[1] |= ((u32)
+ 1 << (rx->rxf.rxf_id - 32));
+}
+
+static void
+bna_rxf_start(struct bna_rxf *rxf)
+{
+ rxf->start_cbfn = bna_rx_cb_rxf_started;
+ rxf->start_cbarg = rxf->rx;
+ rxf->rxf_flags &= ~BNA_RXF_FL_FAILED;
+ bfa_fsm_send_event(rxf, RXF_E_START);
+}
+
+static void
+bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status status)
+{
+ bfa_fsm_send_event(rx, RX_E_RXF_STOPPED);
+ if (rx->rxf.rxf_id < 32)
+ rx->bna->rx_mod.rxf_bmap[0] &= ~(u32)1 << rx->rxf.rxf_id;
+ else
+ rx->bna->rx_mod.rxf_bmap[1] &= ~(u32)
+ 1 << (rx->rxf.rxf_id - 32);
+}
+
+static void
+bna_rxf_stop(struct bna_rxf *rxf)
+{
+ rxf->stop_cbfn = bna_rx_cb_rxf_stopped;
+ rxf->stop_cbarg = rxf->rx;
+ bfa_fsm_send_event(rxf, RXF_E_STOP);
+}
+
+static void
+bna_rxf_fail(struct bna_rxf *rxf)
+{
+ rxf->rxf_flags |= BNA_RXF_FL_FAILED;
+ bfa_fsm_send_event(rxf, RXF_E_FAIL);
+}
+
+int
+bna_rxf_state_get(struct bna_rxf *rxf)
+{
+ return bfa_sm_to_state(rxf_sm_table, rxf->fsm);
+}
+
+enum bna_cb_status
+bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+
+ if (rxf->ucast_active_mac == NULL) {
+ rxf->ucast_active_mac =
+ bna_ucam_mod_mac_get(&rxf->rx->bna->ucam_mod);
+ if (rxf->ucast_active_mac == NULL)
+ return BNA_CB_UCAST_CAM_FULL;
+ bfa_q_qe_init(&rxf->ucast_active_mac->qe);
+ }
+
+ memcpy(rxf->ucast_active_mac->addr, ucmac, ETH_ALEN);
+ rxf->ucast_pending_set++;
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+
+ return BNA_CB_SUCCESS;
+}
+
+enum bna_cb_status
+bna_rx_mcast_add(struct bna_rx *rx, u8 *addr,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ struct list_head *qe;
+ struct bna_mac *mac;
+
+ /* Check if already added */
+ list_for_each(qe, &rxf->mcast_active_q) {
+ mac = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
+ if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+ return BNA_CB_SUCCESS;
+ }
+ }
+
+ /* Check if pending addition */
+ list_for_each(qe, &rxf->mcast_pending_add_q) {
+ mac = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
+ if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+ return BNA_CB_SUCCESS;
+ }
+ }
+
+ mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod);
+ if (mac == NULL)
+ return BNA_CB_MCAST_LIST_FULL;
+ bfa_q_qe_init(&mac->qe);
+ memcpy(mac->addr, addr, ETH_ALEN);
+ list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
+
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+
+ return BNA_CB_SUCCESS;
+}
+
+enum bna_cb_status
+bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mclist,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ struct list_head list_head;
+ struct list_head *qe;
+ u8 *mcaddr;
+ struct bna_mac *mac;
+ struct bna_mac *mac1;
+ int skip;
+ int delete;
+ int need_hw_config = 0;
+ int i;
+
+ /* Allocate nodes */
+ INIT_LIST_HEAD(&list_head);
+ for (i = 0, mcaddr = mclist; i < count; i++) {
+ mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod);
+ if (mac == NULL)
+ goto err_return;
+ bfa_q_qe_init(&mac->qe);
+ memcpy(mac->addr, mcaddr, ETH_ALEN);
+ list_add_tail(&mac->qe, &list_head);
+
+ mcaddr += ETH_ALEN;
+ }
+
+ /* Schedule for addition */
+ while (!list_empty(&list_head)) {
+ bfa_q_deq(&list_head, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+
+ skip = 0;
+
+ /* Skip if already added */
+ list_for_each(qe, &rxf->mcast_active_q) {
+ mac1 = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) {
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod,
+ mac);
+ skip = 1;
+ break;
+ }
+ }
+
+ if (skip)
+ continue;
+
+ /* Skip if pending addition */
+ list_for_each(qe, &rxf->mcast_pending_add_q) {
+ mac1 = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) {
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod,
+ mac);
+ skip = 1;
+ break;
+ }
+ }
+
+ if (skip)
+ continue;
+
+ need_hw_config = 1;
+ list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
+ }
+
+ /**
+ * Delete the entries that are in the pending_add_q but not
+ * in the new list
+ */
+ while (!list_empty(&rxf->mcast_pending_add_q)) {
+ bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) {
+ if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) {
+ delete = 0;
+ break;
+ }
+ mcaddr += ETH_ALEN;
+ }
+ if (delete)
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ else
+ list_add_tail(&mac->qe, &list_head);
+ }
+ while (!list_empty(&list_head)) {
+ bfa_q_deq(&list_head, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
+ }
+
+ /**
+ * Schedule entries for deletion that are in the active_q but not
+ * in the new list
+ */
+ while (!list_empty(&rxf->mcast_active_q)) {
+ bfa_q_deq(&rxf->mcast_active_q, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) {
+ if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) {
+ delete = 0;
+ break;
+ }
+ mcaddr += ETH_ALEN;
+ }
+ if (delete) {
+ list_add_tail(&mac->qe, &rxf->mcast_pending_del_q);
+ need_hw_config = 1;
+ } else {
+ list_add_tail(&mac->qe, &list_head);
+ }
+ }
+ while (!list_empty(&list_head)) {
+ bfa_q_deq(&list_head, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ list_add_tail(&mac->qe, &rxf->mcast_active_q);
+ }
+
+ if (need_hw_config) {
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ } else if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+
+ return BNA_CB_SUCCESS;
+
+err_return:
+ while (!list_empty(&list_head)) {
+ bfa_q_deq(&list_head, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ }
+
+ return BNA_CB_MCAST_LIST_FULL;
+}
+
+void
+bna_rx_vlan_add(struct bna_rx *rx, int vlan_id)
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ int index = (vlan_id >> 5);
+ int bit = (1 << (vlan_id & 0x1F));
+
+ rxf->vlan_filter_table[index] |= bit;
+ if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
+ rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ }
+}
+
+void
+bna_rx_vlan_del(struct bna_rx *rx, int vlan_id)
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ int index = (vlan_id >> 5);
+ int bit = (1 << (vlan_id & 0x1F));
+
+ rxf->vlan_filter_table[index] &= ~bit;
+ if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
+ rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ }
+}
+
+/**
+ * RX
+ */
+#define RXQ_RCB_INIT(q, rxp, qdepth, bna, _id, unmapq_mem) do { \
+ struct bna_doorbell_qset *_qset; \
+ unsigned long off; \
+ (q)->rcb->producer_index = (q)->rcb->consumer_index = 0; \
+ (q)->rcb->q_depth = (qdepth); \
+ (q)->rcb->unmap_q = unmapq_mem; \
+ (q)->rcb->rxq = (q); \
+ (q)->rcb->cq = &(rxp)->cq; \
+ (q)->rcb->bnad = (bna)->bnad; \
+ _qset = (struct bna_doorbell_qset *)0; \
+ off = (unsigned long)&_qset[(q)->rxq_id].rxq[0]; \
+ (q)->rcb->q_dbell = off + \
+ BNA_GET_DOORBELL_BASE_ADDR((bna)->pcidev.pci_bar_kva); \
+ (q)->rcb->id = _id; \
+} while (0)
+
+#define BNA_GET_RXQS(qcfg) (((qcfg)->rxp_type == BNA_RXP_SINGLE) ? \
+ (qcfg)->num_paths : ((qcfg)->num_paths * 2))
+
+#define SIZE_TO_PAGES(size) (((size) >> PAGE_SHIFT) + ((((size) &\
+ (PAGE_SIZE - 1)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
+
+#define call_rx_stop_callback(rx, status) \
+ if ((rx)->stop_cbfn) { \
+ (*(rx)->stop_cbfn)((rx)->stop_cbarg, rx, (status)); \
+ (rx)->stop_cbfn = NULL; \
+ (rx)->stop_cbarg = NULL; \
+ }
+
+/*
+ * Since rx_enable is synchronous callback, there is no start_cbfn required.
+ * Instead, we'll call bnad_rx_post(rxp) so that bnad can post the buffers
+ * for each rxpath.
+ */
+
+#define call_rx_disable_cbfn(rx, status) \
+ if ((rx)->disable_cbfn) { \
+ (*(rx)->disable_cbfn)((rx)->disable_cbarg, \
+ status); \
+ (rx)->disable_cbfn = NULL; \
+ (rx)->disable_cbarg = NULL; \
+ } \
+
+#define rxqs_reqd(type, num_rxqs) \
+ (((type) == BNA_RXP_SINGLE) ? (num_rxqs) : ((num_rxqs) * 2))
+
+#define rx_ib_fail(rx) \
+do { \
+ struct bna_rxp *rxp; \
+ struct list_head *qe; \
+ list_for_each(qe, &(rx)->rxp_q) { \
+ rxp = (struct bna_rxp *)qe; \
+ bna_ib_fail(rxp->cq.ib); \
+ } \
+} while (0)
+
+static void __bna_multi_rxq_stop(struct bna_rxp *, u32 *);
+static void __bna_rxq_start(struct bna_rxq *rxq);
+static void __bna_cq_start(struct bna_cq *cq);
+static void bna_rit_create(struct bna_rx *rx);
+static void bna_rx_cb_multi_rxq_stopped(void *arg, int status);
+static void bna_rx_cb_rxq_stopped_all(void *arg);
+
+bfa_fsm_state_decl(bna_rx, stopped,
+ struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, rxf_start_wait,
+ struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, started,
+ struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, rxf_stop_wait,
+ struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, rxq_stop_wait,
+ struct bna_rx, enum bna_rx_event);
+
+static const struct bfa_sm_table rx_sm_table[] = {
+ {BFA_SM(bna_rx_sm_stopped), BNA_RX_STOPPED},
+ {BFA_SM(bna_rx_sm_rxf_start_wait), BNA_RX_RXF_START_WAIT},
+ {BFA_SM(bna_rx_sm_started), BNA_RX_STARTED},
+ {BFA_SM(bna_rx_sm_rxf_stop_wait), BNA_RX_RXF_STOP_WAIT},
+ {BFA_SM(bna_rx_sm_rxq_stop_wait), BNA_RX_RXQ_STOP_WAIT},
+};
+
+static void bna_rx_sm_stopped_entry(struct bna_rx *rx)
+{
+ struct bna_rxp *rxp;
+ struct list_head *qe_rxp;
+
+ list_for_each(qe_rxp, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe_rxp;
+ rx->rx_cleanup_cbfn(rx->bna->bnad, rxp->cq.ccb);
+ }
+
+ call_rx_stop_callback(rx, BNA_CB_SUCCESS);
+}
+
+static void bna_rx_sm_stopped(struct bna_rx *rx,
+ enum bna_rx_event event)
+{
+ switch (event) {
+ case RX_E_START:
+ bfa_fsm_set_state(rx, bna_rx_sm_rxf_start_wait);
+ break;
+ case RX_E_STOP:
+ call_rx_stop_callback(rx, BNA_CB_SUCCESS);
+ break;
+ case RX_E_FAIL:
+ /* no-op */
+ break;
+ default:
+ bfa_sm_fault(rx->bna, event);
+ break;
+ }
+
+}
+
+static void bna_rx_sm_rxf_start_wait_entry(struct bna_rx *rx)
+{
+ struct bna_rxp *rxp;
+ struct list_head *qe_rxp;
+ struct bna_rxq *q0 = NULL, *q1 = NULL;
+
+ /* Setup the RIT */
+ bna_rit_create(rx);
+
+ list_for_each(qe_rxp, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe_rxp;
+ bna_ib_start(rxp->cq.ib);
+ GET_RXQS(rxp, q0, q1);
+ q0->buffer_size = bna_port_mtu_get(&rx->bna->port);
+ __bna_rxq_start(q0);
+ rx->rx_post_cbfn(rx->bna->bnad, q0->rcb);
+ if (q1) {
+ __bna_rxq_start(q1);
+ rx->rx_post_cbfn(rx->bna->bnad, q1->rcb);
+ }
+ __bna_cq_start(&rxp->cq);
+ }
+
+ bna_rxf_start(&rx->rxf);
+}
+
+static void bna_rx_sm_rxf_start_wait(struct bna_rx *rx,
+ enum bna_rx_event event)
+{
+ switch (event) {
+ case RX_E_STOP:
+ bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
+ break;
+ case RX_E_FAIL:
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+ rx_ib_fail(rx);
+ bna_rxf_fail(&rx->rxf);
+ break;
+ case RX_E_RXF_STARTED:
+ bfa_fsm_set_state(rx, bna_rx_sm_started);
+ break;
+ default:
+ bfa_sm_fault(rx->bna, event);
+ break;
+ }
+}
+
+void
+bna_rx_sm_started_entry(struct bna_rx *rx)
+{
+ struct bna_rxp *rxp;
+ struct list_head *qe_rxp;
+
+ /* Start IB */
+ list_for_each(qe_rxp, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe_rxp;
+ bna_ib_ack(&rxp->cq.ib->door_bell, 0);
+ }
+
+ bna_llport_admin_up(&rx->bna->port.llport);
+}
+
+void
+bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event)
+{
+ switch (event) {
+ case RX_E_FAIL:
+ bna_llport_admin_down(&rx->bna->port.llport);
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+ rx_ib_fail(rx);
+ bna_rxf_fail(&rx->rxf);
+ break;
+ case RX_E_STOP:
+ bna_llport_admin_down(&rx->bna->port.llport);
+ bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
+ break;
+ default:
+ bfa_sm_fault(rx->bna, event);
+ break;
+ }
+}
+
+void
+bna_rx_sm_rxf_stop_wait_entry(struct bna_rx *rx)
+{
+ bna_rxf_stop(&rx->rxf);
+}
+
+void
+bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
+{
+ switch (event) {
+ case RX_E_RXF_STOPPED:
+ bfa_fsm_set_state(rx, bna_rx_sm_rxq_stop_wait);
+ break;
+ case RX_E_RXF_STARTED:
+ /**
+ * RxF was in the process of starting up when
+ * RXF_E_STOP was issued. Ignore this event
+ */
+ break;
+ case RX_E_FAIL:
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+ rx_ib_fail(rx);
+ bna_rxf_fail(&rx->rxf);
+ break;
+ default:
+ bfa_sm_fault(rx->bna, event);
+ break;
+ }
+
+}
+
+void
+bna_rx_sm_rxq_stop_wait_entry(struct bna_rx *rx)
+{
+ struct bna_rxp *rxp = NULL;
+ struct bna_rxq *q0 = NULL;
+ struct bna_rxq *q1 = NULL;
+ struct list_head *qe;
+ u32 rxq_mask[2] = {0, 0};
+
+ /* Only one call to multi-rxq-stop for all RXPs in this RX */
+ bfa_wc_up(&rx->rxq_stop_wc);
+ list_for_each(qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe;
+ GET_RXQS(rxp, q0, q1);
+ if (q0->rxq_id < 32)
+ rxq_mask[0] |= ((u32)1 << q0->rxq_id);
+ else
+ rxq_mask[1] |= ((u32)1 << (q0->rxq_id - 32));
+ if (q1) {
+ if (q1->rxq_id < 32)
+ rxq_mask[0] |= ((u32)1 << q1->rxq_id);
+ else
+ rxq_mask[1] |= ((u32)
+ 1 << (q1->rxq_id - 32));
+ }
+ }
+
+ __bna_multi_rxq_stop(rxp, rxq_mask);
+}
+
+void
+bna_rx_sm_rxq_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
+{
+ struct bna_rxp *rxp = NULL;
+ struct list_head *qe;
+
+ switch (event) {
+ case RX_E_RXQ_STOPPED:
+ list_for_each(qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe;
+ bna_ib_stop(rxp->cq.ib);
+ }
+ /* Fall through */
+ case RX_E_FAIL:
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+ break;
+ default:
+ bfa_sm_fault(rx->bna, event);
+ break;
+ }
+}
+
+void
+__bna_multi_rxq_stop(struct bna_rxp *rxp, u32 * rxq_id_mask)
+{
+ struct bfi_ll_q_stop_req ll_req;
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RXQ_STOP_REQ, 0);
+ ll_req.q_id_mask[0] = htonl(rxq_id_mask[0]);
+ ll_req.q_id_mask[1] = htonl(rxq_id_mask[1]);
+ bna_mbox_qe_fill(&rxp->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_rx_cb_multi_rxq_stopped, rxp);
+ bna_mbox_send(rxp->rx->bna, &rxp->mbox_qe);
+}
+
+void
+__bna_rxq_start(struct bna_rxq *rxq)
+{
+ struct bna_rxtx_q_mem *q_mem;
+ struct bna_rxq_mem rxq_cfg, *rxq_mem;
+ struct bna_dma_addr cur_q_addr;
+ /* struct bna_doorbell_qset *qset; */
+ struct bna_qpt *qpt;
+ u32 pg_num;
+ struct bna *bna = rxq->rx->bna;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ qpt = &rxq->qpt;
+ cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr));
+
+ rxq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb;
+ rxq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb;
+ rxq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
+ rxq_cfg.cur_q_entry_hi = cur_q_addr.msb;
+
+ rxq_cfg.pg_cnt_n_prd_ptr = ((u32)qpt->page_count << 16) | 0x0;
+ rxq_cfg.entry_n_pg_size = ((u32)(BFI_RXQ_WI_SIZE >> 2) << 16) |
+ (qpt->page_size >> 2);
+ rxq_cfg.sg_n_cq_n_cns_ptr =
+ ((u32)(rxq->rxp->cq.cq_id & 0xff) << 16) | 0x0;
+ rxq_cfg.buf_sz_n_q_state = ((u32)rxq->buffer_size << 16) |
+ BNA_Q_IDLE_STATE;
+ rxq_cfg.next_qid = 0x0 | (0x3 << 8);
+
+ /* Write the page number register */
+ pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num,
+ HQM_RXTX_Q_RAM_BASE_OFFSET);
+ writel(pg_num, bna->regs.page_addr);
+
+ /* Write to h/w */
+ base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
+ HQM_RXTX_Q_RAM_BASE_OFFSET);
+
+ q_mem = (struct bna_rxtx_q_mem *)0;
+ rxq_mem = &q_mem[rxq->rxq_id].rxq;
+
+ off = (unsigned long)&rxq_mem->pg_tbl_addr_lo;
+ writel(htonl(rxq_cfg.pg_tbl_addr_lo), base_addr + off);
+
+ off = (unsigned long)&rxq_mem->pg_tbl_addr_hi;
+ writel(htonl(rxq_cfg.pg_tbl_addr_hi), base_addr + off);
+
+ off = (unsigned long)&rxq_mem->cur_q_entry_lo;
+ writel(htonl(rxq_cfg.cur_q_entry_lo), base_addr + off);
+
+ off = (unsigned long)&rxq_mem->cur_q_entry_hi;
+ writel(htonl(rxq_cfg.cur_q_entry_hi), base_addr + off);
+
+ off = (unsigned long)&rxq_mem->pg_cnt_n_prd_ptr;
+ writel(rxq_cfg.pg_cnt_n_prd_ptr, base_addr + off);
+
+ off = (unsigned long)&rxq_mem->entry_n_pg_size;
+ writel(rxq_cfg.entry_n_pg_size, base_addr + off);
+
+ off = (unsigned long)&rxq_mem->sg_n_cq_n_cns_ptr;
+ writel(rxq_cfg.sg_n_cq_n_cns_ptr, base_addr + off);
+
+ off = (unsigned long)&rxq_mem->buf_sz_n_q_state;
+ writel(rxq_cfg.buf_sz_n_q_state, base_addr + off);
+
+ off = (unsigned long)&rxq_mem->next_qid;
+ writel(rxq_cfg.next_qid, base_addr + off);
+
+ rxq->rcb->producer_index = 0;
+ rxq->rcb->consumer_index = 0;
+}
+
+void
+__bna_cq_start(struct bna_cq *cq)
+{
+ struct bna_cq_mem cq_cfg, *cq_mem;
+ const struct bna_qpt *qpt;
+ struct bna_dma_addr cur_q_addr;
+ u32 pg_num;
+ struct bna *bna = cq->rx->bna;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ qpt = &cq->qpt;
+ cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr));
+
+ /*
+ * Fill out structure, to be subsequently written
+ * to hardware
+ */
+ cq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb;
+ cq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb;
+ cq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
+ cq_cfg.cur_q_entry_hi = cur_q_addr.msb;
+
+ cq_cfg.pg_cnt_n_prd_ptr = (qpt->page_count << 16) | 0x0;
+ cq_cfg.entry_n_pg_size =
+ ((u32)(BFI_CQ_WI_SIZE >> 2) << 16) | (qpt->page_size >> 2);
+ cq_cfg.int_blk_n_cns_ptr = ((((u32)cq->ib_seg_offset) << 24) |
+ ((u32)(cq->ib->ib_id & 0xff) << 16) | 0x0);
+ cq_cfg.q_state = BNA_Q_IDLE_STATE;
+
+ /* Write the page number register */
+ pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num,
+ HQM_CQ_RAM_BASE_OFFSET);
+
+ writel(pg_num, bna->regs.page_addr);
+
+ /* H/W write */
+ base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
+ HQM_CQ_RAM_BASE_OFFSET);
+
+ cq_mem = (struct bna_cq_mem *)0;
+
+ off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_lo;
+ writel(htonl(cq_cfg.pg_tbl_addr_lo), base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_hi;
+ writel(htonl(cq_cfg.pg_tbl_addr_hi), base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_lo;
+ writel(htonl(cq_cfg.cur_q_entry_lo), base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_hi;
+ writel(htonl(cq_cfg.cur_q_entry_hi), base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].pg_cnt_n_prd_ptr;
+ writel(cq_cfg.pg_cnt_n_prd_ptr, base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].entry_n_pg_size;
+ writel(cq_cfg.entry_n_pg_size, base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].int_blk_n_cns_ptr;
+ writel(cq_cfg.int_blk_n_cns_ptr, base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].q_state;
+ writel(cq_cfg.q_state, base_addr + off);
+
+ cq->ccb->producer_index = 0;
+ *(cq->ccb->hw_producer_index) = 0;
+}
+
+void
+bna_rit_create(struct bna_rx *rx)
+{
+ struct list_head *qe_rxp;
+ struct bna *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;
+ GET_RXQS(rxp, q0, q1);
+ rx->rxf.rit_segment->rit[offset].large_rxq_id = q0->rxq_id;
+ rx->rxf.rit_segment->rit[offset].small_rxq_id =
+ (q1 ? q1->rxq_id : 0);
+ offset++;
+ }
+}
+
+static int
+_rx_can_satisfy(struct bna_rx_mod *rx_mod,
+ struct bna_rx_config *rx_cfg)
+{
+ if ((rx_mod->rx_free_count == 0) ||
+ (rx_mod->rxp_free_count == 0) ||
+ (rx_mod->rxq_free_count == 0))
+ return 0;
+
+ if (rx_cfg->rxp_type == BNA_RXP_SINGLE) {
+ if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
+ (rx_mod->rxq_free_count < rx_cfg->num_paths))
+ return 0;
+ } else {
+ if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
+ (rx_mod->rxq_free_count < (2 * rx_cfg->num_paths)))
+ return 0;
+ }
+
+ if (!bna_rit_mod_can_satisfy(&rx_mod->bna->rit_mod, rx_cfg->num_paths))
+ return 0;
+
+ return 1;
+}
+
+static struct bna_rxq *
+_get_free_rxq(struct bna_rx_mod *rx_mod)
+{
+ struct bna_rxq *rxq = NULL;
+ struct list_head *qe = NULL;
+
+ bfa_q_deq(&rx_mod->rxq_free_q, &qe);
+ if (qe) {
+ rx_mod->rxq_free_count--;
+ rxq = (struct bna_rxq *)qe;
+ }
+ return rxq;
+}
+
+static void
+_put_free_rxq(struct bna_rx_mod *rx_mod, struct bna_rxq *rxq)
+{
+ bfa_q_qe_init(&rxq->qe);
+ list_add_tail(&rxq->qe, &rx_mod->rxq_free_q);
+ rx_mod->rxq_free_count++;
+}
+
+static struct bna_rxp *
+_get_free_rxp(struct bna_rx_mod *rx_mod)
+{
+ struct list_head *qe = NULL;
+ struct bna_rxp *rxp = NULL;
+
+ bfa_q_deq(&rx_mod->rxp_free_q, &qe);
+ if (qe) {
+ rx_mod->rxp_free_count--;
+
+ rxp = (struct bna_rxp *)qe;
+ }
+
+ return rxp;
+}
+
+static void
+_put_free_rxp(struct bna_rx_mod *rx_mod, struct bna_rxp *rxp)
+{
+ bfa_q_qe_init(&rxp->qe);
+ list_add_tail(&rxp->qe, &rx_mod->rxp_free_q);
+ rx_mod->rxp_free_count++;
+}
+
+static struct bna_rx *
+_get_free_rx(struct bna_rx_mod *rx_mod)
+{
+ struct list_head *qe = NULL;
+ struct bna_rx *rx = NULL;
+
+ bfa_q_deq(&rx_mod->rx_free_q, &qe);
+ if (qe) {
+ rx_mod->rx_free_count--;
+
+ rx = (struct bna_rx *)qe;
+ bfa_q_qe_init(qe);
+ list_add_tail(&rx->qe, &rx_mod->rx_active_q);
+ }
+
+ return rx;
+}
+
+static void
+_put_free_rx(struct bna_rx_mod *rx_mod, struct bna_rx *rx)
+{
+ bfa_q_qe_init(&rx->qe);
+ list_add_tail(&rx->qe, &rx_mod->rx_free_q);
+ rx_mod->rx_free_count++;
+}
+
+static void
+_rx_init(struct bna_rx *rx, struct bna *bna)
+{
+ rx->bna = bna;
+ rx->rx_flags = 0;
+
+ INIT_LIST_HEAD(&rx->rxp_q);
+
+ rx->rxq_stop_wc.wc_resume = bna_rx_cb_rxq_stopped_all;
+ rx->rxq_stop_wc.wc_cbarg = rx;
+ rx->rxq_stop_wc.wc_count = 0;
+
+ rx->stop_cbfn = NULL;
+ rx->stop_cbarg = NULL;
+}
+
+static void
+_rxp_add_rxqs(struct bna_rxp *rxp,
+ struct bna_rxq *q0,
+ struct bna_rxq *q1)
+{
+ switch (rxp->type) {
+ case BNA_RXP_SINGLE:
+ rxp->rxq.single.only = q0;
+ rxp->rxq.single.reserved = NULL;
+ break;
+ case BNA_RXP_SLR:
+ rxp->rxq.slr.large = q0;
+ rxp->rxq.slr.small = q1;
+ break;
+ case BNA_RXP_HDS:
+ rxp->rxq.hds.data = q0;
+ rxp->rxq.hds.hdr = q1;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+_rxq_qpt_init(struct bna_rxq *rxq,
+ struct bna_rxp *rxp,
+ u32 page_count,
+ u32 page_size,
+ struct bna_mem_descr *qpt_mem,
+ struct bna_mem_descr *swqpt_mem,
+ struct bna_mem_descr *page_mem)
+{
+ int i;
+
+ rxq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
+ rxq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
+ rxq->qpt.kv_qpt_ptr = qpt_mem->kva;
+ rxq->qpt.page_count = page_count;
+ rxq->qpt.page_size = page_size;
+
+ rxq->rcb->sw_qpt = (void **) swqpt_mem->kva;
+
+ for (i = 0; i < rxq->qpt.page_count; i++) {
+ rxq->rcb->sw_qpt[i] = page_mem[i].kva;
+ ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].lsb =
+ page_mem[i].dma.lsb;
+ ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].msb =
+ page_mem[i].dma.msb;
+
+ }
+}
+
+static void
+_rxp_cqpt_setup(struct bna_rxp *rxp,
+ u32 page_count,
+ u32 page_size,
+ struct bna_mem_descr *qpt_mem,
+ struct bna_mem_descr *swqpt_mem,
+ struct bna_mem_descr *page_mem)
+{
+ int i;
+
+ rxp->cq.qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
+ rxp->cq.qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
+ rxp->cq.qpt.kv_qpt_ptr = qpt_mem->kva;
+ rxp->cq.qpt.page_count = page_count;
+ rxp->cq.qpt.page_size = page_size;
+
+ rxp->cq.ccb->sw_qpt = (void **) swqpt_mem->kva;
+
+ for (i = 0; i < rxp->cq.qpt.page_count; i++) {
+ rxp->cq.ccb->sw_qpt[i] = page_mem[i].kva;
+
+ ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].lsb =
+ page_mem[i].dma.lsb;
+ ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].msb =
+ page_mem[i].dma.msb;
+
+ }
+}
+
+static void
+_rx_add_rxp(struct bna_rx *rx, struct bna_rxp *rxp)
+{
+ list_add_tail(&rxp->qe, &rx->rxp_q);
+}
+
+static void
+_init_rxmod_queues(struct bna_rx_mod *rx_mod)
+{
+ INIT_LIST_HEAD(&rx_mod->rx_free_q);
+ INIT_LIST_HEAD(&rx_mod->rxq_free_q);
+ INIT_LIST_HEAD(&rx_mod->rxp_free_q);
+ INIT_LIST_HEAD(&rx_mod->rx_active_q);
+
+ rx_mod->rx_free_count = 0;
+ rx_mod->rxq_free_count = 0;
+ rx_mod->rxp_free_count = 0;
+}
+
+static void
+_rx_ctor(struct bna_rx *rx, int id)
+{
+ bfa_q_qe_init(&rx->qe);
+ INIT_LIST_HEAD(&rx->rxp_q);
+ rx->bna = NULL;
+
+ rx->rxf.rxf_id = id;
+
+ /* FIXME: mbox_qe ctor()?? */
+ bfa_q_qe_init(&rx->mbox_qe.qe);
+
+ rx->stop_cbfn = NULL;
+ rx->stop_cbarg = NULL;
+}
+
+void
+bna_rx_cb_multi_rxq_stopped(void *arg, int status)
+{
+ struct bna_rxp *rxp = (struct bna_rxp *)arg;
+
+ bfa_wc_down(&rxp->rx->rxq_stop_wc);
+}
+
+void
+bna_rx_cb_rxq_stopped_all(void *arg)
+{
+ struct bna_rx *rx = (struct bna_rx *)arg;
+
+ bfa_fsm_send_event(rx, RX_E_RXQ_STOPPED);
+}
+
+static void
+bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx,
+ enum bna_cb_status status)
+{
+ struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;
+
+ bfa_wc_down(&rx_mod->rx_stop_wc);
+}
+
+static void
+bna_rx_mod_cb_rx_stopped_all(void *arg)
+{
+ struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;
+
+ if (rx_mod->stop_cbfn)
+ rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS);
+ rx_mod->stop_cbfn = NULL;
+}
+
+static void
+bna_rx_start(struct bna_rx *rx)
+{
+ rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
+ if (rx->rx_flags & BNA_RX_F_ENABLE)
+ bfa_fsm_send_event(rx, RX_E_START);
+}
+
+static void
+bna_rx_stop(struct bna_rx *rx)
+{
+ rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED;
+ if (rx->fsm == (bfa_fsm_t) bna_rx_sm_stopped)
+ bna_rx_mod_cb_rx_stopped(&rx->bna->rx_mod, rx, BNA_CB_SUCCESS);
+ else {
+ rx->stop_cbfn = bna_rx_mod_cb_rx_stopped;
+ rx->stop_cbarg = &rx->bna->rx_mod;
+ bfa_fsm_send_event(rx, RX_E_STOP);
+ }
+}
+
+static void
+bna_rx_fail(struct bna_rx *rx)
+{
+ /* Indicate port is not enabled, and failed */
+ rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED;
+ rx->rx_flags |= BNA_RX_F_PORT_FAILED;
+ bfa_fsm_send_event(rx, RX_E_FAIL);
+}
+
+void
+bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
+{
+ struct bna_rx *rx;
+ struct list_head *qe;
+
+ rx_mod->flags |= BNA_RX_MOD_F_PORT_STARTED;
+ if (type == BNA_RX_T_LOOPBACK)
+ rx_mod->flags |= BNA_RX_MOD_F_PORT_LOOPBACK;
+
+ list_for_each(qe, &rx_mod->rx_active_q) {
+ rx = (struct bna_rx *)qe;
+ if (rx->type == type)
+ bna_rx_start(rx);
+ }
+}
+
+void
+bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
+{
+ struct bna_rx *rx;
+ struct list_head *qe;
+
+ rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED;
+ rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK;
+
+ rx_mod->stop_cbfn = bna_port_cb_rx_stopped;
+
+ /**
+ * Before calling bna_rx_stop(), increment rx_stop_wc as many times
+ * as we are going to call bna_rx_stop
+ */
+ list_for_each(qe, &rx_mod->rx_active_q) {
+ rx = (struct bna_rx *)qe;
+ if (rx->type == type)
+ bfa_wc_up(&rx_mod->rx_stop_wc);
+ }
+
+ if (rx_mod->rx_stop_wc.wc_count == 0) {
+ rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS);
+ rx_mod->stop_cbfn = NULL;
+ return;
+ }
+
+ list_for_each(qe, &rx_mod->rx_active_q) {
+ rx = (struct bna_rx *)qe;
+ if (rx->type == type)
+ bna_rx_stop(rx);
+ }
+}
+
+void
+bna_rx_mod_fail(struct bna_rx_mod *rx_mod)
+{
+ struct bna_rx *rx;
+ struct list_head *qe;
+
+ rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED;
+ rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK;
+
+ list_for_each(qe, &rx_mod->rx_active_q) {
+ rx = (struct bna_rx *)qe;
+ bna_rx_fail(rx);
+ }
+}
+
+void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ int index;
+ struct bna_rx *rx_ptr;
+ struct bna_rxp *rxp_ptr;
+ struct bna_rxq *rxq_ptr;
+
+ rx_mod->bna = bna;
+ rx_mod->flags = 0;
+
+ rx_mod->rx = (struct bna_rx *)
+ res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mdl[0].kva;
+ rx_mod->rxp = (struct bna_rxp *)
+ res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mdl[0].kva;
+ rx_mod->rxq = (struct bna_rxq *)
+ res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mdl[0].kva;
+
+ /* Initialize the queues */
+ _init_rxmod_queues(rx_mod);
+
+ /* Build RX queues */
+ for (index = 0; index < BFI_MAX_RXQ; index++) {
+ rx_ptr = &rx_mod->rx[index];
+ _rx_ctor(rx_ptr, index);
+ list_add_tail(&rx_ptr->qe, &rx_mod->rx_free_q);
+ rx_mod->rx_free_count++;
+ }
+
+ /* build RX-path queue */
+ for (index = 0; index < BFI_MAX_RXQ; index++) {
+ rxp_ptr = &rx_mod->rxp[index];
+ rxp_ptr->cq.cq_id = index;
+ bfa_q_qe_init(&rxp_ptr->qe);
+ list_add_tail(&rxp_ptr->qe, &rx_mod->rxp_free_q);
+ rx_mod->rxp_free_count++;
+ }
+
+ /* build RXQ queue */
+ for (index = 0; index < BFI_MAX_RXQ; index++) {
+ rxq_ptr = &rx_mod->rxq[index];
+ rxq_ptr->rxq_id = index;
+
+ bfa_q_qe_init(&rxq_ptr->qe);
+ list_add_tail(&rxq_ptr->qe, &rx_mod->rxq_free_q);
+ rx_mod->rxq_free_count++;
+ }
+
+ rx_mod->rx_stop_wc.wc_resume = bna_rx_mod_cb_rx_stopped_all;
+ rx_mod->rx_stop_wc.wc_cbarg = rx_mod;
+ rx_mod->rx_stop_wc.wc_count = 0;
+}
+
+void
+bna_rx_mod_uninit(struct bna_rx_mod *rx_mod)
+{
+ struct list_head *qe;
+ int i;
+
+ i = 0;
+ list_for_each(qe, &rx_mod->rx_free_q)
+ i++;
+
+ i = 0;
+ list_for_each(qe, &rx_mod->rxp_free_q)
+ i++;
+
+ i = 0;
+ list_for_each(qe, &rx_mod->rxq_free_q)
+ i++;
+
+ rx_mod->bna = NULL;
+}
+
+int
+bna_rx_state_get(struct bna_rx *rx)
+{
+ return bfa_sm_to_state(rx_sm_table, rx->fsm);
+}
+
+void
+bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info)
+{
+ u32 cq_size, hq_size, dq_size;
+ u32 cpage_count, hpage_count, dpage_count;
+ struct bna_mem_info *mem_info;
+ u32 cq_depth;
+ u32 hq_depth;
+ u32 dq_depth;
+
+ dq_depth = q_cfg->q_depth;
+ hq_depth = ((q_cfg->rxp_type == BNA_RXP_SINGLE) ? 0 : q_cfg->q_depth);
+ cq_depth = dq_depth + hq_depth;
+
+ BNA_TO_POWER_OF_2_HIGH(cq_depth);
+ cq_size = cq_depth * BFI_CQ_WI_SIZE;
+ cq_size = ALIGN(cq_size, PAGE_SIZE);
+ cpage_count = SIZE_TO_PAGES(cq_size);
+
+ BNA_TO_POWER_OF_2_HIGH(dq_depth);
+ dq_size = dq_depth * BFI_RXQ_WI_SIZE;
+ dq_size = ALIGN(dq_size, PAGE_SIZE);
+ dpage_count = SIZE_TO_PAGES(dq_size);
+
+ if (BNA_RXP_SINGLE != q_cfg->rxp_type) {
+ BNA_TO_POWER_OF_2_HIGH(hq_depth);
+ hq_size = hq_depth * BFI_RXQ_WI_SIZE;
+ hq_size = ALIGN(hq_size, PAGE_SIZE);
+ hpage_count = SIZE_TO_PAGES(hq_size);
+ } else {
+ hpage_count = 0;
+ }
+
+ /* CCB structures */
+ res_info[BNA_RX_RES_MEM_T_CCB].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = sizeof(struct bna_ccb);
+ mem_info->num = q_cfg->num_paths;
+
+ /* RCB structures */
+ res_info[BNA_RX_RES_MEM_T_RCB].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = sizeof(struct bna_rcb);
+ mem_info->num = BNA_GET_RXQS(q_cfg);
+
+ /* Completion QPT */
+ res_info[BNA_RX_RES_MEM_T_CQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = cpage_count * sizeof(struct bna_dma_addr);
+ mem_info->num = q_cfg->num_paths;
+
+ /* Completion s/w QPT */
+ res_info[BNA_RX_RES_MEM_T_CSWQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = cpage_count * sizeof(void *);
+ mem_info->num = q_cfg->num_paths;
+
+ /* Completion QPT pages */
+ res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = PAGE_SIZE;
+ mem_info->num = cpage_count * q_cfg->num_paths;
+
+ /* Data QPTs */
+ res_info[BNA_RX_RES_MEM_T_DQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = dpage_count * sizeof(struct bna_dma_addr);
+ mem_info->num = q_cfg->num_paths;
+
+ /* Data s/w QPTs */
+ res_info[BNA_RX_RES_MEM_T_DSWQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = dpage_count * sizeof(void *);
+ mem_info->num = q_cfg->num_paths;
+
+ /* Data QPT pages */
+ res_info[BNA_RX_RES_MEM_T_DPAGE].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = PAGE_SIZE;
+ mem_info->num = dpage_count * q_cfg->num_paths;
+
+ /* Hdr QPTs */
+ res_info[BNA_RX_RES_MEM_T_HQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = hpage_count * sizeof(struct bna_dma_addr);
+ mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
+
+ /* Hdr s/w QPTs */
+ res_info[BNA_RX_RES_MEM_T_HSWQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = hpage_count * sizeof(void *);
+ mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
+
+ /* Hdr QPT pages */
+ res_info[BNA_RX_RES_MEM_T_HPAGE].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = (hpage_count ? PAGE_SIZE : 0);
+ mem_info->num = (hpage_count ? (hpage_count * q_cfg->num_paths) : 0);
+
+ /* RX Interrupts */
+ res_info[BNA_RX_RES_T_INTR].res_type = BNA_RES_T_INTR;
+ res_info[BNA_RX_RES_T_INTR].res_u.intr_info.intr_type = BNA_INTR_T_MSIX;
+ res_info[BNA_RX_RES_T_INTR].res_u.intr_info.num = q_cfg->num_paths;
+}
+
+struct bna_rx *
+bna_rx_create(struct bna *bna, struct bnad *bnad,
+ struct bna_rx_config *rx_cfg,
+ struct bna_rx_event_cbfn *rx_cbfn,
+ struct bna_res_info *res_info,
+ void *priv)
+{
+ struct bna_rx_mod *rx_mod = &bna->rx_mod;
+ struct bna_rx *rx;
+ struct bna_rxp *rxp;
+ struct bna_rxq *q0;
+ struct bna_rxq *q1;
+ struct bna_intr_info *intr_info;
+ u32 page_count;
+ struct bna_mem_descr *ccb_mem;
+ struct bna_mem_descr *rcb_mem;
+ struct bna_mem_descr *unmapq_mem;
+ struct bna_mem_descr *cqpt_mem;
+ struct bna_mem_descr *cswqpt_mem;
+ struct bna_mem_descr *cpage_mem;
+ struct bna_mem_descr *hqpt_mem; /* Header/Small Q qpt */
+ struct bna_mem_descr *dqpt_mem; /* Data/Large Q qpt */
+ struct bna_mem_descr *hsqpt_mem; /* s/w qpt for hdr */
+ struct bna_mem_descr *dsqpt_mem; /* s/w qpt for data */
+ struct bna_mem_descr *hpage_mem; /* hdr page mem */
+ struct bna_mem_descr *dpage_mem; /* data page mem */
+ int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0, ret;
+ int dpage_count, hpage_count, rcb_idx;
+ struct bna_ib_config ibcfg;
+ /* Fail if we don't have enough RXPs, RXQs */
+ if (!_rx_can_satisfy(rx_mod, rx_cfg))
+ return NULL;
+
+ /* Initialize resource pointers */
+ intr_info = &res_info[BNA_RX_RES_T_INTR].res_u.intr_info;
+ ccb_mem = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info.mdl[0];
+ rcb_mem = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info.mdl[0];
+ unmapq_mem = &res_info[BNA_RX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[0];
+ cqpt_mem = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info.mdl[0];
+ cswqpt_mem = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info.mdl[0];
+ cpage_mem = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.mdl[0];
+ hqpt_mem = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info.mdl[0];
+ dqpt_mem = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info.mdl[0];
+ hsqpt_mem = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info.mdl[0];
+ dsqpt_mem = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info.mdl[0];
+ hpage_mem = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.mdl[0];
+ dpage_mem = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.mdl[0];
+
+ /* Compute q depth & page count */
+ page_count = res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.num /
+ rx_cfg->num_paths;
+
+ dpage_count = res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.num /
+ rx_cfg->num_paths;
+
+ hpage_count = res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.num /
+ rx_cfg->num_paths;
+ /* Get RX pointer */
+ rx = _get_free_rx(rx_mod);
+ _rx_init(rx, bna);
+ rx->priv = priv;
+ rx->type = rx_cfg->rx_type;
+
+ rx->rcb_setup_cbfn = rx_cbfn->rcb_setup_cbfn;
+ rx->rcb_destroy_cbfn = rx_cbfn->rcb_destroy_cbfn;
+ rx->ccb_setup_cbfn = rx_cbfn->ccb_setup_cbfn;
+ rx->ccb_destroy_cbfn = rx_cbfn->ccb_destroy_cbfn;
+ /* Following callbacks are mandatory */
+ rx->rx_cleanup_cbfn = rx_cbfn->rx_cleanup_cbfn;
+ rx->rx_post_cbfn = rx_cbfn->rx_post_cbfn;
+
+ if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_STARTED) {
+ switch (rx->type) {
+ case BNA_RX_T_REGULAR:
+ if (!(rx->bna->rx_mod.flags &
+ BNA_RX_MOD_F_PORT_LOOPBACK))
+ rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
+ break;
+ case BNA_RX_T_LOOPBACK:
+ if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_LOOPBACK)
+ rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
+ break;
+ }
+ }
+
+ for (i = 0, rcb_idx = 0; i < rx_cfg->num_paths; i++) {
+ rxp = _get_free_rxp(rx_mod);
+ rxp->type = rx_cfg->rxp_type;
+ rxp->rx = rx;
+ rxp->cq.rx = rx;
+
+ /* Get required RXQs, and queue them to rx-path */
+ q0 = _get_free_rxq(rx_mod);
+ if (BNA_RXP_SINGLE == rx_cfg->rxp_type)
+ q1 = NULL;
+ else
+ q1 = _get_free_rxq(rx_mod);
+
+ /* Initialize IB */
+ if (1 == intr_info->num) {
+ rxp->cq.ib = bna_ib_get(&bna->ib_mod,
+ intr_info->intr_type,
+ intr_info->idl[0].vector);
+ rxp->vector = intr_info->idl[0].vector;
+ } else {
+ rxp->cq.ib = bna_ib_get(&bna->ib_mod,
+ intr_info->intr_type,
+ intr_info->idl[i].vector);
+
+ /* Map the MSI-x vector used for this RXP */
+ rxp->vector = intr_info->idl[i].vector;
+ }
+
+ rxp->cq.ib_seg_offset = bna_ib_reserve_idx(rxp->cq.ib);
+
+ ibcfg.coalescing_timeo = BFI_RX_COALESCING_TIMEO;
+ ibcfg.interpkt_count = BFI_RX_INTERPKT_COUNT;
+ ibcfg.interpkt_timeo = BFI_RX_INTERPKT_TIMEO;
+ ibcfg.ctrl_flags = BFI_IB_CF_INT_ENABLE;
+
+ ret = bna_ib_config(rxp->cq.ib, &ibcfg);
+
+ /* Link rxqs to rxp */
+ _rxp_add_rxqs(rxp, q0, q1);
+
+ /* Link rxp to rx */
+ _rx_add_rxp(rx, rxp);
+
+ q0->rx = rx;
+ q0->rxp = rxp;
+
+ /* Initialize RCB for the large / data q */
+ q0->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
+ RXQ_RCB_INIT(q0, rxp, rx_cfg->q_depth, bna, 0,
+ (void *)unmapq_mem[rcb_idx].kva);
+ rcb_idx++;
+ (q0)->rx_packets = (q0)->rx_bytes = 0;
+ (q0)->rx_packets_with_error = (q0)->rxbuf_alloc_failed = 0;
+
+ /* Initialize RXQs */
+ _rxq_qpt_init(q0, rxp, dpage_count, PAGE_SIZE,
+ &dqpt_mem[i], &dsqpt_mem[i], &dpage_mem[dpage_idx]);
+ q0->rcb->page_idx = dpage_idx;
+ q0->rcb->page_count = dpage_count;
+ dpage_idx += dpage_count;
+
+ /* Call bnad to complete rcb setup */
+ if (rx->rcb_setup_cbfn)
+ rx->rcb_setup_cbfn(bnad, q0->rcb);
+
+ if (q1) {
+ q1->rx = rx;
+ q1->rxp = rxp;
+
+ q1->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
+ RXQ_RCB_INIT(q1, rxp, rx_cfg->q_depth, bna, 1,
+ (void *)unmapq_mem[rcb_idx].kva);
+ rcb_idx++;
+ (q1)->buffer_size = (rx_cfg)->small_buff_size;
+ (q1)->rx_packets = (q1)->rx_bytes = 0;
+ (q1)->rx_packets_with_error =
+ (q1)->rxbuf_alloc_failed = 0;
+
+ _rxq_qpt_init(q1, rxp, hpage_count, PAGE_SIZE,
+ &hqpt_mem[i], &hsqpt_mem[i],
+ &hpage_mem[hpage_idx]);
+ q1->rcb->page_idx = hpage_idx;
+ q1->rcb->page_count = hpage_count;
+ hpage_idx += hpage_count;
+
+ /* Call bnad to complete rcb setup */
+ if (rx->rcb_setup_cbfn)
+ rx->rcb_setup_cbfn(bnad, q1->rcb);
+ }
+ /* Setup RXP::CQ */
+ rxp->cq.ccb = (struct bna_ccb *) ccb_mem[i].kva;
+ _rxp_cqpt_setup(rxp, page_count, PAGE_SIZE,
+ &cqpt_mem[i], &cswqpt_mem[i], &cpage_mem[cpage_idx]);
+ rxp->cq.ccb->page_idx = cpage_idx;
+ rxp->cq.ccb->page_count = page_count;
+ cpage_idx += page_count;
+
+ rxp->cq.ccb->pkt_rate.small_pkt_cnt = 0;
+ rxp->cq.ccb->pkt_rate.large_pkt_cnt = 0;
+
+ rxp->cq.ccb->producer_index = 0;
+ rxp->cq.ccb->q_depth = rx_cfg->q_depth +
+ ((rx_cfg->rxp_type == BNA_RXP_SINGLE) ?
+ 0 : rx_cfg->q_depth);
+ rxp->cq.ccb->i_dbell = &rxp->cq.ib->door_bell;
+ rxp->cq.ccb->rcb[0] = q0->rcb;
+ if (q1)
+ rxp->cq.ccb->rcb[1] = q1->rcb;
+ rxp->cq.ccb->cq = &rxp->cq;
+ rxp->cq.ccb->bnad = bna->bnad;
+ rxp->cq.ccb->hw_producer_index =
+ ((volatile u32 *)rxp->cq.ib->ib_seg_host_addr_kva +
+ (rxp->cq.ib_seg_offset * BFI_IBIDX_SIZE));
+ *(rxp->cq.ccb->hw_producer_index) = 0;
+ rxp->cq.ccb->intr_type = intr_info->intr_type;
+ rxp->cq.ccb->intr_vector = (intr_info->num == 1) ?
+ intr_info->idl[0].vector :
+ intr_info->idl[i].vector;
+ rxp->cq.ccb->rx_coalescing_timeo =
+ rxp->cq.ib->ib_config.coalescing_timeo;
+ rxp->cq.ccb->id = i;
+
+ /* Call bnad to complete CCB setup */
+ if (rx->ccb_setup_cbfn)
+ rx->ccb_setup_cbfn(bnad, rxp->cq.ccb);
+
+ } /* for each rx-path */
+
+ bna_rxf_init(&rx->rxf, rx, rx_cfg);
+
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+
+ return rx;
+}
+
+void
+bna_rx_destroy(struct bna_rx *rx)
+{
+ struct bna_rx_mod *rx_mod = &rx->bna->rx_mod;
+ struct bna_ib_mod *ib_mod = &rx->bna->ib_mod;
+ struct bna_rxq *q0 = NULL;
+ struct bna_rxq *q1 = NULL;
+ struct bna_rxp *rxp;
+ struct list_head *qe;
+
+ bna_rxf_uninit(&rx->rxf);
+
+ while (!list_empty(&rx->rxp_q)) {
+ bfa_q_deq(&rx->rxp_q, &rxp);
+ GET_RXQS(rxp, q0, q1);
+ /* Callback to bnad for destroying RCB */
+ if (rx->rcb_destroy_cbfn)
+ rx->rcb_destroy_cbfn(rx->bna->bnad, q0->rcb);
+ q0->rcb = NULL;
+ q0->rxp = NULL;
+ q0->rx = NULL;
+ _put_free_rxq(rx_mod, q0);
+ if (q1) {
+ /* Callback to bnad for destroying RCB */
+ if (rx->rcb_destroy_cbfn)
+ rx->rcb_destroy_cbfn(rx->bna->bnad, q1->rcb);
+ q1->rcb = NULL;
+ q1->rxp = NULL;
+ q1->rx = NULL;
+ _put_free_rxq(rx_mod, q1);
+ }
+ rxp->rxq.slr.large = NULL;
+ rxp->rxq.slr.small = NULL;
+ if (rxp->cq.ib) {
+ if (rxp->cq.ib_seg_offset != 0xff)
+ bna_ib_release_idx(rxp->cq.ib,
+ rxp->cq.ib_seg_offset);
+ bna_ib_put(ib_mod, rxp->cq.ib);
+ rxp->cq.ib = NULL;
+ }
+ /* Callback to bnad for destroying CCB */
+ if (rx->ccb_destroy_cbfn)
+ rx->ccb_destroy_cbfn(rx->bna->bnad, rxp->cq.ccb);
+ rxp->cq.ccb = NULL;
+ rxp->rx = NULL;
+ _put_free_rxp(rx_mod, rxp);
+ }
+
+ list_for_each(qe, &rx_mod->rx_active_q) {
+ if (qe == &rx->qe) {
+ list_del(&rx->qe);
+ bfa_q_qe_init(&rx->qe);
+ break;
+ }
+ }
+
+ rx->bna = NULL;
+ rx->priv = NULL;
+ _put_free_rx(rx_mod, rx);
+}
+
+void
+bna_rx_enable(struct bna_rx *rx)
+{
+ if (rx->fsm != (bfa_sm_t)bna_rx_sm_stopped)
+ return;
+
+ rx->rx_flags |= BNA_RX_F_ENABLE;
+ if (rx->rx_flags & BNA_RX_F_PORT_ENABLED)
+ bfa_fsm_send_event(rx, RX_E_START);
+}
+
+void
+bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type,
+ void (*cbfn)(void *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ if (type == BNA_SOFT_CLEANUP) {
+ /* h/w should not be accessed. Treat we're stopped */
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+ } else {
+ rx->stop_cbfn = cbfn;
+ rx->stop_cbarg = rx->bna->bnad;
+
+ rx->rx_flags &= ~BNA_RX_F_ENABLE;
+
+ bfa_fsm_send_event(rx, RX_E_STOP);
+ }
+}
+
+/**
+ * TX
+ */
+#define call_tx_stop_cbfn(tx, status)\
+do {\
+ if ((tx)->stop_cbfn)\
+ (tx)->stop_cbfn((tx)->stop_cbarg, (tx), status);\
+ (tx)->stop_cbfn = NULL;\
+ (tx)->stop_cbarg = NULL;\
+} while (0)
+
+#define call_tx_prio_change_cbfn(tx, status)\
+do {\
+ if ((tx)->prio_change_cbfn)\
+ (tx)->prio_change_cbfn((tx)->bna->bnad, (tx), status);\
+ (tx)->prio_change_cbfn = NULL;\
+} while (0)
+
+static void bna_tx_mod_cb_tx_stopped(void *tx_mod, struct bna_tx *tx,
+ enum bna_cb_status status);
+static void bna_tx_cb_txq_stopped(void *arg, int status);
+static void bna_tx_cb_stats_cleared(void *arg, int status);
+static void __bna_tx_stop(struct bna_tx *tx);
+static void __bna_tx_start(struct bna_tx *tx);
+static void __bna_txf_stat_clr(struct bna_tx *tx);
+
+enum bna_tx_event {
+ TX_E_START = 1,
+ TX_E_STOP = 2,
+ TX_E_FAIL = 3,
+ TX_E_TXQ_STOPPED = 4,
+ TX_E_PRIO_CHANGE = 5,
+ TX_E_STAT_CLEARED = 6,
+};
+
+enum bna_tx_state {
+ BNA_TX_STOPPED = 1,
+ BNA_TX_STARTED = 2,
+ BNA_TX_TXQ_STOP_WAIT = 3,
+ BNA_TX_PRIO_STOP_WAIT = 4,
+ BNA_TX_STAT_CLR_WAIT = 5,
+};
+
+bfa_fsm_state_decl(bna_tx, stopped, struct bna_tx,
+ enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, started, struct bna_tx,
+ enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, txq_stop_wait, struct bna_tx,
+ enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, prio_stop_wait, struct bna_tx,
+ enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, stat_clr_wait, struct bna_tx,
+ enum bna_tx_event);
+
+static struct bfa_sm_table tx_sm_table[] = {
+ {BFA_SM(bna_tx_sm_stopped), BNA_TX_STOPPED},
+ {BFA_SM(bna_tx_sm_started), BNA_TX_STARTED},
+ {BFA_SM(bna_tx_sm_txq_stop_wait), BNA_TX_TXQ_STOP_WAIT},
+ {BFA_SM(bna_tx_sm_prio_stop_wait), BNA_TX_PRIO_STOP_WAIT},
+ {BFA_SM(bna_tx_sm_stat_clr_wait), BNA_TX_STAT_CLR_WAIT},
+};
+
+static void
+bna_tx_sm_stopped_entry(struct bna_tx *tx)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ (tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+
+ call_tx_stop_cbfn(tx, BNA_CB_SUCCESS);
+}
+
+static void
+bna_tx_sm_stopped(struct bna_tx *tx, enum bna_tx_event event)
+{
+ switch (event) {
+ case TX_E_START:
+ bfa_fsm_set_state(tx, bna_tx_sm_started);
+ break;
+
+ case TX_E_STOP:
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+ break;
+
+ case TX_E_FAIL:
+ /* No-op */
+ break;
+
+ case TX_E_PRIO_CHANGE:
+ call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS);
+ break;
+
+ case TX_E_TXQ_STOPPED:
+ /**
+ * This event is received due to flushing of mbox when
+ * device fails
+ */
+ /* No-op */
+ break;
+
+ default:
+ bfa_sm_fault(tx->bna, event);
+ }
+}
+
+static void
+bna_tx_sm_started_entry(struct bna_tx *tx)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ __bna_tx_start(tx);
+
+ /* Start IB */
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_ack(&txq->ib->door_bell, 0);
+ }
+}
+
+static void
+bna_tx_sm_started(struct bna_tx *tx, enum bna_tx_event event)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ switch (event) {
+ case TX_E_STOP:
+ bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait);
+ __bna_tx_stop(tx);
+ break;
+
+ case TX_E_FAIL:
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_fail(txq->ib);
+ (tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+ break;
+
+ case TX_E_PRIO_CHANGE:
+ bfa_fsm_set_state(tx, bna_tx_sm_prio_stop_wait);
+ break;
+
+ default:
+ bfa_sm_fault(tx->bna, event);
+ }
+}
+
+static void
+bna_tx_sm_txq_stop_wait_entry(struct bna_tx *tx)
+{
+}
+
+static void
+bna_tx_sm_txq_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ switch (event) {
+ case TX_E_FAIL:
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+ break;
+
+ case TX_E_TXQ_STOPPED:
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_stop(txq->ib);
+ }
+ bfa_fsm_set_state(tx, bna_tx_sm_stat_clr_wait);
+ break;
+
+ case TX_E_PRIO_CHANGE:
+ /* No-op */
+ break;
+
+ default:
+ bfa_sm_fault(tx->bna, event);
+ }
+}
+
+static void
+bna_tx_sm_prio_stop_wait_entry(struct bna_tx *tx)
+{
+ __bna_tx_stop(tx);
+}
+
+static void
+bna_tx_sm_prio_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ switch (event) {
+ case TX_E_STOP:
+ bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait);
+ break;
+
+ case TX_E_FAIL:
+ call_tx_prio_change_cbfn(tx, BNA_CB_FAIL);
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+ break;
+
+ case TX_E_TXQ_STOPPED:
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_stop(txq->ib);
+ (tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+ call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS);
+ bfa_fsm_set_state(tx, bna_tx_sm_started);
+ break;
+
+ case TX_E_PRIO_CHANGE:
+ /* No-op */
+ break;
+
+ default:
+ bfa_sm_fault(tx->bna, event);
+ }
+}
+
+static void
+bna_tx_sm_stat_clr_wait_entry(struct bna_tx *tx)
+{
+ __bna_txf_stat_clr(tx);
+}
+
+static void
+bna_tx_sm_stat_clr_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+ switch (event) {
+ case TX_E_FAIL:
+ case TX_E_STAT_CLEARED:
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(tx->bna, event);
+ }
+}
+
+static void
+__bna_txq_start(struct bna_tx *tx, struct bna_txq *txq)
+{
+ struct bna_rxtx_q_mem *q_mem;
+ struct bna_txq_mem txq_cfg;
+ struct bna_txq_mem *txq_mem;
+ struct bna_dma_addr cur_q_addr;
+ u32 pg_num;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ /* Fill out structure, to be subsequently written to hardware */
+ txq_cfg.pg_tbl_addr_lo = txq->qpt.hw_qpt_ptr.lsb;
+ txq_cfg.pg_tbl_addr_hi = txq->qpt.hw_qpt_ptr.msb;
+ cur_q_addr = *((struct bna_dma_addr *)(txq->qpt.kv_qpt_ptr));
+ txq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
+ txq_cfg.cur_q_entry_hi = cur_q_addr.msb;
+
+ txq_cfg.pg_cnt_n_prd_ptr = (txq->qpt.page_count << 16) | 0x0;
+
+ txq_cfg.entry_n_pg_size = ((u32)(BFI_TXQ_WI_SIZE >> 2) << 16) |
+ (txq->qpt.page_size >> 2);
+ txq_cfg.int_blk_n_cns_ptr = ((((u32)txq->ib_seg_offset) << 24) |
+ ((u32)(txq->ib->ib_id & 0xff) << 16) | 0x0);
+
+ txq_cfg.cns_ptr2_n_q_state = BNA_Q_IDLE_STATE;
+ txq_cfg.nxt_qid_n_fid_n_pri = (((tx->txf.txf_id & 0x3f) << 3) |
+ (txq->priority & 0x3));
+ txq_cfg.wvc_n_cquota_n_rquota =
+ ((((u32)BFI_TX_MAX_WRR_QUOTA & 0xfff) << 12) |
+ (BFI_TX_MAX_WRR_QUOTA & 0xfff));
+
+ /* Setup the page and write to H/W */
+
+ pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + tx->bna->port_num,
+ HQM_RXTX_Q_RAM_BASE_OFFSET);
+ writel(pg_num, tx->bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
+ HQM_RXTX_Q_RAM_BASE_OFFSET);
+ q_mem = (struct bna_rxtx_q_mem *)0;
+ txq_mem = &q_mem[txq->txq_id].txq;
+
+ /*
+ * The following 4 lines, is a hack b'cos the H/W needs to read
+ * these DMA addresses as little endian
+ */
+
+ off = (unsigned long)&txq_mem->pg_tbl_addr_lo;
+ writel(htonl(txq_cfg.pg_tbl_addr_lo), base_addr + off);
+
+ off = (unsigned long)&txq_mem->pg_tbl_addr_hi;
+ writel(htonl(txq_cfg.pg_tbl_addr_hi), base_addr + off);
+
+ off = (unsigned long)&txq_mem->cur_q_entry_lo;
+ writel(htonl(txq_cfg.cur_q_entry_lo), base_addr + off);
+
+ off = (unsigned long)&txq_mem->cur_q_entry_hi;
+ writel(htonl(txq_cfg.cur_q_entry_hi), base_addr + off);
+
+ off = (unsigned long)&txq_mem->pg_cnt_n_prd_ptr;
+ writel(txq_cfg.pg_cnt_n_prd_ptr, base_addr + off);
+
+ off = (unsigned long)&txq_mem->entry_n_pg_size;
+ writel(txq_cfg.entry_n_pg_size, base_addr + off);
+
+ off = (unsigned long)&txq_mem->int_blk_n_cns_ptr;
+ writel(txq_cfg.int_blk_n_cns_ptr, base_addr + off);
+
+ off = (unsigned long)&txq_mem->cns_ptr2_n_q_state;
+ writel(txq_cfg.cns_ptr2_n_q_state, base_addr + off);
+
+ off = (unsigned long)&txq_mem->nxt_qid_n_fid_n_pri;
+ writel(txq_cfg.nxt_qid_n_fid_n_pri, base_addr + off);
+
+ off = (unsigned long)&txq_mem->wvc_n_cquota_n_rquota;
+ writel(txq_cfg.wvc_n_cquota_n_rquota, base_addr + off);
+
+ txq->tcb->producer_index = 0;
+ txq->tcb->consumer_index = 0;
+ *(txq->tcb->hw_consumer_index) = 0;
+
+}
+
+static void
+__bna_txq_stop(struct bna_tx *tx, struct bna_txq *txq)
+{
+ struct bfi_ll_q_stop_req ll_req;
+ u32 bit_mask[2] = {0, 0};
+ if (txq->txq_id < 32)
+ bit_mask[0] = (u32)1 << txq->txq_id;
+ else
+ bit_mask[1] = (u32)1 << (txq->txq_id - 32);
+
+ memset(&ll_req, 0, sizeof(ll_req));
+ ll_req.mh.msg_class = BFI_MC_LL;
+ ll_req.mh.msg_id = BFI_LL_H2I_TXQ_STOP_REQ;
+ ll_req.mh.mtag.h2i.lpu_id = 0;
+ ll_req.q_id_mask[0] = htonl(bit_mask[0]);
+ ll_req.q_id_mask[1] = htonl(bit_mask[1]);
+
+ bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_tx_cb_txq_stopped, tx);
+
+ bna_mbox_send(tx->bna, &tx->mbox_qe);
+}
+
+static void
+__bna_txf_start(struct bna_tx *tx)
+{
+ struct bna_tx_fndb_ram *tx_fndb;
+ struct bna_txf *txf = &tx->txf;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
+ (tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET),
+ tx->bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
+ TX_FNDB_RAM_BASE_OFFSET);
+
+ tx_fndb = (struct bna_tx_fndb_ram *)0;
+ off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags;
+
+ writel(((u32)txf->vlan << 16) | txf->ctrl_flags,
+ base_addr + off);
+
+ if (tx->txf.txf_id < 32)
+ tx->bna->tx_mod.txf_bmap[0] |= ((u32)1 << tx->txf.txf_id);
+ else
+ tx->bna->tx_mod.txf_bmap[1] |= ((u32)
+ 1 << (tx->txf.txf_id - 32));
+}
+
+static void
+__bna_txf_stop(struct bna_tx *tx)
+{
+ struct bna_tx_fndb_ram *tx_fndb;
+ u32 page_num;
+ u32 ctl_flags;
+ struct bna_txf *txf = &tx->txf;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ /* retrieve the running txf_flags & turn off enable bit */
+ page_num = BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
+ (tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET);
+ writel(page_num, tx->bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
+ TX_FNDB_RAM_BASE_OFFSET);
+ tx_fndb = (struct bna_tx_fndb_ram *)0;
+ off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags;
+
+ ctl_flags = readl(base_addr + off);
+ ctl_flags &= ~BFI_TXF_CF_ENABLE;
+
+ writel(ctl_flags, base_addr + off);
+
+ if (tx->txf.txf_id < 32)
+ tx->bna->tx_mod.txf_bmap[0] &= ~((u32)1 << tx->txf.txf_id);
+ else
+ tx->bna->tx_mod.txf_bmap[0] &= ~((u32)
+ 1 << (tx->txf.txf_id - 32));
+}
+
+static void
+__bna_txf_stat_clr(struct bna_tx *tx)
+{
+ struct bfi_ll_stats_req ll_req;
+ u32 txf_bmap[2] = {0, 0};
+ if (tx->txf.txf_id < 32)
+ txf_bmap[0] = ((u32)1 << tx->txf.txf_id);
+ else
+ txf_bmap[1] = ((u32)1 << (tx->txf.txf_id - 32));
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0);
+ ll_req.stats_mask = 0;
+ ll_req.rxf_id_mask[0] = 0;
+ ll_req.rxf_id_mask[1] = 0;
+ ll_req.txf_id_mask[0] = htonl(txf_bmap[0]);
+ ll_req.txf_id_mask[1] = htonl(txf_bmap[1]);
+
+ bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_tx_cb_stats_cleared, tx);
+ bna_mbox_send(tx->bna, &tx->mbox_qe);
+}
+
+static void
+__bna_tx_start(struct bna_tx *tx)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_start(txq->ib);
+ __bna_txq_start(tx, txq);
+ }
+
+ __bna_txf_start(tx);
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ txq->tcb->priority = txq->priority;
+ (tx->tx_resume_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+}
+
+static void
+__bna_tx_stop(struct bna_tx *tx)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ (tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+
+ __bna_txf_stop(tx);
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bfa_wc_up(&tx->txq_stop_wc);
+ }
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ __bna_txq_stop(tx, txq);
+ }
+}
+
+static void
+bna_txq_qpt_setup(struct bna_txq *txq, int page_count, int page_size,
+ struct bna_mem_descr *qpt_mem,
+ struct bna_mem_descr *swqpt_mem,
+ struct bna_mem_descr *page_mem)
+{
+ int i;
+
+ txq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
+ txq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
+ txq->qpt.kv_qpt_ptr = qpt_mem->kva;
+ txq->qpt.page_count = page_count;
+ txq->qpt.page_size = page_size;
+
+ txq->tcb->sw_qpt = (void **) swqpt_mem->kva;
+
+ for (i = 0; i < page_count; i++) {
+ txq->tcb->sw_qpt[i] = page_mem[i].kva;
+
+ ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].lsb =
+ page_mem[i].dma.lsb;
+ ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].msb =
+ page_mem[i].dma.msb;
+
+ }
+}
+
+static void
+bna_tx_free(struct bna_tx *tx)
+{
+ struct bna_tx_mod *tx_mod = &tx->bna->tx_mod;
+ struct bna_txq *txq;
+ struct bna_ib_mod *ib_mod = &tx->bna->ib_mod;
+ struct list_head *qe;
+
+ while (!list_empty(&tx->txq_q)) {
+ bfa_q_deq(&tx->txq_q, &txq);
+ bfa_q_qe_init(&txq->qe);
+ if (txq->ib) {
+ if (txq->ib_seg_offset != -1)
+ bna_ib_release_idx(txq->ib,
+ txq->ib_seg_offset);
+ bna_ib_put(ib_mod, txq->ib);
+ txq->ib = NULL;
+ }
+ txq->tcb = NULL;
+ txq->tx = NULL;
+ list_add_tail(&txq->qe, &tx_mod->txq_free_q);
+ }
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ if (qe == &tx->qe) {
+ list_del(&tx->qe);
+ bfa_q_qe_init(&tx->qe);
+ break;
+ }
+ }
+
+ tx->bna = NULL;
+ tx->priv = NULL;
+ list_add_tail(&tx->qe, &tx_mod->tx_free_q);
+}
+
+static void
+bna_tx_cb_txq_stopped(void *arg, int status)
+{
+ struct bna_tx *tx = (struct bna_tx *)arg;
+
+ bfa_q_qe_init(&tx->mbox_qe.qe);
+ bfa_wc_down(&tx->txq_stop_wc);
+}
+
+static void
+bna_tx_cb_txq_stopped_all(void *arg)
+{
+ struct bna_tx *tx = (struct bna_tx *)arg;
+
+ bfa_fsm_send_event(tx, TX_E_TXQ_STOPPED);
+}
+
+static void
+bna_tx_cb_stats_cleared(void *arg, int status)
+{
+ struct bna_tx *tx = (struct bna_tx *)arg;
+
+ bfa_q_qe_init(&tx->mbox_qe.qe);
+
+ bfa_fsm_send_event(tx, TX_E_STAT_CLEARED);
+}
+
+static void
+bna_tx_start(struct bna_tx *tx)
+{
+ tx->flags |= BNA_TX_F_PORT_STARTED;
+ if (tx->flags & BNA_TX_F_ENABLED)
+ bfa_fsm_send_event(tx, TX_E_START);
+}
+
+static void
+bna_tx_stop(struct bna_tx *tx)
+{
+ tx->stop_cbfn = bna_tx_mod_cb_tx_stopped;
+ tx->stop_cbarg = &tx->bna->tx_mod;
+
+ tx->flags &= ~BNA_TX_F_PORT_STARTED;
+ bfa_fsm_send_event(tx, TX_E_STOP);
+}
+
+static void
+bna_tx_fail(struct bna_tx *tx)
+{
+ tx->flags &= ~BNA_TX_F_PORT_STARTED;
+ bfa_fsm_send_event(tx, TX_E_FAIL);
+}
+
+static void
+bna_tx_prio_changed(struct bna_tx *tx, int prio)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ txq->priority = prio;
+ }
+
+ bfa_fsm_send_event(tx, TX_E_PRIO_CHANGE);
+}
+
+static void
+bna_tx_cee_link_status(struct bna_tx *tx, int cee_link)
+{
+ if (cee_link)
+ tx->flags |= BNA_TX_F_PRIO_LOCK;
+ else
+ tx->flags &= ~BNA_TX_F_PRIO_LOCK;
+}
+
+static void
+bna_tx_mod_cb_tx_stopped(void *arg, struct bna_tx *tx,
+ enum bna_cb_status status)
+{
+ struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;
+
+ bfa_wc_down(&tx_mod->tx_stop_wc);
+}
+
+static void
+bna_tx_mod_cb_tx_stopped_all(void *arg)
+{
+ struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;
+
+ if (tx_mod->stop_cbfn)
+ tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS);
+ tx_mod->stop_cbfn = NULL;
+}
+
+void
+bna_tx_res_req(int num_txq, int txq_depth, struct bna_res_info *res_info)
+{
+ u32 q_size;
+ u32 page_count;
+ struct bna_mem_info *mem_info;
+
+ res_info[BNA_TX_RES_MEM_T_TCB].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = sizeof(struct bna_tcb);
+ mem_info->num = num_txq;
+
+ q_size = txq_depth * BFI_TXQ_WI_SIZE;
+ q_size = ALIGN(q_size, PAGE_SIZE);
+ page_count = q_size >> PAGE_SHIFT;
+
+ res_info[BNA_TX_RES_MEM_T_QPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = page_count * sizeof(struct bna_dma_addr);
+ mem_info->num = num_txq;
+
+ res_info[BNA_TX_RES_MEM_T_SWQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = page_count * sizeof(void *);
+ mem_info->num = num_txq;
+
+ res_info[BNA_TX_RES_MEM_T_PAGE].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = PAGE_SIZE;
+ mem_info->num = num_txq * page_count;
+
+ res_info[BNA_TX_RES_INTR_T_TXCMPL].res_type = BNA_RES_T_INTR;
+ res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.intr_type =
+ BNA_INTR_T_MSIX;
+ res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.num = num_txq;
+}
+
+struct bna_tx *
+bna_tx_create(struct bna *bna, struct bnad *bnad,
+ struct bna_tx_config *tx_cfg,
+ struct bna_tx_event_cbfn *tx_cbfn,
+ struct bna_res_info *res_info, void *priv)
+{
+ struct bna_intr_info *intr_info;
+ struct bna_tx_mod *tx_mod = &bna->tx_mod;
+ struct bna_tx *tx;
+ struct bna_txq *txq;
+ struct list_head *qe;
+ struct bna_ib_mod *ib_mod = &bna->ib_mod;
+ struct bna_doorbell_qset *qset;
+ struct bna_ib_config ib_config;
+ int page_count;
+ int page_size;
+ int page_idx;
+ int i;
+ unsigned long off;
+
+ intr_info = &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info;
+ page_count = (res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.num) /
+ tx_cfg->num_txq;
+ page_size = res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.len;
+
+ /**
+ * Get resources
+ */
+
+ if ((intr_info->num != 1) && (intr_info->num != tx_cfg->num_txq))
+ return NULL;
+
+ /* Tx */
+
+ if (list_empty(&tx_mod->tx_free_q))
+ return NULL;
+ bfa_q_deq(&tx_mod->tx_free_q, &tx);
+ bfa_q_qe_init(&tx->qe);
+
+ /* TxQs */
+
+ INIT_LIST_HEAD(&tx->txq_q);
+ for (i = 0; i < tx_cfg->num_txq; i++) {
+ if (list_empty(&tx_mod->txq_free_q))
+ goto err_return;
+
+ bfa_q_deq(&tx_mod->txq_free_q, &txq);
+ bfa_q_qe_init(&txq->qe);
+ list_add_tail(&txq->qe, &tx->txq_q);
+ txq->ib = NULL;
+ txq->ib_seg_offset = -1;
+ txq->tx = tx;
+ }
+
+ /* IBs */
+ i = 0;
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+
+ if (intr_info->num == 1)
+ txq->ib = bna_ib_get(ib_mod, intr_info->intr_type,
+ intr_info->idl[0].vector);
+ else
+ txq->ib = bna_ib_get(ib_mod, intr_info->intr_type,
+ intr_info->idl[i].vector);
+
+ if (txq->ib == NULL)
+ goto err_return;
+
+ txq->ib_seg_offset = bna_ib_reserve_idx(txq->ib);
+ if (txq->ib_seg_offset == -1)
+ goto err_return;
+
+ i++;
+ }
+
+ /*
+ * Initialize
+ */
+
+ /* Tx */
+
+ tx->tcb_setup_cbfn = tx_cbfn->tcb_setup_cbfn;
+ tx->tcb_destroy_cbfn = tx_cbfn->tcb_destroy_cbfn;
+ /* Following callbacks are mandatory */
+ tx->tx_stall_cbfn = tx_cbfn->tx_stall_cbfn;
+ tx->tx_resume_cbfn = tx_cbfn->tx_resume_cbfn;
+ tx->tx_cleanup_cbfn = tx_cbfn->tx_cleanup_cbfn;
+
+ list_add_tail(&tx->qe, &tx_mod->tx_active_q);
+ tx->bna = bna;
+ tx->priv = priv;
+ tx->txq_stop_wc.wc_resume = bna_tx_cb_txq_stopped_all;
+ tx->txq_stop_wc.wc_cbarg = tx;
+ tx->txq_stop_wc.wc_count = 0;
+
+ tx->type = tx_cfg->tx_type;
+
+ tx->flags = 0;
+ if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_STARTED) {
+ switch (tx->type) {
+ case BNA_TX_T_REGULAR:
+ if (!(tx->bna->tx_mod.flags &
+ BNA_TX_MOD_F_PORT_LOOPBACK))
+ tx->flags |= BNA_TX_F_PORT_STARTED;
+ break;
+ case BNA_TX_T_LOOPBACK:
+ if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_LOOPBACK)
+ tx->flags |= BNA_TX_F_PORT_STARTED;
+ break;
+ }
+ }
+ if (tx->bna->tx_mod.cee_link)
+ tx->flags |= BNA_TX_F_PRIO_LOCK;
+
+ /* TxQ */
+
+ i = 0;
+ page_idx = 0;
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ txq->priority = tx_mod->priority;
+ txq->tcb = (struct bna_tcb *)
+ res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info.mdl[i].kva;
+ txq->tx_packets = 0;
+ txq->tx_bytes = 0;
+
+ /* IB */
+
+ ib_config.coalescing_timeo = BFI_TX_COALESCING_TIMEO;
+ ib_config.interpkt_timeo = 0; /* Not used */
+ ib_config.interpkt_count = BFI_TX_INTERPKT_COUNT;
+ ib_config.ctrl_flags = (BFI_IB_CF_INTER_PKT_DMA |
+ BFI_IB_CF_INT_ENABLE |
+ BFI_IB_CF_COALESCING_MODE);
+ bna_ib_config(txq->ib, &ib_config);
+
+ /* TCB */
+
+ txq->tcb->producer_index = 0;
+ txq->tcb->consumer_index = 0;
+ txq->tcb->hw_consumer_index = (volatile u32 *)
+ ((volatile u8 *)txq->ib->ib_seg_host_addr_kva +
+ (txq->ib_seg_offset * BFI_IBIDX_SIZE));
+ *(txq->tcb->hw_consumer_index) = 0;
+ txq->tcb->q_depth = tx_cfg->txq_depth;
+ txq->tcb->unmap_q = (void *)
+ res_info[BNA_TX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[i].kva;
+ qset = (struct bna_doorbell_qset *)0;
+ off = (unsigned long)&qset[txq->txq_id].txq[0];
+ txq->tcb->q_dbell = off +
+ BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva);
+ txq->tcb->i_dbell = &txq->ib->door_bell;
+ txq->tcb->intr_type = intr_info->intr_type;
+ txq->tcb->intr_vector = (intr_info->num == 1) ?
+ intr_info->idl[0].vector :
+ intr_info->idl[i].vector;
+ txq->tcb->txq = txq;
+ txq->tcb->bnad = bnad;
+ txq->tcb->id = i;
+
+ /* QPT, SWQPT, Pages */
+ bna_txq_qpt_setup(txq, page_count, page_size,
+ &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info.mdl[i],
+ &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info.mdl[i],
+ &res_info[BNA_TX_RES_MEM_T_PAGE].
+ res_u.mem_info.mdl[page_idx]);
+ txq->tcb->page_idx = page_idx;
+ txq->tcb->page_count = page_count;
+ page_idx += page_count;
+
+ /* Callback to bnad for setting up TCB */
+ if (tx->tcb_setup_cbfn)
+ (tx->tcb_setup_cbfn)(bna->bnad, txq->tcb);
+
+ i++;
+ }
+
+ /* TxF */
+
+ tx->txf.ctrl_flags = BFI_TXF_CF_ENABLE | BFI_TXF_CF_VLAN_WI_BASED;
+ tx->txf.vlan = 0;
+
+ /* Mbox element */
+ bfa_q_qe_init(&tx->mbox_qe.qe);
+
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+
+ return tx;
+
+err_return:
+ bna_tx_free(tx);
+ return NULL;
+}
+
+void
+bna_tx_destroy(struct bna_tx *tx)
+{
+ /* Callback to bnad for destroying TCB */
+ if (tx->tcb_destroy_cbfn) {
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ (tx->tcb_destroy_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+ }
+
+ bna_tx_free(tx);
+}
+
+void
+bna_tx_enable(struct bna_tx *tx)
+{
+ if (tx->fsm != (bfa_sm_t)bna_tx_sm_stopped)
+ return;
+
+ tx->flags |= BNA_TX_F_ENABLED;
+
+ if (tx->flags & BNA_TX_F_PORT_STARTED)
+ bfa_fsm_send_event(tx, TX_E_START);
+}
+
+void
+bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type,
+ void (*cbfn)(void *, struct bna_tx *, enum bna_cb_status))
+{
+ if (type == BNA_SOFT_CLEANUP) {
+ (*cbfn)(tx->bna->bnad, tx, BNA_CB_SUCCESS);
+ return;
+ }
+
+ tx->stop_cbfn = cbfn;
+ tx->stop_cbarg = tx->bna->bnad;
+
+ tx->flags &= ~BNA_TX_F_ENABLED;
+
+ bfa_fsm_send_event(tx, TX_E_STOP);
+}
+
+int
+bna_tx_state_get(struct bna_tx *tx)
+{
+ return bfa_sm_to_state(tx_sm_table, tx->fsm);
+}
+
+void
+bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ int i;
+
+ tx_mod->bna = bna;
+ tx_mod->flags = 0;
+
+ tx_mod->tx = (struct bna_tx *)
+ res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mdl[0].kva;
+ tx_mod->txq = (struct bna_txq *)
+ res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mdl[0].kva;
+
+ INIT_LIST_HEAD(&tx_mod->tx_free_q);
+ INIT_LIST_HEAD(&tx_mod->tx_active_q);
+
+ INIT_LIST_HEAD(&tx_mod->txq_free_q);
+
+ for (i = 0; i < BFI_MAX_TXQ; i++) {
+ tx_mod->tx[i].txf.txf_id = i;
+ bfa_q_qe_init(&tx_mod->tx[i].qe);
+ list_add_tail(&tx_mod->tx[i].qe, &tx_mod->tx_free_q);
+
+ tx_mod->txq[i].txq_id = i;
+ bfa_q_qe_init(&tx_mod->txq[i].qe);
+ list_add_tail(&tx_mod->txq[i].qe, &tx_mod->txq_free_q);
+ }
+
+ tx_mod->tx_stop_wc.wc_resume = bna_tx_mod_cb_tx_stopped_all;
+ tx_mod->tx_stop_wc.wc_cbarg = tx_mod;
+ tx_mod->tx_stop_wc.wc_count = 0;
+}
+
+void
+bna_tx_mod_uninit(struct bna_tx_mod *tx_mod)
+{
+ struct list_head *qe;
+ int i;
+
+ i = 0;
+ list_for_each(qe, &tx_mod->tx_free_q)
+ i++;
+
+ i = 0;
+ list_for_each(qe, &tx_mod->txq_free_q)
+ i++;
+
+ tx_mod->bna = NULL;
+}
+
+void
+bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
+{
+ struct bna_tx *tx;
+ struct list_head *qe;
+
+ tx_mod->flags |= BNA_TX_MOD_F_PORT_STARTED;
+ if (type == BNA_TX_T_LOOPBACK)
+ tx_mod->flags |= BNA_TX_MOD_F_PORT_LOOPBACK;
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ if (tx->type == type)
+ bna_tx_start(tx);
+ }
+}
+
+void
+bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
+{
+ struct bna_tx *tx;
+ struct list_head *qe;
+
+ tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED;
+ tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK;
+
+ tx_mod->stop_cbfn = bna_port_cb_tx_stopped;
+
+ /**
+ * Before calling bna_tx_stop(), increment tx_stop_wc as many times
+ * as we are going to call bna_tx_stop
+ */
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ if (tx->type == type)
+ bfa_wc_up(&tx_mod->tx_stop_wc);
+ }
+
+ if (tx_mod->tx_stop_wc.wc_count == 0) {
+ tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS);
+ tx_mod->stop_cbfn = NULL;
+ return;
+ }
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ if (tx->type == type)
+ bna_tx_stop(tx);
+ }
+}
+
+void
+bna_tx_mod_fail(struct bna_tx_mod *tx_mod)
+{
+ struct bna_tx *tx;
+ struct list_head *qe;
+
+ tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED;
+ tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK;
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ bna_tx_fail(tx);
+ }
+}
+
+void
+bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio)
+{
+ struct bna_tx *tx;
+ struct list_head *qe;
+
+ if (prio != tx_mod->priority) {
+ tx_mod->priority = prio;
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ bna_tx_prio_changed(tx, prio);
+ }
+ }
+}
+
+void
+bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link)
+{
+ struct bna_tx *tx;
+ struct list_head *qe;
+
+ tx_mod->cee_link = cee_link;
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ bna_tx_cee_link_status(tx, cee_link);
+ }
+}
diff --git a/drivers/net/bna/bna_types.h b/drivers/net/bna/bna_types.h
new file mode 100644
index 000000000000..6877310f6ef4
--- /dev/null
+++ b/drivers/net/bna/bna_types.h
@@ -0,0 +1,1128 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BNA_TYPES_H__
+#define __BNA_TYPES_H__
+
+#include "cna.h"
+#include "bna_hw.h"
+#include "bfa_cee.h"
+
+/**
+ *
+ * Forward declarations
+ *
+ */
+
+struct bna_txq;
+struct bna_tx;
+struct bna_rxq;
+struct bna_cq;
+struct bna_rx;
+struct bna_rxf;
+struct bna_port;
+struct bna;
+struct bnad;
+
+/**
+ *
+ * Enums, primitive data types
+ *
+ */
+
+enum bna_status {
+ BNA_STATUS_T_DISABLED = 0,
+ BNA_STATUS_T_ENABLED = 1
+};
+
+enum bna_cleanup_type {
+ BNA_HARD_CLEANUP = 0,
+ BNA_SOFT_CLEANUP = 1
+};
+
+enum bna_cb_status {
+ BNA_CB_SUCCESS = 0,
+ BNA_CB_FAIL = 1,
+ BNA_CB_INTERRUPT = 2,
+ BNA_CB_BUSY = 3,
+ BNA_CB_INVALID_MAC = 4,
+ BNA_CB_MCAST_LIST_FULL = 5,
+ BNA_CB_UCAST_CAM_FULL = 6,
+ BNA_CB_WAITING = 7,
+ BNA_CB_NOT_EXEC = 8
+};
+
+enum bna_res_type {
+ BNA_RES_T_MEM = 1,
+ BNA_RES_T_INTR = 2
+};
+
+enum bna_mem_type {
+ BNA_MEM_T_KVA = 1,
+ BNA_MEM_T_DMA = 2
+};
+
+enum bna_intr_type {
+ BNA_INTR_T_INTX = 1,
+ BNA_INTR_T_MSIX = 2
+};
+
+enum bna_res_req_type {
+ BNA_RES_MEM_T_COM = 0,
+ BNA_RES_MEM_T_ATTR = 1,
+ BNA_RES_MEM_T_FWTRC = 2,
+ BNA_RES_MEM_T_STATS = 3,
+ BNA_RES_MEM_T_SWSTATS = 4,
+ BNA_RES_MEM_T_IBIDX = 5,
+ BNA_RES_MEM_T_IB_ARRAY = 6,
+ BNA_RES_MEM_T_INTR_ARRAY = 7,
+ BNA_RES_MEM_T_IDXSEG_ARRAY = 8,
+ BNA_RES_MEM_T_TX_ARRAY = 9,
+ BNA_RES_MEM_T_TXQ_ARRAY = 10,
+ BNA_RES_MEM_T_RX_ARRAY = 11,
+ BNA_RES_MEM_T_RXP_ARRAY = 12,
+ BNA_RES_MEM_T_RXQ_ARRAY = 13,
+ BNA_RES_MEM_T_UCMAC_ARRAY = 14,
+ BNA_RES_MEM_T_MCMAC_ARRAY = 15,
+ BNA_RES_MEM_T_RIT_ENTRY = 16,
+ BNA_RES_MEM_T_RIT_SEGMENT = 17,
+ BNA_RES_INTR_T_MBOX = 18,
+ BNA_RES_T_MAX
+};
+
+enum bna_tx_res_req_type {
+ BNA_TX_RES_MEM_T_TCB = 0,
+ BNA_TX_RES_MEM_T_UNMAPQ = 1,
+ BNA_TX_RES_MEM_T_QPT = 2,
+ BNA_TX_RES_MEM_T_SWQPT = 3,
+ BNA_TX_RES_MEM_T_PAGE = 4,
+ BNA_TX_RES_INTR_T_TXCMPL = 5,
+ BNA_TX_RES_T_MAX,
+};
+
+enum bna_rx_mem_type {
+ BNA_RX_RES_MEM_T_CCB = 0, /* CQ context */
+ BNA_RX_RES_MEM_T_RCB = 1, /* CQ context */
+ BNA_RX_RES_MEM_T_UNMAPQ = 2, /* UnmapQ for RxQs */
+ BNA_RX_RES_MEM_T_CQPT = 3, /* CQ QPT */
+ BNA_RX_RES_MEM_T_CSWQPT = 4, /* S/W QPT */
+ BNA_RX_RES_MEM_T_CQPT_PAGE = 5, /* CQPT page */
+ BNA_RX_RES_MEM_T_HQPT = 6, /* RX QPT */
+ BNA_RX_RES_MEM_T_DQPT = 7, /* RX QPT */
+ BNA_RX_RES_MEM_T_HSWQPT = 8, /* RX s/w QPT */
+ BNA_RX_RES_MEM_T_DSWQPT = 9, /* RX s/w QPT */
+ BNA_RX_RES_MEM_T_DPAGE = 10, /* RX s/w QPT */
+ BNA_RX_RES_MEM_T_HPAGE = 11, /* RX s/w QPT */
+ BNA_RX_RES_T_INTR = 12, /* Rx interrupts */
+ BNA_RX_RES_T_MAX = 13
+};
+
+enum bna_mbox_state {
+ BNA_MBOX_FREE = 0,
+ BNA_MBOX_POSTED = 1
+};
+
+enum bna_tx_type {
+ BNA_TX_T_REGULAR = 0,
+ BNA_TX_T_LOOPBACK = 1,
+};
+
+enum bna_tx_flags {
+ BNA_TX_F_PORT_STARTED = 1,
+ BNA_TX_F_ENABLED = 2,
+ BNA_TX_F_PRIO_LOCK = 4,
+};
+
+enum bna_tx_mod_flags {
+ BNA_TX_MOD_F_PORT_STARTED = 1,
+ BNA_TX_MOD_F_PORT_LOOPBACK = 2,
+};
+
+enum bna_rx_type {
+ BNA_RX_T_REGULAR = 0,
+ BNA_RX_T_LOOPBACK = 1,
+};
+
+enum bna_rxp_type {
+ BNA_RXP_SINGLE = 1,
+ BNA_RXP_SLR = 2,
+ BNA_RXP_HDS = 3
+};
+
+enum bna_rxmode {
+ BNA_RXMODE_PROMISC = 1,
+ BNA_RXMODE_DEFAULT = 2,
+ BNA_RXMODE_ALLMULTI = 4
+};
+
+enum bna_rx_event {
+ RX_E_START = 1,
+ RX_E_STOP = 2,
+ RX_E_FAIL = 3,
+ RX_E_RXF_STARTED = 4,
+ RX_E_RXF_STOPPED = 5,
+ RX_E_RXQ_STOPPED = 6,
+};
+
+enum bna_rx_state {
+ BNA_RX_STOPPED = 1,
+ BNA_RX_RXF_START_WAIT = 2,
+ BNA_RX_STARTED = 3,
+ BNA_RX_RXF_STOP_WAIT = 4,
+ BNA_RX_RXQ_STOP_WAIT = 5,
+};
+
+enum bna_rx_flags {
+ BNA_RX_F_ENABLE = 0x01, /* bnad enabled rxf */
+ BNA_RX_F_PORT_ENABLED = 0x02, /* Port object is enabled */
+ BNA_RX_F_PORT_FAILED = 0x04, /* Port in failed state */
+};
+
+enum bna_rx_mod_flags {
+ BNA_RX_MOD_F_PORT_STARTED = 1,
+ BNA_RX_MOD_F_PORT_LOOPBACK = 2,
+};
+
+enum bna_rxf_oper_state {
+ BNA_RXF_OPER_STATE_RUNNING = 0x01, /* rxf operational */
+ BNA_RXF_OPER_STATE_PAUSED = 0x02, /* rxf in PAUSED state */
+};
+
+enum bna_rxf_flags {
+ BNA_RXF_FL_STOP_PENDING = 0x01,
+ BNA_RXF_FL_FAILED = 0x02,
+ BNA_RXF_FL_RSS_CONFIG_PENDING = 0x04,
+ BNA_RXF_FL_OPERSTATE_CHANGED = 0x08,
+ BNA_RXF_FL_RXF_ENABLED = 0x10,
+ BNA_RXF_FL_VLAN_CONFIG_PENDING = 0x20,
+};
+
+enum bna_rxf_event {
+ RXF_E_START = 1,
+ RXF_E_STOP = 2,
+ RXF_E_FAIL = 3,
+ RXF_E_CAM_FLTR_MOD = 4,
+ RXF_E_STARTED = 5,
+ RXF_E_STOPPED = 6,
+ RXF_E_CAM_FLTR_RESP = 7,
+ RXF_E_PAUSE = 8,
+ RXF_E_RESUME = 9,
+ RXF_E_STAT_CLEARED = 10,
+};
+
+enum bna_rxf_state {
+ BNA_RXF_STOPPED = 1,
+ BNA_RXF_START_WAIT = 2,
+ BNA_RXF_CAM_FLTR_MOD_WAIT = 3,
+ BNA_RXF_STARTED = 4,
+ BNA_RXF_CAM_FLTR_CLR_WAIT = 5,
+ BNA_RXF_STOP_WAIT = 6,
+ BNA_RXF_PAUSE_WAIT = 7,
+ BNA_RXF_RESUME_WAIT = 8,
+ BNA_RXF_STAT_CLR_WAIT = 9,
+};
+
+enum bna_port_type {
+ BNA_PORT_T_REGULAR = 0,
+ BNA_PORT_T_LOOPBACK_INTERNAL = 1,
+ BNA_PORT_T_LOOPBACK_EXTERNAL = 2,
+};
+
+enum bna_link_status {
+ BNA_LINK_DOWN = 0,
+ BNA_LINK_UP = 1,
+ BNA_CEE_UP = 2
+};
+
+enum bna_llport_flags {
+ BNA_LLPORT_F_ENABLED = 1,
+ BNA_LLPORT_F_RX_ENABLED = 2
+};
+
+enum bna_port_flags {
+ BNA_PORT_F_DEVICE_READY = 1,
+ BNA_PORT_F_ENABLED = 2,
+ BNA_PORT_F_PAUSE_CHANGED = 4,
+ BNA_PORT_F_MTU_CHANGED = 8
+};
+
+enum bna_pkt_rates {
+ BNA_PKT_RATE_10K = 10000,
+ BNA_PKT_RATE_20K = 20000,
+ BNA_PKT_RATE_30K = 30000,
+ BNA_PKT_RATE_40K = 40000,
+ BNA_PKT_RATE_50K = 50000,
+ BNA_PKT_RATE_60K = 60000,
+ BNA_PKT_RATE_70K = 70000,
+ BNA_PKT_RATE_80K = 80000,
+};
+
+enum bna_dim_load_types {
+ BNA_LOAD_T_HIGH_4 = 0, /* 80K <= r */
+ BNA_LOAD_T_HIGH_3 = 1, /* 60K <= r < 80K */
+ BNA_LOAD_T_HIGH_2 = 2, /* 50K <= r < 60K */
+ BNA_LOAD_T_HIGH_1 = 3, /* 40K <= r < 50K */
+ BNA_LOAD_T_LOW_1 = 4, /* 30K <= r < 40K */
+ BNA_LOAD_T_LOW_2 = 5, /* 20K <= r < 30K */
+ BNA_LOAD_T_LOW_3 = 6, /* 10K <= r < 20K */
+ BNA_LOAD_T_LOW_4 = 7, /* r < 10K */
+ BNA_LOAD_T_MAX = 8
+};
+
+enum bna_dim_bias_types {
+ BNA_BIAS_T_SMALL = 0, /* small pkts > (large pkts * 2) */
+ BNA_BIAS_T_LARGE = 1, /* Not BNA_BIAS_T_SMALL */
+ BNA_BIAS_T_MAX = 2
+};
+
+struct bna_mac {
+ /* This should be the first one */
+ struct list_head qe;
+ u8 addr[ETH_ALEN];
+};
+
+struct bna_mem_descr {
+ u32 len;
+ void *kva;
+ struct bna_dma_addr dma;
+};
+
+struct bna_mem_info {
+ enum bna_mem_type mem_type;
+ u32 len;
+ u32 num;
+ u32 align_sz; /* 0/1 = no alignment */
+ struct bna_mem_descr *mdl;
+ void *cookie; /* For bnad to unmap dma later */
+};
+
+struct bna_intr_descr {
+ int vector;
+};
+
+struct bna_intr_info {
+ enum bna_intr_type intr_type;
+ int num;
+ struct bna_intr_descr *idl;
+};
+
+union bna_res_u {
+ struct bna_mem_info mem_info;
+ struct bna_intr_info intr_info;
+};
+
+struct bna_res_info {
+ enum bna_res_type res_type;
+ union bna_res_u res_u;
+};
+
+/* HW QPT */
+struct bna_qpt {
+ struct bna_dma_addr hw_qpt_ptr;
+ void *kv_qpt_ptr;
+ u32 page_count;
+ u32 page_size;
+};
+
+/**
+ *
+ * Device
+ *
+ */
+
+struct bna_device {
+ bfa_fsm_t fsm;
+ struct bfa_ioc ioc;
+
+ enum bna_intr_type intr_type;
+ int vector;
+
+ void (*ready_cbfn)(struct bnad *bnad, enum bna_cb_status status);
+ struct bnad *ready_cbarg;
+
+ void (*stop_cbfn)(struct bnad *bnad, enum bna_cb_status status);
+ struct bnad *stop_cbarg;
+
+ struct bna *bna;
+};
+
+/**
+ *
+ * Mail box
+ *
+ */
+
+struct bna_mbox_qe {
+ /* This should be the first one */
+ struct list_head qe;
+
+ struct bfa_mbox_cmd cmd;
+ u32 cmd_len;
+ /* Callback for port, tx, rx, rxf */
+ void (*cbfn)(void *arg, int status);
+ void *cbarg;
+};
+
+struct bna_mbox_mod {
+ enum bna_mbox_state state;
+ struct list_head posted_q;
+ u32 msg_pending;
+ u32 msg_ctr;
+ struct bna *bna;
+};
+
+/**
+ *
+ * Port
+ *
+ */
+
+/* Pause configuration */
+struct bna_pause_config {
+ enum bna_status tx_pause;
+ enum bna_status rx_pause;
+};
+
+struct bna_llport {
+ bfa_fsm_t fsm;
+ enum bna_llport_flags flags;
+
+ enum bna_port_type type;
+
+ enum bna_link_status link_status;
+
+ int admin_up_count;
+
+ void (*stop_cbfn)(struct bna_port *, enum bna_cb_status);
+
+ struct bna_mbox_qe mbox_qe;
+
+ struct bna *bna;
+};
+
+struct bna_port {
+ bfa_fsm_t fsm;
+ enum bna_port_flags flags;
+
+ enum bna_port_type type;
+
+ struct bna_llport llport;
+
+ struct bna_pause_config pause_config;
+ u8 priority;
+ int mtu;
+
+ /* Callback for bna_port_disable(), port_stop() */
+ void (*stop_cbfn)(void *, enum bna_cb_status);
+ void *stop_cbarg;
+
+ /* Callback for bna_port_pause_config() */
+ void (*pause_cbfn)(struct bnad *, enum bna_cb_status);
+
+ /* Callback for bna_port_mtu_set() */
+ void (*mtu_cbfn)(struct bnad *, enum bna_cb_status);
+
+ void (*link_cbfn)(struct bnad *, enum bna_link_status);
+
+ struct bfa_wc chld_stop_wc;
+
+ struct bna_mbox_qe mbox_qe;
+
+ struct bna *bna;
+};
+
+/**
+ *
+ * Interrupt Block
+ *
+ */
+
+/* IB index segment structure */
+struct bna_ibidx_seg {
+ /* This should be the first one */
+ struct list_head qe;
+
+ u8 ib_seg_size;
+ u8 ib_idx_tbl_offset;
+};
+
+/* Interrupt structure */
+struct bna_intr {
+ /* This should be the first one */
+ struct list_head qe;
+ int ref_count;
+
+ enum bna_intr_type intr_type;
+ int vector;
+
+ struct bna_ib *ib;
+};
+
+/* Doorbell structure */
+struct bna_ib_dbell {
+ void *__iomem doorbell_addr;
+ u32 doorbell_ack;
+};
+
+/* Interrupt timer configuration */
+struct bna_ib_config {
+ u8 coalescing_timeo; /* Unit is 5usec. */
+
+ int interpkt_count;
+ int interpkt_timeo;
+
+ enum ib_flags ctrl_flags;
+};
+
+/* IB structure */
+struct bna_ib {
+ /* This should be the first one */
+ struct list_head qe;
+
+ int ib_id;
+
+ int ref_count;
+ int start_count;
+
+ struct bna_dma_addr ib_seg_host_addr;
+ void *ib_seg_host_addr_kva;
+ u32 idx_mask; /* Size >= BNA_IBIDX_MAX_SEGSIZE */
+
+ struct bna_ibidx_seg *idx_seg;
+
+ struct bna_ib_dbell door_bell;
+
+ struct bna_intr *intr;
+
+ struct bna_ib_config ib_config;
+
+ struct bna *bna;
+};
+
+/* IB module - keeps track of IBs and interrupts */
+struct bna_ib_mod {
+ struct bna_ib *ib; /* BFI_MAX_IB entries */
+ struct bna_intr *intr; /* BFI_MAX_IB entries */
+ struct bna_ibidx_seg *idx_seg; /* BNA_IBIDX_TOTAL_SEGS */
+
+ struct list_head ib_free_q;
+
+ struct list_head ibidx_seg_pool[BFI_IBIDX_TOTAL_POOLS];
+
+ struct list_head intr_free_q;
+ struct list_head intr_active_q;
+
+ struct bna *bna;
+};
+
+/**
+ *
+ * Tx object
+ *
+ */
+
+/* Tx datapath control structure */
+#define BNA_Q_NAME_SIZE 16
+struct bna_tcb {
+ /* Fast path */
+ void **sw_qpt;
+ void *unmap_q;
+ u32 producer_index;
+ u32 consumer_index;
+ volatile u32 *hw_consumer_index;
+ u32 q_depth;
+ void *__iomem q_dbell;
+ struct bna_ib_dbell *i_dbell;
+ int page_idx;
+ int page_count;
+ /* Control path */
+ struct bna_txq *txq;
+ struct bnad *bnad;
+ enum bna_intr_type intr_type;
+ int intr_vector;
+ u8 priority; /* Current priority */
+ unsigned long flags; /* Used by bnad as required */
+ int id;
+ char name[BNA_Q_NAME_SIZE];
+};
+
+/* TxQ QPT and configuration */
+struct bna_txq {
+ /* This should be the first one */
+ struct list_head qe;
+
+ int txq_id;
+
+ u8 priority;
+
+ struct bna_qpt qpt;
+ struct bna_tcb *tcb;
+ struct bna_ib *ib;
+ int ib_seg_offset;
+
+ struct bna_tx *tx;
+
+ u64 tx_packets;
+ u64 tx_bytes;
+};
+
+/* TxF structure (hardware Tx Function) */
+struct bna_txf {
+ int txf_id;
+ enum txf_flags ctrl_flags;
+ u16 vlan;
+};
+
+/* Tx object */
+struct bna_tx {
+ /* This should be the first one */
+ struct list_head qe;
+
+ bfa_fsm_t fsm;
+ enum bna_tx_flags flags;
+
+ enum bna_tx_type type;
+
+ struct list_head txq_q;
+ struct bna_txf txf;
+
+ /* Tx event handlers */
+ void (*tcb_setup_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tcb_destroy_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tx_stall_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tx_resume_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tcb *);
+
+ /* callback for bna_tx_disable(), bna_tx_stop() */
+ void (*stop_cbfn)(void *arg, struct bna_tx *tx,
+ enum bna_cb_status status);
+ void *stop_cbarg;
+
+ /* callback for bna_tx_prio_set() */
+ void (*prio_change_cbfn)(struct bnad *bnad, struct bna_tx *tx,
+ enum bna_cb_status status);
+
+ struct bfa_wc txq_stop_wc;
+
+ struct bna_mbox_qe mbox_qe;
+
+ struct bna *bna;
+ void *priv; /* bnad's cookie */
+};
+
+struct bna_tx_config {
+ int num_txq;
+ int txq_depth;
+ enum bna_tx_type tx_type;
+};
+
+struct bna_tx_event_cbfn {
+ /* Optional */
+ void (*tcb_setup_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tcb_destroy_cbfn)(struct bnad *, struct bna_tcb *);
+ /* Mandatory */
+ void (*tx_stall_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tx_resume_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tcb *);
+};
+
+/* Tx module - keeps track of free, active tx objects */
+struct bna_tx_mod {
+ struct bna_tx *tx; /* BFI_MAX_TXQ entries */
+ struct bna_txq *txq; /* BFI_MAX_TXQ entries */
+
+ struct list_head tx_free_q;
+ struct list_head tx_active_q;
+
+ struct list_head txq_free_q;
+
+ /* callback for bna_tx_mod_stop() */
+ void (*stop_cbfn)(struct bna_port *port,
+ enum bna_cb_status status);
+
+ struct bfa_wc tx_stop_wc;
+
+ enum bna_tx_mod_flags flags;
+
+ int priority;
+ int cee_link;
+
+ u32 txf_bmap[2];
+
+ struct bna *bna;
+};
+
+/**
+ *
+ * Receive Indirection Table
+ *
+ */
+
+/* One row of RIT table */
+struct bna_rit_entry {
+ u8 large_rxq_id; /* used for either large or data buffers */
+ u8 small_rxq_id; /* used for either small or header buffers */
+};
+
+/* RIT segment */
+struct bna_rit_segment {
+ struct list_head qe;
+
+ u32 rit_offset;
+ u32 rit_size;
+ /**
+ * max_rit_size: Varies per RIT segment depending on how RIT is
+ * partitioned
+ */
+ u32 max_rit_size;
+
+ struct bna_rit_entry *rit;
+};
+
+struct bna_rit_mod {
+ struct bna_rit_entry *rit;
+ struct bna_rit_segment *rit_segment;
+
+ struct list_head rit_seg_pool[BFI_RIT_SEG_TOTAL_POOLS];
+};
+
+/**
+ *
+ * Rx object
+ *
+ */
+
+/* Rx datapath control structure */
+struct bna_rcb {
+ /* Fast path */
+ void **sw_qpt;
+ void *unmap_q;
+ u32 producer_index;
+ u32 consumer_index;
+ u32 q_depth;
+ void *__iomem q_dbell;
+ int page_idx;
+ int page_count;
+ /* Control path */
+ struct bna_rxq *rxq;
+ struct bna_cq *cq;
+ struct bnad *bnad;
+ unsigned long flags;
+ int id;
+};
+
+/* RxQ structure - QPT, configuration */
+struct bna_rxq {
+ struct list_head qe;
+ int rxq_id;
+
+ int buffer_size;
+ int q_depth;
+
+ struct bna_qpt qpt;
+ struct bna_rcb *rcb;
+
+ struct bna_rxp *rxp;
+ struct bna_rx *rx;
+
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 rx_packets_with_error;
+ u64 rxbuf_alloc_failed;
+};
+
+/* RxQ pair */
+union bna_rxq_u {
+ struct {
+ struct bna_rxq *hdr;
+ struct bna_rxq *data;
+ } hds;
+ struct {
+ struct bna_rxq *small;
+ struct bna_rxq *large;
+ } slr;
+ struct {
+ struct bna_rxq *only;
+ struct bna_rxq *reserved;
+ } single;
+};
+
+/* Packet rate for Dynamic Interrupt Moderation */
+struct bna_pkt_rate {
+ u32 small_pkt_cnt;
+ u32 large_pkt_cnt;
+};
+
+/* Completion control structure */
+struct bna_ccb {
+ /* Fast path */
+ void **sw_qpt;
+ u32 producer_index;
+ volatile u32 *hw_producer_index;
+ u32 q_depth;
+ struct bna_ib_dbell *i_dbell;
+ struct bna_rcb *rcb[2];
+ void *ctrl; /* For bnad */
+ struct bna_pkt_rate pkt_rate;
+ int page_idx;
+ int page_count;
+
+ /* Control path */
+ struct bna_cq *cq;
+ struct bnad *bnad;
+ enum bna_intr_type intr_type;
+ int intr_vector;
+ u8 rx_coalescing_timeo; /* For NAPI */
+ int id;
+ char name[BNA_Q_NAME_SIZE];
+};
+
+/* CQ QPT, configuration */
+struct bna_cq {
+ int cq_id;
+
+ struct bna_qpt qpt;
+ struct bna_ccb *ccb;
+
+ struct bna_ib *ib;
+ u8 ib_seg_offset;
+
+ struct bna_rx *rx;
+};
+
+struct bna_rss_config {
+ enum rss_hash_type hash_type;
+ u8 hash_mask;
+ u32 toeplitz_hash_key[BFI_RSS_HASH_KEY_LEN];
+};
+
+struct bna_hds_config {
+ enum hds_header_type hdr_type;
+ int header_size;
+};
+
+/* This structure is used during RX creation */
+struct bna_rx_config {
+ enum bna_rx_type rx_type;
+ int num_paths;
+ enum bna_rxp_type rxp_type;
+ int paused;
+ int q_depth;
+ /*
+ * Small/Large (or Header/Data) buffer size to be configured
+ * for SLR and HDS queue type. Large buffer size comes from
+ * port->mtu.
+ */
+ int small_buff_size;
+
+ enum bna_status rss_status;
+ struct bna_rss_config rss_config;
+
+ enum bna_status hds_status;
+ struct bna_hds_config hds_config;
+
+ enum bna_status vlan_strip_status;
+};
+
+/* Rx Path structure - one per MSIX vector/CPU */
+struct bna_rxp {
+ /* This should be the first one */
+ struct list_head qe;
+
+ enum bna_rxp_type type;
+ union bna_rxq_u rxq;
+ struct bna_cq cq;
+
+ struct bna_rx *rx;
+
+ /* MSI-x vector number for configuring RSS */
+ int vector;
+
+ struct bna_mbox_qe mbox_qe;
+};
+
+/* HDS configuration structure */
+struct bna_rxf_hds {
+ enum hds_header_type hdr_type;
+ int header_size;
+};
+
+/* RSS configuration structure */
+struct bna_rxf_rss {
+ enum rss_hash_type hash_type;
+ u8 hash_mask;
+ u32 toeplitz_hash_key[BFI_RSS_HASH_KEY_LEN];
+};
+
+/* RxF structure (hardware Rx Function) */
+struct bna_rxf {
+ bfa_fsm_t fsm;
+ int rxf_id;
+ enum rxf_flags ctrl_flags;
+ u16 default_vlan_tag;
+ enum bna_rxf_oper_state rxf_oper_state;
+ enum bna_status hds_status;
+ struct bna_rxf_hds hds_cfg;
+ enum bna_status rss_status;
+ struct bna_rxf_rss rss_cfg;
+ struct bna_rit_segment *rit_segment;
+ struct bna_rx *rx;
+ u32 forced_offset;
+ struct bna_mbox_qe mbox_qe;
+ int mcast_rxq_id;
+
+ /* callback for bna_rxf_start() */
+ void (*start_cbfn) (struct bna_rx *rx, enum bna_cb_status status);
+ struct bna_rx *start_cbarg;
+
+ /* callback for bna_rxf_stop() */
+ void (*stop_cbfn) (struct bna_rx *rx, enum bna_cb_status status);
+ struct bna_rx *stop_cbarg;
+
+ /* callback for bna_rxf_receive_enable() / bna_rxf_receive_disable() */
+ void (*oper_state_cbfn) (struct bnad *bnad, struct bna_rx *rx,
+ enum bna_cb_status status);
+ struct bnad *oper_state_cbarg;
+
+ /**
+ * callback for:
+ * bna_rxf_ucast_set()
+ * bna_rxf_{ucast/mcast}_add(),
+ * bna_rxf_{ucast/mcast}_del(),
+ * bna_rxf_mode_set()
+ */
+ void (*cam_fltr_cbfn)(struct bnad *bnad, struct bna_rx *rx,
+ enum bna_cb_status status);
+ struct bnad *cam_fltr_cbarg;
+
+ enum bna_rxf_flags rxf_flags;
+
+ /* List of unicast addresses yet to be applied to h/w */
+ struct list_head ucast_pending_add_q;
+ struct list_head ucast_pending_del_q;
+ int ucast_pending_set;
+ /* ucast addresses applied to the h/w */
+ struct list_head ucast_active_q;
+ struct bna_mac *ucast_active_mac;
+
+ /* List of multicast addresses yet to be applied to h/w */
+ struct list_head mcast_pending_add_q;
+ struct list_head mcast_pending_del_q;
+ /* multicast addresses applied to the h/w */
+ struct list_head mcast_active_q;
+
+ /* Rx modes yet to be applied to h/w */
+ enum bna_rxmode rxmode_pending;
+ enum bna_rxmode rxmode_pending_bitmask;
+ /* Rx modes applied to h/w */
+ enum bna_rxmode rxmode_active;
+
+ enum bna_status vlan_filter_status;
+ u32 vlan_filter_table[(BFI_MAX_VLAN + 1) / 32];
+};
+
+/* Rx object */
+struct bna_rx {
+ /* This should be the first one */
+ struct list_head qe;
+
+ bfa_fsm_t fsm;
+
+ enum bna_rx_type type;
+
+ /* list-head for RX path objects */
+ struct list_head rxp_q;
+
+ struct bna_rxf rxf;
+
+ enum bna_rx_flags rx_flags;
+
+ struct bna_mbox_qe mbox_qe;
+
+ struct bfa_wc rxq_stop_wc;
+
+ /* Rx event handlers */
+ void (*rcb_setup_cbfn)(struct bnad *, struct bna_rcb *);
+ void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *);
+ void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *);
+ void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *);
+ void (*rx_cleanup_cbfn)(struct bnad *, struct bna_ccb *);
+ void (*rx_post_cbfn)(struct bnad *, struct bna_rcb *);
+
+ /* callback for bna_rx_disable(), bna_rx_stop() */
+ void (*stop_cbfn)(void *arg, struct bna_rx *rx,
+ enum bna_cb_status status);
+ void *stop_cbarg;
+
+ struct bna *bna;
+ void *priv; /* bnad's cookie */
+};
+
+struct bna_rx_event_cbfn {
+ /* Optional */
+ void (*rcb_setup_cbfn)(struct bnad *, struct bna_rcb *);
+ void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *);
+ void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *);
+ void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *);
+ /* Mandatory */
+ void (*rx_cleanup_cbfn)(struct bnad *, struct bna_ccb *);
+ void (*rx_post_cbfn)(struct bnad *, struct bna_rcb *);
+};
+
+/* Rx module - keeps track of free, active rx objects */
+struct bna_rx_mod {
+ struct bna *bna; /* back pointer to parent */
+ struct bna_rx *rx; /* BFI_MAX_RXQ entries */
+ struct bna_rxp *rxp; /* BFI_MAX_RXQ entries */
+ struct bna_rxq *rxq; /* BFI_MAX_RXQ entries */
+
+ struct list_head rx_free_q;
+ struct list_head rx_active_q;
+ int rx_free_count;
+
+ struct list_head rxp_free_q;
+ int rxp_free_count;
+
+ struct list_head rxq_free_q;
+ int rxq_free_count;
+
+ enum bna_rx_mod_flags flags;
+
+ /* callback for bna_rx_mod_stop() */
+ void (*stop_cbfn)(struct bna_port *port,
+ enum bna_cb_status status);
+
+ struct bfa_wc rx_stop_wc;
+ u32 dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX];
+ u32 rxf_bmap[2];
+};
+
+/**
+ *
+ * CAM
+ *
+ */
+
+struct bna_ucam_mod {
+ struct bna_mac *ucmac; /* BFI_MAX_UCMAC entries */
+ struct list_head free_q;
+
+ struct bna *bna;
+};
+
+struct bna_mcam_mod {
+ struct bna_mac *mcmac; /* BFI_MAX_MCMAC entries */
+ struct list_head free_q;
+
+ struct bna *bna;
+};
+
+/**
+ *
+ * Statistics
+ *
+ */
+
+struct bna_tx_stats {
+ int tx_state;
+ int tx_flags;
+ int num_txqs;
+ u32 txq_bmap[2];
+ int txf_id;
+};
+
+struct bna_rx_stats {
+ int rx_state;
+ int rx_flags;
+ int num_rxps;
+ int num_rxqs;
+ u32 rxq_bmap[2];
+ u32 cq_bmap[2];
+ int rxf_id;
+ int rxf_state;
+ int rxf_oper_state;
+ int num_active_ucast;
+ int num_active_mcast;
+ int rxmode_active;
+ int vlan_filter_status;
+ u32 vlan_filter_table[(BFI_MAX_VLAN + 1) / 32];
+ int rss_status;
+ int hds_status;
+};
+
+struct bna_sw_stats {
+ int device_state;
+ int port_state;
+ int port_flags;
+ int llport_state;
+ int priority;
+ int num_active_tx;
+ int num_active_rx;
+ struct bna_tx_stats tx_stats[BFI_MAX_TXQ];
+ struct bna_rx_stats rx_stats[BFI_MAX_RXQ];
+};
+
+struct bna_stats {
+ u32 txf_bmap[2];
+ u32 rxf_bmap[2];
+ struct bfi_ll_stats *hw_stats;
+ struct bna_sw_stats *sw_stats;
+};
+
+/**
+ *
+ * BNA
+ *
+ */
+
+struct bna {
+ struct bfa_pcidev pcidev;
+
+ int port_num;
+
+ struct bna_chip_regs regs;
+
+ struct bna_dma_addr hw_stats_dma;
+ struct bna_stats stats;
+
+ struct bna_device device;
+ struct bfa_cee cee;
+
+ struct bna_mbox_mod mbox_mod;
+
+ struct bna_port port;
+
+ struct bna_tx_mod tx_mod;
+
+ struct bna_rx_mod rx_mod;
+
+ struct bna_ib_mod ib_mod;
+
+ struct bna_ucam_mod ucam_mod;
+ struct bna_mcam_mod mcam_mod;
+
+ struct bna_rit_mod rit_mod;
+
+ int rxf_default_id;
+ int rxf_promisc_id;
+
+ struct bna_mbox_qe mbox_qe;
+
+ struct bnad *bnad;
+};
+
+#endif /* __BNA_TYPES_H__ */
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
new file mode 100644
index 000000000000..7e839b9cec22
--- /dev/null
+++ b/drivers/net/bna/bnad.c
@@ -0,0 +1,3264 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/in.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+
+#include "bnad.h"
+#include "bna.h"
+#include "cna.h"
+
+static DEFINE_MUTEX(bnad_fwimg_mutex);
+
+/*
+ * Module params
+ */
+static uint bnad_msix_disable;
+module_param(bnad_msix_disable, uint, 0444);
+MODULE_PARM_DESC(bnad_msix_disable, "Disable MSIX mode");
+
+static uint bnad_ioc_auto_recover = 1;
+module_param(bnad_ioc_auto_recover, uint, 0444);
+MODULE_PARM_DESC(bnad_ioc_auto_recover, "Enable / Disable auto recovery");
+
+/*
+ * Global variables
+ */
+u32 bnad_rxqs_per_cq = 2;
+
+static const u8 bnad_bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+/*
+ * Local MACROS
+ */
+#define BNAD_TX_UNMAPQ_DEPTH (bnad->txq_depth * 2)
+
+#define BNAD_RX_UNMAPQ_DEPTH (bnad->rxq_depth)
+
+#define BNAD_GET_MBOX_IRQ(_bnad) \
+ (((_bnad)->cfg_flags & BNAD_CF_MSIX) ? \
+ ((_bnad)->msix_table[(_bnad)->msix_num - 1].vector) : \
+ ((_bnad)->pcidev->irq))
+
+#define BNAD_FILL_UNMAPQ_MEM_REQ(_res_info, _num, _depth) \
+do { \
+ (_res_info)->res_type = BNA_RES_T_MEM; \
+ (_res_info)->res_u.mem_info.mem_type = BNA_MEM_T_KVA; \
+ (_res_info)->res_u.mem_info.num = (_num); \
+ (_res_info)->res_u.mem_info.len = \
+ sizeof(struct bnad_unmap_q) + \
+ (sizeof(struct bnad_skb_unmap) * ((_depth) - 1)); \
+} while (0)
+
+/*
+ * Reinitialize completions in CQ, once Rx is taken down
+ */
+static void
+bnad_cq_cmpl_init(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ struct bna_cq_entry *cmpl, *next_cmpl;
+ unsigned int wi_range, wis = 0, ccb_prod = 0;
+ int i;
+
+ BNA_CQ_QPGE_PTR_GET(ccb_prod, ccb->sw_qpt, cmpl,
+ wi_range);
+
+ for (i = 0; i < ccb->q_depth; i++) {
+ wis++;
+ if (likely(--wi_range))
+ next_cmpl = cmpl + 1;
+ else {
+ BNA_QE_INDX_ADD(ccb_prod, wis, ccb->q_depth);
+ wis = 0;
+ BNA_CQ_QPGE_PTR_GET(ccb_prod, ccb->sw_qpt,
+ next_cmpl, wi_range);
+ }
+ cmpl->valid = 0;
+ cmpl = next_cmpl;
+ }
+}
+
+/*
+ * Frees all pending Tx Bufs
+ * At this point no activity is expected on the Q,
+ * so DMA unmap & freeing is fine.
+ */
+static void
+bnad_free_all_txbufs(struct bnad *bnad,
+ struct bna_tcb *tcb)
+{
+ u16 unmap_cons;
+ struct bnad_unmap_q *unmap_q = tcb->unmap_q;
+ struct bnad_skb_unmap *unmap_array;
+ struct sk_buff *skb = NULL;
+ int i;
+
+ unmap_array = unmap_q->unmap_array;
+
+ unmap_cons = 0;
+ while (unmap_cons < unmap_q->q_depth) {
+ skb = unmap_array[unmap_cons].skb;
+ if (!skb) {
+ unmap_cons++;
+ continue;
+ }
+ unmap_array[unmap_cons].skb = NULL;
+
+ pci_unmap_single(bnad->pcidev,
+ pci_unmap_addr(&unmap_array[unmap_cons],
+ dma_addr), skb_headlen(skb),
+ PCI_DMA_TODEVICE);
+
+ pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0);
+ unmap_cons++;
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ pci_unmap_page(bnad->pcidev,
+ pci_unmap_addr(&unmap_array[unmap_cons],
+ dma_addr),
+ skb_shinfo(skb)->frags[i].size,
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr,
+ 0);
+ unmap_cons++;
+ }
+ dev_kfree_skb_any(skb);
+ }
+}
+
+/* Data Path Handlers */
+
+/*
+ * bnad_free_txbufs : Frees the Tx bufs on Tx completion
+ * Can be called in a) Interrupt context
+ * b) Sending context
+ * c) Tasklet context
+ */
+static u32
+bnad_free_txbufs(struct bnad *bnad,
+ struct bna_tcb *tcb)
+{
+ u32 sent_packets = 0, sent_bytes = 0;
+ u16 wis, unmap_cons, updated_hw_cons;
+ struct bnad_unmap_q *unmap_q = tcb->unmap_q;
+ struct bnad_skb_unmap *unmap_array;
+ struct sk_buff *skb;
+ int i;
+
+ /*
+ * Just return if TX is stopped. This check is useful
+ * when bnad_free_txbufs() runs out of a tasklet scheduled
+ * before bnad_cb_tx_cleanup() cleared BNAD_RF_TX_STARTED bit
+ * but this routine runs actually after the cleanup has been
+ * executed.
+ */
+ if (!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))
+ return 0;
+
+ updated_hw_cons = *(tcb->hw_consumer_index);
+
+ wis = BNA_Q_INDEX_CHANGE(tcb->consumer_index,
+ updated_hw_cons, tcb->q_depth);
+
+ BUG_ON(!(wis <= BNA_QE_IN_USE_CNT(tcb, tcb->q_depth)));
+
+ unmap_array = unmap_q->unmap_array;
+ unmap_cons = unmap_q->consumer_index;
+
+ prefetch(&unmap_array[unmap_cons + 1]);
+ while (wis) {
+ skb = unmap_array[unmap_cons].skb;
+
+ unmap_array[unmap_cons].skb = NULL;
+
+ sent_packets++;
+ sent_bytes += skb->len;
+ wis -= BNA_TXQ_WI_NEEDED(1 + skb_shinfo(skb)->nr_frags);
+
+ pci_unmap_single(bnad->pcidev,
+ pci_unmap_addr(&unmap_array[unmap_cons],
+ dma_addr), skb_headlen(skb),
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0);
+ BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth);
+
+ prefetch(&unmap_array[unmap_cons + 1]);
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ prefetch(&unmap_array[unmap_cons + 1]);
+
+ pci_unmap_page(bnad->pcidev,
+ pci_unmap_addr(&unmap_array[unmap_cons],
+ dma_addr),
+ skb_shinfo(skb)->frags[i].size,
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr,
+ 0);
+ BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth);
+ }
+ dev_kfree_skb_any(skb);
+ }
+
+ /* Update consumer pointers. */
+ tcb->consumer_index = updated_hw_cons;
+ unmap_q->consumer_index = unmap_cons;
+
+ tcb->txq->tx_packets += sent_packets;
+ tcb->txq->tx_bytes += sent_bytes;
+
+ return sent_packets;
+}
+
+/* Tx Free Tasklet function */
+/* Frees for all the tcb's in all the Tx's */
+/*
+ * Scheduled from sending context, so that
+ * the fat Tx lock is not held for too long
+ * in the sending context.
+ */
+static void
+bnad_tx_free_tasklet(unsigned long bnad_ptr)
+{
+ struct bnad *bnad = (struct bnad *)bnad_ptr;
+ struct bna_tcb *tcb;
+ u32 acked;
+ int i, j;
+
+ for (i = 0; i < bnad->num_tx; i++) {
+ for (j = 0; j < bnad->num_txq_per_tx; j++) {
+ tcb = bnad->tx_info[i].tcb[j];
+ if (!tcb)
+ continue;
+ if (((u16) (*tcb->hw_consumer_index) !=
+ tcb->consumer_index) &&
+ (!test_and_set_bit(BNAD_TXQ_FREE_SENT,
+ &tcb->flags))) {
+ acked = bnad_free_txbufs(bnad, tcb);
+ bna_ib_ack(tcb->i_dbell, acked);
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+ }
+ }
+ }
+}
+
+static u32
+bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ struct net_device *netdev = bnad->netdev;
+ u32 sent;
+
+ if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
+ return 0;
+
+ sent = bnad_free_txbufs(bnad, tcb);
+ if (sent) {
+ if (netif_queue_stopped(netdev) &&
+ netif_carrier_ok(netdev) &&
+ BNA_QE_FREE_CNT(tcb, tcb->q_depth) >=
+ BNAD_NETIF_WAKE_THRESHOLD) {
+ netif_wake_queue(netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ }
+ bna_ib_ack(tcb->i_dbell, sent);
+ } else
+ bna_ib_ack(tcb->i_dbell, 0);
+
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+
+ return sent;
+}
+
+/* MSIX Tx Completion Handler */
+static irqreturn_t
+bnad_msix_tx(int irq, void *data)
+{
+ struct bna_tcb *tcb = (struct bna_tcb *)data;
+ struct bnad *bnad = tcb->bnad;
+
+ bnad_tx(bnad, tcb);
+
+ return IRQ_HANDLED;
+}
+
+static void
+bnad_reset_rcb(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+
+ rcb->producer_index = 0;
+ rcb->consumer_index = 0;
+
+ unmap_q->producer_index = 0;
+ unmap_q->consumer_index = 0;
+}
+
+static void
+bnad_free_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_unmap_q *unmap_q;
+ struct sk_buff *skb;
+
+ unmap_q = rcb->unmap_q;
+ while (BNA_QE_IN_USE_CNT(unmap_q, unmap_q->q_depth)) {
+ skb = unmap_q->unmap_array[unmap_q->consumer_index].skb;
+ BUG_ON(!(skb));
+ unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL;
+ pci_unmap_single(bnad->pcidev, pci_unmap_addr(&unmap_q->
+ unmap_array[unmap_q->consumer_index],
+ dma_addr), rcb->rxq->buffer_size +
+ NET_IP_ALIGN, PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(skb);
+ BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth);
+ BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth);
+ }
+
+ bnad_reset_rcb(bnad, rcb);
+}
+
+static void
+bnad_alloc_n_post_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ u16 to_alloc, alloced, unmap_prod, wi_range;
+ struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+ struct bnad_skb_unmap *unmap_array;
+ struct bna_rxq_entry *rxent;
+ struct sk_buff *skb;
+ dma_addr_t dma_addr;
+
+ alloced = 0;
+ to_alloc =
+ BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth);
+
+ unmap_array = unmap_q->unmap_array;
+ unmap_prod = unmap_q->producer_index;
+
+ BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent, wi_range);
+
+ while (to_alloc--) {
+ if (!wi_range) {
+ BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent,
+ wi_range);
+ }
+ skb = alloc_skb(rcb->rxq->buffer_size + NET_IP_ALIGN,
+ GFP_ATOMIC);
+ if (unlikely(!skb)) {
+ BNAD_UPDATE_CTR(bnad, rxbuf_alloc_failed);
+ goto finishing;
+ }
+ skb->dev = bnad->netdev;
+ skb_reserve(skb, NET_IP_ALIGN);
+ unmap_array[unmap_prod].skb = skb;
+ dma_addr = pci_map_single(bnad->pcidev, skb->data,
+ rcb->rxq->buffer_size, PCI_DMA_FROMDEVICE);
+ pci_unmap_addr_set(&unmap_array[unmap_prod], dma_addr,
+ dma_addr);
+ BNA_SET_DMA_ADDR(dma_addr, &rxent->host_addr);
+ BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth);
+
+ rxent++;
+ wi_range--;
+ alloced++;
+ }
+
+finishing:
+ if (likely(alloced)) {
+ unmap_q->producer_index = unmap_prod;
+ rcb->producer_index = unmap_prod;
+ smp_mb();
+ bna_rxq_prod_indx_doorbell(rcb);
+ }
+}
+
+/*
+ * Locking is required in the enable path
+ * because it is called from a napi poll
+ * context, where the bna_lock is not held
+ * unlike the IRQ context.
+ */
+static void
+bnad_enable_txrx_irqs(struct bnad *bnad)
+{
+ struct bna_tcb *tcb;
+ struct bna_ccb *ccb;
+ int i, j;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ for (i = 0; i < bnad->num_tx; i++) {
+ for (j = 0; j < bnad->num_txq_per_tx; j++) {
+ tcb = bnad->tx_info[i].tcb[j];
+ bna_ib_coalescing_timer_set(tcb->i_dbell,
+ tcb->txq->ib->ib_config.coalescing_timeo);
+ bna_ib_ack(tcb->i_dbell, 0);
+ }
+ }
+
+ for (i = 0; i < bnad->num_rx; i++) {
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ ccb = bnad->rx_info[i].rx_ctrl[j].ccb;
+ bnad_enable_rx_irq_unsafe(ccb);
+ }
+ }
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+static inline void
+bnad_refill_rxq(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+
+ if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
+ if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
+ >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
+ bnad_alloc_n_post_rxbufs(bnad, rcb);
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
+ }
+}
+
+static u32
+bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
+{
+ struct bna_cq_entry *cmpl, *next_cmpl;
+ struct bna_rcb *rcb = NULL;
+ unsigned int wi_range, packets = 0, wis = 0;
+ struct bnad_unmap_q *unmap_q;
+ struct sk_buff *skb;
+ u32 flags;
+ u32 qid0 = ccb->rcb[0]->rxq->rxq_id;
+ struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate;
+
+ prefetch(bnad->netdev);
+ BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl,
+ wi_range);
+ BUG_ON(!(wi_range <= ccb->q_depth));
+ while (cmpl->valid && packets < budget) {
+ packets++;
+ BNA_UPDATE_PKT_CNT(pkt_rt, ntohs(cmpl->length));
+
+ if (qid0 == cmpl->rxq_id)
+ rcb = ccb->rcb[0];
+ else
+ rcb = ccb->rcb[1];
+
+ unmap_q = rcb->unmap_q;
+
+ skb = unmap_q->unmap_array[unmap_q->consumer_index].skb;
+ BUG_ON(!(skb));
+ unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL;
+ pci_unmap_single(bnad->pcidev,
+ pci_unmap_addr(&unmap_q->
+ unmap_array[unmap_q->
+ consumer_index],
+ dma_addr),
+ rcb->rxq->buffer_size,
+ PCI_DMA_FROMDEVICE);
+ BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth);
+
+ /* Should be more efficient ? Performance ? */
+ BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth);
+
+ wis++;
+ if (likely(--wi_range))
+ next_cmpl = cmpl + 1;
+ else {
+ BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
+ wis = 0;
+ BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt,
+ next_cmpl, wi_range);
+ BUG_ON(!(wi_range <= ccb->q_depth));
+ }
+ prefetch(next_cmpl);
+
+ flags = ntohl(cmpl->flags);
+ if (unlikely
+ (flags &
+ (BNA_CQ_EF_MAC_ERROR | BNA_CQ_EF_FCS_ERROR |
+ BNA_CQ_EF_TOO_LONG))) {
+ dev_kfree_skb_any(skb);
+ rcb->rxq->rx_packets_with_error++;
+ goto next;
+ }
+
+ skb_put(skb, ntohs(cmpl->length));
+ if (likely
+ (bnad->rx_csum &&
+ (((flags & BNA_CQ_EF_IPV4) &&
+ (flags & BNA_CQ_EF_L3_CKSUM_OK)) ||
+ (flags & BNA_CQ_EF_IPV6)) &&
+ (flags & (BNA_CQ_EF_TCP | BNA_CQ_EF_UDP)) &&
+ (flags & BNA_CQ_EF_L4_CKSUM_OK)))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ skb_checksum_none_assert(skb);
+
+ rcb->rxq->rx_packets++;
+ rcb->rxq->rx_bytes += skb->len;
+ skb->protocol = eth_type_trans(skb, bnad->netdev);
+
+ if (bnad->vlan_grp && (flags & BNA_CQ_EF_VLAN)) {
+ struct bnad_rx_ctrl *rx_ctrl =
+ (struct bnad_rx_ctrl *)ccb->ctrl;
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY)
+ vlan_gro_receive(&rx_ctrl->napi, bnad->vlan_grp,
+ ntohs(cmpl->vlan_tag), skb);
+ else
+ vlan_hwaccel_receive_skb(skb,
+ bnad->vlan_grp,
+ ntohs(cmpl->vlan_tag));
+
+ } else { /* Not VLAN tagged/stripped */
+ struct bnad_rx_ctrl *rx_ctrl =
+ (struct bnad_rx_ctrl *)ccb->ctrl;
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY)
+ napi_gro_receive(&rx_ctrl->napi, skb);
+ else
+ netif_receive_skb(skb);
+ }
+
+next:
+ cmpl->valid = 0;
+ cmpl = next_cmpl;
+ }
+
+ BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
+
+ if (likely(ccb)) {
+ bna_ib_ack(ccb->i_dbell, packets);
+ bnad_refill_rxq(bnad, ccb->rcb[0]);
+ if (ccb->rcb[1])
+ bnad_refill_rxq(bnad, ccb->rcb[1]);
+ } else
+ bna_ib_ack(ccb->i_dbell, 0);
+
+ return packets;
+}
+
+static void
+bnad_disable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ bna_ib_coalescing_timer_set(ccb->i_dbell, 0);
+ bna_ib_ack(ccb->i_dbell, 0);
+}
+
+static void
+bnad_enable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags); /* Because of polling context */
+ bnad_enable_rx_irq_unsafe(ccb);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+static void
+bnad_netif_rx_schedule_poll(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
+ if (likely(napi_schedule_prep((&rx_ctrl->napi)))) {
+ bnad_disable_rx_irq(bnad, ccb);
+ __napi_schedule((&rx_ctrl->napi));
+ }
+ BNAD_UPDATE_CTR(bnad, netif_rx_schedule);
+}
+
+/* MSIX Rx Path Handler */
+static irqreturn_t
+bnad_msix_rx(int irq, void *data)
+{
+ struct bna_ccb *ccb = (struct bna_ccb *)data;
+ struct bnad *bnad = ccb->bnad;
+
+ bnad_netif_rx_schedule_poll(bnad, ccb);
+
+ return IRQ_HANDLED;
+}
+
+/* Interrupt handlers */
+
+/* Mbox Interrupt Handlers */
+static irqreturn_t
+bnad_msix_mbox_handler(int irq, void *data)
+{
+ u32 intr_status;
+ unsigned long flags;
+ struct net_device *netdev = data;
+ struct bnad *bnad;
+
+ bnad = netdev_priv(netdev);
+
+ /* BNA_ISR_GET(bnad); Inc Ref count */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ bna_intr_status_get(&bnad->bna, intr_status);
+
+ if (BNA_IS_MBOX_ERR_INTR(intr_status))
+ bna_mbox_handler(&bnad->bna, intr_status);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* BNAD_ISR_PUT(bnad); Dec Ref count */
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+bnad_isr(int irq, void *data)
+{
+ int i, j;
+ u32 intr_status;
+ unsigned long flags;
+ struct net_device *netdev = data;
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bnad_rx_info *rx_info;
+ struct bnad_rx_ctrl *rx_ctrl;
+
+ if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)))
+ return IRQ_NONE;
+
+ bna_intr_status_get(&bnad->bna, intr_status);
+
+ if (unlikely(!intr_status))
+ return IRQ_NONE;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ if (BNA_IS_MBOX_ERR_INTR(intr_status)) {
+ bna_mbox_handler(&bnad->bna, intr_status);
+ if (!BNA_IS_INTX_DATA_INTR(intr_status)) {
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ goto done;
+ }
+ }
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Process data interrupts */
+ for (i = 0; i < bnad->num_rx; i++) {
+ rx_info = &bnad->rx_info[i];
+ if (!rx_info->rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ rx_ctrl = &rx_info->rx_ctrl[j];
+ if (rx_ctrl->ccb)
+ bnad_netif_rx_schedule_poll(bnad,
+ rx_ctrl->ccb);
+ }
+ }
+done:
+ return IRQ_HANDLED;
+}
+
+/*
+ * Called in interrupt / callback context
+ * with bna_lock held, so cfg_flags access is OK
+ */
+static void
+bnad_enable_mbox_irq(struct bnad *bnad)
+{
+ int irq = BNAD_GET_MBOX_IRQ(bnad);
+
+ if (test_and_clear_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))
+ if (bnad->cfg_flags & BNAD_CF_MSIX)
+ enable_irq(irq);
+
+ BNAD_UPDATE_CTR(bnad, mbox_intr_enabled);
+}
+
+/*
+ * Called with bnad->bna_lock held b'cos of
+ * bnad->cfg_flags access.
+ */
+static void
+bnad_disable_mbox_irq(struct bnad *bnad)
+{
+ int irq = BNAD_GET_MBOX_IRQ(bnad);
+
+
+ if (!test_and_set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))
+ if (bnad->cfg_flags & BNAD_CF_MSIX)
+ disable_irq_nosync(irq);
+
+ BNAD_UPDATE_CTR(bnad, mbox_intr_disabled);
+}
+
+/* Control Path Handlers */
+
+/* Callbacks */
+void
+bnad_cb_device_enable_mbox_intr(struct bnad *bnad)
+{
+ bnad_enable_mbox_irq(bnad);
+}
+
+void
+bnad_cb_device_disable_mbox_intr(struct bnad *bnad)
+{
+ bnad_disable_mbox_irq(bnad);
+}
+
+void
+bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status)
+{
+ complete(&bnad->bnad_completions.ioc_comp);
+ bnad->bnad_completions.ioc_comp_status = status;
+}
+
+void
+bnad_cb_device_disabled(struct bnad *bnad, enum bna_cb_status status)
+{
+ complete(&bnad->bnad_completions.ioc_comp);
+ bnad->bnad_completions.ioc_comp_status = status;
+}
+
+static void
+bnad_cb_port_disabled(void *arg, enum bna_cb_status status)
+{
+ struct bnad *bnad = (struct bnad *)arg;
+
+ complete(&bnad->bnad_completions.port_comp);
+
+ netif_carrier_off(bnad->netdev);
+}
+
+void
+bnad_cb_port_link_status(struct bnad *bnad,
+ enum bna_link_status link_status)
+{
+ bool link_up = 0;
+
+ link_up = (link_status == BNA_LINK_UP) || (link_status == BNA_CEE_UP);
+
+ if (link_status == BNA_CEE_UP) {
+ set_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags);
+ BNAD_UPDATE_CTR(bnad, cee_up);
+ } else
+ clear_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags);
+
+ if (link_up) {
+ if (!netif_carrier_ok(bnad->netdev)) {
+ pr_warn("bna: %s link up\n",
+ bnad->netdev->name);
+ netif_carrier_on(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, link_toggle);
+ if (test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) {
+ /* Force an immediate Transmit Schedule */
+ pr_info("bna: %s TX_STARTED\n",
+ bnad->netdev->name);
+ netif_wake_queue(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ } else {
+ netif_stop_queue(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_stop);
+ }
+ }
+ } else {
+ if (netif_carrier_ok(bnad->netdev)) {
+ pr_warn("bna: %s link down\n",
+ bnad->netdev->name);
+ netif_carrier_off(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, link_toggle);
+ }
+ }
+}
+
+static void
+bnad_cb_tx_disabled(void *arg, struct bna_tx *tx,
+ enum bna_cb_status status)
+{
+ struct bnad *bnad = (struct bnad *)arg;
+
+ complete(&bnad->bnad_completions.tx_comp);
+}
+
+static void
+bnad_cb_tcb_setup(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ struct bnad_tx_info *tx_info =
+ (struct bnad_tx_info *)tcb->txq->tx->priv;
+ struct bnad_unmap_q *unmap_q = tcb->unmap_q;
+
+ tx_info->tcb[tcb->id] = tcb;
+ unmap_q->producer_index = 0;
+ unmap_q->consumer_index = 0;
+ unmap_q->q_depth = BNAD_TX_UNMAPQ_DEPTH;
+}
+
+static void
+bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ struct bnad_tx_info *tx_info =
+ (struct bnad_tx_info *)tcb->txq->tx->priv;
+
+ tx_info->tcb[tcb->id] = NULL;
+}
+
+static void
+bnad_cb_rcb_setup(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+
+ unmap_q->producer_index = 0;
+ unmap_q->consumer_index = 0;
+ unmap_q->q_depth = BNAD_RX_UNMAPQ_DEPTH;
+}
+
+static void
+bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ struct bnad_rx_info *rx_info =
+ (struct bnad_rx_info *)ccb->cq->rx->priv;
+
+ rx_info->rx_ctrl[ccb->id].ccb = ccb;
+ ccb->ctrl = &rx_info->rx_ctrl[ccb->id];
+}
+
+static void
+bnad_cb_ccb_destroy(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ struct bnad_rx_info *rx_info =
+ (struct bnad_rx_info *)ccb->cq->rx->priv;
+
+ rx_info->rx_ctrl[ccb->id].ccb = NULL;
+}
+
+static void
+bnad_cb_tx_stall(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ struct bnad_tx_info *tx_info =
+ (struct bnad_tx_info *)tcb->txq->tx->priv;
+
+ if (tx_info != &bnad->tx_info[0])
+ return;
+
+ clear_bit(BNAD_RF_TX_STARTED, &bnad->run_flags);
+ netif_stop_queue(bnad->netdev);
+ pr_info("bna: %s TX_STOPPED\n", bnad->netdev->name);
+}
+
+static void
+bnad_cb_tx_resume(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ if (test_and_set_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))
+ return;
+
+ if (netif_carrier_ok(bnad->netdev)) {
+ pr_info("bna: %s TX_STARTED\n", bnad->netdev->name);
+ netif_wake_queue(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ }
+}
+
+static void
+bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ struct bnad_unmap_q *unmap_q;
+
+ if (!tcb || (!tcb->unmap_q))
+ return;
+
+ unmap_q = tcb->unmap_q;
+ if (!unmap_q->unmap_array)
+ return;
+
+ if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
+ return;
+
+ bnad_free_all_txbufs(bnad, tcb);
+
+ unmap_q->producer_index = 0;
+ unmap_q->consumer_index = 0;
+
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+}
+
+static void
+bnad_cb_rx_cleanup(struct bnad *bnad,
+ struct bna_ccb *ccb)
+{
+ bnad_cq_cmpl_init(bnad, ccb);
+
+ bnad_free_rxbufs(bnad, ccb->rcb[0]);
+ clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags);
+
+ if (ccb->rcb[1]) {
+ bnad_free_rxbufs(bnad, ccb->rcb[1]);
+ clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[1]->flags);
+ }
+}
+
+static void
+bnad_cb_rx_post(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+
+ set_bit(BNAD_RXQ_STARTED, &rcb->flags);
+
+ /* Now allocate & post buffers for this RCB */
+ /* !!Allocation in callback context */
+ if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
+ if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
+ >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
+ bnad_alloc_n_post_rxbufs(bnad, rcb);
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
+ }
+}
+
+static void
+bnad_cb_rx_disabled(void *arg, struct bna_rx *rx,
+ enum bna_cb_status status)
+{
+ struct bnad *bnad = (struct bnad *)arg;
+
+ complete(&bnad->bnad_completions.rx_comp);
+}
+
+static void
+bnad_cb_rx_mcast_add(struct bnad *bnad, struct bna_rx *rx,
+ enum bna_cb_status status)
+{
+ bnad->bnad_completions.mcast_comp_status = status;
+ complete(&bnad->bnad_completions.mcast_comp);
+}
+
+void
+bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status,
+ struct bna_stats *stats)
+{
+ if (status == BNA_CB_SUCCESS)
+ BNAD_UPDATE_CTR(bnad, hw_stats_updates);
+
+ if (!netif_running(bnad->netdev) ||
+ !test_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags))
+ return;
+
+ mod_timer(&bnad->stats_timer,
+ jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ));
+}
+
+/* Resource allocation, free functions */
+
+static void
+bnad_mem_free(struct bnad *bnad,
+ struct bna_mem_info *mem_info)
+{
+ int i;
+ dma_addr_t dma_pa;
+
+ if (mem_info->mdl == NULL)
+ return;
+
+ for (i = 0; i < mem_info->num; i++) {
+ if (mem_info->mdl[i].kva != NULL) {
+ if (mem_info->mem_type == BNA_MEM_T_DMA) {
+ BNA_GET_DMA_ADDR(&(mem_info->mdl[i].dma),
+ dma_pa);
+ pci_free_consistent(bnad->pcidev,
+ mem_info->mdl[i].len,
+ mem_info->mdl[i].kva, dma_pa);
+ } else
+ kfree(mem_info->mdl[i].kva);
+ }
+ }
+ kfree(mem_info->mdl);
+ mem_info->mdl = NULL;
+}
+
+static int
+bnad_mem_alloc(struct bnad *bnad,
+ struct bna_mem_info *mem_info)
+{
+ int i;
+ dma_addr_t dma_pa;
+
+ if ((mem_info->num == 0) || (mem_info->len == 0)) {
+ mem_info->mdl = NULL;
+ return 0;
+ }
+
+ mem_info->mdl = kcalloc(mem_info->num, sizeof(struct bna_mem_descr),
+ GFP_KERNEL);
+ if (mem_info->mdl == NULL)
+ return -ENOMEM;
+
+ if (mem_info->mem_type == BNA_MEM_T_DMA) {
+ for (i = 0; i < mem_info->num; i++) {
+ mem_info->mdl[i].len = mem_info->len;
+ mem_info->mdl[i].kva =
+ pci_alloc_consistent(bnad->pcidev,
+ mem_info->len, &dma_pa);
+
+ if (mem_info->mdl[i].kva == NULL)
+ goto err_return;
+
+ BNA_SET_DMA_ADDR(dma_pa,
+ &(mem_info->mdl[i].dma));
+ }
+ } else {
+ for (i = 0; i < mem_info->num; i++) {
+ mem_info->mdl[i].len = mem_info->len;
+ mem_info->mdl[i].kva = kzalloc(mem_info->len,
+ GFP_KERNEL);
+ if (mem_info->mdl[i].kva == NULL)
+ goto err_return;
+ }
+ }
+
+ return 0;
+
+err_return:
+ bnad_mem_free(bnad, mem_info);
+ return -ENOMEM;
+}
+
+/* Free IRQ for Mailbox */
+static void
+bnad_mbox_irq_free(struct bnad *bnad,
+ struct bna_intr_info *intr_info)
+{
+ int irq;
+ unsigned long flags;
+
+ if (intr_info->idl == NULL)
+ return;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bnad_disable_mbox_irq(bnad);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ irq = BNAD_GET_MBOX_IRQ(bnad);
+ free_irq(irq, bnad->netdev);
+
+ kfree(intr_info->idl);
+}
+
+/*
+ * Allocates IRQ for Mailbox, but keep it disabled
+ * This will be enabled once we get the mbox enable callback
+ * from bna
+ */
+static int
+bnad_mbox_irq_alloc(struct bnad *bnad,
+ struct bna_intr_info *intr_info)
+{
+ int err;
+ unsigned long flags;
+ u32 irq;
+ irq_handler_t irq_handler;
+
+ /* Mbox should use only 1 vector */
+
+ intr_info->idl = kzalloc(sizeof(*(intr_info->idl)), GFP_KERNEL);
+ if (!intr_info->idl)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (bnad->cfg_flags & BNAD_CF_MSIX) {
+ irq_handler = (irq_handler_t)bnad_msix_mbox_handler;
+ irq = bnad->msix_table[bnad->msix_num - 1].vector;
+ flags = 0;
+ intr_info->intr_type = BNA_INTR_T_MSIX;
+ intr_info->idl[0].vector = bnad->msix_num - 1;
+ } else {
+ irq_handler = (irq_handler_t)bnad_isr;
+ irq = bnad->pcidev->irq;
+ flags = IRQF_SHARED;
+ intr_info->intr_type = BNA_INTR_T_INTX;
+ /* intr_info->idl.vector = 0 ? */
+ }
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME);
+
+ /*
+ * Set the Mbox IRQ disable flag, so that the IRQ handler
+ * called from request_irq() for SHARED IRQs do not execute
+ */
+ set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags);
+
+ err = request_irq(irq, irq_handler, flags,
+ bnad->mbox_irq_name, bnad->netdev);
+
+ if (err) {
+ kfree(intr_info->idl);
+ intr_info->idl = NULL;
+ return err;
+ }
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ if (bnad->cfg_flags & BNAD_CF_MSIX)
+ disable_irq_nosync(irq);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ return 0;
+}
+
+static void
+bnad_txrx_irq_free(struct bnad *bnad, struct bna_intr_info *intr_info)
+{
+ kfree(intr_info->idl);
+ intr_info->idl = NULL;
+}
+
+/* Allocates Interrupt Descriptor List for MSIX/INT-X vectors */
+static int
+bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src,
+ uint txrx_id, struct bna_intr_info *intr_info)
+{
+ int i, vector_start = 0;
+ u32 cfg_flags;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ cfg_flags = bnad->cfg_flags;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ if (cfg_flags & BNAD_CF_MSIX) {
+ intr_info->intr_type = BNA_INTR_T_MSIX;
+ intr_info->idl = kcalloc(intr_info->num,
+ sizeof(struct bna_intr_descr),
+ GFP_KERNEL);
+ if (!intr_info->idl)
+ return -ENOMEM;
+
+ switch (src) {
+ case BNAD_INTR_TX:
+ vector_start = txrx_id;
+ break;
+
+ case BNAD_INTR_RX:
+ vector_start = bnad->num_tx * bnad->num_txq_per_tx +
+ txrx_id;
+ break;
+
+ default:
+ BUG();
+ }
+
+ for (i = 0; i < intr_info->num; i++)
+ intr_info->idl[i].vector = vector_start + i;
+ } else {
+ intr_info->intr_type = BNA_INTR_T_INTX;
+ intr_info->num = 1;
+ intr_info->idl = kcalloc(intr_info->num,
+ sizeof(struct bna_intr_descr),
+ GFP_KERNEL);
+ if (!intr_info->idl)
+ return -ENOMEM;
+
+ switch (src) {
+ case BNAD_INTR_TX:
+ intr_info->idl[0].vector = 0x1; /* Bit mask : Tx IB */
+ break;
+
+ case BNAD_INTR_RX:
+ intr_info->idl[0].vector = 0x2; /* Bit mask : Rx IB */
+ break;
+ }
+ }
+ return 0;
+}
+
+/**
+ * NOTE: Should be called for MSIX only
+ * Unregisters Tx MSIX vector(s) from the kernel
+ */
+static void
+bnad_tx_msix_unregister(struct bnad *bnad, struct bnad_tx_info *tx_info,
+ int num_txqs)
+{
+ int i;
+ int vector_num;
+
+ for (i = 0; i < num_txqs; i++) {
+ if (tx_info->tcb[i] == NULL)
+ continue;
+
+ vector_num = tx_info->tcb[i]->intr_vector;
+ free_irq(bnad->msix_table[vector_num].vector, tx_info->tcb[i]);
+ }
+}
+
+/**
+ * NOTE: Should be called for MSIX only
+ * Registers Tx MSIX vector(s) and ISR(s), cookie with the kernel
+ */
+static int
+bnad_tx_msix_register(struct bnad *bnad, struct bnad_tx_info *tx_info,
+ uint tx_id, int num_txqs)
+{
+ int i;
+ int err;
+ int vector_num;
+
+ for (i = 0; i < num_txqs; i++) {
+ vector_num = tx_info->tcb[i]->intr_vector;
+ sprintf(tx_info->tcb[i]->name, "%s TXQ %d", bnad->netdev->name,
+ tx_id + tx_info->tcb[i]->id);
+ err = request_irq(bnad->msix_table[vector_num].vector,
+ (irq_handler_t)bnad_msix_tx, 0,
+ tx_info->tcb[i]->name,
+ tx_info->tcb[i]);
+ if (err)
+ goto err_return;
+ }
+
+ return 0;
+
+err_return:
+ if (i > 0)
+ bnad_tx_msix_unregister(bnad, tx_info, (i - 1));
+ return -1;
+}
+
+/**
+ * NOTE: Should be called for MSIX only
+ * Unregisters Rx MSIX vector(s) from the kernel
+ */
+static void
+bnad_rx_msix_unregister(struct bnad *bnad, struct bnad_rx_info *rx_info,
+ int num_rxps)
+{
+ int i;
+ int vector_num;
+
+ for (i = 0; i < num_rxps; i++) {
+ if (rx_info->rx_ctrl[i].ccb == NULL)
+ continue;
+
+ vector_num = rx_info->rx_ctrl[i].ccb->intr_vector;
+ free_irq(bnad->msix_table[vector_num].vector,
+ rx_info->rx_ctrl[i].ccb);
+ }
+}
+
+/**
+ * NOTE: Should be called for MSIX only
+ * Registers Tx MSIX vector(s) and ISR(s), cookie with the kernel
+ */
+static int
+bnad_rx_msix_register(struct bnad *bnad, struct bnad_rx_info *rx_info,
+ uint rx_id, int num_rxps)
+{
+ int i;
+ int err;
+ int vector_num;
+
+ for (i = 0; i < num_rxps; i++) {
+ vector_num = rx_info->rx_ctrl[i].ccb->intr_vector;
+ sprintf(rx_info->rx_ctrl[i].ccb->name, "%s CQ %d",
+ bnad->netdev->name,
+ rx_id + rx_info->rx_ctrl[i].ccb->id);
+ err = request_irq(bnad->msix_table[vector_num].vector,
+ (irq_handler_t)bnad_msix_rx, 0,
+ rx_info->rx_ctrl[i].ccb->name,
+ rx_info->rx_ctrl[i].ccb);
+ if (err)
+ goto err_return;
+ }
+
+ return 0;
+
+err_return:
+ if (i > 0)
+ bnad_rx_msix_unregister(bnad, rx_info, (i - 1));
+ return -1;
+}
+
+/* Free Tx object Resources */
+static void
+bnad_tx_res_free(struct bnad *bnad, struct bna_res_info *res_info)
+{
+ int i;
+
+ for (i = 0; i < BNA_TX_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
+ else if (res_info[i].res_type == BNA_RES_T_INTR)
+ bnad_txrx_irq_free(bnad, &res_info[i].res_u.intr_info);
+ }
+}
+
+/* Allocates memory and interrupt resources for Tx object */
+static int
+bnad_tx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
+ uint tx_id)
+{
+ int i, err = 0;
+
+ for (i = 0; i < BNA_TX_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ err = bnad_mem_alloc(bnad,
+ &res_info[i].res_u.mem_info);
+ else if (res_info[i].res_type == BNA_RES_T_INTR)
+ err = bnad_txrx_irq_alloc(bnad, BNAD_INTR_TX, tx_id,
+ &res_info[i].res_u.intr_info);
+ if (err)
+ goto err_return;
+ }
+ return 0;
+
+err_return:
+ bnad_tx_res_free(bnad, res_info);
+ return err;
+}
+
+/* Free Rx object Resources */
+static void
+bnad_rx_res_free(struct bnad *bnad, struct bna_res_info *res_info)
+{
+ int i;
+
+ for (i = 0; i < BNA_RX_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
+ else if (res_info[i].res_type == BNA_RES_T_INTR)
+ bnad_txrx_irq_free(bnad, &res_info[i].res_u.intr_info);
+ }
+}
+
+/* Allocates memory and interrupt resources for Rx object */
+static int
+bnad_rx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
+ uint rx_id)
+{
+ int i, err = 0;
+
+ /* All memory needs to be allocated before setup_ccbs */
+ for (i = 0; i < BNA_RX_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ err = bnad_mem_alloc(bnad,
+ &res_info[i].res_u.mem_info);
+ else if (res_info[i].res_type == BNA_RES_T_INTR)
+ err = bnad_txrx_irq_alloc(bnad, BNAD_INTR_RX, rx_id,
+ &res_info[i].res_u.intr_info);
+ if (err)
+ goto err_return;
+ }
+ return 0;
+
+err_return:
+ bnad_rx_res_free(bnad, res_info);
+ return err;
+}
+
+/* Timer callbacks */
+/* a) IOC timer */
+static void
+bnad_ioc_timeout(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bfa_nw_ioc_timeout((void *) &bnad->bna.device.ioc);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+static void
+bnad_ioc_hb_check(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bfa_nw_ioc_hb_check((void *) &bnad->bna.device.ioc);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+static void
+bnad_ioc_sem_timeout(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bfa_nw_ioc_sem_timeout((void *) &bnad->bna.device.ioc);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+/*
+ * All timer routines use bnad->bna_lock to protect against
+ * the following race, which may occur in case of no locking:
+ * Time CPU m CPU n
+ * 0 1 = test_bit
+ * 1 clear_bit
+ * 2 del_timer_sync
+ * 3 mod_timer
+ */
+
+/* b) Dynamic Interrupt Moderation Timer */
+static void
+bnad_dim_timeout(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ struct bnad_rx_info *rx_info;
+ struct bnad_rx_ctrl *rx_ctrl;
+ int i, j;
+ unsigned long flags;
+
+ if (!netif_carrier_ok(bnad->netdev))
+ return;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ for (i = 0; i < bnad->num_rx; i++) {
+ rx_info = &bnad->rx_info[i];
+ if (!rx_info->rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ rx_ctrl = &rx_info->rx_ctrl[j];
+ if (!rx_ctrl->ccb)
+ continue;
+ bna_rx_dim_update(rx_ctrl->ccb);
+ }
+ }
+
+ /* Check for BNAD_CF_DIM_ENABLED, does not eleminate a race */
+ if (test_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags))
+ mod_timer(&bnad->dim_timer,
+ jiffies + msecs_to_jiffies(BNAD_DIM_TIMER_FREQ));
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+/* c) Statistics Timer */
+static void
+bnad_stats_timeout(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ unsigned long flags;
+
+ if (!netif_running(bnad->netdev) ||
+ !test_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags))
+ return;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_stats_get(&bnad->bna);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+/*
+ * Set up timer for DIM
+ * Called with bnad->bna_lock held
+ */
+void
+bnad_dim_timer_start(struct bnad *bnad)
+{
+ if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED &&
+ !test_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags)) {
+ setup_timer(&bnad->dim_timer, bnad_dim_timeout,
+ (unsigned long)bnad);
+ set_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags);
+ mod_timer(&bnad->dim_timer,
+ jiffies + msecs_to_jiffies(BNAD_DIM_TIMER_FREQ));
+ }
+}
+
+/*
+ * Set up timer for statistics
+ * Called with mutex_lock(&bnad->conf_mutex) held
+ */
+static void
+bnad_stats_timer_start(struct bnad *bnad)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (!test_and_set_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) {
+ setup_timer(&bnad->stats_timer, bnad_stats_timeout,
+ (unsigned long)bnad);
+ mod_timer(&bnad->stats_timer,
+ jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ));
+ }
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+/*
+ * Stops the stats timer
+ * Called with mutex_lock(&bnad->conf_mutex) held
+ */
+static void
+bnad_stats_timer_stop(struct bnad *bnad)
+{
+ int to_del = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (test_and_clear_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags))
+ to_del = 1;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ if (to_del)
+ del_timer_sync(&bnad->stats_timer);
+}
+
+/* Utilities */
+
+static void
+bnad_netdev_mc_list_get(struct net_device *netdev, u8 *mc_list)
+{
+ int i = 1; /* Index 0 has broadcast address */
+ struct netdev_hw_addr *mc_addr;
+
+ netdev_for_each_mc_addr(mc_addr, netdev) {
+ memcpy(&mc_list[i * ETH_ALEN], &mc_addr->addr[0],
+ ETH_ALEN);
+ i++;
+ }
+}
+
+static int
+bnad_napi_poll_rx(struct napi_struct *napi, int budget)
+{
+ struct bnad_rx_ctrl *rx_ctrl =
+ container_of(napi, struct bnad_rx_ctrl, napi);
+ struct bna_ccb *ccb;
+ struct bnad *bnad;
+ int rcvd = 0;
+
+ ccb = rx_ctrl->ccb;
+
+ bnad = ccb->bnad;
+
+ if (!netif_carrier_ok(bnad->netdev))
+ goto poll_exit;
+
+ rcvd = bnad_poll_cq(bnad, ccb, budget);
+ if (rcvd == budget)
+ return rcvd;
+
+poll_exit:
+ napi_complete((napi));
+
+ BNAD_UPDATE_CTR(bnad, netif_rx_complete);
+
+ bnad_enable_rx_irq(bnad, ccb);
+ return rcvd;
+}
+
+static int
+bnad_napi_poll_txrx(struct napi_struct *napi, int budget)
+{
+ struct bnad_rx_ctrl *rx_ctrl =
+ container_of(napi, struct bnad_rx_ctrl, napi);
+ struct bna_ccb *ccb;
+ struct bnad *bnad;
+ int rcvd = 0;
+ int i, j;
+
+ ccb = rx_ctrl->ccb;
+
+ bnad = ccb->bnad;
+
+ if (!netif_carrier_ok(bnad->netdev))
+ goto poll_exit;
+
+ /* Handle Tx Completions, if any */
+ for (i = 0; i < bnad->num_tx; i++) {
+ for (j = 0; j < bnad->num_txq_per_tx; j++)
+ bnad_tx(bnad, bnad->tx_info[i].tcb[j]);
+ }
+
+ /* Handle Rx Completions */
+ rcvd = bnad_poll_cq(bnad, ccb, budget);
+ if (rcvd == budget)
+ return rcvd;
+poll_exit:
+ napi_complete((napi));
+
+ BNAD_UPDATE_CTR(bnad, netif_rx_complete);
+
+ bnad_enable_txrx_irqs(bnad);
+ return rcvd;
+}
+
+static void
+bnad_napi_enable(struct bnad *bnad, u32 rx_id)
+{
+ int (*napi_poll) (struct napi_struct *, int);
+ struct bnad_rx_ctrl *rx_ctrl;
+ int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (bnad->cfg_flags & BNAD_CF_MSIX)
+ napi_poll = bnad_napi_poll_rx;
+ else
+ napi_poll = bnad_napi_poll_txrx;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Initialize & enable NAPI */
+ for (i = 0; i < bnad->num_rxp_per_rx; i++) {
+ rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i];
+ netif_napi_add(bnad->netdev, &rx_ctrl->napi,
+ napi_poll, 64);
+ napi_enable(&rx_ctrl->napi);
+ }
+}
+
+static void
+bnad_napi_disable(struct bnad *bnad, u32 rx_id)
+{
+ int i;
+
+ /* First disable and then clean up */
+ for (i = 0; i < bnad->num_rxp_per_rx; i++) {
+ napi_disable(&bnad->rx_info[rx_id].rx_ctrl[i].napi);
+ netif_napi_del(&bnad->rx_info[rx_id].rx_ctrl[i].napi);
+ }
+}
+
+/* Should be held with conf_lock held */
+void
+bnad_cleanup_tx(struct bnad *bnad, uint tx_id)
+{
+ struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id];
+ struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0];
+ unsigned long flags;
+
+ if (!tx_info->tx)
+ return;
+
+ init_completion(&bnad->bnad_completions.tx_comp);
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_tx_disable(tx_info->tx, BNA_HARD_CLEANUP, bnad_cb_tx_disabled);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ wait_for_completion(&bnad->bnad_completions.tx_comp);
+
+ if (tx_info->tcb[0]->intr_type == BNA_INTR_T_MSIX)
+ bnad_tx_msix_unregister(bnad, tx_info,
+ bnad->num_txq_per_tx);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_tx_destroy(tx_info->tx);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ tx_info->tx = NULL;
+
+ if (0 == tx_id)
+ tasklet_kill(&bnad->tx_free_tasklet);
+
+ bnad_tx_res_free(bnad, res_info);
+}
+
+/* Should be held with conf_lock held */
+int
+bnad_setup_tx(struct bnad *bnad, uint tx_id)
+{
+ int err;
+ struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id];
+ struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0];
+ struct bna_intr_info *intr_info =
+ &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info;
+ struct bna_tx_config *tx_config = &bnad->tx_config[tx_id];
+ struct bna_tx_event_cbfn tx_cbfn;
+ struct bna_tx *tx;
+ unsigned long flags;
+
+ /* Initialize the Tx object configuration */
+ tx_config->num_txq = bnad->num_txq_per_tx;
+ tx_config->txq_depth = bnad->txq_depth;
+ tx_config->tx_type = BNA_TX_T_REGULAR;
+
+ /* Initialize the tx event handlers */
+ tx_cbfn.tcb_setup_cbfn = bnad_cb_tcb_setup;
+ tx_cbfn.tcb_destroy_cbfn = bnad_cb_tcb_destroy;
+ tx_cbfn.tx_stall_cbfn = bnad_cb_tx_stall;
+ tx_cbfn.tx_resume_cbfn = bnad_cb_tx_resume;
+ tx_cbfn.tx_cleanup_cbfn = bnad_cb_tx_cleanup;
+
+ /* Get BNA's resource requirement for one tx object */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_tx_res_req(bnad->num_txq_per_tx,
+ bnad->txq_depth, res_info);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Fill Unmap Q memory requirements */
+ BNAD_FILL_UNMAPQ_MEM_REQ(
+ &res_info[BNA_TX_RES_MEM_T_UNMAPQ],
+ bnad->num_txq_per_tx,
+ BNAD_TX_UNMAPQ_DEPTH);
+
+ /* Allocate resources */
+ err = bnad_tx_res_alloc(bnad, res_info, tx_id);
+ if (err)
+ return err;
+
+ /* Ask BNA to create one Tx object, supplying required resources */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ tx = bna_tx_create(&bnad->bna, bnad, tx_config, &tx_cbfn, res_info,
+ tx_info);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ if (!tx)
+ goto err_return;
+ tx_info->tx = tx;
+
+ /* Register ISR for the Tx object */
+ if (intr_info->intr_type == BNA_INTR_T_MSIX) {
+ err = bnad_tx_msix_register(bnad, tx_info,
+ tx_id, bnad->num_txq_per_tx);
+ if (err)
+ goto err_return;
+ }
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_tx_enable(tx);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ return 0;
+
+err_return:
+ bnad_tx_res_free(bnad, res_info);
+ return err;
+}
+
+/* Setup the rx config for bna_rx_create */
+/* bnad decides the configuration */
+static void
+bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)
+{
+ rx_config->rx_type = BNA_RX_T_REGULAR;
+ rx_config->num_paths = bnad->num_rxp_per_rx;
+
+ if (bnad->num_rxp_per_rx > 1) {
+ rx_config->rss_status = BNA_STATUS_T_ENABLED;
+ rx_config->rss_config.hash_type =
+ (BFI_RSS_T_V4_TCP |
+ BFI_RSS_T_V6_TCP |
+ BFI_RSS_T_V4_IP |
+ BFI_RSS_T_V6_IP);
+ rx_config->rss_config.hash_mask =
+ bnad->num_rxp_per_rx - 1;
+ get_random_bytes(rx_config->rss_config.toeplitz_hash_key,
+ sizeof(rx_config->rss_config.toeplitz_hash_key));
+ } else {
+ rx_config->rss_status = BNA_STATUS_T_DISABLED;
+ memset(&rx_config->rss_config, 0,
+ sizeof(rx_config->rss_config));
+ }
+ rx_config->rxp_type = BNA_RXP_SLR;
+ rx_config->q_depth = bnad->rxq_depth;
+
+ rx_config->small_buff_size = BFI_SMALL_RXBUF_SIZE;
+
+ rx_config->vlan_strip_status = BNA_STATUS_T_ENABLED;
+}
+
+/* Called with mutex_lock(&bnad->conf_mutex) held */
+void
+bnad_cleanup_rx(struct bnad *bnad, uint rx_id)
+{
+ struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
+ struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
+ struct bna_res_info *res_info = &bnad->rx_res_info[rx_id].res_info[0];
+ unsigned long flags;
+ int dim_timer_del = 0;
+
+ if (!rx_info->rx)
+ return;
+
+ if (0 == rx_id) {
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ dim_timer_del = bnad_dim_timer_running(bnad);
+ if (dim_timer_del)
+ clear_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ if (dim_timer_del)
+ del_timer_sync(&bnad->dim_timer);
+ }
+
+ bnad_napi_disable(bnad, rx_id);
+
+ init_completion(&bnad->bnad_completions.rx_comp);
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_disable(rx_info->rx, BNA_HARD_CLEANUP, bnad_cb_rx_disabled);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ wait_for_completion(&bnad->bnad_completions.rx_comp);
+
+ if (rx_info->rx_ctrl[0].ccb->intr_type == BNA_INTR_T_MSIX)
+ bnad_rx_msix_unregister(bnad, rx_info, rx_config->num_paths);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_destroy(rx_info->rx);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ rx_info->rx = NULL;
+
+ bnad_rx_res_free(bnad, res_info);
+}
+
+/* Called with mutex_lock(&bnad->conf_mutex) held */
+int
+bnad_setup_rx(struct bnad *bnad, uint rx_id)
+{
+ int err;
+ struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
+ struct bna_res_info *res_info = &bnad->rx_res_info[rx_id].res_info[0];
+ struct bna_intr_info *intr_info =
+ &res_info[BNA_RX_RES_T_INTR].res_u.intr_info;
+ struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
+ struct bna_rx_event_cbfn rx_cbfn;
+ struct bna_rx *rx;
+ unsigned long flags;
+
+ /* Initialize the Rx object configuration */
+ bnad_init_rx_config(bnad, rx_config);
+
+ /* Initialize the Rx event handlers */
+ rx_cbfn.rcb_setup_cbfn = bnad_cb_rcb_setup;
+ rx_cbfn.rcb_destroy_cbfn = NULL;
+ rx_cbfn.ccb_setup_cbfn = bnad_cb_ccb_setup;
+ rx_cbfn.ccb_destroy_cbfn = bnad_cb_ccb_destroy;
+ rx_cbfn.rx_cleanup_cbfn = bnad_cb_rx_cleanup;
+ rx_cbfn.rx_post_cbfn = bnad_cb_rx_post;
+
+ /* Get BNA's resource requirement for one Rx object */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_res_req(rx_config, res_info);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Fill Unmap Q memory requirements */
+ BNAD_FILL_UNMAPQ_MEM_REQ(
+ &res_info[BNA_RX_RES_MEM_T_UNMAPQ],
+ rx_config->num_paths +
+ ((rx_config->rxp_type == BNA_RXP_SINGLE) ? 0 :
+ rx_config->num_paths), BNAD_RX_UNMAPQ_DEPTH);
+
+ /* Allocate resource */
+ err = bnad_rx_res_alloc(bnad, res_info, rx_id);
+ if (err)
+ return err;
+
+ /* Ask BNA to create one Rx object, supplying required resources */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ rx = bna_rx_create(&bnad->bna, bnad, rx_config, &rx_cbfn, res_info,
+ rx_info);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ if (!rx)
+ goto err_return;
+ rx_info->rx = rx;
+
+ /* Register ISR for the Rx object */
+ if (intr_info->intr_type == BNA_INTR_T_MSIX) {
+ err = bnad_rx_msix_register(bnad, rx_info, rx_id,
+ rx_config->num_paths);
+ if (err)
+ goto err_return;
+ }
+
+ /* Enable NAPI */
+ bnad_napi_enable(bnad, rx_id);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (0 == rx_id) {
+ /* Set up Dynamic Interrupt Moderation Vector */
+ if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED)
+ bna_rx_dim_reconfig(&bnad->bna, bna_napi_dim_vector);
+
+ /* Enable VLAN filtering only on the default Rx */
+ bna_rx_vlanfilter_enable(rx);
+
+ /* Start the DIM timer */
+ bnad_dim_timer_start(bnad);
+ }
+
+ bna_rx_enable(rx);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ return 0;
+
+err_return:
+ bnad_cleanup_rx(bnad, rx_id);
+ return err;
+}
+
+/* Called with conf_lock & bnad->bna_lock held */
+void
+bnad_tx_coalescing_timeo_set(struct bnad *bnad)
+{
+ struct bnad_tx_info *tx_info;
+
+ tx_info = &bnad->tx_info[0];
+ if (!tx_info->tx)
+ return;
+
+ bna_tx_coalescing_timeo_set(tx_info->tx, bnad->tx_coalescing_timeo);
+}
+
+/* Called with conf_lock & bnad->bna_lock held */
+void
+bnad_rx_coalescing_timeo_set(struct bnad *bnad)
+{
+ struct bnad_rx_info *rx_info;
+ int i;
+
+ for (i = 0; i < bnad->num_rx; i++) {
+ rx_info = &bnad->rx_info[i];
+ if (!rx_info->rx)
+ continue;
+ bna_rx_coalescing_timeo_set(rx_info->rx,
+ bnad->rx_coalescing_timeo);
+ }
+}
+
+/*
+ * Called with bnad->bna_lock held
+ */
+static int
+bnad_mac_addr_set_locked(struct bnad *bnad, u8 *mac_addr)
+{
+ int ret;
+
+ if (!is_valid_ether_addr(mac_addr))
+ return -EADDRNOTAVAIL;
+
+ /* If datapath is down, pretend everything went through */
+ if (!bnad->rx_info[0].rx)
+ return 0;
+
+ ret = bna_rx_ucast_set(bnad->rx_info[0].rx, mac_addr, NULL);
+ if (ret != BNA_CB_SUCCESS)
+ return -EADDRNOTAVAIL;
+
+ return 0;
+}
+
+/* Should be called with conf_lock held */
+static int
+bnad_enable_default_bcast(struct bnad *bnad)
+{
+ struct bnad_rx_info *rx_info = &bnad->rx_info[0];
+ int ret;
+ unsigned long flags;
+
+ init_completion(&bnad->bnad_completions.mcast_comp);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ ret = bna_rx_mcast_add(rx_info->rx, (u8 *)bnad_bcast_addr,
+ bnad_cb_rx_mcast_add);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ if (ret == BNA_CB_SUCCESS)
+ wait_for_completion(&bnad->bnad_completions.mcast_comp);
+ else
+ return -ENODEV;
+
+ if (bnad->bnad_completions.mcast_comp_status != BNA_CB_SUCCESS)
+ return -ENODEV;
+
+ return 0;
+}
+
+/* Statistics utilities */
+void
+bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
+{
+ int i, j;
+
+ for (i = 0; i < bnad->num_rx; i++) {
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ if (bnad->rx_info[i].rx_ctrl[j].ccb) {
+ stats->rx_packets += bnad->rx_info[i].
+ rx_ctrl[j].ccb->rcb[0]->rxq->rx_packets;
+ stats->rx_bytes += bnad->rx_info[i].
+ rx_ctrl[j].ccb->rcb[0]->rxq->rx_bytes;
+ if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->
+ rcb[1]->rxq) {
+ stats->rx_packets +=
+ bnad->rx_info[i].rx_ctrl[j].
+ ccb->rcb[1]->rxq->rx_packets;
+ stats->rx_bytes +=
+ bnad->rx_info[i].rx_ctrl[j].
+ ccb->rcb[1]->rxq->rx_bytes;
+ }
+ }
+ }
+ }
+ for (i = 0; i < bnad->num_tx; i++) {
+ for (j = 0; j < bnad->num_txq_per_tx; j++) {
+ if (bnad->tx_info[i].tcb[j]) {
+ stats->tx_packets +=
+ bnad->tx_info[i].tcb[j]->txq->tx_packets;
+ stats->tx_bytes +=
+ bnad->tx_info[i].tcb[j]->txq->tx_bytes;
+ }
+ }
+ }
+}
+
+/*
+ * Must be called with the bna_lock held.
+ */
+void
+bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
+{
+ struct bfi_ll_stats_mac *mac_stats;
+ u64 bmap;
+ int i;
+
+ mac_stats = &bnad->stats.bna_stats->hw_stats->mac_stats;
+ stats->rx_errors =
+ mac_stats->rx_fcs_error + mac_stats->rx_alignment_error +
+ mac_stats->rx_frame_length_error + mac_stats->rx_code_error +
+ mac_stats->rx_undersize;
+ stats->tx_errors = mac_stats->tx_fcs_error +
+ mac_stats->tx_undersize;
+ stats->rx_dropped = mac_stats->rx_drop;
+ stats->tx_dropped = mac_stats->tx_drop;
+ stats->multicast = mac_stats->rx_multicast;
+ stats->collisions = mac_stats->tx_total_collision;
+
+ stats->rx_length_errors = mac_stats->rx_frame_length_error;
+
+ /* receive ring buffer overflow ?? */
+
+ stats->rx_crc_errors = mac_stats->rx_fcs_error;
+ stats->rx_frame_errors = mac_stats->rx_alignment_error;
+ /* recv'r fifo overrun */
+ bmap = (u64)bnad->stats.bna_stats->rxf_bmap[0] |
+ ((u64)bnad->stats.bna_stats->rxf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+ if (bmap & 1) {
+ stats->rx_fifo_errors +=
+ bnad->stats.bna_stats->
+ hw_stats->rxf_stats[i].frame_drops;
+ break;
+ }
+ bmap >>= 1;
+ }
+}
+
+static void
+bnad_mbox_irq_sync(struct bnad *bnad)
+{
+ u32 irq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (bnad->cfg_flags & BNAD_CF_MSIX)
+ irq = bnad->msix_table[bnad->msix_num - 1].vector;
+ else
+ irq = bnad->pcidev->irq;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ synchronize_irq(irq);
+}
+
+/* Utility used by bnad_start_xmit, for doing TSO */
+static int
+bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb)
+{
+ int err;
+
+ /* SKB_GSO_TCPV4 and SKB_GSO_TCPV6 is defined since 2.6.18. */
+ BUG_ON(!(skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4 ||
+ skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6));
+ if (skb_header_cloned(skb)) {
+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+ if (err) {
+ BNAD_UPDATE_CTR(bnad, tso_err);
+ return err;
+ }
+ }
+
+ /*
+ * For TSO, the TCP checksum field is seeded with pseudo-header sum
+ * excluding the length field.
+ */
+ if (skb->protocol == htons(ETH_P_IP)) {
+ struct iphdr *iph = ip_hdr(skb);
+
+ /* Do we really need these? */
+ iph->tot_len = 0;
+ iph->check = 0;
+
+ tcp_hdr(skb)->check =
+ ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0,
+ IPPROTO_TCP, 0);
+ BNAD_UPDATE_CTR(bnad, tso4);
+ } else {
+ struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+
+ BUG_ON(!(skb->protocol == htons(ETH_P_IPV6)));
+ ipv6h->payload_len = 0;
+ tcp_hdr(skb)->check =
+ ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, 0,
+ IPPROTO_TCP, 0);
+ BNAD_UPDATE_CTR(bnad, tso6);
+ }
+
+ return 0;
+}
+
+/*
+ * Initialize Q numbers depending on Rx Paths
+ * Called with bnad->bna_lock held, because of cfg_flags
+ * access.
+ */
+static void
+bnad_q_num_init(struct bnad *bnad)
+{
+ int rxps;
+
+ rxps = min((uint)num_online_cpus(),
+ (uint)(BNAD_MAX_RXS * BNAD_MAX_RXPS_PER_RX));
+
+ if (!(bnad->cfg_flags & BNAD_CF_MSIX))
+ rxps = 1; /* INTx */
+
+ bnad->num_rx = 1;
+ bnad->num_tx = 1;
+ bnad->num_rxp_per_rx = rxps;
+ bnad->num_txq_per_tx = BNAD_TXQ_NUM;
+}
+
+/*
+ * Adjusts the Q numbers, given a number of msix vectors
+ * Give preference to RSS as opposed to Tx priority Queues,
+ * in such a case, just use 1 Tx Q
+ * Called with bnad->bna_lock held b'cos of cfg_flags access
+ */
+static void
+bnad_q_num_adjust(struct bnad *bnad, int msix_vectors)
+{
+ bnad->num_txq_per_tx = 1;
+ if ((msix_vectors >= (bnad->num_tx * bnad->num_txq_per_tx) +
+ bnad_rxqs_per_cq + BNAD_MAILBOX_MSIX_VECTORS) &&
+ (bnad->cfg_flags & BNAD_CF_MSIX)) {
+ bnad->num_rxp_per_rx = msix_vectors -
+ (bnad->num_tx * bnad->num_txq_per_tx) -
+ BNAD_MAILBOX_MSIX_VECTORS;
+ } else
+ bnad->num_rxp_per_rx = 1;
+}
+
+static void
+bnad_set_netdev_perm_addr(struct bnad *bnad)
+{
+ struct net_device *netdev = bnad->netdev;
+
+ memcpy(netdev->perm_addr, &bnad->perm_addr, netdev->addr_len);
+ if (is_zero_ether_addr(netdev->dev_addr))
+ memcpy(netdev->dev_addr, &bnad->perm_addr, netdev->addr_len);
+}
+
+/* Enable / disable device */
+static void
+bnad_device_disable(struct bnad *bnad)
+{
+ unsigned long flags;
+
+ init_completion(&bnad->bnad_completions.ioc_comp);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_device_disable(&bnad->bna.device, BNA_HARD_CLEANUP);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ wait_for_completion(&bnad->bnad_completions.ioc_comp);
+}
+
+static int
+bnad_device_enable(struct bnad *bnad)
+{
+ int err = 0;
+ unsigned long flags;
+
+ init_completion(&bnad->bnad_completions.ioc_comp);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_device_enable(&bnad->bna.device);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ wait_for_completion(&bnad->bnad_completions.ioc_comp);
+
+ if (bnad->bnad_completions.ioc_comp_status)
+ err = bnad->bnad_completions.ioc_comp_status;
+
+ return err;
+}
+
+/* Free BNA resources */
+static void
+bnad_res_free(struct bnad *bnad)
+{
+ int i;
+ struct bna_res_info *res_info = &bnad->res_info[0];
+
+ for (i = 0; i < BNA_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
+ else
+ bnad_mbox_irq_free(bnad, &res_info[i].res_u.intr_info);
+ }
+}
+
+/* Allocates memory and interrupt resources for BNA */
+static int
+bnad_res_alloc(struct bnad *bnad)
+{
+ int i, err;
+ struct bna_res_info *res_info = &bnad->res_info[0];
+
+ for (i = 0; i < BNA_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ err = bnad_mem_alloc(bnad, &res_info[i].res_u.mem_info);
+ else
+ err = bnad_mbox_irq_alloc(bnad,
+ &res_info[i].res_u.intr_info);
+ if (err)
+ goto err_return;
+ }
+ return 0;
+
+err_return:
+ bnad_res_free(bnad);
+ return err;
+}
+
+/* Interrupt enable / disable */
+static void
+bnad_enable_msix(struct bnad *bnad)
+{
+ int i, ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (!(bnad->cfg_flags & BNAD_CF_MSIX)) {
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ return;
+ }
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ if (bnad->msix_table)
+ return;
+
+ bnad->msix_table =
+ kcalloc(bnad->msix_num, sizeof(struct msix_entry), GFP_KERNEL);
+
+ if (!bnad->msix_table)
+ goto intx_mode;
+
+ for (i = 0; i < bnad->msix_num; i++)
+ bnad->msix_table[i].entry = i;
+
+ ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, bnad->msix_num);
+ if (ret > 0) {
+ /* Not enough MSI-X vectors. */
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ /* ret = #of vectors that we got */
+ bnad_q_num_adjust(bnad, ret);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx)
+ + (bnad->num_rx
+ * bnad->num_rxp_per_rx) +
+ BNAD_MAILBOX_MSIX_VECTORS;
+
+ /* Try once more with adjusted numbers */
+ /* If this fails, fall back to INTx */
+ ret = pci_enable_msix(bnad->pcidev, bnad->msix_table,
+ bnad->msix_num);
+ if (ret)
+ goto intx_mode;
+
+ } else if (ret < 0)
+ goto intx_mode;
+ return;
+
+intx_mode:
+
+ kfree(bnad->msix_table);
+ bnad->msix_table = NULL;
+ bnad->msix_num = 0;
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bnad->cfg_flags &= ~BNAD_CF_MSIX;
+ bnad_q_num_init(bnad);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+static void
+bnad_disable_msix(struct bnad *bnad)
+{
+ u32 cfg_flags;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ cfg_flags = bnad->cfg_flags;
+ if (bnad->cfg_flags & BNAD_CF_MSIX)
+ bnad->cfg_flags &= ~BNAD_CF_MSIX;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ if (cfg_flags & BNAD_CF_MSIX) {
+ pci_disable_msix(bnad->pcidev);
+ kfree(bnad->msix_table);
+ bnad->msix_table = NULL;
+ }
+}
+
+/* Netdev entry points */
+static int
+bnad_open(struct net_device *netdev)
+{
+ int err;
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bna_pause_config pause_config;
+ int mtu;
+ unsigned long flags;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ /* Tx */
+ err = bnad_setup_tx(bnad, 0);
+ if (err)
+ goto err_return;
+
+ /* Rx */
+ err = bnad_setup_rx(bnad, 0);
+ if (err)
+ goto cleanup_tx;
+
+ /* Port */
+ pause_config.tx_pause = 0;
+ pause_config.rx_pause = 0;
+
+ mtu = ETH_HLEN + bnad->netdev->mtu + ETH_FCS_LEN;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_port_mtu_set(&bnad->bna.port, mtu, NULL);
+ bna_port_pause_config(&bnad->bna.port, &pause_config, NULL);
+ bna_port_enable(&bnad->bna.port);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Enable broadcast */
+ bnad_enable_default_bcast(bnad);
+
+ /* Set the UCAST address */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bnad_mac_addr_set_locked(bnad, netdev->dev_addr);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Start the stats timer */
+ bnad_stats_timer_start(bnad);
+
+ mutex_unlock(&bnad->conf_mutex);
+
+ return 0;
+
+cleanup_tx:
+ bnad_cleanup_tx(bnad, 0);
+
+err_return:
+ mutex_unlock(&bnad->conf_mutex);
+ return err;
+}
+
+static int
+bnad_stop(struct net_device *netdev)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ /* Stop the stats timer */
+ bnad_stats_timer_stop(bnad);
+
+ init_completion(&bnad->bnad_completions.port_comp);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_port_disable(&bnad->bna.port, BNA_HARD_CLEANUP,
+ bnad_cb_port_disabled);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ wait_for_completion(&bnad->bnad_completions.port_comp);
+
+ bnad_cleanup_tx(bnad, 0);
+ bnad_cleanup_rx(bnad, 0);
+
+ /* Synchronize mailbox IRQ */
+ bnad_mbox_irq_sync(bnad);
+
+ mutex_unlock(&bnad->conf_mutex);
+
+ return 0;
+}
+
+/* TX */
+/*
+ * bnad_start_xmit : Netdev entry point for Transmit
+ * Called under lock held by net_device
+ */
+static netdev_tx_t
+bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ u16 txq_prod, vlan_tag = 0;
+ u32 unmap_prod, wis, wis_used, wi_range;
+ u32 vectors, vect_id, i, acked;
+ u32 tx_id;
+ int err;
+
+ struct bnad_tx_info *tx_info;
+ struct bna_tcb *tcb;
+ struct bnad_unmap_q *unmap_q;
+ dma_addr_t dma_addr;
+ struct bna_txq_entry *txqent;
+ bna_txq_wi_ctrl_flag_t flags;
+
+ if (unlikely
+ (skb->len <= ETH_HLEN || skb->len > BFI_TX_MAX_DATA_PER_PKT)) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ /*
+ * Takes care of the Tx that is scheduled between clearing the flag
+ * and the netif_stop_queue() call.
+ */
+ if (unlikely(!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ tx_id = 0;
+
+ tx_info = &bnad->tx_info[tx_id];
+ tcb = tx_info->tcb[tx_id];
+ unmap_q = tcb->unmap_q;
+
+ vectors = 1 + skb_shinfo(skb)->nr_frags;
+ if (vectors > BFI_TX_MAX_VECTORS_PER_PKT) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ wis = BNA_TXQ_WI_NEEDED(vectors); /* 4 vectors per work item */
+ acked = 0;
+ if (unlikely
+ (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
+ vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) {
+ if ((u16) (*tcb->hw_consumer_index) !=
+ tcb->consumer_index &&
+ !test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) {
+ acked = bnad_free_txbufs(bnad, tcb);
+ bna_ib_ack(tcb->i_dbell, acked);
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+ } else {
+ netif_stop_queue(netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_stop);
+ }
+
+ smp_mb();
+ /*
+ * Check again to deal with race condition between
+ * netif_stop_queue here, and netif_wake_queue in
+ * interrupt handler which is not inside netif tx lock.
+ */
+ if (likely
+ (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
+ vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) {
+ BNAD_UPDATE_CTR(bnad, netif_queue_stop);
+ return NETDEV_TX_BUSY;
+ } else {
+ netif_wake_queue(netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ }
+ }
+
+ unmap_prod = unmap_q->producer_index;
+ wis_used = 1;
+ vect_id = 0;
+ flags = 0;
+
+ txq_prod = tcb->producer_index;
+ BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt, txqent, wi_range);
+ BUG_ON(!(wi_range <= tcb->q_depth));
+ txqent->hdr.wi.reserved = 0;
+ txqent->hdr.wi.num_vectors = vectors;
+ txqent->hdr.wi.opcode =
+ htons((skb_is_gso(skb) ? BNA_TXQ_WI_SEND_LSO :
+ BNA_TXQ_WI_SEND));
+
+ if (vlan_tx_tag_present(skb)) {
+ vlan_tag = (u16) vlan_tx_tag_get(skb);
+ flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN);
+ }
+ if (test_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags)) {
+ vlan_tag =
+ (tcb->priority & 0x7) << 13 | (vlan_tag & 0x1fff);
+ flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN);
+ }
+
+ txqent->hdr.wi.vlan_tag = htons(vlan_tag);
+
+ if (skb_is_gso(skb)) {
+ err = bnad_tso_prepare(bnad, skb);
+ if (err) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ txqent->hdr.wi.lso_mss = htons(skb_is_gso(skb));
+ flags |= (BNA_TXQ_WI_CF_IP_CKSUM | BNA_TXQ_WI_CF_TCP_CKSUM);
+ txqent->hdr.wi.l4_hdr_size_n_offset =
+ htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
+ (tcp_hdrlen(skb) >> 2,
+ skb_transport_offset(skb)));
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ u8 proto = 0;
+
+ txqent->hdr.wi.lso_mss = 0;
+
+ if (skb->protocol == htons(ETH_P_IP))
+ proto = ip_hdr(skb)->protocol;
+ else if (skb->protocol == htons(ETH_P_IPV6)) {
+ /* nexthdr may not be TCP immediately. */
+ proto = ipv6_hdr(skb)->nexthdr;
+ }
+ if (proto == IPPROTO_TCP) {
+ flags |= BNA_TXQ_WI_CF_TCP_CKSUM;
+ txqent->hdr.wi.l4_hdr_size_n_offset =
+ htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
+ (0, skb_transport_offset(skb)));
+
+ BNAD_UPDATE_CTR(bnad, tcpcsum_offload);
+
+ BUG_ON(!(skb_headlen(skb) >=
+ skb_transport_offset(skb) + tcp_hdrlen(skb)));
+
+ } else if (proto == IPPROTO_UDP) {
+ flags |= BNA_TXQ_WI_CF_UDP_CKSUM;
+ txqent->hdr.wi.l4_hdr_size_n_offset =
+ htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
+ (0, skb_transport_offset(skb)));
+
+ BNAD_UPDATE_CTR(bnad, udpcsum_offload);
+
+ BUG_ON(!(skb_headlen(skb) >=
+ skb_transport_offset(skb) +
+ sizeof(struct udphdr)));
+ } else {
+ err = skb_checksum_help(skb);
+ BNAD_UPDATE_CTR(bnad, csum_help);
+ if (err) {
+ dev_kfree_skb(skb);
+ BNAD_UPDATE_CTR(bnad, csum_help_err);
+ return NETDEV_TX_OK;
+ }
+ }
+ } else {
+ txqent->hdr.wi.lso_mss = 0;
+ txqent->hdr.wi.l4_hdr_size_n_offset = 0;
+ }
+
+ txqent->hdr.wi.flags = htons(flags);
+
+ txqent->hdr.wi.frame_length = htonl(skb->len);
+
+ unmap_q->unmap_array[unmap_prod].skb = skb;
+ BUG_ON(!(skb_headlen(skb) <= BFI_TX_MAX_DATA_PER_VECTOR));
+ txqent->vector[vect_id].length = htons(skb_headlen(skb));
+ dma_addr = pci_map_single(bnad->pcidev, skb->data, skb_headlen(skb),
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr,
+ dma_addr);
+
+ BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr);
+ BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+ u32 size = frag->size;
+
+ if (++vect_id == BFI_TX_MAX_VECTORS_PER_WI) {
+ vect_id = 0;
+ if (--wi_range)
+ txqent++;
+ else {
+ BNA_QE_INDX_ADD(txq_prod, wis_used,
+ tcb->q_depth);
+ wis_used = 0;
+ BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt,
+ txqent, wi_range);
+ BUG_ON(!(wi_range <= tcb->q_depth));
+ }
+ wis_used++;
+ txqent->hdr.wi_ext.opcode = htons(BNA_TXQ_WI_EXTENSION);
+ }
+
+ BUG_ON(!(size <= BFI_TX_MAX_DATA_PER_VECTOR));
+ txqent->vector[vect_id].length = htons(size);
+ dma_addr =
+ pci_map_page(bnad->pcidev, frag->page,
+ frag->page_offset, size,
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr,
+ dma_addr);
+ BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr);
+ BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth);
+ }
+
+ unmap_q->producer_index = unmap_prod;
+ BNA_QE_INDX_ADD(txq_prod, wis_used, tcb->q_depth);
+ tcb->producer_index = txq_prod;
+
+ smp_mb();
+ bna_txq_prod_indx_doorbell(tcb);
+
+ if ((u16) (*tcb->hw_consumer_index) != tcb->consumer_index)
+ tasklet_schedule(&bnad->tx_free_tasklet);
+
+ return NETDEV_TX_OK;
+}
+
+/*
+ * Used spin_lock to synchronize reading of stats structures, which
+ * is written by BNA under the same lock.
+ */
+static struct rtnl_link_stats64 *
+bnad_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ bnad_netdev_qstats_fill(bnad, stats);
+ bnad_netdev_hwstats_fill(bnad, stats);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ return stats;
+}
+
+static void
+bnad_set_rx_mode(struct net_device *netdev)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ u32 new_mask, valid_mask;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ new_mask = valid_mask = 0;
+
+ if (netdev->flags & IFF_PROMISC) {
+ if (!(bnad->cfg_flags & BNAD_CF_PROMISC)) {
+ new_mask = BNAD_RXMODE_PROMISC_DEFAULT;
+ valid_mask = BNAD_RXMODE_PROMISC_DEFAULT;
+ bnad->cfg_flags |= BNAD_CF_PROMISC;
+ }
+ } else {
+ if (bnad->cfg_flags & BNAD_CF_PROMISC) {
+ new_mask = ~BNAD_RXMODE_PROMISC_DEFAULT;
+ valid_mask = BNAD_RXMODE_PROMISC_DEFAULT;
+ bnad->cfg_flags &= ~BNAD_CF_PROMISC;
+ }
+ }
+
+ if (netdev->flags & IFF_ALLMULTI) {
+ if (!(bnad->cfg_flags & BNAD_CF_ALLMULTI)) {
+ new_mask |= BNA_RXMODE_ALLMULTI;
+ valid_mask |= BNA_RXMODE_ALLMULTI;
+ bnad->cfg_flags |= BNAD_CF_ALLMULTI;
+ }
+ } else {
+ if (bnad->cfg_flags & BNAD_CF_ALLMULTI) {
+ new_mask &= ~BNA_RXMODE_ALLMULTI;
+ valid_mask |= BNA_RXMODE_ALLMULTI;
+ bnad->cfg_flags &= ~BNAD_CF_ALLMULTI;
+ }
+ }
+
+ bna_rx_mode_set(bnad->rx_info[0].rx, new_mask, valid_mask, NULL);
+
+ if (!netdev_mc_empty(netdev)) {
+ u8 *mcaddr_list;
+ int mc_count = netdev_mc_count(netdev);
+
+ /* Index 0 holds the broadcast address */
+ mcaddr_list =
+ kzalloc((mc_count + 1) * ETH_ALEN,
+ GFP_ATOMIC);
+ if (!mcaddr_list)
+ goto unlock;
+
+ memcpy(&mcaddr_list[0], &bnad_bcast_addr[0], ETH_ALEN);
+
+ /* Copy rest of the MC addresses */
+ bnad_netdev_mc_list_get(netdev, mcaddr_list);
+
+ bna_rx_mcast_listset(bnad->rx_info[0].rx, mc_count + 1,
+ mcaddr_list, NULL);
+
+ /* Should we enable BNAD_CF_ALLMULTI for err != 0 ? */
+ kfree(mcaddr_list);
+ }
+unlock:
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+/*
+ * bna_lock is used to sync writes to netdev->addr
+ * conf_lock cannot be used since this call may be made
+ * in a non-blocking context.
+ */
+static int
+bnad_set_mac_address(struct net_device *netdev, void *mac_addr)
+{
+ int err;
+ struct bnad *bnad = netdev_priv(netdev);
+ struct sockaddr *sa = (struct sockaddr *)mac_addr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ err = bnad_mac_addr_set_locked(bnad, sa->sa_data);
+
+ if (!err)
+ memcpy(netdev->dev_addr, sa->sa_data, netdev->addr_len);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ return err;
+}
+
+static int
+bnad_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ int mtu, err = 0;
+ unsigned long flags;
+
+ struct bnad *bnad = netdev_priv(netdev);
+
+ if (new_mtu + ETH_HLEN < ETH_ZLEN || new_mtu > BNAD_JUMBO_MTU)
+ return -EINVAL;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ netdev->mtu = new_mtu;
+
+ mtu = ETH_HLEN + new_mtu + ETH_FCS_LEN;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_port_mtu_set(&bnad->bna.port, mtu, NULL);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+ return err;
+}
+
+static void
+bnad_vlan_rx_register(struct net_device *netdev,
+ struct vlan_group *vlan_grp)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ mutex_lock(&bnad->conf_mutex);
+ bnad->vlan_grp = vlan_grp;
+ mutex_unlock(&bnad->conf_mutex);
+}
+
+static void
+bnad_vlan_rx_add_vid(struct net_device *netdev,
+ unsigned short vid)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+
+ if (!bnad->rx_info[0].rx)
+ return;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_vlan_add(bnad->rx_info[0].rx, vid);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+}
+
+static void
+bnad_vlan_rx_kill_vid(struct net_device *netdev,
+ unsigned short vid)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+
+ if (!bnad->rx_info[0].rx)
+ return;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_vlan_del(bnad->rx_info[0].rx, vid);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void
+bnad_netpoll(struct net_device *netdev)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bnad_rx_info *rx_info;
+ struct bnad_rx_ctrl *rx_ctrl;
+ u32 curr_mask;
+ int i, j;
+
+ if (!(bnad->cfg_flags & BNAD_CF_MSIX)) {
+ bna_intx_disable(&bnad->bna, curr_mask);
+ bnad_isr(bnad->pcidev->irq, netdev);
+ bna_intx_enable(&bnad->bna, curr_mask);
+ } else {
+ for (i = 0; i < bnad->num_rx; i++) {
+ rx_info = &bnad->rx_info[i];
+ if (!rx_info->rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ rx_ctrl = &rx_info->rx_ctrl[j];
+ if (rx_ctrl->ccb) {
+ bnad_disable_rx_irq(bnad,
+ rx_ctrl->ccb);
+ bnad_netif_rx_schedule_poll(bnad,
+ rx_ctrl->ccb);
+ }
+ }
+ }
+ }
+}
+#endif
+
+static const struct net_device_ops bnad_netdev_ops = {
+ .ndo_open = bnad_open,
+ .ndo_stop = bnad_stop,
+ .ndo_start_xmit = bnad_start_xmit,
+ .ndo_get_stats64 = bnad_get_stats64,
+ .ndo_set_rx_mode = bnad_set_rx_mode,
+ .ndo_set_multicast_list = bnad_set_rx_mode,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = bnad_set_mac_address,
+ .ndo_change_mtu = bnad_change_mtu,
+ .ndo_vlan_rx_register = bnad_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = bnad_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = bnad_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = bnad_netpoll
+#endif
+};
+
+static void
+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->features |= NETIF_F_GRO;
+ pr_warn("bna: GRO enabled, using kernel stack GRO\n");
+
+ netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+
+ 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;
+
+ netdev->netdev_ops = &bnad_netdev_ops;
+ bnad_set_ethtool_ops(netdev);
+}
+
+/*
+ * 1. Initialize the bnad structure
+ * 2. Setup netdev pointer in pci_dev
+ * 3. Initialze Tx free tasklet
+ * 4. Initialize no. of TxQ & CQs & MSIX vectors
+ */
+static int
+bnad_init(struct bnad *bnad,
+ struct pci_dev *pdev, struct net_device *netdev)
+{
+ unsigned long flags;
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ pci_set_drvdata(pdev, netdev);
+
+ bnad->netdev = netdev;
+ bnad->pcidev = pdev;
+ bnad->mmio_start = pci_resource_start(pdev, 0);
+ bnad->mmio_len = pci_resource_len(pdev, 0);
+ bnad->bar0 = ioremap_nocache(bnad->mmio_start, bnad->mmio_len);
+ if (!bnad->bar0) {
+ dev_err(&pdev->dev, "ioremap for bar0 failed\n");
+ pci_set_drvdata(pdev, NULL);
+ return -ENOMEM;
+ }
+ pr_info("bar0 mapped to %p, len %llu\n", bnad->bar0,
+ (unsigned long long) bnad->mmio_len);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (!bnad_msix_disable)
+ bnad->cfg_flags = BNAD_CF_MSIX;
+
+ bnad->cfg_flags |= BNAD_CF_DIM_ENABLED;
+
+ bnad_q_num_init(bnad);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx) +
+ (bnad->num_rx * bnad->num_rxp_per_rx) +
+ BNAD_MAILBOX_MSIX_VECTORS;
+
+ 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;
+
+ tasklet_init(&bnad->tx_free_tasklet, bnad_tx_free_tasklet,
+ (unsigned long)bnad);
+
+ return 0;
+}
+
+/*
+ * Must be called after bnad_pci_uninit()
+ * so that iounmap() and pci_set_drvdata(NULL)
+ * happens only after PCI uninitialization.
+ */
+static void
+bnad_uninit(struct bnad *bnad)
+{
+ if (bnad->bar0)
+ iounmap(bnad->bar0);
+ pci_set_drvdata(bnad->pcidev, NULL);
+}
+
+/*
+ * Initialize locks
+ a) Per device mutes used for serializing configuration
+ changes from OS interface
+ b) spin lock used to protect bna state machine
+ */
+static void
+bnad_lock_init(struct bnad *bnad)
+{
+ spin_lock_init(&bnad->bna_lock);
+ mutex_init(&bnad->conf_mutex);
+}
+
+static void
+bnad_lock_uninit(struct bnad *bnad)
+{
+ mutex_destroy(&bnad->conf_mutex);
+}
+
+/* PCI Initialization */
+static int
+bnad_pci_init(struct bnad *bnad,
+ struct pci_dev *pdev, bool *using_dac)
+{
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
+ err = pci_request_regions(pdev, BNAD_NAME);
+ if (err)
+ goto disable_device;
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
+ !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ *using_dac = 1;
+ } else {
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (err) {
+ err = pci_set_consistent_dma_mask(pdev,
+ DMA_BIT_MASK(32));
+ if (err)
+ goto release_regions;
+ }
+ *using_dac = 0;
+ }
+ pci_set_master(pdev);
+ return 0;
+
+release_regions:
+ pci_release_regions(pdev);
+disable_device:
+ pci_disable_device(pdev);
+
+ return err;
+}
+
+static void
+bnad_pci_uninit(struct pci_dev *pdev)
+{
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+static int __devinit
+bnad_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *pcidev_id)
+{
+ bool using_dac;
+ int err;
+ struct bnad *bnad;
+ struct bna *bna;
+ struct net_device *netdev;
+ struct bfa_pcidev pcidev_info;
+ unsigned long flags;
+
+ pr_info("bnad_pci_probe : (0x%p, 0x%p) PCI Func : (%d)\n",
+ pdev, pcidev_id, PCI_FUNC(pdev->devfn));
+
+ mutex_lock(&bnad_fwimg_mutex);
+ if (!cna_get_firmware_buf(pdev)) {
+ mutex_unlock(&bnad_fwimg_mutex);
+ pr_warn("Failed to load Firmware Image!\n");
+ return -ENODEV;
+ }
+ mutex_unlock(&bnad_fwimg_mutex);
+
+ /*
+ * Allocates sizeof(struct net_device + struct bnad)
+ * bnad = netdev->priv
+ */
+ netdev = alloc_etherdev(sizeof(struct bnad));
+ if (!netdev) {
+ dev_err(&pdev->dev, "alloc_etherdev failed\n");
+ err = -ENOMEM;
+ return err;
+ }
+ bnad = netdev_priv(netdev);
+
+ /*
+ * PCI initialization
+ * Output : using_dac = 1 for 64 bit DMA
+ * = 0 for 32 bit DMA
+ */
+ err = bnad_pci_init(bnad, pdev, &using_dac);
+ if (err)
+ goto free_netdev;
+
+ bnad_lock_init(bnad);
+ /*
+ * Initialize bnad structure
+ * Setup relation between pci_dev & netdev
+ * Init Tx free tasklet
+ */
+ err = bnad_init(bnad, pdev, netdev);
+ if (err)
+ goto pci_uninit;
+ /* Initialize netdev structure, set up ethtool ops */
+ bnad_netdev_init(bnad, using_dac);
+
+ bnad_enable_msix(bnad);
+
+ /* Get resource requirement form bna */
+ bna_res_req(&bnad->res_info[0]);
+
+ /* Allocate resources from bna */
+ err = bnad_res_alloc(bnad);
+ if (err)
+ goto free_netdev;
+
+ bna = &bnad->bna;
+
+ /* Setup pcidev_info for bna_init() */
+ pcidev_info.pci_slot = PCI_SLOT(bnad->pcidev->devfn);
+ pcidev_info.pci_func = PCI_FUNC(bnad->pcidev->devfn);
+ pcidev_info.device_id = bnad->pcidev->device;
+ pcidev_info.pci_bar_kva = bnad->bar0;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_init(bna, bnad, &pcidev_info, &bnad->res_info[0]);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ bnad->stats.bna_stats = &bna->stats;
+
+ /* Set up timers */
+ setup_timer(&bnad->bna.device.ioc.ioc_timer, bnad_ioc_timeout,
+ ((unsigned long)bnad));
+ setup_timer(&bnad->bna.device.ioc.hb_timer, bnad_ioc_hb_check,
+ ((unsigned long)bnad));
+ setup_timer(&bnad->bna.device.ioc.sem_timer, bnad_ioc_sem_timeout,
+ ((unsigned long)bnad));
+
+ /* Now start the timer before calling IOC */
+ mod_timer(&bnad->bna.device.ioc.ioc_timer,
+ jiffies + msecs_to_jiffies(BNA_IOC_TIMER_FREQ));
+
+ /*
+ * Start the chip
+ * Don't care even if err != 0, bna state machine will
+ * deal with it
+ */
+ err = bnad_device_enable(bnad);
+
+ /* Get the burnt-in mac */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_port_mac_get(&bna->port, &bnad->perm_addr);
+ bnad_set_netdev_perm_addr(bnad);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+
+ /*
+ * Make sure the link appears down to the stack
+ */
+ netif_carrier_off(netdev);
+
+ /* Finally, reguister with net_device layer */
+ err = register_netdev(netdev);
+ if (err) {
+ pr_err("BNA : Registering with netdev failed\n");
+ goto disable_device;
+ }
+
+ return 0;
+
+disable_device:
+ mutex_lock(&bnad->conf_mutex);
+ bnad_device_disable(bnad);
+ del_timer_sync(&bnad->bna.device.ioc.ioc_timer);
+ del_timer_sync(&bnad->bna.device.ioc.sem_timer);
+ del_timer_sync(&bnad->bna.device.ioc.hb_timer);
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_uninit(bna);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ mutex_unlock(&bnad->conf_mutex);
+
+ bnad_res_free(bnad);
+ bnad_disable_msix(bnad);
+pci_uninit:
+ bnad_pci_uninit(pdev);
+ bnad_lock_uninit(bnad);
+ bnad_uninit(bnad);
+free_netdev:
+ free_netdev(netdev);
+ return err;
+}
+
+static void __devexit
+bnad_pci_remove(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct bnad *bnad;
+ struct bna *bna;
+ unsigned long flags;
+
+ if (!netdev)
+ return;
+
+ pr_info("%s bnad_pci_remove\n", netdev->name);
+ bnad = netdev_priv(netdev);
+ bna = &bnad->bna;
+
+ unregister_netdev(netdev);
+
+ mutex_lock(&bnad->conf_mutex);
+ bnad_device_disable(bnad);
+ del_timer_sync(&bnad->bna.device.ioc.ioc_timer);
+ del_timer_sync(&bnad->bna.device.ioc.sem_timer);
+ del_timer_sync(&bnad->bna.device.ioc.hb_timer);
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_uninit(bna);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ mutex_unlock(&bnad->conf_mutex);
+
+ bnad_res_free(bnad);
+ bnad_disable_msix(bnad);
+ bnad_pci_uninit(pdev);
+ bnad_lock_uninit(bnad);
+ bnad_uninit(bnad);
+ free_netdev(netdev);
+}
+
+static const struct pci_device_id bnad_pci_id_table[] = {
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_BROCADE,
+ PCI_DEVICE_ID_BROCADE_CT),
+ .class = PCI_CLASS_NETWORK_ETHERNET << 8,
+ .class_mask = 0xffff00
+ }, {0, }
+};
+
+MODULE_DEVICE_TABLE(pci, bnad_pci_id_table);
+
+static struct pci_driver bnad_pci_driver = {
+ .name = BNAD_NAME,
+ .id_table = bnad_pci_id_table,
+ .probe = bnad_pci_probe,
+ .remove = __devexit_p(bnad_pci_remove),
+};
+
+static int __init
+bnad_module_init(void)
+{
+ int err;
+
+ pr_info("Brocade 10G Ethernet driver\n");
+
+ bfa_nw_ioc_auto_recover(bnad_ioc_auto_recover);
+
+ err = pci_register_driver(&bnad_pci_driver);
+ if (err < 0) {
+ pr_err("bna : PCI registration failed in module init "
+ "(%d)\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static void __exit
+bnad_module_exit(void)
+{
+ pci_unregister_driver(&bnad_pci_driver);
+
+ if (bfi_fw)
+ release_firmware(bfi_fw);
+}
+
+module_init(bnad_module_init);
+module_exit(bnad_module_exit);
+
+MODULE_AUTHOR("Brocade");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Brocade 10G PCIe Ethernet driver");
+MODULE_VERSION(BNAD_VERSION);
+MODULE_FIRMWARE(CNA_FW_FILE_CT);
diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h
new file mode 100644
index 000000000000..ebc3a9078642
--- /dev/null
+++ b/drivers/net/bna/bnad.h
@@ -0,0 +1,332 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BNAD_H__
+#define __BNAD_H__
+
+#include <linux/rtnetlink.h>
+#include <linux/workqueue.h>
+#include <linux/ipv6.h>
+#include <linux/etherdevice.h>
+#include <linux/mutex.h>
+#include <linux/firmware.h>
+
+/* Fix for IA64 */
+#include <asm/checksum.h>
+#include <net/ip6_checksum.h>
+
+#include <net/ip.h>
+#include <net/tcp.h>
+
+#include "bna.h"
+
+#define BNAD_TXQ_DEPTH 2048
+#define BNAD_RXQ_DEPTH 2048
+
+#define BNAD_MAX_TXS 1
+#define BNAD_MAX_TXQ_PER_TX 8 /* 8 priority queues */
+#define BNAD_TXQ_NUM 1
+
+#define BNAD_MAX_RXS 1
+#define BNAD_MAX_RXPS_PER_RX 16
+
+/*
+ * Control structure pointed to ccb->ctrl, which
+ * determines the NAPI / LRO behavior CCB
+ * There is 1:1 corres. between ccb & ctrl
+ */
+struct bnad_rx_ctrl {
+ struct bna_ccb *ccb;
+ struct napi_struct napi;
+};
+
+#define BNAD_RXMODE_PROMISC_DEFAULT BNA_RXMODE_PROMISC
+
+#define BNAD_GET_TX_ID(_skb) (0)
+
+/*
+ * GLOBAL #defines (CONSTANTS)
+ */
+#define BNAD_NAME "bna"
+#define BNAD_NAME_LEN 64
+
+#define BNAD_VERSION "2.3.2.0"
+
+#define BNAD_MAILBOX_MSIX_VECTORS 1
+
+#define BNAD_STATS_TIMER_FREQ 1000 /* in msecs */
+#define BNAD_DIM_TIMER_FREQ 1000 /* in msecs */
+
+#define BNAD_MAX_Q_DEPTH 0x10000
+#define BNAD_MIN_Q_DEPTH 0x200
+
+#define BNAD_JUMBO_MTU 9000
+
+#define BNAD_NETIF_WAKE_THRESHOLD 8
+
+#define BNAD_RXQ_REFILL_THRESHOLD_SHIFT 3
+
+/* Bit positions for tcb->flags */
+#define BNAD_TXQ_FREE_SENT 0
+
+/* Bit positions for rcb->flags */
+#define BNAD_RXQ_REFILL 0
+#define BNAD_RXQ_STARTED 1
+
+/*
+ * DATA STRUCTURES
+ */
+
+/* enums */
+enum bnad_intr_source {
+ BNAD_INTR_TX = 1,
+ BNAD_INTR_RX = 2
+};
+
+enum bnad_link_state {
+ BNAD_LS_DOWN = 0,
+ BNAD_LS_UP = 1
+};
+
+struct bnad_completion {
+ struct completion ioc_comp;
+ struct completion ucast_comp;
+ struct completion mcast_comp;
+ struct completion tx_comp;
+ struct completion rx_comp;
+ struct completion stats_comp;
+ struct completion port_comp;
+
+ u8 ioc_comp_status;
+ u8 ucast_comp_status;
+ u8 mcast_comp_status;
+ u8 tx_comp_status;
+ u8 rx_comp_status;
+ u8 stats_comp_status;
+ u8 port_comp_status;
+};
+
+/* Tx Rx Control Stats */
+struct bnad_drv_stats {
+ u64 netif_queue_stop;
+ u64 netif_queue_wakeup;
+ u64 tso4;
+ u64 tso6;
+ u64 tso_err;
+ u64 tcpcsum_offload;
+ u64 udpcsum_offload;
+ u64 csum_help;
+ u64 csum_help_err;
+
+ u64 hw_stats_updates;
+ u64 netif_rx_schedule;
+ u64 netif_rx_complete;
+ u64 netif_rx_dropped;
+
+ u64 link_toggle;
+ u64 cee_up;
+
+ u64 rxp_info_alloc_failed;
+ u64 mbox_intr_disabled;
+ u64 mbox_intr_enabled;
+ u64 tx_unmap_q_alloc_failed;
+ u64 rx_unmap_q_alloc_failed;
+
+ u64 rxbuf_alloc_failed;
+};
+
+/* Complete driver stats */
+struct bnad_stats {
+ struct bnad_drv_stats drv_stats;
+ struct bna_stats *bna_stats;
+};
+
+/* Tx / Rx Resources */
+struct bnad_tx_res_info {
+ struct bna_res_info res_info[BNA_TX_RES_T_MAX];
+};
+
+struct bnad_rx_res_info {
+ struct bna_res_info res_info[BNA_RX_RES_T_MAX];
+};
+
+struct bnad_tx_info {
+ struct bna_tx *tx; /* 1:1 between tx_info & tx */
+ struct bna_tcb *tcb[BNAD_MAX_TXQ_PER_TX];
+} ____cacheline_aligned;
+
+struct bnad_rx_info {
+ struct bna_rx *rx; /* 1:1 between rx_info & rx */
+
+ struct bnad_rx_ctrl rx_ctrl[BNAD_MAX_RXPS_PER_RX];
+} ____cacheline_aligned;
+
+/* Unmap queues for Tx / Rx cleanup */
+struct bnad_skb_unmap {
+ struct sk_buff *skb;
+ DECLARE_PCI_UNMAP_ADDR(dma_addr)
+};
+
+struct bnad_unmap_q {
+ u32 producer_index;
+ u32 consumer_index;
+ u32 q_depth;
+ /* This should be the last one */
+ struct bnad_skb_unmap unmap_array[1];
+};
+
+/* Bit mask values for bnad->cfg_flags */
+#define BNAD_CF_DIM_ENABLED 0x01 /* DIM */
+#define BNAD_CF_PROMISC 0x02
+#define BNAD_CF_ALLMULTI 0x04
+#define BNAD_CF_MSIX 0x08 /* If in MSIx mode */
+
+/* Defines for run_flags bit-mask */
+/* Set, tested & cleared using xxx_bit() functions */
+/* Values indicated bit positions */
+#define BNAD_RF_CEE_RUNNING 1
+#define BNAD_RF_HW_ERROR 2
+#define BNAD_RF_MBOX_IRQ_DISABLED 3
+#define BNAD_RF_TX_STARTED 4
+#define BNAD_RF_RX_STARTED 5
+#define BNAD_RF_DIM_TIMER_RUNNING 6
+#define BNAD_RF_STATS_TIMER_RUNNING 7
+
+struct bnad {
+ struct net_device *netdev;
+
+ /* Data path */
+ struct bnad_tx_info tx_info[BNAD_MAX_TXS];
+ struct bnad_rx_info rx_info[BNAD_MAX_RXS];
+
+ struct vlan_group *vlan_grp;
+ /*
+ * These q numbers are global only because
+ * they are used to calculate MSIx vectors.
+ * Actually the exact # of queues are per Tx/Rx
+ * object.
+ */
+ u32 num_tx;
+ u32 num_rx;
+ u32 num_txq_per_tx;
+ u32 num_rxp_per_rx;
+
+ u32 txq_depth;
+ u32 rxq_depth;
+
+ u8 tx_coalescing_timeo;
+ u8 rx_coalescing_timeo;
+
+ 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;
+
+ u32 cfg_flags;
+ unsigned long run_flags;
+
+ struct pci_dev *pcidev;
+ u64 mmio_start;
+ u64 mmio_len;
+
+ u32 msix_num;
+ struct msix_entry *msix_table;
+
+ struct mutex conf_mutex;
+ spinlock_t bna_lock ____cacheline_aligned;
+
+ /* Timers */
+ struct timer_list ioc_timer;
+ struct timer_list dim_timer;
+ struct timer_list stats_timer;
+
+ /* Control path resources, memory & irq */
+ struct bna_res_info res_info[BNA_RES_T_MAX];
+ struct bnad_tx_res_info tx_res_info[BNAD_MAX_TXS];
+ struct bnad_rx_res_info rx_res_info[BNAD_MAX_RXS];
+
+ struct bnad_completion bnad_completions;
+
+ /* Burnt in MAC address */
+ mac_t perm_addr;
+
+ struct tasklet_struct tx_free_tasklet;
+
+ /* Statistics */
+ struct bnad_stats stats;
+
+ struct bnad_diag *diag;
+
+ char adapter_name[BNAD_NAME_LEN];
+ char port_name[BNAD_NAME_LEN];
+ char mbox_irq_name[BNAD_NAME_LEN];
+};
+
+/*
+ * EXTERN VARIABLES
+ */
+extern struct firmware *bfi_fw;
+extern u32 bnad_rxqs_per_cq;
+
+/*
+ * EXTERN PROTOTYPES
+ */
+extern u32 *cna_get_firmware_buf(struct pci_dev *pdev);
+/* Netdev entry point prototypes */
+extern void bnad_set_ethtool_ops(struct net_device *netdev);
+
+/* Configuration & setup */
+extern void bnad_tx_coalescing_timeo_set(struct bnad *bnad);
+extern void bnad_rx_coalescing_timeo_set(struct bnad *bnad);
+
+extern int bnad_setup_rx(struct bnad *bnad, uint rx_id);
+extern int bnad_setup_tx(struct bnad *bnad, uint tx_id);
+extern void bnad_cleanup_tx(struct bnad *bnad, uint tx_id);
+extern void bnad_cleanup_rx(struct bnad *bnad, uint rx_id);
+
+/* Timer start/stop protos */
+extern void bnad_dim_timer_start(struct bnad *bnad);
+
+/* Statistics */
+extern void bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats);
+extern void bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats);
+
+/**
+ * MACROS
+ */
+/* To set & get the stats counters */
+#define BNAD_UPDATE_CTR(_bnad, _ctr) \
+ (((_bnad)->stats.drv_stats._ctr)++)
+
+#define BNAD_GET_CTR(_bnad, _ctr) ((_bnad)->stats.drv_stats._ctr)
+
+#define bnad_enable_rx_irq_unsafe(_ccb) \
+{ \
+ bna_ib_coalescing_timer_set((_ccb)->i_dbell, \
+ (_ccb)->rx_coalescing_timeo); \
+ bna_ib_ack((_ccb)->i_dbell, 0); \
+}
+
+#define bnad_dim_timer_running(_bnad) \
+ (((_bnad)->cfg_flags & BNAD_CF_DIM_ENABLED) && \
+ (test_bit(BNAD_RF_DIM_TIMER_RUNNING, &((_bnad)->run_flags))))
+
+#endif /* __BNAD_H__ */
diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c
new file mode 100644
index 000000000000..11fa2ea842c1
--- /dev/null
+++ b/drivers/net/bna/bnad_ethtool.c
@@ -0,0 +1,1277 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#include "cna.h"
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/rtnetlink.h>
+
+#include "bna.h"
+
+#include "bnad.h"
+
+#define BNAD_NUM_TXF_COUNTERS 12
+#define BNAD_NUM_RXF_COUNTERS 10
+#define BNAD_NUM_CQ_COUNTERS 3
+#define BNAD_NUM_RXQ_COUNTERS 6
+#define BNAD_NUM_TXQ_COUNTERS 5
+
+#define BNAD_ETHTOOL_STATS_NUM \
+ (sizeof(struct rtnl_link_stats64) / sizeof(u64) + \
+ sizeof(struct bnad_drv_stats) / sizeof(u64) + \
+ offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64))
+
+static char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = {
+ "rx_packets",
+ "tx_packets",
+ "rx_bytes",
+ "tx_bytes",
+ "rx_errors",
+ "tx_errors",
+ "rx_dropped",
+ "tx_dropped",
+ "multicast",
+ "collisions",
+
+ "rx_length_errors",
+ "rx_over_errors",
+ "rx_crc_errors",
+ "rx_frame_errors",
+ "rx_fifo_errors",
+ "rx_missed_errors",
+
+ "tx_aborted_errors",
+ "tx_carrier_errors",
+ "tx_fifo_errors",
+ "tx_heartbeat_errors",
+ "tx_window_errors",
+
+ "rx_compressed",
+ "tx_compressed",
+
+ "netif_queue_stop",
+ "netif_queue_wakeup",
+ "tso4",
+ "tso6",
+ "tso_err",
+ "tcpcsum_offload",
+ "udpcsum_offload",
+ "csum_help",
+ "csum_help_err",
+ "hw_stats_updates",
+ "netif_rx_schedule",
+ "netif_rx_complete",
+ "netif_rx_dropped",
+
+ "link_toggle",
+ "cee_up",
+
+ "rxp_info_alloc_failed",
+ "mbox_intr_disabled",
+ "mbox_intr_enabled",
+ "tx_unmap_q_alloc_failed",
+ "rx_unmap_q_alloc_failed",
+ "rxbuf_alloc_failed",
+
+ "mac_frame_64",
+ "mac_frame_65_127",
+ "mac_frame_128_255",
+ "mac_frame_256_511",
+ "mac_frame_512_1023",
+ "mac_frame_1024_1518",
+ "mac_frame_1518_1522",
+ "mac_rx_bytes",
+ "mac_rx_packets",
+ "mac_rx_fcs_error",
+ "mac_rx_multicast",
+ "mac_rx_broadcast",
+ "mac_rx_control_frames",
+ "mac_rx_pause",
+ "mac_rx_unknown_opcode",
+ "mac_rx_alignment_error",
+ "mac_rx_frame_length_error",
+ "mac_rx_code_error",
+ "mac_rx_carrier_sense_error",
+ "mac_rx_undersize",
+ "mac_rx_oversize",
+ "mac_rx_fragments",
+ "mac_rx_jabber",
+ "mac_rx_drop",
+
+ "mac_tx_bytes",
+ "mac_tx_packets",
+ "mac_tx_multicast",
+ "mac_tx_broadcast",
+ "mac_tx_pause",
+ "mac_tx_deferral",
+ "mac_tx_excessive_deferral",
+ "mac_tx_single_collision",
+ "mac_tx_muliple_collision",
+ "mac_tx_late_collision",
+ "mac_tx_excessive_collision",
+ "mac_tx_total_collision",
+ "mac_tx_pause_honored",
+ "mac_tx_drop",
+ "mac_tx_jabber",
+ "mac_tx_fcs_error",
+ "mac_tx_control_frame",
+ "mac_tx_oversize",
+ "mac_tx_undersize",
+ "mac_tx_fragments",
+
+ "bpc_tx_pause_0",
+ "bpc_tx_pause_1",
+ "bpc_tx_pause_2",
+ "bpc_tx_pause_3",
+ "bpc_tx_pause_4",
+ "bpc_tx_pause_5",
+ "bpc_tx_pause_6",
+ "bpc_tx_pause_7",
+ "bpc_tx_zero_pause_0",
+ "bpc_tx_zero_pause_1",
+ "bpc_tx_zero_pause_2",
+ "bpc_tx_zero_pause_3",
+ "bpc_tx_zero_pause_4",
+ "bpc_tx_zero_pause_5",
+ "bpc_tx_zero_pause_6",
+ "bpc_tx_zero_pause_7",
+ "bpc_tx_first_pause_0",
+ "bpc_tx_first_pause_1",
+ "bpc_tx_first_pause_2",
+ "bpc_tx_first_pause_3",
+ "bpc_tx_first_pause_4",
+ "bpc_tx_first_pause_5",
+ "bpc_tx_first_pause_6",
+ "bpc_tx_first_pause_7",
+
+ "bpc_rx_pause_0",
+ "bpc_rx_pause_1",
+ "bpc_rx_pause_2",
+ "bpc_rx_pause_3",
+ "bpc_rx_pause_4",
+ "bpc_rx_pause_5",
+ "bpc_rx_pause_6",
+ "bpc_rx_pause_7",
+ "bpc_rx_zero_pause_0",
+ "bpc_rx_zero_pause_1",
+ "bpc_rx_zero_pause_2",
+ "bpc_rx_zero_pause_3",
+ "bpc_rx_zero_pause_4",
+ "bpc_rx_zero_pause_5",
+ "bpc_rx_zero_pause_6",
+ "bpc_rx_zero_pause_7",
+ "bpc_rx_first_pause_0",
+ "bpc_rx_first_pause_1",
+ "bpc_rx_first_pause_2",
+ "bpc_rx_first_pause_3",
+ "bpc_rx_first_pause_4",
+ "bpc_rx_first_pause_5",
+ "bpc_rx_first_pause_6",
+ "bpc_rx_first_pause_7",
+
+ "rad_rx_frames",
+ "rad_rx_octets",
+ "rad_rx_vlan_frames",
+ "rad_rx_ucast",
+ "rad_rx_ucast_octets",
+ "rad_rx_ucast_vlan",
+ "rad_rx_mcast",
+ "rad_rx_mcast_octets",
+ "rad_rx_mcast_vlan",
+ "rad_rx_bcast",
+ "rad_rx_bcast_octets",
+ "rad_rx_bcast_vlan",
+ "rad_rx_drops",
+
+ "fc_rx_ucast_octets",
+ "fc_rx_ucast",
+ "fc_rx_ucast_vlan",
+ "fc_rx_mcast_octets",
+ "fc_rx_mcast",
+ "fc_rx_mcast_vlan",
+ "fc_rx_bcast_octets",
+ "fc_rx_bcast",
+ "fc_rx_bcast_vlan",
+
+ "fc_tx_ucast_octets",
+ "fc_tx_ucast",
+ "fc_tx_ucast_vlan",
+ "fc_tx_mcast_octets",
+ "fc_tx_mcast",
+ "fc_tx_mcast_vlan",
+ "fc_tx_bcast_octets",
+ "fc_tx_bcast",
+ "fc_tx_bcast_vlan",
+ "fc_tx_parity_errors",
+ "fc_tx_timeout",
+ "fc_tx_fid_parity_errors",
+};
+
+static int
+bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+ cmd->supported = SUPPORTED_10000baseT_Full;
+ cmd->advertising = ADVERTISED_10000baseT_Full;
+ cmd->autoneg = AUTONEG_DISABLE;
+ cmd->supported |= SUPPORTED_FIBRE;
+ cmd->advertising |= ADVERTISED_FIBRE;
+ cmd->port = PORT_FIBRE;
+ cmd->phy_address = 0;
+
+ if (netif_carrier_ok(netdev)) {
+ cmd->speed = SPEED_10000;
+ cmd->duplex = DUPLEX_FULL;
+ } else {
+ cmd->speed = -1;
+ cmd->duplex = -1;
+ }
+ cmd->transceiver = XCVR_EXTERNAL;
+ cmd->maxtxpkt = 0;
+ cmd->maxrxpkt = 0;
+
+ return 0;
+}
+
+static int
+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))
+ return 0;
+ }
+
+ return -EOPNOTSUPP;
+}
+
+static void
+bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bfa_ioc_attr *ioc_attr;
+ unsigned long flags;
+
+ strcpy(drvinfo->driver, BNAD_NAME);
+ strcpy(drvinfo->version, BNAD_VERSION);
+
+ ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL);
+ if (ioc_attr) {
+ memset(ioc_attr, 0, sizeof(*ioc_attr));
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bfa_nw_ioc_get_attr(&bnad->bna.device.ioc, ioc_attr);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ strncpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver,
+ sizeof(drvinfo->fw_version) - 1);
+ kfree(ioc_attr);
+ }
+
+ strncpy(drvinfo->bus_info, pci_name(bnad->pcidev), ETHTOOL_BUSINFO_LEN);
+}
+
+static int
+get_regs(struct bnad *bnad, u32 * regs)
+{
+ int num = 0, i;
+ u32 reg_addr;
+ unsigned long flags;
+
+#define BNAD_GET_REG(addr) \
+do { \
+ if (regs) \
+ regs[num++] = readl(bnad->bar0 + (addr)); \
+ else \
+ num++; \
+} while (0)
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ /* DMA Block Internal Registers */
+ BNAD_GET_REG(DMA_CTRL_REG0);
+ BNAD_GET_REG(DMA_CTRL_REG1);
+ BNAD_GET_REG(DMA_ERR_INT_STATUS);
+ BNAD_GET_REG(DMA_ERR_INT_ENABLE);
+ BNAD_GET_REG(DMA_ERR_INT_STATUS_SET);
+
+ /* APP Block Register Address Offset from BAR0 */
+ BNAD_GET_REG(HOSTFN0_INT_STATUS);
+ BNAD_GET_REG(HOSTFN0_INT_MASK);
+ BNAD_GET_REG(HOST_PAGE_NUM_FN0);
+ BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN0);
+ BNAD_GET_REG(FN0_PCIE_ERR_REG);
+ BNAD_GET_REG(FN0_ERR_TYPE_STATUS_REG);
+ BNAD_GET_REG(FN0_ERR_TYPE_MSK_STATUS_REG);
+
+ BNAD_GET_REG(HOSTFN1_INT_STATUS);
+ BNAD_GET_REG(HOSTFN1_INT_MASK);
+ BNAD_GET_REG(HOST_PAGE_NUM_FN1);
+ BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN1);
+ BNAD_GET_REG(FN1_PCIE_ERR_REG);
+ BNAD_GET_REG(FN1_ERR_TYPE_STATUS_REG);
+ BNAD_GET_REG(FN1_ERR_TYPE_MSK_STATUS_REG);
+
+ BNAD_GET_REG(PCIE_MISC_REG);
+
+ BNAD_GET_REG(HOST_SEM0_REG);
+ BNAD_GET_REG(HOST_SEM1_REG);
+ BNAD_GET_REG(HOST_SEM2_REG);
+ BNAD_GET_REG(HOST_SEM3_REG);
+ BNAD_GET_REG(HOST_SEM0_INFO_REG);
+ BNAD_GET_REG(HOST_SEM1_INFO_REG);
+ BNAD_GET_REG(HOST_SEM2_INFO_REG);
+ BNAD_GET_REG(HOST_SEM3_INFO_REG);
+
+ BNAD_GET_REG(TEMPSENSE_CNTL_REG);
+ BNAD_GET_REG(TEMPSENSE_STAT_REG);
+
+ BNAD_GET_REG(APP_LOCAL_ERR_STAT);
+ BNAD_GET_REG(APP_LOCAL_ERR_MSK);
+
+ BNAD_GET_REG(PCIE_LNK_ERR_STAT);
+ BNAD_GET_REG(PCIE_LNK_ERR_MSK);
+
+ BNAD_GET_REG(FCOE_FIP_ETH_TYPE);
+ BNAD_GET_REG(RESV_ETH_TYPE);
+
+ BNAD_GET_REG(HOSTFN2_INT_STATUS);
+ BNAD_GET_REG(HOSTFN2_INT_MASK);
+ BNAD_GET_REG(HOST_PAGE_NUM_FN2);
+ BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN2);
+ BNAD_GET_REG(FN2_PCIE_ERR_REG);
+ BNAD_GET_REG(FN2_ERR_TYPE_STATUS_REG);
+ BNAD_GET_REG(FN2_ERR_TYPE_MSK_STATUS_REG);
+
+ BNAD_GET_REG(HOSTFN3_INT_STATUS);
+ BNAD_GET_REG(HOSTFN3_INT_MASK);
+ BNAD_GET_REG(HOST_PAGE_NUM_FN3);
+ BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN3);
+ BNAD_GET_REG(FN3_PCIE_ERR_REG);
+ BNAD_GET_REG(FN3_ERR_TYPE_STATUS_REG);
+ BNAD_GET_REG(FN3_ERR_TYPE_MSK_STATUS_REG);
+
+ /* Host Command Status Registers */
+ reg_addr = HOST_CMDSTS0_CLR_REG;
+ for (i = 0; i < 16; i++) {
+ BNAD_GET_REG(reg_addr);
+ BNAD_GET_REG(reg_addr + 4);
+ BNAD_GET_REG(reg_addr + 8);
+ reg_addr += 0x10;
+ }
+
+ /* Function ID register */
+ BNAD_GET_REG(FNC_ID_REG);
+
+ /* Function personality register */
+ BNAD_GET_REG(FNC_PERS_REG);
+
+ /* Operation mode register */
+ BNAD_GET_REG(OP_MODE);
+
+ /* LPU0 Registers */
+ BNAD_GET_REG(LPU0_MBOX_CTL_REG);
+ BNAD_GET_REG(LPU0_MBOX_CMD_REG);
+ BNAD_GET_REG(LPU0_MBOX_LINK_0REG);
+ BNAD_GET_REG(LPU1_MBOX_LINK_0REG);
+ BNAD_GET_REG(LPU0_MBOX_STATUS_0REG);
+ BNAD_GET_REG(LPU1_MBOX_STATUS_0REG);
+ BNAD_GET_REG(LPU0_ERR_STATUS_REG);
+ BNAD_GET_REG(LPU0_ERR_SET_REG);
+
+ /* LPU1 Registers */
+ BNAD_GET_REG(LPU1_MBOX_CTL_REG);
+ BNAD_GET_REG(LPU1_MBOX_CMD_REG);
+ BNAD_GET_REG(LPU0_MBOX_LINK_1REG);
+ BNAD_GET_REG(LPU1_MBOX_LINK_1REG);
+ BNAD_GET_REG(LPU0_MBOX_STATUS_1REG);
+ BNAD_GET_REG(LPU1_MBOX_STATUS_1REG);
+ BNAD_GET_REG(LPU1_ERR_STATUS_REG);
+ BNAD_GET_REG(LPU1_ERR_SET_REG);
+
+ /* PSS Registers */
+ BNAD_GET_REG(PSS_CTL_REG);
+ BNAD_GET_REG(PSS_ERR_STATUS_REG);
+ BNAD_GET_REG(ERR_STATUS_SET);
+ BNAD_GET_REG(PSS_RAM_ERR_STATUS_REG);
+
+ /* Catapult CPQ Registers */
+ BNAD_GET_REG(HOSTFN0_LPU0_MBOX0_CMD_STAT);
+ BNAD_GET_REG(HOSTFN0_LPU1_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN0_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN0_MBOX0_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN0_LPU0_MBOX1_CMD_STAT);
+ BNAD_GET_REG(HOSTFN0_LPU1_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN0_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN0_MBOX1_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN1_LPU0_MBOX0_CMD_STAT);
+ BNAD_GET_REG(HOSTFN1_LPU1_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN1_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN1_MBOX0_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN1_LPU0_MBOX1_CMD_STAT);
+ BNAD_GET_REG(HOSTFN1_LPU1_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN1_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN1_MBOX1_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN2_LPU0_MBOX0_CMD_STAT);
+ BNAD_GET_REG(HOSTFN2_LPU1_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN2_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN2_MBOX0_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN2_LPU0_MBOX1_CMD_STAT);
+ BNAD_GET_REG(HOSTFN2_LPU1_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN2_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN2_MBOX1_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN3_LPU0_MBOX0_CMD_STAT);
+ BNAD_GET_REG(HOSTFN3_LPU1_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN3_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN3_MBOX0_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN3_LPU0_MBOX1_CMD_STAT);
+ BNAD_GET_REG(HOSTFN3_LPU1_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN3_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN3_MBOX1_CMD_STAT);
+
+ /* Host Function Force Parity Error Registers */
+ BNAD_GET_REG(HOSTFN0_LPU_FORCE_PERR);
+ BNAD_GET_REG(HOSTFN1_LPU_FORCE_PERR);
+ BNAD_GET_REG(HOSTFN2_LPU_FORCE_PERR);
+ BNAD_GET_REG(HOSTFN3_LPU_FORCE_PERR);
+
+ /* LL Port[0|1] Halt Mask Registers */
+ BNAD_GET_REG(LL_HALT_MSK_P0);
+ BNAD_GET_REG(LL_HALT_MSK_P1);
+
+ /* LL Port[0|1] Error Mask Registers */
+ BNAD_GET_REG(LL_ERR_MSK_P0);
+ BNAD_GET_REG(LL_ERR_MSK_P1);
+
+ /* EMC FLI Registers */
+ BNAD_GET_REG(FLI_CMD_REG);
+ BNAD_GET_REG(FLI_ADDR_REG);
+ BNAD_GET_REG(FLI_CTL_REG);
+ BNAD_GET_REG(FLI_WRDATA_REG);
+ BNAD_GET_REG(FLI_RDDATA_REG);
+ BNAD_GET_REG(FLI_DEV_STATUS_REG);
+ BNAD_GET_REG(FLI_SIG_WD_REG);
+
+ BNAD_GET_REG(FLI_DEV_VENDOR_REG);
+ BNAD_GET_REG(FLI_ERR_STATUS_REG);
+
+ /* RxAdm 0 Registers */
+ BNAD_GET_REG(RAD0_CTL_REG);
+ BNAD_GET_REG(RAD0_PE_PARM_REG);
+ BNAD_GET_REG(RAD0_BCN_REG);
+ BNAD_GET_REG(RAD0_DEFAULT_REG);
+ BNAD_GET_REG(RAD0_PROMISC_REG);
+ BNAD_GET_REG(RAD0_BCNQ_REG);
+ BNAD_GET_REG(RAD0_DEFAULTQ_REG);
+
+ BNAD_GET_REG(RAD0_ERR_STS);
+ BNAD_GET_REG(RAD0_SET_ERR_STS);
+ BNAD_GET_REG(RAD0_ERR_INT_EN);
+ BNAD_GET_REG(RAD0_FIRST_ERR);
+ BNAD_GET_REG(RAD0_FORCE_ERR);
+
+ BNAD_GET_REG(RAD0_MAC_MAN_1H);
+ BNAD_GET_REG(RAD0_MAC_MAN_1L);
+ BNAD_GET_REG(RAD0_MAC_MAN_2H);
+ BNAD_GET_REG(RAD0_MAC_MAN_2L);
+ BNAD_GET_REG(RAD0_MAC_MAN_3H);
+ BNAD_GET_REG(RAD0_MAC_MAN_3L);
+ BNAD_GET_REG(RAD0_MAC_MAN_4H);
+ BNAD_GET_REG(RAD0_MAC_MAN_4L);
+
+ BNAD_GET_REG(RAD0_LAST4_IP);
+
+ /* RxAdm 1 Registers */
+ BNAD_GET_REG(RAD1_CTL_REG);
+ BNAD_GET_REG(RAD1_PE_PARM_REG);
+ BNAD_GET_REG(RAD1_BCN_REG);
+ BNAD_GET_REG(RAD1_DEFAULT_REG);
+ BNAD_GET_REG(RAD1_PROMISC_REG);
+ BNAD_GET_REG(RAD1_BCNQ_REG);
+ BNAD_GET_REG(RAD1_DEFAULTQ_REG);
+
+ BNAD_GET_REG(RAD1_ERR_STS);
+ BNAD_GET_REG(RAD1_SET_ERR_STS);
+ BNAD_GET_REG(RAD1_ERR_INT_EN);
+
+ /* TxA0 Registers */
+ BNAD_GET_REG(TXA0_CTRL_REG);
+ /* TxA0 TSO Sequence # Registers (RO) */
+ for (i = 0; i < 8; i++) {
+ BNAD_GET_REG(TXA0_TSO_TCP_SEQ_REG(i));
+ BNAD_GET_REG(TXA0_TSO_IP_INFO_REG(i));
+ }
+
+ /* TxA1 Registers */
+ BNAD_GET_REG(TXA1_CTRL_REG);
+ /* TxA1 TSO Sequence # Registers (RO) */
+ for (i = 0; i < 8; i++) {
+ BNAD_GET_REG(TXA1_TSO_TCP_SEQ_REG(i));
+ BNAD_GET_REG(TXA1_TSO_IP_INFO_REG(i));
+ }
+
+ /* RxA Registers */
+ BNAD_GET_REG(RXA0_CTL_REG);
+ BNAD_GET_REG(RXA1_CTL_REG);
+
+ /* PLB0 Registers */
+ BNAD_GET_REG(PLB0_ECM_TIMER_REG);
+ BNAD_GET_REG(PLB0_RL_CTL);
+ for (i = 0; i < 8; i++)
+ BNAD_GET_REG(PLB0_RL_MAX_BC(i));
+ BNAD_GET_REG(PLB0_RL_TU_PRIO);
+ for (i = 0; i < 8; i++)
+ BNAD_GET_REG(PLB0_RL_BYTE_CNT(i));
+ BNAD_GET_REG(PLB0_RL_MIN_REG);
+ BNAD_GET_REG(PLB0_RL_MAX_REG);
+ BNAD_GET_REG(PLB0_EMS_ADD_REG);
+
+ /* PLB1 Registers */
+ BNAD_GET_REG(PLB1_ECM_TIMER_REG);
+ BNAD_GET_REG(PLB1_RL_CTL);
+ for (i = 0; i < 8; i++)
+ BNAD_GET_REG(PLB1_RL_MAX_BC(i));
+ BNAD_GET_REG(PLB1_RL_TU_PRIO);
+ for (i = 0; i < 8; i++)
+ BNAD_GET_REG(PLB1_RL_BYTE_CNT(i));
+ BNAD_GET_REG(PLB1_RL_MIN_REG);
+ BNAD_GET_REG(PLB1_RL_MAX_REG);
+ BNAD_GET_REG(PLB1_EMS_ADD_REG);
+
+ /* HQM Control Register */
+ BNAD_GET_REG(HQM0_CTL_REG);
+ BNAD_GET_REG(HQM0_RXQ_STOP_SEM);
+ BNAD_GET_REG(HQM0_TXQ_STOP_SEM);
+ BNAD_GET_REG(HQM1_CTL_REG);
+ BNAD_GET_REG(HQM1_RXQ_STOP_SEM);
+ BNAD_GET_REG(HQM1_TXQ_STOP_SEM);
+
+ /* LUT Registers */
+ BNAD_GET_REG(LUT0_ERR_STS);
+ BNAD_GET_REG(LUT0_SET_ERR_STS);
+ BNAD_GET_REG(LUT1_ERR_STS);
+ BNAD_GET_REG(LUT1_SET_ERR_STS);
+
+ /* TRC Registers */
+ BNAD_GET_REG(TRC_CTL_REG);
+ BNAD_GET_REG(TRC_MODS_REG);
+ BNAD_GET_REG(TRC_TRGC_REG);
+ BNAD_GET_REG(TRC_CNT1_REG);
+ BNAD_GET_REG(TRC_CNT2_REG);
+ BNAD_GET_REG(TRC_NXTS_REG);
+ BNAD_GET_REG(TRC_DIRR_REG);
+ for (i = 0; i < 10; i++)
+ BNAD_GET_REG(TRC_TRGM_REG(i));
+ for (i = 0; i < 10; i++)
+ BNAD_GET_REG(TRC_NXTM_REG(i));
+ for (i = 0; i < 10; i++)
+ BNAD_GET_REG(TRC_STRM_REG(i));
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+#undef BNAD_GET_REG
+ return num;
+}
+static int
+bnad_get_regs_len(struct net_device *netdev)
+{
+ int ret = get_regs(netdev_priv(netdev), NULL) * sizeof(u32);
+ return ret;
+}
+
+static void
+bnad_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
+{
+ memset(buf, 0, bnad_get_regs_len(netdev));
+ get_regs(netdev_priv(netdev), buf);
+}
+
+static void
+bnad_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wolinfo)
+{
+ wolinfo->supported = 0;
+ wolinfo->wolopts = 0;
+}
+
+static int
+bnad_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+
+ /* Lock rqd. to access bnad->bna_lock */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ coalesce->use_adaptive_rx_coalesce =
+ (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) ? true : false;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ coalesce->rx_coalesce_usecs = bnad->rx_coalescing_timeo *
+ BFI_COALESCING_TIMER_UNIT;
+ coalesce->tx_coalesce_usecs = bnad->tx_coalescing_timeo *
+ BFI_COALESCING_TIMER_UNIT;
+ coalesce->tx_max_coalesced_frames = BFI_TX_INTERPKT_COUNT;
+
+ return 0;
+}
+
+static int
+bnad_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+ int dim_timer_del = 0;
+
+ if (coalesce->rx_coalesce_usecs == 0 ||
+ coalesce->rx_coalesce_usecs >
+ BFI_MAX_COALESCING_TIMEO * BFI_COALESCING_TIMER_UNIT)
+ return -EINVAL;
+
+ if (coalesce->tx_coalesce_usecs == 0 ||
+ coalesce->tx_coalesce_usecs >
+ BFI_MAX_COALESCING_TIMEO * BFI_COALESCING_TIMER_UNIT)
+ return -EINVAL;
+
+ mutex_lock(&bnad->conf_mutex);
+ /*
+ * Do not need to store rx_coalesce_usecs here
+ * Every time DIM is disabled, we can get it from the
+ * stack.
+ */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (coalesce->use_adaptive_rx_coalesce) {
+ if (!(bnad->cfg_flags & BNAD_CF_DIM_ENABLED)) {
+ bnad->cfg_flags |= BNAD_CF_DIM_ENABLED;
+ bnad_dim_timer_start(bnad);
+ }
+ } else {
+ if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) {
+ bnad->cfg_flags &= ~BNAD_CF_DIM_ENABLED;
+ dim_timer_del = bnad_dim_timer_running(bnad);
+ if (dim_timer_del) {
+ clear_bit(BNAD_RF_DIM_TIMER_RUNNING,
+ &bnad->run_flags);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ del_timer_sync(&bnad->dim_timer);
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ }
+ bnad_rx_coalescing_timeo_set(bnad);
+ }
+ }
+ if (bnad->tx_coalescing_timeo != coalesce->tx_coalesce_usecs /
+ BFI_COALESCING_TIMER_UNIT) {
+ bnad->tx_coalescing_timeo = coalesce->tx_coalesce_usecs /
+ BFI_COALESCING_TIMER_UNIT;
+ bnad_tx_coalescing_timeo_set(bnad);
+ }
+
+ if (bnad->rx_coalescing_timeo != coalesce->rx_coalesce_usecs /
+ BFI_COALESCING_TIMER_UNIT) {
+ bnad->rx_coalescing_timeo = coalesce->rx_coalesce_usecs /
+ BFI_COALESCING_TIMER_UNIT;
+
+ if (!(bnad->cfg_flags & BNAD_CF_DIM_ENABLED))
+ bnad_rx_coalescing_timeo_set(bnad);
+
+ }
+
+ /* Add Tx Inter-pkt DMA count? */
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+ return 0;
+}
+
+static void
+bnad_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ringparam)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ ringparam->rx_max_pending = BNAD_MAX_Q_DEPTH / bnad_rxqs_per_cq;
+ ringparam->rx_mini_max_pending = 0;
+ ringparam->rx_jumbo_max_pending = 0;
+ ringparam->tx_max_pending = BNAD_MAX_Q_DEPTH;
+
+ ringparam->rx_pending = bnad->rxq_depth;
+ ringparam->rx_mini_max_pending = 0;
+ ringparam->rx_jumbo_max_pending = 0;
+ ringparam->tx_pending = bnad->txq_depth;
+}
+
+static int
+bnad_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ringparam)
+{
+ int i, current_err, err = 0;
+ struct bnad *bnad = netdev_priv(netdev);
+
+ mutex_lock(&bnad->conf_mutex);
+ if (ringparam->rx_pending == bnad->rxq_depth &&
+ ringparam->tx_pending == bnad->txq_depth) {
+ mutex_unlock(&bnad->conf_mutex);
+ return 0;
+ }
+
+ if (ringparam->rx_pending < BNAD_MIN_Q_DEPTH ||
+ ringparam->rx_pending > BNAD_MAX_Q_DEPTH / bnad_rxqs_per_cq ||
+ !BNA_POWER_OF_2(ringparam->rx_pending)) {
+ mutex_unlock(&bnad->conf_mutex);
+ return -EINVAL;
+ }
+ if (ringparam->tx_pending < BNAD_MIN_Q_DEPTH ||
+ ringparam->tx_pending > BNAD_MAX_Q_DEPTH ||
+ !BNA_POWER_OF_2(ringparam->tx_pending)) {
+ mutex_unlock(&bnad->conf_mutex);
+ return -EINVAL;
+ }
+
+ if (ringparam->rx_pending != bnad->rxq_depth) {
+ bnad->rxq_depth = ringparam->rx_pending;
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ bnad_cleanup_rx(bnad, i);
+ current_err = bnad_setup_rx(bnad, i);
+ if (current_err && !err)
+ err = current_err;
+ }
+ }
+ if (ringparam->tx_pending != bnad->txq_depth) {
+ bnad->txq_depth = ringparam->tx_pending;
+ for (i = 0; i < bnad->num_tx; i++) {
+ if (!bnad->tx_info[i].tx)
+ continue;
+ bnad_cleanup_tx(bnad, i);
+ current_err = bnad_setup_tx(bnad, i);
+ if (current_err && !err)
+ err = current_err;
+ }
+ }
+
+ mutex_unlock(&bnad->conf_mutex);
+ return err;
+}
+
+static void
+bnad_get_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pauseparam)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ pauseparam->autoneg = 0;
+ pauseparam->rx_pause = bnad->bna.port.pause_config.rx_pause;
+ pauseparam->tx_pause = bnad->bna.port.pause_config.tx_pause;
+}
+
+static int
+bnad_set_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pauseparam)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bna_pause_config pause_config;
+ unsigned long flags;
+
+ if (pauseparam->autoneg == AUTONEG_ENABLE)
+ return -EINVAL;
+
+ mutex_lock(&bnad->conf_mutex);
+ if (pauseparam->rx_pause != bnad->bna.port.pause_config.rx_pause ||
+ pauseparam->tx_pause != bnad->bna.port.pause_config.tx_pause) {
+ pause_config.rx_pause = pauseparam->rx_pause;
+ pause_config.tx_pause = pauseparam->tx_pause;
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_port_pause_config(&bnad->bna.port, &pause_config, NULL);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ }
+ mutex_unlock(&bnad->conf_mutex);
+ 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)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ int i, j, q_num;
+ u64 bmap;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < BNAD_ETHTOOL_STATS_NUM; i++) {
+ BUG_ON(!(strlen(bnad_net_stats_strings[i]) <
+ ETH_GSTRING_LEN));
+ memcpy(string, bnad_net_stats_strings[i],
+ ETH_GSTRING_LEN);
+ string += ETH_GSTRING_LEN;
+ }
+ bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] |
+ ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) {
+ if (bmap & 1) {
+ sprintf(string, "txf%d_ucast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_ucast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_ucast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_mcast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_mcast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_mcast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_bcast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_bcast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_bcast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_errors", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_filter_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_filter_mac_sa", i);
+ string += ETH_GSTRING_LEN;
+ }
+ bmap >>= 1;
+ }
+
+ bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] |
+ ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+ if (bmap & 1) {
+ sprintf(string, "rxf%d_ucast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_ucast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_ucast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_mcast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_mcast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_mcast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_bcast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_bcast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_bcast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_frame_drops", i);
+ string += ETH_GSTRING_LEN;
+ }
+ bmap >>= 1;
+ }
+
+ q_num = 0;
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ sprintf(string, "cq%d_producer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "cq%d_consumer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "cq%d_hw_producer_index",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ q_num++;
+ }
+ }
+
+ q_num = 0;
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ sprintf(string, "rxq%d_packets", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_bytes", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_packets_with_error",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_allocbuf_failed", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_producer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_consumer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ q_num++;
+ if (bnad->rx_info[i].rx_ctrl[j].ccb &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->
+ rcb[1] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->
+ rcb[1]->rxq) {
+ sprintf(string, "rxq%d_packets", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_bytes", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string,
+ "rxq%d_packets_with_error", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_allocbuf_failed",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_producer_index",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_consumer_index",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ q_num++;
+ }
+ }
+ }
+
+ q_num = 0;
+ for (i = 0; i < bnad->num_tx; i++) {
+ if (!bnad->tx_info[i].tx)
+ continue;
+ for (j = 0; j < bnad->num_txq_per_tx; j++) {
+ sprintf(string, "txq%d_packets", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txq%d_bytes", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txq%d_producer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txq%d_consumer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txq%d_hw_consumer_index",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ q_num++;
+ }
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ mutex_unlock(&bnad->conf_mutex);
+}
+
+static int
+bnad_get_stats_count_locked(struct net_device *netdev)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ int i, j, count, rxf_active_num = 0, txf_active_num = 0;
+ u64 bmap;
+
+ bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] |
+ ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) {
+ if (bmap & 1)
+ txf_active_num++;
+ bmap >>= 1;
+ }
+ bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] |
+ ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+ if (bmap & 1)
+ rxf_active_num++;
+ bmap >>= 1;
+ }
+ count = BNAD_ETHTOOL_STATS_NUM +
+ txf_active_num * BNAD_NUM_TXF_COUNTERS +
+ rxf_active_num * BNAD_NUM_RXF_COUNTERS;
+
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ count += bnad->num_rxp_per_rx * BNAD_NUM_CQ_COUNTERS;
+ count += bnad->num_rxp_per_rx * BNAD_NUM_RXQ_COUNTERS;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++)
+ if (bnad->rx_info[i].rx_ctrl[j].ccb &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1]->rxq)
+ count += BNAD_NUM_RXQ_COUNTERS;
+ }
+
+ for (i = 0; i < bnad->num_tx; i++) {
+ if (!bnad->tx_info[i].tx)
+ continue;
+ count += bnad->num_txq_per_tx * BNAD_NUM_TXQ_COUNTERS;
+ }
+ return count;
+}
+
+static int
+bnad_per_q_stats_fill(struct bnad *bnad, u64 *buf, int bi)
+{
+ int i, j;
+ struct bna_rcb *rcb = NULL;
+ struct bna_tcb *tcb = NULL;
+
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++)
+ if (bnad->rx_info[i].rx_ctrl[j].ccb &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0]->rxq) {
+ buf[bi++] = bnad->rx_info[i].rx_ctrl[j].
+ ccb->producer_index;
+ buf[bi++] = 0; /* ccb->consumer_index */
+ buf[bi++] = *(bnad->rx_info[i].rx_ctrl[j].
+ ccb->hw_producer_index);
+ }
+ }
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++)
+ if (bnad->rx_info[i].rx_ctrl[j].ccb) {
+ if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->
+ rcb[0]->rxq) {
+ rcb = bnad->rx_info[i].rx_ctrl[j].
+ ccb->rcb[0];
+ buf[bi++] = rcb->rxq->rx_packets;
+ buf[bi++] = rcb->rxq->rx_bytes;
+ buf[bi++] = rcb->rxq->
+ rx_packets_with_error;
+ buf[bi++] = rcb->rxq->
+ rxbuf_alloc_failed;
+ buf[bi++] = rcb->producer_index;
+ buf[bi++] = rcb->consumer_index;
+ }
+ if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->
+ rcb[1]->rxq) {
+ rcb = bnad->rx_info[i].rx_ctrl[j].
+ ccb->rcb[1];
+ buf[bi++] = rcb->rxq->rx_packets;
+ buf[bi++] = rcb->rxq->rx_bytes;
+ buf[bi++] = rcb->rxq->
+ rx_packets_with_error;
+ buf[bi++] = rcb->rxq->
+ rxbuf_alloc_failed;
+ buf[bi++] = rcb->producer_index;
+ buf[bi++] = rcb->consumer_index;
+ }
+ }
+ }
+
+ for (i = 0; i < bnad->num_tx; i++) {
+ if (!bnad->tx_info[i].tx)
+ continue;
+ for (j = 0; j < bnad->num_txq_per_tx; j++)
+ if (bnad->tx_info[i].tcb[j] &&
+ bnad->tx_info[i].tcb[j]->txq) {
+ tcb = bnad->tx_info[i].tcb[j];
+ buf[bi++] = tcb->txq->tx_packets;
+ buf[bi++] = tcb->txq->tx_bytes;
+ buf[bi++] = tcb->producer_index;
+ buf[bi++] = tcb->consumer_index;
+ buf[bi++] = *(tcb->hw_consumer_index);
+ }
+ }
+
+ return bi;
+}
+
+static void
+bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats,
+ u64 *buf)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ int i, j, bi;
+ unsigned long flags;
+ struct rtnl_link_stats64 *net_stats64;
+ u64 *stats64;
+ u64 bmap;
+
+ mutex_lock(&bnad->conf_mutex);
+ if (bnad_get_stats_count_locked(netdev) != stats->n_stats) {
+ mutex_unlock(&bnad->conf_mutex);
+ return;
+ }
+
+ /*
+ * Used bna_lock to sync reads from bna_stats, which is written
+ * under the same lock
+ */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bi = 0;
+ memset(buf, 0, stats->n_stats * sizeof(u64));
+
+ net_stats64 = (struct rtnl_link_stats64 *)buf;
+ bnad_netdev_qstats_fill(bnad, net_stats64);
+ bnad_netdev_hwstats_fill(bnad, net_stats64);
+
+ bi = sizeof(*net_stats64) / sizeof(u64);
+
+ /* Fill driver stats into ethtool buffers */
+ stats64 = (u64 *)&bnad->stats.drv_stats;
+ for (i = 0; i < sizeof(struct bnad_drv_stats) / sizeof(u64); i++)
+ buf[bi++] = stats64[i];
+
+ /* Fill hardware stats excluding the rxf/txf into ethtool bufs */
+ stats64 = (u64 *) bnad->stats.bna_stats->hw_stats;
+ for (i = 0;
+ i < offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64);
+ i++)
+ buf[bi++] = stats64[i];
+
+ /* Fill txf stats into ethtool buffers */
+ bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] |
+ ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) {
+ if (bmap & 1) {
+ stats64 = (u64 *)&bnad->stats.bna_stats->
+ hw_stats->txf_stats[i];
+ for (j = 0; j < sizeof(struct bfi_ll_stats_txf) /
+ sizeof(u64); j++)
+ buf[bi++] = stats64[j];
+ }
+ bmap >>= 1;
+ }
+
+ /* Fill rxf stats into ethtool buffers */
+ bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] |
+ ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+ if (bmap & 1) {
+ stats64 = (u64 *)&bnad->stats.bna_stats->
+ hw_stats->rxf_stats[i];
+ for (j = 0; j < sizeof(struct bfi_ll_stats_rxf) /
+ sizeof(u64); j++)
+ buf[bi++] = stats64[j];
+ }
+ bmap >>= 1;
+ }
+
+ /* Fill per Q stats into ethtool buffers */
+ bi = bnad_per_q_stats_fill(bnad, buf, bi);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+}
+
+static int
+bnad_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return bnad_get_stats_count_locked(netdev);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static struct ethtool_ops bnad_ethtool_ops = {
+ .get_settings = bnad_get_settings,
+ .set_settings = bnad_set_settings,
+ .get_drvinfo = bnad_get_drvinfo,
+ .get_regs_len = bnad_get_regs_len,
+ .get_regs = bnad_get_regs,
+ .get_wol = bnad_get_wol,
+ .get_link = ethtool_op_get_link,
+ .get_coalesce = bnad_get_coalesce,
+ .set_coalesce = bnad_set_coalesce,
+ .get_ringparam = bnad_get_ringparam,
+ .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
+};
+
+void
+bnad_set_ethtool_ops(struct net_device *netdev)
+{
+ SET_ETHTOOL_OPS(netdev, &bnad_ethtool_ops);
+}
diff --git a/drivers/net/bna/cna.h b/drivers/net/bna/cna.h
new file mode 100644
index 000000000000..bbd39dc65972
--- /dev/null
+++ b/drivers/net/bna/cna.h
@@ -0,0 +1,81 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2006-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __CNA_H__
+#define __CNA_H__
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/string.h>
+
+#include <linux/list.h>
+
+#define bfa_sm_fault(__mod, __event) do { \
+ pr_err("SM Assertion failure: %s: %d: event = %d", __FILE__, __LINE__, \
+ __event); \
+} while (0)
+
+extern char bfa_version[];
+
+#define CNA_FW_FILE_CT "ctfw_cna.bin"
+#define FC_SYMNAME_MAX 256 /*!< max name server symbolic name size */
+
+#pragma pack(1)
+
+#define MAC_ADDRLEN (6)
+typedef struct mac { u8 mac[MAC_ADDRLEN]; } mac_t;
+
+#pragma pack()
+
+#define bfa_q_first(_q) ((void *)(((struct list_head *) (_q))->next))
+#define bfa_q_next(_qe) (((struct list_head *) (_qe))->next)
+#define bfa_q_prev(_qe) (((struct list_head *) (_qe))->prev)
+
+/*
+ * bfa_q_qe_init - to initialize a queue element
+ */
+#define bfa_q_qe_init(_qe) { \
+ bfa_q_next(_qe) = (struct list_head *) NULL; \
+ bfa_q_prev(_qe) = (struct list_head *) NULL; \
+}
+
+/*
+ * bfa_q_deq - dequeue an element from head of the queue
+ */
+#define bfa_q_deq(_q, _qe) { \
+ if (!list_empty(_q)) { \
+ (*((struct list_head **) (_qe))) = bfa_q_next(_q); \
+ bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \
+ (struct list_head *) (_q); \
+ bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe)); \
+ bfa_q_qe_init(*((struct list_head **) _qe)); \
+ } else { \
+ *((struct list_head **) (_qe)) = (struct list_head *) NULL; \
+ } \
+}
+
+#endif /* __CNA_H__ */
diff --git a/drivers/net/bna/cna_fwimg.c b/drivers/net/bna/cna_fwimg.c
new file mode 100644
index 000000000000..e8f4ecd9ebb5
--- /dev/null
+++ b/drivers/net/bna/cna_fwimg.c
@@ -0,0 +1,64 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#include <linux/firmware.h>
+#include "cna.h"
+
+const struct firmware *bfi_fw;
+static u32 *bfi_image_ct_cna;
+static u32 bfi_image_ct_cna_size;
+
+static u32 *
+cna_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
+ u32 *bfi_image_size, char *fw_name)
+{
+ const struct firmware *fw;
+
+ if (request_firmware(&fw, fw_name, &pdev->dev)) {
+ pr_alert("Can't locate firmware %s\n", fw_name);
+ goto error;
+ }
+
+ *bfi_image = (u32 *)fw->data;
+ *bfi_image_size = fw->size/sizeof(u32);
+ bfi_fw = fw;
+
+ return *bfi_image;
+error:
+ return NULL;
+}
+
+u32 *
+cna_get_firmware_buf(struct pci_dev *pdev)
+{
+ if (bfi_image_ct_cna_size == 0)
+ cna_read_firmware(pdev, &bfi_image_ct_cna,
+ &bfi_image_ct_cna_size, CNA_FW_FILE_CT);
+ return bfi_image_ct_cna;
+}
+
+u32 *
+bfa_cb_image_get_chunk(int type, u32 off)
+{
+ return (u32 *)(bfi_image_ct_cna + off);
+}
+
+u32
+bfa_cb_image_get_size(int type)
+{
+ return bfi_image_ct_cna_size;
+}
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index e6a803f1c507..062600be073b 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -37,9 +37,6 @@
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define BCM_VLAN 1
-#endif
#include <net/ip.h>
#include <net/tcp.h>
#include <net/checksum.h>
@@ -49,6 +46,7 @@
#include <linux/cache.h>
#include <linux/firmware.h>
#include <linux/log2.h>
+#include <linux/aer.h>
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#define BCM_CNIC 1
@@ -58,13 +56,13 @@
#include "bnx2_fw.h"
#define DRV_MODULE_NAME "bnx2"
-#define DRV_MODULE_VERSION "2.0.17"
-#define DRV_MODULE_RELDATE "July 18, 2010"
-#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-5.0.0.j6.fw"
-#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-5.0.0.j3.fw"
-#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-5.0.0.j15.fw"
-#define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw"
-#define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-5.0.0.j10.fw"
+#define DRV_MODULE_VERSION "2.0.18"
+#define DRV_MODULE_RELDATE "Oct 7, 2010"
+#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.0.15.fw"
+#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw"
+#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.0.17.fw"
+#define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-6.0.17.fw"
+#define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-6.0.17.fw"
#define RUN_AT(x) (jiffies + (x))
@@ -265,7 +263,7 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
if (diff == TX_DESC_CNT)
diff = MAX_TX_DESC_CNT;
}
- return (bp->tx_ring_size - diff);
+ return bp->tx_ring_size - diff;
}
static u32
@@ -298,7 +296,7 @@ bnx2_shmem_wr(struct bnx2 *bp, u32 offset, u32 val)
static u32
bnx2_shmem_rd(struct bnx2 *bp, u32 offset)
{
- return (bnx2_reg_rd_ind(bp, bp->shmem_base + offset));
+ return bnx2_reg_rd_ind(bp, bp->shmem_base + offset);
}
static void
@@ -976,9 +974,9 @@ bnx2_report_fw_link(struct bnx2 *bp)
static char *
bnx2_xceiver_str(struct bnx2 *bp)
{
- return ((bp->phy_port == PORT_FIBRE) ? "SerDes" :
+ return (bp->phy_port == PORT_FIBRE) ? "SerDes" :
((bp->phy_flags & BNX2_PHY_FLAG_SERDES) ? "Remote Copper" :
- "Copper"));
+ "Copper");
}
static void
@@ -1268,30 +1266,9 @@ bnx2_init_rx_context(struct bnx2 *bp, u32 cid)
val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
val |= 0x02 << 8;
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- u32 lo_water, hi_water;
-
- if (bp->flow_ctrl & FLOW_CTRL_TX)
- lo_water = BNX2_L2CTX_LO_WATER_MARK_DEFAULT;
- else
- lo_water = BNX2_L2CTX_LO_WATER_MARK_DIS;
- if (lo_water >= bp->rx_ring_size)
- lo_water = 0;
-
- hi_water = min_t(int, bp->rx_ring_size / 4, lo_water + 16);
-
- if (hi_water <= lo_water)
- lo_water = 0;
-
- hi_water /= BNX2_L2CTX_HI_WATER_MARK_SCALE;
- lo_water /= BNX2_L2CTX_LO_WATER_MARK_SCALE;
+ if (bp->flow_ctrl & FLOW_CTRL_TX)
+ val |= BNX2_L2CTX_FLOW_CTRL_ENABLE;
- if (hi_water > 0xf)
- hi_water = 0xf;
- else if (hi_water == 0)
- lo_water = 0;
- val |= lo_water | (hi_water << BNX2_L2CTX_HI_WATER_MARK_SHIFT);
- }
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
}
@@ -1372,8 +1349,7 @@ bnx2_set_mac_link(struct bnx2 *bp)
/* Acknowledge the interrupt. */
REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- bnx2_init_all_rx_contexts(bp);
+ bnx2_init_all_rx_contexts(bp);
}
static void
@@ -1757,7 +1733,7 @@ __acquires(&bp->phy_lock)
u32 new_adv = 0;
if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
- return (bnx2_setup_remote_phy(bp, port));
+ return bnx2_setup_remote_phy(bp, port);
if (!(bp->autoneg & AUTONEG_SPEED)) {
u32 new_bmcr;
@@ -2170,10 +2146,10 @@ __acquires(&bp->phy_lock)
return 0;
if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
- return (bnx2_setup_serdes_phy(bp, port));
+ return bnx2_setup_serdes_phy(bp, port);
}
else {
- return (bnx2_setup_copper_phy(bp));
+ return bnx2_setup_copper_phy(bp);
}
}
@@ -3108,8 +3084,6 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
struct sw_bd *rx_buf, *next_rx_buf;
struct sk_buff *skb;
dma_addr_t dma_addr;
- u16 vtag = 0;
- int hw_vlan __maybe_unused = 0;
sw_ring_cons = RX_RING_IDX(sw_cons);
sw_ring_prod = RX_RING_IDX(sw_prod);
@@ -3189,23 +3163,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
goto next_rx;
if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
- !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
- vtag = rx_hdr->l2_fhdr_vlan_tag;
-#ifdef BCM_VLAN
- if (bp->vlgrp)
- hw_vlan = 1;
- else
-#endif
- {
- struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
- __skb_push(skb, 4);
-
- memmove(ve, skb->data + 4, ETH_ALEN * 2);
- ve->h_vlan_proto = htons(ETH_P_8021Q);
- ve->h_vlan_TCI = htons(vtag);
- len += 4;
- }
- }
+ !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG))
+ __vlan_hwaccel_put_tag(skb, rx_hdr->l2_fhdr_vlan_tag);
skb->protocol = eth_type_trans(skb, bp->dev);
@@ -3217,7 +3176,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
}
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (bp->rx_csum &&
(status & (L2_FHDR_STATUS_TCP_SEGMENT |
L2_FHDR_STATUS_UDP_DATAGRAM))) {
@@ -3232,14 +3191,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
skb->rxhash = rx_hdr->l2_fhdr_hash;
skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]);
-
-#ifdef BCM_VLAN
- if (hw_vlan)
- vlan_gro_receive(&bnapi->napi, bp->vlgrp, vtag, skb);
- else
-#endif
- napi_gro_receive(&bnapi->napi, skb);
-
+ napi_gro_receive(&bnapi->napi, skb);
rx_pkt++;
next_rx:
@@ -3554,13 +3506,9 @@ bnx2_set_rx_mode(struct net_device *dev)
rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS |
BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
-#ifdef BCM_VLAN
- if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
+ if (!(dev->features & NETIF_F_HW_VLAN_RX) &&
+ (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
-#else
- if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
- rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
-#endif
if (dev->flags & IFF_PROMISC) {
/* Promiscuous mode. */
rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
@@ -4973,6 +4921,11 @@ bnx2_init_chip(struct bnx2 *bp)
REG_WR(bp, BNX2_HC_CONFIG, val);
+ if (bp->rx_ticks < 25)
+ bnx2_reg_wr_ind(bp, BNX2_FW_RX_LOW_LATENCY, 1);
+ else
+ bnx2_reg_wr_ind(bp, BNX2_FW_RX_LOW_LATENCY, 0);
+
for (i = 1; i < bp->irq_nvecs; i++) {
u32 base = ((i - 1) * BNX2_HC_SB_CONFIG_SIZE) +
BNX2_HC_SB_CONFIG_1;
@@ -5241,18 +5194,20 @@ bnx2_init_all_rings(struct bnx2 *bp)
bnx2_init_rx_ring(bp, i);
if (bp->num_rx_rings > 1) {
- u32 tbl_32;
- u8 *tbl = (u8 *) &tbl_32;
-
- bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ,
- BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES);
+ u32 tbl_32 = 0;
for (i = 0; i < BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES; i++) {
- tbl[i % 4] = i % (bp->num_rx_rings - 1);
- if ((i % 4) == 3)
- bnx2_reg_wr_ind(bp,
- BNX2_RXP_SCRATCH_RSS_TBL + i,
- cpu_to_be32(tbl_32));
+ int shift = (i % 8) << 2;
+
+ tbl_32 |= (i % (bp->num_rx_rings - 1)) << shift;
+ if ((i % 8) == 7) {
+ REG_WR(bp, BNX2_RLUP_RSS_DATA, tbl_32);
+ REG_WR(bp, BNX2_RLUP_RSS_COMMAND, (i >> 3) |
+ BNX2_RLUP_RSS_COMMAND_RSS_WRITE_MASK |
+ BNX2_RLUP_RSS_COMMAND_WRITE |
+ BNX2_RLUP_RSS_COMMAND_HASH_MASK);
+ tbl_32 = 0;
+ }
}
val = BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI |
@@ -6201,7 +6156,7 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
}
}
-static void
+static int
bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
{
int cpus = num_online_cpus();
@@ -6230,9 +6185,10 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
}
bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs);
- bp->dev->real_num_tx_queues = bp->num_tx_rings;
+ netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings);
bp->num_rx_rings = bp->irq_nvecs;
+ return netif_set_real_num_rx_queues(bp->dev, bp->num_rx_rings);
}
/* Called with rtnl_lock */
@@ -6247,7 +6203,9 @@ bnx2_open(struct net_device *dev)
bnx2_set_power_state(bp, PCI_D0);
bnx2_disable_int(bp);
- bnx2_setup_int_mode(bp, disable_msi);
+ rc = bnx2_setup_int_mode(bp, disable_msi);
+ if (rc)
+ goto open_err;
bnx2_init_napi(bp);
bnx2_napi_enable(bp);
rc = bnx2_alloc_mem(bp);
@@ -6376,29 +6334,6 @@ bnx2_tx_timeout(struct net_device *dev)
schedule_work(&bp->reset_task);
}
-#ifdef BCM_VLAN
-/* Called with rtnl_lock */
-static void
-bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
-{
- struct bnx2 *bp = netdev_priv(dev);
-
- if (netif_running(dev))
- bnx2_netif_stop(bp, false);
-
- bp->vlgrp = vlgrp;
-
- if (!netif_running(dev))
- return;
-
- bnx2_set_rx_mode(dev);
- if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
- bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
-
- bnx2_netif_start(bp, false);
-}
-#endif
-
/* Called with netif_tx_lock.
* bnx2_tx_int() runs without netif_tx_lock unless it needs to call
* netif_wake_queue().
@@ -6439,12 +6374,11 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
}
-#ifdef BCM_VLAN
- if (bp->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
vlan_tag_flags |=
(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
}
-#endif
+
if ((mss = skb_shinfo(skb)->gso_size)) {
u32 tcp_opt_len;
struct iphdr *iph;
@@ -7581,15 +7515,36 @@ bnx2_set_tx_csum(struct net_device *dev, u32 data)
struct bnx2 *bp = netdev_priv(dev);
if (CHIP_NUM(bp) == CHIP_NUM_5709)
- return (ethtool_op_set_tx_ipv6_csum(dev, data));
+ return ethtool_op_set_tx_ipv6_csum(dev, data);
else
- return (ethtool_op_set_tx_csum(dev, data));
+ return ethtool_op_set_tx_csum(dev, data);
}
static int
bnx2_set_flags(struct net_device *dev, u32 data)
{
- return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH);
+ struct bnx2 *bp = netdev_priv(dev);
+ int rc;
+
+ if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) &&
+ !(data & ETH_FLAG_RXVLAN))
+ return -EINVAL;
+
+ rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN |
+ ETH_FLAG_TXVLAN);
+ if (rc)
+ return rc;
+
+ if ((!!(data & ETH_FLAG_RXVLAN) !=
+ !!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) &&
+ netif_running(dev)) {
+ bnx2_netif_stop(bp, false);
+ bnx2_set_rx_mode(dev);
+ bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
+ bnx2_netif_start(bp, false);
+ }
+
+ return 0;
}
static const struct ethtool_ops bnx2_ethtool_ops = {
@@ -7704,7 +7659,7 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
dev->mtu = new_mtu;
- return (bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size));
+ return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -7890,6 +7845,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
int rc, i, j;
u32 reg;
u64 dma_mask, persist_dma_mask;
+ int err;
SET_NETDEV_DEV(dev, &pdev->dev);
bp = netdev_priv(dev);
@@ -7926,7 +7882,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
}
pci_set_master(pdev);
- pci_save_state(pdev);
bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
if (bp->pm_cap == 0) {
@@ -7981,6 +7936,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->flags |= BNX2_FLAG_PCIE;
if (CHIP_REV(bp) == CHIP_REV_Ax)
bp->flags |= BNX2_FLAG_JUMBO_BROKEN;
+
+ /* AER (Advanced Error Reporting) hooks */
+ err = pci_enable_pcie_error_reporting(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "pci_enable_pcie_error_reporting "
+ "failed 0x%x\n", err);
+ /* non-fatal, continue */
+ }
+
} else {
bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
if (bp->pcix_cap == 0) {
@@ -8237,9 +8201,14 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->timer.data = (unsigned long) bp;
bp->timer.function = bnx2_timer;
+ pci_save_state(pdev);
+
return 0;
err_out_unmap:
+ if (bp->flags & BNX2_FLAG_PCIE)
+ pci_disable_pcie_error_reporting(pdev);
+
if (bp->regview) {
iounmap(bp->regview);
bp->regview = NULL;
@@ -8315,9 +8284,6 @@ static const struct net_device_ops bnx2_netdev_ops = {
.ndo_set_mac_address = bnx2_change_mac_addr,
.ndo_change_mtu = bnx2_change_mtu,
.ndo_tx_timeout = bnx2_tx_timeout,
-#ifdef BCM_VLAN
- .ndo_vlan_rx_register = bnx2_vlan_rx_register,
-#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = poll_bnx2,
#endif
@@ -8325,9 +8291,7 @@ static const struct net_device_ops bnx2_netdev_ops = {
static void inline vlan_features_add(struct net_device *dev, unsigned long flags)
{
-#ifdef BCM_VLAN
dev->vlan_features |= flags;
-#endif
}
static int __devinit
@@ -8376,9 +8340,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->features |= NETIF_F_IPV6_CSUM;
vlan_features_add(dev, NETIF_F_IPV6_CSUM);
}
-#ifdef BCM_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-#endif
dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
vlan_features_add(dev, NETIF_F_TSO | NETIF_F_TSO_ECN);
if (CHIP_NUM(bp) == CHIP_NUM_5709) {
@@ -8435,7 +8397,11 @@ bnx2_remove_one(struct pci_dev *pdev)
kfree(bp->temp_stats_blk);
+ if (bp->flags & BNX2_FLAG_PCIE)
+ pci_disable_pcie_error_reporting(pdev);
+
free_netdev(dev);
+
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
@@ -8527,25 +8493,38 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2 *bp = netdev_priv(dev);
+ pci_ers_result_t result;
+ int err;
rtnl_lock();
if (pci_enable_device(pdev)) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset\n");
- rtnl_unlock();
- return PCI_ERS_RESULT_DISCONNECT;
+ result = PCI_ERS_RESULT_DISCONNECT;
+ } else {
+ pci_set_master(pdev);
+ pci_restore_state(pdev);
+ pci_save_state(pdev);
+
+ if (netif_running(dev)) {
+ bnx2_set_power_state(bp, PCI_D0);
+ bnx2_init_nic(bp, 1);
+ }
+ result = PCI_ERS_RESULT_RECOVERED;
}
- pci_set_master(pdev);
- pci_restore_state(pdev);
- pci_save_state(pdev);
+ rtnl_unlock();
- if (netif_running(dev)) {
- bnx2_set_power_state(bp, PCI_D0);
- bnx2_init_nic(bp, 1);
+ if (!(bp->flags & BNX2_FLAG_PCIE))
+ return result;
+
+ err = pci_cleanup_aer_uncorrect_error_status(pdev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "pci_cleanup_aer_uncorrect_error_status failed 0x%0x\n",
+ err); /* non-fatal, continue */
}
- rtnl_unlock();
- return PCI_ERS_RESULT_RECOVERED;
+ return result;
}
/**
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 2104c1005d02..bf4c3421067d 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -352,12 +352,7 @@ struct l2_fhdr {
#define BNX2_L2CTX_BD_PRE_READ 0x00000000
#define BNX2_L2CTX_CTX_SIZE 0x00000000
#define BNX2_L2CTX_CTX_TYPE 0x00000000
-#define BNX2_L2CTX_LO_WATER_MARK_DEFAULT 4
-#define BNX2_L2CTX_LO_WATER_MARK_SCALE 4
-#define BNX2_L2CTX_LO_WATER_MARK_DIS 0
-#define BNX2_L2CTX_HI_WATER_MARK_SHIFT 4
-#define BNX2_L2CTX_HI_WATER_MARK_SCALE 16
-#define BNX2_L2CTX_WATER_MARKS_MSK 0x000000ff
+#define BNX2_L2CTX_FLOW_CTRL_ENABLE 0x000000ff
#define BNX2_L2CTX_CTX_TYPE_SIZE_L2 ((0x20/20)<<16)
#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE (0xf<<28)
#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED (0<<28)
@@ -4185,6 +4180,15 @@ struct l2_fhdr {
#define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_IP_ONLY_XI (2L<<2)
#define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_RES_XI (3L<<2)
+#define BNX2_RLUP_RSS_COMMAND 0x00002048
+#define BNX2_RLUP_RSS_COMMAND_RSS_IND_TABLE_ADDR (0xfUL<<0)
+#define BNX2_RLUP_RSS_COMMAND_RSS_WRITE_MASK (0xffUL<<4)
+#define BNX2_RLUP_RSS_COMMAND_WRITE (1UL<<12)
+#define BNX2_RLUP_RSS_COMMAND_READ (1UL<<13)
+#define BNX2_RLUP_RSS_COMMAND_HASH_MASK (0x7UL<<14)
+
+#define BNX2_RLUP_RSS_DATA 0x0000204c
+
/*
* rbuf_reg definition
@@ -6077,6 +6081,7 @@ struct l2_fhdr {
#define BNX2_COM_SCRATCH 0x00120000
+#define BNX2_FW_RX_LOW_LATENCY 0x00120058
#define BNX2_FW_RX_DROP_COUNT 0x00120084
@@ -6497,8 +6502,8 @@ struct l2_fhdr {
#define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct tx_bd))
#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
-#define MAX_RX_RINGS 4
-#define MAX_RX_PG_RINGS 16
+#define MAX_RX_RINGS 8
+#define MAX_RX_PG_RINGS 32
#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd))
#define MAX_RX_DESC_CNT (RX_DESC_CNT - 1)
#define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS)
@@ -6737,10 +6742,6 @@ struct bnx2 {
struct bnx2_napi bnx2_napi[BNX2_MAX_MSIX_VEC];
-#ifdef BCM_VLAN
- struct vlan_group *vlgrp;
-#endif
-
u32 rx_buf_use_size; /* useable size */
u32 rx_buf_size; /* with alignment */
u32 rx_copy_thresh;
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 0c2d96ed561c..9571ecf48f35 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -20,26 +20,20 @@
* (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */
-#define DRV_MODULE_VERSION "1.52.53-4"
-#define DRV_MODULE_RELDATE "2010/16/08"
+#define DRV_MODULE_VERSION "1.60.00-3"
+#define DRV_MODULE_RELDATE "2010/10/19"
#define BNX2X_BC_VER 0x040200
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define BCM_VLAN 1
-#endif
-
#define BNX2X_MULTI_QUEUE
#define BNX2X_NEW_NAPI
-
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#define BCM_CNIC 1
#include "../cnic_if.h"
#endif
-
#ifdef BCM_CNIC
#define BNX2X_MIN_MSIX_VEC_CNT 3
#define BNX2X_MSIX_VEC_FP_START 2
@@ -129,16 +123,18 @@ void bnx2x_panic_dump(struct bnx2x *bp);
} while (0)
#endif
+#define bnx2x_mc_addr(ha) ((ha)->addr)
#define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff)
#define U64_HI(x) (u32)(((u64)(x)) >> 32)
#define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo))
-#define REG_ADDR(bp, offset) (bp->regview + offset)
+#define REG_ADDR(bp, offset) ((bp->regview) + (offset))
#define REG_RD(bp, offset) readl(REG_ADDR(bp, offset))
#define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset))
+#define REG_RD16(bp, offset) readw(REG_ADDR(bp, offset))
#define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset))
#define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset))
@@ -160,6 +156,9 @@ void bnx2x_panic_dump(struct bnx2x *bp);
offset, len32); \
} while (0)
+#define REG_WR_DMAE_LEN(bp, offset, valp, len32) \
+ REG_WR_DMAE(bp, offset, valp, len32)
+
#define VIRT_WR_DMAE_LEN(bp, data, addr, len32, le32_swap) \
do { \
memcpy(GUNZIP_BUF(bp), data, (len32) * 4); \
@@ -175,16 +174,59 @@ void bnx2x_panic_dump(struct bnx2x *bp);
offsetof(struct shmem2_region, field))
#define SHMEM2_RD(bp, field) REG_RD(bp, SHMEM2_ADDR(bp, field))
#define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val)
+#define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \
+ offsetof(struct mf_cfg, field))
+#define MF2_CFG_ADDR(bp, field) (bp->common.mf2_cfg_base + \
+ offsetof(struct mf2_cfg, field))
-#define MF_CFG_RD(bp, field) SHMEM_RD(bp, mf_cfg.field)
-#define MF_CFG_WR(bp, field, val) SHMEM_WR(bp, mf_cfg.field, val)
+#define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field))
+#define MF_CFG_WR(bp, field, val) REG_WR(bp,\
+ MF_CFG_ADDR(bp, field), (val))
+#define MF2_CFG_RD(bp, field) REG_RD(bp, MF2_CFG_ADDR(bp, field))
+
+#define SHMEM2_HAS(bp, field) ((bp)->common.shmem2_base && \
+ (SHMEM2_RD((bp), size) > \
+ offsetof(struct shmem2_region, field)))
#define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg)
#define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val)
+/* SP SB indices */
+
+/* General SP events - stats query, cfc delete, etc */
+#define HC_SP_INDEX_ETH_DEF_CONS 3
+
+/* EQ completions */
+#define HC_SP_INDEX_EQ_CONS 7
+
+/* iSCSI L2 */
+#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5
+#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1
+
+/**
+ * CIDs and CLIDs:
+ * CLIDs below is a CLID for func 0, then the CLID for other
+ * functions will be calculated by the formula:
+ *
+ * FUNC_N_CLID_X = N * NUM_SPECIAL_CLIENTS + FUNC_0_CLID_X
+ *
+ */
+/* iSCSI L2 */
+#define BNX2X_ISCSI_ETH_CL_ID 17
+#define BNX2X_ISCSI_ETH_CID 17
+
+/** Additional rings budgeting */
+#ifdef BCM_CNIC
+#define CNIC_CONTEXT_USE 1
+#else
+#define CNIC_CONTEXT_USE 0
+#endif /* BCM_CNIC */
+
#define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \
AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR
+#define SM_RX_ID 0
+#define SM_TX_ID 1
/* fast path */
@@ -254,11 +296,24 @@ union db_prod {
#define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1)
#define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK)
+union host_hc_status_block {
+ /* pointer to fp status block e1x */
+ struct host_hc_status_block_e1x *e1x_sb;
+ /* pointer to fp status block e2 */
+ struct host_hc_status_block_e2 *e2_sb;
+};
struct bnx2x_fastpath {
+#define BNX2X_NAPI_WEIGHT 128
struct napi_struct napi;
- struct host_status_block *status_blk;
+ union host_hc_status_block status_blk;
+ /* chip independed shortcuts into sb structure */
+ __le16 *sb_index_values;
+ __le16 *sb_running_index;
+ /* chip independed shortcut into rx_prods_offset memory */
+ u32 ustorm_rx_prods_offset;
+
dma_addr_t status_blk_mapping;
struct sw_tx_bd *tx_buf_ring;
@@ -288,10 +343,15 @@ struct bnx2x_fastpath {
#define BNX2X_FP_STATE_OPEN 0xa0000
#define BNX2X_FP_STATE_HALTING 0xb0000
#define BNX2X_FP_STATE_HALTED 0xc0000
+#define BNX2X_FP_STATE_TERMINATING 0xd0000
+#define BNX2X_FP_STATE_TERMINATED 0xe0000
- u8 index; /* number in fp array */
- u8 cl_id; /* eth client id */
- u8 sb_id; /* status block number in HW */
+ u8 index; /* number in fp array */
+ u8 cl_id; /* eth client id */
+ u8 cl_qzone_id;
+ u8 fw_sb_id; /* status block number in FW */
+ u8 igu_sb_id; /* status block number in HW */
+ u32 cid;
union db_prod tx_db;
@@ -301,8 +361,7 @@ struct bnx2x_fastpath {
u16 tx_bd_cons;
__le16 *tx_cons_sb;
- __le16 fp_c_idx;
- __le16 fp_u_idx;
+ __le16 fp_hc_idx;
u16 rx_bd_prod;
u16 rx_bd_cons;
@@ -312,8 +371,6 @@ struct bnx2x_fastpath {
/* The last maximal completed SGE */
u16 last_max_sge;
__le16 *rx_cons_sb;
- __le16 *rx_bd_cons_sb;
-
unsigned long tx_pkt,
rx_pkt,
@@ -356,6 +413,8 @@ struct bnx2x_fastpath {
#define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS)
#define MAX_TX_BD (NUM_TX_BD - 1)
#define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2)
+#define INIT_JUMBO_TX_RING_SIZE MAX_TX_AVAIL
+#define INIT_TX_RING_SIZE MAX_TX_AVAIL
#define NEXT_TX_IDX(x) ((((x) & MAX_TX_DESC_CNT) == \
(MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
#define TX_BD(x) ((x) & MAX_TX_BD)
@@ -369,6 +428,9 @@ 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 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) == \
(MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1)
#define RX_BD(x) ((x) & MAX_RX_BD)
@@ -419,11 +481,12 @@ struct bnx2x_fastpath {
le32_to_cpu((bd)->addr_lo))
#define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes))
-
+#define BNX2X_DB_MIN_SHIFT 3 /* 8 bytes */
+#define BNX2X_DB_SHIFT 7 /* 128 bytes*/
#define DPM_TRIGER_TYPE 0x40
#define DOORBELL(bp, cid, val) \
do { \
- writel((u32)(val), bp->doorbells + (BCM_PAGE_SIZE * (cid)) + \
+ writel((u32)(val), bp->doorbells + (bp->db_size * (cid)) + \
DPM_TRIGER_TYPE); \
} while (0)
@@ -481,31 +544,15 @@ struct bnx2x_fastpath {
#define BNX2X_RX_SUM_FIX(cqe) \
BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags)
-
-#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES)
-#define FP_CSB_FUNC_OFF (2 + 2*HC_CSTORM_SB_NUM_INDICES)
-
-#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS
-#define U_SB_ETH_RX_BD_INDEX HC_INDEX_U_ETH_RX_BD_CONS
-#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS
+#define U_SB_ETH_RX_CQ_INDEX 1
+#define U_SB_ETH_RX_BD_INDEX 2
+#define C_SB_ETH_TX_CQ_INDEX 5
#define BNX2X_RX_SB_INDEX \
- (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_CQ_INDEX])
-
-#define BNX2X_RX_SB_BD_INDEX \
- (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_BD_INDEX])
-
-#define BNX2X_RX_SB_INDEX_NUM \
- (((U_SB_ETH_RX_CQ_INDEX << \
- USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \
- USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER) | \
- ((U_SB_ETH_RX_BD_INDEX << \
- USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT) & \
- USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER))
+ (&fp->sb_index_values[U_SB_ETH_RX_CQ_INDEX])
#define BNX2X_TX_SB_INDEX \
- (&fp->status_blk->c_status_block.index_values[C_SB_ETH_TX_CQ_INDEX])
-
+ (&fp->sb_index_values[C_SB_ETH_TX_CQ_INDEX])
/* end of fast path */
@@ -521,12 +568,19 @@ struct bnx2x_common {
#define CHIP_NUM_57710 0x164e
#define CHIP_NUM_57711 0x164f
#define CHIP_NUM_57711E 0x1650
+#define CHIP_NUM_57712 0x1662
+#define CHIP_NUM_57712E 0x1663
#define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710)
#define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711)
#define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E)
+#define CHIP_IS_57712(bp) (CHIP_NUM(bp) == CHIP_NUM_57712)
+#define CHIP_IS_57712E(bp) (CHIP_NUM(bp) == CHIP_NUM_57712E)
#define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \
CHIP_IS_57711E(bp))
-#define IS_E1H_OFFSET CHIP_IS_E1H(bp)
+#define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \
+ CHIP_IS_57712E(bp))
+#define CHIP_IS_E1x(bp) (CHIP_IS_E1((bp)) || CHIP_IS_E1H((bp)))
+#define IS_E1H_OFFSET (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp))
#define CHIP_REV(bp) (bp->common.chip_id & 0x0000f000)
#define CHIP_REV_Ax 0x00000000
@@ -552,12 +606,34 @@ struct bnx2x_common {
u32 shmem_base;
u32 shmem2_base;
+ u32 mf_cfg_base;
+ u32 mf2_cfg_base;
u32 hw_config;
u32 bc_ver;
+
+ u8 int_block;
+#define INT_BLOCK_HC 0
+#define INT_BLOCK_IGU 1
+#define INT_BLOCK_MODE_NORMAL 0
+#define INT_BLOCK_MODE_BW_COMP 2
+#define CHIP_INT_MODE_IS_NBC(bp) \
+ (CHIP_IS_E2(bp) && \
+ !((bp)->common.int_block & INT_BLOCK_MODE_BW_COMP))
+#define CHIP_INT_MODE_IS_BC(bp) (!CHIP_INT_MODE_IS_NBC(bp))
+
+ u8 chip_port_mode;
+#define CHIP_4_PORT_MODE 0x0
+#define CHIP_2_PORT_MODE 0x1
+#define CHIP_PORT_MODE_NONE 0x2
+#define CHIP_MODE(bp) (bp->common.chip_port_mode)
+#define CHIP_MODE_IS_4_PORT(bp) (CHIP_MODE(bp) == CHIP_4_PORT_MODE)
};
+/* IGU MSIX STATISTICS on 57712: 64 for VFs; 4 for PFs; 4 for Attentions */
+#define BNX2X_IGU_STAS_MSG_VF_CNT 64
+#define BNX2X_IGU_STAS_MSG_PF_CNT 4
/* end of common */
@@ -566,13 +642,13 @@ struct bnx2x_common {
struct bnx2x_port {
u32 pmf;
- u32 link_config;
+ u32 link_config[LINK_CONFIG_SIZE];
- u32 supported;
+ u32 supported[LINK_CONFIG_SIZE];
/* link settings - missing defines */
#define SUPPORTED_2500baseX_Full (1 << 15)
- u32 advertising;
+ u32 advertising[LINK_CONFIG_SIZE];
/* link settings - missing defines */
#define ADVERTISED_2500baseX_Full (1 << 15)
@@ -589,27 +665,98 @@ struct bnx2x_port {
/* end of port */
+/* e1h Classification CAM line allocations */
+enum {
+ CAM_ETH_LINE = 0,
+ CAM_ISCSI_ETH_LINE,
+ CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE
+};
+#define BNX2X_VF_ID_INVALID 0xFF
-#ifdef BCM_CNIC
-#define MAX_CONTEXT 15
-#else
-#define MAX_CONTEXT 16
-#endif
+/*
+ * The total number of L2 queues, MSIX vectors and HW contexts (CIDs) is
+ * control by the number of fast-path status blocks supported by the
+ * device (HW/FW). Each fast-path status block (FP-SB) aka non-default
+ * status block represents an independent interrupts context that can
+ * serve a regular L2 networking queue. However special L2 queues such
+ * as the FCoE queue do not require a FP-SB and other components like
+ * the CNIC may consume FP-SB reducing the number of possible L2 queues
+ *
+ * If the maximum number of FP-SB available is X then:
+ * a. If CNIC is supported it consumes 1 FP-SB thus the max number of
+ * regular L2 queues is Y=X-1
+ * b. in MF mode the actual number of L2 queues is Y= (X-1/MF_factor)
+ * c. If the FCoE L2 queue is supported the actual number of L2 queues
+ * is Y+1
+ * d. The number of irqs (MSIX vectors) is either Y+1 (one extra for
+ * slow-path interrupts) or Y+2 if CNIC is supported (one additional
+ * FP interrupt context for the CNIC).
+ * e. The number of HW context (CID count) is always X or X+1 if FCoE
+ * L2 queue is supported. the cid for the FCoE L2 queue is always X.
+ */
+
+#define FP_SB_MAX_E1x 16 /* fast-path interrupt contexts E1x */
+#define FP_SB_MAX_E2 16 /* fast-path interrupt contexts E2 */
+
+/*
+ * cid_cnt paramter below refers to the value returned by
+ * 'bnx2x_get_l2_cid_count()' routine
+ */
+
+/*
+ * The number of FP context allocated by the driver == max number of regular
+ * L2 queues + 1 for the FCoE L2 queue
+ */
+#define L2_FP_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE)
union cdu_context {
struct eth_context eth;
char pad[1024];
};
+/* CDU host DB constants */
+#define CDU_ILT_PAGE_SZ_HW 3
+#define CDU_ILT_PAGE_SZ (4096 << CDU_ILT_PAGE_SZ_HW) /* 32K */
+#define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context))
+
+#ifdef BCM_CNIC
+#define CNIC_ISCSI_CID_MAX 256
+#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX)
+#define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS)
+#endif
+
+#define QM_ILT_PAGE_SZ_HW 3
+#define QM_ILT_PAGE_SZ (4096 << QM_ILT_PAGE_SZ_HW) /* 32K */
+#define QM_CID_ROUND 1024
+
+#ifdef BCM_CNIC
+/* TM (timers) host DB constants */
+#define TM_ILT_PAGE_SZ_HW 2
+#define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 16K */
+/* #define TM_CONN_NUM (CNIC_STARTING_CID+CNIC_ISCSI_CXT_MAX) */
+#define TM_CONN_NUM 1024
+#define TM_ILT_SZ (8 * TM_CONN_NUM)
+#define TM_ILT_LINES DIV_ROUND_UP(TM_ILT_SZ, TM_ILT_PAGE_SZ)
+
+/* SRC (Searcher) host DB constants */
+#define SRC_ILT_PAGE_SZ_HW 3
+#define SRC_ILT_PAGE_SZ (4096 << SRC_ILT_PAGE_SZ_HW) /* 32K */
+#define SRC_HASH_BITS 10
+#define SRC_CONN_NUM (1 << SRC_HASH_BITS) /* 1024 */
+#define SRC_ILT_SZ (sizeof(struct src_ent) * SRC_CONN_NUM)
+#define SRC_T2_SZ SRC_ILT_SZ
+#define SRC_ILT_LINES DIV_ROUND_UP(SRC_ILT_SZ, SRC_ILT_PAGE_SZ)
+#endif
+
#define MAX_DMAE_C 8
/* DMA memory not used in fastpath */
struct bnx2x_slowpath {
- union cdu_context context[MAX_CONTEXT];
struct eth_stats_query fw_stats;
struct mac_configuration_cmd mac_config;
struct mac_configuration_cmd mcast_config;
+ struct client_init_ramrod_data client_init_data;
/* used by dmae command executer */
struct dmae_command dmae[MAX_DMAE_C];
@@ -634,52 +781,83 @@ struct bnx2x_slowpath {
#define MAX_DYNAMIC_ATTN_GRPS 8
struct attn_route {
- u32 sig[4];
+ u32 sig[5];
+};
+
+struct iro {
+ u32 base;
+ u16 m1;
+ u16 m2;
+ u16 m3;
+ u16 size;
};
+struct hw_context {
+ union cdu_context *vcxt;
+ dma_addr_t cxt_mapping;
+ size_t size;
+};
+
+/* forward */
+struct bnx2x_ilt;
+
typedef enum {
BNX2X_RECOVERY_DONE,
BNX2X_RECOVERY_INIT,
BNX2X_RECOVERY_WAIT,
} bnx2x_recovery_state_t;
+/**
+ * Event queue (EQ or event ring) MC hsi
+ * NUM_EQ_PAGES and EQ_DESC_CNT_PAGE must be power of 2
+ */
+#define NUM_EQ_PAGES 1
+#define EQ_DESC_CNT_PAGE (BCM_PAGE_SIZE / sizeof(union event_ring_elem))
+#define EQ_DESC_MAX_PAGE (EQ_DESC_CNT_PAGE - 1)
+#define NUM_EQ_DESC (EQ_DESC_CNT_PAGE * NUM_EQ_PAGES)
+#define EQ_DESC_MASK (NUM_EQ_DESC - 1)
+#define MAX_EQ_AVAIL (EQ_DESC_MAX_PAGE * NUM_EQ_PAGES - 2)
+
+/* depends on EQ_DESC_CNT_PAGE being a power of 2 */
+#define NEXT_EQ_IDX(x) ((((x) & EQ_DESC_MAX_PAGE) == \
+ (EQ_DESC_MAX_PAGE - 1)) ? (x) + 2 : (x) + 1)
+
+/* depends on the above and on NUM_EQ_PAGES being a power of 2 */
+#define EQ_DESC(x) ((x) & EQ_DESC_MASK)
+
+#define BNX2X_EQ_INDEX \
+ (&bp->def_status_blk->sp_sb.\
+ index_values[HC_SP_INDEX_EQ_CONS])
+
struct bnx2x {
/* Fields used in the tx and intr/napi performance paths
* are grouped together in the beginning of the structure
*/
- struct bnx2x_fastpath fp[MAX_CONTEXT];
+ struct bnx2x_fastpath *fp;
void __iomem *regview;
void __iomem *doorbells;
-#ifdef BCM_CNIC
-#define BNX2X_DB_SIZE (18*BCM_PAGE_SIZE)
-#else
-#define BNX2X_DB_SIZE (16*BCM_PAGE_SIZE)
-#endif
+ u16 db_size;
struct net_device *dev;
struct pci_dev *pdev;
+ struct iro *iro_arr;
+#define IRO (bp->iro_arr)
+
atomic_t intr_sem;
bnx2x_recovery_state_t recovery_state;
int is_leader;
-#ifdef BCM_CNIC
- struct msix_entry msix_table[MAX_CONTEXT+2];
-#else
- struct msix_entry msix_table[MAX_CONTEXT+1];
-#endif
+ struct msix_entry *msix_table;
#define INT_MODE_INTx 1
#define INT_MODE_MSI 2
int tx_ring_size;
-#ifdef BCM_VLAN
- struct vlan_group *vlgrp;
-#endif
-
u32 rx_csum;
u32 rx_buf_size;
-#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */
+/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
+#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
#define ETH_MIN_PACKET_SIZE 60
#define ETH_MAX_PACKET_SIZE 1500
#define ETH_MAX_JUMBO_PACKET_SIZE 9600
@@ -688,13 +866,12 @@ struct bnx2x {
#define BNX2X_RX_ALIGN_SHIFT ((L1_CACHE_SHIFT < 8) ? \
L1_CACHE_SHIFT : 8)
#define BNX2X_RX_ALIGN (1 << BNX2X_RX_ALIGN_SHIFT)
+#define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5)
- struct host_def_status_block *def_status_blk;
-#define DEF_SB_ID 16
- __le16 def_c_idx;
- __le16 def_u_idx;
- __le16 def_x_idx;
- __le16 def_t_idx;
+ struct host_sp_status_block *def_status_blk;
+#define DEF_SB_IGU_ID 16
+#define DEF_SB_ID HC_SP_SB_ID
+ __le16 def_idx;
__le16 def_att_idx;
u32 attn_state;
struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS];
@@ -706,10 +883,17 @@ struct bnx2x {
struct eth_spe *spq_prod_bd;
struct eth_spe *spq_last_bd;
__le16 *dsb_sp_prod;
- u16 spq_left; /* serialize spq */
+ atomic_t spq_left; /* serialize spq */
/* used to synchronize spq accesses */
spinlock_t spq_lock;
+ /* event queue */
+ union event_ring_elem *eq_ring;
+ dma_addr_t eq_mapping;
+ u16 eq_prod;
+ u16 eq_cons;
+ __le16 *eq_cons_sb;
+
/* Flags for marking that there is a STAT_QUERY or
SET_MAC ramrod pending */
int stats_pending;
@@ -728,18 +912,27 @@ struct bnx2x {
#define USING_DAC_FLAG 0x10
#define USING_MSIX_FLAG 0x20
#define USING_MSI_FLAG 0x40
+
#define TPA_ENABLE_FLAG 0x80
#define NO_MCP_FLAG 0x100
+#define DISABLE_MSI_FLAG 0x200
#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
-#define HW_VLAN_TX_FLAG 0x400
-#define HW_VLAN_RX_FLAG 0x800
#define MF_FUNC_DIS 0x1000
- int func;
-#define BP_PORT(bp) (bp->func % PORT_MAX)
-#define BP_FUNC(bp) (bp->func)
-#define BP_E1HVN(bp) (bp->func >> 1)
+ int pf_num; /* absolute PF number */
+ int pfid; /* per-path PF number */
+ int base_fw_ndsb;
+#define BP_PATH(bp) (!CHIP_IS_E2(bp) ? \
+ 0 : (bp->pf_num & 1))
+#define BP_PORT(bp) (bp->pfid & 1)
+#define BP_FUNC(bp) (bp->pfid)
+#define BP_ABS_FUNC(bp) (bp->pf_num)
+#define BP_E1HVN(bp) (bp->pfid >> 1)
+#define BP_VN(bp) (CHIP_MODE_IS_4_PORT(bp) ? \
+ 0 : BP_E1HVN(bp))
#define BP_L_ID(bp) (BP_E1HVN(bp) << 2)
+#define BP_FW_MB_IDX(bp) (BP_PORT(bp) +\
+ BP_VN(bp) * (CHIP_IS_E1x(bp) ? 2 : 1))
#ifdef BCM_CNIC
#define BCM_CNIC_CID_START 16
@@ -769,10 +962,11 @@ struct bnx2x {
struct cmng_struct_per_port cmng;
u32 vn_weight_sum;
- u32 mf_config;
- u16 e1hov;
- u8 e1hmf;
-#define IS_E1HMF(bp) (bp->e1hmf != 0)
+ u32 mf_config[E1HVN_MAX];
+ u32 mf2_config[E2_FUNC_MAX];
+ u16 mf_ov;
+ u8 mf_mode;
+#define IS_MF(bp) (bp->mf_mode != 0)
u8 wol;
@@ -800,6 +994,7 @@ struct bnx2x {
#define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000
#define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000
#define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000
+#define BNX2X_STATE_FUNC_STARTED 0x7000
#define BNX2X_STATE_DIAG 0xe000
#define BNX2X_STATE_ERROR 0xf000
@@ -808,6 +1003,15 @@ struct bnx2x {
int disable_tpa;
int int_mode;
+ struct tstorm_eth_mac_filter_config mac_filters;
+#define BNX2X_ACCEPT_NONE 0x0000
+#define BNX2X_ACCEPT_UNICAST 0x0001
+#define BNX2X_ACCEPT_MULTICAST 0x0002
+#define BNX2X_ACCEPT_ALL_UNICAST 0x0004
+#define BNX2X_ACCEPT_ALL_MULTICAST 0x0008
+#define BNX2X_ACCEPT_BROADCAST 0x0010
+#define BNX2X_PROMISCUOUS_MODE 0x10000
+
u32 rx_mode;
#define BNX2X_RX_MODE_NONE 0
#define BNX2X_RX_MODE_NORMAL 1
@@ -816,34 +1020,41 @@ struct bnx2x {
#define BNX2X_MAX_MULTICAST 64
#define BNX2X_MAX_EMUL_MULTI 16
- u32 rx_mode_cl_mask;
-
+ u8 igu_dsb_id;
+ u8 igu_base_sb;
+ u8 igu_sb_cnt;
dma_addr_t def_status_blk_mapping;
struct bnx2x_slowpath *slowpath;
dma_addr_t slowpath_mapping;
+ struct hw_context context;
+
+ struct bnx2x_ilt *ilt;
+#define BP_ILT(bp) ((bp)->ilt)
+#define ILT_MAX_LINES 128
+
+ int l2_cid_count;
+#define L2_ILT_LINES(bp) (DIV_ROUND_UP((bp)->l2_cid_count, \
+ ILT_PAGE_CIDS))
+#define BNX2X_DB_SIZE(bp) ((bp)->l2_cid_count * (1 << BNX2X_DB_SHIFT))
+
+ int qm_cid_count;
int dropless_fc;
#ifdef BCM_CNIC
u32 cnic_flags;
#define BNX2X_CNIC_FLAG_MAC_SET 1
-
- void *t1;
- dma_addr_t t1_mapping;
void *t2;
dma_addr_t t2_mapping;
- void *timers;
- dma_addr_t timers_mapping;
- void *qm;
- dma_addr_t qm_mapping;
struct cnic_ops *cnic_ops;
void *cnic_data;
u32 cnic_tag;
struct cnic_eth_dev cnic_eth_dev;
- struct host_status_block *cnic_sb;
+ union host_hc_status_block cnic_sb;
dma_addr_t cnic_sb_mapping;
-#define CNIC_SB_ID(bp) BP_L_ID(bp)
+#define CNIC_SB_ID(bp) ((bp)->base_fw_ndsb + BP_L_ID(bp))
+#define CNIC_IGU_SB_ID(bp) ((bp)->igu_base_sb)
struct eth_spe *cnic_kwq;
struct eth_spe *cnic_kwq_prod;
struct eth_spe *cnic_kwq_cons;
@@ -913,32 +1124,196 @@ struct bnx2x {
const struct firmware *firmware;
};
+/**
+ * Init queue/func interface
+ */
+/* queue init flags */
+#define QUEUE_FLG_TPA 0x0001
+#define QUEUE_FLG_CACHE_ALIGN 0x0002
+#define QUEUE_FLG_STATS 0x0004
+#define QUEUE_FLG_OV 0x0008
+#define QUEUE_FLG_VLAN 0x0010
+#define QUEUE_FLG_COS 0x0020
+#define QUEUE_FLG_HC 0x0040
+#define QUEUE_FLG_DHC 0x0080
+#define QUEUE_FLG_OOO 0x0100
+
+#define QUEUE_DROP_IP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR
+#define QUEUE_DROP_TCP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR
+#define QUEUE_DROP_TTL0 TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0
+#define QUEUE_DROP_UDP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR
+
+
+
+/* rss capabilities */
+#define RSS_IPV4_CAP 0x0001
+#define RSS_IPV4_TCP_CAP 0x0002
+#define RSS_IPV6_CAP 0x0004
+#define RSS_IPV6_TCP_CAP 0x0008
-#define BNX2X_MAX_QUEUES(bp) (IS_E1HMF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \
- : MAX_CONTEXT)
#define BNX2X_NUM_QUEUES(bp) (bp->num_queues)
#define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1)
+#define BNX2X_MAX_QUEUES(bp) (bp->igu_sb_cnt - CNIC_CONTEXT_USE)
+#define is_eth_multi(bp) (BNX2X_NUM_ETH_QUEUES(bp) > 1)
+
+#define RSS_IPV4_CAP_MASK \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY
+
+#define RSS_IPV4_TCP_CAP_MASK \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY
+
+#define RSS_IPV6_CAP_MASK \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY
+
+#define RSS_IPV6_TCP_CAP_MASK \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY
+
+/* func init flags */
+#define FUNC_FLG_STATS 0x0001
+#define FUNC_FLG_TPA 0x0002
+#define FUNC_FLG_SPQ 0x0004
+#define FUNC_FLG_LEADING 0x0008 /* PF only */
+
+struct rxq_pause_params {
+ u16 bd_th_lo;
+ u16 bd_th_hi;
+ u16 rcq_th_lo;
+ u16 rcq_th_hi;
+ u16 sge_th_lo; /* valid iff QUEUE_FLG_TPA */
+ u16 sge_th_hi; /* valid iff QUEUE_FLG_TPA */
+ u16 pri_map;
+};
+
+struct bnx2x_rxq_init_params {
+ /* cxt*/
+ struct eth_context *cxt;
+
+ /* dma */
+ dma_addr_t dscr_map;
+ dma_addr_t sge_map;
+ dma_addr_t rcq_map;
+ dma_addr_t rcq_np_map;
+
+ u16 flags;
+ u16 drop_flags;
+ u16 mtu;
+ u16 buf_sz;
+ u16 fw_sb_id;
+ u16 cl_id;
+ u16 spcl_id;
+ u16 cl_qzone_id;
+
+ /* valid iff QUEUE_FLG_STATS */
+ u16 stat_id;
+
+ /* valid iff QUEUE_FLG_TPA */
+ u16 tpa_agg_sz;
+ u16 sge_buf_sz;
+ u16 max_sges_pkt;
+
+ /* valid iff QUEUE_FLG_CACHE_ALIGN */
+ u8 cache_line_log;
+
+ u8 sb_cq_index;
+ u32 cid;
+
+ /* desired interrupts per sec. valid iff QUEUE_FLG_HC */
+ u32 hc_rate;
+};
+
+struct bnx2x_txq_init_params {
+ /* cxt*/
+ struct eth_context *cxt;
+
+ /* dma */
+ dma_addr_t dscr_map;
+
+ u16 flags;
+ u16 fw_sb_id;
+ u8 sb_cq_index;
+ u8 cos; /* valid iff QUEUE_FLG_COS */
+ u16 stat_id; /* valid iff QUEUE_FLG_STATS */
+ u16 traffic_type;
+ u32 cid;
+ u16 hc_rate; /* desired interrupts per sec.*/
+ /* valid iff QUEUE_FLG_HC */
+
+};
+
+struct bnx2x_client_ramrod_params {
+ int *pstate;
+ int state;
+ u16 index;
+ u16 cl_id;
+ u32 cid;
+ u8 poll;
+#define CLIENT_IS_LEADING_RSS 0x02
+ u8 flags;
+};
+
+struct bnx2x_client_init_params {
+ struct rxq_pause_params pause;
+ struct bnx2x_rxq_init_params rxq_params;
+ struct bnx2x_txq_init_params txq_params;
+ struct bnx2x_client_ramrod_params ramrod_params;
+};
+
+struct bnx2x_rss_params {
+ int mode;
+ u16 cap;
+ u16 result_mask;
+};
+
+struct bnx2x_func_init_params {
+
+ /* rss */
+ struct bnx2x_rss_params *rss; /* valid iff FUNC_FLG_RSS */
+
+ /* dma */
+ dma_addr_t fw_stat_map; /* valid iff FUNC_FLG_STATS */
+ dma_addr_t spq_map; /* valid iff FUNC_FLG_SPQ */
+
+ u16 func_flgs;
+ u16 func_id; /* abs fid */
+ u16 pf_id;
+ u16 spq_prod; /* valid iff FUNC_FLG_SPQ */
+};
+
#define for_each_queue(bp, var) \
for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++)
#define for_each_nondefault_queue(bp, var) \
for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++)
+#define WAIT_RAMROD_POLL 0x01
+#define WAIT_RAMROD_COMMON 0x02
+int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
+ int *state_p, int flags);
+
+/* 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,
u32 len32);
+void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr,
+ u32 addr, u32 len);
+void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx);
+u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type);
+u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode);
+u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type,
+ bool with_comp, u8 comp_type);
+
int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port);
int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
-u32 bnx2x_fw_command(struct bnx2x *bp, u32 command);
+u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param);
void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
-void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr,
- u32 addr, u32 len);
+
void bnx2x_calc_fc_adv(struct bnx2x *bp);
int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
u32 data_hi, u32 data_lo, int common);
void bnx2x_update_coalesce(struct bnx2x *bp);
+int bnx2x_get_link_cfg_idx(struct bnx2x *bp);
static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
int wait)
@@ -957,6 +1332,40 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
return val;
}
+#define BNX2X_ILT_ZALLOC(x, y, size) \
+ do { \
+ x = pci_alloc_consistent(bp->pdev, size, y); \
+ if (x) \
+ memset(x, 0, size); \
+ } while (0)
+
+#define BNX2X_ILT_FREE(x, y, size) \
+ do { \
+ if (x) { \
+ pci_free_consistent(bp->pdev, size, x, y); \
+ x = NULL; \
+ y = 0; \
+ } \
+ } while (0)
+
+#define ILOG2(x) (ilog2((x)))
+
+#define ILT_NUM_PAGE_ENTRIES (3072)
+/* In 57710/11 we use whole table since we have 8 func
+ * In 57712 we have only 4 func, but use same size per func, then only half of
+ * the table in use
+ */
+#define ILT_PER_FUNC (ILT_NUM_PAGE_ENTRIES/8)
+
+#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC)
+/*
+ * the phys address is shifted right 12 bits and has an added
+ * 1=valid bit added to the 53rd bit
+ * then since this is a wide register(TM)
+ * we split it into two 32 bit writes
+ */
+#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF))
+#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44)))
/* load/unload mode */
#define LOAD_NORMAL 0
@@ -964,18 +1373,44 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define LOAD_DIAG 2
#define UNLOAD_NORMAL 0
#define UNLOAD_CLOSE 1
-#define UNLOAD_RECOVERY 2
+#define UNLOAD_RECOVERY 2
/* DMAE command defines */
-#define DMAE_CMD_SRC_PCI 0
-#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC
+#define DMAE_TIMEOUT -1
+#define DMAE_PCI_ERROR -2 /* E2 and onward */
+#define DMAE_NOT_RDY -3
+#define DMAE_PCI_ERR_FLAG 0x80000000
+
+#define DMAE_SRC_PCI 0
+#define DMAE_SRC_GRC 1
+
+#define DMAE_DST_NONE 0
+#define DMAE_DST_PCI 1
+#define DMAE_DST_GRC 2
+
+#define DMAE_COMP_PCI 0
+#define DMAE_COMP_GRC 1
+
+/* E2 and onward - PCI error handling in the completion */
-#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT)
-#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT)
+#define DMAE_COMP_REGULAR 0
+#define DMAE_COM_SET_ERR 1
-#define DMAE_CMD_C_DST_PCI 0
-#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT)
+#define DMAE_CMD_SRC_PCI (DMAE_SRC_PCI << \
+ DMAE_COMMAND_SRC_SHIFT)
+#define DMAE_CMD_SRC_GRC (DMAE_SRC_GRC << \
+ DMAE_COMMAND_SRC_SHIFT)
+
+#define DMAE_CMD_DST_PCI (DMAE_DST_PCI << \
+ DMAE_COMMAND_DST_SHIFT)
+#define DMAE_CMD_DST_GRC (DMAE_DST_GRC << \
+ DMAE_COMMAND_DST_SHIFT)
+
+#define DMAE_CMD_C_DST_PCI (DMAE_COMP_PCI << \
+ DMAE_COMMAND_C_DST_SHIFT)
+#define DMAE_CMD_C_DST_GRC (DMAE_COMP_GRC << \
+ DMAE_COMMAND_C_DST_SHIFT)
#define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE
@@ -991,10 +1426,20 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET
#define DMAE_CMD_E1HVN_SHIFT DMAE_COMMAND_E1HVN_SHIFT
+#define DMAE_SRC_PF 0
+#define DMAE_SRC_VF 1
+
+#define DMAE_DST_PF 0
+#define DMAE_DST_VF 1
+
+#define DMAE_C_SRC 0
+#define DMAE_C_DST 1
+
#define DMAE_LEN32_RD_MAX 0x80
#define DMAE_LEN32_WR_MAX(bp) (CHIP_IS_E1(bp) ? 0x400 : 0x2000)
-#define DMAE_COMP_VAL 0xe0d0d0ae
+#define DMAE_COMP_VAL 0x60d0d0ae /* E2 and on - upper bit
+ indicates eror */
#define MAX_DMAE_C_PER_PORT 8
#define INIT_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
@@ -1002,7 +1447,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
E1HVN_MAX)
-
/* PCIE link and speed */
#define PCICFG_LINK_WIDTH 0x1f00000
#define PCICFG_LINK_WIDTH_SHIFT 20
@@ -1031,7 +1475,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define MAX_SP_DESC_CNT (SP_DESC_CNT - 1)
-#define BNX2X_BTR 1
+#define BNX2X_BTR 4
#define MAX_SPQ_PENDING 8
@@ -1148,20 +1592,26 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT))
#define MULTI_MASK 0x7f
+#define BNX2X_SP_DSB_INDEX \
+ (&bp->def_status_blk->sp_sb.\
+ index_values[HC_SP_INDEX_ETH_DEF_CONS])
-#define DEF_USB_FUNC_OFF (2 + 2*HC_USTORM_DEF_SB_NUM_INDICES)
-#define DEF_CSB_FUNC_OFF (2 + 2*HC_CSTORM_DEF_SB_NUM_INDICES)
-#define DEF_XSB_FUNC_OFF (2 + 2*HC_XSTORM_DEF_SB_NUM_INDICES)
-#define DEF_TSB_FUNC_OFF (2 + 2*HC_TSTORM_DEF_SB_NUM_INDICES)
+#define SET_FLAG(value, mask, flag) \
+ do {\
+ (value) &= ~(mask);\
+ (value) |= ((flag) << (mask##_SHIFT));\
+ } while (0)
-#define C_DEF_SB_SP_INDEX HC_INDEX_DEF_C_ETH_SLOW_PATH
-
-#define BNX2X_SP_DSB_INDEX \
-(&bp->def_status_blk->c_def_status_block.index_values[C_DEF_SB_SP_INDEX])
+#define GET_FLAG(value, mask) \
+ (((value) &= (mask)) >> (mask##_SHIFT))
+#define GET_FIELD(value, fname) \
+ (((value) & (fname##_MASK)) >> (fname##_SHIFT))
#define CAM_IS_INVALID(x) \
-(x.target_table_entry.flags == TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE)
+ (GET_FLAG(x.flags, \
+ MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \
+ (T_ETH_MAC_COMMAND_INVALIDATE))
#define CAM_INVALIDATE(x) \
(x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE)
@@ -1177,21 +1627,29 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define PXP2_REG_PXP2_INT_STS PXP2_REG_PXP2_INT_STS_0
#endif
+#ifndef ETH_MAX_RX_CLIENTS_E2
+#define ETH_MAX_RX_CLIENTS_E2 ETH_MAX_RX_CLIENTS_E1H
+#endif
+
#define BNX2X_VPD_LEN 128
#define VENDOR_ID_LEN 4
+/* Congestion management fairness mode */
+#define CMNG_FNS_NONE 0
+#define CMNG_FNS_MINMAX 1
+
+#define HC_SEG_ACCESS_DEF 0 /*Driver decision 0-3*/
+#define HC_SEG_ACCESS_ATTN 4
+#define HC_SEG_ACCESS_NORM 0 /*Driver decision 0-1*/
+
#ifdef BNX2X_MAIN
#define BNX2X_EXTERN
#else
#define BNX2X_EXTERN extern
#endif
-BNX2X_EXTERN int load_count[3]; /* 0-common, 1-port0, 2-port1 */
-
-/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */
+BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */
extern void bnx2x_set_ethtool_ops(struct net_device *netdev);
-void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx);
-
#endif /* bnx2x.h */
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 02bf710629a3..bc5837514074 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -15,18 +15,16 @@
*
*/
-
#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
#include <linux/ip.h>
-#include <linux/ipv6.h>
+#include <net/ipv6.h>
#include <net/ip6_checksum.h>
+#include <linux/firmware.h>
#include "bnx2x_cmn.h"
-#ifdef BCM_VLAN
-#include <linux/if_vlan.h>
-#endif
+#include "bnx2x_init.h"
-static int bnx2x_poll(struct napi_struct *napi, int budget);
/* free skb in the packet ring at pos idx
* return idx of last bd freed
@@ -51,7 +49,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp,
DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx);
tx_start_bd = &fp->tx_desc_ring[bd_idx].start_bd;
dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd),
- BD_UNMAP_LEN(tx_start_bd), PCI_DMA_TODEVICE);
+ BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE);
nbd = le16_to_cpu(tx_start_bd->nbd) - 1;
#ifdef BNX2X_STOP_ON_ERROR
@@ -115,16 +113,10 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp)
pkt_cons = TX_BD(sw_cons);
- /* prefetch(bp->tx_buf_ring[pkt_cons].skb); */
-
- DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %u\n",
- hw_cons, sw_cons, pkt_cons);
+ DP(NETIF_MSG_TX_DONE, "queue[%d]: hw_cons %u sw_cons %u "
+ " pkt_cons %u\n",
+ fp->index, hw_cons, sw_cons, pkt_cons);
-/* if (NEXT_TX_IDX(sw_cons) != hw_cons) {
- rmb();
- prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb);
- }
-*/
bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons);
sw_cons++;
}
@@ -140,7 +132,6 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp)
*/
smp_mb();
- /* TBD need a thresh? */
if (unlikely(netif_tx_queue_stopped(txq))) {
/* Taking tx_lock() is needed to prevent reenabling the queue
* while it's empty. This could have happen if rx_action() gets
@@ -189,14 +180,16 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp,
/* First mark all used pages */
for (i = 0; i < sge_len; i++)
- SGE_MASK_CLEAR_BIT(fp, RX_SGE(le16_to_cpu(fp_cqe->sgl[i])));
+ SGE_MASK_CLEAR_BIT(fp,
+ RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[i])));
DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n",
- sge_len - 1, le16_to_cpu(fp_cqe->sgl[sge_len - 1]));
+ sge_len - 1, le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1]));
/* Here we assume that the last SGE index is the biggest */
prefetch((void *)(fp->sge_mask));
- bnx2x_update_last_max_sge(fp, le16_to_cpu(fp_cqe->sgl[sge_len - 1]));
+ bnx2x_update_last_max_sge(fp,
+ le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1]));
last_max = RX_SGE(fp->last_max_sge);
last_elem = last_max >> RX_SGE_MASK_ELEM_SHIFT;
@@ -297,7 +290,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
/* Run through the SGL and compose the fragmented skb */
for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) {
- u16 sge_idx = RX_SGE(le16_to_cpu(fp_cqe->sgl[j]));
+ u16 sge_idx =
+ RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[j]));
/* FW gives the indices of the SGE as if the ring is an array
(meaning that "next" element will consume 2 indices) */
@@ -349,16 +343,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
if (likely(new_skb)) {
/* fix ip xsum and give it to the stack */
/* (no need to map the new skb) */
-#ifdef BCM_VLAN
- int is_vlan_cqe =
- (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
- PARSING_FLAGS_VLAN);
- int is_not_hwaccel_vlan_cqe =
- (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG)));
-#endif
prefetch(skb);
- prefetch(((char *)(skb)) + 128);
+ prefetch(((char *)(skb)) + L1_CACHE_BYTES);
#ifdef BNX2X_STOP_ON_ERROR
if (pad + len > bp->rx_buf_size) {
@@ -380,27 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
struct iphdr *iph;
iph = (struct iphdr *)skb->data;
-#ifdef BCM_VLAN
- /* If there is no Rx VLAN offloading -
- take VLAN tag into an account */
- if (unlikely(is_not_hwaccel_vlan_cqe))
- iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN);
-#endif
iph->check = 0;
iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
}
if (!bnx2x_fill_frag_skb(bp, fp, skb,
&cqe->fast_path_cqe, cqe_idx)) {
-#ifdef BCM_VLAN
- if ((bp->vlgrp != NULL) && is_vlan_cqe &&
- (!is_not_hwaccel_vlan_cqe))
- vlan_gro_receive(&fp->napi, bp->vlgrp,
+ if ((le16_to_cpu(cqe->fast_path_cqe.
+ pars_flags.flags) & PARSING_FLAGS_VLAN))
+ __vlan_hwaccel_put_tag(skb,
le16_to_cpu(cqe->fast_path_cqe.
- vlan_tag), skb);
- else
-#endif
- napi_gro_receive(&fp->napi, skb);
+ vlan_tag));
+ napi_gro_receive(&fp->napi, skb);
} else {
DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages"
" - dropping packet!\n");
@@ -509,8 +487,11 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
pad = cqe->fast_path_cqe.placement_offset;
- /* If CQE is marked both TPA_START and TPA_END
- it is a non-TPA CQE */
+ /* - If CQE is marked both TPA_START and TPA_END it is
+ * a non-TPA CQE.
+ * - FP CQE will always have either TPA_START or/and
+ * TPA_STOP flags set.
+ */
if ((!fp->disable_tpa) &&
(TPA_TYPE(cqe_fp_flags) !=
(TPA_TYPE_START | TPA_TYPE_END))) {
@@ -528,9 +509,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
bnx2x_set_skb_rxhash(bp, cqe, skb);
goto next_rx;
- }
-
- if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_END) {
+ } else { /* TPA_STOP */
DP(NETIF_MSG_RX_STATUS,
"calling tpa_stop on queue %d\n",
queue);
@@ -560,7 +539,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
dma_unmap_addr(rx_buf, mapping),
pad + RX_COPY_THRESH,
DMA_FROM_DEVICE);
- prefetch(((char *)(skb)) + 128);
+ prefetch(((char *)(skb)) + L1_CACHE_BYTES);
/* is this an error packet? */
if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) {
@@ -594,7 +573,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
skb_reserve(new_skb, pad);
skb_put(new_skb, len);
- bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
+ bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod);
skb = new_skb;
@@ -613,7 +592,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
"of alloc failure\n");
fp->eth_q_stats.rx_skb_alloc_failed++;
reuse_rx:
- bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
+ bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod);
goto next_rx;
}
@@ -622,7 +601,8 @@ reuse_rx:
/* Set Toeplitz hash for a none-LRO skb */
bnx2x_set_skb_rxhash(bp, cqe, skb);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
+
if (bp->rx_csum) {
if (likely(BNX2X_RX_CSUM_OK(cqe)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -633,15 +613,11 @@ reuse_rx:
skb_record_rx_queue(skb, fp->index);
-#ifdef BCM_VLAN
- if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
- (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
- PARSING_FLAGS_VLAN))
- vlan_gro_receive(&fp->napi, bp->vlgrp,
- le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb);
- else
-#endif
- napi_gro_receive(&fp->napi, skb);
+ if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
+ PARSING_FLAGS_VLAN)
+ __vlan_hwaccel_put_tag(skb,
+ le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
+ napi_gro_receive(&fp->napi, skb);
next_rx:
@@ -685,9 +661,10 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
return IRQ_HANDLED;
}
- DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n",
- fp->index, fp->sb_id);
- bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0);
+ DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB "
+ "[fp %d fw_sd %d igusb %d]\n",
+ fp->index, fp->fw_sb_id, fp->igu_sb_id);
+ bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0);
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -697,14 +674,12 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
/* Handle Rx and Tx according to MSI-X vector */
prefetch(fp->rx_cons_sb);
prefetch(fp->tx_cons_sb);
- prefetch(&fp->status_blk->u_status_block.status_block_index);
- prefetch(&fp->status_blk->c_status_block.status_block_index);
+ prefetch(&fp->sb_running_index[SM_RX_ID]);
napi_schedule(&bnx2x_fp(bp, fp->index, napi));
return IRQ_HANDLED;
}
-
/* HW Lock for shared dual port PHYs */
void bnx2x_acquire_phy_lock(struct bnx2x *bp)
{
@@ -738,12 +713,13 @@ void bnx2x_link_report(struct bnx2x *bp)
netdev_info(bp->dev, "NIC Link is Up, ");
line_speed = bp->link_vars.line_speed;
- if (IS_E1HMF(bp)) {
+ if (IS_MF(bp)) {
u16 vn_max_rate;
vn_max_rate =
- ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
- FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
+ ((bp->mf_config[BP_VN(bp)] &
+ FUNC_MF_CFG_MAX_BW_MASK) >>
+ FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
if (vn_max_rate < line_speed)
line_speed = vn_max_rate;
}
@@ -773,23 +749,73 @@ void bnx2x_link_report(struct bnx2x *bp)
}
}
+/* 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);
int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 :
ETH_MAX_AGGREGATION_QUEUES_E1H;
- u16 ring_prod, cqe_ring_prod;
+ u16 ring_prod;
int i, j;
- bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN;
+ bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN +
+ IP_HEADER_ALIGNMENT_PADDING;
+
DP(NETIF_MSG_IFUP,
"mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size);
- if (bp->flags & TPA_ENABLE_FLAG) {
-
- for_each_queue(bp, j) {
- struct bnx2x_fastpath *fp = &bp->fp[j];
+ for_each_queue(bp, j) {
+ struct bnx2x_fastpath *fp = &bp->fp[j];
+ if (!fp->disable_tpa) {
for (i = 0; i < max_agg_queues; i++) {
fp->tpa_pool[i].skb =
netdev_alloc_skb(bp->dev, bp->rx_buf_size);
@@ -807,6 +833,35 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
mapping, 0);
fp->tpa_state[i] = BNX2X_TPA_STOP;
}
+
+ /* "next page" elements initialization */
+ bnx2x_set_next_page_sgl(fp);
+
+ /* set SGEs bit mask */
+ bnx2x_init_sge_ring_bit_mask(fp);
+
+ /* Allocate SGEs and initialize the ring elements */
+ for (i = 0, ring_prod = 0;
+ i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) {
+
+ if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) {
+ BNX2X_ERR("was only able to allocate "
+ "%d rx sges\n", i);
+ BNX2X_ERR("disabling TPA for"
+ " queue[%d]\n", j);
+ /* Cleanup already allocated elements */
+ bnx2x_free_rx_sge_range(bp,
+ fp, ring_prod);
+ bnx2x_free_tpa_pool(bp,
+ fp, max_agg_queues);
+ fp->disable_tpa = 1;
+ ring_prod = 0;
+ break;
+ }
+ ring_prod = NEXT_SGE_IDX(ring_prod);
+ }
+
+ fp->rx_sge_prod = ring_prod;
}
}
@@ -814,109 +869,29 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
struct bnx2x_fastpath *fp = &bp->fp[j];
fp->rx_bd_cons = 0;
- fp->rx_cons_sb = BNX2X_RX_SB_INDEX;
- fp->rx_bd_cons_sb = BNX2X_RX_SB_BD_INDEX;
-
- /* "next page" elements initialization */
- /* SGE ring */
- for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
- struct eth_rx_sge *sge;
-
- sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2];
- sge->addr_hi =
- cpu_to_le32(U64_HI(fp->rx_sge_mapping +
- BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES)));
- sge->addr_lo =
- cpu_to_le32(U64_LO(fp->rx_sge_mapping +
- BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES)));
- }
-
- bnx2x_init_sge_ring_bit_mask(fp);
- /* RX BD ring */
- for (i = 1; i <= NUM_RX_RINGS; i++) {
- struct eth_rx_bd *rx_bd;
-
- rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2];
- rx_bd->addr_hi =
- cpu_to_le32(U64_HI(fp->rx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
- rx_bd->addr_lo =
- cpu_to_le32(U64_LO(fp->rx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
- }
+ bnx2x_set_next_page_rx_bd(fp);
/* CQ ring */
- for (i = 1; i <= NUM_RCQ_RINGS; i++) {
- struct eth_rx_cqe_next_page *nextpg;
-
- nextpg = (struct eth_rx_cqe_next_page *)
- &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1];
- nextpg->addr_hi =
- cpu_to_le32(U64_HI(fp->rx_comp_mapping +
- BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
- nextpg->addr_lo =
- cpu_to_le32(U64_LO(fp->rx_comp_mapping +
- BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
- }
-
- /* Allocate SGEs and initialize the ring elements */
- for (i = 0, ring_prod = 0;
- i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) {
-
- if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) {
- BNX2X_ERR("was only able to allocate "
- "%d rx sges\n", i);
- BNX2X_ERR("disabling TPA for queue[%d]\n", j);
- /* Cleanup already allocated elements */
- bnx2x_free_rx_sge_range(bp, fp, ring_prod);
- bnx2x_free_tpa_pool(bp, fp, max_agg_queues);
- fp->disable_tpa = 1;
- ring_prod = 0;
- break;
- }
- ring_prod = NEXT_SGE_IDX(ring_prod);
- }
- fp->rx_sge_prod = ring_prod;
+ bnx2x_set_next_page_rx_cq(fp);
/* Allocate BDs and initialize BD ring */
- fp->rx_comp_cons = 0;
- cqe_ring_prod = ring_prod = 0;
- for (i = 0; i < bp->rx_ring_size; i++) {
- if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
- BNX2X_ERR("was only able to allocate "
- "%d rx skbs on queue[%d]\n", i, j);
- 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);
- }
+ bnx2x_alloc_rx_bd_ring(fp);
- fp->rx_bd_prod = ring_prod;
- /* must not have more available CQEs than BDs */
- fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT,
- cqe_ring_prod);
- fp->rx_pkt = fp->rx_calls = 0;
-
- /* Warning!
- * this will generate an interrupt (to the TSTORM)
- * must only be done after chip is initialized
- */
- bnx2x_update_rx_prod(bp, fp, ring_prod, fp->rx_comp_prod,
- fp->rx_sge_prod);
if (j != 0)
continue;
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func),
- U64_LO(fp->rx_comp_mapping));
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4,
- U64_HI(fp->rx_comp_mapping));
+ if (!CHIP_IS_E2(bp)) {
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func),
+ U64_LO(fp->rx_comp_mapping));
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4,
+ U64_HI(fp->rx_comp_mapping));
+ }
}
}
+
static void bnx2x_free_tx_skbs(struct bnx2x *bp)
{
int i;
@@ -989,55 +964,49 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp)
}
}
-void bnx2x_free_irq(struct bnx2x *bp, bool disable_only)
+void bnx2x_free_irq(struct bnx2x *bp)
{
- if (bp->flags & USING_MSIX_FLAG) {
- if (!disable_only)
- bnx2x_free_msix_irqs(bp);
- pci_disable_msix(bp->pdev);
- bp->flags &= ~USING_MSIX_FLAG;
-
- } else if (bp->flags & USING_MSI_FLAG) {
- if (!disable_only)
- free_irq(bp->pdev->irq, bp->dev);
- pci_disable_msi(bp->pdev);
- bp->flags &= ~USING_MSI_FLAG;
-
- } else if (!disable_only)
+ if (bp->flags & USING_MSIX_FLAG)
+ bnx2x_free_msix_irqs(bp);
+ else if (bp->flags & USING_MSI_FLAG)
+ free_irq(bp->pdev->irq, bp->dev);
+ else
free_irq(bp->pdev->irq, bp->dev);
}
-static int bnx2x_enable_msix(struct bnx2x *bp)
+int bnx2x_enable_msix(struct bnx2x *bp)
{
- int i, rc, offset = 1;
- int igu_vec = 0;
+ int msix_vec = 0, i, rc, req_cnt;
- bp->msix_table[0].entry = igu_vec;
- DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", igu_vec);
+ bp->msix_table[msix_vec].entry = msix_vec;
+ DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n",
+ bp->msix_table[0].entry);
+ msix_vec++;
#ifdef BCM_CNIC
- igu_vec = BP_L_ID(bp) + offset;
- bp->msix_table[1].entry = igu_vec;
- DP(NETIF_MSG_IFUP, "msix_table[1].entry = %d (CNIC)\n", igu_vec);
- offset++;
+ bp->msix_table[msix_vec].entry = msix_vec;
+ DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d (CNIC)\n",
+ bp->msix_table[msix_vec].entry, bp->msix_table[msix_vec].entry);
+ msix_vec++;
#endif
for_each_queue(bp, i) {
- igu_vec = BP_L_ID(bp) + offset + i;
- bp->msix_table[i + offset].entry = igu_vec;
+ bp->msix_table[msix_vec].entry = msix_vec;
DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d "
- "(fastpath #%u)\n", i + offset, igu_vec, i);
+ "(fastpath #%u)\n", msix_vec, msix_vec, i);
+ msix_vec++;
}
- rc = pci_enable_msix(bp->pdev, &bp->msix_table[0],
- BNX2X_NUM_QUEUES(bp) + offset);
+ req_cnt = BNX2X_NUM_QUEUES(bp) + CNIC_CONTEXT_USE + 1;
+
+ rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt);
/*
* reconfigure number of tx/rx queues according to available
* MSI-X vectors
*/
if (rc >= BNX2X_MIN_MSIX_VEC_CNT) {
- /* vectors available for FP */
- int fp_vec = rc - BNX2X_MSIX_VEC_FP_START;
+ /* how less vectors we will have? */
+ int diff = req_cnt - rc;
DP(NETIF_MSG_IFUP,
"Trying to use less MSI-X vectors: %d\n", rc);
@@ -1049,12 +1018,17 @@ static int bnx2x_enable_msix(struct bnx2x *bp)
"MSI-X is not attainable rc %d\n", rc);
return rc;
}
-
- bp->num_queues = min(bp->num_queues, fp_vec);
+ /*
+ * decrease number of queues by number of unallocated entries
+ */
+ bp->num_queues -= diff;
DP(NETIF_MSG_IFUP, "New queue configuration set: %d\n",
bp->num_queues);
} else if (rc) {
+ /* fall to INTx if not enough memory */
+ if (rc == -ENOMEM)
+ bp->flags |= DISABLE_MSI_FLAG;
DP(NETIF_MSG_IFUP, "MSI-X is not attainable rc %d\n", rc);
return rc;
}
@@ -1083,7 +1057,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
snprintf(fp->name, sizeof(fp->name), "%s-fp-%d",
bp->dev->name, i);
- rc = request_irq(bp->msix_table[i + offset].vector,
+ rc = request_irq(bp->msix_table[offset].vector,
bnx2x_msix_fp_int, 0, fp->name, fp);
if (rc) {
BNX2X_ERR("request fp #%d irq failed rc %d\n", i, rc);
@@ -1091,10 +1065,12 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
return -EBUSY;
}
+ offset++;
fp->state = BNX2X_FP_STATE_IRQ;
}
i = BNX2X_NUM_QUEUES(bp);
+ offset = 1 + CNIC_CONTEXT_USE;
netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d"
" ... fp[%d] %d\n",
bp->msix_table[0].vector,
@@ -1104,7 +1080,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
return 0;
}
-static int bnx2x_enable_msi(struct bnx2x *bp)
+int bnx2x_enable_msi(struct bnx2x *bp)
{
int rc;
@@ -1175,35 +1151,29 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
bnx2x_napi_disable(bp);
netif_tx_disable(bp->dev);
}
-static int bnx2x_set_num_queues(struct bnx2x *bp)
-{
- int rc = 0;
- switch (bp->int_mode) {
- case INT_MODE_INTx:
- case INT_MODE_MSI:
+void bnx2x_set_num_queues(struct bnx2x *bp)
+{
+ switch (bp->multi_mode) {
+ case ETH_RSS_MODE_DISABLED:
bp->num_queues = 1;
- DP(NETIF_MSG_IFUP, "set number of queues to 1\n");
break;
- default:
- /* Set number of queues according to bp->multi_mode value */
- bnx2x_set_num_queues_msix(bp);
-
- DP(NETIF_MSG_IFUP, "set number of queues to %d\n",
- bp->num_queues);
+ case ETH_RSS_MODE_REGULAR:
+ bp->num_queues = bnx2x_calc_num_queues(bp);
+ break;
- /* if we can't use MSI-X we only need one fp,
- * so try to enable MSI-X with the requested number of fp's
- * and fallback to MSI or legacy INTx with one fp
- */
- rc = bnx2x_enable_msix(bp);
- if (rc)
- /* failed to enable MSI-X */
- bp->num_queues = 1;
+ default:
+ bp->num_queues = 1;
break;
}
- bp->dev->real_num_tx_queues = bp->num_queues;
- return rc;
+}
+
+static void bnx2x_release_firmware(struct bnx2x *bp)
+{
+ kfree(bp->init_ops_offsets);
+ kfree(bp->init_ops);
+ kfree(bp->init_data);
+ release_firmware(bp->firmware);
}
/* must be called with rtnl_lock */
@@ -1212,6 +1182,13 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
u32 load_code;
int i, rc;
+ /* Set init arrays */
+ rc = bnx2x_init_firmware(bp);
+ if (rc) {
+ BNX2X_ERR("Error loading firmware\n");
+ return rc;
+ }
+
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
return -EPERM;
@@ -1219,83 +1196,64 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
- rc = bnx2x_set_num_queues(bp);
+ /* must be called before memory allocation and HW init */
+ bnx2x_ilt_set_info(bp);
- if (bnx2x_alloc_mem(bp)) {
- bnx2x_free_irq(bp, true);
+ if (bnx2x_alloc_mem(bp))
return -ENOMEM;
+
+ netif_set_real_num_tx_queues(bp->dev, bp->num_queues);
+ rc = netif_set_real_num_rx_queues(bp->dev, bp->num_queues);
+ if (rc) {
+ BNX2X_ERR("Unable to update real_num_rx_queues\n");
+ goto load_error0;
}
for_each_queue(bp, i)
bnx2x_fp(bp, i, disable_tpa) =
((bp->flags & TPA_ENABLE_FLAG) == 0);
- for_each_queue(bp, i)
- netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
- bnx2x_poll, 128);
-
bnx2x_napi_enable(bp);
- if (bp->flags & USING_MSIX_FLAG) {
- rc = bnx2x_req_msix_irqs(bp);
- if (rc) {
- bnx2x_free_irq(bp, true);
- goto load_error1;
- }
- } else {
- /* Fall to INTx if failed to enable MSI-X due to lack of
- memory (in bnx2x_set_num_queues()) */
- if ((rc != -ENOMEM) && (bp->int_mode != INT_MODE_INTx))
- bnx2x_enable_msi(bp);
- bnx2x_ack_int(bp);
- rc = bnx2x_req_irq(bp);
- if (rc) {
- BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
- bnx2x_free_irq(bp, true);
- goto load_error1;
- }
- if (bp->flags & USING_MSI_FLAG) {
- bp->dev->irq = bp->pdev->irq;
- netdev_info(bp->dev, "using MSI IRQ %d\n",
- bp->pdev->irq);
- }
- }
-
/* Send LOAD_REQUEST command to MCP
Returns the type of LOAD command:
if it is the first port to be initialized
common blocks should be initialized, otherwise - not
*/
if (!BP_NOMCP(bp)) {
- load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0);
if (!load_code) {
BNX2X_ERR("MCP response failure, aborting\n");
rc = -EBUSY;
- goto load_error2;
+ goto load_error1;
}
if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
rc = -EBUSY; /* other port in diagnostic mode */
- goto load_error2;
+ goto load_error1;
}
} else {
+ int path = BP_PATH(bp);
int port = BP_PORT(bp);
- DP(NETIF_MSG_IFUP, "NO MCP - load counts %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- load_count[0]++;
- load_count[1 + port]++;
- DP(NETIF_MSG_IFUP, "NO MCP - new load counts %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- if (load_count[0] == 1)
+ DP(NETIF_MSG_IFUP, "NO MCP - load counts[%d] %d, %d, %d\n",
+ path, load_count[path][0], load_count[path][1],
+ load_count[path][2]);
+ load_count[path][0]++;
+ load_count[path][1 + port]++;
+ DP(NETIF_MSG_IFUP, "NO MCP - new load counts[%d] %d, %d, %d\n",
+ path, load_count[path][0], load_count[path][1],
+ load_count[path][2]);
+ if (load_count[path][0] == 1)
load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
- else if (load_count[1 + port] == 1)
+ else if (load_count[path][1 + port] == 1)
load_code = FW_MSG_CODE_DRV_LOAD_PORT;
else
load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
}
if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
+ (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) ||
(load_code == FW_MSG_CODE_DRV_LOAD_PORT))
bp->port.pmf = 1;
else
@@ -1306,16 +1264,22 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
rc = bnx2x_init_hw(bp, load_code);
if (rc) {
BNX2X_ERR("HW init failed, aborting\n");
- bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP);
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
+ goto load_error2;
+ }
+
+ /* Connect to IRQs */
+ rc = bnx2x_setup_irqs(bp);
+ if (rc) {
+ bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
goto load_error2;
}
/* Setup NIC internals and enable interrupts */
bnx2x_nic_init(bp, load_code);
- if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) &&
+ if (((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
+ (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP)) &&
(bp->common.shmem2_base))
SHMEM2_WR(bp, dcc_support,
(SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV |
@@ -1323,7 +1287,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
/* Send LOAD_DONE command to MCP */
if (!BP_NOMCP(bp)) {
- load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
if (!load_code) {
BNX2X_ERR("MCP response failure, aborting\n");
rc = -EBUSY;
@@ -1333,7 +1297,18 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bp->state = BNX2X_STATE_OPENING_WAIT4_PORT;
- rc = bnx2x_setup_leading(bp);
+ rc = bnx2x_func_start(bp);
+ if (rc) {
+ BNX2X_ERR("Function start failed!\n");
+#ifndef BNX2X_STOP_ON_ERROR
+ goto load_error3;
+#else
+ bp->panic = 1;
+ return -EBUSY;
+#endif
+ }
+
+ rc = bnx2x_setup_client(bp, &bp->fp[0], 1 /* Leading */);
if (rc) {
BNX2X_ERR("Setup leading failed!\n");
#ifndef BNX2X_STOP_ON_ERROR
@@ -1344,62 +1319,47 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
#endif
}
- if (CHIP_IS_E1H(bp))
- if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
- DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n");
- bp->flags |= MF_FUNC_DIS;
- }
+ if (!CHIP_IS_E1(bp) &&
+ (bp->mf_config[BP_VN(bp)] & FUNC_MF_CFG_FUNC_DISABLED)) {
+ DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n");
+ bp->flags |= MF_FUNC_DIS;
+ }
- if (bp->state == BNX2X_STATE_OPEN) {
-#ifdef BCM_CNIC
- /* Enable Timer scan */
- REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1);
-#endif
- for_each_nondefault_queue(bp, i) {
- rc = bnx2x_setup_multi(bp, i);
- if (rc)
#ifdef BCM_CNIC
- goto load_error4;
-#else
- goto load_error3;
+ /* Enable Timer scan */
+ REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1);
#endif
- }
- if (CHIP_IS_E1(bp))
- bnx2x_set_eth_mac_addr_e1(bp, 1);
- else
- bnx2x_set_eth_mac_addr_e1h(bp, 1);
+ for_each_nondefault_queue(bp, i) {
+ rc = bnx2x_setup_client(bp, &bp->fp[i], 0);
+ if (rc)
#ifdef BCM_CNIC
- /* Set iSCSI L2 MAC */
- mutex_lock(&bp->cnic_mutex);
- if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) {
- bnx2x_set_iscsi_eth_mac_addr(bp, 1);
- bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET;
- bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping,
- CNIC_SB_ID(bp));
- }
- mutex_unlock(&bp->cnic_mutex);
+ goto load_error4;
+#else
+ goto load_error3;
#endif
}
+ /* Now when Clients are configured we are ready to work */
+ bp->state = BNX2X_STATE_OPEN;
+
+ bnx2x_set_eth_mac(bp, 1);
+
if (bp->port.pmf)
bnx2x_initial_phy_init(bp, load_mode);
/* Start fast path */
switch (load_mode) {
case LOAD_NORMAL:
- if (bp->state == BNX2X_STATE_OPEN) {
- /* Tx queue should be only reenabled */
- netif_tx_wake_all_queues(bp->dev);
- }
+ /* Tx queue should be only reenabled */
+ netif_tx_wake_all_queues(bp->dev);
/* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
break;
case LOAD_OPEN:
netif_tx_start_all_queues(bp->dev);
- if (bp->state != BNX2X_STATE_OPEN)
- netif_tx_disable(bp->dev);
+ smp_mb__after_clear_bit();
/* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
break;
@@ -1427,6 +1387,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
#endif
bnx2x_inc_load_cnt(bp);
+ bnx2x_release_firmware(bp);
+
return 0;
#ifdef BCM_CNIC
@@ -1436,24 +1398,28 @@ load_error4:
#endif
load_error3:
bnx2x_int_disable_sync(bp, 1);
- if (!BP_NOMCP(bp)) {
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP);
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
- }
- bp->port.pmf = 0;
+
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
for_each_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-load_error2:
+
/* Release IRQs */
- bnx2x_free_irq(bp, false);
+ bnx2x_free_irq(bp);
+load_error2:
+ if (!BP_NOMCP(bp)) {
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
+ }
+
+ bp->port.pmf = 0;
load_error1:
bnx2x_napi_disable(bp);
- for_each_queue(bp, i)
- netif_napi_del(&bnx2x_fp(bp, i, napi));
+load_error0:
bnx2x_free_mem(bp);
+ bnx2x_release_firmware(bp);
+
return rc;
}
@@ -1481,21 +1447,26 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
bp->rx_mode = BNX2X_RX_MODE_NONE;
bnx2x_set_storm_rx_mode(bp);
- /* Disable HW interrupts, NAPI and Tx */
- bnx2x_netif_stop(bp, 1);
- netif_carrier_off(bp->dev);
+ /* Stop Tx */
+ bnx2x_tx_disable(bp);
del_timer_sync(&bp->timer);
- SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
+
+ SHMEM_WR(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb,
(DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
- bnx2x_stats_handle(bp, STATS_EVENT_STOP);
- /* Release IRQs */
- bnx2x_free_irq(bp, false);
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
/* Cleanup the chip if needed */
if (unload_mode != UNLOAD_RECOVERY)
bnx2x_chip_cleanup(bp, unload_mode);
+ else {
+ /* Disable HW interrupts, NAPI and Tx */
+ bnx2x_netif_stop(bp, 1);
+
+ /* Release IRQs */
+ bnx2x_free_irq(bp);
+ }
bp->port.pmf = 0;
@@ -1503,8 +1474,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
bnx2x_free_skbs(bp);
for_each_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
- for_each_queue(bp, i)
- netif_napi_del(&bnx2x_fp(bp, i, napi));
+
bnx2x_free_mem(bp);
bp->state = BNX2X_STATE_CLOSED;
@@ -1522,10 +1492,17 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
return 0;
}
+
int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
{
u16 pmcsr;
+ /* If there is no power capability, silently succeed */
+ if (!bp->pm_cap) {
+ DP(NETIF_MSG_HW, "No power capability. Breaking.\n");
+ return 0;
+ }
+
pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr);
switch (state) {
@@ -1568,13 +1545,10 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
return 0;
}
-
-
/*
* net_device service functions
*/
-
-static int bnx2x_poll(struct napi_struct *napi, int budget)
+int bnx2x_poll(struct napi_struct *napi, int budget)
{
int work_done = 0;
struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath,
@@ -1603,27 +1577,28 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
/* Fall out from the NAPI loop if needed */
if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
bnx2x_update_fpsb_idx(fp);
- /* bnx2x_has_rx_work() reads the status block, thus we need
- * to ensure that status block indices have been actually read
- * (bnx2x_update_fpsb_idx) prior to this check
- * (bnx2x_has_rx_work) so that we won't write the "newer"
- * value of the status block to IGU (if there was a DMA right
- * after bnx2x_has_rx_work and if there is no rmb, the memory
- * reading (bnx2x_update_fpsb_idx) may be postponed to right
- * before bnx2x_ack_sb). In this case there will never be
- * another interrupt until there is another update of the
- * status block, while there is still unhandled work.
- */
+ /* bnx2x_has_rx_work() reads the status block,
+ * thus we need to ensure that status block indices
+ * have been actually read (bnx2x_update_fpsb_idx)
+ * prior to this check (bnx2x_has_rx_work) so that
+ * we won't write the "newer" value of the status block
+ * to IGU (if there was a DMA right after
+ * bnx2x_has_rx_work and if there is no rmb, the memory
+ * reading (bnx2x_update_fpsb_idx) may be postponed
+ * to right before bnx2x_ack_sb). In this case there
+ * will never be another interrupt until there is
+ * another update of the status block, while there
+ * is still unhandled work.
+ */
rmb();
if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
napi_complete(napi);
/* Re-enable interrupts */
- bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
- le16_to_cpu(fp->fp_c_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID,
- le16_to_cpu(fp->fp_u_idx),
+ DP(NETIF_MSG_HW,
+ "Update index to %d\n", fp->fp_hc_idx);
+ bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID,
+ le16_to_cpu(fp->fp_hc_idx),
IGU_INT_ENABLE, 1);
break;
}
@@ -1633,7 +1608,6 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
return work_done;
}
-
/* we split the first BD into headers and data BDs
* to ease the pain of our fellow microcode engineers
* we use one mapping for both BDs
@@ -1807,6 +1781,122 @@ exit_lbl:
}
#endif
+static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb,
+ struct eth_tx_parse_bd_e2 *pbd,
+ u32 xmit_type)
+{
+ pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) <<
+ ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT;
+ if ((xmit_type & XMIT_GSO_V6) &&
+ (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6))
+ pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
+}
+
+/**
+ * Update PBD in GSO case.
+ *
+ * @param skb
+ * @param tx_start_bd
+ * @param pbd
+ * @param xmit_type
+ */
+static inline void bnx2x_set_pbd_gso(struct sk_buff *skb,
+ struct eth_tx_parse_bd_e1x *pbd,
+ u32 xmit_type)
+{
+ pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
+ pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq);
+ pbd->tcp_flags = pbd_tcp_flags(skb);
+
+ if (xmit_type & XMIT_GSO_V4) {
+ pbd->ip_id = swab16(ip_hdr(skb)->id);
+ pbd->tcp_pseudo_csum =
+ swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr,
+ ip_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0));
+
+ } else
+ pbd->tcp_pseudo_csum =
+ swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0));
+
+ pbd->global_data |= ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN;
+}
+
+/**
+ *
+ * @param skb
+ * @param tx_start_bd
+ * @param pbd_e2
+ * @param xmit_type
+ *
+ * @return header len
+ */
+static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
+ struct eth_tx_parse_bd_e2 *pbd,
+ u32 xmit_type)
+{
+ pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) <<
+ ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT;
+
+ pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) -
+ skb->data) / 2) <<
+ ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT;
+
+ return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data;
+}
+
+/**
+ *
+ * @param skb
+ * @param tx_start_bd
+ * @param pbd
+ * @param xmit_type
+ *
+ * @return Header length
+ */
+static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb,
+ struct eth_tx_parse_bd_e1x *pbd,
+ u32 xmit_type)
+{
+ u8 hlen = (skb_network_header(skb) - skb->data) / 2;
+
+ /* for now NS flag is not used in Linux */
+ pbd->global_data =
+ (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) <<
+ ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT));
+
+ pbd->ip_hlen_w = (skb_transport_header(skb) -
+ skb_network_header(skb)) / 2;
+
+ hlen += pbd->ip_hlen_w + tcp_hdrlen(skb) / 2;
+
+ pbd->total_hlen_w = cpu_to_le16(hlen);
+ hlen = hlen*2;
+
+ if (xmit_type & XMIT_CSUM_TCP) {
+ pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check);
+
+ } else {
+ s8 fix = SKB_CS_OFF(skb); /* signed! */
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "hlen %d fix %d csum before fix %x\n",
+ le16_to_cpu(pbd->total_hlen_w), fix, SKB_CS(skb));
+
+ /* HW bug: fixup the CSUM */
+ pbd->tcp_pseudo_csum =
+ bnx2x_csum_fix(skb_transport_header(skb),
+ SKB_CS(skb), fix);
+
+ DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n",
+ pbd->tcp_pseudo_csum);
+ }
+
+ return hlen;
+}
+
/* called with netif_tx_lock
* bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
* netif_wake_queue()
@@ -1819,7 +1909,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct sw_tx_bd *tx_buf;
struct eth_tx_start_bd *tx_start_bd;
struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL;
- struct eth_tx_parse_bd *pbd = NULL;
+ struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
+ struct eth_tx_parse_bd_e2 *pbd_e2 = NULL;
u16 pkt_prod, bd_prod;
int nbd, fp_index;
dma_addr_t mapping;
@@ -1847,9 +1938,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
}
- DP(NETIF_MSG_TX_QUEUED, "SKB: summed %x protocol %x protocol(%x,%x)"
- " gso type %x xmit_type %x\n",
- skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr,
+ DP(NETIF_MSG_TX_QUEUED, "queue[%d]: SKB: summed %x protocol %x "
+ "protocol(%x,%x) gso type %x xmit_type %x\n",
+ fp_index, skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr,
ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
eth = (struct ethhdr *)skb->data;
@@ -1895,10 +1986,11 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd;
tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
- tx_start_bd->general_data = (mac_type <<
- ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT);
+ SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_ETH_ADDR_TYPE,
+ mac_type);
+
/* header nbd */
- tx_start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT);
+ SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_HDR_NBDS, 1);
/* remember the first BD of the packet */
tx_buf->first_bd = fp->tx_bd_prod;
@@ -1909,37 +2001,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
"sending pkt %u @%p next_idx %u bd %u @%p\n",
pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd);
-#ifdef BCM_VLAN
- if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) &&
- (bp->flags & HW_VLAN_TX_FLAG)) {
- tx_start_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb));
- tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG;
+ if (vlan_tx_tag_present(skb)) {
+ tx_start_bd->vlan_or_ethertype =
+ cpu_to_le16(vlan_tx_tag_get(skb));
+ tx_start_bd->bd_flags.as_bitfield |=
+ (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
} else
-#endif
- tx_start_bd->vlan = cpu_to_le16(pkt_prod);
+ tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
/* turn on parsing and get a BD */
bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
- pbd = &fp->tx_desc_ring[bd_prod].parse_bd;
-
- memset(pbd, 0, sizeof(struct eth_tx_parse_bd));
if (xmit_type & XMIT_CSUM) {
- hlen = (skb_network_header(skb) - skb->data) / 2;
-
- /* for now NS flag is not used in Linux */
- pbd->global_data =
- (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) <<
- ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
-
- pbd->ip_hlen = (skb_transport_header(skb) -
- skb_network_header(skb)) / 2;
-
- hlen += pbd->ip_hlen + tcp_hdrlen(skb) / 2;
-
- pbd->total_hlen = cpu_to_le16(hlen);
- hlen = hlen*2;
-
tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM;
if (xmit_type & XMIT_CSUM_V4)
@@ -1949,31 +2022,32 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_start_bd->bd_flags.as_bitfield |=
ETH_TX_BD_FLAGS_IPV6;
- if (xmit_type & XMIT_CSUM_TCP) {
- pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check);
-
- } else {
- s8 fix = SKB_CS_OFF(skb); /* signed! */
-
- pbd->global_data |= ETH_TX_PARSE_BD_UDP_CS_FLG;
-
- DP(NETIF_MSG_TX_QUEUED,
- "hlen %d fix %d csum before fix %x\n",
- le16_to_cpu(pbd->total_hlen), fix, SKB_CS(skb));
+ if (!(xmit_type & XMIT_CSUM_TCP))
+ tx_start_bd->bd_flags.as_bitfield |=
+ ETH_TX_BD_FLAGS_IS_UDP;
+ }
- /* HW bug: fixup the CSUM */
- pbd->tcp_pseudo_csum =
- bnx2x_csum_fix(skb_transport_header(skb),
- SKB_CS(skb), fix);
+ if (CHIP_IS_E2(bp)) {
+ pbd_e2 = &fp->tx_desc_ring[bd_prod].parse_bd_e2;
+ memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
+ /* Set PBD in checksum offload case */
+ if (xmit_type & XMIT_CSUM)
+ hlen = bnx2x_set_pbd_csum_e2(bp,
+ skb, pbd_e2, xmit_type);
+ } else {
+ pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x;
+ memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
+ /* Set PBD in checksum offload case */
+ if (xmit_type & XMIT_CSUM)
+ hlen = bnx2x_set_pbd_csum(bp, skb, pbd_e1x, xmit_type);
- DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n",
- pbd->tcp_pseudo_csum);
- }
}
+ /* Map skb linear data for DMA */
mapping = dma_map_single(&bp->pdev->dev, skb->data,
skb_headlen(skb), DMA_TO_DEVICE);
+ /* Setup the data pointer of the first BD of the packet */
tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
nbd = skb_shinfo(skb)->nr_frags + 2; /* start_bd + pbd + frags */
@@ -1985,7 +2059,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
" nbytes %d flags %x vlan %x\n",
tx_start_bd, tx_start_bd->addr_hi, tx_start_bd->addr_lo,
le16_to_cpu(tx_start_bd->nbd), le16_to_cpu(tx_start_bd->nbytes),
- tx_start_bd->bd_flags.as_bitfield, le16_to_cpu(tx_start_bd->vlan));
+ tx_start_bd->bd_flags.as_bitfield,
+ le16_to_cpu(tx_start_bd->vlan_or_ethertype));
if (xmit_type & XMIT_GSO) {
@@ -1999,28 +2074,14 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(skb_headlen(skb) > hlen))
bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd,
hlen, bd_prod, ++nbd);
-
- pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
- pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq);
- pbd->tcp_flags = pbd_tcp_flags(skb);
-
- if (xmit_type & XMIT_GSO_V4) {
- pbd->ip_id = swab16(ip_hdr(skb)->id);
- pbd->tcp_pseudo_csum =
- swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr,
- ip_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0));
-
- } else
- pbd->tcp_pseudo_csum =
- swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
- &ipv6_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0));
-
- pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN;
+ if (CHIP_IS_E2(bp))
+ bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type);
+ else
+ bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type);
}
tx_data_bd = (struct eth_tx_bd *)tx_start_bd;
+ /* Handle fragmented skb */
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -2057,14 +2118,21 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (total_pkt_bd != NULL)
total_pkt_bd->total_pkt_bytes = pkt_size;
- if (pbd)
+ if (pbd_e1x)
DP(NETIF_MSG_TX_QUEUED,
- "PBD @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u"
+ "PBD (E1X) @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u"
" tcp_flags %x xsum %x seq %u hlen %u\n",
- pbd, pbd->global_data, pbd->ip_hlen, pbd->ip_id,
- pbd->lso_mss, pbd->tcp_flags, pbd->tcp_pseudo_csum,
- pbd->tcp_send_seq, le16_to_cpu(pbd->total_hlen));
-
+ pbd_e1x, pbd_e1x->global_data, pbd_e1x->ip_hlen_w,
+ pbd_e1x->ip_id, pbd_e1x->lso_mss, pbd_e1x->tcp_flags,
+ pbd_e1x->tcp_pseudo_csum, pbd_e1x->tcp_send_seq,
+ le16_to_cpu(pbd_e1x->total_hlen_w));
+ if (pbd_e2)
+ DP(NETIF_MSG_TX_QUEUED,
+ "PBD (E2) @%p dst %x %x %x src %x %x %x parsing_data %x\n",
+ pbd_e2, pbd_e2->dst_mac_addr_hi, pbd_e2->dst_mac_addr_mid,
+ pbd_e2->dst_mac_addr_lo, pbd_e2->src_mac_addr_hi,
+ pbd_e2->src_mac_addr_mid, pbd_e2->src_mac_addr_lo,
+ pbd_e2->parsing_data);
DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod);
/*
@@ -2078,7 +2146,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
fp->tx_db.data.prod += nbd;
barrier();
- DOORBELL(bp, fp->index, fp->tx_db.raw);
+
+ DOORBELL(bp, fp->cid, fp->tx_db.raw);
mmiowb();
@@ -2100,6 +2169,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
+
/* called with rtnl_lock */
int bnx2x_change_mac_addr(struct net_device *dev, void *p)
{
@@ -2110,16 +2180,76 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p)
return -EINVAL;
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
- if (netif_running(dev)) {
- if (CHIP_IS_E1(bp))
- bnx2x_set_eth_mac_addr_e1(bp, 1);
- else
- bnx2x_set_eth_mac_addr_e1h(bp, 1);
+ if (netif_running(dev))
+ bnx2x_set_eth_mac(bp, 1);
+
+ return 0;
+}
+
+
+int bnx2x_setup_irqs(struct bnx2x *bp)
+{
+ int rc = 0;
+ if (bp->flags & USING_MSIX_FLAG) {
+ rc = bnx2x_req_msix_irqs(bp);
+ if (rc)
+ return rc;
+ } else {
+ bnx2x_ack_int(bp);
+ rc = bnx2x_req_irq(bp);
+ if (rc) {
+ BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
+ return rc;
+ }
+ if (bp->flags & USING_MSI_FLAG) {
+ bp->dev->irq = bp->pdev->irq;
+ netdev_info(bp->dev, "using MSI IRQ %d\n",
+ bp->pdev->irq);
+ }
}
return 0;
}
+void bnx2x_free_mem_bp(struct bnx2x *bp)
+{
+ kfree(bp->fp);
+ kfree(bp->msix_table);
+ kfree(bp->ilt);
+}
+
+int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp)
+{
+ struct bnx2x_fastpath *fp;
+ struct msix_entry *tbl;
+ struct bnx2x_ilt *ilt;
+
+ /* fp array */
+ fp = kzalloc(L2_FP_COUNT(bp->l2_cid_count)*sizeof(*fp), GFP_KERNEL);
+ if (!fp)
+ goto alloc_err;
+ bp->fp = fp;
+
+ /* msix table */
+ tbl = kzalloc((bp->l2_cid_count + 1) * sizeof(*tbl),
+ GFP_KERNEL);
+ if (!tbl)
+ goto alloc_err;
+ bp->msix_table = tbl;
+
+ /* ilt */
+ ilt = kzalloc(sizeof(*ilt), GFP_KERNEL);
+ if (!ilt)
+ goto alloc_err;
+ bp->ilt = ilt;
+
+ return 0;
+alloc_err:
+ bnx2x_free_mem_bp(bp);
+ return -ENOMEM;
+
+}
+
/* called with rtnl_lock */
int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
{
@@ -2161,29 +2291,6 @@ void bnx2x_tx_timeout(struct net_device *dev)
schedule_delayed_work(&bp->reset_task, 0);
}
-#ifdef BCM_VLAN
-/* called with rtnl_lock */
-void bnx2x_vlan_rx_register(struct net_device *dev,
- struct vlan_group *vlgrp)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- bp->vlgrp = vlgrp;
-
- /* Set flags according to the required capabilities */
- bp->flags &= ~(HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
-
- if (dev->features & NETIF_F_HW_VLAN_TX)
- bp->flags |= HW_VLAN_TX_FLAG;
-
- if (dev->features & NETIF_F_HW_VLAN_RX)
- bp->flags |= HW_VLAN_RX_FLAG;
-
- if (netif_running(dev))
- bnx2x_set_client_config(bp);
-}
-
-#endif
int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -2244,6 +2351,8 @@ int bnx2x_resume(struct pci_dev *pdev)
bnx2x_set_power_state(bp, PCI_D0);
netif_device_attach(dev);
+ /* Since the chip was reset, clear the FW sequence number */
+ bp->fw_seq = 0;
rc = bnx2x_nic_load(bp, LOAD_OPEN);
rtnl_unlock();
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index d1979b1a7ed2..5bfe0ab1d2d4 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -23,6 +23,7 @@
#include "bnx2x.h"
+extern int num_queues;
/*********************** Interfaces ****************************
* Functions that need to be implemented by each driver version
@@ -49,10 +50,11 @@ void bnx2x_link_set(struct bnx2x *bp);
* Query link status
*
* @param bp
+ * @param is_serdes
*
* @return 0 - link is UP
*/
-u8 bnx2x_link_test(struct bnx2x *bp);
+u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes);
/**
* Handles link status change
@@ -62,6 +64,15 @@ u8 bnx2x_link_test(struct bnx2x *bp);
void bnx2x__link_status_update(struct bnx2x *bp);
/**
+ * Report link status to upper layer
+ *
+ * @param bp
+ *
+ * @return int
+ */
+void bnx2x_link_report(struct bnx2x *bp);
+
+/**
* MSI-X slowpath interrupt handler
*
* @param irq
@@ -106,6 +117,13 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp);
void bnx2x_int_enable(struct bnx2x *bp);
/**
+ * Disable HW interrupts.
+ *
+ * @param bp
+ */
+void bnx2x_int_disable(struct bnx2x *bp);
+
+/**
* Disable interrupts. This function ensures that there are no
* ISRs or SP DPCs (sp_task) are running after it returns.
*
@@ -115,6 +133,15 @@ void bnx2x_int_enable(struct bnx2x *bp);
void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw);
/**
+ * Loads device firmware
+ *
+ * @param bp
+ *
+ * @return int
+ */
+int bnx2x_init_firmware(struct bnx2x *bp);
+
+/**
* Init HW blocks according to current initialization stage:
* COMMON, PORT or FUNCTION.
*
@@ -153,32 +180,35 @@ int bnx2x_alloc_mem(struct bnx2x *bp);
void bnx2x_free_mem(struct bnx2x *bp);
/**
- * Bring up a leading (the first) eth Client.
+ * Setup eth Client.
*
* @param bp
+ * @param fp
+ * @param is_leading
*
* @return int
*/
-int bnx2x_setup_leading(struct bnx2x *bp);
+int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ int is_leading);
/**
- * Setup non-leading eth Client.
+ * Bring down an eth client.
*
* @param bp
- * @param fp
+ * @param p
*
* @return int
*/
-int bnx2x_setup_multi(struct bnx2x *bp, int index);
+int bnx2x_stop_fw_client(struct bnx2x *bp,
+ struct bnx2x_client_ramrod_params *p);
/**
- * Set number of quueus according to mode and number of available
- * msi-x vectors
+ * Set number of queues according to mode
*
* @param bp
*
*/
-void bnx2x_set_num_queues_msix(struct bnx2x *bp);
+void bnx2x_set_num_queues(struct bnx2x *bp);
/**
* Cleanup chip internals:
@@ -213,21 +243,12 @@ 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 for 57711
- *
- * @param bp driver handle
- * @param set
- */
-void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set);
-
-/**
- * Configure eth MAC address in the HW according to the value in
- * netdev->dev_addr for 57710
+ * netdev->dev_addr.
*
* @param bp driver handle
* @param set
*/
-void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set);
+void bnx2x_set_eth_mac(struct bnx2x *bp, int set);
#ifdef BCM_CNIC
/**
@@ -247,18 +268,22 @@ int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set);
* Initialize status block in FW and HW
*
* @param bp driver handle
- * @param sb host_status_block
* @param dma_addr_t mapping
* @param int sb_id
+ * @param int vfid
+ * @param u8 vf_valid
+ * @param int fw_sb_id
+ * @param int igu_sb_id
*/
-void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb,
- dma_addr_t mapping, int sb_id);
+void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
+ u8 vf_valid, int fw_sb_id, int igu_sb_id);
/**
- * Reconfigure FW/HW according to dev->flags rx mode
+ * Set MAC filtering configurations.
*
- * @param dev net_device
+ * @remarks called with netif_tx_lock from dev_mcast.c
*
+ * @param dev net_device
*/
void bnx2x_set_rx_mode(struct net_device *dev);
@@ -280,34 +305,162 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp);
* Perform statistics handling according to event
*
* @param bp driver handle
- * @param even tbnx2x_stats_event
+ * @param event bnx2x_stats_event
*/
void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event);
/**
- * Configures FW with client paramteres (like HW VLAN removal)
- * for each active client.
+ * Handle ramrods completion
+ *
+ * @param fp fastpath handle for the event
+ * @param 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.
*
* @param bp
+ *
+ * @return int
*/
-void bnx2x_set_client_config(struct bnx2x *bp);
+int bnx2x_func_start(struct bnx2x *bp);
+int bnx2x_func_stop(struct bnx2x *bp);
/**
- * Handle sp events
+ * Prepare ILT configurations according to current driver
+ * parameters.
*
- * @param fp fastpath handle for the event
- * @param rr_cqe eth_rx_cqe
+ * @param bp
+ */
+void bnx2x_ilt_set_info(struct bnx2x *bp);
+
+/**
+ * Set power state to the requested value. Currently only D0 and
+ * D3hot are supported.
+ *
+ * @param bp
+ * @param state D0 or D3hot
+ *
+ * @return int
*/
-void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe);
+int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state);
+
+/* dev_close main block */
+int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode);
+
+/* dev_open main block */
+int bnx2x_nic_load(struct bnx2x *bp, int load_mode);
+
+/* hard_xmit callback */
+netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev);
+
+int bnx2x_change_mac_addr(struct net_device *dev, void *p);
+
+/* NAPI poll Rx part */
+int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget);
+
+/* NAPI poll Tx part */
+int bnx2x_tx_int(struct bnx2x_fastpath *fp);
+
+/* suspend/resume callbacks */
+int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state);
+int bnx2x_resume(struct pci_dev *pdev);
+
+/* Release IRQ vectors */
+void bnx2x_free_irq(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
+ *
+ * @param bp
+ *
+ * @return int
+ */
+int bnx2x_enable_msix(struct bnx2x *bp);
+
+/**
+ * Request msi mode from OS, updated internals accordingly
+ *
+ * @param bp
+ *
+ * @return int
+ */
+int bnx2x_enable_msi(struct bnx2x *bp);
+
+/**
+ * Request IRQ vectors from OS.
+ *
+ * @param bp
+ *
+ * @return int
+ */
+int bnx2x_setup_irqs(struct bnx2x *bp);
+/**
+ * NAPI callback
+ *
+ * @param napi
+ * @param budget
+ *
+ * @return int
+ */
+int bnx2x_poll(struct napi_struct *napi, int budget);
+
+/**
+ * Allocate/release memories outsize main driver structure
+ *
+ * @param bp
+ *
+ * @return int
+ */
+int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp);
+void bnx2x_free_mem_bp(struct bnx2x *bp);
+
+/**
+ * Change mtu netdev callback
+ *
+ * @param dev
+ * @param new_mtu
+ *
+ * @return int
+ */
+int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
+
+/**
+ * tx timeout netdev callback
+ *
+ * @param dev
+ * @param new_mtu
+ *
+ * @return int
+ */
+void bnx2x_tx_timeout(struct net_device *dev);
+
+#ifdef BCM_VLAN
+/**
+ * vlan rx register netdev callback
+ *
+ * @param dev
+ * @param new_mtu
+ *
+ * @return int
+ */
+void bnx2x_vlan_rx_register(struct net_device *dev,
+ struct vlan_group *vlgrp);
+
+#endif
static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
{
- struct host_status_block *fpsb = fp->status_blk;
-
barrier(); /* status block is written to by the chip */
- fp->fp_c_idx = fpsb->c_status_block.status_block_index;
- fp->fp_u_idx = fpsb->u_status_block.status_block_index;
+ fp->fp_hc_idx = fp->sb_running_index[SM_RX_ID];
}
static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
@@ -334,8 +487,8 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
wmb();
for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++)
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_RX_PRODS_OFFSET(BP_PORT(bp), fp->cl_id) + i*4,
+ REG_WR(bp,
+ BAR_USTRORM_INTMEM + fp->ustorm_rx_prods_offset + i*4,
((u32 *)&rx_prods)[i]);
mmiowb(); /* keep prod updates ordered */
@@ -345,10 +498,77 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
fp->index, bd_prod, rx_comp_prod, rx_sge_prod);
}
+static inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id,
+ u8 segment, u16 index, u8 op,
+ u8 update, u32 igu_addr)
+{
+ struct igu_regular cmd_data = {0};
+
+ cmd_data.sb_id_and_flags =
+ ((index << IGU_REGULAR_SB_INDEX_SHIFT) |
+ (segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) |
+ (update << IGU_REGULAR_BUPDATE_SHIFT) |
+ (op << IGU_REGULAR_ENABLE_INT_SHIFT));
+
+ DP(NETIF_MSG_HW, "write 0x%08x to IGU addr 0x%x\n",
+ cmd_data.sb_id_and_flags, igu_addr);
+ REG_WR(bp, igu_addr, cmd_data.sb_id_and_flags);
+
+ /* Make sure that ACK is written */
+ mmiowb();
+ barrier();
+}
+
+static inline void bnx2x_igu_clear_sb_gen(struct bnx2x *bp,
+ u8 idu_sb_id, bool is_Pf)
+{
+ u32 data, ctl, cnt = 100;
+ u32 igu_addr_data = IGU_REG_COMMAND_REG_32LSB_DATA;
+ u32 igu_addr_ctl = IGU_REG_COMMAND_REG_CTRL;
+ u32 igu_addr_ack = IGU_REG_CSTORM_TYPE_0_SB_CLEANUP + (idu_sb_id/32)*4;
+ u32 sb_bit = 1 << (idu_sb_id%32);
+ u32 func_encode = BP_FUNC(bp) |
+ ((is_Pf == true ? 1 : 0) << IGU_FID_ENCODE_IS_PF_SHIFT);
+ u32 addr_encode = IGU_CMD_E2_PROD_UPD_BASE + idu_sb_id;
+
+ /* Not supported in BC mode */
+ if (CHIP_INT_MODE_IS_BC(bp))
+ return;
+
+ data = (IGU_USE_REGISTER_cstorm_type_0_sb_cleanup
+ << IGU_REGULAR_CLEANUP_TYPE_SHIFT) |
+ IGU_REGULAR_CLEANUP_SET |
+ IGU_REGULAR_BCLEANUP;
+
+ ctl = addr_encode << IGU_CTRL_REG_ADDRESS_SHIFT |
+ func_encode << IGU_CTRL_REG_FID_SHIFT |
+ IGU_CTRL_CMD_TYPE_WR << IGU_CTRL_REG_TYPE_SHIFT;
+
+ DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n",
+ data, igu_addr_data);
+ REG_WR(bp, igu_addr_data, data);
+ mmiowb();
+ barrier();
+ DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n",
+ ctl, igu_addr_ctl);
+ REG_WR(bp, igu_addr_ctl, ctl);
+ mmiowb();
+ barrier();
+
+ /* wait for clean up to finish */
+ while (!(REG_RD(bp, igu_addr_ack) & sb_bit) && --cnt)
+ msleep(20);
+
+ if (!(REG_RD(bp, igu_addr_ack) & sb_bit)) {
+ DP(NETIF_MSG_HW, "Unable to finish IGU cleanup: "
+ "idu_sb_id %d offset %d bit %d (cnt %d)\n",
+ idu_sb_id, idu_sb_id/32, idu_sb_id%32, cnt);
+ }
+}
-static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id,
- u8 storm, u16 index, u8 op, u8 update)
+static inline void bnx2x_hc_ack_sb(struct bnx2x *bp, u8 sb_id,
+ u8 storm, u16 index, u8 op, u8 update)
{
u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 +
COMMAND_REG_INT_ACK);
@@ -369,7 +589,37 @@ static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id,
mmiowb();
barrier();
}
-static inline u16 bnx2x_ack_int(struct bnx2x *bp)
+
+static inline void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment,
+ u16 index, u8 op, u8 update)
+{
+ u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id)*8;
+
+ bnx2x_igu_ack_sb_gen(bp, igu_sb_id, segment, index, op, update,
+ igu_addr);
+}
+
+static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 storm,
+ u16 index, u8 op, u8 update)
+{
+ if (bp->common.int_block == INT_BLOCK_HC)
+ bnx2x_hc_ack_sb(bp, igu_sb_id, storm, index, op, update);
+ else {
+ u8 segment;
+
+ if (CHIP_INT_MODE_IS_BC(bp))
+ segment = storm;
+ else if (igu_sb_id != bp->igu_dsb_id)
+ segment = IGU_SEG_ACCESS_DEF;
+ else if (storm == ATTENTION_ID)
+ segment = IGU_SEG_ACCESS_ATTN;
+ else
+ segment = IGU_SEG_ACCESS_DEF;
+ bnx2x_igu_ack_sb(bp, igu_sb_id, segment, index, op, update);
+ }
+}
+
+static inline u16 bnx2x_hc_ack_int(struct bnx2x *bp)
{
u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 +
COMMAND_REG_SIMD_MASK);
@@ -378,18 +628,36 @@ static inline u16 bnx2x_ack_int(struct bnx2x *bp)
DP(BNX2X_MSG_OFF, "read 0x%08x from HC addr 0x%x\n",
result, hc_addr);
+ barrier();
return result;
}
-/*
- * fast path service functions
- */
+static inline u16 bnx2x_igu_ack_int(struct bnx2x *bp)
+{
+ u32 igu_addr = (BAR_IGU_INTMEM + IGU_REG_SISR_MDPC_WMASK_LSB_UPPER*8);
+ u32 result = REG_RD(bp, igu_addr);
+
+ DP(NETIF_MSG_HW, "read 0x%08x from IGU addr 0x%x\n",
+ result, igu_addr);
+
+ barrier();
+ return result;
+}
+
+static inline u16 bnx2x_ack_int(struct bnx2x *bp)
+{
+ barrier();
+ if (bp->common.int_block == INT_BLOCK_HC)
+ return bnx2x_hc_ack_int(bp);
+ else
+ return bnx2x_igu_ack_int(bp);
+}
static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp)
{
/* Tell compiler that consumer and producer can change */
barrier();
- return (fp->tx_pkt_prod != fp->tx_pkt_cons);
+ return fp->tx_pkt_prod != fp->tx_pkt_cons;
}
static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
@@ -424,6 +692,29 @@ static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp)
return hw_cons != fp->tx_pkt_cons;
}
+static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
+{
+ u16 rx_cons_sb;
+
+ /* Tell compiler that status block fields can change */
+ barrier();
+ rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
+ if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+ rx_cons_sb++;
+ return (fp->rx_comp_cons != rx_cons_sb);
+}
+
+/**
+ * disables tx from stack point of view
+ *
+ * @param bp
+ */
+static inline void bnx2x_tx_disable(struct bnx2x *bp)
+{
+ netif_tx_disable(bp->dev);
+ netif_carrier_off(bp->dev);
+}
+
static inline void bnx2x_free_rx_sge(struct bnx2x *bp,
struct bnx2x_fastpath *fp, u16 index)
{
@@ -436,7 +727,7 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp,
return;
dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(sw_buf, mapping),
- SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE);
+ SGE_PAGE_SIZE*PAGES_PER_SGE, DMA_FROM_DEVICE);
__free_pages(page, PAGES_PER_SGE_SHIFT);
sw_buf->page = NULL;
@@ -444,13 +735,67 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp,
sge->addr_lo = 0;
}
-static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp,
- struct bnx2x_fastpath *fp, int last)
+static inline void bnx2x_add_all_napi(struct bnx2x *bp)
{
int i;
- for (i = 0; i < last; i++)
- bnx2x_free_rx_sge(bp, fp, i);
+ /* Add NAPI objects */
+ for_each_queue(bp, i)
+ netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
+ bnx2x_poll, BNX2X_NAPI_WEIGHT);
+}
+
+static inline void bnx2x_del_all_napi(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_queue(bp, i)
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
+}
+
+static inline void bnx2x_disable_msi(struct bnx2x *bp)
+{
+ if (bp->flags & USING_MSIX_FLAG) {
+ pci_disable_msix(bp->pdev);
+ bp->flags &= ~USING_MSIX_FLAG;
+ } else if (bp->flags & USING_MSI_FLAG) {
+ pci_disable_msi(bp->pdev);
+ bp->flags &= ~USING_MSI_FLAG;
+ }
+}
+
+static inline int bnx2x_calc_num_queues(struct bnx2x *bp)
+{
+ return num_queues ?
+ min_t(int, num_queues, BNX2X_MAX_QUEUES(bp)) :
+ min_t(int, num_online_cpus(), BNX2X_MAX_QUEUES(bp));
+}
+
+static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp)
+{
+ int i, j;
+
+ for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
+ int idx = RX_SGE_CNT * i - 1;
+
+ for (j = 0; j < 2; j++) {
+ SGE_MASK_CLEAR_BIT(fp, idx);
+ idx--;
+ }
+ }
+}
+
+static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp)
+{
+ /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */
+ memset(fp->sge_mask, 0xff,
+ (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64));
+
+ /* Clear the two last indices in the page to 1:
+ these are the indices that correspond to the "next" element,
+ hence will never be indicated and should be removed from
+ the calculations. */
+ bnx2x_clear_sge_mask_next_elems(fp);
}
static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp,
@@ -479,6 +824,7 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp,
return 0;
}
+
static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
struct bnx2x_fastpath *fp, u16 index)
{
@@ -513,7 +859,7 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
* so there is no need to check for dma_mapping_error().
*/
static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp,
- struct sk_buff *skb, u16 cons, u16 prod)
+ u16 cons, u16 prod)
{
struct bnx2x *bp = fp->bp;
struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons];
@@ -531,32 +877,15 @@ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp,
*prod_bd = *cons_bd;
}
-static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp)
+static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, int last)
{
- int i, j;
-
- for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
- int idx = RX_SGE_CNT * i - 1;
+ int i;
- for (j = 0; j < 2; j++) {
- SGE_MASK_CLEAR_BIT(fp, idx);
- idx--;
- }
- }
+ for (i = 0; i < last; i++)
+ bnx2x_free_rx_sge(bp, fp, i);
}
-static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp)
-{
- /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */
- memset(fp->sge_mask, 0xff,
- (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64));
-
- /* Clear the two last indices in the page to 1:
- these are the indices that correspond to the "next" element,
- hence will never be indicated and should be removed from
- the calculations. */
- bnx2x_clear_sge_mask_next_elems(fp);
-}
static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
struct bnx2x_fastpath *fp, int last)
{
@@ -582,7 +911,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
}
-static inline void bnx2x_init_tx_ring(struct bnx2x *bp)
+static inline void bnx2x_init_tx_rings(struct bnx2x *bp)
{
int i, j;
@@ -601,7 +930,7 @@ static inline void bnx2x_init_tx_ring(struct bnx2x *bp)
BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
}
- fp->tx_db.data.header.header = DOORBELL_HDR_DB_TYPE;
+ 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;
@@ -609,44 +938,98 @@ static inline void bnx2x_init_tx_ring(struct bnx2x *bp)
fp->tx_pkt_cons = 0;
fp->tx_bd_prod = 0;
fp->tx_bd_cons = 0;
- fp->tx_cons_sb = BNX2X_TX_SB_INDEX;
fp->tx_pkt = 0;
}
}
-static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
+
+static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp)
{
- u16 rx_cons_sb;
+ int i;
- /* Tell compiler that status block fields can change */
- barrier();
- rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
- if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
- rx_cons_sb++;
- return (fp->rx_comp_cons != rx_cons_sb);
+ for (i = 1; i <= NUM_RX_RINGS; i++) {
+ struct eth_rx_bd *rx_bd;
+
+ rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2];
+ rx_bd->addr_hi =
+ cpu_to_le32(U64_HI(fp->rx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
+ rx_bd->addr_lo =
+ cpu_to_le32(U64_LO(fp->rx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
+ }
+}
+
+static inline void bnx2x_set_next_page_sgl(struct bnx2x_fastpath *fp)
+{
+ int i;
+
+ for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
+ struct eth_rx_sge *sge;
+
+ sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2];
+ sge->addr_hi =
+ cpu_to_le32(U64_HI(fp->rx_sge_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES)));
+
+ sge->addr_lo =
+ cpu_to_le32(U64_LO(fp->rx_sge_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES)));
+ }
+}
+
+static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp)
+{
+ int i;
+ for (i = 1; i <= NUM_RCQ_RINGS; i++) {
+ struct eth_rx_cqe_next_page *nextpg;
+
+ nextpg = (struct eth_rx_cqe_next_page *)
+ &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1];
+ nextpg->addr_hi =
+ cpu_to_le32(U64_HI(fp->rx_comp_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
+ nextpg->addr_lo =
+ cpu_to_le32(U64_LO(fp->rx_comp_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
+ }
+}
+
+
+
+static inline void __storm_memset_struct(struct bnx2x *bp,
+ u32 addr, size_t size, u32 *data)
+{
+ int i;
+ for (i = 0; i < size/4; i++)
+ REG_WR(bp, addr + (i * 4), data[i]);
+}
+
+static inline void storm_memset_mac_filters(struct bnx2x *bp,
+ struct tstorm_eth_mac_filter_config *mac_filters,
+ u16 abs_fid)
+{
+ size_t size = sizeof(struct tstorm_eth_mac_filter_config);
+
+ u32 addr = BAR_TSTRORM_INTMEM +
+ TSTORM_MAC_FILTER_CONFIG_OFFSET(abs_fid);
+
+ __storm_memset_struct(bp, addr, size, (u32 *)mac_filters);
+}
+
+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);
+
+ u32 addr = BAR_XSTRORM_INTMEM +
+ XSTORM_CMNG_PER_PORT_VARS_OFFSET(port);
+
+ __storm_memset_struct(bp, addr, size, (u32 *)cmng);
}
/* HW Lock for shared dual port PHYs */
void bnx2x_acquire_phy_lock(struct bnx2x *bp);
void bnx2x_release_phy_lock(struct bnx2x *bp);
-void bnx2x_link_report(struct bnx2x *bp);
-int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget);
-int bnx2x_tx_int(struct bnx2x_fastpath *fp);
-void bnx2x_init_rx_rings(struct bnx2x *bp);
-netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev);
-
-int bnx2x_change_mac_addr(struct net_device *dev, void *p);
-void bnx2x_tx_timeout(struct net_device *dev);
-void bnx2x_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp);
-void bnx2x_netif_start(struct bnx2x *bp);
-void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw);
-void bnx2x_free_irq(struct bnx2x *bp, bool disable_only);
-int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state);
-int bnx2x_resume(struct pci_dev *pdev);
-void bnx2x_free_skbs(struct bnx2x *bp);
-int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
-int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode);
-int bnx2x_nic_load(struct bnx2x *bp, int load_mode);
-int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state);
-
#endif /* BNX2X_CMN_H */
diff --git a/drivers/net/bnx2x/bnx2x_dump.h b/drivers/net/bnx2x/bnx2x_dump.h
index 3bb9a91bb3f7..dc18c25ca9e5 100644
--- a/drivers/net/bnx2x/bnx2x_dump.h
+++ b/drivers/net/bnx2x/bnx2x_dump.h
@@ -31,14 +31,24 @@ struct dump_sign {
#define RI_E1 0x1
#define RI_E1H 0x2
+#define RI_E2 0x4
#define RI_ONLINE 0x100
-
+#define RI_PATH0_DUMP 0x200
+#define RI_PATH1_DUMP 0x400
#define RI_E1_OFFLINE (RI_E1)
#define RI_E1_ONLINE (RI_E1 | RI_ONLINE)
#define RI_E1H_OFFLINE (RI_E1H)
#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE)
-#define RI_ALL_OFFLINE (RI_E1 | RI_E1H)
-#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_ONLINE)
+#define RI_E2_OFFLINE (RI_E2)
+#define RI_E2_ONLINE (RI_E2 | RI_ONLINE)
+#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H)
+#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE)
+#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H)
+#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE)
+#define RI_E1E2_OFFLINE (RI_E2 | RI_E1)
+#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE)
+#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2)
+#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE)
#define MAX_TIMER_PENDING 200
#define TIMER_SCAN_DONT_CARE 0xFF
@@ -513,6 +523,12 @@ static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = {
{ 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE }
};
+#define WREGS_COUNT_E2 1
+static const u32 read_reg_e2_0[] = { 0x1b1040, 0x1b1000 };
+
+static const struct wreg_addr wreg_addrs_e2[WREGS_COUNT_E2] = {
+ { 0x1b0c00, 128, 2, read_reg_e2_0, RI_E2_OFFLINE }
+};
static const struct dump_sign dump_sign_all = { 0x49aa93ee, 0x40835, 0x22 };
@@ -531,4 +547,17 @@ static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] =
{ 0x1640d0, 0x1640d4 };
+#define PAGE_MODE_VALUES_E2 2
+
+#define PAGE_READ_REGS_E2 1
+
+#define PAGE_WRITE_REGS_E2 1
+
+static const u32 page_vals_e2[PAGE_MODE_VALUES_E2] = { 0, 128 };
+
+static const u32 page_write_regs_e2[PAGE_WRITE_REGS_E2] = { 328476 };
+
+static const struct reg_addr page_read_regs_e2[PAGE_READ_REGS_E2] = {
+ { 0x58000, 4608, RI_E2_ONLINE } };
+
#endif /* BNX2X_DUMP_H */
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 8b75b05e34c5..d02ffbdc9f0e 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -25,70 +25,46 @@
#include "bnx2x_cmn.h"
#include "bnx2x_dump.h"
-
static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
-
- cmd->supported = bp->port.supported;
- cmd->advertising = bp->port.advertising;
+ 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] &
+ (SUPPORTED_TP | SUPPORTED_FIBRE));
+ cmd->advertising = bp->port.advertising[cfg_idx];
if ((bp->state == BNX2X_STATE_OPEN) &&
!(bp->flags & MF_FUNC_DIS) &&
(bp->link_vars.link_up)) {
cmd->speed = bp->link_vars.line_speed;
cmd->duplex = bp->link_vars.duplex;
- if (IS_E1HMF(bp)) {
- u16 vn_max_rate;
-
- vn_max_rate =
- ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
- FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
- if (vn_max_rate < cmd->speed)
- cmd->speed = vn_max_rate;
- }
} else {
- cmd->speed = -1;
- cmd->duplex = -1;
- }
-
- if (bp->link_params.switch_cfg == SWITCH_CFG_10G) {
- u32 ext_phy_type =
- XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- cmd->port = PORT_FIBRE;
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- cmd->port = PORT_TP;
- break;
+ cmd->speed = bp->link_params.req_line_speed[cfg_idx];
+ cmd->duplex = bp->link_params.req_duplex[cfg_idx];
+ }
+ if (IS_MF(bp)) {
+ u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] &
+ FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) *
+ 100;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
- bp->link_params.ext_phy_config);
- break;
+ if (vn_max_rate < cmd->speed)
+ cmd->speed = vn_max_rate;
+ }
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- bp->link_params.ext_phy_config);
- break;
- }
- } else
+ if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
cmd->port = PORT_TP;
+ else if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE)
+ cmd->port = PORT_FIBRE;
+ else
+ BNX2X_ERR("XGXS PHY Failure detected\n");
cmd->phy_address = bp->mdio.prtad;
cmd->transceiver = XCVR_INTERNAL;
- if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
+ if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG)
cmd->autoneg = AUTONEG_ENABLE;
else
cmd->autoneg = AUTONEG_DISABLE;
@@ -110,9 +86,9 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
- u32 advertising;
+ u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config;
- if (IS_E1HMF(bp))
+ if (IS_MF(bp))
return 0;
DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
@@ -123,26 +99,81 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
+ cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ old_multi_phy_config = bp->link_params.multi_phy_config;
+ switch (cmd->port) {
+ case PORT_TP:
+ if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
+ break; /* no port change */
+
+ if (!(bp->port.supported[0] & SUPPORTED_TP ||
+ bp->port.supported[1] & SUPPORTED_TP)) {
+ DP(NETIF_MSG_LINK, "Unsupported port type\n");
+ return -EINVAL;
+ }
+ bp->link_params.multi_phy_config &=
+ ~PORT_HW_CFG_PHY_SELECTION_MASK;
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED)
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
+ else
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
+ break;
+ case PORT_FIBRE:
+ if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE)
+ break; /* no port change */
+
+ if (!(bp->port.supported[0] & SUPPORTED_FIBRE ||
+ bp->port.supported[1] & SUPPORTED_FIBRE)) {
+ DP(NETIF_MSG_LINK, "Unsupported port type\n");
+ return -EINVAL;
+ }
+ bp->link_params.multi_phy_config &=
+ ~PORT_HW_CFG_PHY_SELECTION_MASK;
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED)
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
+ else
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
+ break;
+ default:
+ DP(NETIF_MSG_LINK, "Unsupported port type\n");
+ return -EINVAL;
+ }
+ /* Save new config in case command complete successuly */
+ new_multi_phy_config = bp->link_params.multi_phy_config;
+ /* Get the new cfg_idx */
+ cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ /* Restore old config in case command failed */
+ bp->link_params.multi_phy_config = old_multi_phy_config;
+ DP(NETIF_MSG_LINK, "cfg_idx = %x\n", cfg_idx);
+
if (cmd->autoneg == AUTONEG_ENABLE) {
- if (!(bp->port.supported & SUPPORTED_Autoneg)) {
+ if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) {
DP(NETIF_MSG_LINK, "Autoneg not supported\n");
return -EINVAL;
}
/* advertise the requested speed and duplex if supported */
- cmd->advertising &= bp->port.supported;
+ cmd->advertising &= bp->port.supported[cfg_idx];
- bp->link_params.req_line_speed = SPEED_AUTO_NEG;
- bp->link_params.req_duplex = DUPLEX_FULL;
- bp->port.advertising |= (ADVERTISED_Autoneg |
+ bp->link_params.req_line_speed[cfg_idx] = SPEED_AUTO_NEG;
+ bp->link_params.req_duplex[cfg_idx] = DUPLEX_FULL;
+ bp->port.advertising[cfg_idx] |= (ADVERTISED_Autoneg |
cmd->advertising);
} else { /* forced speed */
/* advertise the requested speed and duplex if supported */
- switch (cmd->speed) {
+ u32 speed = cmd->speed;
+ speed |= (cmd->speed_hi << 16);
+ switch (speed) {
case SPEED_10:
if (cmd->duplex == DUPLEX_FULL) {
- if (!(bp->port.supported &
+ if (!(bp->port.supported[cfg_idx] &
SUPPORTED_10baseT_Full)) {
DP(NETIF_MSG_LINK,
"10M full not supported\n");
@@ -152,7 +183,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
advertising = (ADVERTISED_10baseT_Full |
ADVERTISED_TP);
} else {
- if (!(bp->port.supported &
+ if (!(bp->port.supported[cfg_idx] &
SUPPORTED_10baseT_Half)) {
DP(NETIF_MSG_LINK,
"10M half not supported\n");
@@ -166,7 +197,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case SPEED_100:
if (cmd->duplex == DUPLEX_FULL) {
- if (!(bp->port.supported &
+ if (!(bp->port.supported[cfg_idx] &
SUPPORTED_100baseT_Full)) {
DP(NETIF_MSG_LINK,
"100M full not supported\n");
@@ -176,7 +207,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
advertising = (ADVERTISED_100baseT_Full |
ADVERTISED_TP);
} else {
- if (!(bp->port.supported &
+ if (!(bp->port.supported[cfg_idx] &
SUPPORTED_100baseT_Half)) {
DP(NETIF_MSG_LINK,
"100M half not supported\n");
@@ -194,7 +225,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
}
- if (!(bp->port.supported & SUPPORTED_1000baseT_Full)) {
+ if (!(bp->port.supported[cfg_idx] &
+ SUPPORTED_1000baseT_Full)) {
DP(NETIF_MSG_LINK, "1G full not supported\n");
return -EINVAL;
}
@@ -210,7 +242,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
}
- if (!(bp->port.supported & SUPPORTED_2500baseX_Full)) {
+ if (!(bp->port.supported[cfg_idx]
+ & SUPPORTED_2500baseX_Full)) {
DP(NETIF_MSG_LINK,
"2.5G full not supported\n");
return -EINVAL;
@@ -226,7 +259,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
}
- if (!(bp->port.supported & SUPPORTED_10000baseT_Full)) {
+ if (!(bp->port.supported[cfg_idx]
+ & SUPPORTED_10000baseT_Full)) {
DP(NETIF_MSG_LINK, "10G full not supported\n");
return -EINVAL;
}
@@ -236,20 +270,23 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
default:
- DP(NETIF_MSG_LINK, "Unsupported speed\n");
+ DP(NETIF_MSG_LINK, "Unsupported speed %d\n", speed);
return -EINVAL;
}
- bp->link_params.req_line_speed = cmd->speed;
- bp->link_params.req_duplex = cmd->duplex;
- bp->port.advertising = advertising;
+ bp->link_params.req_line_speed[cfg_idx] = speed;
+ bp->link_params.req_duplex[cfg_idx] = cmd->duplex;
+ bp->port.advertising[cfg_idx] = advertising;
}
DP(NETIF_MSG_LINK, "req_line_speed %d\n"
DP_LEVEL " req_duplex %d advertising 0x%x\n",
- bp->link_params.req_line_speed, bp->link_params.req_duplex,
- bp->port.advertising);
+ bp->link_params.req_line_speed[cfg_idx],
+ bp->link_params.req_duplex[cfg_idx],
+ bp->port.advertising[cfg_idx]);
+ /* Set new config */
+ bp->link_params.multi_phy_config = new_multi_phy_config;
if (netif_running(dev)) {
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
bnx2x_link_set(bp);
@@ -260,6 +297,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
#define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE)
#define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE)
+#define IS_E2_ONLINE(info) (((info) & RI_E2_ONLINE) == RI_E2_ONLINE)
static int bnx2x_get_regs_len(struct net_device *dev)
{
@@ -277,7 +315,7 @@ static int bnx2x_get_regs_len(struct net_device *dev)
regdump_len += wreg_addrs_e1[i].size *
(1 + wreg_addrs_e1[i].read_regs_count);
- } else { /* E1H */
+ } else if (CHIP_IS_E1H(bp)) {
for (i = 0; i < REGS_COUNT; i++)
if (IS_E1H_ONLINE(reg_addrs[i].info))
regdump_len += reg_addrs[i].size;
@@ -286,6 +324,15 @@ static int bnx2x_get_regs_len(struct net_device *dev)
if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info))
regdump_len += wreg_addrs_e1h[i].size *
(1 + wreg_addrs_e1h[i].read_regs_count);
+ } else if (CHIP_IS_E2(bp)) {
+ for (i = 0; i < REGS_COUNT; i++)
+ if (IS_E2_ONLINE(reg_addrs[i].info))
+ regdump_len += reg_addrs[i].size;
+
+ for (i = 0; i < WREGS_COUNT_E2; i++)
+ if (IS_E2_ONLINE(wreg_addrs_e2[i].info))
+ regdump_len += wreg_addrs_e2[i].size *
+ (1 + wreg_addrs_e2[i].read_regs_count);
}
regdump_len *= 4;
regdump_len += sizeof(struct dump_hdr);
@@ -293,6 +340,23 @@ static int bnx2x_get_regs_len(struct net_device *dev)
return regdump_len;
}
+static inline void bnx2x_read_pages_regs_e2(struct bnx2x *bp, u32 *p)
+{
+ u32 i, j, k, n;
+
+ for (i = 0; i < PAGE_MODE_VALUES_E2; i++) {
+ for (j = 0; j < PAGE_WRITE_REGS_E2; j++) {
+ REG_WR(bp, page_write_regs_e2[j], page_vals_e2[i]);
+ for (k = 0; k < PAGE_READ_REGS_E2; k++)
+ if (IS_E2_ONLINE(page_read_regs_e2[k].info))
+ for (n = 0; n <
+ page_read_regs_e2[k].size; n++)
+ *p++ = REG_RD(bp,
+ page_read_regs_e2[k].addr + n*4);
+ }
+ }
+}
+
static void bnx2x_get_regs(struct net_device *dev,
struct ethtool_regs *regs, void *_p)
{
@@ -312,7 +376,14 @@ static void bnx2x_get_regs(struct net_device *dev,
dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR);
dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR);
dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR);
- dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE;
+
+ if (CHIP_IS_E1(bp))
+ dump_hdr.info = RI_E1_ONLINE;
+ else if (CHIP_IS_E1H(bp))
+ dump_hdr.info = RI_E1H_ONLINE;
+ else if (CHIP_IS_E2(bp))
+ dump_hdr.info = RI_E2_ONLINE |
+ (BP_PATH(bp) ? RI_PATH1_DUMP : RI_PATH0_DUMP);
memcpy(p, &dump_hdr, sizeof(struct dump_hdr));
p += dump_hdr.hdr_size + 1;
@@ -324,16 +395,25 @@ static void bnx2x_get_regs(struct net_device *dev,
*p++ = REG_RD(bp,
reg_addrs[i].addr + j*4);
- } else { /* E1H */
+ } else if (CHIP_IS_E1H(bp)) {
for (i = 0; i < REGS_COUNT; i++)
if (IS_E1H_ONLINE(reg_addrs[i].info))
for (j = 0; j < reg_addrs[i].size; j++)
*p++ = REG_RD(bp,
reg_addrs[i].addr + j*4);
+
+ } else if (CHIP_IS_E2(bp)) {
+ for (i = 0; i < REGS_COUNT; i++)
+ if (IS_E2_ONLINE(reg_addrs[i].info))
+ for (j = 0; j < reg_addrs[i].size; j++)
+ *p++ = REG_RD(bp,
+ reg_addrs[i].addr + j*4);
+
+ bnx2x_read_pages_regs_e2(bp, p);
}
}
-#define PHY_FW_VER_LEN 10
+#define PHY_FW_VER_LEN 20
static void bnx2x_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
@@ -436,7 +516,7 @@ static u32 bnx2x_get_link(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
- if (bp->flags & MF_FUNC_DIS)
+ if (bp->flags & MF_FUNC_DIS || (bp->state != BNX2X_STATE_OPEN))
return 0;
return bp->link_vars.link_up;
@@ -811,7 +891,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
struct bnx2x *bp = netdev_priv(dev);
int port = BP_PORT(bp);
int rc = 0;
-
+ u32 ext_phy_config;
if (!netif_running(dev))
return -EAGAIN;
@@ -827,6 +907,10 @@ static int bnx2x_set_eeprom(struct net_device *dev,
!bp->port.pmf)
return -EINVAL;
+ ext_phy_config =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config);
+
if (eeprom->magic == 0x50485950) {
/* 'PHYP' (0x50485950): prepare phy for FW upgrade */
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
@@ -834,7 +918,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
bnx2x_acquire_phy_lock(bp);
rc |= bnx2x_link_reset(&bp->link_params,
&bp->link_vars, 0);
- if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
+ if (XGXS_EXT_PHY_TYPE(ext_phy_config) ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101)
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
MISC_REGISTERS_GPIO_HIGH, port);
@@ -855,10 +939,8 @@ static int bnx2x_set_eeprom(struct net_device *dev,
}
} else if (eeprom->magic == 0x53985943) {
/* 'PHYC' (0x53985943): PHY FW upgrade completed */
- if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
+ if (XGXS_EXT_PHY_TYPE(ext_phy_config) ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) {
- u8 ext_phy_addr =
- XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config);
/* DSP Remove Download Mode */
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
@@ -866,7 +948,8 @@ static int bnx2x_set_eeprom(struct net_device *dev,
bnx2x_acquire_phy_lock(bp);
- bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
+ bnx2x_sfx7101_sp_sw_reset(bp,
+ &bp->link_params.phy[EXT_PHY1]);
/* wait 0.5 sec to allow it to run */
msleep(500);
@@ -879,6 +962,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
return rc;
}
+
static int bnx2x_get_coalesce(struct net_device *dev,
struct ethtool_coalesce *coal)
{
@@ -920,7 +1004,14 @@ static void bnx2x_get_ringparam(struct net_device *dev,
ering->rx_mini_max_pending = 0;
ering->rx_jumbo_max_pending = 0;
- ering->rx_pending = bp->rx_ring_size;
+ if (bp->rx_ring_size)
+ ering->rx_pending = bp->rx_ring_size;
+ else
+ if (bp->state == BNX2X_STATE_OPEN && bp->num_queues)
+ ering->rx_pending = MAX_RX_AVAIL/bp->num_queues;
+ else
+ ering->rx_pending = MAX_RX_AVAIL;
+
ering->rx_mini_pending = 0;
ering->rx_jumbo_pending = 0;
@@ -940,6 +1031,7 @@ static int bnx2x_set_ringparam(struct net_device *dev,
}
if ((ering->rx_pending > MAX_RX_AVAIL) ||
+ (ering->rx_pending < MIN_RX_AVAIL) ||
(ering->tx_pending > MAX_TX_AVAIL) ||
(ering->tx_pending <= MAX_SKB_FRAGS + 4))
return -EINVAL;
@@ -959,10 +1051,9 @@ static void bnx2x_get_pauseparam(struct net_device *dev,
struct ethtool_pauseparam *epause)
{
struct bnx2x *bp = netdev_priv(dev);
-
- epause->autoneg = (bp->link_params.req_flow_ctrl ==
- BNX2X_FLOW_CTRL_AUTO) &&
- (bp->link_params.req_line_speed == SPEED_AUTO_NEG);
+ int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ epause->autoneg = (bp->link_params.req_flow_ctrl[cfg_idx] ==
+ BNX2X_FLOW_CTRL_AUTO);
epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) ==
BNX2X_FLOW_CTRL_RX);
@@ -978,37 +1069,39 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
struct ethtool_pauseparam *epause)
{
struct bnx2x *bp = netdev_priv(dev);
-
- if (IS_E1HMF(bp))
+ u32 cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ if (IS_MF(bp))
return 0;
DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n",
epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
- bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
+ bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_AUTO;
if (epause->rx_pause)
- bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_RX;
+ bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_RX;
if (epause->tx_pause)
- bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_TX;
+ bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_TX;
- if (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
- bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+ if (bp->link_params.req_flow_ctrl[cfg_idx] == BNX2X_FLOW_CTRL_AUTO)
+ bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_NONE;
if (epause->autoneg) {
- if (!(bp->port.supported & SUPPORTED_Autoneg)) {
+ if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) {
DP(NETIF_MSG_LINK, "autoneg not supported\n");
return -EINVAL;
}
- if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
- bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
+ if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG) {
+ bp->link_params.req_flow_ctrl[cfg_idx] =
+ BNX2X_FLOW_CTRL_AUTO;
+ }
}
DP(NETIF_MSG_LINK,
- "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl);
+ "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl[cfg_idx]);
if (netif_running(dev)) {
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
@@ -1024,35 +1117,34 @@ static int bnx2x_set_flags(struct net_device *dev, u32 data)
int changed = 0;
int rc = 0;
- if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH))
- return -EINVAL;
-
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->disable_tpa) {
- if (!(dev->features & NETIF_F_LRO)) {
- dev->features |= NETIF_F_LRO;
- bp->flags |= TPA_ENABLE_FLAG;
- changed = 1;
- }
- } else
- rc = -EINVAL;
- } else if (dev->features & NETIF_F_LRO) {
+ 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 (data & ETH_FLAG_RXHASH)
- dev->features |= NETIF_F_RXHASH;
- else
- dev->features &= ~NETIF_F_RXHASH;
-
if (changed && netif_running(dev)) {
bnx2x_nic_unload(bp, UNLOAD_NORMAL);
rc = bnx2x_nic_load(bp, LOAD_NORMAL);
@@ -1185,6 +1277,9 @@ static int bnx2x_test_registers(struct bnx2x *bp)
for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) {
u32 offset, mask, save_val, val;
+ if (CHIP_IS_E2(bp) &&
+ reg_tbl[i].offset0 == HC_REG_AGG_INT_0)
+ continue;
offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1;
mask = reg_tbl[i].mask;
@@ -1192,6 +1287,7 @@ static int bnx2x_test_registers(struct bnx2x *bp)
save_val = REG_RD(bp, offset);
REG_WR(bp, offset, (wr_val & mask));
+
val = REG_RD(bp, offset);
/* Restore the original register's value */
@@ -1236,20 +1332,33 @@ static int bnx2x_test_memory(struct bnx2x *bp)
u32 offset;
u32 e1_mask;
u32 e1h_mask;
+ u32 e2_mask;
} prty_tbl[] = {
- { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0 },
- { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2 },
- { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0 },
- { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0 },
- { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0 },
- { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0 },
-
- { NULL, 0xffffffff, 0, 0 }
+ { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0, 0 },
+ { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2, 0 },
+ { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0, 0 },
+ { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0, 0 },
+ { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0, 0 },
+ { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0, 0 },
+
+ { NULL, 0xffffffff, 0, 0, 0 }
};
if (!netif_running(bp->dev))
return rc;
+ /* pre-Check the parity status */
+ for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
+ val = REG_RD(bp, prty_tbl[i].offset);
+ if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) ||
+ (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) ||
+ (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) {
+ DP(NETIF_MSG_HW,
+ "%s is 0x%x\n", prty_tbl[i].name, val);
+ goto test_mem_exit;
+ }
+ }
+
/* Go through all the memories */
for (i = 0; mem_tbl[i].offset != 0xffffffff; i++)
for (j = 0; j < mem_tbl[i].size; j++)
@@ -1259,7 +1368,8 @@ static int bnx2x_test_memory(struct bnx2x *bp)
for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
val = REG_RD(bp, prty_tbl[i].offset);
if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) ||
- (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) {
+ (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) ||
+ (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) {
DP(NETIF_MSG_HW,
"%s is 0x%x\n", prty_tbl[i].name, val);
goto test_mem_exit;
@@ -1272,12 +1382,12 @@ test_mem_exit:
return rc;
}
-static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up)
+static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes)
{
- int cnt = 1000;
+ int cnt = 1400;
if (link_up)
- while (bnx2x_link_test(bp) && cnt--)
+ while (bnx2x_link_test(bp, is_serdes) && cnt--)
msleep(10);
}
@@ -1293,7 +1403,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
u16 pkt_prod, bd_prod;
struct sw_tx_bd *tx_buf;
struct eth_tx_start_bd *tx_start_bd;
- struct eth_tx_parse_bd *pbd = NULL;
+ struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
+ struct eth_tx_parse_bd_e2 *pbd_e2 = NULL;
dma_addr_t mapping;
union eth_rx_cqe *cqe;
u8 cqe_fp_flags;
@@ -1304,7 +1415,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
/* check the loopback mode */
switch (loopback_mode) {
case BNX2X_PHY_LOOPBACK:
- if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10)
+ if (bp->link_params.loopback_mode != LOOPBACK_XGXS)
return -EINVAL;
break;
case BNX2X_MAC_LOOPBACK:
@@ -1349,16 +1460,23 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */
tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb));
- tx_start_bd->vlan = cpu_to_le16(pkt_prod);
+ tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
- tx_start_bd->general_data = ((UNICAST_ADDRESS <<
- ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT) | 1);
+ SET_FLAG(tx_start_bd->general_data,
+ ETH_TX_START_BD_ETH_ADDR_TYPE,
+ UNICAST_ADDRESS);
+ SET_FLAG(tx_start_bd->general_data,
+ ETH_TX_START_BD_HDR_NBDS,
+ 1);
/* turn on parsing and get a BD */
bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
- pbd = &fp_tx->tx_desc_ring[bd_prod].parse_bd;
- memset(pbd, 0, sizeof(struct eth_tx_parse_bd));
+ pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x;
+ pbd_e2 = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e2;
+
+ memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
+ memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
wmb();
@@ -1377,6 +1495,13 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
if (tx_idx != tx_start_idx + num_pkts)
goto test_loopback_exit;
+ /* Unlike HC IGU won't generate an interrupt for status block
+ * updates that have been performed while interrupts were
+ * disabled.
+ */
+ if (bp->common.int_block == INT_BLOCK_IGU)
+ bnx2x_tx_int(fp_tx);
+
rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
if (rx_idx != rx_start_idx + num_pkts)
goto test_loopback_exit;
@@ -1519,8 +1644,7 @@ static int bnx2x_test_intr(struct bnx2x *bp)
config->hdr.length = 0;
if (CHIP_IS_E1(bp))
- /* use last unicast entries */
- config->hdr.offset = (BP_PORT(bp) ? 63 : 31);
+ config->hdr.offset = (BP_PORT(bp) ? 32 : 0);
else
config->hdr.offset = BP_FUNC(bp);
config->hdr.client_id = bp->fp->cl_id;
@@ -1528,9 +1652,9 @@ static int bnx2x_test_intr(struct bnx2x *bp)
bp->set_mac_pending++;
smp_wmb();
- rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
+ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
U64_HI(bnx2x_sp_mapping(bp, mac_config)),
- U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
+ U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1);
if (rc == 0) {
for (i = 0; i < 10; i++) {
if (!bp->set_mac_pending)
@@ -1549,7 +1673,7 @@ static void bnx2x_self_test(struct net_device *dev,
struct ethtool_test *etest, u64 *buf)
{
struct bnx2x *bp = netdev_priv(dev);
-
+ u8 is_serdes;
if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
printk(KERN_ERR "Handling parity error recovery. Try again later\n");
etest->flags |= ETH_TEST_FL_FAILED;
@@ -1562,8 +1686,9 @@ static void bnx2x_self_test(struct net_device *dev,
return;
/* offline tests are not supported in MF mode */
- if (IS_E1HMF(bp))
+ if (IS_MF(bp))
etest->flags &= ~ETH_TEST_FL_OFFLINE;
+ is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0;
if (etest->flags & ETH_TEST_FL_OFFLINE) {
int port = BP_PORT(bp);
@@ -1575,11 +1700,12 @@ static void bnx2x_self_test(struct net_device *dev,
/* disable input for TX port IF */
REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0);
- link_up = (bnx2x_link_test(bp) == 0);
+ link_up = bp->link_vars.link_up;
+
bnx2x_nic_unload(bp, UNLOAD_NORMAL);
bnx2x_nic_load(bp, LOAD_DIAG);
/* wait until link state is restored */
- bnx2x_wait_for_link(bp, link_up);
+ bnx2x_wait_for_link(bp, link_up, is_serdes);
if (bnx2x_test_registers(bp) != 0) {
buf[0] = 1;
@@ -1589,6 +1715,7 @@ static void bnx2x_self_test(struct net_device *dev,
buf[1] = 1;
etest->flags |= ETH_TEST_FL_FAILED;
}
+
buf[2] = bnx2x_test_loopback(bp, link_up);
if (buf[2] != 0)
etest->flags |= ETH_TEST_FL_FAILED;
@@ -1600,7 +1727,7 @@ static void bnx2x_self_test(struct net_device *dev,
bnx2x_nic_load(bp, LOAD_NORMAL);
/* wait until link state is restored */
- bnx2x_wait_for_link(bp, link_up);
+ bnx2x_wait_for_link(bp, link_up, is_serdes);
}
if (bnx2x_test_nvram(bp) != 0) {
buf[3] = 1;
@@ -1611,7 +1738,7 @@ static void bnx2x_self_test(struct net_device *dev,
etest->flags |= ETH_TEST_FL_FAILED;
}
if (bp->port.pmf)
- if (bnx2x_link_test(bp) != 0) {
+ if (bnx2x_link_test(bp, is_serdes) != 0) {
buf[5] = 1;
etest->flags |= ETH_TEST_FL_FAILED;
}
@@ -1752,8 +1879,8 @@ static const struct {
#define IS_PORT_STAT(i) \
((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT)
#define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC)
-#define IS_E1HMF_MODE_STAT(bp) \
- (IS_E1HMF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS))
+#define IS_MF_MODE_STAT(bp) \
+ (IS_MF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS))
static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
{
@@ -1764,10 +1891,10 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
case ETH_SS_STATS:
if (is_multi(bp)) {
num_stats = BNX2X_NUM_Q_STATS * bp->num_queues;
- if (!IS_E1HMF_MODE_STAT(bp))
+ if (!IS_MF_MODE_STAT(bp))
num_stats += BNX2X_NUM_STATS;
} else {
- if (IS_E1HMF_MODE_STAT(bp)) {
+ if (IS_MF_MODE_STAT(bp)) {
num_stats = 0;
for (i = 0; i < BNX2X_NUM_STATS; i++)
if (IS_FUNC_STAT(i))
@@ -1800,14 +1927,14 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
bnx2x_q_stats_arr[j].string, i);
k += BNX2X_NUM_Q_STATS;
}
- if (IS_E1HMF_MODE_STAT(bp))
+ if (IS_MF_MODE_STAT(bp))
break;
for (j = 0; j < BNX2X_NUM_STATS; j++)
strcpy(buf + (k + j)*ETH_GSTRING_LEN,
bnx2x_stats_arr[j].string);
} else {
for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
+ if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
continue;
strcpy(buf + j*ETH_GSTRING_LEN,
bnx2x_stats_arr[i].string);
@@ -1851,7 +1978,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
}
k += BNX2X_NUM_Q_STATS;
}
- if (IS_E1HMF_MODE_STAT(bp))
+ if (IS_MF_MODE_STAT(bp))
return;
hw_stats = (u32 *)&bp->eth_stats;
for (j = 0; j < BNX2X_NUM_STATS; j++) {
@@ -1872,7 +1999,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
} else {
hw_stats = (u32 *)&bp->eth_stats;
for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
+ if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
continue;
if (bnx2x_stats_arr[i].size == 0) {
/* skip this counter */
@@ -1910,10 +2037,11 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data)
for (i = 0; i < (data * 2); i++) {
if ((i % 2) == 0)
- bnx2x_set_led(&bp->link_params, LED_MODE_OPER,
- SPEED_1000);
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_OPER, SPEED_1000);
else
- bnx2x_set_led(&bp->link_params, LED_MODE_OFF, 0);
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_OFF, 0);
msleep_interruptible(500);
if (signal_pending(current))
@@ -1921,7 +2049,7 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data)
}
if (bp->link_vars.link_up)
- bnx2x_set_led(&bp->link_params, LED_MODE_OPER,
+ bnx2x_set_led(&bp->link_params, &bp->link_vars, LED_MODE_OPER,
bp->link_vars.line_speed);
return 0;
diff --git a/drivers/net/bnx2x/bnx2x_fw_defs.h b/drivers/net/bnx2x/bnx2x_fw_defs.h
index 08d71bf438d6..f4e5b1ce8149 100644
--- a/drivers/net/bnx2x/bnx2x_fw_defs.h
+++ b/drivers/net/bnx2x/bnx2x_fw_defs.h
@@ -7,369 +7,272 @@
* the Free Software Foundation.
*/
-
-#define CSTORM_ASSERT_LIST_INDEX_OFFSET \
- (IS_E1H_OFFSET ? 0x7000 : 0x1000)
-#define CSTORM_ASSERT_LIST_OFFSET(idx) \
- (IS_E1H_OFFSET ? (0x7020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
-#define CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(function, index) \
- (IS_E1H_OFFSET ? (0x8622 + ((function>>1) * 0x40) + \
- ((function&1) * 0x100) + (index * 0x4)) : (0x3562 + (function * \
- 0x40) + (index * 0x4)))
-#define CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(function, index) \
- (IS_E1H_OFFSET ? (0x8822 + ((function>>1) * 0x80) + \
- ((function&1) * 0x200) + (index * 0x4)) : (0x35e2 + (function * \
- 0x80) + (index * 0x4)))
-#define CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8600 + ((function>>1) * 0x40) + \
- ((function&1) * 0x100)) : (0x3540 + (function * 0x40)))
-#define CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8800 + ((function>>1) * 0x80) + \
- ((function&1) * 0x200)) : (0x35c0 + (function * 0x80)))
-#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8608 + ((function>>1) * 0x40) + \
- ((function&1) * 0x100)) : (0x3548 + (function * 0x40)))
-#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8808 + ((function>>1) * 0x80) + \
- ((function&1) * 0x200)) : (0x35c8 + (function * 0x80)))
-#define CSTORM_FUNCTION_MODE_OFFSET \
- (IS_E1H_OFFSET ? 0x11e8 : 0xffffffff)
-#define CSTORM_HC_BTR_C_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x8c04 + (port * 0xf0)) : (0x36c4 + (port * 0xc0)))
-#define CSTORM_HC_BTR_U_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x8de4 + (port * 0xf0)) : (0x3844 + (port * 0xc0)))
-#define CSTORM_ISCSI_CQ_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6680 + (function * 0x8)) : (0x25a0 + \
- (function * 0x8)))
-#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x66c0 + (function * 0x8)) : (0x25b0 + \
- (function * 0x8)))
-#define CSTORM_ISCSI_EQ_CONS_OFFSET(function, eqIdx) \
- (IS_E1H_OFFSET ? (0x6040 + (function * 0xc0) + (eqIdx * 0x18)) : \
- (0x2410 + (function * 0xc0) + (eqIdx * 0x18)))
-#define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(function, eqIdx) \
- (IS_E1H_OFFSET ? (0x6044 + (function * 0xc0) + (eqIdx * 0x18)) : \
- (0x2414 + (function * 0xc0) + (eqIdx * 0x18)))
-#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(function, eqIdx) \
- (IS_E1H_OFFSET ? (0x604c + (function * 0xc0) + (eqIdx * 0x18)) : \
- (0x241c + (function * 0xc0) + (eqIdx * 0x18)))
-#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(function, eqIdx) \
- (IS_E1H_OFFSET ? (0x6057 + (function * 0xc0) + (eqIdx * 0x18)) : \
- (0x2427 + (function * 0xc0) + (eqIdx * 0x18)))
-#define CSTORM_ISCSI_EQ_PROD_OFFSET(function, eqIdx) \
- (IS_E1H_OFFSET ? (0x6042 + (function * 0xc0) + (eqIdx * 0x18)) : \
- (0x2412 + (function * 0xc0) + (eqIdx * 0x18)))
-#define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(function, eqIdx) \
- (IS_E1H_OFFSET ? (0x6056 + (function * 0xc0) + (eqIdx * 0x18)) : \
- (0x2426 + (function * 0xc0) + (eqIdx * 0x18)))
-#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(function, eqIdx) \
- (IS_E1H_OFFSET ? (0x6054 + (function * 0xc0) + (eqIdx * 0x18)) : \
- (0x2424 + (function * 0xc0) + (eqIdx * 0x18)))
-#define CSTORM_ISCSI_HQ_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6640 + (function * 0x8)) : (0x2590 + \
- (function * 0x8)))
-#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6004 + (function * 0x8)) : (0x2404 + \
- (function * 0x8)))
-#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6002 + (function * 0x8)) : (0x2402 + \
- (function * 0x8)))
-#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6000 + (function * 0x8)) : (0x2400 + \
- (function * 0x8)))
-#define CSTORM_SB_HC_DISABLE_C_OFFSET(port, cpu_id, index) \
- (IS_E1H_OFFSET ? (0x811a + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)) : (0x305a + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)))
-#define CSTORM_SB_HC_DISABLE_U_OFFSET(port, cpu_id, index) \
- (IS_E1H_OFFSET ? (0xb01a + (port * 0x800) + (cpu_id * 0x80) + \
- (index * 0x4)) : (0x401a + (port * 0x800) + (cpu_id * 0x80) + \
- (index * 0x4)))
-#define CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, cpu_id, index) \
- (IS_E1H_OFFSET ? (0x8118 + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)) : (0x3058 + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)))
-#define CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, cpu_id, index) \
- (IS_E1H_OFFSET ? (0xb018 + (port * 0x800) + (cpu_id * 0x80) + \
- (index * 0x4)) : (0x4018 + (port * 0x800) + (cpu_id * 0x80) + \
- (index * 0x4)))
-#define CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, cpu_id) \
- (IS_E1H_OFFSET ? (0x8100 + (port * 0x280) + (cpu_id * 0x28)) : \
- (0x3040 + (port * 0x280) + (cpu_id * 0x28)))
-#define CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, cpu_id) \
- (IS_E1H_OFFSET ? (0xb000 + (port * 0x800) + (cpu_id * 0x80)) : \
- (0x4000 + (port * 0x800) + (cpu_id * 0x80)))
-#define CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, cpu_id) \
- (IS_E1H_OFFSET ? (0x8108 + (port * 0x280) + (cpu_id * 0x28)) : \
- (0x3048 + (port * 0x280) + (cpu_id * 0x28)))
-#define CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, cpu_id) \
- (IS_E1H_OFFSET ? (0xb008 + (port * 0x800) + (cpu_id * 0x80)) : \
- (0x4008 + (port * 0x800) + (cpu_id * 0x80)))
-#define CSTORM_SB_STATUS_BLOCK_C_SIZE 0x10
-#define CSTORM_SB_STATUS_BLOCK_U_SIZE 0x60
-#define CSTORM_STATS_FLAGS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x1108 + (function * 0x8)) : (0x5108 + \
- (function * 0x8)))
-#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x3200 + (function * 0x20)) : 0xffffffff)
-#define TSTORM_ASSERT_LIST_INDEX_OFFSET \
- (IS_E1H_OFFSET ? 0xa000 : 0x1000)
-#define TSTORM_ASSERT_LIST_OFFSET(idx) \
- (IS_E1H_OFFSET ? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
-#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \
- (IS_E1H_OFFSET ? (0x33a0 + (port * 0x1a0) + (client_id * 0x10)) \
- : (0x9c0 + (port * 0x120) + (client_id * 0x10)))
-#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET \
- (IS_E1H_OFFSET ? 0x1ed8 : 0xffffffff)
+#ifndef BNX2X_FW_DEFS_H
+#define BNX2X_FW_DEFS_H
+
+#define CSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[142].base)
+#define CSTORM_ASSERT_LIST_OFFSET(assertListEntry) \
+ (IRO[141].base + ((assertListEntry) * IRO[141].m1))
+#define CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \
+ (IRO[144].base + ((pfId) * IRO[144].m1))
+#define CSTORM_EVENT_RING_DATA_OFFSET(pfId) \
+ (IRO[149].base + (((pfId)>>1) * IRO[149].m1) + (((pfId)&1) * \
+ IRO[149].m2))
+#define CSTORM_EVENT_RING_PROD_OFFSET(pfId) \
+ (IRO[150].base + (((pfId)>>1) * IRO[150].m1) + (((pfId)&1) * \
+ IRO[150].m2))
+#define CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(funcId) \
+ (IRO[156].base + ((funcId) * IRO[156].m1))
+#define CSTORM_FUNC_EN_OFFSET(funcId) \
+ (IRO[146].base + ((funcId) * IRO[146].m1))
+#define CSTORM_FUNCTION_MODE_OFFSET (IRO[153].base)
+#define CSTORM_IGU_MODE_OFFSET (IRO[154].base)
+#define CSTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \
+ (IRO[311].base + ((pfId) * IRO[311].m1))
+#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \
+ (IRO[312].base + ((pfId) * IRO[312].m1))
+ #define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \
+ (IRO[304].base + ((pfId) * IRO[304].m1) + ((iscsiEqId) * \
+ IRO[304].m2))
+ #define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \
+ (IRO[306].base + ((pfId) * IRO[306].m1) + ((iscsiEqId) * \
+ IRO[306].m2))
+ #define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \
+ (IRO[305].base + ((pfId) * IRO[305].m1) + ((iscsiEqId) * \
+ IRO[305].m2))
+ #define \
+ CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \
+ (IRO[307].base + ((pfId) * IRO[307].m1) + ((iscsiEqId) * \
+ IRO[307].m2))
+ #define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \
+ (IRO[303].base + ((pfId) * IRO[303].m1) + ((iscsiEqId) * \
+ IRO[303].m2))
+ #define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \
+ (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * \
+ IRO[309].m2))
+ #define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \
+ (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * \
+ IRO[308].m2))
+#define CSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \
+ (IRO[310].base + ((pfId) * IRO[310].m1))
+#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
+ (IRO[302].base + ((pfId) * IRO[302].m1))
+#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
+ (IRO[301].base + ((pfId) * IRO[301].m1))
+#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
+ (IRO[300].base + ((pfId) * IRO[300].m1))
+#define CSTORM_PATH_ID_OFFSET (IRO[159].base)
+#define CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(pfId) \
+ (IRO[137].base + ((pfId) * IRO[137].m1))
+#define CSTORM_SP_STATUS_BLOCK_OFFSET(pfId) \
+ (IRO[136].base + ((pfId) * IRO[136].m1))
+#define CSTORM_SP_STATUS_BLOCK_SIZE (IRO[136].size)
+#define CSTORM_SP_SYNC_BLOCK_OFFSET(pfId) \
+ (IRO[138].base + ((pfId) * IRO[138].m1))
+#define CSTORM_SP_SYNC_BLOCK_SIZE (IRO[138].size)
+#define CSTORM_STATS_FLAGS_OFFSET(pfId) \
+ (IRO[143].base + ((pfId) * IRO[143].m1))
+#define CSTORM_STATUS_BLOCK_DATA_OFFSET(sbId) \
+ (IRO[129].base + ((sbId) * IRO[129].m1))
+#define CSTORM_STATUS_BLOCK_OFFSET(sbId) \
+ (IRO[128].base + ((sbId) * IRO[128].m1))
+#define CSTORM_STATUS_BLOCK_SIZE (IRO[128].size)
+#define CSTORM_SYNC_BLOCK_OFFSET(sbId) \
+ (IRO[132].base + ((sbId) * IRO[132].m1))
+#define CSTORM_SYNC_BLOCK_SIZE (IRO[132].size)
+#define CSTORM_VF_PF_CHANNEL_STATE_OFFSET(vfId) \
+ (IRO[151].base + ((vfId) * IRO[151].m1))
+#define CSTORM_VF_PF_CHANNEL_VALID_OFFSET(vfId) \
+ (IRO[152].base + ((vfId) * IRO[152].m1))
+#define CSTORM_VF_TO_PF_OFFSET(funcId) \
+ (IRO[147].base + ((funcId) * IRO[147].m1))
+#define TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET (IRO[199].base)
+#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(pfId) \
+ (IRO[198].base + ((pfId) * IRO[198].m1))
+#define TSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[99].base)
+#define TSTORM_ASSERT_LIST_OFFSET(assertListEntry) \
+ (IRO[98].base + ((assertListEntry) * IRO[98].m1))
+ #define TSTORM_CLIENT_CONFIG_OFFSET(portId, clientId) \
+ (IRO[197].base + ((portId) * IRO[197].m1) + ((clientId) * \
+ IRO[197].m2))
+#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET (IRO[104].base)
#define TSTORM_COMMON_SAFC_WORKAROUND_TIMEOUT_10USEC_OFFSET \
- (IS_E1H_OFFSET ? 0x1eda : 0xffffffff)
-#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
- (IS_E1H_OFFSET ? (0xb01a + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
- 0x28) + (index * 0x4)))
-#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0xb000 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1400 + (function * 0x28)))
-#define TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
- (IS_E1H_OFFSET ? (0xb008 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
-#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2940 + (function * 0x8)) : (0x4928 + \
- (function * 0x8)))
-#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x3000 + (function * 0x40)) : (0x1500 + \
- (function * 0x40)))
-#define TSTORM_FUNCTION_MODE_OFFSET \
- (IS_E1H_OFFSET ? 0x1ed0 : 0xffffffff)
-#define TSTORM_HC_BTR_OFFSET(port) \
- (IS_E1H_OFFSET ? (0xb144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
-#define TSTORM_INDIRECTION_TABLE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x12c8 + (function * 0x80)) : (0x22c8 + \
- (function * 0x80)))
-#define TSTORM_INDIRECTION_TABLE_SIZE 0x80
-#define TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(function, pblEntry) \
- (IS_E1H_OFFSET ? (0x60c0 + (function * 0x40) + (pblEntry * 0x8)) \
- : (0x4c30 + (function * 0x40) + (pblEntry * 0x8)))
-#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6340 + (function * 0x8)) : (0x4cd0 + \
- (function * 0x8)))
-#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6004 + (function * 0x8)) : (0x4c04 + \
- (function * 0x8)))
-#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6002 + (function * 0x8)) : (0x4c02 + \
- (function * 0x8)))
-#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6000 + (function * 0x8)) : (0x4c00 + \
- (function * 0x8)))
-#define TSTORM_ISCSI_RQ_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6080 + (function * 0x8)) : (0x4c20 + \
- (function * 0x8)))
-#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6040 + (function * 0x8)) : (0x4c10 + \
- (function * 0x8)))
-#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6042 + (function * 0x8)) : (0x4c12 + \
- (function * 0x8)))
-#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x6044 + (function * 0x8)) : (0x4c14 + \
- (function * 0x8)))
-#define TSTORM_MAC_FILTER_CONFIG_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x3008 + (function * 0x40)) : (0x1508 + \
- (function * 0x40)))
-#define TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
- (IS_E1H_OFFSET ? (0x2010 + (port * 0x490) + (stats_counter_id * \
- 0x40)) : (0x4010 + (port * 0x490) + (stats_counter_id * 0x40)))
-#define TSTORM_STATS_FLAGS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x29c0 + (function * 0x8)) : (0x4948 + \
- (function * 0x8)))
-#define TSTORM_TCP_MAX_CWND_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x4004 + (function * 0x8)) : (0x1fb4 + \
- (function * 0x8)))
-#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa000 : 0x3000)
-#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2000 : 0x1000)
-#define USTORM_ASSERT_LIST_INDEX_OFFSET \
- (IS_E1H_OFFSET ? 0x8000 : 0x1000)
-#define USTORM_ASSERT_LIST_OFFSET(idx) \
- (IS_E1H_OFFSET ? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
-#define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \
- (IS_E1H_OFFSET ? (0x1010 + (port * 0x680) + (clientId * 0x40)) : \
- (0x4010 + (port * 0x360) + (clientId * 0x30)))
-#define USTORM_CQE_PAGE_NEXT_OFFSET(port, clientId) \
- (IS_E1H_OFFSET ? (0x1028 + (port * 0x680) + (clientId * 0x40)) : \
- (0x4028 + (port * 0x360) + (clientId * 0x30)))
-#define USTORM_ETH_PAUSE_ENABLED_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x2ad4 + (port * 0x8)) : 0xffffffff)
-#define USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, clientId) \
- (IS_E1H_OFFSET ? (0x1030 + (port * 0x680) + (clientId * 0x40)) : \
- 0xffffffff)
-#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2a50 + (function * 0x8)) : (0x1dd0 + \
- (function * 0x8)))
-#define USTORM_FUNCTION_MODE_OFFSET \
- (IS_E1H_OFFSET ? 0x2448 : 0xffffffff)
-#define USTORM_ISCSI_CQ_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x7044 + (function * 0x8)) : (0x2414 + \
- (function * 0x8)))
-#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x7046 + (function * 0x8)) : (0x2416 + \
- (function * 0x8)))
-#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x7688 + (function * 0x8)) : (0x29c8 + \
- (function * 0x8)))
-#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x7648 + (function * 0x8)) : (0x29b8 + \
- (function * 0x8)))
-#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x7004 + (function * 0x8)) : (0x2404 + \
- (function * 0x8)))
-#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x7002 + (function * 0x8)) : (0x2402 + \
- (function * 0x8)))
-#define USTORM_ISCSI_PAGE_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x7000 + (function * 0x8)) : (0x2400 + \
- (function * 0x8)))
-#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x7040 + (function * 0x8)) : (0x2410 + \
- (function * 0x8)))
-#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x7080 + (function * 0x8)) : (0x2420 + \
- (function * 0x8)))
-#define USTORM_ISCSI_RQ_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x7084 + (function * 0x8)) : (0x2424 + \
- (function * 0x8)))
-#define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \
- (IS_E1H_OFFSET ? (0x1018 + (port * 0x680) + (clientId * 0x40)) : \
- (0x4018 + (port * 0x360) + (clientId * 0x30)))
-#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x1da8 + \
- (function * 0x8)))
-#define USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
- (IS_E1H_OFFSET ? (0x2450 + (port * 0x2d0) + (stats_counter_id * \
- 0x28)) : (0x1500 + (port * 0x2d0) + (stats_counter_id * 0x28)))
-#define USTORM_RX_PRODS_OFFSET(port, client_id) \
- (IS_E1H_OFFSET ? (0x1000 + (port * 0x680) + (client_id * 0x40)) \
- : (0x4000 + (port * 0x360) + (client_id * 0x30)))
-#define USTORM_STATS_FLAGS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x29f0 + (function * 0x8)) : (0x1db8 + \
- (function * 0x8)))
-#define USTORM_TPA_BTR_OFFSET (IS_E1H_OFFSET ? 0x3da5 : 0x5095)
-#define USTORM_TPA_BTR_SIZE 0x1
-#define XSTORM_ASSERT_LIST_INDEX_OFFSET \
- (IS_E1H_OFFSET ? 0x9000 : 0x1000)
-#define XSTORM_ASSERT_LIST_OFFSET(idx) \
- (IS_E1H_OFFSET ? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
-#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x24a8 + (port * 0x50)) : (0x3a80 + (port * 0x50)))
-#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
- (IS_E1H_OFFSET ? (0xa01a + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
- 0x28) + (index * 0x4)))
-#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0xa000 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1400 + (function * 0x28)))
-#define XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
- (IS_E1H_OFFSET ? (0xa008 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
-#define XSTORM_E1HOV_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2c10 + (function * 0x8)) : 0xffffffff)
-#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3a50 + \
- (function * 0x8)))
-#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2588 + (function * 0x90)) : (0x3b60 + \
- (function * 0x90)))
-#define XSTORM_FUNCTION_MODE_OFFSET \
- (IS_E1H_OFFSET ? 0x2c50 : 0xffffffff)
-#define XSTORM_HC_BTR_OFFSET(port) \
- (IS_E1H_OFFSET ? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
-#define XSTORM_ISCSI_HQ_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x80c0 + (function * 0x8)) : (0x1c30 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8080 + (function * 0x8)) : (0x1c20 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8081 + (function * 0x8)) : (0x1c21 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8082 + (function * 0x8)) : (0x1c22 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8083 + (function * 0x8)) : (0x1c23 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8084 + (function * 0x8)) : (0x1c24 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8085 + (function * 0x8)) : (0x1c25 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8086 + (function * 0x8)) : (0x1c26 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8004 + (function * 0x8)) : (0x1c04 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8002 + (function * 0x8)) : (0x1c02 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8000 + (function * 0x8)) : (0x1c00 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x80c4 + (function * 0x8)) : (0x1c34 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_SQ_SIZE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x80c2 + (function * 0x8)) : (0x1c32 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8043 + (function * 0x8)) : (0x1c13 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8042 + (function * 0x8)) : (0x1c12 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8041 + (function * 0x8)) : (0x1c11 + \
- (function * 0x8)))
-#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8040 + (function * 0x8)) : (0x1c10 + \
- (function * 0x8)))
-#define XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
- (IS_E1H_OFFSET ? (0xc000 + (port * 0x360) + (stats_counter_id * \
- 0x30)) : (0x3378 + (port * 0x360) + (stats_counter_id * 0x30)))
-#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2548 + (function * 0x90)) : (0x3b20 + \
- (function * 0x90)))
-#define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2000 + (function * 0x10)) : (0x3328 + \
- (function * 0x10)))
-#define XSTORM_SPQ_PROD_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2008 + (function * 0x10)) : (0x3330 + \
- (function * 0x10)))
-#define XSTORM_STATS_FLAGS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x23d8 + (function * 0x8)) : (0x3a40 + \
- (function * 0x8)))
-#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x4000 + (port * 0x8)) : (0x1960 + (port * 0x8)))
-#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x4001 + (port * 0x8)) : (0x1961 + (port * 0x8)))
-#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x4060 + ((function>>1) * 0x8) + ((function&1) \
- * 0x4)) : (0x1978 + (function * 0x4)))
+ (IRO[105].base)
+#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \
+ (IRO[96].base + ((pfId) * IRO[96].m1))
+#define TSTORM_FUNC_EN_OFFSET(funcId) \
+ (IRO[101].base + ((funcId) * IRO[101].m1))
+#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(pfId) \
+ (IRO[195].base + ((pfId) * IRO[195].m1))
+#define TSTORM_FUNCTION_MODE_OFFSET (IRO[103].base)
+#define TSTORM_INDIRECTION_TABLE_OFFSET(pfId) \
+ (IRO[91].base + ((pfId) * IRO[91].m1))
+#define TSTORM_INDIRECTION_TABLE_SIZE (IRO[91].size)
+ #define \
+ TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfId, iscsiConBufPblEntry) \
+ (IRO[260].base + ((pfId) * IRO[260].m1) + ((iscsiConBufPblEntry) \
+ * IRO[260].m2))
+#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \
+ (IRO[264].base + ((pfId) * IRO[264].m1))
+#define TSTORM_ISCSI_L2_ISCSI_OOO_CID_TABLE_OFFSET(pfId) \
+ (IRO[265].base + ((pfId) * IRO[265].m1))
+#define TSTORM_ISCSI_L2_ISCSI_OOO_CLIENT_ID_TABLE_OFFSET(pfId) \
+ (IRO[266].base + ((pfId) * IRO[266].m1))
+#define TSTORM_ISCSI_L2_ISCSI_OOO_PROD_OFFSET(pfId) \
+ (IRO[267].base + ((pfId) * IRO[267].m1))
+#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
+ (IRO[263].base + ((pfId) * IRO[263].m1))
+#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
+ (IRO[262].base + ((pfId) * IRO[262].m1))
+#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
+ (IRO[261].base + ((pfId) * IRO[261].m1))
+#define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \
+ (IRO[259].base + ((pfId) * IRO[259].m1))
+#define TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfId) \
+ (IRO[269].base + ((pfId) * IRO[269].m1))
+#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \
+ (IRO[256].base + ((pfId) * IRO[256].m1))
+#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \
+ (IRO[257].base + ((pfId) * IRO[257].m1))
+#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfId) \
+ (IRO[258].base + ((pfId) * IRO[258].m1))
+#define TSTORM_MAC_FILTER_CONFIG_OFFSET(pfId) \
+ (IRO[196].base + ((pfId) * IRO[196].m1))
+ #define TSTORM_PER_COUNTER_ID_STATS_OFFSET(portId, tStatCntId) \
+ (IRO[100].base + ((portId) * IRO[100].m1) + ((tStatCntId) * \
+ IRO[100].m2))
+#define TSTORM_STATS_FLAGS_OFFSET(pfId) \
+ (IRO[95].base + ((pfId) * IRO[95].m1))
+#define TSTORM_TCP_MAX_CWND_OFFSET(pfId) \
+ (IRO[211].base + ((pfId) * IRO[211].m1))
+#define TSTORM_VF_TO_PF_OFFSET(funcId) \
+ (IRO[102].base + ((funcId) * IRO[102].m1))
+#define USTORM_AGG_DATA_OFFSET (IRO[201].base)
+#define USTORM_AGG_DATA_SIZE (IRO[201].size)
+#define USTORM_ASSERT_LIST_INDEX_OFFSET (IRO[170].base)
+#define USTORM_ASSERT_LIST_OFFSET(assertListEntry) \
+ (IRO[169].base + ((assertListEntry) * IRO[169].m1))
+#define USTORM_ETH_PAUSE_ENABLED_OFFSET(portId) \
+ (IRO[178].base + ((portId) * IRO[178].m1))
+#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \
+ (IRO[172].base + ((pfId) * IRO[172].m1))
+#define USTORM_FCOE_EQ_PROD_OFFSET(pfId) \
+ (IRO[313].base + ((pfId) * IRO[313].m1))
+#define USTORM_FUNC_EN_OFFSET(funcId) \
+ (IRO[174].base + ((funcId) * IRO[174].m1))
+#define USTORM_FUNCTION_MODE_OFFSET (IRO[177].base)
+#define USTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \
+ (IRO[277].base + ((pfId) * IRO[277].m1))
+#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \
+ (IRO[278].base + ((pfId) * IRO[278].m1))
+#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \
+ (IRO[282].base + ((pfId) * IRO[282].m1))
+#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfId) \
+ (IRO[279].base + ((pfId) * IRO[279].m1))
+#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
+ (IRO[275].base + ((pfId) * IRO[275].m1))
+#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
+ (IRO[274].base + ((pfId) * IRO[274].m1))
+#define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
+ (IRO[273].base + ((pfId) * IRO[273].m1))
+#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \
+ (IRO[276].base + ((pfId) * IRO[276].m1))
+#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \
+ (IRO[280].base + ((pfId) * IRO[280].m1))
+#define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \
+ (IRO[281].base + ((pfId) * IRO[281].m1))
+#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(pfId) \
+ (IRO[176].base + ((pfId) * IRO[176].m1))
+ #define USTORM_PER_COUNTER_ID_STATS_OFFSET(portId, uStatCntId) \
+ (IRO[173].base + ((portId) * IRO[173].m1) + ((uStatCntId) * \
+ IRO[173].m2))
+ #define USTORM_RX_PRODS_E1X_OFFSET(portId, clientId) \
+ (IRO[204].base + ((portId) * IRO[204].m1) + ((clientId) * \
+ IRO[204].m2))
+#define USTORM_RX_PRODS_E2_OFFSET(qzoneId) \
+ (IRO[205].base + ((qzoneId) * IRO[205].m1))
+#define USTORM_STATS_FLAGS_OFFSET(pfId) \
+ (IRO[171].base + ((pfId) * IRO[171].m1))
+#define USTORM_TPA_BTR_OFFSET (IRO[202].base)
+#define USTORM_TPA_BTR_SIZE (IRO[202].size)
+#define USTORM_VF_TO_PF_OFFSET(funcId) \
+ (IRO[175].base + ((funcId) * IRO[175].m1))
+#define XSTORM_AGG_INT_FINAL_CLEANUP_COMP_TYPE (IRO[59].base)
+#define XSTORM_AGG_INT_FINAL_CLEANUP_INDEX (IRO[58].base)
+#define XSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[54].base)
+#define XSTORM_ASSERT_LIST_OFFSET(assertListEntry) \
+ (IRO[53].base + ((assertListEntry) * IRO[53].m1))
+#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(portId) \
+ (IRO[47].base + ((portId) * IRO[47].m1))
+#define XSTORM_E1HOV_OFFSET(pfId) \
+ (IRO[55].base + ((pfId) * IRO[55].m1))
+#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \
+ (IRO[45].base + ((pfId) * IRO[45].m1))
+#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(pfId) \
+ (IRO[49].base + ((pfId) * IRO[49].m1))
+#define XSTORM_FUNC_EN_OFFSET(funcId) \
+ (IRO[51].base + ((funcId) * IRO[51].m1))
+#define XSTORM_FUNCTION_MODE_OFFSET (IRO[56].base)
+#define XSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \
+ (IRO[290].base + ((pfId) * IRO[290].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfId) \
+ (IRO[293].base + ((pfId) * IRO[293].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \
+ (IRO[294].base + ((pfId) * IRO[294].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \
+ (IRO[295].base + ((pfId) * IRO[295].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \
+ (IRO[296].base + ((pfId) * IRO[296].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \
+ (IRO[297].base + ((pfId) * IRO[297].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \
+ (IRO[298].base + ((pfId) * IRO[298].m1))
+#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \
+ (IRO[299].base + ((pfId) * IRO[299].m1))
+#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
+ (IRO[289].base + ((pfId) * IRO[289].m1))
+#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
+ (IRO[288].base + ((pfId) * IRO[288].m1))
+#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
+ (IRO[287].base + ((pfId) * IRO[287].m1))
+#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \
+ (IRO[292].base + ((pfId) * IRO[292].m1))
+#define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \
+ (IRO[291].base + ((pfId) * IRO[291].m1))
+#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfId) \
+ (IRO[286].base + ((pfId) * IRO[286].m1))
+#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \
+ (IRO[285].base + ((pfId) * IRO[285].m1))
+#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \
+ (IRO[284].base + ((pfId) * IRO[284].m1))
+#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \
+ (IRO[283].base + ((pfId) * IRO[283].m1))
+#define XSTORM_PATH_ID_OFFSET (IRO[65].base)
+ #define XSTORM_PER_COUNTER_ID_STATS_OFFSET(portId, xStatCntId) \
+ (IRO[50].base + ((portId) * IRO[50].m1) + ((xStatCntId) * \
+ IRO[50].m2))
+#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(pfId) \
+ (IRO[48].base + ((pfId) * IRO[48].m1))
+#define XSTORM_SPQ_DATA_OFFSET(funcId) \
+ (IRO[32].base + ((funcId) * IRO[32].m1))
+#define XSTORM_SPQ_DATA_SIZE (IRO[32].size)
+#define XSTORM_SPQ_PAGE_BASE_OFFSET(funcId) \
+ (IRO[30].base + ((funcId) * IRO[30].m1))
+#define XSTORM_SPQ_PROD_OFFSET(funcId) \
+ (IRO[31].base + ((funcId) * IRO[31].m1))
+#define XSTORM_STATS_FLAGS_OFFSET(pfId) \
+ (IRO[43].base + ((pfId) * IRO[43].m1))
+#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(portId) \
+ (IRO[206].base + ((portId) * IRO[206].m1))
+#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(portId) \
+ (IRO[207].base + ((portId) * IRO[207].m1))
+#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(pfId) \
+ (IRO[209].base + (((pfId)>>1) * IRO[209].m1) + (((pfId)&1) * \
+ IRO[209].m2))
+#define XSTORM_VF_TO_PF_OFFSET(funcId) \
+ (IRO[52].base + ((funcId) * IRO[52].m1))
#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
-/**
-* This file defines HSI constants for the ETH flow
-*/
-#ifdef _EVEREST_MICROCODE
-#include "microcode_constants.h"
-#include "eth_rx_bd.h"
-#include "eth_tx_bd.h"
-#include "eth_rx_cqe.h"
-#include "eth_rx_sge.h"
-#include "eth_rx_cqe_next_page.h"
-#endif
-
/* RSS hash types */
#define DEFAULT_HASH_TYPE 0
#define IPV4_HASH_TYPE 1
@@ -389,11 +292,17 @@
#define U_ETH_NUM_OF_SGES_TO_FETCH 8
#define U_ETH_MAX_SGES_FOR_PACKET 3
+/*Tx params*/
+#define X_ETH_NO_VLAN 0
+#define X_ETH_OUTBAND_VLAN 1
+#define X_ETH_INBAND_VLAN 2
/* Rx ring params */
#define U_ETH_LOCAL_BD_RING_SIZE 8
#define U_ETH_LOCAL_SGE_RING_SIZE 10
#define U_ETH_SGL_SIZE 8
-
+ /* The fw will padd the buffer with this value, so the IP header \
+ will be align to 4 Byte */
+#define IP_HEADER_ALIGNMENT_PADDING 2
#define U_ETH_SGES_PER_PAGE_INVERSE_MASK \
(0xFFFF - ((PAGE_SIZE/((STRUCT_SIZE(eth_rx_sge))/8))-1))
@@ -409,16 +318,15 @@
#define U_ETH_UNDEFINED_Q 0xFF
/* values of command IDs in the ramrod message */
-#define RAMROD_CMD_ID_ETH_PORT_SETUP 80
-#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 85
-#define RAMROD_CMD_ID_ETH_STAT_QUERY 90
-#define RAMROD_CMD_ID_ETH_UPDATE 100
-#define RAMROD_CMD_ID_ETH_HALT 105
-#define RAMROD_CMD_ID_ETH_SET_MAC 110
-#define RAMROD_CMD_ID_ETH_CFC_DEL 115
-#define RAMROD_CMD_ID_ETH_PORT_DEL 120
-#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 125
-
+#define RAMROD_CMD_ID_ETH_UNUSED 0
+#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 1
+#define RAMROD_CMD_ID_ETH_UPDATE 2
+#define RAMROD_CMD_ID_ETH_HALT 3
+#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 4
+#define RAMROD_CMD_ID_ETH_ACTIVATE 5
+#define RAMROD_CMD_ID_ETH_DEACTIVATE 6
+#define RAMROD_CMD_ID_ETH_EMPTY 7
+#define RAMROD_CMD_ID_ETH_TERMINATE 8
/* command values for set mac command */
#define T_ETH_MAC_COMMAND_SET 0
@@ -431,7 +339,9 @@
/* Maximal L2 clients supported */
#define ETH_MAX_RX_CLIENTS_E1 18
-#define ETH_MAX_RX_CLIENTS_E1H 26
+#define ETH_MAX_RX_CLIENTS_E1H 28
+
+#define MAX_STAT_COUNTER_ID ETH_MAX_RX_CLIENTS_E1H
/* Maximal aggregation queues supported */
#define ETH_MAX_AGGREGATION_QUEUES_E1 32
@@ -443,6 +353,20 @@
#define ETH_RSS_MODE_VLAN_PRI 2
#define ETH_RSS_MODE_E1HOV_PRI 3
#define ETH_RSS_MODE_IP_DSCP 4
+#define ETH_RSS_MODE_E2_INTEG 5
+
+
+/* ETH vlan filtering modes */
+#define ETH_VLAN_FILTER_ANY_VLAN 0 /* Don't filter by vlan */
+#define ETH_VLAN_FILTER_SPECIFIC_VLAN \
+ 1 /* Only the vlan_id is allowed */
+#define ETH_VLAN_FILTER_CLASSIFY \
+ 2 /* vlan will be added to CAM for classification */
+
+/* Fast path CQE selection */
+#define ETH_FP_CQE_REGULAR 0
+#define ETH_FP_CQE_SGL 1
+#define ETH_FP_CQE_RAW 2
/**
@@ -458,6 +382,7 @@
#define RESERVED_CONNECTION_TYPE_0 5
#define RESERVED_CONNECTION_TYPE_1 6
#define RESERVED_CONNECTION_TYPE_2 7
+#define NONE_CONNECTION_TYPE 8
#define PROTOCOL_STATE_BIT_OFFSET 6
@@ -466,6 +391,16 @@
#define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
#define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
+/* values of command IDs in the ramrod message */
+#define RAMROD_CMD_ID_COMMON_FUNCTION_START 1
+#define RAMROD_CMD_ID_COMMON_FUNCTION_STOP 2
+#define RAMROD_CMD_ID_COMMON_CFC_DEL 3
+#define RAMROD_CMD_ID_COMMON_CFC_DEL_WB 4
+#define RAMROD_CMD_ID_COMMON_SET_MAC 5
+#define RAMROD_CMD_ID_COMMON_STAT_QUERY 6
+#define RAMROD_CMD_ID_COMMON_STOP_TRAFFIC 7
+#define RAMROD_CMD_ID_COMMON_START_TRAFFIC 8
+
/* microcode fixed page page size 4K (chains and ring segments) */
#define MC_PAGE_SIZE 4096
@@ -473,46 +408,26 @@
/* Host coalescing constants */
#define HC_IGU_BC_MODE 0
#define HC_IGU_NBC_MODE 1
+/* Host coalescing constants. E1 includes E1H as well */
+
+/* Number of indices per slow-path SB */
+#define HC_SP_SB_MAX_INDICES 16
+
+/* Number of indices per SB */
+#define HC_SB_MAX_INDICES_E1X 8
+#define HC_SB_MAX_INDICES_E2 8
+
+#define HC_SB_MAX_SB_E1X 32
+#define HC_SB_MAX_SB_E2 136
+
+#define HC_SP_SB_ID 0xde
#define HC_REGULAR_SEGMENT 0
#define HC_DEFAULT_SEGMENT 1
+#define HC_SB_MAX_SM 2
-/* index numbers */
-#define HC_USTORM_DEF_SB_NUM_INDICES 8
-#define HC_CSTORM_DEF_SB_NUM_INDICES 8
-#define HC_XSTORM_DEF_SB_NUM_INDICES 4
-#define HC_TSTORM_DEF_SB_NUM_INDICES 4
-#define HC_USTORM_SB_NUM_INDICES 4
-#define HC_CSTORM_SB_NUM_INDICES 4
-
-/* index values - which counter to update */
-
-#define HC_INDEX_U_TOE_RX_CQ_CONS 0
-#define HC_INDEX_U_ETH_RX_CQ_CONS 1
-#define HC_INDEX_U_ETH_RX_BD_CONS 2
-#define HC_INDEX_U_FCOE_EQ_CONS 3
-
-#define HC_INDEX_C_TOE_TX_CQ_CONS 0
-#define HC_INDEX_C_ETH_TX_CQ_CONS 1
-#define HC_INDEX_C_ISCSI_EQ_CONS 2
-
-#define HC_INDEX_DEF_X_SPQ_CONS 0
-
-#define HC_INDEX_DEF_C_RDMA_EQ_CONS 0
-#define HC_INDEX_DEF_C_RDMA_NAL_PROD 1
-#define HC_INDEX_DEF_C_ETH_FW_TX_CQ_CONS 2
-#define HC_INDEX_DEF_C_ETH_SLOW_PATH 3
-#define HC_INDEX_DEF_C_ETH_RDMA_CQ_CONS 4
-#define HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS 5
-#define HC_INDEX_DEF_C_ETH_FCOE_CQ_CONS 6
-
-#define HC_INDEX_DEF_U_ETH_RDMA_RX_CQ_CONS 0
-#define HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS 1
-#define HC_INDEX_DEF_U_ETH_RDMA_RX_BD_CONS 2
-#define HC_INDEX_DEF_U_ETH_ISCSI_RX_BD_CONS 3
-#define HC_INDEX_DEF_U_ETH_FCOE_RX_CQ_CONS 4
-#define HC_INDEX_DEF_U_ETH_FCOE_RX_BD_CONS 5
-
+#define HC_SB_MAX_DYNAMIC_INDICES 4
+#define HC_FUNCTION_DISABLED 0xff
/* used by the driver to get the SB offset */
#define USTORM_ID 0
#define CSTORM_ID 1
@@ -529,45 +444,17 @@
/**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
-#define EMULATION_FREQUENCY_FACTOR 1600
-#define FPGA_FREQUENCY_FACTOR 100
#define TIMERS_TICK_SIZE_CHIP (1e-3)
-#define TIMERS_TICK_SIZE_EMUL \
- ((TIMERS_TICK_SIZE_CHIP)/((EMULATION_FREQUENCY_FACTOR)))
-#define TIMERS_TICK_SIZE_FPGA \
- ((TIMERS_TICK_SIZE_CHIP)/((FPGA_FREQUENCY_FACTOR)))
#define TSEMI_CLK1_RESUL_CHIP (1e-3)
-#define TSEMI_CLK1_RESUL_EMUL \
- ((TSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
-#define TSEMI_CLK1_RESUL_FPGA \
- ((TSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
-
-#define USEMI_CLK1_RESUL_CHIP (TIMERS_TICK_SIZE_CHIP)
-#define USEMI_CLK1_RESUL_EMUL (TIMERS_TICK_SIZE_EMUL)
-#define USEMI_CLK1_RESUL_FPGA (TIMERS_TICK_SIZE_FPGA)
#define XSEMI_CLK1_RESUL_CHIP (1e-3)
-#define XSEMI_CLK1_RESUL_EMUL \
- ((XSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
-#define XSEMI_CLK1_RESUL_FPGA \
- ((XSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
-
-#define XSEMI_CLK2_RESUL_CHIP (1e-6)
-#define XSEMI_CLK2_RESUL_EMUL \
- ((XSEMI_CLK2_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
-#define XSEMI_CLK2_RESUL_FPGA \
- ((XSEMI_CLK2_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
#define SDM_TIMER_TICK_RESUL_CHIP (4*(1e-6))
-#define SDM_TIMER_TICK_RESUL_EMUL \
- ((SDM_TIMER_TICK_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
-#define SDM_TIMER_TICK_RESUL_FPGA \
- ((SDM_TIMER_TICK_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
-
/**** END DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
+
#define XSTORM_IP_ID_ROLL_HALF 0x8000
#define XSTORM_IP_ID_ROLL_ALL 0
@@ -576,10 +463,36 @@
#define NUM_OF_PROTOCOLS 4
#define NUM_OF_SAFC_BITS 16
#define MAX_COS_NUMBER 4
-#define MAX_T_STAT_COUNTER_ID 18
-#define MAX_X_STAT_COUNTER_ID 18
-#define MAX_U_STAT_COUNTER_ID 18
+#define FAIRNESS_COS_WRR_MODE 0
+#define FAIRNESS_COS_ETS_MODE 1
+
+
+/* Priority Flow Control (PFC) */
+#define MAX_PFC_PRIORITIES 8
+#define MAX_PFC_TRAFFIC_TYPES 8
+
+/* Available Traffic Types for Link Layer Flow Control */
+#define LLFC_TRAFFIC_TYPE_NW 0
+#define LLFC_TRAFFIC_TYPE_FCOE 1
+#define LLFC_TRAFFIC_TYPE_ISCSI 2
+ /***************** START OF E2 INTEGRATION \
+ CODE***************************************/
+#define LLFC_TRAFFIC_TYPE_NW_COS1_E2INTEG 3
+ /***************** END OF E2 INTEGRATION \
+ CODE***************************************/
+#define LLFC_TRAFFIC_TYPE_MAX 4
+
+ /* used by array traffic_type_to_priority[] to mark traffic type \
+ that is not mapped to priority*/
+#define LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED 0xFF
+
+#define LLFC_MODE_NONE 0
+#define LLFC_MODE_PFC 1
+#define LLFC_MODE_SAFC 2
+
+#define DCB_DISABLED 0
+#define DCB_ENABLED 1
#define UNKNOWN_ADDRESS 0
#define UNICAST_ADDRESS 1
@@ -587,8 +500,32 @@
#define BROADCAST_ADDRESS 3
#define SINGLE_FUNCTION 0
-#define MULTI_FUNCTION 1
+#define MULTI_FUNCTION_SD 1
+#define MULTI_FUNCTION_SI 2
#define IP_V4 0
#define IP_V6 1
+
+#define C_ERES_PER_PAGE \
+ (PAGE_SIZE / BITS_TO_BYTES(STRUCT_SIZE(event_ring_elem)))
+#define C_ERE_PER_PAGE_MASK (C_ERES_PER_PAGE - 1)
+
+#define EVENT_RING_OPCODE_VF_PF_CHANNEL 0
+#define EVENT_RING_OPCODE_FUNCTION_START 1
+#define EVENT_RING_OPCODE_FUNCTION_STOP 2
+#define EVENT_RING_OPCODE_CFC_DEL 3
+#define EVENT_RING_OPCODE_CFC_DEL_WB 4
+#define EVENT_RING_OPCODE_SET_MAC 5
+#define EVENT_RING_OPCODE_STAT_QUERY 6
+#define EVENT_RING_OPCODE_STOP_TRAFFIC 7
+#define EVENT_RING_OPCODE_START_TRAFFIC 8
+#define EVENT_RING_OPCODE_FORWARD_SETUP 9
+
+#define VF_PF_CHANNEL_STATE_READY 0
+#define VF_PF_CHANNEL_STATE_WAITING_FOR_ACK 1
+
+#define VF_PF_CHANNEL_STATE_MAX_NUMBER 2
+
+
+#endif /* BNX2X_FW_DEFS_H */
diff --git a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h
index 3f5ee5d7cc2a..f807262911e5 100644
--- a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h
+++ b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h
@@ -31,6 +31,7 @@ struct bnx2x_fw_file_hdr {
struct bnx2x_fw_file_section csem_pram_data;
struct bnx2x_fw_file_section xsem_int_table_data;
struct bnx2x_fw_file_section xsem_pram_data;
+ struct bnx2x_fw_file_section iro_arr;
struct bnx2x_fw_file_section fw_version;
};
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h
index fd1f29e0317d..18c8e23a0e82 100644
--- a/drivers/net/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/bnx2x/bnx2x_hsi.h
@@ -6,6 +6,10 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*/
+#ifndef BNX2X_HSI_H
+#define BNX2X_HSI_H
+
+#include "bnx2x_fw_defs.h"
struct license_key {
u32 reserved[6];
@@ -78,6 +82,8 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_LED_PHY11 0x000b0000
#define SHARED_HW_CFG_LED_MAC4 0x000c0000
#define SHARED_HW_CFG_LED_PHY8 0x000d0000
+#define SHARED_HW_CFG_LED_EXTPHY1 0x000e0000
+
#define SHARED_HW_CFG_AN_ENABLE_MASK 0x3f000000
#define SHARED_HW_CFG_AN_ENABLE_SHIFT 24
@@ -120,6 +126,23 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_FAN_FAILURE_DISABLED 0x00080000
#define SHARED_HW_CFG_FAN_FAILURE_ENABLED 0x00100000
+ /* Set the MDC/MDIO access for the first external phy */
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK 0x1C000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT 26
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE 0x00000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0 0x04000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1 0x08000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH 0x0c000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED 0x10000000
+
+ /* Set the MDC/MDIO access for the second external phy */
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK 0xE0000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT 29
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_PHY_TYPE 0x00000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_EMAC0 0x20000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_EMAC1 0x40000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_BOTH 0x60000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_SWAPPED 0x80000000
u32 power_dissipated; /* 0x11c */
#define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000
#define SHARED_HW_CFG_POWER_DIS_CMN_SHIFT 24
@@ -221,11 +244,93 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
u16 xgxs_config_tx[4]; /* 0x1A0 */
- u32 Reserved1[64]; /* 0x1A8 */
+ u32 Reserved1[57]; /* 0x1A8 */
+ u32 speed_capability_mask2; /* 0x28C */
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_10M_FULL 0x00000001
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3__ 0x00000002
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3___ 0x00000004
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_100M_FULL 0x00000008
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_1G 0x00000010
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_2_DOT_5G 0x00000020
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_10G 0x00000040
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_12G 0x00000080
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_12_DOT_5G 0x00000100
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_13G 0x00000200
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_15G 0x00000400
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_16G 0x00000800
+
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_MASK 0xFFFF0000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_SHIFT 16
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_10M_FULL 0x00010000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0__ 0x00020000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0___ 0x00040000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_100M_FULL 0x00080000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_1G 0x00100000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_2_DOT_5G 0x00200000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_10G 0x00400000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_12G 0x00800000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_12_DOT_5G 0x01000000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_13G 0x02000000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_15G 0x04000000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_16G 0x08000000
+
+ /* In the case where two media types (e.g. copper and fiber) are
+ present and electrically active at the same time, PHY Selection
+ will determine which of the two PHYs will be designated as the
+ Active PHY and used for a connection to the network. */
+ u32 multi_phy_config; /* 0x290 */
+#define PORT_HW_CFG_PHY_SELECTION_MASK 0x00000007
+#define PORT_HW_CFG_PHY_SELECTION_SHIFT 0
+#define PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT 0x00000000
+#define PORT_HW_CFG_PHY_SELECTION_FIRST_PHY 0x00000001
+#define PORT_HW_CFG_PHY_SELECTION_SECOND_PHY 0x00000002
+#define PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY 0x00000003
+#define PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY 0x00000004
+
+ /* When enabled, all second phy nvram parameters will be swapped
+ with the first phy parameters */
+#define PORT_HW_CFG_PHY_SWAPPED_MASK 0x00000008
+#define PORT_HW_CFG_PHY_SWAPPED_SHIFT 3
+#define PORT_HW_CFG_PHY_SWAPPED_DISABLED 0x00000000
+#define PORT_HW_CFG_PHY_SWAPPED_ENABLED 0x00000008
+
+
+ /* Address of the second external phy */
+ u32 external_phy_config2; /* 0x294 */
+#define PORT_HW_CFG_XGXS_EXT_PHY2_ADDR_MASK 0x000000FF
+#define PORT_HW_CFG_XGXS_EXT_PHY2_ADDR_SHIFT 0
+
+ /* The second XGXS external PHY type */
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_MASK 0x0000FF00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_SHIFT 8
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_DIRECT 0x00000000
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8071 0x00000100
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8072 0x00000200
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8073 0x00000300
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8705 0x00000400
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8706 0x00000500
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8726 0x00000600
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8481 0x00000700
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_SFX7101 0x00000800
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8727 0x00000900
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8727_NOC 0x00000a00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84823 0x00000b00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM54640 0x00000c00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84833 0x00000d00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_FAILURE 0x0000fd00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_NOT_CONN 0x0000ff00
+
+ /* 4 times 16 bits for all 4 lanes. For some external PHYs (such as
+ 8706, 8726 and 8727) not all 4 values are needed. */
+ u16 xgxs_config2_rx[4]; /* 0x296 */
+ u16 xgxs_config2_tx[4]; /* 0x2A0 */
u32 lane_config;
#define PORT_HW_CFG_LANE_SWAP_CFG_MASK 0x0000ffff
#define PORT_HW_CFG_LANE_SWAP_CFG_SHIFT 0
+
#define PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK 0x000000ff
#define PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT 0
#define PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK 0x0000ff00
@@ -515,10 +620,17 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
#define PORT_FEATURE_FLOW_CONTROL_NONE 0x00000400
/* The default for MCP link configuration,
- uses the same defines as link_config */
+ uses the same defines as link_config */
u32 mfw_wol_link_cfg;
+ /* The default for the driver of the second external phy,
+ uses the same defines as link_config */
+ u32 link_config2; /* 0x47C */
- u32 reserved[19];
+ /* The default for MCP of the second external phy,
+ uses the same defines as link_config */
+ u32 mfw_wol_link_cfg2; /* 0x480 */
+
+ u32 Reserved2[17]; /* 0x484 */
};
@@ -551,6 +663,7 @@ struct shm_dev_info { /* size */
#define FUNC_7 7
#define E1_FUNC_MAX 2
#define E1H_FUNC_MAX 8
+#define E2_FUNC_MAX 4 /* per path */
#define VN_0 0
#define VN_1 1
@@ -686,8 +799,14 @@ struct drv_func_mb {
* The optic module verification commands require bootcode
* v5.0.6 or later
*/
-#define DRV_MSG_CODE_VRFY_OPT_MDL 0xa0000000
-#define REQ_BC_VER_4_VRFY_OPT_MDL 0x00050006
+#define DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL 0xa0000000
+#define REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL 0x00050006
+ /*
+ * The specific optic module verification command requires bootcode
+ * v5.2.12 or later
+ */
+#define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000
+#define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234
#define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000
#define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000
@@ -703,6 +822,9 @@ struct drv_func_mb {
#define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000
#define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000
#define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000
+ /* Load common chip is supported from bc 6.0.0 */
+#define REQ_BC_VER_4_DRV_LOAD_COMMON_CHIP 0x00060000
+#define FW_MSG_CODE_DRV_LOAD_COMMON_CHIP 0x10130000
#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000
#define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000
#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000
@@ -903,11 +1025,22 @@ struct shmem_region { /* SharedMem Offset (size) */
struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */
struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */
- struct drv_func_mb func_mb[E1H_FUNC_MAX];
+ struct drv_func_mb func_mb[]; /* 0x684
+ (44*2/4/8=0x58/0xb0/0x160) */
+
+}; /* 57710 = 0x6dc | 57711 = 0x7E4 | 57712 = 0x734 */
- struct mf_cfg mf_cfg;
+struct fw_flr_ack {
+ u32 pf_ack;
+ u32 vf_ack[1];
+ u32 iov_dis_ack;
+};
-}; /* 0x6dc */
+struct fw_flr_mb {
+ u32 aggint;
+ u32 opgen_addr;
+ struct fw_flr_ack ack;
+};
struct shmem2_region {
@@ -922,7 +1055,25 @@ struct shmem2_region {
#define SHMEM_DCC_SUPPORT_SET_PROTOCOL_TLV 0x00000040
#define SHMEM_DCC_SUPPORT_SET_PRIORITY_TLV 0x00000080
#define SHMEM_DCC_SUPPORT_DEFAULT SHMEM_DCC_SUPPORT_NONE
-
+ u32 ext_phy_fw_version2[PORT_MAX];
+ /*
+ * For backwards compatibility, if the mf_cfg_addr does not exist
+ * (the size filed is smaller than 0xc) the mf_cfg resides at the
+ * end of struct shmem_region
+ */
+ u32 mf_cfg_addr;
+#define SHMEM_MF_CFG_ADDR_NONE 0x00000000
+
+ struct fw_flr_mb flr_mb;
+ u32 reserved[3];
+ /*
+ * The other shmemX_base_addr holds the other path's shmem address
+ * required for example in case of common phy init, or for path1 to know
+ * the address of mcp debug trace which is located in offset from shmem
+ * of path0
+ */
+ u32 other_shmem_base_addr;
+ u32 other_shmem2_base_addr;
};
@@ -978,7 +1129,7 @@ struct emac_stats {
};
-struct bmac_stats {
+struct bmac1_stats {
u32 tx_stat_gtpkt_lo;
u32 tx_stat_gtpkt_hi;
u32 tx_stat_gtxpf_lo;
@@ -1082,10 +1233,126 @@ struct bmac_stats {
u32 rx_stat_gripj_hi;
};
+struct bmac2_stats {
+ u32 tx_stat_gtpk_lo; /* gtpok */
+ u32 tx_stat_gtpk_hi; /* gtpok */
+ u32 tx_stat_gtxpf_lo; /* gtpf */
+ u32 tx_stat_gtxpf_hi; /* gtpf */
+ u32 tx_stat_gtpp_lo; /* NEW BMAC2 */
+ u32 tx_stat_gtpp_hi; /* NEW BMAC2 */
+ u32 tx_stat_gtfcs_lo;
+ u32 tx_stat_gtfcs_hi;
+ u32 tx_stat_gtuca_lo; /* NEW BMAC2 */
+ u32 tx_stat_gtuca_hi; /* NEW BMAC2 */
+ u32 tx_stat_gtmca_lo;
+ u32 tx_stat_gtmca_hi;
+ u32 tx_stat_gtbca_lo;
+ u32 tx_stat_gtbca_hi;
+ u32 tx_stat_gtovr_lo;
+ u32 tx_stat_gtovr_hi;
+ u32 tx_stat_gtfrg_lo;
+ u32 tx_stat_gtfrg_hi;
+ u32 tx_stat_gtpkt1_lo; /* gtpkt */
+ u32 tx_stat_gtpkt1_hi; /* gtpkt */
+ u32 tx_stat_gt64_lo;
+ u32 tx_stat_gt64_hi;
+ u32 tx_stat_gt127_lo;
+ u32 tx_stat_gt127_hi;
+ u32 tx_stat_gt255_lo;
+ u32 tx_stat_gt255_hi;
+ u32 tx_stat_gt511_lo;
+ u32 tx_stat_gt511_hi;
+ u32 tx_stat_gt1023_lo;
+ u32 tx_stat_gt1023_hi;
+ u32 tx_stat_gt1518_lo;
+ u32 tx_stat_gt1518_hi;
+ u32 tx_stat_gt2047_lo;
+ u32 tx_stat_gt2047_hi;
+ u32 tx_stat_gt4095_lo;
+ u32 tx_stat_gt4095_hi;
+ u32 tx_stat_gt9216_lo;
+ u32 tx_stat_gt9216_hi;
+ u32 tx_stat_gt16383_lo;
+ u32 tx_stat_gt16383_hi;
+ u32 tx_stat_gtmax_lo;
+ u32 tx_stat_gtmax_hi;
+ u32 tx_stat_gtufl_lo;
+ u32 tx_stat_gtufl_hi;
+ u32 tx_stat_gterr_lo;
+ u32 tx_stat_gterr_hi;
+ u32 tx_stat_gtbyt_lo;
+ u32 tx_stat_gtbyt_hi;
+
+ u32 rx_stat_gr64_lo;
+ u32 rx_stat_gr64_hi;
+ u32 rx_stat_gr127_lo;
+ u32 rx_stat_gr127_hi;
+ u32 rx_stat_gr255_lo;
+ u32 rx_stat_gr255_hi;
+ u32 rx_stat_gr511_lo;
+ u32 rx_stat_gr511_hi;
+ u32 rx_stat_gr1023_lo;
+ u32 rx_stat_gr1023_hi;
+ u32 rx_stat_gr1518_lo;
+ u32 rx_stat_gr1518_hi;
+ u32 rx_stat_gr2047_lo;
+ u32 rx_stat_gr2047_hi;
+ u32 rx_stat_gr4095_lo;
+ u32 rx_stat_gr4095_hi;
+ u32 rx_stat_gr9216_lo;
+ u32 rx_stat_gr9216_hi;
+ u32 rx_stat_gr16383_lo;
+ u32 rx_stat_gr16383_hi;
+ u32 rx_stat_grmax_lo;
+ u32 rx_stat_grmax_hi;
+ u32 rx_stat_grpkt_lo;
+ u32 rx_stat_grpkt_hi;
+ u32 rx_stat_grfcs_lo;
+ u32 rx_stat_grfcs_hi;
+ u32 rx_stat_gruca_lo;
+ u32 rx_stat_gruca_hi;
+ u32 rx_stat_grmca_lo;
+ u32 rx_stat_grmca_hi;
+ u32 rx_stat_grbca_lo;
+ u32 rx_stat_grbca_hi;
+ u32 rx_stat_grxpf_lo; /* grpf */
+ u32 rx_stat_grxpf_hi; /* grpf */
+ u32 rx_stat_grpp_lo;
+ u32 rx_stat_grpp_hi;
+ u32 rx_stat_grxuo_lo; /* gruo */
+ u32 rx_stat_grxuo_hi; /* gruo */
+ u32 rx_stat_grjbr_lo;
+ u32 rx_stat_grjbr_hi;
+ u32 rx_stat_grovr_lo;
+ u32 rx_stat_grovr_hi;
+ u32 rx_stat_grxcf_lo; /* grcf */
+ u32 rx_stat_grxcf_hi; /* grcf */
+ u32 rx_stat_grflr_lo;
+ u32 rx_stat_grflr_hi;
+ u32 rx_stat_grpok_lo;
+ u32 rx_stat_grpok_hi;
+ u32 rx_stat_grmeg_lo;
+ u32 rx_stat_grmeg_hi;
+ u32 rx_stat_grmeb_lo;
+ u32 rx_stat_grmeb_hi;
+ u32 rx_stat_grbyt_lo;
+ u32 rx_stat_grbyt_hi;
+ u32 rx_stat_grund_lo;
+ u32 rx_stat_grund_hi;
+ u32 rx_stat_grfrg_lo;
+ u32 rx_stat_grfrg_hi;
+ u32 rx_stat_grerb_lo; /* grerrbyt */
+ u32 rx_stat_grerb_hi; /* grerrbyt */
+ u32 rx_stat_grfre_lo; /* grfrerr */
+ u32 rx_stat_grfre_hi; /* grfrerr */
+ u32 rx_stat_gripj_lo;
+ u32 rx_stat_gripj_hi;
+};
union mac_stats {
- struct emac_stats emac_stats;
- struct bmac_stats bmac_stats;
+ struct emac_stats emac_stats;
+ struct bmac1_stats bmac1_stats;
+ struct bmac2_stats bmac2_stats;
};
@@ -1259,17 +1526,17 @@ struct host_func_stats {
};
-#define BCM_5710_FW_MAJOR_VERSION 5
-#define BCM_5710_FW_MINOR_VERSION 2
-#define BCM_5710_FW_REVISION_VERSION 13
-#define BCM_5710_FW_ENGINEERING_VERSION 0
+#define BCM_5710_FW_MAJOR_VERSION 6
+#define BCM_5710_FW_MINOR_VERSION 0
+#define BCM_5710_FW_REVISION_VERSION 34
+#define BCM_5710_FW_ENGINEERING_VERSION 0
#define BCM_5710_FW_COMPILE_FLAGS 1
/*
* attention bits
*/
-struct atten_def_status_block {
+struct atten_sp_status_block {
__le32 attn_bits;
__le32 attn_bits_ack;
u8 status_block_id;
@@ -1327,7 +1594,60 @@ struct doorbell_set_prod {
/*
- * IGU driver acknowledgement register
+ * 3 lines. status block
+ */
+struct hc_status_block_e1x {
+ __le16 index_values[HC_SB_MAX_INDICES_E1X];
+ __le16 running_index[HC_SB_MAX_SM];
+ u32 rsrv;
+};
+
+/*
+ * host status block
+ */
+struct host_hc_status_block_e1x {
+ struct hc_status_block_e1x sb;
+};
+
+
+/*
+ * 3 lines. status block
+ */
+struct hc_status_block_e2 {
+ __le16 index_values[HC_SB_MAX_INDICES_E2];
+ __le16 running_index[HC_SB_MAX_SM];
+ u32 reserved;
+};
+
+/*
+ * host status block
+ */
+struct host_hc_status_block_e2 {
+ struct hc_status_block_e2 sb;
+};
+
+
+/*
+ * 5 lines. slow-path status block
+ */
+struct hc_sp_status_block {
+ __le16 index_values[HC_SP_SB_MAX_INDICES];
+ __le16 running_index;
+ __le16 rsrv;
+ u32 rsrv1;
+};
+
+/*
+ * host status block
+ */
+struct host_sp_status_block {
+ struct atten_sp_status_block atten_status_block;
+ struct hc_sp_status_block sp_sb;
+};
+
+
+/*
+ * IGU driver acknowledgment register
*/
struct igu_ack_register {
#if defined(__BIG_ENDIAN)
@@ -1417,6 +1737,24 @@ union igu_consprod_reg {
/*
+ * Control register for the IGU command register
+ */
+struct igu_ctrl_reg {
+ u32 ctrl_data;
+#define IGU_CTRL_REG_ADDRESS (0xFFF<<0)
+#define IGU_CTRL_REG_ADDRESS_SHIFT 0
+#define IGU_CTRL_REG_FID (0x7F<<12)
+#define IGU_CTRL_REG_FID_SHIFT 12
+#define IGU_CTRL_REG_RESERVED (0x1<<19)
+#define IGU_CTRL_REG_RESERVED_SHIFT 19
+#define IGU_CTRL_REG_TYPE (0x1<<20)
+#define IGU_CTRL_REG_TYPE_SHIFT 20
+#define IGU_CTRL_REG_UNUSED (0x7FF<<21)
+#define IGU_CTRL_REG_UNUSED_SHIFT 21
+};
+
+
+/*
* Parser parsing flags field
*/
struct parsing_flags {
@@ -1485,8 +1823,14 @@ struct dmae_command {
#define DMAE_COMMAND_DST_RESET_SHIFT 14
#define DMAE_COMMAND_E1HVN (0x3<<15)
#define DMAE_COMMAND_E1HVN_SHIFT 15
-#define DMAE_COMMAND_RESERVED0 (0x7FFF<<17)
-#define DMAE_COMMAND_RESERVED0_SHIFT 17
+#define DMAE_COMMAND_DST_VN (0x3<<17)
+#define DMAE_COMMAND_DST_VN_SHIFT 17
+#define DMAE_COMMAND_C_FUNC (0x1<<19)
+#define DMAE_COMMAND_C_FUNC_SHIFT 19
+#define DMAE_COMMAND_ERR_POLICY (0x3<<20)
+#define DMAE_COMMAND_ERR_POLICY_SHIFT 20
+#define DMAE_COMMAND_RESERVED0 (0x3FF<<22)
+#define DMAE_COMMAND_RESERVED0_SHIFT 22
u32 src_addr_lo;
u32 src_addr_hi;
u32 dst_addr_lo;
@@ -1511,11 +1855,11 @@ struct dmae_command {
u16 crc16_c;
#endif
#if defined(__BIG_ENDIAN)
- u16 reserved2;
+ u16 reserved3;
u16 crc_t10;
#elif defined(__LITTLE_ENDIAN)
u16 crc_t10;
- u16 reserved2;
+ u16 reserved3;
#endif
#if defined(__BIG_ENDIAN)
u16 xsum8;
@@ -1536,96 +1880,20 @@ struct double_regpair {
/*
- * The eth storm context of Ustorm (configuration part)
+ * SDM operation gen command (generate aggregative interrupt)
*/
-struct ustorm_eth_st_context_config {
-#if defined(__BIG_ENDIAN)
- u8 flags;
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<3)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 3
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
- u8 status_block_id;
- u8 clientId;
- u8 sb_index_numbers;
-#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0
-#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4
-#elif defined(__LITTLE_ENDIAN)
- u8 sb_index_numbers;
-#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0
-#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4
- u8 clientId;
- u8 status_block_id;
- u8 flags;
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<3)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 3
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
-#endif
-#if defined(__BIG_ENDIAN)
- u16 bd_buff_size;
- u8 statistics_counter_id;
- u8 mc_alignment_log_size;
-#elif defined(__LITTLE_ENDIAN)
- u8 mc_alignment_log_size;
- u8 statistics_counter_id;
- u16 bd_buff_size;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __local_sge_prod;
- u8 __local_bd_prod;
- u16 sge_buff_size;
-#elif defined(__LITTLE_ENDIAN)
- u16 sge_buff_size;
- u8 __local_bd_prod;
- u8 __local_sge_prod;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __sdm_bd_expected_counter;
- u8 cstorm_agg_int;
- u8 __expected_bds_on_ram;
-#elif defined(__LITTLE_ENDIAN)
- u8 __expected_bds_on_ram;
- u8 cstorm_agg_int;
- u16 __sdm_bd_expected_counter;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __ring_data_ram_addr;
- u16 __hc_cstorm_ram_addr;
-#elif defined(__LITTLE_ENDIAN)
- u16 __hc_cstorm_ram_addr;
- u16 __ring_data_ram_addr;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 reserved1;
- u8 max_sges_for_packet;
- u16 __bd_ring_ram_addr;
-#elif defined(__LITTLE_ENDIAN)
- u16 __bd_ring_ram_addr;
- u8 max_sges_for_packet;
- u8 reserved1;
-#endif
- u32 bd_page_base_lo;
- u32 bd_page_base_hi;
- u32 sge_page_base_lo;
- u32 sge_page_base_hi;
- struct regpair reserved2;
+struct sdm_op_gen {
+ __le32 command;
+#define SDM_OP_GEN_COMP_PARAM (0x1F<<0)
+#define SDM_OP_GEN_COMP_PARAM_SHIFT 0
+#define SDM_OP_GEN_COMP_TYPE (0x7<<5)
+#define SDM_OP_GEN_COMP_TYPE_SHIFT 5
+#define SDM_OP_GEN_AGG_VECT_IDX (0xFF<<8)
+#define SDM_OP_GEN_AGG_VECT_IDX_SHIFT 8
+#define SDM_OP_GEN_AGG_VECT_IDX_VALID (0x1<<16)
+#define SDM_OP_GEN_AGG_VECT_IDX_VALID_SHIFT 16
+#define SDM_OP_GEN_RESERVED (0x7FFF<<17)
+#define SDM_OP_GEN_RESERVED_SHIFT 17
};
/*
@@ -1644,20 +1912,13 @@ struct eth_rx_sge {
__le32 addr_hi;
};
-/*
- * Local BDs and SGEs rings (in ETH)
- */
-struct eth_local_rx_rings {
- struct eth_rx_bd __local_bd_ring[8];
- struct eth_rx_sge __local_sge_ring[10];
-};
+
/*
* The eth storm context of Ustorm
*/
struct ustorm_eth_st_context {
- struct ustorm_eth_st_context_config common;
- struct eth_local_rx_rings __rings;
+ u32 reserved0[48];
};
/*
@@ -1668,337 +1929,53 @@ struct tstorm_eth_st_context {
};
/*
- * The eth aggregative context section of Xstorm
- */
-struct xstorm_eth_extra_ag_context_section {
-#if defined(__BIG_ENDIAN)
- u8 __tcp_agg_vars1;
- u8 __reserved50;
- u16 __mss;
-#elif defined(__LITTLE_ENDIAN)
- u16 __mss;
- u8 __reserved50;
- u8 __tcp_agg_vars1;
-#endif
- u32 __snd_nxt;
- u32 __tx_wnd;
- u32 __snd_una;
- u32 __reserved53;
-#if defined(__BIG_ENDIAN)
- u8 __agg_val8_th;
- u8 __agg_val8;
- u16 __tcp_agg_vars2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __tcp_agg_vars2;
- u8 __agg_val8;
- u8 __agg_val8_th;
-#endif
- u32 __reserved58;
- u32 __reserved59;
- u32 __reserved60;
- u32 __reserved61;
-#if defined(__BIG_ENDIAN)
- u16 __agg_val7_th;
- u16 __agg_val7;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val7;
- u16 __agg_val7_th;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __tcp_agg_vars5;
- u8 __tcp_agg_vars4;
- u8 __tcp_agg_vars3;
- u8 __reserved62;
-#elif defined(__LITTLE_ENDIAN)
- u8 __reserved62;
- u8 __tcp_agg_vars3;
- u8 __tcp_agg_vars4;
- u8 __tcp_agg_vars5;
-#endif
- u32 __tcp_agg_vars6;
-#if defined(__BIG_ENDIAN)
- u16 __agg_misc6;
- u16 __tcp_agg_vars7;
-#elif defined(__LITTLE_ENDIAN)
- u16 __tcp_agg_vars7;
- u16 __agg_misc6;
-#endif
- u32 __agg_val10;
- u32 __agg_val10_th;
-#if defined(__BIG_ENDIAN)
- u16 __reserved3;
- u8 __reserved2;
- u8 __da_only_cnt;
-#elif defined(__LITTLE_ENDIAN)
- u8 __da_only_cnt;
- u8 __reserved2;
- u16 __reserved3;
-#endif
-};
-
-/*
* The eth aggregative context of Xstorm
*/
struct xstorm_eth_ag_context {
-#if defined(__BIG_ENDIAN)
- u16 agg_val1;
- u8 __agg_vars1;
- u8 __state;
-#elif defined(__LITTLE_ENDIAN)
- u8 __state;
- u8 __agg_vars1;
- u16 agg_val1;
-#endif
+ u32 reserved0;
#if defined(__BIG_ENDIAN)
u8 cdu_reserved;
- u8 __agg_vars4;
- u8 __agg_vars3;
- u8 __agg_vars2;
+ u8 reserved2;
+ u16 reserved1;
#elif defined(__LITTLE_ENDIAN)
- u8 __agg_vars2;
- u8 __agg_vars3;
- u8 __agg_vars4;
+ u16 reserved1;
+ u8 reserved2;
u8 cdu_reserved;
#endif
- u32 __bd_prod;
-#if defined(__BIG_ENDIAN)
- u16 __agg_vars5;
- u16 __agg_val4_th;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val4_th;
- u16 __agg_vars5;
-#endif
- struct xstorm_eth_extra_ag_context_section __extra_section;
-#if defined(__BIG_ENDIAN)
- u16 __agg_vars7;
- u8 __agg_val3_th;
- u8 __agg_vars6;
-#elif defined(__LITTLE_ENDIAN)
- u8 __agg_vars6;
- u8 __agg_val3_th;
- u16 __agg_vars7;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __agg_val11_th;
- u16 __agg_val11;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val11;
- u16 __agg_val11_th;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __reserved1;
- u8 __agg_val6_th;
- u16 __agg_val9;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val9;
- u8 __agg_val6_th;
- u8 __reserved1;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __agg_val2_th;
- u16 __agg_val2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val2;
- u16 __agg_val2_th;
-#endif
- u32 __agg_vars8;
-#if defined(__BIG_ENDIAN)
- u16 __agg_misc0;
- u16 __agg_val4;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val4;
- u16 __agg_misc0;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __agg_val3;
- u8 __agg_val6;
- u8 __agg_val5_th;
- u8 __agg_val5;
-#elif defined(__LITTLE_ENDIAN)
- u8 __agg_val5;
- u8 __agg_val5_th;
- u8 __agg_val6;
- u8 __agg_val3;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __agg_misc1;
- u16 __bd_ind_max_val;
-#elif defined(__LITTLE_ENDIAN)
- u16 __bd_ind_max_val;
- u16 __agg_misc1;
-#endif
- u32 __reserved57;
- u32 __agg_misc4;
- u32 __agg_misc5;
-};
-
-/*
- * The eth extra aggregative context section of Tstorm
- */
-struct tstorm_eth_extra_ag_context_section {
- u32 __agg_val1;
-#if defined(__BIG_ENDIAN)
- u8 __tcp_agg_vars2;
- u8 __agg_val3;
- u16 __agg_val2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val2;
- u8 __agg_val3;
- u8 __tcp_agg_vars2;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __agg_val5;
- u8 __agg_val6;
- u8 __tcp_agg_vars3;
-#elif defined(__LITTLE_ENDIAN)
- u8 __tcp_agg_vars3;
- u8 __agg_val6;
- u16 __agg_val5;
-#endif
- u32 __reserved63;
- u32 __reserved64;
- u32 __reserved65;
- u32 __reserved66;
- u32 __reserved67;
- u32 __tcp_agg_vars1;
- u32 __reserved61;
- u32 __reserved62;
- u32 __reserved2;
+ u32 reserved3[30];
};
/*
* The eth aggregative context of Tstorm
*/
struct tstorm_eth_ag_context {
-#if defined(__BIG_ENDIAN)
- u16 __reserved54;
- u8 __agg_vars1;
- u8 __state;
-#elif defined(__LITTLE_ENDIAN)
- u8 __state;
- u8 __agg_vars1;
- u16 __reserved54;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __agg_val4;
- u16 __agg_vars2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_vars2;
- u16 __agg_val4;
-#endif
- struct tstorm_eth_extra_ag_context_section __extra_section;
+ u32 __reserved0[14];
};
+
/*
* The eth aggregative context of Cstorm
*/
struct cstorm_eth_ag_context {
- u32 __agg_vars1;
-#if defined(__BIG_ENDIAN)
- u8 __aux1_th;
- u8 __aux1_val;
- u16 __agg_vars2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_vars2;
- u8 __aux1_val;
- u8 __aux1_th;
-#endif
- u32 __num_of_treated_packet;
- u32 __last_packet_treated;
-#if defined(__BIG_ENDIAN)
- u16 __reserved58;
- u16 __reserved57;
-#elif defined(__LITTLE_ENDIAN)
- u16 __reserved57;
- u16 __reserved58;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __reserved62;
- u8 __reserved61;
- u8 __reserved60;
- u8 __reserved59;
-#elif defined(__LITTLE_ENDIAN)
- u8 __reserved59;
- u8 __reserved60;
- u8 __reserved61;
- u8 __reserved62;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __reserved64;
- u16 __reserved63;
-#elif defined(__LITTLE_ENDIAN)
- u16 __reserved63;
- u16 __reserved64;
-#endif
- u32 __reserved65;
-#if defined(__BIG_ENDIAN)
- u16 __agg_vars3;
- u16 __rq_inv_cnt;
-#elif defined(__LITTLE_ENDIAN)
- u16 __rq_inv_cnt;
- u16 __agg_vars3;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __packet_index_th;
- u16 __packet_index;
-#elif defined(__LITTLE_ENDIAN)
- u16 __packet_index;
- u16 __packet_index_th;
-#endif
+ u32 __reserved0[10];
};
+
/*
* The eth aggregative context of Ustorm
*/
struct ustorm_eth_ag_context {
-#if defined(__BIG_ENDIAN)
- u8 __aux_counter_flags;
- u8 __agg_vars2;
- u8 __agg_vars1;
- u8 __state;
-#elif defined(__LITTLE_ENDIAN)
- u8 __state;
- u8 __agg_vars1;
- u8 __agg_vars2;
- u8 __aux_counter_flags;
-#endif
+ u32 __reserved0;
#if defined(__BIG_ENDIAN)
u8 cdu_usage;
- u8 __agg_misc2;
- u16 __agg_misc1;
+ u8 __reserved2;
+ u16 __reserved1;
#elif defined(__LITTLE_ENDIAN)
- u16 __agg_misc1;
- u8 __agg_misc2;
+ u16 __reserved1;
+ u8 __reserved2;
u8 cdu_usage;
#endif
- u32 __agg_misc4;
-#if defined(__BIG_ENDIAN)
- u8 __agg_val3_th;
- u8 __agg_val3;
- u16 __agg_misc3;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_misc3;
- u8 __agg_val3;
- u8 __agg_val3_th;
-#endif
- u32 __agg_val1;
- u32 __agg_misc4_th;
-#if defined(__BIG_ENDIAN)
- u16 __agg_val2_th;
- u16 __agg_val2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val2;
- u16 __agg_val2_th;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __reserved2;
- u8 __decision_rules;
- u8 __decision_rule_enable_bits;
-#elif defined(__LITTLE_ENDIAN)
- u8 __decision_rule_enable_bits;
- u8 __decision_rules;
- u16 __reserved2;
-#endif
+ u32 __reserved3[6];
};
/*
@@ -2022,18 +1999,16 @@ struct timers_block_context {
*/
struct eth_tx_bd_flags {
u8 as_bitfield;
-#define ETH_TX_BD_FLAGS_VLAN_TAG (0x1<<0)
-#define ETH_TX_BD_FLAGS_VLAN_TAG_SHIFT 0
-#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<1)
-#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 1
-#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<2)
-#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 2
-#define ETH_TX_BD_FLAGS_END_BD (0x1<<3)
-#define ETH_TX_BD_FLAGS_END_BD_SHIFT 3
+#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<0)
+#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 0
+#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<1)
+#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 1
+#define ETH_TX_BD_FLAGS_VLAN_MODE (0x3<<2)
+#define ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT 2
#define ETH_TX_BD_FLAGS_START_BD (0x1<<4)
#define ETH_TX_BD_FLAGS_START_BD_SHIFT 4
-#define ETH_TX_BD_FLAGS_HDR_POOL (0x1<<5)
-#define ETH_TX_BD_FLAGS_HDR_POOL_SHIFT 5
+#define ETH_TX_BD_FLAGS_IS_UDP (0x1<<5)
+#define ETH_TX_BD_FLAGS_IS_UDP_SHIFT 5
#define ETH_TX_BD_FLAGS_SW_LSO (0x1<<6)
#define ETH_TX_BD_FLAGS_SW_LSO_SHIFT 6
#define ETH_TX_BD_FLAGS_IPV6 (0x1<<7)
@@ -2048,7 +2023,7 @@ struct eth_tx_start_bd {
__le32 addr_hi;
__le16 nbd;
__le16 nbytes;
- __le16 vlan;
+ __le16 vlan_or_ethertype;
struct eth_tx_bd_flags bd_flags;
u8 general_data;
#define ETH_TX_START_BD_HDR_NBDS (0x3F<<0)
@@ -2061,48 +2036,48 @@ struct eth_tx_start_bd {
* Tx regular BD structure
*/
struct eth_tx_bd {
- u32 addr_lo;
- u32 addr_hi;
- u16 total_pkt_bytes;
- u16 nbytes;
+ __le32 addr_lo;
+ __le32 addr_hi;
+ __le16 total_pkt_bytes;
+ __le16 nbytes;
u8 reserved[4];
};
/*
- * Tx parsing BD structure for ETH,Relevant in START
+ * Tx parsing BD structure for ETH E1/E1h
*/
-struct eth_tx_parse_bd {
+struct eth_tx_parse_bd_e1x {
u8 global_data;
-#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET (0xF<<0)
-#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET_SHIFT 0
-#define ETH_TX_PARSE_BD_UDP_CS_FLG (0x1<<4)
-#define ETH_TX_PARSE_BD_UDP_CS_FLG_SHIFT 4
-#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN (0x1<<5)
-#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN_SHIFT 5
-#define ETH_TX_PARSE_BD_LLC_SNAP_EN (0x1<<6)
-#define ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT 6
-#define ETH_TX_PARSE_BD_NS_FLG (0x1<<7)
-#define ETH_TX_PARSE_BD_NS_FLG_SHIFT 7
+#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W (0xF<<0)
+#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W_SHIFT 0
+#define ETH_TX_PARSE_BD_E1X_RESERVED0 (0x1<<4)
+#define ETH_TX_PARSE_BD_E1X_RESERVED0_SHIFT 4
+#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN (0x1<<5)
+#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN_SHIFT 5
+#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN (0x1<<6)
+#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT 6
+#define ETH_TX_PARSE_BD_E1X_NS_FLG (0x1<<7)
+#define ETH_TX_PARSE_BD_E1X_NS_FLG_SHIFT 7
u8 tcp_flags;
-#define ETH_TX_PARSE_BD_FIN_FLG (0x1<<0)
-#define ETH_TX_PARSE_BD_FIN_FLG_SHIFT 0
-#define ETH_TX_PARSE_BD_SYN_FLG (0x1<<1)
-#define ETH_TX_PARSE_BD_SYN_FLG_SHIFT 1
-#define ETH_TX_PARSE_BD_RST_FLG (0x1<<2)
-#define ETH_TX_PARSE_BD_RST_FLG_SHIFT 2
-#define ETH_TX_PARSE_BD_PSH_FLG (0x1<<3)
-#define ETH_TX_PARSE_BD_PSH_FLG_SHIFT 3
-#define ETH_TX_PARSE_BD_ACK_FLG (0x1<<4)
-#define ETH_TX_PARSE_BD_ACK_FLG_SHIFT 4
-#define ETH_TX_PARSE_BD_URG_FLG (0x1<<5)
-#define ETH_TX_PARSE_BD_URG_FLG_SHIFT 5
-#define ETH_TX_PARSE_BD_ECE_FLG (0x1<<6)
-#define ETH_TX_PARSE_BD_ECE_FLG_SHIFT 6
-#define ETH_TX_PARSE_BD_CWR_FLG (0x1<<7)
-#define ETH_TX_PARSE_BD_CWR_FLG_SHIFT 7
- u8 ip_hlen;
+#define ETH_TX_PARSE_BD_E1X_FIN_FLG (0x1<<0)
+#define ETH_TX_PARSE_BD_E1X_FIN_FLG_SHIFT 0
+#define ETH_TX_PARSE_BD_E1X_SYN_FLG (0x1<<1)
+#define ETH_TX_PARSE_BD_E1X_SYN_FLG_SHIFT 1
+#define ETH_TX_PARSE_BD_E1X_RST_FLG (0x1<<2)
+#define ETH_TX_PARSE_BD_E1X_RST_FLG_SHIFT 2
+#define ETH_TX_PARSE_BD_E1X_PSH_FLG (0x1<<3)
+#define ETH_TX_PARSE_BD_E1X_PSH_FLG_SHIFT 3
+#define ETH_TX_PARSE_BD_E1X_ACK_FLG (0x1<<4)
+#define ETH_TX_PARSE_BD_E1X_ACK_FLG_SHIFT 4
+#define ETH_TX_PARSE_BD_E1X_URG_FLG (0x1<<5)
+#define ETH_TX_PARSE_BD_E1X_URG_FLG_SHIFT 5
+#define ETH_TX_PARSE_BD_E1X_ECE_FLG (0x1<<6)
+#define ETH_TX_PARSE_BD_E1X_ECE_FLG_SHIFT 6
+#define ETH_TX_PARSE_BD_E1X_CWR_FLG (0x1<<7)
+#define ETH_TX_PARSE_BD_E1X_CWR_FLG_SHIFT 7
+ u8 ip_hlen_w;
s8 reserved;
- __le16 total_hlen;
+ __le16 total_hlen_w;
__le16 tcp_pseudo_csum;
__le16 lso_mss;
__le16 ip_id;
@@ -2110,6 +2085,27 @@ struct eth_tx_parse_bd {
};
/*
+ * Tx parsing BD structure for ETH E2
+ */
+struct eth_tx_parse_bd_e2 {
+ __le16 dst_mac_addr_lo;
+ __le16 dst_mac_addr_mid;
+ __le16 dst_mac_addr_hi;
+ __le16 src_mac_addr_lo;
+ __le16 src_mac_addr_mid;
+ __le16 src_mac_addr_hi;
+ __le32 parsing_data;
+#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W (0x1FFF<<0)
+#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT 0
+#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW (0xF<<13)
+#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT 13
+#define ETH_TX_PARSE_BD_E2_LSO_MSS (0x3FFF<<17)
+#define ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT 17
+#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR (0x1<<31)
+#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR_SHIFT 31
+};
+
+/*
* The last BD in the BD memory will hold a pointer to the next BD memory
*/
struct eth_tx_next_bd {
@@ -2124,79 +2120,24 @@ struct eth_tx_next_bd {
union eth_tx_bd_types {
struct eth_tx_start_bd start_bd;
struct eth_tx_bd reg_bd;
- struct eth_tx_parse_bd parse_bd;
+ struct eth_tx_parse_bd_e1x parse_bd_e1x;
+ struct eth_tx_parse_bd_e2 parse_bd_e2;
struct eth_tx_next_bd next_bd;
};
+
/*
* The eth storm context of Xstorm
*/
struct xstorm_eth_st_context {
- u32 tx_bd_page_base_lo;
- u32 tx_bd_page_base_hi;
-#if defined(__BIG_ENDIAN)
- u16 tx_bd_cons;
- u8 statistics_data;
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0)
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7)
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7
- u8 __local_tx_bd_prod;
-#elif defined(__LITTLE_ENDIAN)
- u8 __local_tx_bd_prod;
- u8 statistics_data;
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0)
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7)
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7
- u16 tx_bd_cons;
-#endif
- u32 __reserved1;
- u32 __reserved2;
-#if defined(__BIG_ENDIAN)
- u8 __ram_cache_index;
- u8 __double_buffer_client;
- u16 __pkt_cons;
-#elif defined(__LITTLE_ENDIAN)
- u16 __pkt_cons;
- u8 __double_buffer_client;
- u8 __ram_cache_index;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __statistics_address;
- u16 __gso_next;
-#elif defined(__LITTLE_ENDIAN)
- u16 __gso_next;
- u16 __statistics_address;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __local_tx_bd_cons;
- u8 safc_group_num;
- u8 safc_group_en;
- u8 __is_eth_conn;
-#elif defined(__LITTLE_ENDIAN)
- u8 __is_eth_conn;
- u8 safc_group_en;
- u8 safc_group_num;
- u8 __local_tx_bd_cons;
-#endif
- union eth_tx_bd_types __bds[13];
+ u32 reserved0[60];
};
/*
* The eth storm context of Cstorm
*/
struct cstorm_eth_st_context {
-#if defined(__BIG_ENDIAN)
- u16 __reserved0;
- u8 sb_index_number;
- u8 status_block_id;
-#elif defined(__LITTLE_ENDIAN)
- u8 status_block_id;
- u8 sb_index_number;
- u16 __reserved0;
-#endif
- u32 __reserved1[3];
+ u32 __reserved0[4];
};
/*
@@ -2244,103 +2185,114 @@ struct eth_tx_doorbell {
/*
- * cstorm default status block, generated by ustorm
- */
-struct cstorm_def_status_block_u {
- __le16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
- __le16 status_block_index;
- u8 func;
- u8 status_block_id;
- __le32 __flags;
-};
-
-/*
- * cstorm default status block, generated by cstorm
- */
-struct cstorm_def_status_block_c {
- __le16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
- __le16 status_block_index;
- u8 func;
- u8 status_block_id;
- __le32 __flags;
-};
-
-/*
- * xstorm status block
+ * client init fc data
*/
-struct xstorm_def_status_block {
- __le16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES];
- __le16 status_block_index;
- u8 func;
- u8 status_block_id;
- __le32 __flags;
+struct client_init_fc_data {
+ __le16 cqe_pause_thr_low;
+ __le16 cqe_pause_thr_high;
+ __le16 bd_pause_thr_low;
+ __le16 bd_pause_thr_high;
+ __le16 sge_pause_thr_low;
+ __le16 sge_pause_thr_high;
+ __le16 rx_cos_mask;
+ u8 safc_group_num;
+ u8 safc_group_en_flg;
+ u8 traffic_type;
+ u8 reserved0;
+ __le16 reserved1;
+ __le32 reserved2;
};
-/*
- * tstorm status block
- */
-struct tstorm_def_status_block {
- __le16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES];
- __le16 status_block_index;
- u8 func;
- u8 status_block_id;
- __le32 __flags;
-};
/*
- * host status block
+ * client init ramrod data
*/
-struct host_def_status_block {
- struct atten_def_status_block atten_status_block;
- struct cstorm_def_status_block_u u_def_status_block;
- struct cstorm_def_status_block_c c_def_status_block;
- struct xstorm_def_status_block x_def_status_block;
- struct tstorm_def_status_block t_def_status_block;
+struct client_init_general_data {
+ u8 client_id;
+ u8 statistics_counter_id;
+ u8 statistics_en_flg;
+ u8 is_fcoe_flg;
+ u8 activate_flg;
+ u8 sp_client_id;
+ __le16 reserved0;
+ __le32 reserved1[2];
};
/*
- * cstorm status block, generated by ustorm
+ * client init rx data
*/
-struct cstorm_status_block_u {
- __le16 index_values[HC_USTORM_SB_NUM_INDICES];
- __le16 status_block_index;
- u8 func;
+struct client_init_rx_data {
+ u8 tpa_en_flg;
+ u8 vmqueue_mode_en_flg;
+ u8 extra_data_over_sgl_en_flg;
+ u8 cache_line_alignment_log_size;
+ u8 enable_dynamic_hc;
+ u8 max_sges_for_packet;
+ u8 client_qzone_id;
+ u8 drop_ip_cs_err_flg;
+ u8 drop_tcp_cs_err_flg;
+ u8 drop_ttl0_flg;
+ u8 drop_udp_cs_err_flg;
+ u8 inner_vlan_removal_enable_flg;
+ u8 outer_vlan_removal_enable_flg;
u8 status_block_id;
- __le32 __flags;
+ u8 rx_sb_index_number;
+ u8 reserved0[3];
+ __le16 bd_buff_size;
+ __le16 sge_buff_size;
+ __le16 mtu;
+ struct regpair bd_page_base;
+ struct regpair sge_page_base;
+ struct regpair cqe_page_base;
+ u8 is_leading_rss;
+ u8 is_approx_mcast;
+ __le16 max_agg_size;
+ __le32 reserved2[3];
+};
+
+/*
+ * client init tx data
+ */
+struct client_init_tx_data {
+ u8 enforce_security_flg;
+ u8 tx_status_block_id;
+ u8 tx_sb_index_number;
+ u8 reserved0;
+ __le16 mtu;
+ __le16 reserved1;
+ struct regpair tx_bd_page_base;
+ __le32 reserved2[2];
};
/*
- * cstorm status block, generated by cstorm
+ * client init ramrod data
*/
-struct cstorm_status_block_c {
- __le16 index_values[HC_CSTORM_SB_NUM_INDICES];
- __le16 status_block_index;
- u8 func;
- u8 status_block_id;
- __le32 __flags;
+struct client_init_ramrod_data {
+ struct client_init_general_data general;
+ struct client_init_rx_data rx;
+ struct client_init_tx_data tx;
+ struct client_init_fc_data fc;
};
+
/*
- * host status block
+ * The data contain client ID need to the ramrod
*/
-struct host_status_block {
- struct cstorm_status_block_u u_status_block;
- struct cstorm_status_block_c c_status_block;
+struct eth_common_ramrod_data {
+ u32 client_id;
+ u32 reserved1;
};
/*
- * The data for RSS setup ramrod
+ * union for sgl and raw data.
*/
-struct eth_client_setup_ramrod_data {
- u32 client_id;
- u8 is_rdma;
- u8 is_fcoe;
- u16 reserved1;
+union eth_sgl_or_raw_data {
+ __le16 sgl[8];
+ u32 raw_data[4];
};
-
/*
* regular eth FP CQE parameters struct
*/
@@ -2358,8 +2310,8 @@ struct eth_fast_path_rx_cqe {
#define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 4
#define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<5)
#define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 5
-#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x3<<6)
-#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 6
+#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL (0x3<<6)
+#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL_SHIFT 6
u8 status_flags;
#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0)
#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0
@@ -2380,7 +2332,7 @@ struct eth_fast_path_rx_cqe {
__le16 pkt_len;
__le16 len_on_bd;
struct parsing_flags pars_flags;
- __le16 sgl[8];
+ union eth_sgl_or_raw_data sgl_or_raw_data;
};
@@ -2392,11 +2344,10 @@ struct eth_halt_ramrod_data {
u32 reserved0;
};
-
/*
* The data for statistics query ramrod
*/
-struct eth_query_ramrod_data {
+struct common_query_ramrod_data {
#if defined(__BIG_ENDIAN)
u8 reserved0;
u8 collect_port;
@@ -2479,9 +2430,9 @@ struct spe_hdr {
__le16 type;
#define SPE_HDR_CONN_TYPE (0xFF<<0)
#define SPE_HDR_CONN_TYPE_SHIFT 0
-#define SPE_HDR_COMMON_RAMROD (0xFF<<8)
-#define SPE_HDR_COMMON_RAMROD_SHIFT 8
- __le16 reserved;
+#define SPE_HDR_FUNCTION_ID (0xFF<<8)
+#define SPE_HDR_FUNCTION_ID_SHIFT 8
+ __le16 reserved1;
};
/*
@@ -2489,12 +2440,10 @@ struct spe_hdr {
*/
union eth_specific_data {
u8 protocol_data[8];
- struct regpair mac_config_addr;
- struct eth_client_setup_ramrod_data client_setup_ramrod_data;
+ struct regpair client_init_ramrod_init_data;
struct eth_halt_ramrod_data halt_ramrod_data;
- struct regpair leading_cqe_addr;
struct regpair update_data_addr;
- struct eth_query_ramrod_data query_ramrod_data;
+ struct eth_common_ramrod_data common_ramrod_data;
};
/*
@@ -2519,7 +2468,7 @@ struct eth_tx_bds_array {
*/
struct tstorm_eth_function_common_config {
#if defined(__BIG_ENDIAN)
- u8 leading_client_id;
+ u8 reserved1;
u8 rss_result_mask;
u16 config_flags;
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
@@ -2532,16 +2481,12 @@ struct tstorm_eth_function_common_config {
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4)
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<10)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 10
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1F<<11)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 11
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<7)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<8)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 8
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x7F<<9)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 9
#elif defined(__LITTLE_ENDIAN)
u16 config_flags;
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
@@ -2554,18 +2499,14 @@ struct tstorm_eth_function_common_config {
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4)
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<10)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 10
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1F<<11)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 11
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<7)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<8)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 8
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x7F<<9)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 9
u8 rss_result_mask;
- u8 leading_client_id;
+ u8 reserved1;
#endif
u16 vlan_id[2];
};
@@ -2613,90 +2554,42 @@ struct mac_configuration_hdr {
u8 length;
u8 offset;
u16 client_id;
- u32 reserved1;
-};
-
-/*
- * MAC address in list for ramrod
- */
-struct tstorm_cam_entry {
- __le16 lsb_mac_addr;
- __le16 middle_mac_addr;
- __le16 msb_mac_addr;
- __le16 flags;
-#define TSTORM_CAM_ENTRY_PORT_ID (0x1<<0)
-#define TSTORM_CAM_ENTRY_PORT_ID_SHIFT 0
-#define TSTORM_CAM_ENTRY_RSRVVAL0 (0x7<<1)
-#define TSTORM_CAM_ENTRY_RSRVVAL0_SHIFT 1
-#define TSTORM_CAM_ENTRY_RESERVED0 (0xFFF<<4)
-#define TSTORM_CAM_ENTRY_RESERVED0_SHIFT 4
-};
-
-/*
- * MAC filtering: CAM target table entry
- */
-struct tstorm_cam_target_table_entry {
- u8 flags;
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST (0x1<<0)
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST_SHIFT 0
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL (0x1<<1)
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL_SHIFT 1
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE (0x1<<2)
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE_SHIFT 2
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC (0x1<<3)
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC_SHIFT 3
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0 (0xF<<4)
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0_SHIFT 4
- u8 reserved1;
- u16 vlan_id;
- u32 clients_bit_vector;
+ u16 echo;
+ u16 reserved1;
};
/*
* MAC address in list for ramrod
*/
struct mac_configuration_entry {
- struct tstorm_cam_entry cam_entry;
- struct tstorm_cam_target_table_entry target_table_entry;
-};
-
-/*
- * MAC filtering configuration command
- */
-struct mac_configuration_cmd {
- struct mac_configuration_hdr hdr;
- struct mac_configuration_entry config_table[64];
-};
-
-
-/*
- * MAC address in list for ramrod
- */
-struct mac_configuration_entry_e1h {
__le16 lsb_mac_addr;
__le16 middle_mac_addr;
__le16 msb_mac_addr;
__le16 vlan_id;
- __le16 e1hov_id;
- u8 reserved0;
+ u8 pf_id;
u8 flags;
-#define MAC_CONFIGURATION_ENTRY_E1H_PORT (0x1<<0)
-#define MAC_CONFIGURATION_ENTRY_E1H_PORT_SHIFT 0
-#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE (0x1<<1)
-#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE_SHIFT 1
-#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC (0x1<<2)
-#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC_SHIFT 2
-#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED1 (0x1F<<3)
-#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED1_SHIFT 3
+#define MAC_CONFIGURATION_ENTRY_ACTION_TYPE (0x1<<0)
+#define MAC_CONFIGURATION_ENTRY_ACTION_TYPE_SHIFT 0
+#define MAC_CONFIGURATION_ENTRY_RDMA_MAC (0x1<<1)
+#define MAC_CONFIGURATION_ENTRY_RDMA_MAC_SHIFT 1
+#define MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE (0x3<<2)
+#define MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE_SHIFT 2
+#define MAC_CONFIGURATION_ENTRY_OVERRIDE_VLAN_REMOVAL (0x1<<4)
+#define MAC_CONFIGURATION_ENTRY_OVERRIDE_VLAN_REMOVAL_SHIFT 4
+#define MAC_CONFIGURATION_ENTRY_BROADCAST (0x1<<5)
+#define MAC_CONFIGURATION_ENTRY_BROADCAST_SHIFT 5
+#define MAC_CONFIGURATION_ENTRY_RESERVED1 (0x3<<6)
+#define MAC_CONFIGURATION_ENTRY_RESERVED1_SHIFT 6
+ u16 reserved0;
u32 clients_bit_vector;
};
/*
* MAC filtering configuration command
*/
-struct mac_configuration_cmd_e1h {
+struct mac_configuration_cmd {
struct mac_configuration_hdr hdr;
- struct mac_configuration_entry_e1h config_table[32];
+ struct mac_configuration_entry config_table[64];
};
@@ -2709,65 +2602,6 @@ struct tstorm_eth_approximate_match_multicast_filtering {
/*
- * Configuration parameters per client in Tstorm
- */
-struct tstorm_eth_client_config {
-#if defined(__BIG_ENDIAN)
- u8 reserved0;
- u8 statistics_counter_id;
- u16 mtu;
-#elif defined(__LITTLE_ENDIAN)
- u16 mtu;
- u8 statistics_counter_id;
- u8 reserved0;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 drop_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2 (0xFFF<<4)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2_SHIFT 4
- u16 config_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x1FFF<<3)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 3
-#elif defined(__LITTLE_ENDIAN)
- u16 config_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x1FFF<<3)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 3
- u16 drop_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2 (0xFFF<<4)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2_SHIFT 4
-#endif
-};
-
-
-/*
* MAC filtering configuration parameters per port in Tstorm
*/
struct tstorm_eth_mac_filter_config {
@@ -2777,8 +2611,8 @@ struct tstorm_eth_mac_filter_config {
u32 mcast_accept_all;
u32 bcast_drop_all;
u32 bcast_accept_all;
- u32 strict_vlan;
u32 vlan_filter[2];
+ u32 unmatched_unicast;
u32 reserved;
};
@@ -2801,41 +2635,6 @@ struct tstorm_eth_tpa_exist {
/*
- * rx rings pause data for E1h only
- */
-struct ustorm_eth_rx_pause_data_e1h {
-#if defined(__BIG_ENDIAN)
- u16 bd_thr_low;
- u16 cqe_thr_low;
-#elif defined(__LITTLE_ENDIAN)
- u16 cqe_thr_low;
- u16 bd_thr_low;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 cos;
- u16 sge_thr_low;
-#elif defined(__LITTLE_ENDIAN)
- u16 sge_thr_low;
- u16 cos;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 bd_thr_high;
- u16 cqe_thr_high;
-#elif defined(__LITTLE_ENDIAN)
- u16 cqe_thr_high;
- u16 bd_thr_high;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 reserved0;
- u16 sge_thr_high;
-#elif defined(__LITTLE_ENDIAN)
- u16 sge_thr_high;
- u16 reserved0;
-#endif
-};
-
-
-/*
* Three RX producers for ETH
*/
struct ustorm_eth_rx_producers {
@@ -2857,6 +2656,18 @@ struct ustorm_eth_rx_producers {
/*
+ * cfc delete event data
+ */
+struct cfc_del_event_data {
+ u32 cid;
+ u8 error;
+ u8 reserved0;
+ u16 reserved1;
+ u32 reserved2;
+};
+
+
+/*
* per-port SAFC demo variables
*/
struct cmng_flags_per_port {
@@ -2872,8 +2683,10 @@ struct cmng_flags_per_port {
#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL_SHIFT 3
#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS (0x1<<4)
#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_SHIFT 4
-#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x7FFFFFF<<5)
-#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 5
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE (0x1<<5)
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE_SHIFT 5
+#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x3FFFFFF<<6)
+#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 6
};
@@ -2907,30 +2720,92 @@ struct safc_struct_per_port {
u8 __reserved0;
u16 __reserved1;
#endif
+ u8 cos_to_traffic_types[MAX_COS_NUMBER];
+ u32 __reserved2;
u16 cos_to_pause_mask[NUM_OF_SAFC_BITS];
};
/*
+ * per-port PFC variables
+ */
+struct pfc_struct_per_port {
+ u8 priority_to_traffic_types[MAX_PFC_PRIORITIES];
+#if defined(__BIG_ENDIAN)
+ u16 pfc_pause_quanta_in_nanosec;
+ u8 __reserved0;
+ u8 priority_non_pausable_mask;
+#elif defined(__LITTLE_ENDIAN)
+ u8 priority_non_pausable_mask;
+ u8 __reserved0;
+ u16 pfc_pause_quanta_in_nanosec;
+#endif
+};
+
+/*
+ * Priority and cos
+ */
+struct priority_cos {
+#if defined(__BIG_ENDIAN)
+ u16 reserved1;
+ u8 cos;
+ u8 priority;
+#elif defined(__LITTLE_ENDIAN)
+ u8 priority;
+ u8 cos;
+ u16 reserved1;
+#endif
+ u32 reserved2;
+};
+
+/*
* Per-port congestion management variables
*/
struct cmng_struct_per_port {
struct rate_shaping_vars_per_port rs_vars;
struct fairness_vars_per_port fair_vars;
struct safc_struct_per_port safc_vars;
+ struct pfc_struct_per_port pfc_vars;
+#if defined(__BIG_ENDIAN)
+ u16 __reserved1;
+ u8 dcb_enabled;
+ u8 llfc_mode;
+#elif defined(__LITTLE_ENDIAN)
+ u8 llfc_mode;
+ u8 dcb_enabled;
+ u16 __reserved1;
+#endif
+ struct priority_cos
+ traffic_type_to_priority_cos[MAX_PFC_TRAFFIC_TYPES];
struct cmng_flags_per_port flags;
};
+
+/*
+ * Dynamic HC counters set by the driver
+ */
+struct hc_dynamic_drv_counter {
+ u32 val[HC_SB_MAX_DYNAMIC_INDICES];
+};
+
+/*
+ * zone A per-queue data
+ */
+struct cstorm_queue_zone_data {
+ struct hc_dynamic_drv_counter hc_dyn_drv_cnt;
+ struct regpair reserved[2];
+};
+
/*
* Dynamic host coalescing init parameters
*/
struct dynamic_hc_config {
u32 threshold[3];
- u8 shift_per_protocol[HC_USTORM_SB_NUM_INDICES];
- u8 hc_timeout0[HC_USTORM_SB_NUM_INDICES];
- u8 hc_timeout1[HC_USTORM_SB_NUM_INDICES];
- u8 hc_timeout2[HC_USTORM_SB_NUM_INDICES];
- u8 hc_timeout3[HC_USTORM_SB_NUM_INDICES];
+ u8 shift_per_protocol[HC_SB_MAX_DYNAMIC_INDICES];
+ u8 hc_timeout0[HC_SB_MAX_DYNAMIC_INDICES];
+ u8 hc_timeout1[HC_SB_MAX_DYNAMIC_INDICES];
+ u8 hc_timeout2[HC_SB_MAX_DYNAMIC_INDICES];
+ u8 hc_timeout3[HC_SB_MAX_DYNAMIC_INDICES];
};
@@ -2954,7 +2829,7 @@ struct xstorm_per_client_stats {
* Common statistics collected by the Xstorm (per port)
*/
struct xstorm_common_stats {
- struct xstorm_per_client_stats client_statistics[MAX_X_STAT_COUNTER_ID];
+ struct xstorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID];
};
/*
@@ -2991,7 +2866,7 @@ struct tstorm_per_client_stats {
*/
struct tstorm_common_stats {
struct tstorm_per_port_stats port_statistics;
- struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID];
+ struct tstorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID];
};
/*
@@ -3012,7 +2887,7 @@ struct ustorm_per_client_stats {
* Protocol-common statistics collected by the Ustorm
*/
struct ustorm_common_stats {
- struct ustorm_per_client_stats client_statistics[MAX_U_STAT_COUNTER_ID];
+ struct ustorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID];
};
/*
@@ -3026,6 +2901,70 @@ struct eth_stats_query {
/*
+ * set mac event data
+ */
+struct set_mac_event_data {
+ u16 echo;
+ u16 reserved0;
+ u32 reserved1;
+ u32 reserved2;
+};
+
+/*
+ * union for all event ring message types
+ */
+union event_data {
+ struct set_mac_event_data set_mac_event;
+ struct cfc_del_event_data cfc_del_event;
+};
+
+
+/*
+ * per PF event ring data
+ */
+struct event_ring_data {
+ struct regpair base_addr;
+#if defined(__BIG_ENDIAN)
+ u8 index_id;
+ u8 sb_id;
+ u16 producer;
+#elif defined(__LITTLE_ENDIAN)
+ u16 producer;
+ u8 sb_id;
+ u8 index_id;
+#endif
+ u32 reserved0;
+};
+
+
+/*
+ * event ring message element (each element is 128 bits)
+ */
+struct event_ring_msg {
+ u8 opcode;
+ u8 reserved0;
+ u16 reserved1;
+ union event_data data;
+};
+
+/*
+ * event ring next page element (128 bits)
+ */
+struct event_ring_next {
+ struct regpair addr;
+ u32 reserved[2];
+};
+
+/*
+ * union for event ring element types (each element is 128 bits)
+ */
+union event_ring_elem {
+ struct event_ring_msg message;
+ struct event_ring_next next_page;
+};
+
+
+/*
* per-vnic fairness variables
*/
struct fairness_vars_per_vn {
@@ -3064,6 +3003,137 @@ struct fw_version {
/*
+ * Dynamic Host-Coalescing - Driver(host) counters
+ */
+struct hc_dynamic_sb_drv_counters {
+ u32 dynamic_hc_drv_counter[HC_SB_MAX_DYNAMIC_INDICES];
+};
+
+
+/*
+ * 2 bytes. configuration/state parameters for a single protocol index
+ */
+struct hc_index_data {
+#if defined(__BIG_ENDIAN)
+ u8 flags;
+#define HC_INDEX_DATA_SM_ID (0x1<<0)
+#define HC_INDEX_DATA_SM_ID_SHIFT 0
+#define HC_INDEX_DATA_HC_ENABLED (0x1<<1)
+#define HC_INDEX_DATA_HC_ENABLED_SHIFT 1
+#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED (0x1<<2)
+#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED_SHIFT 2
+#define HC_INDEX_DATA_RESERVE (0x1F<<3)
+#define HC_INDEX_DATA_RESERVE_SHIFT 3
+ u8 timeout;
+#elif defined(__LITTLE_ENDIAN)
+ u8 timeout;
+ u8 flags;
+#define HC_INDEX_DATA_SM_ID (0x1<<0)
+#define HC_INDEX_DATA_SM_ID_SHIFT 0
+#define HC_INDEX_DATA_HC_ENABLED (0x1<<1)
+#define HC_INDEX_DATA_HC_ENABLED_SHIFT 1
+#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED (0x1<<2)
+#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED_SHIFT 2
+#define HC_INDEX_DATA_RESERVE (0x1F<<3)
+#define HC_INDEX_DATA_RESERVE_SHIFT 3
+#endif
+};
+
+
+/*
+ * HC state-machine
+ */
+struct hc_status_block_sm {
+#if defined(__BIG_ENDIAN)
+ u8 igu_seg_id;
+ u8 igu_sb_id;
+ u8 timer_value;
+ u8 __flags;
+#elif defined(__LITTLE_ENDIAN)
+ u8 __flags;
+ u8 timer_value;
+ u8 igu_sb_id;
+ u8 igu_seg_id;
+#endif
+ u32 time_to_expire;
+};
+
+/*
+ * hold PCI identification variables- used in various places in firmware
+ */
+struct pci_entity {
+#if defined(__BIG_ENDIAN)
+ u8 vf_valid;
+ u8 vf_id;
+ u8 vnic_id;
+ u8 pf_id;
+#elif defined(__LITTLE_ENDIAN)
+ u8 pf_id;
+ u8 vnic_id;
+ u8 vf_id;
+ u8 vf_valid;
+#endif
+};
+
+/*
+ * The fast-path status block meta-data, common to all chips
+ */
+struct hc_sb_data {
+ struct regpair host_sb_addr;
+ struct hc_status_block_sm state_machine[HC_SB_MAX_SM];
+ struct pci_entity p_func;
+#if defined(__BIG_ENDIAN)
+ u8 rsrv0;
+ u8 dhc_qzone_id;
+ u8 __dynamic_hc_level;
+ u8 same_igu_sb_1b;
+#elif defined(__LITTLE_ENDIAN)
+ u8 same_igu_sb_1b;
+ u8 __dynamic_hc_level;
+ u8 dhc_qzone_id;
+ u8 rsrv0;
+#endif
+ struct regpair rsrv1[2];
+};
+
+
+/*
+ * The fast-path status block meta-data
+ */
+struct hc_sp_status_block_data {
+ struct regpair host_sb_addr;
+#if defined(__BIG_ENDIAN)
+ u16 rsrv;
+ u8 igu_seg_id;
+ u8 igu_sb_id;
+#elif defined(__LITTLE_ENDIAN)
+ u8 igu_sb_id;
+ u8 igu_seg_id;
+ u16 rsrv;
+#endif
+ struct pci_entity p_func;
+};
+
+
+/*
+ * The fast-path status block meta-data
+ */
+struct hc_status_block_data_e1x {
+ struct hc_index_data index_data[HC_SB_MAX_INDICES_E1X];
+ struct hc_sb_data common;
+};
+
+
+/*
+ * The fast-path status block meta-data
+ */
+struct hc_status_block_data_e2 {
+ struct hc_index_data index_data[HC_SB_MAX_INDICES_E2];
+ struct hc_sb_data common;
+};
+
+
+/*
* FW version stored in first line of pram
*/
struct pram_fw_version {
@@ -3086,11 +3156,21 @@ struct pram_fw_version {
/*
+ * Ethernet slow path element
+ */
+union protocol_common_specific_data {
+ u8 protocol_data[8];
+ struct regpair phy_address;
+ struct regpair mac_config_addr;
+ struct common_query_ramrod_data query_ramrod_data;
+};
+
+/*
* The send queue element
*/
struct protocol_common_spe {
struct spe_hdr hdr;
- struct regpair phy_address;
+ union protocol_common_specific_data data;
};
@@ -3123,7 +3203,7 @@ struct rate_shaping_vars_per_vn {
*/
struct slow_path_element {
struct spe_hdr hdr;
- u8 protocol_data[8];
+ struct regpair protocol_data;
};
@@ -3136,3 +3216,97 @@ struct stats_indication_flags {
};
+/*
+ * per-port PFC variables
+ */
+struct storm_pfc_struct_per_port {
+#if defined(__BIG_ENDIAN)
+ u16 mid_mac_addr;
+ u16 msb_mac_addr;
+#elif defined(__LITTLE_ENDIAN)
+ u16 msb_mac_addr;
+ u16 mid_mac_addr;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 pfc_pause_quanta_in_nanosec;
+ u16 lsb_mac_addr;
+#elif defined(__LITTLE_ENDIAN)
+ u16 lsb_mac_addr;
+ u16 pfc_pause_quanta_in_nanosec;
+#endif
+};
+
+/*
+ * Per-port congestion management variables
+ */
+struct storm_cmng_struct_per_port {
+ struct storm_pfc_struct_per_port pfc_vars;
+};
+
+
+/*
+ * zone A per-queue data
+ */
+struct tstorm_queue_zone_data {
+ struct regpair reserved[4];
+};
+
+
+/*
+ * zone B per-VF data
+ */
+struct tstorm_vf_zone_data {
+ struct regpair reserved;
+};
+
+
+/*
+ * zone A per-queue data
+ */
+struct ustorm_queue_zone_data {
+ struct ustorm_eth_rx_producers eth_rx_producers;
+ struct regpair reserved[3];
+};
+
+
+/*
+ * zone B per-VF data
+ */
+struct ustorm_vf_zone_data {
+ struct regpair reserved;
+};
+
+
+/*
+ * data per VF-PF channel
+ */
+struct vf_pf_channel_data {
+#if defined(__BIG_ENDIAN)
+ u16 reserved0;
+ u8 valid;
+ u8 state;
+#elif defined(__LITTLE_ENDIAN)
+ u8 state;
+ u8 valid;
+ u16 reserved0;
+#endif
+ u32 reserved1;
+};
+
+
+/*
+ * zone A per-queue data
+ */
+struct xstorm_queue_zone_data {
+ struct regpair reserved[4];
+};
+
+
+/*
+ * zone B per-VF data
+ */
+struct xstorm_vf_zone_data {
+ struct regpair reserved;
+};
+
+#endif /* BNX2X_HSI_H */
diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h
index 65b26cbfe3e7..a9d54874a559 100644
--- a/drivers/net/bnx2x/bnx2x_init.h
+++ b/drivers/net/bnx2x/bnx2x_init.h
@@ -97,6 +97,9 @@
#define MISC_AEU_BLOCK 35
#define PGLUE_B_BLOCK 36
#define IGU_BLOCK 37
+#define ATC_BLOCK 38
+#define QM_4PORT_BLOCK 39
+#define XSEM_4PORT_BLOCK 40
/* Returns the index of start or end of a specific block stage in ops array*/
@@ -148,5 +151,46 @@ union init_op {
struct raw_op raw;
};
+#define INITOP_SET 0 /* set the HW directly */
+#define INITOP_CLEAR 1 /* clear the HW directly */
+#define INITOP_INIT 2 /* set the init-value array */
+
+/****************************************************************************
+* ILT management
+****************************************************************************/
+struct ilt_line {
+ dma_addr_t page_mapping;
+ void *page;
+ u32 size;
+};
+
+struct ilt_client_info {
+ u32 page_size;
+ u16 start;
+ u16 end;
+ u16 client_num;
+ u16 flags;
+#define ILT_CLIENT_SKIP_INIT 0x1
+#define ILT_CLIENT_SKIP_MEM 0x2
+};
+
+struct bnx2x_ilt {
+ u32 start_line;
+ struct ilt_line *lines;
+ struct ilt_client_info clients[4];
+#define ILT_CLIENT_CDU 0
+#define ILT_CLIENT_QM 1
+#define ILT_CLIENT_SRC 2
+#define ILT_CLIENT_TM 3
+};
+
+/****************************************************************************
+* SRC configuration
+****************************************************************************/
+struct src_ent {
+ u8 opaque[56];
+ u64 next;
+};
+
#endif /* BNX2X_INIT_H */
diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h
index 2b1363a6fe78..e65de784182c 100644
--- a/drivers/net/bnx2x/bnx2x_init_ops.h
+++ b/drivers/net/bnx2x/bnx2x_init_ops.h
@@ -151,6 +151,15 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
bnx2x_init_ind_wr(bp, addr, data, len);
}
+static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, u32 val_hi)
+{
+ u32 wb_write[2];
+
+ wb_write[0] = val_lo;
+ wb_write[1] = val_hi;
+ REG_WR_DMAE_LEN(bp, reg, wb_write, 2);
+}
+
static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off)
{
const u8 *data = NULL;
@@ -477,18 +486,30 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order)
REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
- if (r_order == MAX_RD_ORD)
+ if ((CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) && (r_order == MAX_RD_ORD))
REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
- REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
+ if (CHIP_IS_E2(bp))
+ REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x8 << w_order));
+ else
+ REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
- if (CHIP_IS_E1H(bp)) {
+ if (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp)) {
/* MPS w_order optimal TH presently TH
* 128 0 0 2
* 256 1 1 3
* >=512 2 2 3
*/
- val = ((w_order == 0) ? 2 : 3);
+ /* DMAE is special */
+ if (CHIP_IS_E2(bp)) {
+ /* E2 can use optimal TH */
+ val = w_order;
+ REG_WR(bp, PXP2_REG_WR_DMAE_MPS, val);
+ } else {
+ val = ((w_order == 0) ? 2 : 3);
+ REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2);
+ }
+
REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
@@ -498,9 +519,344 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order)
REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
- REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
}
+
+ /* Validate number of tags suppoted by device */
+#define PCIE_REG_PCIER_TL_HDR_FC_ST 0x2980
+ val = REG_RD(bp, PCIE_REG_PCIER_TL_HDR_FC_ST);
+ val &= 0xFF;
+ if (val <= 0x20)
+ REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x20);
+}
+
+/****************************************************************************
+* ILT management
+****************************************************************************/
+/*
+ * This codes hides the low level HW interaction for ILT management and
+ * configuration. The API consists of a shadow ILT table which is set by the
+ * driver and a set of routines to use it to configure the HW.
+ *
+ */
+
+/* ILT HW init operations */
+
+/* ILT memory management operations */
+#define ILT_MEMOP_ALLOC 0
+#define ILT_MEMOP_FREE 1
+
+/* the phys address is shifted right 12 bits and has an added
+ * 1=valid bit added to the 53rd bit
+ * then since this is a wide register(TM)
+ * we split it into two 32 bit writes
+ */
+#define ILT_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF))
+#define ILT_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44)))
+#define ILT_RANGE(f, l) (((l) << 10) | f)
+
+static int bnx2x_ilt_line_mem_op(struct bnx2x *bp, struct ilt_line *line,
+ u32 size, u8 memop)
+{
+ if (memop == ILT_MEMOP_FREE) {
+ BNX2X_ILT_FREE(line->page, line->page_mapping, line->size);
+ return 0;
+ }
+ BNX2X_ILT_ZALLOC(line->page, &line->page_mapping, size);
+ if (!line->page)
+ return -1;
+ line->size = size;
+ return 0;
+}
+
+
+static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num, u8 memop)
+{
+ int i, rc;
+ struct bnx2x_ilt *ilt = BP_ILT(bp);
+ struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
+
+ if (!ilt || !ilt->lines)
+ return -1;
+
+ if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM))
+ return 0;
+
+ for (rc = 0, i = ilt_cli->start; i <= ilt_cli->end && !rc; i++) {
+ rc = bnx2x_ilt_line_mem_op(bp, &ilt->lines[i],
+ ilt_cli->page_size, memop);
+ }
+ return rc;
+}
+
+int bnx2x_ilt_mem_op(struct bnx2x *bp, u8 memop)
+{
+ int rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_CDU, memop);
+ if (!rc)
+ rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_QM, memop);
+ if (!rc)
+ rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_SRC, memop);
+ if (!rc)
+ rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_TM, memop);
+
+ return rc;
+}
+
+static void bnx2x_ilt_line_wr(struct bnx2x *bp, int abs_idx,
+ dma_addr_t page_mapping)
+{
+ u32 reg;
+
+ if (CHIP_IS_E1(bp))
+ reg = PXP2_REG_RQ_ONCHIP_AT + abs_idx*8;
+ else
+ reg = PXP2_REG_RQ_ONCHIP_AT_B0 + abs_idx*8;
+
+ bnx2x_wr_64(bp, reg, ILT_ADDR1(page_mapping), ILT_ADDR2(page_mapping));
+}
+
+static void bnx2x_ilt_line_init_op(struct bnx2x *bp, struct bnx2x_ilt *ilt,
+ int idx, u8 initop)
+{
+ dma_addr_t null_mapping;
+ int abs_idx = ilt->start_line + idx;
+
+
+ switch (initop) {
+ case INITOP_INIT:
+ /* set in the init-value array */
+ case INITOP_SET:
+ bnx2x_ilt_line_wr(bp, abs_idx, ilt->lines[idx].page_mapping);
+ break;
+ case INITOP_CLEAR:
+ null_mapping = 0;
+ bnx2x_ilt_line_wr(bp, abs_idx, null_mapping);
+ break;
+ }
+}
+
+void bnx2x_ilt_boundry_init_op(struct bnx2x *bp,
+ struct ilt_client_info *ilt_cli,
+ u32 ilt_start, u8 initop)
+{
+ u32 start_reg = 0;
+ u32 end_reg = 0;
+
+ /* The boundary is either SET or INIT,
+ CLEAR => SET and for now SET ~~ INIT */
+
+ /* find the appropriate regs */
+ if (CHIP_IS_E1(bp)) {
+ switch (ilt_cli->client_num) {
+ case ILT_CLIENT_CDU:
+ start_reg = PXP2_REG_PSWRQ_CDU0_L2P;
+ break;
+ case ILT_CLIENT_QM:
+ start_reg = PXP2_REG_PSWRQ_QM0_L2P;
+ break;
+ case ILT_CLIENT_SRC:
+ start_reg = PXP2_REG_PSWRQ_SRC0_L2P;
+ break;
+ case ILT_CLIENT_TM:
+ start_reg = PXP2_REG_PSWRQ_TM0_L2P;
+ break;
+ }
+ REG_WR(bp, start_reg + BP_FUNC(bp)*4,
+ ILT_RANGE((ilt_start + ilt_cli->start),
+ (ilt_start + ilt_cli->end)));
+ } else {
+ switch (ilt_cli->client_num) {
+ case ILT_CLIENT_CDU:
+ start_reg = PXP2_REG_RQ_CDU_FIRST_ILT;
+ end_reg = PXP2_REG_RQ_CDU_LAST_ILT;
+ break;
+ case ILT_CLIENT_QM:
+ start_reg = PXP2_REG_RQ_QM_FIRST_ILT;
+ end_reg = PXP2_REG_RQ_QM_LAST_ILT;
+ break;
+ case ILT_CLIENT_SRC:
+ start_reg = PXP2_REG_RQ_SRC_FIRST_ILT;
+ end_reg = PXP2_REG_RQ_SRC_LAST_ILT;
+ break;
+ case ILT_CLIENT_TM:
+ start_reg = PXP2_REG_RQ_TM_FIRST_ILT;
+ end_reg = PXP2_REG_RQ_TM_LAST_ILT;
+ break;
+ }
+ REG_WR(bp, start_reg, (ilt_start + ilt_cli->start));
+ REG_WR(bp, end_reg, (ilt_start + ilt_cli->end));
+ }
+}
+
+void bnx2x_ilt_client_init_op_ilt(struct bnx2x *bp, struct bnx2x_ilt *ilt,
+ struct ilt_client_info *ilt_cli, u8 initop)
+{
+ int i;
+
+ if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT)
+ return;
+
+ for (i = ilt_cli->start; i <= ilt_cli->end; i++)
+ bnx2x_ilt_line_init_op(bp, ilt, i, initop);
+
+ /* init/clear the ILT boundries */
+ bnx2x_ilt_boundry_init_op(bp, ilt_cli, ilt->start_line, initop);
+}
+
+void bnx2x_ilt_client_init_op(struct bnx2x *bp,
+ struct ilt_client_info *ilt_cli, u8 initop)
+{
+ struct bnx2x_ilt *ilt = BP_ILT(bp);
+
+ bnx2x_ilt_client_init_op_ilt(bp, ilt, ilt_cli, initop);
+}
+
+static void bnx2x_ilt_client_id_init_op(struct bnx2x *bp,
+ int cli_num, u8 initop)
+{
+ struct bnx2x_ilt *ilt = BP_ILT(bp);
+ struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
+
+ bnx2x_ilt_client_init_op(bp, ilt_cli, initop);
+}
+
+void bnx2x_ilt_init_op(struct bnx2x *bp, u8 initop)
+{
+ bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_CDU, initop);
+ bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_QM, initop);
+ bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_SRC, initop);
+ bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_TM, initop);
+}
+
+static void bnx2x_ilt_init_client_psz(struct bnx2x *bp, int cli_num,
+ u32 psz_reg, u8 initop)
+{
+ struct bnx2x_ilt *ilt = BP_ILT(bp);
+ struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
+
+ if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT)
+ return;
+
+ switch (initop) {
+ case INITOP_INIT:
+ /* set in the init-value array */
+ case INITOP_SET:
+ REG_WR(bp, psz_reg, ILOG2(ilt_cli->page_size >> 12));
+ break;
+ case INITOP_CLEAR:
+ break;
+ }
+}
+
+/*
+ * called during init common stage, ilt clients should be initialized
+ * prioir to calling this function
+ */
+void bnx2x_ilt_init_page_size(struct bnx2x *bp, u8 initop)
+{
+ bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_CDU,
+ PXP2_REG_RQ_CDU_P_SIZE, initop);
+ bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_QM,
+ PXP2_REG_RQ_QM_P_SIZE, initop);
+ bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_SRC,
+ PXP2_REG_RQ_SRC_P_SIZE, initop);
+ bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_TM,
+ PXP2_REG_RQ_TM_P_SIZE, initop);
+}
+
+/****************************************************************************
+* QM initializations
+****************************************************************************/
+#define QM_QUEUES_PER_FUNC 16 /* E1 has 32, but only 16 are used */
+#define QM_INIT_MIN_CID_COUNT 31
+#define QM_INIT(cid_cnt) (cid_cnt > QM_INIT_MIN_CID_COUNT)
+
+/* called during init port stage */
+void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count,
+ u8 initop)
+{
+ int port = BP_PORT(bp);
+
+ if (QM_INIT(qm_cid_count)) {
+ switch (initop) {
+ case INITOP_INIT:
+ /* set in the init-value array */
+ case INITOP_SET:
+ REG_WR(bp, QM_REG_CONNNUM_0 + port*4,
+ qm_cid_count/16 - 1);
+ break;
+ case INITOP_CLEAR:
+ break;
+ }
+ }
+}
+
+static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count)
+{
+ int i;
+ u32 wb_data[2];
+
+ wb_data[0] = wb_data[1] = 0;
+
+ for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) {
+ REG_WR(bp, QM_REG_BASEADDR + i*4,
+ qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC));
+ bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8,
+ wb_data, 2);
+
+ if (CHIP_IS_E1H(bp)) {
+ REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4,
+ qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC));
+ bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8,
+ wb_data, 2);
+ }
+ }
+}
+
+/* called during init common stage */
+void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count,
+ u8 initop)
+{
+ if (!QM_INIT(qm_cid_count))
+ return;
+
+ switch (initop) {
+ case INITOP_INIT:
+ /* set in the init-value array */
+ case INITOP_SET:
+ bnx2x_qm_set_ptr_table(bp, qm_cid_count);
+ break;
+ case INITOP_CLEAR:
+ break;
+ }
+}
+
+/****************************************************************************
+* SRC initializations
+****************************************************************************/
+
+/* called during init func stage */
+void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
+ dma_addr_t t2_mapping, int src_cid_count)
+{
+ int i;
+ int port = BP_PORT(bp);
+
+ /* Initialize T2 */
+ for (i = 0; i < src_cid_count-1; i++)
+ t2[i].next = (u64)(t2_mapping + (i+1)*sizeof(struct src_ent));
+
+ /* tell the searcher where the T2 table is */
+ REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, src_cid_count);
+
+ bnx2x_wr_64(bp, SRC_REG_FIRSTFREE0 + port*16,
+ U64_LO(t2_mapping), U64_HI(t2_mapping));
+
+ bnx2x_wr_64(bp, SRC_REG_LASTFREE0 + port*16,
+ U64_LO((u64)t2_mapping +
+ (src_cid_count-1) * sizeof(struct src_ent)),
+ U64_HI((u64)t2_mapping +
+ (src_cid_count-1) * sizeof(struct src_ent)));
}
#endif /* BNX2X_INIT_OPS_H */
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index 0383e3066313..3e99bf9c42b9 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -28,7 +28,7 @@
/********************************************************/
#define ETH_HLEN 14
-#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
+#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)/* 16 for CRC + VLAN + LLC */
#define ETH_MIN_PACKET_SIZE 60
#define ETH_MAX_PACKET_SIZE 1500
#define ETH_MAX_JUMBO_PACKET_SIZE 9600
@@ -168,50 +168,19 @@
/**********************************************************/
/* INTERFACE */
/**********************************************************/
-#define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
- bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
- DEFAULT_PHY_DEV_ADDR, \
+
+#define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
+ bnx2x_cl45_write(_bp, _phy, \
+ (_phy)->def_md_devad, \
(_bank + (_addr & 0xf)), \
_val)
-#define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
- bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
- DEFAULT_PHY_DEV_ADDR, \
+#define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
+ bnx2x_cl45_read(_bp, _phy, \
+ (_phy)->def_md_devad, \
(_bank + (_addr & 0xf)), \
_val)
-static void bnx2x_set_serdes_access(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-
- /* Set Clause 22 */
- REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
- udelay(500);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
- udelay(500);
- /* Set Clause 45 */
- REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
-}
-static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
-{
- struct bnx2x *bp = params->bp;
-
- if (phy_flags & PHY_XGXS_FLAG) {
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
- params->port*0x18, 0);
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
- DEFAULT_PHY_DEV_ADDR);
- } else {
- bnx2x_set_serdes_access(params);
-
- REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
- params->port*0x10,
- DEFAULT_PHY_DEV_ADDR);
- }
-}
-
static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
{
u32 val = REG_RD(bp, reg);
@@ -408,9 +377,60 @@ static u8 bnx2x_emac_enable(struct link_params *params,
return 0;
}
+static void bnx2x_update_bmac2(struct link_params *params,
+ struct link_vars *vars,
+ u8 is_lb)
+{
+ /*
+ * Set rx control: Strip CRC and enable BigMAC to relay
+ * control packets to the system as well
+ */
+ u32 wb_data[2];
+ struct bnx2x *bp = params->bp;
+ u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
+ NIG_REG_INGRESS_BMAC0_MEM;
+ u32 val = 0x14;
+
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
+ /* Enable BigMAC to react on received Pause packets */
+ val |= (1<<5);
+ wb_data[0] = val;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL,
+ wb_data, 2);
+ udelay(30);
+
+ /* Tx control */
+ val = 0xc0;
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ val |= 0x800000;
+ wb_data[0] = val;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL,
+ wb_data, 2);
+
+ val = 0x8000;
+ wb_data[0] = val;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
+ wb_data, 2);
+
+ /* mac control */
+ val = 0x3; /* Enable RX and TX */
+ if (is_lb) {
+ val |= 0x4; /* Local loopback */
+ DP(NETIF_MSG_LINK, "enable bmac loopback\n");
+ }
+
+ wb_data[0] = val;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
+ wb_data, 2);
+}
-static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
+static u8 bnx2x_bmac1_enable(struct link_params *params,
+ struct link_vars *vars,
u8 is_lb)
{
struct bnx2x *bp = params->bp;
@@ -420,17 +440,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
u32 wb_data[2];
u32 val;
- DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
- /* reset and unreset the BigMac */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
- msleep(1);
-
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
- /* enable access for bmac registers */
- REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
+ DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
/* XGXS control */
wb_data[0] = 0x3c;
@@ -510,180 +520,121 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
wb_data, 2);
}
- REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
- REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
- REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
- val = 0;
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
- val = 1;
- REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
- REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
- REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
- REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
- REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
- REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
- vars->mac_type = MAC_TYPE_BMAC;
return 0;
}
-static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
-{
- struct bnx2x *bp = params->bp;
- u32 val;
-
- if (phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
- val = XGXS_RESET_BITS;
-
- } else { /* SerDes */
- DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
- val = SERDES_RESET_BITS;
- }
-
- val = val << (params->port*16);
-
- /* reset and unreset the SerDes/XGXS */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
- val);
- udelay(500);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
- val);
- bnx2x_set_phy_mdio(params, phy_flags);
-}
-
-void bnx2x_link_status_update(struct link_params *params,
- struct link_vars *vars)
+static u8 bnx2x_bmac2_enable(struct link_params *params,
+ struct link_vars *vars,
+ u8 is_lb)
{
struct bnx2x *bp = params->bp;
- u8 link_10g;
u8 port = params->port;
+ u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
+ NIG_REG_INGRESS_BMAC0_MEM;
+ u32 wb_data[2];
- if (params->switch_cfg == SWITCH_CFG_1G)
- vars->phy_flags = PHY_SERDES_FLAG;
- else
- vars->phy_flags = PHY_XGXS_FLAG;
- vars->link_status = REG_RD(bp, params->shmem_base +
- offsetof(struct shmem_region,
- port_mb[port].link_status));
-
- vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
-
- if (vars->link_up) {
- DP(NETIF_MSG_LINK, "phy link up\n");
-
- vars->phy_link_up = 1;
- vars->duplex = DUPLEX_FULL;
- switch (vars->link_status &
- LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
- case LINK_10THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_10TFD:
- vars->line_speed = SPEED_10;
- break;
-
- case LINK_100TXHD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_100T4:
- case LINK_100TXFD:
- vars->line_speed = SPEED_100;
- break;
-
- case LINK_1000THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_1000TFD:
- vars->line_speed = SPEED_1000;
- break;
-
- case LINK_2500THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_2500TFD:
- vars->line_speed = SPEED_2500;
- break;
-
- case LINK_10GTFD:
- vars->line_speed = SPEED_10000;
- break;
-
- case LINK_12GTFD:
- vars->line_speed = SPEED_12000;
- break;
+ DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
- case LINK_12_5GTFD:
- vars->line_speed = SPEED_12500;
- break;
+ wb_data[0] = 0;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
+ wb_data, 2);
+ udelay(30);
- case LINK_13GTFD:
- vars->line_speed = SPEED_13000;
- break;
+ /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
+ wb_data[0] = 0x3c;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr +
+ BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
+ wb_data, 2);
- case LINK_15GTFD:
- vars->line_speed = SPEED_15000;
- break;
+ udelay(30);
- case LINK_16GTFD:
- vars->line_speed = SPEED_16000;
- break;
+ /* tx MAC SA */
+ wb_data[0] = ((params->mac_addr[2] << 24) |
+ (params->mac_addr[3] << 16) |
+ (params->mac_addr[4] << 8) |
+ params->mac_addr[5]);
+ wb_data[1] = ((params->mac_addr[0] << 8) |
+ params->mac_addr[1]);
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
+ wb_data, 2);
- default:
- break;
- }
+ udelay(30);
- if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
- vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
- else
- vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
+ /* Configure SAFC */
+ wb_data[0] = 0x1000200;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
+ wb_data, 2);
+ udelay(30);
- if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
- vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
- else
- vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
+ /* set rx mtu */
+ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE,
+ wb_data, 2);
+ udelay(30);
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- if (vars->line_speed &&
- ((vars->line_speed == SPEED_10) ||
- (vars->line_speed == SPEED_100))) {
- vars->phy_flags |= PHY_SGMII_FLAG;
- } else {
- vars->phy_flags &= ~PHY_SGMII_FLAG;
- }
- }
+ /* set tx mtu */
+ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE,
+ wb_data, 2);
+ udelay(30);
+ /* set cnt max size */
+ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE,
+ wb_data, 2);
+ udelay(30);
+ bnx2x_update_bmac2(params, vars, is_lb);
- /* anything 10 and over uses the bmac */
- link_10g = ((vars->line_speed == SPEED_10000) ||
- (vars->line_speed == SPEED_12000) ||
- (vars->line_speed == SPEED_12500) ||
- (vars->line_speed == SPEED_13000) ||
- (vars->line_speed == SPEED_15000) ||
- (vars->line_speed == SPEED_16000));
- if (link_10g)
- vars->mac_type = MAC_TYPE_BMAC;
- else
- vars->mac_type = MAC_TYPE_EMAC;
+ return 0;
+}
- } else { /* link down */
- DP(NETIF_MSG_LINK, "phy link down\n");
+u8 bnx2x_bmac_enable(struct link_params *params,
+ struct link_vars *vars,
+ u8 is_lb)
+{
+ u8 rc, port = params->port;
+ struct bnx2x *bp = params->bp;
+ u32 val;
+ /* reset and unreset the BigMac */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+ udelay(10);
- vars->phy_link_up = 0;
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
- vars->line_speed = 0;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+ /* enable access for bmac registers */
+ REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
- /* indicate no mac active */
- vars->mac_type = MAC_TYPE_NONE;
- }
+ /* Enable BMAC according to BMAC type*/
+ if (CHIP_IS_E2(bp))
+ rc = bnx2x_bmac2_enable(params, vars, is_lb);
+ else
+ rc = bnx2x_bmac1_enable(params, vars, is_lb);
+ REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
+ REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
+ REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
+ val = 0;
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ val = 1;
+ REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
+ REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
+ REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
+ REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
+ REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
+ REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
- DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
- vars->link_status, vars->phy_link_up);
- DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
- vars->line_speed, vars->duplex, vars->flow_ctrl);
+ vars->mac_type = MAC_TYPE_BMAC;
+ return rc;
}
+
static void bnx2x_update_mng(struct link_params *params, u32 link_status)
{
struct bnx2x *bp = params->bp;
@@ -706,13 +657,25 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
nig_bmac_enable) {
- /* Clear Rx Enable bit in BMAC_CONTROL register */
- REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
- wb_data, 2);
- wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
- wb_data, 2);
-
+ if (CHIP_IS_E2(bp)) {
+ /* Clear Rx Enable bit in BMAC_CONTROL register */
+ REG_RD_DMAE(bp, bmac_addr +
+ BIGMAC2_REGISTER_BMAC_CONTROL,
+ wb_data, 2);
+ wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
+ REG_WR_DMAE(bp, bmac_addr +
+ BIGMAC2_REGISTER_BMAC_CONTROL,
+ wb_data, 2);
+ } else {
+ /* Clear Rx Enable bit in BMAC_CONTROL register */
+ REG_RD_DMAE(bp, bmac_addr +
+ BIGMAC_REGISTER_BMAC_CONTROL,
+ wb_data, 2);
+ wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
+ REG_WR_DMAE(bp, bmac_addr +
+ BIGMAC_REGISTER_BMAC_CONTROL,
+ wb_data, 2);
+ }
msleep(1);
}
}
@@ -800,62 +763,69 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
return 0;
}
-static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
+static u32 bnx2x_get_emac_base(struct bnx2x *bp,
+ u32 mdc_mdio_access, u8 port)
{
- u32 emac_base;
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- /* All MDC/MDIO is directed through single EMAC */
+ u32 emac_base = 0;
+ switch (mdc_mdio_access) {
+ case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
+ break;
+ case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
+ if (REG_RD(bp, NIG_REG_PORT_SWAP))
+ emac_base = GRCBASE_EMAC1;
+ else
+ emac_base = GRCBASE_EMAC0;
+ break;
+ case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
if (REG_RD(bp, NIG_REG_PORT_SWAP))
emac_base = GRCBASE_EMAC0;
else
emac_base = GRCBASE_EMAC1;
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
+ emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ break;
+ case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
break;
default:
- emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
break;
}
return emac_base;
}
-u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 val)
+u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
+ u8 devad, u16 reg, u16 val)
{
u32 tmp, saved_mode;
u8 i, rc = 0;
- u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
* (a value of 49==0x31) and make sure that the AUTO poll is off
*/
- saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
EMAC_MDIO_MODE_CLOCK_CNT);
tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
(49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
- REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
+ REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
udelay(40);
/* address */
- tmp = ((phy_addr << 21) | (devad << 16) | reg |
+ tmp = ((phy->addr << 21) | (devad << 16) | reg |
EMAC_MDIO_COMM_COMMAND_ADDRESS |
EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
for (i = 0; i < 50; i++) {
udelay(10);
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
+ tmp = REG_RD(bp, phy->mdio_ctrl +
+ EMAC_REG_EMAC_MDIO_COMM);
if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
@@ -866,15 +836,15 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
rc = -EFAULT;
} else {
/* data */
- tmp = ((phy_addr << 21) | (devad << 16) | val |
+ tmp = ((phy->addr << 21) | (devad << 16) | val |
EMAC_MDIO_COMM_COMMAND_WRITE_45 |
EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
for (i = 0; i < 50; i++) {
udelay(10);
- tmp = REG_RD(bp, mdio_ctrl +
+ tmp = REG_RD(bp, phy->mdio_ctrl +
EMAC_REG_EMAC_MDIO_COMM);
if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
@@ -888,42 +858,41 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
}
/* Restore the saved mode */
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
return rc;
}
-u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
+u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
+ u8 devad, u16 reg, u16 *ret_val)
{
u32 val, saved_mode;
u16 i;
u8 rc = 0;
- u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
* (a value of 49==0x31) and make sure that the AUTO poll is off
*/
- saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
+ saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL |
EMAC_MDIO_MODE_CLOCK_CNT));
val |= (EMAC_MDIO_MODE_CLAUSE_45 |
(49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
- REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
+ REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
udelay(40);
/* address */
- val = ((phy_addr << 21) | (devad << 16) | reg |
+ val = ((phy->addr << 21) | (devad << 16) | reg |
EMAC_MDIO_COMM_COMMAND_ADDRESS |
EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
for (i = 0; i < 50; i++) {
udelay(10);
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
+ val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
@@ -937,15 +906,15 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
} else {
/* data */
- val = ((phy_addr << 21) | (devad << 16) |
+ val = ((phy->addr << 21) | (devad << 16) |
EMAC_MDIO_COMM_COMMAND_READ_45 |
EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
for (i = 0; i < 50; i++) {
udelay(10);
- val = REG_RD(bp, mdio_ctrl +
+ val = REG_RD(bp, phy->mdio_ctrl +
EMAC_REG_EMAC_MDIO_COMM);
if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
*ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
@@ -961,32 +930,262 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
}
/* Restore the saved mode */
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
return rc;
}
-static void bnx2x_set_aer_mmd(struct link_params *params,
- struct link_vars *vars)
+u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
+ u8 devad, u16 reg, u16 *ret_val)
{
- struct bnx2x *bp = params->bp;
- u32 ser_lane;
- u16 offset;
+ u8 phy_index;
+ /**
+ * Probe for the phy according to the given phy_addr, and execute
+ * the read request on it
+ */
+ for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
+ if (params->phy[phy_index].addr == phy_addr) {
+ return bnx2x_cl45_read(params->bp,
+ &params->phy[phy_index], devad,
+ reg, ret_val);
+ }
+ }
+ return -EINVAL;
+}
+u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
+ u8 devad, u16 reg, u16 val)
+{
+ u8 phy_index;
+ /**
+ * Probe for the phy according to the given phy_addr, and execute
+ * the write request on it
+ */
+ for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
+ if (params->phy[phy_index].addr == phy_addr) {
+ return bnx2x_cl45_write(params->bp,
+ &params->phy[phy_index], devad,
+ reg, val);
+ }
+ }
+ return -EINVAL;
+}
+
+static void bnx2x_set_aer_mmd_xgxs(struct link_params *params,
+ struct bnx2x_phy *phy)
+{
+ u32 ser_lane;
+ u16 offset, aer_val;
+ struct bnx2x *bp = params->bp;
ser_lane = ((params->lane_config &
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
- offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
- (params->phy_addr + ser_lane) : 0;
+ offset = phy->addr + ser_lane;
+ if (CHIP_IS_E2(bp))
+ aer_val = 0x2800 + offset - 1;
+ else
+ aer_val = 0x3800 + offset;
+ CL45_WR_OVER_CL22(bp, phy,
+ MDIO_REG_BANK_AER_BLOCK,
+ MDIO_AER_BLOCK_AER_REG, aer_val);
+}
+static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp,
+ struct bnx2x_phy *phy)
+{
+ CL45_WR_OVER_CL22(bp, phy,
+ MDIO_REG_BANK_AER_BLOCK,
+ MDIO_AER_BLOCK_AER_REG, 0x3800);
+}
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_AER_BLOCK,
- MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
+/******************************************************************/
+/* Internal phy section */
+/******************************************************************/
+
+static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
+{
+ u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
+ /* Set Clause 22 */
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
+ udelay(500);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
+ udelay(500);
+ /* Set Clause 45 */
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
+}
+
+static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
+{
+ u32 val;
+
+ DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
+
+ val = SERDES_RESET_BITS << (port*16);
+
+ /* reset and unreset the SerDes/XGXS */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
+ udelay(500);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
+
+ bnx2x_set_serdes_access(bp, port);
+
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
+ port*0x10,
+ DEFAULT_PHY_DEV_ADDR);
}
-static void bnx2x_set_master_ln(struct link_params *params)
+static void bnx2x_xgxs_deassert(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port;
+ u32 val;
+ DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
+ port = params->port;
+
+ val = XGXS_RESET_BITS << (port*16);
+
+ /* reset and unreset the SerDes/XGXS */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
+ udelay(500);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
+
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
+ port*0x18, 0);
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
+ params->phy[INT_PHY].def_md_devad);
+}
+
+
+void bnx2x_link_status_update(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 link_10g;
+ u8 port = params->port;
+
+ vars->link_status = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region,
+ port_mb[port].link_status));
+
+ vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
+
+ if (vars->link_up) {
+ DP(NETIF_MSG_LINK, "phy link up\n");
+
+ vars->phy_link_up = 1;
+ vars->duplex = DUPLEX_FULL;
+ switch (vars->link_status &
+ LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
+ case LINK_10THD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_10TFD:
+ vars->line_speed = SPEED_10;
+ break;
+
+ case LINK_100TXHD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_100T4:
+ case LINK_100TXFD:
+ vars->line_speed = SPEED_100;
+ break;
+
+ case LINK_1000THD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_1000TFD:
+ vars->line_speed = SPEED_1000;
+ break;
+
+ case LINK_2500THD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_2500TFD:
+ vars->line_speed = SPEED_2500;
+ break;
+
+ case LINK_10GTFD:
+ vars->line_speed = SPEED_10000;
+ break;
+
+ case LINK_12GTFD:
+ vars->line_speed = SPEED_12000;
+ break;
+
+ case LINK_12_5GTFD:
+ vars->line_speed = SPEED_12500;
+ break;
+
+ case LINK_13GTFD:
+ vars->line_speed = SPEED_13000;
+ break;
+
+ case LINK_15GTFD:
+ vars->line_speed = SPEED_15000;
+ break;
+
+ case LINK_16GTFD:
+ vars->line_speed = SPEED_16000;
+ break;
+
+ default:
+ break;
+ }
+ vars->flow_ctrl = 0;
+ if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
+ vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
+
+ if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
+ vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
+
+ if (!vars->flow_ctrl)
+ vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+
+ if (vars->line_speed &&
+ ((vars->line_speed == SPEED_10) ||
+ (vars->line_speed == SPEED_100))) {
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ } else {
+ vars->phy_flags &= ~PHY_SGMII_FLAG;
+ }
+
+ /* anything 10 and over uses the bmac */
+ link_10g = ((vars->line_speed == SPEED_10000) ||
+ (vars->line_speed == SPEED_12000) ||
+ (vars->line_speed == SPEED_12500) ||
+ (vars->line_speed == SPEED_13000) ||
+ (vars->line_speed == SPEED_15000) ||
+ (vars->line_speed == SPEED_16000));
+ if (link_10g)
+ vars->mac_type = MAC_TYPE_BMAC;
+ else
+ vars->mac_type = MAC_TYPE_EMAC;
+
+ } else { /* link down */
+ DP(NETIF_MSG_LINK, "phy link down\n");
+
+ vars->phy_link_up = 0;
+
+ vars->line_speed = 0;
+ vars->duplex = DUPLEX_FULL;
+ vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+
+ /* indicate no mac active */
+ vars->mac_type = MAC_TYPE_NONE;
+ }
+
+ DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
+ vars->link_status, vars->phy_link_up);
+ DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
+ vars->line_speed, vars->duplex, vars->flow_ctrl);
+}
+
+
+static void bnx2x_set_master_ln(struct link_params *params,
+ struct bnx2x_phy *phy)
{
struct bnx2x *bp = params->bp;
u16 new_master_ln, ser_lane;
@@ -995,47 +1194,44 @@ static void bnx2x_set_master_ln(struct link_params *params)
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
/* set the master_ln for AN */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
&new_master_ln);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2 ,
MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
(new_master_ln | ser_lane));
}
-static u8 bnx2x_reset_unicore(struct link_params *params)
+static u8 bnx2x_reset_unicore(struct link_params *params,
+ struct bnx2x_phy *phy,
+ u8 set_serdes)
{
struct bnx2x *bp = params->bp;
u16 mii_control;
u16 i;
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
/* reset the unicore */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
(mii_control |
MDIO_COMBO_IEEO_MII_CONTROL_RESET));
- if (params->switch_cfg == SWITCH_CFG_1G)
- bnx2x_set_serdes_access(params);
+ if (set_serdes)
+ bnx2x_set_serdes_access(bp, params->port);
/* wait for the reset to self clear */
for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
udelay(5);
/* the reset erased the previous bank value */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
&mii_control);
@@ -1051,7 +1247,8 @@ static u8 bnx2x_reset_unicore(struct link_params *params)
}
-static void bnx2x_set_swap_lanes(struct link_params *params)
+static void bnx2x_set_swap_lanes(struct link_params *params,
+ struct bnx2x_phy *phy)
{
struct bnx2x *bp = params->bp;
/* Each two bits represents a lane number:
@@ -1069,71 +1266,62 @@ static void bnx2x_set_swap_lanes(struct link_params *params)
PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
if (rx_lane_swap != 0x1b) {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_RX_LN_SWAP,
(rx_lane_swap |
MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
} else {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
}
if (tx_lane_swap != 0x1b) {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_TX_LN_SWAP,
(tx_lane_swap |
MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
} else {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
}
}
-static void bnx2x_set_parallel_detection(struct link_params *params,
- u8 phy_flags)
+static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 control2;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
&control2);
- if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+ if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
else
control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
- DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n",
- params->speed_cap_mask, control2);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
+ phy->speed_cap_mask, control2);
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
control2);
- if ((phy_flags & PHY_XGXS_FLAG) &&
- (params->speed_cap_mask &
+ if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+ (phy->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
DP(NETIF_MSG_LINK, "XGXS\n");
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_10G_PARALLEL_DETECT,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_10G_PARALLEL_DETECT,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
&control2);
@@ -1142,15 +1330,13 @@ static void bnx2x_set_parallel_detection(struct link_params *params,
control2 |=
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_10G_PARALLEL_DETECT,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
control2);
/* Disable parallel detection of HiG */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
@@ -1158,7 +1344,8 @@ static void bnx2x_set_parallel_detection(struct link_params *params,
}
}
-static void bnx2x_set_autoneg(struct link_params *params,
+static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
+ struct link_params *params,
struct link_vars *vars,
u8 enable_cl73)
{
@@ -1166,9 +1353,7 @@ static void bnx2x_set_autoneg(struct link_params *params,
u16 reg_val;
/* CL37 Autoneg */
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
@@ -1179,15 +1364,13 @@ static void bnx2x_set_autoneg(struct link_params *params,
reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
/* Enable/Disable Autodetection */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
@@ -1198,14 +1381,12 @@ static void bnx2x_set_autoneg(struct link_params *params,
else
reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
/* Enable TetonII and BAM autoneg */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_BAM_NEXT_PAGE,
MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
&reg_val);
@@ -1218,23 +1399,20 @@ static void bnx2x_set_autoneg(struct link_params *params,
reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
}
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_BAM_NEXT_PAGE,
MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
reg_val);
if (enable_cl73) {
/* Enable Cl73 FSM status bits */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_USERB0,
MDIO_CL73_USERB0_CL73_UCTRL,
0xe);
/* Enable BAM Station Manager*/
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_USERB0,
MDIO_CL73_USERB0_CL73_BAM_CTRL1,
MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
@@ -1242,20 +1420,18 @@ static void bnx2x_set_autoneg(struct link_params *params,
MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
/* Advertise CL73 link speeds */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_ADV2,
&reg_val);
- if (params->speed_cap_mask &
+ if (phy->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
- if (params->speed_cap_mask &
+ if (phy->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_ADV2,
reg_val);
@@ -1266,38 +1442,35 @@ static void bnx2x_set_autoneg(struct link_params *params,
} else /* CL73 Autoneg Disabled */
reg_val = 0;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB0,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
}
/* program SerDes, forced speed */
-static void bnx2x_program_serdes(struct link_params *params,
+static void bnx2x_program_serdes(struct bnx2x_phy *phy,
+ struct link_params *params,
struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
u16 reg_val;
/* program duplex, disable autoneg and sgmii*/
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
- if (params->req_duplex == DUPLEX_FULL)
+ if (phy->req_duplex == DUPLEX_FULL)
reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
/* program speed
- needed only if the speed is greater than 1G (2.5G or 10G) */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_MISC1, &reg_val);
/* clearing the speed value before setting the right speed */
@@ -1320,14 +1493,14 @@ static void bnx2x_program_serdes(struct link_params *params,
MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
}
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_MISC1, reg_val);
}
-static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
+static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 val = 0;
@@ -1335,29 +1508,28 @@ static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
/* configure the 48 bits for BAM AN */
/* set extended capabilities */
- if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
+ if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
val |= MDIO_OVER_1G_UP1_2_5G;
- if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
+ if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
val |= MDIO_OVER_1G_UP1_10G;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_OVER_1G,
MDIO_OVER_1G_UP1, val);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_OVER_1G,
MDIO_OVER_1G_UP3, 0x400);
}
-static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
+static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
+ struct link_params *params, u16 *ieee_fc)
{
struct bnx2x *bp = params->bp;
*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
/* resolve pause mode and advertisement
* Please refer to Table 28B-3 of the 802.3ab-1999 spec */
- switch (params->req_flow_ctrl) {
+ switch (phy->req_flow_ctrl) {
case BNX2X_FLOW_CTRL_AUTO:
if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
*ieee_fc |=
@@ -1385,30 +1557,30 @@ static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
}
-static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
+static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy,
+ struct link_params *params,
u16 ieee_fc)
{
struct bnx2x *bp = params->bp;
u16 val;
/* for AN, we are always publishing full duplex */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_ADV1, &val);
val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_ADV1, val);
}
-static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
+static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
+ struct link_params *params,
+ u8 enable_cl73)
{
struct bnx2x *bp = params->bp;
u16 mii_control;
@@ -1417,14 +1589,12 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
/* Enable and restart BAM/CL37 aneg */
if (enable_cl73) {
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB0,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
&mii_control);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB0,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
(mii_control |
@@ -1432,16 +1602,14 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
} else {
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
&mii_control);
DP(NETIF_MSG_LINK,
"bnx2x_restart_autoneg mii_control before = 0x%x\n",
mii_control);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
(mii_control |
@@ -1450,7 +1618,8 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
}
}
-static void bnx2x_initialize_sgmii_process(struct link_params *params,
+static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
+ struct link_params *params,
struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
@@ -1458,8 +1627,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
/* in SGMII mode, the unicore is always slave */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
&control1);
@@ -1468,8 +1636,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
control1);
@@ -1479,8 +1646,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
/* set speed, disable autoneg */
u16 mii_control;
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
&mii_control);
@@ -1508,18 +1674,17 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
}
/* setting the full duplex */
- if (params->req_duplex == DUPLEX_FULL)
+ if (phy->req_duplex == DUPLEX_FULL)
mii_control |=
MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
mii_control);
} else { /* AN mode */
/* enable and restart AN */
- bnx2x_restart_autoneg(params, 0);
+ bnx2x_restart_autoneg(phy, params, 0);
}
}
@@ -1549,91 +1714,24 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
default:
break;
}
+ if (pause_result & (1<<0))
+ vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
+ if (pause_result & (1<<1))
+ vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
}
-static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 ext_phy_addr;
- u16 ld_pause; /* local */
- u16 lp_pause; /* link partner */
- u16 an_complete; /* AN complete */
- u16 pause_result;
- u8 ret = 0;
- u32 ext_phy_type;
- u8 port = params->port;
- ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* read twice */
-
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_STATUS, &an_complete);
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_STATUS, &an_complete);
-
- if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
- ret = 1;
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV_PAUSE, &ld_pause);
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
- pause_result = (ld_pause &
- MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
- pause_result |= (lp_pause &
- MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
- DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
- pause_result);
- bnx2x_pause_resolve(vars, pause_result);
- if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
- ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, &ld_pause);
-
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LP, &lp_pause);
- pause_result = (ld_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
- pause_result |= (lp_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
-
- bnx2x_pause_resolve(vars, pause_result);
- DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
- pause_result);
- }
- }
- return ret;
-}
-
-static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
+static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 pd_10g, status2_1000x;
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ if (phy->req_line_speed != SPEED_AUTO_NEG)
+ return 0;
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
&status2_1000x);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
&status2_1000x);
@@ -1643,8 +1741,7 @@ static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
return 1;
}
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_10G_PARALLEL_DETECT,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
&pd_10g);
@@ -1657,9 +1754,10 @@ static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
return 0;
}
-static void bnx2x_flow_ctrl_resolve(struct link_params *params,
- struct link_vars *vars,
- u32 gp_status)
+static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars,
+ u32 gp_status)
{
struct bnx2x *bp = params->bp;
u16 ld_pause; /* local driver */
@@ -1669,12 +1767,13 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
/* resolve from gp_status in case of AN complete and not sgmii */
- if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
- (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
- (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
- if (bnx2x_direct_parallel_detect_used(params)) {
+ if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
+ vars->flow_ctrl = phy->req_flow_ctrl;
+ else if (phy->req_line_speed != SPEED_AUTO_NEG)
+ vars->flow_ctrl = params->req_fc_auto_adv;
+ else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
+ (!(vars->phy_flags & PHY_SGMII_FLAG))) {
+ if (bnx2x_direct_parallel_detect_used(phy, params)) {
vars->flow_ctrl = params->req_fc_auto_adv;
return;
}
@@ -1684,13 +1783,11 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
(MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_ADV1,
&ld_pause);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_LP_ADV1,
&lp_pause);
@@ -1703,14 +1800,11 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
pause_result);
} else {
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
&ld_pause);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
&lp_pause);
@@ -1722,26 +1816,18 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
pause_result);
}
bnx2x_pause_resolve(vars, pause_result);
- } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
- (bnx2x_ext_phy_resolve_fc(params, vars))) {
- return;
- } else {
- if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
- vars->flow_ctrl = params->req_fc_auto_adv;
- else
- vars->flow_ctrl = params->req_flow_ctrl;
}
DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
}
-static void bnx2x_check_fallback_to_cl37(struct link_params *params)
+static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 rx_status, ustat_val, cl37_fsm_recieved;
DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
/* Step 1: Make sure signal is detected */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_RX0,
MDIO_RX0_RX_STATUS,
&rx_status);
@@ -1749,16 +1835,14 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params)
(MDIO_RX0_RX_STATUS_SIGDET)) {
DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
"rx_status(0x80b0) = 0x%x\n", rx_status);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB0,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
return;
}
/* Step 2: Check CL73 state machine */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_USERB0,
MDIO_CL73_USERB0_CL73_USTAT1,
&ustat_val);
@@ -1773,8 +1857,7 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params)
}
/* Step 3: Check CL37 Message Pages received to indicate LP
supports only CL37 */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_REMOTE_PHY,
MDIO_REMOTE_PHY_MISC_RX_STATUS,
&cl37_fsm_recieved);
@@ -1792,25 +1875,45 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params)
connected to a device which does not support cl73, but does support
cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
/* Disable CL73 */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB0,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
0);
/* Restart CL37 autoneg */
- bnx2x_restart_autoneg(params, 0);
+ bnx2x_restart_autoneg(phy, params, 0);
DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
}
-static u8 bnx2x_link_settings_status(struct link_params *params,
- struct link_vars *vars,
- u32 gp_status,
- u8 ext_phy_link_up)
+
+static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars,
+ u32 gp_status)
+{
+ if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
+ vars->link_status |=
+ LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
+
+ if (bnx2x_direct_parallel_detect_used(phy, params))
+ vars->link_status |=
+ LINK_STATUS_PARALLEL_DETECTION_USED;
+}
+
+static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
- u16 new_line_speed;
+ u16 new_line_speed , gp_status;
u8 rc = 0;
- vars->link_status = 0;
+ /* Read gp_status */
+ CL45_RD_OVER_CL22(bp, phy,
+ MDIO_REG_BANK_GP_STATUS,
+ MDIO_GP_STATUS_TOP_AN_STATUS1,
+ &gp_status);
+
+ if (phy->req_line_speed == SPEED_AUTO_NEG)
+ vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
gp_status);
@@ -1823,7 +1926,12 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
else
vars->duplex = DUPLEX_HALF;
- bnx2x_flow_ctrl_resolve(params, vars, gp_status);
+ if (SINGLE_MEDIA_DIRECT(params)) {
+ bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
+ if (phy->req_line_speed == SPEED_AUTO_NEG)
+ bnx2x_xgxs_an_resolve(phy, params, vars,
+ gp_status);
+ }
switch (gp_status & GP_STATUS_SPEED_MASK) {
case GP_STATUS_10M:
@@ -1905,56 +2013,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
return -EINVAL;
}
- /* Upon link speed change set the NIG into drain mode.
- Comes to deals with possible FIFO glitch due to clk change
- when speed is decreased without link down indicator */
- if (new_line_speed != vars->line_speed) {
- if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) !=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT &&
- ext_phy_link_up) {
- DP(NETIF_MSG_LINK, "Internal link speed %d is"
- " different than the external"
- " link speed %d\n", new_line_speed,
- vars->line_speed);
- vars->phy_link_up = 0;
- return 0;
- }
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
- + params->port*4, 0);
- msleep(1);
- }
vars->line_speed = new_line_speed;
- vars->link_status |= LINK_STATUS_SERDES_LINK;
-
- if ((params->req_line_speed == SPEED_AUTO_NEG) &&
- ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
- vars->autoneg = AUTO_NEG_ENABLED;
-
- if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
- vars->autoneg |= AUTO_NEG_COMPLETE;
- vars->link_status |=
- LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
- }
-
- vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
- vars->link_status |=
- LINK_STATUS_PARALLEL_DETECTION_USED;
-
- }
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
- vars->link_status |=
- LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
-
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
- vars->link_status |=
- LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
} else { /* link_down */
DP(NETIF_MSG_LINK, "phy link down\n");
@@ -1963,38 +2022,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
vars->duplex = DUPLEX_FULL;
vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
- vars->autoneg = AUTO_NEG_DISABLED;
vars->mac_type = MAC_TYPE_NONE;
- if ((params->req_line_speed == SPEED_AUTO_NEG) &&
- ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT))) {
+ if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ SINGLE_MEDIA_DIRECT(params)) {
/* Check signal is detected */
- bnx2x_check_fallback_to_cl37(params);
+ bnx2x_check_fallback_to_cl37(phy, params);
}
}
DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n",
gp_status, vars->phy_link_up, vars->line_speed);
- DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
- " autoneg 0x%x\n",
- vars->duplex,
- vars->flow_ctrl, vars->autoneg);
- DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
-
+ DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
+ vars->duplex, vars->flow_ctrl, vars->link_status);
return rc;
}
static void bnx2x_set_gmii_tx_driver(struct link_params *params)
{
struct bnx2x *bp = params->bp;
+ struct bnx2x_phy *phy = &params->phy[INT_PHY];
u16 lp_up2;
u16 tx_driver;
u16 bank;
/* read precomp */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_OVER_1G,
MDIO_OVER_1G_LP_UP2, &lp_up2);
@@ -2008,8 +2061,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params)
for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
bank,
MDIO_TX0_TX_DRIVER, &tx_driver);
@@ -2018,8 +2070,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params)
(tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
tx_driver |= lp_up2;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
bank,
MDIO_TX0_TX_DRIVER, tx_driver);
}
@@ -2027,7 +2078,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params)
}
static u8 bnx2x_emac_program(struct link_params *params,
- u32 line_speed, u32 duplex)
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
@@ -2039,7 +2090,7 @@ static u8 bnx2x_emac_program(struct link_params *params,
(EMAC_MODE_25G_MODE |
EMAC_MODE_PORT_MII_10M |
EMAC_MODE_HALF_DUPLEX));
- switch (line_speed) {
+ switch (vars->line_speed) {
case SPEED_10:
mode |= EMAC_MODE_PORT_MII_10M;
break;
@@ -2058,371 +2109,1373 @@ static u8 bnx2x_emac_program(struct link_params *params,
default:
/* 10G not valid for EMAC */
- DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
+ DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
+ vars->line_speed);
return -EINVAL;
}
- if (duplex == DUPLEX_HALF)
+ if (vars->duplex == DUPLEX_HALF)
mode |= EMAC_MODE_HALF_DUPLEX;
bnx2x_bits_en(bp,
GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
mode);
- bnx2x_set_led(params, LED_MODE_OPER, line_speed);
+ bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
return 0;
}
-/*****************************************************************************/
-/* External Phy section */
-/*****************************************************************************/
-void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
+static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
+ struct link_params *params)
{
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- msleep(1);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
+
+ u16 bank, i = 0;
+ struct bnx2x *bp = params->bp;
+
+ for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
+ bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
+ CL45_WR_OVER_CL22(bp, phy,
+ bank,
+ MDIO_RX0_RX_EQ_BOOST,
+ phy->rx_preemphasis[i]);
+ }
+
+ for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
+ bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
+ CL45_WR_OVER_CL22(bp, phy,
+ bank,
+ MDIO_TX0_TX_DRIVER,
+ phy->tx_preemphasis[i]);
+ }
}
-static void bnx2x_ext_phy_reset(struct link_params *params,
- struct link_vars *vars)
+static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
- u32 ext_phy_type;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+ u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
+ (params->loopback_mode == LOOPBACK_XGXS));
+ if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
+ if (SINGLE_MEDIA_DIRECT(params) &&
+ (params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
+ bnx2x_set_preemphasis(phy, params);
- DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* The PHY reset is controled by GPIO 1
- * Give it 1ms of reset pulse
- */
- if (vars->phy_flags & PHY_XGXS_FLAG) {
+ /* forced speed requested? */
+ if (vars->line_speed != SPEED_AUTO_NEG ||
+ (SINGLE_MEDIA_DIRECT(params) &&
+ params->loopback_mode == LOOPBACK_EXT)) {
+ DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "XGXS Direct\n");
- break;
+ /* disable autoneg */
+ bnx2x_set_autoneg(phy, params, vars, 0);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
+ /* program speed and duplex */
+ bnx2x_program_serdes(phy, params, vars);
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ } else { /* AN_mode */
+ DP(NETIF_MSG_LINK, "not SGMII, AN\n");
- /* HW reset */
- bnx2x_ext_phy_hw_reset(bp, params->port);
+ /* AN enabled */
+ bnx2x_set_brcm_cl37_advertisment(phy, params);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0xa040);
- break;
+ /* program duplex & pause advertisement (for aneg) */
+ bnx2x_set_ieee_aneg_advertisment(phy, params,
+ vars->ieee_fc);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- break;
+ /* enable autoneg */
+ bnx2x_set_autoneg(phy, params, vars, enable_cl73);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ /* enable and restart AN */
+ bnx2x_restart_autoneg(phy, params, enable_cl73);
+ }
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ } else { /* SGMII mode */
+ DP(NETIF_MSG_LINK, "SGMII\n");
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ bnx2x_initialize_sgmii_process(phy, params, vars);
+ }
+}
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 1<<15);
- break;
+static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ u8 rc;
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
+ bnx2x_set_aer_mmd_serdes(params->bp, phy);
+ rc = bnx2x_reset_unicore(params, phy, 1);
+ /* reset the SerDes and wait for reset bit return low */
+ if (rc != 0)
+ return rc;
+ bnx2x_set_aer_mmd_serdes(params->bp, phy);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- DP(NETIF_MSG_LINK, "XGXS 8072\n");
+ return rc;
+}
- /* Unset Low Power Mode and SW reset */
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ u8 rc;
+ vars->phy_flags = PHY_XGXS_FLAG;
+ if ((phy->req_line_speed &&
+ ((phy->req_line_speed == SPEED_100) ||
+ (phy->req_line_speed == SPEED_10))) ||
+ (!phy->req_line_speed &&
+ (phy->speed_cap_mask >=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
+ (phy->speed_cap_mask <
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+ ))
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ else
+ vars->phy_flags &= ~PHY_SGMII_FLAG;
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 1<<15);
- break;
+ bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
+ bnx2x_set_aer_mmd_xgxs(params, phy);
+ bnx2x_set_master_ln(params, phy);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- DP(NETIF_MSG_LINK, "XGXS 8073\n");
+ rc = bnx2x_reset_unicore(params, phy, 0);
+ /* reset the SerDes and wait for reset bit return low */
+ if (rc != 0)
+ return rc;
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ bnx2x_set_aer_mmd_xgxs(params, phy);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ /* setting the masterLn_def again after the reset */
+ bnx2x_set_master_ln(params, phy);
+ bnx2x_set_swap_lanes(params, phy);
+
+ return rc;
+}
+
+static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
+ struct bnx2x_phy *phy)
+{
+ u16 cnt, ctrl;
+ /* Wait for soft reset to get cleared upto 1 sec */
+ for (cnt = 0; cnt < 1000; cnt++) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl);
+ if (!(ctrl & (1<<15)))
break;
+ msleep(1);
+ }
+ DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
+ return cnt;
+}
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
+static void bnx2x_link_int_enable(struct link_params *params)
+{
+ u8 port = params->port;
+ u32 mask;
+ struct bnx2x *bp = params->bp;
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ /* setting the status to report on link up
+ for either XGXS or SerDes */
- /* HW reset */
- bnx2x_ext_phy_hw_reset(bp, params->port);
- break;
+ if (params->switch_cfg == SWITCH_CFG_10G) {
+ mask = (NIG_MASK_XGXS0_LINK10G |
+ NIG_MASK_XGXS0_LINK_STATUS);
+ DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
+ if (!(SINGLE_MEDIA_DIRECT(params)) &&
+ params->phy[INT_PHY].type !=
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
+ mask |= NIG_MASK_MI_INT;
+ DP(NETIF_MSG_LINK, "enabled external phy int\n");
+ }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ } else { /* SerDes */
+ mask = NIG_MASK_SERDES0_LINK_STATUS;
+ DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
+ if (!(SINGLE_MEDIA_DIRECT(params)) &&
+ params->phy[INT_PHY].type !=
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
+ mask |= NIG_MASK_MI_INT;
+ DP(NETIF_MSG_LINK, "enabled external phy int\n");
+ }
+ }
+ bnx2x_bits_en(bp,
+ NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+ mask);
+
+ DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
+ (params->switch_cfg == SWITCH_CFG_10G),
+ REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
+ DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
+ REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+ REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
+ REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
+ DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
+}
- /* HW reset */
- bnx2x_ext_phy_hw_reset(bp, params->port);
+static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
+ u8 exp_mi_int)
+{
+ u32 latch_status = 0;
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 1<<15);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
- break;
+ /**
+ * Disable the MI INT ( external phy int ) by writing 1 to the
+ * status register. Link down indication is high-active-signal,
+ * so in this case we need to write the status to clear the XOR
+ */
+ /* Read Latched signals */
+ latch_status = REG_RD(bp,
+ NIG_REG_LATCH_STATUS_0 + port*8);
+ DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
+ /* Handle only those with latched-signal=up.*/
+ if (exp_mi_int)
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0
+ + port*4,
+ NIG_STATUS_EMAC0_MI_INT);
+ else
+ bnx2x_bits_dis(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0
+ + port*4,
+ NIG_STATUS_EMAC0_MI_INT);
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- params->ext_phy_config);
- break;
+ if (latch_status & 1) {
+
+ /* For all latched-signal=up : Re-Arm Latch signals */
+ REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
+ (latch_status & 0xfffe) | (latch_status & 1));
+ }
+ /* For all latched-signal=up,Write original_signal to status */
+}
+
+static void bnx2x_link_int_ack(struct link_params *params,
+ struct link_vars *vars, u8 is_10g)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+
+ /* first reset all status
+ * we assume only one line will be change at a time */
+ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ (NIG_STATUS_XGXS0_LINK10G |
+ NIG_STATUS_XGXS0_LINK_STATUS |
+ NIG_STATUS_SERDES0_LINK_STATUS));
+ if (vars->phy_link_up) {
+ if (is_10g) {
+ /* Disable the 10G link interrupt
+ * by writing 1 to the status register
+ */
+ DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ NIG_STATUS_XGXS0_LINK10G);
+
+ } else if (params->switch_cfg == SWITCH_CFG_10G) {
+ /* Disable the link interrupt
+ * by writing 1 to the relevant lane
+ * in the status register
+ */
+ u32 ser_lane = ((params->lane_config &
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
+
+ DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
+ vars->line_speed);
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ ((1 << ser_lane) <<
+ NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
+
+ } else { /* SerDes */
+ DP(NETIF_MSG_LINK, "SerDes phy link up\n");
+ /* Disable the link interrupt
+ * by writing 1 to the status register
+ */
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ NIG_STATUS_SERDES0_LINK_STATUS);
}
- } else { /* SerDes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- break;
+ }
+}
+
+static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
+{
+ u8 *str_ptr = str;
+ u32 mask = 0xf0000000;
+ u8 shift = 8*4;
+ u8 digit;
+ u8 remove_leading_zeros = 1;
+ if (*len < 10) {
+ /* Need more than 10chars for this format */
+ *str_ptr = '\0';
+ (*len)--;
+ return -EINVAL;
+ }
+ while (shift > 0) {
+
+ shift -= 4;
+ digit = ((num & mask) >> shift);
+ if (digit == 0 && remove_leading_zeros) {
+ mask = mask >> 4;
+ continue;
+ } else if (digit < 0xa)
+ *str_ptr = digit + '0';
+ else
+ *str_ptr = digit - 0xa + 'a';
+ remove_leading_zeros = 0;
+ str_ptr++;
+ (*len)--;
+ mask = mask >> 4;
+ if (shift == 4*4) {
+ *str_ptr = '.';
+ str_ptr++;
+ (*len)--;
+ remove_leading_zeros = 1;
+ }
+ }
+ return 0;
+}
+
+
+static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
+{
+ str[0] = '\0';
+ (*len)--;
+ return 0;
+}
+
+u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
+ u8 *version, u16 len)
+{
+ struct bnx2x *bp;
+ u32 spirom_ver = 0;
+ u8 status = 0;
+ u8 *ver_p = version;
+ u16 remain_len = len;
+ if (version == NULL || params == NULL)
+ return -EINVAL;
+ bp = params->bp;
+
+ /* Extract first external phy*/
+ version[0] = '\0';
+ spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
+
+ if (params->phy[EXT_PHY1].format_fw_ver) {
+ status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
+ ver_p,
+ &remain_len);
+ ver_p += (len - remain_len);
+ }
+ if ((params->num_phys == MAX_PHYS) &&
+ (params->phy[EXT_PHY2].ver_addr != 0)) {
+ spirom_ver = REG_RD(bp,
+ params->phy[EXT_PHY2].ver_addr);
+ if (params->phy[EXT_PHY2].format_fw_ver) {
+ *ver_p = '/';
+ ver_p++;
+ remain_len--;
+ status |= params->phy[EXT_PHY2].format_fw_ver(
+ spirom_ver,
+ ver_p,
+ &remain_len);
+ ver_p = version + (len - remain_len);
+ }
+ }
+ *ver_p = '\0';
+ return status;
+}
+
+static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ u8 port = params->port;
+ struct bnx2x *bp = params->bp;
+
+ if (phy->req_line_speed != SPEED_1000) {
+ u32 md_devad;
+
+ DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
+
+ /* change the uni_phy_addr in the nig */
+ md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
+ port*0x18));
+
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
+
+ bnx2x_cl45_write(bp, phy,
+ 5,
+ (MDIO_REG_BANK_AER_BLOCK +
+ (MDIO_AER_BLOCK_AER_REG & 0xf)),
+ 0x2800);
+
+ bnx2x_cl45_write(bp, phy,
+ 5,
+ (MDIO_REG_BANK_CL73_IEEEB0 +
+ (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
+ 0x6041);
+ msleep(200);
+ /* set aer mmd back */
+ bnx2x_set_aer_mmd_xgxs(params, phy);
+
+ /* and md_devad */
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
+ md_devad);
+
+ } else {
+ u16 mii_ctrl;
+ DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
+ bnx2x_cl45_read(bp, phy, 5,
+ (MDIO_REG_BANK_COMBO_IEEE0 +
+ (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
+ &mii_ctrl);
+ bnx2x_cl45_write(bp, phy, 5,
+ (MDIO_REG_BANK_COMBO_IEEE0 +
+ (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
+ mii_ctrl |
+ MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
+ }
+}
+
+/*
+ *------------------------------------------------------------------------
+ * bnx2x_override_led_value -
+ *
+ * Override the led value of the requested led
+ *
+ *------------------------------------------------------------------------
+ */
+u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
+ u32 led_idx, u32 value)
+{
+ u32 reg_val;
+
+ /* If port 0 then use EMAC0, else use EMAC1*/
+ u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
+ DP(NETIF_MSG_LINK,
+ "bnx2x_override_led_value() port %x led_idx %d value %d\n",
+ port, led_idx, value);
+
+ switch (led_idx) {
+ case 0: /* 10MB led */
+ /* Read the current value of the LED register in
+ the EMAC block */
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 10M_OVERRIDE bit,
+ otherwise reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_10MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 1: /*100MB led */
+ /*Read the current value of the LED register in
+ the EMAC block */
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 100M_OVERRIDE bit,
+ otherwise reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_100MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 2: /* 1000MB led */
+ /* Read the current value of the LED register in the
+ EMAC block */
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
+ reset it. */
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 3: /* 2500MB led */
+ /* Read the current value of the LED register in the
+ EMAC block*/
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
+ reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 4: /*10G led */
+ if (port == 0) {
+ REG_WR(bp, NIG_REG_LED_10G_P0,
+ value);
+ } else {
+ REG_WR(bp, NIG_REG_LED_10G_P1,
+ value);
+ }
+ break;
+ case 5: /* TRAFFIC led */
+ /* Find if the traffic control is via BMAC or EMAC */
+ if (port == 0)
+ reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
+ else
+ reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
+
+ /* Override the traffic led in the EMAC:*/
+ if (reg_val == 1) {
+ /* Read the current value of the LED register in
+ the EMAC block */
+ reg_val = REG_RD(bp, emac_base +
+ EMAC_REG_EMAC_LED);
+ /* Set the TRAFFIC_OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the TRAFFIC bit, otherwise
+ reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
+ (reg_val & ~EMAC_LED_TRAFFIC);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ } else { /* Override the traffic led in the BMAC: */
+ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+ + port*4, 1);
+ REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
+ value);
+ }
+ break;
+ default:
+ DP(NETIF_MSG_LINK,
+ "bnx2x_override_led_value() unknown led index %d "
+ "(should be 0-5)\n", led_idx);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- bnx2x_ext_phy_hw_reset(bp, params->port);
+u8 bnx2x_set_led(struct link_params *params,
+ struct link_vars *vars, u8 mode, u32 speed)
+{
+ u8 port = params->port;
+ u16 hw_led_mode = params->hw_led_mode;
+ u8 rc = 0, phy_idx;
+ u32 tmp;
+ u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
+ DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
+ speed, hw_led_mode);
+ /* In case */
+ for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
+ if (params->phy[phy_idx].set_link_led) {
+ params->phy[phy_idx].set_link_led(
+ &params->phy[phy_idx], params, mode);
+ }
+ }
+
+ switch (mode) {
+ case LED_MODE_FRONT_PANEL_OFF:
+ case LED_MODE_OFF:
+ REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
+ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
+ SHARED_HW_CFG_LED_MAC1);
+
+ tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
+ EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
+ break;
+
+ case LED_MODE_OPER:
+ /**
+ * For all other phys, OPER mode is same as ON, so in case
+ * link is down, do nothing
+ **/
+ if (!vars->link_up)
break;
+ case LED_MODE_ON:
+ if (SINGLE_MEDIA_DIRECT(params)) {
+ /**
+ * This is a work-around for HW issue found when link
+ * is up in CL73
+ */
+ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
+ REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
+ } else {
+ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
+ hw_led_mode);
+ }
- default:
- DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
- params->ext_phy_config);
+ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
+ port*4, 0);
+ /* Set blinking rate to ~15.9Hz */
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
+ LED_BLINK_RATE_VAL);
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
+ port*4, 1);
+ tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
+ EMAC_WR(bp, EMAC_REG_EMAC_LED,
+ (tmp & (~EMAC_LED_OVERRIDE)));
+
+ if (CHIP_IS_E1(bp) &&
+ ((speed == SPEED_2500) ||
+ (speed == SPEED_1000) ||
+ (speed == SPEED_100) ||
+ (speed == SPEED_10))) {
+ /* On Everest 1 Ax chip versions for speeds less than
+ 10G LED scheme is different */
+ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+ + port*4, 1);
+ REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
+ port*4, 0);
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
+ port*4, 1);
+ }
+ break;
+
+ default:
+ rc = -EINVAL;
+ DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
+ mode);
+ break;
+ }
+ return rc;
+
+}
+
+/**
+ * This function comes to reflect the actual link state read DIRECTLY from the
+ * HW
+ */
+u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars,
+ u8 is_serdes)
+{
+ struct bnx2x *bp = params->bp;
+ u16 gp_status = 0, phy_index = 0;
+ u8 ext_phy_link_up = 0, serdes_phy_type;
+ struct link_vars temp_vars;
+
+ CL45_RD_OVER_CL22(bp, &params->phy[INT_PHY],
+ MDIO_REG_BANK_GP_STATUS,
+ MDIO_GP_STATUS_TOP_AN_STATUS1,
+ &gp_status);
+ /* link is up only if both local phy and external phy are up */
+ if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
+ return -ESRCH;
+
+ switch (params->num_phys) {
+ case 1:
+ /* No external PHY */
+ return 0;
+ case 2:
+ ext_phy_link_up = params->phy[EXT_PHY1].read_status(
+ &params->phy[EXT_PHY1],
+ params, &temp_vars);
+ break;
+ case 3: /* Dual Media */
+ for (phy_index = EXT_PHY1; phy_index < params->num_phys;
+ phy_index++) {
+ serdes_phy_type = ((params->phy[phy_index].media_type ==
+ ETH_PHY_SFP_FIBER) ||
+ (params->phy[phy_index].media_type ==
+ ETH_PHY_XFP_FIBER));
+
+ if (is_serdes != serdes_phy_type)
+ continue;
+ if (params->phy[phy_index].read_status) {
+ ext_phy_link_up |=
+ params->phy[phy_index].read_status(
+ &params->phy[phy_index],
+ params, &temp_vars);
+ }
+ }
+ break;
+ }
+ if (ext_phy_link_up)
+ return 0;
+ return -ESRCH;
+}
+
+static u8 bnx2x_link_initialize(struct link_params *params,
+ struct link_vars *vars)
+{
+ u8 rc = 0;
+ u8 phy_index, non_ext_phy;
+ struct bnx2x *bp = params->bp;
+ /**
+ * In case of external phy existence, the line speed would be the
+ * line speed linked up by the external phy. In case it is direct
+ * only, then the line_speed during initialization will be
+ * equal to the req_line_speed
+ */
+ vars->line_speed = params->phy[INT_PHY].req_line_speed;
+
+ /**
+ * Initialize the internal phy in case this is a direct board
+ * (no external phys), or this board has external phy which requires
+ * to first.
+ */
+
+ if (params->phy[INT_PHY].config_init)
+ params->phy[INT_PHY].config_init(
+ &params->phy[INT_PHY],
+ params, vars);
+
+ /* init ext phy and enable link state int */
+ non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
+ (params->loopback_mode == LOOPBACK_XGXS));
+
+ if (non_ext_phy ||
+ (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
+ (params->loopback_mode == LOOPBACK_EXT_PHY)) {
+ struct bnx2x_phy *phy = &params->phy[INT_PHY];
+ if (vars->line_speed == SPEED_AUTO_NEG)
+ bnx2x_set_parallel_detection(phy, params);
+ bnx2x_init_internal_phy(phy, params, vars);
+ }
+
+ /* Init external phy*/
+ if (!non_ext_phy)
+ for (phy_index = EXT_PHY1; phy_index < params->num_phys;
+ phy_index++) {
+ /**
+ * No need to initialize second phy in case of first
+ * phy only selection. In case of second phy, we do
+ * need to initialize the first phy, since they are
+ * connected.
+ **/
+ if (phy_index == EXT_PHY2 &&
+ (bnx2x_phy_selection(params) ==
+ PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
+ DP(NETIF_MSG_LINK, "Not initializing"
+ "second phy\n");
+ continue;
+ }
+ params->phy[phy_index].config_init(
+ &params->phy[phy_index],
+ params, vars);
+ }
+
+ /* Reset the interrupt indication after phy was initialized */
+ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
+ params->port*4,
+ (NIG_STATUS_XGXS0_LINK10G |
+ NIG_STATUS_XGXS0_LINK_STATUS |
+ NIG_STATUS_SERDES0_LINK_STATUS |
+ NIG_MASK_MI_INT));
+ return rc;
+}
+
+static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ /* reset the SerDes/XGXS */
+ REG_WR(params->bp, GRCBASE_MISC +
+ MISC_REGISTERS_RESET_REG_3_CLEAR,
+ (0x1ff << (params->port*16)));
+}
+
+static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 gpio_port;
+ /* HW reset */
+ if (CHIP_IS_E2(bp))
+ gpio_port = BP_PATH(bp);
+ else
+ gpio_port = params->port;
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW,
+ gpio_port);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW,
+ gpio_port);
+ DP(NETIF_MSG_LINK, "reset external PHY\n");
+}
+
+static u8 bnx2x_update_link_down(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+
+ DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
+ bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
+
+ /* indicate no mac active */
+ vars->mac_type = MAC_TYPE_NONE;
+
+ /* update shared memory */
+ vars->link_status = 0;
+ vars->line_speed = 0;
+ bnx2x_update_mng(params, vars->link_status);
+
+ /* activate nig drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+ msleep(10);
+
+ /* reset BigMac */
+ bnx2x_bmac_rx_disable(bp, params->port);
+ REG_WR(bp, GRCBASE_MISC +
+ MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+ return 0;
+}
+
+static u8 bnx2x_update_link_up(struct link_params *params,
+ struct link_vars *vars,
+ u8 link_10g)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u8 rc = 0;
+
+ vars->link_status |= LINK_STATUS_LINK_UP;
+
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ vars->link_status |=
+ LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
+
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
+ vars->link_status |=
+ LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
+
+ if (link_10g) {
+ bnx2x_bmac_enable(params, vars, 0);
+ bnx2x_set_led(params, vars,
+ LED_MODE_OPER, SPEED_10000);
+ } else {
+ rc = bnx2x_emac_program(params, vars);
+
+ bnx2x_emac_enable(params, vars, 0);
+
+ /* AN complete? */
+ if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
+ && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
+ SINGLE_MEDIA_DIRECT(params))
+ bnx2x_set_gmii_tx_driver(params);
+ }
+
+ /* PBF - link up */
+ if (!(CHIP_IS_E2(bp)))
+ rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
+ vars->line_speed);
+
+ /* disable drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
+
+ /* update shared memory */
+ bnx2x_update_mng(params, vars->link_status);
+ msleep(20);
+ return rc;
+}
+/**
+ * The bnx2x_link_update function should be called upon link
+ * interrupt.
+ * Link is considered up as follows:
+ * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
+ * to be up
+ * - SINGLE_MEDIA - The link between the 577xx and the external
+ * phy (XGXS) need to up as well as the external link of the
+ * phy (PHY_EXT1)
+ * - DUAL_MEDIA - The link between the 577xx and the first
+ * external phy needs to be up, and at least one of the 2
+ * external phy link must be up.
+ */
+u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ struct link_vars phy_vars[MAX_PHYS];
+ u8 port = params->port;
+ u8 link_10g, phy_index;
+ u8 ext_phy_link_up = 0, cur_link_up, rc = 0;
+ u8 is_mi_int = 0;
+ u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
+ u8 active_external_phy = INT_PHY;
+ vars->link_status = 0;
+ for (phy_index = INT_PHY; phy_index < params->num_phys;
+ phy_index++) {
+ phy_vars[phy_index].flow_ctrl = 0;
+ phy_vars[phy_index].link_status = 0;
+ phy_vars[phy_index].line_speed = 0;
+ phy_vars[phy_index].duplex = DUPLEX_FULL;
+ phy_vars[phy_index].phy_link_up = 0;
+ phy_vars[phy_index].link_up = 0;
+ }
+
+ DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
+ port, (vars->phy_flags & PHY_XGXS_FLAG),
+ REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
+
+ is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
+ port*0x18) > 0);
+ DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
+ REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+ is_mi_int,
+ REG_RD(bp,
+ NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
+
+ DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
+
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+ /**
+ * Step 1:
+ * Check external link change only for external phys, and apply
+ * priority selection between them in case the link on both phys
+ * is up. Note that the instead of the common vars, a temporary
+ * vars argument is used since each phy may have different link/
+ * speed/duplex result
+ */
+ for (phy_index = EXT_PHY1; phy_index < params->num_phys;
+ phy_index++) {
+ struct bnx2x_phy *phy = &params->phy[phy_index];
+ if (!phy->read_status)
+ continue;
+ /* Read link status and params of this ext phy */
+ cur_link_up = phy->read_status(phy, params,
+ &phy_vars[phy_index]);
+ if (cur_link_up) {
+ DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
+ phy_index);
+ } else {
+ DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
+ phy_index);
+ continue;
+ }
+
+ if (!ext_phy_link_up) {
+ ext_phy_link_up = 1;
+ active_external_phy = phy_index;
+ } else {
+ switch (bnx2x_phy_selection(params)) {
+ case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
+ /**
+ * In this option, the first PHY makes sure to pass the
+ * traffic through itself only.
+ * Its not clear how to reset the link on the second phy
+ **/
+ active_external_phy = EXT_PHY1;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
+ /**
+ * In this option, the first PHY makes sure to pass the
+ * traffic through the second PHY.
+ **/
+ active_external_phy = EXT_PHY2;
+ break;
+ default:
+ /**
+ * Link indication on both PHYs with the following cases
+ * is invalid:
+ * - FIRST_PHY means that second phy wasn't initialized,
+ * hence its link is expected to be down
+ * - SECOND_PHY means that first phy should not be able
+ * to link up by itself (using configuration)
+ * - DEFAULT should be overriden during initialiazation
+ **/
+ DP(NETIF_MSG_LINK, "Invalid link indication"
+ "mpc=0x%x. DISABLING LINK !!!\n",
+ params->multi_phy_config);
+ ext_phy_link_up = 0;
+ break;
+ }
+ }
+ }
+ prev_line_speed = vars->line_speed;
+ /**
+ * Step 2:
+ * Read the status of the internal phy. In case of
+ * DIRECT_SINGLE_MEDIA board, this link is the external link,
+ * otherwise this is the link between the 577xx and the first
+ * external phy
+ */
+ if (params->phy[INT_PHY].read_status)
+ params->phy[INT_PHY].read_status(
+ &params->phy[INT_PHY],
+ params, vars);
+ /**
+ * The INT_PHY flow control reside in the vars. This include the
+ * case where the speed or flow control are not set to AUTO.
+ * Otherwise, the active external phy flow control result is set
+ * to the vars. The ext_phy_line_speed is needed to check if the
+ * speed is different between the internal phy and external phy.
+ * This case may be result of intermediate link speed change.
+ */
+ if (active_external_phy > INT_PHY) {
+ vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
+ /**
+ * Link speed is taken from the XGXS. AN and FC result from
+ * the external phy.
+ */
+ vars->link_status |= phy_vars[active_external_phy].link_status;
+
+ /**
+ * if active_external_phy is first PHY and link is up - disable
+ * disable TX on second external PHY
+ */
+ if (active_external_phy == EXT_PHY1) {
+ if (params->phy[EXT_PHY2].phy_specific_func) {
+ DP(NETIF_MSG_LINK, "Disabling TX on"
+ " EXT_PHY2\n");
+ params->phy[EXT_PHY2].phy_specific_func(
+ &params->phy[EXT_PHY2],
+ params, DISABLE_TX);
+ }
+ }
+
+ ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
+ vars->duplex = phy_vars[active_external_phy].duplex;
+ if (params->phy[active_external_phy].supported &
+ SUPPORTED_FIBRE)
+ vars->link_status |= LINK_STATUS_SERDES_LINK;
+ DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
+ active_external_phy);
+ }
+
+ for (phy_index = EXT_PHY1; phy_index < params->num_phys;
+ phy_index++) {
+ if (params->phy[phy_index].flags &
+ FLAGS_REARM_LATCH_SIGNAL) {
+ bnx2x_rearm_latch_signal(bp, port,
+ phy_index ==
+ active_external_phy);
break;
}
}
+ DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
+ " ext_phy_line_speed = %d\n", vars->flow_ctrl,
+ vars->link_status, ext_phy_line_speed);
+ /**
+ * Upon link speed change set the NIG into drain mode. Comes to
+ * deals with possible FIFO glitch due to clk change when speed
+ * is decreased without link down indicator
+ */
+
+ if (vars->phy_link_up) {
+ if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
+ (ext_phy_line_speed != vars->line_speed)) {
+ DP(NETIF_MSG_LINK, "Internal link speed %d is"
+ " different than the external"
+ " link speed %d\n", vars->line_speed,
+ ext_phy_line_speed);
+ vars->phy_link_up = 0;
+ } else if (prev_line_speed != vars->line_speed) {
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
+ + params->port*4, 0);
+ msleep(1);
+ }
+ }
+
+ /* anything 10 and over uses the bmac */
+ link_10g = ((vars->line_speed == SPEED_10000) ||
+ (vars->line_speed == SPEED_12000) ||
+ (vars->line_speed == SPEED_12500) ||
+ (vars->line_speed == SPEED_13000) ||
+ (vars->line_speed == SPEED_15000) ||
+ (vars->line_speed == SPEED_16000));
+
+ bnx2x_link_int_ack(params, vars, link_10g);
+
+ /**
+ * In case external phy link is up, and internal link is down
+ * (not initialized yet probably after link initialization, it
+ * needs to be initialized.
+ * Note that after link down-up as result of cable plug, the xgxs
+ * link would probably become up again without the need
+ * initialize it
+ */
+ if (!(SINGLE_MEDIA_DIRECT(params))) {
+ DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
+ " init_preceding = %d\n", ext_phy_link_up,
+ vars->phy_link_up,
+ params->phy[EXT_PHY1].flags &
+ FLAGS_INIT_XGXS_FIRST);
+ if (!(params->phy[EXT_PHY1].flags &
+ FLAGS_INIT_XGXS_FIRST)
+ && ext_phy_link_up && !vars->phy_link_up) {
+ vars->line_speed = ext_phy_line_speed;
+ if (vars->line_speed < SPEED_1000)
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ else
+ vars->phy_flags &= ~PHY_SGMII_FLAG;
+ bnx2x_init_internal_phy(&params->phy[INT_PHY],
+ params,
+ vars);
+ }
+ }
+ /**
+ * Link is up only if both local phy and external phy (in case of
+ * non-direct board) are up
+ */
+ vars->link_up = (vars->phy_link_up &&
+ (ext_phy_link_up ||
+ SINGLE_MEDIA_DIRECT(params)));
+
+ if (vars->link_up)
+ rc = bnx2x_update_link_up(params, vars, link_10g);
+ else
+ rc = bnx2x_update_link_down(params, vars);
+
+ return rc;
+}
+
+
+/*****************************************************************************/
+/* External Phy section */
+/*****************************************************************************/
+void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
+{
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
+ msleep(1);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
}
static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
- u32 shmem_base, u32 spirom_ver)
+ u32 spirom_ver, u32 ver_addr)
{
DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
(u16)(spirom_ver>>16), (u16)spirom_ver, port);
- REG_WR(bp, shmem_base +
- offsetof(struct shmem_region,
- port_mb[port].ext_phy_fw_version),
- spirom_ver);
+
+ if (ver_addr)
+ REG_WR(bp, ver_addr, spirom_ver);
}
-static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
- u32 ext_phy_type, u8 ext_phy_addr,
- u32 shmem_base)
+static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ u8 port)
{
u16 fw_ver1, fw_ver2;
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2, &fw_ver2);
- bnx2x_save_spirom_version(bp, port, shmem_base,
- (u32)(fw_ver1<<16 | fw_ver2));
+ bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
+ phy->ver_addr);
}
-
-static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr, u32 shmem_base)
+static void bnx2x_ext_phy_set_pause(struct link_params *params,
+ struct bnx2x_phy *phy,
+ struct link_vars *vars)
{
- u16 val, fw_ver1, fw_ver2, cnt;
- /* For the 32 bits registers in 8481, access via MDIO2ARM interface.*/
- /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr, MDIO_PMA_DEVAD,
- 0xA819, 0x0014);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA81A,
- 0xc200);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA81B,
- 0x0000);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA81C,
- 0x0300);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA817,
- 0x0009);
+ u16 val;
+ struct bnx2x *bp = params->bp;
+ /* read modify write pause advertizing */
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
- for (cnt = 0; cnt < 100; cnt++) {
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA818,
- &val);
- if (val & 1)
- break;
- udelay(5);
+ val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
+
+ /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+ bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
+ if ((vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
+ val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
}
- if (cnt == 100) {
- DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n");
- bnx2x_save_spirom_version(bp, port,
- shmem_base, 0);
- return;
+ if ((vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
+ val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
}
+ DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
+}
+static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u16 ld_pause; /* local */
+ u16 lp_pause; /* link partner */
+ u16 pause_result;
+ u8 ret = 0;
+ /* read twice */
- /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr, MDIO_PMA_DEVAD,
- 0xA819, 0x0000);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr, MDIO_PMA_DEVAD,
- 0xA81A, 0xc200);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr, MDIO_PMA_DEVAD,
- 0xA817, 0x000A);
- for (cnt = 0; cnt < 100; cnt++) {
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA818,
- &val);
- if (val & 1)
- break;
- udelay(5);
+ vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+
+ if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
+ vars->flow_ctrl = phy->req_flow_ctrl;
+ else if (phy->req_line_speed != SPEED_AUTO_NEG)
+ vars->flow_ctrl = params->req_fc_auto_adv;
+ else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
+ ret = 1;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV_PAUSE, &ld_pause);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
+ pause_result = (ld_pause &
+ MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
+ pause_result |= (lp_pause &
+ MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
+ DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
+ pause_result);
+ bnx2x_pause_resolve(vars, pause_result);
}
- if (cnt == 100) {
- DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(2)\n");
- bnx2x_save_spirom_version(bp, port,
- shmem_base, 0);
+ return ret;
+}
+
+static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ struct link_vars *vars)
+{
+ u16 val;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_STATUS, &val);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_STATUS, &val);
+ if (val & (1<<5))
+ vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
+ if ((val & (1<<0)) == 0)
+ vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
+}
+
+/******************************************************************/
+/* common BCM8073/BCM8727 PHY SECTION */
+/******************************************************************/
+static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ if (phy->req_line_speed == SPEED_10 ||
+ phy->req_line_speed == SPEED_100) {
+ vars->flow_ctrl = phy->req_flow_ctrl;
return;
}
- /* lower 16 bits of the register SPI_FW_STATUS */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA81B,
- &fw_ver1);
- /* upper 16 bits of register SPI_FW_STATUS */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA81C,
- &fw_ver2);
+ if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
+ (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
+ u16 pause_result;
+ u16 ld_pause; /* local */
+ u16 lp_pause; /* link partner */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_FC_LD, &ld_pause);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_FC_LP, &lp_pause);
+ pause_result = (ld_pause &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
+ pause_result |= (lp_pause &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
- bnx2x_save_spirom_version(bp, port,
- shmem_base, (fw_ver2<<16) | fw_ver1);
+ bnx2x_pause_resolve(vars, pause_result);
+ DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
+ pause_result);
+ }
}
-static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
+static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ u8 port)
{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ /* Boot port from external ROM */
+ /* EDC grst */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ 0x0001);
- /* Need to wait 200ms after reset */
- msleep(200);
- /* Boot port from external ROM
- * Set ser_boot_ctl bit in the MISC_CTRL1 register
- */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0001);
+ /* ucode reboot and rst */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ 0x008c);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0001);
/* Reset internal microprocessor */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
- /* set micro reset = 0 */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
- /* Reset internal microprocessor */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
- /* wait for 100ms for code download via SPI port */
- msleep(100);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
+
+ /* Release srst bit */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+
+ /* wait for 120ms for code download via SPI port */
+ msleep(120);
/* Clear ser_boot_ctl bit */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0000);
- /* Wait 100ms */
- msleep(100);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+ bnx2x_save_bcm_spirom_ver(bp, phy, port);
+}
+
+static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp,
+ struct bnx2x_phy *phy)
+{
+ u16 val;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val);
+
+ if (val == 0) {
+ /* Mustn't set low power mode in 8073 A0 */
+ return;
+ }
+
+ /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
+ val &= ~(1<<13);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
- bnx2x_save_bcm_spirom_ver(bp, port,
- ext_phy_type,
- ext_phy_addr,
- params->shmem_base);
+ /* PLL controls */
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490);
+
+ /* Tx Controls */
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640);
+
+ /* Rx Controls */
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015);
+
+ /* Enable PLL sequencer (use read-modify-write to set bit 13) */
+ bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
+ val |= (1<<13);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
}
-static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
+/******************************************************************/
+/* BCM8073 PHY SECTION */
+/******************************************************************/
+static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
{
/* This is only required for 8073A1, version 102 only */
-
- struct bnx2x *bp = params->bp;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u16 val;
/* Read 8073 HW revision*/
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8073_CHIP_REV, &val);
@@ -2431,9 +3484,7 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
return 0;
}
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2, &val);
@@ -2444,15 +3495,11 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
return 1;
}
-static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
+static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
{
- struct bnx2x *bp = params->bp;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u16 val, cnt, cnt1 ;
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8073_CHIP_REV, &val);
@@ -2466,9 +3513,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
poll Dev1, Reg $C820: */
for (cnt = 0; cnt < 1000; cnt++) {
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
&val);
@@ -2485,9 +3530,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
XAUI workaround has completed),
then continue on with system initialization.*/
for (cnt1 = 0; cnt1 < 1000; cnt1++) {
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8073_XAUI_WA, &val);
if (val & (1<<15)) {
@@ -2505,143 +3548,391 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
return -EINVAL;
}
-static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr,
- u32 ext_phy_type,
- u32 shmem_base)
+static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
{
- /* Boot port from external ROM */
- /* EDC grst */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- 0x0001);
+ /* Force KR or KX */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
+}
- /* ucode reboot and rst */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- 0x008c);
+static void bnx2x_8073_set_pause_cl37(struct link_params *params,
+ struct bnx2x_phy *phy,
+ struct link_vars *vars)
+{
+ u16 cl37_val;
+ struct bnx2x *bp = params->bp;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0001);
+ cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+ bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
+ if ((vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
+ cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
+ }
+ if ((vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
+ cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ }
+ if ((vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
+ cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ }
+ DP(NETIF_MSG_LINK,
+ "Ext phy AN advertize cl37 0x%x\n", cl37_val);
- /* Reset internal microprocessor */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
+ msleep(500);
+}
- /* Release srst bit */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u16 val = 0, tmp1;
+ u8 gpio_port;
+ DP(NETIF_MSG_LINK, "Init 8073\n");
- /* wait for 100ms for code download via SPI port */
- msleep(100);
+ if (CHIP_IS_E2(bp))
+ gpio_port = BP_PATH(bp);
+ else
+ gpio_port = params->port;
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
- /* Clear ser_boot_ctl bit */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
- bnx2x_save_bcm_spirom_ver(bp, port,
- ext_phy_type,
- ext_phy_addr,
- shmem_base);
-}
+ /* enable LASI */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004);
-static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr,
- u32 shmem_base)
-{
- bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- shmem_base);
-}
+ bnx2x_8073_set_pause_cl37(params, phy, vars);
-static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr,
- u32 shmem_base)
-{
- bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- shmem_base);
+ bnx2x_8073_set_xaui_low_power_mode(bp, phy);
-}
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
-static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
- /* Need to wait 100ms after reset */
- msleep(100);
+ DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
- /* Micro controller re-boot */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- 0x018B);
+ /* Enable CL37 BAM */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8073_BAM, &val);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8073_BAM, val | 1);
- /* Set soft reset */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
+ if (params->loopback_mode == LOOPBACK_EXT) {
+ bnx2x_807x_force_10G(bp, phy);
+ DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
+ return 0;
+ } else {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
+ }
+ if (phy->req_line_speed != SPEED_AUTO_NEG) {
+ if (phy->req_line_speed == SPEED_10000) {
+ val = (1<<7);
+ } else if (phy->req_line_speed == SPEED_2500) {
+ val = (1<<5);
+ /* Note that 2.5G works only
+ when used with 1G advertisment */
+ } else
+ val = (1<<5);
+ } else {
+ val = 0;
+ if (phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
+ val |= (1<<7);
+
+ /* Note that 2.5G works only when
+ used with 1G advertisment */
+ if (phy->speed_cap_mask &
+ (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
+ val |= (1<<5);
+ DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
+ }
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0001);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
+
+ if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
+ (phy->req_line_speed == SPEED_AUTO_NEG)) ||
+ (phy->req_line_speed == SPEED_2500)) {
+ u16 phy_ver;
+ /* Allow 2.5G for A1 and above */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
+ &phy_ver);
+ DP(NETIF_MSG_LINK, "Add 2.5G\n");
+ if (phy_ver > 0)
+ tmp1 |= 1;
+ else
+ tmp1 &= 0xfffe;
+ } else {
+ DP(NETIF_MSG_LINK, "Disable 2.5G\n");
+ tmp1 &= 0xfffe;
+ }
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
+ /* Add support for CL37 (passive mode) II */
- /* wait for 150ms for microcode load */
- msleep(150);
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
+ (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
+ 0x20 : 0x40)));
- /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+ /* Add support for CL37 (passive mode) III */
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
- msleep(200);
- bnx2x_save_bcm_spirom_ver(bp, port,
- ext_phy_type,
- ext_phy_addr,
- params->shmem_base);
+ /* The SNR will improve about 2db by changing
+ BW and FEE main tap. Rest commands are executed
+ after link is up*/
+ if (bnx2x_8073_is_snr_needed(bp, phy))
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
+ 0xFB0C);
+
+ /* Enable FEC (Forware Error Correction) Request in the AN */
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
+ tmp1 |= (1<<15);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
+
+ bnx2x_ext_phy_set_pause(params, phy, vars);
+
+ /* Restart autoneg */
+ msleep(500);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
+ DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
+ ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
+ return 0;
+}
+
+static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 link_up = 0;
+ u16 val1, val2;
+ u16 link_status = 0;
+ u16 an1000_status = 0;
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
+
+ DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
+
+ /* clear the interrupt LASI status register */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
+ /* Clear MSG-OUT */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
+
+ /* Check the LASI */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
+
+ DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
+
+ /* Check the link status */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
+ DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
+ link_up = ((val1 & 4) == 4);
+ DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
+
+ if (link_up &&
+ ((phy->req_line_speed != SPEED_10000))) {
+ if (bnx2x_8073_xaui_wa(bp, phy) != 0)
+ return 0;
+ }
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
+
+ /* Check the link status on 1.1.2 */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
+ "an_link_status=0x%x\n", val2, val1, an1000_status);
+
+ link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
+ if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
+ /* The SNR will improve about 2dbby
+ changing the BW and FEE main tap.*/
+ /* The 1st write to change FFE main
+ tap is set before restart AN */
+ /* Change PLL Bandwidth in EDC
+ register */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
+ 0x26BC);
+
+ /* Change CDR Bandwidth in EDC register */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
+ 0x0333);
+ }
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
+ &link_status);
+
+ /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
+ if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
+ link_up = 1;
+ vars->line_speed = SPEED_10000;
+ DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
+ params->port);
+ } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
+ link_up = 1;
+ vars->line_speed = SPEED_2500;
+ DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
+ params->port);
+ } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
+ link_up = 1;
+ vars->line_speed = SPEED_1000;
+ DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
+ params->port);
+ } else {
+ link_up = 0;
+ DP(NETIF_MSG_LINK, "port %x: External link is down\n",
+ params->port);
+ }
+
+ if (link_up) {
+ bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
+ bnx2x_8073_resolve_fc(phy, params, vars);
+ }
+ return link_up;
+}
+
+static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 gpio_port;
+ if (CHIP_IS_E2(bp))
+ gpio_port = BP_PATH(bp);
+ else
+ gpio_port = params->port;
+ DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
+ gpio_port);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW,
+ gpio_port);
+}
+
+/******************************************************************/
+/* BCM8705 PHY SECTION */
+/******************************************************************/
+static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "init 8705\n");
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
+ /* HW reset */
+ bnx2x_ext_phy_hw_reset(bp, params->port);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
+ bnx2x_wait_reset_complete(bp, phy);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
+ /* BCM8705 doesn't have microcode, hence the 0 */
+ bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
+ return 0;
+}
+
+static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ u8 link_up = 0;
+ u16 val1, rx_sd;
+ struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "read status 8705\n");
+ bnx2x_cl45_read(bp, phy,
+ MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, 0xc809, &val1);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, 0xc809, &val1);
+
+ DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
+ link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
+ if (link_up) {
+ vars->line_speed = SPEED_10000;
+ bnx2x_ext_phy_resolve_fc(phy, params, vars);
+ }
+ return link_up;
}
-static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port,
- u32 ext_phy_type, u8 ext_phy_addr,
- u8 tx_en)
+/******************************************************************/
+/* SFP+ module Section */
+/******************************************************************/
+static void bnx2x_sfp_set_transmitter(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ u8 port,
+ u8 tx_en)
{
u16 val;
DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
tx_en, port);
/* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
&val);
@@ -2651,58 +3942,42 @@ static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port,
else
val |= (1<<15);
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
val);
}
-static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
+static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
+ struct link_params *params,
u16 addr, u8 byte_cnt, u8 *o_buf)
{
struct bnx2x *bp = params->bp;
u16 val = 0;
u16 i;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
if (byte_cnt > 16) {
DP(NETIF_MSG_LINK, "Reading from eeprom is"
" is limited to 0xf\n");
return -EINVAL;
}
/* Set the read command byte count */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
(byte_cnt | 0xa000));
/* Set the read command address */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
addr);
/* Activate read command */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
0x2c0f);
/* Wait up to 500us for command complete status */
for (i = 0; i < 100; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
@@ -2721,18 +3996,14 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
/* Read the buffer */
for (i = 0; i < byte_cnt; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
}
for (i = 0; i < 100; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
@@ -2743,14 +4014,12 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
return -EINVAL;
}
-static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
+static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
+ struct link_params *params,
u16 addr, u8 byte_cnt, u8 *o_buf)
{
struct bnx2x *bp = params->bp;
u16 val, i;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
if (byte_cnt > 16) {
DP(NETIF_MSG_LINK, "Reading from eeprom is"
@@ -2759,40 +4028,30 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
}
/* Need to read from 1.8000 to clear it */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
&val);
/* Set the read command byte count */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
((byte_cnt < 2) ? 2 : byte_cnt));
/* Set the read command address */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
addr);
/* Set the destination address */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
0x8004,
MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
/* Activate read command */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
0x8002);
@@ -2802,9 +4061,7 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
/* Wait up to 500us for command complete status */
for (i = 0; i < 100; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
@@ -2823,18 +4080,14 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
/* Read the buffer */
for (i = 0; i < byte_cnt; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
}
for (i = 0; i < 100; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
@@ -2846,21 +4099,21 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
return -EINVAL;
}
-u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
+u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
+ struct link_params *params, u16 addr,
u8 byte_cnt, u8 *o_buf)
{
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
- return bnx2x_8726_read_sfp_module_eeprom(params, addr,
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
+ return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
byte_cnt, o_buf);
- else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
- return bnx2x_8727_read_sfp_module_eeprom(params, addr,
+ else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
+ return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
byte_cnt, o_buf);
return -EINVAL;
}
-static u8 bnx2x_get_edc_mode(struct link_params *params,
+static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy,
+ struct link_params *params,
u16 *edc_mode)
{
struct bnx2x *bp = params->bp;
@@ -2868,10 +4121,11 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
*edc_mode = EDC_MODE_LIMITING;
/* First check for copper cable */
- if (bnx2x_read_sfp_module_eeprom(params,
- SFP_EEPROM_CON_TYPE_ADDR,
- 1,
- &val) != 0) {
+ if (bnx2x_read_sfp_module_eeprom(phy,
+ params,
+ SFP_EEPROM_CON_TYPE_ADDR,
+ 1,
+ &val) != 0) {
DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
return -EINVAL;
}
@@ -2883,7 +4137,8 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
/* Check if its active cable( includes SFP+ module)
of passive cable*/
- if (bnx2x_read_sfp_module_eeprom(params,
+ if (bnx2x_read_sfp_module_eeprom(phy,
+ params,
SFP_EEPROM_FC_TX_TECH_ADDR,
1,
&copper_module_type) !=
@@ -2923,10 +4178,11 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
if (check_limiting_mode) {
u8 options[SFP_EEPROM_OPTIONS_SIZE];
- if (bnx2x_read_sfp_module_eeprom(params,
- SFP_EEPROM_OPTIONS_ADDR,
- SFP_EEPROM_OPTIONS_SIZE,
- options) != 0) {
+ if (bnx2x_read_sfp_module_eeprom(phy,
+ params,
+ SFP_EEPROM_OPTIONS_ADDR,
+ SFP_EEPROM_OPTIONS_SIZE,
+ options) != 0) {
DP(NETIF_MSG_LINK, "Failed to read Option"
" field from module EEPROM\n");
return -EINVAL;
@@ -2939,17 +4195,17 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
return 0;
}
-
/* This function read the relevant field from the module ( SFP+ ),
and verify it is compliant with this board */
-static u8 bnx2x_verify_sfp_module(struct link_params *params)
+static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
- u32 val;
- u32 fw_resp;
+ u32 val, cmd;
+ u32 fw_resp, fw_cmd_param;
char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
-
+ phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
port_feature_config[params->port].config));
@@ -2959,29 +4215,44 @@ static u8 bnx2x_verify_sfp_module(struct link_params *params)
return 0;
}
- /* Ask the FW to validate the module */
- if (!(params->feature_config_flags &
- FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) {
+ if (params->feature_config_flags &
+ FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
+ /* Use specific phy request */
+ cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
+ } else if (params->feature_config_flags &
+ FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
+ /* Use first phy request only in case of non-dual media*/
+ if (DUAL_MEDIA(params)) {
+ DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
+ "verification\n");
+ return -EINVAL;
+ }
+ cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
+ } else {
+ /* No support in OPT MDL detection */
DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
- "verification\n");
+ "verification\n");
return -EINVAL;
}
- fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL);
+ fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
+ fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
DP(NETIF_MSG_LINK, "Approved module\n");
return 0;
}
/* format the warning message */
- if (bnx2x_read_sfp_module_eeprom(params,
+ if (bnx2x_read_sfp_module_eeprom(phy,
+ params,
SFP_EEPROM_VENDOR_NAME_ADDR,
SFP_EEPROM_VENDOR_NAME_SIZE,
(u8 *)vendor_name))
vendor_name[0] = '\0';
else
vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
- if (bnx2x_read_sfp_module_eeprom(params,
+ if (bnx2x_read_sfp_module_eeprom(phy,
+ params,
SFP_EEPROM_PART_NO_ADDR,
SFP_EEPROM_PART_NO_SIZE,
(u8 *)vendor_pn))
@@ -2989,22 +4260,78 @@ static u8 bnx2x_verify_sfp_module(struct link_params *params)
else
vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
- netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected, Port %d from %s part number %s\n",
+ netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected,"
+ " Port %d from %s part number %s\n",
params->port, vendor_name, vendor_pn);
+ phy->flags |= FLAGS_SFP_NOT_APPROVED;
return -EINVAL;
}
-static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
- u16 edc_mode)
+static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
+ struct link_params *params)
+
{
+ u8 val;
struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+ u16 timeout;
+ /* Initialization time after hot-plug may take up to 300ms for some
+ phys type ( e.g. JDSU ) */
+ for (timeout = 0; timeout < 60; timeout++) {
+ if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
+ == 0) {
+ DP(NETIF_MSG_LINK, "SFP+ module initialization "
+ "took %d ms\n", timeout * 5);
+ return 0;
+ }
+ msleep(5);
+ }
+ return -EINVAL;
+}
+
+static void bnx2x_8727_power_module(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ u8 is_power_up) {
+ /* Make sure GPIOs are not using for LED mode */
+ u16 val;
+ /*
+ * In the GPIO register, bit 4 is use to detemine if the GPIOs are
+ * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
+ * output
+ * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
+ * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
+ * where the 1st bit is the over-current(only input), and 2nd bit is
+ * for power( only output )
+ */
+
+ /*
+ * In case of NOC feature is disabled and power is up, set GPIO control
+ * as input to enable listening of over-current indication
+ */
+ if (phy->flags & FLAGS_NOC)
+ return;
+ if (!(phy->flags &
+ FLAGS_NOC) && is_power_up)
+ val = (1<<4);
+ else
+ /*
+ * Set GPIO control to OUTPUT, and set the power bit
+ * to according to the is_power_up
+ */
+ val = ((!(is_power_up)) << 1);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_GPIO_CTRL,
+ val);
+}
+
+static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ u16 edc_mode)
+{
u16 cur_limiting_mode;
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2,
&cur_limiting_mode);
@@ -3014,12 +4341,10 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
if (edc_mode == EDC_MODE_LIMITING) {
DP(NETIF_MSG_LINK,
"Setting LIMITING MODE\n");
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2,
- EDC_MODE_LIMITING);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2,
+ EDC_MODE_LIMITING);
} else { /* LRM mode ( default )*/
DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
@@ -3030,27 +4355,19 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
if (cur_limiting_mode != EDC_MODE_LIMITING)
return 0;
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_LRM_MODE,
0);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2,
0x128);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_MISC_CTRL0,
0x4008);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_LRM_MODE,
0xaaaa);
@@ -3058,46 +4375,33 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
return 0;
}
-static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
+static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
u16 edc_mode)
{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
u16 phy_identifier;
u16 rom_ver2_val;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
-
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
&phy_identifier);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
(phy_identifier & ~(1<<9)));
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2,
&rom_ver2_val);
/* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2,
(rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
(phy_identifier | (1<<9)));
@@ -3105,72 +4409,34 @@ static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
return 0;
}
-
-static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
+static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
+ struct link_params *params,
+ u32 action)
{
- u8 val;
struct bnx2x *bp = params->bp;
- u16 timeout;
- /* Initialization time after hot-plug may take up to 300ms for some
- phys type ( e.g. JDSU ) */
- for (timeout = 0; timeout < 60; timeout++) {
- if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
- == 0) {
- DP(NETIF_MSG_LINK, "SFP+ module initialization "
- "took %d ms\n", timeout * 5);
- return 0;
- }
- msleep(5);
- }
- return -EINVAL;
-}
-static void bnx2x_8727_power_module(struct bnx2x *bp,
- struct link_params *params,
- u8 ext_phy_addr, u8 is_power_up) {
- /* Make sure GPIOs are not using for LED mode */
- u16 val;
- u8 port = params->port;
- /*
- * In the GPIO register, bit 4 is use to detemine if the GPIOs are
- * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
- * output
- * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
- * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
- * where the 1st bit is the over-current(only input), and 2nd bit is
- * for power( only output )
- */
-
- /*
- * In case of NOC feature is disabled and power is up, set GPIO control
- * as input to enable listening of over-current indication
- */
-
- if (!(params->feature_config_flags &
- FEATURE_CONFIG_BCM8727_NOC) && is_power_up)
- val = (1<<4);
- else
- /*
- * Set GPIO control to OUTPUT, and set the power bit
- * to according to the is_power_up
- */
- val = ((!(is_power_up)) << 1);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_GPIO_CTRL,
- val);
+ switch (action) {
+ case DISABLE_TX:
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
+ break;
+ case ENABLE_TX:
+ if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
+ break;
+ default:
+ DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
+ action);
+ return;
+ }
}
-static u8 bnx2x_sfp_module_detection(struct link_params *params)
+static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 edc_mode;
u8 rc = 0;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
u32 val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
port_feature_config[params->port].config));
@@ -3178,10 +4444,10 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
params->port);
- if (bnx2x_get_edc_mode(params, &edc_mode) != 0) {
+ if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
return -EINVAL;
- } else if (bnx2x_verify_sfp_module(params) !=
+ } else if (bnx2x_verify_sfp_module(phy, params) !=
0) {
/* check SFP+ module compatibility */
DP(NETIF_MSG_LINK, "Module verification failed!!\n");
@@ -3190,13 +4456,12 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
MISC_REGISTERS_GPIO_HIGH,
params->port);
- if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
+ if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
/* Shutdown SFP+ module */
DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
- bnx2x_8727_power_module(bp, params,
- ext_phy_addr, 0);
+ bnx2x_8727_power_module(bp, phy, 0);
return rc;
}
} else {
@@ -3208,15 +4473,15 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
}
/* power up the SFP module */
- if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
- bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
+ bnx2x_8727_power_module(bp, phy, 1);
/* Check and set limiting mode / LRM mode on 8726.
On 8727 it is done automatically */
- if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
- bnx2x_bcm8726_set_limiting_mode(params, edc_mode);
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
+ bnx2x_8726_set_limiting_mode(bp, phy, edc_mode);
else
- bnx2x_bcm8727_set_limiting_mode(params, edc_mode);
+ bnx2x_8727_set_limiting_mode(bp, phy, edc_mode);
/*
* Enable transmit for this module if the module is approved, or
* if unapproved modules should also enable the Tx laser
@@ -3224,11 +4489,9 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
if (rc == 0 ||
(val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
- bnx2x_sfp_set_transmitter(bp, params->port,
- ext_phy_type, ext_phy_addr, 1);
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
else
- bnx2x_sfp_set_transmitter(bp, params->port,
- ext_phy_type, ext_phy_addr, 0);
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
return rc;
}
@@ -3236,6 +4499,7 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
void bnx2x_handle_module_detect_int(struct link_params *params)
{
struct bnx2x *bp = params->bp;
+ struct bnx2x_phy *phy = &params->phy[EXT_PHY1];
u32 gpio_val;
u8 port = params->port;
@@ -3245,1349 +4509,587 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
params->port);
/* Get current gpio val refelecting module plugged in / out*/
- gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
+ gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
/* Call the handling function in case module is detected */
if (gpio_val == 0) {
bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
- MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
- port);
+ MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
+ port);
- if (bnx2x_wait_for_sfp_module_initialized(params) ==
- 0)
- bnx2x_sfp_module_detection(params);
+ if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
+ bnx2x_sfp_module_detection(phy, params);
else
DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
} else {
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
-
- u32 ext_phy_type =
- XGXS_EXT_PHY_TYPE(params->ext_phy_config);
u32 val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
port_feature_config[params->port].
config));
bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
- MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
- port);
+ MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
+ port);
/* Module was plugged out. */
/* Disable transmit for this module */
if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
- bnx2x_sfp_set_transmitter(bp, params->port,
- ext_phy_type, ext_phy_addr, 0);
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
}
}
-static void bnx2x_bcm807x_force_10G(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* Force KR or KX */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 0x2040);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2,
- 0x000b);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_BCM_CTRL,
- 0x0000);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL,
- 0x0000);
-}
-
-static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
+/******************************************************************/
+/* common BCM8706/BCM8726 PHY SECTION */
+/******************************************************************/
+static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
+ u8 link_up = 0;
+ u16 val1, val2, rx_sd, pcs_status;
struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u16 val;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8073_CHIP_REV, &val);
-
- if (val == 0) {
- /* Mustn't set low power mode in 8073 A0 */
- return;
+ DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
+ /* Clear RX Alarm*/
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
+ /* clear LASI indication*/
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
+ DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
+
+ DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
+ " link_status 0x%x\n", rx_sd, pcs_status, val2);
+ /* link is up if both bit 0 of pmd_rx_sd and
+ * bit 0 of pcs_status are set, or if the autoneg bit
+ * 1 is set
+ */
+ link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
+ if (link_up) {
+ if (val2 & (1<<1))
+ vars->line_speed = SPEED_1000;
+ else
+ vars->line_speed = SPEED_10000;
+ bnx2x_ext_phy_resolve_fc(phy, params, vars);
}
-
- /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD,
- MDIO_XS_PLL_SEQUENCER, &val);
- val &= ~(1<<13);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
-
- /* PLL controls */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805E, 0x1077);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805D, 0x0000);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805C, 0x030B);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805B, 0x1240);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805A, 0x2490);
-
- /* Tx Controls */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80A7, 0x0C74);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80A6, 0x9041);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80A5, 0x4640);
-
- /* Rx Controls */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80FE, 0x01C4);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80FD, 0x9249);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80FC, 0x2015);
-
- /* Enable PLL sequencer (use read-modify-write to set bit 13) */
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD,
- MDIO_XS_PLL_SEQUENCER, &val);
- val |= (1<<13);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
+ return link_up;
}
-static void bnx2x_8073_set_pause_cl37(struct link_params *params,
- struct link_vars *vars)
+/******************************************************************/
+/* BCM8706 PHY SECTION */
+/******************************************************************/
+static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
+ u16 cnt, val;
struct bnx2x *bp = params->bp;
- u16 cl37_val;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, &cl37_val);
-
- cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
+ /* HW reset */
+ bnx2x_ext_phy_hw_reset(bp, params->port);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
+ bnx2x_wait_reset_complete(bp, phy);
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
- cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
+ /* Wait until fw is loaded */
+ for (cnt = 0; cnt < 100; cnt++) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
+ if (val)
+ break;
+ msleep(10);
}
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
- cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+ u8 i;
+ u16 reg;
+ for (i = 0; i < 4; i++) {
+ reg = MDIO_XS_8706_REG_BANK_RX0 +
+ i*(MDIO_XS_8706_REG_BANK_RX1 -
+ MDIO_XS_8706_REG_BANK_RX0);
+ bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
+ /* Clear first 3 bits of the control */
+ val &= ~0x7;
+ /* Set control bits according to configuration */
+ val |= (phy->rx_preemphasis[i] & 0x7);
+ DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
+ " reg 0x%x <-- val 0x%x\n", reg, val);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
+ }
}
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
- cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ /* Force speed */
+ if (phy->req_line_speed == SPEED_10000) {
+ DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
+ } else {
+ /* Force 1Gbps using autoneg with 1G advertisment */
+
+ /* Allow CL37 through CL73 */
+ DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
+
+ /* Enable Full-Duplex advertisment on CL37 */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
+ /* Enable CL37 AN */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
+ /* 1G support */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
+
+ /* Enable clause 73 AN */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x0400);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
+ 0x0004);
}
- DP(NETIF_MSG_LINK,
- "Ext phy AN advertize cl37 0x%x\n", cl37_val);
+ bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
+ return 0;
+}
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, cl37_val);
- msleep(500);
+static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ return bnx2x_8706_8726_read_status(phy, params, vars);
}
-static void bnx2x_ext_phy_set_pause(struct link_params *params,
- struct link_vars *vars)
+/******************************************************************/
+/* BCM8726 PHY SECTION */
+/******************************************************************/
+static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
- u16 val;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* read modify write pause advertizing */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV_PAUSE, &val);
-
- val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
-
- /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
-
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
- val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
- }
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
- val |=
- MDIO_AN_REG_ADV_PAUSE_PAUSE;
- }
- DP(NETIF_MSG_LINK,
- "Ext phy AN advertize 0x%x\n", val);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV_PAUSE, val);
+ DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
}
-static void bnx2x_set_preemphasis(struct link_params *params)
+
+static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
+ struct link_params *params)
{
- u16 bank, i = 0;
struct bnx2x *bp = params->bp;
+ /* Need to wait 100ms after reset */
+ msleep(100);
- for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
- bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- bank,
- MDIO_RX0_RX_EQ_BOOST,
- params->xgxs_config_rx[i]);
- }
-
- for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
- bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- bank,
- MDIO_TX0_TX_DRIVER,
- params->xgxs_config_tx[i]);
- }
-}
+ /* Micro controller re-boot */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
+ /* Set soft reset */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
-static void bnx2x_8481_set_led4(struct link_params *params,
- u32 ext_phy_type, u8 ext_phy_addr)
-{
- struct bnx2x *bp = params->bp;
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0001);
- /* PHYC_CTL_LED_CTL */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482);
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+
+ /* wait for 150ms for microcode load */
+ msleep(150);
- /* Unmask LED4 for 10G link */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
+ /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6));
- /* 'Interrupt Mask' */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0xFFFB, 0xFFFD);
-}
-static void bnx2x_8481_set_legacy_led_mode(struct link_params *params,
- u32 ext_phy_type, u8 ext_phy_addr)
-{
- struct bnx2x *bp = params->bp;
+ MDIO_PMA_REG_MISC_CTRL1, 0x0000);
- /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */
- /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_SHADOW,
- (1<<15) | (0xd << 10) | (0xc<<4) | 0xe);
+ msleep(200);
+ bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
}
-static void bnx2x_8481_set_10G_led_mode(struct link_params *params,
- u32 ext_phy_type, u8 ext_phy_addr)
+static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
u16 val1;
-
- /* LED1 (10G Link) */
- /* Enable continuse based on source 7(10G-link) */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LINK_SIGNAL,
- &val1);
- /* Set bit 2 to 0, and bits [1:0] to 10 */
- val1 &= ~((1<<0) | (1<<2) | (1<<7)); /* Clear bits 0,2,7*/
- val1 |= ((1<<1) | (1<<6)); /* Set bit 1, 6 */
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LINK_SIGNAL,
- val1);
-
- /* Unmask LED1 for 10G link */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LED1_MASK,
- &val1);
- /* Set bit 2 to 0, and bits [1:0] to 10 */
- val1 |= (1<<7);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LED1_MASK,
- val1);
-
- /* LED2 (1G/100/10G Link) */
- /* Mask LED2 for 10G link */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LED2_MASK,
- 0);
-
- /* Unmask LED3 for 10G link */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LED3_MASK,
- 0x6);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LED3_BLINK,
- 0);
+ u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
+ if (link_up) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
+ &val1);
+ if (val1 & (1<<15)) {
+ DP(NETIF_MSG_LINK, "Tx is disabled\n");
+ link_up = 0;
+ vars->line_speed = 0;
+ }
+ }
+ return link_up;
}
-static void bnx2x_init_internal_phy(struct link_params *params,
- struct link_vars *vars,
- u8 enable_cl73)
+static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
+ u32 val;
+ u32 swap_val, swap_override, aeu_gpio_mask, offset;
+ DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
- if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
- if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- (params->feature_config_flags &
- FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
- bnx2x_set_preemphasis(params);
-
- /* forced speed requested? */
- if (vars->line_speed != SPEED_AUTO_NEG ||
- ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- params->loopback_mode == LOOPBACK_EXT)) {
- DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
-
- /* disable autoneg */
- bnx2x_set_autoneg(params, vars, 0);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
+
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
+ bnx2x_wait_reset_complete(bp, phy);
+
+ bnx2x_8726_external_rom_boot(phy, params);
+
+ /* Need to call module detected on initialization since
+ the module detection triggered by actual module
+ insertion might occur before driver is loaded, and when
+ driver is loaded, it reset all registers, including the
+ transmitter */
+ bnx2x_sfp_module_detection(phy, params);
+
+ if (phy->req_line_speed == SPEED_1000) {
+ DP(NETIF_MSG_LINK, "Setting 1G force\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x400);
+ } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ (phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
+ ((phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
+ DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
+ /* Set Flow control */
+ bnx2x_ext_phy_set_pause(params, phy, vars);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
+ /* Enable RX-ALARM control to receive
+ interrupt for 1G speed change */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x400);
+
+ } else { /* Default 10G. Set only LASI control */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
+ }
- /* program speed and duplex */
- bnx2x_program_serdes(params, vars);
+ /* Set TX PreEmphasis if needed */
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+ DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
+ "TX_CTRL2 0x%x\n",
+ phy->tx_preemphasis[0],
+ phy->tx_preemphasis[1]);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TX_CTRL1,
+ phy->tx_preemphasis[0]);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TX_CTRL2,
+ phy->tx_preemphasis[1]);
+ }
- } else { /* AN_mode */
- DP(NETIF_MSG_LINK, "not SGMII, AN\n");
+ /* Set GPIO3 to trigger SFP+ module insertion/removal */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port);
- /* AN enabled */
- bnx2x_set_brcm_cl37_advertisment(params);
+ /* The GPIO should be swapped if the swap register is set and active */
+ swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
+ swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
- /* program duplex & pause advertisement (for aneg) */
- bnx2x_set_ieee_aneg_advertisment(params,
- vars->ieee_fc);
+ /* Select function upon port-swap configuration */
+ if (params->port == 0) {
+ offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
+ aeu_gpio_mask = (swap_val && swap_override) ?
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
+ } else {
+ offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
+ aeu_gpio_mask = (swap_val && swap_override) ?
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
+ }
+ val = REG_RD(bp, offset);
+ /* add GPIO3 to group */
+ val |= aeu_gpio_mask;
+ REG_WR(bp, offset, val);
+ return 0;
- /* enable autoneg */
- bnx2x_set_autoneg(params, vars, enable_cl73);
+}
- /* enable and restart AN */
- bnx2x_restart_autoneg(params, enable_cl73);
- }
+static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
+ /* Set serial boot control for external load */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL, 0x0001);
+}
- } else { /* SGMII mode */
- DP(NETIF_MSG_LINK, "SGMII\n");
+/******************************************************************/
+/* BCM8727 PHY SECTION */
+/******************************************************************/
- bnx2x_initialize_sgmii_process(params, vars);
+static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
+ struct link_params *params, u8 mode)
+{
+ struct bnx2x *bp = params->bp;
+ u16 led_mode_bitmask = 0;
+ u16 gpio_pins_bitmask = 0;
+ u16 val;
+ /* Only NOC flavor requires to set the LED specifically */
+ if (!(phy->flags & FLAGS_NOC))
+ return;
+ switch (mode) {
+ case LED_MODE_FRONT_PANEL_OFF:
+ case LED_MODE_OFF:
+ led_mode_bitmask = 0;
+ gpio_pins_bitmask = 0x03;
+ break;
+ case LED_MODE_ON:
+ led_mode_bitmask = 0;
+ gpio_pins_bitmask = 0x02;
+ break;
+ case LED_MODE_OPER:
+ led_mode_bitmask = 0x60;
+ gpio_pins_bitmask = 0x11;
+ break;
}
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_PCS_OPT_CTRL,
+ &val);
+ val &= 0xff8f;
+ val |= led_mode_bitmask;
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_PCS_OPT_CTRL,
+ val);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_GPIO_CTRL,
+ &val);
+ val &= 0xffe0;
+ val |= gpio_pins_bitmask;
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_GPIO_CTRL,
+ val);
+}
+static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
+ struct link_params *params) {
+ u32 swap_val, swap_override;
+ u8 port;
+ /**
+ * The PHY reset is controlled by GPIO 1. Fake the port number
+ * to cancel the swap done in set_gpio()
+ */
+ struct bnx2x *bp = params->bp;
+ swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
+ swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
+ port = (swap_val && swap_override) ^ 1;
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
}
-static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
+static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
+ u16 tmp1, val, mod_abs;
+ u16 rx_alarm_ctrl_val;
+ u16 lasi_ctrl_val;
struct bnx2x *bp = params->bp;
- u32 ext_phy_type;
- u8 ext_phy_addr;
- u16 cnt;
- u16 ctrl = 0;
- u16 val = 0;
- u8 rc = 0;
-
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* Make sure that the soft reset is off (expect for the 8072:
- * due to the lock, it will be done inside the specific
- * handling)
+ /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
+
+ bnx2x_wait_reset_complete(bp, phy);
+ rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
+ lasi_ctrl_val = 0x0004;
+
+ DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
+ /* enable LASI */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+ rx_alarm_ctrl_val);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
+
+ /* Initially configure MOD_ABS to interrupt when
+ module is presence( bit 8) */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
+ /* Set EDC off by setting OPTXLOS signal input to low
+ (bit 9).
+ When the EDC is off it locks onto a reference clock and
+ avoids becoming 'lost'.*/
+ mod_abs &= ~(1<<8);
+ if (!(phy->flags & FLAGS_NOC))
+ mod_abs &= ~(1<<9);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
+
+
+ /* Make MOD_ABS give interrupt on change */
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
+ &val);
+ val |= (1<<12);
+ if (phy->flags & FLAGS_NOC)
+ val |= (3<<5);
+
+ /**
+ * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
+ * status which reflect SFP+ module over-current
+ */
+ if (!(phy->flags & FLAGS_NOC))
+ val &= 0xff8f; /* Reset bits 4-6 */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
+
+ bnx2x_8727_power_module(bp, phy, 1);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
+
+ /* Set option 1G speed */
+ if (phy->req_line_speed == SPEED_1000) {
+ DP(NETIF_MSG_LINK, "Setting 1G force\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
+ DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
+ /**
+ * Power down the XAUI until link is up in case of dual-media
+ * and 1G
*/
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
- /* Wait for soft reset to get cleared upto 1 sec */
- for (cnt = 0; cnt < 1000; cnt++) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, &ctrl);
- if (!(ctrl & (1<<15)))
- break;
- msleep(1);
- }
- DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
- ctrl, cnt);
- }
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "XGXS 8705\n");
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL,
- 0x8288);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- 0x7fbf);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CMU_PLL_BYPASS,
- 0x0100);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_WIS_DEVAD,
- MDIO_WIS_REG_LASI_CNTL, 0x1);
-
- /* BCM8705 doesn't have microcode, hence the 0 */
- bnx2x_save_spirom_version(bp, params->port,
- params->shmem_base, 0);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- /* Wait until fw is loaded */
- for (cnt = 0; cnt < 100; cnt++) {
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &val);
- if (val)
- break;
- msleep(10);
- }
- DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
- "after %d ms\n", cnt);
- if ((params->feature_config_flags &
- FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
- u8 i;
- u16 reg;
- for (i = 0; i < 4; i++) {
- reg = MDIO_XS_8706_REG_BANK_RX0 +
- i*(MDIO_XS_8706_REG_BANK_RX1 -
- MDIO_XS_8706_REG_BANK_RX0);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_XS_DEVAD,
- reg, &val);
- /* Clear first 3 bits of the control */
- val &= ~0x7;
- /* Set control bits according to
- configuation */
- val |= (params->xgxs_config_rx[i] &
- 0x7);
- DP(NETIF_MSG_LINK, "Setting RX"
- "Equalizer to BCM8706 reg 0x%x"
- " <-- val 0x%x\n", reg, val);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_XS_DEVAD,
- reg, val);
- }
- }
- /* Force speed */
- if (params->req_line_speed == SPEED_10000) {
- DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_DIGITAL_CTRL,
- 0x400);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 1);
- } else {
- /* Force 1Gbps using autoneg with 1G
- advertisment */
-
- /* Allow CL37 through CL73 */
- DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_CL73,
- 0x040c);
-
- /* Enable Full-Duplex advertisment on CL37 */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LP,
- 0x0020);
- /* Enable CL37 AN */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_AN,
- 0x1000);
- /* 1G support */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV, (1<<5));
-
- /* Enable clause 73 AN */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL,
- 0x1200);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- 0x0400);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 0x0004);
-
- }
- bnx2x_save_bcm_spirom_ver(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- params->shmem_base);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
- bnx2x_bcm8726_external_rom_boot(params);
-
- /* Need to call module detected on initialization since
- the module detection triggered by actual module
- insertion might occur before driver is loaded, and when
- driver is loaded, it reset all registers, including the
- transmitter */
- bnx2x_sfp_module_detection(params);
-
- /* Set Flow control */
- bnx2x_ext_phy_set_pause(params, vars);
- if (params->req_line_speed == SPEED_1000) {
- DP(NETIF_MSG_LINK, "Setting 1G force\n");
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0x40);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2, 0xD);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 0x5);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- 0x400);
- } else if ((params->req_line_speed ==
- SPEED_AUTO_NEG) &&
- ((params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
- DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV, 0x20);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_CL73, 0x040c);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, 0x0020);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_AN, 0x1000);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x1200);
-
- /* Enable RX-ALARM control to receive
- interrupt for 1G speed change */
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 0x4);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- 0x400);
-
- } else { /* Default 10G. Set only LASI control */
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 1);
- }
-
- /* Set TX PreEmphasis if needed */
- if ((params->feature_config_flags &
- FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
- DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
- "TX_CTRL2 0x%x\n",
- params->xgxs_config_tx[0],
- params->xgxs_config_tx[1]);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8726_TX_CTRL1,
- params->xgxs_config_tx[0]);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8726_TX_CTRL2,
- params->xgxs_config_tx[1]);
- }
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- u16 tmp1;
- u16 rx_alarm_ctrl_val;
- u16 lasi_ctrl_val;
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
- rx_alarm_ctrl_val = 0x400;
- lasi_ctrl_val = 0x0004;
- } else {
- rx_alarm_ctrl_val = (1<<2);
- lasi_ctrl_val = 0x0004;
- }
-
- /* enable LASI */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- rx_alarm_ctrl_val);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL,
- lasi_ctrl_val);
-
- bnx2x_8073_set_pause_cl37(params, vars);
-
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)
- bnx2x_bcm8072_external_rom_boot(params);
- else
- /* In case of 8073 with long xaui lines,
- don't set the 8073 xaui low power*/
- bnx2x_bcm8073_set_xaui_low_power_mode(params);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_M8051_MSGOUT_REG,
- &tmp1);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &tmp1);
-
- DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
- "0x%x\n", tmp1);
-
- /* If this is forced speed, set to KR or KX
- * (all other are not supported)
- */
- if (params->loopback_mode == LOOPBACK_EXT) {
- bnx2x_bcm807x_force_10G(params);
- DP(NETIF_MSG_LINK,
- "Forced speed 10G on 807X\n");
- break;
- } else {
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_BCM_CTRL,
- 0x0002);
- }
- if (params->req_line_speed != SPEED_AUTO_NEG) {
- if (params->req_line_speed == SPEED_10000) {
- val = (1<<7);
- } else if (params->req_line_speed ==
- SPEED_2500) {
- val = (1<<5);
- /* Note that 2.5G works only
- when used with 1G advertisment */
- } else
- val = (1<<5);
- } else {
-
- val = 0;
- if (params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
- val |= (1<<7);
-
- /* Note that 2.5G works only when
- used with 1G advertisment */
- if (params->speed_cap_mask &
- (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
- PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
- val |= (1<<5);
- DP(NETIF_MSG_LINK,
- "807x autoneg val = 0x%x\n", val);
- }
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV, val);
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8073_2_5G, &tmp1);
-
- if (((params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
- (params->req_line_speed ==
- SPEED_AUTO_NEG)) ||
- (params->req_line_speed ==
- SPEED_2500)) {
- u16 phy_ver;
- /* Allow 2.5G for A1 and above */
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ if (DUAL_MEDIA(params)) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_PCS_GP, &val);
+ val |= (3<<10);
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
- DP(NETIF_MSG_LINK, "Add 2.5G\n");
- if (phy_ver > 0)
- tmp1 |= 1;
- else
- tmp1 &= 0xfffe;
- } else {
- DP(NETIF_MSG_LINK, "Disable 2.5G\n");
- tmp1 &= 0xfffe;
- }
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8073_2_5G, tmp1);
- }
-
- /* Add support for CL37 (passive mode) II */
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD,
- &tmp1);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, (tmp1 |
- ((params->req_duplex == DUPLEX_FULL) ?
- 0x20 : 0x40)));
-
- /* Add support for CL37 (passive mode) III */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_AN, 0x1000);
-
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- /* The SNR will improve about 2db by changing
- BW and FEE main tap. Rest commands are executed
- after link is up*/
- /*Change FFE main cursor to 5 in EDC register*/
- if (bnx2x_8073_is_snr_needed(params))
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_EDC_FFE_MAIN,
- 0xFB0C);
-
- /* Enable FEC (Forware Error Correction)
- Request in the AN */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV2, &tmp1);
-
- tmp1 |= (1<<15);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV2, tmp1);
-
- }
-
- bnx2x_ext_phy_set_pause(params, vars);
-
- /* Restart autoneg */
- msleep(500);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x1200);
- DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
- "Advertise 1G=%x, 10G=%x\n",
- ((val & (1<<5)) > 0),
- ((val & (1<<7)) > 0));
- break;
+ MDIO_PMA_REG_8727_PCS_GP, val);
}
+ } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ ((phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
+ ((phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
+
+ DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
+ } else {
+ /**
+ * Since the 8727 has only single reset pin, need to set the 10G
+ * registers although it is default
+ */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
+ 0x0020);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
+ 0x0008);
+ }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- {
- u16 tmp1;
- u16 rx_alarm_ctrl_val;
- u16 lasi_ctrl_val;
-
- /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
-
- u16 mod_abs;
- rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
- lasi_ctrl_val = 0x0004;
-
- DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
- /* enable LASI */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- rx_alarm_ctrl_val);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL,
- lasi_ctrl_val);
-
- /* Initially configure MOD_ABS to interrupt when
- module is presence( bit 8) */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
- /* Set EDC off by setting OPTXLOS signal input to low
- (bit 9).
- When the EDC is off it locks onto a reference clock and
- avoids becoming 'lost'.*/
- mod_abs &= ~((1<<8) | (1<<9));
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
-
- /* Make MOD_ABS give interrupt on change */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_PCS_OPT_CTRL,
- &val);
- val |= (1<<12);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_PCS_OPT_CTRL,
- val);
-
- /* Set 8727 GPIOs to input to allow reading from the
- 8727 GPIO0 status which reflect SFP+ module
- over-current */
-
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_PCS_OPT_CTRL,
- &val);
- val &= 0xff8f; /* Reset bits 4-6 */
- bnx2x_cl45_write(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_PCS_OPT_CTRL,
- val);
-
- bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
- bnx2x_bcm8073_set_xaui_low_power_mode(params);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_M8051_MSGOUT_REG,
- &tmp1);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &tmp1);
-
- /* Set option 1G speed */
- if (params->req_line_speed == SPEED_1000) {
-
- DP(NETIF_MSG_LINK, "Setting 1G force\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0x40);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2, 0xD);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2, &tmp1);
- DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
-
- } else if ((params->req_line_speed ==
- SPEED_AUTO_NEG) &&
- ((params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
-
- DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_PMA_REG_8727_MISC_CTRL, 0);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_AN, 0x1300);
- } else {
- /* Since the 8727 has only single reset pin,
- need to set the 10G registers although it is
- default */
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x0020);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- 0x7, 0x0100);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0x2040);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2, 0x0008);
- }
-
- /* Set 2-wire transfer rate of SFP+ module EEPROM
- * to 100Khz since some DACs(direct attached cables) do
- * not work at 400Khz.
- */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
- 0xa001);
-
- /* Set TX PreEmphasis if needed */
- if ((params->feature_config_flags &
- FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
- DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
- "TX_CTRL2 0x%x\n",
- params->xgxs_config_tx[0],
- params->xgxs_config_tx[1]);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_TX_CTRL1,
- params->xgxs_config_tx[0]);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_TX_CTRL2,
- params->xgxs_config_tx[1]);
- }
-
- break;
- }
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- {
- u16 fw_ver1, fw_ver2;
- DP(NETIF_MSG_LINK,
- "Setting the SFX7101 LASI indication\n");
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 0x1);
- DP(NETIF_MSG_LINK,
- "Setting the SFX7101 LED to blink on traffic\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
-
- bnx2x_ext_phy_set_pause(params, vars);
- /* Restart autoneg */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, &val);
- val |= 0x200;
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, val);
-
- /* Save spirom version */
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER1, &fw_ver1);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER2, &fw_ver2);
-
- bnx2x_save_spirom_version(params->bp, params->port,
- params->shmem_base,
- (u32)(fw_ver1<<16 | fw_ver2));
- break;
- }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- /* This phy uses the NIG latch mechanism since link
- indication arrives through its LED4 and not via
- its LASI signal, so we get steady signal
- instead of clear on read */
- bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
- 1 << NIG_LATCH_BC_ENABLE_MI_INT);
-
- bnx2x_cl45_write(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0x0000);
-
- bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
- if (params->req_line_speed == SPEED_AUTO_NEG) {
-
- u16 autoneg_val, an_1000_val, an_10_100_val;
- /* set 1000 speed advertisement */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_1000T_CTRL,
- &an_1000_val);
-
- if (params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
- an_1000_val |= (1<<8);
- if (params->req_duplex == DUPLEX_FULL)
- an_1000_val |= (1<<9);
- DP(NETIF_MSG_LINK, "Advertising 1G\n");
- } else
- an_1000_val &= ~((1<<8) | (1<<9));
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_1000T_CTRL,
- an_1000_val);
-
- /* set 100 speed advertisement */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_AN_ADV,
- &an_10_100_val);
-
- if (params->speed_cap_mask &
- (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) {
- an_10_100_val |= (1<<7);
- if (params->req_duplex == DUPLEX_FULL)
- an_10_100_val |= (1<<8);
- DP(NETIF_MSG_LINK,
- "Advertising 100M\n");
- } else
- an_10_100_val &= ~((1<<7) | (1<<8));
-
- /* set 10 speed advertisement */
- if (params->speed_cap_mask &
- (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) {
- an_10_100_val |= (1<<5);
- if (params->req_duplex == DUPLEX_FULL)
- an_10_100_val |= (1<<6);
- DP(NETIF_MSG_LINK, "Advertising 10M\n");
- }
- else
- an_10_100_val &= ~((1<<5) | (1<<6));
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_AN_ADV,
- an_10_100_val);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_MII_CTRL,
- &autoneg_val);
-
- /* Disable forced speed */
- autoneg_val &= ~(1<<6|1<<13);
-
- /* Enable autoneg and restart autoneg
- for legacy speeds */
- autoneg_val |= (1<<9|1<<12);
-
- if (params->req_duplex == DUPLEX_FULL)
- autoneg_val |= (1<<8);
- else
- autoneg_val &= ~(1<<8);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_MII_CTRL,
- autoneg_val);
-
- if (params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
- DP(NETIF_MSG_LINK, "Advertising 10G\n");
- /* Restart autoneg for 10G*/
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x3200);
- }
- } else {
- /* Force speed */
- u16 autoneg_ctrl, pma_ctrl;
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_MII_CTRL,
- &autoneg_ctrl);
-
- /* Disable autoneg */
- autoneg_ctrl &= ~(1<<12);
-
- /* Set 1000 force */
- switch (params->req_line_speed) {
- case SPEED_10000:
- DP(NETIF_MSG_LINK,
- "Unable to set 10G force !\n");
- break;
- case SPEED_1000:
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- &pma_ctrl);
- autoneg_ctrl &= ~(1<<13);
- autoneg_ctrl |= (1<<6);
- pma_ctrl &= ~(1<<13);
- pma_ctrl |= (1<<6);
- DP(NETIF_MSG_LINK,
- "Setting 1000M force\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- pma_ctrl);
- break;
- case SPEED_100:
- autoneg_ctrl |= (1<<13);
- autoneg_ctrl &= ~(1<<6);
- DP(NETIF_MSG_LINK,
- "Setting 100M force\n");
- break;
- case SPEED_10:
- autoneg_ctrl &= ~(1<<13);
- autoneg_ctrl &= ~(1<<6);
- DP(NETIF_MSG_LINK,
- "Setting 10M force\n");
- break;
- }
-
- /* Duplex mode */
- if (params->req_duplex == DUPLEX_FULL) {
- autoneg_ctrl |= (1<<8);
- DP(NETIF_MSG_LINK,
- "Setting full duplex\n");
- } else
- autoneg_ctrl &= ~(1<<8);
-
- /* Update autoneg ctrl and pma ctrl */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_MII_CTRL,
- autoneg_ctrl);
- }
-
- /* Save spirom version */
- bnx2x_save_8481_spirom_version(bp, params->port,
- ext_phy_addr,
- params->shmem_base);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- DP(NETIF_MSG_LINK,
- "XGXS PHY Failure detected 0x%x\n",
- params->ext_phy_config);
- rc = -EINVAL;
- break;
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- params->ext_phy_config);
- rc = -EINVAL;
- break;
- }
-
- } else { /* SerDes */
-
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- break;
-
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
- params->ext_phy_config);
- break;
- }
+ /* Set 2-wire transfer rate of SFP+ module EEPROM
+ * to 100Khz since some DACs(direct attached cables) do
+ * not work at 400Khz.
+ */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
+ 0xa001);
+
+ /* Set TX PreEmphasis if needed */
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+ DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
+ phy->tx_preemphasis[0],
+ phy->tx_preemphasis[1]);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
+ phy->tx_preemphasis[0]);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
+ phy->tx_preemphasis[1]);
}
- return rc;
+
+ return 0;
}
-static void bnx2x_8727_handle_mod_abs(struct link_params *params)
+static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 mod_abs, rx_alarm_status;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
port_feature_config[params->port].
config));
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
if (mod_abs & (1<<8)) {
@@ -4602,18 +5104,16 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params)
(bit 9).
When the EDC is off it locks onto a reference clock and
avoids becoming 'lost'.*/
- mod_abs &= ~((1<<8)|(1<<9));
- bnx2x_cl45_write(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ mod_abs &= ~(1<<8);
+ if (!(phy->flags & FLAGS_NOC))
+ mod_abs &= ~(1<<9);
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
/* Clear RX alarm since it stays up as long as
the mod_abs wasn't changed */
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
@@ -4630,33 +5130,28 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params)
2. Restore the default polarity of the OPRXLOS signal and
this signal will then correctly indicate the presence or
absence of the Rx signal. (bit 9) */
- mod_abs |= ((1<<8)|(1<<9));
- bnx2x_cl45_write(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
+ mod_abs |= (1<<8);
+ if (!(phy->flags & FLAGS_NOC))
+ mod_abs |= (1<<9);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
/* Clear RX alarm since it stays up as long as
the mod_abs wasn't changed. This is need to be done
before calling the module detection, otherwise it will clear
the link update alarm */
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
- bnx2x_sfp_set_transmitter(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr, 0);
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
- if (bnx2x_wait_for_sfp_module_initialized(params)
- == 0)
- bnx2x_sfp_module_detection(params);
+ if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
+ bnx2x_sfp_module_detection(phy, params);
else
DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
}
@@ -4667,1298 +5162,1714 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params)
module plugged in/out */
}
+static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
-static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
- struct link_vars *vars,
- u8 is_mi_int)
{
struct bnx2x *bp = params->bp;
- u32 ext_phy_type;
- u8 ext_phy_addr;
- u16 val1 = 0, val2;
- u16 rx_sd, pcs_status;
- u8 ext_phy_link_up = 0;
- u8 port = params->port;
-
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "XGXS Direct\n");
- ext_phy_link_up = 1;
- break;
+ u8 link_up = 0;
+ u16 link_status = 0;
+ u16 rx_alarm_status, lasi_ctrl, val1;
+
+ /* If PHY is not initialized, do not check link status */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
+ &lasi_ctrl);
+ if (!lasi_ctrl)
+ return 0;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "XGXS 8705\n");
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_WIS_DEVAD,
- MDIO_WIS_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_WIS_DEVAD,
- MDIO_WIS_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_SD, &rx_sd);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- 1,
- 0xc809, &val1);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- 1,
- 0xc809, &val1);
-
- DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
- ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) &&
- ((val1 & (1<<8)) == 0));
- if (ext_phy_link_up)
- vars->line_speed = SPEED_10000;
- break;
+ /* Check the LASI */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
+ &rx_alarm_status);
+ vars->line_speed = 0;
+ DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
- /* Clear RX Alarm*/
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
- &val2);
- /* clear LASI indication*/
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
- &val1);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
- &val2);
- DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
- "0x%x\n", val1, val2);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
- &rx_sd);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
- &pcs_status);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
- &val2);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
- &val2);
-
- DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
- " pcs_status 0x%x 1Gbps link_status 0x%x\n",
- rx_sd, pcs_status, val2);
- /* link is up if both bit 0 of pmd_rx_sd and
- * bit 0 of pcs_status are set, or if the autoneg bit
- 1 is set
- */
- ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
- (val2 & (1<<1)));
- if (ext_phy_link_up) {
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
- /* If transmitter is disabled,
- ignore false link up indication */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- &val1);
- if (val1 & (1<<15)) {
- DP(NETIF_MSG_LINK, "Tx is "
- "disabled\n");
- ext_phy_link_up = 0;
- break;
- }
- }
- if (val2 & (1<<1))
- vars->line_speed = SPEED_1000;
- else
- vars->line_speed = SPEED_10000;
- }
- break;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- {
- u16 link_status = 0;
- u16 rx_alarm_status;
- /* Check the LASI */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
-
- DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
- rx_alarm_status);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
- DP(NETIF_MSG_LINK,
- "8727 LASI status 0x%x\n",
- val1);
+ /* Clear MSG-OUT */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
- /* Clear MSG-OUT */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_M8051_MSGOUT_REG,
- &val1);
+ /**
+ * If a module is present and there is need to check
+ * for over current
+ */
+ if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
+ /* Check over-current using 8727 GPIO0 input*/
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
+ &val1);
+
+ if ((val1 & (1<<8)) == 0) {
+ DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
+ " on port %d\n", params->port);
+ netdev_err(bp->dev, "Error: Power fault on Port %d has"
+ " been detected and the power to "
+ "that SFP+ module has been removed"
+ " to prevent failure of the card."
+ " Please remove the SFP+ module and"
+ " restart the system to clear this"
+ " error.\n",
+ params->port);
/*
- * If a module is present and there is need to check
- * for over current
+ * Disable all RX_ALARMs except for
+ * mod_abs
*/
- if (!(params->feature_config_flags &
- FEATURE_CONFIG_BCM8727_NOC) &&
- !(rx_alarm_status & (1<<5))) {
- /* Check over-current using 8727 GPIO0 input*/
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_GPIO_CTRL,
- &val1);
-
- if ((val1 & (1<<8)) == 0) {
- DP(NETIF_MSG_LINK, "8727 Power fault"
- " has been detected on "
- "port %d\n",
- params->port);
- netdev_err(bp->dev, "Error: Power fault on Port %d has been detected and the power to that SFP+ module has been removed to prevent failure of the card. Please remove the SFP+ module and restart the system to clear this error.\n",
- params->port);
- /*
- * Disable all RX_ALARMs except for
- * mod_abs
- */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- (1<<5));
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- &val1);
- /* Wait for module_absent_event */
- val1 |= (1<<8);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- val1);
- /* Clear RX alarm */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM,
- &rx_alarm_status);
- break;
- }
- } /* Over current check */
-
- /* When module absent bit is set, check module */
- if (rx_alarm_status & (1<<5)) {
- bnx2x_8727_handle_mod_abs(params);
- /* Enable all mod_abs and link detection bits */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- ((1<<5) | (1<<2)));
- }
-
- /* If transmitter is disabled,
- ignore false link up indication */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- &val1);
- if (val1 & (1<<15)) {
- DP(NETIF_MSG_LINK, "Tx is disabled\n");
- ext_phy_link_up = 0;
- break;
- }
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
- &link_status);
-
- /* Bits 0..2 --> speed detected,
- bits 13..15--> link is down */
- if ((link_status & (1<<2)) &&
- (!(link_status & (1<<15)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_10000;
- } else if ((link_status & (1<<0)) &&
- (!(link_status & (1<<13)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_1000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 1G\n", params->port);
- } else {
- ext_phy_link_up = 0;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " is down\n", params->port);
- }
- break;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
+ /* Wait for module_absent_event */
+ val1 |= (1<<8);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER, val1);
+ /* Clear RX alarm */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
+ return 0;
}
+ } /* Over current check */
+
+ /* When module absent bit is set, check module */
+ if (rx_alarm_status & (1<<5)) {
+ bnx2x_8727_handle_mod_abs(phy, params);
+ /* Enable all mod_abs and link detection bits */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+ ((1<<5) | (1<<2)));
+ }
+ DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
+ bnx2x_8727_specific_func(phy, params, ENABLE_TX);
+ /* If transmitter is disabled, ignore false link up indication */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
+ if (val1 & (1<<15)) {
+ DP(NETIF_MSG_LINK, "Tx is disabled\n");
+ return 0;
+ }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- u16 link_status = 0;
- u16 an1000_status = 0;
-
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_LASI_STATUS, &val1);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_LASI_STATUS, &val2);
- DP(NETIF_MSG_LINK,
- "870x LASI status 0x%x->0x%x\n",
- val1, val2);
- } else {
- /* In 8073, port1 is directed through emac0 and
- * port0 is directed through emac1
- */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
-
- DP(NETIF_MSG_LINK,
- "8703 LASI status 0x%x\n",
- val1);
- }
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
- /* clear the interrupt LASI status register */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &val1);
- DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
- val2, val1);
- /* Clear MSG-OUT */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_M8051_MSGOUT_REG,
- &val1);
-
- /* Check the LASI */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &val2);
-
- DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
-
- /* Check the link status */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &val2);
- DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val1);
- ext_phy_link_up = ((val1 & 4) == 4);
- DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
-
- if (ext_phy_link_up &&
- ((params->req_line_speed !=
- SPEED_10000))) {
- if (bnx2x_bcm8073_xaui_wa(params)
- != 0) {
- ext_phy_link_up = 0;
- break;
- }
- }
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS,
- &an1000_status);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS,
- &an1000_status);
-
- /* Check the link status on 1.1.2 */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val1);
- DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
- "an_link_status=0x%x\n",
- val2, val1, an1000_status);
-
- ext_phy_link_up = (((val1 & 4) == 4) ||
- (an1000_status & (1<<1)));
- if (ext_phy_link_up &&
- bnx2x_8073_is_snr_needed(params)) {
- /* The SNR will improve about 2dbby
- changing the BW and FEE main tap.*/
-
- /* The 1st write to change FFE main
- tap is set before restart AN */
- /* Change PLL Bandwidth in EDC
- register */
- bnx2x_cl45_write(bp, port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PLL_BANDWIDTH,
- 0x26BC);
-
- /* Change CDR Bandwidth in EDC
- register */
- bnx2x_cl45_write(bp, port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CDR_BANDWIDTH,
- 0x0333);
- }
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
- &link_status);
-
- /* Bits 0..2 --> speed detected,
- bits 13..15--> link is down */
- if ((link_status & (1<<2)) &&
- (!(link_status & (1<<15)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_10000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 10G\n", params->port);
- } else if ((link_status & (1<<1)) &&
- (!(link_status & (1<<14)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_2500;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 2.5G\n", params->port);
- } else if ((link_status & (1<<0)) &&
- (!(link_status & (1<<13)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_1000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 1G\n", params->port);
- } else {
- ext_phy_link_up = 0;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " is down\n", params->port);
- }
- } else {
- /* See if 1G link is up for the 8072 */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS,
- &an1000_status);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS,
- &an1000_status);
- if (an1000_status & (1<<1)) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_1000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 1G\n", params->port);
- } else if (ext_phy_link_up) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_10000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 10G\n", params->port);
- }
- }
+ /* Bits 0..2 --> speed detected,
+ bits 13..15--> link is down */
+ if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
+ link_up = 1;
+ vars->line_speed = SPEED_10000;
+ } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
+ link_up = 1;
+ vars->line_speed = SPEED_1000;
+ DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
+ params->port);
+ } else {
+ link_up = 0;
+ DP(NETIF_MSG_LINK, "port %x: External link is down\n",
+ params->port);
+ }
+ if (link_up)
+ bnx2x_ext_phy_resolve_fc(phy, params, vars);
+
+ if ((DUAL_MEDIA(params)) &&
+ (phy->req_line_speed == SPEED_1000)) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_PCS_GP, &val1);
+ /**
+ * In case of dual-media board and 1G, power up the XAUI side,
+ * otherwise power it down. For 10G it is done automatically
+ */
+ if (link_up)
+ val1 &= ~(3<<10);
+ else
+ val1 |= (3<<10);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_PCS_GP, val1);
+ }
+ return link_up;
+}
+static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ /* Disable Transmitter */
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
+ /* Clear LASI */
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
- break;
- }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK,
- "10G-base-T LASI status 0x%x->0x%x\n",
- val2, val1);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val1);
- DP(NETIF_MSG_LINK,
- "10G-base-T PMA status 0x%x->0x%x\n",
- val2, val1);
- ext_phy_link_up = ((val1 & 4) == 4);
- /* if link is up
- * print the AN outcome of the SFX7101 PHY
- */
- if (ext_phy_link_up) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_MASTER_STATUS,
- &val2);
- vars->line_speed = SPEED_10000;
- DP(NETIF_MSG_LINK,
- "SFX7101 AN status 0x%x->Master=%x\n",
- val2,
- (val2 & (1<<14)));
- }
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- /* Check 10G-BaseT link status */
- /* Check PMD signal ok */
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0xFFFA,
- &val1);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_PMD_SIGNAL,
- &val2);
- DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2);
-
- /* Check link 10G */
- if (val2 & (1<<11)) {
- vars->line_speed = SPEED_10000;
- ext_phy_link_up = 1;
- bnx2x_8481_set_10G_led_mode(params,
- ext_phy_type,
- ext_phy_addr);
- } else { /* Check Legacy speed link */
- u16 legacy_status, legacy_speed;
-
- /* Enable expansion register 0x42
- (Operation mode status) */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_EXPANSION_REG_ACCESS,
- 0xf42);
-
- /* Get legacy speed operation status */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
- &legacy_status);
-
- DP(NETIF_MSG_LINK, "Legacy speed status"
- " = 0x%x\n", legacy_status);
- ext_phy_link_up = ((legacy_status & (1<<11))
- == (1<<11));
- if (ext_phy_link_up) {
- legacy_speed = (legacy_status & (3<<9));
- if (legacy_speed == (0<<9))
- vars->line_speed = SPEED_10;
- else if (legacy_speed == (1<<9))
- vars->line_speed =
- SPEED_100;
- else if (legacy_speed == (2<<9))
- vars->line_speed =
- SPEED_1000;
- else /* Should not happen */
- vars->line_speed = 0;
-
- if (legacy_status & (1<<8))
- vars->duplex = DUPLEX_FULL;
- else
- vars->duplex = DUPLEX_HALF;
-
- DP(NETIF_MSG_LINK, "Link is up "
- "in %dMbps, is_duplex_full"
- "= %d\n",
- vars->line_speed,
- (vars->duplex == DUPLEX_FULL));
- bnx2x_8481_set_legacy_led_mode(params,
- ext_phy_type,
- ext_phy_addr);
- }
- }
- break;
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- params->ext_phy_config);
- ext_phy_link_up = 0;
- break;
- }
- /* Set SGMII mode for external phy */
- if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
- if (vars->line_speed < SPEED_1000)
- vars->phy_flags |= PHY_SGMII_FLAG;
- else
- vars->phy_flags &= ~PHY_SGMII_FLAG;
- }
+}
- } else { /* SerDes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- ext_phy_link_up = 1;
- break;
+/******************************************************************/
+/* BCM8481/BCM84823/BCM84833 PHY SECTION */
+/******************************************************************/
+static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ u16 val, fw_ver1, fw_ver2, cnt;
+ struct bnx2x *bp = params->bp;
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- ext_phy_link_up = 1;
+ /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
+ /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
+
+ for (cnt = 0; cnt < 100; cnt++) {
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
+ if (val & 1)
break;
+ udelay(5);
+ }
+ if (cnt == 100) {
+ DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
+ bnx2x_save_spirom_version(bp, params->port, 0,
+ phy->ver_addr);
+ return;
+ }
- default:
- DP(NETIF_MSG_LINK,
- "BAD SerDes ext_phy_config 0x%x\n",
- params->ext_phy_config);
- ext_phy_link_up = 0;
+
+ /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
+ for (cnt = 0; cnt < 100; cnt++) {
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
+ if (val & 1)
break;
- }
+ udelay(5);
+ }
+ if (cnt == 100) {
+ DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
+ bnx2x_save_spirom_version(bp, params->port, 0,
+ phy->ver_addr);
+ return;
}
- return ext_phy_link_up;
+ /* lower 16 bits of the register SPI_FW_STATUS */
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
+ /* upper 16 bits of register SPI_FW_STATUS */
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
+
+ bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1,
+ phy->ver_addr);
}
-static void bnx2x_link_int_enable(struct link_params *params)
+static void bnx2x_848xx_set_led(struct bnx2x *bp,
+ struct bnx2x_phy *phy)
{
- u8 port = params->port;
- u32 ext_phy_type;
- u32 mask;
- struct bnx2x *bp = params->bp;
+ u16 val;
- /* setting the status to report on link up
- for either XGXS or SerDes */
+ /* PHYC_CTL_LED_CTL */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
+ val &= 0xFE00;
+ val |= 0x0092;
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL, val);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x80);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED2_MASK,
+ 0x18);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED3_MASK,
+ 0x0040);
- if (params->switch_cfg == SWITCH_CFG_10G) {
- mask = (NIG_MASK_XGXS0_LINK10G |
- NIG_MASK_XGXS0_LINK_STATUS);
- DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
- (ext_phy_type !=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
- mask |= NIG_MASK_MI_INT;
- DP(NETIF_MSG_LINK, "enabled external phy int\n");
- }
+ /* 'Interrupt Mask' */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD,
+ 0xFFFB, 0xFFFD);
+}
- } else { /* SerDes */
- mask = NIG_MASK_SERDES0_LINK_STATUS;
- DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- if ((ext_phy_type !=
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type !=
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
- mask |= NIG_MASK_MI_INT;
- DP(NETIF_MSG_LINK, "enabled external phy int\n");
- }
+static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u16 autoneg_val, an_1000_val, an_10_100_val;
+ bnx2x_wait_reset_complete(bp, phy);
+ bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
+ 1 << NIG_LATCH_BC_ENABLE_MI_INT);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
+
+ bnx2x_848xx_set_led(bp, phy);
+
+ /* set 1000 speed advertisement */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
+ &an_1000_val);
+
+ bnx2x_ext_phy_set_pause(params, phy, vars);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_LEGACY_AN_ADV,
+ &an_10_100_val);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
+ &autoneg_val);
+ /* Disable forced speed */
+ autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
+ an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
+
+ if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ (phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
+ (phy->req_line_speed == SPEED_1000)) {
+ an_1000_val |= (1<<8);
+ autoneg_val |= (1<<9 | 1<<12);
+ if (phy->req_duplex == DUPLEX_FULL)
+ an_1000_val |= (1<<9);
+ DP(NETIF_MSG_LINK, "Advertising 1G\n");
+ } else
+ an_1000_val &= ~((1<<8) | (1<<9));
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
+ an_1000_val);
+
+ /* set 10 speed advertisement */
+ if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ (phy->speed_cap_mask &
+ (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
+ an_10_100_val |= (1<<7);
+ /* Enable autoneg and restart autoneg for legacy speeds */
+ autoneg_val |= (1<<9 | 1<<12);
+
+ if (phy->req_duplex == DUPLEX_FULL)
+ an_10_100_val |= (1<<8);
+ DP(NETIF_MSG_LINK, "Advertising 100M\n");
+ }
+ /* set 10 speed advertisement */
+ if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ (phy->speed_cap_mask &
+ (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
+ an_10_100_val |= (1<<5);
+ autoneg_val |= (1<<9 | 1<<12);
+ if (phy->req_duplex == DUPLEX_FULL)
+ an_10_100_val |= (1<<6);
+ DP(NETIF_MSG_LINK, "Advertising 10M\n");
}
- bnx2x_bits_en(bp,
- NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- mask);
- DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
- (params->switch_cfg == SWITCH_CFG_10G),
- REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
- DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
- REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
- REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
- REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
- DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
-}
+ /* Only 10/100 are allowed to work in FORCE mode */
+ if (phy->req_line_speed == SPEED_100) {
+ autoneg_val |= (1<<13);
+ /* Enabled AUTO-MDIX when autoneg is disabled */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
+ (1<<15 | 1<<9 | 7<<0));
+ DP(NETIF_MSG_LINK, "Setting 100M force\n");
+ }
+ if (phy->req_line_speed == SPEED_10) {
+ /* Enabled AUTO-MDIX when autoneg is disabled */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
+ (1<<15 | 1<<9 | 7<<0));
+ DP(NETIF_MSG_LINK, "Setting 10M force\n");
+ }
-static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
- u8 is_mi_int)
-{
- u32 latch_status = 0, is_mi_int_status;
- /* Disable the MI INT ( external phy int )
- * by writing 1 to the status register. Link down indication
- * is high-active-signal, so in this case we need to write the
- * status to clear the XOR
- */
- /* Read Latched signals */
- latch_status = REG_RD(bp,
- NIG_REG_LATCH_STATUS_0 + port*8);
- is_mi_int_status = REG_RD(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
- DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
- "latch_status = 0x%x\n",
- is_mi_int, is_mi_int_status, latch_status);
- /* Handle only those with latched-signal=up.*/
- if (latch_status & 1) {
- /* For all latched-signal=up,Write original_signal to status */
- if (is_mi_int)
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0
- + port*4,
- NIG_STATUS_EMAC0_MI_INT);
- else
- bnx2x_bits_dis(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0
- + port*4,
- NIG_STATUS_EMAC0_MI_INT);
- /* For all latched-signal=up : Re-Arm Latch signals */
- REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
- (latch_status & 0xfffe) | (latch_status & 1));
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
+ an_10_100_val);
+
+ if (phy->req_duplex == DUPLEX_FULL)
+ autoneg_val |= (1<<8);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
+
+ if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ (phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
+ (phy->req_line_speed == SPEED_10000)) {
+ DP(NETIF_MSG_LINK, "Advertising 10G\n");
+ /* Restart autoneg for 10G*/
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
+ 0x3200);
+ } else if (phy->req_line_speed != SPEED_10 &&
+ phy->req_line_speed != SPEED_100) {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
+ 1);
}
+ /* Save spirom version */
+ bnx2x_save_848xx_spirom_version(phy, params);
+
+ return 0;
}
-/*
- * link management
- */
-static void bnx2x_link_int_ack(struct link_params *params,
- struct link_vars *vars, u8 is_10g,
- u8 is_mi_int)
+
+static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
- u8 port = params->port;
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
- /* first reset all status
- * we assume only one line will be change at a time */
- bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_STATUS_XGXS0_LINK10G |
- NIG_STATUS_XGXS0_LINK_STATUS |
- NIG_STATUS_SERDES0_LINK_STATUS));
- if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config)
- == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config)
- == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) {
- bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
- }
- if (vars->phy_link_up) {
- if (is_10g) {
- /* Disable the 10G link interrupt
- * by writing 1 to the status register
- */
- DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_STATUS_XGXS0_LINK10G);
+ /* HW reset */
+ bnx2x_ext_phy_hw_reset(bp, params->port);
- } else if (params->switch_cfg == SWITCH_CFG_10G) {
- /* Disable the link interrupt
- * by writing 1 to the relevant lane
- * in the status register
- */
- u32 ser_lane = ((params->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
+ return bnx2x_848xx_cmn_config_init(phy, params, vars);
+}
- DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
- vars->line_speed);
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- ((1 << ser_lane) <<
- NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
+static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port, initialize = 1;
+ u16 val;
+ u16 temp;
+ u32 actual_phy_selection;
+ u8 rc = 0;
- } else { /* SerDes */
- DP(NETIF_MSG_LINK, "SerDes phy link up\n");
- /* Disable the link interrupt
- * by writing 1 to the status register
- */
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_STATUS_SERDES0_LINK_STATUS);
- }
+ /* This is just for MDIO_CTL_REG_84823_MEDIA register. */
- } else { /* link_down */
+ msleep(1);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+ port);
+ msleep(200); /* 100 is not enough */
+
+ /* BCM84823 requires that XGXS links up first @ 10G for normal
+ behavior */
+ temp = vars->line_speed;
+ vars->line_speed = SPEED_10000;
+ bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
+ bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
+ vars->line_speed = temp;
+
+ /* Set dual-media configuration according to configuration */
+
+ bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
+ MDIO_CTL_REG_84823_MEDIA, &val);
+ val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
+ MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
+ MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
+ MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
+ MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
+ val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
+ MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
+
+ actual_phy_selection = bnx2x_phy_selection(params);
+
+ switch (actual_phy_selection) {
+ case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
+ /* Do nothing. Essentialy this is like the priority copper */
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
+ val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
+ val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
+ /* Do nothing here. The first PHY won't be initialized at all */
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
+ val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
+ initialize = 0;
+ break;
}
+ if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
+ val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
+
+ bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
+ MDIO_CTL_REG_84823_MEDIA, val);
+ DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
+ params->multi_phy_config, val);
+
+ if (initialize)
+ rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
+ else
+ bnx2x_save_848xx_spirom_version(phy, params);
+ return rc;
}
-static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
+static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
- u8 *str_ptr = str;
- u32 mask = 0xf0000000;
- u8 shift = 8*4;
- u8 digit;
- if (len < 10) {
- /* Need more than 10chars for this format */
- *str_ptr = '\0';
- return -EINVAL;
- }
- while (shift > 0) {
+ struct bnx2x *bp = params->bp;
+ u16 val, val1, val2;
+ u8 link_up = 0;
+
+ /* Check 10G-BaseT link status */
+ /* Check PMD signal ok */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, 0xFFFA, &val1);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
+ &val2);
+ DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
+
+ /* Check link 10G */
+ if (val2 & (1<<11)) {
+ vars->line_speed = SPEED_10000;
+ link_up = 1;
+ bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
+ } else { /* Check Legacy speed link */
+ u16 legacy_status, legacy_speed;
+
+ /* Enable expansion register 0x42 (Operation mode status) */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
+
+ /* Get legacy speed operation status */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
+ &legacy_status);
+
+ DP(NETIF_MSG_LINK, "Legacy speed status"
+ " = 0x%x\n", legacy_status);
+ link_up = ((legacy_status & (1<<11)) == (1<<11));
+ if (link_up) {
+ legacy_speed = (legacy_status & (3<<9));
+ if (legacy_speed == (0<<9))
+ vars->line_speed = SPEED_10;
+ else if (legacy_speed == (1<<9))
+ vars->line_speed = SPEED_100;
+ else if (legacy_speed == (2<<9))
+ vars->line_speed = SPEED_1000;
+ else /* Should not happen */
+ vars->line_speed = 0;
- shift -= 4;
- digit = ((num & mask) >> shift);
- if (digit < 0xa)
- *str_ptr = digit + '0';
- else
- *str_ptr = digit - 0xa + 'a';
- str_ptr++;
- mask = mask >> 4;
- if (shift == 4*4) {
- *str_ptr = ':';
- str_ptr++;
+ if (legacy_status & (1<<8))
+ vars->duplex = DUPLEX_FULL;
+ else
+ vars->duplex = DUPLEX_HALF;
+
+ DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
+ " is_duplex_full= %d\n", vars->line_speed,
+ (vars->duplex == DUPLEX_FULL));
+ /* Check legacy speed AN resolution */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_LEGACY_MII_STATUS,
+ &val);
+ if (val & (1<<5))
+ vars->link_status |=
+ LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
+ &val);
+ if ((val & (1<<0)) == 0)
+ vars->link_status |=
+ LINK_STATUS_PARALLEL_DETECTION_USED;
}
}
- *str_ptr = '\0';
- return 0;
+ if (link_up) {
+ DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
+ vars->line_speed);
+ bnx2x_ext_phy_resolve_fc(phy, params, vars);
+ }
+
+ return link_up;
}
-u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
- u8 *version, u16 len)
+static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
{
- struct bnx2x *bp;
- u32 ext_phy_type = 0;
- u32 spirom_ver = 0;
- u8 status;
+ u8 status = 0;
+ u32 spirom_ver;
+ spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
+ status = bnx2x_format_ver(spirom_ver, str, len);
+ return status;
+}
- if (version == NULL || params == NULL)
- return -EINVAL;
- bp = params->bp;
+static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
+ bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
+}
- spirom_ver = REG_RD(bp, params->shmem_base +
- offsetof(struct shmem_region,
- port_mb[params->port].ext_phy_fw_version));
+static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ bnx2x_cl45_write(params->bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
+ bnx2x_cl45_write(params->bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
+}
- status = 0;
- /* reset the returned value to zero */
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW,
+ port);
+}
- if (len < 5)
- return -EINVAL;
+static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
+ struct link_params *params, u8 mode)
+{
+ struct bnx2x *bp = params->bp;
+ u16 val;
- version[0] = (spirom_ver & 0xFF);
- version[1] = (spirom_ver & 0xFF00) >> 8;
- version[2] = (spirom_ver & 0xFF0000) >> 16;
- version[3] = (spirom_ver & 0xFF000000) >> 24;
- version[4] = '\0';
+ switch (mode) {
+ case LED_MODE_OFF:
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- status = bnx2x_format_ver(spirom_ver, version, len);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 |
- (spirom_ver & 0x7F);
- status = bnx2x_format_ver(spirom_ver, version, len);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- version[0] = '\0';
- break;
+ DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
- " type is FAILURE!\n");
- status = -EINVAL;
+ if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
+ SHARED_HW_CFG_LED_EXTPHY1) {
+
+ /* Set LED masks */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED2_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED3_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED5_MASK,
+ 0x0);
+
+ } else {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x0);
+ }
break;
+ case LED_MODE_FRONT_PANEL_OFF:
- default:
+ DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
+ params->port);
+
+ if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
+ SHARED_HW_CFG_LED_EXTPHY1) {
+
+ /* Set LED masks */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED2_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED3_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED5_MASK,
+ 0x20);
+
+ } else {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x0);
+ }
break;
- }
- return status;
-}
+ case LED_MODE_ON:
-static void bnx2x_set_xgxs_loopback(struct link_params *params,
- struct link_vars *vars,
- u8 is_10g)
-{
- u8 port = params->port;
- struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port);
- if (is_10g) {
- u32 md_devad;
+ if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
+ SHARED_HW_CFG_LED_EXTPHY1) {
+ /* Set control reg */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL,
+ &val);
+ val &= 0x8000;
+ val |= 0x2492;
- DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL,
+ val);
- /* change the uni_phy_addr in the nig */
- md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
- port*0x18));
+ /* Set LED masks */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x0);
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED2_MASK,
+ 0x20);
- bnx2x_cl45_write(bp, port, 0,
- params->phy_addr,
- 5,
- (MDIO_REG_BANK_AER_BLOCK +
- (MDIO_AER_BLOCK_AER_REG & 0xf)),
- 0x2800);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED3_MASK,
+ 0x20);
- bnx2x_cl45_write(bp, port, 0,
- params->phy_addr,
- 5,
- (MDIO_REG_BANK_CL73_IEEEB0 +
- (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
- 0x6041);
- msleep(200);
- /* set aer mmd back */
- bnx2x_set_aer_mmd(params, vars);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED5_MASK,
+ 0x0);
+ } else {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x20);
+ }
+ break;
- /* and md_devad */
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
- md_devad);
+ case LED_MODE_OPER:
- } else {
- u16 mii_control;
+ DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port);
- DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
+ if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
+ SHARED_HW_CFG_LED_EXTPHY1) {
- CL45_RD_OVER_CL22(bp, port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
+ /* Set control reg */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL,
+ &val);
+
+ if (!((val &
+ MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
+ >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)){
+ DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL,
+ 0xa492);
+ }
- CL45_WR_OVER_CL22(bp, port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- (mii_control |
- MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
+ /* Set LED masks */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x10);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED2_MASK,
+ 0x80);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED3_MASK,
+ 0x98);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED5_MASK,
+ 0x40);
+
+ } else {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x80);
+ }
+ break;
}
}
+/******************************************************************/
+/* SFX7101 PHY SECTION */
+/******************************************************************/
+static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ /* SFX7101_XGXS_TEST1 */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
+}
-
-static void bnx2x_ext_phy_loopback(struct link_params *params)
+static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
+ u16 fw_ver1, fw_ver2, val;
struct bnx2x *bp = params->bp;
- u8 ext_phy_addr;
- u32 ext_phy_type;
+ DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
- if (params->switch_cfg == SWITCH_CFG_10G) {
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- /* CL37 Autoneg Enabled */
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
- DP(NETIF_MSG_LINK,
- "ext_phy_loopback: We should not get here\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 0x0001);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- /* SFX7101_XGXS_TEST1 */
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_XS_DEVAD,
- MDIO_XS_SFX7101_XGXS_TEST1,
- 0x100);
- DP(NETIF_MSG_LINK,
- "ext_phy_loopback: set ext phy loopback\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
+ /* HW reset */
+ bnx2x_ext_phy_hw_reset(bp, params->port);
+ bnx2x_wait_reset_complete(bp, phy);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
+ DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
+
+ bnx2x_ext_phy_set_pause(params, phy, vars);
+ /* Restart autoneg */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
+ val |= 0x200;
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
+
+ /* Save spirom version */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
+ bnx2x_save_spirom_version(bp, params->port,
+ (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
+ return 0;
+}
- break;
- } /* switch external PHY type */
- } else {
- /* serdes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- ext_phy_addr = (params->ext_phy_config &
- PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
- >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
+static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 link_up;
+ u16 val1, val2;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
+ val2, val1);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
+ val2, val1);
+ link_up = ((val1 & 4) == 4);
+ /* if link is up
+ * print the AN outcome of the SFX7101 PHY
+ */
+ if (link_up) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
+ &val2);
+ vars->line_speed = SPEED_10000;
+ DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
+ val2, (val2 & (1<<14)));
+ bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
+ bnx2x_ext_phy_resolve_fc(phy, params, vars);
}
+ return link_up;
}
-/*
- *------------------------------------------------------------------------
- * bnx2x_override_led_value -
- *
- * Override the led value of the requsted led
- *
- *------------------------------------------------------------------------
- */
-u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
- u32 led_idx, u32 value)
+static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
{
- u32 reg_val;
+ if (*len < 5)
+ return -EINVAL;
+ str[0] = (spirom_ver & 0xFF);
+ str[1] = (spirom_ver & 0xFF00) >> 8;
+ str[2] = (spirom_ver & 0xFF0000) >> 16;
+ str[3] = (spirom_ver & 0xFF000000) >> 24;
+ str[4] = '\0';
+ *len -= 5;
+ return 0;
+}
- /* If port 0 then use EMAC0, else use EMAC1*/
- u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
+{
+ u16 val, cnt;
- DP(NETIF_MSG_LINK,
- "bnx2x_override_led_value() port %x led_idx %d value %d\n",
- port, led_idx, value);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_RESET, &val);
- switch (led_idx) {
- case 0: /* 10MB led */
- /* Read the current value of the LED register in
- the EMAC block */
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 10M_OVERRIDE bit,
- otherwise reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_10MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
- break;
- case 1: /*100MB led */
- /*Read the current value of the LED register in
- the EMAC block */
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 100M_OVERRIDE bit,
- otherwise reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_100MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ for (cnt = 0; cnt < 10; cnt++) {
+ msleep(50);
+ /* Writes a self-clearing reset */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_RESET,
+ (val | (1<<15)));
+ /* Wait for clear */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_RESET, &val);
+
+ if ((val & (1<<15)) == 0)
+ break;
+ }
+}
+
+static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
+ struct link_params *params) {
+ /* Low power mode is controlled by GPIO 2 */
+ bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
+ /* The PHY reset is controlled by GPIO 1 */
+ bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
+}
+
+static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
+ struct link_params *params, u8 mode)
+{
+ u16 val = 0;
+ struct bnx2x *bp = params->bp;
+ switch (mode) {
+ case LED_MODE_FRONT_PANEL_OFF:
+ case LED_MODE_OFF:
+ val = 2;
break;
- case 2: /* 1000MB led */
- /* Read the current value of the LED register in the
- EMAC block */
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
- reset it. */
- reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ case LED_MODE_ON:
+ val = 1;
break;
- case 3: /* 2500MB led */
- /* Read the current value of the LED register in the
- EMAC block*/
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
- reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ case LED_MODE_OPER:
+ val = 0;
break;
- case 4: /*10G led */
- if (port == 0) {
- REG_WR(bp, NIG_REG_LED_10G_P0,
- value);
+ }
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7107_LINK_LED_CNTL,
+ val);
+}
+
+/******************************************************************/
+/* STATIC PHY DECLARATION */
+/******************************************************************/
+
+static struct bnx2x_phy phy_null = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
+ .addr = 0,
+ .flags = FLAGS_INIT_XGXS_FIRST,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = 0,
+ .media_type = ETH_PHY_NOT_PRESENT,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)NULL,
+ .read_status = (read_status_t)NULL,
+ .link_reset = (link_reset_t)NULL,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)NULL,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_serdes = {
+ .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
+ .addr = 0xff,
+ .flags = 0,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_2500baseX_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_UNSPECIFIED,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_init_serdes,
+ .read_status = (read_status_t)bnx2x_link_settings_status,
+ .link_reset = (link_reset_t)bnx2x_int_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)NULL,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_xgxs = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
+ .addr = 0xff,
+ .flags = 0,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_2500baseX_Full |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_UNSPECIFIED,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_init_xgxs,
+ .read_status = (read_status_t)bnx2x_link_settings_status,
+ .link_reset = (link_reset_t)bnx2x_int_link_reset,
+ .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
+ .format_fw_ver = (format_fw_ver_t)NULL,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_7101 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ .addr = 0xff,
+ .flags = FLAGS_FAN_FAILURE_DET_REQ,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_BASE_T,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_7101_config_init,
+ .read_status = (read_status_t)bnx2x_7101_read_status,
+ .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
+ .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver,
+ .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset,
+ .set_link_led = (set_link_led_t)bnx2x_7101_set_link_led,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+static struct bnx2x_phy phy_8073 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ .addr = 0xff,
+ .flags = FLAGS_HW_LOCK_REQUIRED,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_2500baseX_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_UNSPECIFIED,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8073_config_init,
+ .read_status = (read_status_t)bnx2x_8073_read_status,
+ .link_reset = (link_reset_t)bnx2x_8073_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+static struct bnx2x_phy phy_8705 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
+ .addr = 0xff,
+ .flags = FLAGS_INIT_XGXS_FIRST,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_XFP_FIBER,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8705_config_init,
+ .read_status = (read_status_t)bnx2x_8705_read_status,
+ .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+static struct bnx2x_phy phy_8706 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
+ .addr = 0xff,
+ .flags = FLAGS_INIT_XGXS_FIRST,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_SFP_FIBER,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8706_config_init,
+ .read_status = (read_status_t)bnx2x_8706_read_status,
+ .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_8726 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ .addr = 0xff,
+ .flags = (FLAGS_HW_LOCK_REQUIRED |
+ FLAGS_INIT_XGXS_FIRST),
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_SFP_FIBER,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8726_config_init,
+ .read_status = (read_status_t)bnx2x_8726_read_status,
+ .link_reset = (link_reset_t)bnx2x_8726_link_reset,
+ .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_8727 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+ .addr = 0xff,
+ .flags = FLAGS_FAN_FAILURE_DET_REQ,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_SFP_FIBER,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8727_config_init,
+ .read_status = (read_status_t)bnx2x_8727_read_status,
+ .link_reset = (link_reset_t)bnx2x_8727_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
+ .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset,
+ .set_link_led = (set_link_led_t)bnx2x_8727_set_link_led,
+ .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
+};
+static struct bnx2x_phy phy_8481 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+ .addr = 0xff,
+ .flags = FLAGS_FAN_FAILURE_DET_REQ |
+ FLAGS_REARM_LATCH_SIGNAL,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_BASE_T,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8481_config_init,
+ .read_status = (read_status_t)bnx2x_848xx_read_status,
+ .link_reset = (link_reset_t)bnx2x_8481_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
+ .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset,
+ .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_84823 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
+ .addr = 0xff,
+ .flags = FLAGS_FAN_FAILURE_DET_REQ |
+ FLAGS_REARM_LATCH_SIGNAL,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_BASE_T,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_848x3_config_init,
+ .read_status = (read_status_t)bnx2x_848xx_read_status,
+ .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+/*****************************************************************/
+/* */
+/* Populate the phy according. Main function: bnx2x_populate_phy */
+/* */
+/*****************************************************************/
+
+static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
+ struct bnx2x_phy *phy, u8 port,
+ u8 phy_index)
+{
+ /* Get the 4 lanes xgxs config rx and tx */
+ u32 rx = 0, tx = 0, i;
+ for (i = 0; i < 2; i++) {
+ /**
+ * INT_PHY and EXT_PHY1 share the same value location in the
+ * shmem. When num_phys is greater than 1, than this value
+ * applies only to EXT_PHY1
+ */
+ if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
+ rx = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
+
+ tx = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
} else {
- REG_WR(bp, NIG_REG_LED_10G_P1,
- value);
+ rx = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
+
+ tx = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
}
+
+ phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
+ phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
+
+ phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
+ phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
+ }
+}
+
+static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
+ u8 phy_index, u8 port)
+{
+ u32 ext_phy_config = 0;
+ switch (phy_index) {
+ case EXT_PHY1:
+ ext_phy_config = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].external_phy_config));
break;
- case 5: /* TRAFFIC led */
- /* Find if the traffic control is via BMAC or EMAC */
- if (port == 0)
- reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
- else
- reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
+ case EXT_PHY2:
+ ext_phy_config = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].external_phy_config2));
+ break;
+ default:
+ DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
+ return -EINVAL;
+ }
- /* Override the traffic led in the EMAC:*/
- if (reg_val == 1) {
- /* Read the current value of the LED register in
- the EMAC block */
- reg_val = REG_RD(bp, emac_base +
- EMAC_REG_EMAC_LED);
- /* Set the TRAFFIC_OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the TRAFFIC bit, otherwise
- reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
- (reg_val & ~EMAC_LED_TRAFFIC);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
- } else { /* Override the traffic led in the BMAC: */
- REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
- + port*4, 1);
- REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
- value);
- }
+ return ext_phy_config;
+}
+static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
+ struct bnx2x_phy *phy)
+{
+ u32 phy_addr;
+ u32 chip_id;
+ u32 switch_cfg = (REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_feature_config[port].link_config)) &
+ PORT_FEATURE_CONNECTED_SWITCH_MASK);
+ chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
+ switch (switch_cfg) {
+ case SWITCH_CFG_1G:
+ phy_addr = REG_RD(bp,
+ NIG_REG_SERDES0_CTRL_PHY_ADDR +
+ port * 0x10);
+ *phy = phy_serdes;
+ break;
+ case SWITCH_CFG_10G:
+ phy_addr = REG_RD(bp,
+ NIG_REG_XGXS0_CTRL_PHY_ADDR +
+ port * 0x18);
+ *phy = phy_xgxs;
break;
default:
- DP(NETIF_MSG_LINK,
- "bnx2x_override_led_value() unknown led index %d "
- "(should be 0-5)\n", led_idx);
+ DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
return -EINVAL;
}
+ phy->addr = (u8)phy_addr;
+ phy->mdio_ctrl = bnx2x_get_emac_base(bp,
+ SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
+ port);
+ if (CHIP_IS_E2(bp))
+ phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
+ else
+ phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
+ DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
+ port, phy->addr, phy->mdio_ctrl);
+
+ bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
return 0;
}
-
-u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed)
+static u8 bnx2x_populate_ext_phy(struct bnx2x *bp,
+ u8 phy_index,
+ u32 shmem_base,
+ u32 shmem2_base,
+ u8 port,
+ struct bnx2x_phy *phy)
{
- u8 port = params->port;
- u16 hw_led_mode = params->hw_led_mode;
- u8 rc = 0;
- u32 tmp;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- struct bnx2x *bp = params->bp;
- DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
- DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
- speed, hw_led_mode);
- switch (mode) {
- case LED_MODE_OFF:
- REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
- REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
- SHARED_HW_CFG_LED_MAC1);
-
- tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
- EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
+ u32 ext_phy_config, phy_type, config2;
+ u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
+ ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
+ phy_index, port);
+ phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
+ /* Select the phy type */
+ switch (phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
+ *phy = phy_8073;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ *phy = phy_8705;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ *phy = phy_8706;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
+ *phy = phy_8726;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
+ /* BCM8727_NOC => BCM8727 no over current */
+ mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
+ *phy = phy_8727;
+ phy->flags |= FLAGS_NOC;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
+ mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
+ *phy = phy_8727;
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+ *phy = phy_8481;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
+ *phy = phy_84823;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ *phy = phy_7101;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
+ *phy = phy_null;
+ return -EINVAL;
+ default:
+ *phy = phy_null;
+ return 0;
+ }
- case LED_MODE_OPER:
- if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
- REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
- REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
- } else {
- REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
- hw_led_mode);
- }
+ phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
+ bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
- REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
- port*4, 0);
- /* Set blinking rate to ~15.9Hz */
- REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
- LED_BLINK_RATE_VAL);
- REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
- port*4, 1);
- tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
- EMAC_WR(bp, EMAC_REG_EMAC_LED,
- (tmp & (~EMAC_LED_OVERRIDE)));
+ /**
+ * The shmem address of the phy version is located on different
+ * structures. In case this structure is too old, do not set
+ * the address
+ */
+ config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
+ dev_info.shared_hw_config.config2));
+ if (phy_index == EXT_PHY1) {
+ phy->ver_addr = shmem_base + offsetof(struct shmem_region,
+ port_mb[port].ext_phy_fw_version);
+
+ /* Check specific mdc mdio settings */
+ if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
+ mdc_mdio_access = config2 &
+ SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
+ } else {
+ u32 size = REG_RD(bp, shmem2_base);
- if (CHIP_IS_E1(bp) &&
- ((speed == SPEED_2500) ||
- (speed == SPEED_1000) ||
- (speed == SPEED_100) ||
- (speed == SPEED_10))) {
- /* On Everest 1 Ax chip versions for speeds less than
- 10G LED scheme is different */
- REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
- + port*4, 1);
- REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
- port*4, 0);
- REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
- port*4, 1);
+ if (size >
+ offsetof(struct shmem2_region, ext_phy_fw_version2)) {
+ phy->ver_addr = shmem2_base +
+ offsetof(struct shmem2_region,
+ ext_phy_fw_version2[port]);
}
- break;
-
- default:
- rc = -EINVAL;
- DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
- mode);
- break;
+ /* Check specific mdc mdio settings */
+ if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
+ mdc_mdio_access = (config2 &
+ SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
+ (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
+ SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
}
- return rc;
+ phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
+ /**
+ * In case mdc/mdio_access of the external phy is different than the
+ * mdc/mdio access of the XGXS, a HW lock must be taken in each access
+ * to prevent one port interfere with another port's CL45 operations.
+ */
+ if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
+ phy->flags |= FLAGS_HW_LOCK_REQUIRED;
+ DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
+ phy_type, port, phy_index);
+ DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n",
+ phy->addr, phy->mdio_ctrl);
+ return 0;
}
-u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
+static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
+ u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
{
- struct bnx2x *bp = params->bp;
- u16 gp_status = 0;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_GP_STATUS,
- MDIO_GP_STATUS_TOP_AN_STATUS1,
- &gp_status);
- /* link is up only if both local phy and external phy are up */
- if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
- bnx2x_ext_phy_is_link_up(params, vars, 1))
- return 0;
-
- return -ESRCH;
+ u8 status = 0;
+ phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
+ if (phy_index == INT_PHY)
+ return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
+ status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
+ port, phy);
+ return status;
}
-static u8 bnx2x_link_initialize(struct link_params *params,
- struct link_vars *vars)
+static void bnx2x_phy_def_cfg(struct link_params *params,
+ struct bnx2x_phy *phy,
+ u8 phy_index)
{
struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 rc = 0;
- u8 non_ext_phy;
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* Activate the external PHY */
- bnx2x_ext_phy_reset(params, vars);
-
- bnx2x_set_aer_mmd(params, vars);
+ u32 link_config;
+ /* Populate the default phy configuration for MF mode */
+ if (phy_index == EXT_PHY2) {
+ link_config = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region, dev_info.
+ port_feature_config[params->port].link_config2));
+ phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region, dev_info.
+ port_hw_config[params->port].speed_capability_mask2));
+ } else {
+ link_config = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region, dev_info.
+ port_feature_config[params->port].link_config));
+ phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region, dev_info.
+ port_hw_config[params->port].speed_capability_mask));
+ }
+ DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
+ " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
+
+ phy->req_duplex = DUPLEX_FULL;
+ switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
+ case PORT_FEATURE_LINK_SPEED_10M_HALF:
+ phy->req_duplex = DUPLEX_HALF;
+ case PORT_FEATURE_LINK_SPEED_10M_FULL:
+ phy->req_line_speed = SPEED_10;
+ break;
+ case PORT_FEATURE_LINK_SPEED_100M_HALF:
+ phy->req_duplex = DUPLEX_HALF;
+ case PORT_FEATURE_LINK_SPEED_100M_FULL:
+ phy->req_line_speed = SPEED_100;
+ break;
+ case PORT_FEATURE_LINK_SPEED_1G:
+ phy->req_line_speed = SPEED_1000;
+ break;
+ case PORT_FEATURE_LINK_SPEED_2_5G:
+ phy->req_line_speed = SPEED_2500;
+ break;
+ case PORT_FEATURE_LINK_SPEED_10G_CX4:
+ phy->req_line_speed = SPEED_10000;
+ break;
+ default:
+ phy->req_line_speed = SPEED_AUTO_NEG;
+ break;
+ }
- if (vars->phy_flags & PHY_XGXS_FLAG)
- bnx2x_set_master_ln(params);
+ switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) {
+ case PORT_FEATURE_FLOW_CONTROL_AUTO:
+ phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
+ break;
+ case PORT_FEATURE_FLOW_CONTROL_TX:
+ phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
+ break;
+ case PORT_FEATURE_FLOW_CONTROL_RX:
+ phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
+ break;
+ case PORT_FEATURE_FLOW_CONTROL_BOTH:
+ phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
+ break;
+ default:
+ phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+ break;
+ }
+}
- rc = bnx2x_reset_unicore(params);
- /* reset the SerDes and wait for reset bit return low */
- if (rc != 0)
- return rc;
+u32 bnx2x_phy_selection(struct link_params *params)
+{
+ u32 phy_config_swapped, prio_cfg;
+ u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
+
+ phy_config_swapped = params->multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED;
+
+ prio_cfg = params->multi_phy_config &
+ PORT_HW_CFG_PHY_SELECTION_MASK;
+
+ if (phy_config_swapped) {
+ switch (prio_cfg) {
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
+ return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
+ return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
+ return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
+ return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
+ break;
+ }
+ } else
+ return_cfg = prio_cfg;
- bnx2x_set_aer_mmd(params, vars);
+ return return_cfg;
+}
- /* setting the masterLn_def again after the reset */
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- bnx2x_set_master_ln(params);
- bnx2x_set_swap_lanes(params);
- }
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- if ((params->req_line_speed &&
- ((params->req_line_speed == SPEED_100) ||
- (params->req_line_speed == SPEED_10))) ||
- (!params->req_line_speed &&
- (params->speed_cap_mask >=
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
- (params->speed_cap_mask <
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
- )) {
- vars->phy_flags |= PHY_SGMII_FLAG;
- } else {
- vars->phy_flags &= ~PHY_SGMII_FLAG;
+u8 bnx2x_phy_probe(struct link_params *params)
+{
+ u8 phy_index, actual_phy_idx, link_cfg_idx;
+ u32 phy_config_swapped;
+ struct bnx2x *bp = params->bp;
+ struct bnx2x_phy *phy;
+ params->num_phys = 0;
+ DP(NETIF_MSG_LINK, "Begin phy probe\n");
+ phy_config_swapped = params->multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED;
+
+ for (phy_index = INT_PHY; phy_index < MAX_PHYS;
+ phy_index++) {
+ link_cfg_idx = LINK_CONFIG_IDX(phy_index);
+ actual_phy_idx = phy_index;
+ if (phy_config_swapped) {
+ if (phy_index == EXT_PHY1)
+ actual_phy_idx = EXT_PHY2;
+ else if (phy_index == EXT_PHY2)
+ actual_phy_idx = EXT_PHY1;
+ }
+ DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
+ " actual_phy_idx %x\n", phy_config_swapped,
+ phy_index, actual_phy_idx);
+ phy = &params->phy[actual_phy_idx];
+ if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
+ params->shmem2_base, params->port,
+ phy) != 0) {
+ params->num_phys = 0;
+ DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
+ phy_index);
+ for (phy_index = INT_PHY;
+ phy_index < MAX_PHYS;
+ phy_index++)
+ *phy = phy_null;
+ return -EINVAL;
}
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
+ break;
+
+ bnx2x_phy_def_cfg(params, phy, phy_index);
+ params->num_phys++;
}
- /* In case of external phy existance, the line speed would be the
- line speed linked up by the external phy. In case it is direct only,
- then the line_speed during initialization will be equal to the
- req_line_speed*/
- vars->line_speed = params->req_line_speed;
- bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
+ DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
+ return 0;
+}
- /* init ext phy and enable link state int */
- non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
- (params->loopback_mode == LOOPBACK_XGXS_10));
+u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx)
+{
+ if (phy_idx < params->num_phys)
+ return params->phy[phy_idx].supported;
+ return 0;
+}
- if (non_ext_phy ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
- (params->loopback_mode == LOOPBACK_EXT_PHY)) {
- if (params->req_line_speed == SPEED_AUTO_NEG)
- bnx2x_set_parallel_detection(params, vars->phy_flags);
- bnx2x_init_internal_phy(params, vars, non_ext_phy);
- }
+static void set_phy_vars(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 actual_phy_idx, phy_index, link_cfg_idx;
+ u8 phy_config_swapped = params->multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED;
+ for (phy_index = INT_PHY; phy_index < params->num_phys;
+ phy_index++) {
+ link_cfg_idx = LINK_CONFIG_IDX(phy_index);
+ actual_phy_idx = phy_index;
+ if (phy_config_swapped) {
+ if (phy_index == EXT_PHY1)
+ actual_phy_idx = EXT_PHY2;
+ else if (phy_index == EXT_PHY2)
+ actual_phy_idx = EXT_PHY1;
+ }
+ params->phy[actual_phy_idx].req_flow_ctrl =
+ params->req_flow_ctrl[link_cfg_idx];
- if (!non_ext_phy)
- rc |= bnx2x_ext_phy_init(params, vars);
+ params->phy[actual_phy_idx].req_line_speed =
+ params->req_line_speed[link_cfg_idx];
- bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_STATUS_XGXS0_LINK10G |
- NIG_STATUS_XGXS0_LINK_STATUS |
- NIG_STATUS_SERDES0_LINK_STATUS));
+ params->phy[actual_phy_idx].speed_cap_mask =
+ params->speed_cap_mask[link_cfg_idx];
- return rc;
+ params->phy[actual_phy_idx].req_duplex =
+ params->req_duplex[link_cfg_idx];
+ DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
+ " speed_cap_mask %x\n",
+ params->phy[actual_phy_idx].req_flow_ctrl,
+ params->phy[actual_phy_idx].req_line_speed,
+ params->phy[actual_phy_idx].speed_cap_mask);
+ }
}
-
u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
- u32 val;
-
DP(NETIF_MSG_LINK, "Phy Initialization started\n");
- DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
- params->req_line_speed, params->req_flow_ctrl);
+ DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
+ params->req_line_speed[0], params->req_flow_ctrl[0]);
+ DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
+ params->req_line_speed[1], params->req_flow_ctrl[1]);
vars->link_status = 0;
vars->phy_link_up = 0;
vars->link_up = 0;
@@ -5966,11 +6877,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
vars->duplex = DUPLEX_FULL;
vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
vars->mac_type = MAC_TYPE_NONE;
-
- if (params->switch_cfg == SWITCH_CFG_1G)
- vars->phy_flags = PHY_SERDES_FLAG;
- else
- vars->phy_flags = PHY_XGXS_FLAG;
+ vars->phy_flags = 0;
/* disable attentions */
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
@@ -5981,6 +6888,13 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
bnx2x_emac_init(params, vars);
+ if (params->num_phys == 0) {
+ DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
+ return -EINVAL;
+ }
+ set_phy_vars(params);
+
+ DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
if (CHIP_REV_IS_FPGA(bp)) {
vars->link_up = 1;
@@ -5999,7 +6913,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
}
bnx2x_emac_enable(params, vars, 0);
- bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
+ if (!(CHIP_IS_E2(bp)))
+ bnx2x_pbf_update(params, vars->flow_ctrl,
+ vars->line_speed);
/* disable drain */
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
@@ -6040,7 +6956,8 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
vars->phy_flags = PHY_XGXS_FLAG;
- bnx2x_phy_deassert(params, vars->phy_flags);
+ bnx2x_xgxs_deassert(params);
+
/* set bmac loopback */
bnx2x_bmac_enable(params, vars, 1);
@@ -6057,80 +6974,66 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
vars->phy_flags = PHY_XGXS_FLAG;
- bnx2x_phy_deassert(params, vars->phy_flags);
+ bnx2x_xgxs_deassert(params);
/* set bmac loopback */
bnx2x_emac_enable(params, vars, 1);
- bnx2x_emac_program(params, vars->line_speed,
- vars->duplex);
+ bnx2x_emac_program(params, vars);
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
params->port*4, 0);
- } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
+ } else if ((params->loopback_mode == LOOPBACK_XGXS) ||
(params->loopback_mode == LOOPBACK_EXT_PHY)) {
vars->link_up = 1;
- vars->line_speed = SPEED_10000;
- vars->duplex = DUPLEX_FULL;
vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+ vars->duplex = DUPLEX_FULL;
+ if (params->req_line_speed[0] == SPEED_1000) {
+ vars->line_speed = SPEED_1000;
+ vars->mac_type = MAC_TYPE_EMAC;
+ } else {
+ vars->line_speed = SPEED_10000;
+ vars->mac_type = MAC_TYPE_BMAC;
+ }
- vars->phy_flags = PHY_XGXS_FLAG;
-
- val = REG_RD(bp,
- NIG_REG_XGXS0_CTRL_PHY_ADDR+
- params->port*0x18);
- params->phy_addr = (u8)val;
-
- bnx2x_phy_deassert(params, vars->phy_flags);
+ bnx2x_xgxs_deassert(params);
bnx2x_link_initialize(params, vars);
- vars->mac_type = MAC_TYPE_BMAC;
-
+ if (params->req_line_speed[0] == SPEED_1000) {
+ bnx2x_emac_program(params, vars);
+ bnx2x_emac_enable(params, vars, 0);
+ } else
bnx2x_bmac_enable(params, vars, 0);
- if (params->loopback_mode == LOOPBACK_XGXS_10) {
+ if (params->loopback_mode == LOOPBACK_XGXS) {
/* set 10G XGXS loopback */
- bnx2x_set_xgxs_loopback(params, vars, 1);
+ params->phy[INT_PHY].config_loopback(
+ &params->phy[INT_PHY],
+ params);
+
} else {
/* set external phy loopback */
- bnx2x_ext_phy_loopback(params);
+ u8 phy_index;
+ for (phy_index = EXT_PHY1;
+ phy_index < params->num_phys; phy_index++) {
+ if (params->phy[phy_index].config_loopback)
+ params->phy[phy_index].config_loopback(
+ &params->phy[phy_index],
+ params);
+ }
}
+
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
params->port*4, 0);
- bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed);
+ bnx2x_set_led(params, vars,
+ LED_MODE_OPER, vars->line_speed);
} else
/* No loopback */
{
- bnx2x_phy_deassert(params, vars->phy_flags);
- switch (params->switch_cfg) {
- case SWITCH_CFG_1G:
- vars->phy_flags |= PHY_SERDES_FLAG;
- if ((params->ext_phy_config &
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
- vars->phy_flags |= PHY_SGMII_FLAG;
- }
-
- val = REG_RD(bp,
- NIG_REG_SERDES0_CTRL_PHY_ADDR+
- params->port*0x10);
-
- params->phy_addr = (u8)val;
-
- break;
- case SWITCH_CFG_10G:
- vars->phy_flags |= PHY_XGXS_FLAG;
- val = REG_RD(bp,
- NIG_REG_XGXS0_CTRL_PHY_ADDR+
- params->port*0x18);
- params->phy_addr = (u8)val;
-
- break;
- default:
- DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
- return -EINVAL;
- }
- DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
+ if (params->switch_cfg == SWITCH_CFG_10G)
+ bnx2x_xgxs_deassert(params);
+ else
+ bnx2x_serdes_deassert(bp, params->port);
bnx2x_link_initialize(params, vars);
msleep(30);
@@ -6138,29 +7041,11 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
}
return 0;
}
-
-static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
-{
- DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
-
- /* Set serial boot control for external load */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL, 0x0001);
-}
-
u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
u8 reset_ext_phy)
{
struct bnx2x *bp = params->bp;
- u32 ext_phy_config = params->ext_phy_config;
- u8 port = params->port;
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
- u32 val = REG_RD(bp, params->shmem_base +
- offsetof(struct shmem_region, dev_info.
- port_feature_config[params->port].
- config));
+ u8 phy_index, port = params->port;
DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
/* disable attentions */
vars->link_status = 0;
@@ -6189,73 +7074,21 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
* Hold it as vars low
*/
/* clear link led */
- bnx2x_set_led(params, LED_MODE_OFF, 0);
- if (reset_ext_phy) {
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- break;
+ bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- {
-
- /* Disable Transmitter */
- u8 ext_phy_addr =
- XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
- PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
- bnx2x_sfp_set_transmitter(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr, 0);
- break;
- }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
- "low power mode\n",
- port);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- {
- u8 ext_phy_addr =
- XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- /* Set soft reset */
- bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
- break;
- }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- {
- u8 ext_phy_addr =
- XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x0000);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 1);
- break;
- }
- default:
- /* HW reset */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
- DP(NETIF_MSG_LINK, "reset external PHY\n");
+ if (reset_ext_phy) {
+ for (phy_index = EXT_PHY1; phy_index < params->num_phys;
+ phy_index++) {
+ if (params->phy[phy_index].link_reset)
+ params->phy[phy_index].link_reset(
+ &params->phy[phy_index],
+ params);
}
}
- /* reset the SerDes/XGXS */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
- (0x1ff << (port*16)));
+ if (params->phy[INT_PHY].link_reset)
+ params->phy[INT_PHY].link_reset(
+ &params->phy[INT_PHY], params);
/* reset BigMac */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
@@ -6269,183 +7102,41 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
return 0;
}
-static u8 bnx2x_update_link_down(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
-
- DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
- bnx2x_set_led(params, LED_MODE_OFF, 0);
-
- /* indicate no mac active */
- vars->mac_type = MAC_TYPE_NONE;
-
- /* update shared memory */
- vars->link_status = 0;
- vars->line_speed = 0;
- bnx2x_update_mng(params, vars->link_status);
-
- /* activate nig drain */
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
-
- /* disable emac */
- REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
-
- msleep(10);
-
- /* reset BigMac */
- bnx2x_bmac_rx_disable(bp, params->port);
- REG_WR(bp, GRCBASE_MISC +
- MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
- return 0;
-}
-
-static u8 bnx2x_update_link_up(struct link_params *params,
- struct link_vars *vars,
- u8 link_10g, u32 gp_status)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 rc = 0;
-
- vars->link_status |= LINK_STATUS_LINK_UP;
- if (link_10g) {
- bnx2x_bmac_enable(params, vars, 0);
- bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000);
- } else {
- rc = bnx2x_emac_program(params, vars->line_speed,
- vars->duplex);
-
- bnx2x_emac_enable(params, vars, 0);
-
- /* AN complete? */
- if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
- if (!(vars->phy_flags &
- PHY_SGMII_FLAG))
- bnx2x_set_gmii_tx_driver(params);
- }
- }
-
- /* PBF - link up */
- rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
- vars->line_speed);
-
- /* disable drain */
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
-
- /* update shared memory */
- bnx2x_update_mng(params, vars->link_status);
- msleep(20);
- return rc;
-}
-/* This function should called upon link interrupt */
-/* In case vars->link_up, driver needs to
- 1. Update the pbf
- 2. Disable drain
- 3. Update the shared memory
- 4. Indicate link up
- 5. Set LEDs
- Otherwise,
- 1. Update shared memory
- 2. Reset BigMac
- 3. Report link down
- 4. Unset LEDs
-*/
-u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u16 gp_status;
- u8 link_10g;
- u8 ext_phy_link_up, rc = 0;
- u32 ext_phy_type;
- u8 is_mi_int = 0;
-
- DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
- port, (vars->phy_flags & PHY_XGXS_FLAG),
- REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
-
- is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
- port*0x18) > 0);
- DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
- REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
- is_mi_int,
- REG_RD(bp,
- NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
-
- DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
-
- /* disable emac */
- REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* Check external link change only for non-direct */
- ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int);
-
- /* Read gp_status */
- CL45_RD_OVER_CL22(bp, port, params->phy_addr,
- MDIO_REG_BANK_GP_STATUS,
- MDIO_GP_STATUS_TOP_AN_STATUS1,
- &gp_status);
-
- rc = bnx2x_link_settings_status(params, vars, gp_status,
- ext_phy_link_up);
- if (rc != 0)
- return rc;
-
- /* anything 10 and over uses the bmac */
- link_10g = ((vars->line_speed == SPEED_10000) ||
- (vars->line_speed == SPEED_12000) ||
- (vars->line_speed == SPEED_12500) ||
- (vars->line_speed == SPEED_13000) ||
- (vars->line_speed == SPEED_15000) ||
- (vars->line_speed == SPEED_16000));
-
- bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
-
- /* In case external phy link is up, and internal link is down
- ( not initialized yet probably after link initialization, it needs
- to be initialized.
- Note that after link down-up as result of cable plug,
- the xgxs link would probably become up again without the need to
- initialize it*/
-
- if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
- (ext_phy_link_up && !vars->phy_link_up))
- bnx2x_init_internal_phy(params, vars, 0);
-
- /* link is up only if both local phy and external phy are up */
- vars->link_up = (ext_phy_link_up && vars->phy_link_up);
-
- if (vars->link_up)
- rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
- else
- rc = bnx2x_update_link_down(params, vars);
-
- return rc;
-}
-
-static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
+/****************************************************************************/
+/* Common function */
+/****************************************************************************/
+static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
+ u32 shmem_base_path[],
+ u32 shmem2_base_path[], u8 phy_index,
+ u32 chip_id)
{
- u8 ext_phy_addr[PORT_MAX];
+ struct bnx2x_phy phy[PORT_MAX];
+ struct bnx2x_phy *phy_blk[PORT_MAX];
u16 val;
s8 port;
+ s8 port_of_path = 0;
/* PART1 - Reset both phys */
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
- /* Extract the ext phy address for the port */
- u32 ext_phy_config = REG_RD(bp, shmem_base +
- offsetof(struct shmem_region,
- dev_info.port_hw_config[port].external_phy_config));
+ u32 shmem_base, shmem2_base;
+ /* In E2, same phy is using for port0 of the two paths */
+ if (CHIP_IS_E2(bp)) {
+ shmem_base = shmem_base_path[port];
+ shmem2_base = shmem2_base_path[port];
+ port_of_path = 0;
+ } else {
+ shmem_base = shmem_base_path[0];
+ shmem2_base = shmem2_base_path[0];
+ port_of_path = port;
+ }
+ /* Extract the ext phy address for the port */
+ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
+ port_of_path, &phy[port]) !=
+ 0) {
+ DP(NETIF_MSG_LINK, "populate_phy failed\n");
+ return -EINVAL;
+ }
/* disable attentions */
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
(NIG_MASK_XGXS0_LINK_STATUS |
@@ -6453,17 +7144,13 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
NIG_MASK_SERDES0_LINK_STATUS |
NIG_MASK_MI_INT));
- ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
-
/* Need to take the phy out of low power mode in order
to write to access its registers */
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
/* Reset the phy */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_write(bp, &phy[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL,
1<<15);
@@ -6472,15 +7159,28 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
/* Add delay of 150ms after reset */
msleep(150);
+ if (phy[PORT_0].addr & 0x1) {
+ phy_blk[PORT_0] = &(phy[PORT_1]);
+ phy_blk[PORT_1] = &(phy[PORT_0]);
+ } else {
+ phy_blk[PORT_0] = &(phy[PORT_0]);
+ phy_blk[PORT_1] = &(phy[PORT_1]);
+ }
+
/* PART2 - Download firmware to both phys */
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
u16 fw_ver1;
+ if (CHIP_IS_E2(bp))
+ port_of_path = 0;
+ else
+ port_of_path = port;
- bnx2x_bcm8073_external_rom_boot(bp, port,
- ext_phy_addr[port], shmem_base);
+ DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
+ phy_blk[port]->addr);
+ bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
+ port_of_path);
- bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_read(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
@@ -6492,16 +7192,12 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
}
/* Only set bit 10 = 1 (Tx power down) */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_read(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_TX_POWER_DOWN, &val);
/* Phase1 of TX_POWER_DOWN reset */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_write(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_TX_POWER_DOWN,
(val | 1<<10));
@@ -6515,28 +7211,20 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
/* Phase2 of POWER_DOWN_RESET */
/* Release bit 10 (Release Tx power down) */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_read(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_TX_POWER_DOWN, &val);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_write(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
msleep(15);
/* Read modify write the SPI-ROM version select register */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_read(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_EDC_FFE_MAIN, &val);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_write(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
@@ -6545,46 +7233,111 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
}
return 0;
-
}
+static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
+ u32 shmem_base_path[],
+ u32 shmem2_base_path[], u8 phy_index,
+ u32 chip_id)
+{
+ u32 val;
+ s8 port;
+ struct bnx2x_phy phy;
+ /* Use port1 because of the static port-swap */
+ /* Enable the module detection interrupt */
+ val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
+ val |= ((1<<MISC_REGISTERS_GPIO_3)|
+ (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
+ REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
+
+ bnx2x_ext_phy_hw_reset(bp, 1);
+ msleep(5);
+ for (port = 0; port < PORT_MAX; port++) {
+ u32 shmem_base, shmem2_base;
+
+ /* In E2, same phy is using for port0 of the two paths */
+ if (CHIP_IS_E2(bp)) {
+ shmem_base = shmem_base_path[port];
+ shmem2_base = shmem2_base_path[port];
+ } else {
+ shmem_base = shmem_base_path[0];
+ shmem2_base = shmem2_base_path[0];
+ }
+ /* Extract the ext phy address for the port */
+ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
+ port, &phy) !=
+ 0) {
+ DP(NETIF_MSG_LINK, "populate phy failed\n");
+ return -EINVAL;
+ }
+
+ /* Reset phy*/
+ bnx2x_cl45_write(bp, &phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
+
+
+ /* Set fault module detected LED on */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_HIGH,
+ port);
+ }
-static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
+ return 0;
+}
+static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
+ u32 shmem_base_path[],
+ u32 shmem2_base_path[], u8 phy_index,
+ u32 chip_id)
{
- u8 ext_phy_addr[PORT_MAX];
- s8 port, first_port, i;
+ s8 port;
u32 swap_val, swap_override;
- DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
+ struct bnx2x_phy phy[PORT_MAX];
+ struct bnx2x_phy *phy_blk[PORT_MAX];
+ s8 port_of_path;
swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
- bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override));
- msleep(5);
+ port = 1;
- if (swap_val && swap_override)
- first_port = PORT_0;
- else
- first_port = PORT_1;
+ bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override));
+
+ /* Calculate the port based on port swap */
+ port ^= (swap_val && swap_override);
+
+ msleep(5);
/* PART1 - Reset both phys */
- for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
- /* Extract the ext phy address for the port */
- u32 ext_phy_config = REG_RD(bp, shmem_base +
- offsetof(struct shmem_region,
- dev_info.port_hw_config[port].external_phy_config));
+ for (port = PORT_MAX - 1; port >= PORT_0; port--) {
+ u32 shmem_base, shmem2_base;
+
+ /* In E2, same phy is using for port0 of the two paths */
+ if (CHIP_IS_E2(bp)) {
+ shmem_base = shmem_base_path[port];
+ shmem2_base = shmem2_base_path[port];
+ port_of_path = 0;
+ } else {
+ shmem_base = shmem_base_path[0];
+ shmem2_base = shmem2_base_path[0];
+ port_of_path = port;
+ }
+ /* Extract the ext phy address for the port */
+ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
+ port_of_path, &phy[port]) !=
+ 0) {
+ DP(NETIF_MSG_LINK, "populate phy failed\n");
+ return -EINVAL;
+ }
/* disable attentions */
- bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- (NIG_MASK_XGXS0_LINK_STATUS |
- NIG_MASK_XGXS0_LINK10G |
- NIG_MASK_SERDES0_LINK_STATUS |
- NIG_MASK_MI_INT));
+ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
+ port_of_path*4,
+ (NIG_MASK_XGXS0_LINK_STATUS |
+ NIG_MASK_XGXS0_LINK10G |
+ NIG_MASK_SERDES0_LINK_STATUS |
+ NIG_MASK_MI_INT));
- ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
/* Reset the phy */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr[port],
+ bnx2x_cl45_write(bp, &phy[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL,
1<<15);
@@ -6592,16 +7345,25 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
/* Add delay of 150ms after reset */
msleep(150);
-
+ if (phy[PORT_0].addr & 0x1) {
+ phy_blk[PORT_0] = &(phy[PORT_1]);
+ phy_blk[PORT_1] = &(phy[PORT_0]);
+ } else {
+ phy_blk[PORT_0] = &(phy[PORT_0]);
+ phy_blk[PORT_1] = &(phy[PORT_1]);
+ }
/* PART2 - Download firmware to both phys */
- for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
+ for (port = PORT_MAX - 1; port >= PORT_0; port--) {
u16 fw_ver1;
-
- bnx2x_bcm8727_external_rom_boot(bp, port,
- ext_phy_addr[port], shmem_base);
-
- bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr[port],
+ if (CHIP_IS_E2(bp))
+ port_of_path = 0;
+ else
+ port_of_path = port;
+ DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
+ phy_blk[port]->addr);
+ bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
+ port_of_path);
+ bnx2x_cl45_read(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
@@ -6616,82 +7378,35 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
return 0;
}
-
-static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
-{
- u8 ext_phy_addr;
- u32 val;
- s8 port;
-
- /* Use port1 because of the static port-swap */
- /* Enable the module detection interrupt */
- val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
- val |= ((1<<MISC_REGISTERS_GPIO_3)|
- (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
- REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
-
- bnx2x_ext_phy_hw_reset(bp, 1);
- msleep(5);
- for (port = 0; port < PORT_MAX; port++) {
- /* Extract the ext phy address for the port */
- u32 ext_phy_config = REG_RD(bp, shmem_base +
- offsetof(struct shmem_region,
- dev_info.port_hw_config[port].external_phy_config));
-
- ext_phy_addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
- DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
- ext_phy_addr);
-
- bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
-
- /* Set fault module detected LED on */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
- MISC_REGISTERS_GPIO_HIGH,
- port);
- }
-
- return 0;
-}
-
-
-static u8 bnx2x_84823_common_init_phy(struct bnx2x *bp, u32 shmem_base)
-{
- /* HW reset */
- bnx2x_ext_phy_hw_reset(bp, 1);
- return 0;
-}
-u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
+static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
+ u32 shmem2_base_path[], u8 phy_index,
+ u32 ext_phy_type, u32 chip_id)
{
u8 rc = 0;
- u32 ext_phy_type;
-
- DP(NETIF_MSG_LINK, "Begin common phy init\n");
-
- /* Read the ext_phy_type for arbitrary port(0) */
- ext_phy_type = XGXS_EXT_PHY_TYPE(
- REG_RD(bp, shmem_base +
- offsetof(struct shmem_region,
- dev_info.port_hw_config[0].external_phy_config)));
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- rc = bnx2x_8073_common_init_phy(bp, shmem_base);
+ rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
+ shmem2_base_path,
+ phy_index, chip_id);
break;
- }
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
- rc = bnx2x_8727_common_init_phy(bp, shmem_base);
+ rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
+ shmem2_base_path,
+ phy_index, chip_id);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
/* GPIO1 affects both ports, so there's need to pull
it for single port alone */
- rc = bnx2x_8726_common_init_phy(bp, shmem_base);
+ rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
+ shmem2_base_path,
+ phy_index, chip_id);
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- rc = bnx2x_84823_common_init_phy(bp, shmem_base);
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
+ rc = -EINVAL;
break;
default:
DP(NETIF_MSG_LINK,
@@ -6703,33 +7418,81 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
return rc;
}
-void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
+u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
+ u32 shmem2_base_path[], u32 chip_id)
{
- u16 val, cnt;
+ u8 rc = 0;
+ u8 phy_index;
+ u32 ext_phy_type, ext_phy_config;
+ DP(NETIF_MSG_LINK, "Begin common phy init\n");
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_RESET, &val);
+ if (CHIP_REV_IS_EMUL(bp))
+ return 0;
- for (cnt = 0; cnt < 10; cnt++) {
- msleep(50);
- /* Writes a self-clearing reset */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_RESET,
- (val | (1<<15)));
- /* Wait for clear */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_RESET, &val);
+ /* Read the ext_phy_type for arbitrary port(0) */
+ for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
+ phy_index++) {
+ ext_phy_config = bnx2x_get_ext_phy_config(bp,
+ shmem_base_path[0],
+ phy_index, 0);
+ ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
+ rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
+ shmem2_base_path,
+ phy_index, ext_phy_type,
+ chip_id);
+ }
+ return rc;
+}
- if ((val & (1<<15)) == 0)
- break;
+u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
+{
+ u8 phy_index;
+ struct bnx2x_phy phy;
+ for (phy_index = INT_PHY; phy_index < MAX_PHYS;
+ phy_index++) {
+ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
+ 0, &phy) != 0) {
+ DP(NETIF_MSG_LINK, "populate phy failed\n");
+ return 0;
+ }
+
+ if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
+ return 1;
+ }
+ return 0;
+}
+
+u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
+ u32 shmem_base,
+ u32 shmem2_base,
+ u8 port)
+{
+ u8 phy_index, fan_failure_det_req = 0;
+ struct bnx2x_phy phy;
+ for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
+ phy_index++) {
+ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
+ port, &phy)
+ != 0) {
+ DP(NETIF_MSG_LINK, "populate phy failed\n");
+ return 0;
+ }
+ fan_failure_det_req |= (phy.flags &
+ FLAGS_FAN_FAILURE_DET_REQ);
+ }
+ return fan_failure_det_req;
+}
+
+void bnx2x_hw_reset_phy(struct link_params *params)
+{
+ u8 phy_index;
+ for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
+ phy_index++) {
+ if (params->phy[phy_index].hw_reset) {
+ params->phy[phy_index].hw_reset(
+ &params->phy[phy_index],
+ params);
+ params->phy[phy_index] = phy_null;
+ }
}
}
diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h
index 40c2981de8ed..58a4c7199276 100644
--- a/drivers/net/bnx2x/bnx2x_link.h
+++ b/drivers/net/bnx2x/bnx2x_link.h
@@ -1,4 +1,4 @@
-/* Copyright 2008-2009 Broadcom Corporation
+/* Copyright 2008-2010 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -22,7 +22,8 @@
/***********************************************************/
/* Defines */
/***********************************************************/
-#define DEFAULT_PHY_DEV_ADDR 3
+#define DEFAULT_PHY_DEV_ADDR 3
+#define E2_DEFAULT_PHY_DEV_ADDR 5
@@ -46,9 +47,137 @@
#define SFP_EEPROM_PART_NO_ADDR 0x28
#define SFP_EEPROM_PART_NO_SIZE 16
#define PWR_FLT_ERR_MSG_LEN 250
+
+#define XGXS_EXT_PHY_TYPE(ext_phy_config) \
+ ((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
+#define XGXS_EXT_PHY_ADDR(ext_phy_config) \
+ (((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT)
+#define SERDES_EXT_PHY_TYPE(ext_phy_config) \
+ ((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
+
+/* Single Media Direct board is the plain 577xx board with CX4/RJ45 jacks */
+#define SINGLE_MEDIA_DIRECT(params) (params->num_phys == 1)
+/* Single Media board contains single external phy */
+#define SINGLE_MEDIA(params) (params->num_phys == 2)
+/* Dual Media board contains two external phy with different media */
+#define DUAL_MEDIA(params) (params->num_phys == 3)
+#define FW_PARAM_MDIO_CTRL_OFFSET 16
+#define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \
+ (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET)
/***********************************************************/
/* Structs */
/***********************************************************/
+#define INT_PHY 0
+#define EXT_PHY1 1
+#define EXT_PHY2 2
+#define MAX_PHYS 3
+
+/* Same configuration is shared between the XGXS and the first external phy */
+#define LINK_CONFIG_SIZE (MAX_PHYS - 1)
+#define LINK_CONFIG_IDX(_phy_idx) ((_phy_idx == INT_PHY) ? \
+ 0 : (_phy_idx - 1))
+/***********************************************************/
+/* bnx2x_phy struct */
+/* Defines the required arguments and function per phy */
+/***********************************************************/
+struct link_vars;
+struct link_params;
+struct bnx2x_phy;
+
+typedef u8 (*config_init_t)(struct bnx2x_phy *phy, struct link_params *params,
+ struct link_vars *vars);
+typedef u8 (*read_status_t)(struct bnx2x_phy *phy, struct link_params *params,
+ struct link_vars *vars);
+typedef void (*link_reset_t)(struct bnx2x_phy *phy,
+ struct link_params *params);
+typedef void (*config_loopback_t)(struct bnx2x_phy *phy,
+ struct link_params *params);
+typedef u8 (*format_fw_ver_t)(u32 raw, u8 *str, u16 *len);
+typedef void (*hw_reset_t)(struct bnx2x_phy *phy, struct link_params *params);
+typedef void (*set_link_led_t)(struct bnx2x_phy *phy,
+ struct link_params *params, u8 mode);
+typedef void (*phy_specific_func_t)(struct bnx2x_phy *phy,
+ struct link_params *params, u32 action);
+
+struct bnx2x_phy {
+ u32 type;
+
+ /* Loaded during init */
+ u8 addr;
+
+ u8 flags;
+ /* Require HW lock */
+#define FLAGS_HW_LOCK_REQUIRED (1<<0)
+ /* No Over-Current detection */
+#define FLAGS_NOC (1<<1)
+ /* Fan failure detection required */
+#define FLAGS_FAN_FAILURE_DET_REQ (1<<2)
+ /* Initialize first the XGXS and only then the phy itself */
+#define FLAGS_INIT_XGXS_FIRST (1<<3)
+#define FLAGS_REARM_LATCH_SIGNAL (1<<6)
+#define FLAGS_SFP_NOT_APPROVED (1<<7)
+
+ u8 def_md_devad;
+ u8 reserved;
+ /* preemphasis values for the rx side */
+ u16 rx_preemphasis[4];
+
+ /* preemphasis values for the tx side */
+ u16 tx_preemphasis[4];
+
+ /* EMAC address for access MDIO */
+ u32 mdio_ctrl;
+
+ u32 supported;
+
+ u32 media_type;
+#define ETH_PHY_UNSPECIFIED 0x0
+#define ETH_PHY_SFP_FIBER 0x1
+#define ETH_PHY_XFP_FIBER 0x2
+#define ETH_PHY_DA_TWINAX 0x3
+#define ETH_PHY_BASE_T 0x4
+#define ETH_PHY_NOT_PRESENT 0xff
+
+ /* The address in which version is located*/
+ u32 ver_addr;
+
+ u16 req_flow_ctrl;
+
+ u16 req_line_speed;
+
+ u32 speed_cap_mask;
+
+ u16 req_duplex;
+ u16 rsrv;
+ /* Called per phy/port init, and it configures LASI, speed, autoneg,
+ duplex, flow control negotiation, etc. */
+ config_init_t config_init;
+
+ /* Called due to interrupt. It determines the link, speed */
+ read_status_t read_status;
+
+ /* Called when driver is unloading. Should reset the phy */
+ link_reset_t link_reset;
+
+ /* Set the loopback configuration for the phy */
+ config_loopback_t config_loopback;
+
+ /* Format the given raw number into str up to len */
+ format_fw_ver_t format_fw_ver;
+
+ /* Reset the phy (both ports) */
+ hw_reset_t hw_reset;
+
+ /* Set link led mode (on/off/oper)*/
+ set_link_led_t set_link_led;
+
+ /* PHY Specific tasks */
+ phy_specific_func_t phy_specific_func;
+#define DISABLE_TX 1
+#define ENABLE_TX 2
+};
+
/* Inputs parameters to the CLC */
struct link_params {
@@ -59,56 +188,50 @@ struct link_params {
#define LOOPBACK_NONE 0
#define LOOPBACK_EMAC 1
#define LOOPBACK_BMAC 2
-#define LOOPBACK_XGXS_10 3
+#define LOOPBACK_XGXS 3
#define LOOPBACK_EXT_PHY 4
#define LOOPBACK_EXT 5
- u16 req_duplex;
- u16 req_flow_ctrl;
- u16 req_fc_auto_adv; /* Should be set to TX / BOTH when
- req_flow_ctrl is set to AUTO */
- u16 req_line_speed; /* Also determine AutoNeg */
-
/* Device parameters */
u8 mac_addr[6];
+ u16 req_duplex[LINK_CONFIG_SIZE];
+ u16 req_flow_ctrl[LINK_CONFIG_SIZE];
+
+ u16 req_line_speed[LINK_CONFIG_SIZE]; /* Also determine AutoNeg */
+
/* shmem parameters */
u32 shmem_base;
- u32 speed_cap_mask;
+ u32 shmem2_base;
+ u32 speed_cap_mask[LINK_CONFIG_SIZE];
u32 switch_cfg;
#define SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH
#define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH
#define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT
- u16 hw_led_mode; /* part of the hw_config read from the shmem */
-
- /* phy_addr populated by the phy_init function */
- u8 phy_addr;
- /*u8 reserved1;*/
-
u32 lane_config;
- u32 ext_phy_config;
-#define XGXS_EXT_PHY_TYPE(ext_phy_config) \
- ((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
-#define XGXS_EXT_PHY_ADDR(ext_phy_config) \
- (((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT)
-#define SERDES_EXT_PHY_TYPE(ext_phy_config) \
- ((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
/* Phy register parameter */
u32 chip_id;
- u16 xgxs_config_rx[4]; /* preemphasis values for the rx side */
- u16 xgxs_config_tx[4]; /* preemphasis values for the tx side */
-
u32 feature_config_flags;
#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
#define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2)
-#define FEATURE_CONFIG_BCM8727_NOC (1<<3)
+#define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3)
+ /* Will be populated during common init */
+ struct bnx2x_phy phy[MAX_PHYS];
+
+ /* Will be populated during common init */
+ u8 num_phys;
+
+ u8 rsrv;
+ u16 hw_led_mode; /* part of the hw_config read from the shmem */
+ u32 multi_phy_config;
/* Device pointer passed to all callback functions */
struct bnx2x *bp;
+ u16 req_fc_auto_adv; /* Should be set to TX / BOTH when
+ req_flow_ctrl is set to AUTO */
};
/* Output parameters */
@@ -129,12 +252,6 @@ struct link_vars {
u16 flow_ctrl;
u16 ieee_fc;
- u32 autoneg;
-#define AUTO_NEG_DISABLED 0x0
-#define AUTO_NEG_ENABLED 0x1
-#define AUTO_NEG_COMPLETE 0x2
-#define AUTO_NEG_PARALLEL_DETECTION_USED 0x3
-
/* The same definitions as the shmem parameter */
u32 link_status;
};
@@ -142,8 +259,6 @@ struct link_vars {
/***********************************************************/
/* Functions */
/***********************************************************/
-
-/* Initialize the phy */
u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output);
/* Reset the link. Should be called when driver or interface goes down
@@ -155,17 +270,21 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
/* bnx2x_link_update should be called upon link interrupt */
u8 bnx2x_link_update(struct link_params *input, struct link_vars *output);
-/* use the following cl45 functions to read/write from external_phy
+/* use the following phy functions to read/write from external_phy
In order to use it to read/write internal phy registers, use
DEFAULT_PHY_DEV_ADDR as devad, and (_bank + (_addr & 0xf)) as
- Use ext_phy_type of 0 in case of cl22 over cl45
the register */
-u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 *ret_val);
+u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
+ u8 devad, u16 reg, u16 *ret_val);
+
+u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
+ u8 devad, u16 reg, u16 val);
-u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 val);
+u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
+ u8 devad, u16 reg, u16 *ret_val);
+u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
+ u8 devad, u16 reg, u16 val);
/* Reads the link_status from the shmem,
and update the link vars accordingly */
void bnx2x_link_status_update(struct link_params *input,
@@ -178,9 +297,12 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
Basically, the CLC takes care of the led for the link, but in case one needs
to set/unset the led unnaturally, set the "mode" to LED_MODE_OPER to
blink the led, and LED_MODE_OFF to set the led off.*/
-u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed);
-#define LED_MODE_OFF 0
-#define LED_MODE_OPER 2
+u8 bnx2x_set_led(struct link_params *params, struct link_vars *vars,
+ u8 mode, u32 speed);
+#define LED_MODE_OFF 0
+#define LED_MODE_ON 1
+#define LED_MODE_OPER 2
+#define LED_MODE_FRONT_PANEL_OFF 3
u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value);
@@ -190,17 +312,39 @@ void bnx2x_handle_module_detect_int(struct link_params *params);
/* Get the actual link status. In case it returns 0, link is up,
otherwise link is down*/
-u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
+u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars,
+ u8 is_serdes);
/* One-time initialization for external phy after power up */
-u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base);
+u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
+ u32 shmem2_base_path[], u32 chip_id);
/* Reset the external PHY using GPIO */
void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port);
-void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr);
+/* Reset the external of SFX7101 */
+void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy);
-u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
+u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
+ struct link_params *params, u16 addr,
u8 byte_cnt, u8 *o_buf);
+void bnx2x_hw_reset_phy(struct link_params *params);
+
+/* Checks if HW lock is required for this phy/board type */
+u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base,
+ u32 shmem2_base);
+
+/* Returns the aggregative supported attributes of the phys on board */
+u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx);
+
+/* Check swap bit and adjust PHY order */
+u32 bnx2x_phy_selection(struct link_params *params);
+
+/* Probe the phys on board, and populate them in "params" */
+u8 bnx2x_phy_probe(struct link_params *params);
+/* Checks if fan failure detection is required on one of the phys on board */
+u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base,
+ u32 shmem2_base, u8 port);
+
#endif /* BNX2X_LINK_H */
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index f8c3f08e4ce7..ff99a2fc0426 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -23,7 +23,6 @@
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/init.h>
@@ -57,7 +56,6 @@
#include "bnx2x_init_ops.h"
#include "bnx2x_cmn.h"
-
#include <linux/firmware.h>
#include "bnx2x_fw_file_hdr.h"
/* FW files */
@@ -66,8 +64,9 @@
__stringify(BCM_5710_FW_MINOR_VERSION) "." \
__stringify(BCM_5710_FW_REVISION_VERSION) "." \
__stringify(BCM_5710_FW_ENGINEERING_VERSION)
-#define FW_FILE_NAME_E1 "bnx2x-e1-" FW_FILE_VERSION ".fw"
-#define FW_FILE_NAME_E1H "bnx2x-e1h-" FW_FILE_VERSION ".fw"
+#define FW_FILE_NAME_E1 "bnx2x/bnx2x-e1-" FW_FILE_VERSION ".fw"
+#define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw"
+#define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw"
/* Time in jiffies before concluding the transmitter is hung */
#define TX_TIMEOUT (5*HZ)
@@ -77,18 +76,20 @@ static char version[] __devinitdata =
DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Eliezer Tamir");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver");
+MODULE_DESCRIPTION("Broadcom NetXtreme II "
+ "BCM57710/57711/57711E/57712/57712E Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
MODULE_FIRMWARE(FW_FILE_NAME_E1);
MODULE_FIRMWARE(FW_FILE_NAME_E1H);
+MODULE_FIRMWARE(FW_FILE_NAME_E2);
static int multi_mode = 1;
module_param(multi_mode, int, 0);
MODULE_PARM_DESC(multi_mode, " Multi queue mode "
"(0 Disable; 1 Enable (default))");
-static int num_queues;
+int num_queues;
module_param(num_queues, int, 0);
MODULE_PARM_DESC(num_queues, " Number of queues for multi_mode=1"
" (default is as a number of CPUs)");
@@ -124,6 +125,8 @@ enum bnx2x_board_type {
BCM57710 = 0,
BCM57711 = 1,
BCM57711E = 2,
+ BCM57712 = 3,
+ BCM57712E = 4
};
/* indexed by board_type, above */
@@ -132,14 +135,24 @@ static struct {
} board_info[] __devinitdata = {
{ "Broadcom NetXtreme II BCM57710 XGb" },
{ "Broadcom NetXtreme II BCM57711 XGb" },
- { "Broadcom NetXtreme II BCM57711E XGb" }
+ { "Broadcom NetXtreme II BCM57711E XGb" },
+ { "Broadcom NetXtreme II BCM57712 XGb" },
+ { "Broadcom NetXtreme II BCM57712E XGb" }
};
+#ifndef PCI_DEVICE_ID_NX2_57712
+#define PCI_DEVICE_ID_NX2_57712 0x1662
+#endif
+#ifndef PCI_DEVICE_ID_NX2_57712E
+#define PCI_DEVICE_ID_NX2_57712E 0x1663
+#endif
static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = {
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57710), BCM57710 },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711), BCM57711 },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711E), BCM57711E },
+ { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712), BCM57712 },
+ { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712E), BCM57712E },
{ 0 }
};
@@ -149,6 +162,244 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl);
* General service functions
****************************************************************************/
+static inline void __storm_memset_dma_mapping(struct bnx2x *bp,
+ u32 addr, dma_addr_t mapping)
+{
+ REG_WR(bp, addr, U64_LO(mapping));
+ REG_WR(bp, addr + 4, U64_HI(mapping));
+}
+
+static inline void __storm_memset_fill(struct bnx2x *bp,
+ u32 addr, size_t size, u32 val)
+{
+ int i;
+ for (i = 0; i < size/4; i++)
+ REG_WR(bp, addr + (i * 4), val);
+}
+
+static inline void storm_memset_ustats_zero(struct bnx2x *bp,
+ u8 port, u16 stat_id)
+{
+ size_t size = sizeof(struct ustorm_per_client_stats);
+
+ u32 addr = BAR_USTRORM_INTMEM +
+ USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id);
+
+ __storm_memset_fill(bp, addr, size, 0);
+}
+
+static inline void storm_memset_tstats_zero(struct bnx2x *bp,
+ u8 port, u16 stat_id)
+{
+ size_t size = sizeof(struct tstorm_per_client_stats);
+
+ u32 addr = BAR_TSTRORM_INTMEM +
+ TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id);
+
+ __storm_memset_fill(bp, addr, size, 0);
+}
+
+static inline void storm_memset_xstats_zero(struct bnx2x *bp,
+ u8 port, u16 stat_id)
+{
+ size_t size = sizeof(struct xstorm_per_client_stats);
+
+ u32 addr = BAR_XSTRORM_INTMEM +
+ XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id);
+
+ __storm_memset_fill(bp, addr, size, 0);
+}
+
+
+static inline void storm_memset_spq_addr(struct bnx2x *bp,
+ dma_addr_t mapping, u16 abs_fid)
+{
+ u32 addr = XSEM_REG_FAST_MEMORY +
+ XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid);
+
+ __storm_memset_dma_mapping(bp, addr, mapping);
+}
+
+static inline void storm_memset_ov(struct bnx2x *bp, u16 ov, u16 abs_fid)
+{
+ REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(abs_fid), ov);
+}
+
+static inline void storm_memset_func_cfg(struct bnx2x *bp,
+ struct tstorm_eth_function_common_config *tcfg,
+ u16 abs_fid)
+{
+ size_t size = sizeof(struct tstorm_eth_function_common_config);
+
+ u32 addr = BAR_TSTRORM_INTMEM +
+ TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(abs_fid);
+
+ __storm_memset_struct(bp, addr, size, (u32 *)tcfg);
+}
+
+static inline void storm_memset_xstats_flags(struct bnx2x *bp,
+ struct stats_indication_flags *flags,
+ u16 abs_fid)
+{
+ size_t size = sizeof(struct stats_indication_flags);
+
+ u32 addr = BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(abs_fid);
+
+ __storm_memset_struct(bp, addr, size, (u32 *)flags);
+}
+
+static inline void storm_memset_tstats_flags(struct bnx2x *bp,
+ struct stats_indication_flags *flags,
+ u16 abs_fid)
+{
+ size_t size = sizeof(struct stats_indication_flags);
+
+ u32 addr = BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(abs_fid);
+
+ __storm_memset_struct(bp, addr, size, (u32 *)flags);
+}
+
+static inline void storm_memset_ustats_flags(struct bnx2x *bp,
+ struct stats_indication_flags *flags,
+ u16 abs_fid)
+{
+ size_t size = sizeof(struct stats_indication_flags);
+
+ u32 addr = BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(abs_fid);
+
+ __storm_memset_struct(bp, addr, size, (u32 *)flags);
+}
+
+static inline void storm_memset_cstats_flags(struct bnx2x *bp,
+ struct stats_indication_flags *flags,
+ u16 abs_fid)
+{
+ size_t size = sizeof(struct stats_indication_flags);
+
+ u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(abs_fid);
+
+ __storm_memset_struct(bp, addr, size, (u32 *)flags);
+}
+
+static inline void storm_memset_xstats_addr(struct bnx2x *bp,
+ dma_addr_t mapping, u16 abs_fid)
+{
+ u32 addr = BAR_XSTRORM_INTMEM +
+ XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid);
+
+ __storm_memset_dma_mapping(bp, addr, mapping);
+}
+
+static inline void storm_memset_tstats_addr(struct bnx2x *bp,
+ dma_addr_t mapping, u16 abs_fid)
+{
+ u32 addr = BAR_TSTRORM_INTMEM +
+ TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid);
+
+ __storm_memset_dma_mapping(bp, addr, mapping);
+}
+
+static inline void storm_memset_ustats_addr(struct bnx2x *bp,
+ dma_addr_t mapping, u16 abs_fid)
+{
+ u32 addr = BAR_USTRORM_INTMEM +
+ USTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid);
+
+ __storm_memset_dma_mapping(bp, addr, mapping);
+}
+
+static inline void storm_memset_cstats_addr(struct bnx2x *bp,
+ dma_addr_t mapping, u16 abs_fid)
+{
+ u32 addr = BAR_CSTRORM_INTMEM +
+ CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid);
+
+ __storm_memset_dma_mapping(bp, addr, mapping);
+}
+
+static inline void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid,
+ u16 pf_id)
+{
+ REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid),
+ pf_id);
+ REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid),
+ pf_id);
+ REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid),
+ pf_id);
+ REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid),
+ pf_id);
+}
+
+static inline void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid,
+ u8 enable)
+{
+ REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid),
+ enable);
+ REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid),
+ enable);
+ REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid),
+ enable);
+ REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid),
+ enable);
+}
+
+static inline void storm_memset_eq_data(struct bnx2x *bp,
+ struct event_ring_data *eq_data,
+ u16 pfid)
+{
+ size_t size = sizeof(struct event_ring_data);
+
+ u32 addr = BAR_CSTRORM_INTMEM + CSTORM_EVENT_RING_DATA_OFFSET(pfid);
+
+ __storm_memset_struct(bp, addr, size, (u32 *)eq_data);
+}
+
+static inline void storm_memset_eq_prod(struct bnx2x *bp, u16 eq_prod,
+ u16 pfid)
+{
+ u32 addr = BAR_CSTRORM_INTMEM + CSTORM_EVENT_RING_PROD_OFFSET(pfid);
+ REG_WR16(bp, addr, eq_prod);
+}
+
+static inline void storm_memset_hc_timeout(struct bnx2x *bp, u8 port,
+ u16 fw_sb_id, u8 sb_index,
+ u8 ticks)
+{
+
+ int index_offset = CHIP_IS_E2(bp) ?
+ offsetof(struct hc_status_block_data_e2, index_data) :
+ offsetof(struct hc_status_block_data_e1x, index_data);
+ u32 addr = BAR_CSTRORM_INTMEM +
+ CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) +
+ index_offset +
+ sizeof(struct hc_index_data)*sb_index +
+ offsetof(struct hc_index_data, timeout);
+ REG_WR8(bp, addr, ticks);
+ DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d ticks %d\n",
+ port, fw_sb_id, sb_index, ticks);
+}
+static inline void storm_memset_hc_disable(struct bnx2x *bp, u8 port,
+ u16 fw_sb_id, u8 sb_index,
+ u8 disable)
+{
+ u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT);
+ int index_offset = CHIP_IS_E2(bp) ?
+ offsetof(struct hc_status_block_data_e2, index_data) :
+ offsetof(struct hc_status_block_data_e1x, index_data);
+ u32 addr = BAR_CSTRORM_INTMEM +
+ CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) +
+ index_offset +
+ sizeof(struct hc_index_data)*sb_index +
+ offsetof(struct hc_index_data, flags);
+ u16 flags = REG_RD16(bp, addr);
+ /* clear and set */
+ flags &= ~HC_INDEX_DATA_HC_ENABLED;
+ flags |= enable_flag;
+ REG_WR16(bp, addr, flags);
+ DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d disable %d\n",
+ port, fw_sb_id, sb_index, disable);
+}
+
/* used only at init
* locking is done by mcp
*/
@@ -172,6 +423,75 @@ static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr)
return val;
}
+#define DMAE_DP_SRC_GRC "grc src_addr [%08x]"
+#define DMAE_DP_SRC_PCI "pci src_addr [%x:%08x]"
+#define DMAE_DP_DST_GRC "grc dst_addr [%08x]"
+#define DMAE_DP_DST_PCI "pci dst_addr [%x:%08x]"
+#define DMAE_DP_DST_NONE "dst_addr [none]"
+
+void bnx2x_dp_dmae(struct bnx2x *bp, struct dmae_command *dmae, int msglvl)
+{
+ u32 src_type = dmae->opcode & DMAE_COMMAND_SRC;
+
+ switch (dmae->opcode & DMAE_COMMAND_DST) {
+ case DMAE_CMD_DST_PCI:
+ if (src_type == DMAE_CMD_SRC_PCI)
+ DP(msglvl, "DMAE: opcode 0x%08x\n"
+ "src [%x:%08x], len [%d*4], dst [%x:%08x]\n"
+ "comp_addr [%x:%08x], comp_val 0x%08x\n",
+ dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
+ dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo,
+ dmae->comp_addr_hi, dmae->comp_addr_lo,
+ dmae->comp_val);
+ else
+ DP(msglvl, "DMAE: opcode 0x%08x\n"
+ "src [%08x], len [%d*4], dst [%x:%08x]\n"
+ "comp_addr [%x:%08x], comp_val 0x%08x\n",
+ dmae->opcode, dmae->src_addr_lo >> 2,
+ dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo,
+ dmae->comp_addr_hi, dmae->comp_addr_lo,
+ dmae->comp_val);
+ break;
+ case DMAE_CMD_DST_GRC:
+ if (src_type == DMAE_CMD_SRC_PCI)
+ DP(msglvl, "DMAE: opcode 0x%08x\n"
+ "src [%x:%08x], len [%d*4], dst_addr [%08x]\n"
+ "comp_addr [%x:%08x], comp_val 0x%08x\n",
+ dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
+ dmae->len, dmae->dst_addr_lo >> 2,
+ dmae->comp_addr_hi, dmae->comp_addr_lo,
+ dmae->comp_val);
+ else
+ DP(msglvl, "DMAE: opcode 0x%08x\n"
+ "src [%08x], len [%d*4], dst [%08x]\n"
+ "comp_addr [%x:%08x], comp_val 0x%08x\n",
+ dmae->opcode, dmae->src_addr_lo >> 2,
+ dmae->len, dmae->dst_addr_lo >> 2,
+ dmae->comp_addr_hi, dmae->comp_addr_lo,
+ dmae->comp_val);
+ break;
+ default:
+ if (src_type == DMAE_CMD_SRC_PCI)
+ DP(msglvl, "DMAE: opcode 0x%08x\n"
+ DP_LEVEL "src_addr [%x:%08x] len [%d * 4] "
+ "dst_addr [none]\n"
+ DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
+ dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
+ dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo,
+ dmae->comp_val);
+ else
+ DP(msglvl, "DMAE: opcode 0x%08x\n"
+ DP_LEVEL "src_addr [%08x] len [%d * 4] "
+ "dst_addr [none]\n"
+ DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
+ dmae->opcode, dmae->src_addr_lo >> 2,
+ dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo,
+ dmae->comp_val);
+ break;
+ }
+
+}
+
const u32 dmae_reg_go_c[] = {
DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3,
DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7,
@@ -195,85 +515,137 @@ void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx)
REG_WR(bp, dmae_reg_go_c[idx], 1);
}
-void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
- u32 len32)
+u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type)
{
- struct dmae_command dmae;
- u32 *wb_comp = bnx2x_sp(bp, wb_comp);
- int cnt = 200;
+ return opcode | ((comp_type << DMAE_COMMAND_C_DST_SHIFT) |
+ DMAE_CMD_C_ENABLE);
+}
- if (!bp->dmae_ready) {
- u32 *data = bnx2x_sp(bp, wb_data[0]);
+u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode)
+{
+ return opcode & ~DMAE_CMD_SRC_RESET;
+}
- DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)"
- " using indirect\n", dst_addr, len32);
- bnx2x_init_ind_wr(bp, dst_addr, data, len32);
- return;
- }
+u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type,
+ bool with_comp, u8 comp_type)
+{
+ u32 opcode = 0;
+
+ opcode |= ((src_type << DMAE_COMMAND_SRC_SHIFT) |
+ (dst_type << DMAE_COMMAND_DST_SHIFT));
+
+ opcode |= (DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET);
- memset(&dmae, 0, sizeof(struct dmae_command));
+ opcode |= (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0);
+ opcode |= ((BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT) |
+ (BP_E1HVN(bp) << DMAE_COMMAND_DST_VN_SHIFT));
+ opcode |= (DMAE_COM_SET_ERR << DMAE_COMMAND_ERR_POLICY_SHIFT);
- dmae.opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
+ opcode |= DMAE_CMD_ENDIANITY_B_DW_SWAP;
#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
+ opcode |= DMAE_CMD_ENDIANITY_DW_SWAP;
#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
- dmae.src_addr_lo = U64_LO(dma_addr);
- dmae.src_addr_hi = U64_HI(dma_addr);
- dmae.dst_addr_lo = dst_addr >> 2;
- dmae.dst_addr_hi = 0;
- dmae.len = len32;
- dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
- dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
- dmae.comp_val = DMAE_COMP_VAL;
-
- DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
- DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
- "dst_addr [%x:%08x (%08x)]\n"
- DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
- dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo,
- dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, dst_addr,
- dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val);
- DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
+ if (with_comp)
+ opcode = bnx2x_dmae_opcode_add_comp(opcode, comp_type);
+ return opcode;
+}
+
+void bnx2x_prep_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
+ u8 src_type, u8 dst_type)
+{
+ memset(dmae, 0, sizeof(struct dmae_command));
+
+ /* set the opcode */
+ dmae->opcode = bnx2x_dmae_opcode(bp, src_type, dst_type,
+ true, DMAE_COMP_PCI);
+
+ /* fill in the completion parameters */
+ dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
+ dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
+ dmae->comp_val = DMAE_COMP_VAL;
+}
+
+/* issue a dmae command over the init-channel and wailt for completion */
+int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae)
+{
+ u32 *wb_comp = bnx2x_sp(bp, wb_comp);
+ int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 40;
+ int rc = 0;
+
+ DP(BNX2X_MSG_OFF, "data before [0x%08x 0x%08x 0x%08x 0x%08x]\n",
bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
+ /* lock the dmae channel */
mutex_lock(&bp->dmae_mutex);
+ /* reset completion */
*wb_comp = 0;
- bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp));
+ /* post the command on the channel used for initializations */
+ bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
+ /* wait for completion */
udelay(5);
-
- while (*wb_comp != DMAE_COMP_VAL) {
+ while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) {
DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp);
if (!cnt) {
BNX2X_ERR("DMAE timeout!\n");
- break;
+ rc = DMAE_TIMEOUT;
+ goto unlock;
}
cnt--;
- /* adjust delay for emulation/FPGA */
- if (CHIP_REV_IS_SLOW(bp))
- msleep(100);
- else
- udelay(5);
+ udelay(50);
+ }
+ if (*wb_comp & DMAE_PCI_ERR_FLAG) {
+ BNX2X_ERR("DMAE PCI error!\n");
+ rc = DMAE_PCI_ERROR;
}
+ DP(BNX2X_MSG_OFF, "data after [0x%08x 0x%08x 0x%08x 0x%08x]\n",
+ bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
+ bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
+
+unlock:
mutex_unlock(&bp->dmae_mutex);
+ return rc;
+}
+
+void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
+ u32 len32)
+{
+ struct dmae_command dmae;
+
+ if (!bp->dmae_ready) {
+ u32 *data = bnx2x_sp(bp, wb_data[0]);
+
+ DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)"
+ " using indirect\n", dst_addr, len32);
+ bnx2x_init_ind_wr(bp, dst_addr, data, len32);
+ return;
+ }
+
+ /* set opcode and fixed command fields */
+ bnx2x_prep_dmae_with_comp(bp, &dmae, DMAE_SRC_PCI, DMAE_DST_GRC);
+
+ /* fill in addresses and len */
+ dmae.src_addr_lo = U64_LO(dma_addr);
+ dmae.src_addr_hi = U64_HI(dma_addr);
+ dmae.dst_addr_lo = dst_addr >> 2;
+ dmae.dst_addr_hi = 0;
+ dmae.len = len32;
+
+ bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_OFF);
+
+ /* issue the command and wait for completion */
+ bnx2x_issue_dmae_with_comp(bp, &dmae);
}
void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
{
struct dmae_command dmae;
- u32 *wb_comp = bnx2x_sp(bp, wb_comp);
- int cnt = 200;
if (!bp->dmae_ready) {
u32 *data = bnx2x_sp(bp, wb_data[0]);
@@ -286,62 +658,20 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
return;
}
- memset(&dmae, 0, sizeof(struct dmae_command));
+ /* set opcode and fixed command fields */
+ bnx2x_prep_dmae_with_comp(bp, &dmae, DMAE_SRC_GRC, DMAE_DST_PCI);
- dmae.opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ /* fill in addresses and len */
dmae.src_addr_lo = src_addr >> 2;
dmae.src_addr_hi = 0;
dmae.dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
dmae.dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data));
dmae.len = len32;
- dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
- dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
- dmae.comp_val = DMAE_COMP_VAL;
-
- DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
- DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
- "dst_addr [%x:%08x (%08x)]\n"
- DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
- dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo,
- dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, src_addr,
- dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val);
- mutex_lock(&bp->dmae_mutex);
+ bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_OFF);
- memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
- *wb_comp = 0;
-
- bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp));
-
- udelay(5);
-
- while (*wb_comp != DMAE_COMP_VAL) {
-
- if (!cnt) {
- BNX2X_ERR("DMAE timeout!\n");
- break;
- }
- cnt--;
- /* adjust delay for emulation/FPGA */
- if (CHIP_REV_IS_SLOW(bp))
- msleep(100);
- else
- udelay(5);
- }
- DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
- bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
- bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
-
- mutex_unlock(&bp->dmae_mutex);
+ /* issue the command and wait for completion */
+ bnx2x_issue_dmae_with_comp(bp, &dmae);
}
void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr,
@@ -508,19 +838,24 @@ static void bnx2x_fw_dump(struct bnx2x *bp)
u32 mark, offset;
__be32 data[9];
int word;
-
+ u32 trace_shmem_base;
if (BP_NOMCP(bp)) {
BNX2X_ERR("NO MCP - can not dump\n");
return;
}
- addr = bp->common.shmem_base - 0x0800 + 4;
+ if (BP_PATH(bp) == 0)
+ trace_shmem_base = bp->common.shmem_base;
+ else
+ trace_shmem_base = SHMEM2_RD(bp, other_shmem_base_addr);
+ addr = trace_shmem_base - 0x0800 + 4;
mark = REG_RD(bp, addr);
- mark = MCP_REG_MCPR_SCRATCH + ((mark + 0x3) & ~0x3) - 0x08000000;
+ mark = (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH)
+ + ((mark + 0x3) & ~0x3) - 0x08000000;
pr_err("begin fw dump (mark 0x%x)\n", mark);
pr_err("");
- for (offset = mark; offset <= bp->common.shmem_base; offset += 0x8*4) {
+ for (offset = mark; offset <= trace_shmem_base; offset += 0x8*4) {
for (word = 0; word < 8; word++)
data[word] = htonl(REG_RD(bp, offset + 4*word));
data[8] = 0x0;
@@ -538,7 +873,12 @@ static void bnx2x_fw_dump(struct bnx2x *bp)
void bnx2x_panic_dump(struct bnx2x *bp)
{
int i;
- u16 j, start, end;
+ u16 j;
+ struct hc_sp_status_block_data sp_sb_data;
+ int func = BP_FUNC(bp);
+#ifdef BNX2X_STOP_ON_ERROR
+ u16 start = 0, end = 0;
+#endif
bp->stats_state = STATS_STATE_DISABLED;
DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
@@ -547,44 +887,143 @@ void bnx2x_panic_dump(struct bnx2x *bp)
/* Indices */
/* Common */
- BNX2X_ERR("def_c_idx(0x%x) def_u_idx(0x%x) def_x_idx(0x%x)"
- " def_t_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x)"
+ BNX2X_ERR("def_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x)"
" spq_prod_idx(0x%x)\n",
- bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
- bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+ bp->def_idx, bp->def_att_idx,
+ bp->attn_state, bp->spq_prod_idx);
+ BNX2X_ERR("DSB: attn bits(0x%x) ack(0x%x) id(0x%x) idx(0x%x)\n",
+ bp->def_status_blk->atten_status_block.attn_bits,
+ bp->def_status_blk->atten_status_block.attn_bits_ack,
+ bp->def_status_blk->atten_status_block.status_block_id,
+ bp->def_status_blk->atten_status_block.attn_bits_index);
+ BNX2X_ERR(" def (");
+ for (i = 0; i < HC_SP_SB_MAX_INDICES; i++)
+ pr_cont("0x%x%s",
+ bp->def_status_blk->sp_sb.index_values[i],
+ (i == HC_SP_SB_MAX_INDICES - 1) ? ") " : " ");
+
+ for (i = 0; i < sizeof(struct hc_sp_status_block_data)/sizeof(u32); i++)
+ *((u32 *)&sp_sb_data + i) = REG_RD(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) +
+ i*sizeof(u32));
+
+ pr_cont("igu_sb_id(0x%x) igu_seg_id (0x%x) "
+ "pf_id(0x%x) vnic_id(0x%x) "
+ "vf_id(0x%x) vf_valid (0x%x)\n",
+ sp_sb_data.igu_sb_id,
+ sp_sb_data.igu_seg_id,
+ sp_sb_data.p_func.pf_id,
+ sp_sb_data.p_func.vnic_id,
+ sp_sb_data.p_func.vf_id,
+ sp_sb_data.p_func.vf_valid);
+
- /* Rx */
for_each_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
-
+ int loop;
+ 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 =
+ CHIP_IS_E2(bp) ?
+ sb_data_e2.common.state_machine :
+ sb_data_e1x.common.state_machine;
+ struct hc_index_data *hc_index_p =
+ CHIP_IS_E2(bp) ?
+ sb_data_e2.index_data :
+ sb_data_e1x.index_data;
+ int data_size;
+ u32 *sb_data_p;
+
+ /* Rx */
BNX2X_ERR("fp%d: rx_bd_prod(0x%x) rx_bd_cons(0x%x)"
- " *rx_bd_cons_sb(0x%x) rx_comp_prod(0x%x)"
+ " rx_comp_prod(0x%x)"
" rx_comp_cons(0x%x) *rx_cons_sb(0x%x)\n",
i, fp->rx_bd_prod, fp->rx_bd_cons,
- le16_to_cpu(*fp->rx_bd_cons_sb), fp->rx_comp_prod,
+ fp->rx_comp_prod,
fp->rx_comp_cons, le16_to_cpu(*fp->rx_cons_sb));
BNX2X_ERR(" rx_sge_prod(0x%x) last_max_sge(0x%x)"
- " fp_u_idx(0x%x) *sb_u_idx(0x%x)\n",
+ " fp_hc_idx(0x%x)\n",
fp->rx_sge_prod, fp->last_max_sge,
- le16_to_cpu(fp->fp_u_idx),
- fp->status_blk->u_status_block.status_block_index);
- }
-
- /* Tx */
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
+ le16_to_cpu(fp->fp_hc_idx));
+ /* Tx */
BNX2X_ERR("fp%d: tx_pkt_prod(0x%x) tx_pkt_cons(0x%x)"
" tx_bd_prod(0x%x) tx_bd_cons(0x%x)"
" *tx_cons_sb(0x%x)\n",
i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
- BNX2X_ERR(" fp_c_idx(0x%x) *sb_c_idx(0x%x)"
- " tx_db_prod(0x%x)\n", le16_to_cpu(fp->fp_c_idx),
- fp->status_blk->c_status_block.status_block_index,
- fp->tx_db.data.prod);
+
+ loop = CHIP_IS_E2(bp) ?
+ HC_SB_MAX_INDICES_E2 : HC_SB_MAX_INDICES_E1X;
+
+ /* host sb data */
+
+ BNX2X_ERR(" run indexes (");
+ for (j = 0; j < HC_SB_MAX_SM; j++)
+ pr_cont("0x%x%s",
+ fp->sb_running_index[j],
+ (j == HC_SB_MAX_SM - 1) ? ")" : " ");
+
+ BNX2X_ERR(" indexes (");
+ for (j = 0; j < loop; j++)
+ pr_cont("0x%x%s",
+ fp->sb_index_values[j],
+ (j == loop - 1) ? ")" : " ");
+ /* fw sb data */
+ data_size = CHIP_IS_E2(bp) ?
+ sizeof(struct hc_status_block_data_e2) :
+ sizeof(struct hc_status_block_data_e1x);
+ data_size /= sizeof(u32);
+ sb_data_p = CHIP_IS_E2(bp) ?
+ (u32 *)&sb_data_e2 :
+ (u32 *)&sb_data_e1x;
+ /* copy sb data in here */
+ for (j = 0; j < data_size; j++)
+ *(sb_data_p + j) = REG_RD(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) +
+ j * sizeof(u32));
+
+ if (CHIP_IS_E2(bp)) {
+ pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) "
+ "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n",
+ sb_data_e2.common.p_func.pf_id,
+ sb_data_e2.common.p_func.vf_id,
+ sb_data_e2.common.p_func.vf_valid,
+ sb_data_e2.common.p_func.vnic_id,
+ sb_data_e2.common.same_igu_sb_1b);
+ } else {
+ pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) "
+ "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n",
+ sb_data_e1x.common.p_func.pf_id,
+ sb_data_e1x.common.p_func.vf_id,
+ sb_data_e1x.common.p_func.vf_valid,
+ sb_data_e1x.common.p_func.vnic_id,
+ sb_data_e1x.common.same_igu_sb_1b);
+ }
+
+ /* SB_SMs data */
+ for (j = 0; j < HC_SB_MAX_SM; j++) {
+ pr_cont("SM[%d] __flags (0x%x) "
+ "igu_sb_id (0x%x) igu_seg_id(0x%x) "
+ "time_to_expire (0x%x) "
+ "timer_value(0x%x)\n", j,
+ hc_sm_p[j].__flags,
+ hc_sm_p[j].igu_sb_id,
+ hc_sm_p[j].igu_seg_id,
+ hc_sm_p[j].time_to_expire,
+ hc_sm_p[j].timer_value);
+ }
+
+ /* Indecies data */
+ for (j = 0; j < loop; j++) {
+ pr_cont("INDEX[%d] flags (0x%x) "
+ "timeout (0x%x)\n", j,
+ hc_index_p[j].flags,
+ hc_index_p[j].timeout);
+ }
}
+#ifdef BNX2X_STOP_ON_ERROR
/* Rings */
/* Rx */
for_each_queue(bp, i) {
@@ -642,13 +1081,13 @@ void bnx2x_panic_dump(struct bnx2x *bp)
i, j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
}
}
-
+#endif
bnx2x_fw_dump(bp);
bnx2x_mc_assert(bp);
BNX2X_ERR("end crash dump -----------------\n");
}
-void bnx2x_int_enable(struct bnx2x *bp)
+static void bnx2x_hc_int_enable(struct bnx2x *bp)
{
int port = BP_PORT(bp);
u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
@@ -672,14 +1111,19 @@ void bnx2x_int_enable(struct bnx2x *bp)
HC_CONFIG_0_REG_INT_LINE_EN_0 |
HC_CONFIG_0_REG_ATTN_BIT_EN_0);
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
- val, port, addr);
+ if (!CHIP_IS_E1(bp)) {
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
+ val, port, addr);
- REG_WR(bp, addr, val);
+ REG_WR(bp, addr, val);
- val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
+ val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
+ }
}
+ if (CHIP_IS_E1(bp))
+ REG_WR(bp, HC_REG_INT_MASK + port*4, 0x1FFFF);
+
DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) mode %s\n",
val, port, addr, (msix ? "MSI-X" : (msi ? "MSI" : "INTx")));
@@ -690,9 +1134,9 @@ void bnx2x_int_enable(struct bnx2x *bp)
mmiowb();
barrier();
- if (CHIP_IS_E1H(bp)) {
+ if (!CHIP_IS_E1(bp)) {
/* init leading/trailing edge */
- if (IS_E1HMF(bp)) {
+ if (IS_MF(bp)) {
val = (0xee0f | (1 << (BP_E1HVN(bp) + 4)));
if (bp->port.pmf)
/* enable nig and gpio3 attention */
@@ -708,16 +1152,91 @@ void bnx2x_int_enable(struct bnx2x *bp)
mmiowb();
}
-static void bnx2x_int_disable(struct bnx2x *bp)
+static void bnx2x_igu_int_enable(struct bnx2x *bp)
+{
+ u32 val;
+ int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
+ int msi = (bp->flags & USING_MSI_FLAG) ? 1 : 0;
+
+ val = REG_RD(bp, IGU_REG_PF_CONFIGURATION);
+
+ if (msix) {
+ val &= ~(IGU_PF_CONF_INT_LINE_EN |
+ IGU_PF_CONF_SINGLE_ISR_EN);
+ val |= (IGU_PF_CONF_FUNC_EN |
+ IGU_PF_CONF_MSI_MSIX_EN |
+ IGU_PF_CONF_ATTN_BIT_EN);
+ } else if (msi) {
+ val &= ~IGU_PF_CONF_INT_LINE_EN;
+ val |= (IGU_PF_CONF_FUNC_EN |
+ IGU_PF_CONF_MSI_MSIX_EN |
+ IGU_PF_CONF_ATTN_BIT_EN |
+ IGU_PF_CONF_SINGLE_ISR_EN);
+ } else {
+ val &= ~IGU_PF_CONF_MSI_MSIX_EN;
+ val |= (IGU_PF_CONF_FUNC_EN |
+ IGU_PF_CONF_INT_LINE_EN |
+ IGU_PF_CONF_ATTN_BIT_EN |
+ IGU_PF_CONF_SINGLE_ISR_EN);
+ }
+
+ DP(NETIF_MSG_INTR, "write 0x%x to IGU mode %s\n",
+ val, (msix ? "MSI-X" : (msi ? "MSI" : "INTx")));
+
+ REG_WR(bp, IGU_REG_PF_CONFIGURATION, val);
+
+ barrier();
+
+ /* init leading/trailing edge */
+ if (IS_MF(bp)) {
+ val = (0xee0f | (1 << (BP_E1HVN(bp) + 4)));
+ if (bp->port.pmf)
+ /* enable nig and gpio3 attention */
+ val |= 0x1100;
+ } else
+ val = 0xffff;
+
+ REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, val);
+ REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, val);
+
+ /* Make sure that interrupts are indeed enabled from here on */
+ mmiowb();
+}
+
+void bnx2x_int_enable(struct bnx2x *bp)
+{
+ if (bp->common.int_block == INT_BLOCK_HC)
+ bnx2x_hc_int_enable(bp);
+ else
+ bnx2x_igu_int_enable(bp);
+}
+
+static void bnx2x_hc_int_disable(struct bnx2x *bp)
{
int port = BP_PORT(bp);
u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
u32 val = REG_RD(bp, addr);
- val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
- HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
- HC_CONFIG_0_REG_INT_LINE_EN_0 |
- HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+ /*
+ * in E1 we must use only PCI configuration space to disable
+ * MSI/MSIX capablility
+ * It's forbitten to disable IGU_PF_CONF_MSI_MSIX_EN in HC block
+ */
+ if (CHIP_IS_E1(bp)) {
+ /* Since IGU_PF_CONF_MSI_MSIX_EN still always on
+ * Use mask register to prevent from HC sending interrupts
+ * after we exit the function
+ */
+ REG_WR(bp, HC_REG_INT_MASK + port*4, 0);
+
+ val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+ HC_CONFIG_0_REG_INT_LINE_EN_0 |
+ HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+ } else
+ val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+ HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
+ HC_CONFIG_0_REG_INT_LINE_EN_0 |
+ HC_CONFIG_0_REG_ATTN_BIT_EN_0);
DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
val, port, addr);
@@ -730,6 +1249,32 @@ static void bnx2x_int_disable(struct bnx2x *bp)
BNX2X_ERR("BUG! proper val not read from IGU!\n");
}
+static void bnx2x_igu_int_disable(struct bnx2x *bp)
+{
+ u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION);
+
+ val &= ~(IGU_PF_CONF_MSI_MSIX_EN |
+ IGU_PF_CONF_INT_LINE_EN |
+ IGU_PF_CONF_ATTN_BIT_EN);
+
+ DP(NETIF_MSG_INTR, "write %x to IGU\n", val);
+
+ /* flush all outstanding writes */
+ mmiowb();
+
+ REG_WR(bp, IGU_REG_PF_CONFIGURATION, val);
+ if (REG_RD(bp, IGU_REG_PF_CONFIGURATION) != val)
+ BNX2X_ERR("BUG! proper val not read from IGU!\n");
+}
+
+void bnx2x_int_disable(struct bnx2x *bp)
+{
+ if (bp->common.int_block == INT_BLOCK_HC)
+ bnx2x_hc_int_disable(bp);
+ else
+ bnx2x_igu_int_disable(bp);
+}
+
void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
{
int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
@@ -781,7 +1326,7 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource)
DP(NETIF_MSG_HW,
"resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
resource, HW_LOCK_MAX_RESOURCE_VALUE);
- return -EINVAL;
+ return false;
}
if (func <= 5)
@@ -800,7 +1345,6 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource)
return false;
}
-
#ifdef BCM_CNIC
static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid);
#endif
@@ -817,76 +1361,35 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp,
fp->index, cid, command, bp->state,
rr_cqe->ramrod_cqe.ramrod_type);
- bp->spq_left++;
-
- if (fp->index) {
- switch (command | fp->state) {
- case (RAMROD_CMD_ID_ETH_CLIENT_SETUP |
- BNX2X_FP_STATE_OPENING):
- DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n",
- cid);
- fp->state = BNX2X_FP_STATE_OPEN;
- break;
-
- case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING):
- DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n",
- cid);
- fp->state = BNX2X_FP_STATE_HALTED;
- break;
-
- default:
- BNX2X_ERR("unexpected MC reply (%d) "
- "fp[%d] state is %x\n",
- command, fp->index, fp->state);
- break;
- }
- mb(); /* force bnx2x_wait_ramrod() to see the change */
- return;
- }
-
- switch (command | bp->state) {
- case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT):
- DP(NETIF_MSG_IFUP, "got setup ramrod\n");
- bp->state = BNX2X_STATE_OPEN;
+ switch (command | fp->state) {
+ case (RAMROD_CMD_ID_ETH_CLIENT_SETUP | BNX2X_FP_STATE_OPENING):
+ DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n", cid);
+ fp->state = BNX2X_FP_STATE_OPEN;
break;
- case (RAMROD_CMD_ID_ETH_HALT | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got halt ramrod\n");
- bp->state = BNX2X_STATE_CLOSING_WAIT4_DELETE;
+ case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING):
+ DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n", cid);
fp->state = BNX2X_FP_STATE_HALTED;
break;
- case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid);
- bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
- break;
-
-#ifdef BCM_CNIC
- case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_OPEN):
- DP(NETIF_MSG_IFDOWN, "got delete ramrod for CID %d\n", cid);
- bnx2x_cnic_cfc_comp(bp, cid);
- break;
-#endif
-
- case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
- case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG):
- DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
- bp->set_mac_pending--;
- smp_wmb();
- break;
-
- case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
- bp->set_mac_pending--;
- smp_wmb();
+ case (RAMROD_CMD_ID_ETH_TERMINATE | BNX2X_FP_STATE_TERMINATING):
+ DP(NETIF_MSG_IFDOWN, "got MULTI[%d] teminate ramrod\n", cid);
+ fp->state = BNX2X_FP_STATE_TERMINATED;
break;
default:
- BNX2X_ERR("unexpected MC reply (%d) bp->state is %x\n",
- command, bp->state);
+ BNX2X_ERR("unexpected MC reply (%d) "
+ "fp[%d] state is %x\n",
+ command, fp->index, fp->state);
break;
}
- mb(); /* force bnx2x_wait_ramrod() to see the change */
+
+ smp_mb__before_atomic_inc();
+ atomic_inc(&bp->spq_left);
+ /* push the change in fp->state and towards the memory */
+ smp_wmb();
+
+ return;
}
irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
@@ -914,25 +1417,22 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
return IRQ_HANDLED;
#endif
- for (i = 0; i < BNX2X_NUM_QUEUES(bp); i++) {
+ for_each_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
- mask = 0x2 << fp->sb_id;
+ mask = 0x2 << (fp->index + CNIC_CONTEXT_USE);
if (status & mask) {
/* Handle Rx and Tx according to SB id */
prefetch(fp->rx_cons_sb);
- prefetch(&fp->status_blk->u_status_block.
- status_block_index);
prefetch(fp->tx_cons_sb);
- prefetch(&fp->status_blk->c_status_block.
- status_block_index);
+ prefetch(&fp->sb_running_index[SM_RX_ID]);
napi_schedule(&bnx2x_fp(bp, fp->index, napi));
status &= ~mask;
}
}
#ifdef BCM_CNIC
- mask = 0x2 << CNIC_SB_ID(bp);
+ mask = 0x2;
if (status & (mask | 0x1)) {
struct cnic_ops *c_ops = NULL;
@@ -1227,49 +1727,91 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
return 0;
}
+int bnx2x_get_link_cfg_idx(struct bnx2x *bp)
+{
+ u32 sel_phy_idx = 0;
+ if (bp->link_vars.link_up) {
+ sel_phy_idx = EXT_PHY1;
+ /* In case link is SERDES, check if the EXT_PHY2 is the one */
+ if ((bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) &&
+ (bp->link_params.phy[EXT_PHY2].supported & SUPPORTED_FIBRE))
+ sel_phy_idx = EXT_PHY2;
+ } else {
+
+ switch (bnx2x_phy_selection(&bp->link_params)) {
+ case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
+ sel_phy_idx = EXT_PHY1;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
+ sel_phy_idx = EXT_PHY2;
+ break;
+ }
+ }
+ /*
+ * The selected actived PHY is always after swapping (in case PHY
+ * swapping is enabled). So when swapping is enabled, we need to reverse
+ * the configuration
+ */
+
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED) {
+ if (sel_phy_idx == EXT_PHY1)
+ sel_phy_idx = EXT_PHY2;
+ else if (sel_phy_idx == EXT_PHY2)
+ sel_phy_idx = EXT_PHY1;
+ }
+ return LINK_CONFIG_IDX(sel_phy_idx);
+}
+
void bnx2x_calc_fc_adv(struct bnx2x *bp)
{
+ u8 cfg_idx = bnx2x_get_link_cfg_idx(bp);
switch (bp->link_vars.ieee_fc &
MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) {
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE:
- bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
- ADVERTISED_Pause);
+ bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause |
+ ADVERTISED_Pause);
break;
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
- bp->port.advertising |= (ADVERTISED_Asym_Pause |
- ADVERTISED_Pause);
+ bp->port.advertising[cfg_idx] |= (ADVERTISED_Asym_Pause |
+ ADVERTISED_Pause);
break;
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC:
- bp->port.advertising |= ADVERTISED_Asym_Pause;
+ bp->port.advertising[cfg_idx] |= ADVERTISED_Asym_Pause;
break;
default:
- bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
- ADVERTISED_Pause);
+ bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause |
+ ADVERTISED_Pause);
break;
}
}
-
u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
{
if (!BP_NOMCP(bp)) {
u8 rc;
-
+ int cfx_idx = bnx2x_get_link_cfg_idx(bp);
+ u16 req_line_speed = bp->link_params.req_line_speed[cfx_idx];
/* Initialize link parameters structure variables */
/* It is recommended to turn off RX FC for jumbo frames
for better performance */
- if (bp->dev->mtu > 5000)
+ if ((CHIP_IS_E1x(bp)) && (bp->dev->mtu > 5000))
bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_TX;
else
bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH;
bnx2x_acquire_phy_lock(bp);
- if (load_mode == LOAD_DIAG)
- bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
+ if (load_mode == LOAD_DIAG) {
+ bp->link_params.loopback_mode = LOOPBACK_XGXS;
+ bp->link_params.req_line_speed[cfx_idx] = SPEED_10000;
+ }
rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
@@ -1281,7 +1823,7 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
bnx2x_link_report(bp);
}
-
+ bp->link_params.req_line_speed[cfx_idx] = req_line_speed;
return rc;
}
BNX2X_ERR("Bootcode is missing - can not initialize link\n");
@@ -1292,6 +1834,7 @@ void bnx2x_link_set(struct bnx2x *bp)
{
if (!BP_NOMCP(bp)) {
bnx2x_acquire_phy_lock(bp);
+ bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1);
bnx2x_phy_init(&bp->link_params, &bp->link_vars);
bnx2x_release_phy_lock(bp);
@@ -1310,13 +1853,14 @@ static void bnx2x__link_reset(struct bnx2x *bp)
BNX2X_ERR("Bootcode is missing - can not reset link\n");
}
-u8 bnx2x_link_test(struct bnx2x *bp)
+u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes)
{
u8 rc = 0;
if (!BP_NOMCP(bp)) {
bnx2x_acquire_phy_lock(bp);
- rc = bnx2x_test_link(&bp->link_params, &bp->link_vars);
+ rc = bnx2x_test_link(&bp->link_params, &bp->link_vars,
+ is_serdes);
bnx2x_release_phy_lock(bp);
} else
BNX2X_ERR("Bootcode is missing - can not test link\n");
@@ -1371,13 +1915,11 @@ static void bnx2x_init_port_minmax(struct bnx2x *bp)
static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
{
int all_zero = 1;
- int port = BP_PORT(bp);
int vn;
bp->vn_weight_sum = 0;
for (vn = VN_0; vn < E1HVN_MAX; vn++) {
- int func = 2*vn + port;
- u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+ u32 vn_cfg = bp->mf_config[vn];
u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
@@ -1405,11 +1947,12 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
}
-static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
+static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn)
{
struct rate_shaping_vars_per_vn m_rs_vn;
struct fairness_vars_per_vn m_fair_vn;
- u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+ u32 vn_cfg = bp->mf_config[vn];
+ int func = 2*vn + BP_PORT(bp);
u16 vn_min_rate, vn_max_rate;
int i;
@@ -1422,11 +1965,12 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
/* If min rate is zero - set it to 1 */
- if (!vn_min_rate)
+ if (bp->vn_weight_sum && (vn_min_rate == 0))
vn_min_rate = DEF_MIN_RATE;
vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
}
+
DP(NETIF_MSG_IFUP,
"func %d: vn_min_rate %d vn_max_rate %d vn_weight_sum %d\n",
func, vn_min_rate, vn_max_rate, bp->vn_weight_sum);
@@ -1467,6 +2011,83 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
((u32 *)(&m_fair_vn))[i]);
}
+static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp)
+{
+ if (CHIP_REV_IS_SLOW(bp))
+ return CMNG_FNS_NONE;
+ if (IS_MF(bp))
+ return CMNG_FNS_MINMAX;
+
+ return CMNG_FNS_NONE;
+}
+
+static void bnx2x_read_mf_cfg(struct bnx2x *bp)
+{
+ int vn;
+
+ if (BP_NOMCP(bp))
+ return; /* what should be the default bvalue in this case */
+
+ for (vn = VN_0; vn < E1HVN_MAX; vn++) {
+ int /*abs*/func = 2*vn + BP_PORT(bp);
+ bp->mf_config[vn] =
+ MF_CFG_RD(bp, func_mf_config[func].config);
+ }
+}
+
+static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type)
+{
+
+ if (cmng_type == CMNG_FNS_MINMAX) {
+ int vn;
+
+ /* clear cmng_enables */
+ bp->cmng.flags.cmng_enables = 0;
+
+ /* read mf conf from shmem */
+ if (read_cfg)
+ bnx2x_read_mf_cfg(bp);
+
+ /* Init rate shaping and fairness contexts */
+ bnx2x_init_port_minmax(bp);
+
+ /* vn_weight_sum and enable fairness if not 0 */
+ bnx2x_calc_vn_weight_sum(bp);
+
+ /* calculate and set min-max rate for each vn */
+ for (vn = VN_0; vn < E1HVN_MAX; vn++)
+ bnx2x_init_vn_minmax(bp, vn);
+
+ /* always enable rate shaping and fairness */
+ bp->cmng.flags.cmng_enables |=
+ CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
+ if (!bp->vn_weight_sum)
+ DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
+ " fairness will be disabled\n");
+ return;
+ }
+
+ /* rate shaping and fairness are disabled */
+ DP(NETIF_MSG_IFUP,
+ "rate shaping and fairness are disabled\n");
+}
+
+static inline void bnx2x_link_sync_notify(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ int func;
+ int vn;
+
+ /* Set the attention towards other drivers on the same port */
+ for (vn = VN_0; vn < E1HVN_MAX; vn++) {
+ if (vn == BP_E1HVN(bp))
+ continue;
+
+ func = ((vn << 1) | port);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
+ (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
+ }
+}
/* This function is called upon link interrupt */
static void bnx2x_link_attn(struct bnx2x *bp)
@@ -1480,7 +2101,7 @@ static void bnx2x_link_attn(struct bnx2x *bp)
if (bp->link_vars.link_up) {
/* dropless flow control */
- if (CHIP_IS_E1H(bp) && bp->dropless_fc) {
+ if (!CHIP_IS_E1(bp) && bp->dropless_fc) {
int port = BP_PORT(bp);
u32 pause_enabled = 0;
@@ -1508,37 +2129,19 @@ static void bnx2x_link_attn(struct bnx2x *bp)
if (prev_link_status != bp->link_vars.link_status)
bnx2x_link_report(bp);
- if (IS_E1HMF(bp)) {
- int port = BP_PORT(bp);
- int func;
- int vn;
-
- /* Set the attention towards other drivers on the same port */
- for (vn = VN_0; vn < E1HVN_MAX; vn++) {
- if (vn == BP_E1HVN(bp))
- continue;
+ if (IS_MF(bp))
+ bnx2x_link_sync_notify(bp);
- func = ((vn << 1) | port);
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
- (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
- }
+ if (bp->link_vars.link_up && bp->link_vars.line_speed) {
+ int cmng_fns = bnx2x_get_cmng_fns_mode(bp);
- if (bp->link_vars.link_up) {
- int i;
-
- /* Init rate shaping and fairness contexts */
- bnx2x_init_port_minmax(bp);
-
- for (vn = VN_0; vn < E1HVN_MAX; vn++)
- bnx2x_init_vn_minmax(bp, 2*vn + port);
-
- /* Store it to internal memory */
- for (i = 0;
- i < sizeof(struct cmng_struct_per_port) / 4; i++)
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4,
- ((u32 *)(&bp->cmng))[i]);
- }
+ if (cmng_fns != CMNG_FNS_NONE) {
+ bnx2x_cmng_fns_init(bp, false, cmng_fns);
+ storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp));
+ } else
+ /* rate shaping and fairness are disabled */
+ DP(NETIF_MSG_IFUP,
+ "single function mode without fairness\n");
}
}
@@ -1554,7 +2157,9 @@ void bnx2x__link_status_update(struct bnx2x *bp)
else
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
- bnx2x_calc_vn_weight_sum(bp);
+ /* 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);
@@ -1570,8 +2175,13 @@ static void bnx2x_pmf_update(struct bnx2x *bp)
/* enable nig attention */
val = (0xff0f | (1 << (BP_E1HVN(bp) + 4)));
- REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
- REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
+ if (bp->common.int_block == INT_BLOCK_HC) {
+ REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
+ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
+ } else if (CHIP_IS_E2(bp)) {
+ REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, val);
+ REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, val);
+ }
bnx2x_stats_handle(bp, STATS_EVENT_PMF);
}
@@ -1585,23 +2195,25 @@ static void bnx2x_pmf_update(struct bnx2x *bp)
*/
/* send the MCP a request, block until there is a reply */
-u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
+u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param)
{
- int func = BP_FUNC(bp);
+ int mb_idx = BP_FW_MB_IDX(bp);
u32 seq = ++bp->fw_seq;
u32 rc = 0;
u32 cnt = 1;
u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
mutex_lock(&bp->fw_mb_mutex);
- SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
+ SHMEM_WR(bp, func_mb[mb_idx].drv_mb_param, param);
+ SHMEM_WR(bp, func_mb[mb_idx].drv_mb_header, (command | seq));
+
DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
do {
/* let the FW do it's magic ... */
msleep(delay);
- rc = SHMEM_RD(bp, func_mb[func].fw_mb_header);
+ rc = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_header);
/* Give the FW up to 5 second (500*10ms) */
} while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 500));
@@ -1623,6 +2235,315 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
return rc;
}
+/* must be called under rtnl_lock */
+void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters)
+{
+ u32 mask = (1 << cl_id);
+
+ /* initial seeting is BNX2X_ACCEPT_NONE */
+ u8 drop_all_ucast = 1, drop_all_bcast = 1, drop_all_mcast = 1;
+ u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0;
+ u8 unmatched_unicast = 0;
+
+ if (filters & BNX2X_PROMISCUOUS_MODE) {
+ /* promiscious - accept all, drop none */
+ drop_all_ucast = drop_all_bcast = drop_all_mcast = 0;
+ accp_all_ucast = accp_all_bcast = accp_all_mcast = 1;
+ }
+ if (filters & BNX2X_ACCEPT_UNICAST) {
+ /* accept matched ucast */
+ drop_all_ucast = 0;
+ }
+ if (filters & BNX2X_ACCEPT_MULTICAST) {
+ /* accept matched mcast */
+ drop_all_mcast = 0;
+ }
+ if (filters & BNX2X_ACCEPT_ALL_UNICAST) {
+ /* accept all mcast */
+ drop_all_ucast = 0;
+ accp_all_ucast = 1;
+ }
+ if (filters & BNX2X_ACCEPT_ALL_MULTICAST) {
+ /* accept all mcast */
+ drop_all_mcast = 0;
+ accp_all_mcast = 1;
+ }
+ if (filters & BNX2X_ACCEPT_BROADCAST) {
+ /* accept (all) bcast */
+ drop_all_bcast = 0;
+ accp_all_bcast = 1;
+ }
+
+ bp->mac_filters.ucast_drop_all = drop_all_ucast ?
+ bp->mac_filters.ucast_drop_all | mask :
+ bp->mac_filters.ucast_drop_all & ~mask;
+
+ bp->mac_filters.mcast_drop_all = drop_all_mcast ?
+ bp->mac_filters.mcast_drop_all | mask :
+ bp->mac_filters.mcast_drop_all & ~mask;
+
+ bp->mac_filters.bcast_drop_all = drop_all_bcast ?
+ bp->mac_filters.bcast_drop_all | mask :
+ bp->mac_filters.bcast_drop_all & ~mask;
+
+ bp->mac_filters.ucast_accept_all = accp_all_ucast ?
+ bp->mac_filters.ucast_accept_all | mask :
+ bp->mac_filters.ucast_accept_all & ~mask;
+
+ bp->mac_filters.mcast_accept_all = accp_all_mcast ?
+ bp->mac_filters.mcast_accept_all | mask :
+ bp->mac_filters.mcast_accept_all & ~mask;
+
+ bp->mac_filters.bcast_accept_all = accp_all_bcast ?
+ bp->mac_filters.bcast_accept_all | mask :
+ bp->mac_filters.bcast_accept_all & ~mask;
+
+ bp->mac_filters.unmatched_unicast = unmatched_unicast ?
+ bp->mac_filters.unmatched_unicast | mask :
+ bp->mac_filters.unmatched_unicast & ~mask;
+}
+
+void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p)
+{
+ struct tstorm_eth_function_common_config tcfg = {0};
+ u16 rss_flgs;
+
+ /* tpa */
+ if (p->func_flgs & FUNC_FLG_TPA)
+ tcfg.config_flags |=
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA;
+
+ /* set rss flags */
+ rss_flgs = (p->rss->mode <<
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT);
+
+ if (p->rss->cap & RSS_IPV4_CAP)
+ rss_flgs |= RSS_IPV4_CAP_MASK;
+ if (p->rss->cap & RSS_IPV4_TCP_CAP)
+ rss_flgs |= RSS_IPV4_TCP_CAP_MASK;
+ if (p->rss->cap & RSS_IPV6_CAP)
+ rss_flgs |= RSS_IPV6_CAP_MASK;
+ if (p->rss->cap & RSS_IPV6_TCP_CAP)
+ rss_flgs |= RSS_IPV6_TCP_CAP_MASK;
+
+ tcfg.config_flags |= rss_flgs;
+ tcfg.rss_result_mask = p->rss->result_mask;
+
+ storm_memset_func_cfg(bp, &tcfg, p->func_id);
+
+ /* Enable the function in the FW */
+ storm_memset_vf_to_pf(bp, p->func_id, p->pf_id);
+ storm_memset_func_en(bp, p->func_id, 1);
+
+ /* statistics */
+ if (p->func_flgs & FUNC_FLG_STATS) {
+ struct stats_indication_flags stats_flags = {0};
+ stats_flags.collect_eth = 1;
+
+ storm_memset_xstats_flags(bp, &stats_flags, p->func_id);
+ storm_memset_xstats_addr(bp, p->fw_stat_map, p->func_id);
+
+ storm_memset_tstats_flags(bp, &stats_flags, p->func_id);
+ storm_memset_tstats_addr(bp, p->fw_stat_map, p->func_id);
+
+ storm_memset_ustats_flags(bp, &stats_flags, p->func_id);
+ storm_memset_ustats_addr(bp, p->fw_stat_map, p->func_id);
+
+ storm_memset_cstats_flags(bp, &stats_flags, p->func_id);
+ storm_memset_cstats_addr(bp, p->fw_stat_map, p->func_id);
+ }
+
+ /* spq */
+ if (p->func_flgs & FUNC_FLG_SPQ) {
+ storm_memset_spq_addr(bp, p->spq_map, p->func_id);
+ REG_WR(bp, XSEM_REG_FAST_MEMORY +
+ XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod);
+ }
+}
+
+static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp)
+{
+ u16 flags = 0;
+
+ /* calculate queue flags */
+ flags |= QUEUE_FLG_CACHE_ALIGN;
+ flags |= QUEUE_FLG_HC;
+ flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0;
+
+ flags |= QUEUE_FLG_VLAN;
+ DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
+
+ if (!fp->disable_tpa)
+ flags |= QUEUE_FLG_TPA;
+
+ flags |= QUEUE_FLG_STATS;
+
+ return flags;
+}
+
+static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, struct rxq_pause_params *pause,
+ struct bnx2x_rxq_init_params *rxq_init)
+{
+ u16 max_sge = 0;
+ u16 sge_sz = 0;
+ u16 tpa_agg_size = 0;
+
+ /* calculate queue flags */
+ u16 flags = bnx2x_get_cl_flags(bp, fp);
+
+ if (!fp->disable_tpa) {
+ pause->sge_th_hi = 250;
+ pause->sge_th_lo = 150;
+ tpa_agg_size = min_t(u32,
+ (min_t(u32, 8, MAX_SKB_FRAGS) *
+ SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff);
+ max_sge = SGE_PAGE_ALIGN(bp->dev->mtu) >>
+ SGE_PAGE_SHIFT;
+ max_sge = ((max_sge + PAGES_PER_SGE - 1) &
+ (~(PAGES_PER_SGE-1))) >> PAGES_PER_SGE_SHIFT;
+ sge_sz = (u16)min_t(u32, SGE_PAGE_SIZE * PAGES_PER_SGE,
+ 0xffff);
+ }
+
+ /* pause - not for e1 */
+ if (!CHIP_IS_E1(bp)) {
+ pause->bd_th_hi = 350;
+ pause->bd_th_lo = 250;
+ pause->rcq_th_hi = 350;
+ pause->rcq_th_lo = 250;
+ pause->sge_th_hi = 0;
+ pause->sge_th_lo = 0;
+ pause->pri_map = 1;
+ }
+
+ /* rxq setup */
+ rxq_init->flags = flags;
+ rxq_init->cxt = &bp->context.vcxt[fp->cid].eth;
+ rxq_init->dscr_map = fp->rx_desc_mapping;
+ rxq_init->sge_map = fp->rx_sge_mapping;
+ rxq_init->rcq_map = fp->rx_comp_mapping;
+ rxq_init->rcq_np_map = fp->rx_comp_mapping + BCM_PAGE_SIZE;
+ rxq_init->mtu = bp->dev->mtu;
+ rxq_init->buf_sz = bp->rx_buf_size;
+ rxq_init->cl_qzone_id = fp->cl_qzone_id;
+ rxq_init->cl_id = fp->cl_id;
+ rxq_init->spcl_id = fp->cl_id;
+ rxq_init->stat_id = fp->cl_id;
+ rxq_init->tpa_agg_sz = tpa_agg_size;
+ rxq_init->sge_buf_sz = sge_sz;
+ rxq_init->max_sges_pkt = max_sge;
+ rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT;
+ rxq_init->fw_sb_id = fp->fw_sb_id;
+
+ rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX;
+
+ rxq_init->cid = HW_CID(bp, fp->cid);
+
+ rxq_init->hc_rate = bp->rx_ticks ? (1000000 / bp->rx_ticks) : 0;
+}
+
+static void bnx2x_pf_tx_cl_prep(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, struct bnx2x_txq_init_params *txq_init)
+{
+ u16 flags = bnx2x_get_cl_flags(bp, fp);
+
+ txq_init->flags = flags;
+ txq_init->cxt = &bp->context.vcxt[fp->cid].eth;
+ txq_init->dscr_map = fp->tx_desc_mapping;
+ txq_init->stat_id = fp->cl_id;
+ txq_init->cid = HW_CID(bp, fp->cid);
+ txq_init->sb_cq_index = C_SB_ETH_TX_CQ_INDEX;
+ txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW;
+ txq_init->fw_sb_id = fp->fw_sb_id;
+ txq_init->hc_rate = bp->tx_ticks ? (1000000 / bp->tx_ticks) : 0;
+}
+
+void bnx2x_pf_init(struct bnx2x *bp)
+{
+ struct bnx2x_func_init_params func_init = {0};
+ struct bnx2x_rss_params rss = {0};
+ struct event_ring_data eq_data = { {0} };
+ u16 flags;
+
+ /* pf specific setups */
+ if (!CHIP_IS_E1(bp))
+ storm_memset_ov(bp, bp->mf_ov, BP_FUNC(bp));
+
+ if (CHIP_IS_E2(bp)) {
+ /* reset IGU PF statistics: MSIX + ATTN */
+ /* PF */
+ REG_WR(bp, IGU_REG_STATISTIC_NUM_MESSAGE_SENT +
+ BNX2X_IGU_STAS_MSG_VF_CNT*4 +
+ (CHIP_MODE_IS_4_PORT(bp) ?
+ BP_FUNC(bp) : BP_VN(bp))*4, 0);
+ /* ATTN */
+ REG_WR(bp, IGU_REG_STATISTIC_NUM_MESSAGE_SENT +
+ BNX2X_IGU_STAS_MSG_VF_CNT*4 +
+ BNX2X_IGU_STAS_MSG_PF_CNT*4 +
+ (CHIP_MODE_IS_4_PORT(bp) ?
+ BP_FUNC(bp) : BP_VN(bp))*4, 0);
+ }
+
+ /* function setup flags */
+ flags = (FUNC_FLG_STATS | FUNC_FLG_LEADING | FUNC_FLG_SPQ);
+
+ if (CHIP_IS_E1x(bp))
+ flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0;
+ else
+ flags |= FUNC_FLG_TPA;
+
+ /* function setup */
+
+ /**
+ * Although RSS is meaningless when there is a single HW queue we
+ * still need it enabled in order to have HW Rx hash generated.
+ */
+ rss.cap = (RSS_IPV4_CAP | RSS_IPV4_TCP_CAP |
+ RSS_IPV6_CAP | RSS_IPV6_TCP_CAP);
+ rss.mode = bp->multi_mode;
+ rss.result_mask = MULTI_MASK;
+ func_init.rss = &rss;
+
+ func_init.func_flgs = flags;
+ func_init.pf_id = BP_FUNC(bp);
+ func_init.func_id = BP_FUNC(bp);
+ func_init.fw_stat_map = bnx2x_sp_mapping(bp, fw_stats);
+ func_init.spq_map = bp->spq_mapping;
+ func_init.spq_prod = bp->spq_prod_idx;
+
+ bnx2x_func_init(bp, &func_init);
+
+ memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port));
+
+ /*
+ Congestion management values depend on the link rate
+ There is no active link so initial link rate is set to 10 Gbps.
+ When the link comes up The congestion management values are
+ re-calculated according to the actual link rate.
+ */
+ bp->link_vars.line_speed = SPEED_10000;
+ bnx2x_cmng_fns_init(bp, true, bnx2x_get_cmng_fns_mode(bp));
+
+ /* Only the PMF sets the HW */
+ if (bp->port.pmf)
+ storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp));
+
+ /* no rx until link is up */
+ bp->rx_mode = BNX2X_RX_MODE_NONE;
+ bnx2x_set_storm_rx_mode(bp);
+
+ /* init Event Queue */
+ eq_data.base_addr.hi = U64_HI(bp->eq_mapping);
+ eq_data.base_addr.lo = U64_LO(bp->eq_mapping);
+ eq_data.producer = bp->eq_prod;
+ eq_data.index_id = HC_SP_INDEX_EQ_CONS;
+ eq_data.sb_id = DEF_SB_ID;
+ storm_memset_eq_data(bp, &eq_data, BP_FUNC(bp));
+}
+
+
static void bnx2x_e1h_disable(struct bnx2x *bp)
{
int port = BP_PORT(bp);
@@ -1649,40 +2570,6 @@ static void bnx2x_e1h_enable(struct bnx2x *bp)
*/
}
-static void bnx2x_update_min_max(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- int vn, i;
-
- /* Init rate shaping and fairness contexts */
- bnx2x_init_port_minmax(bp);
-
- bnx2x_calc_vn_weight_sum(bp);
-
- for (vn = VN_0; vn < E1HVN_MAX; vn++)
- bnx2x_init_vn_minmax(bp, 2*vn + port);
-
- if (bp->port.pmf) {
- int func;
-
- /* Set the attention towards other drivers on the same port */
- for (vn = VN_0; vn < E1HVN_MAX; vn++) {
- if (vn == BP_E1HVN(bp))
- continue;
-
- func = ((vn << 1) | port);
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
- (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
- }
-
- /* Store it to internal memory */
- for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4,
- ((u32 *)(&bp->cmng))[i]);
- }
-}
-
static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
{
DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event);
@@ -1694,7 +2581,7 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
* where the bp->flags can change so it is done without any
* locks
*/
- if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
+ if (bp->mf_config[BP_VN(bp)] & FUNC_MF_CFG_FUNC_DISABLED) {
DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n");
bp->flags |= MF_FUNC_DIS;
@@ -1709,15 +2596,17 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
}
if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) {
- bnx2x_update_min_max(bp);
+ bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX);
+ bnx2x_link_sync_notify(bp);
+ storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp));
dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION;
}
/* Report results to MCP */
if (dcc_event)
- bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0);
else
- bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0);
}
/* must be called under the spq lock */
@@ -1744,16 +2633,17 @@ static inline void bnx2x_sp_prod_update(struct bnx2x *bp)
/* Make sure that BD data is updated before writing the producer */
wmb();
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
- bp->spq_prod_idx);
+ REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
+ bp->spq_prod_idx);
mmiowb();
}
/* the slow path queue is odd since completions arrive on the fastpath ring */
int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
- u32 data_hi, u32 data_lo, int common)
+ u32 data_hi, u32 data_lo, int common)
{
struct eth_spe *spe;
+ u16 type;
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -1762,7 +2652,7 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
spin_lock_bh(&bp->spq_lock);
- if (!bp->spq_left) {
+ if (!atomic_read(&bp->spq_left)) {
BNX2X_ERR("BUG! SPQ ring full!\n");
spin_unlock_bh(&bp->spq_lock);
bnx2x_panic();
@@ -1775,22 +2665,42 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
spe->hdr.conn_and_cmd_data =
cpu_to_le32((command << SPE_HDR_CMD_ID_SHIFT) |
HW_CID(bp, cid));
- spe->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE);
+
if (common)
- spe->hdr.type |=
- cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT));
+ /* Common ramrods:
+ * FUNC_START, FUNC_STOP, CFC_DEL, STATS, SET_MAC
+ * TRAFFIC_STOP, TRAFFIC_START
+ */
+ type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT)
+ & SPE_HDR_CONN_TYPE;
+ else
+ /* ETH ramrods: SETUP, HALT */
+ type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT)
+ & SPE_HDR_CONN_TYPE;
- spe->data.mac_config_addr.hi = cpu_to_le32(data_hi);
- spe->data.mac_config_addr.lo = cpu_to_le32(data_lo);
+ type |= ((BP_FUNC(bp) << SPE_HDR_FUNCTION_ID_SHIFT) &
+ SPE_HDR_FUNCTION_ID);
- bp->spq_left--;
+ spe->hdr.type = cpu_to_le16(type);
+
+ spe->data.update_data_addr.hi = cpu_to_le32(data_hi);
+ spe->data.update_data_addr.lo = cpu_to_le32(data_lo);
+
+ /* stats ramrod has it's own slot on the spq */
+ if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY)
+ /* It's ok if the actual decrement is issued towards the memory
+ * somewhere between the spin_lock and spin_unlock. Thus no
+ * more explict memory barrier is needed.
+ */
+ atomic_dec(&bp->spq_left);
DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/,
- "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n",
+ "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) "
+ "type(0x%x) left %x\n",
bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping),
(u32)(U64_LO(bp->spq_mapping) +
(void *)bp->spq_prod_bd - (void *)bp->spq), command,
- HW_CID(bp, cid), data_hi, data_lo, bp->spq_left);
+ HW_CID(bp, cid), data_hi, data_lo, type, atomic_read(&bp->spq_left));
bnx2x_sp_prod_update(bp);
spin_unlock_bh(&bp->spq_lock);
@@ -1827,32 +2737,27 @@ static void bnx2x_release_alr(struct bnx2x *bp)
REG_WR(bp, GRCBASE_MCP + 0x9c, 0);
}
+#define BNX2X_DEF_SB_ATT_IDX 0x0001
+#define BNX2X_DEF_SB_IDX 0x0002
+
static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp)
{
- struct host_def_status_block *def_sb = bp->def_status_blk;
+ struct host_sp_status_block *def_sb = bp->def_status_blk;
u16 rc = 0;
barrier(); /* status block is written to by the chip */
if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) {
bp->def_att_idx = def_sb->atten_status_block.attn_bits_index;
- rc |= 1;
- }
- if (bp->def_c_idx != def_sb->c_def_status_block.status_block_index) {
- bp->def_c_idx = def_sb->c_def_status_block.status_block_index;
- rc |= 2;
- }
- if (bp->def_u_idx != def_sb->u_def_status_block.status_block_index) {
- bp->def_u_idx = def_sb->u_def_status_block.status_block_index;
- rc |= 4;
+ rc |= BNX2X_DEF_SB_ATT_IDX;
}
- if (bp->def_x_idx != def_sb->x_def_status_block.status_block_index) {
- bp->def_x_idx = def_sb->x_def_status_block.status_block_index;
- rc |= 8;
- }
- if (bp->def_t_idx != def_sb->t_def_status_block.status_block_index) {
- bp->def_t_idx = def_sb->t_def_status_block.status_block_index;
- rc |= 16;
+
+ if (bp->def_idx != def_sb->sp_sb.running_index) {
+ bp->def_idx = def_sb->sp_sb.running_index;
+ rc |= BNX2X_DEF_SB_IDX;
}
+
+ /* Do not reorder: indecies reading should complete before handling */
+ barrier();
return rc;
}
@@ -1863,14 +2768,13 @@ static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp)
static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
{
int port = BP_PORT(bp);
- u32 hc_addr = (HC_REG_COMMAND_REG + port*32 +
- COMMAND_REG_ATTN_BITS_SET);
u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
MISC_REG_AEU_MASK_ATTN_FUNC_0;
u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
NIG_REG_MASK_INTERRUPT_PORT0;
u32 aeu_mask;
u32 nig_mask = 0;
+ u32 reg_addr;
if (bp->attn_state & asserted)
BNX2X_ERR("IGU ERROR\n");
@@ -1945,9 +2849,15 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
} /* if hardwired */
- DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n",
- asserted, hc_addr);
- REG_WR(bp, hc_addr, asserted);
+ if (bp->common.int_block == INT_BLOCK_HC)
+ reg_addr = (HC_REG_COMMAND_REG + port*32 +
+ COMMAND_REG_ATTN_BITS_SET);
+ else
+ reg_addr = (BAR_IGU_INTMEM + IGU_CMD_ATTN_BIT_SET_UPPER*8);
+
+ DP(NETIF_MSG_HW, "about to mask 0x%08x at %s addr 0x%x\n", asserted,
+ (bp->common.int_block == INT_BLOCK_HC) ? "HC" : "IGU", reg_addr);
+ REG_WR(bp, reg_addr, asserted);
/* now set back the mask */
if (asserted & ATTN_NIG_FOR_FUNC) {
@@ -1959,12 +2869,16 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
static inline void bnx2x_fan_failure(struct bnx2x *bp)
{
int port = BP_PORT(bp);
-
+ u32 ext_phy_config;
/* mark the failure */
- bp->link_params.ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
- bp->link_params.ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
+ ext_phy_config =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config);
+
+ ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
+ ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
SHMEM_WR(bp, dev_info.port_hw_config[port].external_phy_config,
- bp->link_params.ext_phy_config);
+ ext_phy_config);
/* log the failure */
netdev_err(bp->dev, "Fan Failure on Network Controller has caused"
@@ -1976,7 +2890,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
{
int port = BP_PORT(bp);
int reg_offset;
- u32 val, swap_val, swap_override;
+ u32 val;
reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
@@ -1990,30 +2904,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
BNX2X_ERR("SPIO5 hw attention\n");
/* Fan failure attention */
- switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- /* Low power mode is controlled by GPIO 2 */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- /* The PHY reset is controlled by GPIO 1 */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- /* The PHY reset is controlled by GPIO 1 */
- /* fake the port number to cancel the swap done in
- set_gpio() */
- swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
- swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
- port = (swap_val && swap_override) ^ 1;
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- break;
-
- default:
- break;
- }
+ bnx2x_hw_reset_phy(&bp->link_params);
bnx2x_fan_failure(bp);
}
@@ -2087,6 +2978,10 @@ static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn)
/* RQ_USDMDP_FIFO_OVERFLOW */
if (val & 0x18000)
BNX2X_ERR("FATAL error from PXP\n");
+ if (CHIP_IS_E2(bp)) {
+ val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_1);
+ BNX2X_ERR("PXP hw attention-1 0x%x\n", val);
+ }
}
if (attn & HW_INTERRUT_ASSERT_SET_2) {
@@ -2117,9 +3012,10 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
int func = BP_FUNC(bp);
REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
- bp->mf_config = SHMEM_RD(bp,
- mf_cfg.func_mf_config[func].config);
- val = SHMEM_RD(bp, func_mb[func].drv_status);
+ bp->mf_config[BP_VN(bp)] = MF_CFG_RD(bp,
+ func_mf_config[BP_ABS_FUNC(bp)].config);
+ val = SHMEM_RD(bp,
+ func_mb[BP_FW_MB_IDX(bp)].drv_status);
if (val & DRV_STATUS_DCC_EVENT_MASK)
bnx2x_dcc_event(bp,
(val & DRV_STATUS_DCC_EVENT_MASK));
@@ -2149,13 +3045,13 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) {
BNX2X_ERR("LATCHED attention 0x%08x (masked)\n", attn);
if (attn & BNX2X_GRC_TIMEOUT) {
- val = CHIP_IS_E1H(bp) ?
- REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN) : 0;
+ val = CHIP_IS_E1(bp) ? 0 :
+ REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN);
BNX2X_ERR("GRC time-out 0x%08x\n", val);
}
if (attn & BNX2X_GRC_RSV) {
- val = CHIP_IS_E1H(bp) ?
- REG_RD(bp, MISC_REG_GRC_RSV_ATTN) : 0;
+ val = CHIP_IS_E1(bp) ? 0 :
+ REG_RD(bp, MISC_REG_GRC_RSV_ATTN);
BNX2X_ERR("GRC reserved 0x%08x\n", val);
}
REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff);
@@ -2168,6 +3064,7 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
#define RESET_DONE_FLAG_MASK (~LOAD_COUNTER_MASK)
#define RESET_DONE_FLAG_SHIFT LOAD_COUNTER_BITS
#define CHIP_PARITY_SUPPORTED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp))
+
/*
* should be run under rtnl lock
*/
@@ -2460,6 +3357,74 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp)
attn.sig[3]);
}
+
+static inline void bnx2x_attn_int_deasserted4(struct bnx2x *bp, u32 attn)
+{
+ u32 val;
+ if (attn & AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT) {
+
+ val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS_CLR);
+ BNX2X_ERR("PGLUE hw attention 0x%x\n", val);
+ if (val & PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR)
+ BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_"
+ "ADDRESS_ERROR\n");
+ if (val & PGLUE_B_PGLUE_B_INT_STS_REG_INCORRECT_RCV_BEHAVIOR)
+ BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_"
+ "INCORRECT_RCV_BEHAVIOR\n");
+ if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN)
+ BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_"
+ "WAS_ERROR_ATTN\n");
+ if (val & PGLUE_B_PGLUE_B_INT_STS_REG_VF_LENGTH_VIOLATION_ATTN)
+ BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_"
+ "VF_LENGTH_VIOLATION_ATTN\n");
+ if (val &
+ PGLUE_B_PGLUE_B_INT_STS_REG_VF_GRC_SPACE_VIOLATION_ATTN)
+ BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_"
+ "VF_GRC_SPACE_VIOLATION_ATTN\n");
+ if (val &
+ PGLUE_B_PGLUE_B_INT_STS_REG_VF_MSIX_BAR_VIOLATION_ATTN)
+ BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_"
+ "VF_MSIX_BAR_VIOLATION_ATTN\n");
+ if (val & PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_ERROR_ATTN)
+ BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_"
+ "TCPL_ERROR_ATTN\n");
+ if (val & PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_IN_TWO_RCBS_ATTN)
+ BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_"
+ "TCPL_IN_TWO_RCBS_ATTN\n");
+ if (val & PGLUE_B_PGLUE_B_INT_STS_REG_CSSNOOP_FIFO_OVERFLOW)
+ BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_"
+ "CSSNOOP_FIFO_OVERFLOW\n");
+ }
+ if (attn & AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT) {
+ val = REG_RD(bp, ATC_REG_ATC_INT_STS_CLR);
+ BNX2X_ERR("ATC hw attention 0x%x\n", val);
+ if (val & ATC_ATC_INT_STS_REG_ADDRESS_ERROR)
+ BNX2X_ERR("ATC_ATC_INT_STS_REG_ADDRESS_ERROR\n");
+ if (val & ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND)
+ BNX2X_ERR("ATC_ATC_INT_STS_REG"
+ "_ATC_TCPL_TO_NOT_PEND\n");
+ if (val & ATC_ATC_INT_STS_REG_ATC_GPA_MULTIPLE_HITS)
+ BNX2X_ERR("ATC_ATC_INT_STS_REG_"
+ "ATC_GPA_MULTIPLE_HITS\n");
+ if (val & ATC_ATC_INT_STS_REG_ATC_RCPL_TO_EMPTY_CNT)
+ BNX2X_ERR("ATC_ATC_INT_STS_REG_"
+ "ATC_RCPL_TO_EMPTY_CNT\n");
+ if (val & ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR)
+ BNX2X_ERR("ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR\n");
+ if (val & ATC_ATC_INT_STS_REG_ATC_IREQ_LESS_THAN_STU)
+ BNX2X_ERR("ATC_ATC_INT_STS_REG_"
+ "ATC_IREQ_LESS_THAN_STU\n");
+ }
+
+ if (attn & (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR |
+ AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR)) {
+ BNX2X_ERR("FATAL parity attention set4 0x%x\n",
+ (u32)(attn & (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR |
+ AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR)));
+ }
+
+}
+
static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
{
struct attn_route attn, *group_mask;
@@ -2490,17 +3455,28 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4);
attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4);
attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4);
- DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x\n",
- attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3]);
+ if (CHIP_IS_E2(bp))
+ attn.sig[4] =
+ REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 + port*4);
+ else
+ attn.sig[4] = 0;
+
+ DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x %08x\n",
+ attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3], attn.sig[4]);
for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) {
if (deasserted & (1 << index)) {
group_mask = &bp->attn_group[index];
- DP(NETIF_MSG_HW, "group[%d]: %08x %08x %08x %08x\n",
- index, group_mask->sig[0], group_mask->sig[1],
- group_mask->sig[2], group_mask->sig[3]);
+ DP(NETIF_MSG_HW, "group[%d]: %08x %08x "
+ "%08x %08x %08x\n",
+ index,
+ group_mask->sig[0], group_mask->sig[1],
+ group_mask->sig[2], group_mask->sig[3],
+ group_mask->sig[4]);
+ bnx2x_attn_int_deasserted4(bp,
+ attn.sig[4] & group_mask->sig[4]);
bnx2x_attn_int_deasserted3(bp,
attn.sig[3] & group_mask->sig[3]);
bnx2x_attn_int_deasserted1(bp,
@@ -2514,11 +3490,15 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
bnx2x_release_alr(bp);
- reg_addr = (HC_REG_COMMAND_REG + port*32 + COMMAND_REG_ATTN_BITS_CLR);
+ if (bp->common.int_block == INT_BLOCK_HC)
+ reg_addr = (HC_REG_COMMAND_REG + port*32 +
+ COMMAND_REG_ATTN_BITS_CLR);
+ else
+ reg_addr = (BAR_IGU_INTMEM + IGU_CMD_ATTN_BIT_CLR_UPPER*8);
val = ~deasserted;
- DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n",
- val, reg_addr);
+ DP(NETIF_MSG_HW, "about to mask 0x%08x at %s addr 0x%x\n", val,
+ (bp->common.int_block == INT_BLOCK_HC) ? "HC" : "IGU", reg_addr);
REG_WR(bp, reg_addr, val);
if (~bp->attn_state & deasserted)
@@ -2571,6 +3551,141 @@ static void bnx2x_attn_int(struct bnx2x *bp)
bnx2x_attn_int_deasserted(bp, deasserted);
}
+static inline void bnx2x_update_eq_prod(struct bnx2x *bp, u16 prod)
+{
+ /* No memory barriers */
+ storm_memset_eq_prod(bp, prod, BP_FUNC(bp));
+ mmiowb(); /* keep prod updates ordered */
+}
+
+#ifdef BCM_CNIC
+static int bnx2x_cnic_handle_cfc_del(struct bnx2x *bp, u32 cid,
+ union event_ring_elem *elem)
+{
+ if (!bp->cnic_eth_dev.starting_cid ||
+ cid < bp->cnic_eth_dev.starting_cid)
+ return 1;
+
+ DP(BNX2X_MSG_SP, "got delete ramrod for CNIC CID %d\n", cid);
+
+ if (unlikely(elem->message.data.cfc_del_event.error)) {
+ BNX2X_ERR("got delete ramrod for CNIC CID %d with error!\n",
+ cid);
+ bnx2x_panic_dump(bp);
+ }
+ bnx2x_cnic_cfc_comp(bp, cid);
+ return 0;
+}
+#endif
+
+static void bnx2x_eq_int(struct bnx2x *bp)
+{
+ u16 hw_cons, sw_cons, sw_prod;
+ union event_ring_elem *elem;
+ u32 cid;
+ u8 opcode;
+ int spqe_cnt = 0;
+
+ hw_cons = le16_to_cpu(*bp->eq_cons_sb);
+
+ /* The hw_cos range is 1-255, 257 - the sw_cons range is 0-254, 256.
+ * when we get the the next-page we nned to adjust so the loop
+ * condition below will be met. The next element is the size of a
+ * regular element and hence incrementing by 1
+ */
+ if ((hw_cons & EQ_DESC_MAX_PAGE) == EQ_DESC_MAX_PAGE)
+ hw_cons++;
+
+ /* This function may never run in parralel with itself for a
+ * specific bp, thus there is no need in "paired" read memory
+ * barrier here.
+ */
+ sw_cons = bp->eq_cons;
+ sw_prod = bp->eq_prod;
+
+ DP(BNX2X_MSG_SP, "EQ: hw_cons %u sw_cons %u bp->spq_left %u\n",
+ hw_cons, sw_cons, atomic_read(&bp->spq_left));
+
+ for (; sw_cons != hw_cons;
+ sw_prod = NEXT_EQ_IDX(sw_prod), sw_cons = NEXT_EQ_IDX(sw_cons)) {
+
+
+ elem = &bp->eq_ring[EQ_DESC(sw_cons)];
+
+ cid = SW_CID(elem->message.data.cfc_del_event.cid);
+ opcode = elem->message.opcode;
+
+
+ /* handle eq element */
+ switch (opcode) {
+ case EVENT_RING_OPCODE_STAT_QUERY:
+ DP(NETIF_MSG_TIMER, "got statistics comp event\n");
+ /* nothing to do with stats comp */
+ continue;
+
+ case EVENT_RING_OPCODE_CFC_DEL:
+ /* handle according to cid range */
+ /*
+ * we may want to verify here that the bp state is
+ * HALTING
+ */
+ DP(NETIF_MSG_IFDOWN,
+ "got delete ramrod for MULTI[%d]\n", cid);
+#ifdef BCM_CNIC
+ if (!bnx2x_cnic_handle_cfc_del(bp, cid, elem))
+ goto next_spqe;
+#endif
+ bnx2x_fp(bp, cid, state) =
+ BNX2X_FP_STATE_CLOSED;
+
+ goto next_spqe;
+ }
+
+ switch (opcode | bp->state) {
+ case (EVENT_RING_OPCODE_FUNCTION_START |
+ BNX2X_STATE_OPENING_WAIT4_PORT):
+ DP(NETIF_MSG_IFUP, "got setup ramrod\n");
+ bp->state = BNX2X_STATE_FUNC_STARTED;
+ break;
+
+ case (EVENT_RING_OPCODE_FUNCTION_STOP |
+ BNX2X_STATE_CLOSING_WAIT4_HALT):
+ DP(NETIF_MSG_IFDOWN, "got halt ramrod\n");
+ bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
+ break;
+
+ case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_OPEN):
+ case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_DIAG):
+ DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
+ bp->set_mac_pending = 0;
+ break;
+
+ case (EVENT_RING_OPCODE_SET_MAC |
+ BNX2X_STATE_CLOSING_WAIT4_HALT):
+ DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
+ bp->set_mac_pending = 0;
+ break;
+ default:
+ /* unknown event log error and continue */
+ BNX2X_ERR("Unknown EQ event %d\n",
+ elem->message.opcode);
+ }
+next_spqe:
+ spqe_cnt++;
+ } /* for */
+
+ smp_mb__before_atomic_inc();
+ atomic_add(spqe_cnt, &bp->spq_left);
+
+ bp->eq_cons = sw_cons;
+ bp->eq_prod = sw_prod;
+ /* Make sure that above mem writes were issued towards the memory */
+ smp_wmb();
+
+ /* update producer */
+ bnx2x_update_eq_prod(bp, bp->eq_prod);
+}
+
static void bnx2x_sp_task(struct work_struct *work)
{
struct bnx2x *bp = container_of(work, struct bnx2x, sp_task.work);
@@ -2589,31 +3704,29 @@ static void bnx2x_sp_task(struct work_struct *work)
DP(NETIF_MSG_INTR, "got a slowpath interrupt (status 0x%x)\n", status);
/* HW attentions */
- if (status & 0x1) {
+ if (status & BNX2X_DEF_SB_ATT_IDX) {
bnx2x_attn_int(bp);
- status &= ~0x1;
+ status &= ~BNX2X_DEF_SB_ATT_IDX;
}
- /* CStorm events: STAT_QUERY */
- if (status & 0x2) {
- DP(BNX2X_MSG_SP, "CStorm events: STAT_QUERY\n");
- status &= ~0x2;
+ /* SP events: STAT_QUERY and others */
+ if (status & BNX2X_DEF_SB_IDX) {
+
+ /* Handle EQ completions */
+ bnx2x_eq_int(bp);
+
+ bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID,
+ le16_to_cpu(bp->def_idx), IGU_INT_NOP, 1);
+
+ status &= ~BNX2X_DEF_SB_IDX;
}
if (unlikely(status))
DP(NETIF_MSG_INTR, "got an unknown interrupt! (status 0x%x)\n",
status);
- bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, le16_to_cpu(bp->def_att_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, le16_to_cpu(bp->def_c_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, le16_to_cpu(bp->def_x_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx),
- IGU_INT_ENABLE, 1);
+ bnx2x_ack_sb(bp, bp->igu_dsb_id, ATTENTION_ID,
+ le16_to_cpu(bp->def_att_idx), IGU_INT_ENABLE, 1);
}
irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
@@ -2627,7 +3740,8 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
return IRQ_HANDLED;
}
- bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, 0, IGU_INT_DISABLE, 0);
+ bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, 0,
+ IGU_INT_DISABLE, 0);
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -2671,7 +3785,7 @@ static void bnx2x_timer(unsigned long data)
}
if (!BP_NOMCP(bp)) {
- int func = BP_FUNC(bp);
+ int mb_idx = BP_FW_MB_IDX(bp);
u32 drv_pulse;
u32 mcp_pulse;
@@ -2679,9 +3793,9 @@ static void bnx2x_timer(unsigned long data)
bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK;
/* TBD - add SYSTEM_TIME */
drv_pulse = bp->fw_drv_pulse_wr_seq;
- SHMEM_WR(bp, func_mb[func].drv_pulse_mb, drv_pulse);
+ SHMEM_WR(bp, func_mb[mb_idx].drv_pulse_mb, drv_pulse);
- mcp_pulse = (SHMEM_RD(bp, func_mb[func].mcp_pulse_mb) &
+ mcp_pulse = (SHMEM_RD(bp, func_mb[mb_idx].mcp_pulse_mb) &
MCP_PULSE_SEQ_MASK);
/* The delta between driver pulse and mcp response
* should be 1 (before mcp response) or 0 (after mcp response)
@@ -2709,324 +3823,310 @@ timer_restart:
* nic init service functions
*/
-static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id)
+static inline void bnx2x_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
{
- int port = BP_PORT(bp);
+ u32 i;
+ if (!(len%4) && !(addr%4))
+ for (i = 0; i < len; i += 4)
+ REG_WR(bp, addr + i, fill);
+ else
+ for (i = 0; i < len; i++)
+ REG_WR8(bp, addr + i, fill);
- /* "CSTORM" */
- bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY +
- CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), 0,
- CSTORM_SB_STATUS_BLOCK_U_SIZE / 4);
- bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY +
- CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), 0,
- CSTORM_SB_STATUS_BLOCK_C_SIZE / 4);
}
-void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb,
- dma_addr_t mapping, int sb_id)
+/* helper: writes FP SP data to FW - data_size in dwords */
+static inline void bnx2x_wr_fp_sb_data(struct bnx2x *bp,
+ int fw_sb_id,
+ u32 *sb_data_p,
+ u32 data_size)
{
- int port = BP_PORT(bp);
- int func = BP_FUNC(bp);
int index;
- u64 section;
+ for (index = 0; index < data_size; index++)
+ REG_WR(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) +
+ sizeof(u32)*index,
+ *(sb_data_p + index));
+}
+
+static inline void bnx2x_zero_fp_sb(struct bnx2x *bp, int fw_sb_id)
+{
+ u32 *sb_data_p;
+ u32 data_size = 0;
+ struct hc_status_block_data_e2 sb_data_e2;
+ struct hc_status_block_data_e1x sb_data_e1x;
+
+ /* disable the function first */
+ if (CHIP_IS_E2(bp)) {
+ memset(&sb_data_e2, 0, sizeof(struct hc_status_block_data_e2));
+ sb_data_e2.common.p_func.pf_id = HC_FUNCTION_DISABLED;
+ sb_data_e2.common.p_func.vf_id = HC_FUNCTION_DISABLED;
+ sb_data_e2.common.p_func.vf_valid = false;
+ sb_data_p = (u32 *)&sb_data_e2;
+ data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32);
+ } else {
+ memset(&sb_data_e1x, 0,
+ sizeof(struct hc_status_block_data_e1x));
+ sb_data_e1x.common.p_func.pf_id = HC_FUNCTION_DISABLED;
+ sb_data_e1x.common.p_func.vf_id = HC_FUNCTION_DISABLED;
+ sb_data_e1x.common.p_func.vf_valid = false;
+ sb_data_p = (u32 *)&sb_data_e1x;
+ data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32);
+ }
+ bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size);
- /* USTORM */
- section = ((u64)mapping) + offsetof(struct host_status_block,
- u_status_block);
- sb->u_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id), U64_LO(section));
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- ((CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_USB_FUNC_OFF +
- CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), func);
-
- for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, index), 1);
+ bnx2x_fill(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_STATUS_BLOCK_OFFSET(fw_sb_id), 0,
+ CSTORM_STATUS_BLOCK_SIZE);
+ bnx2x_fill(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_SYNC_BLOCK_OFFSET(fw_sb_id), 0,
+ CSTORM_SYNC_BLOCK_SIZE);
+}
- /* CSTORM */
- section = ((u64)mapping) + offsetof(struct host_status_block,
- c_status_block);
- sb->c_status_block.status_block_id = sb_id;
+/* helper: writes SP SB data to FW */
+static inline void bnx2x_wr_sp_sb_data(struct bnx2x *bp,
+ struct hc_sp_status_block_data *sp_sb_data)
+{
+ int func = BP_FUNC(bp);
+ int i;
+ for (i = 0; i < sizeof(struct hc_sp_status_block_data)/sizeof(u32); i++)
+ REG_WR(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) +
+ i*sizeof(u32),
+ *((u32 *)sp_sb_data + i));
+}
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id), U64_LO(section));
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- ((CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_CSB_FUNC_OFF +
- CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), func);
+static inline void bnx2x_zero_sp_sb(struct bnx2x *bp)
+{
+ int func = BP_FUNC(bp);
+ struct hc_sp_status_block_data sp_sb_data;
+ memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data));
+
+ sp_sb_data.p_func.pf_id = HC_FUNCTION_DISABLED;
+ sp_sb_data.p_func.vf_id = HC_FUNCTION_DISABLED;
+ sp_sb_data.p_func.vf_valid = false;
+
+ bnx2x_wr_sp_sb_data(bp, &sp_sb_data);
- for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, index), 1);
+ bnx2x_fill(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_SP_STATUS_BLOCK_OFFSET(func), 0,
+ CSTORM_SP_STATUS_BLOCK_SIZE);
+ bnx2x_fill(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_SP_SYNC_BLOCK_OFFSET(func), 0,
+ CSTORM_SP_SYNC_BLOCK_SIZE);
- bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
}
-static void bnx2x_zero_def_sb(struct bnx2x *bp)
+
+static inline
+void bnx2x_setup_ndsb_state_machine(struct hc_status_block_sm *hc_sm,
+ int igu_sb_id, int igu_seg_id)
{
- int func = BP_FUNC(bp);
+ hc_sm->igu_sb_id = igu_sb_id;
+ hc_sm->igu_seg_id = igu_seg_id;
+ hc_sm->timer_value = 0xFF;
+ hc_sm->time_to_expire = 0xFFFFFFFF;
+}
+
+void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
+ u8 vf_valid, int fw_sb_id, int igu_sb_id)
+{
+ int igu_seg_id;
+
+ 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;
+
+ if (CHIP_INT_MODE_IS_BC(bp))
+ igu_seg_id = HC_SEG_ACCESS_NORM;
+ else
+ igu_seg_id = IGU_SEG_ACCESS_NORM;
+
+ bnx2x_zero_fp_sb(bp, fw_sb_id);
+
+ if (CHIP_IS_E2(bp)) {
+ memset(&sb_data_e2, 0, sizeof(struct hc_status_block_data_e2));
+ sb_data_e2.common.p_func.pf_id = BP_FUNC(bp);
+ sb_data_e2.common.p_func.vf_id = vfid;
+ sb_data_e2.common.p_func.vf_valid = vf_valid;
+ sb_data_e2.common.p_func.vnic_id = BP_VN(bp);
+ sb_data_e2.common.same_igu_sb_1b = true;
+ 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 {
+ memset(&sb_data_e1x, 0,
+ sizeof(struct hc_status_block_data_e1x));
+ sb_data_e1x.common.p_func.pf_id = BP_FUNC(bp);
+ sb_data_e1x.common.p_func.vf_id = 0xff;
+ sb_data_e1x.common.p_func.vf_valid = false;
+ sb_data_e1x.common.p_func.vnic_id = BP_VN(bp);
+ sb_data_e1x.common.same_igu_sb_1b = true;
+ 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);
+ }
+
+ bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_RX_ID],
+ igu_sb_id, igu_seg_id);
+ bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_TX_ID],
+ igu_sb_id, igu_seg_id);
+
+ DP(NETIF_MSG_HW, "Init FW SB %d\n", fw_sb_id);
+
+ /* write indecies to HW */
+ bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size);
+}
+
+static void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id,
+ u8 sb_index, u8 disable, u16 usec)
+{
+ int port = BP_PORT(bp);
+ u8 ticks = usec / BNX2X_BTR;
+
+ storm_memset_hc_timeout(bp, port, fw_sb_id, sb_index, ticks);
- bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY +
- TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
- sizeof(struct tstorm_def_status_block)/4);
- bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY +
- CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), 0,
- sizeof(struct cstorm_def_status_block_u)/4);
- bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY +
- CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), 0,
- sizeof(struct cstorm_def_status_block_c)/4);
- bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY +
- XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
- sizeof(struct xstorm_def_status_block)/4);
+ disable = disable ? 1 : (usec ? 0 : 1);
+ storm_memset_hc_disable(bp, port, fw_sb_id, sb_index, disable);
+}
+
+static void bnx2x_update_coalesce_sb(struct bnx2x *bp, u16 fw_sb_id,
+ u16 tx_usec, u16 rx_usec)
+{
+ bnx2x_update_coalesce_sb_index(bp, fw_sb_id, U_SB_ETH_RX_CQ_INDEX,
+ false, rx_usec);
+ bnx2x_update_coalesce_sb_index(bp, fw_sb_id, C_SB_ETH_TX_CQ_INDEX,
+ false, tx_usec);
}
-static void bnx2x_init_def_sb(struct bnx2x *bp,
- struct host_def_status_block *def_sb,
- dma_addr_t mapping, int sb_id)
+static void bnx2x_init_def_sb(struct bnx2x *bp)
{
+ struct host_sp_status_block *def_sb = bp->def_status_blk;
+ dma_addr_t mapping = bp->def_status_blk_mapping;
+ int igu_sp_sb_index;
+ int igu_seg_id;
int port = BP_PORT(bp);
int func = BP_FUNC(bp);
- int index, val, reg_offset;
+ int reg_offset;
u64 section;
+ int index;
+ struct hc_sp_status_block_data sp_sb_data;
+ memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data));
+
+ if (CHIP_INT_MODE_IS_BC(bp)) {
+ igu_sp_sb_index = DEF_SB_IGU_ID;
+ igu_seg_id = HC_SEG_ACCESS_DEF;
+ } else {
+ igu_sp_sb_index = bp->igu_dsb_id;
+ igu_seg_id = IGU_SEG_ACCESS_DEF;
+ }
/* ATTN */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
+ section = ((u64)mapping) + offsetof(struct host_sp_status_block,
atten_status_block);
- def_sb->atten_status_block.status_block_id = sb_id;
+ def_sb->atten_status_block.status_block_id = igu_sp_sb_index;
bp->attn_state = 0;
reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
-
for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) {
- bp->attn_group[index].sig[0] = REG_RD(bp,
- reg_offset + 0x10*index);
- bp->attn_group[index].sig[1] = REG_RD(bp,
- reg_offset + 0x4 + 0x10*index);
- bp->attn_group[index].sig[2] = REG_RD(bp,
- reg_offset + 0x8 + 0x10*index);
- bp->attn_group[index].sig[3] = REG_RD(bp,
- reg_offset + 0xc + 0x10*index);
+ int sindex;
+ /* take care of sig[0]..sig[4] */
+ for (sindex = 0; sindex < 4; sindex++)
+ bp->attn_group[index].sig[sindex] =
+ REG_RD(bp, reg_offset + sindex*0x4 + 0x10*index);
+
+ if (CHIP_IS_E2(bp))
+ /*
+ * enable5 is separate from the rest of the registers,
+ * and therefore the address skip is 4
+ * and not 16 between the different groups
+ */
+ bp->attn_group[index].sig[4] = REG_RD(bp,
+ reg_offset + 0x10 + 0x4*index);
+ else
+ bp->attn_group[index].sig[4] = 0;
}
- reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L :
- HC_REG_ATTN_MSG0_ADDR_L);
-
- REG_WR(bp, reg_offset, U64_LO(section));
- REG_WR(bp, reg_offset + 4, U64_HI(section));
+ if (bp->common.int_block == INT_BLOCK_HC) {
+ reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L :
+ HC_REG_ATTN_MSG0_ADDR_L);
- reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0);
-
- val = REG_RD(bp, reg_offset);
- val |= sb_id;
- REG_WR(bp, reg_offset, val);
+ REG_WR(bp, reg_offset, U64_LO(section));
+ REG_WR(bp, reg_offset + 4, U64_HI(section));
+ } else if (CHIP_IS_E2(bp)) {
+ REG_WR(bp, IGU_REG_ATTN_MSG_ADDR_L, U64_LO(section));
+ REG_WR(bp, IGU_REG_ATTN_MSG_ADDR_H, U64_HI(section));
+ }
- /* USTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- u_def_status_block);
- def_sb->u_def_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func), U64_LO(section));
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- ((CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_USB_FUNC_OFF +
- CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), func);
-
- for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(func, index), 1);
+ section = ((u64)mapping) + offsetof(struct host_sp_status_block,
+ sp_sb);
- /* CSTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- c_def_status_block);
- def_sb->c_def_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func), U64_LO(section));
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- ((CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF +
- CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), func);
-
- for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(func, index), 1);
+ bnx2x_zero_sp_sb(bp);
- /* TSTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- t_def_status_block);
- def_sb->t_def_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_TSTRORM_INTMEM + DEF_TSB_FUNC_OFF +
- TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
-
- for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_TSTRORM_INTMEM +
- TSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
+ sp_sb_data.host_sb_addr.lo = U64_LO(section);
+ sp_sb_data.host_sb_addr.hi = U64_HI(section);
+ sp_sb_data.igu_sb_id = igu_sp_sb_index;
+ sp_sb_data.igu_seg_id = igu_seg_id;
+ sp_sb_data.p_func.pf_id = func;
+ sp_sb_data.p_func.vnic_id = BP_VN(bp);
+ sp_sb_data.p_func.vf_id = 0xff;
- /* XSTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- x_def_status_block);
- def_sb->x_def_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_XSTRORM_INTMEM + DEF_XSB_FUNC_OFF +
- XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
-
- for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_XSTRORM_INTMEM +
- XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
+ bnx2x_wr_sp_sb_data(bp, &sp_sb_data);
bp->stats_pending = 0;
bp->set_mac_pending = 0;
- bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+ bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, 0, IGU_INT_ENABLE, 0);
}
void bnx2x_update_coalesce(struct bnx2x *bp)
{
- int port = BP_PORT(bp);
int i;
- for_each_queue(bp, i) {
- int sb_id = bp->fp[i].sb_id;
-
- /* HC_INDEX_U_ETH_RX_CQ_CONS */
- REG_WR8(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, sb_id,
- U_SB_ETH_RX_CQ_INDEX),
- bp->rx_ticks/(4 * BNX2X_BTR));
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id,
- U_SB_ETH_RX_CQ_INDEX),
- (bp->rx_ticks/(4 * BNX2X_BTR)) ? 0 : 1);
-
- /* HC_INDEX_C_ETH_TX_CQ_CONS */
- REG_WR8(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id,
- C_SB_ETH_TX_CQ_INDEX),
- bp->tx_ticks/(4 * BNX2X_BTR));
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id,
- C_SB_ETH_TX_CQ_INDEX),
- (bp->tx_ticks/(4 * BNX2X_BTR)) ? 0 : 1);
- }
+ for_each_queue(bp, i)
+ bnx2x_update_coalesce_sb(bp, bp->fp[i].fw_sb_id,
+ bp->rx_ticks, bp->tx_ticks);
}
static void bnx2x_init_sp_ring(struct bnx2x *bp)
{
- int func = BP_FUNC(bp);
-
spin_lock_init(&bp->spq_lock);
+ atomic_set(&bp->spq_left, MAX_SPQ_PENDING);
- bp->spq_left = MAX_SPQ_PENDING;
bp->spq_prod_idx = 0;
bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX;
bp->spq_prod_bd = bp->spq;
bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT;
-
- REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func),
- U64_LO(bp->spq_mapping));
- REG_WR(bp,
- XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func) + 4,
- U64_HI(bp->spq_mapping));
-
- REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(func),
- bp->spq_prod_idx);
}
-static void bnx2x_init_context(struct bnx2x *bp)
+static void bnx2x_init_eq_ring(struct bnx2x *bp)
{
int i;
+ for (i = 1; i <= NUM_EQ_PAGES; i++) {
+ union event_ring_elem *elem =
+ &bp->eq_ring[EQ_DESC_CNT_PAGE * i - 1];
- /* Rx */
- for_each_queue(bp, i) {
- struct eth_context *context = bnx2x_sp(bp, context[i].eth);
- struct bnx2x_fastpath *fp = &bp->fp[i];
- u8 cl_id = fp->cl_id;
-
- context->ustorm_st_context.common.sb_index_numbers =
- BNX2X_RX_SB_INDEX_NUM;
- context->ustorm_st_context.common.clientId = cl_id;
- context->ustorm_st_context.common.status_block_id = fp->sb_id;
- context->ustorm_st_context.common.flags =
- (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT |
- USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS);
- context->ustorm_st_context.common.statistics_counter_id =
- cl_id;
- context->ustorm_st_context.common.mc_alignment_log_size =
- BNX2X_RX_ALIGN_SHIFT;
- context->ustorm_st_context.common.bd_buff_size =
- bp->rx_buf_size;
- context->ustorm_st_context.common.bd_page_base_hi =
- U64_HI(fp->rx_desc_mapping);
- context->ustorm_st_context.common.bd_page_base_lo =
- U64_LO(fp->rx_desc_mapping);
- if (!fp->disable_tpa) {
- context->ustorm_st_context.common.flags |=
- USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA;
- context->ustorm_st_context.common.sge_buff_size =
- (u16)min_t(u32, SGE_PAGE_SIZE*PAGES_PER_SGE,
- 0xffff);
- context->ustorm_st_context.common.sge_page_base_hi =
- U64_HI(fp->rx_sge_mapping);
- context->ustorm_st_context.common.sge_page_base_lo =
- U64_LO(fp->rx_sge_mapping);
-
- context->ustorm_st_context.common.max_sges_for_packet =
- SGE_PAGE_ALIGN(bp->dev->mtu) >> SGE_PAGE_SHIFT;
- context->ustorm_st_context.common.max_sges_for_packet =
- ((context->ustorm_st_context.common.
- max_sges_for_packet + PAGES_PER_SGE - 1) &
- (~(PAGES_PER_SGE - 1))) >> PAGES_PER_SGE_SHIFT;
- }
-
- context->ustorm_ag_context.cdu_usage =
- CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
- CDU_REGION_NUMBER_UCM_AG,
- ETH_CONNECTION_TYPE);
-
- context->xstorm_ag_context.cdu_reserved =
- CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
- CDU_REGION_NUMBER_XCM_AG,
- ETH_CONNECTION_TYPE);
- }
-
- /* Tx */
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
- struct eth_context *context =
- bnx2x_sp(bp, context[i].eth);
-
- context->cstorm_st_context.sb_index_number =
- C_SB_ETH_TX_CQ_INDEX;
- context->cstorm_st_context.status_block_id = fp->sb_id;
-
- context->xstorm_st_context.tx_bd_page_base_hi =
- U64_HI(fp->tx_desc_mapping);
- context->xstorm_st_context.tx_bd_page_base_lo =
- U64_LO(fp->tx_desc_mapping);
- context->xstorm_st_context.statistics_data = (fp->cl_id |
- XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
+ elem->next_page.addr.hi =
+ cpu_to_le32(U64_HI(bp->eq_mapping +
+ BCM_PAGE_SIZE * (i % NUM_EQ_PAGES)));
+ elem->next_page.addr.lo =
+ cpu_to_le32(U64_LO(bp->eq_mapping +
+ BCM_PAGE_SIZE*(i % NUM_EQ_PAGES)));
}
+ bp->eq_cons = 0;
+ bp->eq_prod = NUM_EQ_DESC;
+ bp->eq_cons_sb = BNX2X_EQ_INDEX;
}
static void bnx2x_init_ind_table(struct bnx2x *bp)
@@ -3045,47 +4145,11 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
bp->fp->cl_id + (i % bp->num_queues));
}
-void bnx2x_set_client_config(struct bnx2x *bp)
-{
- struct tstorm_eth_client_config tstorm_client = {0};
- int port = BP_PORT(bp);
- int i;
-
- tstorm_client.mtu = bp->dev->mtu;
- tstorm_client.config_flags =
- (TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE |
- TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE);
-#ifdef BCM_VLAN
- if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) {
- tstorm_client.config_flags |=
- TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE;
- DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
- }
-#endif
-
- for_each_queue(bp, i) {
- tstorm_client.statistics_counter_id = bp->fp[i].cl_id;
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id),
- ((u32 *)&tstorm_client)[0]);
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id) + 4,
- ((u32 *)&tstorm_client)[1]);
- }
-
- DP(BNX2X_MSG_OFF, "tstorm_client: 0x%08x 0x%08x\n",
- ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]);
-}
-
void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
{
- struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0};
int mode = bp->rx_mode;
- int mask = bp->rx_mode_cl_mask;
- int func = BP_FUNC(bp);
- int port = BP_PORT(bp);
- int i;
+ u16 cl_id;
+
/* All but management unicast packets should pass to the host as well */
u32 llh_mask =
NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST |
@@ -3093,28 +4157,32 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN |
NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN;
- DP(NETIF_MSG_IFUP, "rx mode %d mask 0x%x\n", mode, mask);
-
switch (mode) {
case BNX2X_RX_MODE_NONE: /* no Rx */
- tstorm_mac_filter.ucast_drop_all = mask;
- tstorm_mac_filter.mcast_drop_all = mask;
- tstorm_mac_filter.bcast_drop_all = mask;
+ cl_id = BP_L_ID(bp);
+ bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE);
break;
case BNX2X_RX_MODE_NORMAL:
- tstorm_mac_filter.bcast_accept_all = mask;
+ cl_id = BP_L_ID(bp);
+ bnx2x_rxq_set_mac_filters(bp, cl_id,
+ BNX2X_ACCEPT_UNICAST |
+ BNX2X_ACCEPT_BROADCAST |
+ BNX2X_ACCEPT_MULTICAST);
break;
case BNX2X_RX_MODE_ALLMULTI:
- tstorm_mac_filter.mcast_accept_all = mask;
- tstorm_mac_filter.bcast_accept_all = mask;
+ cl_id = BP_L_ID(bp);
+ bnx2x_rxq_set_mac_filters(bp, cl_id,
+ BNX2X_ACCEPT_UNICAST |
+ BNX2X_ACCEPT_BROADCAST |
+ BNX2X_ACCEPT_ALL_MULTICAST);
break;
case BNX2X_RX_MODE_PROMISC:
- tstorm_mac_filter.ucast_accept_all = mask;
- tstorm_mac_filter.mcast_accept_all = mask;
- tstorm_mac_filter.bcast_accept_all = mask;
+ cl_id = BP_L_ID(bp);
+ bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_PROMISCUOUS_MODE);
+
/* pass management unicast packets as well */
llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST;
break;
@@ -3125,262 +4193,64 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
}
REG_WR(bp,
- (port ? NIG_REG_LLH1_BRB1_DRV_MASK : NIG_REG_LLH0_BRB1_DRV_MASK),
+ BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK :
+ NIG_REG_LLH0_BRB1_DRV_MASK,
llh_mask);
- for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) {
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_MAC_FILTER_CONFIG_OFFSET(func) + i * 4,
- ((u32 *)&tstorm_mac_filter)[i]);
-
-/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i,
- ((u32 *)&tstorm_mac_filter)[i]); */
- }
+ DP(NETIF_MSG_IFUP, "rx mode %d\n"
+ "drop_ucast 0x%x\ndrop_mcast 0x%x\ndrop_bcast 0x%x\n"
+ "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n", mode,
+ bp->mac_filters.ucast_drop_all,
+ bp->mac_filters.mcast_drop_all,
+ bp->mac_filters.bcast_drop_all,
+ bp->mac_filters.ucast_accept_all,
+ bp->mac_filters.mcast_accept_all,
+ bp->mac_filters.bcast_accept_all
+ );
- if (mode != BNX2X_RX_MODE_NONE)
- bnx2x_set_client_config(bp);
+ storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp));
}
static void bnx2x_init_internal_common(struct bnx2x *bp)
{
int i;
- /* Zero this manually as its initialization is
- currently missing in the initTool */
- for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++)
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_AGG_DATA_OFFSET + i * 4, 0);
-}
-
-static void bnx2x_init_internal_port(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
-
- REG_WR(bp,
- BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_U_OFFSET(port), BNX2X_BTR);
- REG_WR(bp,
- BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_C_OFFSET(port), BNX2X_BTR);
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
-}
-
-static void bnx2x_init_internal_func(struct bnx2x *bp)
-{
- struct tstorm_eth_function_common_config tstorm_config = {0};
- struct stats_indication_flags stats_flags = {0};
- int port = BP_PORT(bp);
- int func = BP_FUNC(bp);
- int i, j;
- u32 offset;
- u16 max_agg_size;
-
- tstorm_config.config_flags = RSS_FLAGS(bp);
-
- if (is_multi(bp))
- tstorm_config.rss_result_mask = MULTI_MASK;
-
- /* Enable TPA if needed */
- if (bp->flags & TPA_ENABLE_FLAG)
- tstorm_config.config_flags |=
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA;
-
- if (IS_E1HMF(bp))
- tstorm_config.config_flags |=
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM;
-
- tstorm_config.leading_client_id = BP_L_ID(bp);
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(func),
- (*(u32 *)&tstorm_config));
-
- bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
- bp->rx_mode_cl_mask = (1 << BP_L_ID(bp));
- bnx2x_set_storm_rx_mode(bp);
+ if (!CHIP_IS_E1(bp)) {
- for_each_queue(bp, i) {
- u8 cl_id = bp->fp[i].cl_id;
-
- /* reset xstorm per client statistics */
- offset = BAR_XSTRORM_INTMEM +
- XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
- for (j = 0;
- j < sizeof(struct xstorm_per_client_stats) / 4; j++)
- REG_WR(bp, offset + j*4, 0);
-
- /* reset tstorm per client statistics */
- offset = BAR_TSTRORM_INTMEM +
- TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
- for (j = 0;
- j < sizeof(struct tstorm_per_client_stats) / 4; j++)
- REG_WR(bp, offset + j*4, 0);
-
- /* reset ustorm per client statistics */
- offset = BAR_USTRORM_INTMEM +
- USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
- for (j = 0;
- j < sizeof(struct ustorm_per_client_stats) / 4; j++)
- REG_WR(bp, offset + j*4, 0);
- }
-
- /* Init statistics related context */
- stats_flags.collect_eth = 1;
-
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func),
- ((u32 *)&stats_flags)[0]);
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func) + 4,
- ((u32 *)&stats_flags)[1]);
-
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func),
- ((u32 *)&stats_flags)[0]);
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4,
- ((u32 *)&stats_flags)[1]);
-
- REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func),
- ((u32 *)&stats_flags)[0]);
- REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func) + 4,
- ((u32 *)&stats_flags)[1]);
-
- REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func),
- ((u32 *)&stats_flags)[0]);
- REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4,
- ((u32 *)&stats_flags)[1]);
-
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
- U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
- U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
- U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
- U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
-
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
- U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
- U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
-
- if (CHIP_IS_E1H(bp)) {
+ /* xstorm needs to know whether to add ovlan to packets or not,
+ * in switch-independent we'll write 0 to here... */
REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET,
- IS_E1HMF(bp));
+ bp->mf_mode);
REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET,
- IS_E1HMF(bp));
+ bp->mf_mode);
REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET,
- IS_E1HMF(bp));
+ bp->mf_mode);
REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET,
- IS_E1HMF(bp));
-
- REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(func),
- bp->e1hov);
+ bp->mf_mode);
}
- /* Init CQ ring mapping and aggregation size, the FW limit is 8 frags */
- max_agg_size = min_t(u32, (min_t(u32, 8, MAX_SKB_FRAGS) *
- SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff);
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id),
- U64_LO(fp->rx_comp_mapping));
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4,
- U64_HI(fp->rx_comp_mapping));
-
- /* Next page */
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id),
- U64_LO(fp->rx_comp_mapping + BCM_PAGE_SIZE));
+ /* Zero this manually as its initialization is
+ currently missing in the initTool */
+ for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++)
REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id) + 4,
- U64_HI(fp->rx_comp_mapping + BCM_PAGE_SIZE));
-
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id),
- max_agg_size);
- }
-
- /* dropless flow control */
- if (CHIP_IS_E1H(bp)) {
- struct ustorm_eth_rx_pause_data_e1h rx_pause = {0};
-
- rx_pause.bd_thr_low = 250;
- rx_pause.cqe_thr_low = 250;
- rx_pause.cos = 1;
- rx_pause.sge_thr_low = 0;
- rx_pause.bd_thr_high = 350;
- rx_pause.cqe_thr_high = 350;
- rx_pause.sge_thr_high = 0;
-
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- if (!fp->disable_tpa) {
- rx_pause.sge_thr_low = 150;
- rx_pause.sge_thr_high = 250;
- }
-
-
- offset = BAR_USTRORM_INTMEM +
- USTORM_ETH_RING_PAUSE_DATA_OFFSET(port,
- fp->cl_id);
- for (j = 0;
- j < sizeof(struct ustorm_eth_rx_pause_data_e1h)/4;
- j++)
- REG_WR(bp, offset + j*4,
- ((u32 *)&rx_pause)[j]);
- }
- }
-
- memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port));
-
- /* Init rate shaping and fairness contexts */
- if (IS_E1HMF(bp)) {
- int vn;
-
- /* During init there is no active link
- Until link is up, set link rate to 10Gbps */
- bp->link_vars.line_speed = SPEED_10000;
- bnx2x_init_port_minmax(bp);
-
- if (!BP_NOMCP(bp))
- bp->mf_config =
- SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
- bnx2x_calc_vn_weight_sum(bp);
-
- for (vn = VN_0; vn < E1HVN_MAX; vn++)
- bnx2x_init_vn_minmax(bp, 2*vn + port);
-
- /* Enable rate shaping and fairness */
- bp->cmng.flags.cmng_enables |=
- CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
-
- } else {
- /* rate shaping and fairness are disabled */
- DP(NETIF_MSG_IFUP,
- "single function mode minmax will be disabled\n");
+ USTORM_AGG_DATA_OFFSET + i * 4, 0);
+ if (CHIP_IS_E2(bp)) {
+ REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_IGU_MODE_OFFSET,
+ CHIP_INT_MODE_IS_BC(bp) ?
+ HC_IGU_BC_MODE : HC_IGU_NBC_MODE);
}
+}
-
- /* Store cmng structures to internal memory */
- if (bp->port.pmf)
- for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
- ((u32 *)(&bp->cmng))[i]);
+static void bnx2x_init_internal_port(struct bnx2x *bp)
+{
+ /* port */
}
static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
{
switch (load_code) {
case FW_MSG_CODE_DRV_LOAD_COMMON:
+ case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP:
bnx2x_init_internal_common(bp);
/* no break */
@@ -3389,7 +4259,8 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
/* no break */
case FW_MSG_CODE_DRV_LOAD_FUNCTION:
- bnx2x_init_internal_func(bp);
+ /* internal memory per function is
+ initialized inside bnx2x_pf_init */
break;
default:
@@ -3398,43 +4269,63 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
}
}
+static void bnx2x_init_fp_sb(struct bnx2x *bp, int fp_idx)
+{
+ struct bnx2x_fastpath *fp = &bp->fp[fp_idx];
+
+ fp->state = BNX2X_FP_STATE_CLOSED;
+
+ fp->index = 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;
+ /* qZone id equals to FW (per path) client id */
+ fp->cl_qzone_id = fp->cl_id +
+ BP_PORT(bp)*(CHIP_IS_E2(bp) ? ETH_MAX_RX_CLIENTS_E2 :
+ ETH_MAX_RX_CLIENTS_E1H);
+ /* init shortcut */
+ fp->ustorm_rx_prods_offset = CHIP_IS_E2(bp) ?
+ USTORM_RX_PRODS_E2_OFFSET(fp->cl_qzone_id) :
+ USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), fp->cl_id);
+ /* Setup SB indicies */
+ fp->rx_cons_sb = BNX2X_RX_SB_INDEX;
+ fp->tx_cons_sb = BNX2X_TX_SB_INDEX;
+
+ DP(NETIF_MSG_IFUP, "queue[%d]: bnx2x_init_sb(%p,%p) "
+ "cl_id %d fw_sb %d igu_sb %d\n",
+ fp_idx, bp, fp->status_blk.e1x_sb, fp->cl_id, fp->fw_sb_id,
+ fp->igu_sb_id);
+ bnx2x_init_sb(bp, fp->status_blk_mapping, BNX2X_VF_ID_INVALID, false,
+ fp->fw_sb_id, fp->igu_sb_id);
+
+ bnx2x_update_fpsb_idx(fp);
+}
+
void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
{
int i;
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- fp->bp = bp;
- fp->state = BNX2X_FP_STATE_CLOSED;
- fp->index = i;
- fp->cl_id = BP_L_ID(bp) + i;
+ for_each_queue(bp, i)
+ bnx2x_init_fp_sb(bp, i);
#ifdef BCM_CNIC
- fp->sb_id = fp->cl_id + 1;
-#else
- fp->sb_id = fp->cl_id;
+
+ bnx2x_init_sb(bp, bp->cnic_sb_mapping,
+ BNX2X_VF_ID_INVALID, false,
+ CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp));
+
#endif
- DP(NETIF_MSG_IFUP,
- "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d sb %d\n",
- i, bp, fp->status_blk, fp->cl_id, fp->sb_id);
- bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping,
- fp->sb_id);
- bnx2x_update_fpsb_idx(fp);
- }
/* ensure status block indices were read */
rmb();
-
- bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping,
- DEF_SB_ID);
+ bnx2x_init_def_sb(bp);
bnx2x_update_dsb_idx(bp);
- bnx2x_update_coalesce(bp);
bnx2x_init_rx_rings(bp);
- bnx2x_init_tx_ring(bp);
+ bnx2x_init_tx_rings(bp);
bnx2x_init_sp_ring(bp);
- bnx2x_init_context(bp);
+ bnx2x_init_eq_ring(bp);
bnx2x_init_internal(bp, load_code);
+ bnx2x_pf_init(bp);
bnx2x_init_ind_table(bp);
bnx2x_stats_init(bp);
@@ -3495,7 +4386,6 @@ gunzip_nomem1:
static void bnx2x_gunzip_end(struct bnx2x *bp)
{
kfree(bp->strm->workspace);
-
kfree(bp->strm);
bp->strm = NULL;
@@ -3593,8 +4483,6 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
else
factor = 1;
- DP(NETIF_MSG_HW, "start part1\n");
-
/* Disable inputs of parser neighbor blocks */
REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
@@ -3731,9 +4619,19 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
static void enable_blocks_attention(struct bnx2x *bp)
{
REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
- REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0);
+ if (CHIP_IS_E2(bp))
+ REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0x40);
+ else
+ REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0);
REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
+ /*
+ * mask read length error interrupts in brb for parser
+ * (parsing unit and 'checksum and crc' unit)
+ * these errors are legal (PU reads fixed length and CAC can cause
+ * read length error on truncated packets)
+ */
+ REG_WR(bp, BRB1_REG_BRB1_INT_MASK, 0xFC00);
REG_WR(bp, QM_REG_QM_INT_MASK, 0);
REG_WR(bp, TM_REG_TM_INT_MASK, 0);
REG_WR(bp, XSDM_REG_XSDM_INT_MASK_0, 0);
@@ -3752,8 +4650,16 @@ static void enable_blocks_attention(struct bnx2x *bp)
REG_WR(bp, CCM_REG_CCM_INT_MASK, 0);
/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_0, 0); */
/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */
+
if (CHIP_REV_IS_FPGA(bp))
REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000);
+ else if (CHIP_IS_E2(bp))
+ REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0,
+ (PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_OF
+ | PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_AFT
+ | PXP2_PXP2_INT_MASK_0_REG_PGL_PCIE_ATTN
+ | PXP2_PXP2_INT_MASK_0_REG_PGL_READ_BLOCKED
+ | PXP2_PXP2_INT_MASK_0_REG_PGL_WRITE_BLOCKED));
else
REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x480000);
REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0);
@@ -3771,42 +4677,41 @@ static const struct {
u32 addr;
u32 mask;
} bnx2x_parity_mask[] = {
- {PXP_REG_PXP_PRTY_MASK, 0xffffffff},
- {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff},
- {PXP2_REG_PXP2_PRTY_MASK_1, 0xffffffff},
- {HC_REG_HC_PRTY_MASK, 0xffffffff},
- {MISC_REG_MISC_PRTY_MASK, 0xffffffff},
- {QM_REG_QM_PRTY_MASK, 0x0},
- {DORQ_REG_DORQ_PRTY_MASK, 0x0},
+ {PXP_REG_PXP_PRTY_MASK, 0x3ffffff},
+ {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff},
+ {PXP2_REG_PXP2_PRTY_MASK_1, 0x7f},
+ {HC_REG_HC_PRTY_MASK, 0x7},
+ {MISC_REG_MISC_PRTY_MASK, 0x1},
+ {QM_REG_QM_PRTY_MASK, 0x0},
+ {DORQ_REG_DORQ_PRTY_MASK, 0x0},
{GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 0x0},
{GRCBASE_XPB + PB_REG_PB_PRTY_MASK, 0x0},
- {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */
- {CDU_REG_CDU_PRTY_MASK, 0x0},
- {CFC_REG_CFC_PRTY_MASK, 0x0},
- {DBG_REG_DBG_PRTY_MASK, 0x0},
- {DMAE_REG_DMAE_PRTY_MASK, 0x0},
- {BRB1_REG_BRB1_PRTY_MASK, 0x0},
- {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */
- {TSDM_REG_TSDM_PRTY_MASK, 0x18},/* bit 3,4 */
- {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */
- {USDM_REG_USDM_PRTY_MASK, 0x38},/* bit 3,4,5 */
- {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */
- {TSEM_REG_TSEM_PRTY_MASK_0, 0x0},
- {TSEM_REG_TSEM_PRTY_MASK_1, 0x0},
- {USEM_REG_USEM_PRTY_MASK_0, 0x0},
- {USEM_REG_USEM_PRTY_MASK_1, 0x0},
- {CSEM_REG_CSEM_PRTY_MASK_0, 0x0},
- {CSEM_REG_CSEM_PRTY_MASK_1, 0x0},
- {XSEM_REG_XSEM_PRTY_MASK_0, 0x0},
- {XSEM_REG_XSEM_PRTY_MASK_1, 0x0}
+ {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */
+ {CDU_REG_CDU_PRTY_MASK, 0x0},
+ {CFC_REG_CFC_PRTY_MASK, 0x0},
+ {DBG_REG_DBG_PRTY_MASK, 0x0},
+ {DMAE_REG_DMAE_PRTY_MASK, 0x0},
+ {BRB1_REG_BRB1_PRTY_MASK, 0x0},
+ {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */
+ {TSDM_REG_TSDM_PRTY_MASK, 0x18}, /* bit 3,4 */
+ {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */
+ {USDM_REG_USDM_PRTY_MASK, 0x38}, /* bit 3,4,5 */
+ {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */
+ {TSEM_REG_TSEM_PRTY_MASK_0, 0x0},
+ {TSEM_REG_TSEM_PRTY_MASK_1, 0x0},
+ {USEM_REG_USEM_PRTY_MASK_0, 0x0},
+ {USEM_REG_USEM_PRTY_MASK_1, 0x0},
+ {CSEM_REG_CSEM_PRTY_MASK_0, 0x0},
+ {CSEM_REG_CSEM_PRTY_MASK_1, 0x0},
+ {XSEM_REG_XSEM_PRTY_MASK_0, 0x0},
+ {XSEM_REG_XSEM_PRTY_MASK_1, 0x0}
};
static void enable_blocks_parity(struct bnx2x *bp)
{
- int i, mask_arr_len =
- sizeof(bnx2x_parity_mask)/(sizeof(bnx2x_parity_mask[0]));
+ int i;
- for (i = 0; i < mask_arr_len; i++)
+ for (i = 0; i < ARRAY_SIZE(bnx2x_parity_mask); i++)
REG_WR(bp, bnx2x_parity_mask[i].addr,
bnx2x_parity_mask[i].mask);
}
@@ -3862,17 +4767,12 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp)
*/
else if (val == SHARED_HW_CFG_FAN_FAILURE_PHY_TYPE)
for (port = PORT_0; port < PORT_MAX; port++) {
- u32 phy_type =
- SHMEM_RD(bp, dev_info.port_hw_config[port].
- external_phy_config) &
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
is_required |=
- ((phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) ||
- (phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
- (phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481));
+ bnx2x_fan_failure_det_req(
+ bp,
+ bp->common.shmem_base,
+ bp->common.shmem2_base,
+ port);
}
DP(NETIF_MSG_HW, "fan detection setting: %d\n", is_required);
@@ -3896,26 +4796,97 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp)
REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val);
}
-static int bnx2x_init_common(struct bnx2x *bp)
+static void bnx2x_pretend_func(struct bnx2x *bp, u8 pretend_func_num)
+{
+ u32 offset = 0;
+
+ if (CHIP_IS_E1(bp))
+ return;
+ if (CHIP_IS_E1H(bp) && (pretend_func_num >= E1H_FUNC_MAX))
+ return;
+
+ switch (BP_ABS_FUNC(bp)) {
+ case 0:
+ offset = PXP2_REG_PGL_PRETEND_FUNC_F0;
+ break;
+ case 1:
+ offset = PXP2_REG_PGL_PRETEND_FUNC_F1;
+ break;
+ case 2:
+ offset = PXP2_REG_PGL_PRETEND_FUNC_F2;
+ break;
+ case 3:
+ offset = PXP2_REG_PGL_PRETEND_FUNC_F3;
+ break;
+ case 4:
+ offset = PXP2_REG_PGL_PRETEND_FUNC_F4;
+ break;
+ case 5:
+ offset = PXP2_REG_PGL_PRETEND_FUNC_F5;
+ break;
+ case 6:
+ offset = PXP2_REG_PGL_PRETEND_FUNC_F6;
+ break;
+ case 7:
+ offset = PXP2_REG_PGL_PRETEND_FUNC_F7;
+ break;
+ default:
+ return;
+ }
+
+ REG_WR(bp, offset, pretend_func_num);
+ REG_RD(bp, offset);
+ DP(NETIF_MSG_HW, "Pretending to func %d\n", pretend_func_num);
+}
+
+static void bnx2x_pf_disable(struct bnx2x *bp)
+{
+ u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION);
+ val &= ~IGU_PF_CONF_FUNC_EN;
+
+ REG_WR(bp, IGU_REG_PF_CONFIGURATION, val);
+ REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 0);
+ REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 0);
+}
+
+static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code)
{
u32 val, i;
-#ifdef BCM_CNIC
- u32 wb_write[2];
-#endif
- DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp));
+ DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_ABS_FUNC(bp));
bnx2x_reset_common(bp);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE);
- if (CHIP_IS_E1H(bp))
- REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp));
+ if (!CHIP_IS_E1(bp))
+ REG_WR(bp, MISC_REG_E1HMF_MODE, IS_MF(bp));
- REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100);
- msleep(30);
- REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0);
+ if (CHIP_IS_E2(bp)) {
+ u8 fid;
+
+ /**
+ * 4-port mode or 2-port mode we need to turn of master-enable
+ * for everyone, after that, turn it back on for self.
+ * so, we disregard multi-function or not, and always disable
+ * for all functions on the given path, this means 0,2,4,6 for
+ * path 0 and 1,3,5,7 for path 1
+ */
+ for (fid = BP_PATH(bp); fid < E2_FUNC_MAX*2; fid += 2) {
+ if (fid == BP_ABS_FUNC(bp)) {
+ REG_WR(bp,
+ PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER,
+ 1);
+ continue;
+ }
+
+ bnx2x_pretend_func(bp, fid);
+ /* clear pf enable */
+ bnx2x_pf_disable(bp);
+ bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
+ }
+ }
bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE);
if (CHIP_IS_E1(bp)) {
@@ -3943,12 +4914,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1);
#endif
- REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2);
-#ifdef BCM_CNIC
- REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5);
- REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5);
- REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5);
-#endif
+ bnx2x_ilt_init_page_size(bp, INITOP_SET);
if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp))
REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x1);
@@ -3967,9 +4933,65 @@ static int bnx2x_init_common(struct bnx2x *bp)
return -EBUSY;
}
+ /* Timers bug workaround E2 only. We need to set the entire ILT to
+ * have entries with value "0" and valid bit on.
+ * This needs to be done by the first PF that is loaded in a path
+ * (i.e. common phase)
+ */
+ if (CHIP_IS_E2(bp)) {
+ struct ilt_client_info ilt_cli;
+ struct bnx2x_ilt ilt;
+ memset(&ilt_cli, 0, sizeof(struct ilt_client_info));
+ memset(&ilt, 0, sizeof(struct bnx2x_ilt));
+
+ /* initalize dummy TM client */
+ ilt_cli.start = 0;
+ ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1;
+ ilt_cli.client_num = ILT_CLIENT_TM;
+
+ /* Step 1: set zeroes to all ilt page entries with valid bit on
+ * Step 2: set the timers first/last ilt entry to point
+ * to the entire range to prevent ILT range error for 3rd/4th
+ * vnic (this code assumes existance of the vnic)
+ *
+ * both steps performed by call to bnx2x_ilt_client_init_op()
+ * with dummy TM client
+ *
+ * we must use pretend since PXP2_REG_RQ_##blk##_FIRST_ILT
+ * and his brother are split registers
+ */
+ bnx2x_pretend_func(bp, (BP_PATH(bp) + 6));
+ bnx2x_ilt_client_init_op_ilt(bp, &ilt, &ilt_cli, INITOP_CLEAR);
+ bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
+
+ REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN, BNX2X_PXP_DRAM_ALIGN);
+ REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN_RD, BNX2X_PXP_DRAM_ALIGN);
+ REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN_SEL, 1);
+ }
+
+
REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0);
REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0);
+ if (CHIP_IS_E2(bp)) {
+ int factor = CHIP_REV_IS_EMUL(bp) ? 1000 :
+ (CHIP_REV_IS_FPGA(bp) ? 400 : 0);
+ bnx2x_init_block(bp, PGLUE_B_BLOCK, COMMON_STAGE);
+
+ bnx2x_init_block(bp, ATC_BLOCK, COMMON_STAGE);
+
+ /* let the HW do it's magic ... */
+ do {
+ msleep(200);
+ val = REG_RD(bp, ATC_REG_ATC_INIT_DONE);
+ } while (factor-- && (val != 1));
+
+ if (val != 1) {
+ BNX2X_ERR("ATC_INIT failed\n");
+ return -EBUSY;
+ }
+ }
+
bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE);
/* clean the DMAE memory */
@@ -3988,20 +5010,12 @@ static int bnx2x_init_common(struct bnx2x *bp)
bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE);
-#ifdef BCM_CNIC
- wb_write[0] = 0;
- wb_write[1] = 0;
- for (i = 0; i < 64; i++) {
- REG_WR(bp, QM_REG_BASEADDR + i*4, 1024 * 4 * (i%16));
- bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, wb_write, 2);
+ if (CHIP_MODE_IS_4_PORT(bp))
+ bnx2x_init_block(bp, QM_4PORT_BLOCK, COMMON_STAGE);
+
+ /* QM queues pointers table */
+ bnx2x_qm_init_ptr_table(bp, bp->qm_cid_count, INITOP_SET);
- if (CHIP_IS_E1H(bp)) {
- REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, 1024*4*(i%16));
- bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8,
- wb_write, 2);
- }
- }
-#endif
/* soft reset pulse */
REG_WR(bp, QM_REG_SOFT_RESET, 1);
REG_WR(bp, QM_REG_SOFT_RESET, 0);
@@ -4011,21 +5025,35 @@ static int bnx2x_init_common(struct bnx2x *bp)
#endif
bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE);
- REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT);
+ REG_WR(bp, DORQ_REG_DPM_CID_OFST, BNX2X_DB_SHIFT);
+
if (!CHIP_REV_IS_SLOW(bp)) {
/* enable hw interrupt from doorbell Q */
REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
}
bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
+ if (CHIP_MODE_IS_4_PORT(bp)) {
+ REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD, 248);
+ REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD, 328);
+ }
+
bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
#ifndef BCM_CNIC
/* set NIC mode */
REG_WR(bp, PRS_REG_NIC_MODE, 1);
#endif
- if (CHIP_IS_E1H(bp))
- REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp));
+ if (!CHIP_IS_E1(bp))
+ REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp));
+
+ if (CHIP_IS_E2(bp)) {
+ /* Bit-map indicating which L2 hdrs may appear after the
+ basic Ethernet header */
+ int has_ovlan = IS_MF(bp);
+ REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6));
+ REG_WR(bp, PRS_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0));
+ }
bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE);
bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE);
@@ -4042,6 +5070,9 @@ static int bnx2x_init_common(struct bnx2x *bp)
bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE);
bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE);
+ if (CHIP_MODE_IS_4_PORT(bp))
+ bnx2x_init_block(bp, XSEM_4PORT_BLOCK, COMMON_STAGE);
+
/* sync semi rtc */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
0x80000000);
@@ -4052,9 +5083,16 @@ static int bnx2x_init_common(struct bnx2x *bp)
bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE);
bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE);
+ if (CHIP_IS_E2(bp)) {
+ int has_ovlan = IS_MF(bp);
+ REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6));
+ REG_WR(bp, PBF_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0));
+ }
+
REG_WR(bp, SRC_REG_SOFT_RST, 1);
for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4)
REG_WR(bp, i, random32());
+
bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE);
#ifdef BCM_CNIC
REG_WR(bp, SRC_REG_KEYSEARCH_0, 0x63285672);
@@ -4089,6 +5127,11 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, CFC_REG_DEBUG0, 0x20020000);
bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE);
+
+ if (CHIP_IS_E2(bp) && BP_NOMCP(bp))
+ REG_WR(bp, IGU_REG_RESET_MEMORIES, 0x36);
+
+ bnx2x_init_block(bp, IGU_BLOCK, COMMON_STAGE);
bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE);
bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE);
@@ -4096,15 +5139,34 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, 0x2814, 0xffffffff);
REG_WR(bp, 0x3820, 0xffffffff);
+ if (CHIP_IS_E2(bp)) {
+ REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_CONTROL_5,
+ (PXPCS_TL_CONTROL_5_ERR_UNSPPORT1 |
+ PXPCS_TL_CONTROL_5_ERR_UNSPPORT));
+ REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_FUNC345_STAT,
+ (PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT4 |
+ PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT3 |
+ PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT2));
+ REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_FUNC678_STAT,
+ (PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT7 |
+ PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT6 |
+ PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT5));
+ }
+
bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE);
bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE);
bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE);
bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE);
bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE);
- if (CHIP_IS_E1H(bp)) {
- REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp));
- REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp));
+ if (!CHIP_IS_E1(bp)) {
+ REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp));
+ REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF(bp));
+ }
+ if (CHIP_IS_E2(bp)) {
+ /* Bit-map indicating which L2 hdrs may appear after the
+ basic Ethernet header */
+ REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF(bp) ? 7 : 6));
}
if (CHIP_REV_IS_SLOW(bp))
@@ -4128,28 +5190,22 @@ static int bnx2x_init_common(struct bnx2x *bp)
}
REG_WR(bp, CFC_REG_DEBUG0, 0);
- /* read NIG statistic
- to see if this is our first up since powerup */
- bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
- val = *bnx2x_sp(bp, wb_data[0]);
+ if (CHIP_IS_E1(bp)) {
+ /* read NIG statistic
+ to see if this is our first up since powerup */
+ bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
+ val = *bnx2x_sp(bp, wb_data[0]);
- /* do internal memory self test */
- if ((CHIP_IS_E1(bp)) && (val == 0) && bnx2x_int_mem_test(bp)) {
- BNX2X_ERR("internal mem self test failed\n");
- return -EBUSY;
+ /* do internal memory self test */
+ if ((val == 0) && bnx2x_int_mem_test(bp)) {
+ BNX2X_ERR("internal mem self test failed\n");
+ return -EBUSY;
+ }
}
- switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- bp->port.need_hw_lock = 1;
- break;
-
- default:
- break;
- }
+ bp->port.need_hw_lock = bnx2x_hw_lock_required(bp,
+ bp->common.shmem_base,
+ bp->common.shmem2_base);
bnx2x_setup_fan_failure_detection(bp);
@@ -4161,16 +5217,30 @@ static int bnx2x_init_common(struct bnx2x *bp)
enable_blocks_parity(bp);
if (!BP_NOMCP(bp)) {
- bnx2x_acquire_phy_lock(bp);
- bnx2x_common_init_phy(bp, bp->common.shmem_base);
- bnx2x_release_phy_lock(bp);
+ /* In E2 2-PORT mode, same ext phy is used for the two paths */
+ if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) ||
+ CHIP_IS_E1x(bp)) {
+ u32 shmem_base[2], shmem2_base[2];
+ shmem_base[0] = bp->common.shmem_base;
+ shmem2_base[0] = bp->common.shmem2_base;
+ if (CHIP_IS_E2(bp)) {
+ shmem_base[1] =
+ SHMEM2_RD(bp, other_shmem_base_addr);
+ shmem2_base[1] =
+ SHMEM2_RD(bp, other_shmem2_base_addr);
+ }
+ bnx2x_acquire_phy_lock(bp);
+ bnx2x_common_init_phy(bp, shmem_base, shmem2_base,
+ bp->common.chip_id);
+ bnx2x_release_phy_lock(bp);
+ }
} else
BNX2X_ERR("Bootcode is missing - can not initialize link\n");
return 0;
}
-static int bnx2x_init_port(struct bnx2x *bp)
+static int bnx2x_init_hw_port(struct bnx2x *bp)
{
int port = BP_PORT(bp);
int init_stage = port ? PORT1_STAGE : PORT0_STAGE;
@@ -4184,14 +5254,23 @@ static int bnx2x_init_port(struct bnx2x *bp)
bnx2x_init_block(bp, PXP_BLOCK, init_stage);
bnx2x_init_block(bp, PXP2_BLOCK, init_stage);
+ /* Timers bug workaround: disables the pf_master bit in pglue at
+ * common phase, we need to enable it here before any dmae access are
+ * attempted. Therefore we manually added the enable-master to the
+ * port phase (it also happens in the function phase)
+ */
+ if (CHIP_IS_E2(bp))
+ REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1);
+
bnx2x_init_block(bp, TCM_BLOCK, init_stage);
bnx2x_init_block(bp, UCM_BLOCK, init_stage);
bnx2x_init_block(bp, CCM_BLOCK, init_stage);
bnx2x_init_block(bp, XCM_BLOCK, init_stage);
-#ifdef BCM_CNIC
- REG_WR(bp, QM_REG_CONNNUM_0 + port*4, 1024/16 - 1);
+ /* QM cid (connection) count */
+ bnx2x_qm_init_cid_count(bp, bp->qm_cid_count, INITOP_SET);
+#ifdef BCM_CNIC
bnx2x_init_block(bp, TIMERS_BLOCK, init_stage);
REG_WR(bp, TM_REG_LIN0_SCAN_TIME + port*4, 20);
REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + port*4, 31);
@@ -4199,29 +5278,41 @@ static int bnx2x_init_port(struct bnx2x *bp)
bnx2x_init_block(bp, DQ_BLOCK, init_stage);
- bnx2x_init_block(bp, BRB1_BLOCK, init_stage);
- if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) {
- /* no pause for emulation and FPGA */
- low = 0;
- high = 513;
- } else {
- if (IS_E1HMF(bp))
- low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246);
- else if (bp->dev->mtu > 4096) {
- if (bp->flags & ONE_PORT_FLAG)
- low = 160;
- else {
- val = bp->dev->mtu;
- /* (24*1024 + val*4)/256 */
- low = 96 + (val/64) + ((val % 64) ? 1 : 0);
- }
- } else
- low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160);
- high = low + 56; /* 14*1024/256 */
+ if (CHIP_MODE_IS_4_PORT(bp))
+ bnx2x_init_block(bp, QM_4PORT_BLOCK, init_stage);
+
+ if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) {
+ bnx2x_init_block(bp, BRB1_BLOCK, init_stage);
+ if (CHIP_REV_IS_SLOW(bp) && CHIP_IS_E1(bp)) {
+ /* no pause for emulation and FPGA */
+ low = 0;
+ high = 513;
+ } else {
+ if (IS_MF(bp))
+ low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246);
+ else if (bp->dev->mtu > 4096) {
+ if (bp->flags & ONE_PORT_FLAG)
+ low = 160;
+ else {
+ val = bp->dev->mtu;
+ /* (24*1024 + val*4)/256 */
+ low = 96 + (val/64) +
+ ((val % 64) ? 1 : 0);
+ }
+ } else
+ low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160);
+ high = low + 56; /* 14*1024/256 */
+ }
+ REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low);
+ REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high);
}
- REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low);
- REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high);
+ if (CHIP_MODE_IS_4_PORT(bp)) {
+ REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 + port*8, 248);
+ REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 + port*8, 328);
+ REG_WR(bp, (BP_PORT(bp) ? BRB1_REG_MAC_GUARANTIED_1 :
+ BRB1_REG_MAC_GUARANTIED_0), 40);
+ }
bnx2x_init_block(bp, PRS_BLOCK, init_stage);
@@ -4234,24 +5325,28 @@ static int bnx2x_init_port(struct bnx2x *bp)
bnx2x_init_block(bp, USEM_BLOCK, init_stage);
bnx2x_init_block(bp, CSEM_BLOCK, init_stage);
bnx2x_init_block(bp, XSEM_BLOCK, init_stage);
+ if (CHIP_MODE_IS_4_PORT(bp))
+ bnx2x_init_block(bp, XSEM_4PORT_BLOCK, init_stage);
bnx2x_init_block(bp, UPB_BLOCK, init_stage);
bnx2x_init_block(bp, XPB_BLOCK, init_stage);
bnx2x_init_block(bp, PBF_BLOCK, init_stage);
- /* configure PBF to work without PAUSE mtu 9000 */
- REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
+ if (!CHIP_IS_E2(bp)) {
+ /* configure PBF to work without PAUSE mtu 9000 */
+ REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
- /* update threshold */
- REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16));
- /* update init credit */
- REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22);
+ /* update threshold */
+ REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16));
+ /* update init credit */
+ REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22);
- /* probe changes */
- REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1);
- msleep(5);
- REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0);
+ /* probe changes */
+ REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1);
+ udelay(50);
+ REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0);
+ }
#ifdef BCM_CNIC
bnx2x_init_block(bp, SRCH_BLOCK, init_stage);
@@ -4265,13 +5360,15 @@ static int bnx2x_init_port(struct bnx2x *bp)
}
bnx2x_init_block(bp, HC_BLOCK, init_stage);
+ bnx2x_init_block(bp, IGU_BLOCK, init_stage);
+
bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage);
/* init aeu_mask_attn_func_0/1:
* - SF mode: bits 3-7 are masked. only bits 0-2 are in use
* - MF mode: bit 3 is masked. bits 0-2 are in use as in SF
* bits 4-7 are used for "per vn group attention" */
REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4,
- (IS_E1HMF(bp) ? 0xF7 : 0x7));
+ (IS_MF(bp) ? 0xF7 : 0x7));
bnx2x_init_block(bp, PXPCS_BLOCK, init_stage);
bnx2x_init_block(bp, EMAC0_BLOCK, init_stage);
@@ -4283,11 +5380,25 @@ static int bnx2x_init_port(struct bnx2x *bp)
REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
- if (CHIP_IS_E1H(bp)) {
- /* 0x2 disable e1hov, 0x1 enable */
+ if (!CHIP_IS_E1(bp)) {
+ /* 0x2 disable mf_ov, 0x1 enable */
REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4,
- (IS_E1HMF(bp) ? 0x1 : 0x2));
+ (IS_MF(bp) ? 0x1 : 0x2));
+
+ if (CHIP_IS_E2(bp)) {
+ val = 0;
+ switch (bp->mf_mode) {
+ case MULTI_FUNCTION_SD:
+ val = 1;
+ break;
+ case MULTI_FUNCTION_SI:
+ val = 2;
+ break;
+ }
+ REG_WR(bp, (BP_PORT(bp) ? NIG_REG_LLH1_CLS_TYPE :
+ NIG_REG_LLH0_CLS_TYPE), val);
+ }
{
REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0);
REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0);
@@ -4297,199 +5408,339 @@ static int bnx2x_init_port(struct bnx2x *bp)
bnx2x_init_block(bp, MCP_BLOCK, init_stage);
bnx2x_init_block(bp, DMAE_BLOCK, init_stage);
-
- switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- {
- u32 swap_val, swap_override, aeu_gpio_mask, offset;
-
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
- MISC_REGISTERS_GPIO_INPUT_HI_Z, port);
-
- /* The GPIO should be swapped if the swap register is
- set and active */
- swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
- swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
-
- /* Select function upon port-swap configuration */
- if (port == 0) {
- offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
- aeu_gpio_mask = (swap_val && swap_override) ?
- AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
- AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
- } else {
- offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
- aeu_gpio_mask = (swap_val && swap_override) ?
- AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
- AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
- }
- val = REG_RD(bp, offset);
- /* add GPIO3 to group */
- val |= aeu_gpio_mask;
- REG_WR(bp, offset, val);
- }
- bp->port.need_hw_lock = 1;
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- bp->port.need_hw_lock = 1;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- /* add SPIO 5 to group 0 */
- {
+ bp->port.need_hw_lock = bnx2x_hw_lock_required(bp,
+ bp->common.shmem_base,
+ bp->common.shmem2_base);
+ if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base,
+ bp->common.shmem2_base, port)) {
u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
val = REG_RD(bp, reg_addr);
val |= AEU_INPUTS_ATTN_BITS_SPIO5;
REG_WR(bp, reg_addr, val);
- }
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- bp->port.need_hw_lock = 1;
- break;
- default:
- break;
}
-
bnx2x__link_reset(bp);
return 0;
}
-#define ILT_PER_FUNC (768/2)
-#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC)
-/* the phys address is shifted right 12 bits and has an added
- 1=valid bit added to the 53rd bit
- then since this is a wide register(TM)
- we split it into two 32 bit writes
- */
-#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF))
-#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44)))
-#define PXP_ONE_ILT(x) (((x) << 10) | x)
-#define PXP_ILT_RANGE(f, l) (((l) << 10) | f)
-
-#ifdef BCM_CNIC
-#define CNIC_ILT_LINES 127
-#define CNIC_CTX_PER_ILT 16
-#else
-#define CNIC_ILT_LINES 0
-#endif
-
static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr)
{
int reg;
- if (CHIP_IS_E1H(bp))
- reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8;
- else /* E1 */
+ if (CHIP_IS_E1(bp))
reg = PXP2_REG_RQ_ONCHIP_AT + index*8;
+ else
+ reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8;
bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr));
}
-static int bnx2x_init_func(struct bnx2x *bp)
+static inline void bnx2x_igu_clear_sb(struct bnx2x *bp, u8 idu_sb_id)
+{
+ bnx2x_igu_clear_sb_gen(bp, idu_sb_id, true /*PF*/);
+}
+
+static inline void bnx2x_clear_func_ilt(struct bnx2x *bp, u32 func)
+{
+ u32 i, base = FUNC_ILT_BASE(func);
+ for (i = base; i < base + ILT_PER_FUNC; i++)
+ bnx2x_ilt_wr(bp, i, 0);
+}
+
+static int bnx2x_init_hw_func(struct bnx2x *bp)
{
int port = BP_PORT(bp);
int func = BP_FUNC(bp);
+ struct bnx2x_ilt *ilt = BP_ILT(bp);
+ u16 cdu_ilt_start;
u32 addr, val;
- int i;
+ u32 main_mem_base, main_mem_size, main_mem_prty_clr;
+ int i, main_mem_width;
DP(BNX2X_MSG_MCP, "starting func init func %d\n", func);
/* set MSI reconfigure capability */
- addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0);
- val = REG_RD(bp, addr);
- val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0;
- REG_WR(bp, addr, val);
+ if (bp->common.int_block == INT_BLOCK_HC) {
+ addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0);
+ val = REG_RD(bp, addr);
+ val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0;
+ REG_WR(bp, addr, val);
+ }
- i = FUNC_ILT_BASE(func);
+ ilt = BP_ILT(bp);
+ cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start;
- bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context));
- if (CHIP_IS_E1H(bp)) {
- REG_WR(bp, PXP2_REG_RQ_CDU_FIRST_ILT, i);
- REG_WR(bp, PXP2_REG_RQ_CDU_LAST_ILT, i + CNIC_ILT_LINES);
- } else /* E1 */
- REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4,
- PXP_ILT_RANGE(i, i + CNIC_ILT_LINES));
+ for (i = 0; i < L2_ILT_LINES(bp); i++) {
+ ilt->lines[cdu_ilt_start + i].page =
+ bp->context.vcxt + (ILT_PAGE_CIDS * i);
+ ilt->lines[cdu_ilt_start + i].page_mapping =
+ bp->context.cxt_mapping + (CDU_ILT_PAGE_SZ * i);
+ /* cdu ilt pages are allocated manually so there's no need to
+ set the size */
+ }
+ bnx2x_ilt_init_op(bp, INITOP_SET);
#ifdef BCM_CNIC
- i += 1 + CNIC_ILT_LINES;
- bnx2x_ilt_wr(bp, i, bp->timers_mapping);
- if (CHIP_IS_E1(bp))
- REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i));
- else {
- REG_WR(bp, PXP2_REG_RQ_TM_FIRST_ILT, i);
- REG_WR(bp, PXP2_REG_RQ_TM_LAST_ILT, i);
- }
+ bnx2x_src_init_t2(bp, bp->t2, bp->t2_mapping, SRC_CONN_NUM);
- i++;
- bnx2x_ilt_wr(bp, i, bp->qm_mapping);
- if (CHIP_IS_E1(bp))
- REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i));
- else {
- REG_WR(bp, PXP2_REG_RQ_QM_FIRST_ILT, i);
- REG_WR(bp, PXP2_REG_RQ_QM_LAST_ILT, i);
+ /* T1 hash bits value determines the T1 number of entries */
+ REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, SRC_HASH_BITS);
+#endif
+
+#ifndef BCM_CNIC
+ /* set NIC mode */
+ REG_WR(bp, PRS_REG_NIC_MODE, 1);
+#endif /* BCM_CNIC */
+
+ if (CHIP_IS_E2(bp)) {
+ u32 pf_conf = IGU_PF_CONF_FUNC_EN;
+
+ /* Turn on a single ISR mode in IGU if driver is going to use
+ * INT#x or MSI
+ */
+ if (!(bp->flags & USING_MSIX_FLAG))
+ pf_conf |= IGU_PF_CONF_SINGLE_ISR_EN;
+ /*
+ * Timers workaround bug: function init part.
+ * Need to wait 20msec after initializing ILT,
+ * needed to make sure there are no requests in
+ * one of the PXP internal queues with "old" ILT addresses
+ */
+ msleep(20);
+ /*
+ * Master enable - Due to WB DMAE writes performed before this
+ * register is re-initialized as part of the regular function
+ * init
+ */
+ REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1);
+ /* Enable the function in IGU */
+ REG_WR(bp, IGU_REG_PF_CONFIGURATION, pf_conf);
}
- i++;
- bnx2x_ilt_wr(bp, i, bp->t1_mapping);
- if (CHIP_IS_E1(bp))
- REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
- else {
- REG_WR(bp, PXP2_REG_RQ_SRC_FIRST_ILT, i);
- REG_WR(bp, PXP2_REG_RQ_SRC_LAST_ILT, i);
+ bp->dmae_ready = 1;
+
+ bnx2x_init_block(bp, PGLUE_B_BLOCK, FUNC0_STAGE + func);
+
+ if (CHIP_IS_E2(bp))
+ REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, func);
+
+ bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func);
+
+ if (CHIP_IS_E2(bp)) {
+ REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_PATH_ID_OFFSET,
+ BP_PATH(bp));
+ REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_PATH_ID_OFFSET,
+ BP_PATH(bp));
}
- /* tell the searcher where the T2 table is */
- REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, 16*1024/64);
+ if (CHIP_MODE_IS_4_PORT(bp))
+ bnx2x_init_block(bp, XSEM_4PORT_BLOCK, FUNC0_STAGE + func);
- bnx2x_wb_wr(bp, SRC_REG_FIRSTFREE0 + port*16,
- U64_LO(bp->t2_mapping), U64_HI(bp->t2_mapping));
+ if (CHIP_IS_E2(bp))
+ REG_WR(bp, QM_REG_PF_EN, 1);
- bnx2x_wb_wr(bp, SRC_REG_LASTFREE0 + port*16,
- U64_LO((u64)bp->t2_mapping + 16*1024 - 64),
- U64_HI((u64)bp->t2_mapping + 16*1024 - 64));
+ bnx2x_init_block(bp, QM_BLOCK, FUNC0_STAGE + func);
- REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, 10);
-#endif
+ if (CHIP_MODE_IS_4_PORT(bp))
+ bnx2x_init_block(bp, QM_4PORT_BLOCK, FUNC0_STAGE + func);
+
+ bnx2x_init_block(bp, TIMERS_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, DQ_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, BRB1_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, PRS_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, TSDM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, CSDM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, USDM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, XSDM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, UPB_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, XPB_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, PBF_BLOCK, FUNC0_STAGE + func);
+ if (CHIP_IS_E2(bp))
+ REG_WR(bp, PBF_REG_DISABLE_PF, 0);
+
+ bnx2x_init_block(bp, CDU_BLOCK, FUNC0_STAGE + func);
- if (CHIP_IS_E1H(bp)) {
- bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func);
- bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func);
- bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func);
- bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func);
- bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func);
- bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func);
- bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func);
- bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func);
- bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, CFC_BLOCK, FUNC0_STAGE + func);
+ if (CHIP_IS_E2(bp))
+ REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 1);
+
+ if (IS_MF(bp)) {
REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
- REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
+ REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->mf_ov);
}
+ bnx2x_init_block(bp, MISC_AEU_BLOCK, FUNC0_STAGE + func);
+
/* HC init per function */
- if (CHIP_IS_E1H(bp)) {
+ if (bp->common.int_block == INT_BLOCK_HC) {
+ if (CHIP_IS_E1H(bp)) {
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
+
+ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
+ REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
+ }
+ bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func);
+
+ } else {
+ int num_segs, sb_idx, prod_offset;
+
REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
- REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
- REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
+ if (CHIP_IS_E2(bp)) {
+ REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, 0);
+ REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0);
+ }
+
+ bnx2x_init_block(bp, IGU_BLOCK, FUNC0_STAGE + func);
+
+ if (CHIP_IS_E2(bp)) {
+ int dsb_idx = 0;
+ /**
+ * Producer memory:
+ * E2 mode: address 0-135 match to the mapping memory;
+ * 136 - PF0 default prod; 137 - PF1 default prod;
+ * 138 - PF2 default prod; 139 - PF3 default prod;
+ * 140 - PF0 attn prod; 141 - PF1 attn prod;
+ * 142 - PF2 attn prod; 143 - PF3 attn prod;
+ * 144-147 reserved.
+ *
+ * E1.5 mode - In backward compatible mode;
+ * for non default SB; each even line in the memory
+ * holds the U producer and each odd line hold
+ * the C producer. The first 128 producers are for
+ * NDSB (PF0 - 0-31; PF1 - 32-63 and so on). The last 20
+ * producers are for the DSB for each PF.
+ * Each PF has five segments: (the order inside each
+ * segment is PF0; PF1; PF2; PF3) - 128-131 U prods;
+ * 132-135 C prods; 136-139 X prods; 140-143 T prods;
+ * 144-147 attn prods;
+ */
+ /* non-default-status-blocks */
+ num_segs = CHIP_INT_MODE_IS_BC(bp) ?
+ IGU_BC_NDSB_NUM_SEGS : IGU_NORM_NDSB_NUM_SEGS;
+ for (sb_idx = 0; sb_idx < bp->igu_sb_cnt; sb_idx++) {
+ prod_offset = (bp->igu_base_sb + sb_idx) *
+ num_segs;
+
+ for (i = 0; i < num_segs; i++) {
+ addr = IGU_REG_PROD_CONS_MEMORY +
+ (prod_offset + i) * 4;
+ REG_WR(bp, addr, 0);
+ }
+ /* send consumer update with value 0 */
+ bnx2x_ack_sb(bp, bp->igu_base_sb + sb_idx,
+ USTORM_ID, 0, IGU_INT_NOP, 1);
+ bnx2x_igu_clear_sb(bp,
+ bp->igu_base_sb + sb_idx);
+ }
+
+ /* default-status-blocks */
+ num_segs = CHIP_INT_MODE_IS_BC(bp) ?
+ IGU_BC_DSB_NUM_SEGS : IGU_NORM_DSB_NUM_SEGS;
+
+ if (CHIP_MODE_IS_4_PORT(bp))
+ dsb_idx = BP_FUNC(bp);
+ else
+ dsb_idx = BP_E1HVN(bp);
+
+ prod_offset = (CHIP_INT_MODE_IS_BC(bp) ?
+ IGU_BC_BASE_DSB_PROD + dsb_idx :
+ IGU_NORM_BASE_DSB_PROD + dsb_idx);
+
+ for (i = 0; i < (num_segs * E1HVN_MAX);
+ i += E1HVN_MAX) {
+ addr = IGU_REG_PROD_CONS_MEMORY +
+ (prod_offset + i)*4;
+ REG_WR(bp, addr, 0);
+ }
+ /* send consumer update with 0 */
+ if (CHIP_INT_MODE_IS_BC(bp)) {
+ bnx2x_ack_sb(bp, bp->igu_dsb_id,
+ USTORM_ID, 0, IGU_INT_NOP, 1);
+ bnx2x_ack_sb(bp, bp->igu_dsb_id,
+ CSTORM_ID, 0, IGU_INT_NOP, 1);
+ bnx2x_ack_sb(bp, bp->igu_dsb_id,
+ XSTORM_ID, 0, IGU_INT_NOP, 1);
+ bnx2x_ack_sb(bp, bp->igu_dsb_id,
+ TSTORM_ID, 0, IGU_INT_NOP, 1);
+ bnx2x_ack_sb(bp, bp->igu_dsb_id,
+ ATTENTION_ID, 0, IGU_INT_NOP, 1);
+ } else {
+ bnx2x_ack_sb(bp, bp->igu_dsb_id,
+ USTORM_ID, 0, IGU_INT_NOP, 1);
+ bnx2x_ack_sb(bp, bp->igu_dsb_id,
+ ATTENTION_ID, 0, IGU_INT_NOP, 1);
+ }
+ bnx2x_igu_clear_sb(bp, bp->igu_dsb_id);
+
+ /* !!! these should become driver const once
+ rf-tool supports split-68 const */
+ REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_LSB, 0);
+ REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_MSB, 0);
+ REG_WR(bp, IGU_REG_SB_MASK_LSB, 0);
+ REG_WR(bp, IGU_REG_SB_MASK_MSB, 0);
+ REG_WR(bp, IGU_REG_PBA_STATUS_LSB, 0);
+ REG_WR(bp, IGU_REG_PBA_STATUS_MSB, 0);
+ }
}
- bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func);
/* Reset PCIE errors for debug */
REG_WR(bp, 0x2114, 0xffffffff);
REG_WR(bp, 0x2120, 0xffffffff);
+ bnx2x_init_block(bp, EMAC0_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, EMAC1_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, DBU_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, DBG_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, MCP_BLOCK, FUNC0_STAGE + func);
+ bnx2x_init_block(bp, DMAE_BLOCK, FUNC0_STAGE + func);
+
+ if (CHIP_IS_E1x(bp)) {
+ main_mem_size = HC_REG_MAIN_MEMORY_SIZE / 2; /*dwords*/
+ main_mem_base = HC_REG_MAIN_MEMORY +
+ BP_PORT(bp) * (main_mem_size * 4);
+ main_mem_prty_clr = HC_REG_HC_PRTY_STS_CLR;
+ main_mem_width = 8;
+
+ val = REG_RD(bp, main_mem_prty_clr);
+ if (val)
+ DP(BNX2X_MSG_MCP, "Hmmm... Parity errors in HC "
+ "block during "
+ "function init (0x%x)!\n", val);
+
+ /* Clear "false" parity errors in MSI-X table */
+ for (i = main_mem_base;
+ i < main_mem_base + main_mem_size * 4;
+ i += main_mem_width) {
+ bnx2x_read_dmae(bp, i, main_mem_width / 4);
+ bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data),
+ i, main_mem_width / 4);
+ }
+ /* Clear HC parity attention */
+ REG_RD(bp, main_mem_prty_clr);
+ }
+
+ bnx2x_phy_probe(&bp->link_params);
+
return 0;
}
int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
{
- int i, rc = 0;
+ int rc = 0;
DP(BNX2X_MSG_MCP, "function %d load_code %x\n",
- BP_FUNC(bp), load_code);
+ BP_ABS_FUNC(bp), load_code);
bp->dmae_ready = 0;
mutex_init(&bp->dmae_mutex);
@@ -4499,21 +5750,20 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
switch (load_code) {
case FW_MSG_CODE_DRV_LOAD_COMMON:
- rc = bnx2x_init_common(bp);
+ case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP:
+ rc = bnx2x_init_hw_common(bp, load_code);
if (rc)
goto init_hw_err;
/* no break */
case FW_MSG_CODE_DRV_LOAD_PORT:
- bp->dmae_ready = 1;
- rc = bnx2x_init_port(bp);
+ rc = bnx2x_init_hw_port(bp);
if (rc)
goto init_hw_err;
/* no break */
case FW_MSG_CODE_DRV_LOAD_FUNCTION:
- bp->dmae_ready = 1;
- rc = bnx2x_init_func(bp);
+ rc = bnx2x_init_hw_func(bp);
if (rc)
goto init_hw_err;
break;
@@ -4524,22 +5774,14 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
}
if (!BP_NOMCP(bp)) {
- int func = BP_FUNC(bp);
+ int mb_idx = BP_FW_MB_IDX(bp);
bp->fw_drv_pulse_wr_seq =
- (SHMEM_RD(bp, func_mb[func].drv_pulse_mb) &
+ (SHMEM_RD(bp, func_mb[mb_idx].drv_pulse_mb) &
DRV_PULSE_SEQ_MASK);
DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq);
}
- /* this needs to be done before gunzip end */
- bnx2x_zero_def_sb(bp);
- for_each_queue(bp, i)
- bnx2x_zero_sb(bp, BP_L_ID(bp) + i);
-#ifdef BCM_CNIC
- bnx2x_zero_sb(bp, BP_L_ID(bp) + i);
-#endif
-
init_hw_err:
bnx2x_gunzip_end(bp);
@@ -4552,7 +5794,7 @@ void bnx2x_free_mem(struct bnx2x *bp)
#define BNX2X_PCI_FREE(x, y, size) \
do { \
if (x) { \
- dma_free_coherent(&bp->pdev->dev, size, x, y); \
+ dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \
x = NULL; \
y = 0; \
} \
@@ -4561,7 +5803,7 @@ void bnx2x_free_mem(struct bnx2x *bp)
#define BNX2X_FREE(x) \
do { \
if (x) { \
- vfree(x); \
+ kfree((void *)x); \
x = NULL; \
} \
} while (0)
@@ -4571,11 +5813,15 @@ void bnx2x_free_mem(struct bnx2x *bp)
/* fastpath */
/* Common */
for_each_queue(bp, i) {
-
/* status blocks */
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk),
- bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_status_block));
+ 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));
}
/* Rx */
for_each_queue(bp, i) {
@@ -4609,28 +5855,56 @@ void bnx2x_free_mem(struct bnx2x *bp)
/* end of fastpath */
BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
- sizeof(struct host_def_status_block));
+ sizeof(struct host_sp_status_block));
BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping,
sizeof(struct bnx2x_slowpath));
+ BNX2X_PCI_FREE(bp->context.vcxt, bp->context.cxt_mapping,
+ bp->context.size);
+
+ bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE);
+
+ BNX2X_FREE(bp->ilt->lines);
+
#ifdef BCM_CNIC
- BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024);
- BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024);
- BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024);
- BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024);
- BNX2X_PCI_FREE(bp->cnic_sb, bp->cnic_sb_mapping,
- sizeof(struct host_status_block));
+ if (CHIP_IS_E2(bp))
+ BNX2X_PCI_FREE(bp->cnic_sb.e2_sb, bp->cnic_sb_mapping,
+ sizeof(struct host_hc_status_block_e2));
+ else
+ BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping,
+ sizeof(struct host_hc_status_block_e1x));
+
+ BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, SRC_T2_SZ);
#endif
+
BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE);
+ BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping,
+ BCM_PAGE_SIZE * NUM_EQ_PAGES);
+
#undef BNX2X_PCI_FREE
#undef BNX2X_KFREE
}
-int bnx2x_alloc_mem(struct bnx2x *bp)
+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); \
@@ -4641,10 +5915,9 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
#define BNX2X_ALLOC(x, size) \
do { \
- x = vmalloc(size); \
+ x = kzalloc(size, GFP_KERNEL); \
if (x == NULL) \
goto alloc_mem_err; \
- memset(x, 0, size); \
} while (0)
int i;
@@ -4652,12 +5925,19 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
/* 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 */
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk),
+ 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_status_block));
+ sizeof(struct host_hc_status_block_e1x));
+
+ set_sb_shortcuts(bp, i);
}
/* Rx */
for_each_queue(bp, i) {
@@ -4693,37 +5973,41 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
}
/* end of fastpath */
+#ifdef BCM_CNIC
+ if (CHIP_IS_E2(bp))
+ BNX2X_PCI_ALLOC(bp->cnic_sb.e2_sb, &bp->cnic_sb_mapping,
+ sizeof(struct host_hc_status_block_e2));
+ else
+ BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, &bp->cnic_sb_mapping,
+ sizeof(struct host_hc_status_block_e1x));
+
+ /* allocate searcher T2 table */
+ BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ);
+#endif
+
+
BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping,
- sizeof(struct host_def_status_block));
+ sizeof(struct host_sp_status_block));
BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping,
sizeof(struct bnx2x_slowpath));
-#ifdef BCM_CNIC
- BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024);
-
- /* allocate searcher T2 table
- we allocate 1/4 of alloc num for T2
- (which is not entered into the ILT) */
- BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024);
-
- /* Initialize T2 (for 1024 connections) */
- for (i = 0; i < 16*1024; i += 64)
- *(u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64;
+ bp->context.size = sizeof(union cdu_context) * bp->l2_cid_count;
- /* Timer block array (8*MAX_CONN) phys uncached for now 1024 conns */
- BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024);
+ BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping,
+ bp->context.size);
- /* QM queues (128*MAX_CONN) */
- BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024);
+ BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES);
- BNX2X_PCI_ALLOC(bp->cnic_sb, &bp->cnic_sb_mapping,
- sizeof(struct host_status_block));
-#endif
+ if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC))
+ goto alloc_mem_err;
/* Slow path ring */
BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE);
+ /* EQ */
+ BNX2X_PCI_ALLOC(bp->eq_ring, &bp->eq_mapping,
+ BCM_PAGE_SIZE * NUM_EQ_PAGES);
return 0;
alloc_mem_err:
@@ -4734,97 +6018,47 @@ alloc_mem_err:
#undef BNX2X_ALLOC
}
-
/*
* Init service functions
*/
-
-/**
- * Sets a MAC in a CAM for a few L2 Clients for E1 chip
- *
- * @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 with_bcast set broadcast MAC as well
- */
-static void bnx2x_set_mac_addr_e1_gen(struct bnx2x *bp, int set, u8 *mac,
- u32 cl_bit_vec, u8 cam_offset,
- u8 with_bcast)
+int bnx2x_func_start(struct bnx2x *bp)
{
- struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
- int port = BP_PORT(bp);
-
- /* CAM allocation
- * unicasts 0-31:port0 32-63:port1
- * multicast 64-127:port0 128-191:port1
- */
- config->hdr.length = 1 + (with_bcast ? 1 : 0);
- config->hdr.offset = cam_offset;
- config->hdr.client_id = 0xff;
- config->hdr.reserved1 = 0;
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, 0, 0, 1);
- /* primary MAC */
- config->config_table[0].cam_entry.msb_mac_addr =
- swab16(*(u16 *)&mac[0]);
- config->config_table[0].cam_entry.middle_mac_addr =
- swab16(*(u16 *)&mac[2]);
- config->config_table[0].cam_entry.lsb_mac_addr =
- swab16(*(u16 *)&mac[4]);
- config->config_table[0].cam_entry.flags = cpu_to_le16(port);
- if (set)
- config->config_table[0].target_table_entry.flags = 0;
- else
- CAM_INVALIDATE(config->config_table[0]);
- config->config_table[0].target_table_entry.clients_bit_vector =
- cpu_to_le32(cl_bit_vec);
- config->config_table[0].target_table_entry.vlan_id = 0;
+ /* Wait for completion */
+ return bnx2x_wait_ramrod(bp, BNX2X_STATE_FUNC_STARTED, 0, &(bp->state),
+ WAIT_RAMROD_COMMON);
+}
- DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n",
- (set ? "setting" : "clearing"),
- config->config_table[0].cam_entry.msb_mac_addr,
- config->config_table[0].cam_entry.middle_mac_addr,
- config->config_table[0].cam_entry.lsb_mac_addr);
-
- /* broadcast */
- if (with_bcast) {
- config->config_table[1].cam_entry.msb_mac_addr =
- cpu_to_le16(0xffff);
- config->config_table[1].cam_entry.middle_mac_addr =
- cpu_to_le16(0xffff);
- config->config_table[1].cam_entry.lsb_mac_addr =
- cpu_to_le16(0xffff);
- config->config_table[1].cam_entry.flags = cpu_to_le16(port);
- if (set)
- config->config_table[1].target_table_entry.flags =
- TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
- else
- CAM_INVALIDATE(config->config_table[1]);
- config->config_table[1].target_table_entry.clients_bit_vector =
- cpu_to_le32(cl_bit_vec);
- config->config_table[1].target_table_entry.vlan_id = 0;
- }
+int bnx2x_func_stop(struct bnx2x *bp)
+{
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_STOP, 0, 0, 0, 1);
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
- U64_HI(bnx2x_sp_mapping(bp, mac_config)),
- U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
+ /* Wait for completion */
+ return bnx2x_wait_ramrod(bp, BNX2X_STATE_CLOSING_WAIT4_UNLOAD,
+ 0, &(bp->state), WAIT_RAMROD_COMMON);
}
/**
- * Sets a MAC in a CAM for a few L2 Clients for E1H chip
+ * Sets 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)
*/
-static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac,
- u32 cl_bit_vec, u8 cam_offset)
+static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac,
+ u32 cl_bit_vec, u8 cam_offset,
+ u8 is_bcast)
{
- struct mac_configuration_cmd_e1h *config =
- (struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config);
+ struct mac_configuration_cmd *config =
+ (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config);
+ int ramrod_flags = WAIT_RAMROD_COMMON;
+
+ bp->set_mac_pending = 1;
+ smp_wmb();
config->hdr.length = 1;
config->hdr.offset = cam_offset;
@@ -4841,29 +6075,41 @@ static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac,
config->config_table[0].clients_bit_vector =
cpu_to_le32(cl_bit_vec);
config->config_table[0].vlan_id = 0;
- config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov);
+ config->config_table[0].pf_id = BP_FUNC(bp);
if (set)
- config->config_table[0].flags = BP_PORT(bp);
+ SET_FLAG(config->config_table[0].flags,
+ MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+ T_ETH_MAC_COMMAND_SET);
else
- config->config_table[0].flags =
- MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE;
+ SET_FLAG(config->config_table[0].flags,
+ MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+ T_ETH_MAC_COMMAND_INVALIDATE);
+
+ if (is_bcast)
+ SET_FLAG(config->config_table[0].flags,
+ MAC_CONFIGURATION_ENTRY_BROADCAST, 1);
- DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) E1HOV %d CLID mask %d\n",
+ DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) PF_ID %d CLID mask %d\n",
(set ? "setting" : "clearing"),
config->config_table[0].msb_mac_addr,
config->config_table[0].middle_mac_addr,
- config->config_table[0].lsb_mac_addr, bp->e1hov, cl_bit_vec);
+ config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec);
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
U64_HI(bnx2x_sp_mapping(bp, mac_config)),
- U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
+ U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1);
+
+ /* Wait for a completion */
+ bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags);
}
-static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
- int *state_p, int poll)
+int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
+ int *state_p, int flags)
{
/* can take a while if any port is running */
int cnt = 5000;
+ u8 poll = flags & WAIT_RAMROD_POLL;
+ u8 common = flags & WAIT_RAMROD_COMMON;
DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
poll ? "polling" : "waiting", state, idx);
@@ -4871,13 +6117,17 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
might_sleep();
while (cnt--) {
if (poll) {
- bnx2x_rx_int(bp->fp, 10);
- /* if index is different from 0
- * the reply for some commands will
- * be on the non default queue
- */
- if (idx)
- bnx2x_rx_int(&bp->fp[idx], 10);
+ if (common)
+ bnx2x_eq_int(bp);
+ else {
+ bnx2x_rx_int(bp->fp, 10);
+ /* if index is different from 0
+ * the reply for some commands will
+ * be on the non default queue
+ */
+ if (idx)
+ bnx2x_rx_int(&bp->fp[idx], 10);
+ }
}
mb(); /* state is changed by bnx2x_sp_event() */
@@ -4904,29 +6154,112 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
return -EBUSY;
}
-void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set)
+u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset)
{
- bp->set_mac_pending++;
- smp_wmb();
+ if (CHIP_IS_E1H(bp))
+ return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp);
+ else if (CHIP_MODE_IS_4_PORT(bp))
+ return BP_FUNC(bp) * 32 + rel_offset;
+ else
+ return BP_VN(bp) * 32 + rel_offset;
+}
- bnx2x_set_mac_addr_e1h_gen(bp, set, bp->dev->dev_addr,
- (1 << bp->fp->cl_id), BP_FUNC(bp));
+void bnx2x_set_eth_mac(struct bnx2x *bp, int set)
+{
+ u8 cam_offset = (CHIP_IS_E1(bp) ? (BP_PORT(bp) ? 32 : 0) :
+ bnx2x_e1h_cam_offset(bp, CAM_ETH_LINE));
- /* Wait for a completion */
- bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1);
+ /* networking MAC */
+ bnx2x_set_mac_addr_gen(bp, set, bp->dev->dev_addr,
+ (1 << bp->fp->cl_id), cam_offset , 0);
+
+ if (CHIP_IS_E1(bp)) {
+ /* broadcast MAC */
+ u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1);
+ }
}
+static void bnx2x_set_e1_mc_list(struct bnx2x *bp, u8 offset)
+{
+ int i = 0, old;
+ struct net_device *dev = bp->dev;
+ struct netdev_hw_addr *ha;
+ struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config);
+ dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config);
+
+ netdev_for_each_mc_addr(ha, dev) {
+ /* copy mac */
+ config_cmd->config_table[i].msb_mac_addr =
+ swab16(*(u16 *)&bnx2x_mc_addr(ha)[0]);
+ config_cmd->config_table[i].middle_mac_addr =
+ swab16(*(u16 *)&bnx2x_mc_addr(ha)[2]);
+ config_cmd->config_table[i].lsb_mac_addr =
+ swab16(*(u16 *)&bnx2x_mc_addr(ha)[4]);
+
+ config_cmd->config_table[i].vlan_id = 0;
+ config_cmd->config_table[i].pf_id = BP_FUNC(bp);
+ config_cmd->config_table[i].clients_bit_vector =
+ cpu_to_le32(1 << BP_L_ID(bp));
-void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set)
+ SET_FLAG(config_cmd->config_table[i].flags,
+ MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+ T_ETH_MAC_COMMAND_SET);
+
+ DP(NETIF_MSG_IFUP,
+ "setting MCAST[%d] (%04x:%04x:%04x)\n", i,
+ config_cmd->config_table[i].msb_mac_addr,
+ config_cmd->config_table[i].middle_mac_addr,
+ config_cmd->config_table[i].lsb_mac_addr);
+ i++;
+ }
+ old = config_cmd->hdr.length;
+ if (old > i) {
+ for (; i < old; i++) {
+ if (CAM_IS_INVALID(config_cmd->
+ config_table[i])) {
+ /* already invalidated */
+ break;
+ }
+ /* invalidate */
+ SET_FLAG(config_cmd->config_table[i].flags,
+ MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+ T_ETH_MAC_COMMAND_INVALIDATE);
+ }
+ }
+
+ config_cmd->hdr.length = i;
+ config_cmd->hdr.offset = offset;
+ config_cmd->hdr.client_id = 0xff;
+ config_cmd->hdr.reserved1 = 0;
+
+ bp->set_mac_pending = 1;
+ smp_wmb();
+
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
+ U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1);
+}
+static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp)
{
- bp->set_mac_pending++;
+ int i;
+ struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config);
+ dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config);
+ int ramrod_flags = WAIT_RAMROD_COMMON;
+
+ bp->set_mac_pending = 1;
smp_wmb();
- bnx2x_set_mac_addr_e1_gen(bp, set, bp->dev->dev_addr,
- (1 << bp->fp->cl_id), (BP_PORT(bp) ? 32 : 0),
- 1);
+ for (i = 0; i < config_cmd->hdr.length; i++)
+ SET_FLAG(config_cmd->config_table[i].flags,
+ MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+ T_ETH_MAC_COMMAND_INVALIDATE);
+
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
+ U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1);
/* Wait for a completion */
- bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1);
+ bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending,
+ ramrod_flags);
+
}
#ifdef BCM_CNIC
@@ -4942,174 +6275,463 @@ void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set)
*/
int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set)
{
- u32 cl_bit_vec = (1 << BCM_ISCSI_ETH_CL_ID);
-
- bp->set_mac_pending++;
- smp_wmb();
+ u8 cam_offset = (CHIP_IS_E1(bp) ? ((BP_PORT(bp) ? 32 : 0) + 2) :
+ bnx2x_e1h_cam_offset(bp, CAM_ISCSI_ETH_LINE));
+ u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID;
+ u32 cl_bit_vec = (1 << iscsi_l2_cl_id);
/* Send a SET_MAC ramrod */
- if (CHIP_IS_E1(bp))
- bnx2x_set_mac_addr_e1_gen(bp, set, bp->iscsi_mac,
- cl_bit_vec, (BP_PORT(bp) ? 32 : 0) + 2,
- 1);
- else
- /* CAM allocation for E1H
- * unicasts: by func number
- * multicast: 20+FUNC*20, 20 each
- */
- bnx2x_set_mac_addr_e1h_gen(bp, set, bp->iscsi_mac,
- cl_bit_vec, E1H_FUNC_MAX + BP_FUNC(bp));
-
- /* Wait for a completion when setting */
- bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1);
-
+ bnx2x_set_mac_addr_gen(bp, set, bp->iscsi_mac, cl_bit_vec,
+ cam_offset, 0);
return 0;
}
#endif
-int bnx2x_setup_leading(struct bnx2x *bp)
-{
- int rc;
+static void bnx2x_fill_cl_init_data(struct bnx2x *bp,
+ struct bnx2x_client_init_params *params,
+ u8 activate,
+ struct client_init_ramrod_data *data)
+{
+ /* Clear the buffer */
+ memset(data, 0, sizeof(*data));
+
+ /* general */
+ data->general.client_id = params->rxq_params.cl_id;
+ data->general.statistics_counter_id = params->rxq_params.stat_id;
+ data->general.statistics_en_flg =
+ (params->rxq_params.flags & QUEUE_FLG_STATS) ? 1 : 0;
+ data->general.activate_flg = activate;
+ data->general.sp_client_id = params->rxq_params.spcl_id;
+
+ /* Rx data */
+ data->rx.tpa_en_flg =
+ (params->rxq_params.flags & QUEUE_FLG_TPA) ? 1 : 0;
+ data->rx.vmqueue_mode_en_flg = 0;
+ data->rx.cache_line_alignment_log_size =
+ params->rxq_params.cache_line_log;
+ data->rx.enable_dynamic_hc =
+ (params->rxq_params.flags & QUEUE_FLG_DHC) ? 1 : 0;
+ data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt;
+ data->rx.client_qzone_id = params->rxq_params.cl_qzone_id;
+ data->rx.max_agg_size = params->rxq_params.tpa_agg_sz;
+
+ /* We don't set drop flags */
+ data->rx.drop_ip_cs_err_flg = 0;
+ data->rx.drop_tcp_cs_err_flg = 0;
+ data->rx.drop_ttl0_flg = 0;
+ data->rx.drop_udp_cs_err_flg = 0;
+
+ data->rx.inner_vlan_removal_enable_flg =
+ (params->rxq_params.flags & QUEUE_FLG_VLAN) ? 1 : 0;
+ data->rx.outer_vlan_removal_enable_flg =
+ (params->rxq_params.flags & QUEUE_FLG_OV) ? 1 : 0;
+ data->rx.status_block_id = params->rxq_params.fw_sb_id;
+ data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index;
+ data->rx.bd_buff_size = cpu_to_le16(params->rxq_params.buf_sz);
+ data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz);
+ data->rx.mtu = cpu_to_le16(params->rxq_params.mtu);
+ data->rx.bd_page_base.lo =
+ cpu_to_le32(U64_LO(params->rxq_params.dscr_map));
+ data->rx.bd_page_base.hi =
+ cpu_to_le32(U64_HI(params->rxq_params.dscr_map));
+ data->rx.sge_page_base.lo =
+ cpu_to_le32(U64_LO(params->rxq_params.sge_map));
+ data->rx.sge_page_base.hi =
+ cpu_to_le32(U64_HI(params->rxq_params.sge_map));
+ data->rx.cqe_page_base.lo =
+ cpu_to_le32(U64_LO(params->rxq_params.rcq_map));
+ data->rx.cqe_page_base.hi =
+ cpu_to_le32(U64_HI(params->rxq_params.rcq_map));
+ data->rx.is_leading_rss =
+ (params->ramrod_params.flags & CLIENT_IS_LEADING_RSS) ? 1 : 0;
+ data->rx.is_approx_mcast = data->rx.is_leading_rss;
+
+ /* Tx data */
+ data->tx.enforce_security_flg = 0; /* VF specific */
+ data->tx.tx_status_block_id = params->txq_params.fw_sb_id;
+ data->tx.tx_sb_index_number = params->txq_params.sb_cq_index;
+ data->tx.mtu = 0; /* VF specific */
+ data->tx.tx_bd_page_base.lo =
+ cpu_to_le32(U64_LO(params->txq_params.dscr_map));
+ data->tx.tx_bd_page_base.hi =
+ cpu_to_le32(U64_HI(params->txq_params.dscr_map));
+
+ /* flow control data */
+ data->fc.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo);
+ data->fc.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi);
+ data->fc.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo);
+ data->fc.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi);
+ data->fc.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo);
+ data->fc.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi);
+ data->fc.rx_cos_mask = cpu_to_le16(params->pause.pri_map);
+
+ data->fc.safc_group_num = params->txq_params.cos;
+ data->fc.safc_group_en_flg =
+ (params->txq_params.flags & QUEUE_FLG_COS) ? 1 : 0;
+ data->fc.traffic_type = LLFC_TRAFFIC_TYPE_NW;
+}
+
+static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid)
+{
+ /* ustorm cxt validation */
+ cxt->ustorm_ag_context.cdu_usage =
+ CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_UCM_AG,
+ ETH_CONNECTION_TYPE);
+ /* xcontext validation */
+ cxt->xstorm_ag_context.cdu_reserved =
+ CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_XCM_AG,
+ ETH_CONNECTION_TYPE);
+}
+
+int bnx2x_setup_fw_client(struct bnx2x *bp,
+ struct bnx2x_client_init_params *params,
+ u8 activate,
+ struct client_init_ramrod_data *data,
+ dma_addr_t data_mapping)
+{
+ u16 hc_usec;
+ int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP;
+ int ramrod_flags = 0, rc;
+
+ /* HC and context validation values */
+ hc_usec = params->txq_params.hc_rate ?
+ 1000000 / params->txq_params.hc_rate : 0;
+ bnx2x_update_coalesce_sb_index(bp,
+ params->txq_params.fw_sb_id,
+ params->txq_params.sb_cq_index,
+ !(params->txq_params.flags & QUEUE_FLG_HC),
+ hc_usec);
+
+ *(params->ramrod_params.pstate) = BNX2X_FP_STATE_OPENING;
+
+ hc_usec = params->rxq_params.hc_rate ?
+ 1000000 / params->rxq_params.hc_rate : 0;
+ bnx2x_update_coalesce_sb_index(bp,
+ params->rxq_params.fw_sb_id,
+ params->rxq_params.sb_cq_index,
+ !(params->rxq_params.flags & QUEUE_FLG_HC),
+ hc_usec);
+
+ bnx2x_set_ctx_validation(params->rxq_params.cxt,
+ params->rxq_params.cid);
+
+ /* zero stats */
+ if (params->txq_params.flags & QUEUE_FLG_STATS)
+ storm_memset_xstats_zero(bp, BP_PORT(bp),
+ params->txq_params.stat_id);
+
+ if (params->rxq_params.flags & QUEUE_FLG_STATS) {
+ storm_memset_ustats_zero(bp, BP_PORT(bp),
+ params->rxq_params.stat_id);
+ storm_memset_tstats_zero(bp, BP_PORT(bp),
+ params->rxq_params.stat_id);
+ }
+
+ /* Fill the ramrod data */
+ bnx2x_fill_cl_init_data(bp, params, activate, data);
+
+ /* SETUP ramrod.
+ *
+ * bnx2x_sp_post() takes a spin_lock thus no other explict memory
+ * barrier except from mmiowb() is needed to impose a
+ * proper ordering of memory operations.
+ */
+ mmiowb();
- /* reset IGU state */
- bnx2x_ack_sb(bp, bp->fp[0].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
- /* SETUP ramrod */
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_SETUP, 0, 0, 0, 0);
+ bnx2x_sp_post(bp, ramrod, params->ramrod_params.cid,
+ U64_HI(data_mapping), U64_LO(data_mapping), 0);
/* Wait for completion */
- rc = bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0);
-
+ rc = bnx2x_wait_ramrod(bp, params->ramrod_params.state,
+ params->ramrod_params.index,
+ params->ramrod_params.pstate,
+ ramrod_flags);
return rc;
}
-int bnx2x_setup_multi(struct bnx2x *bp, int index)
+/**
+ * Configure interrupt mode according to current configuration.
+ * In case of MSI-X it will also try to enable MSI-X.
+ *
+ * @param bp
+ *
+ * @return int
+ */
+static int __devinit bnx2x_set_int_mode(struct bnx2x *bp)
{
- struct bnx2x_fastpath *fp = &bp->fp[index];
+ int rc = 0;
- /* reset IGU state */
- bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+ switch (bp->int_mode) {
+ case INT_MODE_MSI:
+ bnx2x_enable_msi(bp);
+ /* falling through... */
+ case INT_MODE_INTx:
+ bp->num_queues = 1;
+ DP(NETIF_MSG_IFUP, "set number of queues to 1\n");
+ break;
+ default:
+ /* Set number of queues according to bp->multi_mode value */
+ bnx2x_set_num_queues(bp);
- /* SETUP ramrod */
- fp->state = BNX2X_FP_STATE_OPENING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0,
- fp->cl_id, 0);
+ DP(NETIF_MSG_IFUP, "set number of queues to %d\n",
+ bp->num_queues);
- /* Wait for completion */
- return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
- &(fp->state), 0);
-}
+ /* if we can't use MSI-X we only need one fp,
+ * so try to enable MSI-X with the requested number of fp's
+ * and fallback to MSI or legacy INTx with one fp
+ */
+ rc = bnx2x_enable_msix(bp);
+ if (rc) {
+ /* failed to enable MSI-X */
+ if (bp->multi_mode)
+ DP(NETIF_MSG_IFUP,
+ "Multi requested but failed to "
+ "enable MSI-X (%d), "
+ "set number of queues to %d\n",
+ bp->num_queues,
+ 1);
+ bp->num_queues = 1;
+
+ if (!(bp->flags & DISABLE_MSI_FLAG))
+ bnx2x_enable_msi(bp);
+ }
+ break;
+ }
+
+ return rc;
+}
-void bnx2x_set_num_queues_msix(struct bnx2x *bp)
+/* must be called prioir to any HW initializations */
+static inline u16 bnx2x_cid_ilt_lines(struct bnx2x *bp)
{
+ return L2_ILT_LINES(bp);
+}
- switch (bp->multi_mode) {
- case ETH_RSS_MODE_DISABLED:
- bp->num_queues = 1;
- break;
+void bnx2x_ilt_set_info(struct bnx2x *bp)
+{
+ struct ilt_client_info *ilt_client;
+ struct bnx2x_ilt *ilt = BP_ILT(bp);
+ u16 line = 0;
- case ETH_RSS_MODE_REGULAR:
- if (num_queues)
- bp->num_queues = min_t(u32, num_queues,
- BNX2X_MAX_QUEUES(bp));
- else
- bp->num_queues = min_t(u32, num_online_cpus(),
- BNX2X_MAX_QUEUES(bp));
- break;
+ ilt->start_line = FUNC_ILT_BASE(BP_FUNC(bp));
+ DP(BNX2X_MSG_SP, "ilt starts at line %d\n", ilt->start_line);
+ /* CDU */
+ ilt_client = &ilt->clients[ILT_CLIENT_CDU];
+ ilt_client->client_num = ILT_CLIENT_CDU;
+ ilt_client->page_size = CDU_ILT_PAGE_SZ;
+ ilt_client->flags = ILT_CLIENT_SKIP_MEM;
+ ilt_client->start = line;
+ line += L2_ILT_LINES(bp);
+#ifdef BCM_CNIC
+ line += CNIC_ILT_LINES;
+#endif
+ ilt_client->end = line - 1;
+
+ DP(BNX2X_MSG_SP, "ilt client[CDU]: start %d, end %d, psz 0x%x, "
+ "flags 0x%x, hw psz %d\n",
+ ilt_client->start,
+ ilt_client->end,
+ ilt_client->page_size,
+ ilt_client->flags,
+ ilog2(ilt_client->page_size >> 12));
+
+ /* QM */
+ if (QM_INIT(bp->qm_cid_count)) {
+ ilt_client = &ilt->clients[ILT_CLIENT_QM];
+ ilt_client->client_num = ILT_CLIENT_QM;
+ ilt_client->page_size = QM_ILT_PAGE_SZ;
+ ilt_client->flags = 0;
+ ilt_client->start = line;
+
+ /* 4 bytes for each cid */
+ line += DIV_ROUND_UP(bp->qm_cid_count * QM_QUEUES_PER_FUNC * 4,
+ QM_ILT_PAGE_SZ);
+
+ ilt_client->end = line - 1;
+
+ DP(BNX2X_MSG_SP, "ilt client[QM]: start %d, end %d, psz 0x%x, "
+ "flags 0x%x, hw psz %d\n",
+ ilt_client->start,
+ ilt_client->end,
+ ilt_client->page_size,
+ ilt_client->flags,
+ ilog2(ilt_client->page_size >> 12));
+
+ }
+ /* SRC */
+ ilt_client = &ilt->clients[ILT_CLIENT_SRC];
+#ifdef BCM_CNIC
+ ilt_client->client_num = ILT_CLIENT_SRC;
+ ilt_client->page_size = SRC_ILT_PAGE_SZ;
+ ilt_client->flags = 0;
+ ilt_client->start = line;
+ line += SRC_ILT_LINES;
+ ilt_client->end = line - 1;
+
+ DP(BNX2X_MSG_SP, "ilt client[SRC]: start %d, end %d, psz 0x%x, "
+ "flags 0x%x, hw psz %d\n",
+ ilt_client->start,
+ ilt_client->end,
+ ilt_client->page_size,
+ ilt_client->flags,
+ ilog2(ilt_client->page_size >> 12));
- default:
- bp->num_queues = 1;
- break;
- }
-}
+#else
+ ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM);
+#endif
+ /* TM */
+ ilt_client = &ilt->clients[ILT_CLIENT_TM];
+#ifdef BCM_CNIC
+ ilt_client->client_num = ILT_CLIENT_TM;
+ ilt_client->page_size = TM_ILT_PAGE_SZ;
+ ilt_client->flags = 0;
+ ilt_client->start = line;
+ line += TM_ILT_LINES;
+ ilt_client->end = line - 1;
+
+ DP(BNX2X_MSG_SP, "ilt client[TM]: start %d, end %d, psz 0x%x, "
+ "flags 0x%x, hw psz %d\n",
+ ilt_client->start,
+ ilt_client->end,
+ ilt_client->page_size,
+ ilt_client->flags,
+ ilog2(ilt_client->page_size >> 12));
+#else
+ ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM);
+#endif
+}
-static int bnx2x_stop_multi(struct bnx2x *bp, int index)
+int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ int is_leading)
{
- struct bnx2x_fastpath *fp = &bp->fp[index];
+ struct bnx2x_client_init_params params = { {0} };
int rc;
- /* halt the connection */
- fp->state = BNX2X_FP_STATE_HALTING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, fp->cl_id, 0);
+ bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0,
+ IGU_INT_ENABLE, 0);
- /* Wait for completion */
- rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
- &(fp->state), 1);
- if (rc) /* timeout */
- return rc;
+ params.ramrod_params.pstate = &fp->state;
+ params.ramrod_params.state = BNX2X_FP_STATE_OPEN;
+ params.ramrod_params.index = fp->index;
+ params.ramrod_params.cid = fp->cid;
- /* delete cfc entry */
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1);
+ if (is_leading)
+ params.ramrod_params.flags |= CLIENT_IS_LEADING_RSS;
- /* Wait for completion */
- rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index,
- &(fp->state), 1);
+ bnx2x_pf_rx_cl_prep(bp, fp, &params.pause, &params.rxq_params);
+
+ bnx2x_pf_tx_cl_prep(bp, fp, &params.txq_params);
+
+ rc = bnx2x_setup_fw_client(bp, &params, 1,
+ bnx2x_sp(bp, client_init_data),
+ bnx2x_sp_mapping(bp, client_init_data));
return rc;
}
-static int bnx2x_stop_leading(struct bnx2x *bp)
+int bnx2x_stop_fw_client(struct bnx2x *bp, struct bnx2x_client_ramrod_params *p)
{
- __le16 dsb_sp_prod_idx;
- /* if the other port is handling traffic,
- this can take a lot of time */
- int cnt = 500;
int rc;
- might_sleep();
+ int poll_flag = p->poll ? WAIT_RAMROD_POLL : 0;
- /* Send HALT ramrod */
- bp->fp[0].state = BNX2X_FP_STATE_HALTING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, bp->fp->cl_id, 0);
+ /* halt the connection */
+ *p->pstate = BNX2X_FP_STATE_HALTING;
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, p->cid, 0,
+ p->cl_id, 0);
/* Wait for completion */
- rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0,
- &(bp->fp[0].state), 1);
+ rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, p->index,
+ p->pstate, poll_flag);
if (rc) /* timeout */
return rc;
- dsb_sp_prod_idx = *bp->dsb_sp_prod;
+ *p->pstate = BNX2X_FP_STATE_TERMINATING;
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TERMINATE, p->cid, 0,
+ p->cl_id, 0);
+ /* Wait for completion */
+ rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_TERMINATED, p->index,
+ p->pstate, poll_flag);
+ if (rc) /* timeout */
+ return rc;
- /* Send PORT_DELETE ramrod */
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1);
- /* Wait for completion to arrive on default status block
- we are going to reset the chip anyway
- so there is not much to do if this times out
- */
- while (dsb_sp_prod_idx == *bp->dsb_sp_prod) {
- if (!cnt) {
- DP(NETIF_MSG_IFDOWN, "timeout waiting for port del "
- "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n",
- *bp->dsb_sp_prod, dsb_sp_prod_idx);
-#ifdef BNX2X_STOP_ON_ERROR
- bnx2x_panic();
-#endif
- rc = -EBUSY;
- break;
- }
- cnt--;
- msleep(1);
- rmb(); /* Refresh the dsb_sp_prod */
- }
- bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
- bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
+ /* delete cfc entry */
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_CFC_DEL, p->cid, 0, 0, 1);
+ /* Wait for completion */
+ rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, p->index,
+ p->pstate, WAIT_RAMROD_COMMON);
return rc;
}
+static int bnx2x_stop_client(struct bnx2x *bp, int index)
+{
+ struct bnx2x_client_ramrod_params client_stop = {0};
+ struct bnx2x_fastpath *fp = &bp->fp[index];
+
+ client_stop.index = index;
+ client_stop.cid = fp->cid;
+ client_stop.cl_id = fp->cl_id;
+ client_stop.pstate = &(fp->state);
+ client_stop.poll = 0;
+
+ return bnx2x_stop_fw_client(bp, &client_stop);
+}
+
+
static void bnx2x_reset_func(struct bnx2x *bp)
{
int port = BP_PORT(bp);
int func = BP_FUNC(bp);
- int base, i;
+ int i;
+ int pfunc_offset_fp = offsetof(struct hc_sb_data, p_func) +
+ (CHIP_IS_E2(bp) ?
+ offsetof(struct hc_status_block_data_e2, common) :
+ offsetof(struct hc_status_block_data_e1x, common));
+ int pfunc_offset_sp = offsetof(struct hc_sp_status_block_data, p_func);
+ int pfid_offset = offsetof(struct pci_entity, pf_id);
+
+ /* Disable the function in the FW */
+ REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(func), 0);
+ REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(func), 0);
+ REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(func), 0);
+ REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(func), 0);
+
+ /* FP SBs */
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ REG_WR8(bp,
+ BAR_CSTRORM_INTMEM +
+ CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id)
+ + pfunc_offset_fp + pfid_offset,
+ HC_FUNCTION_DISABLED);
+ }
+
+ /* SP SB */
+ REG_WR8(bp,
+ BAR_CSTRORM_INTMEM +
+ CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) +
+ pfunc_offset_sp + pfid_offset,
+ HC_FUNCTION_DISABLED);
+
+
+ for (i = 0; i < XSTORM_SPQ_DATA_SIZE / 4; i++)
+ REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_DATA_OFFSET(func),
+ 0);
/* Configure IGU */
- REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
- REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
+ if (bp->common.int_block == INT_BLOCK_HC) {
+ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
+ REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
+ } else {
+ REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, 0);
+ REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0);
+ }
#ifdef BCM_CNIC
/* Disable Timer scan */
@@ -5125,9 +6747,27 @@ static void bnx2x_reset_func(struct bnx2x *bp)
}
#endif
/* Clear ILT */
- base = FUNC_ILT_BASE(func);
- for (i = base; i < base + ILT_PER_FUNC; i++)
- bnx2x_ilt_wr(bp, i, 0);
+ bnx2x_clear_func_ilt(bp, func);
+
+ /* Timers workaround bug for E2: if this is vnic-3,
+ * we need to set the entire ilt range for this timers.
+ */
+ if (CHIP_IS_E2(bp) && BP_VN(bp) == 3) {
+ struct ilt_client_info ilt_cli;
+ /* use dummy TM client */
+ memset(&ilt_cli, 0, sizeof(struct ilt_client_info));
+ ilt_cli.start = 0;
+ ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1;
+ ilt_cli.client_num = ILT_CLIENT_TM;
+
+ bnx2x_ilt_boundry_init_op(bp, &ilt_cli, 0, INITOP_CLEAR);
+ }
+
+ /* this assumes that reset_port() called before reset_func()*/
+ if (CHIP_IS_E2(bp))
+ bnx2x_pf_disable(bp);
+
+ bp->dmae_ready = 0;
}
static void bnx2x_reset_port(struct bnx2x *bp)
@@ -5159,7 +6799,7 @@ static void bnx2x_reset_port(struct bnx2x *bp)
static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
{
DP(BNX2X_MSG_MCP, "function %d reset_code %x\n",
- BP_FUNC(bp), reset_code);
+ BP_ABS_FUNC(bp), reset_code);
switch (reset_code) {
case FW_MSG_CODE_DRV_UNLOAD_COMMON:
@@ -5196,7 +6836,6 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
cnt = 1000;
while (bnx2x_has_tx_work_unload(fp)) {
- bnx2x_tx_int(fp);
if (!cnt) {
BNX2X_ERR("timeout waiting for queue[%d]\n",
i);
@@ -5215,39 +6854,21 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
msleep(1);
if (CHIP_IS_E1(bp)) {
- struct mac_configuration_cmd *config =
- bnx2x_sp(bp, mcast_config);
-
- bnx2x_set_eth_mac_addr_e1(bp, 0);
-
- for (i = 0; i < config->hdr.length; i++)
- CAM_INVALIDATE(config->config_table[i]);
-
- config->hdr.length = i;
- if (CHIP_REV_IS_SLOW(bp))
- config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port);
- else
- config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port);
- config->hdr.client_id = bp->fp->cl_id;
- config->hdr.reserved1 = 0;
-
- bp->set_mac_pending++;
- smp_wmb();
-
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
- U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
- U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0);
+ /* invalidate mc list,
+ * wait and poll (interrupts are off)
+ */
+ bnx2x_invlidate_e1_mc_list(bp);
+ bnx2x_set_eth_mac(bp, 0);
- } else { /* E1H */
+ } else {
REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
- bnx2x_set_eth_mac_addr_e1h(bp, 0);
+ bnx2x_set_eth_mac(bp, 0);
for (i = 0; i < MC_HASH_SIZE; i++)
REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
-
- REG_WR(bp, MISC_REG_E1HMF_MODE, 0);
}
+
#ifdef BCM_CNIC
/* Clear iSCSI L2 MAC */
mutex_lock(&bp->cnic_mutex);
@@ -5286,33 +6907,44 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
/* Close multi and leading connections
Completions for ramrods are collected in a synchronous way */
- for_each_nondefault_queue(bp, i)
- if (bnx2x_stop_multi(bp, i))
+ for_each_queue(bp, i)
+
+ if (bnx2x_stop_client(bp, i))
+#ifdef BNX2X_STOP_ON_ERROR
+ return;
+#else
goto unload_error;
+#endif
- rc = bnx2x_stop_leading(bp);
+ rc = bnx2x_func_stop(bp);
if (rc) {
- BNX2X_ERR("Stop leading failed!\n");
+ BNX2X_ERR("Function stop failed!\n");
#ifdef BNX2X_STOP_ON_ERROR
- return -EBUSY;
+ return;
#else
goto unload_error;
#endif
}
-
+#ifndef BNX2X_STOP_ON_ERROR
unload_error:
+#endif
if (!BP_NOMCP(bp))
- reset_code = bnx2x_fw_command(bp, reset_code);
+ reset_code = bnx2x_fw_command(bp, reset_code, 0);
else {
- DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- load_count[0]--;
- load_count[1 + port]--;
- DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- if (load_count[0] == 0)
+ DP(NETIF_MSG_IFDOWN, "NO MCP - load counts[%d] "
+ "%d, %d, %d\n", BP_PATH(bp),
+ load_count[BP_PATH(bp)][0],
+ load_count[BP_PATH(bp)][1],
+ load_count[BP_PATH(bp)][2]);
+ load_count[BP_PATH(bp)][0]--;
+ load_count[BP_PATH(bp)][1 + port]--;
+ DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts[%d] "
+ "%d, %d, %d\n", BP_PATH(bp),
+ load_count[BP_PATH(bp)][0], load_count[BP_PATH(bp)][1],
+ load_count[BP_PATH(bp)][2]);
+ if (load_count[BP_PATH(bp)][0] == 0)
reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
- else if (load_count[1 + port] == 0)
+ else if (load_count[BP_PATH(bp)][1 + port] == 0)
reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT;
else
reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION;
@@ -5322,12 +6954,18 @@ unload_error:
(reset_code == FW_MSG_CODE_DRV_UNLOAD_PORT))
bnx2x__link_reset(bp);
+ /* Disable HW interrupts, NAPI */
+ bnx2x_netif_stop(bp, 1);
+
+ /* Release IRQs */
+ bnx2x_free_irq(bp);
+
/* Reset the chip */
bnx2x_reset_chip(bp, reset_code);
/* Report UNLOAD_DONE to MCP */
if (!BP_NOMCP(bp))
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
}
@@ -5353,7 +6991,6 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp)
}
}
-
/* Close gates #2, #3 and #4: */
static void bnx2x_set_234_gates(struct bnx2x *bp, bool close)
{
@@ -5399,15 +7036,13 @@ static void bnx2x_clp_reset_prep(struct bnx2x *bp, u32 *magic_val)
static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val)
{
/* Restore the `magic' bit value... */
- /* u32 val = SHMEM_RD(bp, mf_cfg.shared_mf_config.clp_mb);
- SHMEM_WR(bp, mf_cfg.shared_mf_config.clp_mb,
- (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); */
u32 val = MF_CFG_RD(bp, shared_mf_config.clp_mb);
MF_CFG_WR(bp, shared_mf_config.clp_mb,
(val & (~SHARED_MF_CLP_MAGIC)) | magic_val);
}
-/* Prepares for MCP reset: takes care of CLP configurations.
+/**
+ * Prepares for MCP reset: takes care of CLP configurations.
*
* @param bp
* @param magic_val Old value of 'magic' bit.
@@ -5805,39 +7440,23 @@ reset_task_exit:
* Init service functions
*/
-static inline u32 bnx2x_get_pretend_reg(struct bnx2x *bp, int func)
-{
- switch (func) {
- case 0: return PXP2_REG_PGL_PRETEND_FUNC_F0;
- case 1: return PXP2_REG_PGL_PRETEND_FUNC_F1;
- case 2: return PXP2_REG_PGL_PRETEND_FUNC_F2;
- case 3: return PXP2_REG_PGL_PRETEND_FUNC_F3;
- case 4: return PXP2_REG_PGL_PRETEND_FUNC_F4;
- case 5: return PXP2_REG_PGL_PRETEND_FUNC_F5;
- case 6: return PXP2_REG_PGL_PRETEND_FUNC_F6;
- case 7: return PXP2_REG_PGL_PRETEND_FUNC_F7;
- default:
- BNX2X_ERR("Unsupported function index: %d\n", func);
- return (u32)(-1);
- }
+u32 bnx2x_get_pretend_reg(struct bnx2x *bp)
+{
+ u32 base = PXP2_REG_PGL_PRETEND_FUNC_F0;
+ u32 stride = PXP2_REG_PGL_PRETEND_FUNC_F1 - base;
+ return base + (BP_ABS_FUNC(bp)) * stride;
}
-static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func)
+static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp)
{
- u32 reg = bnx2x_get_pretend_reg(bp, orig_func), new_val;
+ u32 reg = bnx2x_get_pretend_reg(bp);
/* Flush all outstanding writes */
mmiowb();
/* Pretend to be function 0 */
REG_WR(bp, reg, 0);
- /* Flush the GRC transaction (in the chip) */
- new_val = REG_RD(bp, reg);
- if (new_val != 0) {
- BNX2X_ERR("Hmmm... Pretend register wasn't updated: (0,%d)!\n",
- new_val);
- BUG();
- }
+ REG_RD(bp, reg); /* Flush the GRC transaction (in the chip) */
/* From now we are in the "like-E1" mode */
bnx2x_int_disable(bp);
@@ -5845,22 +7464,17 @@ static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func)
/* Flush all outstanding writes */
mmiowb();
- /* Restore the original funtion settings */
- REG_WR(bp, reg, orig_func);
- new_val = REG_RD(bp, reg);
- if (new_val != orig_func) {
- BNX2X_ERR("Hmmm... Pretend register wasn't updated: (%d,%d)!\n",
- orig_func, new_val);
- BUG();
- }
+ /* Restore the original function */
+ REG_WR(bp, reg, BP_ABS_FUNC(bp));
+ REG_RD(bp, reg);
}
-static inline void bnx2x_undi_int_disable(struct bnx2x *bp, int func)
+static inline void bnx2x_undi_int_disable(struct bnx2x *bp)
{
- if (CHIP_IS_E1H(bp))
- bnx2x_undi_int_disable_e1h(bp, func);
- else
+ if (CHIP_IS_E1(bp))
bnx2x_int_disable(bp);
+ else
+ bnx2x_undi_int_disable_e1h(bp);
}
static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
@@ -5877,8 +7491,8 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
if (val == 0x7) {
u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
- /* save our func */
- int func = BP_FUNC(bp);
+ /* save our pf_num */
+ int orig_pf_num = bp->pf_num;
u32 swap_en;
u32 swap_val;
@@ -5888,32 +7502,33 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
BNX2X_DEV_INFO("UNDI is active! reset device\n");
/* try unload UNDI on port 0 */
- bp->func = 0;
+ bp->pf_num = 0;
bp->fw_seq =
- (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
+ (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) &
DRV_MSG_SEQ_NUMBER_MASK);
- reset_code = bnx2x_fw_command(bp, reset_code);
+ reset_code = bnx2x_fw_command(bp, reset_code, 0);
/* if UNDI is loaded on the other port */
if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) {
/* send "DONE" for previous unload */
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ bnx2x_fw_command(bp,
+ DRV_MSG_CODE_UNLOAD_DONE, 0);
/* unload UNDI on port 1 */
- bp->func = 1;
+ bp->pf_num = 1;
bp->fw_seq =
- (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
+ (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) &
DRV_MSG_SEQ_NUMBER_MASK);
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
- bnx2x_fw_command(bp, reset_code);
+ bnx2x_fw_command(bp, reset_code, 0);
}
/* now it's safe to release the lock */
bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
- bnx2x_undi_int_disable(bp, func);
+ bnx2x_undi_int_disable(bp);
/* close input traffic and wait for it */
/* Do not rcv packets to BRB */
@@ -5949,14 +7564,13 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en);
/* send unload done to the MCP */
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
/* restore our func and fw_seq */
- bp->func = func;
+ bp->pf_num = orig_pf_num;
bp->fw_seq =
- (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
+ (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) &
DRV_MSG_SEQ_NUMBER_MASK);
-
} else
bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
}
@@ -5978,6 +7592,40 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
val = REG_RD(bp, MISC_REG_BOND_ID);
id |= (val & 0xf);
bp->common.chip_id = id;
+
+ /* Set doorbell size */
+ bp->db_size = (1 << BNX2X_DB_SHIFT);
+
+ if (CHIP_IS_E2(bp)) {
+ val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR);
+ if ((val & 1) == 0)
+ val = REG_RD(bp, MISC_REG_PORT4MODE_EN);
+ else
+ val = (val >> 1) & 1;
+ BNX2X_DEV_INFO("chip is in %s\n", val ? "4_PORT_MODE" :
+ "2_PORT_MODE");
+ bp->common.chip_port_mode = val ? CHIP_4_PORT_MODE :
+ CHIP_2_PORT_MODE;
+
+ if (CHIP_MODE_IS_4_PORT(bp))
+ bp->pfid = (bp->pf_num >> 1); /* 0..3 */
+ else
+ bp->pfid = (bp->pf_num & 0x6); /* 0, 2, 4, 6 */
+ } else {
+ bp->common.chip_port_mode = CHIP_PORT_MODE_NONE; /* N/A */
+ bp->pfid = bp->pf_num; /* 0..7 */
+ }
+
+ /*
+ * set base FW non-default (fast path) status block id, this value is
+ * used to initialize the fw_sb_id saved on the fp/queue structure to
+ * determine the id used by the FW.
+ */
+ if (CHIP_IS_E1x(bp))
+ bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E1x;
+ else /* E2 */
+ bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E2;
+
bp->link_params.chip_id = bp->common.chip_id;
BNX2X_DEV_INFO("chip ID is 0x%x\n", id);
@@ -5995,14 +7643,15 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
bp->common.flash_size, bp->common.flash_size);
bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
- bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0);
+ bp->common.shmem2_base = REG_RD(bp, (BP_PATH(bp) ?
+ MISC_REG_GENERIC_CR_1 :
+ MISC_REG_GENERIC_CR_0));
bp->link_params.shmem_base = bp->common.shmem_base;
+ bp->link_params.shmem2_base = bp->common.shmem2_base;
BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n",
bp->common.shmem_base, bp->common.shmem2_base);
- if (!bp->common.shmem_base ||
- (bp->common.shmem_base < 0xA0000) ||
- (bp->common.shmem_base >= 0xC0000)) {
+ if (!bp->common.shmem_base) {
BNX2X_DEV_INFO("MCP not active\n");
bp->flags |= NO_MCP_FLAG;
return;
@@ -6011,7 +7660,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
!= (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
- BNX2X_ERROR("BAD MCP validity signature\n");
+ BNX2X_ERR("BAD MCP validity signature\n");
bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config);
@@ -6035,12 +7684,16 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
if (val < BNX2X_BC_VER) {
/* for now only warn
* later we might need to enforce this */
- BNX2X_ERROR("This driver needs bc_ver %X but found %X, "
- "please upgrade BC\n", BNX2X_BC_VER, val);
+ BNX2X_ERR("This driver needs bc_ver %X but found %X, "
+ "please upgrade BC\n", BNX2X_BC_VER, val);
}
bp->link_params.feature_config_flags |=
- (val >= REQ_BC_VER_4_VRFY_OPT_MDL) ?
- FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0;
+ (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ?
+ FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0;
+
+ bp->link_params.feature_config_flags |=
+ (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);
@@ -6061,404 +7714,348 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
val, val2, val3, val4);
}
+#define IGU_FID(val) GET_FIELD((val), IGU_REG_MAPPING_MEMORY_FID)
+#define IGU_VEC(val) GET_FIELD((val), IGU_REG_MAPPING_MEMORY_VECTOR)
+
+static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp)
+{
+ int pfid = BP_FUNC(bp);
+ int vn = BP_E1HVN(bp);
+ int igu_sb_id;
+ u32 val;
+ u8 fid;
+
+ bp->igu_base_sb = 0xff;
+ bp->igu_sb_cnt = 0;
+ if (CHIP_INT_MODE_IS_BC(bp)) {
+ bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x,
+ bp->l2_cid_count);
+
+ bp->igu_base_sb = (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn) *
+ FP_SB_MAX_E1x;
+
+ bp->igu_dsb_id = E1HVN_MAX * FP_SB_MAX_E1x +
+ (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn);
+
+ return;
+ }
+
+ /* IGU in normal mode - read CAM */
+ for (igu_sb_id = 0; igu_sb_id < IGU_REG_MAPPING_MEMORY_SIZE;
+ igu_sb_id++) {
+ val = REG_RD(bp, IGU_REG_MAPPING_MEMORY + igu_sb_id * 4);
+ if (!(val & IGU_REG_MAPPING_MEMORY_VALID))
+ continue;
+ fid = IGU_FID(val);
+ if ((fid & IGU_FID_ENCODE_IS_PF)) {
+ if ((fid & IGU_FID_PF_NUM_MASK) != pfid)
+ continue;
+ if (IGU_VEC(val) == 0)
+ /* default status block */
+ bp->igu_dsb_id = igu_sb_id;
+ else {
+ if (bp->igu_base_sb == 0xff)
+ bp->igu_base_sb = igu_sb_id;
+ bp->igu_sb_cnt++;
+ }
+ }
+ }
+ bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, bp->l2_cid_count);
+ if (bp->igu_sb_cnt == 0)
+ BNX2X_ERR("CAM configuration error\n");
+}
+
static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
u32 switch_cfg)
{
- int port = BP_PORT(bp);
- u32 ext_phy_type;
-
- switch (switch_cfg) {
- case SWITCH_CFG_1G:
- BNX2X_DEV_INFO("switch_cfg 0x%x (1G)\n", switch_cfg);
-
- ext_phy_type =
- SERDES_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_TP |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
+ int cfg_size = 0, idx, port = BP_PORT(bp);
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (5482)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
+ /* Aggregation of supported attributes of all external phys */
+ bp->port.supported[0] = 0;
+ bp->port.supported[1] = 0;
+ switch (bp->link_params.num_phys) {
+ case 1:
+ bp->port.supported[0] = bp->link_params.phy[INT_PHY].supported;
+ cfg_size = 1;
+ break;
+ case 2:
+ bp->port.supported[0] = bp->link_params.phy[EXT_PHY1].supported;
+ cfg_size = 1;
+ break;
+ case 3:
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED) {
+ bp->port.supported[1] =
+ bp->link_params.phy[EXT_PHY1].supported;
+ bp->port.supported[0] =
+ bp->link_params.phy[EXT_PHY2].supported;
+ } else {
+ bp->port.supported[0] =
+ bp->link_params.phy[EXT_PHY1].supported;
+ bp->port.supported[1] =
+ bp->link_params.phy[EXT_PHY2].supported;
+ }
+ cfg_size = 2;
+ break;
+ }
- default:
- BNX2X_ERR("NVRAM config error. "
- "BAD SerDes ext_phy_config 0x%x\n",
- bp->link_params.ext_phy_config);
+ if (!(bp->port.supported[0] || bp->port.supported[1])) {
+ BNX2X_ERR("NVRAM config error. BAD phy config."
+ "PHY1 config 0x%x, PHY2 config 0x%x\n",
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config),
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config2));
return;
- }
+ }
+ switch (switch_cfg) {
+ case SWITCH_CFG_1G:
bp->port.phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR +
port*0x10);
BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr);
break;
case SWITCH_CFG_10G:
- BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg);
-
- ext_phy_type =
- XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_10000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8727)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM8481)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_10000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
- bp->link_params.ext_phy_config);
- break;
-
- default:
- BNX2X_ERR("NVRAM config error. "
- "BAD XGXS ext_phy_config 0x%x\n",
- bp->link_params.ext_phy_config);
- return;
- }
-
bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR +
port*0x18);
BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr);
-
break;
default:
BNX2X_ERR("BAD switch_cfg link_config 0x%x\n",
- bp->port.link_config);
+ bp->port.link_config[0]);
return;
}
- bp->link_params.phy_addr = bp->port.phy_addr;
-
- /* mask what we support according to speed_cap_mask */
- if (!(bp->link_params.speed_cap_mask &
+ /* mask what we support according to speed_cap_mask per configuration */
+ for (idx = 0; idx < cfg_size; idx++) {
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF))
- bp->port.supported &= ~SUPPORTED_10baseT_Half;
+ bp->port.supported[idx] &= ~SUPPORTED_10baseT_Half;
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL))
- bp->port.supported &= ~SUPPORTED_10baseT_Full;
+ bp->port.supported[idx] &= ~SUPPORTED_10baseT_Full;
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))
- bp->port.supported &= ~SUPPORTED_100baseT_Half;
+ bp->port.supported[idx] &= ~SUPPORTED_100baseT_Half;
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL))
- bp->port.supported &= ~SUPPORTED_100baseT_Full;
+ bp->port.supported[idx] &= ~SUPPORTED_100baseT_Full;
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))
- bp->port.supported &= ~(SUPPORTED_1000baseT_Half |
- SUPPORTED_1000baseT_Full);
+ bp->port.supported[idx] &= ~(SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full);
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
- bp->port.supported &= ~SUPPORTED_2500baseX_Full;
+ bp->port.supported[idx] &= ~SUPPORTED_2500baseX_Full;
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
- bp->port.supported &= ~SUPPORTED_10000baseT_Full;
+ bp->port.supported[idx] &= ~SUPPORTED_10000baseT_Full;
+
+ }
- BNX2X_DEV_INFO("supported 0x%x\n", bp->port.supported);
+ BNX2X_DEV_INFO("supported 0x%x 0x%x\n", bp->port.supported[0],
+ bp->port.supported[1]);
}
static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
{
- bp->link_params.req_duplex = DUPLEX_FULL;
+ u32 link_config, idx, cfg_size = 0;
+ bp->port.advertising[0] = 0;
+ bp->port.advertising[1] = 0;
+ switch (bp->link_params.num_phys) {
+ case 1:
+ case 2:
+ cfg_size = 1;
+ break;
+ case 3:
+ cfg_size = 2;
+ break;
+ }
+ for (idx = 0; idx < cfg_size; idx++) {
+ bp->link_params.req_duplex[idx] = DUPLEX_FULL;
+ link_config = bp->port.link_config[idx];
+ switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
+ case PORT_FEATURE_LINK_SPEED_AUTO:
+ if (bp->port.supported[idx] & SUPPORTED_Autoneg) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_AUTO_NEG;
+ bp->port.advertising[idx] |=
+ bp->port.supported[idx];
+ } else {
+ /* force 10G, no AN */
+ bp->link_params.req_line_speed[idx] =
+ SPEED_10000;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_10000baseT_Full |
+ ADVERTISED_FIBRE);
+ continue;
+ }
+ break;
- switch (bp->port.link_config & PORT_FEATURE_LINK_SPEED_MASK) {
- case PORT_FEATURE_LINK_SPEED_AUTO:
- if (bp->port.supported & SUPPORTED_Autoneg) {
- bp->link_params.req_line_speed = SPEED_AUTO_NEG;
- bp->port.advertising = bp->port.supported;
- } else {
- u32 ext_phy_type =
- XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+ case PORT_FEATURE_LINK_SPEED_10M_FULL:
+ if (bp->port.supported[idx] & SUPPORTED_10baseT_Full) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_10;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_10baseT_Full |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERROR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " speed_cap_mask 0x%x\n",
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
+ return;
+ }
+ break;
- if ((ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
- (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) {
- /* force 10G, no AN */
- bp->link_params.req_line_speed = SPEED_10000;
- bp->port.advertising =
- (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
- break;
+ case PORT_FEATURE_LINK_SPEED_10M_HALF:
+ if (bp->port.supported[idx] & SUPPORTED_10baseT_Half) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_10;
+ bp->link_params.req_duplex[idx] =
+ DUPLEX_HALF;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_10baseT_Half |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERROR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " speed_cap_mask 0x%x\n",
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
+ return;
}
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " Autoneg not supported\n",
- bp->port.link_config);
- return;
- }
- break;
+ break;
- case PORT_FEATURE_LINK_SPEED_10M_FULL:
- if (bp->port.supported & SUPPORTED_10baseT_Full) {
- bp->link_params.req_line_speed = SPEED_10;
- bp->port.advertising = (ADVERTISED_10baseT_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERROR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
+ case PORT_FEATURE_LINK_SPEED_100M_FULL:
+ if (bp->port.supported[idx] &
+ SUPPORTED_100baseT_Full) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_100;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_100baseT_Full |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERROR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " speed_cap_mask 0x%x\n",
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
+ return;
+ }
+ break;
- case PORT_FEATURE_LINK_SPEED_10M_HALF:
- if (bp->port.supported & SUPPORTED_10baseT_Half) {
- bp->link_params.req_line_speed = SPEED_10;
- bp->link_params.req_duplex = DUPLEX_HALF;
- bp->port.advertising = (ADVERTISED_10baseT_Half |
- ADVERTISED_TP);
- } else {
- BNX2X_ERROR("NVRAM config error. "
+ case PORT_FEATURE_LINK_SPEED_100M_HALF:
+ if (bp->port.supported[idx] &
+ SUPPORTED_100baseT_Half) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_100;
+ bp->link_params.req_duplex[idx] =
+ DUPLEX_HALF;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_100baseT_Half |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
+ return;
+ }
+ break;
- case PORT_FEATURE_LINK_SPEED_100M_FULL:
- if (bp->port.supported & SUPPORTED_100baseT_Full) {
- bp->link_params.req_line_speed = SPEED_100;
- bp->port.advertising = (ADVERTISED_100baseT_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERROR("NVRAM config error. "
+ case PORT_FEATURE_LINK_SPEED_1G:
+ if (bp->port.supported[idx] &
+ SUPPORTED_1000baseT_Full) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_1000;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_1000baseT_Full |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
+ return;
+ }
+ break;
- case PORT_FEATURE_LINK_SPEED_100M_HALF:
- if (bp->port.supported & SUPPORTED_100baseT_Half) {
- bp->link_params.req_line_speed = SPEED_100;
- bp->link_params.req_duplex = DUPLEX_HALF;
- bp->port.advertising = (ADVERTISED_100baseT_Half |
+ case PORT_FEATURE_LINK_SPEED_2_5G:
+ if (bp->port.supported[idx] &
+ SUPPORTED_2500baseX_Full) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_2500;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_2500baseX_Full |
ADVERTISED_TP);
- } else {
- BNX2X_ERROR("NVRAM config error. "
+ } else {
+ BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
+ return;
+ }
+ break;
- case PORT_FEATURE_LINK_SPEED_1G:
- if (bp->port.supported & SUPPORTED_1000baseT_Full) {
- bp->link_params.req_line_speed = SPEED_1000;
- bp->port.advertising = (ADVERTISED_1000baseT_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERROR("NVRAM config error. "
+ case PORT_FEATURE_LINK_SPEED_10G_CX4:
+ case PORT_FEATURE_LINK_SPEED_10G_KX4:
+ case PORT_FEATURE_LINK_SPEED_10G_KR:
+ if (bp->port.supported[idx] &
+ SUPPORTED_10000baseT_Full) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_10000;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_10000baseT_Full |
+ ADVERTISED_FIBRE);
+ } else {
+ BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
+ return;
+ }
+ break;
- case PORT_FEATURE_LINK_SPEED_2_5G:
- if (bp->port.supported & SUPPORTED_2500baseX_Full) {
- bp->link_params.req_line_speed = SPEED_2500;
- bp->port.advertising = (ADVERTISED_2500baseX_Full |
- ADVERTISED_TP);
- } else {
+ default:
BNX2X_ERROR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
+ "BAD link speed link_config 0x%x\n",
+ link_config);
+ bp->link_params.req_line_speed[idx] =
+ SPEED_AUTO_NEG;
+ bp->port.advertising[idx] =
+ bp->port.supported[idx];
+ break;
}
- break;
- case PORT_FEATURE_LINK_SPEED_10G_CX4:
- case PORT_FEATURE_LINK_SPEED_10G_KX4:
- case PORT_FEATURE_LINK_SPEED_10G_KR:
- if (bp->port.supported & SUPPORTED_10000baseT_Full) {
- bp->link_params.req_line_speed = SPEED_10000;
- bp->port.advertising = (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
- } else {
- BNX2X_ERROR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
+ bp->link_params.req_flow_ctrl[idx] = (link_config &
+ PORT_FEATURE_FLOW_CONTROL_MASK);
+ if ((bp->link_params.req_flow_ctrl[idx] ==
+ BNX2X_FLOW_CTRL_AUTO) &&
+ !(bp->port.supported[idx] & SUPPORTED_Autoneg)) {
+ bp->link_params.req_flow_ctrl[idx] =
+ BNX2X_FLOW_CTRL_NONE;
}
- break;
- default:
- BNX2X_ERROR("NVRAM config error. "
- "BAD link speed link_config 0x%x\n",
- bp->port.link_config);
- bp->link_params.req_line_speed = SPEED_AUTO_NEG;
- bp->port.advertising = bp->port.supported;
- break;
+ BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl"
+ " 0x%x advertising 0x%x\n",
+ bp->link_params.req_line_speed[idx],
+ bp->link_params.req_duplex[idx],
+ bp->link_params.req_flow_ctrl[idx],
+ bp->port.advertising[idx]);
}
-
- bp->link_params.req_flow_ctrl = (bp->port.link_config &
- PORT_FEATURE_FLOW_CONTROL_MASK);
- if ((bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
- !(bp->port.supported & SUPPORTED_Autoneg))
- bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
-
- BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x"
- " advertising 0x%x\n",
- bp->link_params.req_line_speed,
- bp->link_params.req_duplex,
- bp->link_params.req_flow_ctrl, bp->port.advertising);
}
static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi)
@@ -6474,48 +8071,28 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
int port = BP_PORT(bp);
u32 val, val2;
u32 config;
- u16 i;
- u32 ext_phy_type;
+ u32 ext_phy_type, ext_phy_config;;
bp->link_params.bp = bp;
bp->link_params.port = port;
bp->link_params.lane_config =
SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
- bp->link_params.ext_phy_config =
- SHMEM_RD(bp,
- dev_info.port_hw_config[port].external_phy_config);
- /* BCM8727_NOC => BCM8727 no over current */
- if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC) {
- bp->link_params.ext_phy_config &=
- ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
- bp->link_params.ext_phy_config |=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727;
- bp->link_params.feature_config_flags |=
- FEATURE_CONFIG_BCM8727_NOC;
- }
- bp->link_params.speed_cap_mask =
+ bp->link_params.speed_cap_mask[0] =
SHMEM_RD(bp,
dev_info.port_hw_config[port].speed_capability_mask);
-
- bp->port.link_config =
+ bp->link_params.speed_cap_mask[1] =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].speed_capability_mask2);
+ bp->port.link_config[0] =
SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
- /* Get the 4 lanes xgxs config rx and tx */
- for (i = 0; i < 2; i++) {
- val = SHMEM_RD(bp,
- dev_info.port_hw_config[port].xgxs_config_rx[i<<1]);
- bp->link_params.xgxs_config_rx[i << 1] = ((val>>16) & 0xffff);
- bp->link_params.xgxs_config_rx[(i << 1) + 1] = (val & 0xffff);
-
- val = SHMEM_RD(bp,
- dev_info.port_hw_config[port].xgxs_config_tx[i<<1]);
- bp->link_params.xgxs_config_tx[i << 1] = ((val>>16) & 0xffff);
- bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff);
- }
+ bp->port.link_config[1] =
+ SHMEM_RD(bp, dev_info.port_feature_config[port].link_config2);
+ bp->link_params.multi_phy_config =
+ SHMEM_RD(bp, dev_info.port_hw_config[port].multi_phy_config);
/* If the device is capable of WoL, set the default state according
* to the HW
*/
@@ -6523,14 +8100,15 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
bp->wol = (!(bp->flags & NO_WOL_FLAG) &&
(config & PORT_FEATURE_WOL_ENABLED));
- BNX2X_DEV_INFO("lane_config 0x%08x ext_phy_config 0x%08x"
- " speed_cap_mask 0x%08x link_config 0x%08x\n",
+ BNX2X_DEV_INFO("lane_config 0x%08x "
+ "speed_cap_mask0 0x%08x link_config0 0x%08x\n",
bp->link_params.lane_config,
- bp->link_params.ext_phy_config,
- bp->link_params.speed_cap_mask, bp->port.link_config);
+ bp->link_params.speed_cap_mask[0],
+ bp->port.link_config[0]);
- bp->link_params.switch_cfg |= (bp->port.link_config &
- PORT_FEATURE_CONNECTED_SWITCH_MASK);
+ bp->link_params.switch_cfg = (bp->port.link_config[0] &
+ PORT_FEATURE_CONNECTED_SWITCH_MASK);
+ bnx2x_phy_probe(&bp->link_params);
bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg);
bnx2x_link_settings_requested(bp);
@@ -6539,14 +8117,17 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
* If connected directly, work with the internal PHY, otherwise, work
* with the external PHY
*/
- ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+ ext_phy_config =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config);
+ ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
- bp->mdio.prtad = bp->link_params.phy_addr;
+ bp->mdio.prtad = bp->port.phy_addr;
else if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
(ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
bp->mdio.prtad =
- XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config);
+ XGXS_EXT_PHY_ADDR(ext_phy_config);
val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
@@ -6563,41 +8144,74 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
{
- int func = BP_FUNC(bp);
+ int func = BP_ABS_FUNC(bp);
+ int vn;
u32 val, val2;
int rc = 0;
bnx2x_get_common_hwinfo(bp);
- bp->e1hov = 0;
- bp->e1hmf = 0;
- if (CHIP_IS_E1H(bp) && !BP_NOMCP(bp)) {
- bp->mf_config =
- SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+ if (CHIP_IS_E1x(bp)) {
+ bp->common.int_block = INT_BLOCK_HC;
+
+ bp->igu_dsb_id = DEF_SB_IGU_ID;
+ bp->igu_base_sb = 0;
+ bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count);
+ } else {
+ bp->common.int_block = INT_BLOCK_IGU;
+ val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION);
+ if (val & IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN) {
+ DP(NETIF_MSG_PROBE, "IGU Backward Compatible Mode\n");
+ bp->common.int_block |= INT_BLOCK_MODE_BW_COMP;
+ } else
+ DP(NETIF_MSG_PROBE, "IGU Normal Mode\n");
+
+ bnx2x_get_igu_cam_info(bp);
+
+ }
+ DP(NETIF_MSG_PROBE, "igu_dsb_id %d igu_base_sb %d igu_sb_cnt %d\n",
+ bp->igu_dsb_id, bp->igu_base_sb, bp->igu_sb_cnt);
+
+ /*
+ * Initialize MF configuration
+ */
- val = (SHMEM_RD(bp, mf_cfg.func_mf_config[FUNC_0].e1hov_tag) &
+ bp->mf_ov = 0;
+ bp->mf_mode = 0;
+ vn = BP_E1HVN(bp);
+ if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) {
+ if (SHMEM2_HAS(bp, mf_cfg_addr))
+ bp->common.mf_cfg_base = SHMEM2_RD(bp, mf_cfg_addr);
+ else
+ bp->common.mf_cfg_base = bp->common.shmem_base +
+ offsetof(struct shmem_region, func_mb) +
+ E1H_FUNC_MAX * sizeof(struct drv_func_mb);
+ bp->mf_config[vn] =
+ MF_CFG_RD(bp, func_mf_config[func].config);
+
+ val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) &
FUNC_MF_CFG_E1HOV_TAG_MASK);
if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT)
- bp->e1hmf = 1;
+ bp->mf_mode = 1;
BNX2X_DEV_INFO("%s function mode\n",
- IS_E1HMF(bp) ? "multi" : "single");
+ IS_MF(bp) ? "multi" : "single");
- if (IS_E1HMF(bp)) {
- val = (SHMEM_RD(bp, mf_cfg.func_mf_config[func].
+ if (IS_MF(bp)) {
+ val = (MF_CFG_RD(bp, func_mf_config[func].
e1hov_tag) &
FUNC_MF_CFG_E1HOV_TAG_MASK);
if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
- bp->e1hov = val;
- BNX2X_DEV_INFO("E1HOV for func %d is %d "
+ bp->mf_ov = val;
+ BNX2X_DEV_INFO("MF OV for func %d is %d "
"(0x%04x)\n",
- func, bp->e1hov, bp->e1hov);
+ func, bp->mf_ov, bp->mf_ov);
} else {
- BNX2X_ERROR("No valid E1HOV for func %d,"
+ BNX2X_ERROR("No valid MF OV for func %d,"
" aborting\n", func);
rc = -EPERM;
}
} else {
- if (BP_E1HVN(bp)) {
+ if (BP_VN(bp)) {
BNX2X_ERROR("VN %d in single function mode,"
" aborting\n", BP_E1HVN(bp));
rc = -EPERM;
@@ -6605,17 +8219,31 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
}
}
+ /* adjust igu_sb_cnt to MF for E1x */
+ if (CHIP_IS_E1x(bp) && IS_MF(bp))
+ bp->igu_sb_cnt /= E1HVN_MAX;
+
+ /*
+ * adjust E2 sb count: to be removed when FW will support
+ * more then 16 L2 clients
+ */
+#define MAX_L2_CLIENTS 16
+ if (CHIP_IS_E2(bp))
+ bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt,
+ MAX_L2_CLIENTS / (IS_MF(bp) ? 4 : 1));
+
if (!BP_NOMCP(bp)) {
bnx2x_get_port_hwinfo(bp);
- bp->fw_seq = (SHMEM_RD(bp, func_mb[func].drv_mb_header) &
- DRV_MSG_SEQ_NUMBER_MASK);
+ bp->fw_seq =
+ (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
+ DRV_MSG_SEQ_NUMBER_MASK);
BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
}
- if (IS_E1HMF(bp)) {
- val2 = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_upper);
- val = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_lower);
+ if (IS_MF(bp)) {
+ val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper);
+ val = MF_CFG_RD(bp, func_mf_config[func].mac_lower);
if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) &&
(val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) {
bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
@@ -6709,7 +8337,7 @@ out_not_found:
static int __devinit bnx2x_init_bp(struct bnx2x *bp)
{
- int func = BP_FUNC(bp);
+ int func;
int timer_interval;
int rc;
@@ -6729,7 +8357,13 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
rc = bnx2x_get_hwinfo(bp);
+ if (!rc)
+ rc = bnx2x_alloc_mem_bp(bp);
+
bnx2x_read_fwinfo(bp);
+
+ func = BP_FUNC(bp);
+
/* need to reset chip if undi was active */
if (!BP_NOMCP(bp))
bnx2x_undi_unload(bp);
@@ -6771,13 +8405,12 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
bp->mrrs = mrrs;
bp->tx_ring_size = MAX_TX_AVAIL;
- bp->rx_ring_size = MAX_RX_AVAIL;
bp->rx_csum = 1;
/* make sure that the numbers are in the right granularity */
- bp->tx_ticks = (50 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR);
- bp->rx_ticks = (25 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR);
+ bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR;
+ bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR;
timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
bp->current_interval = (poll ? poll : timer_interval);
@@ -6869,81 +8502,22 @@ void bnx2x_set_rx_mode(struct net_device *dev)
if (dev->flags & IFF_PROMISC)
rx_mode = BNX2X_RX_MODE_PROMISC;
-
else if ((dev->flags & IFF_ALLMULTI) ||
((netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) &&
CHIP_IS_E1(bp)))
rx_mode = BNX2X_RX_MODE_ALLMULTI;
-
else { /* some multicasts */
if (CHIP_IS_E1(bp)) {
- int i, old, offset;
- struct netdev_hw_addr *ha;
- struct mac_configuration_cmd *config =
- bnx2x_sp(bp, mcast_config);
-
- i = 0;
- netdev_for_each_mc_addr(ha, dev) {
- config->config_table[i].
- cam_entry.msb_mac_addr =
- swab16(*(u16 *)&ha->addr[0]);
- config->config_table[i].
- cam_entry.middle_mac_addr =
- swab16(*(u16 *)&ha->addr[2]);
- config->config_table[i].
- cam_entry.lsb_mac_addr =
- swab16(*(u16 *)&ha->addr[4]);
- config->config_table[i].cam_entry.flags =
- cpu_to_le16(port);
- config->config_table[i].
- target_table_entry.flags = 0;
- config->config_table[i].target_table_entry.
- clients_bit_vector =
- cpu_to_le32(1 << BP_L_ID(bp));
- config->config_table[i].
- target_table_entry.vlan_id = 0;
-
- DP(NETIF_MSG_IFUP,
- "setting MCAST[%d] (%04x:%04x:%04x)\n", i,
- config->config_table[i].
- cam_entry.msb_mac_addr,
- config->config_table[i].
- cam_entry.middle_mac_addr,
- config->config_table[i].
- cam_entry.lsb_mac_addr);
- i++;
- }
- old = config->hdr.length;
- if (old > i) {
- for (; i < old; i++) {
- if (CAM_IS_INVALID(config->
- config_table[i])) {
- /* already invalidated */
- break;
- }
- /* invalidate */
- CAM_INVALIDATE(config->
- config_table[i]);
- }
- }
-
- if (CHIP_REV_IS_SLOW(bp))
- offset = BNX2X_MAX_EMUL_MULTI*(1 + port);
- else
- offset = BNX2X_MAX_MULTICAST*(1 + port);
-
- config->hdr.length = i;
- config->hdr.offset = offset;
- config->hdr.client_id = bp->fp->cl_id;
- config->hdr.reserved1 = 0;
-
- bp->set_mac_pending++;
- smp_wmb();
+ /*
+ * set mc list, do not wait as wait implies sleep
+ * and set_rx_mode can be invoked from non-sleepable
+ * context
+ */
+ u8 offset = (CHIP_REV_IS_SLOW(bp) ?
+ BNX2X_MAX_EMUL_MULTI*(1 + port) :
+ BNX2X_MAX_MULTICAST*(1 + port));
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
- U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
- U64_LO(bnx2x_sp_mapping(bp, mcast_config)),
- 0);
+ bnx2x_set_e1_mc_list(bp, offset);
} else { /* E1H */
/* Accept one or more multicasts */
struct netdev_hw_addr *ha;
@@ -6955,9 +8529,10 @@ void bnx2x_set_rx_mode(struct net_device *dev)
netdev_for_each_mc_addr(ha, dev) {
DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n",
- ha->addr);
+ bnx2x_mc_addr(ha));
- crc = crc32c_le(0, ha->addr, ETH_ALEN);
+ crc = crc32c_le(0, bnx2x_mc_addr(ha),
+ ETH_ALEN);
bit = (crc >> 24) & 0xff;
regidx = bit >> 5;
bit &= 0x1f;
@@ -6974,7 +8549,6 @@ void bnx2x_set_rx_mode(struct net_device *dev)
bnx2x_set_storm_rx_mode(bp);
}
-
/* called with rtnl_lock */
static int bnx2x_mdio_read(struct net_device *netdev, int prtad,
int devad, u16 addr)
@@ -6982,23 +8556,15 @@ static int bnx2x_mdio_read(struct net_device *netdev, int prtad,
struct bnx2x *bp = netdev_priv(netdev);
u16 value;
int rc;
- u32 phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
DP(NETIF_MSG_LINK, "mdio_read: prtad 0x%x, devad 0x%x, addr 0x%x\n",
prtad, devad, addr);
- if (prtad != bp->mdio.prtad) {
- DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n",
- prtad, bp->mdio.prtad);
- return -EINVAL;
- }
-
/* The HW expects different devad if CL22 is used */
devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad;
bnx2x_acquire_phy_lock(bp);
- rc = bnx2x_cl45_read(bp, BP_PORT(bp), phy_type, prtad,
- devad, addr, &value);
+ rc = bnx2x_phy_read(&bp->link_params, prtad, devad, addr, &value);
bnx2x_release_phy_lock(bp);
DP(NETIF_MSG_LINK, "mdio_read_val 0x%x rc = 0x%x\n", value, rc);
@@ -7012,24 +8578,16 @@ static int bnx2x_mdio_write(struct net_device *netdev, int prtad, int devad,
u16 addr, u16 value)
{
struct bnx2x *bp = netdev_priv(netdev);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
int rc;
DP(NETIF_MSG_LINK, "mdio_write: prtad 0x%x, devad 0x%x, addr 0x%x,"
" value 0x%x\n", prtad, devad, addr, value);
- if (prtad != bp->mdio.prtad) {
- DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n",
- prtad, bp->mdio.prtad);
- return -EINVAL;
- }
-
/* The HW expects different devad if CL22 is used */
devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad;
bnx2x_acquire_phy_lock(bp);
- rc = bnx2x_cl45_write(bp, BP_PORT(bp), ext_phy_type, prtad,
- devad, addr, value);
+ rc = bnx2x_phy_write(&bp->link_params, prtad, devad, addr, value);
bnx2x_release_phy_lock(bp);
return rc;
}
@@ -7070,9 +8628,6 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_do_ioctl = bnx2x_ioctl,
.ndo_change_mtu = bnx2x_change_mtu,
.ndo_tx_timeout = bnx2x_tx_timeout,
-#ifdef BCM_VLAN
- .ndo_vlan_rx_register = bnx2x_vlan_rx_register,
-#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = poll_bnx2x,
#endif
@@ -7090,7 +8645,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
bp->dev = dev;
bp->pdev = pdev;
bp->flags = 0;
- bp->func = PCI_FUNC(pdev->devfn);
+ bp->pf_num = PCI_FUNC(pdev->devfn);
rc = pci_enable_device(pdev);
if (rc) {
@@ -7172,7 +8727,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
}
bp->doorbells = ioremap_nocache(pci_resource_start(pdev, 2),
- min_t(u64, BNX2X_DB_SIZE,
+ min_t(u64, BNX2X_DB_SIZE(bp),
pci_resource_len(pdev, 2)));
if (!bp->doorbells) {
dev_err(&bp->pdev->dev,
@@ -7204,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
dev->features |= NETIF_F_HIGHDMA;
dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
dev->features |= NETIF_F_TSO6;
-#ifdef BCM_VLAN
dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
- bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
dev->vlan_features |= NETIF_F_SG;
dev->vlan_features |= NETIF_F_HW_CSUM;
@@ -7214,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
dev->vlan_features |= NETIF_F_HIGHDMA;
dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
dev->vlan_features |= NETIF_F_TSO6;
-#endif
/* get_port_hwinfo() will set prtad and mmds properly */
bp->mdio.prtad = MDIO_PRTAD_NONE;
@@ -7259,7 +8811,7 @@ static void __devinit bnx2x_get_pcie_width_speed(struct bnx2x *bp,
*speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
}
-static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
+static int bnx2x_check_firmware(struct bnx2x *bp)
{
const struct firmware *firmware = bp->firmware;
struct bnx2x_fw_file_hdr *fw_hdr;
@@ -7348,6 +8900,30 @@ static inline void bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n)
}
}
+/**
+ * IRO array is stored in the following format:
+ * {base(24bit), m1(16bit), m2(16bit), m3(16bit), size(16bit) }
+ */
+static inline void bnx2x_prep_iro(const u8 *_source, u8 *_target, u32 n)
+{
+ const __be32 *source = (const __be32 *)_source;
+ struct iro *target = (struct iro *)_target;
+ u32 i, j, tmp;
+
+ for (i = 0, j = 0; i < n/sizeof(struct iro); i++) {
+ target[i].base = be32_to_cpu(source[j]);
+ j++;
+ tmp = be32_to_cpu(source[j]);
+ target[i].m1 = (tmp >> 16) & 0xffff;
+ target[i].m2 = tmp & 0xffff;
+ j++;
+ tmp = be32_to_cpu(source[j]);
+ target[i].m3 = (tmp >> 16) & 0xffff;
+ target[i].size = tmp & 0xffff;
+ j++;
+ }
+}
+
static inline void be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
{
const __be16 *source = (const __be16 *)_source;
@@ -7370,7 +8946,7 @@ do { \
(u8 *)bp->arr, len); \
} while (0)
-static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
+int bnx2x_init_firmware(struct bnx2x *bp)
{
const char *fw_file_name;
struct bnx2x_fw_file_hdr *fw_hdr;
@@ -7380,22 +8956,24 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
fw_file_name = FW_FILE_NAME_E1;
else if (CHIP_IS_E1H(bp))
fw_file_name = FW_FILE_NAME_E1H;
+ else if (CHIP_IS_E2(bp))
+ fw_file_name = FW_FILE_NAME_E2;
else {
- dev_err(dev, "Unsupported chip revision\n");
+ BNX2X_ERR("Unsupported chip revision\n");
return -EINVAL;
}
- dev_info(dev, "Loading %s\n", fw_file_name);
+ BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
- rc = request_firmware(&bp->firmware, fw_file_name, dev);
+ rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev);
if (rc) {
- dev_err(dev, "Can't load firmware file %s\n", fw_file_name);
+ BNX2X_ERR("Can't load firmware file %s\n", fw_file_name);
goto request_firmware_exit;
}
rc = bnx2x_check_firmware(bp);
if (rc) {
- dev_err(dev, "Corrupt firmware file %s\n", fw_file_name);
+ BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name);
goto request_firmware_exit;
}
@@ -7429,9 +9007,13 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
be32_to_cpu(fw_hdr->csem_int_table_data.offset);
INIT_CSEM_PRAM_DATA(bp) = bp->firmware->data +
be32_to_cpu(fw_hdr->csem_pram_data.offset);
+ /* IRO */
+ BNX2X_ALLOC_AND_SET(iro_arr, iro_alloc_err, bnx2x_prep_iro);
return 0;
+iro_alloc_err:
+ kfree(bp->init_ops_offsets);
init_offsets_alloc_err:
kfree(bp->init_ops);
init_ops_alloc_err:
@@ -7442,6 +9024,15 @@ request_firmware_exit:
return rc;
}
+static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp, int l2_cid_count)
+{
+ int cid_count = L2_FP_COUNT(l2_cid_count);
+
+#ifdef BCM_CNIC
+ cid_count += CNIC_CID_MAX;
+#endif
+ return roundup(cid_count, QM_CID_ROUND);
+}
static int __devinit bnx2x_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -7449,10 +9040,30 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
struct net_device *dev = NULL;
struct bnx2x *bp;
int pcie_width, pcie_speed;
- int rc;
+ int rc, cid_count;
+
+ switch (ent->driver_data) {
+ case BCM57710:
+ case BCM57711:
+ case BCM57711E:
+ cid_count = FP_SB_MAX_E1x;
+ break;
+
+ case BCM57712:
+ case BCM57712E:
+ cid_count = FP_SB_MAX_E2;
+ break;
+
+ default:
+ pr_err("Unknown board_type (%ld), aborting\n",
+ ent->driver_data);
+ return ENODEV;
+ }
+
+ cid_count += CNIC_CONTEXT_USE;
/* dev zeroed in init_etherdev */
- dev = alloc_etherdev_mq(sizeof(*bp), MAX_CONTEXT);
+ dev = alloc_etherdev_mq(sizeof(*bp), cid_count);
if (!dev) {
dev_err(&pdev->dev, "Cannot allocate net device\n");
return -ENOMEM;
@@ -7463,6 +9074,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
pci_set_drvdata(pdev, dev);
+ bp->l2_cid_count = cid_count;
+
rc = bnx2x_init_dev(pdev, dev);
if (rc < 0) {
free_netdev(dev);
@@ -7473,12 +9086,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
if (rc)
goto init_one_exit;
- /* Set init arrays */
- rc = bnx2x_init_firmware(bp, &pdev->dev);
- if (rc) {
- dev_err(&pdev->dev, "Error loading firmware\n");
- goto init_one_exit;
- }
+ /* calc qm_cid_count */
+ bp->qm_cid_count = bnx2x_set_qm_cid_count(bp, cid_count);
rc = register_netdev(dev);
if (rc) {
@@ -7486,11 +9095,23 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
goto init_one_exit;
}
+ /* Configure interupt mode: try to enable MSI-X/MSI if
+ * needed, set bp->num_queues appropriately.
+ */
+ bnx2x_set_int_mode(bp);
+
+ /* Add all NAPI objects */
+ bnx2x_add_all_napi(bp);
+
bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed);
+
netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx,"
" IRQ %d, ", board_info[ent->driver_data].name,
(CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
- pcie_width, (pcie_speed == 2) ? "5GHz (Gen2)" : "2.5GHz",
+ pcie_width,
+ ((!CHIP_IS_E2(bp) && pcie_speed == 2) ||
+ (CHIP_IS_E2(bp) && pcie_speed == 1)) ?
+ "5GHz (Gen2)" : "2.5GHz",
dev->base_addr, bp->pdev->irq);
pr_cont("node addr %pM\n", dev->dev_addr);
@@ -7527,20 +9148,23 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
unregister_netdev(dev);
+ /* Delete all NAPI objects */
+ bnx2x_del_all_napi(bp);
+
+ /* Disable MSI/MSI-X */
+ bnx2x_disable_msi(bp);
+
/* Make sure RESET task is not scheduled before continuing */
cancel_delayed_work_sync(&bp->reset_task);
- kfree(bp->init_ops_offsets);
- kfree(bp->init_ops);
- kfree(bp->init_data);
- release_firmware(bp->firmware);
-
if (bp->regview)
iounmap(bp->regview);
if (bp->doorbells)
iounmap(bp->doorbells);
+ bnx2x_free_mem_bp(bp);
+
free_netdev(dev);
if (atomic_read(&pdev->enable_cnt) == 1)
@@ -7566,22 +9190,14 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
/* Release IRQs */
- bnx2x_free_irq(bp, false);
-
- if (CHIP_IS_E1(bp)) {
- struct mac_configuration_cmd *config =
- bnx2x_sp(bp, mcast_config);
-
- for (i = 0; i < config->hdr.length; i++)
- CAM_INVALIDATE(config->config_table[i]);
- }
+ bnx2x_free_irq(bp);
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
+
for_each_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
- for_each_queue(bp, i)
- netif_napi_del(&bnx2x_fp(bp, i, napi));
+
bnx2x_free_mem(bp);
bp->state = BNX2X_STATE_CLOSED;
@@ -7613,8 +9229,9 @@ static void bnx2x_eeh_recover(struct bnx2x *bp)
BNX2X_ERR("BAD MCP validity signature\n");
if (!BP_NOMCP(bp)) {
- bp->fw_seq = (SHMEM_RD(bp, func_mb[BP_FUNC(bp)].drv_mb_header)
- & DRV_MSG_SEQ_NUMBER_MASK);
+ bp->fw_seq =
+ (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
+ DRV_MSG_SEQ_NUMBER_MASK);
BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
}
}
@@ -7697,7 +9314,8 @@ static void bnx2x_io_resume(struct pci_dev *pdev)
struct bnx2x *bp = netdev_priv(dev);
if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
- printk(KERN_ERR "Handling parity error recovery. Try again later\n");
+ printk(KERN_ERR "Handling parity error recovery. "
+ "Try again later\n");
return;
}
@@ -7772,19 +9390,53 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count)
#endif
spin_lock_bh(&bp->spq_lock);
+ BUG_ON(bp->cnic_spq_pending < count);
bp->cnic_spq_pending -= count;
- for (; bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending;
- bp->cnic_spq_pending++) {
- if (!bp->cnic_kwq_pending)
+ for (; bp->cnic_kwq_pending; bp->cnic_kwq_pending--) {
+ u16 type = (le16_to_cpu(bp->cnic_kwq_cons->hdr.type)
+ & SPE_HDR_CONN_TYPE) >>
+ SPE_HDR_CONN_TYPE_SHIFT;
+
+ /* Set validation for iSCSI L2 client before sending SETUP
+ * ramrod
+ */
+ if (type == ETH_CONNECTION_TYPE) {
+ u8 cmd = (le32_to_cpu(bp->cnic_kwq_cons->
+ hdr.conn_and_cmd_data) >>
+ SPE_HDR_CMD_ID_SHIFT) & 0xff;
+
+ if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP)
+ bnx2x_set_ctx_validation(&bp->context.
+ vcxt[BNX2X_ISCSI_ETH_CID].eth,
+ HW_CID(bp, BNX2X_ISCSI_ETH_CID));
+ }
+
+ /* There may be not more than 8 L2 and COMMON SPEs and not more
+ * than 8 L5 SPEs in the air.
+ */
+ if ((type == NONE_CONNECTION_TYPE) ||
+ (type == ETH_CONNECTION_TYPE)) {
+ if (!atomic_read(&bp->spq_left))
+ break;
+ else
+ atomic_dec(&bp->spq_left);
+ } else if (type == ISCSI_CONNECTION_TYPE) {
+ if (bp->cnic_spq_pending >=
+ bp->cnic_eth_dev.max_kwqe_pending)
+ break;
+ else
+ bp->cnic_spq_pending++;
+ } else {
+ BNX2X_ERR("Unknown SPE type: %d\n", type);
+ bnx2x_panic();
break;
+ }
spe = bnx2x_sp_get_next(bp);
*spe = *bp->cnic_kwq_cons;
- bp->cnic_kwq_pending--;
-
DP(NETIF_MSG_TIMER, "pending on SPQ %d, on KWQ %d count %d\n",
bp->cnic_spq_pending, bp->cnic_kwq_pending, count);
@@ -7822,8 +9474,8 @@ static int bnx2x_cnic_sp_queue(struct net_device *dev,
DP(NETIF_MSG_TIMER, "L5 SPQE %x %x %x:%x pos %d\n",
spe->hdr.conn_and_cmd_data, spe->hdr.type,
- spe->data.mac_config_addr.hi,
- spe->data.mac_config_addr.lo,
+ spe->data.update_data_addr.hi,
+ spe->data.update_data_addr.lo,
bp->cnic_kwq_pending);
if (bp->cnic_kwq_prod == bp->cnic_kwq_last)
@@ -7889,7 +9541,7 @@ static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid)
ctl.data.comp.cid = cid;
bnx2x_cnic_ctl_send_bh(bp, &ctl);
- bnx2x_cnic_sp_post(bp, 1);
+ bnx2x_cnic_sp_post(bp, 0);
}
static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
@@ -7906,8 +9558,8 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
break;
}
- case DRV_CTL_COMPLETION_CMD: {
- int count = ctl->data.comp.comp_count;
+ case DRV_CTL_RET_L5_SPQ_CREDIT_CMD: {
+ int count = ctl->data.credit.credit_count;
bnx2x_cnic_sp_post(bp, count);
break;
@@ -7917,8 +9569,24 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
case DRV_CTL_START_L2_CMD: {
u32 cli = ctl->data.ring.client_id;
- bp->rx_mode_cl_mask |= (1 << cli);
- bnx2x_set_storm_rx_mode(bp);
+ /* Set iSCSI MAC address */
+ bnx2x_set_iscsi_eth_mac_addr(bp, 1);
+
+ mmiowb();
+ barrier();
+
+ /* Start accepting on iSCSI L2 ring. Accept all multicasts
+ * because it's the only way for UIO Client to accept
+ * multicasts (in non-promiscuous mode only one Client per
+ * function will receive multicast packets (leading in our
+ * case).
+ */
+ bnx2x_rxq_set_mac_filters(bp, cli,
+ BNX2X_ACCEPT_UNICAST |
+ BNX2X_ACCEPT_BROADCAST |
+ BNX2X_ACCEPT_ALL_MULTICAST);
+ storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp));
+
break;
}
@@ -7926,8 +9594,23 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
case DRV_CTL_STOP_L2_CMD: {
u32 cli = ctl->data.ring.client_id;
- bp->rx_mode_cl_mask &= ~(1 << cli);
- bnx2x_set_storm_rx_mode(bp);
+ /* Stop accepting on iSCSI L2 ring */
+ bnx2x_rxq_set_mac_filters(bp, cli, BNX2X_ACCEPT_NONE);
+ storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp));
+
+ mmiowb();
+ barrier();
+
+ /* Unset iSCSI L2 MAC */
+ bnx2x_set_iscsi_eth_mac_addr(bp, 0);
+ break;
+ }
+ case DRV_CTL_RET_L2_SPQ_CREDIT_CMD: {
+ int count = ctl->data.credit.credit_count;
+
+ smp_mb__before_atomic_inc();
+ atomic_add(count, &bp->spq_left);
+ smp_mb__after_atomic_inc();
break;
}
@@ -7951,10 +9634,16 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp)
cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX;
cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX;
}
- cp->irq_arr[0].status_blk = bp->cnic_sb;
+ if (CHIP_IS_E2(bp))
+ cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e2_sb;
+ else
+ cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e1x_sb;
+
cp->irq_arr[0].status_blk_num = CNIC_SB_ID(bp);
+ cp->irq_arr[0].status_blk_num2 = CNIC_IGU_SB_ID(bp);
cp->irq_arr[1].status_blk = bp->def_status_blk;
cp->irq_arr[1].status_blk_num = DEF_SB_ID;
+ cp->irq_arr[1].status_blk_num2 = DEF_SB_IGU_ID;
cp->num_irq = 2;
}
@@ -7986,12 +9675,10 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops,
cp->num_irq = 0;
cp->drv_state = CNIC_DRV_STATE_REGD;
-
- bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, CNIC_SB_ID(bp));
+ cp->iro_arr = bp->iro_arr;
bnx2x_setup_cnic_irq_info(bp);
- bnx2x_set_iscsi_eth_mac_addr(bp, 1);
- bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET;
+
rcu_assign_pointer(bp->cnic_ops, ops);
return 0;
@@ -8028,15 +9715,24 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev)
cp->io_base = bp->regview;
cp->io_base2 = bp->doorbells;
cp->max_kwqe_pending = 8;
- cp->ctx_blk_size = CNIC_CTX_PER_ILT * sizeof(union cdu_context);
- cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + 1;
+ cp->ctx_blk_size = CDU_ILT_PAGE_SZ;
+ cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) +
+ bnx2x_cid_ilt_lines(bp);
cp->ctx_tbl_len = CNIC_ILT_LINES;
- cp->starting_cid = BCM_CNIC_CID_START;
+ cp->starting_cid = bnx2x_cid_ilt_lines(bp) * ILT_PAGE_CIDS;
cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue;
cp->drv_ctl = bnx2x_drv_ctl;
cp->drv_register_cnic = bnx2x_register_cnic;
cp->drv_unregister_cnic = bnx2x_unregister_cnic;
-
+ cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID;
+ cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID;
+
+ DP(BNX2X_MSG_SP, "page_size %d, tbl_offset %d, tbl_lines %d, "
+ "starting cid %d\n",
+ cp->ctx_blk_size,
+ cp->ctx_tbl_offset,
+ cp->ctx_tbl_len,
+ cp->starting_cid);
return cp;
}
EXPORT_SYMBOL(bnx2x_cnic_probe);
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h
index a1f3bf0cd630..1cefe489a955 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-2009 Broadcom Corporation
+ * Copyright (c) 2007-2010 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
@@ -19,7 +19,20 @@
*
*/
-
+#define ATC_ATC_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define ATC_ATC_INT_STS_REG_ATC_GPA_MULTIPLE_HITS (0x1<<2)
+#define ATC_ATC_INT_STS_REG_ATC_IREQ_LESS_THAN_STU (0x1<<5)
+#define ATC_ATC_INT_STS_REG_ATC_RCPL_TO_EMPTY_CNT (0x1<<3)
+#define ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR (0x1<<4)
+#define ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND (0x1<<1)
+/* [RW 1] Initiate the ATC array - reset all the valid bits */
+#define ATC_REG_ATC_INIT_ARRAY 0x1100b8
+/* [R 1] ATC initalization done */
+#define ATC_REG_ATC_INIT_DONE 0x1100bc
+/* [RC 6] Interrupt register #0 read clear */
+#define ATC_REG_ATC_INT_STS_CLR 0x1101c0
+/* [RW 19] Interrupt mask register #0 read/write */
+#define BRB1_REG_BRB1_INT_MASK 0x60128
/* [R 19] Interrupt register #0 read */
#define BRB1_REG_BRB1_INT_STS 0x6011c
/* [RW 4] Parity mask register #0 read/write */
@@ -27,9 +40,31 @@
/* [R 4] Parity register #0 read */
#define BRB1_REG_BRB1_PRTY_STS 0x6012c
/* [RW 10] At address BRB1_IND_FREE_LIST_PRS_CRDT initialize free head. At
- address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address
- BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */
+ * address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address
+ * BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. Warning -
+ * following reset the first rbc access to this reg must be write; there can
+ * be no more rbc writes after the first one; there can be any number of rbc
+ * read following the first write; rbc access not following these rules will
+ * result in hang condition. */
#define BRB1_REG_FREE_LIST_PRS_CRDT 0x60200
+/* [RW 10] The number of free blocks below which the full signal to class 0
+ * is asserted */
+#define BRB1_REG_FULL_0_XOFF_THRESHOLD_0 0x601d0
+/* [RW 10] The number of free blocks above which the full signal to class 0
+ * is de-asserted */
+#define BRB1_REG_FULL_0_XON_THRESHOLD_0 0x601d4
+/* [RW 10] The number of free blocks below which the full signal to class 1
+ * is asserted */
+#define BRB1_REG_FULL_1_XOFF_THRESHOLD_0 0x601d8
+/* [RW 10] The number of free blocks above which the full signal to class 1
+ * is de-asserted */
+#define BRB1_REG_FULL_1_XON_THRESHOLD_0 0x601dc
+/* [RW 10] The number of free blocks below which the full signal to the LB
+ * port is asserted */
+#define BRB1_REG_FULL_LB_XOFF_THRESHOLD 0x601e0
+/* [RW 10] The number of free blocks above which the full signal to the LB
+ * port is de-asserted */
+#define BRB1_REG_FULL_LB_XON_THRESHOLD 0x601e4
/* [RW 10] The number of free blocks above which the High_llfc signal to
interface #n is de-asserted. */
#define BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD_0 0x6014c
@@ -44,6 +79,9 @@
/* [RW 10] The number of free blocks below which the Low_llfc signal to
interface #n is asserted. */
#define BRB1_REG_LOW_LLFC_LOW_THRESHOLD_0 0x6015c
+/* [RW 10] The number of blocks guarantied for the MAC port */
+#define BRB1_REG_MAC_GUARANTIED_0 0x601e8
+#define BRB1_REG_MAC_GUARANTIED_1 0x60240
/* [R 24] The number of full blocks. */
#define BRB1_REG_NUM_OF_FULL_BLOCKS 0x60090
/* [ST 32] The number of cycles that the write_full signal towards MAC #0
@@ -55,7 +93,19 @@
asserted. */
#define BRB1_REG_NUM_OF_PAUSE_CYCLES_0 0x600b8
#define BRB1_REG_NUM_OF_PAUSE_CYCLES_1 0x600bc
-/* [RW 10] Write client 0: De-assert pause threshold. */
+/* [RW 10] The number of free blocks below which the pause signal to class 0
+ * is asserted */
+#define BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 0x601c0
+/* [RW 10] The number of free blocks above which the pause signal to class 0
+ * is de-asserted */
+#define BRB1_REG_PAUSE_0_XON_THRESHOLD_0 0x601c4
+/* [RW 10] The number of free blocks below which the pause signal to class 1
+ * is asserted */
+#define BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0 0x601c8
+/* [RW 10] The number of free blocks above which the pause signal to class 1
+ * is de-asserted */
+#define BRB1_REG_PAUSE_1_XON_THRESHOLD_0 0x601cc
+/* [RW 10] Write client 0: De-assert pause threshold. Not Functional */
#define BRB1_REG_PAUSE_HIGH_THRESHOLD_0 0x60078
#define BRB1_REG_PAUSE_HIGH_THRESHOLD_1 0x6007c
/* [RW 10] Write client 0: Assert pause threshold. */
@@ -362,6 +412,7 @@
#define CFC_REG_NUM_LCIDS_ARRIVING 0x104004
/* [R 9] Number of Leaving LCIDs in Link List Block */
#define CFC_REG_NUM_LCIDS_LEAVING 0x104018
+#define CFC_REG_WEAK_ENABLE_PF 0x104124
/* [RW 8] The event id for aggregated interrupt 0 */
#define CSDM_REG_AGG_INT_EVENT_0 0xc2038
#define CSDM_REG_AGG_INT_EVENT_10 0xc2060
@@ -590,10 +641,17 @@
#define CSEM_REG_TS_8_AS 0x200058
/* [RW 3] The arbitration scheme of time_slot 9 */
#define CSEM_REG_TS_9_AS 0x20005c
+/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64
+ * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */
+#define CSEM_REG_VFPF_ERR_NUM 0x200380
/* [RW 1] Parity mask register #0 read/write */
#define DBG_REG_DBG_PRTY_MASK 0xc0a8
/* [R 1] Parity register #0 read */
#define DBG_REG_DBG_PRTY_STS 0xc09c
+/* [RW 1] When set the DMAE will process the commands as in E1.5. 1.The
+ * function that is used is always SRC-PCI; 2.VF_Valid = 0; 3.VFID=0;
+ * 4.Completion function=0; 5.Error handling=0 */
+#define DMAE_REG_BACKWARD_COMP_EN 0x10207c
/* [RW 32] Commands memory. The address to command X; row Y is to calculated
as 14*X+Y. */
#define DMAE_REG_CMD_MEM 0x102400
@@ -742,9 +800,13 @@
#define HC_REG_HC_PRTY_MASK 0x1080a0
/* [R 3] Parity register #0 read */
#define HC_REG_HC_PRTY_STS 0x108094
-#define HC_REG_INT_MASK 0x108108
+/* [RC 3] Parity register #0 read clear */
+#define HC_REG_HC_PRTY_STS_CLR 0x108098
+#define HC_REG_INT_MASK 0x108108
#define HC_REG_LEADING_EDGE_0 0x108040
#define HC_REG_LEADING_EDGE_1 0x108048
+#define HC_REG_MAIN_MEMORY 0x108800
+#define HC_REG_MAIN_MEMORY_SIZE 152
#define HC_REG_P0_PROD_CONS 0x108200
#define HC_REG_P1_PROD_CONS 0x108400
#define HC_REG_PBA_COMMAND 0x108140
@@ -758,6 +820,92 @@
#define HC_REG_USTORM_ADDR_FOR_COALESCE 0x108068
#define HC_REG_VQID_0 0x108008
#define HC_REG_VQID_1 0x10800c
+#define IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN (0x1<<1)
+#define IGU_REG_ATTENTION_ACK_BITS 0x130108
+/* [R 4] Debug: attn_fsm */
+#define IGU_REG_ATTN_FSM 0x130054
+#define IGU_REG_ATTN_MSG_ADDR_H 0x13011c
+#define IGU_REG_ATTN_MSG_ADDR_L 0x130120
+/* [R 4] Debug: [3] - attention write done message is pending (0-no pending;
+ * 1-pending). [2:0] = PFID. Pending means attention message was sent; but
+ * write done didnt receive. */
+#define IGU_REG_ATTN_WRITE_DONE_PENDING 0x130030
+#define IGU_REG_BLOCK_CONFIGURATION 0x130000
+#define IGU_REG_COMMAND_REG_32LSB_DATA 0x130124
+#define IGU_REG_COMMAND_REG_CTRL 0x13012c
+/* [WB_R 32] Cleanup bit status per SB. 1 = cleanup is set. 0 = cleanup bit
+ * is clear. The bits in this registers are set and clear via the producer
+ * command. Data valid only in addresses 0-4. all the rest are zero. */
+#define IGU_REG_CSTORM_TYPE_0_SB_CLEANUP 0x130200
+/* [R 5] Debug: ctrl_fsm */
+#define IGU_REG_CTRL_FSM 0x130064
+/* [R 1] data availble for error memory. If this bit is clear do not red
+ * from error_handling_memory. */
+#define IGU_REG_ERROR_HANDLING_DATA_VALID 0x130130
+/* [R 11] Parity register #0 read */
+#define IGU_REG_IGU_PRTY_STS 0x13009c
+/* [R 4] Debug: int_handle_fsm */
+#define IGU_REG_INT_HANDLE_FSM 0x130050
+#define IGU_REG_LEADING_EDGE_LATCH 0x130134
+/* [RW 14] mapping CAM; relevant for E2 operating mode only. [0] - valid.
+ * [6:1] - vector number; [13:7] - FID (if VF - [13] = 0; [12:7] = VF
+ * number; if PF - [13] = 1; [12:10] = 0; [9:7] = PF number); */
+#define IGU_REG_MAPPING_MEMORY 0x131000
+#define IGU_REG_MAPPING_MEMORY_SIZE 136
+#define IGU_REG_PBA_STATUS_LSB 0x130138
+#define IGU_REG_PBA_STATUS_MSB 0x13013c
+#define IGU_REG_PCI_PF_MSI_EN 0x130140
+#define IGU_REG_PCI_PF_MSIX_EN 0x130144
+#define IGU_REG_PCI_PF_MSIX_FUNC_MASK 0x130148
+/* [WB_R 32] Each bit represent the pending bits status for that SB. 0 = no
+ * pending; 1 = pending. Pendings means interrupt was asserted; and write
+ * done was not received. Data valid only in addresses 0-4. all the rest are
+ * zero. */
+#define IGU_REG_PENDING_BITS_STATUS 0x130300
+#define IGU_REG_PF_CONFIGURATION 0x130154
+/* [RW 20] producers only. E2 mode: address 0-135 match to the mapping
+ * memory; 136 - PF0 default prod; 137 PF1 default prod; 138 - PF2 default
+ * prod; 139 PF3 default prod; 140 - PF0 - ATTN prod; 141 - PF1 - ATTN prod;
+ * 142 - PF2 - ATTN prod; 143 - PF3 - ATTN prod; 144-147 reserved. E1.5 mode
+ * - In backward compatible mode; for non default SB; each even line in the
+ * memory holds the U producer and each odd line hold the C producer. The
+ * first 128 producer are for NDSB (PF0 - 0-31; PF1 - 32-63 and so on). The
+ * last 20 producers are for the DSB for each PF. each PF has five segments
+ * (the order inside each segment is PF0; PF1; PF2; PF3) - 128-131 U prods;
+ * 132-135 C prods; 136-139 X prods; 140-143 T prods; 144-147 ATTN prods; */
+#define IGU_REG_PROD_CONS_MEMORY 0x132000
+/* [R 3] Debug: pxp_arb_fsm */
+#define IGU_REG_PXP_ARB_FSM 0x130068
+/* [RW 6] Write one for each bit will reset the appropriate memory. When the
+ * memory reset finished the appropriate bit will be clear. Bit 0 - mapping
+ * memory; Bit 1 - SB memory; Bit 2 - SB interrupt and mask register; Bit 3
+ * - MSIX memory; Bit 4 - PBA memory; Bit 5 - statistics; */
+#define IGU_REG_RESET_MEMORIES 0x130158
+/* [R 4] Debug: sb_ctrl_fsm */
+#define IGU_REG_SB_CTRL_FSM 0x13004c
+#define IGU_REG_SB_INT_BEFORE_MASK_LSB 0x13015c
+#define IGU_REG_SB_INT_BEFORE_MASK_MSB 0x130160
+#define IGU_REG_SB_MASK_LSB 0x130164
+#define IGU_REG_SB_MASK_MSB 0x130168
+/* [RW 16] Number of command that were dropped without causing an interrupt
+ * due to: read access for WO BAR address; or write access for RO BAR
+ * address or any access for reserved address or PCI function error is set
+ * and address is not MSIX; PBA or cleanup */
+#define IGU_REG_SILENT_DROP 0x13016c
+/* [RW 10] Number of MSI/MSIX/ATTN messages sent for the function: 0-63 -
+ * number of MSIX messages per VF; 64-67 - number of MSI/MSIX messages per
+ * PF; 68-71 number of ATTN messages per PF */
+#define IGU_REG_STATISTIC_NUM_MESSAGE_SENT 0x130800
+/* [RW 32] Number of cycles the timer mask masking the IGU interrupt when a
+ * timer mask command arrives. Value must be bigger than 100. */
+#define IGU_REG_TIMER_MASKING_VALUE 0x13003c
+#define IGU_REG_TRAILING_EDGE_LATCH 0x130104
+#define IGU_REG_VF_CONFIGURATION 0x130170
+/* [WB_R 32] Each bit represent write done pending bits status for that SB
+ * (MSI/MSIX message was sent and write done was not received yet). 0 =
+ * clear; 1 = set. Data valid only in addresses 0-4. all the rest are zero. */
+#define IGU_REG_WRITE_DONE_PENDING 0x130480
+#define MCP_A_REG_MCPR_SCRATCH 0x3a0000
#define MCP_REG_MCPR_NVM_ACCESS_ENABLE 0x86424
#define MCP_REG_MCPR_NVM_ADDR 0x8640c
#define MCP_REG_MCPR_NVM_CFG4 0x8642c
@@ -880,6 +1028,11 @@
rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP Latched
ump_tx_parity; [31] MCP Latched scpad_parity; */
#define MISC_REG_AEU_AFTER_INVERT_4_MCP 0xa458
+/* [R 32] Read fifth 32 bit after inversion of function 0. Mapped as
+ * follows: [0] PGLUE config_space; [1] PGLUE misc_flr; [2] PGLUE B RBC
+ * attention [3] PGLUE B RBC parity; [4] ATC attention; [5] ATC parity; [6]
+ * CNIG attention (reserved); [7] CNIG parity (reserved); [31-8] Reserved; */
+#define MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 0xa700
/* [W 14] write to this register results with the clear of the latched
signals; one in d0 clears RBCR latch; one in d1 clears RBCT latch; one in
d2 clears RBCN latch; one in d3 clears RBCU latch; one in d4 clears RBCP
@@ -1251,6 +1404,7 @@
#define MISC_REG_E1HMF_MODE 0xa5f8
/* [RW 32] Debug only: spare RW register reset by core reset */
#define MISC_REG_GENERIC_CR_0 0xa460
+#define MISC_REG_GENERIC_CR_1 0xa464
/* [RW 32] Debug only: spare RW register reset by por reset */
#define MISC_REG_GENERIC_POR_1 0xa474
/* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of
@@ -1373,6 +1527,14 @@
#define MISC_REG_PLL_STORM_CTRL_2 0xa298
#define MISC_REG_PLL_STORM_CTRL_3 0xa29c
#define MISC_REG_PLL_STORM_CTRL_4 0xa2a0
+/* [R 1] Status of 4 port mode enable input pin. */
+#define MISC_REG_PORT4MODE_EN 0xa750
+/* [RW 2] 4 port mode enable overwrite.[0] - Overwrite control; if it is 0 -
+ * the port4mode_en output is equal to 4 port mode input pin; if it is 1 -
+ * the port4mode_en output is equal to bit[1] of this register; [1] -
+ * Overwrite value. If bit[0] of this register is 1 this is the value that
+ * receives the port4mode_en output . */
+#define MISC_REG_PORT4MODE_EN_OVWR 0xa720
/* [RW 32] reset reg#2; rite/read one = the specific block is out of reset;
write/read zero = the specific block is in reset; addr 0-wr- the write
value will be written to the register; addr 1-set - one will be written
@@ -1656,8 +1818,91 @@
/* [R 32] Interrupt register #0 read */
#define NIG_REG_NIG_INT_STS_0 0x103b0
#define NIG_REG_NIG_INT_STS_1 0x103c0
-/* [R 32] Parity register #0 read */
+/* [R 32] Legacy E1 and E1H location for parity error status register. */
#define NIG_REG_NIG_PRTY_STS 0x103d0
+/* [R 32] Parity register #0 read */
+#define NIG_REG_NIG_PRTY_STS_0 0x183bc
+#define NIG_REG_NIG_PRTY_STS_1 0x183cc
+/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic
+ * Ethernet header. */
+#define NIG_REG_P0_HDRS_AFTER_BASIC 0x18038
+/* [RW 1] HW PFC enable bit. Set this bit to enable the PFC functionality in
+ * the NIG. Other flow control modes such as PAUSE and SAFC/LLFC should be
+ * disabled when this bit is set. */
+#define NIG_REG_P0_HWPFC_ENABLE 0x18078
+#define NIG_REG_P0_LLH_FUNC_MEM2 0x18480
+#define NIG_REG_P0_LLH_FUNC_MEM2_ENABLE 0x18440
+/* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for
+ * future expansion) each priorty is to be mapped to. Bits 3:0 specify the
+ * COS for priority 0. Bits 31:28 specify the COS for priority 7. The 3-bit
+ * priority field is extracted from the outer-most VLAN in receive packet.
+ * Only COS 0 and COS 1 are supported in E2. */
+#define NIG_REG_P0_PKT_PRIORITY_TO_COS 0x18054
+/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A
+ * priority is mapped to COS 0 when the corresponding mask bit is 1. More
+ * than one bit may be set; allowing multiple priorities to be mapped to one
+ * COS. */
+#define NIG_REG_P0_RX_COS0_PRIORITY_MASK 0x18058
+/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 1. A
+ * priority is mapped to COS 1 when the corresponding mask bit is 1. More
+ * than one bit may be set; allowing multiple priorities to be mapped to one
+ * COS. */
+#define NIG_REG_P0_RX_COS1_PRIORITY_MASK 0x1805c
+/* [RW 15] Specify which of the credit registers the client is to be mapped
+ * to. Bits[2:0] are for client 0; bits [14:12] are for client 4. For
+ * clients that are not subject to WFQ credit blocking - their
+ * specifications here are not used. */
+#define NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP 0x180f0
+/* [RW 5] Specify whether the client competes directly in the strict
+ * priority arbiter. The bits are mapped according to client ID (client IDs
+ * are defined in tx_arb_priority_client). Default value is set to enable
+ * strict priorities for clients 0-2 -- management and debug traffic. */
+#define NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT 0x180e8
+/* [RW 5] Specify whether the client is subject to WFQ credit blocking. The
+ * bits are mapped according to client ID (client IDs are defined in
+ * tx_arb_priority_client). Default value is 0 for not using WFQ credit
+ * blocking. */
+#define NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ 0x180ec
+/* [RW 32] Specify the upper bound that credit register 0 is allowed to
+ * reach. */
+#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0 0x1810c
+#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1 0x18110
+/* [RW 32] Specify the weight (in bytes) to be added to credit register 0
+ * when it is time to increment. */
+#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0 0x180f8
+#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1 0x180fc
+/* [RW 12] Specify the number of strict priority arbitration slots between
+ * two round-robin arbitration slots to avoid starvation. A value of 0 means
+ * no strict priority cycles - the strict priority with anti-starvation
+ * arbiter becomes a round-robin arbiter. */
+#define NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS 0x180f4
+/* [RW 15] Specify the client number to be assigned to each priority of the
+ * strict priority arbiter. Priority 0 is the highest priority. Bits [2:0]
+ * are for priority 0 client; bits [14:12] are for priority 4 client. The
+ * clients are assigned the following IDs: 0-management; 1-debug traffic
+ * from this port; 2-debug traffic from other port; 3-COS0 traffic; 4-COS1
+ * traffic. The reset value[14:0] is set to 0x4688 (15'b100_011_010_001_000)
+ * for management at priority 0; debug traffic at priorities 1 and 2; COS0
+ * traffic at priority 3; and COS1 traffic at priority 4. */
+#define NIG_REG_P0_TX_ARB_PRIORITY_CLIENT 0x180e4
+#define NIG_REG_P1_LLH_FUNC_MEM2 0x184c0
+#define NIG_REG_P1_LLH_FUNC_MEM2_ENABLE 0x18460
+/* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for
+ * future expansion) each priorty is to be mapped to. Bits 3:0 specify the
+ * COS for priority 0. Bits 31:28 specify the COS for priority 7. The 3-bit
+ * priority field is extracted from the outer-most VLAN in receive packet.
+ * Only COS 0 and COS 1 are supported in E2. */
+#define NIG_REG_P1_PKT_PRIORITY_TO_COS 0x181a8
+/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A
+ * priority is mapped to COS 0 when the corresponding mask bit is 1. More
+ * than one bit may be set; allowing multiple priorities to be mapped to one
+ * COS. */
+#define NIG_REG_P1_RX_COS0_PRIORITY_MASK 0x181ac
+/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 1. A
+ * priority is mapped to COS 1 when the corresponding mask bit is 1. More
+ * than one bit may be set; allowing multiple priorities to be mapped to one
+ * COS. */
+#define NIG_REG_P1_RX_COS1_PRIORITY_MASK 0x181b0
/* [RW 1] Pause enable for port0. This register may get 1 only when
~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same
port */
@@ -1742,6 +1987,10 @@
/* [RW 1] Disable processing further tasks from port 4 (after ending the
current task in process). */
#define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c
+#define PBF_REG_DISABLE_PF 0x1402e8
+/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic
+ * Ethernet header. */
+#define PBF_REG_HDRS_AFTER_BASIC 0x15c0a8
#define PBF_REG_IF_ENABLE_REG 0x140044
/* [RW 1] Init bit. When set the initial credits are copied to the credit
registers (except the port credits). Should be set and then reset after
@@ -1765,6 +2014,8 @@
#define PBF_REG_MAC_IF1_ENABLE 0x140034
/* [RW 1] Enable for the loopback interface. */
#define PBF_REG_MAC_LB_ENABLE 0x140040
+/* [RW 6] Bit-map indicating which headers must appear in the packet */
+#define PBF_REG_MUST_HAVE_HDRS 0x15c0c4
/* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause
not suppoterd. */
#define PBF_REG_P0_ARB_THRSH 0x1400e4
@@ -1804,6 +2055,259 @@
#define PB_REG_PB_PRTY_MASK 0x38
/* [R 4] Parity register #0 read */
#define PB_REG_PB_PRTY_STS 0x2c
+#define PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define PGLUE_B_PGLUE_B_INT_STS_REG_CSSNOOP_FIFO_OVERFLOW (0x1<<8)
+#define PGLUE_B_PGLUE_B_INT_STS_REG_INCORRECT_RCV_BEHAVIOR (0x1<<1)
+#define PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_ERROR_ATTN (0x1<<6)
+#define PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_IN_TWO_RCBS_ATTN (0x1<<7)
+#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_GRC_SPACE_VIOLATION_ATTN (0x1<<4)
+#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_LENGTH_VIOLATION_ATTN (0x1<<3)
+#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_MSIX_BAR_VIOLATION_ATTN (0x1<<5)
+#define PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN (0x1<<2)
+/* [R 8] Config space A attention dirty bits. Each bit indicates that the
+ * corresponding PF generates config space A attention. Set by PXP. Reset by
+ * MCP writing 1 to icfg_space_a_request_clr. Note: register contains bits
+ * from both paths. */
+#define PGLUE_B_REG_CFG_SPACE_A_REQUEST 0x9010
+/* [R 8] Config space B attention dirty bits. Each bit indicates that the
+ * corresponding PF generates config space B attention. Set by PXP. Reset by
+ * MCP writing 1 to icfg_space_b_request_clr. Note: register contains bits
+ * from both paths. */
+#define PGLUE_B_REG_CFG_SPACE_B_REQUEST 0x9014
+/* [RW 1] Type A PF enable inbound interrupt table for CSDM. 0 - disable; 1
+ * - enable. */
+#define PGLUE_B_REG_CSDM_INB_INT_A_PF_ENABLE 0x9194
+/* [RW 18] Type B VF inbound interrupt table for CSDM: bits[17:9]-mask;
+ * its[8:0]-address. Bits [1:0] must be zero (DW resolution address). */
+#define PGLUE_B_REG_CSDM_INB_INT_B_VF 0x916c
+/* [RW 1] Type B VF enable inbound interrupt table for CSDM. 0 - disable; 1
+ * - enable. */
+#define PGLUE_B_REG_CSDM_INB_INT_B_VF_ENABLE 0x919c
+/* [RW 16] Start offset of CSDM zone A (queue zone) in the internal RAM */
+#define PGLUE_B_REG_CSDM_START_OFFSET_A 0x9100
+/* [RW 16] Start offset of CSDM zone B (legacy zone) in the internal RAM */
+#define PGLUE_B_REG_CSDM_START_OFFSET_B 0x9108
+/* [RW 5] VF Shift of CSDM zone B (legacy zone) in the internal RAM */
+#define PGLUE_B_REG_CSDM_VF_SHIFT_B 0x9110
+/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */
+#define PGLUE_B_REG_CSDM_ZONE_A_SIZE_PF 0x91ac
+/* [R 8] FLR request attention dirty bits for PFs 0 to 7. Each bit indicates
+ * that the FLR register of the corresponding PF was set. Set by PXP. Reset
+ * by MCP writing 1 to flr_request_pf_7_0_clr. Note: register contains bits
+ * from both paths. */
+#define PGLUE_B_REG_FLR_REQUEST_PF_7_0 0x9028
+/* [W 8] FLR request attention dirty bits clear for PFs 0 to 7. MCP writes 1
+ * to a bit in this register in order to clear the corresponding bit in
+ * flr_request_pf_7_0 register. Note: register contains bits from both
+ * paths. */
+#define PGLUE_B_REG_FLR_REQUEST_PF_7_0_CLR 0x9418
+/* [R 32] FLR request attention dirty bits for VFs 96 to 127. Each bit
+ * indicates that the FLR register of the corresponding VF was set. Set by
+ * PXP. Reset by MCP writing 1 to flr_request_vf_127_96_clr. */
+#define PGLUE_B_REG_FLR_REQUEST_VF_127_96 0x9024
+/* [R 32] FLR request attention dirty bits for VFs 0 to 31. Each bit
+ * indicates that the FLR register of the corresponding VF was set. Set by
+ * PXP. Reset by MCP writing 1 to flr_request_vf_31_0_clr. */
+#define PGLUE_B_REG_FLR_REQUEST_VF_31_0 0x9018
+/* [R 32] FLR request attention dirty bits for VFs 32 to 63. Each bit
+ * indicates that the FLR register of the corresponding VF was set. Set by
+ * PXP. Reset by MCP writing 1 to flr_request_vf_63_32_clr. */
+#define PGLUE_B_REG_FLR_REQUEST_VF_63_32 0x901c
+/* [R 32] FLR request attention dirty bits for VFs 64 to 95. Each bit
+ * indicates that the FLR register of the corresponding VF was set. Set by
+ * PXP. Reset by MCP writing 1 to flr_request_vf_95_64_clr. */
+#define PGLUE_B_REG_FLR_REQUEST_VF_95_64 0x9020
+/* [R 8] Each bit indicates an incorrect behavior in user RX interface. Bit
+ * 0 - Target memory read arrived with a correctable error. Bit 1 - Target
+ * memory read arrived with an uncorrectable error. Bit 2 - Configuration RW
+ * arrived with a correctable error. Bit 3 - Configuration RW arrived with
+ * an uncorrectable error. Bit 4 - Completion with Configuration Request
+ * Retry Status. Bit 5 - Expansion ROM access received with a write request.
+ * Bit 6 - Completion with pcie_rx_err of 0000; CMPL_STATUS of non-zero; and
+ * pcie_rx_last not asserted. Bit 7 - Completion with pcie_rx_err of 1010;
+ * and pcie_rx_last not asserted. */
+#define PGLUE_B_REG_INCORRECT_RCV_DETAILS 0x9068
+#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER 0x942c
+#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ 0x9430
+#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_WRITE 0x9434
+#define PGLUE_B_REG_INTERNAL_VFID_ENABLE 0x9438
+/* [R 9] Interrupt register #0 read */
+#define PGLUE_B_REG_PGLUE_B_INT_STS 0x9298
+/* [RC 9] Interrupt register #0 read clear */
+#define PGLUE_B_REG_PGLUE_B_INT_STS_CLR 0x929c
+/* [R 2] Parity register #0 read */
+#define PGLUE_B_REG_PGLUE_B_PRTY_STS 0x92a8
+/* [R 13] Details of first request received with error. [2:0] - PFID. [3] -
+ * VF_VALID. [9:4] - VFID. [11:10] - Error Code - 0 - Indicates Completion
+ * Timeout of a User Tx non-posted request. 1 - unsupported request. 2 -
+ * completer abort. 3 - Illegal value for this field. [12] valid - indicates
+ * if there was a completion error since the last time this register was
+ * cleared. */
+#define PGLUE_B_REG_RX_ERR_DETAILS 0x9080
+/* [R 18] Details of first ATS Translation Completion request received with
+ * error. [2:0] - PFID. [3] - VF_VALID. [9:4] - VFID. [11:10] - Error Code -
+ * 0 - Indicates Completion Timeout of a User Tx non-posted request. 1 -
+ * unsupported request. 2 - completer abort. 3 - Illegal value for this
+ * field. [16:12] - ATC OTB EntryID. [17] valid - indicates if there was a
+ * completion error since the last time this register was cleared. */
+#define PGLUE_B_REG_RX_TCPL_ERR_DETAILS 0x9084
+/* [W 8] Debug only - Shadow BME bits clear for PFs 0 to 7. MCP writes 1 to
+ * a bit in this register in order to clear the corresponding bit in
+ * shadow_bme_pf_7_0 register. MCP should never use this unless a
+ * work-around is needed. Note: register contains bits from both paths. */
+#define PGLUE_B_REG_SHADOW_BME_PF_7_0_CLR 0x9458
+/* [R 8] SR IOV disabled attention dirty bits. Each bit indicates that the
+ * VF enable register of the corresponding PF is written to 0 and was
+ * previously 1. Set by PXP. Reset by MCP writing 1 to
+ * sr_iov_disabled_request_clr. Note: register contains bits from both
+ * paths. */
+#define PGLUE_B_REG_SR_IOV_DISABLED_REQUEST 0x9030
+/* [R 32] Indicates the status of tags 32-63. 0 - tags is used - read
+ * completion did not return yet. 1 - tag is unused. Same functionality as
+ * pxp2_registers_pgl_exp_rom_data2 for tags 0-31. */
+#define PGLUE_B_REG_TAGS_63_32 0x9244
+/* [RW 1] Type A PF enable inbound interrupt table for TSDM. 0 - disable; 1
+ * - enable. */
+#define PGLUE_B_REG_TSDM_INB_INT_A_PF_ENABLE 0x9170
+/* [RW 16] Start offset of TSDM zone A (queue zone) in the internal RAM */
+#define PGLUE_B_REG_TSDM_START_OFFSET_A 0x90c4
+/* [RW 16] Start offset of TSDM zone B (legacy zone) in the internal RAM */
+#define PGLUE_B_REG_TSDM_START_OFFSET_B 0x90cc
+/* [RW 5] VF Shift of TSDM zone B (legacy zone) in the internal RAM */
+#define PGLUE_B_REG_TSDM_VF_SHIFT_B 0x90d4
+/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */
+#define PGLUE_B_REG_TSDM_ZONE_A_SIZE_PF 0x91a0
+/* [R 32] Address [31:0] of first read request not submitted due to error */
+#define PGLUE_B_REG_TX_ERR_RD_ADD_31_0 0x9098
+/* [R 32] Address [63:32] of first read request not submitted due to error */
+#define PGLUE_B_REG_TX_ERR_RD_ADD_63_32 0x909c
+/* [R 31] Details of first read request not submitted due to error. [4:0]
+ * VQID. [5] TREQ. 1 - Indicates the request is a Translation Request.
+ * [20:8] - Length in bytes. [23:21] - PFID. [24] - VF_VALID. [30:25] -
+ * VFID. */
+#define PGLUE_B_REG_TX_ERR_RD_DETAILS 0x90a0
+/* [R 26] Details of first read request not submitted due to error. [15:0]
+ * Request ID. [19:16] client ID. [20] - last SR. [24:21] - Error type -
+ * [21] - Indicates was_error was set; [22] - Indicates BME was cleared;
+ * [23] - Indicates FID_enable was cleared; [24] - Indicates VF with parent
+ * PF FLR_request or IOV_disable_request dirty bit is set. [25] valid -
+ * indicates if there was a request not submitted due to error since the
+ * last time this register was cleared. */
+#define PGLUE_B_REG_TX_ERR_RD_DETAILS2 0x90a4
+/* [R 32] Address [31:0] of first write request not submitted due to error */
+#define PGLUE_B_REG_TX_ERR_WR_ADD_31_0 0x9088
+/* [R 32] Address [63:32] of first write request not submitted due to error */
+#define PGLUE_B_REG_TX_ERR_WR_ADD_63_32 0x908c
+/* [R 31] Details of first write request not submitted due to error. [4:0]
+ * VQID. [20:8] - Length in bytes. [23:21] - PFID. [24] - VF_VALID. [30:25]
+ * - VFID. */
+#define PGLUE_B_REG_TX_ERR_WR_DETAILS 0x9090
+/* [R 26] Details of first write request not submitted due to error. [15:0]
+ * Request ID. [19:16] client ID. [20] - last SR. [24:21] - Error type -
+ * [21] - Indicates was_error was set; [22] - Indicates BME was cleared;
+ * [23] - Indicates FID_enable was cleared; [24] - Indicates VF with parent
+ * PF FLR_request or IOV_disable_request dirty bit is set. [25] valid -
+ * indicates if there was a request not submitted due to error since the
+ * last time this register was cleared. */
+#define PGLUE_B_REG_TX_ERR_WR_DETAILS2 0x9094
+/* [RW 10] Type A PF/VF inbound interrupt table for USDM: bits[9:5]-mask;
+ * its[4:0]-address relative to start_offset_a. Bits [1:0] can have any
+ * value (Byte resolution address). */
+#define PGLUE_B_REG_USDM_INB_INT_A_0 0x9128
+#define PGLUE_B_REG_USDM_INB_INT_A_1 0x912c
+#define PGLUE_B_REG_USDM_INB_INT_A_2 0x9130
+#define PGLUE_B_REG_USDM_INB_INT_A_3 0x9134
+#define PGLUE_B_REG_USDM_INB_INT_A_4 0x9138
+#define PGLUE_B_REG_USDM_INB_INT_A_5 0x913c
+#define PGLUE_B_REG_USDM_INB_INT_A_6 0x9140
+/* [RW 1] Type A PF enable inbound interrupt table for USDM. 0 - disable; 1
+ * - enable. */
+#define PGLUE_B_REG_USDM_INB_INT_A_PF_ENABLE 0x917c
+/* [RW 1] Type A VF enable inbound interrupt table for USDM. 0 - disable; 1
+ * - enable. */
+#define PGLUE_B_REG_USDM_INB_INT_A_VF_ENABLE 0x9180
+/* [RW 1] Type B VF enable inbound interrupt table for USDM. 0 - disable; 1
+ * - enable. */
+#define PGLUE_B_REG_USDM_INB_INT_B_VF_ENABLE 0x9184
+/* [RW 16] Start offset of USDM zone A (queue zone) in the internal RAM */
+#define PGLUE_B_REG_USDM_START_OFFSET_A 0x90d8
+/* [RW 16] Start offset of USDM zone B (legacy zone) in the internal RAM */
+#define PGLUE_B_REG_USDM_START_OFFSET_B 0x90e0
+/* [RW 5] VF Shift of USDM zone B (legacy zone) in the internal RAM */
+#define PGLUE_B_REG_USDM_VF_SHIFT_B 0x90e8
+/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */
+#define PGLUE_B_REG_USDM_ZONE_A_SIZE_PF 0x91a4
+/* [R 26] Details of first target VF request accessing VF GRC space that
+ * failed permission check. [14:0] Address. [15] w_nr: 0 - Read; 1 - Write.
+ * [21:16] VFID. [24:22] - PFID. [25] valid - indicates if there was a
+ * request accessing VF GRC space that failed permission check since the
+ * last time this register was cleared. Permission checks are: function
+ * permission; R/W permission; address range permission. */
+#define PGLUE_B_REG_VF_GRC_SPACE_VIOLATION_DETAILS 0x9234
+/* [R 31] Details of first target VF request with length violation (too many
+ * DWs) accessing BAR0. [12:0] Address in DWs (bits [14:2] of byte address).
+ * [14:13] BAR. [20:15] VFID. [23:21] - PFID. [29:24] - Length in DWs. [30]
+ * valid - indicates if there was a request with length violation since the
+ * last time this register was cleared. Length violations: length of more
+ * than 2DWs; length of 2DWs and address not QW aligned; window is GRC and
+ * length is more than 1 DW. */
+#define PGLUE_B_REG_VF_LENGTH_VIOLATION_DETAILS 0x9230
+/* [R 8] Was_error indication dirty bits for PFs 0 to 7. Each bit indicates
+ * that there was a completion with uncorrectable error for the
+ * corresponding PF. Set by PXP. Reset by MCP writing 1 to
+ * was_error_pf_7_0_clr. */
+#define PGLUE_B_REG_WAS_ERROR_PF_7_0 0x907c
+/* [W 8] Was_error indication dirty bits clear for PFs 0 to 7. MCP writes 1
+ * to a bit in this register in order to clear the corresponding bit in
+ * flr_request_pf_7_0 register. */
+#define PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR 0x9470
+/* [R 32] Was_error indication dirty bits for VFs 96 to 127. Each bit
+ * indicates that there was a completion with uncorrectable error for the
+ * corresponding VF. Set by PXP. Reset by MCP writing 1 to
+ * was_error_vf_127_96_clr. */
+#define PGLUE_B_REG_WAS_ERROR_VF_127_96 0x9078
+/* [W 32] Was_error indication dirty bits clear for VFs 96 to 127. MCP
+ * writes 1 to a bit in this register in order to clear the corresponding
+ * bit in was_error_vf_127_96 register. */
+#define PGLUE_B_REG_WAS_ERROR_VF_127_96_CLR 0x9474
+/* [R 32] Was_error indication dirty bits for VFs 0 to 31. Each bit
+ * indicates that there was a completion with uncorrectable error for the
+ * corresponding VF. Set by PXP. Reset by MCP writing 1 to
+ * was_error_vf_31_0_clr. */
+#define PGLUE_B_REG_WAS_ERROR_VF_31_0 0x906c
+/* [W 32] Was_error indication dirty bits clear for VFs 0 to 31. MCP writes
+ * 1 to a bit in this register in order to clear the corresponding bit in
+ * was_error_vf_31_0 register. */
+#define PGLUE_B_REG_WAS_ERROR_VF_31_0_CLR 0x9478
+/* [R 32] Was_error indication dirty bits for VFs 32 to 63. Each bit
+ * indicates that there was a completion with uncorrectable error for the
+ * corresponding VF. Set by PXP. Reset by MCP writing 1 to
+ * was_error_vf_63_32_clr. */
+#define PGLUE_B_REG_WAS_ERROR_VF_63_32 0x9070
+/* [W 32] Was_error indication dirty bits clear for VFs 32 to 63. MCP writes
+ * 1 to a bit in this register in order to clear the corresponding bit in
+ * was_error_vf_63_32 register. */
+#define PGLUE_B_REG_WAS_ERROR_VF_63_32_CLR 0x947c
+/* [R 32] Was_error indication dirty bits for VFs 64 to 95. Each bit
+ * indicates that there was a completion with uncorrectable error for the
+ * corresponding VF. Set by PXP. Reset by MCP writing 1 to
+ * was_error_vf_95_64_clr. */
+#define PGLUE_B_REG_WAS_ERROR_VF_95_64 0x9074
+/* [W 32] Was_error indication dirty bits clear for VFs 64 to 95. MCP writes
+ * 1 to a bit in this register in order to clear the corresponding bit in
+ * was_error_vf_95_64 register. */
+#define PGLUE_B_REG_WAS_ERROR_VF_95_64_CLR 0x9480
+/* [RW 1] Type A PF enable inbound interrupt table for XSDM. 0 - disable; 1
+ * - enable. */
+#define PGLUE_B_REG_XSDM_INB_INT_A_PF_ENABLE 0x9188
+/* [RW 16] Start offset of XSDM zone A (queue zone) in the internal RAM */
+#define PGLUE_B_REG_XSDM_START_OFFSET_A 0x90ec
+/* [RW 16] Start offset of XSDM zone B (legacy zone) in the internal RAM */
+#define PGLUE_B_REG_XSDM_START_OFFSET_B 0x90f4
+/* [RW 5] VF Shift of XSDM zone B (legacy zone) in the internal RAM */
+#define PGLUE_B_REG_XSDM_VF_SHIFT_B 0x90fc
+/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */
+#define PGLUE_B_REG_XSDM_ZONE_A_SIZE_PF 0x91a8
#define PRS_REG_A_PRSU_20 0x40134
/* [R 8] debug only: CFC load request current credit. Transaction based. */
#define PRS_REG_CFC_LD_CURRENT_CREDIT 0x40164
@@ -1866,9 +2370,13 @@
#define PRS_REG_FLUSH_REGIONS_TYPE_5 0x40018
#define PRS_REG_FLUSH_REGIONS_TYPE_6 0x4001c
#define PRS_REG_FLUSH_REGIONS_TYPE_7 0x40020
+/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic
+ * Ethernet header. */
+#define PRS_REG_HDRS_AFTER_BASIC 0x40238
/* [RW 4] The increment value to send in the CFC load request message */
#define PRS_REG_INC_VALUE 0x40048
-/* [RW 1] If set indicates not to send messages to CFC on received packets */
+/* [RW 6] Bit-map indicating which headers must appear in the packet */
+#define PRS_REG_MUST_HAVE_HDRS 0x40254
#define PRS_REG_NIC_MODE 0x40138
/* [RW 8] The 8-bit event ID for cases where there is no match on the
connection. Used in packet start message to TCM. */
@@ -1919,6 +2427,13 @@
#define PRS_REG_TCM_CURRENT_CREDIT 0x40160
/* [R 8] debug only: TSDM current credit. Transaction based. */
#define PRS_REG_TSDM_CURRENT_CREDIT 0x4015c
+#define PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_AFT (0x1<<19)
+#define PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_OF (0x1<<20)
+#define PXP2_PXP2_INT_MASK_0_REG_PGL_PCIE_ATTN (0x1<<22)
+#define PXP2_PXP2_INT_MASK_0_REG_PGL_READ_BLOCKED (0x1<<23)
+#define PXP2_PXP2_INT_MASK_0_REG_PGL_WRITE_BLOCKED (0x1<<24)
+#define PXP2_PXP2_INT_STS_0_REG_WR_PGLUE_EOP_ERROR (0x1<<7)
+#define PXP2_PXP2_INT_STS_CLR_0_REG_WR_PGLUE_EOP_ERROR (0x1<<7)
/* [R 6] Debug only: Number of used entries in the data FIFO */
#define PXP2_REG_HST_DATA_FIFO_STATUS 0x12047c
/* [R 7] Debug only: Number of used entries in the header FIFO */
@@ -2244,8 +2759,17 @@
/* [RW 1] When '1'; requests will enter input buffers but wont get out
towards the glue */
#define PXP2_REG_RQ_DISABLE_INPUTS 0x120330
-/* [RW 1] 1 - SR will be aligned by 64B; 0 - SR will be aligned by 8B */
+/* [RW 4] Determines alignment of write SRs when a request is split into
+ * several SRs. 0 - 8B aligned. 1 - 64B aligned. 2 - 128B aligned. 3 - 256B
+ * aligned. 4 - 512B aligned. */
#define PXP2_REG_RQ_DRAM_ALIGN 0x1205b0
+/* [RW 4] Determines alignment of read SRs when a request is split into
+ * several SRs. 0 - 8B aligned. 1 - 64B aligned. 2 - 128B aligned. 3 - 256B
+ * aligned. 4 - 512B aligned. */
+#define PXP2_REG_RQ_DRAM_ALIGN_RD 0x12092c
+/* [RW 1] when set the new alignment method (E2) will be applied; when reset
+ * the original alignment method (E1 E1H) will be applied */
+#define PXP2_REG_RQ_DRAM_ALIGN_SEL 0x120930
/* [RW 1] If 1 ILT failiue will not result in ELT access; An interrupt will
be asserted */
#define PXP2_REG_RQ_ELT_DISABLE 0x12066c
@@ -2436,7 +2960,8 @@
#define PXP_REG_PXP_INT_STS_1 0x103078
/* [RC 32] Interrupt register #0 read clear */
#define PXP_REG_PXP_INT_STS_CLR_0 0x10306c
-/* [RW 26] Parity mask register #0 read/write */
+#define PXP_REG_PXP_INT_STS_CLR_1 0x10307c
+/* [RW 27] Parity mask register #0 read/write */
#define PXP_REG_PXP_PRTY_MASK 0x103094
/* [R 26] Parity register #0 read */
#define PXP_REG_PXP_PRTY_STS 0x103088
@@ -2566,6 +3091,7 @@
#define QM_REG_PAUSESTATE7 0x16e698
/* [RW 2] The PCI attributes field used in the PCI request. */
#define QM_REG_PCIREQAT 0x168054
+#define QM_REG_PF_EN 0x16e70c
/* [R 16] The byte credit of port 0 */
#define QM_REG_PORT0BYTECRD 0x168300
/* [R 16] The byte credit of port 1 */
@@ -3402,6 +3928,14 @@
/* [R 32] Parity register #0 read */
#define TSEM_REG_TSEM_PRTY_STS_0 0x180114
#define TSEM_REG_TSEM_PRTY_STS_1 0x180124
+/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64
+ * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */
+#define TSEM_REG_VFPF_ERR_NUM 0x180380
+/* [RW 32] Indirect access to AG context with 32-bits granularity. The bits
+ * [10:8] of the address should be the offset within the accessed LCID
+ * context; the bits [7:0] are the accessed LCID.Example: to write to REG10
+ * LCID100. The RBC address should be 12'ha64. */
+#define UCM_REG_AG_CTX 0xe2000
/* [R 5] Used to read the XX protection CAM occupancy counter. */
#define UCM_REG_CAM_OCCUP 0xe0170
/* [RW 1] CDU AG read Interface enable. If 0 - the request input is
@@ -3851,6 +4385,17 @@
/* [R 32] Parity register #0 read */
#define USEM_REG_USEM_PRTY_STS_0 0x300124
#define USEM_REG_USEM_PRTY_STS_1 0x300134
+/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64
+ * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */
+#define USEM_REG_VFPF_ERR_NUM 0x300380
+#define VFC_MEMORIES_RST_REG_CAM_RST (0x1<<0)
+#define VFC_MEMORIES_RST_REG_RAM_RST (0x1<<1)
+#define VFC_REG_MEMORIES_RST 0x1943c
+/* [RW 32] Indirect access to AG context with 32-bits granularity. The bits
+ * [12:8] of the address should be the offset within the accessed LCID
+ * context; the bits [7:0] are the accessed LCID.Example: to write to REG10
+ * LCID100. The RBC address should be 13'ha64. */
+#define XCM_REG_AG_CTX 0x28000
/* [RW 2] The queue index for registration on Aux1 counter flag. */
#define XCM_REG_AUX1_Q 0x20134
/* [RW 2] Per each decision rule the queue index to register to. */
@@ -4333,6 +4878,9 @@
#define XSEM_REG_TS_8_AS 0x280058
/* [RW 3] The arbitration scheme of time_slot 9 */
#define XSEM_REG_TS_9_AS 0x28005c
+/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64
+ * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */
+#define XSEM_REG_VFPF_ERR_NUM 0x280380
/* [RW 32] Interrupt mask register #0 read/write */
#define XSEM_REG_XSEM_INT_MASK_0 0x280110
#define XSEM_REG_XSEM_INT_MASK_1 0x280120
@@ -4371,6 +4919,23 @@
#define BIGMAC_REGISTER_TX_SOURCE_ADDR (0x08<<3)
#define BIGMAC_REGISTER_TX_STAT_GTBYT (0x20<<3)
#define BIGMAC_REGISTER_TX_STAT_GTPKT (0x0C<<3)
+#define BIGMAC2_REGISTER_BMAC_CONTROL (0x00<<3)
+#define BIGMAC2_REGISTER_BMAC_XGXS_CONTROL (0x01<<3)
+#define BIGMAC2_REGISTER_CNT_MAX_SIZE (0x05<<3)
+#define BIGMAC2_REGISTER_PFC_CONTROL (0x06<<3)
+#define BIGMAC2_REGISTER_RX_CONTROL (0x3A<<3)
+#define BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS (0x62<<3)
+#define BIGMAC2_REGISTER_RX_MAX_SIZE (0x3C<<3)
+#define BIGMAC2_REGISTER_RX_STAT_GR64 (0x40<<3)
+#define BIGMAC2_REGISTER_RX_STAT_GRIPJ (0x5f<<3)
+#define BIGMAC2_REGISTER_RX_STAT_GRPP (0x51<<3)
+#define BIGMAC2_REGISTER_TX_CONTROL (0x1C<<3)
+#define BIGMAC2_REGISTER_TX_MAX_SIZE (0x1E<<3)
+#define BIGMAC2_REGISTER_TX_PAUSE_CONTROL (0x20<<3)
+#define BIGMAC2_REGISTER_TX_SOURCE_ADDR (0x1D<<3)
+#define BIGMAC2_REGISTER_TX_STAT_GTBYT (0x39<<3)
+#define BIGMAC2_REGISTER_TX_STAT_GTPOK (0x22<<3)
+#define BIGMAC2_REGISTER_TX_STAT_GTPP (0x24<<3)
#define EMAC_LED_1000MB_OVERRIDE (1L<<1)
#define EMAC_LED_100MB_OVERRIDE (1L<<2)
#define EMAC_LED_10MB_OVERRIDE (1L<<3)
@@ -4478,6 +5043,8 @@
#define HW_LOCK_RESOURCE_SPIO 2
#define HW_LOCK_RESOURCE_UNDI 5
#define PRS_FLAG_OVERETH_IPV4 1
+#define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4)
+#define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5)
#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18)
#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31)
#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9)
@@ -4504,6 +5071,8 @@
#define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR (1<<20)
#define AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR (1<<0)
#define AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT (1<<31)
+#define AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT (0x1<<2)
+#define AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR (0x1<<3)
#define AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT (1<<3)
#define AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR (1<<2)
#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT (1<<5)
@@ -4796,6 +5365,253 @@
#define PCI_ID_VAL1 0x434
#define PCI_ID_VAL2 0x438
+#define PXPCS_TL_CONTROL_5 0x814
+#define PXPCS_TL_CONTROL_5_UNKNOWNTYPE_ERR_ATTN (1 << 29) /*WC*/
+#define PXPCS_TL_CONTROL_5_BOUNDARY4K_ERR_ATTN (1 << 28) /*WC*/
+#define PXPCS_TL_CONTROL_5_MRRS_ERR_ATTN (1 << 27) /*WC*/
+#define PXPCS_TL_CONTROL_5_MPS_ERR_ATTN (1 << 26) /*WC*/
+#define PXPCS_TL_CONTROL_5_TTX_BRIDGE_FORWARD_ERR (1 << 25) /*WC*/
+#define PXPCS_TL_CONTROL_5_TTX_TXINTF_OVERFLOW (1 << 24) /*WC*/
+#define PXPCS_TL_CONTROL_5_PHY_ERR_ATTN (1 << 23) /*RO*/
+#define PXPCS_TL_CONTROL_5_DL_ERR_ATTN (1 << 22) /*RO*/
+#define PXPCS_TL_CONTROL_5_TTX_ERR_NP_TAG_IN_USE (1 << 21) /*WC*/
+#define PXPCS_TL_CONTROL_5_TRX_ERR_UNEXP_RTAG (1 << 20) /*WC*/
+#define PXPCS_TL_CONTROL_5_PRI_SIG_TARGET_ABORT1 (1 << 19) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_UNSPPORT1 (1 << 18) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_ECRC1 (1 << 17) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_MALF_TLP1 (1 << 16) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_RX_OFLOW1 (1 << 15) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_UNEXP_CPL1 (1 << 14) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_MASTER_ABRT1 (1 << 13) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_CPL_TIMEOUT1 (1 << 12) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_FC_PRTL1 (1 << 11) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_PSND_TLP1 (1 << 10) /*WC*/
+#define PXPCS_TL_CONTROL_5_PRI_SIG_TARGET_ABORT (1 << 9) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_UNSPPORT (1 << 8) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_ECRC (1 << 7) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_MALF_TLP (1 << 6) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_RX_OFLOW (1 << 5) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_UNEXP_CPL (1 << 4) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_MASTER_ABRT (1 << 3) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_CPL_TIMEOUT (1 << 2) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_FC_PRTL (1 << 1) /*WC*/
+#define PXPCS_TL_CONTROL_5_ERR_PSND_TLP (1 << 0) /*WC*/
+
+
+#define PXPCS_TL_FUNC345_STAT 0x854
+#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT4 (1 << 29) /* WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT4\
+ (1 << 28) /* Unsupported Request Error Status in function4, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_ECRC4\
+ (1 << 27) /* ECRC Error TLP Status Status in function 4, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP4\
+ (1 << 26) /* Malformed TLP Status Status in function 4, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW4\
+ (1 << 25) /* Receiver Overflow Status Status in function 4, if \
+ set, generate pcie_err_attn output when this error is seen.. WC \
+ */
+#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL4\
+ (1 << 24) /* Unexpected Completion Status Status in function 4, \
+ if set, generate pcie_err_attn output when this error is seen. WC \
+ */
+#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT4\
+ (1 << 23) /* Receive UR Statusin function 4. If set, generate \
+ pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT4\
+ (1 << 22) /* Completer Timeout Status Status in function 4, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL4\
+ (1 << 21) /* Flow Control Protocol Error Status Status in \
+ function 4, if set, generate pcie_err_attn output when this error \
+ is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP4\
+ (1 << 20) /* Poisoned Error Status Status in function 4, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT3 (1 << 19) /* WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT3\
+ (1 << 18) /* Unsupported Request Error Status in function3, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_ECRC3\
+ (1 << 17) /* ECRC Error TLP Status Status in function 3, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP3\
+ (1 << 16) /* Malformed TLP Status Status in function 3, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW3\
+ (1 << 15) /* Receiver Overflow Status Status in function 3, if \
+ set, generate pcie_err_attn output when this error is seen.. WC \
+ */
+#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL3\
+ (1 << 14) /* Unexpected Completion Status Status in function 3, \
+ if set, generate pcie_err_attn output when this error is seen. WC \
+ */
+#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT3\
+ (1 << 13) /* Receive UR Statusin function 3. If set, generate \
+ pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT3\
+ (1 << 12) /* Completer Timeout Status Status in function 3, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL3\
+ (1 << 11) /* Flow Control Protocol Error Status Status in \
+ function 3, if set, generate pcie_err_attn output when this error \
+ is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP3\
+ (1 << 10) /* Poisoned Error Status Status in function 3, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT2 (1 << 9) /* WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT2\
+ (1 << 8) /* Unsupported Request Error Status for Function 2, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_ECRC2\
+ (1 << 7) /* ECRC Error TLP Status Status for Function 2, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP2\
+ (1 << 6) /* Malformed TLP Status Status for Function 2, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW2\
+ (1 << 5) /* Receiver Overflow Status Status for Function 2, if \
+ set, generate pcie_err_attn output when this error is seen.. WC \
+ */
+#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL2\
+ (1 << 4) /* Unexpected Completion Status Status for Function 2, \
+ if set, generate pcie_err_attn output when this error is seen. WC \
+ */
+#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT2\
+ (1 << 3) /* Receive UR Statusfor Function 2. If set, generate \
+ pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT2\
+ (1 << 2) /* Completer Timeout Status Status for Function 2, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL2\
+ (1 << 1) /* Flow Control Protocol Error Status Status for \
+ Function 2, if set, generate pcie_err_attn output when this error \
+ is seen. WC */
+#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP2\
+ (1 << 0) /* Poisoned Error Status Status for Function 2, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+
+
+#define PXPCS_TL_FUNC678_STAT 0x85C
+#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT7 (1 << 29) /* WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT7\
+ (1 << 28) /* Unsupported Request Error Status in function7, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_ECRC7\
+ (1 << 27) /* ECRC Error TLP Status Status in function 7, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP7\
+ (1 << 26) /* Malformed TLP Status Status in function 7, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW7\
+ (1 << 25) /* Receiver Overflow Status Status in function 7, if \
+ set, generate pcie_err_attn output when this error is seen.. WC \
+ */
+#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL7\
+ (1 << 24) /* Unexpected Completion Status Status in function 7, \
+ if set, generate pcie_err_attn output when this error is seen. WC \
+ */
+#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT7\
+ (1 << 23) /* Receive UR Statusin function 7. If set, generate \
+ pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT7\
+ (1 << 22) /* Completer Timeout Status Status in function 7, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL7\
+ (1 << 21) /* Flow Control Protocol Error Status Status in \
+ function 7, if set, generate pcie_err_attn output when this error \
+ is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP7\
+ (1 << 20) /* Poisoned Error Status Status in function 7, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT6 (1 << 19) /* WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT6\
+ (1 << 18) /* Unsupported Request Error Status in function6, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_ECRC6\
+ (1 << 17) /* ECRC Error TLP Status Status in function 6, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP6\
+ (1 << 16) /* Malformed TLP Status Status in function 6, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW6\
+ (1 << 15) /* Receiver Overflow Status Status in function 6, if \
+ set, generate pcie_err_attn output when this error is seen.. WC \
+ */
+#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL6\
+ (1 << 14) /* Unexpected Completion Status Status in function 6, \
+ if set, generate pcie_err_attn output when this error is seen. WC \
+ */
+#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT6\
+ (1 << 13) /* Receive UR Statusin function 6. If set, generate \
+ pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT6\
+ (1 << 12) /* Completer Timeout Status Status in function 6, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL6\
+ (1 << 11) /* Flow Control Protocol Error Status Status in \
+ function 6, if set, generate pcie_err_attn output when this error \
+ is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP6\
+ (1 << 10) /* Poisoned Error Status Status in function 6, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT5 (1 << 9) /* WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT5\
+ (1 << 8) /* Unsupported Request Error Status for Function 5, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_ECRC5\
+ (1 << 7) /* ECRC Error TLP Status Status for Function 5, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP5\
+ (1 << 6) /* Malformed TLP Status Status for Function 5, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW5\
+ (1 << 5) /* Receiver Overflow Status Status for Function 5, if \
+ set, generate pcie_err_attn output when this error is seen.. WC \
+ */
+#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL5\
+ (1 << 4) /* Unexpected Completion Status Status for Function 5, \
+ if set, generate pcie_err_attn output when this error is seen. WC \
+ */
+#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT5\
+ (1 << 3) /* Receive UR Statusfor Function 5. If set, generate \
+ pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT5\
+ (1 << 2) /* Completer Timeout Status Status for Function 5, if \
+ set, generate pcie_err_attn output when this error is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL5\
+ (1 << 1) /* Flow Control Protocol Error Status Status for \
+ Function 5, if set, generate pcie_err_attn output when this error \
+ is seen. WC */
+#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP5\
+ (1 << 0) /* Poisoned Error Status Status for Function 5, if set, \
+ generate pcie_err_attn output when this error is seen.. WC */
+
+
+#define BAR_USTRORM_INTMEM 0x400000
+#define BAR_CSTRORM_INTMEM 0x410000
+#define BAR_XSTRORM_INTMEM 0x420000
+#define BAR_TSTRORM_INTMEM 0x430000
+
+/* for accessing the IGU in case of status block ACK */
+#define BAR_IGU_INTMEM 0x440000
+
+#define BAR_DOORBELL_OFFSET 0x800000
+
+#define BAR_ME_REGISTER 0x450000
+#define ME_REG_PF_NUM_SHIFT 0
+#define ME_REG_PF_NUM\
+ (7L<<ME_REG_PF_NUM_SHIFT) /* Relative PF Num */
+#define ME_REG_VF_VALID (1<<8)
+#define ME_REG_VF_NUM_SHIFT 9
+#define ME_REG_VF_NUM_MASK (0x3f<<ME_REG_VF_NUM_SHIFT)
+#define ME_REG_VF_ERR (0x1<<3)
+#define ME_REG_ABS_PF_NUM_SHIFT 16
+#define ME_REG_ABS_PF_NUM\
+ (7L<<ME_REG_ABS_PF_NUM_SHIFT) /* Absolute PF Num */
+
#define MDIO_REG_BANK_CL73_IEEEB0 0x0
#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL 0x0
@@ -4964,6 +5780,8 @@
#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN 0x0001
#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR 0x0040
#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1 0x14
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SGMII 0x0001
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_LINK 0x0002
#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX 0x0004
#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK 0x0018
#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT 3
@@ -5135,28 +5953,35 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR 0x8005
#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF 0x8007
#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK 0xff
-#define MDIO_PMA_REG_8727_MISC_CTRL 0x8309
#define MDIO_PMA_REG_8727_TX_CTRL1 0xca02
#define MDIO_PMA_REG_8727_TX_CTRL2 0xca05
#define MDIO_PMA_REG_8727_PCS_OPT_CTRL 0xc808
#define MDIO_PMA_REG_8727_GPIO_CTRL 0xc80e
+#define MDIO_PMA_REG_8727_PCS_GP 0xc842
+
+#define MDIO_AN_REG_8727_MISC_CTRL 0x8309
#define MDIO_PMA_REG_8073_CHIP_REV 0xc801
#define MDIO_PMA_REG_8073_SPEED_LINK_STATUS 0xc820
#define MDIO_PMA_REG_8073_XAUI_WA 0xc841
+#define MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL 0xcd08
#define MDIO_PMA_REG_7101_RESET 0xc000
#define MDIO_PMA_REG_7107_LED_CNTL 0xc007
+#define MDIO_PMA_REG_7107_LINK_LED_CNTL 0xc009
#define MDIO_PMA_REG_7101_VER1 0xc026
#define MDIO_PMA_REG_7101_VER2 0xc027
-#define MDIO_PMA_REG_8481_PMD_SIGNAL 0xa811
-#define MDIO_PMA_REG_8481_LED1_MASK 0xa82c
-#define MDIO_PMA_REG_8481_LED2_MASK 0xa82f
-#define MDIO_PMA_REG_8481_LED3_MASK 0xa832
-#define MDIO_PMA_REG_8481_LED3_BLINK 0xa834
-#define MDIO_PMA_REG_8481_SIGNAL_MASK 0xa835
-#define MDIO_PMA_REG_8481_LINK_SIGNAL 0xa83b
+#define MDIO_PMA_REG_8481_PMD_SIGNAL 0xa811
+#define MDIO_PMA_REG_8481_LED1_MASK 0xa82c
+#define MDIO_PMA_REG_8481_LED2_MASK 0xa82f
+#define MDIO_PMA_REG_8481_LED3_MASK 0xa832
+#define MDIO_PMA_REG_8481_LED3_BLINK 0xa834
+#define MDIO_PMA_REG_8481_LED5_MASK 0xa838
+#define MDIO_PMA_REG_8481_SIGNAL_MASK 0xa835
+#define MDIO_PMA_REG_8481_LINK_SIGNAL 0xa83b
+#define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK 0x800
+#define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT 11
#define MDIO_WIS_DEVAD 0x2
@@ -5188,6 +6013,8 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_XS_8706_REG_BANK_RX3 0x80ec
#define MDIO_XS_8706_REG_BANK_RXA 0x80fc
+#define MDIO_XS_REG_8073_RX_CTRL_PCIE 0x80FA
+
#define MDIO_AN_DEVAD 0x7
/*ieee*/
#define MDIO_AN_REG_CTRL 0x0000
@@ -5210,14 +6037,40 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_AN_REG_CL37_FC_LP 0xffe5
#define MDIO_AN_REG_8073_2_5G 0x8329
+#define MDIO_AN_REG_8073_BAM 0x8350
+#define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL 0x0020
#define MDIO_AN_REG_8481_LEGACY_MII_CTRL 0xffe0
+#define MDIO_AN_REG_8481_LEGACY_MII_STATUS 0xffe1
#define MDIO_AN_REG_8481_LEGACY_AN_ADV 0xffe4
+#define MDIO_AN_REG_8481_LEGACY_AN_EXPANSION 0xffe6
#define MDIO_AN_REG_8481_1000T_CTRL 0xffe9
#define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW 0xfff5
#define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS 0xfff7
+#define MDIO_AN_REG_8481_AUX_CTRL 0xfff8
#define MDIO_AN_REG_8481_LEGACY_SHADOW 0xfffc
+/* BCM84823 only */
+#define MDIO_CTL_DEVAD 0x1e
+#define MDIO_CTL_REG_84823_MEDIA 0x401a
+#define MDIO_CTL_REG_84823_MEDIA_MAC_MASK 0x0018
+ /* These pins configure the BCM84823 interface to MAC after reset. */
+#define MDIO_CTL_REG_84823_CTRL_MAC_XFI 0x0008
+#define MDIO_CTL_REG_84823_MEDIA_MAC_XAUI_M 0x0010
+ /* These pins configure the BCM84823 interface to Line after reset. */
+#define MDIO_CTL_REG_84823_MEDIA_LINE_MASK 0x0060
+#define MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L 0x0020
+#define MDIO_CTL_REG_84823_MEDIA_LINE_XFI 0x0040
+ /* When this pin is active high during reset, 10GBASE-T core is power
+ * down, When it is active low the 10GBASE-T is power up
+ */
+#define MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN 0x0080
+#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK 0x0100
+#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER 0x0000
+#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER 0x0100
+#define MDIO_CTL_REG_84823_MEDIA_FIBER_1G 0x1000
+
+
#define IGU_FUNC_BASE 0x0400
#define IGU_ADDR_MSIX 0x0000
@@ -5239,6 +6092,11 @@ Theotherbitsarereservedandshouldbezero*/
#define IGU_INT_NOP 2
#define IGU_INT_NOP2 3
+#define IGU_USE_REGISTER_ustorm_type_0_sb_cleanup 0
+#define IGU_USE_REGISTER_ustorm_type_1_sb_cleanup 1
+#define IGU_USE_REGISTER_cstorm_type_0_sb_cleanup 2
+#define IGU_USE_REGISTER_cstorm_type_1_sb_cleanup 3
+
#define COMMAND_REG_INT_ACK 0x0
#define COMMAND_REG_PROD_UPD 0x4
#define COMMAND_REG_ATTN_BITS_UPD 0x8
@@ -5281,6 +6139,50 @@ Theotherbitsarereservedandshouldbezero*/
#define IGU_REG_SISR_MDPC_WOMASK_UPPER 0x05a6
#define IGU_REG_RESERVED_UPPER 0x05ff
+/* Fields of IGU PF CONFIGRATION REGISTER */
+#define IGU_PF_CONF_FUNC_EN (0x1<<0) /* function enable */
+#define IGU_PF_CONF_MSI_MSIX_EN (0x1<<1) /* MSI/MSIX enable */
+#define IGU_PF_CONF_INT_LINE_EN (0x1<<2) /* INT enable */
+#define IGU_PF_CONF_ATTN_BIT_EN (0x1<<3) /* attention enable */
+#define IGU_PF_CONF_SINGLE_ISR_EN (0x1<<4) /* single ISR mode enable */
+#define IGU_PF_CONF_SIMD_MODE (0x1<<5) /* simd all ones mode */
+
+/* Fields of IGU VF CONFIGRATION REGISTER */
+#define IGU_VF_CONF_FUNC_EN (0x1<<0) /* function enable */
+#define IGU_VF_CONF_MSI_MSIX_EN (0x1<<1) /* MSI/MSIX enable */
+#define IGU_VF_CONF_PARENT_MASK (0x3<<2) /* Parent PF */
+#define IGU_VF_CONF_PARENT_SHIFT 2 /* Parent PF */
+#define IGU_VF_CONF_SINGLE_ISR_EN (0x1<<4) /* single ISR mode enable */
+
+
+#define IGU_BC_DSB_NUM_SEGS 5
+#define IGU_BC_NDSB_NUM_SEGS 2
+#define IGU_NORM_DSB_NUM_SEGS 2
+#define IGU_NORM_NDSB_NUM_SEGS 1
+#define IGU_BC_BASE_DSB_PROD 128
+#define IGU_NORM_BASE_DSB_PROD 136
+
+#define IGU_CTRL_CMD_TYPE_WR\
+ 1
+#define IGU_CTRL_CMD_TYPE_RD\
+ 0
+
+#define IGU_SEG_ACCESS_NORM 0
+#define IGU_SEG_ACCESS_DEF 1
+#define IGU_SEG_ACCESS_ATTN 2
+
+ /* FID (if VF - [6] = 0; [5:0] = VF number; if PF - [6] = 1; \
+ [5:2] = 0; [1:0] = PF number) */
+#define IGU_FID_ENCODE_IS_PF (0x1<<6)
+#define IGU_FID_ENCODE_IS_PF_SHIFT 6
+#define IGU_FID_VF_NUM_MASK (0x3f)
+#define IGU_FID_PF_NUM_MASK (0x7)
+
+#define IGU_REG_MAPPING_MEMORY_VALID (1<<0)
+#define IGU_REG_MAPPING_MEMORY_VECTOR_MASK (0x3F<<1)
+#define IGU_REG_MAPPING_MEMORY_VECTOR_SHIFT 1
+#define IGU_REG_MAPPING_MEMORY_FID_MASK (0x7F<<7)
+#define IGU_REG_MAPPING_MEMORY_FID_SHIFT 7
#define CDU_REGION_NUMBER_XCM_AG 2
diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c
index c74724461020..4733c835dad9 100644
--- a/drivers/net/bnx2x/bnx2x_stats.c
+++ b/drivers/net/bnx2x/bnx2x_stats.c
@@ -14,8 +14,8 @@
* Statistics and Link management by Yitchak Gertner
*
*/
- #include "bnx2x_cmn.h"
- #include "bnx2x_stats.h"
+#include "bnx2x_cmn.h"
+#include "bnx2x_stats.h"
/* Statistics */
@@ -153,7 +153,7 @@ static inline long bnx2x_hilo(u32 *hiref)
static void bnx2x_storm_stats_post(struct bnx2x *bp)
{
if (!bp->stats_pending) {
- struct eth_query_ramrod_data ramrod_data = {0};
+ struct common_query_ramrod_data ramrod_data = {0};
int i, rc;
spin_lock_bh(&bp->stats_lock);
@@ -163,14 +163,11 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
for_each_queue(bp, i)
ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id);
- rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0,
+ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0,
((u32 *)&ramrod_data)[1],
- ((u32 *)&ramrod_data)[0], 0);
- if (rc == 0) {
- /* stats ramrod has it's own slot on the spq */
- bp->spq_left++;
+ ((u32 *)&ramrod_data)[0], 1);
+ if (rc == 0)
bp->stats_pending = 1;
- }
spin_unlock_bh(&bp->stats_lock);
}
@@ -188,20 +185,12 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)
/* loader */
if (bp->executer_idx) {
int loader_idx = PMF_DMAE_C(bp);
+ u32 opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC,
+ true, DMAE_COMP_GRC);
+ opcode = bnx2x_dmae_opcode_clr_src_reset(opcode);
memset(dmae, 0, sizeof(struct dmae_command));
-
- dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
- DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 :
- DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ dmae->opcode = opcode;
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0]));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0]));
dmae->dst_addr_lo = (DMAE_REG_CMD_MEM +
@@ -253,26 +242,17 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp)
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
/* sanity */
- if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) {
+ if (!IS_MF(bp) || !bp->port.pmf || !bp->port.port_stx) {
BNX2X_ERR("BUG!\n");
return;
}
bp->executer_idx = 0;
- opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, false, 0);
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
+ dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_GRC);
dmae->src_addr_lo = bp->port.port_stx >> 2;
dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
@@ -283,7 +263,7 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp)
dmae->comp_val = 1;
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
+ dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX;
dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) +
@@ -304,7 +284,6 @@ static void bnx2x_port_stats_init(struct bnx2x *bp)
{
struct dmae_command *dmae;
int port = BP_PORT(bp);
- int vn = BP_E1HVN(bp);
u32 opcode;
int loader_idx = PMF_DMAE_C(bp);
u32 mac_addr;
@@ -319,16 +298,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp)
bp->executer_idx = 0;
/* MCP */
- opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (vn << DMAE_CMD_E1HVN_SHIFT));
+ opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC,
+ true, DMAE_COMP_GRC);
if (bp->port.port_stx) {
@@ -359,16 +330,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp)
}
/* MAC */
- opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (vn << DMAE_CMD_E1HVN_SHIFT));
+ opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI,
+ true, DMAE_COMP_GRC);
if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
@@ -379,13 +342,21 @@ static void bnx2x_port_stats_init(struct bnx2x *bp)
BIGMAC_REGISTER_TX_STAT_GTBYT */
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
+ if (CHIP_IS_E1x(bp)) {
+ dmae->src_addr_lo = (mac_addr +
BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
+ dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT -
+ BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
+ } else {
+ dmae->src_addr_lo = (mac_addr +
+ BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2;
+ dmae->len = (8 + BIGMAC2_REGISTER_TX_STAT_GTBYT -
+ BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2;
+ }
+
dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
- dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT -
- BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
dmae->comp_addr_hi = 0;
dmae->comp_val = 1;
@@ -394,15 +365,31 @@ static void bnx2x_port_stats_init(struct bnx2x *bp)
BIGMAC_REGISTER_RX_STAT_GRIPJ */
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct bmac_stats, rx_stat_gr64_lo));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct bmac_stats, rx_stat_gr64_lo));
- dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
- BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
+ if (CHIP_IS_E1x(bp)) {
+ dmae->src_addr_lo = (mac_addr +
+ BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
+ dmae->dst_addr_lo =
+ U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
+ offsetof(struct bmac1_stats, rx_stat_gr64_lo));
+ dmae->dst_addr_hi =
+ U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
+ offsetof(struct bmac1_stats, rx_stat_gr64_lo));
+ dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
+ BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
+ } else {
+ dmae->src_addr_lo =
+ (mac_addr + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2;
+ dmae->dst_addr_lo =
+ U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
+ offsetof(struct bmac2_stats, rx_stat_gr64_lo));
+ dmae->dst_addr_hi =
+ U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
+ offsetof(struct bmac2_stats, rx_stat_gr64_lo));
+ dmae->len = (8 + BIGMAC2_REGISTER_RX_STAT_GRIPJ -
+ BIGMAC2_REGISTER_RX_STAT_GR64) >> 2;
+ }
+
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
dmae->comp_addr_hi = 0;
dmae->comp_val = 1;
@@ -483,16 +470,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp)
dmae->comp_val = 1;
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (vn << DMAE_CMD_E1HVN_SHIFT));
+ dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI,
+ true, DMAE_COMP_PCI);
dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 :
NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2;
dmae->src_addr_hi = 0;
@@ -522,16 +501,8 @@ static void bnx2x_func_stats_init(struct bnx2x *bp)
bp->executer_idx = 0;
memset(dmae, 0, sizeof(struct dmae_command));
- dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC,
+ true, DMAE_COMP_PCI);
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
dmae->dst_addr_lo = bp->func_stx >> 2;
@@ -571,7 +542,6 @@ static void bnx2x_stats_restart(struct bnx2x *bp)
static void bnx2x_bmac_stats_update(struct bnx2x *bp)
{
- struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats);
struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
struct bnx2x_eth_stats *estats = &bp->eth_stats;
struct {
@@ -579,35 +549,74 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
u32 hi;
} diff;
- UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
- UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
- UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
- UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
- UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
- UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
- UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
- UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
- UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf);
- UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
- UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
- UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
- UPDATE_STAT64(tx_stat_gt127,
+ if (CHIP_IS_E1x(bp)) {
+ struct bmac1_stats *new = bnx2x_sp(bp, mac_stats.bmac1_stats);
+
+ /* the macros below will use "bmac1_stats" type */
+ UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
+ UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
+ UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
+ UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
+ UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
+ UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
+ UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
+ UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
+ UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf);
+ UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
+ UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
+ UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
+ UPDATE_STAT64(tx_stat_gt127,
+ tx_stat_etherstatspkts65octetsto127octets);
+ UPDATE_STAT64(tx_stat_gt255,
+ tx_stat_etherstatspkts128octetsto255octets);
+ UPDATE_STAT64(tx_stat_gt511,
+ tx_stat_etherstatspkts256octetsto511octets);
+ UPDATE_STAT64(tx_stat_gt1023,
+ tx_stat_etherstatspkts512octetsto1023octets);
+ UPDATE_STAT64(tx_stat_gt1518,
+ tx_stat_etherstatspkts1024octetsto1522octets);
+ UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047);
+ UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095);
+ UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216);
+ UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383);
+ UPDATE_STAT64(tx_stat_gterr,
+ tx_stat_dot3statsinternalmactransmiterrors);
+ UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
+
+ } else {
+ struct bmac2_stats *new = bnx2x_sp(bp, mac_stats.bmac2_stats);
+
+ /* the macros below will use "bmac2_stats" type */
+ UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
+ UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
+ UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
+ UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
+ UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
+ UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
+ UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
+ UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
+ UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf);
+ UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
+ UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
+ UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
+ UPDATE_STAT64(tx_stat_gt127,
tx_stat_etherstatspkts65octetsto127octets);
- UPDATE_STAT64(tx_stat_gt255,
+ UPDATE_STAT64(tx_stat_gt255,
tx_stat_etherstatspkts128octetsto255octets);
- UPDATE_STAT64(tx_stat_gt511,
+ UPDATE_STAT64(tx_stat_gt511,
tx_stat_etherstatspkts256octetsto511octets);
- UPDATE_STAT64(tx_stat_gt1023,
+ UPDATE_STAT64(tx_stat_gt1023,
tx_stat_etherstatspkts512octetsto1023octets);
- UPDATE_STAT64(tx_stat_gt1518,
+ UPDATE_STAT64(tx_stat_gt1518,
tx_stat_etherstatspkts1024octetsto1522octets);
- UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047);
- UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095);
- UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216);
- UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383);
- UPDATE_STAT64(tx_stat_gterr,
+ UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047);
+ UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095);
+ UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216);
+ UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383);
+ UPDATE_STAT64(tx_stat_gterr,
tx_stat_dot3statsinternalmactransmiterrors);
- UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
+ UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
+ }
estats->pause_frames_received_hi =
pstats->mac_stx[1].rx_stat_bmac_xpf_hi;
@@ -969,6 +978,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
{
struct bnx2x_eth_stats *estats = &bp->eth_stats;
struct net_device_stats *nstats = &bp->dev->stats;
+ unsigned long tmp;
int i;
nstats->rx_packets =
@@ -985,10 +995,10 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
- nstats->rx_dropped = estats->mac_discard;
+ tmp = estats->mac_discard;
for_each_queue(bp, i)
- nstats->rx_dropped +=
- le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
+ tmp += le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
+ nstats->rx_dropped = tmp;
nstats->tx_dropped = 0;
@@ -1123,24 +1133,17 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp)
bp->executer_idx = 0;
- opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, false, 0);
if (bp->port.port_stx) {
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
if (bp->func_stx)
- dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
+ dmae->opcode = bnx2x_dmae_opcode_add_comp(
+ opcode, DMAE_COMP_GRC);
else
- dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
+ dmae->opcode = bnx2x_dmae_opcode_add_comp(
+ opcode, DMAE_COMP_PCI);
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
dmae->dst_addr_lo = bp->port.port_stx >> 2;
@@ -1164,7 +1167,8 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp)
if (bp->func_stx) {
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
+ dmae->opcode =
+ bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI);
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
dmae->dst_addr_lo = bp->func_stx >> 2;
@@ -1257,16 +1261,8 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp)
bp->executer_idx = 0;
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC,
+ true, DMAE_COMP_PCI);
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
dmae->dst_addr_lo = bp->port.port_stx >> 2;
@@ -1283,9 +1279,7 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp)
static void bnx2x_func_stats_base_init(struct bnx2x *bp)
{
- int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX;
- int port = BP_PORT(bp);
- int func;
+ int vn, vn_max = IS_MF(bp) ? E1HVN_MAX : E1VN_MAX;
u32 func_stx;
/* sanity */
@@ -1298,9 +1292,9 @@ static void bnx2x_func_stats_base_init(struct bnx2x *bp)
func_stx = bp->func_stx;
for (vn = VN_0; vn < vn_max; vn++) {
- func = 2*vn + port;
+ int mb_idx = !CHIP_IS_E2(bp) ? 2*vn + BP_PORT(bp) : vn;
- bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param);
+ bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param);
bnx2x_func_stats_init(bp);
bnx2x_hw_stats_post(bp);
bnx2x_stats_comp(bp);
@@ -1324,16 +1318,8 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp)
bp->executer_idx = 0;
memset(dmae, 0, sizeof(struct dmae_command));
- dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI,
+ true, DMAE_COMP_PCI);
dmae->src_addr_lo = bp->func_stx >> 2;
dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base));
@@ -1351,8 +1337,9 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp)
void bnx2x_stats_init(struct bnx2x *bp)
{
int port = BP_PORT(bp);
- int func = BP_FUNC(bp);
+ int mb_idx = BP_FW_MB_IDX(bp);
int i;
+ struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
bp->stats_pending = 0;
bp->executer_idx = 0;
@@ -1361,7 +1348,7 @@ void bnx2x_stats_init(struct bnx2x *bp)
/* port and func stats for management */
if (!BP_NOMCP(bp)) {
bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx);
- bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param);
+ bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param);
} else {
bp->port.port_stx = 0;
@@ -1394,6 +1381,18 @@ void bnx2x_stats_init(struct bnx2x *bp)
memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats));
}
+ for_each_queue(bp, i) {
+ /* Set initial stats counter in the stats ramrod data to -1 */
+ int cl_id = bp->fp[i].cl_id;
+
+ stats->xstorm_common.client_statistics[cl_id].
+ stats_counter = 0xffff;
+ stats->ustorm_common.client_statistics[cl_id].
+ stats_counter = 0xffff;
+ stats->tstorm_common.client_statistics[cl_id].
+ stats_counter = 0xffff;
+ }
+
memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h
index 38a4e908f4fb..afd15efa429a 100644
--- a/drivers/net/bnx2x/bnx2x_stats.h
+++ b/drivers/net/bnx2x/bnx2x_stats.h
@@ -9,6 +9,10 @@
* Maintained by: Eilon Greenstein <eilong@broadcom.com>
* Written by: Eliezer Tamir
* Based on code from Michael Chan's bnx2 driver
+ * UDP CSUM errata workaround by Arik Gendelman
+ * Slowpath and fastpath rework by Vladislav Zolotarov
+ * Statistics and Link management by Yitchak Gertner
+ *
*/
#ifndef BNX2X_STATS_H
@@ -228,12 +232,8 @@ struct bnx2x_eth_stats {
/* Forward declaration */
struct bnx2x;
-
void bnx2x_stats_init(struct bnx2x *bp);
extern const u32 dmae_reg_go_c[];
-extern int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
- u32 data_hi, u32 data_lo, int common);
-
#endif /* BNX2X_STATS_H */
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 0ddf4c66afe2..881914bc4e9c 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -93,7 +93,7 @@
// compare MAC addresses
#define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN)
-static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}};
+static struct mac_addr null_mac_addr = { { 0, 0, 0, 0, 0, 0 } };
static u16 ad_ticks_per_sec;
static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
@@ -129,9 +129,8 @@ static void ad_marker_response_received(struct bond_marker *marker, struct port
*/
static inline struct bonding *__get_bond_by_port(struct port *port)
{
- if (port->slave == NULL) {
+ if (port->slave == NULL)
return NULL;
- }
return bond_get_bond_by_slave(port->slave);
}
@@ -144,9 +143,8 @@ static inline struct bonding *__get_bond_by_port(struct port *port)
*/
static inline struct port *__get_first_port(struct bonding *bond)
{
- if (bond->slave_cnt == 0) {
+ if (bond->slave_cnt == 0)
return NULL;
- }
return &(SLAVE_AD_INFO(bond->first_slave).port);
}
@@ -164,9 +162,8 @@ static inline struct port *__get_next_port(struct port *port)
struct slave *slave = port->slave;
// If there's no bond for this port, or this is the last slave
- if ((bond == NULL) || (slave->next == bond->first_slave)) {
+ if ((bond == NULL) || (slave->next == bond->first_slave))
return NULL;
- }
return &(SLAVE_AD_INFO(slave->next).port);
}
@@ -183,9 +180,8 @@ static inline struct aggregator *__get_first_agg(struct port *port)
struct bonding *bond = __get_bond_by_port(port);
// If there's no bond for this port, or bond has no slaves
- if ((bond == NULL) || (bond->slave_cnt == 0)) {
+ if ((bond == NULL) || (bond->slave_cnt == 0))
return NULL;
- }
return &(SLAVE_AD_INFO(bond->first_slave).aggregator);
}
@@ -203,9 +199,8 @@ static inline struct aggregator *__get_next_agg(struct aggregator *aggregator)
struct bonding *bond = bond_get_bond_by_slave(slave);
// If there's no bond for this aggregator, or this is the last slave
- if ((bond == NULL) || (slave->next == bond->first_slave)) {
+ if ((bond == NULL) || (slave->next == bond->first_slave))
return NULL;
- }
return &(SLAVE_AD_INFO(slave->next).aggregator);
}
@@ -240,9 +235,8 @@ static inline void __enable_port(struct port *port)
{
struct slave *slave = port->slave;
- if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) {
+ if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev))
bond_set_slave_active_flags(slave);
- }
}
/**
@@ -252,7 +246,7 @@ static inline void __enable_port(struct port *port)
*/
static inline int __port_is_enabled(struct port *port)
{
- return(port->slave->state == BOND_STATE_ACTIVE);
+ return port->slave->state == BOND_STATE_ACTIVE;
}
/**
@@ -265,9 +259,8 @@ static inline u32 __get_agg_selection_mode(struct port *port)
{
struct bonding *bond = __get_bond_by_port(port);
- if (bond == NULL) {
+ if (bond == NULL)
return BOND_AD_STABLE;
- }
return BOND_AD_INFO(bond).agg_select_mode;
}
@@ -281,9 +274,8 @@ static inline int __check_agg_selection_timer(struct port *port)
{
struct bonding *bond = __get_bond_by_port(port);
- if (bond == NULL) {
+ if (bond == NULL)
return 0;
- }
return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0;
}
@@ -328,9 +320,9 @@ static u16 __get_link_speed(struct port *port)
* link down, it sets the speed to 0.
* This is done in spite of the fact that the e100 driver reports 0 to be
* compatible with MVT in the future.*/
- if (slave->link != BOND_LINK_UP) {
- speed=0;
- } else {
+ if (slave->link != BOND_LINK_UP)
+ speed = 0;
+ else {
switch (slave->speed) {
case SPEED_10:
speed = AD_LINK_SPEED_BITMASK_10MBPS;
@@ -375,18 +367,18 @@ static u8 __get_duplex(struct port *port)
// handling a special case: when the configuration starts with
// link down, it sets the duplex to 0.
- if (slave->link != BOND_LINK_UP) {
- retval=0x0;
- } else {
+ if (slave->link != BOND_LINK_UP)
+ retval = 0x0;
+ else {
switch (slave->duplex) {
case DUPLEX_FULL:
- retval=0x1;
+ retval = 0x1;
pr_debug("Port %d Received status full duplex update from adapter\n",
port->actor_port_number);
break;
case DUPLEX_HALF:
default:
- retval=0x0;
+ retval = 0x0;
pr_debug("Port %d Received status NOT full duplex update from adapter\n",
port->actor_port_number);
break;
@@ -419,15 +411,14 @@ static inline void __initialize_port_locks(struct port *port)
*/
static u16 __ad_timer_to_ticks(u16 timer_type, u16 par)
{
- u16 retval=0; //to silence the compiler
+ u16 retval = 0; /* to silence the compiler */
switch (timer_type) {
case AD_CURRENT_WHILE_TIMER: // for rx machine usage
- if (par) { // for short or long timeout
+ if (par)
retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout
- } else {
+ else
retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout
- }
break;
case AD_ACTOR_CHURN_TIMER: // for local churn machine
retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec);
@@ -519,11 +510,11 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port)
port->actor_oper_port_state &= ~AD_STATE_DEFAULTED;
// set the partner sync. to on if the partner is sync. and the port is matched
- if ((port->sm_vars & AD_PORT_MATCHED) && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) {
+ if ((port->sm_vars & AD_PORT_MATCHED)
+ && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION))
partner->port_state |= AD_STATE_SYNCHRONIZATION;
- } else {
+ else
partner->port_state &= ~AD_STATE_SYNCHRONIZATION;
- }
}
}
@@ -653,7 +644,7 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
*/
static void __attach_bond_to_agg(struct port *port)
{
- port=NULL; // just to satisfy the compiler
+ port = NULL; /* just to satisfy the compiler */
// This function does nothing since the parser/multiplexer of the receive
// and the parser/multiplexer of the aggregator are already combined
}
@@ -668,7 +659,7 @@ static void __attach_bond_to_agg(struct port *port)
*/
static void __detach_bond_from_agg(struct port *port)
{
- port=NULL; // just to satisfy the compiler
+ port = NULL; /* just to satisfy the compiler */
// This function does nothing sience the parser/multiplexer of the receive
// and the parser/multiplexer of the aggregator are already combined
}
@@ -685,7 +676,9 @@ static int __agg_ports_are_ready(struct aggregator *aggregator)
if (aggregator) {
// scan all ports in this aggregator to verfy if they are all ready
- for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
+ for (port = aggregator->lag_ports;
+ port;
+ port = port->next_port_in_aggregator) {
if (!(port->sm_vars & AD_PORT_READY_N)) {
retval = 0;
break;
@@ -706,12 +699,12 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val)
{
struct port *port;
- for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
- if (val) {
+ for (port = aggregator->lag_ports; port;
+ port = port->next_port_in_aggregator) {
+ if (val)
port->sm_vars |= AD_PORT_READY;
- } else {
+ else
port->sm_vars &= ~AD_PORT_READY;
- }
}
}
@@ -722,7 +715,7 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val)
*/
static u32 __get_agg_bandwidth(struct aggregator *aggregator)
{
- u32 bandwidth=0;
+ u32 bandwidth = 0;
u32 basic_speed;
if (aggregator->num_of_ports) {
@@ -744,7 +737,7 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
bandwidth = aggregator->num_of_ports * 10000;
break;
default:
- bandwidth=0; // to silent the compilor ....
+ bandwidth = 0; /*to silence the compiler ....*/
}
}
return bandwidth;
@@ -835,9 +828,8 @@ static int ad_lacpdu_send(struct port *port)
int length = sizeof(struct lacpdu_header);
skb = dev_alloc_skb(length);
- if (!skb) {
+ if (!skb)
return -ENOMEM;
- }
skb->dev = slave->dev;
skb_reset_mac_header(skb);
@@ -876,9 +868,8 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker)
int length = sizeof(struct bond_marker_header);
skb = dev_alloc_skb(length + 16);
- if (!skb) {
+ if (!skb)
return -ENOMEM;
- }
skb_reserve(skb, 16);
@@ -919,9 +910,10 @@ static void ad_mux_machine(struct port *port)
} else {
switch (port->sm_mux_state) {
case AD_MUX_DETACHED:
- if ((port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if SELECTED or STANDBY
+ if ((port->sm_vars & AD_PORT_SELECTED)
+ || (port->sm_vars & AD_PORT_STANDBY))
+ /* if SELECTED or STANDBY */
port->sm_mux_state = AD_MUX_WAITING; // next state
- }
break;
case AD_MUX_WAITING:
// if SELECTED == FALSE return to DETACH state
@@ -935,18 +927,18 @@ static void ad_mux_machine(struct port *port)
}
// check if the wait_while_timer expired
- if (port->sm_mux_timer_counter && !(--port->sm_mux_timer_counter)) {
+ if (port->sm_mux_timer_counter
+ && !(--port->sm_mux_timer_counter))
port->sm_vars |= AD_PORT_READY_N;
- }
// in order to withhold the selection logic to check all ports READY_N value
// every callback cycle to update ready variable, we check READY_N and update READY here
__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
// if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state
- if ((port->sm_vars & AD_PORT_READY) && !port->sm_mux_timer_counter) {
+ if ((port->sm_vars & AD_PORT_READY)
+ && !port->sm_mux_timer_counter)
port->sm_mux_state = AD_MUX_ATTACHED; // next state
- }
break;
case AD_MUX_ATTACHED:
// check also if agg_select_timer expired(so the edable port will take place only after this timer)
@@ -1041,13 +1033,14 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
// check if state machine should change state
// first, check if port was reinitialized
- if (port->sm_vars & AD_PORT_BEGIN) {
- port->sm_rx_state = AD_RX_INITIALIZE; // next state
- }
+ if (port->sm_vars & AD_PORT_BEGIN)
+ /* next state */
+ port->sm_rx_state = AD_RX_INITIALIZE;
// check if port is not enabled
- else if (!(port->sm_vars & AD_PORT_BEGIN) && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) {
- port->sm_rx_state = AD_RX_PORT_DISABLED; // next state
- }
+ else if (!(port->sm_vars & AD_PORT_BEGIN)
+ && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED))
+ /* next state */
+ port->sm_rx_state = AD_RX_PORT_DISABLED;
// check if new lacpdu arrived
else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) {
port->sm_rx_timer_counter = 0; // zero timer
@@ -1069,13 +1062,16 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
// if no lacpdu arrived and no timer is on
switch (port->sm_rx_state) {
case AD_RX_PORT_DISABLED:
- if (port->sm_vars & AD_PORT_MOVED) {
+ if (port->sm_vars & AD_PORT_MOVED)
port->sm_rx_state = AD_RX_INITIALIZE; // next state
- } else if (port->is_enabled && (port->sm_vars & AD_PORT_LACP_ENABLED)) {
+ else if (port->is_enabled
+ && (port->sm_vars
+ & AD_PORT_LACP_ENABLED))
port->sm_rx_state = AD_RX_EXPIRED; // next state
- } else if (port->is_enabled && ((port->sm_vars & AD_PORT_LACP_ENABLED) == 0)) {
+ else if (port->is_enabled
+ && ((port->sm_vars
+ & AD_PORT_LACP_ENABLED) == 0))
port->sm_rx_state = AD_RX_LACP_DISABLED; // next state
- }
break;
default: //to silence the compiler
break;
@@ -1091,11 +1087,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
port->sm_rx_state);
switch (port->sm_rx_state) {
case AD_RX_INITIALIZE:
- if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) {
+ if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS))
port->sm_vars &= ~AD_PORT_LACP_ENABLED;
- } else {
+ else
port->sm_vars |= AD_PORT_LACP_ENABLED;
- }
port->sm_vars &= ~AD_PORT_SELECTED;
__record_default(port);
port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
@@ -1149,9 +1144,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
// verify that if the aggregator is enabled, the port is enabled too.
//(because if the link goes down for a short time, the 802.3ad will not
// catch it, and the port will continue to be disabled)
- if (port->aggregator && port->aggregator->is_active && !__port_is_enabled(port)) {
+ if (port->aggregator
+ && port->aggregator->is_active
+ && !__port_is_enabled(port))
__enable_port(port);
- }
break;
default: //to silence the compiler
break;
@@ -1183,7 +1179,8 @@ static void ad_tx_machine(struct port *port)
}
}
// restart tx timer(to verify that we will not exceed AD_MAX_TX_IN_SECOND
- port->sm_tx_timer_counter=ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
+ port->sm_tx_timer_counter =
+ ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
}
}
@@ -1216,9 +1213,9 @@ static void ad_periodic_machine(struct port *port)
// If not expired, check if there is some new timeout parameter from the partner state
switch (port->sm_periodic_state) {
case AD_FAST_PERIODIC:
- if (!(port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) {
+ if (!(port->partner_oper.port_state
+ & AD_STATE_LACP_TIMEOUT))
port->sm_periodic_state = AD_SLOW_PERIODIC; // next state
- }
break;
case AD_SLOW_PERIODIC:
if ((port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) {
@@ -1237,11 +1234,11 @@ static void ad_periodic_machine(struct port *port)
port->sm_periodic_state = AD_FAST_PERIODIC; // next state
break;
case AD_PERIODIC_TX:
- if (!(port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) {
+ if (!(port->partner_oper.port_state
+ & AD_STATE_LACP_TIMEOUT))
port->sm_periodic_state = AD_SLOW_PERIODIC; // next state
- } else {
+ else
port->sm_periodic_state = AD_FAST_PERIODIC; // next state
- }
break;
default: //to silence the compiler
break;
@@ -1287,35 +1284,37 @@ static void ad_port_selection_logic(struct port *port)
int found = 0;
// if the port is already Selected, do nothing
- if (port->sm_vars & AD_PORT_SELECTED) {
+ if (port->sm_vars & AD_PORT_SELECTED)
return;
- }
// if the port is connected to other aggregator, detach it
if (port->aggregator) {
// detach the port from its former aggregator
- temp_aggregator=port->aggregator;
- for (curr_port=temp_aggregator->lag_ports; curr_port; last_port=curr_port, curr_port=curr_port->next_port_in_aggregator) {
+ temp_aggregator = port->aggregator;
+ for (curr_port = temp_aggregator->lag_ports; curr_port;
+ last_port = curr_port,
+ curr_port = curr_port->next_port_in_aggregator) {
if (curr_port == port) {
temp_aggregator->num_of_ports--;
if (!last_port) {// if it is the first port attached to the aggregator
- temp_aggregator->lag_ports=port->next_port_in_aggregator;
+ temp_aggregator->lag_ports =
+ port->next_port_in_aggregator;
} else {// not the first port attached to the aggregator
- last_port->next_port_in_aggregator=port->next_port_in_aggregator;
+ last_port->next_port_in_aggregator =
+ port->next_port_in_aggregator;
}
// clear the port's relations to this aggregator
port->aggregator = NULL;
- port->next_port_in_aggregator=NULL;
- port->actor_port_aggregator_identifier=0;
+ port->next_port_in_aggregator = NULL;
+ port->actor_port_aggregator_identifier = 0;
pr_debug("Port %d left LAG %d\n",
port->actor_port_number,
temp_aggregator->aggregator_identifier);
// if the aggregator is empty, clear its parameters, and set it ready to be attached
- if (!temp_aggregator->lag_ports) {
+ if (!temp_aggregator->lag_ports)
ad_clear_agg(temp_aggregator);
- }
break;
}
}
@@ -1333,9 +1332,8 @@ static void ad_port_selection_logic(struct port *port)
// keep a free aggregator for later use(if needed)
if (!aggregator->lag_ports) {
- if (!free_aggregator) {
- free_aggregator=aggregator;
- }
+ if (!free_aggregator)
+ free_aggregator = aggregator;
continue;
}
// check if current aggregator suits us
@@ -1350,10 +1348,11 @@ static void ad_port_selection_logic(struct port *port)
) {
// attach to the founded aggregator
port->aggregator = aggregator;
- port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier;
- port->next_port_in_aggregator=aggregator->lag_ports;
+ port->actor_port_aggregator_identifier =
+ port->aggregator->aggregator_identifier;
+ port->next_port_in_aggregator = aggregator->lag_ports;
port->aggregator->num_of_ports++;
- aggregator->lag_ports=port;
+ aggregator->lag_ports = port;
pr_debug("Port %d joined LAG %d(existing LAG)\n",
port->actor_port_number,
port->aggregator->aggregator_identifier);
@@ -1370,20 +1369,23 @@ static void ad_port_selection_logic(struct port *port)
if (free_aggregator) {
// assign port a new aggregator
port->aggregator = free_aggregator;
- port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier;
+ port->actor_port_aggregator_identifier =
+ port->aggregator->aggregator_identifier;
// update the new aggregator's parameters
// if port was responsed from the end-user
- if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) {// if port is full duplex
+ if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)
+ /* if port is full duplex */
port->aggregator->is_individual = false;
- } else {
+ else
port->aggregator->is_individual = true;
- }
port->aggregator->actor_admin_aggregator_key = port->actor_admin_port_key;
port->aggregator->actor_oper_aggregator_key = port->actor_oper_port_key;
- port->aggregator->partner_system=port->partner_oper.system;
- port->aggregator->partner_system_priority = port->partner_oper.system_priority;
+ port->aggregator->partner_system =
+ port->partner_oper.system;
+ port->aggregator->partner_system_priority =
+ port->partner_oper.system_priority;
port->aggregator->partner_oper_aggregator_key = port->partner_oper.key;
port->aggregator->receive_state = 1;
port->aggregator->transmit_state = 1;
@@ -1704,9 +1706,8 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
port->actor_admin_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY;
port->actor_oper_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY;
- if (lacp_fast) {
+ if (lacp_fast)
port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT;
- }
memcpy(&port->partner_admin, &tmpl, sizeof(tmpl));
memcpy(&port->partner_oper, &tmpl, sizeof(tmpl));
@@ -1785,13 +1786,16 @@ static void ad_marker_info_send(struct port *port)
marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |((u16)(port->actor_port_number & 0xFF00) >> 8));
marker.requester_system = port->actor_system;
// convert requester_port(u32) to Big Endian
- marker.requester_transaction_id = (((++port->transaction_id & 0xFF) << 24) |((port->transaction_id & 0xFF00) << 8) |((port->transaction_id & 0xFF0000) >> 8) |((port->transaction_id & 0xFF000000) >> 24));
+ marker.requester_transaction_id =
+ (((++port->transaction_id & 0xFF) << 24)
+ | ((port->transaction_id & 0xFF00) << 8)
+ | ((port->transaction_id & 0xFF0000) >> 8)
+ | ((port->transaction_id & 0xFF000000) >> 24));
marker.pad = 0;
marker.tlv_type_terminator = 0x00;
marker.terminator_length = 0x00;
- for (index=0; index<90; index++) {
- marker.reserved_90[index]=0;
- }
+ for (index = 0; index < 90; index++)
+ marker.reserved_90[index] = 0;
// send the marker information
if (ad_marker_send(port, &marker) >= 0) {
@@ -1816,7 +1820,7 @@ static void ad_marker_info_received(struct bond_marker *marker_info,
//marker = *marker_info;
memcpy(&marker, marker_info, sizeof(struct bond_marker));
// change the marker subtype to marker response
- marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE;
+ marker.tlv_type = AD_MARKER_RESPONSE_SUBTYPE;
// send the marker response
if (ad_marker_send(port, &marker) >= 0) {
@@ -1837,8 +1841,8 @@ static void ad_marker_info_received(struct bond_marker *marker_info,
static void ad_marker_response_received(struct bond_marker *marker,
struct port *port)
{
- marker=NULL; // just to satisfy the compiler
- port=NULL; // just to satisfy the compiler
+ marker = NULL; /* just to satisfy the compiler */
+ port = NULL; /* just to satisfy the compiler */
// DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW
}
@@ -1932,9 +1936,8 @@ int bond_3ad_bind_slave(struct slave *slave)
port->actor_admin_port_key |= (__get_link_speed(port) << 1);
port->actor_oper_port_key = port->actor_admin_port_key;
// if the port is not full duplex, then the port should be not lacp Enabled
- if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) {
+ if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS))
port->sm_vars &= ~AD_PORT_LACP_ENABLED;
- }
// actor system is the bond's system
port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr;
// tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second)
@@ -2006,9 +2009,10 @@ void bond_3ad_unbind_slave(struct slave *slave)
new_aggregator = __get_first_agg(port);
for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) {
// if the new aggregator is empty, or it is connected to our port only
- if (!new_aggregator->lag_ports || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator)) {
+ if (!new_aggregator->lag_ports
+ || ((new_aggregator->lag_ports == port)
+ && !new_aggregator->lag_ports->next_port_in_aggregator))
break;
- }
}
// if new aggregator found, copy the aggregator's parameters
// and connect the related lag_ports to the new aggregator
@@ -2037,17 +2041,17 @@ void bond_3ad_unbind_slave(struct slave *slave)
new_aggregator->num_of_ports = aggregator->num_of_ports;
// update the information that is written on the ports about the aggregator
- for (temp_port=aggregator->lag_ports; temp_port; temp_port=temp_port->next_port_in_aggregator) {
- temp_port->aggregator=new_aggregator;
+ for (temp_port = aggregator->lag_ports; temp_port;
+ temp_port = temp_port->next_port_in_aggregator) {
+ temp_port->aggregator = new_aggregator;
temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier;
}
// clear the aggregator
ad_clear_agg(aggregator);
- if (select_new_active_agg) {
+ if (select_new_active_agg)
ad_agg_selection_logic(__get_first_agg(port));
- }
} else {
pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n",
slave->dev->master->name);
@@ -2071,15 +2075,16 @@ void bond_3ad_unbind_slave(struct slave *slave)
for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) {
prev_port = NULL;
// search the port in the aggregator's related ports
- for (temp_port=temp_aggregator->lag_ports; temp_port; prev_port=temp_port, temp_port=temp_port->next_port_in_aggregator) {
+ for (temp_port = temp_aggregator->lag_ports; temp_port;
+ prev_port = temp_port,
+ temp_port = temp_port->next_port_in_aggregator) {
if (temp_port == port) { // the aggregator found - detach the port from this aggregator
- if (prev_port) {
+ if (prev_port)
prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator;
- } else {
+ else
temp_aggregator->lag_ports = temp_port->next_port_in_aggregator;
- }
temp_aggregator->num_of_ports--;
- if (temp_aggregator->num_of_ports==0) {
+ if (temp_aggregator->num_of_ports == 0) {
select_new_active_agg = temp_aggregator->is_active;
// clear the aggregator
ad_clear_agg(temp_aggregator);
@@ -2094,7 +2099,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
}
}
}
- port->slave=NULL;
+ port->slave = NULL;
}
/**
@@ -2119,14 +2124,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
read_lock(&bond->lock);
- if (bond->kill_timers) {
+ if (bond->kill_timers)
goto out;
- }
//check if there are any slaves
- if (bond->slave_cnt == 0) {
+ if (bond->slave_cnt == 0)
goto re_arm;
- }
// check if agg_select_timer timer after initialize is timed out
if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) {
@@ -2159,9 +2162,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
ad_tx_machine(port);
// turn off the BEGIN bit, since we already handled it
- if (port->sm_vars & AD_PORT_BEGIN) {
+ if (port->sm_vars & AD_PORT_BEGIN)
port->sm_vars &= ~AD_PORT_BEGIN;
- }
}
re_arm:
@@ -2245,7 +2247,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
}
port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
- port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1);
+ port->actor_oper_port_key = port->actor_admin_port_key |=
+ (__get_link_speed(port) << 1);
pr_debug("Port %d changed speed\n", port->actor_port_number);
// there is no need to reselect a new aggregator, just signal the
// state machines to reinitialize
@@ -2262,7 +2265,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
{
struct port *port;
- port=&(SLAVE_AD_INFO(slave).port);
+ port = &(SLAVE_AD_INFO(slave).port);
// if slave is null, the whole port is not initialized
if (!port->slave) {
@@ -2272,7 +2275,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
}
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
- port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port);
+ port->actor_oper_port_key = port->actor_admin_port_key |=
+ __get_duplex(port);
pr_debug("Port %d changed duplex\n", port->actor_port_number);
// there is no need to reselect a new aggregator, just signal the
// state machines to reinitialize
@@ -2304,14 +2308,17 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
if (link == BOND_LINK_UP) {
port->is_enabled = true;
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
- port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port);
+ port->actor_oper_port_key = port->actor_admin_port_key |=
+ __get_duplex(port);
port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
- port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1);
+ port->actor_oper_port_key = port->actor_admin_port_key |=
+ (__get_link_speed(port) << 1);
} else {
/* link has failed */
port->is_enabled = false;
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
- port->actor_oper_port_key= (port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS);
+ port->actor_oper_port_key = (port->actor_admin_port_key &=
+ ~AD_SPEED_KEY_BITS);
}
//BOND_PRINT_DBG(("Port %d changed link status to %s", port->actor_port_number, ((link == BOND_LINK_UP)?"UP":"DOWN")));
// there is no need to reselect a new aggregator, just signal the
@@ -2394,9 +2401,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
*/
read_lock(&bond->lock);
- if (!BOND_IS_OK(bond)) {
+ 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",
@@ -2420,9 +2426,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if (agg && (agg->aggregator_identifier == agg_id)) {
slave_agg_no--;
- if (slave_agg_no < 0) {
+ if (slave_agg_no < 0)
break;
- }
}
}
@@ -2438,9 +2443,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
int slave_agg_id = 0;
struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
- if (agg) {
+ if (agg)
slave_agg_id = agg->aggregator_identifier;
- }
if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index e953c6ad6e6d..beb3b7cecd52 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -76,6 +76,7 @@
#include <linux/if_vlan.h>
#include <linux/if_bonding.h>
#include <linux/jiffies.h>
+#include <linux/preempt.h>
#include <net/route.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
@@ -109,6 +110,7 @@ static char *arp_validate;
static char *fail_over_mac;
static int all_slaves_active = 0;
static struct bond_params bonding_defaults;
+static int resend_igmp = BOND_DEFAULT_RESEND_IGMP;
module_param(max_bonds, int, 0);
MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -163,9 +165,15 @@ module_param(all_slaves_active, int, 0);
MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface"
"by setting active flag for all slaves. "
"0 for never (default), 1 for always.");
+module_param(resend_igmp, int, 0);
+MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link failure");
/*----------------------------- Global variables ----------------------------*/
+#ifdef CONFIG_NET_POLL_CONTROLLER
+cpumask_var_t netpoll_block_tx;
+#endif
+
static const char * const version =
DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
@@ -176,9 +184,6 @@ static int arp_ip_count;
static int bond_mode = BOND_MODE_ROUNDROBIN;
static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2;
static int lacp_fast;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static int disable_netpoll = 1;
-#endif
const struct bond_parm_tbl bond_lacp_tbl[] = {
{ "slow", AD_LACP_SLOW},
@@ -307,6 +312,7 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id)
pr_debug("bond: %s, vlan id %d\n", bond->dev->name, vlan_id);
+ block_netpoll_tx();
write_lock_bh(&bond->lock);
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
@@ -341,6 +347,7 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id)
out:
write_unlock_bh(&bond->lock);
+ unblock_netpoll_tx();
return res;
}
@@ -446,11 +453,9 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) {
struct netpoll *np = bond->dev->npinfo->netpoll;
slave_dev->npinfo = bond->dev->npinfo;
- np->real_dev = np->dev = skb->dev;
slave_dev->priv_flags |= IFF_IN_NETPOLL;
- netpoll_send_skb(np, skb);
+ netpoll_send_skb_on_dev(np, skb, slave_dev);
slave_dev->priv_flags &= ~IFF_IN_NETPOLL;
- np->dev = bond->dev;
} else
#endif
dev_queue_xmit(skb);
@@ -865,18 +870,13 @@ static void bond_mc_del(struct bonding *bond, void *addr)
}
-/*
- * Retrieve the list of registered multicast addresses for the bonding
- * device and retransmit an IGMP JOIN request to the current active
- * slave.
- */
-static void bond_resend_igmp_join_requests(struct bonding *bond)
+static void __bond_resend_igmp_join_requests(struct net_device *dev)
{
struct in_device *in_dev;
struct ip_mc_list *im;
rcu_read_lock();
- in_dev = __in_dev_get_rcu(bond->dev);
+ in_dev = __in_dev_get_rcu(dev);
if (in_dev) {
for (im = in_dev->mc_list; im; im = im->next)
ip_mc_rejoin_group(im);
@@ -886,6 +886,44 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
}
/*
+ * Retrieve the list of registered multicast addresses for the bonding
+ * device and retransmit an IGMP JOIN request to the current active
+ * slave.
+ */
+static void bond_resend_igmp_join_requests(struct bonding *bond)
+{
+ struct net_device *vlan_dev;
+ struct vlan_entry *vlan;
+
+ read_lock(&bond->lock);
+
+ /* rejoin all groups on bond device */
+ __bond_resend_igmp_join_requests(bond->dev);
+
+ /* rejoin all groups on vlan devices */
+ if (bond->vlgrp) {
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
+ vlan_dev = vlan_group_get_device(bond->vlgrp,
+ vlan->vlan_id);
+ if (vlan_dev)
+ __bond_resend_igmp_join_requests(vlan_dev);
+ }
+ }
+
+ if (--bond->igmp_retrans > 0)
+ queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5);
+
+ read_unlock(&bond->lock);
+}
+
+static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
+{
+ struct bonding *bond = container_of(work, struct bonding,
+ mcast_work.work);
+ bond_resend_igmp_join_requests(bond);
+}
+
+/*
* flush all members of flush->mc_list from device dev->mc_list
*/
static void bond_mc_list_flush(struct net_device *bond_dev,
@@ -944,7 +982,6 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
netdev_for_each_mc_addr(ha, bond->dev)
dev_mc_add(new_active->dev, ha->addr);
- bond_resend_igmp_join_requests(bond);
}
}
@@ -1180,9 +1217,12 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
}
}
- /* resend IGMP joins since all were sent on curr_active_slave */
- if (bond->params.mode == BOND_MODE_ROUNDROBIN) {
- bond_resend_igmp_join_requests(bond);
+ /* resend IGMP joins since active slave has changed or
+ * all were sent on curr_active_slave */
+ if ((USES_PRIMARY(bond->params.mode) && new_active) ||
+ bond->params.mode == BOND_MODE_ROUNDROBIN) {
+ bond->igmp_retrans = bond->params.resend_igmp;
+ queue_delayed_work(bond->wq, &bond->mcast_work, 0);
}
}
@@ -1294,9 +1334,14 @@ static bool slaves_support_netpoll(struct net_device *bond_dev)
static void bond_poll_controller(struct net_device *bond_dev)
{
- struct net_device *dev = bond_dev->npinfo->netpoll->real_dev;
- if (dev != bond_dev)
- netpoll_poll_dev(dev);
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave;
+ int i;
+
+ bond_for_each_slave(bond, slave, i) {
+ if (slave->dev && IS_UP(slave->dev))
+ netpoll_poll_dev(slave->dev);
+ }
}
static void bond_netpoll_cleanup(struct net_device *bond_dev)
@@ -1763,23 +1808,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
bond_set_carrier(bond);
#ifdef CONFIG_NET_POLL_CONTROLLER
- /*
- * Netpoll and bonding is broken, make sure it is not initialized
- * until it is fixed.
- */
- if (disable_netpoll) {
+ if (slaves_support_netpoll(bond_dev)) {
+ bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
+ if (bond_dev->npinfo)
+ slave_dev->npinfo = bond_dev->npinfo;
+ } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) {
bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
- } else {
- if (slaves_support_netpoll(bond_dev)) {
- bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
- if (bond_dev->npinfo)
- slave_dev->npinfo = bond_dev->npinfo;
- } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) {
- bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
- pr_info("New slave device %s does not support netpoll\n",
- slave_dev->name);
- pr_info("Disabling netpoll support for %s\n", bond_dev->name);
- }
+ pr_info("New slave device %s does not support netpoll\n",
+ slave_dev->name);
+ pr_info("Disabling netpoll support for %s\n", bond_dev->name);
}
#endif
read_unlock(&bond->lock);
@@ -1851,6 +1888,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
return -EINVAL;
}
+ block_netpoll_tx();
netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE);
write_lock_bh(&bond->lock);
@@ -1860,6 +1898,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
pr_info("%s: %s not enslaved\n",
bond_dev->name, slave_dev->name);
write_unlock_bh(&bond->lock);
+ unblock_netpoll_tx();
return -EINVAL;
}
@@ -1953,6 +1992,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
}
write_unlock_bh(&bond->lock);
+ unblock_netpoll_tx();
/* must do this from outside any spinlocks */
bond_destroy_slave_symlinks(bond_dev, slave_dev);
@@ -1983,10 +2023,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
#ifdef CONFIG_NET_POLL_CONTROLLER
read_lock_bh(&bond->lock);
- /* Make sure netpoll over stays disabled until fixed. */
- if (!disable_netpoll)
- if (slaves_support_netpoll(bond_dev))
- bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
+ if (slaves_support_netpoll(bond_dev))
+ bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
read_unlock_bh(&bond->lock);
if (slave_dev->netdev_ops->ndo_netpoll_cleanup)
slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev);
@@ -2019,8 +2057,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
* First release a slave and than destroy the bond if no more slaves are left.
* Must be under rtnl_lock when this function is called.
*/
-int bond_release_and_destroy(struct net_device *bond_dev,
- struct net_device *slave_dev)
+static int bond_release_and_destroy(struct net_device *bond_dev,
+ struct net_device *slave_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
int ret;
@@ -2142,7 +2180,6 @@ static int bond_release_all(struct net_device *bond_dev)
out:
write_unlock_bh(&bond->lock);
-
return 0;
}
@@ -2191,9 +2228,11 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
(old_active) &&
(new_active->link == BOND_LINK_UP) &&
IS_UP(new_active->dev)) {
+ block_netpoll_tx();
write_lock_bh(&bond->curr_slave_lock);
bond_change_active_slave(bond, new_active);
write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
} else
res = -EINVAL;
@@ -2368,8 +2407,11 @@ static void bond_miimon_commit(struct bonding *bond)
slave->state = BOND_STATE_BACKUP;
}
- pr_info("%s: link status definitely up for interface %s.\n",
- bond->dev->name, slave->dev->name);
+ bond_update_speed_duplex(slave);
+
+ pr_info("%s: link status definitely up for interface %s, %d Mbps %s duplex.\n",
+ bond->dev->name, slave->dev->name,
+ slave->speed, slave->duplex ? "full" : "half");
/* notify ad that the link status has changed */
if (bond->params.mode == BOND_MODE_8023AD)
@@ -2422,9 +2464,11 @@ static void bond_miimon_commit(struct bonding *bond)
do_failover:
ASSERT_RTNL();
+ block_netpoll_tx();
write_lock_bh(&bond->curr_slave_lock);
bond_select_active_slave(bond);
write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
}
bond_set_carrier(bond);
@@ -2867,11 +2911,13 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
}
if (do_failover) {
+ block_netpoll_tx();
write_lock_bh(&bond->curr_slave_lock);
bond_select_active_slave(bond);
write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
}
re_arm:
@@ -3030,9 +3076,11 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
do_failover:
ASSERT_RTNL();
+ block_netpoll_tx();
write_lock_bh(&bond->curr_slave_lock);
bond_select_active_slave(bond);
write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
}
bond_set_carrier(bond);
@@ -3312,6 +3360,8 @@ static void bond_info_show_slave(struct seq_file *seq,
seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
seq_printf(seq, "MII Status: %s\n",
(slave->link == BOND_LINK_UP) ? "up" : "down");
+ seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
+ seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
seq_printf(seq, "Link Failure Count: %u\n",
slave->link_failure_count);
@@ -3744,6 +3794,8 @@ static int bond_open(struct net_device *bond_dev)
bond->kill_timers = 0;
+ INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed);
+
if (bond_is_lb(bond)) {
/* bond_alb_initialize must be called before the timer
* is started.
@@ -3828,6 +3880,8 @@ static int bond_close(struct net_device *bond_dev)
break;
}
+ if (delayed_work_pending(&bond->mcast_work))
+ cancel_delayed_work(&bond->mcast_work);
if (bond_is_lb(bond)) {
/* Must be called only after all
@@ -4514,6 +4568,13 @@ 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;
@@ -4678,6 +4739,10 @@ static void bond_setup(struct net_device *bond_dev)
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;
}
static void bond_work_cancel_all(struct bonding *bond)
@@ -4699,6 +4764,9 @@ static void bond_work_cancel_all(struct bonding *bond)
if (bond->params.mode == BOND_MODE_8023AD &&
delayed_work_pending(&bond->ad_work))
cancel_delayed_work(&bond->ad_work);
+
+ if (delayed_work_pending(&bond->mcast_work))
+ cancel_delayed_work(&bond->mcast_work);
}
/*
@@ -4891,6 +4959,13 @@ static int bond_check_params(struct bond_params *params)
all_slaves_active = 0;
}
+ if (resend_igmp < 0 || resend_igmp > 255) {
+ pr_warning("Warning: resend_igmp (%d) should be between "
+ "0 and 255, resetting to %d\n",
+ resend_igmp, BOND_DEFAULT_RESEND_IGMP);
+ resend_igmp = BOND_DEFAULT_RESEND_IGMP;
+ }
+
/* reset values for TLB/ALB */
if ((bond_mode == BOND_MODE_TLB) ||
(bond_mode == BOND_MODE_ALB)) {
@@ -5063,6 +5138,7 @@ static int bond_check_params(struct bond_params *params)
params->fail_over_mac = fail_over_mac_value;
params->tx_queues = tx_queues;
params->all_slaves_active = all_slaves_active;
+ params->resend_igmp = resend_igmp;
if (primary) {
strncpy(params->primary, primary, IFNAMSIZ);
@@ -5221,6 +5297,13 @@ static int __init bonding_init(void)
if (res)
goto out;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) {
+ res = -ENOMEM;
+ goto out;
+ }
+#endif
+
res = register_pernet_subsys(&bond_net_ops);
if (res)
goto out;
@@ -5239,6 +5322,7 @@ static int __init bonding_init(void)
if (res)
goto err;
+
register_netdevice_notifier(&bond_netdev_notifier);
register_inetaddr_notifier(&bond_inetaddr_notifier);
bond_register_ipv6_notifier();
@@ -5248,6 +5332,9 @@ err:
rtnl_link_unregister(&bond_link_ops);
err_link:
unregister_pernet_subsys(&bond_net_ops);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ free_cpumask_var(netpoll_block_tx);
+#endif
goto out;
}
@@ -5262,6 +5349,10 @@ static void __exit bonding_exit(void)
rtnl_link_unregister(&bond_link_ops);
unregister_pernet_subsys(&bond_net_ops);
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ free_cpumask_var(netpoll_block_tx);
+#endif
}
module_init(bonding_init);
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index c311aed9bd02..8fd0174c5380 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1066,6 +1066,7 @@ static ssize_t bonding_store_primary(struct device *d,
if (!rtnl_trylock())
return restart_syscall();
+ block_netpoll_tx();
read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
@@ -1101,6 +1102,7 @@ static ssize_t bonding_store_primary(struct device *d,
out:
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
+ unblock_netpoll_tx();
rtnl_unlock();
return count;
@@ -1146,11 +1148,13 @@ static ssize_t bonding_store_primary_reselect(struct device *d,
bond->dev->name, pri_reselect_tbl[new_value].modename,
new_value);
+ block_netpoll_tx();
read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
bond_select_active_slave(bond);
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
+ unblock_netpoll_tx();
out:
rtnl_unlock();
return ret;
@@ -1232,6 +1236,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
if (!rtnl_trylock())
return restart_syscall();
+
+ block_netpoll_tx();
read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
@@ -1288,6 +1294,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
out:
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
+ unblock_netpoll_tx();
+
rtnl_unlock();
return count;
@@ -1592,6 +1600,49 @@ out:
static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR,
bonding_show_slaves_active, bonding_store_slaves_active);
+/*
+ * Show and set the number of IGMP membership reports to send on link failure
+ */
+static ssize_t bonding_show_resend_igmp(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bonding *bond = to_bond(d);
+
+ return sprintf(buf, "%d\n", bond->params.resend_igmp);
+}
+
+static ssize_t bonding_store_resend_igmp(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 resend_igmp value specified.\n",
+ bond->dev->name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (new_value < 0) {
+ pr_err("%s: Invalid resend_igmp value %d not in range 0-255; rejected.\n",
+ bond->dev->name, new_value);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ pr_info("%s: Setting resend_igmp to %d.\n",
+ bond->dev->name, new_value);
+ bond->params.resend_igmp = new_value;
+out:
+ return ret;
+}
+
+static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR,
+ bonding_show_resend_igmp, bonding_store_resend_igmp);
+
static struct attribute *per_bond_attrs[] = {
&dev_attr_slaves.attr,
&dev_attr_mode.attr,
@@ -1619,6 +1670,7 @@ static struct attribute *per_bond_attrs[] = {
&dev_attr_ad_partner_mac.attr,
&dev_attr_queue_id.attr,
&dev_attr_all_slaves_active.attr,
+ &dev_attr_resend_igmp.attr,
NULL,
};
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index c6fdd851579a..4eedb12df6ca 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -19,6 +19,7 @@
#include <linux/proc_fs.h>
#include <linux/if_bonding.h>
#include <linux/kobject.h>
+#include <linux/cpumask.h>
#include <linux/in6.h>
#include "bond_3ad.h"
#include "bond_alb.h"
@@ -117,6 +118,35 @@
bond_for_each_slave_from(bond, pos, cnt, (bond)->first_slave)
+#ifdef CONFIG_NET_POLL_CONTROLLER
+extern cpumask_var_t netpoll_block_tx;
+
+static inline void block_netpoll_tx(void)
+{
+ preempt_disable();
+ BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(),
+ netpoll_block_tx));
+}
+
+static inline void unblock_netpoll_tx(void)
+{
+ BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(),
+ netpoll_block_tx));
+ preempt_enable();
+}
+
+static inline int is_netpoll_tx_blocked(struct net_device *dev)
+{
+ if (unlikely(dev->priv_flags & IFF_IN_NETPOLL))
+ return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx);
+ return 0;
+}
+#else
+#define block_netpoll_tx()
+#define unblock_netpoll_tx()
+#define is_netpoll_tx_blocked(dev) (0)
+#endif
+
struct bond_params {
int mode;
int xmit_policy;
@@ -136,6 +166,7 @@ struct bond_params {
__be32 arp_targets[BOND_MAX_ARP_TARGETS];
int tx_queues;
int all_slaves_active;
+ int resend_igmp;
};
struct bond_parm_tbl {
@@ -202,6 +233,7 @@ struct bonding {
s8 send_grat_arp;
s8 send_unsol_na;
s8 setup_by_slave;
+ s8 igmp_retrans;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry;
char proc_file_name[IFNAMSIZ];
@@ -223,6 +255,7 @@ struct bonding {
struct delayed_work arp_work;
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
@@ -331,7 +364,6 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
int bond_create(struct net *net, const char *name);
-int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_create_sysfs(void);
void bond_destroy_sysfs(void);
void bond_prepare_sysfs_group(struct bonding *bond);
diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c
index 88edb986691a..6e99d80ec409 100644
--- a/drivers/net/bsd_comp.c
+++ b/drivers/net/bsd_comp.c
@@ -429,7 +429,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp)
if (!db->lens)
{
bsd_free (db);
- return (NULL);
+ return NULL;
}
}
/*
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
index b11a0cb5ed81..6aadc3e32bd5 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -38,14 +38,14 @@
* static struct mcp251x_platform_data mcp251x_info = {
* .oscillator_frequency = 8000000,
* .board_specific_setup = &mcp251x_setup,
- * .model = CAN_MCP251X_MCP2510,
* .power_enable = mcp251x_power_enable,
* .transceiver_enable = NULL,
* };
*
* static struct spi_board_info spi_board_info[] = {
* {
- * .modalias = "mcp251x",
+ * .modalias = "mcp2510",
+ * // or "mcp2515" depending on your controller
* .platform_data = &mcp251x_info,
* .irq = IRQ_EINT13,
* .max_speed_hz = 2*1000*1000,
@@ -125,6 +125,9 @@
# define CANINTF_TX0IF 0x04
# define CANINTF_RX1IF 0x02
# define CANINTF_RX0IF 0x01
+# define CANINTF_RX (CANINTF_RX0IF | CANINTF_RX1IF)
+# define CANINTF_TX (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)
+# define CANINTF_ERR (CANINTF_ERRIF)
#define EFLG 0x2d
# define EFLG_EWARN 0x01
# define EFLG_RXWAR 0x02
@@ -222,10 +225,16 @@ static struct can_bittiming_const mcp251x_bittiming_const = {
.brp_inc = 1,
};
+enum mcp251x_model {
+ CAN_MCP251X_MCP2510 = 0x2510,
+ CAN_MCP251X_MCP2515 = 0x2515,
+};
+
struct mcp251x_priv {
struct can_priv can;
struct net_device *net;
struct spi_device *spi;
+ enum mcp251x_model model;
struct mutex mcp_lock; /* SPI device lock */
@@ -250,6 +259,16 @@ struct mcp251x_priv {
int restart_tx;
};
+#define MCP251X_IS(_model) \
+static inline int mcp251x_is_##_model(struct spi_device *spi) \
+{ \
+ struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); \
+ return priv->model == CAN_MCP251X_MCP##_model; \
+}
+
+MCP251X_IS(2510);
+MCP251X_IS(2515);
+
static void mcp251x_clean(struct net_device *net)
{
struct mcp251x_priv *priv = netdev_priv(net);
@@ -319,6 +338,20 @@ static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg)
return val;
}
+static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg,
+ uint8_t *v1, uint8_t *v2)
+{
+ struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+
+ priv->spi_tx_buf[0] = INSTRUCTION_READ;
+ priv->spi_tx_buf[1] = reg;
+
+ mcp251x_spi_trans(spi, 4);
+
+ *v1 = priv->spi_rx_buf[2];
+ *v2 = priv->spi_rx_buf[3];
+}
+
static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val)
{
struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
@@ -346,10 +379,9 @@ static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,
int len, int tx_buf_idx)
{
- struct mcp251x_platform_data *pdata = spi->dev.platform_data;
struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
- if (pdata->model == CAN_MCP251X_MCP2510) {
+ if (mcp251x_is_2510(spi)) {
int i;
for (i = 1; i < TXBDAT_OFF + len; i++)
@@ -392,9 +424,8 @@ static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
int buf_idx)
{
struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
- struct mcp251x_platform_data *pdata = spi->dev.platform_data;
- if (pdata->model == CAN_MCP251X_MCP2510) {
+ if (mcp251x_is_2510(spi)) {
int i, len;
for (i = 1; i < RXBDAT_OFF; i++)
@@ -451,7 +482,7 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
priv->net->stats.rx_packets++;
priv->net->stats.rx_bytes += frame->can_dlc;
- netif_rx(skb);
+ netif_rx_ni(skb);
}
static void mcp251x_hw_sleep(struct spi_device *spi)
@@ -674,9 +705,9 @@ static void mcp251x_error_skb(struct net_device *net, int can_id, int data1)
skb = alloc_can_err_skb(net, &frame);
if (skb) {
- frame->can_id = can_id;
+ frame->can_id |= can_id;
frame->data[1] = data1;
- netif_rx(skb);
+ netif_rx_ni(skb);
} else {
dev_err(&net->dev,
"cannot allocate error skb\n");
@@ -754,24 +785,42 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
mutex_lock(&priv->mcp_lock);
while (!priv->force_quit) {
enum can_state new_state;
- u8 intf = mcp251x_read_reg(spi, CANINTF);
- u8 eflag;
+ u8 intf, eflag;
+ u8 clear_intf = 0;
int can_id = 0, data1 = 0;
+ mcp251x_read_2regs(spi, CANINTF, &intf, &eflag);
+
+ /* mask out flags we don't care about */
+ intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR;
+
+ /* receive buffer 0 */
if (intf & CANINTF_RX0IF) {
mcp251x_hw_rx(spi, 0);
- /* Free one buffer ASAP */
- mcp251x_write_bits(spi, CANINTF, intf & CANINTF_RX0IF,
- 0x00);
+ /*
+ * Free one buffer ASAP
+ * (The MCP2515 does this automatically.)
+ */
+ if (mcp251x_is_2510(spi))
+ mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00);
}
- if (intf & CANINTF_RX1IF)
+ /* receive buffer 1 */
+ if (intf & CANINTF_RX1IF) {
mcp251x_hw_rx(spi, 1);
+ /* the MCP2515 does this automatically */
+ if (mcp251x_is_2510(spi))
+ clear_intf |= CANINTF_RX1IF;
+ }
- mcp251x_write_bits(spi, CANINTF, intf, 0x00);
+ /* any error or tx interrupt we need to clear? */
+ if (intf & (CANINTF_ERR | CANINTF_TX))
+ clear_intf |= intf & (CANINTF_ERR | CANINTF_TX);
+ if (clear_intf)
+ mcp251x_write_bits(spi, CANINTF, clear_intf, 0x00);
- eflag = mcp251x_read_reg(spi, EFLG);
- mcp251x_write_reg(spi, EFLG, 0x00);
+ if (eflag)
+ mcp251x_write_bits(spi, EFLG, eflag, 0x00);
/* Update can state */
if (eflag & EFLG_TXBO) {
@@ -816,10 +865,14 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
if (intf & CANINTF_ERRIF) {
/* Handle overflow counters */
if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) {
- if (eflag & EFLG_RX0OVR)
+ if (eflag & EFLG_RX0OVR) {
net->stats.rx_over_errors++;
- if (eflag & EFLG_RX1OVR)
+ net->stats.rx_errors++;
+ }
+ if (eflag & EFLG_RX1OVR) {
net->stats.rx_over_errors++;
+ net->stats.rx_errors++;
+ }
can_id |= CAN_ERR_CRTL;
data1 |= CAN_ERR_CRTL_RX_OVERFLOW;
}
@@ -838,7 +891,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
if (intf == 0)
break;
- if (intf & (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)) {
+ if (intf & CANINTF_TX) {
net->stats.tx_packets++;
net->stats.tx_bytes += priv->tx_len - 1;
if (priv->tx_len) {
@@ -921,16 +974,12 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi)
struct net_device *net;
struct mcp251x_priv *priv;
struct mcp251x_platform_data *pdata = spi->dev.platform_data;
- int model = spi_get_device_id(spi)->driver_data;
int ret = -ENODEV;
if (!pdata)
/* Platform data is required for osc freq */
goto error_out;
- if (model)
- pdata->model = model;
-
/* Allocate can/net device */
net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX);
if (!net) {
@@ -947,6 +996,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi)
priv->can.clock.freq = pdata->oscillator_frequency / 2;
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
+ priv->model = spi_get_device_id(spi)->driver_data;
priv->net = net;
dev_set_drvdata(&spi->dev, priv);
@@ -1120,8 +1170,7 @@ static int mcp251x_can_resume(struct spi_device *spi)
#define mcp251x_can_resume NULL
#endif
-static struct spi_device_id mcp251x_id_table[] = {
- { "mcp251x", 0 /* Use pdata.model */ },
+static const struct spi_device_id mcp251x_id_table[] = {
{ "mcp2510", CAN_MCP251X_MCP2510 },
{ "mcp2515", CAN_MCP251X_MCP2515 },
{ },
diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
index b1bdc909090f..312b9c8f4f3b 100644
--- a/drivers/net/can/mscan/mpc5xxx_can.c
+++ b/drivers/net/can/mscan/mpc5xxx_can.c
@@ -143,12 +143,12 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev,
np_clock = of_find_matching_node(NULL, mpc512x_clock_ids);
if (!np_clock) {
dev_err(&ofdev->dev, "couldn't find clock node\n");
- return -ENODEV;
+ return 0;
}
clockctl = of_iomap(np_clock, 0);
if (!clockctl) {
dev_err(&ofdev->dev, "couldn't map clock registers\n");
- return 0;
+ goto exit_put;
}
/* Determine the MSCAN device index from the physical address */
@@ -233,9 +233,9 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev,
clocksrc == 1 ? "ref_clk" : "sys_clk", clockdiv);
exit_unmap:
- of_node_put(np_clock);
iounmap(clockctl);
-
+exit_put:
+ of_node_put(np_clock);
return freq;
}
#else /* !CONFIG_PPC_MPC512x */
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 28c88eeec757..d6b6d6aa565a 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -419,7 +419,7 @@ static u16 cas_phy_read(struct cas *cp, int reg)
udelay(10);
cmd = readl(cp->regs + REG_MIF_FRAME);
if (cmd & MIF_FRAME_TURN_AROUND_LSB)
- return (cmd & MIF_FRAME_DATA_MASK);
+ return cmd & MIF_FRAME_DATA_MASK;
}
return 0xFFFF; /* -1 */
}
@@ -804,7 +804,7 @@ static int cas_reset_mii_phy(struct cas *cp)
break;
udelay(10);
}
- return (limit <= 0);
+ return limit <= 0;
}
static int cas_saturn_firmware_init(struct cas *cp)
@@ -2149,7 +2149,7 @@ end_copy_pkt:
skb->csum = csum_unfold(~csum);
skb->ip_summed = CHECKSUM_COMPLETE;
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
return len;
}
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index f01cfdb995de..70221ca32683 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1388,7 +1388,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
++st->rx_cso_good;
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (unlikely(adapter->vlan_grp && p->vlan_valid)) {
st->vlan_xtract++;
@@ -1551,7 +1551,7 @@ static inline int responses_pending(const struct adapter *adapter)
const struct respQ *Q = &adapter->sge->respQ;
const struct respQ_e *e = &Q->entries[Q->cidx];
- return (e->GenerationBit == Q->genbit);
+ return e->GenerationBit == Q->genbit;
}
/*
@@ -1870,7 +1870,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
cpl->iff = dev->if_port;
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
cpl->vlan_valid = 1;
cpl->vlan = htons(vlan_tx_tag_get(skb));
st->vlan_insert++;
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c
index 599d178df62d..63ebf76d2390 100644
--- a/drivers/net/chelsio/subr.c
+++ b/drivers/net/chelsio/subr.c
@@ -314,14 +314,12 @@ static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr,
return 0;
}
-#if defined(CONFIG_CHELSIO_T1_1G)
static const struct mdio_ops mi1_mdio_ops = {
.init = mi1_mdio_init,
.read = mi1_mdio_read,
.write = mi1_mdio_write,
.mode_support = MDIO_SUPPORTS_C22
};
-#endif
#endif
diff --git a/drivers/net/chelsio/vsc7326.c b/drivers/net/chelsio/vsc7326.c
index c844111cffeb..106a590f0d9a 100644
--- a/drivers/net/chelsio/vsc7326.c
+++ b/drivers/net/chelsio/vsc7326.c
@@ -255,7 +255,7 @@ static int bist_rd(adapter_t *adapter, int moduleid, int address)
else if ((result & (1 << 8)) != 0x0)
pr_err("bist read error: 0x%x\n", result);
- return (result & 0xff);
+ return result & 0xff;
}
static int bist_wr(adapter_t *adapter, int moduleid, int address, int value)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 09610323a948..92bac19ad60a 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -60,6 +60,7 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(CNIC_MODULE_VERSION);
static LIST_HEAD(cnic_dev_list);
+static LIST_HEAD(cnic_udev_list);
static DEFINE_RWLOCK(cnic_dev_lock);
static DEFINE_MUTEX(cnic_lock);
@@ -81,29 +82,34 @@ static struct cnic_ops cnic_bnx2x_ops = {
.cnic_ctl = cnic_ctl,
};
+static struct workqueue_struct *cnic_wq;
+
static void cnic_shutdown_rings(struct cnic_dev *);
static void cnic_init_rings(struct cnic_dev *);
static int cnic_cm_set_pg(struct cnic_sock *);
static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode)
{
- struct cnic_dev *dev = uinfo->priv;
- struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_uio_dev *udev = uinfo->priv;
+ struct cnic_dev *dev;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (cp->uio_dev != -1)
+ if (udev->uio_dev != -1)
return -EBUSY;
rtnl_lock();
- if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) {
+ dev = udev->dev;
+
+ if (!dev || !test_bit(CNIC_F_CNIC_UP, &dev->flags)) {
rtnl_unlock();
return -ENODEV;
}
- cp->uio_dev = iminor(inode);
+ udev->uio_dev = iminor(inode);
+ cnic_shutdown_rings(dev);
cnic_init_rings(dev);
rtnl_unlock();
@@ -112,12 +118,9 @@ static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode)
static int cnic_uio_close(struct uio_info *uinfo, struct inode *inode)
{
- struct cnic_dev *dev = uinfo->priv;
- struct cnic_local *cp = dev->cnic_priv;
-
- cnic_shutdown_rings(dev);
+ struct cnic_uio_dev *udev = uinfo->priv;
- cp->uio_dev = -1;
+ udev->uio_dev = -1;
return 0;
}
@@ -242,14 +245,14 @@ static int cnic_in_use(struct cnic_sock *csk)
return test_bit(SK_F_INUSE, &csk->flags);
}
-static void cnic_kwq_completion(struct cnic_dev *dev, u32 count)
+static void cnic_spq_completion(struct cnic_dev *dev, int cmd, u32 count)
{
struct cnic_local *cp = dev->cnic_priv;
struct cnic_eth_dev *ethdev = cp->ethdev;
struct drv_ctl_info info;
- info.cmd = DRV_CTL_COMPLETION_CMD;
- info.data.comp.comp_count = count;
+ info.cmd = cmd;
+ info.data.credit.credit_count = count;
ethdev->drv_ctl(dev->netdev, &info);
}
@@ -274,8 +277,9 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type,
u16 len = 0;
u32 msg_type = ISCSI_KEVENT_IF_DOWN;
struct cnic_ulp_ops *ulp_ops;
+ struct cnic_uio_dev *udev = cp->udev;
- if (cp->uio_dev == -1)
+ if (!udev || udev->uio_dev == -1)
return -ENODEV;
if (csk) {
@@ -406,8 +410,7 @@ static void cnic_uio_stop(void)
list_for_each_entry(dev, &cnic_dev_list, list) {
struct cnic_local *cp = dev->cnic_priv;
- if (cp->cnic_uinfo)
- cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
+ cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
}
read_unlock(&cnic_dev_lock);
}
@@ -768,31 +771,45 @@ static void cnic_free_context(struct cnic_dev *dev)
}
}
-static void cnic_free_resc(struct cnic_dev *dev)
+static void __cnic_free_uio(struct cnic_uio_dev *udev)
{
- struct cnic_local *cp = dev->cnic_priv;
- int i = 0;
+ uio_unregister_device(&udev->cnic_uinfo);
- if (cp->cnic_uinfo) {
- while (cp->uio_dev != -1 && i < 15) {
- msleep(100);
- i++;
- }
- uio_unregister_device(cp->cnic_uinfo);
- kfree(cp->cnic_uinfo);
- cp->cnic_uinfo = NULL;
+ if (udev->l2_buf) {
+ dma_free_coherent(&udev->pdev->dev, udev->l2_buf_size,
+ udev->l2_buf, udev->l2_buf_map);
+ udev->l2_buf = NULL;
}
- if (cp->l2_buf) {
- dma_free_coherent(&dev->pcidev->dev, cp->l2_buf_size,
- cp->l2_buf, cp->l2_buf_map);
- cp->l2_buf = NULL;
+ if (udev->l2_ring) {
+ dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size,
+ udev->l2_ring, udev->l2_ring_map);
+ udev->l2_ring = NULL;
}
- if (cp->l2_ring) {
- dma_free_coherent(&dev->pcidev->dev, cp->l2_ring_size,
- cp->l2_ring, cp->l2_ring_map);
- cp->l2_ring = NULL;
+ pci_dev_put(udev->pdev);
+ kfree(udev);
+}
+
+static void cnic_free_uio(struct cnic_uio_dev *udev)
+{
+ if (!udev)
+ return;
+
+ write_lock(&cnic_dev_lock);
+ list_del_init(&udev->list);
+ write_unlock(&cnic_dev_lock);
+ __cnic_free_uio(udev);
+}
+
+static void cnic_free_resc(struct cnic_dev *dev)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_uio_dev *udev = cp->udev;
+
+ if (udev) {
+ udev->dev = NULL;
+ cp->udev = NULL;
}
cnic_free_context(dev);
@@ -894,37 +911,68 @@ static int cnic_alloc_kcq(struct cnic_dev *dev, struct kcq_info *info)
return 0;
}
-static int cnic_alloc_l2_rings(struct cnic_dev *dev, int pages)
+static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
{
struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_uio_dev *udev;
+
+ read_lock(&cnic_dev_lock);
+ list_for_each_entry(udev, &cnic_udev_list, list) {
+ if (udev->pdev == dev->pcidev) {
+ udev->dev = dev;
+ cp->udev = udev;
+ read_unlock(&cnic_dev_lock);
+ return 0;
+ }
+ }
+ read_unlock(&cnic_dev_lock);
+
+ udev = kzalloc(sizeof(struct cnic_uio_dev), GFP_ATOMIC);
+ if (!udev)
+ return -ENOMEM;
- cp->l2_ring_size = pages * BCM_PAGE_SIZE;
- cp->l2_ring = dma_alloc_coherent(&dev->pcidev->dev, cp->l2_ring_size,
- &cp->l2_ring_map,
- GFP_KERNEL | __GFP_COMP);
- if (!cp->l2_ring)
+ udev->uio_dev = -1;
+
+ udev->dev = dev;
+ udev->pdev = dev->pcidev;
+ udev->l2_ring_size = pages * BCM_PAGE_SIZE;
+ udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size,
+ &udev->l2_ring_map,
+ GFP_KERNEL | __GFP_COMP);
+ if (!udev->l2_ring)
return -ENOMEM;
- cp->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
- cp->l2_buf_size = PAGE_ALIGN(cp->l2_buf_size);
- cp->l2_buf = dma_alloc_coherent(&dev->pcidev->dev, cp->l2_buf_size,
- &cp->l2_buf_map,
- GFP_KERNEL | __GFP_COMP);
- if (!cp->l2_buf)
+ udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
+ udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size);
+ udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size,
+ &udev->l2_buf_map,
+ GFP_KERNEL | __GFP_COMP);
+ if (!udev->l2_buf)
return -ENOMEM;
+ write_lock(&cnic_dev_lock);
+ list_add(&udev->list, &cnic_udev_list);
+ write_unlock(&cnic_dev_lock);
+
+ pci_dev_get(udev->pdev);
+
+ cp->udev = udev;
+
return 0;
}
-static int cnic_alloc_uio(struct cnic_dev *dev) {
+static int cnic_init_uio(struct cnic_dev *dev)
+{
struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_uio_dev *udev = cp->udev;
struct uio_info *uinfo;
- int ret;
+ int ret = 0;
- uinfo = kzalloc(sizeof(*uinfo), GFP_ATOMIC);
- if (!uinfo)
+ if (!udev)
return -ENOMEM;
+ uinfo = &udev->cnic_uinfo;
+
uinfo->mem[0].addr = dev->netdev->base_addr;
uinfo->mem[0].internal_addr = dev->regview;
uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start;
@@ -932,7 +980,7 @@ static int cnic_alloc_uio(struct cnic_dev *dev) {
if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen &
- PAGE_MASK;
+ PAGE_MASK;
if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX)
uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9;
else
@@ -942,19 +990,19 @@ static int cnic_alloc_uio(struct cnic_dev *dev) {
} else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk &
PAGE_MASK;
- uinfo->mem[1].size = sizeof(struct host_def_status_block);
+ uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk);
uinfo->name = "bnx2x_cnic";
}
uinfo->mem[1].memtype = UIO_MEM_LOGICAL;
- uinfo->mem[2].addr = (unsigned long) cp->l2_ring;
- uinfo->mem[2].size = cp->l2_ring_size;
+ uinfo->mem[2].addr = (unsigned long) udev->l2_ring;
+ uinfo->mem[2].size = udev->l2_ring_size;
uinfo->mem[2].memtype = UIO_MEM_LOGICAL;
- uinfo->mem[3].addr = (unsigned long) cp->l2_buf;
- uinfo->mem[3].size = cp->l2_buf_size;
+ uinfo->mem[3].addr = (unsigned long) udev->l2_buf;
+ uinfo->mem[3].size = udev->l2_buf_size;
uinfo->mem[3].memtype = UIO_MEM_LOGICAL;
uinfo->version = CNIC_MODULE_VERSION;
@@ -963,16 +1011,17 @@ static int cnic_alloc_uio(struct cnic_dev *dev) {
uinfo->open = cnic_uio_open;
uinfo->release = cnic_uio_close;
- uinfo->priv = dev;
+ if (udev->uio_dev == -1) {
+ if (!uinfo->priv) {
+ uinfo->priv = udev;
- ret = uio_register_device(&dev->pcidev->dev, uinfo);
- if (ret) {
- kfree(uinfo);
- return ret;
+ ret = uio_register_device(&udev->pdev->dev, uinfo);
+ }
+ } else {
+ cnic_init_rings(dev);
}
- cp->cnic_uinfo = uinfo;
- return 0;
+ return ret;
}
static int cnic_alloc_bnx2_resc(struct cnic_dev *dev)
@@ -993,11 +1042,11 @@ static int cnic_alloc_bnx2_resc(struct cnic_dev *dev)
if (ret)
goto error;
- ret = cnic_alloc_l2_rings(dev, 2);
+ ret = cnic_alloc_uio_rings(dev, 2);
if (ret)
goto error;
- ret = cnic_alloc_uio(dev);
+ ret = cnic_init_uio(dev);
if (ret)
goto error;
@@ -1022,13 +1071,13 @@ static int cnic_alloc_bnx2x_context(struct cnic_dev *dev)
if (blks > cp->ethdev->ctx_tbl_len)
return -ENOMEM;
- cp->ctx_arr = kzalloc(blks * sizeof(struct cnic_ctx), GFP_KERNEL);
+ cp->ctx_arr = kcalloc(blks, sizeof(struct cnic_ctx), GFP_KERNEL);
if (cp->ctx_arr == NULL)
return -ENOMEM;
cp->ctx_blks = blks;
cp->ctx_blk_size = ctx_blk_size;
- if (BNX2X_CHIP_IS_E1H(cp->chip_id))
+ if (!BNX2X_CHIP_IS_57710(cp->chip_id))
cp->ctx_align = 0;
else
cp->ctx_align = ctx_blk_size;
@@ -1063,6 +1112,8 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
int i, j, n, ret, pages;
struct cnic_dma *kwq_16_dma = &cp->kwq_16_data_info;
+ cp->iro_arr = ethdev->iro_arr;
+
cp->max_cid_space = MAX_ISCSI_TBL_SZ;
cp->iscsi_start_cid = start_cid;
if (start_cid < BNX2X_ISCSI_START_CID) {
@@ -1127,15 +1178,13 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
cp->bnx2x_def_status_blk = cp->ethdev->irq_arr[1].status_blk;
- memset(cp->status_blk.bnx2x, 0, sizeof(*cp->status_blk.bnx2x));
-
cp->l2_rx_ring_size = 15;
- ret = cnic_alloc_l2_rings(dev, 4);
+ ret = cnic_alloc_uio_rings(dev, 4);
if (ret)
goto error;
- ret = cnic_alloc_uio(dev);
+ ret = cnic_init_uio(dev);
if (ret)
goto error;
@@ -1209,9 +1258,9 @@ static int cnic_submit_kwqe_16(struct cnic_dev *dev, u32 cmd, u32 cid,
kwqe.hdr.conn_and_cmd_data =
cpu_to_le32(((cmd << SPE_HDR_CMD_ID_SHIFT) |
- BNX2X_HW_CID(cid, cp->func)));
+ BNX2X_HW_CID(cp, cid)));
kwqe.hdr.type = cpu_to_le16(type);
- kwqe.hdr.reserved = 0;
+ kwqe.hdr.reserved1 = 0;
kwqe.data.phy_address.lo = cpu_to_le32(l5_data->phy_address.lo);
kwqe.data.phy_address.hi = cpu_to_le32(l5_data->phy_address.hi);
@@ -1246,8 +1295,8 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe)
{
struct cnic_local *cp = dev->cnic_priv;
struct iscsi_kwqe_init1 *req1 = (struct iscsi_kwqe_init1 *) kwqe;
- int func = cp->func, pages;
- int hq_bds;
+ int hq_bds, pages;
+ u32 pfid = cp->pfid;
cp->num_iscsi_tasks = req1->num_tasks_per_conn;
cp->num_ccells = req1->num_ccells_per_conn;
@@ -1264,60 +1313,60 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe)
return 0;
/* init Tstorm RAM */
- CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_RQ_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_RQ_SIZE_OFFSET(pfid),
req1->rq_num_wqes);
- CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_PAGE_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid),
PAGE_SIZE);
CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT);
+ TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT);
CNIC_WR16(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func),
+ TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid),
req1->num_tasks_per_conn);
/* init Ustorm RAM */
CNIC_WR16(dev, BAR_USTRORM_INTMEM +
- USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(func),
+ USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfid),
req1->rq_buffer_size);
- CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_PAGE_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_PAGE_SIZE_OFFSET(pfid),
PAGE_SIZE);
CNIC_WR8(dev, BAR_USTRORM_INTMEM +
- USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT);
+ USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT);
CNIC_WR16(dev, BAR_USTRORM_INTMEM +
- USTORM_ISCSI_NUM_OF_TASKS_OFFSET(func),
+ USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid),
req1->num_tasks_per_conn);
- CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_RQ_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_RQ_SIZE_OFFSET(pfid),
req1->rq_num_wqes);
- CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_CQ_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_CQ_SIZE_OFFSET(pfid),
req1->cq_num_wqes);
- CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_R2TQ_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfid),
cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS);
/* init Xstorm RAM */
- CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_PAGE_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid),
PAGE_SIZE);
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT);
+ XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT);
CNIC_WR16(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func),
+ XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid),
req1->num_tasks_per_conn);
- CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_HQ_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_HQ_SIZE_OFFSET(pfid),
hq_bds);
- CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_SQ_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_SQ_SIZE_OFFSET(pfid),
req1->num_tasks_per_conn);
- CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_R2TQ_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfid),
cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS);
/* init Cstorm RAM */
- CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_PAGE_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid),
PAGE_SIZE);
CNIC_WR8(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT);
+ CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT);
CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func),
+ CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid),
req1->num_tasks_per_conn);
- CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_CQ_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_CQ_SIZE_OFFSET(pfid),
req1->cq_num_wqes);
- CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_HQ_SIZE_OFFSET(func),
+ CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_HQ_SIZE_OFFSET(pfid),
hq_bds);
return 0;
@@ -1327,7 +1376,7 @@ static int cnic_bnx2x_iscsi_init2(struct cnic_dev *dev, struct kwqe *kwqe)
{
struct iscsi_kwqe_init2 *req2 = (struct iscsi_kwqe_init2 *) kwqe;
struct cnic_local *cp = dev->cnic_priv;
- int func = cp->func;
+ u32 pfid = cp->pfid;
struct iscsi_kcqe kcqe;
struct kcqe *cqes[1];
@@ -1339,21 +1388,21 @@ static int cnic_bnx2x_iscsi_init2(struct cnic_dev *dev, struct kwqe *kwqe)
}
CNIC_WR(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_ERROR_BITMAP_OFFSET(func), req2->error_bit_map[0]);
+ TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid), req2->error_bit_map[0]);
CNIC_WR(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_ERROR_BITMAP_OFFSET(func) + 4,
+ TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid) + 4,
req2->error_bit_map[1]);
CNIC_WR16(dev, BAR_USTRORM_INTMEM +
- USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(func), req2->max_cq_sqn);
+ USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfid), req2->max_cq_sqn);
CNIC_WR(dev, BAR_USTRORM_INTMEM +
- USTORM_ISCSI_ERROR_BITMAP_OFFSET(func), req2->error_bit_map[0]);
+ USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid), req2->error_bit_map[0]);
CNIC_WR(dev, BAR_USTRORM_INTMEM +
- USTORM_ISCSI_ERROR_BITMAP_OFFSET(func) + 4,
+ USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid) + 4,
req2->error_bit_map[1]);
CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(func), req2->max_cq_sqn);
+ CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfid), req2->max_cq_sqn);
kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_SUCCESS;
@@ -1461,7 +1510,7 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[],
struct cnic_context *ctx = &cp->ctx_tbl[req1->iscsi_conn_id];
struct cnic_iscsi *iscsi = ctx->proto.iscsi;
u32 cid = ctx->cid;
- u32 hw_cid = BNX2X_HW_CID(cid, cp->func);
+ u32 hw_cid = BNX2X_HW_CID(cp, cid);
struct iscsi_context *ictx;
struct regpair context_addr;
int i, j, n = 2, n_max;
@@ -1527,8 +1576,10 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[],
ictx->tstorm_st_context.tcp.cwnd = 0x5A8;
ictx->tstorm_st_context.tcp.flags2 |=
TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN;
+ ictx->tstorm_st_context.tcp.ooo_support_mode =
+ TCP_TSTORM_OOO_DROP_AND_PROC_ACK;
- ictx->timers_context.flags |= ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG;
+ ictx->timers_context.flags |= TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG;
ictx->ustorm_st_context.ring.rq.pbl_base.lo =
req2->rq_page_table_addr_lo;
@@ -1627,10 +1678,11 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[],
struct iscsi_kwqe_conn_offload1 *req1;
struct iscsi_kwqe_conn_offload2 *req2;
struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_context *ctx;
struct iscsi_kcqe kcqe;
struct kcqe *cqes[1];
u32 l5_cid;
- int ret;
+ int ret = 0;
if (num < 2) {
*work = num;
@@ -1654,9 +1706,15 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[],
kcqe.iscsi_conn_id = l5_cid;
kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE;
+ ctx = &cp->ctx_tbl[l5_cid];
+ if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) {
+ kcqe.completion_status =
+ ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY;
+ goto done;
+ }
+
if (atomic_inc_return(&cp->iscsi_conn) > dev->max_iscsi_conn) {
atomic_dec(&cp->iscsi_conn);
- ret = 0;
goto done;
}
ret = cnic_alloc_bnx2x_conn_resc(dev, l5_cid);
@@ -1673,8 +1731,7 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[],
}
kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_SUCCESS;
- kcqe.iscsi_conn_context_id = BNX2X_HW_CID(cp->ctx_tbl[l5_cid].cid,
- cp->func);
+ kcqe.iscsi_conn_context_id = BNX2X_HW_CID(cp, cp->ctx_tbl[l5_cid].cid);
done:
cqes[0] = (struct kcqe *) &kcqe;
@@ -1707,40 +1764,66 @@ static int cnic_bnx2x_iscsi_update(struct cnic_dev *dev, struct kwqe *kwqe)
return ret;
}
+static int cnic_bnx2x_destroy_ramrod(struct cnic_dev *dev, u32 l5_cid)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
+ union l5cm_specific_data l5_data;
+ int ret;
+ u32 hw_cid, type;
+
+ init_waitqueue_head(&ctx->waitq);
+ ctx->wait_cond = 0;
+ memset(&l5_data, 0, sizeof(l5_data));
+ hw_cid = BNX2X_HW_CID(cp, ctx->cid);
+ type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT)
+ & SPE_HDR_CONN_TYPE;
+ type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) &
+ SPE_HDR_FUNCTION_ID);
+
+ ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL,
+ hw_cid, type, &l5_data);
+
+ if (ret == 0)
+ wait_event(ctx->waitq, ctx->wait_cond);
+
+ return ret;
+}
+
static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
{
struct cnic_local *cp = dev->cnic_priv;
struct iscsi_kwqe_conn_destroy *req =
(struct iscsi_kwqe_conn_destroy *) kwqe;
- union l5cm_specific_data l5_data;
u32 l5_cid = req->reserved0;
struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
int ret = 0;
struct iscsi_kcqe kcqe;
struct kcqe *cqes[1];
- if (!(ctx->ctx_flags & CTX_FL_OFFLD_START))
+ if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
goto skip_cfc_delete;
- while (!time_after(jiffies, ctx->timestamp + (2 * HZ)))
- msleep(250);
+ if (!time_after(jiffies, ctx->timestamp + (2 * HZ))) {
+ unsigned long delta = ctx->timestamp + (2 * HZ) - jiffies;
- init_waitqueue_head(&ctx->waitq);
- ctx->wait_cond = 0;
- memset(&l5_data, 0, sizeof(l5_data));
- ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL,
- req->context_id,
- ETH_CONNECTION_TYPE |
- (1 << SPE_HDR_COMMON_RAMROD_SHIFT),
- &l5_data);
- if (ret == 0)
- wait_event(ctx->waitq, ctx->wait_cond);
+ if (delta > (2 * HZ))
+ delta = 0;
+
+ set_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags);
+ queue_delayed_work(cnic_wq, &cp->delete_task, delta);
+ goto destroy_reply;
+ }
+
+ ret = cnic_bnx2x_destroy_ramrod(dev, l5_cid);
skip_cfc_delete:
cnic_free_bnx2x_conn_resc(dev, l5_cid);
atomic_dec(&cp->iscsi_conn);
+ clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags);
+destroy_reply:
memset(&kcqe, 0, sizeof(kcqe));
kcqe.op_code = ISCSI_KCQE_OPCODE_DESTROY_CONN;
kcqe.iscsi_conn_id = l5_cid;
@@ -1805,37 +1888,37 @@ static void cnic_init_storm_conn_bufs(struct cnic_dev *dev,
static void cnic_init_bnx2x_mac(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
- int func = CNIC_FUNC(cp);
+ u32 pfid = cp->pfid;
u8 *mac = dev->mac_addr;
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(func), mac[0]);
+ XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfid), mac[0]);
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(func), mac[1]);
+ XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfid), mac[1]);
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(func), mac[2]);
+ XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfid), mac[2]);
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(func), mac[3]);
+ XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfid), mac[3]);
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(func), mac[4]);
+ XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfid), mac[4]);
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(func), mac[5]);
+ XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfid), mac[5]);
CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(func), mac[5]);
+ TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfid), mac[5]);
CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(func) + 1,
+ TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 1,
mac[4]);
CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func), mac[3]);
+ TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid), mac[3]);
CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 1,
+ TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 1,
mac[2]);
CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 2,
+ TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 2,
mac[1]);
CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 3,
+ TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 3,
mac[0]);
}
@@ -1851,10 +1934,10 @@ static void cnic_bnx2x_set_tcp_timestamp(struct cnic_dev *dev, int tcp_ts)
}
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->func), xstorm_flags);
+ XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->pfid), xstorm_flags);
CNIC_WR16(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->func), tstorm_flags);
+ TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->pfid), tstorm_flags);
}
static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[],
@@ -1929,7 +2012,7 @@ static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[],
cnic_init_storm_conn_bufs(dev, kwqe1, kwqe3, conn_buf);
CNIC_WR16(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_LOCAL_VLAN_OFFSET(cp->func), csk->vlan_id);
+ XSTORM_ISCSI_LOCAL_VLAN_OFFSET(cp->pfid), csk->vlan_id);
cnic_bnx2x_set_tcp_timestamp(dev,
kwqe1->tcp_flags & L4_KWQ_CONNECT_REQ1_TIME_STAMP);
@@ -1937,7 +2020,7 @@ static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[],
ret = cnic_submit_kwqe_16(dev, L5CM_RAMROD_CMD_ID_TCP_CONNECT,
kwqe1->cid, ISCSI_CONNECTION_TYPE, &l5_data);
if (!ret)
- ctx->ctx_flags |= CTX_FL_OFFLD_START;
+ set_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags);
return ret;
}
@@ -2063,7 +2146,7 @@ static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[],
static void service_kcqes(struct cnic_dev *dev, int num_cqes)
{
struct cnic_local *cp = dev->cnic_priv;
- int i, j;
+ int i, j, comp = 0;
i = 0;
j = 1;
@@ -2074,7 +2157,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes)
u32 kcqe_layer = kcqe_op_flag & KCQE_FLAGS_LAYER_MASK;
if (unlikely(kcqe_op_flag & KCQE_RAMROD_COMPLETION))
- cnic_kwq_completion(dev, 1);
+ comp++;
while (j < num_cqes) {
u32 next_op = cp->completed_kcq[i + j]->kcqe_op_flag;
@@ -2083,7 +2166,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes)
break;
if (unlikely(next_op & KCQE_RAMROD_COMPLETION))
- cnic_kwq_completion(dev, 1);
+ comp++;
j++;
}
@@ -2113,6 +2196,8 @@ end:
i += j;
j = 1;
}
+ if (unlikely(comp))
+ cnic_spq_completion(dev, DRV_CTL_RET_L5_SPQ_CREDIT_CMD, comp);
}
static u16 cnic_bnx2_next_idx(u16 idx)
@@ -2171,8 +2256,9 @@ static int cnic_get_kcqes(struct cnic_dev *dev, struct kcq_info *info)
static int cnic_l2_completion(struct cnic_local *cp)
{
u16 hw_cons, sw_cons;
+ struct cnic_uio_dev *udev = cp->udev;
union eth_rx_cqe *cqe, *cqe_ring = (union eth_rx_cqe *)
- (cp->l2_ring + (2 * BCM_PAGE_SIZE));
+ (udev->l2_ring + (2 * BCM_PAGE_SIZE));
u32 cmd;
int comp = 0;
@@ -2203,13 +2289,14 @@ static int cnic_l2_completion(struct cnic_local *cp)
static void cnic_chk_pkt_rings(struct cnic_local *cp)
{
- u16 rx_cons = *cp->rx_cons_ptr;
- u16 tx_cons = *cp->tx_cons_ptr;
+ u16 rx_cons, tx_cons;
int comp = 0;
- if (!test_bit(CNIC_F_CNIC_UP, &cp->dev->flags))
+ if (!test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags))
return;
+ rx_cons = *cp->rx_cons_ptr;
+ tx_cons = *cp->tx_cons_ptr;
if (cp->tx_cons != tx_cons || cp->rx_cons != rx_cons) {
if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags))
comp = cnic_l2_completion(cp);
@@ -2217,7 +2304,8 @@ static void cnic_chk_pkt_rings(struct cnic_local *cp)
cp->tx_cons = tx_cons;
cp->rx_cons = rx_cons;
- uio_event_notify(cp->cnic_uinfo);
+ if (cp->udev)
+ uio_event_notify(&cp->udev->cnic_uinfo);
}
if (comp)
clear_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags);
@@ -2318,14 +2406,38 @@ static inline void cnic_ack_bnx2x_int(struct cnic_dev *dev, u8 id, u8 storm,
CNIC_WR(dev, hc_addr, (*(u32 *)&igu_ack));
}
+static void cnic_ack_igu_sb(struct cnic_dev *dev, u8 igu_sb_id, u8 segment,
+ u16 index, u8 op, u8 update)
+{
+ struct igu_regular cmd_data;
+ u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id) * 8;
+
+ cmd_data.sb_id_and_flags =
+ (index << IGU_REGULAR_SB_INDEX_SHIFT) |
+ (segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) |
+ (update << IGU_REGULAR_BUPDATE_SHIFT) |
+ (op << IGU_REGULAR_ENABLE_INT_SHIFT);
+
+
+ CNIC_WR(dev, igu_addr, cmd_data.sb_id_and_flags);
+}
+
static void cnic_ack_bnx2x_msix(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
- cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, 0,
+ cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, CSTORM_ID, 0,
IGU_INT_DISABLE, 0);
}
+static void cnic_ack_bnx2x_e2_msix(struct cnic_dev *dev)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+
+ cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, 0,
+ IGU_INT_DISABLE, 0);
+}
+
static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info)
{
u32 last_status = *info->status_idx_ptr;
@@ -2357,8 +2469,12 @@ static void cnic_service_bnx2x_bh(unsigned long data)
status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1);
CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX);
- cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID,
- status_idx, IGU_INT_ENABLE, 1);
+ if (BNX2X_CHIP_IS_E2(cp->chip_id))
+ cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF,
+ status_idx, IGU_INT_ENABLE, 1);
+ else
+ cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID,
+ status_idx, IGU_INT_ENABLE, 1);
}
static int cnic_service_bnx2x(void *data, void *status_blk)
@@ -2379,8 +2495,7 @@ static void cnic_ulp_stop(struct cnic_dev *dev)
struct cnic_local *cp = dev->cnic_priv;
int if_type;
- if (cp->cnic_uinfo)
- cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
+ cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
struct cnic_ulp_ops *ulp_ops;
@@ -2728,6 +2843,13 @@ static int cnic_cm_create(struct cnic_dev *dev, int ulp_type, u32 cid,
if (l5_cid >= MAX_CM_SK_TBL_SZ)
return -EINVAL;
+ if (cp->ctx_tbl) {
+ struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
+
+ if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
+ return -EAGAIN;
+ }
+
csk1 = &cp->csk_tbl[l5_cid];
if (atomic_read(&csk1->ref_count))
return -EAGAIN;
@@ -3279,39 +3401,106 @@ static void cnic_close_bnx2x_conn(struct cnic_sock *csk, u32 opcode)
static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev)
{
+ struct cnic_local *cp = dev->cnic_priv;
+ int i;
+
+ if (!cp->ctx_tbl)
+ return;
+
+ if (!netif_running(dev->netdev))
+ return;
+
+ for (i = 0; i < cp->max_cid_space; i++) {
+ struct cnic_context *ctx = &cp->ctx_tbl[i];
+
+ while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags))
+ msleep(10);
+
+ if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
+ netdev_warn(dev->netdev, "CID %x not deleted\n",
+ ctx->cid);
+ }
+
+ cancel_delayed_work(&cp->delete_task);
+ flush_workqueue(cnic_wq);
+
+ if (atomic_read(&cp->iscsi_conn) != 0)
+ netdev_warn(dev->netdev, "%d iSCSI connections not destroyed\n",
+ atomic_read(&cp->iscsi_conn));
}
static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
- int func = CNIC_FUNC(cp);
+ u32 pfid = cp->pfid;
+ u32 port = CNIC_PORT(cp);
cnic_init_bnx2x_mac(dev);
cnic_bnx2x_set_tcp_timestamp(dev, 1);
CNIC_WR16(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_LOCAL_VLAN_OFFSET(func), 0);
+ XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfid), 0);
CNIC_WR(dev, BAR_XSTRORM_INTMEM +
- XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(func), 1);
+ XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(port), 1);
CNIC_WR(dev, BAR_XSTRORM_INTMEM +
- XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(func),
+ XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(port),
DEF_MAX_DA_COUNT);
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(func), DEF_TTL);
+ XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfid), DEF_TTL);
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(func), DEF_TOS);
+ XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfid), DEF_TOS);
CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(func), 2);
+ XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfid), 2);
CNIC_WR(dev, BAR_XSTRORM_INTMEM +
- XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(func), DEF_SWS_TIMER);
+ XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(pfid), DEF_SWS_TIMER);
- CNIC_WR(dev, BAR_TSTRORM_INTMEM + TSTORM_TCP_MAX_CWND_OFFSET(func),
+ CNIC_WR(dev, BAR_TSTRORM_INTMEM + TSTORM_TCP_MAX_CWND_OFFSET(pfid),
DEF_MAX_CWND);
return 0;
}
+static void cnic_delete_task(struct work_struct *work)
+{
+ struct cnic_local *cp;
+ struct cnic_dev *dev;
+ u32 i;
+ int need_resched = 0;
+
+ cp = container_of(work, struct cnic_local, delete_task.work);
+ dev = cp->dev;
+
+ for (i = 0; i < cp->max_cid_space; i++) {
+ struct cnic_context *ctx = &cp->ctx_tbl[i];
+
+ if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags) ||
+ !test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags))
+ continue;
+
+ if (!time_after(jiffies, ctx->timestamp + (2 * HZ))) {
+ need_resched = 1;
+ continue;
+ }
+
+ if (!test_and_clear_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags))
+ continue;
+
+ cnic_bnx2x_destroy_ramrod(dev, i);
+
+ cnic_free_bnx2x_conn_resc(dev, i);
+ if (ctx->ulp_proto_id == CNIC_ULP_ISCSI)
+ atomic_dec(&cp->iscsi_conn);
+
+ clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags);
+ }
+
+ if (need_resched)
+ queue_delayed_work(cnic_wq, &cp->delete_task,
+ msecs_to_jiffies(10));
+
+}
+
static int cnic_cm_open(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
@@ -3326,6 +3515,8 @@ static int cnic_cm_open(struct cnic_dev *dev)
if (err)
goto err_out;
+ INIT_DELAYED_WORK(&cp->delete_task, cnic_delete_task);
+
dev->cm_create = cnic_cm_create;
dev->cm_destroy = cnic_cm_destroy;
dev->cm_connect = cnic_cm_connect;
@@ -3418,11 +3609,24 @@ static void cnic_free_irq(struct cnic_dev *dev)
if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) {
cp->disable_int_sync(dev);
- tasklet_disable(&cp->cnic_irq_task);
+ tasklet_kill(&cp->cnic_irq_task);
free_irq(ethdev->irq_arr[0].vector, dev);
}
}
+static int cnic_request_irq(struct cnic_dev *dev)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_eth_dev *ethdev = cp->ethdev;
+ int err;
+
+ err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0, "cnic", dev);
+ if (err)
+ tasklet_disable(&cp->cnic_irq_task);
+
+ return err;
+}
+
static int cnic_init_bnx2_irq(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
@@ -3443,12 +3647,10 @@ static int cnic_init_bnx2_irq(struct cnic_dev *dev)
cp->last_status_idx = cp->status_blk.bnx2->status_idx;
tasklet_init(&cp->cnic_irq_task, cnic_service_bnx2_msix,
(unsigned long) dev);
- err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0,
- "cnic", dev);
- if (err) {
- tasklet_disable(&cp->cnic_irq_task);
+ err = cnic_request_irq(dev);
+ if (err)
return err;
- }
+
while (cp->status_blk.bnx2->status_completion_producer_index &&
i < 10) {
CNIC_WR(dev, BNX2_HC_COALESCE_NOW,
@@ -3515,11 +3717,12 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
struct cnic_eth_dev *ethdev = cp->ethdev;
+ struct cnic_uio_dev *udev = cp->udev;
u32 cid_addr, tx_cid, sb_id;
u32 val, offset0, offset1, offset2, offset3;
int i;
struct tx_bd *txbd;
- dma_addr_t buf_map;
+ dma_addr_t buf_map, ring_map = udev->l2_ring_map;
struct status_block *s_blk = cp->status_blk.gen;
sb_id = cp->status_blk_num;
@@ -3561,18 +3764,18 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev)
val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
cnic_ctx_wr(dev, cid_addr, offset1, val);
- txbd = (struct tx_bd *) cp->l2_ring;
+ txbd = (struct tx_bd *) udev->l2_ring;
- buf_map = cp->l2_buf_map;
+ buf_map = udev->l2_buf_map;
for (i = 0; i < MAX_TX_DESC_CNT; i++, txbd++) {
txbd->tx_bd_haddr_hi = (u64) buf_map >> 32;
txbd->tx_bd_haddr_lo = (u64) buf_map & 0xffffffff;
}
- val = (u64) cp->l2_ring_map >> 32;
+ val = (u64) ring_map >> 32;
cnic_ctx_wr(dev, cid_addr, offset2, val);
txbd->tx_bd_haddr_hi = val;
- val = (u64) cp->l2_ring_map & 0xffffffff;
+ val = (u64) ring_map & 0xffffffff;
cnic_ctx_wr(dev, cid_addr, offset3, val);
txbd->tx_bd_haddr_lo = val;
}
@@ -3581,10 +3784,12 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
struct cnic_eth_dev *ethdev = cp->ethdev;
+ struct cnic_uio_dev *udev = cp->udev;
u32 cid_addr, sb_id, val, coal_reg, coal_val;
int i;
struct rx_bd *rxbd;
struct status_block *s_blk = cp->status_blk.gen;
+ dma_addr_t ring_map = udev->l2_ring_map;
sb_id = cp->status_blk_num;
cnic_init_context(dev, 2);
@@ -3618,22 +3823,22 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev)
val = BNX2_L2CTX_L2_STATUSB_NUM(sb_id);
cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_HOST_BDIDX, val);
- rxbd = (struct rx_bd *) (cp->l2_ring + BCM_PAGE_SIZE);
+ rxbd = (struct rx_bd *) (udev->l2_ring + BCM_PAGE_SIZE);
for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) {
dma_addr_t buf_map;
int n = (i % cp->l2_rx_ring_size) + 1;
- buf_map = cp->l2_buf_map + (n * cp->l2_single_buf_size);
+ buf_map = udev->l2_buf_map + (n * cp->l2_single_buf_size);
rxbd->rx_bd_len = cp->l2_single_buf_size;
rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
rxbd->rx_bd_haddr_hi = (u64) buf_map >> 32;
rxbd->rx_bd_haddr_lo = (u64) buf_map & 0xffffffff;
}
- val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) >> 32;
+ val = (u64) (ring_map + BCM_PAGE_SIZE) >> 32;
cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val);
rxbd->rx_bd_haddr_hi = val;
- val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) & 0xffffffff;
+ val = (u64) (ring_map + BCM_PAGE_SIZE) & 0xffffffff;
cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val);
rxbd->rx_bd_haddr_lo = val;
@@ -3850,42 +4055,55 @@ static int cnic_init_bnx2x_irq(struct cnic_dev *dev)
tasklet_init(&cp->cnic_irq_task, cnic_service_bnx2x_bh,
(unsigned long) dev);
- if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) {
- err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0,
- "cnic", dev);
- if (err)
- tasklet_disable(&cp->cnic_irq_task);
- }
+ if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX)
+ err = cnic_request_irq(dev);
+
return err;
}
+static inline void cnic_storm_memset_hc_disable(struct cnic_dev *dev,
+ u16 sb_id, u8 sb_index,
+ u8 disable)
+{
+
+ u32 addr = BAR_CSTRORM_INTMEM +
+ CSTORM_STATUS_BLOCK_DATA_OFFSET(sb_id) +
+ offsetof(struct hc_status_block_data_e1x, index_data) +
+ sizeof(struct hc_index_data)*sb_index +
+ offsetof(struct hc_index_data, flags);
+ u16 flags = CNIC_RD16(dev, addr);
+ /* clear and set */
+ flags &= ~HC_INDEX_DATA_HC_ENABLED;
+ flags |= (((~disable) << HC_INDEX_DATA_HC_ENABLED_SHIFT) &
+ HC_INDEX_DATA_HC_ENABLED);
+ CNIC_WR16(dev, addr, flags);
+}
+
static void cnic_enable_bnx2x_int(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
u8 sb_id = cp->status_blk_num;
- int port = CNIC_PORT(cp);
CNIC_WR8(dev, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id,
- HC_INDEX_C_ISCSI_EQ_CONS),
- 64 / 12);
- CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id,
- HC_INDEX_C_ISCSI_EQ_CONS), 0);
+ CSTORM_STATUS_BLOCK_DATA_OFFSET(sb_id) +
+ offsetof(struct hc_status_block_data_e1x, index_data) +
+ sizeof(struct hc_index_data)*HC_INDEX_ISCSI_EQ_CONS +
+ offsetof(struct hc_index_data, timeout), 64 / 12);
+ cnic_storm_memset_hc_disable(dev, sb_id, HC_INDEX_ISCSI_EQ_CONS, 0);
}
static void cnic_disable_bnx2x_int_sync(struct cnic_dev *dev)
{
}
-static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev)
+static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev,
+ struct client_init_ramrod_data *data)
{
struct cnic_local *cp = dev->cnic_priv;
- union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) cp->l2_ring;
- struct eth_context *context;
- struct regpair context_addr;
- dma_addr_t buf_map;
- int func = CNIC_FUNC(cp);
+ struct cnic_uio_dev *udev = cp->udev;
+ union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) udev->l2_ring;
+ dma_addr_t buf_map, ring_map = udev->l2_ring_map;
+ struct host_sp_status_block *sb = cp->bnx2x_def_status_blk;
int port = CNIC_PORT(cp);
int i;
int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
@@ -3893,7 +4111,7 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev)
memset(txbd, 0, BCM_PAGE_SIZE);
- buf_map = cp->l2_buf_map;
+ buf_map = udev->l2_buf_map;
for (i = 0; i < MAX_TX_DESC_CNT; i += 3, txbd += 3) {
struct eth_tx_start_bd *start_bd = &txbd->start_bd;
struct eth_tx_bd *reg_bd = &((txbd + 2)->reg_bd);
@@ -3910,33 +4128,23 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev)
start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT);
}
- context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 1, &context_addr);
- val = (u64) cp->l2_ring_map >> 32;
+ val = (u64) ring_map >> 32;
txbd->next_bd.addr_hi = cpu_to_le32(val);
- context->xstorm_st_context.tx_bd_page_base_hi = val;
+ data->tx.tx_bd_page_base.hi = cpu_to_le32(val);
- val = (u64) cp->l2_ring_map & 0xffffffff;
+ val = (u64) ring_map & 0xffffffff;
txbd->next_bd.addr_lo = cpu_to_le32(val);
- context->xstorm_st_context.tx_bd_page_base_lo = val;
-
- context->cstorm_st_context.sb_index_number =
- HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS;
- context->cstorm_st_context.status_block_id = BNX2X_DEF_SB_ID;
+ data->tx.tx_bd_page_base.lo = cpu_to_le32(val);
- if (cli < MAX_X_STAT_COUNTER_ID)
- context->xstorm_st_context.statistics_data = cli |
- XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE;
-
- context->xstorm_ag_context.cdu_reserved =
- CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func),
- CDU_REGION_NUMBER_XCM_AG,
- ETH_CONNECTION_TYPE);
+ /* Other ramrod params */
+ data->tx.tx_sb_index_number = HC_SP_INDEX_ETH_ISCSI_CQ_CONS;
+ data->tx.tx_status_block_id = BNX2X_DEF_SB_ID;
/* reset xstorm per client statistics */
- if (cli < MAX_X_STAT_COUNTER_ID) {
+ if (cli < MAX_STAT_COUNTER_ID) {
val = BAR_XSTRORM_INTMEM +
XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++)
@@ -3944,111 +4152,77 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev)
}
cp->tx_cons_ptr =
- &cp->bnx2x_def_status_blk->c_def_status_block.index_values[
- HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS];
+ &sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_CQ_CONS];
}
-static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev)
+static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev,
+ struct client_init_ramrod_data *data)
{
struct cnic_local *cp = dev->cnic_priv;
- struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (cp->l2_ring +
+ struct cnic_uio_dev *udev = cp->udev;
+ struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (udev->l2_ring +
BCM_PAGE_SIZE);
struct eth_rx_cqe_next_page *rxcqe = (struct eth_rx_cqe_next_page *)
- (cp->l2_ring + (2 * BCM_PAGE_SIZE));
- struct eth_context *context;
- struct regpair context_addr;
+ (udev->l2_ring + (2 * BCM_PAGE_SIZE));
+ struct host_sp_status_block *sb = cp->bnx2x_def_status_blk;
int i;
int port = CNIC_PORT(cp);
- int func = CNIC_FUNC(cp);
int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
+ int cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli);
u32 val;
- struct tstorm_eth_client_config tstorm_client = {0};
+ dma_addr_t ring_map = udev->l2_ring_map;
+
+ /* General data */
+ data->general.client_id = cli;
+ data->general.statistics_en_flg = 1;
+ data->general.statistics_counter_id = cli;
+ data->general.activate_flg = 1;
+ data->general.sp_client_id = cli;
for (i = 0; i < BNX2X_MAX_RX_DESC_CNT; i++, rxbd++) {
dma_addr_t buf_map;
int n = (i % cp->l2_rx_ring_size) + 1;
- buf_map = cp->l2_buf_map + (n * cp->l2_single_buf_size);
+ buf_map = udev->l2_buf_map + (n * cp->l2_single_buf_size);
rxbd->addr_hi = cpu_to_le32((u64) buf_map >> 32);
rxbd->addr_lo = cpu_to_le32(buf_map & 0xffffffff);
}
- context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 0, &context_addr);
- val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) >> 32;
+ val = (u64) (ring_map + BCM_PAGE_SIZE) >> 32;
rxbd->addr_hi = cpu_to_le32(val);
+ data->rx.bd_page_base.hi = cpu_to_le32(val);
- context->ustorm_st_context.common.bd_page_base_hi = val;
-
- val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) & 0xffffffff;
+ val = (u64) (ring_map + BCM_PAGE_SIZE) & 0xffffffff;
rxbd->addr_lo = cpu_to_le32(val);
-
- context->ustorm_st_context.common.bd_page_base_lo = val;
-
- context->ustorm_st_context.common.sb_index_numbers =
- BNX2X_ISCSI_RX_SB_INDEX_NUM;
- context->ustorm_st_context.common.clientId = cli;
- context->ustorm_st_context.common.status_block_id = BNX2X_DEF_SB_ID;
- if (cli < MAX_U_STAT_COUNTER_ID) {
- context->ustorm_st_context.common.flags =
- USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS;
- context->ustorm_st_context.common.statistics_counter_id = cli;
- }
- context->ustorm_st_context.common.mc_alignment_log_size = 0;
- context->ustorm_st_context.common.bd_buff_size =
- cp->l2_single_buf_size;
-
- context->ustorm_ag_context.cdu_usage =
- CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func),
- CDU_REGION_NUMBER_UCM_AG,
- ETH_CONNECTION_TYPE);
+ data->rx.bd_page_base.lo = cpu_to_le32(val);
rxcqe += BNX2X_MAX_RCQ_DESC_CNT;
- val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) >> 32;
+ val = (u64) (ring_map + (2 * BCM_PAGE_SIZE)) >> 32;
rxcqe->addr_hi = cpu_to_le32(val);
+ data->rx.cqe_page_base.hi = cpu_to_le32(val);
- CNIC_WR(dev, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_BASE_OFFSET(port, cli) + 4, val);
-
- CNIC_WR(dev, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_NEXT_OFFSET(port, cli) + 4, val);
-
- val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff;
+ val = (u64) (ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff;
rxcqe->addr_lo = cpu_to_le32(val);
+ data->rx.cqe_page_base.lo = cpu_to_le32(val);
- CNIC_WR(dev, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_BASE_OFFSET(port, cli), val);
-
- CNIC_WR(dev, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_NEXT_OFFSET(port, cli), val);
-
- /* client tstorm info */
- tstorm_client.mtu = cp->l2_single_buf_size - 14;
- tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE;
-
- if (cli < MAX_T_STAT_COUNTER_ID) {
- tstorm_client.config_flags |=
- TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
- tstorm_client.statistics_counter_id = cli;
- }
+ /* Other ramrod params */
+ data->rx.client_qzone_id = cl_qzone_id;
+ data->rx.rx_sb_index_number = HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS;
+ data->rx.status_block_id = BNX2X_DEF_SB_ID;
- CNIC_WR(dev, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, cli),
- ((u32 *)&tstorm_client)[0]);
- CNIC_WR(dev, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, cli) + 4,
- ((u32 *)&tstorm_client)[1]);
+ data->rx.cache_line_alignment_log_size = L1_CACHE_SHIFT;
+ data->rx.bd_buff_size = cpu_to_le16(cp->l2_single_buf_size);
- /* reset tstorm per client statistics */
- if (cli < MAX_T_STAT_COUNTER_ID) {
+ data->rx.mtu = cpu_to_le16(cp->l2_single_buf_size - 14);
+ data->rx.outer_vlan_removal_enable_flg = 1;
+ /* reset tstorm and ustorm per client statistics */
+ if (cli < MAX_STAT_COUNTER_ID) {
val = BAR_TSTRORM_INTMEM +
TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++)
CNIC_WR(dev, val + i * 4, 0);
- }
- /* reset ustorm per client statistics */
- if (cli < MAX_U_STAT_COUNTER_ID) {
val = BAR_USTRORM_INTMEM +
USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++)
@@ -4056,21 +4230,22 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev)
}
cp->rx_cons_ptr =
- &cp->bnx2x_def_status_blk->u_def_status_block.index_values[
- HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS];
+ &sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS];
}
static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
- u32 base, addr, val;
+ u32 base, base2, addr, val;
int port = CNIC_PORT(cp);
dev->max_iscsi_conn = 0;
base = CNIC_RD(dev, MISC_REG_SHARED_MEM_ADDR);
- if (base < 0xa0000 || base >= 0xc0000)
+ if (base == 0)
return;
+ base2 = CNIC_RD(dev, (CNIC_PATH(cp) ? MISC_REG_GENERIC_CR_1 :
+ MISC_REG_GENERIC_CR_0));
addr = BNX2X_SHMEM_ADDR(base,
dev_info.port_hw_config[port].iscsi_mac_upper);
@@ -4103,16 +4278,25 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
val16 ^= 0x1e1e;
dev->max_iscsi_conn = val16;
}
- if (BNX2X_CHIP_IS_E1H(cp->chip_id)) {
+ if (BNX2X_CHIP_IS_E1H(cp->chip_id) || BNX2X_CHIP_IS_E2(cp->chip_id)) {
int func = CNIC_FUNC(cp);
+ u32 mf_cfg_addr;
+
+ if (BNX2X_SHMEM2_HAS(base2, mf_cfg_addr))
+ mf_cfg_addr = CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base2,
+ mf_cfg_addr));
+ else
+ mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET;
+
+ addr = mf_cfg_addr +
+ offsetof(struct mf_cfg, func_mf_config[func].e1hov_tag);
- addr = BNX2X_SHMEM_ADDR(base,
- mf_cfg.func_mf_config[func].e1hov_tag);
val = CNIC_RD(dev, addr);
val &= FUNC_MF_CFG_E1HOV_TAG_MASK;
if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
- addr = BNX2X_SHMEM_ADDR(base,
- mf_cfg.func_mf_config[func].config);
+ addr = mf_cfg_addr +
+ offsetof(struct mf_cfg,
+ func_mf_config[func].config);
val = CNIC_RD(dev, addr);
val &= FUNC_MF_CFG_PROTOCOL_MASK;
if (val != FUNC_MF_CFG_PROTOCOL_ISCSI)
@@ -4124,10 +4308,26 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_eth_dev *ethdev = cp->ethdev;
int func = CNIC_FUNC(cp), ret, i;
- int port = CNIC_PORT(cp);
- u16 eq_idx;
- u8 sb_id = cp->status_blk_num;
+ u32 pfid;
+
+ if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
+ u32 val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN_OVWR);
+
+ if (!(val & 1))
+ val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN);
+ else
+ val = (val >> 1) & 1;
+
+ if (val)
+ cp->pfid = func >> 1;
+ else
+ cp->pfid = func & 0x6;
+ } else {
+ cp->pfid = func;
+ }
+ pfid = cp->pfid;
ret = cnic_init_id_tbl(&cp->cid_tbl, MAX_ISCSI_TBL_SZ,
cp->iscsi_start_cid);
@@ -4135,86 +4335,98 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
if (ret)
return -ENOMEM;
+ cp->bnx2x_igu_sb_id = ethdev->irq_arr[0].status_blk_num2;
+
cp->kcq1.io_addr = BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_PROD_OFFSET(func, 0);
+ CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0);
cp->kcq1.sw_prod_idx = 0;
- cp->kcq1.hw_prod_idx_ptr =
- &cp->status_blk.bnx2x->c_status_block.index_values[
- HC_INDEX_C_ISCSI_EQ_CONS];
- cp->kcq1.status_idx_ptr =
- &cp->status_blk.bnx2x->c_status_block.status_block_index;
+ if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
+ struct host_hc_status_block_e2 *sb = cp->status_blk.gen;
+
+ cp->kcq1.hw_prod_idx_ptr =
+ &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS];
+ cp->kcq1.status_idx_ptr =
+ &sb->sb.running_index[SM_RX_ID];
+ } else {
+ struct host_hc_status_block_e1x *sb = cp->status_blk.gen;
+
+ cp->kcq1.hw_prod_idx_ptr =
+ &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS];
+ cp->kcq1.status_idx_ptr =
+ &sb->sb.running_index[SM_RX_ID];
+ }
cnic_get_bnx2x_iscsi_info(dev);
/* Only 1 EQ */
CNIC_WR16(dev, cp->kcq1.io_addr, MAX_KCQ_IDX);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_CONS_OFFSET(func, 0), 0);
+ CSTORM_ISCSI_EQ_CONS_OFFSET(pfid, 0), 0);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, 0),
+ CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfid, 0),
cp->kcq1.dma.pg_map_arr[1] & 0xffffffff);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, 0) + 4,
+ CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfid, 0) + 4,
(u64) cp->kcq1.dma.pg_map_arr[1] >> 32);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, 0),
+ CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfid, 0),
cp->kcq1.dma.pg_map_arr[0] & 0xffffffff);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, 0) + 4,
+ CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfid, 0) + 4,
(u64) cp->kcq1.dma.pg_map_arr[0] >> 32);
CNIC_WR8(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(func, 0), 1);
+ CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfid, 0), 1);
CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_SB_NUM_OFFSET(func, 0), cp->status_blk_num);
+ CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfid, 0), cp->status_blk_num);
CNIC_WR8(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(func, 0),
- HC_INDEX_C_ISCSI_EQ_CONS);
+ CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfid, 0),
+ HC_INDEX_ISCSI_EQ_CONS);
for (i = 0; i < cp->conn_buf_info.num_pages; i++) {
CNIC_WR(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(func, i),
+ TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfid, i),
cp->conn_buf_info.pgtbl[2 * i]);
CNIC_WR(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(func, i) + 4,
+ TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfid, i) + 4,
cp->conn_buf_info.pgtbl[(2 * i) + 1]);
}
CNIC_WR(dev, BAR_USTRORM_INTMEM +
- USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(func),
+ USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfid),
cp->gbl_buf_info.pg_map_arr[0] & 0xffffffff);
CNIC_WR(dev, BAR_USTRORM_INTMEM +
- USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(func) + 4,
+ USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfid) + 4,
(u64) cp->gbl_buf_info.pg_map_arr[0] >> 32);
+ CNIC_WR(dev, BAR_TSTRORM_INTMEM +
+ TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfid), DEF_RCV_BUF);
+
cnic_setup_bnx2x_context(dev);
- eq_idx = CNIC_RD16(dev, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id) +
- offsetof(struct cstorm_status_block_c,
- index_values[HC_INDEX_C_ISCSI_EQ_CONS]));
- if (eq_idx != 0) {
- netdev_err(dev->netdev, "EQ cons index %x != 0\n", eq_idx);
- return -EBUSY;
- }
ret = cnic_init_bnx2x_irq(dev);
if (ret)
return ret;
- cnic_init_bnx2x_tx_ring(dev);
- cnic_init_bnx2x_rx_ring(dev);
-
return 0;
}
static void cnic_init_rings(struct cnic_dev *dev)
{
+ struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_uio_dev *udev = cp->udev;
+
+ if (test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags))
+ return;
+
if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
cnic_init_bnx2_tx_ring(dev);
cnic_init_bnx2_rx_ring(dev);
+ set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags);
} else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
- struct cnic_local *cp = dev->cnic_priv;
u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
+ u32 cl_qzone_id, type;
+ struct client_init_ramrod_data *data;
union l5cm_specific_data l5_data;
struct ustorm_eth_rx_producers rx_prods = {0};
u32 off, i;
@@ -4223,21 +4435,38 @@ static void cnic_init_rings(struct cnic_dev *dev)
rx_prods.cqe_prod = BNX2X_MAX_RCQ_DESC_CNT;
barrier();
+ cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli);
+
off = BAR_USTRORM_INTMEM +
- USTORM_RX_PRODS_OFFSET(CNIC_PORT(cp), cli);
+ (BNX2X_CHIP_IS_E2(cp->chip_id) ?
+ USTORM_RX_PRODS_E2_OFFSET(cl_qzone_id) :
+ USTORM_RX_PRODS_E1X_OFFSET(CNIC_PORT(cp), cli));
for (i = 0; i < sizeof(struct ustorm_eth_rx_producers) / 4; i++)
CNIC_WR(dev, off + i * 4, ((u32 *) &rx_prods)[i]);
set_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags);
- cnic_init_bnx2x_tx_ring(dev);
- cnic_init_bnx2x_rx_ring(dev);
+ data = udev->l2_buf;
+
+ memset(data, 0, sizeof(*data));
+
+ cnic_init_bnx2x_tx_ring(dev, data);
+ cnic_init_bnx2x_rx_ring(dev, data);
+
+ l5_data.phy_address.lo = udev->l2_buf_map & 0xffffffff;
+ l5_data.phy_address.hi = (u64) udev->l2_buf_map >> 32;
+
+ type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT)
+ & SPE_HDR_CONN_TYPE;
+ type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) &
+ SPE_HDR_FUNCTION_ID);
+
+ set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags);
- l5_data.phy_address.lo = cli;
- l5_data.phy_address.hi = 0;
cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP,
- BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data);
+ BNX2X_ISCSI_L2_CID, type, &l5_data);
+
i = 0;
while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) &&
++i < 10)
@@ -4246,13 +4475,18 @@ static void cnic_init_rings(struct cnic_dev *dev)
if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags))
netdev_err(dev->netdev,
"iSCSI CLIENT_SETUP did not complete\n");
- cnic_kwq_completion(dev, 1);
+ cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1);
cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1);
}
}
static void cnic_shutdown_rings(struct cnic_dev *dev)
{
+ struct cnic_local *cp = dev->cnic_priv;
+
+ if (!test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags))
+ return;
+
if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
cnic_shutdown_bnx2_rx_ring(dev);
} else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
@@ -4260,6 +4494,7 @@ static void cnic_shutdown_rings(struct cnic_dev *dev)
u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
union l5cm_specific_data l5_data;
int i;
+ u32 type;
cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 0);
@@ -4277,14 +4512,18 @@ static void cnic_shutdown_rings(struct cnic_dev *dev)
if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags))
netdev_err(dev->netdev,
"iSCSI CLIENT_HALT did not complete\n");
- cnic_kwq_completion(dev, 1);
+ cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1);
memset(&l5_data, 0, sizeof(l5_data));
- cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL,
- BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE |
- (1 << SPE_HDR_COMMON_RAMROD_SHIFT), &l5_data);
+ type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT)
+ & SPE_HDR_CONN_TYPE;
+ type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) &
+ SPE_HDR_FUNCTION_ID);
+ cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL,
+ BNX2X_ISCSI_L2_CID, type, &l5_data);
msleep(10);
}
+ clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags);
}
static int cnic_register_netdev(struct cnic_dev *dev)
@@ -4327,7 +4566,6 @@ static int cnic_start_hw(struct cnic_dev *dev)
return -EALREADY;
dev->regview = ethdev->io_base;
- cp->chip_id = ethdev->chip_id;
pci_dev_get(dev->pcidev);
cp->func = PCI_FUNC(dev->pcidev->devfn);
cp->status_blk.gen = ethdev->irq_arr[0].status_blk;
@@ -4379,17 +4617,11 @@ static void cnic_stop_bnx2_hw(struct cnic_dev *dev)
static void cnic_stop_bnx2x_hw(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
- u8 sb_id = cp->status_blk_num;
- int port = CNIC_PORT(cp);
cnic_free_irq(dev);
- CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id) +
- offsetof(struct cstorm_status_block_c,
- index_values[HC_INDEX_C_ISCSI_EQ_CONS]),
- 0);
+ *cp->kcq1.hw_prod_idx_ptr = 0;
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
- CSTORM_ISCSI_EQ_CONS_OFFSET(cp->func, 0), 0);
+ CSTORM_ISCSI_EQ_CONS_OFFSET(cp->pfid, 0), 0);
CNIC_WR16(dev, cp->kcq1.io_addr, 0);
cnic_free_resc(dev);
}
@@ -4403,10 +4635,11 @@ static void cnic_stop_hw(struct cnic_dev *dev)
/* Need to wait for the ring shutdown event to complete
* before clearing the CNIC_UP flag.
*/
- while (cp->uio_dev != -1 && i < 15) {
+ while (cp->udev->uio_dev != -1 && i < 15) {
msleep(100);
i++;
}
+ cnic_shutdown_rings(dev);
clear_bit(CNIC_F_CNIC_UP, &dev->flags);
rcu_assign_pointer(cp->ulp_ops[CNIC_ULP_L4], NULL);
synchronize_rcu();
@@ -4455,7 +4688,6 @@ static struct cnic_dev *cnic_alloc_dev(struct net_device *dev,
cp = cdev->cnic_priv;
cp->dev = cdev;
- cp->uio_dev = -1;
cp->l2_single_buf_size = 0x400;
cp->l2_rx_ring_size = 3;
@@ -4510,6 +4742,7 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev)
cp = cdev->cnic_priv;
cp->ethdev = ethdev;
cdev->pcidev = pdev;
+ cp->chip_id = ethdev->chip_id;
cp->cnic_ops = &cnic_bnx2_ops;
cp->start_hw = cnic_start_bnx2_hw;
@@ -4564,6 +4797,7 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev)
cp = cdev->cnic_priv;
cp->ethdev = ethdev;
cdev->pcidev = pdev;
+ cp->chip_id = ethdev->chip_id;
cp->cnic_ops = &cnic_bnx2x_ops;
cp->start_hw = cnic_start_bnx2x_hw;
@@ -4575,7 +4809,10 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev)
cp->stop_cm = cnic_cm_stop_bnx2x_hw;
cp->enable_int = cnic_enable_bnx2x_int;
cp->disable_int_sync = cnic_disable_bnx2x_int_sync;
- cp->ack_int = cnic_ack_bnx2x_msix;
+ if (BNX2X_CHIP_IS_E2(cp->chip_id))
+ cp->ack_int = cnic_ack_bnx2x_e2_msix;
+ else
+ cp->ack_int = cnic_ack_bnx2x_msix;
cp->close_conn = cnic_close_bnx2x_conn;
cp->next_idx = cnic_bnx2x_next_idx;
cp->hw_idx = cnic_bnx2x_hw_idx;
@@ -4683,6 +4920,7 @@ static struct notifier_block cnic_netdev_notifier = {
static void cnic_release(void)
{
struct cnic_dev *dev;
+ struct cnic_uio_dev *udev;
while (!list_empty(&cnic_dev_list)) {
dev = list_entry(cnic_dev_list.next, struct cnic_dev, list);
@@ -4696,6 +4934,11 @@ static void cnic_release(void)
list_del_init(&dev->list);
cnic_free_dev(dev);
}
+ while (!list_empty(&cnic_udev_list)) {
+ udev = list_entry(cnic_udev_list.next, struct cnic_uio_dev,
+ list);
+ cnic_free_uio(udev);
+ }
}
static int __init cnic_init(void)
@@ -4710,6 +4953,13 @@ static int __init cnic_init(void)
return rc;
}
+ cnic_wq = create_singlethread_workqueue("cnic_wq");
+ if (!cnic_wq) {
+ cnic_release();
+ unregister_netdevice_notifier(&cnic_netdev_notifier);
+ return -ENOMEM;
+ }
+
return 0;
}
@@ -4717,6 +4967,7 @@ static void __exit cnic_exit(void)
{
unregister_netdevice_notifier(&cnic_netdev_notifier);
cnic_release();
+ destroy_workqueue(cnic_wq);
}
module_init(cnic_init);
diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h
index 275c36114d85..6a4a0ae5cfe3 100644
--- a/drivers/net/cnic.h
+++ b/drivers/net/cnic.h
@@ -12,6 +12,13 @@
#ifndef CNIC_H
#define CNIC_H
+#define HC_INDEX_ISCSI_EQ_CONS 6
+
+#define HC_INDEX_FCOE_EQ_CONS 3
+
+#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5
+#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1
+
#define KWQ_PAGE_CNT 4
#define KCQ_PAGE_CNT 16
@@ -161,8 +168,9 @@ struct cnic_context {
wait_queue_head_t waitq;
int wait_cond;
unsigned long timestamp;
- u32 ctx_flags;
-#define CTX_FL_OFFLD_START 0x00000001
+ unsigned long ctx_flags;
+#define CTX_FL_OFFLD_START 0
+#define CTX_FL_DELETE_WAIT 1
u8 ulp_proto_id;
union {
struct cnic_iscsi *iscsi;
@@ -179,6 +187,31 @@ struct kcq_info {
u32 io_addr;
};
+struct iro {
+ u32 base;
+ u16 m1;
+ u16 m2;
+ u16 m3;
+ u16 size;
+};
+
+struct cnic_uio_dev {
+ struct uio_info cnic_uinfo;
+ u32 uio_dev;
+
+ int l2_ring_size;
+ void *l2_ring;
+ dma_addr_t l2_ring_map;
+
+ int l2_buf_size;
+ void *l2_buf;
+ dma_addr_t l2_buf_map;
+
+ struct cnic_dev *dev;
+ struct pci_dev *pdev;
+ struct list_head list;
+};
+
struct cnic_local {
spinlock_t cnic_ulp_lock;
@@ -192,19 +225,15 @@ struct cnic_local {
unsigned long cnic_local_flags;
#define CNIC_LCL_FL_KWQ_INIT 0x0
#define CNIC_LCL_FL_L2_WAIT 0x1
+#define CNIC_LCL_FL_RINGS_INITED 0x2
struct cnic_dev *dev;
struct cnic_eth_dev *ethdev;
- void *l2_ring;
- dma_addr_t l2_ring_map;
- int l2_ring_size;
- int l2_rx_ring_size;
+ struct cnic_uio_dev *udev;
- void *l2_buf;
- dma_addr_t l2_buf_map;
- int l2_buf_size;
+ int l2_rx_ring_size;
int l2_single_buf_size;
u16 *rx_cons_ptr;
@@ -212,6 +241,9 @@ struct cnic_local {
u16 rx_cons;
u16 tx_cons;
+ struct iro *iro_arr;
+#define IRO (((struct cnic_local *) dev->cnic_priv)->iro_arr)
+
struct cnic_dma kwq_info;
struct kwqe **kwq;
@@ -230,12 +262,16 @@ struct cnic_local {
union {
void *gen;
struct status_block_msix *bnx2;
- struct host_status_block *bnx2x;
+ struct host_hc_status_block_e1x *bnx2x_e1x;
+ /* index values - which counter to update */
+ #define SM_RX_ID 0
+ #define SM_TX_ID 1
} status_blk;
- struct host_def_status_block *bnx2x_def_status_blk;
+ struct host_sp_status_block *bnx2x_def_status_blk;
u32 status_blk_num;
+ u32 bnx2x_igu_sb_id;
u32 int_num;
u32 last_status_idx;
struct tasklet_struct cnic_irq_task;
@@ -264,6 +300,8 @@ struct cnic_local {
int hq_size;
int num_cqs;
+ struct delayed_work delete_task;
+
struct cnic_ctx *ctx_arr;
int ctx_blks;
int ctx_blk_size;
@@ -272,11 +310,9 @@ struct cnic_local {
u32 chip_id;
int func;
+ u32 pfid;
u32 shmem_base;
- u32 uio_dev;
- struct uio_info *cnic_uinfo;
-
struct cnic_ops *cnic_ops;
int (*start_hw)(struct cnic_dev *);
void (*stop_hw)(struct cnic_dev *);
@@ -335,18 +371,36 @@ struct bnx2x_bd_chain_next {
#define BNX2X_ISCSI_GLB_BUF_SIZE 64
#define BNX2X_ISCSI_PBL_NOT_CACHED 0xff
#define BNX2X_ISCSI_PDU_HEADER_NOT_CACHED 0xff
-#define BNX2X_HW_CID(x, func) ((x) | (((func) % PORT_MAX) << 23) | \
- (((func) >> 1) << 17))
-#define BNX2X_SW_CID(x) (x & 0x1ffff)
+
+#define BNX2X_CHIP_NUM_57710 0x164e
#define BNX2X_CHIP_NUM_57711 0x164f
#define BNX2X_CHIP_NUM_57711E 0x1650
+#define BNX2X_CHIP_NUM_57712 0x1662
+#define BNX2X_CHIP_NUM_57712E 0x1663
+#define BNX2X_CHIP_NUM_57713 0x1651
+#define BNX2X_CHIP_NUM_57713E 0x1652
+
#define BNX2X_CHIP_NUM(x) (x >> 16)
+#define BNX2X_CHIP_IS_57710(x) \
+ (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57710)
#define BNX2X_CHIP_IS_57711(x) \
(BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57711)
#define BNX2X_CHIP_IS_57711E(x) \
(BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57711E)
#define BNX2X_CHIP_IS_E1H(x) \
(BNX2X_CHIP_IS_57711(x) || BNX2X_CHIP_IS_57711E(x))
+#define BNX2X_CHIP_IS_57712(x) \
+ (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57712)
+#define BNX2X_CHIP_IS_57712E(x) \
+ (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57712E)
+#define BNX2X_CHIP_IS_57713(x) \
+ (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57713)
+#define BNX2X_CHIP_IS_57713E(x) \
+ (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57713E)
+#define BNX2X_CHIP_IS_E2(x) \
+ (BNX2X_CHIP_IS_57712(x) || BNX2X_CHIP_IS_57712E(x) || \
+ BNX2X_CHIP_IS_57713(x) || BNX2X_CHIP_IS_57713E(x))
+
#define IS_E1H_OFFSET BNX2X_CHIP_IS_E1H(cp->chip_id)
#define BNX2X_RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd))
@@ -358,19 +412,35 @@ struct bnx2x_bd_chain_next {
(BNX2X_MAX_RCQ_DESC_CNT - 1)) ? \
((x) + 2) : ((x) + 1)
-#define BNX2X_DEF_SB_ID 16
+#define BNX2X_DEF_SB_ID HC_SP_SB_ID
-#define BNX2X_ISCSI_RX_SB_INDEX_NUM \
- ((HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS << \
- USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \
- USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER)
+#define BNX2X_SHMEM_MF_BLK_OFFSET 0x7e4
#define BNX2X_SHMEM_ADDR(base, field) (base + \
offsetof(struct shmem_region, field))
-#define CNIC_PORT(cp) ((cp)->func % PORT_MAX)
+#define BNX2X_SHMEM2_ADDR(base, field) (base + \
+ offsetof(struct shmem2_region, field))
+
+#define BNX2X_SHMEM2_HAS(base, field) \
+ ((base) && \
+ (CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base, size)) > \
+ offsetof(struct shmem2_region, field)))
+
+#define CNIC_PORT(cp) ((cp)->pfid & 1)
#define CNIC_FUNC(cp) ((cp)->func)
-#define CNIC_E1HVN(cp) ((cp)->func >> 1)
+#define CNIC_PATH(cp) (!BNX2X_CHIP_IS_E2(cp->chip_id) ? 0 :\
+ (CNIC_FUNC(cp) & 1))
+#define CNIC_E1HVN(cp) ((cp)->pfid >> 1)
+
+#define BNX2X_HW_CID(cp, x) ((CNIC_PORT(cp) << 23) | \
+ (CNIC_E1HVN(cp) << 17) | (x))
+
+#define BNX2X_SW_CID(x) (x & 0x1ffff)
+
+#define BNX2X_CL_QZONE_ID(cp, cli) \
+ (cli + (CNIC_PORT(cp) * ETH_MAX_RX_CLIENTS_E1H))
+#define TCP_TSTORM_OOO_DROP_AND_PROC_ACK (0<<4)
#endif
diff --git a/drivers/net/cnic_defs.h b/drivers/net/cnic_defs.h
index 7ce694d41b6b..328e8b2765a3 100644
--- a/drivers/net/cnic_defs.h
+++ b/drivers/net/cnic_defs.h
@@ -14,6 +14,7 @@
/* KWQ (kernel work queue) request op codes */
#define L2_KWQE_OPCODE_VALUE_FLUSH (4)
+#define L2_KWQE_OPCODE_VALUE_VM_FREE_RX_QUEUE (8)
#define L4_KWQE_OPCODE_VALUE_CONNECT1 (50)
#define L4_KWQE_OPCODE_VALUE_CONNECT2 (51)
@@ -48,11 +49,14 @@
#define L4_KCQE_OPCODE_VALUE_UPLOAD_PG (14)
/* KCQ (kernel completion queue) completion status */
-#define L4_KCQE_COMPLETION_STATUS_SUCCESS (0)
-#define L4_KCQE_COMPLETION_STATUS_TIMEOUT (0x93)
+#define L4_KCQE_COMPLETION_STATUS_SUCCESS (0)
+#define L4_KCQE_COMPLETION_STATUS_TIMEOUT (0x93)
-#define L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL (0x83)
-#define L4_KCQE_COMPLETION_STATUS_OFFLOADED_PG (0x89)
+#define L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL (0x83)
+#define L4_KCQE_COMPLETION_STATUS_OFFLOADED_PG (0x89)
+
+#define L4_KCQE_OPCODE_VALUE_OOO_EVENT_NOTIFICATION (0xa0)
+#define L4_KCQE_OPCODE_VALUE_OOO_FLUSH (0xa1)
#define L4_LAYER_CODE (4)
#define L2_LAYER_CODE (2)
@@ -585,6 +589,100 @@ struct l4_kwq_upload {
*/
/*
+ * The iscsi aggregative context of Cstorm
+ */
+struct cstorm_iscsi_ag_context {
+ u32 agg_vars1;
+#define CSTORM_ISCSI_AG_CONTEXT_STATE (0xFF<<0)
+#define CSTORM_ISCSI_AG_CONTEXT_STATE_SHIFT 0
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<8)
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 8
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<9)
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 9
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<10)
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 10
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<11)
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 11
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN (0x1<<12)
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN_SHIFT 12
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN (0x1<<13)
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN_SHIFT 13
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF (0x3<<14)
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_SHIFT 14
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66 (0x3<<16)
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66_SHIFT 16
+#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN (0x1<<18)
+#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN_SHIFT 18
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN (0x1<<19)
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN_SHIFT 19
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN (0x1<<20)
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN_SHIFT 20
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN (0x1<<21)
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN_SHIFT 21
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN (0x1<<22)
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN_SHIFT 22
+#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE (0x7<<23)
+#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE_SHIFT 23
+#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE (0x3<<26)
+#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE_SHIFT 26
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52 (0x3<<28)
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52_SHIFT 28
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53 (0x3<<30)
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53_SHIFT 30
+#if defined(__BIG_ENDIAN)
+ u8 __aux1_th;
+ u8 __aux1_val;
+ u16 __agg_vars2;
+#elif defined(__LITTLE_ENDIAN)
+ u16 __agg_vars2;
+ u8 __aux1_val;
+ u8 __aux1_th;
+#endif
+ u32 rel_seq;
+ u32 rel_seq_th;
+#if defined(__BIG_ENDIAN)
+ u16 hq_cons;
+ u16 hq_prod;
+#elif defined(__LITTLE_ENDIAN)
+ u16 hq_prod;
+ u16 hq_cons;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 __reserved62;
+ u8 __reserved61;
+ u8 __reserved60;
+ u8 __reserved59;
+#elif defined(__LITTLE_ENDIAN)
+ u8 __reserved59;
+ u8 __reserved60;
+ u8 __reserved61;
+ u8 __reserved62;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 __reserved64;
+ u16 __cq_u_prod0;
+#elif defined(__LITTLE_ENDIAN)
+ u16 __cq_u_prod0;
+ u16 __reserved64;
+#endif
+ u32 __cq_u_prod1;
+#if defined(__BIG_ENDIAN)
+ u16 __agg_vars3;
+ u16 __cq_u_prod2;
+#elif defined(__LITTLE_ENDIAN)
+ u16 __cq_u_prod2;
+ u16 __agg_vars3;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 __aux2_th;
+ u16 __cq_u_prod3;
+#elif defined(__LITTLE_ENDIAN)
+ u16 __cq_u_prod3;
+ u16 __aux2_th;
+#endif
+};
+
+/*
* iSCSI context region, used only in iSCSI
*/
struct ustorm_iscsi_rq_db {
@@ -696,7 +794,7 @@ struct ustorm_iscsi_st_context {
struct regpair task_pbl_base;
struct regpair tce_phy_addr;
struct ustorm_iscsi_placement_db place_db;
- u32 data_rcv_seq;
+ u32 reserved8;
u32 rem_rcv_len;
#if defined(__BIG_ENDIAN)
u16 hdr_itt;
@@ -713,8 +811,10 @@ struct ustorm_iscsi_st_context {
#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0
#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1)
#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1
-#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x3F<<2)
-#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 2
+#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2)
+#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2
+#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3)
+#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3
u8 task_pdu_cache_index;
u8 task_pbe_cache_index;
#elif defined(__LITTLE_ENDIAN)
@@ -725,8 +825,10 @@ struct ustorm_iscsi_st_context {
#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0
#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1)
#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1
-#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x3F<<2)
-#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 2
+#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2)
+#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2
+#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3)
+#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3
u8 hdr_second_byte_union;
#endif
#if defined(__BIG_ENDIAN)
@@ -777,14 +879,14 @@ struct ustorm_iscsi_st_context {
*/
struct tstorm_tcp_st_context_section {
u32 flags1;
-#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_20B (0xFFFFFF<<0)
-#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_20B_SHIFT 0
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT (0xFFFFFF<<0)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_SHIFT 0
#define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID (0x1<<24)
#define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID_SHIFT 24
#define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS (0x1<<25)
#define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS_SHIFT 25
-#define TSTORM_TCP_ST_CONTEXT_SECTION_ISLE_EXISTS (0x1<<26)
-#define TSTORM_TCP_ST_CONTEXT_SECTION_ISLE_EXISTS_SHIFT 26
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0 (0x1<<26)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0_SHIFT 26
#define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD (0x1<<27)
#define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD_SHIFT 27
#define TSTORM_TCP_ST_CONTEXT_SECTION_KA_ENABLED (0x1<<28)
@@ -793,11 +895,11 @@ struct tstorm_tcp_st_context_section {
#define TSTORM_TCP_ST_CONTEXT_SECTION_FIRST_RTO_ESTIMATE_SHIFT 29
#define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN (0x1<<30)
#define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN_SHIFT 30
-#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED3 (0x1<<31)
-#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED3_SHIFT 31
+#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN (0x1<<31)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN_SHIFT 31
u32 flags2;
-#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_20B (0xFFFFFF<<0)
-#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_20B_SHIFT 0
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION (0xFFFFFF<<0)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_SHIFT 0
#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN (0x1<<24)
#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN_SHIFT 24
#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_COUNTER_EN (0x1<<25)
@@ -810,18 +912,18 @@ struct tstorm_tcp_st_context_section {
#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 28
#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<29)
#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 29
-#define __TSTORM_TCP_ST_CONTEXT_SECTION_SECOND_ISLE_DROPPED (0x1<<30)
-#define __TSTORM_TCP_ST_CONTEXT_SECTION_SECOND_ISLE_DROPPED_SHIFT 30
-#define __TSTORM_TCP_ST_CONTEXT_SECTION_DONT_SUPPORT_OOO (0x1<<31)
-#define __TSTORM_TCP_ST_CONTEXT_SECTION_DONT_SUPPORT_OOO_SHIFT 31
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK (0x1<<30)
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK_SHIFT 30
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK (0x1<<31)
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK_SHIFT 31
#if defined(__BIG_ENDIAN)
- u16 reserved_slowpath;
- u8 tcp_sm_state_3b;
- u8 rto_exp_3b;
+ u16 mss;
+ u8 tcp_sm_state;
+ u8 rto_exp;
#elif defined(__LITTLE_ENDIAN)
- u8 rto_exp_3b;
- u8 tcp_sm_state_3b;
- u16 reserved_slowpath;
+ u8 rto_exp;
+ u8 tcp_sm_state;
+ u16 mss;
#endif
u32 rcv_nxt;
u32 timestamp_recent;
@@ -846,11 +948,11 @@ struct tstorm_tcp_st_context_section {
#if defined(__BIG_ENDIAN)
u8 statistics_counter_id;
u8 ooo_support_mode;
- u8 snd_wnd_scale_4b;
+ u8 snd_wnd_scale;
u8 dup_ack_count;
#elif defined(__LITTLE_ENDIAN)
u8 dup_ack_count;
- u8 snd_wnd_scale_4b;
+ u8 snd_wnd_scale;
u8 ooo_support_mode;
u8 statistics_counter_id;
#endif
@@ -860,13 +962,21 @@ struct tstorm_tcp_st_context_section {
u32 isle_start_seq;
u32 isle_end_seq;
#if defined(__BIG_ENDIAN)
- u16 mss;
+ u16 second_isle_address;
u16 recent_seg_wnd;
#elif defined(__LITTLE_ENDIAN)
u16 recent_seg_wnd;
- u16 mss;
+ u16 second_isle_address;
+#endif
+#if defined(__BIG_ENDIAN)
+ u8 max_isles_ever_happened;
+ u8 isles_number;
+ u16 last_isle_address;
+#elif defined(__LITTLE_ENDIAN)
+ u16 last_isle_address;
+ u8 isles_number;
+ u8 max_isles_ever_happened;
#endif
- u32 reserved4;
u32 max_rt_time;
#if defined(__BIG_ENDIAN)
u16 lsb_mac_address;
@@ -876,7 +986,7 @@ struct tstorm_tcp_st_context_section {
u16 lsb_mac_address;
#endif
u32 msb_mac_address;
- u32 reserved2;
+ u32 rightmost_received_seq;
};
/*
@@ -951,7 +1061,7 @@ struct tstorm_iscsi_st_context_section {
u8 scratchpad_idx;
struct iscsi_term_vars term_vars;
#endif
- u32 reserved2;
+ u32 process_nxt;
};
/*
@@ -1174,24 +1284,12 @@ struct xstorm_iscsi_ag_context {
#endif
#if defined(__BIG_ENDIAN)
u8 cdu_reserved;
- u8 agg_vars4;
-#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF (0x3<<0)
-#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_SHIFT 0
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF (0x3<<2)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_SHIFT 2
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN (0x1<<4)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN_SHIFT 4
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN (0x1<<5)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN_SHIFT 5
-#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN (0x1<<6)
-#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN_SHIFT 6
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN (0x1<<7)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN_SHIFT 7
+ u8 __agg_vars4;
u8 agg_vars3;
#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0)
#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF (0x3<<6)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_SHIFT 6
+#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6)
+#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6
u8 agg_vars2;
#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF (0x3<<0)
#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_SHIFT 0
@@ -1222,21 +1320,9 @@ struct xstorm_iscsi_ag_context {
u8 agg_vars3;
#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0)
#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF (0x3<<6)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_SHIFT 6
- u8 agg_vars4;
-#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF (0x3<<0)
-#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_SHIFT 0
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF (0x3<<2)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_SHIFT 2
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN (0x1<<4)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN_SHIFT 4
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN (0x1<<5)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN_SHIFT 5
-#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN (0x1<<6)
-#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN_SHIFT 6
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN (0x1<<7)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN_SHIFT 7
+#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6)
+#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6
+ u8 __agg_vars4;
u8 cdu_reserved;
#endif
u32 more_to_send;
@@ -1270,8 +1356,8 @@ struct xstorm_iscsi_ag_context {
#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0
#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3)
#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3
-#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF (0x3<<4)
-#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_SHIFT 4
+#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4)
+#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4
#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6)
#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6
#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8)
@@ -1286,8 +1372,8 @@ struct xstorm_iscsi_ag_context {
#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13
#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14)
#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG (0x1<<15)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG_SHIFT 15
+#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15)
+#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15
u8 agg_val3_th;
u8 agg_vars6;
#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6 (0x7<<0)
@@ -1310,8 +1396,8 @@ struct xstorm_iscsi_ag_context {
#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0
#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3)
#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3
-#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF (0x3<<4)
-#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_SHIFT 4
+#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4)
+#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4
#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6)
#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6
#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8)
@@ -1326,14 +1412,14 @@ struct xstorm_iscsi_ag_context {
#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13
#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14)
#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG (0x1<<15)
-#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG_SHIFT 15
+#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15)
+#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15
#endif
#if defined(__BIG_ENDIAN)
u16 __agg_val11_th;
- u16 __agg_val11;
+ u16 __gen_data;
#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val11;
+ u16 __gen_data;
u16 __agg_val11_th;
#endif
#if defined(__BIG_ENDIAN)
@@ -1384,7 +1470,7 @@ struct xstorm_iscsi_ag_context {
#endif
u32 hq_cons_tcp_seq;
u32 exp_stat_sn;
- u32 agg_misc5;
+ u32 rst_seq_num;
};
/*
@@ -1478,12 +1564,12 @@ struct tstorm_iscsi_ag_context {
#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF (0x3<<4)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_SHIFT 4
+#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4)
+#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4
#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6)
#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG (0x1<<7)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG_SHIFT 7
+#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7)
+#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7
u8 state;
#elif defined(__LITTLE_ENDIAN)
u8 state;
@@ -1496,63 +1582,63 @@ struct tstorm_iscsi_ag_context {
#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF (0x3<<4)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_SHIFT 4
+#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4)
+#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4
#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6)
#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG (0x1<<7)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG_SHIFT 7
+#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7)
+#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7
u16 ulp_credit;
#endif
#if defined(__BIG_ENDIAN)
u16 __agg_val4;
u16 agg_vars2;
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG (0x1<<0)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG_SHIFT 0
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG (0x1<<1)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG_SHIFT 1
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<2)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 2
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF (0x3<<4)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_SHIFT 4
+#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0)
+#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0
+#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1)
+#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1
+#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2)
+#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2
+#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4)
+#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4
#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6)
#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6
#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8)
#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8
#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10)
#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10
-#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<11)
-#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 11
-#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<12)
-#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 12
-#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN (0x1<<13)
-#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN_SHIFT 13
+#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11)
+#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11
+#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12)
+#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12
+#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13)
+#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13
#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14)
#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14
#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15)
#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN_SHIFT 15
#elif defined(__LITTLE_ENDIAN)
u16 agg_vars2;
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG (0x1<<0)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG_SHIFT 0
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG (0x1<<1)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG_SHIFT 1
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<2)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 2
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF (0x3<<4)
-#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_SHIFT 4
+#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0)
+#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0
+#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1)
+#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1
+#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2)
+#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2
+#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4)
+#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4
#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6)
#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6
#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8)
#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8
#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10)
#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10
-#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<11)
-#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 11
-#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<12)
-#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 12
-#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN (0x1<<13)
-#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN_SHIFT 13
+#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11)
+#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11
+#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12)
+#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12
+#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13)
+#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13
#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14)
#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14
#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15)
@@ -1563,100 +1649,6 @@ struct tstorm_iscsi_ag_context {
};
/*
- * The iscsi aggregative context of Cstorm
- */
-struct cstorm_iscsi_ag_context {
- u32 agg_vars1;
-#define CSTORM_ISCSI_AG_CONTEXT_STATE (0xFF<<0)
-#define CSTORM_ISCSI_AG_CONTEXT_STATE_SHIFT 0
-#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<8)
-#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 8
-#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<9)
-#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 9
-#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<10)
-#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 10
-#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<11)
-#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 11
-#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN (0x1<<12)
-#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN_SHIFT 12
-#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN (0x1<<13)
-#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN_SHIFT 13
-#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF (0x3<<14)
-#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_SHIFT 14
-#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66 (0x3<<16)
-#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66_SHIFT 16
-#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN (0x1<<18)
-#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN_SHIFT 18
-#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN (0x1<<19)
-#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN_SHIFT 19
-#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN (0x1<<20)
-#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN_SHIFT 20
-#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN (0x1<<21)
-#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN_SHIFT 21
-#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN (0x1<<22)
-#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN_SHIFT 22
-#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE (0x7<<23)
-#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE_SHIFT 23
-#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE (0x3<<26)
-#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE_SHIFT 26
-#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52 (0x3<<28)
-#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52_SHIFT 28
-#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53 (0x3<<30)
-#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53_SHIFT 30
-#if defined(__BIG_ENDIAN)
- u8 __aux1_th;
- u8 __aux1_val;
- u16 __agg_vars2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_vars2;
- u8 __aux1_val;
- u8 __aux1_th;
-#endif
- u32 rel_seq;
- u32 rel_seq_th;
-#if defined(__BIG_ENDIAN)
- u16 hq_cons;
- u16 hq_prod;
-#elif defined(__LITTLE_ENDIAN)
- u16 hq_prod;
- u16 hq_cons;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __reserved62;
- u8 __reserved61;
- u8 __reserved60;
- u8 __reserved59;
-#elif defined(__LITTLE_ENDIAN)
- u8 __reserved59;
- u8 __reserved60;
- u8 __reserved61;
- u8 __reserved62;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __reserved64;
- u16 __cq_u_prod0;
-#elif defined(__LITTLE_ENDIAN)
- u16 __cq_u_prod0;
- u16 __reserved64;
-#endif
- u32 __cq_u_prod1;
-#if defined(__BIG_ENDIAN)
- u16 __agg_vars3;
- u16 __cq_u_prod2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __cq_u_prod2;
- u16 __agg_vars3;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __aux2_th;
- u16 __cq_u_prod3;
-#elif defined(__LITTLE_ENDIAN)
- u16 __cq_u_prod3;
- u16 __aux2_th;
-#endif
-};
-
-/*
* The iscsi aggregative context of Ustorm
*/
struct ustorm_iscsi_ag_context {
@@ -1746,8 +1738,8 @@ struct ustorm_iscsi_ag_context {
#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0
#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3)
#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3
-#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6)
-#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6
+#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6)
+#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6
#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7)
#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7
u8 decision_rule_enable_bits;
@@ -1790,8 +1782,8 @@ struct ustorm_iscsi_ag_context {
#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0
#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3)
#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3
-#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6)
-#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6
+#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6)
+#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6
#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7)
#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7
u16 __reserved2;
@@ -1799,22 +1791,6 @@ struct ustorm_iscsi_ag_context {
};
/*
- * Timers connection context
- */
-struct iscsi_timers_block_context {
- u32 __reserved_0;
- u32 __reserved_1;
- u32 __reserved_2;
- u32 flags;
-#define __ISCSI_TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS (0x3<<0)
-#define __ISCSI_TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS_SHIFT 0
-#define ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG (0x1<<2)
-#define ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG_SHIFT 2
-#define __ISCSI_TIMERS_BLOCK_CONTEXT_RESERVED0 (0x1FFFFFFF<<3)
-#define __ISCSI_TIMERS_BLOCK_CONTEXT_RESERVED0_SHIFT 3
-};
-
-/*
* Ethernet context section, shared in TOE, RDMA and ISCSI
*/
struct xstorm_eth_context_section {
@@ -1963,7 +1939,7 @@ struct xstorm_tcp_context_section {
#endif
#if defined(__BIG_ENDIAN)
u8 original_nagle_1b;
- u8 ts_enabled_1b;
+ u8 ts_enabled;
u16 tcp_params;
#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE (0xFF<<0)
#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE_SHIFT 0
@@ -1973,8 +1949,8 @@ struct xstorm_tcp_context_section {
#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9
#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10)
#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10
-#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE (0x1<<11)
-#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE_SHIFT 11
+#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11)
+#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11
#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12)
#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12
#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13)
@@ -1991,15 +1967,15 @@ struct xstorm_tcp_context_section {
#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9
#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10)
#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10
-#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE (0x1<<11)
-#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE_SHIFT 11
+#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11)
+#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11
#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12)
#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12
#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13)
#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED_SHIFT 13
#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER (0x3<<14)
#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER_SHIFT 14
- u8 ts_enabled_1b;
+ u8 ts_enabled;
u8 original_nagle_1b;
#endif
#if defined(__BIG_ENDIAN)
@@ -2030,8 +2006,8 @@ struct xstorm_common_context_section {
#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1
#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2)
#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2
-#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0 (0x1<<7)
-#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0_SHIFT 7
+#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS (0x1<<7)
+#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS_SHIFT 7
u8 ip_version_1b;
#elif defined(__LITTLE_ENDIAN)
u8 ip_version_1b;
@@ -2042,8 +2018,8 @@ struct xstorm_common_context_section {
#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1
#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2)
#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2
-#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0 (0x1<<7)
-#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0_SHIFT 7
+#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS (0x1<<7)
+#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS_SHIFT 7
u16 reserved;
#endif
};
@@ -2284,7 +2260,7 @@ struct iscsi_context {
struct tstorm_iscsi_ag_context tstorm_ag_context;
struct cstorm_iscsi_ag_context cstorm_ag_context;
struct ustorm_iscsi_ag_context ustorm_ag_context;
- struct iscsi_timers_block_context timers_context;
+ struct timers_block_context timers_context;
struct regpair upb_context;
struct xstorm_iscsi_st_context xstorm_st_context;
struct regpair xpb_context;
@@ -2434,16 +2410,16 @@ struct l5cm_packet_size {
* l5cm connection parameters
*/
union l5cm_reduce_param_union {
- u32 passive_side_scramble_key;
- u32 pcs_id;
+ u32 opaque1;
+ u32 opaque2;
};
/*
* l5cm connection parameters
*/
struct l5cm_reduce_conn {
- union l5cm_reduce_param_union param;
- u32 isn;
+ union l5cm_reduce_param_union opaque1;
+ u32 opaque2;
};
/*
diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h
index 344c842d55ab..0dbeaec4f03a 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.1.3"
-#define CNIC_MODULE_RELDATE "June 24, 2010"
+#define CNIC_MODULE_VERSION "2.2.6"
+#define CNIC_MODULE_RELDATE "Oct 12, 2010"
#define CNIC_ULP_RDMA 0
#define CNIC_ULP_ISCSI 1
@@ -80,18 +80,15 @@ struct kcqe {
#define DRV_CTL_IO_RD_CMD 0x102
#define DRV_CTL_CTX_WR_CMD 0x103
#define DRV_CTL_CTXTBL_WR_CMD 0x104
-#define DRV_CTL_COMPLETION_CMD 0x105
+#define DRV_CTL_RET_L5_SPQ_CREDIT_CMD 0x105
#define DRV_CTL_START_L2_CMD 0x106
#define DRV_CTL_STOP_L2_CMD 0x107
+#define DRV_CTL_RET_L2_SPQ_CREDIT_CMD 0x10c
struct cnic_ctl_completion {
u32 cid;
};
-struct drv_ctl_completion {
- u32 comp_count;
-};
-
struct cnic_ctl_info {
int cmd;
union {
@@ -100,6 +97,10 @@ struct cnic_ctl_info {
} data;
};
+struct drv_ctl_spq_credit {
+ u32 credit_count;
+};
+
struct drv_ctl_io {
u32 cid_addr;
u32 offset;
@@ -115,7 +116,7 @@ struct drv_ctl_l2_ring {
struct drv_ctl_info {
int cmd;
union {
- struct drv_ctl_completion comp;
+ struct drv_ctl_spq_credit credit;
struct drv_ctl_io io;
struct drv_ctl_l2_ring ring;
char bytes[MAX_DRV_CTL_DATA];
@@ -138,6 +139,7 @@ struct cnic_irq {
unsigned int vector;
void *status_blk;
u32 status_blk_num;
+ u32 status_blk_num2;
u32 irq_flags;
#define CNIC_IRQ_FL_MSIX 0x00000001
};
@@ -152,6 +154,7 @@ struct cnic_eth_dev {
struct pci_dev *pdev;
void __iomem *io_base;
void __iomem *io_base2;
+ void *iro_arr;
u32 ctx_tbl_offset;
u32 ctx_tbl_len;
@@ -160,7 +163,9 @@ struct cnic_eth_dev {
u32 max_iscsi_conn;
u32 max_fcoe_conn;
u32 max_rdma_conn;
- u32 reserved0[2];
+ u32 fcoe_init_cid;
+ u16 iscsi_l2_client_id;
+ u16 iscsi_l2_cid;
int num_irq;
struct cnic_irq irq_arr[MAX_CNIC_VEC];
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index e1f6156b3710..fec939f8f65f 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -38,7 +38,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
-#include <asm/gpio.h>
+#include <linux/gpio.h>
#include <asm/atomic.h>
MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>");
@@ -108,7 +108,7 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
#define CPMAC_RX_INT_CLEAR 0x019c
#define CPMAC_MAC_INT_ENABLE 0x01a8
#define CPMAC_MAC_INT_CLEAR 0x01ac
-#define CPMAC_MAC_ADDR_LO(channel) (0x01b0 + (channel) * 4)
+#define CPMAC_MAC_ADDR_LO(channel) (0x01b0 + (channel) * 4)
#define CPMAC_MAC_ADDR_MID 0x01d0
#define CPMAC_MAC_ADDR_HI 0x01d4
#define CPMAC_MAC_HASH_LO 0x01d8
@@ -227,7 +227,7 @@ static void cpmac_dump_regs(struct net_device *dev)
for (i = 0; i < CPMAC_REG_END; i += 4) {
if (i % 16 == 0) {
if (i)
- printk("\n");
+ pr_cont("\n");
printk(KERN_DEBUG "%s: reg[%p]:", dev->name,
priv->regs + i);
}
@@ -262,7 +262,7 @@ static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb)
for (i = 0; i < skb->len; i++) {
if (i % 16 == 0) {
if (i)
- printk("\n");
+ pr_cont("\n");
printk(KERN_DEBUG "%s: data[%p]:", dev->name,
skb->data + i);
}
@@ -391,7 +391,7 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv,
if (likely(skb)) {
skb_put(desc->skb, desc->datalen);
desc->skb->protocol = eth_type_trans(desc->skb, priv->dev);
- desc->skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(desc->skb);
priv->dev->stats.rx_packets++;
priv->dev->stats.rx_bytes += desc->datalen;
result = desc->skb;
@@ -506,7 +506,7 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
"restart rx from a descriptor that's "
"not free: %p\n",
priv->dev->name, restart);
- goto fatal_error;
+ goto fatal_error;
}
cpmac_write(priv->regs, CPMAC_RX_PTR(0), restart->mapping);
@@ -873,7 +873,8 @@ static int cpmac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
}
-static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring)
+static void cpmac_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ring)
{
struct cpmac_priv *priv = netdev_priv(dev);
@@ -888,7 +889,8 @@ static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam
ring->tx_pending = 1;
}
-static int cpmac_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ring)
+static int cpmac_set_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ring)
{
struct cpmac_priv *priv = netdev_priv(dev);
@@ -1012,8 +1014,8 @@ static int cpmac_open(struct net_device *dev)
priv->rx_head->prev->hw_next = (u32)0;
- if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED,
- dev->name, dev))) {
+ res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, dev->name, dev);
+ if (res) {
if (netif_msg_drv(priv))
printk(KERN_ERR "%s: failed to obtain irq\n",
dev->name);
@@ -1133,7 +1135,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
}
if (phy_id == PHY_MAX_ADDR) {
- dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n");
+ dev_err(&pdev->dev, "no PHY present, falling back "
+ "to switch on MDIO bus 0\n");
strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
phy_id = pdev->id;
}
@@ -1169,9 +1172,10 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
priv->msg_enable = netif_msg_init(debug_level, 0xff);
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(pdata->dev_addr));
- snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
+ snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT,
+ mdio_bus_id, phy_id);
- priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0,
+ priv->phy = phy_connect(dev, priv->phy_name, cpmac_adjust_link, 0,
PHY_INTERFACE_MODE_MII);
if (IS_ERR(priv->phy)) {
@@ -1182,7 +1186,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
goto fail;
}
- if ((rc = register_netdev(dev))) {
+ rc = register_netdev(dev);
+ if (rc) {
printk(KERN_ERR "cpmac: error %i registering device %s\n", rc,
dev->name);
goto fail;
@@ -1248,11 +1253,13 @@ int __devinit cpmac_init(void)
cpmac_mii->reset(cpmac_mii);
- for (i = 0; i < 300; i++)
- if ((mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE)))
+ for (i = 0; i < 300; i++) {
+ mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE);
+ if (mask)
break;
else
msleep(10);
+ }
mask &= 0x7fffffff;
if (mask & (mask - 1)) {
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 4cd7f420766a..ef67be59680f 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -336,9 +336,6 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
int irq_vec_idx, const struct qset_params *p,
int ntxq, struct net_device *dev,
struct netdev_queue *netdevq);
-int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
- unsigned char *data);
-irqreturn_t t3_sge_intr_msix(int irq, void *cookie);
extern struct workqueue_struct *cxgb3_wq;
int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size);
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index fe08a004b0dd..5ccb77d078aa 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -673,7 +673,6 @@ void t3_xgm_intr_enable(struct adapter *adapter, int idx);
void t3_xgm_intr_disable(struct adapter *adapter, int idx);
void t3_port_intr_enable(struct adapter *adapter, int idx);
void t3_port_intr_disable(struct adapter *adapter, int idx);
-void t3_port_intr_clear(struct adapter *adapter, int idx);
int t3_slow_intr_handler(struct adapter *adapter);
int t3_phy_intr_handler(struct adapter *adapter);
@@ -689,14 +688,10 @@ int t3_check_tpsram_version(struct adapter *adapter);
int t3_check_tpsram(struct adapter *adapter, const u8 *tp_ram,
unsigned int size);
int t3_set_proto_sram(struct adapter *adap, const u8 *data);
-int t3_read_flash(struct adapter *adapter, unsigned int addr,
- unsigned int nwords, u32 *data, int byte_oriented);
int t3_load_fw(struct adapter *adapter, const u8 * fw_data, unsigned int size);
int t3_get_fw_version(struct adapter *adapter, u32 *vers);
int t3_check_fw_version(struct adapter *adapter);
int t3_init_hw(struct adapter *adapter, u32 fw_params);
-void mac_prep(struct cmac *mac, struct adapter *adapter, int index);
-void early_hw_init(struct adapter *adapter, const struct adapter_info *ai);
int t3_reset_adapter(struct adapter *adapter);
int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
int reset);
@@ -706,8 +701,6 @@ void t3_fatal_err(struct adapter *adapter);
void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on);
void t3_config_rss(struct adapter *adapter, unsigned int rss_config,
const u8 * cpus, const u16 *rspq);
-int t3_read_rss(struct adapter *adapter, u8 * lkup, u16 *map);
-int t3_mps_set_active_ports(struct adapter *adap, unsigned int port_mask);
int t3_cim_ctl_blk_read(struct adapter *adap, unsigned int addr,
unsigned int n, unsigned int *valp);
int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n,
@@ -731,19 +724,12 @@ void t3_mc5_prep(struct adapter *adapter, struct mc5 *mc5, int mode);
int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
unsigned int nroutes);
void t3_mc5_intr_handler(struct mc5 *mc5);
-int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, unsigned int n,
- u32 *buf);
-int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh);
-void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size);
void t3_tp_set_offload_mode(struct adapter *adap, int enable);
void t3_tp_get_mib_stats(struct adapter *adap, struct tp_mib_stats *tps);
void t3_load_mtus(struct adapter *adap, unsigned short mtus[NMTUS],
unsigned short alpha[NCCTRL_WIN],
unsigned short beta[NCCTRL_WIN], unsigned short mtu_cap);
-void t3_read_hw_mtus(struct adapter *adap, unsigned short mtus[NMTUS]);
-void t3_get_cong_cntl_tab(struct adapter *adap,
- unsigned short incr[NMTUS][NCCTRL_WIN]);
void t3_config_trace_filter(struct adapter *adapter,
const struct trace_params *tp, int filter_index,
int invert, int enable);
@@ -769,10 +755,6 @@ int t3_sge_enable_ecntxt(struct adapter *adapter, unsigned int id, int enable);
int t3_sge_disable_fl(struct adapter *adapter, unsigned int id);
int t3_sge_disable_rspcntxt(struct adapter *adapter, unsigned int id);
int t3_sge_disable_cqcntxt(struct adapter *adapter, unsigned int id);
-int t3_sge_read_ecntxt(struct adapter *adapter, unsigned int id, u32 data[4]);
-int t3_sge_read_fl(struct adapter *adapter, unsigned int id, u32 data[4]);
-int t3_sge_read_cq(struct adapter *adapter, unsigned int id, u32 data[4]);
-int t3_sge_read_rspq(struct adapter *adapter, unsigned int id, u32 data[4]);
int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op,
unsigned int credits);
diff --git a/drivers/net/cxgb3/cxgb3_defs.h b/drivers/net/cxgb3/cxgb3_defs.h
index 47e53769af5b..920d918ed193 100644
--- a/drivers/net/cxgb3/cxgb3_defs.h
+++ b/drivers/net/cxgb3/cxgb3_defs.h
@@ -43,8 +43,6 @@
void *cxgb_alloc_mem(unsigned long size);
void cxgb_free_mem(void *addr);
-void cxgb_neigh_update(struct neighbour *neigh);
-void cxgb_redirect(struct dst_entry *old, struct dst_entry *new);
/*
* Map an ATID or STID to their entries in the corresponding TID tables.
@@ -111,7 +109,6 @@ static inline struct t3c_tid_entry *lookup_atid(const struct tid_info *t,
return &e->t3c_tid;
}
-int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n);
int attach_t3cdev(struct t3cdev *dev);
void detach_t3cdev(struct t3cdev *dev);
#endif
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index f208712c0b90..a04ce6a5f637 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1286,7 +1286,7 @@ irq_err:
/*
* Release resources when all the ports and offloading have been stopped.
*/
-static void cxgb_down(struct adapter *adapter)
+static void cxgb_down(struct adapter *adapter, int on_wq)
{
t3_sge_stop(adapter);
spin_lock_irq(&adapter->work_lock); /* sync with PHY intr task */
@@ -1296,7 +1296,8 @@ static void cxgb_down(struct adapter *adapter)
free_irq_resources(adapter);
quiesce_rx(adapter);
t3_sge_stop(adapter);
- flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
+ if (!on_wq)
+ flush_workqueue(cxgb3_wq);/* wait for external IRQ handler */
}
static void schedule_chk_task(struct adapter *adap)
@@ -1374,7 +1375,7 @@ static int offload_close(struct t3cdev *tdev)
clear_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map);
if (!adapter->open_device_map)
- cxgb_down(adapter);
+ cxgb_down(adapter, 0);
cxgb3_offload_deactivate(adapter);
return 0;
@@ -1398,7 +1399,10 @@ static int cxgb_open(struct net_device *dev)
"Could not initialize offload capabilities\n");
}
- dev->real_num_tx_queues = pi->nqsets;
+ netif_set_real_num_tx_queues(dev, pi->nqsets);
+ err = netif_set_real_num_rx_queues(dev, pi->nqsets);
+ if (err)
+ return err;
link_start(dev);
t3_port_intr_enable(adapter, pi->port_id);
netif_tx_start_all_queues(dev);
@@ -1409,7 +1413,7 @@ static int cxgb_open(struct net_device *dev)
return 0;
}
-static int cxgb_close(struct net_device *dev)
+static int __cxgb_close(struct net_device *dev, int on_wq)
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
@@ -1436,12 +1440,17 @@ static int cxgb_close(struct net_device *dev)
cancel_delayed_work_sync(&adapter->adap_check_task);
if (!adapter->open_device_map)
- cxgb_down(adapter);
+ cxgb_down(adapter, on_wq);
cxgb3_event_notify(&adapter->tdev, OFFLOAD_PORT_DOWN, pi->port_id);
return 0;
}
+static int cxgb_close(struct net_device *dev)
+{
+ return __cxgb_close(dev, 0);
+}
+
static struct net_device_stats *cxgb_get_stats(struct net_device *dev)
{
struct port_info *pi = netdev_priv(dev);
@@ -2864,7 +2873,7 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
spin_unlock(&adapter->work_lock);
}
-static int t3_adapter_error(struct adapter *adapter, int reset)
+static int t3_adapter_error(struct adapter *adapter, int reset, int on_wq)
{
int i, ret = 0;
@@ -2879,7 +2888,7 @@ static int t3_adapter_error(struct adapter *adapter, int reset)
struct net_device *netdev = adapter->port[i];
if (netif_running(netdev))
- cxgb_close(netdev);
+ __cxgb_close(netdev, on_wq);
}
/* Stop SGE timers */
@@ -2950,7 +2959,7 @@ static void fatal_error_task(struct work_struct *work)
int err = 0;
rtnl_lock();
- err = t3_adapter_error(adapter, 1);
+ err = t3_adapter_error(adapter, 1, 1);
if (!err)
err = t3_reenable_adapter(adapter);
if (!err)
@@ -3000,7 +3009,7 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
if (state == pci_channel_io_perm_failure)
return PCI_ERS_RESULT_DISCONNECT;
- ret = t3_adapter_error(adapter, 0);
+ ret = t3_adapter_error(adapter, 0, 0);
/* Request a slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index c6485b39eb0e..bcf07532953d 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -60,11 +60,14 @@ static LIST_HEAD(adapter_list);
static const unsigned int MAX_ATIDS = 64 * 1024;
static const unsigned int ATID_BASE = 0x10000;
+static void cxgb_neigh_update(struct neighbour *neigh);
+static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new);
+
static inline int offload_activated(struct t3cdev *tdev)
{
const struct adapter *adapter = tdev2adap(tdev);
- return (test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map));
+ return test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map);
}
/**
@@ -1015,7 +1018,7 @@ EXPORT_SYMBOL(t3_register_cpl_handler);
/*
* T3CDEV's receive method.
*/
-int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n)
+static int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n)
{
while (n--) {
struct sk_buff *skb = *skbs++;
@@ -1070,7 +1073,7 @@ static int is_offloading(struct net_device *dev)
return 0;
}
-void cxgb_neigh_update(struct neighbour *neigh)
+static void cxgb_neigh_update(struct neighbour *neigh)
{
struct net_device *dev = neigh->dev;
@@ -1104,7 +1107,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e)
tdev->send(tdev, skb);
}
-void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
+static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
{
struct net_device *olddev, *newdev;
struct tid_info *ti;
diff --git a/drivers/net/cxgb3/mc5.c b/drivers/net/cxgb3/mc5.c
index 3b5517b8fbde..a8766fb2f9ab 100644
--- a/drivers/net/cxgb3/mc5.c
+++ b/drivers/net/cxgb3/mc5.c
@@ -374,44 +374,6 @@ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
return err;
}
-/*
- * read_mc5_range - dump a part of the memory managed by MC5
- * @mc5: the MC5 handle
- * @start: the start address for the dump
- * @n: number of 72-bit words to read
- * @buf: result buffer
- *
- * Read n 72-bit words from MC5 memory from the given start location.
- */
-int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start,
- unsigned int n, u32 *buf)
-{
- u32 read_cmd;
- int err = 0;
- struct adapter *adap = mc5->adapter;
-
- if (mc5->part_type == IDT75P52100)
- read_cmd = IDT_CMD_READ;
- else if (mc5->part_type == IDT75N43102)
- read_cmd = IDT4_CMD_READ;
- else
- return -EINVAL;
-
- mc5_dbgi_mode_enable(mc5);
-
- while (n--) {
- t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR0, start++);
- if (mc5_cmd_write(adap, read_cmd)) {
- err = -EIO;
- break;
- }
- dbgi_rd_rsp3(adap, buf + 2, buf + 1, buf);
- buf += 3;
- }
-
- mc5_dbgi_mode_disable(mc5);
- return 0;
-}
#define MC5_INT_FATAL (F_PARITYERR | F_REQQPARERR | F_DISPQPARERR)
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index cb42353c9fdd..6990f6c65221 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -1997,6 +1997,10 @@
#define A_PL_RST 0x6f0
+#define S_FATALPERREN 4
+#define V_FATALPERREN(x) ((x) << S_FATALPERREN)
+#define F_FATALPERREN V_FATALPERREN(1U)
+
#define S_CRSTWRM 1
#define V_CRSTWRM(x) ((x) << S_CRSTWRM)
#define F_CRSTWRM V_CRSTWRM(1U)
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 8ff96c6f6de5..5d72bda54389 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1145,7 +1145,7 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb,
cpl->len = htonl(skb->len);
cntrl = V_TXPKT_INTF(pi->port_id);
- if (vlan_tx_tag_present(skb) && pi->vlan_grp)
+ if (vlan_tx_tag_present(skb))
cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN(vlan_tx_tag_get(skb));
tso_info = V_LSO_MSS(skb_shinfo(skb)->gso_size);
@@ -1279,7 +1279,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
qs->port_stats[SGE_PSTAT_TX_CSUM]++;
if (skb_shinfo(skb)->gso_size)
qs->port_stats[SGE_PSTAT_TSO]++;
- if (vlan_tx_tag_present(skb) && pi->vlan_grp)
+ if (vlan_tx_tag_present(skb))
qs->port_stats[SGE_PSTAT_VLANINS]++;
/*
@@ -2022,7 +2022,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
if (unlikely(p->vlan_valid)) {
@@ -2554,7 +2554,7 @@ static inline int handle_responses(struct adapter *adap, struct sge_rspq *q)
* The MSI-X interrupt handler for an SGE response queue for the non-NAPI case
* (i.e., response queue serviced in hard interrupt).
*/
-irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
+static irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
{
struct sge_qset *qs = cookie;
struct adapter *adap = qs->adap;
@@ -3320,40 +3320,3 @@ void t3_sge_prep(struct adapter *adap, struct sge_params *p)
spin_lock_init(&adap->sge.reg_lock);
}
-
-/**
- * t3_get_desc - dump an SGE descriptor for debugging purposes
- * @qs: the queue set
- * @qnum: identifies the specific queue (0..2: Tx, 3:response, 4..5: Rx)
- * @idx: the descriptor index in the queue
- * @data: where to dump the descriptor contents
- *
- * Dumps the contents of a HW descriptor of an SGE queue. Returns the
- * size of the descriptor.
- */
-int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
- unsigned char *data)
-{
- if (qnum >= 6)
- return -EINVAL;
-
- if (qnum < 3) {
- if (!qs->txq[qnum].desc || idx >= qs->txq[qnum].size)
- return -EINVAL;
- memcpy(data, &qs->txq[qnum].desc[idx], sizeof(struct tx_desc));
- return sizeof(struct tx_desc);
- }
-
- if (qnum == 3) {
- if (!qs->rspq.desc || idx >= qs->rspq.size)
- return -EINVAL;
- memcpy(data, &qs->rspq.desc[idx], sizeof(struct rsp_desc));
- return sizeof(struct rsp_desc);
- }
-
- qnum -= 4;
- if (!qs->fl[qnum].desc || idx >= qs->fl[qnum].size)
- return -EINVAL;
- memcpy(data, &qs->fl[qnum].desc[idx], sizeof(struct rx_desc));
- return sizeof(struct rx_desc);
-}
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 427c451be1a7..3a6adf0b3e9d 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -34,6 +34,8 @@
#include "sge_defs.h"
#include "firmware_exports.h"
+static void t3_port_intr_clear(struct adapter *adapter, int idx);
+
/**
* t3_wait_op_done_val - wait until an operation is completed
* @adapter: the adapter performing the operation
@@ -840,8 +842,8 @@ static int flash_wait_op(struct adapter *adapter, int attempts, int delay)
* (i.e., big-endian), otherwise as 32-bit words in the platform's
* natural endianess.
*/
-int t3_read_flash(struct adapter *adapter, unsigned int addr,
- unsigned int nwords, u32 *data, int byte_oriented)
+static int t3_read_flash(struct adapter *adapter, unsigned int addr,
+ unsigned int nwords, u32 *data, int byte_oriented)
{
int ret;
@@ -1408,6 +1410,7 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
fatal++;
CH_ALERT(adapter, "%s (0x%x)\n",
acts->msg, status & acts->mask);
+ status &= ~acts->mask;
} else if (acts->msg)
CH_WARN(adapter, "%s (0x%x)\n",
acts->msg, status & acts->mask);
@@ -1843,11 +1846,10 @@ static int mac_intr_handler(struct adapter *adap, unsigned int idx)
t3_os_link_fault_handler(adap, idx);
}
- t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause);
-
if (cause & XGM_INTR_FATAL)
t3_fatal_err(adap);
+ t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause);
return cause != 0;
}
@@ -2111,7 +2113,7 @@ void t3_port_intr_disable(struct adapter *adapter, int idx)
* Clear port-specific (i.e., MAC and PHY) interrupts for the given
* adapter port.
*/
-void t3_port_intr_clear(struct adapter *adapter, int idx)
+static void t3_port_intr_clear(struct adapter *adapter, int idx)
{
struct cphy *phy = &adap2pinfo(adapter, idx)->phy;
@@ -2484,98 +2486,6 @@ int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op,
}
/**
- * t3_sge_read_context - read an SGE context
- * @type: the context type
- * @adapter: the adapter
- * @id: the context id
- * @data: holds the retrieved context
- *
- * Read an SGE egress context. The caller is responsible for ensuring
- * only one context operation occurs at a time.
- */
-static int t3_sge_read_context(unsigned int type, struct adapter *adapter,
- unsigned int id, u32 data[4])
-{
- if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
- return -EBUSY;
-
- t3_write_reg(adapter, A_SG_CONTEXT_CMD,
- V_CONTEXT_CMD_OPCODE(0) | type | V_CONTEXT(id));
- if (t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, 0,
- SG_CONTEXT_CMD_ATTEMPTS, 1))
- return -EIO;
- data[0] = t3_read_reg(adapter, A_SG_CONTEXT_DATA0);
- data[1] = t3_read_reg(adapter, A_SG_CONTEXT_DATA1);
- data[2] = t3_read_reg(adapter, A_SG_CONTEXT_DATA2);
- data[3] = t3_read_reg(adapter, A_SG_CONTEXT_DATA3);
- return 0;
-}
-
-/**
- * t3_sge_read_ecntxt - read an SGE egress context
- * @adapter: the adapter
- * @id: the context id
- * @data: holds the retrieved context
- *
- * Read an SGE egress context. The caller is responsible for ensuring
- * only one context operation occurs at a time.
- */
-int t3_sge_read_ecntxt(struct adapter *adapter, unsigned int id, u32 data[4])
-{
- if (id >= 65536)
- return -EINVAL;
- return t3_sge_read_context(F_EGRESS, adapter, id, data);
-}
-
-/**
- * t3_sge_read_cq - read an SGE CQ context
- * @adapter: the adapter
- * @id: the context id
- * @data: holds the retrieved context
- *
- * Read an SGE CQ context. The caller is responsible for ensuring
- * only one context operation occurs at a time.
- */
-int t3_sge_read_cq(struct adapter *adapter, unsigned int id, u32 data[4])
-{
- if (id >= 65536)
- return -EINVAL;
- return t3_sge_read_context(F_CQ, adapter, id, data);
-}
-
-/**
- * t3_sge_read_fl - read an SGE free-list context
- * @adapter: the adapter
- * @id: the context id
- * @data: holds the retrieved context
- *
- * Read an SGE free-list context. The caller is responsible for ensuring
- * only one context operation occurs at a time.
- */
-int t3_sge_read_fl(struct adapter *adapter, unsigned int id, u32 data[4])
-{
- if (id >= SGE_QSETS * 2)
- return -EINVAL;
- return t3_sge_read_context(F_FREELIST, adapter, id, data);
-}
-
-/**
- * t3_sge_read_rspq - read an SGE response queue context
- * @adapter: the adapter
- * @id: the context id
- * @data: holds the retrieved context
- *
- * Read an SGE response queue context. The caller is responsible for
- * ensuring only one context operation occurs at a time.
- */
-int t3_sge_read_rspq(struct adapter *adapter, unsigned int id, u32 data[4])
-{
- if (id >= SGE_QSETS)
- return -EINVAL;
- return t3_sge_read_context(F_RESPONSEQ, adapter, id, data);
-}
-
-/**
* t3_config_rss - configure Rx packet steering
* @adapter: the adapter
* @rss_config: RSS settings (written to TP_RSS_CONFIG)
@@ -2616,42 +2526,6 @@ void t3_config_rss(struct adapter *adapter, unsigned int rss_config,
}
/**
- * t3_read_rss - read the contents of the RSS tables
- * @adapter: the adapter
- * @lkup: holds the contents of the RSS lookup table
- * @map: holds the contents of the RSS map table
- *
- * Reads the contents of the receive packet steering tables.
- */
-int t3_read_rss(struct adapter *adapter, u8 * lkup, u16 *map)
-{
- int i;
- u32 val;
-
- if (lkup)
- for (i = 0; i < RSS_TABLE_SIZE; ++i) {
- t3_write_reg(adapter, A_TP_RSS_LKP_TABLE,
- 0xffff0000 | i);
- val = t3_read_reg(adapter, A_TP_RSS_LKP_TABLE);
- if (!(val & 0x80000000))
- return -EAGAIN;
- *lkup++ = val;
- *lkup++ = (val >> 8);
- }
-
- if (map)
- for (i = 0; i < RSS_TABLE_SIZE; ++i) {
- t3_write_reg(adapter, A_TP_RSS_MAP_TABLE,
- 0xffff0000 | i);
- val = t3_read_reg(adapter, A_TP_RSS_MAP_TABLE);
- if (!(val & 0x80000000))
- return -EAGAIN;
- *map++ = val;
- }
- return 0;
-}
-
-/**
* t3_tp_set_offload_mode - put TP in NIC/offload mode
* @adap: the adapter
* @enable: 1 to select offload mode, 0 for regular NIC
@@ -2868,7 +2742,8 @@ static void tp_set_timers(struct adapter *adap, unsigned int core_clk)
*
* Set the receive coalescing size and PSH bit handling.
*/
-int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh)
+static int t3_tp_set_coalescing_size(struct adapter *adap,
+ unsigned int size, int psh)
{
u32 val;
@@ -2898,7 +2773,7 @@ int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh)
* Set TP's max receive size. This is the limit that applies when
* receive coalescing is disabled.
*/
-void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size)
+static void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size)
{
t3_write_reg(adap, A_TP_PARA_REG7,
V_PMMAXXFERLEN0(size) | V_PMMAXXFERLEN1(size));
@@ -3018,48 +2893,6 @@ void t3_load_mtus(struct adapter *adap, unsigned short mtus[NMTUS],
}
/**
- * t3_read_hw_mtus - returns the values in the HW MTU table
- * @adap: the adapter
- * @mtus: where to store the HW MTU values
- *
- * Reads the HW MTU table.
- */
-void t3_read_hw_mtus(struct adapter *adap, unsigned short mtus[NMTUS])
-{
- int i;
-
- for (i = 0; i < NMTUS; ++i) {
- unsigned int val;
-
- t3_write_reg(adap, A_TP_MTU_TABLE, 0xff000000 | i);
- val = t3_read_reg(adap, A_TP_MTU_TABLE);
- mtus[i] = val & 0x3fff;
- }
-}
-
-/**
- * t3_get_cong_cntl_tab - reads the congestion control table
- * @adap: the adapter
- * @incr: where to store the alpha values
- *
- * Reads the additive increments programmed into the HW congestion
- * control table.
- */
-void t3_get_cong_cntl_tab(struct adapter *adap,
- unsigned short incr[NMTUS][NCCTRL_WIN])
-{
- unsigned int mtu, w;
-
- for (mtu = 0; mtu < NMTUS; ++mtu)
- for (w = 0; w < NCCTRL_WIN; ++w) {
- t3_write_reg(adap, A_TP_CCTRL_TABLE,
- 0xffff0000 | (mtu << 5) | w);
- incr[mtu][w] = t3_read_reg(adap, A_TP_CCTRL_TABLE) &
- 0x1fff;
- }
-}
-
-/**
* t3_tp_get_mib_stats - read TP's MIB counters
* @adap: the adapter
* @tps: holds the returned counter values
@@ -3223,15 +3056,6 @@ static int tp_init(struct adapter *adap, const struct tp_params *p)
return busy;
}
-int t3_mps_set_active_ports(struct adapter *adap, unsigned int port_mask)
-{
- if (port_mask & ~((1 << adap->params.nports) - 1))
- return -EINVAL;
- t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE | F_PORT0ACTIVE,
- port_mask << S_PORT0ACTIVE);
- return 0;
-}
-
/*
* Perform the bits of HW initialization that are dependent on the Tx
* channels being used.
@@ -3569,6 +3393,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
t3_write_reg(adapter, A_PM1_TX_MODE, 0);
chan_init_hw(adapter, adapter->params.chan_map);
t3_sge_init(adapter, &adapter->params.sge);
+ t3_set_reg_field(adapter, A_PL_RST, 0, F_FATALPERREN);
t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW, calc_gpio_intr(adapter));
@@ -3682,11 +3507,11 @@ static void mc7_prep(struct adapter *adapter, struct mc7 *mc7,
mc7->name = name;
mc7->offset = base_addr - MC7_PMRX_BASE_ADDR;
cfg = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
- mc7->size = mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg);
+ mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg);
mc7->width = G_WIDTH(cfg);
}
-void mac_prep(struct cmac *mac, struct adapter *adapter, int index)
+static void mac_prep(struct cmac *mac, struct adapter *adapter, int index)
{
u16 devid;
@@ -3706,7 +3531,8 @@ void mac_prep(struct cmac *mac, struct adapter *adapter, int index)
}
}
-void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
+static void early_hw_init(struct adapter *adapter,
+ const struct adapter_info *ai)
{
u32 val = V_PORTSPEED(is_10G(adapter) ? 3 : 2);
diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
index 6e562c0dad7d..eaa49e4119f1 100644
--- a/drivers/net/cxgb4/cxgb4.h
+++ b/drivers/net/cxgb4/cxgb4.h
@@ -463,6 +463,8 @@ struct sge {
u8 counter_val[SGE_NCOUNTERS];
unsigned int starve_thres;
u8 idma_state[2];
+ unsigned int egr_start;
+ unsigned int ingr_start;
void *egr_map[MAX_EGRQ]; /* qid->queue egress queue map */
struct sge_rspq *ingr_map[MAX_INGQ]; /* qid->queue ingress queue map */
DECLARE_BITMAP(starving_fl, MAX_EGRQ);
@@ -590,7 +592,6 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id);
void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat);
void *t4_alloc_mem(size_t size);
-void t4_free_mem(void *addr);
void t4_free_sge_resources(struct adapter *adap);
irq_handler_t t4_intr_handler(struct adapter *adap);
@@ -649,7 +650,6 @@ static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd,
void t4_intr_enable(struct adapter *adapter);
void t4_intr_disable(struct adapter *adapter);
-void t4_intr_clear(struct adapter *adapter);
int t4_slow_intr_handler(struct adapter *adapter);
int t4_wait_dev_ready(struct adapter *adap);
@@ -662,24 +662,16 @@ int t4_check_fw_version(struct adapter *adapter);
int t4_prep_adapter(struct adapter *adapter);
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
void t4_fatal_err(struct adapter *adapter);
-int t4_set_trace_filter(struct adapter *adapter, const struct trace_params *tp,
- int filter_index, int enable);
-void t4_get_trace_filter(struct adapter *adapter, struct trace_params *tp,
- int filter_index, int *enabled);
int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
int start, int n, const u16 *rspq, unsigned int nrspq);
int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
unsigned int flags);
-int t4_read_rss(struct adapter *adapter, u16 *entries);
int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *parity);
int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data,
u64 *parity);
void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p);
-void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p);
-
void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log);
-void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st);
void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
struct tp_tcp_stats *v6);
void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
@@ -709,8 +701,6 @@ int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
unsigned int *rss_size);
-int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
- unsigned int vf, unsigned int viid);
int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
int mtu, int promisc, int all_multi, int bcast, int vlanex,
bool sleep_ok);
@@ -729,9 +719,6 @@ int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
unsigned int mmd, unsigned int reg, u16 *valp);
int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
unsigned int mmd, unsigned int reg, u16 val);
-int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start,
- unsigned int pf, unsigned int vf, unsigned int iqid,
- unsigned int fl0id, unsigned int fl1id);
int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
unsigned int vf, unsigned int iqtype, unsigned int iqid,
unsigned int fl0id, unsigned int fl1id);
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index e2bf10d90add..87054e0a5746 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -175,16 +175,26 @@ enum {
static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
CH_DEVICE(0xa000, 0), /* PE10K */
- CH_DEVICE(0x4001, 0),
- CH_DEVICE(0x4002, 0),
- CH_DEVICE(0x4003, 0),
- CH_DEVICE(0x4004, 0),
- CH_DEVICE(0x4005, 0),
- CH_DEVICE(0x4006, 0),
- CH_DEVICE(0x4007, 0),
- CH_DEVICE(0x4008, 0),
- CH_DEVICE(0x4009, 0),
- CH_DEVICE(0x400a, 0),
+ CH_DEVICE(0x4001, -1),
+ CH_DEVICE(0x4002, -1),
+ CH_DEVICE(0x4003, -1),
+ CH_DEVICE(0x4004, -1),
+ CH_DEVICE(0x4005, -1),
+ CH_DEVICE(0x4006, -1),
+ CH_DEVICE(0x4007, -1),
+ CH_DEVICE(0x4008, -1),
+ CH_DEVICE(0x4009, -1),
+ CH_DEVICE(0x400a, -1),
+ CH_DEVICE(0x4401, 4),
+ CH_DEVICE(0x4402, 4),
+ CH_DEVICE(0x4403, 4),
+ CH_DEVICE(0x4404, 4),
+ CH_DEVICE(0x4405, 4),
+ CH_DEVICE(0x4406, 4),
+ CH_DEVICE(0x4407, 4),
+ CH_DEVICE(0x4408, 4),
+ CH_DEVICE(0x4409, 4),
+ CH_DEVICE(0x440a, 4),
{ 0, }
};
@@ -423,10 +433,11 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
if (likely(opcode == CPL_SGE_EGR_UPDATE)) {
const struct cpl_sge_egr_update *p = (void *)rsp;
unsigned int qid = EGR_QID(ntohl(p->opcode_qid));
- struct sge_txq *txq = q->adap->sge.egr_map[qid];
+ struct sge_txq *txq;
+ txq = q->adap->sge.egr_map[qid - q->adap->sge.egr_start];
txq->restarts++;
- if ((u8 *)txq < (u8 *)q->adap->sge.ethrxq) {
+ if ((u8 *)txq < (u8 *)q->adap->sge.ofldtxq) {
struct sge_eth_txq *eq;
eq = container_of(txq, struct sge_eth_txq, q);
@@ -658,6 +669,15 @@ static int setup_rss(struct adapter *adap)
}
/*
+ * Return the channel of the ingress queue with the given qid.
+ */
+static unsigned int rxq_to_chan(const struct sge *p, unsigned int qid)
+{
+ qid -= p->ingr_start;
+ return netdev2pinfo(p->ingr_map[qid]->netdev)->tx_chan;
+}
+
+/*
* Wait until all NAPI handlers are descheduled.
*/
static void quiesce_rx(struct adapter *adap)
@@ -860,7 +880,7 @@ void *t4_alloc_mem(size_t size)
/*
* Free memory allocated through alloc_mem().
*/
-void t4_free_mem(void *addr)
+static void t4_free_mem(void *addr)
{
if (is_vmalloc_addr(addr))
vfree(addr);
@@ -1671,27 +1691,41 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
return 0;
}
-/*
- * Translate a physical EEPROM address to virtual. The first 1K is accessed
- * through virtual addresses starting at 31K, the rest is accessed through
- * virtual addresses starting at 0. This mapping is correct only for PF0.
+/**
+ * eeprom_ptov - translate a physical EEPROM address to virtual
+ * @phys_addr: the physical EEPROM address
+ * @fn: the PCI function number
+ * @sz: size of function-specific area
+ *
+ * Translate a physical EEPROM address to virtual. The first 1K is
+ * accessed through virtual addresses starting at 31K, the rest is
+ * accessed through virtual addresses starting at 0.
+ *
+ * The mapping is as follows:
+ * [0..1K) -> [31K..32K)
+ * [1K..1K+A) -> [31K-A..31K)
+ * [1K+A..ES) -> [0..ES-A-1K)
+ *
+ * where A = @fn * @sz, and ES = EEPROM size.
*/
-static int eeprom_ptov(unsigned int phys_addr)
+static int eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz)
{
+ fn *= sz;
if (phys_addr < 1024)
return phys_addr + (31 << 10);
+ if (phys_addr < 1024 + fn)
+ return 31744 - fn + phys_addr - 1024;
if (phys_addr < EEPROMSIZE)
- return phys_addr - 1024;
+ return phys_addr - 1024 - fn;
return -EINVAL;
}
/*
* The next two routines implement eeprom read/write from physical addresses.
- * The physical->virtual translation is correct only for PF0.
*/
static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v)
{
- int vaddr = eeprom_ptov(phys_addr);
+ int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE);
if (vaddr >= 0)
vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v);
@@ -1700,7 +1734,7 @@ static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v)
static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v)
{
- int vaddr = eeprom_ptov(phys_addr);
+ int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE);
if (vaddr >= 0)
vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v);
@@ -1743,6 +1777,14 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
aligned_offset = eeprom->offset & ~3;
aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3;
+ if (adapter->fn > 0) {
+ u32 start = 1024 + adapter->fn * EEPROMPFSIZE;
+
+ if (aligned_offset < start ||
+ aligned_offset + aligned_len > start + EEPROMPFSIZE)
+ return -EPERM;
+ }
+
if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) {
/*
* RMW possibly needed for first or last words.
@@ -2165,8 +2207,8 @@ static void mk_tid_release(struct sk_buff *skb, unsigned int chan,
* Queue a TID release request and if necessary schedule a work queue to
* process it.
*/
-void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
- unsigned int tid)
+static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
+ unsigned int tid)
{
void **p = &t->tid_tab[tid];
struct adapter *adap = container_of(t, struct adapter, tids);
@@ -2181,7 +2223,6 @@ void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
}
spin_unlock_bh(&adap->tid_release_lock);
}
-EXPORT_SYMBOL(cxgb4_queue_tid_release);
/*
* Process the list of pending TID release requests.
@@ -2305,7 +2346,7 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
req->peer_port = htons(0);
req->local_ip = sip;
req->peer_ip = htonl(0);
- chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan;
+ chan = rxq_to_chan(&adap->sge, queue);
req->opt0 = cpu_to_be64(TX_CHAN(chan));
req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
@@ -2314,48 +2355,6 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
EXPORT_SYMBOL(cxgb4_create_server);
/**
- * cxgb4_create_server6 - create an IPv6 server
- * @dev: the device
- * @stid: the server TID
- * @sip: local IPv6 address to bind server to
- * @sport: the server's TCP port
- * @queue: queue to direct messages from this server to
- *
- * Create an IPv6 server for the given port and address.
- * Returns <0 on error and one of the %NET_XMIT_* values on success.
- */
-int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
- const struct in6_addr *sip, __be16 sport,
- unsigned int queue)
-{
- unsigned int chan;
- struct sk_buff *skb;
- struct adapter *adap;
- struct cpl_pass_open_req6 *req;
-
- skb = alloc_skb(sizeof(*req), GFP_KERNEL);
- if (!skb)
- return -ENOMEM;
-
- adap = netdev2adap(dev);
- req = (struct cpl_pass_open_req6 *)__skb_put(skb, sizeof(*req));
- INIT_TP_WR(req, 0);
- OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ6, stid));
- req->local_port = sport;
- req->peer_port = htons(0);
- req->local_ip_hi = *(__be64 *)(sip->s6_addr);
- req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8);
- req->peer_ip_hi = cpu_to_be64(0);
- req->peer_ip_lo = cpu_to_be64(0);
- chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan;
- req->opt0 = cpu_to_be64(TX_CHAN(chan));
- req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
- SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
- return t4_mgmt_tx(adap, skb);
-}
-EXPORT_SYMBOL(cxgb4_create_server6);
-
-/**
* cxgb4_best_mtu - find the entry in the MTU table closest to an MTU
* @mtus: the HW MTU table
* @mtu: the target MTU
@@ -2414,25 +2413,6 @@ unsigned int cxgb4_port_idx(const struct net_device *dev)
}
EXPORT_SYMBOL(cxgb4_port_idx);
-/**
- * cxgb4_netdev_by_hwid - return the net device of a HW port
- * @pdev: identifies the adapter
- * @id: the HW port id
- *
- * Return the net device associated with the interface with the given HW
- * id.
- */
-struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id)
-{
- const struct adapter *adap = pci_get_drvdata(pdev);
-
- if (!adap || id >= NCHAN)
- return NULL;
- id = adap->chan_map[id];
- return id < MAX_NPORTS ? adap->port[id] : NULL;
-}
-EXPORT_SYMBOL(cxgb4_netdev_by_hwid);
-
void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
struct tp_tcp_stats *v6)
{
@@ -2722,7 +2702,10 @@ static int cxgb_open(struct net_device *dev)
return err;
}
- dev->real_num_tx_queues = pi->nqsets;
+ netif_set_real_num_tx_queues(dev, pi->nqsets);
+ err = netif_set_real_num_rx_queues(dev, pi->nqsets);
+ if (err)
+ return err;
err = link_start(dev);
if (!err)
netif_tx_start_all_queues(dev);
@@ -3062,12 +3045,16 @@ static int adap_init0(struct adapter *adap)
params[2] = FW_PARAM_PFVF(L2T_END);
params[3] = FW_PARAM_PFVF(FILTER_START);
params[4] = FW_PARAM_PFVF(FILTER_END);
- ret = t4_query_params(adap, adap->fn, adap->fn, 0, 5, params, val);
+ params[5] = FW_PARAM_PFVF(IQFLINT_START);
+ params[6] = FW_PARAM_PFVF(EQ_START);
+ ret = t4_query_params(adap, adap->fn, adap->fn, 0, 7, params, val);
if (ret < 0)
goto bye;
port_vec = val[0];
adap->tids.ftid_base = val[3];
adap->tids.nftids = val[4] - val[3] + 1;
+ adap->sge.ingr_start = val[5];
+ adap->sge.egr_start = val[6];
if (c.ofldcaps) {
/* query offload-related parameters */
@@ -3815,7 +3802,7 @@ static void __devexit remove_one(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
- } else if (PCI_FUNC(pdev->devfn) > 0)
+ } else
pci_release_regions(pdev);
}
diff --git a/drivers/net/cxgb4/cxgb4_uld.h b/drivers/net/cxgb4/cxgb4_uld.h
index 85d74e751ce0..1b48c0170145 100644
--- a/drivers/net/cxgb4/cxgb4_uld.h
+++ b/drivers/net/cxgb4/cxgb4_uld.h
@@ -139,16 +139,11 @@ int cxgb4_alloc_stid(struct tid_info *t, int family, void *data);
void cxgb4_free_atid(struct tid_info *t, unsigned int atid);
void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family);
void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid);
-void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
- unsigned int tid);
struct in6_addr;
int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
__be32 sip, __be16 sport, unsigned int queue);
-int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
- const struct in6_addr *sip, __be16 sport,
- unsigned int queue);
static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
{
@@ -233,7 +228,6 @@ int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
unsigned int cxgb4_port_chan(const struct net_device *dev);
unsigned int cxgb4_port_viid(const struct net_device *dev);
unsigned int cxgb4_port_idx(const struct net_device *dev);
-struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id);
unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu,
unsigned int *idx);
void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
diff --git a/drivers/net/cxgb4/l2t.c b/drivers/net/cxgb4/l2t.c
index e8f0f55e9d08..a2d323c473f8 100644
--- a/drivers/net/cxgb4/l2t.c
+++ b/drivers/net/cxgb4/l2t.c
@@ -481,40 +481,6 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
handle_failed_resolution(adap, arpq);
}
-/*
- * Allocate an L2T entry for use by a switching rule. Such entries need to be
- * explicitly freed and while busy they are not on any hash chain, so normal
- * address resolution updates do not see them.
- */
-struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d)
-{
- struct l2t_entry *e;
-
- write_lock_bh(&d->lock);
- e = alloc_l2e(d);
- if (e) {
- spin_lock(&e->lock); /* avoid race with t4_l2t_free */
- e->state = L2T_STATE_SWITCHING;
- atomic_set(&e->refcnt, 1);
- spin_unlock(&e->lock);
- }
- write_unlock_bh(&d->lock);
- return e;
-}
-
-/*
- * Sets/updates the contents of a switching L2T entry that has been allocated
- * with an earlier call to @t4_l2t_alloc_switching.
- */
-int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan,
- u8 port, u8 *eth_addr)
-{
- e->vlan = vlan;
- e->lport = port;
- memcpy(e->dmac, eth_addr, ETH_ALEN);
- return write_l2e(adap, e, 0);
-}
-
struct l2t_data *t4_init_l2t(void)
{
int i;
diff --git a/drivers/net/cxgb4/l2t.h b/drivers/net/cxgb4/l2t.h
index 643f27ed3cf4..7bd8f42378ff 100644
--- a/drivers/net/cxgb4/l2t.h
+++ b/drivers/net/cxgb4/l2t.h
@@ -100,9 +100,6 @@ struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
unsigned int priority);
void t4_l2t_update(struct adapter *adap, struct neighbour *neigh);
-struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d);
-int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan,
- u8 port, u8 *eth_addr);
struct l2t_data *t4_init_l2t(void);
void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl);
diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c
index bf38cfc57565..9967f3debce7 100644
--- a/drivers/net/cxgb4/sge.c
+++ b/drivers/net/cxgb4/sge.c
@@ -557,7 +557,8 @@ out: cred = q->avail - cred;
if (unlikely(fl_starving(q))) {
smp_wmb();
- set_bit(q->cntxt_id, adap->sge.starving_fl);
+ set_bit(q->cntxt_id - adap->sge.egr_start,
+ adap->sge.starving_fl);
}
return cred;
@@ -974,7 +975,7 @@ out_free: dev_kfree_skb(skb);
}
cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) |
- TXPKT_INTF(pi->tx_chan) | TXPKT_PF(0));
+ TXPKT_INTF(pi->tx_chan) | TXPKT_PF(adap->fn));
cpl->pack = htons(0);
cpl->len = htons(skb->len);
cpl->ctrl1 = cpu_to_be64(cntrl);
@@ -1213,7 +1214,8 @@ static void txq_stop_maperr(struct sge_ofld_txq *q)
{
q->mapping_err++;
q->q.stops++;
- set_bit(q->q.cntxt_id, q->adap->sge.txq_maperr);
+ set_bit(q->q.cntxt_id - q->adap->sge.egr_start,
+ q->adap->sge.txq_maperr);
}
/**
@@ -1603,7 +1605,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
rxq->stats.rx_cso++;
}
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (unlikely(pkt->vlan_ex)) {
struct vlan_group *grp = pi->vlan_grp;
@@ -1835,6 +1837,7 @@ static unsigned int process_intrq(struct adapter *adap)
if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) {
unsigned int qid = ntohl(rc->pldbuflen_qid);
+ qid -= adap->sge.ingr_start;
napi_schedule(&adap->sge.ingr_map[qid]->napi);
}
@@ -2050,14 +2053,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
/* set offset to -1 to distinguish ingress queues without FL */
iq->offset = fl ? 0 : -1;
- adap->sge.ingr_map[iq->cntxt_id] = iq;
+ adap->sge.ingr_map[iq->cntxt_id - adap->sge.ingr_start] = iq;
if (fl) {
fl->cntxt_id = ntohs(c.fl0id);
fl->avail = fl->pend_cred = 0;
fl->pidx = fl->cidx = 0;
fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0;
- adap->sge.egr_map[fl->cntxt_id] = fl;
+ adap->sge.egr_map[fl->cntxt_id - adap->sge.egr_start] = fl;
refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL);
}
return 0;
@@ -2087,7 +2090,7 @@ static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id)
q->stops = q->restarts = 0;
q->stat = (void *)&q->desc[q->size];
q->cntxt_id = id;
- adap->sge.egr_map[id] = q;
+ adap->sge.egr_map[id - adap->sge.egr_start] = q;
}
int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
@@ -2259,7 +2262,7 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
{
unsigned int fl_id = fl ? fl->cntxt_id : 0xffff;
- adap->sge.ingr_map[rq->cntxt_id] = NULL;
+ adap->sge.ingr_map[rq->cntxt_id - adap->sge.ingr_start] = NULL;
t4_iq_free(adap, adap->fn, adap->fn, 0, FW_IQ_TYPE_FL_INT_CAP,
rq->cntxt_id, fl_id, 0xffff);
dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len,
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
index 9e1a4b49b47a..bb813d94aea8 100644
--- a/drivers/net/cxgb4/t4_hw.c
+++ b/drivers/net/cxgb4/t4_hw.c
@@ -120,30 +120,6 @@ static void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
}
}
-#if 0
-/**
- * t4_write_indirect - write indirectly addressed registers
- * @adap: the adapter
- * @addr_reg: register holding the indirect addresses
- * @data_reg: register holding the value for the indirect registers
- * @vals: values to write
- * @nregs: how many indirect registers to write
- * @start_idx: address of first indirect register to write
- *
- * Writes a sequential block of registers that are accessed indirectly
- * through an address/data register pair.
- */
-static void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
- unsigned int data_reg, const u32 *vals,
- unsigned int nregs, unsigned int start_idx)
-{
- while (nregs--) {
- t4_write_reg(adap, addr_reg, start_idx++);
- t4_write_reg(adap, data_reg, *vals++);
- }
-}
-#endif
-
/*
* Get the reply to a mailbox command and store it in @rpl in big-endian order.
*/
@@ -1560,44 +1536,6 @@ void t4_intr_disable(struct adapter *adapter)
}
/**
- * t4_intr_clear - clear all interrupts
- * @adapter: the adapter whose interrupts should be cleared
- *
- * Clears all interrupts. The caller must be a PCI function managing
- * global interrupts.
- */
-void t4_intr_clear(struct adapter *adapter)
-{
- static const unsigned int cause_reg[] = {
- SGE_INT_CAUSE1, SGE_INT_CAUSE2, SGE_INT_CAUSE3,
- PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
- PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
- PCIE_NONFAT_ERR, PCIE_INT_CAUSE,
- MC_INT_CAUSE,
- MA_INT_WRAP_STATUS, MA_PARITY_ERROR_STATUS, MA_INT_CAUSE,
- EDC_INT_CAUSE, EDC_REG(EDC_INT_CAUSE, 1),
- CIM_HOST_INT_CAUSE, CIM_HOST_UPACC_INT_CAUSE,
- MYPF_REG(CIM_PF_HOST_INT_CAUSE),
- TP_INT_CAUSE,
- ULP_RX_INT_CAUSE, ULP_TX_INT_CAUSE,
- PM_RX_INT_CAUSE, PM_TX_INT_CAUSE,
- MPS_RX_PERR_INT_CAUSE,
- CPL_INTR_CAUSE,
- MYPF_REG(PL_PF_INT_CAUSE),
- PL_PL_INT_CAUSE,
- LE_DB_INT_CAUSE,
- };
-
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(cause_reg); ++i)
- t4_write_reg(adapter, cause_reg[i], 0xffffffff);
-
- t4_write_reg(adapter, PL_INT_CAUSE, GLBL_INTR_MASK);
- (void) t4_read_reg(adapter, PL_INT_CAUSE); /* flush */
-}
-
-/**
* hash_mac_addr - return the hash value of a MAC address
* @addr: the 48-bit Ethernet MAC address
*
@@ -1709,36 +1647,6 @@ int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
}
-/* Read an RSS table row */
-static int rd_rss_row(struct adapter *adap, int row, u32 *val)
-{
- t4_write_reg(adap, TP_RSS_LKP_TABLE, 0xfff00000 | row);
- return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE, LKPTBLROWVLD, 1,
- 5, 0, val);
-}
-
-/**
- * t4_read_rss - read the contents of the RSS mapping table
- * @adapter: the adapter
- * @map: holds the contents of the RSS mapping table
- *
- * Reads the contents of the RSS hash->queue mapping table.
- */
-int t4_read_rss(struct adapter *adapter, u16 *map)
-{
- u32 val;
- int i, ret;
-
- for (i = 0; i < RSS_NENTRIES / 2; ++i) {
- ret = rd_rss_row(adapter, i, &val);
- if (ret)
- return ret;
- *map++ = LKPTBLQUEUE0_GET(val);
- *map++ = LKPTBLQUEUE1_GET(val);
- }
- return 0;
-}
-
/**
* t4_tp_get_tcp_stats - read TP's TCP MIB counters
* @adap: the adapter
@@ -1779,29 +1687,6 @@ void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
}
/**
- * t4_tp_get_err_stats - read TP's error MIB counters
- * @adap: the adapter
- * @st: holds the counter values
- *
- * Returns the values of TP's error counters.
- */
-void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st)
-{
- t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->macInErrs,
- 12, TP_MIB_MAC_IN_ERR_0);
- t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlCongDrops,
- 8, TP_MIB_TNL_CNG_DROP_0);
- t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlTxDrops,
- 4, TP_MIB_TNL_DROP_0);
- t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->ofldVlanDrops,
- 4, TP_MIB_OFD_VLN_DROP_0);
- t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tcp6InErrs,
- 4, TP_MIB_TCP_V6IN_ERR_0);
- t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, &st->ofldNoNeigh,
- 2, TP_MIB_OFD_ARP_DROP);
-}
-
-/**
* t4_read_mtu_tbl - returns the values in the HW path MTU table
* @adap: the adapter
* @mtus: where to store the MTU values
@@ -1916,122 +1801,6 @@ void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
}
/**
- * t4_set_trace_filter - configure one of the tracing filters
- * @adap: the adapter
- * @tp: the desired trace filter parameters
- * @idx: which filter to configure
- * @enable: whether to enable or disable the filter
- *
- * Configures one of the tracing filters available in HW. If @enable is
- * %0 @tp is not examined and may be %NULL.
- */
-int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp,
- int idx, int enable)
-{
- int i, ofst = idx * 4;
- u32 data_reg, mask_reg, cfg;
- u32 multitrc = TRCMULTIFILTER;
-
- if (!enable) {
- t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0);
- goto out;
- }
-
- if (tp->port > 11 || tp->invert > 1 || tp->skip_len > 0x1f ||
- tp->skip_ofst > 0x1f || tp->min_len > 0x1ff ||
- tp->snap_len > 9600 || (idx && tp->snap_len > 256))
- return -EINVAL;
-
- if (tp->snap_len > 256) { /* must be tracer 0 */
- if ((t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 4) |
- t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 8) |
- t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 12)) & TFEN)
- return -EINVAL; /* other tracers are enabled */
- multitrc = 0;
- } else if (idx) {
- i = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B);
- if (TFCAPTUREMAX_GET(i) > 256 &&
- (t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A) & TFEN))
- return -EINVAL;
- }
-
- /* stop the tracer we'll be changing */
- t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0);
-
- /* disable tracing globally if running in the wrong single/multi mode */
- cfg = t4_read_reg(adap, MPS_TRC_CFG);
- if ((cfg & TRCEN) && multitrc != (cfg & TRCMULTIFILTER)) {
- t4_write_reg(adap, MPS_TRC_CFG, cfg ^ TRCEN);
- t4_read_reg(adap, MPS_TRC_CFG); /* flush */
- msleep(1);
- if (!(t4_read_reg(adap, MPS_TRC_CFG) & TRCFIFOEMPTY))
- return -ETIMEDOUT;
- }
- /*
- * At this point either the tracing is enabled and in the right mode or
- * disabled.
- */
-
- idx *= (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH);
- data_reg = MPS_TRC_FILTER0_MATCH + idx;
- mask_reg = MPS_TRC_FILTER0_DONT_CARE + idx;
-
- for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
- t4_write_reg(adap, data_reg, tp->data[i]);
- t4_write_reg(adap, mask_reg, ~tp->mask[i]);
- }
- t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst,
- TFCAPTUREMAX(tp->snap_len) |
- TFMINPKTSIZE(tp->min_len));
- t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst,
- TFOFFSET(tp->skip_ofst) | TFLENGTH(tp->skip_len) |
- TFPORT(tp->port) | TFEN |
- (tp->invert ? TFINVERTMATCH : 0));
-
- cfg &= ~TRCMULTIFILTER;
- t4_write_reg(adap, MPS_TRC_CFG, cfg | TRCEN | multitrc);
-out: t4_read_reg(adap, MPS_TRC_CFG); /* flush */
- return 0;
-}
-
-/**
- * t4_get_trace_filter - query one of the tracing filters
- * @adap: the adapter
- * @tp: the current trace filter parameters
- * @idx: which trace filter to query
- * @enabled: non-zero if the filter is enabled
- *
- * Returns the current settings of one of the HW tracing filters.
- */
-void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx,
- int *enabled)
-{
- u32 ctla, ctlb;
- int i, ofst = idx * 4;
- u32 data_reg, mask_reg;
-
- ctla = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst);
- ctlb = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst);
-
- *enabled = !!(ctla & TFEN);
- tp->snap_len = TFCAPTUREMAX_GET(ctlb);
- tp->min_len = TFMINPKTSIZE_GET(ctlb);
- tp->skip_ofst = TFOFFSET_GET(ctla);
- tp->skip_len = TFLENGTH_GET(ctla);
- tp->invert = !!(ctla & TFINVERTMATCH);
- tp->port = TFPORT_GET(ctla);
-
- ofst = (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH) * idx;
- data_reg = MPS_TRC_FILTER0_MATCH + ofst;
- mask_reg = MPS_TRC_FILTER0_DONT_CARE + ofst;
-
- for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
- tp->mask[i] = ~t4_read_reg(adap, mask_reg);
- tp->data[i] = t4_read_reg(adap, data_reg) & tp->mask[i];
- }
-}
-
-/**
* get_mps_bg_map - return the buffer groups associated with a port
* @adap: the adapter
* @idx: the port index
@@ -2133,52 +1902,6 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
}
/**
- * t4_get_lb_stats - collect loopback port statistics
- * @adap: the adapter
- * @idx: the loopback port index
- * @p: the stats structure to fill
- *
- * Return HW statistics for the given loopback port.
- */
-void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p)
-{
- u32 bgmap = get_mps_bg_map(adap, idx);
-
-#define GET_STAT(name) \
- t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L))
-#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
-
- p->octets = GET_STAT(BYTES);
- p->frames = GET_STAT(FRAMES);
- p->bcast_frames = GET_STAT(BCAST);
- p->mcast_frames = GET_STAT(MCAST);
- p->ucast_frames = GET_STAT(UCAST);
- p->error_frames = GET_STAT(ERROR);
-
- p->frames_64 = GET_STAT(64B);
- p->frames_65_127 = GET_STAT(65B_127B);
- p->frames_128_255 = GET_STAT(128B_255B);
- p->frames_256_511 = GET_STAT(256B_511B);
- p->frames_512_1023 = GET_STAT(512B_1023B);
- p->frames_1024_1518 = GET_STAT(1024B_1518B);
- p->frames_1519_max = GET_STAT(1519B_MAX);
- p->drop = t4_read_reg(adap, PORT_REG(idx,
- MPS_PORT_STAT_LB_PORT_DROP_FRAMES));
-
- p->ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_DROP_FRAME) : 0;
- p->ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_DROP_FRAME) : 0;
- p->ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_DROP_FRAME) : 0;
- p->ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_DROP_FRAME) : 0;
- p->trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_TRUNC_FRAME) : 0;
- p->trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_TRUNC_FRAME) : 0;
- p->trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_TRUNC_FRAME) : 0;
- p->trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_TRUNC_FRAME) : 0;
-
-#undef GET_STAT
-#undef GET_STAT_COM
-}
-
-/**
* t4_wol_magic_enable - enable/disable magic packet WoL
* @adap: the adapter
* @port: the physical port index
@@ -2584,30 +2307,6 @@ int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
}
/**
- * t4_free_vi - free a virtual interface
- * @adap: the adapter
- * @mbox: mailbox to use for the FW command
- * @pf: the PF owning the VI
- * @vf: the VF owning the VI
- * @viid: virtual interface identifiler
- *
- * Free a previously allocated virtual interface.
- */
-int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
- unsigned int vf, unsigned int viid)
-{
- struct fw_vi_cmd c;
-
- memset(&c, 0, sizeof(c));
- c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST |
- FW_CMD_EXEC | FW_VI_CMD_PFN(pf) |
- FW_VI_CMD_VFN(vf));
- c.alloc_to_len16 = htonl(FW_VI_CMD_FREE | FW_LEN16(c));
- c.type_viid = htons(FW_VI_CMD_VIID(viid));
- return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
-}
-
-/**
* t4_set_rxmode - set Rx properties of a virtual interface
* @adap: the adapter
* @mbox: mailbox to use for the FW command
@@ -2833,37 +2532,6 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
}
/**
- * t4_iq_start_stop - enable/disable an ingress queue and its FLs
- * @adap: the adapter
- * @mbox: mailbox to use for the FW command
- * @start: %true to enable the queues, %false to disable them
- * @pf: the PF owning the queues
- * @vf: the VF owning the queues
- * @iqid: ingress queue id
- * @fl0id: FL0 queue id or 0xffff if no attached FL0
- * @fl1id: FL1 queue id or 0xffff if no attached FL1
- *
- * Starts or stops an ingress queue and its associated FLs, if any.
- */
-int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start,
- unsigned int pf, unsigned int vf, unsigned int iqid,
- unsigned int fl0id, unsigned int fl1id)
-{
- struct fw_iq_cmd c;
-
- memset(&c, 0, sizeof(c));
- c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST |
- FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) |
- FW_IQ_CMD_VFN(vf));
- c.alloc_to_len16 = htonl(FW_IQ_CMD_IQSTART(start) |
- FW_IQ_CMD_IQSTOP(!start) | FW_LEN16(c));
- c.iqid = htons(iqid);
- c.fl0id = htons(fl0id);
- c.fl1id = htons(fl1id);
- return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
-}
-
-/**
* t4_iq_free - free an ingress queue and its FLs
* @adap: the adapter
* @mbox: mailbox to use for the FW command
diff --git a/drivers/net/cxgb4/t4_hw.h b/drivers/net/cxgb4/t4_hw.h
index 10a055565776..c26b455f37de 100644
--- a/drivers/net/cxgb4/t4_hw.h
+++ b/drivers/net/cxgb4/t4_hw.h
@@ -42,6 +42,7 @@ enum {
MAX_MTU = 9600, /* max MAC MTU, excluding header + FCS */
EEPROMSIZE = 17408, /* Serial EEPROM physical size */
EEPROMVSIZE = 32768, /* Serial EEPROM virtual address space size */
+ EEPROMPFSIZE = 1024, /* EEPROM writable area size for PFn, n>0 */
RSS_NENTRIES = 2048, /* # of entries in RSS mapping table */
TCB_SIZE = 128, /* TCB size */
NMTUS = 16, /* size of MTU table */
diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h
index 0969f2fbc1b0..940584a8a640 100644
--- a/drivers/net/cxgb4/t4fw_api.h
+++ b/drivers/net/cxgb4/t4fw_api.h
@@ -487,6 +487,11 @@ enum fw_params_param_pfvf {
FW_PARAMS_PARAM_PFVF_CPMASK = 0x25,
FW_PARAMS_PARAM_PFVF_OCQ_START = 0x26,
FW_PARAMS_PARAM_PFVF_OCQ_END = 0x27,
+ FW_PARAMS_PARAM_PFVF_CONM_MAP = 0x28,
+ FW_PARAMS_PARAM_PFVF_IQFLINT_START = 0x29,
+ FW_PARAMS_PARAM_PFVF_IQFLINT_END = 0x2A,
+ FW_PARAMS_PARAM_PFVF_EQ_START = 0x2B,
+ FW_PARAMS_PARAM_PFVF_EQ_END = 0x2C,
};
/*
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index 7b6d07f50c71..555ecc5a2e93 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -748,7 +748,10 @@ static int cxgb4vf_open(struct net_device *dev)
/*
* Note that this interface is up and start everything up ...
*/
- dev->real_num_tx_queues = pi->nqsets;
+ netif_set_real_num_tx_queues(dev, pi->nqsets);
+ err = netif_set_real_num_rx_queues(dev, pi->nqsets);
+ if (err)
+ return err;
set_bit(pi->port_id, &adapter->open_device_map);
link_start(dev);
netif_tx_start_all_queues(dev);
diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c
index eb5a1c9cb2d3..f10864ddafbe 100644
--- a/drivers/net/cxgb4vf/sge.c
+++ b/drivers/net/cxgb4vf/sge.c
@@ -1520,7 +1520,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
__skb_pull(skb, PKTSHIFT);
skb->protocol = eth_type_trans(skb, rspq->netdev);
skb_record_rx_queue(skb, rspq->idx);
- skb->dev->last_rx = jiffies; /* XXX removed 2.6.29 */
pi = netdev_priv(skb->dev);
rxq->stats.pkts++;
@@ -1535,7 +1534,7 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
}
rxq->stats.rx_cso++;
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (unlikely(pkt->vlan_ex)) {
struct vlan_group *grp = pi->vlan_grp;
diff --git a/drivers/net/cxgb4vf/t4vf_common.h b/drivers/net/cxgb4vf/t4vf_common.h
index 5c7bde7f9bae..873cb7d86c57 100644
--- a/drivers/net/cxgb4vf/t4vf_common.h
+++ b/drivers/net/cxgb4vf/t4vf_common.h
@@ -132,15 +132,15 @@ struct rss_params {
unsigned int mode; /* RSS mode */
union {
struct {
- int synmapen:1; /* SYN Map Enable */
- int syn4tupenipv6:1; /* enable hashing 4-tuple IPv6 SYNs */
- int syn2tupenipv6:1; /* enable hashing 2-tuple IPv6 SYNs */
- int syn4tupenipv4:1; /* enable hashing 4-tuple IPv4 SYNs */
- int syn2tupenipv4:1; /* enable hashing 2-tuple IPv4 SYNs */
- int ofdmapen:1; /* Offload Map Enable */
- int tnlmapen:1; /* Tunnel Map Enable */
- int tnlalllookup:1; /* Tunnel All Lookup */
- int hashtoeplitz:1; /* use Toeplitz hash */
+ unsigned int synmapen:1; /* SYN Map Enable */
+ unsigned int syn4tupenipv6:1; /* enable hashing 4-tuple IPv6 SYNs */
+ unsigned int syn2tupenipv6:1; /* enable hashing 2-tuple IPv6 SYNs */
+ unsigned int syn4tupenipv4:1; /* enable hashing 4-tuple IPv4 SYNs */
+ unsigned int syn2tupenipv4:1; /* enable hashing 2-tuple IPv4 SYNs */
+ unsigned int ofdmapen:1; /* Offload Map Enable */
+ unsigned int tnlmapen:1; /* Tunnel Map Enable */
+ unsigned int tnlalllookup:1; /* Tunnel All Lookup */
+ unsigned int hashtoeplitz:1; /* use Toeplitz hash */
} basicvirtual;
} u;
};
@@ -151,10 +151,10 @@ struct rss_params {
union rss_vi_config {
struct {
u16 defaultq; /* Ingress Queue ID for !tnlalllookup */
- int ip6fourtupen:1; /* hash 4-tuple IPv6 ingress packets */
- int ip6twotupen:1; /* hash 2-tuple IPv6 ingress packets */
- int ip4fourtupen:1; /* hash 4-tuple IPv4 ingress packets */
- int ip4twotupen:1; /* hash 2-tuple IPv4 ingress packets */
+ unsigned int ip6fourtupen:1; /* hash 4-tuple IPv6 ingress packets */
+ unsigned int ip6twotupen:1; /* hash 2-tuple IPv6 ingress packets */
+ unsigned int ip4fourtupen:1; /* hash 4-tuple IPv4 ingress packets */
+ unsigned int ip4twotupen:1; /* hash 2-tuple IPv4 ingress packets */
int udpen; /* hash 4-tuple UDP ingress packets */
} basicvirtual;
};
diff --git a/drivers/net/de620.c b/drivers/net/de620.c
index f3650fd096f4..1c51a7576119 100644
--- a/drivers/net/de620.c
+++ b/drivers/net/de620.c
@@ -676,7 +676,7 @@ static int de620_rx_intr(struct net_device *dev)
de620_set_register(dev, W_NPRF, next_rx_page);
pr_debug("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page);
- return (next_rx_page != curr_page); /* That was slightly tricky... */
+ return next_rx_page != curr_page; /* That was slightly tricky... */
}
/*********************************************
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index d7de376d7178..219eb5ad5c12 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -1255,7 +1255,7 @@ static int __devinit dec_lance_probe(struct device *bdev, const int type)
*/
init_timer(&lp->multicast_timer);
lp->multicast_timer.data = (unsigned long) dev;
- lp->multicast_timer.function = &lance_set_multicast_retry;
+ lp->multicast_timer.function = lance_set_multicast_retry;
ret = register_netdev(dev);
if (ret) {
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index e5667c55844e..417e14385623 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -1024,7 +1024,7 @@ static int __devinit dfx_driver_init(struct net_device *dev,
&data) != DFX_K_SUCCESS) {
printk("%s: Could not read adapter factory MAC address!\n",
print_name);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
le32 = cpu_to_le32(data);
memcpy(&bp->factory_mac_addr[0], &le32, sizeof(u32));
@@ -1033,7 +1033,7 @@ static int __devinit dfx_driver_init(struct net_device *dev,
&data) != DFX_K_SUCCESS) {
printk("%s: Could not read adapter factory MAC address!\n",
print_name);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
le32 = cpu_to_le32(data);
memcpy(&bp->factory_mac_addr[4], &le32, sizeof(u16));
@@ -1075,7 +1075,7 @@ static int __devinit dfx_driver_init(struct net_device *dev,
if (top_v == NULL) {
printk("%s: Could not allocate memory for host buffers "
"and structures!\n", print_name);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
memset(top_v, 0, alloc_size); /* zero out memory before continuing */
top_p = bp->kmalloced_dma; /* get physical address of buffer */
@@ -1145,7 +1145,7 @@ static int __devinit dfx_driver_init(struct net_device *dev,
DBG_printk("%s: Consumer block virt = %0lX, phys = %0X\n",
print_name, (long)bp->cons_block_virt, bp->cons_block_phys);
- return(DFX_K_SUCCESS);
+ return DFX_K_SUCCESS;
}
@@ -1195,7 +1195,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers)
if (dfx_hw_dma_uninit(bp, bp->reset_type) != DFX_K_SUCCESS)
{
printk("%s: Could not uninitialize/reset adapter!\n", bp->dev->name);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
/*
@@ -1229,7 +1229,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers)
NULL) != DFX_K_SUCCESS)
{
printk("%s: Could not set adapter burst size!\n", bp->dev->name);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
/*
@@ -1246,7 +1246,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers)
NULL) != DFX_K_SUCCESS)
{
printk("%s: Could not set consumer block address!\n", bp->dev->name);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
/*
@@ -1278,7 +1278,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers)
if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS)
{
printk("%s: DMA command request failed!\n", bp->dev->name);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
/* Set the initial values for eFDXEnable and MACTReq MIB objects */
@@ -1294,7 +1294,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers)
if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS)
{
printk("%s: DMA command request failed!\n", bp->dev->name);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
/* Initialize adapter CAM */
@@ -1302,7 +1302,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers)
if (dfx_ctl_update_cam(bp) != DFX_K_SUCCESS)
{
printk("%s: Adapter CAM update failed!\n", bp->dev->name);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
/* Initialize adapter filters */
@@ -1310,7 +1310,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers)
if (dfx_ctl_update_filters(bp) != DFX_K_SUCCESS)
{
printk("%s: Adapter filters update failed!\n", bp->dev->name);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
/*
@@ -1328,7 +1328,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers)
printk("%s: Receive buffer allocation failed\n", bp->dev->name);
if (get_buffers)
dfx_rcv_flush(bp);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
/* Issue START command and bring adapter to LINK_(UN)AVAILABLE state */
@@ -1339,13 +1339,13 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers)
printk("%s: Start command failed\n", bp->dev->name);
if (get_buffers)
dfx_rcv_flush(bp);
- return(DFX_K_FAILURE);
+ return DFX_K_FAILURE;
}
/* Initialization succeeded, reenable PDQ interrupts */
dfx_port_write_long(bp, PI_PDQ_K_REG_HOST_INT_ENB, PI_HOST_INT_K_ENABLE_DEF_INTS);
- return(DFX_K_SUCCESS);
+ return DFX_K_SUCCESS;
}
@@ -1434,7 +1434,7 @@ static int dfx_open(struct net_device *dev)
/* Set device structure info */
netif_start_queue(dev);
- return(0);
+ return 0;
}
@@ -1526,7 +1526,7 @@ static int dfx_close(struct net_device *dev)
free_irq(dev->irq, dev);
- return(0);
+ return 0;
}
@@ -2027,7 +2027,7 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev)
bp->cmd_req_virt->cmd_type = PI_CMD_K_SMT_MIB_GET;
if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS)
- return((struct net_device_stats *) &bp->stats);
+ return (struct net_device_stats *)&bp->stats;
/* Fill the bp->stats structure with the SMT MIB object values */
@@ -2128,7 +2128,7 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev)
bp->cmd_req_virt->cmd_type = PI_CMD_K_CNTRS_GET;
if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS)
- return((struct net_device_stats *) &bp->stats);
+ return (struct net_device_stats *)&bp->stats;
/* Fill the bp->stats structure with the FDDI counter values */
@@ -2144,7 +2144,7 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev)
bp->stats.port_lem_cts[0] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[0].ls;
bp->stats.port_lem_cts[1] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[1].ls;
- return((struct net_device_stats *) &bp->stats);
+ return (struct net_device_stats *)&bp->stats;
}
@@ -2354,7 +2354,7 @@ static int dfx_ctl_set_mac_address(struct net_device *dev, void *addr)
{
DBG_printk("%s: Adapter CAM updated with new MAC address\n", dev->name);
}
- return(0); /* always return zero */
+ return 0; /* always return zero */
}
@@ -2438,8 +2438,8 @@ static int dfx_ctl_update_cam(DFX_board_t *bp)
/* Issue command to update adapter CAM, then return */
if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS)
- return(DFX_K_FAILURE);
- return(DFX_K_SUCCESS);
+ return DFX_K_FAILURE;
+ return DFX_K_SUCCESS;
}
@@ -2504,8 +2504,8 @@ static int dfx_ctl_update_filters(DFX_board_t *bp)
/* Issue command to update adapter filters, then return */
if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS)
- return(DFX_K_FAILURE);
- return(DFX_K_SUCCESS);
+ return DFX_K_FAILURE;
+ return DFX_K_SUCCESS;
}
@@ -2561,7 +2561,7 @@ static int dfx_hw_dma_cmd_req(DFX_board_t *bp)
(status == PI_STATE_K_HALTED) ||
(status == PI_STATE_K_DMA_UNAVAIL) ||
(status == PI_STATE_K_UPGRADE))
- return(DFX_K_OUTSTATE);
+ return DFX_K_OUTSTATE;
/* Put response buffer on the command response queue */
@@ -2599,7 +2599,7 @@ static int dfx_hw_dma_cmd_req(DFX_board_t *bp)
udelay(100); /* wait for 100 microseconds */
}
if (timeout_cnt == 0)
- return(DFX_K_HW_TIMEOUT);
+ return DFX_K_HW_TIMEOUT;
/* Bump (and wrap) the completion index and write out to register */
@@ -2619,14 +2619,14 @@ static int dfx_hw_dma_cmd_req(DFX_board_t *bp)
udelay(100); /* wait for 100 microseconds */
}
if (timeout_cnt == 0)
- return(DFX_K_HW_TIMEOUT);
+ return DFX_K_HW_TIMEOUT;
/* Bump (and wrap) the completion index and write out to register */
bp->cmd_rsp_reg.index.comp += 1;
bp->cmd_rsp_reg.index.comp &= PI_CMD_RSP_K_NUM_ENTRIES-1;
dfx_port_write_long(bp, PI_PDQ_K_REG_CMD_RSP_PROD, bp->cmd_rsp_reg.lword);
- return(DFX_K_SUCCESS);
+ return DFX_K_SUCCESS;
}
@@ -2700,7 +2700,7 @@ static int dfx_hw_port_ctrl_req(
udelay(100); /* wait for 100 microseconds */
}
if (timeout_cnt == 0)
- return(DFX_K_HW_TIMEOUT);
+ return DFX_K_HW_TIMEOUT;
/*
* If the address of host_data is non-zero, assume caller has supplied a
@@ -2710,7 +2710,7 @@ static int dfx_hw_port_ctrl_req(
if (host_data != NULL)
dfx_port_read_long(bp, PI_PDQ_K_REG_HOST_DATA, host_data);
- return(DFX_K_SUCCESS);
+ return DFX_K_SUCCESS;
}
@@ -2800,7 +2800,7 @@ static int dfx_hw_adap_state_rd(DFX_board_t *bp)
PI_UINT32 port_status; /* Port Status register value */
dfx_port_read_long(bp, PI_PDQ_K_REG_PORT_STATUS, &port_status);
- return((port_status & PI_PSTATUS_M_STATE) >> PI_PSTATUS_V_STATE);
+ return (port_status & PI_PSTATUS_M_STATE) >> PI_PSTATUS_V_STATE;
}
@@ -2852,8 +2852,8 @@ static int dfx_hw_dma_uninit(DFX_board_t *bp, PI_UINT32 type)
udelay(100); /* wait for 100 microseconds */
}
if (timeout_cnt == 0)
- return(DFX_K_HW_TIMEOUT);
- return(DFX_K_SUCCESS);
+ return DFX_K_HW_TIMEOUT;
+ return DFX_K_SUCCESS;
}
/*
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index a2f238d20caa..e1a8216ff692 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -465,7 +465,7 @@ rio_open (struct net_device *dev)
init_timer (&np->timer);
np->timer.expires = jiffies + 1*HZ;
np->timer.data = (unsigned long) dev;
- np->timer.function = &rio_timer;
+ np->timer.function = rio_timer;
add_timer (&np->timer);
/* Start Tx/Rx */
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 4fd6b2b4554b..9f6aeefa06bf 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1056,7 +1056,7 @@ dm9000_rx(struct net_device *dev)
if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0)
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
netif_rx(skb);
dev->stats.rx_packets++;
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c
index 7c075756611a..9d8a20b72fa9 100644
--- a/drivers/net/dnet.c
+++ b/drivers/net/dnet.c
@@ -27,7 +27,7 @@
#undef DEBUG
/* function for reading internal MAC register */
-u16 dnet_readw_mac(struct dnet *bp, u16 reg)
+static u16 dnet_readw_mac(struct dnet *bp, u16 reg)
{
u16 data_read;
@@ -46,7 +46,7 @@ u16 dnet_readw_mac(struct dnet *bp, u16 reg)
}
/* function for writing internal MAC register */
-void dnet_writew_mac(struct dnet *bp, u16 reg, u16 val)
+static void dnet_writew_mac(struct dnet *bp, u16 reg, u16 val)
{
/* load data to write */
dnet_writel(bp, val, MACREG_DATA);
@@ -63,11 +63,11 @@ static void __dnet_set_hwaddr(struct dnet *bp)
{
u16 tmp;
- tmp = cpu_to_be16(*((u16 *) bp->dev->dev_addr));
+ tmp = be16_to_cpup((__be16 *)bp->dev->dev_addr);
dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG, tmp);
- tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 2)));
+ tmp = be16_to_cpup((__be16 *)(bp->dev->dev_addr + 2));
dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG, tmp);
- tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 4)));
+ tmp = be16_to_cpup((__be16 *)(bp->dev->dev_addr + 4));
dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG, tmp);
}
@@ -89,11 +89,11 @@ static void __devinit dnet_get_hwaddr(struct dnet *bp)
* Mac_addr[15:0]).
*/
tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG);
- *((u16 *) addr) = be16_to_cpu(tmp);
+ *((__be16 *)addr) = cpu_to_be16(tmp);
tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG);
- *((u16 *) (addr + 2)) = be16_to_cpu(tmp);
+ *((__be16 *)(addr + 2)) = cpu_to_be16(tmp);
tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG);
- *((u16 *) (addr + 4)) = be16_to_cpu(tmp);
+ *((__be16 *)(addr + 4)) = cpu_to_be16(tmp);
if (is_valid_ether_addr(addr))
memcpy(bp->dev->dev_addr, addr, sizeof(addr));
@@ -361,7 +361,7 @@ err_out:
}
/* For Neptune board: LINK1000 as Link LED and TX as activity LED */
-int dnet_phy_marvell_fixup(struct phy_device *phydev)
+static int dnet_phy_marvell_fixup(struct phy_device *phydev)
{
return phy_write(phydev, 0x18, 0x4148);
}
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 37dcfdc63456..ff2d29b17858 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -36,6 +36,7 @@
#include <linux/moduleparam.h>
#include <linux/rtnetlink.h>
#include <net/rtnetlink.h>
+#include <linux/u64_stats_sync.h>
static int numdummies = 1;
@@ -55,21 +56,69 @@ static void set_multicast_list(struct net_device *dev)
{
}
+struct pcpu_dstats {
+ u64 tx_packets;
+ u64 tx_bytes;
+ struct u64_stats_sync syncp;
+};
+
+static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev,
+ struct rtnl_link_stats64 *stats)
+{
+ int i;
+
+ for_each_possible_cpu(i) {
+ const struct pcpu_dstats *dstats;
+ u64 tbytes, tpackets;
+ unsigned int start;
+
+ dstats = per_cpu_ptr(dev->dstats, i);
+ do {
+ start = u64_stats_fetch_begin(&dstats->syncp);
+ tbytes = dstats->tx_bytes;
+ tpackets = dstats->tx_packets;
+ } while (u64_stats_fetch_retry(&dstats->syncp, start));
+ stats->tx_bytes += tbytes;
+ stats->tx_packets += tpackets;
+ }
+ return stats;
+}
static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev)
{
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
+ struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
+
+ u64_stats_update_begin(&dstats->syncp);
+ dstats->tx_packets++;
+ dstats->tx_bytes += skb->len;
+ u64_stats_update_end(&dstats->syncp);
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
+static int dummy_dev_init(struct net_device *dev)
+{
+ dev->dstats = alloc_percpu(struct pcpu_dstats);
+ if (!dev->dstats)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void dummy_dev_free(struct net_device *dev)
+{
+ free_percpu(dev->dstats);
+ free_netdev(dev);
+}
+
static const struct net_device_ops dummy_netdev_ops = {
+ .ndo_init = dummy_dev_init,
.ndo_start_xmit = dummy_xmit,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_multicast_list = set_multicast_list,
.ndo_set_mac_address = dummy_set_address,
+ .ndo_get_stats64 = dummy_get_stats64,
};
static void dummy_setup(struct net_device *dev)
@@ -78,14 +127,17 @@ static void dummy_setup(struct net_device *dev)
/* Initialize the device structure. */
dev->netdev_ops = &dummy_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = dummy_dev_free;
/* Fill in device structure with ethernet-generic values. */
dev->tx_queue_len = 0;
dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST;
+ dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO;
+ dev->features |= NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX;
random_ether_addr(dev->dev_addr);
}
+
static int dummy_validate(struct nlattr *tb[], struct nlattr *data[])
{
if (tb[IFLA_ADDRESS]) {
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 8e2eab4e7c75..b0aa9e68990a 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2215,10 +2215,10 @@ static int e100_change_mtu(struct net_device *netdev, int new_mtu)
static int e100_asf(struct nic *nic)
{
/* ASF can be enabled from eeprom */
- return((nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) &&
+ return (nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) &&
(nic->eeprom[eeprom_config_asf] & eeprom_asf) &&
!(nic->eeprom[eeprom_config_asf] & eeprom_gcl) &&
- ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE));
+ ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE);
}
static int e100_up(struct nic *nic)
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 99288b95aead..a881dd0093bd 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -310,6 +310,9 @@ struct e1000_adapter {
int need_ioport;
bool discarding;
+
+ struct work_struct fifo_stall_task;
+ struct work_struct phy_info_task;
};
enum e1000_state_t {
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 5cc39ed289c6..a117f2a0252e 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -123,8 +123,10 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring);
static void e1000_set_rx_mode(struct net_device *netdev);
static void e1000_update_phy_info(unsigned long data);
+static void e1000_update_phy_info_task(struct work_struct *work);
static void e1000_watchdog(unsigned long data);
static void e1000_82547_tx_fifo_stall(unsigned long data);
+static void e1000_82547_tx_fifo_stall_task(struct work_struct *work);
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
struct net_device *netdev);
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
@@ -519,8 +521,21 @@ void e1000_down(struct e1000_adapter *adapter)
e1000_clean_all_rx_rings(adapter);
}
+void e1000_reinit_safe(struct e1000_adapter *adapter)
+{
+ while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
+ msleep(1);
+ rtnl_lock();
+ e1000_down(adapter);
+ e1000_up(adapter);
+ rtnl_unlock();
+ clear_bit(__E1000_RESETTING, &adapter->flags);
+}
+
void e1000_reinit_locked(struct e1000_adapter *adapter)
{
+ /* if rtnl_lock is not held the call path is bogus */
+ ASSERT_RTNL();
WARN_ON(in_interrupt());
while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
msleep(1);
@@ -790,6 +805,70 @@ static const struct net_device_ops e1000_netdev_ops = {
};
/**
+ * e1000_init_hw_struct - initialize members of hw struct
+ * @adapter: board private struct
+ * @hw: structure used by e1000_hw.c
+ *
+ * Factors out initialization of the e1000_hw struct to its own function
+ * that can be called very early at init (just after struct allocation).
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ * Returns negative error codes if MAC type setup fails.
+ */
+static int e1000_init_hw_struct(struct e1000_adapter *adapter,
+ struct e1000_hw *hw)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ /* PCI config space info */
+ hw->vendor_id = pdev->vendor;
+ hw->device_id = pdev->device;
+ hw->subsystem_vendor_id = pdev->subsystem_vendor;
+ hw->subsystem_id = pdev->subsystem_device;
+ hw->revision_id = pdev->revision;
+
+ pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
+
+ hw->max_frame_size = adapter->netdev->mtu +
+ ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
+ hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
+
+ /* identify the MAC */
+ if (e1000_set_mac_type(hw)) {
+ e_err(probe, "Unknown MAC Type\n");
+ return -EIO;
+ }
+
+ switch (hw->mac_type) {
+ default:
+ break;
+ case e1000_82541:
+ case e1000_82547:
+ case e1000_82541_rev_2:
+ case e1000_82547_rev_2:
+ hw->phy_init_script = 1;
+ break;
+ }
+
+ e1000_set_media_type(hw);
+ e1000_get_bus_info(hw);
+
+ hw->wait_autoneg_complete = false;
+ hw->tbi_compatibility_en = true;
+ hw->adaptive_ifs = true;
+
+ /* Copper options */
+
+ if (hw->media_type == e1000_media_type_copper) {
+ hw->mdix = AUTO_ALL_MODES;
+ hw->disable_polarity_correction = false;
+ hw->master_slave = E1000_MASTER_SLAVE;
+ }
+
+ return 0;
+}
+
+/**
* e1000_probe - Device Initialization Routine
* @pdev: PCI device information struct
* @ent: entry in e1000_pci_tbl
@@ -826,22 +905,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (err)
return err;
- if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
- !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
- pci_using_dac = 1;
- } else {
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
- if (err) {
- err = dma_set_coherent_mask(&pdev->dev,
- DMA_BIT_MASK(32));
- if (err) {
- pr_err("No usable DMA config, aborting\n");
- goto err_dma;
- }
- }
- pci_using_dac = 0;
- }
-
err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
if (err)
goto err_pci_reg;
@@ -885,6 +948,32 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
}
}
+ /* make ready for any if (hw->...) below */
+ err = e1000_init_hw_struct(adapter, hw);
+ if (err)
+ goto err_sw_init;
+
+ /*
+ * there is a workaround being applied below that limits
+ * 64-bit DMA addresses to 64-bit hardware. There are some
+ * 32-bit adapters that Tx hang when given 64-bit DMA addresses
+ */
+ pci_using_dac = 0;
+ if ((hw->bus_type == e1000_bus_type_pcix) &&
+ !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
+ /*
+ * according to DMA-API-HOWTO, coherent calls will always
+ * succeed if the set call did
+ */
+ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
+ pci_using_dac = 1;
+ } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
+ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+ } else {
+ pr_err("No usable DMA config, aborting\n");
+ goto err_dma;
+ }
+
netdev->netdev_ops = &e1000_netdev_ops;
e1000_set_ethtool_ops(netdev);
netdev->watchdog_timeo = 5 * HZ;
@@ -914,8 +1003,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
(hw->mac_type != e1000_82547))
netdev->features |= NETIF_F_TSO;
- if (pci_using_dac)
+ if (pci_using_dac) {
netdev->features |= NETIF_F_HIGHDMA;
+ netdev->vlan_features |= NETIF_F_HIGHDMA;
+ }
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_HW_CSUM;
@@ -959,21 +1050,21 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (!is_valid_ether_addr(netdev->perm_addr))
e_err(probe, "Invalid MAC Address\n");
- e1000_get_bus_info(hw);
-
init_timer(&adapter->tx_fifo_stall_timer);
- adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
+ adapter->tx_fifo_stall_timer.function = e1000_82547_tx_fifo_stall;
adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &e1000_watchdog;
+ adapter->watchdog_timer.function = e1000_watchdog;
adapter->watchdog_timer.data = (unsigned long) adapter;
init_timer(&adapter->phy_info_timer);
- adapter->phy_info_timer.function = &e1000_update_phy_info;
+ adapter->phy_info_timer.function = e1000_update_phy_info;
adapter->phy_info_timer.data = (unsigned long)adapter;
+ INIT_WORK(&adapter->fifo_stall_task, e1000_82547_tx_fifo_stall_task);
INIT_WORK(&adapter->reset_task, e1000_reset_task);
+ INIT_WORK(&adapter->phy_info_task, e1000_update_phy_info_task);
e1000_check_options(adapter);
@@ -1072,6 +1163,7 @@ err_eeprom:
iounmap(hw->flash_address);
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
+err_dma:
err_sw_init:
iounmap(hw->hw_addr);
err_ioremap:
@@ -1079,7 +1171,6 @@ err_ioremap:
err_alloc_etherdev:
pci_release_selected_regions(pdev, bars);
err_pci_reg:
-err_dma:
pci_disable_device(pdev);
return err;
}
@@ -1131,62 +1222,12 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
* @adapter: board private structure to initialize
*
* e1000_sw_init initializes the Adapter private data structure.
- * Fields are initialized based on PCI device information and
- * OS network device settings (MTU size).
+ * e1000_init_hw_struct MUST be called before this function
**/
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
{
- struct e1000_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
-
- /* PCI config space info */
-
- hw->vendor_id = pdev->vendor;
- hw->device_id = pdev->device;
- hw->subsystem_vendor_id = pdev->subsystem_vendor;
- hw->subsystem_id = pdev->subsystem_device;
- hw->revision_id = pdev->revision;
-
- pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
-
adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
- hw->max_frame_size = netdev->mtu +
- ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
- hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
-
- /* identify the MAC */
-
- if (e1000_set_mac_type(hw)) {
- e_err(probe, "Unknown MAC Type\n");
- return -EIO;
- }
-
- switch (hw->mac_type) {
- default:
- break;
- case e1000_82541:
- case e1000_82547:
- case e1000_82541_rev_2:
- case e1000_82547_rev_2:
- hw->phy_init_script = 1;
- break;
- }
-
- e1000_set_media_type(hw);
-
- hw->wait_autoneg_complete = false;
- hw->tbi_compatibility_en = true;
- hw->adaptive_ifs = true;
-
- /* Copper options */
-
- if (hw->media_type == e1000_media_type_copper) {
- hw->mdix = AUTO_ALL_MODES;
- hw->disable_polarity_correction = false;
- hw->master_slave = E1000_MASTER_SLAVE;
- }
adapter->num_tx_queues = 1;
adapter->num_rx_queues = 1;
@@ -2210,22 +2251,45 @@ static void e1000_set_rx_mode(struct net_device *netdev)
static void e1000_update_phy_info(unsigned long data)
{
struct e1000_adapter *adapter = (struct e1000_adapter *)data;
+ schedule_work(&adapter->phy_info_task);
+}
+
+static void e1000_update_phy_info_task(struct work_struct *work)
+{
+ struct e1000_adapter *adapter = container_of(work,
+ struct e1000_adapter,
+ phy_info_task);
struct e1000_hw *hw = &adapter->hw;
+
+ rtnl_lock();
e1000_phy_get_info(hw, &adapter->phy_info);
+ rtnl_unlock();
}
/**
* e1000_82547_tx_fifo_stall - Timer Call-back
* @data: pointer to adapter cast into an unsigned long
**/
-
static void e1000_82547_tx_fifo_stall(unsigned long data)
{
struct e1000_adapter *adapter = (struct e1000_adapter *)data;
+ schedule_work(&adapter->fifo_stall_task);
+}
+
+/**
+ * e1000_82547_tx_fifo_stall_task - task to complete work
+ * @work: work struct contained inside adapter struct
+ **/
+static void e1000_82547_tx_fifo_stall_task(struct work_struct *work)
+{
+ struct e1000_adapter *adapter = container_of(work,
+ struct e1000_adapter,
+ fifo_stall_task);
struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
u32 tctl;
+ rtnl_lock();
if (atomic_read(&adapter->tx_fifo_stall)) {
if ((er32(TDT) == er32(TDH)) &&
(er32(TDFT) == er32(TDFH)) &&
@@ -2246,6 +2310,7 @@ static void e1000_82547_tx_fifo_stall(unsigned long data)
mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
}
}
+ rtnl_unlock();
}
bool e1000_has_link(struct e1000_adapter *adapter)
@@ -3054,7 +3119,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
}
}
- if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+ if (unlikely(vlan_tx_tag_present(skb))) {
tx_flags |= E1000_TX_FLAGS_VLAN;
tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
}
@@ -3113,7 +3178,7 @@ static void e1000_reset_task(struct work_struct *work)
struct e1000_adapter *adapter =
container_of(work, struct e1000_adapter, reset_task);
- e1000_reinit_locked(adapter);
+ e1000_reinit_safe(adapter);
}
/**
@@ -3535,7 +3600,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
adapter->total_tx_packets += total_tx_packets;
netdev->stats.tx_bytes += total_tx_bytes;
netdev->stats.tx_packets += total_tx_packets;
- return (count < tx_ring->count);
+ return count < tx_ring->count;
}
/**
@@ -3552,7 +3617,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
struct e1000_hw *hw = &adapter->hw;
u16 status = (u16)status_err;
u8 errors = (u8)(status_err >> 24);
- skb->ip_summed = CHECKSUM_NONE;
+
+ skb_checksum_none_assert(skb);
/* 82543 or newer only */
if (unlikely(hw->mac_type < e1000_82543)) return;
@@ -3598,13 +3664,14 @@ static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
__le16 vlan, struct sk_buff *skb)
{
- if (unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))) {
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(vlan) &
- E1000_RXD_SPC_VLAN_MASK);
- } else {
- netif_receive_skb(skb);
- }
+ skb->protocol = eth_type_trans(skb, adapter->netdev);
+
+ if ((unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))))
+ vlan_gro_receive(&adapter->napi, adapter->vlgrp,
+ le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK,
+ skb);
+ else
+ napi_gro_receive(&adapter->napi, skb);
}
/**
@@ -3762,8 +3829,6 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
goto next_desc;
}
- skb->protocol = eth_type_trans(skb, netdev);
-
e1000_receive_skb(adapter, status, rx_desc->special, skb);
next_desc:
@@ -3926,8 +3991,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
((u32)(rx_desc->errors) << 24),
le16_to_cpu(rx_desc->csum), skb);
- skb->protocol = eth_type_trans(skb, netdev);
-
e1000_receive_skb(adapter, status, rx_desc->special, skb);
next_desc:
@@ -4478,7 +4541,7 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter)
if (adapter->vlgrp) {
u16 vid;
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ for (vid = 0; vid < VLAN_N_VID; vid++) {
if (!vlan_group_get_device(adapter->vlgrp, vid))
continue;
e1000_vlan_rx_add_vid(adapter->netdev, vid);
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index d3d4a57e2450..ca663f19d7df 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -1801,7 +1801,8 @@ struct e1000_info e1000_82571_info = {
| FLAG_RESET_OVERWRITES_LAA /* errata */
| FLAG_TARC_SPEED_MODE_BIT /* errata */
| FLAG_APME_CHECK_PORT_B,
- .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */
+ .flags2 = FLAG2_DISABLE_ASPM_L1 /* errata 13 */
+ | FLAG2_DMA_BURST,
.pba = 38,
.max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
@@ -1819,7 +1820,8 @@ struct e1000_info e1000_82572_info = {
| FLAG_RX_CSUM_ENABLED
| FLAG_HAS_CTRLEXT_ON_LOAD
| FLAG_TARC_SPEED_MODE_BIT, /* errata */
- .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */
+ .flags2 = FLAG2_DISABLE_ASPM_L1 /* errata 13 */
+ | FLAG2_DMA_BURST,
.pba = 38,
.max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 93b3bedae8d2..d3f7a9c3f973 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -446,7 +446,9 @@
/* Transmit Descriptor Control */
#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
+#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */
#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */
+#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
#define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */
/* Enable the counting of desc. still to be processed. */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index f9a31c82f871..cee882dd67bf 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -153,6 +153,33 @@ struct e1000_info;
/* Time to wait before putting the device into D3 if there's no link (in ms). */
#define LINK_TIMEOUT 100
+#define DEFAULT_RDTR 0
+#define DEFAULT_RADV 8
+#define BURST_RDTR 0x20
+#define BURST_RADV 0x20
+
+/*
+ * in the case of WTHRESH, it appears at least the 82571/2 hardware
+ * writes back 4 descriptors when WTHRESH=5, and 3 descriptors when
+ * WTHRESH=4, and since we want 64 bytes at a time written back, set
+ * it to 5
+ */
+#define E1000_TXDCTL_DMA_BURST_ENABLE \
+ (E1000_TXDCTL_GRAN | /* set descriptor granularity */ \
+ E1000_TXDCTL_COUNT_DESC | \
+ (5 << 16) | /* wthresh must be +1 more than desired */\
+ (1 << 8) | /* hthresh */ \
+ 0x1f) /* pthresh */
+
+#define E1000_RXDCTL_DMA_BURST_ENABLE \
+ (0x01000000 | /* set descriptor granularity */ \
+ (4 << 16) | /* set writeback threshold */ \
+ (4 << 8) | /* set prefetch threshold */ \
+ 0x20) /* set hthresh */
+
+#define E1000_TIDV_FPD (1 << 31)
+#define E1000_RDTR_FPD (1 << 31)
+
enum e1000_boards {
board_82571,
board_82572,
@@ -425,6 +452,8 @@ struct e1000_info {
#define FLAG2_DISABLE_ASPM_L1 (1 << 3)
#define FLAG2_HAS_PHY_STATS (1 << 4)
#define FLAG2_HAS_EEE (1 << 5)
+#define FLAG2_DMA_BURST (1 << 6)
+#define FLAG2_DISABLE_AIM (1 << 8)
#define E1000_RX_DESC_PS(R, i) \
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index 45aebb4a6fe1..24f8ac9cf703 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -1494,6 +1494,7 @@ struct e1000_info e1000_es2_info = {
| FLAG_APME_CHECK_PORT_B
| FLAG_DISABLE_FC_PAUSE_TIME /* errata */
| FLAG_TIPG_MEDIUM_FOR_80003ESLAN,
+ .flags2 = FLAG2_DMA_BURST,
.pba = 38,
.max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_80003es2lan,
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 6355a1b779d3..8984d165a39b 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -368,7 +368,7 @@ out:
static u32 e1000_get_rx_csum(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
- return (adapter->flags & FLAG_RX_CSUM_ENABLED);
+ return adapter->flags & FLAG_RX_CSUM_ENABLED;
}
static int e1000_set_rx_csum(struct net_device *netdev, u32 data)
@@ -389,7 +389,7 @@ static int e1000_set_rx_csum(struct net_device *netdev, u32 data)
static u32 e1000_get_tx_csum(struct net_device *netdev)
{
- return ((netdev->features & NETIF_F_HW_CSUM) != 0);
+ return (netdev->features & NETIF_F_HW_CSUM) != 0;
}
static int e1000_set_tx_csum(struct net_device *netdev, u32 data)
@@ -1717,13 +1717,6 @@ static void e1000_diag_test(struct net_device *netdev,
e_info("offline testing starting\n");
- /*
- * Link test performed before hardware reset so autoneg doesn't
- * interfere with test result
- */
- if (e1000_link_test(adapter, &data[4]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
if (if_running)
/* indicate we're in test mode */
dev_close(netdev);
@@ -1747,15 +1740,19 @@ static void e1000_diag_test(struct net_device *netdev,
if (e1000_loopback_test(adapter, &data[3]))
eth_test->flags |= ETH_TEST_FL_FAILED;
+ /* force this routine to wait until autoneg complete/timeout */
+ adapter->hw.phy.autoneg_wait_to_complete = 1;
+ e1000e_reset(adapter);
+ adapter->hw.phy.autoneg_wait_to_complete = 0;
+
+ if (e1000_link_test(adapter, &data[4]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
/* restore speed, duplex, autoneg settings */
adapter->hw.phy.autoneg_advertised = autoneg_advertised;
adapter->hw.mac.forced_speed_duplex = forced_speed_duplex;
adapter->hw.mac.autoneg = autoneg;
-
- /* force this routine to wait until autoneg complete/timeout */
- adapter->hw.phy.autoneg_wait_to_complete = 1;
e1000e_reset(adapter);
- adapter->hw.phy.autoneg_wait_to_complete = 0;
clear_bit(__E1000_TESTING, &adapter->state);
if (if_running)
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 57b5435599ab..e3374d9a2472 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -3986,7 +3986,7 @@ struct e1000_info e1000_pch2_info = {
| FLAG_APME_IN_WUC,
.flags2 = FLAG2_HAS_PHY_STATS
| FLAG2_HAS_EEE,
- .pba = 18,
+ .pba = 26,
.max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_ich8lan,
.mac_ops = &ich8_mac_ops,
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index e561d15c3eb1..ec8cf3f51423 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -475,7 +475,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
{
u16 status = (u16)status_err;
u8 errors = (u8)(status_err >> 24);
- skb->ip_summed = CHECKSUM_NONE;
+
+ skb_checksum_none_assert(skb);
/* Ignore Checksum bit is set */
if (status & E1000_RXD_STAT_IXSM)
@@ -1052,7 +1053,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
adapter->total_tx_packets += total_tx_packets;
netdev->stats.tx_bytes += total_tx_bytes;
netdev->stats.tx_packets += total_tx_packets;
- return (count < tx_ring->count);
+ return count < tx_ring->count;
}
/**
@@ -2289,6 +2290,11 @@ static void e1000_set_itr(struct e1000_adapter *adapter)
goto set_itr_now;
}
+ if (adapter->flags2 & FLAG2_DISABLE_AIM) {
+ new_itr = 0;
+ goto set_itr_now;
+ }
+
adapter->tx_itr = e1000_update_itr(adapter,
adapter->tx_itr,
adapter->total_tx_packets,
@@ -2337,7 +2343,10 @@ set_itr_now:
if (adapter->msix_entries)
adapter->rx_ring->set_itr = 1;
else
- ew32(ITR, 1000000000 / (new_itr * 256));
+ if (new_itr)
+ ew32(ITR, 1000000000 / (new_itr * 256));
+ else
+ ew32(ITR, 0);
}
}
@@ -2536,7 +2545,7 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter)
if (!adapter->vlgrp)
return;
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ for (vid = 0; vid < VLAN_N_VID; vid++) {
if (!vlan_group_get_device(adapter->vlgrp, vid))
continue;
e1000_vlan_rx_add_vid(adapter->netdev, vid);
@@ -2649,6 +2658,26 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
/* Tx irq moderation */
ew32(TADV, adapter->tx_abs_int_delay);
+ if (adapter->flags2 & FLAG2_DMA_BURST) {
+ u32 txdctl = er32(TXDCTL(0));
+ txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH |
+ E1000_TXDCTL_WTHRESH);
+ /*
+ * set up some performance related parameters to encourage the
+ * hardware to use the bus more efficiently in bursts, depends
+ * on the tx_int_delay to be enabled,
+ * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time
+ * hthresh = 1 ==> prefetch when one or more available
+ * pthresh = 0x1f ==> prefetch if internal cache 31 or less
+ * BEWARE: this seems to work but should be considered first if
+ * there are tx hangs or other tx related bugs
+ */
+ txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE;
+ ew32(TXDCTL(0), txdctl);
+ /* erratum work around: set txdctl the same for both queues */
+ ew32(TXDCTL(1), txdctl);
+ }
+
/* Program the Transmit Control Register */
tctl = er32(TCTL);
tctl &= ~E1000_TCTL_CT;
@@ -2871,12 +2900,35 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
e1e_flush();
msleep(10);
+ if (adapter->flags2 & FLAG2_DMA_BURST) {
+ /*
+ * set the writeback threshold (only takes effect if the RDTR
+ * is set). set GRAN=1 and write back up to 0x4 worth, and
+ * enable prefetching of 0x20 rx descriptors
+ * granularity = 01
+ * wthresh = 04,
+ * hthresh = 04,
+ * pthresh = 0x20
+ */
+ ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE);
+ ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE);
+
+ /*
+ * override the delay timers for enabling bursting, only if
+ * the value was not set by the user via module options
+ */
+ if (adapter->rx_int_delay == DEFAULT_RDTR)
+ adapter->rx_int_delay = BURST_RDTR;
+ if (adapter->rx_abs_int_delay == DEFAULT_RADV)
+ adapter->rx_abs_int_delay = BURST_RADV;
+ }
+
/* set the Receive Delay Timer Register */
ew32(RDTR, adapter->rx_int_delay);
/* irq moderation */
ew32(RADV, adapter->rx_abs_int_delay);
- if (adapter->itr_setting != 0)
+ if ((adapter->itr_setting != 0) && (adapter->itr != 0))
ew32(ITR, 1000000000 / (adapter->itr * 256));
ctrl_ext = er32(CTRL_EXT);
@@ -2921,11 +2973,13 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
* packet size is equal or larger than the specified value (in 8 byte
* units), e.g. using jumbo frames when setting to E1000_ERT_2048
*/
- if (adapter->flags & FLAG_HAS_ERT) {
+ if ((adapter->flags & FLAG_HAS_ERT) ||
+ (adapter->hw.mac.type == e1000_pch2lan)) {
if (adapter->netdev->mtu > ETH_DATA_LEN) {
u32 rxdctl = er32(RXDCTL(0));
ew32(RXDCTL(0), rxdctl | 0x3);
- ew32(ERT, E1000_ERT_2048 | (1 << 13));
+ if (adapter->flags & FLAG_HAS_ERT)
+ ew32(ERT, E1000_ERT_2048 | (1 << 13));
/*
* With jumbo frames and early-receive enabled,
* excessive C-state transition latencies result in
@@ -3188,9 +3242,35 @@ void e1000e_reset(struct e1000_adapter *adapter)
fc->low_water = 0x05048;
fc->pause_time = 0x0650;
fc->refresh_time = 0x0400;
+ if (adapter->netdev->mtu > ETH_DATA_LEN) {
+ pba = 14;
+ ew32(PBA, pba);
+ }
break;
}
+ /*
+ * Disable Adaptive Interrupt Moderation if 2 full packets cannot
+ * fit in receive buffer and early-receive not supported.
+ */
+ if (adapter->itr_setting & 0x3) {
+ if (((adapter->max_frame_size * 2) > (pba << 10)) &&
+ !(adapter->flags & FLAG_HAS_ERT)) {
+ if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) {
+ dev_info(&adapter->pdev->dev,
+ "Interrupt Throttle Rate turned off\n");
+ adapter->flags2 |= FLAG2_DISABLE_AIM;
+ ew32(ITR, 0);
+ }
+ } else if (adapter->flags2 & FLAG2_DISABLE_AIM) {
+ dev_info(&adapter->pdev->dev,
+ "Interrupt Throttle Rate turned on\n");
+ adapter->flags2 &= ~FLAG2_DISABLE_AIM;
+ adapter->itr = 20000;
+ ew32(ITR, 1000000000 / (adapter->itr * 256));
+ }
+ }
+
/* Allow time for pending master requests to run */
mac->ops.reset_hw(hw);
@@ -3411,22 +3491,16 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
if (adapter->flags & FLAG_MSI_TEST_FAILED) {
adapter->int_mode = E1000E_INT_MODE_LEGACY;
- err = -EIO;
- e_info("MSI interrupt test failed!\n");
- }
+ e_info("MSI interrupt test failed, using legacy interrupt.\n");
+ } else
+ e_dbg("MSI interrupt test succeeded!\n");
free_irq(adapter->pdev->irq, netdev);
pci_disable_msi(adapter->pdev);
- if (err == -EIO)
- goto msi_test_failed;
-
- /* okay so the test worked, restore settings */
- e_dbg("MSI interrupt test succeeded!\n");
msi_test_failed:
e1000e_set_interrupt_capability(adapter);
- e1000_request_irq(adapter);
- return err;
+ return e1000_request_irq(adapter);
}
/**
@@ -3458,21 +3532,6 @@ static int e1000_test_msi(struct e1000_adapter *adapter)
pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
}
- /* success ! */
- if (!err)
- return 0;
-
- /* EIO means MSI test failed */
- if (err != -EIO)
- return err;
-
- /* back to INTx mode */
- e_warn("MSI interrupt test failed, using legacy interrupt.\n");
-
- e1000_free_irq(adapter);
-
- err = e1000_request_irq(adapter);
-
return err;
}
@@ -3530,7 +3589,8 @@ static int e1000_open(struct net_device *netdev)
e1000_update_mng_vlan(adapter);
/* DMA latency requirement to workaround early-receive/jumbo issue */
- if (adapter->flags & FLAG_HAS_ERT)
+ if ((adapter->flags & FLAG_HAS_ERT) ||
+ (adapter->hw.mac.type == e1000_pch2lan))
pm_qos_add_request(&adapter->netdev->pm_qos_req,
PM_QOS_CPU_DMA_LATENCY,
PM_QOS_DEFAULT_VALUE);
@@ -3639,7 +3699,8 @@ static int e1000_close(struct net_device *netdev)
if (adapter->flags & FLAG_HAS_AMT)
e1000_release_hw_control(adapter);
- if (adapter->flags & FLAG_HAS_ERT)
+ if ((adapter->flags & FLAG_HAS_ERT) ||
+ (adapter->hw.mac.type == e1000_pch2lan))
pm_qos_remove_request(&adapter->netdev->pm_qos_req);
pm_runtime_put_sync(&pdev->dev);
@@ -4255,6 +4316,16 @@ link_up:
/* Force detection of hung controller every watchdog period */
adapter->detect_tx_hung = 1;
+ /* flush partial descriptors to memory before detecting tx hang */
+ if (adapter->flags2 & FLAG2_DMA_BURST) {
+ ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
+ ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
+ /*
+ * no need to flush the writes because the timeout code does
+ * an er32 first thing
+ */
+ }
+
/*
* With 82571 controllers, LAA may be overwritten due to controller
* reset from the other port. Set the appropriate LAA in RAR[0]
@@ -4729,7 +4800,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
if (e1000_maybe_stop_tx(netdev, count + 2))
return NETDEV_TX_BUSY;
- if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
tx_flags |= E1000_TX_FLAGS_VLAN;
tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
}
@@ -5712,8 +5783,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
netdev->vlan_features |= NETIF_F_HW_CSUM;
netdev->vlan_features |= NETIF_F_SG;
- if (pci_using_dac)
+ if (pci_using_dac) {
netdev->features |= NETIF_F_HIGHDMA;
+ netdev->vlan_features |= NETIF_F_HIGHDMA;
+ }
if (e1000e_enable_mng_pass_thru(&adapter->hw))
adapter->flags |= FLAG_MNG_PT_ENABLED;
@@ -5754,11 +5827,11 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
}
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &e1000_watchdog;
+ adapter->watchdog_timer.function = e1000_watchdog;
adapter->watchdog_timer.data = (unsigned long) adapter;
init_timer(&adapter->phy_info_timer);
- adapter->phy_info_timer.function = &e1000_update_phy_info;
+ adapter->phy_info_timer.function = e1000_update_phy_info;
adapter->phy_info_timer.data = (unsigned long) adapter;
INIT_WORK(&adapter->reset_task, e1000_reset_task);
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index 34aeec13bb16..3d36911f77f3 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -91,7 +91,6 @@ E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
* Valid Range: 0-65535
*/
E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
-#define DEFAULT_RDTR 0
#define MAX_RXDELAY 0xFFFF
#define MIN_RXDELAY 0
@@ -101,7 +100,6 @@ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
* Valid Range: 0-65535
*/
E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
-#define DEFAULT_RADV 8
#define MAX_RXABSDELAY 0xFFFF
#define MIN_RXABSDELAY 0
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index 8d97f168f018..7c826319ee5a 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -1457,11 +1457,11 @@ hardware_send_packet(struct net_device *dev, void *buf, short length)
if (net_debug > 5)
printk(KERN_DEBUG "%s: entering hardware_send_packet routine.\n", dev->name);
- /* determine how much of the transmit buffer space is available */
- if (lp->tx_end > lp->tx_start)
+ /* determine how much of the transmit buffer space is available */
+ if (lp->tx_end > lp->tx_start)
tx_available = lp->xmt_ram - (lp->tx_end - lp->tx_start);
- else if (lp->tx_end < lp->tx_start)
- tx_available = lp->tx_start - lp->tx_end;
+ else if (lp->tx_end < lp->tx_start)
+ tx_available = lp->tx_start - lp->tx_end;
else tx_available = lp->xmt_ram;
if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER) >= tx_available) {
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 1846623c6ae6..1321cb6401cf 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -491,6 +491,8 @@ struct ehea_port {
u8 full_duplex;
u8 autoneg;
u8 num_def_qps;
+ wait_queue_head_t swqe_avail_wq;
+ wait_queue_head_t restart_wq;
};
struct port_res_cfg {
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 6372610ed240..bb7d306fb446 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -180,7 +180,7 @@ static void ehea_update_firmware_handles(void)
num_portres * EHEA_NUM_PORTRES_FW_HANDLES;
if (num_fw_handles) {
- arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL);
+ arr = kcalloc(num_fw_handles, sizeof(*arr), GFP_KERNEL);
if (!arr)
goto out; /* Keep the existing array */
} else
@@ -265,7 +265,7 @@ static void ehea_update_bcmc_registrations(void)
}
if (num_registrations) {
- arr = kzalloc(num_registrations * sizeof(*arr), GFP_ATOMIC);
+ arr = kcalloc(num_registrations, sizeof(*arr), GFP_ATOMIC);
if (!arr)
goto out; /* Keep the existing array */
} else
@@ -793,6 +793,7 @@ static void reset_sq_restart_flag(struct ehea_port *port)
struct ehea_port_res *pr = &port->port_res[i];
pr->sq_restart_flag = 0;
}
+ wake_up(&port->restart_wq);
}
static void check_sqs(struct ehea_port *port)
@@ -803,6 +804,7 @@ static void check_sqs(struct ehea_port *port)
for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
struct ehea_port_res *pr = &port->port_res[i];
+ int ret;
k = 0;
swqe = ehea_get_swqe(pr->qp, &swqe_index);
memset(swqe, 0, SWQE_HEADER_SIZE);
@@ -816,17 +818,16 @@ static void check_sqs(struct ehea_port *port)
ehea_post_swqe(pr->qp, swqe);
- while (pr->sq_restart_flag == 0) {
- msleep(5);
- if (++k == 100) {
- ehea_error("HW/SW queues out of sync");
- ehea_schedule_port_reset(pr->port);
- return;
- }
+ ret = wait_event_timeout(port->restart_wq,
+ pr->sq_restart_flag == 0,
+ msecs_to_jiffies(100));
+
+ if (!ret) {
+ ehea_error("HW/SW queues out of sync");
+ ehea_schedule_port_reset(pr->port);
+ return;
}
}
-
- return;
}
@@ -897,6 +898,7 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota)
pr->queue_stopped = 0;
}
spin_unlock_irqrestore(&pr->netif_queue, flags);
+ wake_up(&pr->port->swqe_avail_wq);
return cqe;
}
@@ -1923,7 +1925,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable)
struct hcp_ehea_port_cb7 *cb7;
u64 hret;
- if ((enable && port->promisc) || (!enable && !port->promisc))
+ if (enable == port->promisc)
return;
cb7 = (void *)get_zeroed_page(GFP_ATOMIC);
@@ -2277,7 +2279,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
pr->swqe_id_counter += 1;
- if (port->vgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
swqe->tx_control |= EHEA_SWQE_VLAN_INSERT;
swqe->vlan_tag = vlan_tx_tag_get(skb);
}
@@ -2661,6 +2663,9 @@ static int ehea_open(struct net_device *dev)
netif_start_queue(dev);
}
+ init_waitqueue_head(&port->swqe_avail_wq);
+ init_waitqueue_head(&port->restart_wq);
+
mutex_unlock(&port->port_lock);
return ret;
@@ -2733,13 +2738,15 @@ static void ehea_flush_sq(struct ehea_port *port)
for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
struct ehea_port_res *pr = &port->port_res[i];
int swqe_max = pr->sq_skba_size - 2 - pr->swqe_ll_count;
- int k = 0;
- while (atomic_read(&pr->swqe_avail) < swqe_max) {
- msleep(5);
- if (++k == 20) {
- ehea_error("WARNING: sq not flushed completely");
- break;
- }
+ int ret;
+
+ ret = wait_event_timeout(port->swqe_avail_wq,
+ atomic_read(&pr->swqe_avail) >= swqe_max,
+ msecs_to_jiffies(100));
+
+ if (!ret) {
+ ehea_error("WARNING: sq not flushed completely");
+ break;
}
}
}
@@ -3728,7 +3735,7 @@ int __init ehea_module_init(void)
if (ret)
ehea_info("failed registering memory remove notifier");
- ret = crash_shutdown_register(&ehea_crash_handler);
+ ret = crash_shutdown_register(ehea_crash_handler);
if (ret)
ehea_info("failed registering crash handler");
@@ -3753,7 +3760,7 @@ out3:
out2:
unregister_memory_notifier(&ehea_mem_nb);
unregister_reboot_notifier(&ehea_reboot_nb);
- crash_shutdown_unregister(&ehea_crash_handler);
+ crash_shutdown_unregister(ehea_crash_handler);
out:
return ret;
}
@@ -3766,7 +3773,7 @@ static void __exit ehea_module_exit(void)
driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
ibmebus_unregister_driver(&ehea_driver);
unregister_reboot_notifier(&ehea_reboot_nb);
- ret = crash_shutdown_unregister(&ehea_crash_handler);
+ ret = crash_shutdown_unregister(ehea_crash_handler);
if (ret)
ehea_info("failed unregistering crash handler");
unregister_memory_notifier(&ehea_mem_nb);
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index f239aa8c6f4c..c91d364c5527 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 "1.4.1.1"
+#define DRV_VERSION "1.4.1.6"
#define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc"
#define ENIC_BARS_MAX 6
@@ -42,25 +42,6 @@
#define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX)
#define ENIC_INTR_MAX (ENIC_CQ_MAX + 2)
-enum enic_cq_index {
- ENIC_CQ_RQ,
- ENIC_CQ_WQ,
-};
-
-enum enic_intx_intr_index {
- ENIC_INTX_WQ_RQ,
- ENIC_INTX_ERR,
- ENIC_INTX_NOTIFY,
-};
-
-enum enic_msix_intr_index {
- ENIC_MSIX_RQ,
- ENIC_MSIX_WQ,
- ENIC_MSIX_ERR,
- ENIC_MSIX_NOTIFY,
- ENIC_MSIX_MAX,
-};
-
struct enic_msix_entry {
int requested;
char devname[IFNAMSIZ];
@@ -91,8 +72,8 @@ struct enic {
struct vnic_dev *vdev;
struct timer_list notify_timer;
struct work_struct reset;
- struct msix_entry msix_entry[ENIC_MSIX_MAX];
- struct enic_msix_entry msix[ENIC_MSIX_MAX];
+ struct msix_entry msix_entry[ENIC_INTR_MAX];
+ struct enic_msix_entry msix[ENIC_INTR_MAX];
u32 msg_enable;
spinlock_t devcmd_lock;
u8 mac_addr[ETH_ALEN];
@@ -119,7 +100,7 @@ struct enic {
int (*rq_alloc_buf)(struct vnic_rq *rq);
u64 rq_truncated_pkts;
u64 rq_bad_fcs;
- struct napi_struct napi;
+ struct napi_struct napi[ENIC_RQ_MAX];
/* interrupt resource cache line section */
____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX];
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 9aab85366d21..a466ef91dd43 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -122,6 +122,51 @@ static int enic_is_dynamic(struct enic *enic)
return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
}
+static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq)
+{
+ return rq;
+}
+
+static inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq)
+{
+ return enic->rq_count + wq;
+}
+
+static inline unsigned int enic_legacy_io_intr(void)
+{
+ return 0;
+}
+
+static inline unsigned int enic_legacy_err_intr(void)
+{
+ return 1;
+}
+
+static inline unsigned int enic_legacy_notify_intr(void)
+{
+ return 2;
+}
+
+static inline unsigned int enic_msix_rq_intr(struct enic *enic, unsigned int rq)
+{
+ return rq;
+}
+
+static inline unsigned int enic_msix_wq_intr(struct enic *enic, unsigned int wq)
+{
+ return enic->rq_count + wq;
+}
+
+static inline unsigned int enic_msix_err_intr(struct enic *enic)
+{
+ return enic->rq_count + enic->wq_count;
+}
+
+static inline unsigned int enic_msix_notify_intr(struct enic *enic)
+{
+ return enic->rq_count + enic->wq_count + 1;
+}
+
static int enic_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
@@ -306,6 +351,7 @@ static int enic_set_coalesce(struct net_device *netdev,
struct enic *enic = netdev_priv(netdev);
u32 tx_coalesce_usecs;
u32 rx_coalesce_usecs;
+ unsigned int i, intr;
tx_coalesce_usecs = min_t(u32,
INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
@@ -319,7 +365,8 @@ static int enic_set_coalesce(struct net_device *netdev,
if (tx_coalesce_usecs != rx_coalesce_usecs)
return -EINVAL;
- vnic_intr_coalescing_timer_set(&enic->intr[ENIC_INTX_WQ_RQ],
+ intr = enic_legacy_io_intr();
+ vnic_intr_coalescing_timer_set(&enic->intr[intr],
INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
break;
case VNIC_DEV_INTR_MODE_MSI:
@@ -330,10 +377,18 @@ static int enic_set_coalesce(struct net_device *netdev,
INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
break;
case VNIC_DEV_INTR_MODE_MSIX:
- vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_WQ],
- INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
- vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_RQ],
- INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs));
+ for (i = 0; i < enic->wq_count; i++) {
+ intr = enic_msix_wq_intr(enic, i);
+ vnic_intr_coalescing_timer_set(&enic->intr[intr],
+ INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
+ }
+
+ for (i = 0; i < enic->rq_count; i++) {
+ intr = enic_msix_rq_intr(enic, i);
+ vnic_intr_coalescing_timer_set(&enic->intr[intr],
+ INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs));
+ }
+
break;
default:
break;
@@ -482,34 +537,37 @@ static irqreturn_t enic_isr_legacy(int irq, void *data)
{
struct net_device *netdev = data;
struct enic *enic = netdev_priv(netdev);
+ unsigned int io_intr = enic_legacy_io_intr();
+ unsigned int err_intr = enic_legacy_err_intr();
+ unsigned int notify_intr = enic_legacy_notify_intr();
u32 pba;
- vnic_intr_mask(&enic->intr[ENIC_INTX_WQ_RQ]);
+ vnic_intr_mask(&enic->intr[io_intr]);
pba = vnic_intr_legacy_pba(enic->legacy_pba);
if (!pba) {
- vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
+ vnic_intr_unmask(&enic->intr[io_intr]);
return IRQ_NONE; /* not our interrupt */
}
- if (ENIC_TEST_INTR(pba, ENIC_INTX_NOTIFY)) {
- vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_NOTIFY]);
+ if (ENIC_TEST_INTR(pba, notify_intr)) {
+ vnic_intr_return_all_credits(&enic->intr[notify_intr]);
enic_notify_check(enic);
}
- if (ENIC_TEST_INTR(pba, ENIC_INTX_ERR)) {
- vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_ERR]);
+ if (ENIC_TEST_INTR(pba, err_intr)) {
+ vnic_intr_return_all_credits(&enic->intr[err_intr]);
enic_log_q_error(enic);
/* schedule recovery from WQ/RQ error */
schedule_work(&enic->reset);
return IRQ_HANDLED;
}
- if (ENIC_TEST_INTR(pba, ENIC_INTX_WQ_RQ)) {
- if (napi_schedule_prep(&enic->napi))
- __napi_schedule(&enic->napi);
+ if (ENIC_TEST_INTR(pba, io_intr)) {
+ if (napi_schedule_prep(&enic->napi[0]))
+ __napi_schedule(&enic->napi[0]);
} else {
- vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
+ vnic_intr_unmask(&enic->intr[io_intr]);
}
return IRQ_HANDLED;
@@ -535,17 +593,17 @@ static irqreturn_t enic_isr_msi(int irq, void *data)
* writes).
*/
- napi_schedule(&enic->napi);
+ napi_schedule(&enic->napi[0]);
return IRQ_HANDLED;
}
static irqreturn_t enic_isr_msix_rq(int irq, void *data)
{
- struct enic *enic = data;
+ struct napi_struct *napi = data;
/* schedule NAPI polling for RQ cleanup */
- napi_schedule(&enic->napi);
+ napi_schedule(napi);
return IRQ_HANDLED;
}
@@ -553,13 +611,15 @@ static irqreturn_t enic_isr_msix_rq(int irq, void *data)
static irqreturn_t enic_isr_msix_wq(int irq, void *data)
{
struct enic *enic = data;
+ unsigned int cq = enic_cq_wq(enic, 0);
+ unsigned int intr = enic_msix_wq_intr(enic, 0);
unsigned int wq_work_to_do = -1; /* no limit */
unsigned int wq_work_done;
- wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ],
+ wq_work_done = vnic_cq_service(&enic->cq[cq],
wq_work_to_do, enic_wq_service, NULL);
- vnic_intr_return_credits(&enic->intr[ENIC_MSIX_WQ],
+ vnic_intr_return_credits(&enic->intr[intr],
wq_work_done,
1 /* unmask intr */,
1 /* reset intr timer */);
@@ -570,8 +630,9 @@ static irqreturn_t enic_isr_msix_wq(int irq, void *data)
static irqreturn_t enic_isr_msix_err(int irq, void *data)
{
struct enic *enic = data;
+ unsigned int intr = enic_msix_err_intr(enic);
- vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_ERR]);
+ vnic_intr_return_all_credits(&enic->intr[intr]);
enic_log_q_error(enic);
@@ -584,8 +645,9 @@ static irqreturn_t enic_isr_msix_err(int irq, void *data)
static irqreturn_t enic_isr_msix_notify(int irq, void *data)
{
struct enic *enic = data;
+ unsigned int intr = enic_msix_notify_intr(enic);
- vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_NOTIFY]);
+ vnic_intr_return_all_credits(&enic->intr[intr]);
enic_notify_check(enic);
return IRQ_HANDLED;
@@ -743,7 +805,7 @@ static inline void enic_queue_wq_skb(struct enic *enic,
int vlan_tag_insert = 0;
int loopback = 0;
- if (enic->vlan_group && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
/* VLAN tag from trunking driver */
vlan_tag_insert = 1;
vlan_tag = vlan_tx_tag_get(skb);
@@ -911,7 +973,20 @@ static int enic_set_mac_address_dynamic(struct net_device *netdev, void *p)
static int enic_set_mac_address(struct net_device *netdev, void *p)
{
- return -EOPNOTSUPP;
+ struct sockaddr *saddr = p;
+ char *addr = saddr->sa_data;
+ struct enic *enic = netdev_priv(netdev);
+ int err;
+
+ err = enic_dev_del_station_addr(enic);
+ if (err)
+ return err;
+
+ err = enic_set_mac_addr(netdev, addr);
+ if (err)
+ return err;
+
+ return enic_dev_add_station_addr(enic);
}
static int enic_dev_packet_filter(struct enic *enic, int directed,
@@ -1407,8 +1482,8 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
(vlan_tci & CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK)) {
if (netdev->features & NETIF_F_GRO)
- vlan_gro_receive(&enic->napi, enic->vlan_group,
- vlan_tci, skb);
+ vlan_gro_receive(&enic->napi[q_number],
+ enic->vlan_group, vlan_tci, skb);
else
vlan_hwaccel_receive_skb(skb,
enic->vlan_group, vlan_tci);
@@ -1416,12 +1491,11 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
} else {
if (netdev->features & NETIF_F_GRO)
- napi_gro_receive(&enic->napi, skb);
+ napi_gro_receive(&enic->napi[q_number], skb);
else
netif_receive_skb(skb);
}
-
} else {
/* Buffer overflow
@@ -1445,7 +1519,11 @@ static int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc,
static int enic_poll(struct napi_struct *napi, int budget)
{
- struct enic *enic = container_of(napi, struct enic, napi);
+ struct net_device *netdev = napi->dev;
+ struct enic *enic = netdev_priv(netdev);
+ unsigned int cq_rq = enic_cq_rq(enic, 0);
+ unsigned int cq_wq = enic_cq_wq(enic, 0);
+ unsigned int intr = enic_legacy_io_intr();
unsigned int rq_work_to_do = budget;
unsigned int wq_work_to_do = -1; /* no limit */
unsigned int work_done, rq_work_done, wq_work_done;
@@ -1454,10 +1532,10 @@ static int enic_poll(struct napi_struct *napi, int budget)
/* Service RQ (first) and WQ
*/
- rq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ],
+ rq_work_done = vnic_cq_service(&enic->cq[cq_rq],
rq_work_to_do, enic_rq_service, NULL);
- wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ],
+ wq_work_done = vnic_cq_service(&enic->cq[cq_wq],
wq_work_to_do, enic_wq_service, NULL);
/* Accumulate intr event credits for this polling
@@ -1468,7 +1546,7 @@ static int enic_poll(struct napi_struct *napi, int budget)
work_done = rq_work_done + wq_work_done;
if (work_done > 0)
- vnic_intr_return_credits(&enic->intr[ENIC_INTX_WQ_RQ],
+ vnic_intr_return_credits(&enic->intr[intr],
work_done,
0 /* don't unmask intr */,
0 /* don't reset intr timer */);
@@ -1489,7 +1567,7 @@ static int enic_poll(struct napi_struct *napi, int budget)
*/
napi_complete(napi);
- vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
+ vnic_intr_unmask(&enic->intr[intr]);
}
return rq_work_done;
@@ -1497,7 +1575,11 @@ static int enic_poll(struct napi_struct *napi, int budget)
static int enic_poll_msix(struct napi_struct *napi, int budget)
{
- struct enic *enic = container_of(napi, struct enic, napi);
+ struct net_device *netdev = napi->dev;
+ struct enic *enic = netdev_priv(netdev);
+ unsigned int rq = (napi - &enic->napi[0]);
+ unsigned int cq = enic_cq_rq(enic, rq);
+ unsigned int intr = enic_msix_rq_intr(enic, rq);
unsigned int work_to_do = budget;
unsigned int work_done;
int err;
@@ -1505,7 +1587,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
/* Service RQ
*/
- work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ],
+ work_done = vnic_cq_service(&enic->cq[cq],
work_to_do, enic_rq_service, NULL);
/* Return intr event credits for this polling
@@ -1514,12 +1596,12 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
*/
if (work_done > 0)
- vnic_intr_return_credits(&enic->intr[ENIC_MSIX_RQ],
+ vnic_intr_return_credits(&enic->intr[intr],
work_done,
0 /* don't unmask intr */,
0 /* don't reset intr timer */);
- err = vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
+ err = vnic_rq_fill(&enic->rq[rq], enic->rq_alloc_buf);
/* Buffer allocation failed. Stay in polling mode
* so we can try to fill the ring again.
@@ -1535,7 +1617,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
*/
napi_complete(napi);
- vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
+ vnic_intr_unmask(&enic->intr[intr]);
}
return work_done;
@@ -1577,7 +1659,7 @@ static void enic_free_intr(struct enic *enic)
static int enic_request_intr(struct enic *enic)
{
struct net_device *netdev = enic->netdev;
- unsigned int i;
+ unsigned int i, intr;
int err = 0;
switch (vnic_dev_get_intr_mode(enic->vdev)) {
@@ -1596,27 +1678,38 @@ static int enic_request_intr(struct enic *enic)
case VNIC_DEV_INTR_MODE_MSIX:
- sprintf(enic->msix[ENIC_MSIX_RQ].devname,
- "%.11s-rx-0", netdev->name);
- enic->msix[ENIC_MSIX_RQ].isr = enic_isr_msix_rq;
- enic->msix[ENIC_MSIX_RQ].devid = enic;
+ for (i = 0; i < enic->rq_count; i++) {
+ intr = enic_msix_rq_intr(enic, i);
+ sprintf(enic->msix[intr].devname,
+ "%.11s-rx-%d", netdev->name, i);
+ enic->msix[intr].isr = enic_isr_msix_rq;
+ enic->msix[intr].devid = &enic->napi[i];
+ }
- sprintf(enic->msix[ENIC_MSIX_WQ].devname,
- "%.11s-tx-0", netdev->name);
- enic->msix[ENIC_MSIX_WQ].isr = enic_isr_msix_wq;
- enic->msix[ENIC_MSIX_WQ].devid = enic;
+ for (i = 0; i < enic->wq_count; i++) {
+ intr = enic_msix_wq_intr(enic, i);
+ sprintf(enic->msix[intr].devname,
+ "%.11s-tx-%d", netdev->name, i);
+ enic->msix[intr].isr = enic_isr_msix_wq;
+ enic->msix[intr].devid = enic;
+ }
- sprintf(enic->msix[ENIC_MSIX_ERR].devname,
+ intr = enic_msix_err_intr(enic);
+ sprintf(enic->msix[intr].devname,
"%.11s-err", netdev->name);
- enic->msix[ENIC_MSIX_ERR].isr = enic_isr_msix_err;
- enic->msix[ENIC_MSIX_ERR].devid = enic;
+ enic->msix[intr].isr = enic_isr_msix_err;
+ enic->msix[intr].devid = enic;
- sprintf(enic->msix[ENIC_MSIX_NOTIFY].devname,
+ intr = enic_msix_notify_intr(enic);
+ sprintf(enic->msix[intr].devname,
"%.11s-notify", netdev->name);
- enic->msix[ENIC_MSIX_NOTIFY].isr = enic_isr_msix_notify;
- enic->msix[ENIC_MSIX_NOTIFY].devid = enic;
+ enic->msix[intr].isr = enic_isr_msix_notify;
+ enic->msix[intr].devid = enic;
+
+ for (i = 0; i < ARRAY_SIZE(enic->msix); i++)
+ enic->msix[i].requested = 0;
- for (i = 0; i < ARRAY_SIZE(enic->msix); i++) {
+ for (i = 0; i < enic->intr_count; i++) {
err = request_irq(enic->msix_entry[i].vector,
enic->msix[i].isr, 0,
enic->msix[i].devname,
@@ -1662,10 +1755,12 @@ static int enic_dev_notify_set(struct enic *enic)
spin_lock(&enic->devcmd_lock);
switch (vnic_dev_get_intr_mode(enic->vdev)) {
case VNIC_DEV_INTR_MODE_INTX:
- err = vnic_dev_notify_set(enic->vdev, ENIC_INTX_NOTIFY);
+ err = vnic_dev_notify_set(enic->vdev,
+ enic_legacy_notify_intr());
break;
case VNIC_DEV_INTR_MODE_MSIX:
- err = vnic_dev_notify_set(enic->vdev, ENIC_MSIX_NOTIFY);
+ err = vnic_dev_notify_set(enic->vdev,
+ enic_msix_notify_intr(enic));
break;
default:
err = vnic_dev_notify_set(enic->vdev, -1 /* no intr */);
@@ -1692,7 +1787,7 @@ static int enic_dev_enable(struct enic *enic)
int err;
spin_lock(&enic->devcmd_lock);
- err = vnic_dev_enable(enic->vdev);
+ err = vnic_dev_enable_wait(enic->vdev);
spin_unlock(&enic->devcmd_lock);
return err;
@@ -1760,7 +1855,10 @@ static int enic_open(struct net_device *netdev)
enic_set_multicast_list(netdev);
netif_wake_queue(netdev);
- napi_enable(&enic->napi);
+
+ for (i = 0; i < enic->rq_count; i++)
+ napi_enable(&enic->napi[i]);
+
enic_dev_enable(enic);
for (i = 0; i < enic->intr_count; i++)
@@ -1795,7 +1893,10 @@ static int enic_stop(struct net_device *netdev)
del_timer_sync(&enic->notify_timer);
enic_dev_disable(enic);
- napi_disable(&enic->napi);
+
+ for (i = 0; i < enic->rq_count; i++)
+ napi_disable(&enic->napi[i]);
+
netif_carrier_off(netdev);
netif_tx_disable(netdev);
enic_dev_del_station_addr(enic);
@@ -1855,11 +1956,16 @@ static void enic_poll_controller(struct net_device *netdev)
{
struct enic *enic = netdev_priv(netdev);
struct vnic_dev *vdev = enic->vdev;
+ unsigned int i, intr;
switch (vnic_dev_get_intr_mode(vdev)) {
case VNIC_DEV_INTR_MODE_MSIX:
- enic_isr_msix_rq(enic->pdev->irq, enic);
- enic_isr_msix_wq(enic->pdev->irq, enic);
+ for (i = 0; i < enic->rq_count; i++) {
+ intr = enic_msix_rq_intr(enic, i);
+ enic_isr_msix_rq(enic->msix_entry[intr].vector, enic);
+ }
+ intr = enic_msix_wq_intr(enic, i);
+ enic_isr_msix_wq(enic->msix_entry[intr].vector, enic);
break;
case VNIC_DEV_INTR_MODE_MSI:
enic_isr_msi(enic->pdev->irq, enic);
@@ -1934,19 +2040,73 @@ static int enic_dev_hang_reset(struct enic *enic)
return err;
}
-static int enic_set_niccfg(struct enic *enic)
+static int enic_set_rsskey(struct enic *enic)
+{
+ u64 rss_key_buf_pa;
+ union vnic_rss_key *rss_key_buf_va = NULL;
+ union vnic_rss_key rss_key = {
+ .key[0].b = {85, 67, 83, 97, 119, 101, 115, 111, 109, 101},
+ .key[1].b = {80, 65, 76, 79, 117, 110, 105, 113, 117, 101},
+ .key[2].b = {76, 73, 78, 85, 88, 114, 111, 99, 107, 115},
+ .key[3].b = {69, 78, 73, 67, 105, 115, 99, 111, 111, 108},
+ };
+ int err;
+
+ rss_key_buf_va = pci_alloc_consistent(enic->pdev,
+ sizeof(union vnic_rss_key), &rss_key_buf_pa);
+ if (!rss_key_buf_va)
+ return -ENOMEM;
+
+ memcpy(rss_key_buf_va, &rss_key, sizeof(union vnic_rss_key));
+
+ spin_lock(&enic->devcmd_lock);
+ err = enic_set_rss_key(enic,
+ rss_key_buf_pa,
+ sizeof(union vnic_rss_key));
+ spin_unlock(&enic->devcmd_lock);
+
+ pci_free_consistent(enic->pdev, sizeof(union vnic_rss_key),
+ rss_key_buf_va, rss_key_buf_pa);
+
+ return err;
+}
+
+static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits)
+{
+ u64 rss_cpu_buf_pa;
+ union vnic_rss_cpu *rss_cpu_buf_va = NULL;
+ unsigned int i;
+ int err;
+
+ rss_cpu_buf_va = pci_alloc_consistent(enic->pdev,
+ sizeof(union vnic_rss_cpu), &rss_cpu_buf_pa);
+ if (!rss_cpu_buf_va)
+ return -ENOMEM;
+
+ for (i = 0; i < (1 << rss_hash_bits); i++)
+ (*rss_cpu_buf_va).cpu[i/4].b[i%4] = i % enic->rq_count;
+
+ spin_lock(&enic->devcmd_lock);
+ err = enic_set_rss_cpu(enic,
+ rss_cpu_buf_pa,
+ sizeof(union vnic_rss_cpu));
+ spin_unlock(&enic->devcmd_lock);
+
+ pci_free_consistent(enic->pdev, sizeof(union vnic_rss_cpu),
+ rss_cpu_buf_va, rss_cpu_buf_pa);
+
+ return err;
+}
+
+static int enic_set_niccfg(struct enic *enic, u8 rss_default_cpu,
+ u8 rss_hash_type, u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable)
{
- const u8 rss_default_cpu = 0;
- const u8 rss_hash_type = 0;
- const u8 rss_hash_bits = 0;
- const u8 rss_base_cpu = 0;
- const u8 rss_enable = 0;
const u8 tso_ipid_split_en = 0;
const u8 ig_vlan_strip_en = 1;
int err;
- /* Enable VLAN tag stripping. RSS not enabled (yet).
- */
+ /* Enable VLAN tag stripping.
+ */
spin_lock(&enic->devcmd_lock);
err = enic_set_nic_cfg(enic,
@@ -1959,6 +2119,35 @@ static int enic_set_niccfg(struct enic *enic)
return err;
}
+static int enic_set_rss_nic_cfg(struct enic *enic)
+{
+ struct device *dev = enic_get_dev(enic);
+ const u8 rss_default_cpu = 0;
+ const u8 rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4 |
+ NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 |
+ NIC_CFG_RSS_HASH_TYPE_IPV6 |
+ NIC_CFG_RSS_HASH_TYPE_TCP_IPV6;
+ const u8 rss_hash_bits = 7;
+ const u8 rss_base_cpu = 0;
+ u8 rss_enable = ENIC_SETTING(enic, RSS) && (enic->rq_count > 1);
+
+ if (rss_enable) {
+ if (!enic_set_rsskey(enic)) {
+ if (enic_set_rsscpu(enic, rss_hash_bits)) {
+ rss_enable = 0;
+ dev_warn(dev, "RSS disabled, "
+ "Failed to set RSS cpu indirection table.");
+ }
+ } else {
+ rss_enable = 0;
+ dev_warn(dev, "RSS disabled, Failed to set RSS key.\n");
+ }
+ }
+
+ return enic_set_niccfg(enic, rss_default_cpu, rss_hash_type,
+ rss_hash_bits, rss_base_cpu, rss_enable);
+}
+
static int enic_dev_hang_notify(struct enic *enic)
{
int err;
@@ -1970,7 +2159,7 @@ static int enic_dev_hang_notify(struct enic *enic)
return err;
}
-int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
+static int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
{
int err;
@@ -1996,7 +2185,7 @@ static void enic_reset(struct work_struct *work)
enic_dev_hang_reset(enic);
enic_reset_multicast_list(enic);
enic_init_vnic_resources(enic);
- enic_set_niccfg(enic);
+ enic_set_rss_nic_cfg(enic);
enic_dev_set_ig_vlan_rewrite_mode(enic);
enic_open(enic->netdev);
@@ -2005,12 +2194,12 @@ static void enic_reset(struct work_struct *work)
static int enic_set_intr_mode(struct enic *enic)
{
- unsigned int n = 1;
+ unsigned int n = min_t(unsigned int, enic->rq_count, ENIC_RQ_MAX);
unsigned int m = 1;
unsigned int i;
/* Set interrupt mode (INTx, MSI, MSI-X) depending
- * system capabilities.
+ * on system capabilities.
*
* Try MSI-X first
*
@@ -2023,21 +2212,47 @@ static int enic_set_intr_mode(struct enic *enic)
for (i = 0; i < n + m + 2; i++)
enic->msix_entry[i].entry = i;
- if (enic->config.intr_mode < 1 &&
+ /* Use multiple RQs if RSS is enabled
+ */
+
+ if (ENIC_SETTING(enic, RSS) &&
+ enic->config.intr_mode < 1 &&
enic->rq_count >= n &&
enic->wq_count >= m &&
enic->cq_count >= n + m &&
- enic->intr_count >= n + m + 2 &&
- !pci_enable_msix(enic->pdev, enic->msix_entry, n + m + 2)) {
+ enic->intr_count >= n + m + 2) {
- enic->rq_count = n;
- enic->wq_count = m;
- enic->cq_count = n + m;
- enic->intr_count = n + m + 2;
+ if (!pci_enable_msix(enic->pdev, enic->msix_entry, n + m + 2)) {
- vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_MSIX);
+ enic->rq_count = n;
+ enic->wq_count = m;
+ enic->cq_count = n + m;
+ enic->intr_count = n + m + 2;
- return 0;
+ vnic_dev_set_intr_mode(enic->vdev,
+ VNIC_DEV_INTR_MODE_MSIX);
+
+ return 0;
+ }
+ }
+
+ if (enic->config.intr_mode < 1 &&
+ enic->rq_count >= 1 &&
+ enic->wq_count >= m &&
+ enic->cq_count >= 1 + m &&
+ enic->intr_count >= 1 + m + 2) {
+ if (!pci_enable_msix(enic->pdev, enic->msix_entry, 1 + m + 2)) {
+
+ enic->rq_count = 1;
+ enic->wq_count = m;
+ enic->cq_count = 1 + m;
+ enic->intr_count = 1 + m + 2;
+
+ vnic_dev_set_intr_mode(enic->vdev,
+ VNIC_DEV_INTR_MODE_MSIX);
+
+ return 0;
+ }
}
/* Next try MSI
@@ -2145,28 +2360,22 @@ static const struct net_device_ops enic_netdev_ops = {
#endif
};
-void enic_dev_deinit(struct enic *enic)
+static void enic_dev_deinit(struct enic *enic)
{
- netif_napi_del(&enic->napi);
- enic_free_vnic_resources(enic);
- enic_clear_intr_mode(enic);
-}
-
-static int enic_dev_stats_clear(struct enic *enic)
-{
- int err;
+ unsigned int i;
- spin_lock(&enic->devcmd_lock);
- err = vnic_dev_stats_clear(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ for (i = 0; i < enic->rq_count; i++)
+ netif_napi_del(&enic->napi[i]);
- return err;
+ enic_free_vnic_resources(enic);
+ enic_clear_intr_mode(enic);
}
-int enic_dev_init(struct enic *enic)
+static int enic_dev_init(struct enic *enic)
{
struct device *dev = enic_get_dev(enic);
struct net_device *netdev = enic->netdev;
+ unsigned int i;
int err;
/* Get vNIC configuration
@@ -2205,17 +2414,13 @@ int enic_dev_init(struct enic *enic)
enic_init_vnic_resources(enic);
- /* Clear LIF stats
- */
- enic_dev_stats_clear(enic);
-
err = enic_set_rq_alloc_buf(enic);
if (err) {
dev_err(dev, "Failed to set RQ buffer allocator, aborting\n");
goto err_out_free_vnic_resources;
}
- err = enic_set_niccfg(enic);
+ err = enic_set_rss_nic_cfg(enic);
if (err) {
dev_err(dev, "Failed to config nic, aborting\n");
goto err_out_free_vnic_resources;
@@ -2223,17 +2428,19 @@ int enic_dev_init(struct enic *enic)
err = enic_dev_set_ig_vlan_rewrite_mode(enic);
if (err) {
- netdev_err(netdev,
+ dev_err(dev,
"Failed to set ingress vlan rewrite mode, aborting.\n");
goto err_out_free_vnic_resources;
}
switch (vnic_dev_get_intr_mode(enic->vdev)) {
default:
- netif_napi_add(netdev, &enic->napi, enic_poll, 64);
+ netif_napi_add(netdev, &enic->napi[0], enic_poll, 64);
break;
case VNIC_DEV_INTR_MODE_MSIX:
- netif_napi_add(netdev, &enic->napi, enic_poll_msix, 64);
+ for (i = 0; i < enic->rq_count; i++)
+ netif_napi_add(netdev, &enic->napi[i],
+ enic_poll_msix, 64);
break;
}
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 29ede8a17a2c..f111a37419ce 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -94,13 +94,14 @@ int enic_get_vnic_config(struct enic *enic)
INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
c->intr_timer_usec);
- dev_info(enic_get_dev(enic), "vNIC MAC addr %pM wq/rq %d/%d\n",
- enic->mac_addr, c->wq_desc_count, c->rq_desc_count);
- dev_info(enic_get_dev(enic), "vNIC mtu %d csum tx/rx %d/%d "
- "tso/lro %d/%d intr timer %d usec\n",
- c->mtu, ENIC_SETTING(enic, TXCSUM),
- ENIC_SETTING(enic, RXCSUM), ENIC_SETTING(enic, TSO),
- ENIC_SETTING(enic, LRO), c->intr_timer_usec);
+ dev_info(enic_get_dev(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",
+ ENIC_SETTING(enic, TXCSUM), ENIC_SETTING(enic, RXCSUM),
+ ENIC_SETTING(enic, TSO), ENIC_SETTING(enic, LRO),
+ c->intr_timer_usec, ENIC_SETTING(enic, RSS));
return 0;
}
@@ -181,18 +182,11 @@ void enic_free_vnic_resources(struct enic *enic)
void enic_get_res_counts(struct enic *enic)
{
- enic->wq_count = min_t(int,
- vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ),
- ENIC_WQ_MAX);
- enic->rq_count = min_t(int,
- vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ),
- ENIC_RQ_MAX);
- enic->cq_count = min_t(int,
- vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ),
- ENIC_CQ_MAX);
- enic->intr_count = min_t(int,
- vnic_dev_get_res_count(enic->vdev, RES_TYPE_INTR_CTRL),
- ENIC_INTR_MAX);
+ enic->wq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ);
+ enic->rq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ);
+ enic->cq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ);
+ enic->intr_count = vnic_dev_get_res_count(enic->vdev,
+ RES_TYPE_INTR_CTRL);
dev_info(enic_get_dev(enic),
"vNIC resources avail: wq %d rq %d cq %d intr %d\n",
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 83bd172c356c..9a103d9ef9e2 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -30,7 +30,7 @@
#define ENIC_MIN_RQ_DESCS 64
#define ENIC_MAX_RQ_DESCS 4096
-#define ENIC_MIN_MTU 576 /* minimum for IPv4 */
+#define ENIC_MIN_MTU 68
#define ENIC_MAX_MTU 9000
#define ENIC_MULTICAST_PERFECT_FILTERS 32
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 6a5b578a69e1..fb35d8b17668 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -74,6 +74,7 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
struct vnic_dev_bar *bar, unsigned int num_bars)
{
struct vnic_resource_header __iomem *rh;
+ struct mgmt_barmap_hdr __iomem *mrh;
struct vnic_resource __iomem *r;
u8 type;
@@ -85,22 +86,32 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
return -EINVAL;
}
- rh = bar->vaddr;
+ rh = bar->vaddr;
+ mrh = bar->vaddr;
if (!rh) {
pr_err("vNIC BAR0 res hdr not mem-mapped\n");
return -EINVAL;
}
- if (ioread32(&rh->magic) != VNIC_RES_MAGIC ||
- ioread32(&rh->version) != VNIC_RES_VERSION) {
- pr_err("vNIC BAR0 res magic/version error "
- "exp (%lx/%lx) curr (%x/%x)\n",
+ /* Check for mgmt vnic in addition to normal vnic */
+ if ((ioread32(&rh->magic) != VNIC_RES_MAGIC) ||
+ (ioread32(&rh->version) != VNIC_RES_VERSION)) {
+ if ((ioread32(&mrh->magic) != MGMTVNIC_MAGIC) ||
+ (ioread32(&mrh->version) != MGMTVNIC_VERSION)) {
+ pr_err("vNIC BAR0 res magic/version error "
+ "exp (%lx/%lx) or (%lx/%lx), curr (%x/%x)\n",
VNIC_RES_MAGIC, VNIC_RES_VERSION,
+ MGMTVNIC_MAGIC, MGMTVNIC_VERSION,
ioread32(&rh->magic), ioread32(&rh->version));
- return -EINVAL;
+ return -EINVAL;
+ }
}
- r = (struct vnic_resource __iomem *)(rh + 1);
+ if (ioread32(&mrh->magic) == MGMTVNIC_MAGIC)
+ r = (struct vnic_resource __iomem *)(mrh + 1);
+ else
+ r = (struct vnic_resource __iomem *)(rh + 1);
+
while ((type = ioread8(&r->type)) != RES_TYPE_EOL) {
@@ -175,22 +186,7 @@ void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
}
}
-dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev,
- enum vnic_res_type type, unsigned int index)
-{
- switch (type) {
- case RES_TYPE_WQ:
- case RES_TYPE_RQ:
- case RES_TYPE_CQ:
- case RES_TYPE_INTR_CTRL:
- return vdev->res[type].bus_addr +
- index * VNIC_RES_STRIDE;
- default:
- return vdev->res[type].bus_addr;
- }
-}
-
-unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring,
+static unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring,
unsigned int desc_count, unsigned int desc_size)
{
/* The base address of the desc rings must be 512 byte aligned.
@@ -373,18 +369,6 @@ static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev,
return err;
}
-void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf)
-{
- vdev->proxy = PROXY_BY_BDF;
- vdev->proxy_index = bdf;
-}
-
-void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev)
-{
- vdev->proxy = PROXY_NONE;
- vdev->proxy_index = 0;
-}
-
int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
u64 *a0, u64 *a1, int wait)
{
@@ -477,13 +461,6 @@ int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
return err;
}
-int vnic_dev_stats_clear(struct vnic_dev *vdev)
-{
- u64 a0 = 0, a1 = 0;
- int wait = 1000;
- return vnic_dev_cmd(vdev, CMD_STATS_CLEAR, &a0, &a1, wait);
-}
-
int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats)
{
u64 a0, a1;
@@ -510,13 +487,6 @@ int vnic_dev_close(struct vnic_dev *vdev)
return vnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait);
}
-int vnic_dev_enable(struct vnic_dev *vdev)
-{
- u64 a0 = 0, a1 = 0;
- int wait = 1000;
- return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait);
-}
-
int vnic_dev_enable_wait(struct vnic_dev *vdev)
{
u64 a0 = 0, a1 = 0;
@@ -561,14 +531,14 @@ int vnic_dev_open_done(struct vnic_dev *vdev, int *done)
return 0;
}
-int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg)
+static int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg)
{
u64 a0 = (u32)arg, a1 = 0;
int wait = 1000;
return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait);
}
-int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
+static int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
{
u64 a0 = 0, a1 = 0;
int wait = 1000;
@@ -669,26 +639,6 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
return err;
}
-int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed,
- int multicast, int broadcast, int promisc, int allmulti)
-{
- u64 a0, a1 = 0;
- int wait = 1000;
- int err;
-
- a0 = (directed ? CMD_PFILTER_DIRECTED : 0) |
- (multicast ? CMD_PFILTER_MULTICAST : 0) |
- (broadcast ? CMD_PFILTER_BROADCAST : 0) |
- (promisc ? CMD_PFILTER_PROMISCUOUS : 0) |
- (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0);
-
- err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER_ALL, &a0, &a1, wait);
- if (err)
- pr_err("Can't set packet filter\n");
-
- return err;
-}
-
int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
{
u64 a0 = 0, a1 = 0;
@@ -737,20 +687,7 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
return err;
}
-int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr)
-{
- u64 a0 = intr, a1 = 0;
- int wait = 1000;
- int err;
-
- err = vnic_dev_cmd(vdev, CMD_IAR, &a0, &a1, wait);
- if (err)
- pr_err("Failed to raise INTR[%d], err %d\n", intr, err);
-
- return err;
-}
-
-int vnic_dev_notify_setcmd(struct vnic_dev *vdev,
+static int vnic_dev_notify_setcmd(struct vnic_dev *vdev,
void *notify_addr, dma_addr_t notify_pa, u16 intr)
{
u64 a0, a1;
@@ -789,7 +726,7 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr);
}
-int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev)
+static int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev)
{
u64 a0, a1;
int wait = 1000;
@@ -943,30 +880,6 @@ u32 vnic_dev_mtu(struct vnic_dev *vdev)
return vdev->notify_copy.mtu;
}
-u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev)
-{
- if (!vnic_dev_notify_ready(vdev))
- return 0;
-
- return vdev->notify_copy.link_down_cnt;
-}
-
-u32 vnic_dev_notify_status(struct vnic_dev *vdev)
-{
- if (!vnic_dev_notify_ready(vdev))
- return 0;
-
- return vdev->notify_copy.status;
-}
-
-u32 vnic_dev_uif(struct vnic_dev *vdev)
-{
- if (!vnic_dev_notify_ready(vdev))
- return 0;
-
- return vdev->notify_copy.uif;
-}
-
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
enum vnic_dev_intr_mode intr_mode)
{
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index 3a61873138b6..05f9a24cd459 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -84,10 +84,6 @@ unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev,
enum vnic_res_type type);
void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
unsigned int index);
-dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev,
- enum vnic_res_type type, unsigned int index);
-unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring,
- unsigned int desc_count, unsigned int desc_size);
void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring);
int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring,
unsigned int desc_count, unsigned int desc_size);
@@ -95,39 +91,26 @@ void vnic_dev_free_desc_ring(struct vnic_dev *vdev,
struct vnic_dev_ring *ring);
int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
u64 *a0, u64 *a1, int wait);
-void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf);
-void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev);
int vnic_dev_fw_info(struct vnic_dev *vdev,
struct vnic_devcmd_fw_info **fw_info);
int vnic_dev_hw_version(struct vnic_dev *vdev,
enum vnic_dev_hw_version *hw_ver);
int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
void *value);
-int vnic_dev_stats_clear(struct vnic_dev *vdev);
int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats);
int vnic_dev_hang_notify(struct vnic_dev *vdev);
int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
int broadcast, int promisc, int allmulti);
-int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed,
- int multicast, int broadcast, int promisc, int allmulti);
int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr);
int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr);
int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr);
-int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr);
-int vnic_dev_notify_setcmd(struct vnic_dev *vdev,
- void *notify_addr, dma_addr_t notify_pa, u16 intr);
int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr);
-int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev);
int vnic_dev_notify_unset(struct vnic_dev *vdev);
int vnic_dev_link_status(struct vnic_dev *vdev);
u32 vnic_dev_port_speed(struct vnic_dev *vdev);
u32 vnic_dev_msg_lvl(struct vnic_dev *vdev);
u32 vnic_dev_mtu(struct vnic_dev *vdev);
-u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev);
-u32 vnic_dev_notify_status(struct vnic_dev *vdev);
-u32 vnic_dev_uif(struct vnic_dev *vdev);
int vnic_dev_close(struct vnic_dev *vdev);
-int vnic_dev_enable(struct vnic_dev *vdev);
int vnic_dev_enable_wait(struct vnic_dev *vdev);
int vnic_dev_disable(struct vnic_dev *vdev);
int vnic_dev_open(struct vnic_dev *vdev, int arg);
@@ -136,8 +119,6 @@ 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_soft_reset(struct vnic_dev *vdev, int arg);
-int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done);
int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg);
int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done);
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index 20661755df6b..9abb3d51dea1 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -238,6 +238,18 @@ enum vnic_devcmd_cmd {
* out: (u32)a0=status of proxied cmd
* a1-a15=out args of proxied cmd */
CMD_PROXY_BY_BDF = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 42),
+
+ /*
+ * As for BY_BDF except a0 is index of hvnlink subordinate 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 */
+ CMD_CONFIG_INFO_GET = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 44),
};
/* flags for CMD_OPEN */
diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h
index 3b3291248956..e8740e3704e4 100644
--- a/drivers/net/enic/vnic_enet.h
+++ b/drivers/net/enic/vnic_enet.h
@@ -30,7 +30,7 @@ struct vnic_enet_config {
u32 wq_desc_count;
u32 rq_desc_count;
u16 mtu;
- u16 intr_timer;
+ u16 intr_timer_deprecated;
u8 intr_timer_type;
u8 intr_mode;
char devname[16];
diff --git a/drivers/net/enic/vnic_intr.c b/drivers/net/enic/vnic_intr.c
index 52ab61af2750..3873771d75cc 100644
--- a/drivers/net/enic/vnic_intr.c
+++ b/drivers/net/enic/vnic_intr.c
@@ -65,8 +65,3 @@ void vnic_intr_clean(struct vnic_intr *intr)
{
iowrite32(0, &intr->ctrl->int_credits);
}
-
-void vnic_intr_raise(struct vnic_intr *intr)
-{
- vnic_dev_raise_intr(intr->vdev, (u16)intr->index);
-}
diff --git a/drivers/net/enic/vnic_resource.h b/drivers/net/enic/vnic_resource.h
index 810287beff14..e0a73f1ca6f4 100644
--- a/drivers/net/enic/vnic_resource.h
+++ b/drivers/net/enic/vnic_resource.h
@@ -22,6 +22,11 @@
#define VNIC_RES_MAGIC 0x766E6963L /* 'vnic' */
#define VNIC_RES_VERSION 0x00000000L
+#define MGMTVNIC_MAGIC 0x544d474dL /* 'MGMT' */
+#define MGMTVNIC_VERSION 0x00000000L
+
+/* The MAC address assigned to the CFG vNIC is fixed. */
+#define MGMTVNIC_MAC { 0x02, 0x00, 0x54, 0x4d, 0x47, 0x4d }
/* vNIC resource types */
enum vnic_res_type {
@@ -52,6 +57,14 @@ struct vnic_resource_header {
u32 version;
};
+struct mgmt_barmap_hdr {
+ u32 magic; /* magic number */
+ u32 version; /* header format version */
+ u16 lif; /* loopback lif for mgmt frames */
+ u16 pci_slot; /* installed pci slot */
+ char serial[16]; /* card serial number */
+};
+
struct vnic_resource {
u8 type;
u8 bar;
diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c
index dbb2aca258b9..34105e0951a5 100644
--- a/drivers/net/enic/vnic_rq.c
+++ b/drivers/net/enic/vnic_rq.c
@@ -77,8 +77,10 @@ void vnic_rq_free(struct vnic_rq *rq)
vnic_dev_free_desc_ring(vdev, &rq->ring);
for (i = 0; i < VNIC_RQ_BUF_BLKS_MAX; i++) {
- kfree(rq->bufs[i]);
- rq->bufs[i] = NULL;
+ if (rq->bufs[i]) {
+ kfree(rq->bufs[i]);
+ rq->bufs[i] = NULL;
+ }
}
rq->ctrl = NULL;
@@ -113,7 +115,7 @@ int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
return 0;
}
-void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
+static void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
unsigned int fetch_index, unsigned int posted_index,
unsigned int error_interrupt_enable,
unsigned int error_interrupt_offset)
diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h
index 2dc48f91abf7..37f08de2454a 100644
--- a/drivers/net/enic/vnic_rq.h
+++ b/drivers/net/enic/vnic_rq.h
@@ -143,7 +143,7 @@ static inline void vnic_rq_post(struct vnic_rq *rq,
static inline int vnic_rq_posting_soon(struct vnic_rq *rq)
{
- return ((rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0);
+ return (rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0;
}
static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count)
@@ -202,10 +202,6 @@ static inline int vnic_rq_fill(struct vnic_rq *rq,
void vnic_rq_free(struct vnic_rq *rq);
int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
unsigned int desc_count, unsigned int desc_size);
-void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
- unsigned int fetch_index, unsigned int posted_index,
- unsigned int error_interrupt_enable,
- unsigned int error_interrupt_offset);
void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
unsigned int error_interrupt_enable,
unsigned int error_interrupt_offset);
diff --git a/drivers/net/enic/vnic_rss.h b/drivers/net/enic/vnic_rss.h
index f62d18719629..fa421baf45b8 100644
--- a/drivers/net/enic/vnic_rss.h
+++ b/drivers/net/enic/vnic_rss.h
@@ -37,9 +37,4 @@ union vnic_rss_cpu {
u64 raw[32];
};
-void vnic_set_rss_key(union vnic_rss_key *rss_key, u8 *key);
-void vnic_set_rss_cpu(union vnic_rss_cpu *rss_cpu, u8 *cpu);
-void vnic_get_rss_key(union vnic_rss_key *rss_key, u8 *key);
-void vnic_get_rss_cpu(union vnic_rss_cpu *rss_cpu, u8 *cpu);
-
#endif /* _VNIC_RSS_H_ */
diff --git a/drivers/net/enic/vnic_vic.c b/drivers/net/enic/vnic_vic.c
index 197c9d24af82..4725b79de0ef 100644
--- a/drivers/net/enic/vnic_vic.c
+++ b/drivers/net/enic/vnic_vic.c
@@ -54,8 +54,8 @@ int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
if (!vp || !value)
return -EINVAL;
- if (ntohl(vp->length) + sizeof(*tlv) + length >
- VIC_PROVINFO_MAX_TLV_DATA)
+ if (ntohl(vp->length) + offsetof(struct vic_provinfo_tlv, value) +
+ length > VIC_PROVINFO_MAX_TLV_DATA)
return -ENOMEM;
tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv +
@@ -66,7 +66,8 @@ int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
memcpy(tlv->value, value, length);
vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1);
- vp->length = htonl(ntohl(vp->length) + sizeof(*tlv) + length);
+ vp->length = htonl(ntohl(vp->length) +
+ offsetof(struct vic_provinfo_tlv, value) + length);
return 0;
}
diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c
index 122e33bcc578..df61bd932ea6 100644
--- a/drivers/net/enic/vnic_wq.c
+++ b/drivers/net/enic/vnic_wq.c
@@ -77,8 +77,10 @@ void vnic_wq_free(struct vnic_wq *wq)
vnic_dev_free_desc_ring(vdev, &wq->ring);
for (i = 0; i < VNIC_WQ_BUF_BLKS_MAX; i++) {
- kfree(wq->bufs[i]);
- wq->bufs[i] = NULL;
+ if (wq->bufs[i]) {
+ kfree(wq->bufs[i]);
+ wq->bufs[i] = NULL;
+ }
}
wq->ctrl = NULL;
@@ -113,7 +115,7 @@ int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
return 0;
}
-void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
+static void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
unsigned int fetch_index, unsigned int posted_index,
unsigned int error_interrupt_enable,
unsigned int error_interrupt_offset)
diff --git a/drivers/net/enic/vnic_wq.h b/drivers/net/enic/vnic_wq.h
index 94ac4621acc5..7dd937ac11c2 100644
--- a/drivers/net/enic/vnic_wq.h
+++ b/drivers/net/enic/vnic_wq.h
@@ -153,10 +153,6 @@ static inline void vnic_wq_service(struct vnic_wq *wq,
void vnic_wq_free(struct vnic_wq *wq);
int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
unsigned int desc_count, unsigned int desc_size);
-void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
- unsigned int fetch_index, unsigned int posted_index,
- unsigned int error_interrupt_enable,
- unsigned int error_interrupt_offset);
void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
unsigned int error_interrupt_enable,
unsigned int error_interrupt_offset);
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 57c8ac0ef3f1..32543a300b81 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -758,7 +758,7 @@ static int epic_open(struct net_device *dev)
init_timer(&ep->timer);
ep->timer.expires = jiffies + 3*HZ;
ep->timer.data = (unsigned long)dev;
- ep->timer.function = &epic_timer; /* timer handler */
+ ep->timer.function = epic_timer; /* timer handler */
add_timer(&ep->timer);
return 0;
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index 10e39f2b31c3..fb717be511f6 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -637,7 +637,9 @@ static void eth16i_initialize(struct net_device *dev, int boot)
/* Set interface port type */
if(boot) {
- char *porttype[] = {"BNC", "DIX", "TP", "AUTO", "FROM_EPROM" };
+ static const char * const porttype[] = {
+ "BNC", "DIX", "TP", "AUTO", "FROM_EPROM"
+ };
switch(dev->if_port)
{
@@ -794,7 +796,7 @@ static int eth16i_receive_probe_packet(int ioaddr)
if(eth16i_debug > 1)
printk(KERN_DEBUG "RECEIVE_PACKET\n");
- return(0); /* Found receive packet */
+ return 0; /* Found receive packet */
}
}
@@ -803,7 +805,7 @@ static int eth16i_receive_probe_packet(int ioaddr)
printk(KERN_DEBUG "RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG));
}
- return(0); /* Return success */
+ return 0; /* Return success */
}
#if 0
@@ -839,7 +841,7 @@ static int __init eth16i_get_irq(int ioaddr)
if( ioaddr < 0x1000) {
cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
- return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
+ return eth16i_irqmap[((cbyte & 0xC0) >> 6)];
} else { /* Oh..the card is EISA so method getting IRQ different */
unsigned short index = 0;
cbyte = inb(ioaddr + EISA_IRQ_REG);
@@ -847,7 +849,7 @@ static int __init eth16i_get_irq(int ioaddr)
cbyte = cbyte >> 1;
index++;
}
- return( eth32i_irqmap[ index ] );
+ return eth32i_irqmap[index];
}
}
@@ -907,7 +909,7 @@ static int eth16i_read_eeprom(int ioaddr, int offset)
data = eth16i_read_eeprom_word(ioaddr);
outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
- return(data);
+ return data;
}
static int eth16i_read_eeprom_word(int ioaddr)
@@ -926,7 +928,7 @@ static int eth16i_read_eeprom_word(int ioaddr)
eeprom_slow_io();
}
- return(data);
+ return data;
}
static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 6d653c459c1f..c5a2fe099a8d 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -806,11 +806,6 @@ static void ethoc_tx_timeout(struct net_device *dev)
ethoc_interrupt(dev->irq, dev);
}
-static struct net_device_stats *ethoc_stats(struct net_device *dev)
-{
- return &dev->stats;
-}
-
static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ethoc *priv = netdev_priv(dev);
@@ -863,7 +858,6 @@ static const struct net_device_ops ethoc_netdev_ops = {
.ndo_set_multicast_list = ethoc_set_multicast_list,
.ndo_change_mtu = ethoc_change_mtu,
.ndo_tx_timeout = ethoc_tx_timeout,
- .ndo_get_stats = ethoc_stats,
.ndo_start_xmit = ethoc_start_xmit,
};
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index d7e8f6b8f4cf..dd54abe2f710 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -915,14 +915,14 @@ static int netdev_open(struct net_device *dev)
init_timer(&np->timer);
np->timer.expires = RUN_AT(3 * HZ);
np->timer.data = (unsigned long) dev;
- np->timer.function = &netdev_timer;
+ np->timer.function = netdev_timer;
/* timer handler */
add_timer(&np->timer);
init_timer(&np->reset_timer);
np->reset_timer.data = (unsigned long) dev;
- np->reset_timer.function = &reset_timer;
+ np->reset_timer.function = reset_timer;
np->reset_timer_armed = 0;
return 0;
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index e3e10b4add9c..e9f5d030bc26 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -771,11 +771,6 @@ static void mpc52xx_fec_reset(struct net_device *dev)
/* ethtool interface */
-static void mpc52xx_fec_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRIVER_NAME);
-}
static int mpc52xx_fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
@@ -810,7 +805,6 @@ static void mpc52xx_fec_set_msglevel(struct net_device *dev, u32 level)
}
static const struct ethtool_ops mpc52xx_fec_ethtool_ops = {
- .get_drvinfo = mpc52xx_fec_get_drvinfo,
.get_settings = mpc52xx_fec_get_settings,
.set_settings = mpc52xx_fec_set_settings,
.get_link = ethtool_op_get_link,
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 4da05b1b445c..0fa1776563a3 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2321,14 +2321,11 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0;
/* vlan tag */
- if (likely(!np->vlangrp)) {
+ if (vlan_tx_tag_present(skb))
+ start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT |
+ vlan_tx_tag_get(skb));
+ else
start_tx->txvlan = 0;
- } else {
- if (vlan_tx_tag_present(skb))
- start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb));
- else
- start_tx->txvlan = 0;
- }
spin_lock_irqsave(&np->lock, flags);
@@ -4620,7 +4617,7 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam*
static u32 nv_get_rx_csum(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
- return (np->rx_csum) != 0;
+ return np->rx_csum != 0;
}
static int nv_set_rx_csum(struct net_device *dev, u32 data)
@@ -5440,13 +5437,13 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
init_timer(&np->oom_kick);
np->oom_kick.data = (unsigned long) dev;
- np->oom_kick.function = &nv_do_rx_refill; /* timer handler */
+ np->oom_kick.function = nv_do_rx_refill; /* timer handler */
init_timer(&np->nic_poll);
np->nic_poll.data = (unsigned long) dev;
- np->nic_poll.function = &nv_do_nic_poll; /* timer handler */
+ np->nic_poll.function = nv_do_nic_poll; /* timer handler */
init_timer(&np->stats_poll);
np->stats_poll.data = (unsigned long) dev;
- np->stats_poll.function = &nv_do_stats_poll; /* timer handler */
+ np->stats_poll.function = nv_do_stats_poll; /* timer handler */
err = pci_enable_device(pci_dev);
if (err)
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index d6e3111959ab..d684f187de57 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -1036,7 +1036,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev,
ndev = alloc_etherdev(privsize);
if (!ndev) {
ret = -ENOMEM;
- goto out_free_fpi;
+ goto out_put;
}
SET_NETDEV_DEV(ndev, &ofdev->dev);
@@ -1099,6 +1099,7 @@ out_cleanup_data:
out_free_dev:
free_netdev(ndev);
dev_set_drvdata(&ofdev->dev, NULL);
+out_put:
of_node_put(fpi->phy_node);
out_free_fpi:
kfree(fpi);
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c
index d4bf91aac25f..8d3a2ccbc953 100644
--- a/drivers/net/fsl_pq_mdio.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -125,7 +125,7 @@ int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus);
/* Write to the local MII regs */
- return(fsl_pq_local_mdio_write(regs, mii_id, regnum, value));
+ return fsl_pq_local_mdio_write(regs, mii_id, regnum, value);
}
/*
@@ -137,7 +137,7 @@ int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus);
/* Read the local MII regs */
- return(fsl_pq_local_mdio_read(regs, mii_id, regnum));
+ return fsl_pq_local_mdio_read(regs, mii_id, regnum);
}
/* Reset the MIIM registers, and wait for the bus to free */
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 4f7c3f3ca234..4c4cc80ec0a1 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -654,9 +654,8 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
priv->node = ofdev->dev.of_node;
priv->ndev = dev;
- dev->num_tx_queues = num_tx_qs;
- dev->real_num_tx_queues = num_tx_qs;
priv->num_tx_queues = num_tx_qs;
+ netif_set_real_num_rx_queues(dev, num_rx_qs);
priv->num_rx_queues = num_rx_qs;
priv->num_grps = 0x0;
@@ -1859,7 +1858,7 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
printk(KERN_ERR "%s: Can't get IRQ %d\n",
dev->name, grp->interruptError);
- goto err_irq_fail;
+ goto err_irq_fail;
}
if ((err = request_irq(grp->interruptTransmit, gfar_transmit,
@@ -2048,7 +2047,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 bufaddr;
unsigned long flags;
unsigned int nr_frags, nr_txbds, length;
- union skb_shared_tx *shtx;
/*
* TOE=1 frames larger than 2500 bytes may see excess delays
@@ -2069,15 +2067,15 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txq = netdev_get_tx_queue(dev, rq);
base = tx_queue->tx_bd_base;
regs = tx_queue->grp->regs;
- shtx = skb_tx(skb);
/* check if time stamp should be generated */
- if (unlikely(shtx->hardware && priv->hwts_tx_en))
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+ priv->hwts_tx_en))
do_tstamp = 1;
/* make space for additional header when fcb is needed */
if (((skb->ip_summed == CHECKSUM_PARTIAL) ||
- (priv->vlgrp && vlan_tx_tag_present(skb)) ||
+ vlan_tx_tag_present(skb) ||
unlikely(do_tstamp)) &&
(skb_headroom(skb) < GMAC_FCB_LEN)) {
struct sk_buff *skb_new;
@@ -2163,7 +2161,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
gfar_tx_checksum(skb, fcb);
}
- if (priv->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
if (unlikely(NULL == fcb)) {
fcb = gfar_add_fcb(skb);
lstatus |= BD_LFLAG(TXBD_TOE);
@@ -2174,7 +2172,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Setup tx hardware time stamping if requested */
if (unlikely(do_tstamp)) {
- shtx->in_progress = 1;
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
if (fcb == NULL)
fcb = gfar_add_fcb(skb);
fcb->ptp = 1;
@@ -2446,7 +2444,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
int howmany = 0;
u32 lstatus;
size_t buflen;
- union skb_shared_tx *shtx;
rx_queue = priv->rx_queue[tx_queue->qindex];
bdp = tx_queue->dirty_tx;
@@ -2461,8 +2458,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
* When time stamping, one additional TxBD must be freed.
* Also, we need to dma_unmap_single() the TxPAL.
*/
- shtx = skb_tx(skb);
- if (unlikely(shtx->in_progress))
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
nr_txbds = frags + 2;
else
nr_txbds = frags + 1;
@@ -2476,7 +2472,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
(lstatus & BD_LENGTH_MASK))
break;
- if (unlikely(shtx->in_progress)) {
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
next = next_txbd(bdp, base, tx_ring_size);
buflen = next->length + GMAC_FCB_LEN;
} else
@@ -2485,7 +2481,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
buflen, DMA_TO_DEVICE);
- if (unlikely(shtx->in_progress)) {
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
struct skb_shared_hwtstamps shhwtstamps;
u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7);
memset(&shhwtstamps, 0, sizeof(shhwtstamps));
@@ -2657,7 +2653,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 9bda023c0235..5c566ebc54b8 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -254,7 +254,7 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int use
/* Make sure we return a number greater than 0
* if usecs > 0 */
- return ((usecs * 1000 + count - 1) / count);
+ return (usecs * 1000 + count - 1) / count;
}
/* Convert ethernet clock ticks to microseconds */
@@ -278,7 +278,7 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic
/* Make sure we return a number greater than 0 */
/* if ticks is > 0 */
- return ((ticks * count) / 1000);
+ return (ticks * count) / 1000;
}
/* Get the coalescing parameters, and put them in the cvals
@@ -538,7 +538,7 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
unlock_tx_qs(priv);
unlock_rx_qs(priv);
- local_irq_save(flags);
+ local_irq_restore(flags);
for (i = 0; i < priv->num_rx_queues; i++)
gfar_clean_rx_ring(priv->rx_queue[i],
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index f15c64f1cd38..27d6960ce09e 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -893,7 +893,7 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
if (greth->flags & GRETH_FLAG_RX_CSUM && hw_checksummed(status))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, dev);
dev->stats.rx_packets++;
@@ -1547,10 +1547,10 @@ static int __devinit greth_of_probe(struct platform_device *ofdev, const struct
dev->netdev_ops = &greth_netdev_ops;
dev->ethtool_ops = &greth_ethtool_ops;
- if (register_netdev(dev)) {
+ err = register_netdev(dev);
+ if (err) {
if (netif_msg_probe(greth))
dev_err(greth->dev, "netdevice registration failed.\n");
- err = -ENOMEM;
goto error5;
}
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 49aac7027fbb..9a6485892b3d 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1004,7 +1004,7 @@ static int hamachi_open(struct net_device *dev)
init_timer(&hmp->timer);
hmp->timer.expires = RUN_AT((24*HZ)/10); /* 2.4 sec. */
hmp->timer.data = (unsigned long)dev;
- hmp->timer.function = &hamachi_timer; /* timer handler */
+ hmp->timer.function = hamachi_timer; /* timer handler */
add_timer(&hmp->timer);
return 0;
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 14f01d156db9..ac1d323c5eb5 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -168,7 +168,7 @@ static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev)
static inline int dev_is_ethdev(struct net_device *dev)
{
- return (dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5));
+ return dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5);
}
/* ------------------------------------------------------------------------ */
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index b8bdf9d51cd4..5b37579e84b7 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -110,7 +110,7 @@ static int calc_crc_ccitt(const unsigned char *buf, int cnt)
for (; cnt > 0; cnt--)
crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
crc ^= 0xffff;
- return (crc & 0xffff);
+ return crc & 0xffff;
}
#endif
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index 9f64c8637208..33655814448e 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1069,7 +1069,8 @@ static void scc_tx_done(struct scc_channel *scc)
case KISS_DUPLEX_LINK:
scc->stat.tx_state = TXS_IDLE2;
if (scc->kiss.idletime != TIMER_OFF)
- scc_start_tx_timer(scc, t_idle, scc->kiss.idletime*100);
+ scc_start_tx_timer(scc, t_idle,
+ scc->kiss.idletime*100);
break;
case KISS_DUPLEX_OPTIMA:
scc_notify(scc, HWEV_ALL_SENT);
diff --git a/drivers/net/hp.c b/drivers/net/hp.c
index 86ececd3c658..d15d2f2ba78e 100644
--- a/drivers/net/hp.c
+++ b/drivers/net/hp.c
@@ -204,10 +204,10 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
ei_status.rx_start_page = HP_START_PG + TX_PAGES;
ei_status.stop_page = wordmode ? HP_16BSTOP_PG : HP_8BSTOP_PG;
- ei_status.reset_8390 = &hp_reset_8390;
- ei_status.get_8390_hdr = &hp_get_8390_hdr;
- ei_status.block_input = &hp_block_input;
- ei_status.block_output = &hp_block_output;
+ ei_status.reset_8390 = hp_reset_8390;
+ ei_status.get_8390_hdr = hp_get_8390_hdr;
+ ei_status.block_input = hp_block_input;
+ ei_status.block_output = hp_block_output;
hp_init_card(dev);
retval = register_netdev(dev);
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index 095b17ecf609..8e2c4601b5f5 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -1312,7 +1312,7 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr,
for (p = (ringptr->pdl); p < (ringptr->pdl + 5); p++)
printk("hp100: %s: Adr 0x%.8x = 0x%.8x\n", dev->name, (u_int) p, (u_int) * p);
#endif
- return (1);
+ return 1;
}
/* else: */
/* alloc_skb failed (no memory) -> still can receive the header
@@ -1325,7 +1325,7 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr,
ringptr->pdl[0] = 0x00010000; /* PDH: Count=1 Fragment */
- return (0);
+ return 0;
}
/*
@@ -2752,7 +2752,7 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
hp100_outw(HP100_MISC_ERROR, IRQ_STATUS);
if (val & HP100_LINK_UP_ST)
- return (0); /* login was ok */
+ return 0; /* login was ok */
else {
printk("hp100: %s: Training failed.\n", dev->name);
hp100_down_vg_link(dev);
diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c
index 07d8e5b634f3..c5ef62ceb840 100644
--- a/drivers/net/hydra.c
+++ b/drivers/net/hydra.c
@@ -155,10 +155,10 @@ static int __devinit hydra_init(struct zorro_dev *z)
ei_status.rx_start_page = start_page + TX_PAGES;
- ei_status.reset_8390 = &hydra_reset_8390;
- ei_status.block_input = &hydra_block_input;
- ei_status.block_output = &hydra_block_output;
- ei_status.get_8390_hdr = &hydra_get_8390_hdr;
+ ei_status.reset_8390 = hydra_reset_8390;
+ ei_status.block_input = hydra_block_input;
+ ei_status.block_output = hydra_block_output;
+ ei_status.get_8390_hdr = hydra_get_8390_hdr;
ei_status.reg_offset = hydra_offsets;
dev->netdev_ops = &hydra_netdev_ops;
@@ -173,9 +173,8 @@ static int __devinit hydra_init(struct zorro_dev *z)
zorro_set_drvdata(z, dev);
- printk(KERN_INFO "%s: Hydra at 0x%08llx, address "
- "%pM (hydra.c " HYDRA_VERSION ")\n",
- dev->name, (unsigned long long)z->resource.start, dev->dev_addr);
+ pr_info("%s: Hydra at %pR, address %pM (hydra.c " HYDRA_VERSION ")\n",
+ dev->name, &z->resource, dev->dev_addr);
return 0;
}
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 519e19e23955..385dc3204cb7 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2095,11 +2095,11 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf)
if (emac_has_feature(dev, EMAC_FTR_EMAC4)) {
hdr->version = EMAC4_ETHTOOL_REGS_VER;
memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev));
- return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev));
+ return (void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev);
} else {
hdr->version = EMAC_ETHTOOL_REGS_VER;
memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev));
- return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev));
+ return (void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev);
}
}
@@ -2293,7 +2293,7 @@ static int __devinit emac_check_deps(struct emac_instance *dev,
if (deps[i].drvdata != NULL)
there++;
}
- return (there == EMAC_DEP_COUNT);
+ return there == EMAC_DEP_COUNT;
}
static void emac_put_deps(struct emac_instance *dev)
diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h
index 9e37e3d9c51d..4fec0844d59d 100644
--- a/drivers/net/ibm_newemac/core.h
+++ b/drivers/net/ibm_newemac/core.h
@@ -410,7 +410,7 @@ static inline u32 *emac_xaht_base(struct emac_instance *dev)
else
offset = offsetof(struct emac_regs, u0.emac4.iaht1);
- return ((u32 *)((ptrdiff_t)p + offset));
+ return (u32 *)((ptrdiff_t)p + offset);
}
static inline u32 *emac_gaht_base(struct emac_instance *dev)
@@ -418,7 +418,7 @@ static inline u32 *emac_gaht_base(struct emac_instance *dev)
/* GAHT registers always come after an identical number of
* IAHT registers.
*/
- return (emac_xaht_base(dev) + EMAC_XAHT_REGS(dev));
+ return emac_xaht_base(dev) + EMAC_XAHT_REGS(dev);
}
static inline u32 *emac_iaht_base(struct emac_instance *dev)
@@ -426,7 +426,7 @@ static inline u32 *emac_iaht_base(struct emac_instance *dev)
/* IAHT registers always come before an identical number of
* GAHT registers.
*/
- return (emac_xaht_base(dev));
+ return emac_xaht_base(dev);
}
/* Ethtool get_regs complex data.
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
index 294ccfb427cf..0037a696cd0a 100644
--- a/drivers/net/ibmlana.c
+++ b/drivers/net/ibmlana.c
@@ -602,7 +602,7 @@ static void irqrx_handler(struct net_device *dev)
/* set up skb fields */
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* bookkeeping */
dev->stats.rx_packets++;
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 4734c939ad03..c454b45ca7ec 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1,122 +1,84 @@
-/**************************************************************************/
-/* */
-/* IBM eServer i/pSeries Virtual Ethernet Device Driver */
-/* Copyright (C) 2003 IBM Corp. */
-/* Originally written by Dave Larson (larson1@us.ibm.com) */
-/* Maintained by Santiago Leon (santil@us.ibm.com) */
-/* */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or */
-/* (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */
-/* USA */
-/* */
-/* This module contains the implementation of a virtual ethernet device */
-/* for use with IBM i/pSeries LPAR Linux. It utilizes the logical LAN */
-/* option of the RS/6000 Platform Architechture to interface with virtual */
-/* ethernet NICs that are presented to the partition by the hypervisor. */
-/* */
-/**************************************************************************/
/*
- TODO:
- - add support for sysfs
- - possibly remove procfs support
-*/
+ * IBM Power Virtual Ethernet Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2003, 2010
+ *
+ * Authors: Dave Larson <larson1@us.ibm.com>
+ * Santiago Leon <santil@linux.vnet.ibm.com>
+ * Brian King <brking@linux.vnet.ibm.com>
+ * Robert Jennings <rcj@linux.vnet.ibm.com>
+ * Anton Blanchard <anton@au.ibm.com>
+ */
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/errno.h>
-#include <linux/ioport.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
-#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/pm.h>
#include <linux/ethtool.h>
-#include <linux/proc_fs.h>
#include <linux/in.h>
#include <linux/ip.h>
+#include <linux/ipv6.h>
#include <linux/slab.h>
-#include <net/net_namespace.h>
#include <asm/hvcall.h>
#include <asm/atomic.h>
#include <asm/vio.h>
#include <asm/iommu.h>
-#include <asm/uaccess.h>
#include <asm/firmware.h>
-#include <linux/seq_file.h>
#include "ibmveth.h"
-#undef DEBUG
-
-#define ibmveth_printk(fmt, args...) \
- printk(KERN_DEBUG "%s: " fmt, __FILE__, ## args)
-
-#define ibmveth_error_printk(fmt, args...) \
- printk(KERN_ERR "(%s:%3.3d ua:%x) ERROR: " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args)
-
-#ifdef DEBUG
-#define ibmveth_debug_printk_no_adapter(fmt, args...) \
- printk(KERN_DEBUG "(%s:%3.3d): " fmt, __FILE__, __LINE__ , ## args)
-#define ibmveth_debug_printk(fmt, args...) \
- printk(KERN_DEBUG "(%s:%3.3d ua:%x): " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args)
-#define ibmveth_assert(expr) \
- if(!(expr)) { \
- printk(KERN_DEBUG "assertion failed (%s:%3.3d ua:%x): %s\n", __FILE__, __LINE__, adapter->vdev->unit_address, #expr); \
- BUG(); \
- }
-#else
-#define ibmveth_debug_printk_no_adapter(fmt, args...)
-#define ibmveth_debug_printk(fmt, args...)
-#define ibmveth_assert(expr)
-#endif
-
-static int ibmveth_open(struct net_device *dev);
-static int ibmveth_close(struct net_device *dev);
-static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-static int ibmveth_poll(struct napi_struct *napi, int budget);
-static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static void ibmveth_set_multicast_list(struct net_device *dev);
-static int ibmveth_change_mtu(struct net_device *dev, int new_mtu);
-static void ibmveth_proc_register_driver(void);
-static void ibmveth_proc_unregister_driver(void);
-static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
-static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter);
static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance);
static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter);
static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev);
-static struct kobj_type ktype_veth_pool;
+static struct kobj_type ktype_veth_pool;
-#ifdef CONFIG_PROC_FS
-#define IBMVETH_PROC_DIR "ibmveth"
-static struct proc_dir_entry *ibmveth_proc_dir;
-#endif
static const char ibmveth_driver_name[] = "ibmveth";
-static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet Driver";
-#define ibmveth_driver_version "1.03"
+static const char ibmveth_driver_string[] = "IBM Power Virtual Ethernet Driver";
+#define ibmveth_driver_version "1.04"
-MODULE_AUTHOR("Santiago Leon <santil@us.ibm.com>");
-MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver");
+MODULE_AUTHOR("Santiago Leon <santil@linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("IBM Power Virtual Ethernet Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(ibmveth_driver_version);
+static unsigned int tx_copybreak __read_mostly = 128;
+module_param(tx_copybreak, uint, 0644);
+MODULE_PARM_DESC(tx_copybreak,
+ "Maximum size of packet that is copied to a new buffer on transmit");
+
+static unsigned int rx_copybreak __read_mostly = 128;
+module_param(rx_copybreak, uint, 0644);
+MODULE_PARM_DESC(rx_copybreak,
+ "Maximum size of packet that is copied to a new buffer on receive");
+
+static unsigned int rx_flush __read_mostly = 0;
+module_param(rx_flush, uint, 0644);
+MODULE_PARM_DESC(rx_flush, "Flush receive buffers before use");
+
struct ibmveth_stat {
char name[ETH_GSTRING_LEN];
int offset;
@@ -128,12 +90,16 @@ struct ibmveth_stat {
struct ibmveth_stat ibmveth_stats[] = {
{ "replenish_task_cycles", IBMVETH_STAT_OFF(replenish_task_cycles) },
{ "replenish_no_mem", IBMVETH_STAT_OFF(replenish_no_mem) },
- { "replenish_add_buff_failure", IBMVETH_STAT_OFF(replenish_add_buff_failure) },
- { "replenish_add_buff_success", IBMVETH_STAT_OFF(replenish_add_buff_success) },
+ { "replenish_add_buff_failure",
+ IBMVETH_STAT_OFF(replenish_add_buff_failure) },
+ { "replenish_add_buff_success",
+ IBMVETH_STAT_OFF(replenish_add_buff_success) },
{ "rx_invalid_buffer", IBMVETH_STAT_OFF(rx_invalid_buffer) },
{ "rx_no_buffer", IBMVETH_STAT_OFF(rx_no_buffer) },
{ "tx_map_failed", IBMVETH_STAT_OFF(tx_map_failed) },
{ "tx_send_failed", IBMVETH_STAT_OFF(tx_send_failed) },
+ { "fw_enabled_ipv4_csum", IBMVETH_STAT_OFF(fw_ipv4_csum_support) },
+ { "fw_enabled_ipv6_csum", IBMVETH_STAT_OFF(fw_ipv6_csum_support) },
};
/* simple methods of getting data from the current rxq entry */
@@ -144,41 +110,44 @@ static inline u32 ibmveth_rxq_flags(struct ibmveth_adapter *adapter)
static inline int ibmveth_rxq_toggle(struct ibmveth_adapter *adapter)
{
- return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_TOGGLE) >> IBMVETH_RXQ_TOGGLE_SHIFT;
+ return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_TOGGLE) >>
+ IBMVETH_RXQ_TOGGLE_SHIFT;
}
static inline int ibmveth_rxq_pending_buffer(struct ibmveth_adapter *adapter)
{
- return (ibmveth_rxq_toggle(adapter) == adapter->rx_queue.toggle);
+ return ibmveth_rxq_toggle(adapter) == adapter->rx_queue.toggle;
}
static inline int ibmveth_rxq_buffer_valid(struct ibmveth_adapter *adapter)
{
- return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_VALID);
+ return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_VALID;
}
static inline int ibmveth_rxq_frame_offset(struct ibmveth_adapter *adapter)
{
- return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK);
+ return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK;
}
static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter)
{
- return (adapter->rx_queue.queue_addr[adapter->rx_queue.index].length);
+ return adapter->rx_queue.queue_addr[adapter->rx_queue.index].length;
}
static inline int ibmveth_rxq_csum_good(struct ibmveth_adapter *adapter)
{
- return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_CSUM_GOOD);
+ return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_CSUM_GOOD;
}
/* setup the initial settings for a buffer pool */
-static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool, u32 pool_index, u32 pool_size, u32 buff_size, u32 pool_active)
+static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool,
+ u32 pool_index, u32 pool_size,
+ u32 buff_size, u32 pool_active)
{
pool->size = pool_size;
pool->index = pool_index;
pool->buff_size = buff_size;
- pool->threshold = pool_size / 2;
+ pool->threshold = pool_size * 7 / 8;
pool->active = pool_active;
}
@@ -189,12 +158,11 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
pool->free_map = kmalloc(sizeof(u16) * pool->size, GFP_KERNEL);
- if(!pool->free_map) {
+ if (!pool->free_map)
return -1;
- }
pool->dma_addr = kmalloc(sizeof(dma_addr_t) * pool->size, GFP_KERNEL);
- if(!pool->dma_addr) {
+ if (!pool->dma_addr) {
kfree(pool->free_map);
pool->free_map = NULL;
return -1;
@@ -202,7 +170,7 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
pool->skbuff = kcalloc(pool->size, sizeof(void *), GFP_KERNEL);
- if(!pool->skbuff) {
+ if (!pool->skbuff) {
kfree(pool->dma_addr);
pool->dma_addr = NULL;
@@ -213,9 +181,8 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
memset(pool->dma_addr, 0, sizeof(dma_addr_t) * pool->size);
- for(i = 0; i < pool->size; ++i) {
+ for (i = 0; i < pool->size; ++i)
pool->free_map[i] = i;
- }
atomic_set(&pool->available, 0);
pool->producer_index = 0;
@@ -224,10 +191,19 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
return 0;
}
+static inline void ibmveth_flush_buffer(void *addr, unsigned long length)
+{
+ unsigned long offset;
+
+ for (offset = 0; offset < length; offset += SMP_CACHE_BYTES)
+ asm("dcbfl %0,%1" :: "b" (addr), "r" (offset));
+}
+
/* replenish the buffers for a pool. note that we don't need to
* skb_reserve these since they are used for incoming...
*/
-static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struct ibmveth_buff_pool *pool)
+static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter,
+ struct ibmveth_buff_pool *pool)
{
u32 i;
u32 count = pool->size - atomic_read(&pool->available);
@@ -240,23 +216,26 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
mb();
- for(i = 0; i < count; ++i) {
+ for (i = 0; i < count; ++i) {
union ibmveth_buf_desc desc;
- skb = alloc_skb(pool->buff_size, GFP_ATOMIC);
+ skb = netdev_alloc_skb(adapter->netdev, pool->buff_size);
- if(!skb) {
- ibmveth_debug_printk("replenish: unable to allocate skb\n");
+ if (!skb) {
+ netdev_dbg(adapter->netdev,
+ "replenish: unable to allocate skb\n");
adapter->replenish_no_mem++;
break;
}
free_index = pool->consumer_index;
- pool->consumer_index = (pool->consumer_index + 1) % pool->size;
+ pool->consumer_index++;
+ if (pool->consumer_index >= pool->size)
+ pool->consumer_index = 0;
index = pool->free_map[free_index];
- ibmveth_assert(index != IBM_VETH_INVALID_MAP);
- ibmveth_assert(pool->skbuff[index] == NULL);
+ BUG_ON(index == IBM_VETH_INVALID_MAP);
+ BUG_ON(pool->skbuff[index] != NULL);
dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
pool->buff_size, DMA_FROM_DEVICE);
@@ -269,16 +248,23 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
pool->skbuff[index] = skb;
correlator = ((u64)pool->index << 32) | index;
- *(u64*)skb->data = correlator;
+ *(u64 *)skb->data = correlator;
desc.fields.flags_len = IBMVETH_BUF_VALID | pool->buff_size;
desc.fields.address = dma_addr;
- lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc);
+ if (rx_flush) {
+ unsigned int len = min(pool->buff_size,
+ adapter->netdev->mtu +
+ IBMVETH_BUFF_OH);
+ ibmveth_flush_buffer(skb->data, len);
+ }
+ lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address,
+ desc.desc);
- if (lpar_rc != H_SUCCESS)
+ if (lpar_rc != H_SUCCESS) {
goto failure;
- else {
+ } else {
buffers_added++;
adapter->replenish_add_buff_success++;
}
@@ -313,26 +299,31 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter)
adapter->replenish_task_cycles++;
- for (i = (IbmVethNumBufferPools - 1); i >= 0; i--)
- if(adapter->rx_buff_pool[i].active)
- ibmveth_replenish_buffer_pool(adapter,
- &adapter->rx_buff_pool[i]);
+ for (i = (IBMVETH_NUM_BUFF_POOLS - 1); i >= 0; i--) {
+ struct ibmveth_buff_pool *pool = &adapter->rx_buff_pool[i];
- adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
+ if (pool->active &&
+ (atomic_read(&pool->available) < pool->threshold))
+ ibmveth_replenish_buffer_pool(adapter, pool);
+ }
+
+ adapter->rx_no_buffer = *(u64 *)(((char*)adapter->buffer_list_addr) +
+ 4096 - 8);
}
/* empty and free ana buffer pool - also used to do cleanup in error paths */
-static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibmveth_buff_pool *pool)
+static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter,
+ struct ibmveth_buff_pool *pool)
{
int i;
kfree(pool->free_map);
pool->free_map = NULL;
- if(pool->skbuff && pool->dma_addr) {
- for(i = 0; i < pool->size; ++i) {
+ if (pool->skbuff && pool->dma_addr) {
+ for (i = 0; i < pool->size; ++i) {
struct sk_buff *skb = pool->skbuff[i];
- if(skb) {
+ if (skb) {
dma_unmap_single(&adapter->vdev->dev,
pool->dma_addr[i],
pool->buff_size,
@@ -343,31 +334,32 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm
}
}
- if(pool->dma_addr) {
+ if (pool->dma_addr) {
kfree(pool->dma_addr);
pool->dma_addr = NULL;
}
- if(pool->skbuff) {
+ if (pool->skbuff) {
kfree(pool->skbuff);
pool->skbuff = NULL;
}
}
/* remove a buffer from a pool */
-static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 correlator)
+static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter,
+ u64 correlator)
{
unsigned int pool = correlator >> 32;
unsigned int index = correlator & 0xffffffffUL;
unsigned int free_index;
struct sk_buff *skb;
- ibmveth_assert(pool < IbmVethNumBufferPools);
- ibmveth_assert(index < adapter->rx_buff_pool[pool].size);
+ BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS);
+ BUG_ON(index >= adapter->rx_buff_pool[pool].size);
skb = adapter->rx_buff_pool[pool].skbuff[index];
- ibmveth_assert(skb != NULL);
+ BUG_ON(skb == NULL);
adapter->rx_buff_pool[pool].skbuff[index] = NULL;
@@ -377,9 +369,10 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64
DMA_FROM_DEVICE);
free_index = adapter->rx_buff_pool[pool].producer_index;
- adapter->rx_buff_pool[pool].producer_index
- = (adapter->rx_buff_pool[pool].producer_index + 1)
- % adapter->rx_buff_pool[pool].size;
+ adapter->rx_buff_pool[pool].producer_index++;
+ if (adapter->rx_buff_pool[pool].producer_index >=
+ adapter->rx_buff_pool[pool].size)
+ adapter->rx_buff_pool[pool].producer_index = 0;
adapter->rx_buff_pool[pool].free_map[free_index] = index;
mb();
@@ -394,8 +387,8 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada
unsigned int pool = correlator >> 32;
unsigned int index = correlator & 0xffffffffUL;
- ibmveth_assert(pool < IbmVethNumBufferPools);
- ibmveth_assert(index < adapter->rx_buff_pool[pool].size);
+ BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS);
+ BUG_ON(index >= adapter->rx_buff_pool[pool].size);
return adapter->rx_buff_pool[pool].skbuff[index];
}
@@ -410,10 +403,10 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
union ibmveth_buf_desc desc;
unsigned long lpar_rc;
- ibmveth_assert(pool < IbmVethNumBufferPools);
- ibmveth_assert(index < adapter->rx_buff_pool[pool].size);
+ BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS);
+ BUG_ON(index >= adapter->rx_buff_pool[pool].size);
- if(!adapter->rx_buff_pool[pool].active) {
+ if (!adapter->rx_buff_pool[pool].active) {
ibmveth_rxq_harvest_buffer(adapter);
ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]);
return;
@@ -425,12 +418,13 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_debug_printk("h_add_logical_lan_buffer failed during recycle rc=%ld", lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed "
+ "during recycle rc=%ld", lpar_rc);
ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator);
}
- if(++adapter->rx_queue.index == adapter->rx_queue.num_slots) {
+ if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) {
adapter->rx_queue.index = 0;
adapter->rx_queue.toggle = !adapter->rx_queue.toggle;
}
@@ -440,7 +434,7 @@ static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter)
{
ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator);
- if(++adapter->rx_queue.index == adapter->rx_queue.num_slots) {
+ if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) {
adapter->rx_queue.index = 0;
adapter->rx_queue.toggle = !adapter->rx_queue.toggle;
}
@@ -451,7 +445,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
int i;
struct device *dev = &adapter->vdev->dev;
- if(adapter->buffer_list_addr != NULL) {
+ if (adapter->buffer_list_addr != NULL) {
if (!dma_mapping_error(dev, adapter->buffer_list_dma)) {
dma_unmap_single(dev, adapter->buffer_list_dma, 4096,
DMA_BIDIRECTIONAL);
@@ -461,7 +455,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
adapter->buffer_list_addr = NULL;
}
- if(adapter->filter_list_addr != NULL) {
+ if (adapter->filter_list_addr != NULL) {
if (!dma_mapping_error(dev, adapter->filter_list_dma)) {
dma_unmap_single(dev, adapter->filter_list_dma, 4096,
DMA_BIDIRECTIONAL);
@@ -471,7 +465,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
adapter->filter_list_addr = NULL;
}
- if(adapter->rx_queue.queue_addr != NULL) {
+ if (adapter->rx_queue.queue_addr != NULL) {
if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) {
dma_unmap_single(dev,
adapter->rx_queue.queue_dma,
@@ -483,7 +477,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
adapter->rx_queue.queue_addr = NULL;
}
- for(i = 0; i<IbmVethNumBufferPools; i++)
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
if (adapter->rx_buff_pool[i].active)
ibmveth_free_buffer_pool(adapter,
&adapter->rx_buff_pool[i]);
@@ -506,9 +500,11 @@ static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter,
{
int rc, try_again = 1;
- /* After a kexec the adapter will still be open, so our attempt to
- * open it will fail. So if we get a failure we free the adapter and
- * try again, but only once. */
+ /*
+ * After a kexec the adapter will still be open, so our attempt to
+ * open it will fail. So if we get a failure we free the adapter and
+ * try again, but only once.
+ */
retry:
rc = h_register_logical_lan(adapter->vdev->unit_address,
adapter->buffer_list_dma, rxq_desc.desc,
@@ -537,31 +533,32 @@ static int ibmveth_open(struct net_device *netdev)
int i;
struct device *dev;
- ibmveth_debug_printk("open starting\n");
+ netdev_dbg(netdev, "open starting\n");
napi_enable(&adapter->napi);
- for(i = 0; i<IbmVethNumBufferPools; i++)
+ for(i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
rxq_entries += adapter->rx_buff_pool[i].size;
adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
- if(!adapter->buffer_list_addr || !adapter->filter_list_addr) {
- ibmveth_error_printk("unable to allocate filter or buffer list pages\n");
- ibmveth_cleanup(adapter);
- napi_disable(&adapter->napi);
- return -ENOMEM;
+ if (!adapter->buffer_list_addr || !adapter->filter_list_addr) {
+ netdev_err(netdev, "unable to allocate filter or buffer list "
+ "pages\n");
+ rc = -ENOMEM;
+ goto err_out;
}
- adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * rxq_entries;
- adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, GFP_KERNEL);
+ adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) *
+ rxq_entries;
+ adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len,
+ GFP_KERNEL);
- if(!adapter->rx_queue.queue_addr) {
- ibmveth_error_printk("unable to allocate rx queue pages\n");
- ibmveth_cleanup(adapter);
- napi_disable(&adapter->napi);
- return -ENOMEM;
+ if (!adapter->rx_queue.queue_addr) {
+ netdev_err(netdev, "unable to allocate rx queue pages\n");
+ rc = -ENOMEM;
+ goto err_out;
}
dev = &adapter->vdev->dev;
@@ -577,10 +574,10 @@ static int ibmveth_open(struct net_device *netdev)
if ((dma_mapping_error(dev, adapter->buffer_list_dma)) ||
(dma_mapping_error(dev, adapter->filter_list_dma)) ||
(dma_mapping_error(dev, adapter->rx_queue.queue_dma))) {
- ibmveth_error_printk("unable to map filter or buffer list pages\n");
- ibmveth_cleanup(adapter);
- napi_disable(&adapter->napi);
- return -ENOMEM;
+ netdev_err(netdev, "unable to map filter or buffer list "
+ "pages\n");
+ rc = -ENOMEM;
+ goto err_out;
}
adapter->rx_queue.index = 0;
@@ -590,79 +587,86 @@ static int ibmveth_open(struct net_device *netdev)
memcpy(&mac_address, netdev->dev_addr, netdev->addr_len);
mac_address = mac_address >> 16;
- rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | adapter->rx_queue.queue_len;
+ rxq_desc.fields.flags_len = IBMVETH_BUF_VALID |
+ adapter->rx_queue.queue_len;
rxq_desc.fields.address = adapter->rx_queue.queue_dma;
- ibmveth_debug_printk("buffer list @ 0x%p\n", adapter->buffer_list_addr);
- ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr);
- ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr);
+ netdev_dbg(netdev, "buffer list @ 0x%p\n", adapter->buffer_list_addr);
+ netdev_dbg(netdev, "filter list @ 0x%p\n", adapter->filter_list_addr);
+ netdev_dbg(netdev, "receive q @ 0x%p\n", adapter->rx_queue.queue_addr);
h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE);
lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc);
- ibmveth_error_printk("buffer TCE:0x%llx filter TCE:0x%llx rxq desc:0x%llx MAC:0x%llx\n",
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_register_logical_lan failed with %ld\n",
+ lpar_rc);
+ netdev_err(netdev, "buffer TCE:0x%llx filter TCE:0x%llx rxq "
+ "desc:0x%llx MAC:0x%llx\n",
adapter->buffer_list_dma,
adapter->filter_list_dma,
rxq_desc.desc,
mac_address);
- ibmveth_cleanup(adapter);
- napi_disable(&adapter->napi);
- return -ENONET;
+ rc = -ENONET;
+ goto err_out;
}
- for(i = 0; i<IbmVethNumBufferPools; i++) {
- if(!adapter->rx_buff_pool[i].active)
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
+ if (!adapter->rx_buff_pool[i].active)
continue;
if (ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[i])) {
- ibmveth_error_printk("unable to alloc pool\n");
+ netdev_err(netdev, "unable to alloc pool\n");
adapter->rx_buff_pool[i].active = 0;
- ibmveth_cleanup(adapter);
- napi_disable(&adapter->napi);
- return -ENOMEM ;
+ rc = -ENOMEM;
+ goto err_out;
}
}
- ibmveth_debug_printk("registering irq 0x%x\n", netdev->irq);
- if((rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name, netdev)) != 0) {
- ibmveth_error_printk("unable to request irq 0x%x, rc %d\n", netdev->irq, rc);
+ netdev_dbg(netdev, "registering irq 0x%x\n", netdev->irq);
+ rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name,
+ netdev);
+ if (rc != 0) {
+ netdev_err(netdev, "unable to request irq 0x%x, rc %d\n",
+ netdev->irq, rc);
do {
rc = h_free_logical_lan(adapter->vdev->unit_address);
} while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY));
- ibmveth_cleanup(adapter);
- napi_disable(&adapter->napi);
- return rc;
+ goto err_out;
}
adapter->bounce_buffer =
kmalloc(netdev->mtu + IBMVETH_BUFF_OH, GFP_KERNEL);
if (!adapter->bounce_buffer) {
- ibmveth_error_printk("unable to allocate bounce buffer\n");
- ibmveth_cleanup(adapter);
- napi_disable(&adapter->napi);
- return -ENOMEM;
+ netdev_err(netdev, "unable to allocate bounce buffer\n");
+ rc = -ENOMEM;
+ goto err_out_free_irq;
}
adapter->bounce_buffer_dma =
dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer,
netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) {
- ibmveth_error_printk("unable to map bounce buffer\n");
- ibmveth_cleanup(adapter);
- napi_disable(&adapter->napi);
- return -ENOMEM;
+ netdev_err(netdev, "unable to map bounce buffer\n");
+ rc = -ENOMEM;
+ goto err_out_free_irq;
}
- ibmveth_debug_printk("initial replenish cycle\n");
+ netdev_dbg(netdev, "initial replenish cycle\n");
ibmveth_interrupt(netdev->irq, netdev);
netif_start_queue(netdev);
- ibmveth_debug_printk("open complete\n");
+ netdev_dbg(netdev, "open complete\n");
return 0;
+
+err_out_free_irq:
+ free_irq(netdev->irq, netdev);
+err_out:
+ ibmveth_cleanup(adapter);
+ napi_disable(&adapter->napi);
+ return rc;
}
static int ibmveth_close(struct net_device *netdev)
@@ -670,7 +674,7 @@ static int ibmveth_close(struct net_device *netdev)
struct ibmveth_adapter *adapter = netdev_priv(netdev);
long lpar_rc;
- ibmveth_debug_printk("close starting\n");
+ netdev_dbg(netdev, "close starting\n");
napi_disable(&adapter->napi);
@@ -683,26 +687,29 @@ static int ibmveth_close(struct net_device *netdev)
lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
} while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY));
- if(lpar_rc != H_SUCCESS)
- {
- ibmveth_error_printk("h_free_logical_lan failed with %lx, continuing with close\n",
- lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_free_logical_lan failed with %lx, "
+ "continuing with close\n", lpar_rc);
}
free_irq(netdev->irq, netdev);
- adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
+ adapter->rx_no_buffer = *(u64 *)(((char *)adapter->buffer_list_addr) +
+ 4096 - 8);
ibmveth_cleanup(adapter);
- ibmveth_debug_printk("close complete\n");
+ netdev_dbg(netdev, "close complete\n");
return 0;
}
-static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) {
- cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE);
- cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | ADVERTISED_FIBRE);
+static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
+ SUPPORTED_FIBRE);
+ cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg |
+ ADVERTISED_FIBRE);
cmd->speed = SPEED_1000;
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_FIBRE;
@@ -714,12 +721,16 @@ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return 0;
}
-static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) {
+static void netdev_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
strncpy(info->driver, ibmveth_driver_name, sizeof(info->driver) - 1);
- strncpy(info->version, ibmveth_driver_version, sizeof(info->version) - 1);
+ strncpy(info->version, ibmveth_driver_version,
+ sizeof(info->version) - 1);
}
-static u32 netdev_get_link(struct net_device *dev) {
+static u32 netdev_get_link(struct net_device *dev)
+{
return 1;
}
@@ -727,18 +738,20 @@ static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data)
{
struct ibmveth_adapter *adapter = netdev_priv(dev);
- if (data)
+ if (data) {
adapter->rx_csum = 1;
- else {
+ } 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.
+ * 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;
}
}
@@ -747,10 +760,15 @@ static void ibmveth_set_tx_csum_flags(struct net_device *dev, u32 data)
struct ibmveth_adapter *adapter = netdev_priv(dev);
if (data) {
- dev->features |= NETIF_F_IP_CSUM;
+ 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
+ } else {
dev->features &= ~NETIF_F_IP_CSUM;
+ dev->features &= ~NETIF_F_IPV6_CSUM;
+ }
}
static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
@@ -758,7 +776,8 @@ 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;
- long ret;
+ unsigned long set_attr6, clr_attr6;
+ long ret, ret6;
int rc1 = 0, rc2 = 0;
int restart = 0;
@@ -772,10 +791,13 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
set_attr = 0;
clr_attr = 0;
- if (data)
+ if (data) {
set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM;
- else
+ set_attr6 = IBMVETH_ILLAN_IPV6_TCP_CSUM;
+ } else {
clr_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM;
+ clr_attr6 = IBMVETH_ILLAN_IPV6_TCP_CSUM;
+ }
ret = h_illan_attributes(adapter->vdev->unit_address, 0, 0, &ret_attr);
@@ -786,18 +808,39 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
set_attr, &ret_attr);
if (ret != H_SUCCESS) {
- rc1 = -EIO;
- ibmveth_error_printk("unable to change checksum offload settings."
- " %d rc=%ld\n", data, ret);
+ netdev_err(dev, "unable to change IPv4 checksum "
+ "offload settings. %d rc=%ld\n",
+ data, ret);
ret = h_illan_attributes(adapter->vdev->unit_address,
set_attr, clr_attr, &ret_attr);
+ } else {
+ adapter->fw_ipv4_csum_support = data;
+ }
+
+ ret6 = h_illan_attributes(adapter->vdev->unit_address,
+ clr_attr6, set_attr6, &ret_attr);
+
+ if (ret6 != H_SUCCESS) {
+ netdev_err(dev, "unable to change IPv6 checksum "
+ "offload settings. %d rc=%ld\n",
+ data, ret);
+
+ ret = h_illan_attributes(adapter->vdev->unit_address,
+ set_attr6, clr_attr6,
+ &ret_attr);
} else
+ adapter->fw_ipv6_csum_support = data;
+
+ if (ret == H_SUCCESS || ret6 == H_SUCCESS)
done(dev, data);
+ else
+ rc1 = -EIO;
} else {
rc1 = -EIO;
- ibmveth_error_printk("unable to change checksum offload settings."
- " %d rc=%ld ret_attr=%lx\n", data, ret, ret_attr);
+ netdev_err(dev, "unable to change checksum offload settings."
+ " %d rc=%ld ret_attr=%lx\n", data, ret,
+ ret_attr);
}
if (restart)
@@ -821,13 +864,14 @@ 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))
+ if (data && (dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)))
return 0;
- if (!data && !(dev->features & NETIF_F_IP_CSUM))
+ if (!data && !(dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)))
return 0;
if (data && !adapter->rx_csum)
- rc = ibmveth_set_csum_offload(dev, data, ibmveth_set_tx_csum_flags);
+ rc = ibmveth_set_csum_offload(dev, data,
+ ibmveth_set_tx_csum_flags);
else
ibmveth_set_tx_csum_flags(dev, data);
@@ -881,6 +925,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
.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)
@@ -890,129 +935,216 @@ static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
#define page_offset(v) ((unsigned long)(v) & ((1 << 12) - 1))
-static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb,
- struct net_device *netdev)
+static int ibmveth_send(struct ibmveth_adapter *adapter,
+ union ibmveth_buf_desc *descs)
{
- struct ibmveth_adapter *adapter = netdev_priv(netdev);
- union ibmveth_buf_desc desc;
- unsigned long lpar_rc;
unsigned long correlator;
- unsigned long flags;
unsigned int retry_count;
- unsigned int tx_dropped = 0;
- unsigned int tx_bytes = 0;
- unsigned int tx_packets = 0;
- unsigned int tx_send_failed = 0;
- unsigned int tx_map_failed = 0;
- int used_bounce = 0;
- unsigned long data_dma_addr;
+ unsigned long ret;
- desc.fields.flags_len = IBMVETH_BUF_VALID | skb->len;
+ /*
+ * The retry count sets a maximum for the number of broadcast and
+ * multicast destinations within the system.
+ */
+ retry_count = 1024;
+ correlator = 0;
+ do {
+ ret = h_send_logical_lan(adapter->vdev->unit_address,
+ descs[0].desc, descs[1].desc,
+ descs[2].desc, descs[3].desc,
+ descs[4].desc, descs[5].desc,
+ correlator, &correlator);
+ } while ((ret == H_BUSY) && (retry_count--));
+ if (ret != H_SUCCESS && ret != H_DROPPED) {
+ netdev_err(adapter->netdev, "tx: h_send_logical_lan failed "
+ "with rc=%ld\n", ret);
+ return 1;
+ }
+
+ return 0;
+}
+
+static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct ibmveth_adapter *adapter = netdev_priv(netdev);
+ unsigned int desc_flags;
+ union ibmveth_buf_desc descs[6];
+ int last, i;
+ int force_bounce = 0;
+
+ /*
+ * veth handles a maximum of 6 segments including the header, so
+ * we have to linearize the skb if there are more than this.
+ */
+ if (skb_shinfo(skb)->nr_frags > 5 && __skb_linearize(skb)) {
+ netdev->stats.tx_dropped++;
+ goto out;
+ }
+
+ /* veth can't checksum offload UDP */
if (skb->ip_summed == CHECKSUM_PARTIAL &&
- ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) {
- ibmveth_error_printk("tx: failed to checksum packet\n");
- tx_dropped++;
+ ((skb->protocol == htons(ETH_P_IP) &&
+ ip_hdr(skb)->protocol != IPPROTO_TCP) ||
+ (skb->protocol == htons(ETH_P_IPV6) &&
+ ipv6_hdr(skb)->nexthdr != IPPROTO_TCP)) &&
+ skb_checksum_help(skb)) {
+
+ netdev_err(netdev, "tx: failed to checksum packet\n");
+ netdev->stats.tx_dropped++;
goto out;
}
+ desc_flags = IBMVETH_BUF_VALID;
+
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- unsigned char *buf = skb_transport_header(skb) + skb->csum_offset;
+ unsigned char *buf = skb_transport_header(skb) +
+ skb->csum_offset;
- desc.fields.flags_len |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD);
+ desc_flags |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD);
/* Need to zero out the checksum */
buf[0] = 0;
buf[1] = 0;
}
- data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
- skb->len, DMA_TO_DEVICE);
- if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) {
- if (!firmware_has_feature(FW_FEATURE_CMO))
- ibmveth_error_printk("tx: unable to map xmit buffer\n");
+retry_bounce:
+ memset(descs, 0, sizeof(descs));
+
+ /*
+ * If a linear packet is below the rx threshold then
+ * copy it into the static bounce buffer. This avoids the
+ * cost of a TCE insert and remove.
+ */
+ if (force_bounce || (!skb_is_nonlinear(skb) &&
+ (skb->len < tx_copybreak))) {
skb_copy_from_linear_data(skb, adapter->bounce_buffer,
skb->len);
- desc.fields.address = adapter->bounce_buffer_dma;
- tx_map_failed++;
- used_bounce = 1;
- wmb();
- } else
- desc.fields.address = data_dma_addr;
-
- /* send the frame. Arbitrarily set retrycount to 1024 */
- correlator = 0;
- retry_count = 1024;
- do {
- lpar_rc = h_send_logical_lan(adapter->vdev->unit_address,
- desc.desc, 0, 0, 0, 0, 0,
- correlator, &correlator);
- } while ((lpar_rc == H_BUSY) && (retry_count--));
-
- if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) {
- ibmveth_error_printk("tx: h_send_logical_lan failed with rc=%ld\n", lpar_rc);
- ibmveth_error_printk("tx: valid=%d, len=%d, address=0x%08x\n",
- (desc.fields.flags_len & IBMVETH_BUF_VALID) ? 1 : 0,
- skb->len, desc.fields.address);
- tx_send_failed++;
- tx_dropped++;
- } else {
- tx_packets++;
- tx_bytes += skb->len;
- netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
+
+ descs[0].fields.flags_len = desc_flags | skb->len;
+ descs[0].fields.address = adapter->bounce_buffer_dma;
+
+ if (ibmveth_send(adapter, descs)) {
+ adapter->tx_send_failed++;
+ netdev->stats.tx_dropped++;
+ } else {
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += skb->len;
+ }
+
+ goto out;
+ }
+
+ /* Map the header */
+ descs[0].fields.address = dma_map_single(&adapter->vdev->dev, skb->data,
+ skb_headlen(skb),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&adapter->vdev->dev, descs[0].fields.address))
+ goto map_failed;
+
+ descs[0].fields.flags_len = desc_flags | skb_headlen(skb);
+
+ /* Map the frags */
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ unsigned long dma_addr;
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ dma_addr = dma_map_page(&adapter->vdev->dev, frag->page,
+ frag->page_offset, frag->size,
+ DMA_TO_DEVICE);
+
+ if (dma_mapping_error(&adapter->vdev->dev, dma_addr))
+ goto map_failed_frags;
+
+ descs[i+1].fields.flags_len = desc_flags | frag->size;
+ descs[i+1].fields.address = dma_addr;
}
- if (!used_bounce)
- dma_unmap_single(&adapter->vdev->dev, data_dma_addr,
- skb->len, DMA_TO_DEVICE);
+ if (ibmveth_send(adapter, descs)) {
+ adapter->tx_send_failed++;
+ netdev->stats.tx_dropped++;
+ } else {
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += skb->len;
+ }
-out: spin_lock_irqsave(&adapter->stats_lock, flags);
- netdev->stats.tx_dropped += tx_dropped;
- netdev->stats.tx_bytes += tx_bytes;
- netdev->stats.tx_packets += tx_packets;
- adapter->tx_send_failed += tx_send_failed;
- adapter->tx_map_failed += tx_map_failed;
- spin_unlock_irqrestore(&adapter->stats_lock, flags);
+ for (i = 0; i < skb_shinfo(skb)->nr_frags + 1; i++)
+ dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address,
+ descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK,
+ DMA_TO_DEVICE);
+out:
dev_kfree_skb(skb);
return NETDEV_TX_OK;
+
+map_failed_frags:
+ last = i+1;
+ for (i = 0; i < last; i++)
+ dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address,
+ descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK,
+ DMA_TO_DEVICE);
+
+map_failed:
+ if (!firmware_has_feature(FW_FEATURE_CMO))
+ netdev_err(netdev, "tx: unable to map xmit buffer\n");
+ adapter->tx_map_failed++;
+ skb_linearize(skb);
+ force_bounce = 1;
+ goto retry_bounce;
}
static int ibmveth_poll(struct napi_struct *napi, int budget)
{
- struct ibmveth_adapter *adapter = container_of(napi, struct ibmveth_adapter, napi);
+ struct ibmveth_adapter *adapter =
+ container_of(napi, struct ibmveth_adapter, napi);
struct net_device *netdev = adapter->netdev;
int frames_processed = 0;
unsigned long lpar_rc;
- restart_poll:
+restart_poll:
do {
- struct sk_buff *skb;
-
if (!ibmveth_rxq_pending_buffer(adapter))
break;
- rmb();
+ smp_rmb();
if (!ibmveth_rxq_buffer_valid(adapter)) {
wmb(); /* suggested by larson1 */
adapter->rx_invalid_buffer++;
- ibmveth_debug_printk("recycling invalid buffer\n");
+ netdev_dbg(netdev, "recycling invalid buffer\n");
ibmveth_rxq_recycle_buffer(adapter);
} else {
+ struct sk_buff *skb, *new_skb;
int length = ibmveth_rxq_frame_length(adapter);
int offset = ibmveth_rxq_frame_offset(adapter);
int csum_good = ibmveth_rxq_csum_good(adapter);
skb = ibmveth_rxq_get_buffer(adapter);
- if (csum_good)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- ibmveth_rxq_harvest_buffer(adapter);
+ new_skb = NULL;
+ if (length < rx_copybreak)
+ new_skb = netdev_alloc_skb(netdev, length);
+
+ if (new_skb) {
+ skb_copy_to_linear_data(new_skb,
+ skb->data + offset,
+ length);
+ if (rx_flush)
+ ibmveth_flush_buffer(skb->data,
+ length + offset);
+ skb = new_skb;
+ ibmveth_rxq_recycle_buffer(adapter);
+ } else {
+ ibmveth_rxq_harvest_buffer(adapter);
+ skb_reserve(skb, offset);
+ }
- skb_reserve(skb, offset);
skb_put(skb, length);
skb->protocol = eth_type_trans(skb, netdev);
+ if (csum_good)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
netif_receive_skb(skb); /* send it up */
netdev->stats.rx_packets++;
@@ -1030,7 +1162,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
lpar_rc = h_vio_signal(adapter->vdev->unit_address,
VIO_IRQ_ENABLE);
- ibmveth_assert(lpar_rc == H_SUCCESS);
+ BUG_ON(lpar_rc != H_SUCCESS);
napi_complete(napi);
@@ -1054,7 +1186,7 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance)
if (napi_schedule_prep(&adapter->napi)) {
lpar_rc = h_vio_signal(adapter->vdev->unit_address,
VIO_IRQ_DISABLE);
- ibmveth_assert(lpar_rc == H_SUCCESS);
+ BUG_ON(lpar_rc != H_SUCCESS);
__napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
@@ -1071,8 +1203,9 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
IbmVethMcastEnableRecv |
IbmVethMcastDisableFiltering,
0);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_error_printk("h_multicast_ctrl rc=%ld when entering promisc mode\n", lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_multicast_ctrl rc=%ld when "
+ "entering promisc mode\n", lpar_rc);
}
} else {
struct netdev_hw_addr *ha;
@@ -1082,19 +1215,23 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
IbmVethMcastDisableFiltering |
IbmVethMcastClearFilterTable,
0);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_error_printk("h_multicast_ctrl rc=%ld when attempting to clear filter table\n", lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_multicast_ctrl rc=%ld when "
+ "attempting to clear filter table\n",
+ lpar_rc);
}
/* add the addresses to the filter table */
netdev_for_each_mc_addr(ha, netdev) {
- // add the multicast address to the filter table
+ /* add the multicast address to the filter table */
unsigned long mcast_addr = 0;
memcpy(((char *)&mcast_addr)+2, ha->addr, 6);
lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address,
IbmVethMcastAddFilter,
mcast_addr);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_error_printk("h_multicast_ctrl rc=%ld when adding an entry to the filter table\n", lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_multicast_ctrl rc=%ld "
+ "when adding an entry to the filter "
+ "table\n", lpar_rc);
}
}
@@ -1102,8 +1239,9 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address,
IbmVethMcastEnableFiltering,
0);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_error_printk("h_multicast_ctrl rc=%ld when enabling filtering\n", lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_multicast_ctrl rc=%ld when "
+ "enabling filtering\n", lpar_rc);
}
}
}
@@ -1116,14 +1254,14 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
int i, rc;
int need_restart = 0;
- if (new_mtu < IBMVETH_MAX_MTU)
+ if (new_mtu < IBMVETH_MIN_MTU)
return -EINVAL;
- for (i = 0; i < IbmVethNumBufferPools; i++)
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size)
break;
- if (i == IbmVethNumBufferPools)
+ if (i == IBMVETH_NUM_BUFF_POOLS)
return -EINVAL;
/* Deactivate all the buffer pools so that the next loop can activate
@@ -1136,7 +1274,7 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
}
/* Look for an active buffer pool that can hold the new MTU */
- for(i = 0; i<IbmVethNumBufferPools; i++) {
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
adapter->rx_buff_pool[i].active = 1;
if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) {
@@ -1190,7 +1328,7 @@ static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev)
ret = IBMVETH_BUFF_LIST_SIZE + IBMVETH_FILT_LIST_SIZE;
ret += IOMMU_PAGE_ALIGN(netdev->mtu);
- for (i = 0; i < IbmVethNumBufferPools; i++) {
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
/* add the size of the active receive buffers */
if (adapter->rx_buff_pool[i].active)
ret +=
@@ -1219,41 +1357,36 @@ static const struct net_device_ops ibmveth_netdev_ops = {
#endif
};
-static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
+static int __devinit ibmveth_probe(struct vio_dev *dev,
+ const struct vio_device_id *id)
{
int rc, i;
- long ret;
struct net_device *netdev;
struct ibmveth_adapter *adapter;
- unsigned long set_attr, ret_attr;
-
unsigned char *mac_addr_p;
unsigned int *mcastFilterSize_p;
+ dev_dbg(&dev->dev, "entering ibmveth_probe for UA 0x%x\n",
+ dev->unit_address);
- ibmveth_debug_printk_no_adapter("entering ibmveth_probe for UA 0x%x\n",
- dev->unit_address);
-
- mac_addr_p = (unsigned char *) vio_get_attribute(dev,
- VETH_MAC_ADDR, NULL);
- if(!mac_addr_p) {
- printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find VETH_MAC_ADDR "
- "attribute\n", __FILE__, __LINE__);
- return 0;
+ mac_addr_p = (unsigned char *)vio_get_attribute(dev, VETH_MAC_ADDR,
+ NULL);
+ if (!mac_addr_p) {
+ dev_err(&dev->dev, "Can't find VETH_MAC_ADDR attribute\n");
+ return -EINVAL;
}
- mcastFilterSize_p = (unsigned int *) vio_get_attribute(dev,
+ mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev,
VETH_MCAST_FILTER_SIZE, NULL);
- if(!mcastFilterSize_p) {
- printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find "
- "VETH_MCAST_FILTER_SIZE attribute\n",
- __FILE__, __LINE__);
- return 0;
+ if (!mcastFilterSize_p) {
+ dev_err(&dev->dev, "Can't find VETH_MCAST_FILTER_SIZE "
+ "attribute\n");
+ return -EINVAL;
}
netdev = alloc_etherdev(sizeof(struct ibmveth_adapter));
- if(!netdev)
+ if (!netdev)
return -ENOMEM;
adapter = netdev_priv(netdev);
@@ -1261,19 +1394,19 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
adapter->vdev = dev;
adapter->netdev = netdev;
- adapter->mcastFilterSize= *mcastFilterSize_p;
+ adapter->mcastFilterSize = *mcastFilterSize_p;
adapter->pool_config = 0;
netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16);
- /* Some older boxes running PHYP non-natively have an OF that
- returns a 8-byte local-mac-address field (and the first
- 2 bytes have to be ignored) while newer boxes' OF return
- a 6-byte field. Note that IEEE 1275 specifies that
- local-mac-address must be a 6-byte field.
- The RPA doc specifies that the first byte must be 10b, so
- we'll just look for it to solve this 8 vs. 6 byte field issue */
-
+ /*
+ * Some older boxes running PHYP non-natively have an OF that returns
+ * a 8-byte local-mac-address field (and the first 2 bytes have to be
+ * ignored) while newer boxes' OF return a 6-byte field. Note that
+ * IEEE 1275 specifies that local-mac-address must be a 6-byte field.
+ * The RPA doc specifies that the first byte must be 10b, so we'll
+ * just look for it to solve this 8 vs. 6 byte field issue
+ */
if ((*mac_addr_p & 0x3) != 0x02)
mac_addr_p += 2;
@@ -1284,12 +1417,11 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
netdev->netdev_ops = &ibmveth_netdev_ops;
netdev->ethtool_ops = &netdev_ethtool_ops;
SET_NETDEV_DEV(netdev, &dev->dev);
- netdev->features |= NETIF_F_LLTX;
- spin_lock_init(&adapter->stats_lock);
+ netdev->features |= NETIF_F_SG;
memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
- for(i = 0; i<IbmVethNumBufferPools; i++) {
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
struct kobject *kobj = &adapter->rx_buff_pool[i].kobj;
int error;
@@ -1302,41 +1434,25 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
kobject_uevent(kobj, KOBJ_ADD);
}
- ibmveth_debug_printk("adapter @ 0x%p\n", adapter);
+ netdev_dbg(netdev, "adapter @ 0x%p\n", adapter);
adapter->buffer_list_dma = DMA_ERROR_CODE;
adapter->filter_list_dma = DMA_ERROR_CODE;
adapter->rx_queue.queue_dma = DMA_ERROR_CODE;
- ibmveth_debug_printk("registering netdev...\n");
+ netdev_dbg(netdev, "registering netdev...\n");
- ret = h_illan_attributes(dev->unit_address, 0, 0, &ret_attr);
-
- if (ret == H_SUCCESS && !(ret_attr & IBMVETH_ILLAN_ACTIVE_TRUNK) &&
- !(ret_attr & IBMVETH_ILLAN_TRUNK_PRI_MASK) &&
- (ret_attr & IBMVETH_ILLAN_PADDED_PKT_CSUM)) {
- set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM;
-
- ret = h_illan_attributes(dev->unit_address, 0, set_attr, &ret_attr);
-
- if (ret == H_SUCCESS) {
- adapter->rx_csum = 1;
- netdev->features |= NETIF_F_IP_CSUM;
- } else
- ret = h_illan_attributes(dev->unit_address, set_attr, 0, &ret_attr);
- }
+ ibmveth_set_csum_offload(netdev, 1, ibmveth_set_tx_csum_flags);
rc = register_netdev(netdev);
- if(rc) {
- ibmveth_debug_printk("failed to register netdev rc=%d\n", rc);
+ if (rc) {
+ netdev_dbg(netdev, "failed to register netdev rc=%d\n", rc);
free_netdev(netdev);
return rc;
}
- ibmveth_debug_printk("registered\n");
-
- ibmveth_proc_register_adapter(adapter);
+ netdev_dbg(netdev, "registered\n");
return 0;
}
@@ -1347,114 +1463,23 @@ static int __devexit ibmveth_remove(struct vio_dev *dev)
struct ibmveth_adapter *adapter = netdev_priv(netdev);
int i;
- for(i = 0; i<IbmVethNumBufferPools; i++)
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
kobject_put(&adapter->rx_buff_pool[i].kobj);
unregister_netdev(netdev);
- ibmveth_proc_unregister_adapter(adapter);
-
free_netdev(netdev);
dev_set_drvdata(&dev->dev, NULL);
return 0;
}
-#ifdef CONFIG_PROC_FS
-static void ibmveth_proc_register_driver(void)
-{
- ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, init_net.proc_net);
- if (ibmveth_proc_dir) {
- }
-}
-
-static void ibmveth_proc_unregister_driver(void)
-{
- remove_proc_entry(IBMVETH_PROC_DIR, init_net.proc_net);
-}
-
-static int ibmveth_show(struct seq_file *seq, void *v)
-{
- struct ibmveth_adapter *adapter = seq->private;
- char *current_mac = (char *) adapter->netdev->dev_addr;
- char *firmware_mac = (char *) &adapter->mac_addr;
-
- seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
-
- seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address);
- seq_printf(seq, "Current MAC: %pM\n", current_mac);
- seq_printf(seq, "Firmware MAC: %pM\n", firmware_mac);
-
- seq_printf(seq, "\nAdapter Statistics:\n");
- seq_printf(seq, " TX: vio_map_single failres: %lld\n", adapter->tx_map_failed);
- seq_printf(seq, " send failures: %lld\n", adapter->tx_send_failed);
- seq_printf(seq, " RX: replenish task cycles: %lld\n", adapter->replenish_task_cycles);
- seq_printf(seq, " alloc_skb_failures: %lld\n", adapter->replenish_no_mem);
- seq_printf(seq, " add buffer failures: %lld\n", adapter->replenish_add_buff_failure);
- seq_printf(seq, " invalid buffers: %lld\n", adapter->rx_invalid_buffer);
- seq_printf(seq, " no buffers: %lld\n", adapter->rx_no_buffer);
-
- return 0;
-}
-
-static int ibmveth_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ibmveth_show, PDE(inode)->data);
-}
-
-static const struct file_operations ibmveth_proc_fops = {
- .owner = THIS_MODULE,
- .open = ibmveth_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter)
-{
- struct proc_dir_entry *entry;
- if (ibmveth_proc_dir) {
- char u_addr[10];
- sprintf(u_addr, "%x", adapter->vdev->unit_address);
- entry = proc_create_data(u_addr, S_IFREG, ibmveth_proc_dir,
- &ibmveth_proc_fops, adapter);
- if (!entry)
- ibmveth_error_printk("Cannot create adapter proc entry");
- }
-}
-
-static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter)
-{
- if (ibmveth_proc_dir) {
- char u_addr[10];
- sprintf(u_addr, "%x", adapter->vdev->unit_address);
- remove_proc_entry(u_addr, ibmveth_proc_dir);
- }
-}
-
-#else /* CONFIG_PROC_FS */
-static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter)
-{
-}
-
-static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter)
-{
-}
-static void ibmveth_proc_register_driver(void)
-{
-}
-
-static void ibmveth_proc_unregister_driver(void)
-{
-}
-#endif /* CONFIG_PROC_FS */
-
static struct attribute veth_active_attr;
static struct attribute veth_num_attr;
static struct attribute veth_size_attr;
-static ssize_t veth_pool_show(struct kobject * kobj,
- struct attribute * attr, char * buf)
+static ssize_t veth_pool_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
{
struct ibmveth_buff_pool *pool = container_of(kobj,
struct ibmveth_buff_pool,
@@ -1469,8 +1494,8 @@ static ssize_t veth_pool_show(struct kobject * kobj,
return 0;
}
-static ssize_t veth_pool_store(struct kobject * kobj, struct attribute * attr,
-const char * buf, size_t count)
+static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t count)
{
struct ibmveth_buff_pool *pool = container_of(kobj,
struct ibmveth_buff_pool,
@@ -1484,8 +1509,9 @@ const char * buf, size_t count)
if (attr == &veth_active_attr) {
if (value && !pool->active) {
if (netif_running(netdev)) {
- if(ibmveth_alloc_buffer_pool(pool)) {
- ibmveth_error_printk("unable to alloc pool\n");
+ if (ibmveth_alloc_buffer_pool(pool)) {
+ netdev_err(netdev,
+ "unable to alloc pool\n");
return -ENOMEM;
}
pool->active = 1;
@@ -1494,14 +1520,15 @@ const char * buf, size_t count)
adapter->pool_config = 0;
if ((rc = ibmveth_open(netdev)))
return rc;
- } else
+ } else {
pool->active = 1;
+ }
} else if (!value && pool->active) {
int mtu = netdev->mtu + IBMVETH_BUFF_OH;
int i;
/* Make sure there is a buffer pool with buffers that
can hold a packet of the size of the MTU */
- for (i = 0; i < IbmVethNumBufferPools; i++) {
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
if (pool == &adapter->rx_buff_pool[i])
continue;
if (!adapter->rx_buff_pool[i].active)
@@ -1510,8 +1537,8 @@ const char * buf, size_t count)
break;
}
- if (i == IbmVethNumBufferPools) {
- ibmveth_error_printk("no active pool >= MTU\n");
+ if (i == IBMVETH_NUM_BUFF_POOLS) {
+ netdev_err(netdev, "no active pool >= MTU\n");
return -EPERM;
}
@@ -1526,9 +1553,9 @@ const char * buf, size_t count)
pool->active = 0;
}
} else if (attr == &veth_num_attr) {
- if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT)
+ if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) {
return -EINVAL;
- else {
+ } else {
if (netif_running(netdev)) {
adapter->pool_config = 1;
ibmveth_close(netdev);
@@ -1536,13 +1563,14 @@ const char * buf, size_t count)
pool->size = value;
if ((rc = ibmveth_open(netdev)))
return rc;
- } else
+ } else {
pool->size = value;
+ }
}
} else if (attr == &veth_size_attr) {
- if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE)
+ if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) {
return -EINVAL;
- else {
+ } else {
if (netif_running(netdev)) {
adapter->pool_config = 1;
ibmveth_close(netdev);
@@ -1550,8 +1578,9 @@ const char * buf, size_t count)
pool->buff_size = value;
if ((rc = ibmveth_open(netdev)))
return rc;
- } else
+ } else {
pool->buff_size = value;
+ }
}
}
@@ -1561,16 +1590,16 @@ const char * buf, size_t count)
}
-#define ATTR(_name, _mode) \
- struct attribute veth_##_name##_attr = { \
- .name = __stringify(_name), .mode = _mode, \
- };
+#define ATTR(_name, _mode) \
+ struct attribute veth_##_name##_attr = { \
+ .name = __stringify(_name), .mode = _mode, \
+ };
static ATTR(active, 0644);
static ATTR(num, 0644);
static ATTR(size, 0644);
-static struct attribute * veth_pool_attrs[] = {
+static struct attribute *veth_pool_attrs[] = {
&veth_active_attr,
&veth_num_attr,
&veth_size_attr,
@@ -1595,7 +1624,7 @@ static int ibmveth_resume(struct device *dev)
return 0;
}
-static struct vio_device_id ibmveth_device_table[] __devinitdata= {
+static struct vio_device_id ibmveth_device_table[] __devinitdata = {
{ "network", "IBM,l-lan"},
{ "", "" }
};
@@ -1619,9 +1648,8 @@ static struct vio_driver ibmveth_driver = {
static int __init ibmveth_module_init(void)
{
- ibmveth_printk("%s: %s %s\n", ibmveth_driver_name, ibmveth_driver_string, ibmveth_driver_version);
-
- ibmveth_proc_register_driver();
+ printk(KERN_DEBUG "%s: %s %s\n", ibmveth_driver_name,
+ ibmveth_driver_string, ibmveth_driver_version);
return vio_register_driver(&ibmveth_driver);
}
@@ -1629,7 +1657,6 @@ static int __init ibmveth_module_init(void)
static void __exit ibmveth_module_exit(void)
{
vio_unregister_driver(&ibmveth_driver);
- ibmveth_proc_unregister_driver();
}
module_init(ibmveth_module_init);
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index ec76ace66c6b..43a794fab9ff 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -1,26 +1,28 @@
-/**************************************************************************/
-/* */
-/* IBM eServer i/[Series Virtual Ethernet Device Driver */
-/* Copyright (C) 2003 IBM Corp. */
-/* Dave Larson (larson1@us.ibm.com) */
-/* Santiago Leon (santil@us.ibm.com) */
-/* */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; 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 */
-/* */
-/**************************************************************************/
+/*
+ * IBM Power Virtual Ethernet Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2003, 2010
+ *
+ * Authors: Dave Larson <larson1@us.ibm.com>
+ * Santiago Leon <santil@linux.vnet.ibm.com>
+ * Brian King <brking@linux.vnet.ibm.com>
+ * Robert Jennings <rcj@linux.vnet.ibm.com>
+ * Anton Blanchard <anton@au.ibm.com>
+ */
#ifndef _IBMVETH_H
#define _IBMVETH_H
@@ -92,17 +94,17 @@ static inline long h_illan_attributes(unsigned long unit_address,
#define h_change_logical_lan_mac(ua, mac) \
plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac)
-#define IbmVethNumBufferPools 5
+#define IBMVETH_NUM_BUFF_POOLS 5
#define IBMVETH_IO_ENTITLEMENT_DEFAULT 4243456 /* MTU of 1500 needs 4.2Mb */
#define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */
-#define IBMVETH_MAX_MTU 68
+#define IBMVETH_MIN_MTU 68
#define IBMVETH_MAX_POOL_COUNT 4096
#define IBMVETH_BUFF_LIST_SIZE 4096
#define IBMVETH_FILT_LIST_SIZE 4096
#define IBMVETH_MAX_BUF_SIZE (1024 * 128)
static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 };
-static int pool_count[] = { 256, 768, 256, 256, 256 };
+static int pool_count[] = { 256, 512, 256, 256, 256 };
static int pool_active[] = { 1, 1, 0, 0, 0};
#define IBM_VETH_INVALID_MAP ((u16)0xffff)
@@ -142,13 +144,15 @@ struct ibmveth_adapter {
void * filter_list_addr;
dma_addr_t buffer_list_dma;
dma_addr_t filter_list_dma;
- struct ibmveth_buff_pool rx_buff_pool[IbmVethNumBufferPools];
+ struct ibmveth_buff_pool rx_buff_pool[IBMVETH_NUM_BUFF_POOLS];
struct ibmveth_rx_q rx_queue;
int pool_config;
int rx_csum;
void *bounce_buffer;
dma_addr_t bounce_buffer_dma;
+ u64 fw_ipv6_csum_support;
+ u64 fw_ipv4_csum_support;
/* adapter specific stats */
u64 replenish_task_cycles;
u64 replenish_no_mem;
@@ -158,7 +162,6 @@ struct ibmveth_adapter {
u64 rx_no_buffer;
u64 tx_map_failed;
u64 tx_send_failed;
- spinlock_t stats_lock;
};
struct ibmveth_buf_desc_fields {
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 187622f1c816..bc183f5487cb 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -132,6 +132,8 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
case E1000_DEV_ID_82580_SERDES:
case E1000_DEV_ID_82580_SGMII:
case E1000_DEV_ID_82580_COPPER_DUAL:
+ case E1000_DEV_ID_DH89XXCC_SGMII:
+ case E1000_DEV_ID_DH89XXCC_SERDES:
mac->type = e1000_82580;
break;
case E1000_DEV_ID_I350_COPPER:
@@ -282,10 +284,18 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
/* Verify phy id and set remaining function pointers */
switch (phy->id) {
+ case I347AT4_E_PHY_ID:
+ case M88E1112_E_PHY_ID:
case M88E1111_I_PHY_ID:
phy->type = e1000_phy_m88;
phy->ops.get_phy_info = igb_get_phy_info_m88;
- phy->ops.get_cable_length = igb_get_cable_length_m88;
+
+ if (phy->id == I347AT4_E_PHY_ID ||
+ phy->id == M88E1112_E_PHY_ID)
+ phy->ops.get_cable_length = igb_get_cable_length_m88_gen2;
+ else
+ phy->ops.get_cable_length = igb_get_cable_length_m88;
+
phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88;
break;
case IGP03E1000_E_PHY_ID:
@@ -1058,7 +1068,11 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
}
switch (hw->phy.type) {
case e1000_phy_m88:
- ret_val = igb_copper_link_setup_m88(hw);
+ if (hw->phy.id == I347AT4_E_PHY_ID ||
+ hw->phy.id == M88E1112_E_PHY_ID)
+ ret_val = igb_copper_link_setup_m88_gen2(hw);
+ else
+ ret_val = igb_copper_link_setup_m88(hw);
break;
case e1000_phy_igp_3:
ret_val = igb_copper_link_setup_igp(hw);
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index bbd2ec308eb0..62222796a8b3 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -634,6 +634,8 @@
* E = External
*/
#define M88E1111_I_PHY_ID 0x01410CC0
+#define M88E1112_E_PHY_ID 0x01410C90
+#define I347AT4_E_PHY_ID 0x01410DC0
#define IGP03E1000_E_PHY_ID 0x02A80390
#define I82580_I_PHY_ID 0x015403A0
#define I350_I_PHY_ID 0x015403B0
@@ -702,6 +704,35 @@
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100
#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
+/* Intel i347-AT4 Registers */
+
+#define I347AT4_PCDL 0x10 /* PHY Cable Diagnostics Length */
+#define I347AT4_PCDC 0x15 /* PHY Cable Diagnostics Control */
+#define I347AT4_PAGE_SELECT 0x16
+
+/* i347-AT4 Extended PHY Specific Control Register */
+
+/*
+ * Number of times we will attempt to autonegotiate before downshifting if we
+ * are the master
+ */
+#define I347AT4_PSCR_DOWNSHIFT_ENABLE 0x0800
+#define I347AT4_PSCR_DOWNSHIFT_MASK 0x7000
+#define I347AT4_PSCR_DOWNSHIFT_1X 0x0000
+#define I347AT4_PSCR_DOWNSHIFT_2X 0x1000
+#define I347AT4_PSCR_DOWNSHIFT_3X 0x2000
+#define I347AT4_PSCR_DOWNSHIFT_4X 0x3000
+#define I347AT4_PSCR_DOWNSHIFT_5X 0x4000
+#define I347AT4_PSCR_DOWNSHIFT_6X 0x5000
+#define I347AT4_PSCR_DOWNSHIFT_7X 0x6000
+#define I347AT4_PSCR_DOWNSHIFT_8X 0x7000
+
+/* i347-AT4 PHY Cable Diagnostics Control */
+#define I347AT4_PCDC_CABLE_LENGTH_UNIT 0x0400 /* 0=cm 1=meters */
+
+/* Marvell 1112 only registers */
+#define M88E1112_VCT_DSP_DISTANCE 0x001A
+
/* M88EC018 Rev 2 specific DownShift settings */
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index cb8db78b1a05..c0b017f8d782 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -54,6 +54,8 @@ struct e1000_hw;
#define E1000_DEV_ID_82580_SERDES 0x1510
#define E1000_DEV_ID_82580_SGMII 0x1511
#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516
+#define E1000_DEV_ID_DH89XXCC_SGMII 0x0436
+#define E1000_DEV_ID_DH89XXCC_SERDES 0x0438
#define E1000_DEV_ID_I350_COPPER 0x1521
#define E1000_DEV_ID_I350_FIBER 0x1522
#define E1000_DEV_ID_I350_SERDES 0x1523
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index cf1f32300923..ddd036a78999 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -570,6 +570,89 @@ out:
}
/**
+ * igb_copper_link_setup_m88_gen2 - Setup m88 PHY's for copper link
+ * @hw: pointer to the HW structure
+ *
+ * Sets up MDI/MDI-X and polarity for i347-AT4, m88e1322 and m88e1112 PHY's.
+ * Also enables and sets the downshift parameters.
+ **/
+s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val;
+ u16 phy_data;
+
+ if (phy->reset_disable) {
+ ret_val = 0;
+ goto out;
+ }
+
+ /* Enable CRS on Tx. This must be set for half-duplex operation. */
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+ if (ret_val)
+ goto out;
+
+ /*
+ * Options:
+ * MDI/MDI-X = 0 (default)
+ * 0 - Auto for all speeds
+ * 1 - MDI mode
+ * 2 - MDI-X mode
+ * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+ */
+ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+
+ switch (phy->mdix) {
+ case 1:
+ phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+ break;
+ case 2:
+ phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+ break;
+ case 3:
+ /* M88E1112 does not support this mode) */
+ if (phy->id != M88E1112_E_PHY_ID) {
+ phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+ break;
+ }
+ case 0:
+ default:
+ phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+ break;
+ }
+
+ /*
+ * Options:
+ * disable_polarity_correction = 0 (default)
+ * Automatic Correction for Reversed Cable Polarity
+ * 0 - Disabled
+ * 1 - Enabled
+ */
+ phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+ if (phy->disable_polarity_correction == 1)
+ phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+
+ /* Enable downshift and setting it to X6 */
+ phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK;
+ phy_data |= I347AT4_PSCR_DOWNSHIFT_6X;
+ phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE;
+
+ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+ if (ret_val)
+ goto out;
+
+ /* Commit the changes. */
+ ret_val = igb_phy_sw_reset(hw);
+ if (ret_val) {
+ hw_dbg("Error committing the PHY changes\n");
+ goto out;
+ }
+
+out:
+ return ret_val;
+}
+
+/**
* igb_copper_link_setup_igp - Setup igp PHY's for copper link
* @hw: pointer to the HW structure
*
@@ -1124,18 +1207,25 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
goto out;
if (!link) {
- /*
- * We didn't get link.
- * Reset the DSP and cross our fingers.
- */
- ret_val = phy->ops.write_reg(hw,
- M88E1000_PHY_PAGE_SELECT,
- 0x001d);
- if (ret_val)
- goto out;
- ret_val = igb_phy_reset_dsp(hw);
- if (ret_val)
- goto out;
+ if (hw->phy.type != e1000_phy_m88 ||
+ hw->phy.id == I347AT4_E_PHY_ID ||
+ hw->phy.id == M88E1112_E_PHY_ID) {
+ hw_dbg("Link taking longer than expected.\n");
+ } else {
+
+ /*
+ * We didn't get link.
+ * Reset the DSP and cross our fingers.
+ */
+ ret_val = phy->ops.write_reg(hw,
+ M88E1000_PHY_PAGE_SELECT,
+ 0x001d);
+ if (ret_val)
+ goto out;
+ ret_val = igb_phy_reset_dsp(hw);
+ if (ret_val)
+ goto out;
+ }
}
/* Try once more */
@@ -1145,6 +1235,11 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
goto out;
}
+ if (hw->phy.type != e1000_phy_m88 ||
+ hw->phy.id == I347AT4_E_PHY_ID ||
+ hw->phy.id == M88E1112_E_PHY_ID)
+ goto out;
+
ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
@@ -1557,6 +1652,93 @@ out:
return ret_val;
}
+s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val;
+ u16 phy_data, phy_data2, index, default_page, is_cm;
+
+ switch (hw->phy.id) {
+ case I347AT4_E_PHY_ID:
+ /* Remember the original page select and set it to 7 */
+ ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
+ &default_page);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07);
+ if (ret_val)
+ goto out;
+
+ /* Get cable length from PHY Cable Diagnostics Control Reg */
+ ret_val = phy->ops.read_reg(hw, (I347AT4_PCDL + phy->addr),
+ &phy_data);
+ if (ret_val)
+ goto out;
+
+ /* Check if the unit of cable length is meters or cm */
+ ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2);
+ if (ret_val)
+ goto out;
+
+ is_cm = !(phy_data & I347AT4_PCDC_CABLE_LENGTH_UNIT);
+
+ /* Populate the phy structure with cable length in meters */
+ phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
+ phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
+ phy->cable_length = phy_data / (is_cm ? 100 : 1);
+
+ /* Reset the page selec to its original value */
+ ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
+ default_page);
+ if (ret_val)
+ goto out;
+ break;
+ case M88E1112_E_PHY_ID:
+ /* Remember the original page select and set it to 5 */
+ ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
+ &default_page);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x05);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.read_reg(hw, M88E1112_VCT_DSP_DISTANCE,
+ &phy_data);
+ if (ret_val)
+ goto out;
+
+ index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+ M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+ if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
+ ret_val = -E1000_ERR_PHY;
+ goto out;
+ }
+
+ phy->min_cable_length = e1000_m88_cable_length_table[index];
+ phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
+
+ phy->cable_length = (phy->min_cable_length +
+ phy->max_cable_length) / 2;
+
+ /* Reset the page select to its original value */
+ ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
+ default_page);
+ if (ret_val)
+ goto out;
+
+ break;
+ default:
+ ret_val = -E1000_ERR_PHY;
+ goto out;
+ }
+
+out:
+ return ret_val;
+}
+
/**
* igb_get_cable_length_igp_2 - Determine cable length for igp2 PHY
* @hw: pointer to the HW structure
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h
index 565a6dbb3714..2cc117705a31 100644
--- a/drivers/net/igb/e1000_phy.h
+++ b/drivers/net/igb/e1000_phy.h
@@ -45,9 +45,11 @@ s32 igb_check_downshift(struct e1000_hw *hw);
s32 igb_check_reset_block(struct e1000_hw *hw);
s32 igb_copper_link_setup_igp(struct e1000_hw *hw);
s32 igb_copper_link_setup_m88(struct e1000_hw *hw);
+s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw);
s32 igb_get_cable_length_m88(struct e1000_hw *hw);
+s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw);
s32 igb_get_cable_length_igp_2(struct e1000_hw *hw);
s32 igb_get_phy_id(struct e1000_hw *hw);
s32 igb_get_phy_info_igp(struct e1000_hw *hw);
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 6e63d9a7fc75..edab9c442399 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -143,7 +143,7 @@ struct igb_buffer {
u16 next_to_watch;
unsigned int bytecount;
u16 gso_segs;
- union skb_shared_tx shtx;
+ u8 tx_flags;
u8 mapped_as_page;
};
/* RX */
@@ -159,6 +159,7 @@ struct igb_tx_queue_stats {
u64 packets;
u64 bytes;
u64 restart_queue;
+ u64 restart_queue2;
};
struct igb_rx_queue_stats {
@@ -210,11 +211,14 @@ struct igb_ring {
/* TX */
struct {
struct igb_tx_queue_stats tx_stats;
+ struct u64_stats_sync tx_syncp;
+ struct u64_stats_sync tx_syncp2;
bool detect_tx_hung;
};
/* RX */
struct {
struct igb_rx_queue_stats rx_stats;
+ struct u64_stats_sync rx_syncp;
u32 rx_buffer_len;
};
};
@@ -288,6 +292,9 @@ struct igb_adapter {
struct timecompare compare;
struct hwtstamp_config hwtstamp_config;
+ spinlock_t stats64_lock;
+ struct rtnl_link_stats64 stats64;
+
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
struct e1000_hw_stats stats;
@@ -357,7 +364,7 @@ extern netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *, struct igb_ring *);
extern void igb_unmap_and_free_tx_resource(struct igb_ring *,
struct igb_buffer *);
extern void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
-extern void igb_update_stats(struct igb_adapter *);
+extern void igb_update_stats(struct igb_adapter *, struct rtnl_link_stats64 *);
extern bool igb_has_link(struct igb_adapter *adapter);
extern void igb_set_ethtool_ops(struct net_device *);
extern void igb_power_up_link(struct igb_adapter *);
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 26bf6a13d1c1..a70e16bcfa7e 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -90,8 +90,8 @@ static const struct igb_stats igb_gstrings_stats[] = {
#define IGB_NETDEV_STAT(_net_stat) { \
.stat_string = __stringify(_net_stat), \
- .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
- .stat_offset = offsetof(struct net_device_stats, _net_stat) \
+ .sizeof_stat = FIELD_SIZEOF(struct rtnl_link_stats64, _net_stat), \
+ .stat_offset = offsetof(struct rtnl_link_stats64, _net_stat) \
}
static const struct igb_stats igb_gstrings_net_stats[] = {
IGB_NETDEV_STAT(rx_errors),
@@ -111,8 +111,9 @@ static const struct igb_stats igb_gstrings_net_stats[] = {
(sizeof(igb_gstrings_net_stats) / sizeof(struct igb_stats))
#define IGB_RX_QUEUE_STATS_LEN \
(sizeof(struct igb_rx_queue_stats) / sizeof(u64))
-#define IGB_TX_QUEUE_STATS_LEN \
- (sizeof(struct igb_tx_queue_stats) / sizeof(u64))
+
+#define IGB_TX_QUEUE_STATS_LEN 3 /* packets, bytes, restart_queue */
+
#define IGB_QUEUE_STATS_LEN \
((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \
IGB_RX_QUEUE_STATS_LEN) + \
@@ -2070,12 +2071,14 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *data)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- struct net_device_stats *net_stats = &netdev->stats;
- u64 *queue_stat;
- int i, j, k;
+ struct rtnl_link_stats64 *net_stats = &adapter->stats64;
+ unsigned int start;
+ struct igb_ring *ring;
+ int i, j;
char *p;
- igb_update_stats(adapter);
+ spin_lock(&adapter->stats64_lock);
+ igb_update_stats(adapter, net_stats);
for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
p = (char *)adapter + igb_gstrings_stats[i].stat_offset;
@@ -2088,15 +2091,36 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
for (j = 0; j < adapter->num_tx_queues; j++) {
- queue_stat = (u64 *)&adapter->tx_ring[j]->tx_stats;
- for (k = 0; k < IGB_TX_QUEUE_STATS_LEN; k++, i++)
- data[i] = queue_stat[k];
+ u64 restart2;
+
+ ring = adapter->tx_ring[j];
+ do {
+ start = u64_stats_fetch_begin_bh(&ring->tx_syncp);
+ data[i] = ring->tx_stats.packets;
+ data[i+1] = ring->tx_stats.bytes;
+ data[i+2] = ring->tx_stats.restart_queue;
+ } while (u64_stats_fetch_retry_bh(&ring->tx_syncp, start));
+ do {
+ start = u64_stats_fetch_begin_bh(&ring->tx_syncp2);
+ restart2 = ring->tx_stats.restart_queue2;
+ } while (u64_stats_fetch_retry_bh(&ring->tx_syncp2, start));
+ data[i+2] += restart2;
+
+ i += IGB_TX_QUEUE_STATS_LEN;
}
for (j = 0; j < adapter->num_rx_queues; j++) {
- queue_stat = (u64 *)&adapter->rx_ring[j]->rx_stats;
- for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++)
- data[i] = queue_stat[k];
+ ring = adapter->rx_ring[j];
+ do {
+ start = u64_stats_fetch_begin_bh(&ring->rx_syncp);
+ data[i] = ring->rx_stats.packets;
+ data[i+1] = ring->rx_stats.bytes;
+ data[i+2] = ring->rx_stats.drops;
+ data[i+3] = ring->rx_stats.csum_err;
+ data[i+4] = ring->rx_stats.alloc_failed;
+ } while (u64_stats_fetch_retry_bh(&ring->rx_syncp, start));
+ i += IGB_RX_QUEUE_STATS_LEN;
}
+ spin_unlock(&adapter->stats64_lock);
}
static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 9b4e5895f5f9..75155a27fdde 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -71,6 +71,8 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SGMII), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER_DUAL), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SGMII), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 },
@@ -94,7 +96,6 @@ static int igb_setup_all_rx_resources(struct igb_adapter *);
static void igb_free_all_tx_resources(struct igb_adapter *);
static void igb_free_all_rx_resources(struct igb_adapter *);
static void igb_setup_mrqc(struct igb_adapter *);
-void igb_update_stats(struct igb_adapter *);
static int igb_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit igb_remove(struct pci_dev *pdev);
static int igb_sw_init(struct igb_adapter *);
@@ -111,7 +112,8 @@ static void igb_update_phy_info(unsigned long);
static void igb_watchdog(unsigned long);
static void igb_watchdog_task(struct work_struct *);
static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *);
-static struct net_device_stats *igb_get_stats(struct net_device *);
+static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *dev,
+ struct rtnl_link_stats64 *stats);
static int igb_change_mtu(struct net_device *, int);
static int igb_set_mac(struct net_device *, void *);
static void igb_set_uta(struct igb_adapter *adapter);
@@ -986,7 +988,7 @@ static void igb_clear_interrupt_scheme(struct igb_adapter *adapter)
* Attempt to configure interrupts using the best available
* capabilities of the hardware and kernel.
**/
-static void igb_set_interrupt_capability(struct igb_adapter *adapter)
+static int igb_set_interrupt_capability(struct igb_adapter *adapter)
{
int err;
int numvecs, i;
@@ -1052,8 +1054,10 @@ msi_only:
if (!pci_enable_msi(adapter->pdev))
adapter->flags |= IGB_FLAG_HAS_MSI;
out:
- /* Notify the stack of the (possibly) reduced Tx Queue count. */
- adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
+ /* Notify the stack of the (possibly) reduced queue counts. */
+ netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
+ return netif_set_real_num_rx_queues(adapter->netdev,
+ adapter->num_rx_queues);
}
/**
@@ -1152,7 +1156,9 @@ static int igb_init_interrupt_scheme(struct igb_adapter *adapter)
struct pci_dev *pdev = adapter->pdev;
int err;
- igb_set_interrupt_capability(adapter);
+ err = igb_set_interrupt_capability(adapter);
+ if (err)
+ return err;
err = igb_alloc_q_vectors(adapter);
if (err) {
@@ -1530,7 +1536,9 @@ void igb_down(struct igb_adapter *adapter)
netif_carrier_off(netdev);
/* record the stats before reset*/
- igb_update_stats(adapter);
+ spin_lock(&adapter->stats64_lock);
+ igb_update_stats(adapter, &adapter->stats64);
+ spin_unlock(&adapter->stats64_lock);
adapter->link_speed = 0;
adapter->link_duplex = 0;
@@ -1683,7 +1691,7 @@ static const struct net_device_ops igb_netdev_ops = {
.ndo_open = igb_open,
.ndo_stop = igb_close,
.ndo_start_xmit = igb_xmit_frame_adv,
- .ndo_get_stats = igb_get_stats,
+ .ndo_get_stats64 = igb_get_stats64,
.ndo_set_rx_mode = igb_set_rx_mode,
.ndo_set_multicast_list = igb_set_rx_mode,
.ndo_set_mac_address = igb_set_mac,
@@ -1856,8 +1864,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
netdev->vlan_features |= NETIF_F_IPV6_CSUM;
netdev->vlan_features |= NETIF_F_SG;
- if (pci_using_dac)
+ if (pci_using_dac) {
netdev->features |= NETIF_F_HIGHDMA;
+ netdev->vlan_features |= NETIF_F_HIGHDMA;
+ }
if (hw->mac.type >= e1000_82576)
netdev->features |= NETIF_F_SCTP_CSUM;
@@ -1888,9 +1898,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
goto err_eeprom;
}
- setup_timer(&adapter->watchdog_timer, &igb_watchdog,
+ setup_timer(&adapter->watchdog_timer, igb_watchdog,
(unsigned long) adapter);
- setup_timer(&adapter->phy_info_timer, &igb_update_phy_info,
+ setup_timer(&adapter->phy_info_timer, igb_update_phy_info,
(unsigned long) adapter);
INIT_WORK(&adapter->reset_task, igb_reset_task);
@@ -2268,6 +2278,7 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
+ spin_lock_init(&adapter->stats64_lock);
#ifdef CONFIG_PCI_IOV
if (hw->mac.type == e1000_82576)
adapter->vfs_allocated_count = (max_vfs > 7) ? 7 : max_vfs;
@@ -3475,7 +3486,9 @@ static void igb_watchdog_task(struct work_struct *work)
}
}
- igb_update_stats(adapter);
+ spin_lock(&adapter->stats64_lock);
+ igb_update_stats(adapter, &adapter->stats64);
+ spin_unlock(&adapter->stats64_lock);
for (i = 0; i < adapter->num_tx_queues; i++) {
struct igb_ring *tx_ring = adapter->tx_ring[i];
@@ -3542,6 +3555,8 @@ static void igb_update_ring_itr(struct igb_q_vector *q_vector)
int new_val = q_vector->itr_val;
int avg_wire_size = 0;
struct igb_adapter *adapter = q_vector->adapter;
+ struct igb_ring *ring;
+ unsigned int packets;
/* For non-gigabit speeds, just fix the interrupt rate at 4000
* ints/sec - ITR timer value of 120 ticks.
@@ -3551,16 +3566,21 @@ static void igb_update_ring_itr(struct igb_q_vector *q_vector)
goto set_itr_val;
}
- if (q_vector->rx_ring && q_vector->rx_ring->total_packets) {
- struct igb_ring *ring = q_vector->rx_ring;
- avg_wire_size = ring->total_bytes / ring->total_packets;
+ ring = q_vector->rx_ring;
+ if (ring) {
+ packets = ACCESS_ONCE(ring->total_packets);
+
+ if (packets)
+ avg_wire_size = ring->total_bytes / packets;
}
- if (q_vector->tx_ring && q_vector->tx_ring->total_packets) {
- struct igb_ring *ring = q_vector->tx_ring;
- avg_wire_size = max_t(u32, avg_wire_size,
- (ring->total_bytes /
- ring->total_packets));
+ ring = q_vector->tx_ring;
+ if (ring) {
+ packets = ACCESS_ONCE(ring->total_packets);
+
+ if (packets)
+ avg_wire_size = max_t(u32, avg_wire_size,
+ ring->total_bytes / packets);
}
/* if avg_wire_size isn't set no work was done */
@@ -3954,7 +3974,7 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb,
}
tx_ring->buffer_info[i].skb = skb;
- tx_ring->buffer_info[i].shtx = skb_shinfo(skb)->tx_flags;
+ tx_ring->buffer_info[i].tx_flags = skb_shinfo(skb)->tx_flags;
/* multiply data chunks by size of headers */
tx_ring->buffer_info[i].bytecount = ((gso_segs - 1) * hlen) + skb->len;
tx_ring->buffer_info[i].gso_segs = gso_segs;
@@ -4069,7 +4089,11 @@ static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
/* A reprieve! */
netif_wake_subqueue(netdev, tx_ring->queue_index);
- tx_ring->tx_stats.restart_queue++;
+
+ u64_stats_update_begin(&tx_ring->tx_syncp2);
+ tx_ring->tx_stats.restart_queue2++;
+ u64_stats_update_end(&tx_ring->tx_syncp2);
+
return 0;
}
@@ -4088,7 +4112,6 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
u32 tx_flags = 0;
u16 first;
u8 hdr_len = 0;
- union skb_shared_tx *shtx = skb_tx(skb);
/* need: 1 descriptor per page,
* + 2 desc gap to keep tail from touching head,
@@ -4100,12 +4123,12 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
- if (unlikely(shtx->hardware)) {
- shtx->in_progress = 1;
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
tx_flags |= IGB_TX_FLAGS_TSTAMP;
}
- if (vlan_tx_tag_present(skb) && adapter->vlgrp) {
+ if (vlan_tx_tag_present(skb)) {
tx_flags |= IGB_TX_FLAGS_VLAN;
tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
}
@@ -4207,16 +4230,22 @@ static void igb_reset_task(struct work_struct *work)
}
/**
- * igb_get_stats - Get System Network Statistics
+ * igb_get_stats64 - Get System Network Statistics
* @netdev: network interface device structure
+ * @stats: rtnl_link_stats64 pointer
*
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
**/
-static struct net_device_stats *igb_get_stats(struct net_device *netdev)
+static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *netdev,
+ struct rtnl_link_stats64 *stats)
{
- /* only return the current stats */
- return &netdev->stats;
+ struct igb_adapter *adapter = netdev_priv(netdev);
+
+ spin_lock(&adapter->stats64_lock);
+ igb_update_stats(adapter, &adapter->stats64);
+ memcpy(stats, &adapter->stats64, sizeof(*stats));
+ spin_unlock(&adapter->stats64_lock);
+
+ return stats;
}
/**
@@ -4298,15 +4327,17 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
* @adapter: board private structure
**/
-void igb_update_stats(struct igb_adapter *adapter)
+void igb_update_stats(struct igb_adapter *adapter,
+ struct rtnl_link_stats64 *net_stats)
{
- struct net_device_stats *net_stats = igb_get_stats(adapter->netdev);
struct e1000_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
u32 reg, mpc;
u16 phy_tmp;
int i;
u64 bytes, packets;
+ unsigned int start;
+ u64 _bytes, _packets;
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
@@ -4324,10 +4355,17 @@ void igb_update_stats(struct igb_adapter *adapter)
for (i = 0; i < adapter->num_rx_queues; i++) {
u32 rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0x0FFF;
struct igb_ring *ring = adapter->rx_ring[i];
+
ring->rx_stats.drops += rqdpc_tmp;
net_stats->rx_fifo_errors += rqdpc_tmp;
- bytes += ring->rx_stats.bytes;
- packets += ring->rx_stats.packets;
+
+ do {
+ start = u64_stats_fetch_begin_bh(&ring->rx_syncp);
+ _bytes = ring->rx_stats.bytes;
+ _packets = ring->rx_stats.packets;
+ } while (u64_stats_fetch_retry_bh(&ring->rx_syncp, start));
+ bytes += _bytes;
+ packets += _packets;
}
net_stats->rx_bytes = bytes;
@@ -4337,8 +4375,13 @@ void igb_update_stats(struct igb_adapter *adapter)
packets = 0;
for (i = 0; i < adapter->num_tx_queues; i++) {
struct igb_ring *ring = adapter->tx_ring[i];
- bytes += ring->tx_stats.bytes;
- packets += ring->tx_stats.packets;
+ do {
+ start = u64_stats_fetch_begin_bh(&ring->tx_syncp);
+ _bytes = ring->tx_stats.bytes;
+ _packets = ring->tx_stats.packets;
+ } while (u64_stats_fetch_retry_bh(&ring->tx_syncp, start));
+ bytes += _bytes;
+ packets += _packets;
}
net_stats->tx_bytes = bytes;
net_stats->tx_packets = packets;
@@ -4660,12 +4703,13 @@ static int igb_set_vf_promisc(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
u32 vmolr = rd32(E1000_VMOLR(vf));
struct vf_data_storage *vf_data = &adapter->vf_data[vf];
- vf_data->flags |= ~(IGB_VF_FLAG_UNI_PROMISC |
+ vf_data->flags &= ~(IGB_VF_FLAG_UNI_PROMISC |
IGB_VF_FLAG_MULTI_PROMISC);
vmolr &= ~(E1000_VMOLR_ROPE | E1000_VMOLR_ROMPE | E1000_VMOLR_MPME);
if (*msgbuf & E1000_VF_SET_PROMISC_MULTICAST) {
vmolr |= E1000_VMOLR_MPME;
+ vf_data->flags |= IGB_VF_FLAG_MULTI_PROMISC;
*msgbuf &= ~E1000_VF_SET_PROMISC_MULTICAST;
} else {
/*
@@ -5319,7 +5363,7 @@ static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct igb_buffer *bu
u64 regval;
/* if skb does not support hw timestamp or TX stamp not valid exit */
- if (likely(!buffer_info->shtx.hardware) ||
+ if (likely(!(buffer_info->tx_flags & SKBTX_HW_TSTAMP)) ||
!(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID))
return;
@@ -5389,7 +5433,10 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
!(test_bit(__IGB_DOWN, &adapter->state))) {
netif_wake_subqueue(netdev, tx_ring->queue_index);
+
+ u64_stats_update_begin(&tx_ring->tx_syncp);
tx_ring->tx_stats.restart_queue++;
+ u64_stats_update_end(&tx_ring->tx_syncp);
}
}
@@ -5429,9 +5476,11 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
}
tx_ring->total_bytes += total_bytes;
tx_ring->total_packets += total_packets;
+ u64_stats_update_begin(&tx_ring->tx_syncp);
tx_ring->tx_stats.bytes += total_bytes;
tx_ring->tx_stats.packets += total_packets;
- return (count < tx_ring->count);
+ u64_stats_update_end(&tx_ring->tx_syncp);
+ return count < tx_ring->count;
}
/**
@@ -5456,7 +5505,7 @@ static void igb_receive_skb(struct igb_q_vector *q_vector,
static inline void igb_rx_checksum_adv(struct igb_ring *ring,
u32 status_err, struct sk_buff *skb)
{
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Ignore Checksum bit is set or checksum is disabled through ethtool */
if (!(ring->flags & IGB_RING_FLAG_RX_CSUM) ||
@@ -5472,9 +5521,11 @@ static inline void igb_rx_checksum_adv(struct igb_ring *ring,
* packets, (aka let the stack check the crc32c)
*/
if ((skb->len == 60) &&
- (ring->flags & IGB_RING_FLAG_RX_SCTP_CSUM))
+ (ring->flags & IGB_RING_FLAG_RX_SCTP_CSUM)) {
+ u64_stats_update_begin(&ring->rx_syncp);
ring->rx_stats.csum_err++;
-
+ u64_stats_update_end(&ring->rx_syncp);
+ }
/* let the stack verify checksum errors */
return;
}
@@ -5500,7 +5551,7 @@ static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr,
* values must belong to this one here and therefore we don't need to
* compare any of the additional attributes stored for it.
*
- * If nothing went wrong, then it should have a skb_shared_tx that we
+ * If nothing went wrong, then it should have a shared tx_flags that we
* can turn into a skb_shared_hwtstamps.
*/
if (staterr & E1000_RXDADV_STAT_TSIP) {
@@ -5661,8 +5712,10 @@ next_desc:
rx_ring->total_packets += total_packets;
rx_ring->total_bytes += total_bytes;
+ u64_stats_update_begin(&rx_ring->rx_syncp);
rx_ring->rx_stats.packets += total_packets;
rx_ring->rx_stats.bytes += total_bytes;
+ u64_stats_update_end(&rx_ring->rx_syncp);
return cleaned;
}
@@ -5690,8 +5743,10 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count)
if ((bufsz < IGB_RXBUFFER_1024) && !buffer_info->page_dma) {
if (!buffer_info->page) {
buffer_info->page = netdev_alloc_page(netdev);
- if (!buffer_info->page) {
+ if (unlikely(!buffer_info->page)) {
+ u64_stats_update_begin(&rx_ring->rx_syncp);
rx_ring->rx_stats.alloc_failed++;
+ u64_stats_update_end(&rx_ring->rx_syncp);
goto no_buffers;
}
buffer_info->page_offset = 0;
@@ -5706,7 +5761,9 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count)
if (dma_mapping_error(rx_ring->dev,
buffer_info->page_dma)) {
buffer_info->page_dma = 0;
+ u64_stats_update_begin(&rx_ring->rx_syncp);
rx_ring->rx_stats.alloc_failed++;
+ u64_stats_update_end(&rx_ring->rx_syncp);
goto no_buffers;
}
}
@@ -5714,8 +5771,10 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count)
skb = buffer_info->skb;
if (!skb) {
skb = netdev_alloc_skb_ip_align(netdev, bufsz);
- if (!skb) {
+ if (unlikely(!skb)) {
+ u64_stats_update_begin(&rx_ring->rx_syncp);
rx_ring->rx_stats.alloc_failed++;
+ u64_stats_update_end(&rx_ring->rx_syncp);
goto no_buffers;
}
@@ -5729,7 +5788,9 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count)
if (dma_mapping_error(rx_ring->dev,
buffer_info->dma)) {
buffer_info->dma = 0;
+ u64_stats_update_begin(&rx_ring->rx_syncp);
rx_ring->rx_stats.alloc_failed++;
+ u64_stats_update_end(&rx_ring->rx_syncp);
goto no_buffers;
}
}
@@ -6092,7 +6153,7 @@ static void igb_restore_vlan(struct igb_adapter *adapter)
if (adapter->vlgrp) {
u16 vid;
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ for (vid = 0; vid < VLAN_N_VID; vid++) {
if (!vlan_group_get_device(adapter->vlgrp, vid))
continue;
igb_vlan_rx_add_vid(adapter->netdev, vid);
@@ -6107,6 +6168,13 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
mac->autoneg = 0;
+ /* 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;
+ }
+
switch (spddplx) {
case SPEED_10 + DUPLEX_HALF:
mac->forced_speed_duplex = ADVERTISE_10_HALF;
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c
index 103b3aa1afc2..33add708bcbe 100644
--- a/drivers/net/igbvf/ethtool.c
+++ b/drivers/net/igbvf/ethtool.c
@@ -153,7 +153,7 @@ static int igbvf_set_rx_csum(struct net_device *netdev, u32 data)
static u32 igbvf_get_tx_csum(struct net_device *netdev)
{
- return ((netdev->features & NETIF_F_IP_CSUM) != 0);
+ return (netdev->features & NETIF_F_IP_CSUM) != 0;
}
static int igbvf_set_tx_csum(struct net_device *netdev, u32 data)
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index c539f7c9c3e0..ebfaa68ee630 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -41,14 +41,12 @@
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
-#include <linux/pm_qos_params.h>
#include "igbvf.h"
#define DRV_VERSION "1.0.0-k0"
char igbvf_driver_name[] = "igbvf";
const char igbvf_driver_version[] = DRV_VERSION;
-static struct pm_qos_request_list igbvf_driver_pm_qos_req;
static const char igbvf_driver_string[] =
"Intel(R) Virtual Function Network Driver";
static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
@@ -103,7 +101,7 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter,
static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
u32 status_err, struct sk_buff *skb)
{
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Ignore Checksum bit is set or checksum is disabled through ethtool */
if ((status_err & E1000_RXD_STAT_IXSM) ||
@@ -845,7 +843,7 @@ static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring)
}
adapter->net_stats.tx_bytes += total_bytes;
adapter->net_stats.tx_packets += total_packets;
- return (count < tx_ring->count);
+ return count < tx_ring->count;
}
static irqreturn_t igbvf_msix_other(int irq, void *data)
@@ -1256,7 +1254,7 @@ static void igbvf_restore_vlan(struct igbvf_adapter *adapter)
if (!adapter->vlgrp)
return;
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ for (vid = 0; vid < VLAN_N_VID; vid++) {
if (!vlan_group_get_device(adapter->vlgrp, vid))
continue;
igbvf_vlan_rx_add_vid(adapter->netdev, vid);
@@ -2904,8 +2902,6 @@ static int __init igbvf_init_module(void)
printk(KERN_INFO "%s\n", igbvf_copyright);
ret = pci_register_driver(&igbvf_driver);
- pm_qos_add_request(&igbvf_driver_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
- PM_QOS_DEFAULT_VALUE);
return ret;
}
@@ -2920,7 +2916,6 @@ module_init(igbvf_init_module);
static void __exit igbvf_exit_module(void)
{
pci_unregister_driver(&igbvf_driver);
- pm_qos_remove_request(&igbvf_driver_pm_qos_req);
}
module_exit(igbvf_exit_module);
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 0b3f6df5cff7..c8ee8d28767b 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -827,7 +827,7 @@ static void ioc3_mii_start(struct ioc3_private *ip)
{
ip->ioc3_timer.expires = jiffies + (12 * HZ)/10; /* 1.2 sec. */
ip->ioc3_timer.data = (unsigned long) ip;
- ip->ioc3_timer.function = &ioc3_timer;
+ ip->ioc3_timer.function = ioc3_timer;
add_timer(&ip->ioc3_timer);
}
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 72e3d2da9e9f..dc0198092343 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -1213,7 +1213,7 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev,
skb_put(skb, framelen);
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
netif_rx(skb);
sp->rx_buff[entry] = NULL;
}
@@ -1278,7 +1278,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
jumbo->skb->protocol =
eth_type_trans(jumbo->skb, dev);
- jumbo->skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(jumbo->skb);
netif_rx(jumbo->skb);
}
}
@@ -1476,7 +1476,7 @@ static int ipg_nic_rx(struct net_device *dev)
* IP/TCP/UDP frame was received. Let the
* upper layer decide.
*/
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Hand off frame for higher layer processing.
* The function netif_rx() releases the sk_buff
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 48bd5ec9f29b..b626cccbccd1 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -217,7 +217,7 @@ toshoboe_checkfcs (unsigned char *buf, int len)
for (i = 0; i < len; ++i)
fcs.value = irda_fcs (fcs.value, *(buf++));
- return (fcs.value == GOOD_FCS);
+ return fcs.value == GOOD_FCS;
}
/***********************************************************************/
@@ -759,7 +759,7 @@ toshoboe_maketestpacket (unsigned char *buf, int badcrc, int fir)
if (fir)
{
memset (buf, 0, TT_LEN);
- return (TT_LEN);
+ return TT_LEN;
}
fcs.value = INIT_FCS;
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 4441fa3389c2..e4ea61944c22 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1124,11 +1124,11 @@ static int stir421x_patch_device(struct irda_usb_cb *self)
* The actual image starts after the "STMP" keyword
* so forward to the firmware header tag
*/
- for (i = 0; (fw->data[i] != STIR421X_PATCH_END_OF_HDR_TAG) &&
- (i < fw->size); i++) ;
+ for (i = 0; i < fw->size && fw->data[i] !=
+ STIR421X_PATCH_END_OF_HDR_TAG; i++) ;
/* here we check for the out of buffer case */
- if ((STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) &&
- (i < STIR421X_PATCH_CODE_OFFSET)) {
+ if (i < STIR421X_PATCH_CODE_OFFSET && i < fw->size &&
+ STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) {
if (!memcmp(fw->data + i + 1, STIR421X_PATCH_STMP_TAG,
sizeof(STIR421X_PATCH_STMP_TAG) - 1)) {
@@ -1514,7 +1514,7 @@ static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_
IRDA_DEBUG(0, "%s(), And our endpoints are : in=%02X, out=%02X (%d), int=%02X\n",
__func__, self->bulk_in_ep, self->bulk_out_ep, self->bulk_out_mtu, self->bulk_int_ep);
- return((self->bulk_in_ep != 0) && (self->bulk_out_ep != 0));
+ return (self->bulk_in_ep != 0) && (self->bulk_out_ep != 0);
}
#ifdef IU_DUMP_CLASS_DESC
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 5b1036ac38d7..74b20f179cea 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -734,7 +734,7 @@ static int mcs_net_open(struct net_device *netdev)
}
if (!mcs_setup_urbs(mcs))
- goto error3;
+ goto error3;
ret = mcs_receive_start(mcs);
if (ret)
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index e30cdbb14745..559fe854d76d 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -1348,7 +1348,7 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed)
outb(bank, iobase+BSR);
/* Make sure interrupt handlers keep the proper interrupt mask */
- return(ier);
+ return ier;
}
/*
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 51d74447f8f8..efe05bb34dd8 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -336,7 +336,7 @@ static int sirdev_is_receiving(struct sir_dev *dev)
if (!atomic_read(&dev->enable_rx))
return 0;
- return (dev->rx_buff.state != OUTSIDE_FRAME);
+ return dev->rx_buff.state != OUTSIDE_FRAME;
}
int sirdev_set_dongle(struct sir_dev *dev, IRDA_DONGLE type)
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 850ca1c5ee19..8c57bfb5f098 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -2051,7 +2051,7 @@ static int smsc_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len)
*/
static int smsc_ircc_is_receiving(struct smsc_ircc_cb *self)
{
- return (self->rx_buff.state != OUTSIDE_FRAME);
+ return self->rx_buff.state != OUTSIDE_FRAME;
}
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index e5698fa30a4f..41c96b3d8152 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -219,7 +219,7 @@ static inline int read_reg(struct stir_cb *stir, __u16 reg,
static inline int isfir(u32 speed)
{
- return (speed == 4000000);
+ return speed == 4000000;
}
/*
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index b0a6cd815be1..67c0ad42d818 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -1182,12 +1182,13 @@ F01_E */
skb = dev_alloc_skb(len + 1 - 4);
/*
- * if frame size,data ptr,or skb ptr are wrong ,the get next
+ * if frame size, data ptr, or skb ptr are wrong, then get next
* entry.
*/
if ((skb == NULL) || (skb->data == NULL) ||
(self->rx_buff.data == NULL) || (len < 6)) {
self->netdev->stats.rx_dropped++;
+ kfree_skb(skb);
return TRUE;
}
skb_reserve(skb, 1);
diff --git a/drivers/net/irda/via-ircc.h b/drivers/net/irda/via-ircc.h
index 5a84822b5a43..c6f58482b769 100644
--- a/drivers/net/irda/via-ircc.h
+++ b/drivers/net/irda/via-ircc.h
@@ -238,7 +238,7 @@ static void WriteLPCReg(int iRegNum, unsigned char iVal)
static __u8 ReadReg(unsigned int BaseAddr, int iRegNum)
{
- return ((__u8) inb(BaseAddr + iRegNum));
+ return (__u8) inb(BaseAddr + iRegNum);
}
static void WriteReg(unsigned int BaseAddr, int iRegNum, unsigned char iVal)
diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h
index 3f24a1f33022..d66fab854bf1 100644
--- a/drivers/net/irda/vlsi_ir.h
+++ b/drivers/net/irda/vlsi_ir.h
@@ -595,7 +595,7 @@ struct ring_descr {
static inline int rd_is_active(struct ring_descr *rd)
{
- return ((rd->hw->rd_status & RD_ACTIVE) != 0);
+ return (rd->hw->rd_status & RD_ACTIVE) != 0;
}
static inline void rd_activate(struct ring_descr *rd)
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index ba1de5973fb2..8df645e78f2e 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -1524,7 +1524,7 @@ static void veth_receive(struct veth_lpar_connection *cnx,
skb_put(skb, length);
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
netif_rx(skb); /* send it up */
dev->stats.rx_packets++;
dev->stats.rx_bytes += length;
diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c
index 813993f9c65c..c982ab9f9005 100644
--- a/drivers/net/ixgb/ixgb_ee.c
+++ b/drivers/net/ixgb/ixgb_ee.c
@@ -296,12 +296,12 @@ ixgb_wait_eeprom_command(struct ixgb_hw *hw)
eecd_reg = IXGB_READ_REG(hw, EECD);
if (eecd_reg & IXGB_EECD_DO)
- return (true);
+ return true;
udelay(50);
}
ASSERT(0);
- return (false);
+ return false;
}
/******************************************************************************
@@ -327,9 +327,9 @@ ixgb_validate_eeprom_checksum(struct ixgb_hw *hw)
checksum += ixgb_read_eeprom(hw, i);
if (checksum == (u16) EEPROM_SUM)
- return (true);
+ return true;
else
- return (false);
+ return false;
}
/******************************************************************************
@@ -439,7 +439,7 @@ ixgb_read_eeprom(struct ixgb_hw *hw,
/* End this read operation */
ixgb_standby_eeprom(hw);
- return (data);
+ return data;
}
/******************************************************************************
@@ -476,16 +476,16 @@ ixgb_get_eeprom_data(struct ixgb_hw *hw)
/* clear the init_ctrl_reg_1 to signify that the cache is
* invalidated */
ee_map->init_ctrl_reg_1 = cpu_to_le16(EEPROM_ICW1_SIGNATURE_CLEAR);
- return (false);
+ return false;
}
if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK))
!= cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) {
pr_debug("Signature invalid\n");
- return(false);
+ return false;
}
- return(true);
+ return true;
}
/******************************************************************************
@@ -505,7 +505,7 @@ ixgb_check_and_get_eeprom_data (struct ixgb_hw* hw)
if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK))
== cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) {
- return (true);
+ return true;
} else {
return ixgb_get_eeprom_data(hw);
}
@@ -526,10 +526,10 @@ ixgb_get_eeprom_word(struct ixgb_hw *hw, u16 index)
if ((index < IXGB_EEPROM_SIZE) &&
(ixgb_check_and_get_eeprom_data(hw) == true)) {
- return(hw->eeprom[index]);
+ return hw->eeprom[index];
}
- return(0);
+ return 0;
}
/******************************************************************************
@@ -570,10 +570,10 @@ u32
ixgb_get_ee_pba_number(struct ixgb_hw *hw)
{
if (ixgb_check_and_get_eeprom_data(hw) == true)
- return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
- | (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16));
+ return le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
+ | (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16);
- return(0);
+ return 0;
}
@@ -591,8 +591,8 @@ ixgb_get_ee_device_id(struct ixgb_hw *hw)
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == true)
- return (le16_to_cpu(ee_map->device_id));
+ return le16_to_cpu(ee_map->device_id);
- return (0);
+ return 0;
}
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index a4ed96caae69..43994c199991 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -410,7 +410,7 @@ static int
ixgb_get_eeprom_len(struct net_device *netdev)
{
/* return size in bytes */
- return (IXGB_EEPROM_SIZE << 1);
+ return IXGB_EEPROM_SIZE << 1;
}
static int
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index 397acabccab6..6cb2e42ff4c1 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -167,7 +167,7 @@ ixgb_adapter_stop(struct ixgb_hw *hw)
/* Clear any pending interrupt events. */
icr_reg = IXGB_READ_REG(hw, ICR);
- return (ctrl_reg & IXGB_CTRL0_RST);
+ return ctrl_reg & IXGB_CTRL0_RST;
}
@@ -209,7 +209,7 @@ ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
xpak_vendor = ixgb_xpak_vendor_infineon;
}
- return (xpak_vendor);
+ return xpak_vendor;
}
/******************************************************************************
@@ -273,7 +273,7 @@ ixgb_identify_phy(struct ixgb_hw *hw)
if (hw->subsystem_vendor_id == SUN_SUBVENDOR_ID)
phy_type = ixgb_phy_type_bcm;
- return (phy_type);
+ return phy_type;
}
/******************************************************************************
@@ -366,7 +366,7 @@ ixgb_init_hw(struct ixgb_hw *hw)
/* 82597EX errata: Call check-for-link in case lane deskew is locked */
ixgb_check_for_link(hw);
- return (status);
+ return status;
}
/******************************************************************************
@@ -531,7 +531,7 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw,
}
hash_value &= 0xFFF;
- return (hash_value);
+ return hash_value;
}
/******************************************************************************
@@ -715,7 +715,7 @@ ixgb_setup_fc(struct ixgb_hw *hw)
}
IXGB_WRITE_REG(hw, FCRTH, hw->fc.high_water);
}
- return (status);
+ return status;
}
/******************************************************************************
@@ -1140,7 +1140,7 @@ mac_addr_valid(u8 *mac_addr)
pr_debug("MAC address is all zeros\n");
is_valid = false;
}
- return (is_valid);
+ return is_valid;
}
/******************************************************************************
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 45fc89b9ba64..666207a9c039 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -446,8 +446,10 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
NETIF_F_HW_VLAN_FILTER;
netdev->features |= NETIF_F_TSO;
- if (pci_using_dac)
+ if (pci_using_dac) {
netdev->features |= NETIF_F_HIGHDMA;
+ netdev->vlan_features |= NETIF_F_HIGHDMA;
+ }
/* make sure the EEPROM is good */
@@ -470,7 +472,7 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->part_num = ixgb_get_ee_pba_number(&adapter->hw);
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &ixgb_watchdog;
+ adapter->watchdog_timer.function = ixgb_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task);
@@ -1905,7 +1907,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter,
*/
if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
(!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
return;
}
@@ -1913,7 +1915,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter,
/* now look at the TCP checksum error bit */
if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
/* let the stack verify checksum errors */
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
adapter->hw_csum_rx_error++;
} else {
/* TCP checksum is good */
@@ -2221,7 +2223,7 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter)
if (adapter->vlgrp) {
u16 vid;
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ for (vid = 0; vid < VLAN_N_VID; vid++) {
if (!vlan_group_get_device(adapter->vlgrp, vid))
continue;
ixgb_vlan_rx_add_vid(adapter->netdev, vid);
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 9e15eb93860e..ed8703cfffb7 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -28,10 +28,13 @@
#ifndef _IXGBE_H_
#define _IXGBE_H_
+#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
+#include <linux/cpumask.h>
#include <linux/aer.h>
+#include <linux/if_vlan.h>
#include "ixgbe_type.h"
#include "ixgbe_common.h"
@@ -69,15 +72,20 @@
#define IXGBE_MAX_FCPAUSE 0xFFFF
/* Supported Rx Buffer Sizes */
-#define IXGBE_RXBUFFER_64 64 /* Used for packet split */
-#define IXGBE_RXBUFFER_128 128 /* Used for packet split */
-#define IXGBE_RXBUFFER_256 256 /* Used for packet split */
+#define IXGBE_RXBUFFER_512 512 /* Used for packet split */
#define IXGBE_RXBUFFER_2048 2048
#define IXGBE_RXBUFFER_4096 4096
#define IXGBE_RXBUFFER_8192 8192
#define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */
-#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256
+/*
+ * NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN mans we
+ * reserve 2 more, and skb_shared_info adds an additional 384 bytes more,
+ * this adds up to 512 bytes of extra data meaning the smallest allocation
+ * we could have is 1K.
+ * i.e. RXBUFFER_512 --> size-1024 slab
+ */
+#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_512
#define MAXIMUM_ETHERNET_VLAN_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
@@ -174,8 +182,9 @@ struct ixgbe_ring {
*/
struct ixgbe_queue_stats stats;
- unsigned long reinit_state;
+ struct u64_stats_sync syncp;
int numa_node;
+ unsigned long reinit_state;
u64 rsc_count; /* stat for coalesced packets */
u64 rsc_flush; /* stats for flushed packets */
u32 restart_queue; /* track tx queue restarts */
@@ -236,6 +245,7 @@ struct ixgbe_q_vector {
u8 tx_itr;
u8 rx_itr;
u32 eitr;
+ cpumask_var_t affinity_mask;
};
/* Helper macros to switch between ints/sec and what the register uses.
@@ -251,11 +261,11 @@ struct ixgbe_q_vector {
(R)->next_to_clean - (R)->next_to_use - 1)
#define IXGBE_RX_DESC_ADV(R, i) \
- (&(((union ixgbe_adv_rx_desc *)((R).desc))[i]))
+ (&(((union ixgbe_adv_rx_desc *)((R)->desc))[i]))
#define IXGBE_TX_DESC_ADV(R, i) \
- (&(((union ixgbe_adv_tx_desc *)((R).desc))[i]))
+ (&(((union ixgbe_adv_tx_desc *)((R)->desc))[i]))
#define IXGBE_TX_CTXTDESC_ADV(R, i) \
- (&(((struct ixgbe_adv_tx_context_desc *)((R).desc))[i]))
+ (&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i]))
#define IXGBE_MAX_JUMBO_FRAME_SIZE 16128
#ifdef IXGBE_FCOE
@@ -280,7 +290,7 @@ struct ixgbe_q_vector {
/* board specific private data structure */
struct ixgbe_adapter {
struct timer_list watchdog_timer;
- struct vlan_group *vlgrp;
+ 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];
@@ -448,9 +458,20 @@ extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *)
extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,struct ixgbe_ring *);
+extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,struct ixgbe_ring *);
extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
+extern netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *,
+ struct net_device *,
+ struct ixgbe_adapter *,
+ struct ixgbe_ring *);
+extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *,
+ struct ixgbe_tx_buffer *);
+extern void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *rx_ring,
+ int cleaned_count);
extern void ixgbe_write_eitr(struct ixgbe_q_vector *);
extern int ethtool_ioctl(struct ifreq *ifr);
extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 3e06a61da921..0bd8fbb5bfd0 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -39,20 +39,20 @@
#define IXGBE_82599_MC_TBL_SIZE 128
#define IXGBE_82599_VFT_TBL_SIZE 128
-void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
-void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
-void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
-s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
- ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete);
+static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
+static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
+static void ixgbe_flap_tx_laser_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);
static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg,
bool autoneg_wait_to_complete);
-s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
- bool autoneg_wait_to_complete);
-s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
+static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
+ bool autoneg_wait_to_complete);
+static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg,
bool autoneg_wait_to_complete);
@@ -369,7 +369,7 @@ out:
* Configures link settings based on values in the ixgbe_hw struct.
* Restarts the link. Performs autonegotiation if needed.
**/
-s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
+static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
bool autoneg_wait_to_complete)
{
u32 autoc_reg;
@@ -418,7 +418,7 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
* PHY states. This includes selectively shutting down the Tx
* laser on the PHY, effectively halting physical link.
**/
-void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
{
u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
@@ -437,7 +437,7 @@ void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
* PHY states. This includes selectively turning on the Tx
* laser on the PHY, effectively starting physical link.
**/
-void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
{
u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
@@ -460,7 +460,7 @@ void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
* end. This is consistent with true clause 37 autoneg, which also
* involves a loss of signal.
**/
-void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
{
hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n");
@@ -729,7 +729,7 @@ out:
*
* Set the link speed in the AUTOC register and restarts link.
**/
-s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
+static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
ixgbe_link_speed speed, bool autoneg,
bool autoneg_wait_to_complete)
{
@@ -1415,92 +1415,6 @@ s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr)
}
/**
- * ixgbe_atr_set_src_ipv6_82599 - Sets the source IPv6 address
- * @input: input stream to modify
- * @src_addr_1: the first 4 bytes of the IP address to load
- * @src_addr_2: the second 4 bytes of the IP address to load
- * @src_addr_3: the third 4 bytes of the IP address to load
- * @src_addr_4: the fourth 4 bytes of the IP address to load
- **/
-s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input,
- u32 src_addr_1, u32 src_addr_2,
- u32 src_addr_3, u32 src_addr_4)
-{
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] =
- (src_addr_4 >> 8) & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] =
- (src_addr_4 >> 16) & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] = src_addr_4 >> 24;
-
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4] = src_addr_3 & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] =
- (src_addr_3 >> 8) & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] =
- (src_addr_3 >> 16) & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] = src_addr_3 >> 24;
-
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8] = src_addr_2 & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] =
- (src_addr_2 >> 8) & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] =
- (src_addr_2 >> 16) & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] = src_addr_2 >> 24;
-
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12] = src_addr_1 & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] =
- (src_addr_1 >> 8) & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] =
- (src_addr_1 >> 16) & 0xff;
- input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] = src_addr_1 >> 24;
-
- return 0;
-}
-
-/**
- * ixgbe_atr_set_dst_ipv6_82599 - Sets the destination IPv6 address
- * @input: input stream to modify
- * @dst_addr_1: the first 4 bytes of the IP address to load
- * @dst_addr_2: the second 4 bytes of the IP address to load
- * @dst_addr_3: the third 4 bytes of the IP address to load
- * @dst_addr_4: the fourth 4 bytes of the IP address to load
- **/
-s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input,
- u32 dst_addr_1, u32 dst_addr_2,
- u32 dst_addr_3, u32 dst_addr_4)
-{
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] =
- (dst_addr_4 >> 8) & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] =
- (dst_addr_4 >> 16) & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] = dst_addr_4 >> 24;
-
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4] = dst_addr_3 & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] =
- (dst_addr_3 >> 8) & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] =
- (dst_addr_3 >> 16) & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] = dst_addr_3 >> 24;
-
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8] = dst_addr_2 & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] =
- (dst_addr_2 >> 8) & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] =
- (dst_addr_2 >> 16) & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] = dst_addr_2 >> 24;
-
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12] = dst_addr_1 & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] =
- (dst_addr_1 >> 8) & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] =
- (dst_addr_1 >> 16) & 0xff;
- input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] = dst_addr_1 >> 24;
-
- return 0;
-}
-
-/**
* ixgbe_atr_set_src_port_82599 - Sets the source port
* @input: input stream to modify
* @src_port: the source port to load
@@ -1540,19 +1454,6 @@ s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte)
}
/**
- * ixgbe_atr_set_vm_pool_82599 - Sets the Virtual Machine pool
- * @input: input stream to modify
- * @vm_pool: the Virtual Machine pool to load
- **/
-s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input,
- u8 vm_pool)
-{
- input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool;
-
- return 0;
-}
-
-/**
* ixgbe_atr_set_l4type_82599 - Sets the layer 4 packet type
* @input: input stream to modify
* @l4type: the layer 4 type value to load
@@ -1645,41 +1546,6 @@ static s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input,
}
/**
- * ixgbe_atr_get_dst_ipv6_82599 - Gets the destination IPv6 address
- * @input: input stream to search
- * @dst_addr_1: the first 4 bytes of the IP address to load
- * @dst_addr_2: the second 4 bytes of the IP address to load
- * @dst_addr_3: the third 4 bytes of the IP address to load
- * @dst_addr_4: the fourth 4 bytes of the IP address to load
- **/
-s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input,
- u32 *dst_addr_1, u32 *dst_addr_2,
- u32 *dst_addr_3, u32 *dst_addr_4)
-{
- *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12];
- *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] << 8;
- *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] << 16;
- *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] << 24;
-
- *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8];
- *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] << 8;
- *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] << 16;
- *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] << 24;
-
- *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4];
- *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] << 8;
- *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] << 16;
- *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] << 24;
-
- *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET];
- *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] << 8;
- *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] << 16;
- *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] << 24;
-
- return 0;
-}
-
-/**
* ixgbe_atr_get_src_port_82599 - Gets the source port
* @input: input stream to modify
* @src_port: the source port to load
@@ -1732,19 +1598,6 @@ static s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input,
}
/**
- * ixgbe_atr_get_vm_pool_82599 - Gets the Virtual Machine pool
- * @input: input stream to modify
- * @vm_pool: the Virtual Machine pool to load
- **/
-s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input,
- u8 *vm_pool)
-{
- *vm_pool = input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET];
-
- return 0;
-}
-
-/**
* ixgbe_atr_get_l4type_82599 - Gets the layer 4 packet type
* @input: input stream to modify
* @l4type: the layer 4 type value to load
@@ -1910,56 +1763,27 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
(dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT)));
/*
- * Program the relevant mask registers. If src/dst_port or src/dst_addr
- * are zero, then assume a full mask for that field. Also assume that
- * a VLAN of 0 is unspecified, so mask that out as well. L4type
- * cannot be masked out in this implementation.
+ * Program the relevant mask registers. L4type cannot be
+ * masked out in this implementation.
*
* This also assumes IPv4 only. IPv6 masking isn't supported at this
* point in time.
*/
- if (src_ipv4 == 0)
- IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, 0xffffffff);
- else
- IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask);
-
- if (dst_ipv4 == 0)
- IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, 0xffffffff);
- else
- IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask);
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask);
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask);
switch (l4type & IXGBE_ATR_L4TYPE_MASK) {
case IXGBE_ATR_L4TYPE_TCP:
- if (src_port == 0)
- IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xffff);
- else
- IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
- input_masks->src_port_mask);
-
- if (dst_port == 0)
- IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
- (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) |
- (0xffff << 16)));
- else
- IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
- (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) |
- (input_masks->dst_port_mask << 16)));
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, input_masks->src_port_mask);
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
+ (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) |
+ (input_masks->dst_port_mask << 16)));
break;
case IXGBE_ATR_L4TYPE_UDP:
- if (src_port == 0)
- IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xffff);
- else
- IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
- input_masks->src_port_mask);
-
- if (dst_port == 0)
- IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
- (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) |
- (0xffff << 16)));
- else
- IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
- (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) |
- (input_masks->src_port_mask << 16)));
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, input_masks->src_port_mask);
+ IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
+ (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) |
+ (input_masks->src_port_mask << 16)));
break;
default:
/* this already would have failed above */
@@ -1967,11 +1791,11 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
}
/* Program the last mask register, FDIRM */
- if (input_masks->vlan_id_mask || !vlan_id)
+ if (input_masks->vlan_id_mask)
/* Mask both VLAN and VLANP - bits 0 and 1 */
fdirm |= 0x3;
- if (input_masks->data_mask || !flex_bytes)
+ if (input_masks->data_mask)
/* Flex bytes need masking, so mask the whole thing - bit 4 */
fdirm |= 0x10;
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 9595b1bfb8dd..e3eca1316389 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -52,6 +52,7 @@ static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
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);
/**
* ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
@@ -637,7 +638,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;
@@ -2449,7 +2450,7 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
* return the VLVF index where this VLAN id should be placed
*
**/
-s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
+static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
{
u32 bits = 0;
u32 first_empty_slot = 0;
@@ -2704,48 +2705,3 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
return 0;
}
-
-/**
- * ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from
- * the EEPROM
- * @hw: pointer to hardware structure
- * @wwnn_prefix: the alternative WWNN prefix
- * @wwpn_prefix: the alternative WWPN prefix
- *
- * This function will read the EEPROM from the alternative SAN MAC address
- * block to check the support for the alternative WWNN/WWPN prefix support.
- **/
-s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
- u16 *wwpn_prefix)
-{
- u16 offset, caps;
- u16 alt_san_mac_blk_offset;
-
- /* clear output first */
- *wwnn_prefix = 0xFFFF;
- *wwpn_prefix = 0xFFFF;
-
- /* check if alternative SAN MAC is supported */
- hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR,
- &alt_san_mac_blk_offset);
-
- if ((alt_san_mac_blk_offset == 0) ||
- (alt_san_mac_blk_offset == 0xFFFF))
- goto wwn_prefix_out;
-
- /* check capability in alternative san mac address block */
- offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
- hw->eeprom.ops.read(hw, offset, &caps);
- if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
- goto wwn_prefix_out;
-
- /* get the corresponding prefix for WWNN/WWPN */
- offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
- hw->eeprom.ops.read(hw, offset, wwnn_prefix);
-
- offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET;
- hw->eeprom.ops.read(hw, offset, wwpn_prefix);
-
-wwn_prefix_out:
- return 0;
-}
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index 5cf15aa11cac..424c223437dc 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -52,7 +52,6 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
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);
diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c
index 9aea4f04bbd2..8bb9ddb6dffe 100644
--- a/drivers/net/ixgbe/ixgbe_dcb.c
+++ b/drivers/net/ixgbe/ixgbe_dcb.c
@@ -34,98 +34,6 @@
#include "ixgbe_dcb_82599.h"
/**
- * ixgbe_dcb_config - Struct containing DCB settings.
- * @dcb_config: Pointer to DCB config structure
- *
- * This function checks DCB rules for DCB settings.
- * The following rules are checked:
- * 1. The sum of bandwidth percentages of all Bandwidth Groups must total 100%.
- * 2. The sum of bandwidth percentages of all Traffic Classes within a Bandwidth
- * Group must total 100.
- * 3. A Traffic Class should not be set to both Link Strict Priority
- * and Group Strict Priority.
- * 4. Link strict Bandwidth Groups can only have link strict traffic classes
- * with zero bandwidth.
- */
-s32 ixgbe_dcb_check_config(struct ixgbe_dcb_config *dcb_config)
-{
- struct tc_bw_alloc *p;
- s32 ret_val = 0;
- u8 i, j, bw = 0, bw_id;
- u8 bw_sum[2][MAX_BW_GROUP];
- bool link_strict[2][MAX_BW_GROUP];
-
- memset(bw_sum, 0, sizeof(bw_sum));
- memset(link_strict, 0, sizeof(link_strict));
-
- /* First Tx, then Rx */
- for (i = 0; i < 2; i++) {
- /* Check each traffic class for rule violation */
- for (j = 0; j < MAX_TRAFFIC_CLASS; j++) {
- p = &dcb_config->tc_config[j].path[i];
-
- bw = p->bwg_percent;
- bw_id = p->bwg_id;
-
- if (bw_id >= MAX_BW_GROUP) {
- ret_val = DCB_ERR_CONFIG;
- goto err_config;
- }
- if (p->prio_type == prio_link) {
- link_strict[i][bw_id] = true;
- /* Link strict should have zero bandwidth */
- if (bw) {
- ret_val = DCB_ERR_LS_BW_NONZERO;
- goto err_config;
- }
- } else if (!bw) {
- /*
- * Traffic classes without link strict
- * should have non-zero bandwidth.
- */
- ret_val = DCB_ERR_TC_BW_ZERO;
- goto err_config;
- }
- bw_sum[i][bw_id] += bw;
- }
-
- bw = 0;
-
- /* Check each bandwidth group for rule violation */
- for (j = 0; j < MAX_BW_GROUP; j++) {
- bw += dcb_config->bw_percentage[i][j];
- /*
- * Sum of bandwidth percentages of all traffic classes
- * within a Bandwidth Group must total 100 except for
- * link strict group (zero bandwidth).
- */
- if (link_strict[i][j]) {
- if (bw_sum[i][j]) {
- /*
- * Link strict group should have zero
- * bandwidth.
- */
- ret_val = DCB_ERR_LS_BWG_NONZERO;
- goto err_config;
- }
- } else if (bw_sum[i][j] != BW_PERCENT &&
- bw_sum[i][j] != 0) {
- ret_val = DCB_ERR_TC_BW;
- goto err_config;
- }
- }
-
- if (bw != BW_PERCENT) {
- ret_val = DCB_ERR_BW_GROUP;
- goto err_config;
- }
- }
-
-err_config:
- return ret_val;
-}
-
-/**
* ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits
* @ixgbe_dcb_config: Struct containing DCB settings.
* @direction: Configuring either Tx or Rx.
@@ -203,133 +111,6 @@ out:
}
/**
- * ixgbe_dcb_get_tc_stats - Returns status of each traffic class
- * @hw: pointer to hardware structure
- * @stats: pointer to statistics structure
- * @tc_count: Number of elements in bwg_array.
- *
- * This function returns the status data for each of the Traffic Classes in use.
- */
-s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
- u8 tc_count)
-{
- s32 ret = 0;
- if (hw->mac.type == ixgbe_mac_82598EB)
- ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count);
- else if (hw->mac.type == ixgbe_mac_82599EB)
- ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
- return ret;
-}
-
-/**
- * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class
- * hw - pointer to hardware structure
- * stats - pointer to statistics structure
- * tc_count - Number of elements in bwg_array.
- *
- * This function returns the CBFC status data for each of the Traffic Classes.
- */
-s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
- u8 tc_count)
-{
- s32 ret = 0;
- if (hw->mac.type == ixgbe_mac_82598EB)
- ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count);
- else if (hw->mac.type == ixgbe_mac_82599EB)
- ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
- return ret;
-}
-
-/**
- * ixgbe_dcb_config_rx_arbiter - Config Rx arbiter
- * @hw: pointer to hardware structure
- * @dcb_config: pointer to ixgbe_dcb_config structure
- *
- * Configure Rx Data Arbiter and credits for each traffic class.
- */
-s32 ixgbe_dcb_config_rx_arbiter(struct ixgbe_hw *hw,
- struct ixgbe_dcb_config *dcb_config)
-{
- s32 ret = 0;
- if (hw->mac.type == ixgbe_mac_82598EB)
- ret = ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config);
- else if (hw->mac.type == ixgbe_mac_82599EB)
- ret = ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config);
- return ret;
-}
-
-/**
- * ixgbe_dcb_config_tx_desc_arbiter - Config Tx Desc arbiter
- * @hw: pointer to hardware structure
- * @dcb_config: pointer to ixgbe_dcb_config structure
- *
- * Configure Tx Descriptor Arbiter and credits for each traffic class.
- */
-s32 ixgbe_dcb_config_tx_desc_arbiter(struct ixgbe_hw *hw,
- struct ixgbe_dcb_config *dcb_config)
-{
- s32 ret = 0;
- if (hw->mac.type == ixgbe_mac_82598EB)
- ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config);
- else if (hw->mac.type == ixgbe_mac_82599EB)
- ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config);
- return ret;
-}
-
-/**
- * ixgbe_dcb_config_tx_data_arbiter - Config Tx data arbiter
- * @hw: pointer to hardware structure
- * @dcb_config: pointer to ixgbe_dcb_config structure
- *
- * Configure Tx Data Arbiter and credits for each traffic class.
- */
-s32 ixgbe_dcb_config_tx_data_arbiter(struct ixgbe_hw *hw,
- struct ixgbe_dcb_config *dcb_config)
-{
- s32 ret = 0;
- if (hw->mac.type == ixgbe_mac_82598EB)
- ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config);
- else if (hw->mac.type == ixgbe_mac_82599EB)
- ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config);
- return ret;
-}
-
-/**
- * ixgbe_dcb_config_pfc - Config priority flow control
- * @hw: pointer to hardware structure
- * @dcb_config: pointer to ixgbe_dcb_config structure
- *
- * Configure Priority Flow Control for each traffic class.
- */
-s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw,
- struct ixgbe_dcb_config *dcb_config)
-{
- s32 ret = 0;
- if (hw->mac.type == ixgbe_mac_82598EB)
- ret = ixgbe_dcb_config_pfc_82598(hw, dcb_config);
- else if (hw->mac.type == ixgbe_mac_82599EB)
- ret = ixgbe_dcb_config_pfc_82599(hw, dcb_config);
- return ret;
-}
-
-/**
- * ixgbe_dcb_config_tc_stats - Config traffic class statistics
- * @hw: pointer to hardware structure
- *
- * 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(struct ixgbe_hw *hw)
-{
- s32 ret = 0;
- if (hw->mac.type == ixgbe_mac_82598EB)
- ret = ixgbe_dcb_config_tc_stats_82598(hw);
- else if (hw->mac.type == ixgbe_mac_82599EB)
- ret = ixgbe_dcb_config_tc_stats_82599(hw);
- return ret;
-}
-
-/**
* ixgbe_dcb_hw_config - Config and enable DCB
* @hw: pointer to hardware structure
* @dcb_config: pointer to ixgbe_dcb_config structure
diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h
index 5caafd4afbc3..eb1059f09da0 100644
--- a/drivers/net/ixgbe/ixgbe_dcb.h
+++ b/drivers/net/ixgbe/ixgbe_dcb.h
@@ -149,27 +149,9 @@ struct ixgbe_dcb_config {
/* DCB driver APIs */
-/* DCB rule checking function.*/
-s32 ixgbe_dcb_check_config(struct ixgbe_dcb_config *config);
-
/* DCB credits calculation */
s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, u8);
-/* DCB PFC functions */
-s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *, struct ixgbe_dcb_config *g);
-s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *, struct ixgbe_hw_stats *, u8);
-
-/* DCB traffic class stats */
-s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *);
-s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *, struct ixgbe_hw_stats *, u8);
-
-/* DCB config arbiters */
-s32 ixgbe_dcb_config_tx_desc_arbiter(struct ixgbe_hw *,
- struct ixgbe_dcb_config *);
-s32 ixgbe_dcb_config_tx_data_arbiter(struct ixgbe_hw *,
- struct ixgbe_dcb_config *);
-s32 ixgbe_dcb_config_rx_arbiter(struct ixgbe_hw *, struct ixgbe_dcb_config *);
-
/* DCB hw initialization */
s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *);
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c
index f0e9279d4669..50288bcadc59 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c
@@ -32,65 +32,6 @@
#include "ixgbe_dcb_82598.h"
/**
- * ixgbe_dcb_get_tc_stats_82598 - Return status data for each traffic class
- * @hw: pointer to hardware structure
- * @stats: pointer to statistics structure
- * @tc_count: Number of elements in bwg_array.
- *
- * This function returns the status data for each of the Traffic Classes in use.
- */
-s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *hw,
- struct ixgbe_hw_stats *stats,
- u8 tc_count)
-{
- int tc;
-
- if (tc_count > MAX_TRAFFIC_CLASS)
- return DCB_ERR_PARAM;
-
- /* Statistics pertaining to each traffic class */
- for (tc = 0; tc < tc_count; tc++) {
- /* Transmitted Packets */
- stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
- /* Transmitted Bytes */
- stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
- /* Received Packets */
- stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
- /* Received Bytes */
- stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
- }
-
- return 0;
-}
-
-/**
- * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data
- * @hw: pointer to hardware structure
- * @stats: pointer to statistics structure
- * @tc_count: Number of elements in bwg_array.
- *
- * This function returns the CBFC status data for each of the Traffic Classes.
- */
-s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw,
- struct ixgbe_hw_stats *stats,
- u8 tc_count)
-{
- int tc;
-
- if (tc_count > MAX_TRAFFIC_CLASS)
- return DCB_ERR_PARAM;
-
- for (tc = 0; tc < tc_count; tc++) {
- /* Priority XOFF Transmitted */
- stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
- /* Priority XOFF Received */
- stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc));
- }
-
- return 0;
-}
-
-/**
* ixgbe_dcb_config_packet_buffers_82598 - Configure packet buffers
* @hw: pointer to hardware structure
* @dcb_config: pointer to ixgbe_dcb_config structure
@@ -137,7 +78,7 @@ static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw,
*
* Configure Rx Data Arbiter and credits for each traffic class.
*/
-s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
+static s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
struct tc_bw_alloc *p;
@@ -194,7 +135,7 @@ s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
*
* Configure Tx Descriptor Arbiter and credits for each traffic class.
*/
-s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
+static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
struct tc_bw_alloc *p;
@@ -242,7 +183,7 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
*
* Configure Tx Data Arbiter and credits for each traffic class.
*/
-s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
+static s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
struct tc_bw_alloc *p;
@@ -355,7 +296,7 @@ out:
* 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_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h
index cc728fa092e2..abc03ccfa088 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.h
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h
@@ -72,21 +72,6 @@
/* DCB PFC functions */
s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *);
-s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *, struct ixgbe_hw_stats *,
- u8);
-
-/* DCB traffic class stats */
-s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *);
-s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *, struct ixgbe_hw_stats *,
- u8);
-
-/* DCB config arbiters */
-s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *,
- struct ixgbe_dcb_config *);
-s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *,
- struct ixgbe_dcb_config *);
-s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *,
- struct ixgbe_dcb_config *);
/* DCB hw initialization */
s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *);
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
index 25b02fb425ac..67c219f86c3a 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -31,70 +31,13 @@
#include "ixgbe_dcb_82599.h"
/**
- * ixgbe_dcb_get_tc_stats_82599 - Returns status for each traffic class
- * @hw: pointer to hardware structure
- * @stats: pointer to statistics structure
- * @tc_count: Number of elements in bwg_array.
- *
- * This function returns the status data for each of the Traffic Classes in use.
- */
-s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
- struct ixgbe_hw_stats *stats,
- u8 tc_count)
-{
- int tc;
-
- if (tc_count > MAX_TRAFFIC_CLASS)
- return DCB_ERR_PARAM;
- /* Statistics pertaining to each traffic class */
- for (tc = 0; tc < tc_count; tc++) {
- /* Transmitted Packets */
- stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
- /* Transmitted Bytes */
- stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
- /* Received Packets */
- stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
- /* Received Bytes */
- stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
- }
-
- return 0;
-}
-
-/**
- * ixgbe_dcb_get_pfc_stats_82599 - Return CBFC status data
- * @hw: pointer to hardware structure
- * @stats: pointer to statistics structure
- * @tc_count: Number of elements in bwg_array.
- *
- * This function returns the CBFC status data for each of the Traffic Classes.
- */
-s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
- struct ixgbe_hw_stats *stats,
- u8 tc_count)
-{
- int tc;
-
- if (tc_count > MAX_TRAFFIC_CLASS)
- return DCB_ERR_PARAM;
- for (tc = 0; tc < tc_count; tc++) {
- /* Priority XOFF Transmitted */
- stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
- /* Priority XOFF Received */
- stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(tc));
- }
-
- return 0;
-}
-
-/**
* ixgbe_dcb_config_packet_buffers_82599 - Configure DCB packet buffers
* @hw: pointer to hardware structure
* @dcb_config: pointer to ixgbe_dcb_config structure
*
* Configure packet buffers for DCB mode.
*/
-s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw,
+static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
s32 ret_val = 0;
@@ -136,7 +79,7 @@ s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw,
*
* Configure Rx Packet Arbiter and credits for each traffic class.
*/
-s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
+static s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
struct tc_bw_alloc *p;
@@ -191,7 +134,7 @@ s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
*
* Configure Tx Descriptor Arbiter and credits for each traffic class.
*/
-s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
+static s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
struct tc_bw_alloc *p;
@@ -238,7 +181,7 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
*
* Configure Tx Packet Arbiter and credits for each traffic class.
*/
-s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
+static s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
struct tc_bw_alloc *p;
@@ -359,7 +302,7 @@ out:
* 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_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw)
{
u32 reg = 0;
u8 i = 0;
@@ -412,7 +355,7 @@ s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw)
*
* Configure general DCB parameters.
*/
-s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw)
{
u32 reg;
u32 q;
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h
index 0f3f791e1e1d..18d7fbf6c292 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.h
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h
@@ -101,24 +101,6 @@
/* DCB PFC functions */
s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config);
-s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
- struct ixgbe_hw_stats *stats,
- u8 tc_count);
-
-/* DCB traffic class stats */
-s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw);
-s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
- struct ixgbe_hw_stats *stats,
- u8 tc_count);
-
-/* DCB config arbiters */
-s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
- struct ixgbe_dcb_config *dcb_config);
-s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
- struct ixgbe_dcb_config *dcb_config);
-s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
- struct ixgbe_dcb_config *dcb_config);
-
/* DCB hw initialization */
s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw,
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index dcebc82c6f4d..3dc731c22ff2 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -401,7 +401,7 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
static u32 ixgbe_get_rx_csum(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- return (adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED);
+ return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED;
}
static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
@@ -820,16 +820,19 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
char firmware_version[32];
- strncpy(drvinfo->driver, ixgbe_driver_name, 32);
- strncpy(drvinfo->version, ixgbe_driver_version, 32);
+ strncpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver));
+ strncpy(drvinfo->version, ixgbe_driver_version,
+ sizeof(drvinfo->version));
- sprintf(firmware_version, "%d.%d-%d",
- (adapter->eeprom_version & 0xF000) >> 12,
- (adapter->eeprom_version & 0x0FF0) >> 4,
- adapter->eeprom_version & 0x000F);
+ snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d",
+ (adapter->eeprom_version & 0xF000) >> 12,
+ (adapter->eeprom_version & 0x0FF0) >> 4,
+ adapter->eeprom_version & 0x000F);
- strncpy(drvinfo->fw_version, firmware_version, 32);
- strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+ strncpy(drvinfo->fw_version, firmware_version,
+ sizeof(drvinfo->fw_version));
+ strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
+ sizeof(drvinfo->bus_info));
drvinfo->n_stats = IXGBE_STATS_LEN;
drvinfo->testinfo_len = IXGBE_TEST_LEN;
drvinfo->regdump_len = ixgbe_get_regs_len(netdev);
@@ -985,8 +988,8 @@ static int ixgbe_get_sset_count(struct net_device *netdev, int sset)
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);
+ return ETHTOOL_MAX_NTUPLE_LIST_ENTRY *
+ ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY;
default:
return -EOPNOTSUPP;
}
@@ -996,12 +999,11 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u64 *queue_stat;
- int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
struct rtnl_link_stats64 temp;
const struct rtnl_link_stats64 *net_stats;
- int j, k;
- int i;
+ unsigned int start;
+ struct ixgbe_ring *ring;
+ int i, j;
char *p = NULL;
ixgbe_update_stats(adapter);
@@ -1022,16 +1024,22 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
for (j = 0; j < adapter->num_tx_queues; j++) {
- queue_stat = (u64 *)&adapter->tx_ring[j]->stats;
- for (k = 0; k < stat_count; k++)
- data[i + k] = queue_stat[k];
- i += k;
+ ring = adapter->tx_ring[j];
+ do {
+ start = u64_stats_fetch_begin_bh(&ring->syncp);
+ data[i] = ring->stats.packets;
+ data[i+1] = ring->stats.bytes;
+ } while (u64_stats_fetch_retry_bh(&ring->syncp, start));
+ i += 2;
}
for (j = 0; j < adapter->num_rx_queues; j++) {
- queue_stat = (u64 *)&adapter->rx_ring[j]->stats;
- for (k = 0; k < stat_count; k++)
- data[i + k] = queue_stat[k];
- i += k;
+ ring = adapter->rx_ring[j];
+ do {
+ start = u64_stats_fetch_begin_bh(&ring->syncp);
+ data[i] = ring->stats.packets;
+ data[i+1] = ring->stats.bytes;
+ } while (u64_stats_fetch_retry_bh(&ring->syncp, start));
+ i += 2;
}
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
for (j = 0; j < MAX_TX_PACKET_BUFFERS; j++) {
@@ -1435,9 +1443,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
struct ixgbe_hw *hw = &adapter->hw;
- struct pci_dev *pdev = adapter->pdev;
u32 reg_ctl;
- int i;
/* shut down the DMA engines now so they can be reinitialized later */
@@ -1445,14 +1451,15 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
reg_ctl &= ~IXGBE_RXCTRL_RXEN;
IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl);
- reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(0));
+ reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx));
reg_ctl &= ~IXGBE_RXDCTL_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(0), reg_ctl);
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx), reg_ctl);
/* now Tx */
- reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(0));
+ reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx));
reg_ctl &= ~IXGBE_TXDCTL_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(0), reg_ctl);
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx), reg_ctl);
+
if (hw->mac.type == ixgbe_mac_82599EB) {
reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
reg_ctl &= ~IXGBE_DMATXCTL_TE;
@@ -1461,221 +1468,57 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
ixgbe_reset(adapter);
- if (tx_ring->desc && tx_ring->tx_buffer_info) {
- for (i = 0; i < tx_ring->count; i++) {
- struct ixgbe_tx_buffer *buf =
- &(tx_ring->tx_buffer_info[i]);
- if (buf->dma)
- dma_unmap_single(&pdev->dev, buf->dma,
- buf->length, DMA_TO_DEVICE);
- if (buf->skb)
- dev_kfree_skb(buf->skb);
- }
- }
-
- if (rx_ring->desc && rx_ring->rx_buffer_info) {
- for (i = 0; i < rx_ring->count; i++) {
- struct ixgbe_rx_buffer *buf =
- &(rx_ring->rx_buffer_info[i]);
- if (buf->dma)
- dma_unmap_single(&pdev->dev, buf->dma,
- IXGBE_RXBUFFER_2048,
- DMA_FROM_DEVICE);
- if (buf->skb)
- dev_kfree_skb(buf->skb);
- }
- }
-
- if (tx_ring->desc) {
- dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
- tx_ring->dma);
- tx_ring->desc = NULL;
- }
- if (rx_ring->desc) {
- dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
- rx_ring->dma);
- rx_ring->desc = NULL;
- }
-
- kfree(tx_ring->tx_buffer_info);
- tx_ring->tx_buffer_info = NULL;
- kfree(rx_ring->rx_buffer_info);
- rx_ring->rx_buffer_info = NULL;
+ ixgbe_free_tx_resources(adapter, &adapter->test_tx_ring);
+ ixgbe_free_rx_resources(adapter, &adapter->test_rx_ring);
}
static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
{
struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
- struct pci_dev *pdev = adapter->pdev;
u32 rctl, reg_data;
- int i, ret_val;
+ int ret_val;
+ int err;
/* Setup Tx descriptor ring and Tx buffers */
+ tx_ring->count = IXGBE_DEFAULT_TXD;
+ tx_ring->queue_index = 0;
+ tx_ring->reg_idx = adapter->tx_ring[0]->reg_idx;
+ tx_ring->numa_node = adapter->node;
- if (!tx_ring->count)
- tx_ring->count = IXGBE_DEFAULT_TXD;
-
- tx_ring->tx_buffer_info = kcalloc(tx_ring->count,
- sizeof(struct ixgbe_tx_buffer),
- GFP_KERNEL);
- if (!(tx_ring->tx_buffer_info)) {
- ret_val = 1;
- goto err_nomem;
- }
-
- tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
- tx_ring->size = ALIGN(tx_ring->size, 4096);
- tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size,
- &tx_ring->dma, GFP_KERNEL);
- if (!(tx_ring->desc)) {
- ret_val = 2;
- goto err_nomem;
- }
- tx_ring->next_to_use = tx_ring->next_to_clean = 0;
-
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAL(0),
- ((u64) tx_ring->dma & 0x00000000FFFFFFFF));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAH(0),
- ((u64) tx_ring->dma >> 32));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDLEN(0),
- tx_ring->count * sizeof(union ixgbe_adv_tx_desc));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDH(0), 0);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), 0);
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
- reg_data |= IXGBE_HLREG0_TXPADEN;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+ err = ixgbe_setup_tx_resources(adapter, tx_ring);
+ if (err)
+ return 1;
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL);
reg_data |= IXGBE_DMATXCTL_TE;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data);
}
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(0));
- reg_data |= IXGBE_TXDCTL_ENABLE;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(0), reg_data);
-
- for (i = 0; i < tx_ring->count; i++) {
- union ixgbe_adv_tx_desc *desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
- struct sk_buff *skb;
- unsigned int size = 1024;
-
- skb = alloc_skb(size, GFP_KERNEL);
- if (!skb) {
- ret_val = 3;
- goto err_nomem;
- }
- skb_put(skb, size);
- tx_ring->tx_buffer_info[i].skb = skb;
- tx_ring->tx_buffer_info[i].length = skb->len;
- tx_ring->tx_buffer_info[i].dma =
- dma_map_single(&pdev->dev, skb->data, skb->len,
- DMA_TO_DEVICE);
- desc->read.buffer_addr =
- cpu_to_le64(tx_ring->tx_buffer_info[i].dma);
- desc->read.cmd_type_len = cpu_to_le32(skb->len);
- desc->read.cmd_type_len |= cpu_to_le32(IXGBE_TXD_CMD_EOP |
- IXGBE_TXD_CMD_IFCS |
- IXGBE_TXD_CMD_RS);
- desc->read.olinfo_status = 0;
- if (adapter->hw.mac.type == ixgbe_mac_82599EB)
- desc->read.olinfo_status |=
- (skb->len << IXGBE_ADVTXD_PAYLEN_SHIFT);
- }
+ ixgbe_configure_tx_ring(adapter, tx_ring);
/* Setup Rx Descriptor ring and Rx buffers */
-
- if (!rx_ring->count)
- rx_ring->count = IXGBE_DEFAULT_RXD;
-
- rx_ring->rx_buffer_info = kcalloc(rx_ring->count,
- sizeof(struct ixgbe_rx_buffer),
- GFP_KERNEL);
- if (!(rx_ring->rx_buffer_info)) {
+ rx_ring->count = IXGBE_DEFAULT_RXD;
+ rx_ring->queue_index = 0;
+ rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx;
+ rx_ring->rx_buf_len = IXGBE_RXBUFFER_2048;
+ rx_ring->numa_node = adapter->node;
+
+ err = ixgbe_setup_rx_resources(adapter, rx_ring);
+ if (err) {
ret_val = 4;
goto err_nomem;
}
- rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
- rx_ring->size = ALIGN(rx_ring->size, 4096);
- rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,
- &rx_ring->dma, GFP_KERNEL);
- if (!(rx_ring->desc)) {
- ret_val = 5;
- goto err_nomem;
- }
- rx_ring->next_to_use = rx_ring->next_to_clean = 0;
-
rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl & ~IXGBE_RXCTRL_RXEN);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAL(0),
- ((u64)rx_ring->dma & 0xFFFFFFFF));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAH(0),
- ((u64) rx_ring->dma >> 32));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDLEN(0), rx_ring->size);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDH(0), 0);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), 0);
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
- reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data);
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
- reg_data &= ~IXGBE_HLREG0_LPBK;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RDRXCTL);
-#define IXGBE_RDRXCTL_RDMTS_MASK 0x00000003 /* Receive Descriptor Minimum
- Threshold Size mask */
- reg_data &= ~IXGBE_RDRXCTL_RDMTS_MASK;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDRXCTL, reg_data);
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_MCSTCTRL);
-#define IXGBE_MCSTCTRL_MO_MASK 0x00000003 /* Multicast Offset mask */
- reg_data &= ~IXGBE_MCSTCTRL_MO_MASK;
- reg_data |= adapter->hw.mac.mc_filter_type;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_MCSTCTRL, reg_data);
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(0));
- reg_data |= IXGBE_RXDCTL_ENABLE;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(0), reg_data);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- int j = adapter->rx_ring[0]->reg_idx;
- u32 k;
- for (k = 0; k < 10; k++) {
- if (IXGBE_READ_REG(&adapter->hw,
- IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE)
- break;
- else
- msleep(1);
- }
- }
+ ixgbe_configure_rx_ring(adapter, rx_ring);
rctl |= IXGBE_RXCTRL_RXEN | IXGBE_RXCTRL_DMBYPS;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl);
- for (i = 0; i < rx_ring->count; i++) {
- union ixgbe_adv_rx_desc *rx_desc =
- IXGBE_RX_DESC_ADV(*rx_ring, i);
- struct sk_buff *skb;
-
- skb = alloc_skb(IXGBE_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL);
- if (!skb) {
- ret_val = 6;
- goto err_nomem;
- }
- skb_reserve(skb, NET_IP_ALIGN);
- rx_ring->rx_buffer_info[i].skb = skb;
- rx_ring->rx_buffer_info[i].dma =
- dma_map_single(&pdev->dev, skb->data,
- IXGBE_RXBUFFER_2048, DMA_FROM_DEVICE);
- rx_desc->read.pkt_addr =
- cpu_to_le64(rx_ring->rx_buffer_info[i].dma);
- memset(skb->data, 0x00, skb->len);
- }
-
return 0;
err_nomem:
@@ -1689,16 +1532,21 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter)
u32 reg_data;
/* right now we only support MAC loopback in the driver */
-
- /* Setup MAC loopback */
reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
+ /* Setup MAC loopback */
reg_data |= IXGBE_HLREG0_LPBK;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
+ reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data);
+
reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_AUTOC);
reg_data &= ~IXGBE_AUTOC_LMS_MASK;
reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data);
+ IXGBE_WRITE_FLUSH(&adapter->hw);
+ msleep(10);
/* Disable Atlas Tx lanes; re-enabled in reset path */
if (hw->mac.type == ixgbe_mac_82598EB) {
@@ -1756,15 +1604,81 @@ static int ixgbe_check_lbtest_frame(struct sk_buff *skb,
return 13;
}
+static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *rx_ring,
+ struct ixgbe_ring *tx_ring,
+ unsigned int size)
+{
+ union ixgbe_adv_rx_desc *rx_desc;
+ struct ixgbe_rx_buffer *rx_buffer_info;
+ struct ixgbe_tx_buffer *tx_buffer_info;
+ const int bufsz = rx_ring->rx_buf_len;
+ u32 staterr;
+ u16 rx_ntc, tx_ntc, count = 0;
+
+ /* initialize next to clean and descriptor values */
+ rx_ntc = rx_ring->next_to_clean;
+ tx_ntc = tx_ring->next_to_clean;
+ rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc);
+ staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+
+ while (staterr & IXGBE_RXD_STAT_DD) {
+ /* check Rx buffer */
+ rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc];
+
+ /* unmap Rx buffer, will be remapped by alloc_rx_buffers */
+ dma_unmap_single(&adapter->pdev->dev,
+ rx_buffer_info->dma,
+ bufsz,
+ DMA_FROM_DEVICE);
+ rx_buffer_info->dma = 0;
+
+ /* verify contents of skb */
+ if (!ixgbe_check_lbtest_frame(rx_buffer_info->skb, size))
+ count++;
+
+ /* unmap buffer on Tx side */
+ tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc];
+ ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info);
+
+ /* increment Rx/Tx next to clean counters */
+ rx_ntc++;
+ if (rx_ntc == rx_ring->count)
+ rx_ntc = 0;
+ tx_ntc++;
+ if (tx_ntc == tx_ring->count)
+ tx_ntc = 0;
+
+ /* fetch next descriptor */
+ rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc);
+ staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+ }
+
+ /* re-map buffers to ring, store next to clean values */
+ ixgbe_alloc_rx_buffers(adapter, rx_ring, count);
+ rx_ring->next_to_clean = rx_ntc;
+ tx_ring->next_to_clean = tx_ntc;
+
+ return count;
+}
+
static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter)
{
struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
- struct pci_dev *pdev = adapter->pdev;
- int i, j, k, l, lc, good_cnt, ret_val = 0;
- unsigned long time;
+ int i, j, lc, good_cnt, ret_val = 0;
+ unsigned int size = 1024;
+ netdev_tx_t tx_ret_val;
+ struct sk_buff *skb;
+
+ /* allocate test skb */
+ skb = alloc_skb(size, GFP_KERNEL);
+ if (!skb)
+ return 11;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), rx_ring->count - 1);
+ /* place data into test skb */
+ ixgbe_create_lbtest_frame(skb, size);
+ skb_put(skb, size);
/*
* Calculate the loop count based on the largest descriptor ring
@@ -1777,54 +1691,40 @@ static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter)
else
lc = ((rx_ring->count / 64) * 2) + 1;
- k = l = 0;
for (j = 0; j <= lc; j++) {
- for (i = 0; i < 64; i++) {
- ixgbe_create_lbtest_frame(
- tx_ring->tx_buffer_info[k].skb,
- 1024);
- dma_sync_single_for_device(&pdev->dev,
- tx_ring->tx_buffer_info[k].dma,
- tx_ring->tx_buffer_info[k].length,
- DMA_TO_DEVICE);
- if (unlikely(++k == tx_ring->count))
- k = 0;
- }
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), k);
- msleep(200);
- /* set the start time for the receive */
- time = jiffies;
+ /* reset count of good packets */
good_cnt = 0;
- do {
- /* receive the sent packets */
- dma_sync_single_for_cpu(&pdev->dev,
- rx_ring->rx_buffer_info[l].dma,
- IXGBE_RXBUFFER_2048,
- DMA_FROM_DEVICE);
- ret_val = ixgbe_check_lbtest_frame(
- rx_ring->rx_buffer_info[l].skb, 1024);
- if (!ret_val)
+
+ /* place 64 packets on the transmit queue*/
+ for (i = 0; i < 64; i++) {
+ skb_get(skb);
+ tx_ret_val = ixgbe_xmit_frame_ring(skb,
+ adapter->netdev,
+ adapter,
+ tx_ring);
+ if (tx_ret_val == NETDEV_TX_OK)
good_cnt++;
- if (++l == rx_ring->count)
- l = 0;
- /*
- * time + 20 msecs (200 msecs on 2.4) is more than
- * enough time to complete the receives, if it's
- * exceeded, break and error off
- */
- } while (good_cnt < 64 && jiffies < (time + 20));
+ }
+
if (good_cnt != 64) {
- /* ret_val is the same as mis-compare */
- ret_val = 13;
+ ret_val = 12;
break;
}
- if (jiffies >= (time + 20)) {
- /* Error code for time out error */
- ret_val = 14;
+
+ /* allow 200 milliseconds for packets to go from Tx to Rx */
+ msleep(200);
+
+ good_cnt = ixgbe_clean_test_rings(adapter, rx_ring,
+ tx_ring, size);
+ if (good_cnt != 64) {
+ ret_val = 13;
break;
}
}
+ /* free the original skb */
+ kfree_skb(skb);
+
return ret_val;
}
@@ -2218,7 +2118,17 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
bool need_reset = false;
int rc;
- rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE);
+#ifdef CONFIG_IXGBE_DCB
+ if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
+ !(data & ETH_FLAG_RXVLAN))
+ return -EINVAL;
+#endif
+
+ need_reset = (data & ETH_FLAG_RXVLAN) !=
+ (netdev->features & NETIF_F_HW_VLAN_RX);
+
+ rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO |
+ ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
if (rc)
return rc;
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index 072327c5e41a..05efa6a8ce8e 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -304,12 +304,13 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
if (!ixgbe_rx_is_fcoe(rx_desc))
goto ddp_out;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
sterr = le32_to_cpu(rx_desc->wb.upper.status_error);
fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR);
fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE);
if (fcerr == IXGBE_FCERR_BADCRC)
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
if (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q))
fh = (struct fc_frame_header *)(skb->data +
@@ -471,7 +472,7 @@ int ixgbe_fso(struct ixgbe_adapter *adapter,
/* write context desc */
i = tx_ring->next_to_use;
- context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i);
+ context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i);
context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
context_desc->seqnum_seed = cpu_to_le32(fcoe_sof_eof);
context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd);
@@ -603,11 +604,13 @@ int ixgbe_fcoe_enable(struct net_device *netdev)
{
int rc = -EINVAL;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_fcoe *fcoe = &adapter->fcoe;
if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE))
goto out_enable;
+ atomic_inc(&fcoe->refcnt);
if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
goto out_enable;
@@ -647,6 +650,7 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
{
int rc = -EINVAL;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_fcoe *fcoe = &adapter->fcoe;
if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE))
goto out_disable;
@@ -654,6 +658,9 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
goto out_disable;
+ if (!atomic_dec_and_test(&fcoe->refcnt))
+ goto out_disable;
+
e_info(drv, "Disabling FCoE offload features.\n");
netdev->features &= ~NETIF_F_FCOE_CRC;
netdev->features &= ~NETIF_F_FSO;
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h
index abf4b2b3f252..4bc2c551c8db 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.h
+++ b/drivers/net/ixgbe/ixgbe_fcoe.h
@@ -66,6 +66,7 @@ struct ixgbe_fcoe {
u8 tc;
u8 up;
#endif
+ atomic_t refcnt;
spinlock_t lock;
struct pci_pool *pool;
struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX];
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index e32af434cc9d..f85631263af8 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -50,7 +50,7 @@
char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
- "Intel(R) 10 Gigabit PCI Express Network Driver";
+ "Intel(R) 10 Gigabit PCI Express Network Driver";
#define DRV_VERSION "2.0.84-k2"
const char ixgbe_driver_version[] = DRV_VERSION;
@@ -120,7 +120,7 @@ MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
#ifdef CONFIG_IXGBE_DCA
static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
- void *p);
+ void *p);
static struct notifier_block dca_notifier = {
.notifier_call = ixgbe_notify_dca,
.next = NULL,
@@ -131,8 +131,8 @@ static struct notifier_block dca_notifier = {
#ifdef CONFIG_PCI_IOV
static unsigned int max_vfs;
module_param(max_vfs, uint, 0);
-MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate "
- "per physical function");
+MODULE_PARM_DESC(max_vfs,
+ "Maximum number of virtual functions to allocate per physical function");
#endif /* CONFIG_PCI_IOV */
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
@@ -169,8 +169,8 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
/* take a breather then clean up driver data */
msleep(100);
- if (adapter->vfinfo)
- kfree(adapter->vfinfo);
+
+ kfree(adapter->vfinfo);
adapter->vfinfo = NULL;
adapter->num_vfs = 0;
@@ -282,17 +282,17 @@ static void ixgbe_regdump(struct ixgbe_hw *hw, struct ixgbe_reg_info *reginfo)
regs[i] = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
break;
default:
- printk(KERN_INFO "%-15s %08x\n", reginfo->name,
+ pr_info("%-15s %08x\n", reginfo->name,
IXGBE_READ_REG(hw, reginfo->ofs));
return;
}
for (i = 0; i < 8; i++) {
snprintf(rname, 16, "%s[%d-%d]", reginfo->name, i*8, i*8+7);
- printk(KERN_ERR "%-15s ", rname);
+ pr_err("%-15s", rname);
for (j = 0; j < 8; j++)
- printk(KERN_CONT "%08x ", regs[i*8+j]);
- printk(KERN_CONT "\n");
+ pr_cont(" %08x", regs[i*8+j]);
+ pr_cont("\n");
}
}
@@ -322,18 +322,18 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
/* Print netdevice Info */
if (netdev) {
dev_info(&adapter->pdev->dev, "Net device Info\n");
- printk(KERN_INFO "Device Name state "
+ pr_info("Device Name state "
"trans_start last_rx\n");
- printk(KERN_INFO "%-15s %016lX %016lX %016lX\n",
- netdev->name,
- netdev->state,
- netdev->trans_start,
- netdev->last_rx);
+ pr_info("%-15s %016lX %016lX %016lX\n",
+ netdev->name,
+ netdev->state,
+ netdev->trans_start,
+ netdev->last_rx);
}
/* Print Registers */
dev_info(&adapter->pdev->dev, "Register Dump\n");
- printk(KERN_INFO " Register Name Value\n");
+ pr_info(" Register Name Value\n");
for (reginfo = (struct ixgbe_reg_info *)ixgbe_reg_info_tbl;
reginfo->name; reginfo++) {
ixgbe_regdump(hw, reginfo);
@@ -344,13 +344,12 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
goto exit;
dev_info(&adapter->pdev->dev, "TX Rings Summary\n");
- printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ] "
- "leng ntw timestamp\n");
+ pr_info("Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n");
for (n = 0; n < adapter->num_tx_queues; n++) {
tx_ring = adapter->tx_ring[n];
tx_buffer_info =
&tx_ring->tx_buffer_info[tx_ring->next_to_clean];
- printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n",
+ pr_info(" %5d %5X %5X %016llX %04X %3X %016llX\n",
n, tx_ring->next_to_use, tx_ring->next_to_clean,
(u64)tx_buffer_info->dma,
tx_buffer_info->length,
@@ -377,18 +376,18 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
for (n = 0; n < adapter->num_tx_queues; n++) {
tx_ring = adapter->tx_ring[n];
- printk(KERN_INFO "------------------------------------\n");
- printk(KERN_INFO "TX QUEUE INDEX = %d\n", tx_ring->queue_index);
- printk(KERN_INFO "------------------------------------\n");
- printk(KERN_INFO "T [desc] [address 63:0 ] "
+ pr_info("------------------------------------\n");
+ pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index);
+ pr_info("------------------------------------\n");
+ pr_info("T [desc] [address 63:0 ] "
"[PlPOIdStDDt Ln] [bi->dma ] "
"leng ntw timestamp bi->skb\n");
for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
- tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
+ tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
tx_buffer_info = &tx_ring->tx_buffer_info[i];
u0 = (struct my_u0 *)tx_desc;
- printk(KERN_INFO "T [0x%03X] %016llX %016llX %016llX"
+ pr_info("T [0x%03X] %016llX %016llX %016llX"
" %04X %3X %016llX %p", i,
le64_to_cpu(u0->a),
le64_to_cpu(u0->b),
@@ -399,13 +398,13 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
tx_buffer_info->skb);
if (i == tx_ring->next_to_use &&
i == tx_ring->next_to_clean)
- printk(KERN_CONT " NTC/U\n");
+ pr_cont(" NTC/U\n");
else if (i == tx_ring->next_to_use)
- printk(KERN_CONT " NTU\n");
+ pr_cont(" NTU\n");
else if (i == tx_ring->next_to_clean)
- printk(KERN_CONT " NTC\n");
+ pr_cont(" NTC\n");
else
- printk(KERN_CONT "\n");
+ pr_cont("\n");
if (netif_msg_pktdata(adapter) &&
tx_buffer_info->dma != 0)
@@ -419,11 +418,11 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
/* Print RX Rings Summary */
rx_ring_summary:
dev_info(&adapter->pdev->dev, "RX Rings Summary\n");
- printk(KERN_INFO "Queue [NTU] [NTC]\n");
+ pr_info("Queue [NTU] [NTC]\n");
for (n = 0; n < adapter->num_rx_queues; n++) {
rx_ring = adapter->rx_ring[n];
- printk(KERN_INFO "%5d %5X %5X\n", n,
- rx_ring->next_to_use, rx_ring->next_to_clean);
+ pr_info("%5d %5X %5X\n",
+ n, rx_ring->next_to_use, rx_ring->next_to_clean);
}
/* Print RX Rings */
@@ -454,30 +453,30 @@ rx_ring_summary:
*/
for (n = 0; n < adapter->num_rx_queues; n++) {
rx_ring = adapter->rx_ring[n];
- printk(KERN_INFO "------------------------------------\n");
- printk(KERN_INFO "RX QUEUE INDEX = %d\n", rx_ring->queue_index);
- printk(KERN_INFO "------------------------------------\n");
- printk(KERN_INFO "R [desc] [ PktBuf A0] "
+ pr_info("------------------------------------\n");
+ pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index);
+ pr_info("------------------------------------\n");
+ pr_info("R [desc] [ PktBuf A0] "
"[ HeadBuf DD] [bi->dma ] [bi->skb] "
"<-- Adv Rx Read format\n");
- printk(KERN_INFO "RWB[desc] [PcsmIpSHl PtRs] "
+ pr_info("RWB[desc] [PcsmIpSHl PtRs] "
"[vl er S cks ln] ---------------- [bi->skb] "
"<-- Adv Rx Write-Back format\n");
for (i = 0; i < rx_ring->count; i++) {
rx_buffer_info = &rx_ring->rx_buffer_info[i];
- rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
+ rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
u0 = (struct my_u0 *)rx_desc;
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
if (staterr & IXGBE_RXD_STAT_DD) {
/* Descriptor Done */
- printk(KERN_INFO "RWB[0x%03X] %016llX "
+ pr_info("RWB[0x%03X] %016llX "
"%016llX ---------------- %p", i,
le64_to_cpu(u0->a),
le64_to_cpu(u0->b),
rx_buffer_info->skb);
} else {
- printk(KERN_INFO "R [0x%03X] %016llX "
+ pr_info("R [0x%03X] %016llX "
"%016llX %016llX %p", i,
le64_to_cpu(u0->a),
le64_to_cpu(u0->b),
@@ -503,11 +502,11 @@ rx_ring_summary:
}
if (i == rx_ring->next_to_use)
- printk(KERN_CONT " NTU\n");
+ pr_cont(" NTU\n");
else if (i == rx_ring->next_to_clean)
- printk(KERN_CONT " NTC\n");
+ pr_cont(" NTC\n");
else
- printk(KERN_CONT "\n");
+ pr_cont("\n");
}
}
@@ -523,7 +522,7 @@ static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
/* Let firmware take over control of h/w */
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
- ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
+ ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
}
static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
@@ -533,7 +532,7 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
/* Let firmware know the driver has taken over */
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
- ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
+ ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
}
/*
@@ -545,7 +544,7 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
*
*/
static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
- u8 queue, u8 msix_vector)
+ u8 queue, u8 msix_vector)
{
u32 ivar, index;
struct ixgbe_hw *hw = &adapter->hw;
@@ -586,7 +585,7 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
}
static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
- u64 qmask)
+ u64 qmask)
{
u32 mask;
@@ -601,9 +600,9 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
}
}
-static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
- struct ixgbe_tx_buffer
- *tx_buffer_info)
+void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
+ struct ixgbe_tx_buffer
+ *tx_buffer_info)
{
if (tx_buffer_info->dma) {
if (tx_buffer_info->mapped_as_page)
@@ -637,7 +636,7 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
* Returns : true if in xon state (currently not paused)
*/
static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
u32 txoff = IXGBE_TFCS_TXOFF;
@@ -682,8 +681,8 @@ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter,
}
static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- unsigned int eop)
+ struct ixgbe_ring *tx_ring,
+ unsigned int eop)
{
struct ixgbe_hw *hw = &adapter->hw;
@@ -695,7 +694,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
ixgbe_tx_xon_state(adapter, tx_ring)) {
/* detected Tx unit hang */
union ixgbe_adv_tx_desc *tx_desc;
- tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+ tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
e_err(drv, "Detected Tx Unit Hang\n"
" Tx Queue <%d>\n"
" TDH, TDT <%x>, <%x>\n"
@@ -732,7 +731,7 @@ static void ixgbe_tx_timeout(struct net_device *netdev);
* @tx_ring: tx ring to clean
**/
static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
struct net_device *netdev = adapter->netdev;
@@ -743,7 +742,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
i = tx_ring->next_to_clean;
eop = tx_ring->tx_buffer_info[i].next_to_watch;
- eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+ eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
(count < tx_ring->work_limit)) {
@@ -751,7 +750,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
rmb(); /* read buffer_info after eop_desc */
for ( ; !cleaned; count++) {
struct sk_buff *skb;
- tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
+ tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
tx_buffer_info = &tx_ring->tx_buffer_info[i];
cleaned = (i == eop);
skb = tx_buffer_info->skb;
@@ -781,7 +780,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
}
ixgbe_unmap_and_free_tx_resource(adapter,
- tx_buffer_info);
+ tx_buffer_info);
tx_desc->wb.status = 0;
@@ -791,14 +790,14 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
}
eop = tx_ring->tx_buffer_info[i].next_to_watch;
- eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+ eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
}
tx_ring->next_to_clean = i;
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
if (unlikely(count && netif_carrier_ok(netdev) &&
- (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) {
+ (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) {
/* Make sure that anybody stopping the queue after this
* sees the new next_to_clean.
*/
@@ -825,14 +824,16 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
tx_ring->total_bytes += total_bytes;
tx_ring->total_packets += total_packets;
+ u64_stats_update_begin(&tx_ring->syncp);
tx_ring->stats.packets += total_packets;
tx_ring->stats.bytes += total_bytes;
- return (count < tx_ring->work_limit);
+ u64_stats_update_end(&tx_ring->syncp);
+ return count < tx_ring->work_limit;
}
#ifdef CONFIG_IXGBE_DCA
static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
u32 rxctrl;
int cpu = get_cpu();
@@ -846,13 +847,13 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599;
rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
- IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
+ IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
}
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_DCA_RXCTRL_DESC_HSRO_EN);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
rx_ring->cpu = cpu;
}
@@ -860,7 +861,7 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
}
static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
u32 txctrl;
int cpu = get_cpu();
@@ -878,7 +879,7 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q));
txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
- IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+ IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl);
}
@@ -946,27 +947,22 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
* @rx_desc: rx descriptor
**/
static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
- struct sk_buff *skb, u8 status,
- struct ixgbe_ring *ring,
- union ixgbe_adv_rx_desc *rx_desc)
+ struct sk_buff *skb, u8 status,
+ struct ixgbe_ring *ring,
+ union ixgbe_adv_rx_desc *rx_desc)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
struct napi_struct *napi = &q_vector->napi;
bool is_vlan = (status & IXGBE_RXD_STAT_VP);
u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
- skb_record_rx_queue(skb, ring->queue_index);
- if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
- if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
- vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
- else
- napi_gro_receive(napi, skb);
- } else {
- if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
- vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
- else
- netif_rx(skb);
- }
+ if (is_vlan && (tag & VLAN_VID_MASK))
+ __vlan_hwaccel_put_tag(skb, tag);
+
+ if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
+ napi_gro_receive(napi, skb);
+ else
+ netif_rx(skb);
}
/**
@@ -981,7 +977,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
{
u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Rx csum disabled */
if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
@@ -1017,7 +1013,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
}
static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw,
- struct ixgbe_ring *rx_ring, u32 val)
+ struct ixgbe_ring *rx_ring, u32 val)
{
/*
* Force memory writes to complete before letting h/w
@@ -1033,25 +1029,27 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw,
* ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split
* @adapter: address of board private structure
**/
-static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring,
- int cleaned_count)
+void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *rx_ring,
+ int cleaned_count)
{
+ struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc;
struct ixgbe_rx_buffer *bi;
unsigned int i;
+ unsigned int bufsz = rx_ring->rx_buf_len;
i = rx_ring->next_to_use;
bi = &rx_ring->rx_buffer_info[i];
while (cleaned_count--) {
- rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
+ rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
if (!bi->page_dma &&
(rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)) {
if (!bi->page) {
- bi->page = alloc_page(GFP_ATOMIC);
+ bi->page = netdev_alloc_page(netdev);
if (!bi->page) {
adapter->alloc_rx_page_failed++;
goto no_buffers;
@@ -1063,29 +1061,28 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
}
bi->page_dma = dma_map_page(&pdev->dev, bi->page,
- bi->page_offset,
- (PAGE_SIZE / 2),
+ bi->page_offset,
+ (PAGE_SIZE / 2),
DMA_FROM_DEVICE);
}
if (!bi->skb) {
- struct sk_buff *skb;
- /* netdev_alloc_skb reserves 32 bytes up front!! */
- uint bufsz = rx_ring->rx_buf_len + SMP_CACHE_BYTES;
- skb = netdev_alloc_skb(adapter->netdev, bufsz);
+ struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev,
+ bufsz);
+ bi->skb = skb;
if (!skb) {
adapter->alloc_rx_buff_failed++;
goto no_buffers;
}
+ /* initialize queue mapping */
+ skb_record_rx_queue(skb, rx_ring->queue_index);
+ }
- /* advance the data pointer to the next cache line */
- skb_reserve(skb, (PTR_ALIGN(skb->data, SMP_CACHE_BYTES)
- - skb->data));
-
- bi->skb = skb;
- bi->dma = dma_map_single(&pdev->dev, skb->data,
- rx_ring->rx_buf_len,
+ if (!bi->dma) {
+ bi->dma = dma_map_single(&pdev->dev,
+ bi->skb->data,
+ rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
}
/* Refresh the desc even if buffer_addrs didn't change because
@@ -1095,6 +1092,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
} else {
rx_desc->read.pkt_addr = cpu_to_le64(bi->dma);
+ rx_desc->read.hdr_addr = 0;
}
i++;
@@ -1126,8 +1124,8 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc)
{
return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) &
- IXGBE_RXDADV_RSCCNT_MASK) >>
- IXGBE_RXDADV_RSCCNT_SHIFT;
+ IXGBE_RXDADV_RSCCNT_MASK) >>
+ IXGBE_RXDADV_RSCCNT_SHIFT;
}
/**
@@ -1140,7 +1138,7 @@ static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc)
* turns it into the frag list owner.
**/
static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb,
- u64 *count)
+ u64 *count)
{
unsigned int frag_list_size = 0;
@@ -1168,11 +1166,10 @@ struct ixgbe_rsc_cb {
#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb)
static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
- struct ixgbe_ring *rx_ring,
- int *work_done, int work_to_do)
+ struct ixgbe_ring *rx_ring,
+ int *work_done, int work_to_do)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
@@ -1188,7 +1185,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
#endif /* IXGBE_FCOE */
i = rx_ring->next_to_clean;
- rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
+ rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
rx_buffer_info = &rx_ring->rx_buffer_info[i];
@@ -1231,9 +1228,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma;
} else {
dma_unmap_single(&pdev->dev,
- rx_buffer_info->dma,
- rx_ring->rx_buf_len,
- DMA_FROM_DEVICE);
+ rx_buffer_info->dma,
+ rx_ring->rx_buf_len,
+ DMA_FROM_DEVICE);
}
rx_buffer_info->dma = 0;
skb_put(skb, len);
@@ -1244,9 +1241,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
PAGE_SIZE / 2, DMA_FROM_DEVICE);
rx_buffer_info->page_dma = 0;
skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
- rx_buffer_info->page,
- rx_buffer_info->page_offset,
- upper_len);
+ rx_buffer_info->page,
+ rx_buffer_info->page_offset,
+ upper_len);
if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) ||
(page_count(rx_buffer_info->page) != 1))
@@ -1263,7 +1260,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
if (i == rx_ring->count)
i = 0;
- next_rxd = IXGBE_RX_DESC_ADV(*rx_ring, i);
+ next_rxd = IXGBE_RX_DESC_ADV(rx_ring, i);
prefetch(next_rxd);
cleaned_count++;
@@ -1280,24 +1277,28 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
if (staterr & IXGBE_RXD_STAT_EOP) {
if (skb->prev)
- skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count));
+ skb = ixgbe_transform_rsc_queue(skb,
+ &(rx_ring->rsc_count));
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
if (IXGBE_RSC_CB(skb)->delay_unmap) {
dma_unmap_single(&pdev->dev,
IXGBE_RSC_CB(skb)->dma,
- rx_ring->rx_buf_len,
+ rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
IXGBE_RSC_CB(skb)->dma = 0;
IXGBE_RSC_CB(skb)->delay_unmap = false;
}
if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)
- rx_ring->rsc_count += skb_shinfo(skb)->nr_frags;
+ rx_ring->rsc_count +=
+ skb_shinfo(skb)->nr_frags;
else
rx_ring->rsc_count++;
rx_ring->rsc_flush++;
}
+ u64_stats_update_begin(&rx_ring->syncp);
rx_ring->stats.packets++;
rx_ring->stats.bytes += skb->len;
+ u64_stats_update_end(&rx_ring->syncp);
} else {
if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
rx_buffer_info->skb = next_buffer->skb;
@@ -1373,8 +1374,6 @@ next_desc:
rx_ring->total_packets += total_rx_packets;
rx_ring->total_bytes += total_rx_bytes;
- netdev->stats.rx_bytes += total_rx_bytes;
- netdev->stats.rx_packets += total_rx_packets;
return cleaned;
}
@@ -1403,24 +1402,24 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
q_vector = adapter->q_vector[v_idx];
/* XXX for_each_set_bit(...) */
r_idx = find_first_bit(q_vector->rxr_idx,
- adapter->num_rx_queues);
+ adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
j = adapter->rx_ring[r_idx]->reg_idx;
ixgbe_set_ivar(adapter, 0, j, v_idx);
r_idx = find_next_bit(q_vector->rxr_idx,
- adapter->num_rx_queues,
- r_idx + 1);
+ adapter->num_rx_queues,
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->txr_idx,
- adapter->num_tx_queues);
+ adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
j = adapter->tx_ring[r_idx]->reg_idx;
ixgbe_set_ivar(adapter, 1, j, v_idx);
r_idx = find_next_bit(q_vector->txr_idx,
- adapter->num_tx_queues,
- r_idx + 1);
+ adapter->num_tx_queues,
+ r_idx + 1);
}
if (q_vector->txr_count && !q_vector->rxr_count)
@@ -1431,11 +1430,26 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
q_vector->eitr = adapter->rx_eitr_param;
ixgbe_write_eitr(q_vector);
+ /* If Flow Director is enabled, set interrupt affinity */
+ if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
+ (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) {
+ /*
+ * Allocate the affinity_hint cpumask, assign the mask
+ * for this vector, and set our affinity_hint for
+ * this irq.
+ */
+ if (!alloc_cpumask_var(&q_vector->affinity_mask,
+ GFP_KERNEL))
+ return;
+ cpumask_set_cpu(v_idx, q_vector->affinity_mask);
+ irq_set_affinity_hint(adapter->msix_entries[v_idx].vector,
+ q_vector->affinity_mask);
+ }
}
if (adapter->hw.mac.type == ixgbe_mac_82598EB)
ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX,
- v_idx);
+ v_idx);
else if (adapter->hw.mac.type == ixgbe_mac_82599EB)
ixgbe_set_ivar(adapter, -1, 1, v_idx);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
@@ -1477,8 +1491,8 @@ enum latency_range {
* parameter (see ixgbe_param.c)
**/
static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter,
- u32 eitr, u8 itr_setting,
- int packets, int bytes)
+ u32 eitr, u8 itr_setting,
+ int packets, int bytes)
{
unsigned int retval = itr_setting;
u32 timepassed_us;
@@ -1567,30 +1581,30 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
for (i = 0; i < q_vector->txr_count; i++) {
tx_ring = adapter->tx_ring[r_idx];
ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
- q_vector->tx_itr,
- tx_ring->total_packets,
- tx_ring->total_bytes);
+ q_vector->tx_itr,
+ tx_ring->total_packets,
+ tx_ring->total_bytes);
/* if the result for this queue would decrease interrupt
* rate for this vector then use that result */
q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ?
- q_vector->tx_itr - 1 : ret_itr);
+ q_vector->tx_itr - 1 : ret_itr);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
rx_ring = adapter->rx_ring[r_idx];
ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
- q_vector->rx_itr,
- rx_ring->total_packets,
- rx_ring->total_bytes);
+ q_vector->rx_itr,
+ rx_ring->total_packets,
+ rx_ring->total_bytes);
/* if the result for this queue would decrease interrupt
* rate for this vector then use that result */
q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ?
- q_vector->rx_itr - 1 : ret_itr);
+ q_vector->rx_itr - 1 : ret_itr);
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
- r_idx + 1);
+ r_idx + 1);
}
current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
@@ -1627,39 +1641,40 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
static void ixgbe_check_overtemp_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- check_overtemp_task);
+ 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) {
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82599_T3_LOM: {
- u32 autoneg;
- bool link_up = false;
+ if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE))
+ return;
- if (hw->mac.ops.check_link)
- hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82599_T3_LOM: {
+ u32 autoneg;
+ bool 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;
- }
+ 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;
+ }
+ default:
+ if (!(eicr & IXGBE_EICR_GPI_SDP0))
return;
- default:
- if (!(eicr & IXGBE_EICR_GPI_SDP0))
- return;
- break;
- }
- e_crit(drv, "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);
+ break;
}
+ e_crit(drv,
+ "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);
}
static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
@@ -1746,9 +1761,9 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
netif_tx_stop_all_queues(netdev);
for (i = 0; i < adapter->num_tx_queues; i++) {
struct ixgbe_ring *tx_ring =
- adapter->tx_ring[i];
+ adapter->tx_ring[i];
if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE,
- &tx_ring->reinit_state))
+ &tx_ring->reinit_state))
schedule_work(&adapter->fdir_reinit_task);
}
}
@@ -1777,7 +1792,7 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter,
}
static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter,
- u64 qmask)
+ u64 qmask)
{
u32 mask;
@@ -1809,7 +1824,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
tx_ring->total_bytes = 0;
tx_ring->total_packets = 0;
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
/* EIAM disabled interrupts (on this vector) for us */
@@ -1837,7 +1852,7 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
rx_ring->total_bytes = 0;
rx_ring->total_packets = 0;
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
- r_idx + 1);
+ r_idx + 1);
}
if (!q_vector->rxr_count)
@@ -1867,7 +1882,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
ring->total_bytes = 0;
ring->total_packets = 0;
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
@@ -1876,7 +1891,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
ring->total_bytes = 0;
ring->total_packets = 0;
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
- r_idx + 1);
+ r_idx + 1);
}
/* EIAM disabled interrupts (on this vector) for us */
@@ -1896,7 +1911,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
- container_of(napi, struct ixgbe_q_vector, napi);
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
struct ixgbe_ring *rx_ring = NULL;
int work_done = 0;
@@ -1918,7 +1933,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable_queues(adapter,
- ((u64)1 << q_vector->v_idx));
+ ((u64)1 << q_vector->v_idx));
}
return work_done;
@@ -1935,7 +1950,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
- container_of(napi, struct ixgbe_q_vector, napi);
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
struct ixgbe_ring *ring = NULL;
int work_done = 0, i;
@@ -1951,7 +1966,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
#endif
tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
/* attempt to distribute budget to each queue fairly, but don't allow
@@ -1967,7 +1982,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
#endif
ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget);
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
- r_idx + 1);
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
@@ -1979,7 +1994,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable_queues(adapter,
- ((u64)1 << q_vector->v_idx));
+ ((u64)1 << q_vector->v_idx));
return 0;
}
@@ -1997,7 +2012,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
- container_of(napi, struct ixgbe_q_vector, napi);
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
struct ixgbe_ring *tx_ring = NULL;
int work_done = 0;
@@ -2019,14 +2034,15 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
if (adapter->tx_itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx));
+ ixgbe_irq_enable_queues(adapter,
+ ((u64)1 << q_vector->v_idx));
}
return work_done;
}
static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
- int r_idx)
+ int r_idx)
{
struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
@@ -2035,7 +2051,7 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
}
static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
- int t_idx)
+ int t_idx)
{
struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
@@ -2055,7 +2071,7 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
* mapping configurations in here.
**/
static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter,
- int vectors)
+ int vectors)
{
int v_start = 0;
int rxr_idx = 0, txr_idx = 0;
@@ -2122,7 +2138,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
struct net_device *netdev = adapter->netdev;
irqreturn_t (*handler)(int, void *);
int i, vector, q_vectors, err;
- int ri=0, ti=0;
+ int ri = 0, ti = 0;
/* Decrement for Other and TCP Timer vectors */
q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
@@ -2133,26 +2149,24 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
goto out;
#define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \
- (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
- &ixgbe_msix_clean_many)
+ (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
+ &ixgbe_msix_clean_many)
for (vector = 0; vector < q_vectors; vector++) {
handler = SET_HANDLER(adapter->q_vector[vector]);
- if(handler == &ixgbe_msix_clean_rx) {
+ if (handler == &ixgbe_msix_clean_rx) {
sprintf(adapter->name[vector], "%s-%s-%d",
netdev->name, "rx", ri++);
- }
- else if(handler == &ixgbe_msix_clean_tx) {
+ } else if (handler == &ixgbe_msix_clean_tx) {
sprintf(adapter->name[vector], "%s-%s-%d",
netdev->name, "tx", ti++);
- }
- else
+ } else
sprintf(adapter->name[vector], "%s-%s-%d",
netdev->name, "TxRx", vector);
err = request_irq(adapter->msix_entries[vector].vector,
- handler, 0, adapter->name[vector],
- adapter->q_vector[vector]);
+ handler, 0, adapter->name[vector],
+ adapter->q_vector[vector]);
if (err) {
e_err(probe, "request_irq failed for MSIX interrupt "
"Error: %d\n", err);
@@ -2162,7 +2176,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
sprintf(adapter->name[vector], "%s:lsc", netdev->name);
err = request_irq(adapter->msix_entries[vector].vector,
- ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
+ ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
if (err) {
e_err(probe, "request_irq for msix_lsc failed: %d\n", err);
goto free_queue_irqs;
@@ -2173,7 +2187,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
free_queue_irqs:
for (i = vector - 1; i >= 0; i--)
free_irq(adapter->msix_entries[--vector].vector,
- adapter->q_vector[i]);
+ adapter->q_vector[i]);
adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
pci_disable_msix(adapter->pdev);
kfree(adapter->msix_entries);
@@ -2191,13 +2205,13 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
struct ixgbe_ring *tx_ring = adapter->tx_ring[0];
q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr,
- q_vector->tx_itr,
- tx_ring->total_packets,
- tx_ring->total_bytes);
+ q_vector->tx_itr,
+ tx_ring->total_packets,
+ tx_ring->total_bytes);
q_vector->rx_itr = ixgbe_update_itr(adapter, new_itr,
- q_vector->rx_itr,
- rx_ring->total_packets,
- rx_ring->total_bytes);
+ q_vector->rx_itr,
+ rx_ring->total_packets,
+ rx_ring->total_bytes);
current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
@@ -2231,7 +2245,8 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
* ixgbe_irq_enable - Enable default interrupt generation settings
* @adapter: board private structure
**/
-static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
+static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues,
+ bool flush)
{
u32 mask;
@@ -2252,8 +2267,10 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
mask |= IXGBE_EIMS_FLOW_DIR;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
- ixgbe_irq_enable_queues(adapter, ~0);
- IXGBE_WRITE_FLUSH(&adapter->hw);
+ if (queues)
+ ixgbe_irq_enable_queues(adapter, ~0);
+ if (flush)
+ IXGBE_WRITE_FLUSH(&adapter->hw);
if (adapter->num_vfs > 32) {
u32 eitrsel = (1 << (adapter->num_vfs - 32)) - 1;
@@ -2275,7 +2292,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
u32 eicr;
/*
- * Workaround for silicon errata. Mask the interrupts
+ * Workaround for silicon errata on 82598. Mask the interrupts
* before the read of EICR.
*/
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
@@ -2284,10 +2301,15 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
* therefore no explict interrupt disable is necessary */
eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
if (!eicr) {
- /* shared interrupt alert!
+ /*
+ * shared interrupt alert!
* make sure interrupts are enabled because the read will
- * have disabled interrupts due to EIAM */
- ixgbe_irq_enable(adapter);
+ * have disabled interrupts due to EIAM
+ * finish the workaround of silicon errata on 82598. Unmask
+ * the interrupt that we masked before the EICR read.
+ */
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ ixgbe_irq_enable(adapter, true, true);
return IRQ_NONE; /* Not our interrupt */
}
@@ -2311,6 +2333,14 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
__napi_schedule(&(q_vector->napi));
}
+ /*
+ * re-enable link(maybe) and non-queue interrupts, no flush.
+ * ixgbe_poll will re-enable the queue interrupts
+ */
+
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ ixgbe_irq_enable(adapter, false, false);
+
return IRQ_HANDLED;
}
@@ -2343,10 +2373,10 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter)
err = ixgbe_request_msix_irqs(adapter);
} else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
err = request_irq(adapter->pdev->irq, ixgbe_intr, 0,
- netdev->name, netdev);
+ netdev->name, netdev);
} else {
err = request_irq(adapter->pdev->irq, ixgbe_intr, IRQF_SHARED,
- netdev->name, netdev);
+ netdev->name, netdev);
}
if (err)
@@ -2370,7 +2400,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
i--;
for (; i >= 0; i--) {
free_irq(adapter->msix_entries[i].vector,
- adapter->q_vector[i]);
+ adapter->q_vector[i]);
}
ixgbe_reset_q_vectors(adapter);
@@ -2413,7 +2443,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
- EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr_param));
+ EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr_param));
ixgbe_set_ivar(adapter, 0, 0, 0);
ixgbe_set_ivar(adapter, 1, 0, 0);
@@ -2425,95 +2455,140 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
}
/**
- * ixgbe_configure_tx - Configure 8259x Transmit Unit after Reset
+ * ixgbe_configure_tx_ring - Configure 8259x Tx ring after Reset
* @adapter: board private structure
+ * @ring: structure containing ring specific data
*
- * Configure the Tx unit of the MAC after a reset.
+ * Configure the Tx descriptor ring after a reset.
**/
-static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
+void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
{
- u64 tdba;
struct ixgbe_hw *hw = &adapter->hw;
- u32 i, j, tdlen, txctrl;
+ u64 tdba = ring->dma;
+ int wait_loop = 10;
+ u32 txdctl;
+ u16 reg_idx = ring->reg_idx;
- /* Setup the HW Tx Head and Tail descriptor pointers */
- for (i = 0; i < adapter->num_tx_queues; i++) {
- struct ixgbe_ring *ring = adapter->tx_ring[i];
- j = ring->reg_idx;
- tdba = ring->dma;
- tdlen = ring->count * sizeof(union ixgbe_adv_tx_desc);
- IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
- (tdba & DMA_BIT_MASK(32)));
- IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
- IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen);
- IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
- IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
- adapter->tx_ring[i]->head = IXGBE_TDH(j);
- adapter->tx_ring[i]->tail = IXGBE_TDT(j);
- /*
- * Disable Tx Head Writeback RO bit, since this hoses
- * bookkeeping if things aren't delivered in order.
- */
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j));
- break;
- case ixgbe_mac_82599EB:
- default:
- txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j));
- break;
- }
- txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
- break;
- case ixgbe_mac_82599EB:
- default:
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl);
- break;
- }
+ /* disable queue to avoid issues while updating state */
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx),
+ txdctl & ~IXGBE_TXDCTL_ENABLE);
+ IXGBE_WRITE_FLUSH(hw);
+
+ IXGBE_WRITE_REG(hw, IXGBE_TDBAL(reg_idx),
+ (tdba & DMA_BIT_MASK(32)));
+ IXGBE_WRITE_REG(hw, IXGBE_TDBAH(reg_idx), (tdba >> 32));
+ IXGBE_WRITE_REG(hw, IXGBE_TDLEN(reg_idx),
+ ring->count * sizeof(union ixgbe_adv_tx_desc));
+ IXGBE_WRITE_REG(hw, IXGBE_TDH(reg_idx), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_TDT(reg_idx), 0);
+ ring->head = IXGBE_TDH(reg_idx);
+ ring->tail = IXGBE_TDT(reg_idx);
+
+ /* configure fetching thresholds */
+ if (adapter->rx_itr_setting == 0) {
+ /* cannot set wthresh when itr==0 */
+ txdctl &= ~0x007F0000;
+ } else {
+ /* enable WTHRESH=8 descriptors, to encourage burst writeback */
+ txdctl |= (8 << 16);
+ }
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ /* PThresh workaround for Tx hang with DFP enabled. */
+ txdctl |= 32;
}
- if (hw->mac.type == ixgbe_mac_82599EB) {
- u32 rttdcs;
- u32 mask;
+ /* reinitialize flowdirector state */
+ set_bit(__IXGBE_FDIR_INIT_DONE, &ring->reinit_state);
- /* disable the arbiter while setting MTQC */
- rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
- rttdcs |= IXGBE_RTTDCS_ARBDIS;
- IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+ /* enable queue */
+ txdctl |= IXGBE_TXDCTL_ENABLE;
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl);
- /* set transmit pool layout */
- mask = (IXGBE_FLAG_SRIOV_ENABLED | IXGBE_FLAG_DCB_ENABLED);
- switch (adapter->flags & mask) {
+ /* TXDCTL.EN will return 0 on 82598 if link is down, so skip it */
+ if (hw->mac.type == ixgbe_mac_82598EB &&
+ !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
+ return;
- case (IXGBE_FLAG_SRIOV_ENABLED):
- IXGBE_WRITE_REG(hw, IXGBE_MTQC,
- (IXGBE_MTQC_VT_ENA | IXGBE_MTQC_64VF));
- break;
+ /* poll to verify queue is enabled */
+ do {
+ msleep(1);
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
+ } while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
+ if (!wait_loop)
+ e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+}
- case (IXGBE_FLAG_DCB_ENABLED):
- /* We enable 8 traffic classes, DCB only */
- IXGBE_WRITE_REG(hw, IXGBE_MTQC,
- (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ));
- break;
+static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 rttdcs;
+ u32 mask;
- default:
- IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB);
- break;
- }
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ return;
+
+ /* disable the arbiter while setting MTQC */
+ rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+ rttdcs |= IXGBE_RTTDCS_ARBDIS;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+
+ /* set transmit pool layout */
+ mask = (IXGBE_FLAG_SRIOV_ENABLED | IXGBE_FLAG_DCB_ENABLED);
+ switch (adapter->flags & mask) {
+
+ case (IXGBE_FLAG_SRIOV_ENABLED):
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC,
+ (IXGBE_MTQC_VT_ENA | IXGBE_MTQC_64VF));
+ break;
+
+ case (IXGBE_FLAG_DCB_ENABLED):
+ /* We enable 8 traffic classes, DCB only */
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC,
+ (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ));
+ break;
+
+ default:
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB);
+ break;
+ }
+
+ /* re-enable the arbiter */
+ rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+}
- /* re-eable the arbiter */
- rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
- IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+/**
+ * ixgbe_configure_tx - Configure 8259x Transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 dmatxctl;
+ u32 i;
+
+ ixgbe_setup_mtqc(adapter);
+
+ if (hw->mac.type != ixgbe_mac_82598EB) {
+ /* DMATXCTL.EN must be before Tx queues are enabled */
+ dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+ dmatxctl |= IXGBE_DMATXCTL_TE;
+ IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
}
+
+ /* Setup the HW Tx Head and Tail descriptor pointers */
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ ixgbe_configure_tx_ring(adapter, adapter->tx_ring[i]);
}
#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
u32 srrctl;
int index;
@@ -2529,6 +2604,8 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
+ if (adapter->num_vfs)
+ srrctl |= IXGBE_SRRCTL_DROP_EN;
srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
IXGBE_SRRCTL_BSIZEHDR_MASK;
@@ -2549,20 +2626,46 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
}
-static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
+static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
{
- u32 mrqc = 0;
+ struct ixgbe_hw *hw = &adapter->hw;
+ static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D,
+ 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE,
+ 0x6A3E67EA, 0x14364D17, 0x3BED200D};
+ u32 mrqc = 0, reta = 0;
+ u32 rxcsum;
+ int i, j;
int mask;
- if (!(adapter->hw.mac.type == ixgbe_mac_82599EB))
- return mrqc;
+ /* Fill out hash function seeds */
+ for (i = 0; i < 10; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
- mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED
+ /* Fill out redirection table */
+ for (i = 0, j = 0; i < 128; i++, j++) {
+ if (j == adapter->ring_feature[RING_F_RSS].indices)
+ j = 0;
+ /* reta = 4-byte sliding window of
+ * 0x00..(indices-1)(indices-1)00..etc. */
+ reta = (reta << 8) | (j * 0x11);
+ if ((i & 3) == 3)
+ IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
+ }
+
+ /* Disable indicating checksum in descriptor, enables RSS hash */
+ rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
+ rxcsum |= IXGBE_RXCSUM_PCSD;
+ IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
+
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ mask = adapter->flags & IXGBE_FLAG_RSS_ENABLED;
+ else
+ mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED
#ifdef CONFIG_IXGBE_DCB
- | IXGBE_FLAG_DCB_ENABLED
+ | IXGBE_FLAG_DCB_ENABLED
#endif
- | IXGBE_FLAG_SRIOV_ENABLED
- );
+ | IXGBE_FLAG_SRIOV_ENABLED
+ );
switch (mask) {
case (IXGBE_FLAG_RSS_ENABLED):
@@ -2580,7 +2683,13 @@ static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
break;
}
- return mrqc;
+ /* Perform hash on these packet types */
+ mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4
+ | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
+ | IXGBE_MRQC_RSS_FIELD_IPV6
+ | IXGBE_MRQC_RSS_FIELD_IPV6_TCP;
+
+ IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
}
/**
@@ -2588,25 +2697,26 @@ static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
* @adapter: address of board private structure
* @index: index of ring to set
**/
-static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index)
+static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
{
- struct ixgbe_ring *rx_ring;
struct ixgbe_hw *hw = &adapter->hw;
- int j;
u32 rscctrl;
int rx_buf_len;
+ u16 reg_idx = ring->reg_idx;
+
+ if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))
+ return;
- rx_ring = adapter->rx_ring[index];
- j = rx_ring->reg_idx;
- rx_buf_len = rx_ring->rx_buf_len;
- rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j));
+ rx_buf_len = ring->rx_buf_len;
+ rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx));
rscctrl |= IXGBE_RSCCTL_RSCEN;
/*
* we must limit the number of descriptors so that the
* total size of max desc * buf_len is not greater
* than 65535
*/
- if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
+ if (ring->flags & IXGBE_RING_RX_PS_ENABLED) {
#if (MAX_SKB_FRAGS > 16)
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
#elif (MAX_SKB_FRAGS > 8)
@@ -2624,31 +2734,181 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index)
else
rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
}
- IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl);
+ IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl);
}
/**
- * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
- * @adapter: board private structure
+ * ixgbe_set_uta - Set unicast filter table address
+ * @adapter: board private structure
*
- * Configure the Rx unit of the MAC after a reset.
+ * The unicast table address is a register array of 32-bit registers.
+ * The table is meant to be used in a way similar to how the MTA is used
+ * however due to certain limitations in the hardware it is necessary to
+ * set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscuous
+ * enable bit to allow vlan tag stripping when promiscuous mode is enabled
**/
-static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
+static void ixgbe_set_uta(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+
+ /* The UTA table only exists on 82599 hardware and newer */
+ if (hw->mac.type < ixgbe_mac_82599EB)
+ return;
+
+ /* we only need to do this if VMDq is enabled */
+ if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
+ return;
+
+ for (i = 0; i < 128; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_UTA(i), ~0);
+}
+
+#define IXGBE_MAX_RX_DESC_POLL 10
+static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int reg_idx = ring->reg_idx;
+ int wait_loop = IXGBE_MAX_RX_DESC_POLL;
+ u32 rxdctl;
+
+ /* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */
+ if (hw->mac.type == ixgbe_mac_82598EB &&
+ !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
+ return;
+
+ do {
+ msleep(1);
+ rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
+ } while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE));
+
+ if (!wait_loop) {
+ e_err(drv, "RXDCTL.ENABLE on Rx queue %d not set within "
+ "the polling period\n", reg_idx);
+ }
+}
+
+void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u64 rdba = ring->dma;
+ u32 rxdctl;
+ u16 reg_idx = ring->reg_idx;
+
+ /* disable queue to avoid issues while updating state */
+ rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx),
+ rxdctl & ~IXGBE_RXDCTL_ENABLE);
+ IXGBE_WRITE_FLUSH(hw);
+
+ IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32)));
+ IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32));
+ IXGBE_WRITE_REG(hw, IXGBE_RDLEN(reg_idx),
+ ring->count * sizeof(union ixgbe_adv_rx_desc));
+ IXGBE_WRITE_REG(hw, IXGBE_RDH(reg_idx), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0);
+ ring->head = IXGBE_RDH(reg_idx);
+ ring->tail = IXGBE_RDT(reg_idx);
+
+ ixgbe_configure_srrctl(adapter, ring);
+ ixgbe_configure_rscctl(adapter, ring);
+
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ /*
+ * enable cache line friendly hardware writes:
+ * PTHRESH=32 descriptors (half the internal cache),
+ * this also removes ugly rx_no_buffer_count increment
+ * HTHRESH=4 descriptors (to minimize latency on fetch)
+ * WTHRESH=8 burst writeback up to two cache lines
+ */
+ rxdctl &= ~0x3FFFFF;
+ rxdctl |= 0x080420;
+ }
+
+ /* enable receive descriptor ring */
+ rxdctl |= IXGBE_RXDCTL_ENABLE;
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
+
+ ixgbe_rx_desc_queue_enable(adapter, ring);
+ ixgbe_alloc_rx_buffers(adapter, ring, IXGBE_DESC_UNUSED(ring));
+}
+
+static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int p;
+
+ /* PSRTYPE must be initialized in non 82598 adapters */
+ u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
+ IXGBE_PSRTYPE_UDPHDR |
+ IXGBE_PSRTYPE_IPV4HDR |
+ IXGBE_PSRTYPE_L2HDR |
+ IXGBE_PSRTYPE_IPV6HDR;
+
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ return;
+
+ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED)
+ psrtype |= (adapter->num_rx_queues_per_pool << 29);
+
+ for (p = 0; p < adapter->num_rx_pools; p++)
+ IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(adapter->num_vfs + p),
+ psrtype);
+}
+
+static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 gcr_ext;
+ u32 vt_reg_bits;
+ u32 reg_offset, vf_shift;
+ u32 vmdctl;
+
+ if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
+ return;
+
+ vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
+ vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN | IXGBE_VT_CTL_REPLEN;
+ vt_reg_bits |= (adapter->num_vfs << IXGBE_VT_CTL_POOL_SHIFT);
+ IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits);
+
+ vf_shift = adapter->num_vfs % 32;
+ reg_offset = (adapter->num_vfs > 32) ? 1 : 0;
+
+ /* Enable only the PF's pool for Tx/Rx */
+ IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift));
+ IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset ^ 1), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (1 << vf_shift));
+ IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset ^ 1), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
+
+ /* Map PF MAC address in RAR Entry 0 to first pool following VFs */
+ hw->mac.ops.set_vmdq(hw, 0, adapter->num_vfs);
+
+ /*
+ * Set up VF register offsets for selected VT Mode,
+ * i.e. 32 or 64 VFs for SR-IOV
+ */
+ gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
+ gcr_ext |= IXGBE_GCR_EXT_MSIX_EN;
+ gcr_ext |= IXGBE_GCR_EXT_VT_MODE_64;
+ IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
+
+ /* enable Tx loopback for VF/PF communication */
+ IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
+}
+
+static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)
{
- u64 rdba;
struct ixgbe_hw *hw = &adapter->hw;
- struct ixgbe_ring *rx_ring;
struct net_device *netdev = adapter->netdev;
int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
- int i, j;
- u32 rdlen, rxctrl, rxcsum;
- static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D,
- 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE,
- 0x6A3E67EA, 0x14364D17, 0x3BED200D};
- u32 fctrl, hlreg0;
- u32 reta = 0, mrqc = 0;
- u32 rdrxctl;
int rx_buf_len;
+ struct ixgbe_ring *rx_ring;
+ int i;
+ u32 mhadd, hlreg0;
/* Decide whether to use packet split mode or not */
/* Do not use packet split if we're in SR-IOV Mode */
@@ -2658,62 +2918,40 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
/* Set the RX buffer length according to the mode */
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
rx_buf_len = IXGBE_RX_HDR_SIZE;
- if (hw->mac.type == ixgbe_mac_82599EB) {
- /* PSRTYPE must be initialized in 82599 */
- u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
- IXGBE_PSRTYPE_UDPHDR |
- IXGBE_PSRTYPE_IPV4HDR |
- IXGBE_PSRTYPE_IPV6HDR |
- IXGBE_PSRTYPE_L2HDR;
- IXGBE_WRITE_REG(hw,
- IXGBE_PSRTYPE(adapter->num_vfs),
- psrtype);
- }
} else {
if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) &&
(netdev->mtu <= ETH_DATA_LEN))
rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
else
- rx_buf_len = ALIGN(max_frame, 1024);
+ rx_buf_len = ALIGN(max_frame + VLAN_HLEN, 1024);
}
- fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
- fctrl |= IXGBE_FCTRL_BAM;
- fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
- fctrl |= IXGBE_FCTRL_PMCF;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
+#ifdef IXGBE_FCOE
+ /* adjust max frame to be able to do baby jumbo for FCoE */
+ if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
+ (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE))
+ max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE;
+
+#endif /* IXGBE_FCOE */
+ mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
+ if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
+ mhadd &= ~IXGBE_MHADD_MFS_MASK;
+ mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT;
+
+ IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd);
+ }
hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
- if (adapter->netdev->mtu <= ETH_DATA_LEN)
- hlreg0 &= ~IXGBE_HLREG0_JUMBOEN;
- else
- hlreg0 |= IXGBE_HLREG0_JUMBOEN;
-#ifdef IXGBE_FCOE
- if (netdev->features & NETIF_F_FCOE_MTU)
- hlreg0 |= IXGBE_HLREG0_JUMBOEN;
-#endif
+ /* set jumbo enable since MHADD.MFS is keeping size locked at max_frame */
+ hlreg0 |= IXGBE_HLREG0_JUMBOEN;
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
- rdlen = adapter->rx_ring[0]->count * sizeof(union ixgbe_adv_rx_desc);
- /* disable receives while setting up the descriptors */
- rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
- IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
-
/*
* Setup the HW Rx Head and Tail Descriptor Pointers and
* the Base and Length of the Rx Descriptor Ring
*/
for (i = 0; i < adapter->num_rx_queues; i++) {
rx_ring = adapter->rx_ring[i];
- rdba = rx_ring->dma;
- j = rx_ring->reg_idx;
- IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_BIT_MASK(32)));
- IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32));
- IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j), rdlen);
- IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0);
- IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0);
- rx_ring->head = IXGBE_RDH(j);
- rx_ring->tail = IXGBE_RDT(j);
rx_ring->rx_buf_len = rx_buf_len;
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)
@@ -2729,15 +2967,21 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED;
if (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE)
rx_ring->rx_buf_len =
- IXGBE_FCOE_JUMBO_FRAME_SIZE;
+ IXGBE_FCOE_JUMBO_FRAME_SIZE;
}
}
-
#endif /* IXGBE_FCOE */
- ixgbe_configure_srrctl(adapter, rx_ring);
}
- if (hw->mac.type == ixgbe_mac_82598EB) {
+}
+
+static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
/*
* For VMDq support of different descriptor types or
* buffer sizes through the use of multiple SRRCTL
@@ -2748,110 +2992,66 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
* effects of setting this bit are only that SRRCTL must be
* fully programmed [0..15]
*/
- rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
rdrxctl |= IXGBE_RDRXCTL_MVMEN;
- IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
+ break;
+ case ixgbe_mac_82599EB:
+ /* Disable RSC for ACK packets */
+ IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
+ (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU)));
+ rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE;
+ /* hardware requires some bits to be set by default */
+ rdrxctl |= (IXGBE_RDRXCTL_RSCACKC | IXGBE_RDRXCTL_FCOE_WRFIX);
+ rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
+ break;
+ default:
+ /* We should do nothing since we don't know this hardware */
+ return;
}
- if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
- u32 vt_reg_bits;
- u32 reg_offset, vf_shift;
- u32 vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
- vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN
- | IXGBE_VT_CTL_REPLEN;
- vt_reg_bits |= (adapter->num_vfs <<
- IXGBE_VT_CTL_POOL_SHIFT);
- IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits);
- IXGBE_WRITE_REG(hw, IXGBE_MRQC, 0);
-
- vf_shift = adapter->num_vfs % 32;
- reg_offset = adapter->num_vfs / 32;
- IXGBE_WRITE_REG(hw, IXGBE_VFRE(0), 0);
- IXGBE_WRITE_REG(hw, IXGBE_VFRE(1), 0);
- IXGBE_WRITE_REG(hw, IXGBE_VFTE(0), 0);
- IXGBE_WRITE_REG(hw, IXGBE_VFTE(1), 0);
- /* Enable only the PF's pool for Tx/Rx */
- IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift));
- IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (1 << vf_shift));
- IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
- ixgbe_set_vmolr(hw, adapter->num_vfs, true);
- }
-
- /* Program MRQC for the distribution of queues */
- mrqc = ixgbe_setup_mrqc(adapter);
-
- if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
- /* Fill out redirection table */
- for (i = 0, j = 0; i < 128; i++, j++) {
- if (j == adapter->ring_feature[RING_F_RSS].indices)
- j = 0;
- /* reta = 4-byte sliding window of
- * 0x00..(indices-1)(indices-1)00..etc. */
- reta = (reta << 8) | (j * 0x11);
- if ((i & 3) == 3)
- IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
- }
-
- /* Fill out hash function seeds */
- for (i = 0; i < 10; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
-
- if (hw->mac.type == ixgbe_mac_82598EB)
- mrqc |= IXGBE_MRQC_RSSEN;
- /* Perform hash on these packet types */
- mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4
- | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV6
- | IXGBE_MRQC_RSS_FIELD_IPV6_TCP;
- }
- IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
+ IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
+}
- if (adapter->num_vfs) {
- u32 reg;
+/**
+ * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+ u32 rxctrl;
- /* Map PF MAC address in RAR Entry 0 to first pool
- * following VFs */
- hw->mac.ops.set_vmdq(hw, 0, adapter->num_vfs);
+ /* disable receives while setting up the descriptors */
+ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
- /* Set up VF register offsets for selected VT Mode, i.e.
- * 64 VFs for SR-IOV */
- reg = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
- reg |= IXGBE_GCR_EXT_SRIOV;
- IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, reg);
- }
+ ixgbe_setup_psrtype(adapter);
+ ixgbe_setup_rdrxctl(adapter);
- rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
+ /* Program registers for the distribution of queues */
+ ixgbe_setup_mrqc(adapter);
- if (adapter->flags & IXGBE_FLAG_RSS_ENABLED ||
- adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED) {
- /* Disable indicating checksum in descriptor, enables
- * RSS hash */
- rxcsum |= IXGBE_RXCSUM_PCSD;
- }
- if (!(rxcsum & IXGBE_RXCSUM_PCSD)) {
- /* Enable IPv4 payload checksum for UDP fragments
- * if PCSD is not set */
- rxcsum |= IXGBE_RXCSUM_IPPCSE;
- }
+ ixgbe_set_uta(adapter);
- IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
+ /* set_rx_buffer_len must be called before ring initialization */
+ ixgbe_set_rx_buffer_len(adapter);
- if (hw->mac.type == ixgbe_mac_82599EB) {
- rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
- rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
- rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE;
- IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
- }
+ /*
+ * Setup the HW Rx Head and Tail Descriptor Pointers and
+ * the Base and Length of the Rx Descriptor Ring
+ */
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ ixgbe_configure_rx_ring(adapter, adapter->rx_ring[i]);
- if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
- /* Enable 82599 HW-RSC */
- for (i = 0; i < adapter->num_rx_queues; i++)
- ixgbe_configure_rscctl(adapter, i);
+ /* disable drop enable for 82598 parts */
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ rxctrl |= IXGBE_RXCTRL_DMBYPS;
- /* Disable RSC for ACK packets */
- IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
- (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU)));
- }
+ /* enable all receives */
+ rxctrl |= IXGBE_RXCTRL_RXEN;
+ hw->mac.ops.enable_rx_dma(hw, rxctrl);
}
static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
@@ -2862,6 +3062,7 @@ static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
/* add VID to filter table */
hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, true);
+ set_bit(vid, adapter->active_vlans);
}
static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
@@ -2870,16 +3071,9 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
struct ixgbe_hw *hw = &adapter->hw;
int pool_ndx = adapter->num_vfs;
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_disable(adapter);
-
- vlan_group_set_device(adapter->vlgrp, vid, NULL);
-
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable(adapter);
-
/* remove VID from filter table */
hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false);
+ clear_bit(vid, adapter->active_vlans);
}
/**
@@ -2889,27 +3083,45 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+ u32 vlnctrl;
+
+ vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+ vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
+ IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+}
+
+/**
+ * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering
+ * @adapter: driver data
+ */
+static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 vlnctrl;
+
+ vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+ vlnctrl |= IXGBE_VLNCTRL_VFE;
+ vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+ IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+}
+
+/**
+ * ixgbe_vlan_strip_disable - helper to disable hw vlan stripping
+ * @adapter: driver data
+ */
+static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 vlnctrl;
int i, j;
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
- vlnctrl &= ~IXGBE_VLNCTRL_VFE;
-#ifdef CONFIG_IXGBE_DCB
- if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
- vlnctrl &= ~IXGBE_VLNCTRL_VME;
-#endif
- vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+ vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+ vlnctrl &= ~IXGBE_VLNCTRL_VME;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
break;
case ixgbe_mac_82599EB:
- vlnctrl &= ~IXGBE_VLNCTRL_VFE;
- vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
- IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
-#ifdef CONFIG_IXGBE_DCB
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
- break;
-#endif
for (i = 0; i < adapter->num_rx_queues; i++) {
j = adapter->rx_ring[i]->reg_idx;
vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
@@ -2923,25 +3135,22 @@ static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter)
}
/**
- * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering
+ * ixgbe_vlan_strip_enable - helper to enable hw vlan stripping
* @adapter: driver data
*/
-static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
+static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+ u32 vlnctrl;
int i, j;
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
- vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
- vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+ vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+ vlnctrl |= IXGBE_VLNCTRL_VME;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
break;
case ixgbe_mac_82599EB:
- vlnctrl |= IXGBE_VLNCTRL_VFE;
- vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
- IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
for (i = 0; i < adapter->num_rx_queues; i++) {
j = adapter->rx_ring[i]->reg_idx;
vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
@@ -2954,40 +3163,14 @@ static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
}
}
-static void ixgbe_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_disable(adapter);
- adapter->vlgrp = grp;
-
- /*
- * For a DCB driver, always enable VLAN tag stripping so we can
- * still receive traffic from a DCB-enabled host even if we're
- * not in DCB mode.
- */
- ixgbe_vlan_filter_enable(adapter);
-
- ixgbe_vlan_rx_add_vid(netdev, 0);
-
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable(adapter);
-}
-
static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
{
- ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+ u16 vid;
- if (adapter->vlgrp) {
- u16 vid;
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
- if (!vlan_group_get_device(adapter->vlgrp, vid))
- continue;
- ixgbe_vlan_rx_add_vid(adapter->netdev, vid);
- }
- }
+ ixgbe_vlan_rx_add_vid(adapter->netdev, 0);
+
+ for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
+ ixgbe_vlan_rx_add_vid(adapter->netdev, vid);
}
/**
@@ -3052,6 +3235,11 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ /* set all bits that we expect to always be set */
+ fctrl |= IXGBE_FCTRL_BAM;
+ fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
+ fctrl |= IXGBE_FCTRL_PMCF;
+
/* clear the bits we are changing the status of */
fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
@@ -3097,6 +3285,11 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
}
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+
+ if (netdev->features & NETIF_F_HW_VLAN_RX)
+ ixgbe_vlan_strip_enable(adapter);
+ else
+ ixgbe_vlan_strip_disable(adapter);
}
static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
@@ -3157,7 +3350,15 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
u32 txdctl;
int i, j;
- ixgbe_dcb_check_config(&adapter->dcb_cfg);
+ if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) {
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ netif_set_gso_max_size(adapter->netdev, 65536);
+ return;
+ }
+
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ netif_set_gso_max_size(adapter->netdev, 32768);
+
ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_TX_CONFIG);
ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_RX_CONFIG);
@@ -3172,7 +3373,7 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
}
/* Enable VLAN tag insert/strip */
- ixgbe_vlan_filter_enable(adapter);
+ adapter->netdev->features |= NETIF_F_HW_VLAN_RX;
hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true);
}
@@ -3184,23 +3385,13 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
int i;
- ixgbe_set_rx_mode(netdev);
-
- ixgbe_restore_vlan(adapter);
#ifdef CONFIG_IXGBE_DCB
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- if (hw->mac.type == ixgbe_mac_82598EB)
- netif_set_gso_max_size(netdev, 32768);
- else
- netif_set_gso_max_size(netdev, 65536);
- ixgbe_configure_dcb(adapter);
- } else {
- netif_set_gso_max_size(netdev, 65536);
- }
-#else
- netif_set_gso_max_size(netdev, 65536);
+ ixgbe_configure_dcb(adapter);
#endif
+ ixgbe_set_rx_mode(netdev);
+ ixgbe_restore_vlan(adapter);
+
#ifdef IXGBE_FCOE
if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
ixgbe_configure_fcoe(adapter);
@@ -3209,17 +3400,15 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
for (i = 0; i < adapter->num_tx_queues; i++)
adapter->tx_ring[i]->atr_sample_rate =
- adapter->atr_sample_rate;
+ adapter->atr_sample_rate;
ixgbe_init_fdir_signature_82599(hw, adapter->fdir_pballoc);
} else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) {
ixgbe_init_fdir_perfect_82599(hw, adapter->fdir_pballoc);
}
+ ixgbe_configure_virtualization(adapter);
ixgbe_configure_tx(adapter);
ixgbe_configure_rx(adapter);
- for (i = 0; i < adapter->num_rx_queues; i++)
- ixgbe_alloc_rx_buffers(adapter, adapter->rx_ring[i],
- (adapter->rx_ring[i]->count - 1));
}
static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
@@ -3290,7 +3479,8 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
goto link_cfg_out;
if (hw->mac.ops.get_link_capabilities)
- ret = hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
+ ret = hw->mac.ops.get_link_capabilities(hw, &autoneg,
+ &negotiation);
if (ret)
goto link_cfg_out;
@@ -3300,62 +3490,15 @@ link_cfg_out:
return ret;
}
-#define IXGBE_MAX_RX_DESC_POLL 10
-static inline void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
- int rxr)
+static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter)
{
- int j = adapter->rx_ring[rxr]->reg_idx;
- int k;
-
- for (k = 0; k < IXGBE_MAX_RX_DESC_POLL; k++) {
- if (IXGBE_READ_REG(&adapter->hw,
- IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE)
- break;
- else
- msleep(1);
- }
- if (k >= IXGBE_MAX_RX_DESC_POLL) {
- e_err(drv, "RXDCTL.ENABLE on Rx queue %d not set within "
- "the polling period\n", rxr);
- }
- ixgbe_release_rx_desc(&adapter->hw, adapter->rx_ring[rxr],
- (adapter->rx_ring[rxr]->count - 1));
-}
-
-static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
- int i, j = 0;
- int num_rx_rings = adapter->num_rx_queues;
- int err;
- int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
- u32 txdctl, rxdctl, mhadd;
- u32 dmatxctl;
- u32 gpie;
- u32 ctrl_ext;
-
- ixgbe_get_hw_control(adapter);
-
- if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) ||
- (adapter->flags & IXGBE_FLAG_MSI_ENABLED)) {
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- gpie = (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME |
- IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD);
- } else {
- /* MSI only */
- gpie = 0;
- }
- if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
- gpie &= ~IXGBE_GPIE_VTMODE_MASK;
- gpie |= IXGBE_GPIE_VTMODE_64;
- }
- /* XXX: to interrupt immediately for EICS writes, enable this */
- /* gpie |= IXGBE_GPIE_EIMEN; */
- IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
- }
+ u32 gpie = 0;
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ gpie = IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_PBA_SUPPORT |
+ IXGBE_GPIE_OCD;
+ gpie |= IXGBE_GPIE_EIAME;
/*
* use EIAM to auto-mask when MSI-X interrupt is asserted
* this saves a register write for every interrupt
@@ -3376,98 +3519,33 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
}
- /* Enable Thermal over heat sensor interrupt */
- if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) {
- gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
- gpie |= IXGBE_SDP0_GPIEN;
- IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+ /* XXX: to interrupt immediately for EICS writes, enable this */
+ /* gpie |= IXGBE_GPIE_EIMEN; */
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+ gpie &= ~IXGBE_GPIE_VTMODE_MASK;
+ gpie |= IXGBE_GPIE_VTMODE_64;
}
- /* Enable fan failure interrupt if media type is copper */
- if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
- gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+ /* Enable fan failure interrupt */
+ if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
gpie |= IXGBE_SDP1_GPIEN;
- IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
- }
- if (hw->mac.type == ixgbe_mac_82599EB) {
- gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+ if (hw->mac.type == ixgbe_mac_82599EB)
gpie |= IXGBE_SDP1_GPIEN;
gpie |= IXGBE_SDP2_GPIEN;
- IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
- }
-#ifdef IXGBE_FCOE
- /* adjust max frame to be able to do baby jumbo for FCoE */
- if ((netdev->features & NETIF_F_FCOE_MTU) &&
- (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE))
- max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE;
-
-#endif /* IXGBE_FCOE */
- mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
- if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
- mhadd &= ~IXGBE_MHADD_MFS_MASK;
- mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT;
-
- IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd);
- }
-
- for (i = 0; i < adapter->num_tx_queues; i++) {
- j = adapter->tx_ring[i]->reg_idx;
- txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
- if (adapter->rx_itr_setting == 0) {
- /* cannot set wthresh when itr==0 */
- txdctl &= ~0x007F0000;
- } else {
- /* enable WTHRESH=8 descriptors, to encourage burst writeback */
- txdctl |= (8 << 16);
- }
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
- }
+ IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+}
- if (hw->mac.type == ixgbe_mac_82599EB) {
- /* DMATXCTL.EN must be set after all Tx queue config is done */
- dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
- dmatxctl |= IXGBE_DMATXCTL_TE;
- IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
- }
- for (i = 0; i < adapter->num_tx_queues; i++) {
- j = adapter->tx_ring[i]->reg_idx;
- txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
- txdctl |= IXGBE_TXDCTL_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
- if (hw->mac.type == ixgbe_mac_82599EB) {
- int wait_loop = 10;
- /* poll for Tx Enable ready */
- do {
- msleep(1);
- txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
- } while (--wait_loop &&
- !(txdctl & IXGBE_TXDCTL_ENABLE));
- if (!wait_loop)
- e_err(drv, "Could not enable Tx Queue %d\n", j);
- }
- }
+static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int err;
+ u32 ctrl_ext;
- for (i = 0; i < num_rx_rings; i++) {
- j = adapter->rx_ring[i]->reg_idx;
- rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
- /* enable PTHRESH=32 descriptors (half the internal cache)
- * and HTHRESH=0 descriptors (to minimize latency on fetch),
- * this also removes a pesky rx_no_buffer_count increment */
- rxdctl |= 0x0020;
- rxdctl |= IXGBE_RXDCTL_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), rxdctl);
- if (hw->mac.type == ixgbe_mac_82599EB)
- ixgbe_rx_desc_queue_enable(adapter, i);
- }
- /* enable all receives */
- rxdctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
- if (hw->mac.type == ixgbe_mac_82598EB)
- rxdctl |= (IXGBE_RXCTRL_DMBYPS | IXGBE_RXCTRL_RXEN);
- else
- rxdctl |= IXGBE_RXCTRL_RXEN;
- hw->mac.ops.enable_rx_dma(hw, rxdctl);
+ ixgbe_get_hw_control(adapter);
+ ixgbe_setup_gpie(adapter);
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
ixgbe_configure_msix(adapter);
@@ -3483,8 +3561,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* clear any pending interrupts, may auto mask */
IXGBE_READ_REG(hw, IXGBE_EICR);
-
- ixgbe_irq_enable(adapter);
+ ixgbe_irq_enable(adapter, true, true);
/*
* If this adapter has a fan, check to see if we had a failure
@@ -3525,12 +3602,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
e_err(probe, "link_config FAILED %d\n", err);
}
- for (i = 0; i < adapter->num_tx_queues; i++)
- set_bit(__IXGBE_FDIR_INIT_DONE,
- &(adapter->tx_ring[i]->reinit_state));
-
/* enable transmits */
- netif_tx_start_all_queues(netdev);
+ netif_tx_start_all_queues(adapter->netdev);
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
@@ -3609,21 +3682,24 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
* @rx_ring: ring to free buffers from
**/
static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
unsigned long size;
unsigned int i;
- /* Free all the Rx ring sk_buffs */
+ /* ring already cleared, nothing to do */
+ if (!rx_ring->rx_buffer_info)
+ return;
+ /* Free all the Rx ring sk_buffs */
for (i = 0; i < rx_ring->count; i++) {
struct ixgbe_rx_buffer *rx_buffer_info;
rx_buffer_info = &rx_ring->rx_buffer_info[i];
if (rx_buffer_info->dma) {
dma_unmap_single(&pdev->dev, rx_buffer_info->dma,
- rx_ring->rx_buf_len,
+ rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
rx_buffer_info->dma = 0;
}
@@ -3635,7 +3711,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
if (IXGBE_RSC_CB(this)->delay_unmap) {
dma_unmap_single(&pdev->dev,
IXGBE_RSC_CB(this)->dma,
- rx_ring->rx_buf_len,
+ rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
IXGBE_RSC_CB(this)->dma = 0;
IXGBE_RSC_CB(skb)->delay_unmap = false;
@@ -3677,14 +3753,17 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
* @tx_ring: ring to be cleaned
**/
static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct ixgbe_tx_buffer *tx_buffer_info;
unsigned long size;
unsigned int i;
- /* Free all the Tx ring sk_buffs */
+ /* ring already cleared, nothing to do */
+ if (!tx_ring->tx_buffer_info)
+ return;
+ /* Free all the Tx ring sk_buffs */
for (i = 0; i < tx_ring->count; i++) {
tx_buffer_info = &tx_ring->tx_buffer_info[i];
ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info);
@@ -3736,6 +3815,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
u32 rxctrl;
u32 txdctl;
int i, j;
+ 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);
@@ -3774,6 +3854,15 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+ /* 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];
+ /* clear the affinity_mask in the IRQ descriptor */
+ irq_set_affinity_hint(adapter->msix_entries[i]. vector, NULL);
+ /* release the CPU mask memory */
+ 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);
@@ -3786,13 +3875,13 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
j = adapter->tx_ring[i]->reg_idx;
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j),
- (txdctl & ~IXGBE_TXDCTL_ENABLE));
+ (txdctl & ~IXGBE_TXDCTL_ENABLE));
}
/* Disable the Tx DMA engine on 82599 */
if (hw->mac.type == ixgbe_mac_82599EB)
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
- (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
- ~IXGBE_DMATXCTL_TE));
+ (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
+ ~IXGBE_DMATXCTL_TE));
/* power down the optics */
if (hw->phy.multispeed_fiber)
@@ -3822,7 +3911,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
static int ixgbe_poll(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
- container_of(napi, struct ixgbe_q_vector, napi);
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
int tx_clean_complete, work_done = 0;
@@ -3932,7 +4021,7 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
* Rx load across CPUs using RSS.
*
**/
-static bool inline ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter)
+static inline bool ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter)
{
bool ret = false;
struct ixgbe_ring_feature *f_fdir = &adapter->ring_feature[RING_F_FDIR];
@@ -4024,7 +4113,7 @@ static inline bool ixgbe_set_sriov_queues(struct ixgbe_adapter *adapter)
* fallthrough conditions.
*
**/
-static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+static int ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
{
/* Start with base case */
adapter->num_rx_queues = 1;
@@ -4033,7 +4122,7 @@ static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
adapter->num_rx_queues_per_pool = 1;
if (ixgbe_set_sriov_queues(adapter))
- return;
+ goto done;
#ifdef IXGBE_FCOE
if (ixgbe_set_fcoe_queues(adapter))
@@ -4056,12 +4145,14 @@ static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
adapter->num_tx_queues = 1;
done:
- /* Notify the stack of the (possibly) reduced Tx Queue count. */
+ /* Notify the stack of the (possibly) reduced queue counts. */
netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
+ return netif_set_real_num_rx_queues(adapter->netdev,
+ adapter->num_rx_queues);
}
static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
- int vectors)
+ int vectors)
{
int err, vector_threshold;
@@ -4080,7 +4171,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
*/
while (vectors >= vector_threshold) {
err = pci_enable_msix(adapter->pdev, adapter->msix_entries,
- vectors);
+ vectors);
if (!err) /* Success in acquiring all requested vectors. */
break;
else if (err < 0)
@@ -4107,7 +4198,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
* vectors we were allocated.
*/
adapter->num_msix_vectors = min(vectors,
- adapter->max_msix_q_vectors + NON_Q_VECTORS);
+ adapter->max_msix_q_vectors + NON_Q_VECTORS);
}
}
@@ -4178,12 +4269,12 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
}
for ( ; i < 5; i++) {
adapter->tx_ring[i]->reg_idx =
- ((i + 2) << 4);
+ ((i + 2) << 4);
adapter->rx_ring[i]->reg_idx = i << 4;
}
for ( ; i < dcb_i; i++) {
adapter->tx_ring[i]->reg_idx =
- ((i + 8) << 3);
+ ((i + 8) << 3);
adapter->rx_ring[i]->reg_idx = i << 4;
}
@@ -4226,7 +4317,7 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
* Cache the descriptor ring offsets for Flow Director to the assigned rings.
*
**/
-static bool inline ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter)
+static inline bool ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter)
{
int i;
bool ret = false;
@@ -4383,7 +4474,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
adapter->node = cur_node;
}
ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL,
- adapter->node);
+ adapter->node);
if (!ring)
ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL);
if (!ring)
@@ -4407,7 +4498,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
adapter->node = cur_node;
}
ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL,
- adapter->node);
+ adapter->node);
if (!ring)
ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL);
if (!ring)
@@ -4453,7 +4544,7 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
* (roughly) the same number of vectors as there are CPU's.
*/
v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
- (int)num_online_cpus()) + NON_Q_VECTORS;
+ (int)num_online_cpus()) + NON_Q_VECTORS;
/*
* At the same time, hardware can only support a maximum of
@@ -4467,7 +4558,7 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
/* A failure in MSI-X entry allocation isn't fatal, but it does
* mean we disable MSI-X capabilities of the adapter. */
adapter->msix_entries = kcalloc(v_budget,
- sizeof(struct msix_entry), GFP_KERNEL);
+ sizeof(struct msix_entry), GFP_KERNEL);
if (adapter->msix_entries) {
for (vector = 0; vector < v_budget; vector++)
adapter->msix_entries[vector].entry = vector;
@@ -4486,7 +4577,9 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
ixgbe_disable_sriov(adapter);
- ixgbe_set_num_queues(adapter);
+ err = ixgbe_set_num_queues(adapter);
+ if (err)
+ return err;
err = pci_enable_msi(adapter->pdev);
if (!err) {
@@ -4529,10 +4622,10 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter)
for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
q_vector = kzalloc_node(sizeof(struct ixgbe_q_vector),
- GFP_KERNEL, adapter->node);
+ GFP_KERNEL, adapter->node);
if (!q_vector)
q_vector = kzalloc(sizeof(struct ixgbe_q_vector),
- GFP_KERNEL);
+ GFP_KERNEL);
if (!q_vector)
goto err_out;
q_vector->adapter = adapter;
@@ -4611,7 +4704,9 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
int err;
/* Number of supported queues */
- ixgbe_set_num_queues(adapter);
+ err = ixgbe_set_num_queues(adapter);
+ if (err)
+ return err;
err = ixgbe_set_interrupt_capability(adapter);
if (err) {
@@ -4693,8 +4788,8 @@ static void ixgbe_sfp_timer(unsigned long data)
static void ixgbe_sfp_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- sfp_task);
+ struct ixgbe_adapter,
+ sfp_task);
struct ixgbe_hw *hw = &adapter->hw;
if ((hw->phy.type == ixgbe_phy_nl) &&
@@ -4719,7 +4814,7 @@ static void ixgbe_sfp_task(struct work_struct *work)
reschedule:
if (test_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state))
mod_timer(&adapter->sfp_timer,
- round_jiffies(jiffies + (2 * HZ)));
+ round_jiffies(jiffies + (2 * HZ)));
}
/**
@@ -4775,7 +4870,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->atr_sample_rate = 20;
}
adapter->ring_feature[RING_F_FDIR].indices =
- IXGBE_MAX_FDIR_INDICES;
+ IXGBE_MAX_FDIR_INDICES;
adapter->fdir_pballoc = 0;
#ifdef IXGBE_FCOE
adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE;
@@ -4806,7 +4901,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->dcb_cfg.round_robin_enable = false;
adapter->dcb_set_bitmap = 0x00;
ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg,
- adapter->ring_feature[RING_F_DCB].indices);
+ adapter->ring_feature[RING_F_DCB].indices);
#endif
@@ -4861,7 +4956,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
* Return 0 on success, negative on failure
**/
int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct pci_dev *pdev = adapter->pdev;
int size;
@@ -4928,7 +5023,7 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
* Returns 0 on success, negative on failure
**/
int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
int size;
@@ -5001,7 +5096,7 @@ static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
* Free all transmit software resources
**/
void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct pci_dev *pdev = adapter->pdev;
@@ -5039,7 +5134,7 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter)
* Free all receive software resources
**/
void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
@@ -5333,6 +5428,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
u64 total_mpc = 0;
u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
u64 non_eop_descs = 0, restart_queue = 0;
+ struct ixgbe_hw_stats *hwstats = &adapter->stats;
if (test_bit(__IXGBE_DOWN, &adapter->state) ||
test_bit(__IXGBE_RESETTING, &adapter->state))
@@ -5343,7 +5439,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
u64 rsc_flush = 0;
for (i = 0; i < 16; i++)
adapter->hw_rx_no_dma_resources +=
- IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+ IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
for (i = 0; i < adapter->num_rx_queues; i++) {
rsc_count += adapter->rx_ring[i]->rsc_count;
rsc_flush += adapter->rx_ring[i]->rsc_flush;
@@ -5361,119 +5457,118 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
non_eop_descs += adapter->rx_ring[i]->non_eop_descs;
adapter->non_eop_descs = non_eop_descs;
- adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
+ hwstats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
for (i = 0; i < 8; i++) {
/* for packet buffers not used, the register should read 0 */
mpc = IXGBE_READ_REG(hw, IXGBE_MPC(i));
missed_rx += mpc;
- adapter->stats.mpc[i] += mpc;
- total_mpc += adapter->stats.mpc[i];
+ hwstats->mpc[i] += mpc;
+ total_mpc += hwstats->mpc[i];
if (hw->mac.type == ixgbe_mac_82598EB)
- adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
- adapter->stats.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
- adapter->stats.qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
- adapter->stats.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
- adapter->stats.qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
+ hwstats->rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
+ hwstats->qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
+ hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+ hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
+ hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
if (hw->mac.type == ixgbe_mac_82599EB) {
- adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXONRXCNT(i));
- adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXOFFRXCNT(i));
- adapter->stats.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+ hwstats->pxonrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
+ hwstats->pxoffrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
+ hwstats->qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
} else {
- adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXONRXC(i));
- adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXOFFRXC(i));
+ hwstats->pxonrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
+ hwstats->pxoffrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
}
- adapter->stats.pxontxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXONTXC(i));
- adapter->stats.pxofftxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXOFFTXC(i));
+ hwstats->pxontxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
+ hwstats->pxofftxc[i] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
}
- adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
+ hwstats->gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
/* work around hardware counting issue */
- adapter->stats.gprc -= missed_rx;
+ hwstats->gprc -= missed_rx;
/* 82598 hardware only has a 32 bit counter in the high register */
if (hw->mac.type == ixgbe_mac_82599EB) {
u64 tmp;
- adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
- tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; /* 4 high bits of GORC */
- adapter->stats.gorc += (tmp << 32);
- adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
- tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; /* 4 high bits of GOTC */
- adapter->stats.gotc += (tmp << 32);
- adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL);
- IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
- adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
- adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
- adapter->stats.fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
- adapter->stats.fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
+ hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
+ tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF;
+ /* 4 high bits of GORC */
+ hwstats->gorc += (tmp << 32);
+ hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
+ tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF;
+ /* 4 high bits of GOTC */
+ hwstats->gotc += (tmp << 32);
+ hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORL);
+ IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
+ hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
+ hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
+ hwstats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
+ hwstats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
#ifdef IXGBE_FCOE
- adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
- adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
- adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
- adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);
- adapter->stats.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
- adapter->stats.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
+ hwstats->fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
+ hwstats->fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
+ hwstats->fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
+ hwstats->fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);
+ hwstats->fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
+ hwstats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
#endif /* IXGBE_FCOE */
} else {
- adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
- adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
- adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
- adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
- adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH);
+ hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
+ hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
+ hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
+ hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
+ hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH);
}
bprc = IXGBE_READ_REG(hw, IXGBE_BPRC);
- adapter->stats.bprc += bprc;
- adapter->stats.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC);
+ hwstats->bprc += bprc;
+ hwstats->mprc += IXGBE_READ_REG(hw, IXGBE_MPRC);
if (hw->mac.type == ixgbe_mac_82598EB)
- adapter->stats.mprc -= bprc;
- adapter->stats.roc += IXGBE_READ_REG(hw, IXGBE_ROC);
- adapter->stats.prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64);
- adapter->stats.prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127);
- adapter->stats.prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255);
- adapter->stats.prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511);
- adapter->stats.prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023);
- adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522);
- adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
+ hwstats->mprc -= bprc;
+ hwstats->roc += IXGBE_READ_REG(hw, IXGBE_ROC);
+ hwstats->prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64);
+ hwstats->prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127);
+ hwstats->prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255);
+ hwstats->prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511);
+ hwstats->prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023);
+ hwstats->prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522);
+ hwstats->rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC);
- adapter->stats.lxontxc += lxon;
+ hwstats->lxontxc += lxon;
lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
- adapter->stats.lxofftxc += lxoff;
- adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
- adapter->stats.gptc += IXGBE_READ_REG(hw, IXGBE_GPTC);
- adapter->stats.mptc += IXGBE_READ_REG(hw, IXGBE_MPTC);
+ hwstats->lxofftxc += lxoff;
+ hwstats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
+ hwstats->gptc += IXGBE_READ_REG(hw, IXGBE_GPTC);
+ hwstats->mptc += IXGBE_READ_REG(hw, IXGBE_MPTC);
/*
* 82598 errata - tx of flow control packets is included in tx counters
*/
xon_off_tot = lxon + lxoff;
- adapter->stats.gptc -= xon_off_tot;
- adapter->stats.mptc -= xon_off_tot;
- adapter->stats.gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN));
- adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
- adapter->stats.rfc += IXGBE_READ_REG(hw, IXGBE_RFC);
- adapter->stats.rjc += IXGBE_READ_REG(hw, IXGBE_RJC);
- adapter->stats.tpr += IXGBE_READ_REG(hw, IXGBE_TPR);
- adapter->stats.ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64);
- adapter->stats.ptc64 -= xon_off_tot;
- adapter->stats.ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127);
- adapter->stats.ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255);
- adapter->stats.ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511);
- adapter->stats.ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023);
- adapter->stats.ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522);
- adapter->stats.bptc += IXGBE_READ_REG(hw, IXGBE_BPTC);
+ hwstats->gptc -= xon_off_tot;
+ hwstats->mptc -= xon_off_tot;
+ hwstats->gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN));
+ hwstats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
+ hwstats->rfc += IXGBE_READ_REG(hw, IXGBE_RFC);
+ hwstats->rjc += IXGBE_READ_REG(hw, IXGBE_RJC);
+ hwstats->tpr += IXGBE_READ_REG(hw, IXGBE_TPR);
+ hwstats->ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64);
+ hwstats->ptc64 -= xon_off_tot;
+ hwstats->ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127);
+ hwstats->ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255);
+ hwstats->ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511);
+ hwstats->ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023);
+ hwstats->ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522);
+ hwstats->bptc += IXGBE_READ_REG(hw, IXGBE_BPTC);
/* Fill out the OS statistics structure */
- netdev->stats.multicast = adapter->stats.mprc;
+ netdev->stats.multicast = hwstats->mprc;
/* Rx Errors */
- netdev->stats.rx_errors = adapter->stats.crcerrs +
- adapter->stats.rlec;
+ netdev->stats.rx_errors = hwstats->crcerrs + hwstats->rlec;
netdev->stats.rx_dropped = 0;
- netdev->stats.rx_length_errors = adapter->stats.rlec;
- netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
+ netdev->stats.rx_length_errors = hwstats->rlec;
+ netdev->stats.rx_crc_errors = hwstats->crcerrs;
netdev->stats.rx_missed_errors = total_mpc;
}
@@ -5532,8 +5627,8 @@ watchdog_short_circuit:
static void ixgbe_multispeed_fiber_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- multispeed_fiber_task);
+ struct ixgbe_adapter,
+ multispeed_fiber_task);
struct ixgbe_hw *hw = &adapter->hw;
u32 autoneg;
bool negotiation;
@@ -5556,8 +5651,8 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work)
static void ixgbe_sfp_config_module_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- sfp_config_module_task);
+ struct ixgbe_adapter,
+ sfp_config_module_task);
struct ixgbe_hw *hw = &adapter->hw;
u32 err;
@@ -5590,15 +5685,15 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work)
static void ixgbe_fdir_reinit_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- fdir_reinit_task);
+ struct ixgbe_adapter,
+ fdir_reinit_task);
struct ixgbe_hw *hw = &adapter->hw;
int i;
if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
for (i = 0; i < adapter->num_tx_queues; i++)
set_bit(__IXGBE_FDIR_INIT_DONE,
- &(adapter->tx_ring[i]->reinit_state));
+ &(adapter->tx_ring[i]->reinit_state));
} else {
e_err(probe, "failed to finish FDIR re-initialization, "
"ignored adding FDIR ATR filters\n");
@@ -5616,8 +5711,8 @@ static DEFINE_MUTEX(ixgbe_watchdog_lock);
static void ixgbe_watchdog_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- watchdog_task);
+ struct ixgbe_adapter,
+ watchdog_task);
struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
u32 link_speed;
@@ -5648,7 +5743,7 @@ static void ixgbe_watchdog_task(struct work_struct *work)
if (link_up ||
time_after(jiffies, (adapter->link_check_timeout +
- IXGBE_TRY_LINK_TIMEOUT))) {
+ IXGBE_TRY_LINK_TIMEOUT))) {
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
}
@@ -5719,8 +5814,8 @@ static void ixgbe_watchdog_task(struct work_struct *work)
}
static int ixgbe_tso(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring, struct sk_buff *skb,
- u32 tx_flags, u8 *hdr_len)
+ struct ixgbe_ring *tx_ring, struct sk_buff *skb,
+ u32 tx_flags, u8 *hdr_len)
{
struct ixgbe_adv_tx_context_desc *context_desc;
unsigned int i;
@@ -5743,28 +5838,28 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
iph->tot_len = 0;
iph->check = 0;
tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
- iph->daddr, 0,
- IPPROTO_TCP,
- 0);
+ iph->daddr, 0,
+ IPPROTO_TCP,
+ 0);
} else if (skb_is_gso_v6(skb)) {
ipv6_hdr(skb)->payload_len = 0;
tcp_hdr(skb)->check =
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
- &ipv6_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0);
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
}
i = tx_ring->next_to_use;
tx_buffer_info = &tx_ring->tx_buffer_info[i];
- context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i);
+ context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i);
/* VLAN MACLEN IPLEN */
if (tx_flags & IXGBE_TX_FLAGS_VLAN)
vlan_macip_lens |=
(tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
vlan_macip_lens |= ((skb_network_offset(skb)) <<
- IXGBE_ADVTXD_MACLEN_SHIFT);
+ IXGBE_ADVTXD_MACLEN_SHIFT);
*hdr_len += skb_network_offset(skb);
vlan_macip_lens |=
(skb_transport_header(skb) - skb_network_header(skb));
@@ -5775,7 +5870,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT |
- IXGBE_ADVTXD_DTYP_CTXT);
+ IXGBE_ADVTXD_DTYP_CTXT);
if (skb->protocol == htons(ETH_P_IP))
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
@@ -5803,9 +5898,53 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
return false;
}
+static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb)
+{
+ u32 rtn = 0;
+ __be16 protocol;
+
+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
+ protocol = ((const struct vlan_ethhdr *)skb->data)->
+ h_vlan_encapsulated_proto;
+ else
+ protocol = skb->protocol;
+
+ switch (protocol) {
+ case cpu_to_be16(ETH_P_IP):
+ rtn |= IXGBE_ADVTXD_TUCMD_IPV4;
+ switch (ip_hdr(skb)->protocol) {
+ case IPPROTO_TCP:
+ rtn |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ break;
+ case IPPROTO_SCTP:
+ rtn |= IXGBE_ADVTXD_TUCMD_L4T_SCTP;
+ break;
+ }
+ break;
+ case cpu_to_be16(ETH_P_IPV6):
+ /* XXX what about other V6 headers?? */
+ switch (ipv6_hdr(skb)->nexthdr) {
+ case IPPROTO_TCP:
+ rtn |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ break;
+ case IPPROTO_SCTP:
+ rtn |= IXGBE_ADVTXD_TUCMD_L4T_SCTP;
+ break;
+ }
+ break;
+ default:
+ if (unlikely(net_ratelimit()))
+ e_warn(probe, "partial checksum but proto=%x!\n",
+ skb->protocol);
+ break;
+ }
+
+ return rtn;
+}
+
static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- struct sk_buff *skb, u32 tx_flags)
+ struct ixgbe_ring *tx_ring,
+ struct sk_buff *skb, u32 tx_flags)
{
struct ixgbe_adv_tx_context_desc *context_desc;
unsigned int i;
@@ -5816,63 +5955,25 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
(tx_flags & IXGBE_TX_FLAGS_VLAN)) {
i = tx_ring->next_to_use;
tx_buffer_info = &tx_ring->tx_buffer_info[i];
- context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i);
+ context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i);
if (tx_flags & IXGBE_TX_FLAGS_VLAN)
vlan_macip_lens |=
(tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
vlan_macip_lens |= (skb_network_offset(skb) <<
- IXGBE_ADVTXD_MACLEN_SHIFT);
+ IXGBE_ADVTXD_MACLEN_SHIFT);
if (skb->ip_summed == CHECKSUM_PARTIAL)
vlan_macip_lens |= (skb_transport_header(skb) -
- skb_network_header(skb));
+ skb_network_header(skb));
context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
context_desc->seqnum_seed = 0;
type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT |
- IXGBE_ADVTXD_DTYP_CTXT);
-
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- __be16 protocol;
-
- if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
- const struct vlan_ethhdr *vhdr =
- (const struct vlan_ethhdr *)skb->data;
-
- protocol = vhdr->h_vlan_encapsulated_proto;
- } else {
- protocol = skb->protocol;
- }
+ IXGBE_ADVTXD_DTYP_CTXT);
- switch (protocol) {
- case cpu_to_be16(ETH_P_IP):
- type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
- if (ip_hdr(skb)->protocol == IPPROTO_TCP)
- type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_TCP;
- else if (ip_hdr(skb)->protocol == IPPROTO_SCTP)
- type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_SCTP;
- break;
- case cpu_to_be16(ETH_P_IPV6):
- /* XXX what about other V6 headers?? */
- if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
- type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_TCP;
- else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP)
- type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_SCTP;
- break;
- default:
- if (unlikely(net_ratelimit())) {
- e_warn(probe, "partial checksum "
- "but proto=%x!\n",
- skb->protocol);
- }
- break;
- }
- }
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ type_tucmd_mlhl |= ixgbe_psum(adapter, skb);
context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
/* use index zero for tx checksum offload */
@@ -5893,9 +5994,9 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
}
static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- struct sk_buff *skb, u32 tx_flags,
- unsigned int first)
+ struct ixgbe_ring *tx_ring,
+ struct sk_buff *skb, u32 tx_flags,
+ unsigned int first)
{
struct pci_dev *pdev = adapter->pdev;
struct ixgbe_tx_buffer *tx_buffer_info;
@@ -5990,7 +6091,7 @@ dma_error:
/* clear timestamp and dma mappings for remaining portion of packet */
while (count--) {
- if (i==0)
+ if (i == 0)
i += tx_ring->count;
i--;
tx_buffer_info = &tx_ring->tx_buffer_info[i];
@@ -6001,8 +6102,8 @@ dma_error:
}
static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- int tx_flags, int count, u32 paylen, u8 hdr_len)
+ struct ixgbe_ring *tx_ring,
+ int tx_flags, int count, u32 paylen, u8 hdr_len)
{
union ixgbe_adv_tx_desc *tx_desc = NULL;
struct ixgbe_tx_buffer *tx_buffer_info;
@@ -6021,17 +6122,17 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
/* use index 1 context for tso */
olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
if (tx_flags & IXGBE_TX_FLAGS_IPV4)
olinfo_status |= IXGBE_TXD_POPTS_IXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
} else if (tx_flags & IXGBE_TX_FLAGS_CSUM)
olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
if (tx_flags & IXGBE_TX_FLAGS_FCOE) {
olinfo_status |= IXGBE_ADVTXD_CC;
@@ -6045,10 +6146,10 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
i = tx_ring->next_to_use;
while (count--) {
tx_buffer_info = &tx_ring->tx_buffer_info[i];
- tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
+ tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma);
tx_desc->read.cmd_type_len =
- cpu_to_le32(cmd_type_len | tx_buffer_info->length);
+ cpu_to_le32(cmd_type_len | tx_buffer_info->length);
tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
i++;
if (i == tx_ring->count)
@@ -6070,7 +6171,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
}
static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
- int queue, u32 tx_flags)
+ int queue, u32 tx_flags)
{
struct ixgbe_atr_input atr_input;
struct tcphdr *th;
@@ -6098,7 +6199,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
memset(&atr_input, 0, sizeof(struct ixgbe_atr_input));
vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >>
- IXGBE_TX_FLAGS_VLAN_SHIFT;
+ IXGBE_TX_FLAGS_VLAN_SHIFT;
src_ipv4_addr = iph->saddr;
dst_ipv4_addr = iph->daddr;
flex_bytes = eth->h_proto;
@@ -6117,7 +6218,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
}
static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
- struct ixgbe_ring *tx_ring, int size)
+ struct ixgbe_ring *tx_ring, int size)
{
netif_stop_subqueue(netdev, tx_ring->queue_index);
/* Herbert's original patch had:
@@ -6137,7 +6238,7 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
}
static int ixgbe_maybe_stop_tx(struct net_device *netdev,
- struct ixgbe_ring *tx_ring, int size)
+ struct ixgbe_ring *tx_ring, int size)
{
if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size))
return 0;
@@ -6183,11 +6284,10 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
return skb_tx_hash(dev, skb);
}
-static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
- struct net_device *netdev)
+netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev,
+ struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *tx_ring)
{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_ring *tx_ring;
struct netdev_queue *txq;
unsigned int first;
unsigned int tx_flags = 0;
@@ -6196,7 +6296,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
int count = 0;
unsigned int f;
- if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
tx_flags |= vlan_tx_tag_get(skb);
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK;
@@ -6211,8 +6311,6 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
tx_flags |= IXGBE_TX_FLAGS_VLAN;
}
- tx_ring = adapter->tx_ring[skb->queue_mapping];
-
#ifdef IXGBE_FCOE
/* for FCoE with DCB, we force the priority to what
* was specified by the switch */
@@ -6283,10 +6381,10 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
if (tx_ring->atr_sample_rate) {
++tx_ring->atr_count;
if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) &&
- test_bit(__IXGBE_FDIR_INIT_DONE,
- &tx_ring->reinit_state)) {
+ test_bit(__IXGBE_FDIR_INIT_DONE,
+ &tx_ring->reinit_state)) {
ixgbe_atr(adapter, skb, tx_ring->queue_index,
- tx_flags);
+ tx_flags);
tx_ring->atr_count = 0;
}
}
@@ -6294,7 +6392,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
txq->tx_bytes += skb->len;
txq->tx_packets++;
ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len,
- hdr_len);
+ hdr_len);
ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
} else {
@@ -6306,6 +6404,15 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
return NETDEV_TX_OK;
}
+static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_ring *tx_ring;
+
+ tx_ring = adapter->tx_ring[skb->queue_mapping];
+ return ixgbe_xmit_frame_ring(skb, netdev, adapter, tx_ring);
+}
+
/**
* ixgbe_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
@@ -6436,8 +6543,40 @@ static void ixgbe_netpoll(struct net_device *netdev)
}
#endif
+static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev,
+ struct rtnl_link_stats64 *stats)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ int i;
+
+ /* accurate rx/tx bytes/packets stats */
+ dev_txq_stats_fold(netdev, stats);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ struct ixgbe_ring *ring = adapter->rx_ring[i];
+ u64 bytes, packets;
+ unsigned int start;
+
+ do {
+ start = u64_stats_fetch_begin_bh(&ring->syncp);
+ packets = ring->stats.packets;
+ bytes = ring->stats.bytes;
+ } while (u64_stats_fetch_retry_bh(&ring->syncp, start));
+ stats->rx_packets += packets;
+ stats->rx_bytes += bytes;
+ }
+
+ /* following stats updated by ixgbe_watchdog_task() */
+ stats->multicast = netdev->stats.multicast;
+ stats->rx_errors = netdev->stats.rx_errors;
+ stats->rx_length_errors = netdev->stats.rx_length_errors;
+ stats->rx_crc_errors = netdev->stats.rx_crc_errors;
+ stats->rx_missed_errors = netdev->stats.rx_missed_errors;
+ return stats;
+}
+
+
static const struct net_device_ops ixgbe_netdev_ops = {
- .ndo_open = ixgbe_open,
+ .ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close,
.ndo_start_xmit = ixgbe_xmit_frame,
.ndo_select_queue = ixgbe_select_queue,
@@ -6447,7 +6586,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_set_mac_address = ixgbe_set_mac,
.ndo_change_mtu = ixgbe_change_mtu,
.ndo_tx_timeout = ixgbe_tx_timeout,
- .ndo_vlan_rx_register = ixgbe_vlan_rx_register,
.ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid,
.ndo_do_ioctl = ixgbe_ioctl,
@@ -6455,6 +6593,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan,
.ndo_set_vf_tx_rate = ixgbe_ndo_set_vf_bw,
.ndo_get_vf_config = ixgbe_ndo_get_vf_config,
+ .ndo_get_stats64 = ixgbe_get_stats64,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ixgbe_netpoll,
#endif
@@ -6532,7 +6671,7 @@ err_novfs:
* and a hardware reset occur.
**/
static int __devinit ixgbe_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *ent)
{
struct net_device *netdev;
struct ixgbe_adapter *adapter = NULL;
@@ -6577,7 +6716,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
}
err = pci_request_selected_regions(pdev, pci_select_bars(pdev,
- IORESOURCE_MEM), ixgbe_driver_name);
+ IORESOURCE_MEM), ixgbe_driver_name);
if (err) {
dev_err(&pdev->dev,
"pci_request_selected_regions failed 0x%x\n", err);
@@ -6617,7 +6756,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
+ pci_resource_len(pdev, 0));
if (!hw->hw_addr) {
err = -EIO;
goto err_ioremap;
@@ -6661,7 +6800,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
* which might start the timer
*/
init_timer(&adapter->sfp_timer);
- adapter->sfp_timer.function = &ixgbe_sfp_timer;
+ adapter->sfp_timer.function = ixgbe_sfp_timer;
adapter->sfp_timer.data = (unsigned long) adapter;
INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task);
@@ -6671,7 +6810,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* a new SFP+ module arrival, called from GPI SDP2 context */
INIT_WORK(&adapter->sfp_config_module_task,
- ixgbe_sfp_config_module_task);
+ ixgbe_sfp_config_module_task);
ii->get_invariants(hw);
@@ -6723,10 +6862,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
ixgbe_probe_vf(adapter, ii);
netdev->features = NETIF_F_SG |
- NETIF_F_IP_CSUM |
- NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER;
+ NETIF_F_IP_CSUM |
+ NETIF_F_HW_VLAN_TX |
+ NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER;
netdev->features |= NETIF_F_IPV6_CSUM;
netdev->features |= NETIF_F_TSO;
@@ -6766,8 +6905,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->vlan_features |= NETIF_F_FCOE_MTU;
}
#endif /* IXGBE_FCOE */
- if (pci_using_dac)
+ if (pci_using_dac) {
netdev->features |= NETIF_F_HIGHDMA;
+ netdev->vlan_features |= NETIF_F_HIGHDMA;
+ }
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
netdev->features |= NETIF_F_LRO;
@@ -6793,7 +6934,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->mac.ops.disable_tx_laser(hw);
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &ixgbe_watchdog;
+ adapter->watchdog_timer.function = ixgbe_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->reset_task, ixgbe_reset_task);
@@ -6806,7 +6947,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
switch (pdev->device) {
case IXGBE_DEV_ID_82599_KX4:
adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
- IXGBE_WUFC_MC | IXGBE_WUFC_BC);
+ IXGBE_WUFC_MC | IXGBE_WUFC_BC);
break;
default:
adapter->wol = 0;
@@ -6819,13 +6960,14 @@ 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":"Unknown"),
- ((hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" :
- (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" :
- (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" :
- "Unknown"),
- netdev->dev_addr);
+ (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0Gb/s" :
+ hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5Gb/s" :
+ "Unknown"),
+ (hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" :
+ hw->bus.width == ixgbe_bus_width_pcie_x4 ? "Width x4" :
+ hw->bus.width == ixgbe_bus_width_pcie_x1 ? "Width x1" :
+ "Unknown"),
+ netdev->dev_addr);
ixgbe_read_pba_num_generic(hw, &part_num);
if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present)
e_dev_info("MAC: %d, PHY: %d, SFP+: %d, "
@@ -6872,7 +7014,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
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);
+ 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;
@@ -6908,8 +7051,8 @@ err_eeprom:
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
- pci_release_selected_regions(pdev, pci_select_bars(pdev,
- IORESOURCE_MEM));
+ pci_release_selected_regions(pdev,
+ pci_select_bars(pdev, IORESOURCE_MEM));
err_pci_reg:
err_dma:
pci_disable_device(pdev);
@@ -6976,7 +7119,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
iounmap(adapter->hw.hw_addr);
pci_release_selected_regions(pdev, pci_select_bars(pdev,
- IORESOURCE_MEM));
+ IORESOURCE_MEM));
e_dev_info("complete\n");
@@ -6996,7 +7139,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
* this device has been detected.
*/
static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
+ pci_channel_state_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -7102,8 +7245,7 @@ static struct pci_driver ixgbe_driver = {
static int __init ixgbe_init_module(void)
{
int ret;
- pr_info("%s - version %s\n", ixgbe_driver_string,
- ixgbe_driver_version);
+ pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version);
pr_info("%s\n", ixgbe_copyright);
#ifdef CONFIG_IXGBE_DCA
@@ -7132,12 +7274,12 @@ static void __exit ixgbe_exit_module(void)
#ifdef CONFIG_IXGBE_DCA
static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
- void *p)
+ void *p)
{
int ret_val;
ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event,
- __ixgbe_notify_dca);
+ __ixgbe_notify_dca);
return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
}
diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c
index d75f9148eb1f..471f0f2cdb98 100644
--- a/drivers/net/ixgbe/ixgbe_mbx.c
+++ b/drivers/net/ixgbe/ixgbe_mbx.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -200,7 +200,8 @@ out:
* returns SUCCESS if it successfully received a message notification and
* copied it into the receive buffer.
**/
-s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
+ u16 mbx_id)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
s32 ret_val = IXGBE_ERR_MBX;
@@ -227,7 +228,7 @@ out:
* returns SUCCESS if it successfully copied message into the buffer and
* received an ack to that message within delay * timeout period
**/
-s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
+static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
u16 mbx_id)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
@@ -247,20 +248,6 @@ out:
return ret_val;
}
-/**
- * ixgbe_init_mbx_ops_generic - Initialize MB function pointers
- * @hw: pointer to the HW structure
- *
- * Setup the mailbox read and write message function pointers
- **/
-void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
-{
- struct ixgbe_mbx_info *mbx = &hw->mbx;
-
- mbx->ops.read_posted = ixgbe_read_posted_mbx;
- mbx->ops.write_posted = ixgbe_write_posted_mbx;
-}
-
static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
{
u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h
index be7ab3309ab7..7e0d08ff5b53 100644
--- a/drivers/net/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ixgbe/ixgbe_mbx.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -83,12 +83,9 @@
s32 ixgbe_read_mbx(struct ixgbe_hw *, u32 *, u16, u16);
s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16);
-s32 ixgbe_read_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16);
-s32 ixgbe_write_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16);
s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16);
s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16);
s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16);
-void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw);
void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);
extern struct ixgbe_mbx_operations mbx_ops_82599;
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c
index 49661a138e22..5428153af8f3 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ixgbe/ixgbe_sriov.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -43,8 +43,8 @@
#include "ixgbe_sriov.h"
-int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
- int entries, u16 *hash_list, u32 vf)
+static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
+ int entries, u16 *hash_list, u32 vf)
{
struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
struct ixgbe_hw *hw = &adapter->hw;
@@ -104,13 +104,14 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
}
}
-int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf)
+static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
+ u32 vf)
{
return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
}
-void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe)
+static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe)
{
u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
vmolr |= (IXGBE_VMOLR_ROMPE |
@@ -134,7 +135,7 @@ static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, u32 vid, u32 vf)
IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0);
}
-inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
+static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
{
struct ixgbe_hw *hw = &adapter->hw;
int rar_entry = hw->mac.num_rar_entries - (vf + 1);
@@ -162,8 +163,8 @@ inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
hw->mac.ops.clear_rar(hw, rar_entry);
}
-int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
- int vf, unsigned char *mac_addr)
+static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
+ int vf, unsigned char *mac_addr)
{
struct ixgbe_hw *hw = &adapter->hw;
int rar_entry = hw->mac.num_rar_entries - (vf + 1);
@@ -197,7 +198,7 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
return 0;
}
-inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
+static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 reg;
diff --git a/drivers/net/ixgbe/ixgbe_sriov.h b/drivers/net/ixgbe/ixgbe_sriov.h
index 184730ecdfb6..49dc14debef7 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ixgbe/ixgbe_sriov.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2009 Intel Corporation.
+ Copyright(c) 1999 - 2010 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -28,16 +28,8 @@
#ifndef _IXGBE_SRIOV_H_
#define _IXGBE_SRIOV_H_
-int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
- int entries, u16 *hash_list, u32 vf);
void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter);
-int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf);
-void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe);
-void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf);
-void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf);
void ixgbe_msg_task(struct ixgbe_adapter *adapter);
-int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
- int vf, unsigned char *mac_addr);
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter);
void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 9587d975d66c..d3cc6ce7c973 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -871,6 +871,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_RSCACKC 0x02000000 /* must set 1 when RSC enabled */
+#define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC enabled */
/* RQTC Bit Masks and Shifts */
#define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4)
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c
index 4680b069b84f..4cc817acfb62 100644
--- a/drivers/net/ixgbevf/ethtool.c
+++ b/drivers/net/ixgbevf/ethtool.c
@@ -330,10 +330,8 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
{
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL;
- int i, err;
+ int i, err = 0;
u32 new_rx_count, new_tx_count;
- bool need_tx_update = false;
- bool need_rx_update = false;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
@@ -355,89 +353,96 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state))
msleep(1);
- if (new_tx_count != adapter->tx_ring_count) {
- tx_ring = kcalloc(adapter->num_tx_queues,
- sizeof(struct ixgbevf_ring), GFP_KERNEL);
- if (!tx_ring) {
- err = -ENOMEM;
- goto err_setup;
- }
- memcpy(tx_ring, adapter->tx_ring,
- adapter->num_tx_queues * sizeof(struct ixgbevf_ring));
- for (i = 0; i < adapter->num_tx_queues; i++) {
- tx_ring[i].count = new_tx_count;
- err = ixgbevf_setup_tx_resources(adapter,
- &tx_ring[i]);
- if (err) {
- while (i) {
- i--;
- ixgbevf_free_tx_resources(adapter,
- &tx_ring[i]);
- }
- kfree(tx_ring);
- goto err_setup;
- }
- tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
- }
- need_tx_update = true;
+ /*
+ * If the adapter isn't up and running then just set the
+ * new parameters and scurry for the exits.
+ */
+ if (!netif_running(adapter->netdev)) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_ring[i].count = new_tx_count;
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i].count = new_rx_count;
+ adapter->tx_ring_count = new_tx_count;
+ adapter->rx_ring_count = new_rx_count;
+ goto clear_reset;
}
- if (new_rx_count != adapter->rx_ring_count) {
- rx_ring = kcalloc(adapter->num_rx_queues,
- sizeof(struct ixgbevf_ring), GFP_KERNEL);
- if ((!rx_ring) && (need_tx_update)) {
- err = -ENOMEM;
- goto err_rx_setup;
- }
- memcpy(rx_ring, adapter->rx_ring,
- adapter->num_rx_queues * sizeof(struct ixgbevf_ring));
- for (i = 0; i < adapter->num_rx_queues; i++) {
- rx_ring[i].count = new_rx_count;
- err = ixgbevf_setup_rx_resources(adapter,
- &rx_ring[i]);
- if (err) {
- while (i) {
- i--;
- ixgbevf_free_rx_resources(adapter,
- &rx_ring[i]);
- }
- kfree(rx_ring);
- goto err_rx_setup;
- }
- rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
- }
- need_rx_update = true;
+ tx_ring = kcalloc(adapter->num_tx_queues,
+ sizeof(struct ixgbevf_ring), GFP_KERNEL);
+ if (!tx_ring) {
+ err = -ENOMEM;
+ goto clear_reset;
}
-err_rx_setup:
- /* if rings need to be updated, here's the place to do it in one shot */
- if (need_tx_update || need_rx_update) {
- if (netif_running(netdev))
- ixgbevf_down(adapter);
+ rx_ring = kcalloc(adapter->num_rx_queues,
+ sizeof(struct ixgbevf_ring), GFP_KERNEL);
+ if (!rx_ring) {
+ err = -ENOMEM;
+ goto err_rx_setup;
}
- /* tx */
- if (need_tx_update) {
- kfree(adapter->tx_ring);
- adapter->tx_ring = tx_ring;
- tx_ring = NULL;
- adapter->tx_ring_count = new_tx_count;
+ ixgbevf_down(adapter);
+
+ memcpy(tx_ring, adapter->tx_ring,
+ adapter->num_tx_queues * sizeof(struct ixgbevf_ring));
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ tx_ring[i].count = new_tx_count;
+ err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]);
+ if (err) {
+ while (i) {
+ i--;
+ ixgbevf_free_tx_resources(adapter,
+ &tx_ring[i]);
+ }
+ goto err_tx_ring_setup;
+ }
+ tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
}
- /* rx */
- if (need_rx_update) {
- kfree(adapter->rx_ring);
- adapter->rx_ring = rx_ring;
- rx_ring = NULL;
- adapter->rx_ring_count = new_rx_count;
+ memcpy(rx_ring, adapter->rx_ring,
+ adapter->num_rx_queues * sizeof(struct ixgbevf_ring));
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ rx_ring[i].count = new_rx_count;
+ err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]);
+ if (err) {
+ while (i) {
+ i--;
+ ixgbevf_free_rx_resources(adapter,
+ &rx_ring[i]);
+ }
+ goto err_rx_ring_setup;
+ }
+ rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
}
+ /*
+ * Only switch to new rings if all the prior allocations
+ * and ring setups have succeeded.
+ */
+ kfree(adapter->tx_ring);
+ adapter->tx_ring = tx_ring;
+ adapter->tx_ring_count = new_tx_count;
+
+ kfree(adapter->rx_ring);
+ adapter->rx_ring = rx_ring;
+ adapter->rx_ring_count = new_rx_count;
+
/* success! */
- err = 0;
- if (netif_running(netdev))
- ixgbevf_up(adapter);
+ ixgbevf_up(adapter);
+
+ goto clear_reset;
+
+err_rx_ring_setup:
+ for(i = 0; i < adapter->num_tx_queues; i++)
+ ixgbevf_free_tx_resources(adapter, &tx_ring[i]);
+
+err_tx_ring_setup:
+ kfree(rx_ring);
+
+err_rx_setup:
+ kfree(tx_ring);
-err_setup:
+clear_reset:
clear_bit(__IXGBEVF_RESETTING, &adapter->state);
return err;
}
diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h
index f7015efbff05..da4033c6efa2 100644
--- a/drivers/net/ixgbevf/ixgbevf.h
+++ b/drivers/net/ixgbevf/ixgbevf.h
@@ -243,7 +243,6 @@ struct ixgbevf_adapter {
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
- struct net_device_stats net_stats;
/* structs defined in ixgbe_vf.h */
struct ixgbe_hw hw;
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 918c00359b0a..dc03c9652389 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -308,10 +308,10 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
tx_ring->total_bytes += total_bytes;
tx_ring->total_packets += total_packets;
- adapter->net_stats.tx_bytes += total_bytes;
- adapter->net_stats.tx_packets += total_packets;
+ netdev->stats.tx_bytes += total_bytes;
+ netdev->stats.tx_packets += total_packets;
- return (count < tx_ring->work_limit);
+ return count < tx_ring->work_limit;
}
/**
@@ -356,7 +356,7 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector,
static inline void ixgbevf_rx_checksum(struct ixgbevf_adapter *adapter,
u32 status_err, struct sk_buff *skb)
{
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Rx csum disabled */
if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
@@ -639,8 +639,8 @@ next_desc:
rx_ring->total_packets += total_rx_packets;
rx_ring->total_bytes += total_rx_bytes;
- adapter->net_stats.rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_packets += total_rx_packets;
+ adapter->netdev->stats.rx_bytes += total_rx_bytes;
+ adapter->netdev->stats.rx_packets += total_rx_packets;
return cleaned;
}
@@ -1495,7 +1495,7 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter)
if (adapter->vlgrp) {
u16 vid;
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ for (vid = 0; vid < VLAN_N_VID; vid++) {
if (!vlan_group_get_device(adapter->vlgrp, vid))
continue;
ixgbevf_vlan_rx_add_vid(adapter->netdev, vid);
@@ -2297,7 +2297,7 @@ void ixgbevf_update_stats(struct ixgbevf_adapter *adapter)
adapter->stats.vfmprc);
/* Fill out the OS statistics structure */
- adapter->net_stats.multicast = adapter->stats.vfmprc -
+ adapter->netdev->stats.multicast = adapter->stats.vfmprc -
adapter->stats.base_vfmprc;
}
@@ -3134,7 +3134,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tx_ring = &adapter->tx_ring[r_idx];
- if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
tx_flags |= vlan_tx_tag_get(skb);
tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
tx_flags |= IXGBE_TX_FLAGS_VLAN;
@@ -3181,21 +3181,6 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
/**
- * ixgbevf_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
- **/
-static struct net_device_stats *ixgbevf_get_stats(struct net_device *netdev)
-{
- struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-
- /* only return the current stats */
- return &adapter->net_stats;
-}
-
-/**
* ixgbevf_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
* @p: pointer to an address structure
@@ -3272,7 +3257,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = &ixgbevf_open,
.ndo_stop = &ixgbevf_close,
.ndo_start_xmit = &ixgbevf_xmit_frame,
- .ndo_get_stats = &ixgbevf_get_stats,
.ndo_set_rx_mode = &ixgbevf_set_rx_mode,
.ndo_set_multicast_list = &ixgbevf_set_rx_mode,
.ndo_validate_addr = eth_validate_addr,
@@ -3426,7 +3410,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
}
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &ixgbevf_watchdog;
+ adapter->watchdog_timer.function = ixgbevf_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->reset_task, ixgbevf_reset_task);
diff --git a/drivers/net/ixgbevf/mbx.c b/drivers/net/ixgbevf/mbx.c
index b8143501e6fc..84ac486f4a65 100644
--- a/drivers/net/ixgbevf/mbx.c
+++ b/drivers/net/ixgbevf/mbx.c
@@ -308,7 +308,7 @@ out_no_read:
*
* Initializes the hw->mbx struct to correct values for vf mailbox
*/
-s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)
+static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
diff --git a/drivers/net/ixgbevf/mbx.h b/drivers/net/ixgbevf/mbx.h
index 1b0e0bf4c0f5..8c063bebee7f 100644
--- a/drivers/net/ixgbevf/mbx.h
+++ b/drivers/net/ixgbevf/mbx.h
@@ -95,6 +95,4 @@
/* forward declaration of the HW struct */
struct ixgbe_hw;
-s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *);
-
#endif /* _IXGBE_MBX_H_ */
diff --git a/drivers/net/ixgbevf/vf.c b/drivers/net/ixgbevf/vf.c
index f6f929958ba0..bfe42c1fcfaf 100644
--- a/drivers/net/ixgbevf/vf.c
+++ b/drivers/net/ixgbevf/vf.c
@@ -368,7 +368,7 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
return 0;
}
-struct ixgbe_mac_operations ixgbevf_mac_ops = {
+static struct ixgbe_mac_operations ixgbevf_mac_ops = {
.init_hw = ixgbevf_init_hw_vf,
.reset_hw = ixgbevf_reset_hw_vf,
.start_hw = ixgbevf_start_hw_vf,
diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h
index 94b750b8874f..61f9dc831424 100644
--- a/drivers/net/ixgbevf/vf.h
+++ b/drivers/net/ixgbevf/vf.h
@@ -124,8 +124,6 @@ struct ixgbe_hw {
void *back;
u8 __iomem *hw_addr;
- u8 *flash_address;
- unsigned long io_base;
struct ixgbe_mac_info mac;
struct ixgbe_mbx_info mbx;
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 99f24f5cac53..d7a975ee2add 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -3,6 +3,7 @@
*
* Copyright 2008 JMicron Technology Corporation
* http://www.jmicron.com/
+ * Copyright (c) 2009 - 2010 Guo-Fu Tseng <cooldavid@cooldavid.org>
*
* Author: Guo-Fu Tseng <cooldavid@cooldavid.org>
*
@@ -21,6 +22,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -73,7 +76,7 @@ read_again:
}
if (i == 0) {
- jeprintk(jme->pdev, "phy(%d) read timeout : %d\n", phy, reg);
+ pr_err("phy(%d) read timeout : %d\n", phy, reg);
return 0;
}
@@ -102,7 +105,7 @@ jme_mdio_write(struct net_device *netdev,
}
if (i == 0)
- jeprintk(jme->pdev, "phy(%d) write timeout : %d\n", phy, reg);
+ pr_err("phy(%d) write timeout : %d\n", phy, reg);
}
static inline void
@@ -227,7 +230,7 @@ jme_reload_eeprom(struct jme_adapter *jme)
}
if (i == 0) {
- jeprintk(jme->pdev, "eeprom reload timeout\n");
+ pr_err("eeprom reload timeout\n");
return -EIO;
}
}
@@ -397,8 +400,7 @@ jme_check_link(struct net_device *netdev, int testonly)
phylink = jread32(jme, JME_PHY_LINK);
}
if (!cnt)
- jeprintk(jme->pdev,
- "Waiting speed resolve timeout.\n");
+ pr_err("Waiting speed resolve timeout\n");
strcat(linkmsg, "ANed: ");
}
@@ -480,13 +482,13 @@ jme_check_link(struct net_device *netdev, int testonly)
strcat(linkmsg, (phylink & PHY_LINK_MDI_STAT) ?
"MDI-X" :
"MDI");
- netif_info(jme, link, jme->dev, "Link is up at %s.\n", linkmsg);
+ netif_info(jme, link, jme->dev, "Link is up at %s\n", linkmsg);
netif_carrier_on(netdev);
} else {
if (testonly)
goto out;
- netif_info(jme, link, jme->dev, "Link is down.\n");
+ netif_info(jme, link, jme->dev, "Link is down\n");
jme->phylink = 0;
netif_carrier_off(netdev);
}
@@ -648,7 +650,7 @@ jme_disable_tx_engine(struct jme_adapter *jme)
}
if (!i)
- jeprintk(jme->pdev, "Disable TX engine timeout.\n");
+ pr_err("Disable TX engine timeout\n");
}
static void
@@ -867,7 +869,7 @@ jme_disable_rx_engine(struct jme_adapter *jme)
}
if (!i)
- jeprintk(jme->pdev, "Disable RX engine timeout.\n");
+ pr_err("Disable RX engine timeout\n");
}
@@ -887,13 +889,13 @@ jme_rxsum_ok(struct jme_adapter *jme, u16 flags)
if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_UDPON | RXWBFLAG_UDPCS))
== RXWBFLAG_UDPON)) {
if (flags & RXWBFLAG_IPV4)
- netif_err(jme, rx_err, jme->dev, "UDP Checksum error.\n");
+ netif_err(jme, rx_err, jme->dev, "UDP Checksum error\n");
return false;
}
if (unlikely((flags & (RXWBFLAG_IPV4 | RXWBFLAG_IPCS))
== RXWBFLAG_IPV4)) {
- netif_err(jme, rx_err, jme->dev, "IPv4 Checksum error.\n");
+ netif_err(jme, rx_err, jme->dev, "IPv4 Checksum error\n");
return false;
}
@@ -936,7 +938,7 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) {
if (jme->vlgrp) {
@@ -988,6 +990,7 @@ jme_process_receive(struct jme_adapter *jme, int limit)
goto out;
--limit;
+ rmb();
desccnt = rxdesc->descwb.desccnt & RXWBDCNT_DCNT;
if (unlikely(desccnt > 1 ||
@@ -1185,9 +1188,9 @@ jme_link_change_tasklet(unsigned long arg)
while (!atomic_dec_and_test(&jme->link_changing)) {
atomic_inc(&jme->link_changing);
- netif_info(jme, intr, jme->dev, "Get link change lock failed.\n");
+ netif_info(jme, intr, jme->dev, "Get link change lock failed\n");
while (atomic_read(&jme->link_changing) != 1)
- netif_info(jme, intr, jme->dev, "Waiting link change lock.\n");
+ netif_info(jme, intr, jme->dev, "Waiting link change lock\n");
}
if (jme_check_link(netdev, 1) && jme->old_mtu == netdev->mtu)
@@ -1221,15 +1224,13 @@ jme_link_change_tasklet(unsigned long arg)
if (netif_carrier_ok(netdev)) {
rc = jme_setup_rx_resources(jme);
if (rc) {
- jeprintk(jme->pdev, "Allocating resources for RX error"
- ", Device STOPPED!\n");
+ pr_err("Allocating resources for RX error, Device STOPPED!\n");
goto out_enable_tasklet;
}
rc = jme_setup_tx_resources(jme);
if (rc) {
- jeprintk(jme->pdev, "Allocating resources for TX error"
- ", Device STOPPED!\n");
+ pr_err("Allocating resources for TX error, Device STOPPED!\n");
goto err_out_free_rx_resources;
}
@@ -1324,7 +1325,7 @@ jme_wake_queue_if_stopped(struct jme_adapter *jme)
smp_wmb();
if (unlikely(netif_queue_stopped(jme->dev) &&
atomic_read(&txring->nr_free) >= (jme->tx_wake_threshold))) {
- netif_info(jme, tx_done, jme->dev, "TX Queue Waked.\n");
+ netif_info(jme, tx_done, jme->dev, "TX Queue Waked\n");
netif_wake_queue(jme->dev);
}
@@ -1339,7 +1340,7 @@ jme_tx_clean_tasklet(unsigned long arg)
struct jme_buffer_info *txbi = txring->bufinf, *ctxbi, *ttxbi;
int i, j, cnt = 0, max, err, mask;
- tx_dbg(jme, "Into txclean.\n");
+ tx_dbg(jme, "Into txclean\n");
if (unlikely(!atomic_dec_and_test(&jme->tx_cleaning)))
goto out;
@@ -1361,7 +1362,7 @@ jme_tx_clean_tasklet(unsigned long arg)
!(txdesc[i].descwb.flags & TXWBFLAG_OWN))) {
tx_dbg(jme, "txclean: %d+%d@%lu\n",
- i, ctxbi->nr_desc, jiffies);
+ i, ctxbi->nr_desc, jiffies);
err = txdesc[i].descwb.flags & TXWBFLAG_ALLERR;
@@ -1402,7 +1403,7 @@ jme_tx_clean_tasklet(unsigned long arg)
ctxbi->nr_desc = 0;
}
- tx_dbg(jme, "txclean: done %d@%lu.\n", i, jiffies);
+ tx_dbg(jme, "txclean: done %d@%lu\n", i, jiffies);
atomic_set(&txring->next_to_clean, i);
atomic_add(cnt, &txring->nr_free);
@@ -1548,10 +1549,10 @@ jme_request_irq(struct jme_adapter *jme)
rc = request_irq(jme->pdev->irq, handler, irq_flags, netdev->name,
netdev);
if (rc) {
- jeprintk(jme->pdev,
- "Unable to request %s interrupt (return: %d)\n",
- test_bit(JME_FLAG_MSI, &jme->flags) ? "MSI" : "INTx",
- rc);
+ netdev_err(netdev,
+ "Unable to request %s interrupt (return: %d)\n",
+ test_bit(JME_FLAG_MSI, &jme->flags) ? "MSI" : "INTx",
+ rc);
if (test_bit(JME_FLAG_MSI, &jme->flags)) {
pci_disable_msi(jme->pdev);
@@ -1575,6 +1576,16 @@ jme_free_irq(struct jme_adapter *jme)
}
}
+static inline void
+jme_phy_on(struct jme_adapter *jme)
+{
+ u32 bmcr;
+
+ bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR);
+ bmcr &= ~BMCR_PDOWN;
+ jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr);
+}
+
static int
jme_open(struct net_device *netdev)
{
@@ -1595,10 +1606,12 @@ jme_open(struct net_device *netdev)
jme_start_irq(jme);
- if (test_bit(JME_FLAG_SSET, &jme->flags))
+ if (test_bit(JME_FLAG_SSET, &jme->flags)) {
+ jme_phy_on(jme);
jme_set_settings(netdev, &jme->old_ecmd);
- else
+ } else {
jme_reset_phy_processor(jme);
+ }
jme_reset_link(jme);
@@ -1834,7 +1847,7 @@ jme_tx_csum(struct jme_adapter *jme, struct sk_buff *skb, u8 *flags)
*flags |= TXFLAG_UDPCS;
break;
default:
- netif_err(jme, tx_err, jme->dev, "Error upper layer protocol.\n");
+ netif_err(jme, tx_err, jme->dev, "Error upper layer protocol\n");
break;
}
}
@@ -1909,12 +1922,12 @@ jme_stop_queue_if_full(struct jme_adapter *jme)
smp_wmb();
if (unlikely(atomic_read(&txring->nr_free) < (MAX_SKB_FRAGS+2))) {
netif_stop_queue(jme->dev);
- netif_info(jme, tx_queued, jme->dev, "TX Queue Paused.\n");
+ netif_info(jme, tx_queued, jme->dev, "TX Queue Paused\n");
smp_wmb();
if (atomic_read(&txring->nr_free)
>= (jme->tx_wake_threshold)) {
netif_wake_queue(jme->dev);
- netif_info(jme, tx_queued, jme->dev, "TX Queue Fast Waked.\n");
+ netif_info(jme, tx_queued, jme->dev, "TX Queue Fast Waked\n");
}
}
@@ -1922,7 +1935,8 @@ jme_stop_queue_if_full(struct jme_adapter *jme)
(jiffies - txbi->start_xmit) >= TX_TIMEOUT &&
txbi->skb)) {
netif_stop_queue(jme->dev);
- netif_info(jme, tx_queued, jme->dev, "TX Queue Stopped %d@%lu.\n", idx, jiffies);
+ netif_info(jme, tx_queued, jme->dev,
+ "TX Queue Stopped %d@%lu\n", idx, jiffies);
}
}
@@ -1945,7 +1959,8 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if (unlikely(idx < 0)) {
netif_stop_queue(netdev);
- netif_err(jme, tx_err, jme->dev, "BUG! Tx ring full when queue awake!\n");
+ netif_err(jme, tx_err, jme->dev,
+ "BUG! Tx ring full when queue awake!\n");
return NETDEV_TX_BUSY;
}
@@ -1957,9 +1972,8 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
TXCS_QUEUE0S |
TXCS_ENABLE);
- tx_dbg(jme, "xmit: %d+%d@%lu\n", idx,
- skb_shinfo(skb)->nr_frags + 2,
- jiffies);
+ tx_dbg(jme, "xmit: %d+%d@%lu\n",
+ idx, skb_shinfo(skb)->nr_frags + 2, jiffies);
jme_stop_queue_if_full(jme);
return NETDEV_TX_OK;
@@ -2382,6 +2396,10 @@ jme_set_settings(struct net_device *netdev,
if (ecmd->speed == SPEED_1000 && ecmd->autoneg != AUTONEG_ENABLE)
return -EINVAL;
+ /*
+ * Check If user changed duplex only while force_media.
+ * Hardware would not generate link change interrupt.
+ */
if (jme->mii_if.force_media &&
ecmd->autoneg != AUTONEG_ENABLE &&
(jme->mii_if.full_duplex != ecmd->duplex))
@@ -2391,12 +2409,40 @@ jme_set_settings(struct net_device *netdev,
rc = mii_ethtool_sset(&(jme->mii_if), ecmd);
spin_unlock_bh(&jme->phy_lock);
- if (!rc && fdc)
- jme_reset_link(jme);
-
if (!rc) {
- set_bit(JME_FLAG_SSET, &jme->flags);
+ if (fdc)
+ jme_reset_link(jme);
jme->old_ecmd = *ecmd;
+ set_bit(JME_FLAG_SSET, &jme->flags);
+ }
+
+ return rc;
+}
+
+static int
+jme_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+ int rc;
+ struct jme_adapter *jme = netdev_priv(netdev);
+ struct mii_ioctl_data *mii_data = if_mii(rq);
+ unsigned int duplex_chg;
+
+ if (cmd == SIOCSMIIREG) {
+ u16 val = mii_data->val_in;
+ if (!(val & (BMCR_RESET|BMCR_ANENABLE)) &&
+ (val & BMCR_SPEED1000))
+ return -EINVAL;
+ }
+
+ spin_lock_bh(&jme->phy_lock);
+ rc = generic_mii_ioctl(&jme->mii_if, mii_data, cmd, &duplex_chg);
+ spin_unlock_bh(&jme->phy_lock);
+
+ if (!rc && (cmd == SIOCSMIIREG)) {
+ if (duplex_chg)
+ jme_reset_link(jme);
+ jme_get_settings(netdev, &jme->old_ecmd);
+ set_bit(JME_FLAG_SSET, &jme->flags);
}
return rc;
@@ -2501,7 +2547,7 @@ jme_smb_read(struct jme_adapter *jme, unsigned int addr)
val = jread32(jme, JME_SMBCSR);
}
if (!to) {
- netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
+ netif_err(jme, hw, jme->dev, "SMB Bus Busy\n");
return 0xFF;
}
@@ -2517,7 +2563,7 @@ jme_smb_read(struct jme_adapter *jme, unsigned int addr)
val = jread32(jme, JME_SMBINTF);
}
if (!to) {
- netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
+ netif_err(jme, hw, jme->dev, "SMB Bus Busy\n");
return 0xFF;
}
@@ -2537,7 +2583,7 @@ jme_smb_write(struct jme_adapter *jme, unsigned int addr, u8 data)
val = jread32(jme, JME_SMBCSR);
}
if (!to) {
- netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
+ netif_err(jme, hw, jme->dev, "SMB Bus Busy\n");
return;
}
@@ -2554,7 +2600,7 @@ jme_smb_write(struct jme_adapter *jme, unsigned int addr, u8 data)
val = jread32(jme, JME_SMBINTF);
}
if (!to) {
- netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
+ netif_err(jme, hw, jme->dev, "SMB Bus Busy\n");
return;
}
@@ -2676,6 +2722,7 @@ static const struct net_device_ops jme_netdev_ops = {
.ndo_open = jme_open,
.ndo_stop = jme_close,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = jme_ioctl,
.ndo_start_xmit = jme_start_xmit,
.ndo_set_mac_address = jme_set_macaddr,
.ndo_set_multicast_list = jme_set_multi,
@@ -2699,26 +2746,26 @@ jme_init_one(struct pci_dev *pdev,
*/
rc = pci_enable_device(pdev);
if (rc) {
- jeprintk(pdev, "Cannot enable PCI device.\n");
+ pr_err("Cannot enable PCI device\n");
goto err_out;
}
using_dac = jme_pci_dma64(pdev);
if (using_dac < 0) {
- jeprintk(pdev, "Cannot set PCI DMA Mask.\n");
+ pr_err("Cannot set PCI DMA Mask\n");
rc = -EIO;
goto err_out_disable_pdev;
}
if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
- jeprintk(pdev, "No PCI resource region found.\n");
+ pr_err("No PCI resource region found\n");
rc = -ENOMEM;
goto err_out_disable_pdev;
}
rc = pci_request_regions(pdev, DRV_NAME);
if (rc) {
- jeprintk(pdev, "Cannot obtain PCI resource region.\n");
+ pr_err("Cannot obtain PCI resource region\n");
goto err_out_disable_pdev;
}
@@ -2729,7 +2776,7 @@ jme_init_one(struct pci_dev *pdev,
*/
netdev = alloc_etherdev(sizeof(*jme));
if (!netdev) {
- jeprintk(pdev, "Cannot allocate netdev structure.\n");
+ pr_err("Cannot allocate netdev structure\n");
rc = -ENOMEM;
goto err_out_release_regions;
}
@@ -2767,7 +2814,7 @@ jme_init_one(struct pci_dev *pdev,
jme->regs = ioremap(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
if (!(jme->regs)) {
- jeprintk(pdev, "Mapping PCI resource region error.\n");
+ pr_err("Mapping PCI resource region error\n");
rc = -ENOMEM;
goto err_out_free_netdev;
}
@@ -2855,8 +2902,8 @@ jme_init_one(struct pci_dev *pdev,
if (!jme->mii_if.phy_id) {
rc = -EIO;
- jeprintk(pdev, "Can not find phy_id.\n");
- goto err_out_unmap;
+ pr_err("Can not find phy_id\n");
+ goto err_out_unmap;
}
jme->reg_ghc |= GHC_LINK_POLL;
@@ -2867,6 +2914,8 @@ jme_init_one(struct pci_dev *pdev,
jme->mii_if.supports_gmii = true;
else
jme->mii_if.supports_gmii = false;
+ jme->mii_if.phy_id_mask = 0x1F;
+ jme->mii_if.reg_num_mask = 0x1F;
jme->mii_if.mdio_read = jme_mdio_read;
jme->mii_if.mdio_write = jme_mdio_write;
@@ -2883,8 +2932,7 @@ jme_init_one(struct pci_dev *pdev,
jme_reset_mac_processor(jme);
rc = jme_reload_eeprom(jme);
if (rc) {
- jeprintk(pdev,
- "Reload eeprom for reading MAC Address error.\n");
+ pr_err("Reload eeprom for reading MAC Address error\n");
goto err_out_unmap;
}
jme_load_macaddr(netdev);
@@ -2900,7 +2948,7 @@ jme_init_one(struct pci_dev *pdev,
*/
rc = register_netdev(netdev);
if (rc) {
- jeprintk(pdev, "Cannot register net device.\n");
+ pr_err("Cannot register net device\n");
goto err_out_unmap;
}
@@ -3006,10 +3054,12 @@ jme_resume(struct pci_dev *pdev)
jme_clear_pm(jme);
pci_restore_state(pdev);
- if (test_bit(JME_FLAG_SSET, &jme->flags))
+ if (test_bit(JME_FLAG_SSET, &jme->flags)) {
+ jme_phy_on(jme);
jme_set_settings(netdev, &jme->old_ecmd);
- else
+ } else {
jme_reset_phy_processor(jme);
+ }
jme_start_irq(jme);
netif_device_attach(netdev);
@@ -3042,8 +3092,7 @@ static struct pci_driver jme_driver = {
static int __init
jme_init_module(void)
{
- printk(KERN_INFO PFX "JMicron JMC2XX ethernet "
- "driver version %s\n", DRV_VERSION);
+ pr_info("JMicron JMC2XX ethernet driver version %s\n", DRV_VERSION);
return pci_register_driver(&jme_driver);
}
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index 07ad3a457185..eac09264bf2a 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -3,6 +3,7 @@
*
* Copyright 2008 JMicron Technology Corporation
* http://www.jmicron.com/
+ * Copyright (c) 2009 - 2010 Guo-Fu Tseng <cooldavid@cooldavid.org>
*
* Author: Guo-Fu Tseng <cooldavid@cooldavid.org>
*
@@ -25,7 +26,7 @@
#define __JME_H_INCLUDED__
#define DRV_NAME "jme"
-#define DRV_VERSION "1.0.6"
+#define DRV_VERSION "1.0.7"
#define PFX DRV_NAME ": "
#define PCI_DEVICE_ID_JMICRON_JMC250 0x0250
@@ -41,9 +42,6 @@
NETIF_MSG_TX_ERR | \
NETIF_MSG_HW)
-#define jeprintk(pdev, fmt, args...) \
- printk(KERN_ERR PFX fmt, ## args)
-
#ifdef TX_DEBUG
#define tx_dbg(priv, fmt, args...) \
printk(KERN_DEBUG "%s: " fmt, (priv)->dev->name, ##args)
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
index 87f0a93b165c..9f8e7027b0b3 100644
--- a/drivers/net/ll_temac_main.c
+++ b/drivers/net/ll_temac_main.c
@@ -495,7 +495,7 @@ static u32 temac_setoptions(struct net_device *ndev, u32 options)
lp->options |= options;
mutex_unlock(&lp->indirect_mutex);
- return (0);
+ return 0;
}
/* Initialize temac */
@@ -761,7 +761,7 @@ static void ll_temac_recv(struct net_device *ndev)
skb_put(skb, length);
skb->dev = ndev;
skb->protocol = eth_type_trans(skb, ndev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* if we're doing rx csum offload, set it up */
if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) &&
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 9a0996795321..2d9663a1c54d 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -64,7 +64,6 @@ struct pcpu_lstats {
u64 packets;
u64 bytes;
struct u64_stats_sync syncp;
- unsigned long drops;
};
/*
@@ -74,7 +73,6 @@ struct pcpu_lstats {
static netdev_tx_t loopback_xmit(struct sk_buff *skb,
struct net_device *dev)
{
- struct pcpu_lstats __percpu *pcpu_lstats;
struct pcpu_lstats *lb_stats;
int len;
@@ -83,8 +81,7 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,
skb->protocol = eth_type_trans(skb, dev);
/* it's OK to use per_cpu_ptr() because BHs are off */
- pcpu_lstats = (void __percpu __force *)dev->ml_priv;
- lb_stats = this_cpu_ptr(pcpu_lstats);
+ lb_stats = this_cpu_ptr(dev->lstats);
len = skb->len;
if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {
@@ -92,8 +89,7 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,
lb_stats->bytes += len;
lb_stats->packets++;
u64_stats_update_end(&lb_stats->syncp);
- } else
- lb_stats->drops++;
+ }
return NETDEV_TX_OK;
}
@@ -101,32 +97,26 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,
static struct rtnl_link_stats64 *loopback_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *stats)
{
- const struct pcpu_lstats __percpu *pcpu_lstats;
u64 bytes = 0;
u64 packets = 0;
- u64 drops = 0;
int i;
- pcpu_lstats = (void __percpu __force *)dev->ml_priv;
for_each_possible_cpu(i) {
const struct pcpu_lstats *lb_stats;
u64 tbytes, tpackets;
unsigned int start;
- lb_stats = per_cpu_ptr(pcpu_lstats, i);
+ lb_stats = per_cpu_ptr(dev->lstats, i);
do {
start = u64_stats_fetch_begin(&lb_stats->syncp);
tbytes = lb_stats->bytes;
tpackets = lb_stats->packets;
} while (u64_stats_fetch_retry(&lb_stats->syncp, start));
- drops += lb_stats->drops;
bytes += tbytes;
packets += tpackets;
}
stats->rx_packets = packets;
stats->tx_packets = packets;
- stats->rx_dropped = drops;
- stats->rx_errors = drops;
stats->rx_bytes = bytes;
stats->tx_bytes = bytes;
return stats;
@@ -147,22 +137,16 @@ static const struct ethtool_ops loopback_ethtool_ops = {
static int loopback_dev_init(struct net_device *dev)
{
- struct pcpu_lstats __percpu *lstats;
-
- lstats = alloc_percpu(struct pcpu_lstats);
- if (!lstats)
+ dev->lstats = alloc_percpu(struct pcpu_lstats);
+ if (!dev->lstats)
return -ENOMEM;
- dev->ml_priv = (void __force *)lstats;
return 0;
}
static void loopback_dev_free(struct net_device *dev)
{
- struct pcpu_lstats __percpu *lstats =
- (void __percpu __force *)dev->ml_priv;
-
- free_percpu(lstats);
+ free_percpu(dev->lstats);
free_netdev(dev);
}
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index 3df046a58b1d..3698824744cb 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -460,7 +460,7 @@ init_rx_bufs(struct net_device *dev, int num) {
}
lp->rbd_tail->next = rfd->rbd;
#endif
- return (i);
+ return i;
}
static inline void
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index 3832fa4961dd..f84f5e6ededb 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -562,19 +562,19 @@ static int __init mac8390_initdev(struct net_device *dev,
case ACCESS_16:
/* 16 bit card, register map is reversed */
- ei_status.reset_8390 = &mac8390_no_reset;
- ei_status.block_input = &slow_sane_block_input;
- ei_status.block_output = &slow_sane_block_output;
- ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
ei_status.reg_offset = back4_offsets;
break;
case ACCESS_32:
/* 32 bit card, register map is reversed */
- ei_status.reset_8390 = &mac8390_no_reset;
- ei_status.block_input = &sane_block_input;
- ei_status.block_output = &sane_block_output;
- ei_status.get_8390_hdr = &sane_get_8390_hdr;
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = sane_block_input;
+ ei_status.block_output = sane_block_output;
+ ei_status.get_8390_hdr = sane_get_8390_hdr;
ei_status.reg_offset = back4_offsets;
access_bitmode = 1;
break;
@@ -586,19 +586,19 @@ static int __init mac8390_initdev(struct net_device *dev,
* but overwrite system memory when run at 32 bit.
* so we run them all at 16 bit.
*/
- ei_status.reset_8390 = &mac8390_no_reset;
- ei_status.block_input = &slow_sane_block_input;
- ei_status.block_output = &slow_sane_block_output;
- ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
ei_status.reg_offset = back4_offsets;
break;
case MAC8390_CABLETRON:
/* 16 bit card, register map is short forward */
- ei_status.reset_8390 = &mac8390_no_reset;
- ei_status.block_input = &slow_sane_block_input;
- ei_status.block_output = &slow_sane_block_output;
- ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
ei_status.reg_offset = fwrd2_offsets;
break;
@@ -606,19 +606,19 @@ static int __init mac8390_initdev(struct net_device *dev,
case MAC8390_KINETICS:
/* 16 bit memory, register map is forward */
/* dayna and similar */
- ei_status.reset_8390 = &mac8390_no_reset;
- ei_status.block_input = &dayna_block_input;
- ei_status.block_output = &dayna_block_output;
- ei_status.get_8390_hdr = &dayna_get_8390_hdr;
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = dayna_block_input;
+ ei_status.block_output = dayna_block_output;
+ ei_status.get_8390_hdr = dayna_get_8390_hdr;
ei_status.reg_offset = fwrd4_offsets;
break;
case MAC8390_INTERLAN:
/* 16 bit memory, register map is forward */
- ei_status.reset_8390 = &interlan_reset;
- ei_status.block_input = &slow_sane_block_input;
- ei_status.block_output = &slow_sane_block_output;
- ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+ ei_status.reset_8390 = interlan_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
ei_status.reg_offset = fwrd4_offsets;
break;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index ff2f158ab0b9..4297f6e8c4bc 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -407,7 +407,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
}
skb_reserve(skb, RX_OFFSET);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb_put(skb, len);
for (frag = first_frag; ; frag = NEXT_RX(frag)) {
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 0ef0eb0db945..0fc9dc7f20db 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -788,6 +788,10 @@ static int macvlan_device_event(struct notifier_block *unused,
}
break;
case NETDEV_UNREGISTER:
+ /* twiddle thumbs on netns device moves */
+ if (dev->reg_state != NETREG_UNREGISTERING)
+ break;
+
list_for_each_entry_safe(vlan, next, &port->vlans, list)
vlan->dev->rtnl_link_ops->dellink(vlan->dev, NULL);
break;
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 3b1c54a9c6ef..42567279843e 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -84,26 +84,45 @@ static const struct proto_ops macvtap_socket_ops;
static DEFINE_SPINLOCK(macvtap_lock);
/*
- * Choose the next free queue, for now there is only one
+ * get_slot: return a [unused/occupied] slot in vlan->taps[]:
+ * - if 'q' is NULL, return the first empty slot;
+ * - otherwise, return the slot this pointer occupies.
*/
+static int get_slot(struct macvlan_dev *vlan, struct macvtap_queue *q)
+{
+ int i;
+
+ for (i = 0; i < MAX_MACVTAP_QUEUES; i++) {
+ if (rcu_dereference(vlan->taps[i]) == q)
+ return i;
+ }
+
+ /* Should never happen */
+ BUG_ON(1);
+}
+
static int macvtap_set_queue(struct net_device *dev, struct file *file,
struct macvtap_queue *q)
{
struct macvlan_dev *vlan = netdev_priv(dev);
+ int index;
int err = -EBUSY;
spin_lock(&macvtap_lock);
- if (rcu_dereference(vlan->tap))
+ if (vlan->numvtaps == MAX_MACVTAP_QUEUES)
goto out;
err = 0;
+ index = get_slot(vlan, NULL);
rcu_assign_pointer(q->vlan, vlan);
- rcu_assign_pointer(vlan->tap, q);
+ rcu_assign_pointer(vlan->taps[index], q);
sock_hold(&q->sk);
q->file = file;
file->private_data = q;
+ vlan->numvtaps++;
+
out:
spin_unlock(&macvtap_lock);
return err;
@@ -124,9 +143,12 @@ static void macvtap_put_queue(struct macvtap_queue *q)
spin_lock(&macvtap_lock);
vlan = rcu_dereference(q->vlan);
if (vlan) {
- rcu_assign_pointer(vlan->tap, NULL);
+ int index = get_slot(vlan, q);
+
+ rcu_assign_pointer(vlan->taps[index], NULL);
rcu_assign_pointer(q->vlan, NULL);
sock_put(&q->sk);
+ --vlan->numvtaps;
}
spin_unlock(&macvtap_lock);
@@ -136,39 +158,82 @@ static void macvtap_put_queue(struct macvtap_queue *q)
}
/*
- * Since we only support one queue, just dereference the pointer.
+ * Select a queue based on the rxq of the device on which this packet
+ * arrived. If the incoming device is not mq, calculate a flow hash
+ * to select a queue. If all fails, find the first available queue.
+ * Cache vlan->numvtaps since it can become zero during the execution
+ * of this function.
*/
static struct macvtap_queue *macvtap_get_queue(struct net_device *dev,
struct sk_buff *skb)
{
struct macvlan_dev *vlan = netdev_priv(dev);
+ struct macvtap_queue *tap = NULL;
+ int numvtaps = vlan->numvtaps;
+ __u32 rxq;
+
+ if (!numvtaps)
+ goto out;
+
+ if (likely(skb_rx_queue_recorded(skb))) {
+ rxq = skb_get_rx_queue(skb);
+
+ while (unlikely(rxq >= numvtaps))
+ rxq -= numvtaps;
+
+ tap = rcu_dereference(vlan->taps[rxq]);
+ if (tap)
+ goto out;
+ }
+
+ /* Check if we can use flow to select a queue */
+ rxq = skb_get_rxhash(skb);
+ if (rxq) {
+ tap = rcu_dereference(vlan->taps[rxq % numvtaps]);
+ if (tap)
+ goto out;
+ }
- return rcu_dereference(vlan->tap);
+ /* Everything failed - find first available queue */
+ for (rxq = 0; rxq < MAX_MACVTAP_QUEUES; rxq++) {
+ tap = rcu_dereference(vlan->taps[rxq]);
+ if (tap)
+ break;
+ }
+
+out:
+ return tap;
}
/*
* The net_device is going away, give up the reference
- * that it holds on the queue (all the queues one day)
- * and safely set the pointer from the queues to NULL.
+ * that it holds on all queues and safely set the pointer
+ * from the queues to NULL.
*/
static void macvtap_del_queues(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
- struct macvtap_queue *q;
+ struct macvtap_queue *q, *qlist[MAX_MACVTAP_QUEUES];
+ int i, j = 0;
+ /* macvtap_put_queue can free some slots, so go through all slots */
spin_lock(&macvtap_lock);
- q = rcu_dereference(vlan->tap);
- if (!q) {
- spin_unlock(&macvtap_lock);
- return;
+ for (i = 0; i < MAX_MACVTAP_QUEUES && vlan->numvtaps; i++) {
+ q = rcu_dereference(vlan->taps[i]);
+ if (q) {
+ qlist[j++] = q;
+ rcu_assign_pointer(vlan->taps[i], NULL);
+ rcu_assign_pointer(q->vlan, NULL);
+ vlan->numvtaps--;
+ }
}
-
- rcu_assign_pointer(vlan->tap, NULL);
- rcu_assign_pointer(q->vlan, NULL);
+ BUG_ON(vlan->numvtaps != 0);
spin_unlock(&macvtap_lock);
synchronize_rcu();
- sock_put(&q->sk);
+
+ for (--j; j >= 0; j--)
+ sock_put(&qlist[j]->sk);
}
/*
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 42e3294671d7..60135aa55802 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -461,7 +461,7 @@ static int meth_tx_full(struct net_device *dev)
{
struct meth_private *priv = netdev_priv(dev);
- return (priv->tx_count >= TX_RING_ENTRIES - 1);
+ return priv->tx_count >= TX_RING_ENTRIES - 1;
}
static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status)
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
index 1fd068e1d930..d1aa45a15854 100644
--- a/drivers/net/mlx4/Makefile
+++ b/drivers/net/mlx4/Makefile
@@ -6,4 +6,4 @@ mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
obj-$(CONFIG_MLX4_EN) += mlx4_en.o
mlx4_en-y := en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \
- en_resources.o en_netdev.o
+ en_resources.o en_netdev.o en_selftest.o
diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c
index 8c8515619b8e..8f4bf1f07c11 100644
--- a/drivers/net/mlx4/alloc.c
+++ b/drivers/net/mlx4/alloc.c
@@ -74,7 +74,7 @@ void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj)
u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
{
- u32 obj, i;
+ u32 obj;
if (likely(cnt == 1 && align == 1))
return mlx4_bitmap_alloc(bitmap);
@@ -91,8 +91,7 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
}
if (obj < bitmap->max) {
- for (i = 0; i < cnt; i++)
- set_bit(obj + i, bitmap->table);
+ bitmap_set(bitmap->table, obj, cnt);
if (obj == bitmap->last) {
bitmap->last = (obj + cnt);
if (bitmap->last >= bitmap->max)
@@ -109,13 +108,10 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
{
- u32 i;
-
obj &= bitmap->max + bitmap->reserved_top - 1;
spin_lock(&bitmap->lock);
- for (i = 0; i < cnt; i++)
- clear_bit(obj + i, bitmap->table);
+ bitmap_clear(bitmap->table, obj, cnt);
bitmap->last = min(bitmap->last, obj);
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
& bitmap->mask;
@@ -125,8 +121,6 @@ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
u32 reserved_bot, u32 reserved_top)
{
- int i;
-
/* num must be a power of 2 */
if (num != roundup_pow_of_two(num))
return -EINVAL;
@@ -142,8 +136,7 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
if (!bitmap->table)
return -ENOMEM;
- for (i = 0; i < reserved_bot; ++i)
- set_bit(i, bitmap->table);
+ bitmap_set(bitmap->table, 0, reserved_bot);
return 0;
}
@@ -188,7 +181,7 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE;
buf->npages = buf->nbufs;
buf->page_shift = PAGE_SHIFT;
- buf->page_list = kzalloc(buf->nbufs * sizeof *buf->page_list,
+ buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list),
GFP_KERNEL);
if (!buf->page_list)
return -ENOMEM;
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
index b275238fe70d..056152b3ff58 100644
--- a/drivers/net/mlx4/en_ethtool.c
+++ b/drivers/net/mlx4/en_ethtool.c
@@ -39,21 +39,6 @@
#include "en_port.h"
-static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv)
-{
- int i;
-
- priv->port_stats.lro_aggregated = 0;
- priv->port_stats.lro_flushed = 0;
- priv->port_stats.lro_no_desc = 0;
-
- for (i = 0; i < priv->rx_ring_num; i++) {
- priv->port_stats.lro_aggregated += priv->rx_ring[i].lro.stats.aggregated;
- priv->port_stats.lro_flushed += priv->rx_ring[i].lro.stats.flushed;
- priv->port_stats.lro_no_desc += priv->rx_ring[i].lro.stats.no_desc;
- }
-}
-
static void
mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
{
@@ -112,7 +97,7 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
"tx_heartbeat_errors", "tx_window_errors",
/* port statistics */
- "lro_aggregated", "lro_flushed", "lro_no_desc", "tso_packets",
+ "tso_packets",
"queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
"rx_csum_good", "rx_csum_none", "tx_chksum_offload",
@@ -125,6 +110,14 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
#define NUM_MAIN_STATS 21
#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS)
+static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {
+ "Interupt Test",
+ "Link Test",
+ "Speed Test",
+ "Register Test",
+ "Loopback Test",
+};
+
static u32 mlx4_en_get_msglevel(struct net_device *dev)
{
return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable;
@@ -146,10 +139,15 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
- if (sset != ETH_SS_STATS)
+ switch (sset) {
+ case ETH_SS_STATS:
+ return NUM_ALL_STATS +
+ (priv->tx_ring_num + priv->rx_ring_num) * 2;
+ case ETH_SS_TEST:
+ return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.loopback_support) * 2;
+ default:
return -EOPNOTSUPP;
-
- return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2;
+ }
}
static void mlx4_en_get_ethtool_stats(struct net_device *dev,
@@ -161,8 +159,6 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
spin_lock_bh(&priv->stats_lock);
- mlx4_en_update_lro_stats(priv);
-
for (i = 0; i < NUM_MAIN_STATS; i++)
data[index++] = ((unsigned long *) &priv->stats)[i];
for (i = 0; i < NUM_PORT_STATS; i++)
@@ -181,6 +177,12 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
}
+static void mlx4_en_self_test(struct net_device *dev,
+ struct ethtool_test *etest, u64 *buf)
+{
+ mlx4_en_ex_selftest(dev, &etest->flags, buf);
+}
+
static void mlx4_en_get_strings(struct net_device *dev,
uint32_t stringset, uint8_t *data)
{
@@ -188,44 +190,76 @@ static void mlx4_en_get_strings(struct net_device *dev,
int index = 0;
int i;
- if (stringset != ETH_SS_STATS)
- return;
-
- /* Add main counters */
- for (i = 0; i < NUM_MAIN_STATS; i++)
- strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]);
- for (i = 0; i < NUM_PORT_STATS; i++)
- strcpy(data + (index++) * ETH_GSTRING_LEN,
+ switch (stringset) {
+ case ETH_SS_TEST:
+ for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++)
+ strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]);
+ if (priv->mdev->dev->caps.loopback_support)
+ for (; i < MLX4_EN_NUM_SELF_TEST; i++)
+ strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]);
+ break;
+
+ case ETH_SS_STATS:
+ /* Add main counters */
+ for (i = 0; i < NUM_MAIN_STATS; i++)
+ strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]);
+ for (i = 0; i< NUM_PORT_STATS; i++)
+ strcpy(data + (index++) * ETH_GSTRING_LEN,
main_strings[i + NUM_MAIN_STATS]);
- for (i = 0; i < priv->tx_ring_num; i++) {
- sprintf(data + (index++) * ETH_GSTRING_LEN,
- "tx%d_packets", i);
- sprintf(data + (index++) * ETH_GSTRING_LEN,
- "tx%d_bytes", i);
- }
- for (i = 0; i < priv->rx_ring_num; i++) {
- sprintf(data + (index++) * ETH_GSTRING_LEN,
- "rx%d_packets", i);
- sprintf(data + (index++) * ETH_GSTRING_LEN,
- "rx%d_bytes", i);
- }
- for (i = 0; i < NUM_PKT_STATS; i++)
- strcpy(data + (index++) * ETH_GSTRING_LEN,
+ for (i = 0; i < priv->tx_ring_num; i++) {
+ sprintf(data + (index++) * ETH_GSTRING_LEN,
+ "tx%d_packets", i);
+ sprintf(data + (index++) * ETH_GSTRING_LEN,
+ "tx%d_bytes", i);
+ }
+ for (i = 0; i < priv->rx_ring_num; i++) {
+ sprintf(data + (index++) * ETH_GSTRING_LEN,
+ "rx%d_packets", i);
+ sprintf(data + (index++) * ETH_GSTRING_LEN,
+ "rx%d_bytes", i);
+ }
+ for (i = 0; i< NUM_PKT_STATS; i++)
+ strcpy(data + (index++) * ETH_GSTRING_LEN,
main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]);
+ break;
+ }
}
static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ int trans_type;
+
cmd->autoneg = AUTONEG_DISABLE;
cmd->supported = SUPPORTED_10000baseT_Full;
- cmd->advertising = ADVERTISED_1000baseT_Full;
+ cmd->advertising = ADVERTISED_10000baseT_Full;
+
+ if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
+ return -ENOMEM;
+
+ trans_type = priv->port_state.transciver;
if (netif_carrier_ok(dev)) {
- cmd->speed = SPEED_10000;
+ cmd->speed = priv->port_state.link_speed;
cmd->duplex = DUPLEX_FULL;
} else {
cmd->speed = -1;
cmd->duplex = -1;
}
+
+ if (trans_type > 0 && trans_type <= 0xC) {
+ cmd->port = PORT_FIBRE;
+ cmd->transceiver = XCVR_EXTERNAL;
+ cmd->supported |= SUPPORTED_FIBRE;
+ cmd->advertising |= ADVERTISED_FIBRE;
+ } else if (trans_type == 0x80 || trans_type == 0) {
+ cmd->port = PORT_TP;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->supported |= SUPPORTED_TP;
+ cmd->advertising |= ADVERTISED_TP;
+ } else {
+ cmd->port = -1;
+ cmd->transceiver = -1;
+ }
return 0;
}
@@ -343,8 +377,9 @@ static int mlx4_en_set_ringparam(struct net_device *dev,
tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE);
tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE);
- if (rx_size == priv->prof->rx_ring_size &&
- tx_size == priv->prof->tx_ring_size)
+ if (rx_size == (priv->port_up ? priv->rx_ring[0].actual_size :
+ priv->rx_ring[0].size) &&
+ tx_size == priv->tx_ring[0].size)
return 0;
mutex_lock(&mdev->state_lock);
@@ -378,49 +413,13 @@ static void mlx4_en_get_ringparam(struct net_device *dev,
struct ethtool_ringparam *param)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
- struct mlx4_en_dev *mdev = priv->mdev;
memset(param, 0, sizeof(*param));
param->rx_max_pending = MLX4_EN_MAX_RX_SIZE;
param->tx_max_pending = MLX4_EN_MAX_TX_SIZE;
- param->rx_pending = mdev->profile.prof[priv->port].rx_ring_size;
- param->tx_pending = mdev->profile.prof[priv->port].tx_ring_size;
-}
-
-static int mlx4_ethtool_op_set_flags(struct net_device *dev, u32 data)
-{
- struct mlx4_en_priv *priv = netdev_priv(dev);
- struct mlx4_en_dev *mdev = priv->mdev;
- int rc = 0;
- int changed = 0;
-
- if (data & ~ETH_FLAG_LRO)
- return -EOPNOTSUPP;
-
- if (data & ETH_FLAG_LRO) {
- if (mdev->profile.num_lro == 0)
- return -EOPNOTSUPP;
- if (!(dev->features & NETIF_F_LRO))
- changed = 1;
- } else if (dev->features & NETIF_F_LRO) {
- changed = 1;
- }
-
- if (changed) {
- if (netif_running(dev)) {
- mutex_lock(&mdev->state_lock);
- mlx4_en_stop_port(dev);
- }
- dev->features ^= NETIF_F_LRO;
- if (netif_running(dev)) {
- rc = mlx4_en_start_port(dev);
- if (rc)
- en_err(priv, "Failed to restart port\n");
- mutex_unlock(&mdev->state_lock);
- }
- }
-
- return rc;
+ param->rx_pending = priv->port_up ?
+ priv->rx_ring[0].actual_size : priv->rx_ring[0].size;
+ param->tx_pending = priv->tx_ring[0].size;
}
const struct ethtool_ops mlx4_en_ethtool_ops = {
@@ -441,6 +440,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_strings = mlx4_en_get_strings,
.get_sset_count = mlx4_en_get_sset_count,
.get_ethtool_stats = mlx4_en_get_ethtool_stats,
+ .self_test = mlx4_en_self_test,
.get_wol = mlx4_en_get_wol,
.get_msglevel = mlx4_en_get_msglevel,
.set_msglevel = mlx4_en_set_msglevel,
@@ -451,7 +451,6 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_ringparam = mlx4_en_get_ringparam,
.set_ringparam = mlx4_en_set_ringparam,
.get_flags = ethtool_op_get_flags,
- .set_flags = mlx4_ethtool_op_set_flags,
};
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index 97934f1ec53a..143906417048 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -63,15 +63,12 @@ static const char mlx4_en_version[] =
*/
-/* Use a XOR rathern than Toeplitz hash function for RSS */
-MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS");
-
-/* RSS hash type mask - default to <saddr, daddr, sport, dport> */
-MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask");
-
-/* Number of LRO sessions per Rx ring (rounded up to a power of two) */
-MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS,
- "Number of LRO sessions per ring or disabled (0)");
+/* Enable RSS TCP traffic */
+MLX4_EN_PARM_INT(tcp_rss, 1,
+ "Enable RSS for incomming TCP traffic or disabled (0)");
+/* Enable RSS UDP traffic */
+MLX4_EN_PARM_INT(udp_rss, 1,
+ "Enable RSS for incomming UDP traffic or disabled (0)");
/* Priority pausing */
MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]."
@@ -107,9 +104,12 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
struct mlx4_en_profile *params = &mdev->profile;
int i;
- params->rss_xor = (rss_xor != 0);
- params->rss_mask = rss_mask & 0x1f;
- params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS);
+ params->tcp_rss = tcp_rss;
+ params->udp_rss = udp_rss;
+ if (params->udp_rss && !mdev->dev->caps.udp_rss) {
+ mlx4_warn(mdev, "UDP RSS is not supported on this device.\n");
+ params->udp_rss = 0;
+ }
for (i = 1; i <= MLX4_MAX_PORTS; i++) {
params->prof[i].rx_pause = 1;
params->prof[i].rx_ppp = pfcrx;
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index a0d8a26f5a02..79478bd4211a 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -109,7 +109,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
mutex_unlock(&mdev->state_lock);
}
-static u64 mlx4_en_mac_to_u64(u8 *addr)
+u64 mlx4_en_mac_to_u64(u8 *addr)
{
u64 mac = 0;
int i;
@@ -513,6 +513,10 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
}
+ if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
+ queue_work(mdev->workqueue, &priv->mac_task);
+ mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
+ }
mutex_unlock(&mdev->state_lock);
}
@@ -528,10 +532,10 @@ static void mlx4_en_linkstate(struct work_struct *work)
* report to system log */
if (priv->last_link_state != linkstate) {
if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) {
- en_dbg(LINK, priv, "Link Down\n");
+ en_info(priv, "Link Down\n");
netif_carrier_off(priv->dev);
} else {
- en_dbg(LINK, priv, "Link Up\n");
+ en_info(priv, "Link Up\n");
netif_carrier_on(priv->dev);
}
}
@@ -653,6 +657,7 @@ int mlx4_en_start_port(struct net_device *dev)
en_err(priv, "Failed setting port mac\n");
goto tx_err;
}
+ mdev->mac_removed[priv->port] = 0;
/* Init port */
en_dbg(HW, priv, "Initializing port\n");
@@ -704,12 +709,12 @@ void mlx4_en_stop_port(struct net_device *dev)
netif_tx_stop_all_queues(dev);
netif_tx_unlock_bh(dev);
- /* close port*/
+ /* Set port as not active */
priv->port_up = false;
- mlx4_CLOSE_PORT(mdev->dev, priv->port);
/* Unregister Mac address for the port */
mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
+ mdev->mac_removed[priv->port] = 1;
/* Free TX Rings */
for (i = 0; i < priv->tx_ring_num; i++) {
@@ -731,6 +736,9 @@ void mlx4_en_stop_port(struct net_device *dev)
msleep(1);
mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]);
}
+
+ /* close port*/
+ mlx4_CLOSE_PORT(mdev->dev, priv->port);
}
static void mlx4_en_restart(struct work_struct *work)
@@ -1017,15 +1025,17 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
*/
dev->netdev_ops = &mlx4_netdev_ops;
dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
- dev->real_num_tx_queues = MLX4_EN_NUM_TX_RINGS;
+ netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
+ netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
/* Set defualt MAC */
dev->addr_len = ETH_ALEN;
- for (i = 0; i < ETH_ALEN; i++)
- dev->dev_addr[ETH_ALEN - 1 - i] =
- (u8) (priv->mac >> (8 * i));
+ for (i = 0; i < ETH_ALEN; i++) {
+ dev->dev_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i));
+ dev->perm_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i));
+ }
/*
* Set driver features
@@ -1038,8 +1048,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
dev->features |= NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
- if (mdev->profile.num_lro)
- dev->features |= NETIF_F_LRO;
+ dev->features |= NETIF_F_GRO;
if (mdev->LSO_support) {
dev->features |= NETIF_F_TSO;
dev->features |= NETIF_F_TSO6;
diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c
index a29abe845d2e..aa3ef2aee5bf 100644
--- a/drivers/net/mlx4/en_port.c
+++ b/drivers/net/mlx4/en_port.c
@@ -142,6 +142,38 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
return err;
}
+int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port)
+{
+ struct mlx4_en_query_port_context *qport_context;
+ struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]);
+ struct mlx4_en_port_state *state = &priv->port_state;
+ struct mlx4_cmd_mailbox *mailbox;
+ int err;
+
+ mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
+ if (IS_ERR(mailbox))
+ return PTR_ERR(mailbox);
+ memset(mailbox->buf, 0, sizeof(*qport_context));
+ err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, port, 0,
+ MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B);
+ if (err)
+ goto out;
+ qport_context = mailbox->buf;
+
+ /* This command is always accessed from Ethtool context
+ * already synchronized, no need in locking */
+ state->link_state = !!(qport_context->link_up & MLX4_EN_LINK_UP_MASK);
+ if ((qport_context->link_speed & MLX4_EN_SPEED_MASK) ==
+ MLX4_EN_1G_SPEED)
+ state->link_speed = 1000;
+ else
+ state->link_speed = 10000;
+ state->transciver = qport_context->transceiver;
+
+out:
+ mlx4_free_cmd_mailbox(mdev->dev, mailbox);
+ return err;
+}
int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
{
diff --git a/drivers/net/mlx4/en_port.h b/drivers/net/mlx4/en_port.h
index e6477f12beb5..f6511aa2b7df 100644
--- a/drivers/net/mlx4/en_port.h
+++ b/drivers/net/mlx4/en_port.h
@@ -84,6 +84,20 @@ enum {
MLX4_MCAST_ENABLE = 2,
};
+struct mlx4_en_query_port_context {
+ u8 link_up;
+#define MLX4_EN_LINK_UP_MASK 0x80
+ u8 reserved;
+ __be16 mtu;
+ u8 reserved2;
+ u8 link_speed;
+#define MLX4_EN_SPEED_MASK 0x3
+#define MLX4_EN_1G_SPEED 0x2
+ u16 reserved3[5];
+ __be64 mac;
+ u8 transceiver;
+};
+
struct mlx4_en_stat_out_mbox {
/* Received frames with a length of 64 octets */
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 8e2fcb7103c3..570f2508fb30 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -42,18 +42,6 @@
#include "mlx4_en.h"
-static int mlx4_en_get_frag_header(struct skb_frag_struct *frags, void **mac_hdr,
- void **ip_hdr, void **tcpudp_hdr,
- u64 *hdr_flags, void *priv)
-{
- *mac_hdr = page_address(frags->page) + frags->page_offset;
- *ip_hdr = *mac_hdr + ETH_HLEN;
- *tcpudp_hdr = (struct tcphdr *)(*ip_hdr + sizeof(struct iphdr));
- *hdr_flags = LRO_IPV4 | LRO_TCP;
-
- return 0;
-}
-
static int mlx4_en_alloc_frag(struct mlx4_en_priv *priv,
struct mlx4_en_rx_desc *rx_desc,
struct skb_frag_struct *skb_frags,
@@ -251,7 +239,6 @@ reduce_rings:
ring->prod--;
mlx4_en_free_rx_desc(priv, ring, ring->actual_size);
}
- ring->size_mask = ring->actual_size - 1;
}
return 0;
@@ -313,28 +300,8 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
}
ring->buf = ring->wqres.buf.direct.buf;
- /* Configure lro mngr */
- memset(&ring->lro, 0, sizeof(struct net_lro_mgr));
- ring->lro.dev = priv->dev;
- ring->lro.features = LRO_F_NAPI;
- ring->lro.frag_align_pad = NET_IP_ALIGN;
- ring->lro.ip_summed = CHECKSUM_UNNECESSARY;
- ring->lro.ip_summed_aggr = CHECKSUM_UNNECESSARY;
- ring->lro.max_desc = mdev->profile.num_lro;
- ring->lro.max_aggr = MAX_SKB_FRAGS;
- ring->lro.lro_arr = kzalloc(mdev->profile.num_lro *
- sizeof(struct net_lro_desc),
- GFP_KERNEL);
- if (!ring->lro.lro_arr) {
- en_err(priv, "Failed to allocate lro array\n");
- goto err_map;
- }
- ring->lro.get_frag_header = mlx4_en_get_frag_header;
-
return 0;
-err_map:
- mlx4_en_unmap_buffer(&ring->wqres.buf);
err_hwq:
mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
err_ring:
@@ -389,6 +356,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
ring = &priv->rx_ring[ring_ind];
+ ring->size_mask = ring->actual_size - 1;
mlx4_en_update_rx_prod_db(ring);
}
@@ -412,7 +380,6 @@ void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
{
struct mlx4_en_dev *mdev = priv->mdev;
- kfree(ring->lro.lro_arr);
mlx4_en_unmap_buffer(&ring->wqres.buf);
mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size + TXBB_SIZE);
vfree(ring->rx_info);
@@ -459,7 +426,7 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
goto fail;
/* Unmap buffer */
- pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
+ pci_unmap_single(mdev->pdev, dma, skb_frags_rx[nr].size,
PCI_DMA_FROMDEVICE);
}
/* Adjust size of last fragment to match actual length */
@@ -541,6 +508,21 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
return skb;
}
+static void validate_loopback(struct mlx4_en_priv *priv, struct sk_buff *skb)
+{
+ int i;
+ int offset = ETH_HLEN;
+
+ for (i = 0; i < MLX4_LOOPBACK_TEST_PAYLOAD; i++, offset++) {
+ if (*(skb->data + offset) != (unsigned char) (i & 0xff))
+ goto out_loopback;
+ }
+ /* Loopback found */
+ priv->loopback_ok = 1;
+
+out_loopback:
+ dev_kfree_skb_any(skb);
+}
int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget)
{
@@ -548,7 +530,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
struct mlx4_cqe *cqe;
struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring];
struct skb_frag_struct *skb_frags;
- struct skb_frag_struct lro_frags[MLX4_EN_MAX_RX_FRAGS];
struct mlx4_en_rx_desc *rx_desc;
struct sk_buff *skb;
int index;
@@ -608,37 +589,35 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
* - TCP/IP (v4)
* - without IP options
* - not an IP fragment */
- if (mlx4_en_can_lro(cqe->status) &&
- dev->features & NETIF_F_LRO) {
+ if (dev->features & NETIF_F_GRO) {
+ struct sk_buff *gro_skb = napi_get_frags(&cq->napi);
+ if (!gro_skb)
+ goto next;
nr = mlx4_en_complete_rx_desc(
priv, rx_desc,
- skb_frags, lro_frags,
+ skb_frags, skb_shinfo(gro_skb)->frags,
ring->page_alloc, length);
if (!nr)
goto next;
+ skb_shinfo(gro_skb)->nr_frags = nr;
+ gro_skb->len = length;
+ gro_skb->data_len = length;
+ gro_skb->truesize += length;
+ gro_skb->ip_summed = CHECKSUM_UNNECESSARY;
+
if (priv->vlgrp && (cqe->vlan_my_qpn &
- cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) {
- lro_vlan_hwaccel_receive_frags(
- &ring->lro, lro_frags,
- length, length,
- priv->vlgrp,
- be16_to_cpu(cqe->sl_vid),
- NULL, 0);
- } else
- lro_receive_frags(&ring->lro,
- lro_frags,
- length,
- length,
- NULL, 0);
+ cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK)))
+ vlan_gro_frags(&cq->napi, priv->vlgrp, be16_to_cpu(cqe->sl_vid));
+ else
+ napi_gro_frags(&cq->napi);
goto next;
}
/* LRO not possible, complete processing here */
ip_summed = CHECKSUM_UNNECESSARY;
- INC_PERF_COUNTER(priv->pstats.lro_misses);
} else {
ip_summed = CHECKSUM_NONE;
priv->port_stats.rx_chksum_none++;
@@ -655,6 +634,11 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
goto next;
}
+ if (unlikely(priv->validate_loopback)) {
+ validate_loopback(priv, skb);
+ goto next;
+ }
+
skb->ip_summed = ip_summed;
skb->protocol = eth_type_trans(skb, dev);
skb_record_rx_queue(skb, cq->ring);
@@ -674,14 +658,10 @@ next:
if (++polled == budget) {
/* We are here because we reached the NAPI budget -
* flush only pending LRO sessions */
- lro_flush_all(&ring->lro);
goto out;
}
}
- /* If CQ is empty flush all LRO sessions unconditionally */
- lro_flush_all(&ring->lro);
-
out:
AVG_PERF_COUNTER(priv->pstats.rx_coal_avg, polled);
mlx4_cq_set_ci(&cq->mcq);
@@ -816,7 +796,7 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
qp->event = mlx4_en_sqp_event;
memset(context, 0, sizeof *context);
- mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 0, 0,
+ mlx4_en_fill_qp_context(priv, ring->actual_size, ring->stride, 0, 0,
qpn, ring->cqn, context);
context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);
@@ -839,8 +819,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
struct mlx4_qp_context context;
struct mlx4_en_rss_context *rss_context;
void *ptr;
- int rss_xor = mdev->profile.rss_xor;
- u8 rss_mask = mdev->profile.rss_mask;
+ u8 rss_mask = 0x3f;
int i, qpn;
int err = 0;
int good_qps = 0;
@@ -886,9 +865,10 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 |
(rss_map->base_qpn));
rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn);
- rss_context->hash_fn = rss_xor & 0x3;
- rss_context->flags = rss_mask << 2;
+ rss_context->flags = rss_mask;
+ if (priv->mdev->profile.udp_rss)
+ rss_context->base_qpn_udp = rss_context->default_qpn;
err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context,
&rss_map->indir_qp, &rss_map->indir_state);
if (err)
diff --git a/drivers/net/mlx4/en_selftest.c b/drivers/net/mlx4/en_selftest.c
new file mode 100644
index 000000000000..9c91a92da705
--- /dev/null
+++ b/drivers/net/mlx4/en_selftest.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/ethtool.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/mlx4/driver.h>
+
+#include "mlx4_en.h"
+
+
+static int mlx4_en_test_registers(struct mlx4_en_priv *priv)
+{
+ return mlx4_cmd(priv->mdev->dev, 0, 0, 0, MLX4_CMD_HW_HEALTH_CHECK,
+ MLX4_CMD_TIME_CLASS_A);
+}
+
+static int mlx4_en_test_loopback_xmit(struct mlx4_en_priv *priv)
+{
+ struct sk_buff *skb;
+ struct ethhdr *ethh;
+ unsigned char *packet;
+ unsigned int packet_size = MLX4_LOOPBACK_TEST_PAYLOAD;
+ unsigned int i;
+ int err;
+
+
+ /* build the pkt before xmit */
+ skb = netdev_alloc_skb(priv->dev, MLX4_LOOPBACK_TEST_PAYLOAD + ETH_HLEN + NET_IP_ALIGN);
+ if (!skb) {
+ en_err(priv, "-LOOPBACK_TEST_XMIT- failed to create skb for xmit\n");
+ return -ENOMEM;
+ }
+ skb_reserve(skb, NET_IP_ALIGN);
+
+ ethh = (struct ethhdr *)skb_put(skb, sizeof(struct ethhdr));
+ packet = (unsigned char *)skb_put(skb, packet_size);
+ memcpy(ethh->h_dest, priv->dev->dev_addr, ETH_ALEN);
+ memset(ethh->h_source, 0, ETH_ALEN);
+ ethh->h_proto = htons(ETH_P_ARP);
+ skb_set_mac_header(skb, 0);
+ for (i = 0; i < packet_size; ++i) /* fill our packet */
+ packet[i] = (unsigned char)(i & 0xff);
+
+ /* xmit the pkt */
+ err = mlx4_en_xmit(skb, priv->dev);
+ return err;
+}
+
+static int mlx4_en_test_loopback(struct mlx4_en_priv *priv)
+{
+ u32 loopback_ok = 0;
+ int i;
+
+
+ priv->loopback_ok = 0;
+ priv->validate_loopback = 1;
+
+ /* xmit */
+ if (mlx4_en_test_loopback_xmit(priv)) {
+ en_err(priv, "Transmitting loopback packet failed\n");
+ goto mlx4_en_test_loopback_exit;
+ }
+
+ /* polling for result */
+ for (i = 0; i < MLX4_EN_LOOPBACK_RETRIES; ++i) {
+ msleep(MLX4_EN_LOOPBACK_TIMEOUT);
+ if (priv->loopback_ok) {
+ loopback_ok = 1;
+ break;
+ }
+ }
+ if (!loopback_ok)
+ en_err(priv, "Loopback packet didn't arrive\n");
+
+mlx4_en_test_loopback_exit:
+
+ priv->validate_loopback = 0;
+ return !loopback_ok;
+}
+
+
+static int mlx4_en_test_link(struct mlx4_en_priv *priv)
+{
+ if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
+ return -ENOMEM;
+ if (priv->port_state.link_state == 1)
+ return 0;
+ else
+ return 1;
+}
+
+static int mlx4_en_test_speed(struct mlx4_en_priv *priv)
+{
+
+ if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
+ return -ENOMEM;
+
+ /* The device currently only supports 10G speed */
+ if (priv->port_state.link_speed != SPEED_10000)
+ return priv->port_state.link_speed;
+ return 0;
+}
+
+
+void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ struct mlx4_en_dev *mdev = priv->mdev;
+ struct mlx4_en_tx_ring *tx_ring;
+ int i, carrier_ok;
+
+ memset(buf, 0, sizeof(u64) * MLX4_EN_NUM_SELF_TEST);
+
+ if (*flags & ETH_TEST_FL_OFFLINE) {
+ /* disable the interface */
+ carrier_ok = netif_carrier_ok(dev);
+
+ netif_carrier_off(dev);
+retry_tx:
+ /* Wait untill all tx queues are empty.
+ * there should not be any additional incoming traffic
+ * since we turned the carrier off */
+ msleep(200);
+ for (i = 0; i < priv->tx_ring_num && carrier_ok; i++) {
+ tx_ring = &priv->tx_ring[i];
+ if (tx_ring->prod != (tx_ring->cons + tx_ring->last_nr_txbb))
+ goto retry_tx;
+ }
+
+ if (priv->mdev->dev->caps.loopback_support){
+ buf[3] = mlx4_en_test_registers(priv);
+ buf[4] = mlx4_en_test_loopback(priv);
+ }
+
+ if (carrier_ok)
+ netif_carrier_on(dev);
+
+ }
+ buf[0] = mlx4_test_interrupts(mdev->dev);
+ buf[1] = mlx4_en_test_link(priv);
+ buf[2] = mlx4_en_test_speed(priv);
+
+ for (i = 0; i < MLX4_EN_NUM_SELF_TEST; i++) {
+ if (buf[i])
+ *flags |= ETH_TEST_FL_FAILED;
+ }
+}
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 580968f304eb..a680cd4a5ab6 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -38,6 +38,7 @@
#include <linux/skbuff.h>
#include <linux/if_vlan.h>
#include <linux/vmalloc.h>
+#include <linux/tcp.h>
#include "mlx4_en.h"
@@ -582,7 +583,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
/* If we support per priority flow control and the packet contains
* a vlan tag, send the packet to the TX ring assigned to that priority
*/
- if (priv->prof->rx_ppp && priv->vlgrp && vlan_tx_tag_present(skb)) {
+ if (priv->prof->rx_ppp && vlan_tx_tag_present(skb)) {
vlan_tag = vlan_tx_tag_get(skb);
return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13);
}
@@ -600,6 +601,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
struct mlx4_wqe_data_seg *data;
struct skb_frag_struct *frag;
struct mlx4_en_tx_info *tx_info;
+ struct ethhdr *ethh;
+ u64 mac;
+ u32 mac_l, mac_h;
int tx_ind = 0;
int nr_txbb;
int desc_size;
@@ -612,6 +616,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
int lso_header_size;
void *fragptr;
+ if (!priv->port_up)
+ goto tx_drop;
+
real_size = get_real_size(skb, dev, &lso_header_size);
if (unlikely(!real_size))
goto tx_drop;
@@ -627,7 +634,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
tx_ind = skb->queue_mapping;
ring = &priv->tx_ring[tx_ind];
- if (priv->vlgrp && vlan_tx_tag_present(skb))
+ if (vlan_tx_tag_present(skb))
vlan_tag = vlan_tx_tag_get(skb);
/* Check available TXBBs And 2K spare for prefetch */
@@ -676,6 +683,19 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
priv->port_stats.tx_chksum_offload++;
}
+ if (unlikely(priv->validate_loopback)) {
+ /* Copy dst mac address to wqe */
+ skb_reset_mac_header(skb);
+ ethh = eth_hdr(skb);
+ if (ethh && ethh->h_dest) {
+ mac = mlx4_en_mac_to_u64(ethh->h_dest);
+ mac_h = (u32) ((mac & 0xffff00000000ULL) >> 16);
+ mac_l = (u32) (mac & 0xffffffff);
+ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(mac_h);
+ tx_desc->ctrl.imm = cpu_to_be32(mac_l);
+ }
+ }
+
/* Handle LSO (TSO) packets */
if (lso_header_size) {
/* Mark opcode as LSO */
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 6d7b2bf210ce..552d0fce6f67 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -699,3 +699,47 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev)
kfree(priv->eq_table.uar_map);
}
+
+/* A test that verifies that we can accept interrupts on all
+ * the irq vectors of the device.
+ * Interrupts are checked using the NOP command.
+ */
+int mlx4_test_interrupts(struct mlx4_dev *dev)
+{
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ int i;
+ int err;
+
+ err = mlx4_NOP(dev);
+ /* When not in MSI_X, there is only one irq to check */
+ if (!(dev->flags & MLX4_FLAG_MSI_X))
+ return err;
+
+ /* A loop over all completion vectors, for each vector we will check
+ * whether it works by mapping command completions to that vector
+ * and performing a NOP command
+ */
+ for(i = 0; !err && (i < dev->caps.num_comp_vectors); ++i) {
+ /* Temporary use polling for command completions */
+ mlx4_cmd_use_polling(dev);
+
+ /* Map the new eq to handle all asyncronous events */
+ err = mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0,
+ priv->eq_table.eq[i].eqn);
+ if (err) {
+ mlx4_warn(dev, "Failed mapping eq for interrupt test\n");
+ mlx4_cmd_use_events(dev);
+ break;
+ }
+
+ /* Go back to using events */
+ mlx4_cmd_use_events(dev);
+ err = mlx4_NOP(dev);
+ }
+
+ /* Return to default */
+ mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0,
+ priv->eq_table.eq[dev->caps.num_comp_vectors].eqn);
+ return err;
+}
+EXPORT_SYMBOL(mlx4_test_interrupts);
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index 04f42ae1eda0..b716e1a1b298 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -141,6 +141,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
struct mlx4_cmd_mailbox *mailbox;
u32 *outbox;
u8 field;
+ u32 field32;
u16 size;
u16 stat_rate;
int err;
@@ -178,6 +179,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
#define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b
#define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c
#define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f
+#define QUERY_DEV_CAP_UDP_RSS_OFFSET 0x42
+#define QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET 0x43
#define QUERY_DEV_CAP_FLAGS_OFFSET 0x44
#define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48
#define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49
@@ -268,6 +271,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev_cap->max_msg_sz = 1 << (field & 0x1f);
MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET);
dev_cap->stat_rate_support = stat_rate;
+ MLX4_GET(field, outbox, QUERY_DEV_CAP_UDP_RSS_OFFSET);
+ dev_cap->udp_rss = field & 0x1;
+ MLX4_GET(field, outbox, QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET);
+ dev_cap->loopback_support = field & 0x1;
MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET);
dev_cap->reserved_uars = field >> 4;
@@ -365,6 +372,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
#define QUERY_PORT_MAX_MACVLAN_OFFSET 0x0a
#define QUERY_PORT_MAX_VL_OFFSET 0x0b
#define QUERY_PORT_MAC_OFFSET 0x10
+#define QUERY_PORT_TRANS_VENDOR_OFFSET 0x18
+#define QUERY_PORT_WAVELENGTH_OFFSET 0x1c
+#define QUERY_PORT_TRANS_CODE_OFFSET 0x20
for (i = 1; i <= dev_cap->num_ports; ++i) {
err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT,
@@ -388,6 +398,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev_cap->log_max_vlans[i] = field >> 4;
MLX4_GET(dev_cap->eth_mtu[i], outbox, QUERY_PORT_ETH_MTU_OFFSET);
MLX4_GET(dev_cap->def_mac[i], outbox, QUERY_PORT_MAC_OFFSET);
+ MLX4_GET(field32, outbox, QUERY_PORT_TRANS_VENDOR_OFFSET);
+ dev_cap->trans_type[i] = field32 >> 24;
+ dev_cap->vendor_oui[i] = field32 & 0xffffff;
+ MLX4_GET(dev_cap->wavelength[i], outbox, QUERY_PORT_WAVELENGTH_OFFSET);
+ MLX4_GET(dev_cap->trans_code[i], outbox, QUERY_PORT_TRANS_CODE_OFFSET);
}
}
diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h
index 526d7f30c041..65cc72eb899d 100644
--- a/drivers/net/mlx4/fw.h
+++ b/drivers/net/mlx4/fw.h
@@ -73,7 +73,13 @@ struct mlx4_dev_cap {
int max_pkeys[MLX4_MAX_PORTS + 1];
u64 def_mac[MLX4_MAX_PORTS + 1];
u16 eth_mtu[MLX4_MAX_PORTS + 1];
+ int trans_type[MLX4_MAX_PORTS + 1];
+ int vendor_oui[MLX4_MAX_PORTS + 1];
+ u16 wavelength[MLX4_MAX_PORTS + 1];
+ u64 trans_code[MLX4_MAX_PORTS + 1];
u16 stat_rate_support;
+ int udp_rss;
+ int loopback_support;
u32 flags;
int reserved_uars;
int uar_size;
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 5102ab1ac561..569fa3df381f 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -184,6 +184,10 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.eth_mtu_cap[i] = dev_cap->eth_mtu[i];
dev->caps.def_mac[i] = dev_cap->def_mac[i];
dev->caps.supported_type[i] = dev_cap->supported_port_types[i];
+ dev->caps.trans_type[i] = dev_cap->trans_type[i];
+ dev->caps.vendor_oui[i] = dev_cap->vendor_oui[i];
+ dev->caps.wavelength[i] = dev_cap->wavelength[i];
+ dev->caps.trans_code[i] = dev_cap->trans_code[i];
}
dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE;
@@ -221,6 +225,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.bmme_flags = dev_cap->bmme_flags;
dev->caps.reserved_lkey = dev_cap->reserved_lkey;
dev->caps.stat_rate_support = dev_cap->stat_rate_support;
+ dev->caps.udp_rss = dev_cap->udp_rss;
+ dev->caps.loopback_support = dev_cap->loopback_support;
dev->caps.max_gso_sz = dev_cap->max_gso_sz;
dev->caps.log_num_macs = log_num_mac;
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index 449210994ee9..1fc16ab7ad2f 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -38,19 +38,19 @@
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
-#include <linux/inet_lro.h>
#include <linux/mlx4/device.h>
#include <linux/mlx4/qp.h>
#include <linux/mlx4/cq.h>
#include <linux/mlx4/srq.h>
#include <linux/mlx4/doorbell.h>
+#include <linux/mlx4/cmd.h>
#include "en_port.h"
#define DRV_NAME "mlx4_en"
-#define DRV_VERSION "1.4.1.1"
-#define DRV_RELDATE "June 2009"
+#define DRV_VERSION "1.5.1.6"
+#define DRV_RELDATE "August 2010"
#define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN)
@@ -61,7 +61,6 @@
#define MLX4_EN_PAGE_SHIFT 12
#define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT)
-#define MAX_TX_RINGS 16
#define MAX_RX_RINGS 16
#define TXBB_SIZE 64
#define HEADROOM (2048 / TXBB_SIZE + 1)
@@ -107,6 +106,7 @@ enum {
#define MLX4_EN_SMALL_PKT_SIZE 64
#define MLX4_EN_NUM_TX_RINGS 8
#define MLX4_EN_NUM_PPP_RINGS 8
+#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS)
#define MLX4_EN_DEF_TX_RING_SIZE 512
#define MLX4_EN_DEF_RX_RING_SIZE 1024
@@ -139,10 +139,14 @@ enum {
#define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN)
#define HEADER_COPY_SIZE (128 - NET_IP_ALIGN)
+#define MLX4_LOOPBACK_TEST_PAYLOAD (HEADER_COPY_SIZE - ETH_HLEN)
#define MLX4_EN_MIN_MTU 46
#define ETH_BCAST 0xffffffffffffULL
+#define MLX4_EN_LOOPBACK_RETRIES 5
+#define MLX4_EN_LOOPBACK_TIMEOUT 100
+
#ifdef MLX4_EN_PERF_STAT
/* Number of samples to 'average' */
#define AVG_SIZE 128
@@ -249,7 +253,6 @@ struct mlx4_en_rx_desc {
struct mlx4_en_rx_ring {
struct mlx4_hwq_resources wqres;
struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS];
- struct net_lro_mgr lro;
u32 size ; /* number of Rx descs*/
u32 actual_size;
u32 size_mask;
@@ -313,7 +316,8 @@ struct mlx4_en_port_profile {
struct mlx4_en_profile {
int rss_xor;
- int num_lro;
+ int tcp_rss;
+ int udp_rss;
u8 rss_mask;
u32 active_ports;
u32 small_pkt_int;
@@ -337,6 +341,7 @@ struct mlx4_en_dev {
struct mlx4_mr mr;
u32 priv_pdn;
spinlock_t uar_lock;
+ u8 mac_removed[MLX4_MAX_PORTS + 1];
};
@@ -355,6 +360,13 @@ struct mlx4_en_rss_context {
u8 hash_fn;
u8 flags;
__be32 rss_key[10];
+ __be32 base_qpn_udp;
+};
+
+struct mlx4_en_port_state {
+ int link_state;
+ int link_speed;
+ int transciver;
};
struct mlx4_en_pkt_stats {
@@ -365,9 +377,6 @@ struct mlx4_en_pkt_stats {
};
struct mlx4_en_port_stats {
- unsigned long lro_aggregated;
- unsigned long lro_flushed;
- unsigned long lro_no_desc;
unsigned long tso_packets;
unsigned long queue_stopped;
unsigned long wake_queue;
@@ -376,7 +385,7 @@ struct mlx4_en_port_stats {
unsigned long rx_chksum_good;
unsigned long rx_chksum_none;
unsigned long tx_chksum_offload;
-#define NUM_PORT_STATS 11
+#define NUM_PORT_STATS 8
};
struct mlx4_en_perf_stats {
@@ -405,6 +414,7 @@ struct mlx4_en_priv {
struct vlan_group *vlgrp;
struct net_device_stats stats;
struct net_device_stats ret_stats;
+ struct mlx4_en_port_state port_state;
spinlock_t stats_lock;
unsigned long last_moder_packets;
@@ -423,6 +433,8 @@ struct mlx4_en_priv {
u16 sample_interval;
u16 adaptive_rx_coal;
u32 msg_enable;
+ u32 loopback_ok;
+ u32 validate_loopback;
struct mlx4_hwq_resources res;
int link_state;
@@ -531,6 +543,11 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
u8 promisc);
int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset);
+int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port);
+
+#define MLX4_EN_NUM_SELF_TEST 5
+void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf);
+u64 mlx4_en_mac_to_u64(u8 *addr);
/*
* Globals
@@ -555,6 +572,8 @@ do { \
en_print(KERN_WARNING, priv, format, ##arg)
#define en_err(priv, format, arg...) \
en_print(KERN_ERR, priv, format, ##arg)
+#define en_info(priv, format, arg...) \
+ en_print(KERN_INFO, priv, format, ## arg)
#define mlx4_err(mdev, format, arg...) \
pr_err("%s %s: " format, DRV_NAME, \
diff --git a/drivers/net/mlx4/profile.c b/drivers/net/mlx4/profile.c
index 5caf0115fa5b..e749f82865fe 100644
--- a/drivers/net/mlx4/profile.c
+++ b/drivers/net/mlx4/profile.c
@@ -85,7 +85,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
struct mlx4_resource tmp;
int i, j;
- profile = kzalloc(MLX4_RES_NUM * sizeof *profile, GFP_KERNEL);
+ profile = kcalloc(MLX4_RES_NUM, sizeof(*profile), GFP_KERNEL);
if (!profile)
return -ENOMEM;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 2d488abcf62d..dd2b6a71c6d7 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2901,7 +2901,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
mp->dev = dev;
set_params(mp, pd);
- dev->real_num_tx_queues = mp->txq_count;
+ netif_set_real_num_tx_queues(dev, mp->txq_count);
+ netif_set_real_num_rx_queues(dev, mp->rxq_count);
if (pd->phy_addr != MV643XX_ETH_PHY_NONE)
mp->phy = phy_scan(mp, pd->phy_addr);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index fb2c0927d3cc..8524cc40ec57 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -225,6 +225,7 @@ struct myri10ge_priv {
struct msix_entry *msix_vectors;
#ifdef CONFIG_MYRI10GE_DCA
int dca_enabled;
+ int relaxed_order;
#endif
u32 link_state;
unsigned int rdma_tags_available;
@@ -990,7 +991,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
* RX queues, so if we get an error, first retry using a
* single TX queue before giving up */
if (status != 0 && mgp->dev->real_num_tx_queues > 1) {
- mgp->dev->real_num_tx_queues = 1;
+ netif_set_real_num_tx_queues(mgp->dev, 1);
cmd.data0 = mgp->num_slices;
cmd.data1 = MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE;
status = myri10ge_send_cmd(mgp,
@@ -1074,10 +1075,28 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
}
#ifdef CONFIG_MYRI10GE_DCA
+static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on)
+{
+ int ret, cap, err;
+ u16 ctl;
+
+ cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ if (!cap)
+ return 0;
+
+ err = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
+ ret = (ctl & PCI_EXP_DEVCTL_RELAX_EN) >> 4;
+ if (ret != on) {
+ ctl &= ~PCI_EXP_DEVCTL_RELAX_EN;
+ ctl |= (on << 4);
+ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
+ }
+ return ret;
+}
+
static void
myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag)
{
- ss->cpu = cpu;
ss->cached_dca_tag = tag;
put_be32(htonl(tag), ss->dca_tag);
}
@@ -1088,9 +1107,10 @@ static inline void myri10ge_update_dca(struct myri10ge_slice_state *ss)
int tag;
if (cpu != ss->cpu) {
- tag = dca_get_tag(cpu);
+ tag = dca3_get_tag(&ss->mgp->pdev->dev, cpu);
if (ss->cached_dca_tag != tag)
myri10ge_write_dca(ss, cpu, tag);
+ ss->cpu = cpu;
}
put_cpu();
}
@@ -1113,9 +1133,13 @@ static void myri10ge_setup_dca(struct myri10ge_priv *mgp)
"dca_add_requester() failed, err=%d\n", err);
return;
}
+ mgp->relaxed_order = myri10ge_toggle_relaxed(pdev, 0);
mgp->dca_enabled = 1;
- for (i = 0; i < mgp->num_slices; i++)
- myri10ge_write_dca(&mgp->ss[i], -1, 0);
+ for (i = 0; i < mgp->num_slices; i++) {
+ mgp->ss[i].cpu = -1;
+ mgp->ss[i].cached_dca_tag = -1;
+ myri10ge_update_dca(&mgp->ss[i]);
+ }
}
static void myri10ge_teardown_dca(struct myri10ge_priv *mgp)
@@ -1126,6 +1150,8 @@ static void myri10ge_teardown_dca(struct myri10ge_priv *mgp)
if (!mgp->dca_enabled)
return;
mgp->dca_enabled = 0;
+ if (mgp->relaxed_order)
+ myri10ge_toggle_relaxed(pdev, 1);
err = dca_remove_requester(&pdev->dev);
}
@@ -1555,12 +1581,12 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
* valid since MSI-X irqs are not shared */
if ((mgp->dev->real_num_tx_queues == 1) && (ss != mgp->ss)) {
napi_schedule(&ss->napi);
- return (IRQ_HANDLED);
+ return IRQ_HANDLED;
}
/* make sure it is our IRQ, and that the DMA has finished */
if (unlikely(!stats->valid))
- return (IRQ_NONE);
+ return IRQ_NONE;
/* low bit indicates receives are present, so schedule
* napi poll handler */
@@ -1599,7 +1625,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
myri10ge_check_statblock(mgp);
put_be32(htonl(3), ss->irq_claim + 1);
- return (IRQ_HANDLED);
+ return IRQ_HANDLED;
}
static int
@@ -3753,8 +3779,8 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
* slices. We give up on MSI-X if we can only get a single
* vector. */
- mgp->msix_vectors = kzalloc(mgp->num_slices *
- sizeof(*mgp->msix_vectors), GFP_KERNEL);
+ mgp->msix_vectors = kcalloc(mgp->num_slices, sizeof(*mgp->msix_vectors),
+ GFP_KERNEL);
if (mgp->msix_vectors == NULL)
goto disable_msix;
for (i = 0; i < mgp->num_slices; i++) {
@@ -3923,7 +3949,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_err(&pdev->dev, "failed to alloc slice state\n");
goto abort_with_firmware;
}
- netdev->real_num_tx_queues = mgp->num_slices;
+ netif_set_real_num_tx_queues(netdev, mgp->num_slices);
+ netif_set_real_num_rx_queues(netdev, mgp->num_slices);
status = myri10ge_reset(mgp);
if (status != 0) {
dev_err(&pdev->dev, "failed reset\n");
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 617f898ba5f0..4846e131a04e 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -735,7 +735,7 @@ static int myri_header(struct sk_buff *skb, struct net_device *dev,
int i;
for (i = 0; i < dev->addr_len; i++)
eth->h_dest[i] = 0;
- return(dev->hard_header_len);
+ return dev->hard_header_len;
}
if (daddr) {
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index a6033d48b5cc..2fd39630b1e5 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -1570,7 +1570,7 @@ static int netdev_open(struct net_device *dev)
init_timer(&np->timer);
np->timer.expires = round_jiffies(jiffies + NATSEMI_TIMER_FREQ);
np->timer.data = (unsigned long)dev;
- np->timer.function = &netdev_timer; /* timer handler */
+ np->timer.function = netdev_timer; /* timer handler */
add_timer(&np->timer);
return 0;
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index ca142c47b2e4..94255f09093d 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -678,7 +678,14 @@ static int netconsole_netdev_event(struct notifier_block *this,
strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ);
break;
case NETDEV_UNREGISTER:
- netpoll_cleanup(&nt->np);
+ /*
+ * rtnl_lock already held
+ */
+ if (nt->np.dev) {
+ __netpoll_cleanup(&nt->np);
+ dev_put(nt->np.dev);
+ nt->np.dev = NULL;
+ }
/* Fall through */
case NETDEV_GOING_DOWN:
case NETDEV_BONDING_DESLAVE:
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 6dca3574e355..8e8a97839cb0 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -175,7 +175,10 @@
#define MAX_NUM_CARDS 4
#define MAX_BUFFERS_PER_CMD 32
-#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + 4)
+#define MAX_TSO_HEADER_DESC 2
+#define MGMT_CMD_DESC_RESV 4
+#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \
+ + MGMT_CMD_DESC_RESV)
#define NX_MAX_TX_TIMEOUTS 2
/*
@@ -1253,19 +1256,9 @@ struct netxen_adapter {
const struct firmware *fw;
};
-int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port);
-int netxen_niu_disable_xg_port(struct netxen_adapter *adapter);
-
int nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val);
int nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val);
-/* Functions available from netxen_nic_hw.c */
-int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
-int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu);
-
-int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
-int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
-
#define NXRD32(adapter, off) \
(adapter->crb_read(adapter, off))
#define NXWR32(adapter, off, val) \
@@ -1345,11 +1338,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
struct nx_host_rds_ring *rds_ring);
int netxen_process_cmd_ring(struct netxen_adapter *adapter);
int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max);
-void netxen_p2_nic_set_multi(struct net_device *netdev);
-void netxen_p3_nic_set_multi(struct net_device *netdev);
+
void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
-int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode);
-int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
int netxen_config_rss(struct netxen_adapter *adapter, int enable);
int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd);
@@ -1364,9 +1354,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable);
int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable);
int netxen_send_lro_cleanup(struct netxen_adapter *adapter);
-int netxen_nic_set_mac(struct net_device *netdev, void *p);
-struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
-
void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
struct nx_host_tx_ring *tx_ring);
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 29d7b93d0493..37d3ebd65be8 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -319,6 +319,8 @@ static unsigned crb_hub_agt[64] =
#define NETXEN_PCIE_SEM_TIMEOUT 10000
+static int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
+
int
netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg)
{
@@ -345,7 +347,7 @@ netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem)
NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
}
-int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
+static int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
{
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
@@ -356,7 +358,7 @@ int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
}
/* Disable an XG interface */
-int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
+static int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
{
__u32 mac_cfg;
u32 port = adapter->physical_port;
@@ -383,7 +385,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
#define MAC_LO(addr) \
((addr[5] << 16) | (addr[4] << 8) | (addr[3]))
-int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
+static int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
{
u32 mac_cfg;
u32 cnt = 0;
@@ -434,7 +436,7 @@ int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
return 0;
}
-int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
+static int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
{
u32 mac_hi, mac_lo;
u32 reg_hi, reg_lo;
@@ -531,7 +533,7 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
return 0;
}
-void netxen_p2_nic_set_multi(struct net_device *netdev)
+static void netxen_p2_nic_set_multi(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
struct netdev_hw_addr *ha;
@@ -598,8 +600,14 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
if (nr_desc >= netxen_tx_avail(tx_ring)) {
netif_tx_stop_queue(tx_ring->txq);
- __netif_tx_unlock_bh(tx_ring->txq);
- return -EBUSY;
+ smp_mb();
+ if (netxen_tx_avail(tx_ring) > nr_desc) {
+ if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH)
+ netif_tx_wake_queue(tx_ring->txq);
+ } else {
+ __netif_tx_unlock_bh(tx_ring->txq);
+ return -EBUSY;
+ }
}
do {
@@ -674,7 +682,7 @@ static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
cur->mac_addr, NETXEN_MAC_ADD);
}
-void netxen_p3_nic_set_multi(struct net_device *netdev)
+static void netxen_p3_nic_set_multi(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
struct netdev_hw_addr *ha;
@@ -721,7 +729,7 @@ send_fw_cmd:
}
}
-int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
+static int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
{
nx_nic_req_t req;
u64 word;
@@ -754,7 +762,7 @@ void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
}
}
-int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
+static int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
{
/* assuming caller has already copied new addr to netdev */
netxen_p3_nic_set_multi(adapter->netdev);
@@ -1816,14 +1824,14 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
if (netxen_rom_fast_read(adapter, offset, &board_type))
return -EIO;
- adapter->ahw.board_type = board_type;
-
if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I);
if ((gpio & 0x8000) == 0)
board_type = NETXEN_BRDTYPE_P3_10G_TP;
}
+ adapter->ahw.board_type = board_type;
+
switch (board_type) {
case NETXEN_BRDTYPE_P2_SB35_4G:
adapter->ahw.port_type = NETXEN_NIC_GBE;
@@ -1867,16 +1875,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
}
/* NIU access sections */
-
-int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
-{
- new_mtu += MTU_FUDGE_FACTOR;
- NXWR32(adapter, NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
- new_mtu);
- return 0;
-}
-
-int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
+static int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
{
new_mtu += MTU_FUDGE_FACTOR;
if (adapter->physical_port == 0)
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index b075a35b85d4..95fe552aa279 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -346,7 +346,7 @@ static u32 netxen_decode_crb_addr(u32 addr)
if (pci_base == NETXEN_ADDR_ERROR)
return pci_base;
else
- return (pci_base + offset);
+ return pci_base + offset;
}
#define NETXEN_MAX_ROM_WAIT_USEC 100
@@ -1763,14 +1763,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
smp_mb();
- if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
- __netif_tx_lock(tx_ring->txq, smp_processor_id());
- if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) {
+ if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev))
+ if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH)
netif_wake_queue(netdev);
- adapter->tx_timeo_cnt = 0;
- }
- __netif_tx_unlock(tx_ring->txq);
- }
+ adapter->tx_timeo_cnt = 0;
}
/*
* If everything is freed up to consumer then check if the ring is full
@@ -1789,7 +1785,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
done = (sw_consumer == hw_consumer);
spin_unlock(&adapter->tx_clean_lock);
- return (done);
+ return done;
}
void
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 73d314592230..50820beac3aa 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -95,6 +95,8 @@ static irqreturn_t netxen_msi_intr(int irq, void *data);
static irqreturn_t netxen_msix_intr(int irq, void *data);
static void netxen_config_indev_addr(struct net_device *dev, unsigned long);
+static struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
+static int netxen_nic_set_mac(struct net_device *netdev, void *p);
/* PCI Device ID Table */
#define ENTRY(device) \
@@ -125,11 +127,6 @@ netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
struct nx_host_tx_ring *tx_ring)
{
NXWRIO(adapter, tx_ring->crb_cmd_producer, tx_ring->producer);
-
- if (netxen_tx_avail(tx_ring) <= TX_STOP_THRESH) {
- netif_stop_queue(adapter->netdev);
- smp_mb();
- }
}
static uint32_t crb_cmd_consumer[4] = {
@@ -177,7 +174,7 @@ netxen_alloc_sds_rings(struct netxen_recv_context *recv_ctx, int count)
recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL);
- return (recv_ctx->sds_rings == NULL);
+ return recv_ctx->sds_rings == NULL;
}
static void
@@ -460,7 +457,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
return 0;
}
-int netxen_nic_set_mac(struct net_device *netdev, void *p)
+static int netxen_nic_set_mac(struct net_device *netdev, void *p)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
struct sockaddr *addr = p;
@@ -1209,7 +1206,7 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
adapter->max_mc_count = 16;
netdev->netdev_ops = &netxen_netdev_ops;
- netdev->watchdog_timeo = 2*HZ;
+ netdev->watchdog_timeo = 5*HZ;
netxen_nic_change_mtu(netdev, netdev->mtu);
@@ -1254,6 +1251,28 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
return 0;
}
+#ifdef CONFIG_PCIEAER
+static void netxen_mask_aer_correctable(struct netxen_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct pci_dev *root = pdev->bus->self;
+ u32 aer_pos;
+
+ if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM &&
+ adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP)
+ return;
+
+ if (root->pcie_type != PCI_EXP_TYPE_ROOT_PORT)
+ return;
+
+ aer_pos = pci_find_ext_capability(root, PCI_EXT_CAP_ID_ERR);
+ if (!aer_pos)
+ return;
+
+ pci_write_config_dword(root, aer_pos + PCI_ERR_COR_MASK, 0xffff);
+}
+#endif
+
static int __devinit
netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -1322,6 +1341,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_iounmap;
}
+#ifdef CONFIG_PCIEAER
+ netxen_mask_aer_correctable(adapter);
+#endif
+
/* Mezz cards have PCI function 0,2,3 enabled */
switch (adapter->ahw.board_type) {
case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
@@ -1825,9 +1848,13 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* 4 fragments per cmd des */
no_of_desc = (frag_count + 3) >> 2;
- if (unlikely(no_of_desc + 2 > netxen_tx_avail(tx_ring))) {
+ if (unlikely(netxen_tx_avail(tx_ring) <= TX_STOP_THRESH)) {
netif_stop_queue(netdev);
- return NETDEV_TX_BUSY;
+ smp_mb();
+ if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH)
+ netif_start_queue(netdev);
+ else
+ return NETDEV_TX_BUSY;
}
producer = tx_ring->producer;
@@ -2027,7 +2054,7 @@ request_reset:
clear_bit(__NX_RESETTING, &adapter->state);
}
-struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
+static struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
struct net_device_stats *stats = &netdev->stats;
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index fe6983af6918..781e368329f9 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -283,7 +283,7 @@ static int niu_enable_interrupts(struct niu *np, int on)
static u32 phy_encode(u32 type, int port)
{
- return (type << (port * 2));
+ return type << (port * 2);
}
static u32 phy_decode(u32 val, int port)
@@ -3043,8 +3043,7 @@ static int tcam_flush_all(struct niu *np)
static u64 hash_addr_regval(unsigned long index, unsigned long num_entries)
{
- return ((u64)index | (num_entries == 1 ?
- HASH_TBL_ADDR_AUTOINC : 0));
+ return (u64)index | (num_entries == 1 ? HASH_TBL_ADDR_AUTOINC : 0);
}
#if 0
@@ -3276,7 +3275,7 @@ static u16 tcam_get_index(struct niu *np, u16 idx)
/* One entry reserved for IP fragment rule */
if (idx >= (np->clas.tcam_sz - 1))
idx = 0;
- return (np->clas.tcam_top + ((idx+1) * np->parent->num_ports));
+ return np->clas.tcam_top + ((idx+1) * np->parent->num_ports);
}
static u16 tcam_get_size(struct niu *np)
@@ -3313,7 +3312,7 @@ static unsigned int niu_hash_rxaddr(struct rx_ring_info *rp, u64 a)
a >>= PAGE_SHIFT;
a ^= (a >> ilog2(MAX_RBR_RING_SIZE));
- return (a & (MAX_RBR_RING_SIZE - 1));
+ return a & (MAX_RBR_RING_SIZE - 1);
}
static struct page *niu_find_rxpage(struct rx_ring_info *rp, u64 addr,
@@ -3484,7 +3483,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,
RCR_ENTRY_ERROR)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
} else if (!(val & RCR_ENTRY_MULTI))
append_size = len - skb->len;
@@ -4502,9 +4501,10 @@ static int niu_alloc_channels(struct niu *np)
np->num_rx_rings = parent->rxchan_per_port[port];
np->num_tx_rings = parent->txchan_per_port[port];
- np->dev->real_num_tx_queues = np->num_tx_rings;
+ netif_set_real_num_rx_queues(np->dev, np->num_rx_rings);
+ netif_set_real_num_tx_queues(np->dev, np->num_tx_rings);
- np->rx_rings = kzalloc(np->num_rx_rings * sizeof(struct rx_ring_info),
+ np->rx_rings = kcalloc(np->num_rx_rings, sizeof(struct rx_ring_info),
GFP_KERNEL);
err = -ENOMEM;
if (!np->rx_rings)
@@ -4538,7 +4538,7 @@ static int niu_alloc_channels(struct niu *np)
return err;
}
- np->tx_rings = kzalloc(np->num_tx_rings * sizeof(struct tx_ring_info),
+ np->tx_rings = kcalloc(np->num_tx_rings, sizeof(struct tx_ring_info),
GFP_KERNEL);
err = -ENOMEM;
if (!np->tx_rings)
@@ -7090,24 +7090,20 @@ static int niu_get_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc)
static void niu_get_ip4fs_from_tcam_key(struct niu_tcam_entry *tp,
struct ethtool_rx_flow_spec *fsp)
{
+ u32 tmp;
+ u16 prt;
- fsp->h_u.tcp_ip4_spec.ip4src = (tp->key[3] & TCAM_V4KEY3_SADDR) >>
- TCAM_V4KEY3_SADDR_SHIFT;
- fsp->h_u.tcp_ip4_spec.ip4dst = (tp->key[3] & TCAM_V4KEY3_DADDR) >>
- TCAM_V4KEY3_DADDR_SHIFT;
- fsp->m_u.tcp_ip4_spec.ip4src = (tp->key_mask[3] & TCAM_V4KEY3_SADDR) >>
- TCAM_V4KEY3_SADDR_SHIFT;
- fsp->m_u.tcp_ip4_spec.ip4dst = (tp->key_mask[3] & TCAM_V4KEY3_DADDR) >>
- TCAM_V4KEY3_DADDR_SHIFT;
-
- fsp->h_u.tcp_ip4_spec.ip4src =
- cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4src);
- fsp->m_u.tcp_ip4_spec.ip4src =
- cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4src);
- fsp->h_u.tcp_ip4_spec.ip4dst =
- cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4dst);
- fsp->m_u.tcp_ip4_spec.ip4dst =
- cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4dst);
+ tmp = (tp->key[3] & TCAM_V4KEY3_SADDR) >> TCAM_V4KEY3_SADDR_SHIFT;
+ fsp->h_u.tcp_ip4_spec.ip4src = cpu_to_be32(tmp);
+
+ tmp = (tp->key[3] & TCAM_V4KEY3_DADDR) >> TCAM_V4KEY3_DADDR_SHIFT;
+ fsp->h_u.tcp_ip4_spec.ip4dst = cpu_to_be32(tmp);
+
+ tmp = (tp->key_mask[3] & TCAM_V4KEY3_SADDR) >> TCAM_V4KEY3_SADDR_SHIFT;
+ fsp->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(tmp);
+
+ tmp = (tp->key_mask[3] & TCAM_V4KEY3_DADDR) >> TCAM_V4KEY3_DADDR_SHIFT;
+ fsp->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(tmp);
fsp->h_u.tcp_ip4_spec.tos = (tp->key[2] & TCAM_V4KEY2_TOS) >>
TCAM_V4KEY2_TOS_SHIFT;
@@ -7118,54 +7114,40 @@ static void niu_get_ip4fs_from_tcam_key(struct niu_tcam_entry *tp,
case TCP_V4_FLOW:
case UDP_V4_FLOW:
case SCTP_V4_FLOW:
- fsp->h_u.tcp_ip4_spec.psrc =
- ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
- TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16;
- fsp->h_u.tcp_ip4_spec.pdst =
- ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
- TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff;
- fsp->m_u.tcp_ip4_spec.psrc =
- ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
- TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16;
- fsp->m_u.tcp_ip4_spec.pdst =
- ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
- TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff;
+ prt = ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16;
+ fsp->h_u.tcp_ip4_spec.psrc = cpu_to_be16(prt);
- fsp->h_u.tcp_ip4_spec.psrc =
- cpu_to_be16(fsp->h_u.tcp_ip4_spec.psrc);
- fsp->h_u.tcp_ip4_spec.pdst =
- cpu_to_be16(fsp->h_u.tcp_ip4_spec.pdst);
- fsp->m_u.tcp_ip4_spec.psrc =
- cpu_to_be16(fsp->m_u.tcp_ip4_spec.psrc);
- fsp->m_u.tcp_ip4_spec.pdst =
- cpu_to_be16(fsp->m_u.tcp_ip4_spec.pdst);
+ prt = ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff;
+ fsp->h_u.tcp_ip4_spec.pdst = cpu_to_be16(prt);
+
+ prt = ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16;
+ fsp->m_u.tcp_ip4_spec.psrc = cpu_to_be16(prt);
+
+ prt = ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff;
+ fsp->m_u.tcp_ip4_spec.pdst = cpu_to_be16(prt);
break;
case AH_V4_FLOW:
case ESP_V4_FLOW:
- fsp->h_u.ah_ip4_spec.spi =
- (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
- TCAM_V4KEY2_PORT_SPI_SHIFT;
- fsp->m_u.ah_ip4_spec.spi =
- (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ tmp = (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
TCAM_V4KEY2_PORT_SPI_SHIFT;
+ fsp->h_u.ah_ip4_spec.spi = cpu_to_be32(tmp);
- fsp->h_u.ah_ip4_spec.spi =
- cpu_to_be32(fsp->h_u.ah_ip4_spec.spi);
- fsp->m_u.ah_ip4_spec.spi =
- cpu_to_be32(fsp->m_u.ah_ip4_spec.spi);
+ tmp = (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT;
+ fsp->m_u.ah_ip4_spec.spi = cpu_to_be32(tmp);
break;
case IP_USER_FLOW:
- fsp->h_u.usr_ip4_spec.l4_4_bytes =
- (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
- TCAM_V4KEY2_PORT_SPI_SHIFT;
- fsp->m_u.usr_ip4_spec.l4_4_bytes =
- (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ tmp = (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
TCAM_V4KEY2_PORT_SPI_SHIFT;
+ fsp->h_u.usr_ip4_spec.l4_4_bytes = cpu_to_be32(tmp);
- fsp->h_u.usr_ip4_spec.l4_4_bytes =
- cpu_to_be32(fsp->h_u.usr_ip4_spec.l4_4_bytes);
- fsp->m_u.usr_ip4_spec.l4_4_bytes =
- cpu_to_be32(fsp->m_u.usr_ip4_spec.l4_4_bytes);
+ tmp = (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT;
+ fsp->m_u.usr_ip4_spec.l4_4_bytes = cpu_to_be32(tmp);
fsp->h_u.usr_ip4_spec.proto =
(tp->key[2] & TCAM_V4KEY2_PROTO) >>
@@ -7462,10 +7444,12 @@ static int niu_add_ethtool_tcam_entry(struct niu *np,
if (fsp->flow_type == IP_USER_FLOW) {
int i;
int add_usr_cls = 0;
- int ipv6 = 0;
struct ethtool_usrip4_spec *uspec = &fsp->h_u.usr_ip4_spec;
struct ethtool_usrip4_spec *umask = &fsp->m_u.usr_ip4_spec;
+ if (uspec->ip_ver != ETH_RX_NFC_IP4)
+ return -EINVAL;
+
niu_lock_parent(np, flags);
for (i = 0; i < NIU_L3_PROG_CLS; i++) {
@@ -7494,9 +7478,7 @@ static int niu_add_ethtool_tcam_entry(struct niu *np,
default:
break;
}
- if (uspec->ip_ver == ETH_RX_NFC_IP6)
- ipv6 = 1;
- ret = tcam_user_ip_class_set(np, class, ipv6,
+ ret = tcam_user_ip_class_set(np, class, 0,
uspec->proto,
uspec->tos,
umask->tos);
@@ -7553,16 +7535,7 @@ static int niu_add_ethtool_tcam_entry(struct niu *np,
ret = -EINVAL;
goto out;
case IP_USER_FLOW:
- if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4) {
- niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table,
- class);
- } else {
- /* Not yet implemented */
- netdev_info(np->dev, "niu%d: In %s(): usr flow for IPv6 not implemented\n",
- parent->index, __func__);
- ret = -EINVAL;
- goto out;
- }
+ niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table, class);
break;
default:
netdev_info(np->dev, "niu%d: In %s(): Unknown flow type %d\n",
@@ -7805,11 +7778,11 @@ static int niu_get_sset_count(struct net_device *dev, int stringset)
if (stringset != ETH_SS_STATS)
return -EINVAL;
- return ((np->flags & NIU_FLAGS_XMAC ?
+ return (np->flags & NIU_FLAGS_XMAC ?
NUM_XMAC_STAT_KEYS :
NUM_BMAC_STAT_KEYS) +
(np->num_rx_rings * NUM_RXCHAN_STAT_KEYS) +
- (np->num_tx_rings * NUM_TXCHAN_STAT_KEYS));
+ (np->num_tx_rings * NUM_TXCHAN_STAT_KEYS);
}
static void niu_get_ethtool_stats(struct net_device *dev,
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 5a3488f76b38..84134c766f3a 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -772,7 +772,7 @@ static int ns83820_setup_rx(struct net_device *ndev)
phy_intr(ndev);
/* Okay, let it rip */
- spin_lock_irq(&dev->misc_lock);
+ spin_lock(&dev->misc_lock);
dev->IMR_cache |= ISR_PHY;
dev->IMR_cache |= ISR_RXRCMP;
//dev->IMR_cache |= ISR_RXERR;
@@ -923,7 +923,7 @@ static void rx_irq(struct net_device *ndev)
if ((extsts & 0x002a0000) && !(extsts & 0x00540000)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
skb->protocol = eth_type_trans(skb, ndev);
#ifdef NS83820_VLAN_ACCEL_SUPPORT
@@ -1246,7 +1246,6 @@ static int ns83820_get_settings(struct net_device *ndev,
{
struct ns83820 *dev = PRIV(ndev);
u32 cfg, tanar, tbicr;
- int have_optical = 0;
int fullduplex = 0;
/*
@@ -1267,25 +1266,25 @@ static int ns83820_get_settings(struct net_device *ndev,
tanar = readl(dev->base + TANAR);
tbicr = readl(dev->base + TBICR);
- if (dev->CFG_cache & CFG_TBI_EN) {
- /* we have an optical interface */
- have_optical = 1;
- fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0;
-
- } else {
- /* We have copper */
- fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0;
- }
+ fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0;
cmd->supported = SUPPORTED_Autoneg;
- /* we have optical interface */
if (dev->CFG_cache & CFG_TBI_EN) {
+ /* we have optical interface */
cmd->supported |= SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE;
cmd->port = PORT_FIBRE;
- } /* TODO: else copper related support */
+ } else {
+ /* we have copper */
+ cmd->supported |= SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_MII;
+ cmd->port = PORT_MII;
+ }
cmd->duplex = fullduplex ? DUPLEX_FULL : DUPLEX_HALF;
switch (cfg / CFG_SPDSTS0 & 3) {
@@ -1299,7 +1298,8 @@ static int ns83820_get_settings(struct net_device *ndev,
cmd->speed = SPEED_10;
break;
}
- cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE) ? 1: 0;
+ cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE)
+ ? AUTONEG_ENABLE : AUTONEG_DISABLE;
return 0;
}
@@ -1405,6 +1405,13 @@ static const struct ethtool_ops ops = {
.get_link = ns83820_get_link
};
+static inline void ns83820_disable_interrupts(struct ns83820 *dev)
+{
+ writel(0, dev->base + IMR);
+ writel(0, dev->base + IER);
+ readl(dev->base + IER);
+}
+
/* this function is called in irq context from the ISR */
static void ns83820_mib_isr(struct ns83820 *dev)
{
@@ -1557,10 +1564,7 @@ static int ns83820_stop(struct net_device *ndev)
/* FIXME: protect against interrupt handler? */
del_timer_sync(&dev->tx_watchdog);
- /* disable interrupts */
- writel(0, dev->base + IMR);
- writel(0, dev->base + IER);
- readl(dev->base + IER);
+ ns83820_disable_interrupts(dev);
dev->rx_info.up = 0;
synchronize_irq(dev->pci_dev->irq);
@@ -2023,10 +2027,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev,
dev->tx_descs, (long)dev->tx_phy_descs,
dev->rx_info.descs, (long)dev->rx_info.phy_descs);
- /* disable interrupts */
- writel(0, dev->base + IMR);
- writel(0, dev->base + IER);
- readl(dev->base + IER);
+ ns83820_disable_interrupts(dev);
dev->IMR_cache = 0;
@@ -2250,9 +2251,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev,
return 0;
out_cleanup:
- writel(0, dev->base + IMR); /* paranoia */
- writel(0, dev->base + IER);
- readl(dev->base + IER);
+ ns83820_disable_interrupts(dev); /* paranoia */
out_free_irq:
rtnl_unlock();
free_irq(pci_dev->irq, ndev);
@@ -2277,9 +2276,7 @@ static void __devexit ns83820_remove_one(struct pci_dev *pci_dev)
if (!ndev) /* paranoia */
return;
- writel(0, dev->base + IMR); /* paranoia */
- writel(0, dev->base + IER);
- readl(dev->base + IER);
+ ns83820_disable_interrupts(dev); /* paranoia */
unregister_netdev(ndev);
free_irq(dev->pci_dev->irq, ndev);
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 8ab6ae0a6107..828e97cacdbf 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -808,7 +808,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx,
skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
XCT_MACRX_CSUM_S;
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
packets++;
tot_bytes += len;
diff --git a/drivers/net/pasemi_mac_ethtool.c b/drivers/net/pasemi_mac_ethtool.c
index fefa79e34b95..4825959a0efe 100644
--- a/drivers/net/pasemi_mac_ethtool.c
+++ b/drivers/net/pasemi_mac_ethtool.c
@@ -90,21 +90,6 @@ pasemi_mac_ethtool_set_settings(struct net_device *netdev,
return phy_ethtool_sset(phydev, cmd);
}
-static void
-pasemi_mac_ethtool_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *drvinfo)
-{
- struct pasemi_mac *mac;
- mac = netdev_priv(netdev);
-
- /* clear and fill out info */
- memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
- strncpy(drvinfo->driver, "pasemi_mac", 12);
- strcpy(drvinfo->version, "N/A");
- strcpy(drvinfo->fw_version, "N/A");
- strncpy(drvinfo->bus_info, pci_name(mac->pdev), 32);
-}
-
static u32
pasemi_mac_ethtool_get_msglevel(struct net_device *netdev)
{
@@ -164,7 +149,6 @@ static void pasemi_mac_get_strings(struct net_device *netdev, u32 stringset,
const struct ethtool_ops pasemi_mac_ethtool_ops = {
.get_settings = pasemi_mac_ethtool_get_settings,
.set_settings = pasemi_mac_ethtool_set_settings,
- .get_drvinfo = pasemi_mac_ethtool_get_drvinfo,
.get_msglevel = pasemi_mac_ethtool_get_msglevel,
.set_msglevel = pasemi_mac_ethtool_set_msglevel,
.get_link = ethtool_op_get_link,
diff --git a/drivers/net/pch_gbe/Makefile b/drivers/net/pch_gbe/Makefile
new file mode 100644
index 000000000000..31288d4ad248
--- /dev/null
+++ b/drivers/net/pch_gbe/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_PCH_GBE) += pch_gbe.o
+
+pch_gbe-y := pch_gbe_phy.o pch_gbe_ethtool.o pch_gbe_param.o
+pch_gbe-y += pch_gbe_api.o pch_gbe_main.o
diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h
new file mode 100644
index 000000000000..a0c26a99520f
--- /dev/null
+++ b/drivers/net/pch_gbe/pch_gbe.h
@@ -0,0 +1,659 @@
+/*
+ * Copyright (C) 1999 - 2010 Intel Corporation.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This code was derived from the Intel e1000e Linux driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _PCH_GBE_H_
+#define _PCH_GBE_H_
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/mii.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/vmalloc.h>
+#include <net/ip.h>
+#include <net/tcp.h>
+#include <net/udp.h>
+
+/**
+ * pch_gbe_regs_mac_adr - Structure holding values of mac address registers
+ * @high Denotes the 1st to 4th byte from the initial of MAC address
+ * @low Denotes the 5th to 6th byte from the initial of MAC address
+ */
+struct pch_gbe_regs_mac_adr {
+ u32 high;
+ u32 low;
+};
+/**
+ * pch_udc_regs - Structure holding values of MAC registers
+ */
+struct pch_gbe_regs {
+ u32 INT_ST;
+ u32 INT_EN;
+ u32 MODE;
+ u32 RESET;
+ u32 TCPIP_ACC;
+ u32 EX_LIST;
+ u32 INT_ST_HOLD;
+ u32 PHY_INT_CTRL;
+ u32 MAC_RX_EN;
+ u32 RX_FCTRL;
+ u32 PAUSE_REQ;
+ u32 RX_MODE;
+ u32 TX_MODE;
+ u32 RX_FIFO_ST;
+ u32 TX_FIFO_ST;
+ u32 TX_FID;
+ u32 TX_RESULT;
+ u32 PAUSE_PKT1;
+ u32 PAUSE_PKT2;
+ u32 PAUSE_PKT3;
+ u32 PAUSE_PKT4;
+ u32 PAUSE_PKT5;
+ u32 reserve[2];
+ struct pch_gbe_regs_mac_adr mac_adr[16];
+ u32 ADDR_MASK;
+ u32 MIIM;
+ u32 reserve2;
+ u32 RGMII_ST;
+ u32 RGMII_CTRL;
+ u32 reserve3[3];
+ u32 DMA_CTRL;
+ u32 reserve4[3];
+ u32 RX_DSC_BASE;
+ u32 RX_DSC_SIZE;
+ u32 RX_DSC_HW_P;
+ u32 RX_DSC_HW_P_HLD;
+ u32 RX_DSC_SW_P;
+ u32 reserve5[3];
+ u32 TX_DSC_BASE;
+ u32 TX_DSC_SIZE;
+ u32 TX_DSC_HW_P;
+ u32 TX_DSC_HW_P_HLD;
+ u32 TX_DSC_SW_P;
+ u32 reserve6[3];
+ u32 RX_DMA_ST;
+ u32 TX_DMA_ST;
+ u32 reserve7[2];
+ u32 WOL_ST;
+ u32 WOL_CTRL;
+ u32 WOL_ADDR_MASK;
+};
+
+/* Interrupt Status */
+/* Interrupt Status Hold */
+/* Interrupt Enable */
+#define PCH_GBE_INT_RX_DMA_CMPLT 0x00000001 /* Receive DMA Transfer Complete */
+#define PCH_GBE_INT_RX_VALID 0x00000002 /* MAC Normal Receive Complete */
+#define PCH_GBE_INT_RX_FRAME_ERR 0x00000004 /* Receive frame error */
+#define PCH_GBE_INT_RX_FIFO_ERR 0x00000008 /* Receive FIFO Overflow */
+#define PCH_GBE_INT_RX_DMA_ERR 0x00000010 /* Receive DMA Transfer Error */
+#define PCH_GBE_INT_RX_DSC_EMP 0x00000020 /* Receive Descriptor Empty */
+#define PCH_GBE_INT_TX_CMPLT 0x00000100 /* MAC Transmission Complete */
+#define PCH_GBE_INT_TX_DMA_CMPLT 0x00000200 /* DMA Transfer Complete */
+#define PCH_GBE_INT_TX_FIFO_ERR 0x00000400 /* Transmission FIFO underflow. */
+#define PCH_GBE_INT_TX_DMA_ERR 0x00000800 /* Transmission DMA Error */
+#define PCH_GBE_INT_PAUSE_CMPLT 0x00001000 /* Pause Transmission complete */
+#define PCH_GBE_INT_MIIM_CMPLT 0x00010000 /* MIIM I/F Read completion */
+#define PCH_GBE_INT_PHY_INT 0x00100000 /* Interruption from PHY */
+#define PCH_GBE_INT_WOL_DET 0x01000000 /* Wake On LAN Event detection. */
+#define PCH_GBE_INT_TCPIP_ERR 0x10000000 /* TCP/IP Accelerator Error */
+
+/* Mode */
+#define PCH_GBE_MODE_MII_ETHER 0x00000000 /* GIGA Ethernet Mode [MII] */
+#define PCH_GBE_MODE_GMII_ETHER 0x80000000 /* GIGA Ethernet Mode [GMII] */
+#define PCH_GBE_MODE_HALF_DUPLEX 0x00000000 /* Duplex Mode [half duplex] */
+#define PCH_GBE_MODE_FULL_DUPLEX 0x40000000 /* Duplex Mode [full duplex] */
+#define PCH_GBE_MODE_FR_BST 0x04000000 /* Frame bursting is done */
+
+/* Reset */
+#define PCH_GBE_ALL_RST 0x80000000 /* All reset */
+#define PCH_GBE_TX_RST 0x40000000 /* TX MAC, TX FIFO, TX DMA reset */
+#define PCH_GBE_RX_RST 0x04000000 /* RX MAC, RX FIFO, RX DMA reset */
+
+/* TCP/IP Accelerator Control */
+#define PCH_GBE_EX_LIST_EN 0x00000008 /* External List Enable */
+#define PCH_GBE_RX_TCPIPACC_OFF 0x00000004 /* RX TCP/IP ACC Disabled */
+#define PCH_GBE_TX_TCPIPACC_EN 0x00000002 /* TX TCP/IP ACC Enable */
+#define PCH_GBE_RX_TCPIPACC_EN 0x00000001 /* RX TCP/IP ACC Enable */
+
+/* MAC RX Enable */
+#define PCH_GBE_MRE_MAC_RX_EN 0x00000001 /* MAC Receive Enable */
+
+/* RX Flow Control */
+#define PCH_GBE_FL_CTRL_EN 0x80000000 /* Pause packet is enabled */
+
+/* Pause Packet Request */
+#define PCH_GBE_PS_PKT_RQ 0x80000000 /* Pause packet Request */
+
+/* RX Mode */
+#define PCH_GBE_ADD_FIL_EN 0x80000000 /* Address Filtering Enable */
+/* Multicast Filtering Enable */
+#define PCH_GBE_MLT_FIL_EN 0x40000000
+/* Receive Almost Empty Threshold */
+#define PCH_GBE_RH_ALM_EMP_4 0x00000000 /* 4 words */
+#define PCH_GBE_RH_ALM_EMP_8 0x00004000 /* 8 words */
+#define PCH_GBE_RH_ALM_EMP_16 0x00008000 /* 16 words */
+#define PCH_GBE_RH_ALM_EMP_32 0x0000C000 /* 32 words */
+/* Receive Almost Full Threshold */
+#define PCH_GBE_RH_ALM_FULL_4 0x00000000 /* 4 words */
+#define PCH_GBE_RH_ALM_FULL_8 0x00001000 /* 8 words */
+#define PCH_GBE_RH_ALM_FULL_16 0x00002000 /* 16 words */
+#define PCH_GBE_RH_ALM_FULL_32 0x00003000 /* 32 words */
+/* RX FIFO Read Triger Threshold */
+#define PCH_GBE_RH_RD_TRG_4 0x00000000 /* 4 words */
+#define PCH_GBE_RH_RD_TRG_8 0x00000200 /* 8 words */
+#define PCH_GBE_RH_RD_TRG_16 0x00000400 /* 16 words */
+#define PCH_GBE_RH_RD_TRG_32 0x00000600 /* 32 words */
+#define PCH_GBE_RH_RD_TRG_64 0x00000800 /* 64 words */
+#define PCH_GBE_RH_RD_TRG_128 0x00000A00 /* 128 words */
+#define PCH_GBE_RH_RD_TRG_256 0x00000C00 /* 256 words */
+#define PCH_GBE_RH_RD_TRG_512 0x00000E00 /* 512 words */
+
+/* Receive Descriptor bit definitions */
+#define PCH_GBE_RXD_ACC_STAT_BCAST 0x00000400
+#define PCH_GBE_RXD_ACC_STAT_MCAST 0x00000200
+#define PCH_GBE_RXD_ACC_STAT_UCAST 0x00000100
+#define PCH_GBE_RXD_ACC_STAT_TCPIPOK 0x000000C0
+#define PCH_GBE_RXD_ACC_STAT_IPOK 0x00000080
+#define PCH_GBE_RXD_ACC_STAT_TCPOK 0x00000040
+#define PCH_GBE_RXD_ACC_STAT_IP6ERR 0x00000020
+#define PCH_GBE_RXD_ACC_STAT_OFLIST 0x00000010
+#define PCH_GBE_RXD_ACC_STAT_TYPEIP 0x00000008
+#define PCH_GBE_RXD_ACC_STAT_MACL 0x00000004
+#define PCH_GBE_RXD_ACC_STAT_PPPOE 0x00000002
+#define PCH_GBE_RXD_ACC_STAT_VTAGT 0x00000001
+#define PCH_GBE_RXD_GMAC_STAT_PAUSE 0x0200
+#define PCH_GBE_RXD_GMAC_STAT_MARBR 0x0100
+#define PCH_GBE_RXD_GMAC_STAT_MARMLT 0x0080
+#define PCH_GBE_RXD_GMAC_STAT_MARIND 0x0040
+#define PCH_GBE_RXD_GMAC_STAT_MARNOTMT 0x0020
+#define PCH_GBE_RXD_GMAC_STAT_TLONG 0x0010
+#define PCH_GBE_RXD_GMAC_STAT_TSHRT 0x0008
+#define PCH_GBE_RXD_GMAC_STAT_NOTOCTAL 0x0004
+#define PCH_GBE_RXD_GMAC_STAT_NBLERR 0x0002
+#define PCH_GBE_RXD_GMAC_STAT_CRCERR 0x0001
+
+/* Transmit Descriptor bit definitions */
+#define PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF 0x0008
+#define PCH_GBE_TXD_CTRL_ITAG 0x0004
+#define PCH_GBE_TXD_CTRL_ICRC 0x0002
+#define PCH_GBE_TXD_CTRL_APAD 0x0001
+#define PCH_GBE_TXD_WORDS_SHIFT 2
+#define PCH_GBE_TXD_GMAC_STAT_CMPLT 0x2000
+#define PCH_GBE_TXD_GMAC_STAT_ABT 0x1000
+#define PCH_GBE_TXD_GMAC_STAT_EXCOL 0x0800
+#define PCH_GBE_TXD_GMAC_STAT_SNGCOL 0x0400
+#define PCH_GBE_TXD_GMAC_STAT_MLTCOL 0x0200
+#define PCH_GBE_TXD_GMAC_STAT_CRSER 0x0100
+#define PCH_GBE_TXD_GMAC_STAT_TLNG 0x0080
+#define PCH_GBE_TXD_GMAC_STAT_TSHRT 0x0040
+#define PCH_GBE_TXD_GMAC_STAT_LTCOL 0x0020
+#define PCH_GBE_TXD_GMAC_STAT_TFUNDFLW 0x0010
+#define PCH_GBE_TXD_GMAC_STAT_RTYCNT_MASK 0x000F
+
+/* TX Mode */
+#define PCH_GBE_TM_NO_RTRY 0x80000000 /* No Retransmission */
+#define PCH_GBE_TM_LONG_PKT 0x40000000 /* Long Packt TX Enable */
+#define PCH_GBE_TM_ST_AND_FD 0x20000000 /* Stare and Forward */
+#define PCH_GBE_TM_SHORT_PKT 0x10000000 /* Short Packet TX Enable */
+#define PCH_GBE_TM_LTCOL_RETX 0x08000000 /* Retransmission at Late Collision */
+/* Frame Start Threshold */
+#define PCH_GBE_TM_TH_TX_STRT_4 0x00000000 /* 4 words */
+#define PCH_GBE_TM_TH_TX_STRT_8 0x00004000 /* 8 words */
+#define PCH_GBE_TM_TH_TX_STRT_16 0x00008000 /* 16 words */
+#define PCH_GBE_TM_TH_TX_STRT_32 0x0000C000 /* 32 words */
+/* Transmit Almost Empty Threshold */
+#define PCH_GBE_TM_TH_ALM_EMP_4 0x00000000 /* 4 words */
+#define PCH_GBE_TM_TH_ALM_EMP_8 0x00000800 /* 8 words */
+#define PCH_GBE_TM_TH_ALM_EMP_16 0x00001000 /* 16 words */
+#define PCH_GBE_TM_TH_ALM_EMP_32 0x00001800 /* 32 words */
+#define PCH_GBE_TM_TH_ALM_EMP_64 0x00002000 /* 64 words */
+#define PCH_GBE_TM_TH_ALM_EMP_128 0x00002800 /* 128 words */
+#define PCH_GBE_TM_TH_ALM_EMP_256 0x00003000 /* 256 words */
+#define PCH_GBE_TM_TH_ALM_EMP_512 0x00003800 /* 512 words */
+/* Transmit Almost Full Threshold */
+#define PCH_GBE_TM_TH_ALM_FULL_4 0x00000000 /* 4 words */
+#define PCH_GBE_TM_TH_ALM_FULL_8 0x00000200 /* 8 words */
+#define PCH_GBE_TM_TH_ALM_FULL_16 0x00000400 /* 16 words */
+#define PCH_GBE_TM_TH_ALM_FULL_32 0x00000600 /* 32 words */
+
+/* RX FIFO Status */
+#define PCH_GBE_RF_ALM_FULL 0x80000000 /* RX FIFO is almost full. */
+#define PCH_GBE_RF_ALM_EMP 0x40000000 /* RX FIFO is almost empty. */
+#define PCH_GBE_RF_RD_TRG 0x20000000 /* Become more than RH_RD_TRG. */
+#define PCH_GBE_RF_STRWD 0x1FFE0000 /* The word count of RX FIFO. */
+#define PCH_GBE_RF_RCVING 0x00010000 /* Stored in RX FIFO. */
+
+/* MAC Address Mask */
+#define PCH_GBE_BUSY 0x80000000
+
+/* MIIM */
+#define PCH_GBE_MIIM_OPER_WRITE 0x04000000
+#define PCH_GBE_MIIM_OPER_READ 0x00000000
+#define PCH_GBE_MIIM_OPER_READY 0x04000000
+#define PCH_GBE_MIIM_PHY_ADDR_SHIFT 21
+#define PCH_GBE_MIIM_REG_ADDR_SHIFT 16
+
+/* RGMII Status */
+#define PCH_GBE_LINK_UP 0x80000008
+#define PCH_GBE_RXC_SPEED_MSK 0x00000006
+#define PCH_GBE_RXC_SPEED_2_5M 0x00000000 /* 2.5MHz */
+#define PCH_GBE_RXC_SPEED_25M 0x00000002 /* 25MHz */
+#define PCH_GBE_RXC_SPEED_125M 0x00000004 /* 100MHz */
+#define PCH_GBE_DUPLEX_FULL 0x00000001
+
+/* RGMII Control */
+#define PCH_GBE_CRS_SEL 0x00000010
+#define PCH_GBE_RGMII_RATE_125M 0x00000000
+#define PCH_GBE_RGMII_RATE_25M 0x00000008
+#define PCH_GBE_RGMII_RATE_2_5M 0x0000000C
+#define PCH_GBE_RGMII_MODE_GMII 0x00000000
+#define PCH_GBE_RGMII_MODE_RGMII 0x00000002
+#define PCH_GBE_CHIP_TYPE_EXTERNAL 0x00000000
+#define PCH_GBE_CHIP_TYPE_INTERNAL 0x00000001
+
+/* DMA Control */
+#define PCH_GBE_RX_DMA_EN 0x00000002 /* Enables Receive DMA */
+#define PCH_GBE_TX_DMA_EN 0x00000001 /* Enables Transmission DMA */
+
+/* Wake On LAN Status */
+#define PCH_GBE_WLS_BR 0x00000008 /* Broadcas Address */
+#define PCH_GBE_WLS_MLT 0x00000004 /* Multicast Address */
+
+/* The Frame registered in Address Recognizer */
+#define PCH_GBE_WLS_IND 0x00000002
+#define PCH_GBE_WLS_MP 0x00000001 /* Magic packet Address */
+
+/* Wake On LAN Control */
+#define PCH_GBE_WLC_WOL_MODE 0x00010000
+#define PCH_GBE_WLC_IGN_TLONG 0x00000100
+#define PCH_GBE_WLC_IGN_TSHRT 0x00000080
+#define PCH_GBE_WLC_IGN_OCTER 0x00000040
+#define PCH_GBE_WLC_IGN_NBLER 0x00000020
+#define PCH_GBE_WLC_IGN_CRCER 0x00000010
+#define PCH_GBE_WLC_BR 0x00000008
+#define PCH_GBE_WLC_MLT 0x00000004
+#define PCH_GBE_WLC_IND 0x00000002
+#define PCH_GBE_WLC_MP 0x00000001
+
+/* Wake On LAN Address Mask */
+#define PCH_GBE_WLA_BUSY 0x80000000
+
+
+
+/* TX/RX descriptor defines */
+#define PCH_GBE_MAX_TXD 4096
+#define PCH_GBE_DEFAULT_TXD 256
+#define PCH_GBE_MIN_TXD 8
+#define PCH_GBE_MAX_RXD 4096
+#define PCH_GBE_DEFAULT_RXD 256
+#define PCH_GBE_MIN_RXD 8
+
+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define PCH_GBE_TX_DESC_MULTIPLE 8
+#define PCH_GBE_RX_DESC_MULTIPLE 8
+
+/* Read/Write operation is done through MII Management IF */
+#define PCH_GBE_HAL_MIIM_READ ((u32)0x00000000)
+#define PCH_GBE_HAL_MIIM_WRITE ((u32)0x04000000)
+
+/* flow control values */
+#define PCH_GBE_FC_NONE 0
+#define PCH_GBE_FC_RX_PAUSE 1
+#define PCH_GBE_FC_TX_PAUSE 2
+#define PCH_GBE_FC_FULL 3
+#define PCH_GBE_FC_DEFAULT PCH_GBE_FC_FULL
+
+
+struct pch_gbe_hw;
+/**
+ * struct pch_gbe_functions - HAL APi function pointer
+ * @get_bus_info: for pch_gbe_hal_get_bus_info
+ * @init_hw: for pch_gbe_hal_init_hw
+ * @read_phy_reg: for pch_gbe_hal_read_phy_reg
+ * @write_phy_reg: for pch_gbe_hal_write_phy_reg
+ * @reset_phy: for pch_gbe_hal_phy_hw_reset
+ * @sw_reset_phy: for pch_gbe_hal_phy_sw_reset
+ * @power_up_phy: for pch_gbe_hal_power_up_phy
+ * @power_down_phy: for pch_gbe_hal_power_down_phy
+ * @read_mac_addr: for pch_gbe_hal_read_mac_addr
+ */
+struct pch_gbe_functions {
+ void (*get_bus_info) (struct pch_gbe_hw *);
+ s32 (*init_hw) (struct pch_gbe_hw *);
+ s32 (*read_phy_reg) (struct pch_gbe_hw *, u32, u16 *);
+ s32 (*write_phy_reg) (struct pch_gbe_hw *, u32, u16);
+ void (*reset_phy) (struct pch_gbe_hw *);
+ void (*sw_reset_phy) (struct pch_gbe_hw *);
+ void (*power_up_phy) (struct pch_gbe_hw *hw);
+ void (*power_down_phy) (struct pch_gbe_hw *hw);
+ s32 (*read_mac_addr) (struct pch_gbe_hw *);
+};
+
+/**
+ * struct pch_gbe_mac_info - MAC infomation
+ * @addr[6]: Store the MAC address
+ * @fc: Mode of flow control
+ * @fc_autoneg: Auto negotiation enable for flow control setting
+ * @tx_fc_enable: Enable flag of Transmit flow control
+ * @max_frame_size: Max transmit frame size
+ * @min_frame_size: Min transmit frame size
+ * @autoneg: Auto negotiation enable
+ * @link_speed: Link speed
+ * @link_duplex: Link duplex
+ */
+struct pch_gbe_mac_info {
+ u8 addr[6];
+ u8 fc;
+ u8 fc_autoneg;
+ u8 tx_fc_enable;
+ u32 max_frame_size;
+ u32 min_frame_size;
+ u8 autoneg;
+ u16 link_speed;
+ u16 link_duplex;
+};
+
+/**
+ * struct pch_gbe_phy_info - PHY infomation
+ * @addr: PHY address
+ * @id: PHY's identifier
+ * @revision: PHY's revision
+ * @reset_delay_us: HW reset delay time[us]
+ * @autoneg_advertised: Autoneg advertised
+ */
+struct pch_gbe_phy_info {
+ u32 addr;
+ u32 id;
+ u32 revision;
+ u32 reset_delay_us;
+ u16 autoneg_advertised;
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct pch_gbe_bus_info
+ * @brief Bus infomation
+ */
+struct pch_gbe_bus_info {
+ u8 type;
+ u8 speed;
+ u8 width;
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct pch_gbe_hw
+ * @brief Hardware infomation
+ */
+struct pch_gbe_hw {
+ void *back;
+
+ struct pch_gbe_regs __iomem *reg;
+ spinlock_t miim_lock;
+
+ const struct pch_gbe_functions *func;
+ struct pch_gbe_mac_info mac;
+ struct pch_gbe_phy_info phy;
+ struct pch_gbe_bus_info bus;
+};
+
+/**
+ * struct pch_gbe_rx_desc - Receive Descriptor
+ * @buffer_addr: RX Frame Buffer Address
+ * @tcp_ip_status: TCP/IP Accelerator Status
+ * @rx_words_eob: RX word count and Byte position
+ * @gbec_status: GMAC Status
+ * @dma_status: DMA Status
+ * @reserved1: Reserved
+ * @reserved2: Reserved
+ */
+struct pch_gbe_rx_desc {
+ u32 buffer_addr;
+ u32 tcp_ip_status;
+ u16 rx_words_eob;
+ u16 gbec_status;
+ u8 dma_status;
+ u8 reserved1;
+ u16 reserved2;
+};
+
+/**
+ * struct pch_gbe_tx_desc - Transmit Descriptor
+ * @buffer_addr: TX Frame Buffer Address
+ * @length: Data buffer length
+ * @reserved1: Reserved
+ * @tx_words_eob: TX word count and Byte position
+ * @tx_frame_ctrl: TX Frame Control
+ * @dma_status: DMA Status
+ * @reserved2: Reserved
+ * @gbec_status: GMAC Status
+ */
+struct pch_gbe_tx_desc {
+ u32 buffer_addr;
+ u16 length;
+ u16 reserved1;
+ u16 tx_words_eob;
+ u16 tx_frame_ctrl;
+ u8 dma_status;
+ u8 reserved2;
+ u16 gbec_status;
+};
+
+
+/**
+ * struct pch_gbe_buffer - Buffer infomation
+ * @skb: pointer to a socket buffer
+ * @dma: DMA address
+ * @time_stamp: time stamp
+ * @length: data size
+ */
+struct pch_gbe_buffer {
+ struct sk_buff *skb;
+ dma_addr_t dma;
+ unsigned long time_stamp;
+ u16 length;
+ bool mapped;
+};
+
+/**
+ * struct pch_gbe_tx_ring - tx ring infomation
+ * @tx_lock: spinlock structs
+ * @desc: pointer to the descriptor ring memory
+ * @dma: physical address of the descriptor ring
+ * @size: length of descriptor ring in bytes
+ * @count: number of descriptors in the ring
+ * @next_to_use: next descriptor to associate a buffer with
+ * @next_to_clean: next descriptor to check for DD status bit
+ * @buffer_info: array of buffer information structs
+ */
+struct pch_gbe_tx_ring {
+ spinlock_t tx_lock;
+ struct pch_gbe_tx_desc *desc;
+ dma_addr_t dma;
+ unsigned int size;
+ unsigned int count;
+ unsigned int next_to_use;
+ unsigned int next_to_clean;
+ struct pch_gbe_buffer *buffer_info;
+};
+
+/**
+ * struct pch_gbe_rx_ring - rx ring infomation
+ * @desc: pointer to the descriptor ring memory
+ * @dma: physical address of the descriptor ring
+ * @size: length of descriptor ring in bytes
+ * @count: number of descriptors in the ring
+ * @next_to_use: next descriptor to associate a buffer with
+ * @next_to_clean: next descriptor to check for DD status bit
+ * @buffer_info: array of buffer information structs
+ */
+struct pch_gbe_rx_ring {
+ struct pch_gbe_rx_desc *desc;
+ dma_addr_t dma;
+ unsigned int size;
+ unsigned int count;
+ unsigned int next_to_use;
+ unsigned int next_to_clean;
+ struct pch_gbe_buffer *buffer_info;
+};
+
+/**
+ * struct pch_gbe_hw_stats - Statistics counters collected by the MAC
+ * @rx_packets: total packets received
+ * @tx_packets: total packets transmitted
+ * @rx_bytes: total bytes received
+ * @tx_bytes: total bytes transmitted
+ * @rx_errors: bad packets received
+ * @tx_errors: packet transmit problems
+ * @rx_dropped: no space in Linux buffers
+ * @tx_dropped: no space available in Linux
+ * @multicast: multicast packets received
+ * @collisions: collisions
+ * @rx_crc_errors: received packet with crc error
+ * @rx_frame_errors: received frame alignment error
+ * @rx_alloc_buff_failed: allocate failure of a receive buffer
+ * @tx_length_errors: transmit length error
+ * @tx_aborted_errors: transmit aborted error
+ * @tx_carrier_errors: transmit carrier error
+ * @tx_timeout_count: Number of transmit timeout
+ * @tx_restart_count: Number of transmit restert
+ * @intr_rx_dsc_empty_count: Interrupt count of receive descriptor empty
+ * @intr_rx_frame_err_count: Interrupt count of receive frame error
+ * @intr_rx_fifo_err_count: Interrupt count of receive FIFO error
+ * @intr_rx_dma_err_count: Interrupt count of receive DMA error
+ * @intr_tx_fifo_err_count: Interrupt count of transmit FIFO error
+ * @intr_tx_dma_err_count: Interrupt count of transmit DMA error
+ * @intr_tcpip_err_count: Interrupt count of TCP/IP Accelerator
+ */
+struct pch_gbe_hw_stats {
+ u32 rx_packets;
+ u32 tx_packets;
+ u32 rx_bytes;
+ u32 tx_bytes;
+ u32 rx_errors;
+ u32 tx_errors;
+ u32 rx_dropped;
+ u32 tx_dropped;
+ u32 multicast;
+ u32 collisions;
+ u32 rx_crc_errors;
+ u32 rx_frame_errors;
+ u32 rx_alloc_buff_failed;
+ u32 tx_length_errors;
+ u32 tx_aborted_errors;
+ u32 tx_carrier_errors;
+ u32 tx_timeout_count;
+ u32 tx_restart_count;
+ u32 intr_rx_dsc_empty_count;
+ u32 intr_rx_frame_err_count;
+ u32 intr_rx_fifo_err_count;
+ u32 intr_rx_dma_err_count;
+ u32 intr_tx_fifo_err_count;
+ u32 intr_tx_dma_err_count;
+ u32 intr_tcpip_err_count;
+};
+
+/**
+ * struct pch_gbe_adapter - board specific private data structure
+ * @stats_lock: Spinlock structure for status
+ * @tx_queue_lock: Spinlock structure for transmit
+ * @ethtool_lock: Spinlock structure for ethtool
+ * @irq_sem: Semaphore for interrupt
+ * @netdev: Pointer of network device structure
+ * @pdev: Pointer of pci device structure
+ * @polling_netdev: Pointer of polling network device structure
+ * @napi: NAPI structure
+ * @hw: Pointer of hardware structure
+ * @stats: Hardware status
+ * @reset_task: Reset task
+ * @mii: MII information structure
+ * @watchdog_timer: Watchdog timer list
+ * @wake_up_evt: Wake up event
+ * @config_space: Configuration space
+ * @msg_enable: Driver message level
+ * @led_status: LED status
+ * @tx_ring: Pointer of Tx descriptor ring structure
+ * @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
+ */
+
+struct pch_gbe_adapter {
+ spinlock_t stats_lock;
+ spinlock_t tx_queue_lock;
+ spinlock_t ethtool_lock;
+ atomic_t irq_sem;
+ struct net_device *netdev;
+ struct pci_dev *pdev;
+ struct net_device *polling_netdev;
+ struct napi_struct napi;
+ struct pch_gbe_hw hw;
+ struct pch_gbe_hw_stats stats;
+ struct work_struct reset_task;
+ struct mii_if_info mii;
+ struct timer_list watchdog_timer;
+ u32 wake_up_evt;
+ u32 *config_space;
+ unsigned long led_status;
+ struct pch_gbe_tx_ring *tx_ring;
+ 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;
+};
+
+extern const char pch_driver_version[];
+
+/* pch_gbe_main.c */
+extern int pch_gbe_up(struct pch_gbe_adapter *adapter);
+extern void pch_gbe_down(struct pch_gbe_adapter *adapter);
+extern void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter);
+extern void pch_gbe_reset(struct pch_gbe_adapter *adapter);
+extern int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_tx_ring *txdr);
+extern int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_rx_ring *rxdr);
+extern void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_tx_ring *tx_ring);
+extern void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_rx_ring *rx_ring);
+extern void pch_gbe_update_stats(struct pch_gbe_adapter *adapter);
+
+/* pch_gbe_param.c */
+extern void pch_gbe_check_options(struct pch_gbe_adapter *adapter);
+
+/* pch_gbe_ethtool.c */
+extern void pch_gbe_set_ethtool_ops(struct net_device *netdev);
+
+/* pch_gbe_mac.c */
+extern s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw);
+extern s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw);
+extern u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw,
+ u32 addr, u32 dir, u32 reg, u16 data);
+#endif /* _PCH_GBE_H_ */
diff --git a/drivers/net/pch_gbe/pch_gbe_api.c b/drivers/net/pch_gbe/pch_gbe_api.c
new file mode 100644
index 000000000000..e48f084ad226
--- /dev/null
+++ b/drivers/net/pch_gbe/pch_gbe_api.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 1999 - 2010 Intel Corporation.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This code was derived from the Intel e1000e Linux driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include "pch_gbe.h"
+#include "pch_gbe_phy.h"
+
+/* bus type values */
+#define pch_gbe_bus_type_unknown 0
+#define pch_gbe_bus_type_pci 1
+#define pch_gbe_bus_type_pcix 2
+#define pch_gbe_bus_type_pci_express 3
+#define pch_gbe_bus_type_reserved 4
+
+/* bus speed values */
+#define pch_gbe_bus_speed_unknown 0
+#define pch_gbe_bus_speed_33 1
+#define pch_gbe_bus_speed_66 2
+#define pch_gbe_bus_speed_100 3
+#define pch_gbe_bus_speed_120 4
+#define pch_gbe_bus_speed_133 5
+#define pch_gbe_bus_speed_2500 6
+#define pch_gbe_bus_speed_reserved 7
+
+/* bus width values */
+#define pch_gbe_bus_width_unknown 0
+#define pch_gbe_bus_width_pcie_x1 1
+#define pch_gbe_bus_width_pcie_x2 2
+#define pch_gbe_bus_width_pcie_x4 4
+#define pch_gbe_bus_width_32 5
+#define pch_gbe_bus_width_64 6
+#define pch_gbe_bus_width_reserved 7
+
+/**
+ * pch_gbe_plat_get_bus_info - Obtain bus information for adapter
+ * @hw: Pointer to the HW structure
+ */
+static void pch_gbe_plat_get_bus_info(struct pch_gbe_hw *hw)
+{
+ hw->bus.type = pch_gbe_bus_type_pci_express;
+ hw->bus.speed = pch_gbe_bus_speed_2500;
+ hw->bus.width = pch_gbe_bus_width_pcie_x1;
+}
+
+/**
+ * pch_gbe_plat_init_hw - Initialize hardware
+ * @hw: Pointer to the HW structure
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed-EBUSY
+ */
+static s32 pch_gbe_plat_init_hw(struct pch_gbe_hw *hw)
+{
+ s32 ret_val;
+
+ ret_val = pch_gbe_phy_get_id(hw);
+ if (ret_val) {
+ pr_err("pch_gbe_phy_get_id error\n");
+ return ret_val;
+ }
+ pch_gbe_phy_init_setting(hw);
+ /* Setup Mac interface option RGMII */
+#ifdef PCH_GBE_MAC_IFOP_RGMII
+ pch_gbe_phy_set_rgmii(hw);
+#endif
+ return ret_val;
+}
+
+static const struct pch_gbe_functions pch_gbe_ops = {
+ .get_bus_info = pch_gbe_plat_get_bus_info,
+ .init_hw = pch_gbe_plat_init_hw,
+ .read_phy_reg = pch_gbe_phy_read_reg_miic,
+ .write_phy_reg = pch_gbe_phy_write_reg_miic,
+ .reset_phy = pch_gbe_phy_hw_reset,
+ .sw_reset_phy = pch_gbe_phy_sw_reset,
+ .power_up_phy = pch_gbe_phy_power_up,
+ .power_down_phy = pch_gbe_phy_power_down,
+ .read_mac_addr = pch_gbe_mac_read_mac_addr
+};
+
+/**
+ * pch_gbe_plat_init_function_pointers - Init func ptrs
+ * @hw: Pointer to the HW structure
+ */
+static void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw)
+{
+ /* Set PHY parameter */
+ hw->phy.reset_delay_us = PCH_GBE_PHY_RESET_DELAY_US;
+ /* Set function pointers */
+ hw->func = &pch_gbe_ops;
+}
+
+/**
+ * pch_gbe_hal_setup_init_funcs - Initializes function pointers
+ * @hw: Pointer to the HW structure
+ * Returns
+ * 0: Successfully
+ * ENOSYS: Function is not registered
+ */
+inline s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw)
+{
+ if (!hw->reg) {
+ pr_err("ERROR: Registers not mapped\n");
+ return -ENOSYS;
+ }
+ pch_gbe_plat_init_function_pointers(hw);
+ return 0;
+}
+
+/**
+ * pch_gbe_hal_get_bus_info - Obtain bus information for adapter
+ * @hw: Pointer to the HW structure
+ */
+inline void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw)
+{
+ if (!hw->func->get_bus_info)
+ pr_err("ERROR: configuration\n");
+ else
+ hw->func->get_bus_info(hw);
+}
+
+/**
+ * pch_gbe_hal_init_hw - Initialize hardware
+ * @hw: Pointer to the HW structure
+ * Returns
+ * 0: Successfully
+ * ENOSYS: Function is not registered
+ */
+inline s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw)
+{
+ if (!hw->func->init_hw) {
+ pr_err("ERROR: configuration\n");
+ return -ENOSYS;
+ }
+ return hw->func->init_hw(hw);
+}
+
+/**
+ * pch_gbe_hal_read_phy_reg - Reads PHY register
+ * @hw: Pointer to the HW structure
+ * @offset: The register to read
+ * @data: The buffer to store the 16-bit read.
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+inline s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset,
+ u16 *data)
+{
+ if (!hw->func->read_phy_reg)
+ return 0;
+ return hw->func->read_phy_reg(hw, offset, data);
+}
+
+/**
+ * pch_gbe_hal_write_phy_reg - Writes PHY register
+ * @hw: Pointer to the HW structure
+ * @offset: The register to read
+ * @data: The value to write.
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+inline s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset,
+ u16 data)
+{
+ if (!hw->func->write_phy_reg)
+ return 0;
+ return hw->func->write_phy_reg(hw, offset, data);
+}
+
+/**
+ * pch_gbe_hal_phy_hw_reset - Hard PHY reset
+ * @hw: Pointer to the HW structure
+ */
+inline void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw)
+{
+ if (!hw->func->reset_phy)
+ pr_err("ERROR: configuration\n");
+ else
+ hw->func->reset_phy(hw);
+}
+
+/**
+ * pch_gbe_hal_phy_sw_reset - Soft PHY reset
+ * @hw: Pointer to the HW structure
+ */
+inline void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw)
+{
+ if (!hw->func->sw_reset_phy)
+ pr_err("ERROR: configuration\n");
+ else
+ hw->func->sw_reset_phy(hw);
+}
+
+/**
+ * pch_gbe_hal_read_mac_addr - Reads MAC address
+ * @hw: Pointer to the HW structure
+ * Returns
+ * 0: Successfully
+ * ENOSYS: Function is not registered
+ */
+inline s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw)
+{
+ if (!hw->func->read_mac_addr) {
+ pr_err("ERROR: configuration\n");
+ return -ENOSYS;
+ }
+ return hw->func->read_mac_addr(hw);
+}
+
+/**
+ * pch_gbe_hal_power_up_phy - Power up PHY
+ * @hw: Pointer to the HW structure
+ */
+inline void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw)
+{
+ if (hw->func->power_up_phy)
+ hw->func->power_up_phy(hw);
+}
+
+/**
+ * pch_gbe_hal_power_down_phy - Power down PHY
+ * @hw: Pointer to the HW structure
+ */
+inline void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw)
+{
+ if (hw->func->power_down_phy)
+ hw->func->power_down_phy(hw);
+}
diff --git a/drivers/net/pch_gbe/pch_gbe_api.h b/drivers/net/pch_gbe/pch_gbe_api.h
new file mode 100644
index 000000000000..94aaac5b057b
--- /dev/null
+++ b/drivers/net/pch_gbe/pch_gbe_api.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 1999 - 2010 Intel Corporation.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This code was derived from the Intel e1000e Linux driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef _PCH_GBE_API_H_
+#define _PCH_GBE_API_H_
+
+#include "pch_gbe_phy.h"
+
+s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw);
+void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw);
+s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw);
+s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 *data);
+s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 data);
+void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw);
+void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw);
+s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw);
+void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw);
+void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw);
+
+#endif
diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c
new file mode 100644
index 000000000000..c8cc32c0edc9
--- /dev/null
+++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 1999 - 2010 Intel Corporation.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This code was derived from the Intel e1000e Linux driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include "pch_gbe.h"
+#include "pch_gbe_api.h"
+
+/**
+ * pch_gbe_stats - Stats item infomation
+ */
+struct pch_gbe_stats {
+ char string[ETH_GSTRING_LEN];
+ size_t size;
+ size_t offset;
+};
+
+#define PCH_GBE_STAT(m) \
+{ \
+ .string = #m, \
+ .size = FIELD_SIZEOF(struct pch_gbe_hw_stats, m), \
+ .offset = offsetof(struct pch_gbe_hw_stats, m), \
+}
+
+/**
+ * pch_gbe_gstrings_stats - ethtool information status name list
+ */
+static const struct pch_gbe_stats pch_gbe_gstrings_stats[] = {
+ PCH_GBE_STAT(rx_packets),
+ PCH_GBE_STAT(tx_packets),
+ PCH_GBE_STAT(rx_bytes),
+ PCH_GBE_STAT(tx_bytes),
+ PCH_GBE_STAT(rx_errors),
+ PCH_GBE_STAT(tx_errors),
+ PCH_GBE_STAT(rx_dropped),
+ PCH_GBE_STAT(tx_dropped),
+ PCH_GBE_STAT(multicast),
+ PCH_GBE_STAT(collisions),
+ PCH_GBE_STAT(rx_crc_errors),
+ PCH_GBE_STAT(rx_frame_errors),
+ PCH_GBE_STAT(rx_alloc_buff_failed),
+ PCH_GBE_STAT(tx_length_errors),
+ PCH_GBE_STAT(tx_aborted_errors),
+ PCH_GBE_STAT(tx_carrier_errors),
+ PCH_GBE_STAT(tx_timeout_count),
+ PCH_GBE_STAT(tx_restart_count),
+ PCH_GBE_STAT(intr_rx_dsc_empty_count),
+ PCH_GBE_STAT(intr_rx_frame_err_count),
+ PCH_GBE_STAT(intr_rx_fifo_err_count),
+ PCH_GBE_STAT(intr_rx_dma_err_count),
+ PCH_GBE_STAT(intr_tx_fifo_err_count),
+ PCH_GBE_STAT(intr_tx_dma_err_count),
+ PCH_GBE_STAT(intr_tcpip_err_count)
+};
+
+#define PCH_GBE_QUEUE_STATS_LEN 0
+#define PCH_GBE_GLOBAL_STATS_LEN ARRAY_SIZE(pch_gbe_gstrings_stats)
+#define PCH_GBE_STATS_LEN (PCH_GBE_GLOBAL_STATS_LEN + PCH_GBE_QUEUE_STATS_LEN)
+
+#define PCH_GBE_MAC_REGS_LEN (sizeof(struct pch_gbe_regs) / 4)
+#define PCH_GBE_REGS_LEN (PCH_GBE_MAC_REGS_LEN + PCH_GBE_PHY_REGS_LEN)
+/**
+ * pch_gbe_get_settings - Get device-specific settings
+ * @netdev: Network interface device structure
+ * @ecmd: Ethtool command
+ * Returns
+ * 0: Successful.
+ * Negative value: Failed.
+ */
+static int pch_gbe_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ int ret;
+
+ ret = mii_ethtool_gset(&adapter->mii, ecmd);
+ ecmd->supported &= ~(SUPPORTED_TP | SUPPORTED_1000baseT_Half);
+ ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half);
+
+ if (!netif_carrier_ok(adapter->netdev))
+ ecmd->speed = -1;
+ return ret;
+}
+
+/**
+ * pch_gbe_set_settings - Set device-specific settings
+ * @netdev: Network interface device structure
+ * @ecmd: Ethtool command
+ * Returns
+ * 0: Successful.
+ * Negative value: Failed.
+ */
+static int pch_gbe_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+ int ret;
+
+ pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET);
+
+ if (ecmd->speed == USHRT_MAX) {
+ ecmd->speed = SPEED_1000;
+ ecmd->duplex = DUPLEX_FULL;
+ }
+ ret = mii_ethtool_sset(&adapter->mii, ecmd);
+ if (ret) {
+ pr_err("Error: mii_ethtool_sset\n");
+ return ret;
+ }
+ hw->mac.link_speed = ecmd->speed;
+ hw->mac.link_duplex = ecmd->duplex;
+ hw->phy.autoneg_advertised = ecmd->advertising;
+ hw->mac.autoneg = ecmd->autoneg;
+ pch_gbe_hal_phy_sw_reset(hw);
+
+ /* reset the link */
+ if (netif_running(adapter->netdev)) {
+ pch_gbe_down(adapter);
+ ret = pch_gbe_up(adapter);
+ } else {
+ pch_gbe_reset(adapter);
+ }
+ return ret;
+}
+
+/**
+ * pch_gbe_get_regs_len - Report the size of device registers
+ * @netdev: Network interface device structure
+ * Returns: the size of device registers.
+ */
+static int pch_gbe_get_regs_len(struct net_device *netdev)
+{
+ return PCH_GBE_REGS_LEN * (int)sizeof(u32);
+}
+
+/**
+ * pch_gbe_get_drvinfo - Report driver information
+ * @netdev: Network interface device structure
+ * @drvinfo: Driver information structure
+ */
+static void pch_gbe_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+
+ strcpy(drvinfo->driver, KBUILD_MODNAME);
+ strcpy(drvinfo->version, pch_driver_version);
+ strcpy(drvinfo->fw_version, "N/A");
+ strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
+ drvinfo->regdump_len = pch_gbe_get_regs_len(netdev);
+}
+
+/**
+ * pch_gbe_get_regs - Get device registers
+ * @netdev: Network interface device structure
+ * @regs: Ethtool register structure
+ * @p: Buffer pointer of read device register date
+ */
+static void pch_gbe_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
+ u32 *regs_buff = p;
+ u16 i, tmp;
+
+ regs->version = 0x1000000 | (__u32)pdev->revision << 16 | pdev->device;
+ for (i = 0; i < PCH_GBE_MAC_REGS_LEN; i++)
+ *regs_buff++ = ioread32(&hw->reg->INT_ST + i);
+ /* PHY register */
+ for (i = 0; i < PCH_GBE_PHY_REGS_LEN; i++) {
+ pch_gbe_hal_read_phy_reg(&adapter->hw, i, &tmp);
+ *regs_buff++ = tmp;
+ }
+}
+
+/**
+ * pch_gbe_get_wol - Report whether Wake-on-Lan is enabled
+ * @netdev: Network interface device structure
+ * @wol: Wake-on-Lan information
+ */
+static void pch_gbe_get_wol(struct net_device *netdev,
+ struct ethtool_wolinfo *wol)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+
+ wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
+ wol->wolopts = 0;
+
+ if ((adapter->wake_up_evt & PCH_GBE_WLC_IND))
+ wol->wolopts |= WAKE_UCAST;
+ if ((adapter->wake_up_evt & PCH_GBE_WLC_MLT))
+ wol->wolopts |= WAKE_MCAST;
+ if ((adapter->wake_up_evt & PCH_GBE_WLC_BR))
+ wol->wolopts |= WAKE_BCAST;
+ if ((adapter->wake_up_evt & PCH_GBE_WLC_MP))
+ wol->wolopts |= WAKE_MAGIC;
+}
+
+/**
+ * pch_gbe_set_wol - Turn Wake-on-Lan on or off
+ * @netdev: Network interface device structure
+ * @wol: Pointer of wake-on-Lan information straucture
+ * Returns
+ * 0: Successful.
+ * Negative value: Failed.
+ */
+static int pch_gbe_set_wol(struct net_device *netdev,
+ struct ethtool_wolinfo *wol)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+
+ if ((wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)))
+ return -EOPNOTSUPP;
+ /* these settings will always override what we currently have */
+ adapter->wake_up_evt = 0;
+
+ if ((wol->wolopts & WAKE_UCAST))
+ adapter->wake_up_evt |= PCH_GBE_WLC_IND;
+ if ((wol->wolopts & WAKE_MCAST))
+ adapter->wake_up_evt |= PCH_GBE_WLC_MLT;
+ if ((wol->wolopts & WAKE_BCAST))
+ adapter->wake_up_evt |= PCH_GBE_WLC_BR;
+ if ((wol->wolopts & WAKE_MAGIC))
+ adapter->wake_up_evt |= PCH_GBE_WLC_MP;
+ return 0;
+}
+
+/**
+ * pch_gbe_nway_reset - Restart autonegotiation
+ * @netdev: Network interface device structure
+ * Returns
+ * 0: Successful.
+ * Negative value: Failed.
+ */
+static int pch_gbe_nway_reset(struct net_device *netdev)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+
+ return mii_nway_restart(&adapter->mii);
+}
+
+/**
+ * pch_gbe_get_ringparam - Report ring sizes
+ * @netdev: Network interface device structure
+ * @ring: Ring param structure
+ */
+static void pch_gbe_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_tx_ring *txdr = adapter->tx_ring;
+ struct pch_gbe_rx_ring *rxdr = adapter->rx_ring;
+
+ ring->rx_max_pending = PCH_GBE_MAX_RXD;
+ ring->tx_max_pending = PCH_GBE_MAX_TXD;
+ ring->rx_mini_max_pending = 0;
+ ring->rx_jumbo_max_pending = 0;
+ ring->rx_pending = rxdr->count;
+ ring->tx_pending = txdr->count;
+ ring->rx_mini_pending = 0;
+ ring->rx_jumbo_pending = 0;
+}
+
+/**
+ * pch_gbe_set_ringparam - Set ring sizes
+ * @netdev: Network interface device structure
+ * @ring: Ring param structure
+ * Returns
+ * 0: Successful.
+ * Negative value: Failed.
+ */
+static int pch_gbe_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_tx_ring *txdr, *tx_old;
+ struct pch_gbe_rx_ring *rxdr, *rx_old;
+ int tx_ring_size, rx_ring_size;
+ int err = 0;
+
+ if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+ return -EINVAL;
+ tx_ring_size = (int)sizeof(struct pch_gbe_tx_ring);
+ rx_ring_size = (int)sizeof(struct pch_gbe_rx_ring);
+
+ if ((netif_running(adapter->netdev)))
+ pch_gbe_down(adapter);
+ tx_old = adapter->tx_ring;
+ rx_old = adapter->rx_ring;
+
+ txdr = kzalloc(tx_ring_size, GFP_KERNEL);
+ if (!txdr) {
+ err = -ENOMEM;
+ goto err_alloc_tx;
+ }
+ rxdr = kzalloc(rx_ring_size, GFP_KERNEL);
+ if (!rxdr) {
+ err = -ENOMEM;
+ goto err_alloc_rx;
+ }
+ adapter->tx_ring = txdr;
+ adapter->rx_ring = rxdr;
+
+ rxdr->count =
+ clamp_val(ring->rx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);
+ rxdr->count = roundup(rxdr->count, PCH_GBE_RX_DESC_MULTIPLE);
+
+ txdr->count =
+ clamp_val(ring->tx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);
+ txdr->count = roundup(txdr->count, PCH_GBE_TX_DESC_MULTIPLE);
+
+ if ((netif_running(adapter->netdev))) {
+ /* Try to get new resources before deleting old */
+ err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring);
+ if (err)
+ goto err_setup_rx;
+ err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring);
+ if (err)
+ goto err_setup_tx;
+ /* save the new, restore the old in order to free it,
+ * then restore the new back again */
+#ifdef RINGFREE
+ adapter->rx_ring = rx_old;
+ adapter->tx_ring = tx_old;
+ pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
+ pch_gbe_free_tx_resources(adapter, adapter->tx_ring);
+ kfree(tx_old);
+ kfree(rx_old);
+ adapter->rx_ring = rxdr;
+ adapter->tx_ring = txdr;
+#else
+ pch_gbe_free_rx_resources(adapter, rx_old);
+ pch_gbe_free_tx_resources(adapter, tx_old);
+ kfree(tx_old);
+ kfree(rx_old);
+ adapter->rx_ring = rxdr;
+ adapter->tx_ring = txdr;
+#endif
+ err = pch_gbe_up(adapter);
+ }
+ return err;
+
+err_setup_tx:
+ pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
+err_setup_rx:
+ adapter->rx_ring = rx_old;
+ adapter->tx_ring = tx_old;
+ kfree(rxdr);
+err_alloc_rx:
+ kfree(txdr);
+err_alloc_tx:
+ if (netif_running(adapter->netdev))
+ pch_gbe_up(adapter);
+ return err;
+}
+
+/**
+ * pch_gbe_get_pauseparam - Report pause parameters
+ * @netdev: Network interface device structure
+ * @pause: Pause parameters structure
+ */
+static void pch_gbe_get_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+
+ pause->autoneg =
+ ((hw->mac.fc_autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE);
+
+ if (hw->mac.fc == PCH_GBE_FC_RX_PAUSE) {
+ pause->rx_pause = 1;
+ } else if (hw->mac.fc == PCH_GBE_FC_TX_PAUSE) {
+ pause->tx_pause = 1;
+ } else if (hw->mac.fc == PCH_GBE_FC_FULL) {
+ pause->rx_pause = 1;
+ pause->tx_pause = 1;
+ }
+}
+
+/**
+ * pch_gbe_set_pauseparam - Set pause paramters
+ * @netdev: Network interface device structure
+ * @pause: Pause parameters structure
+ * Returns
+ * 0: Successful.
+ * Negative value: Failed.
+ */
+static int pch_gbe_set_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+ int ret = 0;
+
+ hw->mac.fc_autoneg = pause->autoneg;
+ if ((pause->rx_pause) && (pause->tx_pause))
+ hw->mac.fc = PCH_GBE_FC_FULL;
+ else if ((pause->rx_pause) && (!pause->tx_pause))
+ hw->mac.fc = PCH_GBE_FC_RX_PAUSE;
+ else if ((!pause->rx_pause) && (pause->tx_pause))
+ hw->mac.fc = PCH_GBE_FC_TX_PAUSE;
+ else if ((!pause->rx_pause) && (!pause->tx_pause))
+ hw->mac.fc = PCH_GBE_FC_NONE;
+
+ if (hw->mac.fc_autoneg == AUTONEG_ENABLE) {
+ if ((netif_running(adapter->netdev))) {
+ pch_gbe_down(adapter);
+ ret = pch_gbe_up(adapter);
+ } else {
+ pch_gbe_reset(adapter);
+ }
+ } else {
+ ret = pch_gbe_mac_force_mac_fc(hw);
+ }
+ return ret;
+}
+
+/**
+ * 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_get_tx_csum - Report whether transmit 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_tx_csum(struct net_device *netdev)
+{
+ return (netdev->features & NETIF_F_HW_CSUM) != 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;
+ if (data)
+ netdev->features |= NETIF_F_HW_CSUM;
+ else
+ netdev->features &= ~NETIF_F_HW_CSUM;
+ return 0;
+}
+
+/**
+ * pch_gbe_get_strings - Return a set of strings that describe the requested
+ * objects
+ * @netdev: Network interface device structure
+ * @stringset: Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS]
+ * @data: Pointer of read string data.
+ */
+static void pch_gbe_get_strings(struct net_device *netdev, u32 stringset,
+ u8 *data)
+{
+ u8 *p = data;
+ int i;
+
+ switch (stringset) {
+ case (u32) ETH_SS_STATS:
+ for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {
+ memcpy(p, pch_gbe_gstrings_stats[i].string,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+ break;
+ }
+}
+
+/**
+ * pch_gbe_get_ethtool_stats - Return statistics about the device
+ * @netdev: Network interface device structure
+ * @stats: Ethtool statue structure
+ * @data: Pointer of read status area
+ */
+static void pch_gbe_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ int i;
+ const struct pch_gbe_stats *gstats = pch_gbe_gstrings_stats;
+ char *hw_stats = (char *)&adapter->stats;
+
+ pch_gbe_update_stats(adapter);
+ for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {
+ char *p = hw_stats + gstats->offset;
+ data[i] = gstats->size == sizeof(u64) ? *(u64 *)p:(*(u32 *)p);
+ gstats++;
+ }
+}
+
+static int pch_gbe_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return PCH_GBE_STATS_LEN;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static const struct ethtool_ops pch_gbe_ethtool_ops = {
+ .get_settings = pch_gbe_get_settings,
+ .set_settings = pch_gbe_set_settings,
+ .get_drvinfo = pch_gbe_get_drvinfo,
+ .get_regs_len = pch_gbe_get_regs_len,
+ .get_regs = pch_gbe_get_regs,
+ .get_wol = pch_gbe_get_wol,
+ .set_wol = pch_gbe_set_wol,
+ .nway_reset = pch_gbe_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .get_ringparam = pch_gbe_get_ringparam,
+ .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,
+ .get_tx_csum = pch_gbe_get_tx_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,
+};
+
+void pch_gbe_set_ethtool_ops(struct net_device *netdev)
+{
+ SET_ETHTOOL_OPS(netdev, &pch_gbe_ethtool_ops);
+}
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c
new file mode 100644
index 000000000000..472056b47440
--- /dev/null
+++ b/drivers/net/pch_gbe/pch_gbe_main.c
@@ -0,0 +1,2477 @@
+/*
+ * Copyright (C) 1999 - 2010 Intel Corporation.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This code was derived from the Intel e1000e Linux driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "pch_gbe.h"
+#include "pch_gbe_api.h"
+
+#define DRV_VERSION "1.00"
+const char pch_driver_version[] = DRV_VERSION;
+
+#define PCI_DEVICE_ID_INTEL_IOH1_GBE 0x8802 /* Pci device ID */
+#define PCH_GBE_MAR_ENTRIES 16
+#define PCH_GBE_SHORT_PKT 64
+#define DSC_INIT16 0xC000
+#define PCH_GBE_DMA_ALIGN 0
+#define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */
+#define PCH_GBE_COPYBREAK_DEFAULT 256
+#define PCH_GBE_PCI_BAR 1
+
+#define PCH_GBE_TX_WEIGHT 64
+#define PCH_GBE_RX_WEIGHT 64
+#define PCH_GBE_RX_BUFFER_WRITE 16
+
+/* Initialize the wake-on-LAN settings */
+#define PCH_GBE_WL_INIT_SETTING (PCH_GBE_WLC_MP)
+
+#define PCH_GBE_MAC_RGMII_CTRL_SETTING ( \
+ PCH_GBE_CHIP_TYPE_INTERNAL | \
+ PCH_GBE_RGMII_MODE_RGMII | \
+ PCH_GBE_CRS_SEL \
+ )
+
+/* Ethertype field values */
+#define PCH_GBE_MAX_JUMBO_FRAME_SIZE 10318
+#define PCH_GBE_FRAME_SIZE_2048 2048
+#define PCH_GBE_FRAME_SIZE_4096 4096
+#define PCH_GBE_FRAME_SIZE_8192 8192
+
+#define PCH_GBE_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
+#define PCH_GBE_RX_DESC(R, i) PCH_GBE_GET_DESC(R, i, pch_gbe_rx_desc)
+#define PCH_GBE_TX_DESC(R, i) PCH_GBE_GET_DESC(R, i, pch_gbe_tx_desc)
+#define PCH_GBE_DESC_UNUSED(R) \
+ ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
+ (R)->next_to_clean - (R)->next_to_use - 1)
+
+/* Pause packet value */
+#define PCH_GBE_PAUSE_PKT1_VALUE 0x00C28001
+#define PCH_GBE_PAUSE_PKT2_VALUE 0x00000100
+#define PCH_GBE_PAUSE_PKT4_VALUE 0x01000888
+#define PCH_GBE_PAUSE_PKT5_VALUE 0x0000FFFF
+
+#define PCH_GBE_ETH_ALEN 6
+
+/* This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register. Each bit is documented below:
+ * o RXT0 = Receiver Timer Interrupt (ring 0)
+ * o TXDW = Transmit Descriptor Written Back
+ * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ * o RXSEQ = Receive Sequence Error
+ * o LSC = Link Status Change
+ */
+#define PCH_GBE_INT_ENABLE_MASK ( \
+ PCH_GBE_INT_RX_DMA_CMPLT | \
+ PCH_GBE_INT_RX_DSC_EMP | \
+ PCH_GBE_INT_WOL_DET | \
+ PCH_GBE_INT_TX_CMPLT \
+ )
+
+
+static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT;
+
+static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg);
+static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg,
+ int data);
+/**
+ * pch_gbe_mac_read_mac_addr - Read MAC address
+ * @hw: Pointer to the HW structure
+ * Returns
+ * 0: Successful.
+ */
+s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw)
+{
+ u32 adr1a, adr1b;
+
+ adr1a = ioread32(&hw->reg->mac_adr[0].high);
+ adr1b = ioread32(&hw->reg->mac_adr[0].low);
+
+ hw->mac.addr[0] = (u8)(adr1a & 0xFF);
+ hw->mac.addr[1] = (u8)((adr1a >> 8) & 0xFF);
+ hw->mac.addr[2] = (u8)((adr1a >> 16) & 0xFF);
+ hw->mac.addr[3] = (u8)((adr1a >> 24) & 0xFF);
+ hw->mac.addr[4] = (u8)(adr1b & 0xFF);
+ hw->mac.addr[5] = (u8)((adr1b >> 8) & 0xFF);
+
+ pr_debug("hw->mac.addr : %pM\n", hw->mac.addr);
+ return 0;
+}
+
+/**
+ * pch_gbe_wait_clr_bit - Wait to clear a bit
+ * @reg: Pointer of register
+ * @busy: Busy bit
+ */
+static void pch_gbe_wait_clr_bit(void *reg, u32 bit)
+{
+ u32 tmp;
+ /* wait busy */
+ tmp = 1000;
+ while ((ioread32(reg) & bit) && --tmp)
+ cpu_relax();
+ if (!tmp)
+ pr_err("Error: busy bit is not cleared\n");
+}
+/**
+ * pch_gbe_mac_mar_set - Set MAC address register
+ * @hw: Pointer to the HW structure
+ * @addr: Pointer to the MAC address
+ * @index: MAC address array register
+ */
+static void pch_gbe_mac_mar_set(struct pch_gbe_hw *hw, u8 * addr, u32 index)
+{
+ u32 mar_low, mar_high, adrmask;
+
+ pr_debug("index : 0x%x\n", index);
+
+ /*
+ * HW expects these in little endian so we reverse the byte order
+ * from network order (big endian) to little endian
+ */
+ mar_high = ((u32) addr[0] | ((u32) addr[1] << 8) |
+ ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
+ mar_low = ((u32) addr[4] | ((u32) addr[5] << 8));
+ /* Stop the MAC Address of index. */
+ adrmask = ioread32(&hw->reg->ADDR_MASK);
+ iowrite32((adrmask | (0x0001 << index)), &hw->reg->ADDR_MASK);
+ /* wait busy */
+ pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);
+ /* Set the MAC address to the MAC address 1A/1B register */
+ iowrite32(mar_high, &hw->reg->mac_adr[index].high);
+ iowrite32(mar_low, &hw->reg->mac_adr[index].low);
+ /* Start the MAC address of index */
+ iowrite32((adrmask & ~(0x0001 << index)), &hw->reg->ADDR_MASK);
+ /* wait busy */
+ pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);
+}
+
+/**
+ * pch_gbe_mac_reset_hw - Reset hardware
+ * @hw: Pointer to the HW structure
+ */
+static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw)
+{
+ /* Read the MAC address. and store to the private data */
+ pch_gbe_mac_read_mac_addr(hw);
+ iowrite32(PCH_GBE_ALL_RST, &hw->reg->RESET);
+#ifdef PCH_GBE_MAC_IFOP_RGMII
+ iowrite32(PCH_GBE_MODE_GMII_ETHER, &hw->reg->MODE);
+#endif
+ pch_gbe_wait_clr_bit(&hw->reg->RESET, PCH_GBE_ALL_RST);
+ /* Setup the receive address */
+ pch_gbe_mac_mar_set(hw, hw->mac.addr, 0);
+ return;
+}
+
+/**
+ * pch_gbe_mac_init_rx_addrs - Initialize receive address's
+ * @hw: Pointer to the HW structure
+ * @mar_count: Receive address registers
+ */
+static void pch_gbe_mac_init_rx_addrs(struct pch_gbe_hw *hw, u16 mar_count)
+{
+ u32 i;
+
+ /* Setup the receive address */
+ pch_gbe_mac_mar_set(hw, hw->mac.addr, 0);
+
+ /* Zero out the other receive addresses */
+ for (i = 1; i < mar_count; i++) {
+ iowrite32(0, &hw->reg->mac_adr[i].high);
+ iowrite32(0, &hw->reg->mac_adr[i].low);
+ }
+ iowrite32(0xFFFE, &hw->reg->ADDR_MASK);
+ /* wait busy */
+ pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);
+}
+
+
+/**
+ * pch_gbe_mac_mc_addr_list_update - Update Multicast addresses
+ * @hw: Pointer to the HW structure
+ * @mc_addr_list: Array of multicast addresses to program
+ * @mc_addr_count: Number of multicast addresses to program
+ * @mar_used_count: The first MAC Address register free to program
+ * @mar_total_num: Total number of supported MAC Address Registers
+ */
+static void pch_gbe_mac_mc_addr_list_update(struct pch_gbe_hw *hw,
+ u8 *mc_addr_list, u32 mc_addr_count,
+ u32 mar_used_count, u32 mar_total_num)
+{
+ u32 i, adrmask;
+
+ /* Load the first set of multicast addresses into the exact
+ * filters (RAR). If there are not enough to fill the RAR
+ * array, clear the filters.
+ */
+ for (i = mar_used_count; i < mar_total_num; i++) {
+ if (mc_addr_count) {
+ pch_gbe_mac_mar_set(hw, mc_addr_list, i);
+ mc_addr_count--;
+ mc_addr_list += PCH_GBE_ETH_ALEN;
+ } else {
+ /* Clear MAC address mask */
+ adrmask = ioread32(&hw->reg->ADDR_MASK);
+ iowrite32((adrmask | (0x0001 << i)),
+ &hw->reg->ADDR_MASK);
+ /* wait busy */
+ pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);
+ /* Clear MAC address */
+ iowrite32(0, &hw->reg->mac_adr[i].high);
+ iowrite32(0, &hw->reg->mac_adr[i].low);
+ }
+ }
+}
+
+/**
+ * pch_gbe_mac_force_mac_fc - Force the MAC's flow control settings
+ * @hw: Pointer to the HW structure
+ * Returns
+ * 0: Successful.
+ * Negative value: Failed.
+ */
+s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw)
+{
+ struct pch_gbe_mac_info *mac = &hw->mac;
+ u32 rx_fctrl;
+
+ pr_debug("mac->fc = %u\n", mac->fc);
+
+ rx_fctrl = ioread32(&hw->reg->RX_FCTRL);
+
+ switch (mac->fc) {
+ case PCH_GBE_FC_NONE:
+ rx_fctrl &= ~PCH_GBE_FL_CTRL_EN;
+ mac->tx_fc_enable = false;
+ break;
+ case PCH_GBE_FC_RX_PAUSE:
+ rx_fctrl |= PCH_GBE_FL_CTRL_EN;
+ mac->tx_fc_enable = false;
+ break;
+ case PCH_GBE_FC_TX_PAUSE:
+ rx_fctrl &= ~PCH_GBE_FL_CTRL_EN;
+ mac->tx_fc_enable = true;
+ break;
+ case PCH_GBE_FC_FULL:
+ rx_fctrl |= PCH_GBE_FL_CTRL_EN;
+ mac->tx_fc_enable = true;
+ break;
+ default:
+ pr_err("Flow control param set incorrectly\n");
+ return -EINVAL;
+ }
+ if (mac->link_duplex == DUPLEX_HALF)
+ rx_fctrl &= ~PCH_GBE_FL_CTRL_EN;
+ iowrite32(rx_fctrl, &hw->reg->RX_FCTRL);
+ pr_debug("RX_FCTRL reg : 0x%08x mac->tx_fc_enable : %d\n",
+ ioread32(&hw->reg->RX_FCTRL), mac->tx_fc_enable);
+ return 0;
+}
+
+/**
+ * pch_gbe_mac_set_wol_event - Set wake-on-lan event
+ * @hw: Pointer to the HW structure
+ * @wu_evt: Wake up event
+ */
+static void pch_gbe_mac_set_wol_event(struct pch_gbe_hw *hw, u32 wu_evt)
+{
+ u32 addr_mask;
+
+ pr_debug("wu_evt : 0x%08x ADDR_MASK reg : 0x%08x\n",
+ wu_evt, ioread32(&hw->reg->ADDR_MASK));
+
+ if (wu_evt) {
+ /* Set Wake-On-Lan address mask */
+ addr_mask = ioread32(&hw->reg->ADDR_MASK);
+ iowrite32(addr_mask, &hw->reg->WOL_ADDR_MASK);
+ /* wait busy */
+ pch_gbe_wait_clr_bit(&hw->reg->WOL_ADDR_MASK, PCH_GBE_WLA_BUSY);
+ iowrite32(0, &hw->reg->WOL_ST);
+ iowrite32((wu_evt | PCH_GBE_WLC_WOL_MODE), &hw->reg->WOL_CTRL);
+ iowrite32(0x02, &hw->reg->TCPIP_ACC);
+ iowrite32(PCH_GBE_INT_ENABLE_MASK, &hw->reg->INT_EN);
+ } else {
+ iowrite32(0, &hw->reg->WOL_CTRL);
+ iowrite32(0, &hw->reg->WOL_ST);
+ }
+ return;
+}
+
+/**
+ * pch_gbe_mac_ctrl_miim - Control MIIM interface
+ * @hw: Pointer to the HW structure
+ * @addr: Address of PHY
+ * @dir: Operetion. (Write or Read)
+ * @reg: Access register of PHY
+ * @data: Write data.
+ *
+ * Returns: Read date.
+ */
+u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg,
+ u16 data)
+{
+ u32 data_out = 0;
+ unsigned int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hw->miim_lock, flags);
+
+ for (i = 100; i; --i) {
+ if ((ioread32(&hw->reg->MIIM) & PCH_GBE_MIIM_OPER_READY))
+ break;
+ udelay(20);
+ }
+ if (i == 0) {
+ pr_err("pch-gbe.miim won't go Ready\n");
+ spin_unlock_irqrestore(&hw->miim_lock, flags);
+ return 0; /* No way to indicate timeout error */
+ }
+ iowrite32(((reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) |
+ (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) |
+ dir | data), &hw->reg->MIIM);
+ for (i = 0; i < 100; i++) {
+ udelay(20);
+ data_out = ioread32(&hw->reg->MIIM);
+ if ((data_out & PCH_GBE_MIIM_OPER_READY))
+ break;
+ }
+ spin_unlock_irqrestore(&hw->miim_lock, flags);
+
+ pr_debug("PHY %s: reg=%d, data=0x%04X\n",
+ dir == PCH_GBE_MIIM_OPER_READ ? "READ" : "WRITE", reg,
+ dir == PCH_GBE_MIIM_OPER_READ ? data_out : data);
+ return (u16) data_out;
+}
+
+/**
+ * pch_gbe_mac_set_pause_packet - Set pause packet
+ * @hw: Pointer to the HW structure
+ */
+static void pch_gbe_mac_set_pause_packet(struct pch_gbe_hw *hw)
+{
+ unsigned long tmp2, tmp3;
+
+ /* Set Pause packet */
+ tmp2 = hw->mac.addr[1];
+ tmp2 = (tmp2 << 8) | hw->mac.addr[0];
+ tmp2 = PCH_GBE_PAUSE_PKT2_VALUE | (tmp2 << 16);
+
+ tmp3 = hw->mac.addr[5];
+ tmp3 = (tmp3 << 8) | hw->mac.addr[4];
+ tmp3 = (tmp3 << 8) | hw->mac.addr[3];
+ tmp3 = (tmp3 << 8) | hw->mac.addr[2];
+
+ iowrite32(PCH_GBE_PAUSE_PKT1_VALUE, &hw->reg->PAUSE_PKT1);
+ iowrite32(tmp2, &hw->reg->PAUSE_PKT2);
+ iowrite32(tmp3, &hw->reg->PAUSE_PKT3);
+ iowrite32(PCH_GBE_PAUSE_PKT4_VALUE, &hw->reg->PAUSE_PKT4);
+ iowrite32(PCH_GBE_PAUSE_PKT5_VALUE, &hw->reg->PAUSE_PKT5);
+
+ /* Transmit Pause Packet */
+ iowrite32(PCH_GBE_PS_PKT_RQ, &hw->reg->PAUSE_REQ);
+
+ pr_debug("PAUSE_PKT1-5 reg : 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ ioread32(&hw->reg->PAUSE_PKT1), ioread32(&hw->reg->PAUSE_PKT2),
+ ioread32(&hw->reg->PAUSE_PKT3), ioread32(&hw->reg->PAUSE_PKT4),
+ ioread32(&hw->reg->PAUSE_PKT5));
+
+ return;
+}
+
+
+/**
+ * pch_gbe_alloc_queues - Allocate memory for all rings
+ * @adapter: Board private structure to initialize
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+static int pch_gbe_alloc_queues(struct pch_gbe_adapter *adapter)
+{
+ int size;
+
+ size = (int)sizeof(struct pch_gbe_tx_ring);
+ adapter->tx_ring = kzalloc(size, GFP_KERNEL);
+ if (!adapter->tx_ring)
+ return -ENOMEM;
+ size = (int)sizeof(struct pch_gbe_rx_ring);
+ adapter->rx_ring = kzalloc(size, GFP_KERNEL);
+ if (!adapter->rx_ring) {
+ kfree(adapter->tx_ring);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+/**
+ * pch_gbe_init_stats - Initialize status
+ * @adapter: Board private structure to initialize
+ */
+static void pch_gbe_init_stats(struct pch_gbe_adapter *adapter)
+{
+ memset(&adapter->stats, 0, sizeof(adapter->stats));
+ return;
+}
+
+/**
+ * pch_gbe_init_phy - Initialize PHY
+ * @adapter: Board private structure to initialize
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+static int pch_gbe_init_phy(struct pch_gbe_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ u32 addr;
+ u16 bmcr, stat;
+
+ /* Discover phy addr by searching addrs in order {1,0,2,..., 31} */
+ for (addr = 0; addr < PCH_GBE_PHY_REGS_LEN; addr++) {
+ adapter->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr;
+ bmcr = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMCR);
+ stat = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR);
+ stat = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR);
+ if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0))))
+ break;
+ }
+ adapter->hw.phy.addr = adapter->mii.phy_id;
+ pr_debug("phy_addr = %d\n", adapter->mii.phy_id);
+ if (addr == 32)
+ return -EAGAIN;
+ /* Selected the phy and isolate the rest */
+ for (addr = 0; addr < PCH_GBE_PHY_REGS_LEN; addr++) {
+ if (addr != adapter->mii.phy_id) {
+ pch_gbe_mdio_write(netdev, addr, MII_BMCR,
+ BMCR_ISOLATE);
+ } else {
+ bmcr = pch_gbe_mdio_read(netdev, addr, MII_BMCR);
+ pch_gbe_mdio_write(netdev, addr, MII_BMCR,
+ bmcr & ~BMCR_ISOLATE);
+ }
+ }
+
+ /* MII setup */
+ adapter->mii.phy_id_mask = 0x1F;
+ adapter->mii.reg_num_mask = 0x1F;
+ adapter->mii.dev = adapter->netdev;
+ adapter->mii.mdio_read = pch_gbe_mdio_read;
+ adapter->mii.mdio_write = pch_gbe_mdio_write;
+ adapter->mii.supports_gmii = mii_check_gmii_support(&adapter->mii);
+ return 0;
+}
+
+/**
+ * pch_gbe_mdio_read - The read function for mii
+ * @netdev: Network interface device structure
+ * @addr: Phy ID
+ * @reg: Access location
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+
+ return pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_READ, reg,
+ (u16) 0);
+}
+
+/**
+ * pch_gbe_mdio_write - The write function for mii
+ * @netdev: Network interface device structure
+ * @addr: Phy ID (not used)
+ * @reg: Access location
+ * @data: Write data
+ */
+static void pch_gbe_mdio_write(struct net_device *netdev,
+ int addr, int reg, int data)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+
+ pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_WRITE, reg, data);
+}
+
+/**
+ * pch_gbe_reset_task - Reset processing at the time of transmission timeout
+ * @work: Pointer of board private structure
+ */
+static void pch_gbe_reset_task(struct work_struct *work)
+{
+ struct pch_gbe_adapter *adapter;
+ adapter = container_of(work, struct pch_gbe_adapter, reset_task);
+
+ pch_gbe_reinit_locked(adapter);
+}
+
+/**
+ * pch_gbe_reinit_locked- Re-initialization
+ * @adapter: Board private structure
+ */
+void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ rtnl_lock();
+ if (netif_running(netdev)) {
+ pch_gbe_down(adapter);
+ pch_gbe_up(adapter);
+ }
+ rtnl_unlock();
+}
+
+/**
+ * pch_gbe_reset - Reset GbE
+ * @adapter: Board private structure
+ */
+void pch_gbe_reset(struct pch_gbe_adapter *adapter)
+{
+ pch_gbe_mac_reset_hw(&adapter->hw);
+ /* Setup the receive address. */
+ pch_gbe_mac_init_rx_addrs(&adapter->hw, PCH_GBE_MAR_ENTRIES);
+ if (pch_gbe_hal_init_hw(&adapter->hw))
+ pr_err("Hardware Error\n");
+}
+
+/**
+ * pch_gbe_free_irq - Free an interrupt
+ * @adapter: Board private structure
+ */
+static void pch_gbe_free_irq(struct pch_gbe_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ free_irq(adapter->pdev->irq, netdev);
+ if (adapter->have_msi) {
+ pci_disable_msi(adapter->pdev);
+ pr_debug("call pci_disable_msi\n");
+ }
+}
+
+/**
+ * pch_gbe_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: Board private structure
+ */
+static void pch_gbe_irq_disable(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+
+ atomic_inc(&adapter->irq_sem);
+ iowrite32(0, &hw->reg->INT_EN);
+ ioread32(&hw->reg->INT_ST);
+ synchronize_irq(adapter->pdev->irq);
+
+ pr_debug("INT_EN reg : 0x%08x\n", ioread32(&hw->reg->INT_EN));
+}
+
+/**
+ * pch_gbe_irq_enable - Enable default interrupt generation settings
+ * @adapter: Board private structure
+ */
+static void pch_gbe_irq_enable(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+
+ if (likely(atomic_dec_and_test(&adapter->irq_sem)))
+ iowrite32(PCH_GBE_INT_ENABLE_MASK, &hw->reg->INT_EN);
+ ioread32(&hw->reg->INT_ST);
+ pr_debug("INT_EN reg : 0x%08x\n", ioread32(&hw->reg->INT_EN));
+}
+
+
+
+/**
+ * pch_gbe_setup_tctl - configure the Transmit control registers
+ * @adapter: Board private structure
+ */
+static void pch_gbe_setup_tctl(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ u32 tx_mode, tcpip;
+
+ tx_mode = PCH_GBE_TM_LONG_PKT |
+ PCH_GBE_TM_ST_AND_FD |
+ PCH_GBE_TM_SHORT_PKT |
+ PCH_GBE_TM_TH_TX_STRT_8 |
+ PCH_GBE_TM_TH_ALM_EMP_4 | PCH_GBE_TM_TH_ALM_FULL_8;
+
+ iowrite32(tx_mode, &hw->reg->TX_MODE);
+
+ tcpip = ioread32(&hw->reg->TCPIP_ACC);
+ tcpip |= PCH_GBE_TX_TCPIPACC_EN;
+ iowrite32(tcpip, &hw->reg->TCPIP_ACC);
+ return;
+}
+
+/**
+ * pch_gbe_configure_tx - Configure Transmit Unit after Reset
+ * @adapter: Board private structure
+ */
+static void pch_gbe_configure_tx(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ u32 tdba, tdlen, dctrl;
+
+ pr_debug("dma addr = 0x%08llx size = 0x%08x\n",
+ (unsigned long long)adapter->tx_ring->dma,
+ adapter->tx_ring->size);
+
+ /* Setup the HW Tx Head and Tail descriptor pointers */
+ tdba = adapter->tx_ring->dma;
+ tdlen = adapter->tx_ring->size - 0x10;
+ iowrite32(tdba, &hw->reg->TX_DSC_BASE);
+ iowrite32(tdlen, &hw->reg->TX_DSC_SIZE);
+ iowrite32(tdba, &hw->reg->TX_DSC_SW_P);
+
+ /* Enables Transmission DMA */
+ dctrl = ioread32(&hw->reg->DMA_CTRL);
+ dctrl |= PCH_GBE_TX_DMA_EN;
+ iowrite32(dctrl, &hw->reg->DMA_CTRL);
+}
+
+/**
+ * pch_gbe_setup_rctl - Configure the receive control registers
+ * @adapter: Board private structure
+ */
+static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ u32 rx_mode, tcpip;
+
+ rx_mode = PCH_GBE_ADD_FIL_EN | PCH_GBE_MLT_FIL_EN |
+ PCH_GBE_RH_ALM_EMP_4 | PCH_GBE_RH_ALM_FULL_4 | PCH_GBE_RH_RD_TRG_8;
+
+ iowrite32(rx_mode, &hw->reg->RX_MODE);
+
+ tcpip = ioread32(&hw->reg->TCPIP_ACC);
+
+ if (adapter->rx_csum) {
+ tcpip &= ~PCH_GBE_RX_TCPIPACC_OFF;
+ tcpip |= PCH_GBE_RX_TCPIPACC_EN;
+ } else {
+ tcpip |= PCH_GBE_RX_TCPIPACC_OFF;
+ tcpip &= ~PCH_GBE_RX_TCPIPACC_EN;
+ }
+ iowrite32(tcpip, &hw->reg->TCPIP_ACC);
+ return;
+}
+
+/**
+ * pch_gbe_configure_rx - Configure Receive Unit after Reset
+ * @adapter: Board private structure
+ */
+static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ u32 rdba, rdlen, rctl, rxdma;
+
+ pr_debug("dma adr = 0x%08llx size = 0x%08x\n",
+ (unsigned long long)adapter->rx_ring->dma,
+ adapter->rx_ring->size);
+
+ pch_gbe_mac_force_mac_fc(hw);
+
+ /* Disables Receive MAC */
+ rctl = ioread32(&hw->reg->MAC_RX_EN);
+ iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN);
+
+ /* Disables Receive DMA */
+ rxdma = ioread32(&hw->reg->DMA_CTRL);
+ rxdma &= ~PCH_GBE_RX_DMA_EN;
+ iowrite32(rxdma, &hw->reg->DMA_CTRL);
+
+ pr_debug("MAC_RX_EN reg = 0x%08x DMA_CTRL reg = 0x%08x\n",
+ ioread32(&hw->reg->MAC_RX_EN),
+ ioread32(&hw->reg->DMA_CTRL));
+
+ /* Setup the HW Rx Head and Tail Descriptor Pointers and
+ * the Base and Length of the Rx Descriptor Ring */
+ rdba = adapter->rx_ring->dma;
+ rdlen = adapter->rx_ring->size - 0x10;
+ iowrite32(rdba, &hw->reg->RX_DSC_BASE);
+ iowrite32(rdlen, &hw->reg->RX_DSC_SIZE);
+ iowrite32((rdba + rdlen), &hw->reg->RX_DSC_SW_P);
+
+ /* Enables Receive DMA */
+ rxdma = ioread32(&hw->reg->DMA_CTRL);
+ rxdma |= PCH_GBE_RX_DMA_EN;
+ iowrite32(rxdma, &hw->reg->DMA_CTRL);
+ /* Enables Receive */
+ iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN);
+}
+
+/**
+ * pch_gbe_unmap_and_free_tx_resource - Unmap and free tx socket buffer
+ * @adapter: Board private structure
+ * @buffer_info: Buffer information structure
+ */
+static void pch_gbe_unmap_and_free_tx_resource(
+ struct pch_gbe_adapter *adapter, struct pch_gbe_buffer *buffer_info)
+{
+ if (buffer_info->mapped) {
+ dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
+ buffer_info->length, DMA_TO_DEVICE);
+ buffer_info->mapped = false;
+ }
+ if (buffer_info->skb) {
+ dev_kfree_skb_any(buffer_info->skb);
+ buffer_info->skb = NULL;
+ }
+}
+
+/**
+ * pch_gbe_unmap_and_free_rx_resource - Unmap and free rx socket buffer
+ * @adapter: Board private structure
+ * @buffer_info: Buffer information structure
+ */
+static void pch_gbe_unmap_and_free_rx_resource(
+ struct pch_gbe_adapter *adapter,
+ struct pch_gbe_buffer *buffer_info)
+{
+ if (buffer_info->mapped) {
+ dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
+ buffer_info->length, DMA_FROM_DEVICE);
+ buffer_info->mapped = false;
+ }
+ if (buffer_info->skb) {
+ dev_kfree_skb_any(buffer_info->skb);
+ buffer_info->skb = NULL;
+ }
+}
+
+/**
+ * pch_gbe_clean_tx_ring - Free Tx Buffers
+ * @adapter: Board private structure
+ * @tx_ring: Ring to be cleaned
+ */
+static void pch_gbe_clean_tx_ring(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_tx_ring *tx_ring)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ struct pch_gbe_buffer *buffer_info;
+ unsigned long size;
+ unsigned int i;
+
+ /* Free all the Tx ring sk_buffs */
+ for (i = 0; i < tx_ring->count; i++) {
+ buffer_info = &tx_ring->buffer_info[i];
+ pch_gbe_unmap_and_free_tx_resource(adapter, buffer_info);
+ }
+ pr_debug("call pch_gbe_unmap_and_free_tx_resource() %d count\n", i);
+
+ size = (unsigned long)sizeof(struct pch_gbe_buffer) * tx_ring->count;
+ memset(tx_ring->buffer_info, 0, size);
+
+ /* Zero out the descriptor ring */
+ memset(tx_ring->desc, 0, tx_ring->size);
+ tx_ring->next_to_use = 0;
+ tx_ring->next_to_clean = 0;
+ iowrite32(tx_ring->dma, &hw->reg->TX_DSC_HW_P);
+ iowrite32((tx_ring->size - 0x10), &hw->reg->TX_DSC_SIZE);
+}
+
+/**
+ * pch_gbe_clean_rx_ring - Free Rx Buffers
+ * @adapter: Board private structure
+ * @rx_ring: Ring to free buffers from
+ */
+static void
+pch_gbe_clean_rx_ring(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_rx_ring *rx_ring)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ struct pch_gbe_buffer *buffer_info;
+ unsigned long size;
+ unsigned int i;
+
+ /* Free all the Rx ring sk_buffs */
+ for (i = 0; i < rx_ring->count; i++) {
+ buffer_info = &rx_ring->buffer_info[i];
+ pch_gbe_unmap_and_free_rx_resource(adapter, buffer_info);
+ }
+ pr_debug("call pch_gbe_unmap_and_free_rx_resource() %d count\n", i);
+ size = (unsigned long)sizeof(struct pch_gbe_buffer) * rx_ring->count;
+ memset(rx_ring->buffer_info, 0, size);
+
+ /* Zero out the descriptor ring */
+ memset(rx_ring->desc, 0, rx_ring->size);
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
+ iowrite32(rx_ring->dma, &hw->reg->RX_DSC_HW_P);
+ iowrite32((rx_ring->size - 0x10), &hw->reg->RX_DSC_SIZE);
+}
+
+static void pch_gbe_set_rgmii_ctrl(struct pch_gbe_adapter *adapter, u16 speed,
+ u16 duplex)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ unsigned long rgmii = 0;
+
+ /* Set the RGMII control. */
+#ifdef PCH_GBE_MAC_IFOP_RGMII
+ switch (speed) {
+ case SPEED_10:
+ rgmii = (PCH_GBE_RGMII_RATE_2_5M |
+ PCH_GBE_MAC_RGMII_CTRL_SETTING);
+ break;
+ case SPEED_100:
+ rgmii = (PCH_GBE_RGMII_RATE_25M |
+ PCH_GBE_MAC_RGMII_CTRL_SETTING);
+ break;
+ case SPEED_1000:
+ rgmii = (PCH_GBE_RGMII_RATE_125M |
+ PCH_GBE_MAC_RGMII_CTRL_SETTING);
+ break;
+ }
+ iowrite32(rgmii, &hw->reg->RGMII_CTRL);
+#else /* GMII */
+ rgmii = 0;
+ iowrite32(rgmii, &hw->reg->RGMII_CTRL);
+#endif
+}
+static void pch_gbe_set_mode(struct pch_gbe_adapter *adapter, u16 speed,
+ u16 duplex)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct pch_gbe_hw *hw = &adapter->hw;
+ unsigned long mode = 0;
+
+ /* Set the communication mode */
+ switch (speed) {
+ case SPEED_10:
+ mode = PCH_GBE_MODE_MII_ETHER;
+ netdev->tx_queue_len = 10;
+ break;
+ case SPEED_100:
+ mode = PCH_GBE_MODE_MII_ETHER;
+ netdev->tx_queue_len = 100;
+ break;
+ case SPEED_1000:
+ mode = PCH_GBE_MODE_GMII_ETHER;
+ break;
+ }
+ if (duplex == DUPLEX_FULL)
+ mode |= PCH_GBE_MODE_FULL_DUPLEX;
+ else
+ mode |= PCH_GBE_MODE_HALF_DUPLEX;
+ iowrite32(mode, &hw->reg->MODE);
+}
+
+/**
+ * pch_gbe_watchdog - Watchdog process
+ * @data: Board private structure
+ */
+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))) {
+ netdev->tx_queue_len = adapter->tx_queue_len;
+ /* mii library handles link maintenance tasks */
+ if (mii_ethtool_gset(&adapter->mii, &cmd)) {
+ pr_err("ethtool get setting Error\n");
+ mod_timer(&adapter->watchdog_timer,
+ round_jiffies(jiffies +
+ PCH_GBE_WATCHDOG_PERIOD));
+ return;
+ }
+ hw->mac.link_speed = cmd.speed;
+ hw->mac.link_duplex = cmd.duplex;
+ /* Set the RGMII control. */
+ pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,
+ hw->mac.link_duplex);
+ /* Set the communication mode */
+ pch_gbe_set_mode(adapter, hw->mac.link_speed,
+ hw->mac.link_duplex);
+ netdev_dbg(netdev,
+ "Link is Up %d Mbps %s-Duplex\n",
+ cmd.speed,
+ cmd.duplex == DUPLEX_FULL ? "Full" : "Half");
+ netif_carrier_on(netdev);
+ netif_wake_queue(netdev);
+ } else if ((!mii_link_ok(&adapter->mii)) &&
+ (netif_carrier_ok(netdev))) {
+ netdev_dbg(netdev, "NIC Link is Down\n");
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+ }
+ mod_timer(&adapter->watchdog_timer,
+ round_jiffies(jiffies + PCH_GBE_WATCHDOG_PERIOD));
+}
+
+/**
+ * pch_gbe_tx_queue - Carry out queuing of the transmission data
+ * @adapter: Board private structure
+ * @tx_ring: Tx descriptor ring structure
+ * @skb: Sockt buffer structure
+ */
+static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_tx_ring *tx_ring,
+ struct sk_buff *skb)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ struct pch_gbe_tx_desc *tx_desc;
+ struct pch_gbe_buffer *buffer_info;
+ struct sk_buff *tmp_skb;
+ unsigned int frame_ctrl;
+ unsigned int ring_num;
+ unsigned long flags;
+
+ /*-- Set frame control --*/
+ frame_ctrl = 0;
+ if (unlikely(skb->len < PCH_GBE_SHORT_PKT))
+ frame_ctrl |= PCH_GBE_TXD_CTRL_APAD;
+ if (unlikely(!adapter->tx_csum))
+ frame_ctrl |= PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
+
+ /* Performs checksum processing */
+ /*
+ * 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)) {
+ frame_ctrl |= PCH_GBE_TXD_CTRL_APAD |
+ PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
+ if (skb->protocol == htons(ETH_P_IP)) {
+ struct iphdr *iph = ip_hdr(skb);
+ unsigned int offset;
+ iph->check = 0;
+ iph->check = ip_fast_csum((u8 *) iph, iph->ihl);
+ offset = skb_transport_offset(skb);
+ if (iph->protocol == IPPROTO_TCP) {
+ skb->csum = 0;
+ tcp_hdr(skb)->check = 0;
+ skb->csum = skb_checksum(skb, offset,
+ skb->len - offset, 0);
+ tcp_hdr(skb)->check =
+ csum_tcpudp_magic(iph->saddr,
+ iph->daddr,
+ skb->len - offset,
+ IPPROTO_TCP,
+ skb->csum);
+ } else if (iph->protocol == IPPROTO_UDP) {
+ skb->csum = 0;
+ udp_hdr(skb)->check = 0;
+ skb->csum =
+ skb_checksum(skb, offset,
+ skb->len - offset, 0);
+ udp_hdr(skb)->check =
+ csum_tcpudp_magic(iph->saddr,
+ iph->daddr,
+ skb->len - offset,
+ IPPROTO_UDP,
+ skb->csum);
+ }
+ }
+ }
+ spin_lock_irqsave(&tx_ring->tx_lock, flags);
+ ring_num = tx_ring->next_to_use;
+ if (unlikely((ring_num + 1) == tx_ring->count))
+ tx_ring->next_to_use = 0;
+ else
+ tx_ring->next_to_use = ring_num + 1;
+
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ buffer_info = &tx_ring->buffer_info[ring_num];
+ tmp_skb = buffer_info->skb;
+
+ /* [Header:14][payload] ---> [Header:14][paddong:2][payload] */
+ memcpy(tmp_skb->data, skb->data, ETH_HLEN);
+ tmp_skb->data[ETH_HLEN] = 0x00;
+ tmp_skb->data[ETH_HLEN + 1] = 0x00;
+ tmp_skb->len = skb->len;
+ memcpy(&tmp_skb->data[ETH_HLEN + 2], &skb->data[ETH_HLEN],
+ (skb->len - ETH_HLEN));
+ /*-- Set Buffer infomation --*/
+ buffer_info->length = tmp_skb->len;
+ buffer_info->dma = dma_map_single(&adapter->pdev->dev, tmp_skb->data,
+ buffer_info->length,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) {
+ pr_err("TX DMA map failed\n");
+ buffer_info->dma = 0;
+ buffer_info->time_stamp = 0;
+ tx_ring->next_to_use = ring_num;
+ return;
+ }
+ buffer_info->mapped = true;
+ buffer_info->time_stamp = jiffies;
+
+ /*-- Set Tx descriptor --*/
+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, ring_num);
+ tx_desc->buffer_addr = (buffer_info->dma);
+ tx_desc->length = (tmp_skb->len);
+ tx_desc->tx_words_eob = ((tmp_skb->len + 3));
+ tx_desc->tx_frame_ctrl = (frame_ctrl);
+ tx_desc->gbec_status = (DSC_INIT16);
+
+ if (unlikely(++ring_num == tx_ring->count))
+ ring_num = 0;
+
+ /* Update software pointer of TX descriptor */
+ iowrite32(tx_ring->dma +
+ (int)sizeof(struct pch_gbe_tx_desc) * ring_num,
+ &hw->reg->TX_DSC_SW_P);
+ dev_kfree_skb_any(skb);
+}
+
+/**
+ * pch_gbe_update_stats - Update the board statistics counters
+ * @adapter: Board private structure
+ */
+void pch_gbe_update_stats(struct pch_gbe_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ struct pch_gbe_hw_stats *stats = &adapter->stats;
+ unsigned long flags;
+
+ /*
+ * Prevent stats update while adapter is being reset, or if the pci
+ * connection is down.
+ */
+ if ((pdev->error_state) && (pdev->error_state != pci_channel_io_normal))
+ return;
+
+ spin_lock_irqsave(&adapter->stats_lock, flags);
+
+ /* Update device status "adapter->stats" */
+ stats->rx_errors = stats->rx_crc_errors + stats->rx_frame_errors;
+ stats->tx_errors = stats->tx_length_errors +
+ stats->tx_aborted_errors +
+ stats->tx_carrier_errors + stats->tx_timeout_count;
+
+ /* Update network device status "adapter->net_stats" */
+ netdev->stats.rx_packets = stats->rx_packets;
+ netdev->stats.rx_bytes = stats->rx_bytes;
+ netdev->stats.rx_dropped = stats->rx_dropped;
+ netdev->stats.tx_packets = stats->tx_packets;
+ netdev->stats.tx_bytes = stats->tx_bytes;
+ netdev->stats.tx_dropped = stats->tx_dropped;
+ /* Fill out the OS statistics structure */
+ netdev->stats.multicast = stats->multicast;
+ netdev->stats.collisions = stats->collisions;
+ /* Rx Errors */
+ netdev->stats.rx_errors = stats->rx_errors;
+ netdev->stats.rx_crc_errors = stats->rx_crc_errors;
+ netdev->stats.rx_frame_errors = stats->rx_frame_errors;
+ /* Tx Errors */
+ netdev->stats.tx_errors = stats->tx_errors;
+ netdev->stats.tx_aborted_errors = stats->tx_aborted_errors;
+ netdev->stats.tx_carrier_errors = stats->tx_carrier_errors;
+
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+}
+
+/**
+ * pch_gbe_intr - Interrupt Handler
+ * @irq: Interrupt number
+ * @data: Pointer to a network interface device structure
+ * Returns
+ * - IRQ_HANDLED: Our interrupt
+ * - IRQ_NONE: Not our interrupt
+ */
+static irqreturn_t pch_gbe_intr(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+ u32 int_st;
+ u32 int_en;
+
+ /* Check request status */
+ int_st = ioread32(&hw->reg->INT_ST);
+ int_st = int_st & ioread32(&hw->reg->INT_EN);
+ /* When request status is no interruption factor */
+ if (unlikely(!int_st))
+ return IRQ_NONE; /* Not our interrupt. End processing. */
+ pr_debug("%s occur int_st = 0x%08x\n", __func__, int_st);
+ if (int_st & PCH_GBE_INT_RX_FRAME_ERR)
+ adapter->stats.intr_rx_frame_err_count++;
+ if (int_st & PCH_GBE_INT_RX_FIFO_ERR)
+ adapter->stats.intr_rx_fifo_err_count++;
+ if (int_st & PCH_GBE_INT_RX_DMA_ERR)
+ adapter->stats.intr_rx_dma_err_count++;
+ if (int_st & PCH_GBE_INT_TX_FIFO_ERR)
+ adapter->stats.intr_tx_fifo_err_count++;
+ if (int_st & PCH_GBE_INT_TX_DMA_ERR)
+ adapter->stats.intr_tx_dma_err_count++;
+ if (int_st & PCH_GBE_INT_TCPIP_ERR)
+ adapter->stats.intr_tcpip_err_count++;
+ /* When Rx descriptor is empty */
+ if ((int_st & PCH_GBE_INT_RX_DSC_EMP)) {
+ adapter->stats.intr_rx_dsc_empty_count++;
+ pr_err("Rx descriptor is empty\n");
+ int_en = ioread32(&hw->reg->INT_EN);
+ iowrite32((int_en & ~PCH_GBE_INT_RX_DSC_EMP), &hw->reg->INT_EN);
+ if (hw->mac.tx_fc_enable) {
+ /* Set Pause packet */
+ pch_gbe_mac_set_pause_packet(hw);
+ }
+ if ((int_en & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT))
+ == 0) {
+ return IRQ_HANDLED;
+ }
+ }
+
+ /* When request status is Receive interruption */
+ if ((int_st & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT))) {
+ if (likely(napi_schedule_prep(&adapter->napi))) {
+ /* Enable only Rx Descriptor empty */
+ atomic_inc(&adapter->irq_sem);
+ int_en = ioread32(&hw->reg->INT_EN);
+ int_en &=
+ ~(PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT);
+ iowrite32(int_en, &hw->reg->INT_EN);
+ /* Start polling for NAPI */
+ __napi_schedule(&adapter->napi);
+ }
+ }
+ pr_debug("return = 0x%08x INT_EN reg = 0x%08x\n",
+ IRQ_HANDLED, ioread32(&hw->reg->INT_EN));
+ return IRQ_HANDLED;
+}
+
+/**
+ * pch_gbe_alloc_rx_buffers - Replace used receive buffers; legacy & extended
+ * @adapter: Board private structure
+ * @rx_ring: Rx descriptor ring
+ * @cleaned_count: Cleaned count
+ */
+static void
+pch_gbe_alloc_rx_buffers(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_rx_ring *rx_ring, int cleaned_count)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ struct pch_gbe_hw *hw = &adapter->hw;
+ struct pch_gbe_rx_desc *rx_desc;
+ struct pch_gbe_buffer *buffer_info;
+ struct sk_buff *skb;
+ unsigned int i;
+ unsigned int bufsz;
+
+ bufsz = adapter->rx_buffer_len + PCH_GBE_DMA_ALIGN;
+ i = rx_ring->next_to_use;
+
+ while ((cleaned_count--)) {
+ buffer_info = &rx_ring->buffer_info[i];
+ skb = buffer_info->skb;
+ if (skb) {
+ skb_trim(skb, 0);
+ } else {
+ skb = netdev_alloc_skb(netdev, bufsz);
+ if (unlikely(!skb)) {
+ /* Better luck next round */
+ adapter->stats.rx_alloc_buff_failed++;
+ break;
+ }
+ /* 64byte align */
+ skb_reserve(skb, PCH_GBE_DMA_ALIGN);
+
+ buffer_info->skb = skb;
+ buffer_info->length = adapter->rx_buffer_len;
+ }
+ buffer_info->dma = dma_map_single(&pdev->dev,
+ skb->data,
+ buffer_info->length,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) {
+ dev_kfree_skb(skb);
+ buffer_info->skb = NULL;
+ buffer_info->dma = 0;
+ adapter->stats.rx_alloc_buff_failed++;
+ break; /* while !buffer_info->skb */
+ }
+ buffer_info->mapped = true;
+ rx_desc = PCH_GBE_RX_DESC(*rx_ring, i);
+ rx_desc->buffer_addr = (buffer_info->dma);
+ rx_desc->gbec_status = DSC_INIT16;
+
+ pr_debug("i = %d buffer_info->dma = 0x08%llx buffer_info->length = 0x%x\n",
+ i, (unsigned long long)buffer_info->dma,
+ buffer_info->length);
+
+ if (unlikely(++i == rx_ring->count))
+ i = 0;
+ }
+ if (likely(rx_ring->next_to_use != i)) {
+ rx_ring->next_to_use = i;
+ if (unlikely(i-- == 0))
+ i = (rx_ring->count - 1);
+ iowrite32(rx_ring->dma +
+ (int)sizeof(struct pch_gbe_rx_desc) * i,
+ &hw->reg->RX_DSC_SW_P);
+ }
+ return;
+}
+
+/**
+ * pch_gbe_alloc_tx_buffers - Allocate transmit buffers
+ * @adapter: Board private structure
+ * @tx_ring: Tx descriptor ring
+ */
+static void pch_gbe_alloc_tx_buffers(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_tx_ring *tx_ring)
+{
+ struct pch_gbe_buffer *buffer_info;
+ struct sk_buff *skb;
+ unsigned int i;
+ unsigned int bufsz;
+ struct pch_gbe_tx_desc *tx_desc;
+
+ bufsz =
+ adapter->hw.mac.max_frame_size + PCH_GBE_DMA_ALIGN + NET_IP_ALIGN;
+
+ for (i = 0; i < tx_ring->count; i++) {
+ buffer_info = &tx_ring->buffer_info[i];
+ skb = netdev_alloc_skb(adapter->netdev, bufsz);
+ skb_reserve(skb, PCH_GBE_DMA_ALIGN);
+ buffer_info->skb = skb;
+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, i);
+ tx_desc->gbec_status = (DSC_INIT16);
+ }
+ return;
+}
+
+/**
+ * pch_gbe_clean_tx - Reclaim resources after transmit completes
+ * @adapter: Board private structure
+ * @tx_ring: Tx descriptor ring
+ * Returns
+ * true: Cleaned the descriptor
+ * false: Not cleaned the descriptor
+ */
+static bool
+pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_tx_ring *tx_ring)
+{
+ struct pch_gbe_tx_desc *tx_desc;
+ struct pch_gbe_buffer *buffer_info;
+ struct sk_buff *skb;
+ unsigned int i;
+ unsigned int cleaned_count = 0;
+ bool cleaned = false;
+
+ pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
+
+ i = tx_ring->next_to_clean;
+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, i);
+ pr_debug("gbec_status:0x%04x dma_status:0x%04x\n",
+ tx_desc->gbec_status, tx_desc->dma_status);
+
+ while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) {
+ pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status);
+ cleaned = true;
+ buffer_info = &tx_ring->buffer_info[i];
+ skb = buffer_info->skb;
+
+ if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_ABT)) {
+ adapter->stats.tx_aborted_errors++;
+ pr_err("Transfer Abort Error\n");
+ } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_CRSER)
+ ) {
+ adapter->stats.tx_carrier_errors++;
+ pr_err("Transfer Carrier Sense Error\n");
+ } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_EXCOL)
+ ) {
+ adapter->stats.tx_aborted_errors++;
+ pr_err("Transfer Collision Abort Error\n");
+ } else if ((tx_desc->gbec_status &
+ (PCH_GBE_TXD_GMAC_STAT_SNGCOL |
+ PCH_GBE_TXD_GMAC_STAT_MLTCOL))) {
+ adapter->stats.collisions++;
+ adapter->stats.tx_packets++;
+ adapter->stats.tx_bytes += skb->len;
+ pr_debug("Transfer Collision\n");
+ } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_CMPLT)
+ ) {
+ adapter->stats.tx_packets++;
+ adapter->stats.tx_bytes += skb->len;
+ }
+ if (buffer_info->mapped) {
+ pr_debug("unmap buffer_info->dma : %d\n", i);
+ dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
+ buffer_info->length, DMA_TO_DEVICE);
+ buffer_info->mapped = false;
+ }
+ if (buffer_info->skb) {
+ pr_debug("trim buffer_info->skb : %d\n", i);
+ skb_trim(buffer_info->skb, 0);
+ }
+ tx_desc->gbec_status = DSC_INIT16;
+ if (unlikely(++i == tx_ring->count))
+ i = 0;
+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, i);
+
+ /* weight of a sort for tx, to avoid endless transmit cleanup */
+ if (cleaned_count++ == PCH_GBE_TX_WEIGHT)
+ break;
+ }
+ pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n",
+ cleaned_count);
+ /* Recover from running out of Tx resources in xmit_frame */
+ if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) {
+ netif_wake_queue(adapter->netdev);
+ adapter->stats.tx_restart_count++;
+ pr_debug("Tx wake queue\n");
+ }
+ spin_lock(&adapter->tx_queue_lock);
+ tx_ring->next_to_clean = i;
+ spin_unlock(&adapter->tx_queue_lock);
+ pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
+ return cleaned;
+}
+
+/**
+ * pch_gbe_clean_rx - Send received data up the network stack; legacy
+ * @adapter: Board private structure
+ * @rx_ring: Rx descriptor ring
+ * @work_done: Completed count
+ * @work_to_do: Request count
+ * Returns
+ * true: Cleaned the descriptor
+ * false: Not cleaned the descriptor
+ */
+static bool
+pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_rx_ring *rx_ring,
+ int *work_done, int work_to_do)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ struct pch_gbe_buffer *buffer_info;
+ struct pch_gbe_rx_desc *rx_desc;
+ u32 length;
+ unsigned char tmp_packet[ETH_HLEN];
+ unsigned int i;
+ unsigned int cleaned_count = 0;
+ bool cleaned = false;
+ struct sk_buff *skb;
+ u8 dma_status;
+ u16 gbec_status;
+ u32 tcp_ip_status;
+ u8 skb_copy_flag = 0;
+ u8 skb_padding_flag = 0;
+
+ i = rx_ring->next_to_clean;
+
+ while (*work_done < work_to_do) {
+ /* Check Rx descriptor status */
+ rx_desc = PCH_GBE_RX_DESC(*rx_ring, i);
+ if (rx_desc->gbec_status == DSC_INIT16)
+ break;
+ cleaned = true;
+ cleaned_count++;
+
+ dma_status = rx_desc->dma_status;
+ gbec_status = rx_desc->gbec_status;
+ tcp_ip_status = rx_desc->tcp_ip_status;
+ rx_desc->gbec_status = DSC_INIT16;
+ buffer_info = &rx_ring->buffer_info[i];
+ skb = buffer_info->skb;
+
+ /* unmap dma */
+ dma_unmap_single(&pdev->dev, buffer_info->dma,
+ buffer_info->length, DMA_FROM_DEVICE);
+ buffer_info->mapped = false;
+ /* Prefetch the packet */
+ prefetch(skb->data);
+
+ pr_debug("RxDecNo = 0x%04x Status[DMA:0x%02x GBE:0x%04x "
+ "TCP:0x%08x] BufInf = 0x%p\n",
+ i, dma_status, gbec_status, tcp_ip_status,
+ buffer_info);
+ /* Error check */
+ if (unlikely(gbec_status & PCH_GBE_RXD_GMAC_STAT_NOTOCTAL)) {
+ adapter->stats.rx_frame_errors++;
+ pr_err("Receive Not Octal Error\n");
+ } else if (unlikely(gbec_status &
+ PCH_GBE_RXD_GMAC_STAT_NBLERR)) {
+ adapter->stats.rx_frame_errors++;
+ pr_err("Receive Nibble Error\n");
+ } else if (unlikely(gbec_status &
+ PCH_GBE_RXD_GMAC_STAT_CRCERR)) {
+ adapter->stats.rx_crc_errors++;
+ pr_err("Receive CRC Error\n");
+ } else {
+ /* get receive length */
+ /* length convert[-3], padding[-2] */
+ length = (rx_desc->rx_words_eob) - 3 - 2;
+
+ /* Decide the data conversion method */
+ if (!adapter->rx_csum) {
+ /* [Header:14][payload] */
+ skb_padding_flag = 0;
+ skb_copy_flag = 1;
+ } else {
+ /* [Header:14][padding:2][payload] */
+ skb_padding_flag = 1;
+ if (length < copybreak)
+ skb_copy_flag = 1;
+ else
+ skb_copy_flag = 0;
+ }
+
+ /* Data conversion */
+ if (skb_copy_flag) { /* recycle skb */
+ struct sk_buff *new_skb;
+ new_skb =
+ netdev_alloc_skb(netdev,
+ length + NET_IP_ALIGN);
+ if (new_skb) {
+ if (!skb_padding_flag) {
+ skb_reserve(new_skb,
+ NET_IP_ALIGN);
+ }
+ memcpy(new_skb->data, skb->data,
+ length);
+ /* save the skb
+ * in buffer_info as good */
+ skb = new_skb;
+ } else if (!skb_padding_flag) {
+ /* dorrop error */
+ pr_err("New skb allocation Error\n");
+ goto dorrop;
+ }
+ } else {
+ buffer_info->skb = NULL;
+ }
+ if (skb_padding_flag) {
+ memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN);
+ memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0],
+ ETH_HLEN);
+ skb_reserve(skb, NET_IP_ALIGN);
+
+ }
+
+ /* update status of driver */
+ adapter->stats.rx_bytes += length;
+ adapter->stats.rx_packets++;
+ if ((gbec_status & PCH_GBE_RXD_GMAC_STAT_MARMLT))
+ adapter->stats.multicast++;
+ /* Write meta date of skb */
+ skb_put(skb, length);
+ skb->protocol = eth_type_trans(skb, netdev);
+ if ((tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) ==
+ PCH_GBE_RXD_ACC_STAT_TCPIPOK) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else {
+ skb->ip_summed = CHECKSUM_NONE;
+ }
+ napi_gro_receive(&adapter->napi, skb);
+ (*work_done)++;
+ pr_debug("Receive skb->ip_summed: %d length: %d\n",
+ skb->ip_summed, length);
+ }
+dorrop:
+ /* return some buffers to hardware, one at a time is too slow */
+ if (unlikely(cleaned_count >= PCH_GBE_RX_BUFFER_WRITE)) {
+ pch_gbe_alloc_rx_buffers(adapter, rx_ring,
+ cleaned_count);
+ cleaned_count = 0;
+ }
+ if (++i == rx_ring->count)
+ i = 0;
+ }
+ rx_ring->next_to_clean = i;
+ if (cleaned_count)
+ pch_gbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
+ return cleaned;
+}
+
+/**
+ * pch_gbe_setup_tx_resources - Allocate Tx resources (Descriptors)
+ * @adapter: Board private structure
+ * @tx_ring: Tx descriptor ring (for a specific queue) to setup
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_tx_ring *tx_ring)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct pch_gbe_tx_desc *tx_desc;
+ int size;
+ int desNo;
+
+ size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count;
+ tx_ring->buffer_info = vmalloc(size);
+ if (!tx_ring->buffer_info) {
+ pr_err("Unable to allocate memory for the buffer infomation\n");
+ return -ENOMEM;
+ }
+ memset(tx_ring->buffer_info, 0, size);
+
+ tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc);
+
+ tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size,
+ &tx_ring->dma, GFP_KERNEL);
+ if (!tx_ring->desc) {
+ vfree(tx_ring->buffer_info);
+ pr_err("Unable to allocate memory for the transmit descriptor ring\n");
+ return -ENOMEM;
+ }
+ memset(tx_ring->desc, 0, tx_ring->size);
+
+ tx_ring->next_to_use = 0;
+ tx_ring->next_to_clean = 0;
+ spin_lock_init(&tx_ring->tx_lock);
+
+ for (desNo = 0; desNo < tx_ring->count; desNo++) {
+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, desNo);
+ tx_desc->gbec_status = DSC_INIT16;
+ }
+ pr_debug("tx_ring->desc = 0x%p tx_ring->dma = 0x%08llx\n"
+ "next_to_clean = 0x%08x next_to_use = 0x%08x\n",
+ tx_ring->desc, (unsigned long long)tx_ring->dma,
+ tx_ring->next_to_clean, tx_ring->next_to_use);
+ return 0;
+}
+
+/**
+ * pch_gbe_setup_rx_resources - Allocate Rx resources (Descriptors)
+ * @adapter: Board private structure
+ * @rx_ring: Rx descriptor ring (for a specific queue) to setup
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_rx_ring *rx_ring)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct pch_gbe_rx_desc *rx_desc;
+ int size;
+ int desNo;
+
+ size = (int)sizeof(struct pch_gbe_buffer) * rx_ring->count;
+ rx_ring->buffer_info = vmalloc(size);
+ if (!rx_ring->buffer_info) {
+ pr_err("Unable to allocate memory for the receive descriptor ring\n");
+ return -ENOMEM;
+ }
+ memset(rx_ring->buffer_info, 0, size);
+ rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc);
+ rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,
+ &rx_ring->dma, GFP_KERNEL);
+
+ if (!rx_ring->desc) {
+ pr_err("Unable to allocate memory for the receive descriptor ring\n");
+ vfree(rx_ring->buffer_info);
+ return -ENOMEM;
+ }
+ memset(rx_ring->desc, 0, rx_ring->size);
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
+ for (desNo = 0; desNo < rx_ring->count; desNo++) {
+ rx_desc = PCH_GBE_RX_DESC(*rx_ring, desNo);
+ rx_desc->gbec_status = DSC_INIT16;
+ }
+ pr_debug("rx_ring->desc = 0x%p rx_ring->dma = 0x%08llx "
+ "next_to_clean = 0x%08x next_to_use = 0x%08x\n",
+ rx_ring->desc, (unsigned long long)rx_ring->dma,
+ rx_ring->next_to_clean, rx_ring->next_to_use);
+ return 0;
+}
+
+/**
+ * pch_gbe_free_tx_resources - Free Tx Resources
+ * @adapter: Board private structure
+ * @tx_ring: Tx descriptor ring for a specific queue
+ */
+void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_tx_ring *tx_ring)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ pch_gbe_clean_tx_ring(adapter, tx_ring);
+ vfree(tx_ring->buffer_info);
+ tx_ring->buffer_info = NULL;
+ pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+ tx_ring->desc = NULL;
+}
+
+/**
+ * pch_gbe_free_rx_resources - Free Rx Resources
+ * @adapter: Board private structure
+ * @rx_ring: Ring to clean the resources from
+ */
+void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_rx_ring *rx_ring)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ pch_gbe_clean_rx_ring(adapter, rx_ring);
+ vfree(rx_ring->buffer_info);
+ rx_ring->buffer_info = NULL;
+ pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
+ rx_ring->desc = NULL;
+}
+
+/**
+ * pch_gbe_request_irq - Allocate an interrupt line
+ * @adapter: Board private structure
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+static int pch_gbe_request_irq(struct pch_gbe_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int err;
+ int flags;
+
+ flags = IRQF_SHARED;
+ adapter->have_msi = false;
+ err = pci_enable_msi(adapter->pdev);
+ pr_debug("call pci_enable_msi\n");
+ if (err) {
+ pr_debug("call pci_enable_msi - Error: %d\n", err);
+ } else {
+ flags = 0;
+ adapter->have_msi = true;
+ }
+ err = request_irq(adapter->pdev->irq, &pch_gbe_intr,
+ flags, netdev->name, netdev);
+ if (err)
+ pr_err("Unable to allocate interrupt Error: %d\n", err);
+ pr_debug("adapter->have_msi : %d flags : 0x%04x return : 0x%04x\n",
+ adapter->have_msi, flags, err);
+ return err;
+}
+
+
+static void pch_gbe_set_multi(struct net_device *netdev);
+/**
+ * pch_gbe_up - Up GbE network device
+ * @adapter: Board private structure
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+int pch_gbe_up(struct pch_gbe_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
+ struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
+ int err;
+
+ /* hardware has been reset, we need to reload some things */
+ pch_gbe_set_multi(netdev);
+
+ pch_gbe_setup_tctl(adapter);
+ pch_gbe_configure_tx(adapter);
+ pch_gbe_setup_rctl(adapter);
+ pch_gbe_configure_rx(adapter);
+
+ err = pch_gbe_request_irq(adapter);
+ if (err) {
+ pr_err("Error: can't bring device up\n");
+ return err;
+ }
+ pch_gbe_alloc_tx_buffers(adapter, tx_ring);
+ pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count);
+ adapter->tx_queue_len = netdev->tx_queue_len;
+
+ mod_timer(&adapter->watchdog_timer, jiffies);
+
+ napi_enable(&adapter->napi);
+ pch_gbe_irq_enable(adapter);
+ netif_start_queue(adapter->netdev);
+
+ return 0;
+}
+
+/**
+ * pch_gbe_down - Down GbE network device
+ * @adapter: Board private structure
+ */
+void pch_gbe_down(struct pch_gbe_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ /* signal that we're down so the interrupt handler does not
+ * reschedule our watchdog timer */
+ napi_disable(&adapter->napi);
+ atomic_set(&adapter->irq_sem, 0);
+
+ pch_gbe_irq_disable(adapter);
+ pch_gbe_free_irq(adapter);
+
+ del_timer_sync(&adapter->watchdog_timer);
+
+ netdev->tx_queue_len = adapter->tx_queue_len;
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+
+ pch_gbe_reset(adapter);
+ pch_gbe_clean_tx_ring(adapter, adapter->tx_ring);
+ pch_gbe_clean_rx_ring(adapter, adapter->rx_ring);
+}
+
+/**
+ * pch_gbe_sw_init - Initialize general software structures (struct pch_gbe_adapter)
+ * @adapter: Board private structure to initialize
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+static int pch_gbe_sw_init(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+
+ adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_2048;
+ hw->mac.max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+ hw->mac.min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
+
+ /* Initialize the hardware-specific values */
+ if (pch_gbe_hal_setup_init_funcs(hw)) {
+ pr_err("Hardware Initialization Failure\n");
+ return -EIO;
+ }
+ if (pch_gbe_alloc_queues(adapter)) {
+ pr_err("Unable to allocate memory for queues\n");
+ return -ENOMEM;
+ }
+ spin_lock_init(&adapter->hw.miim_lock);
+ spin_lock_init(&adapter->tx_queue_lock);
+ spin_lock_init(&adapter->stats_lock);
+ spin_lock_init(&adapter->ethtool_lock);
+ atomic_set(&adapter->irq_sem, 0);
+ pch_gbe_irq_disable(adapter);
+
+ pch_gbe_init_stats(adapter);
+
+ pr_debug("rx_buffer_len : %d mac.min_frame_size : %d mac.max_frame_size : %d\n",
+ (u32) adapter->rx_buffer_len,
+ hw->mac.min_frame_size, hw->mac.max_frame_size);
+ return 0;
+}
+
+/**
+ * pch_gbe_open - Called when a network interface is made active
+ * @netdev: Network interface device structure
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+static int pch_gbe_open(struct net_device *netdev)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+ int err;
+
+ /* allocate transmit descriptors */
+ err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring);
+ if (err)
+ goto err_setup_tx;
+ /* allocate receive descriptors */
+ err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring);
+ if (err)
+ goto err_setup_rx;
+ pch_gbe_hal_power_up_phy(hw);
+ err = pch_gbe_up(adapter);
+ if (err)
+ goto err_up;
+ pr_debug("Success End\n");
+ return 0;
+
+err_up:
+ if (!adapter->wake_up_evt)
+ pch_gbe_hal_power_down_phy(hw);
+ pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
+err_setup_rx:
+ pch_gbe_free_tx_resources(adapter, adapter->tx_ring);
+err_setup_tx:
+ pch_gbe_reset(adapter);
+ pr_err("Error End\n");
+ return err;
+}
+
+/**
+ * pch_gbe_stop - Disables a network interface
+ * @netdev: Network interface device structure
+ * Returns
+ * 0: Successfully
+ */
+static int pch_gbe_stop(struct net_device *netdev)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+
+ pch_gbe_down(adapter);
+ if (!adapter->wake_up_evt)
+ pch_gbe_hal_power_down_phy(hw);
+ pch_gbe_free_tx_resources(adapter, adapter->tx_ring);
+ pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
+ return 0;
+}
+
+/**
+ * pch_gbe_xmit_frame - Packet transmitting start
+ * @skb: Socket buffer structure
+ * @netdev: Network interface device structure
+ * Returns
+ * - NETDEV_TX_OK: Normal end
+ * - NETDEV_TX_BUSY: Error end
+ */
+static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
+ unsigned long flags;
+
+ if (unlikely(skb->len > (adapter->hw.mac.max_frame_size - 4))) {
+ pr_err("Transfer length Error: skb len: %d > max: %d\n",
+ skb->len, adapter->hw.mac.max_frame_size);
+ dev_kfree_skb_any(skb);
+ adapter->stats.tx_length_errors++;
+ return NETDEV_TX_OK;
+ }
+ if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) {
+ /* Collision - tell upper layer to requeue */
+ return NETDEV_TX_LOCKED;
+ }
+ if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring))) {
+ netif_stop_queue(netdev);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ pr_debug("Return : BUSY next_to use : 0x%08x next_to clean : 0x%08x\n",
+ tx_ring->next_to_use, tx_ring->next_to_clean);
+ return NETDEV_TX_BUSY;
+ }
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+
+ /* CRC,ITAG no support */
+ pch_gbe_tx_queue(adapter, tx_ring, skb);
+ return NETDEV_TX_OK;
+}
+
+/**
+ * pch_gbe_get_stats - Get System Network Statistics
+ * @netdev: Network interface device structure
+ * Returns: The current stats
+ */
+static struct net_device_stats *pch_gbe_get_stats(struct net_device *netdev)
+{
+ /* only return the current stats */
+ return &netdev->stats;
+}
+
+/**
+ * pch_gbe_set_multi - Multicast and Promiscuous mode set
+ * @netdev: Network interface device structure
+ */
+static void pch_gbe_set_multi(struct net_device *netdev)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+ struct netdev_hw_addr *ha;
+ u8 *mta_list;
+ u32 rctl;
+ int i;
+ int mc_count;
+
+ pr_debug("netdev->flags : 0x%08x\n", netdev->flags);
+
+ /* Check for Promiscuous and All Multicast modes */
+ rctl = ioread32(&hw->reg->RX_MODE);
+ mc_count = netdev_mc_count(netdev);
+ if ((netdev->flags & IFF_PROMISC)) {
+ rctl &= ~PCH_GBE_ADD_FIL_EN;
+ rctl &= ~PCH_GBE_MLT_FIL_EN;
+ } else if ((netdev->flags & IFF_ALLMULTI)) {
+ /* all the multicasting receive permissions */
+ rctl |= PCH_GBE_ADD_FIL_EN;
+ rctl &= ~PCH_GBE_MLT_FIL_EN;
+ } else {
+ if (mc_count >= PCH_GBE_MAR_ENTRIES) {
+ /* all the multicasting receive permissions */
+ rctl |= PCH_GBE_ADD_FIL_EN;
+ rctl &= ~PCH_GBE_MLT_FIL_EN;
+ } else {
+ rctl |= (PCH_GBE_ADD_FIL_EN | PCH_GBE_MLT_FIL_EN);
+ }
+ }
+ iowrite32(rctl, &hw->reg->RX_MODE);
+
+ if (mc_count >= PCH_GBE_MAR_ENTRIES)
+ return;
+ mta_list = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC);
+ if (!mta_list)
+ return;
+
+ /* The shared function expects a packed array of only addresses. */
+ i = 0;
+ netdev_for_each_mc_addr(ha, netdev) {
+ if (i == mc_count)
+ break;
+ memcpy(mta_list + (i++ * ETH_ALEN), &ha->addr, ETH_ALEN);
+ }
+ pch_gbe_mac_mc_addr_list_update(hw, mta_list, i, 1,
+ PCH_GBE_MAR_ENTRIES);
+ kfree(mta_list);
+
+ pr_debug("RX_MODE reg(check bit31,30 ADD,MLT) : 0x%08x netdev->mc_count : 0x%08x\n",
+ ioread32(&hw->reg->RX_MODE), mc_count);
+}
+
+/**
+ * pch_gbe_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: Network interface device structure
+ * @addr: Pointer to an address structure
+ * Returns
+ * 0: Successfully
+ * -EADDRNOTAVAIL: Failed
+ */
+static int pch_gbe_set_mac(struct net_device *netdev, void *addr)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct sockaddr *skaddr = addr;
+ int ret_val;
+
+ if (!is_valid_ether_addr(skaddr->sa_data)) {
+ ret_val = -EADDRNOTAVAIL;
+ } else {
+ memcpy(netdev->dev_addr, skaddr->sa_data, netdev->addr_len);
+ memcpy(adapter->hw.mac.addr, skaddr->sa_data, netdev->addr_len);
+ pch_gbe_mac_mar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+ ret_val = 0;
+ }
+ pr_debug("ret_val : 0x%08x\n", ret_val);
+ pr_debug("dev_addr : %pM\n", netdev->dev_addr);
+ pr_debug("mac_addr : %pM\n", adapter->hw.mac.addr);
+ pr_debug("MAC_ADR1AB reg : 0x%08x 0x%08x\n",
+ ioread32(&adapter->hw.reg->mac_adr[0].high),
+ ioread32(&adapter->hw.reg->mac_adr[0].low));
+ return ret_val;
+}
+
+/**
+ * pch_gbe_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: Network interface device structure
+ * @new_mtu: New value for maximum frame size
+ * Returns
+ * 0: Successfully
+ * -EINVAL: Failed
+ */
+static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ int max_frame;
+
+ max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+ if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+ (max_frame > PCH_GBE_MAX_JUMBO_FRAME_SIZE)) {
+ pr_err("Invalid MTU setting\n");
+ return -EINVAL;
+ }
+ if (max_frame <= PCH_GBE_FRAME_SIZE_2048)
+ adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_2048;
+ else if (max_frame <= PCH_GBE_FRAME_SIZE_4096)
+ adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_4096;
+ else if (max_frame <= PCH_GBE_FRAME_SIZE_8192)
+ adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_8192;
+ else
+ adapter->rx_buffer_len = PCH_GBE_MAX_JUMBO_FRAME_SIZE;
+ netdev->mtu = new_mtu;
+ adapter->hw.mac.max_frame_size = max_frame;
+
+ if (netif_running(netdev))
+ pch_gbe_reinit_locked(adapter);
+ else
+ pch_gbe_reset(adapter);
+
+ pr_debug("max_frame : %d rx_buffer_len : %d mtu : %d max_frame_size : %d\n",
+ max_frame, (u32) adapter->rx_buffer_len, netdev->mtu,
+ adapter->hw.mac.max_frame_size);
+ return 0;
+}
+
+/**
+ * pch_gbe_ioctl - Controls register through a MII interface
+ * @netdev: Network interface device structure
+ * @ifr: Pointer to ifr structure
+ * @cmd: Control command
+ * Returns
+ * 0: Successfully
+ * Negative value: Failed
+ */
+static int pch_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+
+ pr_debug("cmd : 0x%04x\n", cmd);
+
+ return generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL);
+}
+
+/**
+ * pch_gbe_tx_timeout - Respond to a Tx Hang
+ * @netdev: Network interface device structure
+ */
+static void pch_gbe_tx_timeout(struct net_device *netdev)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+
+ /* Do the reset outside of interrupt context */
+ adapter->stats.tx_timeout_count++;
+ schedule_work(&adapter->reset_task);
+}
+
+/**
+ * pch_gbe_napi_poll - NAPI receive and transfer polling callback
+ * @napi: Pointer of polling device struct
+ * @budget: The maximum number of a packet
+ * Returns
+ * false: Exit the polling mode
+ * true: Continue the polling mode
+ */
+static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)
+{
+ struct pch_gbe_adapter *adapter =
+ container_of(napi, struct pch_gbe_adapter, napi);
+ struct net_device *netdev = adapter->netdev;
+ int work_done = 0;
+ bool poll_end_flag = false;
+ bool cleaned = false;
+
+ pr_debug("budget : %d\n", budget);
+
+ /* Keep link state information with original netdev */
+ if (!netif_carrier_ok(netdev)) {
+ poll_end_flag = true;
+ } else {
+ cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);
+ pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget);
+
+ if (cleaned)
+ work_done = budget;
+ /* If no Tx and not enough Rx work done,
+ * exit the polling mode
+ */
+ if ((work_done < budget) || !netif_running(netdev))
+ poll_end_flag = true;
+ }
+
+ if (poll_end_flag) {
+ napi_complete(napi);
+ pch_gbe_irq_enable(adapter);
+ }
+
+ pr_debug("poll_end_flag : %d work_done : %d budget : %d\n",
+ poll_end_flag, work_done, budget);
+
+ return work_done;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * pch_gbe_netpoll - Used by things like netconsole to send skbs
+ * @netdev: Network interface device structure
+ */
+static void pch_gbe_netpoll(struct net_device *netdev)
+{
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+
+ disable_irq(adapter->pdev->irq);
+ pch_gbe_intr(adapter->pdev->irq, netdev);
+ enable_irq(adapter->pdev->irq);
+}
+#endif
+
+static const struct net_device_ops pch_gbe_netdev_ops = {
+ .ndo_open = pch_gbe_open,
+ .ndo_stop = pch_gbe_stop,
+ .ndo_start_xmit = pch_gbe_xmit_frame,
+ .ndo_get_stats = pch_gbe_get_stats,
+ .ndo_set_mac_address = pch_gbe_set_mac,
+ .ndo_tx_timeout = pch_gbe_tx_timeout,
+ .ndo_change_mtu = pch_gbe_change_mtu,
+ .ndo_do_ioctl = pch_gbe_ioctl,
+ .ndo_set_multicast_list = &pch_gbe_set_multi,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = pch_gbe_netpoll,
+#endif
+};
+
+static pci_ers_result_t pch_gbe_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+
+ netif_device_detach(netdev);
+ if (netif_running(netdev))
+ pch_gbe_down(adapter);
+ pci_disable_device(pdev);
+ /* Request a slot slot reset. */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t pch_gbe_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+
+ if (pci_enable_device(pdev)) {
+ pr_err("Cannot re-enable PCI device after reset\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_set_master(pdev);
+ pci_enable_wake(pdev, PCI_D0, 0);
+ pch_gbe_hal_power_up_phy(hw);
+ pch_gbe_reset(adapter);
+ /* Clear wake up status */
+ pch_gbe_mac_set_wol_event(hw, 0);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void pch_gbe_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+
+ if (netif_running(netdev)) {
+ if (pch_gbe_up(adapter)) {
+ pr_debug("can't bring device back up after reset\n");
+ return;
+ }
+ }
+ netif_device_attach(netdev);
+}
+
+static int __pch_gbe_suspend(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+ u32 wufc = adapter->wake_up_evt;
+ int retval = 0;
+
+ netif_device_detach(netdev);
+ if (netif_running(netdev))
+ pch_gbe_down(adapter);
+ if (wufc) {
+ pch_gbe_set_multi(netdev);
+ pch_gbe_setup_rctl(adapter);
+ pch_gbe_configure_rx(adapter);
+ pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,
+ hw->mac.link_duplex);
+ pch_gbe_set_mode(adapter, hw->mac.link_speed,
+ hw->mac.link_duplex);
+ pch_gbe_mac_set_wol_event(hw, wufc);
+ pci_disable_device(pdev);
+ } else {
+ pch_gbe_hal_power_down_phy(hw);
+ pch_gbe_mac_set_wol_event(hw, wufc);
+ pci_disable_device(pdev);
+ }
+ return retval;
+}
+
+#ifdef CONFIG_PM
+static int pch_gbe_suspend(struct device *device)
+{
+ struct pci_dev *pdev = to_pci_dev(device);
+
+ return __pch_gbe_suspend(pdev);
+}
+
+static int pch_gbe_resume(struct device *device)
+{
+ struct pci_dev *pdev = to_pci_dev(device);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+ struct pch_gbe_hw *hw = &adapter->hw;
+ u32 err;
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ pr_err("Cannot enable PCI device from suspend\n");
+ return err;
+ }
+ pci_set_master(pdev);
+ pch_gbe_hal_power_up_phy(hw);
+ pch_gbe_reset(adapter);
+ /* Clear wake on lan control and status */
+ pch_gbe_mac_set_wol_event(hw, 0);
+
+ if (netif_running(netdev))
+ pch_gbe_up(adapter);
+ netif_device_attach(netdev);
+
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+static void pch_gbe_shutdown(struct pci_dev *pdev)
+{
+ __pch_gbe_suspend(pdev);
+ if (system_state == SYSTEM_POWER_OFF) {
+ pci_wake_from_d3(pdev, true);
+ pci_set_power_state(pdev, PCI_D3hot);
+ }
+}
+
+static void pch_gbe_remove(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+
+ flush_scheduled_work();
+ unregister_netdev(netdev);
+
+ pch_gbe_hal_phy_hw_reset(&adapter->hw);
+
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+
+ iounmap(adapter->hw.reg);
+ pci_release_regions(pdev);
+ free_netdev(netdev);
+ pci_disable_device(pdev);
+}
+
+static int pch_gbe_probe(struct pci_dev *pdev,
+ const struct pci_device_id *pci_id)
+{
+ struct net_device *netdev;
+ struct pch_gbe_adapter *adapter;
+ int ret;
+
+ ret = pci_enable_device(pdev);
+ if (ret)
+ return ret;
+
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+ || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (ret) {
+ ret = pci_set_consistent_dma_mask(pdev,
+ DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(&pdev->dev, "ERR: No usable DMA "
+ "configuration, aborting\n");
+ goto err_disable_device;
+ }
+ }
+ }
+
+ ret = pci_request_regions(pdev, KBUILD_MODNAME);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "ERR: Can't reserve PCI I/O and memory resources\n");
+ goto err_disable_device;
+ }
+ pci_set_master(pdev);
+
+ netdev = alloc_etherdev((int)sizeof(struct pch_gbe_adapter));
+ if (!netdev) {
+ ret = -ENOMEM;
+ dev_err(&pdev->dev,
+ "ERR: Can't allocate and set up an Ethernet device\n");
+ goto err_release_pci;
+ }
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
+ pci_set_drvdata(pdev, netdev);
+ adapter = netdev_priv(netdev);
+ adapter->netdev = netdev;
+ adapter->pdev = pdev;
+ adapter->hw.back = adapter;
+ adapter->hw.reg = pci_iomap(pdev, PCH_GBE_PCI_BAR, 0);
+ if (!adapter->hw.reg) {
+ ret = -EIO;
+ dev_err(&pdev->dev, "Can't ioremap\n");
+ goto err_free_netdev;
+ }
+
+ netdev->netdev_ops = &pch_gbe_netdev_ops;
+ 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_HW_CSUM | NETIF_F_GRO;
+ pch_gbe_set_ethtool_ops(netdev);
+
+ pch_gbe_mac_reset_hw(&adapter->hw);
+
+ /* setup the private structure */
+ ret = pch_gbe_sw_init(adapter);
+ if (ret)
+ goto err_iounmap;
+
+ /* Initialize PHY */
+ ret = pch_gbe_init_phy(adapter);
+ if (ret) {
+ dev_err(&pdev->dev, "PHY initialize error\n");
+ goto err_free_adapter;
+ }
+ pch_gbe_hal_get_bus_info(&adapter->hw);
+
+ /* Read the MAC address. and store to the private data */
+ ret = pch_gbe_hal_read_mac_addr(&adapter->hw);
+ if (ret) {
+ dev_err(&pdev->dev, "MAC address Read Error\n");
+ goto err_free_adapter;
+ }
+
+ memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
+ if (!is_valid_ether_addr(netdev->dev_addr)) {
+ dev_err(&pdev->dev, "Invalid MAC Address\n");
+ ret = -EIO;
+ goto err_free_adapter;
+ }
+ setup_timer(&adapter->watchdog_timer, pch_gbe_watchdog,
+ (unsigned long)adapter);
+
+ INIT_WORK(&adapter->reset_task, pch_gbe_reset_task);
+
+ pch_gbe_check_options(adapter);
+
+ if (adapter->tx_csum)
+ netdev->features |= NETIF_F_HW_CSUM;
+ else
+ netdev->features &= ~NETIF_F_HW_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);
+
+ /* reset the hardware with the new settings */
+ pch_gbe_reset(adapter);
+
+ ret = register_netdev(netdev);
+ if (ret)
+ goto err_free_adapter;
+ /* tell the stack to leave us alone until pch_gbe_open() is called */
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+
+ dev_dbg(&pdev->dev, "OKIsemi(R) PCH Network Connection\n");
+
+ device_set_wakeup_enable(&pdev->dev, 1);
+ return 0;
+
+err_free_adapter:
+ pch_gbe_hal_phy_hw_reset(&adapter->hw);
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+err_iounmap:
+ iounmap(adapter->hw.reg);
+err_free_netdev:
+ free_netdev(netdev);
+err_release_pci:
+ pci_release_regions(pdev);
+err_disable_device:
+ pci_disable_device(pdev);
+ return ret;
+}
+
+static DEFINE_PCI_DEVICE_TABLE(pch_gbe_pcidev_id) = {
+ {.vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_IOH1_GBE,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class = (PCI_CLASS_NETWORK_ETHERNET << 8),
+ .class_mask = (0xFFFF00)
+ },
+ /* required last entry */
+ {0}
+};
+
+#ifdef CONFIG_PM
+static const struct dev_pm_ops pch_gbe_pm_ops = {
+ .suspend = pch_gbe_suspend,
+ .resume = pch_gbe_resume,
+ .freeze = pch_gbe_suspend,
+ .thaw = pch_gbe_resume,
+ .poweroff = pch_gbe_suspend,
+ .restore = pch_gbe_resume,
+};
+#endif
+
+static struct pci_error_handlers pch_gbe_err_handler = {
+ .error_detected = pch_gbe_io_error_detected,
+ .slot_reset = pch_gbe_io_slot_reset,
+ .resume = pch_gbe_io_resume
+};
+
+static struct pci_driver pch_gbe_pcidev = {
+ .name = KBUILD_MODNAME,
+ .id_table = pch_gbe_pcidev_id,
+ .probe = pch_gbe_probe,
+ .remove = pch_gbe_remove,
+#ifdef CONFIG_PM_OPS
+ .driver.pm = &pch_gbe_pm_ops,
+#endif
+ .shutdown = pch_gbe_shutdown,
+ .err_handler = &pch_gbe_err_handler
+};
+
+
+static int __init pch_gbe_init_module(void)
+{
+ int ret;
+
+ ret = pci_register_driver(&pch_gbe_pcidev);
+ if (copybreak != PCH_GBE_COPYBREAK_DEFAULT) {
+ if (copybreak == 0) {
+ pr_info("copybreak disabled\n");
+ } else {
+ pr_info("copybreak enabled for packets <= %u bytes\n",
+ copybreak);
+ }
+ }
+ return ret;
+}
+
+static void __exit pch_gbe_exit_module(void)
+{
+ pci_unregister_driver(&pch_gbe_pcidev);
+}
+
+module_init(pch_gbe_init_module);
+module_exit(pch_gbe_exit_module);
+
+MODULE_DESCRIPTION("OKI semiconductor PCH Gigabit ethernet Driver");
+MODULE_AUTHOR("OKI semiconductor, <masa-korg@dsn.okisemi.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_DEVICE_TABLE(pci, pch_gbe_pcidev_id);
+
+module_param(copybreak, uint, 0644);
+MODULE_PARM_DESC(copybreak,
+ "Maximum size of packet that is copied to a new buffer on receive");
+
+/* pch_gbe_main.c */
diff --git a/drivers/net/pch_gbe/pch_gbe_param.c b/drivers/net/pch_gbe/pch_gbe_param.c
new file mode 100644
index 000000000000..2510146fc560
--- /dev/null
+++ b/drivers/net/pch_gbe/pch_gbe_param.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 1999 - 2010 Intel Corporation.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This code was derived from the Intel e1000e Linux driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "pch_gbe.h"
+
+#define OPTION_UNSET -1
+#define OPTION_DISABLED 0
+#define OPTION_ENABLED 1
+
+/**
+ * TxDescriptors - Transmit Descriptor Count
+ * @Valid Range: PCH_GBE_MIN_TXD - PCH_GBE_MAX_TXD
+ * @Default Value: PCH_GBE_DEFAULT_TXD
+ */
+static int TxDescriptors = OPTION_UNSET;
+module_param(TxDescriptors, int, 0);
+MODULE_PARM_DESC(TxDescriptors, "Number of transmit descriptors");
+
+/**
+ * RxDescriptors -Receive Descriptor Count
+ * @Valid Range: PCH_GBE_MIN_RXD - PCH_GBE_MAX_RXD
+ * @Default Value: PCH_GBE_DEFAULT_RXD
+ */
+static int RxDescriptors = OPTION_UNSET;
+module_param(RxDescriptors, int, 0);
+MODULE_PARM_DESC(RxDescriptors, "Number of receive descriptors");
+
+/**
+ * Speed - User Specified Speed Override
+ * @Valid Range: 0, 10, 100, 1000
+ * - 0: auto-negotiate at all supported speeds
+ * - 10: only link at 10 Mbps
+ * - 100: only link at 100 Mbps
+ * - 1000: only link at 1000 Mbps
+ * @Default Value: 0
+ */
+static int Speed = OPTION_UNSET;
+module_param(Speed, int, 0);
+MODULE_PARM_DESC(Speed, "Speed setting");
+
+/**
+ * Duplex - User Specified Duplex Override
+ * @Valid Range: 0-2
+ * - 0: auto-negotiate for duplex
+ * - 1: only link at half duplex
+ * - 2: only link at full duplex
+ * @Default Value: 0
+ */
+static int Duplex = OPTION_UNSET;
+module_param(Duplex, int, 0);
+MODULE_PARM_DESC(Duplex, "Duplex setting");
+
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+/**
+ * AutoNeg - Auto-negotiation Advertisement Override
+ * @Valid Range: 0x01-0x0F, 0x20-0x2F
+ *
+ * The AutoNeg value is a bit mask describing which speed and duplex
+ * combinations should be advertised during auto-negotiation.
+ * The supported speed and duplex modes are listed below
+ *
+ * Bit 7 6 5 4 3 2 1 0
+ * Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10
+ * Duplex Full Full Half Full Half
+ *
+ * @Default Value: 0x2F (copper)
+ */
+static int AutoNeg = OPTION_UNSET;
+module_param(AutoNeg, int, 0);
+MODULE_PARM_DESC(AutoNeg, "Advertised auto-negotiation setting");
+
+#define PHY_ADVERTISE_10_HALF 0x0001
+#define PHY_ADVERTISE_10_FULL 0x0002
+#define PHY_ADVERTISE_100_HALF 0x0004
+#define PHY_ADVERTISE_100_FULL 0x0008
+#define PHY_ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */
+#define PHY_ADVERTISE_1000_FULL 0x0020
+#define PCH_AUTONEG_ADVERTISE_DEFAULT 0x2F
+
+/**
+ * FlowControl - User Specified Flow Control Override
+ * @Valid Range: 0-3
+ * - 0: No Flow Control
+ * - 1: Rx only, respond to PAUSE frames but do not generate them
+ * - 2: Tx only, generate PAUSE frames but ignore them on receive
+ * - 3: Full Flow Control Support
+ * @Default Value: Read flow control settings from the EEPROM
+ */
+static int FlowControl = OPTION_UNSET;
+module_param(FlowControl, int, 0);
+MODULE_PARM_DESC(FlowControl, "Flow Control setting");
+
+/*
+ * XsumRX - Receive Checksum Offload Enable/Disable
+ * @Valid Range: 0, 1
+ * - 0: disables all checksum offload
+ * - 1: enables receive IP/TCP/UDP checksum offload
+ * @Default Value: PCH_GBE_DEFAULT_RX_CSUM
+ */
+static int XsumRX = OPTION_UNSET;
+module_param(XsumRX, int, 0);
+MODULE_PARM_DESC(XsumRX, "Disable or enable Receive Checksum offload");
+
+#define PCH_GBE_DEFAULT_RX_CSUM true /* trueorfalse */
+
+/*
+ * XsumTX - Transmit Checksum Offload Enable/Disable
+ * @Valid Range: 0, 1
+ * - 0: disables all checksum offload
+ * - 1: enables transmit IP/TCP/UDP checksum offload
+ * @Default Value: PCH_GBE_DEFAULT_TX_CSUM
+ */
+static int XsumTX = OPTION_UNSET;
+module_param(XsumTX, int, 0);
+MODULE_PARM_DESC(XsumTX, "Disable or enable Transmit Checksum offload");
+
+#define PCH_GBE_DEFAULT_TX_CSUM true /* trueorfalse */
+
+/**
+ * pch_gbe_option - Force the MAC's flow control settings
+ * @hw: Pointer to the HW structure
+ * Returns
+ * 0: Successful.
+ * Negative value: Failed.
+ */
+struct pch_gbe_option {
+ enum { enable_option, range_option, list_option } type;
+ char *name;
+ char *err;
+ int def;
+ union {
+ struct { /* range_option info */
+ int min;
+ int max;
+ } r;
+ struct { /* list_option info */
+ int nr;
+ const struct pch_gbe_opt_list { int i; char *str; } *p;
+ } l;
+ } arg;
+};
+
+static const struct pch_gbe_opt_list speed_list[] = {
+ { 0, "" },
+ { SPEED_10, "" },
+ { SPEED_100, "" },
+ { SPEED_1000, "" }
+};
+
+static const struct pch_gbe_opt_list dplx_list[] = {
+ { 0, "" },
+ { HALF_DUPLEX, "" },
+ { FULL_DUPLEX, "" }
+};
+
+static const struct pch_gbe_opt_list an_list[] =
+ #define AA "AutoNeg advertising "
+ {{ 0x01, AA "10/HD" },
+ { 0x02, AA "10/FD" },
+ { 0x03, AA "10/FD, 10/HD" },
+ { 0x04, AA "100/HD" },
+ { 0x05, AA "100/HD, 10/HD" },
+ { 0x06, AA "100/HD, 10/FD" },
+ { 0x07, AA "100/HD, 10/FD, 10/HD" },
+ { 0x08, AA "100/FD" },
+ { 0x09, AA "100/FD, 10/HD" },
+ { 0x0a, AA "100/FD, 10/FD" },
+ { 0x0b, AA "100/FD, 10/FD, 10/HD" },
+ { 0x0c, AA "100/FD, 100/HD" },
+ { 0x0d, AA "100/FD, 100/HD, 10/HD" },
+ { 0x0e, AA "100/FD, 100/HD, 10/FD" },
+ { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" },
+ { 0x20, AA "1000/FD" },
+ { 0x21, AA "1000/FD, 10/HD" },
+ { 0x22, AA "1000/FD, 10/FD" },
+ { 0x23, AA "1000/FD, 10/FD, 10/HD" },
+ { 0x24, AA "1000/FD, 100/HD" },
+ { 0x25, AA "1000/FD, 100/HD, 10/HD" },
+ { 0x26, AA "1000/FD, 100/HD, 10/FD" },
+ { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" },
+ { 0x28, AA "1000/FD, 100/FD" },
+ { 0x29, AA "1000/FD, 100/FD, 10/HD" },
+ { 0x2a, AA "1000/FD, 100/FD, 10/FD" },
+ { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" },
+ { 0x2c, AA "1000/FD, 100/FD, 100/HD" },
+ { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" },
+ { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" },
+ { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }
+};
+
+static const struct pch_gbe_opt_list fc_list[] = {
+ { PCH_GBE_FC_NONE, "Flow Control Disabled" },
+ { PCH_GBE_FC_RX_PAUSE, "Flow Control Receive Only" },
+ { PCH_GBE_FC_TX_PAUSE, "Flow Control Transmit Only" },
+ { PCH_GBE_FC_FULL, "Flow Control Enabled" }
+};
+
+/**
+ * pch_gbe_validate_option - Validate option
+ * @value: value
+ * @opt: option
+ * @adapter: Board private structure
+ * Returns
+ * 0: Successful.
+ * Negative value: Failed.
+ */
+static int pch_gbe_validate_option(int *value,
+ const struct pch_gbe_option *opt,
+ struct pch_gbe_adapter *adapter)
+{
+ if (*value == OPTION_UNSET) {
+ *value = opt->def;
+ return 0;
+ }
+
+ switch (opt->type) {
+ case enable_option:
+ switch (*value) {
+ case OPTION_ENABLED:
+ pr_debug("%s Enabled\n", opt->name);
+ return 0;
+ case OPTION_DISABLED:
+ pr_debug("%s Disabled\n", opt->name);
+ return 0;
+ }
+ break;
+ case range_option:
+ if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+ pr_debug("%s set to %i\n", opt->name, *value);
+ return 0;
+ }
+ break;
+ case list_option: {
+ int i;
+ const struct pch_gbe_opt_list *ent;
+
+ for (i = 0; i < opt->arg.l.nr; i++) {
+ ent = &opt->arg.l.p[i];
+ if (*value == ent->i) {
+ if (ent->str[0] != '\0')
+ pr_debug("%s\n", ent->str);
+ return 0;
+ }
+ }
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ pr_debug("Invalid %s value specified (%i) %s\n",
+ opt->name, *value, opt->err);
+ *value = opt->def;
+ return -1;
+}
+
+/**
+ * pch_gbe_check_copper_options - Range Checking for Link Options, Copper Version
+ * @adapter: Board private structure
+ */
+static void pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ int speed, dplx;
+
+ { /* Speed */
+ static const struct pch_gbe_option opt = {
+ .type = list_option,
+ .name = "Speed",
+ .err = "parameter ignored",
+ .def = 0,
+ .arg = { .l = { .nr = (int)ARRAY_SIZE(speed_list),
+ .p = speed_list } }
+ };
+ speed = Speed;
+ pch_gbe_validate_option(&speed, &opt, adapter);
+ }
+ { /* Duplex */
+ static const struct pch_gbe_option opt = {
+ .type = list_option,
+ .name = "Duplex",
+ .err = "parameter ignored",
+ .def = 0,
+ .arg = { .l = { .nr = (int)ARRAY_SIZE(dplx_list),
+ .p = dplx_list } }
+ };
+ dplx = Duplex;
+ pch_gbe_validate_option(&dplx, &opt, adapter);
+ }
+
+ { /* Autoneg */
+ static const struct pch_gbe_option opt = {
+ .type = list_option,
+ .name = "AutoNeg",
+ .err = "parameter ignored",
+ .def = PCH_AUTONEG_ADVERTISE_DEFAULT,
+ .arg = { .l = { .nr = (int)ARRAY_SIZE(an_list),
+ .p = an_list} }
+ };
+ if (speed || dplx) {
+ pr_debug("AutoNeg specified along with Speed or Duplex, AutoNeg parameter ignored\n");
+ hw->phy.autoneg_advertised = opt.def;
+ } else {
+ hw->phy.autoneg_advertised = AutoNeg;
+ pch_gbe_validate_option(
+ (int *)(&hw->phy.autoneg_advertised),
+ &opt, adapter);
+ }
+ }
+
+ switch (speed + dplx) {
+ case 0:
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ if ((speed || dplx))
+ pr_debug("Speed and duplex autonegotiation enabled\n");
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case HALF_DUPLEX:
+ pr_debug("Half Duplex specified without Speed\n");
+ pr_debug("Using Autonegotiation at Half Duplex only\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |
+ PHY_ADVERTISE_100_HALF;
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case FULL_DUPLEX:
+ pr_debug("Full Duplex specified without Speed\n");
+ pr_debug("Using Autonegotiation at Full Duplex only\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ hw->phy.autoneg_advertised = PHY_ADVERTISE_10_FULL |
+ PHY_ADVERTISE_100_FULL |
+ PHY_ADVERTISE_1000_FULL;
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_FULL;
+ break;
+ case SPEED_10:
+ pr_debug("10 Mbps Speed specified without Duplex\n");
+ pr_debug("Using Autonegotiation at 10 Mbps only\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |
+ PHY_ADVERTISE_10_FULL;
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case SPEED_10 + HALF_DUPLEX:
+ pr_debug("Forcing to 10 Mbps Half Duplex\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+ hw->phy.autoneg_advertised = 0;
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case SPEED_10 + FULL_DUPLEX:
+ pr_debug("Forcing to 10 Mbps Full Duplex\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+ hw->phy.autoneg_advertised = 0;
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_FULL;
+ break;
+ case SPEED_100:
+ pr_debug("100 Mbps Speed specified without Duplex\n");
+ pr_debug("Using Autonegotiation at 100 Mbps only\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ hw->phy.autoneg_advertised = PHY_ADVERTISE_100_HALF |
+ PHY_ADVERTISE_100_FULL;
+ hw->mac.link_speed = SPEED_100;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case SPEED_100 + HALF_DUPLEX:
+ pr_debug("Forcing to 100 Mbps Half Duplex\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+ hw->phy.autoneg_advertised = 0;
+ hw->mac.link_speed = SPEED_100;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case SPEED_100 + FULL_DUPLEX:
+ pr_debug("Forcing to 100 Mbps Full Duplex\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+ hw->phy.autoneg_advertised = 0;
+ hw->mac.link_speed = SPEED_100;
+ hw->mac.link_duplex = DUPLEX_FULL;
+ break;
+ case SPEED_1000:
+ pr_debug("1000 Mbps Speed specified without Duplex\n");
+ goto full_duplex_only;
+ case SPEED_1000 + HALF_DUPLEX:
+ pr_debug("Half Duplex is not supported at 1000 Mbps\n");
+ /* fall through */
+ case SPEED_1000 + FULL_DUPLEX:
+full_duplex_only:
+ pr_debug("Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ hw->phy.autoneg_advertised = PHY_ADVERTISE_1000_FULL;
+ hw->mac.link_speed = SPEED_1000;
+ hw->mac.link_duplex = DUPLEX_FULL;
+ break;
+ default:
+ BUG();
+ }
+}
+
+/**
+ * pch_gbe_check_options - Range Checking for Command Line Parameters
+ * @adapter: Board private structure
+ */
+void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+
+ { /* Transmit Descriptor Count */
+ static const struct pch_gbe_option opt = {
+ .type = range_option,
+ .name = "Transmit Descriptors",
+ .err = "using default of "
+ __MODULE_STRING(PCH_GBE_DEFAULT_TXD),
+ .def = PCH_GBE_DEFAULT_TXD,
+ .arg = { .r = { .min = PCH_GBE_MIN_TXD } },
+ .arg = { .r = { .max = PCH_GBE_MAX_TXD } }
+ };
+ struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
+ tx_ring->count = TxDescriptors;
+ pch_gbe_validate_option(&tx_ring->count, &opt, adapter);
+ tx_ring->count = roundup(tx_ring->count,
+ PCH_GBE_TX_DESC_MULTIPLE);
+ }
+ { /* Receive Descriptor Count */
+ static const struct pch_gbe_option opt = {
+ .type = range_option,
+ .name = "Receive Descriptors",
+ .err = "using default of "
+ __MODULE_STRING(PCH_GBE_DEFAULT_RXD),
+ .def = PCH_GBE_DEFAULT_RXD,
+ .arg = { .r = { .min = PCH_GBE_MIN_RXD } },
+ .arg = { .r = { .max = PCH_GBE_MAX_RXD } }
+ };
+ struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
+ rx_ring->count = RxDescriptors;
+ pch_gbe_validate_option(&rx_ring->count, &opt, adapter);
+ rx_ring->count = roundup(rx_ring->count,
+ PCH_GBE_RX_DESC_MULTIPLE);
+ }
+ { /* Checksum Offload Enable/Disable */
+ static const struct pch_gbe_option opt = {
+ .type = enable_option,
+ .name = "Checksum Offload",
+ .err = "defaulting to Enabled",
+ .def = PCH_GBE_DEFAULT_RX_CSUM
+ };
+ adapter->rx_csum = XsumRX;
+ pch_gbe_validate_option((int *)(&adapter->rx_csum),
+ &opt, adapter);
+ }
+ { /* Checksum Offload Enable/Disable */
+ static const struct pch_gbe_option opt = {
+ .type = enable_option,
+ .name = "Checksum Offload",
+ .err = "defaulting to Enabled",
+ .def = PCH_GBE_DEFAULT_TX_CSUM
+ };
+ adapter->tx_csum = XsumTX;
+ pch_gbe_validate_option((int *)(&adapter->tx_csum),
+ &opt, adapter);
+ }
+ { /* Flow Control */
+ static const struct pch_gbe_option opt = {
+ .type = list_option,
+ .name = "Flow Control",
+ .err = "reading default settings from EEPROM",
+ .def = PCH_GBE_FC_DEFAULT,
+ .arg = { .l = { .nr = (int)ARRAY_SIZE(fc_list),
+ .p = fc_list } }
+ };
+ hw->mac.fc = FlowControl;
+ pch_gbe_validate_option((int *)(&hw->mac.fc),
+ &opt, adapter);
+ }
+
+ pch_gbe_check_copper_options(adapter);
+}
diff --git a/drivers/net/pch_gbe/pch_gbe_phy.c b/drivers/net/pch_gbe/pch_gbe_phy.c
new file mode 100644
index 000000000000..923a687acd30
--- /dev/null
+++ b/drivers/net/pch_gbe/pch_gbe_phy.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 1999 - 2010 Intel Corporation.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This code was derived from the Intel e1000e Linux driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "pch_gbe.h"
+#include "pch_gbe_phy.h"
+
+#define PHY_MAX_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
+
+/* PHY 1000 MII Register/Bit Definitions */
+/* PHY Registers defined by IEEE */
+#define PHY_CONTROL 0x00 /* Control Register */
+#define PHY_STATUS 0x01 /* Status Regiser */
+#define PHY_ID1 0x02 /* Phy Id Register (word 1) */
+#define PHY_ID2 0x03 /* Phy Id Register (word 2) */
+#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
+#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Register */
+#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
+#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
+#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Register */
+#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Register */
+#define PHY_EXT_STATUS 0x0F /* Extended Status Register */
+#define PHY_PHYSP_CONTROL 0x10 /* PHY Specific Control Register */
+#define PHY_EXT_PHYSP_CONTROL 0x14 /* Extended PHY Specific Control Register */
+#define PHY_LED_CONTROL 0x18 /* LED Control Register */
+#define PHY_EXT_PHYSP_STATUS 0x1B /* Extended PHY Specific Status Register */
+
+/* PHY Control Register */
+#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
+#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
+#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
+#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
+#define MII_CR_POWER_DOWN 0x0800 /* Power down */
+#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
+#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
+#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
+#define MII_CR_SPEED_1000 0x0040
+#define MII_CR_SPEED_100 0x2000
+#define MII_CR_SPEED_10 0x0000
+
+/* PHY Status Register */
+#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
+#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
+#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
+#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
+#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
+#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
+#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
+#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
+#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
+#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
+#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
+#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
+#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
+#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
+#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
+
+/* Phy Id Register (word 2) */
+#define PHY_REVISION_MASK 0x000F
+
+/* PHY Specific Control Register */
+#define PHYSP_CTRL_ASSERT_CRS_TX 0x0800
+
+
+/* Default value of PHY register */
+#define PHY_CONTROL_DEFAULT 0x1140 /* Control Register */
+#define PHY_AUTONEG_ADV_DEFAULT 0x01e0 /* Autoneg Advertisement */
+#define PHY_NEXT_PAGE_TX_DEFAULT 0x2001 /* Next Page TX */
+#define PHY_1000T_CTRL_DEFAULT 0x0300 /* 1000Base-T Control Register */
+#define PHY_PHYSP_CONTROL_DEFAULT 0x01EE /* PHY Specific Control Register */
+
+/**
+ * pch_gbe_phy_get_id - Retrieve the PHY ID and revision
+ * @hw: Pointer to the HW structure
+ * Returns
+ * 0: Successful.
+ * Negative value: Failed.
+ */
+s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw)
+{
+ struct pch_gbe_phy_info *phy = &hw->phy;
+ s32 ret;
+ u16 phy_id1;
+ u16 phy_id2;
+
+ ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID1, &phy_id1);
+ if (ret)
+ return ret;
+ ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID2, &phy_id2);
+ if (ret)
+ return ret;
+ /*
+ * PHY_ID1: [bit15-0:ID(21-6)]
+ * PHY_ID2: [bit15-10:ID(5-0)][bit9-4:Model][bit3-0:revision]
+ */
+ phy->id = (u32)phy_id1;
+ phy->id = ((phy->id << 6) | ((phy_id2 & 0xFC00) >> 10));
+ phy->revision = (u32) (phy_id2 & 0x000F);
+ pr_debug("phy->id : 0x%08x phy->revision : 0x%08x\n",
+ phy->id, phy->revision);
+ return 0;
+}
+
+/**
+ * pch_gbe_phy_read_reg_miic - Read MII control register
+ * @hw: Pointer to the HW structure
+ * @offset: Register offset to be read
+ * @data: Pointer to the read data
+ * Returns
+ * 0: Successful.
+ * -EINVAL: Invalid argument.
+ */
+s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data)
+{
+ struct pch_gbe_phy_info *phy = &hw->phy;
+
+ if (offset > PHY_MAX_REG_ADDRESS) {
+ pr_err("PHY Address %d is out of range\n", offset);
+ return -EINVAL;
+ }
+ *data = pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_READ,
+ offset, (u16)0);
+ return 0;
+}
+
+/**
+ * pch_gbe_phy_write_reg_miic - Write MII control register
+ * @hw: Pointer to the HW structure
+ * @offset: Register offset to be read
+ * @data: data to write to register at offset
+ * Returns
+ * 0: Successful.
+ * -EINVAL: Invalid argument.
+ */
+s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data)
+{
+ struct pch_gbe_phy_info *phy = &hw->phy;
+
+ if (offset > PHY_MAX_REG_ADDRESS) {
+ pr_err("PHY Address %d is out of range\n", offset);
+ return -EINVAL;
+ }
+ pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_WRITE,
+ offset, data);
+ return 0;
+}
+
+/**
+ * pch_gbe_phy_sw_reset - PHY software reset
+ * @hw: Pointer to the HW structure
+ */
+void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw)
+{
+ u16 phy_ctrl;
+
+ pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &phy_ctrl);
+ phy_ctrl |= MII_CR_RESET;
+ pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, phy_ctrl);
+ udelay(1);
+}
+
+/**
+ * pch_gbe_phy_hw_reset - PHY hardware reset
+ * @hw: Pointer to the HW structure
+ */
+void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw)
+{
+ pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, PHY_CONTROL_DEFAULT);
+ pch_gbe_phy_write_reg_miic(hw, PHY_AUTONEG_ADV,
+ PHY_AUTONEG_ADV_DEFAULT);
+ pch_gbe_phy_write_reg_miic(hw, PHY_NEXT_PAGE_TX,
+ PHY_NEXT_PAGE_TX_DEFAULT);
+ pch_gbe_phy_write_reg_miic(hw, PHY_1000T_CTRL, PHY_1000T_CTRL_DEFAULT);
+ pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL,
+ PHY_PHYSP_CONTROL_DEFAULT);
+}
+
+/**
+ * pch_gbe_phy_power_up - restore link in case the phy was powered down
+ * @hw: Pointer to the HW structure
+ */
+void pch_gbe_phy_power_up(struct pch_gbe_hw *hw)
+{
+ u16 mii_reg;
+
+ mii_reg = 0;
+ /* Just clear the power down bit to wake the phy back up */
+ /* according to the manual, the phy will retain its
+ * settings across a power-down/up cycle */
+ pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg);
+ mii_reg &= ~MII_CR_POWER_DOWN;
+ pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg);
+}
+
+/**
+ * pch_gbe_phy_power_down - Power down PHY
+ * @hw: Pointer to the HW structure
+ */
+void pch_gbe_phy_power_down(struct pch_gbe_hw *hw)
+{
+ u16 mii_reg;
+
+ mii_reg = 0;
+ /* Power down the PHY so no link is implied when interface is down *
+ * The PHY cannot be powered down if any of the following is TRUE *
+ * (a) WoL is enabled
+ * (b) AMT is active
+ */
+ pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg);
+ mii_reg |= MII_CR_POWER_DOWN;
+ pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg);
+ mdelay(1);
+}
+
+/**
+ * pch_gbe_phy_set_rgmii - RGMII interface setting
+ * @hw: Pointer to the HW structure
+ */
+inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw)
+{
+ pch_gbe_phy_sw_reset(hw);
+}
+
+/**
+ * pch_gbe_phy_init_setting - PHY initial setting
+ * @hw: Pointer to the HW structure
+ */
+void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
+{
+ struct pch_gbe_adapter *adapter;
+ struct ethtool_cmd cmd;
+ int ret;
+ u16 mii_reg;
+
+ adapter = container_of(hw, struct pch_gbe_adapter, hw);
+ ret = mii_ethtool_gset(&adapter->mii, &cmd);
+ if (ret)
+ pr_err("Error: mii_ethtool_gset\n");
+
+ cmd.speed = hw->mac.link_speed;
+ cmd.duplex = hw->mac.link_duplex;
+ cmd.advertising = hw->phy.autoneg_advertised;
+ cmd.autoneg = hw->mac.autoneg;
+ pch_gbe_phy_write_reg_miic(hw, MII_BMCR, BMCR_RESET);
+ ret = mii_ethtool_sset(&adapter->mii, &cmd);
+ if (ret)
+ pr_err("Error: mii_ethtool_sset\n");
+
+ pch_gbe_phy_sw_reset(hw);
+
+ pch_gbe_phy_read_reg_miic(hw, PHY_PHYSP_CONTROL, &mii_reg);
+ mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX;
+ pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, mii_reg);
+
+}
diff --git a/drivers/net/pch_gbe/pch_gbe_phy.h b/drivers/net/pch_gbe/pch_gbe_phy.h
new file mode 100644
index 000000000000..03264dc7b5ec
--- /dev/null
+++ b/drivers/net/pch_gbe/pch_gbe_phy.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 1999 - 2010 Intel Corporation.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This code was derived from the Intel e1000e Linux driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef _PCH_GBE_PHY_H_
+#define _PCH_GBE_PHY_H_
+
+#define PCH_GBE_PHY_REGS_LEN 32
+#define PCH_GBE_PHY_RESET_DELAY_US 10
+#define PCH_GBE_MAC_IFOP_RGMII
+
+s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw);
+s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data);
+s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data);
+void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw);
+void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw);
+void pch_gbe_phy_power_up(struct pch_gbe_hw *hw);
+void pch_gbe_phy_power_down(struct pch_gbe_hw *hw);
+void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw);
+void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw);
+
+#endif /* _PCH_GBE_PHY_H_ */
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 56f3fc45dbaa..8dd03439d994 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -1125,7 +1125,7 @@ static int netdrv_open(struct net_device *dev)
init_timer(&tp->timer);
tp->timer.expires = jiffies + 3 * HZ;
tp->timer.data = (unsigned long) dev;
- tp->timer.function = &netdrv_timer;
+ tp->timer.function = netdrv_timer;
add_timer(&tp->timer);
DPRINTK("EXIT, returning 0\n");
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index ff824e11f0b6..2807a0fcadc4 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -69,6 +69,8 @@ earlier 3Com products.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -83,7 +85,6 @@ earlier 3Com products.
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/ioport.h>
-#include <linux/ethtool.h>
#include <linux/bitops.h>
#include <linux/mii.h>
@@ -237,7 +238,6 @@ static int el3_rx(struct net_device *dev, int worklimit);
static int el3_close(struct net_device *dev);
static void el3_tx_timeout(struct net_device *dev);
static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static const struct ethtool_ops netdev_ethtool_ops;
static void set_rx_mode(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
@@ -283,7 +283,6 @@ static int tc574_probe(struct pcmcia_device *link)
link->config_index = 1;
dev->netdev_ops = &el3_netdev_ops;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
dev->watchdog_timeo = TX_TIMEOUT;
return tc574_config(link);
@@ -359,8 +358,8 @@ static int tc574_config(struct pcmcia_device *link)
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
if (phys_addr[0] == htons(0x6060)) {
- printk(KERN_NOTICE "3c574_cs: IO port conflict at 0x%03lx"
- "-0x%03lx\n", dev->base_addr, dev->base_addr+15);
+ pr_notice("IO port conflict at 0x%03lx-0x%03lx\n",
+ dev->base_addr, dev->base_addr+15);
goto failed;
}
}
@@ -374,7 +373,7 @@ static int tc574_config(struct pcmcia_device *link)
outw(2<<11, ioaddr + RunnerRdCtrl);
mcr = inb(ioaddr + 2);
outw(0<<11, ioaddr + RunnerRdCtrl);
- printk(KERN_INFO " ASIC rev %d,", mcr>>3);
+ pr_info(" ASIC rev %d,", mcr>>3);
EL3WINDOW(3);
config = inl(ioaddr + Wn3_Config);
lp->default_media = (config & Xcvr) >> Xcvr_shift;
@@ -411,7 +410,7 @@ static int tc574_config(struct pcmcia_device *link)
}
}
if (phy > 32) {
- printk(KERN_NOTICE " No MII transceivers found!\n");
+ pr_notice(" No MII transceivers found!\n");
goto failed;
}
i = mdio_read(ioaddr, lp->phys, 16) | 0x40;
@@ -427,18 +426,16 @@ static int tc574_config(struct pcmcia_device *link)
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- printk(KERN_INFO "%s: %s at io %#3lx, irq %d, "
- "hw_addr %pM.\n",
- dev->name, cardname, dev->base_addr, dev->irq,
- dev->dev_addr);
- printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n",
- 8 << config & Ram_size,
- ram_split[(config & Ram_split) >> Ram_split_shift],
- config & Autoselect ? "autoselect " : "");
+ netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n",
+ cardname, dev->base_addr, dev->irq, dev->dev_addr);
+ netdev_info(dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n",
+ 8 << config & Ram_size,
+ ram_split[(config & Ram_split) >> Ram_split_shift],
+ config & Autoselect ? "autoselect " : "");
return 0;
@@ -479,14 +476,14 @@ static void dump_status(struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
EL3WINDOW(1);
- printk(KERN_INFO " irq status %04x, rx status %04x, tx status "
- "%02x, tx free %04x\n", inw(ioaddr+EL3_STATUS),
- inw(ioaddr+RxStatus), inb(ioaddr+TxStatus),
- inw(ioaddr+TxFree));
+ netdev_info(dev, " irq status %04x, rx status %04x, tx status %02x, tx free %04x\n",
+ inw(ioaddr+EL3_STATUS),
+ inw(ioaddr+RxStatus), inb(ioaddr+TxStatus),
+ inw(ioaddr+TxFree));
EL3WINDOW(4);
- printk(KERN_INFO " diagnostics: fifo %04x net %04x ethernet %04x"
- " media %04x\n", inw(ioaddr+0x04), inw(ioaddr+0x06),
- inw(ioaddr+0x08), inw(ioaddr+0x0a));
+ netdev_info(dev, " diagnostics: fifo %04x net %04x ethernet %04x media %04x\n",
+ inw(ioaddr+0x04), inw(ioaddr+0x06),
+ inw(ioaddr+0x08), inw(ioaddr+0x0a));
EL3WINDOW(1);
}
@@ -500,7 +497,7 @@ static void tc574_wait_for_completion(struct net_device *dev, int cmd)
while (--i > 0)
if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) break;
if (i == 0)
- printk(KERN_NOTICE "%s: command 0x%04x did not complete!\n", dev->name, cmd);
+ netdev_notice(dev, "command 0x%04x did not complete!\n", cmd);
}
/* Read a word from the EEPROM using the regular EEPROM access register.
@@ -687,7 +684,7 @@ static int el3_open(struct net_device *dev)
netif_start_queue(dev);
tc574_reset(dev);
- lp->media.function = &media_check;
+ lp->media.function = media_check;
lp->media.data = (unsigned long) dev;
lp->media.expires = jiffies + HZ;
add_timer(&lp->media);
@@ -702,7 +699,7 @@ static void el3_tx_timeout(struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
- printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name);
+ netdev_notice(dev, "Transmit timed out!\n");
dump_status(dev);
dev->stats.tx_errors++;
dev->trans_start = jiffies; /* prevent tx timeout */
@@ -825,8 +822,8 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
EL3WINDOW(4);
fifo_diag = inw(ioaddr + Wn4_FIFODiag);
EL3WINDOW(1);
- printk(KERN_NOTICE "%s: adapter failure, FIFO diagnostic"
- " register %04x.\n", dev->name, fifo_diag);
+ netdev_notice(dev, "adapter failure, FIFO diagnostic register %04x\n",
+ fifo_diag);
if (fifo_diag & 0x0400) {
/* Tx overrun */
tc574_wait_for_completion(dev, TxReset);
@@ -880,7 +877,7 @@ static void media_check(unsigned long arg)
this, we can limp along even if the interrupt is blocked */
if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) {
if (!lp->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
local_irq_save(flags);
el3_interrupt(dev->irq, dev);
@@ -903,23 +900,21 @@ static void media_check(unsigned long arg)
if (media != lp->media_status) {
if ((media ^ lp->media_status) & 0x0004)
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (lp->media_status & 0x0004) ? "lost" : "found");
+ netdev_info(dev, "%s link beat\n",
+ (lp->media_status & 0x0004) ? "lost" : "found");
if ((media ^ lp->media_status) & 0x0020) {
lp->partner = 0;
if (lp->media_status & 0x0020) {
- printk(KERN_INFO "%s: autonegotiation restarted\n",
- dev->name);
+ netdev_info(dev, "autonegotiation restarted\n");
} else if (partner) {
partner &= lp->advertising;
lp->partner = partner;
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
- ((partner & 0x0180) ? "100" : "10"),
- ((partner & 0x0140) ? 'F' : 'H'));
+ netdev_info(dev, "autonegotiation complete: "
+ "%dbaseT-%cD selected\n",
+ (partner & 0x0180) ? 100 : 10,
+ (partner & 0x0140) ? 'F' : 'H');
} else {
- printk(KERN_INFO "%s: link partner did not autonegotiate\n",
- dev->name);
+ netdev_info(dev, "link partner did not autonegotiate\n");
}
EL3WINDOW(3);
@@ -929,10 +924,9 @@ static void media_check(unsigned long arg)
}
if (media & 0x0010)
- printk(KERN_INFO "%s: remote fault detected\n",
- dev->name);
+ netdev_info(dev, "remote fault detected\n");
if (media & 0x0002)
- printk(KERN_INFO "%s: jabber detected\n", dev->name);
+ netdev_info(dev, "jabber detected\n");
lp->media_status = media;
}
spin_unlock_irqrestore(&lp->window_lock, flags);
@@ -1042,16 +1036,6 @@ static int el3_rx(struct net_device *dev, int worklimit)
return worklimit;
}
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "3c574_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
/* Provide ioctl() calls to examine the MII xcvr state. */
static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index a07e22295330..79b9ca0dbdb4 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -19,6 +19,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "3c589_cs"
#define DRV_VERSION "1.162-ac"
@@ -237,7 +239,7 @@ static int tc589_config(struct pcmcia_device *link)
__be16 *phys_addr;
int ret, i, j, multi = 0, fifo;
unsigned int ioaddr;
- char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
+ static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
u8 *buf;
size_t len;
@@ -246,8 +248,7 @@ static int tc589_config(struct pcmcia_device *link)
phys_addr = (__be16 *)dev->dev_addr;
/* Is this a 3c562? */
if (link->manf_id != MANFID_3COM)
- printk(KERN_INFO "3c589_cs: hmmm, is this really a "
- "3Com card??\n");
+ dev_info(&link->dev, "hmmm, is this really a 3Com card??\n");
multi = (link->card_id == PRODID_3COM_3C562);
link->io_lines = 16;
@@ -288,8 +289,8 @@ static int tc589_config(struct pcmcia_device *link)
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i));
if (phys_addr[0] == htons(0x6060)) {
- printk(KERN_ERR "3c589_cs: IO port conflict at 0x%03lx"
- "-0x%03lx\n", dev->base_addr, dev->base_addr+15);
+ dev_err(&link->dev, "IO port conflict at 0x%03lx-0x%03lx\n",
+ dev->base_addr, dev->base_addr+15);
goto failed;
}
}
@@ -303,12 +304,12 @@ static int tc589_config(struct pcmcia_device *link)
if ((if_port >= 0) && (if_port <= 3))
dev->if_port = if_port;
else
- printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
+ dev_err(&link->dev, "invalid if_port requested\n");
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
+ dev_err(&link->dev, "register_netdev() failed\n");
goto failed;
}
@@ -502,7 +503,7 @@ static int el3_open(struct net_device *dev)
tc589_reset(dev);
init_timer(&lp->media);
- lp->media.function = &media_check;
+ lp->media.function = media_check;
lp->media.data = (unsigned long) dev;
lp->media.expires = jiffies + HZ;
add_timer(&lp->media);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 9e8b28b271ae..d2e166e29dda 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -24,6 +24,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -32,7 +34,6 @@
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
-#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/crc32.h>
@@ -85,7 +86,6 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb,
static struct net_device_stats *get_stats(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static void axnet_tx_timeout(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
static void ei_watchdog(u_long arg);
static void axnet_reset_8390(struct net_device *dev);
@@ -161,7 +161,6 @@ static int axnet_probe(struct pcmcia_device *link)
dev->netdev_ops = &axnet_netdev_ops;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
dev->watchdog_timeo = TX_TIMEOUT;
return axnet_config(link);
@@ -300,8 +299,8 @@ static int axnet_config(struct pcmcia_device *link)
dev->base_addr = link->resource[0]->start;
if (!get_prom(link)) {
- printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n");
- printk(KERN_NOTICE "axnet_cs: use pcnet_cs instead.\n");
+ pr_notice("this is not an AX88190 card!\n");
+ pr_notice("use pcnet_cs instead.\n");
goto failed;
}
@@ -310,10 +309,10 @@ static int axnet_config(struct pcmcia_device *link)
ei_status.tx_start_page = AXNET_START_PG;
ei_status.rx_start_page = AXNET_START_PG + TX_PAGES;
ei_status.stop_page = AXNET_STOP_PG;
- ei_status.reset_8390 = &axnet_reset_8390;
- ei_status.get_8390_hdr = &get_8390_hdr;
- ei_status.block_input = &block_input;
- ei_status.block_output = &block_output;
+ ei_status.reset_8390 = axnet_reset_8390;
+ ei_status.get_8390_hdr = get_8390_hdr;
+ ei_status.block_input = block_input;
+ ei_status.block_output = block_output;
if (inb(dev->base_addr + AXNET_TEST) != 0)
info->flags |= IS_AX88790;
@@ -346,19 +345,18 @@ static int axnet_config(struct pcmcia_device *link)
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, "
- "hw_addr %pM\n",
- dev->name, ((info->flags & IS_AX88790) ? 7 : 1),
- dev->base_addr, dev->irq,
- dev->dev_addr);
+ netdev_info(dev, "Asix AX88%d90: io %#3lx, irq %d, hw_addr %pM\n",
+ ((info->flags & IS_AX88790) ? 7 : 1),
+ dev->base_addr, dev->irq, dev->dev_addr);
if (info->phy_id != -1) {
- dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", info->phy_id, j);
+ netdev_dbg(dev, " MII transceiver at index %d, status %x\n",
+ info->phy_id, j);
} else {
- printk(KERN_NOTICE " No MII transceivers found!\n");
+ netdev_notice(dev, " No MII transceivers found!\n");
}
return 0;
@@ -477,7 +475,7 @@ static int axnet_open(struct net_device *dev)
info->link_status = 0x00;
init_timer(&info->watchdog);
- info->watchdog.function = &ei_watchdog;
+ info->watchdog.function = ei_watchdog;
info->watchdog.data = (u_long)dev;
info->watchdog.expires = jiffies + HZ;
add_timer(&info->watchdog);
@@ -530,8 +528,7 @@ static void axnet_reset_8390(struct net_device *dev)
outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */
if (i == 100)
- printk(KERN_ERR "%s: axnet_reset_8390() did not complete.\n",
- dev->name);
+ netdev_err(dev, "axnet_reset_8390() did not complete\n");
} /* axnet_reset_8390 */
@@ -558,7 +555,7 @@ static void ei_watchdog(u_long arg)
this, we can limp along even if the interrupt is blocked */
if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
if (!info->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
ei_irq_wrapper(dev->irq, dev);
info->fast_poll = HZ;
}
@@ -573,7 +570,7 @@ static void ei_watchdog(u_long arg)
goto reschedule;
link = mdio_read(mii_addr, info->phy_id, 1);
if (!link || (link == 0xffff)) {
- printk(KERN_INFO "%s: MII is missing!\n", dev->name);
+ netdev_info(dev, "MII is missing!\n");
info->phy_id = -1;
goto reschedule;
}
@@ -581,18 +578,14 @@ static void ei_watchdog(u_long arg)
link &= 0x0004;
if (link != info->link_status) {
u_short p = mdio_read(mii_addr, info->phy_id, 5);
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (link) ? "found" : "lost");
+ netdev_info(dev, "%s link beat\n", link ? "found" : "lost");
if (link) {
info->duplex_flag = (p & 0x0140) ? 0x80 : 0x00;
if (p)
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
- ((p & 0x0180) ? "100" : "10"),
- ((p & 0x0140) ? 'F' : 'H'));
+ netdev_info(dev, "autonegotiation complete: %dbaseT-%cD selected\n",
+ (p & 0x0180) ? 100 : 10, (p & 0x0140) ? 'F' : 'H');
else
- printk(KERN_INFO "%s: link partner did not autonegotiate\n",
- dev->name);
+ netdev_info(dev, "link partner did not autonegotiate\n");
AX88190_init(dev, 1);
}
info->link_status = link;
@@ -603,16 +596,6 @@ reschedule:
add_timer(&info->watchdog);
}
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "axnet_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
/*====================================================================*/
static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -798,9 +781,6 @@ module_exit(exit_axnet_cs);
*/
-static const char version_8390[] = KERN_INFO \
- "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@scyld.com)\n";
-
#include <linux/bitops.h>
#include <asm/irq.h>
#include <linux/fcntl.h>
@@ -947,9 +927,11 @@ static void axnet_tx_timeout(struct net_device *dev)
isr = inb(e8390_base+EN0_ISR);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
- printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",
- dev->name, (txsr & ENTSR_ABT) ? "excess collisions." :
- (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar);
+ netdev_printk(KERN_DEBUG, dev,
+ "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",
+ (txsr & ENTSR_ABT) ? "excess collisions." :
+ (isr) ? "lost interrupt?" : "cable problem?",
+ txsr, isr, tickssofar);
if (!isr && !dev->stats.tx_packets)
{
@@ -1019,22 +1001,28 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb,
output_page = ei_local->tx_start_page;
ei_local->tx1 = send_length;
if (ei_debug && ei_local->tx2 > 0)
- printk(KERN_DEBUG "%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n",
- dev->name, ei_local->tx2, ei_local->lasttx, ei_local->txing);
+ netdev_printk(KERN_DEBUG, dev,
+ "idle transmitter tx2=%d, lasttx=%d, txing=%d\n",
+ ei_local->tx2, ei_local->lasttx,
+ ei_local->txing);
}
else if (ei_local->tx2 == 0)
{
output_page = ei_local->tx_start_page + TX_PAGES/2;
ei_local->tx2 = send_length;
if (ei_debug && ei_local->tx1 > 0)
- printk(KERN_DEBUG "%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n",
- dev->name, ei_local->tx1, ei_local->lasttx, ei_local->txing);
+ netdev_printk(KERN_DEBUG, dev,
+ "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n",
+ ei_local->tx1, ei_local->lasttx,
+ ei_local->txing);
}
else
{ /* We should never get here. */
if (ei_debug)
- printk(KERN_DEBUG "%s: No Tx buffers free! tx1=%d tx2=%d last=%d\n",
- dev->name, ei_local->tx1, ei_local->tx2, ei_local->lasttx);
+ netdev_printk(KERN_DEBUG, dev,
+ "No Tx buffers free! tx1=%d tx2=%d last=%d\n",
+ ei_local->tx1, ei_local->tx2,
+ ei_local->lasttx);
ei_local->irqlock = 0;
netif_stop_queue(dev);
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
@@ -1122,23 +1110,26 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
spin_lock_irqsave(&ei_local->page_lock, flags);
- if (ei_local->irqlock)
- {
+ if (ei_local->irqlock) {
#if 1 /* This might just be an interrupt for a PCI device sharing this line */
+ const char *msg;
/* The "irqlock" check is only for testing. */
- printk(ei_local->irqlock
- ? "%s: Interrupted while interrupts are masked! isr=%#2x imr=%#2x.\n"
- : "%s: Reentering the interrupt handler! isr=%#2x imr=%#2x.\n",
- dev->name, inb_p(e8390_base + EN0_ISR),
- inb_p(e8390_base + EN0_IMR));
+ if (ei_local->irqlock)
+ msg = "Interrupted while interrupts are masked!";
+ else
+ msg = "Reentering the interrupt handler!";
+ netdev_info(dev, "%s, isr=%#2x imr=%#2x\n",
+ msg,
+ inb_p(e8390_base + EN0_ISR),
+ inb_p(e8390_base + EN0_IMR));
#endif
spin_unlock_irqrestore(&ei_local->page_lock, flags);
return IRQ_NONE;
}
if (ei_debug > 3)
- printk(KERN_DEBUG "%s: interrupt(isr=%#2.2x).\n", dev->name,
- inb_p(e8390_base + EN0_ISR));
+ netdev_printk(KERN_DEBUG, dev, "interrupt(isr=%#2.2x)\n",
+ inb_p(e8390_base + EN0_ISR));
outb_p(0x00, e8390_base + EN0_ISR);
ei_local->irqlock = 1;
@@ -1149,7 +1140,8 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
{
if (!netif_running(dev) || (interrupts == 0xff)) {
if (ei_debug > 1)
- printk(KERN_WARNING "%s: interrupt from stopped card\n", dev->name);
+ netdev_warn(dev,
+ "interrupt from stopped card\n");
outb_p(interrupts, e8390_base + EN0_ISR);
interrupts = 0;
break;
@@ -1192,11 +1184,12 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
{
/* 0xFF is valid for a card removal */
if(interrupts!=0xFF)
- printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n",
- dev->name, interrupts);
+ netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n",
+ interrupts);
outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */
} else {
- printk(KERN_WARNING "%s: unknown interrupt %#2x\n", dev->name, interrupts);
+ netdev_warn(dev, "unknown interrupt %#2x\n",
+ interrupts);
outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */
}
}
@@ -1230,18 +1223,19 @@ static void ei_tx_err(struct net_device *dev)
unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
#ifdef VERBOSE_ERROR_DUMP
- printk(KERN_DEBUG "%s: transmitter error (%#2x): ", dev->name, txsr);
+ netdev_printk(KERN_DEBUG, dev,
+ "transmitter error (%#2x):", txsr);
if (txsr & ENTSR_ABT)
- printk("excess-collisions ");
+ pr_cont(" excess-collisions");
if (txsr & ENTSR_ND)
- printk("non-deferral ");
+ pr_cont(" non-deferral");
if (txsr & ENTSR_CRS)
- printk("lost-carrier ");
+ pr_cont(" lost-carrier");
if (txsr & ENTSR_FU)
- printk("FIFO-underrun ");
+ pr_cont(" FIFO-underrun");
if (txsr & ENTSR_CDH)
- printk("lost-heartbeat ");
- printk("\n");
+ pr_cont(" lost-heartbeat");
+ pr_cont("\n");
#endif
if (tx_was_aborted)
@@ -1278,8 +1272,9 @@ static void ei_tx_intr(struct net_device *dev)
if (ei_local->tx1 < 0)
{
if (ei_local->lasttx != 1 && ei_local->lasttx != -1)
- printk(KERN_ERR "%s: bogus last_tx_buffer %d, tx1=%d.\n",
- ei_local->name, ei_local->lasttx, ei_local->tx1);
+ netdev_err(dev, "%s: bogus last_tx_buffer %d, tx1=%d\n",
+ ei_local->name, ei_local->lasttx,
+ ei_local->tx1);
ei_local->tx1 = 0;
if (ei_local->tx2 > 0)
{
@@ -1294,8 +1289,9 @@ static void ei_tx_intr(struct net_device *dev)
else if (ei_local->tx2 < 0)
{
if (ei_local->lasttx != 2 && ei_local->lasttx != -2)
- printk("%s: bogus last_tx_buffer %d, tx2=%d.\n",
- ei_local->name, ei_local->lasttx, ei_local->tx2);
+ netdev_info(dev, "%s: bogus last_tx_buffer %d, tx2=%d\n",
+ ei_local->name, ei_local->lasttx,
+ ei_local->tx2);
ei_local->tx2 = 0;
if (ei_local->tx1 > 0)
{
@@ -1308,8 +1304,9 @@ static void ei_tx_intr(struct net_device *dev)
else
ei_local->lasttx = 10, ei_local->txing = 0;
}
-// else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n",
-// dev->name, ei_local->lasttx);
+// else
+// netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n",
+// ei_local->lasttx);
/* Minimize Tx latency: update the statistics after we restart TXing. */
if (status & ENTSR_COL)
@@ -1372,8 +1369,8 @@ static void ei_receive(struct net_device *dev)
is that some clones crash in roughly the same way.
*/
if (ei_debug > 0 && this_frame != ei_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF))
- printk(KERN_ERR "%s: mismatched read page pointers %2x vs %2x.\n",
- dev->name, this_frame, ei_local->current_page);
+ netdev_err(dev, "mismatched read page pointers %2x vs %2x\n",
+ this_frame, ei_local->current_page);
if (this_frame == rxing_page) /* Read all the frames? */
break; /* Done for now */
@@ -1389,9 +1386,10 @@ static void ei_receive(struct net_device *dev)
if (pkt_len < 60 || pkt_len > 1518)
{
if (ei_debug)
- printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
- dev->name, rx_frame.count, rx_frame.status,
- rx_frame.next);
+ netdev_printk(KERN_DEBUG, dev,
+ "bogus packet size: %d, status=%#2x nxpg=%#2x\n",
+ rx_frame.count, rx_frame.status,
+ rx_frame.next);
dev->stats.rx_errors++;
dev->stats.rx_length_errors++;
}
@@ -1403,8 +1401,9 @@ static void ei_receive(struct net_device *dev)
if (skb == NULL)
{
if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n",
- dev->name, pkt_len);
+ netdev_printk(KERN_DEBUG, dev,
+ "Couldn't allocate a sk_buff of size %d\n",
+ pkt_len);
dev->stats.rx_dropped++;
break;
}
@@ -1424,9 +1423,10 @@ static void ei_receive(struct net_device *dev)
else
{
if (ei_debug)
- printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
- dev->name, rx_frame.status, rx_frame.next,
- rx_frame.count);
+ netdev_printk(KERN_DEBUG, dev,
+ "bogus packet: status=%#2x nxpg=%#2x size=%d\n",
+ rx_frame.status, rx_frame.next,
+ rx_frame.count);
dev->stats.rx_errors++;
/* NB: The NIC counts CRC, frame and missed errors. */
if (pkt_stat & ENRSR_FO)
@@ -1436,8 +1436,8 @@ static void ei_receive(struct net_device *dev)
/* This _should_ never happen: it's here for avoiding bad clones. */
if (next_frame >= ei_local->stop_page) {
- printk("%s: next frame inconsistency, %#2x\n", dev->name,
- next_frame);
+ netdev_info(dev, "next frame inconsistency, %#2x\n",
+ next_frame);
next_frame = ei_local->rx_start_page;
}
ei_local->current_page = next_frame;
@@ -1472,7 +1472,7 @@ static void ei_rx_overrun(struct net_device *dev)
outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD);
if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name);
+ netdev_printk(KERN_DEBUG, dev, "Receiver overrun\n");
dev->stats.rx_over_errors++;
/*
@@ -1669,7 +1669,7 @@ static void AX88190_init(struct net_device *dev, int startp)
{
outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i));
if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i])
- printk(KERN_ERR "Hw. address read/write mismap %d\n",i);
+ netdev_err(dev, "Hw. address read/write mismap %d\n", i);
}
outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG);
@@ -1706,8 +1706,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
if (inb_p(e8390_base) & E8390_TRANS)
{
- printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n",
- dev->name);
+ netdev_warn(dev, "trigger_send() called with the transmitter busy\n");
return;
}
outb_p(length & 0xff, e8390_base + EN0_TCNTLO);
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index b706a7249477..27bfad76fc40 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -51,23 +51,23 @@
#define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
-#ifdef DEBUG
static void regdump(struct net_device *dev)
{
+#ifdef DEBUG
int ioaddr = dev->base_addr;
int count;
- printk("com20020 register dump:\n");
+ netdev_dbg(dev, "register dump:\n");
for (count = ioaddr; count < ioaddr + 16; count++)
{
if (!(count % 16))
- printk("\n%04X: ", count);
- printk("%02X ", inb(count));
+ pr_cont("%04X:", count);
+ pr_cont(" %02X", inb(count));
}
- printk("\n");
+ pr_cont("\n");
- printk("buffer0 dump:\n");
+ netdev_dbg(dev, "buffer0 dump:\n");
/* set up the address register */
count = 0;
outb((count >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
@@ -76,19 +76,15 @@ static void regdump(struct net_device *dev)
for (count = 0; count < 256+32; count++)
{
if (!(count % 16))
- printk("\n%04X: ", count);
+ pr_cont("%04X:", count);
/* copy the data */
- printk("%02X ", inb(_MEMDATA));
+ pr_cont(" %02X", inb(_MEMDATA));
}
- printk("\n");
+ pr_cont("\n");
+#endif
}
-#else
-
-static inline void regdump(struct net_device *dev) { }
-
-#endif
/*====================================================================*/
@@ -274,13 +270,13 @@ static int com20020_config(struct pcmcia_device *link)
i = com20020_found(dev, 0); /* calls register_netdev */
if (i != 0) {
- dev_printk(KERN_NOTICE, &link->dev,
- "com20020_cs: com20020_found() failed\n");
+ dev_notice(&link->dev,
+ "com20020_found() failed\n");
goto failed;
}
- dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
- dev->name, dev->base_addr, dev->irq);
+ netdev_dbg(dev, "port %#3lx, irq %d\n",
+ dev->base_addr, dev->irq);
return 0;
failed:
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 1c327598bbe8..9226cda4d054 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -28,6 +28,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "fmvj18x_cs"
#define DRV_VERSION "2.9"
@@ -289,7 +291,7 @@ static int mfc_try_io_port(struct pcmcia_device *link)
link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
if (link->resource[1]->start == 0) {
link->resource[1]->end = 0;
- printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
+ pr_notice("out of resource for serial\n");
}
ret = pcmcia_request_io(link);
if (ret == 0)
@@ -497,7 +499,7 @@ static int fmvj18x_config(struct pcmcia_device *link)
case XXX10304:
/* Read MACID from Buggy CIS */
if (fmvj18x_get_hwinfo(link, buggybuf) == -1) {
- printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
+ pr_notice("unable to read hardware net address\n");
goto failed;
}
for (i = 0 ; i < 6; i++) {
@@ -518,15 +520,14 @@ static int fmvj18x_config(struct pcmcia_device *link)
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
/* print current configuration */
- printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, "
- "hw_addr %pM\n",
- dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2",
- dev->base_addr, dev->irq, dev->dev_addr);
+ netdev_info(dev, "%s, sram %s, port %#3lx, irq %d, hw_addr %pM\n",
+ card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2",
+ dev->base_addr, dev->irq, dev->dev_addr);
return 0;
@@ -597,7 +598,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
lp->base = ioremap(link->resource[3]->start,
resource_size(link->resource[3]));
if (lp->base == NULL) {
- printk(KERN_NOTICE "fmvj18x_cs: ioremap failed\n");
+ netdev_notice(dev, "ioremap failed\n");
return -1;
}
@@ -787,17 +788,16 @@ static void fjn_tx_timeout(struct net_device *dev)
struct local_info_t *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
- printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n",
- dev->name, htons(inw(ioaddr + TX_STATUS)),
- inb(ioaddr + TX_STATUS) & F_TMT_RDY
- ? "IRQ conflict" : "network cable problem");
- printk(KERN_NOTICE "%s: timeout registers: %04x %04x %04x "
- "%04x %04x %04x %04x %04x.\n",
- dev->name, htons(inw(ioaddr + 0)),
- htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)),
- htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
- htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
- htons(inw(ioaddr +14)));
+ netdev_notice(dev, "transmit timed out with status %04x, %s?\n",
+ htons(inw(ioaddr + TX_STATUS)),
+ inb(ioaddr + TX_STATUS) & F_TMT_RDY
+ ? "IRQ conflict" : "network cable problem");
+ netdev_notice(dev, "timeout registers: %04x %04x %04x "
+ "%04x %04x %04x %04x %04x.\n",
+ htons(inw(ioaddr + 0)), htons(inw(ioaddr + 2)),
+ htons(inw(ioaddr + 4)), htons(inw(ioaddr + 6)),
+ htons(inw(ioaddr + 8)), htons(inw(ioaddr + 10)),
+ htons(inw(ioaddr + 12)), htons(inw(ioaddr + 14)));
dev->stats.tx_errors++;
/* ToDo: We should try to restart the adaptor... */
local_irq_disable();
@@ -832,13 +832,13 @@ static netdev_tx_t fjn_start_xmit(struct sk_buff *skb,
unsigned char *buf = skb->data;
if (length > ETH_FRAME_LEN) {
- printk(KERN_NOTICE "%s: Attempting to send a large packet"
- " (%d bytes).\n", dev->name, length);
+ netdev_notice(dev, "Attempting to send a large packet (%d bytes)\n",
+ length);
return NETDEV_TX_BUSY;
}
- pr_debug("%s: Transmitting a packet of length %lu.\n",
- dev->name, (unsigned long)skb->len);
+ netdev_dbg(dev, "Transmitting a packet of length %lu\n",
+ (unsigned long)skb->len);
dev->stats.tx_bytes += skb->len;
/* Disable both interrupts. */
@@ -891,7 +891,7 @@ static void fjn_reset(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
int i;
- pr_debug("fjn_reset(%s) called.\n",dev->name);
+ netdev_dbg(dev, "fjn_reset() called\n");
/* Reset controller */
if( sram_config == 0 )
@@ -975,8 +975,8 @@ static void fjn_rx(struct net_device *dev)
while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
u_short status = inw(ioaddr + DATAPORT);
- pr_debug("%s: Rxing packet mode %02x status %04x.\n",
- dev->name, inb(ioaddr + RX_MODE), status);
+ netdev_dbg(dev, "Rxing packet mode %02x status %04x.\n",
+ inb(ioaddr + RX_MODE), status);
#ifndef final_version
if (status == 0) {
outb(F_SKP_PKT, ioaddr + RX_SKIP);
@@ -995,16 +995,16 @@ static void fjn_rx(struct net_device *dev)
struct sk_buff *skb;
if (pkt_len > 1550) {
- printk(KERN_NOTICE "%s: The FMV-18x claimed a very "
- "large packet, size %d.\n", dev->name, pkt_len);
+ netdev_notice(dev, "The FMV-18x claimed a very large packet, size %d\n",
+ pkt_len);
outb(F_SKP_PKT, ioaddr + RX_SKIP);
dev->stats.rx_errors++;
break;
}
skb = dev_alloc_skb(pkt_len+2);
if (skb == NULL) {
- printk(KERN_NOTICE "%s: Memory squeeze, dropping "
- "packet (len %d).\n", dev->name, pkt_len);
+ netdev_notice(dev, "Memory squeeze, dropping packet (len %d)\n",
+ pkt_len);
outb(F_SKP_PKT, ioaddr + RX_SKIP);
dev->stats.rx_dropped++;
break;
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index bf7dff96d881..15d57f5b6f29 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -45,6 +45,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ptrace.h>
@@ -52,7 +54,6 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/module.h>
-#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/trdevice.h>
#include <linux/ibmtr.h>
@@ -105,16 +106,6 @@ typedef struct ibmtr_dev_t {
struct tok_info *ti;
} ibmtr_dev_t;
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "ibmtr_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
ibmtr_dev_t *info = dev_id;
struct net_device *dev = info->dev;
@@ -148,8 +139,6 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
info->dev = dev;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-
return ibmtr_config(link);
} /* ibmtr_attach */
@@ -256,15 +245,14 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
i = ibmtr_probe_card(dev);
if (i != 0) {
- printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- printk(KERN_INFO
- "%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
- dev->name, dev->base_addr, dev->irq,
- (u_long)ti->mmio, (u_long)(ti->sram_base << 12),
- dev->dev_addr);
+ netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
+ dev->base_addr, dev->irq,
+ (u_long)ti->mmio, (u_long)(ti->sram_base << 12),
+ dev->dev_addr);
return 0;
failed:
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 1eca4f5a6e78..0a2b0f9cdf33 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -111,6 +111,8 @@ Log: nmclan_cs.c,v
---------------------------------------------------------------------------- */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "nmclan_cs"
#define DRV_VERSION "0.16"
@@ -502,7 +504,7 @@ static int mace_read(mace_private *lp, unsigned int ioaddr, int reg)
spin_unlock_irqrestore(&lp->bank_lock, flags);
break;
}
- return (data & 0xFF);
+ return data & 0xFF;
} /* mace_read */
/* ----------------------------------------------------------------------------
@@ -546,7 +548,7 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr)
/* Wait for reset bit to be cleared automatically after <= 200ns */;
if(++ct > 500)
{
- printk(KERN_ERR "mace: reset failed, card removed ?\n");
+ pr_err("reset failed, card removed?\n");
return -1;
}
udelay(1);
@@ -593,7 +595,7 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr)
{
if(++ ct > 500)
{
- printk(KERN_ERR "mace: ADDRCHG timeout, card removed ?\n");
+ pr_err("ADDRCHG timeout, card removed?\n");
return -1;
}
}
@@ -654,8 +656,8 @@ static int nmclan_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
sig[0], sig[1]);
} else {
- printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
- " be 0x40 0x?9\n", sig[0], sig[1]);
+ pr_notice("mace id not found: %x %x should be 0x40 0x?9\n",
+ sig[0], sig[1]);
return -ENODEV;
}
}
@@ -667,20 +669,18 @@ static int nmclan_config(struct pcmcia_device *link)
if (if_port <= 2)
dev->if_port = if_port;
else
- printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
+ pr_notice("invalid if_port requested\n");
SET_NETDEV_DEV(dev, &link->dev);
i = register_netdev(dev);
if (i != 0) {
- printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port,"
- " hw_addr %pM\n",
- dev->name, dev->base_addr, dev->irq, if_names[dev->if_port],
- dev->dev_addr);
+ netdev_info(dev, "nmclan: port %#3lx, irq %d, %s port, hw_addr %pM\n",
+ dev->base_addr, dev->irq, if_names[dev->if_port], dev->dev_addr);
return 0;
failed:
@@ -768,8 +768,7 @@ static int mace_config(struct net_device *dev, struct ifmap *map)
if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
if (map->port <= 2) {
dev->if_port = map->port;
- printk(KERN_INFO "%s: switched to %s port\n", dev->name,
- if_names[dev->if_port]);
+ netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
} else
return -EINVAL;
}
@@ -848,12 +847,12 @@ static void mace_tx_timeout(struct net_device *dev)
mace_private *lp = netdev_priv(dev);
struct pcmcia_device *link = lp->p_dev;
- printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
+ netdev_notice(dev, "transmit timed out -- ");
#if RESET_ON_TIMEOUT
- printk("resetting card\n");
+ pr_cont("resetting card\n");
pcmcia_reset_card(link->socket);
#else /* #if RESET_ON_TIMEOUT */
- printk("NOT resetting card\n");
+ pr_cont("NOT resetting card\n");
#endif /* #if RESET_ON_TIMEOUT */
dev->trans_start = jiffies; /* prevent tx timeout */
netif_wake_queue(dev);
@@ -935,22 +934,21 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
ioaddr = dev->base_addr;
if (lp->tx_irq_disabled) {
- printk(
- (lp->tx_irq_disabled?
- KERN_NOTICE "%s: Interrupt with tx_irq_disabled "
- "[isr=%02X, imr=%02X]\n":
- KERN_NOTICE "%s: Re-entering the interrupt handler "
- "[isr=%02X, imr=%02X]\n"),
- dev->name,
- inb(ioaddr + AM2150_MACE_BASE + MACE_IR),
- inb(ioaddr + AM2150_MACE_BASE + MACE_IMR)
- );
+ const char *msg;
+ if (lp->tx_irq_disabled)
+ msg = "Interrupt with tx_irq_disabled";
+ else
+ msg = "Re-entering the interrupt handler";
+ netdev_notice(dev, "%s [isr=%02X, imr=%02X]\n",
+ msg,
+ inb(ioaddr + AM2150_MACE_BASE + MACE_IR),
+ inb(ioaddr + AM2150_MACE_BASE + MACE_IMR));
/* WARNING: MACE_IR has been read! */
return IRQ_NONE;
}
if (!netif_device_present(dev)) {
- pr_debug("%s: interrupt from dead card\n", dev->name);
+ netdev_dbg(dev, "interrupt from dead card\n");
return IRQ_NONE;
}
@@ -1348,8 +1346,8 @@ static void BuildLAF(int *ladrf, int *adr)
printk(KERN_DEBUG " adr =%pM\n", adr);
printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode);
for (i = 0; i < 8; i++)
- printk(KERN_CONT " %02X", ladrf[i]);
- printk(KERN_CONT "\n");
+ pr_cont(" %02X", ladrf[i]);
+ pr_cont("\n");
#endif
} /* BuildLAF */
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 5d7d1d3088ae..03096c80103d 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -28,6 +28,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -35,7 +37,6 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
-#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/log2.h>
#include <linux/etherdevice.h>
@@ -99,7 +100,6 @@ static void pcnet_release(struct pcmcia_device *link);
static int pcnet_open(struct net_device *dev);
static int pcnet_close(struct net_device *dev);
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static const struct ethtool_ops netdev_ethtool_ops;
static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
static void ei_watchdog(u_long arg);
static void pcnet_reset_8390(struct net_device *dev);
@@ -415,8 +415,6 @@ static hw_info_t *get_ax88190(struct pcmcia_device *link)
dev->dev_addr[i] = j & 0xff;
dev->dev_addr[i+1] = j >> 8;
}
- printk(KERN_NOTICE "pcnet_cs: this is an AX88190 card!\n");
- printk(KERN_NOTICE "pcnet_cs: use axnet_cs instead.\n");
return NULL;
}
@@ -604,9 +602,7 @@ static int pcnet_config(struct pcmcia_device *link)
ei_status.name = "NE2000";
ei_status.word16 = 1;
- ei_status.reset_8390 = &pcnet_reset_8390;
-
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+ ei_status.reset_8390 = pcnet_reset_8390;
if (info->flags & (IS_DL10019|IS_DL10022))
mii_phy_probe(dev);
@@ -614,25 +610,25 @@ static int pcnet_config(struct pcmcia_device *link)
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
if (info->flags & (IS_DL10019|IS_DL10022)) {
u_char id = inb(dev->base_addr + 0x1a);
- printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ",
- dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id);
+ netdev_info(dev, "NE2000 (DL100%d rev %02x): ",
+ (info->flags & IS_DL10022) ? 22 : 19, id);
if (info->pna_phy)
- printk("PNA, ");
+ pr_cont("PNA, ");
} else {
- printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name);
+ netdev_info(dev, "NE2000 Compatible: ");
}
- printk("io %#3lx, irq %d,", dev->base_addr, dev->irq);
+ pr_cont("io %#3lx, irq %d,", dev->base_addr, dev->irq);
if (info->flags & USE_SHMEM)
- printk (" mem %#5lx,", dev->mem_start);
+ pr_cont(" mem %#5lx,", dev->mem_start);
if (info->flags & HAS_MISC_REG)
- printk(" %s xcvr,", if_names[dev->if_port]);
- printk(" hw_addr %pM\n", dev->dev_addr);
+ pr_cont(" %s xcvr,", if_names[dev->if_port]);
+ pr_cont(" hw_addr %pM\n", dev->dev_addr);
return 0;
failed:
@@ -889,7 +885,7 @@ static void mii_phy_probe(struct net_device *dev)
phyid = tmp << 16;
phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
phyid &= MII_PHYID_REV_MASK;
- pr_debug("%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
+ netdev_dbg(dev, "MII at %d is 0x%08x\n", i, phyid);
if (phyid == AM79C9XX_HOME_PHY) {
info->pna_phy = i;
} else if (phyid != AM79C9XX_ETH_PHY) {
@@ -922,7 +918,7 @@ static int pcnet_open(struct net_device *dev)
info->phy_id = info->eth_phy;
info->link_status = 0x00;
init_timer(&info->watchdog);
- info->watchdog.function = &ei_watchdog;
+ info->watchdog.function = ei_watchdog;
info->watchdog.data = (u_long)dev;
info->watchdog.expires = jiffies + HZ;
add_timer(&info->watchdog);
@@ -975,8 +971,8 @@ static void pcnet_reset_8390(struct net_device *dev)
outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */
if (i == 100)
- printk(KERN_ERR "%s: pcnet_reset_8390() did not complete.\n",
- dev->name);
+ netdev_err(dev, "pcnet_reset_8390() did not complete.\n");
+
set_misc_reg(dev);
} /* pcnet_reset_8390 */
@@ -992,8 +988,7 @@ static int set_config(struct net_device *dev, struct ifmap *map)
else if ((map->port < 1) || (map->port > 2))
return -EINVAL;
dev->if_port = map->port;
- printk(KERN_INFO "%s: switched to %s port\n",
- dev->name, if_names[dev->if_port]);
+ netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
NS8390_init(dev, 1);
}
return 0;
@@ -1028,7 +1023,7 @@ static void ei_watchdog(u_long arg)
this, we can limp along even if the interrupt is blocked */
if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
if (!info->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
ei_irq_wrapper(dev->irq, dev);
info->fast_poll = HZ;
}
@@ -1048,7 +1043,7 @@ static void ei_watchdog(u_long arg)
if (info->eth_phy) {
info->phy_id = info->eth_phy = 0;
} else {
- printk(KERN_INFO "%s: MII is missing!\n", dev->name);
+ netdev_info(dev, "MII is missing!\n");
info->flags &= ~HAS_MII;
}
goto reschedule;
@@ -1057,8 +1052,7 @@ static void ei_watchdog(u_long arg)
link &= 0x0004;
if (link != info->link_status) {
u_short p = mdio_read(mii_addr, info->phy_id, 5);
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (link) ? "found" : "lost");
+ netdev_info(dev, "%s link beat\n", link ? "found" : "lost");
if (link && (info->flags & IS_DL10022)) {
/* Disable collision detection on full duplex links */
outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG);
@@ -1069,13 +1063,12 @@ static void ei_watchdog(u_long arg)
if (link) {
if (info->phy_id == info->eth_phy) {
if (p)
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
+ netdev_info(dev, "autonegotiation complete: "
+ "%sbaseT-%cD selected\n",
((p & 0x0180) ? "100" : "10"),
((p & 0x0140) ? 'F' : 'H'));
else
- printk(KERN_INFO "%s: link partner did not "
- "autonegotiate\n", dev->name);
+ netdev_info(dev, "link partner did not autonegotiate\n");
}
NS8390_init(dev, 1);
}
@@ -1088,7 +1081,7 @@ static void ei_watchdog(u_long arg)
/* isolate this MII and try flipping to the other one */
mdio_write(mii_addr, info->phy_id, 0, 0x0400);
info->phy_id ^= info->pna_phy ^ info->eth_phy;
- printk(KERN_INFO "%s: switched to %s transceiver\n", dev->name,
+ netdev_info(dev, "switched to %s transceiver\n",
(info->phy_id == info->eth_phy) ? "ethernet" : "PNA");
mdio_write(mii_addr, info->phy_id, 0,
(info->phy_id == info->eth_phy) ? 0x1000 : 0);
@@ -1104,18 +1097,6 @@ reschedule:
/*====================================================================*/
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "pcnet_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
-/*====================================================================*/
-
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
@@ -1148,9 +1129,9 @@ static void dma_get_8390_hdr(struct net_device *dev,
unsigned int nic_base = dev->base_addr;
if (ei_status.dmaing) {
- printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
+ netdev_notice(dev, "DMAing conflict in dma_block_input."
"[DMAstat:%1x][irqlock:%1x]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -1181,11 +1162,11 @@ static void dma_block_input(struct net_device *dev, int count,
char *buf = skb->data;
if ((ei_debug > 4) && (count != 4))
- pr_debug("%s: [bi=%d]\n", dev->name, count+4);
+ netdev_dbg(dev, "[bi=%d]\n", count+4);
if (ei_status.dmaing) {
- printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
+ netdev_notice(dev, "DMAing conflict in dma_block_input."
"[DMAstat:%1x][irqlock:%1x]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
@@ -1215,9 +1196,9 @@ static void dma_block_input(struct net_device *dev, int count,
break;
} while (--tries > 0);
if (tries <= 0)
- printk(KERN_NOTICE "%s: RX transfer address mismatch,"
+ netdev_notice(dev, "RX transfer address mismatch,"
"%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, ring_offset + xfer_count, addr);
+ ring_offset + xfer_count, addr);
}
#endif
outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
@@ -1238,7 +1219,7 @@ static void dma_block_output(struct net_device *dev, int count,
#ifdef PCMCIA_DEBUG
if (ei_debug > 4)
- printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
+ netdev_dbg(dev, "[bo=%d]\n", count);
#endif
/* Round the count up for word writes. Do we need to do this?
@@ -1247,9 +1228,9 @@ static void dma_block_output(struct net_device *dev, int count,
if (count & 0x01)
count++;
if (ei_status.dmaing) {
- printk(KERN_NOTICE "%s: DMAing conflict in dma_block_output."
+ netdev_notice(dev, "DMAing conflict in dma_block_output."
"[DMAstat:%1x][irqlock:%1x]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
@@ -1286,9 +1267,9 @@ static void dma_block_output(struct net_device *dev, int count,
break;
} while (--tries > 0);
if (tries <= 0) {
- printk(KERN_NOTICE "%s: Tx packet transfer address mismatch,"
+ netdev_notice(dev, "Tx packet transfer address mismatch,"
"%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, (start_page << 8) + count, addr);
+ (start_page << 8) + count, addr);
if (retries++ == 0)
goto retry;
}
@@ -1297,8 +1278,7 @@ static void dma_block_output(struct net_device *dev, int count,
while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) {
- printk(KERN_NOTICE "%s: timeout waiting for Tx RDC.\n",
- dev->name);
+ netdev_notice(dev, "timeout waiting for Tx RDC.\n");
pcnet_reset_8390(dev);
NS8390_init(dev, 1);
break;
@@ -1322,9 +1302,9 @@ static int setup_dma_config(struct pcmcia_device *link, int start_pg,
ei_status.stop_page = stop_pg;
/* set up block i/o functions */
- ei_status.get_8390_hdr = &dma_get_8390_hdr;
- ei_status.block_input = &dma_block_input;
- ei_status.block_output = &dma_block_output;
+ ei_status.get_8390_hdr = dma_get_8390_hdr;
+ ei_status.block_input = dma_block_input;
+ ei_status.block_output = dma_block_output;
return 0;
}
@@ -1470,9 +1450,9 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
(resource_size(link->resource[3]) - offset) >> 8);
/* set up block i/o functions */
- ei_status.get_8390_hdr = &shmem_get_8390_hdr;
- ei_status.block_input = &shmem_block_input;
- ei_status.block_output = &shmem_block_output;
+ ei_status.get_8390_hdr = shmem_get_8390_hdr;
+ ei_status.block_input = shmem_block_input;
+ ei_status.block_output = shmem_block_output;
info->flags |= USE_SHMEM;
return 0;
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 0af2fc8ec164..8a9ff5318923 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -25,6 +25,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -293,7 +295,7 @@ static const struct net_device_ops smc_netdev_ops = {
.ndo_tx_timeout = smc_tx_timeout,
.ndo_set_config = s9k_config,
.ndo_set_multicast_list = set_rx_mode,
- .ndo_do_ioctl = &smc_ioctl,
+ .ndo_do_ioctl = smc_ioctl,
.ndo_change_mtu = eth_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
@@ -788,11 +790,11 @@ static int check_sig(struct pcmcia_device *link)
((s >> 8) != (s & 0xff))) {
SMC_SELECT_BANK(3);
s = inw(ioaddr + REVISION);
- return (s & 0xff);
+ return s & 0xff;
}
if (width) {
- printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
+ pr_info("using 8-bit IO window\n");
smc91c92_suspend(link);
pcmcia_fixup_iowidth(link);
@@ -845,7 +847,7 @@ static int smc91c92_config(struct pcmcia_device *link)
if ((if_port >= 0) && (if_port <= 2))
dev->if_port = if_port;
else
- printk(KERN_NOTICE "smc91c92_cs: invalid if_port requested\n");
+ dev_notice(&link->dev, "invalid if_port requested\n");
switch (smc->manfid) {
case MANFID_OSITECH:
@@ -863,7 +865,7 @@ static int smc91c92_config(struct pcmcia_device *link)
}
if (i != 0) {
- printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n");
+ dev_notice(&link->dev, "Unable to find hardware address.\n");
goto config_failed;
}
@@ -916,30 +918,28 @@ static int smc91c92_config(struct pcmcia_device *link)
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
+ dev_err(&link->dev, "register_netdev() failed\n");
goto config_undo;
}
- printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, "
- "hw_addr %pM\n",
- dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq,
- dev->dev_addr);
+ netdev_info(dev, "smc91c%s rev %d: io %#3lx, irq %d, hw_addr %pM\n",
+ name, (rev & 0x0f), dev->base_addr, dev->irq, dev->dev_addr);
if (rev > 0) {
if (mir & 0x3ff)
- printk(KERN_INFO " %lu byte", mir);
+ netdev_info(dev, " %lu byte", mir);
else
- printk(KERN_INFO " %lu kb", mir>>10);
- printk(" buffer, %s xcvr\n", (smc->cfg & CFG_MII_SELECT) ?
- "MII" : if_names[dev->if_port]);
+ netdev_info(dev, " %lu kb", mir>>10);
+ pr_cont(" buffer, %s xcvr\n",
+ (smc->cfg & CFG_MII_SELECT) ? "MII" : if_names[dev->if_port]);
}
if (smc->cfg & CFG_MII_SELECT) {
if (smc->mii_if.phy_id != -1) {
- dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n",
- smc->mii_if.phy_id, j);
+ netdev_dbg(dev, " MII transceiver at index %d, status %x\n",
+ smc->mii_if.phy_id, j);
} else {
- printk(KERN_NOTICE " No MII transceivers found!\n");
+ netdev_notice(dev, " No MII transceivers found!\n");
}
}
return 0;
@@ -1037,10 +1037,10 @@ static void smc_dump(struct net_device *dev)
save = inw(ioaddr + BANK_SELECT);
for (w = 0; w < 4; w++) {
SMC_SELECT_BANK(w);
- printk(KERN_DEBUG "bank %d: ", w);
+ netdev_printk(KERN_DEBUG, dev, "bank %d: ", w);
for (i = 0; i < 14; i += 2)
- printk(" %04x", inw(ioaddr + i));
- printk("\n");
+ pr_cont(" %04x", inw(ioaddr + i));
+ pr_cont("\n");
}
outw(save, ioaddr + BANK_SELECT);
}
@@ -1062,7 +1062,7 @@ static int smc_open(struct net_device *dev)
return -ENODEV;
/* Physical device present signature. */
if (check_sig(link) < 0) {
- printk("smc91c92_cs: Yikes! Bad chip signature!\n");
+ netdev_info(dev, "Yikes! Bad chip signature!\n");
return -ENODEV;
}
link->open++;
@@ -1073,7 +1073,7 @@ static int smc_open(struct net_device *dev)
smc_reset(dev);
init_timer(&smc->media);
- smc->media.function = &media_check;
+ smc->media.function = media_check;
smc->media.data = (u_long) dev;
smc->media.expires = jiffies + HZ;
add_timer(&smc->media);
@@ -1128,7 +1128,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
u_char packet_no;
if (!skb) {
- printk(KERN_ERR "%s: In XMIT with no packet to send.\n", dev->name);
+ netdev_err(dev, "In XMIT with no packet to send\n");
return;
}
@@ -1136,8 +1136,8 @@ static void smc_hardware_send_packet(struct net_device * dev)
packet_no = inw(ioaddr + PNR_ARR) >> 8;
if (packet_no & 0x80) {
/* If not, there is a hardware problem! Likely an ejected card. */
- printk(KERN_WARNING "%s: 91c92 hardware Tx buffer allocation"
- " failed, status %#2.2x.\n", dev->name, packet_no);
+ netdev_warn(dev, "hardware Tx buffer allocation failed, status %#2.2x\n",
+ packet_no);
dev_kfree_skb_irq(skb);
smc->saved_skb = NULL;
netif_start_queue(dev);
@@ -1156,8 +1156,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
u_char *buf = skb->data;
u_int length = skb->len; /* The chip will pad to ethernet min. */
- pr_debug("%s: Trying to xmit packet of length %d.\n",
- dev->name, length);
+ netdev_dbg(dev, "Trying to xmit packet of length %d\n", length);
/* send the packet length: +6 for status word, length, and ctl */
outw(0, ioaddr + DATA_1);
@@ -1189,9 +1188,8 @@ static void smc_tx_timeout(struct net_device *dev)
struct smc_private *smc = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
- printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, "
- "Tx_status %2.2x status %4.4x.\n",
- dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2));
+ netdev_notice(dev, "transmit timed out, Tx_status %2.2x status %4.4x.\n",
+ inw(ioaddr)&0xff, inw(ioaddr + 2));
dev->stats.tx_errors++;
smc_reset(dev);
dev->trans_start = jiffies; /* prevent tx timeout */
@@ -1210,14 +1208,14 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
netif_stop_queue(dev);
- pr_debug("%s: smc_start_xmit(length = %d) called,"
- " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
+ netdev_dbg(dev, "smc_start_xmit(length = %d) called, status %04x\n",
+ skb->len, inw(ioaddr + 2));
if (smc->saved_skb) {
/* THIS SHOULD NEVER HAPPEN. */
dev->stats.tx_aborted_errors++;
- printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n",
- dev->name);
+ netdev_printk(KERN_DEBUG, dev,
+ "Internal error -- sent packet while busy\n");
return NETDEV_TX_BUSY;
}
smc->saved_skb = skb;
@@ -1225,7 +1223,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
num_pages = skb->len >> 8;
if (num_pages > 7) {
- printk(KERN_ERR "%s: Far too big packet error.\n", dev->name);
+ netdev_err(dev, "Far too big packet error: %d pages\n", num_pages);
dev_kfree_skb (skb);
smc->saved_skb = NULL;
dev->stats.tx_dropped++;
@@ -1295,8 +1293,7 @@ static void smc_tx_err(struct net_device * dev)
}
if (tx_status & TS_SUCCESS) {
- printk(KERN_NOTICE "%s: Successful packet caused error "
- "interrupt?\n", dev->name);
+ netdev_notice(dev, "Successful packet caused error interrupt?\n");
}
/* re-enable transmit */
SMC_SELECT_BANK(0);
@@ -1486,8 +1483,7 @@ static void smc_rx(struct net_device *dev)
/* Assertion: we are in Window 2. */
if (inw(ioaddr + FIFO_PORTS) & FP_RXEMPTY) {
- printk(KERN_ERR "%s: smc_rx() with nothing on Rx FIFO.\n",
- dev->name);
+ netdev_err(dev, "smc_rx() with nothing on Rx FIFO\n");
return;
}
@@ -1602,8 +1598,7 @@ static int s9k_config(struct net_device *dev, struct ifmap *map)
else if (map->port > 2)
return -EINVAL;
dev->if_port = map->port;
- printk(KERN_INFO "%s: switched to %s port\n",
- dev->name, if_names[dev->if_port]);
+ netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
smc_reset(dev);
}
return 0;
@@ -1754,7 +1749,7 @@ static void media_check(u_long arg)
this, we can limp along even if the interrupt is blocked */
if (smc->watchdog++ && ((i>>8) & i)) {
if (!smc->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
local_irq_save(flags);
smc_interrupt(dev->irq, dev);
local_irq_restore(flags);
@@ -1778,7 +1773,7 @@ static void media_check(u_long arg)
SMC_SELECT_BANK(3);
link = mdio_read(dev, smc->mii_if.phy_id, 1);
if (!link || (link == 0xffff)) {
- printk(KERN_INFO "%s: MII is missing!\n", dev->name);
+ netdev_info(dev, "MII is missing!\n");
smc->mii_if.phy_id = -1;
goto reschedule;
}
@@ -1786,15 +1781,13 @@ static void media_check(u_long arg)
link &= 0x0004;
if (link != smc->link_status) {
u_short p = mdio_read(dev, smc->mii_if.phy_id, 5);
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (link) ? "found" : "lost");
+ netdev_info(dev, "%s link beat\n", link ? "found" : "lost");
smc->duplex = (((p & 0x0100) || ((p & 0x1c0) == 0x40))
? TCR_FDUPLX : 0);
if (link) {
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
- ((p & 0x0180) ? "100" : "10"),
- (smc->duplex ? 'F' : 'H'));
+ netdev_info(dev, "autonegotiation complete: "
+ "%dbaseT-%cD selected\n",
+ (p & 0x0180) ? 100 : 10, smc->duplex ? 'F' : 'H');
}
SMC_SELECT_BANK(0);
outw(inw(ioaddr + TCR) | smc->duplex, ioaddr + TCR);
@@ -1813,25 +1806,23 @@ static void media_check(u_long arg)
if (media != smc->media_status) {
if ((media & smc->media_status & 1) &&
((smc->media_status ^ media) & EPH_LINK_OK))
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (smc->media_status & EPH_LINK_OK ? "lost" : "found"));
+ netdev_info(dev, "%s link beat\n",
+ smc->media_status & EPH_LINK_OK ? "lost" : "found");
else if ((media & smc->media_status & 2) &&
((smc->media_status ^ media) & EPH_16COL))
- printk(KERN_INFO "%s: coax cable %s\n", dev->name,
- (media & EPH_16COL ? "problem" : "ok"));
+ netdev_info(dev, "coax cable %s\n",
+ media & EPH_16COL ? "problem" : "ok");
if (dev->if_port == 0) {
if (media & 1) {
if (media & EPH_LINK_OK)
- printk(KERN_INFO "%s: flipped to 10baseT\n",
- dev->name);
+ netdev_info(dev, "flipped to 10baseT\n");
else
smc_set_xcvr(dev, 2);
} else {
if (media & EPH_16COL)
smc_set_xcvr(dev, 1);
else
- printk(KERN_INFO "%s: flipped to 10base2\n",
- dev->name);
+ netdev_info(dev, "flipped to 10base2\n");
}
}
smc->media_status = media;
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 1fece617c069..a46b7fd6c0f5 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -63,6 +63,8 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -209,13 +211,6 @@ enum xirc_cmd { /* Commands */
static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" };
-
-#define KDBG_XIRC KERN_DEBUG "xirc2ps_cs: "
-#define KERR_XIRC KERN_ERR "xirc2ps_cs: "
-#define KWRN_XIRC KERN_WARNING "xirc2ps_cs: "
-#define KNOT_XIRC KERN_NOTICE "xirc2ps_cs: "
-#define KINF_XIRC KERN_INFO "xirc2ps_cs: "
-
/* card types */
#define XIR_UNKNOWN 0 /* unknown: not supported */
#define XIR_CE 1 /* (prodid 1) different hardware: not supported */
@@ -327,26 +322,26 @@ PrintRegisters(struct net_device *dev)
if (pc_debug > 1) {
int i, page;
- printk(KDBG_XIRC "Register common: ");
+ printk(KERN_DEBUG pr_fmt("Register common: "));
for (i = 0; i < 8; i++)
- printk(" %2.2x", GetByte(i));
- printk("\n");
+ pr_cont(" %2.2x", GetByte(i));
+ pr_cont("\n");
for (page = 0; page <= 8; page++) {
- printk(KDBG_XIRC "Register page %2x: ", page);
+ printk(KERN_DEBUG pr_fmt("Register page %2x: "), page);
SelectPage(page);
for (i = 8; i < 16; i++)
- printk(" %2.2x", GetByte(i));
- printk("\n");
+ pr_cont(" %2.2x", GetByte(i));
+ pr_cont("\n");
}
for (page=0x40 ; page <= 0x5f; page++) {
if (page == 0x43 || (page >= 0x46 && page <= 0x4f) ||
(page >= 0x51 && page <=0x5e))
continue;
- printk(KDBG_XIRC "Register page %2x: ", page);
+ printk(KERN_DEBUG pr_fmt("Register page %2x: "), page);
SelectPage(page);
for (i = 8; i < 16; i++)
- printk(" %2.2x", GetByte(i));
- printk("\n");
+ pr_cont(" %2.2x", GetByte(i));
+ pr_cont("\n");
}
}
}
@@ -566,11 +561,11 @@ set_card_type(struct pcmcia_device *link)
local->modem = 0;
local->card_type = XIR_UNKNOWN;
if (!(prodid & 0x40)) {
- printk(KNOT_XIRC "Ooops: Not a creditcard\n");
+ pr_notice("Oops: Not a creditcard\n");
return 0;
}
if (!(mediaid & 0x01)) {
- printk(KNOT_XIRC "Not an Ethernet card\n");
+ pr_notice("Not an Ethernet card\n");
return 0;
}
if (mediaid & 0x10) {
@@ -601,12 +596,11 @@ set_card_type(struct pcmcia_device *link)
}
}
if (local->card_type == XIR_CE || local->card_type == XIR_CEM) {
- printk(KNOT_XIRC "Sorry, this is an old CE card\n");
+ pr_notice("Sorry, this is an old CE card\n");
return 0;
}
if (local->card_type == XIR_UNKNOWN)
- printk(KNOT_XIRC "unknown card (mediaid=%02x prodid=%02x)\n",
- mediaid, prodid);
+ pr_notice("unknown card (mediaid=%02x prodid=%02x)\n", mediaid, prodid);
return 1;
}
@@ -710,7 +704,7 @@ xirc2ps_config(struct pcmcia_device * link)
/* Is this a valid card */
if (link->has_manf_id == 0) {
- printk(KNOT_XIRC "manfid not found in CIS\n");
+ pr_notice("manfid not found in CIS\n");
goto failure;
}
@@ -732,14 +726,14 @@ xirc2ps_config(struct pcmcia_device * link)
local->manf_str = "Toshiba";
break;
default:
- printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
- (unsigned)link->manf_id);
+ pr_notice("Unknown Card Manufacturer ID: 0x%04x\n",
+ (unsigned)link->manf_id);
goto failure;
}
dev_dbg(&link->dev, "found %s card\n", local->manf_str);
if (!set_card_type(link)) {
- printk(KNOT_XIRC "this card is not supported\n");
+ pr_notice("this card is not supported\n");
goto failure;
}
@@ -765,7 +759,7 @@ xirc2ps_config(struct pcmcia_device * link)
err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
if (err) {
- printk(KNOT_XIRC "node-id not found in CIS\n");
+ pr_notice("node-id not found in CIS\n");
goto failure;
}
@@ -792,7 +786,7 @@ xirc2ps_config(struct pcmcia_device * link)
* try to configure as Ethernet only.
* .... */
}
- printk(KNOT_XIRC "no ports available\n");
+ pr_notice("no ports available\n");
} else {
link->io_lines = 10;
link->resource[0]->end = 16;
@@ -865,24 +859,24 @@ xirc2ps_config(struct pcmcia_device * link)
#if 0
{
u_char tmp;
- printk(KERN_INFO "ECOR:");
+ pr_info("ECOR:");
for (i=0; i < 7; i++) {
tmp = readb(local->dingo_ccr + i*2);
- printk(" %02x", tmp);
+ pr_cont(" %02x", tmp);
}
- printk("\n");
- printk(KERN_INFO "DCOR:");
+ pr_cont("\n");
+ pr_info("DCOR:");
for (i=0; i < 4; i++) {
tmp = readb(local->dingo_ccr + 0x20 + i*2);
- printk(" %02x", tmp);
+ pr_cont(" %02x", tmp);
}
- printk("\n");
- printk(KERN_INFO "SCOR:");
+ pr_cont("\n");
+ pr_info("SCOR:");
for (i=0; i < 10; i++) {
tmp = readb(local->dingo_ccr + 0x40 + i*2);
- printk(" %02x", tmp);
+ pr_cont(" %02x", tmp);
}
- printk("\n");
+ pr_cont("\n");
}
#endif
@@ -901,7 +895,7 @@ xirc2ps_config(struct pcmcia_device * link)
(local->mohawk && if_port==4))
dev->if_port = if_port;
else
- printk(KNOT_XIRC "invalid if_port requested\n");
+ pr_notice("invalid if_port requested\n");
/* we can now register the device with the net subsystem */
dev->irq = link->irq;
@@ -913,14 +907,14 @@ xirc2ps_config(struct pcmcia_device * link)
SET_NETDEV_DEV(dev, &link->dev);
if ((err=register_netdev(dev))) {
- printk(KNOT_XIRC "register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto config_error;
}
/* give some infos about the hardware */
- printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %pM\n",
- dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq,
- dev->dev_addr);
+ netdev_info(dev, "%s: port %#3lx, irq %d, hwaddr %pM\n",
+ local->manf_str, (u_long)dev->base_addr, (int)dev->irq,
+ dev->dev_addr);
return 0;
@@ -1047,8 +1041,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */
if (!skb) {
- printk(KNOT_XIRC "low memory, packet dropped (size=%u)\n",
- pktlen);
+ pr_notice("low memory, packet dropped (size=%u)\n", pktlen);
dev->stats.rx_dropped++;
} else { /* okay get the packet */
skb_reserve(skb, 2);
@@ -1217,7 +1210,7 @@ xirc_tx_timeout(struct net_device *dev)
{
local_info_t *lp = netdev_priv(dev);
dev->stats.tx_errors++;
- printk(KERN_NOTICE "%s: transmit timed out\n", dev->name);
+ netdev_notice(dev, "transmit timed out\n");
schedule_work(&lp->tx_timeout_task);
}
@@ -1384,8 +1377,7 @@ do_config(struct net_device *dev, struct ifmap *map)
local->probe_port = 0;
dev->if_port = map->port;
}
- printk(KERN_INFO "%s: switching to %s port\n",
- dev->name, if_names[dev->if_port]);
+ netdev_info(dev, "switching to %s port\n", if_names[dev->if_port]);
do_reset(dev,1); /* not the fine way :-) */
}
return 0;
@@ -1525,7 +1517,7 @@ do_reset(struct net_device *dev, int full)
{
SelectPage(0);
value = GetByte(XIRCREG_ESR); /* read the ESR */
- printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value);
+ pr_debug("%s: ESR is: %#02x\n", dev->name, value);
}
#endif
@@ -1575,13 +1567,12 @@ do_reset(struct net_device *dev, int full)
if (full && local->mohawk && init_mii(dev)) {
if (dev->if_port == 4 || local->dingo || local->new_mii) {
- printk(KERN_INFO "%s: MII selected\n", dev->name);
+ netdev_info(dev, "MII selected\n");
SelectPage(2);
PutByte(XIRCREG2_MSR, GetByte(XIRCREG2_MSR) | 0x08);
msleep(20);
} else {
- printk(KERN_INFO "%s: MII detected; using 10mbs\n",
- dev->name);
+ netdev_info(dev, "MII detected; using 10mbs\n");
SelectPage(0x42);
if (dev->if_port == 2) /* enable 10Base2 */
PutByte(XIRCREG42_SWC1, 0xC0);
@@ -1626,8 +1617,8 @@ do_reset(struct net_device *dev, int full)
}
if (full)
- printk(KERN_INFO "%s: media %s, silicon revision %d\n",
- dev->name, if_names[dev->if_port], local->silicon);
+ netdev_info(dev, "media %s, silicon revision %d\n",
+ if_names[dev->if_port], local->silicon);
/* We should switch back to page 0 to avoid a bug in revision 0
* where regs with offset below 8 can't be read after an access
* to the MAC registers */
@@ -1669,8 +1660,7 @@ init_mii(struct net_device *dev)
control = mii_rd(ioaddr, 0, 0);
if (control & 0x0400) {
- printk(KERN_NOTICE "%s can't take PHY out of isolation mode\n",
- dev->name);
+ netdev_notice(dev, "can't take PHY out of isolation mode\n");
local->probe_port = 0;
return 0;
}
@@ -1688,8 +1678,7 @@ init_mii(struct net_device *dev)
}
if (!(status & 0x0020)) {
- printk(KERN_INFO "%s: autonegotiation failed;"
- " using 10mbs\n", dev->name);
+ netdev_info(dev, "autonegotiation failed; using 10mbs\n");
if (!local->new_mii) {
control = 0x0000;
mii_wr(ioaddr, 0, 0, control, 16);
@@ -1699,8 +1688,7 @@ init_mii(struct net_device *dev)
}
} else {
linkpartner = mii_rd(ioaddr, 0, 5);
- printk(KERN_INFO "%s: MII link partner: %04x\n",
- dev->name, linkpartner);
+ netdev_info(dev, "MII link partner: %04x\n", linkpartner);
if (linkpartner & 0x0080) {
dev->if_port = 4;
} else
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index c200c2821730..aee3bb0358bf 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -376,7 +376,7 @@ static void pcnet32_wio_reset(unsigned long addr)
static int pcnet32_wio_check(unsigned long addr)
{
outw(88, addr + PCNET32_WIO_RAP);
- return (inw(addr + PCNET32_WIO_RAP) == 88);
+ return inw(addr + PCNET32_WIO_RAP) == 88;
}
static struct pcnet32_access pcnet32_wio = {
@@ -431,7 +431,7 @@ static void pcnet32_dwio_reset(unsigned long addr)
static int pcnet32_dwio_check(unsigned long addr)
{
outl(88, addr + PCNET32_DWIO_RAP);
- return ((inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88);
+ return (inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88;
}
static struct pcnet32_access pcnet32_dwio = {
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index eb799b36c86a..cb3d13e4e074 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -58,7 +58,6 @@ config BROADCOM_PHY
config BCM63XX_PHY
tristate "Drivers for Broadcom 63xx SOCs internal PHY"
- depends on BCM63XX
---help---
Currently supports the 6348 and 6358 PHYs.
diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c
index c12815679837..e16f98cb4f04 100644
--- a/drivers/net/phy/bcm63xx.c
+++ b/drivers/net/phy/bcm63xx.c
@@ -131,7 +131,7 @@ static void __exit bcm63xx_phy_exit(void)
module_init(bcm63xx_phy_init);
module_exit(bcm63xx_phy_exit);
-static struct mdio_device_id bcm63xx_tbl[] = {
+static struct mdio_device_id __maybe_unused bcm63xx_tbl[] = {
{ 0x00406000, 0xfffffc00 },
{ 0x002bdc00, 0xfffffc00 },
{ }
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 4accd83d3dfe..d84c4224dd12 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -930,7 +930,7 @@ static void __exit broadcom_exit(void)
module_init(broadcom_init);
module_exit(broadcom_exit);
-static struct mdio_device_id broadcom_tbl[] = {
+static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
{ PHY_ID_BCM5411, 0xfffffff0 },
{ PHY_ID_BCM5421, 0xfffffff0 },
{ PHY_ID_BCM5461, 0xfffffff0 },
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c
index 1a325d63756b..d28173161c21 100644
--- a/drivers/net/phy/cicada.c
+++ b/drivers/net/phy/cicada.c
@@ -159,7 +159,7 @@ static void __exit cicada_exit(void)
module_init(cicada_init);
module_exit(cicada_exit);
-static struct mdio_device_id cicada_tbl[] = {
+static struct mdio_device_id __maybe_unused cicada_tbl[] = {
{ 0x000fc410, 0x000ffff0 },
{ 0x000fc440, 0x000fffc0 },
{ }
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 29c17617a2ec..2f774acdb551 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -219,7 +219,7 @@ static void __exit davicom_exit(void)
module_init(davicom_init);
module_exit(davicom_exit);
-static struct mdio_device_id davicom_tbl[] = {
+static struct mdio_device_id __maybe_unused davicom_tbl[] = {
{ 0x0181b880, 0x0ffffff0 },
{ 0x0181b8a0, 0x0ffffff0 },
{ 0x00181b80, 0x0ffffff0 },
diff --git a/drivers/net/phy/et1011c.c b/drivers/net/phy/et1011c.c
index 13995f52d6af..a8eb19ec3183 100644
--- a/drivers/net/phy/et1011c.c
+++ b/drivers/net/phy/et1011c.c
@@ -111,7 +111,7 @@ static void __exit et1011c_exit(void)
module_init(et1011c_init);
module_exit(et1011c_exit);
-static struct mdio_device_id et1011c_tbl[] = {
+static struct mdio_device_id __maybe_unused et1011c_tbl[] = {
{ 0x0282f014, 0xfffffff0 },
{ }
};
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index 3f2583f18a39..c1d2d251fe8b 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -134,7 +134,7 @@ static void __exit ip175c_exit(void)
module_init(ip175c_init);
module_exit(ip175c_exit);
-static struct mdio_device_id icplus_tbl[] = {
+static struct mdio_device_id __maybe_unused icplus_tbl[] = {
{ 0x02430d80, 0x0ffffff0 },
{ }
};
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index 29c39ff85de5..6f6e8b616a62 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -223,7 +223,7 @@ static void __exit lxt_exit(void)
module_init(lxt_init);
module_exit(lxt_exit);
-static struct mdio_device_id lxt_tbl[] = {
+static struct mdio_device_id __maybe_unused lxt_tbl[] = {
{ 0x78100000, 0xfffffff0 },
{ 0x001378e0, 0xfffffff0 },
{ 0x00137a10, 0xfffffff0 },
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 0101f2bdf400..e2afdce0a437 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -196,20 +196,27 @@ static int m88e1121_config_aneg(struct phy_device *phydev)
MII_88E1121_PHY_MSCR_PAGE);
if (err < 0)
return err;
- mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) &
- MII_88E1121_PHY_MSCR_DELAY_MASK;
- if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
- mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY |
- MII_88E1121_PHY_MSCR_TX_DELAY);
- else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
- mscr |= MII_88E1121_PHY_MSCR_RX_DELAY;
- else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
- mscr |= MII_88E1121_PHY_MSCR_TX_DELAY;
+ if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+ (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+ (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
+ (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
- err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr);
- if (err < 0)
- return err;
+ mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) &
+ MII_88E1121_PHY_MSCR_DELAY_MASK;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+ mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY |
+ MII_88E1121_PHY_MSCR_TX_DELAY);
+ else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+ mscr |= MII_88E1121_PHY_MSCR_RX_DELAY;
+ else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ mscr |= MII_88E1121_PHY_MSCR_TX_DELAY;
+
+ err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr);
+ if (err < 0)
+ return err;
+ }
phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage);
@@ -721,7 +728,7 @@ static void __exit marvell_exit(void)
module_init(marvell_init);
module_exit(marvell_exit);
-static struct mdio_device_id marvell_tbl[] = {
+static struct mdio_device_id __maybe_unused marvell_tbl[] = {
{ 0x01410c60, 0xfffffff0 },
{ 0x01410c90, 0xfffffff0 },
{ 0x01410cc0, 0xfffffff0 },
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 8bb7db676a5c..0fd1678bc5a9 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -231,7 +231,7 @@ MODULE_DESCRIPTION("Micrel PHY driver");
MODULE_AUTHOR("David J. Choi");
MODULE_LICENSE("GPL");
-static struct mdio_device_id micrel_tbl[] = {
+static struct mdio_device_id __maybe_unused micrel_tbl[] = {
{ PHY_ID_KSZ9021, 0x000fff10 },
{ PHY_ID_KS8001, 0x00fffff0 },
{ PHY_ID_KS8737, 0x00fffff0 },
diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c
index a73ba0bcc0ce..0620ba963508 100644
--- a/drivers/net/phy/national.c
+++ b/drivers/net/phy/national.c
@@ -151,7 +151,7 @@ MODULE_LICENSE("GPL");
module_init(ns_init);
module_exit(ns_exit);
-static struct mdio_device_id ns_tbl[] = {
+static struct mdio_device_id __maybe_unused ns_tbl[] = {
{ DP83865_PHY_ID, 0xfffffff0 },
{ }
};
diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c
index 6736b23f1b28..fe0d0a15d5e1 100644
--- a/drivers/net/phy/qsemi.c
+++ b/drivers/net/phy/qsemi.c
@@ -138,7 +138,7 @@ static void __exit qs6612_exit(void)
module_init(qs6612_init);
module_exit(qs6612_exit);
-static struct mdio_device_id qs6612_tbl[] = {
+static struct mdio_device_id __maybe_unused qs6612_tbl[] = {
{ 0x00181440, 0xfffffff0 },
{ }
};
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index f567c0e1aaa1..a4eae750a414 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -79,7 +79,7 @@ static void __exit realtek_exit(void)
module_init(realtek_init);
module_exit(realtek_exit);
-static struct mdio_device_id realtek_tbl[] = {
+static struct mdio_device_id __maybe_unused realtek_tbl[] = {
{ 0x001cc912, 0x001fffff },
{ }
};
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 78fa988256fc..342505c976d6 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -254,7 +254,7 @@ MODULE_LICENSE("GPL");
module_init(smsc_init);
module_exit(smsc_exit);
-static struct mdio_device_id smsc_tbl[] = {
+static struct mdio_device_id __maybe_unused smsc_tbl[] = {
{ 0x0007c0a0, 0xfffffff0 },
{ 0x0007c0b0, 0xfffffff0 },
{ 0x0007c0c0, 0xfffffff0 },
diff --git a/drivers/net/phy/ste10Xp.c b/drivers/net/phy/ste10Xp.c
index 72290099e5e1..187a2fa814f2 100644
--- a/drivers/net/phy/ste10Xp.c
+++ b/drivers/net/phy/ste10Xp.c
@@ -132,7 +132,7 @@ static void __exit ste10Xp_exit(void)
module_init(ste10Xp_init);
module_exit(ste10Xp_exit);
-static struct mdio_device_id ste10Xp_tbl[] = {
+static struct mdio_device_id __maybe_unused ste10Xp_tbl[] = {
{ STE101P_PHY_ID, 0xfffffff0 },
{ STE100P_PHY_ID, 0xffffffff },
{ }
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 45cce50a2799..5d8f6e17bd55 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -192,7 +192,7 @@ static void __exit vsc82xx_exit(void)
module_init(vsc82xx_init);
module_exit(vsc82xx_exit);
-static struct mdio_device_id vitesse_tbl[] = {
+static struct mdio_device_id __maybe_unused vitesse_tbl[] = {
{ PHY_ID_VSC8244, 0x000fffc0 },
{ PHY_ID_VSC8221, 0x000ffff0 },
{ }
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index ec0349e84a8a..ca4df7f4cf21 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -995,8 +995,10 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
static void
plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth)
{
- const struct in_device *in_dev = dev->ip_ptr;
+ const struct in_device *in_dev;
+ rcu_read_lock();
+ in_dev = __in_dev_get_rcu(dev);
if (in_dev) {
/* Any address will do - we take the first */
const struct in_ifaddr *ifa = in_dev->ifa_list;
@@ -1006,6 +1008,7 @@ plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth)
memcpy(eth->h_dest+2, &ifa->ifa_address, 4);
}
}
+ rcu_read_unlock();
}
static int
@@ -1088,7 +1091,8 @@ plip_open(struct net_device *dev)
when the device address isn't identical to the address of a
received frame, the kernel incorrectly drops it). */
- if ((in_dev=dev->ip_ptr) != NULL) {
+ in_dev=__in_dev_get_rtnl(dev);
+ if (in_dev) {
/* Any address will do - we take the first. We already
have the first two bytes filled with 0xfc, from
plip_init_dev(). */
@@ -1279,7 +1283,6 @@ static void plip_attach (struct parport *port)
if (!nl->pardev) {
printk(KERN_ERR "%s: parport_register failed\n", name);
goto err_free_dev;
- return;
}
plip_init_netdev(dev);
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 4bddb2afdd15..09cf56d0416a 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1548,9 +1548,11 @@ ppp_channel_push(struct channel *pch)
* Receive-side routines.
*/
-/* misuse a few fields of the skb for MP reconstruction */
-#define sequence priority
-#define BEbits cb[0]
+struct ppp_mp_skb_parm {
+ u32 sequence;
+ u8 BEbits;
+};
+#define PPP_MP_CB(skb) ((struct ppp_mp_skb_parm *)((skb)->cb))
static inline void
ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
@@ -1879,13 +1881,13 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
seq = (skb->data[3] << 16) | (skb->data[4] << 8)| skb->data[5];
mask = 0xffffff;
}
- skb->BEbits = skb->data[2];
+ PPP_MP_CB(skb)->BEbits = skb->data[2];
skb_pull(skb, mphdrlen); /* pull off PPP and MP headers */
/*
* Do protocol ID decompression on the first fragment of each packet.
*/
- if ((skb->BEbits & B) && (skb->data[0] & 1))
+ if ((PPP_MP_CB(skb)->BEbits & B) && (skb->data[0] & 1))
*skb_push(skb, 1) = 0;
/*
@@ -1897,7 +1899,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
seq += mask + 1;
else if ((int)(seq - ppp->minseq) > (int)(mask >> 1))
seq -= mask + 1; /* should never happen */
- skb->sequence = seq;
+ PPP_MP_CB(skb)->sequence = seq;
pch->lastseq = seq;
/*
@@ -1933,8 +1935,8 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
before the start of the queue. */
if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) {
struct sk_buff *mskb = skb_peek(&ppp->mrq);
- if (seq_before(ppp->minseq, mskb->sequence))
- ppp->minseq = mskb->sequence;
+ if (seq_before(ppp->minseq, PPP_MP_CB(mskb)->sequence))
+ ppp->minseq = PPP_MP_CB(mskb)->sequence;
}
/* Pull completed packets off the queue and receive them. */
@@ -1964,12 +1966,12 @@ ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb)
{
struct sk_buff *p;
struct sk_buff_head *list = &ppp->mrq;
- u32 seq = skb->sequence;
+ u32 seq = PPP_MP_CB(skb)->sequence;
/* N.B. we don't need to lock the list lock because we have the
ppp unit receive-side lock. */
skb_queue_walk(list, p) {
- if (seq_before(seq, p->sequence))
+ if (seq_before(seq, PPP_MP_CB(p)->sequence))
break;
}
__skb_queue_before(list, p, skb);
@@ -1998,22 +2000,22 @@ ppp_mp_reconstruct(struct ppp *ppp)
tail = NULL;
for (p = head; p != (struct sk_buff *) list; p = next) {
next = p->next;
- if (seq_before(p->sequence, seq)) {
+ if (seq_before(PPP_MP_CB(p)->sequence, seq)) {
/* this can't happen, anyway ignore the skb */
printk(KERN_ERR "ppp_mp_reconstruct bad seq %u < %u\n",
- p->sequence, seq);
+ PPP_MP_CB(p)->sequence, seq);
head = next;
continue;
}
- if (p->sequence != seq) {
+ if (PPP_MP_CB(p)->sequence != seq) {
/* Fragment `seq' is missing. If it is after
minseq, it might arrive later, so stop here. */
if (seq_after(seq, minseq))
break;
/* Fragment `seq' is lost, keep going. */
lost = 1;
- seq = seq_before(minseq, p->sequence)?
- minseq + 1: p->sequence;
+ seq = seq_before(minseq, PPP_MP_CB(p)->sequence)?
+ minseq + 1: PPP_MP_CB(p)->sequence;
next = p;
continue;
}
@@ -2027,7 +2029,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
*/
/* B bit set indicates this fragment starts a packet */
- if (p->BEbits & B) {
+ if (PPP_MP_CB(p)->BEbits & B) {
head = p;
lost = 0;
len = 0;
@@ -2036,7 +2038,8 @@ ppp_mp_reconstruct(struct ppp *ppp)
len += p->len;
/* Got a complete packet yet? */
- if (lost == 0 && (p->BEbits & E) && (head->BEbits & B)) {
+ if (lost == 0 && (PPP_MP_CB(p)->BEbits & E) &&
+ (PPP_MP_CB(head)->BEbits & B)) {
if (len > ppp->mrru + 2) {
++ppp->dev->stats.rx_length_errors;
printk(KERN_DEBUG "PPP: reconstructed packet"
@@ -2062,7 +2065,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
* and we haven't found a complete valid packet yet,
* we can discard up to and including this fragment.
*/
- if (p->BEbits & E)
+ if (PPP_MP_CB(p)->BEbits & E)
head = next;
++seq;
@@ -2072,10 +2075,11 @@ ppp_mp_reconstruct(struct ppp *ppp)
if (tail != NULL) {
/* If we have discarded any fragments,
signal a receive error. */
- if (head->sequence != ppp->nextseq) {
+ if (PPP_MP_CB(head)->sequence != ppp->nextseq) {
if (ppp->debug & 1)
printk(KERN_DEBUG " missed pkts %u..%u\n",
- ppp->nextseq, head->sequence-1);
+ ppp->nextseq,
+ PPP_MP_CB(head)->sequence-1);
++ppp->dev->stats.rx_dropped;
ppp_receive_error(ppp);
}
@@ -2084,7 +2088,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
/* copy to a single skb */
for (p = head; p != tail->next; p = p->next)
skb_copy_bits(p, 0, skb_put(skb, p->len), p->len);
- ppp->nextseq = tail->sequence + 1;
+ ppp->nextseq = PPP_MP_CB(tail)->sequence + 1;
head = tail->next;
}
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index c07de359dc07..d72fb0519a2a 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -1124,7 +1124,7 @@ static const struct proto_ops pppoe_ops = {
.ioctl = pppox_ioctl,
};
-static struct pppox_proto pppoe_proto = {
+static const struct pppox_proto pppoe_proto = {
.create = pppoe_create,
.ioctl = pppoe_ioctl,
.owner = THIS_MODULE,
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
index d4191ef9cad1..8c0d170dabcd 100644
--- a/drivers/net/pppox.c
+++ b/drivers/net/pppox.c
@@ -36,9 +36,9 @@
#include <asm/uaccess.h>
-static struct pppox_proto *pppox_protos[PX_MAX_PROTO + 1];
+static const struct pppox_proto *pppox_protos[PX_MAX_PROTO + 1];
-int register_pppox_proto(int proto_num, struct pppox_proto *pp)
+int register_pppox_proto(int proto_num, const struct pppox_proto *pp)
{
if (proto_num < 0 || proto_num > PX_MAX_PROTO)
return -EINVAL;
diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c
new file mode 100644
index 000000000000..ccbc91326bfa
--- /dev/null
+++ b/drivers/net/pptp.c
@@ -0,0 +1,726 @@
+/*
+ * Point-to-Point Tunneling Protocol for Linux
+ *
+ * Authors: Dmitry Kozlov <xeb@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/net.h>
+#include <linux/skbuff.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/ppp_channel.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_pppox.h>
+#include <linux/if_ppp.h>
+#include <linux/notifier.h>
+#include <linux/file.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/version.h>
+#include <linux/rcupdate.h>
+#include <linux/spinlock.h>
+
+#include <net/sock.h>
+#include <net/protocol.h>
+#include <net/ip.h>
+#include <net/icmp.h>
+#include <net/route.h>
+#include <net/gre.h>
+
+#include <linux/uaccess.h>
+
+#define PPTP_DRIVER_VERSION "0.8.5"
+
+#define MAX_CALLID 65535
+
+static DECLARE_BITMAP(callid_bitmap, MAX_CALLID + 1);
+static struct pppox_sock **callid_sock;
+
+static DEFINE_SPINLOCK(chan_lock);
+
+static struct proto pptp_sk_proto __read_mostly;
+static const struct ppp_channel_ops pptp_chan_ops;
+static const struct proto_ops pptp_ops;
+
+#define PPP_LCP_ECHOREQ 0x09
+#define PPP_LCP_ECHOREP 0x0A
+#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
+
+#define MISSING_WINDOW 20
+#define WRAPPED(curseq, lastseq)\
+ ((((curseq) & 0xffffff00) == 0) &&\
+ (((lastseq) & 0xffffff00) == 0xffffff00))
+
+#define PPTP_GRE_PROTO 0x880B
+#define PPTP_GRE_VER 0x1
+
+#define PPTP_GRE_FLAG_C 0x80
+#define PPTP_GRE_FLAG_R 0x40
+#define PPTP_GRE_FLAG_K 0x20
+#define PPTP_GRE_FLAG_S 0x10
+#define PPTP_GRE_FLAG_A 0x80
+
+#define PPTP_GRE_IS_C(f) ((f)&PPTP_GRE_FLAG_C)
+#define PPTP_GRE_IS_R(f) ((f)&PPTP_GRE_FLAG_R)
+#define PPTP_GRE_IS_K(f) ((f)&PPTP_GRE_FLAG_K)
+#define PPTP_GRE_IS_S(f) ((f)&PPTP_GRE_FLAG_S)
+#define PPTP_GRE_IS_A(f) ((f)&PPTP_GRE_FLAG_A)
+
+#define PPTP_HEADER_OVERHEAD (2+sizeof(struct pptp_gre_header))
+struct pptp_gre_header {
+ u8 flags;
+ u8 ver;
+ u16 protocol;
+ u16 payload_len;
+ u16 call_id;
+ u32 seq;
+ u32 ack;
+} __packed;
+
+static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr)
+{
+ struct pppox_sock *sock;
+ struct pptp_opt *opt;
+
+ rcu_read_lock();
+ sock = rcu_dereference(callid_sock[call_id]);
+ if (sock) {
+ opt = &sock->proto.pptp;
+ if (opt->dst_addr.sin_addr.s_addr != s_addr)
+ sock = NULL;
+ else
+ sock_hold(sk_pppox(sock));
+ }
+ rcu_read_unlock();
+
+ return sock;
+}
+
+static int lookup_chan_dst(u16 call_id, __be32 d_addr)
+{
+ struct pppox_sock *sock;
+ struct pptp_opt *opt;
+ int i;
+
+ rcu_read_lock();
+ for (i = find_next_bit(callid_bitmap, MAX_CALLID, 1); i < MAX_CALLID;
+ i = find_next_bit(callid_bitmap, MAX_CALLID, i + 1)) {
+ sock = rcu_dereference(callid_sock[i]);
+ if (!sock)
+ continue;
+ opt = &sock->proto.pptp;
+ if (opt->dst_addr.call_id == call_id &&
+ opt->dst_addr.sin_addr.s_addr == d_addr)
+ break;
+ }
+ rcu_read_unlock();
+
+ return i < MAX_CALLID;
+}
+
+static int add_chan(struct pppox_sock *sock)
+{
+ static int call_id;
+
+ spin_lock(&chan_lock);
+ if (!sock->proto.pptp.src_addr.call_id) {
+ call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, call_id + 1);
+ if (call_id == MAX_CALLID) {
+ call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, 1);
+ if (call_id == MAX_CALLID)
+ goto out_err;
+ }
+ sock->proto.pptp.src_addr.call_id = call_id;
+ } else if (test_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap))
+ goto out_err;
+
+ set_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap);
+ rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], sock);
+ spin_unlock(&chan_lock);
+
+ return 0;
+
+out_err:
+ spin_unlock(&chan_lock);
+ return -1;
+}
+
+static void del_chan(struct pppox_sock *sock)
+{
+ spin_lock(&chan_lock);
+ clear_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap);
+ rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], NULL);
+ spin_unlock(&chan_lock);
+ synchronize_rcu();
+}
+
+static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
+{
+ struct sock *sk = (struct sock *) chan->private;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ struct pptp_gre_header *hdr;
+ unsigned int header_len = sizeof(*hdr);
+ int err = 0;
+ int islcp;
+ int len;
+ unsigned char *data;
+ __u32 seq_recv;
+
+
+ struct rtable *rt;
+ struct net_device *tdev;
+ struct iphdr *iph;
+ int max_headroom;
+
+ if (sk_pppox(po)->sk_state & PPPOX_DEAD)
+ goto tx_error;
+
+ {
+ struct flowi fl = { .oif = 0,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = opt->dst_addr.sin_addr.s_addr,
+ .saddr = opt->src_addr.sin_addr.s_addr,
+ .tos = RT_TOS(0) } },
+ .proto = IPPROTO_GRE };
+ err = ip_route_output_key(&init_net, &rt, &fl);
+ if (err)
+ goto tx_error;
+ }
+ tdev = rt->dst.dev;
+
+ max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(*iph) + sizeof(*hdr) + 2;
+
+ if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
+ struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
+ if (!new_skb) {
+ ip_rt_put(rt);
+ goto tx_error;
+ }
+ if (skb->sk)
+ skb_set_owner_w(new_skb, skb->sk);
+ kfree_skb(skb);
+ skb = new_skb;
+ }
+
+ data = skb->data;
+ islcp = ((data[0] << 8) + data[1]) == PPP_LCP && 1 <= data[2] && data[2] <= 7;
+
+ /* compress protocol field */
+ if ((opt->ppp_flags & SC_COMP_PROT) && data[0] == 0 && !islcp)
+ skb_pull(skb, 1);
+
+ /* Put in the address/control bytes if necessary */
+ if ((opt->ppp_flags & SC_COMP_AC) == 0 || islcp) {
+ data = skb_push(skb, 2);
+ data[0] = PPP_ALLSTATIONS;
+ data[1] = PPP_UI;
+ }
+
+ len = skb->len;
+
+ seq_recv = opt->seq_recv;
+
+ if (opt->ack_sent == seq_recv)
+ header_len -= sizeof(hdr->ack);
+
+ /* Push down and install GRE header */
+ skb_push(skb, header_len);
+ hdr = (struct pptp_gre_header *)(skb->data);
+
+ hdr->flags = PPTP_GRE_FLAG_K;
+ hdr->ver = PPTP_GRE_VER;
+ hdr->protocol = htons(PPTP_GRE_PROTO);
+ hdr->call_id = htons(opt->dst_addr.call_id);
+
+ hdr->flags |= PPTP_GRE_FLAG_S;
+ hdr->seq = htonl(++opt->seq_sent);
+ if (opt->ack_sent != seq_recv) {
+ /* send ack with this message */
+ hdr->ver |= PPTP_GRE_FLAG_A;
+ hdr->ack = htonl(seq_recv);
+ opt->ack_sent = seq_recv;
+ }
+ hdr->payload_len = htons(len);
+
+ /* Push down and install the IP header. */
+
+ skb_reset_transport_header(skb);
+ skb_push(skb, sizeof(*iph));
+ skb_reset_network_header(skb);
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED);
+
+ iph = ip_hdr(skb);
+ iph->version = 4;
+ iph->ihl = sizeof(struct iphdr) >> 2;
+ if (ip_dont_fragment(sk, &rt->dst))
+ iph->frag_off = htons(IP_DF);
+ else
+ iph->frag_off = 0;
+ iph->protocol = IPPROTO_GRE;
+ iph->tos = 0;
+ iph->daddr = rt->rt_dst;
+ iph->saddr = rt->rt_src;
+ iph->ttl = dst_metric(&rt->dst, RTAX_HOPLIMIT);
+ iph->tot_len = htons(skb->len);
+
+ skb_dst_drop(skb);
+ skb_dst_set(skb, &rt->dst);
+
+ nf_reset(skb);
+
+ skb->ip_summed = CHECKSUM_NONE;
+ ip_select_ident(iph, &rt->dst, NULL);
+ ip_send_check(iph);
+
+ ip_local_out(skb);
+
+tx_error:
+ return 1;
+}
+
+static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb)
+{
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ int headersize, payload_len, seq;
+ __u8 *payload;
+ struct pptp_gre_header *header;
+
+ if (!(sk->sk_state & PPPOX_CONNECTED)) {
+ if (sock_queue_rcv_skb(sk, skb))
+ goto drop;
+ return NET_RX_SUCCESS;
+ }
+
+ header = (struct pptp_gre_header *)(skb->data);
+
+ /* test if acknowledgement present */
+ if (PPTP_GRE_IS_A(header->ver)) {
+ __u32 ack = (PPTP_GRE_IS_S(header->flags)) ?
+ header->ack : header->seq; /* ack in different place if S = 0 */
+
+ ack = ntohl(ack);
+
+ if (ack > opt->ack_recv)
+ opt->ack_recv = ack;
+ /* also handle sequence number wrap-around */
+ if (WRAPPED(ack, opt->ack_recv))
+ opt->ack_recv = ack;
+ }
+
+ /* test if payload present */
+ if (!PPTP_GRE_IS_S(header->flags))
+ goto drop;
+
+ headersize = sizeof(*header);
+ payload_len = ntohs(header->payload_len);
+ seq = ntohl(header->seq);
+
+ /* no ack present? */
+ if (!PPTP_GRE_IS_A(header->ver))
+ headersize -= sizeof(header->ack);
+ /* check for incomplete packet (length smaller than expected) */
+ if (skb->len - headersize < payload_len)
+ goto drop;
+
+ payload = skb->data + headersize;
+ /* check for expected sequence number */
+ if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) {
+ if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) &&
+ (PPP_PROTOCOL(payload) == PPP_LCP) &&
+ ((payload[4] == PPP_LCP_ECHOREQ) || (payload[4] == PPP_LCP_ECHOREP)))
+ goto allow_packet;
+ } else {
+ opt->seq_recv = seq;
+allow_packet:
+ skb_pull(skb, headersize);
+
+ if (payload[0] == PPP_ALLSTATIONS && payload[1] == PPP_UI) {
+ /* chop off address/control */
+ if (skb->len < 3)
+ goto drop;
+ skb_pull(skb, 2);
+ }
+
+ if ((*skb->data) & 1) {
+ /* protocol is compressed */
+ skb_push(skb, 1)[0] = 0;
+ }
+
+ skb->ip_summed = CHECKSUM_NONE;
+ skb_set_network_header(skb, skb->head-skb->data);
+ ppp_input(&po->chan, skb);
+
+ return NET_RX_SUCCESS;
+ }
+drop:
+ kfree_skb(skb);
+ return NET_RX_DROP;
+}
+
+static int pptp_rcv(struct sk_buff *skb)
+{
+ struct pppox_sock *po;
+ struct pptp_gre_header *header;
+ struct iphdr *iph;
+
+ if (skb->pkt_type != PACKET_HOST)
+ goto drop;
+
+ if (!pskb_may_pull(skb, 12))
+ goto drop;
+
+ iph = ip_hdr(skb);
+
+ header = (struct pptp_gre_header *)skb->data;
+
+ if (ntohs(header->protocol) != PPTP_GRE_PROTO || /* PPTP-GRE protocol for PPTP */
+ PPTP_GRE_IS_C(header->flags) || /* flag C should be clear */
+ PPTP_GRE_IS_R(header->flags) || /* flag R should be clear */
+ !PPTP_GRE_IS_K(header->flags) || /* flag K should be set */
+ (header->flags&0xF) != 0) /* routing and recursion ctrl = 0 */
+ /* if invalid, discard this packet */
+ goto drop;
+
+ po = lookup_chan(htons(header->call_id), iph->saddr);
+ if (po) {
+ skb_dst_drop(skb);
+ nf_reset(skb);
+ return sk_receive_skb(sk_pppox(po), skb, 0);
+ }
+drop:
+ kfree_skb(skb);
+ return NET_RX_DROP;
+}
+
+static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr,
+ int sockaddr_len)
+{
+ struct sock *sk = sock->sk;
+ struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ int error = 0;
+
+ lock_sock(sk);
+
+ opt->src_addr = sp->sa_addr.pptp;
+ if (add_chan(po)) {
+ release_sock(sk);
+ error = -EBUSY;
+ }
+
+ release_sock(sk);
+ return error;
+}
+
+static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
+ int sockaddr_len, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ struct rtable *rt;
+ int error = 0;
+
+ if (sp->sa_protocol != PX_PROTO_PPTP)
+ return -EINVAL;
+
+ if (lookup_chan_dst(sp->sa_addr.pptp.call_id, sp->sa_addr.pptp.sin_addr.s_addr))
+ return -EALREADY;
+
+ lock_sock(sk);
+ /* Check for already bound sockets */
+ if (sk->sk_state & PPPOX_CONNECTED) {
+ error = -EBUSY;
+ goto end;
+ }
+
+ /* Check for already disconnected sockets, on attempts to disconnect */
+ if (sk->sk_state & PPPOX_DEAD) {
+ error = -EALREADY;
+ goto end;
+ }
+
+ if (!opt->src_addr.sin_addr.s_addr || !sp->sa_addr.pptp.sin_addr.s_addr) {
+ error = -EINVAL;
+ goto end;
+ }
+
+ po->chan.private = sk;
+ po->chan.ops = &pptp_chan_ops;
+
+ {
+ struct flowi fl = {
+ .nl_u = {
+ .ip4_u = {
+ .daddr = opt->dst_addr.sin_addr.s_addr,
+ .saddr = opt->src_addr.sin_addr.s_addr,
+ .tos = RT_CONN_FLAGS(sk) } },
+ .proto = IPPROTO_GRE };
+ security_sk_classify_flow(sk, &fl);
+ if (ip_route_output_key(&init_net, &rt, &fl)) {
+ error = -EHOSTUNREACH;
+ goto end;
+ }
+ sk_setup_caps(sk, &rt->dst);
+ }
+ po->chan.mtu = dst_mtu(&rt->dst);
+ if (!po->chan.mtu)
+ po->chan.mtu = PPP_MTU;
+ ip_rt_put(rt);
+ po->chan.mtu -= PPTP_HEADER_OVERHEAD;
+
+ po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header);
+ error = ppp_register_channel(&po->chan);
+ if (error) {
+ pr_err("PPTP: failed to register PPP channel (%d)\n", error);
+ goto end;
+ }
+
+ opt->dst_addr = sp->sa_addr.pptp;
+ sk->sk_state = PPPOX_CONNECTED;
+
+ end:
+ release_sock(sk);
+ return error;
+}
+
+static int pptp_getname(struct socket *sock, struct sockaddr *uaddr,
+ int *usockaddr_len, int peer)
+{
+ int len = sizeof(struct sockaddr_pppox);
+ struct sockaddr_pppox sp;
+
+ sp.sa_family = AF_PPPOX;
+ sp.sa_protocol = PX_PROTO_PPTP;
+ sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr;
+
+ memcpy(uaddr, &sp, len);
+
+ *usockaddr_len = len;
+
+ return 0;
+}
+
+static int pptp_release(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+ struct pppox_sock *po;
+ struct pptp_opt *opt;
+ int error = 0;
+
+ if (!sk)
+ return 0;
+
+ lock_sock(sk);
+
+ if (sock_flag(sk, SOCK_DEAD)) {
+ release_sock(sk);
+ return -EBADF;
+ }
+
+ po = pppox_sk(sk);
+ opt = &po->proto.pptp;
+ del_chan(po);
+
+ pppox_unbind_sock(sk);
+ sk->sk_state = PPPOX_DEAD;
+
+ sock_orphan(sk);
+ sock->sk = NULL;
+
+ release_sock(sk);
+ sock_put(sk);
+
+ return error;
+}
+
+static void pptp_sock_destruct(struct sock *sk)
+{
+ if (!(sk->sk_state & PPPOX_DEAD)) {
+ del_chan(pppox_sk(sk));
+ pppox_unbind_sock(sk);
+ }
+ skb_queue_purge(&sk->sk_receive_queue);
+}
+
+static int pptp_create(struct net *net, struct socket *sock)
+{
+ int error = -ENOMEM;
+ struct sock *sk;
+ struct pppox_sock *po;
+ struct pptp_opt *opt;
+
+ sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pptp_sk_proto);
+ if (!sk)
+ goto out;
+
+ sock_init_data(sock, sk);
+
+ sock->state = SS_UNCONNECTED;
+ sock->ops = &pptp_ops;
+
+ sk->sk_backlog_rcv = pptp_rcv_core;
+ sk->sk_state = PPPOX_NONE;
+ sk->sk_type = SOCK_STREAM;
+ sk->sk_family = PF_PPPOX;
+ sk->sk_protocol = PX_PROTO_PPTP;
+ sk->sk_destruct = pptp_sock_destruct;
+
+ po = pppox_sk(sk);
+ opt = &po->proto.pptp;
+
+ opt->seq_sent = 0; opt->seq_recv = 0;
+ opt->ack_recv = 0; opt->ack_sent = 0;
+
+ error = 0;
+out:
+ return error;
+}
+
+static int pptp_ppp_ioctl(struct ppp_channel *chan, unsigned int cmd,
+ unsigned long arg)
+{
+ struct sock *sk = (struct sock *) chan->private;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int err, val;
+
+ err = -EFAULT;
+ switch (cmd) {
+ case PPPIOCGFLAGS:
+ val = opt->ppp_flags;
+ if (put_user(val, p))
+ break;
+ err = 0;
+ break;
+ case PPPIOCSFLAGS:
+ if (get_user(val, p))
+ break;
+ opt->ppp_flags = val & ~SC_RCV_BITS;
+ err = 0;
+ break;
+ default:
+ err = -ENOTTY;
+ }
+
+ return err;
+}
+
+static const struct ppp_channel_ops pptp_chan_ops = {
+ .start_xmit = pptp_xmit,
+ .ioctl = pptp_ppp_ioctl,
+};
+
+static struct proto pptp_sk_proto __read_mostly = {
+ .name = "PPTP",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct pppox_sock),
+};
+
+static const struct proto_ops pptp_ops = {
+ .family = AF_PPPOX,
+ .owner = THIS_MODULE,
+ .release = pptp_release,
+ .bind = pptp_bind,
+ .connect = pptp_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .getname = pptp_getname,
+ .poll = sock_no_poll,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .setsockopt = sock_no_setsockopt,
+ .getsockopt = sock_no_getsockopt,
+ .sendmsg = sock_no_sendmsg,
+ .recvmsg = sock_no_recvmsg,
+ .mmap = sock_no_mmap,
+ .ioctl = pppox_ioctl,
+};
+
+static const struct pppox_proto pppox_pptp_proto = {
+ .create = pptp_create,
+ .owner = THIS_MODULE,
+};
+
+static const struct gre_protocol gre_pptp_protocol = {
+ .handler = pptp_rcv,
+};
+
+static int __init pptp_init_module(void)
+{
+ int err = 0;
+ pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n");
+
+ callid_sock = __vmalloc((MAX_CALLID + 1) * sizeof(void *),
+ GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
+ if (!callid_sock) {
+ pr_err("PPTP: cann't allocate memory\n");
+ return -ENOMEM;
+ }
+
+ err = gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
+ if (err) {
+ pr_err("PPTP: can't add gre protocol\n");
+ goto out_mem_free;
+ }
+
+ err = proto_register(&pptp_sk_proto, 0);
+ if (err) {
+ pr_err("PPTP: can't register sk_proto\n");
+ goto out_gre_del_protocol;
+ }
+
+ err = register_pppox_proto(PX_PROTO_PPTP, &pppox_pptp_proto);
+ if (err) {
+ pr_err("PPTP: can't register pppox_proto\n");
+ goto out_unregister_sk_proto;
+ }
+
+ return 0;
+
+out_unregister_sk_proto:
+ proto_unregister(&pptp_sk_proto);
+out_gre_del_protocol:
+ gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
+out_mem_free:
+ vfree(callid_sock);
+
+ return err;
+}
+
+static void __exit pptp_exit_module(void)
+{
+ unregister_pppox_proto(PX_PROTO_PPTP);
+ proto_unregister(&pptp_sk_proto);
+ gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
+ vfree(callid_sock);
+}
+
+module_init(pptp_init_module);
+module_exit(pptp_exit_module);
+
+MODULE_DESCRIPTION("Point-to-Point Tunneling Protocol");
+MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 87d6b8f36304..5526ab4895e6 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -956,9 +956,9 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr,
(!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* update netdevice statistics */
netdev->stats.rx_packets++;
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 43b8d7797f0a..4a624a29393f 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -85,12 +85,12 @@ static const int bitrate_list[] = {
*/
static inline int wpa2_capable(void)
{
- return (0 <= ps3_compare_firmware_version(2, 0, 0));
+ return 0 <= ps3_compare_firmware_version(2, 0, 0);
}
static inline int precise_ie(void)
{
- return (0 <= ps3_compare_firmware_version(2, 2, 0));
+ return 0 <= ps3_compare_firmware_version(2, 2, 0);
}
/*
* post_eurus_cmd helpers
@@ -506,7 +506,7 @@ static size_t gelic_wl_synthesize_ie(u8 *buf,
start[1] = (buf - start - 2);
pr_debug("%s: ->\n", __func__);
- return (buf - start);
+ return buf - start;
}
struct ie_item {
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c
index 85eddda276bd..18c0297743f1 100644
--- a/drivers/net/pxa168_eth.c
+++ b/drivers/net/pxa168_eth.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2010 Marvell International Ltd.
* Sachin Sanap <ssanap@marvell.com>
+ * Zhangfei Gao <zgao6@marvell.com>
* Philip Rakity <prakity@marvell.com>
* Mark Brown <markb@marvell.com>
*
@@ -42,8 +43,6 @@
#include <linux/types.h>
#include <asm/pgtable.h>
#include <asm/system.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
#include <asm/cacheflush.h>
#include <linux/pxa168_eth.h>
@@ -850,7 +849,6 @@ static int rxq_process(struct net_device *dev, int budget)
skb->protocol = eth_type_trans(skb, dev);
netif_receive_skb(skb);
}
- dev->last_rx = jiffies;
}
/* Fill RX ring with skb's */
rxq_refill(dev);
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 6168a130f33f..7496ed2c34ab 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -2029,7 +2029,7 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev,
dma_unmap_len(lrg_buf_cb2, maplen),
PCI_DMA_FROMDEVICE);
prefetch(skb->data);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, qdev->ndev);
netif_receive_skb(skb);
@@ -2076,7 +2076,7 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
PCI_DMA_FROMDEVICE);
prefetch(skb2->data);
- skb2->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb2);
if (qdev->device_id == QL3022_DEVICE_ID) {
/*
* Copy the ethhdr from first buffer to second. This
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 970389331bbc..26c37d3a5868 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -51,9 +51,11 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 7
-#define QLCNIC_LINUX_VERSIONID "5.0.7"
+#define _QLCNIC_LINUX_SUBVERSION 11
+#define QLCNIC_LINUX_VERSIONID "5.0.11"
#define QLCNIC_DRV_IDC_VER 0x01
+#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
+ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
#define QLCNIC_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
#define _major(v) (((v) >> 24) & 0xff)
@@ -92,11 +94,12 @@
#define FIRST_PAGE_GROUP_START 0
#define FIRST_PAGE_GROUP_END 0x100000
-#define P3_MAX_MTU (9600)
+#define P3P_MAX_MTU (9600)
+#define P3P_MIN_MTU (68)
#define QLCNIC_MAX_ETHERHDR 32 /* This contains some padding */
-#define QLCNIC_P3_RX_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + ETH_DATA_LEN)
-#define QLCNIC_P3_RX_JUMBO_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + P3_MAX_MTU)
+#define QLCNIC_P3P_RX_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + ETH_DATA_LEN)
+#define QLCNIC_P3P_RX_JUMBO_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + P3P_MAX_MTU)
#define QLCNIC_CT_DEFAULT_RX_BUF_LEN 2048
#define QLCNIC_LRO_BUFFER_EXTRA 2048
@@ -148,6 +151,7 @@
#define DEFAULT_RCV_DESCRIPTORS_1G 2048
#define DEFAULT_RCV_DESCRIPTORS_10G 4096
+#define MAX_RDS_RINGS 2
#define get_next_index(index, length) \
(((index) + 1) & ((length) - 1))
@@ -172,7 +176,7 @@
((_desc)->port_ctxid = ((_port) & 0xf) | (((_port) << 4) & 0xf0))
#define qlcnic_set_tx_flags_opcode(_desc, _flags, _opcode) \
- ((_desc)->flags_opcode = \
+ ((_desc)->flags_opcode |= \
cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7)))
#define qlcnic_set_tx_frags_len(_desc, _frags, _len) \
@@ -221,7 +225,8 @@ struct rcv_desc {
#define QLCNIC_LRO_DESC 0x12
/* for status field in status_desc */
-#define STATUS_CKSUM_OK (2)
+#define STATUS_CKSUM_LOOP 0
+#define STATUS_CKSUM_OK 2
/* owner bits of status_desc */
#define STATUS_OWNER_HOST (0x1ULL << 56)
@@ -302,20 +307,20 @@ struct uni_data_desc{
/* Magic number to let user know flash is programmed */
#define QLCNIC_BDINFO_MAGIC 0x12345678
-#define QLCNIC_BRDTYPE_P3_REF_QG 0x0021
-#define QLCNIC_BRDTYPE_P3_HMEZ 0x0022
-#define QLCNIC_BRDTYPE_P3_10G_CX4_LP 0x0023
-#define QLCNIC_BRDTYPE_P3_4_GB 0x0024
-#define QLCNIC_BRDTYPE_P3_IMEZ 0x0025
-#define QLCNIC_BRDTYPE_P3_10G_SFP_PLUS 0x0026
-#define QLCNIC_BRDTYPE_P3_10000_BASE_T 0x0027
-#define QLCNIC_BRDTYPE_P3_XG_LOM 0x0028
-#define QLCNIC_BRDTYPE_P3_4_GB_MM 0x0029
-#define QLCNIC_BRDTYPE_P3_10G_SFP_CT 0x002a
-#define QLCNIC_BRDTYPE_P3_10G_SFP_QT 0x002b
-#define QLCNIC_BRDTYPE_P3_10G_CX4 0x0031
-#define QLCNIC_BRDTYPE_P3_10G_XFP 0x0032
-#define QLCNIC_BRDTYPE_P3_10G_TP 0x0080
+#define QLCNIC_BRDTYPE_P3P_REF_QG 0x0021
+#define QLCNIC_BRDTYPE_P3P_HMEZ 0x0022
+#define QLCNIC_BRDTYPE_P3P_10G_CX4_LP 0x0023
+#define QLCNIC_BRDTYPE_P3P_4_GB 0x0024
+#define QLCNIC_BRDTYPE_P3P_IMEZ 0x0025
+#define QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS 0x0026
+#define QLCNIC_BRDTYPE_P3P_10000_BASE_T 0x0027
+#define QLCNIC_BRDTYPE_P3P_XG_LOM 0x0028
+#define QLCNIC_BRDTYPE_P3P_4_GB_MM 0x0029
+#define QLCNIC_BRDTYPE_P3P_10G_SFP_CT 0x002a
+#define QLCNIC_BRDTYPE_P3P_10G_SFP_QT 0x002b
+#define QLCNIC_BRDTYPE_P3P_10G_CX4 0x0031
+#define QLCNIC_BRDTYPE_P3P_10G_XFP 0x0032
+#define QLCNIC_BRDTYPE_P3P_10G_TP 0x0080
#define QLCNIC_MSIX_TABLE_OFFSET 0x44
@@ -555,6 +560,8 @@ struct qlcnic_recv_context {
#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026
#define QLCNIC_CDRP_CMD_SET_PORTMIRRORING 0x00000027
#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_RCODE_SUCCESS 0
#define QLCNIC_RCODE_TIMEOUT 17
@@ -712,11 +719,13 @@ struct qlcnic_cardrsp_tx_ctx {
/* MAC */
-#define MC_COUNT_P3 38
+#define MC_COUNT_P3P 38
#define QLCNIC_MAC_NOOP 0
#define QLCNIC_MAC_ADD 1
#define QLCNIC_MAC_DEL 2
+#define QLCNIC_MAC_VLAN_ADD 3
+#define QLCNIC_MAC_VLAN_DEL 4
struct qlcnic_mac_list_s {
struct list_head list;
@@ -890,12 +899,28 @@ struct qlcnic_mac_req {
u8 mac_addr[6];
};
+struct qlcnic_vlan_req {
+ __le16 vlan_id;
+ __le16 rsvd[3];
+};
+
+struct qlcnic_ipaddr {
+ __be32 ipv4;
+ __be32 ipv6[4];
+};
+
#define QLCNIC_MSI_ENABLED 0x02
#define QLCNIC_MSIX_ENABLED 0x04
#define QLCNIC_LRO_ENABLED 0x08
+#define QLCNIC_LRO_DISABLED 0x00
#define QLCNIC_BRIDGE_ENABLED 0X10
#define QLCNIC_DIAG_ENABLED 0x20
#define QLCNIC_ESWITCH_ENABLED 0x40
+#define QLCNIC_ADAPTER_INITIALIZED 0x80
+#define QLCNIC_TAGGING_ENABLED 0x100
+#define QLCNIC_MACSPOOF 0x200
+#define QLCNIC_MAC_OVERRIDE_DISABLED 0x400
+#define QLCNIC_PROMISC_DISABLED 0x800
#define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
@@ -916,6 +941,22 @@ struct qlcnic_mac_req {
#define QLCNIC_INTERRUPT_TEST 1
#define QLCNIC_LOOPBACK_TEST 2
+#define QLCNIC_FILTER_AGE 80
+#define QLCNIC_LB_MAX_FILTERS 64
+
+struct qlcnic_filter {
+ struct hlist_node fnode;
+ u8 faddr[ETH_ALEN];
+ __le16 vlan_id;
+ unsigned long ftime;
+};
+
+struct qlcnic_filter_hash {
+ struct hlist_head *fhead;
+ u8 fnum;
+ u8 fmax;
+};
+
struct qlcnic_adapter {
struct qlcnic_hardware_context ahw;
@@ -924,6 +965,7 @@ struct qlcnic_adapter {
struct list_head mac_list;
spinlock_t tx_clean_lock;
+ spinlock_t mac_learn_lock;
u16 num_txd;
u16 num_rxd;
@@ -931,7 +973,6 @@ struct qlcnic_adapter {
u8 max_rds_rings;
u8 max_sds_rings;
- u8 driver_mismatch;
u8 msix_supported;
u8 rx_csum;
u8 portnum;
@@ -961,6 +1002,7 @@ struct qlcnic_adapter {
u16 max_tx_ques;
u16 max_rx_ques;
u16 max_mtu;
+ u16 pvid;
u32 fw_hal_version;
u32 capabilities;
@@ -969,7 +1011,7 @@ struct qlcnic_adapter {
u32 temp;
u32 int_vec_bit;
- u32 heartbit;
+ u32 heartbeat;
u8 max_mac_filters;
u8 dev_state;
@@ -983,6 +1025,7 @@ struct qlcnic_adapter {
u64 dev_rst_time;
+ struct vlan_group *vlgrp;
struct qlcnic_npar_info *npars;
struct qlcnic_eswitch *eswitch;
struct qlcnic_nic_template *nic_ops;
@@ -1003,6 +1046,8 @@ struct qlcnic_adapter {
struct qlcnic_nic_intr_coalesce coal;
+ struct qlcnic_filter_hash fhash;
+
unsigned long state;
__le32 file_prd_off; /*File fw product offset*/
u32 fw_version;
@@ -1042,7 +1087,7 @@ struct qlcnic_pci_info {
};
struct qlcnic_npar_info {
- u16 vlan_id;
+ u16 pvid;
u16 min_bw;
u16 max_bw;
u8 phy_port;
@@ -1050,11 +1095,13 @@ struct qlcnic_npar_info {
u8 active;
u8 enable_pm;
u8 dest_npar;
- u8 host_vlan_tag;
- u8 promisc_mode;
u8 discard_tagged;
- u8 mac_learning;
+ u8 mac_override;
+ u8 mac_anti_spoof;
+ u8 promisc_mode;
+ u8 offload_flags;
};
+
struct qlcnic_eswitch {
u8 port;
u8 active_vports;
@@ -1086,7 +1133,6 @@ struct qlcnic_eswitch {
#define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW)
#define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES)
#define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES)
-#define IS_VALID_MODE(mode) (mode == 0 || mode == 1)
struct qlcnic_pci_func_cfg {
u16 func_type;
@@ -1118,12 +1164,53 @@ struct qlcnic_pm_func_cfg {
struct qlcnic_esw_func_cfg {
u16 vlan_id;
+ u8 op_mode;
+ u8 op_type;
u8 pci_func;
u8 host_vlan_tag;
u8 promisc_mode;
u8 discard_tagged;
- u8 mac_learning;
- u8 reserved;
+ u8 mac_override;
+ u8 mac_anti_spoof;
+ u8 offload_flags;
+ u8 reserved[5];
+};
+
+#define QLCNIC_STATS_VERSION 1
+#define QLCNIC_STATS_PORT 1
+#define QLCNIC_STATS_ESWITCH 2
+#define QLCNIC_QUERY_RX_COUNTER 0
+#define QLCNIC_QUERY_TX_COUNTER 1
+#define QLCNIC_ESW_STATS_NOT_AVAIL 0xffffffffffffffffULL
+
+#define QLCNIC_ADD_ESW_STATS(VAL1, VAL2)\
+do { \
+ if (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) && \
+ ((VAL2) != QLCNIC_ESW_STATS_NOT_AVAIL)) \
+ (VAL1) = (VAL2); \
+ else if (((VAL1) != QLCNIC_ESW_STATS_NOT_AVAIL) && \
+ ((VAL2) != QLCNIC_ESW_STATS_NOT_AVAIL)) \
+ (VAL1) += (VAL2); \
+} while (0)
+
+struct __qlcnic_esw_statistics {
+ __le16 context_id;
+ __le16 version;
+ __le16 size;
+ __le16 unused;
+ __le64 unicast_frames;
+ __le64 multicast_frames;
+ __le64 broadcast_frames;
+ __le64 dropped_frames;
+ __le64 errors;
+ __le64 local_frames;
+ __le64 numbytes;
+ __le64 rsvd[3];
+};
+
+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);
@@ -1171,6 +1258,8 @@ void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int);
int qlcnic_get_board_info(struct qlcnic_adapter *adapter);
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);
/* Functions from qlcnic_init.c */
int qlcnic_load_firmware(struct qlcnic_adapter *adapter);
@@ -1199,7 +1288,7 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter);
void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter);
void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter);
-int qlcnic_init_firmware(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,
struct qlcnic_host_rds_ring *rds_ring);
@@ -1209,7 +1298,7 @@ void qlcnic_free_mac_list(struct qlcnic_adapter *adapter);
int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32);
int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter);
int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable);
-int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd);
+int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd);
int qlcnic_linkevent_request(struct qlcnic_adapter *adapter, int enable);
void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup);
@@ -1220,12 +1309,13 @@ int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
struct qlcnic_host_tx_ring *tx_ring);
-int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac);
void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter);
int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter);
void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *);
/* Functions from qlcnic_main.c */
+int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter);
+void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter);
int qlcnic_reset_context(struct qlcnic_adapter *);
u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd);
@@ -1236,22 +1326,22 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring);
/* Management functions */
-int qlcnic_set_mac_address(struct qlcnic_adapter *, u8*);
int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*);
int qlcnic_get_nic_info(struct qlcnic_adapter *, struct qlcnic_info *, u8);
int qlcnic_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *);
int qlcnic_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info*);
-int qlcnic_reset_partition(struct qlcnic_adapter *, u8);
/* eSwitch management functions */
-int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *, u8,
- struct qlcnic_eswitch *);
-int qlcnic_get_eswitch_status(struct qlcnic_adapter *, u8,
- struct qlcnic_eswitch *);
-int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8);
-int qlcnic_config_switch_port(struct qlcnic_adapter *, u8, int, u8, u8,
- u8, u8, u16);
+int qlcnic_config_switch_port(struct qlcnic_adapter *,
+ struct qlcnic_esw_func_cfg *);
+int qlcnic_get_eswitch_port_config(struct qlcnic_adapter *,
+ struct qlcnic_esw_func_cfg *);
int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8);
+int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8,
+ struct __qlcnic_esw_statistics *);
+int qlcnic_get_eswitch_stats(struct qlcnic_adapter *, const u8, u8,
+ struct __qlcnic_esw_statistics *);
+int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8);
extern int qlcnic_config_tso;
/*
@@ -1280,6 +1370,8 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = {
"3200 Series Quad Port 1Gb Intelligent Ethernet Adapter"},
{0x1077, 0x8020, 0x1077, 0x20f,
"3200 Series Single Port 10Gb Intelligent Ethernet Adapter"},
+ {0x1077, 0x8020, 0x103c, 0x3733,
+ "NC523SFP 10Gb 2-port Server Adapter"},
{0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"},
};
@@ -1298,7 +1390,6 @@ static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring)
extern const struct ethtool_ops qlcnic_ethtool_ops;
struct qlcnic_nic_template {
- int (*get_mac_addr) (struct qlcnic_adapter *, u8*);
int (*config_bridged_mode) (struct qlcnic_adapter *, u32);
int (*config_led) (struct qlcnic_adapter *, u32, u32);
int (*start_firmware) (struct qlcnic_adapter *);
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index cc5d861d9a12..1cdc05dade6b 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -556,32 +556,6 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
}
}
-/* Set MAC address of a NIC partition */
-int qlcnic_set_mac_address(struct qlcnic_adapter *adapter, u8* mac)
-{
- int err = 0;
- u32 arg1, arg2, arg3;
-
- arg1 = adapter->ahw.pci_func | BIT_9;
- arg2 = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24);
- arg3 = mac[4] | (mac[5] << 16);
-
- err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
- adapter->fw_hal_version,
- arg1,
- arg2,
- arg3,
- QLCNIC_CDRP_CMD_MAC_ADDRESS);
-
- if (err != QLCNIC_RCODE_SUCCESS) {
- dev_err(&adapter->pdev->dev,
- "Failed to set mac address%d\n", err);
- err = -EIO;
- }
-
- return err;
-}
/* Get MAC address of a NIC partition */
int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
@@ -742,15 +716,15 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter,
if (err == QLCNIC_RCODE_SUCCESS) {
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) {
- pci_info->id = le32_to_cpu(npar->id);
- pci_info->active = le32_to_cpu(npar->active);
- pci_info->type = le32_to_cpu(npar->type);
+ pci_info->id = le16_to_cpu(npar->id);
+ pci_info->active = le16_to_cpu(npar->active);
+ pci_info->type = le16_to_cpu(npar->type);
pci_info->default_port =
- le32_to_cpu(npar->default_port);
+ le16_to_cpu(npar->default_port);
pci_info->tx_min_bw =
- le32_to_cpu(npar->tx_min_bw);
+ le16_to_cpu(npar->tx_min_bw);
pci_info->tx_max_bw =
- le32_to_cpu(npar->tx_max_bw);
+ le16_to_cpu(npar->tx_max_bw);
memcpy(pci_info->mac, npar->mac, ETH_ALEN);
}
} else {
@@ -764,222 +738,319 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter,
return err;
}
-/* Reset a NIC partition */
-
-int qlcnic_reset_partition(struct qlcnic_adapter *adapter, u8 func_no)
+/* Configure eSwitch for port mirroring */
+int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
+ u8 enable_mirroring, u8 pci_func)
{
int err = -EIO;
+ u32 arg1;
- if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC ||
+ !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE))
return err;
+ arg1 = id | (enable_mirroring ? BIT_4 : 0);
+ arg1 |= pci_func << 8;
+
err = qlcnic_issue_cmd(adapter,
adapter->ahw.pci_func,
adapter->fw_hal_version,
- func_no,
+ arg1,
0,
0,
- QLCNIC_CDRP_CMD_RESET_NPAR);
+ QLCNIC_CDRP_CMD_SET_PORTMIRRORING);
if (err != QLCNIC_RCODE_SUCCESS) {
dev_err(&adapter->pdev->dev,
- "Failed to issue reset partition%d\n", err);
- err = -EIO;
+ "Failed to configure port mirroring%d on eswitch:%d\n",
+ pci_func, id);
+ } else {
+ dev_info(&adapter->pdev->dev,
+ "Configured eSwitch %d for port mirroring:%d\n",
+ id, pci_func);
}
return err;
}
-/* Get eSwitch Capabilities */
-int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port,
- struct qlcnic_eswitch *eswitch)
-{
- int err = -EIO;
- u32 arg1, arg2;
+int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
+ const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
- if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
- return err;
+ size_t stats_size = sizeof(struct __qlcnic_esw_statistics);
+ struct __qlcnic_esw_statistics *stats;
+ dma_addr_t stats_dma_t;
+ void *stats_addr;
+ u32 arg1;
+ int err;
- err = qlcnic_issue_cmd(adapter,
- adapter->ahw.pci_func,
- adapter->fw_hal_version,
- port,
- 0,
- 0,
- QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY);
+ if (esw_stats == NULL)
+ return -ENOMEM;
- if (err == QLCNIC_RCODE_SUCCESS) {
- arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
- arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
-
- eswitch->port = arg1 & 0xf;
- eswitch->active_vports = LSB(arg2);
- eswitch->max_ucast_filters = MSB(arg2);
- eswitch->max_active_vlans = LSB(MSW(arg2));
- if (arg1 & BIT_6)
- eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING;
- if (arg1 & BIT_7)
- eswitch->flags |= QLCNIC_SWITCH_PROMISC_MODE;
- if (arg1 & BIT_8)
- eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING;
- } else {
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC &&
+ func != adapter->ahw.pci_func) {
dev_err(&adapter->pdev->dev,
- "Failed to get eswitch capabilities%d\n", err);
+ "Not privilege to query stats for func=%d", func);
+ return -EIO;
}
- return err;
-}
-
-/* Get current status of eswitch */
-int qlcnic_get_eswitch_status(struct qlcnic_adapter *adapter, u8 port,
- struct qlcnic_eswitch *eswitch)
-{
- int err = -EIO;
- u32 arg1, arg2;
+ stats_addr = pci_alloc_consistent(adapter->pdev, stats_size,
+ &stats_dma_t);
+ if (!stats_addr) {
+ dev_err(&adapter->pdev->dev, "Unable to allocate memory\n");
+ return -ENOMEM;
+ }
+ memset(stats_addr, 0, stats_size);
- if (adapter->op_mode != QLCNIC_MGMT_FUNC)
- return err;
+ arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12;
+ arg1 |= rx_tx << 15 | stats_size << 16;
err = qlcnic_issue_cmd(adapter,
adapter->ahw.pci_func,
adapter->fw_hal_version,
- port,
- 0,
- 0,
- QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS);
-
- if (err == QLCNIC_RCODE_SUCCESS) {
- arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
- arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
-
- eswitch->port = arg1 & 0xf;
- eswitch->active_vports = LSB(arg2);
- eswitch->active_ucast_filters = MSB(arg2);
- eswitch->active_vlans = LSB(MSW(arg2));
- if (arg1 & BIT_6)
- eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING;
- if (arg1 & BIT_8)
- eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING;
-
- } else {
- dev_err(&adapter->pdev->dev,
- "Failed to get eswitch status%d\n", err);
+ arg1,
+ MSD(stats_dma_t),
+ LSD(stats_dma_t),
+ QLCNIC_CDRP_CMD_GET_ESWITCH_STATS);
+
+ if (!err) {
+ stats = (struct __qlcnic_esw_statistics *)stats_addr;
+ esw_stats->context_id = le16_to_cpu(stats->context_id);
+ esw_stats->version = le16_to_cpu(stats->version);
+ esw_stats->size = le16_to_cpu(stats->size);
+ esw_stats->multicast_frames =
+ le64_to_cpu(stats->multicast_frames);
+ esw_stats->broadcast_frames =
+ le64_to_cpu(stats->broadcast_frames);
+ esw_stats->unicast_frames = le64_to_cpu(stats->unicast_frames);
+ esw_stats->dropped_frames = le64_to_cpu(stats->dropped_frames);
+ esw_stats->local_frames = le64_to_cpu(stats->local_frames);
+ esw_stats->errors = le64_to_cpu(stats->errors);
+ esw_stats->numbytes = le64_to_cpu(stats->numbytes);
}
+ pci_free_consistent(adapter->pdev, stats_size, stats_addr,
+ stats_dma_t);
return err;
}
-/* Enable/Disable eSwitch */
-int qlcnic_toggle_eswitch(struct qlcnic_adapter *adapter, u8 id, u8 enable)
+int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
+ const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
+
+ struct __qlcnic_esw_statistics port_stats;
+ u8 i;
+ int ret = -EIO;
+
+ if (esw_stats == NULL)
+ return -ENOMEM;
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+ return -EIO;
+ if (adapter->npars == NULL)
+ return -EIO;
+
+ memset(esw_stats, 0, sizeof(u64));
+ esw_stats->unicast_frames = QLCNIC_ESW_STATS_NOT_AVAIL;
+ esw_stats->multicast_frames = QLCNIC_ESW_STATS_NOT_AVAIL;
+ esw_stats->broadcast_frames = QLCNIC_ESW_STATS_NOT_AVAIL;
+ esw_stats->dropped_frames = QLCNIC_ESW_STATS_NOT_AVAIL;
+ esw_stats->errors = QLCNIC_ESW_STATS_NOT_AVAIL;
+ esw_stats->local_frames = QLCNIC_ESW_STATS_NOT_AVAIL;
+ esw_stats->numbytes = QLCNIC_ESW_STATS_NOT_AVAIL;
+ esw_stats->context_id = eswitch;
+
+ for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
+ if (adapter->npars[i].phy_port != eswitch)
+ continue;
+
+ memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics));
+ if (qlcnic_get_port_stats(adapter, i, rx_tx, &port_stats))
+ continue;
+
+ esw_stats->size = port_stats.size;
+ esw_stats->version = port_stats.version;
+ QLCNIC_ADD_ESW_STATS(esw_stats->unicast_frames,
+ port_stats.unicast_frames);
+ QLCNIC_ADD_ESW_STATS(esw_stats->multicast_frames,
+ port_stats.multicast_frames);
+ QLCNIC_ADD_ESW_STATS(esw_stats->broadcast_frames,
+ port_stats.broadcast_frames);
+ QLCNIC_ADD_ESW_STATS(esw_stats->dropped_frames,
+ port_stats.dropped_frames);
+ QLCNIC_ADD_ESW_STATS(esw_stats->errors,
+ port_stats.errors);
+ QLCNIC_ADD_ESW_STATS(esw_stats->local_frames,
+ port_stats.local_frames);
+ QLCNIC_ADD_ESW_STATS(esw_stats->numbytes,
+ port_stats.numbytes);
+ ret = 0;
+ }
+ return ret;
+}
+
+int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw,
+ const u8 port, const u8 rx_tx)
{
- int err = -EIO;
- u32 arg1, arg2;
- struct qlcnic_eswitch *eswitch;
+
+ u32 arg1;
if (adapter->op_mode != QLCNIC_MGMT_FUNC)
- return err;
+ return -EIO;
- eswitch = &adapter->eswitch[id];
- if (!eswitch)
- return err;
+ if (func_esw == QLCNIC_STATS_PORT) {
+ if (port >= QLCNIC_MAX_PCI_FUNC)
+ goto err_ret;
+ } else if (func_esw == QLCNIC_STATS_ESWITCH) {
+ if (port >= QLCNIC_NIU_MAX_XG_PORTS)
+ goto err_ret;
+ } else {
+ goto err_ret;
+ }
- arg1 = eswitch->port | (enable ? BIT_4 : 0);
- arg2 = eswitch->active_vports | (eswitch->max_ucast_filters << 8) |
- (eswitch->max_active_vlans << 16);
- err = qlcnic_issue_cmd(adapter,
+ if (rx_tx > QLCNIC_QUERY_TX_COUNTER)
+ goto err_ret;
+
+ arg1 = port | QLCNIC_STATS_VERSION << 8 | func_esw << 12;
+ arg1 |= BIT_14 | rx_tx << 15;
+
+ return qlcnic_issue_cmd(adapter,
adapter->ahw.pci_func,
adapter->fw_hal_version,
arg1,
- arg2,
0,
- QLCNIC_CDRP_CMD_TOGGLE_ESWITCH);
-
- if (err != QLCNIC_RCODE_SUCCESS) {
- dev_err(&adapter->pdev->dev,
- "Failed to enable eswitch%d\n", eswitch->port);
- eswitch->flags &= ~QLCNIC_SWITCH_ENABLE;
- err = -EIO;
- } else {
- eswitch->flags |= QLCNIC_SWITCH_ENABLE;
- dev_info(&adapter->pdev->dev,
- "Enabled eSwitch for port %d\n", eswitch->port);
- }
+ 0,
+ QLCNIC_CDRP_CMD_GET_ESWITCH_STATS);
- return err;
+err_ret:
+ dev_err(&adapter->pdev->dev, "Invalid argument func_esw=%d port=%d"
+ "rx_ctx=%d\n", func_esw, port, rx_tx);
+ return -EIO;
}
-/* Configure eSwitch for port mirroring */
-int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
- u8 enable_mirroring, u8 pci_func)
+static int
+__qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
+ u32 *arg1, u32 *arg2)
{
int err = -EIO;
- u32 arg1;
-
- if (adapter->op_mode != QLCNIC_MGMT_FUNC ||
- !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE))
- return err;
-
- arg1 = id | (enable_mirroring ? BIT_4 : 0);
- arg1 |= pci_func << 8;
-
+ u8 pci_func;
+ pci_func = (*arg1 >> 8);
err = qlcnic_issue_cmd(adapter,
adapter->ahw.pci_func,
adapter->fw_hal_version,
- arg1,
+ *arg1,
0,
0,
- QLCNIC_CDRP_CMD_SET_PORTMIRRORING);
+ QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG);
- if (err != QLCNIC_RCODE_SUCCESS) {
- dev_err(&adapter->pdev->dev,
- "Failed to configure port mirroring%d on eswitch:%d\n",
- pci_func, id);
- } else {
+ if (err == QLCNIC_RCODE_SUCCESS) {
+ *arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
+ *arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
dev_info(&adapter->pdev->dev,
- "Configured eSwitch %d for port mirroring:%d\n",
- id, pci_func);
+ "eSwitch port config for pci func %d\n", pci_func);
+ } else {
+ dev_err(&adapter->pdev->dev,
+ "Failed to get eswitch port config for pci func %d\n",
+ pci_func);
}
-
return err;
}
-
-/* Configure eSwitch port */
-int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id,
- int vlan_tagging, u8 discard_tagged, u8 promsc_mode,
- u8 mac_learn, u8 pci_func, u16 vlan_id)
+/* Configure eSwitch port
+op_mode = 0 for setting default port behavior
+op_mode = 1 for setting vlan id
+op_mode = 2 for deleting vlan id
+op_type = 0 for vlan_id
+op_type = 1 for port vlan_id
+*/
+int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
+ struct qlcnic_esw_func_cfg *esw_cfg)
{
int err = -EIO;
- u32 arg1;
- struct qlcnic_eswitch *eswitch;
+ u32 arg1, arg2 = 0;
+ u8 pci_func;
if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return err;
+ pci_func = esw_cfg->pci_func;
+ arg1 = (adapter->npars[pci_func].phy_port & BIT_0);
+ arg1 |= (pci_func << 8);
- eswitch = &adapter->eswitch[id];
- if (!(eswitch->flags & QLCNIC_SWITCH_ENABLE))
+ if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
return err;
-
- arg1 = eswitch->port | (discard_tagged ? BIT_4 : 0);
- arg1 |= (promsc_mode ? BIT_6 : 0) | (mac_learn ? BIT_7 : 0);
- arg1 |= pci_func << 8;
- if (vlan_tagging)
- arg1 |= BIT_5 | (vlan_id << 16);
+ arg1 &= ~(0x0ff << 8);
+ arg1 |= (pci_func << 8);
+ arg1 &= ~(BIT_2 | BIT_3);
+ switch (esw_cfg->op_mode) {
+ case QLCNIC_PORT_DEFAULTS:
+ arg1 |= (BIT_4 | BIT_6 | BIT_7);
+ arg2 |= (BIT_0 | BIT_1);
+ if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
+ arg2 |= (BIT_2 | BIT_3);
+ if (!(esw_cfg->discard_tagged))
+ arg1 &= ~BIT_4;
+ if (!(esw_cfg->promisc_mode))
+ arg1 &= ~BIT_6;
+ if (!(esw_cfg->mac_override))
+ arg1 &= ~BIT_7;
+ if (!(esw_cfg->mac_anti_spoof))
+ arg2 &= ~BIT_0;
+ if (!(esw_cfg->offload_flags & BIT_0))
+ arg2 &= ~(BIT_1 | BIT_2 | BIT_3);
+ if (!(esw_cfg->offload_flags & BIT_1))
+ arg2 &= ~BIT_2;
+ if (!(esw_cfg->offload_flags & BIT_2))
+ arg2 &= ~BIT_3;
+ break;
+ case QLCNIC_ADD_VLAN:
+ arg1 |= (BIT_2 | BIT_5);
+ arg1 |= (esw_cfg->vlan_id << 16);
+ break;
+ case QLCNIC_DEL_VLAN:
+ arg1 |= (BIT_3 | BIT_5);
+ arg1 &= ~(0x0ffff << 16);
+ break;
+ default:
+ return err;
+ }
err = qlcnic_issue_cmd(adapter,
adapter->ahw.pci_func,
adapter->fw_hal_version,
arg1,
- 0,
+ arg2,
0,
QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH);
if (err != QLCNIC_RCODE_SUCCESS) {
dev_err(&adapter->pdev->dev,
- "Failed to configure eswitch port%d\n", eswitch->port);
+ "Failed to configure eswitch pci func %d\n", pci_func);
} else {
dev_info(&adapter->pdev->dev,
- "Configured eSwitch for port %d\n", eswitch->port);
+ "Configured eSwitch for pci func %d\n", pci_func);
}
return err;
}
+
+int
+qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
+ struct qlcnic_esw_func_cfg *esw_cfg)
+{
+ u32 arg1, arg2;
+ u8 phy_port;
+ if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+ phy_port = adapter->npars[esw_cfg->pci_func].phy_port;
+ else
+ phy_port = adapter->physical_port;
+ arg1 = phy_port;
+ arg1 |= (esw_cfg->pci_func << 8);
+ if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
+ return -EIO;
+
+ esw_cfg->discard_tagged = !!(arg1 & BIT_4);
+ esw_cfg->host_vlan_tag = !!(arg1 & BIT_5);
+ esw_cfg->promisc_mode = !!(arg1 & BIT_6);
+ esw_cfg->mac_override = !!(arg1 & BIT_7);
+ esw_cfg->vlan_id = LSW(arg1 >> 16);
+ esw_cfg->mac_anti_spoof = (arg2 & 0x1);
+ esw_cfg->offload_flags = ((arg2 >> 1) & 0x7);
+
+ return 0;
+}
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 9328d59e21e0..25e93a53fca0 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -78,7 +78,25 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
};
+static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
+ "rx unicast frames",
+ "rx multicast frames",
+ "rx broadcast frames",
+ "rx dropped frames",
+ "rx errors",
+ "rx local frames",
+ "rx numbytes",
+ "tx unicast frames",
+ "tx multicast frames",
+ "tx broadcast frames",
+ "tx dropped frames",
+ "tx errors",
+ "tx local frames",
+ "tx numbytes",
+};
+
#define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
+#define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats)
static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
"Register_Test_on_offline",
@@ -96,10 +114,10 @@ static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
static const u32 diag_registers[] = {
CRB_CMDPEG_STATE,
CRB_RCVPEG_STATE,
- CRB_XG_STATE_P3,
+ CRB_XG_STATE_P3P,
CRB_FW_CAPABILITIES_1,
ISR_INT_STATE_REG,
- QLCNIC_CRB_DEV_REF_COUNT,
+ QLCNIC_CRB_DRV_ACTIVE,
QLCNIC_CRB_DEV_STATE,
QLCNIC_CRB_DRV_STATE,
QLCNIC_CRB_DRV_SCRATCH,
@@ -115,9 +133,13 @@ static const u32 diag_registers[] = {
-1
};
+#define QLCNIC_MGMT_API_VERSION 2
+#define QLCNIC_DEV_INFO_SIZE 1
+#define QLCNIC_ETHTOOL_REGS_VER 2
static int qlcnic_get_regs_len(struct net_device *dev)
{
- return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN;
+ return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN +
+ QLCNIC_DEV_INFO_SIZE + 1;
}
static int qlcnic_get_eeprom_len(struct net_device *dev)
@@ -185,9 +207,9 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
goto skip;
}
- val = QLCRD32(adapter, P3_LINK_SPEED_REG(pcifn));
- ecmd->speed = P3_LINK_SPEED_MHZ *
- P3_LINK_SPEED_VAL(pcifn, val);
+ val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
+ ecmd->speed = P3P_LINK_SPEED_MHZ *
+ P3P_LINK_SPEED_VAL(pcifn, val);
ecmd->duplex = DUPLEX_FULL;
ecmd->autoneg = AUTONEG_DISABLE;
} else
@@ -198,42 +220,42 @@ skip:
ecmd->transceiver = XCVR_EXTERNAL;
switch (adapter->ahw.board_type) {
- case QLCNIC_BRDTYPE_P3_REF_QG:
- case QLCNIC_BRDTYPE_P3_4_GB:
- case QLCNIC_BRDTYPE_P3_4_GB_MM:
+ case QLCNIC_BRDTYPE_P3P_REF_QG:
+ case QLCNIC_BRDTYPE_P3P_4_GB:
+ case QLCNIC_BRDTYPE_P3P_4_GB_MM:
ecmd->supported |= SUPPORTED_Autoneg;
ecmd->advertising |= ADVERTISED_Autoneg;
- case QLCNIC_BRDTYPE_P3_10G_CX4:
- case QLCNIC_BRDTYPE_P3_10G_CX4_LP:
- case QLCNIC_BRDTYPE_P3_10000_BASE_T:
+ case QLCNIC_BRDTYPE_P3P_10G_CX4:
+ case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
+ case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
ecmd->supported |= SUPPORTED_TP;
ecmd->advertising |= ADVERTISED_TP;
ecmd->port = PORT_TP;
ecmd->autoneg = adapter->link_autoneg;
break;
- case QLCNIC_BRDTYPE_P3_IMEZ:
- case QLCNIC_BRDTYPE_P3_XG_LOM:
- case QLCNIC_BRDTYPE_P3_HMEZ:
+ case QLCNIC_BRDTYPE_P3P_IMEZ:
+ case QLCNIC_BRDTYPE_P3P_XG_LOM:
+ case QLCNIC_BRDTYPE_P3P_HMEZ:
ecmd->supported |= SUPPORTED_MII;
ecmd->advertising |= ADVERTISED_MII;
ecmd->port = PORT_MII;
ecmd->autoneg = AUTONEG_DISABLE;
break;
- case QLCNIC_BRDTYPE_P3_10G_SFP_PLUS:
- case QLCNIC_BRDTYPE_P3_10G_SFP_CT:
- case QLCNIC_BRDTYPE_P3_10G_SFP_QT:
+ case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
+ case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
+ case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
ecmd->advertising |= ADVERTISED_TP;
ecmd->supported |= SUPPORTED_TP;
check_sfp_module = netif_running(dev) &&
adapter->has_link_events;
- case QLCNIC_BRDTYPE_P3_10G_XFP:
+ case QLCNIC_BRDTYPE_P3P_10G_XFP:
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising |= ADVERTISED_FIBRE;
ecmd->port = PORT_FIBRE;
ecmd->autoneg = AUTONEG_DISABLE;
break;
- case QLCNIC_BRDTYPE_P3_10G_TP:
+ case QLCNIC_BRDTYPE_P3P_10G_TP:
if (adapter->ahw.port_type == QLCNIC_XGBE) {
ecmd->autoneg = AUTONEG_DISABLE;
ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
@@ -339,14 +361,17 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
struct qlcnic_host_sds_ring *sds_ring;
u32 *regs_buff = p;
- int ring, i = 0;
+ int ring, i = 0, j = 0;
memset(p, 0, qlcnic_get_regs_len(dev));
- regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
- (adapter->pdev)->device;
+ regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
+ (adapter->ahw.revision_id << 16) | (adapter->pdev)->device;
+
+ regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
+ regs_buff[1] = QLCNIC_MGMT_API_VERSION;
- for (i = 0; diag_registers[i] != -1; i++)
- regs_buff[i] = QLCRD32(adapter, diag_registers[i]);
+ for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
+ regs_buff[i] = QLCRD32(adapter, diag_registers[j]);
if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
return;
@@ -374,9 +399,9 @@ static u32 qlcnic_test_link(struct net_device *dev)
struct qlcnic_adapter *adapter = netdev_priv(dev);
u32 val;
- val = QLCRD32(adapter, CRB_XG_STATE_P3);
- val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
- return (val == XG_LINK_UP_P3) ? 0 : 1;
+ val = QLCRD32(adapter, CRB_XG_STATE_P3P);
+ val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val);
+ return (val == XG_LINK_UP_P3P) ? 0 : 1;
}
static int
@@ -618,10 +643,13 @@ static int qlcnic_reg_test(struct net_device *dev)
static int qlcnic_get_sset_count(struct net_device *dev, int sset)
{
+ struct qlcnic_adapter *adapter = netdev_priv(dev);
switch (sset) {
case ETH_SS_TEST:
return QLCNIC_TEST_LEN;
case ETH_SS_STATS:
+ if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
+ return QLCNIC_STATS_LEN + QLCNIC_DEVICE_STATS_LEN;
return QLCNIC_STATS_LEN;
default:
return -EOPNOTSUPP;
@@ -629,6 +657,8 @@ static int qlcnic_get_sset_count(struct net_device *dev, int sset)
}
#define QLC_ILB_PKT_SIZE 64
+#define QLC_NUM_ILB_PKT 16
+#define QLC_ILB_MAX_RCV_LOOP 10
static void qlcnic_create_loopback_buff(unsigned char *data)
{
@@ -650,24 +680,34 @@ static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter)
struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
struct sk_buff *skb;
- int i;
+ int i, loop, cnt = 0;
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < QLC_NUM_ILB_PKT; i++) {
skb = dev_alloc_skb(QLC_ILB_PKT_SIZE);
qlcnic_create_loopback_buff(skb->data);
skb_put(skb, QLC_ILB_PKT_SIZE);
adapter->diag_cnt = 0;
-
qlcnic_xmit_frame(skb, adapter->netdev);
- msleep(5);
-
- qlcnic_process_rcv_ring_diag(sds_ring);
+ loop = 0;
+ do {
+ msleep(1);
+ qlcnic_process_rcv_ring_diag(sds_ring);
+ } while (loop++ < QLC_ILB_MAX_RCV_LOOP &&
+ !adapter->diag_cnt);
dev_kfree_skb_any(skb);
+
if (!adapter->diag_cnt)
- return -1;
+ dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet"
+ " not recevied\n", i + 1);
+ else
+ cnt++;
+ }
+ if (cnt != i) {
+ dev_warn(&adapter->pdev->dev, "ILB Test failed\n");
+ return -1;
}
return 0;
}
@@ -687,6 +727,11 @@ static int qlcnic_loopback_test(struct net_device *netdev)
if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
return -EIO;
+ if (qlcnic_request_quiscent_mode(adapter)) {
+ clear_bit(__QLCNIC_RESETTING, &adapter->state);
+ return -EIO;
+ }
+
ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
if (ret)
goto clear_it;
@@ -703,6 +748,7 @@ done:
qlcnic_diag_free_res(netdev, max_sds_rings);
clear_it:
+ qlcnic_clear_quiscent_mode(adapter);
adapter->max_sds_rings = max_sds_rings;
clear_bit(__QLCNIC_RESETTING, &adapter->state);
return ret;
@@ -747,6 +793,14 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
{
memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
+ data[0] = qlcnic_reg_test(dev);
+ if (data[0])
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
+ data[1] = (u64) qlcnic_test_link(dev);
+ if (data[1])
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
data[2] = qlcnic_irq_test(dev);
if (data[2])
@@ -757,21 +811,13 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
eth_test->flags |= ETH_TEST_FL_FAILED;
}
-
- data[0] = qlcnic_reg_test(dev);
- if (data[0])
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- /* link test */
- data[1] = (u64) qlcnic_test_link(dev);
- if (data[1])
- eth_test->flags |= ETH_TEST_FL_FAILED;
}
static void
qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
{
- int index;
+ struct qlcnic_adapter *adapter = netdev_priv(dev);
+ int index, i;
switch (stringset) {
case ETH_SS_TEST:
@@ -784,16 +830,43 @@ qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
qlcnic_gstrings_stats[index].stat_string,
ETH_GSTRING_LEN);
}
- break;
+ if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
+ return;
+ for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) {
+ memcpy(data + index * ETH_GSTRING_LEN,
+ qlcnic_device_gstrings_stats[i],
+ ETH_GSTRING_LEN);
+ }
}
}
+#define QLCNIC_FILL_ESWITCH_STATS(VAL1) \
+ (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) ? 0 : VAL1)
+
+static void
+qlcnic_fill_device_stats(int *index, u64 *data,
+ struct __qlcnic_esw_statistics *stats)
+{
+ int ind = *index;
+
+ data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->unicast_frames);
+ data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->multicast_frames);
+ data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->broadcast_frames);
+ data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->dropped_frames);
+ data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->errors);
+ data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->local_frames);
+ data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->numbytes);
+
+ *index = ind;
+}
+
static void
qlcnic_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 * data)
{
struct qlcnic_adapter *adapter = netdev_priv(dev);
- int index;
+ struct qlcnic_esw_statistics port_stats;
+ int index, ret;
for (index = 0; index < QLCNIC_STATS_LEN; index++) {
char *p =
@@ -803,8 +876,40 @@ qlcnic_get_ethtool_stats(struct net_device *dev,
(qlcnic_gstrings_stats[index].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p:(*(u32 *)p);
}
+
+ if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
+ return;
+
+ memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
+ 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,
+ QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
+ if (ret)
+ return;
+
+ 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;
@@ -819,7 +924,23 @@ static u32 qlcnic_get_rx_csum(struct net_device *dev)
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);
+ }
adapter->rx_csum = !!data;
+ dev_info(&adapter->pdev->dev, "disabling LRO as rx_csum is off\n");
return 0;
}
@@ -1002,6 +1123,15 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data)
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;
@@ -1048,7 +1178,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
.get_pauseparam = qlcnic_get_pauseparam,
.set_pauseparam = qlcnic_set_pauseparam,
.get_tx_csum = qlcnic_get_tx_csum,
- .set_tx_csum = ethtool_op_set_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,
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h
index 15fc32070be3..4290b80cde1a 100644
--- a/drivers/net/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/qlcnic/qlcnic_hdr.h
@@ -556,18 +556,18 @@ enum {
#define XG_LINK_UP 0x10
#define XG_LINK_DOWN 0x20
-#define XG_LINK_UP_P3 0x01
-#define XG_LINK_DOWN_P3 0x02
-#define XG_LINK_STATE_P3_MASK 0xf
-#define XG_LINK_STATE_P3(pcifn, val) \
- (((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3_MASK)
-
-#define P3_LINK_SPEED_MHZ 100
-#define P3_LINK_SPEED_MASK 0xff
-#define P3_LINK_SPEED_REG(pcifn) \
+#define XG_LINK_UP_P3P 0x01
+#define XG_LINK_DOWN_P3P 0x02
+#define XG_LINK_STATE_P3P_MASK 0xf
+#define XG_LINK_STATE_P3P(pcifn, val) \
+ (((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3P_MASK)
+
+#define P3P_LINK_SPEED_MHZ 100
+#define P3P_LINK_SPEED_MASK 0xff
+#define P3P_LINK_SPEED_REG(pcifn) \
(CRB_PF_LINK_SPEED_1 + (((pcifn) / 4) * 4))
-#define P3_LINK_SPEED_VAL(pcifn, reg) \
- (((reg) >> (8 * ((pcifn) & 0x3))) & P3_LINK_SPEED_MASK)
+#define P3P_LINK_SPEED_VAL(pcifn, reg) \
+ (((reg) >> (8 * ((pcifn) & 0x3))) & P3P_LINK_SPEED_MASK)
#define QLCNIC_CAM_RAM_BASE (QLCNIC_CRB_CAM + 0x02000)
#define QLCNIC_CAM_RAM(reg) (QLCNIC_CAM_RAM_BASE + (reg))
@@ -592,7 +592,7 @@ enum {
#define CRB_CMDPEG_STATE (QLCNIC_REG(0x50))
#define CRB_RCVPEG_STATE (QLCNIC_REG(0x13c))
-#define CRB_XG_STATE_P3 (QLCNIC_REG(0x98))
+#define CRB_XG_STATE_P3P (QLCNIC_REG(0x98))
#define CRB_PF_LINK_SPEED_1 (QLCNIC_REG(0xe8))
#define CRB_PF_LINK_SPEED_2 (QLCNIC_REG(0xec))
@@ -698,7 +698,7 @@ enum {
#define QLCNIC_PEG_ALIVE_COUNTER (QLCNIC_CAM_RAM(0xb0))
#define QLCNIC_PEG_HALT_STATUS1 (QLCNIC_CAM_RAM(0xa8))
#define QLCNIC_PEG_HALT_STATUS2 (QLCNIC_CAM_RAM(0xac))
-#define QLCNIC_CRB_DEV_REF_COUNT (QLCNIC_CAM_RAM(0x138))
+#define QLCNIC_CRB_DRV_ACTIVE (QLCNIC_CAM_RAM(0x138))
#define QLCNIC_CRB_DEV_STATE (QLCNIC_CAM_RAM(0x140))
#define QLCNIC_CRB_DRV_STATE (QLCNIC_CAM_RAM(0x144))
@@ -718,8 +718,9 @@ enum {
#define QLCNIC_DEV_FAILED 0x6
#define QLCNIC_DEV_QUISCENT 0x7
-#define QLCNIC_DEV_NPAR_NOT_RDY 0
-#define QLCNIC_DEV_NPAR_RDY 1
+#define QLCNIC_DEV_NPAR_NON_OPER 0 /* NON Operational */
+#define QLCNIC_DEV_NPAR_OPER 1 /* NPAR Operational */
+#define QLCNIC_DEV_NPAR_OPER_TIMEO 30 /* Operational time out */
#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4)))
#define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4)))
@@ -744,6 +745,15 @@ enum {
#define FW_POLL_DELAY (1 * HZ)
#define FW_FAIL_THRESH 2
+#define QLCNIC_RESET_TIMEOUT_SECS 10
+#define QLCNIC_INIT_TIMEOUT_SECS 30
+#define QLCNIC_RCVPEG_CHECK_RETRY_COUNT 2000
+#define QLCNIC_RCVPEG_CHECK_DELAY 10
+#define QLCNIC_CMDPEG_CHECK_RETRY_COUNT 60
+#define QLCNIC_CMDPEG_CHECK_DELAY 500
+#define QLCNIC_HEARTBEAT_PERIOD_MSECS 200
+#define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT 45
+
#define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
#define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200)
@@ -770,6 +780,7 @@ struct qlcnic_legacy_intr_set {
#define QLCNIC_DRV_OP_MODE 0x1b2170
#define QLCNIC_MSIX_BASE 0x132110
#define QLCNIC_MAX_PCI_FUNC 8
+#define QLCNIC_MAX_VLAN_FILTERS 64
/* PCI function operational mode */
enum {
@@ -778,6 +789,12 @@ enum {
QLCNIC_NON_PRIV_FUNC = 2
};
+enum {
+ QLCNIC_PORT_DEFAULTS = 0,
+ QLCNIC_ADD_VLAN = 1,
+ QLCNIC_DEL_VLAN = 2
+};
+
#define QLC_DEV_DRV_DEFAULT 0x11111111
#define LSB(x) ((uint8_t)(x))
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index e08c8b0556a4..7a47a2a7ee27 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -297,8 +297,8 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
break;
if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) {
dev_err(&adapter->pdev->dev,
- "Failed to acquire sem=%d lock;reg_id=%d\n",
- sem, id_reg);
+ "Failed to acquire sem=%d lock; holdby=%d\n",
+ sem, id_reg ? QLCRD32(adapter, id_reg) : -1);
return -EIO;
}
msleep(1);
@@ -375,10 +375,11 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
static int
qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
- unsigned op)
+ __le16 vlan_id, unsigned op)
{
struct qlcnic_nic_req req;
struct qlcnic_mac_req *mac_req;
+ struct qlcnic_vlan_req *vlan_req;
u64 word;
memset(&req, 0, sizeof(struct qlcnic_nic_req));
@@ -391,6 +392,9 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
mac_req->op = op;
memcpy(mac_req->mac_addr, addr, 6);
+ vlan_req = (struct qlcnic_vlan_req *)&req.words[1];
+ vlan_req->vlan_id = vlan_id;
+
return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
}
@@ -415,7 +419,7 @@ static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr)
memcpy(cur->mac_addr, addr, ETH_ALEN);
if (qlcnic_sre_macaddr_change(adapter,
- cur->mac_addr, QLCNIC_MAC_ADD)) {
+ cur->mac_addr, 0, QLCNIC_MAC_ADD)) {
kfree(cur);
return -EIO;
}
@@ -438,7 +442,8 @@ void qlcnic_set_multi(struct net_device *netdev)
qlcnic_nic_add_mac(adapter, bcast_addr);
if (netdev->flags & IFF_PROMISC) {
- mode = VPORT_MISS_MODE_ACCEPT_ALL;
+ if (!(adapter->flags & QLCNIC_PROMISC_DISABLED))
+ mode = VPORT_MISS_MODE_ACCEPT_ALL;
goto send_fw_cmd;
}
@@ -485,12 +490,63 @@ void qlcnic_free_mac_list(struct qlcnic_adapter *adapter)
while (!list_empty(head)) {
cur = list_entry(head->next, struct qlcnic_mac_list_s, list);
qlcnic_sre_macaddr_change(adapter,
- cur->mac_addr, QLCNIC_MAC_DEL);
+ cur->mac_addr, 0, QLCNIC_MAC_DEL);
list_del(&cur->list);
kfree(cur);
}
}
+void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_filter *tmp_fil;
+ struct hlist_node *tmp_hnode, *n;
+ struct hlist_head *head;
+ int i;
+
+ for (i = 0; i < adapter->fhash.fmax; i++) {
+ head = &(adapter->fhash.fhead[i]);
+
+ hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode)
+ {
+ if (jiffies >
+ (QLCNIC_FILTER_AGE * HZ + tmp_fil->ftime)) {
+ qlcnic_sre_macaddr_change(adapter,
+ tmp_fil->faddr, tmp_fil->vlan_id,
+ tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL :
+ QLCNIC_MAC_DEL);
+ spin_lock_bh(&adapter->mac_learn_lock);
+ adapter->fhash.fnum--;
+ hlist_del(&tmp_fil->fnode);
+ spin_unlock_bh(&adapter->mac_learn_lock);
+ kfree(tmp_fil);
+ }
+ }
+ }
+}
+
+void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_filter *tmp_fil;
+ struct hlist_node *tmp_hnode, *n;
+ struct hlist_head *head;
+ int i;
+
+ for (i = 0; i < adapter->fhash.fmax; i++) {
+ head = &(adapter->fhash.fhead[i]);
+
+ hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) {
+ qlcnic_sre_macaddr_change(adapter, tmp_fil->faddr,
+ tmp_fil->vlan_id, tmp_fil->vlan_id ?
+ QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL);
+ spin_lock_bh(&adapter->mac_learn_lock);
+ adapter->fhash.fnum--;
+ hlist_del(&tmp_fil->fnode);
+ spin_unlock_bh(&adapter->mac_learn_lock);
+ kfree(tmp_fil);
+ }
+ }
+}
+
#define QLCNIC_CONFIG_INTR_COALESCE 3
/*
@@ -527,9 +583,6 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable)
u64 word;
int rv;
- if ((adapter->flags & QLCNIC_LRO_ENABLED) == enable)
- return 0;
-
memset(&req, 0, sizeof(struct qlcnic_nic_req));
req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
@@ -544,8 +597,6 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable)
dev_err(&adapter->netdev->dev,
"Could not send configure hw lro request\n");
- adapter->flags ^= QLCNIC_LRO_ENABLED;
-
return rv;
}
@@ -623,9 +674,10 @@ int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable)
return rv;
}
-int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd)
+int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd)
{
struct qlcnic_nic_req req;
+ struct qlcnic_ipaddr *ipa;
u64 word;
int rv;
@@ -636,7 +688,8 @@ int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd)
req.req_hdr = cpu_to_le64(word);
req.words[0] = cpu_to_le64(cmd);
- req.words[1] = cpu_to_le64(ip);
+ ipa = (struct qlcnic_ipaddr *)&req.words[1];
+ ipa->ipv4 = ip;
rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
if (rv != 0)
@@ -701,9 +754,9 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
int rc = 0;
- if (mtu > P3_MAX_MTU) {
- dev_err(&adapter->netdev->dev, "mtu > %d bytes unsupported\n",
- P3_MAX_MTU);
+ if (mtu < P3P_MIN_MTU || mtu > P3P_MAX_MTU) {
+ dev_err(&adapter->netdev->dev, "%d bytes < mtu < %d bytes"
+ " not supported\n", P3P_MAX_MTU, P3P_MIN_MTU);
return -EINVAL;
}
@@ -715,19 +768,6 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
return rc;
}
-int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac)
-{
- u32 crbaddr;
- int pci_func = adapter->ahw.pci_func;
-
- crbaddr = CRB_MAC_BLOCK_START +
- (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
-
- qlcnic_fetch_mac(adapter, crbaddr, crbaddr+4, pci_func & 1, mac);
-
- return 0;
-}
-
/*
* Changes the CRB window to the specified window.
*/
@@ -1121,31 +1161,31 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter)
adapter->ahw.board_type = board_type;
- if (board_type == QLCNIC_BRDTYPE_P3_4_GB_MM) {
+ if (board_type == QLCNIC_BRDTYPE_P3P_4_GB_MM) {
u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I);
if ((gpio & 0x8000) == 0)
- board_type = QLCNIC_BRDTYPE_P3_10G_TP;
+ board_type = QLCNIC_BRDTYPE_P3P_10G_TP;
}
switch (board_type) {
- case QLCNIC_BRDTYPE_P3_HMEZ:
- case QLCNIC_BRDTYPE_P3_XG_LOM:
- case QLCNIC_BRDTYPE_P3_10G_CX4:
- case QLCNIC_BRDTYPE_P3_10G_CX4_LP:
- case QLCNIC_BRDTYPE_P3_IMEZ:
- case QLCNIC_BRDTYPE_P3_10G_SFP_PLUS:
- case QLCNIC_BRDTYPE_P3_10G_SFP_CT:
- case QLCNIC_BRDTYPE_P3_10G_SFP_QT:
- case QLCNIC_BRDTYPE_P3_10G_XFP:
- case QLCNIC_BRDTYPE_P3_10000_BASE_T:
+ case QLCNIC_BRDTYPE_P3P_HMEZ:
+ case QLCNIC_BRDTYPE_P3P_XG_LOM:
+ case QLCNIC_BRDTYPE_P3P_10G_CX4:
+ case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
+ case QLCNIC_BRDTYPE_P3P_IMEZ:
+ case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
+ case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
+ 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;
break;
- case QLCNIC_BRDTYPE_P3_REF_QG:
- case QLCNIC_BRDTYPE_P3_4_GB:
- case QLCNIC_BRDTYPE_P3_4_GB_MM:
+ 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;
break;
- case QLCNIC_BRDTYPE_P3_10G_TP:
+ case QLCNIC_BRDTYPE_P3P_10G_TP:
adapter->ahw.port_type = (adapter->portnum < 2) ?
QLCNIC_XGBE : QLCNIC_GBE;
break;
@@ -1245,4 +1285,5 @@ void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter)
mode = VPORT_MISS_MODE_ACCEPT_MULTI;
qlcnic_nic_set_promisc(adapter, mode);
+ msleep(1000);
}
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 2c7cf0b64811..0d180c6e41fe 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -25,6 +25,7 @@
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
+#include <linux/if_vlan.h>
#include "qlcnic.h"
struct crb_addr_pair {
@@ -45,6 +46,9 @@ static void
qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
struct qlcnic_host_rds_ring *rds_ring);
+static int
+qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter);
+
static void crb_addr_transform_setup(void)
{
crb_addr_transform(XDMA);
@@ -136,8 +140,6 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter)
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
- spin_lock(&rds_ring->lock);
-
INIT_LIST_HEAD(&rds_ring->free_list);
rx_buf = rds_ring->rx_buf_arr;
@@ -146,8 +148,6 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter)
&rds_ring->free_list);
rx_buf++;
}
-
- spin_unlock(&rds_ring->lock);
}
}
@@ -259,14 +259,14 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
switch (ring) {
case RCV_RING_NORMAL:
rds_ring->num_desc = adapter->num_rxd;
- rds_ring->dma_size = QLCNIC_P3_RX_BUF_MAX_LEN;
+ rds_ring->dma_size = QLCNIC_P3P_RX_BUF_MAX_LEN;
rds_ring->skb_size = rds_ring->dma_size + NET_IP_ALIGN;
break;
case RCV_RING_JUMBO:
rds_ring->num_desc = adapter->num_jumbo_rxd;
rds_ring->dma_size =
- QLCNIC_P3_RX_JUMBO_BUF_MAX_LEN;
+ QLCNIC_P3P_RX_JUMBO_BUF_MAX_LEN;
if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
rds_ring->dma_size += QLCNIC_LRO_BUFFER_EXTRA;
@@ -439,11 +439,14 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
u32 off;
struct pci_dev *pdev = adapter->pdev;
- /* resetall */
+ QLCWR32(adapter, CRB_CMDPEG_STATE, 0);
+ QLCWR32(adapter, CRB_RCVPEG_STATE, 0);
+
qlcnic_rom_lock(adapter);
QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0xfeffffff);
qlcnic_rom_unlock(adapter);
+ /* Init HW CRB block */
if (qlcnic_rom_fast_read(adapter, 0, &n) != 0 || (n != 0xcafecafe) ||
qlcnic_rom_fast_read(adapter, 4, &n) != 0) {
dev_err(&pdev->dev, "ERROR Reading crb_init area: val:%x\n", n);
@@ -524,13 +527,10 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
}
kfree(buf);
- /* p2dn replyCount */
+ /* Initialize protocol process engine */
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0xec, 0x1e);
- /* disable_peg_cache 0 & 1*/
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0x4c, 8);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_I + 0x4c, 8);
-
- /* peg_clr_all */
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x8, 0);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0xc, 0);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x8, 0);
@@ -539,10 +539,88 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_2 + 0xc, 0);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x8, 0);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0xc, 0);
+ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x8, 0);
+ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0xc, 0);
+ msleep(1);
+ QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0);
+ QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0);
+ return 0;
+}
+
+static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter)
+{
+ u32 val;
+ int retries = QLCNIC_CMDPEG_CHECK_RETRY_COUNT;
+
+ do {
+ val = QLCRD32(adapter, CRB_CMDPEG_STATE);
+
+ switch (val) {
+ case PHAN_INITIALIZE_COMPLETE:
+ case PHAN_INITIALIZE_ACK:
+ return 0;
+ case PHAN_INITIALIZE_FAILED:
+ goto out_err;
+ default:
+ break;
+ }
+
+ msleep(QLCNIC_CMDPEG_CHECK_DELAY);
+
+ } while (--retries);
+
+ QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
+
+out_err:
+ dev_err(&adapter->pdev->dev, "Command Peg initialization not "
+ "complete, state: 0x%x.\n", val);
+ return -EIO;
+}
+
+static int
+qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter)
+{
+ u32 val;
+ int retries = QLCNIC_RCVPEG_CHECK_RETRY_COUNT;
+
+ do {
+ val = QLCRD32(adapter, CRB_RCVPEG_STATE);
+
+ if (val == PHAN_PEG_RCV_INITIALIZED)
+ return 0;
+
+ msleep(QLCNIC_RCVPEG_CHECK_DELAY);
+
+ } while (--retries);
+
+ if (!retries) {
+ dev_err(&adapter->pdev->dev, "Receive Peg initialization not "
+ "complete, state: 0x%x.\n", val);
+ return -EIO;
+ }
+
return 0;
}
int
+qlcnic_check_fw_status(struct qlcnic_adapter *adapter)
+{
+ int err;
+
+ err = qlcnic_cmd_peg_ready(adapter);
+ if (err)
+ return err;
+
+ err = qlcnic_receive_peg_ready(adapter);
+ if (err)
+ return err;
+
+ QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
+
+ return err;
+}
+
+int
qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) {
int timeo;
@@ -557,12 +635,12 @@ qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) {
}
adapter->physical_port = (val >> 2);
if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DEV_INIT_TIMEOUT, &timeo))
- timeo = 30;
+ timeo = QLCNIC_INIT_TIMEOUT_SECS;
adapter->dev_init_timeo = timeo;
if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DRV_RESET_TIMEOUT, &timeo))
- timeo = 10;
+ timeo = QLCNIC_RESET_TIMEOUT_SECS;
adapter->reset_ack_timeo = timeo;
@@ -906,54 +984,47 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter)
return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24);
}
-int
-qlcnic_need_fw_reset(struct qlcnic_adapter *adapter)
+static void qlcnic_rom_lock_recovery(struct qlcnic_adapter *adapter)
{
- u32 count, old_count;
- u32 val, version, major, minor, build;
- int i, timeout;
-
- if (adapter->need_fw_reset)
- return 1;
+ if (qlcnic_pcie_sem_lock(adapter, 2, QLCNIC_ROM_LOCK_ID))
+ dev_info(&adapter->pdev->dev, "Resetting rom_lock\n");
- /* last attempt had failed */
- if (QLCRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED)
- return 1;
+ qlcnic_pcie_sem_unlock(adapter, 2);
+}
- old_count = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
+static int
+qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter)
+{
+ u32 heartbeat, ret = -EIO;
+ int retries = QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT;
- for (i = 0; i < 10; i++) {
+ adapter->heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
- timeout = msleep_interruptible(200);
- if (timeout) {
- QLCWR32(adapter, CRB_CMDPEG_STATE,
- PHAN_INITIALIZE_FAILED);
- return -EINTR;
+ do {
+ msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS);
+ heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
+ if (heartbeat != adapter->heartbeat) {
+ ret = QLCNIC_RCODE_SUCCESS;
+ break;
}
+ } while (--retries);
- count = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
- if (count != old_count)
- break;
- }
+ return ret;
+}
- /* firmware is dead */
- if (count == old_count)
+int
+qlcnic_need_fw_reset(struct qlcnic_adapter *adapter)
+{
+ if (qlcnic_check_fw_hearbeat(adapter)) {
+ qlcnic_rom_lock_recovery(adapter);
return 1;
+ }
- /* check if we have got newer or different file firmware */
- if (adapter->fw) {
-
- val = qlcnic_get_fw_version(adapter);
-
- version = QLCNIC_DECODE_VERSION(val);
-
- major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
- minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
- build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
+ if (adapter->need_fw_reset)
+ return 1;
- if (version > QLCNIC_VERSION_CODE(major, minor, build))
- return 1;
- }
+ if (adapter->fw)
+ return 1;
return 0;
}
@@ -1089,18 +1160,6 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter)
return -EINVAL;
}
- /* check if flashed firmware is newer */
- if (qlcnic_rom_fast_read(adapter,
- QLCNIC_FW_VERSION_OFFSET, (int *)&val))
- return -EIO;
-
- val = QLCNIC_DECODE_VERSION(val);
- if (val > ver) {
- dev_info(&pdev->dev, "%s: firmware is older than flash\n",
- fw_name[fw_type]);
- return -EINVAL;
- }
-
QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC);
return 0;
}
@@ -1162,78 +1221,6 @@ qlcnic_release_firmware(struct qlcnic_adapter *adapter)
adapter->fw = NULL;
}
-static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter)
-{
- u32 val;
- int retries = 60;
-
- do {
- val = QLCRD32(adapter, CRB_CMDPEG_STATE);
-
- switch (val) {
- case PHAN_INITIALIZE_COMPLETE:
- case PHAN_INITIALIZE_ACK:
- return 0;
- case PHAN_INITIALIZE_FAILED:
- goto out_err;
- default:
- break;
- }
-
- msleep(500);
-
- } while (--retries);
-
- QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
-
-out_err:
- dev_err(&adapter->pdev->dev, "Command Peg initialization not "
- "complete, state: 0x%x.\n", val);
- return -EIO;
-}
-
-static int
-qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter)
-{
- u32 val;
- int retries = 2000;
-
- do {
- val = QLCRD32(adapter, CRB_RCVPEG_STATE);
-
- if (val == PHAN_PEG_RCV_INITIALIZED)
- return 0;
-
- msleep(10);
-
- } while (--retries);
-
- if (!retries) {
- dev_err(&adapter->pdev->dev, "Receive Peg initialization not "
- "complete, state: 0x%x.\n", val);
- return -EIO;
- }
-
- return 0;
-}
-
-int qlcnic_init_firmware(struct qlcnic_adapter *adapter)
-{
- int err;
-
- err = qlcnic_cmd_peg_ready(adapter);
- if (err)
- return err;
-
- err = qlcnic_receive_peg_ready(adapter);
- if (err)
- return err;
-
- QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
-
- return err;
-}
-
static void
qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
struct qlcnic_fw_msg *msg)
@@ -1351,11 +1338,12 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
skb = buffer->skb;
- if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) {
+ if (likely(adapter->rx_csum && (cksum == STATUS_CKSUM_OK ||
+ cksum == STATUS_CKSUM_LOOP))) {
adapter->stats.csummed++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
skb->dev = adapter->netdev;
@@ -1365,6 +1353,31 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
return skb;
}
+static int
+qlcnic_check_rx_tagging(struct qlcnic_adapter *adapter, struct sk_buff *skb,
+ u16 *vlan_tag)
+{
+ struct ethhdr *eth_hdr;
+
+ if (!__vlan_get_tag(skb, vlan_tag)) {
+ eth_hdr = (struct ethhdr *) skb->data;
+ memmove(skb->data + VLAN_HLEN, eth_hdr, ETH_ALEN * 2);
+ skb_pull(skb, VLAN_HLEN);
+ }
+ if (!adapter->pvid)
+ return 0;
+
+ if (*vlan_tag == adapter->pvid) {
+ /* Outer vlan tag. Packet should follow non-vlan path */
+ *vlan_tag = 0xffff;
+ return 0;
+ }
+ if (adapter->flags & QLCNIC_TAGGING_ENABLED)
+ return 0;
+
+ return -EINVAL;
+}
+
static struct qlcnic_rx_buffer *
qlcnic_process_rcv(struct qlcnic_adapter *adapter,
struct qlcnic_host_sds_ring *sds_ring,
@@ -1376,6 +1389,7 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter,
struct sk_buff *skb;
struct qlcnic_host_rds_ring *rds_ring;
int index, length, cksum, pkt_offset;
+ u16 vid = 0xffff;
if (unlikely(ring >= adapter->max_rds_rings))
return NULL;
@@ -1404,9 +1418,18 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter,
if (pkt_offset)
skb_pull(skb, pkt_offset);
+ if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) {
+ adapter->stats.rxdropped++;
+ dev_kfree_skb(skb);
+ return buffer;
+ }
+
skb->protocol = eth_type_trans(skb, netdev);
- napi_gro_receive(&sds_ring->napi, skb);
+ if ((vid != 0xffff) && adapter->vlgrp)
+ vlan_gro_receive(&sds_ring->napi, adapter->vlgrp, vid, skb);
+ else
+ napi_gro_receive(&sds_ring->napi, skb);
adapter->stats.rx_pkts++;
adapter->stats.rxbytes += length;
@@ -1435,6 +1458,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
int index;
u16 lro_length, length, data_offset;
u32 seq_number;
+ u16 vid = 0xffff;
if (unlikely(ring > adapter->max_rds_rings))
return NULL;
@@ -1466,6 +1490,13 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
skb_put(skb, lro_length + data_offset);
skb_pull(skb, l2_hdr_offset);
+
+ if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) {
+ adapter->stats.rxdropped++;
+ dev_kfree_skb(skb);
+ return buffer;
+ }
+
skb->protocol = eth_type_trans(skb, netdev);
iph = (struct iphdr *)skb->data;
@@ -1480,7 +1511,10 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
length = skb->len;
- netif_receive_skb(skb);
+ if ((vid != 0xffff) && adapter->vlgrp)
+ vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vid);
+ else
+ netif_receive_skb(skb);
adapter->stats.lro_pkts++;
adapter->stats.lrobytes += length;
@@ -1584,8 +1618,6 @@ qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
int producer, count = 0;
struct list_head *head;
- spin_lock(&rds_ring->lock);
-
producer = rds_ring->producer;
head = &rds_ring->free_list;
@@ -1615,7 +1647,6 @@ qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
writel((producer-1) & (rds_ring->num_desc-1),
rds_ring->crb_rcv_producer);
}
- spin_unlock(&rds_ring->lock);
}
static void
@@ -1662,6 +1693,18 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
spin_unlock(&rds_ring->lock);
}
+static void dump_skb(struct sk_buff *skb)
+{
+ int i;
+ unsigned char *data = skb->data;
+
+ for (i = 0; i < skb->len; i++) {
+ printk("%02x ", data[i]);
+ if ((i & 0x0f) == 8)
+ printk("\n");
+ }
+}
+
static struct qlcnic_rx_buffer *
qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
struct qlcnic_host_sds_ring *sds_ring,
@@ -1692,13 +1735,18 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
if (!skb)
return buffer;
- skb_put(skb, rds_ring->skb_size);
+ if (length > rds_ring->skb_size)
+ skb_put(skb, rds_ring->skb_size);
+ else
+ skb_put(skb, length);
if (pkt_offset)
skb_pull(skb, pkt_offset);
if (!qlcnic_check_loopback_buff(skb->data))
adapter->diag_cnt++;
+ else
+ dump_skb(skb);
dev_kfree_skb_any(skb);
adapter->stats.rx_pkts++;
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 66eea5972020..f047c7c48314 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -28,6 +28,7 @@
#include "qlcnic.h"
+#include <linux/swab.h>
#include <linux/dma-mapping.h>
#include <linux/if_vlan.h>
#include <net/ip.h>
@@ -45,10 +46,10 @@ char qlcnic_driver_name[] = "qlcnic";
static const char qlcnic_driver_string[] = "QLogic 1/10 GbE "
"Converged/Intelligent Ethernet Driver v" QLCNIC_LINUX_VERSIONID;
-static int port_mode = QLCNIC_PORT_MODE_AUTO_NEG;
-
-/* Default to restricted 1G auto-neg mode */
-static int wol_port_mode = 5;
+static struct workqueue_struct *qlcnic_wq;
+static int qlcnic_mac_learn;
+module_param(qlcnic_mac_learn, int, 0644);
+MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=disabled, 1=enabled)");
static int use_msi = 1;
module_param(use_msi, int, 0644);
@@ -94,7 +95,7 @@ static void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter);
static void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter);
static void qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding);
-static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter);
+static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8);
static int qlcnic_can_start_firmware(struct qlcnic_adapter *adapter);
static irqreturn_t qlcnic_tmp_intr(int irq, void *data);
@@ -103,13 +104,17 @@ static irqreturn_t qlcnic_msi_intr(int irq, void *data);
static irqreturn_t qlcnic_msix_intr(int irq, void *data);
static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev);
-static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long);
+static void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long);
static int qlcnic_start_firmware(struct qlcnic_adapter *);
+static void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter);
+static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter);
static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *);
static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32);
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 *);
/* PCI Device ID Table */
#define ENTRY(device) \
{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
@@ -164,7 +169,7 @@ qlcnic_alloc_sds_rings(struct qlcnic_recv_context *recv_ctx, int count)
recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL);
- return (recv_ctx->sds_rings == NULL);
+ return recv_ctx->sds_rings == NULL;
}
static void
@@ -255,40 +260,6 @@ static void qlcnic_clear_stats(struct qlcnic_adapter *adapter)
memset(&adapter->stats, 0, sizeof(adapter->stats));
}
-static void qlcnic_set_port_mode(struct qlcnic_adapter *adapter)
-{
- u32 val, data;
-
- val = adapter->ahw.board_type;
- if ((val == QLCNIC_BRDTYPE_P3_HMEZ) ||
- (val == QLCNIC_BRDTYPE_P3_XG_LOM)) {
- if (port_mode == QLCNIC_PORT_MODE_802_3_AP) {
- data = QLCNIC_PORT_MODE_802_3_AP;
- QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data);
- } else if (port_mode == QLCNIC_PORT_MODE_XG) {
- data = QLCNIC_PORT_MODE_XG;
- QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data);
- } else if (port_mode == QLCNIC_PORT_MODE_AUTO_NEG_1G) {
- data = QLCNIC_PORT_MODE_AUTO_NEG_1G;
- QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data);
- } else if (port_mode == QLCNIC_PORT_MODE_AUTO_NEG_XG) {
- data = QLCNIC_PORT_MODE_AUTO_NEG_XG;
- QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data);
- } else {
- data = QLCNIC_PORT_MODE_AUTO_NEG;
- QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data);
- }
-
- if ((wol_port_mode != QLCNIC_PORT_MODE_802_3_AP) &&
- (wol_port_mode != QLCNIC_PORT_MODE_XG) &&
- (wol_port_mode != QLCNIC_PORT_MODE_AUTO_NEG_1G) &&
- (wol_port_mode != QLCNIC_PORT_MODE_AUTO_NEG_XG)) {
- wol_port_mode = QLCNIC_PORT_MODE_AUTO_NEG;
- }
- QLCWR32(adapter, QLCNIC_WOL_PORT_MODE, wol_port_mode);
- }
-}
-
static void qlcnic_set_msix_bit(struct pci_dev *pdev, int enable)
{
u32 control;
@@ -320,7 +291,7 @@ qlcnic_read_mac_addr(struct qlcnic_adapter *adapter)
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
- if (adapter->nic_ops->get_mac_addr(adapter, mac_addr) != 0)
+ if (qlcnic_get_mac_address(adapter, mac_addr) != 0)
return -EIO;
memcpy(netdev->dev_addr, mac_addr, ETH_ALEN);
@@ -341,6 +312,9 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct sockaddr *addr = p;
+ if ((adapter->flags & QLCNIC_MAC_OVERRIDE_DISABLED))
+ return -EOPNOTSUPP;
+
if (!is_valid_ether_addr(addr->sa_data))
return -EINVAL;
@@ -360,6 +334,13 @@ 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,
@@ -370,20 +351,19 @@ static const struct net_device_ops qlcnic_netdev_ops = {
.ndo_set_mac_address = qlcnic_set_mac,
.ndo_change_mtu = qlcnic_change_mtu,
.ndo_tx_timeout = qlcnic_tx_timeout,
+ .ndo_vlan_rx_register = qlcnic_vlan_rx_register,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = qlcnic_poll_controller,
#endif
};
static struct qlcnic_nic_template qlcnic_ops = {
- .get_mac_addr = qlcnic_get_mac_address,
.config_bridged_mode = qlcnic_config_bridged_mode,
.config_led = qlcnic_config_led,
.start_firmware = qlcnic_start_firmware
};
static struct qlcnic_nic_template qlcnic_vf_ops = {
- .get_mac_addr = qlcnic_get_mac_address,
.config_bridged_mode = qlcnicvf_config_bridged_mode,
.config_led = qlcnicvf_config_led,
.start_firmware = qlcnicvf_start_firmware
@@ -474,7 +454,7 @@ static int
qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
{
struct qlcnic_pci_info *pci_info;
- int i, ret = 0, err;
+ int i, ret = 0;
u8 pfn;
pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
@@ -484,14 +464,14 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) *
QLCNIC_MAX_PCI_FUNC, GFP_KERNEL);
if (!adapter->npars) {
- err = -ENOMEM;
+ ret = -ENOMEM;
goto err_pci_info;
}
adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) *
QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL);
if (!adapter->eswitch) {
- err = -ENOMEM;
+ ret = -ENOMEM;
goto err_npars;
}
@@ -503,10 +483,9 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
pfn = pci_info[i].id;
if (pfn > QLCNIC_MAX_PCI_FUNC)
return QL_STATUS_INVALID_PARAM;
- adapter->npars[pfn].active = pci_info[i].active;
- adapter->npars[pfn].type = pci_info[i].type;
- adapter->npars[pfn].phy_port = pci_info[i].default_port;
- adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN;
+ 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;
adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw;
adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;
}
@@ -539,12 +518,10 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
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_DEV_REF_COUNT);
+ ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
ret = qlcnic_api_lock(adapter);
if (ret)
goto err_lock;
- if (QLC_DEV_CLR_REF_CNT(ref_count, adapter->ahw.pci_func))
- goto err_npar;
if (qlcnic_config_npars) {
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
@@ -562,18 +539,16 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
adapter->ahw.pci_func));
}
writel(data, priv_op);
-err_npar:
qlcnic_api_unlock(adapter);
err_lock:
return ret;
}
-static u32
-qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
+static void
+qlcnic_check_vf(struct qlcnic_adapter *adapter)
{
void __iomem *msix_base_addr;
void __iomem *priv_op;
- struct qlcnic_info nic_info;
u32 func;
u32 msix_base;
u32 op_mode, priv_level;
@@ -588,20 +563,6 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE;
adapter->ahw.pci_func = func;
- if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) {
- adapter->capabilities = nic_info.capabilities;
-
- if (adapter->capabilities & BIT_6)
- adapter->flags |= QLCNIC_ESWITCH_ENABLED;
- else
- adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
- }
-
- if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
- adapter->nic_ops = &qlcnic_ops;
- return adapter->fw_hal_version;
- }
-
/* Determine function privilege level */
priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
op_mode = readl(priv_op);
@@ -610,37 +571,14 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
else
priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
- switch (priv_level) {
- case QLCNIC_MGMT_FUNC:
- adapter->op_mode = QLCNIC_MGMT_FUNC;
- adapter->nic_ops = &qlcnic_ops;
- qlcnic_init_pci_info(adapter);
- /* Set privilege level for other functions */
- qlcnic_set_function_modes(adapter);
- dev_info(&adapter->pdev->dev,
- "HAL Version: %d, Management function\n",
- adapter->fw_hal_version);
- break;
- case QLCNIC_PRIV_FUNC:
- adapter->op_mode = QLCNIC_PRIV_FUNC;
- dev_info(&adapter->pdev->dev,
- "HAL Version: %d, Privileged function\n",
- adapter->fw_hal_version);
- adapter->nic_ops = &qlcnic_ops;
- break;
- case QLCNIC_NON_PRIV_FUNC:
+ if (priv_level == QLCNIC_NON_PRIV_FUNC) {
adapter->op_mode = QLCNIC_NON_PRIV_FUNC;
dev_info(&adapter->pdev->dev,
"HAL Version: %d Non Privileged function\n",
adapter->fw_hal_version);
adapter->nic_ops = &qlcnic_vf_ops;
- break;
- default:
- dev_info(&adapter->pdev->dev, "Unknown function mode: %d\n",
- priv_level);
- return 0;
- }
- return adapter->fw_hal_version;
+ } else
+ adapter->nic_ops = &qlcnic_ops;
}
static int
@@ -673,10 +611,7 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter)
adapter->ahw.pci_base0 = mem_ptr0;
adapter->ahw.pci_len0 = pci_len0;
- if (!qlcnic_get_driver_mode(adapter)) {
- iounmap(adapter->ahw.pci_base0);
- return -EIO;
- }
+ 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)));
@@ -711,25 +646,7 @@ static void
qlcnic_check_options(struct qlcnic_adapter *adapter)
{
u32 fw_major, fw_minor, fw_build;
- char brd_name[QLCNIC_MAX_BOARD_NAME_LEN];
- char serial_num[32];
- int i, offset, val;
- int *ptr32;
struct pci_dev *pdev = adapter->pdev;
- struct qlcnic_info nic_info;
- adapter->driver_mismatch = 0;
-
- ptr32 = (int *)&serial_num;
- offset = QLCNIC_FW_SERIAL_NUM_OFFSET;
- for (i = 0; i < 8; i++) {
- if (qlcnic_rom_fast_read(adapter, offset, &val) == -1) {
- dev_err(&pdev->dev, "error reading board info\n");
- adapter->driver_mismatch = 1;
- return;
- }
- ptr32[i] = cpu_to_le32(val);
- offset += sizeof(u32);
- }
fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
@@ -737,19 +654,9 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
- if (adapter->portnum == 0) {
- get_brd_name(adapter, brd_name);
-
- pr_info("%s: %s Board Chip rev 0x%x\n",
- module_name(THIS_MODULE),
- brd_name, adapter->ahw.revision_id);
- }
-
dev_info(&pdev->dev, "firmware v%d.%d.%d\n",
fw_major, fw_minor, fw_build);
- adapter->flags &= ~QLCNIC_LRO_ENABLED;
-
if (adapter->ahw.port_type == QLCNIC_XGBE) {
adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G;
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
@@ -758,136 +665,364 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
}
- if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) {
- adapter->physical_port = nic_info.phys_port;
- adapter->switch_mode = nic_info.switch_mode;
- adapter->max_tx_ques = nic_info.max_tx_ques;
- adapter->max_rx_ques = nic_info.max_rx_ques;
- adapter->capabilities = nic_info.capabilities;
- adapter->max_mac_filters = nic_info.max_mac_filters;
- adapter->max_mtu = nic_info.max_mtu;
- }
-
adapter->msix_supported = !!use_msi_x;
adapter->rss_supported = !!use_msi_x;
adapter->num_txd = MAX_CMD_DESCRIPTORS;
- adapter->max_rds_rings = 2;
+ adapter->max_rds_rings = MAX_RDS_RINGS;
+}
+
+static int
+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);
+ if (err)
+ return err;
+
+ adapter->physical_port = (u8)nic_info.phys_port;
+ adapter->switch_mode = nic_info.switch_mode;
+ adapter->max_tx_ques = nic_info.max_tx_ques;
+ adapter->max_rx_ques = nic_info.max_rx_ques;
+ adapter->capabilities = nic_info.capabilities;
+ adapter->max_mac_filters = nic_info.max_mac_filters;
+ adapter->max_mtu = nic_info.max_mtu;
+
+ if (adapter->capabilities & BIT_6)
+ adapter->flags |= QLCNIC_ESWITCH_ENABLED;
+ else
+ adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
+
+ return err;
+}
+
+static void
+qlcnic_set_vlan_config(struct qlcnic_adapter *adapter,
+ struct qlcnic_esw_func_cfg *esw_cfg)
+{
+ if (esw_cfg->discard_tagged)
+ adapter->flags &= ~QLCNIC_TAGGING_ENABLED;
+ else
+ adapter->flags |= QLCNIC_TAGGING_ENABLED;
+
+ if (esw_cfg->vlan_id)
+ adapter->pvid = esw_cfg->vlan_id;
+ else
+ adapter->pvid = 0;
+}
+
+static void
+qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter,
+ struct qlcnic_esw_func_cfg *esw_cfg)
+{
+ adapter->flags &= ~(QLCNIC_MACSPOOF | QLCNIC_MAC_OVERRIDE_DISABLED |
+ QLCNIC_PROMISC_DISABLED);
+
+ if (esw_cfg->mac_anti_spoof)
+ adapter->flags |= QLCNIC_MACSPOOF;
+
+ if (!esw_cfg->mac_override)
+ adapter->flags |= QLCNIC_MAC_OVERRIDE_DISABLED;
+
+ if (!esw_cfg->promisc_mode)
+ adapter->flags |= QLCNIC_PROMISC_DISABLED;
+
+ qlcnic_set_netdev_features(adapter, esw_cfg);
+}
+
+static int
+qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_esw_func_cfg esw_cfg;
+
+ if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
+ return 0;
+
+ 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);
+ qlcnic_set_eswitch_port_features(adapter, &esw_cfg);
+
+ return 0;
+}
+
+static void
+qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
+ struct qlcnic_esw_func_cfg *esw_cfg)
+{
+ struct net_device *netdev = adapter->netdev;
+ unsigned long features, vlan_features;
+
+ features = (NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM | NETIF_F_GRO);
+ vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM);
+
+ 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)
+ 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);
+}
+
+static int
+qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
+{
+ void __iomem *priv_op;
+ u32 op_mode, priv_level;
+ int err = 0;
+
+ err = qlcnic_initialize_nic(adapter);
+ if (err)
+ return err;
+
+ if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED)
+ return 0;
+
+ 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);
+
+ 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);
+
+ if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
+ if (priv_level == QLCNIC_MGMT_FUNC) {
+ adapter->op_mode = QLCNIC_MGMT_FUNC;
+ err = qlcnic_init_pci_info(adapter);
+ if (err)
+ return err;
+ /* Set privilege level for other functions */
+ qlcnic_set_function_modes(adapter);
+ dev_info(&adapter->pdev->dev,
+ "HAL Version: %d, Management function\n",
+ adapter->fw_hal_version);
+ } else if (priv_level == QLCNIC_PRIV_FUNC) {
+ adapter->op_mode = QLCNIC_PRIV_FUNC;
+ dev_info(&adapter->pdev->dev,
+ "HAL Version: %d, Privileged function\n",
+ adapter->fw_hal_version);
+ }
+ }
+
+ adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
+
+ return err;
+}
+
+static int
+qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_esw_func_cfg esw_cfg;
+ struct qlcnic_npar_info *npar;
+ u8 i;
+
+ if (adapter->need_fw_reset)
+ return 0;
+
+ for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
+ if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
+ continue;
+ memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg));
+ esw_cfg.pci_func = i;
+ esw_cfg.offload_flags = BIT_0;
+ esw_cfg.mac_override = BIT_0;
+ esw_cfg.promisc_mode = BIT_0;
+ if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
+ esw_cfg.offload_flags |= (BIT_1 | BIT_2);
+ if (qlcnic_config_switch_port(adapter, &esw_cfg))
+ return -EIO;
+ npar = &adapter->npars[i];
+ npar->pvid = esw_cfg.vlan_id;
+ npar->mac_override = esw_cfg.mac_override;
+ npar->mac_anti_spoof = esw_cfg.mac_anti_spoof;
+ npar->discard_tagged = esw_cfg.discard_tagged;
+ npar->promisc_mode = esw_cfg.promisc_mode;
+ npar->offload_flags = esw_cfg.offload_flags;
+ }
+
+ return 0;
+}
+
+static int
+qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter,
+ struct qlcnic_npar_info *npar, int pci_func)
+{
+ struct qlcnic_esw_func_cfg esw_cfg;
+ esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS;
+ esw_cfg.pci_func = pci_func;
+ esw_cfg.vlan_id = npar->pvid;
+ esw_cfg.mac_override = npar->mac_override;
+ esw_cfg.discard_tagged = npar->discard_tagged;
+ esw_cfg.mac_anti_spoof = npar->mac_anti_spoof;
+ esw_cfg.offload_flags = npar->offload_flags;
+ esw_cfg.promisc_mode = npar->promisc_mode;
+ if (qlcnic_config_switch_port(adapter, &esw_cfg))
+ return -EIO;
+
+ esw_cfg.op_mode = QLCNIC_ADD_VLAN;
+ if (qlcnic_config_switch_port(adapter, &esw_cfg))
+ return -EIO;
+
+ return 0;
}
static int
qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
{
- int i, err = 0;
+ int i, err;
struct qlcnic_npar_info *npar;
struct qlcnic_info nic_info;
- if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
- !adapter->need_fw_reset)
+ if (!adapter->need_fw_reset)
return 0;
- if (adapter->op_mode == QLCNIC_MGMT_FUNC) {
- /* Set the NPAR config data after FW reset */
- for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
- npar = &adapter->npars[i];
- if (npar->type != QLCNIC_TYPE_NIC)
- continue;
- err = qlcnic_get_nic_info(adapter, &nic_info, i);
- if (err)
- goto err_out;
- nic_info.min_tx_bw = npar->min_bw;
- nic_info.max_tx_bw = npar->max_bw;
- err = qlcnic_set_nic_info(adapter, &nic_info);
+ /* Set the NPAR config data after FW reset */
+ for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
+ npar = &adapter->npars[i];
+ if (npar->type != QLCNIC_TYPE_NIC)
+ continue;
+ err = qlcnic_get_nic_info(adapter, &nic_info, i);
+ if (err)
+ return err;
+ nic_info.min_tx_bw = npar->min_bw;
+ nic_info.max_tx_bw = npar->max_bw;
+ err = qlcnic_set_nic_info(adapter, &nic_info);
+ if (err)
+ return err;
+
+ if (npar->enable_pm) {
+ err = qlcnic_config_port_mirroring(adapter,
+ npar->dest_npar, 1, i);
if (err)
- goto err_out;
+ return err;
+ }
+ err = qlcnic_reset_eswitch_config(adapter, npar, i);
+ if (err)
+ return err;
+ }
+ return 0;
+}
- if (npar->enable_pm) {
- err = qlcnic_config_port_mirroring(adapter,
- npar->dest_npar, 1, i);
- if (err)
- goto err_out;
+static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter)
+{
+ u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO;
+ u32 npar_state;
- }
- npar->mac_learning = DEFAULT_MAC_LEARN;
- npar->host_vlan_tag = 0;
- npar->promisc_mode = 0;
- npar->discard_tagged = 0;
- npar->vlan_id = 0;
- }
+ if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+ return 0;
+
+ npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+ while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) {
+ msleep(1000);
+ npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
}
-err_out:
+ if (!npar_opt_timeo) {
+ dev_err(&adapter->pdev->dev,
+ "Waiting for NPAR state to opertional timeout\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int
+qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter)
+{
+ int err;
+
+ if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
+ adapter->op_mode != QLCNIC_MGMT_FUNC)
+ return 0;
+
+ err = qlcnic_set_default_offload_settings(adapter);
+ if (err)
+ return err;
+
+ err = qlcnic_reset_npar_config(adapter);
+ if (err)
+ return err;
+
+ qlcnic_dev_set_npar_ready(adapter);
+
return err;
}
static int
qlcnic_start_firmware(struct qlcnic_adapter *adapter)
{
- int val, err, first_boot;
+ int err;
err = qlcnic_can_start_firmware(adapter);
if (err < 0)
return err;
else if (!err)
- goto wait_init;
-
- first_boot = QLCRD32(adapter, QLCNIC_CAM_RAM(0x1fc));
- if (first_boot == 0x55555555)
- /* This is the first boot after power up */
- QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC);
+ goto check_fw_status;
if (load_fw_file)
qlcnic_request_firmware(adapter);
else {
- if (qlcnic_check_flash_fw_ver(adapter))
+ err = qlcnic_check_flash_fw_ver(adapter);
+ if (err)
goto err_out;
adapter->fw_type = QLCNIC_FLASH_ROMIMAGE;
}
err = qlcnic_need_fw_reset(adapter);
- if (err < 0)
- goto err_out;
if (err == 0)
- goto wait_init;
+ goto check_fw_status;
- if (first_boot != 0x55555555) {
- QLCWR32(adapter, CRB_CMDPEG_STATE, 0);
- QLCWR32(adapter, CRB_RCVPEG_STATE, 0);
- qlcnic_pinit_from_rom(adapter);
- msleep(1);
- }
-
- QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0);
- QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0);
-
- qlcnic_set_port_mode(adapter);
+ err = qlcnic_pinit_from_rom(adapter);
+ if (err)
+ goto err_out;
err = qlcnic_load_firmware(adapter);
if (err)
goto err_out;
qlcnic_release_firmware(adapter);
+ QLCWR32(adapter, CRB_DRIVER_VERSION, QLCNIC_DRIVER_VERSION);
- val = (_QLCNIC_LINUX_MAJOR << 16)
- | ((_QLCNIC_LINUX_MINOR << 8))
- | (_QLCNIC_LINUX_SUBVERSION);
- QLCWR32(adapter, CRB_DRIVER_VERSION, val);
-
-wait_init:
- /* Handshake with the card before we register the devices. */
- err = qlcnic_init_firmware(adapter);
+check_fw_status:
+ err = qlcnic_check_fw_status(adapter);
if (err)
goto err_out;
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
qlcnic_idc_debug_info(adapter, 1);
- qlcnic_check_options(adapter);
- if (qlcnic_reset_npar_config(adapter))
+ err = qlcnic_check_eswitch_mode(adapter);
+ if (err) {
+ dev_err(&adapter->pdev->dev,
+ "Memory allocation failed for eswitch\n");
+ goto err_out;
+ }
+ err = qlcnic_set_mgmt_operations(adapter);
+ if (err)
goto err_out;
- qlcnic_dev_set_npar_ready(adapter);
+ qlcnic_check_options(adapter);
adapter->need_fw_reset = 0;
qlcnic_release_firmware(adapter);
@@ -896,6 +1031,7 @@ wait_init:
err_out:
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED);
dev_err(&adapter->pdev->dev, "Device state set to failed\n");
+
qlcnic_release_firmware(adapter);
return err;
}
@@ -979,6 +1115,8 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
return 0;
+ if (qlcnic_set_eswitch_port_config(adapter))
+ return -EIO;
if (qlcnic_fw_create_ctx(adapter))
return -EIO;
@@ -998,7 +1136,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
qlcnic_config_intr_coalesce(adapter);
- if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+ if (netdev->features & NETIF_F_LRO)
qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED);
qlcnic_napi_enable(adapter);
@@ -1041,6 +1179,9 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
qlcnic_free_mac_list(adapter);
+ if (adapter->fhash.fnum)
+ qlcnic_delete_lb_filters(adapter);
+
qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE);
qlcnic_napi_disable(adapter);
@@ -1277,7 +1418,7 @@ 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_IPV6_CSUM | NETIF_F_GRO | NETIF_F_HW_VLAN_RX);
netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM);
@@ -1296,12 +1437,8 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
netdev->features |= NETIF_F_LRO;
-
netdev->irq = adapter->msix_entries[0].vector;
- if (qlcnic_read_mac_addr(adapter))
- dev_warn(&pdev->dev, "failed to read mac addr\n");
-
netif_carrier_off(netdev);
netif_stop_queue(netdev);
@@ -1338,6 +1475,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int err;
uint8_t revision_id;
uint8_t pci_using_dac;
+ char brd_name[QLCNIC_MAX_BOARD_NAME_LEN];
err = pci_enable_device(pdev);
if (err)
@@ -1395,10 +1533,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_iounmap;
}
- if (qlcnic_read_mac_addr(adapter))
- dev_warn(&pdev->dev, "failed to read mac addr\n");
-
- if (qlcnic_setup_idc_param(adapter))
+ err = qlcnic_setup_idc_param(adapter);
+ if (err)
goto err_out_iounmap;
err = adapter->nic_ops->start_firmware(adapter);
@@ -1407,6 +1543,17 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_decr_ref;
}
+ if (qlcnic_read_mac_addr(adapter))
+ dev_warn(&pdev->dev, "failed to read mac addr\n");
+
+ if (adapter->portnum == 0) {
+ get_brd_name(adapter, brd_name);
+
+ pr_info("%s: %s Board Chip rev 0x%x\n",
+ module_name(THIS_MODULE),
+ brd_name, adapter->ahw.revision_id);
+ }
+
qlcnic_clear_stats(adapter);
qlcnic_setup_intr(adapter);
@@ -1430,6 +1577,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
+ qlcnic_alloc_lb_filters_mem(adapter);
qlcnic_create_diag_entries(adapter);
return 0;
@@ -1438,7 +1586,7 @@ err_out_disable_msi:
qlcnic_teardown_intr(adapter);
err_out_decr_ref:
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 0);
err_out_iounmap:
qlcnic_cleanup_pci_map(adapter);
@@ -1477,10 +1625,12 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev)
if (adapter->eswitch != NULL)
kfree(adapter->eswitch);
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 0);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
+ qlcnic_free_lb_filters_mem(adapter);
+
qlcnic_teardown_intr(adapter);
qlcnic_remove_diag_entries(adapter);
@@ -1509,7 +1659,7 @@ static int __qlcnic_shutdown(struct pci_dev *pdev)
if (netif_running(netdev))
qlcnic_down(adapter, netdev);
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 0);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
@@ -1573,7 +1723,7 @@ qlcnic_resume(struct pci_dev *pdev)
if (err)
goto done;
- qlcnic_config_indev_addr(netdev, NETDEV_UP);
+ qlcnic_restore_indev_addr(netdev, NETDEV_UP);
}
done:
netif_device_attach(netdev);
@@ -1587,9 +1737,6 @@ static int qlcnic_open(struct net_device *netdev)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
int err;
- if (adapter->driver_mismatch)
- return -EIO;
-
err = qlcnic_attach(adapter);
if (err)
return err;
@@ -1619,6 +1766,121 @@ static int qlcnic_close(struct net_device *netdev)
}
static void
+qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter)
+{
+ void *head;
+ int i;
+
+ if (!qlcnic_mac_learn)
+ return;
+
+ spin_lock_init(&adapter->mac_learn_lock);
+
+ head = kcalloc(QLCNIC_LB_MAX_FILTERS, sizeof(struct hlist_head),
+ GFP_KERNEL);
+ if (!head)
+ return;
+
+ adapter->fhash.fmax = QLCNIC_LB_MAX_FILTERS;
+ adapter->fhash.fhead = (struct hlist_head *)head;
+
+ for (i = 0; i < adapter->fhash.fmax; i++)
+ INIT_HLIST_HEAD(&adapter->fhash.fhead[i]);
+}
+
+static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter)
+{
+ if (adapter->fhash.fmax && adapter->fhash.fhead)
+ kfree(adapter->fhash.fhead);
+
+ adapter->fhash.fhead = NULL;
+ adapter->fhash.fmax = 0;
+}
+
+static void qlcnic_change_filter(struct qlcnic_adapter *adapter,
+ u64 uaddr, __le16 vlan_id, struct qlcnic_host_tx_ring *tx_ring)
+{
+ struct cmd_desc_type0 *hwdesc;
+ struct qlcnic_nic_req *req;
+ struct qlcnic_mac_req *mac_req;
+ struct qlcnic_vlan_req *vlan_req;
+ u32 producer;
+ u64 word;
+
+ producer = tx_ring->producer;
+ hwdesc = &tx_ring->desc_head[tx_ring->producer];
+
+ req = (struct qlcnic_nic_req *)hwdesc;
+ memset(req, 0, sizeof(struct qlcnic_nic_req));
+ req->qhdr = cpu_to_le64(QLCNIC_REQUEST << 23);
+
+ word = QLCNIC_MAC_EVENT | ((u64)(adapter->portnum) << 16);
+ req->req_hdr = cpu_to_le64(word);
+
+ mac_req = (struct qlcnic_mac_req *)&(req->words[0]);
+ mac_req->op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD;
+ memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN);
+
+ vlan_req = (struct qlcnic_vlan_req *)&req->words[1];
+ vlan_req->vlan_id = vlan_id;
+
+ tx_ring->producer = get_next_index(producer, tx_ring->num_desc);
+}
+
+#define QLCNIC_MAC_HASH(MAC)\
+ ((((MAC) & 0x70000) >> 0x10) | (((MAC) & 0x70000000000ULL) >> 0x25))
+
+static void
+qlcnic_send_filter(struct qlcnic_adapter *adapter,
+ struct qlcnic_host_tx_ring *tx_ring,
+ struct cmd_desc_type0 *first_desc,
+ struct sk_buff *skb)
+{
+ struct ethhdr *phdr = (struct ethhdr *)(skb->data);
+ struct qlcnic_filter *fil, *tmp_fil;
+ struct hlist_node *tmp_hnode, *n;
+ struct hlist_head *head;
+ u64 src_addr = 0;
+ __le16 vlan_id = 0;
+ u8 hindex;
+
+ if (!compare_ether_addr(phdr->h_source, adapter->mac_addr))
+ return;
+
+ if (adapter->fhash.fnum >= adapter->fhash.fmax)
+ return;
+
+ /* Only NPAR capable devices support vlan based learning*/
+ if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
+ vlan_id = first_desc->vlan_TCI;
+ memcpy(&src_addr, phdr->h_source, ETH_ALEN);
+ hindex = QLCNIC_MAC_HASH(src_addr) & (QLCNIC_LB_MAX_FILTERS - 1);
+ head = &(adapter->fhash.fhead[hindex]);
+
+ hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) {
+ if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) &&
+ tmp_fil->vlan_id == vlan_id) {
+ tmp_fil->ftime = jiffies;
+ return;
+ }
+ }
+
+ fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC);
+ if (!fil)
+ return;
+
+ qlcnic_change_filter(adapter, src_addr, vlan_id, tx_ring);
+
+ fil->ftime = jiffies;
+ fil->vlan_id = vlan_id;
+ memcpy(fil->faddr, &src_addr, ETH_ALEN);
+ spin_lock(&adapter->mac_learn_lock);
+ hlist_add_head(&(fil->fnode), head);
+ adapter->fhash.fnum++;
+ spin_unlock(&adapter->mac_learn_lock);
+}
+
+static void
qlcnic_tso_check(struct net_device *netdev,
struct qlcnic_host_tx_ring *tx_ring,
struct cmd_desc_type0 *first_desc,
@@ -1626,26 +1888,14 @@ qlcnic_tso_check(struct net_device *netdev,
{
u8 opcode = TX_ETHER_PKT;
__be16 protocol = skb->protocol;
- u16 flags = 0, vid = 0;
- int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
+ u16 flags = 0;
+ int copied, offset, copy_len, hdr_len = 0, tso = 0;
struct cmd_desc_type0 *hwdesc;
struct vlan_ethhdr *vh;
struct qlcnic_adapter *adapter = netdev_priv(netdev);
u32 producer = tx_ring->producer;
-
- if (protocol == cpu_to_be16(ETH_P_8021Q)) {
-
- vh = (struct vlan_ethhdr *)skb->data;
- protocol = vh->h_vlan_encapsulated_proto;
- flags = FLAGS_VLAN_TAGGED;
-
- } else if (vlan_tx_tag_present(skb)) {
-
- flags = FLAGS_VLAN_OOB;
- vid = vlan_tx_tag_get(skb);
- qlcnic_set_tx_vlan_tci(first_desc, vid);
- vlan_oob = 1;
- }
+ __le16 vlan_oob = first_desc->flags_opcode &
+ cpu_to_le16(FLAGS_VLAN_OOB);
if (*(skb->data) & BIT_0) {
flags |= BIT_0;
@@ -1716,7 +1966,8 @@ qlcnic_tso_check(struct net_device *netdev,
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(vid);
+ 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);
@@ -1796,11 +2047,47 @@ out_err:
return -ENOMEM;
}
+static int
+qlcnic_check_tx_tagging(struct qlcnic_adapter *adapter,
+ struct sk_buff *skb,
+ struct cmd_desc_type0 *first_desc)
+{
+ u8 opcode = 0;
+ u16 flags = 0;
+ __be16 protocol = skb->protocol;
+ struct vlan_ethhdr *vh;
+
+ 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));
+ }
+ 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;
+}
+
static inline void
qlcnic_clear_cmddesc(u64 *desc)
{
desc[0] = 0ULL;
desc[2] = 0ULL;
+ desc[7] = 0ULL;
}
netdev_tx_t
@@ -1812,6 +2099,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
struct qlcnic_skb_frag *buffrag;
struct cmd_desc_type0 *hwdesc, *first_desc;
struct pci_dev *pdev;
+ struct ethhdr *phdr;
int i, k;
u32 producer;
@@ -1823,6 +2111,13 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_BUSY;
}
+ if (adapter->flags & QLCNIC_MACSPOOF) {
+ phdr = (struct ethhdr *)skb->data;
+ if (compare_ether_addr(phdr->h_source,
+ adapter->mac_addr))
+ goto drop_packet;
+ }
+
frag_count = skb_shinfo(skb)->nr_frags + 1;
/* 4 fragments per cmd des */
@@ -1844,6 +2139,12 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
pdev = adapter->pdev;
+ 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;
@@ -1852,9 +2153,6 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
pbuf->skb = skb;
pbuf->frag_count = frag_count;
- first_desc = hwdesc = &tx_ring->desc_head[producer];
- qlcnic_clear_cmddesc((u64 *)hwdesc);
-
qlcnic_set_tx_frags_len(first_desc, frag_count, skb->len);
qlcnic_set_tx_port(first_desc, adapter->portnum);
@@ -1893,6 +2191,9 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
qlcnic_tso_check(netdev, tx_ring, first_desc, skb);
+ if (qlcnic_mac_learn)
+ qlcnic_send_filter(adapter, tx_ring, first_desc, skb);
+
qlcnic_update_cmd_producer(adapter, tx_ring);
adapter->stats.txbytes += skb->len;
@@ -1947,14 +2248,14 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup)
struct net_device *netdev = adapter->netdev;
if (adapter->ahw.linkup && !linkup) {
- dev_info(&netdev->dev, "NIC Link is down\n");
+ netdev_info(netdev, "NIC Link is down\n");
adapter->ahw.linkup = 0;
if (netif_running(netdev)) {
netif_carrier_off(netdev);
netif_stop_queue(netdev);
}
} else if (!adapter->ahw.linkup && linkup) {
- dev_info(&netdev->dev, "NIC Link is up\n");
+ netdev_info(netdev, "NIC Link is up\n");
adapter->ahw.linkup = 1;
if (netif_running(netdev)) {
netif_carrier_on(netdev);
@@ -2258,18 +2559,22 @@ qlcnic_clr_drv_state(struct qlcnic_adapter *adapter)
}
static void
-qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter)
+qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed)
{
u32 val;
if (qlcnic_api_lock(adapter))
goto err;
- val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
+ val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
QLC_DEV_CLR_REF_CNT(val, adapter->portnum);
- QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val);
+ QLCWR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val);
- if (!(val & 0x11111111))
+ if (failed) {
+ QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED);
+ dev_info(&adapter->pdev->dev,
+ "Device state set to Failed. Please Reboot\n");
+ } else if (!(val & 0x11111111))
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_COLD);
val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
@@ -2290,7 +2595,7 @@ qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
int act, state;
state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
- act = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
+ act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
if (((state & 0x11111111) == (act & 0x11111111)) ||
((act & 0x11111111) == ((state >> 1) & 0x11111111)))
@@ -2325,10 +2630,10 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter)
if (qlcnic_api_lock(adapter))
return -1;
- val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
+ val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
if (!(val & (1 << (portnum * 4)))) {
QLC_DEV_SET_REF_CNT(val, portnum);
- QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val);
+ QLCWR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val);
}
prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
@@ -2403,13 +2708,14 @@ qlcnic_fwinit_work(struct work_struct *work)
{
struct qlcnic_adapter *adapter = container_of(work,
struct qlcnic_adapter, fw_work.work);
- u32 dev_state = 0xf, npar_state;
+ u32 dev_state = 0xf;
if (qlcnic_api_lock(adapter))
goto err_ret;
dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
- if (dev_state == QLCNIC_DEV_QUISCENT) {
+ if (dev_state == QLCNIC_DEV_QUISCENT ||
+ dev_state == QLCNIC_DEV_NEED_QUISCENT) {
qlcnic_api_unlock(adapter);
qlcnic_schedule_work(adapter, qlcnic_fwinit_work,
FW_POLL_DELAY * 2);
@@ -2417,16 +2723,8 @@ qlcnic_fwinit_work(struct work_struct *work)
}
if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
- npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
- if (npar_state == QLCNIC_DEV_NPAR_RDY) {
- qlcnic_api_unlock(adapter);
- goto wait_npar;
- } else {
- qlcnic_schedule_work(adapter, qlcnic_fwinit_work,
- FW_POLL_DELAY);
- qlcnic_api_unlock(adapter);
- return;
- }
+ qlcnic_api_unlock(adapter);
+ goto wait_npar;
}
if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) {
@@ -2439,18 +2737,6 @@ qlcnic_fwinit_work(struct work_struct *work)
skip_ack_check:
dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
- if (dev_state == QLCNIC_DEV_NEED_QUISCENT) {
- QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
- QLCNIC_DEV_QUISCENT);
- qlcnic_schedule_work(adapter, qlcnic_fwinit_work,
- FW_POLL_DELAY * 2);
- QLCDB(adapter, DRV, "Quiscing the driver\n");
- qlcnic_idc_debug_info(adapter, 0);
-
- qlcnic_api_unlock(adapter);
- return;
- }
-
if (dev_state == QLCNIC_DEV_NEED_RESET) {
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
QLCNIC_DEV_INITIALIZING);
@@ -2463,6 +2749,7 @@ skip_ack_check:
if (!adapter->nic_ops->start_firmware(adapter)) {
qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
+ adapter->fw_wait_cnt = 0;
return;
}
goto err_ret;
@@ -2475,27 +2762,25 @@ wait_npar:
QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state);
switch (dev_state) {
- case QLCNIC_DEV_QUISCENT:
- case QLCNIC_DEV_NEED_QUISCENT:
- case QLCNIC_DEV_NEED_RESET:
- qlcnic_schedule_work(adapter,
- qlcnic_fwinit_work, FW_POLL_DELAY);
- return;
- case QLCNIC_DEV_FAILED:
- break;
-
- default:
+ case QLCNIC_DEV_READY:
if (!adapter->nic_ops->start_firmware(adapter)) {
qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
+ adapter->fw_wait_cnt = 0;
return;
}
+ case QLCNIC_DEV_FAILED:
+ break;
+ default:
+ qlcnic_schedule_work(adapter,
+ qlcnic_fwinit_work, FW_POLL_DELAY);
+ return;
}
err_ret:
dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u "
"fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt);
netif_device_attach(adapter->netdev);
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 0);
}
static void
@@ -2508,7 +2793,12 @@ qlcnic_detach_work(struct work_struct *work)
netif_device_detach(netdev);
- qlcnic_down(adapter, netdev);
+ /* Dont grab rtnl lock during Quiscent mode */
+ if (adapter->dev_state == QLCNIC_DEV_NEED_QUISCENT) {
+ if (netif_running(netdev))
+ __qlcnic_down(adapter, netdev);
+ } else
+ qlcnic_down(adapter, netdev);
status = QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1);
@@ -2531,8 +2821,78 @@ err_ret:
dev_err(&adapter->pdev->dev, "detach failed; status=%d temp=%d\n",
status, adapter->temp);
netif_device_attach(netdev);
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 1);
+}
+
+/*Transit NPAR state to NON Operational */
+static void
+qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
+{
+ u32 state;
+
+ state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+ if (state == QLCNIC_DEV_NPAR_NON_OPER)
+ return;
+
+ if (qlcnic_api_lock(adapter))
+ return;
+ QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
+ qlcnic_api_unlock(adapter);
+}
+
+/* Caller should held RESETTING bit.
+ * This should be call in sync with qlcnic_request_quiscent_mode.
+ */
+void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter)
+{
+ qlcnic_clr_drv_state(adapter);
+ qlcnic_api_lock(adapter);
+ QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
+ qlcnic_api_unlock(adapter);
+}
+
+/* Caller should held RESETTING bit.
+ */
+int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter)
+{
+ u8 timeo = adapter->dev_init_timeo / 2;
+ u32 state;
+
+ if (qlcnic_api_lock(adapter))
+ return -EIO;
+
+ state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
+ if (state != QLCNIC_DEV_READY)
+ return -EIO;
+
+ QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_QUISCENT);
+ qlcnic_api_unlock(adapter);
+ QLCDB(adapter, DRV, "NEED QUISCENT state set\n");
+ qlcnic_idc_debug_info(adapter, 0);
+ qlcnic_set_drv_state(adapter, QLCNIC_DEV_NEED_QUISCENT);
+
+ do {
+ msleep(2000);
+ state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
+ if (state == QLCNIC_DEV_QUISCENT)
+ return 0;
+ if (!qlcnic_check_drv_state(adapter)) {
+ if (qlcnic_api_lock(adapter))
+ return -EIO;
+ QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
+ QLCNIC_DEV_QUISCENT);
+ qlcnic_api_unlock(adapter);
+ QLCDB(adapter, DRV, "QUISCENT mode set\n");
+ return 0;
+ }
+ } while (--timeo);
+
+ dev_err(&adapter->pdev->dev, "Failed to quiesce device, DRV_STATE=%08x"
+ " DRV_ACTIVE=%08x\n", QLCRD32(adapter, QLCNIC_CRB_DRV_STATE),
+ QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE));
+ qlcnic_clear_quiscent_mode(adapter);
+ return -EIO;
}
/*Transit to RESET state from READY state only */
@@ -2553,6 +2913,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
qlcnic_idc_debug_info(adapter, 0);
}
+ QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
qlcnic_api_unlock(adapter);
}
@@ -2560,21 +2921,11 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
static void
qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter)
{
- u32 state;
-
- if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
- adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
- return;
if (qlcnic_api_lock(adapter))
return;
- state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
-
- if (state != QLCNIC_DEV_NPAR_RDY) {
- QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE,
- QLCNIC_DEV_NPAR_RDY);
- QLCDB(adapter, DRV, "NPAR READY state set\n");
- }
+ QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_OPER);
+ QLCDB(adapter, DRV, "NPAR operational state set\n");
qlcnic_api_unlock(adapter);
}
@@ -2587,7 +2938,8 @@ qlcnic_schedule_work(struct qlcnic_adapter *adapter,
return;
INIT_DELAYED_WORK(&adapter->fw_work, func);
- schedule_delayed_work(&adapter->fw_work, round_jiffies_relative(delay));
+ queue_delayed_work(qlcnic_wq, &adapter->fw_work,
+ round_jiffies_relative(delay));
}
static void
@@ -2605,12 +2957,26 @@ qlcnic_attach_work(struct work_struct *work)
struct qlcnic_adapter *adapter = container_of(work,
struct qlcnic_adapter, fw_work.work);
struct net_device *netdev = adapter->netdev;
+ u32 npar_state;
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC) {
+ npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+ if (adapter->fw_wait_cnt++ > QLCNIC_DEV_NPAR_OPER_TIMEO)
+ qlcnic_clr_all_drv_state(adapter, 0);
+ else if (npar_state != QLCNIC_DEV_NPAR_OPER)
+ qlcnic_schedule_work(adapter, qlcnic_attach_work,
+ FW_POLL_DELAY);
+ else
+ goto attach;
+ QLCDB(adapter, DRV, "Waiting for NPAR state to operational\n");
+ return;
+ }
+attach:
if (netif_running(netdev)) {
if (qlcnic_up(adapter, netdev))
goto done;
- qlcnic_config_indev_addr(netdev, NETDEV_UP);
+ qlcnic_restore_indev_addr(netdev, NETDEV_UP);
}
done:
@@ -2626,7 +2992,7 @@ done:
static int
qlcnic_check_health(struct qlcnic_adapter *adapter)
{
- u32 state = 0, heartbit;
+ u32 state = 0, heartbeat;
struct net_device *netdev = adapter->netdev;
if (qlcnic_check_temp(adapter))
@@ -2636,12 +3002,15 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
qlcnic_dev_request_reset(adapter);
state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
- if (state == QLCNIC_DEV_NEED_RESET || state == QLCNIC_DEV_NEED_QUISCENT)
+ if (state == QLCNIC_DEV_NEED_RESET) {
+ qlcnic_set_npar_non_operational(adapter);
adapter->need_fw_reset = 1;
+ } else if (state == QLCNIC_DEV_NEED_QUISCENT)
+ goto detach;
- heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
- if (heartbit != adapter->heartbit) {
- adapter->heartbit = heartbit;
+ heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
+ if (heartbeat != adapter->heartbeat) {
+ adapter->heartbeat = heartbeat;
adapter->fw_fail_cnt = 0;
if (adapter->need_fw_reset)
goto detach;
@@ -2692,6 +3061,9 @@ qlcnic_fw_poll_work(struct work_struct *work)
if (qlcnic_check_health(adapter))
return;
+ if (adapter->fhash.fnum)
+ qlcnic_prune_lb_filters(adapter);
+
reschedule:
qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
}
@@ -2738,7 +3110,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
if (qlcnic_api_lock(adapter))
return -EINVAL;
- if (first_func) {
+ if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) {
adapter->need_fw_reset = 1;
set_bit(__QLCNIC_START_FW, &adapter->state);
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING);
@@ -2756,7 +3128,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
if (netif_running(netdev)) {
err = qlcnic_attach(adapter);
if (err) {
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 1);
clear_bit(__QLCNIC_AER, &adapter->state);
netif_device_attach(netdev);
return err;
@@ -2766,7 +3138,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
if (err)
goto done;
- qlcnic_config_indev_addr(netdev, NETDEV_UP);
+ qlcnic_restore_indev_addr(netdev, NETDEV_UP);
}
done:
netif_device_attach(netdev);
@@ -2822,7 +3194,6 @@ static void qlcnic_io_resume(struct pci_dev *pdev)
FW_POLL_DELAY);
}
-
static int
qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
{
@@ -2832,8 +3203,20 @@ qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
if (err)
return err;
+ err = qlcnic_check_npar_opertional(adapter);
+ if (err)
+ return err;
+
+ err = qlcnic_initialize_nic(adapter);
+ if (err)
+ return err;
+
qlcnic_check_options(adapter);
+ err = qlcnic_set_eswitch_port_config(adapter);
+ if (err)
+ return err;
+
adapter->need_fw_reset = 0;
return err;
@@ -3093,9 +3476,6 @@ validate_pm_config(struct qlcnic_adapter *adapter,
if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC)
return QL_STATUS_INVALID_PARAM;
- if (!IS_VALID_MODE(pm_cfg[i].action))
- return QL_STATUS_INVALID_PARAM;
-
s_esw_id = adapter->npars[src_pci_func].phy_port;
d_esw_id = adapter->npars[dest_pci_func].phy_port;
@@ -3129,7 +3509,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
return ret;
for (i = 0; i < count; i++) {
pci_func = pm_cfg[i].pci_func;
- action = pm_cfg[i].action;
+ action = !!pm_cfg[i].action;
id = adapter->npars[pci_func].phy_port;
ret = qlcnic_config_port_mirroring(adapter, id,
action, pci_func);
@@ -3140,7 +3520,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
for (i = 0; i < count; i++) {
pci_func = pm_cfg[i].pci_func;
id = adapter->npars[pci_func].phy_port;
- adapter->npars[pci_func].enable_pm = pm_cfg[i].action;
+ adapter->npars[pci_func].enable_pm = !!pm_cfg[i].action;
adapter->npars[pci_func].dest_npar = id;
}
return size;
@@ -3172,30 +3552,46 @@ qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj,
static int
validate_esw_config(struct qlcnic_adapter *adapter,
- struct qlcnic_esw_func_cfg *esw_cfg, int count)
+ struct qlcnic_esw_func_cfg *esw_cfg, int count)
{
+ u32 op_mode;
u8 pci_func;
int i;
+ op_mode = readl(adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE);
+
for (i = 0; i < count; i++) {
pci_func = esw_cfg[i].pci_func;
if (pci_func >= QLCNIC_MAX_PCI_FUNC)
return QL_STATUS_INVALID_PARAM;
- if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
- return QL_STATUS_INVALID_PARAM;
+ if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+ if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC)
+ return QL_STATUS_INVALID_PARAM;
- if (esw_cfg->host_vlan_tag == 1)
+ switch (esw_cfg[i].op_mode) {
+ case QLCNIC_PORT_DEFAULTS:
+ if (QLC_DEV_GET_DRV(op_mode, pci_func) !=
+ QLCNIC_NON_PRIV_FUNC) {
+ esw_cfg[i].mac_anti_spoof = 0;
+ esw_cfg[i].mac_override = 1;
+ esw_cfg[i].promisc_mode = 1;
+ }
+ break;
+ case QLCNIC_ADD_VLAN:
if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
return QL_STATUS_INVALID_PARAM;
-
- if (!IS_VALID_MODE(esw_cfg[i].promisc_mode)
- || !IS_VALID_MODE(esw_cfg[i].host_vlan_tag)
- || !IS_VALID_MODE(esw_cfg[i].mac_learning)
- || !IS_VALID_MODE(esw_cfg[i].discard_tagged))
+ if (!esw_cfg[i].op_type)
+ return QL_STATUS_INVALID_PARAM;
+ break;
+ case QLCNIC_DEL_VLAN:
+ if (!esw_cfg[i].op_type)
+ return QL_STATUS_INVALID_PARAM;
+ break;
+ default:
return QL_STATUS_INVALID_PARAM;
+ }
}
-
return 0;
}
@@ -3206,8 +3602,9 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_func_cfg *esw_cfg;
+ struct qlcnic_npar_info *npar;
int count, rem, i, ret;
- u8 id, pci_func;
+ u8 pci_func, op_mode = 0;
count = size / sizeof(struct qlcnic_esw_func_cfg);
rem = size % sizeof(struct qlcnic_esw_func_cfg);
@@ -3220,30 +3617,55 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
return ret;
for (i = 0; i < count; i++) {
- pci_func = esw_cfg[i].pci_func;
- id = adapter->npars[pci_func].phy_port;
- ret = qlcnic_config_switch_port(adapter, id,
- esw_cfg[i].host_vlan_tag,
- esw_cfg[i].discard_tagged,
- esw_cfg[i].promisc_mode,
- esw_cfg[i].mac_learning,
- esw_cfg[i].pci_func,
- esw_cfg[i].vlan_id);
- if (ret)
- return ret;
+ if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+ if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
+ return QL_STATUS_INVALID_PARAM;
+
+ 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;
+
+ switch (esw_cfg[i].op_mode) {
+ case QLCNIC_PORT_DEFAULTS:
+ qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
+ break;
+ case QLCNIC_ADD_VLAN:
+ qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
+ break;
+ case QLCNIC_DEL_VLAN:
+ esw_cfg[i].vlan_id = 0;
+ qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
+ break;
+ }
}
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+ goto out;
+
for (i = 0; i < count; i++) {
pci_func = esw_cfg[i].pci_func;
- adapter->npars[pci_func].promisc_mode = esw_cfg[i].promisc_mode;
- adapter->npars[pci_func].mac_learning = esw_cfg[i].mac_learning;
- adapter->npars[pci_func].vlan_id = esw_cfg[i].vlan_id;
- adapter->npars[pci_func].discard_tagged =
- esw_cfg[i].discard_tagged;
- adapter->npars[pci_func].host_vlan_tag =
- esw_cfg[i].host_vlan_tag;
+ npar = &adapter->npars[pci_func];
+ switch (esw_cfg[i].op_mode) {
+ case QLCNIC_PORT_DEFAULTS:
+ npar->promisc_mode = esw_cfg[i].promisc_mode;
+ npar->mac_override = esw_cfg[i].mac_override;
+ npar->offload_flags = esw_cfg[i].offload_flags;
+ npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
+ npar->discard_tagged = esw_cfg[i].discard_tagged;
+ break;
+ case QLCNIC_ADD_VLAN:
+ npar->pvid = esw_cfg[i].vlan_id;
+ break;
+ case QLCNIC_DEL_VLAN:
+ npar->pvid = 0;
+ break;
+ }
}
-
+out:
return size;
}
@@ -3254,7 +3676,7 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC];
- int i;
+ u8 i;
if (size != sizeof(esw_cfg))
return QL_STATUS_INVALID_PARAM;
@@ -3262,12 +3684,9 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
continue;
-
- esw_cfg[i].host_vlan_tag = adapter->npars[i].host_vlan_tag;
- esw_cfg[i].promisc_mode = adapter->npars[i].promisc_mode;
- esw_cfg[i].discard_tagged = adapter->npars[i].discard_tagged;
- esw_cfg[i].vlan_id = adapter->npars[i].vlan_id;
- esw_cfg[i].mac_learning = adapter->npars[i].mac_learning;
+ esw_cfg[i].pci_func = i;
+ if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]))
+ return QL_STATUS_INVALID_PARAM;
}
memcpy(buf, &esw_cfg, size);
@@ -3357,7 +3776,7 @@ qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj,
return ret;
np_cfg[i].pci_func = i;
- np_cfg[i].op_mode = nic_info.op_mode;
+ np_cfg[i].op_mode = (u8)nic_info.op_mode;
np_cfg[i].port_num = nic_info.phys_port;
np_cfg[i].fw_capab = nic_info.capabilities;
np_cfg[i].min_bw = nic_info.min_tx_bw ;
@@ -3370,6 +3789,115 @@ qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj,
}
static ssize_t
+qlcnic_sysfs_get_port_stats(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+ struct qlcnic_esw_statistics port_stats;
+ int ret;
+
+ if (size != sizeof(struct qlcnic_esw_statistics))
+ return QL_STATUS_INVALID_PARAM;
+
+ if (offset >= QLCNIC_MAX_PCI_FUNC)
+ return QL_STATUS_INVALID_PARAM;
+
+ memset(&port_stats, 0, size);
+ ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
+ &port_stats.rx);
+ if (ret)
+ return ret;
+
+ ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
+ &port_stats.tx);
+ if (ret)
+ return ret;
+
+ memcpy(buf, &port_stats, size);
+ return size;
+}
+
+static ssize_t
+qlcnic_sysfs_get_esw_stats(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+ struct qlcnic_esw_statistics esw_stats;
+ int ret;
+
+ if (size != sizeof(struct qlcnic_esw_statistics))
+ return QL_STATUS_INVALID_PARAM;
+
+ if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
+ return QL_STATUS_INVALID_PARAM;
+
+ memset(&esw_stats, 0, size);
+ ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
+ &esw_stats.rx);
+ if (ret)
+ return ret;
+
+ ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
+ &esw_stats.tx);
+ if (ret)
+ return ret;
+
+ memcpy(buf, &esw_stats, size);
+ return size;
+}
+
+static ssize_t
+qlcnic_sysfs_clear_esw_stats(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+ int ret;
+
+ if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
+ return QL_STATUS_INVALID_PARAM;
+
+ ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
+ QLCNIC_QUERY_RX_COUNTER);
+ if (ret)
+ return ret;
+
+ ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
+ QLCNIC_QUERY_TX_COUNTER);
+ if (ret)
+ return ret;
+
+ return size;
+}
+
+static ssize_t
+qlcnic_sysfs_clear_port_stats(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+ int ret;
+
+ if (offset >= QLCNIC_MAX_PCI_FUNC)
+ return QL_STATUS_INVALID_PARAM;
+
+ ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
+ QLCNIC_QUERY_RX_COUNTER);
+ if (ret)
+ return ret;
+
+ ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
+ QLCNIC_QUERY_TX_COUNTER);
+ if (ret)
+ return ret;
+
+ return size;
+}
+
+static ssize_t
qlcnic_sysfs_read_pci_config(struct file *file, struct kobject *kobj,
struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
{
@@ -3418,6 +3946,20 @@ static struct bin_attribute bin_attr_pci_config = {
.write = NULL,
};
+static struct bin_attribute bin_attr_port_stats = {
+ .attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)},
+ .size = 0,
+ .read = qlcnic_sysfs_get_port_stats,
+ .write = qlcnic_sysfs_clear_port_stats,
+};
+
+static struct bin_attribute bin_attr_esw_stats = {
+ .attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)},
+ .size = 0,
+ .read = qlcnic_sysfs_get_esw_stats,
+ .write = qlcnic_sysfs_clear_esw_stats,
+};
+
static struct bin_attribute bin_attr_esw_config = {
.attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
@@ -3457,6 +3999,9 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
{
struct device *dev = &adapter->pdev->dev;
+ if (device_create_bin_file(dev, &bin_attr_port_stats))
+ dev_info(dev, "failed to create port stats sysfs entry");
+
if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
return;
if (device_create_file(dev, &dev_attr_diag_mode))
@@ -3465,18 +4010,20 @@ 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 (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
- adapter->op_mode != QLCNIC_MGMT_FUNC)
+ 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_esw_config))
- dev_info(dev, "failed to create esw config sysfs entry");
if (device_create_bin_file(dev, &bin_attr_pm_config))
dev_info(dev, "failed to create pm config sysfs entry");
-
+ if (device_create_bin_file(dev, &bin_attr_esw_stats))
+ dev_info(dev, "failed to create eswitch stats sysfs entry");
}
static void
@@ -3484,18 +4031,22 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
{
struct device *dev = &adapter->pdev->dev;
+ device_remove_bin_file(dev, &bin_attr_port_stats);
+
if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
return;
device_remove_file(dev, &dev_attr_diag_mode);
device_remove_bin_file(dev, &bin_attr_crb);
device_remove_bin_file(dev, &bin_attr_mem);
- if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
- adapter->op_mode != QLCNIC_MGMT_FUNC)
+ 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_esw_config);
device_remove_bin_file(dev, &bin_attr_pm_config);
+ device_remove_bin_file(dev, &bin_attr_esw_stats);
}
#ifdef CONFIG_INET
@@ -3503,10 +4054,10 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
#define is_qlcnic_netdev(dev) (dev->netdev_ops == &qlcnic_netdev_ops)
static void
-qlcnic_config_indev_addr(struct net_device *dev, unsigned long event)
+qlcnic_config_indev_addr(struct qlcnic_adapter *adapter,
+ struct net_device *dev, unsigned long event)
{
struct in_device *indev;
- struct qlcnic_adapter *adapter = netdev_priv(dev);
indev = in_dev_get(dev);
if (!indev)
@@ -3530,6 +4081,27 @@ qlcnic_config_indev_addr(struct net_device *dev, unsigned long event)
in_dev_put(indev);
}
+static void
+qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
+ struct net_device *dev;
+ u16 vid;
+
+ 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);
+ if (!dev)
+ continue;
+
+ qlcnic_config_indev_addr(adapter, dev, event);
+ }
+}
+
static int qlcnic_netdev_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
@@ -3556,7 +4128,7 @@ recheck:
if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
goto done;
- qlcnic_config_indev_addr(dev, event);
+ qlcnic_config_indev_addr(adapter, dev, event);
done:
return NOTIFY_DONE;
}
@@ -3573,7 +4145,7 @@ qlcnic_inetaddr_event(struct notifier_block *this,
dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
recheck:
- if (dev == NULL || !netif_running(dev))
+ if (dev == NULL)
goto done;
if (dev->priv_flags & IFF_802_1Q_VLAN) {
@@ -3616,7 +4188,7 @@ static struct notifier_block qlcnic_inetaddr_cb = {
};
#else
static void
-qlcnic_config_indev_addr(struct net_device *dev, unsigned long event)
+qlcnic_restore_indev_addr(struct net_device *dev, unsigned long event)
{ }
#endif
static struct pci_error_handlers qlcnic_err_handler = {
@@ -3645,6 +4217,12 @@ static int __init qlcnic_init_module(void)
printk(KERN_INFO "%s\n", qlcnic_driver_string);
+ qlcnic_wq = create_singlethread_workqueue("qlcnic");
+ if (qlcnic_wq == NULL) {
+ printk(KERN_ERR "qlcnic: cannot create workqueue\n");
+ return -ENOMEM;
+ }
+
#ifdef CONFIG_INET
register_netdevice_notifier(&qlcnic_netdev_cb);
register_inetaddr_notifier(&qlcnic_inetaddr_cb);
@@ -3656,6 +4234,7 @@ static int __init qlcnic_init_module(void)
unregister_inetaddr_notifier(&qlcnic_inetaddr_cb);
unregister_netdevice_notifier(&qlcnic_netdev_cb);
#endif
+ destroy_workqueue(qlcnic_wq);
}
return ret;
@@ -3672,6 +4251,7 @@ static void __exit qlcnic_exit_module(void)
unregister_inetaddr_notifier(&qlcnic_inetaddr_cb);
unregister_netdevice_notifier(&qlcnic_netdev_cb);
#endif
+ destroy_workqueue(qlcnic_wq);
}
module_exit(qlcnic_exit_module);
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 5f89e83501f4..ba0053d8515e 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1566,7 +1566,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
rx_ring->rx_packets++;
rx_ring->rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, ndev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (qdev->rx_csum &&
!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
@@ -1676,7 +1676,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
rx_ring->rx_packets++;
rx_ring->rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, ndev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* If rx checksum is on, and there are no
* csum or frame errors.
@@ -1996,7 +1996,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
}
skb->protocol = eth_type_trans(skb, ndev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* If rx checksum is on, and there are no
* csum or frame errors.
@@ -2222,10 +2222,11 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
ql_update_cq(rx_ring);
prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
}
+ if (!net_rsp)
+ return 0;
ql_write_cq_idx(rx_ring);
tx_ring = &qdev->tx_ring[net_rsp->txq_idx];
- if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id) &&
- net_rsp != NULL) {
+ if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id)) {
if (atomic_read(&tx_ring->queue_stopped) &&
(atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4)))
/*
@@ -2571,7 +2572,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
mac_iocb_ptr->frame_len = cpu_to_le16((u16) skb->len);
- if (qdev->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev,
"Adding a vlan tag %d.\n", vlan_tx_tag_get(skb));
mac_iocb_ptr->flags3 |= OB_MAC_IOCB_V;
@@ -3888,11 +3889,8 @@ int ql_wol(struct ql_adapter *qdev)
return status;
}
-static int ql_adapter_down(struct ql_adapter *qdev)
+static void ql_cancel_all_work_sync(struct ql_adapter *qdev)
{
- int i, status = 0;
-
- ql_link_off(qdev);
/* Don't kill the reset worker thread if we
* are in the process of recovery.
@@ -3904,6 +3902,15 @@ static int ql_adapter_down(struct ql_adapter *qdev)
cancel_delayed_work_sync(&qdev->mpi_idc_work);
cancel_delayed_work_sync(&qdev->mpi_core_to_log);
cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+}
+
+static int ql_adapter_down(struct ql_adapter *qdev)
+{
+ int i, status = 0;
+
+ ql_link_off(qdev);
+
+ ql_cancel_all_work_sync(qdev);
for (i = 0; i < qdev->rss_ring_count; i++)
napi_disable(&qdev->rx_ring[i].napi);
@@ -4726,6 +4733,7 @@ static void __devexit qlge_remove(struct pci_dev *pdev)
struct net_device *ndev = pci_get_drvdata(pdev);
struct ql_adapter *qdev = netdev_priv(ndev);
del_timer_sync(&qdev->timer);
+ ql_cancel_all_work_sync(qdev);
unregister_netdev(ndev);
ql_release_all(pdev);
pci_disable_device(pdev);
@@ -4745,13 +4753,7 @@ static void ql_eeh_close(struct net_device *ndev)
/* Disabling the timer */
del_timer_sync(&qdev->timer);
- if (test_bit(QL_ADAPTER_UP, &qdev->flags))
- cancel_delayed_work_sync(&qdev->asic_reset_work);
- cancel_delayed_work_sync(&qdev->mpi_reset_work);
- cancel_delayed_work_sync(&qdev->mpi_work);
- cancel_delayed_work_sync(&qdev->mpi_idc_work);
- cancel_delayed_work_sync(&qdev->mpi_core_to_log);
- cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+ ql_cancel_all_work_sync(qdev);
for (i = 0; i < qdev->rss_ring_count; i++)
netif_napi_del(&qdev->rx_ring[i].napi);
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 142c381e1d73..0b014c894686 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -200,7 +200,7 @@ struct r6040_private {
int old_duplex;
};
-static char version[] __devinitdata = KERN_INFO DRV_NAME
+static char version[] __devinitdata = DRV_NAME
": RDC R6040 NAPI net driver,"
"version "DRV_VERSION " (" DRV_RELDATE ")";
@@ -224,7 +224,8 @@ static int r6040_phy_read(void __iomem *ioaddr, int phy_addr, int reg)
}
/* Write a word data from PHY Chip */
-static void r6040_phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val)
+static void r6040_phy_write(void __iomem *ioaddr,
+ int phy_addr, int reg, u16 val)
{
int limit = 2048;
u16 cmd;
@@ -348,8 +349,8 @@ static int r6040_alloc_rxbufs(struct net_device *dev)
}
desc->skb_ptr = skb;
desc->buf = cpu_to_le32(pci_map_single(lp->pdev,
- desc->skb_ptr->data,
- MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
+ desc->skb_ptr->data,
+ MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
desc->status = DSC_OWNER_MAC;
desc = desc->vndescp;
} while (desc != lp->rx_ring);
@@ -491,12 +492,14 @@ static int r6040_close(struct net_device *dev)
/* Free Descriptor memory */
if (lp->rx_ring) {
- pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
+ pci_free_consistent(pdev,
+ RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
lp->rx_ring = NULL;
}
if (lp->tx_ring) {
- pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
+ pci_free_consistent(pdev,
+ TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
lp->tx_ring = NULL;
}
@@ -547,7 +550,7 @@ static int r6040_rx(struct net_device *dev, int limit)
}
goto next_descr;
}
-
+
/* Packet successfully received */
new_skb = netdev_alloc_skb(dev, MAX_BUF_SIZE);
if (!new_skb) {
@@ -556,13 +559,13 @@ static int r6040_rx(struct net_device *dev, int limit)
}
skb_ptr = descptr->skb_ptr;
skb_ptr->dev = priv->dev;
-
+
/* Do not count the CRC */
skb_put(skb_ptr, descptr->len - 4);
pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev);
-
+
/* Send to upper layer */
netif_receive_skb(skb_ptr);
dev->stats.rx_packets++;
@@ -710,8 +713,10 @@ static int r6040_up(struct net_device *dev)
return ret;
/* improve performance (by RDC guys) */
- r6040_phy_write(ioaddr, 30, 17, (r6040_phy_read(ioaddr, 30, 17) | 0x4000));
- r6040_phy_write(ioaddr, 30, 17, ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000));
+ r6040_phy_write(ioaddr, 30, 17,
+ (r6040_phy_read(ioaddr, 30, 17) | 0x4000));
+ r6040_phy_write(ioaddr, 30, 17,
+ ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000));
r6040_phy_write(ioaddr, 0, 19, 0x0000);
r6040_phy_write(ioaddr, 0, 30, 0x01F0);
@@ -740,6 +745,9 @@ static void r6040_mac_address(struct net_device *dev)
iowrite16(adrp[0], ioaddr + MID_0L);
iowrite16(adrp[1], ioaddr + MID_0M);
iowrite16(adrp[2], ioaddr + MID_0H);
+
+ /* Store MAC Address in perm_addr */
+ memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);
}
static int r6040_open(struct net_device *dev)
@@ -751,7 +759,7 @@ static int r6040_open(struct net_device *dev)
ret = request_irq(dev->irq, r6040_interrupt,
IRQF_SHARED, dev->name, dev);
if (ret)
- return ret;
+ goto out;
/* Set MAC address */
r6040_mac_address(dev);
@@ -759,30 +767,37 @@ static int r6040_open(struct net_device *dev)
/* Allocate Descriptor memory */
lp->rx_ring =
pci_alloc_consistent(lp->pdev, RX_DESC_SIZE, &lp->rx_ring_dma);
- if (!lp->rx_ring)
- return -ENOMEM;
+ if (!lp->rx_ring) {
+ ret = -ENOMEM;
+ goto err_free_irq;
+ }
lp->tx_ring =
pci_alloc_consistent(lp->pdev, TX_DESC_SIZE, &lp->tx_ring_dma);
if (!lp->tx_ring) {
- pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
- lp->rx_ring_dma);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_free_rx_ring;
}
ret = r6040_up(dev);
- if (ret) {
- pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring,
- lp->tx_ring_dma);
- pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
- lp->rx_ring_dma);
- return ret;
- }
+ if (ret)
+ goto err_free_tx_ring;
napi_enable(&lp->napi);
netif_start_queue(dev);
return 0;
+
+err_free_tx_ring:
+ pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring,
+ lp->tx_ring_dma);
+err_free_rx_ring:
+ pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
+ lp->rx_ring_dma);
+err_free_irq:
+ free_irq(dev->irq, dev);
+out:
+ return ret;
}
static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
@@ -893,16 +908,18 @@ static void r6040_multicast_list(struct net_device *dev)
/* Multicast Address 1~4 case */
i = 0;
netdev_for_each_mc_addr(ha, dev) {
- if (i < MCAST_MAX) {
- adrp = (u16 *) ha->addr;
- iowrite16(adrp[0], ioaddr + MID_1L + 8 * i);
- iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
- iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
- } else {
- iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
- iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
- iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
- }
+ if (i >= MCAST_MAX)
+ break;
+ adrp = (u16 *) ha->addr;
+ iowrite16(adrp[0], ioaddr + MID_1L + 8 * i);
+ iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
+ iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
+ i++;
+ }
+ while (i < MCAST_MAX) {
+ iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
+ iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
+ iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
i++;
}
}
@@ -946,7 +963,7 @@ static const struct net_device_ops r6040_netdev_ops = {
.ndo_set_multicast_list = r6040_multicast_list,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_do_ioctl = r6040_ioctl,
.ndo_tx_timeout = r6040_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1039,7 +1056,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
u16 *adrp;
int i;
- printk("%s\n", version);
+ pr_info("%s\n", version);
err = pci_enable_device(pdev);
if (err)
@@ -1113,7 +1130,8 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
/* Some bootloader/BIOSes do not initialize
* MAC address, warn about that */
if (!(adrp[0] || adrp[1] || adrp[2])) {
- netdev_warn(dev, "MAC address not initialized, generating random\n");
+ netdev_warn(dev, "MAC address not initialized, "
+ "generating random\n");
random_ether_addr(dev->dev_addr);
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 992db2fa136e..d88ce9fb1cbd 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -187,12 +187,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = {
MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
-/*
- * we set our copybreak very high so that we don't have
- * to allocate 16k frames all the time (see note in
- * rtl8169_open()
- */
-static int rx_copybreak = 16383;
+static int rx_buf_sz = 16383;
static int use_dac;
static struct {
u32 msg_enable;
@@ -484,10 +479,8 @@ struct rtl8169_private {
struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */
dma_addr_t TxPhyAddr;
dma_addr_t RxPhyAddr;
- struct sk_buff *Rx_skbuff[NUM_RX_DESC]; /* Rx data buffers */
+ void *Rx_databuff[NUM_RX_DESC]; /* Rx data buffers */
struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */
- unsigned align;
- unsigned rx_buf_sz;
struct timer_list timer;
u16 cp_cmd;
u16 intr_event;
@@ -515,8 +508,6 @@ struct rtl8169_private {
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
-module_param(rx_copybreak, int, 0);
-MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
module_param(use_dac, int, 0);
MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
module_param_named(debug, debug.msg_enable, int, 0);
@@ -1043,7 +1034,7 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data)
static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
struct sk_buff *skb)
{
- return (tp->vlgrp && vlan_tx_tag_present(skb)) ?
+ return (vlan_tx_tag_present(skb)) ?
TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
}
@@ -1076,7 +1067,12 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
int ret;
if (vlgrp && (opts2 & RxVlanTag)) {
- __vlan_hwaccel_rx(skb, vlgrp, swab16(opts2 & 0xffff), polling);
+ u16 vtag = swab16(opts2 & 0xffff);
+
+ if (likely(polling))
+ vlan_gro_receive(&tp->napi, vlgrp, vtag, skb);
+ else
+ __vlan_hwaccel_rx(skb, vlgrp, vtag, polling);
ret = 0;
} else
ret = -1;
@@ -1204,6 +1200,7 @@ static void rtl8169_update_counters(struct net_device *dev)
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
@@ -1212,8 +1209,7 @@ static void rtl8169_update_counters(struct net_device *dev)
if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0)
return;
- counters = dma_alloc_coherent(&tp->pci_dev->dev, sizeof(*counters),
- &paddr, GFP_KERNEL);
+ counters = dma_alloc_coherent(d, sizeof(*counters), &paddr, GFP_KERNEL);
if (!counters)
return;
@@ -1234,8 +1230,7 @@ static void rtl8169_update_counters(struct net_device *dev)
RTL_W32(CounterAddrLow, 0);
RTL_W32(CounterAddrHigh, 0);
- dma_free_coherent(&tp->pci_dev->dev, sizeof(*counters), counters,
- paddr);
+ dma_free_coherent(d, sizeof(*counters), counters, paddr);
}
static void rtl8169_get_ethtool_stats(struct net_device *dev,
@@ -3188,9 +3183,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
#ifdef CONFIG_R8169_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
#endif
+ dev->features |= NETIF_F_GRO;
tp->intr_mask = 0xffff;
- tp->align = cfg->align;
tp->hw_start = cfg->hw_start;
tp->intr_event = cfg->intr_event;
tp->napi_event = cfg->napi_event;
@@ -3260,18 +3255,6 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
-static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
- unsigned int mtu)
-{
- unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
-
- if (max_frame != 16383)
- printk(KERN_WARNING PFX "WARNING! Changing of MTU on this "
- "NIC may lead to frame reception errors!\n");
-
- tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
-}
-
static int rtl8169_open(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -3281,18 +3264,6 @@ static int rtl8169_open(struct net_device *dev)
pm_runtime_get_sync(&pdev->dev);
/*
- * Note that we use a magic value here, its wierd I know
- * its done because, some subset of rtl8169 hardware suffers from
- * a problem in which frames received that are longer than
- * the size set in RxMaxSize register return garbage sizes
- * when received. To avoid this we need to turn off filtering,
- * which is done by setting a value of 16383 in the RxMaxSize register
- * and allocating 16k frames to handle the largest possible rx value
- * thats what the magic math below does.
- */
- rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN);
-
- /*
* Rx and Tx desscriptors needs 256 bytes alignment.
* dma_alloc_coherent provides more.
*/
@@ -3468,7 +3439,7 @@ static void rtl_hw_start_8169(struct net_device *dev)
RTL_W8(EarlyTxThres, EarlyTxThld);
- rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
+ 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) ||
@@ -3729,7 +3700,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
RTL_W8(EarlyTxThres, EarlyTxThld);
- rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
+ rtl_set_rx_max_size(ioaddr, rx_buf_sz);
tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
@@ -3909,7 +3880,7 @@ static void rtl_hw_start_8101(struct net_device *dev)
RTL_W8(EarlyTxThres, EarlyTxThld);
- rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
+ rtl_set_rx_max_size(ioaddr, rx_buf_sz);
tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
@@ -3937,33 +3908,11 @@ static void rtl_hw_start_8101(struct net_device *dev)
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
{
- struct rtl8169_private *tp = netdev_priv(dev);
- int ret = 0;
-
if (new_mtu < ETH_ZLEN || new_mtu > SafeMtu)
return -EINVAL;
dev->mtu = new_mtu;
-
- if (!netif_running(dev))
- goto out;
-
- rtl8169_down(dev);
-
- rtl8169_set_rxbufsize(tp, dev->mtu);
-
- ret = rtl8169_init_ring(dev);
- if (ret < 0)
- goto out;
-
- napi_enable(&tp->napi);
-
- rtl_hw_start(dev);
-
- rtl8169_request_timer(dev);
-
-out:
- return ret;
+ return 0;
}
static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc)
@@ -3972,15 +3921,14 @@ static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc)
desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask);
}
-static void rtl8169_free_rx_skb(struct rtl8169_private *tp,
- struct sk_buff **sk_buff, struct RxDesc *desc)
+static void rtl8169_free_rx_databuff(struct rtl8169_private *tp,
+ void **data_buff, struct RxDesc *desc)
{
- struct pci_dev *pdev = tp->pci_dev;
+ dma_unmap_single(&tp->pci_dev->dev, le64_to_cpu(desc->addr), rx_buf_sz,
+ DMA_FROM_DEVICE);
- dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), tp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
- dev_kfree_skb(*sk_buff);
- *sk_buff = NULL;
+ kfree(*data_buff);
+ *data_buff = NULL;
rtl8169_make_unusable_by_asic(desc);
}
@@ -3999,33 +3947,45 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
rtl8169_mark_to_asic(desc, rx_buf_sz);
}
-static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev,
- struct net_device *dev,
- struct RxDesc *desc, int rx_buf_sz,
- unsigned int align, gfp_t gfp)
+static inline void *rtl8169_align(void *data)
{
- struct sk_buff *skb;
- dma_addr_t mapping;
- unsigned int pad;
+ return (void *)ALIGN((long)data, 16);
+}
- pad = align ? align : NET_IP_ALIGN;
+static struct sk_buff *rtl8169_alloc_rx_data(struct rtl8169_private *tp,
+ struct RxDesc *desc)
+{
+ void *data;
+ dma_addr_t mapping;
+ struct device *d = &tp->pci_dev->dev;
+ struct net_device *dev = tp->dev;
+ int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
- skb = __netdev_alloc_skb(dev, rx_buf_sz + pad, gfp);
- if (!skb)
- goto err_out;
+ data = kmalloc_node(rx_buf_sz, GFP_KERNEL, node);
+ if (!data)
+ return NULL;
- skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad);
+ if (rtl8169_align(data) != data) {
+ kfree(data);
+ data = kmalloc_node(rx_buf_sz + 15, GFP_KERNEL, node);
+ if (!data)
+ return NULL;
+ }
- mapping = dma_map_single(&pdev->dev, skb->data, rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ mapping = dma_map_single(d, rtl8169_align(data), rx_buf_sz,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(d, mapping))) {
+ if (net_ratelimit())
+ netif_err(tp, drv, tp->dev, "Failed to map RX DMA!\n");
+ goto err_out;
+ }
rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
-out:
- return skb;
+ return data;
err_out:
- rtl8169_make_unusable_by_asic(desc);
- goto out;
+ kfree(data);
+ return NULL;
}
static void rtl8169_rx_clear(struct rtl8169_private *tp)
@@ -4033,41 +3993,42 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp)
unsigned int i;
for (i = 0; i < NUM_RX_DESC; i++) {
- if (tp->Rx_skbuff[i]) {
- rtl8169_free_rx_skb(tp, tp->Rx_skbuff + i,
+ if (tp->Rx_databuff[i]) {
+ rtl8169_free_rx_databuff(tp, tp->Rx_databuff + i,
tp->RxDescArray + i);
}
}
}
-static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
- u32 start, u32 end, gfp_t gfp)
+static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
{
- u32 cur;
+ desc->opts1 |= cpu_to_le32(RingEnd);
+}
- for (cur = start; end - cur != 0; cur++) {
- struct sk_buff *skb;
- unsigned int i = cur % NUM_RX_DESC;
+static int rtl8169_rx_fill(struct rtl8169_private *tp)
+{
+ unsigned int i;
- WARN_ON((s32)(end - cur) < 0);
+ for (i = 0; i < NUM_RX_DESC; i++) {
+ void *data;
- if (tp->Rx_skbuff[i])
+ if (tp->Rx_databuff[i])
continue;
- skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev,
- tp->RxDescArray + i,
- tp->rx_buf_sz, tp->align, gfp);
- if (!skb)
- break;
-
- tp->Rx_skbuff[i] = skb;
+ data = rtl8169_alloc_rx_data(tp, tp->RxDescArray + i);
+ if (!data) {
+ rtl8169_make_unusable_by_asic(tp->RxDescArray + i);
+ goto err_out;
+ }
+ tp->Rx_databuff[i] = data;
}
- return cur - start;
-}
-static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
-{
- desc->opts1 |= cpu_to_le32(RingEnd);
+ rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1);
+ return 0;
+
+err_out:
+ rtl8169_rx_clear(tp);
+ return -ENOMEM;
}
static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
@@ -4082,54 +4043,51 @@ static int rtl8169_init_ring(struct net_device *dev)
rtl8169_init_ring_indexes(tp);
memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info));
- memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
-
- if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, GFP_KERNEL) != NUM_RX_DESC)
- goto err_out;
-
- rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1);
-
- return 0;
+ memset(tp->Rx_databuff, 0x0, NUM_RX_DESC * sizeof(void *));
-err_out:
- rtl8169_rx_clear(tp);
- return -ENOMEM;
+ return rtl8169_rx_fill(tp);
}
-static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb,
+static void rtl8169_unmap_tx_skb(struct device *d, struct ring_info *tx_skb,
struct TxDesc *desc)
{
unsigned int len = tx_skb->len;
- dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(d, le64_to_cpu(desc->addr), len, DMA_TO_DEVICE);
+
desc->opts1 = 0x00;
desc->opts2 = 0x00;
desc->addr = 0x00;
tx_skb->len = 0;
}
-static void rtl8169_tx_clear(struct rtl8169_private *tp)
+static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
+ unsigned int n)
{
unsigned int i;
- for (i = tp->dirty_tx; i < tp->dirty_tx + NUM_TX_DESC; i++) {
- unsigned int entry = i % NUM_TX_DESC;
+ for (i = 0; i < n; i++) {
+ unsigned int entry = (start + i) % NUM_TX_DESC;
struct ring_info *tx_skb = tp->tx_skb + entry;
unsigned int len = tx_skb->len;
if (len) {
struct sk_buff *skb = tx_skb->skb;
- rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb,
+ rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
tp->TxDescArray + entry);
if (skb) {
+ tp->dev->stats.tx_dropped++;
dev_kfree_skb(skb);
tx_skb->skb = NULL;
}
- tp->dev->stats.tx_dropped++;
}
}
+}
+
+static void rtl8169_tx_clear(struct rtl8169_private *tp)
+{
+ rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
tp->cur_tx = tp->dirty_tx = 0;
}
@@ -4233,6 +4191,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
struct skb_shared_info *info = skb_shinfo(skb);
unsigned int cur_frag, entry;
struct TxDesc * uninitialized_var(txd);
+ struct device *d = &tp->pci_dev->dev;
entry = tp->cur_tx;
for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) {
@@ -4246,8 +4205,13 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
txd = tp->TxDescArray + entry;
len = frag->size;
addr = ((void *) page_address(frag->page)) + frag->page_offset;
- mapping = dma_map_single(&tp->pci_dev->dev, addr, len,
- PCI_DMA_TODEVICE);
+ mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(d, mapping))) {
+ if (net_ratelimit())
+ netif_err(tp, drv, tp->dev,
+ "Failed to map TX fragments DMA!\n");
+ goto err_out;
+ }
/* anti gcc 2.95.3 bugware (sic) */
status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
@@ -4264,6 +4228,10 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
}
return cur_frag;
+
+err_out:
+ rtl8169_tx_clear_range(tp, tp->cur_tx + 1, cur_frag);
+ return -EIO;
}
static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
@@ -4290,40 +4258,47 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
- unsigned int frags, entry = tp->cur_tx % NUM_TX_DESC;
+ unsigned int entry = tp->cur_tx % NUM_TX_DESC;
struct TxDesc *txd = tp->TxDescArray + entry;
void __iomem *ioaddr = tp->mmio_addr;
+ struct device *d = &tp->pci_dev->dev;
dma_addr_t mapping;
u32 status, len;
u32 opts1;
+ int frags;
if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n");
- goto err_stop;
+ goto err_stop_0;
}
if (unlikely(le32_to_cpu(txd->opts1) & DescOwn))
- goto err_stop;
+ goto err_stop_0;
+
+ len = skb_headlen(skb);
+ mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(d, mapping))) {
+ if (net_ratelimit())
+ netif_err(tp, drv, dev, "Failed to map TX DMA!\n");
+ goto err_dma_0;
+ }
+
+ 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);
frags = rtl8169_xmit_frags(tp, skb, opts1);
- if (frags) {
- len = skb_headlen(skb);
+ if (frags < 0)
+ goto err_dma_1;
+ else if (frags)
opts1 |= FirstFrag;
- } else {
- len = skb->len;
+ else {
opts1 |= FirstFrag | LastFrag;
tp->tx_skb[entry].skb = skb;
}
- mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len,
- PCI_DMA_TODEVICE);
-
- tp->tx_skb[entry].len = len;
- txd->addr = cpu_to_le64(mapping);
- txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb));
-
wmb();
/* anti gcc 2.95.3 bugware (sic) */
@@ -4345,7 +4320,14 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
-err_stop:
+err_dma_1:
+ rtl8169_unmap_tx_skb(d, tp->tx_skb + entry, txd);
+err_dma_0:
+ dev_kfree_skb(skb);
+ dev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
+
+err_stop_0:
netif_stop_queue(dev);
dev->stats.tx_dropped++;
return NETDEV_TX_BUSY;
@@ -4410,7 +4392,6 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
while (tx_left > 0) {
unsigned int entry = dirty_tx % NUM_TX_DESC;
struct ring_info *tx_skb = tp->tx_skb + entry;
- u32 len = tx_skb->len;
u32 status;
rmb();
@@ -4418,12 +4399,11 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
if (status & DescOwn)
break;
- dev->stats.tx_bytes += len;
- dev->stats.tx_packets++;
-
- rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
-
+ rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
+ tp->TxDescArray + entry);
if (status & LastFrag) {
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += tx_skb->skb->len;
dev_kfree_skb(tx_skb->skb);
tx_skb->skb = NULL;
}
@@ -4455,9 +4435,8 @@ static inline int rtl8169_fragmented_frame(u32 status)
return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag);
}
-static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
+static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1)
{
- u32 opts1 = le32_to_cpu(desc->opts1);
u32 status = opts1 & RxProtoMask;
if (((status == RxProtoTCP) && !(opts1 & TCPFail)) ||
@@ -4465,30 +4444,26 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
((status == RxProtoIP) && !(opts1 & IPFail)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
-static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff,
- struct rtl8169_private *tp, int pkt_size,
- dma_addr_t addr)
+static struct sk_buff *rtl8169_try_rx_copy(void *data,
+ struct rtl8169_private *tp,
+ int pkt_size,
+ dma_addr_t addr)
{
struct sk_buff *skb;
- bool done = false;
-
- if (pkt_size >= rx_copybreak)
- goto out;
+ struct device *d = &tp->pci_dev->dev;
+ data = rtl8169_align(data);
+ dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE);
+ prefetch(data);
skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size);
- if (!skb)
- goto out;
+ if (skb)
+ memcpy(skb->data, data, pkt_size);
+ dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
- dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, pkt_size,
- PCI_DMA_FROMDEVICE);
- skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size);
- *sk_buff = skb;
- done = true;
-out:
- return done;
+ return skb;
}
/*
@@ -4503,7 +4478,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
void __iomem *ioaddr, u32 budget)
{
unsigned int cur_rx, rx_left;
- unsigned int delta, count;
+ unsigned int count;
int polling = (budget != ~(u32)0) ? 1 : 0;
cur_rx = tp->cur_rx;
@@ -4532,12 +4507,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
rtl8169_schedule_work(dev, rtl8169_reset_task);
dev->stats.rx_fifo_errors++;
}
- rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
+ rtl8169_mark_to_asic(desc, rx_buf_sz);
} else {
- struct sk_buff *skb = tp->Rx_skbuff[entry];
+ struct sk_buff *skb;
dma_addr_t addr = le64_to_cpu(desc->addr);
int pkt_size = (status & 0x00001FFF) - 4;
- struct pci_dev *pdev = tp->pci_dev;
/*
* The driver does not support incoming fragmented
@@ -4547,28 +4521,25 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
if (unlikely(rtl8169_fragmented_frame(status))) {
dev->stats.rx_dropped++;
dev->stats.rx_length_errors++;
- rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
+ rtl8169_mark_to_asic(desc, rx_buf_sz);
continue;
}
- rtl8169_rx_csum(skb, desc);
-
- if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) {
- dma_sync_single_for_device(&pdev->dev, addr,
- pkt_size, PCI_DMA_FROMDEVICE);
- rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
- } else {
- dma_unmap_single(&pdev->dev, addr, tp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
- tp->Rx_skbuff[entry] = NULL;
+ skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry],
+ tp, pkt_size, addr);
+ rtl8169_mark_to_asic(desc, rx_buf_sz);
+ if (!skb) {
+ dev->stats.rx_dropped++;
+ continue;
}
+ rtl8169_rx_csum(skb, status);
skb_put(skb, pkt_size);
skb->protocol = eth_type_trans(skb, dev);
if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) {
if (likely(polling))
- netif_receive_skb(skb);
+ napi_gro_receive(&tp->napi, skb);
else
netif_rx(skb);
}
@@ -4588,20 +4559,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
count = cur_rx - tp->cur_rx;
tp->cur_rx = cur_rx;
- delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx, GFP_ATOMIC);
- if (!delta && count)
- netif_info(tp, intr, dev, "no Rx buffer allocated\n");
- tp->dirty_rx += delta;
-
- /*
- * FIXME: until there is periodic timer to try and refill the ring,
- * a temporary shortage may definitely kill the Rx process.
- * - disable the asic to try and avoid an overflow and kick it again
- * after refill ?
- * - how do others driver handle this condition (Uh oh...).
- */
- if (tp->dirty_rx + NUM_RX_DESC == tp->cur_rx)
- netif_emerg(tp, intr, dev, "Rx buffers exhausted\n");
+ tp->dirty_rx += count;
return count;
}
@@ -4716,7 +4674,6 @@ static void rtl8169_down(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
- unsigned int intrmask;
rtl8169_delete_timer(dev);
@@ -4724,11 +4681,14 @@ static void rtl8169_down(struct net_device *dev)
napi_disable(&tp->napi);
-core_down:
spin_lock_irq(&tp->lock);
rtl8169_asic_down(ioaddr);
-
+ /*
+ * At this point device interrupts can not be enabled in any function,
+ * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task,
+ * rtl8169_reinit_task) and napi is disabled (rtl8169_poll).
+ */
rtl8169_rx_missed(dev, ioaddr);
spin_unlock_irq(&tp->lock);
@@ -4738,23 +4698,6 @@ core_down:
/* Give a racing hard_start_xmit a few cycles to complete. */
synchronize_sched(); /* FIXME: should this be synchronize_irq()? */
- /*
- * And now for the 50k$ question: are IRQ disabled or not ?
- *
- * Two paths lead here:
- * 1) dev->close
- * -> netif_running() is available to sync the current code and the
- * IRQ handler. See rtl8169_interrupt for details.
- * 2) dev->change_mtu
- * -> rtl8169_poll can not be issued again and re-enable the
- * interruptions. Let's simply issue the IRQ down sequence again.
- *
- * No loop if hotpluged or major error (0xffff).
- */
- intrmask = RTL_R16(IntrMask);
- if (intrmask && (intrmask != 0xffff))
- goto core_down;
-
rtl8169_tx_clear(tp);
rtl8169_rx_clear(tp);
@@ -4891,6 +4834,9 @@ static int rtl8169_resume(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+ rtl8169_init_phy(dev, tp);
if (netif_running(dev))
__rtl8169_resume(dev);
@@ -4931,6 +4877,8 @@ static int rtl8169_runtime_resume(struct device *device)
tp->saved_wolopts = 0;
spin_unlock_irq(&tp->lock);
+ rtl8169_init_phy(dev, tp);
+
__rtl8169_resume(dev);
return 0;
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index e26e107f93e0..e68c941926f1 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -1245,7 +1245,7 @@ static int rr_open(struct net_device *dev)
init_timer(&rrpriv->timer);
rrpriv->timer.expires = RUN_AT(5*HZ); /* 5 sec. watchdog */
rrpriv->timer.data = (unsigned long)dev;
- rrpriv->timer.function = &rr_timer; /* timer handler */
+ rrpriv->timer.function = rr_timer; /* timer handler */
add_timer(&rrpriv->timer);
netif_start_queue(dev);
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 18bc5b718bbb..ecc25aab896a 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -38,8 +38,6 @@
* Tx descriptors that can be associated with each corresponding FIFO.
* intr_type: This defines the type of interrupt. The values can be 0(INTA),
* 2(MSI_X). Default value is '2(MSI_X)'
- * lro: Specifies whether to enable Large Receive Offload (LRO) or not.
- * Possible values '1' for enable '0' for disable. Default is '0'
* lro_max_pkts: This parameter defines maximum number of packets can be
* aggregated as a single large packet
* napi: This parameter used to enable/disable NAPI (polling Rx)
@@ -90,7 +88,7 @@
#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.26.26"
+#define DRV_VERSION "2.0.26.27"
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
@@ -496,8 +494,6 @@ S2IO_PARM_INT(rxsync_frequency, 3);
/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
S2IO_PARM_INT(intr_type, 2);
/* Large receive offload feature */
-static unsigned int lro_enable = 1;
-module_param_named(lro, lro_enable, uint, 0);
/* Max pkts to be aggregated by LRO at one time. If not specified,
* aggregation happens until we hit max IP pkt size(64K)
@@ -4105,7 +4101,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev)
}
queue = 0;
- if (sp->vlgrp && vlan_tx_tag_present(skb))
+ if (vlan_tx_tag_present(skb))
vlan_tag = vlan_tx_tag_get(skb);
if (sp->config.tx_steering_type == TX_DEFAULT_STEERING) {
if (skb->protocol == htons(ETH_P_IP)) {
@@ -5124,8 +5120,6 @@ static void s2io_set_multicast(struct net_device *dev)
/* Create the new Rx filter list and update the same in H/W. */
i = 0;
netdev_for_each_mc_addr(ha, dev) {
- memcpy(sp->usr_addrs[i].addr, ha->addr,
- ETH_ALEN);
mac_addr = 0;
for (j = 0; j < ETH_ALEN; j++) {
mac_addr |= ha->addr[j];
@@ -6735,13 +6729,10 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
return -EINVAL;
if (data & ETH_FLAG_LRO) {
- if (lro_enable) {
- if (!(dev->features & NETIF_F_LRO)) {
- dev->features |= NETIF_F_LRO;
- changed = 1;
- }
- } else
- rc = -EINVAL;
+ 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;
@@ -6750,7 +6741,6 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
if (changed && netif_running(dev)) {
s2io_stop_all_tx_queue(sp);
s2io_card_down(sp);
- sp->lro = !!(dev->features & NETIF_F_LRO);
rc = s2io_card_up(sp);
if (rc)
s2io_reset(sp);
@@ -7307,7 +7297,7 @@ static int s2io_card_up(struct s2io_nic *sp)
struct ring_info *ring = &mac_control->rings[i];
ring->mtu = dev->mtu;
- ring->lro = sp->lro;
+ ring->lro = !!(dev->features & NETIF_F_LRO);
ret = fill_rx_buffers(sp, ring, 1);
if (ret) {
DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
@@ -7341,7 +7331,7 @@ static int s2io_card_up(struct s2io_nic *sp)
/* Setting its receive mode */
s2io_set_multicast(dev);
- if (sp->lro) {
+ if (dev->features & NETIF_F_LRO) {
/* Initialize max aggregatable pkts per session based on MTU */
sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu;
/* Check if we can use (if specified) user provided value */
@@ -7613,10 +7603,10 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
* Packet with erroneous checksum, let the
* upper layers deal with it.
*/
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
swstats->mem_freed += skb->truesize;
send_up:
@@ -7911,7 +7901,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
else
sp->device_type = XFRAME_I_DEVICE;
- sp->lro = lro_enable;
/* Initialize some PCI/PCI-X fields of the NIC. */
s2io_init_pci(sp);
@@ -8047,8 +8036,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
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;
- if (lro_enable)
- dev->features |= NETIF_F_LRO;
+ dev->features |= NETIF_F_LRO;
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
if (sp->high_dma_flag == true)
dev->features |= NETIF_F_HIGHDMA;
@@ -8283,9 +8271,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
dev->name);
}
- if (sp->lro)
- DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
- dev->name);
+ DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
+ dev->name);
if (ufo)
DBG_PRINT(ERR_DBG,
"%s: UDP Fragmentation Offload(UFO) enabled\n",
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 0af033533905..00b8614efe48 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -816,12 +816,6 @@ struct mac_info {
struct stat_block *stats_info; /* Logical address of the stat block */
};
-/* structure representing the user defined MAC addresses */
-struct usr_addr {
- char addr[ETH_ALEN];
- int usage_cnt;
-};
-
/* Default Tunable parameters of the NIC. */
#define DEFAULT_FIFO_0_LEN 4096
#define DEFAULT_FIFO_1_7_LEN 512
@@ -894,9 +888,7 @@ struct s2io_nic {
#define ALL_MULTI 2
#define MAX_ADDRS_SUPPORTED 64
- u16 usr_addr_count;
u16 mc_addr_count;
- struct usr_addr usr_addrs[256];
u16 m_cast_flg;
u16 all_multi_pos;
@@ -971,7 +963,6 @@ struct s2io_nic {
unsigned long clubbed_frms_cnt;
unsigned long sending_both;
- u8 lro;
u16 lro_max_aggr_per_sess;
volatile unsigned long state;
u64 general_int_mask;
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 8e6bd45b9f31..d8249d7653c6 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -1170,7 +1170,7 @@ again:
sb->ip_summed = CHECKSUM_UNNECESSARY;
/* don't need to set sb->csum */
} else {
- sb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(sb);
}
}
prefetch(sb->data);
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 8c4067af32b0..31b92f5f32cb 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -1251,16 +1251,6 @@ static int sc92031_ethtool_set_settings(struct net_device *dev,
return 0;
}
-static void sc92031_ethtool_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *drvinfo)
-{
- struct sc92031_priv *priv = netdev_priv(dev);
- struct pci_dev *pdev = priv->pdev;
-
- strcpy(drvinfo->driver, SC92031_NAME);
- strcpy(drvinfo->bus_info, pci_name(pdev));
-}
-
static void sc92031_ethtool_get_wol(struct net_device *dev,
struct ethtool_wolinfo *wolinfo)
{
@@ -1382,7 +1372,6 @@ static void sc92031_ethtool_get_ethtool_stats(struct net_device *dev,
static const struct ethtool_ops sc92031_ethtool_ops = {
.get_settings = sc92031_ethtool_get_settings,
.set_settings = sc92031_ethtool_set_settings,
- .get_drvinfo = sc92031_ethtool_get_drvinfo,
.get_wol = sc92031_ethtool_get_wol,
.set_wol = sc92031_ethtool_set_wol,
.nway_reset = sc92031_ethtool_nway_reset,
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index 1047b19c60a5..ab31c7124db1 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -1,7 +1,8 @@
-sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o \
- falcon_gmac.o falcon_xmac.o mcdi_mac.o \
+sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \
+ falcon_xmac.o mcdi_mac.o \
selftest.o ethtool.o qt202x_phy.o mdio_10g.o \
- tenxpress.o falcon_boards.o mcdi.o mcdi_phy.o
+ tenxpress.o txc43128_phy.o falcon_boards.o \
+ mcdi.o mcdi_phy.o
sfc-$(CONFIG_SFC_MTD) += mtd.o
obj-$(CONFIG_SFC) += sfc.o
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index ba674c5ca29e..05df20e47976 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -68,14 +68,6 @@ const char *efx_loopback_mode_names[] = {
[LOOPBACK_PHYXS_WS] = "PHYXS_WS",
};
-/* Interrupt mode names (see INT_MODE())) */
-const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX;
-const char *efx_interrupt_mode_names[] = {
- [EFX_INT_MODE_MSIX] = "MSI-X",
- [EFX_INT_MODE_MSI] = "MSI",
- [EFX_INT_MODE_LEGACY] = "legacy",
-};
-
const unsigned int efx_reset_type_max = RESET_TYPE_MAX;
const char *efx_reset_type_names[] = {
[RESET_TYPE_INVISIBLE] = "INVISIBLE",
@@ -114,7 +106,7 @@ static struct workqueue_struct *reset_workqueue;
* This is only used in MSI-X interrupt mode
*/
static unsigned int separate_tx_channels;
-module_param(separate_tx_channels, uint, 0644);
+module_param(separate_tx_channels, uint, 0444);
MODULE_PARM_DESC(separate_tx_channels,
"Use separate channels for TX and RX");
@@ -124,10 +116,11 @@ MODULE_PARM_DESC(separate_tx_channels,
static int napi_weight = 64;
/* This is the time (in jiffies) between invocations of the hardware
- * monitor, which checks for known hardware bugs and resets the
- * hardware and driver as necessary.
+ * monitor. On Falcon-based NICs, this will:
+ * - Check the on-board hardware monitor;
+ * - Poll the link state and reconfigure the hardware as necessary.
*/
-unsigned int efx_monitor_interval = 1 * HZ;
+static unsigned int efx_monitor_interval = 1 * HZ;
/* This controls whether or not the driver will initialise devices
* with invalid MAC addresses stored in the EEPROM or flash. If true,
@@ -201,10 +194,13 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
* Utility functions and prototypes
*
*************************************************************************/
-static void efx_remove_channel(struct efx_channel *channel);
+
+static void efx_remove_channels(struct efx_nic *efx);
static void efx_remove_port(struct efx_nic *efx);
static void efx_fini_napi(struct efx_nic *efx);
-static void efx_fini_channels(struct efx_nic *efx);
+static void efx_fini_struct(struct efx_nic *efx);
+static void efx_start_all(struct efx_nic *efx);
+static void efx_stop_all(struct efx_nic *efx);
#define EFX_ASSERT_RESET_SERIALISED(efx) \
do { \
@@ -248,7 +244,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
efx_rx_strategy(channel);
- efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
+ efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel));
return spent;
}
@@ -334,6 +330,7 @@ void efx_process_channel_now(struct efx_channel *channel)
{
struct efx_nic *efx = channel->efx;
+ BUG_ON(channel->channel >= efx->n_channels);
BUG_ON(!channel->enabled);
/* Disable interrupts and wait for ISRs to complete */
@@ -347,7 +344,7 @@ void efx_process_channel_now(struct efx_channel *channel)
napi_disable(&channel->napi_str);
/* Poll the channel */
- efx_process_channel(channel, EFX_EVQ_SIZE);
+ efx_process_channel(channel, channel->eventq_mask + 1);
/* Ack the eventq. This may cause an interrupt to be generated
* when they are reenabled */
@@ -364,9 +361,18 @@ void efx_process_channel_now(struct efx_channel *channel)
*/
static int efx_probe_eventq(struct efx_channel *channel)
{
+ struct efx_nic *efx = channel->efx;
+ unsigned long entries;
+
netif_dbg(channel->efx, probe, channel->efx->net_dev,
"chan %d create event queue\n", channel->channel);
+ /* Build an event queue with room for one event per tx and rx buffer,
+ * plus some extra for link state events and MCDI completions. */
+ entries = roundup_pow_of_two(efx->rxq_entries + efx->txq_entries + 128);
+ EFX_BUG_ON_PARANOID(entries > EFX_MAX_EVQ_SIZE);
+ channel->eventq_mask = max(entries, EFX_MIN_EVQ_SIZE) - 1;
+
return efx_nic_probe_eventq(channel);
}
@@ -403,6 +409,63 @@ static void efx_remove_eventq(struct efx_channel *channel)
*
*************************************************************************/
+/* Allocate and initialise a channel structure, optionally copying
+ * parameters (but not resources) from an old channel structure. */
+static struct efx_channel *
+efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
+{
+ struct efx_channel *channel;
+ struct efx_rx_queue *rx_queue;
+ struct efx_tx_queue *tx_queue;
+ int j;
+
+ if (old_channel) {
+ channel = kmalloc(sizeof(*channel), GFP_KERNEL);
+ if (!channel)
+ return NULL;
+
+ *channel = *old_channel;
+
+ memset(&channel->eventq, 0, sizeof(channel->eventq));
+
+ rx_queue = &channel->rx_queue;
+ rx_queue->buffer = NULL;
+ memset(&rx_queue->rxd, 0, sizeof(rx_queue->rxd));
+
+ for (j = 0; j < EFX_TXQ_TYPES; j++) {
+ tx_queue = &channel->tx_queue[j];
+ if (tx_queue->channel)
+ tx_queue->channel = channel;
+ tx_queue->buffer = NULL;
+ memset(&tx_queue->txd, 0, sizeof(tx_queue->txd));
+ }
+ } else {
+ channel = kzalloc(sizeof(*channel), GFP_KERNEL);
+ if (!channel)
+ return NULL;
+
+ channel->efx = efx;
+ channel->channel = i;
+
+ for (j = 0; j < EFX_TXQ_TYPES; j++) {
+ tx_queue = &channel->tx_queue[j];
+ tx_queue->efx = efx;
+ tx_queue->queue = i * EFX_TXQ_TYPES + j;
+ tx_queue->channel = channel;
+ }
+ }
+
+ spin_lock_init(&channel->tx_stop_lock);
+ atomic_set(&channel->tx_stop_count, 1);
+
+ rx_queue = &channel->rx_queue;
+ rx_queue->efx = efx;
+ setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill,
+ (unsigned long)rx_queue);
+
+ return channel;
+}
+
static int efx_probe_channel(struct efx_channel *channel)
{
struct efx_tx_queue *tx_queue;
@@ -459,11 +522,38 @@ static void efx_set_channel_names(struct efx_nic *efx)
number -= efx->n_rx_channels;
}
}
- snprintf(channel->name, sizeof(channel->name),
+ snprintf(efx->channel_name[channel->channel],
+ sizeof(efx->channel_name[0]),
"%s%s-%d", efx->name, type, number);
}
}
+static int efx_probe_channels(struct efx_nic *efx)
+{
+ struct efx_channel *channel;
+ int rc;
+
+ /* Restart special buffer allocation */
+ efx->next_buffer_table = 0;
+
+ efx_for_each_channel(channel, efx) {
+ rc = efx_probe_channel(channel);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "failed to create channel %d\n",
+ channel->channel);
+ goto fail;
+ }
+ }
+ efx_set_channel_names(efx);
+
+ return 0;
+
+fail:
+ efx_remove_channels(efx);
+ return rc;
+}
+
/* Channels are shutdown and reinitialised whilst the NIC is running
* to propagate configuration changes (mtu, checksum offload), or
* to clear hardware error conditions
@@ -601,6 +691,75 @@ static void efx_remove_channel(struct efx_channel *channel)
efx_remove_eventq(channel);
}
+static void efx_remove_channels(struct efx_nic *efx)
+{
+ struct efx_channel *channel;
+
+ efx_for_each_channel(channel, efx)
+ efx_remove_channel(channel);
+}
+
+int
+efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
+{
+ struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel;
+ u32 old_rxq_entries, old_txq_entries;
+ unsigned i;
+ int rc;
+
+ efx_stop_all(efx);
+ efx_fini_channels(efx);
+
+ /* Clone channels */
+ memset(other_channel, 0, sizeof(other_channel));
+ for (i = 0; i < efx->n_channels; i++) {
+ channel = efx_alloc_channel(efx, i, efx->channel[i]);
+ if (!channel) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ other_channel[i] = channel;
+ }
+
+ /* Swap entry counts and channel pointers */
+ old_rxq_entries = efx->rxq_entries;
+ old_txq_entries = efx->txq_entries;
+ efx->rxq_entries = rxq_entries;
+ efx->txq_entries = txq_entries;
+ for (i = 0; i < efx->n_channels; i++) {
+ channel = efx->channel[i];
+ efx->channel[i] = other_channel[i];
+ other_channel[i] = channel;
+ }
+
+ rc = efx_probe_channels(efx);
+ if (rc)
+ goto rollback;
+
+ /* Destroy old channels */
+ for (i = 0; i < efx->n_channels; i++)
+ efx_remove_channel(other_channel[i]);
+out:
+ /* Free unused channel structures */
+ for (i = 0; i < efx->n_channels; i++)
+ kfree(other_channel[i]);
+
+ efx_init_channels(efx);
+ efx_start_all(efx);
+ return rc;
+
+rollback:
+ /* Swap back */
+ efx->rxq_entries = old_rxq_entries;
+ efx->txq_entries = old_txq_entries;
+ for (i = 0; i < efx->n_channels; i++) {
+ channel = efx->channel[i];
+ efx->channel[i] = other_channel[i];
+ other_channel[i] = channel;
+ }
+ goto out;
+}
+
void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue)
{
mod_timer(&rx_queue->slow_fill, jiffies + msecs_to_jiffies(100));
@@ -761,7 +920,7 @@ static int efx_probe_port(struct efx_nic *efx)
/* Connect up MAC/PHY operations table */
rc = efx->type->probe_port(efx);
if (rc)
- goto err;
+ return rc;
/* Sanity check MAC address */
if (is_valid_ether_addr(efx->mac_address)) {
@@ -782,7 +941,7 @@ static int efx_probe_port(struct efx_nic *efx)
return 0;
err:
- efx_remove_port(efx);
+ efx->type->remove_port(efx);
return rc;
}
@@ -1050,7 +1209,8 @@ static void efx_probe_interrupts(struct efx_nic *efx)
efx->n_rx_channels = efx->n_channels;
}
for (i = 0; i < n_channels; i++)
- efx->channel[i].irq = xentries[i].vector;
+ efx_get_channel(efx, i)->irq =
+ xentries[i].vector;
} else {
/* Fall back to single channel MSI */
efx->interrupt_mode = EFX_INT_MODE_MSI;
@@ -1066,7 +1226,7 @@ static void efx_probe_interrupts(struct efx_nic *efx)
efx->n_tx_channels = 1;
rc = pci_enable_msi(efx->pci_dev);
if (rc == 0) {
- efx->channel[0].irq = efx->pci_dev->irq;
+ efx_get_channel(efx, 0)->irq = efx->pci_dev->irq;
} else {
netif_err(efx, drv, efx->net_dev,
"could not enable MSI\n");
@@ -1097,26 +1257,32 @@ static void efx_remove_interrupts(struct efx_nic *efx)
efx->legacy_irq = 0;
}
+struct efx_tx_queue *
+efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
+{
+ unsigned tx_channel_offset =
+ separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0;
+ EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels ||
+ type >= EFX_TXQ_TYPES);
+ return &efx->channel[tx_channel_offset + index]->tx_queue[type];
+}
+
static void efx_set_channels(struct efx_nic *efx)
{
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
- struct efx_rx_queue *rx_queue;
unsigned tx_channel_offset =
separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0;
+ /* Channel pointers were set in efx_init_struct() but we now
+ * need to clear them for TX queues in any RX-only channels. */
efx_for_each_channel(channel, efx) {
- if (channel->channel - tx_channel_offset < efx->n_tx_channels) {
- channel->tx_queue = &efx->tx_queue[
- (channel->channel - tx_channel_offset) *
- EFX_TXQ_TYPES];
+ if (channel->channel - tx_channel_offset >=
+ efx->n_tx_channels) {
efx_for_each_channel_tx_queue(tx_queue, channel)
- tx_queue->channel = channel;
+ tx_queue->channel = NULL;
}
}
-
- efx_for_each_rx_queue(rx_queue, efx)
- rx_queue->channel = &efx->channel[rx_queue->queue];
}
static int efx_probe_nic(struct efx_nic *efx)
@@ -1141,7 +1307,8 @@ static int efx_probe_nic(struct efx_nic *efx)
efx->rx_indir_table[i] = i % efx->n_rx_channels;
efx_set_channels(efx);
- efx->net_dev->real_num_tx_queues = efx->n_tx_channels;
+ netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels);
+ netif_set_real_num_rx_queues(efx->net_dev, efx->n_rx_channels);
/* Initialise the interrupt moderation settings */
efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true);
@@ -1165,40 +1332,37 @@ static void efx_remove_nic(struct efx_nic *efx)
static int efx_probe_all(struct efx_nic *efx)
{
- struct efx_channel *channel;
int rc;
- /* Create NIC */
rc = efx_probe_nic(efx);
if (rc) {
netif_err(efx, probe, efx->net_dev, "failed to create NIC\n");
goto fail1;
}
- /* Create port */
rc = efx_probe_port(efx);
if (rc) {
netif_err(efx, probe, efx->net_dev, "failed to create port\n");
goto fail2;
}
- /* Create channels */
- efx_for_each_channel(channel, efx) {
- rc = efx_probe_channel(channel);
- if (rc) {
- netif_err(efx, probe, efx->net_dev,
- "failed to create channel %d\n",
- channel->channel);
- goto fail3;
- }
+ efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
+ rc = efx_probe_channels(efx);
+ if (rc)
+ goto fail3;
+
+ rc = efx_probe_filters(efx);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "failed to create filter tables\n");
+ goto fail4;
}
- efx_set_channel_names(efx);
return 0;
+ fail4:
+ efx_remove_channels(efx);
fail3:
- efx_for_each_channel(channel, efx)
- efx_remove_channel(channel);
efx_remove_port(efx);
fail2:
efx_remove_nic(efx);
@@ -1328,10 +1492,8 @@ static void efx_stop_all(struct efx_nic *efx)
static void efx_remove_all(struct efx_nic *efx)
{
- struct efx_channel *channel;
-
- efx_for_each_channel(channel, efx)
- efx_remove_channel(channel);
+ efx_remove_filters(efx);
+ efx_remove_channels(efx);
efx_remove_port(efx);
efx_remove_nic(efx);
}
@@ -1355,20 +1517,20 @@ static unsigned irq_mod_ticks(int usecs, int resolution)
void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
bool rx_adaptive)
{
- struct efx_tx_queue *tx_queue;
- struct efx_rx_queue *rx_queue;
+ struct efx_channel *channel;
unsigned tx_ticks = irq_mod_ticks(tx_usecs, EFX_IRQ_MOD_RESOLUTION);
unsigned rx_ticks = irq_mod_ticks(rx_usecs, EFX_IRQ_MOD_RESOLUTION);
EFX_ASSERT_RESET_SERIALISED(efx);
- efx_for_each_tx_queue(tx_queue, efx)
- tx_queue->channel->irq_moderation = tx_ticks;
-
efx->irq_rx_adaptive = rx_adaptive;
efx->irq_rx_moderation = rx_ticks;
- efx_for_each_rx_queue(rx_queue, efx)
- rx_queue->channel->irq_moderation = rx_ticks;
+ efx_for_each_channel(channel, efx) {
+ if (efx_channel_get_rx_queue(channel))
+ channel->irq_moderation = rx_ticks;
+ else if (efx_channel_get_tx_queue(channel, 0))
+ channel->irq_moderation = tx_ticks;
+ }
}
/**************************************************************************
@@ -1377,8 +1539,7 @@ void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
*
**************************************************************************/
-/* Run periodically off the general workqueue. Serialised against
- * efx_reconfigure_port via the mac_lock */
+/* Run periodically off the general workqueue */
static void efx_monitor(struct work_struct *data)
{
struct efx_nic *efx = container_of(data, struct efx_nic,
@@ -1391,16 +1552,13 @@ static void efx_monitor(struct work_struct *data)
/* If the mac_lock is already held then it is likely a port
* reconfiguration is already in place, which will likely do
- * most of the work of check_hw() anyway. */
- if (!mutex_trylock(&efx->mac_lock))
- goto out_requeue;
- if (!efx->port_enabled)
- goto out_unlock;
- efx->type->monitor(efx);
+ * most of the work of monitor() anyway. */
+ if (mutex_trylock(&efx->mac_lock)) {
+ if (efx->port_enabled)
+ efx->type->monitor(efx);
+ mutex_unlock(&efx->mac_lock);
+ }
-out_unlock:
- mutex_unlock(&efx->mac_lock);
-out_requeue:
queue_delayed_work(efx->workqueue, &efx->monitor_work,
efx_monitor_interval);
}
@@ -1546,11 +1704,11 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc
stats->tx_packets = mac_stats->tx_packets;
stats->rx_bytes = mac_stats->rx_bytes;
stats->tx_bytes = mac_stats->tx_bytes;
+ stats->rx_dropped = efx->n_rx_nodesc_drop_cnt;
stats->multicast = mac_stats->rx_multicast;
stats->collisions = mac_stats->tx_collision;
stats->rx_length_errors = (mac_stats->rx_gtjumbo +
mac_stats->rx_length_error);
- stats->rx_over_errors = efx->n_rx_nodesc_drop_cnt;
stats->rx_crc_errors = mac_stats->rx_bad;
stats->rx_frame_errors = mac_stats->rx_align_error;
stats->rx_fifo_errors = mac_stats->rx_overflow;
@@ -1767,6 +1925,7 @@ fail_registered:
static void efx_unregister_netdev(struct efx_nic *efx)
{
+ struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
if (!efx->net_dev)
@@ -1777,8 +1936,10 @@ static void efx_unregister_netdev(struct efx_nic *efx)
/* Free up any skbs still remaining. This has to happen before
* we try to unregister the netdev as running their destructors
* may be needed to get the device ref. count to 0. */
- efx_for_each_tx_queue(tx_queue, efx)
- efx_release_tx_buffers(tx_queue);
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_tx_queue(tx_queue, channel)
+ efx_release_tx_buffers(tx_queue);
+ }
if (efx_dev_registered(efx)) {
strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name));
@@ -1841,6 +2002,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
efx->mac_op->reconfigure(efx);
efx_init_channels(efx);
+ efx_restore_filters(efx);
mutex_unlock(&efx->spi_lock);
mutex_unlock(&efx->mac_lock);
@@ -2010,10 +2172,8 @@ int efx_port_dummy_op_int(struct efx_nic *efx)
return 0;
}
void efx_port_dummy_op_void(struct efx_nic *efx) {}
-void efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
-{
-}
-bool efx_port_dummy_op_poll(struct efx_nic *efx)
+
+static bool efx_port_dummy_op_poll(struct efx_nic *efx)
{
return false;
}
@@ -2037,9 +2197,6 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
struct pci_dev *pci_dev, struct net_device *net_dev)
{
- struct efx_channel *channel;
- struct efx_tx_queue *tx_queue;
- struct efx_rx_queue *rx_queue;
int i;
/* Initialise common structures */
@@ -2068,36 +2225,13 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
INIT_WORK(&efx->mac_work, efx_mac_work);
for (i = 0; i < EFX_MAX_CHANNELS; i++) {
- channel = &efx->channel[i];
- channel->efx = efx;
- channel->channel = i;
- channel->work_pending = false;
- spin_lock_init(&channel->tx_stop_lock);
- atomic_set(&channel->tx_stop_count, 1);
- }
- for (i = 0; i < EFX_MAX_TX_QUEUES; i++) {
- tx_queue = &efx->tx_queue[i];
- tx_queue->efx = efx;
- tx_queue->queue = i;
- tx_queue->buffer = NULL;
- tx_queue->channel = &efx->channel[0]; /* for safety */
- tx_queue->tso_headers_free = NULL;
- }
- for (i = 0; i < EFX_MAX_RX_QUEUES; i++) {
- rx_queue = &efx->rx_queue[i];
- rx_queue->efx = efx;
- rx_queue->queue = i;
- rx_queue->channel = &efx->channel[0]; /* for safety */
- rx_queue->buffer = NULL;
- setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill,
- (unsigned long)rx_queue);
+ efx->channel[i] = efx_alloc_channel(efx, i, NULL);
+ if (!efx->channel[i])
+ goto fail;
}
efx->type = type;
- /* As close as we can get to guaranteeing that we don't overflow */
- BUILD_BUG_ON(EFX_EVQ_SIZE < EFX_TXQ_SIZE + EFX_RXQ_SIZE);
-
EFX_BUG_ON_PARANOID(efx->type->phys_addr_channels > EFX_MAX_CHANNELS);
/* Higher numbered interrupt modes are less capable! */
@@ -2109,13 +2243,22 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
pci_name(pci_dev));
efx->workqueue = create_singlethread_workqueue(efx->workqueue_name);
if (!efx->workqueue)
- return -ENOMEM;
+ goto fail;
return 0;
+
+fail:
+ efx_fini_struct(efx);
+ return -ENOMEM;
}
static void efx_fini_struct(struct efx_nic *efx)
{
+ int i;
+
+ for (i = 0; i < EFX_MAX_CHANNELS; i++)
+ kfree(efx->channel[i]);
+
if (efx->workqueue) {
destroy_workqueue(efx->workqueue);
efx->workqueue = NULL;
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 060dc952a0fd..10a1bf40da96 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -12,6 +12,7 @@
#define EFX_EFX_H
#include "net_driver.h"
+#include "filter.h"
/* PCI IDs */
#define EFX_VENDID_SFC 0x1924
@@ -37,8 +38,6 @@ efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
extern void efx_stop_queue(struct efx_channel *channel);
extern void efx_wake_queue(struct efx_channel *channel);
-#define EFX_TXQ_SIZE 1024
-#define EFX_TXQ_MASK (EFX_TXQ_SIZE - 1)
/* RX */
extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
@@ -53,23 +52,42 @@ extern void __efx_rx_packet(struct efx_channel *channel,
extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
unsigned int len, bool checksummed, bool discard);
extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
-#define EFX_RXQ_SIZE 1024
-#define EFX_RXQ_MASK (EFX_RXQ_SIZE - 1)
+
+#define EFX_MAX_DMAQ_SIZE 4096UL
+#define EFX_DEFAULT_DMAQ_SIZE 1024UL
+#define EFX_MIN_DMAQ_SIZE 512UL
+
+#define EFX_MAX_EVQ_SIZE 16384UL
+#define EFX_MIN_EVQ_SIZE 512UL
+
+/* The smallest [rt]xq_entries that the driver supports. Callers of
+ * efx_wake_queue() assume that they can subsequently send at least one
+ * skb. Falcon/A1 may require up to three descriptors per skb_frag. */
+#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS))
+
+/* Filters */
+extern int efx_probe_filters(struct efx_nic *efx);
+extern void efx_restore_filters(struct efx_nic *efx);
+extern void efx_remove_filters(struct efx_nic *efx);
+extern int efx_filter_insert_filter(struct efx_nic *efx,
+ struct efx_filter_spec *spec,
+ bool replace);
+extern int efx_filter_remove_filter(struct efx_nic *efx,
+ struct efx_filter_spec *spec);
+extern void efx_filter_table_clear(struct efx_nic *efx,
+ enum efx_filter_table_id table_id,
+ enum efx_filter_priority priority);
/* Channels */
extern void efx_process_channel_now(struct efx_channel *channel);
-#define EFX_EVQ_SIZE 4096
-#define EFX_EVQ_MASK (EFX_EVQ_SIZE - 1)
+extern int
+efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries);
/* Ports */
extern int efx_reconfigure_port(struct efx_nic *efx);
extern int __efx_reconfigure_port(struct efx_nic *efx);
/* Ethtool support */
-extern int efx_ethtool_get_settings(struct net_device *net_dev,
- struct ethtool_cmd *ecmd);
-extern int efx_ethtool_set_settings(struct net_device *net_dev,
- struct ethtool_cmd *ecmd);
extern const struct ethtool_ops efx_ethtool_ops;
/* Reset handling */
@@ -81,15 +99,11 @@ extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok);
extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs,
int rx_usecs, bool rx_adaptive);
-extern int efx_request_power(struct efx_nic *efx, int mw, const char *name);
-extern void efx_hex_dump(const u8 *, unsigned int, const char *);
/* Dummy PHY ops for PHY drivers */
extern int efx_port_dummy_op_int(struct efx_nic *efx);
extern void efx_port_dummy_op_void(struct efx_nic *efx);
-extern void
-efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
-extern bool efx_port_dummy_op_poll(struct efx_nic *efx);
+
/* MTD */
#ifdef CONFIG_SFC_MTD
@@ -102,8 +116,6 @@ static inline void efx_mtd_rename(struct efx_nic *efx) {}
static inline void efx_mtd_remove(struct efx_nic *efx) {}
#endif
-extern unsigned int efx_monitor_interval;
-
static inline void efx_schedule_channel(struct efx_channel *channel)
{
netif_vdbg(channel->efx, intr, channel->efx->net_dev,
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index fd19d6ab97a2..edb9d16b8b47 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -15,6 +15,7 @@
#include "workarounds.h"
#include "selftest.h"
#include "efx.h"
+#include "filter.h"
#include "nic.h"
#include "spi.h"
#include "mdio_10g.h"
@@ -186,8 +187,8 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count)
}
/* This must be called with rtnl_lock held. */
-int efx_ethtool_get_settings(struct net_device *net_dev,
- struct ethtool_cmd *ecmd)
+static int efx_ethtool_get_settings(struct net_device *net_dev,
+ struct ethtool_cmd *ecmd)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_link_state *link_state = &efx->link_state;
@@ -210,8 +211,8 @@ int efx_ethtool_get_settings(struct net_device *net_dev,
}
/* This must be called with rtnl_lock held. */
-int efx_ethtool_set_settings(struct net_device *net_dev,
- struct ethtool_cmd *ecmd)
+static int efx_ethtool_set_settings(struct net_device *net_dev,
+ struct ethtool_cmd *ecmd)
{
struct efx_nic *efx = netdev_priv(net_dev);
int rc;
@@ -328,9 +329,10 @@ static int efx_fill_loopback_test(struct efx_nic *efx,
unsigned int test_index,
struct ethtool_string *strings, u64 *data)
{
+ struct efx_channel *channel = efx_get_channel(efx, 0);
struct efx_tx_queue *tx_queue;
- efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) {
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
efx_fill_test(test_index++, strings, data,
&lb_tests->tx_sent[tx_queue->queue],
EFX_TX_QUEUE_NAME(tx_queue),
@@ -550,9 +552,22 @@ static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev)
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;
+ 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;
- return ethtool_op_set_flags(net_dev, data, supported);
+ if (!(data & ETH_FLAG_NTUPLE)) {
+ efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP,
+ EFX_FILTER_PRI_MANUAL);
+ efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC,
+ EFX_FILTER_PRI_MANUAL);
+ }
+
+ return 0;
}
static void efx_ethtool_self_test(struct net_device *net_dev,
@@ -673,15 +688,15 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev,
struct ethtool_coalesce *coalesce)
{
struct efx_nic *efx = netdev_priv(net_dev);
- struct efx_tx_queue *tx_queue;
struct efx_channel *channel;
memset(coalesce, 0, sizeof(*coalesce));
/* Find lowest IRQ moderation across all used TX queues */
coalesce->tx_coalesce_usecs_irq = ~((u32) 0);
- efx_for_each_tx_queue(tx_queue, efx) {
- channel = tx_queue->channel;
+ efx_for_each_channel(channel, efx) {
+ if (!efx_channel_get_tx_queue(channel, 0))
+ continue;
if (channel->irq_moderation < coalesce->tx_coalesce_usecs_irq) {
if (channel->channel < efx->n_rx_channels)
coalesce->tx_coalesce_usecs_irq =
@@ -708,7 +723,6 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_channel *channel;
- struct efx_tx_queue *tx_queue;
unsigned tx_usecs, rx_usecs, adaptive;
if (coalesce->use_adaptive_tx_coalesce)
@@ -725,8 +739,9 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
adaptive = coalesce->use_adaptive_rx_coalesce;
/* If the channel is shared only allow RX parameters to be set */
- efx_for_each_tx_queue(tx_queue, efx) {
- if ((tx_queue->channel->channel < efx->n_rx_channels) &&
+ efx_for_each_channel(channel, efx) {
+ if (efx_channel_get_rx_queue(channel) &&
+ efx_channel_get_tx_queue(channel, 0) &&
tx_usecs) {
netif_err(efx, drv, efx->net_dev, "Channel is shared. "
"Only RX coalescing may be set\n");
@@ -741,6 +756,42 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
return 0;
}
+static void efx_ethtool_get_ringparam(struct net_device *net_dev,
+ struct ethtool_ringparam *ring)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ ring->rx_max_pending = EFX_MAX_DMAQ_SIZE;
+ ring->tx_max_pending = EFX_MAX_DMAQ_SIZE;
+ ring->rx_mini_max_pending = 0;
+ ring->rx_jumbo_max_pending = 0;
+ ring->rx_pending = efx->rxq_entries;
+ ring->tx_pending = efx->txq_entries;
+ ring->rx_mini_pending = 0;
+ ring->rx_jumbo_pending = 0;
+}
+
+static int efx_ethtool_set_ringparam(struct net_device *net_dev,
+ struct ethtool_ringparam *ring)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
+ ring->rx_pending > EFX_MAX_DMAQ_SIZE ||
+ ring->tx_pending > EFX_MAX_DMAQ_SIZE)
+ return -EINVAL;
+
+ if (ring->rx_pending < EFX_MIN_RING_SIZE ||
+ ring->tx_pending < EFX_MIN_RING_SIZE) {
+ netif_err(efx, drv, efx->net_dev,
+ "TX and RX queues cannot be smaller than %ld\n",
+ EFX_MIN_RING_SIZE);
+ return -EINVAL;
+ }
+
+ return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending);
+}
+
static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause)
{
@@ -840,7 +891,7 @@ static int efx_ethtool_set_wol(struct net_device *net_dev,
return efx->type->set_wol(efx, wol->wolopts);
}
-extern int efx_ethtool_reset(struct net_device *net_dev, u32 *flags)
+static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags)
{
struct efx_nic *efx = netdev_priv(net_dev);
enum reset_type method;
@@ -918,6 +969,105 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev,
}
}
+static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
+ struct ethtool_rx_ntuple *ntuple)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct ethtool_tcpip4_spec *ip_entry = &ntuple->fs.h_u.tcp_ip4_spec;
+ struct ethtool_tcpip4_spec *ip_mask = &ntuple->fs.m_u.tcp_ip4_spec;
+ struct ethhdr *mac_entry = &ntuple->fs.h_u.ether_spec;
+ struct ethhdr *mac_mask = &ntuple->fs.m_u.ether_spec;
+ struct efx_filter_spec filter;
+
+ /* Range-check action */
+ if (ntuple->fs.action < ETHTOOL_RXNTUPLE_ACTION_CLEAR ||
+ ntuple->fs.action >= (s32)efx->n_rx_channels)
+ return -EINVAL;
+
+ if (~ntuple->fs.data_mask)
+ return -EINVAL;
+
+ switch (ntuple->fs.flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ /* Must match all of destination, */
+ if (ip_mask->ip4dst | ip_mask->pdst)
+ return -EINVAL;
+ /* all or none of source, */
+ if ((ip_mask->ip4src | ip_mask->psrc) &&
+ ((__force u32)~ip_mask->ip4src |
+ (__force u16)~ip_mask->psrc))
+ return -EINVAL;
+ /* and nothing else */
+ if ((u8)~ip_mask->tos | (u16)~ntuple->fs.vlan_tag_mask)
+ return -EINVAL;
+ break;
+ case ETHER_FLOW:
+ /* Must match all of destination, */
+ if (!is_zero_ether_addr(mac_mask->h_dest))
+ return -EINVAL;
+ /* all or none of VID, */
+ if (ntuple->fs.vlan_tag_mask != 0xf000 &&
+ ntuple->fs.vlan_tag_mask != 0xffff)
+ return -EINVAL;
+ /* and nothing else */
+ if (!is_broadcast_ether_addr(mac_mask->h_source) ||
+ mac_mask->h_proto != htons(0xffff))
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ filter.priority = EFX_FILTER_PRI_MANUAL;
+ filter.flags = 0;
+
+ switch (ntuple->fs.flow_type) {
+ case TCP_V4_FLOW:
+ if (!ip_mask->ip4src)
+ efx_filter_set_rx_tcp_full(&filter,
+ htonl(ip_entry->ip4src),
+ htons(ip_entry->psrc),
+ htonl(ip_entry->ip4dst),
+ htons(ip_entry->pdst));
+ else
+ efx_filter_set_rx_tcp_wild(&filter,
+ htonl(ip_entry->ip4dst),
+ htons(ip_entry->pdst));
+ break;
+ case UDP_V4_FLOW:
+ if (!ip_mask->ip4src)
+ efx_filter_set_rx_udp_full(&filter,
+ htonl(ip_entry->ip4src),
+ htons(ip_entry->psrc),
+ htonl(ip_entry->ip4dst),
+ htons(ip_entry->pdst));
+ else
+ efx_filter_set_rx_udp_wild(&filter,
+ htonl(ip_entry->ip4dst),
+ htons(ip_entry->pdst));
+ break;
+ case ETHER_FLOW:
+ if (ntuple->fs.vlan_tag_mask == 0xf000)
+ efx_filter_set_rx_mac_full(&filter,
+ ntuple->fs.vlan_tag & 0xfff,
+ mac_entry->h_dest);
+ else
+ efx_filter_set_rx_mac_wild(&filter, mac_entry->h_dest);
+ break;
+ }
+
+ if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR) {
+ return efx_filter_remove_filter(efx, &filter);
+ } else {
+ if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP)
+ filter.dmaq_id = 0xfff;
+ else
+ filter.dmaq_id = ntuple->fs.action;
+ return efx_filter_insert_filter(efx, &filter, true);
+ }
+}
+
static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev,
struct ethtool_rxfh_indir *indir)
{
@@ -971,6 +1121,8 @@ const struct ethtool_ops efx_ethtool_ops = {
.set_eeprom = efx_ethtool_set_eeprom,
.get_coalesce = efx_ethtool_get_coalesce,
.set_coalesce = efx_ethtool_set_coalesce,
+ .get_ringparam = efx_ethtool_get_ringparam,
+ .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,
@@ -994,6 +1146,7 @@ const struct ethtool_ops efx_ethtool_ops = {
.set_wol = efx_ethtool_set_wol,
.reset = efx_ethtool_reset,
.get_rxnfc = efx_ethtool_get_rxnfc,
+ .set_rx_ntuple = efx_ethtool_set_rx_ntuple,
.get_rxfh_indir = efx_ethtool_get_rxfh_indir,
.set_rxfh_indir = efx_ethtool_set_rxfh_indir,
};
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 4f9d33f3cca1..267019bb2b15 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -159,7 +159,6 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
{
struct efx_nic *efx = dev_id;
efx_oword_t *int_ker = efx->irq_status.addr;
- struct efx_channel *channel;
int syserr;
int queues;
@@ -194,15 +193,10 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
wmb(); /* Ensure the vector is cleared before interrupt ack */
falcon_irq_ack_a1(efx);
- /* Schedule processing of any interrupting queues */
- channel = &efx->channel[0];
- while (queues) {
- if (queues & 0x01)
- efx_schedule_channel(channel);
- channel++;
- queues >>= 1;
- }
-
+ if (queues & 1)
+ efx_schedule_channel(efx_get_channel(efx, 0));
+ if (queues & 2)
+ efx_schedule_channel(efx_get_channel(efx, 1));
return IRQ_HANDLED;
}
/**************************************************************************
@@ -452,30 +446,19 @@ static void falcon_reset_macs(struct efx_nic *efx)
/* It's not safe to use GLB_CTL_REG to reset the
* macs, so instead use the internal MAC resets
*/
- if (!EFX_IS10G(efx)) {
- EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 1);
- efx_writeo(efx, &reg, FR_AB_GM_CFG1);
- udelay(1000);
-
- EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 0);
- efx_writeo(efx, &reg, FR_AB_GM_CFG1);
- udelay(1000);
- return;
- } else {
- EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1);
- efx_writeo(efx, &reg, FR_AB_XM_GLB_CFG);
-
- for (count = 0; count < 10000; count++) {
- efx_reado(efx, &reg, FR_AB_XM_GLB_CFG);
- if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) ==
- 0)
- return;
- udelay(10);
- }
-
- netif_err(efx, hw, efx->net_dev,
- "timed out waiting for XMAC core reset\n");
+ EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1);
+ efx_writeo(efx, &reg, FR_AB_XM_GLB_CFG);
+
+ for (count = 0; count < 10000; count++) {
+ efx_reado(efx, &reg, FR_AB_XM_GLB_CFG);
+ if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) ==
+ 0)
+ return;
+ udelay(10);
}
+
+ netif_err(efx, hw, efx->net_dev,
+ "timed out waiting for XMAC core reset\n");
}
/* Mac stats will fail whist the TX fifo is draining */
@@ -514,7 +497,6 @@ static void falcon_reset_macs(struct efx_nic *efx)
* are re-enabled by the caller */
efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL);
- /* This can run even when the GMAC is selected */
falcon_setup_xaui(efx);
}
@@ -652,8 +634,6 @@ static void falcon_stats_timer_func(unsigned long context)
spin_unlock(&efx->stats_lock);
}
-static void falcon_switch_mac(struct efx_nic *efx);
-
static bool falcon_loopback_link_poll(struct efx_nic *efx)
{
struct efx_link_state old_state = efx->link_state;
@@ -664,11 +644,7 @@ static bool falcon_loopback_link_poll(struct efx_nic *efx)
efx->link_state.fd = true;
efx->link_state.fc = efx->wanted_fc;
efx->link_state.up = true;
-
- if (efx->loopback_mode == LOOPBACK_GMAC)
- efx->link_state.speed = 1000;
- else
- efx->link_state.speed = 10000;
+ efx->link_state.speed = 10000;
return !efx_link_state_equal(&efx->link_state, &old_state);
}
@@ -691,7 +667,7 @@ static int falcon_reconfigure_port(struct efx_nic *efx)
falcon_stop_nic_stats(efx);
falcon_deconfigure_mac_wrapper(efx);
- falcon_switch_mac(efx);
+ falcon_reset_macs(efx);
efx->phy_op->reconfigure(efx);
rc = efx->mac_op->reconfigure(efx);
@@ -841,73 +817,23 @@ out:
return rc;
}
-static void falcon_clock_mac(struct efx_nic *efx)
-{
- unsigned strap_val;
- efx_oword_t nic_stat;
-
- /* Configure the NIC generated MAC clock correctly */
- efx_reado(efx, &nic_stat, FR_AB_NIC_STAT);
- strap_val = EFX_IS10G(efx) ? 5 : 3;
- if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
- EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP_EN, 1);
- EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP, strap_val);
- efx_writeo(efx, &nic_stat, FR_AB_NIC_STAT);
- } else {
- /* Falcon A1 does not support 1G/10G speed switching
- * and must not be used with a PHY that does. */
- BUG_ON(EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_PINS) !=
- strap_val);
- }
-}
-
-static void falcon_switch_mac(struct efx_nic *efx)
-{
- struct efx_mac_operations *old_mac_op = efx->mac_op;
- struct falcon_nic_data *nic_data = efx->nic_data;
- unsigned int stats_done_offset;
-
- WARN_ON(!mutex_is_locked(&efx->mac_lock));
- WARN_ON(nic_data->stats_disable_count == 0);
-
- efx->mac_op = (EFX_IS10G(efx) ?
- &falcon_xmac_operations : &falcon_gmac_operations);
-
- if (EFX_IS10G(efx))
- stats_done_offset = XgDmaDone_offset;
- else
- stats_done_offset = GDmaDone_offset;
- nic_data->stats_dma_done = efx->stats_buffer.addr + stats_done_offset;
-
- if (old_mac_op == efx->mac_op)
- return;
-
- falcon_clock_mac(efx);
-
- netif_dbg(efx, hw, efx->net_dev, "selected %cMAC\n",
- EFX_IS10G(efx) ? 'X' : 'G');
- /* Not all macs support a mac-level link state */
- efx->xmac_poll_required = false;
- falcon_reset_macs(efx);
-}
-
/* This call is responsible for hooking in the MAC and PHY operations */
static int falcon_probe_port(struct efx_nic *efx)
{
+ struct falcon_nic_data *nic_data = efx->nic_data;
int rc;
switch (efx->phy_type) {
case PHY_TYPE_SFX7101:
efx->phy_op = &falcon_sfx7101_phy_ops;
break;
- case PHY_TYPE_SFT9001A:
- case PHY_TYPE_SFT9001B:
- efx->phy_op = &falcon_sft9001_phy_ops;
- break;
case PHY_TYPE_QT2022C2:
case PHY_TYPE_QT2025C:
efx->phy_op = &falcon_qt202x_phy_ops;
break;
+ case PHY_TYPE_TXC43128:
+ efx->phy_op = &falcon_txc_phy_ops;
+ break;
default:
netif_err(efx, probe, efx->net_dev, "Unknown PHY type %d\n",
efx->phy_type);
@@ -943,6 +869,7 @@ static int falcon_probe_port(struct efx_nic *efx)
(u64)efx->stats_buffer.dma_addr,
efx->stats_buffer.addr,
(u64)virt_to_phys(efx->stats_buffer.addr));
+ nic_data->stats_dma_done = efx->stats_buffer.addr + XgDmaDone_offset;
return 0;
}
@@ -1207,7 +1134,7 @@ static void falcon_monitor(struct efx_nic *efx)
falcon_stop_nic_stats(efx);
falcon_deconfigure_mac_wrapper(efx);
- falcon_switch_mac(efx);
+ falcon_reset_macs(efx);
rc = efx->mac_op->reconfigure(efx);
BUG_ON(rc);
@@ -1216,8 +1143,7 @@ static void falcon_monitor(struct efx_nic *efx)
efx_link_status_changed(efx);
}
- if (EFX_IS10G(efx))
- falcon_poll_xmac(efx);
+ falcon_poll_xmac(efx);
}
/* Zeroes out the SRAM contents. This routine must be called in
@@ -1610,16 +1536,6 @@ static int falcon_init_nic(struct efx_nic *efx)
EFX_SET_OWORD_FIELD(temp, FRF_AB_ONCHIP_SRAM, 1);
efx_writeo(efx, &temp, FR_AB_NIC_STAT);
- /* Set the source of the GMAC clock */
- if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) {
- efx_reado(efx, &temp, FR_AB_GPIO_CTL);
- EFX_SET_OWORD_FIELD(temp, FRF_AB_USE_NIC_CLK, true);
- efx_writeo(efx, &temp, FR_AB_GPIO_CTL);
- }
-
- /* Select the correct MAC */
- falcon_clock_mac(efx);
-
rc = falcon_reset_sram(efx);
if (rc)
return rc;
@@ -1880,7 +1796,7 @@ struct efx_nic_type falcon_b0_nic_type = {
* channels */
.tx_dc_base = 0x130000,
.rx_dc_base = 0x100000,
- .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH,
+ .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE,
.reset_world_flags = ETH_RESET_IRQ,
};
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index 3d950c2cf205..cfc6a5b5a477 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -26,7 +26,7 @@
/* Board types */
#define FALCON_BOARD_SFE4001 0x01
#define FALCON_BOARD_SFE4002 0x02
-#define FALCON_BOARD_SFN4111T 0x51
+#define FALCON_BOARD_SFE4003 0x03
#define FALCON_BOARD_SFN4112F 0x52
/* Board temperature is about 15°C above ambient when air flow is
@@ -142,17 +142,17 @@ static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask)
#endif /* CONFIG_SENSORS_LM87 */
/*****************************************************************************
- * Support for the SFE4001 and SFN4111T NICs.
+ * Support for the SFE4001 NIC.
*
* The SFE4001 does not power-up fully at reset due to its high power
* consumption. We control its power via a PCA9539 I/O expander.
- * Both boards have a MAX6647 temperature monitor which we expose to
+ * It also has a MAX6647 temperature monitor which we expose to
* the lm90 driver.
*
* This also provides minimal support for reflashing the PHY, which is
* initiated by resetting it with the FLASH_CFG_1 pin pulled down.
* On SFE4001 rev A2 and later this is connected to the 3V3X output of
- * the IO-expander; on the SFN4111T it is connected to Falcon's GPIO3.
+ * the IO-expander.
* We represent reflash mode as PHY_MODE_SPECIAL and make it mutually
* exclusive with the network device being open.
*/
@@ -304,34 +304,6 @@ fail_on:
return rc;
}
-static int sfn4111t_reset(struct efx_nic *efx)
-{
- struct falcon_board *board = falcon_board(efx);
- efx_oword_t reg;
-
- /* GPIO 3 and the GPIO register are shared with I2C, so block that */
- i2c_lock_adapter(&board->i2c_adap);
-
- /* Pull RST_N (GPIO 2) low then let it up again, setting the
- * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the
- * output enables; the output levels should always be 0 (low)
- * and we rely on external pull-ups. */
- efx_reado(efx, &reg, FR_AB_GPIO_CTL);
- EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, true);
- efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
- msleep(1000);
- EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, false);
- EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN,
- !!(efx->phy_mode & PHY_MODE_SPECIAL));
- efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
- msleep(1);
-
- i2c_unlock_adapter(&board->i2c_adap);
-
- ssleep(1);
- return 0;
-}
-
static ssize_t show_phy_flash_cfg(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -363,10 +335,7 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
efx->phy_mode = new_mode;
if (new_mode & PHY_MODE_SPECIAL)
falcon_stop_nic_stats(efx);
- if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001)
- err = sfe4001_poweron(efx);
- else
- err = sfn4111t_reset(efx);
+ err = sfe4001_poweron(efx);
if (!err)
err = efx_reconfigure_port(efx);
if (!(new_mode & PHY_MODE_SPECIAL))
@@ -479,83 +448,6 @@ fail_hwmon:
return rc;
}
-static int sfn4111t_check_hw(struct efx_nic *efx)
-{
- s32 status;
-
- /* If XAUI link is up then do not monitor */
- if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required)
- return 0;
-
- /* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */
- status = i2c_smbus_read_byte_data(falcon_board(efx)->hwmon_client,
- MAX664X_REG_RSL);
- if (status < 0)
- return -EIO;
- if (status & 0x57)
- return -ERANGE;
- return 0;
-}
-
-static void sfn4111t_fini(struct efx_nic *efx)
-{
- netif_info(efx, drv, efx->net_dev, "%s\n", __func__);
-
- device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
- i2c_unregister_device(falcon_board(efx)->hwmon_client);
-}
-
-static struct i2c_board_info sfn4111t_a0_hwmon_info = {
- I2C_BOARD_INFO("max6647", 0x4e),
-};
-
-static struct i2c_board_info sfn4111t_r5_hwmon_info = {
- I2C_BOARD_INFO("max6646", 0x4d),
-};
-
-static void sfn4111t_init_phy(struct efx_nic *efx)
-{
- if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
- if (sft9001_wait_boot(efx) != -EINVAL)
- return;
-
- efx->phy_mode = PHY_MODE_SPECIAL;
- falcon_stop_nic_stats(efx);
- }
-
- sfn4111t_reset(efx);
- sft9001_wait_boot(efx);
-}
-
-static int sfn4111t_init(struct efx_nic *efx)
-{
- struct falcon_board *board = falcon_board(efx);
- int rc;
-
- board->hwmon_client =
- i2c_new_device(&board->i2c_adap,
- (board->minor < 5) ?
- &sfn4111t_a0_hwmon_info :
- &sfn4111t_r5_hwmon_info);
- if (!board->hwmon_client)
- return -EIO;
-
- rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
- if (rc)
- goto fail_hwmon;
-
- if (efx->phy_mode & PHY_MODE_SPECIAL)
- /* PHY may not generate a 156.25 MHz clock and MAC
- * stats fetch will fail. */
- falcon_stop_nic_stats(efx);
-
- return 0;
-
-fail_hwmon:
- i2c_unregister_device(board->hwmon_client);
- return rc;
-}
-
/*****************************************************************************
* Support for the SFE4002
*
@@ -691,6 +583,75 @@ static int sfn4112f_init(struct efx_nic *efx)
return efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs);
}
+/*****************************************************************************
+ * Support for the SFE4003
+ *
+ */
+static u8 sfe4003_lm87_channel = 0x03; /* use AIN not FAN inputs */
+
+static const u8 sfe4003_lm87_regs[] = {
+ LM87_IN_LIMITS(0, 0x67, 0x7f), /* 2.5V: 1.5V +/- 10% */
+ LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */
+ LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */
+ LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */
+ LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */
+ LM87_TEMP_INT_LIMITS(0, 70 + FALCON_BOARD_TEMP_BIAS),
+ 0
+};
+
+static struct i2c_board_info sfe4003_hwmon_info = {
+ I2C_BOARD_INFO("lm87", 0x2e),
+ .platform_data = &sfe4003_lm87_channel,
+};
+
+/* Board-specific LED info. */
+#define SFE4003_RED_LED_GPIO 11
+#define SFE4003_LED_ON 1
+#define SFE4003_LED_OFF 0
+
+static void sfe4003_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
+{
+ struct falcon_board *board = falcon_board(efx);
+
+ /* The LEDs were not wired to GPIOs before A3 */
+ if (board->minor < 3 && board->major == 0)
+ return;
+
+ falcon_txc_set_gpio_val(
+ efx, SFE4003_RED_LED_GPIO,
+ (mode == EFX_LED_ON) ? SFE4003_LED_ON : SFE4003_LED_OFF);
+}
+
+static void sfe4003_init_phy(struct efx_nic *efx)
+{
+ struct falcon_board *board = falcon_board(efx);
+
+ /* The LEDs were not wired to GPIOs before A3 */
+ if (board->minor < 3 && board->major == 0)
+ return;
+
+ falcon_txc_set_gpio_dir(efx, SFE4003_RED_LED_GPIO, TXC_GPIO_DIR_OUTPUT);
+ falcon_txc_set_gpio_val(efx, SFE4003_RED_LED_GPIO, SFE4003_LED_OFF);
+}
+
+static int sfe4003_check_hw(struct efx_nic *efx)
+{
+ struct falcon_board *board = falcon_board(efx);
+
+ /* A0/A1/A2 board rev. 4003s report a temperature fault the whole time
+ * (bad sensor) so we mask it out. */
+ unsigned alarm_mask =
+ (board->major == 0 && board->minor <= 2) ?
+ ~LM87_ALARM_TEMP_EXT1 : ~0;
+
+ return efx_check_lm87(efx, alarm_mask);
+}
+
+static int sfe4003_init(struct efx_nic *efx)
+{
+ return efx_init_lm87(efx, &sfe4003_hwmon_info, sfe4003_lm87_regs);
+}
+
static const struct falcon_board_type board_types[] = {
{
.id = FALCON_BOARD_SFE4001,
@@ -713,14 +674,14 @@ static const struct falcon_board_type board_types[] = {
.monitor = sfe4002_check_hw,
},
{
- .id = FALCON_BOARD_SFN4111T,
- .ref_model = "SFN4111T",
- .gen_type = "100/1000/10GBASE-T adapter",
- .init = sfn4111t_init,
- .init_phy = sfn4111t_init_phy,
- .fini = sfn4111t_fini,
- .set_id_led = tenxpress_set_id_led,
- .monitor = sfn4111t_check_hw,
+ .id = FALCON_BOARD_SFE4003,
+ .ref_model = "SFE4003",
+ .gen_type = "10GBASE-CX4 adapter",
+ .init = sfe4003_init,
+ .init_phy = sfe4003_init_phy,
+ .fini = efx_fini_lm87,
+ .set_id_led = sfe4003_set_id_led,
+ .monitor = sfe4003_check_hw,
},
{
.id = FALCON_BOARD_SFN4112F,
diff --git a/drivers/net/sfc/falcon_gmac.c b/drivers/net/sfc/falcon_gmac.c
deleted file mode 100644
index 7dadfcbd6ce7..000000000000
--- a/drivers/net/sfc/falcon_gmac.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2009 Solarflare Communications Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation, incorporated herein by reference.
- */
-
-#include <linux/delay.h>
-#include "net_driver.h"
-#include "efx.h"
-#include "nic.h"
-#include "mac.h"
-#include "regs.h"
-#include "io.h"
-
-/**************************************************************************
- *
- * MAC operations
- *
- *************************************************************************/
-
-static int falcon_reconfigure_gmac(struct efx_nic *efx)
-{
- struct efx_link_state *link_state = &efx->link_state;
- bool loopback, tx_fc, rx_fc, bytemode;
- int if_mode;
- unsigned int max_frame_len;
- efx_oword_t reg;
-
- /* Configuration register 1 */
- tx_fc = (link_state->fc & EFX_FC_TX) || !link_state->fd;
- rx_fc = !!(link_state->fc & EFX_FC_RX);
- loopback = (efx->loopback_mode == LOOPBACK_GMAC);
- bytemode = (link_state->speed == 1000);
-
- EFX_POPULATE_OWORD_5(reg,
- FRF_AB_GM_LOOP, loopback,
- FRF_AB_GM_TX_EN, 1,
- FRF_AB_GM_TX_FC_EN, tx_fc,
- FRF_AB_GM_RX_EN, 1,
- FRF_AB_GM_RX_FC_EN, rx_fc);
- efx_writeo(efx, &reg, FR_AB_GM_CFG1);
- udelay(10);
-
- /* Configuration register 2 */
- if_mode = (bytemode) ? 2 : 1;
- EFX_POPULATE_OWORD_5(reg,
- FRF_AB_GM_IF_MODE, if_mode,
- FRF_AB_GM_PAD_CRC_EN, 1,
- FRF_AB_GM_LEN_CHK, 1,
- FRF_AB_GM_FD, link_state->fd,
- FRF_AB_GM_PAMBL_LEN, 0x7/*datasheet recommended */);
-
- efx_writeo(efx, &reg, FR_AB_GM_CFG2);
- udelay(10);
-
- /* Max frame len register */
- max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
- EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_MAX_FLEN, max_frame_len);
- efx_writeo(efx, &reg, FR_AB_GM_MAX_FLEN);
- udelay(10);
-
- /* FIFO configuration register 0 */
- EFX_POPULATE_OWORD_5(reg,
- FRF_AB_GMF_FTFENREQ, 1,
- FRF_AB_GMF_STFENREQ, 1,
- FRF_AB_GMF_FRFENREQ, 1,
- FRF_AB_GMF_SRFENREQ, 1,
- FRF_AB_GMF_WTMENREQ, 1);
- efx_writeo(efx, &reg, FR_AB_GMF_CFG0);
- udelay(10);
-
- /* FIFO configuration register 1 */
- EFX_POPULATE_OWORD_2(reg,
- FRF_AB_GMF_CFGFRTH, 0x12,
- FRF_AB_GMF_CFGXOFFRTX, 0xffff);
- efx_writeo(efx, &reg, FR_AB_GMF_CFG1);
- udelay(10);
-
- /* FIFO configuration register 2 */
- EFX_POPULATE_OWORD_2(reg,
- FRF_AB_GMF_CFGHWM, 0x3f,
- FRF_AB_GMF_CFGLWM, 0xa);
- efx_writeo(efx, &reg, FR_AB_GMF_CFG2);
- udelay(10);
-
- /* FIFO configuration register 3 */
- EFX_POPULATE_OWORD_2(reg,
- FRF_AB_GMF_CFGHWMFT, 0x1c,
- FRF_AB_GMF_CFGFTTH, 0x08);
- efx_writeo(efx, &reg, FR_AB_GMF_CFG3);
- udelay(10);
-
- /* FIFO configuration register 4 */
- EFX_POPULATE_OWORD_1(reg, FRF_AB_GMF_HSTFLTRFRM_PAUSE, 1);
- efx_writeo(efx, &reg, FR_AB_GMF_CFG4);
- udelay(10);
-
- /* FIFO configuration register 5 */
- efx_reado(efx, &reg, FR_AB_GMF_CFG5);
- EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGBYTMODE, bytemode);
- EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGHDPLX, !link_state->fd);
- EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTDRPLT64, !link_state->fd);
- EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTFLTRFRMDC_PAUSE, 0);
- efx_writeo(efx, &reg, FR_AB_GMF_CFG5);
- udelay(10);
-
- /* MAC address */
- EFX_POPULATE_OWORD_4(reg,
- FRF_AB_GM_ADR_B0, efx->net_dev->dev_addr[5],
- FRF_AB_GM_ADR_B1, efx->net_dev->dev_addr[4],
- FRF_AB_GM_ADR_B2, efx->net_dev->dev_addr[3],
- FRF_AB_GM_ADR_B3, efx->net_dev->dev_addr[2]);
- efx_writeo(efx, &reg, FR_AB_GM_ADR1);
- udelay(10);
- EFX_POPULATE_OWORD_2(reg,
- FRF_AB_GM_ADR_B4, efx->net_dev->dev_addr[1],
- FRF_AB_GM_ADR_B5, efx->net_dev->dev_addr[0]);
- efx_writeo(efx, &reg, FR_AB_GM_ADR2);
- udelay(10);
-
- falcon_reconfigure_mac_wrapper(efx);
-
- return 0;
-}
-
-static void falcon_update_stats_gmac(struct efx_nic *efx)
-{
- struct efx_mac_stats *mac_stats = &efx->mac_stats;
- unsigned long old_rx_pause, old_tx_pause;
- unsigned long new_rx_pause, new_tx_pause;
-
- /* Pause frames are erroneously counted as errors (SFC bug 3269) */
- old_rx_pause = mac_stats->rx_pause;
- old_tx_pause = mac_stats->tx_pause;
-
- /* Update MAC stats from DMAed values */
- FALCON_STAT(efx, GRxGoodOct, rx_good_bytes);
- FALCON_STAT(efx, GRxBadOct, rx_bad_bytes);
- FALCON_STAT(efx, GRxMissPkt, rx_missed);
- FALCON_STAT(efx, GRxFalseCRS, rx_false_carrier);
- FALCON_STAT(efx, GRxPausePkt, rx_pause);
- FALCON_STAT(efx, GRxBadPkt, rx_bad);
- FALCON_STAT(efx, GRxUcastPkt, rx_unicast);
- FALCON_STAT(efx, GRxMcastPkt, rx_multicast);
- FALCON_STAT(efx, GRxBcastPkt, rx_broadcast);
- FALCON_STAT(efx, GRxGoodLt64Pkt, rx_good_lt64);
- FALCON_STAT(efx, GRxBadLt64Pkt, rx_bad_lt64);
- FALCON_STAT(efx, GRx64Pkt, rx_64);
- FALCON_STAT(efx, GRx65to127Pkt, rx_65_to_127);
- FALCON_STAT(efx, GRx128to255Pkt, rx_128_to_255);
- FALCON_STAT(efx, GRx256to511Pkt, rx_256_to_511);
- FALCON_STAT(efx, GRx512to1023Pkt, rx_512_to_1023);
- FALCON_STAT(efx, GRx1024to15xxPkt, rx_1024_to_15xx);
- FALCON_STAT(efx, GRx15xxtoJumboPkt, rx_15xx_to_jumbo);
- FALCON_STAT(efx, GRxGtJumboPkt, rx_gtjumbo);
- FALCON_STAT(efx, GRxFcsErr64to15xxPkt, rx_bad_64_to_15xx);
- FALCON_STAT(efx, GRxFcsErr15xxtoJumboPkt, rx_bad_15xx_to_jumbo);
- FALCON_STAT(efx, GRxFcsErrGtJumboPkt, rx_bad_gtjumbo);
- FALCON_STAT(efx, GTxGoodBadOct, tx_bytes);
- FALCON_STAT(efx, GTxGoodOct, tx_good_bytes);
- FALCON_STAT(efx, GTxSglColPkt, tx_single_collision);
- FALCON_STAT(efx, GTxMultColPkt, tx_multiple_collision);
- FALCON_STAT(efx, GTxExColPkt, tx_excessive_collision);
- FALCON_STAT(efx, GTxDefPkt, tx_deferred);
- FALCON_STAT(efx, GTxLateCol, tx_late_collision);
- FALCON_STAT(efx, GTxExDefPkt, tx_excessive_deferred);
- FALCON_STAT(efx, GTxPausePkt, tx_pause);
- FALCON_STAT(efx, GTxBadPkt, tx_bad);
- FALCON_STAT(efx, GTxUcastPkt, tx_unicast);
- FALCON_STAT(efx, GTxMcastPkt, tx_multicast);
- FALCON_STAT(efx, GTxBcastPkt, tx_broadcast);
- FALCON_STAT(efx, GTxLt64Pkt, tx_lt64);
- FALCON_STAT(efx, GTx64Pkt, tx_64);
- FALCON_STAT(efx, GTx65to127Pkt, tx_65_to_127);
- FALCON_STAT(efx, GTx128to255Pkt, tx_128_to_255);
- FALCON_STAT(efx, GTx256to511Pkt, tx_256_to_511);
- FALCON_STAT(efx, GTx512to1023Pkt, tx_512_to_1023);
- FALCON_STAT(efx, GTx1024to15xxPkt, tx_1024_to_15xx);
- FALCON_STAT(efx, GTx15xxtoJumboPkt, tx_15xx_to_jumbo);
- FALCON_STAT(efx, GTxGtJumboPkt, tx_gtjumbo);
- FALCON_STAT(efx, GTxNonTcpUdpPkt, tx_non_tcpudp);
- FALCON_STAT(efx, GTxMacSrcErrPkt, tx_mac_src_error);
- FALCON_STAT(efx, GTxIpSrcErrPkt, tx_ip_src_error);
-
- /* Pause frames are erroneously counted as errors (SFC bug 3269) */
- new_rx_pause = mac_stats->rx_pause;
- new_tx_pause = mac_stats->tx_pause;
- mac_stats->rx_bad -= (new_rx_pause - old_rx_pause);
- mac_stats->tx_bad -= (new_tx_pause - old_tx_pause);
-
- /* Derive stats that the MAC doesn't provide directly */
- mac_stats->tx_bad_bytes =
- mac_stats->tx_bytes - mac_stats->tx_good_bytes;
- mac_stats->tx_packets =
- mac_stats->tx_lt64 + mac_stats->tx_64 +
- mac_stats->tx_65_to_127 + mac_stats->tx_128_to_255 +
- mac_stats->tx_256_to_511 + mac_stats->tx_512_to_1023 +
- mac_stats->tx_1024_to_15xx + mac_stats->tx_15xx_to_jumbo +
- mac_stats->tx_gtjumbo;
- mac_stats->tx_collision =
- mac_stats->tx_single_collision +
- mac_stats->tx_multiple_collision +
- mac_stats->tx_excessive_collision +
- mac_stats->tx_late_collision;
- mac_stats->rx_bytes =
- mac_stats->rx_good_bytes + mac_stats->rx_bad_bytes;
- mac_stats->rx_packets =
- mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64 +
- mac_stats->rx_64 + mac_stats->rx_65_to_127 +
- mac_stats->rx_128_to_255 + mac_stats->rx_256_to_511 +
- mac_stats->rx_512_to_1023 + mac_stats->rx_1024_to_15xx +
- mac_stats->rx_15xx_to_jumbo + mac_stats->rx_gtjumbo;
- mac_stats->rx_good = mac_stats->rx_packets - mac_stats->rx_bad;
- mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64;
-}
-
-static bool falcon_gmac_check_fault(struct efx_nic *efx)
-{
- return false;
-}
-
-struct efx_mac_operations falcon_gmac_operations = {
- .reconfigure = falcon_reconfigure_gmac,
- .update_stats = falcon_update_stats_gmac,
- .check_fault = falcon_gmac_check_fault,
-};
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index bae656dd2c4e..b31f595ebb5b 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -143,7 +143,7 @@ static bool falcon_xmac_link_ok(struct efx_nic *efx)
efx_mdio_phyxgxs_lane_sync(efx));
}
-void falcon_reconfigure_xmac_core(struct efx_nic *efx)
+static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
{
unsigned int max_frame_len;
efx_oword_t reg;
diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c
new file mode 100644
index 000000000000..52cb6082b910
--- /dev/null
+++ b/drivers/net/sfc/filter.c
@@ -0,0 +1,454 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2010 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "efx.h"
+#include "filter.h"
+#include "io.h"
+#include "nic.h"
+#include "regs.h"
+
+/* "Fudge factors" - difference between programmed value and actual depth.
+ * Due to pipelined implementation we need to program H/W with a value that
+ * is larger than the hop limit we want.
+ */
+#define FILTER_CTL_SRCH_FUDGE_WILD 3
+#define FILTER_CTL_SRCH_FUDGE_FULL 1
+
+/* Hard maximum hop limit. Hardware will time-out beyond 200-something.
+ * We also need to avoid infinite loops in efx_filter_search() when the
+ * table is full.
+ */
+#define FILTER_CTL_SRCH_MAX 200
+
+struct efx_filter_table {
+ u32 offset; /* address of table relative to BAR */
+ unsigned size; /* number of entries */
+ unsigned step; /* step between entries */
+ unsigned used; /* number currently used */
+ unsigned long *used_bitmap;
+ struct efx_filter_spec *spec;
+};
+
+struct efx_filter_state {
+ spinlock_t lock;
+ struct efx_filter_table table[EFX_FILTER_TABLE_COUNT];
+ unsigned search_depth[EFX_FILTER_TYPE_COUNT];
+};
+
+/* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
+ * key derived from the n-tuple. The initial LFSR state is 0xffff. */
+static u16 efx_filter_hash(u32 key)
+{
+ u16 tmp;
+
+ /* First 16 rounds */
+ tmp = 0x1fff ^ key >> 16;
+ tmp = tmp ^ tmp >> 3 ^ tmp >> 6;
+ tmp = tmp ^ tmp >> 9;
+ /* Last 16 rounds */
+ tmp = tmp ^ tmp << 13 ^ key;
+ tmp = tmp ^ tmp >> 3 ^ tmp >> 6;
+ return tmp ^ tmp >> 9;
+}
+
+/* To allow for hash collisions, filter search continues at these
+ * increments from the first possible entry selected by the hash. */
+static u16 efx_filter_increment(u32 key)
+{
+ return key * 2 - 1;
+}
+
+static enum efx_filter_table_id
+efx_filter_type_table_id(enum efx_filter_type type)
+{
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_FULL >> 2));
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_WILD >> 2));
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_FULL >> 2));
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_WILD >> 2));
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_FULL >> 2));
+ BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_WILD >> 2));
+ return type >> 2;
+}
+
+static void
+efx_filter_table_reset_search_depth(struct efx_filter_state *state,
+ enum efx_filter_table_id table_id)
+{
+ memset(state->search_depth + (table_id << 2), 0,
+ sizeof(state->search_depth[0]) << 2);
+}
+
+static void efx_filter_push_rx_limits(struct efx_nic *efx)
+{
+ struct efx_filter_state *state = efx->filter_state;
+ efx_oword_t filter_ctl;
+
+ efx_reado(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
+
+ EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT,
+ state->search_depth[EFX_FILTER_RX_TCP_FULL] +
+ FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT,
+ state->search_depth[EFX_FILTER_RX_TCP_WILD] +
+ FILTER_CTL_SRCH_FUDGE_WILD);
+ EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT,
+ state->search_depth[EFX_FILTER_RX_UDP_FULL] +
+ FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT,
+ state->search_depth[EFX_FILTER_RX_UDP_WILD] +
+ FILTER_CTL_SRCH_FUDGE_WILD);
+
+ if (state->table[EFX_FILTER_TABLE_RX_MAC].size) {
+ EFX_SET_OWORD_FIELD(
+ filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,
+ state->search_depth[EFX_FILTER_RX_MAC_FULL] +
+ FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_SET_OWORD_FIELD(
+ filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,
+ state->search_depth[EFX_FILTER_RX_MAC_WILD] +
+ FILTER_CTL_SRCH_FUDGE_WILD);
+ }
+
+ efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
+}
+
+/* Build a filter entry and return its n-tuple key. */
+static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
+{
+ u32 data3;
+
+ switch (efx_filter_type_table_id(spec->type)) {
+ case EFX_FILTER_TABLE_RX_IP: {
+ bool is_udp = (spec->type == EFX_FILTER_RX_UDP_FULL ||
+ spec->type == EFX_FILTER_RX_UDP_WILD);
+ EFX_POPULATE_OWORD_7(
+ *filter,
+ FRF_BZ_RSS_EN,
+ !!(spec->flags & EFX_FILTER_FLAG_RX_RSS),
+ FRF_BZ_SCATTER_EN,
+ !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER),
+ FRF_BZ_TCP_UDP, is_udp,
+ FRF_BZ_RXQ_ID, spec->dmaq_id,
+ EFX_DWORD_2, spec->data[2],
+ EFX_DWORD_1, spec->data[1],
+ EFX_DWORD_0, spec->data[0]);
+ data3 = is_udp;
+ break;
+ }
+
+ case EFX_FILTER_TABLE_RX_MAC: {
+ bool is_wild = spec->type == EFX_FILTER_RX_MAC_WILD;
+ EFX_POPULATE_OWORD_8(
+ *filter,
+ FRF_CZ_RMFT_RSS_EN,
+ !!(spec->flags & EFX_FILTER_FLAG_RX_RSS),
+ FRF_CZ_RMFT_SCATTER_EN,
+ !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER),
+ FRF_CZ_RMFT_IP_OVERRIDE,
+ !!(spec->flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP),
+ FRF_CZ_RMFT_RXQ_ID, spec->dmaq_id,
+ FRF_CZ_RMFT_WILDCARD_MATCH, is_wild,
+ FRF_CZ_RMFT_DEST_MAC_HI, spec->data[2],
+ FRF_CZ_RMFT_DEST_MAC_LO, spec->data[1],
+ FRF_CZ_RMFT_VLAN_ID, spec->data[0]);
+ data3 = is_wild;
+ break;
+ }
+
+ default:
+ BUG();
+ }
+
+ return spec->data[0] ^ spec->data[1] ^ spec->data[2] ^ data3;
+}
+
+static bool efx_filter_equal(const struct efx_filter_spec *left,
+ const struct efx_filter_spec *right)
+{
+ if (left->type != right->type ||
+ memcmp(left->data, right->data, sizeof(left->data)))
+ return false;
+
+ return true;
+}
+
+static int efx_filter_search(struct efx_filter_table *table,
+ struct efx_filter_spec *spec, u32 key,
+ bool for_insert, int *depth_required)
+{
+ unsigned hash, incr, filter_idx, depth;
+ struct efx_filter_spec *cmp;
+
+ hash = efx_filter_hash(key);
+ incr = efx_filter_increment(key);
+
+ for (depth = 1, filter_idx = hash & (table->size - 1);
+ depth <= FILTER_CTL_SRCH_MAX &&
+ test_bit(filter_idx, table->used_bitmap);
+ ++depth) {
+ cmp = &table->spec[filter_idx];
+ if (efx_filter_equal(spec, cmp))
+ goto found;
+ filter_idx = (filter_idx + incr) & (table->size - 1);
+ }
+ if (!for_insert)
+ return -ENOENT;
+ if (depth > FILTER_CTL_SRCH_MAX)
+ return -EBUSY;
+found:
+ *depth_required = depth;
+ return filter_idx;
+}
+
+/**
+ * efx_filter_insert_filter - add or replace a filter
+ * @efx: NIC in which to insert the filter
+ * @spec: Specification for the filter
+ * @replace: Flag for whether the specified filter may replace a filter
+ * with an identical match expression and equal or lower priority
+ *
+ * On success, return the filter index within its table.
+ * On failure, return a negative error code.
+ */
+int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
+ bool replace)
+{
+ struct efx_filter_state *state = efx->filter_state;
+ enum efx_filter_table_id table_id =
+ efx_filter_type_table_id(spec->type);
+ struct efx_filter_table *table = &state->table[table_id];
+ struct efx_filter_spec *saved_spec;
+ efx_oword_t filter;
+ int filter_idx, depth;
+ u32 key;
+ int rc;
+
+ if (table->size == 0)
+ return -EINVAL;
+
+ key = efx_filter_build(&filter, spec);
+
+ netif_vdbg(efx, hw, efx->net_dev,
+ "%s: type %d search_depth=%d", __func__, spec->type,
+ state->search_depth[spec->type]);
+
+ spin_lock_bh(&state->lock);
+
+ rc = efx_filter_search(table, spec, key, true, &depth);
+ if (rc < 0)
+ goto out;
+ filter_idx = rc;
+ BUG_ON(filter_idx >= table->size);
+ saved_spec = &table->spec[filter_idx];
+
+ if (test_bit(filter_idx, table->used_bitmap)) {
+ /* Should we replace the existing filter? */
+ if (!replace) {
+ rc = -EEXIST;
+ goto out;
+ }
+ if (spec->priority < saved_spec->priority) {
+ rc = -EPERM;
+ goto out;
+ }
+ } else {
+ __set_bit(filter_idx, table->used_bitmap);
+ ++table->used;
+ }
+ *saved_spec = *spec;
+
+ if (state->search_depth[spec->type] < depth) {
+ state->search_depth[spec->type] = depth;
+ efx_filter_push_rx_limits(efx);
+ }
+
+ efx_writeo(efx, &filter, table->offset + table->step * filter_idx);
+
+ netif_vdbg(efx, hw, efx->net_dev,
+ "%s: filter type %d index %d rxq %u set",
+ __func__, spec->type, filter_idx, spec->dmaq_id);
+
+out:
+ spin_unlock_bh(&state->lock);
+ return rc;
+}
+
+static void efx_filter_table_clear_entry(struct efx_nic *efx,
+ struct efx_filter_table *table,
+ int filter_idx)
+{
+ static efx_oword_t filter;
+
+ if (test_bit(filter_idx, table->used_bitmap)) {
+ __clear_bit(filter_idx, table->used_bitmap);
+ --table->used;
+ memset(&table->spec[filter_idx], 0, sizeof(table->spec[0]));
+
+ efx_writeo(efx, &filter,
+ table->offset + table->step * filter_idx);
+ }
+}
+
+/**
+ * efx_filter_remove_filter - remove a filter by specification
+ * @efx: NIC from which to remove the filter
+ * @spec: Specification for the filter
+ *
+ * On success, return zero.
+ * On failure, return a negative error code.
+ */
+int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec)
+{
+ struct efx_filter_state *state = efx->filter_state;
+ enum efx_filter_table_id table_id =
+ efx_filter_type_table_id(spec->type);
+ struct efx_filter_table *table = &state->table[table_id];
+ struct efx_filter_spec *saved_spec;
+ efx_oword_t filter;
+ int filter_idx, depth;
+ u32 key;
+ int rc;
+
+ key = efx_filter_build(&filter, spec);
+
+ spin_lock_bh(&state->lock);
+
+ rc = efx_filter_search(table, spec, key, false, &depth);
+ if (rc < 0)
+ goto out;
+ filter_idx = rc;
+ saved_spec = &table->spec[filter_idx];
+
+ if (spec->priority < saved_spec->priority) {
+ rc = -EPERM;
+ goto out;
+ }
+
+ efx_filter_table_clear_entry(efx, table, filter_idx);
+ if (table->used == 0)
+ efx_filter_table_reset_search_depth(state, table_id);
+ rc = 0;
+
+out:
+ spin_unlock_bh(&state->lock);
+ return rc;
+}
+
+/**
+ * efx_filter_table_clear - remove filters from a table by priority
+ * @efx: NIC from which to remove the filters
+ * @table_id: Table from which to remove the filters
+ * @priority: Maximum priority to remove
+ */
+void efx_filter_table_clear(struct efx_nic *efx,
+ enum efx_filter_table_id table_id,
+ enum efx_filter_priority priority)
+{
+ struct efx_filter_state *state = efx->filter_state;
+ struct efx_filter_table *table = &state->table[table_id];
+ int filter_idx;
+
+ spin_lock_bh(&state->lock);
+
+ for (filter_idx = 0; filter_idx < table->size; ++filter_idx)
+ if (table->spec[filter_idx].priority <= priority)
+ efx_filter_table_clear_entry(efx, table, filter_idx);
+ if (table->used == 0)
+ efx_filter_table_reset_search_depth(state, table_id);
+
+ spin_unlock_bh(&state->lock);
+}
+
+/* Restore filter stater after reset */
+void efx_restore_filters(struct efx_nic *efx)
+{
+ struct efx_filter_state *state = efx->filter_state;
+ enum efx_filter_table_id table_id;
+ struct efx_filter_table *table;
+ efx_oword_t filter;
+ int filter_idx;
+
+ spin_lock_bh(&state->lock);
+
+ for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
+ table = &state->table[table_id];
+ for (filter_idx = 0; filter_idx < table->size; filter_idx++) {
+ if (!test_bit(filter_idx, table->used_bitmap))
+ continue;
+ efx_filter_build(&filter, &table->spec[filter_idx]);
+ efx_writeo(efx, &filter,
+ table->offset + table->step * filter_idx);
+ }
+ }
+
+ efx_filter_push_rx_limits(efx);
+
+ spin_unlock_bh(&state->lock);
+}
+
+int efx_probe_filters(struct efx_nic *efx)
+{
+ struct efx_filter_state *state;
+ struct efx_filter_table *table;
+ unsigned table_id;
+
+ state = kzalloc(sizeof(*efx->filter_state), GFP_KERNEL);
+ if (!state)
+ return -ENOMEM;
+ efx->filter_state = state;
+
+ spin_lock_init(&state->lock);
+
+ if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
+ table = &state->table[EFX_FILTER_TABLE_RX_IP];
+ table->offset = FR_BZ_RX_FILTER_TBL0;
+ table->size = FR_BZ_RX_FILTER_TBL0_ROWS;
+ table->step = FR_BZ_RX_FILTER_TBL0_STEP;
+ }
+
+ if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) {
+ table = &state->table[EFX_FILTER_TABLE_RX_MAC];
+ table->offset = FR_CZ_RX_MAC_FILTER_TBL0;
+ table->size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
+ table->step = FR_CZ_RX_MAC_FILTER_TBL0_STEP;
+ }
+
+ for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
+ table = &state->table[table_id];
+ if (table->size == 0)
+ continue;
+ table->used_bitmap = kcalloc(BITS_TO_LONGS(table->size),
+ sizeof(unsigned long),
+ GFP_KERNEL);
+ if (!table->used_bitmap)
+ goto fail;
+ table->spec = vmalloc(table->size * sizeof(*table->spec));
+ if (!table->spec)
+ goto fail;
+ memset(table->spec, 0, table->size * sizeof(*table->spec));
+ }
+
+ return 0;
+
+fail:
+ efx_remove_filters(efx);
+ return -ENOMEM;
+}
+
+void efx_remove_filters(struct efx_nic *efx)
+{
+ struct efx_filter_state *state = efx->filter_state;
+ enum efx_filter_table_id table_id;
+
+ for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
+ kfree(state->table[table_id].used_bitmap);
+ vfree(state->table[table_id].spec);
+ }
+ kfree(state);
+}
diff --git a/drivers/net/sfc/filter.h b/drivers/net/sfc/filter.h
new file mode 100644
index 000000000000..a53319ded79c
--- /dev/null
+++ b/drivers/net/sfc/filter.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2010 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_FILTER_H
+#define EFX_FILTER_H
+
+#include <linux/types.h>
+
+enum efx_filter_table_id {
+ EFX_FILTER_TABLE_RX_IP = 0,
+ EFX_FILTER_TABLE_RX_MAC,
+ EFX_FILTER_TABLE_COUNT,
+};
+
+/**
+ * enum efx_filter_type - type of hardware filter
+ * @EFX_FILTER_RX_TCP_FULL: RX, matching TCP/IPv4 4-tuple
+ * @EFX_FILTER_RX_TCP_WILD: RX, matching TCP/IPv4 destination (host, port)
+ * @EFX_FILTER_RX_UDP_FULL: RX, matching UDP/IPv4 4-tuple
+ * @EFX_FILTER_RX_UDP_WILD: RX, matching UDP/IPv4 destination (host, port)
+ * @EFX_FILTER_RX_MAC_FULL: RX, matching Ethernet destination MAC address, VID
+ * @EFX_FILTER_RX_MAC_WILD: RX, matching Ethernet destination MAC address
+ *
+ * Falcon NICs only support the RX TCP/IPv4 and UDP/IPv4 filter types.
+ */
+enum efx_filter_type {
+ EFX_FILTER_RX_TCP_FULL = 0,
+ EFX_FILTER_RX_TCP_WILD,
+ EFX_FILTER_RX_UDP_FULL,
+ EFX_FILTER_RX_UDP_WILD,
+ EFX_FILTER_RX_MAC_FULL = 4,
+ EFX_FILTER_RX_MAC_WILD,
+ EFX_FILTER_TYPE_COUNT,
+};
+
+/**
+ * enum efx_filter_priority - priority of a hardware filter specification
+ * @EFX_FILTER_PRI_HINT: Performance hint
+ * @EFX_FILTER_PRI_MANUAL: Manually configured filter
+ * @EFX_FILTER_PRI_REQUIRED: Required for correct behaviour
+ */
+enum efx_filter_priority {
+ EFX_FILTER_PRI_HINT = 0,
+ EFX_FILTER_PRI_MANUAL,
+ EFX_FILTER_PRI_REQUIRED,
+};
+
+/**
+ * enum efx_filter_flags - flags for hardware filter specifications
+ * @EFX_FILTER_FLAG_RX_RSS: Use RSS to spread across multiple queues.
+ * By default, matching packets will be delivered only to the
+ * specified queue. If this flag is set, they will be delivered
+ * to a range of queues offset from the specified queue number
+ * according to the indirection table.
+ * @EFX_FILTER_FLAG_RX_SCATTER: Enable DMA scatter on the receiving
+ * queue.
+ * @EFX_FILTER_FLAG_RX_OVERRIDE_IP: Enables a MAC filter to override
+ * any IP filter that matches the same packet. By default, IP
+ * filters take precedence.
+ *
+ * Currently, no flags are defined for TX filters.
+ */
+enum efx_filter_flags {
+ EFX_FILTER_FLAG_RX_RSS = 0x01,
+ EFX_FILTER_FLAG_RX_SCATTER = 0x02,
+ EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04,
+};
+
+/**
+ * struct efx_filter_spec - specification for a hardware filter
+ * @type: Type of match to be performed, from &enum efx_filter_type
+ * @priority: Priority of the filter, from &enum efx_filter_priority
+ * @flags: Miscellaneous flags, from &enum efx_filter_flags
+ * @dmaq_id: Source/target queue index
+ * @data: Match data (type-dependent)
+ *
+ * Use the efx_filter_set_*() functions to initialise the @type and
+ * @data fields.
+ */
+struct efx_filter_spec {
+ u8 type:4;
+ u8 priority:4;
+ u8 flags;
+ u16 dmaq_id;
+ u32 data[3];
+};
+
+/**
+ * efx_filter_set_rx_tcp_full - specify RX filter with TCP/IPv4 full match
+ * @spec: Specification to initialise
+ * @shost: Source host address (host byte order)
+ * @sport: Source port (host byte order)
+ * @dhost: Destination host address (host byte order)
+ * @dport: Destination port (host byte order)
+ */
+static inline void
+efx_filter_set_rx_tcp_full(struct efx_filter_spec *spec,
+ u32 shost, u16 sport, u32 dhost, u16 dport)
+{
+ spec->type = EFX_FILTER_RX_TCP_FULL;
+ spec->data[0] = sport | shost << 16;
+ spec->data[1] = dport << 16 | shost >> 16;
+ spec->data[2] = dhost;
+}
+
+/**
+ * efx_filter_set_rx_tcp_wild - specify RX filter with TCP/IPv4 wildcard match
+ * @spec: Specification to initialise
+ * @dhost: Destination host address (host byte order)
+ * @dport: Destination port (host byte order)
+ */
+static inline void
+efx_filter_set_rx_tcp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport)
+{
+ spec->type = EFX_FILTER_RX_TCP_WILD;
+ spec->data[0] = 0;
+ spec->data[1] = dport << 16;
+ spec->data[2] = dhost;
+}
+
+/**
+ * efx_filter_set_rx_udp_full - specify RX filter with UDP/IPv4 full match
+ * @spec: Specification to initialise
+ * @shost: Source host address (host byte order)
+ * @sport: Source port (host byte order)
+ * @dhost: Destination host address (host byte order)
+ * @dport: Destination port (host byte order)
+ */
+static inline void
+efx_filter_set_rx_udp_full(struct efx_filter_spec *spec,
+ u32 shost, u16 sport, u32 dhost, u16 dport)
+{
+ spec->type = EFX_FILTER_RX_UDP_FULL;
+ spec->data[0] = sport | shost << 16;
+ spec->data[1] = dport << 16 | shost >> 16;
+ spec->data[2] = dhost;
+}
+
+/**
+ * efx_filter_set_rx_udp_wild - specify RX filter with UDP/IPv4 wildcard match
+ * @spec: Specification to initialise
+ * @dhost: Destination host address (host byte order)
+ * @dport: Destination port (host byte order)
+ */
+static inline void
+efx_filter_set_rx_udp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport)
+{
+ spec->type = EFX_FILTER_RX_UDP_WILD;
+ spec->data[0] = dport;
+ spec->data[1] = 0;
+ spec->data[2] = dhost;
+}
+
+/**
+ * efx_filter_set_rx_mac_full - specify RX filter with MAC full match
+ * @spec: Specification to initialise
+ * @vid: VLAN ID
+ * @addr: Destination MAC address
+ */
+static inline void efx_filter_set_rx_mac_full(struct efx_filter_spec *spec,
+ u16 vid, const u8 *addr)
+{
+ spec->type = EFX_FILTER_RX_MAC_FULL;
+ spec->data[0] = vid;
+ spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5];
+ spec->data[2] = addr[0] << 8 | addr[1];
+}
+
+/**
+ * efx_filter_set_rx_mac_full - specify RX filter with MAC wildcard match
+ * @spec: Specification to initialise
+ * @addr: Destination MAC address
+ */
+static inline void efx_filter_set_rx_mac_wild(struct efx_filter_spec *spec,
+ const u8 *addr)
+{
+ spec->type = EFX_FILTER_RX_MAC_WILD;
+ spec->data[0] = 0;
+ spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5];
+ spec->data[2] = addr[0] << 8 | addr[1];
+}
+
+#endif /* EFX_FILTER_H */
diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h
index f1aa5f374890..6886cdf87c12 100644
--- a/drivers/net/sfc/mac.h
+++ b/drivers/net/sfc/mac.h
@@ -13,10 +13,8 @@
#include "net_driver.h"
-extern struct efx_mac_operations falcon_gmac_operations;
extern struct efx_mac_operations falcon_xmac_operations;
extern struct efx_mac_operations efx_mcdi_mac_operations;
-extern void falcon_reconfigure_xmac_core(struct efx_nic *efx);
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.c b/drivers/net/sfc/mcdi.c
index 3912b8fed912..12cf910c2ce7 100644
--- a/drivers/net/sfc/mcdi.c
+++ b/drivers/net/sfc/mcdi.c
@@ -1093,8 +1093,8 @@ int efx_mcdi_reset_mc(struct efx_nic *efx)
return rc;
}
-int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type,
- const u8 *mac, int *id_out)
+static int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type,
+ const u8 *mac, int *id_out)
{
u8 inbuf[MC_CMD_WOL_FILTER_SET_IN_LEN];
u8 outbuf[MC_CMD_WOL_FILTER_SET_OUT_LEN];
diff --git a/drivers/net/sfc/mcdi.h b/drivers/net/sfc/mcdi.h
index f1f89ad4075a..c792f1d65e48 100644
--- a/drivers/net/sfc/mcdi.h
+++ b/drivers/net/sfc/mcdi.h
@@ -121,8 +121,6 @@ extern int efx_mcdi_handle_assertion(struct efx_nic *efx);
extern void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
extern int efx_mcdi_reset_port(struct efx_nic *efx);
extern int efx_mcdi_reset_mc(struct efx_nic *efx);
-extern int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type,
- const u8 *mac, int *id_out);
extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx,
const u8 *mac, int *id_out);
extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out);
diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c
index 0121e71702bf..c992742446b1 100644
--- a/drivers/net/sfc/mcdi_phy.c
+++ b/drivers/net/sfc/mcdi_phy.c
@@ -713,7 +713,8 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results,
return 0;
}
-const char *efx_mcdi_phy_test_name(struct efx_nic *efx, unsigned int index)
+static const char *efx_mcdi_phy_test_name(struct efx_nic *efx,
+ unsigned int index)
{
struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index eeaf0bd64bd3..98d946020429 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -286,46 +286,24 @@ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
*/
void efx_mdio_an_reconfigure(struct efx_nic *efx)
{
- bool xnp = (efx->link_advertising & ADVERTISED_10000baseT_Full
- || EFX_WORKAROUND_13204(efx));
int reg;
WARN_ON(!(efx->mdio.mmds & MDIO_DEVS_AN));
/* Set up the base page */
- reg = ADVERTISE_CSMA;
- if (efx->link_advertising & ADVERTISED_10baseT_Half)
- reg |= ADVERTISE_10HALF;
- if (efx->link_advertising & ADVERTISED_10baseT_Full)
- reg |= ADVERTISE_10FULL;
- if (efx->link_advertising & ADVERTISED_100baseT_Half)
- reg |= ADVERTISE_100HALF;
- if (efx->link_advertising & ADVERTISED_100baseT_Full)
- reg |= ADVERTISE_100FULL;
- if (xnp)
- reg |= ADVERTISE_RESV;
- else if (efx->link_advertising & (ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full))
- reg |= ADVERTISE_NPAGE;
+ reg = ADVERTISE_CSMA | ADVERTISE_RESV;
if (efx->link_advertising & ADVERTISED_Pause)
reg |= ADVERTISE_PAUSE_CAP;
if (efx->link_advertising & ADVERTISED_Asym_Pause)
reg |= ADVERTISE_PAUSE_ASYM;
efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
- /* Set up the (extended) next page if necessary */
- if (efx->phy_op->set_npage_adv)
- efx->phy_op->set_npage_adv(efx, efx->link_advertising);
+ /* Set up the (extended) next page */
+ efx->phy_op->set_npage_adv(efx, efx->link_advertising);
/* Enable and restart AN */
reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
- reg |= MDIO_AN_CTRL1_ENABLE;
- if (!(EFX_WORKAROUND_15195(efx) && LOOPBACK_EXTERNAL(efx)))
- reg |= MDIO_AN_CTRL1_RESTART;
- if (xnp)
- reg |= MDIO_AN_CTRL1_XNP;
- else
- reg &= ~MDIO_AN_CTRL1_XNP;
+ reg |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART | MDIO_AN_CTRL1_XNP;
efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
}
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 64e7caa4bbb5..0a7e26d73b52 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -29,6 +29,7 @@
#include <linux/device.h>
#include <linux/highmem.h>
#include <linux/workqueue.h>
+#include <linux/vmalloc.h>
#include <linux/i2c.h>
#include "enum.h"
@@ -137,6 +138,7 @@ struct efx_tx_buffer {
* @channel: The associated channel
* @buffer: The software buffer ring
* @txd: The hardware descriptor ring
+ * @ptr_mask: The size of the ring minus 1.
* @flushed: Used when handling queue flushing
* @read_count: Current read pointer.
* This is the number of buffers that have been removed from both rings.
@@ -170,6 +172,7 @@ struct efx_tx_queue {
struct efx_nic *nic;
struct efx_tx_buffer *buffer;
struct efx_special_buffer txd;
+ unsigned int ptr_mask;
enum efx_flush_state flushed;
/* Members used mainly on the completion path */
@@ -225,10 +228,9 @@ struct efx_rx_page_state {
/**
* struct efx_rx_queue - An Efx RX queue
* @efx: The associated Efx NIC
- * @queue: DMA queue number
- * @channel: The associated channel
* @buffer: The software buffer ring
* @rxd: The hardware descriptor ring
+ * @ptr_mask: The size of the ring minus 1.
* @added_count: Number of buffers added to the receive queue.
* @notified_count: Number of buffers given to NIC (<= @added_count).
* @removed_count: Number of buffers removed from the receive queue.
@@ -240,9 +242,6 @@ struct efx_rx_page_state {
* @min_fill: RX descriptor minimum non-zero fill level.
* This records the minimum fill level observed when a ring
* refill was triggered.
- * @min_overfill: RX descriptor minimum overflow fill level.
- * This records the minimum fill level at which RX queue
- * overflow was observed. It should never be set.
* @alloc_page_count: RX allocation strategy counter.
* @alloc_skb_count: RX allocation strategy counter.
* @slow_fill: Timer used to defer efx_nic_generate_fill_event().
@@ -250,10 +249,9 @@ struct efx_rx_page_state {
*/
struct efx_rx_queue {
struct efx_nic *efx;
- int queue;
- struct efx_channel *channel;
struct efx_rx_buffer *buffer;
struct efx_special_buffer rxd;
+ unsigned int ptr_mask;
int added_count;
int notified_count;
@@ -302,7 +300,6 @@ enum efx_rx_alloc_method {
*
* @efx: Associated Efx NIC
* @channel: Channel instance number
- * @name: Name for channel and IRQ
* @enabled: Channel enabled indicator
* @irq: IRQ number (MSI and MSI-X only)
* @irq_moderation: IRQ moderation value (in hardware ticks)
@@ -311,6 +308,7 @@ enum efx_rx_alloc_method {
* @reset_work: Scheduled reset work thread
* @work_pending: Is work pending via NAPI?
* @eventq: Event queue buffer
+ * @eventq_mask: Event queue pointer mask
* @eventq_read_ptr: Event queue read pointer
* @last_eventq_read_ptr: Last event queue read pointer value.
* @magic_count: Event queue test event count
@@ -327,14 +325,14 @@ enum efx_rx_alloc_method {
* @n_rx_frm_trunc: Count of RX_FRM_TRUNC errors
* @n_rx_overlength: Count of RX_OVERLENGTH errors
* @n_skbuff_leaks: Count of skbuffs leaked due to RX overrun
- * @tx_queue: Pointer to first TX queue, or %NULL if not used for TX
+ * @rx_queue: RX queue for this channel
* @tx_stop_count: Core TX queue stop count
* @tx_stop_lock: Core TX queue stop lock
+ * @tx_queue: TX queues for this channel
*/
struct efx_channel {
struct efx_nic *efx;
int channel;
- char name[IFNAMSIZ + 6];
bool enabled;
int irq;
unsigned int irq_moderation;
@@ -342,6 +340,7 @@ struct efx_channel {
struct napi_struct napi_str;
bool work_pending;
struct efx_special_buffer eventq;
+ unsigned int eventq_mask;
unsigned int eventq_read_ptr;
unsigned int last_eventq_read_ptr;
unsigned int magic_count;
@@ -366,9 +365,12 @@ struct efx_channel {
struct efx_rx_buffer *rx_pkt;
bool rx_pkt_csummed;
- struct efx_tx_queue *tx_queue;
+ struct efx_rx_queue rx_queue;
+
atomic_t tx_stop_count;
spinlock_t tx_stop_lock;
+
+ struct efx_tx_queue tx_queue[2];
};
enum efx_led_mode {
@@ -385,11 +387,6 @@ extern const unsigned int efx_loopback_mode_max;
#define LOOPBACK_MODE(efx) \
STRING_TABLE_LOOKUP((efx)->loopback_mode, efx_loopback_mode)
-extern const char *efx_interrupt_mode_names[];
-extern const unsigned int efx_interrupt_mode_max;
-#define INT_MODE(efx) \
- STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode)
-
extern const char *efx_reset_type_names[];
extern const unsigned int efx_reset_type_max;
#define RESET_TYPE(type) \
@@ -404,8 +401,6 @@ enum efx_int_mode {
};
#define EFX_INT_MODE_USE_MSI(x) (((x)->interrupt_mode) <= EFX_INT_MODE_MSI)
-#define EFX_IS10G(efx) ((efx)->link_state.speed == 10000)
-
enum nic_state {
STATE_INIT = 0,
STATE_RUNNING = 1,
@@ -618,6 +613,8 @@ union efx_multicast_hash {
efx_oword_t oword[EFX_MCAST_HASH_ENTRIES / sizeof(efx_oword_t) / 8];
};
+struct efx_filter_state;
+
/**
* struct efx_nic - an Efx NIC
* @name: Device name (net device name or bus id before net device registered)
@@ -641,6 +638,9 @@ union efx_multicast_hash {
* @tx_queue: TX DMA queues
* @rx_queue: RX DMA queues
* @channel: Channels
+ * @channel_name: Names for channels and their IRQs
+ * @rxq_entries: Size of receive queues requested by user.
+ * @txq_entries: Size of transmit queues requested by user.
* @next_buffer_table: First available buffer table id
* @n_channels: Number of channels in use
* @n_rx_channels: Number of channels used for RX (= number of RX queues)
@@ -724,10 +724,11 @@ struct efx_nic {
enum nic_state state;
enum reset_type reset_pending;
- struct efx_tx_queue tx_queue[EFX_MAX_TX_QUEUES];
- struct efx_rx_queue rx_queue[EFX_MAX_RX_QUEUES];
- struct efx_channel channel[EFX_MAX_CHANNELS];
+ struct efx_channel *channel[EFX_MAX_CHANNELS];
+ char channel_name[EFX_MAX_CHANNELS][IFNAMSIZ + 6];
+ unsigned rxq_entries;
+ unsigned txq_entries;
unsigned next_buffer_table;
unsigned n_channels;
unsigned n_rx_channels;
@@ -794,6 +795,8 @@ struct efx_nic {
u64 loopback_modes;
void *loopback_selftest;
+
+ struct efx_filter_state *filter_state;
};
static inline int efx_dev_registered(struct efx_nic *efx)
@@ -909,39 +912,67 @@ struct efx_nic_type {
*
*************************************************************************/
+static inline struct efx_channel *
+efx_get_channel(struct efx_nic *efx, unsigned index)
+{
+ EFX_BUG_ON_PARANOID(index >= efx->n_channels);
+ return efx->channel[index];
+}
+
/* Iterate over all used channels */
#define efx_for_each_channel(_channel, _efx) \
- for (_channel = &((_efx)->channel[0]); \
- _channel < &((_efx)->channel[(efx)->n_channels]); \
- _channel++)
-
-/* Iterate over all used TX queues */
-#define efx_for_each_tx_queue(_tx_queue, _efx) \
- for (_tx_queue = &((_efx)->tx_queue[0]); \
- _tx_queue < &((_efx)->tx_queue[EFX_TXQ_TYPES * \
- (_efx)->n_tx_channels]); \
- _tx_queue++)
+ for (_channel = (_efx)->channel[0]; \
+ _channel; \
+ _channel = (_channel->channel + 1 < (_efx)->n_channels) ? \
+ (_efx)->channel[_channel->channel + 1] : NULL)
+
+extern struct efx_tx_queue *
+efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type);
+
+static inline struct efx_tx_queue *
+efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type)
+{
+ struct efx_tx_queue *tx_queue = channel->tx_queue;
+ EFX_BUG_ON_PARANOID(type >= EFX_TXQ_TYPES);
+ return tx_queue->channel ? tx_queue + type : NULL;
+}
/* Iterate over all TX queues belonging to a channel */
#define efx_for_each_channel_tx_queue(_tx_queue, _channel) \
- for (_tx_queue = (_channel)->tx_queue; \
+ for (_tx_queue = efx_channel_get_tx_queue(channel, 0); \
_tx_queue && _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \
_tx_queue++)
-/* Iterate over all used RX queues */
-#define efx_for_each_rx_queue(_rx_queue, _efx) \
- for (_rx_queue = &((_efx)->rx_queue[0]); \
- _rx_queue < &((_efx)->rx_queue[(_efx)->n_rx_channels]); \
- _rx_queue++)
+static inline struct efx_rx_queue *
+efx_get_rx_queue(struct efx_nic *efx, unsigned index)
+{
+ EFX_BUG_ON_PARANOID(index >= efx->n_rx_channels);
+ return &efx->channel[index]->rx_queue;
+}
+
+static inline struct efx_rx_queue *
+efx_channel_get_rx_queue(struct efx_channel *channel)
+{
+ return channel->channel < channel->efx->n_rx_channels ?
+ &channel->rx_queue : NULL;
+}
/* Iterate over all RX queues belonging to a channel */
#define efx_for_each_channel_rx_queue(_rx_queue, _channel) \
- for (_rx_queue = &((_channel)->efx->rx_queue[(_channel)->channel]); \
+ for (_rx_queue = efx_channel_get_rx_queue(channel); \
_rx_queue; \
- _rx_queue = NULL) \
- if (_rx_queue->channel != (_channel)) \
- continue; \
- else
+ _rx_queue = NULL)
+
+static inline struct efx_channel *
+efx_rx_queue_channel(struct efx_rx_queue *rx_queue)
+{
+ return container_of(rx_queue, struct efx_channel, rx_queue);
+}
+
+static inline int efx_rx_queue_index(struct efx_rx_queue *rx_queue)
+{
+ return efx_rx_queue_channel(rx_queue)->channel;
+}
/* Returns a pointer to the specified receive buffer in the RX
* descriptor queue.
@@ -949,7 +980,7 @@ struct efx_nic_type {
static inline struct efx_rx_buffer *efx_rx_buffer(struct efx_rx_queue *rx_queue,
unsigned int index)
{
- return (&rx_queue->buffer[index]);
+ return &rx_queue->buffer[index];
}
/* Set bit in a little-endian bitfield */
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index f595d920c7c4..41c36b9a4244 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -104,7 +104,7 @@ static inline void efx_write_buf_tbl(struct efx_nic *efx, efx_qword_t *value,
static inline efx_qword_t *efx_event(struct efx_channel *channel,
unsigned int index)
{
- return (((efx_qword_t *) (channel->eventq.addr)) + index);
+ return ((efx_qword_t *) (channel->eventq.addr)) + index;
}
/* See if an event is present
@@ -119,8 +119,8 @@ static inline efx_qword_t *efx_event(struct efx_channel *channel,
*/
static inline int efx_event_present(efx_qword_t *event)
{
- return (!(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
- EFX_DWORD_IS_ALL_ONES(event->dword[1])));
+ return !(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
+ EFX_DWORD_IS_ALL_ONES(event->dword[1]));
}
static bool efx_masked_compare_oword(const efx_oword_t *a, const efx_oword_t *b,
@@ -263,8 +263,8 @@ static int efx_alloc_special_buffer(struct efx_nic *efx,
{
len = ALIGN(len, EFX_BUF_SIZE);
- buffer->addr = pci_alloc_consistent(efx->pci_dev, len,
- &buffer->dma_addr);
+ buffer->addr = dma_alloc_coherent(&efx->pci_dev->dev, len,
+ &buffer->dma_addr, GFP_KERNEL);
if (!buffer->addr)
return -ENOMEM;
buffer->len = len;
@@ -301,8 +301,8 @@ efx_free_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer)
(u64)buffer->dma_addr, buffer->len,
buffer->addr, (u64)virt_to_phys(buffer->addr));
- pci_free_consistent(efx->pci_dev, buffer->len, buffer->addr,
- buffer->dma_addr);
+ dma_free_coherent(&efx->pci_dev->dev, buffer->len, buffer->addr,
+ buffer->dma_addr);
buffer->addr = NULL;
buffer->entries = 0;
}
@@ -347,7 +347,7 @@ void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer)
static inline efx_qword_t *
efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
{
- return (((efx_qword_t *) (tx_queue->txd.addr)) + index);
+ return ((efx_qword_t *) (tx_queue->txd.addr)) + index;
}
/* This writes to the TX_DESC_WPTR; write pointer for TX descriptor ring */
@@ -356,7 +356,7 @@ static inline void efx_notify_tx_desc(struct efx_tx_queue *tx_queue)
unsigned write_ptr;
efx_dword_t reg;
- write_ptr = tx_queue->write_count & EFX_TXQ_MASK;
+ write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
EFX_POPULATE_DWORD_1(reg, FRF_AZ_TX_DESC_WPTR_DWORD, write_ptr);
efx_writed_page(tx_queue->efx, &reg,
FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue);
@@ -377,7 +377,7 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
BUG_ON(tx_queue->write_count == tx_queue->insert_count);
do {
- write_ptr = tx_queue->write_count & EFX_TXQ_MASK;
+ write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
buffer = &tx_queue->buffer[write_ptr];
txd = efx_tx_desc(tx_queue, write_ptr);
++tx_queue->write_count;
@@ -398,10 +398,11 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
int efx_nic_probe_tx(struct efx_tx_queue *tx_queue)
{
struct efx_nic *efx = tx_queue->efx;
- BUILD_BUG_ON(EFX_TXQ_SIZE < 512 || EFX_TXQ_SIZE > 4096 ||
- EFX_TXQ_SIZE & EFX_TXQ_MASK);
+ unsigned entries;
+
+ entries = tx_queue->ptr_mask + 1;
return efx_alloc_special_buffer(efx, &tx_queue->txd,
- EFX_TXQ_SIZE * sizeof(efx_qword_t));
+ entries * sizeof(efx_qword_t));
}
void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
@@ -501,7 +502,7 @@ void efx_nic_remove_tx(struct efx_tx_queue *tx_queue)
static inline efx_qword_t *
efx_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
{
- return (((efx_qword_t *) (rx_queue->rxd.addr)) + index);
+ return ((efx_qword_t *) (rx_queue->rxd.addr)) + index;
}
/* This creates an entry in the RX descriptor queue */
@@ -526,30 +527,32 @@ efx_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned index)
*/
void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue)
{
+ struct efx_nic *efx = rx_queue->efx;
efx_dword_t reg;
unsigned write_ptr;
while (rx_queue->notified_count != rx_queue->added_count) {
- efx_build_rx_desc(rx_queue,
- rx_queue->notified_count &
- EFX_RXQ_MASK);
+ efx_build_rx_desc(
+ rx_queue,
+ rx_queue->notified_count & rx_queue->ptr_mask);
++rx_queue->notified_count;
}
wmb();
- write_ptr = rx_queue->added_count & EFX_RXQ_MASK;
+ write_ptr = rx_queue->added_count & rx_queue->ptr_mask;
EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr);
- efx_writed_page(rx_queue->efx, &reg,
- FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue);
+ efx_writed_page(efx, &reg, FR_AZ_RX_DESC_UPD_DWORD_P0,
+ efx_rx_queue_index(rx_queue));
}
int efx_nic_probe_rx(struct efx_rx_queue *rx_queue)
{
struct efx_nic *efx = rx_queue->efx;
- BUILD_BUG_ON(EFX_RXQ_SIZE < 512 || EFX_RXQ_SIZE > 4096 ||
- EFX_RXQ_SIZE & EFX_RXQ_MASK);
+ unsigned entries;
+
+ entries = rx_queue->ptr_mask + 1;
return efx_alloc_special_buffer(efx, &rx_queue->rxd,
- EFX_RXQ_SIZE * sizeof(efx_qword_t));
+ entries * sizeof(efx_qword_t));
}
void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
@@ -561,7 +564,7 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
netif_dbg(efx, hw, efx->net_dev,
"RX queue %d ring in special buffers %d-%d\n",
- rx_queue->queue, rx_queue->rxd.index,
+ efx_rx_queue_index(rx_queue), rx_queue->rxd.index,
rx_queue->rxd.index + rx_queue->rxd.entries - 1);
rx_queue->flushed = FLUSH_NONE;
@@ -575,9 +578,10 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
FRF_AZ_RX_ISCSI_HDIG_EN, iscsi_digest_en,
FRF_AZ_RX_DESCQ_BUF_BASE_ID, rx_queue->rxd.index,
FRF_AZ_RX_DESCQ_EVQ_ID,
- rx_queue->channel->channel,
+ efx_rx_queue_channel(rx_queue)->channel,
FRF_AZ_RX_DESCQ_OWNER_ID, 0,
- FRF_AZ_RX_DESCQ_LABEL, rx_queue->queue,
+ FRF_AZ_RX_DESCQ_LABEL,
+ efx_rx_queue_index(rx_queue),
FRF_AZ_RX_DESCQ_SIZE,
__ffs(rx_queue->rxd.entries),
FRF_AZ_RX_DESCQ_TYPE, 0 /* kernel queue */ ,
@@ -585,7 +589,7 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
FRF_AZ_RX_DESCQ_JUMBO, !is_b0,
FRF_AZ_RX_DESCQ_EN, 1);
efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base,
- rx_queue->queue);
+ efx_rx_queue_index(rx_queue));
}
static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue)
@@ -598,7 +602,8 @@ static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue)
/* Post a flush command */
EFX_POPULATE_OWORD_2(rx_flush_descq,
FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
- FRF_AZ_RX_FLUSH_DESCQ, rx_queue->queue);
+ FRF_AZ_RX_FLUSH_DESCQ,
+ efx_rx_queue_index(rx_queue));
efx_writeo(efx, &rx_flush_descq, FR_AZ_RX_FLUSH_DESCQ);
}
@@ -613,7 +618,7 @@ void efx_nic_fini_rx(struct efx_rx_queue *rx_queue)
/* Remove RX descriptor ring from card */
EFX_ZERO_OWORD(rx_desc_ptr);
efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base,
- rx_queue->queue);
+ efx_rx_queue_index(rx_queue));
/* Unpin RX descriptor ring */
efx_fini_special_buffer(efx, &rx_queue->rxd);
@@ -648,7 +653,7 @@ void efx_nic_eventq_read_ack(struct efx_channel *channel)
}
/* Use HW to insert a SW defined event */
-void efx_generate_event(struct efx_channel *channel, efx_qword_t *event)
+static void efx_generate_event(struct efx_channel *channel, efx_qword_t *event)
{
efx_oword_t drv_ev_reg;
@@ -680,15 +685,17 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
/* Transmit completion */
tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR);
tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
- tx_queue = &efx->tx_queue[tx_ev_q_label];
+ tx_queue = efx_channel_get_tx_queue(
+ channel, tx_ev_q_label % EFX_TXQ_TYPES);
tx_packets = ((tx_ev_desc_ptr - tx_queue->read_count) &
- EFX_TXQ_MASK);
+ tx_queue->ptr_mask);
channel->irq_mod_score += tx_packets;
efx_xmit_done(tx_queue, tx_ev_desc_ptr);
} else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) {
/* Rewrite the FIFO write pointer */
tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
- tx_queue = &efx->tx_queue[tx_ev_q_label];
+ tx_queue = efx_channel_get_tx_queue(
+ channel, tx_ev_q_label % EFX_TXQ_TYPES);
if (efx_dev_registered(efx))
netif_tx_lock(efx->net_dev);
@@ -714,6 +721,7 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
bool *rx_ev_pkt_ok,
bool *discard)
{
+ struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
struct efx_nic *efx = rx_queue->efx;
bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err;
bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err;
@@ -746,14 +754,14 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
/* Count errors that are not in MAC stats. Ignore expected
* checksum errors during self-test. */
if (rx_ev_frm_trunc)
- ++rx_queue->channel->n_rx_frm_trunc;
+ ++channel->n_rx_frm_trunc;
else if (rx_ev_tobe_disc)
- ++rx_queue->channel->n_rx_tobe_disc;
+ ++channel->n_rx_tobe_disc;
else if (!efx->loopback_selftest) {
if (rx_ev_ip_hdr_chksum_err)
- ++rx_queue->channel->n_rx_ip_hdr_chksum_err;
+ ++channel->n_rx_ip_hdr_chksum_err;
else if (rx_ev_tcp_udp_chksum_err)
- ++rx_queue->channel->n_rx_tcp_udp_chksum_err;
+ ++channel->n_rx_tcp_udp_chksum_err;
}
/* The frame must be discarded if any of these are true. */
@@ -769,7 +777,7 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
netif_dbg(efx, rx_err, efx->net_dev,
" RX queue %d unexpected RX event "
EFX_QWORD_FMT "%s%s%s%s%s%s%s%s\n",
- rx_queue->queue, EFX_QWORD_VAL(*event),
+ efx_rx_queue_index(rx_queue), EFX_QWORD_VAL(*event),
rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "",
rx_ev_ip_hdr_chksum_err ?
" [IP_HDR_CHKSUM_ERR]" : "",
@@ -791,8 +799,8 @@ efx_handle_rx_bad_index(struct efx_rx_queue *rx_queue, unsigned index)
struct efx_nic *efx = rx_queue->efx;
unsigned expected, dropped;
- expected = rx_queue->removed_count & EFX_RXQ_MASK;
- dropped = (index - expected) & EFX_RXQ_MASK;
+ expected = rx_queue->removed_count & rx_queue->ptr_mask;
+ dropped = (index - expected) & rx_queue->ptr_mask;
netif_info(efx, rx_err, efx->net_dev,
"dropped %d events (index=%d expected=%d)\n",
dropped, index, expected);
@@ -827,10 +835,10 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_Q_LABEL) !=
channel->channel);
- rx_queue = &efx->rx_queue[channel->channel];
+ rx_queue = efx_channel_get_rx_queue(channel);
rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR);
- expected_ptr = rx_queue->removed_count & EFX_RXQ_MASK;
+ expected_ptr = rx_queue->removed_count & rx_queue->ptr_mask;
if (unlikely(rx_ev_desc_ptr != expected_ptr))
efx_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr);
@@ -879,7 +887,7 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event)
/* The queue must be empty, so we won't receive any rx
* events, so efx_process_channel() won't refill the
* queue. Refill it here */
- efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
+ efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel));
else
netif_dbg(efx, hw, efx->net_dev, "channel %d received "
"generated event "EFX_QWORD_FMT"\n",
@@ -997,6 +1005,7 @@ efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
int efx_nic_process_eventq(struct efx_channel *channel, int budget)
{
+ struct efx_nic *efx = channel->efx;
unsigned int read_ptr;
efx_qword_t event, *p_event;
int ev_code;
@@ -1021,7 +1030,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget)
EFX_SET_QWORD(*p_event);
/* Increment read pointer */
- read_ptr = (read_ptr + 1) & EFX_EVQ_MASK;
+ read_ptr = (read_ptr + 1) & channel->eventq_mask;
ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE);
@@ -1033,7 +1042,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget)
break;
case FSE_AZ_EV_CODE_TX_EV:
tx_packets += efx_handle_tx_event(channel, &event);
- if (tx_packets >= EFX_TXQ_SIZE) {
+ if (tx_packets > efx->txq_entries) {
spent = budget;
goto out;
}
@@ -1068,10 +1077,11 @@ out:
int efx_nic_probe_eventq(struct efx_channel *channel)
{
struct efx_nic *efx = channel->efx;
- BUILD_BUG_ON(EFX_EVQ_SIZE < 512 || EFX_EVQ_SIZE > 32768 ||
- EFX_EVQ_SIZE & EFX_EVQ_MASK);
+ unsigned entries;
+
+ entries = channel->eventq_mask + 1;
return efx_alloc_special_buffer(efx, &channel->eventq,
- EFX_EVQ_SIZE * sizeof(efx_qword_t));
+ entries * sizeof(efx_qword_t));
}
void efx_nic_init_eventq(struct efx_channel *channel)
@@ -1163,11 +1173,11 @@ void efx_nic_generate_fill_event(struct efx_channel *channel)
static void efx_poll_flush_events(struct efx_nic *efx)
{
- struct efx_channel *channel = &efx->channel[0];
+ struct efx_channel *channel = efx_get_channel(efx, 0);
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
unsigned int read_ptr = channel->eventq_read_ptr;
- unsigned int end_ptr = (read_ptr - 1) & EFX_EVQ_MASK;
+ unsigned int end_ptr = (read_ptr - 1) & channel->eventq_mask;
do {
efx_qword_t *event = efx_event(channel, read_ptr);
@@ -1185,7 +1195,9 @@ static void efx_poll_flush_events(struct efx_nic *efx)
ev_queue = EFX_QWORD_FIELD(*event,
FSF_AZ_DRIVER_EV_SUBDATA);
if (ev_queue < EFX_TXQ_TYPES * efx->n_tx_channels) {
- tx_queue = efx->tx_queue + ev_queue;
+ tx_queue = efx_get_tx_queue(
+ efx, ev_queue / EFX_TXQ_TYPES,
+ ev_queue % EFX_TXQ_TYPES);
tx_queue->flushed = FLUSH_DONE;
}
} else if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV &&
@@ -1195,7 +1207,7 @@ static void efx_poll_flush_events(struct efx_nic *efx)
ev_failed = EFX_QWORD_FIELD(
*event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);
if (ev_queue < efx->n_rx_channels) {
- rx_queue = efx->rx_queue + ev_queue;
+ rx_queue = efx_get_rx_queue(efx, ev_queue);
rx_queue->flushed =
ev_failed ? FLUSH_FAILED : FLUSH_DONE;
}
@@ -1205,7 +1217,7 @@ static void efx_poll_flush_events(struct efx_nic *efx)
* it's ok to throw away every non-flush event */
EFX_SET_QWORD(*event);
- read_ptr = (read_ptr + 1) & EFX_EVQ_MASK;
+ read_ptr = (read_ptr + 1) & channel->eventq_mask;
} while (read_ptr != end_ptr);
channel->eventq_read_ptr = read_ptr;
@@ -1216,6 +1228,7 @@ static void efx_poll_flush_events(struct efx_nic *efx)
* serialise them */
int efx_nic_flush_queues(struct efx_nic *efx)
{
+ struct efx_channel *channel;
struct efx_rx_queue *rx_queue;
struct efx_tx_queue *tx_queue;
int i, tx_pending, rx_pending;
@@ -1224,29 +1237,35 @@ int efx_nic_flush_queues(struct efx_nic *efx)
efx->type->prepare_flush(efx);
/* Flush all tx queues in parallel */
- efx_for_each_tx_queue(tx_queue, efx)
- efx_flush_tx_queue(tx_queue);
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_tx_queue(tx_queue, channel)
+ efx_flush_tx_queue(tx_queue);
+ }
/* The hardware supports four concurrent rx flushes, each of which may
* need to be retried if there is an outstanding descriptor fetch */
for (i = 0; i < EFX_FLUSH_POLL_COUNT; ++i) {
rx_pending = tx_pending = 0;
- efx_for_each_rx_queue(rx_queue, efx) {
- if (rx_queue->flushed == FLUSH_PENDING)
- ++rx_pending;
- }
- efx_for_each_rx_queue(rx_queue, efx) {
- if (rx_pending == EFX_RX_FLUSH_COUNT)
- break;
- if (rx_queue->flushed == FLUSH_FAILED ||
- rx_queue->flushed == FLUSH_NONE) {
- efx_flush_rx_queue(rx_queue);
- ++rx_pending;
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_rx_queue(rx_queue, channel) {
+ if (rx_queue->flushed == FLUSH_PENDING)
+ ++rx_pending;
}
}
- efx_for_each_tx_queue(tx_queue, efx) {
- if (tx_queue->flushed != FLUSH_DONE)
- ++tx_pending;
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_rx_queue(rx_queue, channel) {
+ if (rx_pending == EFX_RX_FLUSH_COUNT)
+ break;
+ if (rx_queue->flushed == FLUSH_FAILED ||
+ rx_queue->flushed == FLUSH_NONE) {
+ efx_flush_rx_queue(rx_queue);
+ ++rx_pending;
+ }
+ }
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
+ if (tx_queue->flushed != FLUSH_DONE)
+ ++tx_pending;
+ }
}
if (rx_pending == 0 && tx_pending == 0)
@@ -1258,19 +1277,21 @@ int efx_nic_flush_queues(struct efx_nic *efx)
/* Mark the queues as all flushed. We're going to return failure
* leading to a reset, or fake up success anyway */
- efx_for_each_tx_queue(tx_queue, efx) {
- if (tx_queue->flushed != FLUSH_DONE)
- netif_err(efx, hw, efx->net_dev,
- "tx queue %d flush command timed out\n",
- tx_queue->queue);
- tx_queue->flushed = FLUSH_DONE;
- }
- efx_for_each_rx_queue(rx_queue, efx) {
- if (rx_queue->flushed != FLUSH_DONE)
- netif_err(efx, hw, efx->net_dev,
- "rx queue %d flush command timed out\n",
- rx_queue->queue);
- rx_queue->flushed = FLUSH_DONE;
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
+ if (tx_queue->flushed != FLUSH_DONE)
+ netif_err(efx, hw, efx->net_dev,
+ "tx queue %d flush command timed out\n",
+ tx_queue->queue);
+ tx_queue->flushed = FLUSH_DONE;
+ }
+ efx_for_each_channel_rx_queue(rx_queue, channel) {
+ if (rx_queue->flushed != FLUSH_DONE)
+ netif_err(efx, hw, efx->net_dev,
+ "rx queue %d flush command timed out\n",
+ efx_rx_queue_index(rx_queue));
+ rx_queue->flushed = FLUSH_DONE;
+ }
}
return -ETIMEDOUT;
@@ -1457,7 +1478,7 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
*/
static irqreturn_t efx_msi_interrupt(int irq, void *dev_id)
{
- struct efx_channel *channel = dev_id;
+ struct efx_channel *channel = *(struct efx_channel **)dev_id;
struct efx_nic *efx = channel->efx;
efx_oword_t *int_ker = efx->irq_status.addr;
int syserr;
@@ -1532,7 +1553,8 @@ int efx_nic_init_interrupt(struct efx_nic *efx)
efx_for_each_channel(channel, efx) {
rc = request_irq(channel->irq, efx_msi_interrupt,
IRQF_PROBE_SHARED, /* Not shared */
- channel->name, channel);
+ efx->channel_name[channel->channel],
+ &efx->channel[channel->channel]);
if (rc) {
netif_err(efx, drv, efx->net_dev,
"failed to hook IRQ %d\n", channel->irq);
@@ -1544,7 +1566,7 @@ int efx_nic_init_interrupt(struct efx_nic *efx)
fail2:
efx_for_each_channel(channel, efx)
- free_irq(channel->irq, channel);
+ free_irq(channel->irq, &efx->channel[channel->channel]);
fail1:
return rc;
}
@@ -1557,7 +1579,7 @@ void efx_nic_fini_interrupt(struct efx_nic *efx)
/* Disable MSI/MSI-X interrupts */
efx_for_each_channel(channel, efx) {
if (channel->irq)
- free_irq(channel->irq, channel);
+ free_irq(channel->irq, &efx->channel[channel->channel]);
}
/* ACK legacy interrupt */
@@ -1827,8 +1849,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
REGISTER_TABLE_BB_CZ(TX_DESC_PTR_TBL),
REGISTER_TABLE_AA(EVQ_PTR_TBL_KER),
REGISTER_TABLE_BB_CZ(EVQ_PTR_TBL),
- /* The register buffer is allocated with slab, so we can't
- * reasonably read all of the buffer table (up to 8MB!).
+ /* We can't reasonably read all of the buffer table (up to 8MB!).
* However this driver will only use a few entries. Reading
* 1K entries allows for some expansion of queue count and
* size before we need to change the version. */
@@ -1836,7 +1857,6 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
A, A, 8, 1024),
REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL,
B, Z, 8, 1024),
- /* RX_FILTER_TBL{0,1} is huge and not used by this driver */
REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0),
REGISTER_TABLE_BB_CZ(TIMER_TBL),
REGISTER_TABLE_BB_CZ(TX_PACE_TBL),
@@ -1846,6 +1866,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
REGISTER_TABLE_CZ(MC_TREG_SMEM),
/* MSIX_PBA_TABLE is not mapped */
/* SRM_DBG is not mapped (and is redundant with BUF_FLL_TBL) */
+ REGISTER_TABLE_BZ(RX_FILTER_TBL0),
};
size_t efx_nic_get_regs_len(struct efx_nic *efx)
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index 5bc26137257b..1dab609757fb 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -11,17 +11,12 @@
#define EFX_PHY_H
/****************************************************************************
- * 10Xpress (SFX7101 and SFT9001) PHYs
+ * 10Xpress (SFX7101) PHY
*/
extern struct efx_phy_operations falcon_sfx7101_phy_ops;
-extern struct efx_phy_operations falcon_sft9001_phy_ops;
extern void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
-/* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed
- * to boot due to corrupt flash, or some other negative error code. */
-extern int sft9001_wait_boot(struct efx_nic *efx);
-
/****************************************************************************
* AMCC/Quake QT202x PHYs
*/
@@ -42,6 +37,17 @@ extern struct efx_phy_operations falcon_qt202x_phy_ops;
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;
+
+#define TXC_GPIO_DIR_INPUT 0
+#define TXC_GPIO_DIR_OUTPUT 1
+
+extern void falcon_txc_set_gpio_dir(struct efx_nic *efx, int pin, int dir);
+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;
diff --git a/drivers/net/sfc/regs.h b/drivers/net/sfc/regs.h
index 18a3be428348..96430ed81c36 100644
--- a/drivers/net/sfc/regs.h
+++ b/drivers/net/sfc/regs.h
@@ -2893,6 +2893,20 @@
#define FRF_AB_XX_FORCE_SIG_WIDTH 8
#define FFE_AB_XX_FORCE_SIG_ALL_LANES 0xff
+/* RX_MAC_FILTER_TBL0 */
+/* RMFT_DEST_MAC is wider than 32 bits */
+#define FRF_CZ_RMFT_DEST_MAC_LO_LBN 12
+#define FRF_CZ_RMFT_DEST_MAC_LO_WIDTH 32
+#define FRF_CZ_RMFT_DEST_MAC_HI_LBN 44
+#define FRF_CZ_RMFT_DEST_MAC_HI_WIDTH 16
+
+/* TX_MAC_FILTER_TBL0 */
+/* TMFT_SRC_MAC is wider than 32 bits */
+#define FRF_CZ_TMFT_SRC_MAC_LO_LBN 12
+#define FRF_CZ_TMFT_SRC_MAC_LO_WIDTH 32
+#define FRF_CZ_TMFT_SRC_MAC_HI_LBN 44
+#define FRF_CZ_TMFT_SRC_MAC_HI_WIDTH 16
+
/* DRIVER_EV */
/* Sub-fields of an RX flush completion event */
#define FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL_LBN 12
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 799c461ce7b8..6d0959b5158e 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -133,7 +133,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue)
unsigned index, count;
for (count = 0; count < EFX_RX_BATCH; ++count) {
- index = rx_queue->added_count & EFX_RXQ_MASK;
+ index = rx_queue->added_count & rx_queue->ptr_mask;
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->skb = netdev_alloc_skb(net_dev, skb_len);
@@ -208,7 +208,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
dma_addr += sizeof(struct efx_rx_page_state);
split:
- index = rx_queue->added_count & EFX_RXQ_MASK;
+ index = rx_queue->added_count & rx_queue->ptr_mask;
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
rx_buf->skb = NULL;
@@ -285,7 +285,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue,
* we'd like to insert an additional descriptor whilst leaving
* EFX_RXD_HEAD_ROOM for the non-recycle path */
fill_level = (rx_queue->added_count - rx_queue->removed_count + 2);
- if (unlikely(fill_level >= EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM)) {
+ if (unlikely(fill_level > rx_queue->max_fill)) {
/* We could place "state" on a list, and drain the list in
* efx_fast_push_rx_descriptors(). For now, this will do. */
return;
@@ -294,7 +294,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue,
++state->refcnt;
get_page(rx_buf->page);
- index = rx_queue->added_count & EFX_RXQ_MASK;
+ index = rx_queue->added_count & rx_queue->ptr_mask;
new_buf = efx_rx_buffer(rx_queue, index);
new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1);
new_buf->skb = NULL;
@@ -311,7 +311,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel,
struct efx_rx_buffer *rx_buf)
{
struct efx_nic *efx = channel->efx;
- struct efx_rx_queue *rx_queue = &efx->rx_queue[channel->channel];
+ struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
struct efx_rx_buffer *new_buf;
unsigned index;
@@ -319,7 +319,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel,
page_count(rx_buf->page) == 1)
efx_resurrect_rx_buffer(rx_queue, rx_buf);
- index = rx_queue->added_count & EFX_RXQ_MASK;
+ index = rx_queue->added_count & rx_queue->ptr_mask;
new_buf = efx_rx_buffer(rx_queue, index);
memcpy(new_buf, rx_buf, sizeof(*new_buf));
@@ -341,13 +341,13 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel,
*/
void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
{
- struct efx_channel *channel = rx_queue->channel;
+ struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
unsigned fill_level;
int space, rc = 0;
/* Calculate current fill level, and exit if we don't need to fill */
fill_level = (rx_queue->added_count - rx_queue->removed_count);
- EFX_BUG_ON_PARANOID(fill_level > EFX_RXQ_SIZE);
+ EFX_BUG_ON_PARANOID(fill_level > rx_queue->efx->rxq_entries);
if (fill_level >= rx_queue->fast_fill_trigger)
goto out;
@@ -364,7 +364,8 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev,
"RX queue %d fast-filling descriptor ring from"
" level %d to level %d using %s allocation\n",
- rx_queue->queue, fill_level, rx_queue->fast_fill_limit,
+ efx_rx_queue_index(rx_queue), fill_level,
+ rx_queue->fast_fill_limit,
channel->rx_alloc_push_pages ? "page" : "skb");
do {
@@ -382,7 +383,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev,
"RX queue %d fast-filled descriptor ring "
- "to level %d\n", rx_queue->queue,
+ "to level %d\n", efx_rx_queue_index(rx_queue),
rx_queue->added_count - rx_queue->removed_count);
out:
@@ -393,7 +394,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
void efx_rx_slow_fill(unsigned long context)
{
struct efx_rx_queue *rx_queue = (struct efx_rx_queue *)context;
- struct efx_channel *channel = rx_queue->channel;
+ struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
/* Post an event to cause NAPI to run and refill the queue */
efx_nic_generate_fill_event(channel);
@@ -421,7 +422,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
netif_err(efx, rx_err, efx->net_dev,
" RX queue %d seriously overlength "
"RX event (0x%x > 0x%x+0x%x). Leaking\n",
- rx_queue->queue, len, max_len,
+ efx_rx_queue_index(rx_queue), len, max_len,
efx->type->rx_buffer_padding);
/* If this buffer was skb-allocated, then the meta
* data at the end of the skb will be trashed. So
@@ -434,10 +435,10 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
netif_err(efx, rx_err, efx->net_dev,
" RX queue %d overlength RX event "
"(0x%x > 0x%x)\n",
- rx_queue->queue, len, max_len);
+ efx_rx_queue_index(rx_queue), len, max_len);
}
- rx_queue->channel->n_rx_overlength++;
+ efx_rx_queue_channel(rx_queue)->n_rx_overlength++;
}
/* Pass a received packet up through the generic LRO stack
@@ -507,7 +508,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
unsigned int len, bool checksummed, bool discard)
{
struct efx_nic *efx = rx_queue->efx;
- struct efx_channel *channel = rx_queue->channel;
+ struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
struct efx_rx_buffer *rx_buf;
bool leak_packet = false;
@@ -528,7 +529,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
netif_vdbg(efx, rx_status, efx->net_dev,
"RX queue %d received id %x at %llx+%x %s%s\n",
- rx_queue->queue, index,
+ efx_rx_queue_index(rx_queue), index,
(unsigned long long)rx_buf->dma_addr, len,
(checksummed ? " [SUMMED]" : ""),
(discard ? " [DISCARD]" : ""));
@@ -560,12 +561,11 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
*/
rx_buf->len = len;
out:
- if (rx_queue->channel->rx_pkt)
- __efx_rx_packet(rx_queue->channel,
- rx_queue->channel->rx_pkt,
- rx_queue->channel->rx_pkt_csummed);
- rx_queue->channel->rx_pkt = rx_buf;
- rx_queue->channel->rx_pkt_csummed = checksummed;
+ if (channel->rx_pkt)
+ __efx_rx_packet(channel,
+ channel->rx_pkt, channel->rx_pkt_csummed);
+ channel->rx_pkt = rx_buf;
+ channel->rx_pkt_csummed = checksummed;
}
/* Handle a received packet. Second half: Touches packet payload. */
@@ -615,7 +615,7 @@ void __efx_rx_packet(struct efx_channel *channel,
EFX_BUG_ON_PARANOID(!skb);
/* Set the SKB flags */
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Pass the packet up */
netif_receive_skb(skb);
@@ -650,15 +650,22 @@ void efx_rx_strategy(struct efx_channel *channel)
int efx_probe_rx_queue(struct efx_rx_queue *rx_queue)
{
struct efx_nic *efx = rx_queue->efx;
- unsigned int rxq_size;
+ unsigned int entries;
int rc;
+ /* Create the smallest power-of-two aligned ring */
+ entries = max(roundup_pow_of_two(efx->rxq_entries), EFX_MIN_DMAQ_SIZE);
+ EFX_BUG_ON_PARANOID(entries > EFX_MAX_DMAQ_SIZE);
+ rx_queue->ptr_mask = entries - 1;
+
netif_dbg(efx, probe, efx->net_dev,
- "creating RX queue %d\n", rx_queue->queue);
+ "creating RX queue %d size %#x mask %#x\n",
+ efx_rx_queue_index(rx_queue), efx->rxq_entries,
+ rx_queue->ptr_mask);
/* Allocate RX buffers */
- rxq_size = EFX_RXQ_SIZE * sizeof(*rx_queue->buffer);
- rx_queue->buffer = kzalloc(rxq_size, GFP_KERNEL);
+ rx_queue->buffer = kzalloc(entries * sizeof(*rx_queue->buffer),
+ GFP_KERNEL);
if (!rx_queue->buffer)
return -ENOMEM;
@@ -672,20 +679,20 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue)
void efx_init_rx_queue(struct efx_rx_queue *rx_queue)
{
+ struct efx_nic *efx = rx_queue->efx;
unsigned int max_fill, trigger, limit;
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
- "initialising RX queue %d\n", rx_queue->queue);
+ "initialising RX queue %d\n", efx_rx_queue_index(rx_queue));
/* Initialise ptr fields */
rx_queue->added_count = 0;
rx_queue->notified_count = 0;
rx_queue->removed_count = 0;
rx_queue->min_fill = -1U;
- rx_queue->min_overfill = -1U;
/* Initialise limit fields */
- max_fill = EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM;
+ max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM;
trigger = max_fill * min(rx_refill_threshold, 100U) / 100U;
limit = max_fill * min(rx_refill_limit, 100U) / 100U;
@@ -703,14 +710,14 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
struct efx_rx_buffer *rx_buf;
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
- "shutting down RX queue %d\n", rx_queue->queue);
+ "shutting down RX queue %d\n", efx_rx_queue_index(rx_queue));
del_timer_sync(&rx_queue->slow_fill);
efx_nic_fini_rx(rx_queue);
/* Release RX buffers NB start at index 0 not current HW ptr */
if (rx_queue->buffer) {
- for (i = 0; i <= EFX_RXQ_MASK; i++) {
+ for (i = 0; i <= rx_queue->ptr_mask; i++) {
rx_buf = efx_rx_buffer(rx_queue, i);
efx_fini_rx_buffer(rx_queue, rx_buf);
}
@@ -720,7 +727,7 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
void efx_remove_rx_queue(struct efx_rx_queue *rx_queue)
{
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
- "destroying RX queue %d\n", rx_queue->queue);
+ "destroying RX queue %d\n", efx_rx_queue_index(rx_queue));
efx_nic_remove_rx(rx_queue);
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 85f015f005d5..0ebfb99f1299 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -48,6 +48,16 @@ static const unsigned char payload_source[ETH_ALEN] = {
static const char payload_msg[] =
"Hello world! This is an Efx loopback test in progress!";
+/* Interrupt mode names */
+static const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX;
+static const char *efx_interrupt_mode_names[] = {
+ [EFX_INT_MODE_MSIX] = "MSI-X",
+ [EFX_INT_MODE_MSI] = "MSI",
+ [EFX_INT_MODE_LEGACY] = "legacy",
+};
+#define INT_MODE(efx) \
+ STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode)
+
/**
* efx_loopback_state - persistent state during a loopback selftest
* @flush: Drop all packets in efx_loopback_rx_packet
@@ -506,7 +516,7 @@ efx_test_loopback(struct efx_tx_queue *tx_queue,
for (i = 0; i < 3; i++) {
/* Determine how many packets to send */
- state->packet_count = EFX_TXQ_SIZE / 3;
+ state->packet_count = efx->txq_entries / 3;
state->packet_count = min(1 << (i << 2), state->packet_count);
state->skbs = kzalloc(sizeof(state->skbs[0]) *
state->packet_count, GFP_KERNEL);
@@ -567,7 +577,7 @@ static int efx_wait_for_link(struct efx_nic *efx)
efx->type->monitor(efx);
mutex_unlock(&efx->mac_lock);
} else {
- struct efx_channel *channel = &efx->channel[0];
+ struct efx_channel *channel = efx_get_channel(efx, 0);
if (channel->work_pending)
efx_process_channel_now(channel);
}
@@ -594,6 +604,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
{
enum efx_loopback_mode mode;
struct efx_loopback_state *state;
+ struct efx_channel *channel = efx_get_channel(efx, 0);
struct efx_tx_queue *tx_queue;
int rc = 0;
@@ -634,7 +645,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
}
/* Test both types of TX queue */
- efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) {
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
state->offload_csum = (tx_queue->queue &
EFX_TXQ_TYPE_OFFLOAD);
rc = efx_test_loopback(tx_queue,
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c
index 3fab030f8ab5..45236f58a258 100644
--- a/drivers/net/sfc/siena.c
+++ b/drivers/net/sfc/siena.c
@@ -129,7 +129,7 @@ static int siena_probe_port(struct efx_nic *efx)
return 0;
}
-void siena_remove_port(struct efx_nic *efx)
+static void siena_remove_port(struct efx_nic *efx)
{
efx->phy_op->remove(efx);
efx_nic_free_buffer(efx, &efx->stats_buffer);
@@ -450,7 +450,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
mac_stats->rx_bad_bytes);
MAC_STAT(rx_packets, RX_PKTS);
MAC_STAT(rx_good, RX_GOOD_PKTS);
- mac_stats->rx_bad = mac_stats->rx_packets - mac_stats->rx_good;
+ MAC_STAT(rx_bad, RX_BAD_FCS_PKTS);
MAC_STAT(rx_pause, RX_PAUSE_PKTS);
MAC_STAT(rx_control, RX_CONTROL_PKTS);
MAC_STAT(rx_unicast, RX_UNICAST_PKTS);
@@ -651,6 +651,6 @@ struct efx_nic_type siena_a0_nic_type = {
.tx_dc_base = 0x88000,
.rx_dc_base = 0x68000,
.offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
- NETIF_F_RXHASH),
+ NETIF_F_RXHASH | NETIF_F_NTUPLE),
.reset_world_flags = ETH_RESET_MGMT << ETH_RESET_SHARED_SHIFT,
};
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 6791be90c2fe..1bc6c48c96ee 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -19,10 +19,7 @@
#include "workarounds.h"
#include "selftest.h"
-/* We expect these MMDs to be in the package. SFT9001 also has a
- * clause 22 extension MMD, but since it doesn't have all the generic
- * MMD registers it is pointless to include it here.
- */
+/* We expect these MMDs to be in the package. */
#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \
MDIO_DEVS_PCS | \
MDIO_DEVS_PHYXS | \
@@ -33,12 +30,6 @@
(1 << LOOPBACK_PMAPMD) | \
(1 << LOOPBACK_PHYXS_WS))
-#define SFT9001_LOOPBACKS ((1 << LOOPBACK_GPHY) | \
- (1 << LOOPBACK_PHYXS) | \
- (1 << LOOPBACK_PCS) | \
- (1 << LOOPBACK_PMAPMD) | \
- (1 << LOOPBACK_PHYXS_WS))
-
/* We complain if we fail to see the link partner as 10G capable this many
* times in a row (must be > 1 as sampling the autoneg. registers is racy)
*/
@@ -50,9 +41,8 @@
#define PMA_PMD_EXT_GMII_EN_WIDTH 1
#define PMA_PMD_EXT_CLK_OUT_LBN 2
#define PMA_PMD_EXT_CLK_OUT_WIDTH 1
-#define PMA_PMD_LNPGA_POWERDOWN_LBN 8 /* SFX7101 only */
+#define PMA_PMD_LNPGA_POWERDOWN_LBN 8
#define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1
-#define PMA_PMD_EXT_CLK312_LBN 8 /* SFT9001 only */
#define PMA_PMD_EXT_CLK312_WIDTH 1
#define PMA_PMD_EXT_LPOWER_LBN 12
#define PMA_PMD_EXT_LPOWER_WIDTH 1
@@ -84,7 +74,6 @@
#define PMA_PMD_LED_FLASH (3)
#define PMA_PMD_LED_MASK 3
/* All LEDs under hardware control */
-#define SFT9001_PMA_PMD_LED_DEFAULT 0
/* Green and Amber under hardware control, Red off */
#define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
@@ -98,31 +87,7 @@
#define PMA_PMD_SPEED_LBN 4
#define PMA_PMD_SPEED_WIDTH 4
-/* Cable diagnostics - SFT9001 only */
-#define PMA_PMD_CDIAG_CTRL_REG 49213
-#define CDIAG_CTRL_IMMED_LBN 15
-#define CDIAG_CTRL_BRK_LINK_LBN 12
-#define CDIAG_CTRL_IN_PROG_LBN 11
-#define CDIAG_CTRL_LEN_UNIT_LBN 10
-#define CDIAG_CTRL_LEN_METRES 1
-#define PMA_PMD_CDIAG_RES_REG 49174
-#define CDIAG_RES_A_LBN 12
-#define CDIAG_RES_B_LBN 8
-#define CDIAG_RES_C_LBN 4
-#define CDIAG_RES_D_LBN 0
-#define CDIAG_RES_WIDTH 4
-#define CDIAG_RES_OPEN 2
-#define CDIAG_RES_OK 1
-#define CDIAG_RES_INVALID 0
-/* Set of 4 registers for pairs A-D */
-#define PMA_PMD_CDIAG_LEN_REG 49175
-
-/* Serdes control registers - SFT9001 only */
-#define PMA_PMD_CSERDES_CTRL_REG 64258
-/* Set the 156.25 MHz output to 312.5 MHz to drive Falcon's XMAC */
-#define PMA_PMD_CSERDES_DEFAULT 0x000f
-
-/* Misc register defines - SFX7101 only */
+/* Misc register defines */
#define PCS_CLOCK_CTRL_REG 55297
#define PLL312_RST_N_LBN 2
@@ -185,121 +150,17 @@ struct tenxpress_phy_data {
int bad_lp_tries;
};
-static ssize_t show_phy_short_reach(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
- int reg;
-
- reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR);
- return sprintf(buf, "%d\n", !!(reg & MDIO_PMA_10GBT_TXPWR_SHORT));
-}
-
-static ssize_t set_phy_short_reach(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
- int rc;
-
- rtnl_lock();
- if (efx->state != STATE_RUNNING) {
- rc = -EBUSY;
- } else {
- efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR,
- MDIO_PMA_10GBT_TXPWR_SHORT,
- count != 0 && *buf != '0');
- rc = efx_reconfigure_port(efx);
- }
- rtnl_unlock();
-
- return rc < 0 ? rc : (ssize_t)count;
-}
-
-static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach,
- set_phy_short_reach);
-
-int sft9001_wait_boot(struct efx_nic *efx)
-{
- unsigned long timeout = jiffies + HZ + 1;
- int boot_stat;
-
- for (;;) {
- boot_stat = efx_mdio_read(efx, MDIO_MMD_PCS,
- PCS_BOOT_STATUS_REG);
- if (boot_stat >= 0) {
- netif_dbg(efx, hw, efx->net_dev,
- "PHY boot status = %#x\n", boot_stat);
- switch (boot_stat &
- ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
- (3 << PCS_BOOT_PROGRESS_LBN) |
- (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
- (1 << PCS_BOOT_CODE_STARTED_LBN))) {
- case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
- (PCS_BOOT_PROGRESS_CHECKSUM <<
- PCS_BOOT_PROGRESS_LBN)):
- case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
- (PCS_BOOT_PROGRESS_INIT <<
- PCS_BOOT_PROGRESS_LBN) |
- (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
- return -EINVAL;
- case ((PCS_BOOT_PROGRESS_WAIT_MDIO <<
- PCS_BOOT_PROGRESS_LBN) |
- (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
- return (efx->phy_mode & PHY_MODE_SPECIAL) ?
- 0 : -EIO;
- case ((PCS_BOOT_PROGRESS_JUMP <<
- PCS_BOOT_PROGRESS_LBN) |
- (1 << PCS_BOOT_CODE_STARTED_LBN)):
- case ((PCS_BOOT_PROGRESS_JUMP <<
- PCS_BOOT_PROGRESS_LBN) |
- (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
- (1 << PCS_BOOT_CODE_STARTED_LBN)):
- return (efx->phy_mode & PHY_MODE_SPECIAL) ?
- -EIO : 0;
- default:
- if (boot_stat & (1 << PCS_BOOT_FATAL_ERROR_LBN))
- return -EIO;
- break;
- }
- }
-
- if (time_after_eq(jiffies, timeout))
- return -ETIMEDOUT;
-
- msleep(50);
- }
-}
-
static int tenxpress_init(struct efx_nic *efx)
{
- int reg;
-
- if (efx->phy_type == PHY_TYPE_SFX7101) {
- /* Enable 312.5 MHz clock */
- efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
- 1 << CLK312_EN_LBN);
- } else {
- /* Enable 312.5 MHz clock and GMII */
- reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
- reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
- (1 << PMA_PMD_EXT_CLK_OUT_LBN) |
- (1 << PMA_PMD_EXT_CLK312_LBN) |
- (1 << PMA_PMD_EXT_ROBUST_LBN));
-
- efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
- efx_mdio_set_flag(efx, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG, 1 << GPHY_ISOLATE_LBN,
- false);
- }
+ /* Enable 312.5 MHz clock */
+ efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
+ 1 << CLK312_EN_LBN);
/* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
- if (efx->phy_type == PHY_TYPE_SFX7101) {
- efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
- 1 << PMA_PMA_LED_ACTIVITY_LBN, true);
- efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
- SFX7101_PMA_PMD_LED_DEFAULT);
- }
+ efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
+ 1 << PMA_PMA_LED_ACTIVITY_LBN, true);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
+ SFX7101_PMA_PMD_LED_DEFAULT);
return 0;
}
@@ -307,7 +168,6 @@ static int tenxpress_init(struct efx_nic *efx)
static int tenxpress_phy_probe(struct efx_nic *efx)
{
struct tenxpress_phy_data *phy_data;
- int rc;
/* Allocate phy private storage */
phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
@@ -316,42 +176,15 @@ static int tenxpress_phy_probe(struct efx_nic *efx)
efx->phy_data = phy_data;
phy_data->phy_mode = efx->phy_mode;
- /* Create any special files */
- if (efx->phy_type == PHY_TYPE_SFT9001B) {
- rc = device_create_file(&efx->pci_dev->dev,
- &dev_attr_phy_short_reach);
- if (rc)
- goto fail;
- }
-
- if (efx->phy_type == PHY_TYPE_SFX7101) {
- efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
- efx->mdio.mode_support = MDIO_SUPPORTS_C45;
-
- efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
+ efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
+ efx->mdio.mode_support = MDIO_SUPPORTS_C45;
- efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
- ADVERTISED_10000baseT_Full);
- } else {
- efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
- efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+ efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
- efx->loopback_modes = (SFT9001_LOOPBACKS |
- FALCON_XMAC_LOOPBACKS |
- FALCON_GMAC_LOOPBACKS);
-
- efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
- ADVERTISED_10000baseT_Full |
- ADVERTISED_1000baseT_Full |
- ADVERTISED_100baseT_Full);
- }
+ efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
+ ADVERTISED_10000baseT_Full);
return 0;
-
-fail:
- kfree(efx->phy_data);
- efx->phy_data = NULL;
- return rc;
}
static int tenxpress_phy_init(struct efx_nic *efx)
@@ -361,16 +194,6 @@ static int tenxpress_phy_init(struct efx_nic *efx)
falcon_board(efx)->type->init_phy(efx);
if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
- if (efx->phy_type == PHY_TYPE_SFT9001A) {
- int reg;
- reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG);
- reg |= (1 << PMA_PMD_EXT_SSR_LBN);
- efx_mdio_write(efx, MDIO_MMD_PMAPMD,
- PMA_PMD_XCONTROL_REG, reg);
- mdelay(200);
- }
-
rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
return rc;
@@ -403,7 +226,7 @@ static int tenxpress_special_reset(struct efx_nic *efx)
{
int rc, reg;
- /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
+ /* The XGMAC clock is driven from the SFX7101 312MHz clock, so
* a special software reset can glitch the XGMAC sufficiently for stats
* requests to fail. */
falcon_stop_nic_stats(efx);
@@ -484,53 +307,18 @@ static bool sfx7101_link_ok(struct efx_nic *efx)
MDIO_DEVS_PHYXS);
}
-static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
-{
- u32 reg;
-
- if (efx_phy_mode_disabled(efx->phy_mode))
- return false;
- else if (efx->loopback_mode == LOOPBACK_GPHY)
- return true;
- else if (efx->loopback_mode)
- return efx_mdio_links_ok(efx,
- MDIO_DEVS_PMAPMD |
- MDIO_DEVS_PHYXS);
-
- /* We must use the same definition of link state as LASI,
- * otherwise we can miss a link state transition
- */
- if (ecmd->speed == 10000) {
- reg = efx_mdio_read(efx, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
- return reg & MDIO_PCS_10GBRT_STAT1_BLKLK;
- } else {
- reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_STATUS_REG);
- return reg & (1 << C22EXT_STATUS_LINK_LBN);
- }
-}
-
static void tenxpress_ext_loopback(struct efx_nic *efx)
{
efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1,
1 << LOOPBACK_NEAR_LBN,
efx->loopback_mode == LOOPBACK_PHYXS);
- if (efx->phy_type != PHY_TYPE_SFX7101)
- efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, GPHY_XCONTROL_REG,
- 1 << GPHY_LOOPBACK_NEAR_LBN,
- efx->loopback_mode == LOOPBACK_GPHY);
}
static void tenxpress_low_power(struct efx_nic *efx)
{
- if (efx->phy_type == PHY_TYPE_SFX7101)
- efx_mdio_set_mmds_lpower(
- efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
- TENXPRESS_REQUIRED_DEVS);
- else
- efx_mdio_set_flag(
- efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG,
- 1 << PMA_PMD_EXT_LPOWER_LBN,
- !!(efx->phy_mode & PHY_MODE_LOW_POWER));
+ efx_mdio_set_mmds_lpower(
+ efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
+ TENXPRESS_REQUIRED_DEVS);
}
static int tenxpress_phy_reconfigure(struct efx_nic *efx)
@@ -550,12 +338,7 @@ static int tenxpress_phy_reconfigure(struct efx_nic *efx)
if (loop_reset || phy_mode_change) {
tenxpress_special_reset(efx);
-
- /* Reset XAUI if we were in 10G, and are staying
- * in 10G. If we're moving into and out of 10G
- * then xaui will be reset anyway */
- if (EFX_IS10G(efx))
- falcon_reset_xaui(efx);
+ falcon_reset_xaui(efx);
}
tenxpress_low_power(efx);
@@ -578,29 +361,12 @@ static bool tenxpress_phy_poll(struct efx_nic *efx)
{
struct efx_link_state old_state = efx->link_state;
- if (efx->phy_type == PHY_TYPE_SFX7101) {
- efx->link_state.up = sfx7101_link_ok(efx);
- efx->link_state.speed = 10000;
- efx->link_state.fd = true;
- efx->link_state.fc = efx_mdio_get_pause(efx);
-
- sfx7101_check_bad_lp(efx, efx->link_state.up);
- } else {
- struct ethtool_cmd ecmd;
-
- /* Check the LASI alarm first */
- if (efx->loopback_mode == LOOPBACK_NONE &&
- !(efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT) &
- MDIO_PMA_LASI_LSALARM))
- return false;
+ efx->link_state.up = sfx7101_link_ok(efx);
+ efx->link_state.speed = 10000;
+ efx->link_state.fd = true;
+ efx->link_state.fc = efx_mdio_get_pause(efx);
- tenxpress_get_settings(efx, &ecmd);
-
- efx->link_state.up = sft9001_link_ok(efx, &ecmd);
- efx->link_state.speed = ecmd.speed;
- efx->link_state.fd = (ecmd.duplex == DUPLEX_FULL);
- efx->link_state.fc = efx_mdio_get_pause(efx);
- }
+ sfx7101_check_bad_lp(efx, efx->link_state.up);
return !efx_link_state_equal(&efx->link_state, &old_state);
}
@@ -621,10 +387,6 @@ static void sfx7101_phy_fini(struct efx_nic *efx)
static void tenxpress_phy_remove(struct efx_nic *efx)
{
- if (efx->phy_type == PHY_TYPE_SFT9001B)
- device_remove_file(&efx->pci_dev->dev,
- &dev_attr_phy_short_reach);
-
kfree(efx->phy_data);
efx->phy_data = NULL;
}
@@ -647,10 +409,7 @@ void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
(PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN);
break;
default:
- if (efx->phy_type == PHY_TYPE_SFX7101)
- reg = SFX7101_PMA_PMD_LED_DEFAULT;
- else
- reg = SFT9001_PMA_PMD_LED_DEFAULT;
+ reg = SFX7101_PMA_PMD_LED_DEFAULT;
break;
}
@@ -685,102 +444,12 @@ sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags)
return rc;
}
-static const char *const sft9001_test_names[] = {
- "bist",
- "cable.pairA.status",
- "cable.pairB.status",
- "cable.pairC.status",
- "cable.pairD.status",
- "cable.pairA.length",
- "cable.pairB.length",
- "cable.pairC.length",
- "cable.pairD.length",
-};
-
-static const char *sft9001_test_name(struct efx_nic *efx, unsigned int index)
-{
- if (index < ARRAY_SIZE(sft9001_test_names))
- return sft9001_test_names[index];
- return NULL;
-}
-
-static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
-{
- int rc = 0, rc2, i, ctrl_reg, res_reg;
-
- /* Initialise cable diagnostic results to unknown failure */
- for (i = 1; i < 9; ++i)
- results[i] = -1;
-
- /* Run cable diagnostics; wait up to 5 seconds for them to complete.
- * A cable fault is not a self-test failure, but a timeout is. */
- ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) |
- (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
- if (flags & ETH_TEST_FL_OFFLINE) {
- /* Break the link in order to run full diagnostics. We
- * must reset the PHY to resume normal service. */
- ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
- }
- efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG,
- ctrl_reg);
- i = 0;
- while (efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG) &
- (1 << CDIAG_CTRL_IN_PROG_LBN)) {
- if (++i == 50) {
- rc = -ETIMEDOUT;
- goto out;
- }
- msleep(100);
- }
- res_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_RES_REG);
- for (i = 0; i < 4; i++) {
- int pair_res =
- (res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH))
- & ((1 << CDIAG_RES_WIDTH) - 1);
- int len_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_LEN_REG + i);
- if (pair_res == CDIAG_RES_OK)
- results[1 + i] = 1;
- else if (pair_res == CDIAG_RES_INVALID)
- results[1 + i] = -1;
- else
- results[1 + i] = -pair_res;
- if (pair_res != CDIAG_RES_INVALID &&
- pair_res != CDIAG_RES_OPEN &&
- len_reg != 0xffff)
- results[5 + i] = len_reg;
- }
-
-out:
- if (flags & ETH_TEST_FL_OFFLINE) {
- /* Reset, running the BIST and then resuming normal service. */
- rc2 = tenxpress_special_reset(efx);
- results[0] = rc2 ? -1 : 1;
- if (!rc)
- rc = rc2;
-
- efx_mdio_an_reconfigure(efx);
- }
-
- return rc;
-}
-
static void
tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
u32 adv = 0, lpa = 0;
int reg;
- if (efx->phy_type != PHY_TYPE_SFX7101) {
- reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL);
- if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
- adv |= ADVERTISED_1000baseT_Full;
- reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_STATUS);
- if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
- lpa |= ADVERTISED_1000baseT_Half;
- if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
- lpa |= ADVERTISED_1000baseT_Full;
- }
reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
if (reg & MDIO_AN_10GBT_CTRL_ADV10G)
adv |= ADVERTISED_10000baseT_Full;
@@ -790,23 +459,9 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa);
- if (efx->phy_type != PHY_TYPE_SFX7101) {
- ecmd->supported |= (SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full);
- if (ecmd->speed != SPEED_10000) {
- ecmd->eth_tp_mdix =
- (efx_mdio_read(efx, MDIO_MMD_PMAPMD,
- PMA_PMD_XSTATUS_REG) &
- (1 << PMA_PMD_XSTAT_MDIX_LBN))
- ? ETH_TP_MDI_X : ETH_TP_MDI;
- }
- }
-
/* In loopback, the PHY automatically brings up the correct interface,
* but doesn't advertise the correct speed. So override it */
- if (efx->loopback_mode == LOOPBACK_GPHY)
- ecmd->speed = SPEED_1000;
- else if (LOOPBACK_EXTERNAL(efx))
+ if (LOOPBACK_EXTERNAL(efx))
ecmd->speed = SPEED_10000;
}
@@ -825,16 +480,6 @@ static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
advertising & ADVERTISED_10000baseT_Full);
}
-static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
-{
- efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL,
- 1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
- advertising & ADVERTISED_1000baseT_Full);
- efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
- MDIO_AN_10GBT_CTRL_ADV10G,
- advertising & ADVERTISED_10000baseT_Full);
-}
-
struct efx_phy_operations falcon_sfx7101_phy_ops = {
.probe = tenxpress_phy_probe,
.init = tenxpress_phy_init,
@@ -849,18 +494,3 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
.test_name = sfx7101_test_name,
.run_tests = sfx7101_run_tests,
};
-
-struct efx_phy_operations falcon_sft9001_phy_ops = {
- .probe = tenxpress_phy_probe,
- .init = tenxpress_phy_init,
- .reconfigure = tenxpress_phy_reconfigure,
- .poll = tenxpress_phy_poll,
- .fini = efx_port_dummy_op_void,
- .remove = tenxpress_phy_remove,
- .get_settings = tenxpress_get_settings,
- .set_settings = tenxpress_set_settings,
- .set_npage_adv = sft9001_set_npage_adv,
- .test_alive = efx_mdio_test_alive,
- .test_name = sft9001_test_name,
- .run_tests = sft9001_run_tests,
-};
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index c6942da2c99a..11726989fe2d 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -28,7 +28,7 @@
* The tx_queue descriptor ring fill-level must fall below this value
* before we restart the netif queue
*/
-#define EFX_TXQ_THRESHOLD (EFX_TXQ_MASK / 2u)
+#define EFX_TXQ_THRESHOLD(_efx) ((_efx)->txq_entries / 2u)
/* We need to be able to nest calls to netif_tx_stop_queue(), partly
* because of the 2 hardware queues associated with each core queue,
@@ -37,8 +37,9 @@
void efx_stop_queue(struct efx_channel *channel)
{
struct efx_nic *efx = channel->efx;
+ struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0);
- if (!channel->tx_queue)
+ if (!tx_queue)
return;
spin_lock_bh(&channel->tx_stop_lock);
@@ -46,9 +47,8 @@ void efx_stop_queue(struct efx_channel *channel)
atomic_inc(&channel->tx_stop_count);
netif_tx_stop_queue(
- netdev_get_tx_queue(
- efx->net_dev,
- channel->tx_queue->queue / EFX_TXQ_TYPES));
+ netdev_get_tx_queue(efx->net_dev,
+ tx_queue->queue / EFX_TXQ_TYPES));
spin_unlock_bh(&channel->tx_stop_lock);
}
@@ -57,8 +57,9 @@ void efx_stop_queue(struct efx_channel *channel)
void efx_wake_queue(struct efx_channel *channel)
{
struct efx_nic *efx = channel->efx;
+ struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0);
- if (!channel->tx_queue)
+ if (!tx_queue)
return;
local_bh_disable();
@@ -66,9 +67,8 @@ void efx_wake_queue(struct efx_channel *channel)
&channel->tx_stop_lock)) {
netif_vdbg(efx, tx_queued, efx->net_dev, "waking TX queue\n");
netif_tx_wake_queue(
- netdev_get_tx_queue(
- efx->net_dev,
- channel->tx_queue->queue / EFX_TXQ_TYPES));
+ netdev_get_tx_queue(efx->net_dev,
+ tx_queue->queue / EFX_TXQ_TYPES));
spin_unlock(&channel->tx_stop_lock);
}
local_bh_enable();
@@ -207,7 +207,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
}
fill_level = tx_queue->insert_count - tx_queue->old_read_count;
- q_space = EFX_TXQ_MASK - 1 - fill_level;
+ q_space = efx->txq_entries - 1 - fill_level;
/* Map for DMA. Use pci_map_single rather than pci_map_page
* since this is more efficient on machines with sparse
@@ -244,14 +244,14 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
&tx_queue->read_count;
fill_level = (tx_queue->insert_count
- tx_queue->old_read_count);
- q_space = EFX_TXQ_MASK - 1 - fill_level;
+ q_space = efx->txq_entries - 1 - fill_level;
if (unlikely(q_space-- <= 0))
goto stop;
smp_mb();
--tx_queue->stopped;
}
- insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK;
+ insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
buffer = &tx_queue->buffer[insert_ptr];
efx_tsoh_free(tx_queue, buffer);
EFX_BUG_ON_PARANOID(buffer->tsoh);
@@ -320,7 +320,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
/* Work backwards until we hit the original insert pointer value */
while (tx_queue->insert_count != tx_queue->write_count) {
--tx_queue->insert_count;
- insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK;
+ insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
buffer = &tx_queue->buffer[insert_ptr];
efx_dequeue_buffer(tx_queue, buffer);
buffer->len = 0;
@@ -350,8 +350,8 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
struct efx_nic *efx = tx_queue->efx;
unsigned int stop_index, read_ptr;
- stop_index = (index + 1) & EFX_TXQ_MASK;
- read_ptr = tx_queue->read_count & EFX_TXQ_MASK;
+ stop_index = (index + 1) & tx_queue->ptr_mask;
+ read_ptr = tx_queue->read_count & tx_queue->ptr_mask;
while (read_ptr != stop_index) {
struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr];
@@ -368,7 +368,7 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
buffer->len = 0;
++tx_queue->read_count;
- read_ptr = tx_queue->read_count & EFX_TXQ_MASK;
+ read_ptr = tx_queue->read_count & tx_queue->ptr_mask;
}
}
@@ -390,9 +390,9 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
if (unlikely(efx->port_inhibited))
return NETDEV_TX_BUSY;
- tx_queue = &efx->tx_queue[EFX_TXQ_TYPES * skb_get_queue_mapping(skb)];
- if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
- tx_queue += EFX_TXQ_TYPE_OFFLOAD;
+ tx_queue = efx_get_tx_queue(efx, skb_get_queue_mapping(skb),
+ skb->ip_summed == CHECKSUM_PARTIAL ?
+ EFX_TXQ_TYPE_OFFLOAD : 0);
return efx_enqueue_skb(tx_queue, skb);
}
@@ -402,7 +402,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
unsigned fill_level;
struct efx_nic *efx = tx_queue->efx;
- EFX_BUG_ON_PARANOID(index > EFX_TXQ_MASK);
+ EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask);
efx_dequeue_buffers(tx_queue, index);
@@ -412,7 +412,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
smp_mb();
if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) {
fill_level = tx_queue->insert_count - tx_queue->read_count;
- if (fill_level < EFX_TXQ_THRESHOLD) {
+ if (fill_level < EFX_TXQ_THRESHOLD(efx)) {
EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));
/* Do this under netif_tx_lock(), to avoid racing
@@ -430,18 +430,24 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
int efx_probe_tx_queue(struct efx_tx_queue *tx_queue)
{
struct efx_nic *efx = tx_queue->efx;
- unsigned int txq_size;
+ unsigned int entries;
int i, rc;
- netif_dbg(efx, probe, efx->net_dev, "creating TX queue %d\n",
- tx_queue->queue);
+ /* Create the smallest power-of-two aligned ring */
+ entries = max(roundup_pow_of_two(efx->txq_entries), EFX_MIN_DMAQ_SIZE);
+ EFX_BUG_ON_PARANOID(entries > EFX_MAX_DMAQ_SIZE);
+ tx_queue->ptr_mask = entries - 1;
+
+ netif_dbg(efx, probe, efx->net_dev,
+ "creating TX queue %d size %#x mask %#x\n",
+ tx_queue->queue, efx->txq_entries, tx_queue->ptr_mask);
/* Allocate software ring */
- txq_size = EFX_TXQ_SIZE * sizeof(*tx_queue->buffer);
- tx_queue->buffer = kzalloc(txq_size, GFP_KERNEL);
+ tx_queue->buffer = kzalloc(entries * sizeof(*tx_queue->buffer),
+ GFP_KERNEL);
if (!tx_queue->buffer)
return -ENOMEM;
- for (i = 0; i <= EFX_TXQ_MASK; ++i)
+ for (i = 0; i <= tx_queue->ptr_mask; ++i)
tx_queue->buffer[i].continuation = true;
/* Allocate hardware ring */
@@ -481,7 +487,7 @@ void efx_release_tx_buffers(struct efx_tx_queue *tx_queue)
/* Free any buffers left in the ring */
while (tx_queue->read_count != tx_queue->write_count) {
- buffer = &tx_queue->buffer[tx_queue->read_count & EFX_TXQ_MASK];
+ buffer = &tx_queue->buffer[tx_queue->read_count & tx_queue->ptr_mask];
efx_dequeue_buffer(tx_queue, buffer);
buffer->continuation = true;
buffer->len = 0;
@@ -741,7 +747,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
fill_level = tx_queue->insert_count - tx_queue->old_read_count;
/* -1 as there is no way to represent all descriptors used */
- q_space = EFX_TXQ_MASK - 1 - fill_level;
+ q_space = efx->txq_entries - 1 - fill_level;
while (1) {
if (unlikely(q_space-- <= 0)) {
@@ -757,7 +763,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
*(volatile unsigned *)&tx_queue->read_count;
fill_level = (tx_queue->insert_count
- tx_queue->old_read_count);
- q_space = EFX_TXQ_MASK - 1 - fill_level;
+ q_space = efx->txq_entries - 1 - fill_level;
if (unlikely(q_space-- <= 0)) {
*final_buffer = NULL;
return 1;
@@ -766,13 +772,13 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
--tx_queue->stopped;
}
- insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK;
+ insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
buffer = &tx_queue->buffer[insert_ptr];
++tx_queue->insert_count;
EFX_BUG_ON_PARANOID(tx_queue->insert_count -
- tx_queue->read_count >
- EFX_TXQ_MASK);
+ tx_queue->read_count >=
+ efx->txq_entries);
efx_tsoh_free(tx_queue, buffer);
EFX_BUG_ON_PARANOID(buffer->len);
@@ -813,7 +819,7 @@ static void efx_tso_put_header(struct efx_tx_queue *tx_queue,
{
struct efx_tx_buffer *buffer;
- buffer = &tx_queue->buffer[tx_queue->insert_count & EFX_TXQ_MASK];
+ buffer = &tx_queue->buffer[tx_queue->insert_count & tx_queue->ptr_mask];
efx_tsoh_free(tx_queue, buffer);
EFX_BUG_ON_PARANOID(buffer->len);
EFX_BUG_ON_PARANOID(buffer->unmap_len);
@@ -838,7 +844,7 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
while (tx_queue->insert_count != tx_queue->write_count) {
--tx_queue->insert_count;
buffer = &tx_queue->buffer[tx_queue->insert_count &
- EFX_TXQ_MASK];
+ tx_queue->ptr_mask];
efx_tsoh_free(tx_queue, buffer);
EFX_BUG_ON_PARANOID(buffer->skb);
if (buffer->unmap_len) {
@@ -1168,7 +1174,7 @@ static void efx_fini_tso(struct efx_tx_queue *tx_queue)
unsigned i;
if (tx_queue->buffer) {
- for (i = 0; i <= EFX_TXQ_MASK; ++i)
+ for (i = 0; i <= tx_queue->ptr_mask; ++i)
efx_tsoh_free(tx_queue, &tx_queue->buffer[i]);
}
diff --git a/drivers/net/sfc/txc43128_phy.c b/drivers/net/sfc/txc43128_phy.c
new file mode 100644
index 000000000000..351794a79215
--- /dev/null
+++ b/drivers/net/sfc/txc43128_phy.c
@@ -0,0 +1,560 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2006-2010 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+/*
+ * Driver for Transwitch/Mysticom CX4 retimer
+ * see www.transwitch.com, part is TXC-43128
+ */
+
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include "efx.h"
+#include "mdio_10g.h"
+#include "phy.h"
+#include "nic.h"
+
+/* We expect these MMDs to be in the package */
+#define TXC_REQUIRED_DEVS (MDIO_DEVS_PCS | \
+ MDIO_DEVS_PMAPMD | \
+ MDIO_DEVS_PHYXS)
+
+#define TXC_LOOPBACKS ((1 << LOOPBACK_PCS) | \
+ (1 << LOOPBACK_PMAPMD) | \
+ (1 << LOOPBACK_PHYXS_WS))
+
+/**************************************************************************
+ *
+ * Compile-time config
+ *
+ **************************************************************************
+ */
+#define TXCNAME "TXC43128"
+/* Total length of time we'll wait for the PHY to come out of reset (ms) */
+#define TXC_MAX_RESET_TIME 500
+/* Interval between checks (ms) */
+#define TXC_RESET_WAIT 10
+/* How long to run BIST (us) */
+#define TXC_BIST_DURATION 50
+
+/**************************************************************************
+ *
+ * Register definitions
+ *
+ **************************************************************************
+ */
+
+/* Command register */
+#define TXC_GLRGS_GLCMD 0xc004
+/* Useful bits in command register */
+/* Lane power-down */
+#define TXC_GLCMD_L01PD_LBN 5
+#define TXC_GLCMD_L23PD_LBN 6
+/* Limited SW reset: preserves configuration but
+ * initiates a logic reset. Self-clearing */
+#define TXC_GLCMD_LMTSWRST_LBN 14
+
+/* Signal Quality Control */
+#define TXC_GLRGS_GSGQLCTL 0xc01a
+/* Enable bit */
+#define TXC_GSGQLCT_SGQLEN_LBN 15
+/* Lane selection */
+#define TXC_GSGQLCT_LNSL_LBN 13
+#define TXC_GSGQLCT_LNSL_WIDTH 2
+
+/* Analog TX control */
+#define TXC_ALRGS_ATXCTL 0xc040
+/* Lane power-down */
+#define TXC_ATXCTL_TXPD3_LBN 15
+#define TXC_ATXCTL_TXPD2_LBN 14
+#define TXC_ATXCTL_TXPD1_LBN 13
+#define TXC_ATXCTL_TXPD0_LBN 12
+
+/* Amplitude on lanes 0, 1 */
+#define TXC_ALRGS_ATXAMP0 0xc041
+/* Amplitude on lanes 2, 3 */
+#define TXC_ALRGS_ATXAMP1 0xc042
+/* Bit position of value for lane 0 (or 2) */
+#define TXC_ATXAMP_LANE02_LBN 3
+/* Bit position of value for lane 1 (or 3) */
+#define TXC_ATXAMP_LANE13_LBN 11
+
+#define TXC_ATXAMP_1280_mV 0
+#define TXC_ATXAMP_1200_mV 8
+#define TXC_ATXAMP_1120_mV 12
+#define TXC_ATXAMP_1060_mV 14
+#define TXC_ATXAMP_0820_mV 25
+#define TXC_ATXAMP_0720_mV 26
+#define TXC_ATXAMP_0580_mV 27
+#define TXC_ATXAMP_0440_mV 28
+
+#define TXC_ATXAMP_0820_BOTH \
+ ((TXC_ATXAMP_0820_mV << TXC_ATXAMP_LANE02_LBN) \
+ | (TXC_ATXAMP_0820_mV << TXC_ATXAMP_LANE13_LBN))
+
+#define TXC_ATXAMP_DEFAULT 0x6060 /* From databook */
+
+/* Preemphasis on lanes 0, 1 */
+#define TXC_ALRGS_ATXPRE0 0xc043
+/* Preemphasis on lanes 2, 3 */
+#define TXC_ALRGS_ATXPRE1 0xc044
+
+#define TXC_ATXPRE_NONE 0
+#define TXC_ATXPRE_DEFAULT 0x1010 /* From databook */
+
+#define TXC_ALRGS_ARXCTL 0xc045
+/* Lane power-down */
+#define TXC_ARXCTL_RXPD3_LBN 15
+#define TXC_ARXCTL_RXPD2_LBN 14
+#define TXC_ARXCTL_RXPD1_LBN 13
+#define TXC_ARXCTL_RXPD0_LBN 12
+
+/* Main control */
+#define TXC_MRGS_CTL 0xc340
+/* Bits in main control */
+#define TXC_MCTL_RESET_LBN 15 /* Self clear */
+#define TXC_MCTL_TXLED_LBN 14 /* 1 to show align status */
+#define TXC_MCTL_RXLED_LBN 13 /* 1 to show align status */
+
+/* GPIO output */
+#define TXC_GPIO_OUTPUT 0xc346
+#define TXC_GPIO_DIR 0xc348
+
+/* Vendor-specific BIST registers */
+#define TXC_BIST_CTL 0xc280
+#define TXC_BIST_TXFRMCNT 0xc281
+#define TXC_BIST_RX0FRMCNT 0xc282
+#define TXC_BIST_RX1FRMCNT 0xc283
+#define TXC_BIST_RX2FRMCNT 0xc284
+#define TXC_BIST_RX3FRMCNT 0xc285
+#define TXC_BIST_RX0ERRCNT 0xc286
+#define TXC_BIST_RX1ERRCNT 0xc287
+#define TXC_BIST_RX2ERRCNT 0xc288
+#define TXC_BIST_RX3ERRCNT 0xc289
+
+/* BIST type (controls bit patter in test) */
+#define TXC_BIST_CTRL_TYPE_LBN 10
+#define TXC_BIST_CTRL_TYPE_TSD 0 /* TranSwitch Deterministic */
+#define TXC_BIST_CTRL_TYPE_CRP 1 /* CRPAT standard */
+#define TXC_BIST_CTRL_TYPE_CJP 2 /* CJPAT standard */
+#define TXC_BIST_CTRL_TYPE_TSR 3 /* TranSwitch pseudo-random */
+/* Set this to 1 for 10 bit and 0 for 8 bit */
+#define TXC_BIST_CTRL_B10EN_LBN 12
+/* Enable BIST (write 0 to disable) */
+#define TXC_BIST_CTRL_ENAB_LBN 13
+/* Stop BIST (self-clears when stop complete) */
+#define TXC_BIST_CTRL_STOP_LBN 14
+/* Start BIST (cleared by writing 1 to STOP) */
+#define TXC_BIST_CTRL_STRT_LBN 15
+
+/* Mt. Diablo test configuration */
+#define TXC_MTDIABLO_CTRL 0xc34f
+#define TXC_MTDIABLO_CTRL_PMA_LOOP_LBN 10
+
+struct txc43128_data {
+ unsigned long bug10934_timer;
+ enum efx_phy_mode phy_mode;
+ enum efx_loopback_mode loopback_mode;
+};
+
+/* The PHY sometimes needs a reset to bring the link back up. So long as
+ * it reports link down, we reset it every 5 seconds.
+ */
+#define BUG10934_RESET_INTERVAL (5 * HZ)
+
+/* Perform a reset that doesn't clear configuration changes */
+static void txc_reset_logic(struct efx_nic *efx);
+
+/* Set the output value of a gpio */
+void falcon_txc_set_gpio_val(struct efx_nic *efx, int pin, int on)
+{
+ efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, TXC_GPIO_OUTPUT, 1 << pin, on);
+}
+
+/* Set up the GPIO direction register */
+void falcon_txc_set_gpio_dir(struct efx_nic *efx, int pin, int dir)
+{
+ efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, TXC_GPIO_DIR, 1 << pin, dir);
+}
+
+/* Reset the PMA/PMD MMD. The documentation is explicit that this does a
+ * global reset (it's less clear what reset of other MMDs does).*/
+static int txc_reset_phy(struct efx_nic *efx)
+{
+ int rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PMAPMD,
+ TXC_MAX_RESET_TIME / TXC_RESET_WAIT,
+ TXC_RESET_WAIT);
+ if (rc < 0)
+ goto fail;
+
+ /* Check that all the MMDs we expect are present and responding. */
+ rc = efx_mdio_check_mmds(efx, TXC_REQUIRED_DEVS, 0);
+ if (rc < 0)
+ goto fail;
+
+ return 0;
+
+fail:
+ netif_err(efx, hw, efx->net_dev, TXCNAME ": reset timed out!\n");
+ return rc;
+}
+
+/* Run a single BIST on one MMD */
+static int txc_bist_one(struct efx_nic *efx, int mmd, int test)
+{
+ int ctrl, bctl;
+ int lane;
+ int rc = 0;
+
+ /* Set PMA to test into loopback using Mt Diablo reg as per app note */
+ ctrl = efx_mdio_read(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL);
+ ctrl |= (1 << TXC_MTDIABLO_CTRL_PMA_LOOP_LBN);
+ efx_mdio_write(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL, ctrl);
+
+ /* The BIST app. note lists these as 3 distinct steps. */
+ /* Set the BIST type */
+ bctl = (test << TXC_BIST_CTRL_TYPE_LBN);
+ efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl);
+
+ /* Set the BSTEN bit in the BIST Control register to enable */
+ bctl |= (1 << TXC_BIST_CTRL_ENAB_LBN);
+ efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl);
+
+ /* Set the BSTRT bit in the BIST Control register */
+ efx_mdio_write(efx, mmd, TXC_BIST_CTL,
+ bctl | (1 << TXC_BIST_CTRL_STRT_LBN));
+
+ /* Wait. */
+ udelay(TXC_BIST_DURATION);
+
+ /* Set the BSTOP bit in the BIST Control register */
+ bctl |= (1 << TXC_BIST_CTRL_STOP_LBN);
+ efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl);
+
+ /* The STOP bit should go off when things have stopped */
+ while (bctl & (1 << TXC_BIST_CTRL_STOP_LBN))
+ bctl = efx_mdio_read(efx, mmd, TXC_BIST_CTL);
+
+ /* Check all the error counts are 0 and all the frame counts are
+ non-zero */
+ for (lane = 0; lane < 4; lane++) {
+ int count = efx_mdio_read(efx, mmd, TXC_BIST_RX0ERRCNT + lane);
+ if (count != 0) {
+ netif_err(efx, hw, efx->net_dev, TXCNAME": BIST error. "
+ "Lane %d had %d errs\n", lane, count);
+ rc = -EIO;
+ }
+ count = efx_mdio_read(efx, mmd, TXC_BIST_RX0FRMCNT + lane);
+ if (count == 0) {
+ netif_err(efx, hw, efx->net_dev, TXCNAME": BIST error. "
+ "Lane %d got 0 frames\n", lane);
+ rc = -EIO;
+ }
+ }
+
+ if (rc == 0)
+ netif_info(efx, hw, efx->net_dev, TXCNAME": BIST pass\n");
+
+ /* Disable BIST */
+ efx_mdio_write(efx, mmd, TXC_BIST_CTL, 0);
+
+ /* Turn off loopback */
+ ctrl &= ~(1 << TXC_MTDIABLO_CTRL_PMA_LOOP_LBN);
+ efx_mdio_write(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL, ctrl);
+
+ return rc;
+}
+
+static int txc_bist(struct efx_nic *efx)
+{
+ return txc_bist_one(efx, MDIO_MMD_PCS, TXC_BIST_CTRL_TYPE_TSD);
+}
+
+/* Push the non-configurable defaults into the PHY. This must be
+ * done after every full reset */
+static void txc_apply_defaults(struct efx_nic *efx)
+{
+ int mctrl;
+
+ /* Turn amplitude down and preemphasis off on the host side
+ * (PHY<->MAC) as this is believed less likely to upset Falcon
+ * and no adverse effects have been noted. It probably also
+ * saves a picowatt or two */
+
+ /* Turn off preemphasis */
+ efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE0, TXC_ATXPRE_NONE);
+ efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE1, TXC_ATXPRE_NONE);
+
+ /* Turn down the amplitude */
+ efx_mdio_write(efx, MDIO_MMD_PHYXS,
+ TXC_ALRGS_ATXAMP0, TXC_ATXAMP_0820_BOTH);
+ efx_mdio_write(efx, MDIO_MMD_PHYXS,
+ TXC_ALRGS_ATXAMP1, TXC_ATXAMP_0820_BOTH);
+
+ /* Set the line side amplitude and preemphasis to the databook
+ * defaults as an erratum causes them to be 0 on at least some
+ * PHY rev.s */
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+ TXC_ALRGS_ATXPRE0, TXC_ATXPRE_DEFAULT);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+ TXC_ALRGS_ATXPRE1, TXC_ATXPRE_DEFAULT);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+ TXC_ALRGS_ATXAMP0, TXC_ATXAMP_DEFAULT);
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+ TXC_ALRGS_ATXAMP1, TXC_ATXAMP_DEFAULT);
+
+ /* Set up the LEDs */
+ mctrl = efx_mdio_read(efx, MDIO_MMD_PHYXS, TXC_MRGS_CTL);
+
+ /* Set the Green and Red LEDs to their default modes */
+ mctrl &= ~((1 << TXC_MCTL_TXLED_LBN) | (1 << TXC_MCTL_RXLED_LBN));
+ efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_MRGS_CTL, mctrl);
+
+ /* Databook recommends doing this after configuration changes */
+ txc_reset_logic(efx);
+
+ falcon_board(efx)->type->init_phy(efx);
+}
+
+static int txc43128_phy_probe(struct efx_nic *efx)
+{
+ struct txc43128_data *phy_data;
+
+ /* Allocate phy private storage */
+ phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
+ if (!phy_data)
+ return -ENOMEM;
+ efx->phy_data = phy_data;
+ phy_data->phy_mode = efx->phy_mode;
+
+ efx->mdio.mmds = TXC_REQUIRED_DEVS;
+ efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+
+ efx->loopback_modes = TXC_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
+
+ return 0;
+}
+
+/* Initialisation entry point for this PHY driver */
+static int txc43128_phy_init(struct efx_nic *efx)
+{
+ int rc;
+
+ rc = txc_reset_phy(efx);
+ if (rc < 0)
+ return rc;
+
+ rc = txc_bist(efx);
+ if (rc < 0)
+ return rc;
+
+ txc_apply_defaults(efx);
+
+ return 0;
+}
+
+/* Set the lane power down state in the global registers */
+static void txc_glrgs_lane_power(struct efx_nic *efx, int mmd)
+{
+ int pd = (1 << TXC_GLCMD_L01PD_LBN) | (1 << TXC_GLCMD_L23PD_LBN);
+ int ctl = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD);
+
+ if (!(efx->phy_mode & PHY_MODE_LOW_POWER))
+ ctl &= ~pd;
+ else
+ ctl |= pd;
+
+ efx_mdio_write(efx, mmd, TXC_GLRGS_GLCMD, ctl);
+}
+
+/* Set the lane power down state in the analog control registers */
+static void txc_analog_lane_power(struct efx_nic *efx, int mmd)
+{
+ int txpd = (1 << TXC_ATXCTL_TXPD3_LBN) | (1 << TXC_ATXCTL_TXPD2_LBN)
+ | (1 << TXC_ATXCTL_TXPD1_LBN) | (1 << TXC_ATXCTL_TXPD0_LBN);
+ int rxpd = (1 << TXC_ARXCTL_RXPD3_LBN) | (1 << TXC_ARXCTL_RXPD2_LBN)
+ | (1 << TXC_ARXCTL_RXPD1_LBN) | (1 << TXC_ARXCTL_RXPD0_LBN);
+ int txctl = efx_mdio_read(efx, mmd, TXC_ALRGS_ATXCTL);
+ int rxctl = efx_mdio_read(efx, mmd, TXC_ALRGS_ARXCTL);
+
+ if (!(efx->phy_mode & PHY_MODE_LOW_POWER)) {
+ txctl &= ~txpd;
+ rxctl &= ~rxpd;
+ } else {
+ txctl |= txpd;
+ rxctl |= rxpd;
+ }
+
+ efx_mdio_write(efx, mmd, TXC_ALRGS_ATXCTL, txctl);
+ efx_mdio_write(efx, mmd, TXC_ALRGS_ARXCTL, rxctl);
+}
+
+static void txc_set_power(struct efx_nic *efx)
+{
+ /* According to the data book, all the MMDs can do low power */
+ efx_mdio_set_mmds_lpower(efx,
+ !!(efx->phy_mode & PHY_MODE_LOW_POWER),
+ TXC_REQUIRED_DEVS);
+
+ /* Global register bank is in PCS, PHY XS. These control the host
+ * side and line side settings respectively. */
+ txc_glrgs_lane_power(efx, MDIO_MMD_PCS);
+ txc_glrgs_lane_power(efx, MDIO_MMD_PHYXS);
+
+ /* Analog register bank in PMA/PMD, PHY XS */
+ txc_analog_lane_power(efx, MDIO_MMD_PMAPMD);
+ txc_analog_lane_power(efx, MDIO_MMD_PHYXS);
+}
+
+static void txc_reset_logic_mmd(struct efx_nic *efx, int mmd)
+{
+ int val = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD);
+ int tries = 50;
+
+ val |= (1 << TXC_GLCMD_LMTSWRST_LBN);
+ efx_mdio_write(efx, mmd, TXC_GLRGS_GLCMD, val);
+ while (tries--) {
+ val = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD);
+ if (!(val & (1 << TXC_GLCMD_LMTSWRST_LBN)))
+ break;
+ udelay(1);
+ }
+ if (!tries)
+ netif_info(efx, hw, efx->net_dev,
+ TXCNAME " Logic reset timed out!\n");
+}
+
+/* Perform a logic reset. This preserves the configuration registers
+ * and is needed for some configuration changes to take effect */
+static void txc_reset_logic(struct efx_nic *efx)
+{
+ /* The data sheet claims we can do the logic reset on either the
+ * PCS or the PHYXS and the result is a reset of both host- and
+ * line-side logic. */
+ txc_reset_logic_mmd(efx, MDIO_MMD_PCS);
+}
+
+static bool txc43128_phy_read_link(struct efx_nic *efx)
+{
+ return efx_mdio_links_ok(efx, TXC_REQUIRED_DEVS);
+}
+
+static int txc43128_phy_reconfigure(struct efx_nic *efx)
+{
+ struct txc43128_data *phy_data = efx->phy_data;
+ enum efx_phy_mode mode_change = efx->phy_mode ^ phy_data->phy_mode;
+ bool loop_change = LOOPBACK_CHANGED(phy_data, efx, TXC_LOOPBACKS);
+
+ if (efx->phy_mode & mode_change & PHY_MODE_TX_DISABLED) {
+ txc_reset_phy(efx);
+ txc_apply_defaults(efx);
+ falcon_reset_xaui(efx);
+ mode_change &= ~PHY_MODE_TX_DISABLED;
+ }
+
+ efx_mdio_transmit_disable(efx);
+ efx_mdio_phy_reconfigure(efx);
+ if (mode_change & PHY_MODE_LOW_POWER)
+ txc_set_power(efx);
+
+ /* The data sheet claims this is required after every reconfiguration
+ * (note at end of 7.1), but we mustn't do it when nothing changes as
+ * it glitches the link, and reconfigure gets called on link change,
+ * so we get an IRQ storm on link up. */
+ if (loop_change || mode_change)
+ txc_reset_logic(efx);
+
+ phy_data->phy_mode = efx->phy_mode;
+ phy_data->loopback_mode = efx->loopback_mode;
+
+ return 0;
+}
+
+static void txc43128_phy_fini(struct efx_nic *efx)
+{
+ /* Disable link events */
+ efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, 0);
+}
+
+static void txc43128_phy_remove(struct efx_nic *efx)
+{
+ kfree(efx->phy_data);
+ efx->phy_data = NULL;
+}
+
+/* Periodic callback: this exists mainly to poll link status as we
+ * don't use LASI interrupts */
+static bool txc43128_phy_poll(struct efx_nic *efx)
+{
+ struct txc43128_data *data = efx->phy_data;
+ bool was_up = efx->link_state.up;
+
+ efx->link_state.up = txc43128_phy_read_link(efx);
+ efx->link_state.speed = 10000;
+ efx->link_state.fd = true;
+ efx->link_state.fc = efx->wanted_fc;
+
+ if (efx->link_state.up || (efx->loopback_mode != LOOPBACK_NONE)) {
+ data->bug10934_timer = jiffies;
+ } else {
+ if (time_after_eq(jiffies, (data->bug10934_timer +
+ BUG10934_RESET_INTERVAL))) {
+ data->bug10934_timer = jiffies;
+ txc_reset_logic(efx);
+ }
+ }
+
+ return efx->link_state.up != was_up;
+}
+
+static const char *txc43128_test_names[] = {
+ "bist"
+};
+
+static const char *txc43128_test_name(struct efx_nic *efx, unsigned int index)
+{
+ if (index < ARRAY_SIZE(txc43128_test_names))
+ return txc43128_test_names[index];
+ return NULL;
+}
+
+static int txc43128_run_tests(struct efx_nic *efx, int *results, unsigned flags)
+{
+ int rc;
+
+ if (!(flags & ETH_TEST_FL_OFFLINE))
+ return 0;
+
+ rc = txc_reset_phy(efx);
+ if (rc < 0)
+ return rc;
+
+ rc = txc_bist(efx);
+ txc_apply_defaults(efx);
+ results[0] = rc ? -1 : 1;
+ return rc;
+}
+
+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 = {
+ .probe = txc43128_phy_probe,
+ .init = txc43128_phy_init,
+ .reconfigure = txc43128_phy_reconfigure,
+ .poll = txc43128_phy_poll,
+ .fini = txc43128_phy_fini,
+ .remove = txc43128_phy_remove,
+ .get_settings = txc43128_get_settings,
+ .set_settings = efx_mdio_set_settings,
+ .test_alive = efx_mdio_test_alive,
+ .run_tests = txc43128_run_tests,
+ .test_name = txc43128_test_name,
+};
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 782e45a613d6..e0d63083c3a8 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -19,9 +19,7 @@
#define EFX_WORKAROUND_FALCON_A(efx) (efx_nic_rev(efx) <= EFX_REV_FALCON_A1)
#define EFX_WORKAROUND_FALCON_AB(efx) (efx_nic_rev(efx) <= EFX_REV_FALCON_B0)
#define EFX_WORKAROUND_SIENA(efx) (efx_nic_rev(efx) == EFX_REV_SIENA_A0)
-#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
-#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \
- (efx)->phy_type == PHY_TYPE_SFT9001B)
+#define EFX_WORKAROUND_10G(efx) 1
/* XAUI resets if link not detected */
#define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
@@ -58,9 +56,4 @@
/* Leak overlength packets rather than free */
#define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A
-/* Need to send XNP pages for 100BaseT */
-#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001
-/* Don't restart AN in near-side loopback */
-#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001
-
#endif /* EFX_WORKAROUNDS_H */
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 79fd02bc69fd..50259dfec583 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -798,7 +798,7 @@ static int sh_eth_rx(struct net_device *ndev)
skb->dev = ndev;
sh_eth_set_receive_align(skb);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
}
if (entry >= RX_RING_SIZE - 1)
@@ -1031,7 +1031,7 @@ static int sh_eth_phy_init(struct net_device *ndev)
mdp->duplex = -1;
/* Try connect to PHY */
- phydev = phy_connect(ndev, phy_id, &sh_eth_adjust_link,
+ phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link,
0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev)) {
dev_err(&ndev->dev, "phy_connect failed\n");
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index bbbded76ff14..581836867098 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -832,7 +832,7 @@ static u16 __devinit read_eeprom(long ioaddr, int location)
outl(0, ee_addr);
eeprom_delay();
- return (retval);
+ return retval;
}
/* Read and write the MII management registers using software-generated
@@ -1042,7 +1042,7 @@ sis900_open(struct net_device *net_dev)
init_timer(&sis_priv->timer);
sis_priv->timer.expires = jiffies + HZ;
sis_priv->timer.data = (unsigned long)net_dev;
- sis_priv->timer.function = &sis900_timer;
+ sis_priv->timer.function = sis900_timer;
add_timer(&sis_priv->timer);
return 0;
@@ -2247,9 +2247,9 @@ static inline u16 sis900_mcast_bitnr(u8 *addr, u8 revision)
/* leave 8 or 7 most siginifant bits */
if ((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV))
- return ((int)(crc >> 24));
+ return (int)(crc >> 24);
else
- return ((int)(crc >> 25));
+ return (int)(crc >> 25);
}
/**
diff --git a/drivers/net/skfp/cfm.c b/drivers/net/skfp/cfm.c
index 5310d39b5737..e395ace3120b 100644
--- a/drivers/net/skfp/cfm.c
+++ b/drivers/net/skfp/cfm.c
@@ -542,8 +542,8 @@ static void cfm_fsm(struct s_smc *smc, int cmd)
*/
int cfm_get_mac_input(struct s_smc *smc)
{
- return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B ||
- smc->mib.fddiSMTCF_State == SC5_THRU_B) ? PB : PA) ;
+ return (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B ||
+ smc->mib.fddiSMTCF_State == SC5_THRU_B) ? PB : PA;
}
/*
@@ -553,8 +553,8 @@ int cfm_get_mac_input(struct s_smc *smc)
*/
int cfm_get_mac_output(struct s_smc *smc)
{
- return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B ||
- smc->mib.fddiSMTCF_State == SC4_THRU_A) ? PB : PA) ;
+ return (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B ||
+ smc->mib.fddiSMTCF_State == SC4_THRU_A) ? PB : PA;
}
static char path_iso[] = {
@@ -623,5 +623,5 @@ int cem_build_path(struct s_smc *smc, char *to, int path_index)
LINT_USE(path_index);
- return(len) ;
+ return len;
}
diff --git a/drivers/net/skfp/drvfbi.c b/drivers/net/skfp/drvfbi.c
index c77cc14b3227..07da97c303d6 100644
--- a/drivers/net/skfp/drvfbi.c
+++ b/drivers/net/skfp/drvfbi.c
@@ -267,7 +267,7 @@ void timer_irq(struct s_smc *smc)
int pcm_get_s_port(struct s_smc *smc)
{
SK_UNUSED(smc) ;
- return(PS) ;
+ return PS;
}
/*
@@ -366,7 +366,7 @@ void sm_pm_bypass_req(struct s_smc *smc, int mode)
*/
int sm_pm_bypass_present(struct s_smc *smc)
{
- return( (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE: FALSE) ;
+ return (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE : FALSE;
}
void plc_clear_irq(struct s_smc *smc, int p)
@@ -483,9 +483,9 @@ static int is_equal_num(char comp1[], char comp2[], int num)
for (i = 0 ; i < num ; i++) {
if (comp1[i] != comp2[i])
- return (0) ;
+ return 0;
}
- return (1) ;
+ return 1;
} /* is_equal_num */
@@ -522,18 +522,18 @@ int set_oi_id_def(struct s_smc *smc)
i++ ;
break ; /* entry ok */
default:
- return (1) ; /* invalid oi_status */
+ return 1; /* invalid oi_status */
}
}
if (i == 0)
- return (2) ;
+ return 2;
if (!act_entries)
- return (3) ;
+ return 3;
/* ok, we have a valid OEM data base with an active entry */
smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[sel_id] ;
- return (0) ;
+ return 0;
}
#endif /* MULT_OEM */
diff --git a/drivers/net/skfp/ess.c b/drivers/net/skfp/ess.c
index e8387d25f24a..8639a0884f5c 100644
--- a/drivers/net/skfp/ess.c
+++ b/drivers/net/skfp/ess.c
@@ -135,7 +135,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
*/
if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) {
DB_ESS("ESS: RAF frame error, parameter type not found\n",0,0) ;
- return(fs) ;
+ return fs;
}
msg_res_type = ((struct smt_p_0015 *)p)->res_type ;
@@ -147,7 +147,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
* error in frame: para ESS command was not found
*/
DB_ESS("ESS: RAF frame error, parameter command not found\n",0,0);
- return(fs) ;
+ return fs;
}
DB_ESSN(2,"fc %x ft %x\n",sm->smt_class,sm->smt_type) ;
@@ -175,12 +175,12 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
* local and no static allocation is used
*/
if (!local || smc->mib.fddiESSPayload)
- return(fs) ;
+ return fs;
p = (void *) sm_to_para(smc,sm,SMT_P0019) ;
for (i = 0; i < 5; i++) {
if (((struct smt_p_0019 *)p)->alloc_addr.a[i]) {
- return(fs) ;
+ return fs;
}
}
@@ -199,10 +199,10 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
sm->smt_dest = smt_sba_da ;
if (smc->ess.local_sba_active)
- return(fs | I_INDICATOR) ;
+ return fs | I_INDICATOR;
if (!(db = smt_get_mbuf(smc)))
- return(fs) ;
+ return fs;
db->sm_len = mb->sm_len ;
db->sm_off = mb->sm_off ;
@@ -212,7 +212,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
(struct smt_header *)(db->sm_data+db->sm_off),
"RAF") ;
smt_send_frame(smc,db,FC_SMT_INFO,0) ;
- return(fs) ;
+ return fs;
}
/*
@@ -221,7 +221,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
*/
if (smt_check_para(smc,sm,plist_raf_alc_res)) {
DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
- return(fs) ;
+ return fs;
}
/*
@@ -242,7 +242,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
(sm->smt_tid != smc->ess.alloc_trans_id)) {
DB_ESS("ESS: Allocation Responce not accepted\n",0,0) ;
- return(fs) ;
+ return fs;
}
/*
@@ -268,7 +268,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
*/
(void)process_bw_alloc(smc,(long)payload,(long)overhead) ;
- return(fs) ;
+ return fs;
/* end of Process Allocation Request */
/*
@@ -280,7 +280,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
*/
if (sm->smt_type != SMT_REQUEST) {
DB_ESS("ESS: Do not process Change Responses\n",0,0) ;
- return(fs) ;
+ return fs;
}
/*
@@ -288,7 +288,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
*/
if (smt_check_para(smc,sm,plist_raf_chg_req)) {
DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
- return(fs) ;
+ return fs;
}
/*
@@ -300,7 +300,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
!= PRIMARY_RING) || (msg_res_type != SYNC_BW)) {
DB_ESS("ESS: RAF frame with para problem, ignoring\n",0,0) ;
- return(fs) ;
+ return fs;
}
/*
@@ -319,14 +319,14 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
* process the bandwidth allocation
*/
if(!process_bw_alloc(smc,(long)payload,(long)overhead))
- return(fs) ;
+ return fs;
/*
* send an RAF Change Reply
*/
ess_send_response(smc,sm,CHANGE_ALLOCATION) ;
- return(fs) ;
+ return fs;
/* end of Process Change Request */
/*
@@ -338,7 +338,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
*/
if (sm->smt_type != SMT_REQUEST) {
DB_ESS("ESS: Do not process a Report Reply\n",0,0) ;
- return(fs) ;
+ return fs;
}
DB_ESSN(2,"ESS: Report Request from %s\n",
@@ -349,7 +349,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
*/
if (msg_res_type != SYNC_BW) {
DB_ESS("ESS: ignoring RAF with para problem\n",0,0) ;
- return(fs) ;
+ return fs;
}
/*
@@ -357,7 +357,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
*/
ess_send_response(smc,sm,REPORT_ALLOCATION) ;
- return(fs) ;
+ return fs;
/* end of Process Report Request */
default:
@@ -368,7 +368,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
break ;
}
- return(fs) ;
+ return fs;
}
/*
@@ -418,17 +418,17 @@ static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhe
*/
/* if (smt_set_obj(smc,SMT_P320F,payload,S_SET)) {
DB_ESS("ESS: SMT does not accept the payload value\n",0,0) ;
- return(FALSE) ;
+ return FALSE;
}
if (smt_set_obj(smc,SMT_P3210,overhead,S_SET)) {
DB_ESS("ESS: SMT does not accept the overhead value\n",0,0) ;
- return(FALSE) ;
+ return FALSE;
} */
/* premliminary */
if (payload > MAX_PAYLOAD || overhead > 5000) {
DB_ESS("ESS: payload / overhead not accepted\n",0,0) ;
- return(FALSE) ;
+ return FALSE;
}
/*
@@ -468,7 +468,7 @@ static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhe
ess_config_fifo(smc) ;
set_formac_tsync(smc,smc->ess.sync_bw) ;
- return(TRUE) ;
+ return TRUE;
}
static void ess_send_response(struct s_smc *smc, struct smt_header *sm,
diff --git a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c
index 9d8d1ac48176..ca4e7bb6a5a8 100644
--- a/drivers/net/skfp/fplustm.c
+++ b/drivers/net/skfp/fplustm.c
@@ -112,8 +112,8 @@ static u_long mac_get_tneg(struct s_smc *smc)
u_long tneg ;
tneg = (u_long)((long)inpw(FM_A(FM_TNEG))<<5) ;
- return((u_long)((tneg + ((inpw(FM_A(FM_TMRS))>>10)&0x1f)) |
- 0xffe00000L)) ;
+ return (u_long)((tneg + ((inpw(FM_A(FM_TMRS))>>10)&0x1f)) |
+ 0xffe00000L) ;
}
void mac_update_counter(struct s_smc *smc)
@@ -163,7 +163,7 @@ static u_long read_mdr(struct s_smc *smc, unsigned int addr)
/* is used */
p = (u_long)inpw(FM_A(FM_MDRU))<<16 ;
p += (u_long)inpw(FM_A(FM_MDRL)) ;
- return(p) ;
+ return p;
}
#endif
@@ -887,7 +887,7 @@ int init_fplus(struct s_smc *smc)
/* make sure all PCI settings are correct */
mac_do_pci_fix(smc) ;
- return(init_mac(smc,1)) ;
+ return init_mac(smc, 1);
/* enable_formac(smc) ; */
}
@@ -989,7 +989,7 @@ static int init_mac(struct s_smc *smc, int all)
}
smc->hw.hw_state = STARTED ;
- return(0) ;
+ return 0;
}
@@ -1049,7 +1049,7 @@ void sm_ma_control(struct s_smc *smc, int mode)
int sm_mac_get_tx_state(struct s_smc *smc)
{
- return((inpw(FM_A(FM_STMCHN))>>4)&7) ;
+ return (inpw(FM_A(FM_STMCHN))>>4) & 7;
}
/*
@@ -1084,9 +1084,9 @@ static struct s_fpmc* mac_get_mc_table(struct s_smc *smc,
}
if (memcmp((char *)&tb->a,(char *)own,6))
continue ;
- return(tb) ;
+ return tb;
}
- return(slot) ; /* return first free or NULL */
+ return slot; /* return first free or NULL */
}
/*
@@ -1152,12 +1152,12 @@ int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
*/
if (can & 0x80) {
if (smc->hw.fp.smt_slots_used >= SMT_MAX_MULTI) {
- return(1) ;
+ return 1;
}
}
else {
if (smc->hw.fp.os_slots_used >= FPMAX_MULTICAST-SMT_MAX_MULTI) {
- return(1) ;
+ return 1;
}
}
@@ -1165,7 +1165,7 @@ int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
* find empty slot
*/
if (!(tb = mac_get_mc_table(smc,addr,&own,0,can & ~0x80)))
- return(1) ;
+ return 1;
tb->n++ ;
tb->a = own ;
tb->perm = (can & 0x80) ? 1 : 0 ;
@@ -1175,7 +1175,7 @@ int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
else
smc->hw.fp.os_slots_used++ ;
- return(0) ;
+ return 0;
}
/*
diff --git a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c
index d322f1b702ac..af5a755e269d 100644
--- a/drivers/net/skfp/hwmtm.c
+++ b/drivers/net/skfp/hwmtm.c
@@ -232,16 +232,16 @@ u_int mac_drv_check_space(void)
#ifdef COMMON_MB_POOL
call_count++ ;
if (call_count == 1) {
- return(EXT_VIRT_MEM) ;
+ return EXT_VIRT_MEM;
}
else {
- return(EXT_VIRT_MEM_2) ;
+ return EXT_VIRT_MEM_2;
}
#else
- return (EXT_VIRT_MEM) ;
+ return EXT_VIRT_MEM;
#endif
#else
- return (0) ;
+ return 0;
#endif
}
@@ -271,7 +271,7 @@ int mac_drv_init(struct s_smc *smc)
if (!(smc->os.hwm.descr_p = (union s_fp_descr volatile *)
mac_drv_get_desc_mem(smc,(u_int)
(RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd)))) {
- return(1) ; /* no space the hwm modul can't work */
+ return 1; /* no space the hwm modul can't work */
}
/*
@@ -283,18 +283,18 @@ int mac_drv_init(struct s_smc *smc)
#ifndef COMMON_MB_POOL
if (!(smc->os.hwm.mbuf_pool.mb_start = (SMbuf *) mac_drv_get_space(smc,
MAX_MBUF*sizeof(SMbuf)))) {
- return(1) ; /* no space the hwm modul can't work */
+ return 1; /* no space the hwm modul can't work */
}
#else
if (!mb_start) {
if (!(mb_start = (SMbuf *) mac_drv_get_space(smc,
MAX_MBUF*sizeof(SMbuf)))) {
- return(1) ; /* no space the hwm modul can't work */
+ return 1; /* no space the hwm modul can't work */
}
}
#endif
#endif
- return (0) ;
+ return 0;
}
/*
@@ -349,7 +349,7 @@ static u_long init_descr_ring(struct s_smc *smc,
DRV_BUF_FLUSH(&d1->r,DDI_DMA_SYNC_FORDEV) ;
d1++;
}
- return(phys) ;
+ return phys;
}
static void init_txd_ring(struct s_smc *smc)
@@ -502,7 +502,7 @@ SMbuf *smt_get_mbuf(struct s_smc *smc)
mb->sm_use_count = 1 ;
}
DB_GEN("get SMbuf: mb = %x",(void *)mb,0,3) ;
- return (mb) ; /* May be NULL */
+ return mb; /* May be NULL */
}
void smt_free_mbuf(struct s_smc *smc, SMbuf *mb)
@@ -621,7 +621,7 @@ static u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue)
t = t->txd_next ;
tx_used-- ;
}
- return(phys) ;
+ return phys;
}
/*
@@ -673,7 +673,7 @@ static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue)
r = r->rxd_next ;
rx_used-- ;
}
- return(phys) ;
+ return phys;
}
@@ -1595,7 +1595,7 @@ int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len,
}
DB_TX("frame_status = %x",frame_status,0,3) ;
NDD_TRACE("THiE",frame_status,smc->os.hwm.tx_p->tx_free,0) ;
- return(frame_status) ;
+ return frame_status;
}
/*
@@ -1764,7 +1764,7 @@ static SMbuf *get_llc_rx(struct s_smc *smc)
smc->os.hwm.llc_rx_pipe = mb->sm_next ;
}
DB_GEN("get_llc_rx: mb = 0x%x",(void *)mb,0,4) ;
- return(mb) ;
+ return mb;
}
/*
@@ -1797,7 +1797,7 @@ static SMbuf *get_txd_mb(struct s_smc *smc)
smc->os.hwm.txd_tx_pipe = mb->sm_next ;
}
DB_GEN("get_txd_mb: mb = 0x%x",(void *)mb,0,4) ;
- return(mb) ;
+ return mb;
}
/*
diff --git a/drivers/net/skfp/hwt.c b/drivers/net/skfp/hwt.c
index 053151468f93..e6baa53307c7 100644
--- a/drivers/net/skfp/hwt.c
+++ b/drivers/net/skfp/hwt.c
@@ -179,7 +179,7 @@ u_long hwt_read(struct s_smc *smc)
else
smc->hw.t_stop = smc->hw.t_start - tr ;
}
- return (smc->hw.t_stop) ;
+ return smc->hw.t_stop;
}
#ifdef PCI
@@ -208,7 +208,7 @@ u_long hwt_quick_read(struct s_smc *smc)
outpw(ADDR(B2_TI_CRTL), TIM_START) ;
outpd(ADDR(B2_TI_INI),interval) ;
- return(time) ;
+ return time;
}
/************************
diff --git a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c
index ba45bc794d77..112d35b1bf0e 100644
--- a/drivers/net/skfp/pcmplc.c
+++ b/drivers/net/skfp/pcmplc.c
@@ -504,7 +504,7 @@ int sm_pm_get_ls(struct s_smc *smc, int phy)
#ifdef CONCENTRATOR
if (!plc_is_installed(smc,phy))
- return(PC_QLS) ;
+ return PC_QLS;
#endif
state = inpw(PLC(phy,PL_STATUS_A)) & PL_LINE_ST ;
@@ -528,7 +528,7 @@ int sm_pm_get_ls(struct s_smc *smc, int phy)
default :
state = PC_LS_NONE ;
}
- return(state) ;
+ return state;
}
static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len)
@@ -547,7 +547,7 @@ static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len)
#if 0
printf("PL_PCM_SIGNAL is set\n") ;
#endif
- return(1) ;
+ return 1;
}
/* write bit[n] & length = 1 to regs */
outpw(PLC(np,PL_VECTOR_LEN),len-1) ; /* len=nr-1 */
@@ -562,7 +562,7 @@ static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len)
printf("SIGNALING bit %d .. %d\n",phy->bitn,phy->bitn+len-1) ;
#endif
#endif
- return(0) ;
+ return 0;
}
/*
@@ -1590,12 +1590,12 @@ int pcm_status_twisted(struct s_smc *smc)
{
int twist = 0 ;
if (smc->s.sas != SMT_DAS)
- return(0) ;
+ return 0;
if (smc->y[PA].twisted && (smc->y[PA].mib->fddiPORTPCMState == PC8_ACTIVE))
twist |= 1 ;
if (smc->y[PB].twisted && (smc->y[PB].mib->fddiPORTPCMState == PC8_ACTIVE))
twist |= 2 ;
- return(twist) ;
+ return twist;
}
/*
@@ -1636,9 +1636,9 @@ int pcm_rooted_station(struct s_smc *smc)
for (n = 0 ; n < NUMPHYS ; n++) {
if (smc->y[n].mib->fddiPORTPCMState == PC8_ACTIVE &&
smc->y[n].mib->fddiPORTNeighborType == TM)
- return(0) ;
+ return 0;
}
- return(1) ;
+ return 1;
}
/*
@@ -1915,7 +1915,7 @@ int get_pcm_state(struct s_smc *smc, int np)
case PL_PC9 : pcs = PC_MAINT ; break ;
default : pcs = PC_DISABLE ; break ;
}
- return(pcs) ;
+ return pcs;
}
char *get_linestate(struct s_smc *smc, int np)
@@ -1937,7 +1937,7 @@ char *get_linestate(struct s_smc *smc, int np)
default: ls = "unknown" ; break ;
#endif
}
- return(ls) ;
+ return ls;
}
char *get_pcmstate(struct s_smc *smc, int np)
@@ -1959,7 +1959,7 @@ char *get_pcmstate(struct s_smc *smc, int np)
case PL_PC9 : pcs = "MAINT" ; break ;
default : pcs = "UNKNOWN" ; break ;
}
- return(pcs) ;
+ return pcs;
}
void list_phy(struct s_smc *smc)
diff --git a/drivers/net/skfp/pmf.c b/drivers/net/skfp/pmf.c
index a320fdb3727d..9ac4665d7411 100644
--- a/drivers/net/skfp/pmf.c
+++ b/drivers/net/skfp/pmf.c
@@ -328,7 +328,7 @@ static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req,
* build SMT header
*/
if (!(mb = smt_get_mbuf(smc)))
- return(mb) ;
+ return mb;
smt = smtod(mb, struct smt_header *) ;
smt->smt_dest = req->smt_source ; /* DA == source of request */
@@ -493,7 +493,7 @@ static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req,
smt_add_para(smc,&set_pcon,(u_short) SMT_P1035,0,0) ;
smt_add_para(smc,&set_pcon,(u_short) SMT_P1036,0,0) ;
}
- return(mb) ;
+ return mb;
}
static int smt_authorize(struct s_smc *smc, struct smt_header *sm)
@@ -511,7 +511,7 @@ static int smt_authorize(struct s_smc *smc, struct smt_header *sm)
if (i != 8) {
if (memcmp((char *) &sm->smt_sid,
(char *) &smc->mib.fddiPRPMFStation,8))
- return(1) ;
+ return 1;
}
/*
* check authoriziation parameter if passwd not zero
@@ -522,13 +522,13 @@ static int smt_authorize(struct s_smc *smc, struct smt_header *sm)
if (i != 8) {
pa = (struct smt_para *) sm_to_para(smc,sm,SMT_P_AUTHOR) ;
if (!pa)
- return(1) ;
+ return 1;
if (pa->p_len != 8)
- return(1) ;
+ return 1;
if (memcmp((char *)(pa+1),(char *)smc->mib.fddiPRPMFPasswd,8))
- return(1) ;
+ return 1;
}
- return(0) ;
+ return 0;
}
static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm)
@@ -542,9 +542,9 @@ static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm)
if ((smc->mib.fddiSMTSetCount.count != sc->count) ||
memcmp((char *) smc->mib.fddiSMTSetCount.timestamp,
(char *)sc->timestamp,8))
- return(1) ;
+ return 1;
}
- return(0) ;
+ return 0;
}
void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
@@ -1109,7 +1109,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
break ;
case 0x2000 :
if (mac < 0 || mac >= NUMMACS) {
- return(SMT_RDF_NOPARAM) ;
+ return SMT_RDF_NOPARAM;
}
mib_m = &smc->mib.m[mac] ;
mib_addr = (char *) mib_m ;
@@ -1118,7 +1118,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
break ;
case 0x3000 :
if (path < 0 || path >= NUMPATHS) {
- return(SMT_RDF_NOPARAM) ;
+ return SMT_RDF_NOPARAM;
}
mib_a = &smc->mib.a[path] ;
mib_addr = (char *) mib_a ;
@@ -1127,7 +1127,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
break ;
case 0x4000 :
if (port < 0 || port >= smt_mib_phys(smc)) {
- return(SMT_RDF_NOPARAM) ;
+ return SMT_RDF_NOPARAM;
}
mib_p = &smc->mib.p[port_to_mib(smc,port)] ;
mib_addr = (char *) mib_p ;
@@ -1151,22 +1151,20 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
case SMT_P10F9 :
#endif
case SMT_P20F1 :
- if (!local) {
- return(SMT_RDF_NOPARAM) ;
- }
+ if (!local)
+ return SMT_RDF_NOPARAM;
break ;
}
pt = smt_get_ptab(pa->p_type) ;
- if (!pt) {
- return( (pa->p_type & 0xff00) ? SMT_RDF_NOPARAM :
- SMT_RDF_ILLEGAL ) ;
- }
+ if (!pt)
+ return (pa->p_type & 0xff00) ? SMT_RDF_NOPARAM :
+ SMT_RDF_ILLEGAL;
switch (pt->p_access) {
case AC_GR :
case AC_S :
break ;
default :
- return(SMT_RDF_ILLEGAL) ;
+ return SMT_RDF_ILLEGAL;
}
to = mib_addr + pt->p_offset ;
swap = pt->p_swap ; /* pointer to swap string */
@@ -1292,7 +1290,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
break ;
default :
SMT_PANIC(smc,SMT_E0120, SMT_E0120_MSG) ;
- return(SMT_RDF_ILLEGAL) ;
+ return SMT_RDF_ILLEGAL;
}
}
/*
@@ -1501,15 +1499,15 @@ change_mac_para:
default :
break ;
}
- return(0) ;
+ return 0;
val_error:
/* parameter value in frame is out of range */
- return(SMT_RDF_RANGE) ;
+ return SMT_RDF_RANGE;
len_error:
/* parameter value in frame is too short */
- return(SMT_RDF_LENGTH) ;
+ return SMT_RDF_LENGTH;
#if 0
no_author_error:
@@ -1518,7 +1516,7 @@ no_author_error:
* because SBA denied is not a valid return code in the
* PMF protocol.
*/
- return(SMT_RDF_AUTHOR) ;
+ return SMT_RDF_AUTHOR;
#endif
}
@@ -1527,7 +1525,7 @@ static const struct s_p_tab *smt_get_ptab(u_short para)
const struct s_p_tab *pt ;
for (pt = p_tab ; pt->p_num && pt->p_num != para ; pt++)
;
- return(pt->p_num ? pt : NULL) ;
+ return pt->p_num ? pt : NULL;
}
static int smt_mib_phys(struct s_smc *smc)
@@ -1535,11 +1533,11 @@ static int smt_mib_phys(struct s_smc *smc)
#ifdef CONCENTRATOR
SK_UNUSED(smc) ;
- return(NUMPHYS) ;
+ return NUMPHYS;
#else
if (smc->s.sas == SMT_SAS)
- return(1) ;
- return(NUMPHYS) ;
+ return 1;
+ return NUMPHYS;
#endif
}
@@ -1548,11 +1546,11 @@ static int port_to_mib(struct s_smc *smc, int p)
#ifdef CONCENTRATOR
SK_UNUSED(smc) ;
- return(p) ;
+ return p;
#else
if (smc->s.sas == SMT_SAS)
- return(PS) ;
- return(p) ;
+ return PS;
+ return p;
#endif
}
diff --git a/drivers/net/skfp/queue.c b/drivers/net/skfp/queue.c
index 09adb3d68b7c..c1a0df455a59 100644
--- a/drivers/net/skfp/queue.c
+++ b/drivers/net/skfp/queue.c
@@ -128,7 +128,7 @@ u_short smt_online(struct s_smc *smc, int on)
{
queue_event(smc,EVENT_ECM,on ? EC_CONNECT : EC_DISCONNECT) ;
ev_dispatcher(smc) ;
- return(smc->mib.fddiSMTCF_State) ;
+ return smc->mib.fddiSMTCF_State;
}
/*
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 31b2dabf094c..ba2e8339fe90 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -209,7 +209,7 @@ static int skfp_init_one(struct pci_dev *pdev,
void __iomem *mem;
int err;
- pr_debug(KERN_INFO "entering skfp_init_one\n");
+ pr_debug("entering skfp_init_one\n");
if (num_boards == 0)
printk("%s\n", boot_msg);
@@ -385,7 +385,7 @@ static int skfp_driver_init(struct net_device *dev)
skfddi_priv *bp = &smc->os;
int err = -EIO;
- pr_debug(KERN_INFO "entering skfp_driver_init\n");
+ pr_debug("entering skfp_driver_init\n");
// set the io address in private structures
bp->base_addr = dev->base_addr;
@@ -405,7 +405,7 @@ static int skfp_driver_init(struct net_device *dev)
// Determine the required size of the 'shared' memory area.
bp->SharedMemSize = mac_drv_check_space();
- pr_debug(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize);
+ pr_debug("Memory for HWM: %ld\n", bp->SharedMemSize);
if (bp->SharedMemSize > 0) {
bp->SharedMemSize += 16; // for descriptor alignment
@@ -429,18 +429,18 @@ static int skfp_driver_init(struct net_device *dev)
card_stop(smc); // Reset adapter.
- pr_debug(KERN_INFO "mac_drv_init()..\n");
+ pr_debug("mac_drv_init()..\n");
if (mac_drv_init(smc) != 0) {
- pr_debug(KERN_INFO "mac_drv_init() failed.\n");
+ pr_debug("mac_drv_init() failed\n");
goto fail;
}
read_address(smc, NULL);
- pr_debug(KERN_INFO "HW-Addr: %pMF\n", smc->hw.fddi_canon_addr.a);
+ pr_debug("HW-Addr: %pMF\n", smc->hw.fddi_canon_addr.a);
memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6);
smt_reset_defaults(smc, 0);
- return (0);
+ return 0;
fail:
if (bp->SharedMemAddr) {
@@ -485,7 +485,7 @@ static int skfp_open(struct net_device *dev)
struct s_smc *smc = netdev_priv(dev);
int err;
- pr_debug(KERN_INFO "entering skfp_open\n");
+ pr_debug("entering skfp_open\n");
/* Register IRQ - support shared interrupts by passing device ptr */
err = request_irq(dev->irq, skfp_interrupt, IRQF_SHARED,
dev->name, dev);
@@ -516,7 +516,7 @@ static int skfp_open(struct net_device *dev)
mac_drv_rx_mode(smc, RX_DISABLE_PROMISC);
netif_start_queue(dev);
- return (0);
+ return 0;
} // skfp_open
@@ -565,7 +565,7 @@ static int skfp_close(struct net_device *dev)
skb_queue_purge(&bp->SendSkbQueue);
bp->QueueSkb = MAX_TX_QUEUE_LEN;
- return (0);
+ return 0;
} // skfp_close
@@ -794,7 +794,7 @@ static struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev)
bp->stats.port_lem_cts[1] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[1].ls;
#endif
- return ((struct net_device_stats *) &bp->os.MacStat);
+ return (struct net_device_stats *)&bp->os.MacStat;
} // ctl_get_stat
@@ -856,12 +856,12 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
/* Enable promiscuous mode, if necessary */
if (dev->flags & IFF_PROMISC) {
mac_drv_rx_mode(smc, RX_ENABLE_PROMISC);
- pr_debug(KERN_INFO "PROMISCUOUS MODE ENABLED\n");
+ pr_debug("PROMISCUOUS MODE ENABLED\n");
}
/* Else, update multicast address table */
else {
mac_drv_rx_mode(smc, RX_DISABLE_PROMISC);
- pr_debug(KERN_INFO "PROMISCUOUS MODE DISABLED\n");
+ pr_debug("PROMISCUOUS MODE DISABLED\n");
// Reset all MC addresses
mac_clear_multicast(smc);
@@ -869,7 +869,7 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
if (dev->flags & IFF_ALLMULTI) {
mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
- pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
+ pr_debug("ENABLE ALL MC ADDRESSES\n");
} else if (!netdev_mc_empty(dev)) {
if (netdev_mc_count(dev) <= FPMAX_MULTICAST) {
/* use exact filtering */
@@ -880,18 +880,18 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
(struct fddi_addr *)ha->addr,
1);
- pr_debug(KERN_INFO "ENABLE MC ADDRESS: %pMF\n",
- ha->addr);
+ pr_debug("ENABLE MC ADDRESS: %pMF\n",
+ ha->addr);
}
} else { // more MC addresses than HW supports
mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
- pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
+ pr_debug("ENABLE ALL MC ADDRESSES\n");
}
} else { // no MC addresses
- pr_debug(KERN_INFO "DISABLE ALL MC ADDRESSES\n");
+ pr_debug("DISABLE ALL MC ADDRESSES\n");
}
/* Update adapter filters */
@@ -932,7 +932,7 @@ static int skfp_ctl_set_mac_address(struct net_device *dev, void *addr)
ResetAdapter(smc);
spin_unlock_irqrestore(&bp->DriverLock, Flags);
- return (0); /* always return zero */
+ return 0; /* always return zero */
} // skfp_ctl_set_mac_address
@@ -1045,7 +1045,7 @@ static netdev_tx_t skfp_send_pkt(struct sk_buff *skb,
struct s_smc *smc = netdev_priv(dev);
skfddi_priv *bp = &smc->os;
- pr_debug(KERN_INFO "skfp_send_pkt\n");
+ pr_debug("skfp_send_pkt\n");
/*
* Verify that incoming transmit request is OK
@@ -1114,13 +1114,13 @@ static void send_queued_packets(struct s_smc *smc)
int frame_status; // HWM tx frame status.
- pr_debug(KERN_INFO "send queued packets\n");
+ pr_debug("send queued packets\n");
for (;;) {
// send first buffer from queue
skb = skb_dequeue(&bp->SendSkbQueue);
if (!skb) {
- pr_debug(KERN_INFO "queue empty\n");
+ pr_debug("queue empty\n");
return;
} // queue empty !
@@ -1232,7 +1232,7 @@ static void CheckSourceAddress(unsigned char *frame, unsigned char *hw_addr)
static void ResetAdapter(struct s_smc *smc)
{
- pr_debug(KERN_INFO "[fddi: ResetAdapter]\n");
+ pr_debug("[fddi: ResetAdapter]\n");
// Stop the adapter.
@@ -1278,7 +1278,7 @@ void llc_restart_tx(struct s_smc *smc)
{
skfddi_priv *bp = &smc->os;
- pr_debug(KERN_INFO "[llc_restart_tx]\n");
+ pr_debug("[llc_restart_tx]\n");
// Try to send queued packets
spin_unlock(&bp->DriverLock);
@@ -1308,21 +1308,21 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size)
{
void *virt;
- pr_debug(KERN_INFO "mac_drv_get_space (%d bytes), ", size);
+ pr_debug("mac_drv_get_space (%d bytes), ", size);
virt = (void *) (smc->os.SharedMemAddr + smc->os.SharedMemHeap);
if ((smc->os.SharedMemHeap + size) > smc->os.SharedMemSize) {
printk("Unexpected SMT memory size requested: %d\n", size);
- return (NULL);
+ return NULL;
}
smc->os.SharedMemHeap += size; // Move heap pointer.
- pr_debug(KERN_INFO "mac_drv_get_space end\n");
- pr_debug(KERN_INFO "virt addr: %lx\n", (ulong) virt);
- pr_debug(KERN_INFO "bus addr: %lx\n", (ulong)
+ pr_debug("mac_drv_get_space end\n");
+ pr_debug("virt addr: %lx\n", (ulong) virt);
+ pr_debug("bus addr: %lx\n", (ulong)
(smc->os.SharedMemDMA +
((char *) virt - (char *)smc->os.SharedMemAddr)));
- return (virt);
+ return virt;
} // mac_drv_get_space
@@ -1349,7 +1349,7 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
char *virt;
- pr_debug(KERN_INFO "mac_drv_get_desc_mem\n");
+ pr_debug("mac_drv_get_desc_mem\n");
// Descriptor memory must be aligned on 16-byte boundary.
@@ -1363,9 +1363,9 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
if (!mac_drv_get_space(smc, size)) {
printk("fddi: Unable to align descriptor memory.\n");
- return (NULL);
+ return NULL;
}
- return (virt + size);
+ return virt + size;
} // mac_drv_get_desc_mem
@@ -1384,8 +1384,8 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
************************/
unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt)
{
- return (smc->os.SharedMemDMA +
- ((char *) virt - (char *)smc->os.SharedMemAddr));
+ return smc->os.SharedMemDMA +
+ ((char *) virt - (char *)smc->os.SharedMemAddr);
} // mac_drv_virt2phys
@@ -1419,8 +1419,8 @@ unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt)
************************/
u_long dma_master(struct s_smc * smc, void *virt, int len, int flag)
{
- return (smc->os.SharedMemDMA +
- ((char *) virt - (char *)smc->os.SharedMemAddr));
+ return smc->os.SharedMemDMA +
+ ((char *) virt - (char *)smc->os.SharedMemAddr);
} // dma_master
@@ -1493,7 +1493,7 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
{
struct sk_buff *skb;
- pr_debug(KERN_INFO "entering mac_drv_tx_complete\n");
+ pr_debug("entering mac_drv_tx_complete\n");
// Check if this TxD points to a skb
if (!(skb = txd->txd_os.skb)) {
@@ -1513,7 +1513,7 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
// free the skb
dev_kfree_skb_irq(skb);
- pr_debug(KERN_INFO "leaving mac_drv_tx_complete\n");
+ pr_debug("leaving mac_drv_tx_complete\n");
} // mac_drv_tx_complete
@@ -1580,7 +1580,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
unsigned short ri;
u_int RifLength;
- pr_debug(KERN_INFO "entering mac_drv_rx_complete (len=%d)\n", len);
+ pr_debug("entering mac_drv_rx_complete (len=%d)\n", len);
if (frag_count != 1) { // This is not allowed to happen.
printk("fddi: Multi-fragment receive!\n");
@@ -1589,7 +1589,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
}
skb = rxd->rxd_os.skb;
if (!skb) {
- pr_debug(KERN_INFO "No skb in rxd\n");
+ pr_debug("No skb in rxd\n");
smc->os.MacStat.gen.rx_errors++;
goto RequeueRxd;
}
@@ -1619,7 +1619,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
else {
int n;
// goos: RIF removal has still to be tested
- pr_debug(KERN_INFO "RIF found\n");
+ pr_debug("RIF found\n");
// Get RIF length from Routing Control (RC) field.
cp = virt + FDDI_MAC_HDR_LEN; // Point behind MAC header.
@@ -1664,7 +1664,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
return;
RequeueRxd:
- pr_debug(KERN_INFO "Rx: re-queue RXD.\n");
+ pr_debug("Rx: re-queue RXD.\n");
mac_drv_requeue_rxd(smc, rxd, frag_count);
smc->os.MacStat.gen.rx_errors++; // Count receive packets
// not indicated.
@@ -1775,7 +1775,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
struct sk_buff *skb;
volatile struct s_smt_fp_rxd *rxd;
- pr_debug(KERN_INFO "entering mac_drv_fill_rxd\n");
+ pr_debug("entering mac_drv_fill_rxd\n");
// Walk through the list of free receive buffers, passing receive
// buffers to the HWM as long as RXDs are available.
@@ -1783,7 +1783,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
MaxFrameSize = smc->os.MaxFrameSize;
// Check if there is any RXD left.
while (HWM_GET_RX_FREE(smc) > 0) {
- pr_debug(KERN_INFO ".\n");
+ pr_debug(".\n");
rxd = HWM_GET_CURR_RXD(smc);
skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC);
@@ -1814,7 +1814,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
hwm_rx_frag(smc, v_addr, b_addr, MaxFrameSize,
FIRST_FRAG | LAST_FRAG);
}
- pr_debug(KERN_INFO "leaving mac_drv_fill_rxd\n");
+ pr_debug("leaving mac_drv_fill_rxd\n");
} // mac_drv_fill_rxd
@@ -1904,12 +1904,12 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc,
pr_debug("fddi: Discard invalid local SMT frame\n");
pr_debug(" len=%d, la_len=%d, (ULONG) look_ahead=%08lXh.\n",
len, la_len, (unsigned long) look_ahead);
- return (0);
+ return 0;
}
skb = alloc_skb(len + 3, GFP_ATOMIC);
if (!skb) {
pr_debug("fddi: Local SMT: skb memory exhausted.\n");
- return (0);
+ return 0;
}
skb_reserve(skb, 3);
skb_put(skb, len);
@@ -1919,7 +1919,7 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc,
skb->protocol = fddi_type_trans(skb, smc->os.dev);
netif_rx(skb);
- return (0);
+ return 0;
} // mac_drv_rx_init
@@ -2034,17 +2034,17 @@ void smt_stat_counter(struct s_smc *smc, int stat)
{
// BOOLEAN RingIsUp ;
- pr_debug(KERN_INFO "smt_stat_counter\n");
+ pr_debug("smt_stat_counter\n");
switch (stat) {
case 0:
- pr_debug(KERN_INFO "Ring operational change.\n");
+ pr_debug("Ring operational change.\n");
break;
case 1:
- pr_debug(KERN_INFO "Receive fifo overflow.\n");
+ pr_debug("Receive fifo overflow.\n");
smc->os.MacStat.gen.rx_errors++;
break;
default:
- pr_debug(KERN_INFO "Unknown status (%d).\n", stat);
+ pr_debug("Unknown status (%d).\n", stat);
break;
}
} // smt_stat_counter
@@ -2100,10 +2100,10 @@ void cfm_state_change(struct s_smc *smc, int c_state)
s = "SC11_C_WRAP_S";
break;
default:
- pr_debug(KERN_INFO "cfm_state_change: unknown %d\n", c_state);
+ pr_debug("cfm_state_change: unknown %d\n", c_state);
return;
}
- pr_debug(KERN_INFO "cfm_state_change: %s\n", s);
+ pr_debug("cfm_state_change: %s\n", s);
#endif // DRIVERDEBUG
} // cfm_state_change
@@ -2158,7 +2158,7 @@ void ecm_state_change(struct s_smc *smc, int e_state)
s = "unknown";
break;
}
- pr_debug(KERN_INFO "ecm_state_change: %s\n", s);
+ pr_debug("ecm_state_change: %s\n", s);
#endif //DRIVERDEBUG
} // ecm_state_change
@@ -2213,7 +2213,7 @@ void rmt_state_change(struct s_smc *smc, int r_state)
s = "unknown";
break;
}
- pr_debug(KERN_INFO "[rmt_state_change: %s]\n", s);
+ pr_debug("[rmt_state_change: %s]\n", s);
#endif // DRIVERDEBUG
} // rmt_state_change
@@ -2233,7 +2233,7 @@ void rmt_state_change(struct s_smc *smc, int r_state)
************************/
void drv_reset_indication(struct s_smc *smc)
{
- pr_debug(KERN_INFO "entering drv_reset_indication\n");
+ pr_debug("entering drv_reset_indication\n");
smc->os.ResetRequested = TRUE; // Set flag.
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
index 6f35bb77595f..2d9941c045bc 100644
--- a/drivers/net/skfp/smt.c
+++ b/drivers/net/skfp/smt.c
@@ -127,22 +127,22 @@ static inline int is_my_addr(const struct s_smc *smc,
static inline int is_broadcast(const struct fddi_addr *addr)
{
- return(*(u_short *)(&addr->a[0]) == 0xffff &&
+ return *(u_short *)(&addr->a[0]) == 0xffff &&
*(u_short *)(&addr->a[2]) == 0xffff &&
- *(u_short *)(&addr->a[4]) == 0xffff ) ;
+ *(u_short *)(&addr->a[4]) == 0xffff;
}
static inline int is_individual(const struct fddi_addr *addr)
{
- return(!(addr->a[0] & GROUP_ADDR)) ;
+ return !(addr->a[0] & GROUP_ADDR);
}
static inline int is_equal(const struct fddi_addr *addr1,
const struct fddi_addr *addr2)
{
- return(*(u_short *)(&addr1->a[0]) == *(u_short *)(&addr2->a[0]) &&
+ return *(u_short *)(&addr1->a[0]) == *(u_short *)(&addr2->a[0]) &&
*(u_short *)(&addr1->a[2]) == *(u_short *)(&addr2->a[2]) &&
- *(u_short *)(&addr1->a[4]) == *(u_short *)(&addr2->a[4]) ) ;
+ *(u_short *)(&addr1->a[4]) == *(u_short *)(&addr2->a[4]);
}
/*
@@ -457,8 +457,8 @@ static int div_ratio(u_long upper, u_long lower)
else
upper <<= 16L ;
if (!lower)
- return(0) ;
- return((int)(upper/lower)) ;
+ return 0;
+ return (int)(upper/lower) ;
}
#ifndef SLIM_SMT
@@ -1111,11 +1111,11 @@ SMbuf *smt_build_frame(struct s_smc *smc, int class, int type,
#if 0
if (!smc->r.sm_ma_avail) {
- return(0) ;
+ return 0;
}
#endif
if (!(mb = smt_get_mbuf(smc)))
- return(mb) ;
+ return mb;
mb->sm_len = length ;
smt = smtod(mb, struct smt_header *) ;
@@ -1136,7 +1136,7 @@ SMbuf *smt_build_frame(struct s_smc *smc, int class, int type,
smt->smt_tid = smt_get_tid(smc) ; /* set transaction ID */
smt->smt_pad = 0 ;
smt->smt_len = length - sizeof(struct smt_header) ;
- return(mb) ;
+ return mb;
}
static void smt_add_frame_len(SMbuf *mb, int len)
@@ -1375,7 +1375,7 @@ static int smt_fill_path(struct s_smc *smc, struct smt_p_path *path)
pd_mac = (struct smt_mac_rec *) phy ;
pd_mac->mac_addr = smc->mib.m[MAC0].fddiMACSMTAddress ;
pd_mac->mac_resource_idx = mac_con_resource_index(smc,1) ;
- return(len) ;
+ return len;
}
/*
@@ -1563,7 +1563,7 @@ u_long smt_get_tid(struct s_smc *smc)
u_long tid ;
while ((tid = ++(smc->sm.smt_tid) ^ SMT_TID_MAGIC) == 0)
;
- return(tid & 0x3fffffffL) ;
+ return tid & 0x3fffffffL;
}
@@ -1654,11 +1654,11 @@ int smt_check_para(struct s_smc *smc, struct smt_header *sm,
while (*p) {
if (!sm_to_para(smc,sm,(int) *p)) {
DB_SMT("SMT: smt_check_para - missing para %x\n",*p,0);
- return(-1) ;
+ return -1;
}
p++ ;
}
- return(0) ;
+ return 0;
}
void *sm_to_para(struct s_smc *smc, struct smt_header *sm, int para)
@@ -1687,7 +1687,7 @@ void *sm_to_para(struct s_smc *smc, struct smt_header *sm, int para)
return NULL;
}
if (found)
- return(found) ;
+ return found;
}
return NULL;
}
@@ -1732,7 +1732,7 @@ char *addr_to_string(struct fddi_addr *addr)
string[i * 3 + 2] = ':';
}
string[5 * 3 + 2] = 0;
- return(string);
+ return string;
}
#endif
@@ -1742,9 +1742,9 @@ int smt_ifconfig(int argc, char *argv[])
if (argc >= 2 && !strcmp(argv[0],"opt_bypass") &&
!strcmp(argv[1],"yes")) {
smc->mib.fddiSMTBypassPresent = 1 ;
- return(0) ;
+ return 0;
}
- return(amdfddi_config(0,argc,argv)) ;
+ return amdfddi_config(0, argc, argv);
}
#endif
@@ -1756,9 +1756,9 @@ static int mac_index(struct s_smc *smc, int mac)
SK_UNUSED(mac) ;
#ifdef CONCENTRATOR
SK_UNUSED(smc) ;
- return(NUMPHYS+1) ;
+ return NUMPHYS + 1;
#else
- return((smc->s.sas == SMT_SAS) ? 2 : 3) ;
+ return (smc->s.sas == SMT_SAS) ? 2 : 3;
#endif
}
@@ -1768,7 +1768,7 @@ static int mac_index(struct s_smc *smc, int mac)
static int phy_index(struct s_smc *smc, int phy)
{
SK_UNUSED(smc) ;
- return(phy+1);
+ return phy + 1;
}
/*
@@ -1779,19 +1779,19 @@ static int mac_con_resource_index(struct s_smc *smc, int mac)
#ifdef CONCENTRATOR
SK_UNUSED(smc) ;
SK_UNUSED(mac) ;
- return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_MAC))) ;
+ return entity_to_index(smc, cem_get_downstream(smc, ENTITY_MAC));
#else
SK_UNUSED(mac) ;
switch (smc->mib.fddiSMTCF_State) {
case SC9_C_WRAP_A :
case SC5_THRU_B :
case SC11_C_WRAP_S :
- return(1) ;
+ return 1;
case SC10_C_WRAP_B :
case SC4_THRU_A :
- return(2) ;
+ return 2;
}
- return(smc->s.sas == SMT_SAS ? 2 : 3) ;
+ return smc->s.sas == SMT_SAS ? 2 : 3;
#endif
}
@@ -1801,21 +1801,21 @@ static int mac_con_resource_index(struct s_smc *smc, int mac)
static int phy_con_resource_index(struct s_smc *smc, int phy)
{
#ifdef CONCENTRATOR
- return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_PHY(phy)))) ;
+ return entity_to_index(smc, cem_get_downstream(smc, ENTITY_PHY(phy))) ;
#else
switch (smc->mib.fddiSMTCF_State) {
case SC9_C_WRAP_A :
- return(phy == PA ? 3 : 2) ;
+ return phy == PA ? 3 : 2;
case SC10_C_WRAP_B :
- return(phy == PA ? 1 : 3) ;
+ return phy == PA ? 1 : 3;
case SC4_THRU_A :
- return(phy == PA ? 3 : 1) ;
+ return phy == PA ? 3 : 1;
case SC5_THRU_B :
- return(phy == PA ? 2 : 3) ;
+ return phy == PA ? 2 : 3;
case SC11_C_WRAP_S :
- return(2) ;
+ return 2;
}
- return(phy) ;
+ return phy;
#endif
}
@@ -1823,16 +1823,16 @@ static int phy_con_resource_index(struct s_smc *smc, int phy)
static int entity_to_index(struct s_smc *smc, int e)
{
if (e == ENTITY_MAC)
- return(mac_index(smc,1)) ;
+ return mac_index(smc, 1);
else
- return(phy_index(smc,e - ENTITY_PHY(0))) ;
+ return phy_index(smc, e - ENTITY_PHY(0));
}
#endif
#ifdef LITTLE_ENDIAN
static int smt_swap_short(u_short s)
{
- return(((s>>8)&0xff)|((s&0xff)<<8)) ;
+ return ((s>>8)&0xff) | ((s&0xff)<<8);
}
void smt_swap_para(struct smt_header *sm, int len, int direction)
@@ -1996,7 +1996,7 @@ int smt_action(struct s_smc *smc, int class, int code, int index)
}
break ;
default :
- return(1) ;
+ return 1;
}
break ;
case SMT_PORT_ACTION :
@@ -2017,14 +2017,14 @@ int smt_action(struct s_smc *smc, int class, int code, int index)
event = PC_STOP ;
break ;
default :
- return(1) ;
+ return 1;
}
queue_event(smc,EVENT_PCM+index,event) ;
break ;
default :
- return(1) ;
+ return 1;
}
- return(0) ;
+ return 0;
}
/*
diff --git a/drivers/net/skfp/smtdef.c b/drivers/net/skfp/smtdef.c
index 4e07ff7073f1..1acab0b368e3 100644
--- a/drivers/net/skfp/smtdef.c
+++ b/drivers/net/skfp/smtdef.c
@@ -303,7 +303,7 @@ int smt_set_mac_opvalues(struct s_smc *smc)
FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_T_REQ,
smt_get_event_word(smc));
}
- return(st) ;
+ return st;
}
void smt_fixup_mib(struct s_smc *smc)
@@ -350,6 +350,6 @@ static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper)
*oper = limit ;
else
*oper = mib ;
- return(old != *oper) ;
+ return old != *oper;
}
diff --git a/drivers/net/skfp/smtinit.c b/drivers/net/skfp/smtinit.c
index 3c8964ce1837..e3a0c0bc2233 100644
--- a/drivers/net/skfp/smtinit.c
+++ b/drivers/net/skfp/smtinit.c
@@ -120,6 +120,6 @@ int init_smt(struct s_smc *smc, u_char *mac_addr)
PNMI_INIT(smc) ; /* PNMI initialization */
- return(0) ;
+ return 0;
}
diff --git a/drivers/net/skfp/srf.c b/drivers/net/skfp/srf.c
index 40882b3faba6..f6f7baf9f27a 100644
--- a/drivers/net/skfp/srf.c
+++ b/drivers/net/skfp/srf.c
@@ -165,7 +165,7 @@ static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index)
for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) {
if (evc->evc_code == code && evc->evc_index == index)
- return(evc) ;
+ return evc;
}
return NULL;
}
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 465ae7e84507..bfec2e0f5275 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3179,8 +3179,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
skb = skge_rx_get(dev, e, control, rd->status, rd->csum2);
if (likely(skb)) {
- netif_receive_skb(skb);
-
+ napi_gro_receive(napi, skb);
++work_done;
}
}
@@ -3193,6 +3192,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
if (work_done < to_do) {
unsigned long flags;
+ napi_gro_flush(napi);
spin_lock_irqsave(&hw->hw_lock, flags);
__napi_complete(napi);
hw->intr_mask |= napimask[skge->port];
@@ -3850,6 +3850,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
skge->rx_csum = 1;
}
+ 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/sky2.c b/drivers/net/sky2.c
index 194e5cf8c763..d6577084ce70 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1782,7 +1782,7 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb,
ctrl = 0;
#ifdef SKY2_VLAN_TAG_USED
/* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
- if (sky2->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
if (!le) {
le = get_tx_le(sky2, &slot);
le->addr = 0;
@@ -4581,7 +4581,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
sky2->port = port;
- dev->features |= NETIF_F_TSO | NETIF_F_IP_CSUM | NETIF_F_SG;
+ dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG
+ | NETIF_F_TSO | NETIF_F_GRO;
if (highmem)
dev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index fa434fb8fb7c..86cbb9ea2f26 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -271,7 +271,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu)
memcpy(sl->xbuff, sl->xhead, sl->xleft);
} else {
sl->xleft = 0;
- sl->tx_dropped++;
+ dev->stats.tx_dropped++;
}
}
sl->xhead = sl->xbuff;
@@ -281,7 +281,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu)
memcpy(sl->rbuff, rbuff, sl->rcount);
} else {
sl->rcount = 0;
- sl->rx_over_errors++;
+ dev->stats.rx_over_errors++;
set_bit(SLF_ERROR, &sl->flags);
}
}
@@ -319,6 +319,7 @@ static inline void sl_unlock(struct slip *sl)
/* Send one completely decapsulated IP datagram to the IP layer. */
static void sl_bump(struct slip *sl)
{
+ struct net_device *dev = sl->dev;
struct sk_buff *skb;
int count;
@@ -329,13 +330,13 @@ static void sl_bump(struct slip *sl)
if (c & SL_TYPE_COMPRESSED_TCP) {
/* ignore compressed packets when CSLIP is off */
if (!(sl->mode & SL_MODE_CSLIP)) {
- printk(KERN_WARNING "%s: compressed packet ignored\n", sl->dev->name);
+ printk(KERN_WARNING "%s: compressed packet ignored\n", dev->name);
return;
}
/* make sure we've reserved enough space for uncompress
to use */
if (count + 80 > sl->buffsize) {
- sl->rx_over_errors++;
+ dev->stats.rx_over_errors++;
return;
}
count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
@@ -346,7 +347,7 @@ static void sl_bump(struct slip *sl)
/* turn on header compression */
sl->mode |= SL_MODE_CSLIP;
sl->mode &= ~SL_MODE_ADAPTIVE;
- printk(KERN_INFO "%s: header compression turned on\n", sl->dev->name);
+ printk(KERN_INFO "%s: header compression turned on\n", dev->name);
}
sl->rbuff[0] &= 0x4f;
if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0)
@@ -355,20 +356,20 @@ static void sl_bump(struct slip *sl)
}
#endif /* SL_INCLUDE_CSLIP */
- sl->rx_bytes += count;
+ dev->stats.rx_bytes += count;
skb = dev_alloc_skb(count);
if (skb == NULL) {
- printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name);
- sl->rx_dropped++;
+ printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name);
+ dev->stats.rx_dropped++;
return;
}
- skb->dev = sl->dev;
+ skb->dev = dev;
memcpy(skb_put(skb, count), sl->rbuff, count);
skb_reset_mac_header(skb);
skb->protocol = htons(ETH_P_IP);
netif_rx(skb);
- sl->rx_packets++;
+ dev->stats.rx_packets++;
}
/* Encapsulate one IP datagram and stuff into a TTY queue. */
@@ -379,7 +380,7 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len)
if (len > sl->mtu) { /* Sigh, shouldn't occur BUT ... */
printk(KERN_WARNING "%s: truncating oversized transmit packet!\n", sl->dev->name);
- sl->tx_dropped++;
+ sl->dev->stats.tx_dropped++;
sl_unlock(sl);
return;
}
@@ -433,7 +434,7 @@ static void slip_write_wakeup(struct tty_struct *tty)
if (sl->xleft <= 0) {
/* Now serial buffer is almost free & we can start
* transmission of another packet */
- sl->tx_packets++;
+ sl->dev->stats.tx_packets++;
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
sl_unlock(sl);
return;
@@ -496,7 +497,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev)
}
sl_lock(sl);
- sl->tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
sl_encaps(sl, skb->data, skb->len);
spin_unlock(&sl->lock);
@@ -558,39 +559,39 @@ static int sl_change_mtu(struct net_device *dev, int new_mtu)
/* Netdevice get statistics request */
-static struct net_device_stats *
-sl_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *
+sl_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
- static struct net_device_stats stats;
- struct slip *sl = netdev_priv(dev);
+ struct net_device_stats *devstats = &dev->stats;
+ unsigned long c_rx_dropped = 0;
#ifdef SL_INCLUDE_CSLIP
- struct slcompress *comp;
-#endif
+ unsigned long c_rx_fifo_errors = 0;
+ unsigned long c_tx_fifo_errors = 0;
+ unsigned long c_collisions = 0;
+ struct slip *sl = netdev_priv(dev);
+ struct slcompress *comp = sl->slcomp;
- memset(&stats, 0, sizeof(struct net_device_stats));
-
- stats.rx_packets = sl->rx_packets;
- stats.tx_packets = sl->tx_packets;
- stats.rx_bytes = sl->rx_bytes;
- stats.tx_bytes = sl->tx_bytes;
- stats.rx_dropped = sl->rx_dropped;
- stats.tx_dropped = sl->tx_dropped;
- stats.tx_errors = sl->tx_errors;
- stats.rx_errors = sl->rx_errors;
- stats.rx_over_errors = sl->rx_over_errors;
-#ifdef SL_INCLUDE_CSLIP
- stats.rx_fifo_errors = sl->rx_compressed;
- stats.tx_fifo_errors = sl->tx_compressed;
- stats.collisions = sl->tx_misses;
- comp = sl->slcomp;
if (comp) {
- stats.rx_fifo_errors += comp->sls_i_compressed;
- stats.rx_dropped += comp->sls_i_tossed;
- stats.tx_fifo_errors += comp->sls_o_compressed;
- stats.collisions += comp->sls_o_misses;
+ c_rx_fifo_errors = comp->sls_i_compressed;
+ c_rx_dropped = comp->sls_i_tossed;
+ c_tx_fifo_errors = comp->sls_o_compressed;
+ c_collisions = comp->sls_o_misses;
}
-#endif /* CONFIG_INET */
- return (&stats);
+ stats->rx_fifo_errors = sl->rx_compressed + c_rx_fifo_errors;
+ stats->tx_fifo_errors = sl->tx_compressed + c_tx_fifo_errors;
+ stats->collisions = sl->tx_misses + c_collisions;
+#endif
+ stats->rx_packets = devstats->rx_packets;
+ stats->tx_packets = devstats->tx_packets;
+ stats->rx_bytes = devstats->rx_bytes;
+ stats->tx_bytes = devstats->tx_bytes;
+ stats->rx_dropped = devstats->rx_dropped + c_rx_dropped;
+ stats->tx_dropped = devstats->tx_dropped;
+ stats->tx_errors = devstats->tx_errors;
+ stats->rx_errors = devstats->rx_errors;
+ stats->rx_over_errors = devstats->rx_over_errors;
+
+ return stats;
}
/* Netdevice register callback */
@@ -633,7 +634,7 @@ static const struct net_device_ops sl_netdev_ops = {
.ndo_open = sl_open,
.ndo_stop = sl_close,
.ndo_start_xmit = sl_xmit,
- .ndo_get_stats = sl_get_stats,
+ .ndo_get_stats64 = sl_get_stats64,
.ndo_change_mtu = sl_change_mtu,
.ndo_tx_timeout = sl_tx_timeout,
#ifdef CONFIG_SLIP_SMART
@@ -681,7 +682,7 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
while (count--) {
if (fp && *fp++) {
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
- sl->rx_errors++;
+ sl->dev->stats.rx_errors++;
cp++;
continue;
}
@@ -943,7 +944,7 @@ static int slip_esc(unsigned char *s, unsigned char *d, int len)
}
}
*ptr++ = END;
- return (ptr - d);
+ return ptr - d;
}
static void slip_unesc(struct slip *sl, unsigned char s)
@@ -981,7 +982,7 @@ static void slip_unesc(struct slip *sl, unsigned char s)
sl->rbuff[sl->rcount++] = s;
return;
}
- sl->rx_over_errors++;
+ sl->dev->stats.rx_over_errors++;
set_bit(SLF_ERROR, &sl->flags);
}
}
@@ -1057,7 +1058,7 @@ static void slip_unesc6(struct slip *sl, unsigned char s)
sl->rbuff[sl->rcount++] = c;
return;
}
- sl->rx_over_errors++;
+ sl->dev->stats.rx_over_errors++;
set_bit(SLF_ERROR, &sl->flags);
}
}
diff --git a/drivers/net/slip.h b/drivers/net/slip.h
index 9ea5c11287d2..914e958abbfc 100644
--- a/drivers/net/slip.h
+++ b/drivers/net/slip.h
@@ -67,15 +67,6 @@ struct slip {
int xleft; /* bytes left in XMIT queue */
/* SLIP interface statistics. */
- unsigned long rx_packets; /* inbound frames counter */
- unsigned long tx_packets; /* outbound frames counter */
- unsigned long rx_bytes; /* inbound byte counte */
- unsigned long tx_bytes; /* outbound byte counter */
- unsigned long rx_errors; /* Parity, etc. errors */
- unsigned long tx_errors; /* Planned stuff */
- unsigned long rx_dropped; /* No memory for skb */
- unsigned long tx_dropped; /* When MTU change */
- unsigned long rx_over_errors; /* Frame bigger than SLIP buf. */
#ifdef SL_INCLUDE_CSLIP
unsigned long tx_compressed;
unsigned long rx_compressed;
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 8150ba154116..a8e5856ce882 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -1049,7 +1049,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head,
pktwords);
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
netif_receive_skb(skb);
/* Update counters */
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 1636a34d95dd..cb6bcca9d541 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1000,9 +1000,9 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
!(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (data_status & SPIDER_NET_VLAN_PACKET) {
/* further enhancements: HW-accel VLAN
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index a42b6873370b..4adf12422787 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -148,7 +148,7 @@ static int full_duplex[MAX_UNITS] = {0, };
* This SUCKS.
* We need a much better method to determine if dma_addr_t is 64-bit.
*/
-#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))
+#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT))
/* 64-bit dma_addr_t */
#define ADDR_64BITS /* This chip uses 64 bit addresses. */
#define netdrv_addr_t __le64
@@ -302,7 +302,7 @@ enum chipset {
};
static DEFINE_PCI_DEVICE_TABLE(starfire_pci_tbl) = {
- { 0x9004, 0x6915, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_6915 },
+ { PCI_VDEVICE(ADAPTEC, 0x6915), CH_6915 },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, starfire_pci_tbl);
@@ -2078,11 +2078,7 @@ static int __init starfire_init (void)
printk(KERN_INFO DRV_NAME ": polling (NAPI) enabled\n");
#endif
- /* we can do this test only at run-time... sigh */
- if (sizeof(dma_addr_t) != sizeof(netdrv_addr_t)) {
- printk("This driver has dma_addr_t issues, please send email to maintainer\n");
- return -ENODEV;
- }
+ BUILD_BUG_ON(sizeof(dma_addr_t) != sizeof(netdrv_addr_t));
return pci_register_driver(&starfire_driver);
}
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
index eb63d44748a7..7df7df4e79c5 100644
--- a/drivers/net/stmmac/Kconfig
+++ b/drivers/net/stmmac/Kconfig
@@ -3,10 +3,10 @@ config STMMAC_ETH
select MII
select PHYLIB
select CRC32
- depends on NETDEVICES && CPU_SUBTYPE_ST40
+ depends on NETDEVICES && HAS_IOMEM
help
This is the driver for the Ethernet IPs are built around a
- Synopsys IP Core and fully tested on the STMicroelectronics
+ Synopsys IP Core and only tested on the STMicroelectronics
platforms.
if STMMAC_ETH
@@ -32,6 +32,7 @@ config STMMAC_DUAL_MAC
config STMMAC_TIMER
bool "STMMAC Timer optimisation"
default n
+ depends on RTC_HCTOSYS_DEVICE
help
Use an external timer for mitigating the number of network
interrupts. Currently, for SH architectures, it is possible
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
index 66b9da0260fe..375ea193e139 100644
--- a/drivers/net/stmmac/common.h
+++ b/drivers/net/stmmac/common.h
@@ -102,8 +102,6 @@ struct stmmac_extra_stats {
#define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */
-#define HW_CSUM 1
-#define NO_HW_CSUM 0
enum rx_frame_status { /* IPC status */
good_frame = 0,
discard_frame = 1,
@@ -167,7 +165,7 @@ struct stmmac_desc_ops {
int (*get_tx_ls) (struct dma_desc *p);
/* Return the transmit status looking at the TDES1 */
int (*tx_status) (void *data, struct stmmac_extra_stats *x,
- struct dma_desc *p, unsigned long ioaddr);
+ struct dma_desc *p, void __iomem *ioaddr);
/* Get the buffer size from the descriptor */
int (*get_tx_len) (struct dma_desc *p);
/* Handle extra events on specific interrupts hw dependent */
@@ -182,44 +180,46 @@ struct stmmac_desc_ops {
struct stmmac_dma_ops {
/* DMA core initialization */
- int (*init) (unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
+ int (*init) (void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
/* Dump DMA registers */
- void (*dump_regs) (unsigned long ioaddr);
+ void (*dump_regs) (void __iomem *ioaddr);
/* Set tx/rx threshold in the csr6 register
* An invalid value enables the store-and-forward mode */
- void (*dma_mode) (unsigned long ioaddr, int txmode, int rxmode);
+ void (*dma_mode) (void __iomem *ioaddr, int txmode, int rxmode);
/* To track extra statistic (if supported) */
void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
- unsigned long ioaddr);
- void (*enable_dma_transmission) (unsigned long ioaddr);
- void (*enable_dma_irq) (unsigned long ioaddr);
- void (*disable_dma_irq) (unsigned long ioaddr);
- void (*start_tx) (unsigned long ioaddr);
- void (*stop_tx) (unsigned long ioaddr);
- void (*start_rx) (unsigned long ioaddr);
- void (*stop_rx) (unsigned long ioaddr);
- int (*dma_interrupt) (unsigned long ioaddr,
+ void __iomem *ioaddr);
+ void (*enable_dma_transmission) (void __iomem *ioaddr);
+ void (*enable_dma_irq) (void __iomem *ioaddr);
+ void (*disable_dma_irq) (void __iomem *ioaddr);
+ void (*start_tx) (void __iomem *ioaddr);
+ void (*stop_tx) (void __iomem *ioaddr);
+ void (*start_rx) (void __iomem *ioaddr);
+ void (*stop_rx) (void __iomem *ioaddr);
+ int (*dma_interrupt) (void __iomem *ioaddr,
struct stmmac_extra_stats *x);
};
struct stmmac_ops {
/* MAC core initialization */
- void (*core_init) (unsigned long ioaddr) ____cacheline_aligned;
+ void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned;
+ /* Support checksum offload engine */
+ int (*rx_coe) (void __iomem *ioaddr);
/* Dump MAC registers */
- void (*dump_regs) (unsigned long ioaddr);
+ void (*dump_regs) (void __iomem *ioaddr);
/* Handle extra events on specific interrupts hw dependent */
- void (*host_irq_status) (unsigned long ioaddr);
+ void (*host_irq_status) (void __iomem *ioaddr);
/* Multicast filter setting */
void (*set_filter) (struct net_device *dev);
/* Flow control setting */
- void (*flow_ctrl) (unsigned long ioaddr, unsigned int duplex,
+ void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex,
unsigned int fc, unsigned int pause_time);
/* Set power management mode (e.g. magic frame) */
- void (*pmt) (unsigned long ioaddr, unsigned long mode);
+ void (*pmt) (void __iomem *ioaddr, unsigned long mode);
/* Set/Get Unicast MAC addresses */
- void (*set_umac_addr) (unsigned long ioaddr, unsigned char *addr,
+ void (*set_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n);
- void (*get_umac_addr) (unsigned long ioaddr, unsigned char *addr,
+ void (*get_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n);
};
@@ -235,19 +235,18 @@ struct mii_regs {
};
struct mac_device_info {
- struct stmmac_ops *mac;
- struct stmmac_desc_ops *desc;
- struct stmmac_dma_ops *dma;
- unsigned int pmt; /* support Power-Down */
+ const struct stmmac_ops *mac;
+ const struct stmmac_desc_ops *desc;
+ const struct stmmac_dma_ops *dma;
struct mii_regs mii; /* MII register Addresses */
struct mac_link link;
};
-struct mac_device_info *dwmac1000_setup(unsigned long addr);
-struct mac_device_info *dwmac100_setup(unsigned long addr);
+struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr);
+struct mac_device_info *dwmac100_setup(void __iomem *ioaddr);
-extern void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
+extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
unsigned int high, unsigned int low);
-extern void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr,
+extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int high, unsigned int low);
-extern void dwmac_dma_flush_tx_fifo(unsigned long ioaddr);
+extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
diff --git a/drivers/net/stmmac/dwmac100.h b/drivers/net/stmmac/dwmac100.h
index 97956cbf1cb4..7c6d857a9cc7 100644
--- a/drivers/net/stmmac/dwmac100.h
+++ b/drivers/net/stmmac/dwmac100.h
@@ -118,4 +118,4 @@ enum ttc_control {
#define DMA_MISSED_FRAME_OVE_M 0x00010000 /* Missed Frame Overflow */
#define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */
-extern struct stmmac_dma_ops dwmac100_dma_ops;
+extern const struct stmmac_dma_ops dwmac100_dma_ops;
diff --git a/drivers/net/stmmac/dwmac1000.h b/drivers/net/stmmac/dwmac1000.h
index 8b20b19971cb..cfcef0ea0fa5 100644
--- a/drivers/net/stmmac/dwmac1000.h
+++ b/drivers/net/stmmac/dwmac1000.h
@@ -99,7 +99,7 @@ enum inter_frame_gap {
#define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */
#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
- GMAC_CONTROL_IPC | GMAC_CONTROL_JE | GMAC_CONTROL_BE)
+ GMAC_CONTROL_JE | GMAC_CONTROL_BE)
/* GMAC Frame Filter defines */
#define GMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */
@@ -205,4 +205,4 @@ enum rtc_control {
#define GMAC_MMC_TX_INTR 0x108
#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
-extern struct stmmac_dma_ops dwmac1000_dma_ops;
+extern const struct stmmac_dma_ops dwmac1000_dma_ops;
diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c
index 2b2f5c8caf1c..6ae4c3f4c63c 100644
--- a/drivers/net/stmmac/dwmac1000_core.c
+++ b/drivers/net/stmmac/dwmac1000_core.c
@@ -30,7 +30,7 @@
#include <linux/slab.h>
#include "dwmac1000.h"
-static void dwmac1000_core_init(unsigned long ioaddr)
+static void dwmac1000_core_init(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + GMAC_CONTROL);
value |= GMAC_CORE_INIT;
@@ -50,10 +50,22 @@ static void dwmac1000_core_init(unsigned long ioaddr)
#endif
}
-static void dwmac1000_dump_regs(unsigned long ioaddr)
+static int dwmac1000_rx_coe_supported(void __iomem *ioaddr)
+{
+ u32 value = readl(ioaddr + GMAC_CONTROL);
+
+ value |= GMAC_CONTROL_IPC;
+ writel(value, ioaddr + GMAC_CONTROL);
+
+ value = readl(ioaddr + GMAC_CONTROL);
+
+ return !!(value & GMAC_CONTROL_IPC);
+}
+
+static void dwmac1000_dump_regs(void __iomem *ioaddr)
{
int i;
- pr_info("\tDWMAC1000 regs (base addr = 0x%8x)\n", (unsigned int)ioaddr);
+ pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
for (i = 0; i < 55; i++) {
int offset = i * 4;
@@ -62,14 +74,14 @@ static void dwmac1000_dump_regs(unsigned long ioaddr)
}
}
-static void dwmac1000_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
+static void dwmac1000_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n)
{
stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
GMAC_ADDR_LOW(reg_n));
}
-static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
+static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n)
{
stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
@@ -78,7 +90,7 @@ static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
static void dwmac1000_set_filter(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = (void __iomem *) dev->base_addr;
unsigned int value = 0;
CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
@@ -139,7 +151,7 @@ static void dwmac1000_set_filter(struct net_device *dev)
readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
}
-static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
+static void dwmac1000_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
unsigned int fc, unsigned int pause_time)
{
unsigned int flow = 0;
@@ -162,7 +174,7 @@ static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
writel(flow, ioaddr + GMAC_FLOW_CTRL);
}
-static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode)
+static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
{
unsigned int pmt = 0;
@@ -178,7 +190,7 @@ static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode)
}
-static void dwmac1000_irq_status(unsigned long ioaddr)
+static void dwmac1000_irq_status(void __iomem *ioaddr)
{
u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
@@ -200,8 +212,9 @@ static void dwmac1000_irq_status(unsigned long ioaddr)
}
}
-struct stmmac_ops dwmac1000_ops = {
+static const struct stmmac_ops dwmac1000_ops = {
.core_init = dwmac1000_core_init,
+ .rx_coe = dwmac1000_rx_coe_supported,
.dump_regs = dwmac1000_dump_regs,
.host_irq_status = dwmac1000_irq_status,
.set_filter = dwmac1000_set_filter,
@@ -211,7 +224,7 @@ struct stmmac_ops dwmac1000_ops = {
.get_umac_addr = dwmac1000_get_umac_addr,
};
-struct mac_device_info *dwmac1000_setup(unsigned long ioaddr)
+struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
{
struct mac_device_info *mac;
u32 uid = readl(ioaddr + GMAC_VERSION);
@@ -226,7 +239,6 @@ struct mac_device_info *dwmac1000_setup(unsigned long ioaddr)
mac->mac = &dwmac1000_ops;
mac->dma = &dwmac1000_dma_ops;
- mac->pmt = PMT_SUPPORTED;
mac->link.port = GMAC_CONTROL_PS;
mac->link.duplex = GMAC_CONTROL_DM;
mac->link.speed = GMAC_CONTROL_FES;
diff --git a/drivers/net/stmmac/dwmac1000_dma.c b/drivers/net/stmmac/dwmac1000_dma.c
index 415805057cb0..2c47712d45d0 100644
--- a/drivers/net/stmmac/dwmac1000_dma.c
+++ b/drivers/net/stmmac/dwmac1000_dma.c
@@ -29,14 +29,22 @@
#include "dwmac1000.h"
#include "dwmac_dma.h"
-static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
+static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
u32 dma_rx)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
+ int limit;
+
/* DMA SW reset */
value |= DMA_BUS_MODE_SFT_RESET;
writel(value, ioaddr + DMA_BUS_MODE);
- do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
+ limit = 15000;
+ while (limit--) {
+ if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
+ break;
+ }
+ if (limit < 0)
+ return -EBUSY;
value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
((pbl << DMA_BUS_MODE_PBL_SHIFT) |
@@ -58,7 +66,7 @@ static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
return 0;
}
-static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode,
+static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
int rxmode)
{
u32 csr6 = readl(ioaddr + DMA_CONTROL);
@@ -111,12 +119,12 @@ static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode,
/* Not yet implemented --- no RMON module */
static void dwmac1000_dma_diagnostic_fr(void *data,
- struct stmmac_extra_stats *x, unsigned long ioaddr)
+ struct stmmac_extra_stats *x, void __iomem *ioaddr)
{
return;
}
-static void dwmac1000_dump_dma_regs(unsigned long ioaddr)
+static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
{
int i;
pr_info(" DMA registers\n");
@@ -130,7 +138,7 @@ static void dwmac1000_dump_dma_regs(unsigned long ioaddr)
}
}
-struct stmmac_dma_ops dwmac1000_dma_ops = {
+const struct stmmac_dma_ops dwmac1000_dma_ops = {
.init = dwmac1000_dma_init,
.dump_regs = dwmac1000_dump_dma_regs,
.dma_mode = dwmac1000_dma_operation_mode,
diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c
index 2fb165fa2ba0..c724fc36a24f 100644
--- a/drivers/net/stmmac/dwmac100_core.c
+++ b/drivers/net/stmmac/dwmac100_core.c
@@ -31,7 +31,7 @@
#include <linux/crc32.h>
#include "dwmac100.h"
-static void dwmac100_core_init(unsigned long ioaddr)
+static void dwmac100_core_init(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + MAC_CONTROL);
@@ -42,12 +42,17 @@ static void dwmac100_core_init(unsigned long ioaddr)
#endif
}
-static void dwmac100_dump_mac_regs(unsigned long ioaddr)
+static int dwmac100_rx_coe_supported(void __iomem *ioaddr)
+{
+ return 0;
+}
+
+static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
{
pr_info("\t----------------------------------------------\n"
- "\t DWMAC 100 CSR (base addr = 0x%8x)\n"
+ "\t DWMAC 100 CSR (base addr = 0x%p)\n"
"\t----------------------------------------------\n",
- (unsigned int)ioaddr);
+ ioaddr);
pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
readl(ioaddr + MAC_CONTROL));
pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
@@ -77,18 +82,18 @@ static void dwmac100_dump_mac_regs(unsigned long ioaddr)
MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
}
-static void dwmac100_irq_status(unsigned long ioaddr)
+static void dwmac100_irq_status(void __iomem *ioaddr)
{
return;
}
-static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
+static void dwmac100_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n)
{
stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
}
-static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
+static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n)
{
stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
@@ -96,7 +101,7 @@ static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
static void dwmac100_set_filter(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = (void __iomem *) dev->base_addr;
u32 value = readl(ioaddr + MAC_CONTROL);
if (dev->flags & IFF_PROMISC) {
@@ -145,7 +150,7 @@ static void dwmac100_set_filter(struct net_device *dev)
readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
}
-static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
+static void dwmac100_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
unsigned int fc, unsigned int pause_time)
{
unsigned int flow = MAC_FLOW_CTRL_ENABLE;
@@ -158,13 +163,14 @@ static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
/* No PMT module supported for this Ethernet Controller.
* Tested on ST platforms only.
*/
-static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode)
+static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode)
{
return;
}
-struct stmmac_ops dwmac100_ops = {
+static const struct stmmac_ops dwmac100_ops = {
.core_init = dwmac100_core_init,
+ .rx_coe = dwmac100_rx_coe_supported,
.dump_regs = dwmac100_dump_mac_regs,
.host_irq_status = dwmac100_irq_status,
.set_filter = dwmac100_set_filter,
@@ -174,7 +180,7 @@ struct stmmac_ops dwmac100_ops = {
.get_umac_addr = dwmac100_get_umac_addr,
};
-struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
+struct mac_device_info *dwmac100_setup(void __iomem *ioaddr)
{
struct mac_device_info *mac;
@@ -187,7 +193,6 @@ struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
mac->mac = &dwmac100_ops;
mac->dma = &dwmac100_dma_ops;
- mac->pmt = PMT_NOT_SUPPORTED;
mac->link.port = MAC_CONTROL_PS;
mac->link.duplex = MAC_CONTROL_F;
mac->link.speed = 0;
diff --git a/drivers/net/stmmac/dwmac100_dma.c b/drivers/net/stmmac/dwmac100_dma.c
index 2fece7b72727..e3e224b7d9e2 100644
--- a/drivers/net/stmmac/dwmac100_dma.c
+++ b/drivers/net/stmmac/dwmac100_dma.c
@@ -31,14 +31,22 @@
#include "dwmac100.h"
#include "dwmac_dma.h"
-static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
+static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
u32 dma_rx)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
+ int limit;
+
/* DMA SW reset */
value |= DMA_BUS_MODE_SFT_RESET;
writel(value, ioaddr + DMA_BUS_MODE);
- do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
+ limit = 15000;
+ while (limit--) {
+ if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
+ break;
+ }
+ if (limit < 0)
+ return -EBUSY;
/* Enable Application Access by writing to DMA CSR0 */
writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
@@ -58,7 +66,7 @@ static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
/* Store and Forward capability is not used at all..
* The transmit threshold can be programmed by
* setting the TTC bits in the DMA control register.*/
-static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode,
+static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode,
int rxmode)
{
u32 csr6 = readl(ioaddr + DMA_CONTROL);
@@ -73,7 +81,7 @@ static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode,
writel(csr6, ioaddr + DMA_CONTROL);
}
-static void dwmac100_dump_dma_regs(unsigned long ioaddr)
+static void dwmac100_dump_dma_regs(void __iomem *ioaddr)
{
int i;
@@ -91,7 +99,7 @@ static void dwmac100_dump_dma_regs(unsigned long ioaddr)
/* DMA controller has two counters to track the number of
* the receive missed frames. */
static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
- unsigned long ioaddr)
+ void __iomem *ioaddr)
{
struct net_device_stats *stats = (struct net_device_stats *)data;
u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
@@ -118,7 +126,7 @@ static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
}
}
-struct stmmac_dma_ops dwmac100_dma_ops = {
+const struct stmmac_dma_ops dwmac100_dma_ops = {
.init = dwmac100_dma_init,
.dump_regs = dwmac100_dump_dma_regs,
.dma_mode = dwmac100_dma_operation_mode,
diff --git a/drivers/net/stmmac/dwmac_dma.h b/drivers/net/stmmac/dwmac_dma.h
index 7b815a1b7b8c..da3f5ccf83d3 100644
--- a/drivers/net/stmmac/dwmac_dma.h
+++ b/drivers/net/stmmac/dwmac_dma.h
@@ -97,12 +97,12 @@
#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */
#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
-extern void dwmac_enable_dma_transmission(unsigned long ioaddr);
-extern void dwmac_enable_dma_irq(unsigned long ioaddr);
-extern void dwmac_disable_dma_irq(unsigned long ioaddr);
-extern void dwmac_dma_start_tx(unsigned long ioaddr);
-extern void dwmac_dma_stop_tx(unsigned long ioaddr);
-extern void dwmac_dma_start_rx(unsigned long ioaddr);
-extern void dwmac_dma_stop_rx(unsigned long ioaddr);
-extern int dwmac_dma_interrupt(unsigned long ioaddr,
+extern void dwmac_enable_dma_transmission(void __iomem *ioaddr);
+extern void dwmac_enable_dma_irq(void __iomem *ioaddr);
+extern void dwmac_disable_dma_irq(void __iomem *ioaddr);
+extern void dwmac_dma_start_tx(void __iomem *ioaddr);
+extern void dwmac_dma_stop_tx(void __iomem *ioaddr);
+extern void dwmac_dma_start_rx(void __iomem *ioaddr);
+extern void dwmac_dma_stop_rx(void __iomem *ioaddr);
+extern int dwmac_dma_interrupt(void __iomem *ioaddr,
struct stmmac_extra_stats *x);
diff --git a/drivers/net/stmmac/dwmac_lib.c b/drivers/net/stmmac/dwmac_lib.c
index a85415216ef4..d65fab1ba790 100644
--- a/drivers/net/stmmac/dwmac_lib.c
+++ b/drivers/net/stmmac/dwmac_lib.c
@@ -32,43 +32,43 @@
#endif
/* CSR1 enables the transmit DMA to check for new descriptor */
-void dwmac_enable_dma_transmission(unsigned long ioaddr)
+void dwmac_enable_dma_transmission(void __iomem *ioaddr)
{
writel(1, ioaddr + DMA_XMT_POLL_DEMAND);
}
-void dwmac_enable_dma_irq(unsigned long ioaddr)
+void dwmac_enable_dma_irq(void __iomem *ioaddr)
{
writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
}
-void dwmac_disable_dma_irq(unsigned long ioaddr)
+void dwmac_disable_dma_irq(void __iomem *ioaddr)
{
writel(0, ioaddr + DMA_INTR_ENA);
}
-void dwmac_dma_start_tx(unsigned long ioaddr)
+void dwmac_dma_start_tx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + DMA_CONTROL);
value |= DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CONTROL);
}
-void dwmac_dma_stop_tx(unsigned long ioaddr)
+void dwmac_dma_stop_tx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + DMA_CONTROL);
value &= ~DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CONTROL);
}
-void dwmac_dma_start_rx(unsigned long ioaddr)
+void dwmac_dma_start_rx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + DMA_CONTROL);
value |= DMA_CONTROL_SR;
writel(value, ioaddr + DMA_CONTROL);
}
-void dwmac_dma_stop_rx(unsigned long ioaddr)
+void dwmac_dma_stop_rx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + DMA_CONTROL);
value &= ~DMA_CONTROL_SR;
@@ -145,7 +145,7 @@ static void show_rx_process_state(unsigned int status)
}
#endif
-int dwmac_dma_interrupt(unsigned long ioaddr,
+int dwmac_dma_interrupt(void __iomem *ioaddr,
struct stmmac_extra_stats *x)
{
int ret = 0;
@@ -219,7 +219,7 @@ int dwmac_dma_interrupt(unsigned long ioaddr,
return ret;
}
-void dwmac_dma_flush_tx_fifo(unsigned long ioaddr)
+void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr)
{
u32 csr6 = readl(ioaddr + DMA_CONTROL);
writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
@@ -227,7 +227,7 @@ void dwmac_dma_flush_tx_fifo(unsigned long ioaddr)
do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
}
-void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
+void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
unsigned int high, unsigned int low)
{
unsigned long data;
@@ -238,7 +238,7 @@ void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
writel(data, ioaddr + low);
}
-void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr,
+void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int high, unsigned int low)
{
unsigned int hi_addr, lo_addr;
diff --git a/drivers/net/stmmac/enh_desc.c b/drivers/net/stmmac/enh_desc.c
index f612f986a7e1..e5dfb6a30182 100644
--- a/drivers/net/stmmac/enh_desc.c
+++ b/drivers/net/stmmac/enh_desc.c
@@ -25,7 +25,7 @@
#include "common.h"
static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x,
- struct dma_desc *p, unsigned long ioaddr)
+ struct dma_desc *p, void __iomem *ioaddr)
{
int ret = 0;
struct net_device_stats *stats = (struct net_device_stats *)data;
@@ -284,7 +284,7 @@ static void enh_desc_release_tx_desc(struct dma_desc *p)
{
int ter = p->des01.etx.end_ring;
- memset(p, 0, sizeof(struct dma_desc));
+ memset(p, 0, offsetof(struct dma_desc, des2));
p->des01.etx.end_ring = ter;
}
@@ -318,7 +318,7 @@ static int enh_desc_get_rx_frame_len(struct dma_desc *p)
return p->des01.erx.frame_length;
}
-struct stmmac_desc_ops enh_desc_ops = {
+const struct stmmac_desc_ops enh_desc_ops = {
.tx_status = enh_desc_get_tx_status,
.rx_status = enh_desc_get_rx_status,
.get_tx_len = enh_desc_get_tx_len,
diff --git a/drivers/net/stmmac/norm_desc.c b/drivers/net/stmmac/norm_desc.c
index 31ad53643792..cd0cc76f7a1c 100644
--- a/drivers/net/stmmac/norm_desc.c
+++ b/drivers/net/stmmac/norm_desc.c
@@ -25,7 +25,7 @@
#include "common.h"
static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x,
- struct dma_desc *p, unsigned long ioaddr)
+ struct dma_desc *p, void __iomem *ioaddr)
{
int ret = 0;
struct net_device_stats *stats = (struct net_device_stats *)data;
@@ -174,22 +174,7 @@ static void ndesc_release_tx_desc(struct dma_desc *p)
{
int ter = p->des01.tx.end_ring;
- /* clean field used within the xmit */
- p->des01.tx.first_segment = 0;
- p->des01.tx.last_segment = 0;
- p->des01.tx.buffer1_size = 0;
-
- /* clean status reported */
- p->des01.tx.error_summary = 0;
- p->des01.tx.underflow_error = 0;
- p->des01.tx.no_carrier = 0;
- p->des01.tx.loss_carrier = 0;
- p->des01.tx.excessive_deferral = 0;
- p->des01.tx.excessive_collisions = 0;
- p->des01.tx.late_collision = 0;
- p->des01.tx.heartbeat_fail = 0;
- p->des01.tx.deferred = 0;
-
+ memset(p, 0, offsetof(struct dma_desc, des2));
/* set termination field */
p->des01.tx.end_ring = ter;
}
@@ -217,7 +202,7 @@ static int ndesc_get_rx_frame_len(struct dma_desc *p)
return p->des01.rx.frame_length;
}
-struct stmmac_desc_ops ndesc_ops = {
+const struct stmmac_desc_ops ndesc_ops = {
.tx_status = ndesc_get_tx_status,
.rx_status = ndesc_get_rx_status,
.get_tx_len = ndesc_get_tx_len,
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index ebebc644b1b8..79bdc2e13224 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -21,6 +21,7 @@
*******************************************************************************/
#define DRV_MODULE_VERSION "Apr_2010"
+#include <linux/platform_device.h>
#include <linux/stmmac.h>
#include "common.h"
@@ -50,10 +51,10 @@ struct stmmac_priv {
int is_gmac;
dma_addr_t dma_rx_phy;
unsigned int dma_rx_size;
- int rx_csum;
unsigned int dma_buf_sz;
struct device *device;
struct mac_device_info *hw;
+ void __iomem *ioaddr;
struct stmmac_extra_stats xstats;
struct napi_struct napi;
@@ -65,7 +66,7 @@ struct stmmac_priv {
int phy_mask;
int (*phy_reset) (void *priv);
void (*fix_mac_speed) (void *priv, unsigned int speed);
- void (*bus_setup)(unsigned long ioaddr);
+ void (*bus_setup)(void __iomem *ioaddr);
void *bsp_priv;
int phy_irq;
@@ -76,6 +77,7 @@ struct stmmac_priv {
unsigned int flow_ctrl;
unsigned int pause;
struct mii_bus *mii;
+ int mii_clk_csr;
u32 msg_enable;
spinlock_t lock;
@@ -89,6 +91,9 @@ struct stmmac_priv {
struct vlan_group *vlgrp;
#endif
int enh_desc;
+ int rx_coe;
+ int bugged_jumbo;
+ int no_csum_insertion;
};
#ifdef CONFIG_STM_DRIVERS
@@ -116,5 +121,5 @@ static inline int stmmac_claim_resource(struct platform_device *pdev)
extern int stmmac_mdio_unregister(struct net_device *ndev);
extern int stmmac_mdio_register(struct net_device *ndev);
extern void stmmac_set_ethtool_ops(struct net_device *netdev);
-extern struct stmmac_desc_ops enh_desc_ops;
-extern struct stmmac_desc_ops ndesc_ops;
+extern const struct stmmac_desc_ops enh_desc_ops;
+extern const struct stmmac_desc_ops ndesc_ops;
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index f080509923f0..6d65482e789a 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -89,8 +89,8 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
};
#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
-void stmmac_ethtool_getdrvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
+static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
{
struct stmmac_priv *priv = netdev_priv(dev);
@@ -104,7 +104,8 @@ void stmmac_ethtool_getdrvinfo(struct net_device *dev,
info->n_stats = STMMAC_STATS_LEN;
}
-int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int stmmac_ethtool_getsettings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
{
struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phy = priv->phydev;
@@ -126,7 +127,8 @@ int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
return rc;
}
-int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int stmmac_ethtool_setsettings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
{
struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phy = priv->phydev;
@@ -139,32 +141,32 @@ int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
return rc;
}
-u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
+static u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
return priv->msg_enable;
}
-void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
+static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
{
struct stmmac_priv *priv = netdev_priv(dev);
priv->msg_enable = level;
}
-int stmmac_check_if_running(struct net_device *dev)
+static int stmmac_check_if_running(struct net_device *dev)
{
if (!netif_running(dev))
return -EBUSY;
return 0;
}
-int stmmac_ethtool_get_regs_len(struct net_device *dev)
+static int stmmac_ethtool_get_regs_len(struct net_device *dev)
{
return REG_SPACE_SIZE;
}
-void stmmac_ethtool_gregs(struct net_device *dev,
+static void stmmac_ethtool_gregs(struct net_device *dev,
struct ethtool_regs *regs, void *space)
{
int i;
@@ -177,25 +179,25 @@ void stmmac_ethtool_gregs(struct net_device *dev,
if (!priv->is_gmac) {
/* MAC registers */
for (i = 0; i < 12; i++)
- reg_space[i] = readl(dev->base_addr + (i * 4));
+ reg_space[i] = readl(priv->ioaddr + (i * 4));
/* DMA registers */
for (i = 0; i < 9; i++)
reg_space[i + 12] =
- readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
- reg_space[22] = readl(dev->base_addr + DMA_CUR_TX_BUF_ADDR);
- reg_space[23] = readl(dev->base_addr + DMA_CUR_RX_BUF_ADDR);
+ readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
+ reg_space[22] = readl(priv->ioaddr + DMA_CUR_TX_BUF_ADDR);
+ reg_space[23] = readl(priv->ioaddr + DMA_CUR_RX_BUF_ADDR);
} else {
/* MAC registers */
for (i = 0; i < 55; i++)
- reg_space[i] = readl(dev->base_addr + (i * 4));
+ reg_space[i] = readl(priv->ioaddr + (i * 4));
/* DMA registers */
for (i = 0; i < 22; i++)
reg_space[i + 55] =
- readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
+ readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
}
}
-int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data)
+static int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data)
{
if (data)
netdev->features |= NETIF_F_HW_CSUM;
@@ -205,11 +207,11 @@ int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data)
return 0;
}
-u32 stmmac_ethtool_get_rx_csum(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_csum;
+ return priv->rx_coe;
}
static void
@@ -263,11 +265,9 @@ stmmac_set_pauseparam(struct net_device *netdev,
cmd.phy_address = phy->addr;
ret = phy_ethtool_sset(phy, &cmd);
}
- } else {
- unsigned long ioaddr = netdev->base_addr;
- priv->hw->mac->flow_ctrl(ioaddr, phy->duplex,
+ } else
+ priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
priv->flow_ctrl, priv->pause);
- }
spin_unlock(&priv->lock);
return ret;
}
@@ -276,12 +276,11 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *dummy, u64 *data)
{
struct stmmac_priv *priv = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
int i;
/* Update HW stats if supported */
priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats,
- ioaddr);
+ priv->ioaddr);
for (i = 0; i < STMMAC_STATS_LEN; i++) {
char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
@@ -325,7 +324,7 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
struct stmmac_priv *priv = netdev_priv(dev);
spin_lock_irq(&priv->lock);
- if (priv->wolenabled == PMT_SUPPORTED) {
+ if (device_can_wakeup(priv->device)) {
wol->supported = WAKE_MAGIC;
wol->wolopts = priv->wolopts;
}
@@ -337,16 +336,20 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
struct stmmac_priv *priv = netdev_priv(dev);
u32 support = WAKE_MAGIC;
- if (priv->wolenabled == PMT_NOT_SUPPORTED)
+ if (!device_can_wakeup(priv->device))
return -EINVAL;
if (wol->wolopts & ~support)
return -EINVAL;
- if (wol->wolopts == 0)
- device_set_wakeup_enable(priv->device, 0);
- else
+ if (wol->wolopts) {
+ pr_info("stmmac: wakeup enable\n");
device_set_wakeup_enable(priv->device, 1);
+ enable_irq_wake(dev->irq);
+ } else {
+ device_set_wakeup_enable(priv->device, 0);
+ disable_irq_wake(dev->irq);
+ }
spin_lock_irq(&priv->lock);
priv->wolopts = wol->wolopts;
@@ -377,10 +380,8 @@ static struct ethtool_ops stmmac_ethtool_ops = {
.get_wol = stmmac_get_wol,
.set_wol = stmmac_set_wol,
.get_sset_count = stmmac_get_sset_count,
-#ifdef NETIF_F_TSO
.get_tso = ethtool_op_get_tso,
.set_tso = ethtool_op_set_tso,
-#endif
};
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 ea0461eb2dbe..823b9e6431d5 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -134,13 +134,6 @@ static int buf_sz = DMA_BUFFER_SIZE;
module_param(buf_sz, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(buf_sz, "DMA buffer size");
-/* In case of Giga ETH, we can enable/disable the COE for the
- * transmit HW checksum computation.
- * Note that, if tx csum is off in HW, SG will be still supported. */
-static int tx_coe = HW_CSUM;
-module_param(tx_coe, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(tx_coe, "GMAC COE type 2 [on/off]");
-
static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
NETIF_MSG_LINK | NETIF_MSG_IFUP |
NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
@@ -202,7 +195,6 @@ static void stmmac_adjust_link(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phydev = priv->phydev;
- unsigned long ioaddr = dev->base_addr;
unsigned long flags;
int new_state = 0;
unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
@@ -215,7 +207,7 @@ static void stmmac_adjust_link(struct net_device *dev)
spin_lock_irqsave(&priv->lock, flags);
if (phydev->link) {
- u32 ctrl = readl(ioaddr + MAC_CTRL_REG);
+ u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
/* Now we make sure that we can be in full duplex mode.
* If not, we operate in half-duplex mode. */
@@ -229,7 +221,7 @@ static void stmmac_adjust_link(struct net_device *dev)
}
/* Flow Control operation */
if (phydev->pause)
- priv->hw->mac->flow_ctrl(ioaddr, phydev->duplex,
+ priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex,
fc, pause_time);
if (phydev->speed != priv->speed) {
@@ -238,6 +230,9 @@ static void stmmac_adjust_link(struct net_device *dev)
case 1000:
if (likely(priv->is_gmac))
ctrl &= ~priv->hw->link.port;
+ if (likely(priv->fix_mac_speed))
+ priv->fix_mac_speed(priv->bsp_priv,
+ phydev->speed);
break;
case 100:
case 10:
@@ -265,7 +260,7 @@ static void stmmac_adjust_link(struct net_device *dev)
priv->speed = phydev->speed;
}
- writel(ctrl, ioaddr + MAC_CTRL_REG);
+ writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
if (!priv->oldlink) {
new_state = 1;
@@ -342,7 +337,7 @@ static int stmmac_init_phy(struct net_device *dev)
return 0;
}
-static inline void stmmac_mac_enable_rx(unsigned long ioaddr)
+static inline void stmmac_mac_enable_rx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + MAC_CTRL_REG);
value |= MAC_RNABLE_RX;
@@ -350,7 +345,7 @@ static inline void stmmac_mac_enable_rx(unsigned long ioaddr)
writel(value, ioaddr + MAC_CTRL_REG);
}
-static inline void stmmac_mac_enable_tx(unsigned long ioaddr)
+static inline void stmmac_mac_enable_tx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + MAC_CTRL_REG);
value |= MAC_ENABLE_TX;
@@ -358,14 +353,14 @@ static inline void stmmac_mac_enable_tx(unsigned long ioaddr)
writel(value, ioaddr + MAC_CTRL_REG);
}
-static inline void stmmac_mac_disable_rx(unsigned long ioaddr)
+static inline void stmmac_mac_disable_rx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + MAC_CTRL_REG);
value &= ~MAC_RNABLE_RX;
writel(value, ioaddr + MAC_CTRL_REG);
}
-static inline void stmmac_mac_disable_tx(unsigned long ioaddr)
+static inline void stmmac_mac_disable_tx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + MAC_CTRL_REG);
value &= ~MAC_ENABLE_TX;
@@ -567,29 +562,22 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
* stmmac_dma_operation_mode - HW DMA operation mode
* @priv : pointer to the private device structure.
* Description: it sets the DMA operation mode: tx/rx DMA thresholds
- * or Store-And-Forward capability. It also verifies the COE for the
- * transmission in case of Giga ETH.
+ * or Store-And-Forward capability.
*/
static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
{
- if (!priv->is_gmac) {
- /* MAC 10/100 */
- priv->hw->dma->dma_mode(priv->dev->base_addr, tc, 0);
- priv->tx_coe = NO_HW_CSUM;
- } else {
- if ((priv->dev->mtu <= ETH_DATA_LEN) && (tx_coe)) {
- priv->hw->dma->dma_mode(priv->dev->base_addr,
- SF_DMA_MODE, SF_DMA_MODE);
- tc = SF_DMA_MODE;
- priv->tx_coe = HW_CSUM;
- } else {
- /* Checksum computation is performed in software. */
- priv->hw->dma->dma_mode(priv->dev->base_addr, tc,
- SF_DMA_MODE);
- priv->tx_coe = NO_HW_CSUM;
- }
- }
- tx_coe = priv->tx_coe;
+ if (likely((priv->tx_coe) && (!priv->no_csum_insertion))) {
+ /* In case of GMAC, SF mode has to be enabled
+ * to perform the TX COE. This depends on:
+ * 1) TX COE if actually supported
+ * 2) There is no bugged Jumbo frame support
+ * that needs to not insert csum in the TDES.
+ */
+ priv->hw->dma->dma_mode(priv->ioaddr,
+ SF_DMA_MODE, SF_DMA_MODE);
+ tc = SF_DMA_MODE;
+ } else
+ priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
}
/**
@@ -600,7 +588,6 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
static void stmmac_tx(struct stmmac_priv *priv)
{
unsigned int txsize = priv->dma_tx_size;
- unsigned long ioaddr = priv->dev->base_addr;
while (priv->dirty_tx != priv->cur_tx) {
int last;
@@ -618,7 +605,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
int tx_error =
priv->hw->desc->tx_status(&priv->dev->stats,
&priv->xstats, p,
- ioaddr);
+ priv->ioaddr);
if (likely(tx_error == 0)) {
priv->dev->stats.tx_packets++;
priv->xstats.tx_pkt_n++;
@@ -674,7 +661,7 @@ static inline void stmmac_enable_irq(struct stmmac_priv *priv)
priv->tm->timer_start(tmrate);
else
#endif
- priv->hw->dma->enable_dma_irq(priv->dev->base_addr);
+ priv->hw->dma->enable_dma_irq(priv->ioaddr);
}
static inline void stmmac_disable_irq(struct stmmac_priv *priv)
@@ -684,7 +671,7 @@ static inline void stmmac_disable_irq(struct stmmac_priv *priv)
priv->tm->timer_stop();
else
#endif
- priv->hw->dma->disable_dma_irq(priv->dev->base_addr);
+ priv->hw->dma->disable_dma_irq(priv->ioaddr);
}
static int stmmac_has_work(struct stmmac_priv *priv)
@@ -739,14 +726,15 @@ static void stmmac_no_timer_stopped(void)
*/
static void stmmac_tx_err(struct stmmac_priv *priv)
{
+
netif_stop_queue(priv->dev);
- priv->hw->dma->stop_tx(priv->dev->base_addr);
+ priv->hw->dma->stop_tx(priv->ioaddr);
dma_free_tx_skbufs(priv);
priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
priv->dirty_tx = 0;
priv->cur_tx = 0;
- priv->hw->dma->start_tx(priv->dev->base_addr);
+ priv->hw->dma->start_tx(priv->ioaddr);
priv->dev->stats.tx_errors++;
netif_wake_queue(priv->dev);
@@ -755,11 +743,9 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
static void stmmac_dma_interrupt(struct stmmac_priv *priv)
{
- unsigned long ioaddr = priv->dev->base_addr;
int status;
- status = priv->hw->dma->dma_interrupt(priv->dev->base_addr,
- &priv->xstats);
+ status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
if (likely(status == handle_tx_rx))
_stmmac_schedule(priv);
@@ -767,7 +753,7 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
/* Try to bump up the dma threshold on this failure */
if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
tc += 64;
- priv->hw->dma->dma_mode(ioaddr, tc, SF_DMA_MODE);
+ priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
priv->xstats.threshold = tc;
}
stmmac_tx_err(priv);
@@ -787,7 +773,6 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
static int stmmac_open(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
int ret;
/* Check that the MAC address is valid. If its not, refuse
@@ -843,7 +828,8 @@ static int stmmac_open(struct net_device *dev)
init_dma_desc_rings(dev);
/* DMA initialization and SW reset */
- if (unlikely(priv->hw->dma->init(ioaddr, priv->pbl, priv->dma_tx_phy,
+ if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->pbl,
+ priv->dma_tx_phy,
priv->dma_rx_phy) < 0)) {
pr_err("%s: DMA initialization failed\n", __func__);
@@ -851,22 +837,28 @@ static int stmmac_open(struct net_device *dev)
}
/* Copy the MAC addr into the HW */
- priv->hw->mac->set_umac_addr(ioaddr, dev->dev_addr, 0);
+ priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
/* If required, perform hw setup of the bus. */
if (priv->bus_setup)
- priv->bus_setup(ioaddr);
+ priv->bus_setup(priv->ioaddr);
/* Initialize the MAC Core */
- priv->hw->mac->core_init(ioaddr);
+ priv->hw->mac->core_init(priv->ioaddr);
+
+ priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
+ if (priv->rx_coe)
+ pr_info("stmmac: Rx Checksum Offload Engine supported\n");
+ if (priv->tx_coe)
+ pr_info("\tTX Checksum insertion supported\n");
priv->shutdown = 0;
/* Initialise the MMC (if present) to disable all interrupts. */
- writel(0xffffffff, ioaddr + MMC_HIGH_INTR_MASK);
- writel(0xffffffff, ioaddr + MMC_LOW_INTR_MASK);
+ writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
+ writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK);
/* Enable the MAC Rx/Tx */
- stmmac_mac_enable_rx(ioaddr);
- stmmac_mac_enable_tx(ioaddr);
+ stmmac_mac_enable_rx(priv->ioaddr);
+ stmmac_mac_enable_tx(priv->ioaddr);
/* Set the HW DMA mode and the COE */
stmmac_dma_operation_mode(priv);
@@ -877,16 +869,16 @@ static int stmmac_open(struct net_device *dev)
/* Start the ball rolling... */
DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
- priv->hw->dma->start_tx(ioaddr);
- priv->hw->dma->start_rx(ioaddr);
+ priv->hw->dma->start_tx(priv->ioaddr);
+ priv->hw->dma->start_rx(priv->ioaddr);
#ifdef CONFIG_STMMAC_TIMER
priv->tm->timer_start(tmrate);
#endif
/* Dump DMA/MAC registers */
if (netif_msg_hw(priv)) {
- priv->hw->mac->dump_regs(ioaddr);
- priv->hw->dma->dump_regs(ioaddr);
+ priv->hw->mac->dump_regs(priv->ioaddr);
+ priv->hw->dma->dump_regs(priv->ioaddr);
}
if (priv->phydev)
@@ -930,15 +922,15 @@ static int stmmac_release(struct net_device *dev)
free_irq(dev->irq, dev);
/* Stop TX/RX DMA and clear the descriptors */
- priv->hw->dma->stop_tx(dev->base_addr);
- priv->hw->dma->stop_rx(dev->base_addr);
+ priv->hw->dma->stop_tx(priv->ioaddr);
+ priv->hw->dma->stop_rx(priv->ioaddr);
/* Release and free the Rx/Tx resources */
free_dma_desc_resources(priv);
/* Disable the MAC core */
- stmmac_mac_disable_tx(dev->base_addr);
- stmmac_mac_disable_rx(dev->base_addr);
+ stmmac_mac_disable_tx(priv->ioaddr);
+ stmmac_mac_disable_rx(priv->ioaddr);
netif_carrier_off(dev);
@@ -1066,7 +1058,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
return stmmac_sw_tso(priv, skb);
if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) {
- if (likely(priv->tx_coe == NO_HW_CSUM))
+ if (unlikely((!priv->tx_coe) || (priv->no_csum_insertion)))
skb_checksum_help(skb);
else
csum_insertion = 1;
@@ -1140,7 +1132,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_bytes += skb->len;
- priv->hw->dma->enable_dma_transmission(dev->base_addr);
+ priv->hw->dma->enable_dma_transmission(priv->ioaddr);
return NETDEV_TX_OK;
}
@@ -1256,7 +1248,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
if (unlikely(status == csum_none)) {
/* always for the old mac 10/100 */
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
netif_receive_skb(skb);
} else {
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1390,6 +1382,15 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
}
+ /* 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->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN))
+ priv->no_csum_insertion = 1;
+ else
+ priv->no_csum_insertion = 0;
+
dev->mtu = new_mtu;
return 0;
@@ -1405,11 +1406,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}
- if (priv->is_gmac) {
- unsigned long ioaddr = dev->base_addr;
+ if (priv->is_gmac)
/* To handle GMAC own interrupts */
- priv->hw->mac->host_irq_status(ioaddr);
- }
+ priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr);
stmmac_dma_interrupt(priv);
@@ -1512,9 +1511,6 @@ static int stmmac_probe(struct net_device *dev)
#endif
priv->msg_enable = netif_msg_init(debug, default_msg_level);
- if (priv->is_gmac)
- priv->rx_csum = 1;
-
if (flow_ctrl)
priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */
@@ -1522,7 +1518,8 @@ static int stmmac_probe(struct net_device *dev)
netif_napi_add(dev, &priv->napi, stmmac_poll, 64);
/* Get the MAC address */
- priv->hw->mac->get_umac_addr(dev->base_addr, dev->dev_addr, 0);
+ priv->hw->mac->get_umac_addr((void __iomem *) dev->base_addr,
+ dev->dev_addr, 0);
if (!is_valid_ether_addr(dev->dev_addr))
pr_warning("\tno valid MAC address;"
@@ -1552,14 +1549,13 @@ static int stmmac_probe(struct net_device *dev)
static int stmmac_mac_device_setup(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
struct mac_device_info *device;
if (priv->is_gmac)
- device = dwmac1000_setup(ioaddr);
+ device = dwmac1000_setup(priv->ioaddr);
else
- device = dwmac100_setup(ioaddr);
+ device = dwmac100_setup(priv->ioaddr);
if (!device)
return -ENOMEM;
@@ -1572,9 +1568,8 @@ static int stmmac_mac_device_setup(struct net_device *dev)
priv->hw = device;
- priv->wolenabled = priv->hw->pmt; /* PMT supported */
- if (priv->wolenabled == PMT_SUPPORTED)
- priv->wolopts = WAKE_MAGIC; /* Magic Frame */
+ if (device_can_wakeup(priv->device))
+ priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
return 0;
}
@@ -1653,7 +1648,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
{
int ret = 0;
struct resource *res;
- unsigned int *addr = NULL;
+ void __iomem *addr = NULL;
struct net_device *ndev = NULL;
struct stmmac_priv *priv;
struct plat_stmmacenet_data *plat_dat;
@@ -1664,7 +1659,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
ret = -ENODEV;
goto out;
}
- pr_info("done!\n");
+ pr_info("\tdone!\n");
if (!request_mem_region(res->start, resource_size(res),
pdev->name)) {
@@ -1706,8 +1701,18 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
plat_dat = pdev->dev.platform_data;
priv->bus_id = plat_dat->bus_id;
priv->pbl = plat_dat->pbl; /* TLI */
+ priv->mii_clk_csr = plat_dat->clk_csr;
+ priv->tx_coe = plat_dat->tx_coe;
+ priv->bugged_jumbo = plat_dat->bugged_jumbo;
priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */
priv->enh_desc = plat_dat->enh_desc;
+ priv->ioaddr = addr;
+
+ /* PMT module is not integrated in all the MAC devices. */
+ if (plat_dat->pmt) {
+ pr_info("\tPMT module supported\n");
+ device_set_wakeup_capable(&pdev->dev, 1);
+ }
platform_set_drvdata(pdev, ndev);
@@ -1743,8 +1748,8 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
priv->bsp_priv = plat_dat->bsp_priv;
pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
- "\tIO base addr: 0x%08x)\n", ndev->name, pdev->name,
- pdev->id, ndev->irq, (unsigned int)addr);
+ "\tIO base addr: 0x%p)\n", ndev->name, pdev->name,
+ pdev->id, ndev->irq, addr);
/* MDIO bus Registration */
pr_debug("\tMDIO bus (id: %d)...", priv->bus_id);
@@ -1779,11 +1784,11 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
pr_info("%s:\n\tremoving driver", __func__);
- priv->hw->dma->stop_rx(ndev->base_addr);
- priv->hw->dma->stop_tx(ndev->base_addr);
+ priv->hw->dma->stop_rx(priv->ioaddr);
+ priv->hw->dma->stop_tx(priv->ioaddr);
- stmmac_mac_disable_rx(ndev->base_addr);
- stmmac_mac_disable_tx(ndev->base_addr);
+ stmmac_mac_disable_rx(priv->ioaddr);
+ stmmac_mac_disable_tx(priv->ioaddr);
netif_carrier_off(ndev);
@@ -1792,7 +1797,7 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
unregister_netdev(ndev);
- iounmap((void *)ndev->base_addr);
+ iounmap((void *)priv->ioaddr);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, resource_size(res));
@@ -1827,23 +1832,20 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
napi_disable(&priv->napi);
/* Stop TX/RX DMA */
- priv->hw->dma->stop_tx(dev->base_addr);
- priv->hw->dma->stop_rx(dev->base_addr);
+ priv->hw->dma->stop_tx(priv->ioaddr);
+ priv->hw->dma->stop_rx(priv->ioaddr);
/* Clear the Rx/Tx descriptors */
priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
dis_ic);
priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
- stmmac_mac_disable_tx(dev->base_addr);
+ stmmac_mac_disable_tx(priv->ioaddr);
- if (device_may_wakeup(&(pdev->dev))) {
- /* Enable Power down mode by programming the PMT regs */
- if (priv->wolenabled == PMT_SUPPORTED)
- priv->hw->mac->pmt(dev->base_addr,
- priv->wolopts);
- } else {
- stmmac_mac_disable_rx(dev->base_addr);
- }
+ /* Enable Power down mode by programming the PMT regs */
+ if (device_can_wakeup(priv->device))
+ priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
+ else
+ stmmac_mac_disable_rx(priv->ioaddr);
} else {
priv->shutdown = 1;
/* Although this can appear slightly redundant it actually
@@ -1860,7 +1862,6 @@ static int stmmac_resume(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct stmmac_priv *priv = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
if (!netif_running(dev))
return 0;
@@ -1879,17 +1880,16 @@ static int stmmac_resume(struct platform_device *pdev)
* is received. Anyway, it's better to manually clear
* this bit because it can generate problems while resuming
* from another devices (e.g. serial console). */
- if (device_may_wakeup(&(pdev->dev)))
- if (priv->wolenabled == PMT_SUPPORTED)
- priv->hw->mac->pmt(dev->base_addr, 0);
+ if (device_can_wakeup(priv->device))
+ priv->hw->mac->pmt(priv->ioaddr, 0);
netif_device_attach(dev);
/* Enable the MAC and DMA */
- stmmac_mac_enable_rx(ioaddr);
- stmmac_mac_enable_tx(ioaddr);
- priv->hw->dma->start_tx(ioaddr);
- priv->hw->dma->start_rx(ioaddr);
+ stmmac_mac_enable_rx(priv->ioaddr);
+ stmmac_mac_enable_tx(priv->ioaddr);
+ priv->hw->dma->start_tx(priv->ioaddr);
+ priv->hw->dma->start_rx(priv->ioaddr);
#ifdef CONFIG_STMMAC_TIMER
priv->tm->timer_start(tmrate);
@@ -1968,8 +1968,6 @@ static int __init stmmac_cmdline_opt(char *str)
strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz);
else if (!strncmp(opt, "tc:", 3))
strict_strtoul(opt + 3, 0, (unsigned long *)&tc);
- else if (!strncmp(opt, "tx_coe:", 7))
- strict_strtoul(opt + 7, 0, (unsigned long *)&tx_coe);
else if (!strncmp(opt, "watchdog:", 9))
strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog);
else if (!strncmp(opt, "flow_ctrl:", 10))
diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c
index 40b2c7929719..d7441616357d 100644
--- a/drivers/net/stmmac/stmmac_mdio.c
+++ b/drivers/net/stmmac/stmmac_mdio.c
@@ -47,21 +47,20 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
- unsigned long ioaddr = ndev->base_addr;
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
int data;
u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
((phyreg << 6) & (0x000007C0)));
- regValue |= MII_BUSY; /* in case of GMAC */
+ regValue |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2);
- do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
- writel(regValue, ioaddr + mii_address);
- do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+ do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+ writel(regValue, priv->ioaddr + mii_address);
+ do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
/* Read the data from the MII data register */
- data = (int)readl(ioaddr + mii_data);
+ data = (int)readl(priv->ioaddr + mii_data);
return data;
}
@@ -79,7 +78,6 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
- unsigned long ioaddr = ndev->base_addr;
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
@@ -87,17 +85,18 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
(((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
| MII_WRITE;
- value |= MII_BUSY;
+ value |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2);
+
/* Wait until any existing MII operation is complete */
- do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+ do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
/* Set the MII address register to write */
- writel(phydata, ioaddr + mii_data);
- writel(value, ioaddr + mii_address);
+ writel(phydata, priv->ioaddr + mii_data);
+ writel(value, priv->ioaddr + mii_address);
/* Wait until any existing MII operation is complete */
- do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+ do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
return 0;
}
@@ -111,7 +110,6 @@ static int stmmac_mdio_reset(struct mii_bus *bus)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
- unsigned long ioaddr = ndev->base_addr;
unsigned int mii_address = priv->hw->mii.addr;
if (priv->phy_reset) {
@@ -123,7 +121,7 @@ static int stmmac_mdio_reset(struct mii_bus *bus)
* It doesn't complete its reset until at least one clock cycle
* on MDC, so perform a dummy mdio read.
*/
- writel(0, ioaddr + mii_address);
+ writel(0, priv->ioaddr + mii_address);
return 0;
}
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 358c22f9acbe..7d9ec23aabf6 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -436,7 +436,7 @@ static int lance_open( struct net_device *dev )
DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
dev->name, i, DREG ));
DREG = CSR0_STOP;
- return( -EIO );
+ return -EIO;
}
DREG = CSR0_IDON | CSR0_STRT | CSR0_INEA;
@@ -445,7 +445,7 @@ static int lance_open( struct net_device *dev )
DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
- return( 0 );
+ return 0;
}
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 618643e3ca3e..0a6a5ced3c1c 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -617,7 +617,7 @@ static void bigmac_begin_auto_negotiation(struct bigmac *bp)
bp->timer_ticks = 0;
bp->bigmac_timer.expires = jiffies + (12 * HZ) / 10;
bp->bigmac_timer.data = (unsigned long) bp;
- bp->bigmac_timer.function = &bigmac_timer;
+ bp->bigmac_timer.function = bigmac_timer;
add_timer(&bp->bigmac_timer);
}
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 2678588ea4b2..3ed2a67bd6d3 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -96,16 +96,10 @@ static char *media[MAX_UNITS];
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
-#ifndef _COMPAT_WITH_OLD_KERNEL
+#include <linux/dma-mapping.h>
#include <linux/crc32.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
-#else
-#include "crc32.h"
-#include "ethtool.h"
-#include "mii.h"
-#include "compat.h"
-#endif
/* These identify the driver base version and may not be removed. */
static const char version[] __devinitconst =
@@ -369,9 +363,21 @@ struct netdev_private {
dma_addr_t tx_ring_dma;
dma_addr_t rx_ring_dma;
struct timer_list timer; /* Media monitoring timer. */
+ /* ethtool extra stats */
+ struct {
+ u64 tx_multiple_collisions;
+ u64 tx_single_collisions;
+ u64 tx_late_collisions;
+ u64 tx_deferred;
+ u64 tx_deferred_excessive;
+ u64 tx_aborted;
+ u64 tx_bcasts;
+ u64 rx_bcasts;
+ u64 tx_mcasts;
+ u64 rx_mcasts;
+ } xstats;
/* Frequently used values: keep some adjacent for cache effect. */
spinlock_t lock;
- spinlock_t rx_lock; /* Group with Tx control cache line. */
int msg_enable;
int chip_id;
unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
@@ -396,6 +402,7 @@ struct netdev_private {
unsigned char phys[MII_CNT]; /* MII device addresses, only first one used. */
struct pci_dev *pci_dev;
void __iomem *base;
+ spinlock_t statlock;
};
/* The station address location in the EEPROM. */
@@ -520,16 +527,19 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
np->chip_id = chip_idx;
np->msg_enable = (1 << debug) - 1;
spin_lock_init(&np->lock);
+ spin_lock_init(&np->statlock);
tasklet_init(&np->rx_tasklet, rx_poll, (unsigned long)dev);
tasklet_init(&np->tx_tasklet, tx_poll, (unsigned long)dev);
- ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE,
+ &ring_dma, GFP_KERNEL);
if (!ring_space)
goto err_out_cleardev;
np->tx_ring = (struct netdev_desc *)ring_space;
np->tx_ring_dma = ring_dma;
- ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE,
+ &ring_dma, GFP_KERNEL);
if (!ring_space)
goto err_out_unmap_tx;
np->rx_ring = (struct netdev_desc *)ring_space;
@@ -663,9 +673,11 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
err_out_unregister:
unregister_netdev(dev);
err_out_unmap_rx:
- pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
+ dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE,
+ np->rx_ring, np->rx_ring_dma);
err_out_unmap_tx:
- pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
+ dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE,
+ np->tx_ring, np->tx_ring_dma);
err_out_cleardev:
pci_set_drvdata(pdev, NULL);
pci_iounmap(pdev, ioaddr);
@@ -874,7 +886,7 @@ static int netdev_open(struct net_device *dev)
init_timer(&np->timer);
np->timer.expires = jiffies + 3*HZ;
np->timer.data = (unsigned long)dev;
- np->timer.function = &netdev_timer; /* timer handler */
+ np->timer.function = netdev_timer; /* timer handler */
add_timer(&np->timer);
/* Enable interrupts by setting the interrupt mask. */
@@ -1011,8 +1023,14 @@ static void init_ring(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* 16 byte align the IP header. */
np->rx_ring[i].frag[0].addr = cpu_to_le32(
- pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz,
- PCI_DMA_FROMDEVICE));
+ dma_map_single(&np->pci_dev->dev, skb->data,
+ np->rx_buf_sz, DMA_FROM_DEVICE));
+ if (dma_mapping_error(&np->pci_dev->dev,
+ np->rx_ring[i].frag[0].addr)) {
+ dev_kfree_skb(skb);
+ np->rx_skbuff[i] = NULL;
+ break;
+ }
np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag);
}
np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -1063,9 +1081,11 @@ start_tx (struct sk_buff *skb, struct net_device *dev)
txdesc->next_desc = 0;
txdesc->status = cpu_to_le32 ((entry << 2) | DisableAlign);
- txdesc->frag[0].addr = cpu_to_le32 (pci_map_single (np->pci_dev, skb->data,
- skb->len,
- PCI_DMA_TODEVICE));
+ txdesc->frag[0].addr = cpu_to_le32(dma_map_single(&np->pci_dev->dev,
+ skb->data, skb->len, DMA_TO_DEVICE));
+ if (dma_mapping_error(&np->pci_dev->dev,
+ txdesc->frag[0].addr))
+ goto drop_frame;
txdesc->frag[0].length = cpu_to_le32 (skb->len | LastFrag);
/* Increment cur_tx before tasklet_schedule() */
@@ -1087,6 +1107,12 @@ start_tx (struct sk_buff *skb, struct net_device *dev)
dev->name, np->cur_tx, entry);
}
return NETDEV_TX_OK;
+
+drop_frame:
+ dev_kfree_skb(skb);
+ np->tx_skbuff[entry] = NULL;
+ dev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
}
/* Reset hardware tx and free all of tx buffers */
@@ -1097,7 +1123,6 @@ reset_tx (struct net_device *dev)
void __iomem *ioaddr = np->base;
struct sk_buff *skb;
int i;
- int irq = in_interrupt();
/* Reset tx logic, TxListPtr will be cleaned */
iowrite16 (TxDisable, ioaddr + MACCtrl1);
@@ -1109,13 +1134,10 @@ reset_tx (struct net_device *dev)
skb = np->tx_skbuff[i];
if (skb) {
- pci_unmap_single(np->pci_dev,
+ dma_unmap_single(&np->pci_dev->dev,
le32_to_cpu(np->tx_ring[i].frag[0].addr),
- skb->len, PCI_DMA_TODEVICE);
- if (irq)
- dev_kfree_skb_irq (skb);
- else
- dev_kfree_skb (skb);
+ skb->len, DMA_TO_DEVICE);
+ dev_kfree_skb_any(skb);
np->tx_skbuff[i] = NULL;
dev->stats.tx_dropped++;
}
@@ -1233,9 +1255,9 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
break;
skb = np->tx_skbuff[entry];
/* Free the original skb. */
- pci_unmap_single(np->pci_dev,
+ dma_unmap_single(&np->pci_dev->dev,
le32_to_cpu(np->tx_ring[entry].frag[0].addr),
- skb->len, PCI_DMA_TODEVICE);
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_irq (np->tx_skbuff[entry]);
np->tx_skbuff[entry] = NULL;
np->tx_ring[entry].frag[0].addr = 0;
@@ -1252,9 +1274,9 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
break;
skb = np->tx_skbuff[entry];
/* Free the original skb. */
- pci_unmap_single(np->pci_dev,
+ dma_unmap_single(&np->pci_dev->dev,
le32_to_cpu(np->tx_ring[entry].frag[0].addr),
- skb->len, PCI_DMA_TODEVICE);
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_irq (np->tx_skbuff[entry]);
np->tx_skbuff[entry] = NULL;
np->tx_ring[entry].frag[0].addr = 0;
@@ -1334,22 +1356,18 @@ static void rx_poll(unsigned long data)
if (pkt_len < rx_copybreak &&
(skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
skb_reserve(skb, 2); /* 16 byte align the IP header */
- pci_dma_sync_single_for_cpu(np->pci_dev,
- le32_to_cpu(desc->frag[0].addr),
- np->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
-
+ dma_sync_single_for_cpu(&np->pci_dev->dev,
+ le32_to_cpu(desc->frag[0].addr),
+ np->rx_buf_sz, DMA_FROM_DEVICE);
skb_copy_to_linear_data(skb, np->rx_skbuff[entry]->data, pkt_len);
- pci_dma_sync_single_for_device(np->pci_dev,
- le32_to_cpu(desc->frag[0].addr),
- np->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&np->pci_dev->dev,
+ le32_to_cpu(desc->frag[0].addr),
+ np->rx_buf_sz, DMA_FROM_DEVICE);
skb_put(skb, pkt_len);
} else {
- pci_unmap_single(np->pci_dev,
+ dma_unmap_single(&np->pci_dev->dev,
le32_to_cpu(desc->frag[0].addr),
- np->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ np->rx_buf_sz, DMA_FROM_DEVICE);
skb_put(skb = np->rx_skbuff[entry], pkt_len);
np->rx_skbuff[entry] = NULL;
}
@@ -1396,8 +1414,14 @@ static void refill_rx (struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
np->rx_ring[entry].frag[0].addr = cpu_to_le32(
- pci_map_single(np->pci_dev, skb->data,
- np->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ dma_map_single(&np->pci_dev->dev, skb->data,
+ np->rx_buf_sz, DMA_FROM_DEVICE));
+ if (dma_mapping_error(&np->pci_dev->dev,
+ np->rx_ring[entry].frag[0].addr)) {
+ dev_kfree_skb_irq(skb);
+ np->rx_skbuff[entry] = NULL;
+ break;
+ }
}
/* Perhaps we need not reset this field. */
np->rx_ring[entry].frag[0].length =
@@ -1475,27 +1499,41 @@ static struct net_device_stats *get_stats(struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base;
- int i;
+ unsigned long flags;
+ u8 late_coll, single_coll, mult_coll;
- /* We should lock this segment of code for SMP eventually, although
- the vulnerability window is very small and statistics are
- non-critical. */
+ spin_lock_irqsave(&np->statlock, flags);
/* The chip only need report frame silently dropped. */
dev->stats.rx_missed_errors += ioread8(ioaddr + RxMissed);
dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK);
dev->stats.rx_packets += ioread16(ioaddr + RxFramesOK);
- dev->stats.collisions += ioread8(ioaddr + StatsLateColl);
- dev->stats.collisions += ioread8(ioaddr + StatsMultiColl);
- dev->stats.collisions += ioread8(ioaddr + StatsOneColl);
dev->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError);
- ioread8(ioaddr + StatsTxDefer);
- for (i = StatsTxDefer; i <= StatsMcastRx; i++)
- ioread8(ioaddr + i);
+
+ mult_coll = ioread8(ioaddr + StatsMultiColl);
+ np->xstats.tx_multiple_collisions += mult_coll;
+ single_coll = ioread8(ioaddr + StatsOneColl);
+ np->xstats.tx_single_collisions += single_coll;
+ late_coll = ioread8(ioaddr + StatsLateColl);
+ np->xstats.tx_late_collisions += late_coll;
+ dev->stats.collisions += mult_coll
+ + single_coll
+ + late_coll;
+
+ np->xstats.tx_deferred += ioread8(ioaddr + StatsTxDefer);
+ np->xstats.tx_deferred_excessive += ioread8(ioaddr + StatsTxXSDefer);
+ np->xstats.tx_aborted += ioread8(ioaddr + StatsTxAbort);
+ np->xstats.tx_bcasts += ioread8(ioaddr + StatsBcastTx);
+ np->xstats.rx_bcasts += ioread8(ioaddr + StatsBcastRx);
+ np->xstats.tx_mcasts += ioread8(ioaddr + StatsMcastTx);
+ np->xstats.rx_mcasts += ioread8(ioaddr + StatsMcastRx);
+
dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow);
dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16;
dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow);
dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16;
+ spin_unlock_irqrestore(&np->statlock, flags);
+
return &dev->stats;
}
@@ -1554,6 +1592,21 @@ static int __set_mac_addr(struct net_device *dev)
return 0;
}
+static const struct {
+ const char name[ETH_GSTRING_LEN];
+} sundance_stats[] = {
+ { "tx_multiple_collisions" },
+ { "tx_single_collisions" },
+ { "tx_late_collisions" },
+ { "tx_deferred" },
+ { "tx_deferred_excessive" },
+ { "tx_aborted" },
+ { "tx_bcasts" },
+ { "rx_bcasts" },
+ { "tx_mcasts" },
+ { "rx_mcasts" },
+};
+
static int check_if_running(struct net_device *dev)
{
if (!netif_running(dev))
@@ -1612,6 +1665,42 @@ static void set_msglevel(struct net_device *dev, u32 val)
np->msg_enable = val;
}
+static void get_strings(struct net_device *dev, u32 stringset,
+ u8 *data)
+{
+ if (stringset == ETH_SS_STATS)
+ memcpy(data, sundance_stats, sizeof(sundance_stats));
+}
+
+static int get_sset_count(struct net_device *dev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return ARRAY_SIZE(sundance_stats);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct netdev_private *np = netdev_priv(dev);
+ int i = 0;
+
+ get_stats(dev);
+ data[i++] = np->xstats.tx_multiple_collisions;
+ data[i++] = np->xstats.tx_single_collisions;
+ data[i++] = np->xstats.tx_late_collisions;
+ data[i++] = np->xstats.tx_deferred;
+ data[i++] = np->xstats.tx_deferred_excessive;
+ data[i++] = np->xstats.tx_aborted;
+ data[i++] = np->xstats.tx_bcasts;
+ data[i++] = np->xstats.rx_bcasts;
+ data[i++] = np->xstats.tx_mcasts;
+ data[i++] = np->xstats.rx_mcasts;
+}
+
static const struct ethtool_ops ethtool_ops = {
.begin = check_if_running,
.get_drvinfo = get_drvinfo,
@@ -1621,6 +1710,9 @@ static const struct ethtool_ops ethtool_ops = {
.get_link = get_link,
.get_msglevel = get_msglevel,
.set_msglevel = set_msglevel,
+ .get_strings = get_strings,
+ .get_sset_count = get_sset_count,
+ .get_ethtool_stats = get_ethtool_stats,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -1715,9 +1807,9 @@ static int netdev_close(struct net_device *dev)
np->rx_ring[i].status = 0;
skb = np->rx_skbuff[i];
if (skb) {
- pci_unmap_single(np->pci_dev,
+ dma_unmap_single(&np->pci_dev->dev,
le32_to_cpu(np->rx_ring[i].frag[0].addr),
- np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ np->rx_buf_sz, DMA_FROM_DEVICE);
dev_kfree_skb(skb);
np->rx_skbuff[i] = NULL;
}
@@ -1727,9 +1819,9 @@ static int netdev_close(struct net_device *dev)
np->tx_ring[i].next_desc = 0;
skb = np->tx_skbuff[i];
if (skb) {
- pci_unmap_single(np->pci_dev,
+ dma_unmap_single(&np->pci_dev->dev,
le32_to_cpu(np->tx_ring[i].frag[0].addr),
- skb->len, PCI_DMA_TODEVICE);
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb(skb);
np->tx_skbuff[i] = NULL;
}
@@ -1743,25 +1835,72 @@ static void __devexit sundance_remove1 (struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
if (dev) {
- struct netdev_private *np = netdev_priv(dev);
-
- unregister_netdev(dev);
- pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring,
- np->rx_ring_dma);
- pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring,
- np->tx_ring_dma);
- pci_iounmap(pdev, np->base);
- pci_release_regions(pdev);
- free_netdev(dev);
- pci_set_drvdata(pdev, NULL);
+ struct netdev_private *np = netdev_priv(dev);
+ unregister_netdev(dev);
+ dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE,
+ np->rx_ring, np->rx_ring_dma);
+ dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE,
+ np->tx_ring, np->tx_ring_dma);
+ pci_iounmap(pdev, np->base);
+ pci_release_regions(pdev);
+ free_netdev(dev);
+ pci_set_drvdata(pdev, NULL);
+ }
+}
+
+#ifdef CONFIG_PM
+
+static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pci_dev);
+
+ if (!netif_running(dev))
+ return 0;
+
+ netdev_close(dev);
+ netif_device_detach(dev);
+
+ pci_save_state(pci_dev);
+ pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
+
+ return 0;
+}
+
+static int sundance_resume(struct pci_dev *pci_dev)
+{
+ struct net_device *dev = pci_get_drvdata(pci_dev);
+ int err = 0;
+
+ if (!netif_running(dev))
+ return 0;
+
+ pci_set_power_state(pci_dev, PCI_D0);
+ pci_restore_state(pci_dev);
+
+ err = netdev_open(dev);
+ if (err) {
+ printk(KERN_ERR "%s: Can't resume interface!\n",
+ dev->name);
+ goto out;
}
+
+ netif_device_attach(dev);
+
+out:
+ return err;
}
+#endif /* CONFIG_PM */
+
static struct pci_driver sundance_driver = {
.name = DRV_NAME,
.id_table = sundance_pci_tbl,
.probe = sundance_probe1,
.remove = __devexit_p(sundance_remove1),
+#ifdef CONFIG_PM
+ .suspend = sundance_suspend,
+ .resume = sundance_resume,
+#endif /* CONFIG_PM */
};
static int __init sundance_init(void)
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 434f9d735333..4ceb3cf6a9a9 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -31,6 +31,8 @@
* about when we can start taking interrupts or get xmit() called...
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -105,7 +107,6 @@ MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver");
MODULE_LICENSE("GPL");
#define GEM_MODULE_NAME "gem"
-#define PFX GEM_MODULE_NAME ": "
static DEFINE_PCI_DEVICE_TABLE(gem_pci_tbl) = {
{ PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_GEM,
@@ -262,8 +263,7 @@ static int gem_pcs_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
gp->dev->name, pcs_istat);
if (!(pcs_istat & PCS_ISTAT_LSC)) {
- printk(KERN_ERR "%s: PCS irq but no link status change???\n",
- dev->name);
+ netdev_err(dev, "PCS irq but no link status change???\n");
return 0;
}
@@ -282,20 +282,16 @@ static int gem_pcs_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
* when autoneg has completed.
*/
if (pcs_miistat & PCS_MIISTAT_RF)
- printk(KERN_INFO "%s: PCS AutoNEG complete, "
- "RemoteFault\n", dev->name);
+ netdev_info(dev, "PCS AutoNEG complete, RemoteFault\n");
else
- printk(KERN_INFO "%s: PCS AutoNEG complete.\n",
- dev->name);
+ netdev_info(dev, "PCS AutoNEG complete\n");
}
if (pcs_miistat & PCS_MIISTAT_LS) {
- printk(KERN_INFO "%s: PCS link is now up.\n",
- dev->name);
+ netdev_info(dev, "PCS link is now up\n");
netif_carrier_on(gp->dev);
} else {
- printk(KERN_INFO "%s: PCS link is now down.\n",
- dev->name);
+ netdev_info(dev, "PCS link is now down\n");
netif_carrier_off(gp->dev);
/* If this happens and the link timer is not running,
* reset so we re-negotiate.
@@ -323,14 +319,12 @@ static int gem_txmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s
return 0;
if (txmac_stat & MAC_TXSTAT_URUN) {
- printk(KERN_ERR "%s: TX MAC xmit underrun.\n",
- dev->name);
+ netdev_err(dev, "TX MAC xmit underrun\n");
gp->net_stats.tx_fifo_errors++;
}
if (txmac_stat & MAC_TXSTAT_MPE) {
- printk(KERN_ERR "%s: TX MAC max packet size error.\n",
- dev->name);
+ netdev_err(dev, "TX MAC max packet size error\n");
gp->net_stats.tx_errors++;
}
@@ -377,8 +371,7 @@ static int gem_rxmac_reset(struct gem *gp)
udelay(10);
}
if (limit == 5000) {
- printk(KERN_ERR "%s: RX MAC will not reset, resetting whole "
- "chip.\n", dev->name);
+ netdev_err(dev, "RX MAC will not reset, resetting whole chip\n");
return 1;
}
@@ -390,8 +383,7 @@ static int gem_rxmac_reset(struct gem *gp)
udelay(10);
}
if (limit == 5000) {
- printk(KERN_ERR "%s: RX MAC will not disable, resetting whole "
- "chip.\n", dev->name);
+ netdev_err(dev, "RX MAC will not disable, resetting whole chip\n");
return 1;
}
@@ -403,8 +395,7 @@ static int gem_rxmac_reset(struct gem *gp)
udelay(10);
}
if (limit == 5000) {
- printk(KERN_ERR "%s: RX DMA will not disable, resetting whole "
- "chip.\n", dev->name);
+ netdev_err(dev, "RX DMA will not disable, resetting whole chip\n");
return 1;
}
@@ -419,8 +410,7 @@ static int gem_rxmac_reset(struct gem *gp)
udelay(10);
}
if (limit == 5000) {
- printk(KERN_ERR "%s: RX reset command will not execute, resetting "
- "whole chip.\n", dev->name);
+ netdev_err(dev, "RX reset command will not execute, resetting whole chip\n");
return 1;
}
@@ -429,8 +419,7 @@ static int gem_rxmac_reset(struct gem *gp)
struct gem_rxd *rxd = &gp->init_block->rxd[i];
if (gp->rx_skbs[i] == NULL) {
- printk(KERN_ERR "%s: Parts of RX ring empty, resetting "
- "whole chip.\n", dev->name);
+ netdev_err(dev, "Parts of RX ring empty, resetting whole chip\n");
return 1;
}
@@ -479,8 +468,7 @@ static int gem_rxmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s
if (rxmac_stat & MAC_RXSTAT_OFLW) {
u32 smac = readl(gp->regs + MAC_SMACHINE);
- printk(KERN_ERR "%s: RX MAC fifo overflow smac[%08x].\n",
- dev->name, smac);
+ netdev_err(dev, "RX MAC fifo overflow smac[%08x]\n", smac);
gp->net_stats.rx_over_errors++;
gp->net_stats.rx_fifo_errors++;
@@ -542,19 +530,18 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
if (gp->pdev->vendor == PCI_VENDOR_ID_SUN &&
gp->pdev->device == PCI_DEVICE_ID_SUN_GEM) {
- printk(KERN_ERR "%s: PCI error [%04x] ",
- dev->name, pci_estat);
+ netdev_err(dev, "PCI error [%04x]", pci_estat);
if (pci_estat & GREG_PCIESTAT_BADACK)
- printk("<No ACK64# during ABS64 cycle> ");
+ pr_cont(" <No ACK64# during ABS64 cycle>");
if (pci_estat & GREG_PCIESTAT_DTRTO)
- printk("<Delayed transaction timeout> ");
+ pr_cont(" <Delayed transaction timeout>");
if (pci_estat & GREG_PCIESTAT_OTHER)
- printk("<other>");
- printk("\n");
+ pr_cont(" <other>");
+ pr_cont("\n");
} else {
pci_estat |= GREG_PCIESTAT_OTHER;
- printk(KERN_ERR "%s: PCI error\n", dev->name);
+ netdev_err(dev, "PCI error\n");
}
if (pci_estat & GREG_PCIESTAT_OTHER) {
@@ -565,26 +552,20 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
*/
pci_read_config_word(gp->pdev, PCI_STATUS,
&pci_cfg_stat);
- printk(KERN_ERR "%s: Read PCI cfg space status [%04x]\n",
- dev->name, pci_cfg_stat);
+ netdev_err(dev, "Read PCI cfg space status [%04x]\n",
+ pci_cfg_stat);
if (pci_cfg_stat & PCI_STATUS_PARITY)
- printk(KERN_ERR "%s: PCI parity error detected.\n",
- dev->name);
+ netdev_err(dev, "PCI parity error detected\n");
if (pci_cfg_stat & PCI_STATUS_SIG_TARGET_ABORT)
- printk(KERN_ERR "%s: PCI target abort.\n",
- dev->name);
+ netdev_err(dev, "PCI target abort\n");
if (pci_cfg_stat & PCI_STATUS_REC_TARGET_ABORT)
- printk(KERN_ERR "%s: PCI master acks target abort.\n",
- dev->name);
+ netdev_err(dev, "PCI master acks target abort\n");
if (pci_cfg_stat & PCI_STATUS_REC_MASTER_ABORT)
- printk(KERN_ERR "%s: PCI master abort.\n",
- dev->name);
+ netdev_err(dev, "PCI master abort\n");
if (pci_cfg_stat & PCI_STATUS_SIG_SYSTEM_ERROR)
- printk(KERN_ERR "%s: PCI system error SERR#.\n",
- dev->name);
+ netdev_err(dev, "PCI system error SERR#\n");
if (pci_cfg_stat & PCI_STATUS_DETECTED_PARITY)
- printk(KERN_ERR "%s: PCI parity error.\n",
- dev->name);
+ netdev_err(dev, "PCI parity error\n");
/* Write the error bits back to clear them. */
pci_cfg_stat &= (PCI_STATUS_PARITY |
@@ -874,8 +855,7 @@ static int gem_rx(struct gem *gp, int work_to_do)
gp->rx_new = entry;
if (drops)
- printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
- gp->dev->name);
+ netdev_info(gp->dev, "Memory squeeze, deferring packet\n");
return work_done;
}
@@ -981,21 +961,19 @@ static void gem_tx_timeout(struct net_device *dev)
{
struct gem *gp = netdev_priv(dev);
- printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
+ netdev_err(dev, "transmit timed out, resetting\n");
if (!gp->running) {
- printk("%s: hrm.. hw not running !\n", dev->name);
+ netdev_err(dev, "hrm.. hw not running !\n");
return;
}
- printk(KERN_ERR "%s: TX_STATE[%08x:%08x:%08x]\n",
- dev->name,
- readl(gp->regs + TXDMA_CFG),
- readl(gp->regs + MAC_TXSTAT),
- readl(gp->regs + MAC_TXCFG));
- printk(KERN_ERR "%s: RX_STATE[%08x:%08x:%08x]\n",
- dev->name,
- readl(gp->regs + RXDMA_CFG),
- readl(gp->regs + MAC_RXSTAT),
- readl(gp->regs + MAC_RXCFG));
+ netdev_err(dev, "TX_STATE[%08x:%08x:%08x]\n",
+ readl(gp->regs + TXDMA_CFG),
+ readl(gp->regs + MAC_TXSTAT),
+ readl(gp->regs + MAC_TXCFG));
+ netdev_err(dev, "RX_STATE[%08x:%08x:%08x]\n",
+ readl(gp->regs + RXDMA_CFG),
+ readl(gp->regs + MAC_RXSTAT),
+ readl(gp->regs + MAC_RXCFG));
spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
@@ -1048,8 +1026,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb,
if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) {
netif_stop_queue(dev);
spin_unlock_irqrestore(&gp->tx_lock, flags);
- printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
- dev->name);
+ netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
return NETDEV_TX_BUSY;
}
@@ -1158,8 +1135,7 @@ static void gem_pcs_reset(struct gem *gp)
break;
}
if (limit < 0)
- printk(KERN_WARNING "%s: PCS reset bit would not clear.\n",
- gp->dev->name);
+ netdev_warn(gp->dev, "PCS reset bit would not clear\n");
}
static void gem_pcs_reinit_adv(struct gem *gp)
@@ -1230,7 +1206,7 @@ static void gem_reset(struct gem *gp)
} while (val & (GREG_SWRST_TXRST | GREG_SWRST_RXRST));
if (limit < 0)
- printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name);
+ netdev_err(gp->dev, "SW reset is ghetto\n");
if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes)
gem_pcs_reinit_adv(gp);
@@ -1395,9 +1371,8 @@ static int gem_set_link_modes(struct gem *gp)
speed = SPEED_1000;
}
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: Link is up at %d Mbps, %s-duplex.\n",
- gp->dev->name, speed, (full_duplex ? "full" : "half"));
+ netif_info(gp, link, gp->dev, "Link is up at %d Mbps, %s-duplex\n",
+ speed, (full_duplex ? "full" : "half"));
if (!gp->running)
return 0;
@@ -1451,15 +1426,13 @@ static int gem_set_link_modes(struct gem *gp)
if (netif_msg_link(gp)) {
if (pause) {
- printk(KERN_INFO "%s: Pause is enabled "
- "(rxfifo: %d off: %d on: %d)\n",
- gp->dev->name,
- gp->rx_fifo_sz,
- gp->rx_pause_off,
- gp->rx_pause_on);
+ netdev_info(gp->dev,
+ "Pause is enabled (rxfifo: %d off: %d on: %d)\n",
+ gp->rx_fifo_sz,
+ gp->rx_pause_off,
+ gp->rx_pause_on);
} else {
- printk(KERN_INFO "%s: Pause is disabled\n",
- gp->dev->name);
+ netdev_info(gp->dev, "Pause is disabled\n");
}
}
@@ -1484,9 +1457,8 @@ static int gem_mdio_link_not_up(struct gem *gp)
{
switch (gp->lstate) {
case link_force_ret:
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: Autoneg failed again, keeping"
- " forced mode\n", gp->dev->name);
+ netif_info(gp, link, gp->dev,
+ "Autoneg failed again, keeping forced mode\n");
gp->phy_mii.def->ops->setup_forced(&gp->phy_mii,
gp->last_forced_speed, DUPLEX_HALF);
gp->timer_ticks = 5;
@@ -1499,9 +1471,7 @@ static int gem_mdio_link_not_up(struct gem *gp)
*/
if (gp->phy_mii.def->magic_aneg)
return 1;
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: switching to forced 100bt\n",
- gp->dev->name);
+ netif_info(gp, link, gp->dev, "switching to forced 100bt\n");
/* Try forced modes. */
gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_100,
DUPLEX_HALF);
@@ -1517,9 +1487,8 @@ static int gem_mdio_link_not_up(struct gem *gp)
gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_10,
DUPLEX_HALF);
gp->timer_ticks = 5;
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: switching to forced 10bt\n",
- gp->dev->name);
+ netif_info(gp, link, gp->dev,
+ "switching to forced 10bt\n");
return 0;
} else
return 1;
@@ -1574,8 +1543,8 @@ static void gem_link_timer(unsigned long data)
gp->last_forced_speed = gp->phy_mii.speed;
gp->timer_ticks = 5;
if (netif_msg_link(gp))
- printk(KERN_INFO "%s: Got link after fallback, retrying"
- " autoneg once...\n", gp->dev->name);
+ netdev_info(gp->dev,
+ "Got link after fallback, retrying autoneg once...\n");
gp->phy_mii.def->ops->setup_aneg(&gp->phy_mii, gp->phy_mii.advertising);
} else if (gp->lstate != link_up) {
gp->lstate = link_up;
@@ -1589,9 +1558,7 @@ static void gem_link_timer(unsigned long data)
*/
if (gp->lstate == link_up) {
gp->lstate = link_down;
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: Link down\n",
- gp->dev->name);
+ netif_info(gp, link, gp->dev, "Link down\n");
netif_carrier_off(gp->dev);
gp->reset_task_pending = 1;
schedule_work(&gp->reset_task);
@@ -1746,8 +1713,7 @@ static void gem_init_phy(struct gem *gp)
if (phy_read(gp, MII_BMCR) != 0xffff)
break;
if (i == 2)
- printk(KERN_WARNING "%s: GMAC PHY not responding !\n",
- gp->dev->name);
+ netdev_warn(gp->dev, "GMAC PHY not responding !\n");
}
}
@@ -2038,7 +2004,7 @@ static int gem_check_invariants(struct gem *gp)
* as this chip has no gigabit PHY.
*/
if ((mif_cfg & (MIF_CFG_MDI0 | MIF_CFG_MDI1)) == 0) {
- printk(KERN_ERR PFX "RIO GEM lacks MII phy, mif_cfg[%08x]\n",
+ pr_err("RIO GEM lacks MII phy, mif_cfg[%08x]\n",
mif_cfg);
return -1;
}
@@ -2078,7 +2044,7 @@ static int gem_check_invariants(struct gem *gp)
}
if (i == 32) {
if (pdev->device != PCI_DEVICE_ID_SUN_GEM) {
- printk(KERN_ERR PFX "RIO MII phy will not respond.\n");
+ pr_err("RIO MII phy will not respond\n");
return -1;
}
gp->phy_type = phy_serdes;
@@ -2093,7 +2059,7 @@ static int gem_check_invariants(struct gem *gp)
if (pdev->device == PCI_DEVICE_ID_SUN_GEM) {
if (gp->tx_fifo_sz != (9 * 1024) ||
gp->rx_fifo_sz != (20 * 1024)) {
- printk(KERN_ERR PFX "GEM has bogus fifo sizes tx(%d) rx(%d)\n",
+ pr_err("GEM has bogus fifo sizes tx(%d) rx(%d)\n",
gp->tx_fifo_sz, gp->rx_fifo_sz);
return -1;
}
@@ -2101,7 +2067,7 @@ static int gem_check_invariants(struct gem *gp)
} else {
if (gp->tx_fifo_sz != (2 * 1024) ||
gp->rx_fifo_sz != (2 * 1024)) {
- printk(KERN_ERR PFX "RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n",
+ pr_err("RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n",
gp->tx_fifo_sz, gp->rx_fifo_sz);
return -1;
}
@@ -2239,7 +2205,7 @@ static int gem_do_start(struct net_device *dev)
if (request_irq(gp->pdev->irq, gem_interrupt,
IRQF_SHARED, dev->name, (void *)dev)) {
- printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
+ netdev_err(dev, "failed to request irq !\n");
spin_lock_irqsave(&gp->lock, flags);
spin_lock(&gp->tx_lock);
@@ -2378,9 +2344,8 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
mutex_lock(&gp->pm_mutex);
- printk(KERN_INFO "%s: suspending, WakeOnLan %s\n",
- dev->name,
- (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
+ netdev_info(dev, "suspending, WakeOnLan %s\n",
+ (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
/* Keep the cell enabled during the entire operation */
spin_lock_irqsave(&gp->lock, flags);
@@ -2440,7 +2405,7 @@ static int gem_resume(struct pci_dev *pdev)
struct gem *gp = netdev_priv(dev);
unsigned long flags;
- printk(KERN_INFO "%s: resuming\n", dev->name);
+ netdev_info(dev, "resuming\n");
mutex_lock(&gp->pm_mutex);
@@ -2452,8 +2417,7 @@ static int gem_resume(struct pci_dev *pdev)
/* Make sure PCI access and bus master are enabled */
if (pci_enable_device(gp->pdev)) {
- printk(KERN_ERR "%s: Can't re-enable chip !\n",
- dev->name);
+ netdev_err(dev, "Can't re-enable chip !\n");
/* Put cell and forget it for now, it will be considered as
* still asleep, a new sleep cycle may bring it back
*/
@@ -2938,7 +2902,7 @@ static int __devinit gem_get_device_address(struct gem *gp)
addr = idprom->id_ethaddr;
#else
printk("\n");
- printk(KERN_ERR "%s: can't get mac-address\n", dev->name);
+ pr_err("%s: can't get mac-address\n", dev->name);
return -1;
#endif
}
@@ -3009,14 +2973,12 @@ static const struct net_device_ops gem_netdev_ops = {
static int __devinit gem_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- static int gem_version_printed = 0;
unsigned long gemreg_base, gemreg_len;
struct net_device *dev;
struct gem *gp;
int err, pci_using_dac;
- if (gem_version_printed++ == 0)
- printk(KERN_INFO "%s", version);
+ printk_once(KERN_INFO "%s", version);
/* Apple gmac note: during probe, the chip is powered up by
* the arch code to allow the code below to work (and to let
@@ -3026,8 +2988,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
*/
err = pci_enable_device(pdev);
if (err) {
- printk(KERN_ERR PFX "Cannot enable MMIO operation, "
- "aborting.\n");
+ pr_err("Cannot enable MMIO operation, aborting\n");
return err;
}
pci_set_master(pdev);
@@ -3048,8 +3009,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
} else {
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
- printk(KERN_ERR PFX "No usable DMA configuration, "
- "aborting.\n");
+ pr_err("No usable DMA configuration, aborting\n");
goto err_disable_device;
}
pci_using_dac = 0;
@@ -3059,15 +3019,14 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
gemreg_len = pci_resource_len(pdev, 0);
if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
- printk(KERN_ERR PFX "Cannot find proper PCI device "
- "base address, aborting.\n");
+ pr_err("Cannot find proper PCI device base address, aborting\n");
err = -ENODEV;
goto err_disable_device;
}
dev = alloc_etherdev(sizeof(*gp));
if (!dev) {
- printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
+ pr_err("Etherdev alloc failed, aborting\n");
err = -ENOMEM;
goto err_disable_device;
}
@@ -3077,8 +3036,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
- printk(KERN_ERR PFX "Cannot obtain PCI resources, "
- "aborting.\n");
+ pr_err("Cannot obtain PCI resources, aborting\n");
goto err_out_free_netdev;
}
@@ -3104,8 +3062,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
gp->regs = ioremap(gemreg_base, gemreg_len);
if (!gp->regs) {
- printk(KERN_ERR PFX "Cannot map device registers, "
- "aborting.\n");
+ pr_err("Cannot map device registers, aborting\n");
err = -EIO;
goto err_out_free_res;
}
@@ -3150,8 +3107,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
pci_alloc_consistent(pdev, sizeof(struct gem_init_block),
&gp->gblock_dvma);
if (!gp->init_block) {
- printk(KERN_ERR PFX "Cannot allocate init block, "
- "aborting.\n");
+ pr_err("Cannot allocate init block, aborting\n");
err = -ENOMEM;
goto err_out_iounmap;
}
@@ -3180,19 +3136,18 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
/* Register with kernel */
if (register_netdev(dev)) {
- printk(KERN_ERR PFX "Cannot register net device, "
- "aborting.\n");
+ pr_err("Cannot register net device, aborting\n");
err = -ENOMEM;
goto err_out_free_consistent;
}
- printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n",
- dev->name, dev->dev_addr);
+ netdev_info(dev, "Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n",
+ dev->dev_addr);
if (gp->phy_type == phy_mii_mdio0 ||
gp->phy_type == phy_mii_mdio1)
- printk(KERN_INFO "%s: Found %s PHY\n", dev->name,
- gp->phy_mii.def ? gp->phy_mii.def->name : "no");
+ netdev_info(dev, "Found %s PHY\n",
+ 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;
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 78f8cee5fd74..d16880d7099b 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -88,7 +88,7 @@ static int reset_one_mii_phy(struct mii_phy* phy, int phy_id)
if ((val & BMCR_ISOLATE) && limit > 0)
__phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE);
- return (limit <= 0);
+ return limit <= 0;
}
static int bcm5201_init(struct mii_phy* phy)
@@ -1175,7 +1175,8 @@ int mii_phy_probe(struct mii_phy *phy, int mii_id)
/* Read ID and find matching entry */
id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2));
- printk(KERN_DEBUG "PHY ID: %x, addr: %x\n", id, mii_id);
+ printk(KERN_DEBUG KBUILD_MODNAME ": " "PHY ID: %x, addr: %x\n",
+ id, mii_id);
for (i=0; (def = mii_phy_table[i]) != NULL; i++)
if ((id & def->phy_id_mask) == def->phy_id)
break;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index bd0df1c14955..5e28c414421a 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -1409,7 +1409,7 @@ force_link:
hp->timer_ticks = 0;
hp->happy_timer.expires = jiffies + (12 * HZ)/10; /* 1.2 sec. */
hp->happy_timer.data = (unsigned long) hp;
- hp->happy_timer.function = &happy_meal_timer;
+ hp->happy_timer.function = happy_meal_timer;
add_timer(&hp->happy_timer);
}
@@ -2497,7 +2497,7 @@ static u32 hme_get_link(struct net_device *dev)
hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR);
spin_unlock_irq(&hp->happy_lock);
- return (hp->sw_bmsr & BMSR_LSTATUS);
+ return hp->sw_bmsr & BMSR_LSTATUS;
}
static const struct ethtool_ops hme_ethtool_ops = {
@@ -2808,7 +2808,8 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i
happy_meal_set_initial_advertisement(hp);
spin_unlock_irq(&hp->happy_lock);
- if (register_netdev(hp->dev)) {
+ err = register_netdev(hp->dev);
+ if (err) {
printk(KERN_ERR "happymeal: Cannot register net device, "
"aborting.\n");
goto err_out_free_coherent;
@@ -3130,7 +3131,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
happy_meal_set_initial_advertisement(hp);
spin_unlock_irq(&hp->happy_lock);
- if (register_netdev(hp->dev)) {
+ err = register_netdev(hp->dev);
+ if (err) {
printk(KERN_ERR "happymeal(PCI): Cannot register net device, "
"aborting.\n");
goto err_out_iounmap;
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 8dcb858f2168..2cf84e5968b2 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -1483,7 +1483,7 @@ no_link_test:
*/
init_timer(&lp->multicast_timer);
lp->multicast_timer.data = (unsigned long) dev;
- lp->multicast_timer.function = &lance_set_multicast_retry;
+ lp->multicast_timer.function = lance_set_multicast_retry;
if (register_netdev(dev)) {
printk(KERN_ERR "SunLance: Cannot register device.\n");
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index 72e65d4666ef..9536b2f010be 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -711,7 +711,7 @@ static u32 qe_get_link(struct net_device *dev)
phyconfig = sbus_readb(mregs + MREGS_PHYCONFIG);
spin_unlock_irq(&qep->lock);
- return (phyconfig & MREGS_PHYCONFIG_LSTAT);
+ return phyconfig & MREGS_PHYCONFIG_LSTAT;
}
static const struct ethtool_ops qe_ethtool_ops = {
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c
index d281a7b34701..bf3c762de620 100644
--- a/drivers/net/sunvnet.c
+++ b/drivers/net/sunvnet.c
@@ -3,6 +3,8 @@
* Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -20,7 +22,6 @@
#include "sunvnet.h"
#define DRV_MODULE_NAME "sunvnet"
-#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.0"
#define DRV_MODULE_RELDATE "June 25, 2007"
@@ -45,9 +46,9 @@ static int vnet_handle_unknown(struct vnet_port *port, void *arg)
{
struct vio_msg_tag *pkt = arg;
- printk(KERN_ERR PFX "Received unknown msg [%02x:%02x:%04x:%08x]\n",
+ pr_err("Received unknown msg [%02x:%02x:%04x:%08x]\n",
pkt->type, pkt->stype, pkt->stype_env, pkt->sid);
- printk(KERN_ERR PFX "Resetting connection.\n");
+ pr_err("Resetting connection\n");
ldc_disconnect(port->vio.lp);
@@ -400,8 +401,8 @@ static int vnet_rx(struct vnet_port *port, void *msgbuf)
if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA))
return 0;
if (unlikely(pkt->seq != dr->rcv_nxt)) {
- printk(KERN_ERR PFX "RX out of sequence seq[0x%llx] "
- "rcv_nxt[0x%llx]\n", pkt->seq, dr->rcv_nxt);
+ pr_err("RX out of sequence seq[0x%llx] rcv_nxt[0x%llx]\n",
+ pkt->seq, dr->rcv_nxt);
return 0;
}
@@ -464,8 +465,7 @@ static int handle_mcast(struct vnet_port *port, void *msgbuf)
struct vio_net_mcast_info *pkt = msgbuf;
if (pkt->tag.stype != VIO_SUBTYPE_ACK)
- printk(KERN_ERR PFX "%s: Got unexpected MCAST reply "
- "[%02x:%02x:%04x:%08x]\n",
+ pr_err("%s: Got unexpected MCAST reply [%02x:%02x:%04x:%08x]\n",
port->vp->dev->name,
pkt->tag.type,
pkt->tag.stype,
@@ -520,7 +520,7 @@ static void vnet_event(void *arg, int event)
}
if (unlikely(event != LDC_EVENT_DATA_READY)) {
- printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event);
+ pr_warning("Unexpected LDC event %d\n", event);
spin_unlock_irqrestore(&vio->lock, flags);
return;
}
@@ -662,8 +662,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
/* This is a hard error, log it. */
- printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
- "queue awake!\n", dev->name);
+ netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
dev->stats.tx_errors++;
}
spin_unlock_irqrestore(&port->vio.lock, flags);
@@ -696,8 +695,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
err = __vnet_tx_trigger(port);
if (unlikely(err < 0)) {
- printk(KERN_INFO PFX "%s: TX trigger error %d\n",
- dev->name, err);
+ netdev_info(dev, "TX trigger error %d\n", err);
d->hdr.state = VIO_DESC_FREE;
dev->stats.tx_carrier_errors++;
goto out_dropped_unlock;
@@ -952,12 +950,12 @@ static int __devinit vnet_port_alloc_tx_bufs(struct vnet_port *port)
err = -ENOMEM;
if (!buf) {
- printk(KERN_ERR "TX buffer allocation failure\n");
+ pr_err("TX buffer allocation failure\n");
goto err_out;
}
err = -EFAULT;
if ((unsigned long)buf & (8UL - 1)) {
- printk(KERN_ERR "TX buffer misaligned\n");
+ pr_err("TX buffer misaligned\n");
kfree(buf);
goto err_out;
}
@@ -1030,7 +1028,7 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac)
dev = alloc_etherdev(sizeof(*vp));
if (!dev) {
- printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
+ pr_err("Etherdev alloc failed, aborting\n");
return ERR_PTR(-ENOMEM);
}
@@ -1056,12 +1054,11 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac)
err = register_netdev(dev);
if (err) {
- printk(KERN_ERR PFX "Cannot register net device, "
- "aborting.\n");
+ pr_err("Cannot register net device, aborting\n");
goto err_out_free_dev;
}
- printk(KERN_INFO "%s: Sun LDOM vnet %pM\n", dev->name, dev->dev_addr);
+ netdev_info(dev, "Sun LDOM vnet %pM\n", dev->dev_addr);
list_add(&vp->list, &vnet_list);
@@ -1133,10 +1130,7 @@ static struct vio_driver_ops vnet_vio_ops = {
static void __devinit print_version(void)
{
- static int version_printed;
-
- if (version_printed++ == 0)
- printk(KERN_INFO "%s", version);
+ printk_once(KERN_INFO "%s", version);
}
const char *remote_macaddr_prop = "remote-mac-address";
@@ -1157,7 +1151,7 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
vp = vnet_find_parent(hp, vdev->mp);
if (IS_ERR(vp)) {
- printk(KERN_ERR PFX "Cannot find port parent vnet.\n");
+ pr_err("Cannot find port parent vnet\n");
err = PTR_ERR(vp);
goto err_out_put_mdesc;
}
@@ -1165,15 +1159,14 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len);
err = -ENODEV;
if (!rmac) {
- printk(KERN_ERR PFX "Port lacks %s property.\n",
- remote_macaddr_prop);
+ pr_err("Port lacks %s property\n", remote_macaddr_prop);
goto err_out_put_mdesc;
}
port = kzalloc(sizeof(*port), GFP_KERNEL);
err = -ENOMEM;
if (!port) {
- printk(KERN_ERR PFX "Cannot allocate vnet_port.\n");
+ pr_err("Cannot allocate vnet_port\n");
goto err_out_put_mdesc;
}
@@ -1214,9 +1207,8 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
dev_set_drvdata(&vdev->dev, port);
- printk(KERN_INFO "%s: PORT ( remote-mac %pM%s )\n",
- vp->dev->name, port->raddr,
- switch_port ? " switch-port" : "");
+ pr_info("%s: PORT ( remote-mac %pM%s )\n",
+ vp->dev->name, port->raddr, switch_port ? " switch-port" : "");
vio_port_up(&port->vio);
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 99e423a5b9f1..b6eec8cea209 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -1167,7 +1167,7 @@ static void print_eth(const u8 *add)
static int tc35815_tx_full(struct net_device *dev)
{
struct tc35815_local *lp = netdev_priv(dev);
- return ((lp->tfd_start + 1) % TX_FD_NUM == lp->tfd_end);
+ return (lp->tfd_start + 1) % TX_FD_NUM == lp->tfd_end;
}
static void tc35815_restart(struct net_device *dev)
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 737df6032bbc..8b3dc1eb4015 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -92,7 +92,7 @@ static void bdx_rx_free(struct bdx_priv *priv);
static void bdx_tx_free(struct bdx_priv *priv);
/* Definitions needed by bdx_probe */
-static void bdx_ethtool_ops(struct net_device *netdev);
+static void bdx_set_ethtool_ops(struct net_device *netdev);
/*************************************************************************
* Print Info *
@@ -927,13 +927,6 @@ static void bdx_update_stats(struct bdx_priv *priv)
BDX_ASSERT((sizeof(struct bdx_stats) / sizeof(u64)) != i);
}
-static struct net_device_stats *bdx_get_stats(struct net_device *ndev)
-{
- struct bdx_priv *priv = netdev_priv(ndev);
- struct net_device_stats *net_stat = &priv->net_stats;
- return net_stat;
-}
-
static void print_rxdd(struct rxd_desc *rxdd, u32 rxd_val1, u16 len,
u16 rxd_vlan);
static void print_rxfd(struct rxf_desc *rxfd);
@@ -1220,6 +1213,7 @@ static void bdx_recycle_skb(struct bdx_priv *priv, struct rxd_desc *rxdd)
static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
{
+ struct net_device *ndev = priv->ndev;
struct sk_buff *skb, *skb2;
struct rxd_desc *rxdd;
struct rx_map *dm;
@@ -1273,7 +1267,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
if (unlikely(GET_RXD_ERR(rxd_val1))) {
DBG("rxd_err = 0x%x\n", GET_RXD_ERR(rxd_val1));
- priv->net_stats.rx_errors++;
+ ndev->stats.rx_errors++;
bdx_recycle_skb(priv, rxdd);
continue;
}
@@ -1300,15 +1294,16 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
bdx_rxdb_free_elem(db, rxdd->va_lo);
}
- priv->net_stats.rx_bytes += len;
+ ndev->stats.rx_bytes += len;
skb_put(skb, len);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- skb->protocol = eth_type_trans(skb, priv->ndev);
+ skb->protocol = eth_type_trans(skb, ndev);
/* Non-IP packets aren't checksum-offloaded */
if (GET_RXD_PKT_ID(rxd_val1) == 0)
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
NETIF_RX_MUX(priv, rxd_val1, rxd_vlan, skb);
@@ -1316,7 +1311,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
break;
}
- priv->net_stats.rx_packets += done;
+ ndev->stats.rx_packets += done;
/* FIXME: do smth to minimize pci accesses */
WRITE_REG(priv, f->m.reg_RPTR, f->m.rptr & TXF_WPTR_WR_PTR);
@@ -1712,8 +1707,8 @@ static netdev_tx_t bdx_tx_transmit(struct sk_buff *skb,
#ifdef BDX_LLTX
ndev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
#endif
- priv->net_stats.tx_packets++;
- priv->net_stats.tx_bytes += skb->len;
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += skb->len;
if (priv->tx_level < BDX_MIN_TX_LEVEL) {
DBG("%s: %s: TX Q STOP level %d\n",
@@ -1888,7 +1883,6 @@ static const struct net_device_ops bdx_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = bdx_ioctl,
.ndo_set_multicast_list = bdx_setmulti,
- .ndo_get_stats = bdx_get_stats,
.ndo_change_mtu = bdx_change_mtu,
.ndo_set_mac_address = bdx_set_mac,
.ndo_vlan_rx_register = bdx_vlan_rx_register,
@@ -2012,7 +2006,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ndev->netdev_ops = &bdx_netdev_ops;
ndev->tx_queue_len = BDX_NDEV_TXQ_LEN;
- bdx_ethtool_ops(ndev); /* ethtool interface */
+ bdx_set_ethtool_ops(ndev); /* ethtool interface */
/* these fields are used for info purposes only
* so we can have them same for all ports of the board */
@@ -2417,10 +2411,10 @@ static void bdx_get_ethtool_stats(struct net_device *netdev,
}
/*
- * bdx_ethtool_ops - ethtool interface implementation
+ * bdx_set_ethtool_ops - ethtool interface implementation
* @netdev
*/
-static void bdx_ethtool_ops(struct net_device *netdev)
+static void bdx_set_ethtool_ops(struct net_device *netdev)
{
static const struct ethtool_ops bdx_ethtool_ops = {
.get_settings = bdx_get_settings,
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index 67e3b71bf705..b6ba8601e2b5 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -269,7 +269,6 @@ struct bdx_priv {
u32 msg_enable;
int stats_flag;
struct bdx_stats hw_stats;
- struct net_device_stats net_stats;
struct pci_dev *pdev;
struct pci_nic *nic;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 1ec4b9e0239a..852e917778f8 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -69,10 +69,10 @@
#define DRV_MODULE_NAME "tg3"
#define TG3_MAJ_NUM 3
-#define TG3_MIN_NUM 113
+#define TG3_MIN_NUM 115
#define DRV_MODULE_VERSION \
__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE "August 2, 2010"
+#define DRV_MODULE_RELDATE "October 14, 2010"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -101,9 +101,15 @@
* You can't change the ring sizes, but you can change where you place
* them in the NIC onboard memory.
*/
-#define TG3_RX_RING_SIZE 512
+#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)
#define TG3_DEF_RX_RING_PENDING 200
-#define TG3_RX_JUMBO_RING_SIZE 256
+#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)
#define TG3_DEF_RX_JUMBO_RING_PENDING 100
#define TG3_RSS_INDIR_TBL_SIZE 128
@@ -113,19 +119,16 @@
* hw multiply/modulo instructions. Another solution would be to
* replace things like '% foo' with '& (foo - 1)'.
*/
-#define TG3_RX_RCB_RING_SIZE(tp) \
- (((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && \
- !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) ? 1024 : 512)
#define TG3_TX_RING_SIZE 512
#define TG3_DEF_TX_RING_PENDING (TG3_TX_RING_SIZE - 1)
-#define TG3_RX_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * \
- TG3_RX_RING_SIZE)
-#define TG3_RX_JUMBO_RING_BYTES (sizeof(struct tg3_ext_rx_buffer_desc) * \
- TG3_RX_JUMBO_RING_SIZE)
-#define TG3_RX_RCB_RING_BYTES(tp) (sizeof(struct tg3_rx_buffer_desc) * \
- TG3_RX_RCB_RING_SIZE(tp))
+#define TG3_RX_STD_RING_BYTES(tp) \
+ (sizeof(struct tg3_rx_buffer_desc) * TG3_RX_STD_RING_SIZE(tp))
+#define TG3_RX_JMB_RING_BYTES(tp) \
+ (sizeof(struct tg3_ext_rx_buffer_desc) * TG3_RX_JMB_RING_SIZE(tp))
+#define TG3_RX_RCB_RING_BYTES(tp) \
+ (sizeof(struct tg3_rx_buffer_desc) * (tp->rx_ret_ring_mask + 1))
#define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \
TG3_TX_RING_SIZE)
#define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1))
@@ -143,11 +146,11 @@
#define TG3_RX_STD_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ)
#define TG3_RX_JMB_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ)
-#define TG3_RX_STD_BUFF_RING_SIZE \
- (sizeof(struct ring_info) * TG3_RX_RING_SIZE)
+#define TG3_RX_STD_BUFF_RING_SIZE(tp) \
+ (sizeof(struct ring_info) * TG3_RX_STD_RING_SIZE(tp))
-#define TG3_RX_JMB_BUFF_RING_SIZE \
- (sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE)
+#define TG3_RX_JMB_BUFF_RING_SIZE(tp) \
+ (sizeof(struct ring_info) * TG3_RX_JMB_RING_SIZE(tp))
/* Due to a hardware bug, the 5701 can only DMA to memory addresses
* that are at least dword aligned when used in PCIX mode. The driver
@@ -264,7 +267,6 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)},
- {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5724)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57781)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57785)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57761)},
@@ -752,42 +754,6 @@ static void tg3_int_reenable(struct tg3_napi *tnapi)
HOSTCC_MODE_ENABLE | tnapi->coal_now);
}
-static void tg3_napi_disable(struct tg3 *tp)
-{
- int i;
-
- for (i = tp->irq_cnt - 1; i >= 0; i--)
- napi_disable(&tp->napi[i].napi);
-}
-
-static void tg3_napi_enable(struct tg3 *tp)
-{
- int i;
-
- for (i = 0; i < tp->irq_cnt; i++)
- napi_enable(&tp->napi[i].napi);
-}
-
-static inline void tg3_netif_stop(struct tg3 *tp)
-{
- tp->dev->trans_start = jiffies; /* prevent tx timeout */
- tg3_napi_disable(tp);
- netif_tx_disable(tp->dev);
-}
-
-static inline void tg3_netif_start(struct tg3 *tp)
-{
- /* NOTE: unconditional netif_tx_wake_all_queues is only
- * appropriate so long as all callers are assured to
- * have free tx slots (such as after tg3_init_hw)
- */
- netif_tx_wake_all_queues(tp->dev);
-
- tg3_napi_enable(tp);
- tp->napi[0].hw_status->status |= SD_STATUS_UPDATED;
- tg3_enable_ints(tp);
-}
-
static void tg3_switch_clocks(struct tg3 *tp)
{
u32 clock_ctrl;
@@ -1196,6 +1162,52 @@ static void tg3_mdio_fini(struct tg3 *tp)
}
}
+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)
{
@@ -1572,6 +1584,17 @@ 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;
@@ -1735,6 +1758,42 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
}
+static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
+{
+ u32 val;
+
+ if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP))
+ return;
+
+ tp->setlpicnt = 0;
+
+ if (tp->link_config.autoneg == AUTONEG_ENABLE &&
+ current_link_up == 1 &&
+ (tp->link_config.active_speed == SPEED_1000 ||
+ (tp->link_config.active_speed == SPEED_100 &&
+ tp->link_config.active_duplex == DUPLEX_FULL))) {
+ u32 eeectl;
+
+ if (tp->link_config.active_speed == SPEED_1000)
+ eeectl = TG3_CPMU_EEE_CTRL_EXIT_16_5_US;
+ else
+ eeectl = TG3_CPMU_EEE_CTRL_EXIT_36_US;
+
+ tw32(TG3_CPMU_EEE_CTRL, eeectl);
+
+ tg3_phy_cl45_read(tp, 0x7, TG3_CL45_D7_EEERES_STAT, &val);
+
+ if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T ||
+ val == TG3_CL45_D7_EEERES_STAT_LP_100TX)
+ tp->setlpicnt = 2;
+ }
+
+ if (!tp->setlpicnt) {
+ 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;
@@ -1917,19 +1976,16 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
*/
static int tg3_phy_reset(struct tg3 *tp)
{
- u32 cpmuctrl;
- u32 phy_status;
+ u32 val, cpmuctrl;
int err;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
- u32 val;
-
val = tr32(GRC_MISC_CFG);
tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ);
udelay(40);
}
- err = tg3_readphy(tp, MII_BMSR, &phy_status);
- err |= tg3_readphy(tp, MII_BMSR, &phy_status);
+ err = tg3_readphy(tp, MII_BMSR, &val);
+ err |= tg3_readphy(tp, MII_BMSR, &val);
if (err != 0)
return -EBUSY;
@@ -1961,18 +2017,14 @@ static int tg3_phy_reset(struct tg3 *tp)
return err;
if (cpmuctrl & CPMU_CTRL_GPHY_10MB_RXONLY) {
- u32 phy;
-
- phy = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz;
- tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, phy);
+ val = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz;
+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, val);
tw32(TG3_CPMU_CTRL, cpmuctrl);
}
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX ||
GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5761_AX) {
- u32 val;
-
val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
if ((val & CPMU_LSPD_1000MB_MACCLK_MASK) ==
CPMU_LSPD_1000MB_MACCLK_12_5) {
@@ -2028,23 +2080,19 @@ out:
/* Cannot do read-modify-write on 5401 */
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
} else if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
- u32 phy_reg;
-
/* 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, &phy_reg))
- tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000);
+ !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val))
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, val | 0x4000);
}
/* Set phy register 0x10 bit 0 to high fifo elasticity to support
* jumbo frames transmission.
*/
if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
- u32 phy_reg;
-
- if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &phy_reg))
+ if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &val))
tg3_writephy(tp, MII_TG3_EXT_CTRL,
- phy_reg | MII_TG3_EXT_CTRL_FIFO_ELASTIC);
+ val | MII_TG3_EXT_CTRL_FIFO_ELASTIC);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
@@ -2920,6 +2968,44 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
tg3_writephy(tp, MII_TG3_CTRL, new_adv);
}
+ if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
+ u32 val = 0;
+
+ 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);
+
+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
+ !tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val))
+ tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2,
+ val | MII_TG3_DSP_CH34TP2_HIBW01);
+
+ if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+ /* Advertise 100-BaseTX EEE ability */
+ if (tp->link_config.advertising &
+ (ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full))
+ val |= TG3_CL45_D7_EEEADV_CAP_100TX;
+ /* Advertise 1000-BaseT EEE ability */
+ if (tp->link_config.advertising &
+ (ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full))
+ val |= TG3_CL45_D7_EEEADV_CAP_1000T;
+ }
+ tg3_phy_cl45_write(tp, 0x7, TG3_CL45_D7_EEEADV_CAP, 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);
+ }
+
if (tp->link_config.autoneg == AUTONEG_DISABLE &&
tp->link_config.speed != SPEED_INVALID) {
u32 bmcr, orig_bmcr;
@@ -3060,7 +3146,7 @@ static int tg3_adv_1000T_flowctrl_ok(struct tg3 *tp, u32 *lcladv, u32 *rmtadv)
static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
{
int current_link_up;
- u32 bmsr, dummy;
+ u32 bmsr, val;
u32 lcl_adv, rmt_adv;
u16 current_speed;
u8 current_duplex;
@@ -3140,8 +3226,8 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
}
/* Clear pending interrupts... */
- tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
- tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
+ tg3_readphy(tp, MII_TG3_ISTAT, &val);
+ tg3_readphy(tp, MII_TG3_ISTAT, &val);
if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT)
tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG);
@@ -3162,8 +3248,6 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
current_duplex = DUPLEX_INVALID;
if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) {
- u32 val;
-
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007);
tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
if (!(val & (1 << 10))) {
@@ -3238,13 +3322,11 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
relink:
if (current_link_up == 0 || (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
- u32 tmp;
-
tg3_phy_copper_begin(tp);
- tg3_readphy(tp, MII_BMSR, &tmp);
- if (!tg3_readphy(tp, MII_BMSR, &tmp) &&
- (tmp & BMSR_LSTATUS))
+ tg3_readphy(tp, MII_BMSR, &bmsr);
+ if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
+ (bmsr & BMSR_LSTATUS))
current_link_up = 1;
}
@@ -3285,6 +3367,8 @@ relink:
tw32_f(MAC_MODE, tp->mac_mode);
udelay(40);
+ tg3_phy_eee_adjust(tp, current_link_up);
+
if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
/* Polled via timer. */
tw32_f(MAC_EVENT, 0);
@@ -4353,6 +4437,11 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
return err;
}
+static inline int tg3_irq_sync(struct tg3 *tp)
+{
+ return tp->irq_sync;
+}
+
/* 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
@@ -4484,22 +4573,21 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
u32 opaque_key, u32 dest_idx_unmasked)
{
struct tg3_rx_buffer_desc *desc;
- struct ring_info *map, *src_map;
+ struct ring_info *map;
struct sk_buff *skb;
dma_addr_t mapping;
int skb_size, dest_idx;
- src_map = NULL;
switch (opaque_key) {
case RXD_OPAQUE_RING_STD:
- dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
+ dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask;
desc = &tpr->rx_std[dest_idx];
map = &tpr->rx_std_buffers[dest_idx];
skb_size = tp->rx_pkt_map_sz;
break;
case RXD_OPAQUE_RING_JUMBO:
- dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
+ dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask;
desc = &tpr->rx_jmb[dest_idx].std;
map = &tpr->rx_jmb_buffers[dest_idx];
skb_size = TG3_RX_JMB_MAP_SZ;
@@ -4549,12 +4637,12 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi,
struct tg3 *tp = tnapi->tp;
struct tg3_rx_buffer_desc *src_desc, *dest_desc;
struct ring_info *src_map, *dest_map;
- struct tg3_rx_prodring_set *spr = &tp->prodring[0];
+ struct tg3_rx_prodring_set *spr = &tp->napi[0].prodring;
int dest_idx;
switch (opaque_key) {
case RXD_OPAQUE_RING_STD:
- dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
+ dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask;
dest_desc = &dpr->rx_std[dest_idx];
dest_map = &dpr->rx_std_buffers[dest_idx];
src_desc = &spr->rx_std[src_idx];
@@ -4562,7 +4650,7 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi,
break;
case RXD_OPAQUE_RING_JUMBO:
- dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
+ dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask;
dest_desc = &dpr->rx_jmb[dest_idx].std;
dest_map = &dpr->rx_jmb_buffers[dest_idx];
src_desc = &spr->rx_jmb[src_idx].std;
@@ -4619,7 +4707,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
u32 sw_idx = tnapi->rx_rcb_ptr;
u16 hw_idx;
int received;
- struct tg3_rx_prodring_set *tpr = tnapi->prodring;
+ struct tg3_rx_prodring_set *tpr = &tnapi->prodring;
hw_idx = *(tnapi->rx_rcb_prod_idx);
/*
@@ -4644,13 +4732,13 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
if (opaque_key == RXD_OPAQUE_RING_STD) {
- ri = &tp->prodring[0].rx_std_buffers[desc_idx];
+ ri = &tp->napi[0].prodring.rx_std_buffers[desc_idx];
dma_addr = dma_unmap_addr(ri, mapping);
skb = ri->skb;
post_ptr = &std_prod_idx;
rx_std_posted++;
} else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
- ri = &tp->prodring[0].rx_jmb_buffers[desc_idx];
+ ri = &tp->napi[0].prodring.rx_jmb_buffers[desc_idx];
dma_addr = dma_unmap_addr(ri, mapping);
skb = ri->skb;
post_ptr = &jmb_prod_idx;
@@ -4719,7 +4807,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
>> RXD_TCPCSUM_SHIFT) == 0xffff))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, tp->dev);
@@ -4762,7 +4850,8 @@ next_pkt:
(*post_ptr)++;
if (unlikely(rx_std_posted >= tp->rx_std_max_post)) {
- tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
+ tpr->rx_std_prod_idx = std_prod_idx &
+ tp->rx_std_ring_mask;
tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
tpr->rx_std_prod_idx);
work_mask &= ~RXD_OPAQUE_RING_STD;
@@ -4770,7 +4859,7 @@ next_pkt:
}
next_pkt_nopost:
sw_idx++;
- sw_idx &= (TG3_RX_RCB_RING_SIZE(tp) - 1);
+ sw_idx &= tp->rx_ret_ring_mask;
/* Refresh hw_idx to see if there is new work */
if (sw_idx == hw_idx) {
@@ -4786,13 +4875,14 @@ next_pkt_nopost:
/* Refill RX ring(s). */
if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) {
if (work_mask & RXD_OPAQUE_RING_STD) {
- tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
+ tpr->rx_std_prod_idx = std_prod_idx &
+ tp->rx_std_ring_mask;
tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
tpr->rx_std_prod_idx);
}
if (work_mask & RXD_OPAQUE_RING_JUMBO) {
- tpr->rx_jmb_prod_idx = jmb_prod_idx %
- TG3_RX_JUMBO_RING_SIZE;
+ tpr->rx_jmb_prod_idx = jmb_prod_idx &
+ tp->rx_jmb_ring_mask;
tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
tpr->rx_jmb_prod_idx);
}
@@ -4803,8 +4893,8 @@ next_pkt_nopost:
*/
smp_wmb();
- tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
- tpr->rx_jmb_prod_idx = jmb_prod_idx % TG3_RX_JUMBO_RING_SIZE;
+ tpr->rx_std_prod_idx = std_prod_idx & tp->rx_std_ring_mask;
+ tpr->rx_jmb_prod_idx = jmb_prod_idx & tp->rx_jmb_ring_mask;
if (tnapi != &tp->napi[1])
napi_schedule(&tp->napi[1].napi);
@@ -4860,9 +4950,11 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp,
if (spr->rx_std_cons_idx < src_prod_idx)
cpycnt = src_prod_idx - spr->rx_std_cons_idx;
else
- cpycnt = TG3_RX_RING_SIZE - spr->rx_std_cons_idx;
+ cpycnt = tp->rx_std_ring_mask + 1 -
+ spr->rx_std_cons_idx;
- cpycnt = min(cpycnt, TG3_RX_RING_SIZE - dpr->rx_std_prod_idx);
+ cpycnt = min(cpycnt,
+ tp->rx_std_ring_mask + 1 - dpr->rx_std_prod_idx);
si = spr->rx_std_cons_idx;
di = dpr->rx_std_prod_idx;
@@ -4896,10 +4988,10 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp,
dbd->addr_lo = sbd->addr_lo;
}
- spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) %
- TG3_RX_RING_SIZE;
- dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) %
- TG3_RX_RING_SIZE;
+ spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) &
+ tp->rx_std_ring_mask;
+ dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) &
+ tp->rx_std_ring_mask;
}
while (1) {
@@ -4916,10 +5008,11 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp,
if (spr->rx_jmb_cons_idx < src_prod_idx)
cpycnt = src_prod_idx - spr->rx_jmb_cons_idx;
else
- cpycnt = TG3_RX_JUMBO_RING_SIZE - spr->rx_jmb_cons_idx;
+ cpycnt = tp->rx_jmb_ring_mask + 1 -
+ spr->rx_jmb_cons_idx;
cpycnt = min(cpycnt,
- TG3_RX_JUMBO_RING_SIZE - dpr->rx_jmb_prod_idx);
+ tp->rx_jmb_ring_mask + 1 - dpr->rx_jmb_prod_idx);
si = spr->rx_jmb_cons_idx;
di = dpr->rx_jmb_prod_idx;
@@ -4953,10 +5046,10 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp,
dbd->addr_lo = sbd->addr_lo;
}
- spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) %
- TG3_RX_JUMBO_RING_SIZE;
- dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) %
- TG3_RX_JUMBO_RING_SIZE;
+ spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) &
+ tp->rx_jmb_ring_mask;
+ dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) &
+ tp->rx_jmb_ring_mask;
}
return err;
@@ -4981,14 +5074,14 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
work_done += tg3_rx(tnapi, budget - work_done);
if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
- struct tg3_rx_prodring_set *dpr = &tp->prodring[0];
+ struct tg3_rx_prodring_set *dpr = &tp->napi[0].prodring;
int i, err = 0;
u32 std_prod_idx = dpr->rx_std_prod_idx;
u32 jmb_prod_idx = dpr->rx_jmb_prod_idx;
for (i = 1; i < tp->irq_cnt; i++)
err |= tg3_rx_prodring_xfer(tp, dpr,
- tp->napi[i].prodring);
+ &tp->napi[i].prodring);
wmb();
@@ -5098,6 +5191,59 @@ tx_recovery:
return work_done;
}
+static void tg3_napi_disable(struct tg3 *tp)
+{
+ int i;
+
+ for (i = tp->irq_cnt - 1; i >= 0; i--)
+ napi_disable(&tp->napi[i].napi);
+}
+
+static void tg3_napi_enable(struct tg3 *tp)
+{
+ int i;
+
+ for (i = 0; i < tp->irq_cnt; i++)
+ napi_enable(&tp->napi[i].napi);
+}
+
+static void tg3_napi_init(struct tg3 *tp)
+{
+ int i;
+
+ netif_napi_add(tp->dev, &tp->napi[0].napi, tg3_poll, 64);
+ for (i = 1; i < tp->irq_cnt; i++)
+ netif_napi_add(tp->dev, &tp->napi[i].napi, tg3_poll_msix, 64);
+}
+
+static void tg3_napi_fini(struct tg3 *tp)
+{
+ int i;
+
+ for (i = 0; i < tp->irq_cnt; i++)
+ netif_napi_del(&tp->napi[i].napi);
+}
+
+static inline void tg3_netif_stop(struct tg3 *tp)
+{
+ tp->dev->trans_start = jiffies; /* prevent tx timeout */
+ tg3_napi_disable(tp);
+ netif_tx_disable(tp->dev);
+}
+
+static inline void tg3_netif_start(struct tg3 *tp)
+{
+ /* NOTE: unconditional netif_tx_wake_all_queues is only
+ * appropriate so long as all callers are assured to
+ * have free tx slots (such as after tg3_init_hw)
+ */
+ netif_tx_wake_all_queues(tp->dev);
+
+ tg3_napi_enable(tp);
+ tp->napi[0].hw_status->status |= SD_STATUS_UPDATED;
+ tg3_enable_ints(tp);
+}
+
static void tg3_irq_quiesce(struct tg3 *tp)
{
int i;
@@ -5111,11 +5257,6 @@ static void tg3_irq_quiesce(struct tg3 *tp)
synchronize_irq(tp->napi[i].irq_vec);
}
-static inline int tg3_irq_sync(struct tg3 *tp)
-{
- return tp->irq_sync;
-}
-
/* Fully shutdown all tg3 driver activity elsewhere in the system.
* If irq_sync is non-zero, then the IRQ handler must be synchronized
* with as well. Most of the time, this is not necessary except when
@@ -5404,8 +5545,7 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
{
u32 base = (u32) mapping & 0xffffffff;
- return ((base > 0xffffdcc0) &&
- (base + len + 8 < base));
+ return (base > 0xffffdcc0) && (base + len + 8 < base);
}
/* Test for DMA addresses > 40-bit */
@@ -5414,7 +5554,7 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
{
#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG)
- return (((u64) mapping + len) > DMA_BIT_MASK(40));
+ return ((u64) mapping + len) > DMA_BIT_MASK(40);
return 0;
#else
return 0;
@@ -5574,9 +5714,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
goto out_unlock;
}
- if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+ if (skb_is_gso_v6(skb)) {
hdrlen = skb_headlen(skb) - ETH_HLEN;
- else {
+ } else {
struct iphdr *iph = ip_hdr(skb);
tcp_opt_len = tcp_optlen(skb);
@@ -5605,7 +5745,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
}
#if TG3_VLAN_TAG_USED
- if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
+ if (vlan_tx_tag_present(skb))
base_flags |= (TXD_FLAG_VLAN |
(vlan_tx_tag_get(skb) << 16));
#endif
@@ -5798,7 +5938,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
iph = ip_hdr(skb);
tcp_opt_len = tcp_optlen(skb);
- if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
+ if (skb_is_gso_v6(skb)) {
hdr_len = skb_headlen(skb) - ETH_HLEN;
} else {
u32 ip_tcp_len;
@@ -5851,7 +5991,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
}
}
#if TG3_VLAN_TAG_USED
- if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
+ if (vlan_tx_tag_present(skb))
base_flags |= (TXD_FLAG_VLAN |
(vlan_tx_tag_get(skb) << 16));
#endif
@@ -6057,16 +6197,16 @@ static void tg3_rx_prodring_free(struct tg3 *tp,
{
int i;
- if (tpr != &tp->prodring[0]) {
+ if (tpr != &tp->napi[0].prodring) {
for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx;
- i = (i + 1) % TG3_RX_RING_SIZE)
+ i = (i + 1) & tp->rx_std_ring_mask)
tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
tp->rx_pkt_map_sz);
if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
for (i = tpr->rx_jmb_cons_idx;
i != tpr->rx_jmb_prod_idx;
- i = (i + 1) % TG3_RX_JUMBO_RING_SIZE) {
+ i = (i + 1) & tp->rx_jmb_ring_mask) {
tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
TG3_RX_JMB_MAP_SZ);
}
@@ -6075,12 +6215,13 @@ static void tg3_rx_prodring_free(struct tg3 *tp,
return;
}
- for (i = 0; i < TG3_RX_RING_SIZE; i++)
+ for (i = 0; i <= tp->rx_std_ring_mask; i++)
tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
tp->rx_pkt_map_sz);
- if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
- for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++)
+ if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
+ !(tp->tg3_flags2 & TG3_FLG2_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);
}
@@ -6103,16 +6244,17 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
tpr->rx_jmb_cons_idx = 0;
tpr->rx_jmb_prod_idx = 0;
- if (tpr != &tp->prodring[0]) {
- memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE);
- if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE)
+ if (tpr != &tp->napi[0].prodring) {
+ memset(&tpr->rx_std_buffers[0], 0,
+ TG3_RX_STD_BUFF_RING_SIZE(tp));
+ if (tpr->rx_jmb_buffers)
memset(&tpr->rx_jmb_buffers[0], 0,
- TG3_RX_JMB_BUFF_RING_SIZE);
+ TG3_RX_JMB_BUFF_RING_SIZE(tp));
goto done;
}
/* Zero out all descriptors. */
- memset(tpr->rx_std, 0, TG3_RX_RING_BYTES);
+ 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) &&
@@ -6124,7 +6266,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
* stuff once. This works because the card does not
* write into the rx buffer posting rings.
*/
- for (i = 0; i < TG3_RX_RING_SIZE; i++) {
+ for (i = 0; i <= tp->rx_std_ring_mask; i++) {
struct tg3_rx_buffer_desc *rxd;
rxd = &tpr->rx_std[i];
@@ -6148,15 +6290,16 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
}
}
- if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE))
+ if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) ||
+ (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
goto done;
- memset(tpr->rx_jmb, 0, TG3_RX_JUMBO_RING_BYTES);
+ memset(tpr->rx_jmb, 0, TG3_RX_JMB_RING_BYTES(tp));
if (!(tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE))
goto done;
- for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
+ for (i = 0; i <= tp->rx_jmb_ring_mask; i++) {
struct tg3_rx_buffer_desc *rxd;
rxd = &tpr->rx_jmb[i].std;
@@ -6196,12 +6339,12 @@ static void tg3_rx_prodring_fini(struct tg3 *tp,
kfree(tpr->rx_jmb_buffers);
tpr->rx_jmb_buffers = NULL;
if (tpr->rx_std) {
- pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES,
+ pci_free_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp),
tpr->rx_std, tpr->rx_std_mapping);
tpr->rx_std = NULL;
}
if (tpr->rx_jmb) {
- pci_free_consistent(tp->pdev, TG3_RX_JUMBO_RING_BYTES,
+ pci_free_consistent(tp->pdev, TG3_RX_JMB_RING_BYTES(tp),
tpr->rx_jmb, tpr->rx_jmb_mapping);
tpr->rx_jmb = NULL;
}
@@ -6210,23 +6353,25 @@ static void tg3_rx_prodring_fini(struct tg3 *tp,
static int tg3_rx_prodring_init(struct tg3 *tp,
struct tg3_rx_prodring_set *tpr)
{
- tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE, GFP_KERNEL);
+ tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE(tp),
+ GFP_KERNEL);
if (!tpr->rx_std_buffers)
return -ENOMEM;
- tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
+ tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp),
&tpr->rx_std_mapping);
if (!tpr->rx_std)
goto err_out;
- if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
- tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE,
+ if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
+ !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+ tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE(tp),
GFP_KERNEL);
if (!tpr->rx_jmb_buffers)
goto err_out;
tpr->rx_jmb = pci_alloc_consistent(tp->pdev,
- TG3_RX_JUMBO_RING_BYTES,
+ TG3_RX_JMB_RING_BYTES(tp),
&tpr->rx_jmb_mapping);
if (!tpr->rx_jmb)
goto err_out;
@@ -6253,7 +6398,7 @@ static void tg3_free_rings(struct tg3 *tp)
for (j = 0; j < tp->irq_cnt; j++) {
struct tg3_napi *tnapi = &tp->napi[j];
- tg3_rx_prodring_free(tp, &tp->prodring[j]);
+ tg3_rx_prodring_free(tp, &tnapi->prodring);
if (!tnapi->tx_buffers)
continue;
@@ -6325,7 +6470,7 @@ static int tg3_init_rings(struct tg3 *tp)
if (tnapi->rx_rcb)
memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
- if (tg3_rx_prodring_alloc(tp, &tp->prodring[i])) {
+ if (tg3_rx_prodring_alloc(tp, &tnapi->prodring)) {
tg3_free_rings(tp);
return -ENOMEM;
}
@@ -6361,6 +6506,8 @@ static void tg3_free_consistent(struct tg3 *tp)
tnapi->rx_rcb = NULL;
}
+ tg3_rx_prodring_fini(tp, &tnapi->prodring);
+
if (tnapi->hw_status) {
pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
tnapi->hw_status,
@@ -6374,9 +6521,6 @@ static void tg3_free_consistent(struct tg3 *tp)
tp->hw_stats, tp->stats_mapping);
tp->hw_stats = NULL;
}
-
- for (i = 0; i < tp->irq_cnt; i++)
- tg3_rx_prodring_fini(tp, &tp->prodring[i]);
}
/*
@@ -6387,11 +6531,6 @@ static int tg3_alloc_consistent(struct tg3 *tp)
{
int i;
- for (i = 0; i < tp->irq_cnt; i++) {
- if (tg3_rx_prodring_init(tp, &tp->prodring[i]))
- goto err_out;
- }
-
tp->hw_stats = pci_alloc_consistent(tp->pdev,
sizeof(struct tg3_hw_stats),
&tp->stats_mapping);
@@ -6413,6 +6552,9 @@ static int tg3_alloc_consistent(struct tg3 *tp)
memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
sblk = tnapi->hw_status;
+ if (tg3_rx_prodring_init(tp, &tnapi->prodring))
+ goto err_out;
+
/* If multivector TSS is enabled, vector 0 does not handle
* tx interrupts. Don't allocate any resources for it.
*/
@@ -6452,8 +6594,6 @@ static int tg3_alloc_consistent(struct tg3 *tp)
break;
}
- tnapi->prodring = &tp->prodring[i];
-
/*
* If multivector RSS is enabled, vector 0 does not handle
* rx or tx interrupts. Don't allocate any resources for it.
@@ -6596,6 +6736,10 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event)
int i;
u32 apedata;
+ /* NCSI does not support APE events */
+ if (tp->tg3_flags3 & TG3_FLG3_APE_HAS_NCSI)
+ return;
+
apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
if (apedata != APE_SEG_SIG_MAGIC)
return;
@@ -6647,6 +6791,8 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
APE_HOST_DRIVER_ID_MAGIC(TG3_MAJ_NUM, TG3_MIN_NUM));
tg3_ape_write32(tp, TG3_APE_HOST_BEHAVIOR,
APE_HOST_BEHAV_NO_PHYLOCK);
+ tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE,
+ TG3_APE_HOST_DRVR_STATE_START);
event = APE_EVENT_STATUS_STATE_START;
break;
@@ -6658,6 +6804,16 @@ 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_ape_write32(tp, TG3_APE_HOST_WOL_SPEED,
+ TG3_APE_HOST_WOL_SPEED_AUTO);
+ apedata = TG3_APE_HOST_DRVR_STATE_WOL;
+ } else
+ apedata = TG3_APE_HOST_DRVR_STATE_UNLOAD;
+
+ tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, apedata);
+
event = APE_EVENT_STATUS_STATE_UNLOAD;
break;
case RESET_KIND_SUSPEND:
@@ -7515,6 +7671,9 @@ static void tg3_rings_reset(struct tg3 *tp)
/* Disable all transmit rings but the first. */
if (!(tp->tg3_flags2 & TG3_FLG2_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)
+ 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;
else
@@ -7548,7 +7707,7 @@ static void tg3_rings_reset(struct tg3 *tp)
/* Zero mailbox registers. */
if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) {
- for (i = 1; i < TG3_IRQ_MAX_VECS; i++) {
+ 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)
@@ -7594,8 +7753,8 @@ static void tg3_rings_reset(struct tg3 *tp)
if (tnapi->rx_rcb) {
tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
- (TG3_RX_RCB_RING_SIZE(tp) <<
- BDINFO_FLAGS_MAXLEN_SHIFT), 0);
+ (tp->rx_ret_ring_mask + 1) <<
+ BDINFO_FLAGS_MAXLEN_SHIFT, 0);
rxrcb += TG3_BDINFO_SIZE;
}
@@ -7618,7 +7777,7 @@ static void tg3_rings_reset(struct tg3 *tp)
}
tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
- (TG3_RX_RCB_RING_SIZE(tp) <<
+ ((tp->rx_ret_ring_mask + 1) <<
BDINFO_FLAGS_MAXLEN_SHIFT), 0);
stblk += 8;
@@ -7631,7 +7790,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
{
u32 val, rdmac_mode;
int i, err, limit;
- struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+ struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring;
tg3_disable_ints(tp);
@@ -7720,6 +7879,22 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(TG3_CPMU_LSPD_10MB_CLK, val);
}
+ /* Enable MAC control of LPI */
+ if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
+ tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL,
+ TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
+ TG3_CPMU_EEE_LNKIDL_UART_IDL);
+
+ tw32_f(TG3_CPMU_EEE_CTRL,
+ TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
+
+ tw32_f(TG3_CPMU_EEE_MODE,
+ TG3_CPMU_EEEMD_ERLY_L1_XIT_DET |
+ TG3_CPMU_EEEMD_LPI_IN_TX |
+ TG3_CPMU_EEEMD_LPI_IN_RX |
+ TG3_CPMU_EEEMD_EEE_ENABLE);
+ }
+
/* This works around an issue with Athlon chipsets on
* B3 tigon3 silicon. This bit has no effect on any
* other revision. But do not set this on PCI Express
@@ -7845,7 +8020,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(BUFMGR_DMA_HIGH_WATER,
tp->bufmgr_config.dma_high_water);
- tw32(BUFMGR_MODE, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
+ 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;
+ tw32(BUFMGR_MODE, val);
for (i = 0; i < 2000; i++) {
if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE)
break;
@@ -7928,10 +8106,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
BDINFO_FLAGS_DISABLED);
}
- if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
- val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) |
- (TG3_RX_STD_DMA_SZ << 2);
- else
+ if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+ val = RX_STD_MAX_SIZE_5705;
+ else
+ val = 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;
@@ -8015,6 +8197,23 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
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_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)) {
+ val = tr32(TG3_RDMA_RSRVCTRL_REG);
+ tw32(TG3_RDMA_RSRVCTRL_REG,
+ val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
+ }
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+ 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 |
+ TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K);
+ }
+
/* Receive/send statistics. */
if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
val = tr32(RCVLPC_STATS_ENABLE);
@@ -8197,7 +8396,11 @@ 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);
- tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ);
+ 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)
+ val |= RCVDBDI_MODE_LRG_RING_SZ;
+ tw32(RCVDBDI_MODE, val);
tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8);
@@ -8500,6 +8703,12 @@ static void tg3_timer(unsigned long __opaque)
if (tp->tg3_flags2 & TG3_FLG2_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->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
u32 mac_stat;
int phy_event;
@@ -8816,16 +9025,14 @@ static bool tg3_enable_msix(struct tg3 *tp)
for (i = 0; i < tp->irq_max; i++)
tp->napi[i].irq_vec = msix_ent[i].vector;
- tp->dev->real_num_tx_queues = 1;
- if (tp->irq_cnt > 1) {
- tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
-
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
- tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS;
- tp->dev->real_num_tx_queues = tp->irq_cnt - 1;
- }
+ netif_set_real_num_tx_queues(tp->dev, 1);
+ rc = tp->irq_cnt > 1 ? tp->irq_cnt - 1 : 1;
+ if (netif_set_real_num_rx_queues(tp->dev, rc)) {
+ pci_disable_msix(tp->pdev);
+ return false;
}
+ if (tp->irq_cnt > 1)
+ tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
return true;
}
@@ -8858,7 +9065,8 @@ defcfg:
if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
tp->irq_cnt = 1;
tp->napi[0].irq_vec = tp->pdev->irq;
- tp->dev->real_num_tx_queues = 1;
+ netif_set_real_num_tx_queues(tp->dev, 1);
+ netif_set_real_num_rx_queues(tp->dev, 1);
}
}
@@ -8917,6 +9125,8 @@ static int tg3_open(struct net_device *dev)
if (err)
goto err_out1;
+ tg3_napi_init(tp);
+
tg3_napi_enable(tp);
for (i = 0; i < tp->irq_cnt; i++) {
@@ -9004,6 +9214,7 @@ err_out3:
err_out2:
tg3_napi_disable(tp);
+ tg3_napi_fini(tp);
tg3_free_consistent(tp);
err_out1:
@@ -9051,6 +9262,8 @@ static int tg3_close(struct net_device *dev)
memcpy(&tp->estats_prev, tg3_get_estats(tp),
sizeof(tp->estats_prev));
+ tg3_napi_fini(tp);
+
tg3_free_consistent(tp);
tg3_set_power_state(tp, PCI_D3hot);
@@ -9596,6 +9809,9 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (netif_running(dev)) {
cmd->speed = tp->link_config.active_speed;
cmd->duplex = tp->link_config.active_duplex;
+ } else {
+ cmd->speed = SPEED_INVALID;
+ cmd->duplex = DUPLEX_INVALID;
}
cmd->phy_address = tp->phy_addr;
cmd->transceiver = XCVR_INTERNAL;
@@ -9822,10 +10038,10 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
{
struct tg3 *tp = netdev_priv(dev);
- ering->rx_max_pending = TG3_RX_RING_SIZE - 1;
+ ering->rx_max_pending = tp->rx_std_ring_mask;
ering->rx_mini_max_pending = 0;
if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE)
- ering->rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1;
+ ering->rx_jumbo_max_pending = tp->rx_jmb_ring_mask;
else
ering->rx_jumbo_max_pending = 0;
@@ -9846,8 +10062,8 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
struct tg3 *tp = netdev_priv(dev);
int i, irq_sync = 0, err = 0;
- if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) ||
- (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
+ if ((ering->rx_pending > tp->rx_std_ring_mask) ||
+ (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) &&
@@ -9869,7 +10085,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
tp->rx_pending = 63;
tp->rx_jumbo_pending = ering->rx_jumbo_pending;
- for (i = 0; i < TG3_IRQ_MAX_VECS; i++)
+ for (i = 0; i < tp->irq_max; i++)
tp->napi[i].tx_pending = ering->tx_pending;
if (netif_running(dev)) {
@@ -9917,8 +10133,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
if (!(phydev->supported & SUPPORTED_Pause) ||
(!(phydev->supported & SUPPORTED_Asym_Pause) &&
- ((epause->rx_pause && !epause->tx_pause) ||
- (!epause->rx_pause && epause->tx_pause))))
+ (epause->rx_pause != epause->tx_pause)))
return -EINVAL;
tp->link_config.flowctrl = 0;
@@ -10610,12 +10825,13 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
int num_pkts, tx_len, rx_len, i, err;
struct tg3_rx_buffer_desc *desc;
struct tg3_napi *tnapi, *rnapi;
- struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+ struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring;
tnapi = &tp->napi[0];
rnapi = &tp->napi[0];
if (tp->irq_cnt > 1) {
- rnapi = &tp->napi[1];
+ if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)
+ rnapi = &tp->napi[1];
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
tnapi = &tp->napi[1];
}
@@ -12332,6 +12548,11 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
}
}
+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
+ tp->pci_chip_rev_id != CHIPREV_ID_57765_A0))
+ tp->phy_flags |= TG3_PHYFLG_EEE_CAP;
+
if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) &&
!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
@@ -12403,14 +12624,18 @@ skip_phy_reset:
static void __devinit tg3_read_vpd(struct tg3 *tp)
{
- u8 vpd_data[TG3_NVM_VPD_LEN];
+ 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_not_found;
+ goto out_no_vpd;
+
+ vpd_data = kmalloc(TG3_NVM_VPD_LEN, GFP_KERNEL);
+ if (!vpd_data)
+ goto out_no_vpd;
if (magic == TG3_EEPROM_MAGIC) {
for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
@@ -12494,43 +12719,51 @@ partno:
memcpy(tp->board_part_number, &vpd_data[i], len);
- return;
-
out_not_found:
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+ kfree(vpd_data);
+ if (tp->board_part_number[0])
+ return;
+
+out_no_vpd:
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717)
+ strcpy(tp->board_part_number, "BCM5717");
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718)
+ strcpy(tp->board_part_number, "BCM5718");
+ else
+ goto nomatch;
+ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780)
+ strcpy(tp->board_part_number, "BCM57780");
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760)
+ strcpy(tp->board_part_number, "BCM57760");
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790)
+ strcpy(tp->board_part_number, "BCM57790");
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788)
+ strcpy(tp->board_part_number, "BCM57788");
+ else
+ goto nomatch;
+ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761)
+ strcpy(tp->board_part_number, "BCM57761");
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765)
+ strcpy(tp->board_part_number, "BCM57765");
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781)
+ strcpy(tp->board_part_number, "BCM57781");
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785)
+ strcpy(tp->board_part_number, "BCM57785");
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791)
+ strcpy(tp->board_part_number, "BCM57791");
+ else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795)
+ strcpy(tp->board_part_number, "BCM57795");
+ else
+ goto nomatch;
+ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
strcpy(tp->board_part_number, "BCM95906");
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780)
- strcpy(tp->board_part_number, "BCM57780");
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760)
- strcpy(tp->board_part_number, "BCM57760");
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790)
- strcpy(tp->board_part_number, "BCM57790");
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788)
- strcpy(tp->board_part_number, "BCM57788");
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761)
- strcpy(tp->board_part_number, "BCM57761");
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765)
- strcpy(tp->board_part_number, "BCM57765");
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781)
- strcpy(tp->board_part_number, "BCM57781");
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785)
- strcpy(tp->board_part_number, "BCM57785");
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791)
- strcpy(tp->board_part_number, "BCM57791");
- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795)
- strcpy(tp->board_part_number, "BCM57795");
- else
+ } else {
+nomatch:
strcpy(tp->board_part_number, "none");
+ }
}
static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
@@ -12639,6 +12872,9 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
case TG3_EEPROM_SB_REVISION_5:
offset = TG3_EEPROM_SB_F1R5_EDH_OFF;
break;
+ case TG3_EEPROM_SB_REVISION_6:
+ offset = TG3_EEPROM_SB_F1R6_EDH_OFF;
+ break;
default:
return;
}
@@ -12738,10 +12974,12 @@ 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)
+ if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) {
+ tp->tg3_flags3 |= TG3_FLG3_APE_HAS_NCSI;
fwtype = "NCSI";
- else
+ } else {
fwtype = "DASH";
+ }
vlen = strlen(tp->fw_ver);
@@ -12797,6 +13035,18 @@ static void inline vlan_features_add(struct net_device *dev, unsigned long flags
#endif
}
+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;
+ else
+ return 512;
+}
+
static int __devinit tg3_get_invariants(struct tg3 *tp)
{
static struct pci_device_id write_reorder_chipsets[] = {
@@ -12841,7 +13091,6 @@ 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_5724 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719)
pci_read_config_dword(tp->pdev,
TG3PCI_GEN2_PRODID_ASICREV,
@@ -13412,10 +13661,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (err)
return err;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
- tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
- return -ENOTSUPP;
-
/* Initialize data/descriptor byte/word swapping. */
val = tr32(GRC_MODE);
val &= GRC_MODE_HOST_STACKUP;
@@ -13555,7 +13800,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
#endif
}
- tp->rx_std_max_post = TG3_RX_RING_SIZE;
+ tp->rx_std_ring_mask = TG3_RX_STD_RING_SIZE(tp) - 1;
+ tp->rx_jmb_ring_mask = TG3_RX_JMB_RING_SIZE(tp) - 1;
+ tp->rx_ret_ring_mask = tg3_rx_ret_ring_size(tp) - 1;
+
+ tp->rx_std_max_post = tp->rx_std_ring_mask + 1;
/* Increment the rx prod index on the rx std ring by at most
* 8 for these chips to workaround hw errata.
@@ -14444,7 +14693,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
}
if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
- tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 &&
+ 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
@@ -14583,7 +14832,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
- for (i = 0; i < TG3_IRQ_MAX_VECS; i++) {
+ for (i = 0; i < tp->irq_max; i++) {
struct tg3_napi *tnapi = &tp->napi[i];
tnapi->tp = tp;
@@ -14598,13 +14847,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tnapi->consmbox = rcvmbx;
tnapi->prodmbox = sndmbx;
- if (i) {
+ if (i)
tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1);
- netif_napi_add(dev, &tnapi->napi, tg3_poll_msix, 64);
- } else {
+ else
tnapi->coal_now = HOSTCC_MODE_NOW;
- netif_napi_add(dev, &tnapi->napi, tg3_poll, 64);
- }
if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
break;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index be7ff138a7f9..4a1974804b9f 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -26,6 +26,7 @@
#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 */
/* First 256 bytes are a mirror of PCI config space. */
@@ -46,7 +47,6 @@
#define TG3PCI_DEVICE_TIGON3_5785_F 0x16a0 /* 10/100 only */
#define TG3PCI_DEVICE_TIGON3_5717 0x1655
#define TG3PCI_DEVICE_TIGON3_5718 0x1656
-#define TG3PCI_DEVICE_TIGON3_5724 0x165c
#define TG3PCI_DEVICE_TIGON3_57781 0x16b1
#define TG3PCI_DEVICE_TIGON3_57785 0x16b5
#define TG3PCI_DEVICE_TIGON3_57761 0x16b0
@@ -973,6 +973,7 @@
#define RCVDBDI_MODE_JUMBOBD_NEEDED 0x00000004
#define RCVDBDI_MODE_FRM_TOO_BIG 0x00000008
#define RCVDBDI_MODE_INV_RING_SZ 0x00000010
+#define RCVDBDI_MODE_LRG_RING_SZ 0x00010000
#define RCVDBDI_STATUS 0x00002404
#define RCVDBDI_STATUS_JUMBOBD_NEEDED 0x00000004
#define RCVDBDI_STATUS_FRM_TOO_BIG 0x00000008
@@ -1090,7 +1091,26 @@
#define CPMU_MUTEX_GNT_DRIVER 0x00001000
#define TG3_CPMU_PHY_STRAP 0x00003664
#define TG3_CPMU_PHY_STRAP_IS_SERDES 0x00000020
-/* 0x3664 --> 0x3800 unused */
+/* 0x3664 --> 0x36b0 unused */
+
+#define TG3_CPMU_EEE_MODE 0x000036b0
+#define TG3_CPMU_EEEMD_ERLY_L1_XIT_DET 0x00000008
+#define TG3_CPMU_EEEMD_LPI_ENABLE 0x00000080
+#define TG3_CPMU_EEEMD_LPI_IN_TX 0x00000100
+#define TG3_CPMU_EEEMD_LPI_IN_RX 0x00000200
+#define TG3_CPMU_EEEMD_EEE_ENABLE 0x00100000
+/* 0x36b4 --> 0x36b8 unused */
+
+#define TG3_CPMU_EEE_LNKIDL_CTRL 0x000036bc
+#define TG3_CPMU_EEE_LNKIDL_PCIE_NL0 0x01000000
+#define TG3_CPMU_EEE_LNKIDL_UART_IDL 0x00000004
+/* 0x36c0 --> 0x36d0 unused */
+
+#define TG3_CPMU_EEE_CTRL 0x000036d0
+#define TG3_CPMU_EEE_CTRL_EXIT_16_5_US 0x0000019d
+#define TG3_CPMU_EEE_CTRL_EXIT_36_US 0x00000384
+#define TG3_CPMU_EEE_CTRL_EXIT_20_1_US 0x000001f8
+/* 0x36d4 --> 0x3800 unused */
/* Mbuf cluster free registers */
#define MBFREE_MODE 0x00003800
@@ -1225,6 +1245,7 @@
#define BUFMGR_MODE_ATTN_ENABLE 0x00000004
#define BUFMGR_MODE_BM_TEST 0x00000008
#define BUFMGR_MODE_MBLOW_ATTN_ENAB 0x00000010
+#define BUFMGR_MODE_NO_TX_UNDERRUN 0x80000000
#define BUFMGR_STATUS 0x00004404
#define BUFMGR_STATUS_ERROR 0x00000004
#define BUFMGR_STATUS_MBLOW 0x00000010
@@ -1302,7 +1323,16 @@
#define RDMAC_STATUS_FIFOURUN 0x00000080
#define RDMAC_STATUS_FIFOOREAD 0x00000100
#define RDMAC_STATUS_LNGREAD 0x00000200
-/* 0x4808 --> 0x4c00 unused */
+/* 0x4808 --> 0x4900 unused */
+
+#define TG3_RDMA_RSRVCTRL_REG 0x00004900
+#define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004
+/* 0x4904 --> 0x4910 unused */
+
+#define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910
+#define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K 0x00030000
+#define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K 0x000c0000
+/* 0x4914 --> 0x4c00 unused */
/* Write DMA control registers */
#define WDMAC_MODE 0x00004c00
@@ -1904,6 +1934,7 @@
#define TG3_EEPROM_SB_REVISION_3 0x00030000
#define TG3_EEPROM_SB_REVISION_4 0x00040000
#define TG3_EEPROM_SB_REVISION_5 0x00050000
+#define TG3_EEPROM_SB_REVISION_6 0x00060000
#define TG3_EEPROM_MAGIC_HW 0xabcd
#define TG3_EEPROM_MAGIC_HW_MSK 0xffff
@@ -1923,6 +1954,7 @@
#define TG3_EEPROM_SB_F1R3_EDH_OFF 0x18
#define TG3_EEPROM_SB_F1R4_EDH_OFF 0x1c
#define TG3_EEPROM_SB_F1R5_EDH_OFF 0x20
+#define TG3_EEPROM_SB_F1R6_EDH_OFF 0x4c
#define TG3_EEPROM_SB_EDH_MAJ_MASK 0x00000700
#define TG3_EEPROM_SB_EDH_MAJ_SHFT 8
#define TG3_EEPROM_SB_EDH_MIN_MASK 0x000000ff
@@ -2048,6 +2080,10 @@
#define MII_TG3_CTRL_AS_MASTER 0x0800
#define MII_TG3_CTRL_ENABLE_AS_MASTER 0x1000
+#define MII_TG3_MMD_CTRL 0x0d /* MMD Access Control register */
+#define MII_TG3_MMD_CTRL_DATA_NOINC 0x4000
+#define MII_TG3_MMD_ADDRESS 0x0e /* MMD Address Data register */
+
#define MII_TG3_EXT_CTRL 0x10 /* Extended control register */
#define MII_TG3_EXT_CTRL_FIFO_ELASTIC 0x0001
#define MII_TG3_EXT_CTRL_LNK3_LED_MODE 0x0002
@@ -2065,6 +2101,8 @@
#define MII_TG3_DSP_TAP1 0x0001
#define MII_TG3_DSP_TAP1_AGCTGT_DFLT 0x0007
#define MII_TG3_DSP_AADJ1CH0 0x001f
+#define MII_TG3_DSP_CH34TP2 0x4022
+#define MII_TG3_DSP_CH34TP2_HIBW01 0x0010
#define MII_TG3_DSP_AADJ1CH3 0x601f
#define MII_TG3_DSP_AADJ1CH3_ADCCKADJ 0x0002
#define MII_TG3_DSP_EXP1_INT_STAT 0x0f01
@@ -2131,6 +2169,14 @@
#define MII_TG3_TEST1_TRIM_EN 0x0010
#define MII_TG3_TEST1_CRC_EN 0x8000
+/* Clause 45 expansion registers */
+#define TG3_CL45_D7_EEEADV_CAP 0x003c
+#define TG3_CL45_D7_EEEADV_CAP_100TX 0x0002
+#define TG3_CL45_D7_EEEADV_CAP_1000T 0x0004
+#define TG3_CL45_D7_EEERES_STAT 0x803e
+#define TG3_CL45_D7_EEERES_STAT_LP_100TX 0x0002
+#define TG3_CL45_D7_EEERES_STAT_LP_1000T 0x0004
+
/* Fast Ethernet Tranceiver definitions */
#define MII_TG3_FET_PTEST 0x17
@@ -2176,7 +2222,7 @@
#define TG3_APE_HOST_SEG_SIG 0x4200
#define APE_HOST_SEG_SIG_MAGIC 0x484f5354
#define TG3_APE_HOST_SEG_LEN 0x4204
-#define APE_HOST_SEG_LEN_MAGIC 0x0000001c
+#define APE_HOST_SEG_LEN_MAGIC 0x00000020
#define TG3_APE_HOST_INIT_COUNT 0x4208
#define TG3_APE_HOST_DRIVER_ID 0x420c
#define APE_HOST_DRIVER_ID_LINUX 0xf0000000
@@ -2188,6 +2234,12 @@
#define APE_HOST_HEARTBEAT_INT_DISABLE 0
#define APE_HOST_HEARTBEAT_INT_5SEC 5000
#define TG3_APE_HOST_HEARTBEAT_COUNT 0x4218
+#define TG3_APE_HOST_DRVR_STATE 0x421c
+#define TG3_APE_HOST_DRVR_STATE_START 0x00000001
+#define TG3_APE_HOST_DRVR_STATE_UNLOAD 0x00000002
+#define TG3_APE_HOST_DRVR_STATE_WOL 0x00000003
+#define TG3_APE_HOST_WOL_SPEED 0x4224
+#define TG3_APE_HOST_WOL_SPEED_AUTO 0x00008000
#define TG3_APE_EVENT_STATUS 0x4300
@@ -2649,7 +2701,8 @@ struct tg3_rx_prodring_set {
dma_addr_t rx_jmb_mapping;
};
-#define TG3_IRQ_MAX_VECS 5
+#define TG3_IRQ_MAX_VECS_RSS 5
+#define TG3_IRQ_MAX_VECS TG3_IRQ_MAX_VECS_RSS
struct tg3_napi {
struct napi_struct napi ____cacheline_aligned;
@@ -2668,7 +2721,7 @@ struct tg3_napi {
u32 consmbox;
u32 rx_rcb_ptr;
u16 *rx_rcb_prod_idx;
- struct tg3_rx_prodring_set *prodring;
+ struct tg3_rx_prodring_set prodring;
struct tg3_rx_buffer_desc *rx_rcb;
struct tg3_tx_buffer_desc *tx_ring;
@@ -2746,6 +2799,9 @@ struct tg3 {
void (*write32_rx_mbox) (struct tg3 *, u32,
u32);
u32 rx_copy_thresh;
+ u32 rx_std_ring_mask;
+ u32 rx_jmb_ring_mask;
+ u32 rx_ret_ring_mask;
u32 rx_pending;
u32 rx_jumbo_pending;
u32 rx_std_max_post;
@@ -2755,8 +2811,6 @@ struct tg3 {
struct vlan_group *vlgrp;
#endif
- struct tg3_rx_prodring_set prodring[TG3_IRQ_MAX_VECS];
-
/* begin "everything else" cacheline(s) section */
unsigned long rx_dropped;
@@ -2850,6 +2904,7 @@ struct tg3 {
#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;
@@ -2966,9 +3021,11 @@ struct tg3 {
#define TG3_PHYFLG_BER_BUG 0x00008000
#define TG3_PHYFLG_SERDES_PREEMPHASIS 0x00010000
#define TG3_PHYFLG_PARALLEL_DETECT 0x00020000
+#define TG3_PHYFLG_EEE_CAP 0x00040000
u32 led_ctrl;
u32 phy_otp;
+ u32 setlpicnt;
#define TG3_BPN_SIZE 24
char board_part_number[TG3_BPN_SIZE];
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index ccee3eddc5f4..ec8c804a795d 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -393,7 +393,7 @@ TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type )
spin_unlock_irqrestore(&priv->lock, flags);
return;
}
- priv->timer.function = &TLan_Timer;
+ priv->timer.function = TLan_Timer;
if (!in_irq())
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1453,7 +1453,7 @@ static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
TLan_DioWrite8( dev->base_addr,
TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
if ( priv->timer.function == NULL ) {
- priv->timer.function = &TLan_Timer;
+ priv->timer.function = TLan_Timer;
priv->timer.data = (unsigned long) dev;
priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
priv->timerSetAt = jiffies;
@@ -1601,7 +1601,7 @@ drop_and_reuse:
TLan_DioWrite8( dev->base_addr,
TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
if ( priv->timer.function == NULL ) {
- priv->timer.function = &TLan_Timer;
+ priv->timer.function = TLan_Timer;
priv->timer.data = (unsigned long) dev;
priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
priv->timerSetAt = jiffies;
@@ -1897,7 +1897,7 @@ static void TLan_Timer( unsigned long data )
TLan_DioWrite8( dev->base_addr,
TLAN_LED_REG, TLAN_LED_LINK );
} else {
- priv->timer.function = &TLan_Timer;
+ priv->timer.function = TLan_Timer;
priv->timer.expires = priv->timerSetAt
+ TLAN_TIMER_ACT_DELAY;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -3187,7 +3187,7 @@ static int TLan_EeSendByte( u16 io_base, u8 data, int stop )
TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
}
- return ( err );
+ return err;
} /* TLan_EeSendByte */
diff --git a/drivers/net/tlan.h b/drivers/net/tlan.h
index d13ff12d7500..3315ced774e2 100644
--- a/drivers/net/tlan.h
+++ b/drivers/net/tlan.h
@@ -442,7 +442,7 @@ typedef struct tlan_private_tag {
static inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr)
{
outw(internal_addr, base_addr + TLAN_DIO_ADR);
- return (inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3)));
+ return inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3));
} /* TLan_DioRead8 */
@@ -452,7 +452,7 @@ static inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr)
static inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr)
{
outw(internal_addr, base_addr + TLAN_DIO_ADR);
- return (inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2)));
+ return inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2));
} /* TLan_DioRead16 */
@@ -462,7 +462,7 @@ static inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr)
static inline u32 TLan_DioRead32(u16 base_addr, u16 internal_addr)
{
outw(internal_addr, base_addr + TLAN_DIO_ADR);
- return (inl(base_addr + TLAN_DIO_DATA));
+ return inl(base_addr + TLAN_DIO_DATA);
} /* TLan_DioRead32 */
@@ -537,6 +537,6 @@ static inline u32 TLan_HashFunc( const u8 *a )
hash ^= ((a[2]^a[5])<<4); /* & 060 */
hash ^= ((a[2]^a[5])>>2); /* & 077 */
- return (hash & 077);
+ return hash & 077;
}
#endif
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
index 16e8783ee9cd..8d362e64a40e 100644
--- a/drivers/net/tokenring/proteon.c
+++ b/drivers/net/tokenring/proteon.c
@@ -110,7 +110,7 @@ static int __init proteon_probe1(struct net_device *dev, int ioaddr)
}
dev->base_addr = ioaddr;
- return (0);
+ return 0;
nodev:
release_region(ioaddr, PROTEON_IO_EXTENT);
return -ENODEV;
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index 0929fff5982c..63db5a6762ae 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -435,7 +435,7 @@ static int smctr_alloc_shared_memory(struct net_device *dev)
RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[NON_MAC_QUEUE]);
tp->rx_buff_end[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
- return (0);
+ return 0;
}
/* Enter Bypass state. */
@@ -448,7 +448,7 @@ static int smctr_bypass_state(struct net_device *dev)
err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_BYPASS_STATE);
- return (err);
+ return err;
}
static int smctr_checksum_firmware(struct net_device *dev)
@@ -471,9 +471,9 @@ static int smctr_checksum_firmware(struct net_device *dev)
smctr_disable_adapter_ctrl_store(dev);
if(checksum)
- return (checksum);
+ return checksum;
- return (0);
+ return 0;
}
static int __init smctr_chk_mca(struct net_device *dev)
@@ -485,7 +485,7 @@ static int __init smctr_chk_mca(struct net_device *dev)
current_slot = mca_find_unused_adapter(smctr_posid, 0);
if(current_slot == MCA_NOTFOUND)
- return (-ENODEV);
+ return -ENODEV;
mca_set_adapter_name(current_slot, smctr_name);
mca_mark_as_used(current_slot);
@@ -622,9 +622,9 @@ static int __init smctr_chk_mca(struct net_device *dev)
break;
}
- return (0);
+ return 0;
#else
- return (-1);
+ return -1;
#endif /* CONFIG_MCA_LEGACY */
}
@@ -677,18 +677,18 @@ static int smctr_chg_rx_mask(struct net_device *dev)
if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_0,
&tp->config_word0)))
{
- return (err);
+ return err;
}
if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_1,
&tp->config_word1)))
{
- return (err);
+ return err;
}
smctr_disable_16bit(dev);
- return (0);
+ return 0;
}
static int smctr_clear_int(struct net_device *dev)
@@ -697,7 +697,7 @@ static int smctr_clear_int(struct net_device *dev)
outb((tp->trc_mask | CSR_CLRTINT), dev->base_addr + CSR);
- return (0);
+ return 0;
}
static int smctr_clear_trc_reset(int ioaddr)
@@ -707,7 +707,7 @@ static int smctr_clear_trc_reset(int ioaddr)
r = inb(ioaddr + MSR);
outb(~MSR_RST & r, ioaddr + MSR);
- return (0);
+ return 0;
}
/*
@@ -725,7 +725,7 @@ static int smctr_close(struct net_device *dev)
/* Check to see if adapter is already in a closed state. */
if(tp->status != OPEN)
- return (0);
+ return 0;
smctr_enable_16bit(dev);
smctr_set_page(dev, (__u8 *)tp->ram_access);
@@ -733,7 +733,7 @@ static int smctr_close(struct net_device *dev)
if((err = smctr_issue_remove_cmd(dev)))
{
smctr_disable_16bit(dev);
- return (err);
+ return err;
}
for(;;)
@@ -746,7 +746,7 @@ static int smctr_close(struct net_device *dev)
}
- return (0);
+ return 0;
}
static int smctr_decode_firmware(struct net_device *dev,
@@ -807,12 +807,12 @@ static int smctr_decode_firmware(struct net_device *dev,
if(buff)
*(mem++) = SWAP_BYTES(buff);
- return (0);
+ return 0;
}
static int smctr_disable_16bit(struct net_device *dev)
{
- return (0);
+ return 0;
}
/*
@@ -832,7 +832,7 @@ static int smctr_disable_adapter_ctrl_store(struct net_device *dev)
tp->trc_mask |= CSR_WCSS;
outb(tp->trc_mask, ioaddr + CSR);
- return (0);
+ return 0;
}
static int smctr_disable_bic_int(struct net_device *dev)
@@ -844,7 +844,7 @@ static int smctr_disable_bic_int(struct net_device *dev)
| CSR_MSKTINT | CSR_WCSS;
outb(tp->trc_mask, ioaddr + CSR);
- return (0);
+ return 0;
}
static int smctr_enable_16bit(struct net_device *dev)
@@ -858,7 +858,7 @@ static int smctr_enable_16bit(struct net_device *dev)
outb((r | LAAR_MEM16ENB), dev->base_addr + LAAR);
}
- return (0);
+ return 0;
}
/*
@@ -881,7 +881,7 @@ static int smctr_enable_adapter_ctrl_store(struct net_device *dev)
tp->trc_mask &= ~CSR_WCSS;
outb(tp->trc_mask, ioaddr + CSR);
- return (0);
+ return 0;
}
static int smctr_enable_adapter_ram(struct net_device *dev)
@@ -895,7 +895,7 @@ static int smctr_enable_adapter_ram(struct net_device *dev)
r = inb(ioaddr + MSR);
outb(MSR_MEMB | r, ioaddr + MSR);
- return (0);
+ return 0;
}
static int smctr_enable_bic_int(struct net_device *dev)
@@ -921,7 +921,7 @@ static int smctr_enable_bic_int(struct net_device *dev)
break;
}
- return (0);
+ return 0;
}
static int __init smctr_chk_isa(struct net_device *dev)
@@ -1145,7 +1145,7 @@ static int __init smctr_chk_isa(struct net_device *dev)
*/
}
- return (0);
+ return 0;
out2:
release_region(ioaddr, SMCTR_IO_EXTENT);
@@ -1199,7 +1199,7 @@ static int __init smctr_get_boardid(struct net_device *dev, int mca)
* return;
*/
if(IdByte & 0xF8)
- return (-1);
+ return -1;
r1 = inb(ioaddr + BID_REG_1);
r1 &= BID_ICR_MASK;
@@ -1250,21 +1250,21 @@ static int __init smctr_get_boardid(struct net_device *dev, int mca)
while(r1 & BID_RECALL_DONE_MASK)
r1 = inb(ioaddr + BID_REG_1);
- return (BoardIdMask);
+ return BoardIdMask;
}
static int smctr_get_group_address(struct net_device *dev)
{
smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_GROUP_ADDR);
- return(smctr_wait_cmd(dev));
+ return smctr_wait_cmd(dev);
}
static int smctr_get_functional_address(struct net_device *dev)
{
smctr_issue_read_word_cmd(dev, RW_FUNCTIONAL_ADDR);
- return(smctr_wait_cmd(dev));
+ return smctr_wait_cmd(dev);
}
/* Calculate number of Non-MAC receive BDB's and data buffers.
@@ -1346,14 +1346,14 @@ static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev)
*/
mem_used += 0x100;
- return((0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock)));
+ return (0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock));
}
static int smctr_get_physical_drop_number(struct net_device *dev)
{
smctr_issue_read_word_cmd(dev, RW_PHYSICAL_DROP_NUMBER);
- return(smctr_wait_cmd(dev));
+ return smctr_wait_cmd(dev);
}
static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue)
@@ -1366,14 +1366,14 @@ static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue)
tp->rx_fcb_curr[queue]->bdb_ptr = bdb;
- return ((__u8 *)bdb->data_block_ptr);
+ return (__u8 *)bdb->data_block_ptr;
}
static int smctr_get_station_id(struct net_device *dev)
{
smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_MAC_ADDRESS);
- return(smctr_wait_cmd(dev));
+ return smctr_wait_cmd(dev);
}
/*
@@ -1384,7 +1384,7 @@ static struct net_device_stats *smctr_get_stats(struct net_device *dev)
{
struct net_local *tp = netdev_priv(dev);
- return ((struct net_device_stats *)&tp->MacStat);
+ return (struct net_device_stats *)&tp->MacStat;
}
static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
@@ -1401,14 +1401,14 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
/* check if there is enough FCB blocks */
if(tp->num_tx_fcbs_used[queue] >= tp->num_tx_fcbs[queue])
- return ((FCBlock *)(-1L));
+ return (FCBlock *)(-1L);
/* round off the input pkt size to the nearest even number */
alloc_size = (bytes_count + 1) & 0xfffe;
/* check if enough mem */
if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue])
- return ((FCBlock *)(-1L));
+ return (FCBlock *)(-1L);
/* check if past the end ;
* if exactly enough mem to end of ring, alloc from front.
@@ -1425,7 +1425,7 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
if((tp->tx_buff_used[queue] + alloc_size)
> tp->tx_buff_size[queue])
{
- return ((FCBlock *)(-1L));
+ return (FCBlock *)(-1L);
}
/* ring wrap */
@@ -1448,14 +1448,14 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
pFCB = tp->tx_fcb_curr[queue];
tp->tx_fcb_curr[queue] = tp->tx_fcb_curr[queue]->next_ptr;
- return (pFCB);
+ return pFCB;
}
static int smctr_get_upstream_neighbor_addr(struct net_device *dev)
{
smctr_issue_read_word_cmd(dev, RW_UPSTREAM_NEIGHBOR_ADDRESS);
- return(smctr_wait_cmd(dev));
+ return smctr_wait_cmd(dev);
}
static int smctr_hardware_send_packet(struct net_device *dev,
@@ -1469,21 +1469,22 @@ static int smctr_hardware_send_packet(struct net_device *dev,
printk(KERN_DEBUG"%s: smctr_hardware_send_packet\n", dev->name);
if(tp->status != OPEN)
- return (-1);
+ return -1;
if(tp->monitor_state_ready != 1)
- return (-1);
+ return -1;
for(;;)
{
/* Send first buffer from queue */
skb = skb_dequeue(&tp->SendSkbQueue);
if(skb == NULL)
- return (-1);
+ return -1;
tp->QueueSkb++;
- if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size) return (-1);
+ if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size)
+ return -1;
smctr_enable_16bit(dev);
smctr_set_page(dev, (__u8 *)tp->ram_access);
@@ -1492,7 +1493,7 @@ static int smctr_hardware_send_packet(struct net_device *dev,
== (FCBlock *)(-1L))
{
smctr_disable_16bit(dev);
- return (-1);
+ return -1;
}
smctr_tx_move_frame(dev, skb,
@@ -1508,7 +1509,7 @@ static int smctr_hardware_send_packet(struct net_device *dev,
smctr_disable_16bit(dev);
}
- return (0);
+ return 0;
}
static int smctr_init_acbs(struct net_device *dev)
@@ -1552,7 +1553,7 @@ static int smctr_init_acbs(struct net_device *dev)
tp->acb_curr = tp->acb_head->next_ptr;
tp->num_acbs_used = 0;
- return (0);
+ return 0;
}
static int smctr_init_adapter(struct net_device *dev)
@@ -1590,13 +1591,14 @@ static int smctr_init_adapter(struct net_device *dev)
if(smctr_checksum_firmware(dev))
{
- printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name); return (-ENOENT);
+ printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name);
+ return -ENOENT;
}
if((err = smctr_ram_memory_test(dev)))
{
printk(KERN_ERR "%s: RAM memory test failed.\n", dev->name);
- return (-EIO);
+ return -EIO;
}
smctr_set_rx_look_ahead(dev);
@@ -1608,7 +1610,7 @@ static int smctr_init_adapter(struct net_device *dev)
{
printk(KERN_ERR "%s: Initialization of card failed (%d)\n",
dev->name, err);
- return (-EINVAL);
+ return -EINVAL;
}
/* This routine clobbers the TRC's internal registers. */
@@ -1616,7 +1618,7 @@ static int smctr_init_adapter(struct net_device *dev)
{
printk(KERN_ERR "%s: Card failed internal self test (%d)\n",
dev->name, err);
- return (-EINVAL);
+ return -EINVAL;
}
/* Re-Initialize adapter's internal registers */
@@ -1625,17 +1627,17 @@ static int smctr_init_adapter(struct net_device *dev)
{
printk(KERN_ERR "%s: Initialization of card failed (%d)\n",
dev->name, err);
- return (-EINVAL);
+ return -EINVAL;
}
smctr_enable_bic_int(dev);
if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK)))
- return (err);
+ return err;
smctr_disable_16bit(dev);
- return (0);
+ return 0;
}
static int smctr_init_card_real(struct net_device *dev)
@@ -1703,15 +1705,15 @@ static int smctr_init_card_real(struct net_device *dev)
smctr_init_shared_memory(dev);
if((err = smctr_issue_init_timers_cmd(dev)))
- return (err);
+ return err;
if((err = smctr_issue_init_txrx_cmd(dev)))
{
printk(KERN_ERR "%s: Hardware failure\n", dev->name);
- return (err);
+ return err;
}
- return (0);
+ return 0;
}
static int smctr_init_rx_bdbs(struct net_device *dev)
@@ -1763,7 +1765,7 @@ static int smctr_init_rx_bdbs(struct net_device *dev)
tp->rx_bdb_curr[i] = tp->rx_bdb_head[i]->next_ptr;
}
- return (0);
+ return 0;
}
static int smctr_init_rx_fcbs(struct net_device *dev)
@@ -1813,7 +1815,7 @@ static int smctr_init_rx_fcbs(struct net_device *dev)
tp->rx_fcb_curr[i] = tp->rx_fcb_head[i]->next_ptr;
}
- return(0);
+ return 0;
}
static int smctr_init_shared_memory(struct net_device *dev)
@@ -1871,7 +1873,7 @@ static int smctr_init_shared_memory(struct net_device *dev)
smctr_init_rx_bdbs(dev);
smctr_init_rx_fcbs(dev);
- return (0);
+ return 0;
}
static int smctr_init_tx_bdbs(struct net_device *dev)
@@ -1901,7 +1903,7 @@ static int smctr_init_tx_bdbs(struct net_device *dev)
tp->tx_bdb_head[i]->back_ptr = bdb;
}
- return (0);
+ return 0;
}
static int smctr_init_tx_fcbs(struct net_device *dev)
@@ -1940,7 +1942,7 @@ static int smctr_init_tx_fcbs(struct net_device *dev)
tp->num_tx_fcbs_used[i] = 0;
}
- return (0);
+ return 0;
}
static int smctr_internal_self_test(struct net_device *dev)
@@ -1949,33 +1951,33 @@ static int smctr_internal_self_test(struct net_device *dev)
int err;
if((err = smctr_issue_test_internal_rom_cmd(dev)))
- return (err);
+ return err;
if((err = smctr_wait_cmd(dev)))
- return (err);
+ return err;
if(tp->acb_head->cmd_done_status & 0xff)
- return (-1);
+ return -1;
if((err = smctr_issue_test_hic_cmd(dev)))
- return (err);
+ return err;
if((err = smctr_wait_cmd(dev)))
- return (err);
+ return err;
if(tp->acb_head->cmd_done_status & 0xff)
- return (-1);
+ return -1;
if((err = smctr_issue_test_mac_reg_cmd(dev)))
- return (err);
+ return err;
if((err = smctr_wait_cmd(dev)))
- return (err);
+ return err;
if(tp->acb_head->cmd_done_status & 0xff)
- return (-1);
+ return -1;
- return (0);
+ return 0;
}
/*
@@ -2468,14 +2470,14 @@ static int smctr_issue_enable_int_cmd(struct net_device *dev,
int err;
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
tp->sclb_ptr->int_mask_control = interrupt_enable_mask;
tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK;
smctr_set_ctrl_attention(dev);
- return (0);
+ return 0;
}
static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits)
@@ -2483,7 +2485,7 @@ static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ib
struct net_local *tp = netdev_priv(dev);
if(smctr_wait_while_cbusy(dev))
- return (-1);
+ return -1;
tp->sclb_ptr->int_mask_control = ibits;
tp->sclb_ptr->iack_code = iack_code << 1; /* use the offset from base */ tp->sclb_ptr->resume_control = 0;
@@ -2491,7 +2493,7 @@ static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ib
smctr_set_ctrl_attention(dev);
- return (0);
+ return 0;
}
static int smctr_issue_init_timers_cmd(struct net_device *dev)
@@ -2502,10 +2504,10 @@ static int smctr_issue_init_timers_cmd(struct net_device *dev)
__u16 *pTimer_Struc = (__u16 *)tp->misc_command_data;
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
if((err = smctr_wait_cmd(dev)))
- return (err);
+ return err;
tp->config_word0 = THDREN | DMA_TRIGGER | USETPT | NO_AUTOREMOVE;
tp->config_word1 = 0;
@@ -2648,7 +2650,7 @@ static int smctr_issue_init_timers_cmd(struct net_device *dev)
err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TRC_TIMERS, 0);
- return (err);
+ return err;
}
static int smctr_issue_init_txrx_cmd(struct net_device *dev)
@@ -2659,12 +2661,12 @@ static int smctr_issue_init_txrx_cmd(struct net_device *dev)
void **txrx_ptrs = (void *)tp->misc_command_data;
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
if((err = smctr_wait_cmd(dev)))
{
printk(KERN_ERR "%s: Hardware failure\n", dev->name);
- return (err);
+ return err;
}
/* Initialize Transmit Queue Pointers that are used, to point to
@@ -2695,7 +2697,7 @@ static int smctr_issue_init_txrx_cmd(struct net_device *dev)
err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TX_RX, 0);
- return (err);
+ return err;
}
static int smctr_issue_insert_cmd(struct net_device *dev)
@@ -2704,7 +2706,7 @@ static int smctr_issue_insert_cmd(struct net_device *dev)
err = smctr_setup_single_cmd(dev, ACB_CMD_INSERT, ACB_SUB_CMD_NOP);
- return (err);
+ return err;
}
static int smctr_issue_read_ring_status_cmd(struct net_device *dev)
@@ -2712,15 +2714,15 @@ static int smctr_issue_read_ring_status_cmd(struct net_device *dev)
int err;
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
if((err = smctr_wait_cmd(dev)))
- return (err);
+ return err;
err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_READ_TRC_STATUS,
RW_TRC_STATUS_BLOCK);
- return (err);
+ return err;
}
static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt)
@@ -2728,15 +2730,15 @@ static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt)
int err;
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
if((err = smctr_wait_cmd(dev)))
- return (err);
+ return err;
err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_READ_VALUE,
aword_cnt);
- return (err);
+ return err;
}
static int smctr_issue_remove_cmd(struct net_device *dev)
@@ -2745,14 +2747,14 @@ static int smctr_issue_remove_cmd(struct net_device *dev)
int err;
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
tp->sclb_ptr->resume_control = 0;
tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_REMOVE;
smctr_set_ctrl_attention(dev);
- return (0);
+ return 0;
}
static int smctr_issue_resume_acb_cmd(struct net_device *dev)
@@ -2761,7 +2763,7 @@ static int smctr_issue_resume_acb_cmd(struct net_device *dev)
int err;
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
tp->sclb_ptr->resume_control = SCLB_RC_ACB;
tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID;
@@ -2770,7 +2772,7 @@ static int smctr_issue_resume_acb_cmd(struct net_device *dev)
smctr_set_ctrl_attention(dev);
- return (0);
+ return 0;
}
static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue)
@@ -2779,7 +2781,7 @@ static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue)
int err;
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
if(queue == MAC_QUEUE)
tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_BDB;
@@ -2790,7 +2792,7 @@ static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue)
smctr_set_ctrl_attention(dev);
- return (0);
+ return 0;
}
static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue)
@@ -2801,7 +2803,7 @@ static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue)
printk(KERN_DEBUG "%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name);
if(smctr_wait_while_cbusy(dev))
- return (-1);
+ return -1;
if(queue == MAC_QUEUE)
tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_FCB;
@@ -2812,7 +2814,7 @@ static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue)
smctr_set_ctrl_attention(dev);
- return (0);
+ return 0;
}
static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue)
@@ -2823,14 +2825,14 @@ static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue)
printk(KERN_DEBUG "%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name);
if(smctr_wait_while_cbusy(dev))
- return (-1);
+ return -1;
tp->sclb_ptr->resume_control = (SCLB_RC_TFCB0 << queue);
tp->sclb_ptr->valid_command = SCLB_RESUME_CONTROL_VALID | SCLB_VALID;
smctr_set_ctrl_attention(dev);
- return (0);
+ return 0;
}
static int smctr_issue_test_internal_rom_cmd(struct net_device *dev)
@@ -2840,7 +2842,7 @@ static int smctr_issue_test_internal_rom_cmd(struct net_device *dev)
err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
TRC_INTERNAL_ROM_TEST);
- return (err);
+ return err;
}
static int smctr_issue_test_hic_cmd(struct net_device *dev)
@@ -2850,7 +2852,7 @@ static int smctr_issue_test_hic_cmd(struct net_device *dev)
err = smctr_setup_single_cmd(dev, ACB_CMD_HIC_TEST,
TRC_HOST_INTERFACE_REG_TEST);
- return (err);
+ return err;
}
static int smctr_issue_test_mac_reg_cmd(struct net_device *dev)
@@ -2860,7 +2862,7 @@ static int smctr_issue_test_mac_reg_cmd(struct net_device *dev)
err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
TRC_MAC_REGISTERS_TEST);
- return (err);
+ return err;
}
static int smctr_issue_trc_loopback_cmd(struct net_device *dev)
@@ -2870,7 +2872,7 @@ static int smctr_issue_trc_loopback_cmd(struct net_device *dev)
err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
TRC_INTERNAL_LOOPBACK);
- return (err);
+ return err;
}
static int smctr_issue_tri_loopback_cmd(struct net_device *dev)
@@ -2880,7 +2882,7 @@ static int smctr_issue_tri_loopback_cmd(struct net_device *dev)
err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
TRC_TRI_LOOPBACK);
- return (err);
+ return err;
}
static int smctr_issue_write_byte_cmd(struct net_device *dev,
@@ -2891,10 +2893,10 @@ static int smctr_issue_write_byte_cmd(struct net_device *dev,
int err;
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
if((err = smctr_wait_cmd(dev)))
- return (err);
+ return err;
for(iword = 0, ibyte = 0; iword < (unsigned int)(aword_cnt & 0xff);
iword++, ibyte += 2)
@@ -2903,8 +2905,8 @@ static int smctr_issue_write_byte_cmd(struct net_device *dev,
| (*((__u8 *)byte + ibyte + 1));
}
- return (smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE,
- aword_cnt));
+ return smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE,
+ aword_cnt);
}
static int smctr_issue_write_word_cmd(struct net_device *dev,
@@ -2914,10 +2916,10 @@ static int smctr_issue_write_word_cmd(struct net_device *dev,
unsigned int i, err;
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
if((err = smctr_wait_cmd(dev)))
- return (err);
+ return err;
for(i = 0; i < (unsigned int)(aword_cnt & 0xff); i++)
tp->misc_command_data[i] = *((__u16 *)word + i);
@@ -2925,7 +2927,7 @@ static int smctr_issue_write_word_cmd(struct net_device *dev,
err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE,
aword_cnt);
- return (err);
+ return err;
}
static int smctr_join_complete_state(struct net_device *dev)
@@ -2935,7 +2937,7 @@ static int smctr_join_complete_state(struct net_device *dev)
err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE,
JS_JOIN_COMPLETE_STATE);
- return (err);
+ return err;
}
static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev)
@@ -2959,7 +2961,7 @@ static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev)
}
}
- return (0);
+ return 0;
}
static int smctr_load_firmware(struct net_device *dev)
@@ -2974,7 +2976,7 @@ static int smctr_load_firmware(struct net_device *dev)
if (request_firmware(&fw, "tr_smctr.bin", &dev->dev)) {
printk(KERN_ERR "%s: firmware not found\n", dev->name);
- return (UCODE_NOT_PRESENT);
+ return UCODE_NOT_PRESENT;
}
tp->num_of_tx_buffs = 4;
@@ -3036,7 +3038,7 @@ static int smctr_load_firmware(struct net_device *dev)
smctr_disable_16bit(dev);
out:
release_firmware(fw);
- return (err);
+ return err;
}
static int smctr_load_node_addr(struct net_device *dev)
@@ -3052,7 +3054,7 @@ static int smctr_load_node_addr(struct net_device *dev)
}
dev->addr_len = 6;
- return (0);
+ return 0;
}
/* Lobe Media Test.
@@ -3146,14 +3148,14 @@ static int smctr_lobe_media_test_cmd(struct net_device *dev)
if(smctr_wait_cmd(dev))
{
printk(KERN_ERR "Lobe Failed test state\n");
- return (LOBE_MEDIA_TEST_FAILED);
+ return LOBE_MEDIA_TEST_FAILED;
}
}
err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
TRC_LOBE_MEDIA_TEST);
- return (err);
+ return err;
}
static int smctr_lobe_media_test_state(struct net_device *dev)
@@ -3163,7 +3165,7 @@ static int smctr_lobe_media_test_state(struct net_device *dev)
err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE,
JS_LOBE_TEST_STATE);
- return (err);
+ return err;
}
static int smctr_make_8025_hdr(struct net_device *dev,
@@ -3212,7 +3214,7 @@ static int smctr_make_8025_hdr(struct net_device *dev,
break;
}
- return (0);
+ return 0;
}
static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv)
@@ -3225,7 +3227,7 @@ static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv)
tsv->svv[0] = MSB(tp->authorized_access_priority);
tsv->svv[1] = LSB(tp->authorized_access_priority);
- return (0);
+ return 0;
}
static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv)
@@ -3236,7 +3238,7 @@ static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv)
tsv->svv[0] = 0;
tsv->svv[1] = 0;
- return (0);
+ return 0;
}
static int smctr_make_auth_funct_class(struct net_device *dev,
@@ -3250,7 +3252,7 @@ static int smctr_make_auth_funct_class(struct net_device *dev,
tsv->svv[0] = MSB(tp->authorized_function_classes);
tsv->svv[1] = LSB(tp->authorized_function_classes);
- return (0);
+ return 0;
}
static int smctr_make_corr(struct net_device *dev,
@@ -3262,7 +3264,7 @@ static int smctr_make_corr(struct net_device *dev,
tsv->svv[0] = MSB(correlator);
tsv->svv[1] = LSB(correlator);
- return (0);
+ return 0;
}
static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv)
@@ -3280,7 +3282,7 @@ static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv)
tsv->svv[2] = MSB(tp->misc_command_data[1]);
tsv->svv[3] = LSB(tp->misc_command_data[1]);
- return (0);
+ return 0;
}
static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv)
@@ -3305,7 +3307,7 @@ static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv)
tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00)
tsv->svv[0] = 0x00;
- return (0);
+ return 0;
}
static int smctr_make_phy_drop_num(struct net_device *dev,
@@ -3324,7 +3326,7 @@ static int smctr_make_phy_drop_num(struct net_device *dev,
tsv->svv[2] = MSB(tp->misc_command_data[1]);
tsv->svv[3] = LSB(tp->misc_command_data[1]);
- return (0);
+ return 0;
}
static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv)
@@ -3337,7 +3339,7 @@ static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv)
for(i = 0; i < 18; i++)
tsv->svv[i] = 0xF0;
- return (0);
+ return 0;
}
static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv)
@@ -3358,7 +3360,7 @@ static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv)
tsv->svv[4] = MSB(tp->misc_command_data[2]);
tsv->svv[5] = LSB(tp->misc_command_data[2]);
- return (0);
+ return 0;
}
static int smctr_make_ring_station_status(struct net_device *dev,
@@ -3374,7 +3376,7 @@ static int smctr_make_ring_station_status(struct net_device *dev,
tsv->svv[4] = 0;
tsv->svv[5] = 0;
- return (0);
+ return 0;
}
static int smctr_make_ring_station_version(struct net_device *dev,
@@ -3400,7 +3402,7 @@ static int smctr_make_ring_station_version(struct net_device *dev,
else
tsv->svv[9] = 0xc4; /* EBCDIC - D */
- return (0);
+ return 0;
}
static int smctr_make_tx_status_code(struct net_device *dev,
@@ -3414,7 +3416,7 @@ static int smctr_make_tx_status_code(struct net_device *dev,
/* Stripped frame status of Transmitted Frame */
tsv->svv[1] = tx_fstatus & 0xff;
- return (0);
+ return 0;
}
static int smctr_make_upstream_neighbor_addr(struct net_device *dev,
@@ -3436,7 +3438,7 @@ static int smctr_make_upstream_neighbor_addr(struct net_device *dev,
tsv->svv[4] = MSB(tp->misc_command_data[2]);
tsv->svv[5] = LSB(tp->misc_command_data[2]);
- return (0);
+ return 0;
}
static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv)
@@ -3444,7 +3446,7 @@ static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv)
tsv->svi = WRAP_DATA;
tsv->svl = S_WRAP_DATA;
- return (0);
+ return 0;
}
/*
@@ -3464,9 +3466,9 @@ static int smctr_open(struct net_device *dev)
err = smctr_init_adapter(dev);
if(err < 0)
- return (err);
+ return err;
- return (err);
+ return err;
}
/* Interrupt driven open of Token card. */
@@ -3481,9 +3483,9 @@ static int smctr_open_tr(struct net_device *dev)
/* Now we can actually open the adapter. */
if(tp->status == OPEN)
- return (0);
+ return 0;
if(tp->status != INITIALIZED)
- return (-1);
+ return -1;
/* FIXME: it would work a lot better if we masked the irq sources
on the card here, then we could skip the locking and poll nicely */
@@ -3560,7 +3562,7 @@ static int smctr_open_tr(struct net_device *dev)
out:
spin_unlock_irqrestore(&tp->lock, flags);
- return (err);
+ return err;
}
/* Check for a network adapter of this type,
@@ -3675,7 +3677,7 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
dev->netdev_ops = &smctr_netdev_ops;
dev->watchdog_timeo = HZ;
- return (0);
+ return 0;
out:
return err;
@@ -3699,13 +3701,13 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
case INIT:
if((rcode = smctr_rcv_init(dev, rmf, &correlator)) == HARDWARE_FAILED)
{
- return (rcode);
+ return rcode;
}
if((err = smctr_send_rsp(dev, rmf, rcode,
correlator)))
{
- return (err);
+ return err;
}
break;
@@ -3713,13 +3715,13 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
if((rcode = smctr_rcv_chg_param(dev, rmf,
&correlator)) ==HARDWARE_FAILED)
{
- return (rcode);
+ return rcode;
}
if((err = smctr_send_rsp(dev, rmf, rcode,
correlator)))
{
- return (err);
+ return err;
}
break;
@@ -3728,16 +3730,16 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
rmf, &correlator)) != POSITIVE_ACK)
{
if(rcode == HARDWARE_FAILED)
- return (rcode);
+ return rcode;
else
- return (smctr_send_rsp(dev, rmf,
- rcode, correlator));
+ return smctr_send_rsp(dev, rmf,
+ rcode, correlator);
}
if((err = smctr_send_rpt_addr(dev, rmf,
correlator)))
{
- return (err);
+ return err;
}
break;
@@ -3746,17 +3748,17 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
rmf, &correlator)) != POSITIVE_ACK)
{
if(rcode == HARDWARE_FAILED)
- return (rcode);
+ return rcode;
else
- return (smctr_send_rsp(dev, rmf,
+ return smctr_send_rsp(dev, rmf,
rcode,
- correlator));
+ correlator);
}
if((err = smctr_send_rpt_attch(dev, rmf,
correlator)))
{
- return (err);
+ return err;
}
break;
@@ -3765,17 +3767,17 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
rmf, &correlator)) != POSITIVE_ACK)
{
if(rcode == HARDWARE_FAILED)
- return (rcode);
+ return rcode;
else
- return (smctr_send_rsp(dev, rmf,
+ return smctr_send_rsp(dev, rmf,
rcode,
- correlator));
+ correlator);
}
if((err = smctr_send_rpt_state(dev, rmf,
correlator)))
{
- return (err);
+ return err;
}
break;
@@ -3786,17 +3788,17 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
!= POSITIVE_ACK)
{
if(rcode == HARDWARE_FAILED)
- return (rcode);
+ return rcode;
else
- return (smctr_send_rsp(dev, rmf,
+ return smctr_send_rsp(dev, rmf,
rcode,
- correlator));
+ correlator);
}
if((err = smctr_send_tx_forward(dev, rmf,
&tx_fstatus)) == HARDWARE_FAILED)
{
- return (err);
+ return err;
}
if(err == A_FRAME_WAS_FORWARDED)
@@ -3805,7 +3807,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
rmf, tx_fstatus))
== HARDWARE_FAILED)
{
- return (err);
+ return err;
}
}
break;
@@ -3834,7 +3836,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
if((err = smctr_send_rsp(dev, rmf,rcode,
correlator)))
{
- return (err);
+ return err;
}
}
@@ -3899,7 +3901,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
err = 0;
}
- return (err);
+ return err;
}
/* Adapter RAM test. Incremental word ODD boundary data test. */
@@ -3942,7 +3944,7 @@ static int smctr_ram_memory_test(struct net_device *dev)
err_offset = j;
err_word = word_read;
err_pattern = word_pattern;
- return (RAM_TEST_FAILED);
+ return RAM_TEST_FAILED;
}
}
}
@@ -3966,14 +3968,14 @@ static int smctr_ram_memory_test(struct net_device *dev)
err_offset = j;
err_word = word_read;
err_pattern = word_pattern;
- return (RAM_TEST_FAILED);
+ return RAM_TEST_FAILED;
}
}
}
smctr_set_page(dev, (__u8 *)tp->ram_access);
- return (0);
+ return 0;
}
static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf,
@@ -3986,7 +3988,7 @@ static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf,
/* This Frame can only come from a CRS */
if((rmf->dc_sc & SC_MASK) != SC_CRS)
- return(E_INAPPROPRIATE_SOURCE_CLASS);
+ return E_INAPPROPRIATE_SOURCE_CLASS;
/* Remove MVID Length from total length. */
vlen = (signed short)rmf->vl - 4;
@@ -4058,7 +4060,7 @@ static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf,
}
}
- return (rcode);
+ return rcode;
}
static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf,
@@ -4071,7 +4073,7 @@ static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf,
/* This Frame can only come from a RPS */
if((rmf->dc_sc & SC_MASK) != SC_RPS)
- return (E_INAPPROPRIATE_SOURCE_CLASS);
+ return E_INAPPROPRIATE_SOURCE_CLASS;
/* Remove MVID Length from total length. */
vlen = (signed short)rmf->vl - 4;
@@ -4133,7 +4135,7 @@ static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf,
}
}
- return (rcode);
+ return rcode;
}
static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf)
@@ -4145,7 +4147,7 @@ static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf)
/* This Frame can only come from a CRS */
if((rmf->dc_sc & SC_MASK) != SC_CRS)
- return (E_INAPPROPRIATE_SOURCE_CLASS);
+ return E_INAPPROPRIATE_SOURCE_CLASS;
/* Remove MVID Length from total length */
vlen = (signed short)rmf->vl - 4;
@@ -4193,7 +4195,7 @@ static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf)
}
}
- return (rcode);
+ return rcode;
}
static int smctr_rcv_rq_addr_state_attch(struct net_device *dev,
@@ -4250,7 +4252,7 @@ static int smctr_rcv_rq_addr_state_attch(struct net_device *dev,
}
}
- return (rcode);
+ return rcode;
}
static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf,
@@ -4284,7 +4286,7 @@ static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf,
rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
}
- return (E_UNRECOGNIZED_VECTOR_ID);
+ return E_UNRECOGNIZED_VECTOR_ID;
}
/*
@@ -4311,7 +4313,7 @@ static int smctr_reset_adapter(struct net_device *dev)
*/
outb(tp->trc_mask | CSR_CLRTINT | CSR_CLRCBUSY, ioaddr + CSR);
- return (0);
+ return 0;
}
static int smctr_restart_tx_chain(struct net_device *dev, short queue)
@@ -4329,7 +4331,7 @@ static int smctr_restart_tx_chain(struct net_device *dev, short queue)
err = smctr_issue_resume_tx_fcb_cmd(dev, queue);
}
- return (err);
+ return err;
}
static int smctr_ring_status_chg(struct net_device *dev)
@@ -4371,7 +4373,7 @@ static int smctr_ring_status_chg(struct net_device *dev)
}
if(!(tp->ring_status_flags & RING_STATUS_CHANGED))
- return (0);
+ return 0;
switch(tp->ring_status)
{
@@ -4421,7 +4423,7 @@ static int smctr_ring_status_chg(struct net_device *dev)
break;
}
- return (0);
+ return 0;
}
static int smctr_rx_frame(struct net_device *dev)
@@ -4486,7 +4488,7 @@ static int smctr_rx_frame(struct net_device *dev)
break;
}
- return (err);
+ return err;
}
static int smctr_send_dat(struct net_device *dev)
@@ -4502,7 +4504,7 @@ static int smctr_send_dat(struct net_device *dev)
if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE,
sizeof(MAC_HEADER))) == (FCBlock *)(-1L))
{
- return (OUT_OF_RESOURCES);
+ return OUT_OF_RESOURCES;
}
/* Initialize DAT Data Fields. */
@@ -4524,7 +4526,7 @@ static int smctr_send_dat(struct net_device *dev)
/* Start Transmit. */
if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
- return (err);
+ return err;
/* Wait for Transmit to Complete */
for(i = 0; i < 10000; i++)
@@ -4538,7 +4540,7 @@ static int smctr_send_dat(struct net_device *dev)
if(!(fcb->frame_status & FCB_COMMAND_DONE) ||
fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS))
{
- return (INITIALIZE_FAILED);
+ return INITIALIZE_FAILED;
}
/* De-allocated Tx FCB and Frame Buffer
@@ -4549,7 +4551,7 @@ static int smctr_send_dat(struct net_device *dev)
tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING;
smctr_update_tx_chain(dev, fcb, MAC_QUEUE);
- return (0);
+ return 0;
}
static void smctr_timeout(struct net_device *dev)
@@ -4610,7 +4612,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev)
if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(struct trh_hdr)
+ S_WRAP_DATA + S_WRAP_DATA)) == (FCBlock *)(-1L))
{
- return (OUT_OF_RESOURCES);
+ return OUT_OF_RESOURCES;
}
/* Initialize DAT Data Fields. */
@@ -4639,7 +4641,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev)
/* Start Transmit. */
tmf->vl = SWAP_BYTES(tmf->vl);
if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
- return (err);
+ return err;
/* Wait for Transmit to Complete. (10 ms). */
for(i=0; i < 10000; i++)
@@ -4653,7 +4655,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev)
if(!(fcb->frame_status & FCB_COMMAND_DONE) ||
fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS))
{
- return (LOBE_MEDIA_TEST_FAILED);
+ return LOBE_MEDIA_TEST_FAILED;
}
/* De-allocated Tx FCB and Frame Buffer
@@ -4664,7 +4666,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev)
tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING;
smctr_update_tx_chain(dev, fcb, MAC_QUEUE);
- return (0);
+ return 0;
}
static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf,
@@ -4679,7 +4681,7 @@ static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf,
+ S_ADDRESS_MODIFER + S_GROUP_ADDRESS + S_FUNCTIONAL_ADDRESS))
== (FCBlock *)(-1L))
{
- return (0);
+ return 0;
}
tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
@@ -4722,7 +4724,7 @@ static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf,
*/
tmf->vl = SWAP_BYTES(tmf->vl);
- return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE));
+ return smctr_trc_send_packet(dev, fcb, MAC_QUEUE);
}
static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf,
@@ -4737,7 +4739,7 @@ static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf,
+ S_AUTHORIZED_FUNCTION_CLASS + S_AUTHORIZED_ACCESS_PRIORITY))
== (FCBlock *)(-1L))
{
- return (0);
+ return 0;
}
tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
@@ -4776,7 +4778,7 @@ static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf,
*/
tmf->vl = SWAP_BYTES(tmf->vl);
- return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE));
+ return smctr_trc_send_packet(dev, fcb, MAC_QUEUE);
}
static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf,
@@ -4791,7 +4793,7 @@ static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf,
+ S_RING_STATION_STATUS + S_STATION_IDENTIFER))
== (FCBlock *)(-1L))
{
- return (0);
+ return 0;
}
tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
@@ -4826,7 +4828,7 @@ static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf,
*/
tmf->vl = SWAP_BYTES(tmf->vl);
- return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE));
+ return smctr_trc_send_packet(dev, fcb, MAC_QUEUE);
}
static int smctr_send_rpt_tx_forward(struct net_device *dev,
@@ -4839,7 +4841,7 @@ static int smctr_send_rpt_tx_forward(struct net_device *dev,
if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
+ S_TRANSMIT_STATUS_CODE)) == (FCBlock *)(-1L))
{
- return (0);
+ return 0;
}
tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
@@ -4862,7 +4864,7 @@ static int smctr_send_rpt_tx_forward(struct net_device *dev,
*/
tmf->vl = SWAP_BYTES(tmf->vl);
- return(smctr_trc_send_packet(dev, fcb, MAC_QUEUE));
+ return smctr_trc_send_packet(dev, fcb, MAC_QUEUE);
}
static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf,
@@ -4875,7 +4877,7 @@ static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf,
if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
+ S_CORRELATOR + S_RESPONSE_CODE)) == (FCBlock *)(-1L))
{
- return (0);
+ return 0;
}
tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
@@ -4888,7 +4890,7 @@ static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf,
tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
smctr_make_corr(dev, tsv, correlator);
- return (0);
+ return 0;
}
static int smctr_send_rq_init(struct net_device *dev)
@@ -4907,7 +4909,7 @@ static int smctr_send_rq_init(struct net_device *dev)
+ S_RING_STATION_VERSION_NUMBER + S_ADDRESS_MODIFER))
== (FCBlock *)(-1L)))
{
- return (0);
+ return 0;
}
tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
@@ -4943,7 +4945,7 @@ static int smctr_send_rq_init(struct net_device *dev)
tmf->vl = SWAP_BYTES(tmf->vl);
if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
- return (err);
+ return err;
/* Wait for Transmit to Complete */
for(i = 0; i < 10000; i++)
@@ -4957,7 +4959,7 @@ static int smctr_send_rq_init(struct net_device *dev)
fstatus = fcb->frame_status;
if(!(fstatus & FCB_COMMAND_DONE))
- return (HARDWARE_FAILED);
+ return HARDWARE_FAILED;
if(!(fstatus & FCB_TX_STATUS_E))
count++;
@@ -4971,7 +4973,7 @@ static int smctr_send_rq_init(struct net_device *dev)
smctr_update_tx_chain(dev, fcb, MAC_QUEUE);
} while(count < 4 && ((fstatus & FCB_TX_AC_BITS) ^ FCB_TX_AC_BITS));
- return (smctr_join_complete_state(dev));
+ return smctr_join_complete_state(dev);
}
static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf,
@@ -4984,13 +4986,13 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf,
/* Check if this is the END POINT of the Transmit Forward Chain. */
if(rmf->vl <= 18)
- return (0);
+ return 0;
/* Allocate Transmit FCB only by requesting 0 bytes
* of data buffer.
*/
if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, 0)) == (FCBlock *)(-1L))
- return (0);
+ return 0;
/* Set pointer to Transmit Frame Buffer to the data
* portion of the received TX Forward frame, making
@@ -5006,7 +5008,7 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf,
fcb->bdb_ptr->buffer_length = rmf->vl - 4 - 2;
if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
- return (err);
+ return err;
/* Wait for Transmit to Complete */
for(i = 0; i < 10000; i++)
@@ -5020,7 +5022,7 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf,
if(!(fcb->frame_status & FCB_COMMAND_DONE))
{
if((err = smctr_issue_resume_tx_fcb_cmd(dev, MAC_QUEUE)))
- return (err);
+ return err;
for(i = 0; i < 10000; i++)
{
@@ -5030,12 +5032,12 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf,
}
if(!(fcb->frame_status & FCB_COMMAND_DONE))
- return (HARDWARE_FAILED);
+ return HARDWARE_FAILED;
}
*tx_fstatus = fcb->frame_status;
- return (A_FRAME_WAS_FORWARDED);
+ return A_FRAME_WAS_FORWARDED;
}
static int smctr_set_auth_access_pri(struct net_device *dev,
@@ -5044,11 +5046,11 @@ static int smctr_set_auth_access_pri(struct net_device *dev,
struct net_local *tp = netdev_priv(dev);
if(rsv->svl != S_AUTHORIZED_ACCESS_PRIORITY)
- return (E_SUB_VECTOR_LENGTH_ERROR);
+ return E_SUB_VECTOR_LENGTH_ERROR;
tp->authorized_access_priority = (rsv->svv[0] << 8 | rsv->svv[1]);
- return (POSITIVE_ACK);
+ return POSITIVE_ACK;
}
static int smctr_set_auth_funct_class(struct net_device *dev,
@@ -5057,22 +5059,22 @@ static int smctr_set_auth_funct_class(struct net_device *dev,
struct net_local *tp = netdev_priv(dev);
if(rsv->svl != S_AUTHORIZED_FUNCTION_CLASS)
- return (E_SUB_VECTOR_LENGTH_ERROR);
+ return E_SUB_VECTOR_LENGTH_ERROR;
tp->authorized_function_classes = (rsv->svv[0] << 8 | rsv->svv[1]);
- return (POSITIVE_ACK);
+ return POSITIVE_ACK;
}
static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv,
__u16 *correlator)
{
if(rsv->svl != S_CORRELATOR)
- return (E_SUB_VECTOR_LENGTH_ERROR);
+ return E_SUB_VECTOR_LENGTH_ERROR;
*correlator = (rsv->svv[0] << 8 | rsv->svv[1]);
- return (POSITIVE_ACK);
+ return POSITIVE_ACK;
}
static int smctr_set_error_timer_value(struct net_device *dev,
@@ -5082,34 +5084,34 @@ static int smctr_set_error_timer_value(struct net_device *dev,
int err;
if(rsv->svl != S_ERROR_TIMER_VALUE)
- return (E_SUB_VECTOR_LENGTH_ERROR);
+ return E_SUB_VECTOR_LENGTH_ERROR;
err_tval = (rsv->svv[0] << 8 | rsv->svv[1])*10;
smctr_issue_write_word_cmd(dev, RW_TER_THRESHOLD, &err_tval);
if((err = smctr_wait_cmd(dev)))
- return (err);
+ return err;
- return (POSITIVE_ACK);
+ return POSITIVE_ACK;
}
static int smctr_set_frame_forward(struct net_device *dev,
MAC_SUB_VECTOR *rsv, __u8 dc_sc)
{
if((rsv->svl < 2) || (rsv->svl > S_FRAME_FORWARD))
- return (E_SUB_VECTOR_LENGTH_ERROR);
+ return E_SUB_VECTOR_LENGTH_ERROR;
if((dc_sc & DC_MASK) != DC_CRS)
{
if(rsv->svl >= 2 && rsv->svl < 20)
- return (E_TRANSMIT_FORWARD_INVALID);
+ return E_TRANSMIT_FORWARD_INVALID;
if((rsv->svv[0] != 0) || (rsv->svv[1] != 0))
- return (E_TRANSMIT_FORWARD_INVALID);
+ return E_TRANSMIT_FORWARD_INVALID;
}
- return (POSITIVE_ACK);
+ return POSITIVE_ACK;
}
static int smctr_set_local_ring_num(struct net_device *dev,
@@ -5118,13 +5120,13 @@ static int smctr_set_local_ring_num(struct net_device *dev,
struct net_local *tp = netdev_priv(dev);
if(rsv->svl != S_LOCAL_RING_NUMBER)
- return (E_SUB_VECTOR_LENGTH_ERROR);
+ return E_SUB_VECTOR_LENGTH_ERROR;
if(tp->ptr_local_ring_num)
*(__u16 *)(tp->ptr_local_ring_num)
= (rsv->svv[0] << 8 | rsv->svv[1]);
- return (POSITIVE_ACK);
+ return POSITIVE_ACK;
}
static unsigned short smctr_set_ctrl_attention(struct net_device *dev)
@@ -5140,7 +5142,7 @@ static unsigned short smctr_set_ctrl_attention(struct net_device *dev)
outb(tp->trc_mask, ioaddr + CSR);
}
- return (0);
+ return 0;
}
static void smctr_set_multicast_list(struct net_device *dev)
@@ -5159,7 +5161,7 @@ static int smctr_set_page(struct net_device *dev, __u8 *buf)
amask = (__u8)((tptr & PR_PAGE_MASK) >> 8);
outb(amask, dev->base_addr + PR);
- return (0);
+ return 0;
}
static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv)
@@ -5167,13 +5169,13 @@ static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv)
int err;
if(rsv->svl != S_PHYSICAL_DROP)
- return (E_SUB_VECTOR_LENGTH_ERROR);
+ return E_SUB_VECTOR_LENGTH_ERROR;
smctr_issue_write_byte_cmd(dev, RW_PHYSICAL_DROP_NUMBER, &rsv->svv[0]);
if((err = smctr_wait_cmd(dev)))
- return (err);
+ return err;
- return (POSITIVE_ACK);
+ return POSITIVE_ACK;
}
/* Reset the ring speed to the opposite of what it was. This auto-pilot
@@ -5195,16 +5197,16 @@ static int smctr_set_ring_speed(struct net_device *dev)
smctr_reset_adapter(dev);
if((err = smctr_init_card_real(dev)))
- return (err);
+ return err;
smctr_enable_bic_int(dev);
if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK)))
- return (err);
+ return err;
smctr_disable_16bit(dev);
- return (0);
+ return 0;
}
static int smctr_set_rx_look_ahead(struct net_device *dev)
@@ -5233,7 +5235,7 @@ static int smctr_set_rx_look_ahead(struct net_device *dev)
*((__u16 *)(tp->ram_access)) = sword;
}
- return (0);
+ return 0;
}
static int smctr_set_trc_reset(int ioaddr)
@@ -5243,7 +5245,7 @@ static int smctr_set_trc_reset(int ioaddr)
r = inb(ioaddr + MSR);
outb(MSR_RST | r, ioaddr + MSR);
- return (0);
+ return 0;
}
/*
@@ -5259,10 +5261,10 @@ static int smctr_setup_single_cmd(struct net_device *dev,
printk(KERN_DEBUG "%s: smctr_setup_single_cmd\n", dev->name);
if((err = smctr_wait_while_cbusy(dev)))
- return (err);
+ return err;
if((err = (unsigned int)smctr_wait_cmd(dev)))
- return (err);
+ return err;
tp->acb_head->cmd_done_status = 0;
tp->acb_head->cmd = command;
@@ -5270,7 +5272,7 @@ static int smctr_setup_single_cmd(struct net_device *dev,
err = smctr_issue_resume_acb_cmd(dev);
- return (err);
+ return err;
}
/*
@@ -5287,7 +5289,7 @@ static int smctr_setup_single_cmd_w_data(struct net_device *dev,
tp->acb_head->data_offset_lo
= (__u16)TRC_POINTER(tp->misc_command_data);
- return(smctr_issue_resume_acb_cmd(dev));
+ return smctr_issue_resume_acb_cmd(dev);
}
static char *smctr_malloc(struct net_device *dev, __u16 size)
@@ -5298,7 +5300,7 @@ static char *smctr_malloc(struct net_device *dev, __u16 size)
m = (char *)(tp->ram_access + tp->sh_mem_used);
tp->sh_mem_used += (__u32)size;
- return (m);
+ return m;
}
static int smctr_status_chg(struct net_device *dev)
@@ -5333,7 +5335,7 @@ static int smctr_status_chg(struct net_device *dev)
break;
}
- return (0);
+ return 0;
}
static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb,
@@ -5355,7 +5357,7 @@ static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb,
err = smctr_issue_resume_tx_fcb_cmd(dev, queue);
}
- return (err);
+ return err;
}
static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue)
@@ -5409,7 +5411,7 @@ static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue)
break;
}
- return (err);
+ return err;
}
static unsigned short smctr_tx_move_frame(struct net_device *dev,
@@ -5450,7 +5452,7 @@ static unsigned short smctr_tx_move_frame(struct net_device *dev,
pbuff += len;
}
- return (0);
+ return 0;
}
/* Update the error statistic counters for this adapter. */
@@ -5493,7 +5495,7 @@ static int smctr_update_err_stats(struct net_device *dev)
if(tstat->token_errors)
tstat->token_errors += *(tp->misc_command_data + 5) >> 8;
- return (0);
+ return 0;
}
static int smctr_update_rx_chain(struct net_device *dev, __u16 queue)
@@ -5530,7 +5532,7 @@ static int smctr_update_rx_chain(struct net_device *dev, __u16 queue)
tp->rx_bdb_curr[queue]->back_ptr->info = BDB_NOT_CHAIN_END;
tp->rx_bdb_curr[queue] = bdb;
- return (0);
+ return 0;
}
static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb,
@@ -5542,13 +5544,13 @@ static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb,
printk(KERN_DEBUG "smctr_update_tx_chain\n");
if(tp->num_tx_fcbs_used[queue] <= 0)
- return (HARDWARE_FAILED);
+ return HARDWARE_FAILED;
else
{
if(tp->tx_buff_used[queue] < fcb->memory_alloc)
{
tp->tx_buff_used[queue] = 0;
- return (HARDWARE_FAILED);
+ return HARDWARE_FAILED;
}
tp->tx_buff_used[queue] -= fcb->memory_alloc;
@@ -5566,7 +5568,7 @@ static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb,
fcb->frame_status = 0;
tp->tx_fcb_end[queue] = fcb->next_ptr;
netif_wake_queue(dev);
- return (0);
+ return 0;
}
}
@@ -5587,12 +5589,12 @@ static int smctr_wait_cmd(struct net_device *dev)
}
if(loop_count == 0)
- return(HARDWARE_FAILED);
+ return HARDWARE_FAILED;
if(tp->acb_head->cmd_done_status & 0xff)
- return(HARDWARE_FAILED);
+ return HARDWARE_FAILED;
- return (0);
+ return 0;
}
static int smctr_wait_while_cbusy(struct net_device *dev)
@@ -5624,9 +5626,9 @@ static int smctr_wait_while_cbusy(struct net_device *dev)
}
if(timeout)
- return (0);
+ return 0;
else
- return (HARDWARE_FAILED);
+ return HARDWARE_FAILED;
}
#ifdef MODULE
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index 435ef7d5470f..c83f4f6e39e1 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -224,7 +224,7 @@ static int madgemc_sifprobe(struct net_device *dev)
chk2 ^= 0x0FE;
if(chk1 != chk2)
- return (-1); /* No adapter */
+ return -1; /* No adapter */
chk1 -= 2;
} while(chk1 != 0); /* Repeat 128 times (all byte values) */
@@ -232,7 +232,7 @@ static int madgemc_sifprobe(struct net_device *dev)
/* Restore the SIFADR value */
SIFWRITEB(old, SIFADR);
- return (0);
+ return 0;
}
#endif
@@ -271,7 +271,7 @@ int tms380tr_open(struct net_device *dev)
{
printk(KERN_INFO "%s: Chipset initialization error\n",
dev->name);
- return (-1);
+ return -1;
}
tp->timer.expires = jiffies + 30*HZ;
@@ -298,7 +298,7 @@ int tms380tr_open(struct net_device *dev)
if(tp->AdapterVirtOpenFlag == 0)
{
tms380tr_disable_interrupts(dev);
- return (-1);
+ return -1;
}
tp->StartTime = jiffies;
@@ -309,7 +309,7 @@ int tms380tr_open(struct net_device *dev)
tp->timer.data = (unsigned long)dev;
add_timer(&tp->timer);
- return (0);
+ return 0;
}
/*
@@ -343,23 +343,23 @@ static int tms380tr_chipset_init(struct net_device *dev)
printk(KERN_DEBUG "%s: Resetting adapter...\n", dev->name);
err = tms380tr_reset_adapter(dev);
if(err < 0)
- return (-1);
+ return -1;
if(tms380tr_debug > 3)
printk(KERN_DEBUG "%s: Bringup diags...\n", dev->name);
err = tms380tr_bringup_diags(dev);
if(err < 0)
- return (-1);
+ return -1;
if(tms380tr_debug > 3)
printk(KERN_DEBUG "%s: Init adapter...\n", dev->name);
err = tms380tr_init_adapter(dev);
if(err < 0)
- return (-1);
+ return -1;
if(tms380tr_debug > 3)
printk(KERN_DEBUG "%s: Done!\n", dev->name);
- return (0);
+ return 0;
}
/*
@@ -877,7 +877,7 @@ static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqTy
IrqType != STS_IRQ_COMMAND_STATUS &&
IrqType != STS_IRQ_RING_STATUS)
{
- return (1); /* SSB not involved. */
+ return 1; /* SSB not involved. */
}
/* Note: All fields of the SSB have been set to all ones (-1) after it
@@ -887,21 +887,21 @@ static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqTy
*/
if(ssb->STS == (unsigned short) -1)
- return (0); /* Command field not yet available. */
+ return 0; /* Command field not yet available. */
if(IrqType == STS_IRQ_COMMAND_STATUS)
- return (1); /* Status fields not always affected. */
+ return 1; /* Status fields not always affected. */
if(ssb->Parm[0] == (unsigned short) -1)
- return (0); /* Status 1 field not yet available. */
+ return 0; /* Status 1 field not yet available. */
if(IrqType == STS_IRQ_RING_STATUS)
- return (1); /* Status 2 & 3 fields not affected. */
+ return 1; /* Status 2 & 3 fields not affected. */
/* Note: At this point, the interrupt is either TRANSMIT or RECEIVE. */
if(ssb->Parm[1] == (unsigned short) -1)
- return (0); /* Status 2 field not yet available. */
+ return 0; /* Status 2 field not yet available. */
if(ssb->Parm[2] == (unsigned short) -1)
- return (0); /* Status 3 field not yet available. */
+ return 0; /* Status 3 field not yet available. */
- return (1); /* All SSB fields have been written by the adapter. */
+ return 1; /* All SSB fields have been written by the adapter. */
}
/*
@@ -1143,7 +1143,7 @@ int tms380tr_close(struct net_device *dev)
#endif
tms380tr_cancel_tx_queue(tp);
- return (0);
+ return 0;
}
/*
@@ -1154,7 +1154,7 @@ static struct net_device_stats *tms380tr_get_stats(struct net_device *dev)
{
struct net_local *tp = netdev_priv(dev);
- return ((struct net_device_stats *)&tp->MacStat);
+ return (struct net_device_stats *)&tp->MacStat;
}
/*
@@ -1256,7 +1256,7 @@ static int tms380tr_reset_adapter(struct net_device *dev)
if (request_firmware(&fw_entry, "tms380tr.bin", tp->pdev) != 0) {
printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n",
dev->name, "tms380tr.bin");
- return (-1);
+ return -1;
}
fw_ptr = (unsigned short *)fw_entry->data;
@@ -1321,16 +1321,14 @@ static int tms380tr_reset_adapter(struct net_device *dev)
/* Clear CPHALT and start BUD */
SIFWRITEW(c, SIFACL);
- if (fw_entry)
- release_firmware(fw_entry);
- return (1);
+ release_firmware(fw_entry);
+ return 1;
}
} while(count == 0);
- if (fw_entry)
- release_firmware(fw_entry);
+ release_firmware(fw_entry);
printk(KERN_INFO "%s: Adapter Download Failed\n", dev->name);
- return (-1);
+ return -1;
}
MODULE_FIRMWARE("tms380tr.bin");
@@ -1365,7 +1363,7 @@ static int tms380tr_bringup_diags(struct net_device *dev)
printk(KERN_DEBUG " %04X\n", Status);
/* BUD successfully completed */
if(Status == STS_INITIALIZE)
- return (1);
+ return 1;
/* Unrecoverable hardware error, BUD not completed? */
} while((loop_cnt > 0) && ((Status & (STS_ERROR | STS_TEST))
!= (STS_ERROR | STS_TEST)));
@@ -1392,7 +1390,7 @@ static int tms380tr_bringup_diags(struct net_device *dev)
else
printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f);
- return (-1);
+ return -1;
}
/*
@@ -1466,7 +1464,7 @@ static int tms380tr_init_adapter(struct net_device *dev)
{
printk(KERN_INFO "%s: DMA failed\n", dev->name);
/* DMA data error: wrong data in SCB */
- return (-1);
+ return -1;
}
i++;
} while(i < 6);
@@ -1475,11 +1473,11 @@ static int tms380tr_init_adapter(struct net_device *dev)
do { /* Test if contents of SSB is valid */
if(SSB_Test[i] != *(sb_ptr + i))
/* DMA data error: wrong data in SSB */
- return (-1);
+ return -1;
i++;
} while (i < 8);
- return (1); /* Adapter successfully initialized */
+ return 1; /* Adapter successfully initialized */
}
else
{
@@ -1490,7 +1488,7 @@ static int tms380tr_init_adapter(struct net_device *dev)
Status &= STS_ERROR_MASK;
/* ShowInitialisationErrorCode(Status); */
printk(KERN_INFO "%s: Status error: %d\n", dev->name, Status);
- return (-1); /* Unrecoverable error */
+ return -1; /* Unrecoverable error */
}
else
{
@@ -1505,7 +1503,7 @@ static int tms380tr_init_adapter(struct net_device *dev)
} while(retry_cnt > 0);
printk(KERN_INFO "%s: Retry exceeded\n", dev->name);
- return (-1);
+ return -1;
}
/*
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
index d4c7c0c0a3d6..d3e788a9cd1c 100644
--- a/drivers/net/tokenring/tmspci.c
+++ b/drivers/net/tokenring/tmspci.c
@@ -125,18 +125,16 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic
dev->irq = pci_irq_line;
dev->dma = 0;
- printk("%s: %s\n", dev->name, cardinfo->name);
- printk("%s: IO: %#4lx IRQ: %d\n",
- dev->name, dev->base_addr, dev->irq);
+ dev_info(&pdev->dev, "%s\n", cardinfo->name);
+ dev_info(&pdev->dev, " IO: %#4lx IRQ: %d\n", dev->base_addr, dev->irq);
tms_pci_read_eeprom(dev);
- printk("%s: Ring Station Address: %pM\n",
- dev->name, dev->dev_addr);
+ dev_info(&pdev->dev, " Ring Station Address: %pM\n", dev->dev_addr);
ret = tmsdev_init(dev, &pdev->dev);
if (ret) {
- printk("%s: unable to get memory for dev->priv.\n", dev->name);
+ dev_info(&pdev->dev, "unable to get memory for dev->priv.\n");
goto err_out_region;
}
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index a03730bd1da5..5c633a32eaeb 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -219,7 +219,7 @@ static int tsi108_read_mii(struct tsi108_prv_data *data, int reg)
if (i == 100)
return 0xffff;
else
- return (TSI_READ_PHY(TSI108_MAC_MII_DATAIN));
+ return TSI_READ_PHY(TSI108_MAC_MII_DATAIN);
}
static void tsi108_write_mii(struct tsi108_prv_data *data,
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig
index 516713fa0a05..f3035951422f 100644
--- a/drivers/net/tulip/Kconfig
+++ b/drivers/net/tulip/Kconfig
@@ -11,8 +11,8 @@ menuconfig NET_TULIP
if NET_TULIP
config DE2104X
- tristate "Early DECchip Tulip (dc2104x) PCI support (EXPERIMENTAL)"
- depends on PCI && EXPERIMENTAL
+ tristate "Early DECchip Tulip (dc2104x) PCI support"
+ depends on PCI
select CRC32
---help---
This driver is developed for the SMC EtherPower series Ethernet
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 6888e3d41462..28e1ffb13db9 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -948,8 +948,9 @@ static void de_set_media (struct de_private *de)
else
macmode &= ~FullDuplex;
- if (netif_msg_link(de)) {
+ 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));
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 75a64c88cf7a..4dbd493b996b 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -1448,7 +1448,7 @@ de4x5_sw_reset(struct net_device *dev)
status = -EIO;
}
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ lp->tx_new = (lp->tx_new + 1) % lp->txRingSize;
lp->tx_old = lp->tx_new;
return status;
@@ -1506,7 +1506,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
lp->stats.tx_bytes += skb->len;
outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ lp->tx_new = (lp->tx_new + 1) % lp->txRingSize;
if (TX_BUFFS_AVAIL) {
netif_start_queue(dev); /* Another pkt may be queued */
@@ -1657,7 +1657,7 @@ de4x5_rx(struct net_device *dev)
}
/* Change buffer ownership for this frame, back to the adapter */
- for (;lp->rx_old!=entry;lp->rx_old=(++lp->rx_old)%lp->rxRingSize) {
+ for (;lp->rx_old!=entry;lp->rx_old=(lp->rx_old + 1)%lp->rxRingSize) {
lp->rx_ring[lp->rx_old].status = cpu_to_le32(R_OWN);
barrier();
}
@@ -1668,7 +1668,7 @@ de4x5_rx(struct net_device *dev)
/*
** Update entry information
*/
- lp->rx_new = (++lp->rx_new) % lp->rxRingSize;
+ lp->rx_new = (lp->rx_new + 1) % lp->rxRingSize;
}
return 0;
@@ -1726,7 +1726,7 @@ de4x5_tx(struct net_device *dev)
}
/* Update all the pointers */
- lp->tx_old = (++lp->tx_old) % lp->txRingSize;
+ lp->tx_old = (lp->tx_old + 1) % lp->txRingSize;
}
/* Any resources available? */
@@ -1801,7 +1801,7 @@ de4x5_rx_ovfc(struct net_device *dev)
for (; (s32)le32_to_cpu(lp->rx_ring[lp->rx_new].status)>=0;) {
lp->rx_ring[lp->rx_new].status = cpu_to_le32(R_OWN);
- lp->rx_new = (++lp->rx_new % lp->rxRingSize);
+ lp->rx_new = (lp->rx_new + 1) % lp->rxRingSize;
}
outl(omr, DE4X5_OMR);
@@ -1932,7 +1932,7 @@ set_multicast_list(struct net_device *dev)
load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
SETUP_FRAME_LEN, (struct sk_buff *)1);
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ lp->tx_new = (lp->tx_new + 1) % lp->txRingSize;
outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */
dev->trans_start = jiffies; /* prevent tx timeout */
}
@@ -3119,7 +3119,7 @@ dc2114x_autoconf(struct net_device *dev)
if (lp->media == _100Mb) {
if ((slnk = test_for_100Mb(dev, 6500)) < 0) {
lp->media = SPD_DET;
- return (slnk & ~TIMER_CB);
+ return slnk & ~TIMER_CB;
}
} else {
if (wait_for_link(dev) < 0) {
@@ -3484,7 +3484,7 @@ is_spd_100(struct net_device *dev)
spd = ((~gep_rd(dev)) & GEP_SLNK);
} else {
if ((lp->ibn == 2) || !lp->asBitValid)
- return ((lp->chipset == DC21143)?(~inl(DE4X5_SISR)&SISR_LS100):0);
+ return (lp->chipset == DC21143) ? (~inl(DE4X5_SISR)&SISR_LS100) : 0;
spd = (lp->asBitValid & (lp->asPolarity ^ (gep_rd(dev) & lp->asBit))) |
(lp->linkOK & ~lp->asBitValid);
@@ -3502,15 +3502,15 @@ is_100_up(struct net_device *dev)
if (lp->useMII) {
/* Double read for sticky bits & temporary drops */
mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII);
- return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS);
+ return mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS;
} else if (!lp->useSROM) { /* de500-xa */
- return ((~gep_rd(dev)) & GEP_SLNK);
+ return (~gep_rd(dev)) & GEP_SLNK;
} else {
if ((lp->ibn == 2) || !lp->asBitValid)
- return ((lp->chipset == DC21143)?(~inl(DE4X5_SISR)&SISR_LS100):0);
+ return (lp->chipset == DC21143) ? (~inl(DE4X5_SISR)&SISR_LS100) : 0;
- return ((lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) |
- (lp->linkOK & ~lp->asBitValid));
+ return (lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) |
+ (lp->linkOK & ~lp->asBitValid);
}
}
@@ -3523,17 +3523,17 @@ is_10_up(struct net_device *dev)
if (lp->useMII) {
/* Double read for sticky bits & temporary drops */
mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII);
- return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS);
+ return mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS;
} else if (!lp->useSROM) { /* de500-xa */
- return ((~gep_rd(dev)) & GEP_LNP);
+ return (~gep_rd(dev)) & GEP_LNP;
} else {
if ((lp->ibn == 2) || !lp->asBitValid)
- return (((lp->chipset & ~0x00ff) == DC2114x) ?
+ return ((lp->chipset & ~0x00ff) == DC2114x) ?
(~inl(DE4X5_SISR)&SISR_LS10):
- 0);
+ 0;
- return ((lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) |
- (lp->linkOK & ~lp->asBitValid));
+ return (lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) |
+ (lp->linkOK & ~lp->asBitValid);
}
}
@@ -3544,7 +3544,7 @@ is_anc_capable(struct net_device *dev)
u_long iobase = dev->base_addr;
if (lp->phy[lp->active].id && (!lp->useSROM || lp->useMII)) {
- return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII));
+ return mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII);
} else if ((lp->chipset & ~0x00ff) == DC2114x) {
return (inl(DE4X5_SISR) & SISR_LPN) >> 12;
} else {
@@ -3568,7 +3568,7 @@ ping_media(struct net_device *dev, int msec)
lp->tmp = lp->tx_new; /* Remember the ring position */
load_packet(dev, lp->frame, TD_LS | TD_FS | sizeof(lp->frame), (struct sk_buff *)1);
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ lp->tx_new = (lp->tx_new + 1) % lp->txRingSize;
outl(POLL_DEMAND, DE4X5_TPD);
}
@@ -4930,7 +4930,7 @@ getfrom_mii(u32 command, u_long ioaddr)
outl(command | MII_MDC, ioaddr);
udelay(1);
- return ((inl(ioaddr) >> 19) & 1);
+ return (inl(ioaddr) >> 19) & 1;
}
/*
@@ -4975,8 +4975,8 @@ mii_get_oui(u_char phyaddr, u_long ioaddr)
a.breg[0]=a.breg[1];
a.breg[1]=i;
- return ((a.reg<<8)|ret); */ /* SEEQ and Cypress way */
-/* return ((r2<<6)|(u_int)(r3>>10)); */ /* NATIONAL and BROADCOM way */
+ return (a.reg<<8)|ret; */ /* SEEQ and Cypress way */
+/* return (r2<<6)|(u_int)(r3>>10); */ /* NATIONAL and BROADCOM way */
return r2; /* (I did it) My way */
}
@@ -5144,7 +5144,7 @@ gep_rd(struct net_device *dev)
if (lp->chipset == DC21140) {
return inl(DE4X5_GEP);
} else if ((lp->chipset & ~0x00ff) == DC2114x) {
- return (inl(DE4X5_SIGR) & 0x000fffff);
+ return inl(DE4X5_SIGR) & 0x000fffff;
}
return 0;
@@ -5417,7 +5417,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
/* Set up the descriptor and give ownership to the card */
load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
SETUP_FRAME_LEN, (struct sk_buff *)1);
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ lp->tx_new = (lp->tx_new + 1) % lp->txRingSize;
outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */
netif_wake_queue(dev); /* Unlock the TX ring */
break;
@@ -5474,7 +5474,8 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
tmp.lval[6] = inl(DE4X5_STRR); j+=4;
tmp.lval[7] = inl(DE4X5_SIGR); j+=4;
ioc->len = j;
- if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
+ if (copy_to_user(ioc->data, tmp.lval, ioc->len))
+ return -EFAULT;
break;
#define DE4X5_DUMP 0x0f /* Dump the DE4X5 Status */
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index 0bc4f3030a80..a9f7d5d1a269 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -599,7 +599,7 @@ static int dmfe_open(struct DEVICE *dev)
init_timer(&db->timer);
db->timer.expires = DMFE_TIMER_WUT + HZ * 2;
db->timer.data = (unsigned long)dev;
- db->timer.function = &dmfe_timer;
+ db->timer.function = dmfe_timer;
add_timer(&db->timer);
return 0;
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index 1faf7a4d7202..0013642903ee 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -180,21 +180,24 @@ int tulip_poll(struct napi_struct *napi, int budget)
dev_warn(&dev->dev,
"Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
status);
- tp->stats.rx_length_errors++;
- }
+ 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);
- tp->stats.rx_errors++; /* end of a packet.*/
- if (pkt_len > 1518 ||
- (status & RxDescRunt))
- tp->stats.rx_length_errors++;
-
- if (status & 0x0004) tp->stats.rx_frame_errors++;
- if (status & 0x0002) tp->stats.rx_crc_errors++;
- if (status & 0x0001) tp->stats.rx_fifo_errors++;
+ dev->stats.rx_errors++; /* end of a packet.*/
+ if (pkt_len > 1518 ||
+ (status & RxDescRunt))
+ dev->stats.rx_length_errors++;
+
+ if (status & 0x0004)
+ dev->stats.rx_frame_errors++;
+ if (status & 0x0002)
+ dev->stats.rx_crc_errors++;
+ if (status & 0x0001)
+ dev->stats.rx_fifo_errors++;
}
} else {
struct sk_buff *skb;
@@ -244,8 +247,8 @@ int tulip_poll(struct napi_struct *napi, int budget)
netif_receive_skb(skb);
- tp->stats.rx_packets++;
- tp->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
}
#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
received++;
@@ -404,20 +407,23 @@ static int tulip_rx(struct net_device *dev)
dev_warn(&dev->dev,
"Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
status);
- tp->stats.rx_length_errors++;
+ 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);
- tp->stats.rx_errors++; /* end of a packet.*/
+ dev->stats.rx_errors++; /* end of a packet.*/
if (pkt_len > 1518 ||
(status & RxDescRunt))
- tp->stats.rx_length_errors++;
- if (status & 0x0004) tp->stats.rx_frame_errors++;
- if (status & 0x0002) tp->stats.rx_crc_errors++;
- if (status & 0x0001) tp->stats.rx_fifo_errors++;
+ dev->stats.rx_length_errors++;
+ if (status & 0x0004)
+ dev->stats.rx_frame_errors++;
+ if (status & 0x0002)
+ dev->stats.rx_crc_errors++;
+ if (status & 0x0001)
+ dev->stats.rx_fifo_errors++;
}
} else {
struct sk_buff *skb;
@@ -467,8 +473,8 @@ static int tulip_rx(struct net_device *dev)
netif_rx(skb);
- tp->stats.rx_packets++;
- tp->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
}
received++;
entry = (++tp->cur_rx) % RX_RING_SIZE;
@@ -602,18 +608,22 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n",
dev->name, status);
#endif
- tp->stats.tx_errors++;
- if (status & 0x4104) tp->stats.tx_aborted_errors++;
- if (status & 0x0C00) tp->stats.tx_carrier_errors++;
- if (status & 0x0200) tp->stats.tx_window_errors++;
- if (status & 0x0002) tp->stats.tx_fifo_errors++;
+ dev->stats.tx_errors++;
+ if (status & 0x4104)
+ dev->stats.tx_aborted_errors++;
+ if (status & 0x0C00)
+ dev->stats.tx_carrier_errors++;
+ if (status & 0x0200)
+ dev->stats.tx_window_errors++;
+ if (status & 0x0002)
+ dev->stats.tx_fifo_errors++;
if ((status & 0x0080) && tp->full_duplex == 0)
- tp->stats.tx_heartbeat_errors++;
+ dev->stats.tx_heartbeat_errors++;
} else {
- tp->stats.tx_bytes +=
+ dev->stats.tx_bytes +=
tp->tx_buffers[entry].skb->len;
- tp->stats.collisions += (status >> 3) & 15;
- tp->stats.tx_packets++;
+ dev->stats.collisions += (status >> 3) & 15;
+ dev->stats.tx_packets++;
}
pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping,
@@ -655,7 +665,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
if (csr5 & AbnormalIntr) { /* Abnormal error summary bit. */
if (csr5 == 0xffffffff)
break;
- if (csr5 & TxJabber) tp->stats.tx_errors++;
+ if (csr5 & TxJabber)
+ dev->stats.tx_errors++;
if (csr5 & TxFIFOUnderflow) {
if ((tp->csr6 & 0xC000) != 0xC000)
tp->csr6 += 0x4000; /* Bump up the Tx threshold */
@@ -672,8 +683,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
}
}
if (csr5 & RxDied) { /* Missed a Rx frame. */
- tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
- tp->stats.rx_errors++;
+ dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
+ dev->stats.rx_errors++;
tulip_start_rxtx(tp);
}
/*
@@ -789,7 +800,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
#endif /* CONFIG_TULIP_NAPI */
if ((missed = ioread32(ioaddr + CSR8) & 0x1ffff)) {
- tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
+ dev->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
}
if (tulip_debug > 4)
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index e525875ed67d..ed66a16711dc 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -417,7 +417,6 @@ struct tulip_private {
int revision;
int flags;
struct napi_struct napi;
- struct net_device_stats stats;
struct timer_list timer; /* Media selection timer. */
struct timer_list oom_timer; /* Out of memory timer. */
u32 mc_filter[2];
@@ -570,7 +569,7 @@ static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __io
/* Trigger an immediate transmit demand. */
iowrite32(0, ioaddr + CSR1);
- tp->stats.tx_errors++;
+ tp->dev->stats.tx_errors++;
}
#endif /* __NET_TULIP_H__ */
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 3a8d7efa2acf..2c39f2591216 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -725,7 +725,7 @@ static void tulip_clean_tx_ring(struct tulip_private *tp)
int status = le32_to_cpu(tp->tx_ring[entry].status);
if (status < 0) {
- tp->stats.tx_errors++; /* It wasn't Txed */
+ tp->dev->stats.tx_errors++; /* It wasn't Txed */
tp->tx_ring[entry].status = 0;
}
@@ -781,8 +781,8 @@ static void tulip_down (struct net_device *dev)
/* release any unconsumed transmit buffers */
tulip_clean_tx_ring(tp);
- if (ioread32 (ioaddr + CSR6) != 0xffffffff)
- tp->stats.rx_missed_errors += ioread32 (ioaddr + CSR8) & 0xffff;
+ if (ioread32(ioaddr + CSR6) != 0xffffffff)
+ dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
spin_unlock_irqrestore (&tp->lock, flags);
@@ -864,12 +864,12 @@ static struct net_device_stats *tulip_get_stats(struct net_device *dev)
spin_lock_irqsave (&tp->lock, flags);
- tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
+ dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
spin_unlock_irqrestore(&tp->lock, flags);
}
- return &tp->stats;
+ return &dev->stats;
}
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 96de5829b940..74217dbf0143 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -480,7 +480,7 @@ static int uli526x_open(struct net_device *dev)
init_timer(&db->timer);
db->timer.expires = ULI526X_TIMER_WUT + HZ * 2;
db->timer.data = (unsigned long)dev;
- db->timer.function = &uli526x_timer;
+ db->timer.function = uli526x_timer;
add_timer(&db->timer);
return 0;
@@ -1747,7 +1747,7 @@ static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset)
if(cr10_value&0x10000000)
break;
}
- return (cr10_value&0x0ffff);
+ return cr10_value & 0x0ffff;
}
static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data)
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 66d41cf8da29..f0b231035dee 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -662,7 +662,7 @@ static int netdev_open(struct net_device *dev)
init_timer(&np->timer);
np->timer.expires = jiffies + 1*HZ;
np->timer.data = (unsigned long)dev;
- np->timer.function = &netdev_timer; /* timer handler */
+ np->timer.function = netdev_timer; /* timer handler */
add_timer(&np->timer);
return 0;
out_err:
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
index a439e93be22d..5a73752be2ca 100644
--- a/drivers/net/tulip/xircom_cb.c
+++ b/drivers/net/tulip/xircom_cb.c
@@ -29,7 +29,6 @@
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/init.h>
-#include <linux/ethtool.h>
#include <linux/bitops.h>
#include <asm/uaccess.h>
@@ -181,19 +180,6 @@ static void print_binary(unsigned int number)
}
#endif
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct xircom_private *private = netdev_priv(dev);
-
- strcpy(info->driver, "xircom_cb");
- strcpy(info->bus_info, pci_name(private->pdev));
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
static const struct net_device_ops netdev_ops = {
.ndo_open = xircom_open,
.ndo_stop = xircom_close,
@@ -279,7 +265,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
setup_descriptors(private);
dev->netdev_ops = &netdev_ops;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
pci_set_drvdata(pdev, dev);
if (register_netdev(dev)) {
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 2e50077ff450..1cc67138adbf 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -541,7 +541,7 @@ cleanup:
indexes->respCleared = cpu_to_le32(cleared);
wmb();
- return (resp_save == NULL);
+ return resp_save == NULL;
}
static inline int
@@ -962,36 +962,34 @@ typhoon_do_get_stats(struct typhoon *tp)
* The extra status reported would be a good candidate for
* ethtool_ops->get_{strings,stats}()
*/
- stats->tx_packets = le32_to_cpu(s->txPackets);
- stats->tx_bytes = le64_to_cpu(s->txBytes);
- stats->tx_errors = le32_to_cpu(s->txCarrierLost);
- stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost);
- stats->collisions = le32_to_cpu(s->txMultipleCollisions);
- stats->rx_packets = le32_to_cpu(s->rxPacketsGood);
- stats->rx_bytes = le64_to_cpu(s->rxBytesGood);
- stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns);
+ stats->tx_packets = le32_to_cpu(s->txPackets) +
+ saved->tx_packets;
+ stats->tx_bytes = le64_to_cpu(s->txBytes) +
+ saved->tx_bytes;
+ stats->tx_errors = le32_to_cpu(s->txCarrierLost) +
+ saved->tx_errors;
+ stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost) +
+ saved->tx_carrier_errors;
+ stats->collisions = le32_to_cpu(s->txMultipleCollisions) +
+ saved->collisions;
+ stats->rx_packets = le32_to_cpu(s->rxPacketsGood) +
+ saved->rx_packets;
+ stats->rx_bytes = le64_to_cpu(s->rxBytesGood) +
+ saved->rx_bytes;
+ stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns) +
+ saved->rx_fifo_errors;
stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) +
- le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors);
- stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors);
- stats->rx_length_errors = le32_to_cpu(s->rxOversized);
+ le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors) +
+ saved->rx_errors;
+ stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors) +
+ saved->rx_crc_errors;
+ stats->rx_length_errors = le32_to_cpu(s->rxOversized) +
+ saved->rx_length_errors;
tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ?
SPEED_100 : SPEED_10;
tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ?
DUPLEX_FULL : DUPLEX_HALF;
- /* add in the saved statistics
- */
- stats->tx_packets += saved->tx_packets;
- stats->tx_bytes += saved->tx_bytes;
- stats->tx_errors += saved->tx_errors;
- stats->collisions += saved->collisions;
- stats->rx_packets += saved->rx_packets;
- stats->rx_bytes += saved->rx_bytes;
- stats->rx_fifo_errors += saved->rx_fifo_errors;
- stats->rx_errors += saved->rx_errors;
- stats->rx_crc_errors += saved->rx_crc_errors;
- stats->rx_length_errors += saved->rx_length_errors;
-
return 0;
}
@@ -1762,7 +1760,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read
(TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) {
new_skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
- new_skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(new_skb);
spin_lock(&tp->state_lock);
if(tp->vlgrp != NULL && rx->rxStatus & TYPHOON_RX_VLAN)
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index d7b7018a1de1..52ffabe6db0e 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -358,6 +358,14 @@ config USB_NET_ZAURUS
really need this non-conformant variant of CDC Ethernet (or in
some cases CDC MDLM) protocol, not "g_ether".
+config USB_NET_CX82310_ETH
+ tristate "Conexant CX82310 USB ethernet port"
+ depends on USB_USBNET
+ help
+ Choose this option if you're using a Conexant CX82310-based ADSL
+ router with USB ethernet port. This driver is for routers only,
+ it will not work with ADSL modems (use cxacru driver instead).
+
config USB_HSO
tristate "Option USB High Speed Mobile Devices"
depends on USB && RFKILL
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index b13a279663ba..a19b0259ae16 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -25,4 +25,5 @@ obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o
obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o
obj-$(CONFIG_USB_IPHETH) += ipheth.o
obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
+obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o
diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c
new file mode 100644
index 000000000000..8969f124c18c
--- /dev/null
+++ b/drivers/net/usb/cx82310_eth.c
@@ -0,0 +1,346 @@
+/*
+ * Driver for USB ethernet port of Conexant CX82310-based ADSL routers
+ * Copyright (C) 2010 by Ondrej Zary
+ * some parts inspired by the cxacru driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/usbnet.h>
+
+enum cx82310_cmd {
+ CMD_START = 0x84, /* no effect? */
+ CMD_STOP = 0x85, /* no effect? */
+ CMD_GET_STATUS = 0x90, /* returns nothing? */
+ CMD_GET_MAC_ADDR = 0x91, /* read MAC address */
+ CMD_GET_LINK_STATUS = 0x92, /* not useful, link is always up */
+ CMD_ETHERNET_MODE = 0x99, /* unknown, needed during init */
+};
+
+enum cx82310_status {
+ STATUS_UNDEFINED,
+ STATUS_SUCCESS,
+ STATUS_ERROR,
+ STATUS_UNSUPPORTED,
+ STATUS_UNIMPLEMENTED,
+ STATUS_PARAMETER_ERROR,
+ STATUS_DBG_LOOPBACK,
+};
+
+#define CMD_PACKET_SIZE 64
+/* first command after power on can take around 8 seconds */
+#define CMD_TIMEOUT 15000
+#define CMD_REPLY_RETRY 5
+
+#define CX82310_MTU 1514
+#define CMD_EP 0x01
+
+/*
+ * execute control command
+ * - optionally send some data (command parameters)
+ * - optionally wait for the reply
+ * - optionally read some data from the reply
+ */
+static int cx82310_cmd(struct usbnet *dev, enum cx82310_cmd cmd, bool reply,
+ u8 *wdata, int wlen, u8 *rdata, int rlen)
+{
+ int actual_len, retries, ret;
+ struct usb_device *udev = dev->udev;
+ u8 *buf = kzalloc(CMD_PACKET_SIZE, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+
+ /* create command packet */
+ buf[0] = cmd;
+ if (wdata)
+ memcpy(buf + 4, wdata, min_t(int, wlen, CMD_PACKET_SIZE - 4));
+
+ /* send command packet */
+ ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, CMD_EP), buf,
+ CMD_PACKET_SIZE, &actual_len, CMD_TIMEOUT);
+ if (ret < 0) {
+ dev_err(&dev->udev->dev, "send command %#x: error %d\n",
+ cmd, ret);
+ goto end;
+ }
+
+ if (reply) {
+ /* wait for reply, retry if it's empty */
+ for (retries = 0; retries < CMD_REPLY_RETRY; retries++) {
+ ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, CMD_EP),
+ buf, CMD_PACKET_SIZE, &actual_len,
+ CMD_TIMEOUT);
+ if (ret < 0) {
+ dev_err(&dev->udev->dev,
+ "reply receive error %d\n", ret);
+ goto end;
+ }
+ if (actual_len > 0)
+ break;
+ }
+ if (actual_len == 0) {
+ dev_err(&dev->udev->dev, "no reply to command %#x\n",
+ cmd);
+ ret = -EIO;
+ goto end;
+ }
+ if (buf[0] != cmd) {
+ dev_err(&dev->udev->dev,
+ "got reply to command %#x, expected: %#x\n",
+ buf[0], cmd);
+ ret = -EIO;
+ goto end;
+ }
+ if (buf[1] != STATUS_SUCCESS) {
+ dev_err(&dev->udev->dev, "command %#x failed: %#x\n",
+ cmd, buf[1]);
+ ret = -EIO;
+ goto end;
+ }
+ if (rdata)
+ memcpy(rdata, buf + 4,
+ min_t(int, rlen, CMD_PACKET_SIZE - 4));
+ }
+end:
+ kfree(buf);
+ return ret;
+}
+
+#define partial_len data[0] /* length of partial packet data */
+#define partial_rem data[1] /* remaining (missing) data length */
+#define partial_data data[2] /* partial packet data */
+
+static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int ret;
+ char buf[15];
+ struct usb_device *udev = dev->udev;
+
+ /* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */
+ if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0
+ && strcmp(buf, "USB NET CARD")) {
+ dev_info(&udev->dev, "ignoring: probably an ADSL modem\n");
+ return -ENODEV;
+ }
+
+ ret = usbnet_get_endpoints(dev, intf);
+ if (ret)
+ return ret;
+
+ /*
+ * this must not include ethernet header as the device can send partial
+ * packets with no header (and sometimes even empty URBs)
+ */
+ dev->net->hard_header_len = 0;
+ /* we can send at most 1514 bytes of data (+ 2-byte header) per URB */
+ dev->hard_mtu = CX82310_MTU + 2;
+ /* we can receive URBs up to 4KB from the device */
+ dev->rx_urb_size = 4096;
+
+ dev->partial_data = (unsigned long) kmalloc(dev->hard_mtu, GFP_KERNEL);
+ if (!dev->partial_data)
+ return -ENOMEM;
+
+ /* enable ethernet mode (?) */
+ ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0);
+ if (ret) {
+ dev_err(&udev->dev, "unable to enable ethernet mode: %d\n",
+ ret);
+ goto err;
+ }
+
+ /* get the MAC address */
+ ret = cx82310_cmd(dev, CMD_GET_MAC_ADDR, true, NULL, 0,
+ dev->net->dev_addr, ETH_ALEN);
+ if (ret) {
+ dev_err(&udev->dev, "unable to read MAC address: %d\n", ret);
+ goto err;
+ }
+
+ /* start (does not seem to have any effect?) */
+ ret = cx82310_cmd(dev, CMD_START, false, NULL, 0, NULL, 0);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ kfree((void *)dev->partial_data);
+ return ret;
+}
+
+static void cx82310_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ kfree((void *)dev->partial_data);
+}
+
+/*
+ * RX is NOT easy - we can receive multiple packets per skb, each having 2-byte
+ * packet length at the beginning.
+ * The last packet might be incomplete (when it crosses the 4KB URB size),
+ * continuing in the next skb (without any headers).
+ * If a packet has odd length, there is one extra byte at the end (before next
+ * packet or at the end of the URB).
+ */
+static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ int len;
+ struct sk_buff *skb2;
+
+ /*
+ * If the last skb ended with an incomplete packet, this skb contains
+ * end of that packet at the beginning.
+ */
+ if (dev->partial_rem) {
+ len = dev->partial_len + dev->partial_rem;
+ skb2 = alloc_skb(len, GFP_ATOMIC);
+ if (!skb2)
+ return 0;
+ skb_put(skb2, len);
+ memcpy(skb2->data, (void *)dev->partial_data,
+ dev->partial_len);
+ memcpy(skb2->data + dev->partial_len, skb->data,
+ dev->partial_rem);
+ usbnet_skb_return(dev, skb2);
+ skb_pull(skb, (dev->partial_rem + 1) & ~1);
+ dev->partial_rem = 0;
+ if (skb->len < 2)
+ return 1;
+ }
+
+ /* a skb can contain multiple packets */
+ while (skb->len > 1) {
+ /* first two bytes are packet length */
+ len = skb->data[0] | (skb->data[1] << 8);
+ skb_pull(skb, 2);
+
+ /* if last packet in the skb, let usbnet to process it */
+ if (len == skb->len || len + 1 == skb->len) {
+ skb_trim(skb, len);
+ break;
+ }
+
+ if (len > CX82310_MTU) {
+ dev_err(&dev->udev->dev, "RX packet too long: %d B\n",
+ len);
+ return 0;
+ }
+
+ /* incomplete packet, save it for the next skb */
+ if (len > skb->len) {
+ dev->partial_len = skb->len;
+ dev->partial_rem = len - skb->len;
+ memcpy((void *)dev->partial_data, skb->data,
+ dev->partial_len);
+ skb_pull(skb, skb->len);
+ break;
+ }
+
+ skb2 = alloc_skb(len, GFP_ATOMIC);
+ if (!skb2)
+ return 0;
+ skb_put(skb2, len);
+ memcpy(skb2->data, skb->data, len);
+ /* process the packet */
+ usbnet_skb_return(dev, skb2);
+
+ skb_pull(skb, (len + 1) & ~1);
+ }
+
+ /* let usbnet process the last packet */
+ return 1;
+}
+
+/* TX is easy, just add 2 bytes of length at the beginning */
+static struct sk_buff *cx82310_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+ gfp_t flags)
+{
+ int len = skb->len;
+
+ if (skb_headroom(skb) < 2) {
+ struct sk_buff *skb2 = skb_copy_expand(skb, 2, 0, flags);
+ dev_kfree_skb_any(skb);
+ skb = skb2;
+ if (!skb)
+ return NULL;
+ }
+ skb_push(skb, 2);
+
+ skb->data[0] = len;
+ skb->data[1] = len >> 8;
+
+ return skb;
+}
+
+
+static const struct driver_info cx82310_info = {
+ .description = "Conexant CX82310 USB ethernet",
+ .flags = FLAG_ETHER,
+ .bind = cx82310_bind,
+ .unbind = cx82310_unbind,
+ .rx_fixup = cx82310_rx_fixup,
+ .tx_fixup = cx82310_tx_fixup,
+};
+
+#define USB_DEVICE_CLASS(vend, prod, cl, sc, pr) \
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+ USB_DEVICE_ID_MATCH_DEV_INFO, \
+ .idVendor = (vend), \
+ .idProduct = (prod), \
+ .bDeviceClass = (cl), \
+ .bDeviceSubClass = (sc), \
+ .bDeviceProtocol = (pr)
+
+static const struct usb_device_id products[] = {
+ {
+ USB_DEVICE_CLASS(0x0572, 0xcb01, 0xff, 0, 0),
+ .driver_info = (unsigned long) &cx82310_info
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver cx82310_driver = {
+ .name = "cx82310_eth",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init cx82310_init(void)
+{
+ return usb_register(&cx82310_driver);
+}
+module_init(cx82310_init);
+
+static void __exit cx82310_exit(void)
+{
+ usb_deregister(&cx82310_driver);
+}
+module_exit(cx82310_exit);
+
+MODULE_AUTHOR("Ondrej Zary");
+MODULE_DESCRIPTION("Conexant CX82310-based ADSL router USB ethernet driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index b8e957249132..b154a94de03e 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -843,16 +843,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
}
-static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
-{
- struct hso_net *odev = netdev_priv(net);
-
- strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN);
- usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info);
-}
-
static const struct ethtool_ops ops = {
- .get_drvinfo = hso_get_drvinfo,
.get_link = ethtool_op_get_link
};
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index 2b7b39cad1ce..5e98643a4a21 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -759,14 +759,6 @@ static int kaweth_close(struct net_device *net)
return 0;
}
-static void kaweth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- struct kaweth_device *kaweth = netdev_priv(dev);
-
- strlcpy(info->driver, driver_name, sizeof(info->driver));
- usb_make_path(kaweth->dev, info->bus_info, sizeof (info->bus_info));
-}
-
static u32 kaweth_get_link(struct net_device *dev)
{
struct kaweth_device *kaweth = netdev_priv(dev);
@@ -775,7 +767,6 @@ static u32 kaweth_get_link(struct net_device *dev)
}
static const struct ethtool_ops ops = {
- .get_drvinfo = kaweth_get_drvinfo,
.get_link = kaweth_get_link
};
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index ee85c8b9a858..d1ac15c95faf 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -203,7 +203,7 @@ static inline void sierra_net_set_private(struct usbnet *dev,
/* is packet IPv4 */
static inline int is_ip(struct sk_buff *skb)
{
- return (skb->protocol == cpu_to_be16(ETH_P_IP));
+ return skb->protocol == cpu_to_be16(ETH_P_IP);
}
/*
@@ -354,7 +354,7 @@ static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix)
static inline int sierra_net_is_valid_addrlen(u8 len)
{
- return (len == sizeof(struct in_addr));
+ return len == sizeof(struct in_addr);
}
static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 12a3c88c5282..65cb1abfbe57 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -805,8 +805,6 @@ static int smsc95xx_reset(struct usbnet *dev)
return ret;
}
- smsc95xx_init_mac_address(dev);
-
ret = smsc95xx_set_mac_address(dev);
if (ret < 0)
return ret;
@@ -1047,6 +1045,8 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE;
pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
+ smsc95xx_init_mac_address(dev);
+
/* Init all registers */
ret = smsc95xx_reset(dev);
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 5ec542dd5b50..0bbc0c323135 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -250,7 +250,7 @@ static int veth_close(struct net_device *dev)
static int is_valid_veth_mtu(int new_mtu)
{
- return (new_mtu >= MIN_MTU && new_mtu <= MAX_MTU);
+ return new_mtu >= MIN_MTU && new_mtu <= MAX_MTU;
}
static int veth_change_mtu(struct net_device *dev, int new_mtu)
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index f53412368ce1..cab96ad49e60 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -312,13 +312,14 @@ VELOCITY_PARAM(flow_control, "Enable flow control ability");
#define MED_LNK_DEF 0
#define MED_LNK_MIN 0
-#define MED_LNK_MAX 4
+#define MED_LNK_MAX 5
/* speed_duplex[] is used for setting the speed and duplex mode of NIC.
0: indicate autonegotiation for both speed and duplex mode
1: indicate 100Mbps half duplex mode
2: indicate 100Mbps full duplex mode
3: indicate 10Mbps half duplex mode
4: indicate 10Mbps full duplex mode
+ 5: indicate 1000Mbps full duplex mode
Note:
if EEPROM have been set to the force mode, this option is ignored
@@ -617,6 +618,9 @@ static u32 velocity_get_opt_media_mode(struct velocity_info *vptr)
case SPD_DPX_10_HALF:
status = VELOCITY_SPEED_10;
break;
+ case SPD_DPX_1000_FULL:
+ status = VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL;
+ break;
}
vptr->mii_status = status;
return status;
@@ -922,6 +926,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
/* enable AUTO-NEGO mode */
mii_set_auto_on(vptr);
} else {
+ u16 CTRL1000;
u16 ANAR;
u8 CHIPGCR;
@@ -936,7 +941,11 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
BYTE_REG_BITS_ON(CHIPGCR_FCMODE, &regs->CHIPGCR);
CHIPGCR = readb(&regs->CHIPGCR);
- CHIPGCR &= ~CHIPGCR_FCGMII;
+
+ if (mii_status & VELOCITY_SPEED_1000)
+ CHIPGCR |= CHIPGCR_FCGMII;
+ else
+ CHIPGCR &= ~CHIPGCR_FCGMII;
if (mii_status & VELOCITY_DUPLEX_FULL) {
CHIPGCR |= CHIPGCR_FCFDX;
@@ -952,7 +961,13 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
}
- MII_REG_BITS_OFF(ADVERTISE_1000FULL | ADVERTISE_1000HALF, MII_CTRL1000, vptr->mac_regs);
+ velocity_mii_read(vptr->mac_regs, MII_CTRL1000, &CTRL1000);
+ CTRL1000 &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
+ if ((mii_status & VELOCITY_SPEED_1000) &&
+ (mii_status & VELOCITY_DUPLEX_FULL)) {
+ CTRL1000 |= ADVERTISE_1000FULL;
+ }
+ velocity_mii_write(vptr->mac_regs, MII_CTRL1000, CTRL1000);
if (!(mii_status & VELOCITY_DUPLEX_FULL) && (mii_status & VELOCITY_SPEED_10))
BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
@@ -967,7 +982,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
ANAR |= ADVERTISE_100FULL;
else
ANAR |= ADVERTISE_100HALF;
- } else {
+ } else if (mii_status & VELOCITY_SPEED_10) {
if (mii_status & VELOCITY_DUPLEX_FULL)
ANAR |= ADVERTISE_10FULL;
else
@@ -1013,6 +1028,9 @@ static void velocity_print_link_status(struct velocity_info *vptr)
} else {
VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name);
switch (vptr->options.spd_dpx) {
+ case SPD_DPX_1000_FULL:
+ VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps full duplex\n");
+ break;
case SPD_DPX_100_HALF:
VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps half duplex\n");
break;
@@ -1954,7 +1972,7 @@ static int velocity_tx_srv(struct velocity_info *vptr)
*/
static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
{
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (rd->rdesc1.CSM & CSM_IPKT) {
if (rd->rdesc1.CSM & CSM_IPOK) {
@@ -2574,7 +2592,7 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
td_ptr->tdesc1.cmd = TCPLS_NORMAL + (tdinfo->nskb_dma + 1) * 16;
- if (vptr->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
td_ptr->tdesc1.vlan = cpu_to_le16(vlan_tx_tag_get(skb));
td_ptr->tdesc1.TCR |= TCR0_VETAG;
}
@@ -3170,6 +3188,37 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full;
+
+ cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
+ if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
+ cmd->advertising |=
+ ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full;
+ } else {
+ switch (vptr->options.spd_dpx) {
+ case SPD_DPX_1000_FULL:
+ cmd->advertising |= ADVERTISED_1000baseT_Full;
+ break;
+ case SPD_DPX_100_HALF:
+ cmd->advertising |= ADVERTISED_100baseT_Half;
+ break;
+ case SPD_DPX_100_FULL:
+ cmd->advertising |= ADVERTISED_100baseT_Full;
+ break;
+ case SPD_DPX_10_HALF:
+ cmd->advertising |= ADVERTISED_10baseT_Half;
+ break;
+ case SPD_DPX_10_FULL:
+ cmd->advertising |= ADVERTISED_10baseT_Full;
+ break;
+ default:
+ break;
+ }
+ }
if (status & VELOCITY_SPEED_1000)
cmd->speed = SPEED_1000;
else if (status & VELOCITY_SPEED_100)
@@ -3200,14 +3249,35 @@ 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 |= ((cmd->duplex == DUPLEX_FULL) ? VELOCITY_DUPLEX_FULL : 0);
- if ((new_status & VELOCITY_AUTONEG_ENABLE) && (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE)))
+ if ((new_status & VELOCITY_AUTONEG_ENABLE) &&
+ (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE))) {
ret = -EINVAL;
- else
+ } else {
+ enum speed_opt spd_dpx;
+
+ if (new_status & VELOCITY_AUTONEG_ENABLE)
+ spd_dpx = SPD_DPX_AUTO;
+ else if ((new_status & VELOCITY_SPEED_1000) &&
+ (new_status & VELOCITY_DUPLEX_FULL)) {
+ spd_dpx = SPD_DPX_1000_FULL;
+ } else if (new_status & VELOCITY_SPEED_100)
+ spd_dpx = (new_status & VELOCITY_DUPLEX_FULL) ?
+ SPD_DPX_100_FULL : SPD_DPX_100_HALF;
+ else if (new_status & VELOCITY_SPEED_10)
+ spd_dpx = (new_status & VELOCITY_DUPLEX_FULL) ?
+ SPD_DPX_10_FULL : SPD_DPX_10_HALF;
+ else
+ return -EOPNOTSUPP;
+
+ vptr->options.spd_dpx = spd_dpx;
+
velocity_set_media_mode(vptr, new_status);
+ }
return ret;
}
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index f7b33ae7a703..aa2e69b9ff61 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -848,7 +848,7 @@ enum velocity_owner {
* Bits in CHIPGCR register
*/
-#define CHIPGCR_FCGMII 0x80
+#define CHIPGCR_FCGMII 0x80 /* enable GMII mode */
#define CHIPGCR_FCFDX 0x40
#define CHIPGCR_FCRESV 0x20
#define CHIPGCR_FCMODE 0x10
@@ -1390,7 +1390,8 @@ enum speed_opt {
SPD_DPX_100_HALF = 1,
SPD_DPX_100_FULL = 2,
SPD_DPX_10_HALF = 3,
- SPD_DPX_10_FULL = 4
+ SPD_DPX_10_FULL = 4,
+ SPD_DPX_1000_FULL = 5
};
enum velocity_init_type {
@@ -1504,22 +1505,25 @@ struct velocity_info {
* addresses on this chain then we use the first - multi-IP WOL is not
* supported.
*
- * CHECK ME: locking
*/
static inline int velocity_get_ip(struct velocity_info *vptr)
{
- struct in_device *in_dev = (struct in_device *) vptr->dev->ip_ptr;
+ struct in_device *in_dev;
struct in_ifaddr *ifa;
+ int res = -ENOENT;
+ rcu_read_lock();
+ in_dev = __in_dev_get_rcu(vptr->dev);
if (in_dev != NULL) {
ifa = (struct in_ifaddr *) in_dev->ifa_list;
if (ifa != NULL) {
memcpy(vptr->ip_addr, &ifa->ifa_address, 4);
- return 0;
+ res = 0;
}
}
- return -ENOENT;
+ rcu_read_unlock();
+ return res;
}
/**
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 4598e9d2608f..bb6b67f6b0cc 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -705,19 +705,6 @@ static int virtnet_close(struct net_device *dev)
return 0;
}
-static void virtnet_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *drvinfo)
-{
- struct virtnet_info *vi = netdev_priv(dev);
- struct virtio_device *vdev = vi->vdev;
-
- strncpy(drvinfo->driver, KBUILD_MODNAME, ARRAY_SIZE(drvinfo->driver));
- strncpy(drvinfo->version, "N/A", ARRAY_SIZE(drvinfo->version));
- strncpy(drvinfo->fw_version, "N/A", ARRAY_SIZE(drvinfo->fw_version));
- strncpy(drvinfo->bus_info, dev_name(&vdev->dev),
- ARRAY_SIZE(drvinfo->bus_info));
-}
-
static int virtnet_set_tx_csum(struct net_device *dev, u32 data)
{
struct virtnet_info *vi = netdev_priv(dev);
@@ -830,7 +817,6 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
}
static const struct ethtool_ops virtnet_ethtool_ops = {
- .get_drvinfo = virtnet_get_drvinfo,
.set_tx_csum = virtnet_set_tx_csum,
.set_sg = ethtool_op_set_sg,
.set_tso = ethtool_op_set_tso,
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index abe0ff53daf3..3f60e0e3097b 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -1042,11 +1042,11 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
skb->csum = htons(gdesc->rcd.csum);
skb->ip_summed = CHECKSUM_PARTIAL;
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
}
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
}
@@ -1548,23 +1548,6 @@ vmxnet3_free_irqs(struct vmxnet3_adapter *adapter)
}
}
-
-inline void set_flag_le16(__le16 *data, u16 flag)
-{
- *data = cpu_to_le16(le16_to_cpu(*data) | flag);
-}
-
-inline void set_flag_le64(__le64 *data, u64 flag)
-{
- *data = cpu_to_le64(le64_to_cpu(*data) | flag);
-}
-
-inline void reset_flag_le64(__le64 *data, u64 flag)
-{
- *data = cpu_to_le64(le64_to_cpu(*data) & ~flag);
-}
-
-
static void
vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
{
@@ -1634,7 +1617,7 @@ vmxnet3_restore_vlan(struct vmxnet3_adapter *adapter)
u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
bool activeVlan = false;
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ for (vid = 0; vid < VLAN_N_VID; vid++) {
if (vlan_group_get_device(adapter->vlan_grp, vid)) {
VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
activeVlan = true;
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index 2121c735cabd..c88ea5cbba0d 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -353,9 +353,20 @@ struct vmxnet3_adapter {
#define VMXNET3_MAX_ETH_HDR_SIZE 22
#define VMXNET3_MAX_SKB_BUF_SIZE (3*1024)
-void set_flag_le16(__le16 *data, u16 flag);
-void set_flag_le64(__le64 *data, u64 flag);
-void reset_flag_le64(__le64 *data, u64 flag);
+static inline void set_flag_le16(__le16 *data, u16 flag)
+{
+ *data = cpu_to_le16(le16_to_cpu(*data) | flag);
+}
+
+static inline void set_flag_le64(__le64 *data, u64 flag)
+{
+ *data = cpu_to_le64(le64_to_cpu(*data) | flag);
+}
+
+static inline void reset_flag_le64(__le64 *data, u64 flag)
+{
+ *data = cpu_to_le64(le64_to_cpu(*data) & ~flag);
+}
int
vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter);
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index c7c5605b3728..a69542ecb68d 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -501,7 +501,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK)
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
vxge_rx_complete(ring, skb, ext_info.vlan,
pkt_length, &ext_info);
@@ -822,7 +822,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
dev->name, __func__, __LINE__,
fifo_hw, dtr, dtr_priv);
- if (vdev->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
u16 vlan_tag = vlan_tx_tag_get(skb);
vxge_hw_fifo_txdl_vlan_set(dtr, vlan_tag);
}
@@ -1862,7 +1862,7 @@ enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath)
if (vdev->vlgrp && vpath->is_open) {
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ for (vid = 0; vid < VLAN_N_VID; vid++) {
if (!vlan_group_get_device(vdev->vlgrp, vid))
continue;
/* Add these vlan to the vid table */
@@ -2159,8 +2159,8 @@ start:
/* Alarm MSIX Vectors count */
vdev->intr_cnt++;
- vdev->entries = kzalloc(vdev->intr_cnt * sizeof(struct msix_entry),
- GFP_KERNEL);
+ vdev->entries = kcalloc(vdev->intr_cnt, sizeof(struct msix_entry),
+ GFP_KERNEL);
if (!vdev->entries) {
vxge_debug_init(VXGE_ERR,
"%s: memory allocation failed",
@@ -2169,9 +2169,9 @@ start:
goto alloc_entries_failed;
}
- vdev->vxge_entries =
- kzalloc(vdev->intr_cnt * sizeof(struct vxge_msix_entry),
- GFP_KERNEL);
+ vdev->vxge_entries = kcalloc(vdev->intr_cnt,
+ sizeof(struct vxge_msix_entry),
+ GFP_KERNEL);
if (!vdev->vxge_entries) {
vxge_debug_init(VXGE_ERR, "%s: memory allocation failed",
VXGE_DRIVER_NAME);
@@ -2914,26 +2914,18 @@ static int vxge_change_mtu(struct net_device *dev, int new_mtu)
}
/**
- * vxge_get_stats
+ * vxge_get_stats64
* @dev: pointer to the device structure
+ * @stats: pointer to struct rtnl_link_stats64
*
- * Updates the device statistics structure. This function updates the device
- * statistics structure in the net_device structure and returns a pointer
- * to the same.
*/
-static struct net_device_stats *
-vxge_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *
+vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats)
{
- struct vxgedev *vdev;
- struct net_device_stats *net_stats;
+ struct vxgedev *vdev = netdev_priv(dev);
int k;
- vdev = netdev_priv(dev);
-
- net_stats = &vdev->stats.net_stats;
-
- memset(net_stats, 0, sizeof(struct net_device_stats));
-
+ /* net_stats already zeroed by caller */
for (k = 0; k < vdev->no_of_vpath; k++) {
net_stats->rx_packets += vdev->vpaths[k].ring.stats.rx_frms;
net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes;
@@ -3102,7 +3094,7 @@ vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
static const struct net_device_ops vxge_netdev_ops = {
.ndo_open = vxge_open,
.ndo_stop = vxge_close,
- .ndo_get_stats = vxge_get_stats,
+ .ndo_get_stats64 = vxge_get_stats64,
.ndo_start_xmit = vxge_xmit,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_multicast_list = vxge_set_multicast,
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index 2e3b064b8e4b..d4be07eaacd7 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -172,7 +172,6 @@ struct vxge_msix_entry {
struct vxge_sw_stats {
/* Network Stats (interface stats) */
- struct net_device_stats net_stats;
/* Tx */
u64 tx_frms;
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index 0bd898c94759..4ac85a09c5a6 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -264,7 +264,7 @@ static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
new_line.clock_type != CLOCK_TXFROMRX &&
new_line.clock_type != CLOCK_INT &&
new_line.clock_type != CLOCK_TXINT)
- return -EINVAL; /* No such clock setting */
+ return -EINVAL; /* No such clock setting */
if (new_line.loopback != 0 && new_line.loopback != 1)
return -EINVAL;
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c
index a5ddc6c8963e..164c3624ba89 100644
--- a/drivers/net/wan/cycx_drv.c
+++ b/drivers/net/wan/cycx_drv.c
@@ -73,7 +73,7 @@ static int reset_cyc2x(void __iomem *addr);
static int detect_cyc2x(void __iomem *addr);
/* Miscellaneous functions */
-static int get_option_index(long *optlist, long optval);
+static int get_option_index(const long *optlist, long optval);
static u16 checksum(u8 *buf, u32 len);
#define wait_cyc(addr) cycx_exec(addr + CMD_OFFSET)
@@ -81,23 +81,23 @@ static u16 checksum(u8 *buf, u32 len);
/* Global Data */
/* private data */
-static char modname[] = "cycx_drv";
-static char fullname[] = "Cyclom 2X Support Module";
-static char copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo "
+static const char modname[] = "cycx_drv";
+static const char fullname[] = "Cyclom 2X Support Module";
+static const char copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo "
"<acme@conectiva.com.br>";
/* Hardware configuration options.
* These are arrays of configuration options used by verification routines.
* The first element of each array is its size (i.e. number of options).
*/
-static long cyc2x_dpmbase_options[] = {
+static const long cyc2x_dpmbase_options[] = {
20,
0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000, 0xB8000,
0xBC000, 0xC0000, 0xC4000, 0xC8000, 0xCC000, 0xD0000, 0xD4000,
0xD8000, 0xDC000, 0xE0000, 0xE4000, 0xE8000, 0xEC000
};
-static long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 };
+static const long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 };
/* Kernel Loadable Module Entry Points */
/* Module 'insert' entry point.
@@ -529,7 +529,7 @@ static int detect_cyc2x(void __iomem *addr)
/* Miscellaneous */
/* Get option's index into the options list.
* Return option's index (1 .. N) or zero if option is invalid. */
-static int get_option_index(long *optlist, long optval)
+static int get_option_index(const long *optlist, long optval)
{
int i = 1;
diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
index a0e8611ad8e8..859dba9b972e 100644
--- a/drivers/net/wan/cycx_main.c
+++ b/drivers/net/wan/cycx_main.c
@@ -81,9 +81,9 @@ static irqreturn_t cycx_isr(int irq, void *dev_id);
*/
/* private data */
-static char cycx_drvname[] = "cyclomx";
-static char cycx_fullname[] = "CYCLOM 2X(tm) Sync Card Driver";
-static char cycx_copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo "
+static const char cycx_drvname[] = "cyclomx";
+static const char cycx_fullname[] = "CYCLOM 2X(tm) Sync Card Driver";
+static const char cycx_copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo "
"<acme@conectiva.com.br>";
static int cycx_ncards = CONFIG_CYCX_CARDS;
static struct cycx_device *cycx_card_array; /* adapter data space */
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index 421d0715310e..1481a446fefb 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -97,11 +97,11 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev,
dest = skb_push(skb, hlen);
if (!dest)
- return(0);
+ return 0;
memcpy(dest, &hdr, hlen);
- return(hlen);
+ return hlen;
}
static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
@@ -211,14 +211,14 @@ static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, in
if (copy_from_user(&config, conf, sizeof(struct dlci_conf)))
return -EFAULT;
if (config.flags & ~DLCI_VALID_FLAGS)
- return(-EINVAL);
+ return -EINVAL;
memcpy(&dlp->config, &config, sizeof(struct dlci_conf));
dlp->configured = 1;
}
err = (*flp->dlci_conf)(dlp->slave, dev, get);
if (err)
- return(err);
+ return err;
if (get)
{
@@ -226,7 +226,7 @@ static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, in
return -EFAULT;
}
- return(0);
+ return 0;
}
static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -234,7 +234,7 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct dlci_local *dlp;
if (!capable(CAP_NET_ADMIN))
- return(-EPERM);
+ return -EPERM;
dlp = netdev_priv(dev);
@@ -242,7 +242,7 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
case DLCI_GET_SLAVE:
if (!*(short *)(dev->dev_addr))
- return(-EINVAL);
+ return -EINVAL;
strncpy(ifr->ifr_slave, dlp->slave->name, sizeof(ifr->ifr_slave));
break;
@@ -250,15 +250,15 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
case DLCI_GET_CONF:
case DLCI_SET_CONF:
if (!*(short *)(dev->dev_addr))
- return(-EINVAL);
+ return -EINVAL;
- return(dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF));
+ return dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF);
break;
default:
- return(-EOPNOTSUPP);
+ return -EOPNOTSUPP;
}
- return(0);
+ return 0;
}
static int dlci_change_mtu(struct net_device *dev, int new_mtu)
@@ -277,15 +277,15 @@ static int dlci_open(struct net_device *dev)
dlp = netdev_priv(dev);
if (!*(short *)(dev->dev_addr))
- return(-EINVAL);
+ return -EINVAL;
if (!netif_running(dlp->slave))
- return(-ENOTCONN);
+ return -ENOTCONN;
flp = netdev_priv(dlp->slave);
err = (*flp->activate)(dlp->slave, dev);
if (err)
- return(err);
+ return err;
netif_start_queue(dev);
@@ -365,14 +365,14 @@ static int dlci_add(struct dlci_add *dlci)
list_add(&dlp->list, &dlci_devs);
rtnl_unlock();
- return(0);
+ return 0;
err2:
rtnl_unlock();
free_netdev(master);
err1:
dev_put(slave);
- return(err);
+ return err;
}
static int dlci_del(struct dlci_add *dlci)
@@ -385,10 +385,10 @@ static int dlci_del(struct dlci_add *dlci)
/* validate slave device */
master = __dev_get_by_name(&init_net, dlci->devname);
if (!master)
- return(-ENODEV);
+ return -ENODEV;
if (netif_running(master)) {
- return(-EBUSY);
+ return -EBUSY;
}
dlp = netdev_priv(master);
@@ -406,7 +406,7 @@ static int dlci_del(struct dlci_add *dlci)
}
rtnl_unlock();
- return(err);
+ return err;
}
static int dlci_ioctl(unsigned int cmd, void __user *arg)
@@ -415,7 +415,7 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg)
int err;
if (!capable(CAP_NET_ADMIN))
- return(-EPERM);
+ return -EPERM;
if (copy_from_user(&add, arg, sizeof(struct dlci_add)))
return -EFAULT;
@@ -438,7 +438,7 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg)
err = -EINVAL;
}
- return(err);
+ return err;
}
static const struct header_ops dlci_header_ops = {
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index b38ffa149aba..b1e5e5b69c2a 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -191,7 +191,8 @@ static int cisco_rx(struct sk_buff *skb)
switch (ntohl (cisco_data->type)) {
case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
- in_dev = dev->ip_ptr;
+ rcu_read_lock();
+ in_dev = __in_dev_get_rcu(dev);
addr = 0;
mask = ~cpu_to_be32(0); /* is the mask correct? */
@@ -211,6 +212,7 @@ static int cisco_rx(struct sk_buff *skb)
cisco_keepalive_send(dev, CISCO_ADDR_REPLY,
addr, mask);
}
+ rcu_read_unlock();
dev_kfree_skb_any(skb);
return NET_RX_SUCCESS;
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index 4d4dc38c7290..7f5bb913c8b9 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -46,7 +46,7 @@
#include <net/x25device.h>
-static char bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+static const u8 bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
/* If this number is made larger, check that the temporary string buffer
* in lapbeth_new_device is large enough to store the probe device name.*/
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index e2c6f7f4f51c..70feb84df670 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -1022,7 +1022,7 @@ static int lmc_open(struct net_device *dev)
if (sc->lmc_ok){
lmc_trace(dev, "lmc_open lmc_ok out");
- return (0);
+ return 0;
}
lmc_softreset (sc);
@@ -1105,12 +1105,12 @@ static int lmc_open(struct net_device *dev)
init_timer (&sc->timer);
sc->timer.expires = jiffies + HZ;
sc->timer.data = (unsigned long) dev;
- sc->timer.function = &lmc_watchdog;
+ sc->timer.function = lmc_watchdog;
add_timer (&sc->timer);
lmc_trace(dev, "lmc_open out");
- return (0);
+ return 0;
}
/* Total reset to compensate for the AdTran DSU doing bad things
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index 5394b51bdb2f..17d408fe693f 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -282,7 +282,7 @@ static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
new_line.clock_type != CLOCK_TXFROMRX &&
new_line.clock_type != CLOCK_INT &&
new_line.clock_type != CLOCK_TXINT)
- return -EINVAL; /* No such clock setting */
+ return -EINVAL; /* No such clock setting */
if (new_line.loopback != 0 && new_line.loopback != 1)
return -EINVAL;
@@ -379,14 +379,14 @@ static int __init n2_run(unsigned long io, unsigned long irq,
if (request_irq(irq, sca_intr, 0, devname, card)) {
printk(KERN_ERR "n2: could not allocate IRQ\n");
n2_destroy_card(card);
- return(-EBUSY);
+ return -EBUSY;
}
card->irq = irq;
if (!request_mem_region(winbase, USE_WINDOWSIZE, devname)) {
printk(KERN_ERR "n2: could not request RAM window\n");
n2_destroy_card(card);
- return(-EBUSY);
+ return -EBUSY;
}
card->phy_winbase = winbase;
card->winbase = ioremap(winbase, USE_WINDOWSIZE);
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index c6aa66e5b52f..f875cfae3093 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -1,5 +1,5 @@
#define USE_PCI_CLOCK
-static char rcsid[] =
+static const char rcsid[] =
"Revision: 3.4.5 Date: 2002/03/07 ";
/*
@@ -451,11 +451,11 @@ static int dma_get_rx_frame_size(pc300_t * card, int ch)
if ((status & DST_EOM) || (first_bd == card->chan[ch].rx_last_bd)) {
/* Return the size of a good frame or incomplete bad frame
* (dma_buf_read will clean the buffer descriptors in this case). */
- return (rcvd);
+ return rcvd;
}
ptdescr = (card->hw.rambase + cpc_readl(&ptdescr->next));
}
- return (-1);
+ return -1;
}
/*
@@ -557,7 +557,7 @@ static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch),
RX_BD_ADDR(ch, chan->rx_last_bd));
}
- return (rcvd);
+ return rcvd;
}
static void tx_dma_stop(pc300_t * card, int ch)
@@ -1733,7 +1733,7 @@ static u16 falc_pattern_test_error(pc300_t * card, int ch)
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
- return (pfalc->bec);
+ return pfalc->bec;
}
/**********************************/
@@ -2819,7 +2819,7 @@ static int clock_rate_calc(u32 rate, u32 clock, int *br_io)
*br_io = 0;
if (rate == 0)
- return (0);
+ return 0;
for (br = 0, br_pwr = 1; br <= 9; br++, br_pwr <<= 1) {
if ((tc = clock / br_pwr / rate) <= 0xff) {
@@ -2832,11 +2832,11 @@ static int clock_rate_calc(u32 rate, u32 clock, int *br_io)
error = ((rate - (clock / br_pwr / rate)) / rate) * 1000;
/* Errors bigger than +/- 1% won't be tolerated */
if (error < -10 || error > 10)
- return (-1);
+ return -1;
else
- return (tc);
+ return tc;
} else {
- return (-1);
+ return -1;
}
}
@@ -3207,7 +3207,7 @@ static u32 detect_ram(pc300_t * card)
break;
}
}
- return (i);
+ return i;
}
static void plx_init(pc300_t * card)
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index 4293889e287e..515d9b8af01e 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -540,7 +540,7 @@ static int cpc_tty_chars_in_buffer(struct tty_struct *tty)
return -ENODEV;
}
- return(0);
+ return 0;
}
static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index e2cff64a446a..fd7375955e41 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -220,7 +220,7 @@ static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
new_line.clock_type != CLOCK_TXFROMRX &&
new_line.clock_type != CLOCK_INT &&
new_line.clock_type != CLOCK_TXINT)
- return -EINVAL; /* No such clock setting */
+ return -EINVAL; /* No such clock setting */
if (new_line.loopback != 0 && new_line.loopback != 1)
return -EINVAL;
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index f4125da2762f..3f4e2b5684db 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -178,7 +178,7 @@ static char sdla_byte(struct net_device *dev, int addr)
byte = *temp;
spin_unlock_irqrestore(&sdla_lock, flags);
- return(byte);
+ return byte;
}
static void sdla_stop(struct net_device *dev)
@@ -267,7 +267,7 @@ static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char r
resp = *temp;
}
}
- return(time_before(jiffies, done) ? jiffies - start : -1);
+ return time_before(jiffies, done) ? jiffies - start : -1;
}
/* constants for Z80 CPU speed */
@@ -283,13 +283,13 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr)
sdla_start(dev);
if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0)
- return(-EIO);
+ return -EIO;
data = LOADER_READY;
sdla_write(dev, 0, &data, 1);
if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0)
- return(-EIO);
+ return -EIO;
sdla_stop(dev);
sdla_read(dev, 0, &data, 1);
@@ -297,11 +297,11 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr)
if (data == Z80_SCC_BAD)
{
printk("%s: SCC bad\n", dev->name);
- return(-EIO);
+ return -EIO;
}
if (data != Z80_SCC_OK)
- return(-EINVAL);
+ return -EINVAL;
if (jiffs < 165)
ifr->ifr_mtu = SDLA_CPU_16M;
@@ -316,7 +316,7 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr)
else
ifr->ifr_mtu = SDLA_CPU_3M;
- return(0);
+ return 0;
}
/************************************************
@@ -493,7 +493,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
if (ret != SDLA_RET_OK)
sdla_errors(dev, cmd, dlci, ret, len, &status);
- return(ret);
+ return ret;
}
/***********************************************
@@ -516,14 +516,14 @@ static int sdla_activate(struct net_device *slave, struct net_device *master)
break;
if (i == CONFIG_DLCI_MAX)
- return(-ENODEV);
+ return -ENODEV;
flp->dlci[i] = abs(flp->dlci[i]);
if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE))
sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
- return(0);
+ return 0;
}
static int sdla_deactivate(struct net_device *slave, struct net_device *master)
@@ -538,14 +538,14 @@ static int sdla_deactivate(struct net_device *slave, struct net_device *master)
break;
if (i == CONFIG_DLCI_MAX)
- return(-ENODEV);
+ return -ENODEV;
flp->dlci[i] = -abs(flp->dlci[i]);
if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE))
sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
- return(0);
+ return 0;
}
static int sdla_assoc(struct net_device *slave, struct net_device *master)
@@ -554,7 +554,7 @@ static int sdla_assoc(struct net_device *slave, struct net_device *master)
int i;
if (master->type != ARPHRD_DLCI)
- return(-EINVAL);
+ return -EINVAL;
flp = netdev_priv(slave);
@@ -563,11 +563,11 @@ static int sdla_assoc(struct net_device *slave, struct net_device *master)
if (!flp->master[i])
break;
if (abs(flp->dlci[i]) == *(short *)(master->dev_addr))
- return(-EADDRINUSE);
+ return -EADDRINUSE;
}
if (i == CONFIG_DLCI_MAX)
- return(-EMLINK); /* #### Alan: Comments on this ?? */
+ return -EMLINK; /* #### Alan: Comments on this ?? */
flp->master[i] = master;
@@ -581,7 +581,7 @@ static int sdla_assoc(struct net_device *slave, struct net_device *master)
sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
}
- return(0);
+ return 0;
}
static int sdla_deassoc(struct net_device *slave, struct net_device *master)
@@ -596,7 +596,7 @@ static int sdla_deassoc(struct net_device *slave, struct net_device *master)
break;
if (i == CONFIG_DLCI_MAX)
- return(-ENODEV);
+ return -ENODEV;
flp->master[i] = NULL;
flp->dlci[i] = 0;
@@ -609,7 +609,7 @@ static int sdla_deassoc(struct net_device *slave, struct net_device *master)
sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
}
- return(0);
+ return 0;
}
static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
@@ -626,7 +626,7 @@ static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, i
break;
if (i == CONFIG_DLCI_MAX)
- return(-ENODEV);
+ return -ENODEV;
dlp = netdev_priv(master);
@@ -641,7 +641,7 @@ static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, i
&dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL);
}
- return(ret == SDLA_RET_OK ? 0 : -EIO);
+ return ret == SDLA_RET_OK ? 0 : -EIO;
}
/**************************
@@ -986,7 +986,7 @@ static int sdla_close(struct net_device *dev)
netif_stop_queue(dev);
- return(0);
+ return 0;
}
struct conf_data {
@@ -1006,10 +1006,10 @@ static int sdla_open(struct net_device *dev)
flp = netdev_priv(dev);
if (!flp->initialized)
- return(-EPERM);
+ return -EPERM;
if (!flp->configured)
- return(-EPERM);
+ return -EPERM;
/* time to send in the configuration */
len = 0;
@@ -1087,7 +1087,7 @@ static int sdla_open(struct net_device *dev)
netif_start_queue(dev);
- return(0);
+ return 0;
}
static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get)
@@ -1098,48 +1098,48 @@ static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, in
short size;
if (dev->type == 0xFFFF)
- return(-EUNATCH);
+ return -EUNATCH;
flp = netdev_priv(dev);
if (!get)
{
if (netif_running(dev))
- return(-EBUSY);
+ return -EBUSY;
if(copy_from_user(&data.config, conf, sizeof(struct frad_conf)))
return -EFAULT;
if (data.config.station & ~FRAD_STATION_NODE)
- return(-EINVAL);
+ return -EINVAL;
if (data.config.flags & ~FRAD_VALID_FLAGS)
- return(-EINVAL);
+ return -EINVAL;
if ((data.config.kbaud < 0) ||
((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
- return(-EINVAL);
+ return -EINVAL;
if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
- return(-EINVAL);
+ return -EINVAL;
if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
- return(-EINVAL);
+ return -EINVAL;
if ((data.config.T391 < 5) || (data.config.T391 > 30))
- return(-EINVAL);
+ return -EINVAL;
if ((data.config.T392 < 5) || (data.config.T392 > 30))
- return(-EINVAL);
+ return -EINVAL;
if ((data.config.N391 < 1) || (data.config.N391 > 255))
- return(-EINVAL);
+ return -EINVAL;
if ((data.config.N392 < 1) || (data.config.N392 > 10))
- return(-EINVAL);
+ return -EINVAL;
if ((data.config.N393 < 1) || (data.config.N393 > 10))
- return(-EINVAL);
+ return -EINVAL;
memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
flp->config.flags |= SDLA_DIRECT_RECV;
@@ -1171,7 +1171,7 @@ static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, in
{
size = sizeof(data);
if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK)
- return(-EIO);
+ return -EIO;
}
else
if (flp->configured)
@@ -1185,7 +1185,7 @@ static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, in
return copy_to_user(conf, &data.config, sizeof(struct frad_conf))?-EFAULT:0;
}
- return(0);
+ return 0;
}
static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read)
@@ -1200,7 +1200,7 @@ static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int r
{
temp = kzalloc(mem.len, GFP_KERNEL);
if (!temp)
- return(-ENOMEM);
+ return -ENOMEM;
sdla_read(dev, mem.addr, temp, mem.len);
if(copy_to_user(mem.data, temp, mem.len))
{
@@ -1217,7 +1217,7 @@ static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int r
sdla_write(dev, mem.addr, temp, mem.len);
kfree(temp);
}
- return(0);
+ return 0;
}
static int sdla_reconfig(struct net_device *dev)
@@ -1241,7 +1241,7 @@ static int sdla_reconfig(struct net_device *dev)
sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
- return(0);
+ return 0;
}
static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1254,20 +1254,20 @@ static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
flp = netdev_priv(dev);
if (!flp->initialized)
- return(-EINVAL);
+ return -EINVAL;
switch (cmd)
{
case FRAD_GET_CONF:
case FRAD_SET_CONF:
- return(sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF));
+ return sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF);
case SDLA_IDENTIFY:
ifr->ifr_flags = flp->type;
break;
case SDLA_CPUSPEED:
- return(sdla_cpuspeed(dev, ifr));
+ return sdla_cpuspeed(dev, ifr);
/* ==========================================================
NOTE: This is rather a useless action right now, as the
@@ -1277,7 +1277,7 @@ NOTE: This is rather a useless action right now, as the
============================================================*/
case SDLA_PROTOCOL:
if (flp->configured)
- return(-EALREADY);
+ return -EALREADY;
switch (ifr->ifr_flags)
{
@@ -1285,7 +1285,7 @@ NOTE: This is rather a useless action right now, as the
dev->type = ifr->ifr_flags;
break;
default:
- return(-ENOPROTOOPT);
+ return -ENOPROTOOPT;
}
break;
@@ -1297,7 +1297,7 @@ NOTE: This is rather a useless action right now, as the
case SDLA_READMEM:
if(!capable(CAP_SYS_RAWIO))
return -EPERM;
- return(sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM));
+ return sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM);
case SDLA_START:
sdla_start(dev);
@@ -1308,9 +1308,9 @@ NOTE: This is rather a useless action right now, as the
break;
default:
- return(-EOPNOTSUPP);
+ return -EOPNOTSUPP;
}
- return(0);
+ return 0;
}
static int sdla_change_mtu(struct net_device *dev, int new_mtu)
@@ -1320,10 +1320,10 @@ static int sdla_change_mtu(struct net_device *dev, int new_mtu)
flp = netdev_priv(dev);
if (netif_running(dev))
- return(-EBUSY);
+ return -EBUSY;
/* for now, you can't change the MTU! */
- return(-EOPNOTSUPP);
+ return -EOPNOTSUPP;
}
static int sdla_set_config(struct net_device *dev, struct ifmap *map)
@@ -1337,18 +1337,18 @@ static int sdla_set_config(struct net_device *dev, struct ifmap *map)
flp = netdev_priv(dev);
if (flp->initialized)
- return(-EINVAL);
+ return -EINVAL;
for(i=0; i < ARRAY_SIZE(valid_port); i++)
if (valid_port[i] == map->base_addr)
break;
if (i == ARRAY_SIZE(valid_port))
- return(-EINVAL);
+ return -EINVAL;
if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){
printk(KERN_WARNING "SDLA: io-port 0x%04lx in use\n", dev->base_addr);
- return(-EINVAL);
+ return -EINVAL;
}
base = map->base_addr;
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index e47f5a986b1c..d81ad8397885 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -648,7 +648,7 @@ static int x25_asy_esc(unsigned char *s, unsigned char *d, int len)
}
}
*ptr++ = X25_END;
- return (ptr - d);
+ return ptr - d;
}
static void x25_asy_unesc(struct x25_asy *sl, unsigned char s)
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index fbf5e843d48c..93956861ea21 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -766,7 +766,7 @@ irqreturn_t z8530_interrupt(int irq, void *dev_id)
EXPORT_SYMBOL(z8530_interrupt);
-static char reg_init[16]=
+static const u8 reg_init[16]=
{
0,0,0,0,
0,0,0,0,
@@ -1206,7 +1206,7 @@ EXPORT_SYMBOL(z8530_sync_txdma_close);
* it exists...
*/
-static char *z8530_type_name[]={
+static const char *z8530_type_name[]={
"Z8530",
"Z85C30",
"Z85230"
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index eb72c67699ab..f1549fff0edc 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -342,10 +342,10 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
model_name, dev->irq, dev->mem_start, dev->mem_end-1);
- ei_status.reset_8390 = &wd_reset_8390;
- ei_status.block_input = &wd_block_input;
- ei_status.block_output = &wd_block_output;
- ei_status.get_8390_hdr = &wd_get_8390_hdr;
+ ei_status.reset_8390 = wd_reset_8390;
+ ei_status.block_input = wd_block_input;
+ ei_status.block_output = wd_block_output;
+ ei_status.get_8390_hdr = wd_get_8390_hdr;
dev->netdev_ops = &wd_netdev_ops;
NS8390_init(dev, 0);
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index 9fb03082153a..12b84ed0e38a 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -98,7 +98,7 @@ MODULE_PARM_DESC(power_save_disabled,
"False by default (so the device is told to do power "
"saving).");
-int i2400m_passive_mode; /* 0 (passive mode disabled) by default */
+static int i2400m_passive_mode; /* 0 (passive mode disabled) by default */
module_param_named(passive_mode, i2400m_passive_mode, int, 0644);
MODULE_PARM_DESC(passive_mode,
"If true, the driver will not do any device setup "
@@ -558,8 +558,9 @@ void i2400m_report_hook(struct i2400m *i2400m,
* processing should be done in the function that calls the
* command. This is here for some cases where it can't happen...
*/
-void i2400m_msg_ack_hook(struct i2400m *i2400m,
- const struct i2400m_l3l4_hdr *l3l4_hdr, size_t size)
+static void i2400m_msg_ack_hook(struct i2400m *i2400m,
+ const struct i2400m_l3l4_hdr *l3l4_hdr,
+ size_t size)
{
int result;
struct device *dev = i2400m_dev(i2400m);
@@ -1135,7 +1136,7 @@ error_alloc:
* i2400m_report_state_hook() to parse the answer. This will set the
* carrier state, as well as the RF Kill switches state.
*/
-int i2400m_cmd_get_state(struct i2400m *i2400m)
+static int i2400m_cmd_get_state(struct i2400m *i2400m)
{
int result;
struct device *dev = i2400m_dev(i2400m);
@@ -1177,8 +1178,6 @@ error_msg_to_dev:
error_alloc:
return result;
}
-EXPORT_SYMBOL_GPL(i2400m_cmd_get_state);
-
/**
* Set basic configuration settings
@@ -1190,8 +1189,9 @@ EXPORT_SYMBOL_GPL(i2400m_cmd_get_state);
* right endianess (LE).
* @arg_size: number of pointers in the @args array
*/
-int i2400m_set_init_config(struct i2400m *i2400m,
- const struct i2400m_tlv_hdr **arg, size_t args)
+static int i2400m_set_init_config(struct i2400m *i2400m,
+ const struct i2400m_tlv_hdr **arg,
+ size_t args)
{
int result;
struct device *dev = i2400m_dev(i2400m);
@@ -1258,8 +1258,6 @@ none:
return result;
}
-EXPORT_SYMBOL_GPL(i2400m_set_init_config);
-
/**
* i2400m_set_idle_timeout - Set the device's idle mode timeout
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 9c8b78d4abd2..cdedab46ba21 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -122,7 +122,7 @@ struct i2400m_work *__i2400m_work_setup(
* works struct was already queued, but we have just allocated it, so
* it should not happen.
*/
-int i2400m_schedule_work(struct i2400m *i2400m,
+static int i2400m_schedule_work(struct i2400m *i2400m,
void (*fn)(struct work_struct *), gfp_t gfp_flags,
const void *pl, size_t pl_size)
{
diff --git a/drivers/net/wimax/i2400m/i2400m-sdio.h b/drivers/net/wimax/i2400m/i2400m-sdio.h
index 360d4fb195f4..1d63ffdedfde 100644
--- a/drivers/net/wimax/i2400m/i2400m-sdio.h
+++ b/drivers/net/wimax/i2400m/i2400m-sdio.h
@@ -140,7 +140,6 @@ void i2400ms_init(struct i2400ms *i2400ms)
extern int i2400ms_rx_setup(struct i2400ms *);
extern void i2400ms_rx_release(struct i2400ms *);
-extern ssize_t __i2400ms_rx_get_size(struct i2400ms *);
extern int i2400ms_tx_setup(struct i2400ms *);
extern void i2400ms_tx_release(struct i2400ms *);
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index fa74777fd65f..59ac7705e76e 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -910,28 +910,19 @@ struct i2400m_work {
u8 pl[0];
};
-extern int i2400m_schedule_work(struct i2400m *,
- void (*)(struct work_struct *), gfp_t,
- const void *, size_t);
-
extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *,
char *, size_t);
extern int i2400m_msg_size_check(struct i2400m *,
const struct i2400m_l3l4_hdr *, size_t);
extern struct sk_buff *i2400m_msg_to_dev(struct i2400m *, const void *, size_t);
extern void i2400m_msg_to_dev_cancel_wait(struct i2400m *, int);
-extern void i2400m_msg_ack_hook(struct i2400m *,
- const struct i2400m_l3l4_hdr *, size_t);
extern void i2400m_report_hook(struct i2400m *,
const struct i2400m_l3l4_hdr *, size_t);
extern void i2400m_report_hook_work(struct work_struct *);
extern int i2400m_cmd_enter_powersave(struct i2400m *);
-extern int i2400m_cmd_get_state(struct i2400m *);
extern int i2400m_cmd_exit_idle(struct i2400m *);
extern struct sk_buff *i2400m_get_device_info(struct i2400m *);
extern int i2400m_firmware_check(struct i2400m *);
-extern int i2400m_set_init_config(struct i2400m *,
- const struct i2400m_tlv_hdr **, size_t);
extern int i2400m_set_idle_timeout(struct i2400m *, unsigned);
static inline
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c
index 1737d1488b35..844133b44af0 100644
--- a/drivers/net/wimax/i2400m/rx.c
+++ b/drivers/net/wimax/i2400m/rx.c
@@ -922,7 +922,7 @@ void i2400m_roq_queue_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
* rx_roq_refcount becomes zero. This routine gets executed when
* rx_roq_refcount becomes zero.
*/
-void i2400m_rx_roq_destroy(struct kref *ref)
+static void i2400m_rx_roq_destroy(struct kref *ref)
{
unsigned itr;
struct i2400m *i2400m
diff --git a/drivers/net/wimax/i2400m/sdio-rx.c b/drivers/net/wimax/i2400m/sdio-rx.c
index 8b809c2ead6c..fb6396dd115f 100644
--- a/drivers/net/wimax/i2400m/sdio-rx.c
+++ b/drivers/net/wimax/i2400m/sdio-rx.c
@@ -87,7 +87,7 @@ static const __le32 i2400m_ACK_BARKER[4] = {
*
* sdio_readl() doesn't work.
*/
-ssize_t __i2400ms_rx_get_size(struct i2400ms *i2400ms)
+static ssize_t __i2400ms_rx_get_size(struct i2400ms *i2400ms)
{
int ret, cnt, val;
ssize_t rx_size;
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 174e3442d519..4de4410cd38e 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig"
source "drivers/net/wireless/orinoco/Kconfig"
source "drivers/net/wireless/p54/Kconfig"
source "drivers/net/wireless/rt2x00/Kconfig"
+source "drivers/net/wireless/wl1251/Kconfig"
source "drivers/net/wireless/wl12xx/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 5d4ce4d2b32b..06f8ca26c5c1 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_ATH_COMMON) += ath/
obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
+obj-$(CONFIG_WL1251) += wl1251/
obj-$(CONFIG_WL12XX) += wl12xx/
+obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/
obj-$(CONFIG_IWM) += iwmc3200wifi/
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index ce77575e88b3..a36e7870b03e 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -105,7 +105,7 @@ static struct pci_driver airo_driver = {
of statistics in the /proc filesystem */
#define IGNLABEL(comment) NULL
-static char *statsLabels[] = {
+static const char *statsLabels[] = {
"RxOverrun",
IGNLABEL("RxPlcpCrcErr"),
IGNLABEL("RxPlcpFormatErr"),
@@ -217,7 +217,6 @@ static char *statsLabels[] = {
(no spaces) list of rates (up to 8). */
static int rates[8];
-static int basic_rate;
static char *ssids[3];
static int io[4];
@@ -250,7 +249,6 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
module_param_array(io, int, NULL, 0);
module_param_array(irq, int, NULL, 0);
-module_param(basic_rate, int, 0);
module_param_array(rates, int, NULL, 0);
module_param_array(ssids, charp, NULL, 0);
module_param(auto_wep, int, 0);
@@ -932,7 +930,7 @@ typedef struct aironet_ioctl {
unsigned char __user *data; // d-data
} aironet_ioctl;
-static char swversion[] = "2.1";
+static const char swversion[] = "2.1";
#endif /* CISCO_EXT */
#define NUM_MODULES 2
@@ -1374,7 +1372,7 @@ static int micsetup(struct airo_info *ai) {
return SUCCESS;
}
-static char micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
+static const u8 micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
/*===========================================================================
* Description: Mic a packet
@@ -2723,9 +2721,8 @@ static int airo_networks_allocate(struct airo_info *ai)
if (ai->networks)
return 0;
- ai->networks =
- kzalloc(AIRO_MAX_NETWORK_COUNT * sizeof(BSSListElement),
- GFP_KERNEL);
+ ai->networks = kcalloc(AIRO_MAX_NETWORK_COUNT, sizeof(BSSListElement),
+ GFP_KERNEL);
if (!ai->networks) {
airo_print_warn("", "Out of memory allocating beacons");
return -ENOMEM;
@@ -3884,15 +3881,6 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
ai->config.rates[i] = rates[i];
}
}
- if ( basic_rate > 0 ) {
- for( i = 0; i < 8; i++ ) {
- if ( ai->config.rates[i] == basic_rate ||
- !ai->config.rates ) {
- ai->config.rates[i] = basic_rate | 0x80;
- break;
- }
- }
- }
set_bit (FLAG_COMMIT, &ai->flags);
}
@@ -5032,7 +5020,7 @@ static void proc_config_on_close(struct inode *inode, struct file *file)
airo_config_commit(dev, NULL, NULL, NULL);
}
-static char *get_rmode(__le16 mode)
+static const char *get_rmode(__le16 mode)
{
switch(mode & RXMODE_MASK) {
case RXMODE_RFMON: return "rfmon";
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 1128fa8c9ed5..1476314afa8a 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1525,8 +1525,7 @@ static void at76_rx_tasklet(unsigned long param)
if (priv->device_unplugged) {
at76_dbg(DBG_DEVSTART, "device unplugged");
- if (urb)
- at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+ at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
return;
}
@@ -2061,11 +2060,12 @@ static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
int i;
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
+ at76_dbg(DBG_MAC80211, "%s(): cmd %d key->cipher %d key->keyidx %d "
"key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ __func__, cmd, key->cipher, key->keyidx, key->keylen);
- if (key->alg != ALG_WEP)
+ if ((key->cipher != WLAN_CIPHER_SUITE_WEP40) &&
+ (key->cipher != WLAN_CIPHER_SUITE_WEP104))
return -EOPNOTSUPP;
key->hw_key_idx = key->keyidx;
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 0a75be027afa..92c216263ee9 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -25,5 +25,6 @@ config ATH_DEBUG
source "drivers/net/wireless/ath/ath5k/Kconfig"
source "drivers/net/wireless/ath/ath9k/Kconfig"
source "drivers/net/wireless/ath/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 8113a5042afa..6d711ec97ec2 100644
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
@@ -1,11 +1,13 @@
obj-$(CONFIG_ATH5K) += ath5k/
obj-$(CONFIG_ATH9K_HW) += ath9k/
obj-$(CONFIG_AR9170_USB) += ar9170/
+obj-$(CONFIG_CARL9170) += carl9170/
obj-$(CONFIG_ATH_COMMON) += ath.o
ath-objs := main.o \
regd.o \
- hw.o
+ hw.o \
+ key.o
ath-$(CONFIG_ATH_DEBUG) += debug.o
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index debfb0fbc7c5..32bf79e6a320 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -1190,14 +1190,13 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
if (info->control.hw_key) {
icv = info->control.hw_key->icv_len;
- switch (info->control.hw_key->alg) {
- case ALG_WEP:
+ 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 ALG_TKIP:
- keytype = AR9170_TX_MAC_ENCR_RC4;
- break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
keytype = AR9170_TX_MAC_ENCR_AES;
break;
default:
@@ -1778,17 +1777,17 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if ((!ar->vif) || (ar->disable_offload))
return -EOPNOTSUPP;
- switch (key->alg) {
- case ALG_WEP:
- if (key->keylen == WLAN_KEY_LEN_WEP40)
- ktype = AR9170_ENC_ALG_WEP64;
- else
- ktype = AR9170_ENC_ALG_WEP128;
+ 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 ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
ktype = AR9170_ENC_ALG_TKIP;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
ktype = AR9170_ENC_ALG_AESCCMP;
break;
default:
@@ -1827,7 +1826,7 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (err)
goto out;
- if (key->alg == ALG_TKIP) {
+ 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)
@@ -1864,7 +1863,7 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (err)
goto out;
- if (key->alg == ALG_TKIP) {
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
err = ar9170_upload_key(ar, key->hw_key_idx,
NULL,
AR9170_ENC_ALG_NONE, 1,
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index a93dc18a45c3..5dbb5361fd51 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -54,8 +54,6 @@ MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
MODULE_FIRMWARE("ar9170.fw");
-MODULE_FIRMWARE("ar9170-1.fw");
-MODULE_FIRMWARE("ar9170-2.fw");
enum ar9170_requirements {
AR9170_REQ_FW1_ONLY = 1,
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index d32f2828b098..501050c0296f 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -19,6 +19,7 @@
#include <linux/skbuff.h>
#include <linux/if_ether.h>
+#include <linux/spinlock.h>
#include <net/mac80211.h>
/*
@@ -35,7 +36,6 @@ static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
struct ath_ani {
bool caldone;
- int16_t noise_floor;
unsigned int longcal_timer;
unsigned int shortcal_timer;
unsigned int resetcal_timer;
@@ -43,6 +43,13 @@ struct ath_ani {
struct timer_list timer;
};
+struct ath_cycle_counters {
+ u32 cycles;
+ u32 rx_busy;
+ u32 rx_frame;
+ u32 tx_frame;
+};
+
enum ath_device_state {
ATH_HW_UNAVAILABLE,
ATH_HW_INITIALIZED,
@@ -71,20 +78,44 @@ struct ath_regulatory {
struct reg_dmn_pair_mapping *regpair;
};
+enum ath_crypt_caps {
+ ATH_CRYPT_CAP_CIPHER_AESCCM = BIT(0),
+ ATH_CRYPT_CAP_MIC_COMBINED = BIT(1),
+};
+
+struct ath_keyval {
+ u8 kv_type;
+ u8 kv_pad;
+ u16 kv_len;
+ u8 kv_val[16]; /* TK */
+ u8 kv_mic[8]; /* Michael MIC key */
+ u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
+ * supports both MIC keys in the same key cache entry;
+ * in that case, kv_mic is the RX key) */
+};
+
+enum ath_cipher {
+ ATH_CIPHER_WEP = 0,
+ ATH_CIPHER_AES_OCB = 1,
+ ATH_CIPHER_AES_CCM = 2,
+ ATH_CIPHER_CKIP = 3,
+ ATH_CIPHER_TKIP = 4,
+ ATH_CIPHER_CLR = 5,
+ ATH_CIPHER_MIC = 127
+};
+
/**
* struct ath_ops - Register read/write operations
*
* @read: Register read
* @write: Register write
* @enable_write_buffer: Enable multiple register writes
- * @disable_write_buffer: Disable multiple register writes
- * @write_flush: Flush buffered register writes
+ * @write_flush: flush buffered register writes and disable buffering
*/
struct ath_ops {
unsigned int (*read)(void *, u32 reg_offset);
void (*write)(void *, u32 val, u32 reg_offset);
void (*enable_write_buffer)(void *);
- void (*disable_write_buffer)(void *);
void (*write_flush) (void *);
};
@@ -119,7 +150,14 @@ struct ath_common {
u32 keymax;
DECLARE_BITMAP(keymap, ATH_KEYMAX);
- u8 splitmic;
+ DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX);
+ enum ath_crypt_caps crypt_caps;
+
+ unsigned int clockrate;
+
+ spinlock_t cc_lock;
+ struct ath_cycle_counters cc_ani;
+ struct ath_cycle_counters cc_survey;
struct ath_regulatory regulatory;
const struct ath_ops *ops;
@@ -131,5 +169,13 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
gfp_t gfp_mask);
void ath_hw_setbssidmask(struct ath_common *common);
+void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key);
+int ath_key_config(struct ath_common *common,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key);
+bool ath_hw_keyreset(struct ath_common *common, u16 entry);
+void ath_hw_cycle_counters_update(struct ath_common *common);
+int32_t ath_hw_get_listen_time(struct ath_common *common);
#endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index 26dbe65fedb0..f1419198a479 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -355,41 +355,28 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
/**
- * ath5k_hw_ani_get_listen_time() - Calculate time spent listening
+ * ath5k_hw_ani_get_listen_time() - Update counters and return listening time
*
* Return an approximation of the time spent "listening" in milliseconds (ms)
- * since the last call of this function by deducting the cycles spent
- * transmitting and receiving from the total cycle count.
- * Save profile count values for debugging/statistics and because we might want
- * to use them later.
- *
- * We assume no one else clears these registers!
+ * since the last call of this function.
+ * Save a snapshot of the counter values for debugging/statistics.
*/
static int
ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
{
+ struct ath_common *common = ath5k_hw_common(ah);
int listen;
- /* freeze */
- ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC);
- /* read */
- as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE);
- as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR);
- as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX);
- as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX);
- /* clear */
- ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
- ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
- ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
- ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
- /* un-freeze */
- ath5k_hw_reg_write(ah, 0, AR5K_MIBC);
-
- /* TODO: where does 44000 come from? (11g clock rate?) */
- listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000;
-
- if (as->pfc_cycles == 0 || listen < 0)
- return 0;
+ spin_lock_bh(&common->cc_lock);
+
+ ath_hw_cycle_counters_update(common);
+ memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc));
+
+ /* clears common->cc_ani */
+ listen = ath_hw_get_listen_time(common);
+
+ spin_unlock_bh(&common->cc_lock);
+
return listen;
}
@@ -552,9 +539,9 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah)
if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO)
return;
- /* if one of the errors triggered, we can get a superfluous second
- * interrupt, even though we have already reset the register. the
- * function detects that so we can return early */
+ /* If one of the errors triggered, we can get a superfluous second
+ * interrupt, even though we have already reset the register. The
+ * function detects that so we can return early. */
if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0)
return;
diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h
index 55cf26d8522c..d0a664039c87 100644
--- a/drivers/net/wireless/ath/ath5k/ani.h
+++ b/drivers/net/wireless/ath/ath5k/ani.h
@@ -75,10 +75,7 @@ struct ath5k_ani_state {
unsigned int cck_errors;
/* debug/statistics only: numbers from last ANI calibration */
- unsigned int pfc_tx;
- unsigned int pfc_rx;
- unsigned int pfc_busy;
- unsigned int pfc_cycles;
+ struct ath_cycle_counters last_cc;
unsigned int last_listen;
unsigned int last_ofdm_errors;
unsigned int last_cck_errors;
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index ea6362a8988d..4a367cdb3eb9 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -175,7 +175,7 @@
#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0
#define AR5K_TUNE_RADAR_ALERT false
#define AR5K_TUNE_MIN_TX_FIFO_THRES 1
-#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1)
+#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_FRAME_LEN / 64) + 1)
#define AR5K_TUNE_REGISTER_TIMEOUT 20000
/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
* be the max value. */
@@ -206,6 +206,8 @@
#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */
#define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */
+#define ATH5K_TX_COMPLETE_POLL_INT 3000 /* 3 sec */
+
#define AR5K_INIT_CARR_SENSE_EN 1
/*Swap RX/TX Descriptor for big endian archs*/
@@ -256,8 +258,6 @@
(AR5K_INIT_PROG_IFS_TURBO) \
)
-/* token to use for aifs, cwmin, cwmax in MadWiFi */
-#define AR5K_TXQ_USEDEFAULT ((u32) -1)
/* GENERIC CHIPSET DEFINITIONS */
@@ -343,9 +343,6 @@ struct ath5k_srev_name {
#define AR5K_SREV_PHY_5413 0x61
#define AR5K_SREV_PHY_2425 0x70
-/* IEEE defs */
-#define IEEE80211_MAX_LEN 2500
-
/* TODO add support to mac80211 for vendor-specific rates and modes */
/*
@@ -531,9 +528,9 @@ struct ath5k_txq_info {
enum ath5k_tx_queue tqi_type;
enum ath5k_tx_queue_subtype tqi_subtype;
u16 tqi_flags; /* Tx queue flags (see above) */
- u32 tqi_aifs; /* Arbitrated Interframe Space */
- s32 tqi_cw_min; /* Minimum Contention Window */
- s32 tqi_cw_max; /* Maximum Contention Window */
+ u8 tqi_aifs; /* Arbitrated Interframe Space */
+ u16 tqi_cw_min; /* Minimum Contention Window */
+ u16 tqi_cw_max; /* Maximum Contention Window */
u32 tqi_cbr_period; /* Constant bit rate period */
u32 tqi_cbr_overflow_limit;
u32 tqi_burst_time;
@@ -1031,8 +1028,6 @@ struct ath5k_hw {
bool ah_turbo;
bool ah_calibration;
bool ah_single_chip;
- bool ah_aes_support;
- bool ah_combined_mic;
enum ath5k_version ah_version;
enum ath5k_radio ah_radio;
@@ -1046,10 +1041,6 @@ struct ath5k_hw {
#define ah_modes ah_capabilities.cap_mode
#define ah_ee_version ah_capabilities.cap_eeprom.ee_version
- u32 ah_atim_window;
- u32 ah_aifs;
- u32 ah_cw_min;
- u32 ah_cw_max;
u32 ah_limit_tx_retries;
u8 ah_coverage_class;
@@ -1190,7 +1181,7 @@ extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
/* BSSID Functions */
int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
-void ath5k_hw_set_associd(struct ath5k_hw *ah);
+void ath5k_hw_set_bssid(struct ath5k_hw *ah);
void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
/* Receive start/stop functions */
void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
@@ -1204,17 +1195,13 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
+bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval);
/* ACK bit rate */
void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
/* Clock rate related functions */
unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
-unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
-/* Key table (WEP) functions */
-int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
-int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
- const struct ieee80211_key_conf *key, const u8 *mac);
-int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
+void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
/* Queue Control Unit, DFS Control Unit Functions */
int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index b32e28caeee2..cd0b14a0a93a 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -118,9 +118,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
ah->ah_turbo = false;
ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
ah->ah_imr = 0;
- ah->ah_atim_window = 0;
- ah->ah_aifs = AR5K_TUNE_AIFS;
- ah->ah_cw_min = AR5K_TUNE_CWMIN;
ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
ah->ah_software_retry = false;
ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
@@ -139,12 +136,12 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
else
ah->ah_version = AR5K_AR5212;
- /*Fill the ath5k_hw struct with the needed functions*/
+ /* Fill the ath5k_hw struct with the needed functions */
ret = ath5k_hw_init_desc_functions(ah);
if (ret)
goto err_free;
- /* Bring device out of sleep and reset it's units */
+ /* Bring device out of sleep and reset its units */
ret = ath5k_hw_nic_wakeup(ah, 0, true);
if (ret)
goto err_free;
@@ -158,7 +155,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
CHANNEL_5GHZ);
ah->ah_phy = AR5K_PHY(0);
- /* Try to identify radio chip based on it's srev */
+ /* Try to identify radio chip based on its srev */
switch (ah->ah_radio_5ghz_revision & 0xf0) {
case AR5K_SREV_RAD_5111:
ah->ah_radio = AR5K_RF5111;
@@ -314,12 +311,16 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
}
/* Crypto settings */
- ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 &&
- (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 &&
- !AR5K_EEPROM_AES_DIS(ee->ee_misc5));
+ 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 &&
+ !AR5K_EEPROM_AES_DIS(ee->ee_misc5)))
+ common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
if (srev >= AR5K_SREV_AR2414) {
- ah->ah_combined_mic = true;
+ common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE,
AR5K_MISC_MODE_COMBINED_MIC);
}
@@ -329,7 +330,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
- ath5k_hw_set_associd(ah);
+ ath5k_hw_set_bssid(ah);
ath5k_hw_set_opmode(ah, sc->opmode);
ath5k_hw_rfgain_opt_init(ah);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index d77ce9906b6c..f1ae75d35d5d 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -52,6 +52,7 @@
#include <linux/ethtool.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
+#include <linux/etherdevice.h>
#include <net/ieee80211_radiotap.h>
@@ -61,6 +62,7 @@
#include "reg.h"
#include "debug.h"
#include "ani.h"
+#include "../debug.h"
static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
@@ -70,11 +72,6 @@ static int modparam_all_channels;
module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
-
-/******************\
-* Internal defines *
-\******************/
-
/* Module info */
MODULE_AUTHOR("Jiri Slaby");
MODULE_AUTHOR("Nick Kossifidis");
@@ -83,6 +80,10 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
+static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
+static int ath5k_beacon_update(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
+static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
/* Known PCI ids */
static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
@@ -190,129 +191,6 @@ static const struct ieee80211_rate ath5k_rates[] = {
/* XR missing */
};
-/*
- * Prototypes - PCI stack related functions
- */
-static int __devinit ath5k_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id);
-static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
-#ifdef CONFIG_PM_SLEEP
-static int ath5k_pci_suspend(struct device *dev);
-static int ath5k_pci_resume(struct device *dev);
-
-static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
-#define ATH5K_PM_OPS (&ath5k_pm_ops)
-#else
-#define ATH5K_PM_OPS NULL
-#endif /* CONFIG_PM_SLEEP */
-
-static struct pci_driver ath5k_pci_driver = {
- .name = KBUILD_MODNAME,
- .id_table = ath5k_pci_id_table,
- .probe = ath5k_pci_probe,
- .remove = __devexit_p(ath5k_pci_remove),
- .driver.pm = ATH5K_PM_OPS,
-};
-
-
-
-/*
- * Prototypes - MAC 802.11 stack related functions
- */
-static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ath5k_txq *txq);
-static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
-static int ath5k_start(struct ieee80211_hw *hw);
-static void ath5k_stop(struct ieee80211_hw *hw);
-static int ath5k_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif);
-static void ath5k_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif);
-static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
-static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
- struct netdev_hw_addr_list *mc_list);
-static void ath5k_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *new_flags,
- u64 multicast);
-static int ath5k_set_key(struct ieee80211_hw *hw,
- enum set_key_cmd cmd,
- struct ieee80211_vif *vif, struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key);
-static int ath5k_get_stats(struct ieee80211_hw *hw,
- struct ieee80211_low_level_stats *stats);
-static int ath5k_get_survey(struct ieee80211_hw *hw,
- int idx, struct survey_info *survey);
-static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
-static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
-static void ath5k_reset_tsf(struct ieee80211_hw *hw);
-static int ath5k_beacon_update(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif);
-static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes);
-static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
-static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
-static void ath5k_set_coverage_class(struct ieee80211_hw *hw,
- u8 coverage_class);
-
-static const struct ieee80211_ops ath5k_hw_ops = {
- .tx = ath5k_tx,
- .start = ath5k_start,
- .stop = ath5k_stop,
- .add_interface = ath5k_add_interface,
- .remove_interface = ath5k_remove_interface,
- .config = ath5k_config,
- .prepare_multicast = ath5k_prepare_multicast,
- .configure_filter = ath5k_configure_filter,
- .set_key = ath5k_set_key,
- .get_stats = ath5k_get_stats,
- .get_survey = ath5k_get_survey,
- .conf_tx = NULL,
- .get_tsf = ath5k_get_tsf,
- .set_tsf = ath5k_set_tsf,
- .reset_tsf = ath5k_reset_tsf,
- .bss_info_changed = ath5k_bss_info_changed,
- .sw_scan_start = ath5k_sw_scan_start,
- .sw_scan_complete = ath5k_sw_scan_complete,
- .set_coverage_class = ath5k_set_coverage_class,
-};
-
-/*
- * Prototypes - Internal functions
- */
-/* Attach detach */
-static int ath5k_attach(struct pci_dev *pdev,
- struct ieee80211_hw *hw);
-static void ath5k_detach(struct pci_dev *pdev,
- struct ieee80211_hw *hw);
-/* Channel/mode setup */
-static inline short ath5k_ieee2mhz(short chan);
-static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
- struct ieee80211_channel *channels,
- unsigned int mode,
- unsigned int max);
-static int ath5k_setup_bands(struct ieee80211_hw *hw);
-static int ath5k_chan_set(struct ath5k_softc *sc,
- struct ieee80211_channel *chan);
-static void ath5k_setcurmode(struct ath5k_softc *sc,
- unsigned int mode);
-static void ath5k_mode_setup(struct ath5k_softc *sc);
-
-/* Descriptor setup */
-static int ath5k_desc_alloc(struct ath5k_softc *sc,
- struct pci_dev *pdev);
-static void ath5k_desc_free(struct ath5k_softc *sc,
- struct pci_dev *pdev);
-/* Buffers setup */
-static int ath5k_rxbuf_setup(struct ath5k_softc *sc,
- struct ath5k_buf *bf);
-static int ath5k_txbuf_setup(struct ath5k_softc *sc,
- struct ath5k_buf *bf,
- struct ath5k_txq *txq, int padsize);
-
static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc,
struct ath5k_buf *bf)
{
@@ -345,35 +223,6 @@ static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc,
}
-/* Queues setup */
-static struct ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
- int qtype, int subtype);
-static int ath5k_beaconq_setup(struct ath5k_hw *ah);
-static int ath5k_beaconq_config(struct ath5k_softc *sc);
-static void ath5k_txq_drainq(struct ath5k_softc *sc,
- struct ath5k_txq *txq);
-static void ath5k_txq_cleanup(struct ath5k_softc *sc);
-static void ath5k_txq_release(struct ath5k_softc *sc);
-/* Rx handling */
-static int ath5k_rx_start(struct ath5k_softc *sc);
-static void ath5k_rx_stop(struct ath5k_softc *sc);
-static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
- struct sk_buff *skb,
- struct ath5k_rx_status *rs);
-static void ath5k_tasklet_rx(unsigned long data);
-/* Tx handling */
-static void ath5k_tx_processq(struct ath5k_softc *sc,
- struct ath5k_txq *txq);
-static void ath5k_tasklet_tx(unsigned long data);
-/* Beacon handling */
-static int ath5k_beacon_setup(struct ath5k_softc *sc,
- struct ath5k_buf *bf);
-static void ath5k_beacon_send(struct ath5k_softc *sc);
-static void ath5k_beacon_config(struct ath5k_softc *sc);
-static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
-static void ath5k_tasklet_beacon(unsigned long data);
-static void ath5k_tasklet_ani(unsigned long data);
-
static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
{
u64 tsf = ath5k_hw_get_tsf64(ah);
@@ -384,50 +233,6 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
return (tsf & ~0x7fff) | rstamp;
}
-/* Interrupt handling */
-static int ath5k_init(struct ath5k_softc *sc);
-static int ath5k_stop_locked(struct ath5k_softc *sc);
-static int ath5k_stop_hw(struct ath5k_softc *sc);
-static irqreturn_t ath5k_intr(int irq, void *dev_id);
-static void ath5k_reset_work(struct work_struct *work);
-
-static void ath5k_tasklet_calibrate(unsigned long data);
-
-/*
- * Module init/exit functions
- */
-static int __init
-init_ath5k_pci(void)
-{
- int ret;
-
- ath5k_debug_init();
-
- ret = pci_register_driver(&ath5k_pci_driver);
- if (ret) {
- printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
- return ret;
- }
-
- return 0;
-}
-
-static void __exit
-exit_ath5k_pci(void)
-{
- pci_unregister_driver(&ath5k_pci_driver);
-
- ath5k_debug_finish();
-}
-
-module_init(init_ath5k_pci);
-module_exit(exit_ath5k_pci);
-
-
-/********************\
-* PCI Initialization *
-\********************/
-
static const char *
ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
{
@@ -466,299 +271,6 @@ static const struct ath_ops ath5k_common_ops = {
.write = ath5k_iowrite32,
};
-static int __devinit
-ath5k_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- void __iomem *mem;
- struct ath5k_softc *sc;
- struct ath_common *common;
- struct ieee80211_hw *hw;
- int ret;
- u8 csz;
-
- /*
- * L0s needs to be disabled on all ath5k cards.
- *
- * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
- * by default in the future in 2.6.36) this will also mean both L1 and
- * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
- * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
- * though but cannot currently undue the effect of a blacklist, for
- * details you can read pcie_aspm_sanity_check() and see how it adjusts
- * the device link capability.
- *
- * It may be possible in the future to implement some PCI API to allow
- * drivers to override blacklists for pre 1.1 PCIe but for now it is
- * best to accept that both L0s and L1 will be disabled completely for
- * distributions shipping with CONFIG_PCIEASPM rather than having this
- * issue present. Motivation for adding this new API will be to help
- * with power consumption for some of these devices.
- */
- pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
-
- ret = pci_enable_device(pdev);
- if (ret) {
- dev_err(&pdev->dev, "can't enable device\n");
- goto err;
- }
-
- /* XXX 32-bit addressing only */
- ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
- if (ret) {
- dev_err(&pdev->dev, "32-bit DMA not available\n");
- goto err_dis;
- }
-
- /*
- * Cache line size is used to size and align various
- * structures used to communicate with the hardware.
- */
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
- if (csz == 0) {
- /*
- * Linux 2.4.18 (at least) writes the cache line size
- * register as a 16-bit wide register which is wrong.
- * We must have this setup properly for rx buffer
- * DMA to work so force a reasonable value here if it
- * comes up zero.
- */
- csz = L1_CACHE_BYTES >> 2;
- pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
- }
- /*
- * The default setting of latency timer yields poor results,
- * set it to the value used by other systems. It may be worth
- * tweaking this setting more.
- */
- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
-
- /* Enable bus mastering */
- pci_set_master(pdev);
-
- /*
- * Disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state.
- */
- pci_write_config_byte(pdev, 0x41, 0);
-
- ret = pci_request_region(pdev, 0, "ath5k");
- if (ret) {
- dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
- goto err_dis;
- }
-
- mem = pci_iomap(pdev, 0, 0);
- if (!mem) {
- dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
- ret = -EIO;
- goto err_reg;
- }
-
- /*
- * Allocate hw (mac80211 main struct)
- * and hw->priv (driver private data)
- */
- hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
- if (hw == NULL) {
- dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
- ret = -ENOMEM;
- goto err_map;
- }
-
- dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
-
- /* Initialize driver private data */
- SET_IEEE80211_DEV(hw, &pdev->dev);
- hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
-
- hw->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_AP) |
- BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_MESH_POINT);
-
- hw->extra_tx_headroom = 2;
- hw->channel_change_time = 5000;
- sc = hw->priv;
- sc->hw = hw;
- sc->pdev = pdev;
-
- ath5k_debug_init_device(sc);
-
- /*
- * Mark the device as detached to avoid processing
- * interrupts until setup is complete.
- */
- __set_bit(ATH_STAT_INVALID, sc->status);
-
- sc->iobase = mem; /* So we can unmap it on detach */
- sc->opmode = NL80211_IFTYPE_STATION;
- sc->bintval = 1000;
- mutex_init(&sc->lock);
- spin_lock_init(&sc->rxbuflock);
- spin_lock_init(&sc->txbuflock);
- spin_lock_init(&sc->block);
-
- /* Set private data */
- pci_set_drvdata(pdev, sc);
-
- /* Setup interrupt handler */
- ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
- if (ret) {
- ATH5K_ERR(sc, "request_irq failed\n");
- goto err_free;
- }
-
- /*If we passed the test malloc a ath5k_hw struct*/
- sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
- if (!sc->ah) {
- ret = -ENOMEM;
- ATH5K_ERR(sc, "out of memory\n");
- goto err_irq;
- }
-
- sc->ah->ah_sc = sc;
- sc->ah->ah_iobase = sc->iobase;
- common = ath5k_hw_common(sc->ah);
- common->ops = &ath5k_common_ops;
- common->ah = sc->ah;
- common->hw = hw;
- common->cachelsz = csz << 2; /* convert to bytes */
-
- /* Initialize device */
- ret = ath5k_hw_attach(sc);
- if (ret) {
- goto err_free_ah;
- }
-
- /* set up multi-rate retry capabilities */
- if (sc->ah->ah_version == AR5K_AR5212) {
- hw->max_rates = 4;
- hw->max_rate_tries = 11;
- }
-
- /* Finish private driver data initialization */
- ret = ath5k_attach(pdev, hw);
- if (ret)
- goto err_ah;
-
- ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
- sc->ah->ah_mac_srev,
- sc->ah->ah_phy_revision);
-
- if (!sc->ah->ah_single_chip) {
- /* Single chip radio (!RF5111) */
- if (sc->ah->ah_radio_5ghz_revision &&
- !sc->ah->ah_radio_2ghz_revision) {
- /* No 5GHz support -> report 2GHz radio */
- if (!test_bit(AR5K_MODE_11A,
- sc->ah->ah_capabilities.cap_mode)) {
- ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- /* No 2GHz support (5110 and some
- * 5Ghz only cards) -> report 5Ghz radio */
- } else if (!test_bit(AR5K_MODE_11B,
- sc->ah->ah_capabilities.cap_mode)) {
- ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- /* Multiband radio */
- } else {
- ATH5K_INFO(sc, "RF%s multiband radio found"
- " (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- }
- }
- /* Multi chip radio (RF5111 - RF2111) ->
- * report both 2GHz/5GHz radios */
- else if (sc->ah->ah_radio_5ghz_revision &&
- sc->ah->ah_radio_2ghz_revision){
- ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_2ghz_revision),
- sc->ah->ah_radio_2ghz_revision);
- }
- }
-
-
- /* ready to process interrupts */
- __clear_bit(ATH_STAT_INVALID, sc->status);
-
- return 0;
-err_ah:
- ath5k_hw_detach(sc->ah);
-err_irq:
- free_irq(pdev->irq, sc);
-err_free_ah:
- kfree(sc->ah);
-err_free:
- ieee80211_free_hw(hw);
-err_map:
- pci_iounmap(pdev, mem);
-err_reg:
- pci_release_region(pdev, 0);
-err_dis:
- pci_disable_device(pdev);
-err:
- return ret;
-}
-
-static void __devexit
-ath5k_pci_remove(struct pci_dev *pdev)
-{
- struct ath5k_softc *sc = pci_get_drvdata(pdev);
-
- ath5k_debug_finish_device(sc);
- ath5k_detach(pdev, sc->hw);
- ath5k_hw_detach(sc->ah);
- kfree(sc->ah);
- free_irq(pdev->irq, sc);
- pci_iounmap(pdev, sc->iobase);
- pci_release_region(pdev, 0);
- pci_disable_device(pdev);
- ieee80211_free_hw(sc->hw);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int ath5k_pci_suspend(struct device *dev)
-{
- struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
-
- ath5k_led_off(sc);
- return 0;
-}
-
-static int ath5k_pci_resume(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct ath5k_softc *sc = pci_get_drvdata(pdev);
-
- /*
- * Suspend/Resume resets the PCI configuration space, so we have to
- * re-disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state
- */
- pci_write_config_byte(pdev, 0x41, 0);
-
- ath5k_led_enable(sc);
- return 0;
-}
-#endif /* CONFIG_PM_SLEEP */
-
-
/***********************\
* Driver Initialization *
\***********************/
@@ -772,170 +284,6 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re
return ath_reg_notifier_apply(wiphy, request, regulatory);
}
-static int
-ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
-{
- struct ath5k_softc *sc = hw->priv;
- struct ath5k_hw *ah = sc->ah;
- struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
- u8 mac[ETH_ALEN] = {};
- int ret;
-
- ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
-
- /*
- * Check if the MAC has multi-rate retry support.
- * We do this by trying to setup a fake extended
- * descriptor. MAC's that don't have support will
- * return false w/o doing anything. MAC's that do
- * support it will return true w/o doing anything.
- */
- ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
-
- if (ret < 0)
- goto err;
- if (ret > 0)
- __set_bit(ATH_STAT_MRRETRY, sc->status);
-
- /*
- * Collect the channel list. The 802.11 layer
- * is resposible for filtering this list based
- * on settings like the phy mode and regulatory
- * domain restrictions.
- */
- ret = ath5k_setup_bands(hw);
- if (ret) {
- ATH5K_ERR(sc, "can't get channels\n");
- goto err;
- }
-
- /* NB: setup here so ath5k_rate_update is happy */
- if (test_bit(AR5K_MODE_11A, ah->ah_modes))
- ath5k_setcurmode(sc, AR5K_MODE_11A);
- else
- ath5k_setcurmode(sc, AR5K_MODE_11B);
-
- /*
- * Allocate tx+rx descriptors and populate the lists.
- */
- ret = ath5k_desc_alloc(sc, pdev);
- if (ret) {
- ATH5K_ERR(sc, "can't allocate descriptors\n");
- goto err;
- }
-
- /*
- * Allocate hardware transmit queues: one queue for
- * beacon frames and one data queue for each QoS
- * priority. Note that hw functions handle reseting
- * these queues at the needed time.
- */
- ret = ath5k_beaconq_setup(ah);
- if (ret < 0) {
- ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
- goto err_desc;
- }
- sc->bhalq = ret;
- sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0);
- if (IS_ERR(sc->cabq)) {
- ATH5K_ERR(sc, "can't setup cab queue\n");
- ret = PTR_ERR(sc->cabq);
- goto err_bhal;
- }
-
- sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
- if (IS_ERR(sc->txq)) {
- ATH5K_ERR(sc, "can't setup xmit queue\n");
- ret = PTR_ERR(sc->txq);
- goto err_queues;
- }
-
- tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
- tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
- tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
- tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
- tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
-
- INIT_WORK(&sc->reset_work, ath5k_reset_work);
-
- ret = ath5k_eeprom_read_mac(ah, mac);
- if (ret) {
- ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
- sc->pdev->device);
- goto err_queues;
- }
-
- SET_IEEE80211_PERM_ADDR(hw, mac);
- /* All MAC address bits matter for ACKs */
- memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
- ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
-
- regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
- ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
- if (ret) {
- ATH5K_ERR(sc, "can't initialize regulatory system\n");
- goto err_queues;
- }
-
- ret = ieee80211_register_hw(hw);
- if (ret) {
- ATH5K_ERR(sc, "can't register ieee80211 hw\n");
- goto err_queues;
- }
-
- if (!ath_is_world_regd(regulatory))
- regulatory_hint(hw->wiphy, regulatory->alpha2);
-
- ath5k_init_leds(sc);
-
- ath5k_sysfs_register(sc);
-
- return 0;
-err_queues:
- ath5k_txq_release(sc);
-err_bhal:
- ath5k_hw_release_tx_queue(ah, sc->bhalq);
-err_desc:
- ath5k_desc_free(sc, pdev);
-err:
- return ret;
-}
-
-static void
-ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
-{
- struct ath5k_softc *sc = hw->priv;
-
- /*
- * NB: the order of these is important:
- * o call the 802.11 layer before detaching ath5k_hw to
- * insure callbacks into the driver to delete global
- * key cache entries can be handled
- * o reclaim the tx queue data structures after calling
- * the 802.11 layer as we'll get called back to reclaim
- * node state and potentially want to use them
- * o to cleanup the tx queues the hal is called, so detach
- * it last
- * XXX: ??? detach ath5k_hw ???
- * Other than that, it's straightforward...
- */
- ieee80211_unregister_hw(hw);
- ath5k_desc_free(sc, pdev);
- ath5k_txq_release(sc);
- ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
- ath5k_unregister_leds(sc);
-
- ath5k_sysfs_unregister(sc);
- /*
- * NB: can't reclaim these until after ieee80211_ifdetach
- * returns because we'll get called back to reclaim node
- * state and potentially want to use them.
- */
-}
-
-
-
-
/********************\
* Channel/mode setup *
\********************/
@@ -1163,8 +511,101 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
}
}
+struct ath_vif_iter_data {
+ const u8 *hw_macaddr;
+ u8 mask[ETH_ALEN];
+ u8 active_mac[ETH_ALEN]; /* first active MAC */
+ bool need_set_hw_addr;
+ bool found_active;
+ bool any_assoc;
+ enum nl80211_iftype opmode;
+};
+
+static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct ath_vif_iter_data *iter_data = data;
+ int i;
+ struct ath5k_vif *avf = (void *)vif->drv_priv;
+
+ if (iter_data->hw_macaddr)
+ for (i = 0; i < ETH_ALEN; i++)
+ iter_data->mask[i] &=
+ ~(iter_data->hw_macaddr[i] ^ mac[i]);
+
+ if (!iter_data->found_active) {
+ iter_data->found_active = true;
+ memcpy(iter_data->active_mac, mac, ETH_ALEN);
+ }
+
+ if (iter_data->need_set_hw_addr && iter_data->hw_macaddr)
+ if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0)
+ iter_data->need_set_hw_addr = false;
+
+ if (!iter_data->any_assoc) {
+ if (avf->assoc)
+ iter_data->any_assoc = true;
+ }
+
+ /* Calculate combined mode - when APs are active, operate in AP mode.
+ * Otherwise use the mode of the new interface. This can currently
+ * only deal with combinations of APs and STAs. Only one ad-hoc
+ * interfaces is allowed above.
+ */
+ if (avf->opmode == NL80211_IFTYPE_AP)
+ iter_data->opmode = NL80211_IFTYPE_AP;
+ else
+ if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED)
+ iter_data->opmode = avf->opmode;
+}
+
+static void ath_do_set_opmode(struct ath5k_softc *sc)
+{
+ struct ath5k_hw *ah = sc->ah;
+ ath5k_hw_set_opmode(ah, sc->opmode);
+ ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
+ sc->opmode, ath_opmode_to_string(sc->opmode));
+}
+
+void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
+ struct ieee80211_vif *vif)
+{
+ struct ath_common *common = ath5k_hw_common(sc->ah);
+ struct ath_vif_iter_data iter_data;
+
+ /*
+ * Use the hardware MAC address as reference, the hardware uses it
+ * together with the BSSID mask when matching addresses.
+ */
+ iter_data.hw_macaddr = common->macaddr;
+ memset(&iter_data.mask, 0xff, ETH_ALEN);
+ iter_data.found_active = false;
+ iter_data.need_set_hw_addr = true;
+ iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED;
+
+ if (vif)
+ ath_vif_iter(&iter_data, vif->addr, vif);
+
+ /* Get list of all active MAC addresses */
+ ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter,
+ &iter_data);
+ memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
+
+ sc->opmode = iter_data.opmode;
+ if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED)
+ /* Nothing active, default to station mode */
+ sc->opmode = NL80211_IFTYPE_STATION;
+
+ ath_do_set_opmode(sc);
+
+ if (iter_data.need_set_hw_addr && iter_data.found_active)
+ ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
+
+ if (ath5k_hw_hasbssidmask(sc->ah))
+ ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
+}
+
static void
-ath5k_mode_setup(struct ath5k_softc *sc)
+ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif)
{
struct ath5k_hw *ah = sc->ah;
u32 rfilt;
@@ -1172,15 +613,9 @@ ath5k_mode_setup(struct ath5k_softc *sc)
/* configure rx filter */
rfilt = sc->filter_flags;
ath5k_hw_set_rx_filter(ah, rfilt);
-
- if (ath5k_hw_hasbssidmask(ah))
- ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
-
- /* configure operational mode */
- ath5k_hw_set_opmode(ah, sc->opmode);
-
- ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
+
+ ath5k_update_bssid_mask_and_opmode(sc, vif);
}
static inline int
@@ -1352,13 +787,13 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
flags |= AR5K_TXDESC_RTSENA;
cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
- sc->vif, pktlen, info));
+ info->control.vif, pktlen, info));
}
if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
flags |= AR5K_TXDESC_CTSENA;
cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
- sc->vif, pktlen, info));
+ info->control.vif, pktlen, info));
}
ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
ieee80211_get_hdrlen_from_skb(skb), padsize,
@@ -1391,6 +826,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
spin_lock_bh(&txq->lock);
list_add_tail(&bf->list, &txq->q);
+ txq->txq_len++;
if (txq->link == NULL) /* is this first packet? */
ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
else /* no, so only link it */
@@ -1459,10 +895,13 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
list_add_tail(&bf->list, &sc->txbuf);
}
- /* beacon buffer */
- bf->desc = ds;
- bf->daddr = da;
- sc->bbuf = bf;
+ /* beacon buffers */
+ INIT_LIST_HEAD(&sc->bcbuf);
+ for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) {
+ bf->desc = ds;
+ bf->daddr = da;
+ list_add_tail(&bf->list, &sc->bcbuf);
+ }
return 0;
err_free:
@@ -1477,11 +916,12 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
{
struct ath5k_buf *bf;
- ath5k_txbuf_free_skb(sc, sc->bbuf);
list_for_each_entry(bf, &sc->txbuf, list)
ath5k_txbuf_free_skb(sc, bf);
list_for_each_entry(bf, &sc->rxbuf, list)
ath5k_rxbuf_free_skb(sc, bf);
+ list_for_each_entry(bf, &sc->bcbuf, list)
+ ath5k_txbuf_free_skb(sc, bf);
/* Free memory associated with all descriptors */
pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
@@ -1490,13 +930,9 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
kfree(sc->bufptr);
sc->bufptr = NULL;
- sc->bbuf = NULL;
}
-
-
-
/**************\
* Queues setup *
\**************/
@@ -1509,16 +945,18 @@ ath5k_txq_setup(struct ath5k_softc *sc,
struct ath5k_txq *txq;
struct ath5k_txq_info qi = {
.tqi_subtype = subtype,
- .tqi_aifs = AR5K_TXQ_USEDEFAULT,
- .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
- .tqi_cw_max = AR5K_TXQ_USEDEFAULT
+ /* XXX: default values not correct for B and XR channels,
+ * but who cares? */
+ .tqi_aifs = AR5K_TUNE_AIFS,
+ .tqi_cw_min = AR5K_TUNE_CWMIN,
+ .tqi_cw_max = AR5K_TUNE_CWMAX
};
int qnum;
/*
* Enable interrupts only for EOL and DESC conditions.
* We mark tx descriptors to receive a DESC interrupt
- * when a tx queue gets deep; otherwise waiting for the
+ * when a tx queue gets deep; otherwise we wait for the
* EOL to reap descriptors. Note that this is done to
* reduce interrupt load and this only defers reaping
* descriptors, never transmitting frames. Aside from
@@ -1550,6 +988,9 @@ ath5k_txq_setup(struct ath5k_softc *sc,
INIT_LIST_HEAD(&txq->q);
spin_lock_init(&txq->lock);
txq->setup = true;
+ txq->txq_len = 0;
+ txq->txq_poll_mark = false;
+ txq->txq_stuck = 0;
}
return &sc->txqs[qnum];
}
@@ -1558,9 +999,11 @@ static int
ath5k_beaconq_setup(struct ath5k_hw *ah)
{
struct ath5k_txq_info qi = {
- .tqi_aifs = AR5K_TXQ_USEDEFAULT,
- .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
- .tqi_cw_max = AR5K_TXQ_USEDEFAULT,
+ /* XXX: default values not correct for B and XR channels,
+ * but who cares? */
+ .tqi_aifs = AR5K_TUNE_AIFS,
+ .tqi_cw_min = AR5K_TUNE_CWMIN,
+ .tqi_cw_max = AR5K_TUNE_CWMAX,
/* NB: for dynamic turbo, don't enable any other interrupts */
.tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE
};
@@ -1594,7 +1037,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
*/
qi.tqi_aifs = 0;
qi.tqi_cw_min = 0;
- qi.tqi_cw_max = 2 * ah->ah_cw_min;
+ qi.tqi_cw_max = 2 * AR5K_TUNE_CWMIN;
}
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
@@ -1644,9 +1087,11 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
spin_lock_bh(&sc->txbuflock);
list_move_tail(&bf->list, &sc->txbuf);
sc->txbuf_len++;
+ txq->txq_len--;
spin_unlock_bh(&sc->txbuflock);
}
txq->link = NULL;
+ txq->txq_poll_mark = false;
spin_unlock_bh(&txq->lock);
}
@@ -1696,8 +1141,6 @@ ath5k_txq_release(struct ath5k_softc *sc)
}
-
-
/*************\
* RX Handling *
\*************/
@@ -1713,7 +1156,7 @@ ath5k_rx_start(struct ath5k_softc *sc)
struct ath5k_buf *bf;
int ret;
- common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz);
+ common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz);
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n",
common->cachelsz, common->rx_bufsize);
@@ -1732,7 +1175,7 @@ ath5k_rx_start(struct ath5k_softc *sc)
spin_unlock_bh(&sc->rxbuflock);
ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */
- ath5k_mode_setup(sc); /* set filters, etc. */
+ ath5k_mode_setup(sc, NULL); /* set filters, etc. */
ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
return 0;
@@ -1840,6 +1283,15 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
*/
if (hw_tu >= sc->nexttbtt)
ath5k_beacon_update_timers(sc, bc_tstamp);
+
+ /* Check if the beacon timers are still correct, because a TSF
+ * update might have created a window between them - for a
+ * longer description see the comment of this function: */
+ if (!ath5k_hw_check_beacon_timers(sc->ah, sc->bintval)) {
+ ath5k_beacon_update_timers(sc, bc_tstamp);
+ ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+ "fixed beacon timers after beacon receive\n");
+ }
}
}
@@ -1863,7 +1315,7 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
}
/*
- * Compute padding position. skb must contains an IEEE 802.11 frame
+ * Compute padding position. skb must contain an IEEE 802.11 frame
*/
static int ath5k_common_padpos(struct sk_buff *skb)
{
@@ -1882,10 +1334,9 @@ static int ath5k_common_padpos(struct sk_buff *skb)
}
/*
- * This function expects a 802.11 frame and returns the number of
- * bytes added, or -1 if we don't have enought header room.
+ * This function expects an 802.11 frame and returns the number of
+ * bytes added, or -1 if we don't have enough header room.
*/
-
static int ath5k_add_padding(struct sk_buff *skb)
{
int padpos = ath5k_common_padpos(skb);
@@ -1905,10 +1356,18 @@ static int ath5k_add_padding(struct sk_buff *skb)
}
/*
- * This function expects a 802.11 frame and returns the number of
- * bytes removed
+ * The MAC header is padded to have 32-bit boundary if the
+ * packet payload is non-zero. The general calculation for
+ * padsize would take into account odd header lengths:
+ * padsize = 4 - (hdrlen & 3); however, since only
+ * even-length headers are used, padding can only be 0 or 2
+ * bytes and we can optimize this a bit. We must not try to
+ * remove padding from short control frames that do not have a
+ * payload.
+ *
+ * This function expects an 802.11 frame and returns the number of
+ * bytes removed.
*/
-
static int ath5k_remove_padding(struct sk_buff *skb)
{
int padpos = ath5k_common_padpos(skb);
@@ -1929,14 +1388,6 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
{
struct ieee80211_rx_status *rxs;
- /* The MAC header is padded to have 32-bit boundary if the
- * packet payload is non-zero. The general calculation for
- * padsize would take into account odd header lengths:
- * padsize = (4 - hdrlen % 4) % 4; However, since only
- * even-length headers are used, padding can only be 0 or 2
- * bytes and we can optimize this a bit. In addition, we must
- * not try to remove padding from short control frames that do
- * not have payload. */
ath5k_remove_padding(skb);
rxs = IEEE80211_SKB_RXCB(skb);
@@ -2007,6 +1458,7 @@ static bool
ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
{
sc->stats.rx_all_count++;
+ sc->stats.rx_bytes_count += rs->rs_datalen;
if (unlikely(rs->rs_status)) {
if (rs->rs_status & AR5K_RXERR_CRC)
@@ -2040,9 +1492,8 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
return true;
}
- /* let crypto-error packets fall through in MNTR */
- if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
- sc->opmode != NL80211_IFTYPE_MONITOR)
+ /* reject any frames with non-crypto errors */
+ if (rs->rs_status & ~(AR5K_RXERR_DECRYPT))
return false;
}
@@ -2123,6 +1574,118 @@ unlock:
* TX Handling *
\*************/
+static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct ath5k_txq *txq)
+{
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_buf *bf;
+ unsigned long flags;
+ int padsize;
+
+ ath5k_debug_dump_skb(sc, skb, "TX ", 1);
+
+ /*
+ * The hardware expects the header padded to 4 byte boundaries.
+ * If this is not the case, we add the padding after the header.
+ */
+ padsize = ath5k_add_padding(skb);
+ if (padsize < 0) {
+ ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
+ " headroom to pad");
+ goto drop_packet;
+ }
+
+ if (txq->txq_len >= ATH5K_TXQ_LEN_MAX)
+ ieee80211_stop_queue(hw, txq->qnum);
+
+ spin_lock_irqsave(&sc->txbuflock, flags);
+ if (list_empty(&sc->txbuf)) {
+ ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
+ spin_unlock_irqrestore(&sc->txbuflock, flags);
+ ieee80211_stop_queues(hw);
+ goto drop_packet;
+ }
+ bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
+ list_del(&bf->list);
+ sc->txbuf_len--;
+ if (list_empty(&sc->txbuf))
+ ieee80211_stop_queues(hw);
+ spin_unlock_irqrestore(&sc->txbuflock, flags);
+
+ bf->skb = skb;
+
+ if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
+ bf->skb = NULL;
+ spin_lock_irqsave(&sc->txbuflock, flags);
+ list_add_tail(&bf->list, &sc->txbuf);
+ sc->txbuf_len++;
+ spin_unlock_irqrestore(&sc->txbuflock, flags);
+ goto drop_packet;
+ }
+ return NETDEV_TX_OK;
+
+drop_packet:
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+static void
+ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
+ struct ath5k_tx_status *ts)
+{
+ struct ieee80211_tx_info *info;
+ int i;
+
+ sc->stats.tx_all_count++;
+ sc->stats.tx_bytes_count += skb->len;
+ info = IEEE80211_SKB_CB(skb);
+
+ ieee80211_tx_info_clear_status(info);
+ for (i = 0; i < 4; i++) {
+ struct ieee80211_tx_rate *r =
+ &info->status.rates[i];
+
+ if (ts->ts_rate[i]) {
+ r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]);
+ r->count = ts->ts_retry[i];
+ } else {
+ r->idx = -1;
+ r->count = 0;
+ }
+ }
+
+ /* count the successful attempt as well */
+ info->status.rates[ts->ts_final_idx].count++;
+
+ if (unlikely(ts->ts_status)) {
+ sc->stats.ack_fail++;
+ if (ts->ts_status & AR5K_TXERR_FILT) {
+ info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+ sc->stats.txerr_filt++;
+ }
+ if (ts->ts_status & AR5K_TXERR_XRETRY)
+ sc->stats.txerr_retry++;
+ if (ts->ts_status & AR5K_TXERR_FIFO)
+ sc->stats.txerr_fifo++;
+ } else {
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ info->status.ack_signal = ts->ts_rssi;
+ }
+
+ /*
+ * Remove MAC header padding before giving the frame
+ * back to mac80211.
+ */
+ ath5k_remove_padding(skb);
+
+ if (ts->ts_antenna > 0 && ts->ts_antenna < 5)
+ sc->stats.antenna_tx[ts->ts_antenna]++;
+ else
+ sc->stats.antenna_tx[0]++; /* invalid */
+
+ ieee80211_tx_status(sc->hw, skb);
+}
+
static void
ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
{
@@ -2130,96 +1693,51 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
struct ath5k_buf *bf, *bf0;
struct ath5k_desc *ds;
struct sk_buff *skb;
- struct ieee80211_tx_info *info;
- int i, ret;
+ int ret;
spin_lock(&txq->lock);
list_for_each_entry_safe(bf, bf0, &txq->q, list) {
- ds = bf->desc;
- /*
- * It's possible that the hardware can say the buffer is
- * completed when it hasn't yet loaded the ds_link from
- * host memory and moved on. If there are more TX
- * descriptors in the queue, wait for TXDP to change
- * before processing this one.
- */
- if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr &&
- !list_is_last(&bf->list, &txq->q))
- break;
+ txq->txq_poll_mark = false;
- ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
- if (unlikely(ret == -EINPROGRESS))
- break;
- else if (unlikely(ret)) {
- ATH5K_ERR(sc, "error %d while processing queue %u\n",
- ret, txq->qnum);
- break;
- }
-
- sc->stats.tx_all_count++;
- skb = bf->skb;
- info = IEEE80211_SKB_CB(skb);
- bf->skb = NULL;
-
- pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
- PCI_DMA_TODEVICE);
+ /* skb might already have been processed last time. */
+ if (bf->skb != NULL) {
+ ds = bf->desc;
- ieee80211_tx_info_clear_status(info);
- for (i = 0; i < 4; i++) {
- struct ieee80211_tx_rate *r =
- &info->status.rates[i];
-
- if (ts.ts_rate[i]) {
- r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
- r->count = ts.ts_retry[i];
- } else {
- r->idx = -1;
- r->count = 0;
+ ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
+ if (unlikely(ret == -EINPROGRESS))
+ break;
+ else if (unlikely(ret)) {
+ ATH5K_ERR(sc,
+ "error %d while processing "
+ "queue %u\n", ret, txq->qnum);
+ break;
}
- }
- /* count the successful attempt as well */
- info->status.rates[ts.ts_final_idx].count++;
-
- if (unlikely(ts.ts_status)) {
- sc->stats.ack_fail++;
- if (ts.ts_status & AR5K_TXERR_FILT) {
- info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
- sc->stats.txerr_filt++;
- }
- if (ts.ts_status & AR5K_TXERR_XRETRY)
- sc->stats.txerr_retry++;
- if (ts.ts_status & AR5K_TXERR_FIFO)
- sc->stats.txerr_fifo++;
- } else {
- info->flags |= IEEE80211_TX_STAT_ACK;
- info->status.ack_signal = ts.ts_rssi;
+ skb = bf->skb;
+ bf->skb = NULL;
+ pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
+ PCI_DMA_TODEVICE);
+ ath5k_tx_frame_completed(sc, skb, &ts);
}
/*
- * Remove MAC header padding before giving the frame
- * back to mac80211.
+ * It's possible that the hardware can say the buffer is
+ * completed when it hasn't yet loaded the ds_link from
+ * host memory and moved on.
+ * Always keep the last descriptor to avoid HW races...
*/
- ath5k_remove_padding(skb);
-
- if (ts.ts_antenna > 0 && ts.ts_antenna < 5)
- sc->stats.antenna_tx[ts.ts_antenna]++;
- else
- sc->stats.antenna_tx[0]++; /* invalid */
-
- ieee80211_tx_status(sc->hw, skb);
-
- spin_lock(&sc->txbuflock);
- list_move_tail(&bf->list, &sc->txbuf);
- sc->txbuf_len++;
- spin_unlock(&sc->txbuflock);
+ if (ath5k_hw_get_txdp(sc->ah, txq->qnum) != bf->daddr) {
+ spin_lock(&sc->txbuflock);
+ list_move_tail(&bf->list, &sc->txbuf);
+ sc->txbuf_len++;
+ txq->txq_len--;
+ spin_unlock(&sc->txbuflock);
+ }
}
- if (likely(list_empty(&txq->q)))
- txq->link = NULL;
spin_unlock(&txq->lock);
- if (sc->txbuf_len > ATH_TXBUF / 5)
- ieee80211_wake_queues(sc->hw);
+ if (txq->txq_len < ATH5K_TXQ_LEN_LOW && txq->qnum < 4)
+ ieee80211_wake_queue(sc->hw, txq->qnum);
}
static void
@@ -2285,10 +1803,11 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
* default antenna which is supposed to be an omni.
*
* Note2: On sectored scenarios it's possible to have
- * multiple antennas (1omni -the default- and 14 sectors)
- * so if we choose to actually support this mode we need
- * to allow user to set how many antennas we have and tweak
- * the code below to send beacons on all of them.
+ * multiple antennas (1 omni -- the default -- and 14
+ * sectors), so if we choose to actually support this
+ * mode, we need to allow the user to set how many antennas
+ * we have and tweak the code below to send beacons
+ * on all of them.
*/
if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
antenna = sc->bsent & 4 ? 2 : 1;
@@ -2314,6 +1833,44 @@ err_unmap:
}
/*
+ * Updates the beacon that is sent by ath5k_beacon_send. For adhoc,
+ * this is called only once at config_bss time, for AP we do it every
+ * SWBA interrupt so that the TIM will reflect buffered frames.
+ *
+ * Called with the beacon lock.
+ */
+static int
+ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ int ret;
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_vif *avf = (void *)vif->drv_priv;
+ struct sk_buff *skb;
+
+ if (WARN_ON(!vif)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ skb = ieee80211_beacon_get(hw, vif);
+
+ if (!skb) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ath5k_debug_dump_skb(sc, skb, "BC ", 1);
+
+ ath5k_txbuf_free_skb(sc, avf->bbuf);
+ avf->bbuf->skb = skb;
+ ret = ath5k_beacon_setup(sc, avf->bbuf);
+ if (ret)
+ avf->bbuf->skb = NULL;
+out:
+ return ret;
+}
+
+/*
* Transmit a beacon frame at SWBA. Dynamic updates to the
* frame contents are done as needed and the slot time is
* also adjusted based on current state.
@@ -2324,20 +1881,17 @@ err_unmap:
static void
ath5k_beacon_send(struct ath5k_softc *sc)
{
- struct ath5k_buf *bf = sc->bbuf;
struct ath5k_hw *ah = sc->ah;
+ struct ieee80211_vif *vif;
+ struct ath5k_vif *avf;
+ struct ath5k_buf *bf;
struct sk_buff *skb;
ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
- if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
- sc->opmode == NL80211_IFTYPE_MONITOR)) {
- ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
- return;
- }
/*
* Check if the previous beacon has gone out. If
- * not don't don't try to post another, skip this
+ * not, don't don't try to post another: skip this
* period and wait for the next. Missed beacons
* indicate a problem and should not occur. If we
* miss too many consecutive beacons reset the device.
@@ -2363,6 +1917,28 @@ ath5k_beacon_send(struct ath5k_softc *sc)
sc->bmisscount = 0;
}
+ if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
+ u64 tsf = ath5k_hw_get_tsf64(ah);
+ u32 tsftu = TSF_TO_TU(tsf);
+ int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
+ vif = sc->bslot[(slot + 1) % ATH_BCBUF];
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+ "tsf %llx tsftu %x intval %u slot %u vif %p\n",
+ (unsigned long long)tsf, tsftu, sc->bintval, slot, vif);
+ } else /* only one interface */
+ vif = sc->bslot[0];
+
+ if (!vif)
+ return;
+
+ avf = (void *)vif->drv_priv;
+ bf = avf->bbuf;
+ if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
+ sc->opmode == NL80211_IFTYPE_MONITOR)) {
+ ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
+ return;
+ }
+
/*
* Stop any current dma and put the new frame on the queue.
* This should never fail since we check above that no frames
@@ -2375,23 +1951,22 @@ ath5k_beacon_send(struct ath5k_softc *sc)
/* refresh the beacon for AP mode */
if (sc->opmode == NL80211_IFTYPE_AP)
- ath5k_beacon_update(sc->hw, sc->vif);
+ ath5k_beacon_update(sc->hw, vif);
ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
ath5k_hw_start_tx_dma(ah, sc->bhalq);
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
- skb = ieee80211_get_buffered_bc(sc->hw, sc->vif);
+ skb = ieee80211_get_buffered_bc(sc->hw, vif);
while (skb) {
ath5k_tx_queue(sc->hw, skb, sc->cabq);
- skb = ieee80211_get_buffered_bc(sc->hw, sc->vif);
+ skb = ieee80211_get_buffered_bc(sc->hw, vif);
}
sc->bsent++;
}
-
/**
* ath5k_beacon_update_timers - update beacon timers
*
@@ -2416,6 +1991,12 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
u64 hw_tsf;
intval = sc->bintval & AR5K_BEACON_PERIOD;
+ if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
+ intval /= ATH_BCBUF; /* staggered multi-bss beacons */
+ if (intval < 15)
+ ATH5K_WARN(sc, "intval %u is too low, min 15\n",
+ intval);
+ }
if (WARN_ON(!intval))
return;
@@ -2426,8 +2007,11 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
hw_tsf = ath5k_hw_get_tsf64(ah);
hw_tu = TSF_TO_TU(hw_tsf);
-#define FUDGE 3
- /* we use FUDGE to make sure the next TBTT is ahead of the current TU */
+#define FUDGE AR5K_TUNE_SW_BEACON_RESP + 3
+ /* We use FUDGE to make sure the next TBTT is ahead of the current TU.
+ * Since we later substract AR5K_TUNE_SW_BEACON_RESP (10) in the timer
+ * configuration we need to make sure it is bigger than that. */
+
if (bc_tsf == -1) {
/*
* no beacons received, called internally.
@@ -2493,7 +2077,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : "");
}
-
/**
* ath5k_beacon_config - Configure the beacon queues and interrupts
*
@@ -2572,155 +2155,6 @@ static void ath5k_tasklet_beacon(unsigned long data)
* Interrupt handling *
\********************/
-static int
-ath5k_init(struct ath5k_softc *sc)
-{
- struct ath5k_hw *ah = sc->ah;
- int ret, i;
-
- mutex_lock(&sc->lock);
-
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
-
- /*
- * Stop anything previously setup. This is safe
- * no matter this is the first time through or not.
- */
- ath5k_stop_locked(sc);
-
- /*
- * The basic interface to setting the hardware in a good
- * state is ``reset''. On return the hardware is known to
- * be powered up and with interrupts disabled. This must
- * be followed by initialization of the appropriate bits
- * and then setup of the interrupt mask.
- */
- sc->curchan = sc->hw->conf.channel;
- sc->curband = &sc->sbands[sc->curchan->band];
- sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
- AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
- AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
-
- ret = ath5k_reset(sc, NULL);
- if (ret)
- goto done;
-
- ath5k_rfkill_hw_start(ah);
-
- /*
- * Reset the key cache since some parts do not reset the
- * contents on initial power up or resume from suspend.
- */
- for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
- ath5k_hw_reset_key(ah, i);
-
- ath5k_hw_set_ack_bitrate_high(ah, true);
- ret = 0;
-done:
- mmiowb();
- mutex_unlock(&sc->lock);
- return ret;
-}
-
-static int
-ath5k_stop_locked(struct ath5k_softc *sc)
-{
- struct ath5k_hw *ah = sc->ah;
-
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
- test_bit(ATH_STAT_INVALID, sc->status));
-
- /*
- * Shutdown the hardware and driver:
- * stop output from above
- * disable interrupts
- * turn off timers
- * turn off the radio
- * clear transmit machinery
- * clear receive machinery
- * drain and release tx queues
- * reclaim beacon resources
- * power down hardware
- *
- * Note that some of this work is not possible if the
- * hardware is gone (invalid).
- */
- ieee80211_stop_queues(sc->hw);
-
- if (!test_bit(ATH_STAT_INVALID, sc->status)) {
- ath5k_led_off(sc);
- ath5k_hw_set_imr(ah, 0);
- synchronize_irq(sc->pdev->irq);
- }
- ath5k_txq_cleanup(sc);
- if (!test_bit(ATH_STAT_INVALID, sc->status)) {
- ath5k_rx_stop(sc);
- ath5k_hw_phy_disable(ah);
- }
-
- return 0;
-}
-
-static void stop_tasklets(struct ath5k_softc *sc)
-{
- tasklet_kill(&sc->rxtq);
- tasklet_kill(&sc->txtq);
- tasklet_kill(&sc->calib);
- tasklet_kill(&sc->beacontq);
- tasklet_kill(&sc->ani_tasklet);
-}
-
-/*
- * Stop the device, grabbing the top-level lock to protect
- * against concurrent entry through ath5k_init (which can happen
- * if another thread does a system call and the thread doing the
- * stop is preempted).
- */
-static int
-ath5k_stop_hw(struct ath5k_softc *sc)
-{
- int ret;
-
- mutex_lock(&sc->lock);
- ret = ath5k_stop_locked(sc);
- if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
- /*
- * Don't set the card in full sleep mode!
- *
- * a) When the device is in this state it must be carefully
- * woken up or references to registers in the PCI clock
- * domain may freeze the bus (and system). This varies
- * by chip and is mostly an issue with newer parts
- * (madwifi sources mentioned srev >= 0x78) that go to
- * sleep more quickly.
- *
- * b) On older chips full sleep results a weird behaviour
- * during wakeup. I tested various cards with srev < 0x78
- * and they don't wake up after module reload, a second
- * module reload is needed to bring the card up again.
- *
- * Until we figure out what's going on don't enable
- * full chip reset on any chip (this is what Legacy HAL
- * and Sam's HAL do anyway). Instead Perform a full reset
- * on the device (same as initial state after attach) and
- * leave it idle (keep MAC/BB on warm reset) */
- ret = ath5k_hw_on_hold(sc->ah);
-
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
- "putting device to sleep\n");
- }
- ath5k_txbuf_free_skb(sc, sc->bbuf);
-
- mmiowb();
- mutex_unlock(&sc->lock);
-
- stop_tasklets(sc);
-
- ath5k_rfkill_hw_stop(sc->ah);
-
- return ret;
-}
-
static void
ath5k_intr_calibration_poll(struct ath5k_hw *ah)
{
@@ -2857,14 +2291,13 @@ ath5k_tasklet_calibrate(unsigned long data)
sc->curchan->center_freq));
/* Noise floor calibration interrupts rx/tx path while I/Q calibration
- * doesn't. We stop the queues so that calibration doesn't interfere
- * with TX and don't run it as often */
+ * doesn't.
+ * TODO: We should stop TX here, so that it doesn't interfere.
+ * Note that stopping the queues is not enough to stop TX! */
if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) {
ah->ah_cal_next_nf = jiffies +
msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF);
- ieee80211_stop_queues(sc->hw);
ath5k_hw_update_noise_floor(ah);
- ieee80211_wake_queues(sc->hw);
}
ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
@@ -2883,71 +2316,208 @@ ath5k_tasklet_ani(unsigned long data)
}
-/********************\
-* Mac80211 functions *
-\********************/
+static void
+ath5k_tx_complete_poll_work(struct work_struct *work)
+{
+ struct ath5k_softc *sc = container_of(work, struct ath5k_softc,
+ tx_complete_work.work);
+ struct ath5k_txq *txq;
+ int i;
+ bool needreset = false;
+
+ for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
+ if (sc->txqs[i].setup) {
+ txq = &sc->txqs[i];
+ spin_lock_bh(&txq->lock);
+ if (txq->txq_len > 1) {
+ if (txq->txq_poll_mark) {
+ ATH5K_DBG(sc, ATH5K_DEBUG_XMIT,
+ "TX queue stuck %d\n",
+ txq->qnum);
+ needreset = true;
+ txq->txq_stuck++;
+ spin_unlock_bh(&txq->lock);
+ break;
+ } else {
+ txq->txq_poll_mark = true;
+ }
+ }
+ spin_unlock_bh(&txq->lock);
+ }
+ }
+
+ if (needreset) {
+ ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+ "TX queues stuck, resetting\n");
+ ath5k_reset(sc, sc->curchan);
+ }
+
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
+ msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
+}
+
+
+/*************************\
+* Initialization routines *
+\*************************/
static int
-ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+ath5k_stop_locked(struct ath5k_softc *sc)
{
- struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+
+ ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
+ test_bit(ATH_STAT_INVALID, sc->status));
+
+ /*
+ * Shutdown the hardware and driver:
+ * stop output from above
+ * disable interrupts
+ * turn off timers
+ * turn off the radio
+ * clear transmit machinery
+ * clear receive machinery
+ * drain and release tx queues
+ * reclaim beacon resources
+ * power down hardware
+ *
+ * Note that some of this work is not possible if the
+ * hardware is gone (invalid).
+ */
+ ieee80211_stop_queues(sc->hw);
- return ath5k_tx_queue(hw, skb, sc->txq);
+ if (!test_bit(ATH_STAT_INVALID, sc->status)) {
+ ath5k_led_off(sc);
+ ath5k_hw_set_imr(ah, 0);
+ synchronize_irq(sc->pdev->irq);
+ }
+ ath5k_txq_cleanup(sc);
+ if (!test_bit(ATH_STAT_INVALID, sc->status)) {
+ ath5k_rx_stop(sc);
+ ath5k_hw_phy_disable(ah);
+ }
+
+ return 0;
}
-static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ath5k_txq *txq)
+static int
+ath5k_init(struct ath5k_softc *sc)
{
- struct ath5k_softc *sc = hw->priv;
- struct ath5k_buf *bf;
- unsigned long flags;
- int padsize;
+ struct ath5k_hw *ah = sc->ah;
+ struct ath_common *common = ath5k_hw_common(ah);
+ int ret, i;
- ath5k_debug_dump_skb(sc, skb, "TX ", 1);
+ mutex_lock(&sc->lock);
- if (sc->opmode == NL80211_IFTYPE_MONITOR)
- ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n");
+ ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
/*
- * the hardware expects the header padded to 4 byte boundaries
- * if this is not the case we add the padding after the header
+ * Stop anything previously setup. This is safe
+ * no matter this is the first time through or not.
*/
- padsize = ath5k_add_padding(skb);
- if (padsize < 0) {
- ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
- " headroom to pad");
- goto drop_packet;
- }
+ ath5k_stop_locked(sc);
- spin_lock_irqsave(&sc->txbuflock, flags);
- if (list_empty(&sc->txbuf)) {
- ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
- spin_unlock_irqrestore(&sc->txbuflock, flags);
- ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
- goto drop_packet;
- }
- bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
- list_del(&bf->list);
- sc->txbuf_len--;
- if (list_empty(&sc->txbuf))
- ieee80211_stop_queues(hw);
- spin_unlock_irqrestore(&sc->txbuflock, flags);
+ /*
+ * The basic interface to setting the hardware in a good
+ * state is ``reset''. On return the hardware is known to
+ * be powered up and with interrupts disabled. This must
+ * be followed by initialization of the appropriate bits
+ * and then setup of the interrupt mask.
+ */
+ sc->curchan = sc->hw->conf.channel;
+ sc->curband = &sc->sbands[sc->curchan->band];
+ sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
+ AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
+ AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
- bf->skb = skb;
+ ret = ath5k_reset(sc, NULL);
+ if (ret)
+ goto done;
- if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
- bf->skb = NULL;
- spin_lock_irqsave(&sc->txbuflock, flags);
- list_add_tail(&bf->list, &sc->txbuf);
- sc->txbuf_len++;
- spin_unlock_irqrestore(&sc->txbuflock, flags);
- goto drop_packet;
+ ath5k_rfkill_hw_start(ah);
+
+ /*
+ * Reset the key cache since some parts do not reset the
+ * contents on initial power up or resume from suspend.
+ */
+ for (i = 0; i < common->keymax; i++)
+ ath_hw_keyreset(common, (u16) i);
+
+ ath5k_hw_set_ack_bitrate_high(ah, true);
+
+ for (i = 0; i < ARRAY_SIZE(sc->bslot); i++)
+ sc->bslot[i] = NULL;
+
+ ret = 0;
+done:
+ mmiowb();
+ mutex_unlock(&sc->lock);
+
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
+ msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
+
+ return ret;
+}
+
+static void stop_tasklets(struct ath5k_softc *sc)
+{
+ tasklet_kill(&sc->rxtq);
+ tasklet_kill(&sc->txtq);
+ tasklet_kill(&sc->calib);
+ tasklet_kill(&sc->beacontq);
+ tasklet_kill(&sc->ani_tasklet);
+}
+
+/*
+ * Stop the device, grabbing the top-level lock to protect
+ * against concurrent entry through ath5k_init (which can happen
+ * if another thread does a system call and the thread doing the
+ * stop is preempted).
+ */
+static int
+ath5k_stop_hw(struct ath5k_softc *sc)
+{
+ int ret;
+
+ mutex_lock(&sc->lock);
+ ret = ath5k_stop_locked(sc);
+ if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
+ /*
+ * Don't set the card in full sleep mode!
+ *
+ * a) When the device is in this state it must be carefully
+ * woken up or references to registers in the PCI clock
+ * domain may freeze the bus (and system). This varies
+ * by chip and is mostly an issue with newer parts
+ * (madwifi sources mentioned srev >= 0x78) that go to
+ * sleep more quickly.
+ *
+ * b) On older chips full sleep results a weird behaviour
+ * during wakeup. I tested various cards with srev < 0x78
+ * and they don't wake up after module reload, a second
+ * module reload is needed to bring the card up again.
+ *
+ * Until we figure out what's going on don't enable
+ * full chip reset on any chip (this is what Legacy HAL
+ * and Sam's HAL do anyway). Instead Perform a full reset
+ * on the device (same as initial state after attach) and
+ * leave it idle (keep MAC/BB on warm reset) */
+ ret = ath5k_hw_on_hold(sc->ah);
+
+ ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+ "putting device to sleep\n");
}
- return NETDEV_TX_OK;
-drop_packet:
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
+ mmiowb();
+ mutex_unlock(&sc->lock);
+
+ stop_tasklets(sc);
+
+ cancel_delayed_work_sync(&sc->tx_complete_work);
+
+ ath5k_rfkill_hw_stop(sc->ah);
+
+ return ret;
}
/*
@@ -3024,6 +2594,208 @@ static void ath5k_reset_work(struct work_struct *work)
mutex_unlock(&sc->lock);
}
+static int
+ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+{
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+ struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
+ struct ath5k_txq *txq;
+ u8 mac[ETH_ALEN] = {};
+ int ret;
+
+ ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
+
+ /*
+ * Check if the MAC has multi-rate retry support.
+ * We do this by trying to setup a fake extended
+ * descriptor. MACs that don't have support will
+ * return false w/o doing anything. MACs that do
+ * support it will return true w/o doing anything.
+ */
+ ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
+
+ if (ret < 0)
+ goto err;
+ if (ret > 0)
+ __set_bit(ATH_STAT_MRRETRY, sc->status);
+
+ /*
+ * Collect the channel list. The 802.11 layer
+ * is resposible for filtering this list based
+ * on settings like the phy mode and regulatory
+ * domain restrictions.
+ */
+ ret = ath5k_setup_bands(hw);
+ if (ret) {
+ ATH5K_ERR(sc, "can't get channels\n");
+ goto err;
+ }
+
+ /* NB: setup here so ath5k_rate_update is happy */
+ if (test_bit(AR5K_MODE_11A, ah->ah_modes))
+ ath5k_setcurmode(sc, AR5K_MODE_11A);
+ else
+ ath5k_setcurmode(sc, AR5K_MODE_11B);
+
+ /*
+ * Allocate tx+rx descriptors and populate the lists.
+ */
+ ret = ath5k_desc_alloc(sc, pdev);
+ if (ret) {
+ ATH5K_ERR(sc, "can't allocate descriptors\n");
+ goto err;
+ }
+
+ /*
+ * Allocate hardware transmit queues: one queue for
+ * beacon frames and one data queue for each QoS
+ * priority. Note that hw functions handle resetting
+ * these queues at the needed time.
+ */
+ ret = ath5k_beaconq_setup(ah);
+ if (ret < 0) {
+ ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
+ goto err_desc;
+ }
+ sc->bhalq = ret;
+ sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0);
+ if (IS_ERR(sc->cabq)) {
+ ATH5K_ERR(sc, "can't setup cab queue\n");
+ ret = PTR_ERR(sc->cabq);
+ goto err_bhal;
+ }
+
+ /* This order matches mac80211's queue priority, so we can
+ * directly use the mac80211 queue number without any mapping */
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ hw->queues = 4;
+
+ tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
+ tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
+ tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
+ tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
+ tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
+
+ 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);
+ if (ret) {
+ ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
+ sc->pdev->device);
+ goto err_queues;
+ }
+
+ SET_IEEE80211_PERM_ADDR(hw, mac);
+ memcpy(&sc->lladdr, mac, ETH_ALEN);
+ /* All MAC address bits matter for ACKs */
+ ath5k_update_bssid_mask_and_opmode(sc, NULL);
+
+ regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
+ ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
+ if (ret) {
+ ATH5K_ERR(sc, "can't initialize regulatory system\n");
+ goto err_queues;
+ }
+
+ ret = ieee80211_register_hw(hw);
+ if (ret) {
+ ATH5K_ERR(sc, "can't register ieee80211 hw\n");
+ goto err_queues;
+ }
+
+ if (!ath_is_world_regd(regulatory))
+ regulatory_hint(hw->wiphy, regulatory->alpha2);
+
+ ath5k_init_leds(sc);
+
+ ath5k_sysfs_register(sc);
+
+ return 0;
+err_queues:
+ ath5k_txq_release(sc);
+err_bhal:
+ ath5k_hw_release_tx_queue(ah, sc->bhalq);
+err_desc:
+ ath5k_desc_free(sc, pdev);
+err:
+ return ret;
+}
+
+static void
+ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ /*
+ * NB: the order of these is important:
+ * o call the 802.11 layer before detaching ath5k_hw to
+ * ensure callbacks into the driver to delete global
+ * key cache entries can be handled
+ * o reclaim the tx queue data structures after calling
+ * the 802.11 layer as we'll get called back to reclaim
+ * node state and potentially want to use them
+ * o to cleanup the tx queues the hal is called, so detach
+ * it last
+ * XXX: ??? detach ath5k_hw ???
+ * Other than that, it's straightforward...
+ */
+ ieee80211_unregister_hw(hw);
+ ath5k_desc_free(sc, pdev);
+ ath5k_txq_release(sc);
+ ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
+ ath5k_unregister_leds(sc);
+
+ ath5k_sysfs_unregister(sc);
+ /*
+ * NB: can't reclaim these until after ieee80211_ifdetach
+ * returns because we'll get called back to reclaim node
+ * state and potentially want to use them.
+ */
+}
+
+/********************\
+* Mac80211 functions *
+\********************/
+
+static int
+ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ath5k_softc *sc = hw->priv;
+ u16 qnum = skb_get_queue_mapping(skb);
+
+ if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) {
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
+
+ return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]);
+}
+
static int ath5k_start(struct ieee80211_hw *hw)
{
return ath5k_init(hw->priv);
@@ -3039,32 +2811,78 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
{
struct ath5k_softc *sc = hw->priv;
int ret;
+ struct ath5k_vif *avf = (void *)vif->drv_priv;
mutex_lock(&sc->lock);
- if (sc->vif) {
- ret = 0;
+
+ if ((vif->type == NL80211_IFTYPE_AP ||
+ vif->type == NL80211_IFTYPE_ADHOC)
+ && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) {
+ ret = -ELNRNG;
goto end;
}
- sc->vif = vif;
+ /* Don't allow other interfaces if one ad-hoc is configured.
+ * TODO: Fix the problems with ad-hoc and multiple other interfaces.
+ * We would need to operate the HW in ad-hoc mode to allow TSF updates
+ * for the IBSS, but this breaks with additional AP or STA interfaces
+ * at the moment. */
+ if (sc->num_adhoc_vifs ||
+ (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
+ ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n");
+ ret = -ELNRNG;
+ goto end;
+ }
switch (vif->type) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
- case NL80211_IFTYPE_MONITOR:
- sc->opmode = vif->type;
+ avf->opmode = vif->type;
break;
default:
ret = -EOPNOTSUPP;
goto end;
}
- ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode);
+ sc->nvifs++;
+ ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode);
+
+ /* Assign the vap/adhoc to a beacon xmit slot. */
+ if ((avf->opmode == NL80211_IFTYPE_AP) ||
+ (avf->opmode == NL80211_IFTYPE_ADHOC)) {
+ int slot;
+ WARN_ON(list_empty(&sc->bcbuf));
+ avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf,
+ list);
+ list_del(&avf->bbuf->list);
+
+ avf->bslot = 0;
+ for (slot = 0; slot < ATH_BCBUF; slot++) {
+ if (!sc->bslot[slot]) {
+ avf->bslot = slot;
+ break;
+ }
+ }
+ BUG_ON(sc->bslot[avf->bslot] != NULL);
+ sc->bslot[avf->bslot] = vif;
+ if (avf->opmode == NL80211_IFTYPE_AP)
+ sc->num_ap_vifs++;
+ else
+ sc->num_adhoc_vifs++;
+ }
+
+ /* Any MAC address is fine, all others are included through the
+ * filter.
+ */
+ memcpy(&sc->lladdr, vif->addr, ETH_ALEN);
ath5k_hw_set_lladdr(sc->ah, vif->addr);
- ath5k_mode_setup(sc);
+
+ memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
+
+ ath5k_mode_setup(sc, vif);
ret = 0;
end:
@@ -3077,15 +2895,29 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct ath5k_softc *sc = hw->priv;
- u8 mac[ETH_ALEN] = {};
+ struct ath5k_vif *avf = (void *)vif->drv_priv;
+ unsigned int i;
mutex_lock(&sc->lock);
- if (sc->vif != vif)
- goto end;
+ sc->nvifs--;
+
+ if (avf->bbuf) {
+ ath5k_txbuf_free_skb(sc, avf->bbuf);
+ list_add_tail(&avf->bbuf->list, &sc->bcbuf);
+ for (i = 0; i < ATH_BCBUF; i++) {
+ if (sc->bslot[i] == vif) {
+ sc->bslot[i] = NULL;
+ break;
+ }
+ }
+ avf->bbuf = NULL;
+ }
+ if (avf->opmode == NL80211_IFTYPE_AP)
+ sc->num_ap_vifs--;
+ else if (avf->opmode == NL80211_IFTYPE_ADHOC)
+ sc->num_adhoc_vifs--;
- ath5k_hw_set_lladdr(sc->ah, mac);
- sc->vif = NULL;
-end:
+ ath5k_update_bssid_mask_and_opmode(sc, NULL);
mutex_unlock(&sc->lock);
}
@@ -3168,6 +3000,19 @@ static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
return ((u64)(mfilt[1]) << 32) | mfilt[0];
}
+static bool ath_any_vif_assoc(struct ath5k_softc *sc)
+{
+ struct ath_vif_iter_data iter_data;
+ iter_data.hw_macaddr = NULL;
+ iter_data.any_assoc = false;
+ iter_data.need_set_hw_addr = false;
+ iter_data.found_active = true;
+
+ ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter,
+ &iter_data);
+ return iter_data.any_assoc;
+}
+
#define SUPPORTED_FIF_FLAGS \
FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
@@ -3237,9 +3082,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
rfilt |= AR5K_RX_FILTER_PHYERR;
/* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
- * and probes for any BSSID, this needs testing */
- if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
- rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ;
+ * and probes for any BSSID */
+ if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1))
+ rfilt |= AR5K_RX_FILTER_BEACON;
/* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
* set we should only pass on control frames for this
@@ -3255,7 +3100,6 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
switch (sc->opmode) {
case NL80211_IFTYPE_MESH_POINT:
- case NL80211_IFTYPE_MONITOR:
rfilt |= AR5K_RX_FILTER_CONTROL |
AR5K_RX_FILTER_BEACON |
AR5K_RX_FILTER_PROBEREQ |
@@ -3278,7 +3122,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
/* Set multicast bits */
ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
- /* Set the cached hw filter flags, this will alter actually
+ /* Set the cached hw filter flags, this will later actually
* be set in HW */
sc->filter_flags = rfilt;
@@ -3298,17 +3142,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (modparam_nohwcrypt)
return -EOPNOTSUPP;
- if (sc->opmode == NL80211_IFTYPE_AP)
- return -EOPNOTSUPP;
-
- switch (key->alg) {
- case ALG_WEP:
- case ALG_TKIP:
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
break;
- case ALG_CCMP:
- if (sc->ah->ah_aes_support)
+ case WLAN_CIPHER_SUITE_CCMP:
+ if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)
break;
-
return -EOPNOTSUPP;
default:
WARN_ON(1);
@@ -3319,27 +3160,25 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
switch (cmd) {
case SET_KEY:
- ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
- sta ? sta->addr : NULL);
- if (ret) {
- ATH5K_ERR(sc, "can't set the key\n");
- goto unlock;
+ ret = ath_key_config(common, vif, sta, key);
+ if (ret >= 0) {
+ key->hw_key_idx = ret;
+ /* push IV and Michael MIC generation to stack */
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
+ ret = 0;
}
- __set_bit(key->keyidx, common->keymap);
- key->hw_key_idx = key->keyidx;
- key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV |
- IEEE80211_KEY_FLAG_GENERATE_MMIC);
break;
case DISABLE_KEY:
- ath5k_hw_reset_key(sc->ah, key->keyidx);
- __clear_bit(key->keyidx, common->keymap);
+ ath_key_delete(common, key);
break;
default:
ret = -EINVAL;
- goto unlock;
}
-unlock:
mmiowb();
mutex_unlock(&sc->lock);
return ret;
@@ -3409,43 +3248,6 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
ath5k_hw_reset_tsf(sc->ah);
}
-/*
- * Updates the beacon that is sent by ath5k_beacon_send. For adhoc,
- * this is called only once at config_bss time, for AP we do it every
- * SWBA interrupt so that the TIM will reflect buffered frames.
- *
- * Called with the beacon lock.
- */
-static int
-ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
-{
- int ret;
- struct ath5k_softc *sc = hw->priv;
- struct sk_buff *skb;
-
- if (WARN_ON(!vif)) {
- ret = -EINVAL;
- goto out;
- }
-
- skb = ieee80211_beacon_get(hw, vif);
-
- if (!skb) {
- ret = -ENOMEM;
- goto out;
- }
-
- ath5k_debug_dump_skb(sc, skb, "BC ", 1);
-
- ath5k_txbuf_free_skb(sc, sc->bbuf);
- sc->bbuf->skb = skb;
- ret = ath5k_beacon_setup(sc, sc->bbuf);
- if (ret)
- sc->bbuf->skb = NULL;
-out:
- return ret;
-}
-
static void
set_beacon_filter(struct ieee80211_hw *hw, bool enable)
{
@@ -3466,20 +3268,19 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u32 changes)
{
+ struct ath5k_vif *avf = (void *)vif->drv_priv;
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
struct ath_common *common = ath5k_hw_common(ah);
unsigned long flags;
mutex_lock(&sc->lock);
- if (WARN_ON(sc->vif != vif))
- goto unlock;
if (changes & BSS_CHANGED_BSSID) {
/* Cache for later use during resets */
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
common->curaid = 0;
- ath5k_hw_set_associd(ah);
+ ath5k_hw_set_bssid(ah);
mmiowb();
}
@@ -3487,7 +3288,12 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
sc->bintval = bss_conf->beacon_int;
if (changes & BSS_CHANGED_ASSOC) {
- sc->assoc = bss_conf->assoc;
+ avf->assoc = bss_conf->assoc;
+ if (bss_conf->assoc)
+ sc->assoc = bss_conf->assoc;
+ else
+ sc->assoc = ath_any_vif_assoc(sc);
+
if (sc->opmode == NL80211_IFTYPE_STATION)
set_beacon_filter(hw, sc->assoc);
ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
@@ -3497,7 +3303,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
"Bss Info ASSOC %d, bssid: %pM\n",
bss_conf->aid, common->curbssid);
common->curaid = bss_conf->aid;
- ath5k_hw_set_associd(ah);
+ ath5k_hw_set_bssid(ah);
/* Once ANI is available you would start it here */
}
}
@@ -3515,7 +3321,6 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
BSS_CHANGED_BEACON_INT))
ath5k_beacon_config(sc);
- unlock:
mutex_unlock(&sc->lock);
}
@@ -3551,3 +3356,399 @@ static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
ath5k_hw_set_coverage_class(sc->ah, coverage_class);
mutex_unlock(&sc->lock);
}
+
+static int ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params)
+{
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+ struct ath5k_txq_info qi;
+ int ret = 0;
+
+ if (queue >= ah->ah_capabilities.cap_queues.q_tx_num)
+ return 0;
+
+ mutex_lock(&sc->lock);
+
+ ath5k_hw_get_tx_queueprops(ah, queue, &qi);
+
+ qi.tqi_aifs = params->aifs;
+ qi.tqi_cw_min = params->cw_min;
+ qi.tqi_cw_max = params->cw_max;
+ qi.tqi_burst_time = params->txop;
+
+ ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
+ "Configure tx [queue %d], "
+ "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
+ queue, params->aifs, params->cw_min,
+ params->cw_max, params->txop);
+
+ if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) {
+ ATH5K_ERR(sc,
+ "Unable to update hardware queue %u!\n", queue);
+ ret = -EIO;
+ } else
+ ath5k_hw_reset_tx_queue(ah, queue);
+
+ mutex_unlock(&sc->lock);
+
+ return ret;
+}
+
+static const struct ieee80211_ops ath5k_hw_ops = {
+ .tx = ath5k_tx,
+ .start = ath5k_start,
+ .stop = ath5k_stop,
+ .add_interface = ath5k_add_interface,
+ .remove_interface = ath5k_remove_interface,
+ .config = ath5k_config,
+ .prepare_multicast = ath5k_prepare_multicast,
+ .configure_filter = ath5k_configure_filter,
+ .set_key = ath5k_set_key,
+ .get_stats = ath5k_get_stats,
+ .get_survey = ath5k_get_survey,
+ .conf_tx = ath5k_conf_tx,
+ .get_tsf = ath5k_get_tsf,
+ .set_tsf = ath5k_set_tsf,
+ .reset_tsf = ath5k_reset_tsf,
+ .bss_info_changed = ath5k_bss_info_changed,
+ .sw_scan_start = ath5k_sw_scan_start,
+ .sw_scan_complete = ath5k_sw_scan_complete,
+ .set_coverage_class = ath5k_set_coverage_class,
+};
+
+/********************\
+* PCI Initialization *
+\********************/
+
+static int __devinit
+ath5k_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ void __iomem *mem;
+ struct ath5k_softc *sc;
+ struct ath_common *common;
+ struct ieee80211_hw *hw;
+ int ret;
+ u8 csz;
+
+ /*
+ * L0s needs to be disabled on all ath5k cards.
+ *
+ * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
+ * by default in the future in 2.6.36) this will also mean both L1 and
+ * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
+ * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
+ * though but cannot currently undue the effect of a blacklist, for
+ * details you can read pcie_aspm_sanity_check() and see how it adjusts
+ * the device link capability.
+ *
+ * It may be possible in the future to implement some PCI API to allow
+ * drivers to override blacklists for pre 1.1 PCIe but for now it is
+ * best to accept that both L0s and L1 will be disabled completely for
+ * distributions shipping with CONFIG_PCIEASPM rather than having this
+ * issue present. Motivation for adding this new API will be to help
+ * with power consumption for some of these devices.
+ */
+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "can't enable device\n");
+ goto err;
+ }
+
+ /* XXX 32-bit addressing only */
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(&pdev->dev, "32-bit DMA not available\n");
+ goto err_dis;
+ }
+
+ /*
+ * Cache line size is used to size and align various
+ * structures used to communicate with the hardware.
+ */
+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+ if (csz == 0) {
+ /*
+ * Linux 2.4.18 (at least) writes the cache line size
+ * register as a 16-bit wide register which is wrong.
+ * We must have this setup properly for rx buffer
+ * DMA to work so force a reasonable value here if it
+ * comes up zero.
+ */
+ csz = L1_CACHE_BYTES >> 2;
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+ }
+ /*
+ * The default setting of latency timer yields poor results,
+ * set it to the value used by other systems. It may be worth
+ * tweaking this setting more.
+ */
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+ /* Enable bus mastering */
+ pci_set_master(pdev);
+
+ /*
+ * Disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state.
+ */
+ pci_write_config_byte(pdev, 0x41, 0);
+
+ ret = pci_request_region(pdev, 0, "ath5k");
+ if (ret) {
+ dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
+ goto err_dis;
+ }
+
+ mem = pci_iomap(pdev, 0, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
+ ret = -EIO;
+ goto err_reg;
+ }
+
+ /*
+ * Allocate hw (mac80211 main struct)
+ * and hw->priv (driver private data)
+ */
+ hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
+ if (hw == NULL) {
+ dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
+ ret = -ENOMEM;
+ goto err_map;
+ }
+
+ dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
+
+ /* Initialize driver private data */
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM;
+
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_MESH_POINT);
+
+ hw->extra_tx_headroom = 2;
+ hw->channel_change_time = 5000;
+ sc = hw->priv;
+ sc->hw = hw;
+ sc->pdev = pdev;
+
+ /*
+ * Mark the device as detached to avoid processing
+ * interrupts until setup is complete.
+ */
+ __set_bit(ATH_STAT_INVALID, sc->status);
+
+ sc->iobase = mem; /* So we can unmap it on detach */
+ sc->opmode = NL80211_IFTYPE_STATION;
+ sc->bintval = 1000;
+ mutex_init(&sc->lock);
+ spin_lock_init(&sc->rxbuflock);
+ spin_lock_init(&sc->txbuflock);
+ spin_lock_init(&sc->block);
+
+ /* Set private data */
+ pci_set_drvdata(pdev, sc);
+
+ /* Setup interrupt handler */
+ ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
+ if (ret) {
+ ATH5K_ERR(sc, "request_irq failed\n");
+ goto err_free;
+ }
+
+ /* If we passed the test, malloc an ath5k_hw struct */
+ sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
+ if (!sc->ah) {
+ ret = -ENOMEM;
+ ATH5K_ERR(sc, "out of memory\n");
+ goto err_irq;
+ }
+
+ sc->ah->ah_sc = sc;
+ sc->ah->ah_iobase = sc->iobase;
+ common = ath5k_hw_common(sc->ah);
+ common->ops = &ath5k_common_ops;
+ common->ah = sc->ah;
+ common->hw = hw;
+ common->cachelsz = csz << 2; /* convert to bytes */
+
+ /* Initialize device */
+ ret = ath5k_hw_attach(sc);
+ if (ret) {
+ goto err_free_ah;
+ }
+
+ /* set up multi-rate retry capabilities */
+ if (sc->ah->ah_version == AR5K_AR5212) {
+ hw->max_rates = 4;
+ hw->max_rate_tries = 11;
+ }
+
+ hw->vif_data_size = sizeof(struct ath5k_vif);
+
+ /* Finish private driver data initialization */
+ ret = ath5k_attach(pdev, hw);
+ if (ret)
+ goto err_ah;
+
+ ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
+ sc->ah->ah_mac_srev,
+ sc->ah->ah_phy_revision);
+
+ if (!sc->ah->ah_single_chip) {
+ /* Single chip radio (!RF5111) */
+ if (sc->ah->ah_radio_5ghz_revision &&
+ !sc->ah->ah_radio_2ghz_revision) {
+ /* No 5GHz support -> report 2GHz radio */
+ if (!test_bit(AR5K_MODE_11A,
+ sc->ah->ah_capabilities.cap_mode)) {
+ ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ /* No 2GHz support (5110 and some
+ * 5Ghz only cards) -> report 5Ghz radio */
+ } else if (!test_bit(AR5K_MODE_11B,
+ sc->ah->ah_capabilities.cap_mode)) {
+ ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ /* Multiband radio */
+ } else {
+ ATH5K_INFO(sc, "RF%s multiband radio found"
+ " (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ }
+ }
+ /* Multi chip radio (RF5111 - RF2111) ->
+ * report both 2GHz/5GHz radios */
+ else if (sc->ah->ah_radio_5ghz_revision &&
+ sc->ah->ah_radio_2ghz_revision){
+ ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_2ghz_revision),
+ sc->ah->ah_radio_2ghz_revision);
+ }
+ }
+
+ ath5k_debug_init_device(sc);
+
+ /* ready to process interrupts */
+ __clear_bit(ATH_STAT_INVALID, sc->status);
+
+ return 0;
+err_ah:
+ ath5k_hw_detach(sc->ah);
+err_free_ah:
+ kfree(sc->ah);
+err_irq:
+ free_irq(pdev->irq, sc);
+err_free:
+ ieee80211_free_hw(hw);
+err_map:
+ pci_iounmap(pdev, mem);
+err_reg:
+ pci_release_region(pdev, 0);
+err_dis:
+ pci_disable_device(pdev);
+err:
+ return ret;
+}
+
+static void __devexit
+ath5k_pci_remove(struct pci_dev *pdev)
+{
+ struct ath5k_softc *sc = pci_get_drvdata(pdev);
+
+ ath5k_debug_finish_device(sc);
+ ath5k_detach(pdev, sc->hw);
+ ath5k_hw_detach(sc->ah);
+ kfree(sc->ah);
+ free_irq(pdev->irq, sc);
+ pci_iounmap(pdev, sc->iobase);
+ pci_release_region(pdev, 0);
+ pci_disable_device(pdev);
+ ieee80211_free_hw(sc->hw);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ath5k_pci_suspend(struct device *dev)
+{
+ struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
+
+ ath5k_led_off(sc);
+ return 0;
+}
+
+static int ath5k_pci_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct ath5k_softc *sc = pci_get_drvdata(pdev);
+
+ /*
+ * Suspend/Resume resets the PCI configuration space, so we have to
+ * re-disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state
+ */
+ pci_write_config_byte(pdev, 0x41, 0);
+
+ ath5k_led_enable(sc);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
+#define ATH5K_PM_OPS (&ath5k_pm_ops)
+#else
+#define ATH5K_PM_OPS NULL
+#endif /* CONFIG_PM_SLEEP */
+
+static struct pci_driver ath5k_pci_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = ath5k_pci_id_table,
+ .probe = ath5k_pci_probe,
+ .remove = __devexit_p(ath5k_pci_remove),
+ .driver.pm = ATH5K_PM_OPS,
+};
+
+/*
+ * Module init/exit functions
+ */
+static int __init
+init_ath5k_pci(void)
+{
+ int ret;
+
+ ret = pci_register_driver(&ath5k_pci_driver);
+ if (ret) {
+ printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit
+exit_ath5k_pci(void)
+{
+ pci_unregister_driver(&ath5k_pci_driver);
+}
+
+module_init(init_ath5k_pci);
+module_exit(exit_ath5k_pci);
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index dc1241f9c4e8..9a79773cdc2a 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -58,7 +58,9 @@
#define ATH_RXBUF 40 /* number of RX buffers */
#define ATH_TXBUF 200 /* number of TX buffers */
-#define ATH_BCBUF 1 /* number of beacon buffers */
+#define ATH_BCBUF 4 /* number of beacon buffers */
+#define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */
+#define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */
struct ath5k_buf {
struct list_head list;
@@ -83,6 +85,9 @@ struct ath5k_txq {
struct list_head q; /* transmit queue */
spinlock_t lock; /* lock on q and link */
bool setup;
+ int txq_len; /* number of queued buffers */
+ bool txq_poll_mark;
+ unsigned int txq_stuck; /* informational counter */
};
#define ATH5K_LED_MAX_NAME_LEN 31
@@ -116,6 +121,13 @@ struct ath5k_statistics {
/* frame errors */
unsigned int rx_all_count; /* all RX frames, including errors */
unsigned int tx_all_count; /* all TX frames, including errors */
+ unsigned int rx_bytes_count; /* all RX bytes, including errored pks
+ * and the MAC headers for each packet
+ */
+ unsigned int tx_bytes_count; /* all TX bytes, including errored pkts
+ * and the MAC headers and padding for
+ * each packet.
+ */
unsigned int rxerr_crc;
unsigned int rxerr_phy;
unsigned int rxerr_phy_code[32];
@@ -146,6 +158,14 @@ struct ath5k_statistics {
#define ATH_CHAN_MAX (14+14+14+252+20)
#endif
+struct ath5k_vif {
+ bool assoc; /* are we associated or not */
+ enum nl80211_iftype opmode;
+ int bslot;
+ struct ath5k_buf *bbuf; /* beacon buffer */
+ u8 lladdr[ETH_ALEN];
+};
+
/* Software Carrier, keeps track of the driver state
* associated with an instance of a device */
struct ath5k_softc {
@@ -182,10 +202,11 @@ struct ath5k_softc {
unsigned int curmode; /* current phy mode */
struct ieee80211_channel *curchan; /* current h/w channel */
- struct ieee80211_vif *vif;
+ u16 nvifs;
enum ath5k_int imask; /* interrupt mask copy */
+ u8 lladdr[ETH_ALEN];
u8 bssidmask[ETH_ALEN];
unsigned int led_pin, /* GPIO pin for driving LED */
@@ -204,7 +225,6 @@ struct ath5k_softc {
spinlock_t txbuflock;
unsigned int txbuf_len; /* buf count in txbuf list */
struct ath5k_txq txqs[AR5K_NUM_TX_QUEUES]; /* tx queues */
- struct ath5k_txq *txq; /* main tx queue */
struct tasklet_struct txtq; /* tx intr tasklet */
struct ath5k_led tx_led; /* tx led */
@@ -214,7 +234,10 @@ struct ath5k_softc {
spinlock_t block; /* protects beacon */
struct tasklet_struct beacontq; /* beacon intr tasklet */
- struct ath5k_buf *bbuf; /* beacon buffer */
+ struct list_head bcbuf; /* beacon buffer */
+ struct ieee80211_vif *bslot[ATH_BCBUF];
+ u16 num_ap_vifs;
+ u16 num_adhoc_vifs;
unsigned int bhalq, /* SW q for outgoing beacons */
bmisscount, /* missed beacon transmits */
bintval, /* beacon interval in TU */
@@ -230,6 +253,8 @@ struct ath5k_softc {
struct ath5k_ani_state ani_state;
struct tasklet_struct ani_tasklet; /* ANI calibration */
+
+ struct delayed_work tx_complete_work;
};
#define ath5k_hw_hasbssidmask(_ah) \
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index fb339c3852ee..acda56ee521b 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -60,6 +60,7 @@
#include "base.h"
#include "debug.h"
+#include "../debug.h"
static unsigned int ath5k_debug;
module_param_named(debug, ath5k_debug, uint, 0);
@@ -71,8 +72,6 @@ module_param_named(debug, ath5k_debug, uint, 0);
#include "reg.h"
#include "ani.h"
-static struct dentry *ath5k_global_debugfs;
-
static int ath5k_debugfs_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
@@ -314,6 +313,7 @@ static const struct {
{ ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
{ ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
{ ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
+ { ATH5K_DEBUG_DESC, "desc", "descriptor chains" },
{ ATH5K_DEBUG_ANY, "all", "show all debug levels" },
};
@@ -486,6 +486,60 @@ static const struct file_operations fops_antenna = {
.llseek = default_llseek,
};
+/* debugfs: misc */
+
+static ssize_t read_file_misc(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath5k_softc *sc = file->private_data;
+ char buf[700];
+ unsigned int len = 0;
+ u32 filt = ath5k_hw_get_rx_filter(sc->ah);
+
+ len += snprintf(buf+len, sizeof(buf)-len, "bssid-mask: %pM\n",
+ sc->bssidmask);
+ len += snprintf(buf+len, sizeof(buf)-len, "filter-flags: 0x%x ",
+ filt);
+ if (filt & AR5K_RX_FILTER_UCAST)
+ len += snprintf(buf+len, sizeof(buf)-len, " UCAST");
+ if (filt & AR5K_RX_FILTER_MCAST)
+ len += snprintf(buf+len, sizeof(buf)-len, " MCAST");
+ if (filt & AR5K_RX_FILTER_BCAST)
+ len += snprintf(buf+len, sizeof(buf)-len, " BCAST");
+ if (filt & AR5K_RX_FILTER_CONTROL)
+ len += snprintf(buf+len, sizeof(buf)-len, " CONTROL");
+ if (filt & AR5K_RX_FILTER_BEACON)
+ len += snprintf(buf+len, sizeof(buf)-len, " BEACON");
+ if (filt & AR5K_RX_FILTER_PROM)
+ len += snprintf(buf+len, sizeof(buf)-len, " PROM");
+ if (filt & AR5K_RX_FILTER_XRPOLL)
+ len += snprintf(buf+len, sizeof(buf)-len, " XRPOLL");
+ if (filt & AR5K_RX_FILTER_PROBEREQ)
+ len += snprintf(buf+len, sizeof(buf)-len, " PROBEREQ");
+ if (filt & AR5K_RX_FILTER_PHYERR_5212)
+ len += snprintf(buf+len, sizeof(buf)-len, " PHYERR-5212");
+ if (filt & AR5K_RX_FILTER_RADARERR_5212)
+ len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5212");
+ if (filt & AR5K_RX_FILTER_PHYERR_5211)
+ snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211");
+ if (filt & AR5K_RX_FILTER_RADARERR_5211)
+ len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211");
+
+ len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n",
+ ath_opmode_to_string(sc->opmode), sc->opmode);
+
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_misc = {
+ .read = read_file_misc,
+ .open = ath5k_debugfs_open,
+ .owner = THIS_MODULE,
+};
+
/* debugfs: frameerrors */
@@ -537,6 +591,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
st->rxerr_jumbo*100/st->rx_all_count : 0);
len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n",
st->rx_all_count);
+ len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%d\n",
+ st->rx_bytes_count);
len += snprintf(buf+len, sizeof(buf)-len,
"\nTX\n---------------------\n");
@@ -554,6 +610,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
st->txerr_filt*100/st->tx_all_count : 0);
len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
st->tx_all_count);
+ len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%d\n",
+ st->tx_bytes_count);
if (len > sizeof(buf))
len = sizeof(buf);
@@ -662,20 +720,21 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
len += snprintf(buf+len, sizeof(buf)-len,
"beacon RSSI average:\t%d\n",
sc->ah->ah_beacon_rssi_avg.avg);
+
+#define CC_PRINT(_struct, _field) \
+ _struct._field, \
+ _struct.cycles > 0 ? \
+ _struct._field*100/_struct.cycles : 0
+
len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n",
- as->pfc_tx,
- as->pfc_cycles > 0 ?
- as->pfc_tx*100/as->pfc_cycles : 0);
+ CC_PRINT(as->last_cc, tx_frame));
len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n",
- as->pfc_rx,
- as->pfc_cycles > 0 ?
- as->pfc_rx*100/as->pfc_cycles : 0);
+ CC_PRINT(as->last_cc, rx_frame));
len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n",
- as->pfc_busy,
- as->pfc_cycles > 0 ?
- as->pfc_busy*100/as->pfc_cycles : 0);
+ CC_PRINT(as->last_cc, rx_busy));
+#undef CC_PRINT
len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n",
- as->pfc_cycles);
+ as->last_cc.cycles);
len += snprintf(buf+len, sizeof(buf)-len,
"listen time\t\t%d\tlast: %d\n",
as->listen_time, as->last_listen);
@@ -768,7 +827,7 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf,
struct ath5k_txq *txq;
struct ath5k_buf *bf, *bf0;
- int i, n = 0;
+ int i, n;
len += snprintf(buf+len, sizeof(buf)-len,
"available txbuffers: %d\n", sc->txbuf_len);
@@ -782,9 +841,16 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf,
if (!txq->setup)
continue;
+ n = 0;
+ spin_lock_bh(&txq->lock);
list_for_each_entry_safe(bf, bf0, &txq->q, list)
n++;
- len += snprintf(buf+len, sizeof(buf)-len, " len: %d\n", n);
+ spin_unlock_bh(&txq->lock);
+
+ len += snprintf(buf+len, sizeof(buf)-len,
+ " len: %d bufs: %d\n", txq->txq_len, n);
+ len += snprintf(buf+len, sizeof(buf)-len,
+ " stuck: %d\n", txq->txq_stuck);
}
if (len > sizeof(buf))
@@ -821,21 +887,13 @@ static const struct file_operations fops_queue = {
};
-/* init */
-
-void
-ath5k_debug_init(void)
-{
- ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
-}
-
void
ath5k_debug_init_device(struct ath5k_softc *sc)
{
sc->debug.level = ath5k_debug;
- sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
- ath5k_global_debugfs);
+ sc->debug.debugfs_phydir = debugfs_create_dir("ath5k",
+ sc->hw->wiphy->debugfsdir);
sc->debug.debugfs_debug = debugfs_create_file("debug",
S_IWUSR | S_IRUSR,
@@ -855,6 +913,10 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
S_IWUSR | S_IRUSR,
sc->debug.debugfs_phydir, sc, &fops_antenna);
+ sc->debug.debugfs_misc = debugfs_create_file("misc",
+ S_IRUSR,
+ sc->debug.debugfs_phydir, sc, &fops_misc);
+
sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors",
S_IWUSR | S_IRUSR,
sc->debug.debugfs_phydir, sc,
@@ -872,12 +934,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
}
void
-ath5k_debug_finish(void)
-{
- debugfs_remove(ath5k_global_debugfs);
-}
-
-void
ath5k_debug_finish_device(struct ath5k_softc *sc)
{
debugfs_remove(sc->debug.debugfs_debug);
@@ -885,6 +941,7 @@ ath5k_debug_finish_device(struct ath5k_softc *sc)
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);
@@ -962,7 +1019,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
struct ath5k_rx_status rs = {};
int status;
- if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
+ if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC)))
return;
printk(KERN_DEBUG "rxdp %x, rxlink %p\n",
@@ -1004,7 +1061,7 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
struct ath5k_tx_status ts = {};
int done;
- if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
+ if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC)))
return;
done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts);
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 606ae94a9157..236edbd2507d 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -75,6 +75,7 @@ struct ath5k_dbg_info {
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;
@@ -95,6 +96,7 @@ struct ath5k_dbg_info {
* @ATH5K_DEBUG_DUMP_TX: print transmit skb content
* @ATH5K_DEBUG_DUMPBANDS: dump bands
* @ATH5K_DEBUG_TRACE: trace function calls
+ * @ATH5K_DEBUG_DESC: descriptor setup
* @ATH5K_DEBUG_ANY: show at any debug level
*
* The debug level is used to control the amount and type of debugging output
@@ -117,6 +119,7 @@ enum ath5k_debug_level {
ATH5K_DEBUG_DUMP_TX = 0x00000200,
ATH5K_DEBUG_DUMPBANDS = 0x00000400,
ATH5K_DEBUG_ANI = 0x00002000,
+ ATH5K_DEBUG_DESC = 0x00004000,
ATH5K_DEBUG_ANY = 0xffffffff
};
@@ -135,15 +138,9 @@ enum ath5k_debug_level {
} while (0)
void
-ath5k_debug_init(void);
-
-void
ath5k_debug_init_device(struct ath5k_softc *sc);
void
-ath5k_debug_finish(void);
-
-void
ath5k_debug_finish_device(struct ath5k_softc *sc);
void
@@ -171,15 +168,9 @@ ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
{}
static inline void
-ath5k_debug_init(void) {}
-
-static inline void
ath5k_debug_init_device(struct ath5k_softc *sc) {}
static inline void
-ath5k_debug_finish(void) {}
-
-static inline void
ath5k_debug_finish_device(struct ath5k_softc *sc) {}
static inline void
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index 484f31870ba8..923c9ca5c4f0 100644
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -244,7 +244,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
/* Force channel idle high */
AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
- AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
+ AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
/* Wait a while and disable mechanism */
udelay(200);
@@ -261,7 +261,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
} while (--i && pending);
AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
- AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
+ AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
}
/* Clear register */
@@ -377,11 +377,11 @@ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
*
* This function increases/decreases the tx trigger level for the tx fifo
* buffer (aka FIFO threshold) that is used to indicate when PCU flushes
- * the buffer and transmits it's data. Lowering this results sending small
+ * the buffer and transmits its data. Lowering this results sending small
* frames more quickly but can lead to tx underruns, raising it a lot can
* result other problems (i think bmiss is related). Right now we start with
* the lowest possible (64Bytes) and if we get tx underrun we increase it using
- * the increase flag. Returns -EIO if we have have reached maximum/minimum.
+ * the increase flag. Returns -EIO if we have reached maximum/minimum.
*
* XXX: Link this with tx DMA size ?
* XXX: Use it to save interrupts ?
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index ae316fec4a6a..39722dd73e43 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -661,7 +661,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
* (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
* steps that match with the power values we read from eeprom. On
* older eeprom versions (< 3.2) these steps are equaly spaced at
- * 10% of the pcdac curve -until the curve reaches it's maximum-
+ * 10% of the pcdac curve -until the curve reaches its maximum-
* (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
* these 11 steps are spaced in a different way. This function returns
* the pcdac steps based on eeprom version and curve min/max so that we
@@ -1113,7 +1113,7 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
*/
/* For RF2413 power calibration data doesn't start on a fixed location and
- * if a mode is not supported, it's section is missing -not zeroed-.
+ * if a mode is not supported, its section is missing -not zeroed-.
* So we need to calculate the starting offset for each section by using
* these two functions */
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 86fdb6ddfaaa..074b4c644399 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -137,11 +137,11 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
* ath5k_hw_set_ack_bitrate - set bitrate for ACKs
*
* @ah: The &struct ath5k_hw
- * @high: Flag to determine if we want to use high transmition rate
+ * @high: Flag to determine if we want to use high transmission rate
* for ACKs or not
*
* If high flag is set, we tell hw to use a set of control rates based on
- * the current transmition rate (check out control_rates array inside reset.c).
+ * the current transmission rate (check out control_rates array inside reset.c).
* If not hw just uses the lowest rate available for the current modulation
* scheme being used (1Mbit for CCK and 6Mbits for OFDM).
*/
@@ -207,7 +207,8 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
*/
unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
{
- return usec * ath5k_hw_get_clockrate(ah);
+ struct ath_common *common = ath5k_hw_common(ah);
+ return usec * common->clockrate;
}
/**
@@ -216,17 +217,19 @@ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
*/
unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
{
- return clock / ath5k_hw_get_clockrate(ah);
+ struct ath_common *common = ath5k_hw_common(ah);
+ return clock / common->clockrate;
}
/**
- * ath5k_hw_get_clockrate - Get the clock rate for current mode
+ * ath5k_hw_set_clockrate - Set common->clockrate for the current channel
*
* @ah: The &struct ath5k_hw
*/
-unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
+void ath5k_hw_set_clockrate(struct ath5k_hw *ah)
{
struct ieee80211_channel *channel = ah->ah_current_channel;
+ struct ath_common *common = ath5k_hw_common(ah);
int clock;
if (channel->hw_value & CHANNEL_5GHZ)
@@ -240,7 +243,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
if (channel->hw_value & CHANNEL_TURBO)
clock *= 2;
- return clock;
+ common->clockrate = clock;
}
/**
@@ -308,27 +311,26 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
}
/**
- * ath5k_hw_set_associd - Set BSSID for association
+ * ath5k_hw_set_bssid - Set current BSSID on hw
*
* @ah: The &struct ath5k_hw
- * @bssid: BSSID
- * @assoc_id: Assoc id
*
- * Sets the BSSID which trigers the "SME Join" operation
+ * Sets the current BSSID and BSSID mask we have from the
+ * common struct into the hardware
*/
-void ath5k_hw_set_associd(struct ath5k_hw *ah)
+void ath5k_hw_set_bssid(struct ath5k_hw *ah)
{
struct ath_common *common = ath5k_hw_common(ah);
u16 tim_offset = 0;
/*
- * Set simple BSSID mask on 5212
+ * Set BSSID mask on 5212
*/
if (ah->ah_version == AR5K_AR5212)
ath_hw_setbssidmask(common);
/*
- * Set BSSID which triggers the "SME Join" operation
+ * Set BSSID
*/
ath5k_hw_reg_write(ah,
get_unaligned_le32(common->curbssid),
@@ -496,6 +498,10 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
{
u32 tsf_lower, tsf_upper1, tsf_upper2;
int i;
+ unsigned long flags;
+
+ /* This code is time critical - we don't want to be interrupted here */
+ local_irq_save(flags);
/*
* While reading TSF upper and then lower part, the clock is still
@@ -518,6 +524,8 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
tsf_upper1 = tsf_upper2;
}
+ local_irq_restore(flags);
+
WARN_ON( i == ATH5K_MAX_TSF_READ );
return (((u64)tsf_upper1 << 32) | tsf_lower);
@@ -601,7 +609,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
/* Timer3 marks the end of our ATIM window
* a zero length window is not allowed because
* we 'll get no beacons */
- timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
+ timer3 = next_beacon + 1;
/*
* Set the beacon register and enable all timers.
@@ -641,198 +649,95 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
}
-
-/*********************\
-* Key table functions *
-\*********************/
-
-/*
- * Reset a key entry on the table
+/**
+ * ath5k_check_timer_win - Check if timer B is timer A + window
+ *
+ * @a: timer a (before b)
+ * @b: timer b (after a)
+ * @window: difference between a and b
+ * @intval: timers are increased by this interval
+ *
+ * This helper function checks if timer B is timer A + window and covers
+ * cases where timer A or B might have already been updated or wrapped
+ * around (Timers are 16 bit).
+ *
+ * Returns true if O.K.
*/
-int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
+static inline bool
+ath5k_check_timer_win(int a, int b, int window, int intval)
{
- unsigned int i, type;
- u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
-
- AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
-
- type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry));
-
- for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
- ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
-
- /* Reset associated MIC entry if TKIP
- * is enabled located at offset (entry + 64) */
- if (type == AR5K_KEYTABLE_TYPE_TKIP) {
- AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE);
- for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++)
- ath5k_hw_reg_write(ah, 0,
- AR5K_KEYTABLE_OFF(micentry, i));
- }
-
/*
- * Set NULL encryption on AR5212+
- *
- * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
- * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
- *
- * Note2: Windows driver (ndiswrapper) sets this to
- * 0x00000714 instead of 0x00000007
+ * 1.) usually B should be A + window
+ * 2.) A already updated, B not updated yet
+ * 3.) A already updated and has wrapped around
+ * 4.) B has wrapped around
*/
- if (ah->ah_version >= AR5K_AR5211) {
- ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
- AR5K_KEYTABLE_TYPE(entry));
-
- if (type == AR5K_KEYTABLE_TYPE_TKIP) {
- ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
- AR5K_KEYTABLE_TYPE(micentry));
- }
- }
-
- return 0;
+ if ((b - a == window) || /* 1.) */
+ (a - b == intval - window) || /* 2.) */
+ ((a | 0x10000) - b == intval - window) || /* 3.) */
+ ((b | 0x10000) - a == window)) /* 4.) */
+ return true; /* O.K. */
+ return false;
}
-static
-int ath5k_keycache_type(const struct ieee80211_key_conf *key)
-{
- switch (key->alg) {
- case ALG_TKIP:
- return AR5K_KEYTABLE_TYPE_TKIP;
- case ALG_CCMP:
- return AR5K_KEYTABLE_TYPE_CCM;
- case ALG_WEP:
- if (key->keylen == WLAN_KEY_LEN_WEP40)
- return AR5K_KEYTABLE_TYPE_40;
- else if (key->keylen == WLAN_KEY_LEN_WEP104)
- return AR5K_KEYTABLE_TYPE_104;
- return -EINVAL;
- default:
- return -EINVAL;
- }
- return -EINVAL;
-}
-
-/*
- * Set a key entry on the table
+/**
+ * ath5k_hw_check_beacon_timers - Check if the beacon timers are correct
+ *
+ * @ah: The &struct ath5k_hw
+ * @intval: beacon interval
+ *
+ * This is a workaround for IBSS mode:
+ *
+ * The need for this function arises from the fact that we have 4 separate
+ * HW timer registers (TIMER0 - TIMER3), which are closely related to the
+ * next beacon target time (NBTT), and that the HW updates these timers
+ * seperately based on the current TSF value. The hardware increments each
+ * timer by the beacon interval, when the local TSF coverted to TU is equal
+ * to the value stored in the timer.
+ *
+ * The reception of a beacon with the same BSSID can update the local HW TSF
+ * at any time - this is something we can't avoid. If the TSF jumps to a
+ * time which is later than the time stored in a timer, this timer will not
+ * be updated until the TSF in TU wraps around at 16 bit (the size of the
+ * timers) and reaches the time which is stored in the timer.
+ *
+ * The problem is that these timers are closely related to TIMER0 (NBTT) and
+ * that they define a time "window". When the TSF jumps between two timers
+ * (e.g. ATIM and NBTT), the one in the past will be left behind (not
+ * updated), while the one in the future will be updated every beacon
+ * interval. This causes the window to get larger, until the TSF wraps
+ * around as described above and the timer which was left behind gets
+ * updated again. But - because the beacon interval is usually not an exact
+ * divisor of the size of the timers (16 bit), an unwanted "window" between
+ * these timers has developed!
+ *
+ * This is especially important with the ATIM window, because during
+ * the ATIM window only ATIM frames and no data frames are allowed to be
+ * sent, which creates transmission pauses after each beacon. This symptom
+ * has been described as "ramping ping" because ping times increase linearly
+ * for some time and then drop down again. A wrong window on the DMA beacon
+ * timer has the same effect, so we check for these two conditions.
+ *
+ * Returns true if O.K.
*/
-int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
- const struct ieee80211_key_conf *key, const u8 *mac)
-{
- unsigned int i;
- int keylen;
- __le32 key_v[5] = {};
- __le32 key0 = 0, key1 = 0;
- __le32 *rxmic, *txmic;
- int keytype;
- u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
- bool is_tkip;
- const u8 *key_ptr;
-
- is_tkip = (key->alg == ALG_TKIP);
-
- /*
- * key->keylen comes in from mac80211 in bytes.
- * TKIP is 128 bit + 128 bit mic
- */
- keylen = (is_tkip) ? (128 / 8) : key->keylen;
-
- if (entry > AR5K_KEYTABLE_SIZE ||
- (is_tkip && micentry > AR5K_KEYTABLE_SIZE))
- return -EOPNOTSUPP;
-
- if (unlikely(keylen > 16))
- return -EOPNOTSUPP;
-
- keytype = ath5k_keycache_type(key);
- if (keytype < 0)
- return keytype;
-
- /*
- * each key block is 6 bytes wide, written as pairs of
- * alternating 32 and 16 bit le values.
- */
- key_ptr = key->key;
- for (i = 0; keylen >= 6; keylen -= 6) {
- memcpy(&key_v[i], key_ptr, 6);
- i += 2;
- key_ptr += 6;
- }
- if (keylen)
- memcpy(&key_v[i], key_ptr, keylen);
-
- /* intentionally corrupt key until mic is installed */
- if (is_tkip) {
- key0 = key_v[0] = ~key_v[0];
- key1 = key_v[1] = ~key_v[1];
- }
-
- for (i = 0; i < ARRAY_SIZE(key_v); i++)
- ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
- AR5K_KEYTABLE_OFF(entry, i));
-
- ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
-
- if (is_tkip) {
- /* Install rx/tx MIC */
- rxmic = (__le32 *) &key->key[16];
- txmic = (__le32 *) &key->key[24];
-
- if (ah->ah_combined_mic) {
- key_v[0] = rxmic[0];
- key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16);
- key_v[2] = rxmic[1];
- key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff);
- key_v[4] = txmic[1];
- } else {
- key_v[0] = rxmic[0];
- key_v[1] = 0;
- key_v[2] = rxmic[1];
- key_v[3] = 0;
- key_v[4] = 0;
- }
- for (i = 0; i < ARRAY_SIZE(key_v); i++)
- ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
- AR5K_KEYTABLE_OFF(micentry, i));
-
- ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
- AR5K_KEYTABLE_TYPE(micentry));
- ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC0(micentry));
- ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC1(micentry));
-
- /* restore first 2 words of key */
- ath5k_hw_reg_write(ah, le32_to_cpu(~key0),
- AR5K_KEYTABLE_OFF(entry, 0));
- ath5k_hw_reg_write(ah, le32_to_cpu(~key1),
- AR5K_KEYTABLE_OFF(entry, 1));
- }
-
- return ath5k_hw_set_key_lladdr(ah, entry, mac);
-}
-
-int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
+bool
+ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
{
- u32 low_id, high_id;
-
- /* Invalid entry (key table overflow) */
- AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+ unsigned int nbtt, atim, dma;
- /*
- * MAC may be NULL if it's a broadcast key. In this case no need to
- * to compute get_unaligned_le32 and get_unaligned_le16 as we
- * already know it.
- */
- if (!mac) {
- low_id = 0xffffffff;
- high_id = 0xffff | AR5K_KEYTABLE_VALID;
- } else {
- low_id = get_unaligned_le32(mac);
- high_id = get_unaligned_le16(mac + 4) | AR5K_KEYTABLE_VALID;
- }
+ nbtt = ath5k_hw_reg_read(ah, AR5K_TIMER0);
+ atim = ath5k_hw_reg_read(ah, AR5K_TIMER3);
+ dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3;
- ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
- ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
+ /* NOTE: SWBA is different. Having a wrong window there does not
+ * stop us from sending data and this condition is catched thru
+ * other means (SWBA interrupt) */
- return 0;
+ if (ath5k_check_timer_win(nbtt, atim, 1, intval) &&
+ ath5k_check_timer_win(dma, nbtt, AR5K_TUNE_DMA_BEACON_RESP,
+ intval))
+ return true; /* O.K. */
+ return false;
}
/**
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 6284c389ba18..219367884e64 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -115,7 +115,7 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
\**********************/
/*
- * This code is used to optimize rf gain on different environments
+ * This code is used to optimize RF gain on different environments
* (temperature mostly) based on feedback from a power detector.
*
* It's only used on RF5111 and RF5112, later RF chips seem to have
@@ -302,7 +302,7 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
}
/* Perform gain_F adjustment by choosing the right set
- * of parameters from rf gain optimization ladder */
+ * of parameters from RF gain optimization ladder */
static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
{
const struct ath5k_gain_opt *go;
@@ -367,7 +367,7 @@ done:
return ret;
}
-/* Main callback for thermal rf gain calibration engine
+/* Main callback for thermal RF gain calibration engine
* Check for a new gain reading and schedule an adjustment
* if needed.
*
@@ -433,7 +433,7 @@ done:
return ah->ah_gain.g_state;
}
-/* Write initial rf gain table to set the RF sensitivity
+/* Write initial RF gain table to set the RF sensitivity
* this one works on all RF chips and has nothing to do
* with gain_F calibration */
int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
@@ -496,7 +496,7 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
/*
- * Setup RF registers by writing rf buffer on hw
+ * Setup RF registers by writing RF buffer on hw
*/
int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
unsigned int mode)
@@ -571,7 +571,7 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
return -EINVAL;
}
- /* If it's the first time we set rf buffer, allocate
+ /* If it's the first time we set RF buffer, allocate
* ah->ah_rf_banks based on ah->ah_rf_banks_size
* we set above */
if (ah->ah_rf_banks == NULL) {
@@ -1093,6 +1093,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
ah->ah_current_channel = channel;
ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
+ ath5k_hw_set_clockrate(ah);
return 0;
}
@@ -1257,7 +1258,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
* Disable beacons and RX/TX queues, wait
*/
AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210,
- AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
+ AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);
@@ -1336,7 +1337,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
* Re-enable RX/TX and beacons
*/
AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
- AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
+ AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
return 0;
@@ -1377,7 +1378,7 @@ ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
/* protect against divide by 0 and loss of sign bits */
if (i_coffd == 0 || q_coffd < 2)
- return -1;
+ return 0;
i_coff = (-iq_corr) / i_coffd;
i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
@@ -1582,7 +1583,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
else if (curr_sym_off >= 31 && curr_sym_off <= 46)
mag_mask[2] |=
plt_mag_map << (curr_sym_off - 31) * 2;
- else if (curr_sym_off >= 46 && curr_sym_off <= 53)
+ else if (curr_sym_off >= 47 && curr_sym_off <= 53)
mag_mask[3] |=
plt_mag_map << (curr_sym_off - 47) * 2;
@@ -2987,7 +2988,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
/*
- * Set transmition power
+ * Set transmission power
*/
int
ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
@@ -3035,9 +3036,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
/* Limit max power if we have a CTL available */
ath5k_get_max_ctl_power(ah, channel);
- /* FIXME: Tx power limit for this regdomain
- * XXX: Mac80211/CRDA will do that anyway ? */
-
/* FIXME: Antenna reduction stuff */
/* FIXME: Limit power on turbo modes */
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 4186ff4c6e9c..84c717ded1c5 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -36,24 +36,58 @@ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
}
/*
+ * Make sure cw is a power of 2 minus 1 and smaller than 1024
+ */
+static u16 ath5k_cw_validate(u16 cw_req)
+{
+ u32 cw = 1;
+ cw_req = min(cw_req, (u16)1023);
+
+ while (cw < cw_req)
+ cw = (cw << 1) | 1;
+
+ return cw;
+}
+
+/*
* Set properties for a transmit queue
*/
int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
- const struct ath5k_txq_info *queue_info)
+ const struct ath5k_txq_info *qinfo)
{
+ struct ath5k_txq_info *qi;
+
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
- if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+ qi = &ah->ah_txq[queue];
+
+ if (qi->tqi_type == AR5K_TX_QUEUE_INACTIVE)
return -EIO;
- memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
+ /* copy and validate values */
+ qi->tqi_type = qinfo->tqi_type;
+ qi->tqi_subtype = qinfo->tqi_subtype;
+ qi->tqi_flags = qinfo->tqi_flags;
+ /*
+ * According to the docs: Although the AIFS field is 8 bit wide,
+ * the maximum supported value is 0xFC. Setting it higher than that
+ * will cause the DCU to hang.
+ */
+ qi->tqi_aifs = min(qinfo->tqi_aifs, (u8)0xFC);
+ qi->tqi_cw_min = ath5k_cw_validate(qinfo->tqi_cw_min);
+ qi->tqi_cw_max = ath5k_cw_validate(qinfo->tqi_cw_max);
+ qi->tqi_cbr_period = qinfo->tqi_cbr_period;
+ qi->tqi_cbr_overflow_limit = qinfo->tqi_cbr_overflow_limit;
+ qi->tqi_burst_time = qinfo->tqi_burst_time;
+ qi->tqi_ready_time = qinfo->tqi_ready_time;
/*XXX: Is this supported on 5210 ?*/
- if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
- ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
- (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
- queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
- ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
+ /*XXX: Is this correct for AR5K_WME_AC_VI,VO ???*/
+ if ((qinfo->tqi_type == AR5K_TX_QUEUE_DATA &&
+ ((qinfo->tqi_subtype == AR5K_WME_AC_VI) ||
+ (qinfo->tqi_subtype == AR5K_WME_AC_VO))) ||
+ qinfo->tqi_type == AR5K_TX_QUEUE_UAPSD)
+ qi->tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
return 0;
}
@@ -186,7 +220,7 @@ void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
*/
int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
{
- u32 cw_min, cw_max, retry_lg, retry_sh;
+ u32 retry_lg, retry_sh;
struct ath5k_txq_info *tq = &ah->ah_txq[queue];
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
@@ -217,14 +251,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
/* Set IFS0 */
if (ah->ah_turbo) {
ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
- (ah->ah_aifs + tq->tqi_aifs) *
- AR5K_INIT_SLOT_TIME_TURBO) <<
+ tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO) <<
AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
AR5K_IFS0);
} else {
ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
- (ah->ah_aifs + tq->tqi_aifs) *
- AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
+ tq->tqi_aifs * AR5K_INIT_SLOT_TIME) <<
+ AR5K_IFS0_DIFS_S) |
AR5K_INIT_SIFS, AR5K_IFS0);
}
@@ -248,35 +281,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
}
/*
- * Calculate cwmin/max by channel mode
- */
- cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
- cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
- ah->ah_aifs = AR5K_TUNE_AIFS;
- /*XR is only supported on 5212*/
- if (IS_CHAN_XR(ah->ah_current_channel) &&
- ah->ah_version == AR5K_AR5212) {
- cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
- cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
- ah->ah_aifs = AR5K_TUNE_AIFS_XR;
- /*B mode is not supported on 5210*/
- } else if (IS_CHAN_B(ah->ah_current_channel) &&
- ah->ah_version != AR5K_AR5210) {
- cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
- cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
- ah->ah_aifs = AR5K_TUNE_AIFS_11B;
- }
-
- cw_min = 1;
- while (cw_min < ah->ah_cw_min)
- cw_min = (cw_min << 1) | 1;
-
- cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
- ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
- cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
- ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
-
- /*
* Calculate and set retry limits
*/
if (ah->ah_software_retry) {
@@ -292,7 +296,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
/*No QCU/DCU [5210]*/
if (ah->ah_version == AR5K_AR5210) {
ath5k_hw_reg_write(ah,
- (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
+ (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
| AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
AR5K_NODCU_RETRY_LMT_SLG_RETRY)
| AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
@@ -314,14 +318,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
/*===Rest is also for QCU/DCU only [5211+]===*/
/*
- * Set initial content window (cw_min/cw_max)
+ * Set contention window (cw_min/cw_max)
* and arbitrated interframe space (aifs)...
*/
ath5k_hw_reg_write(ah,
- AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
- AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
- AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
- AR5K_DCU_LCL_IFS_AIFS),
+ AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
+ AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
+ AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
AR5K_QUEUE_DFS_LOCAL_IFS(queue));
/*
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 55b4ac6d236f..a34929f06533 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -1387,10 +1387,9 @@
/*
- * PCU control register
+ * PCU Diagnostic register
*
- * Only DIS_RX is used in the code, the rest i guess are
- * for tweaking/diagnostics.
+ * Used for tweaking/diagnostics.
*/
#define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */
#define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */
@@ -1399,22 +1398,22 @@
#define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */
#define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */
#define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */
-#define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable encryption */
-#define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable decryption */
-#define AR5K_DIAG_SW_DIS_TX 0x00000020 /* Disable transmit [5210] */
-#define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable recieve */
+#define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable HW encryption */
+#define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable HW decryption */
+#define AR5K_DIAG_SW_DIS_TX_5210 0x00000020 /* Disable transmit [5210] */
+#define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable receive */
#define AR5K_DIAG_SW_DIS_RX_5211 0x00000020
#define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \
AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211)
-#define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* Loopback (i guess it goes with DIS_TX) [5210] */
+#define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* TX Data Loopback (i guess it goes with DIS_TX) [5210] */
#define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040
#define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \
AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211)
-#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Corrupted FCS */
+#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Generate invalid TX FCS */
#define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080
#define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \
AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211)
-#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Dump channel info */
+#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Add 56 bytes of channel info before the frame data in the RX buffer */
#define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100
#define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \
AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211)
@@ -1426,17 +1425,17 @@
#define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */
#define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */
#define AR5K_DIAG_SW_SCRAM_SEED_S 10
-#define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */
+#define AR5K_DIAG_SW_DIS_SEQ_INC_5210 0x00040000 /* Disable seqnum increment (?)[5210] */
#define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000
#define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */
#define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \
AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211)
#define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */
#define AR5K_DIAG_SW_OBSPT_S 18
-#define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x0010000 /* Force RX Clear high */
-#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000 /* Ignore virtual carrier sense */
-#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH 0x0040000 /* Force channel idle high */
-#define AR5K_DIAG_SW_PHEAR_ME 0x0080000 /* ??? */
+#define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x00100000 /* Ignore carrier sense */
+#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x00200000 /* Ignore virtual carrier sense */
+#define AR5K_DIAG_SW_CHANNEL_IDLE_HIGH 0x00400000 /* Force channel idle high */
+#define AR5K_DIAG_SW_PHEAR_ME 0x00800000 /* ??? */
/*
* TSF (clock) register (lower 32 bits)
@@ -1822,50 +1821,8 @@
/*===5212 end===*/
-/*
- * Key table (WEP) register
- */
-#define AR5K_KEYTABLE_0_5210 0x9000
-#define AR5K_KEYTABLE_0_5211 0x8800
-#define AR5K_KEYTABLE_5210(_n) (AR5K_KEYTABLE_0_5210 + ((_n) << 5))
-#define AR5K_KEYTABLE_5211(_n) (AR5K_KEYTABLE_0_5211 + ((_n) << 5))
-#define AR5K_KEYTABLE(_n) (ah->ah_version == AR5K_AR5210 ? \
- AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n))
-#define AR5K_KEYTABLE_OFF(_n, x) (AR5K_KEYTABLE(_n) + (x << 2))
-#define AR5K_KEYTABLE_TYPE(_n) AR5K_KEYTABLE_OFF(_n, 5)
-#define AR5K_KEYTABLE_TYPE_40 0x00000000
-#define AR5K_KEYTABLE_TYPE_104 0x00000001
-#define AR5K_KEYTABLE_TYPE_128 0x00000003
-#define AR5K_KEYTABLE_TYPE_TKIP 0x00000004 /* [5212+] */
-#define AR5K_KEYTABLE_TYPE_AES 0x00000005 /* [5211+] */
-#define AR5K_KEYTABLE_TYPE_CCM 0x00000006 /* [5212+] */
-#define AR5K_KEYTABLE_TYPE_NULL 0x00000007 /* [5211+] */
-#define AR5K_KEYTABLE_ANTENNA 0x00000008 /* [5212+] */
-#define AR5K_KEYTABLE_MAC0(_n) AR5K_KEYTABLE_OFF(_n, 6)
-#define AR5K_KEYTABLE_MAC1(_n) AR5K_KEYTABLE_OFF(_n, 7)
-#define AR5K_KEYTABLE_VALID 0x00008000
-
-/* If key type is TKIP and MIC is enabled
- * MIC key goes in offset entry + 64 */
-#define AR5K_KEYTABLE_MIC_OFFSET 64
-
-/* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit
- * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit
- * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit
- *
- * Some vendors have introduced bigger WEP keys to address
- * security vulnerabilities in WEP. This includes:
- *
- * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit
- *
- * We can expand this if we find ar5k Atheros cards with a larger
- * key table size.
- */
#define AR5K_KEYTABLE_SIZE_5210 64
#define AR5K_KEYTABLE_SIZE_5211 128
-#define AR5K_KEYTABLE_SIZE (ah->ah_version == AR5K_AR5210 ? \
- AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211)
-
/*===PHY REGISTERS===*/
@@ -1911,7 +1868,7 @@
#define AR5K_PHY_TURBO 0x9804 /* Register Address */
#define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */
#define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */
-#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */
+#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo */
/*
* PHY agility command register
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 498aa28ea9e6..5b179d01f97d 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -167,7 +167,7 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
* ieee80211_duration() for a brief description of
* what rate we should choose to TX ACKs. */
tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
- sc->vif, 10, rate));
+ NULL, 10, rate));
ath5k_hw_reg_write(ah, tx_time, reg);
@@ -326,7 +326,7 @@ commit:
* register). After this MAC and Baseband are
* disabled and a full reset is needed to come
* back. This way we save as much power as possible
- * without puting the card on full sleep.
+ * without putting the card on full sleep.
*/
int ath5k_hw_on_hold(struct ath5k_hw *ah)
{
@@ -344,7 +344,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
/*
* Put chipset on warm reset...
*
- * Note: puting PCI core on warm reset on PCI-E cards
+ * Note: putting PCI core on warm reset on PCI-E cards
* results card to hang and always return 0xffff... so
* we ingore that flag for PCI-E cards. On PCI cards
* this flag gets cleared after 64 PCI clocks.
@@ -400,7 +400,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
/*
* Put chipset on warm reset...
*
- * Note: puting PCI core on warm reset on PCI-E cards
+ * Note: putting PCI core on warm reset on PCI-E cards
* results card to hang and always return 0xffff... so
* we ingore that flag for PCI-E cards. On PCI cards
* this flag gets cleared after 64 PCI clocks.
@@ -959,7 +959,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
AR5K_QUEUE_DCU_SEQNUM(0));
}
- /* TSF accelerates on AR5211 durring reset
+ /* TSF accelerates on AR5211 during reset
* As a workaround save it here and restore
* it later so that it's back in time after
* reset. This way it'll get re-synced on the
@@ -1060,7 +1060,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
* XXX: rethink this after new mode changes to
* mac80211 are integrated */
if (ah->ah_version == AR5K_AR5212 &&
- ah->ah_sc->vif != NULL)
+ ah->ah_sc->nvifs)
ath5k_hw_write_rate_duration(ah, mode);
/*
@@ -1080,7 +1080,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
return ret;
/* Spur info is available only from EEPROM versions
- * bigger than 5.3 but but the EEPOM routines will use
+ * greater than 5.3, but the EEPROM routines will use
* static values for older versions */
if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
ath5k_hw_set_spur_mitigation_filter(ah,
@@ -1160,7 +1160,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
*/
/* Restore bssid and bssid mask */
- ath5k_hw_set_associd(ah);
+ ath5k_hw_set_bssid(ah);
/* Set PCU config */
ath5k_hw_set_opmode(ah, op_mode);
@@ -1173,11 +1173,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/* Set RSSI/BRSSI thresholds
*
* Note: If we decide to set this value
- * dynamicaly, have in mind that when AR5K_RSSI_THR
- * register is read it might return 0x40 if we haven't
- * wrote anything to it plus BMISS RSSI threshold is zeroed.
+ * dynamically, keep in mind that when AR5K_RSSI_THR
+ * register is read, it might return 0x40 if we haven't
+ * written anything to it. Also, BMISS RSSI threshold is zeroed.
* So doing a save/restore procedure here isn't the right
- * choice. Instead store it on ath5k_hw */
+ * choice. Instead, store it in ath5k_hw */
ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
AR5K_TUNE_BMISS_THRES <<
AR5K_RSSI_THR_BMISS_S),
@@ -1235,7 +1235,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/*
* Perform ADC test to see if baseband is ready
- * Set tx hold and check adc test register
+ * Set TX hold and check ADC test register
*/
phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
@@ -1254,15 +1254,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
*
* This method is used to calibrate some static offsets
* used together with on-the fly I/Q calibration (the
- * one performed via ath5k_hw_phy_calibrate), that doesn't
+ * one performed via ath5k_hw_phy_calibrate), which doesn't
* interrupt rx path.
*
* While rx path is re-routed to the power detector we also
- * start a noise floor calibration, to measure the
+ * start a noise floor calibration to measure the
* card's noise floor (the noise we measure when we are not
- * transmiting or receiving anything).
+ * transmitting or receiving anything).
*
- * If we are in a noisy environment AGC calibration may time
+ * If we are in a noisy environment, AGC calibration may time
* out and/or noise floor calibration might timeout.
*/
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h
index e50baff66175..3ac4cff4239d 100644
--- a/drivers/net/wireless/ath/ath5k/rfbuffer.h
+++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h
@@ -25,10 +25,10 @@
*
* We don't write on those registers directly but
* we send a data packet on the chip, using a special register,
- * that holds all the settings we need. After we 've sent the
+ * that holds all the settings we need. After we've sent the
* data packet, we write on another special register to notify hw
* to apply the settings. This is done so that control registers
- * can be dynamicaly programmed during operation and the settings
+ * can be dynamically programmed during operation and the settings
* are applied faster on the hw.
*
* We call each data packet an "RF Bank" and all the data we write
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 35f23bdc442f..ad57a6d23110 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -32,6 +32,14 @@ config ATH9K_DEBUGFS
Also required for changing debug message flags at run time.
+config ATH9K_RATE_CONTROL
+ bool "Atheros ath9k rate control"
+ depends on ATH9K
+ default y
+ ---help---
+ Say Y, if you want to use the ath9k specific rate control
+ module instead of minstrel_ht.
+
config ATH9K_HTC
tristate "Atheros HTC based wireless cards support"
depends on USB && MAC80211
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 973ae4f49f35..aca01621c205 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -5,8 +5,8 @@ ath9k-y += beacon.o \
recv.o \
xmit.o \
virtual.o \
- rc.o
+ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
ath9k-$(CONFIG_PCI) += pci.o
ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
@@ -46,6 +46,7 @@ ath9k_htc-y += htc_hst.o \
htc_drv_txrx.o \
htc_drv_main.o \
htc_drv_beacon.o \
- htc_drv_init.o
+ htc_drv_init.o \
+ htc_drv_gpio.o
obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index a3d95cca8f0c..63ccb39cdcd4 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -14,6 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/kernel.h>
#include "hw.h"
#include "hw-ops.h"
@@ -48,7 +49,7 @@ static const struct ani_ofdm_level_entry ofdm_level_table[] = {
{ 7, 8, 0 } /* lvl 9 */
};
#define ATH9K_ANI_OFDM_NUM_LEVEL \
- (sizeof(ofdm_level_table)/sizeof(ofdm_level_table[0]))
+ ARRAY_SIZE(ofdm_level_table)
#define ATH9K_ANI_OFDM_MAX_LEVEL \
(ATH9K_ANI_OFDM_NUM_LEVEL-1)
#define ATH9K_ANI_OFDM_DEF_LEVEL \
@@ -94,7 +95,7 @@ static const struct ani_cck_level_entry cck_level_table[] = {
};
#define ATH9K_ANI_CCK_NUM_LEVEL \
- (sizeof(cck_level_table)/sizeof(cck_level_table[0]))
+ ARRAY_SIZE(cck_level_table)
#define ATH9K_ANI_CCK_MAX_LEVEL \
(ATH9K_ANI_CCK_NUM_LEVEL-1)
#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \
@@ -102,31 +103,9 @@ static const struct ani_cck_level_entry cck_level_table[] = {
#define ATH9K_ANI_CCK_DEF_LEVEL \
2 /* default level - matches the INI settings */
-/* Private to ani.c */
-static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
+static bool use_new_ani(struct ath_hw *ah)
{
- ath9k_hw_private_ops(ah)->ani_lower_immunity(ah);
-}
-
-int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
- struct ath9k_channel *chan)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
- if (ah->ani[i].c &&
- ah->ani[i].c->channel == chan->channel)
- return i;
- if (ah->ani[i].c == NULL) {
- ah->ani[i].c = chan;
- return i;
- }
- }
-
- ath_print(ath9k_hw_common(ah), ATH_DBG_ANI,
- "No more channel states left. Using channel 0\n");
-
- return 0;
+ return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani;
}
static void ath9k_hw_update_mibstats(struct ath_hw *ah,
@@ -139,82 +118,34 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah,
stats->beacons += REG_READ(ah, AR_BEACON_CNT);
}
-static void ath9k_ani_restart_old(struct ath_hw *ah)
+static void ath9k_ani_restart(struct ath_hw *ah)
{
struct ar5416AniState *aniState;
struct ath_common *common = ath9k_hw_common(ah);
+ u32 ofdm_base = 0, cck_base = 0;
if (!DO_ANI(ah))
return;
- aniState = ah->curani;
+ aniState = &ah->curchan->ani;
aniState->listenTime = 0;
- if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
- aniState->ofdmPhyErrBase = 0;
- ath_print(common, ATH_DBG_ANI,
- "OFDM Trigger is too high for hw counters\n");
- } else {
- aniState->ofdmPhyErrBase =
- AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
- }
- if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
- aniState->cckPhyErrBase = 0;
- ath_print(common, ATH_DBG_ANI,
- "CCK Trigger is too high for hw counters\n");
- } else {
- aniState->cckPhyErrBase =
- AR_PHY_COUNTMAX - aniState->cckTrigHigh;
+ if (!use_new_ani(ah)) {
+ ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
+ cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
}
- ath_print(common, ATH_DBG_ANI,
- "Writing ofdmbase=%u cckbase=%u\n",
- aniState->ofdmPhyErrBase,
- aniState->cckPhyErrBase);
-
- ENABLE_REGWRITE_BUFFER(ah);
-
- REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
- REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
-
- REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
-
- ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-
- aniState->ofdmPhyErrCount = 0;
- aniState->cckPhyErrCount = 0;
-}
-
-static void ath9k_ani_restart_new(struct ath_hw *ah)
-{
- struct ar5416AniState *aniState;
- struct ath_common *common = ath9k_hw_common(ah);
-
- if (!DO_ANI(ah))
- return;
-
- aniState = ah->curani;
- aniState->listenTime = 0;
-
- aniState->ofdmPhyErrBase = 0;
- aniState->cckPhyErrBase = 0;
ath_print(common, ATH_DBG_ANI,
- "Writing ofdmbase=%08x cckbase=%08x\n",
- aniState->ofdmPhyErrBase,
- aniState->cckPhyErrBase);
+ "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base);
ENABLE_REGWRITE_BUFFER(ah);
- REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
+ REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
+ REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
@@ -228,10 +159,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
struct ar5416AniState *aniState;
int32_t rssi;
- if (!DO_ANI(ah))
- return;
-
- aniState = ah->curani;
+ aniState = &ah->curchan->ani;
if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
@@ -300,10 +228,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
struct ar5416AniState *aniState;
int32_t rssi;
- if (!DO_ANI(ah))
- return;
-
- aniState = ah->curani;
+ aniState = &ah->curchan->ani;
if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel + 1)) {
@@ -335,7 +260,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
/* Adjust the OFDM Noise Immunity Level */
static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
{
- struct ar5416AniState *aniState = ah->curani;
+ struct ar5416AniState *aniState = &ah->curchan->ani;
struct ath_common *common = ath9k_hw_common(ah);
const struct ani_ofdm_level_entry *entry_ofdm;
const struct ani_cck_level_entry *entry_cck;
@@ -380,14 +305,19 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
}
}
-static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah)
+static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
{
struct ar5416AniState *aniState;
if (!DO_ANI(ah))
return;
- aniState = ah->curani;
+ if (!use_new_ani(ah)) {
+ ath9k_hw_ani_ofdm_err_trigger_old(ah);
+ return;
+ }
+
+ aniState = &ah->curchan->ani;
if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1);
@@ -398,7 +328,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah)
*/
static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
{
- struct ar5416AniState *aniState = ah->curani;
+ struct ar5416AniState *aniState = &ah->curchan->ani;
struct ath_common *common = ath9k_hw_common(ah);
const struct ani_ofdm_level_entry *entry_ofdm;
const struct ani_cck_level_entry *entry_cck;
@@ -437,14 +367,19 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
entry_cck->mrc_cck_on);
}
-static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah)
+static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
{
struct ar5416AniState *aniState;
if (!DO_ANI(ah))
return;
- aniState = ah->curani;
+ if (!use_new_ani(ah)) {
+ ath9k_hw_ani_cck_err_trigger_old(ah);
+ return;
+ }
+
+ aniState = &ah->curchan->ani;
if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
@@ -455,7 +390,7 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
struct ar5416AniState *aniState;
int32_t rssi;
- aniState = ah->curani;
+ aniState = &ah->curchan->ani;
if (ah->opmode == NL80211_IFTYPE_AP) {
if (aniState->firstepLevel > 0) {
@@ -507,11 +442,16 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
* only lower either OFDM or CCK errors per turn
* we lower the other one next time
*/
-static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah)
+static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
{
struct ar5416AniState *aniState;
- aniState = ah->curani;
+ aniState = &ah->curchan->ani;
+
+ if (!use_new_ani(ah)) {
+ ath9k_hw_ani_lower_immunity_old(ah);
+ return;
+ }
/* lower OFDM noise immunity */
if (aniState->ofdmNoiseImmunityLevel > 0 &&
@@ -525,87 +465,18 @@ static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah)
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
}
-static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
-{
- struct ath9k_channel *chan = ah->curchan;
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
- u8 clockrate; /* in MHz */
-
- if (!ah->curchan) /* should really check for CCK instead */
- clockrate = ATH9K_CLOCK_RATE_CCK;
- else if (conf->channel->band == IEEE80211_BAND_2GHZ)
- clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
- else if (IS_CHAN_A_FAST_CLOCK(ah, chan))
- clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
- else
- clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
-
- if (conf_is_ht40(conf))
- return clockrate * 2;
-
- return clockrate;
-}
-
-static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
-{
- struct ar5416AniState *aniState;
- struct ath_common *common = ath9k_hw_common(ah);
- u32 txFrameCount, rxFrameCount, cycleCount;
- int32_t listenTime;
-
- txFrameCount = REG_READ(ah, AR_TFCNT);
- rxFrameCount = REG_READ(ah, AR_RFCNT);
- cycleCount = REG_READ(ah, AR_CCCNT);
-
- aniState = ah->curani;
- if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
- listenTime = 0;
- ah->stats.ast_ani_lzero++;
- ath_print(common, ATH_DBG_ANI,
- "1st call: aniState->cycleCount=%d\n",
- aniState->cycleCount);
- } else {
- int32_t ccdelta = cycleCount - aniState->cycleCount;
- int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
- int32_t tfdelta = txFrameCount - aniState->txFrameCount;
- int32_t clock_rate;
-
- /*
- * convert HW counter values to ms using mode
- * specifix clock rate
- */
- clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;;
-
- listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate;
-
- ath_print(common, ATH_DBG_ANI,
- "cyclecount=%d, rfcount=%d, "
- "tfcount=%d, listenTime=%d CLOCK_RATE=%d\n",
- ccdelta, rfdelta, tfdelta, listenTime, clock_rate);
- }
-
- aniState->cycleCount = cycleCount;
- aniState->txFrameCount = txFrameCount;
- aniState->rxFrameCount = rxFrameCount;
-
- return listenTime;
-}
-
static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
{
struct ar5416AniState *aniState;
struct ath9k_channel *chan = ah->curchan;
struct ath_common *common = ath9k_hw_common(ah);
- int index;
if (!DO_ANI(ah))
return;
- index = ath9k_hw_get_ani_channel_idx(ah, chan);
- aniState = &ah->ani[index];
- ah->curani = aniState;
+ aniState = &ah->curchan->ani;
- if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
+ if (ah->opmode != NL80211_IFTYPE_STATION
&& ah->opmode != NL80211_IFTYPE_ADHOC) {
ath_print(common, ATH_DBG_ANI,
"Reset ANI state opmode %u\n", ah->opmode);
@@ -634,17 +505,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
ATH9K_RX_FILTER_PHYERR);
- if (ah->opmode == NL80211_IFTYPE_AP) {
- ah->curani->ofdmTrigHigh =
- ah->config.ofdm_trig_high;
- ah->curani->ofdmTrigLow =
- ah->config.ofdm_trig_low;
- ah->curani->cckTrigHigh =
- ah->config.cck_trig_high;
- ah->curani->cckTrigLow =
- ah->config.cck_trig_low;
- }
- ath9k_ani_restart_old(ah);
+ ath9k_ani_restart(ah);
return;
}
@@ -666,7 +527,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
~ATH9K_RX_FILTER_PHYERR);
- ath9k_ani_restart_old(ah);
+ ath9k_ani_restart(ah);
ENABLE_REGWRITE_BUFFER(ah);
@@ -674,7 +535,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
/*
@@ -682,15 +542,18 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
* This routine should be called for every hardware reset and for
* every channel change.
*/
-static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
+void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
{
- struct ar5416AniState *aniState = ah->curani;
+ struct ar5416AniState *aniState = &ah->curchan->ani;
struct ath9k_channel *chan = ah->curchan;
struct ath_common *common = ath9k_hw_common(ah);
if (!DO_ANI(ah))
return;
+ if (!use_new_ani(ah))
+ return ath9k_ani_reset_old(ah, is_scanning);
+
BUG_ON(aniState == NULL);
ah->stats.ast_ani_reset++;
@@ -760,7 +623,7 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
* enable phy counters if hw supports or if not, enable phy
* interrupts (so we can count each one)
*/
- ath9k_ani_restart_new(ah);
+ ath9k_ani_restart(ah);
ENABLE_REGWRITE_BUFFER(ah);
@@ -768,28 +631,30 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
-static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
- struct ath9k_channel *chan)
+static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
{
- struct ar5416AniState *aniState;
struct ath_common *common = ath9k_hw_common(ah);
- int32_t listenTime;
- u32 phyCnt1, phyCnt2;
+ struct ar5416AniState *aniState = &ah->curchan->ani;
+ u32 ofdm_base = 0;
+ u32 cck_base = 0;
u32 ofdmPhyErrCnt, cckPhyErrCnt;
+ u32 phyCnt1, phyCnt2;
+ int32_t listenTime;
- if (!DO_ANI(ah))
- return;
-
- aniState = ah->curani;
+ ath_hw_cycle_counters_update(common);
+ listenTime = ath_hw_get_listen_time(common);
- listenTime = ath9k_hw_ani_get_listen_time(ah);
- if (listenTime < 0) {
+ if (listenTime <= 0) {
ah->stats.ast_ani_lneg++;
- ath9k_ani_restart_old(ah);
- return;
+ ath9k_ani_restart(ah);
+ return false;
+ }
+
+ if (!use_new_ani(ah)) {
+ ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
+ cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
}
aniState->listenTime += listenTime;
@@ -799,145 +664,55 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
- if (phyCnt1 < aniState->ofdmPhyErrBase ||
- phyCnt2 < aniState->cckPhyErrBase) {
- if (phyCnt1 < aniState->ofdmPhyErrBase) {
+ if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
+ if (phyCnt1 < ofdm_base) {
ath_print(common, ATH_DBG_ANI,
"phyCnt1 0x%x, resetting "
"counter value to 0x%x\n",
- phyCnt1,
- aniState->ofdmPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_1,
- aniState->ofdmPhyErrBase);
+ phyCnt1, ofdm_base);
+ REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
REG_WRITE(ah, AR_PHY_ERR_MASK_1,
AR_PHY_ERR_OFDM_TIMING);
}
- if (phyCnt2 < aniState->cckPhyErrBase) {
+ if (phyCnt2 < cck_base) {
ath_print(common, ATH_DBG_ANI,
"phyCnt2 0x%x, resetting "
"counter value to 0x%x\n",
- phyCnt2,
- aniState->cckPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_2,
- aniState->cckPhyErrBase);
+ phyCnt2, cck_base);
+ REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
REG_WRITE(ah, AR_PHY_ERR_MASK_2,
AR_PHY_ERR_CCK_TIMING);
}
- return;
+ return false;
}
- ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
+ ofdmPhyErrCnt = phyCnt1 - ofdm_base;
ah->stats.ast_ani_ofdmerrs +=
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
- cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
+ cckPhyErrCnt = phyCnt2 - cck_base;
ah->stats.ast_ani_cckerrs +=
cckPhyErrCnt - aniState->cckPhyErrCount;
aniState->cckPhyErrCount = cckPhyErrCnt;
-
- if (aniState->listenTime > 5 * ah->aniperiod) {
- if (aniState->ofdmPhyErrCount <= aniState->listenTime *
- aniState->ofdmTrigLow / 1000 &&
- aniState->cckPhyErrCount <= aniState->listenTime *
- aniState->cckTrigLow / 1000)
- ath9k_hw_ani_lower_immunity(ah);
- ath9k_ani_restart_old(ah);
- } else if (aniState->listenTime > ah->aniperiod) {
- if (aniState->ofdmPhyErrCount > aniState->listenTime *
- aniState->ofdmTrigHigh / 1000) {
- ath9k_hw_ani_ofdm_err_trigger_old(ah);
- ath9k_ani_restart_old(ah);
- } else if (aniState->cckPhyErrCount >
- aniState->listenTime * aniState->cckTrigHigh /
- 1000) {
- ath9k_hw_ani_cck_err_trigger_old(ah);
- ath9k_ani_restart_old(ah);
- }
- }
+ return true;
}
-static void ath9k_hw_ani_monitor_new(struct ath_hw *ah,
- struct ath9k_channel *chan)
+void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
{
struct ar5416AniState *aniState;
struct ath_common *common = ath9k_hw_common(ah);
- int32_t listenTime;
- u32 phyCnt1, phyCnt2;
- u32 ofdmPhyErrCnt, cckPhyErrCnt;
u32 ofdmPhyErrRate, cckPhyErrRate;
if (!DO_ANI(ah))
return;
- aniState = ah->curani;
+ aniState = &ah->curchan->ani;
if (WARN_ON(!aniState))
return;
- listenTime = ath9k_hw_ani_get_listen_time(ah);
- if (listenTime <= 0) {
- ah->stats.ast_ani_lneg++;
- /* restart ANI period if listenTime is invalid */
- ath_print(common, ATH_DBG_ANI,
- "listenTime=%d - on new ani monitor\n",
- listenTime);
- ath9k_ani_restart_new(ah);
- return;
- }
-
- aniState->listenTime += listenTime;
-
- ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-
- phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
- phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
-
- if (phyCnt1 < aniState->ofdmPhyErrBase ||
- phyCnt2 < aniState->cckPhyErrBase) {
- if (phyCnt1 < aniState->ofdmPhyErrBase) {
- ath_print(common, ATH_DBG_ANI,
- "phyCnt1 0x%x, resetting "
- "counter value to 0x%x\n",
- phyCnt1,
- aniState->ofdmPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_1,
- aniState->ofdmPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_MASK_1,
- AR_PHY_ERR_OFDM_TIMING);
- }
- if (phyCnt2 < aniState->cckPhyErrBase) {
- ath_print(common, ATH_DBG_ANI,
- "phyCnt2 0x%x, resetting "
- "counter value to 0x%x\n",
- phyCnt2,
- aniState->cckPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_2,
- aniState->cckPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_MASK_2,
- AR_PHY_ERR_CCK_TIMING);
- }
+ if (!ath9k_hw_ani_read_counters(ah))
return;
- }
-
- ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
- ah->stats.ast_ani_ofdmerrs +=
- ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
- aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
-
- cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
- ah->stats.ast_ani_cckerrs +=
- cckPhyErrCnt - aniState->cckPhyErrCount;
- aniState->cckPhyErrCount = cckPhyErrCnt;
-
- ath_print(common, ATH_DBG_ANI,
- "Errors: OFDM=0x%08x-0x%08x=%d "
- "CCK=0x%08x-0x%08x=%d\n",
- phyCnt1,
- aniState->ofdmPhyErrBase,
- ofdmPhyErrCnt,
- phyCnt2,
- aniState->cckPhyErrBase,
- cckPhyErrCnt);
ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
aniState->listenTime;
@@ -947,61 +722,34 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah,
ath_print(common, ATH_DBG_ANI,
"listenTime=%d OFDM:%d errs=%d/s CCK:%d "
"errs=%d/s ofdm_turn=%d\n",
- listenTime, aniState->ofdmNoiseImmunityLevel,
+ aniState->listenTime,
+ aniState->ofdmNoiseImmunityLevel,
ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
cckPhyErrRate, aniState->ofdmsTurn);
if (aniState->listenTime > 5 * ah->aniperiod) {
- if (ofdmPhyErrRate <= aniState->ofdmTrigLow &&
- cckPhyErrRate <= aniState->cckTrigLow) {
- ath_print(common, ATH_DBG_ANI,
- "1. listenTime=%d OFDM:%d errs=%d/s(<%d) "
- "CCK:%d errs=%d/s(<%d) -> "
- "ath9k_hw_ani_lower_immunity()\n",
- aniState->listenTime,
- aniState->ofdmNoiseImmunityLevel,
- ofdmPhyErrRate,
- aniState->ofdmTrigLow,
- aniState->cckNoiseImmunityLevel,
- cckPhyErrRate,
- aniState->cckTrigLow);
+ if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
+ cckPhyErrRate <= ah->config.cck_trig_low) {
ath9k_hw_ani_lower_immunity(ah);
aniState->ofdmsTurn = !aniState->ofdmsTurn;
}
- ath_print(common, ATH_DBG_ANI,
- "1 listenTime=%d ofdm=%d/s cck=%d/s - "
- "calling ath9k_ani_restart_new()\n",
- aniState->listenTime, ofdmPhyErrRate, cckPhyErrRate);
- ath9k_ani_restart_new(ah);
+ ath9k_ani_restart(ah);
} else if (aniState->listenTime > ah->aniperiod) {
/* check to see if need to raise immunity */
- if (ofdmPhyErrRate > aniState->ofdmTrigHigh &&
- (cckPhyErrRate <= aniState->cckTrigHigh ||
+ if (ofdmPhyErrRate > ah->config.ofdm_trig_high &&
+ (cckPhyErrRate <= ah->config.cck_trig_high ||
aniState->ofdmsTurn)) {
- ath_print(common, ATH_DBG_ANI,
- "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> "
- "ath9k_hw_ani_ofdm_err_trigger_new()\n",
- aniState->listenTime,
- aniState->ofdmNoiseImmunityLevel,
- ofdmPhyErrRate,
- aniState->ofdmTrigHigh);
- ath9k_hw_ani_ofdm_err_trigger_new(ah);
- ath9k_ani_restart_new(ah);
+ ath9k_hw_ani_ofdm_err_trigger(ah);
+ ath9k_ani_restart(ah);
aniState->ofdmsTurn = false;
- } else if (cckPhyErrRate > aniState->cckTrigHigh) {
- ath_print(common, ATH_DBG_ANI,
- "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> "
- "ath9k_hw_ani_cck_err_trigger_new()\n",
- aniState->listenTime,
- aniState->cckNoiseImmunityLevel,
- cckPhyErrRate,
- aniState->cckTrigHigh);
- ath9k_hw_ani_cck_err_trigger_new(ah);
- ath9k_ani_restart_new(ah);
+ } else if (cckPhyErrRate > ah->config.cck_trig_high) {
+ ath9k_hw_ani_cck_err_trigger(ah);
+ ath9k_ani_restart(ah);
aniState->ofdmsTurn = true;
}
}
}
+EXPORT_SYMBOL(ath9k_hw_ani_monitor);
void ath9k_enable_mib_counters(struct ath_hw *ah)
{
@@ -1022,7 +770,6 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
/* Freeze the MIB counters, get the stats and then clear them */
@@ -1040,53 +787,12 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
- u32 *rxc_pcnt,
- u32 *rxf_pcnt,
- u32 *txf_pcnt)
-{
- struct ath_common *common = ath9k_hw_common(ah);
- static u32 cycles, rx_clear, rx_frame, tx_frame;
- u32 good = 1;
-
- u32 rc = REG_READ(ah, AR_RCCNT);
- u32 rf = REG_READ(ah, AR_RFCNT);
- u32 tf = REG_READ(ah, AR_TFCNT);
- u32 cc = REG_READ(ah, AR_CCCNT);
-
- if (cycles == 0 || cycles > cc) {
- ath_print(common, ATH_DBG_ANI,
- "cycle counter wrap. ExtBusy = 0\n");
- good = 0;
- } else {
- u32 cc_d = cc - cycles;
- u32 rc_d = rc - rx_clear;
- u32 rf_d = rf - rx_frame;
- u32 tf_d = tf - tx_frame;
-
- if (cc_d != 0) {
- *rxc_pcnt = rc_d * 100 / cc_d;
- *rxf_pcnt = rf_d * 100 / cc_d;
- *txf_pcnt = tf_d * 100 / cc_d;
- } else {
- good = 0;
- }
- }
-
- cycles = cc;
- rx_frame = rf;
- rx_clear = rc;
- tx_frame = tf;
-
- return good;
-}
-
/*
* Process a MIB interrupt. We may potentially be invoked because
* any of the MIB counters overflow/trigger so don't assume we're
* here because a PHY error counter triggered.
*/
-static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah)
+void ath9k_hw_proc_mib_event(struct ath_hw *ah)
{
u32 phyCnt1, phyCnt2;
@@ -1114,72 +820,15 @@ static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah)
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
- struct ar5416AniState *aniState = ah->curani;
- u32 ofdmPhyErrCnt, cckPhyErrCnt;
-
- /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
- ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
- ah->stats.ast_ani_ofdmerrs +=
- ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
- aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
- cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
- ah->stats.ast_ani_cckerrs +=
- cckPhyErrCnt - aniState->cckPhyErrCount;
- aniState->cckPhyErrCount = cckPhyErrCnt;
+ if (!use_new_ani(ah))
+ ath9k_hw_ani_read_counters(ah);
- /*
- * NB: figure out which counter triggered. If both
- * trigger we'll only deal with one as the processing
- * clobbers the error counter so the trigger threshold
- * check will never be true.
- */
- if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
- ath9k_hw_ani_ofdm_err_trigger_new(ah);
- if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
- ath9k_hw_ani_cck_err_trigger_old(ah);
/* NB: always restart to insure the h/w counters are reset */
- ath9k_ani_restart_old(ah);
- }
-}
-
-/*
- * Process a MIB interrupt. We may potentially be invoked because
- * any of the MIB counters overflow/trigger so don't assume we're
- * here because a PHY error counter triggered.
- */
-static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah)
-{
- u32 phyCnt1, phyCnt2;
-
- /* Reset these counters regardless */
- REG_WRITE(ah, AR_FILT_OFDM, 0);
- REG_WRITE(ah, AR_FILT_CCK, 0);
- if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
- REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
-
- /* Clear the mib counters and save them in the stats */
- ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-
- if (!DO_ANI(ah)) {
- /*
- * We must always clear the interrupt cause by
- * resetting the phy error regs.
- */
- REG_WRITE(ah, AR_PHY_ERR_1, 0);
- REG_WRITE(ah, AR_PHY_ERR_2, 0);
- return;
+ ath9k_ani_restart(ah);
}
-
- /* NB: these are not reset-on-read */
- phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
- phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
-
- /* NB: always restart to insure the h/w counters are reset */
- if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
- ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK))
- ath9k_ani_restart_new(ah);
}
+EXPORT_SYMBOL(ath9k_hw_proc_mib_event);
void ath9k_hw_ani_setup(struct ath_hw *ah)
{
@@ -1205,61 +854,58 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
ath_print(common, ATH_DBG_ANI, "Initialize ANI\n");
- memset(ah->ani, 0, sizeof(ah->ani));
- for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
- if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) {
- ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
- ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
+ if (use_new_ani(ah)) {
+ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
+ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
- ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
- ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_NEW;
+ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
+ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW;
+ } else {
+ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
+ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
- ah->ani[i].spurImmunityLevel =
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
+ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
+ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
+ }
- ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
+ for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
+ struct ath9k_channel *chan = &ah->channels[i];
+ struct ar5416AniState *ani = &chan->ani;
- ah->ani[i].ofdmPhyErrBase = 0;
- ah->ani[i].cckPhyErrBase = 0;
+ if (use_new_ani(ah)) {
+ ani->spurImmunityLevel =
+ ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
+
+ ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
if (AR_SREV_9300_20_OR_LATER(ah))
- ah->ani[i].mrcCCKOff =
+ ani->mrcCCKOff =
!ATH9K_ANI_ENABLE_MRC_CCK;
else
- ah->ani[i].mrcCCKOff = true;
+ ani->mrcCCKOff = true;
- ah->ani[i].ofdmsTurn = true;
+ ani->ofdmsTurn = true;
} else {
- ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
- ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
-
- ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
- ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_OLD;
-
- ah->ani[i].spurImmunityLevel =
+ ani->spurImmunityLevel =
ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
- ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
+ ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
- ah->ani[i].ofdmPhyErrBase =
- AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
- ah->ani[i].cckPhyErrBase =
- AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH_OLD;
- ah->ani[i].cckWeakSigThreshold =
+ ani->cckWeakSigThreshold =
ATH9K_ANI_CCK_WEAK_SIG_THR;
}
- ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
- ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
- ah->ani[i].ofdmWeakSigDetectOff =
+ ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
+ ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
+ ani->ofdmWeakSigDetectOff =
!ATH9K_ANI_USE_OFDM_WEAK_SIG;
- ah->ani[i].cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
+ ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
}
/*
* since we expect some ongoing maintenance on the tables, let's sanity
* check here default level should not modify INI setting.
*/
- if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) {
+ if (use_new_ani(ah)) {
const struct ani_ofdm_level_entry *entry_ofdm;
const struct ani_cck_level_entry *entry_cck;
@@ -1273,50 +919,9 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
}
- ath_print(common, ATH_DBG_ANI,
- "Setting OfdmErrBase = 0x%08x\n",
- ah->ani[0].ofdmPhyErrBase);
- ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
- ah->ani[0].cckPhyErrBase);
-
- ENABLE_REGWRITE_BUFFER(ah);
-
- REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
-
- REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
-
- ath9k_enable_mib_counters(ah);
-
if (ah->config.enable_ani)
ah->proc_phyerr |= HAL_PROCESS_ANI;
-}
-
-void ath9k_hw_attach_ani_ops_old(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->ani_reset = ath9k_ani_reset_old;
- priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_old;
-
- ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_old;
- ops->ani_monitor = ath9k_hw_ani_monitor_old;
- ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n");
-}
-
-void ath9k_hw_attach_ani_ops_new(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->ani_reset = ath9k_ani_reset_new;
- priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new;
-
- ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_new;
- ops->ani_monitor = ath9k_hw_ani_monitor_new;
-
- ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n");
+ ath9k_ani_restart(ah);
+ ath9k_enable_mib_counters(ah);
}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index f4d0a4d48b37..0cd6783de883 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -19,7 +19,7 @@
#define HAL_PROCESS_ANI 0x00000001
-#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
+#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan)
#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
@@ -123,20 +123,11 @@ struct ar5416AniState {
u8 ofdmWeakSigDetectOff;
u8 cckWeakSigThreshold;
u32 listenTime;
- u32 ofdmTrigHigh;
- u32 ofdmTrigLow;
- int32_t cckTrigHigh;
- int32_t cckTrigLow;
int32_t rssiThrLow;
int32_t rssiThrHigh;
u32 noiseFloor;
- u32 txFrameCount;
- u32 rxFrameCount;
- u32 cycleCount;
u32 ofdmPhyErrCount;
u32 cckPhyErrCount;
- u32 ofdmPhyErrBase;
- u32 cckPhyErrBase;
int16_t pktRssi[2];
int16_t ofdmErrRssi[2];
int16_t cckErrRssi[2];
@@ -166,8 +157,6 @@ struct ar5416Stats {
void ath9k_enable_mib_counters(struct ath_hw *ah);
void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
- u32 *rxf_pcnt, u32 *txf_pcnt);
void ath9k_hw_ani_setup(struct ath_hw *ah);
void ath9k_hw_ani_init(struct ath_hw *ah);
int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 3d2c8679bc85..ea9f4497f58c 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -118,7 +118,7 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
if (!AR_SREV_5416(ah) || synth_freq >= 3000)
return;
- BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+ BUG_ON(AR_SREV_9280_20_OR_LATER(ah));
if (synth_freq < 2412)
new_bias = 0;
@@ -454,7 +454,7 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
- BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+ BUG_ON(AR_SREV_9280_20_OR_LATER(ah));
ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
@@ -484,7 +484,7 @@ static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah)
bank = NULL; \
} while (0);
- BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+ BUG_ON(AR_SREV_9280_20_OR_LATER(ah));
ATH_FREE_BANK(ah->analogBank0Data);
ATH_FREE_BANK(ah->analogBank1Data);
@@ -525,7 +525,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
* for single chip devices, that is AR9280 or anything
* after that.
*/
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah))
return true;
/* Setup rf parameters */
@@ -613,14 +613,11 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
rx_chainmask = ah->rxchainmask;
tx_chainmask = ah->txchainmask;
- ENABLE_REGWRITE_BUFFER(ah);
switch (rx_chainmask) {
case 0x5:
- DISABLE_REGWRITE_BUFFER(ah);
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
AR_PHY_SWAP_ALT_CHAIN);
- ENABLE_REGWRITE_BUFFER(ah);
case 0x3:
if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
@@ -630,17 +627,18 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
case 0x1:
case 0x2:
case 0x7:
+ ENABLE_REGWRITE_BUFFER(ah);
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
break;
default:
+ ENABLE_REGWRITE_BUFFER(ah);
break;
}
REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (tx_chainmask == 0x5) {
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
@@ -663,20 +661,20 @@ static void ar5008_hw_override_ini(struct ath_hw *ah,
*/
REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
val = REG_READ(ah, AR_PCU_MISC_MODE2);
if (!AR_SREV_9271(ah))
val &= ~AR_PCU_MISC_MODE2_HWWAR1;
- if (AR_SREV_9287_10_OR_LATER(ah))
+ if (AR_SREV_9287_11_OR_LATER(ah))
val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
}
if (!AR_SREV_5416_20_OR_LATER(ah) ||
- AR_SREV_9280_10_OR_LATER(ah))
+ AR_SREV_9280_20_OR_LATER(ah))
return;
/*
* Disable BB clock gating
@@ -701,7 +699,7 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
u32 phymode;
u32 enableDacFifo = 0;
- if (AR_SREV_9285_10_OR_LATER(ah))
+ if (AR_SREV_9285_12_OR_LATER(ah))
enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
AR_PHY_FC_ENABLE_DAC_FIFO);
@@ -726,7 +724,6 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
@@ -818,13 +815,12 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
- if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah))
+ if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah))
REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) ||
- AR_SREV_9287_10_OR_LATER(ah))
+ AR_SREV_9287_11_OR_LATER(ah))
REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
if (AR_SREV_9271_10(ah))
@@ -849,7 +845,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (AR_SREV_9271(ah)) {
if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
@@ -900,7 +895,7 @@ static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
- if (!AR_SREV_9280_10_OR_LATER(ah))
+ if (!AR_SREV_9280_20_OR_LATER(ah))
rfMode |= (IS_CHAN_5GHZ(chan)) ?
AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
@@ -1053,7 +1048,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
enum ath9k_ani_cmd cmd,
int param)
{
- struct ar5416AniState *aniState = ah->curani;
+ struct ar5416AniState *aniState = &ah->curchan->ani;
struct ath_common *common = ath9k_hw_common(ah);
switch (cmd & ah->ani_function) {
@@ -1225,8 +1220,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
aniState->firstepLevel,
aniState->listenTime);
ath_print(common, ATH_DBG_ANI,
- "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
- aniState->cycleCount,
+ "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
aniState->ofdmPhyErrCount,
aniState->cckPhyErrCount);
@@ -1237,9 +1231,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
enum ath9k_ani_cmd cmd,
int param)
{
- struct ar5416AniState *aniState = ah->curani;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
+ struct ar5416AniState *aniState = &chan->ani;
s32 value, value2;
switch (cmd & ah->ani_function) {
@@ -1478,15 +1472,13 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
ath_print(common, ATH_DBG_ANI,
"ANI parameters: SI=%d, ofdmWS=%s FS=%d "
- "MRCcck=%s listenTime=%d CC=%d listen=%d "
+ "MRCcck=%s listenTime=%d "
"ofdmErrs=%d cckErrs=%d\n",
aniState->spurImmunityLevel,
!aniState->ofdmWeakSigDetectOff ? "on" : "off",
aniState->firstepLevel,
!aniState->mrcCCKOff ? "on" : "off",
aniState->listenTime,
- aniState->cycleCount,
- aniState->listenTime,
aniState->ofdmPhyErrCount,
aniState->cckPhyErrCount);
return true;
@@ -1526,16 +1518,12 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah,
*/
static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
{
- struct ar5416AniState *aniState;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
+ struct ar5416AniState *aniState = &chan->ani;
struct ath9k_ani_default *iniDef;
- int index;
u32 val;
- index = ath9k_hw_get_ani_channel_idx(ah, chan);
- aniState = &ah->ani[index];
- ah->curani = aniState;
iniDef = &aniState->iniDef;
ath_print(common, ATH_DBG_ANI,
@@ -1579,8 +1567,6 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
aniState->mrcCCKOff = true; /* not available on pre AR9003 */
-
- aniState->cycleCount = 0;
}
static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index fe7418aefc4a..15f62cd0cc38 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -20,6 +20,13 @@
#define AR9285_CLCAL_REDO_THRESH 1
+enum ar9002_cal_types {
+ ADC_GAIN_CAL = BIT(0),
+ ADC_DC_CAL = BIT(1),
+ IQ_MISMATCH_CAL = BIT(2),
+};
+
+
static void ar9002_hw_setup_calibration(struct ath_hw *ah,
struct ath9k_cal_list *currCal)
{
@@ -45,13 +52,6 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah,
ath_print(common, ATH_DBG_CALIBRATE,
"starting ADC DC Calibration\n");
break;
- case ADC_DC_INIT_CAL:
- REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting Init ADC DC Calibration\n");
- break;
- case TEMP_COMP_CAL:
- break; /* Not supported */
}
REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
@@ -96,25 +96,6 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah,
return iscaldone;
}
-/* Assumes you are talking about the currently configured channel */
-static bool ar9002_hw_iscal_supported(struct ath_hw *ah,
- enum ath9k_cal_types calType)
-{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
- switch (calType & ah->supp_cals) {
- case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
- return true;
- case ADC_GAIN_CAL:
- case ADC_DC_CAL:
- if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
- conf_is_ht20(conf)))
- return true;
- break;
- }
- return false;
-}
-
static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
{
int i;
@@ -541,7 +522,6 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
REG_WRITE(ah, regList[i][0], regList[i][1]);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
@@ -567,11 +547,6 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
AR5416_EEP_TXGAIN_HIGH_POWER)
return;
- if (AR_SREV_9285_11(ah)) {
- REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
- udelay(10);
- }
-
for (i = 0; i < ARRAY_SIZE(regList); i++)
regList[i][1] = REG_READ(ah, regList[i][0]);
@@ -651,10 +626,6 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
REG_WRITE(ah, regList[i][0], regList[i][1]);
REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
-
- if (AR_SREV_9285_11(ah))
- REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
-
}
static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
@@ -664,7 +635,7 @@ static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
ar9271_hw_pa_cal(ah, is_reset);
else
ah->pacal_info.skipcount--;
- } else if (AR_SREV_9285_11_OR_LATER(ah)) {
+ } else if (AR_SREV_9285_12_OR_LATER(ah)) {
if (is_reset || !ah->pacal_info.skipcount)
ar9285_hw_pa_cal(ah, is_reset);
else
@@ -841,8 +812,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
if (!ar9285_hw_clc(ah, chan))
return false;
} else {
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- if (!AR_SREV_9287_10_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
+ if (!AR_SREV_9287_11_OR_LATER(ah))
REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
AR_PHY_ADC_CTL_OFF_PWDADC);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
@@ -864,8 +835,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
return false;
}
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- if (!AR_SREV_9287_10_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
+ if (!AR_SREV_9287_11_OR_LATER(ah))
REG_SET_BIT(ah, AR_PHY_ADC_CTL,
AR_PHY_ADC_CTL_OFF_PWDADC);
REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
@@ -886,24 +857,28 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
/* Enable IQ, ADC Gain and ADC DC offset CALs */
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
- if (ar9002_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
+ ah->supp_cals = IQ_MISMATCH_CAL;
+
+ if (AR_SREV_9160_10_OR_LATER(ah) &&
+ !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) {
+ ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
+
+
INIT_CAL(&ah->adcgain_caldata);
INSERT_CAL(ah, &ah->adcgain_caldata);
ath_print(common, ATH_DBG_CALIBRATE,
"enabling ADC Gain Calibration.\n");
- }
- if (ar9002_hw_iscal_supported(ah, ADC_DC_CAL)) {
+
INIT_CAL(&ah->adcdc_caldata);
INSERT_CAL(ah, &ah->adcdc_caldata);
ath_print(common, ATH_DBG_CALIBRATE,
"enabling ADC DC Calibration.\n");
}
- if (ar9002_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
- INIT_CAL(&ah->iq_caldata);
- INSERT_CAL(ah, &ah->iq_caldata);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling IQ Calibration.\n");
- }
+
+ INIT_CAL(&ah->iq_caldata);
+ INSERT_CAL(ah, &ah->iq_caldata);
+ ath_print(common, ATH_DBG_CALIBRATE,
+ "enabling IQ Calibration.\n");
ah->cal_list_curr = ah->cal_list;
@@ -959,13 +934,6 @@ static const struct ath9k_percal_data adc_dc_cal_single_sample = {
ar9002_hw_adc_dccal_collect,
ar9002_hw_adc_dccal_calibrate
};
-static const struct ath9k_percal_data adc_init_dc_cal = {
- ADC_DC_INIT_CAL,
- MIN_CAL_SAMPLES,
- INIT_LOG_COUNT,
- ar9002_hw_adc_dccal_collect,
- ar9002_hw_adc_dccal_calibrate
-};
static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
{
@@ -976,22 +944,18 @@ static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
}
if (AR_SREV_9160_10_OR_LATER(ah)) {
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
ah->iq_caldata.calData = &iq_cal_single_sample;
ah->adcgain_caldata.calData =
&adc_gain_cal_single_sample;
ah->adcdc_caldata.calData =
&adc_dc_cal_single_sample;
- ah->adcdc_calinitdata.calData =
- &adc_init_dc_cal;
} else {
ah->iq_caldata.calData = &iq_cal_multi_sample;
ah->adcgain_caldata.calData =
&adc_gain_cal_multi_sample;
ah->adcdc_caldata.calData =
&adc_dc_cal_multi_sample;
- ah->adcdc_calinitdata.calData =
- &adc_init_dc_cal;
}
ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
}
@@ -1005,7 +969,6 @@ void ar9002_hw_attach_calib_ops(struct ath_hw *ah)
priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
priv_ops->init_cal = ar9002_hw_init_cal;
priv_ops->setup_calibration = ar9002_hw_setup_calibration;
- priv_ops->iscal_supported = ar9002_hw_iscal_supported;
ops->calibrate = ar9002_hw_calibrate;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 303c63da5ea3..a0471f2e1c7a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -371,7 +371,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
udelay(1000);
@@ -468,7 +467,6 @@ static int ar9002_hw_get_radiorev(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
@@ -569,14 +567,57 @@ void ar9002_hw_attach_ops(struct ath_hw *ah)
ops->config_pci_powersave = ar9002_hw_configpcipowersave;
ar5008_hw_attach_phy_ops(ah);
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah))
ar9002_hw_attach_phy_ops(ah);
ar9002_hw_attach_calib_ops(ah);
ar9002_hw_attach_mac_ops(ah);
+}
+
+void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+ u32 modesIndex;
+ int i;
+
+ switch (chan->chanmode) {
+ case CHANNEL_A:
+ case CHANNEL_A_HT20:
+ modesIndex = 1;
+ break;
+ case CHANNEL_A_HT40PLUS:
+ case CHANNEL_A_HT40MINUS:
+ modesIndex = 2;
+ break;
+ case CHANNEL_G:
+ case CHANNEL_G_HT20:
+ case CHANNEL_B:
+ modesIndex = 4;
+ break;
+ case CHANNEL_G_HT40PLUS:
+ case CHANNEL_G_HT40MINUS:
+ modesIndex = 3;
+ break;
+
+ default:
+ return;
+ }
+
+ ENABLE_REGWRITE_BUFFER(ah);
- if (modparam_force_new_ani)
- ath9k_hw_attach_ani_ops_new(ah);
- else
- ath9k_hw_attach_ani_ops_old(ah);
+ for (i = 0; i < ah->iniModes_9271_ANI_reg.ia_rows; i++) {
+ u32 reg = INI_RA(&ah->iniModes_9271_ANI_reg, i, 0);
+ u32 val = INI_RA(&ah->iniModes_9271_ANI_reg, i, modesIndex);
+ u32 val_orig;
+
+ if (reg == AR_PHY_CCK_DETECT) {
+ val_orig = REG_READ(ah, reg);
+ val &= AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
+ val_orig &= ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
+
+ REG_WRITE(ah, reg, val|val_orig);
+ } else
+ REG_WRITE(ah, reg, val);
+ }
+
+ REGWRITE_BUFFER_FLUSH(ah);
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index adbf031fbc5a..c00cdc67b55b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -415,7 +415,6 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
static void ar9002_olc_init(struct ath_hw *ah)
@@ -530,3 +529,38 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
ar9002_hw_set_nf_limits(ah);
}
+
+void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
+{
+ u32 regval;
+
+ regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
+ antconf->main_lna_conf = (regval & AR_PHY_9285_ANT_DIV_MAIN_LNACONF) >>
+ AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S;
+ antconf->alt_lna_conf = (regval & AR_PHY_9285_ANT_DIV_ALT_LNACONF) >>
+ 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;
+}
+EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_get);
+
+void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
+{
+ u32 regval;
+
+ regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
+ regval &= ~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF |
+ AR_PHY_9285_ANT_DIV_ALT_LNACONF |
+ AR_PHY_9285_FAST_DIV_BIAS);
+ regval |= ((antconf->main_lna_conf << AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S)
+ & AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
+ regval |= ((antconf->alt_lna_conf << AR_PHY_9285_ANT_DIV_ALT_LNACONF_S)
+ & AR_PHY_9285_ANT_DIV_ALT_LNACONF);
+ regval |= ((antconf->fast_div_bias << AR_PHY_9285_FAST_DIV_BIAS_S)
+ & AR_PHY_9285_FAST_DIV_BIAS);
+
+ REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
+}
+EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_set);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
index c5151a4dd10b..37663dbbcf57 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -302,6 +302,8 @@
#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
+#define AR_PHY_9285_FAST_DIV_BIAS 0x00007E00
+#define AR_PHY_9285_FAST_DIV_BIAS_S 9
#define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000
#define AR_PHY_9285_ANT_DIV_CTL 0x01000000
#define AR_PHY_9285_ANT_DIV_CTL_S 24
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h
deleted file mode 100644
index d3375fc4ce8b..000000000000
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h
+++ /dev/null
@@ -1,1784 +0,0 @@
-/*
- * Copyright (c) 2010 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef INITVALS_9003_2P0_H
-#define INITVALS_9003_2P0_H
-
-/* AR9003 2.0 */
-
-static const u32 ar9300_2p0_radio_postamble[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
- {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
- {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
- {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
- {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
- {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-};
-
-static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][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, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
- {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
- {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
- {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
- {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
- {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
- {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
- {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
- {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-};
-
-static const u32 ar9300Modes_fast_clock_2p0[][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 ar9300_2p0_radio_core[][2] = {
- /* Addr allmodes */
- {0x00016000, 0x36db6db6},
- {0x00016004, 0x6db6db40},
- {0x00016008, 0x73f00000},
- {0x0001600c, 0x00000000},
- {0x00016040, 0x7f80fff8},
- {0x0001604c, 0x76d005b5},
- {0x00016050, 0x556cf031},
- {0x00016054, 0x13449440},
- {0x00016058, 0x0c51c92c},
- {0x0001605c, 0x3db7fffc},
- {0x00016060, 0xfffffffc},
- {0x00016064, 0x000f0278},
- {0x0001606c, 0x6db60000},
- {0x00016080, 0x00000000},
- {0x00016084, 0x0e48048c},
- {0x00016088, 0x54214514},
- {0x0001608c, 0x119f481e},
- {0x00016090, 0x24926490},
- {0x00016098, 0xd2888888},
- {0x000160a0, 0x0a108ffe},
- {0x000160a4, 0x812fc370},
- {0x000160a8, 0x423c8000},
- {0x000160b4, 0x92480080},
- {0x000160c0, 0x00adb6d0},
- {0x000160c4, 0x6db6db60},
- {0x000160c8, 0x6db6db6c},
- {0x000160cc, 0x01e6c000},
- {0x00016100, 0x3fffbe01},
- {0x00016104, 0xfff80000},
- {0x00016108, 0x00080010},
- {0x00016144, 0x02084080},
- {0x00016148, 0x00000000},
- {0x00016280, 0x058a0001},
- {0x00016284, 0x3d840208},
- {0x00016288, 0x05a20408},
- {0x0001628c, 0x00038c07},
- {0x00016290, 0x40000004},
- {0x00016294, 0x458aa14f},
- {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},
- {0x0001644c, 0x76d005b5},
- {0x00016450, 0x556cf031},
- {0x00016454, 0x13449440},
- {0x00016458, 0x0c51c92c},
- {0x0001645c, 0x3db7fffc},
- {0x00016460, 0xfffffffc},
- {0x00016464, 0x000f0278},
- {0x0001646c, 0x6db60000},
- {0x00016500, 0x3fffbe01},
- {0x00016504, 0xfff80000},
- {0x00016508, 0x00080010},
- {0x00016544, 0x02084080},
- {0x00016548, 0x00000000},
- {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},
- {0x00016800, 0x36db6db6},
- {0x00016804, 0x6db6db40},
- {0x00016808, 0x73f00000},
- {0x0001680c, 0x00000000},
- {0x00016840, 0x7f80fff8},
- {0x0001684c, 0x76d005b5},
- {0x00016850, 0x556cf031},
- {0x00016854, 0x13449440},
- {0x00016858, 0x0c51c92c},
- {0x0001685c, 0x3db7fffc},
- {0x00016860, 0xfffffffc},
- {0x00016864, 0x000f0278},
- {0x0001686c, 0x6db60000},
- {0x00016900, 0x3fffbe01},
- {0x00016904, 0xfff80000},
- {0x00016908, 0x00080010},
- {0x00016944, 0x02084080},
- {0x00016948, 0x00000000},
- {0x00016b80, 0x00000000},
- {0x00016b84, 0x00000000},
- {0x00016b88, 0x00800700},
- {0x00016b8c, 0x00800700},
- {0x00016b90, 0x00800700},
- {0x00016b94, 0x00000000},
- {0x00016b98, 0x00000000},
- {0x00016b9c, 0x00000000},
- {0x00016ba0, 0x00000001},
- {0x00016ba4, 0x00000001},
- {0x00016ba8, 0x00000000},
- {0x00016bac, 0x00000000},
- {0x00016bb0, 0x00000000},
- {0x00016bb4, 0x00000000},
- {0x00016bb8, 0x00000000},
- {0x00016bbc, 0x00000000},
- {0x00016bc0, 0x000000a0},
- {0x00016bc4, 0x000c0000},
- {0x00016bc8, 0x14021402},
- {0x00016bcc, 0x00001402},
- {0x00016bd0, 0x00000000},
- {0x00016bd4, 0x00000000},
-};
-
-static const u32 ar9300Common_rx_gain_table_merlin_2p0[][2] = {
- /* Addr allmodes */
- {0x0000a000, 0x02000101},
- {0x0000a004, 0x02000102},
- {0x0000a008, 0x02000103},
- {0x0000a00c, 0x02000104},
- {0x0000a010, 0x02000200},
- {0x0000a014, 0x02000201},
- {0x0000a018, 0x02000202},
- {0x0000a01c, 0x02000203},
- {0x0000a020, 0x02000204},
- {0x0000a024, 0x02000205},
- {0x0000a028, 0x02000208},
- {0x0000a02c, 0x02000302},
- {0x0000a030, 0x02000303},
- {0x0000a034, 0x02000304},
- {0x0000a038, 0x02000400},
- {0x0000a03c, 0x02010300},
- {0x0000a040, 0x02010301},
- {0x0000a044, 0x02010302},
- {0x0000a048, 0x02000500},
- {0x0000a04c, 0x02010400},
- {0x0000a050, 0x02020300},
- {0x0000a054, 0x02020301},
- {0x0000a058, 0x02020302},
- {0x0000a05c, 0x02020303},
- {0x0000a060, 0x02020400},
- {0x0000a064, 0x02030300},
- {0x0000a068, 0x02030301},
- {0x0000a06c, 0x02030302},
- {0x0000a070, 0x02030303},
- {0x0000a074, 0x02030400},
- {0x0000a078, 0x02040300},
- {0x0000a07c, 0x02040301},
- {0x0000a080, 0x02040302},
- {0x0000a084, 0x02040303},
- {0x0000a088, 0x02030500},
- {0x0000a08c, 0x02040400},
- {0x0000a090, 0x02050203},
- {0x0000a094, 0x02050204},
- {0x0000a098, 0x02050205},
- {0x0000a09c, 0x02040500},
- {0x0000a0a0, 0x02050301},
- {0x0000a0a4, 0x02050302},
- {0x0000a0a8, 0x02050303},
- {0x0000a0ac, 0x02050400},
- {0x0000a0b0, 0x02050401},
- {0x0000a0b4, 0x02050402},
- {0x0000a0b8, 0x02050403},
- {0x0000a0bc, 0x02050500},
- {0x0000a0c0, 0x02050501},
- {0x0000a0c4, 0x02050502},
- {0x0000a0c8, 0x02050503},
- {0x0000a0cc, 0x02050504},
- {0x0000a0d0, 0x02050600},
- {0x0000a0d4, 0x02050601},
- {0x0000a0d8, 0x02050602},
- {0x0000a0dc, 0x02050603},
- {0x0000a0e0, 0x02050604},
- {0x0000a0e4, 0x02050700},
- {0x0000a0e8, 0x02050701},
- {0x0000a0ec, 0x02050702},
- {0x0000a0f0, 0x02050703},
- {0x0000a0f4, 0x02050704},
- {0x0000a0f8, 0x02050705},
- {0x0000a0fc, 0x02050708},
- {0x0000a100, 0x02050709},
- {0x0000a104, 0x0205070a},
- {0x0000a108, 0x0205070b},
- {0x0000a10c, 0x0205070c},
- {0x0000a110, 0x0205070d},
- {0x0000a114, 0x02050710},
- {0x0000a118, 0x02050711},
- {0x0000a11c, 0x02050712},
- {0x0000a120, 0x02050713},
- {0x0000a124, 0x02050714},
- {0x0000a128, 0x02050715},
- {0x0000a12c, 0x02050730},
- {0x0000a130, 0x02050731},
- {0x0000a134, 0x02050732},
- {0x0000a138, 0x02050733},
- {0x0000a13c, 0x02050734},
- {0x0000a140, 0x02050735},
- {0x0000a144, 0x02050750},
- {0x0000a148, 0x02050751},
- {0x0000a14c, 0x02050752},
- {0x0000a150, 0x02050753},
- {0x0000a154, 0x02050754},
- {0x0000a158, 0x02050755},
- {0x0000a15c, 0x02050770},
- {0x0000a160, 0x02050771},
- {0x0000a164, 0x02050772},
- {0x0000a168, 0x02050773},
- {0x0000a16c, 0x02050774},
- {0x0000a170, 0x02050775},
- {0x0000a174, 0x00000776},
- {0x0000a178, 0x00000776},
- {0x0000a17c, 0x00000776},
- {0x0000a180, 0x00000776},
- {0x0000a184, 0x00000776},
- {0x0000a188, 0x00000776},
- {0x0000a18c, 0x00000776},
- {0x0000a190, 0x00000776},
- {0x0000a194, 0x00000776},
- {0x0000a198, 0x00000776},
- {0x0000a19c, 0x00000776},
- {0x0000a1a0, 0x00000776},
- {0x0000a1a4, 0x00000776},
- {0x0000a1a8, 0x00000776},
- {0x0000a1ac, 0x00000776},
- {0x0000a1b0, 0x00000776},
- {0x0000a1b4, 0x00000776},
- {0x0000a1b8, 0x00000776},
- {0x0000a1bc, 0x00000776},
- {0x0000a1c0, 0x00000776},
- {0x0000a1c4, 0x00000776},
- {0x0000a1c8, 0x00000776},
- {0x0000a1cc, 0x00000776},
- {0x0000a1d0, 0x00000776},
- {0x0000a1d4, 0x00000776},
- {0x0000a1d8, 0x00000776},
- {0x0000a1dc, 0x00000776},
- {0x0000a1e0, 0x00000776},
- {0x0000a1e4, 0x00000776},
- {0x0000a1e8, 0x00000776},
- {0x0000a1ec, 0x00000776},
- {0x0000a1f0, 0x00000776},
- {0x0000a1f4, 0x00000776},
- {0x0000a1f8, 0x00000776},
- {0x0000a1fc, 0x00000776},
- {0x0000b000, 0x02000101},
- {0x0000b004, 0x02000102},
- {0x0000b008, 0x02000103},
- {0x0000b00c, 0x02000104},
- {0x0000b010, 0x02000200},
- {0x0000b014, 0x02000201},
- {0x0000b018, 0x02000202},
- {0x0000b01c, 0x02000203},
- {0x0000b020, 0x02000204},
- {0x0000b024, 0x02000205},
- {0x0000b028, 0x02000208},
- {0x0000b02c, 0x02000302},
- {0x0000b030, 0x02000303},
- {0x0000b034, 0x02000304},
- {0x0000b038, 0x02000400},
- {0x0000b03c, 0x02010300},
- {0x0000b040, 0x02010301},
- {0x0000b044, 0x02010302},
- {0x0000b048, 0x02000500},
- {0x0000b04c, 0x02010400},
- {0x0000b050, 0x02020300},
- {0x0000b054, 0x02020301},
- {0x0000b058, 0x02020302},
- {0x0000b05c, 0x02020303},
- {0x0000b060, 0x02020400},
- {0x0000b064, 0x02030300},
- {0x0000b068, 0x02030301},
- {0x0000b06c, 0x02030302},
- {0x0000b070, 0x02030303},
- {0x0000b074, 0x02030400},
- {0x0000b078, 0x02040300},
- {0x0000b07c, 0x02040301},
- {0x0000b080, 0x02040302},
- {0x0000b084, 0x02040303},
- {0x0000b088, 0x02030500},
- {0x0000b08c, 0x02040400},
- {0x0000b090, 0x02050203},
- {0x0000b094, 0x02050204},
- {0x0000b098, 0x02050205},
- {0x0000b09c, 0x02040500},
- {0x0000b0a0, 0x02050301},
- {0x0000b0a4, 0x02050302},
- {0x0000b0a8, 0x02050303},
- {0x0000b0ac, 0x02050400},
- {0x0000b0b0, 0x02050401},
- {0x0000b0b4, 0x02050402},
- {0x0000b0b8, 0x02050403},
- {0x0000b0bc, 0x02050500},
- {0x0000b0c0, 0x02050501},
- {0x0000b0c4, 0x02050502},
- {0x0000b0c8, 0x02050503},
- {0x0000b0cc, 0x02050504},
- {0x0000b0d0, 0x02050600},
- {0x0000b0d4, 0x02050601},
- {0x0000b0d8, 0x02050602},
- {0x0000b0dc, 0x02050603},
- {0x0000b0e0, 0x02050604},
- {0x0000b0e4, 0x02050700},
- {0x0000b0e8, 0x02050701},
- {0x0000b0ec, 0x02050702},
- {0x0000b0f0, 0x02050703},
- {0x0000b0f4, 0x02050704},
- {0x0000b0f8, 0x02050705},
- {0x0000b0fc, 0x02050708},
- {0x0000b100, 0x02050709},
- {0x0000b104, 0x0205070a},
- {0x0000b108, 0x0205070b},
- {0x0000b10c, 0x0205070c},
- {0x0000b110, 0x0205070d},
- {0x0000b114, 0x02050710},
- {0x0000b118, 0x02050711},
- {0x0000b11c, 0x02050712},
- {0x0000b120, 0x02050713},
- {0x0000b124, 0x02050714},
- {0x0000b128, 0x02050715},
- {0x0000b12c, 0x02050730},
- {0x0000b130, 0x02050731},
- {0x0000b134, 0x02050732},
- {0x0000b138, 0x02050733},
- {0x0000b13c, 0x02050734},
- {0x0000b140, 0x02050735},
- {0x0000b144, 0x02050750},
- {0x0000b148, 0x02050751},
- {0x0000b14c, 0x02050752},
- {0x0000b150, 0x02050753},
- {0x0000b154, 0x02050754},
- {0x0000b158, 0x02050755},
- {0x0000b15c, 0x02050770},
- {0x0000b160, 0x02050771},
- {0x0000b164, 0x02050772},
- {0x0000b168, 0x02050773},
- {0x0000b16c, 0x02050774},
- {0x0000b170, 0x02050775},
- {0x0000b174, 0x00000776},
- {0x0000b178, 0x00000776},
- {0x0000b17c, 0x00000776},
- {0x0000b180, 0x00000776},
- {0x0000b184, 0x00000776},
- {0x0000b188, 0x00000776},
- {0x0000b18c, 0x00000776},
- {0x0000b190, 0x00000776},
- {0x0000b194, 0x00000776},
- {0x0000b198, 0x00000776},
- {0x0000b19c, 0x00000776},
- {0x0000b1a0, 0x00000776},
- {0x0000b1a4, 0x00000776},
- {0x0000b1a8, 0x00000776},
- {0x0000b1ac, 0x00000776},
- {0x0000b1b0, 0x00000776},
- {0x0000b1b4, 0x00000776},
- {0x0000b1b8, 0x00000776},
- {0x0000b1bc, 0x00000776},
- {0x0000b1c0, 0x00000776},
- {0x0000b1c4, 0x00000776},
- {0x0000b1c8, 0x00000776},
- {0x0000b1cc, 0x00000776},
- {0x0000b1d0, 0x00000776},
- {0x0000b1d4, 0x00000776},
- {0x0000b1d8, 0x00000776},
- {0x0000b1dc, 0x00000776},
- {0x0000b1e0, 0x00000776},
- {0x0000b1e4, 0x00000776},
- {0x0000b1e8, 0x00000776},
- {0x0000b1ec, 0x00000776},
- {0x0000b1f0, 0x00000776},
- {0x0000b1f4, 0x00000776},
- {0x0000b1f8, 0x00000776},
- {0x0000b1fc, 0x00000776},
-};
-
-static const u32 ar9300_2p0_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 ar9300_2p0_soc_postamble[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
-};
-
-static const u32 ar9200_merlin_2p0_radio_core[][2] = {
- /* Addr allmodes */
- {0x00007800, 0x00040000},
- {0x00007804, 0xdb005012},
- {0x00007808, 0x04924914},
- {0x0000780c, 0x21084210},
- {0x00007810, 0x6d801300},
- {0x00007814, 0x0019beff},
- {0x00007818, 0x07e41000},
- {0x0000781c, 0x00392000},
- {0x00007820, 0x92592480},
- {0x00007824, 0x00040000},
- {0x00007828, 0xdb005012},
- {0x0000782c, 0x04924914},
- {0x00007830, 0x21084210},
- {0x00007834, 0x6d801300},
- {0x00007838, 0x0019beff},
- {0x0000783c, 0x07e40000},
- {0x00007840, 0x00392000},
- {0x00007844, 0x92592480},
- {0x00007848, 0x00100000},
- {0x0000784c, 0x773f0567},
- {0x00007850, 0x54214514},
- {0x00007854, 0x12035828},
- {0x00007858, 0x92592692},
- {0x0000785c, 0x00000000},
- {0x00007860, 0x56400000},
- {0x00007864, 0x0a8e370e},
- {0x00007868, 0xc0102850},
- {0x0000786c, 0x812d4000},
- {0x00007870, 0x807ec400},
- {0x00007874, 0x001b6db0},
- {0x00007878, 0x00376b63},
- {0x0000787c, 0x06db6db6},
- {0x00007880, 0x006d8000},
- {0x00007884, 0xffeffffe},
- {0x00007888, 0xffeffffe},
- {0x0000788c, 0x00010000},
- {0x00007890, 0x02060aeb},
- {0x00007894, 0x5a108000},
-};
-
-static const u32 ar9300_2p0_baseband_postamble[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
- {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
- {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
- {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, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
- {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
- {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
- {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, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
- {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, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
- {0x0000a28c, 0x00022222, 0x00022222, 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, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
- {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
- {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
- {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
- {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
- {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
- {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
- {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
- {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
-};
-
-static const u32 ar9300_2p0_baseband_core[][2] = {
- /* Addr allmodes */
- {0x00009800, 0xafe68e30},
- {0x00009804, 0xfd14e000},
- {0x00009808, 0x9c0a9f6b},
- {0x0000980c, 0x04900000},
- {0x00009814, 0x9280c00a},
- {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, 0x00000001},
- {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},
- {0x0000b8d0, 0x004b6a8e},
- {0x0000b8d4, 0x00000820},
- {0x0000b8dc, 0x00000000},
- {0x0000b8f0, 0x00000000},
- {0x0000b8f4, 0x00000000},
- {0x0000c2d0, 0x00000080},
- {0x0000c2d4, 0x00000000},
- {0x0000c2dc, 0x00000000},
- {0x0000c2e0, 0x00000000},
- {0x0000c2e4, 0x00000000},
- {0x0000c2e8, 0x00000000},
- {0x0000c2ec, 0x00000000},
- {0x0000c2f0, 0x00000000},
- {0x0000c2f4, 0x00000000},
- {0x0000c2f8, 0x00000000},
- {0x0000c408, 0x0e79e5c0},
- {0x0000c40c, 0x00820820},
- {0x0000c420, 0x00000000},
-};
-
-static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][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, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
- {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
- {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
- {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
- {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
- {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
- {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
- {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
- {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-};
-
-static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][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, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
- {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
- {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
- {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
- {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
- {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
- {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
- {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
- {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-};
-
-static const u32 ar9300Common_rx_gain_table_2p0[][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 ar9300Modes_low_ob_db_tx_gain_table_2p0[][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, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
- {0x00016048, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
- {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
- {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
- {0x00016448, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
- {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
- {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
- {0x00016848, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
- {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-};
-
-static const u32 ar9300_2p0_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, 0x98a00010},
- {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 ar9300Common_wo_xlna_rx_gain_table_2p0[][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 ar9300_2p0_soc_preamble[][2] = {
- /* Addr allmodes */
- {0x000040a4, 0x00a0c1c9},
- {0x00007008, 0x00000000},
- {0x00007020, 0x00000000},
- {0x00007034, 0x00000002},
- {0x00007038, 0x000004c2},
-};
-
-static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = {
- /* Addr allmodes */
- {0x00004040, 0x08212e5e},
- {0x00004040, 0x0008003b},
- {0x00004044, 0x00000000},
-};
-
-static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = {
- /* Addr allmodes */
- {0x00004040, 0x08253e5e},
- {0x00004040, 0x0008003b},
- {0x00004044, 0x00000000},
-};
-
-static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = {
- /* Addr allmodes */
- {0x00004040, 0x08213e5e},
- {0x00004040, 0x0008003b},
- {0x00004044, 0x00000000},
-};
-
-#endif /* INITVALS_9003_2P0_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 4674ea8c9c99..9e6edffe0bd1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -18,6 +18,11 @@
#include "hw-ops.h"
#include "ar9003_phy.h"
+enum ar9003_cal_types {
+ IQ_MISMATCH_CAL = BIT(0),
+ TEMP_COMP_CAL = BIT(1),
+};
+
static void ar9003_hw_setup_calibration(struct ath_hw *ah,
struct ath9k_cal_list *currCal)
{
@@ -50,11 +55,6 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
ath_print(common, ATH_DBG_CALIBRATE,
"starting Temperature Compensation Calibration\n");
break;
- case ADC_DC_INIT_CAL:
- case ADC_GAIN_CAL:
- case ADC_DC_CAL:
- /* Not yet */
- break;
}
}
@@ -314,27 +314,6 @@ static const struct ath9k_percal_data iq_cal_single_sample = {
static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
{
ah->iq_caldata.calData = &iq_cal_single_sample;
- ah->supp_cals = IQ_MISMATCH_CAL;
-}
-
-static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
- enum ath9k_cal_types calType)
-{
- switch (calType & ah->supp_cals) {
- case IQ_MISMATCH_CAL:
- /*
- * XXX: Run IQ Mismatch for non-CCK only
- * Note that CHANNEL_B is never set though.
- */
- return true;
- case ADC_GAIN_CAL:
- case ADC_DC_CAL:
- return false;
- case TEMP_COMP_CAL:
- return true;
- }
-
- return false;
}
/*
@@ -773,15 +752,16 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
/* Initialize list pointers */
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+ ah->supp_cals = IQ_MISMATCH_CAL;
- if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+ if (ah->supp_cals & IQ_MISMATCH_CAL) {
INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata);
ath_print(common, ATH_DBG_CALIBRATE,
"enabling IQ Calibration.\n");
}
- if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) {
+ if (ah->supp_cals & TEMP_COMP_CAL) {
INIT_CAL(&ah->tempCompCalData);
INSERT_CAL(ah, &ah->tempCompCalData);
ath_print(common, ATH_DBG_CALIBRATE,
@@ -808,7 +788,6 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
priv_ops->init_cal = ar9003_hw_init_cal;
priv_ops->setup_calibration = ar9003_hw_setup_calibration;
- priv_ops->iscal_supported = ar9003_hw_iscal_supported;
ops->calibrate = ar9003_hw_calibrate;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 057fb69ddf7f..c4182359bee4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -968,7 +968,7 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
}
static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
- enum ieee80211_band freq_band)
+ enum ath9k_hal_freq_band freq_band)
{
return 1;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 064168909108..c2a057156bfa 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -16,7 +16,6 @@
#include "hw.h"
#include "ar9003_mac.h"
-#include "ar9003_2p0_initvals.h"
#include "ar9003_2p2_initvals.h"
/* General hardware code for the AR9003 hadware family */
@@ -32,79 +31,12 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
return false;
}
-/* AR9003 2.0 */
-static void ar9003_2p0_hw_init_mode_regs(struct ath_hw *ah)
-{
- /* mac */
- INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
- ar9300_2p0_mac_core,
- ARRAY_SIZE(ar9300_2p0_mac_core), 2);
- INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
- ar9300_2p0_mac_postamble,
- ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
-
- /* bb */
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
- ar9300_2p0_baseband_core,
- ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
- ar9300_2p0_baseband_postamble,
- ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
-
- /* radio */
- INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
- ar9300_2p0_radio_core,
- ARRAY_SIZE(ar9300_2p0_radio_core), 2);
- INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
- ar9300_2p0_radio_postamble,
- ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
-
- /* soc */
- INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
- ar9300_2p0_soc_preamble,
- ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
- INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
- ar9300_2p0_soc_postamble,
- ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
-
- /* rx/tx gain */
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_rx_gain_table_2p0,
- ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
- ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
- 5);
-
- /* Load PCIE SERDES settings from INI */
-
- /* Awake Setting */
-
- INIT_INI_ARRAY(&ah->iniPcieSerdes,
- ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
- ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
- 2);
-
- /* Sleep Setting */
-
- INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
- ar9300PciePhy_clkreq_enable_L1_2p0,
- ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
- 2);
-
- /* Fast clock modal settings */
- INIT_INI_ARRAY(&ah->iniModesAdditional,
- ar9300Modes_fast_clock_2p0,
- ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
- 3);
-}
-
-/* AR9003 2.2 */
-static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
+/*
+ * The AR9003 family uses a new INI format (pre, core, post
+ * arrays per subsystem). This provides support for the
+ * AR9003 2.2 chipsets.
+ */
+static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
@@ -174,57 +106,27 @@ static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
3);
}
-/*
- * The AR9003 family uses a new INI format (pre, core, post
- * arrays per subsystem).
- */
-static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
-{
- if (AR_SREV_9300_20(ah))
- ar9003_2p0_hw_init_mode_regs(ah);
- else
- ar9003_2p2_hw_init_mode_regs(ah);
-}
-
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_9300_20(ah))
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
- ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
- 5);
- else
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
- 5);
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
+ 5);
break;
case 1:
- if (AR_SREV_9300_20(ah))
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_high_ob_db_tx_gain_table_2p0,
- ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
- 5);
- else
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_high_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
- 5);
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_high_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
+ 5);
break;
case 2:
- if (AR_SREV_9300_20(ah))
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_low_ob_db_tx_gain_table_2p0,
- ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
- 5);
- else
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_low_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
- 5);
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_low_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
+ 5);
break;
}
}
@@ -234,28 +136,16 @@ 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_9300_20(ah))
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_rx_gain_table_2p0,
- ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
- 2);
- else
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_rx_gain_table_2p2,
- ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
- 2);
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9300Common_rx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
+ 2);
break;
case 1:
- if (AR_SREV_9300_20(ah))
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_wo_xlna_rx_gain_table_2p0,
- ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
- 2);
- else
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_wo_xlna_rx_gain_table_2p2,
- ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
- 2);
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9300Common_wo_xlna_rx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
+ 2);
break;
}
}
@@ -333,6 +223,4 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
ar9003_hw_attach_phy_ops(ah);
ar9003_hw_attach_calib_ops(ah);
ar9003_hw_attach_mac_ops(ah);
-
- ath9k_hw_attach_ani_ops_new(ah);
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 5b995bee70ae..3b424ca1ba84 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -185,7 +185,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
ath_print(common, ATH_DBG_INTERRUPT,
"AR_INTR_SYNC_LOCAL_TIMEOUT\n");
- REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
+ REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
}
@@ -616,7 +616,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
} else if (rxsp->status11 & AR_MichaelErr) {
rxs->rs_status |= ATH9K_RXERR_MIC;
- }
+ } else if (rxsp->status11 & AR_KeyMiss)
+ rxs->rs_status |= ATH9K_RXERR_DECRYPT;
}
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index a491854fa38a..669b777729b3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -747,9 +747,9 @@ static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
static bool ar9003_hw_ani_control(struct ath_hw *ah,
enum ath9k_ani_cmd cmd, int param)
{
- struct ar5416AniState *aniState = ah->curani;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
+ struct ar5416AniState *aniState = &chan->ani;
s32 value, value2;
switch (cmd & ah->ani_function) {
@@ -1005,15 +1005,13 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
ath_print(common, ATH_DBG_ANI,
"ANI parameters: SI=%d, ofdmWS=%s FS=%d "
- "MRCcck=%s listenTime=%d CC=%d listen=%d "
+ "MRCcck=%s listenTime=%d "
"ofdmErrs=%d cckErrs=%d\n",
aniState->spurImmunityLevel,
!aniState->ofdmWeakSigDetectOff ? "on" : "off",
aniState->firstepLevel,
!aniState->mrcCCKOff ? "on" : "off",
aniState->listenTime,
- aniState->cycleCount,
- aniState->listenTime,
aniState->ofdmPhyErrCount,
aniState->cckPhyErrCount);
return true;
@@ -1067,12 +1065,9 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
struct ath9k_ani_default *iniDef;
- int index;
u32 val;
- index = ath9k_hw_get_ani_channel_idx(ah, chan);
- aniState = &ah->ani[index];
- ah->curani = aniState;
+ aniState = &ah->curchan->ani;
iniDef = &aniState->iniDef;
ath_print(common, ATH_DBG_ANI,
@@ -1116,8 +1111,6 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
-
- aniState->cycleCount = 0;
}
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
@@ -1232,7 +1225,7 @@ void ar9003_hw_bb_watchdog_read(struct ath_hw *ah)
void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status;
+ u32 status;
if (likely(!(common->debug_mask & ATH_DBG_RESET)))
return;
@@ -1261,11 +1254,12 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
"** BB mode: BB_gen_controls=0x%08x **\n",
REG_READ(ah, AR_PHY_GEN_CTRL));
- if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt))
+#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles)
+ if (common->cc_survey.cycles)
ath_print(common, ATH_DBG_RESET,
"** BB busy times: rx_clear=%d%%, "
"rx_frame=%d%%, tx_frame=%d%% **\n",
- rxc_pcnt, rxf_pcnt, txf_pcnt);
+ PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
ath_print(common, ATH_DBG_RESET,
"==== BB update: done ====\n\n");
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 07f26ee7a723..973c919fdd27 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -239,13 +239,11 @@ struct ath_buf {
struct sk_buff *bf_mpdu; /* enclosing frame structure */
void *bf_desc; /* virtual addr of desc */
dma_addr_t bf_daddr; /* physical addr of desc */
- dma_addr_t bf_buf_addr; /* physical addr of data buffer */
+ dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */
bool bf_stale;
- bool bf_isnullfunc;
bool bf_tx_aborted;
u16 bf_flags;
struct ath_buf_state bf_state;
- dma_addr_t bf_dmacontext;
struct ath_wiphy *aphy;
};
@@ -254,7 +252,7 @@ struct ath_atx_tid {
struct list_head buf_q;
struct ath_node *an;
struct ath_atx_ac *ac;
- struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
+ unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
u16 seq_start;
u16 seq_next;
u16 baw_size;
@@ -345,12 +343,10 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
void ath_tx_tasklet(struct ath_softc *sc);
void ath_tx_edma_tasklet(struct ath_softc *sc);
void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
-void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
- u16 tid, u16 *ssn);
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn);
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 ath9k_enable_ps(struct ath_softc *sc);
/********/
/* VIFs */
@@ -423,6 +419,7 @@ int ath_beaconq_config(struct ath_softc *sc);
#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */
#define ATH_ANI_POLLINTERVAL_OLD 100 /* 100 ms */
#define ATH_ANI_POLLINTERVAL_NEW 1000 /* 1000 ms */
+#define ATH_LONG_CALINTERVAL_INT 1000 /* 1000 ms */
#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
@@ -436,14 +433,6 @@ void ath_ani_calibrate(unsigned long data);
/* BTCOEX */
/**********/
-/* 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
-};
-
struct ath_btcoex {
bool hw_timer_enabled;
spinlock_t btcoex_lock;
@@ -488,6 +477,60 @@ struct ath_led {
void ath_init_leds(struct ath_softc *sc);
void ath_deinit_leds(struct ath_softc *sc);
+/* Antenna diversity/combining */
+#define ATH_ANT_RX_CURRENT_SHIFT 4
+#define ATH_ANT_RX_MAIN_SHIFT 2
+#define ATH_ANT_RX_MASK 0x3
+
+#define ATH_ANT_DIV_COMB_SHORT_SCAN_INTR 50
+#define ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT 0x100
+#define ATH_ANT_DIV_COMB_MAX_PKTCOUNT 0x200
+#define ATH_ANT_DIV_COMB_INIT_COUNT 95
+#define ATH_ANT_DIV_COMB_MAX_COUNT 100
+#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
+#define ATH_ANT_DIV_COMB_LNA1_DELTA_LOW 2
+
+enum ath9k_ant_div_comb_lna_conf {
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2,
+ ATH_ANT_DIV_COMB_LNA2,
+ ATH_ANT_DIV_COMB_LNA1,
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2,
+};
+
+struct ath_ant_comb {
+ u16 count;
+ u16 total_pkt_count;
+ bool scan;
+ bool scan_not_start;
+ int main_total_rssi;
+ int alt_total_rssi;
+ int alt_recv_cnt;
+ int main_recv_cnt;
+ int rssi_lna1;
+ int rssi_lna2;
+ int rssi_add;
+ int rssi_sub;
+ int rssi_first;
+ int rssi_second;
+ int rssi_third;
+ bool alt_good;
+ int quick_scan_cnt;
+ int main_conf;
+ enum ath9k_ant_div_comb_lna_conf first_quick_scan_conf;
+ enum ath9k_ant_div_comb_lna_conf second_quick_scan_conf;
+ int first_bias;
+ int second_bias;
+ bool first_ratio;
+ bool second_ratio;
+ unsigned long scan_start_time;
+};
+
/********************/
/* Main driver core */
/********************/
@@ -516,7 +559,6 @@ void ath_deinit_leds(struct ath_softc *sc);
#define SC_OP_RXFLUSH BIT(7)
#define SC_OP_LED_ASSOCIATED BIT(8)
#define SC_OP_LED_ON BIT(9)
-#define SC_OP_SCANNING BIT(10)
#define SC_OP_TSF_RESET BIT(11)
#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
#define SC_OP_BT_SCAN BIT(13)
@@ -528,8 +570,6 @@ void ath_deinit_leds(struct ath_softc *sc);
#define PS_WAIT_FOR_PSPOLL_DATA BIT(2)
#define PS_WAIT_FOR_TX_ACK BIT(3)
#define PS_BEACON_SYNC BIT(4)
-#define PS_NULLFUNC_COMPLETED BIT(5)
-#define PS_ENABLED BIT(6)
struct ath_wiphy;
struct ath_rate_table;
@@ -552,6 +592,8 @@ struct ath_softc {
struct delayed_work wiphy_work;
unsigned long wiphy_scheduler_int;
int wiphy_scheduler_index;
+ struct survey_info *cur_survey;
+ struct survey_info survey[ATH9K_NUM_CHANNELS];
struct tasklet_struct intr_tq;
struct tasklet_struct bcon_tasklet;
@@ -580,8 +622,6 @@ struct ath_softc {
struct ath_rx rx;
struct ath_tx tx;
struct ath_beacon beacon;
- const struct ath_rate_table *cur_rate_table;
- enum wireless_mode cur_rate_mode;
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ath_led radio_led;
@@ -604,6 +644,8 @@ struct ath_softc {
struct ath_btcoex btcoex;
struct ath_descdma txsdma;
+
+ struct ath_ant_comb ant_comb;
};
struct ath_wiphy {
@@ -670,7 +712,7 @@ static inline void ath_ahb_exit(void) {};
void ath9k_ps_wakeup(struct ath_softc *sc);
void ath9k_ps_restore(struct ath_softc *sc);
-void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
int ath9k_wiphy_add(struct ath_softc *sc);
int ath9k_wiphy_del(struct ath_wiphy *aphy);
void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 4d4b22d52dfd..4ed010d4ef96 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -136,9 +136,10 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
bf = avp->av_bcbuf;
skb = bf->bf_mpdu;
if (skb) {
- dma_unmap_single(sc->dev, bf->bf_dmacontext,
+ dma_unmap_single(sc->dev, bf->bf_buf_addr,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
+ bf->bf_buf_addr = 0;
}
/* Get a new beacon from mac80211 */
@@ -162,12 +163,12 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
}
- bf->bf_buf_addr = bf->bf_dmacontext =
- dma_map_single(sc->dev, skb->data,
- skb->len, DMA_TO_DEVICE);
+ bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
+ bf->bf_buf_addr = 0;
ath_print(common, ATH_DBG_FATAL,
"dma_mapping_error on beaconing\n");
return NULL;
@@ -252,10 +253,11 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
skb = bf->bf_mpdu;
- dma_unmap_single(sc->dev, bf->bf_dmacontext,
+ dma_unmap_single(sc->dev, bf->bf_buf_addr,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
+ bf->bf_buf_addr = 0;
}
/* NB: the beacon data buffer must be 32-bit aligned. */
@@ -296,12 +298,12 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
avp->tsf_adjust = cpu_to_le64(0);
bf->bf_mpdu = skb;
- bf->bf_buf_addr = bf->bf_dmacontext =
- dma_map_single(sc->dev, skb->data,
- skb->len, DMA_TO_DEVICE);
+ bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
+ bf->bf_buf_addr = 0;
ath_print(common, ATH_DBG_FATAL,
"dma_mapping_error on beacon alloc\n");
return -ENOMEM;
@@ -324,10 +326,11 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = bf->bf_mpdu;
- dma_unmap_single(sc->dev, bf->bf_dmacontext,
+ dma_unmap_single(sc->dev, bf->bf_buf_addr,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
+ bf->bf_buf_addr = 0;
}
list_add_tail(&bf->list, &sc->beacon.bbuf);
@@ -359,11 +362,12 @@ void ath_beacon_tasklet(unsigned long data)
sc->beacon.bmisscnt++;
if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
- ath_print(common, ATH_DBG_BEACON,
+ ath_print(common, ATH_DBG_BSTUCK,
"missed %u consecutive beacons\n",
sc->beacon.bmisscnt);
+ ath9k_hw_bstuck_nfcal(ah);
} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
- ath_print(common, ATH_DBG_BEACON,
+ ath_print(common, ATH_DBG_BSTUCK,
"beacon is officially stuck\n");
sc->sc_flags |= SC_OP_TSF_RESET;
ath_reset(sc, false);
@@ -373,7 +377,7 @@ void ath_beacon_tasklet(unsigned long data)
}
if (sc->beacon.bmisscnt != 0) {
- ath_print(common, ATH_DBG_BEACON,
+ ath_print(common, ATH_DBG_BSTUCK,
"resume beacon xmit after %u misses\n",
sc->beacon.bmisscnt);
sc->beacon.bmisscnt = 0;
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index fb4ac15f3b93..6a92e57fddf0 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -168,6 +168,7 @@ 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;
+ u32 val;
/*
* Program coex mode and weight registers to
@@ -177,6 +178,12 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
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_9271(ah)) {
+ val = REG_READ(ah, 0x50040);
+ val &= 0xFFFFFEFF;
+ REG_WRITE(ah, 0x50040, val);
+ }
+
REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 45208690c0ec..6d509484b5f6 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -19,8 +19,7 @@
/* Common calibration code */
-/* We can tune this as we go by monitoring really low values */
-#define ATH9K_NF_TOO_LOW -60
+#define ATH9K_NF_TOO_HIGH -60
static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
{
@@ -45,11 +44,39 @@ static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
return nfval;
}
-static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
+static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ struct ath_nf_limits *limit;
+
+ if (!chan || IS_CHAN_2GHZ(chan))
+ limit = &ah->nf_2g;
+ else
+ limit = &ah->nf_5g;
+
+ return limit;
+}
+
+static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ return ath9k_hw_get_nf_limits(ah, chan)->nominal;
+}
+
+
+static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
+ struct ath9k_hw_cal_data *cal,
int16_t *nfarray)
{
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath_nf_limits *limit;
+ struct ath9k_nfcal_hist *h;
+ bool high_nf_mid = false;
int i;
+ h = cal->nfCalHist;
+ limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
+
for (i = 0; i < NUM_NF_READINGS; i++) {
h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
@@ -63,7 +90,39 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
h[i].privNF =
ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
}
+
+ if (!h[i].privNF)
+ continue;
+
+ if (h[i].privNF > limit->max) {
+ high_nf_mid = true;
+
+ ath_print(common, ATH_DBG_CALIBRATE,
+ "NFmid[%d] (%d) > MAX (%d), %s\n",
+ i, h[i].privNF, limit->max,
+ (cal->nfcal_interference ?
+ "not corrected (due to interference)" :
+ "correcting to MAX"));
+
+ /*
+ * Normally we limit the average noise floor by the
+ * hardware specific maximum here. However if we have
+ * encountered stuck beacons because of interference,
+ * we bypass this limit here in order to better deal
+ * with our environment.
+ */
+ if (!cal->nfcal_interference)
+ h[i].privNF = limit->max;
+ }
}
+
+ /*
+ * If the noise floor seems normal for all chains, assume that
+ * there is no significant interference in the environment anymore.
+ * Re-enable the enforcement of the NF maximum again.
+ */
+ if (!high_nf_mid)
+ cal->nfcal_interference = false;
}
static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah,
@@ -104,19 +163,6 @@ void ath9k_hw_reset_calibration(struct ath_hw *ah,
ah->cal_samples = 0;
}
-static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
- struct ath9k_channel *chan)
-{
- struct ath_nf_limits *limit;
-
- if (!chan || IS_CHAN_2GHZ(chan))
- limit = &ah->nf_2g;
- else
- limit = &ah->nf_5g;
-
- return limit->nominal;
-}
-
/* This is done for the currently configured channel */
bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
{
@@ -140,7 +186,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
return true;
}
- if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
+ if (!(ah->supp_cals & currCal->calData->calType))
return true;
ath_print(common, ATH_DBG_CALIBRATE,
@@ -254,7 +300,6 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
}
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
@@ -277,10 +322,10 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
"NF calibrated [%s] [chain %d] is %d\n",
(i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
- if (nf[i] > limit->max) {
+ if (nf[i] > ATH9K_NF_TOO_HIGH) {
ath_print(common, ATH_DBG_CALIBRATE,
"NF[%d] (%d) > MAX (%d), correcting to MAX",
- i, nf[i], limit->max);
+ i, nf[i], ATH9K_NF_TOO_HIGH);
nf[i] = limit->max;
} else if (nf[i] < limit->min) {
ath_print(common, ATH_DBG_CALIBRATE,
@@ -300,34 +345,34 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
struct ieee80211_channel *c = chan->chan;
struct ath9k_hw_cal_data *caldata = ah->caldata;
- if (!caldata)
- return false;
-
chan->channelFlags &= (~CHANNEL_CW_INT);
if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
ath_print(common, ATH_DBG_CALIBRATE,
"NF did not complete in calibration window\n");
- nf = 0;
- caldata->rawNoiseFloor = nf;
return false;
- } else {
- ath9k_hw_do_getnf(ah, nfarray);
- ath9k_hw_nf_sanitize(ah, nfarray);
- nf = nfarray[0];
- if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
- && nf > nfThresh) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "noise floor failed detected; "
- "detected %d, threshold %d\n",
- nf, nfThresh);
- chan->channelFlags |= CHANNEL_CW_INT;
- }
+ }
+
+ ath9k_hw_do_getnf(ah, nfarray);
+ ath9k_hw_nf_sanitize(ah, nfarray);
+ nf = nfarray[0];
+ if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
+ && nf > nfThresh) {
+ ath_print(common, ATH_DBG_CALIBRATE,
+ "noise floor failed detected; "
+ "detected %d, threshold %d\n",
+ nf, nfThresh);
+ chan->channelFlags |= CHANNEL_CW_INT;
+ }
+
+ if (!caldata) {
+ chan->noisefloor = nf;
+ return false;
}
h = caldata->nfCalHist;
caldata->nfcal_pending = false;
- ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
- caldata->rawNoiseFloor = h[0].privNF;
+ ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
+ chan->noisefloor = h[0].privNF;
return true;
}
@@ -355,9 +400,34 @@ 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->caldata || !ah->caldata->rawNoiseFloor)
+ if (!ah->curchan || !ah->curchan->noisefloor)
return ath9k_hw_get_default_nf(ah, chan);
- return ah->caldata->rawNoiseFloor;
+ return ah->curchan->noisefloor;
}
EXPORT_SYMBOL(ath9k_hw_getchan_noise);
+
+void ath9k_hw_bstuck_nfcal(struct ath_hw *ah)
+{
+ struct ath9k_hw_cal_data *caldata = ah->caldata;
+
+ if (unlikely(!caldata))
+ return;
+
+ /*
+ * If beacons are stuck, the most likely cause is interference.
+ * Triggering a noise floor calibration at this point helps the
+ * hardware adapt to a noisy environment much faster.
+ * To ensure that we recover from stuck beacons quickly, let
+ * the baseband update the internal NF value itself, similar to
+ * what is being done after a full reset.
+ */
+ if (!caldata->nfcal_pending)
+ ath9k_hw_start_nfcal(ah, true);
+ else if (!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF))
+ ath9k_hw_getnf(ah, ah->curchan);
+
+ caldata->nfcal_interference = true;
+}
+EXPORT_SYMBOL(ath9k_hw_bstuck_nfcal);
+
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 0a304b3eeeb6..b8973eb8d858 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -58,14 +58,6 @@ struct ar5416IniArray {
} \
} while (0)
-enum ath9k_cal_types {
- ADC_DC_INIT_CAL = 0x1,
- ADC_GAIN_CAL = 0x2,
- ADC_DC_CAL = 0x4,
- IQ_MISMATCH_CAL = 0x8,
- TEMP_COMP_CAL = 0x10,
-};
-
enum ath9k_cal_state {
CAL_INACTIVE,
CAL_WAITING,
@@ -80,7 +72,7 @@ enum ath9k_cal_state {
#define PER_MAX_LOG_COUNT 10
struct ath9k_percal_data {
- enum ath9k_cal_types calType;
+ u32 calType;
u32 calNumSamples;
u32 calCountMax;
void (*calCollect) (struct ath_hw *);
@@ -113,6 +105,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
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 c86f7d3593ab..f43a2d98421c 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -46,12 +46,17 @@ int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
if (tx_info->control.hw_key) {
- if (tx_info->control.hw_key->alg == ALG_WEP)
+ switch (tx_info->control.hw_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
return ATH9K_KEY_TYPE_WEP;
- else if (tx_info->control.hw_key->alg == ALG_TKIP)
+ case WLAN_CIPHER_SUITE_TKIP:
return ATH9K_KEY_TYPE_TKIP;
- else if (tx_info->control.hw_key->alg == ALG_CCMP)
+ case WLAN_CIPHER_SUITE_CCMP:
return ATH9K_KEY_TYPE_AES;
+ default:
+ break;
+ }
}
return ATH9K_KEY_TYPE_CLEAR;
@@ -143,276 +148,49 @@ struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
}
EXPORT_SYMBOL(ath9k_cmn_get_curchannel);
-static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
- struct ath9k_keyval *hk, const u8 *addr,
- bool authenticator)
-{
- struct ath_hw *ah = common->ah;
- const u8 *key_rxmic;
- const u8 *key_txmic;
-
- key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
- key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
-
- if (addr == NULL) {
- /*
- * Group key installation - only two key cache entries are used
- * regardless of splitmic capability since group key is only
- * used either for TX or RX.
- */
- if (authenticator) {
- memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
- memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
- } else {
- memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
- memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
- }
- return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
- }
- if (!common->splitmic) {
- /* TX and RX keys share the same key cache entry. */
- memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
- memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
- return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
- }
-
- /* Separate key cache entries for TX and RX */
-
- /* TX key goes at first index, RX key at +32. */
- memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
- if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) {
- /* TX MIC entry failed. No need to proceed further */
- ath_print(common, ATH_DBG_FATAL,
- "Setting TX MIC Key Failed\n");
- return 0;
- }
-
- memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
- /* XXX delete tx key on failure? */
- return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr);
-}
-
-static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
-{
- int i;
-
- for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
- if (test_bit(i, common->keymap) ||
- test_bit(i + 64, common->keymap))
- continue; /* At least one part of TKIP key allocated */
- if (common->splitmic &&
- (test_bit(i + 32, common->keymap) ||
- test_bit(i + 64 + 32, common->keymap)))
- continue; /* At least one part of TKIP key allocated */
-
- /* Found a free slot for a TKIP key */
- return i;
- }
- return -1;
-}
-
-static int ath_reserve_key_cache_slot(struct ath_common *common,
- enum ieee80211_key_alg alg)
+int ath9k_cmn_count_streams(unsigned int chainmask, int max)
{
- int i;
-
- if (alg == ALG_TKIP)
- return ath_reserve_key_cache_slot_tkip(common);
-
- /* First, try to find slots that would not be available for TKIP. */
- if (common->splitmic) {
- for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
- if (!test_bit(i, common->keymap) &&
- (test_bit(i + 32, common->keymap) ||
- test_bit(i + 64, common->keymap) ||
- test_bit(i + 64 + 32, common->keymap)))
- return i;
- if (!test_bit(i + 32, common->keymap) &&
- (test_bit(i, common->keymap) ||
- test_bit(i + 64, common->keymap) ||
- test_bit(i + 64 + 32, common->keymap)))
- return i + 32;
- if (!test_bit(i + 64, common->keymap) &&
- (test_bit(i , common->keymap) ||
- test_bit(i + 32, common->keymap) ||
- test_bit(i + 64 + 32, common->keymap)))
- return i + 64;
- if (!test_bit(i + 64 + 32, common->keymap) &&
- (test_bit(i, common->keymap) ||
- test_bit(i + 32, common->keymap) ||
- test_bit(i + 64, common->keymap)))
- return i + 64 + 32;
- }
- } else {
- for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
- if (!test_bit(i, common->keymap) &&
- test_bit(i + 64, common->keymap))
- return i;
- if (test_bit(i, common->keymap) &&
- !test_bit(i + 64, common->keymap))
- return i + 64;
- }
- }
-
- /* No partially used TKIP slots, pick any available slot */
- for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
- /* Do not allow slots that could be needed for TKIP group keys
- * to be used. This limitation could be removed if we know that
- * TKIP will not be used. */
- if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
- continue;
- if (common->splitmic) {
- if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
- continue;
- if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
- continue;
- }
+ int streams = 0;
- if (!test_bit(i, common->keymap))
- return i; /* Found a free slot for a key */
- }
+ do {
+ if (++streams == max)
+ break;
+ } while ((chainmask = chainmask & (chainmask - 1)));
- /* No free slot found */
- return -1;
+ return streams;
}
+EXPORT_SYMBOL(ath9k_cmn_count_streams);
/*
- * Configure encryption in the HW.
+ * Configures appropriate weight based on stomp type.
*/
-int ath9k_cmn_key_config(struct ath_common *common,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
+void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
+ enum ath_stomp_type stomp_type)
{
struct ath_hw *ah = common->ah;
- struct ath9k_keyval hk;
- const u8 *mac = NULL;
- u8 gmac[ETH_ALEN];
- int ret = 0;
- int idx;
- memset(&hk, 0, sizeof(hk));
-
- switch (key->alg) {
- case ALG_WEP:
- hk.kv_type = ATH9K_CIPHER_WEP;
+ 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 ALG_TKIP:
- hk.kv_type = ATH9K_CIPHER_TKIP;
+ case ATH_BTCOEX_STOMP_LOW:
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_LOW_WLAN_WGHT);
break;
- case ALG_CCMP:
- hk.kv_type = ATH9K_CIPHER_AES_CCM;
+ case ATH_BTCOEX_STOMP_NONE:
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_NONE_WLAN_WGHT);
break;
default:
- return -EOPNOTSUPP;
- }
-
- hk.kv_len = key->keylen;
- memcpy(hk.kv_val, key->key, key->keylen);
-
- if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
- switch (vif->type) {
- case NL80211_IFTYPE_AP:
- memcpy(gmac, vif->addr, ETH_ALEN);
- gmac[0] |= 0x01;
- mac = gmac;
- idx = ath_reserve_key_cache_slot(common, key->alg);
- break;
- case NL80211_IFTYPE_ADHOC:
- if (!sta) {
- idx = key->keyidx;
- break;
- }
- memcpy(gmac, sta->addr, ETH_ALEN);
- gmac[0] |= 0x01;
- mac = gmac;
- idx = ath_reserve_key_cache_slot(common, key->alg);
- break;
- default:
- idx = key->keyidx;
- break;
- }
- } else if (key->keyidx) {
- if (WARN_ON(!sta))
- return -EOPNOTSUPP;
- mac = sta->addr;
-
- if (vif->type != NL80211_IFTYPE_AP) {
- /* Only keyidx 0 should be used with unicast key, but
- * allow this for client mode for now. */
- idx = key->keyidx;
- } else
- return -EIO;
- } else {
- if (WARN_ON(!sta))
- return -EOPNOTSUPP;
- mac = sta->addr;
-
- idx = ath_reserve_key_cache_slot(common, key->alg);
- }
-
- if (idx < 0)
- return -ENOSPC; /* no free key cache entries */
-
- if (key->alg == ALG_TKIP)
- ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
- vif->type == NL80211_IFTYPE_AP);
- else
- ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac);
-
- if (!ret)
- return -EIO;
-
- set_bit(idx, common->keymap);
- if (key->alg == ALG_TKIP) {
- set_bit(idx + 64, common->keymap);
- if (common->splitmic) {
- set_bit(idx + 32, common->keymap);
- set_bit(idx + 64 + 32, common->keymap);
- }
- }
-
- return idx;
-}
-EXPORT_SYMBOL(ath9k_cmn_key_config);
-
-/*
- * Delete Key.
- */
-void ath9k_cmn_key_delete(struct ath_common *common,
- struct ieee80211_key_conf *key)
-{
- struct ath_hw *ah = common->ah;
-
- ath9k_hw_keyreset(ah, key->hw_key_idx);
- if (key->hw_key_idx < IEEE80211_WEP_NKID)
- return;
-
- clear_bit(key->hw_key_idx, common->keymap);
- if (key->alg != ALG_TKIP)
- return;
-
- clear_bit(key->hw_key_idx + 64, common->keymap);
- if (common->splitmic) {
- ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
- clear_bit(key->hw_key_idx + 32, common->keymap);
- clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
+ ath_print(common, ATH_DBG_BTCOEX,
+ "Invalid Stomptype\n");
+ break;
}
-}
-EXPORT_SYMBOL(ath9k_cmn_key_delete);
-
-int ath9k_cmn_count_streams(unsigned int chainmask, int max)
-{
- int streams = 0;
-
- do {
- if (++streams == max)
- break;
- } while ((chainmask = chainmask & (chainmask - 1)));
- return streams;
+ ath9k_hw_btcoex_enable(ah);
}
-EXPORT_SYMBOL(ath9k_cmn_count_streams);
+EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp);
static int __init ath9k_cmn_init(void)
{
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 97809d39c73f..fea3b3315391 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -52,16 +52,20 @@
#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 ieee80211_hw *hw,
struct ath9k_channel *ichan);
struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
struct ath_hw *ah);
-int ath9k_cmn_key_config(struct ath_common *common,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key);
-void ath9k_cmn_key_delete(struct ath_common *common,
- struct ieee80211_key_conf *key);
int ath9k_cmn_count_streams(unsigned int chainmask, int max);
+void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
+ enum ath_stomp_type stomp_type);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index cf500bf25ad5..43e71a944cb1 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -383,96 +383,6 @@ static const struct file_operations fops_interrupt = {
.llseek = default_llseek,
};
-void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
-{
- struct ath_rc_stats *stats;
-
- stats = &sc->debug.stats.rcstats[final_rate];
- stats->success++;
-}
-
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
- int xretries, int retries, u8 per)
-{
- struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
-
- stats->xretries += xretries;
- stats->retries += retries;
- stats->per = per;
-}
-
-static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath_softc *sc = file->private_data;
- char *buf;
- unsigned int len = 0, max;
- int i = 0;
- ssize_t retval;
-
- if (sc->cur_rate_table == NULL)
- return 0;
-
- max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1;
- buf = kmalloc(max, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- len += sprintf(buf, "%6s %6s %6s "
- "%10s %10s %10s %10s\n",
- "HT", "MCS", "Rate",
- "Success", "Retries", "XRetries", "PER");
-
- for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
- u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
- struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
- char mcs[5];
- char htmode[5];
- int used_mcs = 0, used_htmode = 0;
-
- if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
- used_mcs = snprintf(mcs, 5, "%d",
- sc->cur_rate_table->info[i].ratecode);
-
- if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
- used_htmode = snprintf(htmode, 5, "HT40");
- else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
- used_htmode = snprintf(htmode, 5, "HT20");
- else
- used_htmode = snprintf(htmode, 5, "????");
- }
-
- mcs[used_mcs] = '\0';
- htmode[used_htmode] = '\0';
-
- len += snprintf(buf + len, max - len,
- "%6s %6s %3u.%d: "
- "%10u %10u %10u %10u\n",
- htmode,
- mcs,
- ratekbps / 1000,
- (ratekbps % 1000) / 100,
- stats->success,
- stats->retries,
- stats->xretries,
- stats->per);
- }
-
- if (len > max)
- len = max;
-
- retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
- kfree(buf);
- return retval;
-}
-
-static const struct file_operations fops_rcstat = {
- .read = read_file_rcstat,
- .open = ath9k_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
{
switch (state) {
@@ -494,26 +404,20 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
+ struct ath_wiphy *aphy = sc->pri_wiphy;
+ struct ieee80211_channel *chan = aphy->hw->conf.channel;
char buf[512];
unsigned int len = 0;
int i;
u8 addr[ETH_ALEN];
+ u32 tmp;
len += snprintf(buf + len, sizeof(buf) - len,
"primary: %s (%s chan=%d ht=%d)\n",
wiphy_name(sc->pri_wiphy->hw->wiphy),
ath_wiphy_state_str(sc->pri_wiphy->state),
- sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht);
- for (i = 0; i < sc->num_sec_wiphy; i++) {
- struct ath_wiphy *aphy = sc->sec_wiphy[i];
- if (aphy == NULL)
- continue;
- len += snprintf(buf + len, sizeof(buf) - len,
- "secondary: %s (%s chan=%d ht=%d)\n",
- wiphy_name(aphy->hw->wiphy),
- ath_wiphy_state_str(aphy->state),
- aphy->chan_idx, aphy->chan_is_ht);
- }
+ ieee80211_frequency_to_channel(chan->center_freq),
+ aphy->chan_is_ht);
put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr);
put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
@@ -523,7 +427,51 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
len += snprintf(buf + len, sizeof(buf) - len,
"addrmask: %pM\n", addr);
-
+ tmp = ath9k_hw_getrxfilter(sc->sc_ah);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "rfilt: 0x%x", tmp);
+ if (tmp & ATH9K_RX_FILTER_UCAST)
+ len += snprintf(buf + len, sizeof(buf) - len, " UCAST");
+ if (tmp & ATH9K_RX_FILTER_MCAST)
+ len += snprintf(buf + len, sizeof(buf) - len, " MCAST");
+ if (tmp & ATH9K_RX_FILTER_BCAST)
+ len += snprintf(buf + len, sizeof(buf) - len, " BCAST");
+ if (tmp & ATH9K_RX_FILTER_CONTROL)
+ len += snprintf(buf + len, sizeof(buf) - len, " CONTROL");
+ if (tmp & ATH9K_RX_FILTER_BEACON)
+ len += snprintf(buf + len, sizeof(buf) - len, " BEACON");
+ if (tmp & ATH9K_RX_FILTER_PROM)
+ len += snprintf(buf + len, sizeof(buf) - len, " PROM");
+ if (tmp & ATH9K_RX_FILTER_PROBEREQ)
+ len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ");
+ if (tmp & ATH9K_RX_FILTER_PHYERR)
+ len += snprintf(buf + len, sizeof(buf) - len, " PHYERR");
+ if (tmp & ATH9K_RX_FILTER_MYBEACON)
+ len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON");
+ if (tmp & ATH9K_RX_FILTER_COMP_BAR)
+ len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR");
+ if (tmp & ATH9K_RX_FILTER_PSPOLL)
+ len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL");
+ if (tmp & ATH9K_RX_FILTER_PHYRADAR)
+ len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR");
+ if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL)
+ len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL\n");
+ else
+ len += snprintf(buf + len, sizeof(buf) - len, "\n");
+
+ /* Put variable-length stuff down here, and check for overflows. */
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ if (aphy == NULL)
+ continue;
+ chan = aphy->hw->conf.channel;
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "secondary: %s (%s chan=%d ht=%d)\n",
+ wiphy_name(aphy->hw->wiphy),
+ ath_wiphy_state_str(aphy->state),
+ ieee80211_frequency_to_channel(chan->center_freq),
+ aphy->chan_is_ht);
+ }
if (len > sizeof(buf))
len = sizeof(buf);
@@ -670,6 +618,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
PR("DESC CFG Error: ", desc_cfg_err);
PR("DATA Underrun: ", data_underrun);
PR("DELIM Underrun: ", delim_underrun);
+ PR("TX-Pkts-All: ", tx_pkts_all);
+ PR("TX-Bytes-All: ", tx_bytes_all);
if (len > size)
len = size;
@@ -683,6 +633,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf, struct ath_tx_status *ts)
{
+ TX_STAT_INC(txq->axq_qnum, tx_pkts_all);
+ sc->debug.stats.txstats[txq->axq_qnum].tx_bytes_all += bf->bf_mpdu->len;
+
if (bf_isampdu(bf)) {
if (bf_isxretried(bf))
TX_STAT_INC(txq->axq_qnum, a_xretries);
@@ -778,6 +731,13 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
+ len += snprintf(buf + len, size - len,
+ "%18s : %10u\n", "RX-Pkts-All",
+ sc->debug.stats.rxstats.rx_pkts_all);
+ len += snprintf(buf + len, size - len,
+ "%18s : %10u\n", "RX-Bytes-All",
+ sc->debug.stats.rxstats.rx_bytes_all);
+
if (len > size)
len = size;
@@ -796,6 +756,9 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
u32 phyerr;
+ RX_STAT_INC(rx_pkts_all);
+ sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen;
+
if (rs->rs_status & ATH9K_RXERR_CRC)
RX_STAT_INC(crc_err);
if (rs->rs_status & ATH9K_RXERR_DECRYPT)
@@ -935,10 +898,6 @@ int ath9k_init_debug(struct ath_hw *ah)
sc, &fops_interrupt))
goto err;
- if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_rcstat))
- goto err;
-
if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_wiphy))
goto err;
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 5d21704e87ff..bb0823242ba0 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -80,15 +80,12 @@ struct ath_interrupt_stats {
u32 bb_watchdog;
};
-struct ath_rc_stats {
- u32 success;
- u32 retries;
- u32 xretries;
- u8 per;
-};
-
/**
* struct ath_tx_stats - Statistics about TX
+ * @tx_pkts_all: No. of total frames transmitted, including ones that
+ may have had errors.
+ * @tx_bytes_all: No. of total bytes transmitted, including ones that
+ may have had errors.
* @queued: Total MPDUs (non-aggr) queued
* @completed: Total MPDUs (non-aggr) completed
* @a_aggr: Total no. of aggregates queued
@@ -107,6 +104,8 @@ struct ath_rc_stats {
* @delim_urn: TX delimiter underrun errors
*/
struct ath_tx_stats {
+ u32 tx_pkts_all;
+ u32 tx_bytes_all;
u32 queued;
u32 completed;
u32 a_aggr;
@@ -124,6 +123,10 @@ struct ath_tx_stats {
/**
* struct ath_rx_stats - RX Statistics
+ * @rx_pkts_all: No. of total frames received, including ones that
+ may have had errors.
+ * @rx_bytes_all: No. of total bytes received, including ones that
+ may have had errors.
* @crc_err: No. of frames with incorrect CRC value
* @decrypt_crc_err: No. of frames whose CRC check failed after
decryption process completed
@@ -136,6 +139,8 @@ struct ath_tx_stats {
* @phy_err_stats: Individual PHY error statistics
*/
struct ath_rx_stats {
+ u32 rx_pkts_all;
+ u32 rx_bytes_all;
u32 crc_err;
u32 decrypt_crc_err;
u32 phy_err;
@@ -148,7 +153,6 @@ struct ath_rx_stats {
struct ath_stats {
struct ath_interrupt_stats istats;
- struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
struct ath_rx_stats rxstats;
};
@@ -165,12 +169,9 @@ void ath9k_exit_debug(struct ath_hw *ah);
int ath9k_debug_create_root(void);
void ath9k_debug_remove_root(void);
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf, struct ath_tx_status *ts);
void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
- int xretries, int retries, u8 per);
#else
@@ -197,11 +198,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
{
}
-static inline void ath_debug_stat_rc(struct ath_softc *sc,
- int final_rate)
-{
-}
-
static inline void ath_debug_stat_tx(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_buf *bf,
@@ -214,11 +210,6 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
{
}
-static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
- int xretries, int retries, u8 per)
-{
-}
-
#endif /* CONFIG_ATH9K_DEBUGFS */
#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 0b09db0f8e7d..dacb45e1b906 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -101,7 +101,7 @@
#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
-#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_10_OR_LATER(ah) && \
+#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_11_OR_LATER(ah) && \
ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
@@ -266,6 +266,8 @@ enum eeprom_param {
EEP_INTERNAL_REGULATOR,
EEP_SWREG,
EEP_PAPRD,
+ EEP_MODAL_VER,
+ EEP_ANT_DIV_CTL1,
};
enum ar5416_rates {
@@ -670,7 +672,8 @@ struct eeprom_ops {
bool (*fill_eeprom)(struct ath_hw *hw);
int (*get_eeprom_ver)(struct ath_hw *hw);
int (*get_eeprom_rev)(struct ath_hw *hw);
- u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
+ u8 (*get_num_ant_config)(struct ath_hw *hw,
+ enum ath9k_hal_freq_band band);
u32 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
struct ath9k_channel *chan);
void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 9cccd12e8f21..4fa4d8e28c64 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -179,6 +179,9 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
struct modal_eep_4k_header *pModal = &eep->modalHeader;
struct base_eep_header_4k *pBase = &eep->baseEepHeader;
+ u16 ver_minor;
+
+ ver_minor = pBase->version & AR5416_EEP_VER_MINOR_MASK;
switch (param) {
case EEP_NFTHRESH_2:
@@ -204,7 +207,7 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
case EEP_DB_2:
return pModal->db1_1;
case EEP_MINOR_REV:
- return pBase->version & AR5416_EEP_VER_MINOR_MASK;
+ return ver_minor;
case EEP_TX_MASK:
return pBase->txMask;
case EEP_RX_MASK:
@@ -213,6 +216,15 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
return 0;
case EEP_PWR_TABLE_OFFSET:
return AR5416_PWR_TABLE_OFFSET_DB;
+ case EEP_MODAL_VER:
+ return pModal->version;
+ case EEP_ANT_DIV_CTL1:
+ return pModal->antdiv_ctl1;
+ case EEP_TXGAIN_TYPE:
+ if (ver_minor >= AR5416_EEP_MINOR_VER_19)
+ return pBase->txGainType;
+ else
+ return AR5416_EEP_TXGAIN_ORIGINAL;
default:
return 0;
}
@@ -329,7 +341,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
}
if (i == 0) {
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah))
ss = (int16_t)(0 - (minPwrT4[i] / 2));
else
ss = 0;
@@ -496,7 +508,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
}
@@ -757,7 +768,7 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
regulatory->max_power_level = ratesArray[i];
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
for (i = 0; i < Ar5416RateSize; i++)
ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
}
@@ -828,7 +839,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
@@ -905,9 +915,6 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
-
- if (AR_SREV_9285_11(ah))
- REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
}
/*
@@ -1105,9 +1112,6 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
}
- if (AR_SREV_9285_11(ah))
- REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
-
REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
pModal->switchSettling);
REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
@@ -1157,7 +1161,7 @@ static u32 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
}
static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
- enum ieee80211_band freq_band)
+ enum ath9k_hal_freq_band freq_band)
{
return 1;
}
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index dff2da777312..966b9496a9dd 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -324,7 +324,7 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah,
minDelta = 0;
if (i == 0) {
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah))
ss = (int16_t)(0 - (minPwrT4[i] / 2));
else
ss = 0;
@@ -883,7 +883,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
ratesArray[i] = AR9287_MAX_RATE_POWER;
}
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
for (i = 0; i < Ar5416RateSize; i++)
ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
}
@@ -977,7 +977,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
else
i = rate6mb;
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah))
regulatory->max_power_level =
ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2;
else
@@ -1126,7 +1126,7 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
}
static u8 ath9k_hw_ar9287_get_num_ant_config(struct ath_hw *ah,
- enum ieee80211_band freq_band)
+ enum ath9k_hal_freq_band freq_band)
{
return 1;
}
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index afa2b73ddbdd..76b4d65472dd 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -223,7 +223,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
}
/* Enable fixup for AR_AN_TOP2 if necessary */
- if (AR_SREV_9280_10_OR_LATER(ah) &&
+ if (AR_SREV_9280_20_OR_LATER(ah) &&
(eep->baseEepHeader.version & 0xff) > 0x0a &&
eep->baseEepHeader.pwdclkind == 0)
ah->need_an_top2_fixup = 1;
@@ -317,7 +317,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
txRxAttenLocal = pModal->txRxAttenCh[i];
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
pModal->bswMargin[i]);
@@ -344,7 +344,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
}
}
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
REG_RMW_FIELD(ah,
AR_PHY_RXGAIN + regChainOffset,
AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
@@ -408,7 +408,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
regChainOffset, i);
}
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
if (IS_CHAN_2GHZ(chan)) {
ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
AR_AN_RF2G1_CH0_OB,
@@ -461,7 +461,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
pModal->adcDesiredSize);
- if (!AR_SREV_9280_10_OR_LATER(ah))
+ if (!AR_SREV_9280_20_OR_LATER(ah))
REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
AR_PHY_DESIRED_SZ_PGA,
pModal->pgaDesiredSize);
@@ -478,7 +478,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
pModal->txEndToRxOn);
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
pModal->thresh62);
REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
@@ -696,7 +696,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
}
if (i == 0) {
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah))
ss = (int16_t)(0 - (minPwrT4[i] / 2));
else
ss = 0;
@@ -1291,7 +1291,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
ratesArray[i] = AR5416_MAX_RATE_POWER;
}
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
for (i = 0; i < Ar5416RateSize; i++) {
int8_t pwr_table_offset;
@@ -1395,7 +1395,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
else if (IS_CHAN_HT20(chan))
i = rateHt20_0;
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah))
regulatory->max_power_level =
ratesArray[i] + AR5416_PWR_TABLE_OFFSET_DB * 2;
else
@@ -1418,11 +1418,11 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
}
static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
- enum ieee80211_band freq_band)
+ enum ath9k_hal_freq_band freq_band)
{
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
struct modal_eep_header *pModal =
- &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
+ &(eep->modalHeader[freq_band]);
struct base_eep_header *pBase = &eep->baseEepHeader;
u8 num_ant_config;
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 3a8ee999da5d..4a9a68bba324 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -251,36 +251,6 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
}
}
-/*
- * Configures appropriate weight based on stomp type.
- */
-static void ath9k_btcoex_bt_stomp(struct ath_softc *sc,
- enum ath_stomp_type stomp_type)
-{
- struct ath_hw *ah = sc->sc_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_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
- "Invalid Stomptype\n");
- break;
- }
-
- ath9k_hw_btcoex_enable(ah);
-}
-
static void ath9k_gen_timer_start(struct ath_hw *ah,
struct ath_gen_timer *timer,
u32 timer_next,
@@ -319,6 +289,7 @@ 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;
@@ -328,7 +299,7 @@ static void ath_btcoex_period_timer(unsigned long data)
spin_lock_bh(&btcoex->btcoex_lock);
- ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+ ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
btcoex->bt_stomp_type);
spin_unlock_bh(&btcoex->btcoex_lock);
@@ -359,17 +330,18 @@ static void ath_btcoex_no_stomp_timer(void *arg)
struct ath_softc *sc = (struct ath_softc *)arg;
struct ath_hw *ah = sc->sc_ah;
struct ath_btcoex *btcoex = &sc->btcoex;
+ struct ath_common *common = ath9k_hw_common(ah);
bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ ath_print(common, ATH_DBG_BTCOEX,
"no stomp timer running\n");
spin_lock_bh(&btcoex->btcoex_lock);
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
- ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
+ ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
- ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
+ ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
spin_unlock_bh(&btcoex->btcoex_lock);
}
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 17e7a9a367e7..728d904c74d7 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -92,10 +92,10 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
cmd->skb = skb;
cmd->hif_dev = hif_dev;
- usb_fill_int_urb(urb, hif_dev->udev,
- usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE),
+ usb_fill_bulk_urb(urb, hif_dev->udev,
+ usb_sndbulkpipe(hif_dev->udev, USB_REG_OUT_PIPE),
skb->data, skb->len,
- hif_usb_regout_cb, cmd, 1);
+ hif_usb_regout_cb, cmd);
usb_anchor_urb(urb, &hif_dev->regout_submitted);
ret = usb_submit_urb(urb, GFP_KERNEL);
@@ -541,7 +541,8 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
}
usb_fill_int_urb(urb, hif_dev->udev,
- usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
+ usb_rcvbulkpipe(hif_dev->udev,
+ USB_REG_IN_PIPE),
nskb->data, MAX_REG_IN_BUF_SIZE,
ath9k_hif_usb_reg_in_cb, nskb, 1);
@@ -720,7 +721,8 @@ static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
goto err;
usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev,
- usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
+ usb_rcvbulkpipe(hif_dev->udev,
+ USB_REG_IN_PIPE),
skb->data, MAX_REG_IN_BUF_SIZE,
ath9k_hif_usb_reg_in_cb, skb, 1);
@@ -822,7 +824,9 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
{
- int ret;
+ int ret, idx;
+ struct usb_host_interface *alt = &hif_dev->interface->altsetting[0];
+ struct usb_endpoint_descriptor *endp;
/* Request firmware */
ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name,
@@ -850,6 +854,22 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
goto err_fw_download;
}
+ /* On downloading the firmware to the target, the USB descriptor of EP4
+ * is 'patched' to change the type of the endpoint to Bulk. This will
+ * bring down CPU usage during the scan period.
+ */
+ for (idx = 0; idx < alt->desc.bNumEndpoints; idx++) {
+ endp = &alt->endpoint[idx].desc;
+ if (((endp->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
+ == 0x04) &&
+ ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_INT)) {
+ endp->bmAttributes &= ~USB_ENDPOINT_XFERTYPE_MASK;
+ endp->bmAttributes |= USB_ENDPOINT_XFER_BULK;
+ endp->bInterval = 0;
+ }
+ }
+
return 0;
err_fw_download:
@@ -920,7 +940,8 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
}
ret = ath9k_htc_hw_init(hif_dev->htc_handle,
- &hif_dev->udev->dev, hif_dev->device_id);
+ &hif_dev->udev->dev, hif_dev->device_id,
+ hif_dev->udev->product);
if (ret) {
ret = -EINVAL;
goto err_htc_hw_init;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 43b9e21bc562..75ecf6a30d25 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -316,17 +316,32 @@ struct htc_beacon_config {
u8 dtim_count;
};
-#define OP_INVALID BIT(0)
-#define OP_SCANNING BIT(1)
-#define OP_FULL_RESET BIT(2)
-#define OP_LED_ASSOCIATED BIT(3)
-#define OP_LED_ON BIT(4)
-#define OP_PREAMBLE_SHORT BIT(5)
-#define OP_PROTECT_ENABLE BIT(6)
-#define OP_ASSOCIATED BIT(7)
-#define OP_ENABLE_BEACON BIT(8)
-#define OP_LED_DEINIT BIT(9)
-#define OP_UNPLUGGED BIT(10)
+struct ath_btcoex {
+ u32 bt_priority_cnt;
+ unsigned long bt_priority_time;
+ int bt_stomp_type; /* Types of BT stomping */
+ u32 btcoex_no_stomp;
+ u32 btcoex_period;
+ u32 btscan_no_stomp;
+};
+
+void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv);
+void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv);
+void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
+
+#define OP_INVALID BIT(0)
+#define OP_SCANNING BIT(1)
+#define OP_FULL_RESET BIT(2)
+#define OP_LED_ASSOCIATED BIT(3)
+#define OP_LED_ON BIT(4)
+#define OP_PREAMBLE_SHORT BIT(5)
+#define OP_PROTECT_ENABLE BIT(6)
+#define OP_ASSOCIATED BIT(7)
+#define OP_ENABLE_BEACON BIT(8)
+#define OP_LED_DEINIT BIT(9)
+#define OP_UNPLUGGED BIT(10)
+#define OP_BT_PRIORITY_DETECTED BIT(11)
+#define OP_BT_SCAN BIT(12)
struct ath9k_htc_priv {
struct device *dev;
@@ -391,6 +406,9 @@ struct ath9k_htc_priv {
int cabq;
int hwq_map[WME_NUM_AC];
+ struct ath_btcoex btcoex;
+ struct delayed_work coex_period_work;
+ struct delayed_work duty_cycle_work;
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
struct ath9k_debug debug;
#endif
@@ -443,7 +461,7 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv);
void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
- u16 devid);
+ u16 devid, char *product);
void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
#ifdef CONFIG_PM
int ath9k_htc_resume(struct htc_target *htc_handle);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index bd1506e69105..1b72aa482ac7 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -235,7 +235,14 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
ath9k_hw_get_txq_props(ah, qnum, &qi_be);
qi.tqi_aifs = qi_be.tqi_aifs;
- qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
+ /* 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)) {
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
new file mode 100644
index 000000000000..50eec9a3b88c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -0,0 +1,134 @@
+#include "htc.h"
+
+/******************/
+/* BTCOEX */
+/******************/
+
+/*
+ * Detects if there is any priority bt traffic
+ */
+static void ath_detect_bt_priority(struct ath9k_htc_priv *priv)
+{
+ struct ath_btcoex *btcoex = &priv->btcoex;
+ struct ath_hw *ah = priv->ah;
+
+ if (ath9k_hw_gpio_get(ah, ah->btcoex_hw.btpriority_gpio))
+ btcoex->bt_priority_cnt++;
+
+ if (time_after(jiffies, btcoex->bt_priority_time +
+ msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
+ priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN);
+ /* Detect if colocated bt started scanning */
+ if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
+ ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "BT scan detected");
+ priv->op_flags |= (OP_BT_SCAN |
+ OP_BT_PRIORITY_DETECTED);
+ } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
+ ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "BT priority traffic detected");
+ priv->op_flags |= OP_BT_PRIORITY_DETECTED;
+ }
+
+ btcoex->bt_priority_cnt = 0;
+ btcoex->bt_priority_time = jiffies;
+ }
+}
+
+/*
+ * This is the master bt coex work which runs for every
+ * 45ms, bt traffic will be given priority during 55% of this
+ * period while wlan gets remaining 45%
+ */
+static void ath_btcoex_period_work(struct work_struct *work)
+{
+ struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
+ coex_period_work.work);
+ struct ath_btcoex *btcoex = &priv->btcoex;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ 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);
+
+ ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+ btcoex->bt_stomp_type);
+
+ timer_period = is_btscan ? btcoex->btscan_no_stomp :
+ btcoex->btcoex_no_stomp;
+ ieee80211_queue_delayed_work(priv->hw, &priv->duty_cycle_work,
+ msecs_to_jiffies(timer_period));
+ ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work,
+ msecs_to_jiffies(btcoex->btcoex_period));
+}
+
+/*
+ * Work to time slice between wlan and bt traffic and
+ * configure weight registers
+ */
+static void ath_btcoex_duty_cycle_work(struct work_struct *work)
+{
+ struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
+ duty_cycle_work.work);
+ struct ath_hw *ah = priv->ah;
+ struct ath_btcoex *btcoex = &priv->btcoex;
+ struct ath_common *common = ath9k_hw_common(ah);
+ bool is_btscan = priv->op_flags & OP_BT_SCAN;
+
+ ath_print(common, ATH_DBG_BTCOEX,
+ "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);
+ else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
+ ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
+}
+
+void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
+{
+ struct ath_btcoex *btcoex = &priv->btcoex;
+
+ btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD;
+ btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
+ btcoex->btcoex_period / 100;
+ btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
+ btcoex->btcoex_period / 100;
+ INIT_DELAYED_WORK(&priv->coex_period_work, ath_btcoex_period_work);
+ INIT_DELAYED_WORK(&priv->duty_cycle_work, ath_btcoex_duty_cycle_work);
+}
+
+/*
+ * (Re)start btcoex work
+ */
+
+void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv)
+{
+ struct ath_btcoex *btcoex = &priv->btcoex;
+ struct ath_hw *ah = priv->ah;
+
+ ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "Starting btcoex work");
+
+ btcoex->bt_priority_cnt = 0;
+ btcoex->bt_priority_time = jiffies;
+ priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN);
+ ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, 0);
+}
+
+
+/*
+ * Cancel btcoex and bt duty cycle work.
+ */
+void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
+{
+ cancel_delayed_work_sync(&priv->coex_period_work);
+ cancel_delayed_work_sync(&priv->duty_cycle_work);
+}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 2d4279191d7a..3d7b97f1b3ae 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -41,6 +41,8 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
.max_power = 20, \
}
+#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193"
+
static struct ieee80211_channel ath9k_2ghz_channels[] = {
CHAN2G(2412, 0), /* Channel 1 */
CHAN2G(2417, 1), /* Channel 2 */
@@ -378,15 +380,6 @@ static void ath9k_enable_regwrite_buffer(void *hw_priv)
atomic_inc(&priv->wmi->mwrite_cnt);
}
-static void ath9k_disable_regwrite_buffer(void *hw_priv)
-{
- struct ath_hw *ah = (struct ath_hw *) hw_priv;
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
-
- atomic_dec(&priv->wmi->mwrite_cnt);
-}
-
static void ath9k_regwrite_flush(void *hw_priv)
{
struct ath_hw *ah = (struct ath_hw *) hw_priv;
@@ -395,6 +388,8 @@ static void ath9k_regwrite_flush(void *hw_priv)
u32 rsp_status;
int r;
+ atomic_dec(&priv->wmi->mwrite_cnt);
+
mutex_lock(&priv->wmi->multi_write_mutex);
if (priv->wmi->multi_write_idx) {
@@ -418,7 +413,6 @@ static const struct ath_ops ath9k_common_ops = {
.read = ath9k_regread,
.write = ath9k_regwrite,
.enable_write_buffer = ath9k_enable_regwrite_buffer,
- .disable_write_buffer = ath9k_disable_regwrite_buffer,
.write_flush = ath9k_regwrite_flush,
};
@@ -559,17 +553,20 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
common->keymax = ATH_KEYMAX;
}
+ if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
+ common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
+
/*
* Reset the key cache since some parts do not
* reset the contents on initial power up.
*/
for (i = 0; i < common->keymax; i++)
- ath9k_hw_keyreset(priv->ah, (u16) i);
+ ath_hw_keyreset(common, (u16) i);
}
static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
{
- if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) {
+ if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
priv->sbands[IEEE80211_BAND_2GHZ].channels =
ath9k_2ghz_channels;
priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
@@ -580,7 +577,7 @@ static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
ARRAY_SIZE(ath9k_legacy_rates);
}
- if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) {
+ if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels;
priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
priv->sbands[IEEE80211_BAND_5GHZ].n_channels =
@@ -599,13 +596,36 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv)
common->tx_chainmask = priv->ah->caps.tx_chainmask;
common->rx_chainmask = priv->ah->caps.rx_chainmask;
- if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
+ memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
priv->ah->opmode = NL80211_IFTYPE_STATION;
}
-static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
+static void ath9k_init_btcoex(struct ath9k_htc_priv *priv)
+{
+ int qnum;
+
+ switch (priv->ah->btcoex_hw.scheme) {
+ case ATH_BTCOEX_CFG_NONE:
+ break;
+ case ATH_BTCOEX_CFG_3WIRE:
+ priv->ah->btcoex_hw.btactive_gpio = 7;
+ priv->ah->btcoex_hw.btpriority_gpio = 6;
+ priv->ah->btcoex_hw.wlanactive_gpio = 8;
+ priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+ ath9k_hw_btcoex_init_3wire(priv->ah);
+ ath_htc_init_btcoex_work(priv);
+ qnum = priv->hwq_map[WME_AC_BE];
+ ath9k_hw_init_btcoex_hw(priv->ah, qnum);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+}
+
+static int ath9k_init_priv(struct ath9k_htc_priv *priv,
+ u16 devid, char *product)
{
struct ath_hw *ah = NULL;
struct ath_common *common;
@@ -672,6 +692,11 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
ath9k_init_channels_rates(priv);
ath9k_init_misc(priv);
+ if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) {
+ ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE;
+ ath9k_init_btcoex(priv);
+ }
+
return 0;
err_queues:
@@ -715,18 +740,18 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
sizeof(struct htc_frame_hdr) + 4;
- if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
+ if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&priv->sbands[IEEE80211_BAND_2GHZ];
- if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
+ if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&priv->sbands[IEEE80211_BAND_5GHZ];
if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
- if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
+ if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
setup_ht_cap(priv,
&priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
- if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
+ if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
setup_ht_cap(priv,
&priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
}
@@ -734,7 +759,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
}
-static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid)
+static int ath9k_init_device(struct ath9k_htc_priv *priv,
+ u16 devid, char *product)
{
struct ieee80211_hw *hw = priv->hw;
struct ath_common *common;
@@ -743,7 +769,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid)
struct ath_regulatory *reg;
/* Bring up device */
- error = ath9k_init_priv(priv, devid);
+ error = ath9k_init_priv(priv, devid, product);
if (error != 0)
goto err_init;
@@ -801,7 +827,7 @@ err_init:
}
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
- u16 devid)
+ u16 devid, char *product)
{
struct ieee80211_hw *hw;
struct ath9k_htc_priv *priv;
@@ -835,7 +861,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
/* The device may have been unplugged earlier. */
priv->op_flags &= ~OP_UNPLUGGED;
- ret = ath9k_init_device(priv, devid);
+ ret = ath9k_init_device(priv, devid, product);
if (ret)
goto err_init;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index bc2ca7d898e9..9a3be8da755d 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -137,8 +137,6 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
if (priv->op_flags & OP_FULL_RESET)
fastcc = false;
- /* Fiddle around with fastcc later on, for now just use full reset */
- fastcc = false;
ath9k_htc_ps_wakeup(priv);
htc_stop(priv->htc);
WMI_CMD(WMI_DISABLE_INTR_CMDID);
@@ -146,9 +144,10 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
WMI_CMD(WMI_STOP_RECV_CMDID);
ath_print(common, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), HT: %d, HT40: %d\n",
+ "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
priv->ah->curchan->channel,
- channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf));
+ channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
+ fastcc);
caldata = &priv->caldata[channel->hw_value];
ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
@@ -764,23 +763,12 @@ void ath9k_ani_work(struct work_struct *work)
ath9k_hw_ani_monitor(ah, ah->curchan);
/* Perform calibration if necessary */
- if (longcal || shortcal) {
+ if (longcal || shortcal)
common->ani.caldone =
ath9k_hw_calibrate(ah, ah->curchan,
common->rx_chainmask,
longcal);
- if (longcal)
- common->ani.noise_floor =
- ath9k_hw_getchan_noise(ah, ah->curchan);
-
- ath_print(common, ATH_DBG_ANI,
- " calibrate chan %u/%x nf: %d\n",
- ah->curchan->channel,
- ah->curchan->channelFlags,
- common->ani.noise_floor);
- }
-
ath9k_htc_ps_restore(priv);
}
@@ -1213,6 +1201,12 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
ieee80211_wake_queues(hw);
+ if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_LOW_WLAN_WGHT);
+ ath9k_hw_btcoex_enable(ah);
+ ath_htc_resume_btcoex_work(priv);
+ }
mutex_unlock(&priv->mutex);
return ret;
@@ -1236,7 +1230,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
/* Cancel all the running timers/work .. */
cancel_work_sync(&priv->ps_work);
- cancel_delayed_work_sync(&priv->ath9k_ani_work);
cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
ath9k_led_stop_brightness(priv);
@@ -1257,6 +1250,12 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
"Monitor interface removed\n");
}
+ if (ah->btcoex_hw.enabled) {
+ ath9k_hw_btcoex_disable(ah);
+ if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+ ath_htc_cancel_btcoex_work(priv);
+ }
+
ath9k_hw_phy_disable(ah);
ath9k_hw_disable(ah);
ath9k_hw_configpcipowersave(ah, 1, 1);
@@ -1458,6 +1457,7 @@ out:
FIF_PSPOLL | \
FIF_OTHER_BSS | \
FIF_BCN_PRBRESP_PROMISC | \
+ FIF_PROBE_REQ | \
FIF_FCSFAIL)
static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
@@ -1583,20 +1583,21 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw,
switch (cmd) {
case SET_KEY:
- ret = ath9k_cmn_key_config(common, vif, sta, key);
+ ret = ath_key_config(common, vif, sta, key);
if (ret >= 0) {
key->hw_key_idx = ret;
/* push IV and Michael MIC generation to stack */
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- if (key->alg == ALG_TKIP)
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- if (priv->ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+ if (priv->ah->sw_mgmt_crypto &&
+ key->cipher == WLAN_CIPHER_SUITE_CCMP)
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
ret = 0;
}
break;
case DISABLE_KEY:
- ath9k_cmn_key_delete(common, key);
+ ath_key_delete(common, key);
break;
default:
ret = -EINVAL;
@@ -1777,7 +1778,8 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
priv->op_flags |= OP_SCANNING;
spin_unlock_bh(&priv->beacon_lock);
cancel_work_sync(&priv->ps_work);
- cancel_delayed_work_sync(&priv->ath9k_ani_work);
+ if (priv->op_flags & OP_ASSOCIATED)
+ cancel_delayed_work_sync(&priv->ath9k_ani_work);
mutex_unlock(&priv->mutex);
}
@@ -1791,9 +1793,10 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
priv->op_flags &= ~OP_SCANNING;
spin_unlock_bh(&priv->beacon_lock);
priv->op_flags |= OP_FULL_RESET;
- if (priv->op_flags & OP_ASSOCIATED)
+ if (priv->op_flags & OP_ASSOCIATED) {
ath9k_htc_beacon_config(priv, priv->vif);
- ath_start_ani(priv);
+ ath_start_ani(priv);
+ }
ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex);
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 2a6e45a293a9..3d19b5bc937f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -369,8 +369,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
| ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
| ATH9K_RX_FILTER_MCAST;
- /* If not a STA, enable processing of Probe Requests */
- if (ah->opmode != NL80211_IFTYPE_STATION)
+ if (priv->rxfilter & FIF_PROBE_REQ)
rfilt |= ATH9K_RX_FILTER_PROBEREQ;
/*
@@ -415,8 +414,7 @@ static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv)
ath9k_hw_setrxfilter(ah, rfilt);
/* configure bssid mask */
- if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- ath_hw_setbssidmask(common);
+ ath_hw_setbssidmask(common);
/* configure operational mode */
ath9k_hw_setopmode(ah);
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 705c0f342e1c..861ec9269309 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -462,9 +462,9 @@ void ath9k_htc_hw_free(struct htc_target *htc)
}
int ath9k_htc_hw_init(struct htc_target *target,
- struct device *dev, u16 devid)
+ struct device *dev, u16 devid, char *product)
{
- if (ath9k_htc_probe_device(target, dev, devid)) {
+ if (ath9k_htc_probe_device(target, dev, devid, product)) {
printk(KERN_ERR "Failed to initialize the device\n");
return -ENODEV;
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
index faba6790328b..07b6509d5896 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.h
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -239,7 +239,7 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
struct device *dev);
void ath9k_htc_hw_free(struct htc_target *htc);
int ath9k_htc_hw_init(struct htc_target *target,
- struct device *dev, u16 devid);
+ struct device *dev, u16 devid, char *product);
void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
#endif /* HTC_HST_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index ffecbadaea4a..0a4ad348b699 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -128,17 +128,6 @@ static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
}
-static inline void ath9k_hw_procmibevent(struct ath_hw *ah)
-{
- ath9k_hw_ops(ah)->ani_proc_mib_event(ah);
-}
-
-static inline void ath9k_hw_ani_monitor(struct ath_hw *ah,
- struct ath9k_channel *chan)
-{
- ath9k_hw_ops(ah)->ani_monitor(ah, chan);
-}
-
/* Private hardware call ops */
/* PHY ops */
@@ -276,15 +265,4 @@ static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
}
-static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah,
- enum ath9k_cal_types calType)
-{
- return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType);
-}
-
-static inline void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
-{
- ath9k_hw_private_ops(ah)->ani_reset(ah, is_scanning);
-}
-
#endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 3384ca164562..cc13ee117823 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -88,29 +88,32 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
/* Helper Functions */
/********************/
-static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
+static void ath9k_hw_set_clockrate(struct ath_hw *ah)
{
struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+ struct ath_common *common = ath9k_hw_common(ah);
+ unsigned int clockrate;
if (!ah->curchan) /* should really check for CCK instead */
- return usecs *ATH9K_CLOCK_RATE_CCK;
- if (conf->channel->band == IEEE80211_BAND_2GHZ)
- return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
-
- if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
- return usecs * ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
+ clockrate = ATH9K_CLOCK_RATE_CCK;
+ else if (conf->channel->band == IEEE80211_BAND_2GHZ)
+ clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
+ else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
+ clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
else
- return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM;
+ clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
+
+ if (conf_is_ht40(conf))
+ clockrate *= 2;
+
+ common->clockrate = clockrate;
}
static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+ struct ath_common *common = ath9k_hw_common(ah);
- if (conf_is_ht40(conf))
- return ath9k_hw_mac_clks(ah, usecs) * 2;
- else
- return ath9k_hw_mac_clks(ah, usecs);
+ return usecs * common->clockrate;
}
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
@@ -299,7 +302,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
/* This should work for all families including legacy */
@@ -371,10 +373,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
ah->config.pcie_clock_req = 0;
ah->config.pcie_waen = 0;
ah->config.analog_shiftreg = 1;
- ah->config.ofdm_trig_low = 200;
- ah->config.ofdm_trig_high = 500;
- ah->config.cck_trig_high = 200;
- ah->config.cck_trig_low = 100;
ah->config.enable_ani = true;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
@@ -565,7 +563,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
ath9k_hw_init_cal_settings(ah);
ah->ani_function = ATH9K_ANI_ALL;
- if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah))
ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
if (!AR_SREV_9300_20_OR_LATER(ah))
ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
@@ -676,7 +674,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
static void ath9k_hw_init_pll(struct ath_hw *ah,
@@ -741,7 +738,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (AR_SREV_9300_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
@@ -885,7 +881,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
/*
* Restore TX Trigger Level to its pre-reset value.
@@ -933,7 +928,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (AR_SREV_9300_20_OR_LATER(ah))
ath9k_hw_reset_txstatus_ring(ah);
@@ -1031,7 +1025,6 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
REG_WRITE(ah, AR_RTC_RC, rst_flags);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
udelay(50);
@@ -1070,7 +1063,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
udelay(2);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (!AR_SREV_9300_20_OR_LATER(ah))
udelay(2);
@@ -1167,6 +1159,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
"Failed to set channel\n");
return false;
}
+ ath9k_hw_set_clockrate(ah);
ah->eep_ops->set_txpower(ah, chan,
ath9k_regd_get_ctl(regulatory, chan),
@@ -1190,7 +1183,7 @@ bool ath9k_hw_check_alive(struct ath_hw *ah)
int count = 50;
u32 reg;
- if (AR_SREV_9285_10_OR_LATER(ah))
+ if (AR_SREV_9285_12_OR_LATER(ah))
return true;
do {
@@ -1239,7 +1232,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return -EIO;
- if (curchan && !ah->chip_fullsleep && ah->caldata)
+ if (curchan && !ah->chip_fullsleep)
ath9k_hw_getnf(ah, curchan);
ah->caldata = caldata;
@@ -1258,11 +1251,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
(chan->channel != ah->curchan->channel) &&
((chan->channelFlags & CHANNEL_ALL) ==
(ah->curchan->channelFlags & CHANNEL_ALL)) &&
- !AR_SREV_9280(ah)) {
+ (!AR_SREV_9280(ah) || AR_DEVID_7010(ah))) {
if (ath9k_hw_channel_change(ah, chan)) {
ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah, true);
+ if (AR_SREV_9271(ah))
+ ar9002_hw_load_ani_reg(ah, chan);
return 0;
}
}
@@ -1310,7 +1305,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (tsf)
ath9k_hw_settsf64(ah, tsf);
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9280_20_OR_LATER(ah))
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
if (!AR_SREV_9300_20_OR_LATER(ah))
@@ -1372,19 +1367,19 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
r = ath9k_hw_rf_set_freq(ah, chan);
if (r)
return r;
+ ath9k_hw_set_clockrate(ah);
+
ENABLE_REGWRITE_BUFFER(ah);
for (i = 0; i < AR_NUM_DCU; i++)
REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
ah->intr_txqs = 0;
for (i = 0; i < ah->caps.total_queues; i++)
@@ -1432,7 +1427,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
/*
* For big endian systems turn on swapping for descriptors
@@ -1474,283 +1468,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
}
EXPORT_SYMBOL(ath9k_hw_reset);
-/************************/
-/* Key Cache Management */
-/************************/
-
-bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
-{
- u32 keyType;
-
- if (entry >= ah->caps.keycache_size) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "keychache entry %u out of range\n", entry);
- return false;
- }
-
- keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
-
- REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
- REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
- REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
- REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
- REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
- REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
- REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
- REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
-
- if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
- u16 micentry = entry + 64;
-
- REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
- REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
- REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
- REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
-
- }
-
- return true;
-}
-EXPORT_SYMBOL(ath9k_hw_keyreset);
-
-static bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
-{
- u32 macHi, macLo;
- u32 unicast_flag = AR_KEYTABLE_VALID;
-
- if (entry >= ah->caps.keycache_size) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "keychache entry %u out of range\n", entry);
- return false;
- }
-
- if (mac != NULL) {
- /*
- * AR_KEYTABLE_VALID indicates that the address is a unicast
- * address, which must match the transmitter address for
- * decrypting frames.
- * Not setting this bit allows the hardware to use the key
- * for multicast frame decryption.
- */
- if (mac[0] & 0x01)
- unicast_flag = 0;
-
- macHi = (mac[5] << 8) | mac[4];
- macLo = (mac[3] << 24) |
- (mac[2] << 16) |
- (mac[1] << 8) |
- mac[0];
- macLo >>= 1;
- macLo |= (macHi & 1) << 31;
- macHi >>= 1;
- } else {
- macLo = macHi = 0;
- }
- REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
- REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
-
- return true;
-}
-
-bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
- const struct ath9k_keyval *k,
- const u8 *mac)
-{
- const struct ath9k_hw_capabilities *pCap = &ah->caps;
- struct ath_common *common = ath9k_hw_common(ah);
- u32 key0, key1, key2, key3, key4;
- u32 keyType;
-
- if (entry >= pCap->keycache_size) {
- ath_print(common, ATH_DBG_FATAL,
- "keycache entry %u out of range\n", entry);
- return false;
- }
-
- switch (k->kv_type) {
- case ATH9K_CIPHER_AES_OCB:
- keyType = AR_KEYTABLE_TYPE_AES;
- break;
- case ATH9K_CIPHER_AES_CCM:
- if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
- ath_print(common, ATH_DBG_ANY,
- "AES-CCM not supported by mac rev 0x%x\n",
- ah->hw_version.macRev);
- return false;
- }
- keyType = AR_KEYTABLE_TYPE_CCM;
- break;
- case ATH9K_CIPHER_TKIP:
- keyType = AR_KEYTABLE_TYPE_TKIP;
- if (ATH9K_IS_MIC_ENABLED(ah)
- && entry + 64 >= pCap->keycache_size) {
- ath_print(common, ATH_DBG_ANY,
- "entry %u inappropriate for TKIP\n", entry);
- return false;
- }
- break;
- case ATH9K_CIPHER_WEP:
- if (k->kv_len < WLAN_KEY_LEN_WEP40) {
- ath_print(common, ATH_DBG_ANY,
- "WEP key length %u too small\n", k->kv_len);
- return false;
- }
- if (k->kv_len <= WLAN_KEY_LEN_WEP40)
- keyType = AR_KEYTABLE_TYPE_40;
- else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
- keyType = AR_KEYTABLE_TYPE_104;
- else
- keyType = AR_KEYTABLE_TYPE_128;
- break;
- case ATH9K_CIPHER_CLR:
- keyType = AR_KEYTABLE_TYPE_CLR;
- break;
- default:
- ath_print(common, ATH_DBG_FATAL,
- "cipher %u not supported\n", k->kv_type);
- return false;
- }
-
- key0 = get_unaligned_le32(k->kv_val + 0);
- key1 = get_unaligned_le16(k->kv_val + 4);
- key2 = get_unaligned_le32(k->kv_val + 6);
- key3 = get_unaligned_le16(k->kv_val + 10);
- key4 = get_unaligned_le32(k->kv_val + 12);
- if (k->kv_len <= WLAN_KEY_LEN_WEP104)
- key4 &= 0xff;
-
- /*
- * Note: Key cache registers access special memory area that requires
- * two 32-bit writes to actually update the values in the internal
- * memory. Consequently, the exact order and pairs used here must be
- * maintained.
- */
-
- if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
- u16 micentry = entry + 64;
-
- /*
- * Write inverted key[47:0] first to avoid Michael MIC errors
- * on frames that could be sent or received at the same time.
- * The correct key will be written in the end once everything
- * else is ready.
- */
- REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
- REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
-
- /* Write key[95:48] */
- REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
- REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
-
- /* Write key[127:96] and key type */
- REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
- REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
-
- /* Write MAC address for the entry */
- (void) ath9k_hw_keysetmac(ah, entry, mac);
-
- if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
- /*
- * TKIP uses two key cache entries:
- * Michael MIC TX/RX keys in the same key cache entry
- * (idx = main index + 64):
- * key0 [31:0] = RX key [31:0]
- * key1 [15:0] = TX key [31:16]
- * key1 [31:16] = reserved
- * key2 [31:0] = RX key [63:32]
- * key3 [15:0] = TX key [15:0]
- * key3 [31:16] = reserved
- * key4 [31:0] = TX key [63:32]
- */
- u32 mic0, mic1, mic2, mic3, mic4;
-
- mic0 = get_unaligned_le32(k->kv_mic + 0);
- mic2 = get_unaligned_le32(k->kv_mic + 4);
- mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
- mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
- mic4 = get_unaligned_le32(k->kv_txmic + 4);
-
- /* Write RX[31:0] and TX[31:16] */
- REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
- REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
-
- /* Write RX[63:32] and TX[15:0] */
- REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
- REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
-
- /* Write TX[63:32] and keyType(reserved) */
- REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
- REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
- AR_KEYTABLE_TYPE_CLR);
-
- } else {
- /*
- * TKIP uses four key cache entries (two for group
- * keys):
- * Michael MIC TX/RX keys are in different key cache
- * entries (idx = main index + 64 for TX and
- * main index + 32 + 96 for RX):
- * key0 [31:0] = TX/RX MIC key [31:0]
- * key1 [31:0] = reserved
- * key2 [31:0] = TX/RX MIC key [63:32]
- * key3 [31:0] = reserved
- * key4 [31:0] = reserved
- *
- * Upper layer code will call this function separately
- * for TX and RX keys when these registers offsets are
- * used.
- */
- u32 mic0, mic2;
-
- mic0 = get_unaligned_le32(k->kv_mic + 0);
- mic2 = get_unaligned_le32(k->kv_mic + 4);
-
- /* Write MIC key[31:0] */
- REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
- REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
-
- /* Write MIC key[63:32] */
- REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
- REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
-
- /* Write TX[63:32] and keyType(reserved) */
- REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
- REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
- AR_KEYTABLE_TYPE_CLR);
- }
-
- /* MAC address registers are reserved for the MIC entry */
- REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
- REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
-
- /*
- * Write the correct (un-inverted) key[47:0] last to enable
- * TKIP now that all other registers are set with correct
- * values.
- */
- REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
- REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
- } else {
- /* Write key[47:0] */
- REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
- REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
-
- /* Write key[95:48] */
- REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
- REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
-
- /* Write key[127:96] and key type */
- REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
- REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
-
- /* Write MAC address for the entry */
- (void) ath9k_hw_keysetmac(ah, entry, mac);
- }
-
- return true;
-}
-EXPORT_SYMBOL(ath9k_hw_set_keycache_entry);
-
/******************************/
/* Power Management (Chipset) */
/******************************/
@@ -1959,7 +1676,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
beacon_period &= ~ATH9K_BEACON_ENA;
if (beacon_period & ATH9K_BEACON_RESET_TSF) {
@@ -1987,7 +1703,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
REG_RMW_FIELD(ah, AR_RSSI_THR,
AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
@@ -2033,7 +1748,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
REG_SET_BIT(ah, AR_TIMER_MODE,
AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
@@ -2056,12 +1770,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
u16 capField = 0, eeval;
+ u8 ant_div_ctl1;
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
regulatory->current_rd = eeval;
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
- if (AR_SREV_9285_10_OR_LATER(ah))
+ if (AR_SREV_9285_12_OR_LATER(ah))
eeval |= AR9285_RDEXT_DEFAULT;
regulatory->current_rd_ext = eeval;
@@ -2085,37 +1800,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
return -EINVAL;
}
- bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
+ if (eeval & AR5416_OPFLAGS_11A)
+ pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
- if (eeval & AR5416_OPFLAGS_11A) {
- set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
- if (ah->config.ht_enable) {
- if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
- set_bit(ATH9K_MODE_11NA_HT20,
- pCap->wireless_modes);
- if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
- set_bit(ATH9K_MODE_11NA_HT40PLUS,
- pCap->wireless_modes);
- set_bit(ATH9K_MODE_11NA_HT40MINUS,
- pCap->wireless_modes);
- }
- }
- }
-
- if (eeval & AR5416_OPFLAGS_11G) {
- set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
- if (ah->config.ht_enable) {
- if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
- set_bit(ATH9K_MODE_11NG_HT20,
- pCap->wireless_modes);
- if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
- set_bit(ATH9K_MODE_11NG_HT40PLUS,
- pCap->wireless_modes);
- set_bit(ATH9K_MODE_11NG_HT40MINUS,
- pCap->wireless_modes);
- }
- }
- }
+ if (eeval & AR5416_OPFLAGS_11G)
+ pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
/*
@@ -2131,8 +1820,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
/* Use rx_chainmask from EEPROM. */
pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
- if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
- ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
+ ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
pCap->low_2ghz_chan = 2312;
pCap->high_2ghz_chan = 2732;
@@ -2140,24 +1828,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->low_5ghz_chan = 4920;
pCap->high_5ghz_chan = 6100;
- pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
- pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
- pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
-
- pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
- pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
- pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
+ common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
if (ah->config.ht_enable)
pCap->hw_caps |= ATH9K_HW_CAP_HT;
else
pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
- pCap->hw_caps |= ATH9K_HW_CAP_GTT;
- pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
- pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
- pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
-
if (capField & AR_EEPROM_EEPCAP_MAXQCU)
pCap->total_queues =
MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
@@ -2170,8 +1847,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
else
pCap->keycache_size = AR_KEYTABLE_SIZE;
- pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
-
if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
else
@@ -2181,9 +1856,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->num_gpio_pins = AR9271_NUM_GPIO;
else if (AR_DEVID_7010(ah))
pCap->num_gpio_pins = AR7010_NUM_GPIO;
- else if (AR_SREV_9285_10_OR_LATER(ah))
+ else if (AR_SREV_9285_12_OR_LATER(ah))
pCap->num_gpio_pins = AR9285_NUM_GPIO;
- else if (AR_SREV_9280_10_OR_LATER(ah))
+ else if (AR_SREV_9280_20_OR_LATER(ah))
pCap->num_gpio_pins = AR928X_NUM_GPIO;
else
pCap->num_gpio_pins = AR_NUM_GPIO;
@@ -2240,7 +1915,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->num_antcfg_2ghz =
ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
- if (AR_SREV_9280_10_OR_LATER(ah) &&
+ if (AR_SREV_9280_20_OR_LATER(ah) &&
ath9k_hw_btcoex_supported(ah)) {
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
@@ -2277,9 +1952,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
if (AR_SREV_9300_20_OR_LATER(ah))
pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
- if (AR_SREV_9287_10_OR_LATER(ah) || AR_SREV_9271(ah))
+ if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah))
pCap->hw_caps |= ATH9K_HW_CAP_SGI_20;
+ if (AR_SREV_9285(ah))
+ if (ah->eep_ops->get_eeprom(ah, EEP_MODAL_VER) >= 3) {
+ ant_div_ctl1 =
+ ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+ if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1))
+ pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
+ }
+
return 0;
}
@@ -2353,11 +2036,11 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
return MS_REG_READ(AR9300, gpio) != 0;
else if (AR_SREV_9271(ah))
return MS_REG_READ(AR9271, gpio) != 0;
- else if (AR_SREV_9287_10_OR_LATER(ah))
+ else if (AR_SREV_9287_11_OR_LATER(ah))
return MS_REG_READ(AR9287, gpio) != 0;
- else if (AR_SREV_9285_10_OR_LATER(ah))
+ else if (AR_SREV_9285_12_OR_LATER(ah))
return MS_REG_READ(AR9285, gpio) != 0;
- else if (AR_SREV_9280_10_OR_LATER(ah))
+ else if (AR_SREV_9280_20_OR_LATER(ah))
return MS_REG_READ(AR928X, gpio) != 0;
else
return MS_REG_READ(AR, gpio) != 0;
@@ -2456,7 +2139,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
EXPORT_SYMBOL(ath9k_hw_setrxfilter);
@@ -2854,7 +2536,7 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len)
int used;
/* chipsets >= AR9280 are single-chip */
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
used = snprintf(hw_name, len,
"Atheros AR%s Rev:%x",
ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 399f7c1283cd..d032939768b0 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -61,6 +61,8 @@
#define ATH9K_RSSI_BAD -128
+#define ATH9K_NUM_CHANNELS 38
+
/* Register read/write primitives */
#define REG_WRITE(_ah, _reg, _val) \
ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
@@ -70,19 +72,13 @@
#define ENABLE_REGWRITE_BUFFER(_ah) \
do { \
- if (AR_SREV_9271(_ah)) \
+ if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \
ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
} while (0)
-#define DISABLE_REGWRITE_BUFFER(_ah) \
- do { \
- if (AR_SREV_9271(_ah)) \
- ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \
- } while (0)
-
#define REGWRITE_BUFFER_FLUSH(_ah) \
do { \
- if (AR_SREV_9271(_ah)) \
+ if (ath9k_hw_common(_ah)->ops->write_flush) \
ath9k_hw_common(_ah)->ops->write_flush((_ah)); \
} while (0)
@@ -168,47 +164,26 @@ enum ath_ini_subsys {
ATH_INI_NUM_SPLIT,
};
-enum wireless_mode {
- ATH9K_MODE_11A = 0,
- ATH9K_MODE_11G,
- ATH9K_MODE_11NA_HT20,
- ATH9K_MODE_11NG_HT20,
- ATH9K_MODE_11NA_HT40PLUS,
- ATH9K_MODE_11NA_HT40MINUS,
- ATH9K_MODE_11NG_HT40PLUS,
- ATH9K_MODE_11NG_HT40MINUS,
- ATH9K_MODE_MAX,
-};
-
enum ath9k_hw_caps {
- ATH9K_HW_CAP_MIC_AESCCM = BIT(0),
- ATH9K_HW_CAP_MIC_CKIP = BIT(1),
- ATH9K_HW_CAP_MIC_TKIP = BIT(2),
- ATH9K_HW_CAP_CIPHER_AESCCM = BIT(3),
- ATH9K_HW_CAP_CIPHER_CKIP = BIT(4),
- ATH9K_HW_CAP_CIPHER_TKIP = BIT(5),
- ATH9K_HW_CAP_VEOL = BIT(6),
- ATH9K_HW_CAP_BSSIDMASK = BIT(7),
- ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(8),
- ATH9K_HW_CAP_HT = BIT(9),
- ATH9K_HW_CAP_GTT = BIT(10),
- ATH9K_HW_CAP_FASTCC = BIT(11),
- ATH9K_HW_CAP_RFSILENT = BIT(12),
- ATH9K_HW_CAP_CST = BIT(13),
- ATH9K_HW_CAP_ENHANCEDPM = BIT(14),
- ATH9K_HW_CAP_AUTOSLEEP = BIT(15),
- ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16),
- ATH9K_HW_CAP_EDMA = BIT(17),
- ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18),
- ATH9K_HW_CAP_LDPC = BIT(19),
- ATH9K_HW_CAP_FASTCLOCK = BIT(20),
- ATH9K_HW_CAP_SGI_20 = BIT(21),
- ATH9K_HW_CAP_PAPRD = BIT(22),
+ 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),
+ ATH9K_HW_CAP_RAC_SUPPORTED = BIT(7),
+ ATH9K_HW_CAP_LDPC = BIT(8),
+ ATH9K_HW_CAP_FASTCLOCK = BIT(9),
+ ATH9K_HW_CAP_SGI_20 = BIT(10),
+ ATH9K_HW_CAP_PAPRD = BIT(11),
+ ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12),
+ ATH9K_HW_CAP_2GHZ = BIT(13),
+ ATH9K_HW_CAP_5GHZ = BIT(14),
};
struct ath9k_hw_capabilities {
u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
- DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
u16 total_queues;
u16 keycache_size;
u16 low_5ghz_chan, high_5ghz_chan;
@@ -352,9 +327,9 @@ struct ath9k_hw_cal_data {
int32_t CalValid;
int8_t iCoff;
int8_t qCoff;
- int16_t rawNoiseFloor;
bool paprd_done;
bool nfcal_pending;
+ bool nfcal_interference;
u16 small_signal_gain[AR9300_MAX_CHAINS];
u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
@@ -362,9 +337,11 @@ struct ath9k_hw_cal_data {
struct ath9k_channel {
struct ieee80211_channel *chan;
+ struct ar5416AniState ani;
u16 channel;
u32 channelFlags;
u32 chanmode;
+ s16 noisefloor;
};
#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
@@ -494,6 +471,12 @@ struct ath_gen_timer_table {
} timer_mask;
};
+struct ath_hw_antcomb_conf {
+ u8 main_lna_conf;
+ u8 alt_lna_conf;
+ u8 fast_div_bias;
+};
+
/**
* struct ath_hw_private_ops - callbacks used internally by hardware code
*
@@ -517,14 +500,6 @@ struct ath_gen_timer_table {
* @setup_calibration: set up calibration
* @iscal_supported: used to query if a type of calibration is supported
*
- * @ani_reset: reset ANI parameters to default values
- * @ani_lower_immunity: lower the noise immunity level. The level controls
- * the power-based packet detection on hardware. If a power jump is
- * detected the adapter takes it as an indication that a packet has
- * arrived. The level ranges from 0-5. Each level corresponds to a
- * few dB more of noise immunity. If you have a strong time-varying
- * interference that is causing false detections (OFDM timing errors or
- * CCK timing errors) the level can be increased.
* @ani_cache_ini_regs: cache the values for ANI from the initial
* register settings through the register initialization.
*/
@@ -538,8 +513,6 @@ struct ath_hw_private_ops {
bool (*macversion_supported)(u32 macversion);
void (*setup_calibration)(struct ath_hw *ah,
struct ath9k_cal_list *currCal);
- bool (*iscal_supported)(struct ath_hw *ah,
- enum ath9k_cal_types calType);
/* PHY ops */
int (*rf_set_freq)(struct ath_hw *ah,
@@ -571,8 +544,6 @@ struct ath_hw_private_ops {
void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
/* ANI */
- void (*ani_reset)(struct ath_hw *ah, bool is_scanning);
- void (*ani_lower_immunity)(struct ath_hw *ah);
void (*ani_cache_ini_regs)(struct ath_hw *ah);
};
@@ -584,11 +555,6 @@ struct ath_hw_private_ops {
*
* @config_pci_powersave:
* @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
- *
- * @ani_proc_mib_event: process MIB events, this would happen upon specific ANI
- * thresholds being reached or having overflowed.
- * @ani_monitor: called periodically by the core driver to collect
- * MIB stats and adjust ANI if specific thresholds have been reached.
*/
struct ath_hw_ops {
void (*config_pci_powersave)(struct ath_hw *ah,
@@ -629,9 +595,6 @@ struct ath_hw_ops {
u32 burstDuration);
void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
u32 vmf);
-
- void (*ani_proc_mib_event)(struct ath_hw *ah);
- void (*ani_monitor)(struct ath_hw *ah, struct ath9k_channel *chan);
};
struct ath_nf_limits {
@@ -646,7 +609,7 @@ struct ath_hw {
struct ath9k_hw_version hw_version;
struct ath9k_ops_config config;
struct ath9k_hw_capabilities caps;
- struct ath9k_channel channels[38];
+ struct ath9k_channel channels[ATH9K_NUM_CHANNELS];
struct ath9k_channel *curchan;
union {
@@ -692,10 +655,9 @@ struct ath_hw {
u32 atim_window;
/* Calibration */
- enum ath9k_cal_types supp_cals;
+ u32 supp_cals;
struct ath9k_cal_list iq_caldata;
struct ath9k_cal_list adcgain_caldata;
- struct ath9k_cal_list adcdc_calinitdata;
struct ath9k_cal_list adcdc_caldata;
struct ath9k_cal_list tempCompCalData;
struct ath9k_cal_list *cal_list;
@@ -764,8 +726,6 @@ struct ath_hw {
/* ANI */
u32 proc_phyerr;
u32 aniperiod;
- struct ar5416AniState *curani;
- struct ar5416AniState ani[255];
int totalSizeDesired[5];
int coarse_high[5];
int coarse_low[5];
@@ -873,12 +833,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
int ath9k_hw_fill_cap_info(struct ath_hw *ah);
u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
-/* Key Cache Management */
-bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
-bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
- const struct ath9k_keyval *k,
- const u8 *mac);
-
/* GPIO / RFKILL / Antennae */
void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
@@ -887,6 +841,10 @@ 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);
@@ -984,6 +942,7 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah);
void ar9002_hw_attach_ops(struct ath_hw *ah);
void ar9003_hw_attach_ops(struct ath_hw *ah);
+void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan);
/*
* ANI work can be shared between all families but a next
* generation implementation of ANI will be used only for AR9003 only
@@ -992,8 +951,9 @@ void ar9003_hw_attach_ops(struct ath_hw *ah);
* older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani.
*/
extern int modparam_force_new_ani;
-void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah);
-void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah);
+void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
+void ath9k_hw_proc_mib_event(struct ath_hw *ah);
+void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
#define ATH_PCIE_CAP_LINK_CTRL 0x70
#define ATH_PCIE_CAP_LINK_L0S 1
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 243c1775f343..bc6c4df9712c 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -33,7 +33,7 @@ int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
-int led_blink = 1;
+int led_blink;
module_param_named(blink, led_blink, int, 0444);
MODULE_PARM_DESC(blink, "Enable LED blink on activity");
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(blink, "Enable LED blink on activity");
* on 5 MHz steps, we support the channels which we know
* we have calibration data for all cards though to make
* this static */
-static struct ieee80211_channel ath9k_2ghz_chantable[] = {
+static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
CHAN2G(2412, 0), /* Channel 1 */
CHAN2G(2417, 1), /* Channel 2 */
CHAN2G(2422, 2), /* Channel 3 */
@@ -77,7 +77,7 @@ static struct ieee80211_channel ath9k_2ghz_chantable[] = {
* on 5 MHz steps, we support the channels which we know
* we have calibration data for all cards though to make
* this static */
-static struct ieee80211_channel ath9k_5ghz_chantable[] = {
+static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
/* _We_ call this UNII 1 */
CHAN5G(5180, 14), /* Channel 36 */
CHAN5G(5200, 15), /* Channel 40 */
@@ -211,7 +211,7 @@ static void setup_ht_cap(struct ath_softc *sc,
else
max_streams = 2;
- if (AR_SREV_9280_10_OR_LATER(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
if (max_streams >= 2)
ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
@@ -381,7 +381,7 @@ static void ath9k_init_crypto(struct ath_softc *sc)
* reset the contents on initial power up.
*/
for (i = 0; i < common->keymax; i++)
- ath9k_hw_keyreset(sc->sc_ah, (u16) i);
+ ath_hw_keyreset(common, (u16) i);
/*
* Check whether the separate key cache entries
@@ -389,8 +389,8 @@ static void ath9k_init_crypto(struct ath_softc *sc)
* With split mic keys the number of stations is limited
* to 27 otherwise 59.
*/
- if (!(sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA))
- common->splitmic = 1;
+ if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
+ common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
}
static int ath9k_init_btcoex(struct ath_softc *sc)
@@ -477,10 +477,21 @@ err:
return -EIO;
}
-static void ath9k_init_channels_rates(struct ath_softc *sc)
+static int ath9k_init_channels_rates(struct ath_softc *sc)
{
- if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
- sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
+ void *channels;
+
+ BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
+ ARRAY_SIZE(ath9k_5ghz_chantable) !=
+ ATH9K_NUM_CHANNELS);
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
+ channels = kmemdup(ath9k_2ghz_chantable,
+ sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
+ if (!channels)
+ return -ENOMEM;
+
+ sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
ARRAY_SIZE(ath9k_2ghz_chantable);
@@ -489,8 +500,16 @@ static void ath9k_init_channels_rates(struct ath_softc *sc)
ARRAY_SIZE(ath9k_legacy_rates);
}
- if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
- sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
+ channels = kmemdup(ath9k_5ghz_chantable,
+ sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
+ if (!channels) {
+ if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
+ kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
+ return -ENOMEM;
+ }
+
+ sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
ARRAY_SIZE(ath9k_5ghz_chantable);
@@ -499,6 +518,7 @@ static void ath9k_init_channels_rates(struct ath_softc *sc)
sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
ARRAY_SIZE(ath9k_legacy_rates) - 4;
}
+ return 0;
}
static void ath9k_init_misc(struct ath_softc *sc)
@@ -506,7 +526,6 @@ static void ath9k_init_misc(struct ath_softc *sc)
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
int i = 0;
- common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
sc->config.txpowlimit = ATH_TXPOWER_MAX;
@@ -522,8 +541,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
ath9k_hw_set_diversity(sc->sc_ah, true);
sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
+ memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
sc->beacon.slottime = ATH9K_SLOT_TIME_9;
@@ -531,6 +549,9 @@ static void ath9k_init_misc(struct ath_softc *sc)
sc->beacon.bslot[i] = NULL;
sc->beacon.bslot_aphy[i] = NULL;
}
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
+ sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
}
static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
@@ -593,8 +614,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
if (ret)
goto err_btcoex;
+ ret = ath9k_init_channels_rates(sc);
+ if (ret)
+ goto err_btcoex;
+
ath9k_init_crypto(sc);
- ath9k_init_channels_rates(sc);
ath9k_init_misc(sc);
return 0;
@@ -637,11 +661,13 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_WDS) |
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
- hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+ if (AR_SREV_5416(sc->sc_ah))
+ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
hw->queues = 4;
hw->max_rates = 4;
@@ -651,19 +677,21 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->sta_data_size = sizeof(struct ath_node);
hw->vif_data_size = sizeof(struct ath_vif);
+#ifdef CONFIG_ATH9K_RATE_CONTROL
hw->rate_control_algorithm = "ath9k_rate_control";
+#endif
- if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&sc->sbands[IEEE80211_BAND_2GHZ];
- if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&sc->sbands[IEEE80211_BAND_5GHZ];
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
- if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
- if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
}
@@ -751,6 +779,12 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
{
int i = 0;
+ if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
+ kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
+
+ if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
+ kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
+
if ((sc->btcoex.no_stomp_timer) &&
sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index e955bb9d98cb..8c13479b17cd 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -40,7 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -492,8 +491,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
REG_WRITE(ah, AR_DMISC(q),
AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
- REGWRITE_BUFFER_FLUSH(ah);
-
if (qi->tqi_cbrPeriod) {
REG_WRITE(ah, AR_QCBRCFG(q),
SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
@@ -509,8 +506,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
AR_Q_RDYTIMECFG_EN);
}
- REGWRITE_BUFFER_FLUSH(ah);
-
REG_WRITE(ah, AR_DCHNTIME(q),
SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
(qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
@@ -530,7 +525,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
REG_WRITE(ah, AR_DMISC(q),
@@ -553,7 +547,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
| AR_D_MISC_POST_FR_BKOFF_DIS);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
/*
* cwmin and cwmax should be 0 for beacon queue
@@ -585,7 +578,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
break;
case ATH9K_TX_QUEUE_PSPOLL:
@@ -711,8 +703,11 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
rs->rs_phyerr = phyerr;
} else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
rs->rs_status |= ATH9K_RXERR_DECRYPT;
- else if (ads.ds_rxstatus8 & AR_MichaelErr)
+ else if ((ads.ds_rxstatus8 & AR_MichaelErr) &&
+ rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
rs->rs_status |= ATH9K_RXERR_MIC;
+ else if (ads.ds_rxstatus8 & AR_KeyMiss)
+ rs->rs_status |= ATH9K_RXERR_DECRYPT;
}
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 2633896d3998..7c1a34d64f6d 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -660,17 +660,6 @@ struct ath9k_11n_rate_series {
u32 RateFlags;
};
-struct ath9k_keyval {
- u8 kv_type;
- u8 kv_pad;
- u16 kv_len;
- u8 kv_val[16]; /* TK */
- u8 kv_mic[8]; /* Michael MIC key */
- u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
- * supports both MIC keys in the same key cache entry;
- * in that case, kv_mic is the RX key) */
-};
-
enum ath9k_key_type {
ATH9K_KEY_TYPE_CLEAR,
ATH9K_KEY_TYPE_WEP,
@@ -678,16 +667,6 @@ enum ath9k_key_type {
ATH9K_KEY_TYPE_TKIP,
};
-enum ath9k_cipher {
- ATH9K_CIPHER_WEP = 0,
- ATH9K_CIPHER_AES_OCB = 1,
- ATH9K_CIPHER_AES_CCM = 2,
- ATH9K_CIPHER_CKIP = 3,
- ATH9K_CIPHER_TKIP = 4,
- ATH9K_CIPHER_CLR = 5,
- ATH9K_CIPHER_MIC = 127
-};
-
struct ath_hw;
struct ath9k_channel;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3caa32316e7b..3ff0e476c2b3 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -18,36 +18,6 @@
#include "ath9k.h"
#include "btcoex.h"
-static void ath_cache_conf_rate(struct ath_softc *sc,
- struct ieee80211_conf *conf)
-{
- switch (conf->channel->band) {
- case IEEE80211_BAND_2GHZ:
- if (conf_is_ht20(conf))
- sc->cur_rate_mode = ATH9K_MODE_11NG_HT20;
- else if (conf_is_ht40_minus(conf))
- sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS;
- else if (conf_is_ht40_plus(conf))
- sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS;
- else
- sc->cur_rate_mode = ATH9K_MODE_11G;
- break;
- case IEEE80211_BAND_5GHZ:
- if (conf_is_ht20(conf))
- sc->cur_rate_mode = ATH9K_MODE_11NA_HT20;
- else if (conf_is_ht40_minus(conf))
- sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS;
- else if (conf_is_ht40_plus(conf))
- sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS;
- else
- sc->cur_rate_mode = ATH9K_MODE_11A;
- break;
- default:
- BUG_ON(1);
- break;
- }
-}
-
static void ath_update_txpow(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
@@ -121,6 +91,7 @@ bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
void ath9k_ps_wakeup(struct ath_softc *sc)
{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
unsigned long flags;
spin_lock_irqsave(&sc->sc_pm_lock, flags);
@@ -129,18 +100,33 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+ /*
+ * While the hardware is asleep, the cycle counters contain no
+ * useful data. Better clear them now so that they don't mess up
+ * survey data results.
+ */
+ spin_lock(&common->cc_lock);
+ ath_hw_cycle_counters_update(common);
+ memset(&common->cc_survey, 0, sizeof(common->cc_survey));
+ spin_unlock(&common->cc_lock);
+
unlock:
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
}
void ath9k_ps_restore(struct ath_softc *sc)
{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
unsigned long flags;
spin_lock_irqsave(&sc->sc_pm_lock, flags);
if (--sc->ps_usecount != 0)
goto unlock;
+ spin_lock(&common->cc_lock);
+ ath_hw_cycle_counters_update(common);
+ spin_unlock(&common->cc_lock);
+
if (sc->ps_idle)
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
else if (sc->ps_enabled &&
@@ -175,6 +161,45 @@ static void ath_start_ani(struct ath_common *common)
msecs_to_jiffies((u32)ah->config.ani_poll_interval));
}
+static void ath_update_survey_nf(struct ath_softc *sc, int channel)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath9k_channel *chan = &ah->channels[channel];
+ struct survey_info *survey = &sc->survey[channel];
+
+ if (chan->noisefloor) {
+ survey->filled |= SURVEY_INFO_NOISE_DBM;
+ survey->noise = chan->noisefloor;
+ }
+}
+
+static void ath_update_survey_stats(struct ath_softc *sc)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ int pos = ah->curchan - &ah->channels[0];
+ struct survey_info *survey = &sc->survey[pos];
+ struct ath_cycle_counters *cc = &common->cc_survey;
+ unsigned int div = common->clockrate * 1000;
+
+ if (ah->power_mode == ATH9K_PM_AWAKE)
+ ath_hw_cycle_counters_update(common);
+
+ if (cc->cycles > 0) {
+ survey->filled |= SURVEY_INFO_CHANNEL_TIME |
+ SURVEY_INFO_CHANNEL_TIME_BUSY |
+ SURVEY_INFO_CHANNEL_TIME_RX |
+ SURVEY_INFO_CHANNEL_TIME_TX;
+ survey->channel_time += cc->cycles / div;
+ survey->channel_time_busy += cc->rx_busy / div;
+ survey->channel_time_rx += cc->rx_frame / div;
+ survey->channel_time_tx += cc->tx_frame / div;
+ }
+ memset(cc, 0, sizeof(*cc));
+
+ ath_update_survey_nf(sc, pos);
+}
+
/*
* Set/change channels. If the channel is really being changed, it's done
* by reseting the chip. To accomplish this we must first cleanup any pending
@@ -226,9 +251,10 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
caldata = &aphy->caldata;
ath_print(common, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n",
+ "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
sc->sc_ah->curchan->channel,
- channel->center_freq, conf_is_ht40(conf));
+ channel->center_freq, conf_is_ht40(conf),
+ fastcc);
spin_lock_bh(&sc->sc_resetlock);
@@ -250,14 +276,13 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
goto ps_restore;
}
- ath_cache_conf_rate(sc, &hw->conf);
ath_update_txpow(sc);
ath9k_hw_set_interrupts(ah, ah->imask);
- if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) {
- ath_start_ani(common);
- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
+ if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
ath_beacon_config(sc, NULL);
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
+ ath_start_ani(common);
}
ps_restore:
@@ -269,6 +294,7 @@ static void ath_paprd_activate(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
struct ath9k_hw_cal_data *caldata = ah->caldata;
+ struct ath_common *common = ath9k_hw_common(ah);
int chain;
if (!caldata || !caldata->paprd_done)
@@ -277,7 +303,7 @@ static void ath_paprd_activate(struct ath_softc *sc)
ath9k_ps_wakeup(sc);
ar9003_paprd_enable(ah, false);
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
- if (!(ah->caps.tx_chainmask & BIT(chain)))
+ if (!(common->tx_chainmask & BIT(chain)))
continue;
ar9003_paprd_populate_single_table(ah, caldata, chain);
@@ -299,6 +325,7 @@ void ath_paprd_calibrate(struct work_struct *work)
struct ieee80211_supported_band *sband = &sc->sbands[band];
struct ath_tx_control txctl;
struct ath9k_hw_cal_data *caldata = ah->caldata;
+ struct ath_common *common = ath9k_hw_common(ah);
int qnum, ftype;
int chain_ok = 0;
int chain;
@@ -332,7 +359,7 @@ void ath_paprd_calibrate(struct work_struct *work)
ath9k_ps_wakeup(sc);
ar9003_paprd_init_table(ah);
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
- if (!(ah->caps.tx_chainmask & BIT(chain)))
+ if (!(common->tx_chainmask & BIT(chain)))
continue;
chain_ok = 0;
@@ -395,7 +422,13 @@ void ath_ani_calibrate(unsigned long data)
bool shortcal = false;
bool aniflag = false;
unsigned int timestamp = jiffies_to_msecs(jiffies);
- u32 cal_interval, short_cal_interval;
+ u32 cal_interval, short_cal_interval, long_cal_interval;
+ unsigned long flags;
+
+ if (ah->caldata && ah->caldata->nfcal_interference)
+ long_cal_interval = ATH_LONG_CALINTERVAL_INT;
+ else
+ long_cal_interval = ATH_LONG_CALINTERVAL;
short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
@@ -407,7 +440,7 @@ void ath_ani_calibrate(unsigned long data)
ath9k_ps_wakeup(sc);
/* Long calibration runs independently of short calibration. */
- if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
+ if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
longcal = true;
ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
common->ani.longcal_timer = timestamp;
@@ -441,8 +474,12 @@ void ath_ani_calibrate(unsigned long data)
/* Skip all processing if there's nothing to do. */
if (longcal || shortcal || aniflag) {
/* Call ANI routine if necessary */
- if (aniflag)
+ if (aniflag) {
+ spin_lock_irqsave(&common->cc_lock, flags);
ath9k_hw_ani_monitor(ah, ah->curchan);
+ ath_update_survey_stats(sc);
+ spin_unlock_irqrestore(&common->cc_lock, flags);
+ }
/* Perform calibration if necessary */
if (longcal || shortcal) {
@@ -451,16 +488,6 @@ void ath_ani_calibrate(unsigned long data)
ah->curchan,
common->rx_chainmask,
longcal);
-
- if (longcal)
- common->ani.noise_floor = ath9k_hw_getchan_noise(ah,
- ah->curchan);
-
- ath_print(common, ATH_DBG_ANI,
- " calibrate chan %u/%x nf: %d\n",
- ah->curchan->channel,
- ah->curchan->channelFlags,
- common->ani.noise_floor);
}
}
@@ -637,6 +664,7 @@ irqreturn_t ath_isr(int irq, void *dev)
struct ath_softc *sc = dev;
struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
enum ath9k_int status;
bool sched = false;
@@ -686,7 +714,12 @@ irqreturn_t ath_isr(int irq, void *dev)
if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
(status & ATH9K_INT_BB_WATCHDOG)) {
+
+ spin_lock(&common->cc_lock);
+ ath_hw_cycle_counters_update(common);
ar9003_hw_bb_watchdog_dbg_info(ah);
+ spin_unlock(&common->cc_lock);
+
goto chip_reset;
}
@@ -715,7 +748,9 @@ irqreturn_t ath_isr(int irq, void *dev)
* it will clear whatever condition caused
* the interrupt.
*/
- ath9k_hw_procmibevent(ah);
+ spin_lock(&common->cc_lock);
+ ath9k_hw_proc_mib_event(ah);
+ spin_unlock(&common->cc_lock);
ath9k_hw_set_interrupts(ah, ah->imask);
}
@@ -947,11 +982,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
* that changes the channel so update any state that
* might change as a result.
*/
- ath_cache_conf_rate(sc, &hw->conf);
-
ath_update_txpow(sc);
- if (sc->sc_flags & SC_OP_BEACONS)
+ if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
ath_beacon_config(sc, NULL); /* restart beacons */
ath9k_hw_set_interrupts(ah, ah->imask);
@@ -1150,14 +1183,11 @@ static int ath9k_start(struct ieee80211_hw *hw)
else
ah->imask |= ATH9K_INT_RX;
- if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
- ah->imask |= ATH9K_INT_GTT;
+ ah->imask |= ATH9K_INT_GTT;
if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
ah->imask |= ATH9K_INT_CST;
- ath_cache_conf_rate(sc, &hw->conf);
-
sc->sc_flags &= ~SC_OP_INVALID;
/* Disable BMISS interrupt when we're not associated */
@@ -1373,16 +1403,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);
- if (!(ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
- sc->nvifs > 0) {
- ret = -ENOBUFS;
- goto out;
- }
-
switch (vif->type) {
case NL80211_IFTYPE_STATION:
ic_opmode = NL80211_IFTYPE_STATION;
break;
+ case NL80211_IFTYPE_WDS:
+ ic_opmode = NL80211_IFTYPE_WDS;
+ break;
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_MESH_POINT:
@@ -1408,8 +1435,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
sc->nvifs++;
- if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- ath9k_set_bssid_mask(hw);
+ ath9k_set_bssid_mask(hw, vif);
if (sc->nvifs > 1)
goto out; /* skip global settings for secondary vif */
@@ -1491,7 +1517,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
mutex_unlock(&sc->mutex);
}
-void ath9k_enable_ps(struct ath_softc *sc)
+static void ath9k_enable_ps(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
@@ -1505,13 +1531,33 @@ void ath9k_enable_ps(struct ath_softc *sc)
}
}
+static void ath9k_disable_ps(struct ath_softc *sc)
+{
+ struct ath_hw *ah = sc->sc_ah;
+
+ sc->ps_enabled = false;
+ ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
+ if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+ ath9k_hw_setrxabort(ah, 0);
+ sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
+ PS_WAIT_FOR_CAB |
+ PS_WAIT_FOR_PSPOLL_DATA |
+ PS_WAIT_FOR_TX_ACK);
+ if (ah->imask & ATH9K_INT_TIM_TIMER) {
+ ah->imask &= ~ATH9K_INT_TIM_TIMER;
+ ath9k_hw_set_interrupts(ah, ah->imask);
+ }
+ }
+
+}
+
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ieee80211_conf *conf = &hw->conf;
struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_conf *conf = &hw->conf;
bool disable_radio;
mutex_lock(&sc->mutex);
@@ -1556,35 +1602,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
* IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode.
*/
if (changed & IEEE80211_CONF_CHANGE_PS) {
- if (conf->flags & IEEE80211_CONF_PS) {
- sc->ps_flags |= PS_ENABLED;
- /*
- * At this point we know hardware has received an ACK
- * of a previously sent null data frame.
- */
- if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) {
- sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
- ath9k_enable_ps(sc);
- }
- } else {
- sc->ps_enabled = false;
- sc->ps_flags &= ~(PS_ENABLED |
- PS_NULLFUNC_COMPLETED);
- ath9k_setpower(sc, ATH9K_PM_AWAKE);
- if (!(ah->caps.hw_caps &
- ATH9K_HW_CAP_AUTOSLEEP)) {
- ath9k_hw_setrxabort(sc->sc_ah, 0);
- sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
- PS_WAIT_FOR_CAB |
- PS_WAIT_FOR_PSPOLL_DATA |
- PS_WAIT_FOR_TX_ACK);
- if (ah->imask & ATH9K_INT_TIM_TIMER) {
- ah->imask &= ~ATH9K_INT_TIM_TIMER;
- ath9k_hw_set_interrupts(sc->sc_ah,
- ah->imask);
- }
- }
- }
+ unsigned long flags;
+ spin_lock_irqsave(&sc->sc_pm_lock, flags);
+ if (conf->flags & IEEE80211_CONF_PS)
+ ath9k_enable_ps(sc);
+ else
+ ath9k_disable_ps(sc);
+ spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
}
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
@@ -1598,6 +1622,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
struct ieee80211_channel *curchan = hw->conf.channel;
int pos = curchan->hw_value;
+ int old_pos = -1;
+ unsigned long flags;
+
+ if (ah->curchan)
+ old_pos = ah->curchan - &ah->channels[0];
aphy->chan_idx = pos;
aphy->chan_is_ht = conf_is_ht(conf);
@@ -1625,12 +1654,45 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
ath_update_chainmask(sc, conf_is_ht(conf));
+ /* update survey stats for the old channel before switching */
+ spin_lock_irqsave(&common->cc_lock, flags);
+ ath_update_survey_stats(sc);
+ spin_unlock_irqrestore(&common->cc_lock, flags);
+
+ /*
+ * If the operating channel changes, change the survey in-use flags
+ * along with it.
+ * Reset the survey data for the new channel, unless we're switching
+ * back to the operating channel from an off-channel operation.
+ */
+ if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
+ sc->cur_survey != &sc->survey[pos]) {
+
+ if (sc->cur_survey)
+ sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
+
+ sc->cur_survey = &sc->survey[pos];
+
+ memset(sc->cur_survey, 0, sizeof(struct survey_info));
+ sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
+ } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
+ memset(&sc->survey[pos], 0, sizeof(struct survey_info));
+ }
+
if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
ath_print(common, ATH_DBG_FATAL,
"Unable to set channel\n");
mutex_unlock(&sc->mutex);
return -EINVAL;
}
+
+ /*
+ * The most recent snapshot of channel->noisefloor for the old
+ * channel is only available after the hardware reset. Copy it to
+ * the survey stats now.
+ */
+ if (old_pos >= 0)
+ ath_update_survey_nf(sc, old_pos);
}
skip_chan_change:
@@ -1661,6 +1723,7 @@ skip_chan_change:
FIF_PSPOLL | \
FIF_OTHER_BSS | \
FIF_BCN_PRBRESP_PROMISC | \
+ FIF_PROBE_REQ | \
FIF_FCSFAIL)
/* FIXME: sc->sc_full_reset ? */
@@ -1771,20 +1834,21 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
switch (cmd) {
case SET_KEY:
- ret = ath9k_cmn_key_config(common, vif, sta, key);
+ ret = ath_key_config(common, vif, sta, key);
if (ret >= 0) {
key->hw_key_idx = ret;
/* push IV and Michael MIC generation to stack */
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- if (key->alg == ALG_TKIP)
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+ if (sc->sc_ah->sw_mgmt_crypto &&
+ key->cipher == WLAN_CIPHER_SUITE_CCMP)
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
ret = 0;
}
break;
case DISABLE_KEY:
- ath9k_cmn_key_delete(common, key);
+ ath_key_delete(common, key);
break;
default:
ret = -EINVAL;
@@ -1968,8 +2032,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
break;
case IEEE80211_AMPDU_TX_START:
ath9k_ps_wakeup(sc);
- ath_tx_aggr_start(sc, sta, tid, ssn);
- ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ ret = ath_tx_aggr_start(sc, sta, tid, ssn);
+ if (!ret)
+ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
ath9k_ps_restore(sc);
break;
case IEEE80211_AMPDU_TX_STOP:
@@ -1998,16 +2063,35 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_conf *conf = &hw->conf;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *chan;
+ unsigned long flags;
+ int pos;
- if (idx != 0)
+ spin_lock_irqsave(&common->cc_lock, flags);
+ if (idx == 0)
+ ath_update_survey_stats(sc);
+
+ sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
+ if (sband && idx >= sband->n_channels) {
+ idx -= sband->n_channels;
+ sband = NULL;
+ }
+
+ if (!sband)
+ sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
+
+ if (!sband || idx >= sband->n_channels) {
+ spin_unlock_irqrestore(&common->cc_lock, flags);
return -ENOENT;
+ }
- survey->channel = conf->channel;
- survey->filled = SURVEY_INFO_NOISE_DBM;
- survey->noise = common->ani.noise_floor;
+ chan = &sband->channels[idx];
+ pos = chan->hw_value;
+ memcpy(survey, &sc->survey[pos], sizeof(*survey));
+ survey->channel = chan;
+ spin_unlock_irqrestore(&common->cc_lock, flags);
return 0;
}
@@ -2032,7 +2116,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
aphy->state = ATH_WIPHY_SCAN;
ath9k_wiphy_pause_all_forced(sc, aphy);
- sc->sc_flags |= SC_OP_SCANNING;
mutex_unlock(&sc->mutex);
}
@@ -2047,7 +2130,6 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
mutex_lock(&sc->mutex);
aphy->state = ATH_WIPHY_ACTIVE;
- sc->sc_flags &= ~SC_OP_SCANNING;
mutex_unlock(&sc->mutex);
}
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index e724c2c1ae2a..17969af842f6 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -45,9 +45,6 @@
} \
} while (0)
-#define ATH9K_IS_MIC_ENABLED(ah) \
- ((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
-
#define ANTSWAP_AB 0x0001
#define REDUCE_CHAIN_0 0x00000050
#define REDUCE_CHAIN_1 0x00000051
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index e49be733d546..0cee90cf8dc9 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -302,7 +302,7 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
[64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */
[65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
- 224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */
+ 224700, 20, 20, 8, 64, 65, 65 }, /* 270 Mb */
[66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */
[67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
@@ -378,17 +378,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
0, /* Phy rates allowed initially */
};
-static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = {
- [ATH9K_MODE_11A] = &ar5416_11a_ratetable,
- [ATH9K_MODE_11G] = &ar5416_11g_ratetable,
- [ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable,
- [ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable,
- [ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable,
- [ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable,
- [ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable,
- [ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable,
-};
-
static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate);
@@ -791,7 +780,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
*/
try_per_rate = 4;
- rate_table = sc->cur_rate_table;
+ rate_table = ath_rc_priv->rate_table;
rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
/*
@@ -1026,6 +1015,16 @@ 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,
+ int xretries, int retries, u8 per)
+{
+ struct ath_rc_stats *stats = &rc->rcstats[rix];
+
+ stats->xretries += xretries;
+ stats->retries += retries;
+ stats->per = per;
+}
+
/* Update PER, RSSI and whatever else that the code thinks it is doing.
If you can make sense of all this, you really need to go out more. */
@@ -1038,7 +1037,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
int rate;
u8 last_per;
bool state_change = false;
- const struct ath_rate_table *rate_table = sc->cur_rate_table;
+ const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
int size = ath_rc_priv->rate_table_size;
if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
@@ -1098,7 +1097,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
ath_rc_priv->per_down_time = now_msec;
}
- ath_debug_stat_retries(sc, tx_rate, xretries, retries,
+ ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries,
ath_rc_priv->per[tx_rate]);
}
@@ -1140,7 +1139,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
u8 flags;
u32 i = 0, rix;
- rate_table = sc->cur_rate_table;
+ rate_table = ath_rc_priv->rate_table;
/*
* If the first rate is not the final index, there
@@ -1190,39 +1189,23 @@ static void ath_rc_tx_status(struct ath_softc *sc,
static const
struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
enum ieee80211_band band,
- bool is_ht,
- bool is_cw_40)
+ bool is_ht)
{
- int mode = 0;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
switch(band) {
case IEEE80211_BAND_2GHZ:
- mode = ATH9K_MODE_11G;
if (is_ht)
- mode = ATH9K_MODE_11NG_HT20;
- if (is_cw_40)
- mode = ATH9K_MODE_11NG_HT40PLUS;
- break;
+ return &ar5416_11ng_ratetable;
+ return &ar5416_11g_ratetable;
case IEEE80211_BAND_5GHZ:
- mode = ATH9K_MODE_11A;
if (is_ht)
- mode = ATH9K_MODE_11NA_HT20;
- if (is_cw_40)
- mode = ATH9K_MODE_11NA_HT40PLUS;
- break;
+ return &ar5416_11na_ratetable;
+ return &ar5416_11a_ratetable;
default:
ath_print(common, ATH_DBG_CONFIG, "Invalid band\n");
return NULL;
}
-
- BUG_ON(mode >= ATH9K_MODE_MAX);
-
- ath_print(common, ATH_DBG_CONFIG,
- "Choosing rate table for mode: %d\n", mode);
-
- sc->cur_rate_mode = mode;
- return hw_rate_table[mode];
}
static void ath_rc_init(struct ath_softc *sc,
@@ -1293,7 +1276,7 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_priv->max_valid_rate = k;
ath_rc_sort_validrates(rate_table, ath_rc_priv);
ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
- sc->cur_rate_table = rate_table;
+ ath_rc_priv->rate_table = rate_table;
ath_print(common, ATH_DBG_CONFIG,
"RC Initialized with capabilities: 0x%x\n",
@@ -1320,10 +1303,35 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
return caps;
}
+static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an,
+ u8 tidno)
+{
+ struct ath_atx_tid *txtid;
+
+ if (!(sc->sc_flags & SC_OP_TXAGGR))
+ return false;
+
+ txtid = ATH_AN_2_TID(an, tidno);
+
+ if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS)))
+ return true;
+ return false;
+}
+
+
/***********************************/
/* mac80211 Rate Control callbacks */
/***********************************/
+static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
+{
+ struct ath_rc_stats *stats;
+
+ stats = &rc->rcstats[final_rate];
+ stats->success++;
+}
+
+
static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb)
@@ -1359,6 +1367,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
return;
+ if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) {
+ tx_info->status.ampdu_ack_len =
+ (tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
+ tx_info->status.ampdu_len = 1;
+ }
+
/*
* If an underrun error is seen assume it as an excessive retry only
* if max frame trigger level has been reached (2 KB for singel stream,
@@ -1397,8 +1411,9 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
}
}
- ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table,
- &tx_info->status.rates[final_ts_idx]));
+ ath_debug_stat_rc(ath_rc_priv,
+ ath_rc_get_rateindex(ath_rc_priv->rate_table,
+ &tx_info->status.rates[final_ts_idx]));
}
static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1438,14 +1453,8 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
/* Choose rate table first */
- if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
- (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
- (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
- rate_table = ath_choose_rate_table(sc, sband->band,
- sta->ht_cap.ht_supported, is_cw40);
- } else {
- rate_table = hw_rate_table[sc->cur_rate_mode];
- }
+ rate_table = ath_choose_rate_table(sc, sband->band,
+ sta->ht_cap.ht_supported);
ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi);
ath_rc_init(sc, priv_sta, sband, sta, rate_table);
@@ -1485,8 +1494,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) {
rate_table = ath_choose_rate_table(sc, sband->band,
- sta->ht_cap.ht_supported,
- oper_cw40);
+ sta->ht_cap.ht_supported);
ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
oper_cw40, oper_sgi);
ath_rc_init(sc, priv_sta, sband, sta, rate_table);
@@ -1494,11 +1502,98 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
"Operating HT Bandwidth changed to: %d\n",
sc->hw->conf.channel_type);
- sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode];
}
}
}
+#ifdef CONFIG_ATH9K_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_rcstat(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_rate_priv *rc = file->private_data;
+ char *buf;
+ unsigned int len = 0, max;
+ int i = 0;
+ ssize_t retval;
+
+ if (rc->rate_table == NULL)
+ return 0;
+
+ max = 80 + rc->rate_table->rate_cnt * 1024 + 1;
+ buf = kmalloc(max, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ len += sprintf(buf, "%6s %6s %6s "
+ "%10s %10s %10s %10s\n",
+ "HT", "MCS", "Rate",
+ "Success", "Retries", "XRetries", "PER");
+
+ for (i = 0; i < rc->rate_table->rate_cnt; i++) {
+ u32 ratekbps = rc->rate_table->info[i].ratekbps;
+ struct ath_rc_stats *stats = &rc->rcstats[i];
+ char mcs[5];
+ char htmode[5];
+ int used_mcs = 0, used_htmode = 0;
+
+ if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) {
+ used_mcs = snprintf(mcs, 5, "%d",
+ rc->rate_table->info[i].ratecode);
+
+ if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy))
+ used_htmode = snprintf(htmode, 5, "HT40");
+ else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy))
+ used_htmode = snprintf(htmode, 5, "HT20");
+ else
+ used_htmode = snprintf(htmode, 5, "????");
+ }
+
+ mcs[used_mcs] = '\0';
+ htmode[used_htmode] = '\0';
+
+ len += snprintf(buf + len, max - len,
+ "%6s %6s %3u.%d: "
+ "%10u %10u %10u %10u\n",
+ htmode,
+ mcs,
+ ratekbps / 1000,
+ (ratekbps % 1000) / 100,
+ stats->success,
+ stats->retries,
+ stats->xretries,
+ stats->per);
+ }
+
+ if (len > max)
+ len = max;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+ return retval;
+}
+
+static const struct file_operations fops_rcstat = {
+ .read = read_file_rcstat,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE
+};
+
+static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta,
+ struct dentry *dir)
+{
+ struct ath_rate_priv *rc = priv_sta;
+ debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat);
+}
+
+#endif /* CONFIG_ATH9K_DEBUGFS */
+
static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
{
struct ath_wiphy *aphy = hw->priv;
@@ -1545,6 +1640,9 @@ static struct rate_control_ops ath_rate_ops = {
.free = ath_rate_free,
.alloc_sta = ath_rate_alloc_sta,
.free_sta = ath_rate_free_sta,
+#ifdef CONFIG_ATH9K_DEBUGFS
+ .add_sta_debugfs = ath_rate_add_sta_debugfs,
+#endif
};
int ath_rate_control_register(void)
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index dc1082654501..2f46a2266ba1 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -135,20 +135,21 @@ enum {
/**
* struct ath_rate_table - Rate Control table
- * @valid: valid for use in rate control
- * @valid_single_stream: valid for use in rate control for
- * single stream operation
- * @phy: CCK/OFDM
+ * @rate_cnt: total number of rates for the given wireless mode
+ * @mcs_start: MCS rate index offset
+ * @rate_flags: Rate Control flags
+ * @phy: CCK/OFDM/HT20/HT40
* @ratekbps: rate in Kbits per second
* @user_ratekbps: user rate in Kbits per second
* @ratecode: rate that goes into HW descriptors
- * @short_preamble: Mask for enabling short preamble in ratecode for CCK
* @dot11rate: value that goes into supported
* rates info element of MLME
* @ctrl_rate: Index of next lower basic rate, used for duration computation
- * @max_4ms_framelen: maximum frame length(bytes) for tx duration
+ * @cw40index: Index of rates having 40MHz channel width
+ * @sgi_index: Index of rates having Short Guard Interval
+ * @ht_index: high throughput rates having 40MHz channel width and
+ * Short Guard Interval
* @probe_interval: interval for rate control to probe for other rates
- * @rssi_reduce_interval: interval for rate control to reduce rssi
* @initial_ratemax: initial ratemax value
*/
struct ath_rate_table {
@@ -175,6 +176,13 @@ struct ath_rateset {
u8 rs_rates[ATH_RATE_MAX];
};
+struct ath_rc_stats {
+ u32 success;
+ u32 retries;
+ u32 xretries;
+ u8 per;
+};
+
/**
* struct ath_rate_priv - Rate Control priv data
* @state: RC state
@@ -211,6 +219,10 @@ struct ath_rate_priv {
struct ath_rateset neg_rates;
struct ath_rateset neg_ht_rates;
struct ath_rate_softc *asc;
+ const struct ath_rate_table *rate_table;
+
+ struct dentry *debugfs_rcstats;
+ struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
};
#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0)
@@ -224,7 +236,18 @@ enum ath9k_internal_frame_type {
ATH9K_IFT_UNPAUSE
};
+#ifdef CONFIG_ATH9K_RATE_CONTROL
int ath_rate_control_register(void);
void ath_rate_control_unregister(void);
+#else
+static inline int ath_rate_control_register(void)
+{
+ return 0;
+}
+
+static inline void ath_rate_control_unregister(void)
+{
+}
+#endif
#endif /* RC_H */
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index a3fc987ebab0..fe73fc50082a 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -19,6 +19,15 @@
#define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb))
+static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta,
+ int mindelta, int main_rssi_avg,
+ int alt_rssi_avg, int pkt_count)
+{
+ return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
+ (alt_rssi_avg > main_rssi_avg + maxdelta)) ||
+ (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
+}
+
static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
{
return sc->ps_enabled &&
@@ -110,8 +119,7 @@ static void ath_opmode_init(struct ath_softc *sc)
ath9k_hw_setrxfilter(ah, rfilt);
/* configure bssid mask */
- if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- ath_hw_setbssidmask(common);
+ ath_hw_setbssidmask(common);
/* configure operational mode */
ath9k_hw_setopmode(ah);
@@ -260,6 +268,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
+ bf->bf_buf_addr = 0;
ath_print(common, ATH_DBG_FATAL,
"dma_mapping_error() on RX init\n");
error = -ENOMEM;
@@ -292,7 +301,7 @@ static void ath_edma_start_recv(struct ath_softc *sc)
ath_opmode_init(sc);
- ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING));
+ ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
}
static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -350,12 +359,12 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
+ bf->bf_buf_addr = 0;
ath_print(common, ATH_DBG_FATAL,
"dma_mapping_error() on RX init\n");
error = -ENOMEM;
goto err;
}
- bf->bf_dmacontext = bf->bf_buf_addr;
}
sc->rx.rxlink = NULL;
}
@@ -385,6 +394,8 @@ void ath_rx_cleanup(struct ath_softc *sc)
common->rx_bufsize,
DMA_FROM_DEVICE);
dev_kfree_skb(skb);
+ bf->bf_buf_addr = 0;
+ bf->bf_mpdu = NULL;
}
}
@@ -422,8 +433,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
| ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
| ATH9K_RX_FILTER_MCAST;
- /* If not a STA, enable processing of Probe Requests */
- if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+ if (sc->rx.rxfilter & FIF_PROBE_REQ)
rfilt |= ATH9K_RX_FILTER_PROBEREQ;
/*
@@ -440,13 +450,14 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
rfilt |= ATH9K_RX_FILTER_CONTROL;
if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
+ (sc->nvifs <= 1) &&
!(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC))
rfilt |= ATH9K_RX_FILTER_MYBEACON;
else
rfilt |= ATH9K_RX_FILTER_BEACON;
- if ((AR_SREV_9280_10_OR_LATER(sc->sc_ah) ||
- AR_SREV_9285_10_OR_LATER(sc->sc_ah)) &&
+ 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) &&
(sc->rx.rxfilter & FIF_PSPOLL))
rfilt |= ATH9K_RX_FILTER_PSPOLL;
@@ -454,9 +465,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
if (conf_is_ht(&sc->hw->conf))
rfilt |= ATH9K_RX_FILTER_COMP_BAR;
- if (sc->sec_wiphy || (sc->rx.rxfilter & FIF_OTHER_BSS)) {
- /* TODO: only needed if more than one BSSID is in use in
- * station/adhoc mode */
+ if (sc->sec_wiphy || (sc->nvifs > 1) ||
+ (sc->rx.rxfilter & FIF_OTHER_BSS)) {
/* The following may also be needed for other older chips */
if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160)
rfilt |= ATH9K_RX_FILTER_PROM;
@@ -498,7 +508,7 @@ int ath_startrecv(struct ath_softc *sc)
start_recv:
spin_unlock_bh(&sc->rx.rxbuflock);
ath_opmode_init(sc);
- ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING));
+ ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
return 0;
}
@@ -631,7 +641,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
* No more broadcast/multicast frames to be received at this
* point.
*/
- sc->ps_flags &= ~PS_WAIT_FOR_CAB;
+ sc->ps_flags &= ~(PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON);
ath_print(common, ATH_DBG_PS,
"All PS CAB frames received, back to sleep\n");
} else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) &&
@@ -870,15 +880,18 @@ static bool ath9k_rx_accept(struct ath_common *common,
if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
*decrypt_error = true;
} else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
- if (ieee80211_is_ctl(fc))
- /*
- * Sometimes, we get invalid
- * MIC failures on valid control frames.
- * Remove these mic errors.
- */
- rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
- else
+ /*
+ * The MIC error bit is only valid if the frame
+ * is not a control frame or fragment, and it was
+ * decrypted using a valid TKIP key.
+ */
+ if (!ieee80211_is_ctl(fc) &&
+ !ieee80211_has_morefrags(fc) &&
+ !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
+ test_bit(rx_stats->rs_keyix, common->tkip_keymap))
rxs->flag |= RX_FLAG_MMIC_ERROR;
+ else
+ rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
}
/*
* Reject error frames with the exception of
@@ -966,7 +979,11 @@ static void ath9k_process_rssi(struct ath_common *common,
* at least one sdata of a wiphy on mac80211 but with ath9k virtual
* wiphy you'd have to iterate over every wiphy and each sdata.
*/
- sta = ieee80211_find_sta_by_hw(hw, hdr->addr2);
+ if (is_multicast_ether_addr(hdr->addr1))
+ sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
+ else
+ sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1);
+
if (sta) {
an = (struct ath_node *) sta->drv_priv;
if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
@@ -1073,6 +1090,539 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common,
rxs->flag &= ~RX_FLAG_DECRYPTED;
}
+static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb,
+ struct ath_hw_antcomb_conf ant_conf,
+ int main_rssi_avg)
+{
+ antcomb->quick_scan_cnt = 0;
+
+ if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
+ antcomb->rssi_lna2 = main_rssi_avg;
+ else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1)
+ antcomb->rssi_lna1 = main_rssi_avg;
+
+ switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) {
+ case (0x10): /* LNA2 A-B */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1;
+ break;
+ case (0x20): /* LNA1 A-B */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2;
+ break;
+ case (0x21): /* LNA1 LNA2 */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->second_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ break;
+ case (0x12): /* LNA2 LNA1 */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->second_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ break;
+ case (0x13): /* LNA2 A+B */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1;
+ break;
+ case (0x23): /* LNA1 A+B */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2;
+ break;
+ default:
+ break;
+ }
+}
+
+static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
+ struct ath_hw_antcomb_conf *div_ant_conf,
+ int main_rssi_avg, int alt_rssi_avg,
+ int alt_ratio)
+{
+ /* alt_good */
+ switch (antcomb->quick_scan_cnt) {
+ case 0:
+ /* set alt to main, and alt to first conf */
+ div_ant_conf->main_lna_conf = antcomb->main_conf;
+ div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf;
+ break;
+ case 1:
+ /* set alt to main, and alt to first conf */
+ div_ant_conf->main_lna_conf = antcomb->main_conf;
+ div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf;
+ antcomb->rssi_first = main_rssi_avg;
+ antcomb->rssi_second = alt_rssi_avg;
+
+ if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
+ /* main is LNA1 */
+ if (ath_is_alt_ant_ratio_better(alt_ratio,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
+ main_rssi_avg, alt_rssi_avg,
+ antcomb->total_pkt_count))
+ antcomb->first_ratio = true;
+ else
+ antcomb->first_ratio = false;
+ } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) {
+ if (ath_is_alt_ant_ratio_better(alt_ratio,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
+ main_rssi_avg, alt_rssi_avg,
+ antcomb->total_pkt_count))
+ antcomb->first_ratio = true;
+ else
+ antcomb->first_ratio = false;
+ } else {
+ if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
+ (alt_rssi_avg > main_rssi_avg +
+ ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) ||
+ (alt_rssi_avg > main_rssi_avg)) &&
+ (antcomb->total_pkt_count > 50))
+ antcomb->first_ratio = true;
+ else
+ antcomb->first_ratio = false;
+ }
+ break;
+ case 2:
+ antcomb->alt_good = false;
+ antcomb->scan_not_start = false;
+ antcomb->scan = false;
+ antcomb->rssi_first = main_rssi_avg;
+ antcomb->rssi_third = alt_rssi_avg;
+
+ if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1)
+ antcomb->rssi_lna1 = alt_rssi_avg;
+ else if (antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ antcomb->rssi_lna2 = alt_rssi_avg;
+ else if (antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) {
+ if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)
+ antcomb->rssi_lna2 = main_rssi_avg;
+ else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1)
+ antcomb->rssi_lna1 = main_rssi_avg;
+ }
+
+ if (antcomb->rssi_lna2 > antcomb->rssi_lna1 +
+ ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)
+ div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
+ else
+ div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
+
+ if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
+ if (ath_is_alt_ant_ratio_better(alt_ratio,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
+ main_rssi_avg, alt_rssi_avg,
+ antcomb->total_pkt_count))
+ antcomb->second_ratio = true;
+ else
+ antcomb->second_ratio = false;
+ } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) {
+ if (ath_is_alt_ant_ratio_better(alt_ratio,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
+ main_rssi_avg, alt_rssi_avg,
+ antcomb->total_pkt_count))
+ antcomb->second_ratio = true;
+ else
+ antcomb->second_ratio = false;
+ } else {
+ if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
+ (alt_rssi_avg > main_rssi_avg +
+ ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) ||
+ (alt_rssi_avg > main_rssi_avg)) &&
+ (antcomb->total_pkt_count > 50))
+ antcomb->second_ratio = true;
+ else
+ antcomb->second_ratio = false;
+ }
+
+ /* set alt to the conf with maximun ratio */
+ if (antcomb->first_ratio && antcomb->second_ratio) {
+ if (antcomb->rssi_second > antcomb->rssi_third) {
+ /* first alt*/
+ if ((antcomb->first_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA1) ||
+ (antcomb->first_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA2))
+ /* Set alt LNA1 or LNA2*/
+ if (div_ant_conf->main_lna_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ else
+ /* Set alt to A+B or A-B */
+ div_ant_conf->alt_lna_conf =
+ antcomb->first_quick_scan_conf;
+ } else if ((antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA1) ||
+ (antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA2)) {
+ /* Set alt LNA1 or LNA2 */
+ if (div_ant_conf->main_lna_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ } else {
+ /* Set alt to A+B or A-B */
+ div_ant_conf->alt_lna_conf =
+ antcomb->second_quick_scan_conf;
+ }
+ } else if (antcomb->first_ratio) {
+ /* first alt */
+ if ((antcomb->first_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA1) ||
+ (antcomb->first_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA2))
+ /* Set alt LNA1 or LNA2 */
+ if (div_ant_conf->main_lna_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ else
+ /* Set alt to A+B or A-B */
+ div_ant_conf->alt_lna_conf =
+ antcomb->first_quick_scan_conf;
+ } else if (antcomb->second_ratio) {
+ /* second alt */
+ if ((antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA1) ||
+ (antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA2))
+ /* Set alt LNA1 or LNA2 */
+ if (div_ant_conf->main_lna_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ else
+ /* Set alt to A+B or A-B */
+ div_ant_conf->alt_lna_conf =
+ antcomb->second_quick_scan_conf;
+ } else {
+ /* main is largest */
+ if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) ||
+ (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2))
+ /* Set alt LNA1 or LNA2 */
+ if (div_ant_conf->main_lna_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ else
+ /* Set alt to A+B or A-B */
+ div_ant_conf->alt_lna_conf = antcomb->main_conf;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf)
+{
+ /* 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;
+ }
+}
+
+/* Antenna diversity and combining */
+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 main_rssi = rs->rs_rssi_ctl0;
+ int alt_rssi = rs->rs_rssi_ctl1;
+ int rx_ant_conf, main_ant_conf;
+ bool short_scan = false;
+
+ rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
+ ATH_ANT_RX_MASK;
+ 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) {
+ antcomb->total_pkt_count++;
+ antcomb->main_total_rssi += main_rssi;
+ antcomb->alt_total_rssi += alt_rssi;
+ if (main_ant_conf == rx_ant_conf)
+ antcomb->main_recv_cnt++;
+ else
+ antcomb->alt_recv_cnt++;
+ }
+
+ /* Short scan check */
+ if (antcomb->scan && antcomb->alt_good) {
+ if (time_after(jiffies, antcomb->scan_start_time +
+ msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR)))
+ short_scan = true;
+ else
+ if (antcomb->total_pkt_count ==
+ ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) {
+ alt_ratio = ((antcomb->alt_recv_cnt * 100) /
+ antcomb->total_pkt_count);
+ if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
+ short_scan = true;
+ }
+ }
+
+ if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) ||
+ rs->rs_moreaggr) && !short_scan)
+ return;
+
+ if (antcomb->total_pkt_count) {
+ alt_ratio = ((antcomb->alt_recv_cnt * 100) /
+ antcomb->total_pkt_count);
+ main_rssi_avg = (antcomb->main_total_rssi /
+ antcomb->total_pkt_count);
+ alt_rssi_avg = (antcomb->alt_total_rssi /
+ antcomb->total_pkt_count);
+ }
+
+
+ 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++;
+
+ if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) {
+ if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
+ ath_lnaconf_alt_good_scan(antcomb, div_ant_conf,
+ main_rssi_avg);
+ antcomb->alt_good = true;
+ } else {
+ antcomb->alt_good = false;
+ }
+
+ antcomb->count = 0;
+ antcomb->scan = true;
+ antcomb->scan_not_start = true;
+ }
+
+ if (!antcomb->scan) {
+ if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
+ if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
+ /* Switch main and alt LNA */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) {
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ }
+
+ goto div_comb_done;
+ } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) &&
+ (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) {
+ /* Set alt to another LNA */
+ if (curr_main_set == ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1)
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+
+ goto div_comb_done;
+ }
+
+ if ((alt_rssi_avg < (main_rssi_avg +
+ ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA)))
+ goto div_comb_done;
+ }
+
+ if (!antcomb->scan_not_start) {
+ switch (curr_alt_set) {
+ case ATH_ANT_DIV_COMB_LNA2:
+ antcomb->rssi_lna2 = alt_rssi_avg;
+ antcomb->rssi_lna1 = main_rssi_avg;
+ antcomb->scan = true;
+ /* set to A+B */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ break;
+ case ATH_ANT_DIV_COMB_LNA1:
+ antcomb->rssi_lna1 = alt_rssi_avg;
+ antcomb->rssi_lna2 = main_rssi_avg;
+ antcomb->scan = true;
+ /* set to A+B */
+ div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ break;
+ case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2:
+ antcomb->rssi_add = alt_rssi_avg;
+ antcomb->scan = true;
+ /* set to A-B */
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ break;
+ case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2:
+ antcomb->rssi_sub = alt_rssi_avg;
+ antcomb->scan = false;
+ if (antcomb->rssi_lna2 >
+ (antcomb->rssi_lna1 +
+ ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) {
+ /* use LNA2 as main LNA */
+ if ((antcomb->rssi_add > antcomb->rssi_lna1) &&
+ (antcomb->rssi_add > antcomb->rssi_sub)) {
+ /* set to A+B */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ } else if (antcomb->rssi_sub >
+ antcomb->rssi_lna1) {
+ /* set to A-B */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ } else {
+ /* set to LNA1 */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ }
+ } else {
+ /* use LNA1 as main LNA */
+ if ((antcomb->rssi_add > antcomb->rssi_lna2) &&
+ (antcomb->rssi_add > antcomb->rssi_sub)) {
+ /* set to A+B */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ } else if (antcomb->rssi_sub >
+ antcomb->rssi_lna1) {
+ /* set to A-B */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ } else {
+ /* set to LNA2 */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ if (!antcomb->alt_good) {
+ antcomb->scan_not_start = false;
+ /* Set alt to another LNA */
+ if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) {
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) {
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ }
+ goto div_comb_done;
+ }
+ }
+
+ ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf,
+ main_rssi_avg, alt_rssi_avg,
+ alt_ratio);
+
+ antcomb->quick_scan_cnt++;
+
+div_comb_done:
+ ath_ant_div_conf_fast_divbias(&div_ant_conf);
+
+ ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
+
+ antcomb->scan_start_time = jiffies;
+ antcomb->total_pkt_count = 0;
+ antcomb->main_total_rssi = 0;
+ antcomb->alt_total_rssi = 0;
+ antcomb->main_recv_cnt = 0;
+ antcomb->alt_recv_cnt = 0;
+}
+
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
{
struct ath_buf *bf;
@@ -1096,6 +1646,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
u8 rx_status_len = ah->caps.rx_status_len;
u64 tsf = 0;
u32 tsf_lower = 0;
+ unsigned long flags;
if (edma)
dma_type = DMA_BIDIRECTIONAL;
@@ -1186,12 +1737,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
bf->bf_buf_addr))) {
dev_kfree_skb_any(requeue_skb);
bf->bf_mpdu = NULL;
+ bf->bf_buf_addr = 0;
ath_print(common, ATH_DBG_FATAL,
"dma_mapping_error() on RX\n");
ath_rx_send_to_mac80211(hw, sc, skb, rxs);
break;
}
- bf->bf_dmacontext = bf->bf_buf_addr;
/*
* change the default rx antenna if rx diversity chooses the
@@ -1204,11 +1755,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
sc->rx.rxotherant = 0;
}
+ spin_lock_irqsave(&sc->sc_pm_lock, flags);
if (unlikely(ath9k_check_auto_sleep(sc) ||
(sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
PS_WAIT_FOR_PSPOLL_DATA))))
ath_rx_ps(sc, skb);
+ spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
+ ath_ant_comb_scan(sc, &rs);
ath_rx_send_to_mac80211(hw, sc, skb, rxs);
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index d01c4adab8d6..42976b0a01c1 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -107,12 +107,6 @@
#define AR_RXCFG_DMASZ_256B 6
#define AR_RXCFG_DMASZ_512B 7
-#define AR_MIBC 0x0040
-#define AR_MIBC_COW 0x00000001
-#define AR_MIBC_FMC 0x00000002
-#define AR_MIBC_CMC 0x00000004
-#define AR_MIBC_MCS 0x00000008
-
#define AR_TOPS 0x0044
#define AR_TOPS_MASK 0x0000FFFF
@@ -819,49 +813,23 @@
((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11))
#define AR_SREV_9280(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
-#define AR_SREV_9280_10_OR_LATER(_ah) \
+#define AR_SREV_9280_20_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280))
#define AR_SREV_9280_20(_ah) \
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
- ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))
-#define AR_SREV_9280_20_OR_LATER(_ah) \
- (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
- ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)))
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
#define AR_SREV_9285(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285))
-#define AR_SREV_9285_10_OR_LATER(_ah) \
- (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
-#define AR_SREV_9285_11(_ah) \
- (AR_SREV_9285(ah) && \
- ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11))
-#define AR_SREV_9285_11_OR_LATER(_ah) \
- (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
- (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
- AR_SREV_REVISION_9285_11)))
-#define AR_SREV_9285_12(_ah) \
- (AR_SREV_9285(ah) && \
- ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12))
#define AR_SREV_9285_12_OR_LATER(_ah) \
- (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
- (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
- AR_SREV_REVISION_9285_12)))
+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
#define AR_SREV_9287(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287))
-#define AR_SREV_9287_10_OR_LATER(_ah) \
+#define AR_SREV_9287_11_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9287))
-#define AR_SREV_9287_10(_ah) \
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
- ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_10))
#define AR_SREV_9287_11(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_11))
-#define AR_SREV_9287_11_OR_LATER(_ah) \
- (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
- ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_11)))
#define AR_SREV_9287_12(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_12))
@@ -885,9 +853,6 @@
#define AR_SREV_9300(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
-#define AR_SREV_9300_20(_ah) \
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
- ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20))
#define AR_SREV_9300_20_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
@@ -1550,11 +1515,6 @@ enum {
#define AR_TPC_CHIRP 0x003f0000
#define AR_TPC_CHIRP_S 0x16
-#define AR_TFCNT 0x80ec
-#define AR_RFCNT 0x80f0
-#define AR_RCCNT 0x80f4
-#define AR_CCCNT 0x80f8
-
#define AR_QUIET1 0x80fc
#define AR_QUIET1_NEXT_QUIET_S 0
#define AR_QUIET1_NEXT_QUIET_M 0x0000ffff
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index fd20241f57d8..ec7cf5ee56bc 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -19,45 +19,36 @@
#include "ath9k.h"
struct ath9k_vif_iter_data {
- int count;
- u8 *addr;
+ const u8 *hw_macaddr;
+ u8 mask[ETH_ALEN];
};
static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
{
struct ath9k_vif_iter_data *iter_data = data;
- u8 *nbuf;
-
- nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN,
- GFP_ATOMIC);
- if (nbuf == NULL)
- return;
+ int i;
- memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN);
- iter_data->addr = nbuf;
- iter_data->count++;
+ for (i = 0; i < ETH_ALEN; i++)
+ iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
}
-void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath9k_vif_iter_data iter_data;
- int i, j;
- u8 mask[ETH_ALEN];
+ int i;
/*
- * Add primary MAC address even if it is not in active use since it
- * will be configured to the hardware as the starting point and the
- * BSSID mask will need to be changed if another address is active.
+ * Use the hardware MAC address as reference, the hardware uses it
+ * together with the BSSID mask when matching addresses.
*/
- iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC);
- if (iter_data.addr) {
- memcpy(iter_data.addr, common->macaddr, ETH_ALEN);
- iter_data.count = 1;
- } else
- iter_data.count = 0;
+ iter_data.hw_macaddr = common->macaddr;
+ memset(&iter_data.mask, 0xff, ETH_ALEN);
+
+ if (vif)
+ ath9k_vif_iter(&iter_data, vif->addr, vif);
/* Get list of all active MAC addresses */
spin_lock_bh(&sc->wiphy_lock);
@@ -71,31 +62,7 @@ void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
}
spin_unlock_bh(&sc->wiphy_lock);
- /* Generate an address mask to cover all active addresses */
- memset(mask, 0, ETH_ALEN);
- for (i = 0; i < iter_data.count; i++) {
- u8 *a1 = iter_data.addr + i * ETH_ALEN;
- for (j = i + 1; j < iter_data.count; j++) {
- u8 *a2 = iter_data.addr + j * ETH_ALEN;
- mask[0] |= a1[0] ^ a2[0];
- mask[1] |= a1[1] ^ a2[1];
- mask[2] |= a1[2] ^ a2[2];
- mask[3] |= a1[3] ^ a2[3];
- mask[4] |= a1[4] ^ a2[4];
- mask[5] |= a1[5] ^ a2[5];
- }
- }
-
- kfree(iter_data.addr);
-
- /* Invert the mask and configure hardware */
- common->bssidmask[0] = ~mask[0];
- common->bssidmask[1] = ~mask[1];
- common->bssidmask[2] = ~mask[2];
- common->bssidmask[3] = ~mask[3];
- common->bssidmask[4] = ~mask[4];
- common->bssidmask[5] = ~mask[5];
-
+ memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
ath_hw_setbssidmask(common);
}
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 6260faa658a2..93a8bda09c25 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -85,6 +85,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
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";
}
return "Bogus";
@@ -122,55 +124,11 @@ void ath9k_wmi_tasklet(unsigned long data)
{
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
struct ath_common *common = ath9k_hw_common(priv->ah);
- struct wmi_cmd_hdr *hdr;
- struct wmi_swba *swba_hdr;
- enum wmi_event_id event;
- struct sk_buff *skb;
- void *wmi_event;
- unsigned long flags;
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
- __be32 txrate;
-#endif
- spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
- skb = priv->wmi->wmi_skb;
- spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
+ ath_print(common, ATH_DBG_WMI, "SWBA Event received\n");
- hdr = (struct wmi_cmd_hdr *) skb->data;
- event = be16_to_cpu(hdr->command_id);
- wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
+ ath9k_htc_swba(priv, priv->wmi->beacon_pending);
- ath_print(common, ATH_DBG_WMI,
- "WMI Event: 0x%x\n", event);
-
- switch (event) {
- case WMI_TGT_RDY_EVENTID:
- break;
- case WMI_SWBA_EVENTID:
- swba_hdr = (struct wmi_swba *) wmi_event;
- ath9k_htc_swba(priv, swba_hdr->beacon_pending);
- break;
- case WMI_FATAL_EVENTID:
- break;
- case WMI_TXTO_EVENTID:
- break;
- case WMI_BMISS_EVENTID:
- break;
- case WMI_WLAN_TXCOMP_EVENTID:
- break;
- case WMI_DELBA_EVENTID:
- break;
- case WMI_TXRATE_EVENTID:
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
- txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
- priv->debug.txrate = be32_to_cpu(txrate);
-#endif
- break;
- default:
- break;
- }
-
- kfree_skb(skb);
}
static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
@@ -189,6 +147,10 @@ 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;
@@ -197,10 +159,22 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
cmd_id = be16_to_cpu(hdr->command_id);
if (cmd_id & 0x1000) {
- spin_lock(&wmi->wmi_lock);
- wmi->wmi_skb = skb;
- spin_unlock(&wmi->wmi_lock);
- tasklet_schedule(&wmi->drv_priv->wmi_tasklet);
+ 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->wmi_tasklet);
+ 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);
return;
}
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index 765db5faa2d3..ac61074af8ac 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -31,10 +31,6 @@ struct wmi_cmd_hdr {
__be16 seq_no;
} __packed;
-struct wmi_swba {
- u8 beacon_pending;
-} __packed;
-
enum wmi_cmd_id {
WMI_ECHO_CMDID = 0x0001,
WMI_ACCESS_MEMORY_CMDID,
@@ -71,6 +67,7 @@ enum wmi_cmd_id {
WMI_TX_AGGR_ENABLE_CMDID,
WMI_TGT_DETACH_CMDID,
WMI_TGT_TXQ_ENABLE_CMDID,
+ WMI_AGGR_LIMIT_CMD = 0x0026,
};
enum wmi_event_id {
@@ -103,7 +100,7 @@ struct wmi {
u32 cmd_rsp_len;
bool stopped;
- struct sk_buff *wmi_skb;
+ u8 beacon_pending;
spinlock_t wmi_lock;
atomic_t mwrite_cnt;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 4dda14e36227..d077186da870 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -61,6 +61,8 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
struct ath_tx_status *ts, int txok);
static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
int nbad, int txok, bool update_rc);
+static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+ int seqno);
enum {
MCS_HT20,
@@ -143,18 +145,23 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
struct ath_buf *bf;
struct list_head bf_head;
- INIT_LIST_HEAD(&bf_head);
+ struct ath_tx_status ts;
- WARN_ON(!tid->paused);
+ INIT_LIST_HEAD(&bf_head);
+ memset(&ts, 0, sizeof(ts));
spin_lock_bh(&txq->axq_lock);
- tid->paused = false;
while (!list_empty(&tid->buf_q)) {
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
- BUG_ON(bf_isretried(bf));
list_move_tail(&bf->list, &bf_head);
- ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
+
+ if (bf_isretried(bf)) {
+ ath_tx_update_baw(sc, tid, bf->bf_seqno);
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
+ } else {
+ ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
+ }
}
spin_unlock_bh(&txq->axq_lock);
@@ -168,9 +175,9 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
index = ATH_BA_INDEX(tid->seq_start, seqno);
cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
- tid->tx_buf[cindex] = NULL;
+ __clear_bit(cindex, tid->tx_buf);
- while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) {
+ while (tid->baw_head != tid->baw_tail && !test_bit(tid->baw_head, tid->tx_buf)) {
INCR(tid->seq_start, IEEE80211_SEQ_MAX);
INCR(tid->baw_head, ATH_TID_MAX_BUFS);
}
@@ -186,9 +193,7 @@ static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-
- BUG_ON(tid->tx_buf[cindex] != NULL);
- tid->tx_buf[cindex] = bf;
+ __set_bit(cindex, tid->tx_buf);
if (index >= ((tid->baw_tail - tid->baw_head) &
(ATH_TID_MAX_BUFS - 1))) {
@@ -289,7 +294,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
tbf->bf_buf_addr = bf->bf_buf_addr;
memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len);
tbf->bf_state = bf->bf_state;
- tbf->bf_dmacontext = bf->bf_dmacontext;
return tbf;
}
@@ -312,6 +316,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
bool rc_update = true;
struct ieee80211_tx_rate rates[4];
+ int nframes;
skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -320,11 +325,11 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
hw = bf->aphy->hw;
memcpy(rates, tx_info->control.rates, sizeof(rates));
+ nframes = bf->bf_nframes;
rcu_read_lock();
- /* XXX: use ieee80211_find_sta! */
- sta = ieee80211_find_sta_by_hw(hw, hdr->addr1);
+ sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
if (!sta) {
rcu_read_unlock();
@@ -337,7 +342,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
!bf->bf_stale || bf_next != NULL)
list_move_tail(&bf->list, &bf_head);
- ath_tx_rc_status(bf, ts, 0, 0, false);
+ ath_tx_rc_status(bf, ts, 1, 0, false);
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
0, 0);
@@ -431,7 +436,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
list_move_tail(&bf->list, &bf_head);
}
- if (!txpending) {
+ if (!txpending || (tid->state & AGGR_CLEANUP)) {
/*
* complete the acked-ones/xretried ones; update
* block-ack window
@@ -442,6 +447,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
memcpy(tx_info->control.rates, rates, sizeof(rates));
+ bf->bf_nframes = nframes;
ath_tx_rc_status(bf, ts, nbad, txok, true);
rc_update = false;
} else {
@@ -510,15 +516,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
}
if (tid->state & AGGR_CLEANUP) {
+ ath_tx_flush_tid(sc, tid);
+
if (tid->baw_head == tid->baw_tail) {
tid->state &= ~AGGR_ADDBA_COMPLETE;
tid->state &= ~AGGR_CLEANUP;
-
- /* send buffered frames as singles */
- ath_tx_flush_tid(sc, tid);
}
- rcu_read_unlock();
- return;
}
rcu_read_unlock();
@@ -785,17 +788,23 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
status != ATH_AGGR_BAW_CLOSED);
}
-void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
- u16 tid, u16 *ssn)
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn)
{
struct ath_atx_tid *txtid;
struct ath_node *an;
an = (struct ath_node *)sta->drv_priv;
txtid = ATH_AN_2_TID(an, tid);
+
+ if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE))
+ return -EAGAIN;
+
txtid->state |= AGGR_ADDBA_PROGRESS;
txtid->paused = true;
*ssn = txtid->seq_start;
+
+ return 0;
}
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
@@ -803,12 +812,6 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
struct ath_node *an = (struct ath_node *)sta->drv_priv;
struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
- struct ath_tx_status ts;
- struct ath_buf *bf;
- struct list_head bf_head;
-
- memset(&ts, 0, sizeof(ts));
- INIT_LIST_HEAD(&bf_head);
if (txtid->state & AGGR_CLEANUP)
return;
@@ -818,31 +821,22 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
return;
}
- /* drop all software retried frames and mark this TID */
spin_lock_bh(&txq->axq_lock);
txtid->paused = true;
- while (!list_empty(&txtid->buf_q)) {
- bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
- if (!bf_isretried(bf)) {
- /*
- * NB: it's based on the assumption that
- * software retried frame will always stay
- * at the head of software queue.
- */
- break;
- }
- list_move_tail(&bf->list, &bf_head);
- ath_tx_update_baw(sc, txtid, bf->bf_seqno);
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
- }
- spin_unlock_bh(&txq->axq_lock);
- if (txtid->baw_head != txtid->baw_tail) {
+ /*
+ * If frames are still being transmitted for this TID, they will be
+ * cleaned up during tx completion. To prevent race conditions, this
+ * TID can only be reused after all in-progress subframes have been
+ * completed.
+ */
+ if (txtid->baw_head != txtid->baw_tail)
txtid->state |= AGGR_CLEANUP;
- } else {
+ else
txtid->state &= ~AGGR_ADDBA_COMPLETE;
- ath_tx_flush_tid(sc, txtid);
- }
+ spin_unlock_bh(&txq->axq_lock);
+
+ ath_tx_flush_tid(sc, txtid);
}
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
@@ -862,20 +856,6 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
}
}
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
-{
- struct ath_atx_tid *txtid;
-
- if (!(sc->sc_flags & SC_OP_TXAGGR))
- return false;
-
- txtid = ATH_AN_2_TID(an, tidno);
-
- if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS)))
- return true;
- return false;
-}
-
/********************/
/* Queue Management */
/********************/
@@ -1407,22 +1387,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
return htype;
}
-static int get_hw_crypto_keytype(struct sk_buff *skb)
-{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-
- if (tx_info->control.hw_key) {
- if (tx_info->control.hw_key->alg == ALG_WEP)
- return ATH9K_KEY_TYPE_WEP;
- else if (tx_info->control.hw_key->alg == ALG_TKIP)
- return ATH9K_KEY_TYPE_TKIP;
- else if (tx_info->control.hw_key->alg == ALG_CCMP)
- return ATH9K_KEY_TYPE_AES;
- }
-
- return ATH9K_KEY_TYPE_CLEAR;
-}
-
static void assign_aggr_tid_seqno(struct sk_buff *skb,
struct ath_buf *bf)
{
@@ -1661,7 +1625,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
bf->bf_state.bfs_paprd_timestamp = jiffies;
bf->bf_flags = setup_tx_flags(skb, use_ldpc);
- bf->bf_keytype = get_hw_crypto_keytype(skb);
+ bf->bf_keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
bf->bf_frmlen += tx_info->control.hw_key->icv_len;
bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
@@ -1675,24 +1639,16 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
bf->bf_mpdu = skb;
- bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
- skb->len, DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
+ bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
bf->bf_mpdu = NULL;
+ bf->bf_buf_addr = 0;
ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
"dma_mapping_error() on TX\n");
return -ENOMEM;
}
- bf->bf_buf_addr = bf->bf_dmacontext;
-
- /* tag if this is a nullfunc frame to enable PS when AP acks it */
- if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
- bf->bf_isnullfunc = true;
- sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
- } else
- bf->bf_isnullfunc = false;
-
bf->bf_tx_aborted = false;
return 0;
@@ -1956,7 +1912,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
tx_flags |= ATH_TX_XRETRY;
}
- dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
+ dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE);
+ bf->bf_buf_addr = 0;
if (bf->bf_state.bfs_paprd) {
if (time_after(jiffies,
@@ -1966,9 +1923,13 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
else
complete(&sc->paprd_complete);
} else {
- ath_tx_complete(sc, skb, bf->aphy, tx_flags);
ath_debug_stat_tx(sc, txq, bf, ts);
+ ath_tx_complete(sc, skb, bf->aphy, tx_flags);
}
+ /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
+ * accidentally reference it later.
+ */
+ bf->bf_mpdu = NULL;
/*
* Return the list of ath_buf of this mpdu to free queue
@@ -2024,9 +1985,15 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
if (ts->ts_status & ATH9K_TXERR_FILT)
tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
- if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc)
+ if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) {
tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
+ BUG_ON(nbad > bf->bf_nframes);
+
+ tx_info->status.ampdu_len = bf->bf_nframes;
+ tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
+ }
+
if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
(bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
if (ieee80211_is_data(hdr->frame_control)) {
@@ -2036,8 +2003,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
if ((ts->ts_status & ATH9K_TXERR_XRETRY) ||
(ts->ts_status & ATH9K_TXERR_FIFO))
tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
- tx_info->status.ampdu_len = bf->bf_nframes;
- tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
}
}
@@ -2120,18 +2085,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
}
/*
- * We now know the nullfunc frame has been ACKed so we
- * can disable RX.
- */
- if (bf->bf_isnullfunc &&
- (ts.ts_status & ATH9K_TX_ACKED)) {
- if ((sc->ps_flags & PS_ENABLED))
- ath9k_enable_ps(sc);
- else
- sc->ps_flags |= PS_NULLFUNC_COMPLETED;
- }
-
- /*
* Remove ath_buf's of the same transmit unit from txq,
* however leave the last descriptor back as the holding
* descriptor for hw.
@@ -2159,7 +2112,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
*/
if (ts.ts_status & ATH9K_TXERR_XRETRY)
bf->bf_state.bf_type |= BUF_XRETRY;
- ath_tx_rc_status(bf, &ts, 0, txok, true);
+ ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true);
}
if (bf_isampdu(bf))
@@ -2274,21 +2227,10 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
txok = !(txs.ts_status & ATH9K_TXERR_MASK);
- /*
- * Make sure null func frame is acked before configuring
- * hw into ps mode.
- */
- if (bf->bf_isnullfunc && txok) {
- if ((sc->ps_flags & PS_ENABLED))
- ath9k_enable_ps(sc);
- else
- sc->ps_flags |= PS_NULLFUNC_COMPLETED;
- }
-
if (!bf_isampdu(bf)) {
if (txs.ts_status & ATH9K_TXERR_XRETRY)
bf->bf_state.bf_type |= BUF_XRETRY;
- ath_tx_rc_status(bf, &txs, 0, txok, true);
+ ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true);
}
if (bf_isampdu(bf))
diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig
new file mode 100644
index 000000000000..2d1b821b440d
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/Kconfig
@@ -0,0 +1,41 @@
+config CARL9170
+ tristate "Linux Community AR9170 802.11n USB support"
+ depends on USB && MAC80211 && EXPERIMENTAL
+ select FW_LOADER
+ select CRC32
+ help
+ This is another driver for the Atheros "otus" 802.11n USB devices.
+
+ This driver provides more features than the original,
+ but it needs a special firmware (carl9170-1.fw) to do that.
+
+ The firmware can be downloaded from our wiki here:
+ <http://wireless.kernel.org/en/users/Drivers/carl9170>
+
+ If you choose to build a module, it'll be called carl9170.
+
+config CARL9170_LEDS
+ bool "SoftLED Support"
+ depends on CARL9170
+ select MAC80211_LEDS
+ select LEDS_CLASS
+ select NEW_LEDS
+ default y
+ help
+ This option is necessary, if you want your device' LEDs to blink
+
+ Say Y, unless you need the LEDs for firmware debugging.
+
+config CARL9170_DEBUGFS
+ bool "DebugFS Support"
+ depends on CARL9170 && DEBUG_FS && MAC80211_DEBUGFS
+ default n
+ help
+ Export several driver and device internals to user space.
+
+ Say N.
+
+config CARL9170_WPC
+ bool
+ depends on CARL9170 && (INPUT = y || INPUT = CARL9170)
+ default y
diff --git a/drivers/net/wireless/ath/carl9170/Makefile b/drivers/net/wireless/ath/carl9170/Makefile
new file mode 100644
index 000000000000..f64ed76af8ad
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/Makefile
@@ -0,0 +1,4 @@
+carl9170-objs := main.o usb.o cmd.o mac.o phy.o led.o fw.o tx.o rx.o
+carl9170-$(CONFIG_CARL9170_DEBUGFS) += debug.o
+
+obj-$(CONFIG_CARL9170) += carl9170.o
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
new file mode 100644
index 000000000000..6cf0c9ef47aa
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -0,0 +1,628 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * Driver specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 __CARL9170_H
+#define __CARL9170_H
+
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include <linux/usb.h>
+#ifdef CONFIG_CARL9170_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_CARL170_LEDS */
+#ifdef CONFIG_CARL9170_WPC
+#include <linux/input.h>
+#endif /* CONFIG_CARL9170_WPC */
+#include "eeprom.h"
+#include "wlan.h"
+#include "hw.h"
+#include "fwdesc.h"
+#include "fwcmd.h"
+#include "../regd.h"
+
+#ifdef CONFIG_CARL9170_DEBUGFS
+#include "debug.h"
+#endif /* CONFIG_CARL9170_DEBUGFS */
+
+#define CARL9170FW_NAME "carl9170-1.fw"
+
+#define PAYLOAD_MAX (CARL9170_MAX_CMD_LEN / 4 - 1)
+
+enum carl9170_rf_init_mode {
+ CARL9170_RFI_NONE,
+ CARL9170_RFI_WARM,
+ CARL9170_RFI_COLD,
+};
+
+#define CARL9170_MAX_RX_BUFFER_SIZE 8192
+
+enum carl9170_device_state {
+ CARL9170_UNKNOWN_STATE,
+ CARL9170_STOPPED,
+ CARL9170_IDLE,
+ CARL9170_STARTED,
+};
+
+#define CARL9170_NUM_TID 16
+#define WME_BA_BMP_SIZE 64
+#define CARL9170_TX_USER_RATE_TRIES 3
+
+#define WME_AC_BE 2
+#define WME_AC_BK 3
+#define WME_AC_VI 1
+#define WME_AC_VO 0
+
+#define TID_TO_WME_AC(_tid) \
+ ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
+ (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
+ (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
+ WME_AC_VO)
+
+#define SEQ_DIFF(_start, _seq) \
+ (((_start) - (_seq)) & 0x0fff)
+#define SEQ_PREV(_seq) \
+ (((_seq) - 1) & 0x0fff)
+#define SEQ_NEXT(_seq) \
+ (((_seq) + 1) & 0x0fff)
+#define BAW_WITHIN(_start, _bawsz, _seqno) \
+ ((((_seqno) - (_start)) & 0xfff) < (_bawsz))
+
+enum carl9170_tid_state {
+ CARL9170_TID_STATE_INVALID,
+ CARL9170_TID_STATE_KILLED,
+ CARL9170_TID_STATE_SHUTDOWN,
+ CARL9170_TID_STATE_SUSPEND,
+ CARL9170_TID_STATE_PROGRESS,
+ CARL9170_TID_STATE_IDLE,
+ CARL9170_TID_STATE_XMIT,
+};
+
+#define CARL9170_BAW_BITS (2 * WME_BA_BMP_SIZE)
+#define CARL9170_BAW_SIZE (BITS_TO_LONGS(CARL9170_BAW_BITS))
+#define CARL9170_BAW_LEN (DIV_ROUND_UP(CARL9170_BAW_BITS, BITS_PER_BYTE))
+
+struct carl9170_sta_tid {
+ /* must be the first entry! */
+ struct list_head list;
+
+ /* temporary list for RCU unlink procedure */
+ struct list_head tmp_list;
+
+ /* lock for the following data structures */
+ spinlock_t lock;
+
+ unsigned int counter;
+ enum carl9170_tid_state state;
+ u8 tid; /* TID number ( 0 - 15 ) */
+ u16 max; /* max. AMPDU size */
+
+ u16 snx; /* awaiting _next_ frame */
+ u16 hsn; /* highest _queued_ sequence */
+ u16 bsn; /* base of the tx/agg bitmap */
+ unsigned long bitmap[CARL9170_BAW_SIZE];
+
+ /* Preaggregation reorder queue */
+ struct sk_buff_head queue;
+};
+
+#define CARL9170_QUEUE_TIMEOUT 256
+#define CARL9170_BUMP_QUEUE 1000
+#define CARL9170_TX_TIMEOUT 2500
+#define CARL9170_JANITOR_DELAY 128
+#define CARL9170_QUEUE_STUCK_TIMEOUT 5500
+
+#define CARL9170_NUM_TX_AGG_MAX 30
+
+/*
+ * Tradeoff between stability/latency and speed.
+ *
+ * AR9170_TXQ_DEPTH is devised by dividing the amount of available
+ * tx buffers with the size of a full ethernet frame + overhead.
+ *
+ * Naturally: The higher the limit, the faster the device CAN send.
+ * However, even a slight over-commitment at the wrong time and the
+ * hardware is doomed to send all already-queued frames at suboptimal
+ * rates. This in turn leads to an enourmous amount of unsuccessful
+ * retries => Latency goes up, whereas the throughput goes down. CRASH!
+ */
+#define CARL9170_NUM_TX_LIMIT_HARD ((AR9170_TXQ_DEPTH * 3) / 2)
+#define CARL9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH)
+
+struct carl9170_tx_queue_stats {
+ unsigned int count;
+ unsigned int limit;
+ unsigned int len;
+};
+
+struct carl9170_vif {
+ unsigned int id;
+ struct ieee80211_vif *vif;
+};
+
+struct carl9170_vif_info {
+ struct list_head list;
+ bool active;
+ unsigned int id;
+ struct sk_buff *beacon;
+ bool enable_beacon;
+};
+
+#define AR9170_NUM_RX_URBS 16
+#define AR9170_NUM_RX_URBS_MUL 2
+#define AR9170_NUM_TX_URBS 8
+#define AR9170_NUM_RX_URBS_POOL (AR9170_NUM_RX_URBS_MUL * AR9170_NUM_RX_URBS)
+
+enum carl9170_device_features {
+ CARL9170_WPS_BUTTON = BIT(0),
+ CARL9170_ONE_LED = BIT(1),
+};
+
+#ifdef CONFIG_CARL9170_LEDS
+struct ar9170;
+
+struct carl9170_led {
+ struct ar9170 *ar;
+ struct led_classdev l;
+ char name[32];
+ unsigned int toggled;
+ bool last_state;
+ bool registered;
+};
+#endif /* CONFIG_CARL9170_LEDS */
+
+enum carl9170_restart_reasons {
+ CARL9170_RR_NO_REASON = 0,
+ CARL9170_RR_FATAL_FIRMWARE_ERROR,
+ CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS,
+ CARL9170_RR_WATCHDOG,
+ CARL9170_RR_STUCK_TX,
+ CARL9170_RR_SLOW_SYSTEM,
+ CARL9170_RR_COMMAND_TIMEOUT,
+ CARL9170_RR_TOO_MANY_PHY_ERRORS,
+ CARL9170_RR_LOST_RSP,
+ CARL9170_RR_INVALID_RSP,
+ CARL9170_RR_USER_REQUEST,
+
+ __CARL9170_RR_LAST,
+};
+
+enum carl9170_erp_modes {
+ CARL9170_ERP_INVALID,
+ CARL9170_ERP_AUTO,
+ CARL9170_ERP_MAC80211,
+ CARL9170_ERP_OFF,
+ CARL9170_ERP_CTS,
+ CARL9170_ERP_RTS,
+ __CARL9170_ERP_NUM,
+};
+
+struct ar9170 {
+ struct ath_common common;
+ struct ieee80211_hw *hw;
+ struct mutex mutex;
+ enum carl9170_device_state state;
+ spinlock_t state_lock;
+ enum carl9170_restart_reasons last_reason;
+ bool registered;
+
+ /* USB */
+ struct usb_device *udev;
+ struct usb_interface *intf;
+ struct usb_anchor rx_anch;
+ struct usb_anchor rx_work;
+ struct usb_anchor rx_pool;
+ struct usb_anchor tx_wait;
+ struct usb_anchor tx_anch;
+ struct usb_anchor tx_cmd;
+ struct usb_anchor tx_err;
+ struct tasklet_struct usb_tasklet;
+ atomic_t tx_cmd_urbs;
+ atomic_t tx_anch_urbs;
+ atomic_t rx_anch_urbs;
+ atomic_t rx_work_urbs;
+ atomic_t rx_pool_urbs;
+ kernel_ulong_t features;
+
+ /* firmware settings */
+ struct completion fw_load_wait;
+ struct completion fw_boot_wait;
+ struct {
+ const struct carl9170fw_desc_head *desc;
+ const struct firmware *fw;
+ unsigned int offset;
+ unsigned int address;
+ unsigned int cmd_bufs;
+ unsigned int api_version;
+ unsigned int vif_num;
+ unsigned int err_counter;
+ unsigned int bug_counter;
+ u32 beacon_addr;
+ unsigned int beacon_max_len;
+ bool rx_stream;
+ bool tx_stream;
+ bool rx_filter;
+ unsigned int mem_blocks;
+ unsigned int mem_block_size;
+ unsigned int rx_size;
+ } fw;
+
+ /* reset / stuck frames/queue detection */
+ struct work_struct restart_work;
+ unsigned int restart_counter;
+ unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
+ unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
+ bool needs_full_reset;
+ atomic_t pending_restarts;
+
+ /* interface mode settings */
+ struct list_head vif_list;
+ unsigned long vif_bitmap;
+ unsigned int vifs;
+ struct carl9170_vif vif_priv[AR9170_MAX_VIRTUAL_MAC];
+
+ /* beaconing */
+ spinlock_t beacon_lock;
+ unsigned int global_pretbtt;
+ unsigned int global_beacon_int;
+ struct carl9170_vif_info *beacon_iter;
+ unsigned int beacon_enabled;
+
+ /* cryptographic engine */
+ u64 usedkeys;
+ bool rx_software_decryption;
+ bool disable_offload;
+
+ /* filter settings */
+ u64 cur_mc_hash;
+ u32 cur_filter;
+ unsigned int filter_state;
+ unsigned int rx_filter_caps;
+ bool sniffer_enabled;
+
+ /* MAC */
+ enum carl9170_erp_modes erp_mode;
+
+ /* PHY */
+ struct ieee80211_channel *channel;
+ int noise[4];
+ unsigned int chan_fail;
+ unsigned int total_chan_fail;
+ u8 heavy_clip;
+ u8 ht_settings;
+
+ /* power calibration data */
+ u8 power_5G_leg[4];
+ u8 power_2G_cck[4];
+ u8 power_2G_ofdm[4];
+ u8 power_5G_ht20[8];
+ u8 power_5G_ht40[8];
+ u8 power_2G_ht20[8];
+ u8 power_2G_ht40[8];
+
+#ifdef CONFIG_CARL9170_LEDS
+ /* LED */
+ struct delayed_work led_work;
+ struct carl9170_led leds[AR9170_NUM_LEDS];
+#endif /* CONFIG_CARL9170_LEDS */
+
+ /* qos queue settings */
+ spinlock_t tx_stats_lock;
+ struct carl9170_tx_queue_stats tx_stats[__AR9170_NUM_TXQ];
+ struct ieee80211_tx_queue_params edcf[5];
+ struct completion tx_flush;
+
+ /* CMD */
+ int cmd_seq;
+ int readlen;
+ u8 *readbuf;
+ spinlock_t cmd_lock;
+ struct completion cmd_wait;
+ union {
+ __le32 cmd_buf[PAYLOAD_MAX + 1];
+ struct carl9170_cmd cmd;
+ struct carl9170_rsp rsp;
+ };
+
+ /* statistics */
+ unsigned int tx_dropped;
+ unsigned int tx_ack_failures;
+ unsigned int tx_fcs_errors;
+ unsigned int rx_dropped;
+
+ /* EEPROM */
+ struct ar9170_eeprom eeprom;
+
+ /* tx queuing */
+ struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
+ struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
+ struct delayed_work tx_janitor;
+ unsigned long tx_janitor_last_run;
+ bool tx_schedule;
+
+ /* tx ampdu */
+ struct work_struct ampdu_work;
+ spinlock_t tx_ampdu_list_lock;
+ struct carl9170_sta_tid *tx_ampdu_iter;
+ struct list_head tx_ampdu_list;
+ atomic_t tx_ampdu_upload;
+ atomic_t tx_ampdu_scheduler;
+ atomic_t tx_total_pending;
+ atomic_t tx_total_queued;
+ unsigned int tx_ampdu_list_len;
+ int current_density;
+ int current_factor;
+ bool tx_ampdu_schedule;
+
+ /* internal memory management */
+ spinlock_t mem_lock;
+ unsigned long *mem_bitmap;
+ atomic_t mem_free_blocks;
+ atomic_t mem_allocs;
+
+ /* rxstream mpdu merge */
+ struct ar9170_rx_head rx_plcp;
+ bool rx_has_plcp;
+ struct sk_buff *rx_failover;
+ int rx_failover_missing;
+
+#ifdef CONFIG_CARL9170_WPC
+ struct {
+ bool pbc_state;
+ struct input_dev *pbc;
+ char name[32];
+ char phys[32];
+ } wps;
+#endif /* CONFIG_CARL9170_WPC */
+
+#ifdef CONFIG_CARL9170_DEBUGFS
+ struct carl9170_debug debug;
+ struct dentry *debug_dir;
+#endif /* CONFIG_CARL9170_DEBUGFS */
+
+ /* PSM */
+ struct work_struct ps_work;
+ struct {
+ unsigned int dtim_counter;
+ unsigned long last_beacon;
+ unsigned long last_action;
+ unsigned long last_slept;
+ unsigned int sleep_ms;
+ unsigned int off_override;
+ bool state;
+ } ps;
+};
+
+enum carl9170_ps_off_override_reasons {
+ PS_OFF_VIF = BIT(0),
+ PS_OFF_BCN = BIT(1),
+ PS_OFF_5GHZ = BIT(2),
+};
+
+struct carl9170_ba_stats {
+ u8 ampdu_len;
+ u8 ampdu_ack_len;
+ bool clear;
+};
+
+struct carl9170_sta_info {
+ bool ht_sta;
+ unsigned int ampdu_max_len;
+ struct carl9170_sta_tid *agg[CARL9170_NUM_TID];
+ struct carl9170_ba_stats stats[CARL9170_NUM_TID];
+};
+
+struct carl9170_tx_info {
+ unsigned long timeout;
+ struct ar9170 *ar;
+ struct kref ref;
+};
+
+#define CHK_DEV_STATE(a, s) (((struct ar9170 *)a)->state >= (s))
+#define IS_INITIALIZED(a) (CHK_DEV_STATE(a, CARL9170_STOPPED))
+#define IS_ACCEPTING_CMD(a) (CHK_DEV_STATE(a, CARL9170_IDLE))
+#define IS_STARTED(a) (CHK_DEV_STATE(a, CARL9170_STARTED))
+
+static inline void __carl9170_set_state(struct ar9170 *ar,
+ enum carl9170_device_state newstate)
+{
+ ar->state = newstate;
+}
+
+static inline void carl9170_set_state(struct ar9170 *ar,
+ enum carl9170_device_state newstate)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ar->state_lock, flags);
+ __carl9170_set_state(ar, newstate);
+ spin_unlock_irqrestore(&ar->state_lock, flags);
+}
+
+static inline void carl9170_set_state_when(struct ar9170 *ar,
+ enum carl9170_device_state min, enum carl9170_device_state newstate)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ar->state_lock, flags);
+ if (CHK_DEV_STATE(ar, min))
+ __carl9170_set_state(ar, newstate);
+ spin_unlock_irqrestore(&ar->state_lock, flags);
+}
+
+/* exported interface */
+void *carl9170_alloc(size_t priv_size);
+int carl9170_register(struct ar9170 *ar);
+void carl9170_unregister(struct ar9170 *ar);
+void carl9170_free(struct ar9170 *ar);
+void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r);
+void carl9170_ps_check(struct ar9170 *ar);
+
+/* USB back-end */
+int carl9170_usb_open(struct ar9170 *ar);
+void carl9170_usb_stop(struct ar9170 *ar);
+void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb);
+void carl9170_usb_handle_tx_err(struct ar9170 *ar);
+int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids,
+ u32 plen, void *payload, u32 rlen, void *resp);
+int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd,
+ const bool free_buf);
+int carl9170_usb_restart(struct ar9170 *ar);
+void carl9170_usb_reset(struct ar9170 *ar);
+
+/* MAC */
+int carl9170_init_mac(struct ar9170 *ar);
+int carl9170_set_qos(struct ar9170 *ar);
+int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
+int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id,
+ const u8 *mac);
+int carl9170_set_operating_mode(struct ar9170 *ar);
+int carl9170_set_beacon_timers(struct ar9170 *ar);
+int carl9170_set_dyn_sifs_ack(struct ar9170 *ar);
+int carl9170_set_rts_cts_rate(struct ar9170 *ar);
+int carl9170_set_ampdu_settings(struct ar9170 *ar);
+int carl9170_set_slot_time(struct ar9170 *ar);
+int carl9170_set_mac_rates(struct ar9170 *ar);
+int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry);
+int carl9170_update_beacon(struct ar9170 *ar, const bool submit);
+int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
+ const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen);
+int carl9170_disable_key(struct ar9170 *ar, const u8 id);
+
+/* RX */
+void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len);
+void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
+
+/* TX */
+int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+void carl9170_tx_janitor(struct work_struct *work);
+void carl9170_tx_process_status(struct ar9170 *ar,
+ const struct carl9170_rsp *cmd);
+void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+ const bool success);
+void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb);
+void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb);
+void carl9170_tx_scheduler(struct ar9170 *ar);
+void carl9170_tx_get_skb(struct sk_buff *skb);
+int carl9170_tx_put_skb(struct sk_buff *skb);
+
+/* LEDs */
+#ifdef CONFIG_CARL9170_LEDS
+int carl9170_led_register(struct ar9170 *ar);
+void carl9170_led_unregister(struct ar9170 *ar);
+#endif /* CONFIG_CARL9170_LEDS */
+int carl9170_led_init(struct ar9170 *ar);
+int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state);
+
+/* PHY / RF */
+int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+ enum nl80211_channel_type bw, enum carl9170_rf_init_mode rfi);
+int carl9170_get_noisefloor(struct ar9170 *ar);
+
+/* FW */
+int carl9170_parse_firmware(struct ar9170 *ar);
+int carl9170_fw_fix_eeprom(struct ar9170 *ar);
+
+extern struct ieee80211_rate __carl9170_ratetable[];
+extern int modparam_noht;
+
+static inline struct ar9170 *carl9170_get_priv(struct carl9170_vif *carl_vif)
+{
+ return container_of(carl_vif, struct ar9170,
+ vif_priv[carl_vif->id]);
+}
+
+static inline struct ieee80211_hdr *carl9170_get_hdr(struct sk_buff *skb)
+{
+ return (void *)((struct _carl9170_tx_superframe *)
+ skb->data)->frame_data;
+}
+
+static inline u16 get_seq_h(struct ieee80211_hdr *hdr)
+{
+ return le16_to_cpu(hdr->seq_ctrl) >> 4;
+}
+
+static inline u16 carl9170_get_seq(struct sk_buff *skb)
+{
+ return get_seq_h(carl9170_get_hdr(skb));
+}
+
+static inline u16 get_tid_h(struct ieee80211_hdr *hdr)
+{
+ return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
+}
+
+static inline u16 carl9170_get_tid(struct sk_buff *skb)
+{
+ return get_tid_h(carl9170_get_hdr(skb));
+}
+
+static inline struct ieee80211_vif *
+carl9170_get_vif(struct carl9170_vif_info *priv)
+{
+ return container_of((void *)priv, struct ieee80211_vif, drv_priv);
+}
+
+/* Protected by ar->mutex or RCU */
+static inline struct ieee80211_vif *carl9170_get_main_vif(struct ar9170 *ar)
+{
+ struct carl9170_vif_info *cvif;
+
+ list_for_each_entry_rcu(cvif, &ar->vif_list, list) {
+ if (cvif->active)
+ return carl9170_get_vif(cvif);
+ }
+
+ return NULL;
+}
+
+static inline bool is_main_vif(struct ar9170 *ar, struct ieee80211_vif *vif)
+{
+ bool ret;
+
+ rcu_read_lock();
+ ret = (carl9170_get_main_vif(ar) == vif);
+ rcu_read_unlock();
+ return ret;
+}
+
+#endif /* __CARL9170_H */
diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c
new file mode 100644
index 000000000000..c21f3364bfec
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/cmd.c
@@ -0,0 +1,188 @@
+/*
+ * Atheros CARL9170 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 "carl9170.h"
+#include "cmd.h"
+
+int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
+{
+ __le32 buf[2] = {
+ cpu_to_le32(reg),
+ cpu_to_le32(val),
+ };
+ int err;
+
+ err = carl9170_exec_cmd(ar, CARL9170_CMD_WREG, sizeof(buf),
+ (u8 *) buf, 0, NULL);
+ if (err) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "writing reg %#x "
+ "(val %#x) failed (%d)\n", reg, val, err);
+ }
+ }
+ return err;
+}
+
+int carl9170_read_mreg(struct ar9170 *ar, const int nregs,
+ const u32 *regs, u32 *out)
+{
+ int i, err;
+ __le32 *offs, *res;
+
+ /* 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 = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
+ 4 * nregs, (u8 *)offs,
+ 4 * nregs, (u8 *)res);
+ if (err) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "reading regs failed (%d)\n",
+ err);
+ }
+ return err;
+ }
+
+ /* convert result to cpu endian */
+ for (i = 0; i < nregs; i++)
+ out[i] = le32_to_cpu(res[i]);
+
+ return 0;
+}
+
+int carl9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
+{
+ return carl9170_read_mreg(ar, 1, &reg, val);
+}
+
+int carl9170_echo_test(struct ar9170 *ar, const u32 v)
+{
+ u32 echores;
+ int err;
+
+ err = carl9170_exec_cmd(ar, CARL9170_CMD_ECHO,
+ 4, (u8 *)&v,
+ 4, (u8 *)&echores);
+ if (err)
+ return err;
+
+ if (v != echores) {
+ wiphy_info(ar->hw->wiphy, "wrong echo %x != %x", v, echores);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
+ const enum carl9170_cmd_oids cmd, const unsigned int len)
+{
+ struct carl9170_cmd *tmp;
+
+ tmp = kzalloc(sizeof(struct carl9170_cmd_head) + len, GFP_ATOMIC);
+ if (tmp) {
+ tmp->hdr.cmd = cmd;
+ tmp->hdr.len = len;
+ }
+
+ return tmp;
+}
+
+int carl9170_reboot(struct ar9170 *ar)
+{
+ struct carl9170_cmd *cmd;
+ int err;
+
+ cmd = carl9170_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0);
+ if (!cmd)
+ return -ENOMEM;
+
+ err = __carl9170_exec_cmd(ar, (struct carl9170_cmd *)cmd, true);
+ return err;
+}
+
+int carl9170_mac_reset(struct ar9170 *ar)
+{
+ return carl9170_exec_cmd(ar, CARL9170_CMD_SWRST,
+ 0, NULL, 0, NULL);
+}
+
+int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
+ const u32 mode, const u32 addr, const u32 len)
+{
+ struct carl9170_cmd *cmd;
+
+ cmd = carl9170_cmd_buf(ar, CARL9170_CMD_BCN_CTRL_ASYNC,
+ sizeof(struct carl9170_bcn_ctrl_cmd));
+ if (!cmd)
+ return -ENOMEM;
+
+ cmd->bcn_ctrl.vif_id = cpu_to_le32(vif_id);
+ cmd->bcn_ctrl.mode = cpu_to_le32(mode);
+ cmd->bcn_ctrl.bcn_addr = cpu_to_le32(addr);
+ cmd->bcn_ctrl.bcn_len = cpu_to_le32(len);
+
+ return __carl9170_exec_cmd(ar, cmd, true);
+}
+
+int carl9170_powersave(struct ar9170 *ar, const bool ps)
+{
+ struct carl9170_cmd *cmd;
+ u32 state;
+
+ cmd = carl9170_cmd_buf(ar, CARL9170_CMD_PSM_ASYNC,
+ sizeof(struct carl9170_psm));
+ if (!cmd)
+ return -ENOMEM;
+
+ if (ps) {
+ /* Sleep until next TBTT */
+ state = CARL9170_PSM_SLEEP | 1;
+ } else {
+ /* wake up immediately */
+ state = 1;
+ }
+
+ cmd->psm.state = cpu_to_le32(state);
+ return __carl9170_exec_cmd(ar, cmd, true);
+}
diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h
new file mode 100644
index 000000000000..f78728c38294
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/cmd.h
@@ -0,0 +1,168 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "carl9170.h"
+
+/* basic HW access */
+int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
+int carl9170_read_reg(struct ar9170 *ar, const u32 reg, u32 *val);
+int carl9170_read_mreg(struct ar9170 *ar, const int nregs,
+ const u32 *regs, u32 *out);
+int carl9170_echo_test(struct ar9170 *ar, u32 v);
+int carl9170_reboot(struct ar9170 *ar);
+int carl9170_mac_reset(struct ar9170 *ar);
+int carl9170_powersave(struct ar9170 *ar, const bool power_on);
+int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
+ const u32 mode, const u32 addr, const u32 len);
+
+static inline int carl9170_flush_cab(struct ar9170 *ar,
+ const unsigned int vif_id)
+{
+ return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0);
+}
+
+static inline int carl9170_rx_filter(struct ar9170 *ar,
+ const unsigned int _rx_filter)
+{
+ __le32 rx_filter = cpu_to_le32(_rx_filter);
+
+ return carl9170_exec_cmd(ar, CARL9170_CMD_RX_FILTER,
+ sizeof(rx_filter), (u8 *)&rx_filter,
+ 0, NULL);
+}
+
+struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
+ const enum carl9170_cmd_oids cmd, const unsigned int len);
+
+/*
+ * 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 carl9170_regwrite_begin(ar) \
+do { \
+ int __nreg = 0, __err = 0; \
+ struct ar9170 *__ar = ar;
+
+#define carl9170_regwrite(r, v) do { \
+ __ar->cmd_buf[2 * __nreg + 1] = cpu_to_le32(r); \
+ __ar->cmd_buf[2 * __nreg + 2] = cpu_to_le32(v); \
+ __nreg++; \
+ if ((__nreg >= PAYLOAD_MAX/2)) { \
+ if (IS_ACCEPTING_CMD(__ar)) \
+ __err = carl9170_exec_cmd(__ar, \
+ CARL9170_CMD_WREG, 8 * __nreg, \
+ (u8 *) &__ar->cmd_buf[1], 0, NULL); \
+ else \
+ goto __regwrite_out; \
+ \
+ __nreg = 0; \
+ if (__err) \
+ goto __regwrite_out; \
+ } \
+} while (0)
+
+#define carl9170_regwrite_finish() \
+__regwrite_out : \
+ if (__err == 0 && __nreg) { \
+ if (IS_ACCEPTING_CMD(__ar)) \
+ __err = carl9170_exec_cmd(__ar, \
+ CARL9170_CMD_WREG, 8 * __nreg, \
+ (u8 *) &__ar->cmd_buf[1], 0, NULL); \
+ __nreg = 0; \
+ }
+
+#define carl9170_regwrite_result() \
+ __err; \
+} while (0);
+
+
+#define carl9170_async_get_buf() \
+do { \
+ __cmd = carl9170_cmd_buf(__carl, CARL9170_CMD_WREG_ASYNC, \
+ CARL9170_MAX_CMD_PAYLOAD_LEN); \
+ if (__cmd == NULL) { \
+ __err = -ENOMEM; \
+ goto __async_regwrite_out; \
+ } \
+} while (0);
+
+#define carl9170_async_regwrite_begin(carl) \
+do { \
+ int __nreg = 0, __err = 0; \
+ struct ar9170 *__carl = carl; \
+ struct carl9170_cmd *__cmd; \
+ carl9170_async_get_buf(); \
+
+#define carl9170_async_regwrite(r, v) do { \
+ __cmd->wreg.regs[__nreg].addr = cpu_to_le32(r); \
+ __cmd->wreg.regs[__nreg].val = cpu_to_le32(v); \
+ __nreg++; \
+ if ((__nreg >= PAYLOAD_MAX/2)) { \
+ if (IS_ACCEPTING_CMD(__carl)) { \
+ __cmd->hdr.len = 8 * __nreg; \
+ __err = __carl9170_exec_cmd(__carl, __cmd, true);\
+ __cmd = NULL; \
+ carl9170_async_get_buf(); \
+ } else { \
+ goto __async_regwrite_out; \
+ } \
+ __nreg = 0; \
+ if (__err) \
+ goto __async_regwrite_out; \
+ } \
+} while (0)
+
+#define carl9170_async_regwrite_finish() \
+__async_regwrite_out : \
+ if (__err == 0 && __nreg) { \
+ __cmd->hdr.len = 8 * __nreg; \
+ if (IS_ACCEPTING_CMD(__carl)) \
+ __err = __carl9170_exec_cmd(__carl, __cmd, true);\
+ __nreg = 0; \
+ }
+
+#define carl9170_async_regwrite_result() \
+ __err; \
+} while (0);
+
+#endif /* __CMD_H */
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c
new file mode 100644
index 000000000000..0ac1124c2a0b
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/debug.c
@@ -0,0 +1,902 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * debug(fs) probing
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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) 2008-2009 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/vmalloc.h>
+#include "carl9170.h"
+#include "cmd.h"
+
+#define ADD(buf, off, max, fmt, args...) \
+ off += snprintf(&buf[off], max - off, fmt, ##args);
+
+static int carl9170_debugfs_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+struct carl9170_debugfs_fops {
+ unsigned int read_bufsize;
+ mode_t attr;
+ char *(*read)(struct ar9170 *ar, char *buf, size_t bufsize,
+ ssize_t *len);
+ ssize_t (*write)(struct ar9170 *aru, const char *buf, size_t size);
+ const struct file_operations fops;
+
+ enum carl9170_device_state req_dev_state;
+};
+
+static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct carl9170_debugfs_fops *dfops;
+ struct ar9170 *ar;
+ char *buf = NULL, *res_buf = NULL;
+ ssize_t ret = 0;
+ int err = 0;
+
+ if (!count)
+ return 0;
+
+ ar = file->private_data;
+
+ if (!ar)
+ return -ENODEV;
+ dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops);
+
+ if (!dfops->read)
+ return -ENOSYS;
+
+ if (dfops->read_bufsize) {
+ buf = vmalloc(dfops->read_bufsize);
+ if (!buf)
+ return -ENOMEM;
+ }
+
+ mutex_lock(&ar->mutex);
+ if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) {
+ err = -ENODEV;
+ res_buf = buf;
+ goto out_free;
+ }
+
+ res_buf = dfops->read(ar, buf, dfops->read_bufsize, &ret);
+
+ if (ret > 0)
+ err = simple_read_from_buffer(userbuf, count, ppos,
+ res_buf, ret);
+ else
+ err = ret;
+
+ WARN_ON_ONCE(dfops->read_bufsize && (res_buf != buf));
+
+out_free:
+ vfree(res_buf);
+ mutex_unlock(&ar->mutex);
+ return err;
+}
+
+static ssize_t carl9170_debugfs_write(struct file *file,
+ const char __user *userbuf, size_t count, loff_t *ppos)
+{
+ struct carl9170_debugfs_fops *dfops;
+ struct ar9170 *ar;
+ char *buf = NULL;
+ int err = 0;
+
+ if (!count)
+ return 0;
+
+ if (count > PAGE_SIZE)
+ return -E2BIG;
+
+ ar = file->private_data;
+
+ if (!ar)
+ return -ENODEV;
+ dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops);
+
+ if (!dfops->write)
+ return -ENOSYS;
+
+ buf = vmalloc(count);
+ if (!buf)
+ return -ENOMEM;
+
+ if (copy_from_user(buf, userbuf, count)) {
+ err = -EFAULT;
+ goto out_free;
+ }
+
+ if (mutex_trylock(&ar->mutex) == 0) {
+ err = -EAGAIN;
+ goto out_free;
+ }
+
+ if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) {
+ err = -ENODEV;
+ goto out_unlock;
+ }
+
+ err = dfops->write(ar, buf, count);
+ if (err)
+ goto out_unlock;
+
+out_unlock:
+ mutex_unlock(&ar->mutex);
+
+out_free:
+ vfree(buf);
+ return err;
+}
+
+#define __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \
+ _attr, _dstate) \
+static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\
+ .read_bufsize = _read_bufsize, \
+ .read = _read, \
+ .write = _write, \
+ .attr = _attr, \
+ .req_dev_state = _dstate, \
+ .fops = { \
+ .open = carl9170_debugfs_open, \
+ .read = carl9170_debugfs_read, \
+ .write = carl9170_debugfs_write, \
+ .owner = THIS_MODULE \
+ }, \
+}
+
+#define DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, _attr) \
+ __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \
+ _attr, CARL9170_STARTED) \
+
+#define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) \
+ DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \
+ NULL, _read_bufsize, S_IRUSR)
+
+#define DEBUGFS_DECLARE_WO_FILE(name) \
+ DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\
+ 0, S_IWUSR)
+
+#define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize) \
+ DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \
+ carl9170_debugfs_##name ##_write, \
+ _read_bufsize, S_IRUSR | S_IWUSR)
+
+#define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate) \
+ __DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \
+ carl9170_debugfs_##name ##_write, \
+ _read_bufsize, S_IRUSR | S_IWUSR, _dstate)
+
+#define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...) \
+static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar, \
+ char *buf, size_t buf_size,\
+ ssize_t *len) \
+{ \
+ ADD(buf, *len, buf_size, fmt "\n", ##value); \
+ return buf; \
+} \
+DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize)
+
+static char *carl9170_debugfs_mem_usage_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ ADD(buf, *len, bufsize, "jar: [");
+
+ spin_lock_bh(&ar->mem_lock);
+
+ *len += bitmap_scnprintf(&buf[*len], bufsize - *len,
+ ar->mem_bitmap, ar->fw.mem_blocks);
+
+ ADD(buf, *len, bufsize, "]\n");
+
+ ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n",
+ bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks),
+ ar->fw.mem_blocks, atomic_read(&ar->mem_allocs));
+
+ ADD(buf, *len, bufsize, "memory: free:%3d (%3d KiB) / total:%3d KiB)\n",
+ atomic_read(&ar->mem_free_blocks),
+ (atomic_read(&ar->mem_free_blocks) * ar->fw.mem_block_size) / 1024,
+ (ar->fw.mem_blocks * ar->fw.mem_block_size) / 1024);
+
+ spin_unlock_bh(&ar->mem_lock);
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(mem_usage, 512);
+
+static char *carl9170_debugfs_qos_stat_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ ADD(buf, *len, bufsize, "%s QoS AC\n", modparam_noht ? "Hardware" :
+ "Software");
+
+ ADD(buf, *len, bufsize, "[ VO VI "
+ " BE BK ]\n");
+
+ spin_lock_bh(&ar->tx_stats_lock);
+ ADD(buf, *len, bufsize, "[length/limit length/limit "
+ "length/limit length/limit ]\n"
+ "[ %3d/%3d %3d/%3d "
+ " %3d/%3d %3d/%3d ]\n\n",
+ ar->tx_stats[0].len, ar->tx_stats[0].limit,
+ ar->tx_stats[1].len, ar->tx_stats[1].limit,
+ ar->tx_stats[2].len, ar->tx_stats[2].limit,
+ ar->tx_stats[3].len, ar->tx_stats[3].limit);
+
+ ADD(buf, *len, bufsize, "[ total total "
+ " total total ]\n"
+ "[%10d %10d %10d %10d ]\n\n",
+ ar->tx_stats[0].count, ar->tx_stats[1].count,
+ ar->tx_stats[2].count, ar->tx_stats[3].count);
+
+ spin_unlock_bh(&ar->tx_stats_lock);
+
+ ADD(buf, *len, bufsize, "[ pend/waittx pend/waittx "
+ " pend/waittx pend/waittx]\n"
+ "[ %3d/%3d %3d/%3d "
+ " %3d/%3d %3d/%3d ]\n\n",
+ skb_queue_len(&ar->tx_pending[0]),
+ skb_queue_len(&ar->tx_status[0]),
+ skb_queue_len(&ar->tx_pending[1]),
+ skb_queue_len(&ar->tx_status[1]),
+ skb_queue_len(&ar->tx_pending[2]),
+ skb_queue_len(&ar->tx_status[2]),
+ skb_queue_len(&ar->tx_pending[3]),
+ skb_queue_len(&ar->tx_status[3]));
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(qos_stat, 512);
+
+static void carl9170_debugfs_format_frame(struct ar9170 *ar,
+ struct sk_buff *skb, const char *prefix, char *buf,
+ ssize_t *off, ssize_t bufsize)
+{
+ struct _carl9170_tx_superframe *txc = (void *) skb->data;
+ struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
+ struct carl9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
+ struct ieee80211_hdr *hdr = (void *) txc->frame_data;
+
+ ADD(buf, *off, bufsize, "%s %p, c:%2x, DA:%pM, sq:%4d, mc:%.4x, "
+ "pc:%.8x, to:%d ms\n", prefix, skb, txc->s.cookie,
+ ieee80211_get_DA(hdr), get_seq_h(hdr),
+ le16_to_cpu(txc->f.mac_control), le32_to_cpu(txc->f.phy_control),
+ jiffies_to_msecs(jiffies - arinfo->timeout));
+}
+
+
+static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ struct carl9170_sta_tid *iter;
+ struct sk_buff *skb;
+ int cnt = 0, fc;
+ int offset;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
+
+ spin_lock_bh(&iter->lock);
+ ADD(buf, *len, bufsize, "Entry: #%2d TID:%1d, BSN:%4d, "
+ "SNX:%4d, HSN:%4d, BAW:%2d, state:%1d, toggles:%d\n",
+ cnt, iter->tid, iter->bsn, iter->snx, iter->hsn,
+ iter->max, iter->state, iter->counter);
+
+ ADD(buf, *len, bufsize, "\tWindow: [");
+
+ *len += bitmap_scnprintf(&buf[*len], bufsize - *len,
+ iter->bitmap, CARL9170_BAW_BITS);
+
+#define BM_STR_OFF(offset) \
+ ((CARL9170_BAW_BITS - (offset) - 1) / 4 + \
+ (CARL9170_BAW_BITS - (offset) - 1) / 32 + 1)
+
+ ADD(buf, *len, bufsize, ",W]\n");
+
+ offset = BM_STR_OFF(0);
+ ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T");
+
+ offset = BM_STR_OFF(SEQ_DIFF(iter->snx, iter->bsn));
+ ADD(buf, *len, bufsize, "\tNext Seq: %*s\n", offset, "W");
+
+ offset = BM_STR_OFF(((int)iter->hsn - (int)iter->bsn) %
+ CARL9170_BAW_BITS);
+ ADD(buf, *len, bufsize, "\tLast Seq: %*s\n", offset, "N");
+
+ ADD(buf, *len, bufsize, "\tPre-Aggregation reorder buffer: "
+ " currently queued:%d\n", skb_queue_len(&iter->queue));
+
+ fc = 0;
+ skb_queue_walk(&iter->queue, skb) {
+ char prefix[32];
+
+ snprintf(prefix, sizeof(prefix), "\t\t%3d :", fc);
+ carl9170_debugfs_format_frame(ar, skb, prefix, buf,
+ len, bufsize);
+
+ fc++;
+ }
+ spin_unlock_bh(&iter->lock);
+ cnt++;
+ }
+ rcu_read_unlock();
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(ampdu_state, 8000);
+
+static void carl9170_debugfs_queue_dump(struct ar9170 *ar, char *buf,
+ ssize_t *len, size_t bufsize, struct sk_buff_head *queue)
+{
+ struct sk_buff *skb;
+ char prefix[16];
+ int fc = 0;
+
+ spin_lock_bh(&queue->lock);
+ skb_queue_walk(queue, skb) {
+ snprintf(prefix, sizeof(prefix), "%3d :", fc);
+ carl9170_debugfs_format_frame(ar, skb, prefix, buf,
+ len, bufsize);
+ fc++;
+ }
+ spin_unlock_bh(&queue->lock);
+}
+
+#define DEBUGFS_QUEUE_DUMP(q, qi) \
+static char *carl9170_debugfs_##q ##_##qi ##_read(struct ar9170 *ar, \
+ char *buf, size_t bufsize, ssize_t *len) \
+{ \
+ carl9170_debugfs_queue_dump(ar, buf, len, bufsize, &ar->q[qi]); \
+ return buf; \
+} \
+DEBUGFS_DECLARE_RO_FILE(q##_##qi, 8000);
+
+static char *carl9170_debugfs_sta_psm_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ ADD(buf, *len, bufsize, "psm state: %s\n", (ar->ps.off_override ?
+ "FORCE CAM" : (ar->ps.state ? "PSM" : "CAM")));
+
+ ADD(buf, *len, bufsize, "sleep duration: %d ms.\n", ar->ps.sleep_ms);
+ ADD(buf, *len, bufsize, "last power-state transition: %d ms ago.\n",
+ jiffies_to_msecs(jiffies - ar->ps.last_action));
+ ADD(buf, *len, bufsize, "last CAM->PSM transition: %d ms ago.\n",
+ jiffies_to_msecs(jiffies - ar->ps.last_slept));
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(sta_psm, 160);
+
+static char *carl9170_debugfs_tx_stuck_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ int i;
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ ADD(buf, *len, bufsize, "TX queue [%d]: %10d max:%10d ms.\n",
+ i, ieee80211_queue_stopped(ar->hw, i) ?
+ jiffies_to_msecs(jiffies - ar->queue_stop_timeout[i]) : 0,
+ jiffies_to_msecs(ar->max_queue_stop_timeout[i]));
+
+ ar->max_queue_stop_timeout[i] = 0;
+ }
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(tx_stuck, 180);
+
+static char *carl9170_debugfs_phy_noise_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ int err;
+
+ err = carl9170_get_noisefloor(ar);
+ if (err) {
+ *len = err;
+ return buf;
+ }
+
+ ADD(buf, *len, bufsize, "Chain 0: %10d dBm, ext. chan.:%10d dBm\n",
+ ar->noise[0], ar->noise[2]);
+ ADD(buf, *len, bufsize, "Chain 2: %10d dBm, ext. chan.:%10d dBm\n",
+ ar->noise[1], ar->noise[3]);
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(phy_noise, 180);
+
+static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ struct carl9170_vif_info *iter;
+ int i = 0;
+
+ ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n",
+ ar->vifs, ar->fw.vif_num);
+
+ ADD(buf, *len, bufsize, "VIF bitmap: [");
+
+ *len += bitmap_scnprintf(&buf[*len], bufsize - *len,
+ &ar->vif_bitmap, ar->fw.vif_num);
+
+ ADD(buf, *len, bufsize, "]\n");
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(iter, &ar->vif_list, list) {
+ struct ieee80211_vif *vif = carl9170_get_vif(iter);
+ ADD(buf, *len, bufsize, "\t%d = [%s VIF, id:%d, type:%x "
+ " mac:%pM %s]\n", i, (carl9170_get_main_vif(ar) == vif ?
+ "Master" : " Slave"), iter->id, vif->type, vif->addr,
+ iter->enable_beacon ? "beaconing " : "");
+ i++;
+ }
+ rcu_read_unlock();
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(vif_dump, 8000);
+
+#define UPDATE_COUNTER(ar, name) ({ \
+ u32 __tmp[ARRAY_SIZE(name##_regs)]; \
+ unsigned int __i, __err = -ENODEV; \
+ \
+ for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) { \
+ __tmp[__i] = name##_regs[__i].reg; \
+ ar->debug.stats.name##_counter[__i] = 0; \
+ } \
+ \
+ if (IS_STARTED(ar)) \
+ __err = carl9170_read_mreg(ar, ARRAY_SIZE(name##_regs), \
+ __tmp, ar->debug.stats.name##_counter); \
+ (__err); })
+
+#define TALLY_SUM_UP(ar, name) do { \
+ unsigned int __i; \
+ \
+ for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) { \
+ ar->debug.stats.name##_sum[__i] += \
+ ar->debug.stats.name##_counter[__i]; \
+ } \
+} while (0)
+
+#define DEBUGFS_HW_TALLY_FILE(name, f) \
+static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar, \
+ char *dum, size_t bufsize, ssize_t *ret) \
+{ \
+ char *buf; \
+ int i, max_len, err; \
+ \
+ max_len = ARRAY_SIZE(name##_regs) * 80; \
+ buf = vmalloc(max_len); \
+ if (!buf) \
+ return NULL; \
+ \
+ err = UPDATE_COUNTER(ar, name); \
+ if (err) { \
+ *ret = err; \
+ return buf; \
+ } \
+ \
+ TALLY_SUM_UP(ar, name); \
+ \
+ for (i = 0; i < ARRAY_SIZE(name##_regs); i++) { \
+ ADD(buf, *ret, max_len, "%22s = %" f "[+%" f "]\n", \
+ name##_regs[i].nreg, ar->debug.stats.name ##_sum[i],\
+ ar->debug.stats.name ##_counter[i]); \
+ } \
+ \
+ return buf; \
+} \
+DEBUGFS_DECLARE_RO_FILE(name, 0);
+
+#define DEBUGFS_HW_REG_FILE(name, f) \
+static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar, \
+ char *dum, size_t bufsize, ssize_t *ret) \
+{ \
+ char *buf; \
+ int i, max_len, err; \
+ \
+ max_len = ARRAY_SIZE(name##_regs) * 80; \
+ buf = vmalloc(max_len); \
+ if (!buf) \
+ return NULL; \
+ \
+ err = UPDATE_COUNTER(ar, name); \
+ if (err) { \
+ *ret = err; \
+ return buf; \
+ } \
+ \
+ for (i = 0; i < ARRAY_SIZE(name##_regs); i++) { \
+ ADD(buf, *ret, max_len, "%22s = %" f "\n", \
+ name##_regs[i].nreg, \
+ ar->debug.stats.name##_counter[i]); \
+ } \
+ \
+ return buf; \
+} \
+DEBUGFS_DECLARE_RO_FILE(name, 0);
+
+static ssize_t carl9170_debugfs_hw_ioread32_write(struct ar9170 *ar,
+ const char *buf, size_t count)
+{
+ int err = 0, i, n = 0, max_len = 32, res;
+ unsigned int reg, tmp;
+
+ if (!count)
+ return 0;
+
+ if (count > max_len)
+ return -E2BIG;
+
+ res = sscanf(buf, "0x%X %d", &reg, &n);
+ if (res < 1) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (res == 1)
+ n = 1;
+
+ if (n > 15) {
+ err = -EMSGSIZE;
+ goto out;
+ }
+
+ if ((reg >= 0x280000) || ((reg + (n << 2)) >= 0x280000)) {
+ err = -EADDRNOTAVAIL;
+ goto out;
+ }
+
+ if (reg & 3) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ for (i = 0; i < n; i++) {
+ err = carl9170_read_reg(ar, reg + (i << 2), &tmp);
+ if (err)
+ goto out;
+
+ ar->debug.ring[ar->debug.ring_tail].reg = reg + (i << 2);
+ ar->debug.ring[ar->debug.ring_tail].value = tmp;
+ ar->debug.ring_tail++;
+ ar->debug.ring_tail %= CARL9170_DEBUG_RING_SIZE;
+ }
+
+out:
+ return err ? err : count;
+}
+
+static char *carl9170_debugfs_hw_ioread32_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *ret)
+{
+ int i = 0;
+
+ while (ar->debug.ring_head != ar->debug.ring_tail) {
+ ADD(buf, *ret, bufsize, "%.8x = %.8x\n",
+ ar->debug.ring[ar->debug.ring_head].reg,
+ ar->debug.ring[ar->debug.ring_head].value);
+
+ ar->debug.ring_head++;
+ ar->debug.ring_head %= CARL9170_DEBUG_RING_SIZE;
+
+ if (i++ == 64)
+ break;
+ }
+ ar->debug.ring_head = ar->debug.ring_tail;
+ return buf;
+}
+DEBUGFS_DECLARE_RW_FILE(hw_ioread32, CARL9170_DEBUG_RING_SIZE * 40);
+
+static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
+ size_t count)
+{
+ int err;
+
+ if (count < 1)
+ return -EINVAL;
+
+ switch (buf[0]) {
+ case 'F':
+ ar->needs_full_reset = true;
+ break;
+
+ case 'R':
+ if (!IS_STARTED(ar)) {
+ err = -EAGAIN;
+ goto out;
+ }
+
+ ar->needs_full_reset = false;
+ break;
+
+ case 'M':
+ err = carl9170_mac_reset(ar);
+ if (err < 0)
+ count = err;
+
+ goto out;
+
+ case 'P':
+ err = carl9170_set_channel(ar, ar->hw->conf.channel,
+ ar->hw->conf.channel_type, CARL9170_RFI_COLD);
+ if (err < 0)
+ count = err;
+
+ goto out;
+
+ default:
+ return -EINVAL;
+ }
+
+ carl9170_restart(ar, CARL9170_RR_USER_REQUEST);
+
+out:
+ return count;
+}
+
+static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *ret)
+{
+ ADD(buf, *ret, bufsize, "[P]hy reinit, [R]estart, [F]ull usb reset, "
+ "[M]ac reset\n");
+ ADD(buf, *ret, bufsize, "firmware restarts:%d, last reason:%d\n",
+ ar->restart_counter, ar->last_reason);
+ ADD(buf, *ret, bufsize, "phy reinit errors:%d (%d)\n",
+ ar->total_chan_fail, ar->chan_fail);
+ ADD(buf, *ret, bufsize, "reported firmware errors:%d\n",
+ ar->fw.err_counter);
+ ADD(buf, *ret, bufsize, "reported firmware BUGs:%d\n",
+ ar->fw.bug_counter);
+ ADD(buf, *ret, bufsize, "pending restart requests:%d\n",
+ atomic_read(&ar->pending_restarts));
+ return buf;
+}
+__DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED);
+
+static const char *erp_modes[] = {
+ [CARL9170_ERP_INVALID] = "INVALID",
+ [CARL9170_ERP_AUTO] = "Automatic",
+ [CARL9170_ERP_MAC80211] = "Set by MAC80211",
+ [CARL9170_ERP_OFF] = "Force Off",
+ [CARL9170_ERP_RTS] = "Force RTS",
+ [CARL9170_ERP_CTS] = "Force CTS"
+};
+
+static char *carl9170_debugfs_erp_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *ret)
+{
+ ADD(buf, *ret, bufsize, "ERP Setting: (%d) -> %s\n", ar->erp_mode,
+ erp_modes[ar->erp_mode]);
+ return buf;
+}
+
+static ssize_t carl9170_debugfs_erp_write(struct ar9170 *ar, const char *buf,
+ size_t count)
+{
+ int res, val;
+
+ if (count < 1)
+ return -EINVAL;
+
+ res = sscanf(buf, "%d", &val);
+ if (res != 1)
+ return -EINVAL;
+
+ if (!((val > CARL9170_ERP_INVALID) &&
+ (val < __CARL9170_ERP_NUM)))
+ return -EINVAL;
+
+ ar->erp_mode = val;
+ return count;
+}
+
+DEBUGFS_DECLARE_RW_FILE(erp, 80);
+
+static ssize_t carl9170_debugfs_hw_iowrite32_write(struct ar9170 *ar,
+ const char *buf, size_t count)
+{
+ int err = 0, max_len = 22, res;
+ u32 reg, val;
+
+ if (!count)
+ return 0;
+
+ if (count > max_len)
+ return -E2BIG;
+
+ res = sscanf(buf, "0x%X 0x%X", &reg, &val);
+ if (res != 2) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (reg <= 0x100000 || reg >= 0x280000) {
+ err = -EADDRNOTAVAIL;
+ goto out;
+ }
+
+ if (reg & 3) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ err = carl9170_write_reg(ar, reg, val);
+ if (err)
+ goto out;
+
+out:
+ return err ? err : count;
+}
+DEBUGFS_DECLARE_WO_FILE(hw_iowrite32);
+
+DEBUGFS_HW_TALLY_FILE(hw_tx_tally, "u");
+DEBUGFS_HW_TALLY_FILE(hw_rx_tally, "u");
+DEBUGFS_HW_TALLY_FILE(hw_phy_errors, "u");
+DEBUGFS_HW_REG_FILE(hw_wlan_queue, ".8x");
+DEBUGFS_HW_REG_FILE(hw_pta_queue, ".8x");
+DEBUGFS_HW_REG_FILE(hw_ampdu_info, ".8x");
+DEBUGFS_QUEUE_DUMP(tx_status, 0);
+DEBUGFS_QUEUE_DUMP(tx_status, 1);
+DEBUGFS_QUEUE_DUMP(tx_status, 2);
+DEBUGFS_QUEUE_DUMP(tx_status, 3);
+DEBUGFS_QUEUE_DUMP(tx_pending, 0);
+DEBUGFS_QUEUE_DUMP(tx_pending, 1);
+DEBUGFS_QUEUE_DUMP(tx_pending, 2);
+DEBUGFS_QUEUE_DUMP(tx_pending, 3);
+DEBUGFS_READONLY_FILE(usb_tx_anch_urbs, 20, "%d",
+ atomic_read(&ar->tx_anch_urbs));
+DEBUGFS_READONLY_FILE(usb_rx_anch_urbs, 20, "%d",
+ atomic_read(&ar->rx_anch_urbs));
+DEBUGFS_READONLY_FILE(usb_rx_work_urbs, 20, "%d",
+ atomic_read(&ar->rx_work_urbs));
+DEBUGFS_READONLY_FILE(usb_rx_pool_urbs, 20, "%d",
+ atomic_read(&ar->rx_pool_urbs));
+
+DEBUGFS_READONLY_FILE(tx_total_queued, 20, "%d",
+ atomic_read(&ar->tx_total_queued));
+DEBUGFS_READONLY_FILE(tx_ampdu_scheduler, 20, "%d",
+ atomic_read(&ar->tx_ampdu_scheduler));
+
+DEBUGFS_READONLY_FILE(tx_total_pending, 20, "%d",
+ atomic_read(&ar->tx_total_pending));
+
+DEBUGFS_READONLY_FILE(tx_ampdu_list_len, 20, "%d",
+ ar->tx_ampdu_list_len);
+
+DEBUGFS_READONLY_FILE(tx_ampdu_upload, 20, "%d",
+ atomic_read(&ar->tx_ampdu_upload));
+
+DEBUGFS_READONLY_FILE(tx_janitor_last_run, 64, "last run:%d ms ago",
+ jiffies_to_msecs(jiffies - ar->tx_janitor_last_run));
+
+DEBUGFS_READONLY_FILE(tx_dropped, 20, "%d", ar->tx_dropped);
+
+DEBUGFS_READONLY_FILE(rx_dropped, 20, "%d", ar->rx_dropped);
+
+DEBUGFS_READONLY_FILE(sniffer_enabled, 20, "%d", ar->sniffer_enabled);
+DEBUGFS_READONLY_FILE(rx_software_decryption, 20, "%d",
+ ar->rx_software_decryption);
+DEBUGFS_READONLY_FILE(ampdu_factor, 20, "%d",
+ ar->current_factor);
+DEBUGFS_READONLY_FILE(ampdu_density, 20, "%d",
+ ar->current_density);
+
+DEBUGFS_READONLY_FILE(beacon_int, 20, "%d TU", ar->global_beacon_int);
+DEBUGFS_READONLY_FILE(pretbtt, 20, "%d TU", ar->global_pretbtt);
+
+void carl9170_debugfs_register(struct ar9170 *ar)
+{
+ ar->debug_dir = debugfs_create_dir(KBUILD_MODNAME,
+ ar->hw->wiphy->debugfsdir);
+
+#define DEBUGFS_ADD(name) \
+ debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr, \
+ ar->debug_dir, ar, \
+ &carl_debugfs_##name ## _ops.fops);
+
+ DEBUGFS_ADD(usb_tx_anch_urbs);
+ DEBUGFS_ADD(usb_rx_pool_urbs);
+ DEBUGFS_ADD(usb_rx_anch_urbs);
+ DEBUGFS_ADD(usb_rx_work_urbs);
+
+ DEBUGFS_ADD(tx_total_queued);
+ DEBUGFS_ADD(tx_total_pending);
+ DEBUGFS_ADD(tx_dropped);
+ DEBUGFS_ADD(tx_stuck);
+ DEBUGFS_ADD(tx_ampdu_upload);
+ DEBUGFS_ADD(tx_ampdu_scheduler);
+ DEBUGFS_ADD(tx_ampdu_list_len);
+
+ DEBUGFS_ADD(rx_dropped);
+ DEBUGFS_ADD(sniffer_enabled);
+ DEBUGFS_ADD(rx_software_decryption);
+
+ DEBUGFS_ADD(mem_usage);
+ DEBUGFS_ADD(qos_stat);
+ DEBUGFS_ADD(sta_psm);
+ DEBUGFS_ADD(ampdu_state);
+
+ DEBUGFS_ADD(hw_tx_tally);
+ DEBUGFS_ADD(hw_rx_tally);
+ DEBUGFS_ADD(hw_phy_errors);
+ DEBUGFS_ADD(phy_noise);
+
+ DEBUGFS_ADD(hw_wlan_queue);
+ DEBUGFS_ADD(hw_pta_queue);
+ DEBUGFS_ADD(hw_ampdu_info);
+
+ DEBUGFS_ADD(ampdu_density);
+ DEBUGFS_ADD(ampdu_factor);
+
+ DEBUGFS_ADD(tx_janitor_last_run);
+
+ DEBUGFS_ADD(tx_status_0);
+ DEBUGFS_ADD(tx_status_1);
+ DEBUGFS_ADD(tx_status_2);
+ DEBUGFS_ADD(tx_status_3);
+
+ DEBUGFS_ADD(tx_pending_0);
+ DEBUGFS_ADD(tx_pending_1);
+ DEBUGFS_ADD(tx_pending_2);
+ DEBUGFS_ADD(tx_pending_3);
+
+ DEBUGFS_ADD(hw_ioread32);
+ DEBUGFS_ADD(hw_iowrite32);
+ DEBUGFS_ADD(bug);
+
+ DEBUGFS_ADD(erp);
+
+ DEBUGFS_ADD(vif_dump);
+
+ DEBUGFS_ADD(beacon_int);
+ DEBUGFS_ADD(pretbtt);
+
+#undef DEBUGFS_ADD
+}
+
+void carl9170_debugfs_unregister(struct ar9170 *ar)
+{
+ debugfs_remove_recursive(ar->debug_dir);
+}
diff --git a/drivers/net/wireless/ath/carl9170/debug.h b/drivers/net/wireless/ath/carl9170/debug.h
new file mode 100644
index 000000000000..ea4b97524122
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/debug.h
@@ -0,0 +1,134 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * debug header
+ *
+ * Copyright 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 __DEBUG_H
+#define __DEBUG_H
+
+#include "eeprom.h"
+#include "wlan.h"
+#include "hw.h"
+#include "fwdesc.h"
+#include "fwcmd.h"
+#include "../regd.h"
+
+struct hw_stat_reg_entry {
+ u32 reg;
+ char nreg[32];
+};
+
+#define STAT_MAC_REG(reg) \
+ { (AR9170_MAC_REG_##reg), #reg }
+
+#define STAT_PTA_REG(reg) \
+ { (AR9170_PTA_REG_##reg), #reg }
+
+#define STAT_USB_REG(reg) \
+ { (AR9170_USB_REG_##reg), #reg }
+
+static const struct hw_stat_reg_entry hw_rx_tally_regs[] = {
+ STAT_MAC_REG(RX_CRC32), STAT_MAC_REG(RX_CRC16),
+ STAT_MAC_REG(RX_TIMEOUT_COUNT), STAT_MAC_REG(RX_ERR_DECRYPTION_UNI),
+ STAT_MAC_REG(RX_ERR_DECRYPTION_MUL), STAT_MAC_REG(RX_MPDU),
+ STAT_MAC_REG(RX_DROPPED_MPDU), STAT_MAC_REG(RX_DEL_MPDU),
+};
+
+static const struct hw_stat_reg_entry hw_phy_errors_regs[] = {
+ STAT_MAC_REG(RX_PHY_MISC_ERROR), STAT_MAC_REG(RX_PHY_XR_ERROR),
+ STAT_MAC_REG(RX_PHY_OFDM_ERROR), STAT_MAC_REG(RX_PHY_CCK_ERROR),
+ STAT_MAC_REG(RX_PHY_HT_ERROR), STAT_MAC_REG(RX_PHY_TOTAL),
+};
+
+static const struct hw_stat_reg_entry hw_tx_tally_regs[] = {
+ STAT_MAC_REG(TX_TOTAL), STAT_MAC_REG(TX_UNDERRUN),
+ STAT_MAC_REG(TX_RETRY),
+};
+
+static const struct hw_stat_reg_entry hw_wlan_queue_regs[] = {
+ STAT_MAC_REG(DMA_STATUS), STAT_MAC_REG(DMA_TRIGGER),
+ STAT_MAC_REG(DMA_TXQ0_ADDR), STAT_MAC_REG(DMA_TXQ0_CURR_ADDR),
+ STAT_MAC_REG(DMA_TXQ1_ADDR), STAT_MAC_REG(DMA_TXQ1_CURR_ADDR),
+ STAT_MAC_REG(DMA_TXQ2_ADDR), STAT_MAC_REG(DMA_TXQ2_CURR_ADDR),
+ STAT_MAC_REG(DMA_TXQ3_ADDR), STAT_MAC_REG(DMA_TXQ3_CURR_ADDR),
+ STAT_MAC_REG(DMA_RXQ_ADDR), STAT_MAC_REG(DMA_RXQ_CURR_ADDR),
+};
+
+static const struct hw_stat_reg_entry hw_ampdu_info_regs[] = {
+ STAT_MAC_REG(AMPDU_DENSITY), STAT_MAC_REG(AMPDU_FACTOR),
+};
+
+static const struct hw_stat_reg_entry hw_pta_queue_regs[] = {
+ STAT_PTA_REG(DN_CURR_ADDRH), STAT_PTA_REG(DN_CURR_ADDRL),
+ STAT_PTA_REG(UP_CURR_ADDRH), STAT_PTA_REG(UP_CURR_ADDRL),
+ STAT_PTA_REG(DMA_STATUS), STAT_PTA_REG(DMA_MODE_CTRL),
+};
+
+#define DEFINE_TALLY(name) \
+ u32 name##_sum[ARRAY_SIZE(name##_regs)], \
+ name##_counter[ARRAY_SIZE(name##_regs)] \
+
+#define DEFINE_STAT(name) \
+ u32 name##_counter[ARRAY_SIZE(name##_regs)] \
+
+struct ath_stats {
+ DEFINE_TALLY(hw_tx_tally);
+ DEFINE_TALLY(hw_rx_tally);
+ DEFINE_TALLY(hw_phy_errors);
+ DEFINE_STAT(hw_wlan_queue);
+ DEFINE_STAT(hw_pta_queue);
+ DEFINE_STAT(hw_ampdu_info);
+};
+
+struct carl9170_debug_mem_rbe {
+ u32 reg;
+ u32 value;
+};
+
+#define CARL9170_DEBUG_RING_SIZE 64
+
+struct carl9170_debug {
+ struct ath_stats stats;
+ struct carl9170_debug_mem_rbe ring[CARL9170_DEBUG_RING_SIZE];
+ struct mutex ring_lock;
+ unsigned int ring_head, ring_tail;
+ struct delayed_work update_tally;
+};
+
+struct ar9170;
+
+void carl9170_debugfs_register(struct ar9170 *ar);
+void carl9170_debugfs_unregister(struct ar9170 *ar);
+#endif /* __DEBUG_H */
diff --git a/drivers/net/wireless/ath/carl9170/eeprom.h b/drivers/net/wireless/ath/carl9170/eeprom.h
new file mode 100644
index 000000000000..7cff40ac7759
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/eeprom.h
@@ -0,0 +1,216 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * 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 __CARL9170_SHARED_EEPROM_H
+#define __CARL9170_SHARED_EEPROM_H
+
+#define AR9170_EEPROM_START 0x1600
+
+#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;
+
+#define AR9170_LED_MODE_POWER_ON 0x0001
+#define AR9170_LED_MODE_RESERVED 0x0002
+#define AR9170_LED_MODE_DISABLE_STATE 0x0004
+#define AR9170_LED_MODE_OFF_IN_PSM 0x0008
+
+/* AR9170_LED_MODE BIT is set */
+#define AR9170_LED_MODE_FREQUENCY_S 4
+#define AR9170_LED_MODE_FREQUENCY 0x0030
+#define AR9170_LED_MODE_FREQUENCY_1HZ 0x0000
+#define AR9170_LED_MODE_FREQUENCY_0_5HZ 0x0010
+#define AR9170_LED_MODE_FREQUENCY_0_25HZ 0x0020
+#define AR9170_LED_MODE_FREQUENCY_0_125HZ 0x0030
+
+/* AR9170_LED_MODE BIT is not set */
+#define AR9170_LED_MODE_CONN_STATE_S 4
+#define AR9170_LED_MODE_CONN_STATE 0x0030
+#define AR9170_LED_MODE_CONN_STATE_FORCE_OFF 0x0000
+#define AR9170_LED_MODE_CONN_STATE_FORCE_ON 0x0010
+/* Idle off / Active on */
+#define AR9170_LED_MODE_CONN_STATE_IOFF_AON 0x0020
+/* Idle on / Active off */
+#define AR9170_LED_MODE_CONN_STATE_ION_AOFF 0x0010
+
+#define AR9170_LED_MODE_MODE 0x0040
+#define AR9170_LED_MODE_RESERVED2 0x0080
+
+#define AR9170_LED_MODE_TON_SCAN_S 8
+#define AR9170_LED_MODE_TON_SCAN 0x0f00
+
+#define AR9170_LED_MODE_TOFF_SCAN_S 12
+#define AR9170_LED_MODE_TOFF_SCAN 0xf000
+
+struct ar9170_led_mode {
+ __le16 led;
+};
+
+#endif /* __CARL9170_SHARED_EEPROM_H */
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
new file mode 100644
index 000000000000..ae6c006bbc56
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -0,0 +1,402 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * firmware parser
+ *
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/.
+ */
+
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+#include <linux/crc32.h>
+#include "carl9170.h"
+#include "fwcmd.h"
+#include "version.h"
+
+#define MAKE_STR(symbol) #symbol
+#define TO_STR(symbol) MAKE_STR(symbol)
+#define CARL9170FW_API_VER_STR TO_STR(CARL9170FW_API_MAX_VER)
+MODULE_VERSION(CARL9170FW_API_VER_STR ":" CARL9170FW_VERSION_GIT);
+
+static const u8 otus_magic[4] = { OTUS_MAGIC };
+
+static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4],
+ const unsigned int len, const u8 compatible_revision)
+{
+ const struct carl9170fw_desc_head *iter;
+
+ carl9170fw_for_each_hdr(iter, ar->fw.desc) {
+ if (carl9170fw_desc_cmp(iter, descid, len,
+ compatible_revision))
+ return (void *)iter;
+ }
+
+ /* needed to find the LAST desc */
+ if (carl9170fw_desc_cmp(iter, descid, len,
+ compatible_revision))
+ return (void *)iter;
+
+ return NULL;
+}
+
+static int carl9170_fw_verify_descs(struct ar9170 *ar,
+ const struct carl9170fw_desc_head *head, unsigned int max_len)
+{
+ const struct carl9170fw_desc_head *pos;
+ unsigned long pos_addr, end_addr;
+ unsigned int pos_length;
+
+ if (max_len < sizeof(*pos))
+ return -ENODATA;
+
+ max_len = min_t(unsigned int, CARL9170FW_DESC_MAX_LENGTH, max_len);
+
+ pos = head;
+ pos_addr = (unsigned long) pos;
+ end_addr = pos_addr + max_len;
+
+ while (pos_addr < end_addr) {
+ if (pos_addr + sizeof(*head) > end_addr)
+ return -E2BIG;
+
+ pos_length = le16_to_cpu(pos->length);
+
+ if (pos_length < sizeof(*head))
+ return -EBADMSG;
+
+ if (pos_length > max_len)
+ return -EOVERFLOW;
+
+ if (pos_addr + pos_length > end_addr)
+ return -EMSGSIZE;
+
+ if (carl9170fw_desc_cmp(pos, LAST_MAGIC,
+ CARL9170FW_LAST_DESC_SIZE,
+ CARL9170FW_LAST_DESC_CUR_VER))
+ return 0;
+
+ pos_addr += pos_length;
+ pos = (void *)pos_addr;
+ max_len -= pos_length;
+ }
+ return -EINVAL;
+}
+
+static void carl9170_fw_info(struct ar9170 *ar)
+{
+ const struct carl9170fw_motd_desc *motd_desc;
+ unsigned int str_ver_len;
+ u32 fw_date;
+
+ dev_info(&ar->udev->dev, "driver API: %s 2%03d-%02d-%02d [%d-%d]\n",
+ CARL9170FW_VERSION_GIT, CARL9170FW_VERSION_YEAR,
+ CARL9170FW_VERSION_MONTH, CARL9170FW_VERSION_DAY,
+ CARL9170FW_API_MIN_VER, CARL9170FW_API_MAX_VER);
+
+ motd_desc = carl9170_fw_find_desc(ar, MOTD_MAGIC,
+ sizeof(*motd_desc), CARL9170FW_MOTD_DESC_CUR_VER);
+
+ if (motd_desc) {
+ str_ver_len = strnlen(motd_desc->release,
+ CARL9170FW_MOTD_RELEASE_LEN);
+
+ fw_date = le32_to_cpu(motd_desc->fw_year_month_day);
+
+ dev_info(&ar->udev->dev, "firmware API: %.*s 2%03d-%02d-%02d\n",
+ str_ver_len, motd_desc->release,
+ CARL9170FW_GET_YEAR(fw_date),
+ CARL9170FW_GET_MONTH(fw_date),
+ CARL9170FW_GET_DAY(fw_date));
+
+ strlcpy(ar->hw->wiphy->fw_version, motd_desc->release,
+ sizeof(ar->hw->wiphy->fw_version));
+ }
+}
+
+static bool valid_dma_addr(const u32 address)
+{
+ if (address >= AR9170_SRAM_OFFSET &&
+ address < (AR9170_SRAM_OFFSET + AR9170_SRAM_SIZE))
+ return true;
+
+ return false;
+}
+
+static bool valid_cpu_addr(const u32 address)
+{
+ if (valid_dma_addr(address) || (address >= AR9170_PRAM_OFFSET &&
+ address < (AR9170_PRAM_OFFSET + AR9170_PRAM_SIZE)))
+ return true;
+
+ return false;
+}
+
+static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
+{
+ const struct carl9170fw_otus_desc *otus_desc;
+ const struct carl9170fw_chk_desc *chk_desc;
+ const struct carl9170fw_last_desc *last_desc;
+
+ last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC,
+ sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER);
+ if (!last_desc)
+ return -EINVAL;
+
+ otus_desc = carl9170_fw_find_desc(ar, OTUS_MAGIC,
+ sizeof(*otus_desc), CARL9170FW_OTUS_DESC_CUR_VER);
+ if (!otus_desc) {
+ dev_err(&ar->udev->dev, "failed to find compatible firmware "
+ "descriptor.\n");
+ return -ENODATA;
+ }
+
+ chk_desc = carl9170_fw_find_desc(ar, CHK_MAGIC,
+ sizeof(*chk_desc), CARL9170FW_CHK_DESC_CUR_VER);
+
+ if (chk_desc) {
+ unsigned long fin, diff;
+ unsigned int dsc_len;
+ u32 crc32;
+
+ dsc_len = min_t(unsigned int, len,
+ (unsigned long)chk_desc - (unsigned long)otus_desc);
+
+ fin = (unsigned long) last_desc + sizeof(*last_desc);
+ diff = fin - (unsigned long) otus_desc;
+
+ if (diff < len)
+ len -= diff;
+
+ if (len < 256)
+ return -EIO;
+
+ crc32 = crc32_le(~0, data, len);
+ if (cpu_to_le32(crc32) != chk_desc->fw_crc32) {
+ dev_err(&ar->udev->dev, "fw checksum test failed.\n");
+ return -ENOEXEC;
+ }
+
+ crc32 = crc32_le(crc32, (void *)otus_desc, dsc_len);
+ if (cpu_to_le32(crc32) != chk_desc->hdr_crc32) {
+ dev_err(&ar->udev->dev, "descriptor check failed.\n");
+ return -EINVAL;
+ }
+ } else {
+ dev_warn(&ar->udev->dev, "Unprotected firmware image.\n");
+ }
+
+#define SUPP(feat) \
+ (carl9170fw_supports(otus_desc->feature_set, feat))
+
+ if (!SUPP(CARL9170FW_DUMMY_FEATURE)) {
+ dev_err(&ar->udev->dev, "invalid firmware descriptor "
+ "format detected.\n");
+ return -EINVAL;
+ }
+
+ ar->fw.api_version = otus_desc->api_ver;
+
+ if (ar->fw.api_version < CARL9170FW_API_MIN_VER ||
+ ar->fw.api_version > CARL9170FW_API_MAX_VER) {
+ dev_err(&ar->udev->dev, "unsupported firmware api version.\n");
+ return -EINVAL;
+ }
+
+ if (!SUPP(CARL9170FW_COMMAND_PHY) || SUPP(CARL9170FW_UNUSABLE) ||
+ !SUPP(CARL9170FW_HANDLE_BACK_REQ)) {
+ dev_err(&ar->udev->dev, "firmware does support "
+ "mandatory features.\n");
+ return -ECANCELED;
+ }
+
+ if (ilog2(le32_to_cpu(otus_desc->feature_set)) >=
+ __CARL9170FW_FEATURE_NUM) {
+ dev_warn(&ar->udev->dev, "driver does not support all "
+ "firmware features.\n");
+ }
+
+ if (!SUPP(CARL9170FW_COMMAND_CAM)) {
+ dev_info(&ar->udev->dev, "crypto offloading is disabled "
+ "by firmware.\n");
+ ar->disable_offload = true;
+ }
+
+ if (SUPP(CARL9170FW_PSM))
+ ar->hw->flags |= IEEE80211_HW_SUPPORTS_PS;
+
+ if (!SUPP(CARL9170FW_USB_INIT_FIRMWARE)) {
+ dev_err(&ar->udev->dev, "firmware does not provide "
+ "mandatory interfaces.\n");
+ return -EINVAL;
+ }
+
+ if (SUPP(CARL9170FW_MINIBOOT))
+ ar->fw.offset = le16_to_cpu(otus_desc->miniboot_size);
+ else
+ ar->fw.offset = 0;
+
+ if (SUPP(CARL9170FW_USB_DOWN_STREAM)) {
+ ar->hw->extra_tx_headroom += sizeof(struct ar9170_stream);
+ ar->fw.tx_stream = true;
+ }
+
+ if (SUPP(CARL9170FW_USB_UP_STREAM))
+ ar->fw.rx_stream = true;
+
+ if (SUPP(CARL9170FW_RX_FILTER)) {
+ ar->fw.rx_filter = true;
+ ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL |
+ FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS |
+ FIF_PROMISC_IN_BSS;
+ }
+
+ ar->fw.vif_num = otus_desc->vif_num;
+ ar->fw.cmd_bufs = otus_desc->cmd_bufs;
+ ar->fw.address = le32_to_cpu(otus_desc->fw_address);
+ ar->fw.rx_size = le16_to_cpu(otus_desc->rx_max_frame_len);
+ ar->fw.mem_blocks = min_t(unsigned int, otus_desc->tx_descs, 0xfe);
+ atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks);
+ ar->fw.mem_block_size = le16_to_cpu(otus_desc->tx_frag_len);
+
+ if (ar->fw.vif_num >= AR9170_MAX_VIRTUAL_MAC || !ar->fw.vif_num ||
+ ar->fw.mem_blocks < 16 || !ar->fw.cmd_bufs ||
+ ar->fw.mem_block_size < 64 || ar->fw.mem_block_size > 512 ||
+ ar->fw.rx_size > 32768 || ar->fw.rx_size < 4096 ||
+ !valid_cpu_addr(ar->fw.address)) {
+ dev_err(&ar->udev->dev, "firmware shows obvious signs of "
+ "malicious tampering.\n");
+ return -EINVAL;
+ }
+
+ ar->fw.beacon_addr = le32_to_cpu(otus_desc->bcn_addr);
+ ar->fw.beacon_max_len = le16_to_cpu(otus_desc->bcn_len);
+
+ if (valid_dma_addr(ar->fw.beacon_addr) && ar->fw.beacon_max_len >=
+ AR9170_MAC_BCN_LENGTH_MAX) {
+ ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
+
+ if (SUPP(CARL9170FW_WLANTX_CAB)) {
+ ar->hw->wiphy->interface_modes |=
+ BIT(NL80211_IFTYPE_AP);
+ }
+ }
+
+#undef SUPPORTED
+ return 0;
+}
+
+static struct carl9170fw_desc_head *
+carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len)
+
+{
+ int scan = 0, found = 0;
+
+ if (!carl9170fw_size_check(len)) {
+ dev_err(&ar->udev->dev, "firmware size is out of bound.\n");
+ return NULL;
+ }
+
+ while (scan < len - sizeof(struct carl9170fw_desc_head)) {
+ if (fw_data[scan++] == otus_magic[found])
+ found++;
+ else
+ found = 0;
+
+ if (scan >= len)
+ break;
+
+ if (found == sizeof(otus_magic))
+ break;
+ }
+
+ if (found != sizeof(otus_magic))
+ return NULL;
+
+ return (void *)&fw_data[scan - found];
+}
+
+int carl9170_fw_fix_eeprom(struct ar9170 *ar)
+{
+ const struct carl9170fw_fix_desc *fix_desc = NULL;
+ unsigned int i, n, off;
+ u32 *data = (void *)&ar->eeprom;
+
+ fix_desc = carl9170_fw_find_desc(ar, FIX_MAGIC,
+ sizeof(*fix_desc), CARL9170FW_FIX_DESC_CUR_VER);
+
+ if (!fix_desc)
+ return 0;
+
+ n = (le16_to_cpu(fix_desc->head.length) - sizeof(*fix_desc)) /
+ sizeof(struct carl9170fw_fix_entry);
+
+ for (i = 0; i < n; i++) {
+ off = le32_to_cpu(fix_desc->data[i].address) -
+ AR9170_EEPROM_START;
+
+ if (off >= sizeof(struct ar9170_eeprom) || (off & 3)) {
+ dev_err(&ar->udev->dev, "Skip invalid entry %d\n", i);
+ continue;
+ }
+
+ data[off / sizeof(*data)] &=
+ le32_to_cpu(fix_desc->data[i].mask);
+ data[off / sizeof(*data)] |=
+ le32_to_cpu(fix_desc->data[i].value);
+ }
+
+ return 0;
+}
+
+int carl9170_parse_firmware(struct ar9170 *ar)
+{
+ const struct carl9170fw_desc_head *fw_desc = NULL;
+ const struct firmware *fw = ar->fw.fw;
+ unsigned long header_offset = 0;
+ int err;
+
+ if (WARN_ON(!fw))
+ return -EINVAL;
+
+ fw_desc = carl9170_find_fw_desc(ar, fw->data, fw->size);
+
+ if (!fw_desc) {
+ dev_err(&ar->udev->dev, "unsupported firmware.\n");
+ return -ENODATA;
+ }
+
+ header_offset = (unsigned long)fw_desc - (unsigned long)fw->data;
+
+ err = carl9170_fw_verify_descs(ar, fw_desc, fw->size - header_offset);
+ if (err) {
+ dev_err(&ar->udev->dev, "damaged firmware (%d).\n", err);
+ return err;
+ }
+
+ ar->fw.desc = fw_desc;
+
+ carl9170_fw_info(ar);
+
+ err = carl9170_fw(ar, fw->data, fw->size);
+ if (err) {
+ dev_err(&ar->udev->dev, "failed to parse firmware (%d).\n",
+ err);
+ return err;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
new file mode 100644
index 000000000000..d552166db505
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -0,0 +1,284 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * Firmware command interface definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * 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 __CARL9170_SHARED_FWCMD_H
+#define __CARL9170_SHARED_FWCMD_H
+
+#define CARL9170_MAX_CMD_LEN 64
+#define CARL9170_MAX_CMD_PAYLOAD_LEN 60
+
+#define CARL9170FW_API_MIN_VER 1
+#define CARL9170FW_API_MAX_VER 1
+
+enum carl9170_cmd_oids {
+ CARL9170_CMD_RREG = 0x00,
+ CARL9170_CMD_WREG = 0x01,
+ CARL9170_CMD_ECHO = 0x02,
+ CARL9170_CMD_SWRST = 0x03,
+ CARL9170_CMD_REBOOT = 0x04,
+ CARL9170_CMD_BCN_CTRL = 0x05,
+ CARL9170_CMD_READ_TSF = 0x06,
+ CARL9170_CMD_RX_FILTER = 0x07,
+
+ /* CAM */
+ CARL9170_CMD_EKEY = 0x10,
+ CARL9170_CMD_DKEY = 0x11,
+
+ /* RF / PHY */
+ CARL9170_CMD_FREQUENCY = 0x20,
+ CARL9170_CMD_RF_INIT = 0x21,
+ CARL9170_CMD_SYNTH = 0x22,
+ CARL9170_CMD_FREQ_START = 0x23,
+ CARL9170_CMD_PSM = 0x24,
+
+ /* Asychronous command flag */
+ CARL9170_CMD_ASYNC_FLAG = 0x40,
+ CARL9170_CMD_WREG_ASYNC = (CARL9170_CMD_WREG |
+ CARL9170_CMD_ASYNC_FLAG),
+ CARL9170_CMD_REBOOT_ASYNC = (CARL9170_CMD_REBOOT |
+ CARL9170_CMD_ASYNC_FLAG),
+ CARL9170_CMD_BCN_CTRL_ASYNC = (CARL9170_CMD_BCN_CTRL |
+ CARL9170_CMD_ASYNC_FLAG),
+ CARL9170_CMD_PSM_ASYNC = (CARL9170_CMD_PSM |
+ CARL9170_CMD_ASYNC_FLAG),
+
+ /* responses and traps */
+ CARL9170_RSP_FLAG = 0xc0,
+ CARL9170_RSP_PRETBTT = 0xc0,
+ CARL9170_RSP_TXCOMP = 0xc1,
+ CARL9170_RSP_BEACON_CONFIG = 0xc2,
+ CARL9170_RSP_ATIM = 0xc3,
+ CARL9170_RSP_WATCHDOG = 0xc6,
+ CARL9170_RSP_TEXT = 0xca,
+ CARL9170_RSP_HEXDUMP = 0xcc,
+ CARL9170_RSP_RADAR = 0xcd,
+ CARL9170_RSP_GPIO = 0xce,
+ CARL9170_RSP_BOOT = 0xcf,
+};
+
+struct carl9170_set_key_cmd {
+ __le16 user;
+ __le16 keyId;
+ __le16 type;
+ u8 macAddr[6];
+ u32 key[4];
+} __packed;
+#define CARL9170_SET_KEY_CMD_SIZE 28
+
+struct carl9170_disable_key_cmd {
+ __le16 user;
+ __le16 padding;
+} __packed;
+#define CARL9170_DISABLE_KEY_CMD_SIZE 4
+
+struct carl9170_u32_list {
+ u32 vals[0];
+} __packed;
+
+struct carl9170_reg_list {
+ __le32 regs[0];
+} __packed;
+
+struct carl9170_write_reg {
+ struct {
+ __le32 addr;
+ __le32 val;
+ } regs[0] __packed;
+} __packed;
+
+#define CARL9170FW_PHY_HT_ENABLE 0x4
+#define CARL9170FW_PHY_HT_DYN2040 0x8
+#define CARL9170FW_PHY_HT_EXT_CHAN_OFF 0x3
+#define CARL9170FW_PHY_HT_EXT_CHAN_OFF_S 2
+
+struct carl9170_rf_init {
+ __le32 freq;
+ u8 ht_settings;
+ u8 padding2[3];
+ __le32 delta_slope_coeff_exp;
+ __le32 delta_slope_coeff_man;
+ __le32 delta_slope_coeff_exp_shgi;
+ __le32 delta_slope_coeff_man_shgi;
+ __le32 finiteLoopCount;
+} __packed;
+#define CARL9170_RF_INIT_SIZE 28
+
+struct carl9170_rf_init_result {
+ __le32 ret; /* AR9170_PHY_REG_AGC_CONTROL */
+} __packed;
+#define CARL9170_RF_INIT_RESULT_SIZE 4
+
+#define CARL9170_PSM_SLEEP 0x1000
+#define CARL9170_PSM_SOFTWARE 0
+#define CARL9170_PSM_WAKE 0 /* internally used. */
+#define CARL9170_PSM_COUNTER 0xfff
+#define CARL9170_PSM_COUNTER_S 0
+
+struct carl9170_psm {
+ __le32 state;
+} __packed;
+#define CARL9170_PSM_SIZE 4
+
+struct carl9170_rx_filter_cmd {
+ __le32 rx_filter;
+} __packed;
+#define CARL9170_RX_FILTER_CMD_SIZE 4
+
+#define CARL9170_RX_FILTER_BAD 0x01
+#define CARL9170_RX_FILTER_OTHER_RA 0x02
+#define CARL9170_RX_FILTER_DECRY_FAIL 0x04
+#define CARL9170_RX_FILTER_CTL_OTHER 0x08
+#define CARL9170_RX_FILTER_CTL_PSPOLL 0x10
+#define CARL9170_RX_FILTER_CTL_BACKR 0x20
+#define CARL9170_RX_FILTER_MGMT 0x40
+#define CARL9170_RX_FILTER_DATA 0x80
+
+struct carl9170_bcn_ctrl_cmd {
+ __le32 vif_id;
+ __le32 mode;
+ __le32 bcn_addr;
+ __le32 bcn_len;
+} __packed;
+#define CARL9170_BCN_CTRL_CMD_SIZE 16
+
+#define CARL9170_BCN_CTRL_DRAIN 0
+#define CARL9170_BCN_CTRL_CAB_TRIGGER 1
+
+struct carl9170_cmd_head {
+ union {
+ struct {
+ u8 len;
+ u8 cmd;
+ u8 seq;
+ u8 ext;
+ } __packed;
+
+ u32 hdr_data;
+ } __packed;
+} __packed;
+
+struct carl9170_cmd {
+ struct carl9170_cmd_head hdr;
+ union {
+ struct carl9170_set_key_cmd setkey;
+ struct carl9170_disable_key_cmd disablekey;
+ struct carl9170_u32_list echo;
+ struct carl9170_reg_list rreg;
+ struct carl9170_write_reg wreg;
+ struct carl9170_rf_init rf_init;
+ struct carl9170_psm psm;
+ struct carl9170_bcn_ctrl_cmd bcn_ctrl;
+ struct carl9170_rx_filter_cmd rx_filter;
+ u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
+ } __packed;
+} __packed;
+
+#define CARL9170_TX_STATUS_QUEUE 3
+#define CARL9170_TX_STATUS_QUEUE_S 0
+#define CARL9170_TX_STATUS_RIX_S 2
+#define CARL9170_TX_STATUS_RIX (3 << CARL9170_TX_STATUS_RIX_S)
+#define CARL9170_TX_STATUS_TRIES_S 4
+#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S)
+#define CARL9170_TX_STATUS_SUCCESS 0x80
+
+/*
+ * NOTE:
+ * Both structs [carl9170_tx_status and _carl9170_tx_status]
+ * need to be "bit for bit" in sync.
+ */
+struct carl9170_tx_status {
+ /*
+ * Beware of compiler bugs in all gcc pre 4.4!
+ */
+
+ u8 cookie;
+ u8 queue:2;
+ u8 rix:2;
+ u8 tries:3;
+ u8 success:1;
+} __packed;
+struct _carl9170_tx_status {
+ /*
+ * This version should be immune to all alignment bugs.
+ */
+
+ u8 cookie;
+ u8 info;
+} __packed;
+#define CARL9170_TX_STATUS_SIZE 2
+
+#define CARL9170_RSP_TX_STATUS_NUM (CARL9170_MAX_CMD_PAYLOAD_LEN / \
+ sizeof(struct _carl9170_tx_status))
+
+#define CARL9170_TX_MAX_RATE_TRIES 7
+
+#define CARL9170_TX_MAX_RATES 4
+#define CARL9170_TX_MAX_RETRY_RATES (CARL9170_TX_MAX_RATES - 1)
+#define CARL9170_ERR_MAGIC "ERR:"
+#define CARL9170_BUG_MAGIC "BUG:"
+
+struct carl9170_gpio {
+ __le32 gpio;
+} __packed;
+#define CARL9170_GPIO_SIZE 4
+
+struct carl9170_tsf_rsp {
+ union {
+ __le32 tsf[2];
+ __le64 tsf_64;
+ } __packed;
+} __packed;
+#define CARL9170_TSF_RSP_SIZE 8
+
+struct carl9170_rsp {
+ struct carl9170_cmd_head hdr;
+
+ union {
+ struct carl9170_rf_init_result rf_init_res;
+ struct carl9170_u32_list rreg_res;
+ struct carl9170_u32_list echo;
+ struct carl9170_tx_status tx_status[0];
+ struct _carl9170_tx_status _tx_status[0];
+ struct carl9170_gpio gpio;
+ struct carl9170_tsf_rsp tsf;
+ struct carl9170_psm psm;
+ u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
+ } __packed;
+} __packed;
+
+#endif /* __CARL9170_SHARED_FWCMD_H */
diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h
new file mode 100644
index 000000000000..71f3821f6058
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/fwdesc.h
@@ -0,0 +1,241 @@
+/*
+ * Shared CARL9170 Header
+ *
+ * Firmware descriptor format
+ *
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * 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/.
+ */
+
+#ifndef __CARL9170_SHARED_FWDESC_H
+#define __CARL9170_SHARED_FWDESC_H
+
+/* NOTE: Don't mess with the order of the flags! */
+enum carl9170fw_feature_list {
+ /* Always set */
+ CARL9170FW_DUMMY_FEATURE,
+
+ /*
+ * Indicates that this image has special boot block which prevents
+ * legacy drivers to drive the firmware.
+ */
+ CARL9170FW_MINIBOOT,
+
+ /* usb registers are initialized by the firmware */
+ CARL9170FW_USB_INIT_FIRMWARE,
+
+ /* command traps & notifications are send through EP2 */
+ CARL9170FW_USB_RESP_EP2,
+
+ /* usb download (app -> fw) stream */
+ CARL9170FW_USB_DOWN_STREAM,
+
+ /* usb upload (fw -> app) stream */
+ CARL9170FW_USB_UP_STREAM,
+
+ /* unusable - reserved to flag non-functional debug firmwares */
+ CARL9170FW_UNUSABLE,
+
+ /* AR9170_CMD_RF_INIT, AR9170_CMD_FREQ_START, AR9170_CMD_FREQUENCY */
+ CARL9170FW_COMMAND_PHY,
+
+ /* AR9170_CMD_EKEY, AR9170_CMD_DKEY */
+ CARL9170FW_COMMAND_CAM,
+
+ /* Firmware has a software Content After Beacon Queueing mechanism */
+ CARL9170FW_WLANTX_CAB,
+
+ /* The firmware is capable of responding to incoming BAR frames */
+ CARL9170FW_HANDLE_BACK_REQ,
+
+ /* GPIO Interrupt | CARL9170_RSP_GPIO */
+ CARL9170FW_GPIO_INTERRUPT,
+
+ /* Firmware PSM support | CARL9170_CMD_PSM */
+ CARL9170FW_PSM,
+
+ /* Firmware RX filter | CARL9170_CMD_RX_FILTER */
+ CARL9170FW_RX_FILTER,
+
+ /* KEEP LAST */
+ __CARL9170FW_FEATURE_NUM
+};
+
+#define OTUS_MAGIC "OTAR"
+#define MOTD_MAGIC "MOTD"
+#define FIX_MAGIC "FIX\0"
+#define DBG_MAGIC "DBG\0"
+#define CHK_MAGIC "CHK\0"
+#define LAST_MAGIC "LAST"
+
+#define CARL9170FW_SET_DAY(d) (((d) - 1) % 31)
+#define CARL9170FW_SET_MONTH(m) ((((m) - 1) % 12) * 31)
+#define CARL9170FW_SET_YEAR(y) (((y) - 10) * 372)
+
+#define CARL9170FW_GET_DAY(d) (((d) % 31) + 1)
+#define CARL9170FW_GET_MONTH(m) ((((m) / 31) % 12) + 1)
+#define CARL9170FW_GET_YEAR(y) ((y) / 372 + 10)
+
+struct carl9170fw_desc_head {
+ u8 magic[4];
+ __le16 length;
+ u8 min_ver;
+ u8 cur_ver;
+} __packed;
+#define CARL9170FW_DESC_HEAD_SIZE \
+ (sizeof(struct carl9170fw_desc_head))
+
+#define CARL9170FW_OTUS_DESC_MIN_VER 6
+#define CARL9170FW_OTUS_DESC_CUR_VER 6
+struct carl9170fw_otus_desc {
+ struct carl9170fw_desc_head head;
+ __le32 feature_set;
+ __le32 fw_address;
+ __le32 bcn_addr;
+ __le16 bcn_len;
+ __le16 miniboot_size;
+ __le16 tx_frag_len;
+ __le16 rx_max_frame_len;
+ u8 tx_descs;
+ u8 cmd_bufs;
+ u8 api_ver;
+ u8 vif_num;
+} __packed;
+#define CARL9170FW_OTUS_DESC_SIZE \
+ (sizeof(struct carl9170fw_otus_desc))
+
+#define CARL9170FW_MOTD_STRING_LEN 24
+#define CARL9170FW_MOTD_RELEASE_LEN 20
+#define CARL9170FW_MOTD_DESC_MIN_VER 1
+#define CARL9170FW_MOTD_DESC_CUR_VER 2
+struct carl9170fw_motd_desc {
+ struct carl9170fw_desc_head head;
+ __le32 fw_year_month_day;
+ char desc[CARL9170FW_MOTD_STRING_LEN];
+ char release[CARL9170FW_MOTD_RELEASE_LEN];
+} __packed;
+#define CARL9170FW_MOTD_DESC_SIZE \
+ (sizeof(struct carl9170fw_motd_desc))
+
+#define CARL9170FW_FIX_DESC_MIN_VER 1
+#define CARL9170FW_FIX_DESC_CUR_VER 2
+struct carl9170fw_fix_entry {
+ __le32 address;
+ __le32 mask;
+ __le32 value;
+} __packed;
+
+struct carl9170fw_fix_desc {
+ struct carl9170fw_desc_head head;
+ struct carl9170fw_fix_entry data[0];
+} __packed;
+#define CARL9170FW_FIX_DESC_SIZE \
+ (sizeof(struct carl9170fw_fix_desc))
+
+#define CARL9170FW_DBG_DESC_MIN_VER 1
+#define CARL9170FW_DBG_DESC_CUR_VER 3
+struct carl9170fw_dbg_desc {
+ struct carl9170fw_desc_head head;
+
+ __le32 bogoclock_addr;
+ __le32 counter_addr;
+ __le32 rx_total_addr;
+ __le32 rx_overrun_addr;
+ __le32 rx_filter;
+
+ /* Put your debugging definitions here */
+} __packed;
+#define CARL9170FW_DBG_DESC_SIZE \
+ (sizeof(struct carl9170fw_dbg_desc))
+
+#define CARL9170FW_CHK_DESC_MIN_VER 1
+#define CARL9170FW_CHK_DESC_CUR_VER 2
+struct carl9170fw_chk_desc {
+ struct carl9170fw_desc_head head;
+ __le32 fw_crc32;
+ __le32 hdr_crc32;
+} __packed;
+#define CARL9170FW_CHK_DESC_SIZE \
+ (sizeof(struct carl9170fw_chk_desc))
+
+#define CARL9170FW_LAST_DESC_MIN_VER 1
+#define CARL9170FW_LAST_DESC_CUR_VER 2
+struct carl9170fw_last_desc {
+ struct carl9170fw_desc_head head;
+} __packed;
+#define CARL9170FW_LAST_DESC_SIZE \
+ (sizeof(struct carl9170fw_fix_desc))
+
+#define CARL9170FW_DESC_MAX_LENGTH 8192
+
+#define CARL9170FW_FILL_DESC(_magic, _length, _min_ver, _cur_ver) \
+ .head = { \
+ .magic = _magic, \
+ .length = cpu_to_le16(_length), \
+ .min_ver = _min_ver, \
+ .cur_ver = _cur_ver, \
+ }
+
+static inline void carl9170fw_fill_desc(struct carl9170fw_desc_head *head,
+ u8 magic[4], __le16 length,
+ u8 min_ver, u8 cur_ver)
+{
+ head->magic[0] = magic[0];
+ head->magic[1] = magic[1];
+ head->magic[2] = magic[2];
+ head->magic[3] = magic[3];
+
+ head->length = length;
+ head->min_ver = min_ver;
+ head->cur_ver = cur_ver;
+}
+
+#define carl9170fw_for_each_hdr(desc, fw_desc) \
+ for (desc = fw_desc; \
+ memcmp(desc->magic, LAST_MAGIC, 4) && \
+ le16_to_cpu(desc->length) >= CARL9170FW_DESC_HEAD_SIZE && \
+ le16_to_cpu(desc->length) < CARL9170FW_DESC_MAX_LENGTH; \
+ desc = (void *)((unsigned long)desc + le16_to_cpu(desc->length)))
+
+#define CHECK_HDR_VERSION(head, _min_ver) \
+ (((head)->cur_ver < _min_ver) || ((head)->min_ver > _min_ver)) \
+
+static inline bool carl9170fw_supports(__le32 list, u8 feature)
+{
+ return le32_to_cpu(list) & BIT(feature);
+}
+
+static inline bool carl9170fw_desc_cmp(const struct carl9170fw_desc_head *head,
+ const u8 descid[4], u16 min_len,
+ u8 compatible_revision)
+{
+ if (descid[0] == head->magic[0] && descid[1] == head->magic[1] &&
+ descid[2] == head->magic[2] && descid[3] == head->magic[3] &&
+ !CHECK_HDR_VERSION(head, compatible_revision) &&
+ (le16_to_cpu(head->length) >= min_len))
+ return true;
+
+ return false;
+}
+
+#define CARL9170FW_MIN_SIZE 32
+#define CARL9170FW_MAX_SIZE 16384
+
+static inline bool carl9170fw_size_check(unsigned int len)
+{
+ return (len <= CARL9170FW_MAX_SIZE && len >= CARL9170FW_MIN_SIZE);
+}
+
+#endif /* __CARL9170_SHARED_FWDESC_H */
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
new file mode 100644
index 000000000000..2f471b3f05af
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -0,0 +1,739 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * Register map, hardware-specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * 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 __CARL9170_SHARED_HW_H
+#define __CARL9170_SHARED_HW_H
+
+/* High Speed UART */
+#define AR9170_UART_REG_BASE 0x1c0000
+
+/* Definitions of interrupt registers */
+#define AR9170_UART_REG_RX_BUFFER (AR9170_UART_REG_BASE + 0x000)
+#define AR9170_UART_REG_TX_HOLDING (AR9170_UART_REG_BASE + 0x004)
+#define AR9170_UART_REG_FIFO_CONTROL (AR9170_UART_REG_BASE + 0x010)
+#define AR9170_UART_FIFO_CTRL_RESET_RX_FIFO 0x02
+#define AR9170_UART_FIFO_CTRL_RESET_TX_FIFO 0x04
+
+#define AR9170_UART_REG_LINE_CONTROL (AR9170_UART_REG_BASE + 0x014)
+#define AR9170_UART_REG_MODEM_CONTROL (AR9170_UART_REG_BASE + 0x018)
+#define AR9170_UART_MODEM_CTRL_DTR_BIT 0x01
+#define AR9170_UART_MODEM_CTRL_RTS_BIT 0x02
+#define AR9170_UART_MODEM_CTRL_INTERNAL_LOOP_BACK 0x10
+#define AR9170_UART_MODEM_CTRL_AUTO_RTS 0x20
+#define AR9170_UART_MODEM_CTRL_AUTO_CTR 0x40
+
+#define AR9170_UART_REG_LINE_STATUS (AR9170_UART_REG_BASE + 0x01c)
+#define AR9170_UART_LINE_STS_RX_DATA_READY 0x01
+#define AR9170_UART_LINE_STS_RX_BUFFER_OVERRUN 0x02
+#define AR9170_UART_LINE_STS_RX_BREAK_IND 0x10
+#define AR9170_UART_LINE_STS_TX_FIFO_NEAR_EMPTY 0x20
+#define AR9170_UART_LINE_STS_TRANSMITTER_EMPTY 0x40
+
+#define AR9170_UART_REG_MODEM_STATUS (AR9170_UART_REG_BASE + 0x020)
+#define AR9170_UART_MODEM_STS_CTS_CHANGE 0x01
+#define AR9170_UART_MODEM_STS_DSR_CHANGE 0x02
+#define AR9170_UART_MODEM_STS_DCD_CHANGE 0x08
+#define AR9170_UART_MODEM_STS_CTS_COMPL 0x10
+#define AR9170_UART_MODEM_STS_DSR_COMPL 0x20
+#define AR9170_UART_MODEM_STS_DCD_COMPL 0x80
+
+#define AR9170_UART_REG_SCRATCH (AR9170_UART_REG_BASE + 0x024)
+#define AR9170_UART_REG_DIVISOR_LSB (AR9170_UART_REG_BASE + 0x028)
+#define AR9170_UART_REG_DIVISOR_MSB (AR9170_UART_REG_BASE + 0x02c)
+#define AR9170_UART_REG_WORD_RX_BUFFER (AR9170_UART_REG_BASE + 0x034)
+#define AR9170_UART_REG_WORD_TX_HOLDING (AR9170_UART_REG_BASE + 0x038)
+#define AR9170_UART_REG_FIFO_COUNT (AR9170_UART_REG_BASE + 0x03c)
+#define AR9170_UART_REG_REMAINDER (AR9170_UART_REG_BASE + 0x04c)
+
+/* Timer */
+#define AR9170_TIMER_REG_BASE 0x1c1000
+
+#define AR9170_TIMER_REG_WATCH_DOG (AR9170_TIMER_REG_BASE + 0x000)
+#define AR9170_TIMER_REG_TIMER0 (AR9170_TIMER_REG_BASE + 0x010)
+#define AR9170_TIMER_REG_TIMER1 (AR9170_TIMER_REG_BASE + 0x014)
+#define AR9170_TIMER_REG_TIMER2 (AR9170_TIMER_REG_BASE + 0x018)
+#define AR9170_TIMER_REG_TIMER3 (AR9170_TIMER_REG_BASE + 0x01c)
+#define AR9170_TIMER_REG_TIMER4 (AR9170_TIMER_REG_BASE + 0x020)
+#define AR9170_TIMER_REG_CONTROL (AR9170_TIMER_REG_BASE + 0x024)
+#define AR9170_TIMER_CTRL_DISABLE_CLOCK 0x100
+
+#define AR9170_TIMER_REG_INTERRUPT (AR9170_TIMER_REG_BASE + 0x028)
+#define AR9170_TIMER_INT_TIMER0 0x001
+#define AR9170_TIMER_INT_TIMER1 0x002
+#define AR9170_TIMER_INT_TIMER2 0x004
+#define AR9170_TIMER_INT_TIMER3 0x008
+#define AR9170_TIMER_INT_TIMER4 0x010
+#define AR9170_TIMER_INT_TICK_TIMER 0x100
+
+#define AR9170_TIMER_REG_TICK_TIMER (AR9170_TIMER_REG_BASE + 0x030)
+#define AR9170_TIMER_REG_CLOCK_LOW (AR9170_TIMER_REG_BASE + 0x040)
+#define AR9170_TIMER_REG_CLOCK_HIGH (AR9170_TIMER_REG_BASE + 0x044)
+
+#define AR9170_MAC_REG_BASE 0x1c3000
+
+#define AR9170_MAC_REG_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x500)
+#define AR9170_MAC_POWER_STATE_CTRL_RESET 0x20
+
+#define AR9170_MAC_REG_MAC_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x50c)
+
+#define AR9170_MAC_REG_INT_CTRL (AR9170_MAC_REG_BASE + 0x510)
+#define AR9170_MAC_INT_TXC BIT(0)
+#define AR9170_MAC_INT_RXC BIT(1)
+#define AR9170_MAC_INT_RETRY_FAIL BIT(2)
+#define AR9170_MAC_INT_WAKEUP BIT(3)
+#define AR9170_MAC_INT_ATIM BIT(4)
+#define AR9170_MAC_INT_DTIM BIT(5)
+#define AR9170_MAC_INT_CFG_BCN BIT(6)
+#define AR9170_MAC_INT_ABORT BIT(7)
+#define AR9170_MAC_INT_QOS BIT(8)
+#define AR9170_MAC_INT_MIMO_PS BIT(9)
+#define AR9170_MAC_INT_KEY_GEN BIT(10)
+#define AR9170_MAC_INT_DECRY_NOUSER BIT(11)
+#define AR9170_MAC_INT_RADAR BIT(12)
+#define AR9170_MAC_INT_QUIET_FRAME BIT(13)
+#define AR9170_MAC_INT_PRETBTT BIT(14)
+
+#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_ATIM_PERIOD_S 0
+#define AR9170_MAC_ATIM_PERIOD 0x0000ffff
+
+#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520)
+#define AR9170_MAC_BCN_PERIOD_S 0
+#define AR9170_MAC_BCN_PERIOD 0x0000ffff
+#define AR9170_MAC_BCN_DTIM_S 16
+#define AR9170_MAC_BCN_DTIM 0x00ff0000
+#define AR9170_MAC_BCN_AP_MODE BIT(24)
+#define AR9170_MAC_BCN_IBSS_MODE BIT(25)
+#define AR9170_MAC_BCN_PWR_MGT BIT(26)
+#define AR9170_MAC_BCN_STA_PS BIT(27)
+
+#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524)
+#define AR9170_MAC_PRETBTT_S 0
+#define AR9170_MAC_PRETBTT 0x0000ffff
+#define AR9170_MAC_PRETBTT2_S 16
+#define AR9170_MAC_PRETBTT2 0xffff0000
+
+#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_AFTER_PNP (AR9170_MAC_REG_BASE + 0x648)
+#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_SNIFFER_ENABLE_PROMISC BIT(0)
+#define AR9170_MAC_SNIFFER_DEFAULTS 0x02000000
+#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678)
+#define AR9170_MAC_ENCRYPTION_RX_SOFTWARE BIT(3)
+#define AR9170_MAC_ENCRYPTION_DEFAULTS 0x70
+
+#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680)
+#define AR9170_MAC_REG_MISC_684 (AR9170_MAC_REG_BASE + 0x684)
+#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_FTF_ASSOC_REQ BIT(0)
+#define AR9170_MAC_FTF_ASSOC_RESP BIT(1)
+#define AR9170_MAC_FTF_REASSOC_REQ BIT(2)
+#define AR9170_MAC_FTF_REASSOC_RESP BIT(3)
+#define AR9170_MAC_FTF_PRB_REQ BIT(4)
+#define AR9170_MAC_FTF_PRB_RESP BIT(5)
+#define AR9170_MAC_FTF_BIT6 BIT(6)
+#define AR9170_MAC_FTF_BIT7 BIT(7)
+#define AR9170_MAC_FTF_BEACON BIT(8)
+#define AR9170_MAC_FTF_ATIM BIT(9)
+#define AR9170_MAC_FTF_DEASSOC BIT(10)
+#define AR9170_MAC_FTF_AUTH BIT(11)
+#define AR9170_MAC_FTF_DEAUTH BIT(12)
+#define AR9170_MAC_FTF_BIT13 BIT(13)
+#define AR9170_MAC_FTF_BIT14 BIT(14)
+#define AR9170_MAC_FTF_BIT15 BIT(15)
+#define AR9170_MAC_FTF_BAR BIT(24)
+#define AR9170_MAC_FTF_BA BIT(25)
+#define AR9170_MAC_FTF_PSPOLL BIT(26)
+#define AR9170_MAC_FTF_RTS BIT(27)
+#define AR9170_MAC_FTF_CTS BIT(28)
+#define AR9170_MAC_FTF_ACK BIT(29)
+#define AR9170_MAC_FTF_CFE BIT(30)
+#define AR9170_MAC_FTF_CFE_ACK BIT(31)
+#define AR9170_MAC_FTF_DEFAULTS 0x0500ffff
+#define AR9170_MAC_FTF_MONITOR 0xff00ffff
+
+#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690)
+#define AR9170_MAC_REG_ACK_TPC (AR9170_MAC_REG_BASE + 0x694)
+#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698)
+#define AR9170_MAC_REG_RX_TIMEOUT_COUNT (AR9170_MAC_REG_BASE + 0x69c)
+#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_BLOCKACKS (AR9170_MAC_REG_BASE + 0x6c0)
+#define AR9170_MAC_REG_NAV_COUNT (AR9170_MAC_REG_BASE + 0x6c4)
+#define AR9170_MAC_REG_BACKOFF_STATUS (AR9170_MAC_REG_BASE + 0x6c8)
+#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6cc)
+
+#define AR9170_MAC_REG_TX_COMPLETE (AR9170_MAC_REG_BASE + 0x6d4)
+
+#define AR9170_MAC_REG_CHANNEL_BUSY (AR9170_MAC_REG_BASE + 0x6e8)
+#define AR9170_MAC_REG_EXT_BUSY (AR9170_MAC_REG_BASE + 0x6ec)
+
+#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6f0)
+#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6f4)
+#define AR9170_MAC_REG_ACK_FC (AR9170_MAC_REG_BASE + 0x6f8)
+
+#define AR9170_MAC_REG_CAM_MODE (AR9170_MAC_REG_BASE + 0x700)
+#define AR9170_MAC_CAM_IBSS 0xe0
+#define AR9170_MAC_CAM_AP 0xa1
+#define AR9170_MAC_CAM_STA 0x2
+#define AR9170_MAC_CAM_AP_WDS 0x3
+#define AR9170_MAC_CAM_DEFAULTS (0xf << 24)
+#define AR9170_MAC_CAM_HOST_PENDING 0x80000000
+
+#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704)
+#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708)
+
+#define AR9170_MAC_REG_CAM_ADDR (AR9170_MAC_REG_BASE + 0x70c)
+#define AR9170_MAC_CAM_ADDR_WRITE 0x80000000
+#define AR9170_MAC_REG_CAM_DATA0 (AR9170_MAC_REG_BASE + 0x720)
+#define AR9170_MAC_REG_CAM_DATA1 (AR9170_MAC_REG_BASE + 0x724)
+#define AR9170_MAC_REG_CAM_DATA2 (AR9170_MAC_REG_BASE + 0x728)
+#define AR9170_MAC_REG_CAM_DATA3 (AR9170_MAC_REG_BASE + 0x72c)
+
+#define AR9170_MAC_REG_CAM_DBG0 (AR9170_MAC_REG_BASE + 0x730)
+#define AR9170_MAC_REG_CAM_DBG1 (AR9170_MAC_REG_BASE + 0x734)
+#define AR9170_MAC_REG_CAM_DBG2 (AR9170_MAC_REG_BASE + 0x738)
+#define AR9170_MAC_REG_CAM_STATE (AR9170_MAC_REG_BASE + 0x73c)
+#define AR9170_MAC_CAM_STATE_READ_PENDING 0x40000000
+#define AR9170_MAC_CAM_STATE_WRITE_PENDING 0x80000000
+
+#define AR9170_MAC_REG_CAM_TXKEY (AR9170_MAC_REG_BASE + 0x740)
+#define AR9170_MAC_REG_CAM_RXKEY (AR9170_MAC_REG_BASE + 0x750)
+
+#define AR9170_MAC_REG_CAM_TX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x760)
+#define AR9170_MAC_REG_CAM_RX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x770)
+#define AR9170_MAC_REG_CAM_TX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x780)
+#define AR9170_MAC_REG_CAM_RX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x790)
+
+#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_AC2_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xb14)
+#define AR9170_MAC_REG_AC4_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xb18)
+#define AR9170_MAC_REG_TXOP_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0xb1c)
+#define AR9170_MAC_REG_TXOP_ACK_INTERVAL (AR9170_MAC_REG_BASE + 0xb20)
+#define AR9170_MAC_REG_CONTENTION_POINT (AR9170_MAC_REG_BASE + 0xb24)
+#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xb28)
+#define AR9170_MAC_REG_TID_CFACK_CFEND_RATE (AR9170_MAC_REG_BASE + 0xb2c)
+#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xb30)
+#define AR9170_MAC_REG_TKIP_TSC (AR9170_MAC_REG_BASE + 0xb34)
+#define AR9170_MAC_REG_TXOP_DURATION (AR9170_MAC_REG_BASE + 0xb38)
+#define AR9170_MAC_REG_TX_QOS_THRESHOLD (AR9170_MAC_REG_BASE + 0xb3c)
+#define AR9170_MAC_REG_QOS_PRIORITY_VIRTUAL_CCA (AR9170_MAC_REG_BASE + 0xb40)
+#define AR9170_MAC_VIRTUAL_CCA_Q0 BIT(15)
+#define AR9170_MAC_VIRTUAL_CCA_Q1 BIT(16)
+#define AR9170_MAC_VIRTUAL_CCA_Q2 BIT(17)
+#define AR9170_MAC_VIRTUAL_CCA_Q3 BIT(18)
+#define AR9170_MAC_VIRTUAL_CCA_Q4 BIT(19)
+#define AR9170_MAC_VIRTUAL_CCA_ALL (0xf8000)
+
+#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_COUNT (AR9170_MAC_REG_BASE + 0xb88)
+#define AR9170_MAC_REG_MPDU_COUNT (AR9170_MAC_REG_BASE + 0xb8c)
+
+#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xb9c)
+#define AR9170_MAC_AMPDU_FACTOR 0x7f0000
+#define AR9170_MAC_AMPDU_FACTOR_S 16
+#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xba0)
+#define AR9170_MAC_AMPDU_DENSITY 0x7
+#define AR9170_MAC_AMPDU_DENSITY_S 0
+
+#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_RTS_CTS_TPC (AR9170_MAC_REG_BASE + 0xbb4)
+#define AR9170_MAC_REG_CFEND_QOSNULL_TPC (AR9170_MAC_REG_BASE + 0xbb8)
+
+#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xc00)
+#define AR9170_MAC_REG_RX_CONTROL (AR9170_MAC_REG_BASE + 0xc40)
+#define AR9170_MAC_RX_CTRL_DEAGG 0x1
+#define AR9170_MAC_RX_CTRL_SHORT_FILTER 0x2
+#define AR9170_MAC_RX_CTRL_SA_DA_SEARCH 0x20
+#define AR9170_MAC_RX_CTRL_PASS_TO_HOST BIT(28)
+#define AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER BIT(30)
+
+#define AR9170_MAC_REG_RX_CONTROL_1 (AR9170_MAC_REG_BASE + 0xc44)
+
+#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xc50)
+
+#define AR9170_MAC_REG_RX_MPDU (AR9170_MAC_REG_BASE + 0xca0)
+#define AR9170_MAC_REG_RX_DROPPED_MPDU (AR9170_MAC_REG_BASE + 0xca4)
+#define AR9170_MAC_REG_RX_DEL_MPDU (AR9170_MAC_REG_BASE + 0xca8)
+#define AR9170_MAC_REG_RX_PHY_MISC_ERROR (AR9170_MAC_REG_BASE + 0xcac)
+#define AR9170_MAC_REG_RX_PHY_XR_ERROR (AR9170_MAC_REG_BASE + 0xcb0)
+#define AR9170_MAC_REG_RX_PHY_OFDM_ERROR (AR9170_MAC_REG_BASE + 0xcb4)
+#define AR9170_MAC_REG_RX_PHY_CCK_ERROR (AR9170_MAC_REG_BASE + 0xcb8)
+#define AR9170_MAC_REG_RX_PHY_HT_ERROR (AR9170_MAC_REG_BASE + 0xcbc)
+#define AR9170_MAC_REG_RX_PHY_TOTAL (AR9170_MAC_REG_BASE + 0xcc0)
+
+#define AR9170_MAC_REG_DMA_TXQ_ADDR (AR9170_MAC_REG_BASE + 0xd00)
+#define AR9170_MAC_REG_DMA_TXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04)
+#define AR9170_MAC_REG_DMA_TXQ0_ADDR (AR9170_MAC_REG_BASE + 0xd00)
+#define AR9170_MAC_REG_DMA_TXQ0_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04)
+#define AR9170_MAC_REG_DMA_TXQ1_ADDR (AR9170_MAC_REG_BASE + 0xd08)
+#define AR9170_MAC_REG_DMA_TXQ1_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd0c)
+#define AR9170_MAC_REG_DMA_TXQ2_ADDR (AR9170_MAC_REG_BASE + 0xd10)
+#define AR9170_MAC_REG_DMA_TXQ2_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd14)
+#define AR9170_MAC_REG_DMA_TXQ3_ADDR (AR9170_MAC_REG_BASE + 0xd18)
+#define AR9170_MAC_REG_DMA_TXQ3_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd1c)
+#define AR9170_MAC_REG_DMA_TXQ4_ADDR (AR9170_MAC_REG_BASE + 0xd20)
+#define AR9170_MAC_REG_DMA_TXQ4_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd24)
+#define AR9170_MAC_REG_DMA_RXQ_ADDR (AR9170_MAC_REG_BASE + 0xd28)
+#define AR9170_MAC_REG_DMA_RXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd2c)
+
+#define AR9170_MAC_REG_DMA_TRIGGER (AR9170_MAC_REG_BASE + 0xd30)
+#define AR9170_DMA_TRIGGER_TXQ0 BIT(0)
+#define AR9170_DMA_TRIGGER_TXQ1 BIT(1)
+#define AR9170_DMA_TRIGGER_TXQ2 BIT(2)
+#define AR9170_DMA_TRIGGER_TXQ3 BIT(3)
+#define AR9170_DMA_TRIGGER_TXQ4 BIT(4)
+#define AR9170_DMA_TRIGGER_RXQ BIT(8)
+
+#define AR9170_MAC_REG_DMA_WLAN_STATUS (AR9170_MAC_REG_BASE + 0xd38)
+#define AR9170_MAC_REG_DMA_STATUS (AR9170_MAC_REG_BASE + 0xd3c)
+
+#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_BCN_LENGTH_MAX 256
+
+#define AR9170_MAC_REG_BCN_STATUS (AR9170_MAC_REG_BASE + 0xd8c)
+
+#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xd90)
+#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xd94)
+#define AR9170_BCN_CTRL_READY 0x01
+#define AR9170_BCN_CTRL_LOCK 0x02
+
+#define AR9170_MAC_REG_BCN_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd98)
+#define AR9170_MAC_REG_BCN_COUNT (AR9170_MAC_REG_BASE + 0xd9c)
+
+
+#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xda0)
+#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xda4)
+
+#define AR9170_MAC_REG_DMA_TXQX_ADDR_CURR (AR9170_MAC_REG_BASE + 0xdc0)
+
+/* Random number generator */
+#define AR9170_RAND_REG_BASE 0x1d0000
+
+#define AR9170_RAND_REG_NUM (AR9170_RAND_REG_BASE + 0x000)
+#define AR9170_RAND_REG_MODE (AR9170_RAND_REG_BASE + 0x004)
+#define AR9170_RAND_MODE_MANUAL 0x000
+#define AR9170_RAND_MODE_FREE 0x001
+
+/* GPIO */
+#define AR9170_GPIO_REG_BASE 0x1d0100
+#define AR9170_GPIO_REG_PORT_TYPE (AR9170_GPIO_REG_BASE + 0x000)
+#define AR9170_GPIO_REG_PORT_DATA (AR9170_GPIO_REG_BASE + 0x004)
+#define AR9170_GPIO_PORT_LED_0 1
+#define AR9170_GPIO_PORT_LED_1 2
+/* WPS Button GPIO for TP-Link TL-WN821N */
+#define AR9170_GPIO_PORT_WPS_BUTTON_PRESSED 4
+
+/* Memory Controller */
+#define AR9170_MC_REG_BASE 0x1d1000
+
+#define AR9170_MC_REG_FLASH_WAIT_STATE (AR9170_MC_REG_BASE + 0x000)
+#define AR9170_MC_REG_SEEPROM_WP0 (AR9170_MC_REG_BASE + 0x400)
+#define AR9170_MC_REG_SEEPROM_WP1 (AR9170_MC_REG_BASE + 0x404)
+#define AR9170_MC_REG_SEEPROM_WP2 (AR9170_MC_REG_BASE + 0x408)
+
+/* Interrupt Controller */
+#define AR9170_MAX_INT_SRC 9
+#define AR9170_INT_REG_BASE 0x1d2000
+
+#define AR9170_INT_REG_FLAG (AR9170_INT_REG_BASE + 0x000)
+#define AR9170_INT_REG_FIQ_MASK (AR9170_INT_REG_BASE + 0x004)
+#define AR9170_INT_REG_IRQ_MASK (AR9170_INT_REG_BASE + 0x008)
+/* INT_REG_FLAG, INT_REG_FIQ_MASK and INT_REG_IRQ_MASK */
+#define AR9170_INT_FLAG_WLAN 0x001
+#define AR9170_INT_FLAG_PTAB_BIT 0x002
+#define AR9170_INT_FLAG_SE_BIT 0x004
+#define AR9170_INT_FLAG_UART_BIT 0x008
+#define AR9170_INT_FLAG_TIMER_BIT 0x010
+#define AR9170_INT_FLAG_EXT_BIT 0x020
+#define AR9170_INT_FLAG_SW_BIT 0x040
+#define AR9170_INT_FLAG_USB_BIT 0x080
+#define AR9170_INT_FLAG_ETHERNET_BIT 0x100
+
+#define AR9170_INT_REG_PRIORITY1 (AR9170_INT_REG_BASE + 0x00c)
+#define AR9170_INT_REG_PRIORITY2 (AR9170_INT_REG_BASE + 0x010)
+#define AR9170_INT_REG_PRIORITY3 (AR9170_INT_REG_BASE + 0x014)
+#define AR9170_INT_REG_EXT_INT_CONTROL (AR9170_INT_REG_BASE + 0x018)
+#define AR9170_INT_REG_SW_INT_CONTROL (AR9170_INT_REG_BASE + 0x01c)
+#define AR9170_INT_SW_INT_ENABLE 0x1
+
+#define AR9170_INT_REG_FIQ_ENCODE (AR9170_INT_REG_BASE + 0x020)
+#define AR9170_INT_INT_IRQ_ENCODE (AR9170_INT_REG_BASE + 0x024)
+
+/* Power Management */
+#define AR9170_PWR_REG_BASE 0x1d4000
+
+#define AR9170_PWR_REG_POWER_STATE (AR9170_PWR_REG_BASE + 0x000)
+
+#define AR9170_PWR_REG_RESET (AR9170_PWR_REG_BASE + 0x004)
+#define AR9170_PWR_RESET_COMMIT_RESET_MASK BIT(0)
+#define AR9170_PWR_RESET_WLAN_MASK BIT(1)
+#define AR9170_PWR_RESET_DMA_MASK BIT(2)
+#define AR9170_PWR_RESET_BRIDGE_MASK BIT(3)
+#define AR9170_PWR_RESET_AHB_MASK BIT(9)
+#define AR9170_PWR_RESET_BB_WARM_RESET BIT(10)
+#define AR9170_PWR_RESET_BB_COLD_RESET BIT(11)
+#define AR9170_PWR_RESET_ADDA_CLK_COLD_RESET BIT(12)
+#define AR9170_PWR_RESET_PLL BIT(13)
+#define AR9170_PWR_RESET_USB_PLL BIT(14)
+
+#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
+
+#define AR9170_PWR_REG_CHIP_REVISION (AR9170_PWR_REG_BASE + 0x010)
+#define AR9170_PWR_REG_PLL_ADDAC (AR9170_PWR_REG_BASE + 0x014)
+#define AR9170_PWR_REG_WATCH_DOG_MAGIC (AR9170_PWR_REG_BASE + 0x020)
+
+/* Faraday USB Controller */
+#define AR9170_USB_REG_BASE 0x1e1000
+
+#define AR9170_USB_REG_MAIN_CTRL (AR9170_USB_REG_BASE + 0x000)
+#define AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP BIT(0)
+#define AR9170_USB_MAIN_CTRL_ENABLE_GLOBAL_INT BIT(2)
+#define AR9170_USB_MAIN_CTRL_HIGHSPEED BIT(6)
+
+#define AR9170_USB_REG_DEVICE_ADDRESS (AR9170_USB_REG_BASE + 0x001)
+#define AR9170_USB_DEVICE_ADDRESS_CONFIGURE BIT(7)
+
+#define AR9170_USB_REG_TEST (AR9170_USB_REG_BASE + 0x002)
+#define AR9170_USB_REG_PHY_TEST_SELECT (AR9170_USB_REG_BASE + 0x008)
+#define AR9170_USB_REG_CX_CONFIG_STATUS (AR9170_USB_REG_BASE + 0x00b)
+#define AR9170_USB_REG_EP0_DATA (AR9170_USB_REG_BASE + 0x00c)
+#define AR9170_USB_REG_EP0_DATA1 (AR9170_USB_REG_BASE + 0x00c)
+#define AR9170_USB_REG_EP0_DATA2 (AR9170_USB_REG_BASE + 0x00d)
+
+#define AR9170_USB_REG_INTR_MASK_BYTE_0 (AR9170_USB_REG_BASE + 0x011)
+#define AR9170_USB_REG_INTR_MASK_BYTE_1 (AR9170_USB_REG_BASE + 0x012)
+#define AR9170_USB_REG_INTR_MASK_BYTE_2 (AR9170_USB_REG_BASE + 0x013)
+#define AR9170_USB_REG_INTR_MASK_BYTE_3 (AR9170_USB_REG_BASE + 0x014)
+#define AR9170_USB_REG_INTR_MASK_BYTE_4 (AR9170_USB_REG_BASE + 0x015)
+#define AR9170_USB_INTR_DISABLE_OUT_INT (BIT(7) | BIT(6))
+
+#define AR9170_USB_REG_INTR_MASK_BYTE_5 (AR9170_USB_REG_BASE + 0x016)
+#define AR9170_USB_REG_INTR_MASK_BYTE_6 (AR9170_USB_REG_BASE + 0x017)
+#define AR9170_USB_INTR_DISABLE_IN_INT BIT(6)
+
+#define AR9170_USB_REG_INTR_MASK_BYTE_7 (AR9170_USB_REG_BASE + 0x018)
+
+#define AR9170_USB_REG_INTR_GROUP (AR9170_USB_REG_BASE + 0x020)
+
+#define AR9170_USB_REG_INTR_SOURCE_0 (AR9170_USB_REG_BASE + 0x021)
+#define AR9170_USB_REG_INTR_SOURCE_1 (AR9170_USB_REG_BASE + 0x022)
+#define AR9170_USB_REG_INTR_SOURCE_2 (AR9170_USB_REG_BASE + 0x023)
+#define AR9170_USB_REG_INTR_SOURCE_3 (AR9170_USB_REG_BASE + 0x024)
+#define AR9170_USB_REG_INTR_SOURCE_4 (AR9170_USB_REG_BASE + 0x025)
+#define AR9170_USB_REG_INTR_SOURCE_5 (AR9170_USB_REG_BASE + 0x026)
+#define AR9170_USB_REG_INTR_SOURCE_6 (AR9170_USB_REG_BASE + 0x027)
+#define AR9170_USB_REG_INTR_SOURCE_7 (AR9170_USB_REG_BASE + 0x028)
+
+#define AR9170_USB_REG_EP_MAP (AR9170_USB_REG_BASE + 0x030)
+#define AR9170_USB_REG_EP1_MAP (AR9170_USB_REG_BASE + 0x030)
+#define AR9170_USB_REG_EP2_MAP (AR9170_USB_REG_BASE + 0x031)
+#define AR9170_USB_REG_EP3_MAP (AR9170_USB_REG_BASE + 0x032)
+#define AR9170_USB_REG_EP4_MAP (AR9170_USB_REG_BASE + 0x033)
+#define AR9170_USB_REG_EP5_MAP (AR9170_USB_REG_BASE + 0x034)
+#define AR9170_USB_REG_EP6_MAP (AR9170_USB_REG_BASE + 0x035)
+#define AR9170_USB_REG_EP7_MAP (AR9170_USB_REG_BASE + 0x036)
+#define AR9170_USB_REG_EP8_MAP (AR9170_USB_REG_BASE + 0x037)
+#define AR9170_USB_REG_EP9_MAP (AR9170_USB_REG_BASE + 0x038)
+#define AR9170_USB_REG_EP10_MAP (AR9170_USB_REG_BASE + 0x039)
+
+#define AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x03f)
+#define AR9170_USB_EP_IN_TOGGLE 0x10
+
+#define AR9170_USB_REG_EP_IN_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x03e)
+
+#define AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x05f)
+#define AR9170_USB_EP_OUT_TOGGLE 0x10
+
+#define AR9170_USB_REG_EP_OUT_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x05e)
+
+#define AR9170_USB_REG_EP3_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0ae)
+#define AR9170_USB_REG_EP3_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0be)
+#define AR9170_USB_REG_EP4_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0af)
+#define AR9170_USB_REG_EP4_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0bf)
+
+#define AR9170_USB_REG_FIFO_MAP (AR9170_USB_REG_BASE + 0x080)
+#define AR9170_USB_REG_FIFO0_MAP (AR9170_USB_REG_BASE + 0x080)
+#define AR9170_USB_REG_FIFO1_MAP (AR9170_USB_REG_BASE + 0x081)
+#define AR9170_USB_REG_FIFO2_MAP (AR9170_USB_REG_BASE + 0x082)
+#define AR9170_USB_REG_FIFO3_MAP (AR9170_USB_REG_BASE + 0x083)
+#define AR9170_USB_REG_FIFO4_MAP (AR9170_USB_REG_BASE + 0x084)
+#define AR9170_USB_REG_FIFO5_MAP (AR9170_USB_REG_BASE + 0x085)
+#define AR9170_USB_REG_FIFO6_MAP (AR9170_USB_REG_BASE + 0x086)
+#define AR9170_USB_REG_FIFO7_MAP (AR9170_USB_REG_BASE + 0x087)
+#define AR9170_USB_REG_FIFO8_MAP (AR9170_USB_REG_BASE + 0x088)
+#define AR9170_USB_REG_FIFO9_MAP (AR9170_USB_REG_BASE + 0x089)
+
+#define AR9170_USB_REG_FIFO_CONFIG (AR9170_USB_REG_BASE + 0x090)
+#define AR9170_USB_REG_FIFO0_CONFIG (AR9170_USB_REG_BASE + 0x090)
+#define AR9170_USB_REG_FIFO1_CONFIG (AR9170_USB_REG_BASE + 0x091)
+#define AR9170_USB_REG_FIFO2_CONFIG (AR9170_USB_REG_BASE + 0x092)
+#define AR9170_USB_REG_FIFO3_CONFIG (AR9170_USB_REG_BASE + 0x093)
+#define AR9170_USB_REG_FIFO4_CONFIG (AR9170_USB_REG_BASE + 0x094)
+#define AR9170_USB_REG_FIFO5_CONFIG (AR9170_USB_REG_BASE + 0x095)
+#define AR9170_USB_REG_FIFO6_CONFIG (AR9170_USB_REG_BASE + 0x096)
+#define AR9170_USB_REG_FIFO7_CONFIG (AR9170_USB_REG_BASE + 0x097)
+#define AR9170_USB_REG_FIFO8_CONFIG (AR9170_USB_REG_BASE + 0x098)
+#define AR9170_USB_REG_FIFO9_CONFIG (AR9170_USB_REG_BASE + 0x099)
+
+#define AR9170_USB_REG_EP3_DATA (AR9170_USB_REG_BASE + 0x0f8)
+#define AR9170_USB_REG_EP4_DATA (AR9170_USB_REG_BASE + 0x0fc)
+
+#define AR9170_USB_REG_FIFO_SIZE (AR9170_USB_REG_BASE + 0x100)
+#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108)
+#define AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE BIT(0)
+#define AR9170_USB_DMA_CTL_ENABLE_FROM_DEVICE BIT(1)
+#define AR9170_USB_DMA_CTL_HIGH_SPEED BIT(2)
+#define AR9170_USB_DMA_CTL_UP_PACKET_MODE BIT(3)
+#define AR9170_USB_DMA_CTL_UP_STREAM_S 4
+#define AR9170_USB_DMA_CTL_UP_STREAM (BIT(4) | BIT(5))
+#define AR9170_USB_DMA_CTL_UP_STREAM_4K (0)
+#define AR9170_USB_DMA_CTL_UP_STREAM_8K BIT(4)
+#define AR9170_USB_DMA_CTL_UP_STREAM_16K BIT(5)
+#define AR9170_USB_DMA_CTL_UP_STREAM_32K (BIT(4) | BIT(5))
+#define AR9170_USB_DMA_CTL_DOWN_STREAM BIT(6)
+
+#define AR9170_USB_REG_DMA_STATUS (AR9170_USB_REG_BASE + 0x10c)
+#define AR9170_USB_DMA_STATUS_UP_IDLE BIT(8)
+#define AR9170_USB_DMA_STATUS_DN_IDLE BIT(16)
+
+#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_USB_REG_CBUS_CTRL (AR9170_USB_REG_BASE + 0x1f0)
+#define AR9170_USB_CBUS_CTRL_BUFFER_END (BIT(1))
+
+/* PCI/USB to AHB Bridge */
+#define AR9170_PTA_REG_BASE 0x1e2000
+
+#define AR9170_PTA_REG_CMD (AR9170_PTA_REG_BASE + 0x000)
+#define AR9170_PTA_REG_PARAM1 (AR9170_PTA_REG_BASE + 0x004)
+#define AR9170_PTA_REG_PARAM2 (AR9170_PTA_REG_BASE + 0x008)
+#define AR9170_PTA_REG_PARAM3 (AR9170_PTA_REG_BASE + 0x00c)
+#define AR9170_PTA_REG_RSP (AR9170_PTA_REG_BASE + 0x010)
+#define AR9170_PTA_REG_STATUS1 (AR9170_PTA_REG_BASE + 0x014)
+#define AR9170_PTA_REG_STATUS2 (AR9170_PTA_REG_BASE + 0x018)
+#define AR9170_PTA_REG_STATUS3 (AR9170_PTA_REG_BASE + 0x01c)
+#define AR9170_PTA_REG_AHB_INT_FLAG (AR9170_PTA_REG_BASE + 0x020)
+#define AR9170_PTA_REG_AHB_INT_MASK (AR9170_PTA_REG_BASE + 0x024)
+#define AR9170_PTA_REG_AHB_INT_ACK (AR9170_PTA_REG_BASE + 0x028)
+#define AR9170_PTA_REG_AHB_SCRATCH1 (AR9170_PTA_REG_BASE + 0x030)
+#define AR9170_PTA_REG_AHB_SCRATCH2 (AR9170_PTA_REG_BASE + 0x034)
+#define AR9170_PTA_REG_AHB_SCRATCH3 (AR9170_PTA_REG_BASE + 0x038)
+#define AR9170_PTA_REG_AHB_SCRATCH4 (AR9170_PTA_REG_BASE + 0x03c)
+
+#define AR9170_PTA_REG_SHARE_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124)
+
+/*
+ * PCI to AHB Bridge
+ */
+
+#define AR9170_PTA_REG_INT_FLAG (AR9170_PTA_REG_BASE + 0x100)
+#define AR9170_PTA_INT_FLAG_DN 0x01
+#define AR9170_PTA_INT_FLAG_UP 0x02
+#define AR9170_PTA_INT_FLAG_CMD 0x04
+
+#define AR9170_PTA_REG_INT_MASK (AR9170_PTA_REG_BASE + 0x104)
+#define AR9170_PTA_REG_DN_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x108)
+#define AR9170_PTA_REG_DN_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x10c)
+#define AR9170_PTA_REG_UP_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x110)
+#define AR9170_PTA_REG_UP_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x114)
+#define AR9170_PTA_REG_DN_PEND_TIME (AR9170_PTA_REG_BASE + 0x118)
+#define AR9170_PTA_REG_UP_PEND_TIME (AR9170_PTA_REG_BASE + 0x11c)
+#define AR9170_PTA_REG_CONTROL (AR9170_PTA_REG_BASE + 0x120)
+#define AR9170_PTA_CTRL_4_BEAT_BURST 0x00
+#define AR9170_PTA_CTRL_8_BEAT_BURST 0x01
+#define AR9170_PTA_CTRL_16_BEAT_BURST 0x02
+#define AR9170_PTA_CTRL_LOOPBACK_MODE 0x10
+
+#define AR9170_PTA_REG_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124)
+#define AR9170_PTA_REG_MEM_ADDR (AR9170_PTA_REG_BASE + 0x128)
+#define AR9170_PTA_REG_DN_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x12c)
+#define AR9170_PTA_REG_UP_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x130)
+#define AR9170_PTA_REG_DMA_STATUS (AR9170_PTA_REG_BASE + 0x134)
+#define AR9170_PTA_REG_DN_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x138)
+#define AR9170_PTA_REG_DN_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x13c)
+#define AR9170_PTA_REG_UP_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x140)
+#define AR9170_PTA_REG_UP_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x144)
+#define AR9170_PTA_REG_DMA_MODE_CTRL (AR9170_PTA_REG_BASE + 0x148)
+#define AR9170_PTA_DMA_MODE_CTRL_RESET BIT(0)
+#define AR9170_PTA_DMA_MODE_CTRL_DISABLE_USB BIT(1)
+
+/* Protocol Controller Module */
+#define AR9170_MAC_REG_PC_REG_BASE (AR9170_MAC_REG_BASE + 0xe00)
+
+
+#define AR9170_NUM_LEDS 2
+
+/* CAM */
+#define AR9170_CAM_MAX_USER 64
+#define AR9170_CAM_MAX_KEY_LENGTH 16
+
+#define AR9170_SRAM_OFFSET 0x100000
+#define AR9170_SRAM_SIZE 0x18000
+
+#define AR9170_PRAM_OFFSET 0x200000
+#define AR9170_PRAM_SIZE 0x8000
+
+enum cpu_clock {
+ AHB_STATIC_40MHZ = 0,
+ AHB_GMODE_22MHZ = 1,
+ AHB_AMODE_20MHZ = 1,
+ AHB_GMODE_44MHZ = 2,
+ AHB_AMODE_40MHZ = 2,
+ AHB_GMODE_88MHZ = 3,
+ AHB_AMODE_80MHZ = 3
+};
+
+/* USB endpoints */
+enum ar9170_usb_ep {
+ /*
+ * Control EP is always EP 0 (USB SPEC)
+ *
+ * The weird thing is: the original firmware has a few
+ * comments that suggest that the actual EP numbers
+ * are in the 1 to 10 range?!
+ */
+ AR9170_USB_EP_CTRL = 0,
+
+ AR9170_USB_EP_TX,
+ AR9170_USB_EP_RX,
+ AR9170_USB_EP_IRQ,
+ AR9170_USB_EP_CMD,
+ AR9170_USB_NUM_EXTRA_EP = 4,
+
+ __AR9170_USB_NUM_EP,
+
+ __AR9170_USB_NUM_MAX_EP = 10
+};
+
+enum ar9170_usb_fifo {
+ __AR9170_USB_NUM_MAX_FIFO = 10
+};
+
+enum ar9170_tx_queues {
+ AR9170_TXQ0 = 0,
+ AR9170_TXQ1,
+ AR9170_TXQ2,
+ AR9170_TXQ3,
+ AR9170_TXQ_SPECIAL,
+
+ /* keep last */
+ __AR9170_NUM_TX_QUEUES = 5
+};
+
+#define AR9170_TX_STREAM_TAG 0x697e
+#define AR9170_RX_STREAM_TAG 0x4e00
+#define AR9170_RX_STREAM_MAX_SIZE 0xffff
+
+struct ar9170_stream {
+ __le16 length;
+ __le16 tag;
+
+ u8 payload[0];
+};
+
+#define AR9170_MAX_ACKTABLE_ENTRIES 8
+#define AR9170_MAX_VIRTUAL_MAC 7
+
+#define AR9170_USB_EP_CTRL_MAX 64
+#define AR9170_USB_EP_TX_MAX 512
+#define AR9170_USB_EP_RX_MAX 512
+#define AR9170_USB_EP_IRQ_MAX 64
+#define AR9170_USB_EP_CMD_MAX 64
+
+/* Trigger PRETBTT interrupt 6 Kus earlier */
+#define CARL9170_PRETBTT_KUS 6
+
+#define AR5416_MAX_RATE_POWER 63
+
+#define SET_VAL(reg, value, newvalue) \
+ (value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg))
+
+#define SET_CONSTVAL(reg, newvalue) \
+ (((newvalue) << reg##_S) & reg)
+
+#define MOD_VAL(reg, value, newvalue) \
+ (((value) & ~reg) | (((newvalue) << reg##_S) & reg))
+#endif /* __CARL9170_SHARED_HW_H */
diff --git a/drivers/net/wireless/ath/carl9170/led.c b/drivers/net/wireless/ath/carl9170/led.c
new file mode 100644
index 000000000000..4bb2cbd8bd9b
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/led.c
@@ -0,0 +1,190 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * LED handling
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparer <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "carl9170.h"
+#include "cmd.h"
+
+int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state)
+{
+ return carl9170_write_reg(ar, AR9170_GPIO_REG_PORT_DATA, led_state);
+}
+
+int carl9170_led_init(struct ar9170 *ar)
+{
+ int err;
+
+ /* disable LEDs */
+ /* GPIO [0/1 mode: output, 2/3: input] */
+ err = carl9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
+ if (err)
+ goto out;
+
+ /* GPIO 0/1 value: off */
+ err = carl9170_led_set_state(ar, 0);
+
+out:
+ return err;
+}
+
+#ifdef CONFIG_CARL9170_LEDS
+static void carl9170_led_update(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
+ int i, tmp = 300, blink_delay = 1000;
+ u32 led_val = 0;
+ bool rerun = false;
+
+ if (!IS_ACCEPTING_CMD(ar))
+ return;
+
+ mutex_lock(&ar->mutex);
+ for (i = 0; i < AR9170_NUM_LEDS; i++) {
+ if (ar->leds[i].registered) {
+ if (ar->leds[i].last_state ||
+ ar->leds[i].toggled) {
+
+ if (ar->leds[i].toggled)
+ tmp = 70 + 200 / (ar->leds[i].toggled);
+
+ if (tmp < blink_delay)
+ blink_delay = tmp;
+
+ led_val |= 1 << i;
+ ar->leds[i].toggled = 0;
+ rerun = true;
+ }
+ }
+ }
+
+ carl9170_led_set_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 carl9170_led_set_brightness(struct led_classdev *led,
+ enum led_brightness brightness)
+{
+ struct carl9170_led *arl = container_of(led, struct carl9170_led, l);
+ struct ar9170 *ar = arl->ar;
+
+ if (!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 carl9170_led_register_led(struct ar9170 *ar, int i, char *name,
+ char *trigger)
+{
+ int err;
+
+ snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
+ "carl9170-%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 = carl9170_led_set_brightness;
+ 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 carl9170_led_unregister(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 carl9170_led_register(struct ar9170 *ar)
+{
+ int err;
+
+ INIT_DELAYED_WORK(&ar->led_work, carl9170_led_update);
+
+ err = carl9170_led_register_led(ar, 0, "tx",
+ ieee80211_get_tx_led_name(ar->hw));
+ if (err)
+ goto fail;
+
+ if (ar->features & CARL9170_ONE_LED)
+ return 0;
+
+ err = carl9170_led_register_led(ar, 1, "assoc",
+ ieee80211_get_assoc_led_name(ar->hw));
+ if (err)
+ goto fail;
+
+ return 0;
+
+fail:
+ carl9170_led_unregister(ar);
+ return err;
+}
+
+#endif /* CONFIG_CARL9170_LEDS */
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
new file mode 100644
index 000000000000..2305bc27151c
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -0,0 +1,604 @@
+/*
+ * Atheros CARL9170 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 "carl9170.h"
+#include "cmd.h"
+
+int carl9170_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 carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
+}
+
+int carl9170_set_rts_cts_rate(struct ar9170 *ar)
+{
+ u32 rts_rate, cts_rate;
+
+ if (conf_is_ht(&ar->hw->conf)) {
+ /* 12 mbit OFDM */
+ rts_rate = 0x1da;
+ cts_rate = 0x10a;
+ } else {
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+ /* 11 mbit CCK */
+ rts_rate = 033;
+ cts_rate = 003;
+ } else {
+ /* 6 mbit OFDM */
+ rts_rate = 0x1bb;
+ cts_rate = 0x10b;
+ }
+ }
+
+ return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE,
+ rts_rate | (cts_rate) << 16);
+}
+
+int carl9170_set_slot_time(struct ar9170 *ar)
+{
+ struct ieee80211_vif *vif;
+ u32 slottime = 20;
+
+ rcu_read_lock();
+ vif = carl9170_get_main_vif(ar);
+ if (!vif) {
+ rcu_read_unlock();
+ return 0;
+ }
+
+ if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
+ vif->bss_conf.use_short_slot)
+ slottime = 9;
+
+ rcu_read_unlock();
+
+ return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
+ slottime << 10);
+}
+
+int carl9170_set_mac_rates(struct ar9170 *ar)
+{
+ struct ieee80211_vif *vif;
+ u32 basic, mandatory;
+
+ rcu_read_lock();
+ vif = carl9170_get_main_vif(ar);
+
+ if (!vif) {
+ rcu_read_unlock();
+ return 0;
+ }
+
+ basic = (vif->bss_conf.basic_rates & 0xf);
+ basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
+ rcu_read_unlock();
+
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+ mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */
+ else
+ mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */
+
+ carl9170_regwrite_begin(ar);
+ carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic);
+ carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory);
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+int carl9170_set_qos(struct ar9170 *ar)
+{
+ carl9170_regwrite_begin(ar);
+
+ carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
+ (ar->edcf[0].cw_max << 16));
+ carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
+ (ar->edcf[1].cw_max << 16));
+ carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
+ (ar->edcf[2].cw_max << 16));
+ carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
+ (ar->edcf[3].cw_max << 16));
+ carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
+ (ar->edcf[4].cw_max << 16));
+
+ carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS,
+ ((ar->edcf[0].aifs * 9 + 10)) |
+ ((ar->edcf[1].aifs * 9 + 10) << 12) |
+ ((ar->edcf[2].aifs * 9 + 10) << 24));
+ carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS,
+ ((ar->edcf[2].aifs * 9 + 10) >> 8) |
+ ((ar->edcf[3].aifs * 9 + 10) << 4) |
+ ((ar->edcf[4].aifs * 9 + 10) << 16));
+
+ carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
+ ar->edcf[0].txop | ar->edcf[1].txop << 16);
+ carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
+ ar->edcf[2].txop | ar->edcf[3].txop << 16 |
+ ar->edcf[4].txop << 24);
+
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+int carl9170_init_mac(struct ar9170 *ar)
+{
+ carl9170_regwrite_begin(ar);
+
+ /* switch MAC to OTUS interface */
+ carl9170_regwrite(0x1c3600, 0x3);
+
+ carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
+
+ carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0);
+
+ carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
+ AR9170_MAC_FTF_MONITOR);
+
+ /* enable MMIC */
+ carl9170_regwrite(AR9170_MAC_REG_SNIFFER,
+ AR9170_MAC_SNIFFER_DEFAULTS);
+
+ carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
+
+ carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
+ carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
+ carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
+
+ /* CF-END & CF-ACK rate => 24M OFDM */
+ carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000);
+
+ /* NAV protects ACK only (in TXOP) */
+ carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201);
+
+ /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
+ /* OTUS set AM to 0x1 */
+ carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
+
+ carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
+
+ /* Aggregation MAX number and timeout */
+ carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa);
+ carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00);
+
+ carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
+ AR9170_MAC_FTF_DEFAULTS);
+
+ carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL,
+ AR9170_MAC_RX_CTRL_DEAGG |
+ AR9170_MAC_RX_CTRL_SHORT_FILTER);
+
+ /* rate sets */
+ carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
+ carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
+ carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033);
+
+ /* MIMO response control */
+ carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e);
+
+ carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
+
+ /* set PHY register read timeout (??) */
+ carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
+
+ /* Disable Rx TimeOut, workaround for BB. */
+ carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
+
+ /* Set WLAN DMA interrupt mode: generate int per packet */
+ carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
+
+ carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
+ AR9170_MAC_FCS_FIFO_PROT);
+
+ /* Disables the CF_END frame, undocumented register */
+ carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
+ 0x141e0f48);
+
+ /* reset group hash table */
+ carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff);
+ carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff);
+
+ /* disable PRETBTT interrupt */
+ carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0);
+ carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0);
+
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+static int carl9170_set_mac_reg(struct ar9170 *ar,
+ const u32 reg, const u8 *mac)
+{
+ static const u8 zero[ETH_ALEN] = { 0 };
+
+ if (!mac)
+ mac = zero;
+
+ carl9170_regwrite_begin(ar);
+
+ carl9170_regwrite(reg, get_unaligned_le32(mac));
+ carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
+
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id,
+ const u8 *mac)
+{
+ if (WARN_ON(id >= ar->fw.vif_num))
+ return -EINVAL;
+
+ return carl9170_set_mac_reg(ar,
+ AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac);
+}
+
+int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
+{
+ int err;
+
+ carl9170_regwrite_begin(ar);
+ carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
+ carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
+ carl9170_regwrite_finish();
+ err = carl9170_regwrite_result();
+ if (err)
+ return err;
+
+ ar->cur_mc_hash = mc_hash;
+ return 0;
+}
+
+int carl9170_set_operating_mode(struct ar9170 *ar)
+{
+ struct ieee80211_vif *vif;
+ struct ath_common *common = &ar->common;
+ u8 *mac_addr, *bssid;
+ u32 cam_mode = AR9170_MAC_CAM_DEFAULTS;
+ u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS;
+ u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG |
+ AR9170_MAC_RX_CTRL_SHORT_FILTER;
+ u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS;
+ int err = 0;
+
+ rcu_read_lock();
+ vif = carl9170_get_main_vif(ar);
+
+ if (vif) {
+ mac_addr = common->macaddr;
+ bssid = common->curbssid;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_ADHOC:
+ cam_mode |= AR9170_MAC_CAM_IBSS;
+ break;
+ case NL80211_IFTYPE_AP:
+ cam_mode |= AR9170_MAC_CAM_AP;
+
+ /* iwlagn 802.11n STA Workaround */
+ rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
+ break;
+ case NL80211_IFTYPE_WDS:
+ cam_mode |= AR9170_MAC_CAM_AP_WDS;
+ rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
+ break;
+ case NL80211_IFTYPE_STATION:
+ cam_mode |= AR9170_MAC_CAM_STA;
+ rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
+ break;
+ default:
+ WARN(1, "Unsupported operation mode %x\n", vif->type);
+ err = -EOPNOTSUPP;
+ break;
+ }
+ } else {
+ mac_addr = NULL;
+ bssid = NULL;
+ }
+ rcu_read_unlock();
+
+ if (err)
+ return err;
+
+ if (ar->rx_software_decryption)
+ enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
+
+ if (ar->sniffer_enabled) {
+ rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER;
+ sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC;
+ enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
+ }
+
+ err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
+ if (err)
+ return err;
+
+ err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
+ if (err)
+ return err;
+
+ carl9170_regwrite_begin(ar);
+ carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
+ carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode);
+ carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode);
+ carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl);
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry)
+{
+ u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
+
+ return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
+}
+
+int carl9170_set_beacon_timers(struct ar9170 *ar)
+{
+ struct ieee80211_vif *vif;
+ u32 v = 0;
+ u32 pretbtt = 0;
+
+ rcu_read_lock();
+ vif = carl9170_get_main_vif(ar);
+
+ if (vif) {
+ struct carl9170_vif_info *mvif;
+ mvif = (void *) vif->drv_priv;
+
+ if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) {
+ ar->global_beacon_int = vif->bss_conf.beacon_int /
+ ar->beacon_enabled;
+
+ SET_VAL(AR9170_MAC_BCN_DTIM, v,
+ vif->bss_conf.dtim_period);
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_ADHOC:
+ v |= AR9170_MAC_BCN_IBSS_MODE;
+ break;
+ case NL80211_IFTYPE_AP:
+ v |= AR9170_MAC_BCN_AP_MODE;
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ break;
+ }
+ } else if (vif->type == NL80211_IFTYPE_STATION) {
+ ar->global_beacon_int = vif->bss_conf.beacon_int;
+
+ SET_VAL(AR9170_MAC_BCN_DTIM, v,
+ ar->hw->conf.ps_dtim_period);
+
+ v |= AR9170_MAC_BCN_STA_PS |
+ AR9170_MAC_BCN_PWR_MGT;
+ }
+
+ if (ar->global_beacon_int) {
+ if (ar->global_beacon_int < 15) {
+ rcu_read_unlock();
+ return -ERANGE;
+ }
+
+ ar->global_pretbtt = ar->global_beacon_int -
+ CARL9170_PRETBTT_KUS;
+ } else {
+ ar->global_pretbtt = 0;
+ }
+ } else {
+ ar->global_beacon_int = 0;
+ ar->global_pretbtt = 0;
+ }
+
+ rcu_read_unlock();
+
+ SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int);
+ SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt);
+ SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt);
+
+ carl9170_regwrite_begin(ar);
+ carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
+ carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
+ carl9170_regwrite_finish();
+ return carl9170_regwrite_result();
+}
+
+int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
+{
+ struct sk_buff *skb;
+ struct carl9170_vif_info *cvif;
+ __le32 *data, *old = NULL;
+ u32 word, off, addr, len;
+ int i = 0, err = 0;
+
+ rcu_read_lock();
+ cvif = rcu_dereference(ar->beacon_iter);
+retry:
+ if (ar->vifs == 0 || !cvif)
+ goto out_unlock;
+
+ list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
+ if (cvif->active && cvif->enable_beacon)
+ goto found;
+ }
+
+ if (!ar->beacon_enabled || i++)
+ goto out_unlock;
+
+ goto retry;
+
+found:
+ rcu_assign_pointer(ar->beacon_iter, cvif);
+
+ skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
+ NULL, NULL);
+
+ if (!skb) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ spin_lock_bh(&ar->beacon_lock);
+ data = (__le32 *)skb->data;
+ if (cvif->beacon)
+ old = (__le32 *)cvif->beacon->data;
+
+ off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX;
+ addr = ar->fw.beacon_addr + off;
+ len = roundup(skb->len + FCS_LEN, 4);
+
+ if ((off + len) > ar->fw.beacon_max_len) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "beacon does not "
+ "fit into device memory!\n");
+ }
+
+ spin_unlock_bh(&ar->beacon_lock);
+ dev_kfree_skb_any(skb);
+ err = -EINVAL;
+ goto out_unlock;
+ }
+
+ if (len > AR9170_MAC_BCN_LENGTH_MAX) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "no support for beacons "
+ "bigger than %d (yours:%d).\n",
+ AR9170_MAC_BCN_LENGTH_MAX, len);
+ }
+
+ spin_unlock_bh(&ar->beacon_lock);
+ dev_kfree_skb_any(skb);
+ err = -EMSGSIZE;
+ goto out_unlock;
+ }
+
+ carl9170_async_regwrite_begin(ar);
+
+ /* XXX: use skb->cb info */
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+ carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
+ ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400);
+ } else {
+ carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
+ ((skb->len + FCS_LEN) << 16) + 0x001b);
+ }
+
+ 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]);
+ carl9170_async_regwrite(addr + 4 * i, word);
+ }
+ carl9170_async_regwrite_finish();
+
+ dev_kfree_skb_any(cvif->beacon);
+ cvif->beacon = NULL;
+
+ err = carl9170_async_regwrite_result();
+ if (!err)
+ cvif->beacon = skb;
+ spin_unlock_bh(&ar->beacon_lock);
+ if (err)
+ goto out_unlock;
+
+ if (submit) {
+ err = carl9170_bcn_ctrl(ar, cvif->id,
+ CARL9170_BCN_CTRL_CAB_TRIGGER,
+ addr, skb->len + FCS_LEN);
+
+ if (err)
+ goto out_unlock;
+ }
+out_unlock:
+ rcu_read_unlock();
+ return err;
+}
+
+int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
+ const u8 ktype, const u8 keyidx, const u8 *keydata,
+ const int keylen)
+{
+ struct carl9170_set_key_cmd key = { };
+ static const u8 bcast[ETH_ALEN] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ mac = mac ? : bcast;
+
+ key.user = cpu_to_le16(id);
+ key.keyId = cpu_to_le16(keyidx);
+ key.type = cpu_to_le16(ktype);
+ memcpy(&key.macAddr, mac, ETH_ALEN);
+ if (keydata)
+ memcpy(&key.key, keydata, keylen);
+
+ return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY,
+ sizeof(key), (u8 *)&key, 0, NULL);
+}
+
+int carl9170_disable_key(struct ar9170 *ar, const u8 id)
+{
+ struct carl9170_disable_key_cmd key = { };
+
+ key.user = cpu_to_le16(id);
+
+ return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY,
+ sizeof(key), (u8 *)&key, 0, NULL);
+}
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
new file mode 100644
index 000000000000..3cc99f3f7ab5
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -0,0 +1,1891 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * mac80211 interaction code
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/random.h>
+#include <net/mac80211.h>
+#include <net/cfg80211.h>
+#include "hw.h"
+#include "carl9170.h"
+#include "cmd.h"
+
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload.");
+
+int modparam_noht;
+module_param_named(noht, modparam_noht, int, S_IRUGO);
+MODULE_PARM_DESC(noht, "Disable MPDU aggregation.");
+
+#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
+ .bitrate = (_bitrate), \
+ .flags = (_flags), \
+ .hw_value = (_hw_rate) | (_txpidx) << 4, \
+}
+
+struct ieee80211_rate __carl9170_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 carl9170_g_ratetable (__carl9170_ratetable + 0)
+#define carl9170_g_ratetable_size 12
+#define carl9170_a_ratetable (__carl9170_ratetable + 4)
+#define carl9170_a_ratetable_size 8
+
+/*
+ * NB: The hw_value is used as an index into the carl9170_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 carl9170_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 carl9170_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 CARL9170_HT_CAP \
+{ \
+ .ht_supported = true, \
+ .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
+ IEEE80211_HT_CAP_SGI_40 | \
+ IEEE80211_HT_CAP_DSSSCCK40 | \
+ IEEE80211_HT_CAP_SM_PS, \
+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \
+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
+ .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 carl9170_band_2GHz = {
+ .channels = carl9170_2ghz_chantable,
+ .n_channels = ARRAY_SIZE(carl9170_2ghz_chantable),
+ .bitrates = carl9170_g_ratetable,
+ .n_bitrates = carl9170_g_ratetable_size,
+ .ht_cap = CARL9170_HT_CAP,
+};
+
+static struct ieee80211_supported_band carl9170_band_5GHz = {
+ .channels = carl9170_5ghz_chantable,
+ .n_channels = ARRAY_SIZE(carl9170_5ghz_chantable),
+ .bitrates = carl9170_a_ratetable,
+ .n_bitrates = carl9170_a_ratetable_size,
+ .ht_cap = CARL9170_HT_CAP,
+};
+
+static void carl9170_ampdu_gc(struct ar9170 *ar)
+{
+ struct carl9170_sta_tid *tid_info;
+ LIST_HEAD(tid_gc);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(tid_info, &ar->tx_ampdu_list, list) {
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ if (tid_info->state == CARL9170_TID_STATE_SHUTDOWN) {
+ tid_info->state = CARL9170_TID_STATE_KILLED;
+ list_del_rcu(&tid_info->list);
+ ar->tx_ampdu_list_len--;
+ list_add_tail(&tid_info->tmp_list, &tid_gc);
+ }
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+
+ }
+ rcu_assign_pointer(ar->tx_ampdu_iter, tid_info);
+ rcu_read_unlock();
+
+ synchronize_rcu();
+
+ while (!list_empty(&tid_gc)) {
+ struct sk_buff *skb;
+ tid_info = list_first_entry(&tid_gc, struct carl9170_sta_tid,
+ tmp_list);
+
+ while ((skb = __skb_dequeue(&tid_info->queue)))
+ carl9170_tx_status(ar, skb, false);
+
+ list_del_init(&tid_info->tmp_list);
+ kfree(tid_info);
+ }
+}
+
+static void carl9170_flush(struct ar9170 *ar, bool drop_queued)
+{
+ if (drop_queued) {
+ int i;
+
+ /*
+ * We can only drop frames which have not been uploaded
+ * to the device yet.
+ */
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(&ar->tx_pending[i]))) {
+ struct ieee80211_tx_info *info;
+
+ info = IEEE80211_SKB_CB(skb);
+ if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ atomic_dec(&ar->tx_ampdu_upload);
+
+ carl9170_tx_status(ar, skb, false);
+ }
+ }
+ }
+
+ /* Wait for all other outstanding frames to timeout. */
+ if (atomic_read(&ar->tx_total_queued))
+ WARN_ON(wait_for_completion_timeout(&ar->tx_flush, HZ) == 0);
+}
+
+static void carl9170_flush_ba(struct ar9170 *ar)
+{
+ struct sk_buff_head free;
+ struct carl9170_sta_tid *tid_info;
+ struct sk_buff *skb;
+
+ __skb_queue_head_init(&free);
+
+ rcu_read_lock();
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ list_for_each_entry_rcu(tid_info, &ar->tx_ampdu_list, list) {
+ if (tid_info->state > CARL9170_TID_STATE_SUSPEND) {
+ tid_info->state = CARL9170_TID_STATE_SUSPEND;
+
+ spin_lock(&tid_info->lock);
+ while ((skb = __skb_dequeue(&tid_info->queue)))
+ __skb_queue_tail(&free, skb);
+ spin_unlock(&tid_info->lock);
+ }
+ }
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+ rcu_read_unlock();
+
+ while ((skb = __skb_dequeue(&free)))
+ carl9170_tx_status(ar, skb, false);
+}
+
+static void carl9170_zap_queues(struct ar9170 *ar)
+{
+ struct carl9170_vif_info *cvif;
+ unsigned int i;
+
+ carl9170_ampdu_gc(ar);
+
+ carl9170_flush_ba(ar);
+ carl9170_flush(ar, true);
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ spin_lock_bh(&ar->tx_status[i].lock);
+ while (!skb_queue_empty(&ar->tx_status[i])) {
+ struct sk_buff *skb;
+
+ skb = skb_peek(&ar->tx_status[i]);
+ carl9170_tx_get_skb(skb);
+ spin_unlock_bh(&ar->tx_status[i].lock);
+ carl9170_tx_drop(ar, skb);
+ spin_lock_bh(&ar->tx_status[i].lock);
+ carl9170_tx_put_skb(skb);
+ }
+ spin_unlock_bh(&ar->tx_status[i].lock);
+ }
+
+ BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_SOFT < 1);
+ BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_HARD < CARL9170_NUM_TX_LIMIT_SOFT);
+ BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_HARD >= CARL9170_BAW_BITS);
+
+ /* reinitialize queues statistics */
+ memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
+ for (i = 0; i < ar->hw->queues; i++)
+ ar->tx_stats[i].limit = CARL9170_NUM_TX_LIMIT_HARD;
+
+ for (i = 0; i < DIV_ROUND_UP(ar->fw.mem_blocks, BITS_PER_LONG); i++)
+ ar->mem_bitmap[i] = 0;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(cvif, &ar->vif_list, list) {
+ spin_lock_bh(&ar->beacon_lock);
+ dev_kfree_skb_any(cvif->beacon);
+ cvif->beacon = NULL;
+ spin_unlock_bh(&ar->beacon_lock);
+ }
+ rcu_read_unlock();
+
+ atomic_set(&ar->tx_ampdu_upload, 0);
+ atomic_set(&ar->tx_ampdu_scheduler, 0);
+ atomic_set(&ar->tx_total_pending, 0);
+ atomic_set(&ar->tx_total_queued, 0);
+ atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks);
+}
+
+#define CARL9170_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 carl9170_op_start(struct ieee80211_hw *hw)
+{
+ struct ar9170 *ar = hw->priv;
+ int err, i;
+
+ mutex_lock(&ar->mutex);
+
+ carl9170_zap_queues(ar);
+
+ /* reset QoS defaults */
+ CARL9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT */
+ CARL9170_FILL_QUEUE(ar->edcf[1], 2, 7, 15, 94); /* VIDEO */
+ CARL9170_FILL_QUEUE(ar->edcf[2], 2, 3, 7, 47); /* VOICE */
+ CARL9170_FILL_QUEUE(ar->edcf[3], 7, 15, 1023, 0); /* BACKGROUND */
+ CARL9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
+
+ ar->current_factor = ar->current_density = -1;
+ /* "The first key is unique." */
+ ar->usedkeys = 1;
+ ar->filter_state = 0;
+ ar->ps.last_action = jiffies;
+ ar->ps.last_slept = jiffies;
+ ar->erp_mode = CARL9170_ERP_AUTO;
+ ar->rx_software_decryption = false;
+ ar->disable_offload = false;
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ ar->queue_stop_timeout[i] = jiffies;
+ ar->max_queue_stop_timeout[i] = 0;
+ }
+
+ atomic_set(&ar->mem_allocs, 0);
+
+ err = carl9170_usb_open(ar);
+ if (err)
+ goto out;
+
+ err = carl9170_init_mac(ar);
+ if (err)
+ goto out;
+
+ err = carl9170_set_qos(ar);
+ if (err)
+ goto out;
+
+ if (ar->fw.rx_filter) {
+ err = carl9170_rx_filter(ar, CARL9170_RX_FILTER_OTHER_RA |
+ CARL9170_RX_FILTER_CTL_OTHER | CARL9170_RX_FILTER_BAD);
+ if (err)
+ goto out;
+ }
+
+ err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER,
+ AR9170_DMA_TRIGGER_RXQ);
+ if (err)
+ goto out;
+
+ /* Clear key-cache */
+ for (i = 0; i < AR9170_CAM_MAX_USER + 4; i++) {
+ err = carl9170_upload_key(ar, i, NULL, AR9170_ENC_ALG_NONE,
+ 0, NULL, 0);
+ if (err)
+ goto out;
+
+ err = carl9170_upload_key(ar, i, NULL, AR9170_ENC_ALG_NONE,
+ 1, NULL, 0);
+ if (err)
+ goto out;
+
+ if (i < AR9170_CAM_MAX_USER) {
+ err = carl9170_disable_key(ar, i);
+ if (err)
+ goto out;
+ }
+ }
+
+ carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STARTED);
+
+ ieee80211_wake_queues(ar->hw);
+ err = 0;
+
+out:
+ mutex_unlock(&ar->mutex);
+ return err;
+}
+
+static void carl9170_cancel_worker(struct ar9170 *ar)
+{
+ cancel_delayed_work_sync(&ar->tx_janitor);
+#ifdef CONFIG_CARL9170_LEDS
+ cancel_delayed_work_sync(&ar->led_work);
+#endif /* CONFIG_CARL9170_LEDS */
+ cancel_work_sync(&ar->ps_work);
+ cancel_work_sync(&ar->ampdu_work);
+}
+
+static void carl9170_op_stop(struct ieee80211_hw *hw)
+{
+ struct ar9170 *ar = hw->priv;
+
+ carl9170_set_state_when(ar, CARL9170_STARTED, CARL9170_IDLE);
+
+ ieee80211_stop_queues(ar->hw);
+
+ mutex_lock(&ar->mutex);
+ if (IS_ACCEPTING_CMD(ar)) {
+ rcu_assign_pointer(ar->beacon_iter, NULL);
+
+ carl9170_led_set_state(ar, 0);
+
+ /* stop DMA */
+ carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, 0);
+ carl9170_usb_stop(ar);
+ }
+
+ carl9170_zap_queues(ar);
+ mutex_unlock(&ar->mutex);
+
+ carl9170_cancel_worker(ar);
+}
+
+static void carl9170_restart_work(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ restart_work);
+ int err;
+
+ ar->usedkeys = 0;
+ ar->filter_state = 0;
+ carl9170_cancel_worker(ar);
+
+ mutex_lock(&ar->mutex);
+ err = carl9170_usb_restart(ar);
+ if (net_ratelimit()) {
+ if (err) {
+ dev_err(&ar->udev->dev, "Failed to restart device "
+ " (%d).\n", err);
+ } else {
+ dev_info(&ar->udev->dev, "device restarted "
+ "successfully.\n");
+ }
+ }
+
+ carl9170_zap_queues(ar);
+ mutex_unlock(&ar->mutex);
+ if (!err) {
+ ar->restart_counter++;
+ atomic_set(&ar->pending_restarts, 0);
+
+ ieee80211_restart_hw(ar->hw);
+ } else {
+ /*
+ * The reset was unsuccessful and the device seems to
+ * be dead. But there's still one option: a low-level
+ * usb subsystem reset...
+ */
+
+ carl9170_usb_reset(ar);
+ }
+}
+
+void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
+{
+ carl9170_set_state_when(ar, CARL9170_STARTED, CARL9170_IDLE);
+
+ /*
+ * Sometimes, an error can trigger several different reset events.
+ * By ignoring these *surplus* reset events, the device won't be
+ * killed again, right after it has recovered.
+ */
+ if (atomic_inc_return(&ar->pending_restarts) > 1) {
+ dev_dbg(&ar->udev->dev, "ignoring restart (%d)\n", r);
+ return;
+ }
+
+ ieee80211_stop_queues(ar->hw);
+
+ dev_err(&ar->udev->dev, "restart device (%d)\n", r);
+
+ if (!WARN_ON(r == CARL9170_RR_NO_REASON) ||
+ !WARN_ON(r >= __CARL9170_RR_LAST))
+ ar->last_reason = r;
+
+ if (!ar->registered)
+ return;
+
+ if (IS_ACCEPTING_CMD(ar) && !ar->needs_full_reset)
+ ieee80211_queue_work(ar->hw, &ar->restart_work);
+ else
+ carl9170_usb_reset(ar);
+
+ /*
+ * At this point, the device instance might have vanished/disabled.
+ * So, don't put any code which access the ar9170 struct
+ * without proper protection.
+ */
+}
+
+static int carl9170_init_interface(struct ar9170 *ar,
+ struct ieee80211_vif *vif)
+{
+ struct ath_common *common = &ar->common;
+ int err;
+
+ if (!vif) {
+ WARN_ON_ONCE(IS_STARTED(ar));
+ return 0;
+ }
+
+ memcpy(common->macaddr, vif->addr, ETH_ALEN);
+
+ if (modparam_nohwcrypt ||
+ ((vif->type != NL80211_IFTYPE_STATION) &&
+ (vif->type != NL80211_IFTYPE_AP))) {
+ ar->rx_software_decryption = true;
+ ar->disable_offload = true;
+ }
+
+ err = carl9170_set_operating_mode(ar);
+ return err;
+}
+
+static int carl9170_op_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv;
+ struct ieee80211_vif *main_vif;
+ struct ar9170 *ar = hw->priv;
+ int vif_id = -1, err = 0;
+
+ mutex_lock(&ar->mutex);
+ rcu_read_lock();
+ if (vif_priv->active) {
+ /*
+ * Skip the interface structure initialization,
+ * if the vif survived the _restart call.
+ */
+ vif_id = vif_priv->id;
+ vif_priv->enable_beacon = false;
+
+ spin_lock_bh(&ar->beacon_lock);
+ dev_kfree_skb_any(vif_priv->beacon);
+ vif_priv->beacon = NULL;
+ spin_unlock_bh(&ar->beacon_lock);
+
+ goto init;
+ }
+
+ main_vif = carl9170_get_main_vif(ar);
+
+ if (main_vif) {
+ switch (main_vif->type) {
+ case NL80211_IFTYPE_STATION:
+ if (vif->type == NL80211_IFTYPE_STATION)
+ break;
+
+ err = -EBUSY;
+ rcu_read_unlock();
+
+ goto unlock;
+
+ case NL80211_IFTYPE_AP:
+ if ((vif->type == NL80211_IFTYPE_STATION) ||
+ (vif->type == NL80211_IFTYPE_WDS) ||
+ (vif->type == NL80211_IFTYPE_AP))
+ break;
+
+ err = -EBUSY;
+ rcu_read_unlock();
+ goto unlock;
+
+ default:
+ rcu_read_unlock();
+ goto unlock;
+ }
+ }
+
+ vif_id = bitmap_find_free_region(&ar->vif_bitmap, ar->fw.vif_num, 0);
+
+ if (vif_id < 0) {
+ rcu_read_unlock();
+
+ err = -ENOSPC;
+ goto unlock;
+ }
+
+ BUG_ON(ar->vif_priv[vif_id].id != vif_id);
+
+ vif_priv->active = true;
+ vif_priv->id = vif_id;
+ vif_priv->enable_beacon = false;
+ ar->vifs++;
+ list_add_tail_rcu(&vif_priv->list, &ar->vif_list);
+ rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif);
+
+init:
+ if (carl9170_get_main_vif(ar) == vif) {
+ rcu_assign_pointer(ar->beacon_iter, vif_priv);
+ rcu_read_unlock();
+
+ err = carl9170_init_interface(ar, vif);
+ if (err)
+ goto unlock;
+ } else {
+ err = carl9170_mod_virtual_mac(ar, vif_id, vif->addr);
+ rcu_read_unlock();
+
+ if (err)
+ goto unlock;
+ }
+
+unlock:
+ if (err && (vif_id != -1)) {
+ vif_priv->active = false;
+ bitmap_release_region(&ar->vif_bitmap, vif_id, 0);
+ ar->vifs--;
+ rcu_assign_pointer(ar->vif_priv[vif_id].vif, NULL);
+ list_del_rcu(&vif_priv->list);
+ mutex_unlock(&ar->mutex);
+ synchronize_rcu();
+ } else {
+ if (ar->vifs > 1)
+ ar->ps.off_override |= PS_OFF_VIF;
+
+ mutex_unlock(&ar->mutex);
+ }
+
+ return err;
+}
+
+static void carl9170_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv;
+ struct ieee80211_vif *main_vif;
+ struct ar9170 *ar = hw->priv;
+ unsigned int id;
+
+ mutex_lock(&ar->mutex);
+
+ if (WARN_ON_ONCE(!vif_priv->active))
+ goto unlock;
+
+ ar->vifs--;
+
+ rcu_read_lock();
+ main_vif = carl9170_get_main_vif(ar);
+
+ id = vif_priv->id;
+
+ vif_priv->active = false;
+ WARN_ON(vif_priv->enable_beacon);
+ vif_priv->enable_beacon = false;
+ list_del_rcu(&vif_priv->list);
+ rcu_assign_pointer(ar->vif_priv[id].vif, NULL);
+
+ if (vif == main_vif) {
+ rcu_read_unlock();
+
+ if (ar->vifs) {
+ WARN_ON(carl9170_init_interface(ar,
+ carl9170_get_main_vif(ar)));
+ } else {
+ carl9170_set_operating_mode(ar);
+ }
+ } else {
+ rcu_read_unlock();
+
+ WARN_ON(carl9170_mod_virtual_mac(ar, id, NULL));
+ }
+
+ carl9170_update_beacon(ar, false);
+ carl9170_flush_cab(ar, id);
+
+ spin_lock_bh(&ar->beacon_lock);
+ dev_kfree_skb_any(vif_priv->beacon);
+ vif_priv->beacon = NULL;
+ spin_unlock_bh(&ar->beacon_lock);
+
+ bitmap_release_region(&ar->vif_bitmap, id, 0);
+
+ carl9170_set_beacon_timers(ar);
+
+ if (ar->vifs == 1)
+ ar->ps.off_override &= ~PS_OFF_VIF;
+
+unlock:
+ mutex_unlock(&ar->mutex);
+
+ synchronize_rcu();
+}
+
+void carl9170_ps_check(struct ar9170 *ar)
+{
+ ieee80211_queue_work(ar->hw, &ar->ps_work);
+}
+
+/* caller must hold ar->mutex */
+static int carl9170_ps_update(struct ar9170 *ar)
+{
+ bool ps = false;
+ int err = 0;
+
+ if (!ar->ps.off_override)
+ ps = (ar->hw->conf.flags & IEEE80211_CONF_PS);
+
+ if (ps != ar->ps.state) {
+ err = carl9170_powersave(ar, ps);
+ if (err)
+ return err;
+
+ if (ar->ps.state && !ps) {
+ ar->ps.sleep_ms = jiffies_to_msecs(jiffies -
+ ar->ps.last_action);
+ }
+
+ if (ps)
+ ar->ps.last_slept = jiffies;
+
+ ar->ps.last_action = jiffies;
+ ar->ps.state = ps;
+ }
+
+ return 0;
+}
+
+static void carl9170_ps_work(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ ps_work);
+ mutex_lock(&ar->mutex);
+ if (IS_STARTED(ar))
+ WARN_ON_ONCE(carl9170_ps_update(ar) != 0);
+ mutex_unlock(&ar->mutex);
+}
+
+
+static int carl9170_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) {
+ err = carl9170_ps_update(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ /* TODO */
+ err = 0;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_SMPS) {
+ /* TODO */
+ err = 0;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ /* adjust slot time for 5 GHz */
+ err = carl9170_set_slot_time(ar);
+ if (err)
+ goto out;
+
+ err = carl9170_set_channel(ar, hw->conf.channel,
+ hw->conf.channel_type, CARL9170_RFI_NONE);
+ if (err)
+ goto out;
+
+ err = carl9170_set_dyn_sifs_ack(ar);
+ if (err)
+ goto out;
+
+ err = carl9170_set_rts_cts_rate(ar);
+ if (err)
+ goto out;
+ }
+
+out:
+ mutex_unlock(&ar->mutex);
+ return err;
+}
+
+static u64 carl9170_op_prepare_multicast(struct ieee80211_hw *hw,
+ struct netdev_hw_addr_list *mc_list)
+{
+ struct netdev_hw_addr *ha;
+ u64 mchash;
+
+ /* 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 carl9170_op_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *new_flags,
+ u64 multicast)
+{
+ struct ar9170 *ar = hw->priv;
+
+ /* mask supported flags */
+ *new_flags &= FIF_ALLMULTI | ar->rx_filter_caps;
+
+ if (!IS_ACCEPTING_CMD(ar))
+ return;
+
+ mutex_lock(&ar->mutex);
+
+ 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)
+ WARN_ON(carl9170_update_multicast(ar, multicast));
+
+ if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
+ ar->sniffer_enabled = !!(*new_flags &
+ (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS));
+
+ WARN_ON(carl9170_set_operating_mode(ar));
+ }
+
+ if (ar->fw.rx_filter && changed_flags & ar->rx_filter_caps) {
+ u32 rx_filter = 0;
+
+ if (!(*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)))
+ rx_filter |= CARL9170_RX_FILTER_BAD;
+
+ if (!(*new_flags & FIF_CONTROL))
+ rx_filter |= CARL9170_RX_FILTER_CTL_OTHER;
+
+ if (!(*new_flags & FIF_PSPOLL))
+ rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL;
+
+ if (!(*new_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))) {
+ rx_filter |= CARL9170_RX_FILTER_OTHER_RA;
+ rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL;
+ }
+
+ WARN_ON(carl9170_rx_filter(ar, rx_filter));
+ }
+
+ mutex_unlock(&ar->mutex);
+}
+
+
+static void carl9170_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;
+ struct carl9170_vif_info *vif_priv;
+ struct ieee80211_vif *main_vif;
+
+ mutex_lock(&ar->mutex);
+ vif_priv = (void *) vif->drv_priv;
+ main_vif = carl9170_get_main_vif(ar);
+ if (WARN_ON(!main_vif))
+ goto out;
+
+ if (changed & BSS_CHANGED_BEACON_ENABLED) {
+ struct carl9170_vif_info *iter;
+ int i = 0;
+
+ vif_priv->enable_beacon = bss_conf->enable_beacon;
+ rcu_read_lock();
+ list_for_each_entry_rcu(iter, &ar->vif_list, list) {
+ if (iter->active && iter->enable_beacon)
+ i++;
+
+ }
+ rcu_read_unlock();
+
+ ar->beacon_enabled = i;
+ }
+
+ if (changed & BSS_CHANGED_BEACON) {
+ err = carl9170_update_beacon(ar, false);
+ if (err)
+ goto out;
+ }
+
+ if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
+ BSS_CHANGED_BEACON_INT)) {
+
+ if (main_vif != vif) {
+ bss_conf->beacon_int = main_vif->bss_conf.beacon_int;
+ bss_conf->dtim_period = main_vif->bss_conf.dtim_period;
+ }
+
+ /*
+ * Therefore a hard limit for the broadcast traffic should
+ * prevent false alarms.
+ */
+ if (vif->type != NL80211_IFTYPE_STATION &&
+ (bss_conf->beacon_int * bss_conf->dtim_period >=
+ (CARL9170_QUEUE_STUCK_TIMEOUT / 2))) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ err = carl9170_set_beacon_timers(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_HT) {
+ /* TODO */
+ err = 0;
+ if (err)
+ goto out;
+ }
+
+ if (main_vif != vif)
+ goto out;
+
+ /*
+ * The following settings can only be changed by the
+ * master interface.
+ */
+
+ if (changed & BSS_CHANGED_BSSID) {
+ memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+ err = carl9170_set_operating_mode(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_ASSOC) {
+ ar->common.curaid = bss_conf->aid;
+ err = carl9170_set_beacon_timers(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ err = carl9170_set_slot_time(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ err = carl9170_set_mac_rates(ar);
+ if (err)
+ goto out;
+ }
+
+out:
+ WARN_ON_ONCE(err && IS_STARTED(ar));
+ mutex_unlock(&ar->mutex);
+}
+
+static u64 carl9170_op_get_tsf(struct ieee80211_hw *hw)
+{
+ struct ar9170 *ar = hw->priv;
+ struct carl9170_tsf_rsp tsf;
+ int err;
+
+ mutex_lock(&ar->mutex);
+ err = carl9170_exec_cmd(ar, CARL9170_CMD_READ_TSF,
+ 0, NULL, sizeof(tsf), &tsf);
+ mutex_unlock(&ar->mutex);
+ if (WARN_ON(err))
+ return 0;
+
+ return le64_to_cpu(tsf.tsf_64);
+}
+
+static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct ar9170 *ar = hw->priv;
+ int err = 0, i;
+ u8 ktype;
+
+ if (ar->disable_offload || !vif)
+ return -EOPNOTSUPP;
+
+ /*
+ * We have to fall back to software encryption, whenever
+ * the user choose to participates in an IBSS or is connected
+ * to more than one network.
+ *
+ * This is very unfortunate, because some machines cannot handle
+ * the high througput speed in 802.11n networks.
+ */
+
+ if (!is_main_vif(ar, vif))
+ goto err_softw;
+
+ /*
+ * While the hardware supports *catch-all* key, for offloading
+ * group-key en-/de-cryption. The way of how the hardware
+ * decides which keyId maps to which key, remains a mystery...
+ */
+ if ((vif->type != NL80211_IFTYPE_STATION &&
+ vif->type != NL80211_IFTYPE_ADHOC) &&
+ !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+ 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 (!IS_STARTED(ar)) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+ sta = NULL;
+
+ i = 64 + key->keyidx;
+ } else {
+ for (i = 0; i < 64; i++)
+ if (!(ar->usedkeys & BIT(i)))
+ break;
+ if (i == 64)
+ goto err_softw;
+ }
+
+ key->hw_key_idx = i;
+
+ err = carl9170_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 = carl9170_upload_key(ar, i, sta ? sta->addr :
+ NULL, ktype, 1,
+ key->key + 16, 16);
+ if (err)
+ goto out;
+
+ /*
+ * hardware is not capable generating MMIC
+ * of 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 (!IS_STARTED(ar)) {
+ /* The device is gone... together with the key ;-) */
+ err = 0;
+ goto out;
+ }
+
+ if (key->hw_key_idx < 64) {
+ ar->usedkeys &= ~BIT(key->hw_key_idx);
+ } else {
+ err = carl9170_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 = carl9170_upload_key(ar, key->hw_key_idx,
+ NULL,
+ AR9170_ENC_ALG_NONE,
+ 1, NULL, 0);
+ if (err)
+ goto out;
+ }
+
+ }
+
+ err = carl9170_disable_key(ar, key->hw_key_idx);
+ if (err)
+ goto out;
+ }
+
+out:
+ mutex_unlock(&ar->mutex);
+ return err;
+
+err_softw:
+ if (!ar->rx_software_decryption) {
+ ar->rx_software_decryption = true;
+ carl9170_set_operating_mode(ar);
+ }
+ mutex_unlock(&ar->mutex);
+ return -ENOSPC;
+}
+
+static int carl9170_op_sta_add(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
+ unsigned int i;
+
+ if (sta->ht_cap.ht_supported) {
+ if (sta->ht_cap.ampdu_density > 6) {
+ /*
+ * HW does support 16us AMPDU density.
+ * No HT-Xmit for station.
+ */
+
+ return 0;
+ }
+
+ for (i = 0; i < CARL9170_NUM_TID; i++)
+ rcu_assign_pointer(sta_info->agg[i], NULL);
+
+ sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
+ sta_info->ht_sta = true;
+ }
+
+ return 0;
+}
+
+static int carl9170_op_sta_remove(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct ar9170 *ar = hw->priv;
+ struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
+ unsigned int i;
+ bool cleanup = false;
+
+ if (sta->ht_cap.ht_supported) {
+
+ sta_info->ht_sta = false;
+
+ 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]);
+ rcu_assign_pointer(sta_info->agg[i], NULL);
+
+ if (!tid_info)
+ continue;
+
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ if (tid_info->state > CARL9170_TID_STATE_SHUTDOWN)
+ tid_info->state = CARL9170_TID_STATE_SHUTDOWN;
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+ cleanup = true;
+ }
+ rcu_read_unlock();
+
+ if (cleanup)
+ carl9170_ampdu_gc(ar);
+ }
+
+ return 0;
+}
+
+static int carl9170_op_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 < ar->hw->queues) {
+ memcpy(&ar->edcf[ar9170_qmap[queue]], param, sizeof(*param));
+ ret = carl9170_set_qos(ar);
+ } else {
+ ret = -EINVAL;
+ }
+
+ mutex_unlock(&ar->mutex);
+ return ret;
+}
+
+static void carl9170_ampdu_work(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ ampdu_work);
+
+ if (!IS_STARTED(ar))
+ return;
+
+ mutex_lock(&ar->mutex);
+ carl9170_ampdu_gc(ar);
+ mutex_unlock(&ar->mutex);
+}
+
+static int carl9170_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)
+{
+ struct ar9170 *ar = hw->priv;
+ struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
+ struct carl9170_sta_tid *tid_info;
+
+ if (modparam_noht)
+ return -EOPNOTSUPP;
+
+ switch (action) {
+ case IEEE80211_AMPDU_TX_START:
+ if (!sta_info->ht_sta)
+ return -EOPNOTSUPP;
+
+ rcu_read_lock();
+ if (rcu_dereference(sta_info->agg[tid])) {
+ rcu_read_unlock();
+ return -EBUSY;
+ }
+
+ tid_info = kzalloc(sizeof(struct carl9170_sta_tid),
+ GFP_ATOMIC);
+ if (!tid_info) {
+ rcu_read_unlock();
+ return -ENOMEM;
+ }
+
+ tid_info->hsn = tid_info->bsn = tid_info->snx = (*ssn);
+ tid_info->state = CARL9170_TID_STATE_PROGRESS;
+ tid_info->tid = tid;
+ tid_info->max = sta_info->ampdu_max_len;
+
+ INIT_LIST_HEAD(&tid_info->list);
+ INIT_LIST_HEAD(&tid_info->tmp_list);
+ skb_queue_head_init(&tid_info->queue);
+ spin_lock_init(&tid_info->lock);
+
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ ar->tx_ampdu_list_len++;
+ list_add_tail_rcu(&tid_info->list, &ar->tx_ampdu_list);
+ rcu_assign_pointer(sta_info->agg[tid], tid_info);
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+ rcu_read_unlock();
+
+ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ break;
+
+ case IEEE80211_AMPDU_TX_STOP:
+ rcu_read_lock();
+ tid_info = rcu_dereference(sta_info->agg[tid]);
+ if (tid_info) {
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ if (tid_info->state > CARL9170_TID_STATE_SHUTDOWN)
+ tid_info->state = CARL9170_TID_STATE_SHUTDOWN;
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+ }
+
+ rcu_assign_pointer(sta_info->agg[tid], NULL);
+ rcu_read_unlock();
+
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ ieee80211_queue_work(ar->hw, &ar->ampdu_work);
+ break;
+
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
+ rcu_read_lock();
+ tid_info = rcu_dereference(sta_info->agg[tid]);
+
+ sta_info->stats[tid].clear = true;
+
+ if (tid_info) {
+ bitmap_zero(tid_info->bitmap, CARL9170_BAW_SIZE);
+ tid_info->state = CARL9170_TID_STATE_IDLE;
+ }
+ rcu_read_unlock();
+
+ if (WARN_ON_ONCE(!tid_info))
+ return -EFAULT;
+
+ break;
+
+ case IEEE80211_AMPDU_RX_START:
+ case IEEE80211_AMPDU_RX_STOP:
+ /* Handled by hardware */
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_CARL9170_WPC
+static int carl9170_register_wps_button(struct ar9170 *ar)
+{
+ struct input_dev *input;
+ int err;
+
+ if (!(ar->features & CARL9170_WPS_BUTTON))
+ return 0;
+
+ input = input_allocate_device();
+ if (!input)
+ return -ENOMEM;
+
+ snprintf(ar->wps.name, sizeof(ar->wps.name), "%s WPS Button",
+ wiphy_name(ar->hw->wiphy));
+
+ snprintf(ar->wps.phys, sizeof(ar->wps.phys),
+ "ieee80211/%s/input0", wiphy_name(ar->hw->wiphy));
+
+ input->name = ar->wps.name;
+ input->phys = ar->wps.phys;
+ input->id.bustype = BUS_USB;
+ input->dev.parent = &ar->hw->wiphy->dev;
+
+ input_set_capability(input, EV_KEY, KEY_WPS_BUTTON);
+
+ err = input_register_device(input);
+ if (err) {
+ input_free_device(input);
+ return err;
+ }
+
+ ar->wps.pbc = input;
+ return 0;
+}
+#endif /* CONFIG_CARL9170_WPC */
+
+static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx,
+ struct survey_info *survey)
+{
+ struct ar9170 *ar = hw->priv;
+ int err;
+
+ if (idx != 0)
+ return -ENOENT;
+
+ mutex_lock(&ar->mutex);
+ err = carl9170_get_noisefloor(ar);
+ mutex_unlock(&ar->mutex);
+ if (err)
+ return err;
+
+ survey->channel = ar->channel;
+ survey->filled = SURVEY_INFO_NOISE_DBM;
+ survey->noise = ar->noise[0];
+ return 0;
+}
+
+static void carl9170_op_flush(struct ieee80211_hw *hw, bool drop)
+{
+ struct ar9170 *ar = hw->priv;
+ unsigned int vid;
+
+ mutex_lock(&ar->mutex);
+ for_each_set_bit(vid, &ar->vif_bitmap, ar->fw.vif_num)
+ carl9170_flush_cab(ar, vid);
+
+ carl9170_flush(ar, drop);
+ mutex_unlock(&ar->mutex);
+}
+
+static int carl9170_op_get_stats(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
+{
+ struct ar9170 *ar = hw->priv;
+
+ memset(stats, 0, sizeof(*stats));
+ stats->dot11ACKFailureCount = ar->tx_ack_failures;
+ stats->dot11FCSErrorCount = ar->tx_fcs_errors;
+ return 0;
+}
+
+static void carl9170_op_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta)
+{
+ struct ar9170 *ar = hw->priv;
+ struct 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);
+
+ 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();
+ break;
+ }
+}
+
+static const struct ieee80211_ops carl9170_ops = {
+ .start = carl9170_op_start,
+ .stop = carl9170_op_stop,
+ .tx = carl9170_op_tx,
+ .flush = carl9170_op_flush,
+ .add_interface = carl9170_op_add_interface,
+ .remove_interface = carl9170_op_remove_interface,
+ .config = carl9170_op_config,
+ .prepare_multicast = carl9170_op_prepare_multicast,
+ .configure_filter = carl9170_op_configure_filter,
+ .conf_tx = carl9170_op_conf_tx,
+ .bss_info_changed = carl9170_op_bss_info_changed,
+ .get_tsf = carl9170_op_get_tsf,
+ .set_key = carl9170_op_set_key,
+ .sta_add = carl9170_op_sta_add,
+ .sta_remove = carl9170_op_sta_remove,
+ .sta_notify = carl9170_op_sta_notify,
+ .get_survey = carl9170_op_get_survey,
+ .get_stats = carl9170_op_get_stats,
+ .ampdu_action = carl9170_op_ampdu_action,
+};
+
+void *carl9170_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, &carl9170_ops);
+ if (!hw)
+ goto err_nomem;
+
+ ar = hw->priv;
+ ar->hw = hw;
+ ar->rx_failover = skb;
+
+ memset(&ar->rx_plcp, 0, sizeof(struct ar9170_rx_head));
+ ar->rx_has_plcp = false;
+
+ /*
+ * Here's a hidden pitfall!
+ *
+ * All 4 AC queues work perfectly well under _legacy_ operation.
+ * However as soon as aggregation is enabled, the traffic flow
+ * gets very bumpy. Therefore we have to _switch_ to a
+ * software AC with a single HW queue.
+ */
+ hw->queues = __AR9170_NUM_TXQ;
+
+ mutex_init(&ar->mutex);
+ spin_lock_init(&ar->beacon_lock);
+ spin_lock_init(&ar->cmd_lock);
+ spin_lock_init(&ar->tx_stats_lock);
+ spin_lock_init(&ar->tx_ampdu_list_lock);
+ spin_lock_init(&ar->mem_lock);
+ spin_lock_init(&ar->state_lock);
+ atomic_set(&ar->pending_restarts, 0);
+ ar->vifs = 0;
+ for (i = 0; i < ar->hw->queues; i++) {
+ skb_queue_head_init(&ar->tx_status[i]);
+ skb_queue_head_init(&ar->tx_pending[i]);
+ }
+ INIT_WORK(&ar->ps_work, carl9170_ps_work);
+ INIT_WORK(&ar->restart_work, carl9170_restart_work);
+ INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work);
+ INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor);
+ INIT_LIST_HEAD(&ar->tx_ampdu_list);
+ rcu_assign_pointer(ar->tx_ampdu_iter,
+ (struct carl9170_sta_tid *) &ar->tx_ampdu_list);
+
+ bitmap_zero(&ar->vif_bitmap, ar->fw.vif_num);
+ INIT_LIST_HEAD(&ar->vif_list);
+ init_completion(&ar->tx_flush);
+
+ /*
+ * Note:
+ * IBSS/ADHOC and AP mode are only enabled, if the firmware
+ * supports these modes. The code which will add the
+ * additional interface_modes is in fw.c.
+ */
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+
+ hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK |
+ IEEE80211_HW_SIGNAL_DBM;
+
+ if (!modparam_noht) {
+ /*
+ * see the comment above, why we allow the user
+ * to disable HT by a module parameter.
+ */
+ hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+ }
+
+ hw->extra_tx_headroom = sizeof(struct _carl9170_tx_superframe);
+ hw->sta_data_size = sizeof(struct carl9170_sta_info);
+ hw->vif_data_size = sizeof(struct carl9170_vif_info);
+
+ hw->max_rates = CARL9170_TX_MAX_RATES;
+ hw->max_rate_tries = CARL9170_TX_USER_RATE_TRIES;
+
+ for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
+ ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
+
+ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+ return ar;
+
+err_nomem:
+ kfree_skb(skb);
+ return ERR_PTR(-ENOMEM);
+}
+
+static int carl9170_read_eeprom(struct ar9170 *ar)
+{
+#define RW 8 /* number of words to read at once */
+#define RB (sizeof(u32) * RW)
+ u8 *eeprom = (void *)&ar->eeprom;
+ __le32 offsets[RW];
+ int i, j, err;
+
+ BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
+
+ BUILD_BUG_ON(RB > CARL9170_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 = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
+ RB, (u8 *) &offsets,
+ RB, eeprom + RB * i);
+ if (err)
+ return err;
+ }
+
+#undef RW
+#undef RB
+ return 0;
+}
+
+static int carl9170_parse_eeprom(struct ar9170 *ar)
+{
+ struct ath_regulatory *regulatory = &ar->common.regulatory;
+ unsigned int rx_streams, tx_streams, tx_params = 0;
+ int bands = 0;
+
+ if (ar->eeprom.length == cpu_to_le16(0xffff))
+ return -ENODATA;
+
+ 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;
+
+ WARN_ON(!(tx_streams >= 1 && tx_streams <=
+ IEEE80211_HT_MCS_TX_MAX_STREAMS));
+
+ tx_params = (tx_streams - 1) <<
+ IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
+
+ carl9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
+ carl9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
+ }
+
+ if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
+ ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &carl9170_band_2GHz;
+ bands++;
+ }
+ if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
+ ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &carl9170_band_5GHz;
+ bands++;
+ }
+
+ /*
+ * I measured this, a bandswitch takes roughly
+ * 135 ms and a frequency switch about 80.
+ *
+ * FIXME: measure these values again once EEPROM settings
+ * are used, that will influence them!
+ */
+ if (bands == 2)
+ ar->hw->channel_change_time = 135 * 1000;
+ else
+ ar->hw->channel_change_time = 80 * 1000;
+
+ 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, ar->eeprom.mac_address);
+
+ return bands ? 0 : -EINVAL;
+}
+
+static int carl9170_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 carl9170_register(struct ar9170 *ar)
+{
+ struct ath_regulatory *regulatory = &ar->common.regulatory;
+ int err = 0, i;
+
+ if (WARN_ON(ar->mem_bitmap))
+ return -EINVAL;
+
+ ar->mem_bitmap = kzalloc(roundup(ar->fw.mem_blocks, BITS_PER_LONG) *
+ sizeof(unsigned long), GFP_KERNEL);
+
+ if (!ar->mem_bitmap)
+ return -ENOMEM;
+
+ /* try to read EEPROM, init MAC addr */
+ err = carl9170_read_eeprom(ar);
+ if (err)
+ return err;
+
+ err = carl9170_fw_fix_eeprom(ar);
+ if (err)
+ return err;
+
+ err = carl9170_parse_eeprom(ar);
+ if (err)
+ return err;
+
+ err = ath_regd_init(regulatory, ar->hw->wiphy,
+ carl9170_reg_notifier);
+ if (err)
+ return err;
+
+ if (modparam_noht) {
+ carl9170_band_2GHz.ht_cap.ht_supported = false;
+ carl9170_band_5GHz.ht_cap.ht_supported = false;
+ }
+
+ for (i = 0; i < ar->fw.vif_num; i++) {
+ ar->vif_priv[i].id = i;
+ ar->vif_priv[i].vif = NULL;
+ }
+
+ err = ieee80211_register_hw(ar->hw);
+ if (err)
+ return err;
+
+ /* mac80211 interface is now registered */
+ ar->registered = true;
+
+ if (!ath_is_world_regd(regulatory))
+ regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
+
+#ifdef CONFIG_CARL9170_DEBUGFS
+ carl9170_debugfs_register(ar);
+#endif /* CONFIG_CARL9170_DEBUGFS */
+
+ err = carl9170_led_init(ar);
+ if (err)
+ goto err_unreg;
+
+#ifdef CONFIG_CARL9170_LEDS
+ err = carl9170_led_register(ar);
+ if (err)
+ goto err_unreg;
+#endif /* CONFIG_CAR9L170_LEDS */
+
+#ifdef CONFIG_CARL9170_WPC
+ err = carl9170_register_wps_button(ar);
+ if (err)
+ goto err_unreg;
+#endif /* CONFIG_CARL9170_WPC */
+
+ dev_info(&ar->udev->dev, "Atheros AR9170 is registered as '%s'\n",
+ wiphy_name(ar->hw->wiphy));
+
+ return 0;
+
+err_unreg:
+ carl9170_unregister(ar);
+ return err;
+}
+
+void carl9170_unregister(struct ar9170 *ar)
+{
+ if (!ar->registered)
+ return;
+
+ ar->registered = false;
+
+#ifdef CONFIG_CARL9170_LEDS
+ carl9170_led_unregister(ar);
+#endif /* CONFIG_CARL9170_LEDS */
+
+#ifdef CONFIG_CARL9170_DEBUGFS
+ carl9170_debugfs_unregister(ar);
+#endif /* CONFIG_CARL9170_DEBUGFS */
+
+#ifdef CONFIG_CARL9170_WPC
+ if (ar->wps.pbc) {
+ input_unregister_device(ar->wps.pbc);
+ ar->wps.pbc = NULL;
+ }
+#endif /* CONFIG_CARL9170_WPC */
+
+ carl9170_cancel_worker(ar);
+ cancel_work_sync(&ar->restart_work);
+
+ ieee80211_unregister_hw(ar->hw);
+}
+
+void carl9170_free(struct ar9170 *ar)
+{
+ WARN_ON(ar->registered);
+ WARN_ON(IS_INITIALIZED(ar));
+
+ kfree_skb(ar->rx_failover);
+ ar->rx_failover = NULL;
+
+ kfree(ar->mem_bitmap);
+ ar->mem_bitmap = NULL;
+
+ mutex_destroy(&ar->mutex);
+
+ ieee80211_free_hw(ar->hw);
+}
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
new file mode 100644
index 000000000000..89deca37a988
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -0,0 +1,1810 @@
+/*
+ * Atheros CARL9170 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 "carl9170.h"
+#include "cmd.h"
+#include "phy.h"
+
+static int carl9170_init_power_cal(struct ar9170 *ar)
+{
+ carl9170_regwrite_begin(ar);
+
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE_MAX, 0x7f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE1, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE2, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE3, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE4, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE5, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE6, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE7, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE8, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE9, 0x3f3f3f3f);
+
+ carl9170_regwrite_finish();
+ return carl9170_regwrite_result();
+}
+
+struct carl9170_phy_init {
+ u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
+};
+
+static struct carl9170_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, 0x6d48b4e4, 0x6d48b0e4, 0x6c48b0e4, },
+ { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
+ { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
+ { 0x1c585c, 0x31395c5e, 0x3139605e, 0x3139605e, 0x31395c5e, },
+ { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
+ { 0x1c5864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
+ { 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, },
+ { 0x1c59bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
+ { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
+ { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
+ { 0x1c59c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, },
+ { 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 carl9170_def_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 bandwith
+ */
+static int carl9170_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
+ };
+ /* pointer to the modal_header acc. to band */
+ struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz];
+ u32 val;
+
+ carl9170_regwrite_begin(ar);
+
+ /* ant common control (index 0) */
+ carl9170_regwrite(AR9170_PHY_REG_SWITCH_COM,
+ le32_to_cpu(m->antCtrlCommon));
+
+ /* ant control chain 0 (index 1) */
+ carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_0,
+ le32_to_cpu(m->antCtrlChain[0]));
+
+ /* ant control chain 2 (index 2) */
+ carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_2,
+ le32_to_cpu(m->antCtrlChain[1]));
+
+ /* SwSettle (index 3) */
+ if (!is_40mhz) {
+ val = carl9170_def_val(AR9170_PHY_REG_SETTLING,
+ is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_SETTLING_SWITCH, val, m->switchSettling);
+ carl9170_regwrite(AR9170_PHY_REG_SETTLING, val);
+ }
+
+ /* adcDesired, pdaDesired (index 4) */
+ val = carl9170_def_val(AR9170_PHY_REG_DESIRED_SZ, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_DESIRED_SZ_PGA, val, m->pgaDesiredSize);
+ SET_VAL(AR9170_PHY_DESIRED_SZ_ADC, val, m->adcDesiredSize);
+ carl9170_regwrite(AR9170_PHY_REG_DESIRED_SZ, val);
+
+ /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */
+ val = carl9170_def_val(AR9170_PHY_REG_RF_CTL4, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF, val, m->txEndToXpaOff);
+ SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF, val, m->txEndToXpaOff);
+ SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAB_ON, val, m->txFrameToXpaOn);
+ SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAA_ON, val, m->txFrameToXpaOn);
+ carl9170_regwrite(AR9170_PHY_REG_RF_CTL4, val);
+
+ /* TxEndToRxOn (index 6) */
+ val = carl9170_def_val(AR9170_PHY_REG_RF_CTL3, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON, val, m->txEndToRxOn);
+ carl9170_regwrite(AR9170_PHY_REG_RF_CTL3, val);
+
+ /* thresh62 (index 7) */
+ val = carl9170_def_val(0x1c8864, is_2ghz, is_40mhz);
+ val = (val & ~0x7f000) | (m->thresh62 << 12);
+ carl9170_regwrite(0x1c8864, val);
+
+ /* tx/rx attenuation chain 0 (index 8) */
+ val = carl9170_def_val(AR9170_PHY_REG_RXGAIN, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[0]);
+ carl9170_regwrite(AR9170_PHY_REG_RXGAIN, val);
+
+ /* tx/rx attenuation chain 2 (index 9) */
+ val = carl9170_def_val(AR9170_PHY_REG_RXGAIN_CHAIN_2,
+ is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[1]);
+ carl9170_regwrite(AR9170_PHY_REG_RXGAIN_CHAIN_2, val);
+
+ /* tx/rx margin chain 0 (index 10) */
+ val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[0]);
+ /* bsw margin chain 0 for 5GHz only */
+ if (!is_2ghz)
+ SET_VAL(AR9170_PHY_GAIN_2GHZ_BSW_MARGIN, val, m->bswMargin[0]);
+ carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ, val);
+
+ /* tx/rx margin chain 2 (index 11) */
+ val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2,
+ is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[1]);
+ carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2, val);
+
+ /* iqCall, iqCallq chain 0 (index 12) */
+ val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(0),
+ is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[0]);
+ SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[0]);
+ carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(0), val);
+
+ /* iqCall, iqCallq chain 2 (index 13) */
+ val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(2),
+ is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[1]);
+ SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[1]);
+ carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(2), val);
+
+ /* xpd gain mask (index 14) */
+ val = carl9170_def_val(AR9170_PHY_REG_TPCRG1, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_1, val,
+ xpd2pd[m->xpdGain & 0xf] & 3);
+ SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_2, val,
+ xpd2pd[m->xpdGain & 0xf] >> 2);
+ carl9170_regwrite(AR9170_PHY_REG_TPCRG1, val);
+
+ carl9170_regwrite(AR9170_PHY_REG_RX_CHAINMASK, ar->eeprom.rx_mask);
+ carl9170_regwrite(AR9170_PHY_REG_CAL_CHAINMASK, ar->eeprom.rx_mask);
+
+ carl9170_regwrite_finish();
+ return carl9170_regwrite_result();
+}
+
+static int carl9170_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);
+
+ carl9170_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;
+ }
+
+ carl9170_regwrite(ar5416_phy_init[i].reg, val);
+ }
+
+ carl9170_regwrite_finish();
+ err = carl9170_regwrite_result();
+ if (err)
+ return err;
+
+ err = carl9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz);
+ if (err)
+ return err;
+
+ err = carl9170_init_power_cal(ar);
+ if (err)
+ return err;
+
+ /* XXX: remove magic! */
+ if (is_2ghz)
+ err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, 0x5163);
+ else
+ err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, 0x5143);
+
+ return err;
+}
+
+struct carl9170_rf_initvals {
+ u32 reg, _5ghz, _2ghz;
+};
+
+static struct carl9170_rf_initvals carl9170_rf_initval[] = {
+ /* 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 carl9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
+{
+ int err, i;
+
+ carl9170_regwrite_begin(ar);
+
+ for (i = 0; i < ARRAY_SIZE(carl9170_rf_initval); i++)
+ carl9170_regwrite(carl9170_rf_initval[i].reg,
+ band5ghz ? carl9170_rf_initval[i]._5ghz
+ : carl9170_rf_initval[i]._2ghz);
+
+ carl9170_regwrite_finish();
+ err = carl9170_regwrite_result();
+ if (err)
+ wiphy_err(ar->hw->wiphy, "rf init failed\n");
+
+ return err;
+}
+
+struct carl9170_phy_freq_params {
+ u8 coeff_exp;
+ u16 coeff_man;
+ u8 coeff_exp_shgi;
+ u16 coeff_man_shgi;
+};
+
+enum carl9170_bw {
+ CARL9170_BW_20,
+ CARL9170_BW_40_BELOW,
+ CARL9170_BW_40_ABOVE,
+
+ __CARL9170_NUM_BW,
+};
+
+struct carl9170_phy_freq_entry {
+ u16 freq;
+ struct carl9170_phy_freq_params params[__CARL9170_NUM_BW];
+};
+
+/* NB: must be in sync with channel tables in main! */
+static const struct carl9170_phy_freq_entry carl9170_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 int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
+ u32 freq, enum carl9170_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 CARL9170_BW_40_ABOVE:
+ freq += 10;
+ break;
+ case CARL9170_BW_40_BELOW:
+ freq -= 10;
+ break;
+ case CARL9170_BW_20:
+ break;
+ default:
+ BUG();
+ return -ENOSYS;
+ }
+
+ 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;
+
+ carl9170_regwrite_begin(ar);
+
+ carl9170_regwrite(0x1c58b0, fd0);
+ carl9170_regwrite(0x1c58e8, fd1);
+
+ carl9170_regwrite_finish();
+ err = carl9170_regwrite_result();
+ if (err)
+ return err;
+
+ msleep(20);
+
+ return 0;
+}
+
+static const struct carl9170_phy_freq_params *
+carl9170_get_hw_dyn_params(struct ieee80211_channel *channel,
+ enum carl9170_bw bw)
+{
+ unsigned int chanidx = 0;
+ u16 freq = 2412;
+
+ if (channel) {
+ chanidx = channel->hw_value;
+ freq = channel->center_freq;
+ }
+
+ BUG_ON(chanidx >= ARRAY_SIZE(carl9170_phy_freq_params));
+
+ BUILD_BUG_ON(__CARL9170_NUM_BW != 3);
+
+ WARN_ON(carl9170_phy_freq_params[chanidx].freq != freq);
+
+ return &carl9170_phy_freq_params[chanidx].params[bw];
+}
+
+static int carl9170_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 carl9170_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 carl9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
+{
+#define SHIFT 8
+ s32 y;
+
+ y = carl9170_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 carl9170_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 carl9170_interpolate_u8(x, x_array[i], y_array[i],
+ x_array[i + 1], y_array[i + 1]);
+}
+
+static int carl9170_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 = carl9170_find_freq_idx(i, cal_freq_pier, f);
+
+ carl9170_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] = carl9170_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] = carl9170_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 = carl9170_interpolate_val(i, &pwrs[0][0],
+ &vpds[0][0]);
+ } else {
+ tmp = carl9170_interpolate_val(i - 12,
+ &pwrs[1][0],
+ &vpds[1][0]);
+ }
+
+ phy_data |= tmp << ((i & 3) << 3);
+ if ((i & 3) == 3) {
+ carl9170_regwrite(0x1c6280 + chain * 0x1000 +
+ (i & ~3), phy_data);
+ phy_data = 0;
+ }
+ }
+
+ for (i = 19; i < 32; i++)
+ carl9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2),
+ 0x0);
+ }
+
+ carl9170_regwrite_finish();
+ return carl9170_regwrite_result();
+}
+
+static u8 carl9170_get_max_edge_power(struct ar9170 *ar,
+ u32 freq, struct ar9170_calctl_edges edges[])
+{
+ 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 carl9170_get_heavy_clip(struct ar9170 *ar, u32 freq,
+ enum carl9170_bw bw, struct ar9170_calctl_edges edges[])
+{
+ u8 f;
+ int i;
+ u8 rc = 0;
+
+ if (freq < 3000)
+ f = freq - 2300;
+ else
+ f = (freq - 4800) / 5;
+
+ if (bw == CARL9170_BW_40_BELOW || bw == CARL9170_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 carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_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->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 heavy clip parameter
+ * from the 11G edges array
+ */
+ if (modes[i].ctl_mode == CTL_11G) {
+ ar->heavy_clip =
+ carl9170_get_heavy_clip(ar,
+ freq, bw, EDGES(ctl_idx, 1));
+ }
+
+ /* adjust freq for 40MHz */
+ if (modes[i].ctl_mode == CTL_2GHT40 ||
+ modes[i].ctl_mode == CTL_5GHT40) {
+ if (bw == CARL9170_BW_40_BELOW)
+ f_off = -10;
+ else
+ f_off = 10;
+ }
+
+ modes[i].max_power =
+ carl9170_get_max_edge_power(ar,
+ freq+f_off, EDGES(ctl_idx, 1));
+
+ /*
+ * 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->heavy_clip & 0xf0) {
+ ar->power_2G_ht40[0]--;
+ ar->power_2G_ht40[1]--;
+ ar->power_2G_ht40[2]--;
+ }
+ if (ar->heavy_clip & 0xf) {
+ ar->power_2G_ht20[0]++;
+ ar->power_2G_ht20[1]++;
+ ar->power_2G_ht20[2]++;
+ }
+
+#undef EDGES
+}
+
+static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
+ enum carl9170_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 = carl9170_find_freq_idx(ntargets, pwr_freqs, f);
+ for (n = 0; n < 4; n++)
+ ctpres[n] = carl9170_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 = carl9170_find_freq_idx(ntargets, pwr_freqs, f);
+ for (n = 0; n < 8; n++)
+ ctpres[n] = carl9170_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*[] */
+ carl9170_calc_ctl(ar, freq, bw);
+
+ /* set ACK/CTS TX power */
+ carl9170_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;
+
+ carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
+ 0x3c1e | ackpower << 20 | ackchains << 26);
+ carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
+ ackpower << 5 | ackchains << 11 |
+ ackpower << 21 | ackchains << 27);
+
+ carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
+ ackpower << 5 | ackchains << 11 |
+ ackpower << 21 | ackchains << 27);
+
+ carl9170_regwrite_finish();
+ return carl9170_regwrite_result();
+}
+
+/* TODO: replace this with sign_extend32(noise, 8) */
+static int carl9170_calc_noise_dbm(u32 raw_noise)
+{
+ if (raw_noise & 0x100)
+ return ~0x1ff | raw_noise;
+ else
+ return raw_noise;
+}
+
+int carl9170_get_noisefloor(struct ar9170 *ar)
+{
+ static const u32 phy_regs[] = {
+ AR9170_PHY_REG_CCA, AR9170_PHY_REG_CH2_CCA,
+ AR9170_PHY_REG_EXT_CCA, AR9170_PHY_REG_CH2_EXT_CCA };
+ u32 phy_res[ARRAY_SIZE(phy_regs)];
+ int err, i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(phy_regs) != ARRAY_SIZE(ar->noise));
+
+ err = carl9170_read_mreg(ar, ARRAY_SIZE(phy_regs), phy_regs, phy_res);
+ if (err)
+ return err;
+
+ for (i = 0; i < 2; i++) {
+ ar->noise[i] = carl9170_calc_noise_dbm(
+ (phy_res[i] >> 19) & 0x1ff);
+
+ ar->noise[i + 2] = carl9170_calc_noise_dbm(
+ (phy_res[i + 2] >> 23) & 0x1ff);
+ }
+
+ return 0;
+}
+
+static enum carl9170_bw nl80211_to_carl(enum nl80211_channel_type type)
+{
+ switch (type) {
+ case NL80211_CHAN_NO_HT:
+ case NL80211_CHAN_HT20:
+ return CARL9170_BW_20;
+ case NL80211_CHAN_HT40MINUS:
+ return CARL9170_BW_40_BELOW;
+ case NL80211_CHAN_HT40PLUS:
+ return CARL9170_BW_40_ABOVE;
+ default:
+ BUG();
+ }
+}
+
+int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+ enum nl80211_channel_type _bw,
+ enum carl9170_rf_init_mode rfi)
+{
+ const struct carl9170_phy_freq_params *freqpar;
+ struct carl9170_rf_init_result rf_res;
+ struct carl9170_rf_init rf;
+ u32 cmd, tmp, offs = 0, new_ht = 0;
+ int err;
+ enum carl9170_bw bw;
+ bool warm_reset;
+ struct ieee80211_channel *old_channel = NULL;
+
+ bw = nl80211_to_carl(_bw);
+
+ if (conf_is_ht(&ar->hw->conf))
+ new_ht |= CARL9170FW_PHY_HT_ENABLE;
+
+ if (conf_is_ht40(&ar->hw->conf))
+ new_ht |= CARL9170FW_PHY_HT_DYN2040;
+
+ /* may be NULL at first setup */
+ if (ar->channel) {
+ old_channel = ar->channel;
+ warm_reset = (old_channel->band != channel->band) ||
+ (old_channel->center_freq ==
+ channel->center_freq) ||
+ (ar->ht_settings != new_ht);
+
+ ar->channel = NULL;
+ } else {
+ warm_reset = true;
+ }
+
+ /* HW workaround */
+ if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
+ channel->center_freq <= 2417)
+ warm_reset = true;
+
+ if (rfi != CARL9170_RFI_NONE || warm_reset) {
+ u32 val;
+
+ if (rfi == CARL9170_RFI_COLD)
+ val = AR9170_PWR_RESET_BB_COLD_RESET;
+ else
+ val = AR9170_PWR_RESET_BB_WARM_RESET;
+
+ /* warm/cold reset BB/ADDA */
+ err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, val);
+ if (err)
+ return err;
+
+ err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0);
+ if (err)
+ return err;
+
+ err = carl9170_init_phy(ar, channel->band);
+ if (err)
+ return err;
+
+ err = carl9170_init_rf_banks_0_7(ar,
+ channel->band == IEEE80211_BAND_5GHZ);
+ if (err)
+ return err;
+
+ cmd = CARL9170_CMD_RF_INIT;
+
+ msleep(100);
+
+ err = carl9170_echo_test(ar, 0xaabbccdd);
+ if (err)
+ return err;
+ } else {
+ cmd = CARL9170_CMD_FREQUENCY;
+ }
+
+ err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL);
+ if (err)
+ return err;
+
+ err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE,
+ 0x200);
+
+ err = carl9170_init_rf_bank4_pwr(ar,
+ channel->band == IEEE80211_BAND_5GHZ,
+ channel->center_freq, bw);
+ if (err)
+ return err;
+
+ tmp = AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 |
+ AR9170_PHY_TURBO_FC_HT_EN;
+
+ switch (bw) {
+ case CARL9170_BW_20:
+ break;
+ case CARL9170_BW_40_BELOW:
+ tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN |
+ AR9170_PHY_TURBO_FC_SHORT_GI_40;
+ offs = 3;
+ break;
+ case CARL9170_BW_40_ABOVE:
+ tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN |
+ AR9170_PHY_TURBO_FC_SHORT_GI_40 |
+ AR9170_PHY_TURBO_FC_DYN2040_PRI_CH;
+ offs = 1;
+ break;
+ default:
+ BUG();
+ return -ENOSYS;
+ }
+
+ if (ar->eeprom.tx_mask != 1)
+ tmp |= AR9170_PHY_TURBO_FC_WALSH;
+
+ err = carl9170_write_reg(ar, AR9170_PHY_REG_TURBO, tmp);
+ if (err)
+ return err;
+
+ err = carl9170_set_freq_cal_data(ar, channel);
+ if (err)
+ return err;
+
+ err = carl9170_set_power_cal(ar, channel->center_freq, bw);
+ if (err)
+ return err;
+
+ freqpar = carl9170_get_hw_dyn_params(channel, bw);
+
+ rf.ht_settings = new_ht;
+ if (conf_is_ht40(&ar->hw->conf))
+ SET_VAL(CARL9170FW_PHY_HT_EXT_CHAN_OFF, rf.ht_settings, offs);
+
+ rf.freq = cpu_to_le32(channel->center_freq * 1000);
+ rf.delta_slope_coeff_exp = cpu_to_le32(freqpar->coeff_exp);
+ rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man);
+ rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi);
+ rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi);
+
+ if (rfi != CARL9170_RFI_NONE)
+ rf.finiteLoopCount = cpu_to_le32(2000);
+ else
+ rf.finiteLoopCount = cpu_to_le32(1000);
+
+ err = carl9170_exec_cmd(ar, cmd, sizeof(rf), &rf,
+ sizeof(rf_res), &rf_res);
+ if (err)
+ return err;
+
+ err = le32_to_cpu(rf_res.ret);
+ if (err != 0) {
+ ar->chan_fail++;
+ ar->total_chan_fail++;
+
+ wiphy_err(ar->hw->wiphy, "channel change: %d -> %d "
+ "failed (%d).\n", old_channel ?
+ old_channel->center_freq : -1, channel->center_freq,
+ err);
+
+ if ((rfi == CARL9170_RFI_COLD) || (ar->chan_fail > 3)) {
+ /*
+ * We have tried very hard to change to _another_
+ * channel and we've failed to do so!
+ * Chances are that the PHY/RF is no longer
+ * operable (due to corruptions/fatal events/bugs?)
+ * and we need to reset at a higher level.
+ */
+ carl9170_restart(ar, CARL9170_RR_TOO_MANY_PHY_ERRORS);
+ return 0;
+ }
+
+ err = carl9170_set_channel(ar, channel, _bw,
+ CARL9170_RFI_COLD);
+ if (err)
+ return err;
+ } else {
+ ar->chan_fail = 0;
+ }
+
+ err = carl9170_get_noisefloor(ar);
+ if (err)
+ return err;
+
+ if (ar->heavy_clip) {
+ err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE,
+ 0x200 | ar->heavy_clip);
+ if (err) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "failed to set "
+ "heavy clip\n");
+ }
+
+ return err;
+ }
+ }
+
+ /* FIXME: PSM does not work in 5GHz Band */
+ if (channel->band == IEEE80211_BAND_5GHZ)
+ ar->ps.off_override |= PS_OFF_5GHZ;
+ else
+ ar->ps.off_override &= ~PS_OFF_5GHZ;
+
+ ar->channel = channel;
+ ar->ht_settings = new_ht;
+ return 0;
+}
diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h
new file mode 100644
index 000000000000..02c34eb4ebde
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/phy.h
@@ -0,0 +1,564 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * PHY register map
+ *
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __CARL9170_SHARED_PHY_H
+#define __CARL9170_SHARED_PHY_H
+
+#define AR9170_PHY_REG_BASE (0x1bc000 + 0x9800)
+#define AR9170_PHY_REG(_n) (AR9170_PHY_REG_BASE + \
+ ((_n) << 2))
+
+#define AR9170_PHY_REG_TEST (AR9170_PHY_REG_BASE + 0x0000)
+#define AR9170_PHY_TEST_AGC_CLR 0x10000000
+#define AR9170_PHY_TEST_RFSILENT_BB 0x00002000
+
+#define AR9170_PHY_REG_TURBO (AR9170_PHY_REG_BASE + 0x0004)
+#define AR9170_PHY_TURBO_FC_TURBO_MODE 0x00000001
+#define AR9170_PHY_TURBO_FC_TURBO_SHORT 0x00000002
+#define AR9170_PHY_TURBO_FC_DYN2040_EN 0x00000004
+#define AR9170_PHY_TURBO_FC_DYN2040_PRI_ONLY 0x00000008
+#define AR9170_PHY_TURBO_FC_DYN2040_PRI_CH 0x00000010
+/* For 25 MHz channel spacing -- not used but supported by hw */
+#define AR9170_PHY_TURBO_FC_DYN2040_EXT_CH 0x00000020
+#define AR9170_PHY_TURBO_FC_HT_EN 0x00000040
+#define AR9170_PHY_TURBO_FC_SHORT_GI_40 0x00000080
+#define AR9170_PHY_TURBO_FC_WALSH 0x00000100
+#define AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 0x00000200
+#define AR9170_PHY_TURBO_FC_ENABLE_DAC_FIFO 0x00000800
+
+#define AR9170_PHY_REG_TEST2 (AR9170_PHY_REG_BASE + 0x0008)
+
+#define AR9170_PHY_REG_TIMING2 (AR9170_PHY_REG_BASE + 0x0010)
+#define AR9170_PHY_TIMING2_USE_FORCE 0x00001000
+#define AR9170_PHY_TIMING2_FORCE 0x00000fff
+#define AR9170_PHY_TIMING2_FORCE_S 0
+
+#define AR9170_PHY_REG_TIMING3 (AR9170_PHY_REG_BASE + 0x0014)
+#define AR9170_PHY_TIMING3_DSC_EXP 0x0001e000
+#define AR9170_PHY_TIMING3_DSC_EXP_S 13
+#define AR9170_PHY_TIMING3_DSC_MAN 0xfffe0000
+#define AR9170_PHY_TIMING3_DSC_MAN_S 17
+
+#define AR9170_PHY_REG_CHIP_ID (AR9170_PHY_REG_BASE + 0x0018)
+#define AR9170_PHY_CHIP_ID_REV_0 0x80
+#define AR9170_PHY_CHIP_ID_REV_1 0x81
+#define AR9170_PHY_CHIP_ID_9160_REV_0 0xb0
+
+#define AR9170_PHY_REG_ACTIVE (AR9170_PHY_REG_BASE + 0x001c)
+#define AR9170_PHY_ACTIVE_EN 0x00000001
+#define AR9170_PHY_ACTIVE_DIS 0x00000000
+
+#define AR9170_PHY_REG_RF_CTL2 (AR9170_PHY_REG_BASE + 0x0024)
+#define AR9170_PHY_RF_CTL2_TX_END_DATA_START 0x000000ff
+#define AR9170_PHY_RF_CTL2_TX_END_DATA_START_S 0
+#define AR9170_PHY_RF_CTL2_TX_END_PA_ON 0x0000ff00
+#define AR9170_PHY_RF_CTL2_TX_END_PA_ON_S 8
+
+#define AR9170_PHY_REG_RF_CTL3 (AR9170_PHY_REG_BASE + 0x0028)
+#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON 0x00ff0000
+#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON_S 16
+
+#define AR9170_PHY_REG_ADC_CTL (AR9170_PHY_REG_BASE + 0x002c)
+#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003
+#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN_S 0
+#define AR9170_PHY_ADC_CTL_OFF_PWDDAC 0x00002000
+#define AR9170_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000
+#define AR9170_PHY_ADC_CTL_OFF_PWDADC 0x00008000
+#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000
+#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN_S 16
+
+#define AR9170_PHY_REG_ADC_SERIAL_CTL (AR9170_PHY_REG_BASE + 0x0030)
+#define AR9170_PHY_ADC_SCTL_SEL_INTERNAL_ADDAC 0x00000000
+#define AR9170_PHY_ADC_SCTL_SEL_EXTERNAL_RADIO 0x00000001
+
+#define AR9170_PHY_REG_RF_CTL4 (AR9170_PHY_REG_BASE + 0x0034)
+#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF 0xff000000
+#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24
+#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00ff0000
+#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16
+#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000ff00
+#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON_S 8
+#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000ff
+#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
+
+#define AR9170_PHY_REG_TSTDAC_CONST (AR9170_PHY_REG_BASE + 0x003c)
+
+#define AR9170_PHY_REG_SETTLING (AR9170_PHY_REG_BASE + 0x0044)
+#define AR9170_PHY_SETTLING_SWITCH 0x00003f80
+#define AR9170_PHY_SETTLING_SWITCH_S 7
+
+#define AR9170_PHY_REG_RXGAIN (AR9170_PHY_REG_BASE + 0x0048)
+#define AR9170_PHY_REG_RXGAIN_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2048)
+#define AR9170_PHY_RXGAIN_TXRX_ATTEN 0x0003f000
+#define AR9170_PHY_RXGAIN_TXRX_ATTEN_S 12
+#define AR9170_PHY_RXGAIN_TXRX_RF_MAX 0x007c0000
+#define AR9170_PHY_RXGAIN_TXRX_RF_MAX_S 18
+
+#define AR9170_PHY_REG_DESIRED_SZ (AR9170_PHY_REG_BASE + 0x0050)
+#define AR9170_PHY_DESIRED_SZ_ADC 0x000000ff
+#define AR9170_PHY_DESIRED_SZ_ADC_S 0
+#define AR9170_PHY_DESIRED_SZ_PGA 0x0000ff00
+#define AR9170_PHY_DESIRED_SZ_PGA_S 8
+#define AR9170_PHY_DESIRED_SZ_TOT_DES 0x0ff00000
+#define AR9170_PHY_DESIRED_SZ_TOT_DES_S 20
+
+#define AR9170_PHY_REG_FIND_SIG (AR9170_PHY_REG_BASE + 0x0058)
+#define AR9170_PHY_FIND_SIG_FIRSTEP 0x0003f000
+#define AR9170_PHY_FIND_SIG_FIRSTEP_S 12
+#define AR9170_PHY_FIND_SIG_FIRPWR 0x03fc0000
+#define AR9170_PHY_FIND_SIG_FIRPWR_S 18
+
+#define AR9170_PHY_REG_AGC_CTL1 (AR9170_PHY_REG_BASE + 0x005c)
+#define AR9170_PHY_AGC_CTL1_COARSE_LOW 0x00007f80
+#define AR9170_PHY_AGC_CTL1_COARSE_LOW_S 7
+#define AR9170_PHY_AGC_CTL1_COARSE_HIGH 0x003f8000
+#define AR9170_PHY_AGC_CTL1_COARSE_HIGH_S 15
+
+#define AR9170_PHY_REG_AGC_CONTROL (AR9170_PHY_REG_BASE + 0x0060)
+#define AR9170_PHY_AGC_CONTROL_CAL 0x00000001
+#define AR9170_PHY_AGC_CONTROL_NF 0x00000002
+#define AR9170_PHY_AGC_CONTROL_ENABLE_NF 0x00008000
+#define AR9170_PHY_AGC_CONTROL_FLTR_CAL 0x00010000
+#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
+
+#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064)
+#define AR9170_PHY_CCA_MINCCA_PWR 0x0ff80000
+#define AR9170_PHY_CCA_MINCCA_PWR_S 19
+#define AR9170_PHY_CCA_THRESH62 0x0007f000
+#define AR9170_PHY_CCA_THRESH62_S 12
+
+#define AR9170_PHY_REG_SFCORR (AR9170_PHY_REG_BASE + 0x0068)
+#define AR9170_PHY_SFCORR_M2COUNT_THR 0x0000001f
+#define AR9170_PHY_SFCORR_M2COUNT_THR_S 0
+#define AR9170_PHY_SFCORR_M1_THRESH 0x00fe0000
+#define AR9170_PHY_SFCORR_M1_THRESH_S 17
+#define AR9170_PHY_SFCORR_M2_THRESH 0x7f000000
+#define AR9170_PHY_SFCORR_M2_THRESH_S 24
+
+#define AR9170_PHY_REG_SFCORR_LOW (AR9170_PHY_REG_BASE + 0x006c)
+#define AR9170_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
+#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003f00
+#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
+#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001fc000
+#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
+#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0fe00000
+#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
+
+#define AR9170_PHY_REG_SLEEP_CTR_CONTROL (AR9170_PHY_REG_BASE + 0x0070)
+#define AR9170_PHY_REG_SLEEP_CTR_LIMIT (AR9170_PHY_REG_BASE + 0x0074)
+#define AR9170_PHY_REG_SLEEP_SCAL (AR9170_PHY_REG_BASE + 0x0078)
+
+#define AR9170_PHY_REG_PLL_CTL (AR9170_PHY_REG_BASE + 0x007c)
+#define AR9170_PHY_PLL_CTL_40 0xaa
+#define AR9170_PHY_PLL_CTL_40_5413 0x04
+#define AR9170_PHY_PLL_CTL_44 0xab
+#define AR9170_PHY_PLL_CTL_44_2133 0xeb
+#define AR9170_PHY_PLL_CTL_40_2133 0xea
+
+#define AR9170_PHY_REG_BIN_MASK_1 (AR9170_PHY_REG_BASE + 0x0100)
+#define AR9170_PHY_REG_BIN_MASK_2 (AR9170_PHY_REG_BASE + 0x0104)
+#define AR9170_PHY_REG_BIN_MASK_3 (AR9170_PHY_REG_BASE + 0x0108)
+#define AR9170_PHY_REG_MASK_CTL (AR9170_PHY_REG_BASE + 0x010c)
+
+/* analogue power on time (100ns) */
+#define AR9170_PHY_REG_RX_DELAY (AR9170_PHY_REG_BASE + 0x0114)
+#define AR9170_PHY_REG_SEARCH_START_DELAY (AR9170_PHY_REG_BASE + 0x0118)
+#define AR9170_PHY_RX_DELAY_DELAY 0x00003fff
+
+#define AR9170_PHY_REG_TIMING_CTRL4(_i) (AR9170_PHY_REG_BASE + \
+ (0x0120 + ((_i) << 12)))
+#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01f
+#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0
+#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7e0
+#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5
+#define AR9170_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800
+#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xf000
+#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12
+#define AR9170_PHY_TIMING_CTRL4_DO_IQCAL 0x10000
+#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000
+#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000
+#define AR9170_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000
+#define AR9170_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000
+
+#define AR9170_PHY_REG_TIMING5 (AR9170_PHY_REG_BASE + 0x0124)
+#define AR9170_PHY_TIMING5_CYCPWR_THR1 0x000000fe
+#define AR9170_PHY_TIMING5_CYCPWR_THR1_S 1
+
+#define AR9170_PHY_REG_POWER_TX_RATE1 (AR9170_PHY_REG_BASE + 0x0134)
+#define AR9170_PHY_REG_POWER_TX_RATE2 (AR9170_PHY_REG_BASE + 0x0138)
+#define AR9170_PHY_REG_POWER_TX_RATE_MAX (AR9170_PHY_REG_BASE + 0x013c)
+#define AR9170_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
+
+#define AR9170_PHY_REG_FRAME_CTL (AR9170_PHY_REG_BASE + 0x0144)
+#define AR9170_PHY_FRAME_CTL_TX_CLIP 0x00000038
+#define AR9170_PHY_FRAME_CTL_TX_CLIP_S 3
+
+#define AR9170_PHY_REG_SPUR_REG (AR9170_PHY_REG_BASE + 0x014c)
+#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL (0xff << 18)
+#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
+#define AR9170_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000
+#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT (0xff << 9)
+#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT_S 9
+#define AR9170_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
+#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7f
+#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
+
+#define AR9170_PHY_REG_RADAR_EXT (AR9170_PHY_REG_BASE + 0x0140)
+#define AR9170_PHY_RADAR_EXT_ENA 0x00004000
+
+#define AR9170_PHY_REG_RADAR_0 (AR9170_PHY_REG_BASE + 0x0154)
+#define AR9170_PHY_RADAR_0_ENA 0x00000001
+#define AR9170_PHY_RADAR_0_FFT_ENA 0x80000000
+/* inband pulse threshold */
+#define AR9170_PHY_RADAR_0_INBAND 0x0000003e
+#define AR9170_PHY_RADAR_0_INBAND_S 1
+/* pulse RSSI threshold */
+#define AR9170_PHY_RADAR_0_PRSSI 0x00000fc0
+#define AR9170_PHY_RADAR_0_PRSSI_S 6
+/* pulse height threshold */
+#define AR9170_PHY_RADAR_0_HEIGHT 0x0003f000
+#define AR9170_PHY_RADAR_0_HEIGHT_S 12
+/* radar RSSI threshold */
+#define AR9170_PHY_RADAR_0_RRSSI 0x00fc0000
+#define AR9170_PHY_RADAR_0_RRSSI_S 18
+/* radar firepower threshold */
+#define AR9170_PHY_RADAR_0_FIRPWR 0x7f000000
+#define AR9170_PHY_RADAR_0_FIRPWR_S 24
+
+#define AR9170_PHY_REG_RADAR_1 (AR9170_PHY_REG_BASE + 0x0158)
+#define AR9170_PHY_RADAR_1_RELPWR_ENA 0x00800000
+#define AR9170_PHY_RADAR_1_USE_FIR128 0x00400000
+#define AR9170_PHY_RADAR_1_RELPWR_THRESH 0x003f0000
+#define AR9170_PHY_RADAR_1_RELPWR_THRESH_S 16
+#define AR9170_PHY_RADAR_1_BLOCK_CHECK 0x00008000
+#define AR9170_PHY_RADAR_1_MAX_RRSSI 0x00004000
+#define AR9170_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
+#define AR9170_PHY_RADAR_1_RELSTEP_THRESH 0x00001f00
+#define AR9170_PHY_RADAR_1_RELSTEP_THRESH_S 8
+#define AR9170_PHY_RADAR_1_MAXLEN 0x000000ff
+#define AR9170_PHY_RADAR_1_MAXLEN_S 0
+
+#define AR9170_PHY_REG_SWITCH_CHAIN_0 (AR9170_PHY_REG_BASE + 0x0160)
+#define AR9170_PHY_REG_SWITCH_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2160)
+
+#define AR9170_PHY_REG_SWITCH_COM (AR9170_PHY_REG_BASE + 0x0164)
+
+#define AR9170_PHY_REG_CCA_THRESHOLD (AR9170_PHY_REG_BASE + 0x0168)
+
+#define AR9170_PHY_REG_SIGMA_DELTA (AR9170_PHY_REG_BASE + 0x016c)
+#define AR9170_PHY_SIGMA_DELTA_ADC_SEL 0x00000003
+#define AR9170_PHY_SIGMA_DELTA_ADC_SEL_S 0
+#define AR9170_PHY_SIGMA_DELTA_FILT2 0x000000f8
+#define AR9170_PHY_SIGMA_DELTA_FILT2_S 3
+#define AR9170_PHY_SIGMA_DELTA_FILT1 0x00001f00
+#define AR9170_PHY_SIGMA_DELTA_FILT1_S 8
+#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000
+#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP_S 13
+
+#define AR9170_PHY_REG_RESTART (AR9170_PHY_REG_BASE + 0x0170)
+#define AR9170_PHY_RESTART_DIV_GC 0x001c0000
+#define AR9170_PHY_RESTART_DIV_GC_S 18
+
+#define AR9170_PHY_REG_RFBUS_REQ (AR9170_PHY_REG_BASE + 0x017c)
+#define AR9170_PHY_RFBUS_REQ_EN 0x00000001
+
+#define AR9170_PHY_REG_TIMING7 (AR9170_PHY_REG_BASE + 0x0180)
+#define AR9170_PHY_REG_TIMING8 (AR9170_PHY_REG_BASE + 0x0184)
+#define AR9170_PHY_TIMING8_PILOT_MASK_2 0x000fffff
+#define AR9170_PHY_TIMING8_PILOT_MASK_2_S 0
+
+#define AR9170_PHY_REG_BIN_MASK2_1 (AR9170_PHY_REG_BASE + 0x0188)
+#define AR9170_PHY_REG_BIN_MASK2_2 (AR9170_PHY_REG_BASE + 0x018c)
+#define AR9170_PHY_REG_BIN_MASK2_3 (AR9170_PHY_REG_BASE + 0x0190)
+#define AR9170_PHY_REG_BIN_MASK2_4 (AR9170_PHY_REG_BASE + 0x0194)
+#define AR9170_PHY_BIN_MASK2_4_MASK_4 0x00003fff
+#define AR9170_PHY_BIN_MASK2_4_MASK_4_S 0
+
+#define AR9170_PHY_REG_TIMING9 (AR9170_PHY_REG_BASE + 0x0198)
+#define AR9170_PHY_REG_TIMING10 (AR9170_PHY_REG_BASE + 0x019c)
+#define AR9170_PHY_TIMING10_PILOT_MASK_2 0x000fffff
+#define AR9170_PHY_TIMING10_PILOT_MASK_2_S 0
+
+#define AR9170_PHY_REG_TIMING11 (AR9170_PHY_REG_BASE + 0x01a0)
+#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE 0x000fffff
+#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
+#define AR9170_PHY_TIMING11_SPUR_FREQ_SD 0x3ff00000
+#define AR9170_PHY_TIMING11_SPUR_FREQ_SD_S 20
+#define AR9170_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
+#define AR9170_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
+
+#define AR9170_PHY_REG_RX_CHAINMASK (AR9170_PHY_REG_BASE + 0x01a4)
+#define AR9170_PHY_REG_NEW_ADC_DC_GAIN_CORR(_i) (AR9170_PHY_REG_BASE + \
+ 0x01b4 + ((_i) << 12))
+#define AR9170_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
+#define AR9170_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
+
+#define AR9170_PHY_REG_MULTICHAIN_GAIN_CTL (AR9170_PHY_REG_BASE + 0x01ac)
+#define AR9170_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000
+#define AR9170_PHY_9285_ANT_DIV_CTL 0x01000000
+#define AR9170_PHY_9285_ANT_DIV_CTL_S 24
+#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000
+#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF_S 25
+#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000
+#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27
+#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000
+#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB_S 29
+#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000
+#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30
+#define AR9170_PHY_9285_ANT_DIV_LNA1 2
+#define AR9170_PHY_9285_ANT_DIV_LNA2 1
+#define AR9170_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3
+#define AR9170_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
+#define AR9170_PHY_9285_ANT_DIV_GAINTB_0 0
+#define AR9170_PHY_9285_ANT_DIV_GAINTB_1 1
+
+#define AR9170_PHY_REG_EXT_CCA0 (AR9170_PHY_REG_BASE + 0x01b8)
+#define AR9170_PHY_REG_EXT_CCA0_THRESH62 0x000000ff
+#define AR9170_PHY_REG_EXT_CCA0_THRESH62_S 0
+
+#define AR9170_PHY_REG_EXT_CCA (AR9170_PHY_REG_BASE + 0x01bc)
+#define AR9170_PHY_EXT_CCA_CYCPWR_THR1 0x0000fe00
+#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9
+#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000
+#define AR9170_PHY_EXT_CCA_THRESH62_S 16
+#define AR9170_PHY_EXT_MINCCA_PWR 0xff800000
+#define AR9170_PHY_EXT_MINCCA_PWR_S 23
+
+#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0)
+#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f
+#define AR9170_PHY_SFCORR_EXT_M1_THRESH_S 0
+#define AR9170_PHY_SFCORR_EXT_M2_THRESH 0x00003f80
+#define AR9170_PHY_SFCORR_EXT_M2_THRESH_S 7
+#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001fc000
+#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
+#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0fe00000
+#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
+#define AR9170_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
+
+#define AR9170_PHY_REG_HALFGI (AR9170_PHY_REG_BASE + 0x01d0)
+#define AR9170_PHY_HALFGI_DSC_MAN 0x0007fff0
+#define AR9170_PHY_HALFGI_DSC_MAN_S 4
+#define AR9170_PHY_HALFGI_DSC_EXP 0x0000000f
+#define AR9170_PHY_HALFGI_DSC_EXP_S 0
+
+#define AR9170_PHY_REG_CHANNEL_MASK_01_30 (AR9170_PHY_REG_BASE + 0x01d4)
+#define AR9170_PHY_REG_CHANNEL_MASK_31_60 (AR9170_PHY_REG_BASE + 0x01d8)
+
+#define AR9170_PHY_REG_CHAN_INFO_MEMORY (AR9170_PHY_REG_BASE + 0x01dc)
+#define AR9170_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
+
+#define AR9170_PHY_REG_HEAVY_CLIP_ENABLE (AR9170_PHY_REG_BASE + 0x01e0)
+#define AR9170_PHY_REG_HEAVY_CLIP_FACTOR_RIFS (AR9170_PHY_REG_BASE + 0x01ec)
+#define AR9170_PHY_RIFS_INIT_DELAY 0x03ff0000
+
+#define AR9170_PHY_REG_CALMODE (AR9170_PHY_REG_BASE + 0x01f0)
+#define AR9170_PHY_CALMODE_IQ 0x00000000
+#define AR9170_PHY_CALMODE_ADC_GAIN 0x00000001
+#define AR9170_PHY_CALMODE_ADC_DC_PER 0x00000002
+#define AR9170_PHY_CALMODE_ADC_DC_INIT 0x00000003
+
+#define AR9170_PHY_REG_REFCLKDLY (AR9170_PHY_REG_BASE + 0x01f4)
+#define AR9170_PHY_REG_REFCLKPD (AR9170_PHY_REG_BASE + 0x01f8)
+
+
+#define AR9170_PHY_REG_CAL_MEAS_0(_i) (AR9170_PHY_REG_BASE + \
+ 0x0410 + ((_i) << 12))
+#define AR9170_PHY_REG_CAL_MEAS_1(_i) (AR9170_PHY_REG_BASE + \
+ 0x0414 \ + ((_i) << 12))
+#define AR9170_PHY_REG_CAL_MEAS_2(_i) (AR9170_PHY_REG_BASE + \
+ 0x0418 + ((_i) << 12))
+#define AR9170_PHY_REG_CAL_MEAS_3(_i) (AR9170_PHY_REG_BASE + \
+ 0x041c + ((_i) << 12))
+
+#define AR9170_PHY_REG_CURRENT_RSSI (AR9170_PHY_REG_BASE + 0x041c)
+
+#define AR9170_PHY_REG_RFBUS_GRANT (AR9170_PHY_REG_BASE + 0x0420)
+#define AR9170_PHY_RFBUS_GRANT_EN 0x00000001
+
+#define AR9170_PHY_REG_CHAN_INFO_GAIN_DIFF (AR9170_PHY_REG_BASE + 0x04f4)
+#define AR9170_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
+
+#define AR9170_PHY_REG_CHAN_INFO_GAIN (AR9170_PHY_REG_BASE + 0x04fc)
+
+#define AR9170_PHY_REG_MODE (AR9170_PHY_REG_BASE + 0x0a00)
+#define AR9170_PHY_MODE_ASYNCFIFO 0x80
+#define AR9170_PHY_MODE_AR2133 0x08
+#define AR9170_PHY_MODE_AR5111 0x00
+#define AR9170_PHY_MODE_AR5112 0x08
+#define AR9170_PHY_MODE_DYNAMIC 0x04
+#define AR9170_PHY_MODE_RF2GHZ 0x02
+#define AR9170_PHY_MODE_RF5GHZ 0x00
+#define AR9170_PHY_MODE_CCK 0x01
+#define AR9170_PHY_MODE_OFDM 0x00
+#define AR9170_PHY_MODE_DYN_CCK_DISABLE 0x100
+
+#define AR9170_PHY_REG_CCK_TX_CTRL (AR9170_PHY_REG_BASE + 0x0a04)
+#define AR9170_PHY_CCK_TX_CTRL_JAPAN 0x00000010
+#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000c
+#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2
+
+#define AR9170_PHY_REG_CCK_DETECT (AR9170_PHY_REG_BASE + 0x0a08)
+#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003f
+#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
+/* [12:6] settling time for antenna switch */
+#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001fc0
+#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
+#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
+#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
+
+#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c)
+#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c)
+#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000
+#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
+#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00
+#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN_S 10
+#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001f
+#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN_S 0
+#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003e0000
+#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17
+#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001f000
+#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12
+#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000fc0
+#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB_S 6
+#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003f
+#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB_S 0
+
+#define AR9170_PHY_REG_CCK_RXCTRL4 (AR9170_PHY_REG_BASE + 0x0a1c)
+#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01f80000
+#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
+
+#define AR9170_PHY_REG_DAG_CTRLCCK (AR9170_PHY_REG_BASE + 0x0a28)
+#define AR9170_REG_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
+#define AR9170_REG_DAG_CTRLCCK_RSSI_THR 0x0001fc00
+#define AR9170_REG_DAG_CTRLCCK_RSSI_THR_S 10
+
+#define AR9170_PHY_REG_FORCE_CLKEN_CCK (AR9170_PHY_REG_BASE + 0x0a2c)
+#define AR9170_FORCE_CLKEN_CCK_MRC_MUX 0x00000040
+
+#define AR9170_PHY_REG_POWER_TX_RATE3 (AR9170_PHY_REG_BASE + 0x0a34)
+#define AR9170_PHY_REG_POWER_TX_RATE4 (AR9170_PHY_REG_BASE + 0x0a38)
+
+#define AR9170_PHY_REG_SCRM_SEQ_XR (AR9170_PHY_REG_BASE + 0x0a3c)
+#define AR9170_PHY_REG_HEADER_DETECT_XR (AR9170_PHY_REG_BASE + 0x0a40)
+#define AR9170_PHY_REG_CHIRP_DETECTED_XR (AR9170_PHY_REG_BASE + 0x0a44)
+#define AR9170_PHY_REG_BLUETOOTH (AR9170_PHY_REG_BASE + 0x0a54)
+
+#define AR9170_PHY_REG_TPCRG1 (AR9170_PHY_REG_BASE + 0x0a58)
+#define AR9170_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
+#define AR9170_PHY_TPCRG1_NUM_PD_GAIN_S 14
+#define AR9170_PHY_TPCRG1_PD_GAIN_1 0x00030000
+#define AR9170_PHY_TPCRG1_PD_GAIN_1_S 16
+#define AR9170_PHY_TPCRG1_PD_GAIN_2 0x000c0000
+#define AR9170_PHY_TPCRG1_PD_GAIN_2_S 18
+#define AR9170_PHY_TPCRG1_PD_GAIN_3 0x00300000
+#define AR9170_PHY_TPCRG1_PD_GAIN_3_S 20
+#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
+#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR9170_PHY_REG_TX_PWRCTRL4 (AR9170_PHY_REG_BASE + 0x0a64)
+#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
+#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0
+#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001fe
+#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1
+
+#define AR9170_PHY_REG_ANALOG_SWAP (AR9170_PHY_REG_BASE + 0x0a68)
+#define AR9170_PHY_ANALOG_SWAP_AB 0x0001
+#define AR9170_PHY_ANALOG_SWAP_ALT_CHAIN 0x00000040
+
+#define AR9170_PHY_REG_TPCRG5 (AR9170_PHY_REG_BASE + 0x0a6c)
+#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000f
+#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003f0
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000fc00
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003f0000
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0fc00000
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
+
+#define AR9170_PHY_REG_TX_PWRCTRL6_0 (AR9170_PHY_REG_BASE + 0x0a70)
+#define AR9170_PHY_REG_TX_PWRCTRL6_1 (AR9170_PHY_REG_BASE + 0x1a70)
+#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000
+#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24
+
+#define AR9170_PHY_REG_TX_PWRCTRL7 (AR9170_PHY_REG_BASE + 0x0a74)
+#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01f80000
+#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
+
+#define AR9170_PHY_REG_TX_PWRCTRL9 (AR9170_PHY_REG_BASE + 0x0a7c)
+#define AR9170_PHY_TX_DESIRED_SCALE_CCK 0x00007c00
+#define AR9170_PHY_TX_DESIRED_SCALE_CCK_S 10
+#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
+#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
+
+#define AR9170_PHY_REG_TX_GAIN_TBL1 (AR9170_PHY_REG_BASE + 0x0b00)
+#define AR9170_PHY_TX_GAIN 0x0007f000
+#define AR9170_PHY_TX_GAIN_S 12
+
+/* Carrier leak calibration control, do it after AGC calibration */
+#define AR9170_PHY_REG_CL_CAL_CTL (AR9170_PHY_REG_BASE + 0x0b58)
+#define AR9170_PHY_CL_CAL_ENABLE 0x00000002
+#define AR9170_PHY_CL_CAL_PARALLEL_CAL_ENABLE 0x00000001
+
+#define AR9170_PHY_REG_POWER_TX_RATE5 (AR9170_PHY_REG_BASE + 0x0b8c)
+#define AR9170_PHY_REG_POWER_TX_RATE6 (AR9170_PHY_REG_BASE + 0x0b90)
+
+#define AR9170_PHY_REG_CH0_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x0b98)
+#define AR9170_PHY_REG_CH1_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x1b98)
+#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP 0x0000fc00
+#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP_S 10
+
+#define AR9170_PHY_REG_CAL_CHAINMASK (AR9170_PHY_REG_BASE + 0x0b9c)
+#define AR9170_PHY_REG_VIT_MASK2_M_46_61 (AR9170_PHY_REG_BASE + 0x0ba0)
+#define AR9170_PHY_REG_MASK2_M_31_45 (AR9170_PHY_REG_BASE + 0x0ba4)
+#define AR9170_PHY_REG_MASK2_M_16_30 (AR9170_PHY_REG_BASE + 0x0ba8)
+#define AR9170_PHY_REG_MASK2_M_00_15 (AR9170_PHY_REG_BASE + 0x0bac)
+#define AR9170_PHY_REG_PILOT_MASK_01_30 (AR9170_PHY_REG_BASE + 0x0bb0)
+#define AR9170_PHY_REG_PILOT_MASK_31_60 (AR9170_PHY_REG_BASE + 0x0bb4)
+#define AR9170_PHY_REG_MASK2_P_15_01 (AR9170_PHY_REG_BASE + 0x0bb8)
+#define AR9170_PHY_REG_MASK2_P_30_16 (AR9170_PHY_REG_BASE + 0x0bbc)
+#define AR9170_PHY_REG_MASK2_P_45_31 (AR9170_PHY_REG_BASE + 0x0bc0)
+#define AR9170_PHY_REG_MASK2_P_61_45 (AR9170_PHY_REG_BASE + 0x0bc4)
+#define AR9170_PHY_REG_POWER_TX_SUB (AR9170_PHY_REG_BASE + 0x0bc8)
+#define AR9170_PHY_REG_POWER_TX_RATE7 (AR9170_PHY_REG_BASE + 0x0bcc)
+#define AR9170_PHY_REG_POWER_TX_RATE8 (AR9170_PHY_REG_BASE + 0x0bd0)
+#define AR9170_PHY_REG_POWER_TX_RATE9 (AR9170_PHY_REG_BASE + 0x0bd4)
+#define AR9170_PHY_REG_XPA_CFG (AR9170_PHY_REG_BASE + 0x0bd8)
+#define AR9170_PHY_FORCE_XPA_CFG 0x000000001
+#define AR9170_PHY_FORCE_XPA_CFG_S 0
+
+#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064)
+#define AR9170_PHY_CH1_MINCCA_PWR 0x0ff80000
+#define AR9170_PHY_CH1_MINCCA_PWR_S 19
+
+#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064)
+#define AR9170_PHY_CH2_MINCCA_PWR 0x0ff80000
+#define AR9170_PHY_CH2_MINCCA_PWR_S 19
+
+#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc)
+#define AR9170_PHY_CH1_EXT_MINCCA_PWR 0xff800000
+#define AR9170_PHY_CH1_EXT_MINCCA_PWR_S 23
+
+#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc)
+#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000
+#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23
+
+#endif /* __CARL9170_SHARED_PHY_H */
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
new file mode 100644
index 000000000000..939a0e96ed1f
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -0,0 +1,938 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * 802.11 & command trap routines
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/crc32.h>
+#include <net/mac80211.h>
+#include "carl9170.h"
+#include "hw.h"
+#include "cmd.h"
+
+static void carl9170_dbg_message(struct ar9170 *ar, const char *buf, u32 len)
+{
+ bool restart = false;
+ enum carl9170_restart_reasons reason = CARL9170_RR_NO_REASON;
+
+ if (len > 3) {
+ if (memcmp(buf, CARL9170_ERR_MAGIC, 3) == 0) {
+ ar->fw.err_counter++;
+ if (ar->fw.err_counter > 3) {
+ restart = true;
+ reason = CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS;
+ }
+ }
+
+ if (memcmp(buf, CARL9170_BUG_MAGIC, 3) == 0) {
+ ar->fw.bug_counter++;
+ restart = true;
+ reason = CARL9170_RR_FATAL_FIRMWARE_ERROR;
+ }
+ }
+
+ wiphy_info(ar->hw->wiphy, "FW: %.*s\n", len, buf);
+
+ if (restart)
+ carl9170_restart(ar, reason);
+}
+
+static void carl9170_handle_ps(struct ar9170 *ar, struct carl9170_rsp *rsp)
+{
+ u32 ps;
+ bool new_ps;
+
+ ps = le32_to_cpu(rsp->psm.state);
+
+ new_ps = (ps & CARL9170_PSM_COUNTER) != CARL9170_PSM_WAKE;
+ if (ar->ps.state != new_ps) {
+ if (!new_ps) {
+ ar->ps.sleep_ms = jiffies_to_msecs(jiffies -
+ ar->ps.last_action);
+ }
+
+ ar->ps.last_action = jiffies;
+
+ ar->ps.state = new_ps;
+ }
+}
+
+static int carl9170_check_sequence(struct ar9170 *ar, unsigned int seq)
+{
+ if (ar->cmd_seq < -1)
+ return 0;
+
+ /*
+ * Initialize Counter
+ */
+ if (ar->cmd_seq < 0)
+ ar->cmd_seq = seq;
+
+ /*
+ * The sequence is strictly monotonic increasing and it never skips!
+ *
+ * Therefore we can safely assume that whenever we received an
+ * unexpected sequence we have lost some valuable data.
+ */
+ if (seq != ar->cmd_seq) {
+ int count;
+
+ count = (seq - ar->cmd_seq) % ar->fw.cmd_bufs;
+
+ wiphy_err(ar->hw->wiphy, "lost %d command responses/traps! "
+ "w:%d g:%d\n", count, ar->cmd_seq, seq);
+
+ carl9170_restart(ar, CARL9170_RR_LOST_RSP);
+ return -EIO;
+ }
+
+ ar->cmd_seq = (ar->cmd_seq + 1) % ar->fw.cmd_bufs;
+ return 0;
+}
+
+static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)
+{
+ /*
+ * Some commands may 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(ar->readlen != (len - 4))) {
+ dev_warn(&ar->udev->dev, "received invalid command response:"
+ "got %d, instead of %d\n", len - 4, ar->readlen);
+ print_hex_dump_bytes("carl9170 cmd:", DUMP_PREFIX_OFFSET,
+ ar->cmd_buf, (ar->cmd.hdr.len + 4) & 0x3f);
+ print_hex_dump_bytes("carl9170 rsp:", DUMP_PREFIX_OFFSET,
+ buffer, len);
+ /*
+ * Do not complete. The command times out,
+ * and we get a stack trace from there.
+ */
+ carl9170_restart(ar, CARL9170_RR_INVALID_RSP);
+ }
+
+ spin_lock(&ar->cmd_lock);
+ if (ar->readbuf) {
+ if (len >= 4)
+ memcpy(ar->readbuf, buffer + 4, len - 4);
+
+ ar->readbuf = NULL;
+ }
+ complete(&ar->cmd_wait);
+ spin_unlock(&ar->cmd_lock);
+}
+
+void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
+{
+ struct carl9170_rsp *cmd = (void *) buf;
+ struct ieee80211_vif *vif;
+
+ if (carl9170_check_sequence(ar, cmd->hdr.seq))
+ return;
+
+ if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) {
+ if (!(cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG))
+ carl9170_cmd_callback(ar, len, buf);
+
+ return;
+ }
+
+ if (unlikely(cmd->hdr.len != (len - 4))) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "FW: received over-/under"
+ "sized event %x (%d, but should be %d).\n",
+ cmd->hdr.cmd, cmd->hdr.len, len - 4);
+
+ print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE,
+ buf, len);
+ }
+
+ return;
+ }
+
+ /* hardware event handlers */
+ switch (cmd->hdr.cmd) {
+ case CARL9170_RSP_PRETBTT:
+ /* pre-TBTT event */
+ rcu_read_lock();
+ vif = carl9170_get_main_vif(ar);
+
+ if (!vif) {
+ rcu_read_unlock();
+ break;
+ }
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ carl9170_handle_ps(ar, cmd);
+ break;
+
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_ADHOC:
+ carl9170_update_beacon(ar, true);
+ break;
+
+ default:
+ break;
+ }
+ rcu_read_unlock();
+
+ break;
+
+
+ case CARL9170_RSP_TXCOMP:
+ /* TX status notification */
+ carl9170_tx_process_status(ar, cmd);
+ break;
+
+ case CARL9170_RSP_BEACON_CONFIG:
+ /*
+ * (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 CARL9170_RSP_ATIM:
+ /* End of Atim Window */
+ break;
+
+ case CARL9170_RSP_WATCHDOG:
+ /* Watchdog Interrupt */
+ carl9170_restart(ar, CARL9170_RR_WATCHDOG);
+ break;
+
+ case CARL9170_RSP_TEXT:
+ /* firmware debug */
+ carl9170_dbg_message(ar, (char *)buf + 4, len - 4);
+ break;
+
+ case CARL9170_RSP_HEXDUMP:
+ wiphy_dbg(ar->hw->wiphy, "FW: HD %d\n", len - 4);
+ print_hex_dump_bytes("FW:", DUMP_PREFIX_NONE,
+ (char *)buf + 4, len - 4);
+ break;
+
+ case CARL9170_RSP_RADAR:
+ if (!net_ratelimit())
+ break;
+
+ wiphy_info(ar->hw->wiphy, "FW: RADAR! Please report this "
+ "incident to linux-wireless@vger.kernel.org !\n");
+ break;
+
+ case CARL9170_RSP_GPIO:
+#ifdef CONFIG_CARL9170_WPC
+ if (ar->wps.pbc) {
+ bool state = !!(cmd->gpio.gpio & cpu_to_le32(
+ AR9170_GPIO_PORT_WPS_BUTTON_PRESSED));
+
+ if (state != ar->wps.pbc_state) {
+ ar->wps.pbc_state = state;
+ input_report_key(ar->wps.pbc, KEY_WPS_BUTTON,
+ state);
+ input_sync(ar->wps.pbc);
+ }
+ }
+#endif /* CONFIG_CARL9170_WPC */
+ break;
+
+ case CARL9170_RSP_BOOT:
+ complete(&ar->fw_boot_wait);
+ break;
+
+ default:
+ wiphy_err(ar->hw->wiphy, "FW: received unhandled event %x\n",
+ cmd->hdr.cmd);
+ print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
+ break;
+ }
+}
+
+static int carl9170_rx_mac_status(struct ar9170 *ar,
+ struct ar9170_rx_head *head, struct ar9170_rx_macstatus *mac,
+ struct ieee80211_rx_status *status)
+{
+ struct ieee80211_channel *chan;
+ 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_WRONG_RA) {
+ if (!ar->sniffer_enabled)
+ return -EINVAL;
+ }
+
+ if (error & AR9170_RX_ERROR_PLCP) {
+ if (!(ar->filter_state & FIF_PLCPFAIL))
+ return -EINVAL;
+
+ status->flag |= RX_FLAG_FAILED_PLCP_CRC;
+ }
+
+ if (error & AR9170_RX_ERROR_FCS) {
+ ar->tx_fcs_errors++;
+
+ if (!(ar->filter_state & FIF_FCSFAIL))
+ return -EINVAL;
+
+ status->flag |= RX_FLAG_FAILED_FCS_CRC;
+ }
+
+ decrypt = ar9170_get_decrypt_type(mac);
+ if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
+ decrypt != AR9170_ENC_ALG_NONE) {
+ if ((decrypt == AR9170_ENC_ALG_TKIP) &&
+ (error & AR9170_RX_ERROR_MMIC))
+ status->flag |= RX_FLAG_MMIC_ERROR;
+
+ status->flag |= RX_FLAG_DECRYPTED;
+ }
+
+ if (error & AR9170_RX_ERROR_DECRYPT && !ar->sniffer_enabled)
+ return -ENODATA;
+
+ error &= ~(AR9170_RX_ERROR_MMIC |
+ AR9170_RX_ERROR_FCS |
+ AR9170_RX_ERROR_WRONG_RA |
+ AR9170_RX_ERROR_DECRYPT |
+ AR9170_RX_ERROR_PLCP);
+
+ /* drop any other error frames */
+ if (unlikely(error)) {
+ /* TODO: update netdevice's RX dropped/errors statistics */
+
+ if (net_ratelimit())
+ wiphy_dbg(ar->hw->wiphy, "received frame with "
+ "suspicious error code (%#x).\n", error);
+
+ return -EINVAL;
+ }
+
+ chan = ar->channel;
+ if (chan) {
+ status->band = chan->band;
+ status->freq = chan->center_freq;
+ }
+
+ switch (mac->status & AR9170_RX_STATUS_MODULATION) {
+ case AR9170_RX_STATUS_MODULATION_CCK:
+ if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
+ status->flag |= RX_FLAG_SHORTPRE;
+ switch (head->plcp[0]) {
+ case AR9170_RX_PHY_RATE_CCK_1M:
+ status->rate_idx = 0;
+ break;
+ case AR9170_RX_PHY_RATE_CCK_2M:
+ status->rate_idx = 1;
+ break;
+ case AR9170_RX_PHY_RATE_CCK_5M:
+ status->rate_idx = 2;
+ break;
+ case AR9170_RX_PHY_RATE_CCK_11M:
+ status->rate_idx = 3;
+ break;
+ default:
+ if (net_ratelimit()) {
+ 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 AR9170_TXRX_PHY_RATE_OFDM_6M:
+ status->rate_idx = 0;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_9M:
+ status->rate_idx = 1;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_12M:
+ status->rate_idx = 2;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_18M:
+ status->rate_idx = 3;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_24M:
+ status->rate_idx = 4;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_36M:
+ status->rate_idx = 5;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_48M:
+ status->rate_idx = 6;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_54M:
+ status->rate_idx = 7;
+ break;
+ default:
+ if (net_ratelimit()) {
+ 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[3] & 0x7f);
+ status->flag |= RX_FLAG_HT;
+ break;
+
+ default:
+ BUG();
+ return -ENOSYS;
+ }
+
+ return 0;
+}
+
+static void carl9170_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 *carl9170_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;
+}
+
+static u8 *carl9170_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;
+}
+
+/*
+ * NOTE:
+ *
+ * The firmware is in charge of waking up the device just before
+ * the AP is expected to transmit the next beacon.
+ *
+ * This leaves the driver with the important task of deciding when
+ * to set the PHY back to bed again.
+ */
+static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
+{
+ struct ieee80211_hdr *hdr = (void *) data;
+ struct ieee80211_tim_ie *tim_ie;
+ u8 *tim;
+ u8 tim_len;
+ bool cam;
+
+ if (likely(!(ar->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, ar->common.curbssid) ||
+ !ar->common.curaid)
+ return;
+
+ ar->ps.last_beacon = jiffies;
+
+ tim = carl9170_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(!ar->hw->conf.ps_dtim_period))
+ ar->ps.dtim_counter = (tim_ie->dtim_count - 1) %
+ ar->hw->conf.ps_dtim_period;
+
+ /* 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, ar->common.curaid);
+
+ /* 2. Maybe the AP wants to send multicast/broadcast data? */
+ cam = !!(tim_ie->bitmap_ctrl & 0x01);
+
+ if (!cam) {
+ /* back to low-power land. */
+ ar->ps.off_override &= ~PS_OFF_BCN;
+ carl9170_ps_check(ar);
+ } else {
+ /* force CAM */
+ ar->ps.off_override |= PS_OFF_BCN;
+ }
+}
+
+static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms)
+{
+ __le16 fc;
+
+ if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE) {
+ /*
+ * This frame is not part of an aMPDU.
+ * Therefore it is not subjected to any
+ * of the following content restrictions.
+ */
+ return true;
+ }
+
+ /*
+ * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts
+ * certain frame types can be part of an aMPDU.
+ *
+ * In order to keep the processing cost down, I opted for a
+ * stateless filter solely based on the frame control field.
+ */
+
+ fc = ((struct ieee80211_hdr *)buf)->frame_control;
+ if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc))
+ return true;
+
+ if (ieee80211_is_ack(fc) || ieee80211_is_back(fc) ||
+ ieee80211_is_back_req(fc))
+ return true;
+
+ if (ieee80211_is_action(fc))
+ return true;
+
+ return false;
+}
+
+/*
+ * 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 carl9170_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;
+ u8 mac_status;
+
+ if (!IS_STARTED(ar))
+ return;
+
+ if (unlikely(len < sizeof(*mac)))
+ goto drop;
+
+ mpdu_len = len - sizeof(*mac);
+
+ mac = (void *)(buf + mpdu_len);
+ mac_status = mac->status;
+ switch (mac_status & AR9170_RX_STATUS_MPDU) {
+ case AR9170_RX_STATUS_MPDU_FIRST:
+ /* Aggregated MPDUs start with an PLCP header */
+ if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
+ head = (void *) buf;
+
+ /*
+ * The PLCP header needs to be cached for the
+ * following MIDDLE + LAST A-MPDU packets.
+ *
+ * So, if you are wondering why all frames seem
+ * to share a common RX status information,
+ * then you have the answer right here...
+ */
+ memcpy(&ar->rx_plcp, (void *) buf,
+ sizeof(struct ar9170_rx_head));
+
+ mpdu_len -= sizeof(struct ar9170_rx_head);
+ buf += sizeof(struct ar9170_rx_head);
+
+ ar->rx_has_plcp = true;
+ } else {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "plcp info "
+ "is clipped.\n");
+ }
+
+ goto drop;
+ }
+ break;
+
+ case AR9170_RX_STATUS_MPDU_LAST:
+ /*
+ * The last frame of an A-MPDU has an extra tail
+ * which does contain the phy status of the whole
+ * aggregate.
+ */
+
+ if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
+ mpdu_len -= sizeof(struct ar9170_rx_phystatus);
+ phy = (void *)(buf + mpdu_len);
+ } else {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "frame tail "
+ "is clipped.\n");
+ }
+
+ goto drop;
+ }
+
+ case AR9170_RX_STATUS_MPDU_MIDDLE:
+ /* These are just data + mac status */
+ if (unlikely(!ar->rx_has_plcp)) {
+ if (!net_ratelimit())
+ return;
+
+ wiphy_err(ar->hw->wiphy, "rx stream does not start "
+ "with a first_mpdu frame tag.\n");
+
+ goto drop;
+ }
+
+ head = &ar->rx_plcp;
+ break;
+
+ case AR9170_RX_STATUS_MPDU_SINGLE:
+ /* single mpdu has both: 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;
+ }
+
+ /* FC + DU + RA + FCS */
+ if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN)))
+ goto drop;
+
+ memset(&status, 0, sizeof(status));
+ if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status)))
+ goto drop;
+
+ if (!carl9170_ampdu_check(ar, buf, mac_status))
+ goto drop;
+
+ if (phy)
+ carl9170_rx_phy_status(ar, phy, &status);
+
+ carl9170_ps_beacon(ar, buf, mpdu_len);
+
+ skb = carl9170_rx_copy_data(buf, mpdu_len);
+ if (!skb)
+ goto drop;
+
+ memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+ ieee80211_rx(ar->hw, skb);
+ return;
+
+drop:
+ ar->rx_dropped++;
+}
+
+static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf,
+ const unsigned int resplen)
+{
+ struct carl9170_rsp *cmd;
+ int i = 0;
+
+ while (i < resplen) {
+ cmd = (void *) &respbuf[i];
+
+ i += cmd->hdr.len + 4;
+ if (unlikely(i > resplen))
+ break;
+
+ carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4);
+ }
+
+ if (unlikely(i != resplen)) {
+ if (!net_ratelimit())
+ return;
+
+ wiphy_err(ar->hw->wiphy, "malformed firmware trap:\n");
+ print_hex_dump_bytes("rxcmd:", DUMP_PREFIX_OFFSET,
+ respbuf, resplen);
+ }
+}
+
+static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len)
+{
+ unsigned int i = 0;
+
+ /* weird thing, but this is the same in the original driver */
+ while (len > 2 && i < 12 && buf[0] == 0xff && buf[1] == 0xff) {
+ i += 2;
+ len -= 2;
+ buf += 2;
+ }
+
+ if (unlikely(len < 4))
+ return;
+
+ /* found the 6 * 0xffff marker? */
+ if (i == 12)
+ carl9170_rx_untie_cmds(ar, buf, len);
+ else
+ carl9170_handle_mpdu(ar, buf, len);
+}
+
+static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len)
+{
+ unsigned int tlen, wlen = 0, clen = 0;
+ struct ar9170_stream *rx_stream;
+ u8 *tbuf;
+
+ tbuf = buf;
+ tlen = len;
+
+ while (tlen >= 4) {
+ rx_stream = (void *) tbuf;
+ clen = le16_to_cpu(rx_stream->length);
+ wlen = ALIGN(clen, 4);
+
+ /* check if this is stream has a valid tag.*/
+ if (rx_stream->tag != cpu_to_le16(AR9170_RX_STREAM_TAG)) {
+ /*
+ * 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 not "short read". */
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy,
+ "missing tag!\n");
+ }
+
+ __carl9170_rx(ar, tbuf, tlen);
+ return;
+ }
+
+ if (ar->rx_failover_missing > tlen) {
+ if (net_ratelimit()) {
+ 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 carl9170_rx_stream call!
+ *
+ * termination is guranteed, even when the
+ * combined frame also have an element with
+ * a bad tag.
+ */
+
+ ar->rx_failover_missing = 0;
+ carl9170_rx_stream(ar, ar->rx_failover->data,
+ ar->rx_failover->len);
+
+ 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 (net_ratelimit()) {
+ 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;
+ }
+ __carl9170_rx(ar, rx_stream->payload, clen);
+
+ tbuf += wlen + 4;
+ tlen -= wlen + 4;
+ }
+
+ 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,
+ buf, len);
+
+ wiphy_err(ar->hw->wiphy, "please check your hardware and cables, if "
+ "you see this message frequently.\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;
+ }
+}
+
+void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len)
+{
+ if (ar->fw.rx_stream)
+ carl9170_rx_stream(ar, buf, len);
+ else
+ __carl9170_rx(ar, buf, len);
+}
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
new file mode 100644
index 000000000000..b575c865142d
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -0,0 +1,1335 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * 802.11 xmit & status routines
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "carl9170.h"
+#include "hw.h"
+#include "cmd.h"
+
+static inline unsigned int __carl9170_get_queue(struct ar9170 *ar,
+ unsigned int queue)
+{
+ if (unlikely(modparam_noht)) {
+ return queue;
+ } else {
+ /*
+ * This is just another workaround, until
+ * someone figures out how to get QoS and
+ * AMPDU to play nicely together.
+ */
+
+ return 2; /* AC_BE */
+ }
+}
+
+static inline unsigned int carl9170_get_queue(struct ar9170 *ar,
+ struct sk_buff *skb)
+{
+ return __carl9170_get_queue(ar, skb_get_queue_mapping(skb));
+}
+
+static bool is_mem_full(struct ar9170 *ar)
+{
+ return (DIV_ROUND_UP(IEEE80211_MAX_FRAME_LEN, ar->fw.mem_block_size) >
+ atomic_read(&ar->mem_free_blocks));
+}
+
+static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb)
+{
+ int queue, i;
+ bool mem_full;
+
+ atomic_inc(&ar->tx_total_queued);
+
+ queue = skb_get_queue_mapping(skb);
+ spin_lock_bh(&ar->tx_stats_lock);
+
+ /*
+ * The driver has to accept the frame, regardless if the queue is
+ * full to the brim, or not. We have to do the queuing internally,
+ * since mac80211 assumes that a driver which can operate with
+ * aggregated frames does not reject frames for this reason.
+ */
+ ar->tx_stats[queue].len++;
+ ar->tx_stats[queue].count++;
+
+ mem_full = is_mem_full(ar);
+ for (i = 0; i < ar->hw->queues; i++) {
+ if (mem_full || ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
+ ieee80211_stop_queue(ar->hw, i);
+ ar->queue_stop_timeout[i] = jiffies;
+ }
+ }
+
+ spin_unlock_bh(&ar->tx_stats_lock);
+}
+
+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);
+
+ ar->tx_stats[queue].len--;
+
+ if (!is_mem_full(ar)) {
+ unsigned int i;
+ for (i = 0; i < ar->hw->queues; i++) {
+ if (ar->tx_stats[i].len >= CARL9170_NUM_TX_LIMIT_SOFT)
+ continue;
+
+ if (ieee80211_queue_stopped(ar->hw, i)) {
+ unsigned long tmp;
+
+ tmp = jiffies - ar->queue_stop_timeout[i];
+ if (tmp > ar->max_queue_stop_timeout[i])
+ ar->max_queue_stop_timeout[i] = tmp;
+ }
+
+ ieee80211_wake_queue(ar->hw, i);
+ }
+ }
+
+ spin_unlock_bh(&ar->tx_stats_lock);
+ if (atomic_dec_and_test(&ar->tx_total_queued))
+ complete(&ar->tx_flush);
+}
+
+static int carl9170_alloc_dev_space(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super = (void *) skb->data;
+ unsigned int chunks;
+ int cookie = -1;
+
+ atomic_inc(&ar->mem_allocs);
+
+ chunks = DIV_ROUND_UP(skb->len, ar->fw.mem_block_size);
+ if (unlikely(atomic_sub_return(chunks, &ar->mem_free_blocks) < 0)) {
+ atomic_add(chunks, &ar->mem_free_blocks);
+ return -ENOSPC;
+ }
+
+ spin_lock_bh(&ar->mem_lock);
+ cookie = bitmap_find_free_region(ar->mem_bitmap, ar->fw.mem_blocks, 0);
+ spin_unlock_bh(&ar->mem_lock);
+
+ if (unlikely(cookie < 0)) {
+ atomic_add(chunks, &ar->mem_free_blocks);
+ return -ENOSPC;
+ }
+
+ super = (void *) skb->data;
+
+ /*
+ * Cookie #0 serves two special purposes:
+ * 1. The firmware might use it generate BlockACK frames
+ * in responds of an incoming BlockAckReqs.
+ *
+ * 2. Prevent double-free bugs.
+ */
+ super->s.cookie = (u8) cookie + 1;
+ return 0;
+}
+
+static void carl9170_release_dev_space(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super = (void *) skb->data;
+ int cookie;
+
+ /* make a local copy of the cookie */
+ cookie = super->s.cookie;
+ /* invalidate cookie */
+ super->s.cookie = 0;
+
+ /*
+ * Do a out-of-bounds check on the cookie:
+ *
+ * * cookie "0" is reserved and won't be assigned to any
+ * out-going frame. Internally however, it is used to
+ * mark no longer/un-accounted frames and serves as a
+ * cheap way of preventing frames from being freed
+ * twice by _accident_. NB: There is a tiny race...
+ *
+ * * obviously, cookie number is limited by the amount
+ * of available memory blocks, so the number can
+ * never execeed the mem_blocks count.
+ */
+ if (unlikely(WARN_ON_ONCE(cookie == 0) ||
+ WARN_ON_ONCE(cookie > ar->fw.mem_blocks)))
+ return;
+
+ atomic_add(DIV_ROUND_UP(skb->len, ar->fw.mem_block_size),
+ &ar->mem_free_blocks);
+
+ spin_lock_bh(&ar->mem_lock);
+ bitmap_release_region(ar->mem_bitmap, cookie - 1, 0);
+ spin_unlock_bh(&ar->mem_lock);
+}
+
+/* Called from any context */
+static void carl9170_tx_release(struct kref *ref)
+{
+ struct ar9170 *ar;
+ struct carl9170_tx_info *arinfo;
+ struct ieee80211_tx_info *txinfo;
+ struct sk_buff *skb;
+
+ arinfo = container_of(ref, struct carl9170_tx_info, ref);
+ txinfo = container_of((void *) arinfo, struct ieee80211_tx_info,
+ rate_driver_data);
+ skb = container_of((void *) txinfo, struct sk_buff, cb);
+
+ ar = arinfo->ar;
+ if (WARN_ON_ONCE(!ar))
+ return;
+
+ BUILD_BUG_ON(
+ offsetof(struct ieee80211_tx_info, status.ampdu_ack_len) != 23);
+
+ memset(&txinfo->status.ampdu_ack_len, 0,
+ sizeof(struct ieee80211_tx_info) -
+ offsetof(struct ieee80211_tx_info, status.ampdu_ack_len));
+
+ if (atomic_read(&ar->tx_total_queued))
+ ar->tx_schedule = true;
+
+ if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) {
+ if (!atomic_read(&ar->tx_ampdu_upload))
+ ar->tx_ampdu_schedule = true;
+
+ if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) {
+ txinfo->status.ampdu_len = txinfo->pad[0];
+ txinfo->status.ampdu_ack_len = txinfo->pad[1];
+ txinfo->pad[0] = txinfo->pad[1] = 0;
+ } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) {
+ /*
+ * drop redundant tx_status reports:
+ *
+ * 1. ampdu_ack_len of the final tx_status does
+ * include the feedback of this particular frame.
+ *
+ * 2. tx_status_irqsafe only queues up to 128
+ * tx feedback reports and discards the rest.
+ *
+ * 3. minstrel_ht is picky, it only accepts
+ * reports of frames with the TX_STATUS_AMPDU flag.
+ */
+
+ dev_kfree_skb_any(skb);
+ return;
+ } else {
+ /*
+ * Frame has failed, but we want to keep it in
+ * case it was lost due to a power-state
+ * transition.
+ */
+ }
+ }
+
+ skb_pull(skb, sizeof(struct _carl9170_tx_superframe));
+ ieee80211_tx_status_irqsafe(ar->hw, skb);
+}
+
+void carl9170_tx_get_skb(struct sk_buff *skb)
+{
+ struct carl9170_tx_info *arinfo = (void *)
+ (IEEE80211_SKB_CB(skb))->rate_driver_data;
+ kref_get(&arinfo->ref);
+}
+
+int carl9170_tx_put_skb(struct sk_buff *skb)
+{
+ struct carl9170_tx_info *arinfo = (void *)
+ (IEEE80211_SKB_CB(skb))->rate_driver_data;
+
+ return kref_put(&arinfo->ref, carl9170_tx_release);
+}
+
+/* Caller must hold the tid_info->lock & rcu_read_lock */
+static void carl9170_tx_shift_bm(struct ar9170 *ar,
+ struct carl9170_sta_tid *tid_info, u16 seq)
+{
+ u16 off;
+
+ off = SEQ_DIFF(seq, tid_info->bsn);
+
+ if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS))
+ return;
+
+ /*
+ * Sanity check. For each MPDU we set the bit in bitmap and
+ * clear it once we received the tx_status.
+ * But if the bit is already cleared then we've been bitten
+ * by a bug.
+ */
+ WARN_ON_ONCE(!test_and_clear_bit(off, tid_info->bitmap));
+
+ off = SEQ_DIFF(tid_info->snx, tid_info->bsn);
+ if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS))
+ return;
+
+ if (!bitmap_empty(tid_info->bitmap, off))
+ off = find_first_bit(tid_info->bitmap, off);
+
+ tid_info->bsn += off;
+ tid_info->bsn &= 0x0fff;
+
+ bitmap_shift_right(tid_info->bitmap, tid_info->bitmap,
+ off, CARL9170_BAW_BITS);
+}
+
+static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
+ struct sk_buff *skb, struct ieee80211_tx_info *txinfo)
+{
+ 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_tid *tid_info;
+ struct ieee80211_vif *vif;
+ unsigned int vif_id;
+ u8 tid;
+
+ if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
+ txinfo->flags & IEEE80211_TX_CTL_INJECTED)
+ 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);
+ if (unlikely(!sta))
+ goto out_rcu;
+
+ tid = get_tid_h(hdr);
+
+ sta_info = (void *) sta->drv_priv;
+ tid_info = rcu_dereference(sta_info->agg[tid]);
+ if (!tid_info)
+ goto out_rcu;
+
+ spin_lock_bh(&tid_info->lock);
+ if (likely(tid_info->state >= CARL9170_TID_STATE_IDLE))
+ carl9170_tx_shift_bm(ar, tid_info, get_seq_h(hdr));
+
+ if (sta_info->stats[tid].clear) {
+ sta_info->stats[tid].clear = false;
+ sta_info->stats[tid].ampdu_len = 0;
+ sta_info->stats[tid].ampdu_ack_len = 0;
+ }
+
+ sta_info->stats[tid].ampdu_len++;
+ if (txinfo->status.rates[0].count == 1)
+ sta_info->stats[tid].ampdu_ack_len++;
+
+ if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) {
+ txinfo->pad[0] = sta_info->stats[tid].ampdu_len;
+ txinfo->pad[1] = sta_info->stats[tid].ampdu_ack_len;
+ txinfo->flags |= IEEE80211_TX_STAT_AMPDU;
+ sta_info->stats[tid].clear = true;
+ }
+ spin_unlock_bh(&tid_info->lock);
+
+out_rcu:
+ rcu_read_unlock();
+}
+
+void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+ const bool success)
+{
+ struct ieee80211_tx_info *txinfo;
+
+ carl9170_tx_accounting_free(ar, skb);
+
+ txinfo = IEEE80211_SKB_CB(skb);
+
+ if (success)
+ txinfo->flags |= IEEE80211_TX_STAT_ACK;
+ else
+ ar->tx_ack_failures++;
+
+ if (txinfo->flags & IEEE80211_TX_CTL_AMPDU)
+ carl9170_tx_status_process_ampdu(ar, skb, txinfo);
+
+ carl9170_tx_put_skb(skb);
+}
+
+/* This function may be called form any context */
+void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
+
+ atomic_dec(&ar->tx_total_pending);
+
+ if (txinfo->flags & IEEE80211_TX_CTL_AMPDU)
+ atomic_dec(&ar->tx_ampdu_upload);
+
+ if (carl9170_tx_put_skb(skb))
+ tasklet_hi_schedule(&ar->usb_tasklet);
+}
+
+static struct sk_buff *carl9170_get_queued_skb(struct ar9170 *ar, u8 cookie,
+ struct sk_buff_head *queue)
+{
+ struct sk_buff *skb;
+
+ spin_lock_bh(&queue->lock);
+ skb_queue_walk(queue, skb) {
+ struct _carl9170_tx_superframe *txc = (void *) skb->data;
+
+ if (txc->s.cookie != cookie)
+ continue;
+
+ __skb_unlink(skb, queue);
+ spin_unlock_bh(&queue->lock);
+
+ carl9170_release_dev_space(ar, skb);
+ return skb;
+ }
+ spin_unlock_bh(&queue->lock);
+
+ return NULL;
+}
+
+static void carl9170_tx_fill_rateinfo(struct ar9170 *ar, unsigned int rix,
+ unsigned int tries, struct ieee80211_tx_info *txinfo)
+{
+ unsigned int i;
+
+ for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+ if (txinfo->status.rates[i].idx < 0)
+ break;
+
+ if (i == rix) {
+ txinfo->status.rates[i].count = tries;
+ i++;
+ break;
+ }
+ }
+
+ for (; i < IEEE80211_TX_MAX_RATES; i++) {
+ txinfo->status.rates[i].idx = -1;
+ txinfo->status.rates[i].count = 0;
+ }
+}
+
+static void carl9170_check_queue_stop_timeout(struct ar9170 *ar)
+{
+ int i;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *txinfo;
+ struct carl9170_tx_info *arinfo;
+ bool restart = false;
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ spin_lock_bh(&ar->tx_status[i].lock);
+
+ skb = skb_peek(&ar->tx_status[i]);
+
+ if (!skb)
+ goto next;
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ arinfo = (void *) txinfo->rate_driver_data;
+
+ if (time_is_before_jiffies(arinfo->timeout +
+ msecs_to_jiffies(CARL9170_QUEUE_STUCK_TIMEOUT)) == true)
+ restart = true;
+
+next:
+ spin_unlock_bh(&ar->tx_status[i].lock);
+ }
+
+ if (restart) {
+ /*
+ * At least one queue has been stuck for long enough.
+ * Give the device a kick and hope it gets back to
+ * work.
+ *
+ * possible reasons may include:
+ * - frames got lost/corrupted (bad connection to the device)
+ * - stalled rx processing/usb controller hiccups
+ * - firmware errors/bugs
+ * - every bug you can think of.
+ * - all bugs you can't...
+ * - ...
+ */
+ carl9170_restart(ar, CARL9170_RR_STUCK_TX);
+ }
+}
+
+void carl9170_tx_janitor(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ tx_janitor.work);
+ if (!IS_STARTED(ar))
+ return;
+
+ ar->tx_janitor_last_run = jiffies;
+
+ carl9170_check_queue_stop_timeout(ar);
+
+ if (!atomic_read(&ar->tx_total_queued))
+ return;
+
+ ieee80211_queue_delayed_work(ar->hw, &ar->tx_janitor,
+ msecs_to_jiffies(CARL9170_TX_TIMEOUT));
+}
+
+static void __carl9170_tx_process_status(struct ar9170 *ar,
+ const uint8_t cookie, const uint8_t info)
+{
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *txinfo;
+ struct carl9170_tx_info *arinfo;
+ unsigned int r, t, q;
+ bool success = true;
+
+ q = ar9170_qmap[info & CARL9170_TX_STATUS_QUEUE];
+
+ skb = carl9170_get_queued_skb(ar, cookie, &ar->tx_status[q]);
+ if (!skb) {
+ /*
+ * We have lost the race to another thread.
+ */
+
+ return ;
+ }
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ arinfo = (void *) txinfo->rate_driver_data;
+
+ if (!(info & CARL9170_TX_STATUS_SUCCESS))
+ success = false;
+
+ r = (info & CARL9170_TX_STATUS_RIX) >> CARL9170_TX_STATUS_RIX_S;
+ t = (info & CARL9170_TX_STATUS_TRIES) >> CARL9170_TX_STATUS_TRIES_S;
+
+ carl9170_tx_fill_rateinfo(ar, r, t, txinfo);
+ carl9170_tx_status(ar, skb, success);
+}
+
+void carl9170_tx_process_status(struct ar9170 *ar,
+ const struct carl9170_rsp *cmd)
+{
+ unsigned int i;
+
+ for (i = 0; i < cmd->hdr.ext; i++) {
+ if (WARN_ON(i > ((cmd->hdr.len / 2) + 1))) {
+ print_hex_dump_bytes("UU:", DUMP_PREFIX_NONE,
+ (void *) cmd, cmd->hdr.len + 4);
+ break;
+ }
+
+ __carl9170_tx_process_status(ar, cmd->_tx_status[i].cookie,
+ cmd->_tx_status[i].info);
+ }
+}
+
+static __le32 carl9170_tx_physet(struct ar9170 *ar,
+ struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate)
+{
+ struct ieee80211_rate *rate = NULL;
+ u32 power, chains;
+ __le32 tmp;
+
+ tmp = cpu_to_le32(0);
+
+ if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ tmp |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ <<
+ AR9170_TX_PHY_BW_S);
+ /* this works because 40 MHz is 2 and dup is 3 */
+ if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
+ tmp |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP <<
+ AR9170_TX_PHY_BW_S);
+
+ if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+ tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
+
+ if (txrate->flags & IEEE80211_TX_RC_MCS) {
+ u32 r = txrate->idx;
+ u8 *txpower;
+
+ /* heavy clip control */
+ tmp |= cpu_to_le32((r & 0x7) <<
+ AR9170_TX_PHY_TX_HEAVY_CLIP_S);
+
+ 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[r & 7];
+
+ /* +1 dBm for HT40 */
+ if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ power += 2;
+
+ r <<= AR9170_TX_PHY_MCS_S;
+ BUG_ON(r & ~AR9170_TX_PHY_MCS);
+
+ tmp |= cpu_to_le32(r & AR9170_TX_PHY_MCS);
+ tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
+
+ /*
+ * green field preamble does not work.
+ *
+ * if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+ * tmp |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
+ */
+ } 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 = &__carl9170_ratetable[idx];
+
+ phyrate = rate->hw_value & 0xF;
+ power = txpower[(rate->hw_value & 0x30) >> 4];
+ phyrate <<= AR9170_TX_PHY_MCS_S;
+
+ tmp |= cpu_to_le32(mod);
+ tmp |= cpu_to_le32(phyrate);
+
+ /*
+ * short preamble seems to be broken too.
+ *
+ * if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ * tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
+ */
+ }
+ power <<= AR9170_TX_PHY_TX_PWR_S;
+ power &= AR9170_TX_PHY_TX_PWR;
+ tmp |= 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 &&
+ !(txrate->flags & IEEE80211_TX_RC_MCS))
+ chains = AR9170_TX_PHY_TXCHAIN_1;
+ }
+ tmp |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_S);
+
+ return tmp;
+}
+
+static bool carl9170_tx_rts_check(struct ar9170 *ar,
+ struct ieee80211_tx_rate *rate,
+ bool ampdu, bool multi)
+{
+ switch (ar->erp_mode) {
+ case CARL9170_ERP_AUTO:
+ if (ampdu)
+ break;
+
+ case CARL9170_ERP_MAC80211:
+ if (!(rate->flags & IEEE80211_TX_RC_USE_RTS_CTS))
+ break;
+
+ case CARL9170_ERP_RTS:
+ if (likely(!multi))
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static bool carl9170_tx_cts_check(struct ar9170 *ar,
+ struct ieee80211_tx_rate *rate)
+{
+ switch (ar->erp_mode) {
+ case CARL9170_ERP_AUTO:
+ case CARL9170_ERP_MAC80211:
+ if (!(rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
+ break;
+
+ case CARL9170_ERP_CTS:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+ struct _carl9170_tx_superframe *txc;
+ struct carl9170_vif_info *cvif;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_tx_rate *txrate;
+ struct ieee80211_sta *sta;
+ struct carl9170_tx_info *arinfo;
+ unsigned int hw_queue;
+ int i;
+ __le16 mac_tmp;
+ u16 len;
+ bool ampdu, no_ack;
+
+ BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
+ BUILD_BUG_ON(sizeof(struct _carl9170_tx_superdesc) !=
+ CARL9170_TX_SUPERDESC_LEN);
+
+ BUILD_BUG_ON(sizeof(struct _ar9170_tx_hwdesc) !=
+ AR9170_TX_HWDESC_LEN);
+
+ BUILD_BUG_ON(IEEE80211_TX_MAX_RATES < CARL9170_TX_MAX_RATES);
+
+ BUILD_BUG_ON(AR9170_MAX_VIRTUAL_MAC >
+ ((CARL9170_TX_SUPER_MISC_VIF_ID >>
+ CARL9170_TX_SUPER_MISC_VIF_ID_S) + 1));
+
+ hw_queue = ar9170_qmap[carl9170_get_queue(ar, skb)];
+
+ hdr = (void *)skb->data;
+ info = IEEE80211_SKB_CB(skb);
+ len = skb->len;
+
+ /*
+ * Note: If the frame was sent through a monitor interface,
+ * the ieee80211_vif pointer can be NULL.
+ */
+ if (likely(info->control.vif))
+ cvif = (void *) info->control.vif->drv_priv;
+ else
+ cvif = NULL;
+
+ sta = info->control.sta;
+
+ txc = (void *)skb_push(skb, sizeof(*txc));
+ memset(txc, 0, sizeof(*txc));
+
+ SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, txc->s.misc, hw_queue);
+
+ if (likely(cvif))
+ SET_VAL(CARL9170_TX_SUPER_MISC_VIF_ID, txc->s.misc, cvif->id);
+
+ if (unlikely(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM))
+ txc->s.misc |= CARL9170_TX_SUPER_MISC_CAB;
+
+ if (unlikely(ieee80211_is_probe_resp(hdr->frame_control)))
+ txc->s.misc |= CARL9170_TX_SUPER_MISC_FILL_IN_TSF;
+
+ mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
+ AR9170_TX_MAC_BACKOFF);
+ mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &&
+ AR9170_TX_MAC_QOS);
+
+ no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK);
+ if (unlikely(no_ack))
+ mac_tmp |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
+
+ if (info->control.hw_key) {
+ len += 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:
+ mac_tmp |= cpu_to_le16(AR9170_TX_MAC_ENCR_RC4);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ mac_tmp |= cpu_to_le16(AR9170_TX_MAC_ENCR_AES);
+ break;
+ default:
+ WARN_ON(1);
+ goto err_out;
+ }
+ }
+
+ ampdu = !!(info->flags & IEEE80211_TX_CTL_AMPDU);
+ if (ampdu) {
+ unsigned int density, factor;
+
+ if (unlikely(!sta || !cvif))
+ goto err_out;
+
+ factor = min_t(unsigned int, 1u,
+ info->control.sta->ht_cap.ampdu_factor);
+
+ density = info->control.sta->ht_cap.ampdu_density;
+
+ if (density) {
+ /*
+ * Watch out!
+ *
+ * Otus uses slightly different density values than
+ * those from the 802.11n spec.
+ */
+
+ density = max_t(unsigned int, density + 1, 7u);
+ }
+
+ SET_VAL(CARL9170_TX_SUPER_AMPDU_DENSITY,
+ txc->s.ampdu_settings, density);
+
+ SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR,
+ txc->s.ampdu_settings, factor);
+
+ for (i = 0; i < CARL9170_TX_MAX_RATES; i++) {
+ txrate = &info->control.rates[i];
+ if (txrate->idx >= 0) {
+ txc->s.ri[i] =
+ CARL9170_TX_SUPER_RI_AMPDU;
+
+ if (WARN_ON(!(txrate->flags &
+ IEEE80211_TX_RC_MCS))) {
+ /*
+ * Not sure if it's even possible
+ * to aggregate non-ht rates with
+ * this HW.
+ */
+ goto err_out;
+ }
+ continue;
+ }
+
+ txrate->idx = 0;
+ txrate->count = ar->hw->max_rate_tries;
+ }
+
+ mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR);
+ }
+
+ /*
+ * NOTE: For the first rate, the ERP & AMPDU flags are directly
+ * taken from mac_control. For all fallback rate, the firmware
+ * updates the mac_control flags from the rate info field.
+ */
+ for (i = 1; i < CARL9170_TX_MAX_RATES; i++) {
+ txrate = &info->control.rates[i];
+ if (txrate->idx < 0)
+ break;
+
+ SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i],
+ txrate->count);
+
+ if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
+ txc->s.ri[i] |= (AR9170_TX_MAC_PROT_RTS <<
+ CARL9170_TX_SUPER_RI_ERP_PROT_S);
+ else if (carl9170_tx_cts_check(ar, txrate))
+ txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS <<
+ CARL9170_TX_SUPER_RI_ERP_PROT_S);
+
+ txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate);
+ }
+
+ txrate = &info->control.rates[0];
+ SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count);
+
+ if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
+ mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
+ else if (carl9170_tx_cts_check(ar, txrate))
+ mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
+
+ txc->s.len = cpu_to_le16(skb->len);
+ txc->f.length = cpu_to_le16(len + FCS_LEN);
+ txc->f.mac_control = mac_tmp;
+ txc->f.phy_control = carl9170_tx_physet(ar, info, txrate);
+
+ arinfo = (void *)info->rate_driver_data;
+ arinfo->timeout = jiffies;
+ arinfo->ar = ar;
+ kref_init(&arinfo->ref);
+ return 0;
+
+err_out:
+ skb_pull(skb, sizeof(*txc));
+ return -EINVAL;
+}
+
+static void carl9170_set_immba(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super;
+
+ super = (void *) skb->data;
+ super->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_BA);
+}
+
+static void carl9170_set_ampdu_params(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super;
+ int tmp;
+
+ super = (void *) skb->data;
+
+ tmp = (super->s.ampdu_settings & CARL9170_TX_SUPER_AMPDU_DENSITY) <<
+ CARL9170_TX_SUPER_AMPDU_DENSITY_S;
+
+ /*
+ * If you haven't noticed carl9170_tx_prepare has already filled
+ * in all ampdu spacing & factor parameters.
+ * Now it's the time to check whenever the settings have to be
+ * updated by the firmware, or if everything is still the same.
+ *
+ * There's no sane way to handle different density values with
+ * this hardware, so we may as well just do the compare in the
+ * driver.
+ */
+
+ if (tmp != ar->current_density) {
+ ar->current_density = tmp;
+ super->s.ampdu_settings |=
+ CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY;
+ }
+
+ tmp = (super->s.ampdu_settings & CARL9170_TX_SUPER_AMPDU_FACTOR) <<
+ CARL9170_TX_SUPER_AMPDU_FACTOR_S;
+
+ if (tmp != ar->current_factor) {
+ ar->current_factor = tmp;
+ super->s.ampdu_settings |=
+ CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR;
+ }
+}
+
+static bool carl9170_tx_rate_check(struct ar9170 *ar, struct sk_buff *_dest,
+ struct sk_buff *_src)
+{
+ struct _carl9170_tx_superframe *dest, *src;
+
+ dest = (void *) _dest->data;
+ src = (void *) _src->data;
+
+ /*
+ * The mac80211 rate control algorithm expects that all MPDUs in
+ * an AMPDU share the same tx vectors.
+ * This is not really obvious right now, because the hardware
+ * does the AMPDU setup according to its own rulebook.
+ * Our nicely assembled, strictly monotonic increasing mpdu
+ * chains will be broken up, mashed back together...
+ */
+
+ return (dest->f.phy_control == src->f.phy_control);
+}
+
+static void carl9170_tx_ampdu(struct ar9170 *ar)
+{
+ struct sk_buff_head agg;
+ struct carl9170_sta_tid *tid_info;
+ struct sk_buff *skb, *first;
+ unsigned int i = 0, done_ampdus = 0;
+ u16 seq, queue, tmpssn;
+
+ atomic_inc(&ar->tx_ampdu_scheduler);
+ ar->tx_ampdu_schedule = false;
+
+ if (atomic_read(&ar->tx_ampdu_upload))
+ return;
+
+ if (!ar->tx_ampdu_list_len)
+ return;
+
+ __skb_queue_head_init(&agg);
+
+ rcu_read_lock();
+ tid_info = rcu_dereference(ar->tx_ampdu_iter);
+ if (WARN_ON_ONCE(!tid_info)) {
+ rcu_read_unlock();
+ return;
+ }
+
+retry:
+ list_for_each_entry_continue_rcu(tid_info, &ar->tx_ampdu_list, list) {
+ i++;
+
+ if (tid_info->state < CARL9170_TID_STATE_PROGRESS)
+ continue;
+
+ queue = TID_TO_WME_AC(tid_info->tid);
+
+ spin_lock_bh(&tid_info->lock);
+ if (tid_info->state != CARL9170_TID_STATE_XMIT)
+ goto processed;
+
+ tid_info->counter++;
+ first = skb_peek(&tid_info->queue);
+ tmpssn = carl9170_get_seq(first);
+ seq = tid_info->snx;
+
+ if (unlikely(tmpssn != seq)) {
+ tid_info->state = CARL9170_TID_STATE_IDLE;
+
+ goto processed;
+ }
+
+ while ((skb = skb_peek(&tid_info->queue))) {
+ /* strict 0, 1, ..., n - 1, n frame sequence order */
+ if (unlikely(carl9170_get_seq(skb) != seq))
+ break;
+
+ /* don't upload more than AMPDU FACTOR allows. */
+ if (unlikely(SEQ_DIFF(tid_info->snx, tid_info->bsn) >=
+ (tid_info->max - 1)))
+ break;
+
+ if (!carl9170_tx_rate_check(ar, skb, first))
+ break;
+
+ atomic_inc(&ar->tx_ampdu_upload);
+ tid_info->snx = seq = SEQ_NEXT(seq);
+ __skb_unlink(skb, &tid_info->queue);
+
+ __skb_queue_tail(&agg, skb);
+
+ if (skb_queue_len(&agg) >= CARL9170_NUM_TX_AGG_MAX)
+ break;
+ }
+
+ if (skb_queue_empty(&tid_info->queue) ||
+ carl9170_get_seq(skb_peek(&tid_info->queue)) !=
+ tid_info->snx) {
+ /*
+ * stop TID, if A-MPDU frames are still missing,
+ * or whenever the queue is empty.
+ */
+
+ tid_info->state = CARL9170_TID_STATE_IDLE;
+ }
+ done_ampdus++;
+
+processed:
+ spin_unlock_bh(&tid_info->lock);
+
+ if (skb_queue_empty(&agg))
+ continue;
+
+ /* apply ampdu spacing & factor settings */
+ carl9170_set_ampdu_params(ar, skb_peek(&agg));
+
+ /* set aggregation push bit */
+ carl9170_set_immba(ar, skb_peek_tail(&agg));
+
+ spin_lock_bh(&ar->tx_pending[queue].lock);
+ skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]);
+ spin_unlock_bh(&ar->tx_pending[queue].lock);
+ ar->tx_schedule = true;
+ }
+ if ((done_ampdus++ == 0) && (i++ == 0))
+ goto retry;
+
+ rcu_assign_pointer(ar->tx_ampdu_iter, tid_info);
+ rcu_read_unlock();
+}
+
+static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar,
+ struct sk_buff_head *queue)
+{
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ struct carl9170_tx_info *arinfo;
+
+ BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
+
+ spin_lock_bh(&queue->lock);
+ skb = skb_peek(queue);
+ if (unlikely(!skb))
+ goto err_unlock;
+
+ if (carl9170_alloc_dev_space(ar, skb))
+ goto err_unlock;
+
+ __skb_unlink(skb, queue);
+ spin_unlock_bh(&queue->lock);
+
+ info = IEEE80211_SKB_CB(skb);
+ 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:
+ spin_unlock_bh(&queue->lock);
+ return NULL;
+}
+
+void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super;
+ uint8_t q = 0;
+
+ ar->tx_dropped++;
+
+ super = (void *)skb->data;
+ SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, q,
+ ar9170_qmap[carl9170_get_queue(ar, skb)]);
+ __carl9170_tx_process_status(ar, super->s.cookie, q);
+}
+
+static void carl9170_tx(struct ar9170 *ar)
+{
+ struct sk_buff *skb;
+ unsigned int i, q;
+ bool schedule_garbagecollector = false;
+
+ ar->tx_schedule = false;
+
+ if (unlikely(!IS_STARTED(ar)))
+ return;
+
+ carl9170_usb_handle_tx_err(ar);
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ while (!skb_queue_empty(&ar->tx_pending[i])) {
+ skb = carl9170_tx_pick_skb(ar, &ar->tx_pending[i]);
+ if (unlikely(!skb))
+ break;
+
+ atomic_inc(&ar->tx_total_pending);
+
+ q = __carl9170_get_queue(ar, i);
+ /*
+ * NB: tx_status[i] vs. tx_status[q],
+ * TODO: Move into pick_skb or alloc_dev_space.
+ */
+ skb_queue_tail(&ar->tx_status[q], skb);
+
+ carl9170_usb_tx(ar, skb);
+ schedule_garbagecollector = true;
+ }
+ }
+
+ if (!schedule_garbagecollector)
+ return;
+
+ ieee80211_queue_delayed_work(ar->hw, &ar->tx_janitor,
+ msecs_to_jiffies(CARL9170_TX_TIMEOUT));
+}
+
+static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
+ struct ieee80211_sta *sta, struct sk_buff *skb)
+{
+ 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;
+
+ tid = carl9170_get_tid(skb);
+ seq = carl9170_get_seq(skb);
+ sta_info = (void *) sta->drv_priv;
+
+ rcu_read_lock();
+ agg = rcu_dereference(sta_info->agg[tid]);
+ max = sta_info->ampdu_max_len;
+
+ if (!agg)
+ goto err_unlock_rcu;
+
+ spin_lock_bh(&agg->lock);
+ if (unlikely(agg->state < CARL9170_TID_STATE_IDLE))
+ goto err_unlock;
+
+ /* check if sequence is within the BA window */
+ if (unlikely(!BAW_WITHIN(agg->bsn, CARL9170_BAW_BITS, seq)))
+ goto err_unlock;
+
+ if (WARN_ON_ONCE(!BAW_WITHIN(agg->snx, CARL9170_BAW_BITS, seq)))
+ goto err_unlock;
+
+ off = SEQ_DIFF(seq, agg->bsn);
+ if (WARN_ON_ONCE(test_and_set_bit(off, agg->bitmap)))
+ goto err_unlock;
+
+ if (likely(BAW_WITHIN(agg->hsn, CARL9170_BAW_BITS, seq))) {
+ __skb_queue_tail(&agg->queue, skb);
+ agg->hsn = seq;
+ goto queued;
+ }
+
+ skb_queue_reverse_walk(&agg->queue, iter) {
+ qseq = carl9170_get_seq(iter);
+
+ if (BAW_WITHIN(qseq, CARL9170_BAW_BITS, seq)) {
+ __skb_queue_after(&agg->queue, iter, skb);
+ goto queued;
+ }
+ }
+
+ __skb_queue_head(&agg->queue, skb);
+queued:
+
+ if (unlikely(agg->state != CARL9170_TID_STATE_XMIT)) {
+ if (agg->snx == carl9170_get_seq(skb_peek(&agg->queue))) {
+ agg->state = CARL9170_TID_STATE_XMIT;
+ run = true;
+ }
+ }
+
+ spin_unlock_bh(&agg->lock);
+ rcu_read_unlock();
+
+ return run;
+
+err_unlock:
+ spin_unlock_bh(&agg->lock);
+
+err_unlock_rcu:
+ rcu_read_unlock();
+ carl9170_tx_status(ar, skb, false);
+ ar->tx_dropped++;
+ return false;
+}
+
+int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ar9170 *ar = hw->priv;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_sta *sta;
+ bool run;
+
+ if (unlikely(!IS_STARTED(ar)))
+ goto err_free;
+
+ info = IEEE80211_SKB_CB(skb);
+ sta = info->control.sta;
+
+ if (unlikely(carl9170_tx_prepare(ar, skb)))
+ goto err_free;
+
+ carl9170_tx_accounting(ar, skb);
+ /*
+ * from now on, one has to use carl9170_tx_status to free
+ * all ressouces which are associated with the frame.
+ */
+
+ if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+ if (WARN_ON_ONCE(!sta))
+ goto err_free;
+
+ run = carl9170_tx_ampdu_queue(ar, sta, skb);
+ if (run)
+ carl9170_tx_ampdu(ar);
+
+ } else {
+ unsigned int queue = skb_get_queue_mapping(skb);
+
+ skb_queue_tail(&ar->tx_pending[queue], skb);
+ }
+
+ carl9170_tx(ar);
+ return NETDEV_TX_OK;
+
+err_free:
+ ar->tx_dropped++;
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+void carl9170_tx_scheduler(struct ar9170 *ar)
+{
+
+ if (ar->tx_ampdu_schedule)
+ carl9170_tx_ampdu(ar);
+
+ if (ar->tx_schedule)
+ carl9170_tx(ar);
+}
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
new file mode 100644
index 000000000000..c7f6193934ea
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -0,0 +1,1136 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * USB - frontend
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "carl9170.h"
+#include "cmd.h"
+#include "hw.h"
+#include "fwcmd.h"
+
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_AUTHOR("Christian Lamparter <chunkeey@googlemail.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
+MODULE_FIRMWARE(CARL9170FW_NAME);
+MODULE_ALIAS("ar9170usb");
+MODULE_ALIAS("arusb_lnx");
+
+/*
+ * Note:
+ *
+ * Always update our wiki's device list (located at:
+ * http://wireless.kernel.org/en/users/Drivers/ar9170/devices ),
+ * whenever you add a new device.
+ */
+static struct usb_device_id carl9170_usb_ids[] = {
+ /* Atheros 9170 */
+ { USB_DEVICE(0x0cf3, 0x9170) },
+ /* Atheros TG121N */
+ { USB_DEVICE(0x0cf3, 0x1001) },
+ /* TP-Link TL-WN821N v2 */
+ { USB_DEVICE(0x0cf3, 0x1002), .driver_info = CARL9170_WPS_BUTTON |
+ CARL9170_ONE_LED },
+ /* 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), .driver_info = CARL9170_ONE_LED },
+ /* 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) },
+ /* NEC WL300NU-G */
+ { USB_DEVICE(0x0409, 0x0249) },
+ /* AVM FRITZ!WLAN USB Stick N */
+ { USB_DEVICE(0x057c, 0x8401) },
+ /* AVM FRITZ!WLAN USB Stick N 2.4 */
+ { USB_DEVICE(0x057c, 0x8402) },
+ /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */
+ { USB_DEVICE(0x1668, 0x1200) },
+
+ /* terminate */
+ {}
+};
+MODULE_DEVICE_TABLE(usb, carl9170_usb_ids);
+
+static void carl9170_usb_submit_data_urb(struct ar9170 *ar)
+{
+ struct urb *urb;
+ int err;
+
+ if (atomic_inc_return(&ar->tx_anch_urbs) > AR9170_NUM_TX_URBS)
+ goto err_acc;
+
+ urb = usb_get_from_anchor(&ar->tx_wait);
+ if (!urb)
+ goto err_acc;
+
+ usb_anchor_urb(urb, &ar->tx_anch);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(err)) {
+ if (net_ratelimit()) {
+ dev_err(&ar->udev->dev, "tx submit failed (%d)\n",
+ urb->status);
+ }
+
+ usb_unanchor_urb(urb);
+ usb_anchor_urb(urb, &ar->tx_err);
+ }
+
+ usb_free_urb(urb);
+
+ if (likely(err == 0))
+ return;
+
+err_acc:
+ atomic_dec(&ar->tx_anch_urbs);
+}
+
+static void carl9170_usb_tx_data_complete(struct urb *urb)
+{
+ struct ar9170 *ar = (struct ar9170 *)
+ usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+
+ if (WARN_ON_ONCE(!ar)) {
+ dev_kfree_skb_irq(urb->context);
+ return;
+ }
+
+ atomic_dec(&ar->tx_anch_urbs);
+
+ switch (urb->status) {
+ /* everything is fine */
+ case 0:
+ carl9170_tx_callback(ar, (void *)urb->context);
+ break;
+
+ /* disconnect */
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ /*
+ * Defer the frame clean-up to the tasklet worker.
+ * This is necessary, because carl9170_tx_drop
+ * does not work in an irqsave context.
+ */
+ usb_anchor_urb(urb, &ar->tx_err);
+ return;
+
+ /* a random transmission error has occurred? */
+ default:
+ if (net_ratelimit()) {
+ dev_err(&ar->udev->dev, "tx failed (%d)\n",
+ urb->status);
+ }
+
+ usb_anchor_urb(urb, &ar->tx_err);
+ break;
+ }
+
+ if (likely(IS_STARTED(ar)))
+ carl9170_usb_submit_data_urb(ar);
+}
+
+static int carl9170_usb_submit_cmd_urb(struct ar9170 *ar)
+{
+ struct urb *urb;
+ int err;
+
+ if (atomic_inc_return(&ar->tx_cmd_urbs) != 1) {
+ atomic_dec(&ar->tx_cmd_urbs);
+ return 0;
+ }
+
+ urb = usb_get_from_anchor(&ar->tx_cmd);
+ if (!urb) {
+ atomic_dec(&ar->tx_cmd_urbs);
+ return 0;
+ }
+
+ usb_anchor_urb(urb, &ar->tx_anch);
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(err)) {
+ usb_unanchor_urb(urb);
+ atomic_dec(&ar->tx_cmd_urbs);
+ }
+ usb_free_urb(urb);
+
+ return err;
+}
+
+static void carl9170_usb_cmd_complete(struct urb *urb)
+{
+ struct ar9170 *ar = urb->context;
+ int err = 0;
+
+ if (WARN_ON_ONCE(!ar))
+ return;
+
+ atomic_dec(&ar->tx_cmd_urbs);
+
+ switch (urb->status) {
+ /* everything is fine */
+ case 0:
+ break;
+
+ /* disconnect */
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ err = urb->status;
+ break;
+ }
+
+ if (!IS_INITIALIZED(ar))
+ return;
+
+ if (err)
+ dev_err(&ar->udev->dev, "submit cmd cb failed (%d).\n", err);
+
+ err = carl9170_usb_submit_cmd_urb(ar);
+ if (err)
+ dev_err(&ar->udev->dev, "submit cmd failed (%d).\n", err);
+}
+
+static void carl9170_usb_rx_irq_complete(struct urb *urb)
+{
+ struct ar9170 *ar = urb->context;
+
+ if (WARN_ON_ONCE(!ar))
+ return;
+
+ switch (urb->status) {
+ /* everything is fine */
+ case 0:
+ break;
+
+ /* disconnect */
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ goto resubmit;
+ }
+
+ carl9170_handle_command_response(ar, urb->transfer_buffer,
+ urb->actual_length);
+
+resubmit:
+ usb_anchor_urb(urb, &ar->rx_anch);
+ if (unlikely(usb_submit_urb(urb, GFP_ATOMIC)))
+ usb_unanchor_urb(urb);
+}
+
+static int carl9170_usb_submit_rx_urb(struct ar9170 *ar, gfp_t gfp)
+{
+ struct urb *urb;
+ int err = 0, runs = 0;
+
+ while ((atomic_read(&ar->rx_anch_urbs) < AR9170_NUM_RX_URBS) &&
+ (runs++ < AR9170_NUM_RX_URBS)) {
+ err = -ENOSPC;
+ urb = usb_get_from_anchor(&ar->rx_pool);
+ if (urb) {
+ usb_anchor_urb(urb, &ar->rx_anch);
+ err = usb_submit_urb(urb, gfp);
+ if (unlikely(err)) {
+ usb_unanchor_urb(urb);
+ usb_anchor_urb(urb, &ar->rx_pool);
+ } else {
+ atomic_dec(&ar->rx_pool_urbs);
+ atomic_inc(&ar->rx_anch_urbs);
+ }
+ usb_free_urb(urb);
+ }
+ }
+
+ return err;
+}
+
+static void carl9170_usb_rx_work(struct ar9170 *ar)
+{
+ struct urb *urb;
+ int i;
+
+ for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) {
+ urb = usb_get_from_anchor(&ar->rx_work);
+ if (!urb)
+ break;
+
+ atomic_dec(&ar->rx_work_urbs);
+ if (IS_INITIALIZED(ar)) {
+ carl9170_rx(ar, urb->transfer_buffer,
+ urb->actual_length);
+ }
+
+ usb_anchor_urb(urb, &ar->rx_pool);
+ atomic_inc(&ar->rx_pool_urbs);
+
+ usb_free_urb(urb);
+
+ carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC);
+ }
+}
+
+void carl9170_usb_handle_tx_err(struct ar9170 *ar)
+{
+ struct urb *urb;
+
+ while ((urb = usb_get_from_anchor(&ar->tx_err))) {
+ struct sk_buff *skb = (void *)urb->context;
+
+ carl9170_tx_drop(ar, skb);
+ carl9170_tx_callback(ar, skb);
+ usb_free_urb(urb);
+ }
+}
+
+static void carl9170_usb_tasklet(unsigned long data)
+{
+ struct ar9170 *ar = (struct ar9170 *) data;
+
+ if (!IS_INITIALIZED(ar))
+ return;
+
+ carl9170_usb_rx_work(ar);
+
+ /*
+ * Strictly speaking: The tx scheduler is not part of the USB system.
+ * But the rx worker returns frames back to the mac80211-stack and
+ * this is the _perfect_ place to generate the next transmissions.
+ */
+ if (IS_STARTED(ar))
+ carl9170_tx_scheduler(ar);
+}
+
+static void carl9170_usb_rx_complete(struct urb *urb)
+{
+ struct ar9170 *ar = (struct ar9170 *)urb->context;
+ int err;
+
+ if (WARN_ON_ONCE(!ar))
+ return;
+
+ atomic_dec(&ar->rx_anch_urbs);
+
+ switch (urb->status) {
+ case 0:
+ /* rx path */
+ usb_anchor_urb(urb, &ar->rx_work);
+ atomic_inc(&ar->rx_work_urbs);
+ break;
+
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ /* handle disconnect events*/
+ return;
+
+ default:
+ /* handle all other errors */
+ usb_anchor_urb(urb, &ar->rx_pool);
+ atomic_inc(&ar->rx_pool_urbs);
+ break;
+ }
+
+ err = carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC);
+ if (unlikely(err)) {
+ /*
+ * usb_submit_rx_urb reported a problem.
+ * In case this is due to a rx buffer shortage,
+ * elevate the tasklet worker priority to
+ * the highest available level.
+ */
+ tasklet_hi_schedule(&ar->usb_tasklet);
+
+ if (atomic_read(&ar->rx_anch_urbs) == 0) {
+ /*
+ * The system is too slow to cope with
+ * the enormous workload. We have simply
+ * run out of active rx urbs and this
+ * unfortunatly leads to an unpredictable
+ * device.
+ */
+
+ carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM);
+ }
+ } else {
+ /*
+ * Using anything less than _high_ priority absolutely
+ * kills the rx performance my UP-System...
+ */
+ tasklet_hi_schedule(&ar->usb_tasklet);
+ }
+}
+
+static struct urb *carl9170_usb_alloc_rx_urb(struct ar9170 *ar, gfp_t gfp)
+{
+ struct urb *urb;
+ void *buf;
+
+ buf = kmalloc(ar->fw.rx_size, gfp);
+ if (!buf)
+ return NULL;
+
+ urb = usb_alloc_urb(0, gfp);
+ if (!urb) {
+ kfree(buf);
+ return NULL;
+ }
+
+ usb_fill_bulk_urb(urb, ar->udev, usb_rcvbulkpipe(ar->udev,
+ AR9170_USB_EP_RX), buf, ar->fw.rx_size,
+ carl9170_usb_rx_complete, ar);
+
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ return urb;
+}
+
+static int carl9170_usb_send_rx_irq_urb(struct ar9170 *ar)
+{
+ struct urb *urb = NULL;
+ void *ibuf;
+ int err = -ENOMEM;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ goto out;
+
+ ibuf = kmalloc(AR9170_USB_EP_CTRL_MAX, GFP_KERNEL);
+ if (!ibuf)
+ goto out;
+
+ usb_fill_int_urb(urb, ar->udev, usb_rcvintpipe(ar->udev,
+ AR9170_USB_EP_IRQ), ibuf, AR9170_USB_EP_CTRL_MAX,
+ carl9170_usb_rx_irq_complete, ar, 1);
+
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ usb_anchor_urb(urb, &ar->rx_anch);
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err)
+ usb_unanchor_urb(urb);
+
+out:
+ usb_free_urb(urb);
+ return err;
+}
+
+static int carl9170_usb_init_rx_bulk_urbs(struct ar9170 *ar)
+{
+ struct urb *urb;
+ int i, err = -EINVAL;
+
+ /*
+ * The driver actively maintains a second shadow
+ * pool for inactive, but fully-prepared rx urbs.
+ *
+ * The pool should help the driver to master huge
+ * workload spikes without running the risk of
+ * undersupplying the hardware or wasting time by
+ * processing rx data (streams) inside the urb
+ * completion (hardirq context).
+ */
+ for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) {
+ urb = carl9170_usb_alloc_rx_urb(ar, GFP_KERNEL);
+ if (!urb) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ usb_anchor_urb(urb, &ar->rx_pool);
+ atomic_inc(&ar->rx_pool_urbs);
+ usb_free_urb(urb);
+ }
+
+ err = carl9170_usb_submit_rx_urb(ar, GFP_KERNEL);
+ if (err)
+ goto err_out;
+
+ /* the device now waiting for the firmware. */
+ carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE);
+ return 0;
+
+err_out:
+
+ usb_scuttle_anchored_urbs(&ar->rx_pool);
+ usb_scuttle_anchored_urbs(&ar->rx_work);
+ usb_kill_anchored_urbs(&ar->rx_anch);
+ return err;
+}
+
+static int carl9170_usb_flush(struct ar9170 *ar)
+{
+ struct urb *urb;
+ int ret, err = 0;
+
+ while ((urb = usb_get_from_anchor(&ar->tx_wait))) {
+ struct sk_buff *skb = (void *)urb->context;
+ carl9170_tx_drop(ar, skb);
+ carl9170_tx_callback(ar, skb);
+ usb_free_urb(urb);
+ }
+
+ ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, HZ);
+ if (ret == 0)
+ err = -ETIMEDOUT;
+
+ /* lets wait a while until the tx - queues are dried out */
+ ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, HZ);
+ if (ret == 0)
+ err = -ETIMEDOUT;
+
+ usb_kill_anchored_urbs(&ar->tx_anch);
+ carl9170_usb_handle_tx_err(ar);
+
+ return err;
+}
+
+static void carl9170_usb_cancel_urbs(struct ar9170 *ar)
+{
+ int err;
+
+ carl9170_set_state(ar, CARL9170_UNKNOWN_STATE);
+
+ err = carl9170_usb_flush(ar);
+ if (err)
+ dev_err(&ar->udev->dev, "stuck tx urbs!\n");
+
+ usb_poison_anchored_urbs(&ar->tx_anch);
+ carl9170_usb_handle_tx_err(ar);
+ usb_poison_anchored_urbs(&ar->rx_anch);
+
+ tasklet_kill(&ar->usb_tasklet);
+
+ usb_scuttle_anchored_urbs(&ar->rx_work);
+ usb_scuttle_anchored_urbs(&ar->rx_pool);
+ usb_scuttle_anchored_urbs(&ar->tx_cmd);
+}
+
+int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd,
+ const bool free_buf)
+{
+ struct urb *urb;
+
+ if (!IS_INITIALIZED(ar))
+ return -EPERM;
+
+ if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4))
+ return -EINVAL;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+ return -ENOMEM;
+
+ usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev,
+ AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4,
+ carl9170_usb_cmd_complete, ar, 1);
+
+ if (free_buf)
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ usb_anchor_urb(urb, &ar->tx_cmd);
+ usb_free_urb(urb);
+
+ return carl9170_usb_submit_cmd_urb(ar);
+}
+
+int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd,
+ unsigned int plen, void *payload, unsigned int outlen, void *out)
+{
+ int err = -ENOMEM;
+
+ if (!IS_ACCEPTING_CMD(ar))
+ return -EIO;
+
+ if (!(cmd & CARL9170_CMD_ASYNC_FLAG))
+ might_sleep();
+
+ ar->cmd.hdr.len = plen;
+ ar->cmd.hdr.cmd = cmd;
+ /* writing multiple regs fills this buffer already */
+ if (plen && payload != (u8 *)(ar->cmd.data))
+ memcpy(ar->cmd.data, payload, plen);
+
+ spin_lock_bh(&ar->cmd_lock);
+ ar->readbuf = (u8 *)out;
+ ar->readlen = outlen;
+ spin_unlock_bh(&ar->cmd_lock);
+
+ err = __carl9170_exec_cmd(ar, &ar->cmd, false);
+
+ if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) {
+ err = wait_for_completion_timeout(&ar->cmd_wait, HZ);
+ if (err == 0) {
+ err = -ETIMEDOUT;
+ goto err_unbuf;
+ }
+
+ if (ar->readlen != outlen) {
+ err = -EMSGSIZE;
+ goto err_unbuf;
+ }
+ }
+
+ return 0;
+
+err_unbuf:
+ /* Maybe the device was removed in the moment we were waiting? */
+ if (IS_STARTED(ar)) {
+ dev_err(&ar->udev->dev, "no command feedback "
+ "received (%d).\n", err);
+
+ /* provide some maybe useful debug information */
+ print_hex_dump_bytes("carl9170 cmd: ", DUMP_PREFIX_NONE,
+ &ar->cmd, plen + 4);
+
+ carl9170_restart(ar, CARL9170_RR_COMMAND_TIMEOUT);
+ }
+
+ /* invalidate to avoid completing the next command prematurely */
+ spin_lock_bh(&ar->cmd_lock);
+ ar->readbuf = NULL;
+ ar->readlen = 0;
+ spin_unlock_bh(&ar->cmd_lock);
+
+ return err;
+}
+
+void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct urb *urb;
+ struct ar9170_stream *tx_stream;
+ void *data;
+ unsigned int len;
+
+ if (!IS_STARTED(ar))
+ goto err_drop;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+ goto err_drop;
+
+ if (ar->fw.tx_stream) {
+ tx_stream = (void *) (skb->data - sizeof(*tx_stream));
+
+ len = skb->len + sizeof(*tx_stream);
+ tx_stream->length = cpu_to_le16(len);
+ tx_stream->tag = cpu_to_le16(AR9170_TX_STREAM_TAG);
+ data = tx_stream;
+ } else {
+ data = skb->data;
+ len = skb->len;
+ }
+
+ usb_fill_bulk_urb(urb, ar->udev, usb_sndbulkpipe(ar->udev,
+ AR9170_USB_EP_TX), data, len,
+ carl9170_usb_tx_data_complete, skb);
+
+ urb->transfer_flags |= URB_ZERO_PACKET;
+
+ usb_anchor_urb(urb, &ar->tx_wait);
+
+ usb_free_urb(urb);
+
+ carl9170_usb_submit_data_urb(ar);
+ return;
+
+err_drop:
+ carl9170_tx_drop(ar, skb);
+ carl9170_tx_callback(ar, skb);
+}
+
+static void carl9170_release_firmware(struct ar9170 *ar)
+{
+ if (ar->fw.fw) {
+ release_firmware(ar->fw.fw);
+ memset(&ar->fw, 0, sizeof(ar->fw));
+ }
+}
+
+void carl9170_usb_stop(struct ar9170 *ar)
+{
+ int ret;
+
+ carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STOPPED);
+
+ ret = carl9170_usb_flush(ar);
+ if (ret)
+ dev_err(&ar->udev->dev, "kill pending tx urbs.\n");
+
+ usb_poison_anchored_urbs(&ar->tx_anch);
+ carl9170_usb_handle_tx_err(ar);
+
+ /* kill any pending command */
+ spin_lock_bh(&ar->cmd_lock);
+ ar->readlen = 0;
+ spin_unlock_bh(&ar->cmd_lock);
+ complete_all(&ar->cmd_wait);
+
+ /* This is required to prevent an early completion on _start */
+ INIT_COMPLETION(ar->cmd_wait);
+
+ /*
+ * 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...
+ */
+}
+
+int carl9170_usb_open(struct ar9170 *ar)
+{
+ usb_unpoison_anchored_urbs(&ar->tx_anch);
+
+ carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE);
+ return 0;
+}
+
+static int carl9170_usb_load_firmware(struct ar9170 *ar)
+{
+ const u8 *data;
+ u8 *buf;
+ unsigned int transfer;
+ size_t len;
+ u32 addr;
+ int err = 0;
+
+ buf = kmalloc(4096, GFP_KERNEL);
+ if (!buf) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ data = ar->fw.fw->data;
+ len = ar->fw.fw->size;
+ addr = ar->fw.address;
+
+ /* this removes the miniboot image */
+ data += ar->fw.offset;
+ len -= ar->fw.offset;
+
+ while (len) {
+ transfer = min_t(unsigned int, len, 4096u);
+ memcpy(buf, data, transfer);
+
+ err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0),
+ 0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
+ addr >> 8, 0, buf, transfer, 100);
+
+ if (err < 0) {
+ kfree(buf);
+ goto err_out;
+ }
+
+ len -= transfer;
+ data += transfer;
+ addr += transfer;
+ }
+ kfree(buf);
+
+ err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0),
+ 0x31 /* FW DL COMPLETE */,
+ 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 200);
+
+ if (wait_for_completion_timeout(&ar->fw_boot_wait, HZ) == 0) {
+ err = -ETIMEDOUT;
+ goto err_out;
+ }
+
+ err = carl9170_echo_test(ar, 0x4a110123);
+ if (err)
+ goto err_out;
+
+ /* firmware restarts cmd counter */
+ ar->cmd_seq = -1;
+
+ return 0;
+
+err_out:
+ dev_err(&ar->udev->dev, "firmware upload failed (%d).\n", err);
+ return err;
+}
+
+int carl9170_usb_restart(struct ar9170 *ar)
+{
+ int err = 0;
+
+ if (ar->intf->condition != USB_INTERFACE_BOUND)
+ return 0;
+
+ /* Disable command response sequence counter. */
+ ar->cmd_seq = -2;
+
+ err = carl9170_reboot(ar);
+
+ carl9170_usb_stop(ar);
+
+ if (err)
+ goto err_out;
+
+ tasklet_schedule(&ar->usb_tasklet);
+
+ /* The reboot procedure can take quite a while to complete. */
+ msleep(1100);
+
+ err = carl9170_usb_open(ar);
+ if (err)
+ goto err_out;
+
+ err = carl9170_usb_load_firmware(ar);
+ if (err)
+ goto err_out;
+
+ return 0;
+
+err_out:
+ carl9170_usb_cancel_urbs(ar);
+ return err;
+}
+
+void carl9170_usb_reset(struct ar9170 *ar)
+{
+ /*
+ * This is the last resort to get the device going again
+ * without any *user replugging action*.
+ *
+ * But there is a catch: usb_reset really is like a physical
+ * *reconnect*. The mac80211 state will be lost in the process.
+ * Therefore a userspace application, which is monitoring
+ * the link must step in.
+ */
+ carl9170_usb_cancel_urbs(ar);
+
+ carl9170_usb_stop(ar);
+
+ usb_queue_reset_device(ar->intf);
+}
+
+static int carl9170_usb_init_device(struct ar9170 *ar)
+{
+ int err;
+
+ err = carl9170_usb_send_rx_irq_urb(ar);
+ if (err)
+ goto err_out;
+
+ err = carl9170_usb_init_rx_bulk_urbs(ar);
+ if (err)
+ goto err_unrx;
+
+ mutex_lock(&ar->mutex);
+ err = carl9170_usb_load_firmware(ar);
+ mutex_unlock(&ar->mutex);
+ if (err)
+ goto err_unrx;
+
+ return 0;
+
+err_unrx:
+ carl9170_usb_cancel_urbs(ar);
+
+err_out:
+ return err;
+}
+
+static void carl9170_usb_firmware_failed(struct ar9170 *ar)
+{
+ struct device *parent = ar->udev->dev.parent;
+ struct usb_device *udev;
+
+ /*
+ * Store a copy of the usb_device pointer locally.
+ * This is because device_release_driver initiates
+ * carl9170_usb_disconnect, which in turn frees our
+ * driver context (ar).
+ */
+ udev = ar->udev;
+
+ complete(&ar->fw_load_wait);
+
+ /* unbind anything failed */
+ if (parent)
+ device_lock(parent);
+
+ device_release_driver(&udev->dev);
+ if (parent)
+ device_unlock(parent);
+
+ usb_put_dev(udev);
+}
+
+static void carl9170_usb_firmware_finish(struct ar9170 *ar)
+{
+ int err;
+
+ err = carl9170_parse_firmware(ar);
+ if (err)
+ goto err_freefw;
+
+ err = carl9170_usb_init_device(ar);
+ if (err)
+ goto err_freefw;
+
+ err = carl9170_usb_open(ar);
+ if (err)
+ goto err_unrx;
+
+ err = carl9170_register(ar);
+
+ carl9170_usb_stop(ar);
+ if (err)
+ goto err_unrx;
+
+ complete(&ar->fw_load_wait);
+ usb_put_dev(ar->udev);
+ return;
+
+err_unrx:
+ carl9170_usb_cancel_urbs(ar);
+
+err_freefw:
+ carl9170_release_firmware(ar);
+ carl9170_usb_firmware_failed(ar);
+}
+
+static void carl9170_usb_firmware_step2(const struct firmware *fw,
+ void *context)
+{
+ struct ar9170 *ar = context;
+
+ if (fw) {
+ ar->fw.fw = fw;
+ carl9170_usb_firmware_finish(ar);
+ return;
+ }
+
+ dev_err(&ar->udev->dev, "firmware not found.\n");
+ carl9170_usb_firmware_failed(ar);
+}
+
+static int carl9170_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct ar9170 *ar;
+ struct usb_device *udev;
+ int err;
+
+ err = usb_reset_device(interface_to_usbdev(intf));
+ if (err)
+ return err;
+
+ ar = carl9170_alloc(sizeof(*ar));
+ if (IS_ERR(ar))
+ return PTR_ERR(ar);
+
+ udev = interface_to_usbdev(intf);
+ usb_get_dev(udev);
+ ar->udev = udev;
+ ar->intf = intf;
+ ar->features = id->driver_info;
+
+ usb_set_intfdata(intf, ar);
+ SET_IEEE80211_DEV(ar->hw, &intf->dev);
+
+ init_usb_anchor(&ar->rx_anch);
+ init_usb_anchor(&ar->rx_pool);
+ init_usb_anchor(&ar->rx_work);
+ init_usb_anchor(&ar->tx_wait);
+ init_usb_anchor(&ar->tx_anch);
+ init_usb_anchor(&ar->tx_cmd);
+ init_usb_anchor(&ar->tx_err);
+ init_completion(&ar->cmd_wait);
+ init_completion(&ar->fw_boot_wait);
+ init_completion(&ar->fw_load_wait);
+ tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet,
+ (unsigned long)ar);
+
+ atomic_set(&ar->tx_cmd_urbs, 0);
+ atomic_set(&ar->tx_anch_urbs, 0);
+ atomic_set(&ar->rx_work_urbs, 0);
+ atomic_set(&ar->rx_anch_urbs, 0);
+ atomic_set(&ar->rx_pool_urbs, 0);
+ ar->cmd_seq = -2;
+
+ usb_get_dev(ar->udev);
+
+ carl9170_set_state(ar, CARL9170_STOPPED);
+
+ return request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME,
+ &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2);
+}
+
+static void carl9170_usb_disconnect(struct usb_interface *intf)
+{
+ struct ar9170 *ar = usb_get_intfdata(intf);
+ struct usb_device *udev;
+
+ if (WARN_ON(!ar))
+ return;
+
+ udev = ar->udev;
+ wait_for_completion(&ar->fw_load_wait);
+
+ if (IS_INITIALIZED(ar)) {
+ carl9170_reboot(ar);
+ carl9170_usb_stop(ar);
+ }
+
+ carl9170_usb_cancel_urbs(ar);
+ carl9170_unregister(ar);
+
+ usb_set_intfdata(intf, NULL);
+
+ carl9170_release_firmware(ar);
+ carl9170_free(ar);
+ usb_put_dev(udev);
+}
+
+#ifdef CONFIG_PM
+static int carl9170_usb_suspend(struct usb_interface *intf,
+ pm_message_t message)
+{
+ struct ar9170 *ar = usb_get_intfdata(intf);
+
+ if (!ar)
+ return -ENODEV;
+
+ carl9170_usb_cancel_urbs(ar);
+
+ /*
+ * firmware automatically reboots for usb suspend.
+ */
+
+ return 0;
+}
+
+static int carl9170_usb_resume(struct usb_interface *intf)
+{
+ struct ar9170 *ar = usb_get_intfdata(intf);
+ int err;
+
+ if (!ar)
+ return -ENODEV;
+
+ usb_unpoison_anchored_urbs(&ar->rx_anch);
+
+ err = carl9170_usb_init_device(ar);
+ if (err)
+ goto err_unrx;
+
+ err = carl9170_usb_open(ar);
+ if (err)
+ goto err_unrx;
+
+ return 0;
+
+err_unrx:
+ carl9170_usb_cancel_urbs(ar);
+
+ return err;
+}
+#endif /* CONFIG_PM */
+
+static struct usb_driver carl9170_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = carl9170_usb_probe,
+ .disconnect = carl9170_usb_disconnect,
+ .id_table = carl9170_usb_ids,
+ .soft_unbind = 1,
+#ifdef CONFIG_PM
+ .suspend = carl9170_usb_suspend,
+ .resume = carl9170_usb_resume,
+#endif /* CONFIG_PM */
+};
+
+static int __init carl9170_usb_init(void)
+{
+ return usb_register(&carl9170_driver);
+}
+
+static void __exit carl9170_usb_exit(void)
+{
+ usb_deregister(&carl9170_driver);
+}
+
+module_init(carl9170_usb_init);
+module_exit(carl9170_usb_exit);
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
new file mode 100644
index 000000000000..ff53f078a0b5
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -0,0 +1,7 @@
+#ifndef __CARL9170_SHARED_VERSION_H
+#define __CARL9170_SHARED_VERSION_H
+#define CARL9170FW_VERSION_YEAR 10
+#define CARL9170FW_VERSION_MONTH 9
+#define CARL9170FW_VERSION_DAY 28
+#define CARL9170FW_VERSION_GIT "1.8.8.3"
+#endif /* __CARL9170_SHARED_VERSION_H */
diff --git a/drivers/net/wireless/ath/carl9170/wlan.h b/drivers/net/wireless/ath/carl9170/wlan.h
new file mode 100644
index 000000000000..24d63b583b6b
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/wlan.h
@@ -0,0 +1,420 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * RX/TX meta descriptor format
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * 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 __CARL9170_SHARED_WLAN_H
+#define __CARL9170_SHARED_WLAN_H
+
+#include "fwcmd.h"
+
+#define AR9170_RX_PHY_RATE_CCK_1M 0x0a
+#define AR9170_RX_PHY_RATE_CCK_2M 0x14
+#define AR9170_RX_PHY_RATE_CCK_5M 0x37
+#define AR9170_RX_PHY_RATE_CCK_11M 0x6e
+
+#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
+
+#define AR9170_RX_STATUS_MODULATION 0x03
+#define AR9170_RX_STATUS_MODULATION_S 0
+#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 0x30
+#define AR9170_RX_STATUS_MPDU_S 4
+#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_STATUS_CONT_AGGR 0x40
+#define AR9170_RX_STATUS_TOTAL_ERROR 0x80
+
+#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
+
+/* these are either-or */
+#define AR9170_TX_MAC_PROT_RTS 0x0001
+#define AR9170_TX_MAC_PROT_CTS 0x0002
+#define AR9170_TX_MAC_PROT 0x0003
+
+#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_S 10
+#define AR9170_TX_MAC_QOS 0x0c00
+#define AR9170_TX_MAC_DISABLE_TXOP 0x1000
+#define AR9170_TX_MAC_TXOP_RIFS 0x2000
+#define AR9170_TX_MAC_IMM_BA 0x4000
+
+/* either-or */
+#define AR9170_TX_PHY_MOD_CCK 0x00000000
+#define AR9170_TX_PHY_MOD_OFDM 0x00000001
+#define AR9170_TX_PHY_MOD_HT 0x00000002
+
+/* depends on modulation */
+#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004
+#define AR9170_TX_PHY_GREENFIELD 0x00000004
+
+#define AR9170_TX_PHY_BW_S 3
+#define AR9170_TX_PHY_BW (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_S 6
+#define AR9170_TX_PHY_TX_HEAVY_CLIP (7 << \
+ AR9170_TX_PHY_TX_HEAVY_CLIP_S)
+
+#define AR9170_TX_PHY_TX_PWR_S 9
+#define AR9170_TX_PHY_TX_PWR (0x3f << \
+ AR9170_TX_PHY_TX_PWR_S)
+
+#define AR9170_TX_PHY_TXCHAIN_S 15
+#define AR9170_TX_PHY_TXCHAIN (7 << \
+ AR9170_TX_PHY_TXCHAIN_S)
+#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_S 18
+#define AR9170_TX_PHY_MCS (0x7f << \
+ AR9170_TX_PHY_MCS_S)
+
+#define AR9170_TX_PHY_RATE_CCK_1M 0x0
+#define AR9170_TX_PHY_RATE_CCK_2M 0x1
+#define AR9170_TX_PHY_RATE_CCK_5M 0x2
+#define AR9170_TX_PHY_RATE_CCK_11M 0x3
+
+/* same as AR9170_RX_PHY_RATE */
+#define AR9170_TXRX_PHY_RATE_OFDM_6M 0xb
+#define AR9170_TXRX_PHY_RATE_OFDM_9M 0xf
+#define AR9170_TXRX_PHY_RATE_OFDM_12M 0xa
+#define AR9170_TXRX_PHY_RATE_OFDM_18M 0xe
+#define AR9170_TXRX_PHY_RATE_OFDM_24M 0x9
+#define AR9170_TXRX_PHY_RATE_OFDM_36M 0xd
+#define AR9170_TXRX_PHY_RATE_OFDM_48M 0x8
+#define AR9170_TXRX_PHY_RATE_OFDM_54M 0xc
+
+#define AR9170_TXRX_PHY_RATE_HT_MCS0 0x0
+#define AR9170_TXRX_PHY_RATE_HT_MCS1 0x1
+#define AR9170_TXRX_PHY_RATE_HT_MCS2 0x2
+#define AR9170_TXRX_PHY_RATE_HT_MCS3 0x3
+#define AR9170_TXRX_PHY_RATE_HT_MCS4 0x4
+#define AR9170_TXRX_PHY_RATE_HT_MCS5 0x5
+#define AR9170_TXRX_PHY_RATE_HT_MCS6 0x6
+#define AR9170_TXRX_PHY_RATE_HT_MCS7 0x7
+#define AR9170_TXRX_PHY_RATE_HT_MCS8 0x8
+#define AR9170_TXRX_PHY_RATE_HT_MCS9 0x9
+#define AR9170_TXRX_PHY_RATE_HT_MCS10 0xa
+#define AR9170_TXRX_PHY_RATE_HT_MCS11 0xb
+#define AR9170_TXRX_PHY_RATE_HT_MCS12 0xc
+#define AR9170_TXRX_PHY_RATE_HT_MCS13 0xd
+#define AR9170_TXRX_PHY_RATE_HT_MCS14 0xe
+#define AR9170_TXRX_PHY_RATE_HT_MCS15 0xf
+
+#define AR9170_TX_PHY_SHORT_GI 0x80000000
+
+#ifdef __CARL9170FW__
+struct ar9170_tx_hw_mac_control {
+ union {
+ struct {
+ /*
+ * Beware of compiler bugs in all gcc pre 4.4!
+ */
+
+ u8 erp_prot:2;
+ u8 no_ack:1;
+ u8 backoff:1;
+ u8 burst:1;
+ u8 ampdu:1;
+
+ u8 enc_mode:2;
+
+ u8 hw_mmic:1;
+ u8 hw_duration:1;
+
+ u8 qos_queue:2;
+
+ u8 disable_txop:1;
+ u8 txop_rifs:1;
+
+ u8 ba_end:1;
+ u8 probe:1;
+ } __packed;
+
+ __le16 set;
+ } __packed;
+} __packed;
+
+struct ar9170_tx_hw_phy_control {
+ union {
+ struct {
+ /*
+ * Beware of compiler bugs in all gcc pre 4.4!
+ */
+
+ u8 modulation:2;
+ u8 preamble:1;
+ u8 bandwidth:2;
+ u8:1;
+ u8 heavy_clip:3;
+ u8 tx_power:6;
+ u8 chains:3;
+ u8 mcs:7;
+ u8:6;
+ u8 short_gi:1;
+ } __packed;
+
+ __le32 set;
+ } __packed;
+} __packed;
+
+struct ar9170_tx_rate_info {
+ u8 tries:3;
+ u8 erp_prot:2;
+ u8 ampdu:1;
+ u8 free:2; /* free for use (e.g.:RIFS/TXOP/AMPDU) */
+} __packed;
+
+struct carl9170_tx_superdesc {
+ __le16 len;
+ u8 rix;
+ u8 cnt;
+ u8 cookie;
+ u8 ampdu_density:3;
+ u8 ampdu_factor:2;
+ u8 ampdu_commit_density:1;
+ u8 ampdu_commit_factor:1;
+ u8 ampdu_unused_bit:1;
+ u8 queue:2;
+ u8 reserved:1;
+ u8 vif_id:3;
+ u8 fill_in_tsf:1;
+ u8 cab:1;
+ u8 padding2;
+ struct ar9170_tx_rate_info ri[CARL9170_TX_MAX_RATES];
+ struct ar9170_tx_hw_phy_control rr[CARL9170_TX_MAX_RETRY_RATES];
+} __packed;
+
+struct ar9170_tx_hwdesc {
+ __le16 length;
+ struct ar9170_tx_hw_mac_control mac;
+ struct ar9170_tx_hw_phy_control phy;
+} __packed;
+
+struct ar9170_tx_frame {
+ struct ar9170_tx_hwdesc hdr;
+
+ union {
+ struct ieee80211_hdr i3e;
+ u8 payload[0];
+ } data;
+} __packed;
+
+struct carl9170_tx_superframe {
+ struct carl9170_tx_superdesc s;
+ struct ar9170_tx_frame f;
+} __packed;
+
+#endif /* __CARL9170FW__ */
+
+struct _ar9170_tx_hwdesc {
+ __le16 length;
+ __le16 mac_control;
+ __le32 phy_control;
+} __packed;
+
+#define CARL9170_TX_SUPER_AMPDU_DENSITY_S 0
+#define CARL9170_TX_SUPER_AMPDU_DENSITY 0x7
+#define CARL9170_TX_SUPER_AMPDU_FACTOR 0x18
+#define CARL9170_TX_SUPER_AMPDU_FACTOR_S 3
+#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY 0x20
+#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY_S 5
+#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR 0x40
+#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR_S 6
+
+#define CARL9170_TX_SUPER_MISC_QUEUE 0x3
+#define CARL9170_TX_SUPER_MISC_QUEUE_S 0
+#define CARL9170_TX_SUPER_MISC_VIF_ID 0x38
+#define CARL9170_TX_SUPER_MISC_VIF_ID_S 3
+#define CARL9170_TX_SUPER_MISC_FILL_IN_TSF 0x40
+#define CARL9170_TX_SUPER_MISC_CAB 0x80
+
+#define CARL9170_TX_SUPER_RI_TRIES 0x7
+#define CARL9170_TX_SUPER_RI_TRIES_S 0
+#define CARL9170_TX_SUPER_RI_ERP_PROT 0x18
+#define CARL9170_TX_SUPER_RI_ERP_PROT_S 3
+#define CARL9170_TX_SUPER_RI_AMPDU 0x20
+#define CARL9170_TX_SUPER_RI_AMPDU_S 5
+
+struct _carl9170_tx_superdesc {
+ __le16 len;
+ u8 rix;
+ u8 cnt;
+ u8 cookie;
+ u8 ampdu_settings;
+ u8 misc;
+ u8 padding;
+ u8 ri[CARL9170_TX_MAX_RATES];
+ __le32 rr[CARL9170_TX_MAX_RETRY_RATES];
+} __packed;
+
+struct _carl9170_tx_superframe {
+ struct _carl9170_tx_superdesc s;
+ struct _ar9170_tx_hwdesc f;
+ u8 frame_data[0];
+} __packed;
+
+#define CARL9170_TX_SUPERDESC_LEN 24
+#define AR9170_TX_HWDESC_LEN 8
+#define CARL9170_TX_SUPERFRAME_LEN (CARL9170_TX_SUPERDESC_LEN + \
+ AR9170_TX_HWDESC_LEN)
+
+struct ar9170_rx_head {
+ u8 plcp[12];
+} __packed;
+
+#define AR9170_RX_HEAD_LEN 12
+
+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;
+
+#define AR9170_RX_PHYSTATUS_LEN 20
+
+struct ar9170_rx_macstatus {
+ u8 SAidx, DAidx;
+ u8 error;
+ u8 status;
+} __packed;
+
+#define AR9170_RX_MACSTATUS_LEN 4
+
+struct ar9170_rx_frame_single {
+ struct ar9170_rx_head phy_head;
+ struct ieee80211_hdr i3e;
+ struct ar9170_rx_phystatus phy_tail;
+ struct ar9170_rx_macstatus macstatus;
+} __packed;
+
+struct ar9170_rx_frame_head {
+ struct ar9170_rx_head phy_head;
+ struct ieee80211_hdr i3e;
+ struct ar9170_rx_macstatus macstatus;
+} __packed;
+
+struct ar9170_rx_frame_middle {
+ struct ieee80211_hdr i3e;
+ struct ar9170_rx_macstatus macstatus;
+} __packed;
+
+struct ar9170_rx_frame_tail {
+ struct ieee80211_hdr i3e;
+ struct ar9170_rx_phystatus phy_tail;
+ struct ar9170_rx_macstatus macstatus;
+} __packed;
+
+struct ar9170_rx_frame {
+ union {
+ struct ar9170_rx_frame_single single;
+ struct ar9170_rx_frame_head head;
+ struct ar9170_rx_frame_middle middle;
+ struct ar9170_rx_frame_tail tail;
+ } __packed;
+} __packed;
+
+static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
+{
+ return (t->SAidx & 0xc0) >> 4 |
+ (t->DAidx & 0xc0) >> 6;
+}
+
+enum ar9170_txq {
+ AR9170_TXQ_BE,
+
+ AR9170_TXQ_VI,
+ AR9170_TXQ_VO,
+ AR9170_TXQ_BK,
+
+ __AR9170_NUM_TXQ,
+};
+
+static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 2, 1, 0, 3 };
+
+#define AR9170_TXQ_DEPTH 32
+
+#endif /* __CARL9170_SHARED_WLAN_H */
diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c
index 53e77bd131b9..dacfb234f491 100644
--- a/drivers/net/wireless/ath/debug.c
+++ b/drivers/net/wireless/ath/debug.c
@@ -30,3 +30,32 @@ void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
va_end(args);
}
EXPORT_SYMBOL(ath_print);
+
+const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+{
+ switch (opmode) {
+ case NL80211_IFTYPE_UNSPECIFIED:
+ return "UNSPEC";
+ case NL80211_IFTYPE_ADHOC:
+ return "ADHOC";
+ case NL80211_IFTYPE_STATION:
+ return "STATION";
+ case NL80211_IFTYPE_AP:
+ return "AP";
+ case NL80211_IFTYPE_AP_VLAN:
+ return "AP-VLAN";
+ case NL80211_IFTYPE_WDS:
+ return "WDS";
+ case NL80211_IFTYPE_MONITOR:
+ return "MONITOR";
+ case NL80211_IFTYPE_MESH_POINT:
+ return "MESH";
+ case NL80211_IFTYPE_P2P_CLIENT:
+ return "P2P-CLIENT";
+ case NL80211_IFTYPE_P2P_GO:
+ return "P2P-GO";
+ default:
+ return "UNKNOWN";
+ }
+}
+EXPORT_SYMBOL(ath_opmode_to_string);
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index 873bf526e11f..64e4af2c2887 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -36,6 +36,7 @@
* @ATH_DBG_PS: power save processing
* @ATH_DBG_HWTIMER: hardware timer handling
* @ATH_DBG_BTCOEX: bluetooth coexistance
+ * @ATH_DBG_BSTUCK: stuck beacons
* @ATH_DBG_ANY: enable all debugging
*
* The debug level is used to control the amount and type of debugging output
@@ -60,6 +61,7 @@ enum ATH_DEBUG {
ATH_DBG_HWTIMER = 0x00001000,
ATH_DBG_BTCOEX = 0x00002000,
ATH_DBG_WMI = 0x00004000,
+ ATH_DBG_BSTUCK = 0x00008000,
ATH_DBG_ANY = 0xffffffff
};
@@ -75,4 +77,14 @@ ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
}
#endif /* CONFIG_ATH_DEBUG */
+/** Returns string describing opmode, or NULL if unknown mode. */
+#ifdef CONFIG_ATH_DEBUG
+const char *ath_opmode_to_string(enum nl80211_iftype opmode);
+#else
+static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+{
+ return "UNKNOWN";
+}
+#endif
+
#endif /* ATH_DEBUG_H */
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
index a8f81ea09f14..183c28281385 100644
--- a/drivers/net/wireless/ath/hw.c
+++ b/drivers/net/wireless/ath/hw.c
@@ -124,3 +124,62 @@ void ath_hw_setbssidmask(struct ath_common *common)
REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
}
EXPORT_SYMBOL(ath_hw_setbssidmask);
+
+
+/**
+ * ath_hw_cycle_counters_update - common function to update cycle counters
+ *
+ * @common: the ath_common struct for the device.
+ *
+ * This function is used to update all cycle counters in one place.
+ * It has to be called while holding common->cc_lock!
+ */
+void ath_hw_cycle_counters_update(struct ath_common *common)
+{
+ u32 cycles, busy, rx, tx;
+ void *ah = common->ah;
+
+ /* freeze */
+ REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC);
+
+ /* read */
+ cycles = REG_READ(ah, AR_CCCNT);
+ busy = REG_READ(ah, AR_RCCNT);
+ rx = REG_READ(ah, AR_RFCNT);
+ tx = REG_READ(ah, AR_TFCNT);
+
+ /* clear */
+ REG_WRITE(ah, 0, AR_CCCNT);
+ REG_WRITE(ah, 0, AR_RFCNT);
+ REG_WRITE(ah, 0, AR_RCCNT);
+ REG_WRITE(ah, 0, AR_TFCNT);
+
+ /* unfreeze */
+ REG_WRITE(ah, 0, AR_MIBC);
+
+ /* update all cycle counters here */
+ common->cc_ani.cycles += cycles;
+ common->cc_ani.rx_busy += busy;
+ common->cc_ani.rx_frame += rx;
+ common->cc_ani.tx_frame += tx;
+
+ common->cc_survey.cycles += cycles;
+ common->cc_survey.rx_busy += busy;
+ common->cc_survey.rx_frame += rx;
+ common->cc_survey.tx_frame += tx;
+}
+EXPORT_SYMBOL(ath_hw_cycle_counters_update);
+
+int32_t ath_hw_get_listen_time(struct ath_common *common)
+{
+ struct ath_cycle_counters *cc = &common->cc_ani;
+ int32_t listen_time;
+
+ listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) /
+ (common->clockrate * 1000);
+
+ memset(cc, 0, sizeof(*cc));
+
+ return listen_time;
+}
+EXPORT_SYMBOL(ath_hw_get_listen_time);
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
new file mode 100644
index 000000000000..bd21a4d82085
--- /dev/null
+++ b/drivers/net/wireless/ath/key.c
@@ -0,0 +1,568 @@
+/*
+ * Copyright (c) 2009 Atheros Communications Inc.
+ * Copyright (c) 2010 Bruno Randolf <br1@einfach.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <asm/unaligned.h>
+#include <net/mac80211.h>
+
+#include "ath.h"
+#include "reg.h"
+#include "debug.h"
+
+#define REG_READ (common->ops->read)
+#define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg)
+
+#define IEEE80211_WEP_NKID 4 /* number of key ids */
+
+/************************/
+/* Key Cache Management */
+/************************/
+
+bool ath_hw_keyreset(struct ath_common *common, u16 entry)
+{
+ u32 keyType;
+ void *ah = common->ah;
+
+ if (entry >= common->keymax) {
+ ath_print(common, ATH_DBG_FATAL,
+ "keychache entry %u out of range\n", entry);
+ return false;
+ }
+
+ keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
+
+ REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
+ REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
+
+ if (keyType == AR_KEYTABLE_TYPE_TKIP) {
+ u16 micentry = entry + 64;
+
+ REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(ath_hw_keyreset);
+
+bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
+{
+ u32 macHi, macLo;
+ u32 unicast_flag = AR_KEYTABLE_VALID;
+ void *ah = common->ah;
+
+ if (entry >= common->keymax) {
+ ath_print(common, ATH_DBG_FATAL,
+ "keychache entry %u out of range\n", entry);
+ return false;
+ }
+
+ if (mac != NULL) {
+ /*
+ * AR_KEYTABLE_VALID indicates that the address is a unicast
+ * address, which must match the transmitter address for
+ * decrypting frames.
+ * Not setting this bit allows the hardware to use the key
+ * for multicast frame decryption.
+ */
+ if (mac[0] & 0x01)
+ unicast_flag = 0;
+
+ macHi = (mac[5] << 8) | mac[4];
+ macLo = (mac[3] << 24) |
+ (mac[2] << 16) |
+ (mac[1] << 8) |
+ mac[0];
+ macLo >>= 1;
+ macLo |= (macHi & 1) << 31;
+ macHi >>= 1;
+ } else {
+ macLo = macHi = 0;
+ }
+ REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
+ REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
+
+ return true;
+}
+
+bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
+ const struct ath_keyval *k,
+ const u8 *mac)
+{
+ void *ah = common->ah;
+ u32 key0, key1, key2, key3, key4;
+ u32 keyType;
+
+ if (entry >= common->keymax) {
+ ath_print(common, ATH_DBG_FATAL,
+ "keycache entry %u out of range\n", entry);
+ return false;
+ }
+
+ switch (k->kv_type) {
+ case ATH_CIPHER_AES_OCB:
+ keyType = AR_KEYTABLE_TYPE_AES;
+ break;
+ case ATH_CIPHER_AES_CCM:
+ if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) {
+ ath_print(common, ATH_DBG_ANY,
+ "AES-CCM not supported by this mac rev\n");
+ return false;
+ }
+ keyType = AR_KEYTABLE_TYPE_CCM;
+ break;
+ case ATH_CIPHER_TKIP:
+ keyType = AR_KEYTABLE_TYPE_TKIP;
+ if (entry + 64 >= common->keymax) {
+ ath_print(common, ATH_DBG_ANY,
+ "entry %u inappropriate for TKIP\n", entry);
+ return false;
+ }
+ break;
+ case ATH_CIPHER_WEP:
+ if (k->kv_len < WLAN_KEY_LEN_WEP40) {
+ ath_print(common, ATH_DBG_ANY,
+ "WEP key length %u too small\n", k->kv_len);
+ return false;
+ }
+ if (k->kv_len <= WLAN_KEY_LEN_WEP40)
+ keyType = AR_KEYTABLE_TYPE_40;
+ else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
+ keyType = AR_KEYTABLE_TYPE_104;
+ else
+ keyType = AR_KEYTABLE_TYPE_128;
+ break;
+ case ATH_CIPHER_CLR:
+ keyType = AR_KEYTABLE_TYPE_CLR;
+ break;
+ default:
+ ath_print(common, ATH_DBG_FATAL,
+ "cipher %u not supported\n", k->kv_type);
+ return false;
+ }
+
+ key0 = get_unaligned_le32(k->kv_val + 0);
+ key1 = get_unaligned_le16(k->kv_val + 4);
+ key2 = get_unaligned_le32(k->kv_val + 6);
+ key3 = get_unaligned_le16(k->kv_val + 10);
+ key4 = get_unaligned_le32(k->kv_val + 12);
+ if (k->kv_len <= WLAN_KEY_LEN_WEP104)
+ key4 &= 0xff;
+
+ /*
+ * Note: Key cache registers access special memory area that requires
+ * two 32-bit writes to actually update the values in the internal
+ * memory. Consequently, the exact order and pairs used here must be
+ * maintained.
+ */
+
+ if (keyType == AR_KEYTABLE_TYPE_TKIP) {
+ u16 micentry = entry + 64;
+
+ /*
+ * Write inverted key[47:0] first to avoid Michael MIC errors
+ * on frames that could be sent or received at the same time.
+ * The correct key will be written in the end once everything
+ * else is ready.
+ */
+ REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
+
+ /* Write key[95:48] */
+ REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
+ REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+ /* Write key[127:96] and key type */
+ REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
+ REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+
+ /* Write MAC address for the entry */
+ (void) ath_hw_keysetmac(common, entry, mac);
+
+ if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
+ /*
+ * TKIP uses two key cache entries:
+ * Michael MIC TX/RX keys in the same key cache entry
+ * (idx = main index + 64):
+ * key0 [31:0] = RX key [31:0]
+ * key1 [15:0] = TX key [31:16]
+ * key1 [31:16] = reserved
+ * key2 [31:0] = RX key [63:32]
+ * key3 [15:0] = TX key [15:0]
+ * key3 [31:16] = reserved
+ * key4 [31:0] = TX key [63:32]
+ */
+ u32 mic0, mic1, mic2, mic3, mic4;
+
+ mic0 = get_unaligned_le32(k->kv_mic + 0);
+ mic2 = get_unaligned_le32(k->kv_mic + 4);
+ mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
+ mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
+ mic4 = get_unaligned_le32(k->kv_txmic + 4);
+
+ /* Write RX[31:0] and TX[31:16] */
+ REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
+
+ /* Write RX[63:32] and TX[15:0] */
+ REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
+ REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
+
+ /* Write TX[63:32] and keyType(reserved) */
+ REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
+ REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+ AR_KEYTABLE_TYPE_CLR);
+
+ } else {
+ /*
+ * TKIP uses four key cache entries (two for group
+ * keys):
+ * Michael MIC TX/RX keys are in different key cache
+ * entries (idx = main index + 64 for TX and
+ * main index + 32 + 96 for RX):
+ * key0 [31:0] = TX/RX MIC key [31:0]
+ * key1 [31:0] = reserved
+ * key2 [31:0] = TX/RX MIC key [63:32]
+ * key3 [31:0] = reserved
+ * key4 [31:0] = reserved
+ *
+ * Upper layer code will call this function separately
+ * for TX and RX keys when these registers offsets are
+ * used.
+ */
+ u32 mic0, mic2;
+
+ mic0 = get_unaligned_le32(k->kv_mic + 0);
+ mic2 = get_unaligned_le32(k->kv_mic + 4);
+
+ /* Write MIC key[31:0] */
+ REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+
+ /* Write MIC key[63:32] */
+ REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
+ REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+
+ /* Write TX[63:32] and keyType(reserved) */
+ REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+ AR_KEYTABLE_TYPE_CLR);
+ }
+
+ /* MAC address registers are reserved for the MIC entry */
+ REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
+ REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
+
+ /*
+ * Write the correct (un-inverted) key[47:0] last to enable
+ * TKIP now that all other registers are set with correct
+ * values.
+ */
+ REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+ } else {
+ /* Write key[47:0] */
+ REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
+ REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+
+ /* Write key[95:48] */
+ REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
+ REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+ /* Write key[127:96] and key type */
+ REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
+ REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+
+ /* Write MAC address for the entry */
+ (void) ath_hw_keysetmac(common, entry, mac);
+ }
+
+ return true;
+}
+
+static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
+ struct ath_keyval *hk, const u8 *addr,
+ bool authenticator)
+{
+ const u8 *key_rxmic;
+ const u8 *key_txmic;
+
+ key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
+ key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
+
+ if (addr == NULL) {
+ /*
+ * Group key installation - only two key cache entries are used
+ * regardless of splitmic capability since group key is only
+ * used either for TX or RX.
+ */
+ if (authenticator) {
+ memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
+ memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
+ } else {
+ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+ memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
+ }
+ return ath_hw_set_keycache_entry(common, keyix, hk, addr);
+ }
+ if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
+ /* TX and RX keys share the same key cache entry. */
+ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+ memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
+ return ath_hw_set_keycache_entry(common, keyix, hk, addr);
+ }
+
+ /* Separate key cache entries for TX and RX */
+
+ /* TX key goes at first index, RX key at +32. */
+ memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
+ if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) {
+ /* TX MIC entry failed. No need to proceed further */
+ ath_print(common, ATH_DBG_FATAL,
+ "Setting TX MIC Key Failed\n");
+ return 0;
+ }
+
+ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+ /* XXX delete tx key on failure? */
+ return ath_hw_set_keycache_entry(common, keyix + 32, hk, addr);
+}
+
+static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
+{
+ int i;
+
+ for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
+ if (test_bit(i, common->keymap) ||
+ test_bit(i + 64, common->keymap))
+ continue; /* At least one part of TKIP key allocated */
+ if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) &&
+ (test_bit(i + 32, common->keymap) ||
+ test_bit(i + 64 + 32, common->keymap)))
+ continue; /* At least one part of TKIP key allocated */
+
+ /* Found a free slot for a TKIP key */
+ return i;
+ }
+ return -1;
+}
+
+static int ath_reserve_key_cache_slot(struct ath_common *common,
+ u32 cipher)
+{
+ int i;
+
+ if (cipher == WLAN_CIPHER_SUITE_TKIP)
+ return ath_reserve_key_cache_slot_tkip(common);
+
+ /* First, try to find slots that would not be available for TKIP. */
+ if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
+ for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
+ if (!test_bit(i, common->keymap) &&
+ (test_bit(i + 32, common->keymap) ||
+ test_bit(i + 64, common->keymap) ||
+ test_bit(i + 64 + 32, common->keymap)))
+ return i;
+ if (!test_bit(i + 32, common->keymap) &&
+ (test_bit(i, common->keymap) ||
+ test_bit(i + 64, common->keymap) ||
+ test_bit(i + 64 + 32, common->keymap)))
+ return i + 32;
+ if (!test_bit(i + 64, common->keymap) &&
+ (test_bit(i , common->keymap) ||
+ test_bit(i + 32, common->keymap) ||
+ test_bit(i + 64 + 32, common->keymap)))
+ return i + 64;
+ if (!test_bit(i + 64 + 32, common->keymap) &&
+ (test_bit(i, common->keymap) ||
+ test_bit(i + 32, common->keymap) ||
+ test_bit(i + 64, common->keymap)))
+ return i + 64 + 32;
+ }
+ } else {
+ for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
+ if (!test_bit(i, common->keymap) &&
+ test_bit(i + 64, common->keymap))
+ return i;
+ if (test_bit(i, common->keymap) &&
+ !test_bit(i + 64, common->keymap))
+ return i + 64;
+ }
+ }
+
+ /* No partially used TKIP slots, pick any available slot */
+ for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
+ /* Do not allow slots that could be needed for TKIP group keys
+ * to be used. This limitation could be removed if we know that
+ * TKIP will not be used. */
+ if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
+ continue;
+ if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
+ if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
+ continue;
+ if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
+ continue;
+ }
+
+ if (!test_bit(i, common->keymap))
+ return i; /* Found a free slot for a key */
+ }
+
+ /* No free slot found */
+ return -1;
+}
+
+/*
+ * Configure encryption in the HW.
+ */
+int ath_key_config(struct ath_common *common,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct ath_keyval hk;
+ const u8 *mac = NULL;
+ u8 gmac[ETH_ALEN];
+ int ret = 0;
+ int idx;
+
+ memset(&hk, 0, sizeof(hk));
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ hk.kv_type = ATH_CIPHER_WEP;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ hk.kv_type = ATH_CIPHER_TKIP;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ hk.kv_type = ATH_CIPHER_AES_CCM;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ hk.kv_len = key->keylen;
+ memcpy(hk.kv_val, key->key, key->keylen);
+
+ if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+ switch (vif->type) {
+ case NL80211_IFTYPE_AP:
+ memcpy(gmac, vif->addr, ETH_ALEN);
+ gmac[0] |= 0x01;
+ mac = gmac;
+ idx = ath_reserve_key_cache_slot(common, key->cipher);
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ if (!sta) {
+ idx = key->keyidx;
+ break;
+ }
+ memcpy(gmac, sta->addr, ETH_ALEN);
+ gmac[0] |= 0x01;
+ mac = gmac;
+ idx = ath_reserve_key_cache_slot(common, key->cipher);
+ break;
+ default:
+ idx = key->keyidx;
+ break;
+ }
+ } else if (key->keyidx) {
+ if (WARN_ON(!sta))
+ return -EOPNOTSUPP;
+ mac = sta->addr;
+
+ if (vif->type != NL80211_IFTYPE_AP) {
+ /* Only keyidx 0 should be used with unicast key, but
+ * allow this for client mode for now. */
+ idx = key->keyidx;
+ } else
+ return -EIO;
+ } else {
+ if (WARN_ON(!sta))
+ return -EOPNOTSUPP;
+ mac = sta->addr;
+
+ idx = ath_reserve_key_cache_slot(common, key->cipher);
+ }
+
+ if (idx < 0)
+ return -ENOSPC; /* no free key cache entries */
+
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
+ ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
+ vif->type == NL80211_IFTYPE_AP);
+ else
+ ret = ath_hw_set_keycache_entry(common, idx, &hk, mac);
+
+ if (!ret)
+ return -EIO;
+
+ set_bit(idx, common->keymap);
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
+ set_bit(idx + 64, common->keymap);
+ set_bit(idx, common->tkip_keymap);
+ set_bit(idx + 64, common->tkip_keymap);
+ if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
+ set_bit(idx + 32, common->keymap);
+ set_bit(idx + 64 + 32, common->keymap);
+ set_bit(idx + 32, common->tkip_keymap);
+ set_bit(idx + 64 + 32, common->tkip_keymap);
+ }
+ }
+
+ return idx;
+}
+EXPORT_SYMBOL(ath_key_config);
+
+/*
+ * Delete Key.
+ */
+void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key)
+{
+ ath_hw_keyreset(common, key->hw_key_idx);
+ if (key->hw_key_idx < IEEE80211_WEP_NKID)
+ return;
+
+ clear_bit(key->hw_key_idx, common->keymap);
+ if (key->cipher != WLAN_CIPHER_SUITE_TKIP)
+ return;
+
+ clear_bit(key->hw_key_idx + 64, common->keymap);
+
+ clear_bit(key->hw_key_idx, common->tkip_keymap);
+ clear_bit(key->hw_key_idx + 64, common->tkip_keymap);
+
+ if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
+ ath_hw_keyreset(common, key->hw_key_idx + 32);
+ clear_bit(key->hw_key_idx + 32, common->keymap);
+ clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
+
+ clear_bit(key->hw_key_idx + 32, common->tkip_keymap);
+ clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap);
+ }
+}
+EXPORT_SYMBOL(ath_key_delete);
diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h
index dfe1fbec24f5..298e53f3fa48 100644
--- a/drivers/net/wireless/ath/reg.h
+++ b/drivers/net/wireless/ath/reg.h
@@ -17,6 +17,12 @@
#ifndef ATH_REGISTERS_H
#define ATH_REGISTERS_H
+#define AR_MIBC 0x0040
+#define AR_MIBC_COW 0x00000001
+#define AR_MIBC_FMC 0x00000002
+#define AR_MIBC_CMC 0x00000004
+#define AR_MIBC_MCS 0x00000008
+
/*
* BSSID mask registers. See ath_hw_set_bssid_mask()
* for detailed documentation about these registers.
@@ -24,4 +30,32 @@
#define AR_BSSMSKL 0x80e0
#define AR_BSSMSKU 0x80e4
+#define AR_TFCNT 0x80ec
+#define AR_RFCNT 0x80f0
+#define AR_RCCNT 0x80f4
+#define AR_CCCNT 0x80f8
+
+#define AR_KEYTABLE_0 0x8800
+#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32))
+#define AR_KEY_CACHE_SIZE 128
+#define AR_RSVD_KEYTABLE_ENTRIES 4
+#define AR_KEY_TYPE 0x00000007
+#define AR_KEYTABLE_TYPE_40 0x00000000
+#define AR_KEYTABLE_TYPE_104 0x00000001
+#define AR_KEYTABLE_TYPE_128 0x00000003
+#define AR_KEYTABLE_TYPE_TKIP 0x00000004
+#define AR_KEYTABLE_TYPE_AES 0x00000005
+#define AR_KEYTABLE_TYPE_CCM 0x00000006
+#define AR_KEYTABLE_TYPE_CLR 0x00000007
+#define AR_KEYTABLE_ANT 0x00000008
+#define AR_KEYTABLE_VALID 0x00008000
+#define AR_KEYTABLE_KEY0(_n) (AR_KEYTABLE(_n) + 0)
+#define AR_KEYTABLE_KEY1(_n) (AR_KEYTABLE(_n) + 4)
+#define AR_KEYTABLE_KEY2(_n) (AR_KEYTABLE(_n) + 8)
+#define AR_KEYTABLE_KEY3(_n) (AR_KEYTABLE(_n) + 12)
+#define AR_KEYTABLE_KEY4(_n) (AR_KEYTABLE(_n) + 16)
+#define AR_KEYTABLE_TYPE(_n) (AR_KEYTABLE(_n) + 20)
+#define AR_KEYTABLE_MAC0(_n) (AR_KEYTABLE(_n) + 24)
+#define AR_KEYTABLE_MAC1(_n) (AR_KEYTABLE(_n) + 28)
+
#endif /* ATH_REGISTERS_H */
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 5e83b6f0a3a0..69d4af09a6cb 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -1,6 +1,8 @@
b43-y += main.o
b43-y += tables.o
b43-$(CONFIG_B43_NPHY) += tables_nphy.o
+b43-$(CONFIG_B43_NPHY) += radio_2055.o
+b43-$(CONFIG_B43_NPHY) += radio_2056.o
b43-y += phy_common.o
b43-y += phy_g.o
b43-y += phy_a.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 8674a99356af..72821c456b02 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -186,7 +186,8 @@ enum {
#define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */
#define B43_SHM_SH_RFRXSP1 0x0072 /* RF RX SP Register 1 */
#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */
-#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5Ghz channel */
+#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */
+#define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */
#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */
/* TSSI information */
#define B43_SHM_SH_TSSI_CCK 0x0058 /* TSSI for last 4 CCK frames (32bit) */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 20631ae2ddd7..a1186525c70d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2280,6 +2280,7 @@ out:
static int b43_upload_microcode(struct b43_wldev *dev)
{
+ struct wiphy *wiphy = dev->wl->hw->wiphy;
const size_t hdr_len = sizeof(struct b43_fw_header);
const __be32 *data;
unsigned int i, len;
@@ -2405,6 +2406,10 @@ static int b43_upload_microcode(struct b43_wldev *dev)
}
}
+ snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u",
+ dev->fw.rev, dev->fw.patch);
+ wiphy->hw_version = dev->dev->id.coreid;
+
if (b43_is_old_txhdr_format(dev)) {
/* We're over the deadline, but we keep support for old fw
* until it turns out to be in major conflict with something new. */
@@ -3754,17 +3759,17 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
}
err = -EINVAL;
- switch (key->alg) {
- case ALG_WEP:
- if (key->keylen == WLAN_KEY_LEN_WEP40)
- algorithm = B43_SEC_ALGO_WEP40;
- else
- algorithm = B43_SEC_ALGO_WEP104;
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ algorithm = B43_SEC_ALGO_WEP40;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ algorithm = B43_SEC_ALGO_WEP104;
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
algorithm = B43_SEC_ALGO_TKIP;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
algorithm = B43_SEC_ALGO_AES;
break;
default:
@@ -4250,6 +4255,10 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED);
if (!dev || b43_status(dev) != B43_STAT_INITIALIZED)
return;
+
+ /* Unregister HW RNG driver */
+ b43_rng_exit(dev->wl);
+
b43_set_status(dev, B43_STAT_UNINIT);
/* Stop the microcode PSM. */
@@ -4379,6 +4388,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
b43_set_status(dev, B43_STAT_INITIALIZED);
+ /* Register HW RNG driver */
+ b43_rng_init(dev->wl);
+
out:
return err;
@@ -4984,7 +4996,6 @@ static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id)
if (err)
goto err_one_core_detach;
b43_leds_register(wl->current_dev);
- b43_rng_init(wl);
}
out:
@@ -5020,7 +5031,6 @@ static void b43_remove(struct ssb_device *dev)
b43_one_core_detach(dev);
if (list_empty(&wl->devlist)) {
- b43_rng_exit(wl);
b43_leds_unregister(wl);
/* Last core on the chip unregistered.
* We can destroy common struct b43_wl.
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 8f7d7eff2d80..7b2ea6781457 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -294,8 +294,10 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
*/
channelcookie = new_channel;
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
- channelcookie |= 0x100;
- //FIXME set 40Mhz flag if required
+ channelcookie |= B43_SHM_SH_CHAN_5GHZ;
+ /* FIXME: set 40Mhz flag if required */
+ if (0)
+ channelcookie |= B43_SHM_SH_CHAN_40MHZ;
savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN);
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie);
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index bd480b481bfc..0e6194228845 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -2,6 +2,7 @@
#define LINUX_B43_PHY_COMMON_H_
#include <linux/types.h>
+#include <linux/nl80211.h>
struct b43_wldev;
@@ -250,8 +251,10 @@ struct b43_phy {
* check is needed. */
unsigned long next_txpwr_check_time;
- /* current channel */
+ /* Current channel */
unsigned int channel;
+ u16 channel_freq;
+ enum nl80211_channel_type channel_type;
/* PHY TX errors counter. */
atomic_t txerr_cnt;
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 5a725703770c..dfec5496055e 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -29,6 +29,8 @@
#include "b43.h"
#include "phy_n.h"
#include "tables_nphy.h"
+#include "radio_2055.h"
+#include "radio_2056.h"
#include "main.h"
struct nphy_txgains {
@@ -73,21 +75,12 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
u16 value, u8 core, bool off);
static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
u16 value, u8 core);
-static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel);
-static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec)
+static inline bool b43_channel_type_is_40mhz(
+ enum nl80211_channel_type channel_type)
{
- return !chanspec->channel && !chanspec->sideband &&
- !chanspec->b_width && !chanspec->b_freq;
-}
-
-static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1,
- struct b43_chanspec *chanspec2)
-{
- return (chanspec1->channel == chanspec2->channel &&
- chanspec1->sideband == chanspec2->sideband &&
- chanspec1->b_width == chanspec2->b_width &&
- chanspec1->b_freq == chanspec2->b_freq);
+ return (channel_type == NL80211_CHAN_HT40MINUS ||
+ channel_type == NL80211_CHAN_HT40PLUS);
}
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
@@ -223,7 +216,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
if (i)
b43err(dev->wl, "radio post init timeout\n");
b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
- nphy_channel_switch(dev, dev->phy.channel);
+ b43_switch_channel(dev, dev->phy.channel);
b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9);
b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9);
b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
@@ -782,7 +775,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
- u8 channel = nphy->radio_chanspec.channel;
+ u8 channel = dev->phy.channel;
int tone[2] = { 57, 58 };
u32 noise[2] = { 0x3FF, 0x3FF };
@@ -856,9 +849,9 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
gain[0] = 6;
gain[1] = 6;
} else {
- tmp = 40370 - 315 * nphy->radio_chanspec.channel;
+ tmp = 40370 - 315 * dev->phy.channel;
gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1));
- tmp = 23242 - 224 * nphy->radio_chanspec.channel;
+ tmp = 23242 - 224 * dev->phy.channel;
gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1));
}
} else {
@@ -893,7 +886,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
-static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
+static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
u8 i, j;
@@ -1094,11 +1087,12 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
- b43_nphy_gain_crtl_workarounds(dev);
+ b43_nphy_gain_ctrl_workarounds(dev);
if (dev->phy.rev < 2) {
if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2)
- ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/
+ b43_hf_write(dev, b43_hf_read(dev) |
+ B43_HF_MLADVW);
} else if (dev->phy.rev == 2) {
b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0);
b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0);
@@ -1182,7 +1176,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
len = bw << 1;
}
- samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL);
+ samples = kcalloc(len, sizeof(struct b43_c32), GFP_KERNEL);
if (!samples) {
b43err(dev->wl, "allocation for samples generation failed\n");
return 0;
@@ -2083,12 +2077,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
u16 *rssical_phy_regs = NULL;
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
- if (b43_empty_chanspec(&nphy->rssical_chanspec_2G))
+ if (!nphy->rssical_chanspec_2G.center_freq)
return;
rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
} else {
- if (b43_empty_chanspec(&nphy->rssical_chanspec_5G))
+ if (!nphy->rssical_chanspec_5G.center_freq)
return;
rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
@@ -2544,8 +2538,9 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
}
- *iqcal_chanspec = nphy->radio_chanspec;
- b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table);
+ iqcal_chanspec->center_freq = dev->phy.channel_freq;
+ iqcal_chanspec->channel_type = dev->phy.channel_type;
+ b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
if (nphy->hang_avoid)
b43_nphy_stay_in_carrier_search(dev, 0);
@@ -2565,12 +2560,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
- if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G))
+ if (!nphy->iqcal_chanspec_2G.center_freq)
return;
table = nphy->cal_cache.txcal_coeffs_2G;
loft = &nphy->cal_cache.txcal_coeffs_2G[5];
} else {
- if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G))
+ if (!nphy->iqcal_chanspec_5G.center_freq)
return;
table = nphy->cal_cache.txcal_coeffs_5G;
loft = &nphy->cal_cache.txcal_coeffs_5G[5];
@@ -2815,7 +2810,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
nphy->txiqlocal_bestc);
nphy->txiqlocal_coeffsvalid = true;
- nphy->txiqlocal_chanspec = nphy->radio_chanspec;
+ nphy->txiqlocal_chanspec.center_freq =
+ dev->phy.channel_freq;
+ nphy->txiqlocal_chanspec.channel_type =
+ dev->phy.channel_type;
} else {
length = 11;
if (dev->phy.rev < 3)
@@ -2851,7 +2849,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
bool equal = true;
if (!nphy->txiqlocal_coeffsvalid ||
- b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec))
+ nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
+ nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
return;
b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
@@ -3073,6 +3072,57 @@ 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 |= SSB_TMSLOW_PHYCLK;
+ else
+ tmslow &= ~SSB_TMSLOW_PHYCLK;
+ 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)
+{
+ struct b43_phy *phy = &dev->phy;
+ struct b43_phy_n *nphy = phy->n;
+ u16 buf[16];
+
+ nphy->phyrxchain = mask;
+
+ if (0 /* FIXME clk */)
+ return;
+
+ b43_mac_suspend(dev);
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, true);
+
+ b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN,
+ (mask & 0x3) << B43_NPHY_RFSEQCA_RXEN_SHIFT);
+
+ if ((mask & 0x3) != 0x3) {
+ b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 1);
+ if (dev->phy.rev >= 3) {
+ /* TODO */
+ }
+ } else {
+ b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 0x1E);
+ if (dev->phy.rev >= 3) {
+ /* TODO */
+ }
+ }
+
+ b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, false);
+
+ b43_mac_enable(dev);
+}
+
/*
* Init N-PHY
* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N
@@ -3173,7 +3223,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);
- /* TODO N PHY MAC PHY Clock Set with argument 1 */
+ b43_nphy_mac_phy_clock_set(dev, true);
b43_nphy_pa_override(dev, false);
b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
@@ -3199,18 +3249,16 @@ int b43_phy_initn(struct b43_wldev *dev)
}
if (nphy->phyrxchain != 3)
- ;/* TODO N PHY RX Core Set State with phyrxchain as argument */
+ b43_nphy_set_rx_core_state(dev, nphy->phyrxchain);
if (nphy->mphase_cal_phase_id > 0)
;/* TODO PHY Periodic Calibration Multi-Phase Restart */
do_rssi_cal = false;
if (phy->rev >= 3) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
- do_rssi_cal =
- b43_empty_chanspec(&nphy->rssical_chanspec_2G);
+ do_rssi_cal = !nphy->rssical_chanspec_2G.center_freq;
else
- do_rssi_cal =
- b43_empty_chanspec(&nphy->rssical_chanspec_5G);
+ do_rssi_cal = !nphy->rssical_chanspec_5G.center_freq;
if (do_rssi_cal)
b43_nphy_rssi_cal(dev);
@@ -3222,9 +3270,9 @@ int b43_phy_initn(struct b43_wldev *dev)
if (!((nphy->measure_hold & 0x6) != 0)) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
- do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G);
+ do_cal = !nphy->iqcal_chanspec_2G.center_freq;
else
- do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G);
+ do_cal = !nphy->iqcal_chanspec_5G.center_freq;
if (nphy->mute)
do_cal = false;
@@ -3272,24 +3320,25 @@ int b43_phy_initn(struct b43_wldev *dev)
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
-static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
+static void b43_nphy_channel_setup(struct b43_wldev *dev,
const struct b43_phy_n_sfo_cfg *e,
- struct b43_chanspec chanspec)
+ struct ieee80211_channel *new_channel)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
- u16 tmp;
+ u16 old_band_5ghz;
u32 tmp32;
- tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
- if (chanspec.b_freq == 1 && tmp == 0) {
+ old_band_5ghz =
+ b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
+ if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
- } else if (chanspec.b_freq == 1) {
+ } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
@@ -3299,19 +3348,12 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
b43_chantab_phy_upload(dev, e);
- tmp = chanspec.channel;
- if (chanspec.b_freq == 1)
- tmp |= 0x0100;
- if (chanspec.b_width == 3)
- tmp |= 0x0200;
- b43_shm_write16(dev, B43_SHM_SHARED, 0xA0, tmp);
-
- if (nphy->radio_chanspec.channel == 14) {
+ if (new_channel->hw_value == 14) {
b43_nphy_classifier(dev, 2, 0);
b43_phy_set(dev, B43_PHY_B_TEST, 0x0800);
} else {
b43_nphy_classifier(dev, 2, 2);
- if (chanspec.b_freq == 2)
+ if (new_channel->band == IEEE80211_BAND_2GHZ)
b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
}
@@ -3334,70 +3376,62 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
-static int b43_nphy_set_chanspec(struct b43_wldev *dev,
- struct b43_chanspec chanspec)
+static int b43_nphy_set_channel(struct b43_wldev *dev,
+ struct ieee80211_channel *channel,
+ enum nl80211_channel_type channel_type)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
u8 tmp;
- u8 channel = chanspec.channel;
if (dev->phy.rev >= 3) {
- /* TODO */
+ tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
+ channel->center_freq);
tabent_r3 = NULL;
if (!tabent_r3)
return -ESRCH;
} else {
- tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel);
+ tabent_r2 = b43_nphy_get_chantabent_rev2(dev,
+ channel->hw_value);
if (!tabent_r2)
return -ESRCH;
}
- nphy->radio_chanspec = chanspec;
+ /* Channel is set later in common code, but we need to set it on our
+ own to let this function's subcalls work properly. */
+ phy->channel = channel->hw_value;
+ phy->channel_freq = channel->center_freq;
- if (chanspec.b_width != nphy->b_width)
- ; /* TODO: BMAC BW Set (chanspec.b_width) */
+ if (b43_channel_type_is_40mhz(phy->channel_type) !=
+ b43_channel_type_is_40mhz(channel_type))
+ ; /* TODO: BMAC BW Set (channel_type) */
- /* TODO: use defines */
- if (chanspec.b_width == 3) {
- if (chanspec.sideband == 2)
- b43_phy_set(dev, B43_NPHY_RXCTL,
- B43_NPHY_RXCTL_BSELU20);
- else
- b43_phy_mask(dev, B43_NPHY_RXCTL,
- ~B43_NPHY_RXCTL_BSELU20);
- }
+ if (channel_type == NL80211_CHAN_HT40PLUS)
+ b43_phy_set(dev, B43_NPHY_RXCTL,
+ B43_NPHY_RXCTL_BSELU20);
+ else if (channel_type == NL80211_CHAN_HT40MINUS)
+ b43_phy_mask(dev, B43_NPHY_RXCTL,
+ ~B43_NPHY_RXCTL_BSELU20);
if (dev->phy.rev >= 3) {
- tmp = (chanspec.b_freq == 1) ? 4 : 0;
+ tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
/* TODO: PHY Radio2056 Setup (dev, tabent_r3); */
- b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec);
+ b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel);
} else {
- tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050;
+ tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050;
b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp);
b43_radio_2055_setup(dev, tabent_r2);
- b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec);
+ b43_nphy_channel_setup(dev, &(tabent_r2->phy_regs), channel);
}
return 0;
}
-/* Tune the hardware to a new channel */
-static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
-{
- struct b43_phy_n *nphy = dev->phy.n;
-
- struct b43_chanspec chanspec;
- chanspec = nphy->radio_chanspec;
- chanspec.channel = channel;
-
- return b43_nphy_set_chanspec(dev, chanspec);
-}
-
static int b43_nphy_op_allocate(struct b43_wldev *dev)
{
struct b43_phy_n *nphy;
@@ -3518,7 +3552,7 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
} else {
if (dev->phy.rev >= 3) {
b43_radio_init2056(dev);
- b43_nphy_set_chanspec(dev, nphy->radio_chanspec);
+ b43_switch_channel(dev, dev->phy.channel);
} else {
b43_radio_init2055(dev);
}
@@ -3534,6 +3568,9 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
unsigned int new_channel)
{
+ struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
+ enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
+
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
if ((new_channel < 1) || (new_channel > 14))
return -EINVAL;
@@ -3542,7 +3579,7 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
return -EINVAL;
}
- return nphy_channel_switch(dev, new_channel);
+ return b43_nphy_set_channel(dev, channel, channel_type);
}
static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 8b6d570dd0aa..c144e59a708b 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -714,223 +714,11 @@
#define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */
#define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A)
-
-/* Broadcom 2055 radio registers */
-
-#define B2055_GEN_SPARE 0x00 /* GEN spare */
-#define B2055_SP_PINPD 0x02 /* SP PIN PD */
-#define B2055_C1_SP_RSSI 0x03 /* SP RSSI Core 1 */
-#define B2055_C1_SP_PDMISC 0x04 /* SP PD MISC Core 1 */
-#define B2055_C2_SP_RSSI 0x05 /* SP RSSI Core 2 */
-#define B2055_C2_SP_PDMISC 0x06 /* SP PD MISC Core 2 */
-#define B2055_C1_SP_RXGC1 0x07 /* SP RX GC1 Core 1 */
-#define B2055_C1_SP_RXGC2 0x08 /* SP RX GC2 Core 1 */
-#define B2055_C2_SP_RXGC1 0x09 /* SP RX GC1 Core 2 */
-#define B2055_C2_SP_RXGC2 0x0A /* SP RX GC2 Core 2 */
-#define B2055_C1_SP_LPFBWSEL 0x0B /* SP LPF BW select Core 1 */
-#define B2055_C2_SP_LPFBWSEL 0x0C /* SP LPF BW select Core 2 */
-#define B2055_C1_SP_TXGC1 0x0D /* SP TX GC1 Core 1 */
-#define B2055_C1_SP_TXGC2 0x0E /* SP TX GC2 Core 1 */
-#define B2055_C2_SP_TXGC1 0x0F /* SP TX GC1 Core 2 */
-#define B2055_C2_SP_TXGC2 0x10 /* SP TX GC2 Core 2 */
-#define B2055_MASTER1 0x11 /* Master control 1 */
-#define B2055_MASTER2 0x12 /* Master control 2 */
-#define B2055_PD_LGEN 0x13 /* PD LGEN */
-#define B2055_PD_PLLTS 0x14 /* PD PLL TS */
-#define B2055_C1_PD_LGBUF 0x15 /* PD Core 1 LGBUF */
-#define B2055_C1_PD_TX 0x16 /* PD Core 1 TX */
-#define B2055_C1_PD_RXTX 0x17 /* PD Core 1 RXTX */
-#define B2055_C1_PD_RSSIMISC 0x18 /* PD Core 1 RSSI MISC */
-#define B2055_C2_PD_LGBUF 0x19 /* PD Core 2 LGBUF */
-#define B2055_C2_PD_TX 0x1A /* PD Core 2 TX */
-#define B2055_C2_PD_RXTX 0x1B /* PD Core 2 RXTX */
-#define B2055_C2_PD_RSSIMISC 0x1C /* PD Core 2 RSSI MISC */
-#define B2055_PWRDET_LGEN 0x1D /* PWRDET LGEN */
-#define B2055_C1_PWRDET_LGBUF 0x1E /* PWRDET LGBUF Core 1 */
-#define B2055_C1_PWRDET_RXTX 0x1F /* PWRDET RXTX Core 1 */
-#define B2055_C2_PWRDET_LGBUF 0x20 /* PWRDET LGBUF Core 2 */
-#define B2055_C2_PWRDET_RXTX 0x21 /* PWRDET RXTX Core 2 */
-#define B2055_RRCCAL_CS 0x22 /* RRCCAL Control spare */
-#define B2055_RRCCAL_NOPTSEL 0x23 /* RRCCAL N OPT SEL */
-#define B2055_CAL_MISC 0x24 /* CAL MISC */
-#define B2055_CAL_COUT 0x25 /* CAL Counter out */
-#define B2055_CAL_COUT2 0x26 /* CAL Counter out 2 */
-#define B2055_CAL_CVARCTL 0x27 /* CAL CVAR Control */
-#define B2055_CAL_RVARCTL 0x28 /* CAL RVAR Control */
-#define B2055_CAL_LPOCTL 0x29 /* CAL LPO Control */
-#define B2055_CAL_TS 0x2A /* CAL TS */
-#define B2055_CAL_RCCALRTS 0x2B /* CAL RCCAL READ TS */
-#define B2055_CAL_RCALRTS 0x2C /* CAL RCAL READ TS */
-#define B2055_PADDRV 0x2D /* PAD driver */
-#define B2055_XOCTL1 0x2E /* XO Control 1 */
-#define B2055_XOCTL2 0x2F /* XO Control 2 */
-#define B2055_XOREGUL 0x30 /* XO Regulator */
-#define B2055_XOMISC 0x31 /* XO misc */
-#define B2055_PLL_LFC1 0x32 /* PLL LF C1 */
-#define B2055_PLL_CALVTH 0x33 /* PLL CAL VTH */
-#define B2055_PLL_LFC2 0x34 /* PLL LF C2 */
-#define B2055_PLL_REF 0x35 /* PLL reference */
-#define B2055_PLL_LFR1 0x36 /* PLL LF R1 */
-#define B2055_PLL_PFDCP 0x37 /* PLL PFD CP */
-#define B2055_PLL_IDAC_CPOPAMP 0x38 /* PLL IDAC CPOPAMP */
-#define B2055_PLL_CPREG 0x39 /* PLL CP Regulator */
-#define B2055_PLL_RCAL 0x3A /* PLL RCAL */
-#define B2055_RF_PLLMOD0 0x3B /* RF PLL MOD0 */
-#define B2055_RF_PLLMOD1 0x3C /* RF PLL MOD1 */
-#define B2055_RF_MMDIDAC1 0x3D /* RF MMD IDAC 1 */
-#define B2055_RF_MMDIDAC0 0x3E /* RF MMD IDAC 0 */
-#define B2055_RF_MMDSP 0x3F /* RF MMD spare */
-#define B2055_VCO_CAL1 0x40 /* VCO cal 1 */
-#define B2055_VCO_CAL2 0x41 /* VCO cal 2 */
-#define B2055_VCO_CAL3 0x42 /* VCO cal 3 */
-#define B2055_VCO_CAL4 0x43 /* VCO cal 4 */
-#define B2055_VCO_CAL5 0x44 /* VCO cal 5 */
-#define B2055_VCO_CAL6 0x45 /* VCO cal 6 */
-#define B2055_VCO_CAL7 0x46 /* VCO cal 7 */
-#define B2055_VCO_CAL8 0x47 /* VCO cal 8 */
-#define B2055_VCO_CAL9 0x48 /* VCO cal 9 */
-#define B2055_VCO_CAL10 0x49 /* VCO cal 10 */
-#define B2055_VCO_CAL11 0x4A /* VCO cal 11 */
-#define B2055_VCO_CAL12 0x4B /* VCO cal 12 */
-#define B2055_VCO_CAL13 0x4C /* VCO cal 13 */
-#define B2055_VCO_CAL14 0x4D /* VCO cal 14 */
-#define B2055_VCO_CAL15 0x4E /* VCO cal 15 */
-#define B2055_VCO_CAL16 0x4F /* VCO cal 16 */
-#define B2055_VCO_KVCO 0x50 /* VCO KVCO */
-#define B2055_VCO_CAPTAIL 0x51 /* VCO CAP TAIL */
-#define B2055_VCO_IDACVCO 0x52 /* VCO IDAC VCO */
-#define B2055_VCO_REG 0x53 /* VCO Regulator */
-#define B2055_PLL_RFVTH 0x54 /* PLL RF VTH */
-#define B2055_LGBUF_CENBUF 0x55 /* LGBUF CEN BUF */
-#define B2055_LGEN_TUNE1 0x56 /* LGEN tune 1 */
-#define B2055_LGEN_TUNE2 0x57 /* LGEN tune 2 */
-#define B2055_LGEN_IDAC1 0x58 /* LGEN IDAC 1 */
-#define B2055_LGEN_IDAC2 0x59 /* LGEN IDAC 2 */
-#define B2055_LGEN_BIASC 0x5A /* LGEN BIAS counter */
-#define B2055_LGEN_BIASIDAC 0x5B /* LGEN BIAS IDAC */
-#define B2055_LGEN_RCAL 0x5C /* LGEN RCAL */
-#define B2055_LGEN_DIV 0x5D /* LGEN div */
-#define B2055_LGEN_SPARE2 0x5E /* LGEN spare 2 */
-#define B2055_C1_LGBUF_ATUNE 0x5F /* Core 1 LGBUF A tune */
-#define B2055_C1_LGBUF_GTUNE 0x60 /* Core 1 LGBUF G tune */
-#define B2055_C1_LGBUF_DIV 0x61 /* Core 1 LGBUF div */
-#define B2055_C1_LGBUF_AIDAC 0x62 /* Core 1 LGBUF A IDAC */
-#define B2055_C1_LGBUF_GIDAC 0x63 /* Core 1 LGBUF G IDAC */
-#define B2055_C1_LGBUF_IDACFO 0x64 /* Core 1 LGBUF IDAC filter override */
-#define B2055_C1_LGBUF_SPARE 0x65 /* Core 1 LGBUF spare */
-#define B2055_C1_RX_RFSPC1 0x66 /* Core 1 RX RF SPC1 */
-#define B2055_C1_RX_RFR1 0x67 /* Core 1 RX RF reg 1 */
-#define B2055_C1_RX_RFR2 0x68 /* Core 1 RX RF reg 2 */
-#define B2055_C1_RX_RFRCAL 0x69 /* Core 1 RX RF RCAL */
-#define B2055_C1_RX_BB_BLCMP 0x6A /* Core 1 RX Baseband BUFI LPF CMP */
-#define B2055_C1_RX_BB_LPF 0x6B /* Core 1 RX Baseband LPF */
-#define B2055_C1_RX_BB_MIDACHP 0x6C /* Core 1 RX Baseband MIDAC High-pass */
-#define B2055_C1_RX_BB_VGA1IDAC 0x6D /* Core 1 RX Baseband VGA1 IDAC */
-#define B2055_C1_RX_BB_VGA2IDAC 0x6E /* Core 1 RX Baseband VGA2 IDAC */
-#define B2055_C1_RX_BB_VGA3IDAC 0x6F /* Core 1 RX Baseband VGA3 IDAC */
-#define B2055_C1_RX_BB_BUFOCTL 0x70 /* Core 1 RX Baseband BUFO Control */
-#define B2055_C1_RX_BB_RCCALCTL 0x71 /* Core 1 RX Baseband RCCAL Control */
-#define B2055_C1_RX_BB_RSSICTL1 0x72 /* Core 1 RX Baseband RSSI Control 1 */
-#define B2055_C1_RX_BB_RSSICTL2 0x73 /* Core 1 RX Baseband RSSI Control 2 */
-#define B2055_C1_RX_BB_RSSICTL3 0x74 /* Core 1 RX Baseband RSSI Control 3 */
-#define B2055_C1_RX_BB_RSSICTL4 0x75 /* Core 1 RX Baseband RSSI Control 4 */
-#define B2055_C1_RX_BB_RSSICTL5 0x76 /* Core 1 RX Baseband RSSI Control 5 */
-#define B2055_C1_RX_BB_REG 0x77 /* Core 1 RX Baseband Regulator */
-#define B2055_C1_RX_BB_SPARE1 0x78 /* Core 1 RX Baseband spare 1 */
-#define B2055_C1_RX_TXBBRCAL 0x79 /* Core 1 RX TX BB RCAL */
-#define B2055_C1_TX_RF_SPGA 0x7A /* Core 1 TX RF SGM PGA */
-#define B2055_C1_TX_RF_SPAD 0x7B /* Core 1 TX RF SGM PAD */
-#define B2055_C1_TX_RF_CNTPGA1 0x7C /* Core 1 TX RF counter PGA 1 */
-#define B2055_C1_TX_RF_CNTPAD1 0x7D /* Core 1 TX RF counter PAD 1 */
-#define B2055_C1_TX_RF_PGAIDAC 0x7E /* Core 1 TX RF PGA IDAC */
-#define B2055_C1_TX_PGAPADTN 0x7F /* Core 1 TX PGA PAD TN */
-#define B2055_C1_TX_PADIDAC1 0x80 /* Core 1 TX PAD IDAC 1 */
-#define B2055_C1_TX_PADIDAC2 0x81 /* Core 1 TX PAD IDAC 2 */
-#define B2055_C1_TX_MXBGTRIM 0x82 /* Core 1 TX MX B/G TRIM */
-#define B2055_C1_TX_RF_RCAL 0x83 /* Core 1 TX RF RCAL */
-#define B2055_C1_TX_RF_PADTSSI1 0x84 /* Core 1 TX RF PAD TSSI1 */
-#define B2055_C1_TX_RF_PADTSSI2 0x85 /* Core 1 TX RF PAD TSSI2 */
-#define B2055_C1_TX_RF_SPARE 0x86 /* Core 1 TX RF spare */
-#define B2055_C1_TX_RF_IQCAL1 0x87 /* Core 1 TX RF I/Q CAL 1 */
-#define B2055_C1_TX_RF_IQCAL2 0x88 /* Core 1 TX RF I/Q CAL 2 */
-#define B2055_C1_TXBB_RCCAL 0x89 /* Core 1 TXBB RC CAL Control */
-#define B2055_C1_TXBB_LPF1 0x8A /* Core 1 TXBB LPF 1 */
-#define B2055_C1_TX_VOSCNCL 0x8B /* Core 1 TX VOS CNCL */
-#define B2055_C1_TX_LPF_MXGMIDAC 0x8C /* Core 1 TX LPF MXGM IDAC */
-#define B2055_C1_TX_BB_MXGM 0x8D /* Core 1 TX BB MXGM */
-#define B2055_C2_LGBUF_ATUNE 0x8E /* Core 2 LGBUF A tune */
-#define B2055_C2_LGBUF_GTUNE 0x8F /* Core 2 LGBUF G tune */
-#define B2055_C2_LGBUF_DIV 0x90 /* Core 2 LGBUF div */
-#define B2055_C2_LGBUF_AIDAC 0x91 /* Core 2 LGBUF A IDAC */
-#define B2055_C2_LGBUF_GIDAC 0x92 /* Core 2 LGBUF G IDAC */
-#define B2055_C2_LGBUF_IDACFO 0x93 /* Core 2 LGBUF IDAC filter override */
-#define B2055_C2_LGBUF_SPARE 0x94 /* Core 2 LGBUF spare */
-#define B2055_C2_RX_RFSPC1 0x95 /* Core 2 RX RF SPC1 */
-#define B2055_C2_RX_RFR1 0x96 /* Core 2 RX RF reg 1 */
-#define B2055_C2_RX_RFR2 0x97 /* Core 2 RX RF reg 2 */
-#define B2055_C2_RX_RFRCAL 0x98 /* Core 2 RX RF RCAL */
-#define B2055_C2_RX_BB_BLCMP 0x99 /* Core 2 RX Baseband BUFI LPF CMP */
-#define B2055_C2_RX_BB_LPF 0x9A /* Core 2 RX Baseband LPF */
-#define B2055_C2_RX_BB_MIDACHP 0x9B /* Core 2 RX Baseband MIDAC High-pass */
-#define B2055_C2_RX_BB_VGA1IDAC 0x9C /* Core 2 RX Baseband VGA1 IDAC */
-#define B2055_C2_RX_BB_VGA2IDAC 0x9D /* Core 2 RX Baseband VGA2 IDAC */
-#define B2055_C2_RX_BB_VGA3IDAC 0x9E /* Core 2 RX Baseband VGA3 IDAC */
-#define B2055_C2_RX_BB_BUFOCTL 0x9F /* Core 2 RX Baseband BUFO Control */
-#define B2055_C2_RX_BB_RCCALCTL 0xA0 /* Core 2 RX Baseband RCCAL Control */
-#define B2055_C2_RX_BB_RSSICTL1 0xA1 /* Core 2 RX Baseband RSSI Control 1 */
-#define B2055_C2_RX_BB_RSSICTL2 0xA2 /* Core 2 RX Baseband RSSI Control 2 */
-#define B2055_C2_RX_BB_RSSICTL3 0xA3 /* Core 2 RX Baseband RSSI Control 3 */
-#define B2055_C2_RX_BB_RSSICTL4 0xA4 /* Core 2 RX Baseband RSSI Control 4 */
-#define B2055_C2_RX_BB_RSSICTL5 0xA5 /* Core 2 RX Baseband RSSI Control 5 */
-#define B2055_C2_RX_BB_REG 0xA6 /* Core 2 RX Baseband Regulator */
-#define B2055_C2_RX_BB_SPARE1 0xA7 /* Core 2 RX Baseband spare 1 */
-#define B2055_C2_RX_TXBBRCAL 0xA8 /* Core 2 RX TX BB RCAL */
-#define B2055_C2_TX_RF_SPGA 0xA9 /* Core 2 TX RF SGM PGA */
-#define B2055_C2_TX_RF_SPAD 0xAA /* Core 2 TX RF SGM PAD */
-#define B2055_C2_TX_RF_CNTPGA1 0xAB /* Core 2 TX RF counter PGA 1 */
-#define B2055_C2_TX_RF_CNTPAD1 0xAC /* Core 2 TX RF counter PAD 1 */
-#define B2055_C2_TX_RF_PGAIDAC 0xAD /* Core 2 TX RF PGA IDAC */
-#define B2055_C2_TX_PGAPADTN 0xAE /* Core 2 TX PGA PAD TN */
-#define B2055_C2_TX_PADIDAC1 0xAF /* Core 2 TX PAD IDAC 1 */
-#define B2055_C2_TX_PADIDAC2 0xB0 /* Core 2 TX PAD IDAC 2 */
-#define B2055_C2_TX_MXBGTRIM 0xB1 /* Core 2 TX MX B/G TRIM */
-#define B2055_C2_TX_RF_RCAL 0xB2 /* Core 2 TX RF RCAL */
-#define B2055_C2_TX_RF_PADTSSI1 0xB3 /* Core 2 TX RF PAD TSSI1 */
-#define B2055_C2_TX_RF_PADTSSI2 0xB4 /* Core 2 TX RF PAD TSSI2 */
-#define B2055_C2_TX_RF_SPARE 0xB5 /* Core 2 TX RF spare */
-#define B2055_C2_TX_RF_IQCAL1 0xB6 /* Core 2 TX RF I/Q CAL 1 */
-#define B2055_C2_TX_RF_IQCAL2 0xB7 /* Core 2 TX RF I/Q CAL 2 */
-#define B2055_C2_TXBB_RCCAL 0xB8 /* Core 2 TXBB RC CAL Control */
-#define B2055_C2_TXBB_LPF1 0xB9 /* Core 2 TXBB LPF 1 */
-#define B2055_C2_TX_VOSCNCL 0xBA /* Core 2 TX VOS CNCL */
-#define B2055_C2_TX_LPF_MXGMIDAC 0xBB /* Core 2 TX LPF MXGM IDAC */
-#define B2055_C2_TX_BB_MXGM 0xBC /* Core 2 TX BB MXGM */
-#define B2055_PRG_GCHP21 0xBD /* PRG GC HPVGA23 21 */
-#define B2055_PRG_GCHP22 0xBE /* PRG GC HPVGA23 22 */
-#define B2055_PRG_GCHP23 0xBF /* PRG GC HPVGA23 23 */
-#define B2055_PRG_GCHP24 0xC0 /* PRG GC HPVGA23 24 */
-#define B2055_PRG_GCHP25 0xC1 /* PRG GC HPVGA23 25 */
-#define B2055_PRG_GCHP26 0xC2 /* PRG GC HPVGA23 26 */
-#define B2055_PRG_GCHP27 0xC3 /* PRG GC HPVGA23 27 */
-#define B2055_PRG_GCHP28 0xC4 /* PRG GC HPVGA23 28 */
-#define B2055_PRG_GCHP29 0xC5 /* PRG GC HPVGA23 29 */
-#define B2055_PRG_GCHP30 0xC6 /* PRG GC HPVGA23 30 */
-#define B2055_C1_LNA_GAINBST 0xCD /* Core 1 LNA GAINBST */
-#define B2055_C1_B0NB_RSSIVCM 0xD2 /* Core 1 B0 narrow-band RSSI VCM */
-#define B2055_C1_GENSPARE2 0xD6 /* Core 1 GEN spare 2 */
-#define B2055_C2_LNA_GAINBST 0xD9 /* Core 2 LNA GAINBST */
-#define B2055_C2_B0NB_RSSIVCM 0xDE /* Core 2 B0 narrow-band RSSI VCM */
-#define B2055_C2_GENSPARE2 0xE2 /* Core 2 GEN spare 2 */
-
-
-
struct b43_wldev;
struct b43_chanspec {
- u8 channel;
- u8 sideband;
- u8 b_width;
- u8 b_freq;
+ u16 center_freq;
+ enum nl80211_channel_type channel_type;
};
struct b43_phy_n_iq_comp {
@@ -984,8 +772,6 @@ struct b43_phy_n {
u16 papd_epsilon_offset[2];
s32 preamble_override;
u32 bb_mult_save;
- u8 b_width;
- struct b43_chanspec radio_chanspec;
bool gain_boost;
bool elna_gain_config;
diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c
new file mode 100644
index 000000000000..1b5316586cbf
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2055.c
@@ -0,0 +1,1332 @@
+/*
+
+ Broadcom B43 wireless driver
+ IEEE 802.11n PHY and radio device data tables
+
+ Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "radio_2055.h"
+#include "phy_common.h"
+
+struct b2055_inittab_entry {
+ /* Value to write if we use the 5GHz band. */
+ u16 ghz5;
+ /* Value to write if we use the 2.4GHz band. */
+ u16 ghz2;
+ /* Flags */
+ u8 flags;
+#define B2055_INITTAB_ENTRY_OK 0x01
+#define B2055_INITTAB_UPLOAD 0x02
+};
+#define UPLOAD .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD
+#define NOUPLOAD .flags = B2055_INITTAB_ENTRY_OK
+
+static const struct b2055_inittab_entry b2055_inittab [] = {
+ [B2055_SP_PINPD] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+ [B2055_C1_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C1_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
+ [B2055_C2_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
+ [B2055_C1_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
+ [B2055_C1_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2055_C2_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
+ [B2055_C2_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+ [B2055_C1_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2055_C2_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2055_C1_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
+ [B2055_C1_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
+ [B2055_C2_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
+ [B2055_C2_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
+ [B2055_MASTER1] = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, },
+ [B2055_MASTER2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2055_PD_LGEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_PD_PLLTS] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
+ [B2055_C1_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C1_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C1_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C1_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_PWRDET_LGEN] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+ [B2055_C1_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+ [B2055_C1_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+ [B2055_C2_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+ [B2055_C2_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+ [B2055_RRCCAL_CS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_RRCCAL_NOPTSEL] = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, },
+ [B2055_CAL_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_CAL_COUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_CAL_COUT2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_CAL_CVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_CAL_RVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_CAL_LPOCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_CAL_TS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_CAL_RCCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_CAL_RCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_PADDRV] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+ [B2055_XOCTL1] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
+ [B2055_XOCTL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_XOREGUL] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+ [B2055_XOMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_PLL_LFC1] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+ [B2055_PLL_CALVTH] = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, },
+ [B2055_PLL_LFC2] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
+ [B2055_PLL_REF] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+ [B2055_PLL_LFR1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+ [B2055_PLL_PFDCP] = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, },
+ [B2055_PLL_IDAC_CPOPAMP] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2055_PLL_CPREG] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+ [B2055_PLL_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2055_RF_PLLMOD0] = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, },
+ [B2055_RF_PLLMOD1] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
+ [B2055_RF_MMDIDAC1] = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, },
+ [B2055_RF_MMDIDAC0] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_RF_MMDSP] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_VCO_CAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_VCO_CAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_VCO_CAL3] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+ [B2055_VCO_CAL4] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2055_VCO_CAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
+ [B2055_VCO_CAL6] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
+ [B2055_VCO_CAL7] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
+ [B2055_VCO_CAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+ [B2055_VCO_CAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+ [B2055_VCO_CAL10] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2055_VCO_CAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2055_VCO_CAL12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_VCO_CAL13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_VCO_CAL14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_VCO_CAL15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_VCO_CAL16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_VCO_KVCO] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2055_VCO_CAPTAIL] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2055_VCO_IDACVCO] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2055_VCO_REG] = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, },
+ [B2055_PLL_RFVTH] = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, },
+ [B2055_LGBUF_CENBUF] = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, },
+ [B2055_LGEN_TUNE1] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+ [B2055_LGEN_TUNE2] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+ [B2055_LGEN_IDAC1] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_LGEN_IDAC2] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_LGEN_BIASC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_LGEN_BIASIDAC] = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, },
+ [B2055_LGEN_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2055_LGEN_DIV] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+ [B2055_LGEN_SPARE2] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+ [B2055_C1_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
+ [B2055_C1_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_C1_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_C1_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
+ [B2055_C1_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_C1_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C1_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
+ [B2055_C1_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
+ [B2055_C1_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2055_C1_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+ [B2055_C1_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2055_C1_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
+ [B2055_C1_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+ [B2055_C1_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+ [B2055_C1_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+ [B2055_C1_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+ [B2055_C1_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+ [B2055_C1_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+ [B2055_C1_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2055_C1_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
+ [B2055_C1_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
+ [B2055_C1_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
+ [B2055_C1_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
+ [B2055_C1_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
+ [B2055_C1_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+ [B2055_C1_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C1_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2055_C1_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2055_C1_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2055_C1_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2055_C1_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2055_C1_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
+ [B2055_C1_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2055_C1_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
+ [B2055_C1_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
+ [B2055_C1_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_C1_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2055_C1_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+ [B2055_C1_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+ [B2055_C1_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+ [B2055_C1_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+ [B2055_C1_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+ [B2055_C1_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2055_C1_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
+ [B2055_C1_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C1_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
+ [B2055_C1_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
+ [B2055_C2_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_C2_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_C2_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
+ [B2055_C2_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_C2_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
+ [B2055_C2_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
+ [B2055_C2_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2055_C2_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+ [B2055_C2_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2055_C2_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
+ [B2055_C2_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+ [B2055_C2_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+ [B2055_C2_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+ [B2055_C2_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+ [B2055_C2_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+ [B2055_C2_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+ [B2055_C2_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2055_C2_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
+ [B2055_C2_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
+ [B2055_C2_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
+ [B2055_C2_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
+ [B2055_C2_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
+ [B2055_C2_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+ [B2055_C2_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2055_C2_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2055_C2_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+ [B2055_C2_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+ [B2055_C2_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+ [B2055_C2_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
+ [B2055_C2_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+ [B2055_C2_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
+ [B2055_C2_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
+ [B2055_C2_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [B2055_C2_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+ [B2055_C2_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+ [B2055_C2_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+ [B2055_C2_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+ [B2055_C2_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+ [B2055_C2_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+ [B2055_C2_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2055_C2_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
+ [B2055_C2_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
+ [B2055_C2_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_PRG_GCHP21] = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, },
+ [B2055_PRG_GCHP22] = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, },
+ [B2055_PRG_GCHP23] = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, },
+ [B2055_PRG_GCHP24] = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, },
+ [B2055_PRG_GCHP25] = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, },
+ [B2055_PRG_GCHP26] = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, },
+ [B2055_PRG_GCHP27] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+ [B2055_PRG_GCHP28] = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, },
+ [B2055_PRG_GCHP29] = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, },
+ [B2055_PRG_GCHP30] = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, },
+ [0xC7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xC8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xC9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xCA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2055_C1_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [0xD3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xD4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xD5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C1_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+ [B2055_C2_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+ [0xDF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xE0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [B2055_C2_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \
+ r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \
+ .radio_pll_ref = r0, \
+ .radio_rf_pllmod0 = r1, \
+ .radio_rf_pllmod1 = r2, \
+ .radio_vco_captail = r3, \
+ .radio_vco_cal1 = r4, \
+ .radio_vco_cal2 = r5, \
+ .radio_pll_lfc1 = r6, \
+ .radio_pll_lfr1 = r7, \
+ .radio_pll_lfc2 = r8, \
+ .radio_lgbuf_cenbuf = r9, \
+ .radio_lgen_tune1 = r10, \
+ .radio_lgen_tune2 = r11, \
+ .radio_c1_lgbuf_atune = r12, \
+ .radio_c1_lgbuf_gtune = r13, \
+ .radio_c1_rx_rfr1 = r14, \
+ .radio_c1_tx_pgapadtn = r15, \
+ .radio_c1_tx_mxbgtrim = r16, \
+ .radio_c2_lgbuf_atune = r17, \
+ .radio_c2_lgbuf_gtune = r18, \
+ .radio_c2_rx_rfr1 = r19, \
+ .radio_c2_tx_pgapadtn = r20, \
+ .radio_c2_tx_mxbgtrim = r21
+
+#define PHYREGS(r0, r1, r2, r3, r4, r5) \
+ .phy_regs.phy_bw1a = r0, \
+ .phy_regs.phy_bw2 = r1, \
+ .phy_regs.phy_bw3 = r2, \
+ .phy_regs.phy_bw4 = r3, \
+ .phy_regs.phy_bw5 = r4, \
+ .phy_regs.phy_bw6 = r5
+
+static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = {
+ { .channel = 184,
+ .freq = 4920, /* MHz */
+ .unk2 = 3280,
+ RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
+ },
+ { .channel = 186,
+ .freq = 4930, /* MHz */
+ .unk2 = 3287,
+ RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
+ },
+ { .channel = 188,
+ .freq = 4940, /* MHz */
+ .unk2 = 3293,
+ RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
+ },
+ { .channel = 190,
+ .freq = 4950, /* MHz */
+ .unk2 = 3300,
+ RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
+ },
+ { .channel = 192,
+ .freq = 4960, /* MHz */
+ .unk2 = 3307,
+ RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
+ },
+ { .channel = 194,
+ .freq = 4970, /* MHz */
+ .unk2 = 3313,
+ RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
+ },
+ { .channel = 196,
+ .freq = 4980, /* MHz */
+ .unk2 = 3320,
+ RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
+ },
+ { .channel = 198,
+ .freq = 4990, /* MHz */
+ .unk2 = 3327,
+ RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
+ },
+ { .channel = 200,
+ .freq = 5000, /* MHz */
+ .unk2 = 3333,
+ RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
+ },
+ { .channel = 202,
+ .freq = 5010, /* MHz */
+ .unk2 = 3340,
+ RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
+ },
+ { .channel = 204,
+ .freq = 5020, /* MHz */
+ .unk2 = 3347,
+ RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
+ },
+ { .channel = 206,
+ .freq = 5030, /* MHz */
+ .unk2 = 3353,
+ RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
+ },
+ { .channel = 208,
+ .freq = 5040, /* MHz */
+ .unk2 = 3360,
+ RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
+ },
+ { .channel = 210,
+ .freq = 5050, /* MHz */
+ .unk2 = 3367,
+ RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+ 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+ PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
+ },
+ { .channel = 212,
+ .freq = 5060, /* MHz */
+ .unk2 = 3373,
+ RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
+ 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
+ PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
+ },
+ { .channel = 214,
+ .freq = 5070, /* MHz */
+ .unk2 = 3380,
+ RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
+ 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
+ PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
+ },
+ { .channel = 216,
+ .freq = 5080, /* MHz */
+ .unk2 = 3387,
+ RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
+ 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
+ PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
+ },
+ { .channel = 218,
+ .freq = 5090, /* MHz */
+ .unk2 = 3393,
+ RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
+ 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
+ PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
+ },
+ { .channel = 220,
+ .freq = 5100, /* MHz */
+ .unk2 = 3400,
+ RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
+ 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
+ PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
+ },
+ { .channel = 222,
+ .freq = 5110, /* MHz */
+ .unk2 = 3407,
+ RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
+ 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
+ PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
+ },
+ { .channel = 224,
+ .freq = 5120, /* MHz */
+ .unk2 = 3413,
+ RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
+ 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
+ PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
+ },
+ { .channel = 226,
+ .freq = 5130, /* MHz */
+ .unk2 = 3420,
+ RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
+ 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
+ PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
+ },
+ { .channel = 228,
+ .freq = 5140, /* MHz */
+ .unk2 = 3427,
+ RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
+ 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
+ PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
+ },
+ { .channel = 32,
+ .freq = 5160, /* MHz */
+ .unk2 = 3440,
+ RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
+ 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
+ PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
+ },
+ { .channel = 34,
+ .freq = 5170, /* MHz */
+ .unk2 = 3447,
+ RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
+ 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
+ PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
+ },
+ { .channel = 36,
+ .freq = 5180, /* MHz */
+ .unk2 = 3453,
+ RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
+ 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
+ PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
+ },
+ { .channel = 38,
+ .freq = 5190, /* MHz */
+ .unk2 = 3460,
+ RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
+ 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
+ PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
+ },
+ { .channel = 40,
+ .freq = 5200, /* MHz */
+ .unk2 = 3467,
+ RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
+ 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
+ PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
+ },
+ { .channel = 42,
+ .freq = 5210, /* MHz */
+ .unk2 = 3473,
+ RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
+ 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
+ PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
+ },
+ { .channel = 44,
+ .freq = 5220, /* MHz */
+ .unk2 = 3480,
+ RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+ 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
+ 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
+ PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
+ },
+ { .channel = 46,
+ .freq = 5230, /* MHz */
+ .unk2 = 3487,
+ RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+ 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
+ 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
+ PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
+ },
+ { .channel = 48,
+ .freq = 5240, /* MHz */
+ .unk2 = 3493,
+ RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+ 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
+ 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
+ PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
+ },
+ { .channel = 50,
+ .freq = 5250, /* MHz */
+ .unk2 = 3500,
+ RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+ 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
+ 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
+ PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
+ },
+ { .channel = 52,
+ .freq = 5260, /* MHz */
+ .unk2 = 3507,
+ RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+ 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
+ 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
+ PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
+ },
+ { .channel = 54,
+ .freq = 5270, /* MHz */
+ .unk2 = 3513,
+ RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+ 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
+ 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
+ PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
+ },
+ { .channel = 56,
+ .freq = 5280, /* MHz */
+ .unk2 = 3520,
+ RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
+ 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
+ 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
+ PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
+ },
+ { .channel = 58,
+ .freq = 5290, /* MHz */
+ .unk2 = 3527,
+ RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
+ 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
+ 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
+ PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
+ },
+ { .channel = 60,
+ .freq = 5300, /* MHz */
+ .unk2 = 3533,
+ RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+ 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
+ 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
+ PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
+ },
+ { .channel = 62,
+ .freq = 5310, /* MHz */
+ .unk2 = 3540,
+ RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+ 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
+ 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
+ PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
+ },
+ { .channel = 64,
+ .freq = 5320, /* MHz */
+ .unk2 = 3547,
+ RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
+ 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
+ 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
+ PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
+ },
+ { .channel = 66,
+ .freq = 5330, /* MHz */
+ .unk2 = 3553,
+ RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
+ 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
+ 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
+ PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
+ },
+ { .channel = 68,
+ .freq = 5340, /* MHz */
+ .unk2 = 3560,
+ RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+ 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
+ 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
+ PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
+ },
+ { .channel = 70,
+ .freq = 5350, /* MHz */
+ .unk2 = 3567,
+ RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+ 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
+ 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
+ PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
+ },
+ { .channel = 72,
+ .freq = 5360, /* MHz */
+ .unk2 = 3573,
+ RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
+ 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
+ 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
+ PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
+ },
+ { .channel = 74,
+ .freq = 5370, /* MHz */
+ .unk2 = 3580,
+ RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
+ 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
+ 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
+ PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
+ },
+ { .channel = 76,
+ .freq = 5380, /* MHz */
+ .unk2 = 3587,
+ RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+ 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
+ 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
+ PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
+ },
+ { .channel = 78,
+ .freq = 5390, /* MHz */
+ .unk2 = 3593,
+ RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+ 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
+ 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
+ PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
+ },
+ { .channel = 80,
+ .freq = 5400, /* MHz */
+ .unk2 = 3600,
+ RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
+ 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
+ 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
+ PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
+ },
+ { .channel = 82,
+ .freq = 5410, /* MHz */
+ .unk2 = 3607,
+ RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
+ 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
+ 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
+ PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
+ },
+ { .channel = 84,
+ .freq = 5420, /* MHz */
+ .unk2 = 3613,
+ RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
+ 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
+ 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
+ PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
+ },
+ { .channel = 86,
+ .freq = 5430, /* MHz */
+ .unk2 = 3620,
+ RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
+ 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
+ 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
+ PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
+ },
+ { .channel = 88,
+ .freq = 5440, /* MHz */
+ .unk2 = 3627,
+ RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+ 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
+ 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
+ PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
+ },
+ { .channel = 90,
+ .freq = 5450, /* MHz */
+ .unk2 = 3633,
+ RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+ 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
+ 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
+ PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
+ },
+ { .channel = 92,
+ .freq = 5460, /* MHz */
+ .unk2 = 3640,
+ RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
+ 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
+ 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
+ PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
+ },
+ { .channel = 94,
+ .freq = 5470, /* MHz */
+ .unk2 = 3647,
+ RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
+ 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
+ 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
+ PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
+ },
+ { .channel = 96,
+ .freq = 5480, /* MHz */
+ .unk2 = 3653,
+ RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+ 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
+ 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+ PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
+ },
+ { .channel = 98,
+ .freq = 5490, /* MHz */
+ .unk2 = 3660,
+ RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+ 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
+ 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+ PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
+ },
+ { .channel = 100,
+ .freq = 5500, /* MHz */
+ .unk2 = 3667,
+ RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
+ 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
+ 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+ PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
+ },
+ { .channel = 102,
+ .freq = 5510, /* MHz */
+ .unk2 = 3673,
+ RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
+ 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
+ 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+ PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
+ },
+ { .channel = 104,
+ .freq = 5520, /* MHz */
+ .unk2 = 3680,
+ RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
+ 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+ 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+ PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
+ },
+ { .channel = 106,
+ .freq = 5530, /* MHz */
+ .unk2 = 3687,
+ RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
+ 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+ 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+ PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
+ },
+ { .channel = 108,
+ .freq = 5540, /* MHz */
+ .unk2 = 3693,
+ RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+ 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+ 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+ PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
+ },
+ { .channel = 110,
+ .freq = 5550, /* MHz */
+ .unk2 = 3700,
+ RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+ 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+ 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+ PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
+ },
+ { .channel = 112,
+ .freq = 5560, /* MHz */
+ .unk2 = 3707,
+ RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
+ 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+ 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+ PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
+ },
+ { .channel = 114,
+ .freq = 5570, /* MHz */
+ .unk2 = 3713,
+ RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
+ 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+ 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+ PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
+ },
+ { .channel = 116,
+ .freq = 5580, /* MHz */
+ .unk2 = 3720,
+ RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+ 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+ 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+ PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
+ },
+ { .channel = 118,
+ .freq = 5590, /* MHz */
+ .unk2 = 3727,
+ RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+ 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+ 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+ PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
+ },
+ { .channel = 120,
+ .freq = 5600, /* MHz */
+ .unk2 = 3733,
+ RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
+ 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
+ 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
+ PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
+ },
+ { .channel = 122,
+ .freq = 5610, /* MHz */
+ .unk2 = 3740,
+ RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
+ 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
+ 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
+ PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
+ },
+ { .channel = 124,
+ .freq = 5620, /* MHz */
+ .unk2 = 3747,
+ RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
+ 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
+ },
+ { .channel = 126,
+ .freq = 5630, /* MHz */
+ .unk2 = 3753,
+ RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
+ 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
+ },
+ { .channel = 128,
+ .freq = 5640, /* MHz */
+ .unk2 = 3760,
+ RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
+ },
+ { .channel = 130,
+ .freq = 5650, /* MHz */
+ .unk2 = 3767,
+ RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
+ },
+ { .channel = 132,
+ .freq = 5660, /* MHz */
+ .unk2 = 3773,
+ RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
+ },
+ { .channel = 134,
+ .freq = 5670, /* MHz */
+ .unk2 = 3780,
+ RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
+ },
+ { .channel = 136,
+ .freq = 5680, /* MHz */
+ .unk2 = 3787,
+ RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
+ },
+ { .channel = 138,
+ .freq = 5690, /* MHz */
+ .unk2 = 3793,
+ RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
+ },
+ { .channel = 140,
+ .freq = 5700, /* MHz */
+ .unk2 = 3800,
+ RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
+ },
+ { .channel = 142,
+ .freq = 5710, /* MHz */
+ .unk2 = 3807,
+ RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
+ },
+ { .channel = 144,
+ .freq = 5720, /* MHz */
+ .unk2 = 3813,
+ RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
+ },
+ { .channel = 145,
+ .freq = 5725, /* MHz */
+ .unk2 = 3817,
+ RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
+ },
+ { .channel = 146,
+ .freq = 5730, /* MHz */
+ .unk2 = 3820,
+ RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
+ },
+ { .channel = 147,
+ .freq = 5735, /* MHz */
+ .unk2 = 3823,
+ RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
+ },
+ { .channel = 148,
+ .freq = 5740, /* MHz */
+ .unk2 = 3827,
+ RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
+ },
+ { .channel = 149,
+ .freq = 5745, /* MHz */
+ .unk2 = 3830,
+ RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
+ },
+ { .channel = 150,
+ .freq = 5750, /* MHz */
+ .unk2 = 3833,
+ RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
+ },
+ { .channel = 151,
+ .freq = 5755, /* MHz */
+ .unk2 = 3837,
+ RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
+ },
+ { .channel = 152,
+ .freq = 5760, /* MHz */
+ .unk2 = 3840,
+ RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
+ },
+ { .channel = 153,
+ .freq = 5765, /* MHz */
+ .unk2 = 3843,
+ RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
+ },
+ { .channel = 154,
+ .freq = 5770, /* MHz */
+ .unk2 = 3847,
+ RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
+ },
+ { .channel = 155,
+ .freq = 5775, /* MHz */
+ .unk2 = 3850,
+ RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
+ },
+ { .channel = 156,
+ .freq = 5780, /* MHz */
+ .unk2 = 3853,
+ RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
+ },
+ { .channel = 157,
+ .freq = 5785, /* MHz */
+ .unk2 = 3857,
+ RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
+ },
+ { .channel = 158,
+ .freq = 5790, /* MHz */
+ .unk2 = 3860,
+ RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
+ },
+ { .channel = 159,
+ .freq = 5795, /* MHz */
+ .unk2 = 3863,
+ RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
+ },
+ { .channel = 160,
+ .freq = 5800, /* MHz */
+ .unk2 = 3867,
+ RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
+ },
+ { .channel = 161,
+ .freq = 5805, /* MHz */
+ .unk2 = 3870,
+ RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
+ },
+ { .channel = 162,
+ .freq = 5810, /* MHz */
+ .unk2 = 3873,
+ RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
+ },
+ { .channel = 163,
+ .freq = 5815, /* MHz */
+ .unk2 = 3877,
+ RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
+ },
+ { .channel = 164,
+ .freq = 5820, /* MHz */
+ .unk2 = 3880,
+ RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
+ },
+ { .channel = 165,
+ .freq = 5825, /* MHz */
+ .unk2 = 3883,
+ RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
+ },
+ { .channel = 166,
+ .freq = 5830, /* MHz */
+ .unk2 = 3887,
+ RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
+ },
+ { .channel = 168,
+ .freq = 5840, /* MHz */
+ .unk2 = 3893,
+ RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
+ },
+ { .channel = 170,
+ .freq = 5850, /* MHz */
+ .unk2 = 3900,
+ RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
+ },
+ { .channel = 172,
+ .freq = 5860, /* MHz */
+ .unk2 = 3907,
+ RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
+ },
+ { .channel = 174,
+ .freq = 5870, /* MHz */
+ .unk2 = 3913,
+ RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
+ },
+ { .channel = 176,
+ .freq = 5880, /* MHz */
+ .unk2 = 3920,
+ RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
+ },
+ { .channel = 178,
+ .freq = 5890, /* MHz */
+ .unk2 = 3927,
+ RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
+ },
+ { .channel = 180,
+ .freq = 5900, /* MHz */
+ .unk2 = 3933,
+ RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
+ },
+ { .channel = 182,
+ .freq = 5910, /* MHz */
+ .unk2 = 3940,
+ RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+ PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
+ },
+ { .channel = 1,
+ .freq = 2412, /* MHz */
+ .unk2 = 3216,
+ RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
+ 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
+ PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
+ },
+ { .channel = 2,
+ .freq = 2417, /* MHz */
+ .unk2 = 3223,
+ RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
+ 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
+ PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
+ },
+ { .channel = 3,
+ .freq = 2422, /* MHz */
+ .unk2 = 3229,
+ RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
+ 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
+ PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
+ },
+ { .channel = 4,
+ .freq = 2427, /* MHz */
+ .unk2 = 3236,
+ RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
+ 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
+ PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
+ },
+ { .channel = 5,
+ .freq = 2432, /* MHz */
+ .unk2 = 3243,
+ RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
+ 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
+ PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
+ },
+ { .channel = 6,
+ .freq = 2437, /* MHz */
+ .unk2 = 3249,
+ RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
+ 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
+ PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
+ },
+ { .channel = 7,
+ .freq = 2442, /* MHz */
+ .unk2 = 3256,
+ RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
+ 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
+ PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
+ },
+ { .channel = 8,
+ .freq = 2447, /* MHz */
+ .unk2 = 3263,
+ RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
+ 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
+ PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
+ },
+ { .channel = 9,
+ .freq = 2452, /* MHz */
+ .unk2 = 3269,
+ RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
+ 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
+ PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
+ },
+ { .channel = 10,
+ .freq = 2457, /* MHz */
+ .unk2 = 3276,
+ RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
+ 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
+ PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
+ },
+ { .channel = 11,
+ .freq = 2462, /* MHz */
+ .unk2 = 3283,
+ RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
+ 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
+ PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
+ },
+ { .channel = 12,
+ .freq = 2467, /* MHz */
+ .unk2 = 3289,
+ RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
+ 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
+ PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
+ },
+ { .channel = 13,
+ .freq = 2472, /* MHz */
+ .unk2 = 3296,
+ RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
+ 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
+ PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
+ },
+ { .channel = 14,
+ .freq = 2484, /* MHz */
+ .unk2 = 3312,
+ RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
+ 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
+ PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
+ },
+};
+
+void b2055_upload_inittab(struct b43_wldev *dev,
+ bool ghz5, bool ignore_uploadflag)
+{
+ const struct b2055_inittab_entry *e;
+ unsigned int i;
+ u16 value;
+
+ for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
+ e = &(b2055_inittab[i]);
+ if (!(e->flags & B2055_INITTAB_ENTRY_OK))
+ continue;
+ if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) {
+ if (ghz5)
+ value = e->ghz5;
+ else
+ value = e->ghz2;
+ b43_radio_write16(dev, i, value);
+ }
+ }
+}
+
+const struct b43_nphy_channeltab_entry_rev2 *
+b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
+{
+ const struct b43_nphy_channeltab_entry_rev2 *e;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev2); i++) {
+ e = &(b43_nphy_channeltab_rev2[i]);
+ if (e->channel == channel)
+ return e;
+ }
+
+ return NULL;
+}
diff --git a/drivers/net/wireless/b43/radio_2055.h b/drivers/net/wireless/b43/radio_2055.h
new file mode 100644
index 000000000000..d9bfa0f21b72
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2055.h
@@ -0,0 +1,254 @@
+#ifndef B43_RADIO_2055_H_
+#define B43_RADIO_2055_H_
+
+#include <linux/types.h>
+
+#include "tables_nphy.h"
+
+#define B2055_GEN_SPARE 0x00 /* GEN spare */
+#define B2055_SP_PINPD 0x02 /* SP PIN PD */
+#define B2055_C1_SP_RSSI 0x03 /* SP RSSI Core 1 */
+#define B2055_C1_SP_PDMISC 0x04 /* SP PD MISC Core 1 */
+#define B2055_C2_SP_RSSI 0x05 /* SP RSSI Core 2 */
+#define B2055_C2_SP_PDMISC 0x06 /* SP PD MISC Core 2 */
+#define B2055_C1_SP_RXGC1 0x07 /* SP RX GC1 Core 1 */
+#define B2055_C1_SP_RXGC2 0x08 /* SP RX GC2 Core 1 */
+#define B2055_C2_SP_RXGC1 0x09 /* SP RX GC1 Core 2 */
+#define B2055_C2_SP_RXGC2 0x0A /* SP RX GC2 Core 2 */
+#define B2055_C1_SP_LPFBWSEL 0x0B /* SP LPF BW select Core 1 */
+#define B2055_C2_SP_LPFBWSEL 0x0C /* SP LPF BW select Core 2 */
+#define B2055_C1_SP_TXGC1 0x0D /* SP TX GC1 Core 1 */
+#define B2055_C1_SP_TXGC2 0x0E /* SP TX GC2 Core 1 */
+#define B2055_C2_SP_TXGC1 0x0F /* SP TX GC1 Core 2 */
+#define B2055_C2_SP_TXGC2 0x10 /* SP TX GC2 Core 2 */
+#define B2055_MASTER1 0x11 /* Master control 1 */
+#define B2055_MASTER2 0x12 /* Master control 2 */
+#define B2055_PD_LGEN 0x13 /* PD LGEN */
+#define B2055_PD_PLLTS 0x14 /* PD PLL TS */
+#define B2055_C1_PD_LGBUF 0x15 /* PD Core 1 LGBUF */
+#define B2055_C1_PD_TX 0x16 /* PD Core 1 TX */
+#define B2055_C1_PD_RXTX 0x17 /* PD Core 1 RXTX */
+#define B2055_C1_PD_RSSIMISC 0x18 /* PD Core 1 RSSI MISC */
+#define B2055_C2_PD_LGBUF 0x19 /* PD Core 2 LGBUF */
+#define B2055_C2_PD_TX 0x1A /* PD Core 2 TX */
+#define B2055_C2_PD_RXTX 0x1B /* PD Core 2 RXTX */
+#define B2055_C2_PD_RSSIMISC 0x1C /* PD Core 2 RSSI MISC */
+#define B2055_PWRDET_LGEN 0x1D /* PWRDET LGEN */
+#define B2055_C1_PWRDET_LGBUF 0x1E /* PWRDET LGBUF Core 1 */
+#define B2055_C1_PWRDET_RXTX 0x1F /* PWRDET RXTX Core 1 */
+#define B2055_C2_PWRDET_LGBUF 0x20 /* PWRDET LGBUF Core 2 */
+#define B2055_C2_PWRDET_RXTX 0x21 /* PWRDET RXTX Core 2 */
+#define B2055_RRCCAL_CS 0x22 /* RRCCAL Control spare */
+#define B2055_RRCCAL_NOPTSEL 0x23 /* RRCCAL N OPT SEL */
+#define B2055_CAL_MISC 0x24 /* CAL MISC */
+#define B2055_CAL_COUT 0x25 /* CAL Counter out */
+#define B2055_CAL_COUT2 0x26 /* CAL Counter out 2 */
+#define B2055_CAL_CVARCTL 0x27 /* CAL CVAR Control */
+#define B2055_CAL_RVARCTL 0x28 /* CAL RVAR Control */
+#define B2055_CAL_LPOCTL 0x29 /* CAL LPO Control */
+#define B2055_CAL_TS 0x2A /* CAL TS */
+#define B2055_CAL_RCCALRTS 0x2B /* CAL RCCAL READ TS */
+#define B2055_CAL_RCALRTS 0x2C /* CAL RCAL READ TS */
+#define B2055_PADDRV 0x2D /* PAD driver */
+#define B2055_XOCTL1 0x2E /* XO Control 1 */
+#define B2055_XOCTL2 0x2F /* XO Control 2 */
+#define B2055_XOREGUL 0x30 /* XO Regulator */
+#define B2055_XOMISC 0x31 /* XO misc */
+#define B2055_PLL_LFC1 0x32 /* PLL LF C1 */
+#define B2055_PLL_CALVTH 0x33 /* PLL CAL VTH */
+#define B2055_PLL_LFC2 0x34 /* PLL LF C2 */
+#define B2055_PLL_REF 0x35 /* PLL reference */
+#define B2055_PLL_LFR1 0x36 /* PLL LF R1 */
+#define B2055_PLL_PFDCP 0x37 /* PLL PFD CP */
+#define B2055_PLL_IDAC_CPOPAMP 0x38 /* PLL IDAC CPOPAMP */
+#define B2055_PLL_CPREG 0x39 /* PLL CP Regulator */
+#define B2055_PLL_RCAL 0x3A /* PLL RCAL */
+#define B2055_RF_PLLMOD0 0x3B /* RF PLL MOD0 */
+#define B2055_RF_PLLMOD1 0x3C /* RF PLL MOD1 */
+#define B2055_RF_MMDIDAC1 0x3D /* RF MMD IDAC 1 */
+#define B2055_RF_MMDIDAC0 0x3E /* RF MMD IDAC 0 */
+#define B2055_RF_MMDSP 0x3F /* RF MMD spare */
+#define B2055_VCO_CAL1 0x40 /* VCO cal 1 */
+#define B2055_VCO_CAL2 0x41 /* VCO cal 2 */
+#define B2055_VCO_CAL3 0x42 /* VCO cal 3 */
+#define B2055_VCO_CAL4 0x43 /* VCO cal 4 */
+#define B2055_VCO_CAL5 0x44 /* VCO cal 5 */
+#define B2055_VCO_CAL6 0x45 /* VCO cal 6 */
+#define B2055_VCO_CAL7 0x46 /* VCO cal 7 */
+#define B2055_VCO_CAL8 0x47 /* VCO cal 8 */
+#define B2055_VCO_CAL9 0x48 /* VCO cal 9 */
+#define B2055_VCO_CAL10 0x49 /* VCO cal 10 */
+#define B2055_VCO_CAL11 0x4A /* VCO cal 11 */
+#define B2055_VCO_CAL12 0x4B /* VCO cal 12 */
+#define B2055_VCO_CAL13 0x4C /* VCO cal 13 */
+#define B2055_VCO_CAL14 0x4D /* VCO cal 14 */
+#define B2055_VCO_CAL15 0x4E /* VCO cal 15 */
+#define B2055_VCO_CAL16 0x4F /* VCO cal 16 */
+#define B2055_VCO_KVCO 0x50 /* VCO KVCO */
+#define B2055_VCO_CAPTAIL 0x51 /* VCO CAP TAIL */
+#define B2055_VCO_IDACVCO 0x52 /* VCO IDAC VCO */
+#define B2055_VCO_REG 0x53 /* VCO Regulator */
+#define B2055_PLL_RFVTH 0x54 /* PLL RF VTH */
+#define B2055_LGBUF_CENBUF 0x55 /* LGBUF CEN BUF */
+#define B2055_LGEN_TUNE1 0x56 /* LGEN tune 1 */
+#define B2055_LGEN_TUNE2 0x57 /* LGEN tune 2 */
+#define B2055_LGEN_IDAC1 0x58 /* LGEN IDAC 1 */
+#define B2055_LGEN_IDAC2 0x59 /* LGEN IDAC 2 */
+#define B2055_LGEN_BIASC 0x5A /* LGEN BIAS counter */
+#define B2055_LGEN_BIASIDAC 0x5B /* LGEN BIAS IDAC */
+#define B2055_LGEN_RCAL 0x5C /* LGEN RCAL */
+#define B2055_LGEN_DIV 0x5D /* LGEN div */
+#define B2055_LGEN_SPARE2 0x5E /* LGEN spare 2 */
+#define B2055_C1_LGBUF_ATUNE 0x5F /* Core 1 LGBUF A tune */
+#define B2055_C1_LGBUF_GTUNE 0x60 /* Core 1 LGBUF G tune */
+#define B2055_C1_LGBUF_DIV 0x61 /* Core 1 LGBUF div */
+#define B2055_C1_LGBUF_AIDAC 0x62 /* Core 1 LGBUF A IDAC */
+#define B2055_C1_LGBUF_GIDAC 0x63 /* Core 1 LGBUF G IDAC */
+#define B2055_C1_LGBUF_IDACFO 0x64 /* Core 1 LGBUF IDAC filter override */
+#define B2055_C1_LGBUF_SPARE 0x65 /* Core 1 LGBUF spare */
+#define B2055_C1_RX_RFSPC1 0x66 /* Core 1 RX RF SPC1 */
+#define B2055_C1_RX_RFR1 0x67 /* Core 1 RX RF reg 1 */
+#define B2055_C1_RX_RFR2 0x68 /* Core 1 RX RF reg 2 */
+#define B2055_C1_RX_RFRCAL 0x69 /* Core 1 RX RF RCAL */
+#define B2055_C1_RX_BB_BLCMP 0x6A /* Core 1 RX Baseband BUFI LPF CMP */
+#define B2055_C1_RX_BB_LPF 0x6B /* Core 1 RX Baseband LPF */
+#define B2055_C1_RX_BB_MIDACHP 0x6C /* Core 1 RX Baseband MIDAC High-pass */
+#define B2055_C1_RX_BB_VGA1IDAC 0x6D /* Core 1 RX Baseband VGA1 IDAC */
+#define B2055_C1_RX_BB_VGA2IDAC 0x6E /* Core 1 RX Baseband VGA2 IDAC */
+#define B2055_C1_RX_BB_VGA3IDAC 0x6F /* Core 1 RX Baseband VGA3 IDAC */
+#define B2055_C1_RX_BB_BUFOCTL 0x70 /* Core 1 RX Baseband BUFO Control */
+#define B2055_C1_RX_BB_RCCALCTL 0x71 /* Core 1 RX Baseband RCCAL Control */
+#define B2055_C1_RX_BB_RSSICTL1 0x72 /* Core 1 RX Baseband RSSI Control 1 */
+#define B2055_C1_RX_BB_RSSICTL2 0x73 /* Core 1 RX Baseband RSSI Control 2 */
+#define B2055_C1_RX_BB_RSSICTL3 0x74 /* Core 1 RX Baseband RSSI Control 3 */
+#define B2055_C1_RX_BB_RSSICTL4 0x75 /* Core 1 RX Baseband RSSI Control 4 */
+#define B2055_C1_RX_BB_RSSICTL5 0x76 /* Core 1 RX Baseband RSSI Control 5 */
+#define B2055_C1_RX_BB_REG 0x77 /* Core 1 RX Baseband Regulator */
+#define B2055_C1_RX_BB_SPARE1 0x78 /* Core 1 RX Baseband spare 1 */
+#define B2055_C1_RX_TXBBRCAL 0x79 /* Core 1 RX TX BB RCAL */
+#define B2055_C1_TX_RF_SPGA 0x7A /* Core 1 TX RF SGM PGA */
+#define B2055_C1_TX_RF_SPAD 0x7B /* Core 1 TX RF SGM PAD */
+#define B2055_C1_TX_RF_CNTPGA1 0x7C /* Core 1 TX RF counter PGA 1 */
+#define B2055_C1_TX_RF_CNTPAD1 0x7D /* Core 1 TX RF counter PAD 1 */
+#define B2055_C1_TX_RF_PGAIDAC 0x7E /* Core 1 TX RF PGA IDAC */
+#define B2055_C1_TX_PGAPADTN 0x7F /* Core 1 TX PGA PAD TN */
+#define B2055_C1_TX_PADIDAC1 0x80 /* Core 1 TX PAD IDAC 1 */
+#define B2055_C1_TX_PADIDAC2 0x81 /* Core 1 TX PAD IDAC 2 */
+#define B2055_C1_TX_MXBGTRIM 0x82 /* Core 1 TX MX B/G TRIM */
+#define B2055_C1_TX_RF_RCAL 0x83 /* Core 1 TX RF RCAL */
+#define B2055_C1_TX_RF_PADTSSI1 0x84 /* Core 1 TX RF PAD TSSI1 */
+#define B2055_C1_TX_RF_PADTSSI2 0x85 /* Core 1 TX RF PAD TSSI2 */
+#define B2055_C1_TX_RF_SPARE 0x86 /* Core 1 TX RF spare */
+#define B2055_C1_TX_RF_IQCAL1 0x87 /* Core 1 TX RF I/Q CAL 1 */
+#define B2055_C1_TX_RF_IQCAL2 0x88 /* Core 1 TX RF I/Q CAL 2 */
+#define B2055_C1_TXBB_RCCAL 0x89 /* Core 1 TXBB RC CAL Control */
+#define B2055_C1_TXBB_LPF1 0x8A /* Core 1 TXBB LPF 1 */
+#define B2055_C1_TX_VOSCNCL 0x8B /* Core 1 TX VOS CNCL */
+#define B2055_C1_TX_LPF_MXGMIDAC 0x8C /* Core 1 TX LPF MXGM IDAC */
+#define B2055_C1_TX_BB_MXGM 0x8D /* Core 1 TX BB MXGM */
+#define B2055_C2_LGBUF_ATUNE 0x8E /* Core 2 LGBUF A tune */
+#define B2055_C2_LGBUF_GTUNE 0x8F /* Core 2 LGBUF G tune */
+#define B2055_C2_LGBUF_DIV 0x90 /* Core 2 LGBUF div */
+#define B2055_C2_LGBUF_AIDAC 0x91 /* Core 2 LGBUF A IDAC */
+#define B2055_C2_LGBUF_GIDAC 0x92 /* Core 2 LGBUF G IDAC */
+#define B2055_C2_LGBUF_IDACFO 0x93 /* Core 2 LGBUF IDAC filter override */
+#define B2055_C2_LGBUF_SPARE 0x94 /* Core 2 LGBUF spare */
+#define B2055_C2_RX_RFSPC1 0x95 /* Core 2 RX RF SPC1 */
+#define B2055_C2_RX_RFR1 0x96 /* Core 2 RX RF reg 1 */
+#define B2055_C2_RX_RFR2 0x97 /* Core 2 RX RF reg 2 */
+#define B2055_C2_RX_RFRCAL 0x98 /* Core 2 RX RF RCAL */
+#define B2055_C2_RX_BB_BLCMP 0x99 /* Core 2 RX Baseband BUFI LPF CMP */
+#define B2055_C2_RX_BB_LPF 0x9A /* Core 2 RX Baseband LPF */
+#define B2055_C2_RX_BB_MIDACHP 0x9B /* Core 2 RX Baseband MIDAC High-pass */
+#define B2055_C2_RX_BB_VGA1IDAC 0x9C /* Core 2 RX Baseband VGA1 IDAC */
+#define B2055_C2_RX_BB_VGA2IDAC 0x9D /* Core 2 RX Baseband VGA2 IDAC */
+#define B2055_C2_RX_BB_VGA3IDAC 0x9E /* Core 2 RX Baseband VGA3 IDAC */
+#define B2055_C2_RX_BB_BUFOCTL 0x9F /* Core 2 RX Baseband BUFO Control */
+#define B2055_C2_RX_BB_RCCALCTL 0xA0 /* Core 2 RX Baseband RCCAL Control */
+#define B2055_C2_RX_BB_RSSICTL1 0xA1 /* Core 2 RX Baseband RSSI Control 1 */
+#define B2055_C2_RX_BB_RSSICTL2 0xA2 /* Core 2 RX Baseband RSSI Control 2 */
+#define B2055_C2_RX_BB_RSSICTL3 0xA3 /* Core 2 RX Baseband RSSI Control 3 */
+#define B2055_C2_RX_BB_RSSICTL4 0xA4 /* Core 2 RX Baseband RSSI Control 4 */
+#define B2055_C2_RX_BB_RSSICTL5 0xA5 /* Core 2 RX Baseband RSSI Control 5 */
+#define B2055_C2_RX_BB_REG 0xA6 /* Core 2 RX Baseband Regulator */
+#define B2055_C2_RX_BB_SPARE1 0xA7 /* Core 2 RX Baseband spare 1 */
+#define B2055_C2_RX_TXBBRCAL 0xA8 /* Core 2 RX TX BB RCAL */
+#define B2055_C2_TX_RF_SPGA 0xA9 /* Core 2 TX RF SGM PGA */
+#define B2055_C2_TX_RF_SPAD 0xAA /* Core 2 TX RF SGM PAD */
+#define B2055_C2_TX_RF_CNTPGA1 0xAB /* Core 2 TX RF counter PGA 1 */
+#define B2055_C2_TX_RF_CNTPAD1 0xAC /* Core 2 TX RF counter PAD 1 */
+#define B2055_C2_TX_RF_PGAIDAC 0xAD /* Core 2 TX RF PGA IDAC */
+#define B2055_C2_TX_PGAPADTN 0xAE /* Core 2 TX PGA PAD TN */
+#define B2055_C2_TX_PADIDAC1 0xAF /* Core 2 TX PAD IDAC 1 */
+#define B2055_C2_TX_PADIDAC2 0xB0 /* Core 2 TX PAD IDAC 2 */
+#define B2055_C2_TX_MXBGTRIM 0xB1 /* Core 2 TX MX B/G TRIM */
+#define B2055_C2_TX_RF_RCAL 0xB2 /* Core 2 TX RF RCAL */
+#define B2055_C2_TX_RF_PADTSSI1 0xB3 /* Core 2 TX RF PAD TSSI1 */
+#define B2055_C2_TX_RF_PADTSSI2 0xB4 /* Core 2 TX RF PAD TSSI2 */
+#define B2055_C2_TX_RF_SPARE 0xB5 /* Core 2 TX RF spare */
+#define B2055_C2_TX_RF_IQCAL1 0xB6 /* Core 2 TX RF I/Q CAL 1 */
+#define B2055_C2_TX_RF_IQCAL2 0xB7 /* Core 2 TX RF I/Q CAL 2 */
+#define B2055_C2_TXBB_RCCAL 0xB8 /* Core 2 TXBB RC CAL Control */
+#define B2055_C2_TXBB_LPF1 0xB9 /* Core 2 TXBB LPF 1 */
+#define B2055_C2_TX_VOSCNCL 0xBA /* Core 2 TX VOS CNCL */
+#define B2055_C2_TX_LPF_MXGMIDAC 0xBB /* Core 2 TX LPF MXGM IDAC */
+#define B2055_C2_TX_BB_MXGM 0xBC /* Core 2 TX BB MXGM */
+#define B2055_PRG_GCHP21 0xBD /* PRG GC HPVGA23 21 */
+#define B2055_PRG_GCHP22 0xBE /* PRG GC HPVGA23 22 */
+#define B2055_PRG_GCHP23 0xBF /* PRG GC HPVGA23 23 */
+#define B2055_PRG_GCHP24 0xC0 /* PRG GC HPVGA23 24 */
+#define B2055_PRG_GCHP25 0xC1 /* PRG GC HPVGA23 25 */
+#define B2055_PRG_GCHP26 0xC2 /* PRG GC HPVGA23 26 */
+#define B2055_PRG_GCHP27 0xC3 /* PRG GC HPVGA23 27 */
+#define B2055_PRG_GCHP28 0xC4 /* PRG GC HPVGA23 28 */
+#define B2055_PRG_GCHP29 0xC5 /* PRG GC HPVGA23 29 */
+#define B2055_PRG_GCHP30 0xC6 /* PRG GC HPVGA23 30 */
+#define B2055_C1_LNA_GAINBST 0xCD /* Core 1 LNA GAINBST */
+#define B2055_C1_B0NB_RSSIVCM 0xD2 /* Core 1 B0 narrow-band RSSI VCM */
+#define B2055_C1_GENSPARE2 0xD6 /* Core 1 GEN spare 2 */
+#define B2055_C2_LNA_GAINBST 0xD9 /* Core 2 LNA GAINBST */
+#define B2055_C2_B0NB_RSSIVCM 0xDE /* Core 2 B0 narrow-band RSSI VCM */
+#define B2055_C2_GENSPARE2 0xE2 /* Core 2 GEN spare 2 */
+
+struct b43_nphy_channeltab_entry_rev2 {
+ /* The channel number */
+ u8 channel;
+ /* The channel frequency in MHz */
+ u16 freq;
+ /* An unknown value */
+ u16 unk2;
+ /* Radio register values on channelswitch */
+ u8 radio_pll_ref;
+ u8 radio_rf_pllmod0;
+ u8 radio_rf_pllmod1;
+ u8 radio_vco_captail;
+ u8 radio_vco_cal1;
+ u8 radio_vco_cal2;
+ u8 radio_pll_lfc1;
+ u8 radio_pll_lfr1;
+ u8 radio_pll_lfc2;
+ u8 radio_lgbuf_cenbuf;
+ u8 radio_lgen_tune1;
+ u8 radio_lgen_tune2;
+ u8 radio_c1_lgbuf_atune;
+ u8 radio_c1_lgbuf_gtune;
+ u8 radio_c1_rx_rfr1;
+ u8 radio_c1_tx_pgapadtn;
+ u8 radio_c1_tx_mxbgtrim;
+ u8 radio_c2_lgbuf_atune;
+ u8 radio_c2_lgbuf_gtune;
+ u8 radio_c2_rx_rfr1;
+ u8 radio_c2_tx_pgapadtn;
+ u8 radio_c2_tx_mxbgtrim;
+ /* PHY register values on channelswitch */
+ struct b43_phy_n_sfo_cfg phy_regs;
+};
+
+/* Upload the default register value table.
+ * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
+ * table is uploaded. If "ignore_uploadflag" is true, we upload any value
+ * and ignore the "UPLOAD" flag. */
+void b2055_upload_inittab(struct b43_wldev *dev,
+ bool ghz5, bool ignore_uploadflag);
+
+#endif /* B43_RADIO_2055_H_ */
diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c
new file mode 100644
index 000000000000..d8563192ce56
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2056.c
@@ -0,0 +1,43 @@
+/*
+
+ Broadcom B43 wireless driver
+ IEEE 802.11n 2056 radio device data tables
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "radio_2056.h"
+#include "phy_common.h"
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = {
+};
+
+const struct b43_nphy_channeltab_entry_rev3 *
+b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
+{
+ const struct b43_nphy_channeltab_entry_rev3 *e;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) {
+ e = &(b43_nphy_channeltab_rev3[i]);
+ if (e->freq == freq)
+ return e;
+ }
+
+ return NULL;
+}
diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h
new file mode 100644
index 000000000000..fda6dafecb8c
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2056.h
@@ -0,0 +1,42 @@
+/*
+
+ Broadcom B43 wireless driver
+
+ Copyright (c) 2010 Rafał Miłecki <zajec5@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; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef B43_RADIO_2056_H_
+#define B43_RADIO_2056_H_
+
+#include <linux/types.h>
+
+#include "tables_nphy.h"
+
+struct b43_nphy_channeltab_entry_rev3 {
+ /* The channel number */
+ u8 channel;
+ /* The channel frequency in MHz */
+ u16 freq;
+ /* Radio register values on channelswitch */
+ /* TODO */
+ /* PHY register values on channelswitch */
+ struct b43_phy_n_sfo_cfg phy_regs;
+};
+
+#endif /* B43_RADIO_2056_H_ */
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index d96e870ab8fe..d60db078eae2 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -1,7 +1,7 @@
/*
Broadcom B43 wireless driver
- IEEE 802.11n PHY and radio device data tables
+ IEEE 802.11n PHY data tables
Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
@@ -27,1315 +27,6 @@
#include "phy_common.h"
#include "phy_n.h"
-
-struct b2055_inittab_entry {
- /* Value to write if we use the 5GHz band. */
- u16 ghz5;
- /* Value to write if we use the 2.4GHz band. */
- u16 ghz2;
- /* Flags */
- u8 flags;
-#define B2055_INITTAB_ENTRY_OK 0x01
-#define B2055_INITTAB_UPLOAD 0x02
-};
-#define UPLOAD .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD
-#define NOUPLOAD .flags = B2055_INITTAB_ENTRY_OK
-
-static const struct b2055_inittab_entry b2055_inittab [] = {
- [B2055_SP_PINPD] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
- [B2055_C1_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C1_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
- [B2055_C2_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
- [B2055_C1_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
- [B2055_C1_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
- [B2055_C2_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
- [B2055_C2_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
- [B2055_C1_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
- [B2055_C2_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
- [B2055_C1_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
- [B2055_C1_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
- [B2055_C2_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
- [B2055_C2_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
- [B2055_MASTER1] = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, },
- [B2055_MASTER2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
- [B2055_PD_LGEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_PD_PLLTS] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
- [B2055_C1_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C1_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C1_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C1_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_PWRDET_LGEN] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
- [B2055_C1_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
- [B2055_C1_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
- [B2055_C2_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
- [B2055_C2_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
- [B2055_RRCCAL_CS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_RRCCAL_NOPTSEL] = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, },
- [B2055_CAL_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_CAL_COUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_CAL_COUT2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_CAL_CVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_CAL_RVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_CAL_LPOCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_CAL_TS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_CAL_RCCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_CAL_RCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_PADDRV] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
- [B2055_XOCTL1] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
- [B2055_XOCTL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_XOREGUL] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
- [B2055_XOMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_PLL_LFC1] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
- [B2055_PLL_CALVTH] = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, },
- [B2055_PLL_LFC2] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
- [B2055_PLL_REF] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
- [B2055_PLL_LFR1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
- [B2055_PLL_PFDCP] = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, },
- [B2055_PLL_IDAC_CPOPAMP] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
- [B2055_PLL_CPREG] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
- [B2055_PLL_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
- [B2055_RF_PLLMOD0] = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, },
- [B2055_RF_PLLMOD1] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
- [B2055_RF_MMDIDAC1] = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, },
- [B2055_RF_MMDIDAC0] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_RF_MMDSP] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_VCO_CAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_VCO_CAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_VCO_CAL3] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
- [B2055_VCO_CAL4] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
- [B2055_VCO_CAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
- [B2055_VCO_CAL6] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
- [B2055_VCO_CAL7] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
- [B2055_VCO_CAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
- [B2055_VCO_CAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
- [B2055_VCO_CAL10] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
- [B2055_VCO_CAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
- [B2055_VCO_CAL12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_VCO_CAL13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_VCO_CAL14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_VCO_CAL15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_VCO_CAL16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_VCO_KVCO] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
- [B2055_VCO_CAPTAIL] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
- [B2055_VCO_IDACVCO] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
- [B2055_VCO_REG] = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, },
- [B2055_PLL_RFVTH] = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, },
- [B2055_LGBUF_CENBUF] = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, },
- [B2055_LGEN_TUNE1] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
- [B2055_LGEN_TUNE2] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
- [B2055_LGEN_IDAC1] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_LGEN_IDAC2] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_LGEN_BIASC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_LGEN_BIASIDAC] = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, },
- [B2055_LGEN_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
- [B2055_LGEN_DIV] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
- [B2055_LGEN_SPARE2] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
- [B2055_C1_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
- [B2055_C1_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_C1_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_C1_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
- [B2055_C1_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_C1_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C1_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
- [B2055_C1_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
- [B2055_C1_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
- [B2055_C1_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
- [B2055_C1_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
- [B2055_C1_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
- [B2055_C1_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
- [B2055_C1_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
- [B2055_C1_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
- [B2055_C1_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
- [B2055_C1_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
- [B2055_C1_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
- [B2055_C1_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
- [B2055_C1_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
- [B2055_C1_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
- [B2055_C1_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
- [B2055_C1_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
- [B2055_C1_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
- [B2055_C1_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
- [B2055_C1_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C1_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
- [B2055_C1_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
- [B2055_C1_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
- [B2055_C1_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
- [B2055_C1_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
- [B2055_C1_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
- [B2055_C1_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
- [B2055_C1_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
- [B2055_C1_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
- [B2055_C1_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_C1_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
- [B2055_C1_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
- [B2055_C1_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
- [B2055_C1_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
- [B2055_C1_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
- [B2055_C1_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
- [B2055_C1_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
- [B2055_C1_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
- [B2055_C1_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C1_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
- [B2055_C1_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
- [B2055_C2_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_C2_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_C2_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
- [B2055_C2_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_C2_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
- [B2055_C2_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
- [B2055_C2_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
- [B2055_C2_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
- [B2055_C2_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
- [B2055_C2_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
- [B2055_C2_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
- [B2055_C2_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
- [B2055_C2_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
- [B2055_C2_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
- [B2055_C2_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
- [B2055_C2_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
- [B2055_C2_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
- [B2055_C2_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
- [B2055_C2_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
- [B2055_C2_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
- [B2055_C2_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
- [B2055_C2_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
- [B2055_C2_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
- [B2055_C2_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
- [B2055_C2_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
- [B2055_C2_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
- [B2055_C2_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
- [B2055_C2_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
- [B2055_C2_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
- [B2055_C2_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
- [B2055_C2_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
- [B2055_C2_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
- [B2055_C2_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [B2055_C2_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
- [B2055_C2_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
- [B2055_C2_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
- [B2055_C2_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
- [B2055_C2_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
- [B2055_C2_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
- [B2055_C2_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
- [B2055_C2_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
- [B2055_C2_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
- [B2055_C2_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_PRG_GCHP21] = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, },
- [B2055_PRG_GCHP22] = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, },
- [B2055_PRG_GCHP23] = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, },
- [B2055_PRG_GCHP24] = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, },
- [B2055_PRG_GCHP25] = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, },
- [B2055_PRG_GCHP26] = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, },
- [B2055_PRG_GCHP27] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
- [B2055_PRG_GCHP28] = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, },
- [B2055_PRG_GCHP29] = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, },
- [B2055_PRG_GCHP30] = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, },
- [0xC7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xC8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xC9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xCA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
- [B2055_C1_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [0xD3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xD4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xD5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C1_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
- [B2055_C2_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
- [0xDF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xE0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [B2055_C2_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-};
-
-
-void b2055_upload_inittab(struct b43_wldev *dev,
- bool ghz5, bool ignore_uploadflag)
-{
- const struct b2055_inittab_entry *e;
- unsigned int i;
- u16 value;
-
- for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
- e = &(b2055_inittab[i]);
- if (!(e->flags & B2055_INITTAB_ENTRY_OK))
- continue;
- if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) {
- if (ghz5)
- value = e->ghz5;
- else
- value = e->ghz2;
- b43_radio_write16(dev, i, value);
- }
- }
-}
-
-
-#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \
- r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \
- .radio_pll_ref = r0, \
- .radio_rf_pllmod0 = r1, \
- .radio_rf_pllmod1 = r2, \
- .radio_vco_captail = r3, \
- .radio_vco_cal1 = r4, \
- .radio_vco_cal2 = r5, \
- .radio_pll_lfc1 = r6, \
- .radio_pll_lfr1 = r7, \
- .radio_pll_lfc2 = r8, \
- .radio_lgbuf_cenbuf = r9, \
- .radio_lgen_tune1 = r10, \
- .radio_lgen_tune2 = r11, \
- .radio_c1_lgbuf_atune = r12, \
- .radio_c1_lgbuf_gtune = r13, \
- .radio_c1_rx_rfr1 = r14, \
- .radio_c1_tx_pgapadtn = r15, \
- .radio_c1_tx_mxbgtrim = r16, \
- .radio_c2_lgbuf_atune = r17, \
- .radio_c2_lgbuf_gtune = r18, \
- .radio_c2_rx_rfr1 = r19, \
- .radio_c2_tx_pgapadtn = r20, \
- .radio_c2_tx_mxbgtrim = r21
-
-#define PHYREGS(r0, r1, r2, r3, r4, r5) \
- .phy_regs.phy_bw1a = r0, \
- .phy_regs.phy_bw2 = r1, \
- .phy_regs.phy_bw3 = r2, \
- .phy_regs.phy_bw4 = r3, \
- .phy_regs.phy_bw5 = r4, \
- .phy_regs.phy_bw6 = r5
-
-static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab[] = {
- { .channel = 184,
- .freq = 4920, /* MHz */
- .unk2 = 3280,
- RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
- },
- { .channel = 186,
- .freq = 4930, /* MHz */
- .unk2 = 3287,
- RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
- },
- { .channel = 188,
- .freq = 4940, /* MHz */
- .unk2 = 3293,
- RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
- },
- { .channel = 190,
- .freq = 4950, /* MHz */
- .unk2 = 3300,
- RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
- },
- { .channel = 192,
- .freq = 4960, /* MHz */
- .unk2 = 3307,
- RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
- },
- { .channel = 194,
- .freq = 4970, /* MHz */
- .unk2 = 3313,
- RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
- },
- { .channel = 196,
- .freq = 4980, /* MHz */
- .unk2 = 3320,
- RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
- },
- { .channel = 198,
- .freq = 4990, /* MHz */
- .unk2 = 3327,
- RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
- },
- { .channel = 200,
- .freq = 5000, /* MHz */
- .unk2 = 3333,
- RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
- },
- { .channel = 202,
- .freq = 5010, /* MHz */
- .unk2 = 3340,
- RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
- },
- { .channel = 204,
- .freq = 5020, /* MHz */
- .unk2 = 3347,
- RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
- },
- { .channel = 206,
- .freq = 5030, /* MHz */
- .unk2 = 3353,
- RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
- },
- { .channel = 208,
- .freq = 5040, /* MHz */
- .unk2 = 3360,
- RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
- },
- { .channel = 210,
- .freq = 5050, /* MHz */
- .unk2 = 3367,
- RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
- 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
- },
- { .channel = 212,
- .freq = 5060, /* MHz */
- .unk2 = 3373,
- RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
- 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
- PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
- },
- { .channel = 214,
- .freq = 5070, /* MHz */
- .unk2 = 3380,
- RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
- 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
- 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
- PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
- },
- { .channel = 216,
- .freq = 5080, /* MHz */
- .unk2 = 3387,
- RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
- 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
- 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
- PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
- },
- { .channel = 218,
- .freq = 5090, /* MHz */
- .unk2 = 3393,
- RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
- 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
- 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
- PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
- },
- { .channel = 220,
- .freq = 5100, /* MHz */
- .unk2 = 3400,
- RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
- 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
- 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
- PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
- },
- { .channel = 222,
- .freq = 5110, /* MHz */
- .unk2 = 3407,
- RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
- 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
- 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
- PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
- },
- { .channel = 224,
- .freq = 5120, /* MHz */
- .unk2 = 3413,
- RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
- 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
- 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
- PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
- },
- { .channel = 226,
- .freq = 5130, /* MHz */
- .unk2 = 3420,
- RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
- 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
- 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
- PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
- },
- { .channel = 228,
- .freq = 5140, /* MHz */
- .unk2 = 3427,
- RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
- 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
- 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
- PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
- },
- { .channel = 32,
- .freq = 5160, /* MHz */
- .unk2 = 3440,
- RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
- 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
- 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
- PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
- },
- { .channel = 34,
- .freq = 5170, /* MHz */
- .unk2 = 3447,
- RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
- 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
- 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
- PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
- },
- { .channel = 36,
- .freq = 5180, /* MHz */
- .unk2 = 3453,
- RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
- 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
- 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
- PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
- },
- { .channel = 38,
- .freq = 5190, /* MHz */
- .unk2 = 3460,
- RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
- 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
- 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
- PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
- },
- { .channel = 40,
- .freq = 5200, /* MHz */
- .unk2 = 3467,
- RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
- 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
- 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
- PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
- },
- { .channel = 42,
- .freq = 5210, /* MHz */
- .unk2 = 3473,
- RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
- 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
- 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
- PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
- },
- { .channel = 44,
- .freq = 5220, /* MHz */
- .unk2 = 3480,
- RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
- 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
- 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
- PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
- },
- { .channel = 46,
- .freq = 5230, /* MHz */
- .unk2 = 3487,
- RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
- 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
- 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
- PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
- },
- { .channel = 48,
- .freq = 5240, /* MHz */
- .unk2 = 3493,
- RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
- 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
- 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
- PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
- },
- { .channel = 50,
- .freq = 5250, /* MHz */
- .unk2 = 3500,
- RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
- 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
- 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
- PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
- },
- { .channel = 52,
- .freq = 5260, /* MHz */
- .unk2 = 3507,
- RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
- 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
- 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
- PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
- },
- { .channel = 54,
- .freq = 5270, /* MHz */
- .unk2 = 3513,
- RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
- 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
- 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
- PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
- },
- { .channel = 56,
- .freq = 5280, /* MHz */
- .unk2 = 3520,
- RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
- 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
- 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
- PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
- },
- { .channel = 58,
- .freq = 5290, /* MHz */
- .unk2 = 3527,
- RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
- 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
- 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
- PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
- },
- { .channel = 60,
- .freq = 5300, /* MHz */
- .unk2 = 3533,
- RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
- 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
- 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
- PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
- },
- { .channel = 62,
- .freq = 5310, /* MHz */
- .unk2 = 3540,
- RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
- 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
- 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
- PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
- },
- { .channel = 64,
- .freq = 5320, /* MHz */
- .unk2 = 3547,
- RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
- 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
- 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
- PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
- },
- { .channel = 66,
- .freq = 5330, /* MHz */
- .unk2 = 3553,
- RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
- 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
- 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
- PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
- },
- { .channel = 68,
- .freq = 5340, /* MHz */
- .unk2 = 3560,
- RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
- 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
- 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
- PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
- },
- { .channel = 70,
- .freq = 5350, /* MHz */
- .unk2 = 3567,
- RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
- 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
- 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
- PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
- },
- { .channel = 72,
- .freq = 5360, /* MHz */
- .unk2 = 3573,
- RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
- 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
- 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
- PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
- },
- { .channel = 74,
- .freq = 5370, /* MHz */
- .unk2 = 3580,
- RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
- 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
- 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
- PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
- },
- { .channel = 76,
- .freq = 5380, /* MHz */
- .unk2 = 3587,
- RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
- 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
- 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
- PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
- },
- { .channel = 78,
- .freq = 5390, /* MHz */
- .unk2 = 3593,
- RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
- 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
- 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
- PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
- },
- { .channel = 80,
- .freq = 5400, /* MHz */
- .unk2 = 3600,
- RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
- 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
- 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
- PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
- },
- { .channel = 82,
- .freq = 5410, /* MHz */
- .unk2 = 3607,
- RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
- 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
- 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
- PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
- },
- { .channel = 84,
- .freq = 5420, /* MHz */
- .unk2 = 3613,
- RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
- 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
- 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
- PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
- },
- { .channel = 86,
- .freq = 5430, /* MHz */
- .unk2 = 3620,
- RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
- 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
- 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
- PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
- },
- { .channel = 88,
- .freq = 5440, /* MHz */
- .unk2 = 3627,
- RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
- 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
- 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
- PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
- },
- { .channel = 90,
- .freq = 5450, /* MHz */
- .unk2 = 3633,
- RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
- 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
- 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
- PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
- },
- { .channel = 92,
- .freq = 5460, /* MHz */
- .unk2 = 3640,
- RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
- 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
- 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
- PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
- },
- { .channel = 94,
- .freq = 5470, /* MHz */
- .unk2 = 3647,
- RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
- 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
- 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
- PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
- },
- { .channel = 96,
- .freq = 5480, /* MHz */
- .unk2 = 3653,
- RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
- 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
- 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
- },
- { .channel = 98,
- .freq = 5490, /* MHz */
- .unk2 = 3660,
- RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
- 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
- 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
- },
- { .channel = 100,
- .freq = 5500, /* MHz */
- .unk2 = 3667,
- RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
- 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
- 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
- },
- { .channel = 102,
- .freq = 5510, /* MHz */
- .unk2 = 3673,
- RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
- 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
- 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
- },
- { .channel = 104,
- .freq = 5520, /* MHz */
- .unk2 = 3680,
- RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
- 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
- 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
- },
- { .channel = 106,
- .freq = 5530, /* MHz */
- .unk2 = 3687,
- RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
- 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
- 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
- },
- { .channel = 108,
- .freq = 5540, /* MHz */
- .unk2 = 3693,
- RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
- 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
- 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
- },
- { .channel = 110,
- .freq = 5550, /* MHz */
- .unk2 = 3700,
- RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
- 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
- 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
- },
- { .channel = 112,
- .freq = 5560, /* MHz */
- .unk2 = 3707,
- RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
- 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
- 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
- },
- { .channel = 114,
- .freq = 5570, /* MHz */
- .unk2 = 3713,
- RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
- 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
- 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
- },
- { .channel = 116,
- .freq = 5580, /* MHz */
- .unk2 = 3720,
- RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
- 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
- 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
- },
- { .channel = 118,
- .freq = 5590, /* MHz */
- .unk2 = 3727,
- RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
- 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
- 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
- },
- { .channel = 120,
- .freq = 5600, /* MHz */
- .unk2 = 3733,
- RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
- 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
- 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
- },
- { .channel = 122,
- .freq = 5610, /* MHz */
- .unk2 = 3740,
- RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
- 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
- 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
- },
- { .channel = 124,
- .freq = 5620, /* MHz */
- .unk2 = 3747,
- RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
- 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
- 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
- },
- { .channel = 126,
- .freq = 5630, /* MHz */
- .unk2 = 3753,
- RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
- 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
- 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
- },
- { .channel = 128,
- .freq = 5640, /* MHz */
- .unk2 = 3760,
- RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
- },
- { .channel = 130,
- .freq = 5650, /* MHz */
- .unk2 = 3767,
- RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
- },
- { .channel = 132,
- .freq = 5660, /* MHz */
- .unk2 = 3773,
- RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
- },
- { .channel = 134,
- .freq = 5670, /* MHz */
- .unk2 = 3780,
- RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
- },
- { .channel = 136,
- .freq = 5680, /* MHz */
- .unk2 = 3787,
- RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
- },
- { .channel = 138,
- .freq = 5690, /* MHz */
- .unk2 = 3793,
- RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
- },
- { .channel = 140,
- .freq = 5700, /* MHz */
- .unk2 = 3800,
- RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
- },
- { .channel = 142,
- .freq = 5710, /* MHz */
- .unk2 = 3807,
- RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
- },
- { .channel = 144,
- .freq = 5720, /* MHz */
- .unk2 = 3813,
- RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
- },
- { .channel = 145,
- .freq = 5725, /* MHz */
- .unk2 = 3817,
- RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
- },
- { .channel = 146,
- .freq = 5730, /* MHz */
- .unk2 = 3820,
- RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
- },
- { .channel = 147,
- .freq = 5735, /* MHz */
- .unk2 = 3823,
- RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
- },
- { .channel = 148,
- .freq = 5740, /* MHz */
- .unk2 = 3827,
- RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
- },
- { .channel = 149,
- .freq = 5745, /* MHz */
- .unk2 = 3830,
- RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
- },
- { .channel = 150,
- .freq = 5750, /* MHz */
- .unk2 = 3833,
- RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
- },
- { .channel = 151,
- .freq = 5755, /* MHz */
- .unk2 = 3837,
- RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
- },
- { .channel = 152,
- .freq = 5760, /* MHz */
- .unk2 = 3840,
- RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
- },
- { .channel = 153,
- .freq = 5765, /* MHz */
- .unk2 = 3843,
- RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
- },
- { .channel = 154,
- .freq = 5770, /* MHz */
- .unk2 = 3847,
- RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
- },
- { .channel = 155,
- .freq = 5775, /* MHz */
- .unk2 = 3850,
- RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
- },
- { .channel = 156,
- .freq = 5780, /* MHz */
- .unk2 = 3853,
- RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
- },
- { .channel = 157,
- .freq = 5785, /* MHz */
- .unk2 = 3857,
- RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
- },
- { .channel = 158,
- .freq = 5790, /* MHz */
- .unk2 = 3860,
- RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
- },
- { .channel = 159,
- .freq = 5795, /* MHz */
- .unk2 = 3863,
- RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
- },
- { .channel = 160,
- .freq = 5800, /* MHz */
- .unk2 = 3867,
- RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
- },
- { .channel = 161,
- .freq = 5805, /* MHz */
- .unk2 = 3870,
- RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
- },
- { .channel = 162,
- .freq = 5810, /* MHz */
- .unk2 = 3873,
- RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
- },
- { .channel = 163,
- .freq = 5815, /* MHz */
- .unk2 = 3877,
- RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
- },
- { .channel = 164,
- .freq = 5820, /* MHz */
- .unk2 = 3880,
- RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
- },
- { .channel = 165,
- .freq = 5825, /* MHz */
- .unk2 = 3883,
- RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
- },
- { .channel = 166,
- .freq = 5830, /* MHz */
- .unk2 = 3887,
- RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
- },
- { .channel = 168,
- .freq = 5840, /* MHz */
- .unk2 = 3893,
- RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
- },
- { .channel = 170,
- .freq = 5850, /* MHz */
- .unk2 = 3900,
- RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
- },
- { .channel = 172,
- .freq = 5860, /* MHz */
- .unk2 = 3907,
- RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
- },
- { .channel = 174,
- .freq = 5870, /* MHz */
- .unk2 = 3913,
- RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
- },
- { .channel = 176,
- .freq = 5880, /* MHz */
- .unk2 = 3920,
- RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
- },
- { .channel = 178,
- .freq = 5890, /* MHz */
- .unk2 = 3927,
- RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
- },
- { .channel = 180,
- .freq = 5900, /* MHz */
- .unk2 = 3933,
- RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
- },
- { .channel = 182,
- .freq = 5910, /* MHz */
- .unk2 = 3940,
- RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
- },
- { .channel = 1,
- .freq = 2412, /* MHz */
- .unk2 = 3216,
- RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
- 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
- PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
- },
- { .channel = 2,
- .freq = 2417, /* MHz */
- .unk2 = 3223,
- RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
- 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
- PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
- },
- { .channel = 3,
- .freq = 2422, /* MHz */
- .unk2 = 3229,
- RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
- 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
- PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
- },
- { .channel = 4,
- .freq = 2427, /* MHz */
- .unk2 = 3236,
- RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
- 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
- PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
- },
- { .channel = 5,
- .freq = 2432, /* MHz */
- .unk2 = 3243,
- RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
- 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
- PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
- },
- { .channel = 6,
- .freq = 2437, /* MHz */
- .unk2 = 3249,
- RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
- 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
- PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
- },
- { .channel = 7,
- .freq = 2442, /* MHz */
- .unk2 = 3256,
- RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
- 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
- PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
- },
- { .channel = 8,
- .freq = 2447, /* MHz */
- .unk2 = 3263,
- RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
- 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
- PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
- },
- { .channel = 9,
- .freq = 2452, /* MHz */
- .unk2 = 3269,
- RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
- 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
- PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
- },
- { .channel = 10,
- .freq = 2457, /* MHz */
- .unk2 = 3276,
- RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
- 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
- PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
- },
- { .channel = 11,
- .freq = 2462, /* MHz */
- .unk2 = 3283,
- RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
- 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
- PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
- },
- { .channel = 12,
- .freq = 2467, /* MHz */
- .unk2 = 3289,
- RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
- 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
- PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
- },
- { .channel = 13,
- .freq = 2472, /* MHz */
- .unk2 = 3296,
- RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
- 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
- PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
- },
- { .channel = 14,
- .freq = 2484, /* MHz */
- .unk2 = 3312,
- RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
- 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
- 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
- PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
- },
-};
-
-const struct b43_nphy_channeltab_entry_rev2 *
-b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
-{
- const struct b43_nphy_channeltab_entry_rev2 *e;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) {
- e = &(b43_nphy_channeltab[i]);
- if (e->channel == channel)
- return e;
- }
-
- return NULL;
-}
-
-
static const u8 b43_ntab_adjustpower0[] = {
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 8fc1da9f8fe5..4ec593ba3eef 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -3,7 +3,6 @@
#include <linux/types.h>
-
struct b43_phy_n_sfo_cfg {
u16 phy_bw1a;
u16 phy_bw2;
@@ -13,52 +12,6 @@ struct b43_phy_n_sfo_cfg {
u16 phy_bw6;
};
-struct b43_nphy_channeltab_entry_rev2 {
- /* The channel number */
- u8 channel;
- /* The channel frequency in MHz */
- u16 freq;
- /* An unknown value */
- u16 unk2;
- /* Radio register values on channelswitch */
- u8 radio_pll_ref;
- u8 radio_rf_pllmod0;
- u8 radio_rf_pllmod1;
- u8 radio_vco_captail;
- u8 radio_vco_cal1;
- u8 radio_vco_cal2;
- u8 radio_pll_lfc1;
- u8 radio_pll_lfr1;
- u8 radio_pll_lfc2;
- u8 radio_lgbuf_cenbuf;
- u8 radio_lgen_tune1;
- u8 radio_lgen_tune2;
- u8 radio_c1_lgbuf_atune;
- u8 radio_c1_lgbuf_gtune;
- u8 radio_c1_rx_rfr1;
- u8 radio_c1_tx_pgapadtn;
- u8 radio_c1_tx_mxbgtrim;
- u8 radio_c2_lgbuf_atune;
- u8 radio_c2_lgbuf_gtune;
- u8 radio_c2_rx_rfr1;
- u8 radio_c2_tx_pgapadtn;
- u8 radio_c2_tx_mxbgtrim;
- /* PHY register values on channelswitch */
- struct b43_phy_n_sfo_cfg phy_regs;
-};
-
-struct b43_nphy_channeltab_entry_rev3 {
- /* The channel number */
- u8 channel;
- /* The channel frequency in MHz */
- u16 freq;
- /* Radio register values on channelswitch */
- /* TODO */
- /* PHY register values on channelswitch */
- struct b43_phy_n_sfo_cfg phy_regs;
-};
-
-
struct b43_wldev;
struct nphy_txiqcal_ladder {
@@ -82,18 +35,12 @@ struct nphy_rf_control_override_rev3 {
u8 val_addr1;
};
-/* Upload the default register value table.
- * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
- * table is uploaded. If "ignore_uploadflag" is true, we upload any value
- * and ignore the "UPLOAD" flag. */
-void b2055_upload_inittab(struct b43_wldev *dev,
- bool ghz5, bool ignore_uploadflag);
-
-
-/* Get the NPHY Channel Switch Table entry for a channel number.
+/* Get the NPHY Channel Switch Table entry for a channel.
* Returns NULL on failure to find an entry. */
const struct b43_nphy_channeltab_entry_rev2 *
b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel);
+const struct b43_nphy_channeltab_entry_rev3 *
+b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq);
/* The N-PHY tables. */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 1713f5f7a58b..67f18ecdb3bf 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -1623,6 +1623,7 @@ error:
static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
{
+ struct wiphy *wiphy = dev->wl->hw->wiphy;
const size_t hdr_len = sizeof(struct b43legacy_fw_header);
const __be32 *data;
unsigned int i;
@@ -1732,6 +1733,10 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
dev->fw.rev = fwrev;
dev->fw.patch = fwpatch;
+ snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u",
+ dev->fw.rev, dev->fw.patch);
+ wiphy->hw_version = dev->dev->id.coreid;
+
return 0;
error:
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index a85e43a8d758..6038633ef361 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1696,7 +1696,7 @@ static int prism2_request_scan(struct net_device *dev)
hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,
HFA384X_ROAMING_FIRMWARE);
- return 0;
+ return ret;
}
#else /* !PRISM2_NO_STATION_MODES */
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 996e9d7d7586..61915f371416 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -1921,9 +1921,9 @@ static int ipw2100_net_init(struct net_device *dev)
bg_band->band = IEEE80211_BAND_2GHZ;
bg_band->n_channels = geo->bg_channels;
- bg_band->channels =
- kzalloc(geo->bg_channels *
- sizeof(struct ieee80211_channel), GFP_KERNEL);
+ bg_band->channels = kcalloc(geo->bg_channels,
+ sizeof(struct ieee80211_channel),
+ GFP_KERNEL);
if (!bg_band->channels) {
ipw2100_down(priv);
return -ENOMEM;
@@ -3056,9 +3056,9 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
packet = list_entry(element, struct ipw2100_tx_packet, list);
- IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
+ IPW_DEBUG_TX("using TBD at virt=%p, phys=%04X\n",
&txq->drv[txq->next],
- (void *)(txq->nic + txq->next *
+ (u32) (txq->nic + txq->next *
sizeof(struct ipw2100_bd)));
packet->index = txq->next;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index cb2552a6777c..8d6ed5f6f46f 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -11467,9 +11467,13 @@ static int ipw_net_init(struct net_device *dev)
bg_band->band = IEEE80211_BAND_2GHZ;
bg_band->n_channels = geo->bg_channels;
- bg_band->channels =
- kzalloc(geo->bg_channels *
- sizeof(struct ieee80211_channel), GFP_KERNEL);
+ bg_band->channels = kcalloc(geo->bg_channels,
+ sizeof(struct ieee80211_channel),
+ GFP_KERNEL);
+ if (!bg_band->channels) {
+ rc = -ENOMEM;
+ goto out;
+ }
/* translate geo->bg to bg_band.channels */
for (i = 0; i < geo->bg_channels; i++) {
bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
@@ -11502,9 +11506,13 @@ static int ipw_net_init(struct net_device *dev)
a_band->band = IEEE80211_BAND_5GHZ;
a_band->n_channels = geo->a_channels;
- a_band->channels =
- kzalloc(geo->a_channels *
- sizeof(struct ieee80211_channel), GFP_KERNEL);
+ a_band->channels = kcalloc(geo->a_channels,
+ sizeof(struct ieee80211_channel),
+ GFP_KERNEL);
+ if (!a_band->channels) {
+ rc = -ENOMEM;
+ goto out;
+ }
/* translate geo->bg to a_band.channels */
for (i = 0; i < geo->a_channels; i++) {
a_band->channels[i].band = IEEE80211_BAND_2GHZ;
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index a51e4da1bdfc..b82364258dc5 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -3,6 +3,9 @@ config IWLWIFI
depends on PCI && MAC80211
select FW_LOADER
+menu "Debugging Options"
+ depends on IWLWIFI
+
config IWLWIFI_DEBUG
bool "Enable full debugging output in iwlagn and iwl3945 drivers"
depends on IWLWIFI
@@ -36,6 +39,12 @@ config IWLWIFI_DEBUGFS
is a low-impact option that allows getting insight into the
driver's state at runtime.
+config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
+ bool "Experimental uCode support"
+ depends on IWLWIFI && IWLWIFI_DEBUG
+ ---help---
+ Enable use of experimental ucode for testing and debugging.
+
config IWLWIFI_DEVICE_TRACING
bool "iwlwifi device access tracing"
depends on IWLWIFI
@@ -53,6 +62,7 @@ config IWLWIFI_DEVICE_TRACING
If unsure, say Y so we can help you better when problems
occur.
+endmenu
config IWLAGN
tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 728bb858ba97..63edbe2e557f 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o
iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
+iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 0b779a41a142..db540910b110 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -50,14 +50,20 @@
/* Highest firmware API version supported */
#define IWL1000_UCODE_API_MAX 3
+#define IWL100_UCODE_API_MAX 5
/* Lowest firmware API version supported */
#define IWL1000_UCODE_API_MIN 1
+#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 IWL100_FW_PRE "iwlwifi-100-"
+#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
+#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api)
+
/*
* For 1000, use advance thermal throttling critical temperature threshold,
@@ -120,17 +126,17 @@ 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)
- priv->cfg->num_of_queues =
+ priv->cfg->base_params->num_of_queues =
priv->cfg->mod_params->num_of_queues;
- priv->hw_params.max_txq_num = priv->cfg->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;
priv->hw_params.scd_bc_tbls_size =
- priv->cfg->num_of_queues *
+ priv->cfg->base_params->num_of_queues *
sizeof(struct iwlagn_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -145,8 +151,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
- if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
- priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+ iwl1000_set_ct_threshold(priv);
/* Set initial sensitivity parameters */
/* Set initial calibration set */
@@ -189,9 +194,7 @@ static struct iwl_lib_ops iwl1000_lib = {
.update_chain_flags = iwl_update_chain_flags,
.apm_ops = {
.init = iwl_apm_init,
- .stop = iwl_apm_stop,
.config = iwl1000_nic_config,
- .set_pwr_src = iwl_set_pwr_src,
},
.eeprom_ops = {
.regulatory_bands = {
@@ -203,7 +206,6 @@ static struct iwl_lib_ops iwl1000_lib = {
EEPROM_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
.release_semaphore = iwlcore_eeprom_release_semaphore,
.calib_version = iwlagn_eeprom_calib_version,
@@ -214,21 +216,26 @@ static struct iwl_lib_ops iwl1000_lib = {
.config_ap = iwl_config_ap,
.temp_ops = {
.temperature = iwlagn_temperature,
- .set_ct_kill = iwl1000_set_ct_threshold,
},
.manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_station = iwl_update_bcast_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
.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,
},
.recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.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 = {
@@ -238,29 +245,16 @@ static const struct iwl_ops iwl1000_ops = {
.led = &iwlagn_led_ops,
};
-struct iwl_cfg iwl1000_bgn_cfg = {
- .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
- .fw_name_pre = IWL1000_FW_PRE,
- .ucode_api_max = IWL1000_UCODE_API_MAX,
- .ucode_api_min = IWL1000_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl1000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
- .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
+static struct iwl_base_params iwl1000_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
- .mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
+ .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,
- .ht_greenfield_support = true,
.led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
@@ -271,6 +265,26 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
+static struct iwl_ht_params iwl1000_ht_params = {
+ .ht_greenfield_support = true,
+ .use_rts_for_aggregation = true, /* use rts/cts protection */
+};
+
+struct iwl_cfg iwl1000_bgn_cfg = {
+ .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
+ .fw_name_pre = IWL1000_FW_PRE,
+ .ucode_api_max = IWL1000_UCODE_API_MAX,
+ .ucode_api_min = IWL1000_UCODE_API_MIN,
+ .sku = IWL_SKU_G|IWL_SKU_N,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
+ .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,
+ .ht_params = &iwl1000_ht_params,
+};
struct iwl_cfg iwl1000_bg_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
@@ -278,30 +292,45 @@ struct iwl_cfg iwl1000_bg_cfg = {
.ucode_api_max = IWL1000_UCODE_API_MAX,
.ucode_api_min = IWL1000_UCODE_API_MIN,
.sku = IWL_SKU_G,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
+ .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
.ops = &iwl1000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .mod_params = &iwlagn_mod_params,
+ .base_params = &iwl1000_base_params,
+};
+
+struct iwl_cfg iwl100_bgn_cfg = {
+ .name = "Intel(R) 100 Series 1x1 BGN",
+ .fw_name_pre = IWL100_FW_PRE,
+ .ucode_api_max = IWL100_UCODE_API_MAX,
+ .ucode_api_min = IWL100_UCODE_API_MIN,
+ .sku = IWL_SKU_G|IWL_SKU_N,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_A,
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl1000_ops,
.mod_params = &iwlagn_mod_params,
+ .base_params = &iwl1000_base_params,
+ .ht_params = &iwl1000_ht_params,
+};
+
+struct iwl_cfg iwl100_bg_cfg = {
+ .name = "Intel(R) 100 Series 1x1 BG",
+ .fw_name_pre = IWL100_FW_PRE,
+ .ucode_api_max = IWL100_UCODE_API_MAX,
+ .ucode_api_min = IWL100_UCODE_API_MIN,
+ .sku = IWL_SKU_G,
.valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .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,
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
- .max_event_log_size = 128,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .valid_rx_ant = ANT_A,
+ .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,
};
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 7c731a793632..65b5834da28c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -62,7 +62,7 @@
*****************************************************************************/
/*
* Please use this file (iwl-3945-hw.h) only for hardware-related definitions.
- * Please use iwl-3945-commands.h for uCode API definitions.
+ * Please use iwl-commands.h for uCode API definitions.
* Please use iwl-3945.h for driver implementation definitions.
*/
@@ -226,6 +226,7 @@ struct iwl3945_eeprom {
/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */
#define IWL39_NUM_QUEUES 5
+#define IWL39_CMD_QUEUE_NUM 4
#define IWL_DEFAULT_TX_RETRY 15
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 293e1dbc166c..1f3e7e34fbc7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -343,7 +343,7 @@ void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 s
int i;
IWL_DEBUG_INFO(priv, "enter\n");
- if (sta_id == priv->hw_params.bcast_sta_id)
+ if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id)
goto out;
psta = (struct iwl3945_sta_priv *) sta->drv_priv;
@@ -933,7 +933,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
rcu_read_lock();
- sta = ieee80211_find_sta(priv->vif,
+ sta = ieee80211_find_sta(priv->contexts[IWL_RXON_CTX_BSS].vif,
priv->stations[sta_id].sta.sta.addr);
if (!sta) {
IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n");
@@ -950,7 +950,8 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
switch (priv->band) {
case IEEE80211_BAND_2GHZ:
/* TODO: this always does G, not a regression */
- if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) {
+ if (priv->contexts[IWL_RXON_CTX_BSS].active.flags &
+ RXON_FLG_TGG_PROTECT_MSK) {
rs_sta->tgg = 1;
rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot;
} else
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8ccfcd08218d..176e52577673 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -87,6 +87,15 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */
};
+static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
+{
+ u8 rate = iwl3945_rates[rate_index].prev_ieee;
+
+ if (rate == IWL_RATE_INVALID)
+ rate = rate_index;
+ return rate;
+}
+
/* 1 = enable the iwl3945_disable_events() function */
#define IWL_EVT_DISABLE (0)
#define IWL_EVT_DISABLE_SIZE (1532/32)
@@ -245,7 +254,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
break;
case IEEE80211_BAND_2GHZ:
if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
- iwl_is_associated(priv)) {
+ iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
if (rate == IWL_RATE_11M_INDEX)
next_rate = IWL_RATE_5M_INDEX;
}
@@ -273,7 +282,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
struct iwl_queue *q = &txq->q;
struct iwl_tx_info *tx_info;
- BUG_ON(txq_id == IWL_CMD_QUEUE_NUM);
+ BUG_ON(txq_id == IWL39_CMD_QUEUE_NUM);
for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
@@ -285,7 +294,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
}
if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
- (txq_id != IWL_CMD_QUEUE_NUM) &&
+ (txq_id != IWL39_CMD_QUEUE_NUM) &&
priv->mac80211_registered)
iwl_wake_queue(priv, txq_id);
}
@@ -339,7 +348,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index);
iwl3945_tx_queue_reclaim(priv, txq_id, index);
- if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
+ if (status & TX_ABORT_REQUIRED_MSK)
IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
}
@@ -406,7 +415,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
unsigned int plcp_msec;
unsigned long plcp_received_jiffies;
- if (priv->cfg->plcp_delta_threshold ==
+ if (priv->cfg->base_params->plcp_delta_threshold ==
IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
return rc;
@@ -432,7 +441,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
if ((combined_plcp_delta > 0) &&
((combined_plcp_delta * 100) / plcp_msec) >
- priv->cfg->plcp_delta_threshold) {
+ priv->cfg->base_params->plcp_delta_threshold) {
/*
* if plcp_err exceed the threshold, the following
* data is printed in csv format:
@@ -444,7 +453,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
*/
IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
"%u, %d, %u mSecs\n",
- priv->cfg->plcp_delta_threshold,
+ priv->cfg->base_params->plcp_delta_threshold,
le32_to_cpu(current_stat.rx.ofdm.plcp_err),
combined_plcp_delta, plcp_msec);
/*
@@ -760,7 +769,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
data_retry_limit = IWL_DEFAULT_TX_RETRY;
tx_cmd->data_retry_limit = data_retry_limit;
- if (tx_id >= IWL_CMD_QUEUE_NUM)
+ if (tx_id >= IWL39_CMD_QUEUE_NUM)
rts_retry_limit = 3;
else
rts_retry_limit = 7;
@@ -807,9 +816,12 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate)
return sta_id;
}
-static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
+static void iwl3945_set_pwr_vmain(struct iwl_priv *priv)
{
- if (src == IWL_PWR_SRC_VAUX) {
+/*
+ * (for documentation purposes)
+ * to set power to V_AUX, do
+
if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
@@ -819,16 +831,14 @@ static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
CSR_GPIO_IN_BIT_AUX_POWER, 5000);
}
- } else {
- iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
- APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
- ~APMG_PS_CTRL_MSK_PWR_SRC);
+ */
- iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
- CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */
- }
+ iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+ APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
+ ~APMG_PS_CTRL_MSK_PWR_SRC);
- return 0;
+ iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
+ CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */
}
static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
@@ -909,7 +919,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
/* Tx queue(s) */
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
- slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
+ slots_num = (txq_id == IWL39_CMD_QUEUE_NUM) ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
txq_id);
@@ -1022,9 +1032,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
priv->cfg->ops->lib->apm_ops.init(priv);
spin_unlock_irqrestore(&priv->lock, flags);
- rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
- if (rc)
- return rc;
+ iwl3945_set_pwr_vmain(priv);
priv->cfg->ops->lib->apm_ops.config(priv);
@@ -1072,7 +1080,7 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
if (priv->txq)
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
txq_id++)
- if (txq_id == IWL_CMD_QUEUE_NUM)
+ if (txq_id == IWL39_CMD_QUEUE_NUM)
iwl_cmd_queue_free(priv);
else
iwl_tx_queue_free(priv, txq_id);
@@ -1439,17 +1447,18 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv)
int rate_idx, i;
const struct iwl_channel_info *ch_info = NULL;
struct iwl3945_txpowertable_cmd txpower = {
- .channel = priv->active_rxon.channel,
+ .channel = priv->contexts[IWL_RXON_CTX_BSS].active.channel,
};
+ u16 chan;
+
+ chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel);
txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
- ch_info = iwl_get_channel_info(priv,
- priv->band,
- le16_to_cpu(priv->active_rxon.channel));
+ ch_info = iwl_get_channel_info(priv, priv->band, chan);
if (!ch_info) {
IWL_ERR(priv,
"Failed to get channel info for channel %d [%d]\n",
- le16_to_cpu(priv->active_rxon.channel), priv->band);
+ chan, priv->band);
return -EINVAL;
}
@@ -1710,7 +1719,8 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
return 0;
}
-static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
+static int iwl3945_send_rxon_assoc(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
int rc = 0;
struct iwl_rx_packet *pkt;
@@ -1721,8 +1731,8 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
.flags = CMD_WANT_SKB,
.data = &rxon_assoc,
};
- const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
+ const struct 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) &&
@@ -1732,10 +1742,10 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
return 0;
}
- rxon_assoc.flags = priv->staging_rxon.flags;
- rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
- rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+ rxon_assoc.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.reserved = 0;
rc = iwl_send_cmd_sync(priv, &cmd);
@@ -1761,14 +1771,13 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
-static int iwl3945_commit_rxon(struct iwl_priv *priv)
+int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
/* cast away the const for active_rxon in this function */
- struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
- struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
+ struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active;
+ struct iwl3945_rxon_cmd *staging_rxon = (void *)&ctx->staging;
int rc = 0;
- bool new_assoc =
- !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
+ bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK);
if (!iwl_is_alive(priv))
return -1;
@@ -1781,7 +1790,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
- rc = iwl_check_rxon_cmd(priv);
+ rc = iwl_check_rxon_cmd(priv, ctx);
if (rc) {
IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
return -EINVAL;
@@ -1790,8 +1799,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
/* If we don't need to send a full RXON, we can use
* iwl3945_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
- if (!iwl_full_rxon_required(priv)) {
- rc = iwl_send_rxon_assoc(priv);
+ if (!iwl_full_rxon_required(priv, &priv->contexts[IWL_RXON_CTX_BSS])) {
+ rc = iwl_send_rxon_assoc(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
if (rc) {
IWL_ERR(priv, "Error setting RXON_ASSOC "
"configuration (%d).\n", rc);
@@ -1807,7 +1817,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
* an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration
* before we apply the new config */
- if (iwl_is_associated(priv) && new_assoc) {
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) {
IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@@ -1819,7 +1829,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
active_rxon->reserved5 = 0;
rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl3945_rxon_cmd),
- &priv->active_rxon);
+ &priv->contexts[IWL_RXON_CTX_BSS].active);
/* If the mask clearing failed then we set
* active_rxon back to what it was previously */
@@ -1829,8 +1839,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
"configuration (%d).\n", rc);
return rc;
}
- iwl_clear_ucode_stations(priv);
- iwl_restore_stations(priv);
+ iwl_clear_ucode_stations(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
+ iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]);
}
IWL_DEBUG_INFO(priv, "Sending RXON\n"
@@ -1848,7 +1859,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
staging_rxon->reserved4 = 0;
staging_rxon->reserved5 = 0;
- iwl_set_rxon_hwcrypto(priv, !iwl3945_mod_params.sw_crypto);
+ iwl_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto);
/* Apply the new configuration */
rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -1862,8 +1873,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
if (!new_assoc) {
- iwl_clear_ucode_stations(priv);
- iwl_restore_stations(priv);
+ iwl_clear_ucode_stations(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
+ iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]);
}
/* If we issue a new RXON command which required a tune then we must
@@ -2295,6 +2307,32 @@ static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
return (u16)sizeof(struct iwl3945_addsta_cmd);
}
+static int iwl3945_add_bssid_station(struct iwl_priv *priv,
+ const u8 *addr, u8 *sta_id_r)
+{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ int ret;
+ u8 sta_id;
+ unsigned long flags;
+
+ if (sta_id_r)
+ *sta_id_r = IWL_INVALID_STATION;
+
+ ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
+ if (ret) {
+ IWL_ERR(priv, "Unable to add station %pM\n", addr);
+ return ret;
+ }
+
+ if (sta_id_r)
+ *sta_id_r = sta_id;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].used |= IWL_STA_LOCAL;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return 0;
+}
static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add)
{
@@ -2302,8 +2340,8 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
int ret;
if (add) {
- ret = iwl_add_bssid_station(priv, vif->bss_conf.bssid, false,
- &vif_priv->ibss_bssid_sta_id);
+ ret = iwl3945_add_bssid_station(priv, vif->bss_conf.bssid,
+ &vif_priv->ibss_bssid_sta_id);
if (ret)
return ret;
@@ -2366,7 +2404,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
* 1M CCK rates */
if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
- iwl_is_associated(priv)) {
+ iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
index = IWL_FIRST_CCK_RATE;
for (i = IWL_RATE_6M_INDEX_TABLE;
@@ -2414,14 +2452,16 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
}
/* Assign number of Usable TX queues */
- priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
+ priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K);
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
priv->hw_params.max_stations = IWL3945_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID;
+
+ priv->sta_key_max_num = STA_KEY_MAX_NUM;
priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL;
@@ -2439,7 +2479,8 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
- tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
+ tx_beacon_cmd->tx.sta_id =
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl3945_fill_beacon_frame(priv,
@@ -2663,9 +2704,7 @@ static struct iwl_lib_ops iwl3945_lib = {
.dump_nic_error_log = iwl3945_dump_nic_error_log,
.apm_ops = {
.init = iwl3945_apm_init,
- .stop = iwl_apm_stop,
.config = iwl3945_nic_config,
- .set_pwr_src = iwl3945_set_pwr_src,
},
.eeprom_ops = {
.regulatory_bands = {
@@ -2677,7 +2716,6 @@ static struct iwl_lib_ops iwl3945_lib = {
EEPROM_REGULATORY_BAND_NO_HT40,
EEPROM_REGULATORY_BAND_NO_HT40,
},
- .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
.release_semaphore = iwl3945_eeprom_release_semaphore,
.query_addr = iwlcore_eeprom_query_addr,
@@ -2703,6 +2741,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
.build_addsta_hcmd = iwl3945_build_addsta_hcmd,
.tx_cmd_protection = iwlcore_tx_cmd_protection,
.request_scan = iwl3945_request_scan,
+ .post_scan = iwl3945_post_scan,
};
static const struct iwl_ops iwl3945_ops = {
@@ -2712,22 +2751,13 @@ static const struct iwl_ops iwl3945_ops = {
.led = &iwl3945_led_ops,
};
-static struct iwl_cfg iwl3945_bg_cfg = {
- .name = "3945BG",
- .fw_name_pre = IWL3945_FW_PRE,
- .ucode_api_max = IWL3945_UCODE_API_MAX,
- .ucode_api_min = IWL3945_UCODE_API_MIN,
- .sku = IWL_SKU_G,
+static struct iwl_base_params iwl3945_base_params = {
.eeprom_size = IWL3945_EEPROM_IMG_SIZE,
- .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
- .ops = &iwl3945_ops,
.num_of_queues = IWL39_NUM_QUEUES,
- .mod_params = &iwl3945_mod_params,
.pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
.set_l0s = false,
.use_bsm = true,
.use_isr_legacy = true,
- .ht_greenfield_support = false,
.led_compensation = 64,
.broken_powersave = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
@@ -2736,25 +2766,28 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.tx_power_by_driver = true,
};
+static struct iwl_cfg iwl3945_bg_cfg = {
+ .name = "3945BG",
+ .fw_name_pre = IWL3945_FW_PRE,
+ .ucode_api_max = IWL3945_UCODE_API_MAX,
+ .ucode_api_min = IWL3945_UCODE_API_MIN,
+ .sku = IWL_SKU_G,
+ .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
+ .ops = &iwl3945_ops,
+ .mod_params = &iwl3945_mod_params,
+ .base_params = &iwl3945_base_params,
+};
+
static struct iwl_cfg iwl3945_abg_cfg = {
.name = "3945ABG",
.fw_name_pre = IWL3945_FW_PRE,
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
- .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
.ops = &iwl3945_ops,
- .num_of_queues = IWL39_NUM_QUEUES,
.mod_params = &iwl3945_mod_params,
- .use_isr_legacy = true,
- .ht_greenfield_support = false,
- .led_compensation = 64,
- .broken_powersave = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .tx_power_by_driver = true,
+ .base_params = &iwl3945_base_params,
};
DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index bb2aeebf3652..09391f0ee61f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -138,8 +138,6 @@ enum iwl3945_antenna {
#define DEFAULT_SHORT_RETRY_LIMIT 7U
#define DEFAULT_LONG_RETRY_LIMIT 4U
-#include "iwl-agn-rs.h"
-
#define IWL_TX_FIFO_AC0 0
#define IWL_TX_FIFO_AC1 1
#define IWL_TX_FIFO_AC2 2
@@ -271,6 +269,9 @@ extern void iwl3945_post_associate(struct iwl_priv *priv,
extern void iwl3945_config_ap(struct iwl_priv *priv,
struct ieee80211_vif *vif);
+extern int iwl3945_commit_rxon(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
+
/**
* iwl3945_hw_find_station - Find station id for a given BSSID
* @bssid: MAC address of station ID to find
@@ -295,7 +296,11 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info(
extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
/* scanning */
-void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+void iwl3945_post_scan(struct iwl_priv *priv);
+
+/* rates */
+extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
/* Requires full declaration of iwl_priv before including */
#include "iwl-io.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index d92b72909233..b207e3e9299f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -43,7 +43,7 @@
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-helpers.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
#include "iwl-sta.h"
#include "iwl-agn-led.h"
#include "iwl-agn.h"
@@ -347,7 +347,7 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
struct iwl_chain_noise_data *data = &(priv->chain_noise_data);
if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
- iwl_is_associated(priv)) {
+ iwl_is_any_associated(priv)) {
struct iwl_calib_diff_gain_cmd cmd;
/* clear data for chain noise calibration algorithm */
@@ -576,7 +576,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
/* Activate all Tx DMA/FIFO channels */
priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 6));
- iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
+ iwl4965_set_wr_ptrs(priv, IWL_DEFAULT_CMD_QUEUE_NUM, 0);
/* make sure all queue are not stopped */
memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
@@ -587,6 +587,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
priv->txq_ctx_active_msk = 0;
/* Map each Tx/cmd queue to its corresponding fifo */
BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7);
+
for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
int ac = default_queue_to_tx_fifo[i];
@@ -646,17 +647,17 @@ static int iwl4965_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 <= IWL49_NUM_QUEUES)
- priv->cfg->num_of_queues =
+ priv->cfg->base_params->num_of_queues =
priv->cfg->mod_params->num_of_queues;
- priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
+ priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
- priv->cfg->num_of_queues *
+ priv->cfg->base_params->num_of_queues *
sizeof(struct iwl4965_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL4965_BROADCAST_ID;
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE;
priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
@@ -668,8 +669,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
- if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
- priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+
+ iwl4965_set_ct_threshold(priv);
priv->hw_params.sens = &iwl4965_sensitivity;
priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
@@ -1374,6 +1375,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
u8 band = 0;
bool is_ht40 = false;
u8 ctrl_chan_high = 0;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
if (test_bit(STATUS_SCANNING, &priv->status)) {
/* If this gets hit a lot, switch it to a BUG() and catch
@@ -1385,17 +1387,16 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
band = priv->band == IEEE80211_BAND_2GHZ;
- is_ht40 = is_ht40_channel(priv->active_rxon.flags);
+ is_ht40 = is_ht40_channel(ctx->active.flags);
- if (is_ht40 &&
- (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+ if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
ctrl_chan_high = 1;
cmd.band = band;
- cmd.channel = priv->active_rxon.channel;
+ cmd.channel = ctx->active.channel;
ret = iwl4965_fill_txpower_tbl(priv, band,
- le16_to_cpu(priv->active_rxon.channel),
+ le16_to_cpu(ctx->active.channel),
is_ht40, ctrl_chan_high, &cmd.tx_power);
if (ret)
goto out;
@@ -1406,12 +1407,13 @@ out:
return ret;
}
-static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
+static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
int ret = 0;
struct iwl4965_rxon_assoc_cmd rxon_assoc;
- const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
+ 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) &&
@@ -1426,16 +1428,16 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
return 0;
}
- rxon_assoc.flags = priv->staging_rxon.flags;
- rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
- rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+ rxon_assoc.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.reserved = 0;
rxon_assoc.ofdm_ht_single_stream_basic_rates =
- priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
+ ctx->staging.ofdm_ht_single_stream_basic_rates;
rxon_assoc.ofdm_ht_dual_stream_basic_rates =
- priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
- rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
+ ctx->staging.ofdm_ht_dual_stream_basic_rates;
+ rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
sizeof(rxon_assoc), &rxon_assoc, NULL);
@@ -1448,6 +1450,7 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
struct ieee80211_channel_switch *ch_switch)
{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
int rc;
u8 band = 0;
bool is_ht40 = false;
@@ -1458,22 +1461,22 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
u16 ch;
u32 tsf_low;
u8 switch_count;
- u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
- struct ieee80211_vif *vif = priv->vif;
+ u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
+ struct ieee80211_vif *vif = ctx->vif;
band = priv->band == IEEE80211_BAND_2GHZ;
- is_ht40 = is_ht40_channel(priv->staging_rxon.flags);
+ is_ht40 = is_ht40_channel(ctx->staging.flags);
if (is_ht40 &&
- (priv->staging_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+ (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
ctrl_chan_high = 1;
cmd.band = band;
cmd.expect_beacon = 0;
- ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq);
+ ch = ch_switch->channel->hw_value;
cmd.channel = cpu_to_le16(ch);
- cmd.rxon_flags = priv->staging_rxon.flags;
- cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
+ cmd.rxon_flags = ctx->staging.flags;
+ cmd.rxon_filter_flags = ctx->staging.filter_flags;
switch_count = ch_switch->count;
tsf_low = ch_switch->timestamp & 0x0ffffffff;
/*
@@ -1508,7 +1511,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
cmd.expect_beacon = is_channel_radar(ch_info);
else {
IWL_ERR(priv, "invalid channel switch from %u to %u\n",
- priv->active_rxon.channel, ch);
+ ctx->active.channel, ch);
return -EFAULT;
}
@@ -1721,13 +1724,13 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
u16 ssn_idx, u8 tx_fifo)
{
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
- (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
- <= txq_id)) {
+ (IWL49_FIRST_AMPDU_QUEUE +
+ priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
IWL_WARN(priv,
"queue number out of range: %d, must be %d to %d\n",
txq_id, IWL49_FIRST_AMPDU_QUEUE,
IWL49_FIRST_AMPDU_QUEUE +
- priv->cfg->num_of_ampdu_queues - 1);
+ priv->cfg->base_params->num_of_ampdu_queues - 1);
return -EINVAL;
}
@@ -1789,13 +1792,13 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
int ret;
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
- (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
- <= txq_id)) {
+ (IWL49_FIRST_AMPDU_QUEUE +
+ priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
IWL_WARN(priv,
"queue number out of range: %d, must be %d to %d\n",
txq_id, IWL49_FIRST_AMPDU_QUEUE,
IWL49_FIRST_AMPDU_QUEUE +
- priv->cfg->num_of_ampdu_queues - 1);
+ priv->cfg->base_params->num_of_ampdu_queues - 1);
return -EINVAL;
}
@@ -2007,7 +2010,7 @@ static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
start = IWL_STA_ID;
if (is_broadcast_ether_addr(addr))
- return priv->hw_params.bcast_sta_id;
+ return priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
spin_lock_irqsave(&priv->sta_lock, flags);
for (i = start; i < priv->hw_params.max_stations; i++)
@@ -2213,11 +2216,23 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
static struct iwl_hcmd_ops iwl4965_hcmd = {
.rxon_assoc = iwl4965_send_rxon_assoc,
- .commit_rxon = iwl_commit_rxon,
- .set_rxon_chain = iwl_set_rxon_chain,
+ .commit_rxon = iwlagn_commit_rxon,
+ .set_rxon_chain = iwlagn_set_rxon_chain,
.send_bt_config = iwl_send_bt_config,
};
+static void iwl4965_post_scan(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+
+ /*
+ * Since setting the RXON may have been deferred while
+ * performing the scan, fire one off if needed
+ */
+ if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+ iwlcore_commit_rxon(priv, ctx);
+}
+
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
.get_hcmd_size = iwl4965_get_hcmd_size,
.build_addsta_hcmd = iwl4965_build_addsta_hcmd,
@@ -2226,6 +2241,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
.tx_cmd_protection = iwlcore_tx_cmd_protection,
.calc_rssi = iwl4965_calc_rssi,
.request_scan = iwlagn_request_scan,
+ .post_scan = iwl4965_post_scan,
};
static struct iwl_lib_ops iwl4965_lib = {
@@ -2250,9 +2266,7 @@ static struct iwl_lib_ops iwl4965_lib = {
.set_channel_switch = iwl4965_hw_channel_switch,
.apm_ops = {
.init = iwl_apm_init,
- .stop = iwl_apm_stop,
.config = iwl4965_nic_config,
- .set_pwr_src = iwl_set_pwr_src,
},
.eeprom_ops = {
.regulatory_bands = {
@@ -2264,7 +2278,6 @@ static struct iwl_lib_ops iwl4965_lib = {
EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
},
- .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
.release_semaphore = iwlcore_eeprom_release_semaphore,
.calib_version = iwl4965_eeprom_calib_version,
@@ -2277,15 +2290,15 @@ static struct iwl_lib_ops iwl4965_lib = {
.isr = iwl_isr_legacy,
.temp_ops = {
.temperature = iwl4965_temperature_calib,
- .set_ct_kill = iwl4965_set_ct_threshold,
},
.manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_station = iwl_update_bcast_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
.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,
},
.recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
@@ -2298,26 +2311,14 @@ static const struct iwl_ops iwl4965_ops = {
.led = &iwlagn_led_ops,
};
-struct iwl_cfg iwl4965_agn_cfg = {
- .name = "Intel(R) Wireless WiFi Link 4965AGN",
- .fw_name_pre = IWL4965_FW_PRE,
- .ucode_api_max = IWL4965_UCODE_API_MAX,
- .ucode_api_min = IWL4965_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+static struct iwl_base_params iwl4965_base_params = {
.eeprom_size = IWL4965_EEPROM_IMG_SIZE,
- .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
- .ops = &iwl4965_ops,
.num_of_queues = IWL49_NUM_QUEUES,
.num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
- .mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_ABC,
.pll_cfg_val = 0,
.set_l0s = true,
.use_bsm = true,
.use_isr_legacy = true,
- .ht_greenfield_support = false,
.broken_powersave = true,
.led_compensation = 61,
.chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
@@ -2329,6 +2330,21 @@ struct iwl_cfg iwl4965_agn_cfg = {
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
+};
+
+struct iwl_cfg iwl4965_agn_cfg = {
+ .name = "Intel(R) Wireless WiFi Link 4965AGN",
+ .fw_name_pre = IWL4965_FW_PRE,
+ .ucode_api_max = IWL4965_UCODE_API_MAX,
+ .ucode_api_min = IWL4965_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_ABC,
+ .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
+ .ops = &iwl4965_ops,
+ .mod_params = &iwlagn_mod_params,
+ .base_params = &iwl4965_base_params,
/*
* Force use of chains B and C for scan RX on 5 GHz band
* because the device has off-channel reception on chain A.
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 146e6431ae95..3975e45e7500 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -62,7 +62,7 @@
*****************************************************************************/
/*
* Please use this file (iwl-5000-hw.h) only for hardware-related definitions.
- * Use iwl-5000-commands.h for uCode API definitions.
+ * Use iwl-commands.h for uCode API definitions.
*/
#ifndef __iwl_5000_hw_h__
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 48bdcd8d2e94..fd9fbc93ea1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -170,17 +170,17 @@ 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)
- priv->cfg->num_of_queues =
+ priv->cfg->base_params->num_of_queues =
priv->cfg->mod_params->num_of_queues;
- priv->hw_params.max_txq_num = priv->cfg->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;
priv->hw_params.scd_bc_tbls_size =
- priv->cfg->num_of_queues *
+ priv->cfg->base_params->num_of_queues *
sizeof(struct iwlagn_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -195,8 +195,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
- if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
- priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+ iwl5000_set_ct_threshold(priv);
/* Set initial sensitivity parameters */
/* Set initial calibration set */
@@ -217,17 +216,17 @@ 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)
- priv->cfg->num_of_queues =
+ priv->cfg->base_params->num_of_queues =
priv->cfg->mod_params->num_of_queues;
- priv->hw_params.max_txq_num = priv->cfg->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;
priv->hw_params.scd_bc_tbls_size =
- priv->cfg->num_of_queues *
+ priv->cfg->base_params->num_of_queues *
sizeof(struct iwlagn_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -242,8 +241,7 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
- if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
- priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+ iwl5150_set_ct_threshold(priv);
/* Set initial sensitivity parameters */
/* Set initial calibration set */
@@ -275,14 +273,19 @@ static void iwl5150_temperature(struct iwl_priv *priv)
static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
struct ieee80211_channel_switch *ch_switch)
{
+ /*
+ * MULTI-FIXME
+ * See iwl_mac_channel_switch.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct iwl5000_channel_switch_cmd cmd;
const struct iwl_channel_info *ch_info;
u32 switch_time_in_usec, ucode_switch_time;
u16 ch;
u32 tsf_low;
u8 switch_count;
- u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
- struct ieee80211_vif *vif = priv->vif;
+ u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
+ struct ieee80211_vif *vif = ctx->vif;
struct iwl_host_cmd hcmd = {
.id = REPLY_CHANNEL_SWITCH,
.len = sizeof(cmd),
@@ -291,12 +294,12 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
};
cmd.band = priv->band == IEEE80211_BAND_2GHZ;
- ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq);
+ ch = ch_switch->channel->hw_value;
IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
- priv->active_rxon.channel, ch);
+ ctx->active.channel, ch);
cmd.channel = cpu_to_le16(ch);
- cmd.rxon_flags = priv->staging_rxon.flags;
- cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
+ cmd.rxon_flags = ctx->staging.flags;
+ cmd.rxon_filter_flags = ctx->staging.filter_flags;
switch_count = ch_switch->count;
tsf_low = ch_switch->timestamp & 0x0ffffffff;
/*
@@ -331,7 +334,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
cmd.expect_beacon = is_channel_radar(ch_info);
else {
IWL_ERR(priv, "invalid channel switch from %u to %u\n",
- priv->active_rxon.channel, ch);
+ ctx->active.channel, ch);
return -EFAULT;
}
priv->switch_rxon.channel = cmd.channel;
@@ -365,9 +368,7 @@ static struct iwl_lib_ops iwl5000_lib = {
.set_channel_switch = iwl5000_hw_channel_switch,
.apm_ops = {
.init = iwl_apm_init,
- .stop = iwl_apm_stop,
.config = iwl5000_nic_config,
- .set_pwr_src = iwl_set_pwr_src,
},
.eeprom_ops = {
.regulatory_bands = {
@@ -379,7 +380,6 @@ static struct iwl_lib_ops iwl5000_lib = {
EEPROM_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
.release_semaphore = iwlcore_eeprom_release_semaphore,
.calib_version = iwlagn_eeprom_calib_version,
@@ -390,21 +390,26 @@ static struct iwl_lib_ops iwl5000_lib = {
.config_ap = iwl_config_ap,
.temp_ops = {
.temperature = iwlagn_temperature,
- .set_ct_kill = iwl5000_set_ct_threshold,
},
.manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_station = iwl_update_bcast_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
.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,
},
.recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.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 = {
@@ -431,9 +436,7 @@ static struct iwl_lib_ops iwl5150_lib = {
.set_channel_switch = iwl5000_hw_channel_switch,
.apm_ops = {
.init = iwl_apm_init,
- .stop = iwl_apm_stop,
.config = iwl5000_nic_config,
- .set_pwr_src = iwl_set_pwr_src,
},
.eeprom_ops = {
.regulatory_bands = {
@@ -445,7 +448,6 @@ static struct iwl_lib_ops iwl5150_lib = {
EEPROM_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
.release_semaphore = iwlcore_eeprom_release_semaphore,
.calib_version = iwlagn_eeprom_calib_version,
@@ -456,20 +458,26 @@ static struct iwl_lib_ops iwl5150_lib = {
.config_ap = iwl_config_ap,
.temp_ops = {
.temperature = iwl5150_temperature,
- .set_ct_kill = iwl5150_set_ct_threshold,
},
.manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_station = iwl_update_bcast_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
.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,
},
.recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.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 = {
@@ -486,27 +494,14 @@ static const struct iwl_ops iwl5150_ops = {
.led = &iwlagn_led_ops,
};
-struct iwl_cfg iwl5300_agn_cfg = {
- .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
- .fw_name_pre = IWL5000_FW_PRE,
- .ucode_api_max = IWL5000_UCODE_API_MAX,
- .ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl5000_ops,
+static struct iwl_base_params iwl5000_base_params = {
.eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
- .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
- .mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_ABC,
- .valid_rx_ant = ANT_ABC,
.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
.set_l0s = true,
.use_bsm = false,
- .ht_greenfield_support = true,
.led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
@@ -516,6 +511,26 @@ struct iwl_cfg iwl5300_agn_cfg = {
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
+static struct iwl_ht_params iwl5000_ht_params = {
+ .ht_greenfield_support = true,
+ .use_rts_for_aggregation = true, /* use rts/cts protection */
+};
+
+struct iwl_cfg iwl5300_agn_cfg = {
+ .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
+ .fw_name_pre = IWL5000_FW_PRE,
+ .ucode_api_max = IWL5000_UCODE_API_MAX,
+ .ucode_api_min = IWL5000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .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,
+ .ht_params = &iwl5000_ht_params,
+};
struct iwl_cfg iwl5100_bgn_cfg = {
.name = "Intel(R) WiFi Link 5100 BGN",
@@ -523,29 +538,14 @@ struct iwl_cfg iwl5100_bgn_cfg = {
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl5000_ops,
- .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
+ .valid_tx_ant = ANT_B,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_B,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
- .set_l0s = true,
- .use_bsm = false,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl5000_base_params,
+ .ht_params = &iwl5000_ht_params,
};
struct iwl_cfg iwl5100_abg_cfg = {
@@ -554,27 +554,13 @@ struct iwl_cfg iwl5100_abg_cfg = {
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
- .ops = &iwl5000_ops,
- .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
+ .valid_tx_ant = ANT_B,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_B,
- .valid_rx_ant = ANT_AB,
- .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,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl5000_base_params,
};
struct iwl_cfg iwl5100_agn_cfg = {
@@ -583,29 +569,14 @@ struct iwl_cfg iwl5100_agn_cfg = {
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl5000_ops,
- .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
+ .valid_tx_ant = ANT_B,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_B,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
- .set_l0s = true,
- .use_bsm = false,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl5000_base_params,
+ .ht_params = &iwl5000_ht_params,
};
struct iwl_cfg iwl5350_agn_cfg = {
@@ -614,29 +585,14 @@ struct iwl_cfg iwl5350_agn_cfg = {
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl5000_ops,
- .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_ABC,
- .valid_rx_ant = ANT_ABC,
- .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
- .set_l0s = true,
- .use_bsm = false,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl5000_base_params,
+ .ht_params = &iwl5000_ht_params,
};
struct iwl_cfg iwl5150_agn_cfg = {
@@ -645,29 +601,14 @@ struct iwl_cfg iwl5150_agn_cfg = {
.ucode_api_max = IWL5150_UCODE_API_MAX,
.ucode_api_min = IWL5150_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl5150_ops,
- .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl5150_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
- .set_l0s = true,
- .use_bsm = false,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl5000_base_params,
+ .ht_params = &iwl5000_ht_params,
.need_dc_calib = true,
};
@@ -677,27 +618,13 @@ struct iwl_cfg iwl5150_abg_cfg = {
.ucode_api_max = IWL5150_UCODE_API_MAX,
.ucode_api_min = IWL5150_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
- .ops = &iwl5150_ops,
- .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl5150_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .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,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl5000_base_params,
.need_dc_calib = true,
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index ddba39999997..47891e16a758 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -62,7 +62,7 @@
*****************************************************************************/
/*
* Please use this file (iwl-6000-hw.h) only for hardware-related definitions.
- * Use iwl-5000-commands.h for uCode API definitions.
+ * Use iwl-commands.h for uCode API definitions.
*/
#ifndef __iwl_6000_hw_h__
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index cee06b968de8..11e6532fc573 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -51,13 +51,15 @@
/* Highest firmware API version supported */
#define IWL6000_UCODE_API_MAX 4
-#define IWL6050_UCODE_API_MAX 4
-#define IWL6000G2_UCODE_API_MAX 4
+#define IWL6050_UCODE_API_MAX 5
+#define IWL6000G2_UCODE_API_MAX 5
+#define IWL130_UCODE_API_MAX 5
/* Lowest firmware API version supported */
#define IWL6000_UCODE_API_MIN 4
#define IWL6050_UCODE_API_MIN 4
#define IWL6000G2_UCODE_API_MIN 4
+#define IWL130_UCODE_API_MIN 5
#define IWL6000_FW_PRE "iwlwifi-6000-"
#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
@@ -75,6 +77,9 @@
#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode"
#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api)
+#define IWL130_FW_PRE "iwlwifi-130-"
+#define _IWL130_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode"
+#define IWL130_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api)
static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
{
@@ -83,15 +88,24 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
}
-/* Indicate calibration version to uCode. */
-static void iwl6000_set_calib_version(struct iwl_priv *priv)
+static void iwl6050_additional_nic_config(struct iwl_priv *priv)
{
- if (priv->cfg->need_dc_calib &&
- (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6))
+ /* Indicate calibration version to uCode. */
+ if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
}
+static void iwl6050g2_additional_nic_config(struct iwl_priv *priv)
+{
+ /* Indicate calibration version to uCode. */
+ if (priv->cfg->ops->lib->eeprom_ops.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,
+ CSR_GP_DRIVER_REG_BIT_6050_1x2);
+}
+
/* NIC configuration for 6000 series */
static void iwl6000_nic_config(struct iwl_priv *priv)
{
@@ -117,9 +131,11 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
iwl_write32(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
}
- /* else do nothing, uCode configured */
- if (priv->cfg->ops->lib->temp_ops.set_calib_version)
- priv->cfg->ops->lib->temp_ops.set_calib_version(priv);
+ /* do additional nic configuration if needed */
+ if (priv->cfg->ops->nic &&
+ priv->cfg->ops->nic->additional_nic_config) {
+ priv->cfg->ops->nic->additional_nic_config(priv);
+ }
}
static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
@@ -151,17 +167,17 @@ 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)
- priv->cfg->num_of_queues =
+ priv->cfg->base_params->num_of_queues =
priv->cfg->mod_params->num_of_queues;
- priv->hw_params.max_txq_num = priv->cfg->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;
priv->hw_params.scd_bc_tbls_size =
- priv->cfg->num_of_queues *
+ priv->cfg->base_params->num_of_queues *
sizeof(struct iwlagn_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
@@ -176,8 +192,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
- if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
- priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+ iwl6000_set_ct_threshold(priv);
/* Set initial sensitivity parameters */
/* Set initial calibration set */
@@ -188,7 +203,9 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
BIT(IWL_CALIB_TX_IQ) |
BIT(IWL_CALIB_BASE_BAND);
if (priv->cfg->need_dc_calib)
- priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC);
+ priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX);
+ if (priv->cfg->need_temp_offset_calib)
+ priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET);
priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
@@ -198,14 +215,19 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
struct ieee80211_channel_switch *ch_switch)
{
+ /*
+ * MULTI-FIXME
+ * See iwl_mac_channel_switch.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct iwl6000_channel_switch_cmd cmd;
const struct iwl_channel_info *ch_info;
u32 switch_time_in_usec, ucode_switch_time;
u16 ch;
u32 tsf_low;
u8 switch_count;
- u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
- struct ieee80211_vif *vif = priv->vif;
+ u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
+ struct ieee80211_vif *vif = ctx->vif;
struct iwl_host_cmd hcmd = {
.id = REPLY_CHANNEL_SWITCH,
.len = sizeof(cmd),
@@ -214,12 +236,12 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
};
cmd.band = priv->band == IEEE80211_BAND_2GHZ;
- ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq);
+ ch = ch_switch->channel->hw_value;
IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
- priv->active_rxon.channel, ch);
+ ctx->active.channel, ch);
cmd.channel = cpu_to_le16(ch);
- cmd.rxon_flags = priv->staging_rxon.flags;
- cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
+ cmd.rxon_flags = ctx->staging.flags;
+ cmd.rxon_filter_flags = ctx->staging.filter_flags;
switch_count = ch_switch->count;
tsf_low = ch_switch->timestamp & 0x0ffffffff;
/*
@@ -254,7 +276,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
cmd.expect_beacon = is_channel_radar(ch_info);
else {
IWL_ERR(priv, "invalid channel switch from %u to %u\n",
- priv->active_rxon.channel, ch);
+ ctx->active.channel, ch);
return -EFAULT;
}
priv->switch_rxon.channel = cmd.channel;
@@ -288,9 +310,7 @@ static struct iwl_lib_ops iwl6000_lib = {
.set_channel_switch = iwl6000_hw_channel_switch,
.apm_ops = {
.init = iwl_apm_init,
- .stop = iwl_apm_stop,
.config = iwl6000_nic_config,
- .set_pwr_src = iwl_set_pwr_src,
},
.eeprom_ops = {
.regulatory_bands = {
@@ -302,7 +322,6 @@ static struct iwl_lib_ops iwl6000_lib = {
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
.release_semaphore = iwlcore_eeprom_release_semaphore,
.calib_version = iwlagn_eeprom_calib_version,
@@ -314,22 +333,105 @@ static struct iwl_lib_ops iwl6000_lib = {
.config_ap = iwl_config_ap,
.temp_ops = {
.temperature = iwlagn_temperature,
- .set_ct_kill = iwl6000_set_ct_threshold,
- .set_calib_version = iwl6000_set_calib_version,
},
.manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_station = iwl_update_bcast_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
+ .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,
+ },
+ .recover_from_tx_stall = iwl_bg_monitor_recover,
+ .check_plcp_health = iwl_good_plcp_health,
+ .check_ack_health = iwl_good_ack_health,
+ .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 iwl6000g2b_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_bt_rx_handler_setup,
+ .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,
+ .apm_ops = {
+ .init = iwl_apm_init,
+ .config = iwl6000_nic_config,
+ },
+ .eeprom_ops = {
+ .regulatory_bands = {
+ EEPROM_REG_BAND_1_CHANNELS,
+ EEPROM_REG_BAND_2_CHANNELS,
+ EEPROM_REG_BAND_3_CHANNELS,
+ EEPROM_REG_BAND_4_CHANNELS,
+ EEPROM_REG_BAND_5_CHANNELS,
+ 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,
+ },
+ .post_associate = iwl_post_associate,
+ .isr = iwl_isr_ict,
+ .config_ap = iwl_config_ap,
+ .temp_ops = {
+ .temperature = iwlagn_temperature,
+ },
+ .manage_ibss_station = iwlagn_manage_ibss_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
.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,
},
.recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.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 = {
+ .additional_nic_config = &iwl6050_additional_nic_config,
+};
+
+static struct iwl_nic_ops iwl6050g2_nic_ops = {
+ .additional_nic_config = &iwl6050g2_additional_nic_config,
};
static const struct iwl_ops iwl6000_ops = {
@@ -339,49 +441,39 @@ static const struct iwl_ops iwl6000_ops = {
.led = &iwlagn_led_ops,
};
-static void do_not_send_bt_config(struct iwl_priv *priv)
-{
-}
+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,
+};
-static struct iwl_hcmd_ops iwl6000g2b_hcmd = {
- .rxon_assoc = iwlagn_send_rxon_assoc,
- .commit_rxon = iwl_commit_rxon,
- .set_rxon_chain = iwl_set_rxon_chain,
- .set_tx_ant = iwlagn_send_tx_ant_config,
- .send_bt_config = do_not_send_bt_config,
+static const struct iwl_ops iwl6050g2_ops = {
+ .lib = &iwl6000_lib,
+ .hcmd = &iwlagn_hcmd,
+ .utils = &iwlagn_hcmd_utils,
+ .led = &iwlagn_led_ops,
+ .nic = &iwl6050g2_nic_ops,
};
static const struct iwl_ops iwl6000g2b_ops = {
- .lib = &iwl6000_lib,
- .hcmd = &iwl6000g2b_hcmd,
+ .lib = &iwl6000g2b_lib,
+ .hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
};
-struct iwl_cfg iwl6000g2a_2agn_cfg = {
- .name = "6000 Series 2x2 AGN Gen2a",
- .fw_name_pre = IWL6000G2A_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl6000_ops,
+static struct iwl_base_params iwl6000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
- .mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.pll_cfg_val = 0,
.set_l0s = true,
.use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
- .ht_greenfield_support = true,
.led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.supports_idle = true,
.adv_thermal_throttle = true,
@@ -393,29 +485,16 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
- .need_dc_calib = true,
};
-struct iwl_cfg iwl6000g2a_2abg_cfg = {
- .name = "6000 Series 2x2 ABG Gen2a",
- .fw_name_pre = IWL6000G2A_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .ops = &iwl6000_ops,
+static struct iwl_base_params iwl6050_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
- .mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.pll_cfg_val = 0,
.set_l0s = true,
.use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+ .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
.shadow_ram_support = true,
.led_compensation = 51,
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -423,33 +502,20 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
.adv_thermal_throttle = true,
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
+ .chain_noise_scale = 1500,
.monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
- .max_event_log_size = 512,
+ .max_event_log_size = 1024,
+ .ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
- .need_dc_calib = true,
};
-
-struct iwl_cfg iwl6000g2a_2bg_cfg = {
- .name = "6000 Series 2x2 BG Gen2a",
- .fw_name_pre = IWL6000G2A_FW_PRE,
- .ucode_api_max = IWL6000G2_UCODE_API_MAX,
- .ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .ops = &iwl6000_ops,
+static struct iwl_base_params iwl6000_coex_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE,
- .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.num_of_queues = IWLAGN_NUM_QUEUES,
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
- .mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.pll_cfg_val = 0,
.set_l0s = true,
.use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.led_compensation = 51,
@@ -459,11 +525,76 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
+};
+
+static struct iwl_ht_params iwl6000_ht_params = {
+ .ht_greenfield_support = true,
+ .use_rts_for_aggregation = true, /* use rts/cts protection */
+};
+
+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,
+ .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
+ .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
+};
+
+struct iwl_cfg iwl6000g2a_2agn_cfg = {
+ .name = "6000 Series 2x2 AGN Gen2a",
+ .fw_name_pre = IWL6000G2A_FW_PRE,
+ .ucode_api_max = IWL6000G2_UCODE_API_MAX,
+ .ucode_api_min = IWL6000G2_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
+ .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_6000G2_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,
+ .need_temp_offset_calib = true,
+};
+
+struct iwl_cfg iwl6000g2a_2abg_cfg = {
+ .name = "6000 Series 2x2 ABG Gen2a",
+ .fw_name_pre = IWL6000G2A_FW_PRE,
+ .ucode_api_max = IWL6000G2_UCODE_API_MAX,
+ .ucode_api_min = IWL6000G2_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
+ .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
+ .ops = &iwl6000_ops,
+ .mod_params = &iwlagn_mod_params,
+ .base_params = &iwl6000_base_params,
+ .need_dc_calib = true,
+ .need_temp_offset_calib = true,
+};
+
+struct iwl_cfg iwl6000g2a_2bg_cfg = {
+ .name = "6000 Series 2x2 BG Gen2a",
+ .fw_name_pre = IWL6000G2A_FW_PRE,
+ .ucode_api_max = IWL6000G2_UCODE_API_MAX,
+ .ucode_api_min = IWL6000G2_UCODE_API_MIN,
+ .sku = IWL_SKU_G,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
+ .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
+ .ops = &iwl6000_ops,
+ .mod_params = &iwlagn_mod_params,
+ .base_params = &iwl6000_base_params,
.need_dc_calib = true,
+ .need_temp_offset_calib = true,
};
struct iwl_cfg iwl6000g2b_2agn_cfg = {
@@ -472,36 +603,19 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl6000g2b_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6000g2b_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl6000_coex_base_params,
+ .bt_params = &iwl6000_bt_params,
+ .ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
- .bt_statistics = true,
+ .need_temp_offset_calib = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
struct iwl_cfg iwl6000g2b_2abg_cfg = {
@@ -510,34 +624,18 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
- .ops = &iwl6000g2b_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6000g2b_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .led_compensation = 51,
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl6000_coex_base_params,
+ .bt_params = &iwl6000_bt_params,
.need_dc_calib = true,
- .bt_statistics = true,
+ .need_temp_offset_calib = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
struct iwl_cfg iwl6000g2b_2bgn_cfg = {
@@ -546,36 +644,19 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
.sku = IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl6000g2b_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6000g2b_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl6000_coex_base_params,
+ .bt_params = &iwl6000_bt_params,
+ .ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
- .bt_statistics = true,
+ .need_temp_offset_calib = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
struct iwl_cfg iwl6000g2b_2bg_cfg = {
@@ -584,34 +665,18 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
.sku = IWL_SKU_G,
- .ops = &iwl6000g2b_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6000g2b_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .led_compensation = 51,
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl6000_coex_base_params,
+ .bt_params = &iwl6000_bt_params,
.need_dc_calib = true,
- .bt_statistics = true,
+ .need_temp_offset_calib = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
struct iwl_cfg iwl6000g2b_bgn_cfg = {
@@ -620,36 +685,19 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
.sku = IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl6000g2b_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6000g2b_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl6000_coex_base_params,
+ .bt_params = &iwl6000_bt_params,
+ .ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
- .bt_statistics = true,
+ .need_temp_offset_calib = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
struct iwl_cfg iwl6000g2b_bg_cfg = {
@@ -658,34 +706,18 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
.sku = IWL_SKU_G,
- .ops = &iwl6000g2b_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6000g2b_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .led_compensation = 51,
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
- .max_event_log_size = 512,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl6000_coex_base_params,
+ .bt_params = &iwl6000_bt_params,
.need_dc_calib = true,
- .bt_statistics = true,
+ .need_temp_offset_calib = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
/*
@@ -697,35 +729,15 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl6000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6000_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
+ .base_params = &iwl6000_base_params,
+ .ht_params = &iwl6000_ht_params,
.pa_type = IWL_PA_INTERNAL,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
- .max_event_log_size = 1024,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -734,33 +746,14 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
- .ops = &iwl6000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6000_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
+ .base_params = &iwl6000_base_params,
.pa_type = IWL_PA_INTERNAL,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .led_compensation = 51,
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
- .max_event_log_size = 1024,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -769,33 +762,14 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
.sku = IWL_SKU_G,
- .ops = &iwl6000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6000_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
+ .base_params = &iwl6000_base_params,
.pa_type = IWL_PA_INTERNAL,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .led_compensation = 51,
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
- .max_event_log_size = 1024,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl6050_2agn_cfg = {
@@ -804,35 +778,14 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.ucode_api_max = IWL6050_UCODE_API_MAX,
.ucode_api_min = IWL6050_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl6000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
+ .ops = &iwl6050_ops,
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
- .shadow_ram_support = true,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1500,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
- .max_event_log_size = 1024,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl6050_base_params,
+ .ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
};
@@ -842,35 +795,14 @@ struct iwl_cfg iwl6050g2_bgn_cfg = {
.ucode_api_max = IWL6050_UCODE_API_MAX,
.ucode_api_min = IWL6050_UCODE_API_MIN,
.sku = IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl6000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6050G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6050g2_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
- .shadow_ram_support = true,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1500,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
- .max_event_log_size = 1024,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl6050_base_params,
+ .ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
};
@@ -880,33 +812,13 @@ struct iwl_cfg iwl6050_2abg_cfg = {
.ucode_api_max = IWL6050_UCODE_API_MAX,
.ucode_api_min = IWL6050_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
- .ops = &iwl6000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6050_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
- .shadow_ram_support = true,
- .led_compensation = 51,
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1500,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
- .max_event_log_size = 1024,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl6050_base_params,
.need_dc_calib = true,
};
@@ -916,38 +828,58 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl6000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
- .num_of_queues = IWLAGN_NUM_QUEUES,
- .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+ .ops = &iwl6000_ops,
.mod_params = &iwlagn_mod_params,
- .valid_tx_ant = ANT_ABC,
- .valid_rx_ant = ANT_ABC,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_SYSTEM,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_aggregation = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
- .max_event_log_size = 1024,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .base_params = &iwl6000_base_params,
+ .ht_params = &iwl6000_ht_params,
+ .need_dc_calib = true,
+};
+
+struct iwl_cfg iwl130_bgn_cfg = {
+ .name = "Intel(R) 130 Series 1x1 BGN",
+ .fw_name_pre = IWL6000G2B_FW_PRE,
+ .ucode_api_max = IWL130_UCODE_API_MAX,
+ .ucode_api_min = IWL130_UCODE_API_MIN,
+ .sku = IWL_SKU_G|IWL_SKU_N,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_A,
+ .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
+ .ops = &iwl6000g2b_ops,
+ .mod_params = &iwlagn_mod_params,
+ .base_params = &iwl6000_coex_base_params,
+ .bt_params = &iwl6000_bt_params,
+ .ht_params = &iwl6000_ht_params,
+ .need_dc_calib = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+};
+
+struct iwl_cfg iwl130_bg_cfg = {
+ .name = "Intel(R) 130 Series 1x2 BG",
+ .fw_name_pre = IWL6000G2B_FW_PRE,
+ .ucode_api_max = IWL130_UCODE_API_MAX,
+ .ucode_api_min = IWL130_UCODE_API_MIN,
+ .sku = IWL_SKU_G,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_A,
+ .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
+ .ops = &iwl6000g2b_ops,
+ .mod_params = &iwlagn_mod_params,
+ .base_params = &iwl6000_coex_base_params,
+ .bt_params = &iwl6000_bt_params,
+ .need_dc_calib = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL130_MODULE_FIRMWARE(IWL130_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index c4c5691032a6..e2019e756936 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -65,7 +65,7 @@
#include "iwl-dev.h"
#include "iwl-core.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
/*****************************************************************************
* INIT calibrations framework
@@ -625,13 +625,14 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
data = &(priv->sensitivity_data);
- if (!iwl_is_associated(priv)) {
+ if (!iwl_is_any_associated(priv)) {
IWL_DEBUG_CALIB(priv, "<< - not associated\n");
return;
}
spin_lock_irqsave(&priv->lock, flags);
- if (priv->cfg->bt_statistics) {
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics) {
rx_info = &(((struct iwl_bt_notif_statistics *)resp)->
rx.general.common);
ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm);
@@ -763,6 +764,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
unsigned long flags;
struct statistics_rx_non_phy *rx_info;
u8 first_chain;
+ /*
+ * MULTI-FIXME:
+ * When we support multiple interfaces on different channels,
+ * this must be modified/fixed.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
if (priv->disable_chain_noise_cal)
return;
@@ -780,7 +787,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
}
spin_lock_irqsave(&priv->lock, flags);
- if (priv->cfg->bt_statistics) {
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics) {
rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)->
rx.general.common);
} else {
@@ -793,9 +801,10 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
return;
}
- rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK);
- rxon_chnum = le16_to_cpu(priv->staging_rxon.channel);
- if (priv->cfg->bt_statistics) {
+ rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
+ rxon_chnum = le16_to_cpu(ctx->staging.channel);
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics) {
stat_band24 = !!(((struct iwl_bt_notif_statistics *)
stat_resp)->flag &
STATISTICS_REPLY_FLG_BAND_24G_MSK);
@@ -855,16 +864,17 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
/* If this is the "chain_noise_num_beacons", determine:
* 1) Disconnected antennas (using signal strengths)
* 2) Differential gain (using silence noise) to balance receivers */
- if (data->beacon_count != priv->cfg->chain_noise_num_beacons)
+ if (data->beacon_count !=
+ priv->cfg->base_params->chain_noise_num_beacons)
return;
/* Analyze signal for disconnected antenna */
- average_sig[0] =
- (data->chain_signal_a) / priv->cfg->chain_noise_num_beacons;
- average_sig[1] =
- (data->chain_signal_b) / priv->cfg->chain_noise_num_beacons;
- average_sig[2] =
- (data->chain_signal_c) / priv->cfg->chain_noise_num_beacons;
+ average_sig[0] = data->chain_signal_a /
+ priv->cfg->base_params->chain_noise_num_beacons;
+ average_sig[1] = data->chain_signal_b /
+ priv->cfg->base_params->chain_noise_num_beacons;
+ average_sig[2] = data->chain_signal_c /
+ priv->cfg->base_params->chain_noise_num_beacons;
if (average_sig[0] >= average_sig[1]) {
max_average_sig = average_sig[0];
@@ -914,7 +924,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
* To be safe, simply mask out any chains that we know
* are not on the device.
*/
- active_chains &= priv->hw_params.valid_rx_ant;
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist &&
+ priv->bt_full_concurrent) {
+ /* operated as 1x1 in full concurrency mode */
+ active_chains &= first_antenna(priv->hw_params.valid_rx_ant);
+ } else
+ active_chains &= priv->hw_params.valid_rx_ant;
num_tx_chains = 0;
for (i = 0; i < NUM_RX_CHAINS; i++) {
@@ -957,12 +973,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
active_chains);
/* Analyze noise for rx balance */
- average_noise[0] =
- ((data->chain_noise_a) / priv->cfg->chain_noise_num_beacons);
- average_noise[1] =
- ((data->chain_noise_b) / priv->cfg->chain_noise_num_beacons);
- average_noise[2] =
- ((data->chain_noise_c) / priv->cfg->chain_noise_num_beacons);
+ average_noise[0] = data->chain_noise_a /
+ priv->cfg->base_params->chain_noise_num_beacons;
+ average_noise[1] = data->chain_noise_b /
+ priv->cfg->base_params->chain_noise_num_beacons;
+ average_noise[2] = data->chain_noise_c /
+ priv->cfg->base_params->chain_noise_num_beacons;
for (i = 0; i < NUM_RX_CHAINS; i++) {
if (!(data->disconn_array[i]) &&
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
index ba9523fbb300..e37ae7261630 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
@@ -79,4 +79,8 @@ static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
priv->cfg->ops->utils->chain_noise_reset(priv);
}
+int iwl_send_calib_results(struct iwl_priv *priv);
+int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
+void iwl_calib_free_results(struct iwl_priv *priv);
+
#endif /* __iwl_calib_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index d706b8afbe5a..a358d4334a1a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -25,15 +25,22 @@
* 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 (priv->cfg->bt_statistics)
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics)
flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
else
flag = le32_to_cpu(priv->_agn.statistics.flag);
@@ -82,7 +89,8 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
* the last statistics notification from uCode
* might not reflect the current uCode activity
*/
- if (priv->cfg->bt_statistics) {
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics) {
ofdm = &priv->_agn.statistics_bt.rx.ofdm;
cck = &priv->_agn.statistics_bt.rx.cck;
general = &priv->_agn.statistics_bt.rx.general.common;
@@ -121,436 +129,380 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
}
pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
- "acumulative delta max\n",
- "Statistics_Rx - OFDM:");
pos += scnprintf(buf + pos, bufsz - pos,
- " %-30s %10u %10u %10u %10u\n",
- "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "fina_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "plcp_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "crc32_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "overrun_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "early_overrun_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "crc32_good:", le32_to_cpu(ofdm->crc32_good),
+ 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,
- " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "fina_sync_err_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "sfd_timeout:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "fina_timeout:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "unresponded_rts:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "rxe_frame_lmt_ovrun:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "sent_ba_rsp_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "dsp_self_kill:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "mh_format_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "re_acq_main_rssi_sum:",
+ 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, "%-32s current"
- "acumulative delta max\n",
- "Statistics_Rx - CCK:");
pos += scnprintf(buf + pos, bufsz - pos,
- " %-30s %10u %10u %10u %10u\n",
- "ina_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "fina_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "plcp_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "crc32_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "overrun_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "early_overrun_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "crc32_good:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "false_alarm_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "fina_sync_err_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "sfd_timeout:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "fina_timeout:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "unresponded_rts:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "rxe_frame_lmt_ovrun:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "sent_ba_rsp_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "dsp_self_kill:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "mh_format_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "re_acq_main_rssi_sum:",
+ 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, "%-32s current"
- "acumulative delta max\n",
- "Statistics_Rx - GENERAL:");
pos += scnprintf(buf + pos, bufsz - pos,
- " %-30s %10u %10u %10u %10u\n", "bogus_cts:",
+ 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,
- " %-30s %10u %10u %10u %10u\n", "bogus_ack:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "non_bssid_frames:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "filtered_frames:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "non_channel_beacons:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "channel_beacons:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "num_missed_bcon:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "adc_rx_saturation_time:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "ina_detect_search_tm:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "beacon_silence_rssi_a:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "beacon_silence_rssi_b:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "beacon_silence_rssi_c:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "interference_data_flag:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "channel_load:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "dsp_false_alarms:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "beacon_rssi_a:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "beacon_rssi_b:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "beacon_rssi_c:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "beacon_energy_a:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "beacon_energy_b:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "beacon_energy_c:",
+ 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, "Statistics_Rx - OFDM_HT:\n");
- pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
- "acumulative delta max\n",
- "Statistics_Rx - OFDM_HT:");
pos += scnprintf(buf + pos, bufsz - pos,
- " %-30s %10u %10u %10u %10u\n",
- "plcp_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "overrun_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "early_overrun_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "crc32_good:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "crc32_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "mh_format_err:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg_crc32_good:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg_mpdu_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "unsupport_mcs:",
+ fmt_table, "unsupport_mcs:",
le32_to_cpu(ht->unsupport_mcs),
accum_ht->unsupport_mcs,
delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
@@ -584,7 +536,8 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
* the last statistics notification from uCode
* might not reflect the current uCode activity
*/
- if (priv->cfg->bt_statistics) {
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics) {
tx = &priv->_agn.statistics_bt.tx;
accum_tx = &priv->_agn.accum_statistics_bt.tx;
delta_tx = &priv->_agn.delta_statistics_bt.tx;
@@ -597,166 +550,141 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
}
pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
- "acumulative delta max\n",
- "Statistics_Tx:");
pos += scnprintf(buf + pos, bufsz - pos,
- " %-30s %10u %10u %10u %10u\n",
- "preamble:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "rx_detected_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "bt_prio_defer_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "bt_prio_kill_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "few_bytes_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "cts_timeout:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "ack_timeout:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "expected_ack_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "actual_ack_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "dump_msdu_cnt:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "abort_nxt_frame_mismatch:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "abort_missing_nxt_frame:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "cts_timeout_collision:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "ack_ba_timeout_collision:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg ba_timeout:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg ba_resched_frames:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg scd_query_agg_frame:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg scd_query_no_agg:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg scd_query_agg:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg scd_query_mismatch:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg frame_not_ready:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg underrun:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg bt_prio_kill:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "agg rx_ba_rsp_cnt:",
+ 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,
@@ -767,15 +695,15 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
"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,
- "\tantenna A: 0x%X\n",
+ 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,
- "\tantenna B: 0x%X\n",
+ 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,
- "\tantenna C: 0x%X\n",
+ fmt_hex, "antenna C:",
tx->tx_power.ant_c);
}
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
@@ -809,7 +737,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
* the last statistics notification from uCode
* might not reflect the current uCode activity
*/
- if (priv->cfg->bt_statistics) {
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics) {
general = &priv->_agn.statistics_bt.general.common;
dbg = &priv->_agn.statistics_bt.general.common.dbg;
div = &priv->_agn.statistics_bt.general.common.div;
@@ -838,84 +767,72 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
}
pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
- "acumulative delta max\n",
- "Statistics_General:");
- pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n",
- "temperature:",
+ 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, " %-30s %10u\n",
- "temperature_m:",
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_value, "temperature_m:",
le32_to_cpu(general->temperature_m));
pos += scnprintf(buf + pos, bufsz - pos,
- " %-30s %10u %10u %10u %10u\n",
- "burst_check:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "burst_count:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "wait_for_silence_timeout_count:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "sleep_time:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "slots_out:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "slots_idle:",
+ 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, "ttl_timestamp:\t\t\t%u\n",
- le32_to_cpu(general->ttl_timestamp));
pos += scnprintf(buf + pos, bufsz - pos,
- " %-30s %10u %10u %10u %10u\n",
- "tx_on_a:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "tx_on_b:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "exec_time:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "probe_time:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "rx_enable_counter:",
+ 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,
- " %-30s %10u %10u %10u %10u\n",
- "num_of_sos_states:",
+ 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,
@@ -1011,3 +928,147 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,
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
index bbdce5913ac7..f2573b5486cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
@@ -39,6 +39,8 @@ 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)
@@ -60,4 +62,9 @@ static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
{
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
new file mode 100644
index 000000000000..a650baba0809
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -0,0 +1,454 @@
+/******************************************************************************
+ *
+ * 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) 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
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2010 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/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <net/mac80211.h>
+
+#include "iwl-commands.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-debug.h"
+#include "iwl-agn.h"
+#include "iwl-io.h"
+
+/************************** EEPROM BANDS ****************************
+ *
+ * The iwl_eeprom_band definitions below provide the mapping from the
+ * EEPROM contents to the specific channel number supported for each
+ * band.
+ *
+ * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3
+ * definition below maps to physical channel 42 in the 5.2GHz spectrum.
+ * The specific geography and calibration information for that channel
+ * is contained in the eeprom map itself.
+ *
+ * During init, we copy the eeprom information and channel map
+ * information into priv->channel_info_24/52 and priv->channel_map_24/52
+ *
+ * channel_map_24/52 provides the index in the channel_info array for a
+ * given channel. We have to have two separate maps as there is channel
+ * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
+ * band_2
+ *
+ * A value of 0xff stored in the channel_map indicates that the channel
+ * is not supported by the hardware at all.
+ *
+ * A value of 0xfe in the channel_map indicates that the channel is not
+ * valid for Tx with the current hardware. This means that
+ * while the system can tune and receive on a given channel, it may not
+ * be able to associate or transmit any frames on that
+ * channel. There is no corresponding channel information for that
+ * entry.
+ *
+ *********************************************************************/
+
+/**
+ * struct iwl_txpwr_section: eeprom section information
+ * @offset: indirect address into eeprom image
+ * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
+ * @band: band type for the section
+ * @is_common - true: common section, false: channel section
+ * @is_cck - true: cck section, false: not cck section
+ * @is_ht_40 - true: all channel in the section are HT40 channel,
+ * false: legacy or HT 20 MHz
+ * ignore if it is common section
+ * @iwl_eeprom_section_channel: channel array in the section,
+ * ignore if common section
+ */
+struct iwl_txpwr_section {
+ u32 offset;
+ u8 count;
+ enum ieee80211_band band;
+ bool is_common;
+ bool is_cck;
+ bool is_ht40;
+ u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
+};
+
+/**
+ * section 1 - 3 are regulatory tx power apply to all channels based on
+ * modulation: CCK, OFDM
+ * Band: 2.4GHz, 5.2GHz
+ * section 4 - 10 are regulatory tx power apply to specified channels
+ * For example:
+ * 1L - Channel 1 Legacy
+ * 1HT - Channel 1 HT
+ * (1,+1) - Channel 1 HT40 "_above_"
+ *
+ * Section 1: all CCK channels
+ * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
+ * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
+ * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
+ * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
+ * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
+ * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
+ * Section 8: 2.4 GHz channel: 13L, 13HT
+ * Section 9: 2.4 GHz channel: 140L, 140HT
+ * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1)
+ *
+ */
+static const struct iwl_txpwr_section enhinfo[] = {
+ { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
+ { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
+ { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
+ { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
+ false, false, false,
+ {1, 1, 2, 2, 10, 10, 11, 11 } },
+ { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
+ false, false, true,
+ { 1, 2, 6, 7, 9 } },
+ { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
+ false, false, false,
+ { 36, 64, 100, 36, 64, 100 } },
+ { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
+ false, false, true,
+ { 36, 60, 100 } },
+ { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
+ false, false, false,
+ { 13, 13 } },
+ { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
+ false, false, false,
+ { 140, 140 } },
+ { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
+ false, false, true,
+ { 132, 44 } },
+};
+
+/******************************************************************************
+ *
+ * EEPROM related functions
+ *
+******************************************************************************/
+
+/*
+ * 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);
+
+ if (eeprom_ver < priv->cfg->eeprom_ver ||
+ calib_ver < priv->cfg->eeprom_calib_ver)
+ goto err;
+
+ IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
+ eeprom_ver, calib_ver);
+
+ return 0;
+err:
+ IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x "
+ "CALIB=0x%x < 0x%x\n",
+ eeprom_ver, priv->cfg->eeprom_ver,
+ calib_ver, priv->cfg->eeprom_calib_ver);
+ return -EINVAL;
+
+}
+
+void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
+{
+ const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
+ EEPROM_MAC_ADDRESS);
+ memcpy(mac, addr, ETH_ALEN);
+}
+
+/**
+ * iwl_get_max_txpower_avg - get the highest tx power from all chains.
+ * find the highest tx power from all chains for the channel
+ */
+static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
+ struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+ int element, s8 *max_txpower_in_half_dbm)
+{
+ s8 max_txpower_avg = 0; /* (dBm) */
+
+ IWL_DEBUG_INFO(priv, "%d - "
+ "chain_a: %d dB chain_b: %d dB "
+ "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
+ element,
+ enhanced_txpower[element].chain_a_max >> 1,
+ enhanced_txpower[element].chain_b_max >> 1,
+ enhanced_txpower[element].chain_c_max >> 1,
+ enhanced_txpower[element].mimo2_max >> 1,
+ enhanced_txpower[element].mimo3_max >> 1);
+ /* Take the highest tx power from any valid chains */
+ if ((priv->cfg->valid_tx_ant & ANT_A) &&
+ (enhanced_txpower[element].chain_a_max > max_txpower_avg))
+ max_txpower_avg = enhanced_txpower[element].chain_a_max;
+ if ((priv->cfg->valid_tx_ant & ANT_B) &&
+ (enhanced_txpower[element].chain_b_max > max_txpower_avg))
+ max_txpower_avg = enhanced_txpower[element].chain_b_max;
+ if ((priv->cfg->valid_tx_ant & ANT_C) &&
+ (enhanced_txpower[element].chain_c_max > max_txpower_avg))
+ max_txpower_avg = enhanced_txpower[element].chain_c_max;
+ if (((priv->cfg->valid_tx_ant == ANT_AB) |
+ (priv->cfg->valid_tx_ant == ANT_BC) |
+ (priv->cfg->valid_tx_ant == ANT_AC)) &&
+ (enhanced_txpower[element].mimo2_max > max_txpower_avg))
+ max_txpower_avg = enhanced_txpower[element].mimo2_max;
+ if ((priv->cfg->valid_tx_ant == ANT_ABC) &&
+ (enhanced_txpower[element].mimo3_max > max_txpower_avg))
+ max_txpower_avg = enhanced_txpower[element].mimo3_max;
+
+ /*
+ * max. tx power in EEPROM is in 1/2 dBm format
+ * convert from 1/2 dBm to dBm (round-up convert)
+ * but we also do not want to loss 1/2 dBm resolution which
+ * will impact performance
+ */
+ *max_txpower_in_half_dbm = max_txpower_avg;
+ return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
+}
+
+/**
+ * iwl_update_common_txpower: update channel tx power
+ * update tx power per band based on EEPROM enhanced tx power info.
+ */
+static s8 iwl_update_common_txpower(struct iwl_priv *priv,
+ struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+ int section, int element, s8 *max_txpower_in_half_dbm)
+{
+ struct iwl_channel_info *ch_info;
+ int ch;
+ bool is_ht40 = false;
+ s8 max_txpower_avg; /* (dBm) */
+
+ /* it is common section, contain all type (Legacy, HT and HT40)
+ * based on the element in the section to determine
+ * is it HT 40 or not
+ */
+ if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
+ is_ht40 = true;
+ max_txpower_avg =
+ iwl_get_max_txpower_avg(priv, enhanced_txpower,
+ element, max_txpower_in_half_dbm);
+
+ ch_info = priv->channel_info;
+
+ for (ch = 0; ch < priv->channel_count; ch++) {
+ /* find matching band and update tx power if needed */
+ if ((ch_info->band == enhinfo[section].band) &&
+ (ch_info->max_power_avg < max_txpower_avg) &&
+ (!is_ht40)) {
+ /* Update regulatory-based run-time data */
+ ch_info->max_power_avg = ch_info->curr_txpow =
+ max_txpower_avg;
+ ch_info->scan_power = max_txpower_avg;
+ }
+ if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
+ (ch_info->ht40_max_power_avg < max_txpower_avg)) {
+ /* Update regulatory-based run-time data */
+ ch_info->ht40_max_power_avg = max_txpower_avg;
+ }
+ ch_info++;
+ }
+ return max_txpower_avg;
+}
+
+/**
+ * iwl_update_channel_txpower: update channel tx power
+ * update channel tx power based on EEPROM enhanced tx power info.
+ */
+static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
+ struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+ int section, int element, s8 *max_txpower_in_half_dbm)
+{
+ struct iwl_channel_info *ch_info;
+ int ch;
+ u8 channel;
+ s8 max_txpower_avg; /* (dBm) */
+
+ channel = enhinfo[section].iwl_eeprom_section_channel[element];
+ max_txpower_avg =
+ iwl_get_max_txpower_avg(priv, enhanced_txpower,
+ element, max_txpower_in_half_dbm);
+
+ ch_info = priv->channel_info;
+ for (ch = 0; ch < priv->channel_count; ch++) {
+ /* find matching channel and update tx power if needed */
+ if (ch_info->channel == channel) {
+ if ((ch_info->max_power_avg < max_txpower_avg) &&
+ (!enhinfo[section].is_ht40)) {
+ /* Update regulatory-based run-time data */
+ ch_info->max_power_avg = max_txpower_avg;
+ ch_info->curr_txpow = max_txpower_avg;
+ ch_info->scan_power = max_txpower_avg;
+ }
+ if ((enhinfo[section].is_ht40) &&
+ (ch_info->ht40_max_power_avg < max_txpower_avg)) {
+ /* Update regulatory-based run-time data */
+ ch_info->ht40_max_power_avg = max_txpower_avg;
+ }
+ break;
+ }
+ ch_info++;
+ }
+ return max_txpower_avg;
+}
+
+/**
+ * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
+ */
+void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
+{
+ int eeprom_section_count = 0;
+ int section, element;
+ struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
+ u32 offset;
+ s8 max_txpower_avg; /* (dBm) */
+ s8 max_txpower_in_half_dbm; /* (half-dBm) */
+
+ /* Loop through all the sections
+ * adjust bands and channel's max tx power
+ * Set the tx_power_user_lmt to the highest power
+ * supported by any channels and chains
+ */
+ for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
+ eeprom_section_count = enhinfo[section].count;
+ offset = enhinfo[section].offset;
+ enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
+ iwl_eeprom_query_addr(priv, offset);
+
+ /*
+ * check for valid entry -
+ * different version of EEPROM might contain different set
+ * of enhanced tx power table
+ * always check for valid entry before process
+ * the information
+ */
+ if (!enhanced_txpower->common || enhanced_txpower->reserved)
+ continue;
+
+ for (element = 0; element < eeprom_section_count; element++) {
+ if (enhinfo[section].is_common)
+ max_txpower_avg =
+ iwl_update_common_txpower(priv,
+ enhanced_txpower, section,
+ element,
+ &max_txpower_in_half_dbm);
+ else
+ max_txpower_avg =
+ iwl_update_channel_txpower(priv,
+ enhanced_txpower, section,
+ element,
+ &max_txpower_in_half_dbm);
+
+ /* Update the tx_power_user_lmt to the highest power
+ * supported by any channel */
+ if (max_txpower_avg > priv->tx_power_user_lmt)
+ priv->tx_power_user_lmt = max_txpower_avg;
+
+ /*
+ * Update the tx_power_lmt_in_half_dbm to
+ * the highest power supported by any channel
+ */
+ if (max_txpower_in_half_dbm >
+ priv->tx_power_lmt_in_half_dbm)
+ priv->tx_power_lmt_in_half_dbm =
+ max_txpower_in_half_dbm;
+ }
+ }
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 75b901b3eb1e..ffb2f4111ad0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -37,12 +37,13 @@
#include "iwl-io.h"
#include "iwl-agn.h"
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
+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 = &priv->staging_rxon;
- const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
+ 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) &&
@@ -60,23 +61,23 @@ int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
return 0;
}
- rxon_assoc.flags = priv->staging_rxon.flags;
- rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
- rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+ rxon_assoc.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 =
- priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
+ ctx->staging.ofdm_ht_single_stream_basic_rates;
rxon_assoc.ofdm_ht_dual_stream_basic_rates =
- priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
- rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
+ 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 =
- priv->staging_rxon.ofdm_ht_triple_stream_basic_rates;
- rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data;
+ ctx->staging.ofdm_ht_triple_stream_basic_rates;
+ rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
- ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
+ ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
sizeof(rxon_assoc), &rxon_assoc, NULL);
if (ret)
return ret;
@@ -136,7 +137,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
continue;
}
- delta_g = (priv->cfg->chain_noise_scale *
+ delta_g = (priv->cfg->base_params->chain_noise_scale *
((s32)average_noise[default_chain] -
(s32)average_noise[i])) / 1500;
@@ -184,7 +185,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
int ret;
if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
- iwl_is_associated(priv)) {
+ iwl_is_any_associated(priv)) {
struct iwl_calib_chain_noise_reset_cmd cmd;
/* clear data for chain noise calibration algorithm */
@@ -221,7 +222,8 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
return;
}
- if (priv->cfg->use_rts_for_aggregation &&
+ if (priv->cfg->ht_params &&
+ priv->cfg->ht_params->use_rts_for_aggregation &&
info->flags & IEEE80211_TX_CTL_AMPDU) {
*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
return;
@@ -235,13 +237,13 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
/* data from PHY/DSP regarding signal strength, etc.,
* contents are always there, not configurable by host
*/
- struct iwl5000_non_cfg_phy *ncphy =
- (struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
+ struct iwlagn_non_cfg_phy *ncphy =
+ (struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
u8 agc;
- val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
- agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
+ val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]);
+ agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS;
/* Find max rssi among 3 possible receivers.
* These values are measured by the digital signal processor (DSP).
@@ -249,11 +251,14 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
* if the radio's automatic gain control (AGC) is working right.
* AGC value (see below) will provide the "interesting" info.
*/
- val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
- rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
- rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
- val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
- rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
+ val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]);
+ rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >>
+ IWLAGN_OFDM_RSSI_A_BIT_POS;
+ rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >>
+ IWLAGN_OFDM_RSSI_B_BIT_POS;
+ val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]);
+ rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >>
+ IWLAGN_OFDM_RSSI_C_BIT_POS;
max_rssi = max_t(u32, rssi_a, rssi_b);
max_rssi = max_t(u32, max_rssi, rssi_c);
@@ -266,12 +271,109 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
return max_rssi - agc - IWLAGN_RSSI_OFFSET;
}
+static int iwlagn_set_pan_params(struct iwl_priv *priv)
+{
+ struct iwl_wipan_params_cmd cmd;
+ struct iwl_rxon_context *ctx_bss, *ctx_pan;
+ int slot0 = 300, slot1 = 0;
+ int ret;
+
+ if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS))
+ return 0;
+
+ BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+
+ lockdep_assert_held(&priv->mutex);
+
+ ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS];
+ ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN];
+
+ /*
+ * If the PAN context is inactive, then we don't need
+ * to update the PAN parameters, the last thing we'll
+ * have done before it goes inactive is making the PAN
+ * parameters be WLAN-only.
+ */
+ if (!ctx_pan->is_active)
+ return 0;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ /* only 2 slots are currently allowed */
+ cmd.num_slots = 2;
+
+ cmd.slots[0].type = 0; /* BSS */
+ cmd.slots[1].type = 1; /* PAN */
+
+ if (ctx_bss->vif && ctx_pan->vif) {
+ int bcnint = ctx_pan->vif->bss_conf.beacon_int;
+
+ /* should be set, but seems unused?? */
+ cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE);
+
+ if (ctx_pan->vif->type == NL80211_IFTYPE_AP &&
+ bcnint &&
+ bcnint != ctx_bss->vif->bss_conf.beacon_int) {
+ IWL_ERR(priv,
+ "beacon intervals don't match (%d, %d)\n",
+ ctx_bss->vif->bss_conf.beacon_int,
+ ctx_pan->vif->bss_conf.beacon_int);
+ } else
+ bcnint = max_t(int, bcnint,
+ ctx_bss->vif->bss_conf.beacon_int);
+ if (!bcnint)
+ bcnint = DEFAULT_BEACON_INTERVAL;
+ slot0 = bcnint / 2;
+ slot1 = bcnint - slot0;
+
+ if (test_bit(STATUS_SCAN_HW, &priv->status) ||
+ (!ctx_bss->vif->bss_conf.idle &&
+ !ctx_bss->vif->bss_conf.assoc)) {
+ slot0 = bcnint * 3 - 20;
+ slot1 = 20;
+ } else if (!ctx_pan->vif->bss_conf.idle &&
+ !ctx_pan->vif->bss_conf.assoc) {
+ slot1 = bcnint * 3 - 20;
+ slot0 = 20;
+ }
+ } else if (ctx_pan->vif) {
+ slot0 = 0;
+ slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) *
+ ctx_pan->vif->bss_conf.beacon_int;
+ slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);
+
+ if (test_bit(STATUS_SCAN_HW, &priv->status)) {
+ slot0 = slot1 * 3 - 20;
+ slot1 = 20;
+ }
+ }
+
+ cmd.slots[0].width = cpu_to_le16(slot0);
+ cmd.slots[1].width = cpu_to_le16(slot1);
+
+ ret = iwl_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, sizeof(cmd), &cmd);
+ if (ret)
+ IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret);
+
+ return ret;
+}
+
struct iwl_hcmd_ops iwlagn_hcmd = {
.rxon_assoc = iwlagn_send_rxon_assoc,
- .commit_rxon = iwl_commit_rxon,
- .set_rxon_chain = iwl_set_rxon_chain,
+ .commit_rxon = iwlagn_commit_rxon,
+ .set_rxon_chain = iwlagn_set_rxon_chain,
.set_tx_ant = iwlagn_send_tx_ant_config,
.send_bt_config = iwl_send_bt_config,
+ .set_pan_params = iwlagn_set_pan_params,
+};
+
+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,
+ .send_bt_config = iwlagn_send_advance_bt_config,
+ .set_pan_params = iwlagn_set_pan_params,
};
struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
@@ -282,4 +384,5 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
.tx_cmd_protection = iwlagn_tx_cmd_protection,
.calc_rssi = iwlagn_calc_rssi,
.request_scan = iwlagn_request_scan,
+ .post_scan = iwlagn_post_scan,
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
index c92b2c0cbd91..a5dbfea1bfad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
@@ -59,7 +59,7 @@ void iwl_free_isr_ict(struct iwl_priv *priv)
int iwl_alloc_isr_ict(struct iwl_priv *priv)
{
- if (priv->cfg->use_isr_legacy)
+ if (priv->cfg->base_params->use_isr_legacy)
return 0;
/* allocate shrared data table */
priv->_agn.ict_tbl_vir =
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 8fd00a6e5120..b555edd53354 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -40,22 +40,195 @@
#include "iwl-agn.h"
#include "iwl-sta.h"
-static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
+static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp)
{
return le32_to_cpup((__le32 *)&tx_resp->status +
tx_resp->frame_count) & MAX_SN;
}
+static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status)
+{
+ status &= TX_STATUS_MSK;
+
+ switch (status) {
+ case TX_STATUS_POSTPONE_DELAY:
+ priv->_agn.reply_tx_stats.pp_delay++;
+ break;
+ case TX_STATUS_POSTPONE_FEW_BYTES:
+ priv->_agn.reply_tx_stats.pp_few_bytes++;
+ break;
+ case TX_STATUS_POSTPONE_BT_PRIO:
+ priv->_agn.reply_tx_stats.pp_bt_prio++;
+ break;
+ case TX_STATUS_POSTPONE_QUIET_PERIOD:
+ priv->_agn.reply_tx_stats.pp_quiet_period++;
+ break;
+ case TX_STATUS_POSTPONE_CALC_TTAK:
+ priv->_agn.reply_tx_stats.pp_calc_ttak++;
+ break;
+ case TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY:
+ priv->_agn.reply_tx_stats.int_crossed_retry++;
+ break;
+ case TX_STATUS_FAIL_SHORT_LIMIT:
+ priv->_agn.reply_tx_stats.short_limit++;
+ break;
+ case TX_STATUS_FAIL_LONG_LIMIT:
+ priv->_agn.reply_tx_stats.long_limit++;
+ break;
+ case TX_STATUS_FAIL_FIFO_UNDERRUN:
+ priv->_agn.reply_tx_stats.fifo_underrun++;
+ break;
+ case TX_STATUS_FAIL_DRAIN_FLOW:
+ priv->_agn.reply_tx_stats.drain_flow++;
+ break;
+ case TX_STATUS_FAIL_RFKILL_FLUSH:
+ priv->_agn.reply_tx_stats.rfkill_flush++;
+ break;
+ case TX_STATUS_FAIL_LIFE_EXPIRE:
+ priv->_agn.reply_tx_stats.life_expire++;
+ break;
+ case TX_STATUS_FAIL_DEST_PS:
+ priv->_agn.reply_tx_stats.dest_ps++;
+ break;
+ case TX_STATUS_FAIL_HOST_ABORTED:
+ priv->_agn.reply_tx_stats.host_abort++;
+ break;
+ case TX_STATUS_FAIL_BT_RETRY:
+ priv->_agn.reply_tx_stats.bt_retry++;
+ break;
+ case TX_STATUS_FAIL_STA_INVALID:
+ priv->_agn.reply_tx_stats.sta_invalid++;
+ break;
+ case TX_STATUS_FAIL_FRAG_DROPPED:
+ priv->_agn.reply_tx_stats.frag_drop++;
+ break;
+ case TX_STATUS_FAIL_TID_DISABLE:
+ priv->_agn.reply_tx_stats.tid_disable++;
+ break;
+ case TX_STATUS_FAIL_FIFO_FLUSHED:
+ priv->_agn.reply_tx_stats.fifo_flush++;
+ break;
+ case TX_STATUS_FAIL_INSUFFICIENT_CF_POLL:
+ priv->_agn.reply_tx_stats.insuff_cf_poll++;
+ break;
+ case TX_STATUS_FAIL_PASSIVE_NO_RX:
+ priv->_agn.reply_tx_stats.fail_hw_drop++;
+ break;
+ case TX_STATUS_FAIL_NO_BEACON_ON_RADAR:
+ priv->_agn.reply_tx_stats.sta_color_mismatch++;
+ break;
+ default:
+ priv->_agn.reply_tx_stats.unknown++;
+ break;
+ }
+}
+
+static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
+{
+ status &= AGG_TX_STATUS_MSK;
+
+ switch (status) {
+ case AGG_TX_STATE_UNDERRUN_MSK:
+ priv->_agn.reply_agg_tx_stats.underrun++;
+ break;
+ case AGG_TX_STATE_BT_PRIO_MSK:
+ priv->_agn.reply_agg_tx_stats.bt_prio++;
+ break;
+ case AGG_TX_STATE_FEW_BYTES_MSK:
+ priv->_agn.reply_agg_tx_stats.few_bytes++;
+ break;
+ case AGG_TX_STATE_ABORT_MSK:
+ priv->_agn.reply_agg_tx_stats.abort++;
+ break;
+ case AGG_TX_STATE_LAST_SENT_TTL_MSK:
+ priv->_agn.reply_agg_tx_stats.last_sent_ttl++;
+ break;
+ case AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK:
+ priv->_agn.reply_agg_tx_stats.last_sent_try++;
+ break;
+ case AGG_TX_STATE_LAST_SENT_BT_KILL_MSK:
+ priv->_agn.reply_agg_tx_stats.last_sent_bt_kill++;
+ break;
+ case AGG_TX_STATE_SCD_QUERY_MSK:
+ priv->_agn.reply_agg_tx_stats.scd_query++;
+ break;
+ case AGG_TX_STATE_TEST_BAD_CRC32_MSK:
+ priv->_agn.reply_agg_tx_stats.bad_crc32++;
+ break;
+ case AGG_TX_STATE_RESPONSE_MSK:
+ priv->_agn.reply_agg_tx_stats.response++;
+ break;
+ case AGG_TX_STATE_DUMP_TX_MSK:
+ priv->_agn.reply_agg_tx_stats.dump_tx++;
+ break;
+ case AGG_TX_STATE_DELAY_TX_MSK:
+ priv->_agn.reply_agg_tx_stats.delay_tx++;
+ break;
+ default:
+ priv->_agn.reply_agg_tx_stats.unknown++;
+ break;
+ }
+}
+
+static void iwlagn_set_tx_status(struct iwl_priv *priv,
+ struct ieee80211_tx_info *info,
+ struct iwlagn_tx_resp *tx_resp,
+ int txq_id, bool is_agg)
+{
+ u16 status = le16_to_cpu(tx_resp->status.status);
+
+ info->status.rates[0].count = tx_resp->failure_frame + 1;
+ if (is_agg)
+ info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+ info->flags |= iwl_tx_status_to_mac80211(status);
+ iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
+ info);
+ if (!iwl_is_tx_success(status))
+ iwlagn_count_tx_err_status(priv, status);
+
+ IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
+ "0x%x retries %d\n",
+ txq_id,
+ iwl_get_tx_fail_reason(status), status,
+ le32_to_cpu(tx_resp->rate_n_flags),
+ tx_resp->failure_frame);
+}
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+#define AGG_TX_STATE_FAIL(x) case AGG_TX_STATE_ ## x: return #x
+
+const char *iwl_get_agg_tx_fail_reason(u16 status)
+{
+ status &= AGG_TX_STATUS_MSK;
+ switch (status) {
+ case AGG_TX_STATE_TRANSMITTED:
+ return "SUCCESS";
+ AGG_TX_STATE_FAIL(UNDERRUN_MSK);
+ AGG_TX_STATE_FAIL(BT_PRIO_MSK);
+ AGG_TX_STATE_FAIL(FEW_BYTES_MSK);
+ AGG_TX_STATE_FAIL(ABORT_MSK);
+ AGG_TX_STATE_FAIL(LAST_SENT_TTL_MSK);
+ AGG_TX_STATE_FAIL(LAST_SENT_TRY_CNT_MSK);
+ AGG_TX_STATE_FAIL(LAST_SENT_BT_KILL_MSK);
+ AGG_TX_STATE_FAIL(SCD_QUERY_MSK);
+ AGG_TX_STATE_FAIL(TEST_BAD_CRC32_MSK);
+ AGG_TX_STATE_FAIL(RESPONSE_MSK);
+ AGG_TX_STATE_FAIL(DUMP_TX_MSK);
+ AGG_TX_STATE_FAIL(DELAY_TX_MSK);
+ }
+
+ return "UNKNOWN";
+}
+#endif /* CONFIG_IWLWIFI_DEBUG */
+
static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
struct iwl_ht_agg *agg,
- struct iwl5000_tx_resp *tx_resp,
+ struct iwlagn_tx_resp *tx_resp,
int txq_id, u16 start_idx)
{
u16 status;
struct agg_tx_status *frame_status = &tx_resp->status;
- struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL;
- u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
int i, sh, idx;
u16 seq;
@@ -64,31 +237,20 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
- agg->rate_n_flags = rate_n_flags;
+ agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
agg->bitmap = 0;
/* # frames attempted by Tx command */
if (agg->frame_count == 1) {
/* Only one frame was attempted; no block-ack will arrive */
- status = le16_to_cpu(frame_status[0].status);
idx = start_idx;
- /* FIXME: code repetition */
IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
agg->frame_count, agg->start_idx, idx);
-
- info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb);
- info->status.rates[0].count = tx_resp->failure_frame + 1;
- info->flags &= ~IEEE80211_TX_CTL_AMPDU;
- info->flags |= iwl_tx_status_to_mac80211(status);
- iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info);
-
- /* FIXME: code repetition end */
-
- IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
- status & 0xff, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
-
+ iwlagn_set_tx_status(priv,
+ IEEE80211_SKB_CB(
+ priv->txq[txq_id].txb[idx].skb),
+ tx_resp, txq_id, true);
agg->wait_for_ba = 0;
} else {
/* Two or more frames were attempted; expect block-ack */
@@ -109,12 +271,20 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
idx = SEQ_TO_INDEX(seq);
txq_id = SEQ_TO_QUEUE(seq);
+ if (status & AGG_TX_STATUS_MSK)
+ iwlagn_count_agg_tx_err_status(priv, status);
+
if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
AGG_TX_STATE_ABORT_MSK))
continue;
IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
agg->frame_count, txq_id, idx);
+ IWL_DEBUG_TX_REPLY(priv, "status %s (0x%08x), "
+ "try-count (0x%08x)\n",
+ iwl_get_agg_tx_fail_reason(status),
+ status & AGG_TX_STATUS_MSK,
+ status & AGG_TX_TRY_MSK);
hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
if (!hdr) {
@@ -220,7 +390,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
int index = SEQ_TO_INDEX(sequence);
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct ieee80211_tx_info *info;
- struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+ struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le16_to_cpu(tx_resp->status.status);
int tid;
int sta_id;
@@ -238,8 +408,10 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
memset(&info->status, 0, sizeof(info->status));
- tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
- sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
+ tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >>
+ IWLAGN_TX_RES_TID_POS;
+ sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >>
+ IWLAGN_TX_RES_RA_POS;
spin_lock_irqsave(&priv->sta_lock, flags);
if (txq->sched_retry) {
@@ -247,7 +419,15 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
struct iwl_ht_agg *agg;
agg = &priv->stations[sta_id].tid[tid].agg;
-
+ /*
+ * If the BT kill count is non-zero, we'll get this
+ * notification again.
+ */
+ if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 &&
+ priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ IWL_WARN(priv, "receive reply tx with bt_kill\n");
+ }
iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
/* check if BAR is needed */
@@ -274,20 +454,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
}
} else {
BUG_ON(txq_id != txq->swq_id);
-
- info->status.rates[0].count = tx_resp->failure_frame + 1;
- info->flags |= iwl_tx_status_to_mac80211(status);
- iwlagn_hwrate_to_tx_control(priv,
- le32_to_cpu(tx_resp->rate_n_flags),
- info);
-
- IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
- "0x%x retries %d\n",
- txq_id,
- iwl_get_tx_fail_reason(status), status,
- le32_to_cpu(tx_resp->rate_n_flags),
- tx_resp->failure_frame);
-
+ iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false);
freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
@@ -326,7 +493,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr)
int iwlagn_send_tx_power(struct iwl_priv *priv)
{
- struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
+ struct iwlagn_tx_power_dbm_cmd tx_power_cmd;
u8 tx_ant_cfg_cmd;
/* half dBm need to multiply */
@@ -347,8 +514,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
*/
tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm;
}
- tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
- tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
+ tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED;
+ tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO;
if (IWL_UCODE_API(priv->ucode_ver) == 1)
tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
@@ -425,7 +592,7 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
size_t offset)
{
u32 address = eeprom_indirect_address(priv, offset);
- BUG_ON(address >= priv->cfg->eeprom_size);
+ BUG_ON(address >= priv->cfg->base_params->eeprom_size);
return &priv->eeprom[address];
}
@@ -473,7 +640,7 @@ 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->use_isr_legacy)
+ if (!priv->cfg->base_params->use_isr_legacy)
rb_timeout = RX_RB_TIMEOUT;
if (priv->cfg->mod_params->amsdu_size_8K)
@@ -518,6 +685,23 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
return 0;
}
+static void iwlagn_set_pwr_vmain(struct iwl_priv *priv)
+{
+/*
+ * (for documentation purposes)
+ * to set power to V_AUX, do:
+
+ if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
+ iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+ APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
+ ~APMG_PS_CTRL_MSK_PWR_SRC);
+ */
+
+ iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+ APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
+ ~APMG_PS_CTRL_MSK_PWR_SRC);
+}
+
int iwlagn_hw_nic_init(struct iwl_priv *priv)
{
unsigned long flags;
@@ -533,7 +717,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
- ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
+ iwlagn_set_pwr_vmain(priv);
priv->cfg->ops->lib->apm_ops.config(priv);
@@ -1098,7 +1282,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
if (chan->band != band)
continue;
- channel = ieee80211_frequency_to_channel(chan->center_freq);
+ channel = chan->hw_value;
scan_ch->channel = cpu_to_le16(channel);
ch_info = iwl_get_channel_info(priv, band, channel);
@@ -1147,7 +1331,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
return added;
}
-void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
+int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
@@ -1155,7 +1339,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
.flags = CMD_SIZE_HUGE,
};
struct iwl_scan_cmd *scan;
- struct ieee80211_conf *conf = NULL;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
u32 rate_flags = 0;
u16 cmd_len;
u16 rx_chain = 0;
@@ -1167,48 +1351,12 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
int chan_mod;
u8 active_chains;
u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
+ int ret;
- conf = ieee80211_get_hw_conf(priv->hw);
-
- cancel_delayed_work(&priv->scan_check);
-
- if (!iwl_is_ready(priv)) {
- IWL_WARN(priv, "request scan called when driver not ready.\n");
- goto done;
- }
-
- /* Make sure the scan wasn't canceled before this queued work
- * was given the chance to run... */
- if (!test_bit(STATUS_SCANNING, &priv->status))
- goto done;
-
- /* This should never be called or scheduled if there is currently
- * a scan active in the hardware. */
- if (test_bit(STATUS_SCAN_HW, &priv->status)) {
- IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
- "Ignoring second request.\n");
- goto done;
- }
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
- goto done;
- }
-
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n");
- goto done;
- }
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
- goto done;
- }
+ lockdep_assert_held(&priv->mutex);
- if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n");
- goto done;
- }
+ if (vif)
+ ctx = iwl_rxon_ctx_from_vif(vif);
if (!priv->scan_cmd) {
priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
@@ -1216,7 +1364,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
if (!priv->scan_cmd) {
IWL_DEBUG_SCAN(priv,
"fail to allocate memory for scan\n");
- goto done;
+ return -ENOMEM;
}
}
scan = priv->scan_cmd;
@@ -1225,7 +1373,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
- if (iwl_is_associated(priv)) {
+ if (iwl_is_any_associated(priv)) {
u16 interval = 0;
u32 extra;
u32 suspend_time = 100;
@@ -1276,13 +1424,15 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
+ scan->tx_cmd.sta_id = ctx->bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
switch (priv->scan_band) {
case IEEE80211_BAND_2GHZ:
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
- chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
+ chan_mod = le32_to_cpu(
+ priv->contexts[IWL_RXON_CTX_BSS].active.flags &
+ RXON_FLG_CHANNEL_MODE_MSK)
>> RXON_FLG_CHANNEL_MODE_POS;
if (chan_mod == CHANNEL_MODE_PURE_40) {
rate = IWL_RATE_6M_PLCP;
@@ -1290,35 +1440,42 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
rate = IWL_RATE_1M_PLCP;
rate_flags = RATE_MCS_CCK_MSK;
}
- scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
+ /*
+ * Internal scans are passive, so we can indiscriminately set
+ * the BT ignore flag on 2.4 GHz since it applies to TX only.
+ */
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist)
+ scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
break;
case IEEE80211_BAND_5GHZ:
rate = IWL_RATE_6M_PLCP;
- /*
- * If active scanning is requested but a certain channel is
- * marked passive, we can do active scanning if we detect
- * transmissions.
- *
- * There is an issue with some firmware versions that triggers
- * a sysassert on a "good CRC threshold" of zero (== disabled),
- * on a radar channel even though this means that we should NOT
- * send probes.
- *
- * The "good CRC threshold" is the number of frames that we
- * need to receive during our dwell time on a channel before
- * sending out probes -- setting this to a huge value will
- * 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.
- */
- scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
- IWL_GOOD_CRC_TH_NEVER;
break;
default:
- IWL_WARN(priv, "Invalid scan band count\n");
- goto done;
+ IWL_WARN(priv, "Invalid scan band\n");
+ return -EIO;
}
+ /*
+ * If active scanning is requested but a certain channel is
+ * marked passive, we can do active scanning if we detect
+ * transmissions.
+ *
+ * There is an issue with some firmware versions that triggers
+ * a sysassert on a "good CRC threshold" of zero (== disabled),
+ * on a radar channel even though this means that we should NOT
+ * send probes.
+ *
+ * The "good CRC threshold" is the number of frames that we
+ * need to receive during our dwell time on a channel before
+ * sending out probes -- setting this to a huge value will
+ * 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.
+ */
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+ IWL_GOOD_CRC_TH_NEVER;
+
band = priv->scan_band;
if (priv->cfg->scan_rx_antennas[band])
@@ -1327,6 +1484,14 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
if (priv->cfg->scan_tx_antennas[band])
scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist &&
+ priv->bt_full_concurrent) {
+ /* operated as 1x1 in full concurrency mode */
+ scan_tx_antennas = first_antenna(
+ priv->cfg->scan_tx_antennas[band]);
+ }
+
priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band],
scan_tx_antennas);
rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
@@ -1345,6 +1510,13 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
rx_ant = first_antenna(active_chains);
}
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist &&
+ priv->bt_full_concurrent) {
+ /* operated as 1x1 in full concurrency mode */
+ rx_ant = first_antenna(rx_ant);
+ }
+
/* MIMO is not used here, but value is required */
rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
@@ -1385,7 +1557,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
}
if (scan->channel_count == 0) {
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
- goto done;
+ return -EIO;
}
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
@@ -1393,25 +1565,39 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
cmd.data = scan;
scan->len = cpu_to_le16(cmd.len);
+ /* set scan bit here for PAN params */
set_bit(STATUS_SCAN_HW, &priv->status);
- if (iwl_send_cmd_sync(priv, &cmd))
- goto done;
- queue_delayed_work(priv->workqueue, &priv->scan_check,
- IWL_SCAN_CHECK_WATCHDOG);
-
- return;
-
- done:
- /* Cannot perform scan. Make sure we clear scanning
- * bits from status so next scan request can be performed.
- * If we don't clear scanning status bit here all next scan
- * will fail
- */
- clear_bit(STATUS_SCAN_HW, &priv->status);
- clear_bit(STATUS_SCANNING, &priv->status);
- /* inform mac80211 scan aborted */
- queue_work(priv->workqueue, &priv->abort_scan);
+ if (priv->cfg->ops->hcmd->set_pan_params) {
+ ret = priv->cfg->ops->hcmd->set_pan_params(priv);
+ if (ret)
+ return ret;
+ }
+
+ ret = iwl_send_cmd_sync(priv, &cmd);
+ if (ret) {
+ clear_bit(STATUS_SCAN_HW, &priv->status);
+ if (priv->cfg->ops->hcmd->set_pan_params)
+ priv->cfg->ops->hcmd->set_pan_params(priv);
+ }
+
+ return ret;
+}
+
+void iwlagn_post_scan(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx;
+
+ /*
+ * Since setting the RXON may have been deferred while
+ * performing the scan, fire one off if needed
+ */
+ for_each_context(priv, ctx)
+ if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+ iwlagn_commit_rxon(priv, ctx);
+
+ if (priv->cfg->ops->hcmd->set_pan_params)
+ priv->cfg->ops->hcmd->set_pan_params(priv);
}
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
@@ -1420,8 +1606,9 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
if (add)
- return iwl_add_bssid_station(priv, vif->bss_conf.bssid, true,
- &vif_priv->ibss_bssid_sta_id);
+ return iwlagn_add_bssid_station(priv, vif_priv->ctx,
+ vif->bss_conf.bssid,
+ &vif_priv->ibss_bssid_sta_id);
return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
vif->bss_conf.bssid);
}
@@ -1453,7 +1640,7 @@ int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv)
/* waiting for all the tx frames complete might take a while */
for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
- if (cnt == IWL_CMD_QUEUE_NUM)
+ if (cnt == priv->cmd_queue)
continue;
txq = &priv->txq[cnt];
q = &txq->q;
@@ -1518,3 +1705,669 @@ done:
ieee80211_wake_queues(priv->hw);
mutex_unlock(&priv->mutex);
}
+
+/*
+ * BT coex
+ */
+/*
+ * Macros to access the lookup table.
+ *
+ * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req,
+* wifi_prio, wifi_txrx and wifi_sh_ant_req.
+ *
+ * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH
+ *
+ * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits
+ * one after another in 32-bit registers, and "registers" 0 through 7 contain
+ * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order).
+ *
+ * These macros encode that format.
+ */
+#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \
+ wifi_txrx, wifi_sh_ant_req) \
+ (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \
+ (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6))
+
+#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \
+ lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f)))
+#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, \
+ bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
+ wifi_sh_ant_req))))
+#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \
+ bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
+ wifi_sh_ant_req))
+#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, \
+ wifi_sh_ant_req) \
+ LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \
+ bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
+ wifi_sh_ant_req))
+
+#define LUT_WLAN_KILL_OP(lut, op, val) \
+ lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e)))
+#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))))
+#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
+#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
+
+#define LUT_ANT_SWITCH_OP(lut, op, val) \
+ lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1)))
+#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, \
+ wifi_sh_ant_req))))
+#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
+#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
+
+static const __le32 iwlagn_def_3w_lookup[12] = {
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaeaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xcc00ff28),
+ cpu_to_le32(0x0000aaaa),
+ cpu_to_le32(0xcc00aaaa),
+ cpu_to_le32(0x0000aaaa),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0x00004000),
+ cpu_to_le32(0xf0005000),
+ cpu_to_le32(0xf0004000),
+};
+
+static const __le32 iwlagn_concurrent_lookup[12] = {
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000),
+};
+
+void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
+{
+ struct iwlagn_bt_cmd bt_cmd = {
+ .max_kill = IWLAGN_BT_MAX_KILL_DEFAULT,
+ .bt3_timer_t7_value = IWLAGN_BT3_T7_DEFAULT,
+ .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT,
+ .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT,
+ };
+
+ BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
+ sizeof(bt_cmd.bt3_lookup_table));
+
+ if (priv->cfg->bt_params)
+ bt_cmd.prio_boost = priv->cfg->bt_params->bt_prio_boost;
+ else
+ bt_cmd.prio_boost = 0;
+ bt_cmd.kill_ack_mask = priv->kill_ack_mask;
+ bt_cmd.kill_cts_mask = priv->kill_cts_mask;
+ bt_cmd.valid = priv->bt_valid;
+ bt_cmd.tx_prio_boost = 0;
+ bt_cmd.rx_prio_boost = 0;
+
+ /*
+ * Configure BT coex mode to "no coexistence" when the
+ * user disabled BT coexistence, we have no interface
+ * (might be in monitor mode), or the interface is in
+ * IBSS mode (no proper uCode support for coex then).
+ */
+ if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) {
+ bt_cmd.flags = 0;
+ } else {
+ bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
+ IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
+ if (priv->bt_ch_announce)
+ bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION;
+ IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags);
+ }
+ if (priv->bt_full_concurrent)
+ memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup,
+ sizeof(iwlagn_concurrent_lookup));
+ else
+ memcpy(bt_cmd.bt3_lookup_table, iwlagn_def_3w_lookup,
+ sizeof(iwlagn_def_3w_lookup));
+
+ IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n",
+ bt_cmd.flags ? "active" : "disabled",
+ priv->bt_full_concurrent ?
+ "full concurrency" : "3-wire");
+
+ if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd))
+ IWL_ERR(priv, "failed to send BT Coex Config\n");
+
+ /*
+ * When we are doing a restart, need to also reconfigure BT
+ * SCO to the device. If not doing a restart, bt_sco_active
+ * will always be false, so there's no need to have an extra
+ * variable to check for it.
+ */
+ if (priv->bt_sco_active) {
+ struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
+
+ if (priv->bt_sco_active)
+ sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE;
+ if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO,
+ sizeof(sco_cmd), &sco_cmd))
+ IWL_ERR(priv, "failed to send BT SCO command\n");
+ }
+}
+
+static void iwlagn_bt_traffic_change_work(struct work_struct *work)
+{
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, bt_traffic_change_work);
+ struct iwl_rxon_context *ctx;
+ int smps_request = -1;
+
+ IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
+ priv->bt_traffic_load);
+
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ smps_request = IEEE80211_SMPS_AUTOMATIC;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ smps_request = IEEE80211_SMPS_DYNAMIC;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ smps_request = IEEE80211_SMPS_STATIC;
+ break;
+ default:
+ IWL_ERR(priv, "Invalid BT traffic load: %d\n",
+ priv->bt_traffic_load);
+ break;
+ }
+
+ mutex_lock(&priv->mutex);
+
+ if (priv->cfg->ops->lib->update_chain_flags)
+ priv->cfg->ops->lib->update_chain_flags(priv);
+
+ if (smps_request != -1) {
+ for_each_context(priv, ctx) {
+ if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION)
+ ieee80211_request_smps(ctx->vif, smps_request);
+ }
+ }
+
+ mutex_unlock(&priv->mutex);
+}
+
+static void iwlagn_print_uartmsg(struct iwl_priv *priv,
+ struct iwl_bt_uart_msg *uart_msg)
+{
+ IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, "
+ "Update Req = 0x%X",
+ (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >>
+ BT_UART_MSG_FRAME1MSGTYPE_POS,
+ (BT_UART_MSG_FRAME1SSN_MSK & uart_msg->frame1) >>
+ BT_UART_MSG_FRAME1SSN_POS,
+ (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >>
+ BT_UART_MSG_FRAME1UPDATEREQ_POS);
+
+ IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, "
+ "Chl_SeqN = 0x%X, In band = 0x%X",
+ (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >>
+ BT_UART_MSG_FRAME2OPENCONNECTIONS_POS,
+ (BT_UART_MSG_FRAME2TRAFFICLOAD_MSK & uart_msg->frame2) >>
+ BT_UART_MSG_FRAME2TRAFFICLOAD_POS,
+ (BT_UART_MSG_FRAME2CHLSEQN_MSK & uart_msg->frame2) >>
+ BT_UART_MSG_FRAME2CHLSEQN_POS,
+ (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >>
+ BT_UART_MSG_FRAME2INBAND_POS);
+
+ IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, "
+ "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X",
+ (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3SCOESCO_POS,
+ (BT_UART_MSG_FRAME3SNIFF_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3SNIFF_POS,
+ (BT_UART_MSG_FRAME3A2DP_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3A2DP_POS,
+ (BT_UART_MSG_FRAME3ACL_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3ACL_POS,
+ (BT_UART_MSG_FRAME3MASTER_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3MASTER_POS,
+ (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3OBEX_POS);
+
+ IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X",
+ (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >>
+ BT_UART_MSG_FRAME4IDLEDURATION_POS);
+
+ IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, "
+ "eSCO Retransmissions = 0x%X",
+ (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >>
+ BT_UART_MSG_FRAME5TXACTIVITY_POS,
+ (BT_UART_MSG_FRAME5RXACTIVITY_MSK & uart_msg->frame5) >>
+ BT_UART_MSG_FRAME5RXACTIVITY_POS,
+ (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >>
+ BT_UART_MSG_FRAME5ESCORETRANSMIT_POS);
+
+ IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X",
+ (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >>
+ BT_UART_MSG_FRAME6SNIFFINTERVAL_POS,
+ (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >>
+ BT_UART_MSG_FRAME6DISCOVERABLE_POS);
+
+ IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Inquiry/Page SR Mode = "
+ "0x%X, Connectable = 0x%X",
+ (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >>
+ BT_UART_MSG_FRAME7SNIFFACTIVITY_POS,
+ (BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK & uart_msg->frame7) >>
+ BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS,
+ (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >>
+ BT_UART_MSG_FRAME7CONNECTABLE_POS);
+}
+
+static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv,
+ struct iwl_bt_uart_msg *uart_msg)
+{
+ u8 kill_ack_msk;
+ __le32 bt_kill_ack_msg[2] = {
+ cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) };
+
+ kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK |
+ BT_UART_MSG_FRAME3SNIFF_MSK |
+ BT_UART_MSG_FRAME3SCOESCO_MSK) &
+ uart_msg->frame3) == 0) ? 1 : 0;
+ if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) {
+ priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK;
+ priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk];
+ /* schedule to send runtime bt_config */
+ queue_work(priv->workqueue, &priv->bt_runtime_config);
+ }
+
+}
+
+void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ unsigned long flags;
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
+ struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
+ struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
+ u8 last_traffic_load;
+
+ IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
+ IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status);
+ IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load);
+ IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n",
+ coex->bt_ci_compliance);
+ iwlagn_print_uartmsg(priv, uart_msg);
+
+ last_traffic_load = priv->notif_bt_traffic_load;
+ priv->notif_bt_traffic_load = coex->bt_traffic_load;
+ if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
+ if (priv->bt_status != coex->bt_status ||
+ last_traffic_load != coex->bt_traffic_load) {
+ if (coex->bt_status) {
+ /* BT on */
+ if (!priv->bt_ch_announce)
+ priv->bt_traffic_load =
+ IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
+ else
+ priv->bt_traffic_load =
+ coex->bt_traffic_load;
+ } else {
+ /* BT off */
+ priv->bt_traffic_load =
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE;
+ }
+ priv->bt_status = coex->bt_status;
+ queue_work(priv->workqueue,
+ &priv->bt_traffic_change_work);
+ }
+ if (priv->bt_sco_active !=
+ (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) {
+ priv->bt_sco_active = uart_msg->frame3 &
+ BT_UART_MSG_FRAME3SCOESCO_MSK;
+ if (priv->bt_sco_active)
+ sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE;
+ iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO,
+ sizeof(sco_cmd), &sco_cmd, NULL);
+ }
+ }
+
+ iwlagn_set_kill_ack_msk(priv, uart_msg);
+
+ /* FIXME: based on notification, adjust the prio_boost */
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->bt_ci_compliance = coex->bt_ci_compliance;
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv)
+{
+ iwlagn_rx_handler_setup(priv);
+ priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] =
+ iwlagn_bt_coex_profile_notif;
+}
+
+void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv)
+{
+ iwlagn_setup_deferred_work(priv);
+
+ INIT_WORK(&priv->bt_traffic_change_work,
+ iwlagn_bt_traffic_change_work);
+}
+
+void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv)
+{
+ cancel_work_sync(&priv->bt_traffic_change_work);
+}
+
+static bool is_single_rx_stream(struct iwl_priv *priv)
+{
+ return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
+ priv->current_ht_config.single_chain_sufficient;
+}
+
+#define IWL_NUM_RX_CHAINS_MULTIPLE 3
+#define IWL_NUM_RX_CHAINS_SINGLE 2
+#define IWL_NUM_IDLE_CHAINS_DUAL 2
+#define IWL_NUM_IDLE_CHAINS_SINGLE 1
+
+/*
+ * Determine how many receiver/antenna chains to use.
+ *
+ * More provides better reception via diversity. Fewer saves power
+ * at the expense of throughput, but only when not in powersave to
+ * start with.
+ *
+ * MIMO (dual stream) requires at least 2, but works better with 3.
+ * This does not determine *which* chains to use, just how many.
+ */
+static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
+{
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist &&
+ (priv->bt_full_concurrent ||
+ priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
+ /*
+ * only use chain 'A' in bt high traffic load or
+ * full concurrency mode
+ */
+ return IWL_NUM_RX_CHAINS_SINGLE;
+ }
+ /* # of Rx chains to use when expecting MIMO. */
+ if (is_single_rx_stream(priv))
+ return IWL_NUM_RX_CHAINS_SINGLE;
+ else
+ return IWL_NUM_RX_CHAINS_MULTIPLE;
+}
+
+/*
+ * When we are in power saving mode, unless device support spatial
+ * multiplexing power save, use the active count for rx chain count.
+ */
+static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
+{
+ /* # Rx chains when idling, depending on SMPS mode */
+ switch (priv->current_ht_config.smps) {
+ case IEEE80211_SMPS_STATIC:
+ case IEEE80211_SMPS_DYNAMIC:
+ return IWL_NUM_IDLE_CHAINS_SINGLE;
+ case IEEE80211_SMPS_OFF:
+ return active_cnt;
+ default:
+ WARN(1, "invalid SMPS mode %d",
+ priv->current_ht_config.smps);
+ return active_cnt;
+ }
+}
+
+/* up to 4 chains */
+static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
+{
+ u8 res;
+ res = (chain_bitmap & BIT(0)) >> 0;
+ res += (chain_bitmap & BIT(1)) >> 1;
+ res += (chain_bitmap & BIT(2)) >> 2;
+ res += (chain_bitmap & BIT(3)) >> 3;
+ return res;
+}
+
+/**
+ * iwlagn_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
+ *
+ * Selects how many and which Rx receivers/antennas/chains to use.
+ * This should not be used for scan command ... it puts data in wrong place.
+ */
+void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+ bool is_single = is_single_rx_stream(priv);
+ bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
+ u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
+ u32 active_chains;
+ u16 rx_chain;
+
+ /* Tell uCode which antennas are actually connected.
+ * Before first association, we assume all antennas are connected.
+ * Just after first association, iwl_chain_noise_calibration()
+ * checks which antennas actually *are* connected. */
+ if (priv->chain_noise_data.active_chains)
+ active_chains = priv->chain_noise_data.active_chains;
+ else
+ active_chains = priv->hw_params.valid_rx_ant;
+
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist &&
+ (priv->bt_full_concurrent ||
+ priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
+ /*
+ * only use chain 'A' in bt high traffic load or
+ * full concurrency mode
+ */
+ active_chains = first_antenna(active_chains);
+ }
+
+ rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
+
+ /* How many receivers should we use? */
+ active_rx_cnt = iwl_get_active_rx_chain_count(priv);
+ idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
+
+
+ /* correct rx chain count according hw settings
+ * and chain noise calibration
+ */
+ valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
+ if (valid_rx_cnt < active_rx_cnt)
+ active_rx_cnt = valid_rx_cnt;
+
+ if (valid_rx_cnt < idle_rx_cnt)
+ idle_rx_cnt = valid_rx_cnt;
+
+ rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
+ rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
+
+ ctx->staging.rx_chain = cpu_to_le16(rx_chain);
+
+ if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
+ ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
+ else
+ ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
+
+ IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
+ ctx->staging.rx_chain,
+ active_rx_cnt, idle_rx_cnt);
+
+ WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
+ active_rx_cnt < idle_rx_cnt);
+}
+
+u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
+{
+ int i;
+ u8 ind = ant;
+
+ if (priv->band == IEEE80211_BAND_2GHZ &&
+ priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
+ return 0;
+
+ for (i = 0; i < RATE_ANT_NUM - 1; i++) {
+ ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0;
+ if (valid & BIT(ind))
+ return ind;
+ }
+ return ant;
+}
+
+static const char *get_csr_string(int cmd)
+{
+ switch (cmd) {
+ IWL_CMD(CSR_HW_IF_CONFIG_REG);
+ IWL_CMD(CSR_INT_COALESCING);
+ IWL_CMD(CSR_INT);
+ IWL_CMD(CSR_INT_MASK);
+ IWL_CMD(CSR_FH_INT_STATUS);
+ IWL_CMD(CSR_GPIO_IN);
+ IWL_CMD(CSR_RESET);
+ IWL_CMD(CSR_GP_CNTRL);
+ IWL_CMD(CSR_HW_REV);
+ IWL_CMD(CSR_EEPROM_REG);
+ IWL_CMD(CSR_EEPROM_GP);
+ IWL_CMD(CSR_OTP_GP_REG);
+ IWL_CMD(CSR_GIO_REG);
+ IWL_CMD(CSR_GP_UCODE_REG);
+ IWL_CMD(CSR_GP_DRIVER_REG);
+ IWL_CMD(CSR_UCODE_DRV_GP1);
+ IWL_CMD(CSR_UCODE_DRV_GP2);
+ IWL_CMD(CSR_LED_REG);
+ IWL_CMD(CSR_DRAM_INT_TBL_REG);
+ IWL_CMD(CSR_GIO_CHICKEN_BITS);
+ IWL_CMD(CSR_ANA_PLL_CFG);
+ IWL_CMD(CSR_HW_REV_WA_REG);
+ IWL_CMD(CSR_DBG_HPET_MEM_REG);
+ default:
+ return "UNKNOWN";
+ }
+}
+
+void iwl_dump_csr(struct iwl_priv *priv)
+{
+ int i;
+ u32 csr_tbl[] = {
+ CSR_HW_IF_CONFIG_REG,
+ CSR_INT_COALESCING,
+ CSR_INT,
+ CSR_INT_MASK,
+ CSR_FH_INT_STATUS,
+ CSR_GPIO_IN,
+ CSR_RESET,
+ CSR_GP_CNTRL,
+ CSR_HW_REV,
+ CSR_EEPROM_REG,
+ CSR_EEPROM_GP,
+ CSR_OTP_GP_REG,
+ CSR_GIO_REG,
+ CSR_GP_UCODE_REG,
+ CSR_GP_DRIVER_REG,
+ CSR_UCODE_DRV_GP1,
+ CSR_UCODE_DRV_GP2,
+ CSR_LED_REG,
+ CSR_DRAM_INT_TBL_REG,
+ CSR_GIO_CHICKEN_BITS,
+ CSR_ANA_PLL_CFG,
+ CSR_HW_REV_WA_REG,
+ CSR_DBG_HPET_MEM_REG
+ };
+ IWL_ERR(priv, "CSR values:\n");
+ IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
+ "CSR_INT_PERIODIC_REG)\n");
+ for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
+ IWL_ERR(priv, " %25s: 0X%08x\n",
+ get_csr_string(csr_tbl[i]),
+ iwl_read32(priv, csr_tbl[i]));
+ }
+}
+
+static const char *get_fh_string(int cmd)
+{
+ switch (cmd) {
+ IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
+ IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
+ IWL_CMD(FH_RSCSR_CHNL0_WPTR);
+ IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
+ IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
+ IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
+ IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
+ IWL_CMD(FH_TSSR_TX_STATUS_REG);
+ IWL_CMD(FH_TSSR_TX_ERROR_REG);
+ default:
+ return "UNKNOWN";
+ }
+}
+
+int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
+{
+ int i;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ int pos = 0;
+ size_t bufsz = 0;
+#endif
+ u32 fh_tbl[] = {
+ FH_RSCSR_CHNL0_STTS_WPTR_REG,
+ FH_RSCSR_CHNL0_RBDCB_BASE_REG,
+ FH_RSCSR_CHNL0_WPTR,
+ FH_MEM_RCSR_CHNL0_CONFIG_REG,
+ FH_MEM_RSSR_SHARED_CTRL_REG,
+ FH_MEM_RSSR_RX_STATUS_REG,
+ FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
+ FH_TSSR_TX_STATUS_REG,
+ FH_TSSR_TX_ERROR_REG
+ };
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (display) {
+ bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
+ *buf = kmalloc(bufsz, GFP_KERNEL);
+ if (!*buf)
+ return -ENOMEM;
+ pos += scnprintf(*buf + pos, bufsz - pos,
+ "FH register values:\n");
+ for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
+ pos += scnprintf(*buf + pos, bufsz - pos,
+ " %34s: 0X%08x\n",
+ get_fh_string(fh_tbl[i]),
+ iwl_read_direct32(priv, fh_tbl[i]));
+ }
+ return pos;
+ }
+#endif
+ IWL_ERR(priv, "FH register values:\n");
+ for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
+ IWL_ERR(priv, " %34s: 0X%08x\n",
+ get_fh_string(fh_tbl[i]),
+ iwl_read_direct32(priv, fh_tbl[i]));
+ }
+ return 0;
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index a4378ba31ef6..065553629de5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -39,6 +39,7 @@
#include "iwl-dev.h"
#include "iwl-sta.h"
#include "iwl-core.h"
+#include "iwl-agn.h"
#define RS_NAME "iwl-agn-rs"
@@ -76,12 +77,81 @@ static const u8 ant_toggle_lookup[] = {
/*ANT_ABC -> */ ANT_ABC,
};
+#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
+ [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
+ IWL_RATE_SISO_##s##M_PLCP, \
+ IWL_RATE_MIMO2_##s##M_PLCP,\
+ IWL_RATE_MIMO3_##s##M_PLCP,\
+ IWL_RATE_##r##M_IEEE, \
+ IWL_RATE_##ip##M_INDEX, \
+ IWL_RATE_##in##M_INDEX, \
+ IWL_RATE_##rp##M_INDEX, \
+ IWL_RATE_##rn##M_INDEX, \
+ IWL_RATE_##pp##M_INDEX, \
+ IWL_RATE_##np##M_INDEX }
+
+/*
+ * Parameter order:
+ * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
+ *
+ * If there isn't a valid next or previous rate then INV is used which
+ * maps to IWL_RATE_INVALID
+ *
+ */
+const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
+ IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */
+ IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */
+ IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */
+ IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */
+ IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */
+ IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */
+ IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */
+ IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */
+ IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */
+ IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */
+ IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */
+ IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
+ IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
+ /* FIXME:RS: ^^ should be INV (legacy) */
+};
+
+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);
+
+ if (idx >= IWL_RATE_MIMO3_6M_PLCP)
+ idx = idx - IWL_RATE_MIMO3_6M_PLCP;
+ else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
+ idx = idx - IWL_RATE_MIMO2_6M_PLCP;
+
+ idx += IWL_FIRST_OFDM_RATE;
+ /* skip 9M not supported in ht*/
+ if (idx >= IWL_RATE_9M_INDEX)
+ idx += 1;
+ if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
+ return idx;
+
+ /* 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))
+ return idx;
+ }
+
+ return -1;
+}
+
static void rs_rate_scale_perform(struct iwl_priv *priv,
struct sk_buff *skb,
struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta);
static void rs_fill_link_cmd(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
+static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
#ifdef CONFIG_MAC80211_DEBUGFS
@@ -300,7 +370,19 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
struct ieee80211_sta *sta)
{
int ret = -EAGAIN;
- u32 load = rs_tl_get_load(lq_data, tid);
+ u32 load;
+
+ /*
+ * Don't create TX aggregation sessions when in high
+ * BT traffic, as they would just be disrupted by BT.
+ */
+ if (priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) {
+ IWL_ERR(priv, "BT traffic (%d), no aggregation allowed\n",
+ priv->bt_traffic_load);
+ return ret;
+ }
+
+ load = rs_tl_get_load(lq_data, tid);
if (load > IWL_AGG_LOAD_THRESHOLD) {
IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
@@ -502,6 +584,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
u8 mcs;
+ memset(tbl, 0, sizeof(struct iwl_scale_tbl_info));
*rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
if (*rate_idx == IWL_RATE_INVALID) {
@@ -588,11 +671,13 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
* Green-field mode is valid if the station supports it and
* there are no non-GF stations present in the BSS.
*/
-static inline u8 rs_use_green(struct ieee80211_sta *sta,
- struct iwl_ht_config *ht_conf)
+static bool rs_use_green(struct ieee80211_sta *sta)
{
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+
return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
- !(ht_conf->non_GF_STA_present);
+ !(ctx->ht.non_gf_sta_present);
}
/**
@@ -744,6 +829,32 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
(a->is_SGI == b->is_SGI);
}
+static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ struct iwl_lq_sta *lq_sta)
+{
+ struct iwl_scale_tbl_info *tbl;
+ bool full_concurrent;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
+ full_concurrent = true;
+ else
+ full_concurrent = false;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (priv->bt_full_concurrent != full_concurrent) {
+ priv->bt_full_concurrent = full_concurrent;
+
+ /* Update uCode's rate table. */
+ tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+ rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
+ iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
+
+ queue_work(priv->workqueue, &priv->bt_full_concurrency);
+ }
+}
+
/*
* mac80211 sends us Tx status
*/
@@ -763,6 +874,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
u32 tx_rate;
struct iwl_scale_tbl_info tbl_type;
struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
@@ -829,7 +942,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->missed_rate_counter++;
if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
lq_sta->missed_rate_counter = 0;
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
+ iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
}
/* Regardless, ignore this status info for outdated rate */
return;
@@ -848,7 +961,20 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
} else {
IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
- return;
+ tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+ IWL_DEBUG_RATE(priv, "active- lq:%x, ant:%x, SGI:%d\n",
+ tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI);
+ tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
+ IWL_DEBUG_RATE(priv, "search- lq:%x, ant:%x, SGI:%d\n",
+ tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI);
+ IWL_DEBUG_RATE(priv, "actual- lq:%x, ant:%x, SGI:%d\n",
+ tbl_type.lq_type, tbl_type.ant_type, tbl_type.is_SGI);
+ /*
+ * no matching table found, let's by-pass the data collection
+ * and continue to perform rate scale to find the rate table
+ */
+ rs_stay_in_table(lq_sta, true);
+ goto done;
}
/*
@@ -909,10 +1035,14 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
}
/* The last TX rate is cached in lq_sta; it's set in if/else above */
lq_sta->last_rate_n_flags = tx_rate;
-
+done:
/* See if there's a better rate or modulation mode to try. */
if (sta && sta->supp_rates[sband->band])
rs_rate_scale_perform(priv, skb, sta, lq_sta);
+
+ /* Is there a need to switch between full concurrency and 3-wire? */
+ if (priv->bt_ant_couple_ok)
+ rs_bt_update_lq(priv, ctx, lq_sta);
}
/*
@@ -1106,6 +1236,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
u16 rate_mask;
s32 rate;
s8 is_green = lq_sta->is_green;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
@@ -1126,7 +1258,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
tbl->max_search = IWL_MAX_SEARCH;
rate_mask = lq_sta->active_mimo2_rate;
- if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
+ if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
tbl->is_ht40 = 1;
else
tbl->is_ht40 = 0;
@@ -1160,6 +1292,8 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
u16 rate_mask;
s32 rate;
s8 is_green = lq_sta->is_green;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
@@ -1180,7 +1314,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
rate_mask = lq_sta->active_mimo3_rate;
- if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
+ if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
tbl->is_ht40 = 1;
else
tbl->is_ht40 = 0;
@@ -1215,6 +1349,8 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
u16 rate_mask;
u8 is_green = lq_sta->is_green;
s32 rate;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
@@ -1227,7 +1363,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
tbl->max_search = IWL_MAX_SEARCH;
rate_mask = lq_sta->active_siso_rate;
- if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
+ if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
tbl->is_ht40 = 1;
else
tbl->is_ht40 = 0;
@@ -1265,18 +1401,52 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
struct iwl_rate_scale_data *window = &(tbl->win[index]);
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
- u8 start_action = tbl->action;
+ u8 start_action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret = 0;
u8 update_search_tbl_counter = 0;
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2)
+ tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 &&
+ tbl->action != IWL_LEGACY_SWITCH_SISO)
+ tbl->action = IWL_LEGACY_SWITCH_SISO;
+ break;
+ default:
+ IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
+ break;
+ }
+
if (!iwl_ht_enabled(priv))
/* stay in Legacy */
tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
tbl->action > IWL_LEGACY_SWITCH_SISO)
tbl->action = IWL_LEGACY_SWITCH_SISO;
+
+ /* configure as 1x1 if bt full concurrency */
+ if (priv->bt_full_concurrent) {
+ if (!iwl_ht_enabled(priv))
+ tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
+ else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
+ tbl->action = IWL_LEGACY_SWITCH_SISO;
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ }
+
+ start_action = tbl->action;
for (; ;) {
lq_sta->action_counter++;
switch (tbl->action) {
@@ -1291,7 +1461,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
break;
/* Don't change antenna if success has been great */
- if (window->success_ratio >= IWL_RS_GOOD_RATIO)
+ if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
+ !priv->bt_full_concurrent &&
+ priv->bt_traffic_load ==
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE)
break;
/* Set up search table to try other antenna */
@@ -1403,31 +1576,64 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
- u8 start_action = tbl->action;
+ u8 start_action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
u8 update_search_tbl_counter = 0;
int ret;
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
+ tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
+ tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+ break;
+ default:
+ IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
+ break;
+ }
+
if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
tbl->action > IWL_SISO_SWITCH_ANTENNA2) {
/* stay in SISO */
tbl->action = IWL_SISO_SWITCH_ANTENNA1;
}
+
+ /* configure as 1x1 if bt full concurrency */
+ if (priv->bt_full_concurrent) {
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
+ tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+ }
+
+ start_action = tbl->action;
for (;;) {
lq_sta->action_counter++;
switch (tbl->action) {
case IWL_SISO_SWITCH_ANTENNA1:
case IWL_SISO_SWITCH_ANTENNA2:
IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");
-
if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
- tx_chains_num <= 1) ||
+ tx_chains_num <= 1) ||
(tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
- tx_chains_num <= 2))
+ tx_chains_num <= 2))
break;
- if (window->success_ratio >= IWL_RS_GOOD_RATIO)
+ if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
+ !priv->bt_full_concurrent &&
+ priv->bt_traffic_load ==
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE)
break;
memcpy(search_tbl, tbl, sz);
@@ -1541,18 +1747,47 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
- u8 start_action = tbl->action;
+ u8 start_action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
u8 update_search_tbl_counter = 0;
int ret;
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)
+ tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ if (tbl->action == IWL_MIMO2_SWITCH_SISO_B ||
+ tbl->action == IWL_MIMO2_SWITCH_SISO_C)
+ tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+ break;
+ default:
+ IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
+ break;
+ }
+
if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
(tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
tbl->action > IWL_MIMO2_SWITCH_SISO_C)) {
/* switch in SISO */
tbl->action = IWL_MIMO2_SWITCH_SISO_A;
}
+
+ /* configure as 1x1 if bt full concurrency */
+ if (priv->bt_full_concurrent &&
+ (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
+ tbl->action > IWL_MIMO2_SWITCH_SISO_C))
+ tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+
+ start_action = tbl->action;
for (;;) {
lq_sta->action_counter++;
switch (tbl->action) {
@@ -1682,18 +1917,47 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
- u8 start_action = tbl->action;
+ u8 start_action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret;
u8 update_search_tbl_counter = 0;
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)
+ tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||
+ tbl->action == IWL_MIMO3_SWITCH_SISO_C)
+ tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+ break;
+ default:
+ IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
+ break;
+ }
+
if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
(tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
tbl->action > IWL_MIMO3_SWITCH_SISO_C)) {
/* switch in SISO */
tbl->action = IWL_MIMO3_SWITCH_SISO_A;
}
+
+ /* configure as 1x1 if bt full concurrency */
+ if (priv->bt_full_concurrent &&
+ (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
+ tbl->action > IWL_MIMO3_SWITCH_SISO_C))
+ tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+
+ start_action = tbl->action;
for (;;) {
lq_sta->action_counter++;
switch (tbl->action) {
@@ -1820,7 +2084,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
* 2) # times calling this function
* 3) elapsed time in this mode (not used, for now)
*/
-static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
+static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
{
struct iwl_scale_tbl_info *tbl;
int i;
@@ -1851,7 +2115,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
* allow a new search. Also (below) reset all bitmaps and
* stats in active history.
*/
- if ((lq_sta->total_failed > lq_sta->max_failure_limit) ||
+ if (force_search ||
+ (lq_sta->total_failed > lq_sta->max_failure_limit) ||
(lq_sta->total_success > lq_sta->max_success_limit) ||
((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
&& (flush_interval_passed))) {
@@ -1900,6 +2165,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
* return rate_n_flags as used in the table
*/
static u32 rs_update_rate_tbl(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
struct iwl_lq_sta *lq_sta,
struct iwl_scale_tbl_info *tbl,
int index, u8 is_green)
@@ -1909,7 +2175,7 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv,
/* Update uCode's rate table. */
rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
rs_fill_link_cmd(priv, lq_sta, rate);
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
+ iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
return rate;
}
@@ -1948,6 +2214,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
s32 sr;
u8 tid = MAX_TID_COUNT;
struct iwl_tid_data *tid_data;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
@@ -1986,7 +2254,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (is_legacy(tbl->lq_type))
lq_sta->is_green = 0;
else
- lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
+ lq_sta->is_green = rs_use_green(sta);
is_green = lq_sta->is_green;
/* current tx rate */
@@ -2025,7 +2293,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
/* get "active" rate info */
index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
- rate = rs_update_rate_tbl(priv, lq_sta,
+ rate = rs_update_rate_tbl(priv, ctx, lq_sta,
tbl, index, is_green);
}
return;
@@ -2067,7 +2335,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* Should we stay with this modulation mode,
* or search for a new one? */
- rs_stay_in_table(lq_sta);
+ rs_stay_in_table(lq_sta, false);
goto out;
}
@@ -2215,6 +2483,28 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI &&
(is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))
scale_action = -1;
+
+ if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
+ (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
+ if (lq_sta->last_bt_traffic > priv->bt_traffic_load) {
+ /*
+ * don't set scale_action, don't want to scale up if
+ * the rate scale doesn't otherwise think that is a
+ * good idea.
+ */
+ } else if (lq_sta->last_bt_traffic <= priv->bt_traffic_load) {
+ scale_action = -1;
+ }
+ }
+ lq_sta->last_bt_traffic = priv->bt_traffic_load;
+
+ if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
+ (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
+ /* search for a new modulation */
+ rs_stay_in_table(lq_sta, true);
+ goto lq_update;
+ }
+
switch (scale_action) {
case -1:
/* Decrease starting rate, update uCode's rate table */
@@ -2245,13 +2535,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
lq_update:
/* Replace uCode's rate table for the destination station. */
if (update_lq)
- rate = rs_update_rate_tbl(priv, lq_sta,
+ rate = rs_update_rate_tbl(priv, ctx, lq_sta,
tbl, index, is_green);
if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {
/* Should we stay with this modulation mode,
* or search for a new one? */
- rs_stay_in_table(lq_sta);
+ rs_stay_in_table(lq_sta, false);
}
/*
* Search for new modulation mode if we're:
@@ -2287,7 +2577,7 @@ lq_update:
IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",
tbl->current_rate, index);
rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
+ iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
} else
done_search = 1;
}
@@ -2357,12 +2647,17 @@ static void rs_initialize_lq(struct iwl_priv *priv,
int rate_idx;
int i;
u32 rate;
- u8 use_green = rs_use_green(sta, &priv->current_ht_config);
+ u8 use_green = rs_use_green(sta);
u8 active_tbl = 0;
u8 valid_tx_ant;
+ struct iwl_station_priv *sta_priv;
+ struct iwl_rxon_context *ctx;
if (!sta || !lq_sta)
- goto out;
+ return;
+
+ sta_priv = (void *)sta->drv_priv;
+ ctx = sta_priv->common.ctx;
i = lq_sta->last_txrate_idx;
@@ -2394,9 +2689,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
rs_set_expected_tpt_table(lq_sta, tbl);
rs_fill_link_cmd(NULL, lq_sta, rate);
priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_SYNC, true);
- out:
- return;
+ iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_SYNC, true);
}
static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
@@ -2524,7 +2817,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
lq_sta->is_dup = 0;
lq_sta->max_rate_idx = -1;
lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
- lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
+ lq_sta->is_green = rs_use_green(sta);
lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
lq_sta->band = priv->band;
/*
@@ -2594,10 +2887,15 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
/* Interpret new_rate (rate_n_flags) */
- memset(&tbl_type, 0, sizeof(tbl_type));
rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
&tbl_type, &rate_idx);
+ if (priv && priv->bt_full_concurrent) {
+ /* 1x1 only */
+ tbl_type.ant_type =
+ first_antenna(priv->hw_params.valid_tx_ant);
+ }
+
/* How many times should we repeat the initial rate? */
if (is_legacy(tbl_type.lq_type)) {
ant_toggle_cnt = 1;
@@ -2622,9 +2920,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
index++;
repeat_rate--;
-
- if (priv)
- valid_tx_ant = priv->hw_params.valid_tx_ant;
+ if (priv) {
+ if (priv->bt_full_concurrent)
+ valid_tx_ant = ANT_A;
+ else
+ valid_tx_ant = priv->hw_params.valid_tx_ant;
+ }
/* Fill rest of rate table */
while (index < LINK_QUAL_MAX_RETRY_NUM) {
@@ -2639,7 +2940,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
rs_toggle_antenna(valid_tx_ant,
&new_rate, &tbl_type))
ant_toggle_cnt = 1;
-}
+ }
/* Override next rate if needed for debug purposes */
rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
@@ -2654,6 +2955,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
&rate_idx);
+ if (priv && priv->bt_full_concurrent) {
+ /* 1x1 only */
+ tbl_type.ant_type =
+ first_antenna(priv->hw_params.valid_tx_ant);
+ }
+
/* Indicate to uCode which entries might be MIMO.
* If initial rate was MIMO, this will finally end up
* as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
@@ -2694,8 +3001,21 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+
lq_cmd->agg_params.agg_time_limit =
cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
+ /*
+ * overwrite if needed, pass aggregation time limit
+ * to uCode in uSec
+ */
+ if (priv && priv->cfg->bt_params &&
+ priv->cfg->bt_params->agg_time_limit &&
+ priv->cfg->bt_params->agg_time_limit >=
+ LINK_QUAL_AGG_TIME_LIMIT_MIN &&
+ priv->cfg->bt_params->agg_time_limit <=
+ LINK_QUAL_AGG_TIME_LIMIT_MAX)
+ lq_cmd->agg_params.agg_time_limit =
+ cpu_to_le16(priv->cfg->bt_params->agg_time_limit);
}
static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -2760,6 +3080,9 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
char buf[64];
int buf_size;
u32 parsed_rate;
+ struct iwl_station_priv *sta_priv =
+ container_of(lq_sta, struct iwl_station_priv, lq_sta);
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
priv = lq_sta->drv;
memset(buf, 0, sizeof(buf));
@@ -2782,7 +3105,8 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
if (lq_sta->dbg_fixed_rate) {
rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
- iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
+ iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,
+ false);
}
return count;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 8292f6d48ec6..75e50d33ecb3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -299,7 +299,6 @@ enum {
#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
-extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
enum iwl_table_type {
LQ_NONE,
@@ -432,6 +431,8 @@ struct iwl_lq_sta {
u32 last_rate_n_flags;
/* packets destined for this STA are aggregated */
u8 is_agg;
+ /* BT traffic this sta was last updated in */
+ u8 last_bt_traffic;
};
static inline u8 num_of_ant(u8 mask)
@@ -451,24 +452,6 @@ static inline u8 first_antenna(u8 mask)
}
-static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
-{
- u8 rate = iwl_rates[rate_index].prev_ieee;
-
- if (rate == IWL_RATE_INVALID)
- rate = rate_index;
- return rate;
-}
-
-static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
-{
- u8 rate = iwl3945_rates[rate_index].prev_ieee;
-
- if (rate == IWL_RATE_INVALID)
- rate = rate_index;
- return rate;
-}
-
/**
* iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index 9490eced1198..bbd40b7dd597 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -34,7 +34,7 @@
#include "iwl-dev.h"
#include "iwl-core.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
#include "iwl-sta.h"
#include "iwl-io.h"
#include "iwl-helpers.h"
@@ -73,7 +73,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 (priv->cfg->bt_statistics)
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics)
rx_info = &(priv->_agn.statistics_bt.rx.general.common);
else
rx_info = &(priv->_agn.statistics.rx.general);
@@ -124,7 +125,8 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
struct statistics_general_common *general, *accum_general;
struct statistics_tx *tx, *accum_tx;
- if (priv->cfg->bt_statistics) {
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics) {
prev_stats = (__le32 *)&priv->_agn.statistics_bt;
accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
size = sizeof(struct iwl_bt_notif_statistics);
@@ -183,7 +185,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
unsigned int plcp_msec;
unsigned long plcp_received_jiffies;
- if (priv->cfg->plcp_delta_threshold ==
+ if (priv->cfg->base_params->plcp_delta_threshold ==
IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
return rc;
@@ -205,7 +207,8 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
struct statistics_rx_phy *ofdm;
struct statistics_rx_ht_phy *ofdm_ht;
- if (priv->cfg->bt_statistics) {
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics) {
ofdm = &pkt->u.stats_bt.rx.ofdm;
ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
combined_plcp_delta =
@@ -229,7 +232,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
if ((combined_plcp_delta > 0) &&
((combined_plcp_delta * 100) / plcp_msec) >
- priv->cfg->plcp_delta_threshold) {
+ priv->cfg->base_params->plcp_delta_threshold) {
/*
* if plcp_err exceed the threshold,
* the following data is printed in csv format:
@@ -242,13 +245,13 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
* plcp_msec
*/
IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
- "%u, %u, %u, %u, %d, %u mSecs\n",
- priv->cfg->plcp_delta_threshold,
- le32_to_cpu(ofdm->plcp_err),
- le32_to_cpu(ofdm->plcp_err),
- le32_to_cpu(ofdm_ht->plcp_err),
- le32_to_cpu(ofdm_ht->plcp_err),
- combined_plcp_delta, plcp_msec);
+ "%u, %u, %u, %u, %d, %u mSecs\n",
+ priv->cfg->base_params->plcp_delta_threshold,
+ le32_to_cpu(ofdm->plcp_err),
+ le32_to_cpu(ofdm->plcp_err),
+ le32_to_cpu(ofdm_ht->plcp_err),
+ le32_to_cpu(ofdm_ht->plcp_err),
+ combined_plcp_delta, plcp_msec);
rc = false;
}
@@ -262,7 +265,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
int change;
struct iwl_rx_packet *pkt = rxb_addr(rxb);
- if (priv->cfg->bt_statistics) {
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics) {
IWL_DEBUG_RX(priv,
"Statistics notification received (%d vs %d).\n",
(int)sizeof(struct iwl_bt_notif_statistics),
@@ -300,7 +304,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
iwl_recover_from_statistics(priv, pkt);
- if (priv->cfg->bt_statistics)
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics)
memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
sizeof(priv->_agn.statistics_bt));
else
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
new file mode 100644
index 000000000000..35a30d2e0734
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -0,0 +1,716 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <net/mac80211.h>
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-sta.h"
+#include "iwl-agn.h"
+
+static struct iwl_link_quality_cmd *
+iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id)
+{
+ int i, r;
+ struct iwl_link_quality_cmd *link_cmd;
+ u32 rate_flags = 0;
+ __le32 rate_n_flags;
+
+ link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
+ if (!link_cmd) {
+ IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
+ return NULL;
+ }
+ /* Set up the rate scaling to start at selected rate, fall back
+ * all the way down to 1M in IEEE order, and then spin on 1M */
+ if (priv->band == IEEE80211_BAND_5GHZ)
+ r = IWL_RATE_6M_INDEX;
+ else
+ r = IWL_RATE_1M_INDEX;
+
+ if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
+ rate_flags |= RATE_MCS_CCK_MSK;
+
+ rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
+ RATE_MCS_ANT_POS;
+ rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
+ for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
+ link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
+
+ link_cmd->general_params.single_stream_ant_msk =
+ first_antenna(priv->hw_params.valid_tx_ant);
+
+ link_cmd->general_params.dual_stream_ant_msk =
+ priv->hw_params.valid_tx_ant &
+ ~first_antenna(priv->hw_params.valid_tx_ant);
+ if (!link_cmd->general_params.dual_stream_ant_msk) {
+ link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
+ } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
+ link_cmd->general_params.dual_stream_ant_msk =
+ priv->hw_params.valid_tx_ant;
+ }
+
+ link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+ link_cmd->agg_params.agg_time_limit =
+ cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
+
+ link_cmd->sta_id = sta_id;
+
+ return link_cmd;
+}
+
+/*
+ * iwlagn_add_bssid_station - Add the special IBSS BSSID station
+ *
+ * Function sleeps.
+ */
+int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, u8 *sta_id_r)
+{
+ int ret;
+ u8 sta_id;
+ struct iwl_link_quality_cmd *link_cmd;
+ unsigned long flags;
+
+ if (sta_id_r)
+ *sta_id_r = IWL_INVALID_STATION;
+
+ ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
+ if (ret) {
+ IWL_ERR(priv, "Unable to add station %pM\n", addr);
+ return ret;
+ }
+
+ if (sta_id_r)
+ *sta_id_r = sta_id;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].used |= IWL_STA_LOCAL;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ /* Set up default rate scaling table in device's station table */
+ link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+ if (!link_cmd) {
+ IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
+ addr);
+ return -ENOMEM;
+ }
+
+ ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true);
+ if (ret)
+ IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].lq = link_cmd;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return 0;
+}
+
+static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ bool send_if_empty)
+{
+ int i, not_empty = 0;
+ u8 buff[sizeof(struct iwl_wep_cmd) +
+ sizeof(struct iwl_wep_key) * WEP_KEYS_MAX];
+ struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
+ size_t cmd_size = sizeof(struct iwl_wep_cmd);
+ struct iwl_host_cmd cmd = {
+ .id = ctx->wep_key_cmd,
+ .data = wep_cmd,
+ .flags = CMD_SYNC,
+ };
+
+ might_sleep();
+
+ memset(wep_cmd, 0, cmd_size +
+ (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));
+
+ for (i = 0; i < WEP_KEYS_MAX ; i++) {
+ wep_cmd->key[i].key_index = i;
+ if (ctx->wep_keys[i].key_size) {
+ wep_cmd->key[i].key_offset = i;
+ not_empty = 1;
+ } else {
+ wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
+ }
+
+ wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
+ memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
+ ctx->wep_keys[i].key_size);
+ }
+
+ wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
+ wep_cmd->num_keys = WEP_KEYS_MAX;
+
+ cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;
+
+ cmd.len = cmd_size;
+
+ if (not_empty || send_if_empty)
+ return iwl_send_cmd(priv, &cmd);
+ else
+ return 0;
+}
+
+int iwl_restore_default_wep_keys(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ lockdep_assert_held(&priv->mutex);
+
+ return iwl_send_static_wepkey_cmd(priv, ctx, false);
+}
+
+int iwl_remove_default_wep_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf)
+{
+ int ret;
+
+ lockdep_assert_held(&priv->mutex);
+
+ IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
+ keyconf->keyidx);
+
+ memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
+ /* but keys in device are clear anyway so return success */
+ return 0;
+ }
+ ret = iwl_send_static_wepkey_cmd(priv, ctx, 1);
+ IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
+ keyconf->keyidx, ret);
+
+ return ret;
+}
+
+int iwl_set_default_wep_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf)
+{
+ int ret;
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (keyconf->keylen != WEP_KEY_LEN_128 &&
+ keyconf->keylen != WEP_KEY_LEN_64) {
+ IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
+ return -EINVAL;
+ }
+
+ keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
+ keyconf->hw_key_idx = HW_KEY_DEFAULT;
+ priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
+
+ ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
+ memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
+ keyconf->keylen);
+
+ ret = iwl_send_static_wepkey_cmd(priv, ctx, false);
+ IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
+ keyconf->keylen, keyconf->keyidx, ret);
+
+ return ret;
+}
+
+static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
+{
+ unsigned long flags;
+ __le16 key_flags = 0;
+ struct iwl_addsta_cmd sta_cmd;
+
+ lockdep_assert_held(&priv->mutex);
+
+ keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
+
+ key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
+ key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+ key_flags &= ~STA_KEY_FLG_INVALID;
+
+ if (keyconf->keylen == WEP_KEY_LEN_128)
+ key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
+
+ if (sta_id == ctx->bcast_sta_id)
+ key_flags |= STA_KEY_MULTICAST_MSK;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+
+ priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
+ priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
+ priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
+
+ memcpy(priv->stations[sta_id].keyinfo.key,
+ keyconf->key, keyconf->keylen);
+
+ memcpy(&priv->stations[sta_id].sta.key.key[3],
+ keyconf->key, keyconf->keylen);
+
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ priv->stations[sta_id].sta.key.key_offset =
+ iwl_get_free_ucode_key_index(priv);
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */
+
+ WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+ "no space for a new key");
+
+ priv->stations[sta_id].sta.key.key_flags = key_flags;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+ memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
+{
+ unsigned long flags;
+ __le16 key_flags = 0;
+ struct iwl_addsta_cmd sta_cmd;
+
+ lockdep_assert_held(&priv->mutex);
+
+ key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
+ key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+ key_flags &= ~STA_KEY_FLG_INVALID;
+
+ if (sta_id == ctx->bcast_sta_id)
+ key_flags |= STA_KEY_MULTICAST_MSK;
+
+ keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
+ priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
+
+ memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
+ keyconf->keylen);
+
+ memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
+ keyconf->keylen);
+
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ priv->stations[sta_id].sta.key.key_offset =
+ iwl_get_free_ucode_key_index(priv);
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */
+
+ WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+ "no space for a new key");
+
+ priv->stations[sta_id].sta.key.key_flags = key_flags;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+ memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
+{
+ unsigned long flags;
+ int ret = 0;
+ __le16 key_flags = 0;
+
+ key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
+ key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+ key_flags &= ~STA_KEY_FLG_INVALID;
+
+ if (sta_id == ctx->bcast_sta_id)
+ key_flags |= STA_KEY_MULTICAST_MSK;
+
+ keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+
+ priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
+ priv->stations[sta_id].keyinfo.keylen = 16;
+
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ priv->stations[sta_id].sta.key.key_offset =
+ iwl_get_free_ucode_key_index(priv);
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */
+
+ WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+ "no space for a new key");
+
+ priv->stations[sta_id].sta.key.key_flags = key_flags;
+
+
+ /* This copy is acutally not needed: we get the key with each TX */
+ memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
+
+ memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
+
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return ret;
+}
+
+void iwl_update_tkip_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
+{
+ u8 sta_id;
+ unsigned long flags;
+ int i;
+
+ if (iwl_scan_cancel(priv)) {
+ /* cancel scan failed, just live w/ bad key and rely
+ briefly on SW decryption */
+ return;
+ }
+
+ sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta);
+ if (sta_id == IWL_INVALID_STATION)
+ return;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+
+ priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
+
+ for (i = 0; i < 5; i++)
+ priv->stations[sta_id].sta.key.tkip_rx_ttak[i] =
+ cpu_to_le16(phase1key[i]);
+
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+ iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+}
+
+int iwl_remove_dynamic_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
+{
+ unsigned long flags;
+ u16 key_flags;
+ u8 keyidx;
+ struct iwl_addsta_cmd sta_cmd;
+
+ lockdep_assert_held(&priv->mutex);
+
+ ctx->key_mapping_keys--;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
+ keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
+
+ IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
+ keyconf->keyidx, sta_id);
+
+ if (keyconf->keyidx != keyidx) {
+ /* We need to remove a key with index different that the one
+ * in the uCode. This means that the key we need to remove has
+ * been replaced by another one with different index.
+ * Don't do anything and return ok
+ */
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return 0;
+ }
+
+ if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
+ IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
+ keyconf->keyidx, key_flags);
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return 0;
+ }
+
+ if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
+ &priv->ucode_key_table))
+ IWL_ERR(priv, "index %d not used in uCode key table.\n",
+ priv->stations[sta_id].sta.key.key_offset);
+ memset(&priv->stations[sta_id].keyinfo, 0,
+ sizeof(struct iwl_hw_key));
+ memset(&priv->stations[sta_id].sta.key, 0,
+ sizeof(struct iwl4965_keyinfo));
+ priv->stations[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;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return 0;
+ }
+ memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf, u8 sta_id)
+{
+ int ret;
+
+ lockdep_assert_held(&priv->mutex);
+
+ ctx->key_mapping_keys++;
+ keyconf->hw_key_idx = HW_KEY_DYNAMIC;
+
+ switch (keyconf->cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
+ ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id);
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id);
+ break;
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id);
+ break;
+ default:
+ IWL_ERR(priv,
+ "Unknown alg: %s cipher = %x\n", __func__,
+ keyconf->cipher);
+ ret = -EINVAL;
+ }
+
+ IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n",
+ keyconf->cipher, keyconf->keylen, keyconf->keyidx,
+ sta_id, ret);
+
+ return ret;
+}
+
+/**
+ * iwlagn_alloc_bcast_station - add broadcast station into driver's station table.
+ *
+ * This adds the broadcast station into the driver's station table
+ * and marks it driver active, so that it will be restored to the
+ * device at the next best time.
+ */
+int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ struct iwl_link_quality_cmd *link_cmd;
+ unsigned long flags;
+ u8 sta_id;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Unable to prepare broadcast station\n");
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return -EINVAL;
+ }
+
+ priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
+ priv->stations[sta_id].used |= IWL_STA_BCAST;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+ if (!link_cmd) {
+ IWL_ERR(priv,
+ "Unable to initialize rate scaling for bcast station.\n");
+ return -ENOMEM;
+ }
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].lq = link_cmd;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return 0;
+}
+
+/**
+ * iwl_update_bcast_station - update broadcast station's LQ command
+ *
+ * Only used by iwlagn. Placed here to have all bcast station management
+ * code together.
+ */
+static int iwl_update_bcast_station(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ unsigned long flags;
+ struct iwl_link_quality_cmd *link_cmd;
+ u8 sta_id = ctx->bcast_sta_id;
+
+ link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+ if (!link_cmd) {
+ IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n");
+ return -ENOMEM;
+ }
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ if (priv->stations[sta_id].lq)
+ kfree(priv->stations[sta_id].lq);
+ else
+ IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
+ priv->stations[sta_id].lq = link_cmd;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return 0;
+}
+
+int iwl_update_bcast_stations(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx;
+ int ret = 0;
+
+ for_each_context(priv, ctx) {
+ ret = iwl_update_bcast_station(priv, ctx);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
+ */
+int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
+{
+ unsigned long flags;
+ struct iwl_addsta_cmd sta_cmd;
+
+ lockdep_assert_held(&priv->mutex);
+
+ /* Remove "disable" flag, to enable Tx for this TID */
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
+ priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
+ int tid, u16 ssn)
+{
+ unsigned long flags;
+ int sta_id;
+ struct iwl_addsta_cmd sta_cmd;
+
+ lockdep_assert_held(&priv->mutex);
+
+ sta_id = iwl_sta_id(sta);
+ if (sta_id == IWL_INVALID_STATION)
+ return -ENXIO;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].sta.station_flags_msk = 0;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
+ priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
+ priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
+ int tid)
+{
+ unsigned long flags;
+ int sta_id;
+ struct iwl_addsta_cmd sta_cmd;
+
+ lockdep_assert_held(&priv->mutex);
+
+ sta_id = iwl_sta_id(sta);
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
+ return -ENXIO;
+ }
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].sta.station_flags_msk = 0;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
+ priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
+ priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
+ priv->stations[sta_id].sta.sta.modify_mask = 0;
+ priv->stations[sta_id].sta.sleep_tx_count = 0;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+}
+
+void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
+ priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
+ priv->stations[sta_id].sta.sta.modify_mask =
+ STA_MODIFY_SLEEP_TX_COUNT_MSK;
+ priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
new file mode 100644
index 000000000000..e3a8216a033c
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -0,0 +1,699 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <net/mac80211.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-commands.h"
+#include "iwl-debug.h"
+#include "iwl-agn-tt.h"
+
+/* default Thermal Throttling transaction table
+ * Current state | Throttling Down | Throttling Up
+ *=============================================================================
+ * Condition Nxt State Condition Nxt State Condition Nxt State
+ *-----------------------------------------------------------------------------
+ * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A
+ * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0
+ * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1
+ * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
+ *=============================================================================
+ */
+static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {
+ {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104},
+ {IWL_TI_1, 105, CT_KILL_THRESHOLD - 1},
+ {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
+};
+static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {
+ {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95},
+ {IWL_TI_2, 110, CT_KILL_THRESHOLD - 1},
+ {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
+};
+static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {
+ {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100},
+ {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX},
+ {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
+};
+static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {
+ {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD},
+ {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
+ {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
+};
+
+/* Advance Thermal Throttling default restriction table */
+static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {
+ {IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true },
+ {IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true },
+ {IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false },
+ {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false }
+};
+
+bool iwl_tt_is_low_power_state(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ if (tt->state >= IWL_TI_1)
+ return true;
+ return false;
+}
+
+u8 iwl_tt_current_power_mode(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ return tt->tt_power_mode;
+}
+
+bool iwl_ht_enabled(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ struct iwl_tt_restriction *restriction;
+
+ if (!priv->thermal_throttle.advanced_tt)
+ return true;
+ restriction = tt->restriction + tt->state;
+ return restriction->is_ht;
+}
+
+static bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
+{
+ s32 temp = priv->temperature; /* degrees CELSIUS except specified */
+ bool within_margin = false;
+
+ if (priv->cfg->base_params->temperature_kelvin)
+ temp = KELVIN_TO_CELSIUS(priv->temperature);
+
+ if (!priv->thermal_throttle.advanced_tt)
+ within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
+ CT_KILL_THRESHOLD_LEGACY) ? true : false;
+ else
+ within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
+ CT_KILL_THRESHOLD) ? true : false;
+ return within_margin;
+}
+
+bool iwl_check_for_ct_kill(struct iwl_priv *priv)
+{
+ bool is_ct_kill = false;
+
+ if (iwl_within_ct_kill_margin(priv)) {
+ iwl_tt_enter_ct_kill(priv);
+ is_ct_kill = true;
+ }
+ return is_ct_kill;
+}
+
+enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ struct iwl_tt_restriction *restriction;
+
+ if (!priv->thermal_throttle.advanced_tt)
+ return IWL_ANT_OK_MULTI;
+ restriction = tt->restriction + tt->state;
+ return restriction->tx_stream;
+}
+
+enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ struct iwl_tt_restriction *restriction;
+
+ if (!priv->thermal_throttle.advanced_tt)
+ return IWL_ANT_OK_MULTI;
+ restriction = tt->restriction + tt->state;
+ return restriction->rx_stream;
+}
+
+#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */
+#define CT_KILL_WAITING_DURATION (300) /* 300ms duration */
+
+/*
+ * toggle the bit to wake up uCode and check the temperature
+ * if the temperature is below CT, uCode will stay awake and send card
+ * state notification with CT_KILL bit clear to inform Thermal Throttling
+ * Management to change state. Otherwise, uCode will go back to sleep
+ * without doing anything, driver should continue the 5 seconds timer
+ * to wake up uCode for temperature check until temperature drop below CT
+ */
+static void iwl_tt_check_exit_ct_kill(unsigned long data)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)data;
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ unsigned long flags;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ if (tt->state == IWL_TI_CT_KILL) {
+ if (priv->thermal_throttle.ct_kill_toggle) {
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+ CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
+ priv->thermal_throttle.ct_kill_toggle = false;
+ } else {
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
+ CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
+ priv->thermal_throttle.ct_kill_toggle = true;
+ }
+ iwl_read32(priv, CSR_UCODE_DRV_GP1);
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ if (!iwl_grab_nic_access(priv))
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+
+ /* Reschedule the ct_kill timer to occur in
+ * CT_KILL_EXIT_DURATION seconds to ensure we get a
+ * thermal update */
+ IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n");
+ mod_timer(&priv->thermal_throttle.ct_kill_exit_tm,
+ jiffies + CT_KILL_EXIT_DURATION * HZ);
+ }
+}
+
+static void iwl_perform_ct_kill_task(struct iwl_priv *priv,
+ bool stop)
+{
+ if (stop) {
+ IWL_DEBUG_POWER(priv, "Stop all queues\n");
+ if (priv->mac80211_registered)
+ ieee80211_stop_queues(priv->hw);
+ IWL_DEBUG_POWER(priv,
+ "Schedule 5 seconds CT_KILL Timer\n");
+ mod_timer(&priv->thermal_throttle.ct_kill_exit_tm,
+ jiffies + CT_KILL_EXIT_DURATION * HZ);
+ } else {
+ IWL_DEBUG_POWER(priv, "Wake all queues\n");
+ if (priv->mac80211_registered)
+ ieee80211_wake_queues(priv->hw);
+ }
+}
+
+static void iwl_tt_ready_for_ct_kill(unsigned long data)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)data;
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ /* temperature timer expired, ready to go into CT_KILL state */
+ if (tt->state != IWL_TI_CT_KILL) {
+ IWL_DEBUG_POWER(priv, "entering CT_KILL state when "
+ "temperature timer expired\n");
+ tt->state = IWL_TI_CT_KILL;
+ set_bit(STATUS_CT_KILL, &priv->status);
+ iwl_perform_ct_kill_task(priv, true);
+ }
+}
+
+static void iwl_prepare_ct_kill_task(struct iwl_priv *priv)
+{
+ IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n");
+ /* make request to retrieve statistics information */
+ iwl_send_statistics_request(priv, CMD_SYNC, false);
+ /* Reschedule the ct_kill wait timer */
+ mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
+ jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION));
+}
+
+#define IWL_MINIMAL_POWER_THRESHOLD (CT_KILL_THRESHOLD_LEGACY)
+#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100)
+#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90)
+
+/*
+ * Legacy thermal throttling
+ * 1) Avoid NIC destruction due to high temperatures
+ * Chip will identify dangerously high temperatures that can
+ * harm the device and will power down
+ * 2) Avoid the NIC power down due to high temperature
+ * Throttle early enough to lower the power consumption before
+ * drastic steps are needed
+ */
+static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ enum iwl_tt_state old_state;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if ((tt->tt_previous_temp) &&
+ (temp > tt->tt_previous_temp) &&
+ ((temp - tt->tt_previous_temp) >
+ IWL_TT_INCREASE_MARGIN)) {
+ IWL_DEBUG_POWER(priv,
+ "Temperature increase %d degree Celsius\n",
+ (temp - tt->tt_previous_temp));
+ }
+#endif
+ old_state = tt->state;
+ /* in Celsius */
+ if (temp >= IWL_MINIMAL_POWER_THRESHOLD)
+ tt->state = IWL_TI_CT_KILL;
+ else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2)
+ tt->state = IWL_TI_2;
+ else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1)
+ tt->state = IWL_TI_1;
+ else
+ tt->state = IWL_TI_0;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ tt->tt_previous_temp = temp;
+#endif
+ /* stop ct_kill_waiting_tm timer */
+ del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
+ if (tt->state != old_state) {
+ switch (tt->state) {
+ case IWL_TI_0:
+ /*
+ * When the system is ready to go back to IWL_TI_0
+ * we only have to call iwl_power_update_mode() to
+ * do so.
+ */
+ break;
+ case IWL_TI_1:
+ tt->tt_power_mode = IWL_POWER_INDEX_3;
+ break;
+ case IWL_TI_2:
+ tt->tt_power_mode = IWL_POWER_INDEX_4;
+ break;
+ default:
+ tt->tt_power_mode = IWL_POWER_INDEX_5;
+ break;
+ }
+ mutex_lock(&priv->mutex);
+ if (old_state == IWL_TI_CT_KILL)
+ clear_bit(STATUS_CT_KILL, &priv->status);
+ if (tt->state != IWL_TI_CT_KILL &&
+ iwl_power_update_mode(priv, true)) {
+ /* TT state not updated
+ * try again during next temperature read
+ */
+ if (old_state == IWL_TI_CT_KILL)
+ set_bit(STATUS_CT_KILL, &priv->status);
+ tt->state = old_state;
+ IWL_ERR(priv, "Cannot update power mode, "
+ "TT state not updated\n");
+ } else {
+ if (tt->state == IWL_TI_CT_KILL) {
+ if (force) {
+ set_bit(STATUS_CT_KILL, &priv->status);
+ iwl_perform_ct_kill_task(priv, true);
+ } else {
+ iwl_prepare_ct_kill_task(priv);
+ tt->state = old_state;
+ }
+ } else if (old_state == IWL_TI_CT_KILL &&
+ tt->state != IWL_TI_CT_KILL)
+ iwl_perform_ct_kill_task(priv, false);
+ IWL_DEBUG_POWER(priv, "Temperature state changed %u\n",
+ tt->state);
+ IWL_DEBUG_POWER(priv, "Power Index change to %u\n",
+ tt->tt_power_mode);
+ }
+ mutex_unlock(&priv->mutex);
+ }
+}
+
+/*
+ * Advance thermal throttling
+ * 1) Avoid NIC destruction due to high temperatures
+ * Chip will identify dangerously high temperatures that can
+ * harm the device and will power down
+ * 2) Avoid the NIC power down due to high temperature
+ * Throttle early enough to lower the power consumption before
+ * drastic steps are needed
+ * Actions include relaxing the power down sleep thresholds and
+ * decreasing the number of TX streams
+ * 3) Avoid throughput performance impact as much as possible
+ *
+ *=============================================================================
+ * Condition Nxt State Condition Nxt State Condition Nxt State
+ *-----------------------------------------------------------------------------
+ * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A
+ * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0
+ * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1
+ * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
+ *=============================================================================
+ */
+static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ int i;
+ bool changed = false;
+ enum iwl_tt_state old_state;
+ struct iwl_tt_trans *transaction;
+
+ old_state = tt->state;
+ for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) {
+ /* based on the current TT state,
+ * find the curresponding transaction table
+ * each table has (IWL_TI_STATE_MAX - 1) entries
+ * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1))
+ * will advance to the correct table.
+ * then based on the current temperature
+ * find the next state need to transaction to
+ * go through all the possible (IWL_TI_STATE_MAX - 1) entries
+ * in the current table to see if transaction is needed
+ */
+ transaction = tt->transaction +
+ ((old_state * (IWL_TI_STATE_MAX - 1)) + i);
+ if (temp >= transaction->tt_low &&
+ temp <= transaction->tt_high) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if ((tt->tt_previous_temp) &&
+ (temp > tt->tt_previous_temp) &&
+ ((temp - tt->tt_previous_temp) >
+ IWL_TT_INCREASE_MARGIN)) {
+ IWL_DEBUG_POWER(priv,
+ "Temperature increase %d "
+ "degree Celsius\n",
+ (temp - tt->tt_previous_temp));
+ }
+ tt->tt_previous_temp = temp;
+#endif
+ if (old_state !=
+ transaction->next_state) {
+ changed = true;
+ tt->state =
+ transaction->next_state;
+ }
+ break;
+ }
+ }
+ /* stop ct_kill_waiting_tm timer */
+ del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
+ if (changed) {
+ if (tt->state >= IWL_TI_1) {
+ /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
+ tt->tt_power_mode = IWL_POWER_INDEX_5;
+
+ if (!iwl_ht_enabled(priv)) {
+ struct iwl_rxon_context *ctx;
+
+ for_each_context(priv, ctx) {
+ struct iwl_rxon_cmd *rxon;
+
+ rxon = &ctx->staging;
+
+ /* disable HT */
+ rxon->flags &= ~(
+ RXON_FLG_CHANNEL_MODE_MSK |
+ RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
+ RXON_FLG_HT40_PROT_MSK |
+ RXON_FLG_HT_PROT_MSK);
+ }
+ } else {
+ /* check HT capability and set
+ * according to the system HT capability
+ * in case get disabled before */
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+ }
+
+ } else {
+ /*
+ * restore system power setting -- it will be
+ * recalculated automatically.
+ */
+
+ /* check HT capability and set
+ * according to the system HT capability
+ * in case get disabled before */
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+ }
+ mutex_lock(&priv->mutex);
+ if (old_state == IWL_TI_CT_KILL)
+ clear_bit(STATUS_CT_KILL, &priv->status);
+ if (tt->state != IWL_TI_CT_KILL &&
+ iwl_power_update_mode(priv, true)) {
+ /* TT state not updated
+ * try again during next temperature read
+ */
+ IWL_ERR(priv, "Cannot update power mode, "
+ "TT state not updated\n");
+ if (old_state == IWL_TI_CT_KILL)
+ set_bit(STATUS_CT_KILL, &priv->status);
+ tt->state = old_state;
+ } else {
+ IWL_DEBUG_POWER(priv,
+ "Thermal Throttling to new state: %u\n",
+ tt->state);
+ if (old_state != IWL_TI_CT_KILL &&
+ tt->state == IWL_TI_CT_KILL) {
+ if (force) {
+ IWL_DEBUG_POWER(priv,
+ "Enter IWL_TI_CT_KILL\n");
+ set_bit(STATUS_CT_KILL, &priv->status);
+ iwl_perform_ct_kill_task(priv, true);
+ } else {
+ iwl_prepare_ct_kill_task(priv);
+ tt->state = old_state;
+ }
+ } else if (old_state == IWL_TI_CT_KILL &&
+ tt->state != IWL_TI_CT_KILL) {
+ IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n");
+ iwl_perform_ct_kill_task(priv, false);
+ }
+ }
+ mutex_unlock(&priv->mutex);
+ }
+}
+
+/* Card State Notification indicated reach critical temperature
+ * if PSP not enable, no Thermal Throttling function will be performed
+ * just set the GP1 bit to acknowledge the event
+ * otherwise, go into IWL_TI_CT_KILL state
+ * since Card State Notification will not provide any temperature reading
+ * for Legacy mode
+ * so just pass the CT_KILL temperature to iwl_legacy_tt_handler()
+ * for advance mode
+ * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state
+ */
+static void iwl_bg_ct_enter(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ if (!iwl_is_ready(priv))
+ return;
+
+ if (tt->state != IWL_TI_CT_KILL) {
+ IWL_ERR(priv, "Device reached critical temperature "
+ "- ucode going to sleep!\n");
+ if (!priv->thermal_throttle.advanced_tt)
+ iwl_legacy_tt_handler(priv,
+ IWL_MINIMAL_POWER_THRESHOLD,
+ true);
+ else
+ iwl_advance_tt_handler(priv,
+ CT_KILL_THRESHOLD + 1, true);
+ }
+}
+
+/* Card State Notification indicated out of critical temperature
+ * since Card State Notification will not provide any temperature reading
+ * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature
+ * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state
+ */
+static void iwl_bg_ct_exit(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ if (!iwl_is_ready(priv))
+ return;
+
+ /* stop ct_kill_exit_tm timer */
+ del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
+
+ if (tt->state == IWL_TI_CT_KILL) {
+ IWL_ERR(priv,
+ "Device temperature below critical"
+ "- ucode awake!\n");
+ /*
+ * exit from CT_KILL state
+ * reset the current temperature reading
+ */
+ priv->temperature = 0;
+ if (!priv->thermal_throttle.advanced_tt)
+ iwl_legacy_tt_handler(priv,
+ IWL_REDUCED_PERFORMANCE_THRESHOLD_2,
+ true);
+ else
+ iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD,
+ true);
+ }
+}
+
+void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n");
+ queue_work(priv->workqueue, &priv->ct_enter);
+}
+
+void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n");
+ queue_work(priv->workqueue, &priv->ct_exit);
+}
+
+static void iwl_bg_tt_work(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
+ s32 temp = priv->temperature; /* degrees CELSIUS except specified */
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ if (priv->cfg->base_params->temperature_kelvin)
+ temp = KELVIN_TO_CELSIUS(priv->temperature);
+
+ if (!priv->thermal_throttle.advanced_tt)
+ iwl_legacy_tt_handler(priv, temp, false);
+ else
+ iwl_advance_tt_handler(priv, temp, false);
+}
+
+void iwl_tt_handler(struct iwl_priv *priv)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n");
+ queue_work(priv->workqueue, &priv->tt_work);
+}
+
+/* Thermal throttling initialization
+ * For advance thermal throttling:
+ * Initialize Thermal Index and temperature threshold table
+ * Initialize thermal throttling restriction table
+ */
+void iwl_tt_initialize(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
+ struct iwl_tt_trans *transaction;
+
+ IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n");
+
+ memset(tt, 0, sizeof(struct iwl_tt_mgmt));
+
+ tt->state = IWL_TI_0;
+ init_timer(&priv->thermal_throttle.ct_kill_exit_tm);
+ priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv;
+ priv->thermal_throttle.ct_kill_exit_tm.function =
+ iwl_tt_check_exit_ct_kill;
+ init_timer(&priv->thermal_throttle.ct_kill_waiting_tm);
+ priv->thermal_throttle.ct_kill_waiting_tm.data =
+ (unsigned long)priv;
+ priv->thermal_throttle.ct_kill_waiting_tm.function =
+ iwl_tt_ready_for_ct_kill;
+ /* setup deferred ct kill work */
+ INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
+ INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
+ INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
+
+ if (priv->cfg->base_params->adv_thermal_throttle) {
+ IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
+ tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
+ IWL_TI_STATE_MAX, GFP_KERNEL);
+ tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) *
+ IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1),
+ GFP_KERNEL);
+ if (!tt->restriction || !tt->transaction) {
+ IWL_ERR(priv, "Fallback to Legacy Throttling\n");
+ priv->thermal_throttle.advanced_tt = false;
+ kfree(tt->restriction);
+ tt->restriction = NULL;
+ kfree(tt->transaction);
+ tt->transaction = NULL;
+ } else {
+ transaction = tt->transaction +
+ (IWL_TI_0 * (IWL_TI_STATE_MAX - 1));
+ memcpy(transaction, &tt_range_0[0], size);
+ transaction = tt->transaction +
+ (IWL_TI_1 * (IWL_TI_STATE_MAX - 1));
+ memcpy(transaction, &tt_range_1[0], size);
+ transaction = tt->transaction +
+ (IWL_TI_2 * (IWL_TI_STATE_MAX - 1));
+ memcpy(transaction, &tt_range_2[0], size);
+ transaction = tt->transaction +
+ (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1));
+ memcpy(transaction, &tt_range_3[0], size);
+ size = sizeof(struct iwl_tt_restriction) *
+ IWL_TI_STATE_MAX;
+ memcpy(tt->restriction,
+ &restriction_range[0], size);
+ priv->thermal_throttle.advanced_tt = true;
+ }
+ } else {
+ IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n");
+ priv->thermal_throttle.advanced_tt = false;
+ }
+}
+
+/* cleanup thermal throttling management related memory and timer */
+void iwl_tt_exit(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ /* stop ct_kill_exit_tm timer if activated */
+ del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
+ /* stop ct_kill_waiting_tm timer if activated */
+ del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
+ cancel_work_sync(&priv->tt_work);
+ cancel_work_sync(&priv->ct_enter);
+ cancel_work_sync(&priv->ct_exit);
+
+ if (priv->thermal_throttle.advanced_tt) {
+ /* free advance thermal throttling memory */
+ kfree(tt->restriction);
+ tt->restriction = NULL;
+ kfree(tt->transaction);
+ tt->transaction = NULL;
+ }
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
new file mode 100644
index 000000000000..d55060427cac
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
@@ -0,0 +1,129 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+#ifndef __iwl_tt_setting_h__
+#define __iwl_tt_setting_h__
+
+#include "iwl-commands.h"
+
+#define IWL_ABSOLUTE_ZERO 0
+#define IWL_ABSOLUTE_MAX 0xFFFFFFFF
+#define IWL_TT_INCREASE_MARGIN 5
+#define IWL_TT_CT_KILL_MARGIN 3
+
+enum iwl_antenna_ok {
+ IWL_ANT_OK_NONE,
+ IWL_ANT_OK_SINGLE,
+ IWL_ANT_OK_MULTI,
+};
+
+/* Thermal Throttling State Machine states */
+enum iwl_tt_state {
+ IWL_TI_0, /* normal temperature, system power state */
+ IWL_TI_1, /* high temperature detect, low power state */
+ IWL_TI_2, /* higher temperature detected, lower power state */
+ IWL_TI_CT_KILL, /* critical temperature detected, lowest power state */
+ IWL_TI_STATE_MAX
+};
+
+/**
+ * struct iwl_tt_restriction - Thermal Throttling restriction table
+ * @tx_stream: number of tx stream allowed
+ * @is_ht: ht enable/disable
+ * @rx_stream: number of rx stream allowed
+ *
+ * This table is used by advance thermal throttling management
+ * based on the current thermal throttling state, and determines
+ * the number of tx/rx streams and the status of HT operation.
+ */
+struct iwl_tt_restriction {
+ enum iwl_antenna_ok tx_stream;
+ enum iwl_antenna_ok rx_stream;
+ bool is_ht;
+};
+
+/**
+ * struct iwl_tt_trans - Thermal Throttling transaction table
+ * @next_state: next thermal throttling mode
+ * @tt_low: low temperature threshold to change state
+ * @tt_high: high temperature threshold to change state
+ *
+ * This is used by the advanced thermal throttling algorithm
+ * to determine the next thermal state to go based on the
+ * current temperature.
+ */
+struct iwl_tt_trans {
+ enum iwl_tt_state next_state;
+ u32 tt_low;
+ u32 tt_high;
+};
+
+/**
+ * struct iwl_tt_mgnt - Thermal Throttling Management structure
+ * @advanced_tt: advanced thermal throttle required
+ * @state: current Thermal Throttling state
+ * @tt_power_mode: Thermal Throttling power mode index
+ * being used to set power level when
+ * when thermal throttling state != IWL_TI_0
+ * the tt_power_mode should set to different
+ * power mode based on the current tt state
+ * @tt_previous_temperature: last measured temperature
+ * @iwl_tt_restriction: ptr to restriction tbl, used by advance
+ * thermal throttling to determine how many tx/rx streams
+ * should be used in tt state; and can HT be enabled or not
+ * @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling
+ * state transaction
+ * @ct_kill_toggle: used to toggle the CSR bit when checking uCode temperature
+ * @ct_kill_exit_tm: timer to exit thermal kill
+ */
+struct iwl_tt_mgmt {
+ enum iwl_tt_state state;
+ bool advanced_tt;
+ u8 tt_power_mode;
+ bool ct_kill_toggle;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ s32 tt_previous_temp;
+#endif
+ struct iwl_tt_restriction *restriction;
+ struct iwl_tt_trans *transaction;
+ struct timer_list ct_kill_exit_tm;
+ struct timer_list ct_kill_waiting_tm;
+};
+
+u8 iwl_tt_current_power_mode(struct iwl_priv *priv);
+bool iwl_tt_is_low_power_state(struct iwl_priv *priv);
+bool iwl_ht_enabled(struct iwl_priv *priv);
+bool iwl_check_for_ct_kill(struct iwl_priv *priv);
+enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv);
+enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv);
+void iwl_tt_enter_ct_kill(struct iwl_priv *priv);
+void iwl_tt_exit_ct_kill(struct iwl_priv *priv);
+void iwl_tt_handler(struct iwl_priv *priv);
+void iwl_tt_initialize(struct iwl_priv *priv);
+void iwl_tt_exit(struct iwl_priv *priv);
+
+#endif /* __iwl_tt_setting_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 69155aa448fb..db57aea629d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -71,18 +71,6 @@ static const u8 tid_to_ac[] = {
2, 3, 3, 2, 1, 1, 0, 0
};
-static const u8 ac_to_fifo[] = {
- IWL_TX_FIFO_VO,
- IWL_TX_FIFO_VI,
- IWL_TX_FIFO_BE,
- IWL_TX_FIFO_BK,
-};
-
-static inline int get_fifo_from_ac(u8 ac)
-{
- return ac_to_fifo[ac];
-}
-
static inline int get_ac_from_tid(u16 tid)
{
if (likely(tid < ARRAY_SIZE(tid_to_ac)))
@@ -92,10 +80,10 @@ static inline int get_ac_from_tid(u16 tid)
return -EINVAL;
}
-static inline int get_fifo_from_tid(u16 tid)
+static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid)
{
if (likely(tid < ARRAY_SIZE(tid_to_ac)))
- return get_fifo_from_ac(tid_to_ac[tid]);
+ return ctx->ac_to_fifo[tid_to_ac[tid]];
/* no support for TIDs 8-15 yet */
return -EINVAL;
@@ -118,7 +106,7 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
- if (txq_id != IWL_CMD_QUEUE_NUM) {
+ 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;
@@ -155,7 +143,7 @@ void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
- if (txq_id != IWL_CMD_QUEUE_NUM)
+ if (txq_id != priv->cmd_queue)
sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
bc_ent = cpu_to_le16(1 | (sta_id << 12));
@@ -236,13 +224,13 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
int ret;
if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
- (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
- <= txq_id)) {
+ (IWLAGN_FIRST_AMPDU_QUEUE +
+ priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
IWL_WARN(priv,
"queue number out of range: %d, must be %d to %d\n",
txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
IWLAGN_FIRST_AMPDU_QUEUE +
- priv->cfg->num_of_ampdu_queues - 1);
+ priv->cfg->base_params->num_of_ampdu_queues - 1);
return -EINVAL;
}
@@ -298,13 +286,13 @@ 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 + priv->cfg->num_of_ampdu_queues
- <= txq_id)) {
+ (IWLAGN_FIRST_AMPDU_QUEUE +
+ priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
IWL_ERR(priv,
"queue number out of range: %d, must be %d to %d\n",
txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
IWLAGN_FIRST_AMPDU_QUEUE +
- priv->cfg->num_of_ampdu_queues - 1);
+ priv->cfg->base_params->num_of_ampdu_queues - 1);
return -EINVAL;
}
@@ -333,19 +321,15 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask);
}
-static inline int get_queue_from_ac(u16 ac)
-{
- return ac;
-}
-
/*
* handle build REPLY_TX command notification.
*/
static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
- struct iwl_tx_cmd *tx_cmd,
- struct ieee80211_tx_info *info,
- struct ieee80211_hdr *hdr,
- u8 std_id)
+ struct sk_buff *skb,
+ struct iwl_tx_cmd *tx_cmd,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_hdr *hdr,
+ u8 std_id)
{
__le16 fc = hdr->frame_control;
__le32 tx_flags = tx_cmd->tx_flags;
@@ -365,6 +349,13 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
if (ieee80211_is_back_req(fc))
tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
+ else if (info->band == IEEE80211_BAND_2GHZ &&
+ priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist &&
+ (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
+ ieee80211_is_reassoc_req(fc) ||
+ skb->protocol == cpu_to_be16(ETH_P_PAE)))
+ tx_flags |= TX_CMD_FLG_IGNORE_BT;
tx_cmd->sta_id = std_id;
@@ -454,7 +445,14 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
rate_flags |= RATE_MCS_CCK_MSK;
/* Set up antennas */
- priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist &&
+ priv->bt_full_concurrent) {
+ /* operated as 1x1 in full concurrency mode */
+ priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
+ first_antenna(priv->hw_params.valid_tx_ant));
+ } else
+ priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
priv->hw_params.valid_tx_ant);
rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
@@ -470,8 +468,8 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
{
struct ieee80211_key_conf *keyconf = info->control.hw_key;
- switch (keyconf->alg) {
- case ALG_CCMP:
+ switch (keyconf->cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
if (info->flags & IEEE80211_TX_CTL_AMPDU)
@@ -479,20 +477,20 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
ieee80211_get_tkip_key(keyconf, skb_frag,
IEEE80211_TKIP_P2_KEY, tx_cmd->key);
IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
break;
- case ALG_WEP:
+ case WLAN_CIPHER_SUITE_WEP104:
+ tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
+ /* fall through */
+ case WLAN_CIPHER_SUITE_WEP40:
tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP |
(keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT);
- if (keyconf->keylen == WEP_KEY_LEN_128)
- tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
-
memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
@@ -500,7 +498,7 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
break;
default:
- IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg);
+ IWL_ERR(priv, "Unknown encode cipher %x\n", keyconf->cipher);
break;
}
}
@@ -519,6 +517,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
struct iwl_device_cmd *out_cmd;
struct iwl_cmd_meta *out_meta;
struct iwl_tx_cmd *tx_cmd;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
int swq_id, txq_id;
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
@@ -533,6 +532,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
u8 *qc = NULL;
unsigned long flags;
+ if (info->control.vif)
+ ctx = iwl_rxon_ctx_from_vif(info->control.vif);
+
spin_lock_irqsave(&priv->lock, flags);
if (iwl_is_rfkill(priv)) {
IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
@@ -553,7 +555,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find index into station table for destination station */
- sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
+ sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
@@ -565,8 +567,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (sta)
sta_priv = (void *)sta->drv_priv;
- if (sta_priv && sta_id != priv->hw_params.bcast_sta_id &&
- sta_priv->asleep) {
+ if (sta_priv && sta_priv->asleep) {
WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
/*
* This sends an asynchronous command to the device,
@@ -580,7 +581,20 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
}
- txq_id = get_queue_from_ac(skb_get_queue_mapping(skb));
+ /*
+ * Send this frame after DTIM -- there's a special queue
+ * reserved for this for contexts that support AP mode.
+ */
+ if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
+ txq_id = ctx->mcast_queue;
+ /*
+ * The microcode will clear the more data
+ * bit in the last frame it transmits.
+ */
+ hdr->frame_control |=
+ cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+ } else
+ txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
/* irqs already disabled/saved above when locking priv->lock */
spin_lock(&priv->sta_lock);
@@ -625,6 +639,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
txq->txb[q->write_ptr].skb = skb;
+ txq->txb[q->write_ptr].ctx = ctx;
/* Set up first empty entry in queue's array of Tx/cmd buffers */
out_cmd = txq->cmd[q->write_ptr];
@@ -655,7 +670,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
/* TODO need this for burst mode later on */
- iwlagn_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
+ iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id);
iwl_dbg_log_tx_data_frame(priv, len, hdr);
iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc);
@@ -813,7 +828,7 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv)
/* Tx queues */
if (priv->txq) {
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
- if (txq_id == IWL_CMD_QUEUE_NUM)
+ if (txq_id == priv->cmd_queue)
iwl_cmd_queue_free(priv);
else
iwl_tx_queue_free(priv, txq_id);
@@ -870,9 +885,9 @@ int iwlagn_txq_ctx_alloc(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
- /* Alloc and init all Tx queues, including the command queue (#4) */
+ /* Alloc and init all Tx queues, including the command queue (#4/#9) */
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
- slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
+ slots_num = (txq_id == priv->cmd_queue) ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
txq_id);
@@ -910,7 +925,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv)
/* Alloc and init all Tx queues, including the command queue (#4) */
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
- slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
+ slots_num = txq_id == priv->cmd_queue ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
}
@@ -968,7 +983,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
unsigned long flags;
struct iwl_tid_data *tid_data;
- tx_fifo = get_fifo_from_tid(tid);
+ tx_fifo = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid);
if (unlikely(tx_fifo < 0))
return tx_fifo;
@@ -1024,12 +1039,12 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid)
{
- int tx_fifo_id, txq_id, sta_id, ssn = -1;
+ int tx_fifo_id, txq_id, sta_id, ssn;
struct iwl_tid_data *tid_data;
int write_ptr, read_ptr;
unsigned long flags;
- tx_fifo_id = get_fifo_from_tid(tid);
+ tx_fifo_id = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid);
if (unlikely(tx_fifo_id < 0))
return tx_fifo_id;
@@ -1042,21 +1057,26 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
spin_lock_irqsave(&priv->sta_lock, flags);
- if (priv->stations[sta_id].tid[tid].agg.state ==
- IWL_EMPTYING_HW_QUEUE_ADDBA) {
- IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
- ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
- priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return 0;
- }
-
- if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
- IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
-
tid_data = &priv->stations[sta_id].tid[tid];
ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
txq_id = tid_data->agg.txq_id;
+
+ switch (priv->stations[sta_id].tid[tid].agg.state) {
+ case IWL_EMPTYING_HW_QUEUE_ADDBA:
+ /*
+ * This can happen if the peer stops aggregation
+ * again before we've had a chance to drain the
+ * queue we selected previously, i.e. before the
+ * session was really started completely.
+ */
+ IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
+ goto turn_off;
+ case IWL_AGG_ON:
+ break;
+ default:
+ IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
+ }
+
write_ptr = priv->txq[txq_id].q.write_ptr;
read_ptr = priv->txq[txq_id].q.read_ptr;
@@ -1070,6 +1090,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
}
IWL_DEBUG_HT(priv, "HW queue is empty\n");
+ turn_off:
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
/* do not restore/save irqs */
@@ -1098,6 +1119,9 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
struct iwl_queue *q = &priv->txq[txq_id].q;
u8 *addr = priv->stations[sta_id].sta.sta.addr;
struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
+ struct iwl_rxon_context *ctx;
+
+ ctx = &priv->contexts[priv->stations[sta_id].ctxid];
lockdep_assert_held(&priv->sta_lock);
@@ -1108,12 +1132,12 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
if ((txq_id == tid_data->agg.txq_id) &&
(q->read_ptr == q->write_ptr)) {
u16 ssn = SEQ_TO_SN(tid_data->seq_number);
- int tx_fifo = get_fifo_from_tid(tid);
+ 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);
tid_data->agg.state = IWL_AGG_OFF;
- ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid);
+ ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
}
break;
case IWL_EMPTYING_HW_QUEUE_ADDBA:
@@ -1121,7 +1145,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
if (tid_data->tfds_in_queue == 0) {
IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
tid_data->agg.state = IWL_AGG_ON;
- ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid);
+ ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
}
break;
}
@@ -1129,14 +1153,14 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
return 0;
}
-static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
+static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
struct ieee80211_sta *sta;
struct iwl_station_priv *sta_priv;
rcu_read_lock();
- sta = ieee80211_find_sta(priv->vif, hdr->addr1);
+ sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1);
if (sta) {
sta_priv = (void *)sta->drv_priv;
/* avoid atomic ops if this isn't a client */
@@ -1146,7 +1170,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
}
rcu_read_unlock();
- ieee80211_tx_status_irqsafe(priv->hw, skb);
+ ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb);
}
int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
@@ -1169,7 +1193,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
tx_info = &txq->txb[txq->q.read_ptr];
- iwlagn_tx_status(priv, tx_info->skb);
+ iwlagn_tx_status(priv, tx_info);
hdr = (struct ieee80211_hdr *)tx_info->skb->data;
if (hdr && ieee80211_is_data_qos(hdr->frame_control))
@@ -1367,3 +1391,43 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+const char *iwl_get_tx_fail_reason(u32 status)
+{
+#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
+#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
+
+ switch (status & TX_STATUS_MSK) {
+ case TX_STATUS_SUCCESS:
+ return "SUCCESS";
+ TX_STATUS_POSTPONE(DELAY);
+ TX_STATUS_POSTPONE(FEW_BYTES);
+ TX_STATUS_POSTPONE(BT_PRIO);
+ TX_STATUS_POSTPONE(QUIET_PERIOD);
+ TX_STATUS_POSTPONE(CALC_TTAK);
+ TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
+ TX_STATUS_FAIL(SHORT_LIMIT);
+ TX_STATUS_FAIL(LONG_LIMIT);
+ TX_STATUS_FAIL(FIFO_UNDERRUN);
+ TX_STATUS_FAIL(DRAIN_FLOW);
+ TX_STATUS_FAIL(RFKILL_FLUSH);
+ TX_STATUS_FAIL(LIFE_EXPIRE);
+ TX_STATUS_FAIL(DEST_PS);
+ TX_STATUS_FAIL(HOST_ABORTED);
+ TX_STATUS_FAIL(BT_RETRY);
+ TX_STATUS_FAIL(STA_INVALID);
+ TX_STATUS_FAIL(FRAG_DROPPED);
+ TX_STATUS_FAIL(TID_DISABLE);
+ TX_STATUS_FAIL(FIFO_FLUSHED);
+ TX_STATUS_FAIL(INSUFFICIENT_CF_POLL);
+ TX_STATUS_FAIL(PASSIVE_NO_RX);
+ TX_STATUS_FAIL(NO_BEACON_ON_RADAR);
+ }
+
+ return "UNKNOWN";
+
+#undef TX_STATUS_FAIL
+#undef TX_STATUS_POSTPONE
+}
+#endif /* CONFIG_IWLWIFI_DEBUG */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 6f77441cb65a..703621107dac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -38,6 +38,7 @@
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
#include "iwl-agn.h"
+#include "iwl-agn-calib.h"
static const s8 iwlagn_default_queue_to_tx_fifo[] = {
IWL_TX_FIFO_VO,
@@ -52,6 +53,19 @@ static const s8 iwlagn_default_queue_to_tx_fifo[] = {
IWL_TX_FIFO_UNUSED,
};
+static const s8 iwlagn_ipan_queue_to_tx_fifo[] = {
+ IWL_TX_FIFO_VO,
+ IWL_TX_FIFO_VI,
+ IWL_TX_FIFO_BE,
+ IWL_TX_FIFO_BK,
+ IWL_TX_FIFO_BK_IPAN,
+ IWL_TX_FIFO_BE_IPAN,
+ IWL_TX_FIFO_VI_IPAN,
+ IWL_TX_FIFO_VO_IPAN,
+ IWL_TX_FIFO_BE_IPAN,
+ IWLAGN_CMD_FIFO_NUM,
+};
+
static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
{COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
0, COEX_UNASSOC_IDLE_FLAGS},
@@ -201,6 +215,25 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv)
(u8 *)&cmd, sizeof(cmd));
}
+static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv)
+{
+ struct iwl_calib_temperature_offset_cmd cmd;
+ __le16 *offset_calib =
+ (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE);
+ cmd.hdr.op_code = IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD;
+ cmd.hdr.first_group = 0;
+ cmd.hdr.groups_num = 1;
+ cmd.hdr.data_valid = 1;
+ cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]);
+ if (!(cmd.radio_sensor_offset))
+ cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET;
+ cmd.reserved = 0;
+ IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
+ cmd.radio_sensor_offset);
+ return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET],
+ (u8 *)&cmd, sizeof(cmd));
+}
+
static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
{
struct iwl_calib_cfg_cmd calib_cfg_cmd;
@@ -294,7 +327,27 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
goto restart;
}
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ /*
+ * Tell uCode we are ready to perform calibration
+ * need to perform this before any calibration
+ * 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,
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+
+ }
iwlagn_send_calib_cfg(priv);
+
+ /**
+ * 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;
restart:
@@ -306,7 +359,7 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
{
struct iwl_wimax_coex_cmd coex_cmd;
- if (priv->cfg->support_wimax_coexist) {
+ if (priv->cfg->base_params->support_wimax_coexist) {
/* UnMask wake up src at associated sleep */
coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
@@ -329,8 +382,54 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
sizeof(coex_cmd), &coex_cmd);
}
+static const u8 iwlagn_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
+ ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_COEX_OFF << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_COEX_ON << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+void iwlagn_send_prio_tbl(struct iwl_priv *priv)
+{
+ struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd;
+
+ memcpy(prio_tbl_cmd.prio_tbl, iwlagn_bt_prio_tbl,
+ sizeof(iwlagn_bt_prio_tbl));
+ if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PRIO_TABLE,
+ sizeof(prio_tbl_cmd), &prio_tbl_cmd))
+ IWL_ERR(priv, "failed to send BT prio tbl command\n");
+}
+
+void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
+{
+ struct iwl_bt_coex_prot_env_cmd env_cmd;
+
+ env_cmd.action = action;
+ env_cmd.type = type;
+ if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
+ sizeof(env_cmd), &env_cmd))
+ IWL_ERR(priv, "failed to send BT env command\n");
+}
+
+
int iwlagn_alive_notify(struct iwl_priv *priv)
{
+ const s8 *queues;
u32 a;
unsigned long flags;
int i, chan;
@@ -365,7 +464,7 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL,
- IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
+ IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv));
iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0);
/* initiate the queues */
@@ -391,7 +490,13 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
/* Activate all Tx DMA/FIFO channels */
priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
- iwlagn_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
+ /* map queues to FIFOs */
+ if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
+ queues = iwlagn_ipan_queue_to_tx_fifo;
+ else
+ queues = iwlagn_default_queue_to_tx_fifo;
+
+ iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0);
/* make sure all queue are not stopped */
memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
@@ -400,11 +505,12 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
/* reset to 0 to enable all the queue first */
priv->txq_ctx_active_msk = 0;
- /* map qos queues to fifos one-to-one */
+
BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10);
+ BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10);
- for (i = 0; i < ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); i++) {
- int ac = iwlagn_default_queue_to_tx_fifo[i];
+ for (i = 0; i < 10; i++) {
+ int ac = queues[i];
iwl_txq_ctx_activate(priv, i);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 10d7b9b7f064..c2636a7ab9ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/pci-aspm.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -56,7 +57,7 @@
#include "iwl-io.h"
#include "iwl-helpers.h"
#include "iwl-sta.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
#include "iwl-agn.h"
@@ -86,29 +87,36 @@ MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");
MODULE_ALIAS("iwl4965");
+static int iwlagn_ant_coupling;
+static bool iwlagn_bt_ch_announce = 1;
+
/**
- * iwl_commit_rxon - commit staging_rxon to hardware
+ * iwlagn_commit_rxon - commit staging_rxon to hardware
*
* The RXON command in staging_rxon is committed to the hardware and
* the active_rxon structure is updated with the new data. This
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
-int iwl_commit_rxon(struct iwl_priv *priv)
+int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
/* cast away the const for active_rxon in this function */
- struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+ struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
int ret;
bool new_assoc =
- !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
+ !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
+ bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
if (!iwl_is_alive(priv))
return -EBUSY;
+ if (!ctx->is_active)
+ return 0;
+
/* always get timestamp with Rx frame */
- priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
+ ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
- ret = iwl_check_rxon_cmd(priv);
+ ret = iwl_check_rxon_cmd(priv, ctx);
if (ret) {
IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
return -EINVAL;
@@ -119,7 +127,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
* abort any previous channel switch if still in process
*/
if (priv->switch_rxon.switch_in_progress &&
- (priv->switch_rxon.channel != priv->staging_rxon.channel)) {
+ (priv->switch_rxon.channel != ctx->staging.channel)) {
IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
le16_to_cpu(priv->switch_rxon.channel));
iwl_chswitch_done(priv, false);
@@ -128,15 +136,15 @@ int iwl_commit_rxon(struct iwl_priv *priv)
/* If we don't need to send a full RXON, we can use
* iwl_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
- if (!iwl_full_rxon_required(priv)) {
- ret = iwl_send_rxon_assoc(priv);
+ if (!iwl_full_rxon_required(priv, ctx)) {
+ ret = iwl_send_rxon_assoc(priv, ctx);
if (ret) {
IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
return ret;
}
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
- iwl_print_rx_config_cmd(priv);
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ iwl_print_rx_config_cmd(priv, ctx);
return 0;
}
@@ -144,13 +152,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
* an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration
* before we apply the new config */
- if (iwl_is_associated(priv) && new_assoc) {
+ if (iwl_is_associated_ctx(ctx) && new_assoc) {
IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl_rxon_cmd),
- &priv->active_rxon);
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd),
+ active_rxon);
/* If the mask clearing failed then we set
* active_rxon back to what it was previously */
@@ -159,9 +167,9 @@ int iwl_commit_rxon(struct iwl_priv *priv)
IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
return ret;
}
- iwl_clear_ucode_stations(priv);
- iwl_restore_stations(priv);
- ret = iwl_restore_default_wep_keys(priv);
+ 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;
@@ -173,47 +181,65 @@ int iwl_commit_rxon(struct iwl_priv *priv)
"* channel = %d\n"
"* bssid = %pM\n",
(new_assoc ? "" : "out"),
- le16_to_cpu(priv->staging_rxon.channel),
- priv->staging_rxon.bssid_addr);
+ le16_to_cpu(ctx->staging.channel),
+ ctx->staging.bssid_addr);
+
+ iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
- iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto);
+ if (!old_assoc) {
+ /*
+ * First of all, before setting associated, we need to
+ * send RXON timing so the device knows about the DTIM
+ * period and other timing values
+ */
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Error setting RXON timing!\n");
+ return ret;
+ }
+ }
+
+ if (priv->cfg->ops->hcmd->set_pan_params) {
+ ret = priv->cfg->ops->hcmd->set_pan_params(priv);
+ if (ret)
+ return ret;
+ }
/* Apply the new configuration
* RXON unassoc clears the station table in uCode so restoration of
* stations is needed after it (the RXON command) completes
*/
if (!new_assoc) {
- ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
+ 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;
}
IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
- iwl_clear_ucode_stations(priv);
- iwl_restore_stations(priv);
- ret = iwl_restore_default_wep_keys(priv);
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ 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;
}
}
-
- priv->start_calib = 0;
if (new_assoc) {
+ priv->start_calib = 0;
/* Apply the new configuration
* RXON assoc doesn't clear the station table in uCode,
*/
- ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
+ 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_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
}
- iwl_print_rx_config_cmd(priv);
+ iwl_print_rx_config_cmd(priv, ctx);
iwl_init_sensitivity(priv);
@@ -230,10 +256,14 @@ int iwl_commit_rxon(struct iwl_priv *priv)
void iwl_update_chain_flags(struct iwl_priv *priv)
{
+ struct iwl_rxon_context *ctx;
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
- iwlcore_commit_rxon(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain) {
+ for_each_context(priv, ctx) {
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+ iwlcore_commit_rxon(priv, ctx);
+ }
+ }
}
static void iwl_clear_free_frames(struct iwl_priv *priv)
@@ -284,24 +314,26 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
}
static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr,
- int left)
+ struct ieee80211_hdr *hdr,
+ int left)
{
- if (!priv->ibss_beacon)
+ lockdep_assert_held(&priv->mutex);
+
+ if (!priv->beacon_skb)
return 0;
- if (priv->ibss_beacon->len > left)
+ if (priv->beacon_skb->len > left)
return 0;
- memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len);
+ memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
- return priv->ibss_beacon->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,
- u8 *beacon, u32 frame_size)
+ struct iwl_tx_beacon_cmd *tx_beacon_cmd,
+ u8 *beacon, u32 frame_size)
{
u16 tim_idx;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
@@ -337,6 +369,13 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
* beacon contents.
*/
+ lockdep_assert_held(&priv->mutex);
+
+ if (!priv->beacon_ctx) {
+ IWL_ERR(priv, "trying to build beacon w/o beacon context!\n");
+ return 0;
+ }
+
/* Initialize memory */
tx_beacon_cmd = &frame->u.beacon;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
@@ -346,20 +385,22 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
sizeof(frame->u) - sizeof(*tx_beacon_cmd));
if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
return 0;
+ if (!frame_size)
+ return 0;
/* Set up TX command fields */
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
- tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
+ tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
/* Set up TX beacon command fields */
iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame,
- frame_size);
+ frame_size);
/* Set up packet rate and flags */
- rate = iwl_rate_get_lowest_plcp(priv);
+ rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx);
priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
priv->hw_params.valid_tx_ant);
rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
@@ -592,23 +633,83 @@ static void iwl_bg_beacon_update(struct work_struct *work)
container_of(work, struct iwl_priv, beacon_update);
struct sk_buff *beacon;
- /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
- beacon = ieee80211_beacon_get(priv->hw, priv->vif);
+ mutex_lock(&priv->mutex);
+ if (!priv->beacon_ctx) {
+ IWL_ERR(priv, "updating beacon w/o beacon context!\n");
+ goto out;
+ }
+
+ if (priv->beacon_ctx->vif->type != NL80211_IFTYPE_AP) {
+ /*
+ * The ucode will send beacon notifications even in
+ * IBSS mode, but we don't want to process them. But
+ * we need to defer the type check to here due to
+ * requiring locking around the beacon_ctx access.
+ */
+ goto out;
+ }
+ /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
+ beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif);
if (!beacon) {
- IWL_ERR(priv, "update beacon failed\n");
- return;
+ IWL_ERR(priv, "update beacon failed -- keeping old\n");
+ goto out;
}
- mutex_lock(&priv->mutex);
/* new beacon skb is allocated every time; dispose previous.*/
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
+ dev_kfree_skb(priv->beacon_skb);
- priv->ibss_beacon = beacon;
- mutex_unlock(&priv->mutex);
+ priv->beacon_skb = beacon;
iwl_send_beacon_cmd(priv);
+ out:
+ mutex_unlock(&priv->mutex);
+}
+
+static void iwl_bg_bt_runtime_config(struct work_struct *work)
+{
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, bt_runtime_config);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ /* dont send host command if rf-kill is on */
+ if (!iwl_is_ready_rf(priv))
+ return;
+ priv->cfg->ops->hcmd->send_bt_config(priv);
+}
+
+static void iwl_bg_bt_full_concurrency(struct work_struct *work)
+{
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, bt_full_concurrency);
+ struct iwl_rxon_context *ctx;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ /* dont send host command if rf-kill is on */
+ if (!iwl_is_ready_rf(priv))
+ return;
+
+ IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
+ priv->bt_full_concurrent ?
+ "full concurrency" : "3-wire");
+
+ /*
+ * 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);
}
/**
@@ -763,10 +864,10 @@ static void iwl_bg_ucode_trace(unsigned long data)
static void iwl_rx_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl4965_beacon_notif *beacon =
(struct iwl4965_beacon_notif *)pkt->u.raw;
+#ifdef CONFIG_IWLWIFI_DEBUG
u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
@@ -778,8 +879,9 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
le32_to_cpu(beacon->low_tsf), rate);
#endif
- if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
- (!test_bit(STATUS_EXIT_PENDING, &priv->status)))
+ priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
+
+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
queue_work(priv->workqueue, &priv->beacon_update);
}
@@ -836,22 +938,6 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
wake_up_interruptible(&priv->wait_command_queue);
}
-int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
-{
- if (src == IWL_PWR_SRC_VAUX) {
- if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
- iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
- APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
- ~APMG_PS_CTRL_MSK_PWR_SRC);
- } else {
- iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
- APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
- ~APMG_PS_CTRL_MSK_PWR_SRC);
- }
-
- return 0;
-}
-
static void iwl_bg_tx_flush(struct work_struct *work)
{
struct iwl_priv *priv =
@@ -1181,7 +1267,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
IWL_ERR(priv, "Microcode SW error detected. "
" Restarting 0x%X.\n", inta);
priv->isr_stats.sw++;
- priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -1362,7 +1447,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
IWL_ERR(priv, "Microcode SW error detected. "
" Restarting 0x%X.\n", inta);
priv->isr_stats.sw++;
- priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -1650,30 +1734,44 @@ static void iwl_nic_start(struct iwl_priv *priv)
struct iwlagn_ucode_capabilities {
u32 max_probe_length;
u32 standard_phy_calibration_size;
+ bool pan;
};
static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
static int iwl_mac_setup_register(struct iwl_priv *priv,
struct iwlagn_ucode_capabilities *capa);
+#define UCODE_EXPERIMENTAL_INDEX 100
+#define UCODE_EXPERIMENTAL_TAG "exp"
+
static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
{
const char *name_pre = priv->cfg->fw_name_pre;
+ char tag[8];
- if (first)
+ if (first) {
+#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
+ priv->fw_index = UCODE_EXPERIMENTAL_INDEX;
+ strcpy(tag, UCODE_EXPERIMENTAL_TAG);
+ } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) {
+#endif
priv->fw_index = priv->cfg->ucode_api_max;
- else
+ sprintf(tag, "%d", priv->fw_index);
+ } else {
priv->fw_index--;
+ sprintf(tag, "%d", priv->fw_index);
+ }
if (priv->fw_index < priv->cfg->ucode_api_min) {
IWL_ERR(priv, "no suitable firmware found!\n");
return -ENOENT;
}
- sprintf(priv->firmware_name, "%s%d%s",
- name_pre, priv->fw_index, ".ucode");
+ sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
- IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n",
+ IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n",
+ (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+ ? "EXPERIMENTAL " : "",
priv->firmware_name);
return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
@@ -1874,6 +1972,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
capa->max_probe_length =
le32_to_cpup((__le32 *)tlv_data);
break;
+ case IWL_UCODE_TLV_PAN:
+ if (tlv_len)
+ goto invalid_tlv_len;
+ capa->pan = true;
+ break;
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
if (tlv_len != sizeof(u32))
goto invalid_tlv_len;
@@ -1962,14 +2065,16 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
struct iwlagn_ucode_capabilities ucode_capa = {
.max_probe_length = 200,
.standard_phy_calibration_size =
- IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE,
+ IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
};
memset(&pieces, 0, sizeof(pieces));
if (!ucode_raw) {
- IWL_ERR(priv, "request for firmware file '%s' failed.\n",
- priv->firmware_name);
+ if (priv->fw_index <= priv->cfg->ucode_api_max)
+ IWL_ERR(priv,
+ "request for firmware file '%s' failed.\n",
+ priv->firmware_name);
goto try_again;
}
@@ -2002,21 +2107,28 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
* firmware filename ... but we don't check for that and only rely
* on the API version read from firmware header from here on forward
*/
- if (api_ver < api_min || api_ver > api_max) {
- IWL_ERR(priv, "Driver unable to support your firmware API. "
- "Driver supports v%u, firmware is v%u.\n",
- api_max, api_ver);
- goto try_again;
- }
+ /* no api version check required for experimental uCode */
+ if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
+ if (api_ver < api_min || api_ver > api_max) {
+ IWL_ERR(priv,
+ "Driver unable to support your firmware API. "
+ "Driver supports v%u, firmware is v%u.\n",
+ api_max, api_ver);
+ goto try_again;
+ }
- if (api_ver != api_max)
- IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
- "got v%u. New firmware can be obtained "
- "from http://www.intellinuxwireless.org.\n",
- api_max, api_ver);
+ if (api_ver != api_max)
+ IWL_ERR(priv,
+ "Firmware has old API version. Expected v%u, "
+ "got v%u. New firmware can be obtained "
+ "from http://www.intellinuxwireless.org.\n",
+ api_max, api_ver);
+ }
if (build)
- sprintf(buildstr, " build %u", build);
+ sprintf(buildstr, " build %u%s", build,
+ (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+ ? " (EXP)" : "");
else
buildstr[0] = '\0';
@@ -2136,15 +2248,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
if (pieces.init_evtlog_size)
priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
else
- priv->_agn.init_evtlog_size = priv->cfg->max_event_log_size;
+ priv->_agn.init_evtlog_size =
+ priv->cfg->base_params->max_event_log_size;
priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr;
priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr;
if (pieces.inst_evtlog_size)
priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
else
- priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size;
+ priv->_agn.inst_evtlog_size =
+ priv->cfg->base_params->max_event_log_size;
priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
+ if (ucode_capa.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) */
@@ -2341,6 +2461,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
}
desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
+ 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));
@@ -2543,6 +2664,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
return pos;
}
+ /* enable/disable bt channel announcement */
+ priv->bt_ch_announce = iwlagn_bt_ch_announce;
+
#ifdef CONFIG_IWLWIFI_DEBUG
if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log)
size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
@@ -2589,6 +2713,69 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
return pos;
}
+static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
+{
+ struct iwl_ct_kill_config cmd;
+ struct iwl_ct_kill_throttling_config adv_cmd;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+ CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ priv->thermal_throttle.ct_kill_toggle = false;
+
+ if (priv->cfg->base_params->support_ct_kill_exit) {
+ adv_cmd.critical_temperature_enter =
+ cpu_to_le32(priv->hw_params.ct_kill_threshold);
+ adv_cmd.critical_temperature_exit =
+ cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
+
+ ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
+ sizeof(adv_cmd), &adv_cmd);
+ if (ret)
+ IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
+ else
+ IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
+ "succeeded, "
+ "critical temperature enter is %d,"
+ "exit is %d\n",
+ priv->hw_params.ct_kill_threshold,
+ priv->hw_params.ct_kill_exit_threshold);
+ } else {
+ cmd.critical_temperature_R =
+ cpu_to_le32(priv->hw_params.ct_kill_threshold);
+
+ ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
+ sizeof(cmd), &cmd);
+ if (ret)
+ IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
+ else
+ IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
+ "succeeded, "
+ "critical temperature is %d\n",
+ priv->hw_params.ct_kill_threshold);
+ }
+}
+
+static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
+{
+ struct iwl_calib_cfg_cmd calib_cfg_cmd;
+ struct iwl_host_cmd cmd = {
+ .id = CALIBRATION_CFG_CMD,
+ .len = sizeof(struct iwl_calib_cfg_cmd),
+ .data = &calib_cfg_cmd,
+ };
+
+ memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
+ calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
+ calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
+
+ return iwl_send_cmd(priv, &cmd);
+}
+
+
/**
* iwl_alive_start - called after REPLY_ALIVE notification received
* from protocol/runtime uCode (initialization uCode's
@@ -2597,6 +2784,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
static void 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");
@@ -2624,6 +2812,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
goto restart;
}
+
/* After the ALIVE response, we can send host commands to the uCode */
set_bit(STATUS_ALIVE, &priv->status);
@@ -2631,12 +2820,33 @@ static void iwl_alive_start(struct iwl_priv *priv)
/* Enable timer to monitor the driver queues */
mod_timer(&priv->monitor_recover,
jiffies +
- msecs_to_jiffies(priv->cfg->monitor_recover_period));
+ msecs_to_jiffies(
+ priv->cfg->base_params->monitor_recover_period));
}
if (iwl_is_rfkill(priv))
return;
+ /* download priority table before any calibration request */
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ /* Configure Bluetooth device coexistence support */
+ priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
+ priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
+ priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
+ priv->cfg->ops->hcmd->send_bt_config(priv);
+ priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
+ 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);
+ }
+ if (priv->hw_params.calib_rt_cfg)
+ iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
+
ieee80211_wake_queues(priv->hw);
priv->active_rate = IWL_RATES_MASK;
@@ -2645,27 +2855,32 @@ static void iwl_alive_start(struct iwl_priv *priv)
if (priv->cfg->ops->hcmd->set_tx_ant)
priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant);
- if (iwl_is_associated(priv)) {
+ if (iwl_is_associated_ctx(ctx)) {
struct iwl_rxon_cmd *active_rxon =
- (struct iwl_rxon_cmd *)&priv->active_rxon;
+ (struct iwl_rxon_cmd *)&ctx->active;
/* apply any changes in staging */
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
+ struct iwl_rxon_context *tmp;
/* Initialize our rx_config data */
- iwl_connection_init_rx_config(priv, NULL);
+ for_each_context(priv, tmp)
+ iwl_connection_init_rx_config(priv, tmp);
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
}
- /* Configure Bluetooth device coexistence support */
- priv->cfg->ops->hcmd->send_bt_config(priv);
+ if (priv->cfg->bt_params &&
+ !priv->cfg->bt_params->advanced_bt_coexist) {
+ /* Configure Bluetooth device coexistence support */
+ priv->cfg->ops->hcmd->send_bt_config(priv);
+ }
iwl_reset_run_time_calib(priv);
/* Configure the adapter for unassociated operation */
- iwlcore_commit_rxon(priv);
+ iwlcore_commit_rxon(priv, ctx);
/* At this point, the NIC is initialized and operational */
iwl_rf_kill_ct_config(priv);
@@ -2695,13 +2910,30 @@ static void __iwl_down(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
- if (!exit_pending)
- set_bit(STATUS_EXIT_PENDING, &priv->status);
+ iwl_scan_cancel_timeout(priv, 200);
- iwl_clear_ucode_stations(priv);
- iwl_dealloc_bcast_station(priv);
+ exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
+
+ /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
+ * to prevent rearm timer */
+ if (priv->cfg->ops->lib->recover_from_tx_stall)
+ del_timer_sync(&priv->monitor_recover);
+
+ iwl_clear_ucode_stations(priv, NULL);
+ iwl_dealloc_bcast_stations(priv);
iwl_clear_driver_stations(priv);
+ /* reset BT coex data */
+ priv->bt_status = 0;
+ if (priv->cfg->bt_params)
+ priv->bt_traffic_load =
+ priv->cfg->bt_params->bt_init_traffic_load;
+ else
+ priv->bt_traffic_load = 0;
+ priv->bt_sco_active = false;
+ priv->bt_full_concurrent = false;
+ priv->bt_ci_compliance = 0;
+
/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2759,14 +2991,13 @@ static void __iwl_down(struct iwl_priv *priv)
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 */
- priv->cfg->ops->lib->apm_ops.stop(priv);
+ iwl_apm_stop(priv);
exit:
memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
- priv->ibss_beacon = NULL;
+ dev_kfree_skb(priv->beacon_skb);
+ priv->beacon_skb = NULL;
/* clear out any free frames */
iwl_clear_free_frames(priv);
@@ -2834,6 +3065,7 @@ 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;
@@ -2847,9 +3079,13 @@ static int __iwl_up(struct iwl_priv *priv)
return -EIO;
}
- ret = iwl_alloc_bcast_station(priv, true);
- if (ret)
- return ret;
+ for_each_context(priv, ctx) {
+ ret = iwlagn_alloc_bcast_station(priv, ctx);
+ if (ret) {
+ iwl_dealloc_bcast_stations(priv);
+ return ret;
+ }
+ }
iwl_prepare_card_hw(priv);
@@ -2874,6 +3110,12 @@ static int __iwl_up(struct iwl_priv *priv)
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);
if (ret) {
IWL_ERR(priv, "Unable to init nic\n");
@@ -2980,7 +3222,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
}
if (priv->start_calib) {
- if (priv->cfg->bt_statistics) {
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_statistics) {
iwl_chain_noise_calibration(priv,
(void *)&priv->_agn.statistics_bt);
iwl_sensitivity_calibration(priv,
@@ -3004,11 +3247,42 @@ 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_sco, bt_full_concurrent;
+ u8 bt_ci_compliance;
+ u8 bt_load;
+ u8 bt_status;
+
mutex_lock(&priv->mutex);
- priv->vif = NULL;
+ 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_sco = priv->bt_sco_active;
+ 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_sco_active = bt_sco;
+ 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;
+
mutex_unlock(&priv->mutex);
- iwl_down(priv);
+ iwl_cancel_deferred_work(priv);
ieee80211_restart_hw(priv->hw);
} else {
iwl_down(priv);
@@ -3039,12 +3313,15 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
+ struct iwl_rxon_context *ctx;
struct ieee80211_conf *conf = NULL;
int ret = 0;
if (!vif || !priv->is_open)
return;
+ ctx = iwl_rxon_ctx_from_vif(vif);
+
if (vif->type == NL80211_IFTYPE_AP) {
IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
@@ -3057,44 +3334,42 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
conf = ieee80211_get_hw_conf(priv->hw);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
- iwl_setup_rxon_timing(priv, vif);
- ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing), &priv->rxon_timing);
+ ret = iwl_send_rxon_timing(priv, ctx);
if (ret)
- IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "RXON timing - "
"Attempting to continue.\n");
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwl_set_rxon_ht(priv, &priv->current_ht_config);
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+ ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
vif->bss_conf.aid, vif->bss_conf.beacon_int);
if (vif->bss_conf.use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
}
- iwlcore_commit_rxon(priv);
+ iwlcore_commit_rxon(priv, ctx);
IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
- vif->bss_conf.aid, priv->active_rxon.bssid_addr);
+ vif->bss_conf.aid, ctx->active.bssid_addr);
switch (vif->type) {
case NL80211_IFTYPE_STATION:
@@ -3137,14 +3412,17 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
{
int ret;
struct ieee80211_hw *hw = priv->hw;
+ struct iwl_rxon_context *ctx;
+
hw->rate_control_algorithm = "iwl-agn-rs";
/* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_AMPDU_AGGREGATION |
+ IEEE80211_HW_NEED_DTIM_PERIOD |
IEEE80211_HW_SPECTRUM_MGMT;
- if (!priv->cfg->broken_powersave)
+ if (!priv->cfg->base_params->broken_powersave)
hw->flags |= IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
@@ -3155,9 +3433,10 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
hw->sta_data_size = sizeof(struct iwl_station_priv);
hw->vif_data_size = sizeof(struct iwl_vif_priv);
- hw->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC);
+ for_each_context(priv, ctx) {
+ hw->wiphy->interface_modes |= ctx->interface_modes;
+ hw->wiphy->interface_modes |= ctx->exclusive_interface_modes;
+ }
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS;
@@ -3247,15 +3526,6 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
priv->is_open = 0;
- if (iwl_is_ready_rf(priv) || test_bit(STATUS_SCAN_HW, &priv->status)) {
- /* stop mac, cancel any scan request and clear
- * RXON_FILTER_ASSOC_MSK BIT
- */
- mutex_lock(&priv->mutex);
- iwl_scan_cancel_timeout(priv, 100);
- mutex_unlock(&priv->mutex);
- }
-
iwl_down(priv);
flush_workqueue(priv->workqueue);
@@ -3285,24 +3555,25 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
int ret = 0;
+ lockdep_assert_held(&priv->mutex);
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
/* The following should be done only at AP bring up */
- if (!iwl_is_associated(priv)) {
+ if (!iwl_is_associated_ctx(ctx)) {
/* RXON - unassoc (to set timing command) */
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
/* RXON Timing */
- iwl_setup_rxon_timing(priv, vif);
- ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing), &priv->rxon_timing);
+ ret = iwl_send_rxon_timing(priv, ctx);
if (ret)
- IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "RXON timing failed - "
"Attempting to continue.\n");
/* AP has all antennas */
@@ -3310,28 +3581,30 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
priv->hw_params.valid_rx_ant;
iwl_set_rxon_ht(priv, &priv->current_ht_config);
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- priv->staging_rxon.assoc_id = 0;
+ ctx->staging.assoc_id = 0;
if (vif->bss_conf.use_short_preamble)
- priv->staging_rxon.flags |=
+ ctx->staging.flags |=
RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &=
+ ctx->staging.flags &=
~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- priv->staging_rxon.flags |=
+ ctx->staging.flags |=
RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &=
+ ctx->staging.flags &=
~RXON_FLG_SHORT_SLOT_MSK;
}
+ /* need to send beacon cmd before committing assoc RXON! */
+ iwl_send_beacon_cmd(priv);
/* restore RXON assoc */
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
}
iwl_send_beacon_cmd(priv);
@@ -3348,9 +3621,11 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+
IWL_DEBUG_MAC80211(priv, "enter\n");
- iwl_update_tkip_key(priv, keyconf, sta,
+ iwl_update_tkip_key(priv, vif_priv->ctx, keyconf, sta,
iv32, phase1key);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -3362,6 +3637,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+ struct iwl_rxon_context *ctx = vif_priv->ctx;
int ret;
u8 sta_id;
bool is_default_wep_key = false;
@@ -3373,7 +3650,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return -EOPNOTSUPP;
}
- sta_id = iwl_sta_id_or_broadcast(priv, sta);
+ sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta);
if (sta_id == IWL_INVALID_STATION)
return -EINVAL;
@@ -3386,9 +3663,11 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
* in 1X mode.
* In legacy wep mode, we use another host command to the uCode.
*/
- if (key->alg == ALG_WEP && !sta && vif->type != NL80211_IFTYPE_AP) {
+ if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
+ !sta) {
if (cmd == SET_KEY)
- is_default_wep_key = !priv->key_mapping_key;
+ is_default_wep_key = !ctx->key_mapping_keys;
else
is_default_wep_key =
(key->hw_key_idx == HW_KEY_DEFAULT);
@@ -3397,17 +3676,18 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
switch (cmd) {
case SET_KEY:
if (is_default_wep_key)
- ret = iwl_set_default_wep_key(priv, key);
+ ret = iwl_set_default_wep_key(priv, vif_priv->ctx, key);
else
- ret = iwl_set_dynamic_key(priv, key, sta_id);
+ ret = iwl_set_dynamic_key(priv, vif_priv->ctx,
+ key, sta_id);
IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
break;
case DISABLE_KEY:
if (is_default_wep_key)
- ret = iwl_remove_default_wep_key(priv, key);
+ ret = iwl_remove_default_wep_key(priv, ctx, key);
else
- ret = iwl_remove_dynamic_key(priv, key, sta_id);
+ ret = iwl_remove_dynamic_key(priv, ctx, key, sta_id);
IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
break;
@@ -3467,7 +3747,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
}
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
ret = 0;
- if (priv->cfg->use_rts_for_aggregation) {
+ if (priv->cfg->ht_params &&
+ priv->cfg->ht_params->use_rts_for_aggregation) {
struct iwl_station_priv *sta_priv =
(void *) sta->drv_priv;
/*
@@ -3476,12 +3757,13 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
sta_priv->lq_sta.lq.general_params.flags &=
~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
- iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq,
- CMD_ASYNC, false);
+ iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
+ &sta_priv->lq_sta.lq, CMD_ASYNC, false);
}
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
- if (priv->cfg->use_rts_for_aggregation) {
+ if (priv->cfg->ht_params &&
+ priv->cfg->ht_params->use_rts_for_aggregation) {
struct iwl_station_priv *sta_priv =
(void *) sta->drv_priv;
@@ -3492,8 +3774,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
sta_priv->lq_sta.lq.general_params.flags |=
LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
- iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq,
- CMD_ASYNC, false);
+ iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
+ &sta_priv->lq_sta.lq, CMD_ASYNC, false);
}
ret = 0;
break;
@@ -3539,6 +3821,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
bool is_ap = vif->type == NL80211_IFTYPE_STATION;
int ret;
u8 sta_id;
@@ -3554,8 +3837,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_AP)
sta_priv->client = true;
- ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
- &sta_id);
+ ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr,
+ is_ap, sta, &sta_id);
if (ret) {
IWL_ERR(priv, "Unable to add station %pM (%d)\n",
sta->addr, ret);
@@ -3581,7 +3864,17 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
struct iwl_priv *priv = hw->priv;
const struct iwl_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf;
+ struct ieee80211_channel *channel = ch_switch->channel;
struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+ /*
+ * MULTI-FIXME
+ * When we add support for multiple interfaces, we need to
+ * revisit this. The channel switch command in the device
+ * only affects the BSS context, but what does that really
+ * mean? And what if we get a CSA on the second interface?
+ * This needs a lot of work.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
u16 ch;
unsigned long flags = 0;
@@ -3594,7 +3887,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
test_bit(STATUS_SCANNING, &priv->status))
goto out_exit;
- if (!iwl_is_associated(priv))
+ if (!iwl_is_associated_ctx(ctx))
goto out_exit;
/* channel switch in progress */
@@ -3604,11 +3897,10 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (priv->cfg->ops->lib->set_channel_switch) {
- ch = ieee80211_frequency_to_channel(
- ch_switch->channel->center_freq);
- if (le16_to_cpu(priv->active_rxon.channel) != ch) {
+ ch = channel->hw_value;
+ if (le16_to_cpu(ctx->active.channel) != ch) {
ch_info = iwl_get_channel_info(priv,
- conf->channel->band,
+ channel->band,
ch);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_MAC80211(priv, "invalid channel\n");
@@ -3619,34 +3911,31 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
priv->current_ht_config.smps = conf->smps_mode;
/* Configure HT40 channels */
- ht_conf->is_ht = conf_is_ht(conf);
- if (ht_conf->is_ht) {
+ ctx->ht.enabled = conf_is_ht(conf);
+ if (ctx->ht.enabled) {
if (conf_is_ht40_minus(conf)) {
- ht_conf->extension_chan_offset =
+ ctx->ht.extension_chan_offset =
IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- ht_conf->is_40mhz = true;
+ ctx->ht.is_40mhz = true;
} else if (conf_is_ht40_plus(conf)) {
- ht_conf->extension_chan_offset =
+ ctx->ht.extension_chan_offset =
IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
- ht_conf->is_40mhz = true;
+ ctx->ht.is_40mhz = true;
} else {
- ht_conf->extension_chan_offset =
+ ctx->ht.extension_chan_offset =
IEEE80211_HT_PARAM_CHA_SEC_NONE;
- ht_conf->is_40mhz = false;
+ ctx->ht.is_40mhz = false;
}
} else
- ht_conf->is_40mhz = false;
+ ctx->ht.is_40mhz = false;
- /* if we are switching from ht to 2.4 clear flags
- * from any ht related info since 2.4 does not
- * support ht */
- if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
- priv->staging_rxon.flags = 0;
+ if ((le16_to_cpu(ctx->staging.channel) != ch))
+ ctx->staging.flags = 0;
- iwl_set_rxon_channel(priv, conf->channel);
+ iwl_set_rxon_channel(priv, channel, ctx);
iwl_set_rxon_ht(priv, ht_conf);
- iwl_set_flags_for_band(priv, conf->channel->band,
- priv->vif);
+ iwl_set_flags_for_band(priv, ctx, channel->band,
+ ctx->vif);
spin_unlock_irqrestore(&priv->lock, flags);
iwl_set_rate(priv);
@@ -3663,7 +3952,7 @@ out:
mutex_unlock(&priv->mutex);
out_exit:
if (!priv->switch_rxon.switch_in_progress)
- ieee80211_chswitch_done(priv->vif, false);
+ ieee80211_chswitch_done(ctx->vif, false);
IWL_DEBUG_MAC80211(priv, "leave\n");
}
@@ -3674,6 +3963,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
__le32 filter_or = 0, filter_nand = 0;
+ struct iwl_rxon_context *ctx;
#define CHK(test, flag) do { \
if (*total_flags & (test)) \
@@ -3693,10 +3983,11 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
- priv->staging_rxon.filter_flags &= ~filter_nand;
- priv->staging_rxon.filter_flags |= filter_or;
-
- iwlcore_commit_rxon(priv);
+ for_each_context(priv, ctx) {
+ ctx->staging.filter_flags &= ~filter_nand;
+ ctx->staging.filter_flags |= filter_or;
+ iwlcore_commit_rxon(priv, ctx);
+ }
mutex_unlock(&priv->mutex);
@@ -3765,6 +4056,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
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);
@@ -3788,7 +4081,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
priv->cfg->ops->lib->recover_from_tx_stall;
}
- if (!priv->cfg->use_isr_legacy)
+ if (!priv->cfg->base_params->use_isr_legacy)
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
iwl_irq_tasklet, (unsigned long)priv);
else
@@ -3802,15 +4095,17 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
priv->cfg->ops->lib->cancel_deferred_work(priv);
cancel_delayed_work_sync(&priv->init_alive_start);
- cancel_delayed_work(&priv->scan_check);
- cancel_work_sync(&priv->start_internal_scan);
cancel_delayed_work(&priv->alive_start);
cancel_work_sync(&priv->run_time_calib_work);
cancel_work_sync(&priv->beacon_update);
+
+ iwl_cancel_scan_deferred_work(priv);
+
+ cancel_work_sync(&priv->bt_full_concurrency);
+ cancel_work_sync(&priv->bt_runtime_config);
+
del_timer_sync(&priv->statistics_periodic);
del_timer_sync(&priv->ucode_trace);
- if (priv->cfg->ops->lib->recover_from_tx_stall)
- del_timer_sync(&priv->monitor_recover);
}
static void iwl_init_hw_rates(struct iwl_priv *priv,
@@ -3838,8 +4133,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
{
int ret;
- priv->ibss_beacon = NULL;
-
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
@@ -3865,10 +4158,23 @@ static int iwl_init_drv(struct iwl_priv *priv)
/* Choose which receivers/antennas to use */
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
iwl_init_scan_params(priv);
+ /* init bt coex */
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
+ priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
+ priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
+ priv->bt_on_thresh = BT_ON_THRESHOLD_DEF;
+ priv->bt_duration = BT_DURATION_LIMIT_DEF;
+ priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
+ priv->dynamic_agg_thresh = BT_AGG_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 */
@@ -3923,11 +4229,60 @@ static struct ieee80211_ops iwl_hw_ops = {
.sta_remove = iwl_mac_sta_remove,
.channel_switch = iwl_mac_channel_switch,
.flush = iwl_mac_flush,
+ .tx_last_beacon = iwl_mac_tx_last_beacon,
+};
+
+static void 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);
+ pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id);
+ IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id);
+}
+
+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)
+ 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)
+ priv->cfg->sku &= ~IWL_SKU_N;
+
+ /* Device-specific setup */
+ return priv->cfg->ops->lib->set_hw_params(priv);
+}
+
+static const u8 iwlagn_bss_ac_to_fifo[] = {
+ IWL_TX_FIFO_VO,
+ IWL_TX_FIFO_VI,
+ IWL_TX_FIFO_BE,
+ IWL_TX_FIFO_BK,
+};
+
+static const u8 iwlagn_bss_ac_to_queue[] = {
+ 0, 1, 2, 3,
+};
+
+static const u8 iwlagn_pan_ac_to_fifo[] = {
+ IWL_TX_FIFO_VO_IPAN,
+ IWL_TX_FIFO_VI_IPAN,
+ IWL_TX_FIFO_BE_IPAN,
+ IWL_TX_FIFO_BK_IPAN,
+};
+
+static const u8 iwlagn_pan_ac_to_queue[] = {
+ 7, 6, 5, 4,
};
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int err = 0;
+ int err = 0, i;
struct iwl_priv *priv;
struct ieee80211_hw *hw;
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
@@ -3941,9 +4296,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* 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) {
- if (iwl_debug_level & IWL_DL_INFO)
- dev_printk(KERN_DEBUG, &(pdev->dev),
- "Disabling hw_scan\n");
+ dev_printk(KERN_DEBUG, &(pdev->dev),
+ "sw scan support is deprecated\n");
iwl_hw_ops.hw_scan = NULL;
}
@@ -3955,6 +4309,53 @@ 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. */
+ /*
+ * The default context is always valid,
+ * more may be discovered when firmware
+ * is loaded.
+ */
+ priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
+
+ for (i = 0; i < NUM_IWL_RXON_CTX; i++)
+ priv->contexts[i].ctxid = i;
+
+ priv->contexts[IWL_RXON_CTX_BSS].always_active = true;
+ priv->contexts[IWL_RXON_CTX_BSS].is_active = true;
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
+ priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
+ priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
+ priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
+ priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
+ priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
+ BIT(NL80211_IFTYPE_ADHOC);
+ priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
+ BIT(NL80211_IFTYPE_STATION);
+ priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
+ priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
+ priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
+
+ priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
+ priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING;
+ priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = REPLY_WIPAN_RXON_ASSOC;
+ priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM;
+ priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN;
+ priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
+ priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
+ priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
+ priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
+ priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
+ priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
+ priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
+ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
+ priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
+ priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
+ priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;
+
+ BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+
SET_IEEE80211_DEV(hw, &pdev->dev);
IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
@@ -3962,12 +4363,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
priv->pci_dev = pdev;
priv->inta_mask = CSR_INI_SET_MASK;
+ /* is antenna coupling more than 35dB ? */
+ priv->bt_ant_couple_ok =
+ (iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
+ true : false;
+
+ /* enable/disable bt channel announcement */
+ priv->bt_ch_announce = iwlagn_bt_ch_announce;
+
if (iwl_alloc_traffic_mem(priv))
IWL_ERR(priv, "Not enough memory to generate traffic log\n");
/**************************
* 2. Initializing PCI bus
**************************/
+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+ PCIE_LINK_STATE_CLKPM);
+
if (pci_enable_device(pdev)) {
err = -ENODEV;
goto out_ieee80211_free_hw;
@@ -4190,7 +4602,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
* paths to avoid running iwl_down() at all before leaving driver.
* This (inexpensive) call *makes sure* device is reset.
*/
- priv->cfg->ops->lib->apm_ops.stop(priv);
+ iwl_apm_stop(priv);
iwl_tt_exit(priv);
@@ -4233,8 +4645,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
iwl_free_isr_ict(priv);
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
+ dev_kfree_skb(priv->beacon_skb);
ieee80211_free_hw(priv->hw);
}
@@ -4398,6 +4809,22 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)},
{IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)},
{IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)},
+
+/* 100 Series WiFi */
+ {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)},
+ {IWL_PCI_DEVICE(0x08AE, 0x1017, iwl100_bg_cfg)},
+
+/* 130 Series WiFi */
+ {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)},
+
#endif /* CONFIG_IWL5000 */
{0}
@@ -4486,9 +4913,18 @@ 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)");
+MODULE_PARM_DESC(disable_hw_scan,
+ "disable hardware scanning (default 0) (deprecated)");
module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
S_IRUGO);
MODULE_PARM_DESC(ucode_alternative,
"specify ucode alternative to use from ucode file");
+
+module_param_named(antenna_coupling, iwlagn_ant_coupling, int, S_IRUGO);
+MODULE_PARM_DESC(antenna_coupling,
+ "specify antenna coupling in dB (defualt: 0 dB)");
+
+module_param_named(bt_ch_announce, iwlagn_bt_ch_announce, bool, S_IRUGO);
+MODULE_PARM_DESC(bt_ch_announce,
+ "Enable BT channel announcement mode (default: enable)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index cc6464dc72e5..f525d55f2c0f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -92,9 +92,14 @@ extern struct iwl_cfg iwl6050_2abg_cfg;
extern struct iwl_cfg iwl6050g2_bgn_cfg;
extern struct iwl_cfg iwl1000_bgn_cfg;
extern struct iwl_cfg iwl1000_bg_cfg;
+extern struct iwl_cfg iwl100_bgn_cfg;
+extern struct iwl_cfg iwl100_bg_cfg;
+extern struct iwl_cfg iwl130_bgn_cfg;
+extern struct iwl_cfg iwl130_bg_cfg;
extern struct iwl_mod_params iwlagn_mod_params;
extern struct iwl_hcmd_ops iwlagn_hcmd;
+extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
int iwl_reset_ict(struct iwl_priv *priv);
@@ -124,6 +129,10 @@ 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);
+/* RXON */
+int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+
/* uCode */
int iwlagn_load_ucode(struct iwl_priv *priv);
void iwlagn_rx_calib_result(struct iwl_priv *priv,
@@ -133,6 +142,8 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv,
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);
+void iwlagn_send_prio_tbl(struct iwl_priv *priv);
/* lib */
void iwl_check_abort_status(struct iwl_priv *priv,
@@ -151,6 +162,8 @@ 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);
@@ -164,8 +177,15 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_handle(struct iwl_priv *priv);
/* tx */
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len, u8 reset, u8 pad);
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
struct ieee80211_tx_info *info);
int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
@@ -205,6 +225,8 @@ static inline bool iwl_is_tx_success(u32 status)
(status == TX_STATUS_DIRECT_DONE);
}
+u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
+
/* rx */
void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
@@ -216,14 +238,84 @@ void iwl_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
/* scan */
-void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+void iwlagn_post_scan(struct iwl_priv *priv);
/* station mgmt */
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);
+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);
+/* bt coex */
+void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
+void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv);
+void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
+void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+const char *iwl_get_tx_fail_reason(u32 status);
+const char *iwl_get_agg_tx_fail_reason(u16 status);
+#else
+static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
+static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; }
+#endif
+
+/* station management */
+int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
+int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, u8 *sta_id_r);
+int iwl_remove_default_wep_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *key);
+int iwl_set_default_wep_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *key);
+int iwl_restore_default_wep_keys(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
+int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *key, u8 sta_id);
+int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *key, u8 sta_id);
+void iwl_update_tkip_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
+int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
+int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
+ int tid, u16 ssn);
+int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
+ int tid);
+void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
+void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
+int iwl_update_bcast_stations(struct iwl_priv *priv);
+
+/* rate */
+static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
+{
+ return BIT(ant_idx) << RATE_MCS_ANT_POS;
+}
+
+static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
+{
+ return le32_to_cpu(rate_n_flags) & 0xFF;
+}
+
+static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
+{
+ return cpu_to_le32(flags|(u32)rate);
+}
+
+/* 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);
+
#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 60725a5c1b69..424801abc80e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -62,7 +62,7 @@
*****************************************************************************/
/*
* Please use this file (iwl-commands.h) only for uCode API definitions.
- * Please use iwl-4965-hw.h for hardware-related definitions.
+ * Please use iwl-xxxx-hw.h for hardware-related definitions.
* Please use iwl-dev.h for driver implementation definitions.
*/
@@ -173,6 +173,23 @@ enum {
REPLY_RX_MPDU_CMD = 0xc1,
REPLY_RX = 0xc3,
REPLY_COMPRESSED_BA = 0xc5,
+
+ /* BT Coex */
+ REPLY_BT_COEX_PRIO_TABLE = 0xcc,
+ REPLY_BT_COEX_PROT_ENV = 0xcd,
+ REPLY_BT_COEX_PROFILE_NOTIF = 0xce,
+ REPLY_BT_COEX_SCO = 0xcf,
+
+ /* PAN commands */
+ REPLY_WIPAN_PARAMS = 0xb2,
+ REPLY_WIPAN_RXON = 0xb3, /* use REPLY_RXON structure */
+ REPLY_WIPAN_RXON_TIMING = 0xb4, /* use REPLY_RXON_TIMING structure */
+ REPLY_WIPAN_RXON_ASSOC = 0xb6, /* use REPLY_RXON_ASSOC structure */
+ REPLY_WIPAN_QOS_PARAM = 0xb7, /* use REPLY_QOS_PARAM structure */
+ REPLY_WIPAN_WEPKEY = 0xb8, /* use REPLY_WEPKEY structure */
+ REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9,
+ REPLY_WIPAN_NOA_NOTIFICATION = 0xbc,
+
REPLY_MAX = 0xff
};
@@ -403,12 +420,12 @@ struct iwl4965_tx_power_db {
/**
* Command REPLY_TX_POWER_DBM_CMD = 0x98
- * struct iwl5000_tx_power_dbm_cmd
+ * struct iwlagn_tx_power_dbm_cmd
*/
-#define IWL50_TX_POWER_AUTO 0x7f
-#define IWL50_TX_POWER_NO_CLOSED (0x1 << 6)
+#define IWLAGN_TX_POWER_AUTO 0x7f
+#define IWLAGN_TX_POWER_NO_CLOSED (0x1 << 6)
-struct iwl5000_tx_power_dbm_cmd {
+struct iwlagn_tx_power_dbm_cmd {
s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
u8 flags;
s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
@@ -600,6 +617,9 @@ enum {
RXON_DEV_TYPE_ESS = 3,
RXON_DEV_TYPE_IBSS = 4,
RXON_DEV_TYPE_SNIFFER = 6,
+ RXON_DEV_TYPE_CP = 7,
+ RXON_DEV_TYPE_2STA = 8,
+ RXON_DEV_TYPE_P2P = 9,
};
@@ -816,7 +836,8 @@ struct iwl_rxon_time_cmd {
__le16 atim_window;
__le32 beacon_init_val;
__le16 listen_interval;
- __le16 reserved;
+ u8 dtim_period;
+ u8 delta_cp_bss_tbtts;
} __packed;
/*
@@ -953,11 +974,13 @@ struct iwl_qosparam_cmd {
/* Special, dedicated locations within device's station table */
#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
@@ -966,6 +989,7 @@ struct iwl_qosparam_cmd {
#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2)
#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8)
+#define STA_FLG_PAN_STATION cpu_to_le32(1 << 13)
#define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17)
#define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18)
#define STA_FLG_MAX_AGG_SIZE_POS (19)
@@ -994,6 +1018,7 @@ struct iwl_qosparam_cmd {
#define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000)
#define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000)
#define STA_KEY_MAX_NUM 8
+#define STA_KEY_MAX_NUM_PAN 16
/* Flags indicate whether to modify vs. don't change various station params */
#define STA_MODIFY_KEY_MASK 0x01
@@ -1017,7 +1042,7 @@ struct iwl4965_keyinfo {
u8 key[16]; /* 16-byte unicast decryption key */
} __packed;
-/* 5000 */
+/* agn */
struct iwl_keyinfo {
__le16 key_flags;
u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */
@@ -1056,7 +1081,8 @@ struct sta_id_modify {
*
* The device contains an internal table of per-station information,
* with info on security keys, aggregation parameters, and Tx rates for
- * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD,
+ * 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
@@ -1142,7 +1168,7 @@ struct iwl4965_addsta_cmd {
__le16 reserved2;
} __packed;
-/* 5000 */
+/* agn */
struct iwl_addsta_cmd {
u8 mode; /* 1: modify existing, 0: add new station */
u8 reserved[3];
@@ -1367,21 +1393,24 @@ struct iwl4965_rx_non_cfg_phy {
} __packed;
-#define IWL50_RX_RES_PHY_CNT 8
-#define IWL50_RX_RES_AGC_IDX 1
-#define IWL50_RX_RES_RSSI_AB_IDX 2
-#define IWL50_RX_RES_RSSI_C_IDX 3
-#define IWL50_OFDM_AGC_MSK 0xfe00
-#define IWL50_OFDM_AGC_BIT_POS 9
-#define IWL50_OFDM_RSSI_A_MSK 0x00ff
-#define IWL50_OFDM_RSSI_A_BIT_POS 0
-#define IWL50_OFDM_RSSI_B_MSK 0xff0000
-#define IWL50_OFDM_RSSI_B_BIT_POS 16
-#define IWL50_OFDM_RSSI_C_MSK 0x00ff
-#define IWL50_OFDM_RSSI_C_BIT_POS 0
+#define IWLAGN_RX_RES_PHY_CNT 8
+#define IWLAGN_RX_RES_AGC_IDX 1
+#define IWLAGN_RX_RES_RSSI_AB_IDX 2
+#define IWLAGN_RX_RES_RSSI_C_IDX 3
+#define IWLAGN_OFDM_AGC_MSK 0xfe00
+#define IWLAGN_OFDM_AGC_BIT_POS 9
+#define IWLAGN_OFDM_RSSI_INBAND_A_BITMSK 0x00ff
+#define IWLAGN_OFDM_RSSI_ALLBAND_A_BITMSK 0xff00
+#define IWLAGN_OFDM_RSSI_A_BIT_POS 0
+#define IWLAGN_OFDM_RSSI_INBAND_B_BITMSK 0xff0000
+#define IWLAGN_OFDM_RSSI_ALLBAND_B_BITMSK 0xff000000
+#define IWLAGN_OFDM_RSSI_B_BIT_POS 16
+#define IWLAGN_OFDM_RSSI_INBAND_C_BITMSK 0x00ff
+#define IWLAGN_OFDM_RSSI_ALLBAND_C_BITMSK 0xff00
+#define IWLAGN_OFDM_RSSI_C_BIT_POS 0
-struct iwl5000_non_cfg_phy {
- __le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT]; /* up to 8 phy entries */
+struct iwlagn_non_cfg_phy {
+ __le32 non_cfg_phy[IWLAGN_RX_RES_PHY_CNT]; /* up to 8 phy entries */
} __packed;
@@ -1401,7 +1430,7 @@ struct iwl_rx_phy_res {
u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */
__le32 rate_n_flags; /* RATE_MCS_* */
__le16 byte_count; /* frame's byte-count */
- __le16 reserved3;
+ __le16 frame_time; /* frame's time on the air */
} __packed;
struct iwl_rx_mpdu_res_start {
@@ -1424,12 +1453,12 @@ struct iwl_rx_mpdu_res_start {
* uCode handles all timing and protocol related to control frames
* (RTS/CTS/ACK), based on flags in the Tx command. uCode and Tx scheduler
* handle reception of block-acks; uCode updates the host driver via
- * REPLY_COMPRESSED_BA (4965).
+ * REPLY_COMPRESSED_BA.
*
* uCode handles retrying Tx when an ACK is expected but not received.
* This includes trying lower data rates than the one requested in the Tx
* command, as set up by the REPLY_RATE_SCALE (for 3945) or
- * REPLY_TX_LINK_QUALITY_CMD (4965).
+ * REPLY_TX_LINK_QUALITY_CMD (agn).
*
* Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD.
* This command must be executed after every RXON command, before Tx can occur.
@@ -1465,7 +1494,7 @@ struct iwl_rx_mpdu_res_start {
* Set this for unicast frames, but not broadcast/multicast. */
#define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3)
-/* For 4965:
+/* For agn devices:
* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD).
* Tx command's initial_rate_index indicates first rate to try;
* uCode walks through table for additional Tx attempts.
@@ -1484,7 +1513,7 @@ struct iwl_rx_mpdu_res_start {
*/
#define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7)
-/* Tx antenna selection field; used only for 3945, reserved (0) for 4965.
+/* Tx antenna selection field; used only for 3945, reserved (0) for agn devices.
* Set field to "0" to allow 3945 uCode to select antenna (normal usage). */
#define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00)
#define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
@@ -1791,13 +1820,8 @@ enum {
TX_STATUS_FAIL_TID_DISABLE = 0x8d,
TX_STATUS_FAIL_FIFO_FLUSHED = 0x8e,
TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
- /* uCode drop due to FW drop request */
- TX_STATUS_FAIL_FW_DROP = 0x90,
- /*
- * uCode drop due to station color mismatch
- * between tx command and station table
- */
- TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP = 0x91,
+ TX_STATUS_FAIL_PASSIVE_NO_RX = 0x90,
+ TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
};
#define TX_PACKET_MODE_REGULAR 0x0000
@@ -1839,6 +1863,9 @@ enum {
AGG_TX_STATE_DELAY_TX_MSK = 0x400
};
+#define AGG_TX_STATUS_MSK 0x00000fff /* bits 0:11 */
+#define AGG_TX_TRY_MSK 0x0000f000 /* bits 12:15 */
+
#define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \
AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \
AGG_TX_STATE_LAST_SENT_BT_KILL_MSK)
@@ -1867,9 +1894,10 @@ enum {
* frame in this new agg block failed in previous agg block(s).
*
* Note that, for aggregation, ACK (block-ack) status is not delivered here;
- * block-ack has not been received by the time the 4965 records this status.
+ * block-ack has not been received by the time the agn device records
+ * this status.
* This status relates to reasons the tx might have been blocked or aborted
- * within the sending station (this 4965), rather than whether it was
+ * within the sending station (this agn device), rather than whether it was
* received successfully by the destination station.
*/
struct agg_tx_status {
@@ -1931,12 +1959,12 @@ struct iwl4965_tx_resp {
#define IWL50_TX_RES_INV_RATE_INDEX_MSK 0x80
/* refer to ra_tid */
-#define IWL50_TX_RES_TID_POS 0
-#define IWL50_TX_RES_TID_MSK 0x0f
-#define IWL50_TX_RES_RA_POS 4
-#define IWL50_TX_RES_RA_MSK 0xf0
+#define IWLAGN_TX_RES_TID_POS 0
+#define IWLAGN_TX_RES_TID_MSK 0x0f
+#define IWLAGN_TX_RES_RA_POS 4
+#define IWLAGN_TX_RES_RA_MSK 0xf0
-struct iwl5000_tx_resp {
+struct iwlagn_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 */
@@ -2092,8 +2120,8 @@ struct iwl_link_qual_general_params {
} __packed;
#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
-#define LINK_QUAL_AGG_TIME_LIMIT_MAX (65535)
-#define LINK_QUAL_AGG_TIME_LIMIT_MIN (0)
+#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
+#define LINK_QUAL_AGG_TIME_LIMIT_MIN (100)
#define LINK_QUAL_AGG_DISABLE_START_DEF (3)
#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
@@ -2110,8 +2138,10 @@ struct iwl_link_qual_general_params {
*/
struct iwl_link_qual_agg_params {
- /* Maximum number of uSec in aggregation.
- * Driver should set this to 4000 (4 milliseconds). */
+ /*
+ *Maximum number of uSec in aggregation.
+ * default set to 4000 (4 milliseconds) if not configured in .cfg
+ */
__le16 agg_time_limit;
/*
@@ -2135,14 +2165,16 @@ struct iwl_link_qual_agg_params {
/*
* REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response)
*
- * For 4965 only; 3945 uses REPLY_RATE_SCALE.
+ * For agn devices only; 3945 uses REPLY_RATE_SCALE.
*
- * Each station in the 4965's internal station table has its own table of 16
+ * Each station in the agn device's internal station table has its own table
+ * of 16
* Tx rates and modulation modes (e.g. legacy/SISO/MIMO) for retrying Tx when
* an ACK is not received. This command replaces the entire table for
* one station.
*
- * NOTE: Station must already be in 4965's station table. Use REPLY_ADD_STA.
+ * NOTE: Station must already be in agn device's station table.
+ * Use REPLY_ADD_STA.
*
* The rate scaling procedures described below work well. Of course, other
* procedures are possible, and may work better for particular environments.
@@ -2179,12 +2211,12 @@ struct iwl_link_qual_agg_params {
*
* ACCUMULATING HISTORY
*
- * The rate scaling algorithm for 4965, as implemented in Linux driver, uses
- * two sets of frame Tx success history: One for the current/active modulation
- * mode, and one for a speculative/search mode that is being attempted. If the
- * speculative mode turns out to be more effective (i.e. actual transfer
- * rate is better), then the driver continues to use the speculative mode
- * as the new current active mode.
+ * The rate scaling algorithm for agn devices, as implemented in Linux driver,
+ * uses two sets of frame Tx success history: One for the current/active
+ * modulation mode, and one for a speculative/search mode that is being
+ * attempted. If the speculative mode turns out to be more effective (i.e.
+ * actual transfer rate is better), then the driver continues to use the
+ * speculative mode as the new current active mode.
*
* Each history set contains, separately for each possible rate, data for a
* sliding window of the 62 most recent tx attempts at that rate. The data
@@ -2195,12 +2227,12 @@ struct iwl_link_qual_agg_params {
* The driver uses the bit map to remove successes from the success sum, as
* the oldest tx attempts fall out of the window.
*
- * When the 4965 makes multiple tx attempts for a given frame, each attempt
- * might be at a different rate, and have different modulation characteristics
- * (e.g. antenna, fat channel, short guard interval), as set up in the rate
- * scaling table in the Link Quality command. The driver must determine
- * which rate table entry was used for each tx attempt, to determine which
- * rate-specific history to update, and record only those attempts that
+ * When the agn device makes multiple tx attempts for a given frame, each
+ * attempt might be at a different rate, and have different modulation
+ * characteristics (e.g. antenna, fat channel, short guard interval), as set
+ * up in the rate scaling table in the Link Quality command. The driver must
+ * determine which rate table entry was used for each tx attempt, to determine
+ * which rate-specific history to update, and record only those attempts that
* match the modulation characteristics of the history set.
*
* When using block-ack (aggregation), all frames are transmitted at the same
@@ -2330,7 +2362,7 @@ struct iwl_link_quality_cmd {
/*
* Rate info; when using rate-scaling, Tx command's initial_rate_index
* specifies 1st Tx rate attempted, via index into this table.
- * 4965 works its way through table when retrying Tx.
+ * agn devices works its way through table when retrying Tx.
*/
struct {
__le32 rate_n_flags; /* RATE_MCS_*, IWL_RATE_* */
@@ -2363,10 +2395,26 @@ struct iwl_link_quality_cmd {
#define BT_MAX_KILL_DEF (0x5)
#define BT_MAX_KILL_MAX (0xFF)
+#define BT_DURATION_LIMIT_DEF 625
+#define BT_DURATION_LIMIT_MAX 1250
+#define BT_DURATION_LIMIT_MIN 625
+
+#define BT_ON_THRESHOLD_DEF 4
+#define BT_ON_THRESHOLD_MAX 1000
+#define BT_ON_THRESHOLD_MIN 1
+
+#define BT_FRAG_THRESHOLD_DEF 0
+#define BT_FRAG_THRESHOLD_MAX 0
+#define BT_FRAG_THRESHOLD_MIN 0
+
+#define BT_AGG_THRESHOLD_DEF 0
+#define BT_AGG_THRESHOLD_MAX 0
+#define BT_AGG_THRESHOLD_MIN 0
+
/*
* REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
*
- * 3945 and 4965 support hardware handshake with Bluetooth device on
+ * 3945 and agn devices support hardware handshake with Bluetooth device on
* same platform. Bluetooth device alerts wireless device when it will Tx;
* wireless device can delay or kill its own Tx to accommodate.
*/
@@ -2379,6 +2427,79 @@ struct iwl_bt_cmd {
__le32 kill_cts_mask;
} __packed;
+#define IWLAGN_BT_FLAG_CHANNEL_INHIBITION BIT(0)
+
+#define IWLAGN_BT_FLAG_COEX_MODE_MASK (BIT(3)|BIT(4)|BIT(5))
+#define IWLAGN_BT_FLAG_COEX_MODE_SHIFT 3
+#define IWLAGN_BT_FLAG_COEX_MODE_DISABLED 0
+#define IWLAGN_BT_FLAG_COEX_MODE_LEGACY_2W 1
+#define IWLAGN_BT_FLAG_COEX_MODE_3W 2
+#define IWLAGN_BT_FLAG_COEX_MODE_4W 3
+
+#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6)
+#define IWLAGN_BT_FLAG_NOCOEX_NOTIF BIT(7)
+
+#define IWLAGN_BT_PRIO_BOOST_MAX 0xFF
+#define IWLAGN_BT_PRIO_BOOST_MIN 0x00
+#define IWLAGN_BT_PRIO_BOOST_DEFAULT 0xF0
+
+#define IWLAGN_BT_MAX_KILL_DEFAULT 5
+
+#define IWLAGN_BT3_T7_DEFAULT 1
+
+#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff)
+#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff)
+
+#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2
+
+#define IWLAGN_BT3_T2_DEFAULT 0xc
+
+#define IWLAGN_BT_VALID_ENABLE_FLAGS cpu_to_le16(BIT(0))
+#define IWLAGN_BT_VALID_BOOST cpu_to_le16(BIT(1))
+#define IWLAGN_BT_VALID_MAX_KILL cpu_to_le16(BIT(2))
+#define IWLAGN_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3))
+#define IWLAGN_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4))
+#define IWLAGN_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5))
+#define IWLAGN_BT_VALID_BT4_TIMES cpu_to_le16(BIT(6))
+#define IWLAGN_BT_VALID_3W_LUT cpu_to_le16(BIT(7))
+
+#define IWLAGN_BT_ALL_VALID_MSK (IWLAGN_BT_VALID_ENABLE_FLAGS | \
+ IWLAGN_BT_VALID_BOOST | \
+ IWLAGN_BT_VALID_MAX_KILL | \
+ IWLAGN_BT_VALID_3W_TIMERS | \
+ IWLAGN_BT_VALID_KILL_ACK_MASK | \
+ IWLAGN_BT_VALID_KILL_CTS_MASK | \
+ IWLAGN_BT_VALID_BT4_TIMES | \
+ IWLAGN_BT_VALID_3W_LUT)
+
+struct iwlagn_bt_cmd {
+ u8 flags;
+ u8 ledtime; /* unused */
+ u8 max_kill;
+ u8 bt3_timer_t7_value;
+ __le32 kill_ack_mask;
+ __le32 kill_cts_mask;
+ u8 bt3_prio_sample_time;
+ u8 bt3_timer_t2_value;
+ __le16 bt4_reaction_time; /* unused */
+ __le32 bt3_lookup_table[12];
+ __le16 bt4_decision_time; /* unused */
+ __le16 valid;
+ u8 prio_boost;
+ /*
+ * set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask
+ * if configure the following patterns
+ */
+ u8 tx_prio_boost; /* SW boost of WiFi tx priority */
+ __le16 rx_prio_boost; /* SW boost of WiFi rx priority */
+};
+
+#define IWLAGN_BT_SCO_ACTIVE cpu_to_le32(BIT(0))
+
+struct iwlagn_bt_sco_cmd {
+ __le32 flags;
+};
+
/******************************************************************************
* (6)
* Spectrum Management (802.11h) Commands, Responses, Notifications:
@@ -2567,7 +2688,7 @@ struct iwl_powertable_cmd {
/*
* PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
- * 3945 and 4965 identical.
+ * all devices identical.
*/
struct iwl_sleep_notification {
u8 pm_sleep_mode;
@@ -2578,7 +2699,7 @@ struct iwl_sleep_notification {
__le32 bcon_timer;
} __packed;
-/* Sleep states. 3945 and 4965 identical. */
+/* Sleep states. all devices identical. */
enum {
IWL_PM_NO_SLEEP = 0,
IWL_PM_SLP_MAC = 1,
@@ -2887,6 +3008,12 @@ struct iwl_scanstart_notification {
#define SCAN_OWNER_STATUS 0x1;
#define MEASURE_OWNER_STATUS 0x2;
+#define IWL_PROBE_STATUS_OK 0
+#define IWL_PROBE_STATUS_TX_FAILED BIT(0)
+/* error statuses combined with TX_FAILED */
+#define IWL_PROBE_STATUS_FAIL_TTL BIT(1)
+#define IWL_PROBE_STATUS_FAIL_BT BIT(2)
+
#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */
/*
* SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
@@ -2894,7 +3021,8 @@ struct iwl_scanstart_notification {
struct iwl_scanresults_notification {
u8 channel;
u8 band;
- u8 reserved[2];
+ u8 probe_status;
+ u8 num_probe_not_sent; /* not enough time to send */
__le32 tsf_low;
__le32 tsf_high;
__le32 statistics[NUMBER_OF_STATISTICS];
@@ -2906,7 +3034,7 @@ struct iwl_scanresults_notification {
struct iwl_scancomplete_notification {
u8 scanned_channels;
u8 status;
- u8 reserved;
+ u8 bt_status; /* BT On/Off status */
u8 last_channel;
__le32 tsf_low;
__le32 tsf_high;
@@ -2919,6 +3047,11 @@ struct iwl_scancomplete_notification {
*
*****************************************************************************/
+enum iwl_ibss_manager {
+ IWL_NOT_IBSS_MANAGER = 0,
+ IWL_IBSS_MANAGER = 1,
+};
+
/*
* BEACON_NOTIFICATION = 0x90 (notification only, not a command)
*/
@@ -3260,7 +3393,7 @@ struct statistics_general_bt {
/*
* REPLY_STATISTICS_CMD = 0x9c,
- * 3945 and 4965 identical.
+ * all devices identical.
*
* This command triggers an immediate response containing uCode statistics.
* The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below.
@@ -3598,7 +3731,7 @@ struct iwl_enhance_sensitivity_cmd {
/**
* REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response)
*
- * This command sets the relative gains of 4965's 3 radio receiver chains.
+ * This command sets the relative gains of agn device's 3 radio receiver chains.
*
* After the first association, driver should accumulate signal and noise
* statistics from the STATISTICS_NOTIFICATIONs that follow the first 20
@@ -3651,7 +3784,8 @@ struct iwl_enhance_sensitivity_cmd {
*/
/* Phy calibration command for series */
-
+/* The default calibrate table size if not specified by firmware */
+#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18
enum {
IWL_PHY_CALIBRATE_DIFF_GAIN_CMD = 7,
IWL_PHY_CALIBRATE_DC_CMD = 8,
@@ -3660,13 +3794,29 @@ enum {
IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15,
IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16,
IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17,
- IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 18,
+ IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18,
+ IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19,
};
#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253)
#define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff)
+/* This enum defines the bitmap of various calibrations to enable in both
+ * init ucode and runtime ucode through CALIBRATION_CFG_CMD.
+ */
+enum iwl_ucode_calib_cfg {
+ IWL_CALIB_CFG_RX_BB_IDX,
+ IWL_CALIB_CFG_DC_IDX,
+ IWL_CALIB_CFG_TX_IQ_IDX,
+ IWL_CALIB_CFG_RX_IQ_IDX,
+ IWL_CALIB_CFG_NOISE_IDX,
+ IWL_CALIB_CFG_CRYSTAL_IDX,
+ IWL_CALIB_CFG_TEMPERATURE_IDX,
+ IWL_CALIB_CFG_PAPD_IDX,
+};
+
+
struct iwl_calib_cfg_elmnt_s {
__le32 is_enable;
__le32 start;
@@ -3715,6 +3865,13 @@ struct iwl_calib_xtal_freq_cmd {
u8 pad[2];
} __packed;
+#define DEFAULT_RADIO_SENSOR_OFFSET 2700
+struct iwl_calib_temperature_offset_cmd {
+ struct iwl_calib_hdr hdr;
+ s16 radio_sensor_offset;
+ s16 reserved;
+} __packed;
+
/* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
struct iwl_calib_chain_noise_reset_cmd {
struct iwl_calib_hdr hdr;
@@ -3955,6 +4112,201 @@ struct iwl_coex_event_resp {
/******************************************************************************
+ * Bluetooth Coexistence commands
+ *
+ *****************************************************************************/
+
+/*
+ * BT Status notification
+ * REPLY_BT_COEX_PROFILE_NOTIF = 0xce
+ */
+enum iwl_bt_coex_profile_traffic_load {
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0,
+ IWL_BT_COEX_TRAFFIC_LOAD_LOW = 1,
+ IWL_BT_COEX_TRAFFIC_LOAD_HIGH = 2,
+ IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS = 3,
+/*
+ * There are no more even though below is a u8, the
+ * indication from the BT device only has two bits.
+ */
+};
+
+#define BT_UART_MSG_FRAME1MSGTYPE_POS (0)
+#define BT_UART_MSG_FRAME1MSGTYPE_MSK \
+ (0x7 << BT_UART_MSG_FRAME1MSGTYPE_POS)
+#define BT_UART_MSG_FRAME1SSN_POS (3)
+#define BT_UART_MSG_FRAME1SSN_MSK \
+ (0x3 << BT_UART_MSG_FRAME1SSN_POS)
+#define BT_UART_MSG_FRAME1UPDATEREQ_POS (5)
+#define BT_UART_MSG_FRAME1UPDATEREQ_MSK \
+ (0x1 << BT_UART_MSG_FRAME1UPDATEREQ_POS)
+#define BT_UART_MSG_FRAME1RESERVED_POS (6)
+#define BT_UART_MSG_FRAME1RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME1RESERVED_POS)
+
+#define BT_UART_MSG_FRAME2OPENCONNECTIONS_POS (0)
+#define BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK \
+ (0x3 << BT_UART_MSG_FRAME2OPENCONNECTIONS_POS)
+#define BT_UART_MSG_FRAME2TRAFFICLOAD_POS (2)
+#define BT_UART_MSG_FRAME2TRAFFICLOAD_MSK \
+ (0x3 << BT_UART_MSG_FRAME2TRAFFICLOAD_POS)
+#define BT_UART_MSG_FRAME2CHLSEQN_POS (4)
+#define BT_UART_MSG_FRAME2CHLSEQN_MSK \
+ (0x1 << BT_UART_MSG_FRAME2CHLSEQN_POS)
+#define BT_UART_MSG_FRAME2INBAND_POS (5)
+#define BT_UART_MSG_FRAME2INBAND_MSK \
+ (0x1 << BT_UART_MSG_FRAME2INBAND_POS)
+#define BT_UART_MSG_FRAME2RESERVED_POS (6)
+#define BT_UART_MSG_FRAME2RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME2RESERVED_POS)
+
+#define BT_UART_MSG_FRAME3SCOESCO_POS (0)
+#define BT_UART_MSG_FRAME3SCOESCO_MSK \
+ (0x1 << BT_UART_MSG_FRAME3SCOESCO_POS)
+#define BT_UART_MSG_FRAME3SNIFF_POS (1)
+#define BT_UART_MSG_FRAME3SNIFF_MSK \
+ (0x1 << BT_UART_MSG_FRAME3SNIFF_POS)
+#define BT_UART_MSG_FRAME3A2DP_POS (2)
+#define BT_UART_MSG_FRAME3A2DP_MSK \
+ (0x1 << BT_UART_MSG_FRAME3A2DP_POS)
+#define BT_UART_MSG_FRAME3ACL_POS (3)
+#define BT_UART_MSG_FRAME3ACL_MSK \
+ (0x1 << BT_UART_MSG_FRAME3ACL_POS)
+#define BT_UART_MSG_FRAME3MASTER_POS (4)
+#define BT_UART_MSG_FRAME3MASTER_MSK \
+ (0x1 << BT_UART_MSG_FRAME3MASTER_POS)
+#define BT_UART_MSG_FRAME3OBEX_POS (5)
+#define BT_UART_MSG_FRAME3OBEX_MSK \
+ (0x1 << BT_UART_MSG_FRAME3OBEX_POS)
+#define BT_UART_MSG_FRAME3RESERVED_POS (6)
+#define BT_UART_MSG_FRAME3RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME3RESERVED_POS)
+
+#define BT_UART_MSG_FRAME4IDLEDURATION_POS (0)
+#define BT_UART_MSG_FRAME4IDLEDURATION_MSK \
+ (0x3F << BT_UART_MSG_FRAME4IDLEDURATION_POS)
+#define BT_UART_MSG_FRAME4RESERVED_POS (6)
+#define BT_UART_MSG_FRAME4RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME4RESERVED_POS)
+
+#define BT_UART_MSG_FRAME5TXACTIVITY_POS (0)
+#define BT_UART_MSG_FRAME5TXACTIVITY_MSK \
+ (0x3 << BT_UART_MSG_FRAME5TXACTIVITY_POS)
+#define BT_UART_MSG_FRAME5RXACTIVITY_POS (2)
+#define BT_UART_MSG_FRAME5RXACTIVITY_MSK \
+ (0x3 << BT_UART_MSG_FRAME5RXACTIVITY_POS)
+#define BT_UART_MSG_FRAME5ESCORETRANSMIT_POS (4)
+#define BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK \
+ (0x3 << BT_UART_MSG_FRAME5ESCORETRANSMIT_POS)
+#define BT_UART_MSG_FRAME5RESERVED_POS (6)
+#define BT_UART_MSG_FRAME5RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME5RESERVED_POS)
+
+#define BT_UART_MSG_FRAME6SNIFFINTERVAL_POS (0)
+#define BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK \
+ (0x1F << BT_UART_MSG_FRAME6SNIFFINTERVAL_POS)
+#define BT_UART_MSG_FRAME6DISCOVERABLE_POS (5)
+#define BT_UART_MSG_FRAME6DISCOVERABLE_MSK \
+ (0x1 << BT_UART_MSG_FRAME6DISCOVERABLE_POS)
+#define BT_UART_MSG_FRAME6RESERVED_POS (6)
+#define BT_UART_MSG_FRAME6RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME6RESERVED_POS)
+
+#define BT_UART_MSG_FRAME7SNIFFACTIVITY_POS (0)
+#define BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK \
+ (0x7 << BT_UART_MSG_FRAME7SNIFFACTIVITY_POS)
+#define BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS (3)
+#define BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK \
+ (0x3 << BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS)
+#define BT_UART_MSG_FRAME7CONNECTABLE_POS (5)
+#define BT_UART_MSG_FRAME7CONNECTABLE_MSK \
+ (0x1 << BT_UART_MSG_FRAME7CONNECTABLE_POS)
+#define BT_UART_MSG_FRAME7RESERVED_POS (6)
+#define BT_UART_MSG_FRAME7RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME7RESERVED_POS)
+
+
+struct iwl_bt_uart_msg {
+ u8 header;
+ u8 frame1;
+ u8 frame2;
+ u8 frame3;
+ u8 frame4;
+ u8 frame5;
+ u8 frame6;
+ u8 frame7;
+} __attribute__((packed));
+
+struct iwl_bt_coex_profile_notif {
+ struct iwl_bt_uart_msg last_bt_uart_msg;
+ u8 bt_status; /* 0 - off, 1 - on */
+ u8 bt_traffic_load; /* 0 .. 3? */
+ u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */
+ u8 reserved;
+} __attribute__((packed));
+
+#define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0
+#define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1
+#define IWL_BT_COEX_PRIO_TBL_PRIO_POS 1
+#define IWL_BT_COEX_PRIO_TBL_PRIO_MASK 0x0e
+#define IWL_BT_COEX_PRIO_TBL_RESERVED_POS 4
+#define IWL_BT_COEX_PRIO_TBL_RESERVED_MASK 0xf0
+#define IWL_BT_COEX_PRIO_TBL_PRIO_SHIFT 1
+
+/*
+ * BT Coexistence Priority table
+ * REPLY_BT_COEX_PRIO_TABLE = 0xcc
+ */
+enum bt_coex_prio_table_events {
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0,
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1,
+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2,
+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3, /* DC calib */
+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4,
+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5,
+ BT_COEX_PRIO_TBL_EVT_DTIM = 6,
+ BT_COEX_PRIO_TBL_EVT_SCAN52 = 7,
+ BT_COEX_PRIO_TBL_EVT_SCAN24 = 8,
+ BT_COEX_PRIO_TBL_EVT_RESERVED0 = 9,
+ BT_COEX_PRIO_TBL_EVT_RESERVED1 = 10,
+ BT_COEX_PRIO_TBL_EVT_RESERVED2 = 11,
+ BT_COEX_PRIO_TBL_EVT_RESERVED3 = 12,
+ BT_COEX_PRIO_TBL_EVT_RESERVED4 = 13,
+ BT_COEX_PRIO_TBL_EVT_RESERVED5 = 14,
+ BT_COEX_PRIO_TBL_EVT_RESERVED6 = 15,
+ /* BT_COEX_PRIO_TBL_EVT_MAX should always be last */
+ BT_COEX_PRIO_TBL_EVT_MAX,
+};
+
+enum bt_coex_prio_table_priorities {
+ BT_COEX_PRIO_TBL_DISABLED = 0,
+ BT_COEX_PRIO_TBL_PRIO_LOW = 1,
+ BT_COEX_PRIO_TBL_PRIO_HIGH = 2,
+ BT_COEX_PRIO_TBL_PRIO_BYPASS = 3,
+ BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4,
+ BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5,
+ BT_COEX_PRIO_TBL_PRIO_RSRVD1 = 6,
+ BT_COEX_PRIO_TBL_PRIO_RSRVD2 = 7,
+ BT_COEX_PRIO_TBL_MAX,
+};
+
+struct iwl_bt_coex_prio_table_cmd {
+ u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];
+} __attribute__((packed));
+
+#define IWL_BT_COEX_ENV_CLOSE 0
+#define IWL_BT_COEX_ENV_OPEN 1
+/*
+ * BT Protection Envelope
+ * REPLY_BT_COEX_PROT_ENV = 0xcd
+ */
+struct iwl_bt_coex_prot_env_cmd {
+ u8 action; /* 0 = closed, 1 = open */
+ u8 type; /* 0 .. 15 */
+ u8 reserved[2];
+} __attribute__((packed));
+
+/******************************************************************************
* (13)
* Union of all expected notifications/responses:
*
@@ -3993,6 +4345,7 @@ struct iwl_rx_packet {
struct iwl_missed_beacon_notif missed_beacon;
struct iwl_coex_medium_notification coex_medium_notif;
struct iwl_coex_event_resp coex_event;
+ struct iwl_bt_coex_profile_notif bt_coex_profile_notif;
__le32 status;
u8 raw[0];
} u;
@@ -4000,4 +4353,94 @@ struct iwl_rx_packet {
int iwl_agn_check_rxon_cmd(struct iwl_priv *priv);
+/*
+ * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification)
+ */
+
+/**
+ * struct iwl_wipan_slot
+ * @width: Time in TU
+ * @type:
+ * 0 - BSS
+ * 1 - PAN
+ */
+struct iwl_wipan_slot {
+ __le16 width;
+ u8 type;
+ u8 reserved;
+} __packed;
+
+#define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_CTS BIT(1) /* reserved */
+#define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_QUIET BIT(2) /* reserved */
+#define IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE BIT(3) /* reserved */
+#define IWL_WIPAN_PARAMS_FLG_FILTER_BEACON_NOTIF BIT(4)
+#define IWL_WIPAN_PARAMS_FLG_FULL_SLOTTED_MODE BIT(5)
+
+/**
+ * struct iwl_wipan_params_cmd
+ * @flags:
+ * bit0: reserved
+ * bit1: CP leave channel with CTS
+ * bit2: CP leave channel qith Quiet
+ * bit3: slotted mode
+ * 1 - work in slotted mode
+ * 0 - work in non slotted mode
+ * bit4: filter beacon notification
+ * bit5: full tx slotted mode. if this flag is set,
+ * uCode will perform leaving channel methods in context switch
+ * also when working in same channel mode
+ * @num_slots: 1 - 10
+ */
+struct iwl_wipan_params_cmd {
+ __le16 flags;
+ u8 reserved;
+ u8 num_slots;
+ struct iwl_wipan_slot slots[10];
+} __packed;
+
+/*
+ * REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9
+ *
+ * TODO: Figure out what this is used for,
+ * it can only switch between 2.4 GHz
+ * channels!!
+ */
+
+struct iwl_wipan_p2p_channel_switch_cmd {
+ __le16 channel;
+ __le16 reserved;
+};
+
+/*
+ * REPLY_WIPAN_NOA_NOTIFICATION = 0xbc
+ *
+ * This is used by the device to notify us of the
+ * NoA schedule it determined so we can forward it
+ * to userspace for inclusion in probe responses.
+ *
+ * In beacons, the NoA schedule is simply appended
+ * to the frame we give the device.
+ */
+
+struct iwl_wipan_noa_descriptor {
+ u8 count;
+ __le32 duration;
+ __le32 interval;
+ __le32 starttime;
+} __packed;
+
+struct iwl_wipan_noa_attribute {
+ u8 id;
+ __le16 length;
+ u8 index;
+ u8 ct_window;
+ struct iwl_wipan_noa_descriptor descr0, descr1;
+ u8 reserved;
+} __packed;
+
+struct iwl_wipan_noa_notification {
+ u32 noa_active;
+ struct iwl_wipan_noa_attribute noa_attribute;
+} __packed;
+
#endif /* __iwl_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e23c4060a0f0..25fb3912342c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -64,97 +64,14 @@ MODULE_LICENSE("GPL");
*
* default: bt_coex_active = true (BT_COEX_ENABLE)
*/
-static bool bt_coex_active = true;
+bool bt_coex_active = true;
+EXPORT_SYMBOL_GPL(bt_coex_active);
module_param(bt_coex_active, bool, S_IRUGO);
MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
-#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
- [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
- IWL_RATE_SISO_##s##M_PLCP, \
- IWL_RATE_MIMO2_##s##M_PLCP,\
- IWL_RATE_MIMO3_##s##M_PLCP,\
- IWL_RATE_##r##M_IEEE, \
- IWL_RATE_##ip##M_INDEX, \
- IWL_RATE_##in##M_INDEX, \
- IWL_RATE_##rp##M_INDEX, \
- IWL_RATE_##rn##M_INDEX, \
- IWL_RATE_##pp##M_INDEX, \
- IWL_RATE_##np##M_INDEX }
-
u32 iwl_debug_level;
EXPORT_SYMBOL(iwl_debug_level);
-/*
- * Parameter order:
- * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
- *
- * If there isn't a valid next or previous rate then INV is used which
- * maps to IWL_RATE_INVALID
- *
- */
-const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
- IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */
- IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */
- IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */
- IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */
- IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */
- IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */
- IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */
- IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */
- IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */
- IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */
- IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */
- IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
- IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
- /* FIXME:RS: ^^ should be INV (legacy) */
-};
-EXPORT_SYMBOL(iwl_rates);
-
-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);
-
- if (idx >= IWL_RATE_MIMO3_6M_PLCP)
- idx = idx - IWL_RATE_MIMO3_6M_PLCP;
- else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
- idx = idx - IWL_RATE_MIMO2_6M_PLCP;
-
- idx += IWL_FIRST_OFDM_RATE;
- /* skip 9M not supported in ht*/
- if (idx >= IWL_RATE_9M_INDEX)
- idx += 1;
- if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
- return idx;
-
- /* 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))
- return idx;
- }
-
- return -1;
-}
-EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
-
-u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
-{
- int i;
- u8 ind = ant;
-
- for (i = 0; i < RATE_ANT_NUM - 1; i++) {
- ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0;
- if (valid & BIT(ind))
- return ind;
- }
- return ant;
-}
-EXPORT_SYMBOL(iwl_toggle_tx_ant);
-
const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
EXPORT_SYMBOL(iwl_bcast_addr);
@@ -183,38 +100,33 @@ out:
}
EXPORT_SYMBOL(iwl_alloc_all);
-void 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);
- pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id);
-}
-EXPORT_SYMBOL(iwl_hw_detect);
-
/*
* QoS support
*/
-static void iwl_update_qos(struct iwl_priv *priv)
+static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- priv->qos_data.def_qos_parm.qos_flags = 0;
+ if (!ctx->is_active)
+ return;
+
+ ctx->qos_data.def_qos_parm.qos_flags = 0;
- if (priv->qos_data.qos_active)
- priv->qos_data.def_qos_parm.qos_flags |=
+ if (ctx->qos_data.qos_active)
+ ctx->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;
- if (priv->current_ht_config.is_ht)
- priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+ if (ctx->ht.enabled)
+ ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
- priv->qos_data.qos_active,
- priv->qos_data.def_qos_parm.qos_flags);
+ ctx->qos_data.qos_active,
+ ctx->qos_data.def_qos_parm.qos_flags);
- iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
+ iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
sizeof(struct iwl_qosparam_cmd),
- &priv->qos_data.def_qos_parm, NULL);
+ &ctx->qos_data.def_qos_parm, NULL);
}
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
@@ -232,7 +144,8 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
ht_info->ht_supported = true;
- if (priv->cfg->ht_greenfield_support)
+ if (priv->cfg->ht_params &&
+ priv->cfg->ht_params->ht_greenfield_support)
ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
max_bit_rate = MAX_BIT_RATE_20_MHZ;
@@ -247,7 +160,11 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
+ if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_factor)
+ ht_info->ampdu_factor = priv->cfg->bt_params->ampdu_factor;
ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
+ if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_density)
+ ht_info->ampdu_density = priv->cfg->bt_params->ampdu_density;
ht_info->mcs.rx_mask[0] = 0xFF;
if (rx_chains_num >= 2)
@@ -434,21 +351,15 @@ void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
EXPORT_SYMBOL(iwlcore_tx_cmd_protection);
-static bool is_single_rx_stream(struct iwl_priv *priv)
-{
- return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
- priv->current_ht_config.single_chain_sufficient;
-}
-
-static u8 iwl_is_channel_extension(struct iwl_priv *priv,
- enum ieee80211_band band,
- u16 channel, u8 extension_chan_offset)
+static bool iwl_is_channel_extension(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u16 channel, u8 extension_chan_offset)
{
const struct iwl_channel_info *ch_info;
ch_info = iwl_get_channel_info(priv, band, channel);
if (!is_channel_valid(ch_info))
- return 0;
+ return false;
if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
return !(ch_info->ht40_extension_channel &
@@ -457,38 +368,59 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv,
return !(ch_info->ht40_extension_channel &
IEEE80211_CHAN_NO_HT40MINUS);
- return 0;
+ return false;
}
-u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
- struct ieee80211_sta_ht_cap *sta_ht_inf)
+bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_sta_ht_cap *ht_cap)
{
- struct iwl_ht_config *ht_conf = &priv->current_ht_config;
-
- if (!ht_conf->is_ht || !ht_conf->is_40mhz)
- return 0;
+ if (!ctx->ht.enabled || !ctx->ht.is_40mhz)
+ return false;
- /* We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
+ /*
+ * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
* the bit will not set if it is pure 40MHz case
*/
- if (sta_ht_inf) {
- if (!sta_ht_inf->ht_supported)
- return 0;
- }
+ if (ht_cap && !ht_cap->ht_supported)
+ return false;
+
#ifdef CONFIG_IWLWIFI_DEBUGFS
if (priv->disable_ht40)
- return 0;
+ return false;
#endif
+
return iwl_is_channel_extension(priv, priv->band,
- le16_to_cpu(priv->staging_rxon.channel),
- ht_conf->extension_chan_offset);
+ le16_to_cpu(ctx->staging.channel),
+ ctx->ht.extension_chan_offset);
}
EXPORT_SYMBOL(iwl_is_ht40_tx_allowed);
static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
{
- u16 new_val = 0;
- u16 beacon_factor = 0;
+ u16 new_val;
+ u16 beacon_factor;
+
+ /*
+ * If mac80211 hasn't given us a beacon interval, program
+ * the default into the device (not checking this here
+ * would cause the adjustment below to return the maximum
+ * value, which may break PAN.)
+ */
+ if (!beacon_val)
+ return DEFAULT_BEACON_INTERVAL;
+
+ /*
+ * If the beacon interval we obtained from the peer
+ * is too large, we'll have to wake up more often
+ * (and in IBSS case, we'll beacon too much)
+ *
+ * For example, if max_beacon_val is 4096, and the
+ * requested beacon interval is 7000, we'll have to
+ * use 3500 to be able to wake up on the beacons.
+ *
+ * This could badly influence beacon detection stats.
+ */
beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val;
new_val = beacon_val / beacon_factor;
@@ -499,51 +431,76 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
return new_val;
}
-void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif)
+int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
u64 tsf;
s32 interval_tm, rem;
- unsigned long flags;
struct ieee80211_conf *conf = NULL;
u16 beacon_int;
+ struct ieee80211_vif *vif = ctx->vif;
conf = ieee80211_get_hw_conf(priv->hw);
- spin_lock_irqsave(&priv->lock, flags);
- priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
- priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
+ lockdep_assert_held(&priv->mutex);
- beacon_int = vif->bss_conf.beacon_int;
+ memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd));
- if (vif->type == NL80211_IFTYPE_ADHOC) {
- /* TODO: we need to get atim_window from upper stack
- * for now we set to 0 */
- priv->rxon_timing.atim_window = 0;
- } else {
- priv->rxon_timing.atim_window = 0;
- }
+ ctx->timing.timestamp = cpu_to_le64(priv->timestamp);
+ ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval);
- beacon_int = iwl_adjust_beacon_interval(beacon_int,
+ beacon_int = vif ? vif->bss_conf.beacon_int : 0;
+
+ /*
+ * TODO: For IBSS we need to get atim_window from mac80211,
+ * for now just always use 0
+ */
+ ctx->timing.atim_window = 0;
+
+ if (ctx->ctxid == IWL_RXON_CTX_PAN &&
+ (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION) &&
+ iwl_is_associated(priv, IWL_RXON_CTX_BSS) &&
+ priv->contexts[IWL_RXON_CTX_BSS].vif &&
+ priv->contexts[IWL_RXON_CTX_BSS].vif->bss_conf.beacon_int) {
+ ctx->timing.beacon_interval =
+ priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval;
+ beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
+ } else if (ctx->ctxid == IWL_RXON_CTX_BSS &&
+ iwl_is_associated(priv, IWL_RXON_CTX_PAN) &&
+ priv->contexts[IWL_RXON_CTX_PAN].vif &&
+ priv->contexts[IWL_RXON_CTX_PAN].vif->bss_conf.beacon_int &&
+ (!iwl_is_associated_ctx(ctx) || !ctx->vif ||
+ !ctx->vif->bss_conf.beacon_int)) {
+ ctx->timing.beacon_interval =
+ priv->contexts[IWL_RXON_CTX_PAN].timing.beacon_interval;
+ beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
+ } else {
+ beacon_int = iwl_adjust_beacon_interval(beacon_int,
priv->hw_params.max_beacon_itrvl * TIME_UNIT);
- priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int);
+ ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
+ }
tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
interval_tm = beacon_int * TIME_UNIT;
rem = do_div(tsf, interval_tm);
- priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
+ ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
+
+ ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ?: 1) : 1;
- spin_unlock_irqrestore(&priv->lock, flags);
IWL_DEBUG_ASSOC(priv,
"beacon interval %d beacon timer %d beacon tim %d\n",
- le16_to_cpu(priv->rxon_timing.beacon_interval),
- le32_to_cpu(priv->rxon_timing.beacon_init_val),
- le16_to_cpu(priv->rxon_timing.atim_window));
+ le16_to_cpu(ctx->timing.beacon_interval),
+ le32_to_cpu(ctx->timing.beacon_init_val),
+ le16_to_cpu(ctx->timing.atim_window));
+
+ return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd,
+ sizeof(ctx->timing), &ctx->timing);
}
-EXPORT_SYMBOL(iwl_setup_rxon_timing);
+EXPORT_SYMBOL(iwl_send_rxon_timing);
-void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ int hw_decrypt)
{
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ struct iwl_rxon_cmd *rxon = &ctx->staging;
if (hw_decrypt)
rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
@@ -553,76 +510,74 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
}
EXPORT_SYMBOL(iwl_set_rxon_hwcrypto);
-/**
- * iwl_check_rxon_cmd - validate RXON structure is valid
- *
- * NOTE: This is really only useful during development and can eventually
- * be #ifdef'd out once the driver is stable and folks aren't actively
- * making changes
- */
-int iwl_check_rxon_cmd(struct iwl_priv *priv)
+/* validate RXON structure is valid */
+int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
- int error = 0;
- int counter = 1;
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ struct iwl_rxon_cmd *rxon = &ctx->staging;
+ bool error = false;
if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
- error |= le32_to_cpu(rxon->flags &
- (RXON_FLG_TGJ_NARROW_BAND_MSK |
- RXON_FLG_RADAR_DETECT_MSK));
- if (error)
- IWL_WARN(priv, "check 24G fields %d | %d\n",
- counter++, error);
+ if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
+ IWL_WARN(priv, "check 2.4G: wrong narrow\n");
+ error = true;
+ }
+ if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
+ IWL_WARN(priv, "check 2.4G: wrong radar\n");
+ error = true;
+ }
} else {
- error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
- 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
- if (error)
- IWL_WARN(priv, "check 52 fields %d | %d\n",
- counter++, error);
- error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
- if (error)
- IWL_WARN(priv, "check 52 CCK %d | %d\n",
- counter++, error);
- }
- error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
- if (error)
- IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error);
+ if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
+ IWL_WARN(priv, "check 5.2G: not short slot!\n");
+ error = true;
+ }
+ if (rxon->flags & RXON_FLG_CCK_MSK) {
+ IWL_WARN(priv, "check 5.2G: CCK!\n");
+ error = true;
+ }
+ }
+ if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
+ IWL_WARN(priv, "mac/bssid mcast!\n");
+ error = true;
+ }
/* make sure basic rates 6Mbps and 1Mbps are supported */
- error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
- ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
- if (error)
- IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error);
+ 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;
+ }
- error |= (le16_to_cpu(rxon->assoc_id) > 2007);
- if (error)
- IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error);
+ if (le16_to_cpu(rxon->assoc_id) > 2007) {
+ IWL_WARN(priv, "aid > 2007\n");
+ error = true;
+ }
- error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
- == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
- if (error)
- IWL_WARN(priv, "check CCK and short slot %d | %d\n",
- counter++, error);
+ 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;
+ }
- error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
- == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
- if (error)
- IWL_WARN(priv, "check CCK & auto detect %d | %d\n",
- counter++, error);
+ 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;
+ }
- error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
- RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
- if (error)
- IWL_WARN(priv, "check TGG and auto detect %d | %d\n",
- counter++, error);
+ 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;
+ }
if (error)
IWL_WARN(priv, "Tuning to channel %d\n",
le16_to_cpu(rxon->channel));
if (error) {
- IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n");
- return -1;
+ IWL_ERR(priv, "Invalid RXON\n");
+ return -EINVAL;
}
return 0;
}
@@ -636,66 +591,83 @@ EXPORT_SYMBOL(iwl_check_rxon_cmd);
* or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
* a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
*/
-int iwl_full_rxon_required(struct iwl_priv *priv)
+int iwl_full_rxon_required(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
+ const struct iwl_rxon_cmd *staging = &ctx->staging;
+ const struct iwl_rxon_cmd *active = &ctx->active;
+
+#define CHK(cond) \
+ if ((cond)) { \
+ IWL_DEBUG_INFO(priv, "need full RXON - " #cond "\n"); \
+ return 1; \
+ }
+
+#define CHK_NEQ(c1, c2) \
+ if ((c1) != (c2)) { \
+ IWL_DEBUG_INFO(priv, "need full RXON - " \
+ #c1 " != " #c2 " - %d != %d\n", \
+ (c1), (c2)); \
+ return 1; \
+ }
/* These items are only settable from the full RXON command */
- if (!(iwl_is_associated(priv)) ||
- compare_ether_addr(priv->staging_rxon.bssid_addr,
- priv->active_rxon.bssid_addr) ||
- compare_ether_addr(priv->staging_rxon.node_addr,
- priv->active_rxon.node_addr) ||
- compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
- priv->active_rxon.wlap_bssid_addr) ||
- (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
- (priv->staging_rxon.channel != priv->active_rxon.channel) ||
- (priv->staging_rxon.air_propagation !=
- priv->active_rxon.air_propagation) ||
- (priv->staging_rxon.ofdm_ht_single_stream_basic_rates !=
- priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
- (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
- priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
- (priv->staging_rxon.ofdm_ht_triple_stream_basic_rates !=
- priv->active_rxon.ofdm_ht_triple_stream_basic_rates) ||
- (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
- return 1;
+ CHK(!iwl_is_associated_ctx(ctx));
+ CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr));
+ CHK(compare_ether_addr(staging->node_addr, active->node_addr));
+ CHK(compare_ether_addr(staging->wlap_bssid_addr,
+ active->wlap_bssid_addr));
+ CHK_NEQ(staging->dev_type, active->dev_type);
+ CHK_NEQ(staging->channel, active->channel);
+ CHK_NEQ(staging->air_propagation, active->air_propagation);
+ CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates,
+ active->ofdm_ht_single_stream_basic_rates);
+ CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates,
+ active->ofdm_ht_dual_stream_basic_rates);
+ CHK_NEQ(staging->ofdm_ht_triple_stream_basic_rates,
+ active->ofdm_ht_triple_stream_basic_rates);
+ CHK_NEQ(staging->assoc_id, active->assoc_id);
/* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
* be updated with the RXON_ASSOC command -- however only some
* flag transitions are allowed using RXON_ASSOC */
/* Check if we are not switching bands */
- if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
- (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
- return 1;
+ CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK,
+ active->flags & RXON_FLG_BAND_24G_MSK);
/* Check if we are switching association toggle */
- if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
- (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
- return 1;
+ CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK,
+ active->filter_flags & RXON_FILTER_ASSOC_MSK);
+
+#undef CHK
+#undef CHK_NEQ
return 0;
}
EXPORT_SYMBOL(iwl_full_rxon_required);
-u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
+u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
/*
* Assign the lowest rate -- should really get this from
* the beacon skb from mac80211.
*/
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK)
return IWL_RATE_1M_PLCP;
else
return IWL_RATE_6M_PLCP;
}
EXPORT_SYMBOL(iwl_rate_get_lowest_plcp);
-void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
+static void _iwl_set_rxon_ht(struct iwl_priv *priv,
+ struct iwl_ht_config *ht_conf,
+ struct iwl_rxon_context *ctx)
{
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ struct iwl_rxon_cmd *rxon = &ctx->staging;
- if (!ht_conf->is_ht) {
+ if (!ctx->ht.enabled) {
rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
RXON_FLG_HT40_PROT_MSK |
@@ -703,22 +675,22 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
return;
}
- /* FIXME: if the definition of ht_protection changed, the "translation"
+ /* FIXME: if the definition of ht.protection changed, the "translation"
* will be needed for rxon->flags
*/
- rxon->flags |= cpu_to_le32(ht_conf->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS);
+ rxon->flags |= cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
/* Set up channel bandwidth:
* 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
/* clear the HT channel mode before set the mode */
rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
- if (iwl_is_ht40_tx_allowed(priv, NULL)) {
+ if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) {
/* pure ht40 */
- if (ht_conf->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
+ if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
/* Note: control channel is opposite of extension channel */
- switch (ht_conf->extension_chan_offset) {
+ switch (ctx->ht.extension_chan_offset) {
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
break;
@@ -728,7 +700,7 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
}
} else {
/* Note: control channel is opposite of extension channel */
- switch (ht_conf->extension_chan_offset) {
+ switch (ctx->ht.extension_chan_offset) {
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
@@ -749,162 +721,58 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
}
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
"extension channel offset 0x%x\n",
- le32_to_cpu(rxon->flags), ht_conf->ht_protection,
- ht_conf->extension_chan_offset);
-}
-EXPORT_SYMBOL(iwl_set_rxon_ht);
-
-#define IWL_NUM_RX_CHAINS_MULTIPLE 3
-#define IWL_NUM_RX_CHAINS_SINGLE 2
-#define IWL_NUM_IDLE_CHAINS_DUAL 2
-#define IWL_NUM_IDLE_CHAINS_SINGLE 1
-
-/*
- * Determine how many receiver/antenna chains to use.
- *
- * More provides better reception via diversity. Fewer saves power
- * at the expense of throughput, but only when not in powersave to
- * start with.
- *
- * MIMO (dual stream) requires at least 2, but works better with 3.
- * This does not determine *which* chains to use, just how many.
- */
-static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
-{
- /* # of Rx chains to use when expecting MIMO. */
- if (is_single_rx_stream(priv))
- return IWL_NUM_RX_CHAINS_SINGLE;
- else
- return IWL_NUM_RX_CHAINS_MULTIPLE;
-}
-
-/*
- * When we are in power saving mode, unless device support spatial
- * multiplexing power save, use the active count for rx chain count.
- */
-static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
-{
- /* # Rx chains when idling, depending on SMPS mode */
- switch (priv->current_ht_config.smps) {
- case IEEE80211_SMPS_STATIC:
- case IEEE80211_SMPS_DYNAMIC:
- return IWL_NUM_IDLE_CHAINS_SINGLE;
- case IEEE80211_SMPS_OFF:
- return active_cnt;
- default:
- WARN(1, "invalid SMPS mode %d",
- priv->current_ht_config.smps);
- return active_cnt;
- }
+ le32_to_cpu(rxon->flags), ctx->ht.protection,
+ ctx->ht.extension_chan_offset);
}
-/* up to 4 chains */
-static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
+void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
{
- u8 res;
- res = (chain_bitmap & BIT(0)) >> 0;
- res += (chain_bitmap & BIT(1)) >> 1;
- res += (chain_bitmap & BIT(2)) >> 2;
- res += (chain_bitmap & BIT(3)) >> 3;
- return res;
-}
-
-/**
- * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
- *
- * Selects how many and which Rx receivers/antennas/chains to use.
- * This should not be used for scan command ... it puts data in wrong place.
- */
-void iwl_set_rxon_chain(struct iwl_priv *priv)
-{
- bool is_single = is_single_rx_stream(priv);
- bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
- u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
- u32 active_chains;
- u16 rx_chain;
-
- /* Tell uCode which antennas are actually connected.
- * Before first association, we assume all antennas are connected.
- * Just after first association, iwl_chain_noise_calibration()
- * checks which antennas actually *are* connected. */
- if (priv->chain_noise_data.active_chains)
- active_chains = priv->chain_noise_data.active_chains;
- else
- active_chains = priv->hw_params.valid_rx_ant;
-
- rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
-
- /* How many receivers should we use? */
- active_rx_cnt = iwl_get_active_rx_chain_count(priv);
- idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
-
-
- /* correct rx chain count according hw settings
- * and chain noise calibration
- */
- valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
- if (valid_rx_cnt < active_rx_cnt)
- active_rx_cnt = valid_rx_cnt;
-
- if (valid_rx_cnt < idle_rx_cnt)
- idle_rx_cnt = valid_rx_cnt;
-
- rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
- rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
-
- priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
-
- if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
- priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
- else
- priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
+ struct iwl_rxon_context *ctx;
- IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
- priv->staging_rxon.rx_chain,
- active_rx_cnt, idle_rx_cnt);
-
- WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
- active_rx_cnt < idle_rx_cnt);
+ for_each_context(priv, ctx)
+ _iwl_set_rxon_ht(priv, ht_conf, ctx);
}
-EXPORT_SYMBOL(iwl_set_rxon_chain);
+EXPORT_SYMBOL(iwl_set_rxon_ht);
-/* Return valid channel */
+/* Return valid, unused, channel for a passive scan to reset the RF */
u8 iwl_get_single_channel_number(struct iwl_priv *priv,
- enum ieee80211_band band)
+ enum ieee80211_band band)
{
const struct iwl_channel_info *ch_info;
int i;
u8 channel = 0;
+ u8 min, max;
+ struct iwl_rxon_context *ctx;
- /* only scan single channel, good enough to reset the RF */
- /* pick the first valid not in-use channel */
if (band == IEEE80211_BAND_5GHZ) {
- for (i = 14; i < priv->channel_count; i++) {
- if (priv->channel_info[i].channel !=
- le16_to_cpu(priv->staging_rxon.channel)) {
- channel = priv->channel_info[i].channel;
- ch_info = iwl_get_channel_info(priv,
- band, channel);
- if (is_channel_valid(ch_info))
- break;
- }
- }
+ min = 14;
+ max = priv->channel_count;
} else {
- for (i = 0; i < 14; i++) {
- if (priv->channel_info[i].channel !=
- le16_to_cpu(priv->staging_rxon.channel)) {
- channel =
- priv->channel_info[i].channel;
- ch_info = iwl_get_channel_info(priv,
- band, channel);
- if (is_channel_valid(ch_info))
- break;
- }
+ min = 0;
+ max = 14;
+ }
+
+ for (i = min; i < max; i++) {
+ bool busy = false;
+
+ for_each_context(priv, ctx) {
+ busy = priv->channel_info[i].channel ==
+ le16_to_cpu(ctx->staging.channel);
+ if (busy)
+ break;
}
+
+ if (busy)
+ continue;
+
+ channel = priv->channel_info[i].channel;
+ ch_info = iwl_get_channel_info(priv, band, channel);
+ if (is_channel_valid(ch_info))
+ break;
}
return channel;
@@ -912,35 +780,27 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_get_single_channel_number);
/**
- * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON
- * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
- * @channel: Any channel valid for the requested phymode
+ * iwl_set_rxon_channel - Set the band and channel values in staging RXON
+ * @ch: requested channel as a pointer to struct ieee80211_channel
- * In addition to setting the staging RXON, priv->phymode is also set.
- *
* NOTE: Does not commit to the hardware; it sets appropriate bit fields
- * in the staging RXON flag structure based on the phymode
+ * in the staging RXON flag structure based on the ch->band
*/
-int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
+int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
+ struct iwl_rxon_context *ctx)
{
enum ieee80211_band band = ch->band;
- u16 channel = ieee80211_frequency_to_channel(ch->center_freq);
+ u16 channel = ch->hw_value;
- if (!iwl_get_channel_info(priv, band, channel)) {
- IWL_DEBUG_INFO(priv, "Could not set channel to %d [%d]\n",
- channel, band);
- return -EINVAL;
- }
-
- if ((le16_to_cpu(priv->staging_rxon.channel) == channel) &&
+ if ((le16_to_cpu(ctx->staging.channel) == channel) &&
(priv->band == band))
return 0;
- priv->staging_rxon.channel = cpu_to_le16(channel);
+ ctx->staging.channel = cpu_to_le16(channel);
if (band == IEEE80211_BAND_5GHZ)
- priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
+ ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
else
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
+ ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
priv->band = band;
@@ -951,24 +811,25 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
EXPORT_SYMBOL(iwl_set_rxon_channel);
void iwl_set_flags_for_band(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
enum ieee80211_band band,
struct ieee80211_vif *vif)
{
if (band == IEEE80211_BAND_5GHZ) {
- priv->staging_rxon.flags &=
+ ctx->staging.flags &=
~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
| RXON_FLG_CCK_MSK);
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
} else {
/* Copied from iwl_post_associate() */
if (vif && vif->bss_conf.use_short_slot)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
- priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
- priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
+ ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
+ ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
+ ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
}
}
EXPORT_SYMBOL(iwl_set_flags_for_band);
@@ -977,35 +838,34 @@ EXPORT_SYMBOL(iwl_set_flags_for_band);
* initialize rxon structure with default values from eeprom
*/
void iwl_connection_init_rx_config(struct iwl_priv *priv,
- struct ieee80211_vif *vif)
+ struct iwl_rxon_context *ctx)
{
const struct iwl_channel_info *ch_info;
- enum nl80211_iftype type = NL80211_IFTYPE_STATION;
- if (vif)
- type = vif->type;
+ memset(&ctx->staging, 0, sizeof(ctx->staging));
- memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
-
- switch (type) {
+ if (!ctx->vif) {
+ ctx->staging.dev_type = ctx->unused_devtype;
+ } else switch (ctx->vif->type) {
case NL80211_IFTYPE_AP:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
+ ctx->staging.dev_type = ctx->ap_devtype;
break;
case NL80211_IFTYPE_STATION:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
- priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
+ ctx->staging.dev_type = ctx->station_devtype;
+ ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
break;
case NL80211_IFTYPE_ADHOC:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
- priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
- priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
+ ctx->staging.dev_type = ctx->ibss_devtype;
+ ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
RXON_FILTER_ACCEPT_GRP_MSK;
break;
default:
- IWL_ERR(priv, "Unsupported interface type %d\n", type);
+ IWL_ERR(priv, "Unsupported interface type %d\n",
+ ctx->vif->type);
break;
}
@@ -1013,37 +873,36 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
/* TODO: Figure out when short_preamble would be set and cache from
* that */
if (!hw_to_local(priv->hw)->short_preamble)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
#endif
ch_info = iwl_get_channel_info(priv, priv->band,
- le16_to_cpu(priv->active_rxon.channel));
+ le16_to_cpu(ctx->active.channel));
if (!ch_info)
ch_info = &priv->channel_info[0];
- priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
+ ctx->staging.channel = cpu_to_le16(ch_info->channel);
priv->band = ch_info->band;
- iwl_set_flags_for_band(priv, priv->band, vif);
+ iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);
- priv->staging_rxon.ofdm_basic_rates =
+ ctx->staging.ofdm_basic_rates =
(IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
- priv->staging_rxon.cck_basic_rates =
+ ctx->staging.cck_basic_rates =
(IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
/* clear both MIX and PURE40 mode flag */
- priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
+ ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
RXON_FLG_CHANNEL_MODE_PURE_40);
+ if (ctx->vif)
+ memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
- if (vif)
- memcpy(priv->staging_rxon.node_addr, vif->addr, ETH_ALEN);
-
- priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
- priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
- priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff;
+ ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;
+ ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
+ ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff;
}
EXPORT_SYMBOL(iwl_connection_init_rx_config);
@@ -1051,6 +910,7 @@ void iwl_set_rate(struct iwl_priv *priv)
{
const struct ieee80211_supported_band *hw = NULL;
struct ieee80211_rate *rate;
+ struct iwl_rxon_context *ctx;
int i;
hw = iwl_get_hw_mode(priv, priv->band);
@@ -1069,21 +929,29 @@ void iwl_set_rate(struct iwl_priv *priv)
IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate);
- priv->staging_rxon.cck_basic_rates =
- (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
+ for_each_context(priv, ctx) {
+ ctx->staging.cck_basic_rates =
+ (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
- priv->staging_rxon.ofdm_basic_rates =
- (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
+ ctx->staging.ofdm_basic_rates =
+ (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
+ }
}
EXPORT_SYMBOL(iwl_set_rate);
void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
{
+ /*
+ * MULTI-FIXME
+ * See iwl_mac_channel_switch.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
if (priv->switch_rxon.switch_in_progress) {
- ieee80211_chswitch_done(priv->vif, is_success);
+ ieee80211_chswitch_done(ctx->vif, is_success);
mutex_lock(&priv->mutex);
priv->switch_rxon.switch_in_progress = false;
mutex_unlock(&priv->mutex);
@@ -1094,14 +962,19 @@ EXPORT_SYMBOL(iwl_chswitch_done);
void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
- struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
+ /*
+ * MULTI-FIXME
+ * See iwl_mac_channel_switch.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
if (priv->switch_rxon.switch_in_progress) {
if (!le32_to_cpu(csa->status) &&
(csa->channel == priv->switch_rxon.channel)) {
rxon->channel = csa->channel;
- priv->staging_rxon.channel = csa->channel;
+ ctx->staging.channel = csa->channel;
IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
le16_to_cpu(csa->channel));
iwl_chswitch_done(priv, true);
@@ -1115,9 +988,10 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
EXPORT_SYMBOL(iwl_rx_csa);
#ifdef CONFIG_IWLWIFI_DEBUG
-void iwl_print_rx_config_cmd(struct iwl_priv *priv)
+void iwl_print_rx_config_cmd(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ struct iwl_rxon_cmd *rxon = &ctx->staging;
IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
@@ -1157,7 +1031,8 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
priv->cfg->ops->lib->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);
+ iwl_print_rx_config_cmd(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
#endif
wake_up_interruptible(&priv->wait_command_queue);
@@ -1261,7 +1136,7 @@ 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->set_l0s) {
+ 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) {
@@ -1278,8 +1153,9 @@ int iwl_apm_init(struct iwl_priv *priv)
}
/* Configure analog phase-lock-loop before activating to D0A */
- if (priv->cfg->pll_cfg_val)
- iwl_set_bit(priv, CSR_ANA_PLL_CFG, priv->cfg->pll_cfg_val);
+ if (priv->cfg->base_params->pll_cfg_val)
+ iwl_set_bit(priv, CSR_ANA_PLL_CFG,
+ priv->cfg->base_params->pll_cfg_val);
/*
* Set "initialization complete" bit to move adapter from
@@ -1310,7 +1186,7 @@ int iwl_apm_init(struct iwl_priv *priv)
* do not disable clocks. This preserves any hardware bits already
* set by default in "CLK_CTRL_REG" after reset.
*/
- if (priv->cfg->use_bsm)
+ 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
@@ -1328,25 +1204,6 @@ out:
EXPORT_SYMBOL(iwl_apm_init);
-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)
- 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)
- priv->cfg->sku &= ~IWL_SKU_N;
-
- /* Device-specific setup */
- return priv->cfg->ops->lib->set_hw_params(priv);
-}
-EXPORT_SYMBOL(iwl_set_hw_params);
-
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
{
int ret = 0;
@@ -1496,76 +1353,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
}
EXPORT_SYMBOL(iwl_send_statistics_request);
-void iwl_rf_kill_ct_config(struct iwl_priv *priv)
-{
- struct iwl_ct_kill_config cmd;
- struct iwl_ct_kill_throttling_config adv_cmd;
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
- CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
- spin_unlock_irqrestore(&priv->lock, flags);
- priv->thermal_throttle.ct_kill_toggle = false;
-
- if (priv->cfg->support_ct_kill_exit) {
- adv_cmd.critical_temperature_enter =
- cpu_to_le32(priv->hw_params.ct_kill_threshold);
- adv_cmd.critical_temperature_exit =
- cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
-
- ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
- sizeof(adv_cmd), &adv_cmd);
- if (ret)
- IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
- else
- IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
- "succeeded, "
- "critical temperature enter is %d,"
- "exit is %d\n",
- priv->hw_params.ct_kill_threshold,
- priv->hw_params.ct_kill_exit_threshold);
- } else {
- cmd.critical_temperature_R =
- cpu_to_le32(priv->hw_params.ct_kill_threshold);
-
- ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
- sizeof(cmd), &cmd);
- if (ret)
- IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
- else
- IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
- "succeeded, "
- "critical temperature is %d\n",
- priv->hw_params.ct_kill_threshold);
- }
-}
-EXPORT_SYMBOL(iwl_rf_kill_ct_config);
-
-
-/*
- * CARD_STATE_CMD
- *
- * Use: Sets the device's internal card state to enable, disable, or halt
- *
- * When in the 'enable' state the card operates as normal.
- * When in the 'disable' state, the card enters into a low power mode.
- * When in the 'halt' state, the card is shut down and must be fully
- * restarted to come back on.
- */
-int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
-{
- struct iwl_host_cmd cmd = {
- .id = REPLY_CARD_STATE_CMD,
- .len = sizeof(u32),
- .data = &flags,
- .flags = meta_flag,
- };
-
- return iwl_send_cmd(priv, &cmd);
-}
-
void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
@@ -1614,6 +1401,7 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx;
unsigned long flags;
int q;
@@ -1633,13 +1421,21 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
- priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
- priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
- priv->qos_data.def_qos_parm.ac[q].edca_txop =
- cpu_to_le16((params->txop * 32));
+ /*
+ * MULTI-FIXME
+ * This may need to be done per interface in nl80211/cfg80211/mac80211.
+ */
+ for_each_context(priv, ctx) {
+ ctx->qos_data.def_qos_parm.ac[q].cw_min =
+ cpu_to_le16(params->cw_min);
+ ctx->qos_data.def_qos_parm.ac[q].cw_max =
+ cpu_to_le16(params->cw_max);
+ ctx->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
+ ctx->qos_data.def_qos_parm.ac[q].edca_txop =
+ cpu_to_le16((params->txop * 32));
- priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
+ ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0;
+ }
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1648,21 +1444,30 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
}
EXPORT_SYMBOL(iwl_mac_conf_tx);
+int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw)
+{
+ struct iwl_priv *priv = hw->priv;
+
+ return priv->ibss_manager == IWL_IBSS_MANAGER;
+}
+EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon);
+
static void iwl_ht_conf(struct iwl_priv *priv,
struct ieee80211_vif *vif)
{
struct iwl_ht_config *ht_conf = &priv->current_ht_config;
struct ieee80211_sta *sta;
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
IWL_DEBUG_MAC80211(priv, "enter:\n");
- if (!ht_conf->is_ht)
+ if (!ctx->ht.enabled)
return;
- ht_conf->ht_protection =
+ ctx->ht.protection =
bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
- ht_conf->non_GF_STA_present =
+ ctx->ht.non_gf_sta_present =
!!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
ht_conf->single_chain_sufficient = false;
@@ -1706,49 +1511,63 @@ static void iwl_ht_conf(struct iwl_priv *priv,
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-static inline void iwl_set_no_assoc(struct iwl_priv *priv)
+static inline void iwl_set_no_assoc(struct iwl_priv *priv,
+ struct ieee80211_vif *vif)
{
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+
iwl_led_disassociate(priv);
/*
* inform the ucode that there is no longer an
* association and that no more packets should be
* sent
*/
- priv->staging_rxon.filter_flags &=
- ~RXON_FILTER_ASSOC_MSK;
- priv->staging_rxon.assoc_id = 0;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ ctx->staging.assoc_id = 0;
+ iwlcore_commit_rxon(priv, ctx);
}
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
+static void iwlcore_beacon_update(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
{
struct iwl_priv *priv = hw->priv;
unsigned long flags;
__le64 timestamp;
+ struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
- IWL_DEBUG_MAC80211(priv, "enter\n");
+ if (!skb)
+ return;
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
+ IWL_DEBUG_ASSOC(priv, "enter\n");
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (!priv->beacon_ctx) {
+ IWL_ERR(priv, "update beacon but no beacon context!\n");
+ dev_kfree_skb(skb);
+ return;
}
spin_lock_irqsave(&priv->lock, flags);
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
+ if (priv->beacon_skb)
+ dev_kfree_skb(priv->beacon_skb);
- priv->ibss_beacon = skb;
+ priv->beacon_skb = skb;
timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
priv->timestamp = le64_to_cpu(timestamp);
- IWL_DEBUG_MAC80211(priv, "leave\n");
+ IWL_DEBUG_ASSOC(priv, "leave\n");
+
spin_unlock_irqrestore(&priv->lock, flags);
- priv->cfg->ops->lib->post_associate(priv, priv->vif);
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+ return;
+ }
- return 0;
+ priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
}
void iwl_bss_info_changed(struct ieee80211_hw *hw,
@@ -1757,6 +1576,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
u32 changes)
{
struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
int ret;
IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
@@ -1770,20 +1590,31 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.qos_active = bss_conf->qos;
- iwl_update_qos(priv);
+ ctx->qos_data.qos_active = bss_conf->qos;
+ iwl_update_qos(priv, ctx);
spin_unlock_irqrestore(&priv->lock, flags);
}
- if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
- dev_kfree_skb(priv->ibss_beacon);
- priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
+ if (changes & BSS_CHANGED_BEACON_ENABLED) {
+ /*
+ * the add_interface code must make sure we only ever
+ * have a single interface that could be beaconing at
+ * any time.
+ */
+ if (vif->bss_conf.enable_beacon)
+ priv->beacon_ctx = ctx;
+ else
+ priv->beacon_ctx = NULL;
}
- if (changes & BSS_CHANGED_BEACON_INT) {
- /* TODO: in AP mode, do something to make this take effect */
+ if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
+ dev_kfree_skb(priv->beacon_skb);
+ priv->beacon_skb = ieee80211_beacon_get(hw, vif);
}
+ if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
+ iwl_send_rxon_timing(priv, ctx);
+
if (changes & BSS_CHANGED_BSSID) {
IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
@@ -1801,13 +1632,13 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
/* mac80211 only sets assoc when in STATION mode */
if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
- memcpy(priv->staging_rxon.bssid_addr,
+ memcpy(ctx->staging.bssid_addr,
bss_conf->bssid, ETH_ALEN);
/* currently needed in a few places */
memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
} else {
- priv->staging_rxon.filter_flags &=
+ ctx->staging.filter_flags &=
~RXON_FILTER_ASSOC_MSK;
}
@@ -1818,33 +1649,28 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
* mac80211 decides to do both changes at once because
* it will invoke post_associate.
*/
- if (vif->type == NL80211_IFTYPE_ADHOC &&
- changes & BSS_CHANGED_BEACON) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
-
- if (beacon)
- iwl_mac_beacon_update(hw, beacon);
- }
+ if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
+ iwlcore_beacon_update(hw, vif);
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
}
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
- priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+ ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
if (bss_conf->use_cts_prot)
- priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
+ ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
+ ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
}
if (changes & BSS_CHANGED_BASIC_RATES) {
@@ -1854,12 +1680,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
* like this here:
*
if (A-band)
- priv->staging_rxon.ofdm_basic_rates =
+ ctx->staging.ofdm_basic_rates =
bss_conf->basic_rates;
else
- priv->staging_rxon.ofdm_basic_rates =
+ ctx->staging.ofdm_basic_rates =
bss_conf->basic_rates >> 4;
- priv->staging_rxon.cck_basic_rates =
+ ctx->staging.cck_basic_rates =
bss_conf->basic_rates & 0xF;
*/
}
@@ -1868,7 +1694,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
iwl_ht_conf(priv, vif);
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
}
if (changes & BSS_CHANGED_ASSOC) {
@@ -1881,29 +1707,30 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
if (!iwl_is_rfkill(priv))
priv->cfg->ops->lib->post_associate(priv, vif);
} else
- iwl_set_no_assoc(priv);
+ iwl_set_no_assoc(priv, vif);
}
- if (changes && iwl_is_associated(priv) && bss_conf->aid) {
+ if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
changes);
- ret = iwl_send_rxon_assoc(priv);
+ ret = iwl_send_rxon_assoc(priv, ctx);
if (!ret) {
/* Sync active_rxon with latest change. */
- memcpy((void *)&priv->active_rxon,
- &priv->staging_rxon,
+ memcpy((void *)&ctx->active,
+ &ctx->staging,
sizeof(struct iwl_rxon_cmd));
}
}
if (changes & BSS_CHANGED_BEACON_ENABLED) {
if (vif->bss_conf.enable_beacon) {
- memcpy(priv->staging_rxon.bssid_addr,
+ memcpy(ctx->staging.bssid_addr,
bss_conf->bssid, ETH_ALEN);
memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+ iwl_led_associate(priv);
iwlcore_config_ap(priv, vif);
} else
- iwl_set_no_assoc(priv);
+ iwl_set_no_assoc(priv, vif);
}
if (changes & BSS_CHANGED_IBSS) {
@@ -1915,6 +1742,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
bss_conf->bssid);
}
+ if (changes & BSS_CHANGED_IDLE &&
+ priv->cfg->ops->hcmd->set_pan_params) {
+ if (priv->cfg->ops->hcmd->set_pan_params(priv))
+ IWL_ERR(priv, "failed to update PAN params\n");
+ }
+
mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -1923,17 +1756,21 @@ EXPORT_SYMBOL(iwl_bss_info_changed);
static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
- iwl_connection_init_rx_config(priv, vif);
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+
+ iwl_connection_init_rx_config(priv, ctx);
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- return iwlcore_commit_rxon(priv);
+ return iwlcore_commit_rxon(priv, ctx);
}
int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct iwl_priv *priv = hw->priv;
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+ struct iwl_rxon_context *tmp, *ctx = NULL;
int err = 0;
IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
@@ -1941,28 +1778,72 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
mutex_lock(&priv->mutex);
- if (WARN_ON(!iwl_is_ready_rf(priv))) {
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_WARN(priv, "Try to add interface when device not ready\n");
err = -EINVAL;
goto out;
}
- if (priv->vif) {
- IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
+ for_each_context(priv, tmp) {
+ u32 possible_modes =
+ tmp->interface_modes | tmp->exclusive_interface_modes;
+
+ if (tmp->vif) {
+ /* check if this busy context is exclusive */
+ if (tmp->exclusive_interface_modes &
+ BIT(tmp->vif->type)) {
+ err = -EINVAL;
+ goto out;
+ }
+ continue;
+ }
+
+ if (!(possible_modes & BIT(vif->type)))
+ continue;
+
+ /* have maybe usable context w/o interface */
+ ctx = tmp;
+ break;
+ }
+
+ if (!ctx) {
err = -EOPNOTSUPP;
goto out;
}
- priv->vif = vif;
+ vif_priv->ctx = ctx;
+ ctx->vif = vif;
+ /*
+ * This variable will be correct only when there's just
+ * a single context, but all code using it is for hardware
+ * that supports only one context.
+ */
priv->iw_mode = vif->type;
+ ctx->is_active = true;
+
err = iwl_set_mode(priv, vif);
- if (err)
+ if (err) {
+ if (!ctx->always_active)
+ ctx->is_active = false;
goto out_err;
+ }
+
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist &&
+ vif->type == NL80211_IFTYPE_ADHOC) {
+ /*
+ * pretend to have high BT traffic as long as we
+ * are operating in IBSS mode, as this will cause
+ * the rate scaling etc. to behave as intended.
+ */
+ priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
+ }
goto out;
out_err:
- priv->vif = NULL;
+ ctx->vif = NULL;
priv->iw_mode = NL80211_IFTYPE_STATION;
out:
mutex_unlock(&priv->mutex);
@@ -1976,30 +1857,36 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct iwl_priv *priv = hw->priv;
- bool scan_completed = false;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex);
- if (iwl_is_ready_rf(priv)) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
- }
- if (priv->vif == vif) {
- priv->vif = NULL;
- if (priv->scan_vif == vif) {
- scan_completed = true;
- priv->scan_vif = NULL;
- priv->scan_request = NULL;
- }
- memset(priv->bssid, 0, ETH_ALEN);
+ WARN_ON(ctx->vif != vif);
+ ctx->vif = NULL;
+
+ if (priv->scan_vif == vif) {
+ iwl_scan_cancel_timeout(priv, 200);
+ iwl_force_scan_end(priv);
}
- mutex_unlock(&priv->mutex);
+ iwl_set_mode(priv, vif);
- if (scan_completed)
- ieee80211_scan_completed(priv->hw, true);
+ if (!ctx->always_active)
+ ctx->is_active = false;
+
+ /*
+ * When removing the IBSS interface, overwrite the
+ * BT traffic load with the stored one from the last
+ * notification, if any. If this is a device that
+ * doesn't implement this, this has no effect since
+ * both values are the same and zero.
+ */
+ if (vif->type == NL80211_IFTYPE_ADHOC)
+ priv->bt_traffic_load = priv->notif_bt_traffic_load;
+
+ memset(priv->bssid, 0, ETH_ALEN);
+ mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -2014,7 +1901,9 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
struct iwl_priv *priv = hw->priv;
const struct iwl_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf;
+ struct ieee80211_channel *channel = conf->channel;
struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+ struct iwl_rxon_context *ctx;
unsigned long flags = 0;
int ret = 0;
u16 ch;
@@ -2023,7 +1912,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
- conf->channel->hw_value, changed);
+ channel->hw_value, changed);
if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
test_bit(STATUS_SCANNING, &priv->status))) {
@@ -2044,7 +1933,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
* configured.
*/
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ for_each_context(priv, ctx)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
}
/* during scanning mac80211 will delay channel setting until
@@ -2054,8 +1944,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
if (scan_active)
goto set_ch_out;
- ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
- ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
+ ch = channel->hw_value;
+ ch_info = iwl_get_channel_info(priv, channel->band, ch);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
ret = -EINVAL;
@@ -2064,42 +1954,49 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
spin_lock_irqsave(&priv->lock, flags);
- /* Configure HT40 channels */
- ht_conf->is_ht = conf_is_ht(conf);
- if (ht_conf->is_ht) {
- if (conf_is_ht40_minus(conf)) {
- ht_conf->extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- ht_conf->is_40mhz = true;
- } else if (conf_is_ht40_plus(conf)) {
- ht_conf->extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
- ht_conf->is_40mhz = true;
- } else {
- ht_conf->extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_NONE;
- ht_conf->is_40mhz = false;
- }
- } else
- ht_conf->is_40mhz = false;
- /* Default to no protection. Protection mode will later be set
- * from BSS config in iwl_ht_conf */
- ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+ for_each_context(priv, ctx) {
+ /* Configure HT40 channels */
+ ctx->ht.enabled = conf_is_ht(conf);
+ if (ctx->ht.enabled) {
+ if (conf_is_ht40_minus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ ctx->ht.is_40mhz = true;
+ } else if (conf_is_ht40_plus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+ ctx->ht.is_40mhz = true;
+ } else {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ ctx->ht.is_40mhz = false;
+ }
+ } else
+ ctx->ht.is_40mhz = false;
- /* if we are switching from ht to 2.4 clear flags
- * from any ht related info since 2.4 does not
- * support ht */
- if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
- priv->staging_rxon.flags = 0;
+ /*
+ * Default to no protection. Protection mode will
+ * later be set from BSS config in iwl_ht_conf
+ */
+ ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
- iwl_set_rxon_channel(priv, conf->channel);
- iwl_set_rxon_ht(priv, ht_conf);
+ /* if we are switching from ht to 2.4 clear flags
+ * from any ht related info since 2.4 does not
+ * support ht */
+ if ((le16_to_cpu(ctx->staging.channel) != ch))
+ ctx->staging.flags = 0;
+
+ iwl_set_rxon_channel(priv, channel, ctx);
+ iwl_set_rxon_ht(priv, ht_conf);
+
+ iwl_set_flags_for_band(priv, ctx, channel->band,
+ ctx->vif);
+ }
- iwl_set_flags_for_band(priv, conf->channel->band, priv->vif);
spin_unlock_irqrestore(&priv->lock, flags);
- if (priv->cfg->ops->lib->update_bcast_station)
- ret = priv->cfg->ops->lib->update_bcast_station(priv);
+ if (priv->cfg->ops->lib->update_bcast_stations)
+ ret = priv->cfg->ops->lib->update_bcast_stations(priv);
set_ch_out:
/* The list of supported rates and rate mask can be different
@@ -2130,12 +2027,13 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
if (scan_active)
goto out;
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
- iwlcore_commit_rxon(priv);
- else
- IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration.\n");
-
+ for_each_context(priv, ctx) {
+ if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
+ iwlcore_commit_rxon(priv, ctx);
+ else
+ IWL_DEBUG_INFO(priv,
+ "Not re-sending same RXON configuration.\n");
+ }
out:
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -2148,6 +2046,8 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
unsigned long flags;
+ /* IBSS can only be the IWL_RXON_CTX_BSS context */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -2159,15 +2059,16 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
spin_lock_irqsave(&priv->lock, flags);
/* new association get rid of ibss beacon skb */
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
+ if (priv->beacon_skb)
+ dev_kfree_skb(priv->beacon_skb);
- priv->ibss_beacon = NULL;
+ priv->beacon_skb = NULL;
priv->timestamp = 0;
spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_scan_cancel_timeout(priv, 100);
if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
mutex_unlock(&priv->mutex);
@@ -2177,9 +2078,8 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
/* we are restarting association process
* clear RXON_FILTER_ASSOC_MSK bit
*/
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
iwl_set_rate(priv);
@@ -2193,7 +2093,8 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv)
{
if (!priv->txq)
priv->txq = kzalloc(
- sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues,
+ sizeof(struct iwl_tx_queue) *
+ priv->cfg->base_params->num_of_queues,
GFP_KERNEL);
if (!priv->txq) {
IWL_ERR(priv, "Not enough memory for txq\n");
@@ -2449,146 +2350,12 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
EXPORT_SYMBOL(iwl_update_stats);
#endif
-static const char *get_csr_string(int cmd)
-{
- switch (cmd) {
- IWL_CMD(CSR_HW_IF_CONFIG_REG);
- IWL_CMD(CSR_INT_COALESCING);
- IWL_CMD(CSR_INT);
- IWL_CMD(CSR_INT_MASK);
- IWL_CMD(CSR_FH_INT_STATUS);
- IWL_CMD(CSR_GPIO_IN);
- IWL_CMD(CSR_RESET);
- IWL_CMD(CSR_GP_CNTRL);
- IWL_CMD(CSR_HW_REV);
- IWL_CMD(CSR_EEPROM_REG);
- IWL_CMD(CSR_EEPROM_GP);
- IWL_CMD(CSR_OTP_GP_REG);
- IWL_CMD(CSR_GIO_REG);
- IWL_CMD(CSR_GP_UCODE_REG);
- IWL_CMD(CSR_GP_DRIVER_REG);
- IWL_CMD(CSR_UCODE_DRV_GP1);
- IWL_CMD(CSR_UCODE_DRV_GP2);
- IWL_CMD(CSR_LED_REG);
- IWL_CMD(CSR_DRAM_INT_TBL_REG);
- IWL_CMD(CSR_GIO_CHICKEN_BITS);
- IWL_CMD(CSR_ANA_PLL_CFG);
- IWL_CMD(CSR_HW_REV_WA_REG);
- IWL_CMD(CSR_DBG_HPET_MEM_REG);
- default:
- return "UNKNOWN";
-
- }
-}
-
-void iwl_dump_csr(struct iwl_priv *priv)
-{
- int i;
- u32 csr_tbl[] = {
- CSR_HW_IF_CONFIG_REG,
- CSR_INT_COALESCING,
- CSR_INT,
- CSR_INT_MASK,
- CSR_FH_INT_STATUS,
- CSR_GPIO_IN,
- CSR_RESET,
- CSR_GP_CNTRL,
- CSR_HW_REV,
- CSR_EEPROM_REG,
- CSR_EEPROM_GP,
- CSR_OTP_GP_REG,
- CSR_GIO_REG,
- CSR_GP_UCODE_REG,
- CSR_GP_DRIVER_REG,
- CSR_UCODE_DRV_GP1,
- CSR_UCODE_DRV_GP2,
- CSR_LED_REG,
- CSR_DRAM_INT_TBL_REG,
- CSR_GIO_CHICKEN_BITS,
- CSR_ANA_PLL_CFG,
- CSR_HW_REV_WA_REG,
- CSR_DBG_HPET_MEM_REG
- };
- IWL_ERR(priv, "CSR values:\n");
- IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
- "CSR_INT_PERIODIC_REG)\n");
- for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
- IWL_ERR(priv, " %25s: 0X%08x\n",
- get_csr_string(csr_tbl[i]),
- iwl_read32(priv, csr_tbl[i]));
- }
-}
-EXPORT_SYMBOL(iwl_dump_csr);
-
-static const char *get_fh_string(int cmd)
-{
- switch (cmd) {
- IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
- IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
- IWL_CMD(FH_RSCSR_CHNL0_WPTR);
- IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
- IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
- IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
- IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
- IWL_CMD(FH_TSSR_TX_STATUS_REG);
- IWL_CMD(FH_TSSR_TX_ERROR_REG);
- default:
- return "UNKNOWN";
-
- }
-}
-
-int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
-{
- int i;
-#ifdef CONFIG_IWLWIFI_DEBUG
- int pos = 0;
- size_t bufsz = 0;
-#endif
- u32 fh_tbl[] = {
- FH_RSCSR_CHNL0_STTS_WPTR_REG,
- FH_RSCSR_CHNL0_RBDCB_BASE_REG,
- FH_RSCSR_CHNL0_WPTR,
- FH_MEM_RCSR_CHNL0_CONFIG_REG,
- FH_MEM_RSSR_SHARED_CTRL_REG,
- FH_MEM_RSSR_RX_STATUS_REG,
- FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
- FH_TSSR_TX_STATUS_REG,
- FH_TSSR_TX_ERROR_REG
- };
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (display) {
- bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
- *buf = kmalloc(bufsz, GFP_KERNEL);
- if (!*buf)
- return -ENOMEM;
- pos += scnprintf(*buf + pos, bufsz - pos,
- "FH register values:\n");
- for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
- pos += scnprintf(*buf + pos, bufsz - pos,
- " %34s: 0X%08x\n",
- get_fh_string(fh_tbl[i]),
- iwl_read_direct32(priv, fh_tbl[i]));
- }
- return pos;
- }
-#endif
- IWL_ERR(priv, "FH register values:\n");
- for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
- IWL_ERR(priv, " %34s: 0X%08x\n",
- get_fh_string(fh_tbl[i]),
- iwl_read_direct32(priv, fh_tbl[i]));
- }
- return 0;
-}
-EXPORT_SYMBOL(iwl_dump_fh);
-
static void iwl_force_rf_reset(struct iwl_priv *priv)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- if (!iwl_is_associated(priv)) {
+ if (!iwl_is_any_associated(priv)) {
IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
return;
}
@@ -2613,11 +2380,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return -EINVAL;
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- IWL_DEBUG_INFO(priv, "scan in progress.\n");
- return -EINVAL;
- }
-
if (mode >= IWL_MAX_FORCE_RESET) {
IWL_DEBUG_INFO(priv, "invalid reset request.\n");
return -EINVAL;
@@ -2668,7 +2430,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
}
return 0;
}
-EXPORT_SYMBOL(iwl_force_reset);
/**
* iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover
@@ -2704,29 +2465,31 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
txq = &priv->txq[cnt];
q = &txq->q;
/* queue is empty, skip */
- if (q->read_ptr != q->write_ptr) {
- if (q->read_ptr == q->last_read_ptr) {
- /* a queue has not been read from last time */
- if (q->repeat_same_read_ptr > MAX_REPEAT) {
- IWL_ERR(priv,
- "queue %d stuck %d time. Fw reload.\n",
- q->id, q->repeat_same_read_ptr);
- q->repeat_same_read_ptr = 0;
- iwl_force_reset(priv, IWL_FW_RESET, false);
- } else {
- q->repeat_same_read_ptr++;
- IWL_DEBUG_RADIO(priv,
- "queue %d, not read %d time\n",
- q->id,
- q->repeat_same_read_ptr);
- mod_timer(&priv->monitor_recover, jiffies +
- msecs_to_jiffies(IWL_ONE_HUNDRED_MSECS));
- }
- return 1;
- } else {
- q->last_read_ptr = q->read_ptr;
+ if (q->read_ptr == q->write_ptr)
+ return 0;
+
+ if (q->read_ptr == q->last_read_ptr) {
+ /* a queue has not been read from last time */
+ if (q->repeat_same_read_ptr > MAX_REPEAT) {
+ IWL_ERR(priv,
+ "queue %d stuck %d time. Fw reload.\n",
+ q->id, q->repeat_same_read_ptr);
q->repeat_same_read_ptr = 0;
+ iwl_force_reset(priv, IWL_FW_RESET, false);
+ } else {
+ q->repeat_same_read_ptr++;
+ IWL_DEBUG_RADIO(priv,
+ "queue %d, not read %d time\n",
+ q->id,
+ q->repeat_same_read_ptr);
+ mod_timer(&priv->monitor_recover,
+ jiffies + msecs_to_jiffies(
+ IWL_ONE_HUNDRED_MSECS));
+ return 1;
}
+ } else {
+ q->last_read_ptr = q->read_ptr;
+ q->repeat_same_read_ptr = 0;
}
return 0;
}
@@ -2740,25 +2503,27 @@ void iwl_bg_monitor_recover(unsigned long data)
return;
/* monitor and check for stuck cmd queue */
- if (iwl_check_stuck_queue(priv, IWL_CMD_QUEUE_NUM))
+ if (iwl_check_stuck_queue(priv, priv->cmd_queue))
return;
/* monitor and check for other stuck queues */
- if (iwl_is_associated(priv)) {
+ if (iwl_is_any_associated(priv)) {
for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
/* skip as we already checked the command queue */
- if (cnt == IWL_CMD_QUEUE_NUM)
+ if (cnt == priv->cmd_queue)
continue;
if (iwl_check_stuck_queue(priv, cnt))
return;
}
}
- /*
- * Reschedule the timer to occur in
- * priv->cfg->monitor_recover_period
- */
- mod_timer(&priv->monitor_recover,
- jiffies + msecs_to_jiffies(priv->cfg->monitor_recover_period));
+ if (priv->cfg->base_params->monitor_recover_period) {
+ /*
+ * Reschedule the timer to occur in
+ * priv->cfg->base_params->monitor_recover_period
+ */
+ mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
+ priv->cfg->base_params->monitor_recover_period));
+ }
}
EXPORT_SYMBOL(iwl_bg_monitor_recover);
@@ -2830,7 +2595,7 @@ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
* it will not call apm_ops.stop() to stop the DMA operation.
* Calling apm_ops.stop here to make sure we stop the DMA.
*/
- priv->cfg->ops->lib->apm_ops.stop(priv);
+ iwl_apm_stop(priv);
pci_save_state(pdev);
pci_disable_device(pdev);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 5e6ee3da6bbf..64527def059f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -88,11 +88,13 @@ struct iwl_cmd;
#define IWL_CMD(x) case x: return #x
struct iwl_hcmd_ops {
- int (*rxon_assoc)(struct iwl_priv *priv);
- int (*commit_rxon)(struct iwl_priv *priv);
- void (*set_rxon_chain)(struct iwl_priv *priv);
+ 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);
int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant);
void (*send_bt_config)(struct iwl_priv *priv);
+ int (*set_pan_params)(struct iwl_priv *priv);
};
struct iwl_hcmd_utils_ops {
@@ -109,14 +111,13 @@ struct iwl_hcmd_utils_ops {
__le16 fc, __le32 *tx_flags);
int (*calc_rssi)(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp);
- void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
+ int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
+ void (*post_scan)(struct iwl_priv *priv);
};
struct iwl_apm_ops {
int (*init)(struct iwl_priv *priv);
- void (*stop)(struct iwl_priv *priv);
void (*config)(struct iwl_priv *priv);
- int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
};
struct iwl_debugfs_ops {
@@ -128,12 +129,18 @@ struct iwl_debugfs_ops {
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);
- void (*set_ct_kill)(struct iwl_priv *priv);
- void (*set_calib_version)(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 {
@@ -199,7 +206,7 @@ struct iwl_lib_ops {
/* station management */
int (*manage_ibss_station)(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add);
- int (*update_bcast_station)(struct iwl_priv *priv);
+ int (*update_bcast_stations)(struct iwl_priv *priv);
/* recover from tx queue stall */
void (*recover_from_tx_stall)(unsigned long data);
/* check for plcp health */
@@ -212,6 +219,9 @@ struct iwl_lib_ops {
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 {
@@ -220,11 +230,17 @@ struct iwl_led_ops {
int (*off)(struct iwl_priv *priv);
};
+/* NIC specific ops */
+struct iwl_nic_ops {
+ void (*additional_nic_config)(struct iwl_priv *priv);
+};
+
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;
};
struct iwl_mod_params {
@@ -237,20 +253,12 @@ struct iwl_mod_params {
int restart_fw; /* def: 1 = restart firmware */
};
-/**
- * struct iwl_cfg
- * @fw_name_pre: Firmware filename prefix. The api version and extension
- * (.ucode) will be added to filename before loading from disk. The
- * filename is constructed as fw_name_pre<api>.ucode.
- * @ucode_api_max: Highest version of uCode API supported by driver.
- * @ucode_api_min: Lowest version of uCode API supported by driver.
- * @pa_type: used by 6000 series only to identify the type of Power Amplifier
+/*
* @max_ll_items: max number of OTP blocks
* @shadow_ram_support: shadow support for OTP memory
* @led_compensation: compensate on the led on/off time per HW according
* to the deviation to achieve the desired led frequency.
* The detail algorithm is described in iwl-led.c
- * @use_rts_for_aggregation: use rts/cts protection for HT traffic
* @chain_noise_num_beacons: number of beacons used to compute chain noise
* @adv_thermal_throttle: support advance thermal throttle
* @support_ct_kill_exit: support ct kill exit condition
@@ -268,6 +276,73 @@ struct iwl_mod_params {
* sensitivity calibration operation
* @chain_noise_calib_by_driver: driver has the capability to perform
* chain noise calibration operation
+*/
+struct iwl_base_params {
+ int eeprom_size;
+ int num_of_queues; /* def: HW dependent */
+ 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;
+ const bool supports_idle;
+ bool adv_thermal_throttle;
+ bool support_ct_kill_exit;
+ const bool support_wimax_coexist;
+ u8 plcp_delta_threshold;
+ s32 chain_noise_scale;
+ /* timer period for monitor the driver queues */
+ u32 monitor_recover_period;
+ 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;
+};
+/*
+ * @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
+*/
+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;
+};
+/*
+ * @use_rts_for_aggregation: use rts/cts protection for HT traffic
+*/
+struct iwl_ht_params {
+ const bool ht_greenfield_support; /* if used set to true */
+ bool use_rts_for_aggregation;
+};
+
+/**
+ * struct iwl_cfg
+ * @fw_name_pre: Firmware filename prefix. The api version and extension
+ * (.ucode) will be added to filename before loading from disk. The
+ * filename is constructed as fw_name_pre<api>.ucode.
+ * @ucode_api_max: Highest version of uCode API supported by driver.
+ * @ucode_api_min: Lowest version of uCode API supported by driver.
+ * @pa_type: used by 6000 series only to identify the type of Power Amplifier
+ * @need_dc_calib: need to perform init dc calibration
+ * @need_temp_offset_calib: need to perform temperature offset calibration
* @scan_antennas: available antenna for scan operation
*
* We enable the driver to be backward compatible wrt API version. The
@@ -279,9 +354,9 @@ struct iwl_mod_params {
*
* For example,
* if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
- * Driver interacts with Firmware API version >= 2.
+ * Driver interacts with Firmware API version >= 2.
* } else {
- * Driver interacts with Firmware API version 1.
+ * Driver interacts with Firmware API version 1.
* }
*
* The ideal usage of this infrastructure is to treat a new ucode API
@@ -292,53 +367,29 @@ struct iwl_mod_params {
*
*/
struct iwl_cfg {
+ /* params specific to an individual device within a device family */
const char *name;
const char *fw_name_pre;
const unsigned int ucode_api_max;
const unsigned int ucode_api_min;
+ u8 valid_tx_ant;
+ u8 valid_rx_ant;
unsigned int sku;
- int eeprom_size;
u16 eeprom_ver;
u16 eeprom_calib_ver;
- int num_of_queues; /* def: HW dependent */
- int num_of_ampdu_queues;/* def: HW dependent */
const struct iwl_ops *ops;
+ /* module based parameters which can be set from modprobe cmd */
const struct iwl_mod_params *mod_params;
- u8 valid_tx_ant;
- u8 valid_rx_ant;
-
- /* for iwl_apm_init() */
- u32 pll_cfg_val;
- bool set_l0s;
- bool use_bsm;
-
- bool use_isr_legacy;
- enum iwl_pa_type pa_type;
- const u16 max_ll_items;
- const bool shadow_ram_support;
- const bool ht_greenfield_support;
- u16 led_compensation;
- const bool broken_powersave;
- bool use_rts_for_aggregation;
- int chain_noise_num_beacons;
- const bool supports_idle;
- bool adv_thermal_throttle;
- bool support_ct_kill_exit;
- const bool support_wimax_coexist;
- u8 plcp_delta_threshold;
- s32 chain_noise_scale;
- /* timer period for monitor the driver queues */
- u32 monitor_recover_period;
- 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;
+ /* params not likely to change within a device family */
+ struct iwl_base_params *base_params;
+ /* params likely to change within a device family */
+ struct iwl_ht_params *ht_params;
+ struct iwl_bt_params *bt_params;
+ enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */
+ const bool need_dc_calib; /* if used set to true */
+ const bool need_temp_offset_calib; /* if used set to true */
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
- const bool need_dc_calib;
- const bool bt_statistics;
};
/***************************
@@ -347,38 +398,38 @@ struct iwl_cfg {
struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_ops *hw_ops);
-void iwl_hw_detect(struct iwl_priv *priv);
-void iwl_activate_qos(struct iwl_priv *priv);
int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
-void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
-int iwl_check_rxon_cmd(struct iwl_priv *priv);
-int iwl_full_rxon_required(struct iwl_priv *priv);
-void iwl_set_rxon_chain(struct iwl_priv *priv);
-int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
+int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ int hw_decrypt);
+int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
+ struct iwl_rxon_context *ctx);
void iwl_set_flags_for_band(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
enum ieee80211_band band,
struct ieee80211_vif *vif);
u8 iwl_get_single_channel_number(struct iwl_priv *priv,
enum ieee80211_band band);
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
-u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
- struct ieee80211_sta_ht_cap *sta_ht_inf);
+bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_sta_ht_cap *ht_cap);
void iwl_connection_init_rx_config(struct iwl_priv *priv,
- struct ieee80211_vif *vif);
+ struct iwl_rxon_context *ctx);
void iwl_set_rate(struct iwl_priv *priv);
int iwl_set_decrypted_flag(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
u32 decrypt_res,
struct ieee80211_rx_status *stats);
void iwl_irq_handle_error(struct iwl_priv *priv);
-int iwl_set_hw_params(struct iwl_priv *priv);
void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
void iwl_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changes);
-int iwl_commit_rxon(struct iwl_priv *priv);
int iwl_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
void iwl_mac_remove_interface(struct ieee80211_hw *hw,
@@ -455,7 +506,6 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
******************************************************/
void iwl_cmd_queue_free(struct iwl_priv *priv);
int iwl_rx_queue_alloc(struct iwl_priv *priv);
-void iwl_rx_handle(struct iwl_priv *priv);
void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
struct iwl_rx_queue *q);
int iwl_rx_queue_space(const struct iwl_rx_queue *q);
@@ -473,12 +523,6 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
/*****************************************************
* TX
******************************************************/
-void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
-int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
- struct iwl_tx_queue *txq,
- dma_addr_t addr, u16 len, u8 reset, u8 pad);
-int iwl_hw_tx_queue_init(struct iwl_priv *priv,
- struct iwl_tx_queue *txq);
void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id);
@@ -494,29 +538,8 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
* Rate
******************************************************************************/
-int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
-
-u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
-
-u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
-
-static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
-{
- return BIT(ant_idx) << RATE_MCS_ANT_POS;
-}
-
-static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
-{
- return le32_to_cpu(rate_n_flags) & 0xFF;
-}
-static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags)
-{
- return le32_to_cpu(rate_n_flags) & 0x1FFFF;
-}
-static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
-{
- return cpu_to_le32(flags|(u32)rate);
-}
+u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
/*******************************************************************************
* Scanning
@@ -524,10 +547,10 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
+void iwl_force_scan_end(struct iwl_priv *priv);
int iwl_mac_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_scan_request *req);
-void iwl_bg_start_internal_scan(struct work_struct *work);
void iwl_internal_short_hw_scan(struct iwl_priv *priv);
int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
@@ -539,10 +562,8 @@ u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
enum ieee80211_band band,
struct ieee80211_vif *vif);
-void iwl_bg_scan_check(struct work_struct *data);
-void iwl_bg_abort_scan(struct work_struct *work);
-void iwl_bg_scan_completed(struct work_struct *work);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
/* For faster active scanning, scan will move to the next channel if fewer than
* PLCP_QUIET_THRESH packets are heard on this channel within
@@ -555,13 +576,6 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
#define IWL_SCAN_CHECK_WATCHDOG (HZ * 7)
-/*******************************************************************************
- * Calibrations - implemented in iwl-calib.c
- ******************************************************************************/
-int iwl_send_calib_results(struct iwl_priv *priv);
-int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
-void iwl_calib_free_results(struct iwl_priv *priv);
-
/*****************************************************
* S e n d i n g H o s t C o m m a n d s *
*****************************************************/
@@ -580,8 +594,6 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
-int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
- u8 meta_flag);
/*****************************************************
* PCI *
@@ -613,12 +625,12 @@ int iwl_pci_resume(struct pci_dev *pdev);
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);
+void iwl_print_rx_config_cmd(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
#else
-static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv)
+static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
}
#endif
@@ -695,23 +707,22 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
return iwl_is_ready(priv);
}
-extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
extern void iwl_send_bt_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv,
u8 flags, bool clear);
-extern int iwl_send_lq_cmd(struct iwl_priv *priv,
- struct iwl_link_quality_cmd *lq, u8 flags, bool init);
void iwl_apm_stop(struct iwl_priv *priv);
int iwl_apm_init(struct iwl_priv *priv);
-void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif);
-static inline int iwl_send_rxon_assoc(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);
+ return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx);
}
-static inline int iwlcore_commit_rxon(struct iwl_priv *priv)
+static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
- return priv->cfg->ops->hcmd->commit_rxon(priv);
+ return priv->cfg->ops->hcmd->commit_rxon(priv, ctx);
}
static inline void iwlcore_config_ap(struct iwl_priv *priv,
struct ieee80211_vif *vif)
@@ -723,4 +734,8 @@ static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
{
return priv->hw->wiphy->bands[band];
}
+
+extern bool bt_coex_active;
+extern bool bt_siso_mode;
+
#endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index ecf98e7ac4ed..2aa15ab13892 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -371,7 +371,8 @@
#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000)
#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001)
#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002)
-#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004)
+#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004)
+#define CSR_GP_DRIVER_REG_BIT_6050_1x2 (0x00000008)
/* GIO Chicken Bits (PCI Express bus link power management) */
#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index a32d5d337649..8fdd4efdb1d3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -39,7 +39,6 @@
#include "iwl-debug.h"
#include "iwl-core.h"
#include "iwl-io.h"
-#include "iwl-calib.h"
/* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
@@ -359,7 +358,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
const u8 *ptr;
char *buf;
u16 eeprom_ver;
- size_t eeprom_len = priv->cfg->eeprom_size;
+ size_t eeprom_len = priv->cfg->base_params->eeprom_size;
buf_size = 4 * eeprom_len + 256;
if (eeprom_len % 16) {
@@ -470,8 +469,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
for (i = 0; i < supp_band->n_channels; i++)
pos += scnprintf(buf + pos, bufsz - pos,
"%d: %ddBm: BSS%s%s, %s.\n",
- ieee80211_frequency_to_channel(
- channels[i].center_freq),
+ channels[i].hw_value,
channels[i].max_power,
channels[i].flags & IEEE80211_CHAN_RADAR ?
" (IEEE 802.11h required)" : "",
@@ -494,8 +492,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
for (i = 0; i < supp_band->n_channels; i++)
pos += scnprintf(buf + pos, bufsz - pos,
"%d: %ddBm: BSS%s%s, %s.\n",
- ieee80211_frequency_to_channel(
- channels[i].center_freq),
+ channels[i].hw_value,
channels[i].max_power,
channels[i].flags & IEEE80211_CHAN_RADAR ?
" (IEEE 802.11h required)" : "",
@@ -580,10 +577,10 @@ static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
priv->isr_stats.hw);
pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
priv->isr_stats.sw);
- if (priv->isr_stats.sw > 0) {
+ if (priv->isr_stats.sw || priv->isr_stats.hw) {
pos += scnprintf(buf + pos, bufsz - pos,
"\tLast Restarting Code: 0x%X\n",
- priv->isr_stats.sw_err);
+ priv->isr_stats.err_code);
}
#ifdef CONFIG_IWLWIFI_DEBUG
pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
@@ -648,19 +645,25 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
+ struct iwl_rxon_context *ctx;
int pos = 0, i;
- char buf[256];
+ char buf[256 * NUM_IWL_RXON_CTX];
const size_t bufsz = sizeof(buf);
- for (i = 0; i < AC_NUM; i++) {
- pos += scnprintf(buf + pos, bufsz - pos,
- "\tcw_min\tcw_max\taifsn\ttxop\n");
- pos += scnprintf(buf + pos, bufsz - pos,
+ for_each_context(priv, ctx) {
+ pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n",
+ ctx->ctxid);
+ for (i = 0; i < AC_NUM; i++) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\tcw_min\tcw_max\taifsn\ttxop\n");
+ pos += scnprintf(buf + pos, bufsz - pos,
"AC[%d]\t%u\t%u\t%u\t%u\n", i,
- priv->qos_data.def_qos_parm.ac[i].cw_min,
- priv->qos_data.def_qos_parm.ac[i].cw_max,
- priv->qos_data.def_qos_parm.ac[i].aifsn,
- priv->qos_data.def_qos_parm.ac[i].edca_txop);
+ ctx->qos_data.def_qos_parm.ac[i].cw_min,
+ ctx->qos_data.def_qos_parm.ac[i].cw_max,
+ ctx->qos_data.def_qos_parm.ac[i].aifsn,
+ ctx->qos_data.def_qos_parm.ac[i].edca_txop);
+ }
+ pos += scnprintf(buf + pos, bufsz - pos, "\n");
}
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
@@ -735,7 +738,7 @@ static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
return -EFAULT;
if (sscanf(buf, "%d", &ht40) != 1)
return -EFAULT;
- if (!iwl_is_associated(priv))
+ if (!iwl_is_any_associated(priv))
priv->disable_ht40 = ht40 ? true : false;
else {
IWL_ERR(priv, "Sta associated with AP - "
@@ -871,7 +874,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
struct iwl_rx_queue *rxq = &priv->rxq;
char *buf;
int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
- (priv->cfg->num_of_queues * 32 * 8) + 400;
+ (priv->cfg->base_params->num_of_queues * 32 * 8) + 400;
const u8 *ptr;
ssize_t ret;
@@ -970,7 +973,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
int pos = 0;
int cnt;
int ret;
- const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues;
+ const size_t bufsz = sizeof(char) * 64 *
+ priv->cfg->base_params->num_of_queues;
if (!priv->txq) {
IWL_ERR(priv, "txq not ready\n");
@@ -1324,7 +1328,8 @@ static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file,
int len = 0;
char buf[20];
- len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags));
+ len = sprintf(buf, "0x%04X\n",
+ le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags));
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
@@ -1337,7 +1342,7 @@ static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file,
char buf[20];
len = sprintf(buf, "0x%04X\n",
- le32_to_cpu(priv->active_rxon.filter_flags));
+ le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags));
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
@@ -1413,7 +1418,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
const size_t bufsz = sizeof(buf);
pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
- priv->cfg->plcp_delta_threshold);
+ priv->cfg->base_params->plcp_delta_threshold);
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
@@ -1435,10 +1440,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
return -EINVAL;
if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
(plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
- priv->cfg->plcp_delta_threshold =
+ priv->cfg->base_params->plcp_delta_threshold =
IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE;
else
- priv->cfg->plcp_delta_threshold = plcp;
+ priv->cfg->base_params->plcp_delta_threshold = plcp;
return count;
}
@@ -1532,6 +1537,135 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
user_buf, count, ppos);
}
+static ssize_t iwl_dbgfs_monitor_period_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos) {
+
+ struct iwl_priv *priv = file->private_data;
+ char buf[8];
+ int buf_size;
+ int period;
+
+ memset(buf, 0, sizeof(buf));
+ buf_size = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ if (sscanf(buf, "%d", &period) != 1)
+ return -EINVAL;
+ if (period < 0 || period > IWL_MAX_MONITORING_PERIOD)
+ priv->cfg->base_params->monitor_recover_period =
+ IWL_DEF_MONITORING_PERIOD;
+ else
+ priv->cfg->base_params->monitor_recover_period = period;
+
+ if (priv->cfg->base_params->monitor_recover_period)
+ mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
+ priv->cfg->base_params->monitor_recover_period));
+ else
+ del_timer_sync(&priv->monitor_recover);
+ return count;
+}
+
+static ssize_t iwl_dbgfs_bt_traffic_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[200];
+ const size_t bufsz = sizeof(buf);
+ ssize_t ret;
+
+ pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n",
+ priv->bt_full_concurrent ? "full concurrency" : "3-wire");
+ pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, "
+ "last traffic notif: %d\n",
+ priv->bt_status ? "On" : "Off", priv->notif_bt_traffic_load);
+ pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, "
+ "sco_active: %d, kill_ack_mask: %x, "
+ "kill_cts_mask: %x\n",
+ priv->bt_ch_announce, priv->bt_sco_active,
+ priv->kill_ack_mask, priv->kill_cts_mask);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: ");
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ pos += scnprintf(buf + pos, bufsz - pos, "Continuous\n");
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ pos += scnprintf(buf + pos, bufsz - pos, "High\n");
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ pos += scnprintf(buf + pos, bufsz - pos, "Low\n");
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ default:
+ pos += scnprintf(buf + pos, bufsz - pos, "None\n");
+ break;
+ }
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_protection_mode_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[40];
+ const size_t bufsz = sizeof(buf);
+
+ if (priv->cfg->ht_params)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "use %s for aggregation\n",
+ (priv->cfg->ht_params->use_rts_for_aggregation) ?
+ "rts/cts" : "cts-to-self");
+ else
+ pos += scnprintf(buf + pos, bufsz - pos, "N/A");
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos) {
+
+ struct iwl_priv *priv = file->private_data;
+ char buf[8];
+ int buf_size;
+ int rts;
+
+ if (!priv->cfg->ht_params)
+ return -EINVAL;
+
+ memset(buf, 0, sizeof(buf));
+ buf_size = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ if (sscanf(buf, "%d", &rts) != 1)
+ return -EINVAL;
+ if (rts)
+ priv->cfg->ht_params->use_rts_for_aggregation = true;
+ else
+ priv->cfg->ht_params->use_rts_for_aggregation = false;
+ 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);
@@ -1555,6 +1689,10 @@ DEBUGFS_READ_FILE_OPS(rxon_flags);
DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
DEBUGFS_READ_FILE_OPS(ucode_bt_stats);
+DEBUGFS_WRITE_FILE_OPS(monitor_period);
+DEBUGFS_READ_FILE_OPS(bt_traffic);
+DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
+DEBUGFS_READ_FILE_OPS(reply_tx_error);
/*
* Create the debugfs files and directories
@@ -1590,7 +1728,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
- if (!priv->cfg->broken_powersave) {
+ 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);
@@ -1615,24 +1753,29 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
if (priv->cfg->ops->lib->dev_txfifo_flush)
DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
+ DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR);
- if (priv->cfg->sensitivity_calib_by_driver)
+ if (priv->cfg->base_params->sensitivity_calib_by_driver)
DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
- if (priv->cfg->chain_noise_calib_by_driver)
+ if (priv->cfg->base_params->chain_noise_calib_by_driver)
DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
- if (priv->cfg->ucode_tracing)
+ if (priv->cfg->base_params->ucode_tracing)
DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
- if (priv->cfg->bt_statistics)
+ if (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics)
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);
- if (priv->cfg->sensitivity_calib_by_driver)
+ DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR);
+ if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
+ 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->chain_noise_calib_by_driver)
+ 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->tx_power_by_driver)
+ if (priv->cfg->base_params->tx_power_by_driver)
DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
&priv->disable_tx_power_cal);
return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 2e97cd2fa98a..70e07fa48405 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -47,6 +47,7 @@
#include "iwl-led.h"
#include "iwl-power.h"
#include "iwl-agn-rs.h"
+#include "iwl-agn-tt.h"
struct iwl_tx_queue;
@@ -143,6 +144,7 @@ struct iwl_queue {
/* One for each TFD */
struct iwl_tx_info {
struct sk_buff *skb;
+ struct iwl_rxon_context *ctx;
};
/**
@@ -252,10 +254,14 @@ struct iwl_channel_info {
struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
};
-#define IWL_TX_FIFO_BK 0
+#define IWL_TX_FIFO_BK 0 /* shared */
#define IWL_TX_FIFO_BE 1
-#define IWL_TX_FIFO_VI 2
+#define IWL_TX_FIFO_VI 2 /* shared */
#define IWL_TX_FIFO_VO 3
+#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK
+#define IWL_TX_FIFO_BE_IPAN 4
+#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI
+#define IWL_TX_FIFO_VO_IPAN 5
#define IWL_TX_FIFO_UNUSED -1
/* Minimum number of queues. MAX_NUM is defined in hw specific files.
@@ -264,18 +270,17 @@ struct iwl_channel_info {
#define IWL_MIN_NUM_QUEUES 10
/*
- * Queue #4 is the command queue for 3945/4965/5x00/1000/6x00,
- * the driver maps it into the appropriate device FIFO for the
- * uCode.
+ * Command queue depends on iPAN support.
*/
-#define IWL_CMD_QUEUE_NUM 4
+#define IWL_DEFAULT_CMD_QUEUE_NUM 4
+#define IWL_IPAN_CMD_QUEUE_NUM 9
-/* Power management (not Tx power) structures */
-
-enum iwl_pwr_src {
- IWL_PWR_SRC_VMAIN,
- IWL_PWR_SRC_VAUX,
-};
+/*
+ * This queue number is required for proper operation
+ * because the ucode will stop/start the scheduler as
+ * required.
+ */
+#define IWL_IPAN_MCAST_QUEUE 8
#define IEEE80211_DATA_LEN 2304
#define IEEE80211_4ADDR_LEN 30
@@ -420,7 +425,7 @@ struct iwl_tid_data {
};
struct iwl_hw_key {
- enum ieee80211_key_alg alg;
+ u32 cipher;
int keylen;
u8 keyidx;
u8 key[32];
@@ -434,7 +439,13 @@ union iwl_ht_rate_supp {
};
};
-#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3)
+#define CFG_HT_RX_AMPDU_FACTOR_8K (0x0)
+#define CFG_HT_RX_AMPDU_FACTOR_16K (0x1)
+#define CFG_HT_RX_AMPDU_FACTOR_32K (0x2)
+#define CFG_HT_RX_AMPDU_FACTOR_64K (0x3)
+#define CFG_HT_RX_AMPDU_FACTOR_DEF CFG_HT_RX_AMPDU_FACTOR_64K
+#define CFG_HT_RX_AMPDU_FACTOR_MAX CFG_HT_RX_AMPDU_FACTOR_64K
+#define CFG_HT_RX_AMPDU_FACTOR_MIN CFG_HT_RX_AMPDU_FACTOR_8K
/*
* Maximal MPDU density for TX aggregation
@@ -443,19 +454,17 @@ union iwl_ht_rate_supp {
* 6 - 8us density
* 7 - 16us density
*/
+#define CFG_HT_MPDU_DENSITY_2USEC (0x4)
#define CFG_HT_MPDU_DENSITY_4USEC (0x5)
+#define CFG_HT_MPDU_DENSITY_8USEC (0x6)
+#define CFG_HT_MPDU_DENSITY_16USEC (0x7)
#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC
+#define CFG_HT_MPDU_DENSITY_MAX CFG_HT_MPDU_DENSITY_16USEC
+#define CFG_HT_MPDU_DENSITY_MIN (0x1)
struct iwl_ht_config {
- /* self configuration data */
- bool is_ht;
- bool is_40mhz;
bool single_chain_sufficient;
enum ieee80211_smps_mode smps; /* current smps mode */
- /* BSS related data */
- u8 extension_chan_offset;
- u8 ht_protection;
- u8 non_GF_STA_present;
};
/* QoS structures */
@@ -473,12 +482,13 @@ struct iwl_qos_info {
struct iwl_station_entry {
struct iwl_addsta_cmd sta;
struct iwl_tid_data tid[MAX_TID_COUNT];
- u8 used;
+ u8 used, ctxid;
struct iwl_hw_key keyinfo;
struct iwl_link_quality_cmd *lq;
};
struct iwl_station_priv_common {
+ struct iwl_rxon_context *ctx;
u8 sta_id;
};
@@ -507,6 +517,7 @@ struct iwl_station_priv {
* space for us to put data into.
*/
struct iwl_vif_priv {
+ struct iwl_rxon_context *ctx;
u8 ibss_bssid_sta_id;
};
@@ -564,6 +575,7 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_INIT_DATA = 4,
IWL_UCODE_TLV_BOOT = 5,
IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */
+ IWL_UCODE_TLV_PAN = 7,
IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8,
IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9,
IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10,
@@ -658,7 +670,6 @@ struct iwl_sensitivity_ranges {
* @rx_page_order: Rx buffer page order
* @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
* @max_stations:
- * @bcast_sta_id:
* @ht40_channel: is 40MHz width possible in band 2.4
* BIT(IEEE80211_BAND_5GHZ) BIT(IEEE80211_BAND_5GHZ)
* @sw_crypto: 0 for hw, 1 for sw
@@ -666,6 +677,7 @@ struct iwl_sensitivity_ranges {
* @ct_kill_threshold: temperature threshold
* @beacon_time_tsf_bits: number of valid tsf bits for beacon time
* @calib_init_cfg: setup initial calibrations for the hw
+ * @calib_rt_cfg: setup runtime calibrations for the hw
* @struct iwl_sensitivity_ranges: range of sensitivity values
*/
struct iwl_hw_params {
@@ -682,7 +694,6 @@ struct iwl_hw_params {
u32 rx_page_order;
u32 rx_wrt_ptr_reg;
u8 max_stations;
- u8 bcast_sta_id;
u8 ht40_channel;
u8 max_beacon_itrvl; /* in 1024 ms */
u32 max_inst_size;
@@ -693,6 +704,7 @@ struct iwl_hw_params {
/* for 1000, 6000 series and up */
u16 beacon_time_tsf_bits;
u32 calib_init_cfg;
+ u32 calib_rt_cfg;
const struct iwl_sensitivity_ranges *sens;
};
@@ -713,7 +725,6 @@ struct iwl_hw_params {
*
****************************************************************************/
extern void iwl_update_chain_flags(struct iwl_priv *priv);
-extern int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
extern const u8 iwl_bcast_addr[ETH_ALEN];
extern int iwl_rxq_stop(struct iwl_priv *priv);
extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
@@ -824,6 +835,7 @@ enum iwl_calib {
IWL_CALIB_TX_IQ,
IWL_CALIB_TX_IQ_PERD,
IWL_CALIB_BASE_BAND,
+ IWL_CALIB_TEMP_OFFSET,
IWL_CALIB_MAX
};
@@ -928,7 +940,7 @@ enum iwl_pa_type {
struct isr_statistics {
u32 hw;
u32 sw;
- u32 sw_err;
+ u32 err_code;
u32 sch;
u32 alive;
u32 rfkill;
@@ -940,6 +952,50 @@ struct isr_statistics {
u32 unhandled;
};
+/* reply_tx_statistics (for _agn devices) */
+struct reply_tx_error_statistics {
+ u32 pp_delay;
+ u32 pp_few_bytes;
+ u32 pp_bt_prio;
+ u32 pp_quiet_period;
+ u32 pp_calc_ttak;
+ u32 int_crossed_retry;
+ u32 short_limit;
+ u32 long_limit;
+ u32 fifo_underrun;
+ u32 drain_flow;
+ u32 rfkill_flush;
+ u32 life_expire;
+ u32 dest_ps;
+ u32 host_abort;
+ u32 bt_retry;
+ u32 sta_invalid;
+ u32 frag_drop;
+ u32 tid_disable;
+ u32 fifo_flush;
+ u32 insuff_cf_poll;
+ u32 fail_hw_drop;
+ u32 sta_color_mismatch;
+ u32 unknown;
+};
+
+/* reply_agg_tx_statistics (for _agn devices) */
+struct reply_agg_tx_error_statistics {
+ u32 underrun;
+ u32 bt_prio;
+ u32 few_bytes;
+ u32 abort;
+ u32 last_sent_ttl;
+ u32 last_sent_try;
+ u32 last_sent_bt_kill;
+ u32 scd_query;
+ u32 bad_crc32;
+ u32 response;
+ u32 dump_tx;
+ u32 delay_tx;
+ u32 unknown;
+};
+
#ifdef CONFIG_IWLWIFI_DEBUGFS
/* management statistics */
enum iwl_mgmt_stats {
@@ -1052,7 +1108,10 @@ struct iwl_event_log {
#define IWL_DEF_MONITORING_PERIOD (1000)
#define IWL_LONG_MONITORING_PERIOD (5000)
#define IWL_ONE_HUNDRED_MSECS (100)
-#define IWL_SIXTY_SECS (60000)
+#define IWL_MAX_MONITORING_PERIOD (60000)
+
+/* BT Antenna Coupling Threshold (dB) */
+#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
enum iwl_reset {
IWL_RF_RESET = 0,
@@ -1082,6 +1141,64 @@ struct iwl_force_reset {
*/
#define IWLAGN_EXT_BEACON_TIME_POS 22
+enum iwl_rxon_context_id {
+ IWL_RXON_CTX_BSS,
+ IWL_RXON_CTX_PAN,
+
+ NUM_IWL_RXON_CTX
+};
+
+struct iwl_rxon_context {
+ struct ieee80211_vif *vif;
+
+ const u8 *ac_to_fifo;
+ const u8 *ac_to_queue;
+ u8 mcast_queue;
+
+ /*
+ * We could use the vif to indicate active, but we
+ * also need it to be active during disabling when
+ * we already removed the vif for type setting.
+ */
+ bool always_active, is_active;
+
+ enum iwl_rxon_context_id ctxid;
+
+ u32 interface_modes, exclusive_interface_modes;
+ u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype;
+
+ /*
+ * We declare this const so it can only be
+ * changed via explicit cast within the
+ * routines that actually update the physical
+ * hardware.
+ */
+ const struct iwl_rxon_cmd active;
+ struct iwl_rxon_cmd staging;
+
+ struct iwl_rxon_time_cmd timing;
+
+ struct iwl_qos_info qos_data;
+
+ u8 bcast_sta_id, ap_sta_id;
+
+ u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd;
+ u8 qos_cmd;
+ u8 wep_key_cmd;
+
+ struct iwl_wep_key wep_keys[WEP_KEYS_MAX];
+ u8 key_mapping_keys;
+
+ __le32 station_flags;
+
+ struct {
+ bool non_gf_sta_present;
+ u8 protection;
+ bool enabled, is_40mhz;
+ u8 extension_chan_offset;
+ } ht;
+};
+
struct iwl_priv {
/* ieee device used by generic ieee processing code */
@@ -1110,6 +1227,9 @@ struct iwl_priv {
u32 ucode_beacon_time;
int missed_beacon_threshold;
+ /* track IBSS manager (last beacon) status */
+ u32 ibss_manager;
+
/* storing the jiffies when the plcp error rate is received */
unsigned long plcp_jiffies;
@@ -1155,6 +1275,15 @@ struct iwl_priv {
u32 hw_wa_rev;
u8 rev_id;
+ /* microcode/device supports multiple contexts */
+ u8 valid_contexts;
+
+ /* command queue number */
+ u8 cmd_queue;
+
+ /* max number of station keys */
+ u8 sta_key_max_num;
+
/* EEPROM MAC addresses */
struct mac_address addresses[2];
@@ -1172,15 +1301,7 @@ struct iwl_priv {
u8 ucode_write_complete; /* the image write is complete */
char firmware_name[25];
-
- struct iwl_rxon_time_cmd rxon_timing;
-
- /* We declare this const so it can only be
- * changed via explicit cast within the
- * routines that actually update the physical
- * hardware */
- const struct iwl_rxon_cmd active_rxon;
- struct iwl_rxon_cmd staging_rxon;
+ struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
struct iwl_switch_rxon switch_rxon;
@@ -1242,8 +1363,6 @@ struct iwl_priv {
spinlock_t sta_lock;
int num_stations;
struct iwl_station_entry stations[IWL_STATION_COUNT];
- struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; /* protected by mutex */
- u8 key_mapping_key;
unsigned long ucode_key_table;
/* queue refcounts */
@@ -1264,11 +1383,8 @@ struct iwl_priv {
enum nl80211_iftype iw_mode;
- struct sk_buff *ibss_beacon;
-
/* Last Rx'd beacon timestamp */
u64 timestamp;
- struct ieee80211_vif *vif;
union {
#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE)
@@ -1336,6 +1452,9 @@ struct iwl_priv {
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;
#ifdef CONFIG_IWLWIFI_DEBUGFS
struct iwl_notif_statistics accum_statistics;
struct iwl_notif_statistics delta_statistics;
@@ -1348,24 +1467,45 @@ struct iwl_priv {
#endif
};
+ /* bt coex */
+ u8 bt_status;
+ u8 bt_traffic_load, notif_bt_traffic_load;
+ bool bt_ch_announce;
+ bool bt_sco_active;
+ bool bt_full_concurrent;
+ bool bt_ant_couple_ok;
+ __le32 kill_ack_mask;
+ __le32 kill_cts_mask;
+ __le16 bt_valid;
+ u16 bt_on_thresh;
+ u16 bt_duration;
+ u16 dynamic_frag_thresh;
+ u16 dynamic_agg_thresh;
+ u8 bt_ci_compliance;
+ struct work_struct bt_traffic_change_work;
+
struct iwl_hw_params hw_params;
u32 inta_mask;
- struct iwl_qos_info qos_data;
-
struct workqueue_struct *workqueue;
struct work_struct restart;
struct work_struct scan_completed;
struct work_struct rx_replenish;
struct work_struct abort_scan;
+
struct work_struct beacon_update;
+ struct iwl_rxon_context *beacon_ctx;
+ struct sk_buff *beacon_skb;
+
struct work_struct tt_work;
struct work_struct ct_enter;
struct work_struct ct_exit;
struct work_struct start_internal_scan;
struct work_struct tx_flush;
+ struct work_struct bt_full_concurrency;
+ struct work_struct bt_runtime_config;
struct tasklet_struct irq_tasklet;
@@ -1419,7 +1559,6 @@ static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
}
#ifdef CONFIG_IWLWIFI_DEBUG
-const char *iwl_get_tx_fail_reason(u32 status);
/*
* iwl_get_debug_level: Return active debug level for device
*
@@ -1435,8 +1574,6 @@ static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
return iwl_debug_level;
}
#else
-static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
-
static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
{
return iwl_debug_level;
@@ -1453,10 +1590,34 @@ static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
return NULL;
}
+static inline struct iwl_rxon_context *
+iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif)
+{
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+
+ return vif_priv->ctx;
+}
+
+#define for_each_context(priv, ctx) \
+ for (ctx = &priv->contexts[IWL_RXON_CTX_BSS]; \
+ 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)
+{
+ return (priv->contexts[ctxid].active.filter_flags &
+ RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+}
+
+static inline int iwl_is_any_associated(struct iwl_priv *priv)
+{
+ return iwl_is_associated(priv, IWL_RXON_CTX_BSS);
+}
-static inline int iwl_is_associated(struct iwl_priv *priv)
+static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
{
- return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+ return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
}
static inline int is_channel_valid(const struct iwl_channel_info *ch_info)
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index a45d02e555cf..87cd10ff285d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -136,85 +136,13 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */
36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157
};
-/**
- * struct iwl_txpwr_section: eeprom section information
- * @offset: indirect address into eeprom image
- * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
- * @band: band type for the section
- * @is_common - true: common section, false: channel section
- * @is_cck - true: cck section, false: not cck section
- * @is_ht_40 - true: all channel in the section are HT40 channel,
- * false: legacy or HT 20 MHz
- * ignore if it is common section
- * @iwl_eeprom_section_channel: channel array in the section,
- * ignore if common section
- */
-struct iwl_txpwr_section {
- u32 offset;
- u8 count;
- enum ieee80211_band band;
- bool is_common;
- bool is_cck;
- bool is_ht40;
- u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
-};
-
-/**
- * section 1 - 3 are regulatory tx power apply to all channels based on
- * modulation: CCK, OFDM
- * Band: 2.4GHz, 5.2GHz
- * section 4 - 10 are regulatory tx power apply to specified channels
- * For example:
- * 1L - Channel 1 Legacy
- * 1HT - Channel 1 HT
- * (1,+1) - Channel 1 HT40 "_above_"
- *
- * Section 1: all CCK channels
- * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
- * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
- * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
- * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
- * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
- * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
- * Section 8: 2.4 GHz channel: 13L, 13HT
- * Section 9: 2.4 GHz channel: 140L, 140HT
- * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1)
- *
- */
-static const struct iwl_txpwr_section enhinfo[] = {
- { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
- { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
- { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
- { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
- false, false, false,
- {1, 1, 2, 2, 10, 10, 11, 11 } },
- { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
- false, false, true,
- { 1, 2, 6, 7, 9 } },
- { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
- false, false, false,
- { 36, 64, 100, 36, 64, 100 } },
- { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
- false, false, true,
- { 36, 60, 100 } },
- { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
- false, false, false,
- { 13, 13 } },
- { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
- false, false, false,
- { 140, 140 } },
- { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
- false, false, true,
- { 132, 44 } },
-};
-
/******************************************************************************
*
* EEPROM related functions
*
******************************************************************************/
-int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
+static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
{
u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
int ret = 0;
@@ -246,7 +174,6 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
}
return ret;
}
-EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
{
@@ -290,49 +217,9 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv)
return nvm_type;
}
-/*
- * The device's EEPROM semaphore prevents conflicts between driver and uCode
- * when accessing the EEPROM; each access is a series of pulses to/from the
- * 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;
-}
-EXPORT_SYMBOL(iwlcore_eeprom_acquire_semaphore);
-
-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);
-
-}
-EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
-
const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
{
- BUG_ON(offset >= priv->cfg->eeprom_size);
+ BUG_ON(offset >= priv->cfg->base_params->eeprom_size);
return &priv->eeprom[offset];
}
EXPORT_SYMBOL(iwlcore_eeprom_query_addr);
@@ -364,7 +251,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
* CSR auto clock gate disable bit -
* this is only applicable for HW with OTP shadow RAM
*/
- if (priv->cfg->shadow_ram_support)
+ if (priv->cfg->base_params->shadow_ram_support)
iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG,
CSR_RESET_LINK_PWR_MGMT_DISABLED);
}
@@ -484,13 +371,27 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
}
/* more in the link list, continue */
usedblocks++;
- } while (usedblocks <= priv->cfg->max_ll_items);
+ } while (usedblocks <= priv->cfg->base_params->max_ll_items);
/* OTP has no valid blocks */
IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n");
return -EINVAL;
}
+const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
+{
+ return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
+}
+EXPORT_SYMBOL(iwl_eeprom_query_addr);
+
+u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
+{
+ if (!priv->eeprom)
+ return 0;
+ return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
+}
+EXPORT_SYMBOL(iwl_eeprom_query16);
+
/**
* iwl_eeprom_init - read EEPROM contents
*
@@ -512,8 +413,8 @@ int iwl_eeprom_init(struct iwl_priv *priv)
if (priv->nvm_device_type == -ENOENT)
return -ENOENT;
/* allocate eeprom */
- IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size);
- sz = priv->cfg->eeprom_size;
+ sz = priv->cfg->base_params->eeprom_size;
+ IWL_DEBUG_INFO(priv, "NVM size = %d\n", sz);
priv->eeprom = kzalloc(sz, GFP_KERNEL);
if (!priv->eeprom) {
ret = -ENOMEM;
@@ -523,7 +424,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
priv->cfg->ops->lib->apm_ops.init(priv);
- ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
+ ret = iwl_eeprom_verify_signature(priv);
if (ret < 0) {
IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
ret = -ENOENT;
@@ -554,7 +455,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
/* traversing the linked list if no shadow ram supported */
- if (!priv->cfg->shadow_ram_support) {
+ if (!priv->cfg->base_params->shadow_ram_support) {
if (iwl_find_otp_image(priv, &validblockaddr)) {
ret = -ENOENT;
goto done;
@@ -604,7 +505,7 @@ err:
if (ret)
iwl_eeprom_free(priv);
/* Reset chip to save power until we load uCode during "up". */
- priv->cfg->ops->lib->apm_ops.stop(priv);
+ iwl_apm_stop(priv);
alloc_err:
return ret;
}
@@ -617,53 +518,6 @@ void iwl_eeprom_free(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_eeprom_free);
-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);
-
- if (eeprom_ver < priv->cfg->eeprom_ver ||
- calib_ver < priv->cfg->eeprom_calib_ver)
- goto err;
-
- IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
- eeprom_ver, calib_ver);
-
- return 0;
-err:
- IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
- eeprom_ver, priv->cfg->eeprom_ver,
- calib_ver, priv->cfg->eeprom_calib_ver);
- return -EINVAL;
-
-}
-EXPORT_SYMBOL(iwl_eeprom_check_version);
-
-const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
-{
- return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
-}
-EXPORT_SYMBOL(iwl_eeprom_query_addr);
-
-u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
-{
- if (!priv->eeprom)
- return 0;
- return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
-}
-EXPORT_SYMBOL(iwl_eeprom_query16);
-
-void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
-{
- const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
- EEPROM_MAC_ADDRESS);
- memcpy(mac, addr, ETH_ALEN);
-}
-EXPORT_SYMBOL(iwl_eeprom_get_mac);
-
static void iwl_init_band_reference(const struct iwl_priv *priv,
int eep_band, int *eeprom_ch_count,
const struct iwl_eeprom_channel **eeprom_ch_info,
@@ -722,7 +576,6 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
#define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \
? # x " " : "")
-
/**
* iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv.
*
@@ -766,205 +619,6 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
return 0;
}
-/**
- * iwl_get_max_txpower_avg - get the highest tx power from all chains.
- * find the highest tx power from all chains for the channel
- */
-static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
- struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
- int element, s8 *max_txpower_in_half_dbm)
-{
- s8 max_txpower_avg = 0; /* (dBm) */
-
- IWL_DEBUG_INFO(priv, "%d - "
- "chain_a: %d dB chain_b: %d dB "
- "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
- element,
- enhanced_txpower[element].chain_a_max >> 1,
- enhanced_txpower[element].chain_b_max >> 1,
- enhanced_txpower[element].chain_c_max >> 1,
- enhanced_txpower[element].mimo2_max >> 1,
- enhanced_txpower[element].mimo3_max >> 1);
- /* Take the highest tx power from any valid chains */
- if ((priv->cfg->valid_tx_ant & ANT_A) &&
- (enhanced_txpower[element].chain_a_max > max_txpower_avg))
- max_txpower_avg = enhanced_txpower[element].chain_a_max;
- if ((priv->cfg->valid_tx_ant & ANT_B) &&
- (enhanced_txpower[element].chain_b_max > max_txpower_avg))
- max_txpower_avg = enhanced_txpower[element].chain_b_max;
- if ((priv->cfg->valid_tx_ant & ANT_C) &&
- (enhanced_txpower[element].chain_c_max > max_txpower_avg))
- max_txpower_avg = enhanced_txpower[element].chain_c_max;
- if (((priv->cfg->valid_tx_ant == ANT_AB) |
- (priv->cfg->valid_tx_ant == ANT_BC) |
- (priv->cfg->valid_tx_ant == ANT_AC)) &&
- (enhanced_txpower[element].mimo2_max > max_txpower_avg))
- max_txpower_avg = enhanced_txpower[element].mimo2_max;
- if ((priv->cfg->valid_tx_ant == ANT_ABC) &&
- (enhanced_txpower[element].mimo3_max > max_txpower_avg))
- max_txpower_avg = enhanced_txpower[element].mimo3_max;
-
- /*
- * max. tx power in EEPROM is in 1/2 dBm format
- * convert from 1/2 dBm to dBm (round-up convert)
- * but we also do not want to loss 1/2 dBm resolution which
- * will impact performance
- */
- *max_txpower_in_half_dbm = max_txpower_avg;
- return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
-}
-
-/**
- * iwl_update_common_txpower: update channel tx power
- * update tx power per band based on EEPROM enhanced tx power info.
- */
-static s8 iwl_update_common_txpower(struct iwl_priv *priv,
- struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
- int section, int element, s8 *max_txpower_in_half_dbm)
-{
- struct iwl_channel_info *ch_info;
- int ch;
- bool is_ht40 = false;
- s8 max_txpower_avg; /* (dBm) */
-
- /* it is common section, contain all type (Legacy, HT and HT40)
- * based on the element in the section to determine
- * is it HT 40 or not
- */
- if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
- is_ht40 = true;
- max_txpower_avg =
- iwl_get_max_txpower_avg(priv, enhanced_txpower,
- element, max_txpower_in_half_dbm);
-
- ch_info = priv->channel_info;
-
- for (ch = 0; ch < priv->channel_count; ch++) {
- /* find matching band and update tx power if needed */
- if ((ch_info->band == enhinfo[section].band) &&
- (ch_info->max_power_avg < max_txpower_avg) &&
- (!is_ht40)) {
- /* Update regulatory-based run-time data */
- ch_info->max_power_avg = ch_info->curr_txpow =
- max_txpower_avg;
- ch_info->scan_power = max_txpower_avg;
- }
- if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
- (ch_info->ht40_max_power_avg < max_txpower_avg)) {
- /* Update regulatory-based run-time data */
- ch_info->ht40_max_power_avg = max_txpower_avg;
- }
- ch_info++;
- }
- return max_txpower_avg;
-}
-
-/**
- * iwl_update_channel_txpower: update channel tx power
- * update channel tx power based on EEPROM enhanced tx power info.
- */
-static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
- struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
- int section, int element, s8 *max_txpower_in_half_dbm)
-{
- struct iwl_channel_info *ch_info;
- int ch;
- u8 channel;
- s8 max_txpower_avg; /* (dBm) */
-
- channel = enhinfo[section].iwl_eeprom_section_channel[element];
- max_txpower_avg =
- iwl_get_max_txpower_avg(priv, enhanced_txpower,
- element, max_txpower_in_half_dbm);
-
- ch_info = priv->channel_info;
- for (ch = 0; ch < priv->channel_count; ch++) {
- /* find matching channel and update tx power if needed */
- if (ch_info->channel == channel) {
- if ((ch_info->max_power_avg < max_txpower_avg) &&
- (!enhinfo[section].is_ht40)) {
- /* Update regulatory-based run-time data */
- ch_info->max_power_avg = max_txpower_avg;
- ch_info->curr_txpow = max_txpower_avg;
- ch_info->scan_power = max_txpower_avg;
- }
- if ((enhinfo[section].is_ht40) &&
- (ch_info->ht40_max_power_avg < max_txpower_avg)) {
- /* Update regulatory-based run-time data */
- ch_info->ht40_max_power_avg = max_txpower_avg;
- }
- break;
- }
- ch_info++;
- }
- return max_txpower_avg;
-}
-
-/**
- * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
- */
-void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
-{
- int eeprom_section_count = 0;
- int section, element;
- struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
- u32 offset;
- s8 max_txpower_avg; /* (dBm) */
- s8 max_txpower_in_half_dbm; /* (half-dBm) */
-
- /* Loop through all the sections
- * adjust bands and channel's max tx power
- * Set the tx_power_user_lmt to the highest power
- * supported by any channels and chains
- */
- for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
- eeprom_section_count = enhinfo[section].count;
- offset = enhinfo[section].offset;
- enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
- iwl_eeprom_query_addr(priv, offset);
-
- /*
- * check for valid entry -
- * different version of EEPROM might contain different set
- * of enhanced tx power table
- * always check for valid entry before process
- * the information
- */
- if (!enhanced_txpower->common || enhanced_txpower->reserved)
- continue;
-
- for (element = 0; element < eeprom_section_count; element++) {
- if (enhinfo[section].is_common)
- max_txpower_avg =
- iwl_update_common_txpower(priv,
- enhanced_txpower, section,
- element,
- &max_txpower_in_half_dbm);
- else
- max_txpower_avg =
- iwl_update_channel_txpower(priv,
- enhanced_txpower, section,
- element,
- &max_txpower_in_half_dbm);
-
- /* Update the tx_power_user_lmt to the highest power
- * supported by any channel */
- if (max_txpower_avg > priv->tx_power_user_lmt)
- priv->tx_power_user_lmt = max_txpower_avg;
-
- /*
- * Update the tx_power_lmt_in_half_dbm to
- * the highest power supported by any channel
- */
- if (max_txpower_in_half_dbm >
- priv->tx_power_lmt_in_half_dbm)
- priv->tx_power_lmt_in_half_dbm =
- max_txpower_in_half_dbm;
- }
- }
-}
-EXPORT_SYMBOL(iwlcore_eeprom_enhanced_txpower);
-
#define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
? # x " " : "")
@@ -1162,4 +816,3 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
return NULL;
}
EXPORT_SYMBOL(iwl_get_channel_info);
-
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index a4772aff51fe..d9b590625ae4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -493,7 +493,6 @@ struct iwl_eeprom_calib_info {
struct iwl_eeprom_ops {
const u32 regulatory_bands[7];
- int (*verify_signature) (struct iwl_priv *priv);
int (*acquire_semaphore) (struct iwl_priv *priv);
void (*release_semaphore) (struct iwl_priv *priv);
u16 (*calib_version) (struct iwl_priv *priv);
@@ -502,18 +501,13 @@ struct iwl_eeprom_ops {
};
-void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
int iwl_eeprom_init(struct iwl_priv *priv);
void iwl_eeprom_free(struct iwl_priv *priv);
int iwl_eeprom_check_version(struct iwl_priv *priv);
const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
-u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
-
int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
-void iwlcore_eeprom_release_semaphore(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);
-void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
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-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 258d059ef41f..c373b53babea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -97,6 +97,17 @@ const char *get_cmd_string(u8 cmd)
IWL_CMD(REPLY_TX_POWER_DBM_CMD);
IWL_CMD(TEMPERATURE_NOTIFICATION);
IWL_CMD(TX_ANT_CONFIGURATION_CMD);
+ IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF);
+ IWL_CMD(REPLY_BT_COEX_PRIO_TABLE);
+ IWL_CMD(REPLY_BT_COEX_PROT_ENV);
+ IWL_CMD(REPLY_WIPAN_PARAMS);
+ IWL_CMD(REPLY_WIPAN_RXON);
+ IWL_CMD(REPLY_WIPAN_RXON_TIMING);
+ IWL_CMD(REPLY_WIPAN_RXON_ASSOC);
+ IWL_CMD(REPLY_WIPAN_QOS_PARAM);
+ IWL_CMD(REPLY_WIPAN_WEPKEY);
+ IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH);
+ IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION);
default:
return "UNKNOWN";
@@ -229,7 +240,7 @@ cancel:
* in later, it will possibly set an invalid
* address (cmd->meta.source).
*/
- priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_idx].flags &=
+ priv->txq[priv->cmd_queue].meta[cmd_idx].flags &=
~CMD_WANT_SKB;
}
fail:
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 621abe3c5afc..1aaef70deaec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -44,11 +44,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf(
return &hw->conf;
}
-static inline int iwl_check_bits(unsigned long field, unsigned long mask)
-{
- return ((field & mask) == mask) ? 1 : 0;
-}
-
static inline unsigned long elapsed_jiffies(unsigned long start,
unsigned long end)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index db5bfcb036ca..86c2b6fed0c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -108,13 +108,13 @@ static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx)
BUG_ON(idx > IWL_MAX_BLINK_TBL);
IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n",
- priv->cfg->led_compensation);
+ priv->cfg->base_params->led_compensation);
led_cmd.on =
iwl_blink_compensation(priv, blink_tbl[idx].on_time,
- priv->cfg->led_compensation);
+ priv->cfg->base_params->led_compensation);
led_cmd.off =
iwl_blink_compensation(priv, blink_tbl[idx].off_time,
- priv->cfg->led_compensation);
+ priv->cfg->base_params->led_compensation);
return priv->cfg->ops->led->cmd(priv, &led_cmd);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index cda6a94d6cc9..49d7788937a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -192,47 +192,6 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1);
}
-/* default Thermal Throttling transaction table
- * Current state | Throttling Down | Throttling Up
- *=============================================================================
- * Condition Nxt State Condition Nxt State Condition Nxt State
- *-----------------------------------------------------------------------------
- * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A
- * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0
- * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1
- * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
- *=============================================================================
- */
-static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {
- {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104},
- {IWL_TI_1, 105, CT_KILL_THRESHOLD - 1},
- {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
-};
-static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {
- {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95},
- {IWL_TI_2, 110, CT_KILL_THRESHOLD - 1},
- {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
-};
-static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {
- {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100},
- {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX},
- {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
-};
-static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {
- {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD},
- {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
- {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
-};
-
-/* Advance Thermal Throttling default restriction table */
-static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {
- {IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true },
- {IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true },
- {IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false },
- {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false }
-};
-
-
static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv,
struct iwl_powertable_cmd *cmd)
{
@@ -308,7 +267,6 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
int iwl_power_update_mode(struct iwl_priv *priv, bool force)
{
int ret = 0;
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
bool update_chains;
struct iwl_powertable_cmd cmd;
@@ -320,14 +278,18 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
dtimper = priv->hw->conf.ps_dtim_period ?: 1;
- if (priv->cfg->broken_powersave)
+ if (priv->cfg->base_params->broken_powersave)
iwl_power_sleep_cam_cmd(priv, &cmd);
- else if (priv->cfg->supports_idle &&
+ else if (priv->cfg->base_params->supports_idle &&
priv->hw->conf.flags & IEEE80211_CONF_IDLE)
iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20);
- else if (tt->state >= IWL_TI_1)
- iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper);
- else if (!enabled)
+ 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)) {
+ /* in thermal throttling low power state */
+ iwl_static_sleep_cmd(priv, &cmd,
+ priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper);
+ } else if (!enabled)
iwl_power_sleep_cam_cmd(priv, &cmd);
else if (priv->power_data.debug_sleep_level_override >= 0)
iwl_static_sleep_cmd(priv, &cmd,
@@ -367,592 +329,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
}
EXPORT_SYMBOL(iwl_power_update_mode);
-bool iwl_ht_enabled(struct iwl_priv *priv)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- struct iwl_tt_restriction *restriction;
-
- if (!priv->thermal_throttle.advanced_tt)
- return true;
- restriction = tt->restriction + tt->state;
- return restriction->is_ht;
-}
-EXPORT_SYMBOL(iwl_ht_enabled);
-
-bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
-{
- s32 temp = priv->temperature; /* degrees CELSIUS except specified */
- bool within_margin = false;
-
- if (priv->cfg->temperature_kelvin)
- temp = KELVIN_TO_CELSIUS(priv->temperature);
-
- if (!priv->thermal_throttle.advanced_tt)
- within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
- CT_KILL_THRESHOLD_LEGACY) ? true : false;
- else
- within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
- CT_KILL_THRESHOLD) ? true : false;
- return within_margin;
-}
-
-enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- struct iwl_tt_restriction *restriction;
-
- if (!priv->thermal_throttle.advanced_tt)
- return IWL_ANT_OK_MULTI;
- restriction = tt->restriction + tt->state;
- return restriction->tx_stream;
-}
-EXPORT_SYMBOL(iwl_tx_ant_restriction);
-
-enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- struct iwl_tt_restriction *restriction;
-
- if (!priv->thermal_throttle.advanced_tt)
- return IWL_ANT_OK_MULTI;
- restriction = tt->restriction + tt->state;
- return restriction->rx_stream;
-}
-
-#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */
-#define CT_KILL_WAITING_DURATION (300) /* 300ms duration */
-
-/*
- * toggle the bit to wake up uCode and check the temperature
- * if the temperature is below CT, uCode will stay awake and send card
- * state notification with CT_KILL bit clear to inform Thermal Throttling
- * Management to change state. Otherwise, uCode will go back to sleep
- * without doing anything, driver should continue the 5 seconds timer
- * to wake up uCode for temperature check until temperature drop below CT
- */
-static void iwl_tt_check_exit_ct_kill(unsigned long data)
-{
- struct iwl_priv *priv = (struct iwl_priv *)data;
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- unsigned long flags;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (tt->state == IWL_TI_CT_KILL) {
- if (priv->thermal_throttle.ct_kill_toggle) {
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
- CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
- priv->thermal_throttle.ct_kill_toggle = false;
- } else {
- iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
- CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
- priv->thermal_throttle.ct_kill_toggle = true;
- }
- iwl_read32(priv, CSR_UCODE_DRV_GP1);
- spin_lock_irqsave(&priv->reg_lock, flags);
- if (!iwl_grab_nic_access(priv))
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, flags);
-
- /* Reschedule the ct_kill timer to occur in
- * CT_KILL_EXIT_DURATION seconds to ensure we get a
- * thermal update */
- IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n");
- mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies +
- CT_KILL_EXIT_DURATION * HZ);
- }
-}
-
-static void iwl_perform_ct_kill_task(struct iwl_priv *priv,
- bool stop)
-{
- if (stop) {
- IWL_DEBUG_POWER(priv, "Stop all queues\n");
- if (priv->mac80211_registered)
- ieee80211_stop_queues(priv->hw);
- IWL_DEBUG_POWER(priv,
- "Schedule 5 seconds CT_KILL Timer\n");
- mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies +
- CT_KILL_EXIT_DURATION * HZ);
- } else {
- IWL_DEBUG_POWER(priv, "Wake all queues\n");
- if (priv->mac80211_registered)
- ieee80211_wake_queues(priv->hw);
- }
-}
-
-static void iwl_tt_ready_for_ct_kill(unsigned long data)
-{
- struct iwl_priv *priv = (struct iwl_priv *)data;
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- /* temperature timer expired, ready to go into CT_KILL state */
- if (tt->state != IWL_TI_CT_KILL) {
- IWL_DEBUG_POWER(priv, "entering CT_KILL state when temperature timer expired\n");
- tt->state = IWL_TI_CT_KILL;
- set_bit(STATUS_CT_KILL, &priv->status);
- iwl_perform_ct_kill_task(priv, true);
- }
-}
-
-static void iwl_prepare_ct_kill_task(struct iwl_priv *priv)
-{
- IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n");
- /* make request to retrieve statistics information */
- iwl_send_statistics_request(priv, CMD_SYNC, false);
- /* Reschedule the ct_kill wait timer */
- mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
- jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION));
-}
-
-#define IWL_MINIMAL_POWER_THRESHOLD (CT_KILL_THRESHOLD_LEGACY)
-#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100)
-#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90)
-
-/*
- * Legacy thermal throttling
- * 1) Avoid NIC destruction due to high temperatures
- * Chip will identify dangerously high temperatures that can
- * harm the device and will power down
- * 2) Avoid the NIC power down due to high temperature
- * Throttle early enough to lower the power consumption before
- * drastic steps are needed
- */
-static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- enum iwl_tt_state old_state;
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if ((tt->tt_previous_temp) &&
- (temp > tt->tt_previous_temp) &&
- ((temp - tt->tt_previous_temp) >
- IWL_TT_INCREASE_MARGIN)) {
- IWL_DEBUG_POWER(priv,
- "Temperature increase %d degree Celsius\n",
- (temp - tt->tt_previous_temp));
- }
-#endif
- old_state = tt->state;
- /* in Celsius */
- if (temp >= IWL_MINIMAL_POWER_THRESHOLD)
- tt->state = IWL_TI_CT_KILL;
- else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2)
- tt->state = IWL_TI_2;
- else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1)
- tt->state = IWL_TI_1;
- else
- tt->state = IWL_TI_0;
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- tt->tt_previous_temp = temp;
-#endif
- /* stop ct_kill_waiting_tm timer */
- del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
- if (tt->state != old_state) {
- switch (tt->state) {
- case IWL_TI_0:
- /*
- * When the system is ready to go back to IWL_TI_0
- * we only have to call iwl_power_update_mode() to
- * do so.
- */
- break;
- case IWL_TI_1:
- tt->tt_power_mode = IWL_POWER_INDEX_3;
- break;
- case IWL_TI_2:
- tt->tt_power_mode = IWL_POWER_INDEX_4;
- break;
- default:
- tt->tt_power_mode = IWL_POWER_INDEX_5;
- break;
- }
- mutex_lock(&priv->mutex);
- if (old_state == IWL_TI_CT_KILL)
- clear_bit(STATUS_CT_KILL, &priv->status);
- if (tt->state != IWL_TI_CT_KILL &&
- iwl_power_update_mode(priv, true)) {
- /* TT state not updated
- * try again during next temperature read
- */
- if (old_state == IWL_TI_CT_KILL)
- set_bit(STATUS_CT_KILL, &priv->status);
- tt->state = old_state;
- IWL_ERR(priv, "Cannot update power mode, "
- "TT state not updated\n");
- } else {
- if (tt->state == IWL_TI_CT_KILL) {
- if (force) {
- set_bit(STATUS_CT_KILL, &priv->status);
- iwl_perform_ct_kill_task(priv, true);
- } else {
- iwl_prepare_ct_kill_task(priv);
- tt->state = old_state;
- }
- } else if (old_state == IWL_TI_CT_KILL &&
- tt->state != IWL_TI_CT_KILL)
- iwl_perform_ct_kill_task(priv, false);
- IWL_DEBUG_POWER(priv, "Temperature state changed %u\n",
- tt->state);
- IWL_DEBUG_POWER(priv, "Power Index change to %u\n",
- tt->tt_power_mode);
- }
- mutex_unlock(&priv->mutex);
- }
-}
-
-/*
- * Advance thermal throttling
- * 1) Avoid NIC destruction due to high temperatures
- * Chip will identify dangerously high temperatures that can
- * harm the device and will power down
- * 2) Avoid the NIC power down due to high temperature
- * Throttle early enough to lower the power consumption before
- * drastic steps are needed
- * Actions include relaxing the power down sleep thresholds and
- * decreasing the number of TX streams
- * 3) Avoid throughput performance impact as much as possible
- *
- *=============================================================================
- * Condition Nxt State Condition Nxt State Condition Nxt State
- *-----------------------------------------------------------------------------
- * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A
- * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0
- * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1
- * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
- *=============================================================================
- */
-static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- int i;
- bool changed = false;
- enum iwl_tt_state old_state;
- struct iwl_tt_trans *transaction;
-
- old_state = tt->state;
- for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) {
- /* based on the current TT state,
- * find the curresponding transaction table
- * each table has (IWL_TI_STATE_MAX - 1) entries
- * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1))
- * will advance to the correct table.
- * then based on the current temperature
- * find the next state need to transaction to
- * go through all the possible (IWL_TI_STATE_MAX - 1) entries
- * in the current table to see if transaction is needed
- */
- transaction = tt->transaction +
- ((old_state * (IWL_TI_STATE_MAX - 1)) + i);
- if (temp >= transaction->tt_low &&
- temp <= transaction->tt_high) {
-#ifdef CONFIG_IWLWIFI_DEBUG
- if ((tt->tt_previous_temp) &&
- (temp > tt->tt_previous_temp) &&
- ((temp - tt->tt_previous_temp) >
- IWL_TT_INCREASE_MARGIN)) {
- IWL_DEBUG_POWER(priv,
- "Temperature increase %d "
- "degree Celsius\n",
- (temp - tt->tt_previous_temp));
- }
- tt->tt_previous_temp = temp;
-#endif
- if (old_state !=
- transaction->next_state) {
- changed = true;
- tt->state =
- transaction->next_state;
- }
- break;
- }
- }
- /* stop ct_kill_waiting_tm timer */
- del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
- if (changed) {
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
-
- if (tt->state >= IWL_TI_1) {
- /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
- tt->tt_power_mode = IWL_POWER_INDEX_5;
- if (!iwl_ht_enabled(priv))
- /* disable HT */
- rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
- RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
- RXON_FLG_HT40_PROT_MSK |
- RXON_FLG_HT_PROT_MSK);
- else {
- /* check HT capability and set
- * according to the system HT capability
- * in case get disabled before */
- iwl_set_rxon_ht(priv, &priv->current_ht_config);
- }
-
- } else {
- /*
- * restore system power setting -- it will be
- * recalculated automatically.
- */
-
- /* check HT capability and set
- * according to the system HT capability
- * in case get disabled before */
- iwl_set_rxon_ht(priv, &priv->current_ht_config);
- }
- mutex_lock(&priv->mutex);
- if (old_state == IWL_TI_CT_KILL)
- clear_bit(STATUS_CT_KILL, &priv->status);
- if (tt->state != IWL_TI_CT_KILL &&
- iwl_power_update_mode(priv, true)) {
- /* TT state not updated
- * try again during next temperature read
- */
- IWL_ERR(priv, "Cannot update power mode, "
- "TT state not updated\n");
- if (old_state == IWL_TI_CT_KILL)
- set_bit(STATUS_CT_KILL, &priv->status);
- tt->state = old_state;
- } else {
- IWL_DEBUG_POWER(priv,
- "Thermal Throttling to new state: %u\n",
- tt->state);
- if (old_state != IWL_TI_CT_KILL &&
- tt->state == IWL_TI_CT_KILL) {
- if (force) {
- IWL_DEBUG_POWER(priv,
- "Enter IWL_TI_CT_KILL\n");
- set_bit(STATUS_CT_KILL, &priv->status);
- iwl_perform_ct_kill_task(priv, true);
- } else {
- iwl_prepare_ct_kill_task(priv);
- tt->state = old_state;
- }
- } else if (old_state == IWL_TI_CT_KILL &&
- tt->state != IWL_TI_CT_KILL) {
- IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n");
- iwl_perform_ct_kill_task(priv, false);
- }
- }
- mutex_unlock(&priv->mutex);
- }
-}
-
-/* Card State Notification indicated reach critical temperature
- * if PSP not enable, no Thermal Throttling function will be performed
- * just set the GP1 bit to acknowledge the event
- * otherwise, go into IWL_TI_CT_KILL state
- * since Card State Notification will not provide any temperature reading
- * for Legacy mode
- * so just pass the CT_KILL temperature to iwl_legacy_tt_handler()
- * for advance mode
- * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state
- */
-static void iwl_bg_ct_enter(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (!iwl_is_ready(priv))
- return;
-
- if (tt->state != IWL_TI_CT_KILL) {
- IWL_ERR(priv, "Device reached critical temperature "
- "- ucode going to sleep!\n");
- if (!priv->thermal_throttle.advanced_tt)
- iwl_legacy_tt_handler(priv,
- IWL_MINIMAL_POWER_THRESHOLD,
- true);
- else
- iwl_advance_tt_handler(priv,
- CT_KILL_THRESHOLD + 1, true);
- }
-}
-
-/* Card State Notification indicated out of critical temperature
- * since Card State Notification will not provide any temperature reading
- * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature
- * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state
- */
-static void iwl_bg_ct_exit(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (!iwl_is_ready(priv))
- return;
-
- /* stop ct_kill_exit_tm timer */
- del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
-
- if (tt->state == IWL_TI_CT_KILL) {
- IWL_ERR(priv,
- "Device temperature below critical"
- "- ucode awake!\n");
- /*
- * exit from CT_KILL state
- * reset the current temperature reading
- */
- priv->temperature = 0;
- if (!priv->thermal_throttle.advanced_tt)
- iwl_legacy_tt_handler(priv,
- IWL_REDUCED_PERFORMANCE_THRESHOLD_2,
- true);
- else
- iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD,
- true);
- }
-}
-
-void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n");
- queue_work(priv->workqueue, &priv->ct_enter);
-}
-EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
-
-void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n");
- queue_work(priv->workqueue, &priv->ct_exit);
-}
-EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
-
-static void iwl_bg_tt_work(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
- s32 temp = priv->temperature; /* degrees CELSIUS except specified */
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (priv->cfg->temperature_kelvin)
- temp = KELVIN_TO_CELSIUS(priv->temperature);
-
- if (!priv->thermal_throttle.advanced_tt)
- iwl_legacy_tt_handler(priv, temp, false);
- else
- iwl_advance_tt_handler(priv, temp, false);
-}
-
-void iwl_tt_handler(struct iwl_priv *priv)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n");
- queue_work(priv->workqueue, &priv->tt_work);
-}
-EXPORT_SYMBOL(iwl_tt_handler);
-
-/* Thermal throttling initialization
- * For advance thermal throttling:
- * Initialize Thermal Index and temperature threshold table
- * Initialize thermal throttling restriction table
- */
-void iwl_tt_initialize(struct iwl_priv *priv)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
- struct iwl_tt_trans *transaction;
-
- IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n");
-
- memset(tt, 0, sizeof(struct iwl_tt_mgmt));
-
- tt->state = IWL_TI_0;
- init_timer(&priv->thermal_throttle.ct_kill_exit_tm);
- priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv;
- priv->thermal_throttle.ct_kill_exit_tm.function =
- iwl_tt_check_exit_ct_kill;
- init_timer(&priv->thermal_throttle.ct_kill_waiting_tm);
- priv->thermal_throttle.ct_kill_waiting_tm.data = (unsigned long)priv;
- priv->thermal_throttle.ct_kill_waiting_tm.function =
- iwl_tt_ready_for_ct_kill;
- /* setup deferred ct kill work */
- INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
- INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
- INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
-
- if (priv->cfg->adv_thermal_throttle) {
- IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
- tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
- IWL_TI_STATE_MAX, GFP_KERNEL);
- tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) *
- IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1),
- GFP_KERNEL);
- if (!tt->restriction || !tt->transaction) {
- IWL_ERR(priv, "Fallback to Legacy Throttling\n");
- priv->thermal_throttle.advanced_tt = false;
- kfree(tt->restriction);
- tt->restriction = NULL;
- kfree(tt->transaction);
- tt->transaction = NULL;
- } else {
- transaction = tt->transaction +
- (IWL_TI_0 * (IWL_TI_STATE_MAX - 1));
- memcpy(transaction, &tt_range_0[0], size);
- transaction = tt->transaction +
- (IWL_TI_1 * (IWL_TI_STATE_MAX - 1));
- memcpy(transaction, &tt_range_1[0], size);
- transaction = tt->transaction +
- (IWL_TI_2 * (IWL_TI_STATE_MAX - 1));
- memcpy(transaction, &tt_range_2[0], size);
- transaction = tt->transaction +
- (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1));
- memcpy(transaction, &tt_range_3[0], size);
- size = sizeof(struct iwl_tt_restriction) *
- IWL_TI_STATE_MAX;
- memcpy(tt->restriction,
- &restriction_range[0], size);
- priv->thermal_throttle.advanced_tt = true;
- }
- } else {
- IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n");
- priv->thermal_throttle.advanced_tt = false;
- }
-}
-EXPORT_SYMBOL(iwl_tt_initialize);
-
-/* cleanup thermal throttling management related memory and timer */
-void iwl_tt_exit(struct iwl_priv *priv)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
-
- /* stop ct_kill_exit_tm timer if activated */
- del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
- /* stop ct_kill_waiting_tm timer if activated */
- del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
- cancel_work_sync(&priv->tt_work);
- cancel_work_sync(&priv->ct_enter);
- cancel_work_sync(&priv->ct_exit);
-
- if (priv->thermal_throttle.advanced_tt) {
- /* free advance thermal throttling memory */
- kfree(tt->restriction);
- tt->restriction = NULL;
- kfree(tt->transaction);
- tt->transaction = NULL;
- }
-}
-EXPORT_SYMBOL(iwl_tt_exit);
-
/* initialize to default */
void iwl_power_initialize(struct iwl_priv *priv)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 5db91c10dcc8..df81565a7cc4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -30,90 +30,6 @@
#include "iwl-commands.h"
-#define IWL_ABSOLUTE_ZERO 0
-#define IWL_ABSOLUTE_MAX 0xFFFFFFFF
-#define IWL_TT_INCREASE_MARGIN 5
-#define IWL_TT_CT_KILL_MARGIN 3
-
-enum iwl_antenna_ok {
- IWL_ANT_OK_NONE,
- IWL_ANT_OK_SINGLE,
- IWL_ANT_OK_MULTI,
-};
-
-/* Thermal Throttling State Machine states */
-enum iwl_tt_state {
- IWL_TI_0, /* normal temperature, system power state */
- IWL_TI_1, /* high temperature detect, low power state */
- IWL_TI_2, /* higher temperature detected, lower power state */
- IWL_TI_CT_KILL, /* critical temperature detected, lowest power state */
- IWL_TI_STATE_MAX
-};
-
-/**
- * struct iwl_tt_restriction - Thermal Throttling restriction table
- * @tx_stream: number of tx stream allowed
- * @is_ht: ht enable/disable
- * @rx_stream: number of rx stream allowed
- *
- * This table is used by advance thermal throttling management
- * based on the current thermal throttling state, and determines
- * the number of tx/rx streams and the status of HT operation.
- */
-struct iwl_tt_restriction {
- enum iwl_antenna_ok tx_stream;
- enum iwl_antenna_ok rx_stream;
- bool is_ht;
-};
-
-/**
- * struct iwl_tt_trans - Thermal Throttling transaction table
- * @next_state: next thermal throttling mode
- * @tt_low: low temperature threshold to change state
- * @tt_high: high temperature threshold to change state
- *
- * This is used by the advanced thermal throttling algorithm
- * to determine the next thermal state to go based on the
- * current temperature.
- */
-struct iwl_tt_trans {
- enum iwl_tt_state next_state;
- u32 tt_low;
- u32 tt_high;
-};
-
-/**
- * struct iwl_tt_mgnt - Thermal Throttling Management structure
- * @advanced_tt: advanced thermal throttle required
- * @state: current Thermal Throttling state
- * @tt_power_mode: Thermal Throttling power mode index
- * being used to set power level when
- * when thermal throttling state != IWL_TI_0
- * the tt_power_mode should set to different
- * power mode based on the current tt state
- * @tt_previous_temperature: last measured temperature
- * @iwl_tt_restriction: ptr to restriction tbl, used by advance
- * thermal throttling to determine how many tx/rx streams
- * should be used in tt state; and can HT be enabled or not
- * @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling
- * state transaction
- * @ct_kill_toggle: used to toggle the CSR bit when checking uCode temperature
- * @ct_kill_exit_tm: timer to exit thermal kill
- */
-struct iwl_tt_mgmt {
- enum iwl_tt_state state;
- bool advanced_tt;
- u8 tt_power_mode;
- bool ct_kill_toggle;
-#ifdef CONFIG_IWLWIFI_DEBUG
- s32 tt_previous_temp;
-#endif
- struct iwl_tt_restriction *restriction;
- struct iwl_tt_trans *transaction;
- struct timer_list ct_kill_exit_tm;
- struct timer_list ct_kill_waiting_tm;
-};
-
enum iwl_power_level {
IWL_POWER_INDEX_1,
IWL_POWER_INDEX_2,
@@ -130,15 +46,6 @@ struct iwl_power_mgr {
};
int iwl_power_update_mode(struct iwl_priv *priv, bool force);
-bool iwl_ht_enabled(struct iwl_priv *priv);
-bool iwl_within_ct_kill_margin(struct iwl_priv *priv);
-enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv);
-enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv);
-void iwl_tt_enter_ct_kill(struct iwl_priv *priv);
-void iwl_tt_exit_ct_kill(struct iwl_priv *priv);
-void iwl_tt_handler(struct iwl_priv *priv);
-void iwl_tt_initialize(struct iwl_priv *priv);
-void iwl_tt_exit(struct iwl_priv *priv);
void iwl_power_initialize(struct iwl_priv *priv);
extern bool no_sleep_autoadjust;
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index b1f101caf19d..5469655646ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -306,7 +306,7 @@
* at a time, until receiving ACK from receiving station, or reaching
* retry limit and giving up.
*
- * The command queue (#4) must use this mode!
+ * The command queue (#4/#9) must use this mode!
* This mode does not require use of the Byte Count table in host DRAM.
*
* Driver controls scheduler operation via 3 means:
@@ -322,7 +322,7 @@
* (1024 bytes for each queue).
*
* After receiving "Alive" response from uCode, driver must initialize
- * the scheduler (especially for queue #4, the command queue, otherwise
+ * the scheduler (especially for queue #4/#9, the command queue, otherwise
* the driver can't issue commands!):
*/
@@ -555,8 +555,9 @@
#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
((IWLAGN_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc)
-#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(x) (((1<<(x)) - 1) &\
- (~(1<<IWL_CMD_QUEUE_NUM)))
+#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv) \
+ (((1<<(priv)->hw_params.max_txq_num) - 1) &\
+ (~(1<<(priv)->cmd_queue)))
#define IWLAGN_SCD_BASE (PRPH_BASE + 0xa02c00)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 79773e353baa..f436270ca39a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -36,7 +36,6 @@
#include "iwl-core.h"
#include "iwl-sta.h"
#include "iwl-io.h"
-#include "iwl-calib.h"
#include "iwl-helpers.h"
/************************** RX-FUNCTIONS ****************************/
/*
@@ -228,7 +227,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- if (iwl_is_associated(priv)) {
+ if (iwl_is_any_associated(priv)) {
if (priv->cfg->ops->lib->check_ack_health) {
if (!priv->cfg->ops->lib->check_ack_health(
priv, pkt)) {
@@ -266,7 +265,12 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
{
u16 fc = le16_to_cpu(hdr->frame_control);
- if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
+ /*
+ * All contexts have the same setting here due to it being
+ * a module parameter, so OK to check any context.
+ */
+ if (priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags &
+ RXON_FILTER_DIS_DECRYPT_MSK)
return 0;
if (!(fc & IEEE80211_FCTL_PROTECTED))
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index a4b3663a262f..67da31295781 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -54,100 +54,133 @@
#define IWL_PASSIVE_DWELL_BASE (100)
#define IWL_CHANNEL_TUNE_TIME 5
+static int iwl_send_scan_abort(struct iwl_priv *priv)
+{
+ int ret;
+ struct iwl_rx_packet *pkt;
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_SCAN_ABORT_CMD,
+ .flags = CMD_WANT_SKB,
+ };
+ /* Exit instantly with error when device is not ready
+ * to receive scan abort command or it does not perform
+ * hardware scan currently */
+ if (!test_bit(STATUS_READY, &priv->status) ||
+ !test_bit(STATUS_GEO_CONFIGURED, &priv->status) ||
+ !test_bit(STATUS_SCAN_HW, &priv->status) ||
+ test_bit(STATUS_FW_ERROR, &priv->status) ||
+ test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return -EIO;
-/**
- * iwl_scan_cancel - Cancel any currently executing HW scan
- *
- * NOTE: priv->mutex is not required before calling this function
- */
-int iwl_scan_cancel(struct iwl_priv *priv)
+ ret = iwl_send_cmd_sync(priv, &cmd);
+ if (ret)
+ return ret;
+
+ pkt = (struct iwl_rx_packet *)cmd.reply_page;
+ if (pkt->u.status != CAN_ABORT_STATUS) {
+ /* The scan abort will return 1 for success or
+ * 2 for "failure". A failure condition can be
+ * due to simply not being in an active scan which
+ * can occur if we send the scan abort before we
+ * the microcode has notified us that a scan is
+ * completed. */
+ IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
+ ret = -EIO;
+ }
+
+ iwl_free_pages(priv, cmd.reply_page);
+ return ret;
+}
+
+static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
{
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCANNING, &priv->status);
- return 0;
+ /* check if scan was requested from mac80211 */
+ if (priv->scan_request) {
+ IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n");
+ ieee80211_scan_completed(priv->hw, aborted);
}
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
- queue_work(priv->workqueue, &priv->abort_scan);
+ priv->is_internal_short_scan = false;
+ priv->scan_vif = NULL;
+ priv->scan_request = NULL;
+}
- } else
- IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n");
+void iwl_force_scan_end(struct iwl_priv *priv)
+{
+ lockdep_assert_held(&priv->mutex);
- return test_bit(STATUS_SCANNING, &priv->status);
+ if (!test_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n");
+ return;
}
+ IWL_DEBUG_SCAN(priv, "Forcing scan end\n");
+ clear_bit(STATUS_SCANNING, &priv->status);
+ clear_bit(STATUS_SCAN_HW, &priv->status);
+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ iwl_complete_scan(priv, true);
+}
+
+static void iwl_do_scan_abort(struct iwl_priv *priv)
+{
+ int ret;
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (!test_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n");
+ return;
+ }
+
+ if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Scan abort in progress\n");
+ return;
+ }
+
+ ret = iwl_send_scan_abort(priv);
+ if (ret) {
+ IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret);
+ iwl_force_scan_end(priv);
+ } else
+ IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n");
+}
+
+/**
+ * iwl_scan_cancel - Cancel any currently executing HW scan
+ */
+int iwl_scan_cancel(struct iwl_priv *priv)
+{
+ IWL_DEBUG_SCAN(priv, "Queuing abort scan\n");
+ queue_work(priv->workqueue, &priv->abort_scan);
return 0;
}
EXPORT_SYMBOL(iwl_scan_cancel);
+
/**
* iwl_scan_cancel_timeout - Cancel any currently executing HW scan
* @ms: amount of time to wait (in milliseconds) for scan to abort
*
- * NOTE: priv->mutex must be held before calling this function
*/
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
{
- unsigned long now = jiffies;
- int ret;
-
- ret = iwl_scan_cancel(priv);
- if (ret && ms) {
- mutex_unlock(&priv->mutex);
- while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
- test_bit(STATUS_SCANNING, &priv->status))
- msleep(1);
- mutex_lock(&priv->mutex);
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
+ unsigned long timeout = jiffies + msecs_to_jiffies(ms);
- return ret;
-}
-EXPORT_SYMBOL(iwl_scan_cancel_timeout);
+ lockdep_assert_held(&priv->mutex);
-static int iwl_send_scan_abort(struct iwl_priv *priv)
-{
- int ret = 0;
- struct iwl_rx_packet *pkt;
- struct iwl_host_cmd cmd = {
- .id = REPLY_SCAN_ABORT_CMD,
- .flags = CMD_WANT_SKB,
- };
+ IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n");
- /* If there isn't a scan actively going on in the hardware
- * then we are in between scan bands and not actually
- * actively scanning, so don't send the abort command */
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return 0;
- }
+ iwl_do_scan_abort(priv);
- ret = iwl_send_cmd_sync(priv, &cmd);
- if (ret) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return ret;
- }
-
- pkt = (struct iwl_rx_packet *)cmd.reply_page;
- if (pkt->u.status != CAN_ABORT_STATUS) {
- /* The scan abort will return 1 for success or
- * 2 for "failure". A failure condition can be
- * due to simply not being in an active scan which
- * can occur if we send the scan abort before we
- * the microcode has notified us that a scan is
- * completed. */
- IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status);
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- clear_bit(STATUS_SCAN_HW, &priv->status);
+ while (time_before_eq(jiffies, timeout)) {
+ if (!test_bit(STATUS_SCAN_HW, &priv->status))
+ break;
+ msleep(20);
}
- iwl_free_pages(priv, cmd.reply_page);
-
- return ret;
+ return test_bit(STATUS_SCAN_HW, &priv->status);
}
+EXPORT_SYMBOL(iwl_scan_cancel_timeout);
/* Service response to REPLY_SCAN_CMD (0x80) */
static void iwl_rx_reply_scan(struct iwl_priv *priv,
@@ -158,7 +191,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
struct iwl_scanreq_notification *notif =
(struct iwl_scanreq_notification *)pkt->u.raw;
- IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status);
+ IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
#endif
}
@@ -206,7 +239,6 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
@@ -214,29 +246,38 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
scan_notif->scanned_channels,
scan_notif->tsf_low,
scan_notif->tsf_high, scan_notif->status);
-#endif
/* The HW is no longer scanning */
clear_bit(STATUS_SCAN_HW, &priv->status);
- IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n",
+ IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n",
(priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
jiffies_to_msecs(elapsed_jiffies
(priv->scan_start, jiffies)));
- /*
- * If a request to abort was given, or the scan did not succeed
- * then we reset the scan state machine and terminate,
- * re-queuing another scan if one has been requested
- */
- if (test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status))
- IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
-
- IWL_DEBUG_INFO(priv, "Setting scan to off\n");
-
- clear_bit(STATUS_SCANNING, &priv->status);
-
queue_work(priv->workqueue, &priv->scan_completed);
+
+ if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
+ priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist &&
+ priv->bt_status != scan_notif->bt_status) {
+ if (scan_notif->bt_status) {
+ /* BT on */
+ if (!priv->bt_ch_announce)
+ priv->bt_traffic_load =
+ IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
+ /*
+ * otherwise, no traffic load information provided
+ * no changes made
+ */
+ } else {
+ /* BT off */
+ priv->bt_traffic_load =
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE;
+ }
+ priv->bt_status = scan_notif->bt_status;
+ queue_work(priv->workqueue, &priv->bt_traffic_change_work);
+ }
}
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
@@ -268,18 +309,28 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
enum ieee80211_band band,
struct ieee80211_vif *vif)
{
+ struct iwl_rxon_context *ctx;
u16 passive = (band == IEEE80211_BAND_2GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
- if (iwl_is_associated(priv)) {
- /* If we're associated, we clamp the maximum passive
- * dwell time to be 98% of the beacon interval (minus
- * 2 * channel tune time) */
- passive = vif ? vif->bss_conf.beacon_int : 0;
- if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
- passive = IWL_PASSIVE_DWELL_BASE;
- passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
+ if (iwl_is_any_associated(priv)) {
+ /*
+ * If we're associated, we clamp the maximum passive
+ * dwell time to be 98% of the smallest beacon interval
+ * (minus 2 * channel tune time)
+ */
+ for_each_context(priv, ctx) {
+ u16 value;
+
+ if (!iwl_is_associated_ctx(ctx))
+ continue;
+ value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0;
+ if ((value > IWL_PASSIVE_DWELL_BASE) || !value)
+ value = IWL_PASSIVE_DWELL_BASE;
+ value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
+ passive = min(value, passive);
+ }
}
return passive;
@@ -296,19 +347,53 @@ void iwl_init_scan_params(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_init_scan_params);
-static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif)
+static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
+ struct ieee80211_vif *vif,
+ bool internal,
+ enum ieee80211_band band)
{
+ int ret;
+
lockdep_assert_held(&priv->mutex);
- IWL_DEBUG_INFO(priv, "Starting scan...\n");
+ if (WARN_ON(!priv->cfg->ops->utils->request_scan))
+ return -EOPNOTSUPP;
+
+ cancel_delayed_work(&priv->scan_check);
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_WARN(priv, "Request scan called when driver not ready.\n");
+ return -EIO;
+ }
+
+ if (test_bit(STATUS_SCAN_HW, &priv->status)) {
+ IWL_DEBUG_SCAN(priv,
+ "Multiple concurrent scan requests in parallel.\n");
+ return -EBUSY;
+ }
+
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n");
+ return -EBUSY;
+ }
+
+ IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
+ internal ? "internal short " : "");
+
set_bit(STATUS_SCANNING, &priv->status);
- priv->is_internal_short_scan = false;
+ priv->is_internal_short_scan = internal;
priv->scan_start = jiffies;
+ priv->scan_band = band;
- if (WARN_ON(!priv->cfg->ops->utils->request_scan))
- return -EOPNOTSUPP;
+ ret = priv->cfg->ops->utils->request_scan(priv, vif);
+ if (ret) {
+ clear_bit(STATUS_SCANNING, &priv->status);
+ priv->is_internal_short_scan = false;
+ return ret;
+ }
- priv->cfg->ops->utils->request_scan(priv, vif);
+ queue_delayed_work(priv->workqueue, &priv->scan_check,
+ IWL_SCAN_CHECK_WATCHDOG);
return 0;
}
@@ -327,12 +412,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
- if (!iwl_is_ready_rf(priv)) {
- ret = -EIO;
- IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n");
- goto out_unlock;
- }
-
if (test_bit(STATUS_SCANNING, &priv->status) &&
!priv->is_internal_short_scan) {
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
@@ -340,14 +419,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
goto out_unlock;
}
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
- ret = -EAGAIN;
- goto out_unlock;
- }
-
/* mac80211 will only ask for one band at a time */
- priv->scan_band = req->channels[0]->band;
priv->scan_request = req;
priv->scan_vif = vif;
@@ -355,10 +427,12 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
* If an internal scan is in progress, just set
* up the scan_request as per above.
*/
- if (priv->is_internal_short_scan)
+ if (priv->is_internal_short_scan) {
+ IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n");
ret = 0;
- else
- ret = iwl_scan_initiate(priv, vif);
+ } else
+ ret = iwl_scan_initiate(priv, vif, false,
+ req->channels[0]->band);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -378,11 +452,13 @@ void iwl_internal_short_hw_scan(struct iwl_priv *priv)
queue_work(priv->workqueue, &priv->start_internal_scan);
}
-void iwl_bg_start_internal_scan(struct work_struct *work)
+static void iwl_bg_start_internal_scan(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, start_internal_scan);
+ IWL_DEBUG_SCAN(priv, "Start internal scan\n");
+
mutex_lock(&priv->mutex);
if (priv->is_internal_short_scan == true) {
@@ -390,56 +466,31 @@ void iwl_bg_start_internal_scan(struct work_struct *work)
goto unlock;
}
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
- goto unlock;
- }
-
if (test_bit(STATUS_SCANNING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
goto unlock;
}
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
- goto unlock;
- }
-
- priv->scan_band = priv->band;
-
- IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
- set_bit(STATUS_SCANNING, &priv->status);
- priv->is_internal_short_scan = true;
-
- if (WARN_ON(!priv->cfg->ops->utils->request_scan))
- goto unlock;
-
- priv->cfg->ops->utils->request_scan(priv, NULL);
+ if (iwl_scan_initiate(priv, NULL, true, priv->band))
+ IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n");
unlock:
mutex_unlock(&priv->mutex);
}
-EXPORT_SYMBOL(iwl_bg_start_internal_scan);
-void iwl_bg_scan_check(struct work_struct *data)
+static void iwl_bg_scan_check(struct work_struct *data)
{
struct iwl_priv *priv =
container_of(data, struct iwl_priv, scan_check.work);
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ IWL_DEBUG_SCAN(priv, "Scan check work\n");
+ /* Since we are here firmware does not finish scan and
+ * most likely is in bad shape, so we don't bother to
+ * send abort command, just force scan complete to mac80211 */
mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCANNING, &priv->status) &&
- !test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n",
- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- iwl_send_scan_abort(priv);
- }
+ iwl_force_scan_end(priv);
mutex_unlock(&priv->mutex);
}
-EXPORT_SYMBOL(iwl_bg_scan_check);
/**
* iwl_fill_probe_req - fill in all required fields and IE for probe request
@@ -489,73 +540,78 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
}
EXPORT_SYMBOL(iwl_fill_probe_req);
-void iwl_bg_abort_scan(struct work_struct *work)
+static void iwl_bg_abort_scan(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
- if (!test_bit(STATUS_READY, &priv->status) ||
- !test_bit(STATUS_GEO_CONFIGURED, &priv->status))
- return;
-
- cancel_delayed_work(&priv->scan_check);
+ IWL_DEBUG_SCAN(priv, "Abort scan work\n");
+ /* We keep scan_check work queued in case when firmware will not
+ * report back scan completed notification */
mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status))
- iwl_send_scan_abort(priv);
+ iwl_scan_cancel_timeout(priv, 200);
mutex_unlock(&priv->mutex);
}
-EXPORT_SYMBOL(iwl_bg_abort_scan);
-void iwl_bg_scan_completed(struct work_struct *work)
+static void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
- bool internal = false;
+ bool aborted;
- IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
+ IWL_DEBUG_SCAN(priv, "Completed %sscan.\n",
+ priv->is_internal_short_scan ? "internal short " : "");
cancel_delayed_work(&priv->scan_check);
mutex_lock(&priv->mutex);
- if (priv->is_internal_short_scan) {
- priv->is_internal_short_scan = false;
- IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
- internal = true;
- } else {
- priv->scan_request = NULL;
- priv->scan_vif = NULL;
+
+ aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ if (aborted)
+ IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");
+
+ if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
+ goto out_settings;
}
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ if (priv->is_internal_short_scan && !aborted) {
+ int err;
+
+ /* Check if mac80211 requested scan during our internal scan */
+ if (priv->scan_request == NULL)
+ goto out_complete;
+
+ /* If so request a new scan */
+ err = iwl_scan_initiate(priv, priv->scan_vif, false,
+ priv->scan_request->channels[0]->band);
+ if (err) {
+ IWL_DEBUG_SCAN(priv,
+ "failed to initiate pending scan: %d\n", err);
+ aborted = true;
+ goto out_complete;
+ }
+
goto out;
+ }
+
+out_complete:
+ iwl_complete_scan(priv, aborted);
- if (internal && priv->scan_request)
- iwl_scan_initiate(priv, priv->scan_vif);
+out_settings:
+ /* Can we still talk to firmware ? */
+ if (!iwl_is_ready_rf(priv))
+ goto out;
/* Since setting the TXPOWER may have been deferred while
* performing the scan, fire one off */
iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
- /*
- * Since setting the RXON may have been deferred while
- * performing the scan, fire one off if needed
- */
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
- iwlcore_commit_rxon(priv);
+ priv->cfg->ops->utils->post_scan(priv);
out:
mutex_unlock(&priv->mutex);
-
- /*
- * Do not hold mutex here since this will cause mac80211 to call
- * into driver again into functions that will attempt to take
- * mutex.
- */
- if (!internal)
- ieee80211_scan_completed(priv->hw, false);
}
-EXPORT_SYMBOL(iwl_bg_scan_completed);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
{
@@ -566,3 +622,16 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
+void iwl_cancel_scan_deferred_work(struct iwl_priv *priv)
+{
+ cancel_work_sync(&priv->start_internal_scan);
+ cancel_work_sync(&priv->abort_scan);
+ cancel_work_sync(&priv->scan_completed);
+
+ if (cancel_delayed_work_sync(&priv->scan_check)) {
+ mutex_lock(&priv->mutex);
+ iwl_force_scan_end(priv);
+ mutex_unlock(&priv->mutex);
+ }
+}
+EXPORT_SYMBOL(iwl_cancel_scan_deferred_work);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 7e0829be5e78..7c7f7dcb1b1e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -172,12 +172,14 @@ int iwl_send_add_sta(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_send_add_sta);
static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
- struct ieee80211_sta_ht_cap *sta_ht_inf)
+ struct ieee80211_sta *sta,
+ struct iwl_rxon_context *ctx)
{
+ struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
__le32 sta_flags;
u8 mimo_ps_mode;
- if (!sta_ht_inf || !sta_ht_inf->ht_supported)
+ if (!sta || !sta_ht_inf->ht_supported)
goto done;
mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
@@ -211,7 +213,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
sta_flags |= cpu_to_le32(
(u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
- if (iwl_is_ht40_tx_allowed(priv, sta_ht_inf))
+ if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
sta_flags |= STA_FLG_HT40_EN_MSK;
else
sta_flags &= ~STA_FLG_HT40_EN_MSK;
@@ -226,9 +228,8 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
*
* should be called with sta_lock held
*/
-static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
- bool is_ap,
- struct ieee80211_sta_ht_cap *ht_info)
+u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
{
struct iwl_station_entry *station;
int i;
@@ -236,9 +237,9 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
u16 rate;
if (is_ap)
- sta_id = IWL_AP_ID;
+ sta_id = ctx->ap_sta_id;
else if (is_broadcast_ether_addr(addr))
- sta_id = priv->hw_params.bcast_sta_id;
+ sta_id = ctx->bcast_sta_id;
else
for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
@@ -289,14 +290,22 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
memcpy(station->sta.sta.addr, addr, ETH_ALEN);
station->sta.mode = 0;
station->sta.sta.sta_id = sta_id;
- station->sta.station_flags = 0;
+ station->sta.station_flags = ctx->station_flags;
+ station->ctxid = ctx->ctxid;
+
+ if (sta) {
+ struct iwl_station_priv_common *sta_priv;
+
+ sta_priv = (void *)sta->drv_priv;
+ sta_priv->ctx = ctx;
+ }
/*
* OK to call unconditionally, since local stations (IBSS BSSID
- * STA and broadcast STA) pass in a NULL ht_info, and mac80211
+ * STA and broadcast STA) pass in a NULL sta, and mac80211
* doesn't allow HT IBSS.
*/
- iwl_set_ht_add_station(priv, sta_id, ht_info);
+ iwl_set_ht_add_station(priv, sta_id, sta, ctx);
/* 3945 only */
rate = (priv->band == IEEE80211_BAND_5GHZ) ?
@@ -307,16 +316,16 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
return sta_id;
}
+EXPORT_SYMBOL_GPL(iwl_prep_station);
#define STA_WAIT_TIMEOUT (HZ/2)
/**
* iwl_add_station_common -
*/
-int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
- bool is_ap,
- struct ieee80211_sta_ht_cap *ht_info,
- u8 *sta_id_r)
+int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, bool is_ap,
+ struct ieee80211_sta *sta, u8 *sta_id_r)
{
unsigned long flags_spin;
int ret = 0;
@@ -325,7 +334,7 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
*sta_id_r = 0;
spin_lock_irqsave(&priv->sta_lock, flags_spin);
- sta_id = iwl_prep_station(priv, addr, is_ap, ht_info);
+ sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
addr);
@@ -372,111 +381,6 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
}
EXPORT_SYMBOL(iwl_add_station_common);
-static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
- u8 sta_id)
-{
- int i, r;
- struct iwl_link_quality_cmd *link_cmd;
- u32 rate_flags;
-
- link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
- if (!link_cmd) {
- IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
- return NULL;
- }
- /* Set up the rate scaling to start at selected rate, fall back
- * all the way down to 1M in IEEE order, and then spin on 1M */
- if (priv->band == IEEE80211_BAND_5GHZ)
- r = IWL_RATE_6M_INDEX;
- else
- r = IWL_RATE_1M_INDEX;
-
- for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
- rate_flags = 0;
- if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
- rate_flags |= RATE_MCS_CCK_MSK;
-
- rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
- RATE_MCS_ANT_POS;
-
- link_cmd->rs_table[i].rate_n_flags =
- iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
- r = iwl_get_prev_ieee_rate(r);
- }
-
- link_cmd->general_params.single_stream_ant_msk =
- first_antenna(priv->hw_params.valid_tx_ant);
-
- link_cmd->general_params.dual_stream_ant_msk =
- priv->hw_params.valid_tx_ant &
- ~first_antenna(priv->hw_params.valid_tx_ant);
- if (!link_cmd->general_params.dual_stream_ant_msk) {
- link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
- } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
- link_cmd->general_params.dual_stream_ant_msk =
- priv->hw_params.valid_tx_ant;
- }
-
- link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
- link_cmd->agg_params.agg_time_limit =
- cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
-
- link_cmd->sta_id = sta_id;
-
- return link_cmd;
-}
-
-/*
- * iwl_add_bssid_station - Add the special IBSS BSSID station
- *
- * Function sleeps.
- */
-int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
- u8 *sta_id_r)
-{
- int ret;
- u8 sta_id;
- struct iwl_link_quality_cmd *link_cmd;
- unsigned long flags;
-
- if (sta_id_r)
- *sta_id_r = IWL_INVALID_STATION;
-
- ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id);
- if (ret) {
- IWL_ERR(priv, "Unable to add station %pM\n", addr);
- return ret;
- }
-
- if (sta_id_r)
- *sta_id_r = sta_id;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].used |= IWL_STA_LOCAL;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- if (init_rs) {
- /* Set up default rate scaling table in device's station table */
- link_cmd = iwl_sta_alloc_lq(priv, sta_id);
- if (!link_cmd) {
- IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
- addr);
- return -ENOMEM;
- }
-
- ret = iwl_send_lq_cmd(priv, link_cmd, CMD_SYNC, true);
- if (ret)
- IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].lq = link_cmd;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- }
-
- return 0;
-}
-EXPORT_SYMBOL(iwl_add_bssid_station);
-
/**
* iwl_sta_ucode_deactivate - deactivate ucode status for a station
*
@@ -616,7 +520,8 @@ EXPORT_SYMBOL_GPL(iwl_remove_station);
* other than explicit station management would cause this in
* the ucode, e.g. unassociated RXON.
*/
-void iwl_clear_ucode_stations(struct iwl_priv *priv)
+void iwl_clear_ucode_stations(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
int i;
unsigned long flags_spin;
@@ -626,6 +531,9 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv)
spin_lock_irqsave(&priv->sta_lock, flags_spin);
for (i = 0; i < priv->hw_params.max_stations; i++) {
+ if (ctx && ctx->ctxid != priv->stations[i].ctxid)
+ continue;
+
if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i);
priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
@@ -647,7 +555,7 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations);
*
* Function sleeps.
*/
-void iwl_restore_stations(struct iwl_priv *priv)
+void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
struct iwl_addsta_cmd sta_cmd;
struct iwl_link_quality_cmd lq;
@@ -665,6 +573,8 @@ void iwl_restore_stations(struct iwl_priv *priv)
IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
spin_lock_irqsave(&priv->sta_lock, flags_spin);
for (i = 0; i < priv->hw_params.max_stations; i++) {
+ if (ctx->ctxid != priv->stations[i].ctxid)
+ continue;
if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
!(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
@@ -700,7 +610,7 @@ void iwl_restore_stations(struct iwl_priv *priv)
* current LQ command
*/
if (send_lq)
- iwl_send_lq_cmd(priv, &lq, CMD_SYNC, true);
+ iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
spin_lock_irqsave(&priv->sta_lock, flags_spin);
priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
}
@@ -718,7 +628,7 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;
- for (i = 0; i < STA_KEY_MAX_NUM; i++)
+ for (i = 0; i < priv->sta_key_max_num; i++)
if (!test_and_set_bit(i, &priv->ucode_key_table))
return i;
@@ -726,393 +636,25 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_get_free_ucode_key_index);
-static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
-{
- int i, not_empty = 0;
- u8 buff[sizeof(struct iwl_wep_cmd) +
- sizeof(struct iwl_wep_key) * WEP_KEYS_MAX];
- struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
- size_t cmd_size = sizeof(struct iwl_wep_cmd);
- struct iwl_host_cmd cmd = {
- .id = REPLY_WEPKEY,
- .data = wep_cmd,
- .flags = CMD_SYNC,
- };
-
- might_sleep();
-
- memset(wep_cmd, 0, cmd_size +
- (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));
-
- for (i = 0; i < WEP_KEYS_MAX ; i++) {
- wep_cmd->key[i].key_index = i;
- if (priv->wep_keys[i].key_size) {
- wep_cmd->key[i].key_offset = i;
- not_empty = 1;
- } else {
- wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
- }
-
- wep_cmd->key[i].key_size = priv->wep_keys[i].key_size;
- memcpy(&wep_cmd->key[i].key[3], priv->wep_keys[i].key,
- priv->wep_keys[i].key_size);
- }
-
- wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
- wep_cmd->num_keys = WEP_KEYS_MAX;
-
- cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;
-
- cmd.len = cmd_size;
-
- if (not_empty || send_if_empty)
- return iwl_send_cmd(priv, &cmd);
- else
- return 0;
-}
-
-int iwl_restore_default_wep_keys(struct iwl_priv *priv)
-{
- lockdep_assert_held(&priv->mutex);
-
- return iwl_send_static_wepkey_cmd(priv, 0);
-}
-EXPORT_SYMBOL(iwl_restore_default_wep_keys);
-
-int iwl_remove_default_wep_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf)
-{
- int ret;
-
- lockdep_assert_held(&priv->mutex);
-
- IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
- keyconf->keyidx);
-
- memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
- /* but keys in device are clear anyway so return success */
- return 0;
- }
- ret = iwl_send_static_wepkey_cmd(priv, 1);
- IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
- keyconf->keyidx, ret);
-
- return ret;
-}
-EXPORT_SYMBOL(iwl_remove_default_wep_key);
-
-int iwl_set_default_wep_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf)
+void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
{
- int ret;
-
- lockdep_assert_held(&priv->mutex);
-
- if (keyconf->keylen != WEP_KEY_LEN_128 &&
- keyconf->keylen != WEP_KEY_LEN_64) {
- IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
- return -EINVAL;
- }
-
- keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
- keyconf->hw_key_idx = HW_KEY_DEFAULT;
- priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP;
-
- priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
- memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key,
- keyconf->keylen);
-
- ret = iwl_send_static_wepkey_cmd(priv, 0);
- IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
- keyconf->keylen, keyconf->keyidx, ret);
-
- return ret;
-}
-EXPORT_SYMBOL(iwl_set_default_wep_key);
-
-static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- u8 sta_id)
-{
- unsigned long flags;
- __le16 key_flags = 0;
- struct iwl_addsta_cmd sta_cmd;
-
- lockdep_assert_held(&priv->mutex);
-
- keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
-
- key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
- key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
- key_flags &= ~STA_KEY_FLG_INVALID;
-
- if (keyconf->keylen == WEP_KEY_LEN_128)
- key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
-
- if (sta_id == priv->hw_params.bcast_sta_id)
- key_flags |= STA_KEY_MULTICAST_MSK;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
- priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
- priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
-
- memcpy(priv->stations[sta_id].keyinfo.key,
- keyconf->key, keyconf->keylen);
-
- memcpy(&priv->stations[sta_id].sta.key.key[3],
- keyconf->key, keyconf->keylen);
-
- if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
- == STA_KEY_FLG_NO_ENC)
- priv->stations[sta_id].sta.key.key_offset =
- iwl_get_free_ucode_key_index(priv);
- /* else, we are overriding an existing key => no need to allocated room
- * in uCode. */
-
- WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for a new key");
-
- priv->stations[sta_id].sta.key.key_flags = key_flags;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
- memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-
-static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- u8 sta_id)
-{
- unsigned long flags;
- __le16 key_flags = 0;
- struct iwl_addsta_cmd sta_cmd;
-
- lockdep_assert_held(&priv->mutex);
-
- key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
- key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
- key_flags &= ~STA_KEY_FLG_INVALID;
-
- if (sta_id == priv->hw_params.bcast_sta_id)
- key_flags |= STA_KEY_MULTICAST_MSK;
-
- keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
- priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
-
- memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
- keyconf->keylen);
-
- memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
- keyconf->keylen);
-
- if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
- == STA_KEY_FLG_NO_ENC)
- priv->stations[sta_id].sta.key.key_offset =
- iwl_get_free_ucode_key_index(priv);
- /* else, we are overriding an existing key => no need to allocated room
- * in uCode. */
-
- WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for a new key");
-
- priv->stations[sta_id].sta.key.key_flags = key_flags;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
- memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-
-static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- u8 sta_id)
-{
- unsigned long flags;
- int ret = 0;
- __le16 key_flags = 0;
-
- key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
- key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
- key_flags &= ~STA_KEY_FLG_INVALID;
-
- if (sta_id == priv->hw_params.bcast_sta_id)
- key_flags |= STA_KEY_MULTICAST_MSK;
-
- keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
- priv->stations[sta_id].keyinfo.keylen = 16;
-
- if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
- == STA_KEY_FLG_NO_ENC)
- priv->stations[sta_id].sta.key.key_offset =
- iwl_get_free_ucode_key_index(priv);
- /* else, we are overriding an existing key => no need to allocated room
- * in uCode. */
-
- WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for a new key");
-
- priv->stations[sta_id].sta.key.key_flags = key_flags;
-
-
- /* This copy is acutally not needed: we get the key with each TX */
- memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
-
- memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
-
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- return ret;
-}
-
-void iwl_update_tkip_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
-{
- u8 sta_id;
unsigned long flags;
int i;
- if (iwl_scan_cancel(priv)) {
- /* cancel scan failed, just live w/ bad key and rely
- briefly on SW decryption */
- return;
- }
-
- sta_id = iwl_sta_id_or_broadcast(priv, sta);
- if (sta_id == IWL_INVALID_STATION)
- return;
-
spin_lock_irqsave(&priv->sta_lock, flags);
+ for (i = 0; i < priv->hw_params.max_stations; i++) {
+ if (!(priv->stations[i].used & IWL_STA_BCAST))
+ continue;
- priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
-
- for (i = 0; i < 5; i++)
- priv->stations[sta_id].sta.key.tkip_rx_ttak[i] =
- cpu_to_le16(phase1key[i]);
-
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
- iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-}
-EXPORT_SYMBOL(iwl_update_tkip_key);
-
-int iwl_remove_dynamic_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- u8 sta_id)
-{
- unsigned long flags;
- u16 key_flags;
- u8 keyidx;
- struct iwl_addsta_cmd sta_cmd;
-
- lockdep_assert_held(&priv->mutex);
-
- priv->key_mapping_key--;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
- keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
-
- IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
- keyconf->keyidx, sta_id);
-
- if (keyconf->keyidx != keyidx) {
- /* We need to remove a key with index different that the one
- * in the uCode. This means that the key we need to remove has
- * been replaced by another one with different index.
- * Don't do anything and return ok
- */
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return 0;
- }
-
- if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
- IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
- keyconf->keyidx, key_flags);
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return 0;
- }
-
- if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
- &priv->ucode_key_table))
- IWL_ERR(priv, "index %d not used in uCode key table.\n",
- priv->stations[sta_id].sta.key.key_offset);
- memset(&priv->stations[sta_id].keyinfo, 0,
- sizeof(struct iwl_hw_key));
- memset(&priv->stations[sta_id].sta.key, 0,
- sizeof(struct iwl4965_keyinfo));
- priv->stations[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;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return 0;
+ priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
+ priv->num_stations--;
+ BUG_ON(priv->num_stations < 0);
+ kfree(priv->stations[i].lq);
+ priv->stations[i].lq = NULL;
}
- memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_remove_dynamic_key);
-
-int iwl_set_dynamic_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf, u8 sta_id)
-{
- int ret;
-
- lockdep_assert_held(&priv->mutex);
-
- priv->key_mapping_key++;
- keyconf->hw_key_idx = HW_KEY_DYNAMIC;
-
- switch (keyconf->alg) {
- case ALG_CCMP:
- ret = iwl_set_ccmp_dynamic_key_info(priv, keyconf, sta_id);
- break;
- case ALG_TKIP:
- ret = iwl_set_tkip_dynamic_key_info(priv, keyconf, sta_id);
- break;
- case ALG_WEP:
- ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id);
- break;
- default:
- IWL_ERR(priv,
- "Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
- ret = -EINVAL;
- }
-
- IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
- keyconf->alg, keyconf->keylen, keyconf->keyidx,
- sta_id, ret);
-
- return ret;
}
-EXPORT_SYMBOL(iwl_set_dynamic_key);
+EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations);
#ifdef CONFIG_IWLWIFI_DEBUG
static void iwl_dump_lq_cmd(struct iwl_priv *priv,
@@ -1147,16 +689,16 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
* RXON flags are updated and when LQ command is updated.
*/
static bool is_lq_table_valid(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
struct iwl_link_quality_cmd *lq)
{
int i;
- struct iwl_ht_config *ht_conf = &priv->current_ht_config;
- if (ht_conf->is_ht)
+ if (ctx->ht.enabled)
return true;
IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
- priv->active_rxon.channel);
+ ctx->active.channel);
for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
IWL_DEBUG_INFO(priv,
@@ -1178,7 +720,7 @@ static bool is_lq_table_valid(struct iwl_priv *priv,
* this case to clear the state indicating that station creation is in
* progress.
*/
-int iwl_send_lq_cmd(struct iwl_priv *priv,
+int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_link_quality_cmd *lq, u8 flags, bool init)
{
int ret = 0;
@@ -1197,7 +739,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
iwl_dump_lq_cmd(priv, lq);
BUG_ON(init && (cmd.flags & CMD_ASYNC));
- if (is_lq_table_valid(priv, lq))
+ if (is_lq_table_valid(priv, ctx, lq))
ret = iwl_send_cmd(priv, &cmd);
else
ret = -EINVAL;
@@ -1216,207 +758,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_send_lq_cmd);
-/**
- * iwl_alloc_bcast_station - add broadcast station into driver's station table.
- *
- * This adds the broadcast station into the driver's station table
- * and marks it driver active, so that it will be restored to the
- * device at the next best time.
- */
-int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq)
-{
- struct iwl_link_quality_cmd *link_cmd;
- unsigned long flags;
- u8 sta_id;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- sta_id = iwl_prep_station(priv, iwl_bcast_addr, false, NULL);
- if (sta_id == IWL_INVALID_STATION) {
- IWL_ERR(priv, "Unable to prepare broadcast station\n");
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- return -EINVAL;
- }
-
- priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
- priv->stations[sta_id].used |= IWL_STA_BCAST;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- if (init_lq) {
- link_cmd = iwl_sta_alloc_lq(priv, sta_id);
- if (!link_cmd) {
- IWL_ERR(priv,
- "Unable to initialize rate scaling for bcast station.\n");
- return -ENOMEM;
- }
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].lq = link_cmd;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station);
-
-/**
- * iwl_update_bcast_station - update broadcast station's LQ command
- *
- * Only used by iwlagn. Placed here to have all bcast station management
- * code together.
- */
-int iwl_update_bcast_station(struct iwl_priv *priv)
-{
- unsigned long flags;
- struct iwl_link_quality_cmd *link_cmd;
- u8 sta_id = priv->hw_params.bcast_sta_id;
-
- link_cmd = iwl_sta_alloc_lq(priv, sta_id);
- if (!link_cmd) {
- IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n");
- return -ENOMEM;
- }
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- if (priv->stations[sta_id].lq)
- kfree(priv->stations[sta_id].lq);
- else
- IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
- priv->stations[sta_id].lq = link_cmd;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(iwl_update_bcast_station);
-
-void iwl_dealloc_bcast_station(struct iwl_priv *priv)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- for (i = 0; i < priv->hw_params.max_stations; i++) {
- if (!(priv->stations[i].used & IWL_STA_BCAST))
- continue;
-
- priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
- priv->num_stations--;
- BUG_ON(priv->num_stations < 0);
- kfree(priv->stations[i].lq);
- priv->stations[i].lq = NULL;
- }
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-}
-EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station);
-
-/**
- * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
- */
-int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
-{
- unsigned long flags;
- struct iwl_addsta_cmd sta_cmd;
-
- lockdep_assert_held(&priv->mutex);
-
- /* Remove "disable" flag, to enable Tx for this TID */
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
- priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
-
-int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
- int tid, u16 ssn)
-{
- unsigned long flags;
- int sta_id;
- struct iwl_addsta_cmd sta_cmd;
-
- lockdep_assert_held(&priv->mutex);
-
- sta_id = iwl_sta_id(sta);
- if (sta_id == IWL_INVALID_STATION)
- return -ENXIO;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].sta.station_flags_msk = 0;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
- priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
- priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_sta_rx_agg_start);
-
-int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
- int tid)
-{
- unsigned long flags;
- int sta_id;
- struct iwl_addsta_cmd sta_cmd;
-
- lockdep_assert_held(&priv->mutex);
-
- sta_id = iwl_sta_id(sta);
- if (sta_id == IWL_INVALID_STATION) {
- IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
- return -ENXIO;
- }
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].sta.station_flags_msk = 0;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
- priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
-
-void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
- priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
- priv->stations[sta_id].sta.sta.modify_mask = 0;
- priv->stations[sta_id].sta.sleep_tx_count = 0;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-}
-EXPORT_SYMBOL(iwl_sta_modify_ps_wake);
-
-void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
- priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
- priv->stations[sta_id].sta.sta.modify_mask =
- STA_MODIFY_SLEEP_TX_COUNT_MSK;
- priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-}
-EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
-
int iwl_mac_sta_remove(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index d38a350ba0bd..06475872eee4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -43,44 +43,26 @@
#define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */
-int iwl_remove_default_wep_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key);
-int iwl_set_default_wep_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key);
-int iwl_restore_default_wep_keys(struct iwl_priv *priv);
-int iwl_set_dynamic_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key, u8 sta_id);
-int iwl_remove_dynamic_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key, u8 sta_id);
-void iwl_update_tkip_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
-
-void iwl_restore_stations(struct iwl_priv *priv);
-void iwl_clear_ucode_stations(struct iwl_priv *priv);
-int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq);
-void iwl_dealloc_bcast_station(struct iwl_priv *priv);
-int iwl_update_bcast_station(struct iwl_priv *priv);
+void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+void iwl_clear_ucode_stations(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
+void iwl_dealloc_bcast_stations(struct iwl_priv *priv);
int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags);
-int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
- u8 *sta_id_r);
-int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
- bool is_ap,
- struct ieee80211_sta_ht_cap *ht_info,
- u8 *sta_id_r);
+int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, bool is_ap,
+ struct ieee80211_sta *sta, u8 *sta_id_r);
int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
const u8 *addr);
int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
-int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
-int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
- int tid, u16 ssn);
-int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
- int tid);
-void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
-void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
+
+u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
+
+int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ struct iwl_link_quality_cmd *lq, u8 flags, bool init);
/**
* iwl_clear_driver_stations - clear knowledge of all stations from driver
@@ -94,20 +76,25 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
{
unsigned long flags;
+ struct iwl_rxon_context *ctx;
spin_lock_irqsave(&priv->sta_lock, flags);
memset(priv->stations, 0, sizeof(priv->stations));
priv->num_stations = 0;
- /*
- * Remove all key information that is not stored as part of station
- * information since mac80211 may not have had a
- * chance to remove all the keys. When device is reconfigured by
- * mac80211 after an error all keys will be reconfigured.
- */
priv->ucode_key_table = 0;
- priv->key_mapping_key = 0;
- memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
+
+ for_each_context(priv, ctx) {
+ /*
+ * Remove all key information that is not stored as part
+ * of station information since mac80211 may not have had
+ * a chance to remove all the keys. When device is
+ * reconfigured by mac80211 after an error all keys will
+ * be reconfigured.
+ */
+ memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
+ ctx->key_mapping_keys = 0;
+ }
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
@@ -123,6 +110,7 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
/**
* iwl_sta_id_or_broadcast - return sta_id or broadcast sta
* @priv: iwl priv
+ * @context: the current context
* @sta: mac80211 station
*
* In certain circumstances mac80211 passes a station pointer
@@ -131,12 +119,13 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
* inline wraps that pattern.
*/
static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
+ struct iwl_rxon_context *context,
struct ieee80211_sta *sta)
{
int sta_id;
if (!sta)
- return priv->hw_params.bcast_sta_id;
+ return context->bcast_sta_id;
sta_id = iwl_sta_id(sta);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index a81989c06983..7261ee49f282 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -134,7 +134,7 @@ EXPORT_SYMBOL(iwl_tx_queue_free);
*/
void iwl_cmd_queue_free(struct iwl_priv *priv)
{
- struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
+ struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
struct iwl_queue *q = &txq->q;
struct device *dev = &priv->pci_dev->dev;
int i;
@@ -271,7 +271,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
/* Driver private data, only for Tx (not command) queues,
* not shared with device. */
- if (id != IWL_CMD_QUEUE_NUM) {
+ if (id != priv->cmd_queue) {
txq->txb = kzalloc(sizeof(txq->txb[0]) *
TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
if (!txq->txb) {
@@ -314,13 +314,13 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
/*
* Alloc buffer array for commands (Tx or other types of commands).
- * For the command queue (#4), allocate command space + one big
+ * For the command queue (#4/#9), allocate command space + one big
* command for scan, since scan command is very huge; the system will
* not have two scans at the same time, so only one is needed.
* For normal Tx queues (all other queues), no super-size command
* space is needed.
*/
- if (txq_id == IWL_CMD_QUEUE_NUM)
+ if (txq_id == priv->cmd_queue)
actual_slots++;
txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots,
@@ -355,7 +355,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
* need an swq_id so don't set one to catch errors, all others can
* be set up to the identity mapping.
*/
- if (txq_id != IWL_CMD_QUEUE_NUM)
+ if (txq_id != priv->cmd_queue)
txq->swq_id = txq_id;
/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
@@ -385,7 +385,7 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
{
int actual_slots = slots_num;
- if (txq_id == IWL_CMD_QUEUE_NUM)
+ if (txq_id == priv->cmd_queue)
actual_slots++;
memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
@@ -413,7 +413,7 @@ EXPORT_SYMBOL(iwl_tx_queue_reset);
*/
int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
{
- struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
+ struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
struct iwl_queue *q = &txq->q;
struct iwl_device_cmd *out_cmd;
struct iwl_cmd_meta *out_meta;
@@ -422,6 +422,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
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));
@@ -443,9 +444,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
IWL_ERR(priv, "No space in command queue\n");
- if (iwl_within_ct_kill_margin(priv))
- iwl_tt_enter_ct_kill(priv);
- else {
+ if (priv->cfg->ops->lib->tt_ops.ct_kill_check) {
+ is_ct_kill =
+ priv->cfg->ops->lib->tt_ops.ct_kill_check(priv);
+ }
+ if (!is_ct_kill) {
IWL_ERR(priv, "Restarting adapter due to queue full\n");
queue_work(priv->workqueue, &priv->restart);
}
@@ -480,7 +483,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
* information */
out_cmd->hdr.flags = 0;
- out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
+ out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) |
INDEX_TO_SEQ(q->write_ptr));
if (cmd->flags & CMD_SIZE_HUGE)
out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
@@ -497,15 +500,15 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
get_cmd_string(out_cmd->hdr.cmd),
out_cmd->hdr.cmd,
le16_to_cpu(out_cmd->hdr.sequence), fix_size,
- q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
- break;
+ q->write_ptr, idx, priv->cmd_queue);
+ break;
default:
IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, "
"%d bytes at %d[%d]:%d\n",
get_cmd_string(out_cmd->hdr.cmd),
out_cmd->hdr.cmd,
le16_to_cpu(out_cmd->hdr.sequence), fix_size,
- q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
+ q->write_ptr, idx, priv->cmd_queue);
}
#endif
txq->need_update = 1;
@@ -584,16 +587,16 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
struct iwl_device_cmd *cmd;
struct iwl_cmd_meta *meta;
- struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
+ struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
/* 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
* in the queue management code. */
- if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
- "wrong command queue %d, sequence 0x%X readp=%d writep=%d\n",
- txq_id, sequence,
- priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr,
- priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) {
+ if (WARN(txq_id != priv->cmd_queue,
+ "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n",
+ txq_id, priv->cmd_queue, sequence,
+ priv->txq[priv->cmd_queue].q.read_ptr,
+ priv->txq[priv->cmd_queue].q.write_ptr)) {
iwl_print_hex_error(priv, pkt, 32);
return;
}
@@ -633,41 +636,3 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
meta->flags = 0;
}
EXPORT_SYMBOL(iwl_tx_cmd_complete);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
-#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
-
-const char *iwl_get_tx_fail_reason(u32 status)
-{
- switch (status & TX_STATUS_MSK) {
- case TX_STATUS_SUCCESS:
- return "SUCCESS";
- TX_STATUS_POSTPONE(DELAY);
- TX_STATUS_POSTPONE(FEW_BYTES);
- TX_STATUS_POSTPONE(BT_PRIO);
- TX_STATUS_POSTPONE(QUIET_PERIOD);
- TX_STATUS_POSTPONE(CALC_TTAK);
- TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
- TX_STATUS_FAIL(SHORT_LIMIT);
- TX_STATUS_FAIL(LONG_LIMIT);
- TX_STATUS_FAIL(FIFO_UNDERRUN);
- TX_STATUS_FAIL(DRAIN_FLOW);
- TX_STATUS_FAIL(RFKILL_FLUSH);
- TX_STATUS_FAIL(LIFE_EXPIRE);
- TX_STATUS_FAIL(DEST_PS);
- TX_STATUS_FAIL(HOST_ABORTED);
- TX_STATUS_FAIL(BT_RETRY);
- TX_STATUS_FAIL(STA_INVALID);
- TX_STATUS_FAIL(FRAG_DROPPED);
- TX_STATUS_FAIL(TID_DISABLE);
- TX_STATUS_FAIL(FIFO_FLUSHED);
- TX_STATUS_FAIL(INSUFFICIENT_CF_POLL);
- TX_STATUS_FAIL(FW_DROP);
- TX_STATUS_FAIL(STA_COLOR_MISMATCH_DROP);
- }
-
- return "UNKNOWN";
-}
-EXPORT_SYMBOL(iwl_get_tx_fail_reason);
-#endif /* CONFIG_IWLWIFI_DEBUG */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d31661c1ce77..8f8c4b73f8b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/pci-aspm.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -143,7 +144,7 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
- if (sta_id == priv->hw_params.bcast_sta_id)
+ if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id)
key_flags |= STA_KEY_MULTICAST_MSK;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -151,7 +152,7 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
key_flags &= ~STA_KEY_FLG_INVALID;
spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
+ priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
keyconf->keylen);
@@ -222,23 +223,25 @@ static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
keyconf->hw_key_idx = HW_KEY_DYNAMIC;
- switch (keyconf->alg) {
- case ALG_CCMP:
+ switch (keyconf->cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id);
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id);
break;
- case ALG_WEP:
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id);
break;
default:
- IWL_ERR(priv, "Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+ IWL_ERR(priv, "Unknown alg: %s alg=%x\n", __func__,
+ keyconf->cipher);
ret = -EINVAL;
}
- IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
- keyconf->alg, keyconf->keylen, keyconf->keyidx,
+ IWL_DEBUG_WEP(priv, "Set dynamic key: alg=%x len=%d idx=%d sta=%d ret=%d\n",
+ keyconf->cipher, keyconf->keylen, keyconf->keyidx,
sta_id, ret);
return ret;
@@ -254,10 +257,11 @@ static int iwl3945_remove_static_key(struct iwl_priv *priv)
static int iwl3945_set_static_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key)
{
- if (key->alg == ALG_WEP)
+ if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ key->cipher == WLAN_CIPHER_SUITE_WEP104)
return -EOPNOTSUPP;
- IWL_ERR(priv, "Static key invalid: alg %d\n", key->alg);
+ IWL_ERR(priv, "Static key invalid: cipher %x\n", key->cipher);
return -EINVAL;
}
@@ -313,15 +317,15 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
int left)
{
- if (!iwl_is_associated(priv) || !priv->ibss_beacon)
+ if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb)
return 0;
- if (priv->ibss_beacon->len > left)
+ if (priv->beacon_skb->len > left)
return 0;
- memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len);
+ memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
- return priv->ibss_beacon->len;
+ return priv->beacon_skb->len;
}
static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
@@ -339,7 +343,8 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
return -ENOMEM;
}
- rate = iwl_rate_get_lowest_plcp(priv);
+ rate = iwl_rate_get_lowest_plcp(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
@@ -369,23 +374,25 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
- switch (keyinfo->alg) {
- case ALG_CCMP:
+ tx_cmd->sec_ctl = 0;
+
+ switch (keyinfo->cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen);
IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
break;
- case ALG_WEP:
- tx_cmd->sec_ctl = TX_CMD_SEC_WEP |
+ case WLAN_CIPHER_SUITE_WEP104:
+ tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
+ /* fall through */
+ case WLAN_CIPHER_SUITE_WEP40:
+ tx_cmd->sec_ctl |= TX_CMD_SEC_WEP |
(info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
- if (keyinfo->keylen == 13)
- tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
-
memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen);
IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
@@ -393,7 +400,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
break;
default:
- IWL_ERR(priv, "Unknown encode alg %d\n", keyinfo->alg);
+ IWL_ERR(priv, "Unknown encode cipher %x\n", keyinfo->cipher);
break;
}
}
@@ -506,7 +513,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find index into station table for destination station */
- sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
+ sta_id = iwl_sta_id_or_broadcast(
+ priv, &priv->contexts[IWL_RXON_CTX_BSS],
+ info->control.sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
@@ -536,6 +545,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
txq->txb[q->write_ptr].skb = skb;
+ txq->txb[q->write_ptr].ctx = &priv->contexts[IWL_RXON_CTX_BSS];
/* Init first empty entry in queue's array of Tx/cmd buffers */
out_cmd = txq->cmd[idx];
@@ -677,11 +687,12 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
int rc;
int spectrum_resp_status;
int duration = le16_to_cpu(params->duration);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- if (iwl_is_associated(priv))
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS))
add_time = iwl_usecs_to_beacons(priv,
le64_to_cpu(params->start_time) - priv->_3945.last_tsf,
- le16_to_cpu(priv->rxon_timing.beacon_interval));
+ le16_to_cpu(ctx->timing.beacon_interval));
memset(&spectrum, 0, sizeof(spectrum));
@@ -692,18 +703,18 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
cmd.len = sizeof(spectrum);
spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
- if (iwl_is_associated(priv))
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS))
spectrum.start_time =
iwl_add_beacon_time(priv,
priv->_3945.last_beacon_time, add_time,
- le16_to_cpu(priv->rxon_timing.beacon_interval));
+ le16_to_cpu(ctx->timing.beacon_interval));
else
spectrum.start_time = 0;
spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
spectrum.channels[0].channel = params->channel;
spectrum.channels[0].type = type;
- if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ if (ctx->active.flags & RXON_FLG_BAND_24G_MSK)
spectrum.flags |= RXON_FLG_BAND_24G_MSK |
RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
@@ -792,7 +803,8 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
struct sk_buff *beacon;
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
- beacon = ieee80211_beacon_get(priv->hw, priv->vif);
+ beacon = ieee80211_beacon_get(priv->hw,
+ priv->contexts[IWL_RXON_CTX_BSS].vif);
if (!beacon) {
IWL_ERR(priv, "update beacon failed\n");
@@ -801,10 +813,10 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
mutex_lock(&priv->mutex);
/* new beacon skb is allocated every time; dispose previous.*/
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
+ if (priv->beacon_skb)
+ dev_kfree_skb(priv->beacon_skb);
- priv->ibss_beacon = beacon;
+ priv->beacon_skb = beacon;
mutex_unlock(&priv->mutex);
iwl3945_send_beacon_cmd(priv);
@@ -813,9 +825,9 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
+#ifdef CONFIG_IWLWIFI_DEBUG
u8 rate = beacon->beacon_notify_hdr.rate;
IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
@@ -827,6 +839,8 @@ static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
le32_to_cpu(beacon->low_tsf), rate);
#endif
+ priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
+
if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
(!test_bit(STATUS_EXIT_PENDING, &priv->status)))
queue_work(priv->workqueue, &priv->beacon_update);
@@ -1567,16 +1581,16 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
- if (capacity > priv->cfg->max_event_log_size) {
+ if (capacity > priv->cfg->base_params->max_event_log_size) {
IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
- capacity, priv->cfg->max_event_log_size);
- capacity = priv->cfg->max_event_log_size;
+ capacity, priv->cfg->base_params->max_event_log_size);
+ capacity = priv->cfg->base_params->max_event_log_size;
}
- if (next_entry > priv->cfg->max_event_log_size) {
+ if (next_entry > priv->cfg->base_params->max_event_log_size) {
IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
- next_entry, priv->cfg->max_event_log_size);
- next_entry = priv->cfg->max_event_log_size;
+ next_entry, priv->cfg->base_params->max_event_log_size);
+ next_entry = priv->cfg->base_params->max_event_log_size;
}
size = num_wraps ? capacity : next_entry;
@@ -1716,7 +1730,6 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
IWL_ERR(priv, "Microcode SW error detected. "
"Restarting 0x%X.\n", inta);
priv->isr_stats.sw++;
- priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -2460,6 +2473,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
{
int thermal_spin = 0;
u32 rfkill;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
@@ -2505,7 +2519,8 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
/* Enable timer to monitor the driver queues */
mod_timer(&priv->monitor_recover,
jiffies +
- msecs_to_jiffies(priv->cfg->monitor_recover_period));
+ msecs_to_jiffies(
+ priv->cfg->base_params->monitor_recover_period));
}
if (iwl_is_rfkill(priv))
@@ -2517,22 +2532,22 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
iwl_power_update_mode(priv, true);
- if (iwl_is_associated(priv)) {
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
struct iwl3945_rxon_cmd *active_rxon =
- (struct iwl3945_rxon_cmd *)(&priv->active_rxon);
+ (struct iwl3945_rxon_cmd *)(&ctx->active);
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
- iwl_connection_init_rx_config(priv, NULL);
+ iwl_connection_init_rx_config(priv, ctx);
}
/* Configure Bluetooth device coexistence support */
priv->cfg->ops->hcmd->send_bt_config(priv);
/* Configure the adapter for unassociated operation */
- iwlcore_commit_rxon(priv);
+ iwl3945_commit_rxon(priv, ctx);
iwl3945_reg_txpower_periodic(priv);
@@ -2553,19 +2568,22 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv);
static void __iwl3945_down(struct iwl_priv *priv)
{
unsigned long flags;
- int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
- struct ieee80211_conf *conf = NULL;
+ int exit_pending;
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
- conf = ieee80211_get_hw_conf(priv->hw);
+ iwl_scan_cancel_timeout(priv, 200);
- if (!exit_pending)
- set_bit(STATUS_EXIT_PENDING, &priv->status);
+ exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
+
+ /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
+ * to prevent rearm timer */
+ if (priv->cfg->ops->lib->recover_from_tx_stall)
+ del_timer_sync(&priv->monitor_recover);
/* Station information will now be cleared in device */
- iwl_clear_ucode_stations(priv);
- iwl_dealloc_bcast_station(priv);
+ iwl_clear_ucode_stations(priv, NULL);
+ iwl_dealloc_bcast_stations(priv);
iwl_clear_driver_stations(priv);
/* Unblock any waiting calls */
@@ -2619,14 +2637,14 @@ static void __iwl3945_down(struct iwl_priv *priv)
udelay(5);
/* Stop the device, and put it in low power state */
- priv->cfg->ops->lib->apm_ops.stop(priv);
+ iwl_apm_stop(priv);
exit:
memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
- priv->ibss_beacon = NULL;
+ if (priv->beacon_skb)
+ dev_kfree_skb(priv->beacon_skb);
+ priv->beacon_skb = NULL;
/* clear out any free frames */
iwl3945_clear_free_frames(priv);
@@ -2643,11 +2661,33 @@ static void iwl3945_down(struct iwl_priv *priv)
#define MAX_HW_RESTARTS 5
+static int iwl3945_alloc_bcast_station(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ unsigned long flags;
+ u8 sta_id;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Unable to prepare broadcast station\n");
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return -EINVAL;
+ }
+
+ priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
+ priv->stations[sta_id].used |= IWL_STA_BCAST;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return 0;
+}
+
static int __iwl3945_up(struct iwl_priv *priv)
{
int rc, i;
- rc = iwl_alloc_bcast_station(priv, false);
+ rc = iwl3945_alloc_bcast_station(priv);
if (rc)
return rc;
@@ -2799,7 +2839,7 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
}
-void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
+int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
@@ -2807,61 +2847,19 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
.flags = CMD_SIZE_HUGE,
};
struct iwl3945_scan_cmd *scan;
- struct ieee80211_conf *conf = NULL;
u8 n_probes = 0;
enum ieee80211_band band;
bool is_active = false;
+ int ret;
- conf = ieee80211_get_hw_conf(priv->hw);
-
- cancel_delayed_work(&priv->scan_check);
-
- if (!iwl_is_ready(priv)) {
- IWL_WARN(priv, "request scan called when driver not ready.\n");
- goto done;
- }
-
- /* Make sure the scan wasn't canceled before this queued work
- * was given the chance to run... */
- if (!test_bit(STATUS_SCANNING, &priv->status))
- goto done;
-
- /* This should never be called or scheduled if there is currently
- * a scan active in the hardware. */
- if (test_bit(STATUS_SCAN_HW, &priv->status)) {
- IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests "
- "Ignoring second request.\n");
- goto done;
- }
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
- goto done;
- }
-
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_HC(priv,
- "Scan request while abort pending. Queuing.\n");
- goto done;
- }
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
- goto done;
- }
-
- if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_DEBUG_HC(priv,
- "Scan request while uninitialized. Queuing.\n");
- goto done;
- }
+ lockdep_assert_held(&priv->mutex);
if (!priv->scan_cmd) {
priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) +
IWL_MAX_SCAN_SIZE, GFP_KERNEL);
if (!priv->scan_cmd) {
IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n");
- goto done;
+ return -ENOMEM;
}
}
scan = priv->scan_cmd;
@@ -2870,7 +2868,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
- if (iwl_is_associated(priv)) {
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
u16 interval = 0;
u32 extra;
u32 suspend_time = 100;
@@ -2931,7 +2929,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
/* We don't build a direct scan probe request; the uCode will do
* that based on the direct_mask added to each channel entry */
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
+ scan->tx_cmd.sta_id = priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
/* flags + rate selection */
@@ -2940,25 +2938,25 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
case IEEE80211_BAND_2GHZ:
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
- scan->good_CRC_th = 0;
band = IEEE80211_BAND_2GHZ;
break;
case IEEE80211_BAND_5GHZ:
scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
- /*
- * If active scaning is requested but a certain channel
- * is marked passive, we can do active scanning if we
- * detect transmissions.
- */
- scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
- IWL_GOOD_CRC_TH_DISABLED;
band = IEEE80211_BAND_5GHZ;
break;
default:
IWL_WARN(priv, "Invalid scan band\n");
- goto done;
+ return -EIO;
}
+ /*
+ * If active scaning is requested but a certain channel
+ * is marked passive, we can do active scanning if we
+ * detect transmissions.
+ */
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+ IWL_GOOD_CRC_TH_DISABLED;
+
if (!priv->is_internal_short_scan) {
scan->tx_cmd.len = cpu_to_le16(
iwl_fill_probe_req(priv,
@@ -2991,7 +2989,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
if (scan->channel_count == 0) {
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
- goto done;
+ return -EIO;
}
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
@@ -3000,25 +2998,22 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
scan->len = cpu_to_le16(cmd.len);
set_bit(STATUS_SCAN_HW, &priv->status);
- if (iwl_send_cmd_sync(priv, &cmd))
- goto done;
-
- queue_delayed_work(priv->workqueue, &priv->scan_check,
- IWL_SCAN_CHECK_WATCHDOG);
+ ret = iwl_send_cmd_sync(priv, &cmd);
+ if (ret)
+ clear_bit(STATUS_SCAN_HW, &priv->status);
+ return ret;
+}
- return;
+void iwl3945_post_scan(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- done:
- /* can not perform scan make sure we clear scanning
- * bits from status so next scan request can be performed.
- * if we dont clear scanning status bit here all next scan
- * will fail
- */
- clear_bit(STATUS_SCAN_HW, &priv->status);
- clear_bit(STATUS_SCANNING, &priv->status);
-
- /* inform mac80211 scan aborted */
- queue_work(priv->workqueue, &priv->abort_scan);
+ /*
+ * Since setting the RXON may have been deferred while
+ * performing the scan, fire one off if needed
+ */
+ if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+ iwl3945_commit_rxon(priv, ctx);
}
static void iwl3945_bg_restart(struct work_struct *data)
@@ -3029,8 +3024,10 @@ static void iwl3945_bg_restart(struct work_struct *data)
return;
if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+ struct iwl_rxon_context *ctx;
mutex_lock(&priv->mutex);
- priv->vif = NULL;
+ for_each_context(priv, ctx)
+ ctx->vif = NULL;
priv->is_open = 0;
mutex_unlock(&priv->mutex);
iwl3945_down(priv);
@@ -3064,6 +3061,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
if (!vif || !priv->is_open)
return;
@@ -3074,7 +3072,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
}
IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
- vif->bss_conf.aid, priv->active_rxon.bssid_addr);
+ vif->bss_conf.aid, ctx->active.bssid_addr);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -3083,37 +3081,34 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
conf = ieee80211_get_hw_conf(priv->hw);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwl3945_commit_rxon(priv, ctx);
- memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
- iwl_setup_rxon_timing(priv, vif);
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing), &priv->rxon_timing);
+ rc = iwl_send_rxon_timing(priv, ctx);
if (rc)
IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
- priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+ ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
vif->bss_conf.aid, vif->bss_conf.beacon_int);
if (vif->bss_conf.use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
}
- iwlcore_commit_rxon(priv);
+ iwl3945_commit_rxon(priv, ctx);
switch (vif->type) {
case NL80211_IFTYPE_STATION:
@@ -3212,15 +3207,6 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
priv->is_open = 0;
- if (iwl_is_ready_rf(priv)) {
- /* stop mac, cancel any scan request and clear
- * RXON_FILTER_ASSOC_MSK BIT
- */
- mutex_lock(&priv->mutex);
- iwl_scan_cancel_timeout(priv, 100);
- mutex_unlock(&priv->mutex);
- }
-
iwl3945_down(priv);
flush_workqueue(priv->workqueue);
@@ -3250,48 +3236,45 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
int rc = 0;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
/* The following should be done only at AP bring up */
- if (!(iwl_is_associated(priv))) {
+ if (!(iwl_is_associated(priv, IWL_RXON_CTX_BSS))) {
/* RXON - unassoc (to set timing command) */
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwl3945_commit_rxon(priv, ctx);
/* RXON Timing */
- memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
- iwl_setup_rxon_timing(priv, vif);
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing),
- &priv->rxon_timing);
+ rc = iwl_send_rxon_timing(priv, ctx);
if (rc)
IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
- priv->staging_rxon.assoc_id = 0;
+ ctx->staging.assoc_id = 0;
if (vif->bss_conf.use_short_preamble)
- priv->staging_rxon.flags |=
+ ctx->staging.flags |=
RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &=
+ ctx->staging.flags &=
~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- priv->staging_rxon.flags |=
+ ctx->staging.flags |=
RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &=
+ ctx->staging.flags &=
~RXON_FLG_SHORT_SLOT_MSK;
}
/* restore RXON assoc */
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ iwl3945_commit_rxon(priv, ctx);
}
iwl3945_send_beacon_cmd(priv);
@@ -3317,10 +3300,11 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return -EOPNOTSUPP;
}
- static_key = !iwl_is_associated(priv);
+ static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS);
if (!static_key) {
- sta_id = iwl_sta_id_or_broadcast(priv, sta);
+ sta_id = iwl_sta_id_or_broadcast(
+ priv, &priv->contexts[IWL_RXON_CTX_BSS], sta);
if (sta_id == IWL_INVALID_STATION)
return -EINVAL;
}
@@ -3371,8 +3355,8 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
sta_priv->common.sta_id = IWL_INVALID_STATION;
- ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
- &sta_id);
+ ret = iwl_add_station_common(priv, &priv->contexts[IWL_RXON_CTX_BSS],
+ sta->addr, is_ap, sta, &sta_id);
if (ret) {
IWL_ERR(priv, "Unable to add station %pM (%d)\n",
sta->addr, ret);
@@ -3399,6 +3383,7 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
__le32 filter_or = 0, filter_nand = 0;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
#define CHK(test, flag) do { \
if (*total_flags & (test)) \
@@ -3418,8 +3403,8 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
- priv->staging_rxon.filter_flags &= ~filter_nand;
- priv->staging_rxon.filter_flags |= filter_or;
+ ctx->staging.filter_flags &= ~filter_nand;
+ ctx->staging.filter_flags |= filter_or;
/*
* Committing directly here breaks for some reason,
@@ -3533,8 +3518,9 @@ static ssize_t show_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
+ return sprintf(buf, "0x%04X\n", ctx->active.flags);
}
static ssize_t store_flags(struct device *d,
@@ -3543,17 +3529,18 @@ static ssize_t store_flags(struct device *d,
{
struct iwl_priv *priv = dev_get_drvdata(d);
u32 flags = simple_strtoul(buf, NULL, 0);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
mutex_lock(&priv->mutex);
- if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
+ if (le32_to_cpu(ctx->staging.flags) != flags) {
/* Cancel any currently running scans... */
if (iwl_scan_cancel_timeout(priv, 100))
IWL_WARN(priv, "Could not cancel scan.\n");
else {
IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
flags);
- priv->staging_rxon.flags = cpu_to_le32(flags);
- iwlcore_commit_rxon(priv);
+ ctx->staging.flags = cpu_to_le32(flags);
+ iwl3945_commit_rxon(priv, ctx);
}
}
mutex_unlock(&priv->mutex);
@@ -3567,9 +3554,10 @@ static ssize_t show_filter_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
return sprintf(buf, "0x%04X\n",
- le32_to_cpu(priv->active_rxon.filter_flags));
+ le32_to_cpu(ctx->active.filter_flags));
}
static ssize_t store_filter_flags(struct device *d,
@@ -3577,19 +3565,20 @@ static ssize_t store_filter_flags(struct device *d,
const char *buf, size_t count)
{
struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
u32 filter_flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
- if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
+ if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
if (iwl_scan_cancel_timeout(priv, 100))
IWL_WARN(priv, "Could not cancel scan.\n");
else {
IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
"0x%04X\n", filter_flags);
- priv->staging_rxon.filter_flags =
+ ctx->staging.filter_flags =
cpu_to_le32(filter_flags);
- iwlcore_commit_rxon(priv);
+ iwl3945_commit_rxon(priv, ctx);
}
}
mutex_unlock(&priv->mutex);
@@ -3637,8 +3626,9 @@ static ssize_t store_measurement(struct device *d,
const char *buf, size_t count)
{
struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct ieee80211_measurement_params params = {
- .channel = le16_to_cpu(priv->active_rxon.channel),
+ .channel = le16_to_cpu(ctx->active.channel),
.start_time = cpu_to_le64(priv->_3945.last_tsf),
.duration = cpu_to_le16(1),
};
@@ -3785,10 +3775,8 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll);
- INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
- INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
- INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
- INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
+
+ iwl_setup_scan_deferred_work(priv);
iwl3945_hw_setup_deferred_work(priv);
@@ -3808,12 +3796,10 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
iwl3945_hw_cancel_deferred_work(priv);
cancel_delayed_work_sync(&priv->init_alive_start);
- cancel_delayed_work(&priv->scan_check);
cancel_delayed_work(&priv->alive_start);
- cancel_work_sync(&priv->start_internal_scan);
cancel_work_sync(&priv->beacon_update);
- if (priv->cfg->ops->lib->recover_from_tx_stall)
- del_timer_sync(&priv->monitor_recover);
+
+ iwl_cancel_scan_deferred_work(priv);
}
static struct attribute *iwl3945_sysfs_entries[] = {
@@ -3853,6 +3839,7 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.hw_scan = iwl_mac_hw_scan,
.sta_add = iwl3945_mac_sta_add,
.sta_remove = iwl_mac_sta_remove,
+ .tx_last_beacon = iwl_mac_tx_last_beacon,
};
static int iwl3945_init_drv(struct iwl_priv *priv)
@@ -3861,7 +3848,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
priv->retry_rate = 1;
- priv->ibss_beacon = NULL;
+ priv->beacon_skb = NULL;
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
@@ -3928,13 +3915,12 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SPECTRUM_MGMT;
- if (!priv->cfg->broken_powersave)
+ if (!priv->cfg->base_params->broken_powersave)
hw->flags |= IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
hw->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC);
+ priv->contexts[IWL_RXON_CTX_BSS].interface_modes;
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS;
@@ -3966,7 +3952,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int err = 0;
+ int err = 0, i;
struct iwl_priv *priv;
struct ieee80211_hw *hw;
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
@@ -3988,12 +3974,33 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
priv = hw->priv;
SET_IEEE80211_DEV(hw, &pdev->dev);
+ priv->cmd_queue = IWL39_CMD_QUEUE_NUM;
+
+ /* 3945 has only one valid context */
+ priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
+
+ for (i = 0; i < NUM_IWL_RXON_CTX; i++)
+ priv->contexts[i].ctxid = i;
+
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
+ priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
+ priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
+ priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC);
+ priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
+ priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
+ priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
+
/*
* Disabling hardware scan means that mac80211 will perform scans
* "the hard way", rather than using device's scan.
*/
if (iwl3945_mod_params.disable_hw_scan) {
- IWL_DEBUG_INFO(priv, "Disabling hw_scan\n");
+ IWL_ERR(priv, "sw scan support is deprecated\n");
iwl3945_hw_ops.hw_scan = NULL;
}
@@ -4009,6 +4016,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/***************************
* 2. Initializing PCI bus
* *************************/
+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+ PCIE_LINK_STATE_CLKPM);
+
if (pci_enable_device(pdev)) {
err = -ENODEV;
goto out_ieee80211_free_hw;
@@ -4120,7 +4130,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
}
iwl_set_rxon_channel(priv,
- &priv->bands[IEEE80211_BAND_2GHZ].channels[5]);
+ &priv->bands[IEEE80211_BAND_2GHZ].channels[5],
+ &priv->contexts[IWL_RXON_CTX_BSS]);
iwl3945_setup_deferred_work(priv);
iwl3945_setup_rx_handlers(priv);
iwl_power_initialize(priv);
@@ -4201,7 +4212,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
* paths to avoid running iwl_down() at all before leaving driver.
* This (inexpensive) call *makes sure* device is reset.
*/
- priv->cfg->ops->lib->apm_ops.stop(priv);
+ iwl_apm_stop(priv);
/* make sure we flush any pending irq or
* tasklet for the driver
@@ -4245,8 +4256,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
iwl_free_channel_map(priv);
iwlcore_free_geos(priv);
kfree(priv->scan_cmd);
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
+ if (priv->beacon_skb)
+ dev_kfree_skb(priv->beacon_skb);
ieee80211_free_hw(priv->hw);
}
@@ -4314,7 +4325,8 @@ MODULE_PARM_DESC(debug, "debug output mask");
#endif
module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan,
int, S_IRUGO);
-MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
+MODULE_PARM_DESC(disable_hw_scan,
+ "disable hardware scanning (default 0) (deprecated)");
module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO);
MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 60619678f4ec..c6c0eff9b5ed 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -161,7 +161,7 @@ static int iwm_key_init(struct iwm_key *key, u8 key_index,
}
static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_index, const u8 *mac_addr,
+ u8 key_index, bool pairwise, const u8 *mac_addr,
struct key_params *params)
{
struct iwm_priv *iwm = ndev_to_iwm(ndev);
@@ -181,7 +181,8 @@ static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
}
static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_index, const u8 *mac_addr, void *cookie,
+ u8 key_index, bool pairwise, const u8 *mac_addr,
+ void *cookie,
void (*callback)(void *cookie,
struct key_params*))
{
@@ -206,7 +207,7 @@ static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_index, const u8 *mac_addr)
+ u8 key_index, bool pairwise, const u8 *mac_addr)
{
struct iwm_priv *iwm = ndev_to_iwm(ndev);
struct iwm_key *key = &iwm->keys[key_index];
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index c02fcedea9fa..a944893ae3ca 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1195,11 +1195,8 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: "
"oid is 0x%x\n", hdr->oid);
- if (hdr->oid <= WIFI_IF_NTFY_MAX) {
- set_bit(hdr->oid, &iwm->wifi_ntfy[0]);
- wake_up_interruptible(&iwm->wifi_ntfy_queue);
- } else
- return -EINVAL;
+ set_bit(hdr->oid, &iwm->wifi_ntfy[0]);
+ wake_up_interruptible(&iwm->wifi_ntfy_queue);
switch (hdr->oid) {
case UMAC_WIFI_IF_CMD_SET_PROFILE:
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 3e82f1627209..5046a0005034 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -10,6 +10,7 @@
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/sched.h>
+#include <linux/wait.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <asm/unaligned.h>
@@ -480,7 +481,6 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
int bsssize;
const u8 *pos;
- u16 nr_sets;
const u8 *tsfdesc;
int tsfsize;
int i;
@@ -489,12 +489,11 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
lbs_deb_enter(LBS_DEB_CFG80211);
bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
- nr_sets = le16_to_cpu(scanresp->nr_sets);
lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n",
- nr_sets, bsssize, le16_to_cpu(resp->size));
+ scanresp->nr_sets, bsssize, le16_to_cpu(resp->size));
- if (nr_sets == 0) {
+ if (scanresp->nr_sets == 0) {
ret = 0;
goto done;
}
@@ -526,20 +525,31 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
pos = scanresp->bssdesc_and_tlvbuffer;
+ lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer,
+ scanresp->bssdescriptsize);
+
tsfdesc = pos + bsssize;
tsfsize = 4 + 8 * scanresp->nr_sets;
+ lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TSF", (u8 *) tsfdesc, tsfsize);
/* Validity check: we expect a Marvell-Local TLV */
i = get_unaligned_le16(tsfdesc);
tsfdesc += 2;
- if (i != TLV_TYPE_TSFTIMESTAMP)
+ if (i != TLV_TYPE_TSFTIMESTAMP) {
+ lbs_deb_scan("scan response: invalid TSF Timestamp %d\n", i);
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 */
i = get_unaligned_le16(tsfdesc);
tsfdesc += 2;
- if (i / 8 != scanresp->nr_sets)
+ if (i / 8 != scanresp->nr_sets) {
+ lbs_deb_scan("scan response: invalid number of TSF timestamp "
+ "sets (expected %d got %d)\n", scanresp->nr_sets,
+ i / 8);
goto done;
+ }
for (i = 0; i < scanresp->nr_sets; i++) {
const u8 *bssid;
@@ -581,8 +591,11 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
id = *pos++;
elen = *pos++;
left -= 2;
- if (elen > left || elen == 0)
+ if (elen > left || elen == 0) {
+ lbs_deb_scan("scan response: invalid IE fmt\n");
goto done;
+ }
+
if (id == WLAN_EID_DS_PARAMS)
chan_no = *pos;
if (id == WLAN_EID_SSID) {
@@ -613,7 +626,9 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
capa, intvl, ie, ielen,
LBS_SCAN_RSSI_TO_MBM(rssi),
GFP_KERNEL);
- }
+ } else
+ lbs_deb_scan("scan response: missing BSS channel IE\n");
+
tsfdesc += 8;
}
ret = 0;
@@ -1103,7 +1118,7 @@ static int lbs_associate(struct lbs_private *priv,
lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp);
/* add auth type TLV */
- if (priv->fwrelease >= 0x09000000)
+ if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9)
pos += lbs_add_auth_type_tlv(pos, sme->auth_type);
/* add WPA/WPA2 TLV */
@@ -1114,6 +1129,9 @@ static int lbs_associate(struct lbs_private *priv,
(u16)(pos - (u8 *) &cmd->iebuf);
cmd->hdr.size = cpu_to_le16(len);
+ lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_CMD", (u8 *) cmd,
+ le16_to_cpu(cmd->hdr.size));
+
/* store for later use */
memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN);
@@ -1121,14 +1139,28 @@ static int lbs_associate(struct lbs_private *priv,
if (ret)
goto done;
-
/* generate connect message to cfg80211 */
resp = (void *) cmd; /* recast for easier field access */
status = le16_to_cpu(resp->statuscode);
- /* Convert statis code of old firmware */
- if (priv->fwrelease < 0x09000000)
+ /* Older FW versions map the IEEE 802.11 Status Code in the association
+ * response to the following values returned in resp->statuscode:
+ *
+ * IEEE Status Code Marvell Status Code
+ * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
+ * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * others -> 0x0003 ASSOC_RESULT_REFUSED
+ *
+ * Other response codes:
+ * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
+ * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
+ * association response from the AP)
+ */
+ if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
switch (status) {
case 0:
break;
@@ -1150,11 +1182,16 @@ static int lbs_associate(struct lbs_private *priv,
break;
default:
lbs_deb_assoc("association failure %d\n", status);
- status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ /* v5 OLPC firmware does return the AP status code if
+ * it's not one of the values above. Let that through.
+ */
+ break;
+ }
}
- lbs_deb_assoc("status %d, capability 0x%04x\n", status,
- le16_to_cpu(resp->capability));
+ lbs_deb_assoc("status %d, statuscode 0x%04x, capability 0x%04x, "
+ "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode),
+ le16_to_cpu(resp->capability), le16_to_cpu(resp->aid));
resp_ie_len = le16_to_cpu(resp->hdr.size)
- sizeof(resp->hdr)
@@ -1174,7 +1211,6 @@ static int lbs_associate(struct lbs_private *priv,
netif_tx_wake_all_queues(priv->dev);
}
-
done:
lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
return ret;
@@ -1404,7 +1440,7 @@ static int lbs_cfg_set_default_key(struct wiphy *wiphy,
static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
- u8 idx, const u8 *mac_addr,
+ u8 idx, bool pairwise, const u8 *mac_addr,
struct key_params *params)
{
struct lbs_private *priv = wiphy_priv(wiphy);
@@ -1464,7 +1500,7 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, const u8 *mac_addr)
+ u8 key_index, bool pairwise, const u8 *mac_addr)
{
lbs_deb_enter(LBS_DEB_CFG80211);
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 1d141fefd767..2ae752d10065 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -8,7 +8,14 @@
#define _LBS_DECL_H_
#include <linux/netdevice.h>
+#include <linux/firmware.h>
+/* Should be terminated by a NULL entry */
+struct lbs_fw_table {
+ int model;
+ const char *helper;
+ const char *fwname;
+};
struct lbs_private;
struct sk_buff;
@@ -53,4 +60,10 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
u32 lbs_fw_index_to_data_rate(u8 index);
u8 lbs_data_rate_to_fw_index(u32 rate);
+int lbs_get_firmware(struct device *dev, const char *user_helper,
+ const char *user_mainfw, u32 card_model,
+ const struct lbs_fw_table *fw_table,
+ const struct firmware **helper,
+ const struct firmware **mainfw);
+
#endif
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index ff1280f41336..fc8121190d38 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -47,7 +47,6 @@
MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>");
MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards");
MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("libertas_cs_helper.fw");
@@ -60,9 +59,34 @@ struct if_cs_card {
struct lbs_private *priv;
void __iomem *iobase;
bool align_regs;
+ u32 model;
};
+enum {
+ MODEL_UNKNOWN = 0x00,
+ MODEL_8305 = 0x01,
+ MODEL_8381 = 0x02,
+ MODEL_8385 = 0x03
+};
+
+static const struct lbs_fw_table fw_table[] = {
+ { MODEL_8305, "libertas/cf8305.bin", NULL },
+ { MODEL_8305, "libertas_cs_helper.fw", NULL },
+ { MODEL_8381, "libertas/cf8381_helper.bin", "libertas/cf8381.bin" },
+ { MODEL_8381, "libertas_cs_helper.fw", "libertas_cs.fw" },
+ { MODEL_8385, "libertas/cf8385_helper.bin", "libertas/cf8385.bin" },
+ { MODEL_8385, "libertas_cs_helper.fw", "libertas_cs.fw" },
+ { 0, NULL, NULL }
+};
+MODULE_FIRMWARE("libertas/cf8305.bin");
+MODULE_FIRMWARE("libertas/cf8381_helper.bin");
+MODULE_FIRMWARE("libertas/cf8381.bin");
+MODULE_FIRMWARE("libertas/cf8385_helper.bin");
+MODULE_FIRMWARE("libertas/cf8385.bin");
+MODULE_FIRMWARE("libertas_cs_helper.fw");
+MODULE_FIRMWARE("libertas_cs.fw");
+
/********************************************************************/
/* Hardware access */
@@ -288,22 +312,19 @@ 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
-static inline int if_cs_hw_is_cf8305(struct pcmcia_device *p_dev)
-{
- return (p_dev->manf_id == CF8305_MANFID &&
- p_dev->card_id == CF8305_CARDID);
-}
-
-static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev)
-{
- return (p_dev->manf_id == CF8381_MANFID &&
- p_dev->card_id == CF8381_CARDID);
-}
-
-static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev)
+/* 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)
{
- return (p_dev->manf_id == CF8385_MANFID &&
- p_dev->card_id == CF8385_CARDID);
+ /* NOTE: keep in sync with if_cs_ids */
+ if (manf_id == CF8305_MANFID && card_id == CF8305_CARDID)
+ return MODEL_8305;
+ else if (manf_id == CF8381_MANFID && card_id == CF8381_CARDID)
+ return MODEL_8381;
+ else if (manf_id == CF8385_MANFID && card_id == CF8385_CARDID)
+ return MODEL_8385;
+ return MODEL_UNKNOWN;
}
/********************************************************************/
@@ -557,12 +578,11 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
*
* Return 0 on success
*/
-static int if_cs_prog_helper(struct if_cs_card *card)
+static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
{
int ret = 0;
int sent = 0;
u8 scratch;
- const struct firmware *fw;
lbs_deb_enter(LBS_DEB_CS);
@@ -588,14 +608,6 @@ static int if_cs_prog_helper(struct if_cs_card *card)
goto done;
}
- /* TODO: make firmware file configurable */
- ret = request_firmware(&fw, "libertas_cs_helper.fw",
- &card->p_dev->dev);
- if (ret) {
- lbs_pr_err("can't load helper firmware\n");
- ret = -ENODEV;
- goto done;
- }
lbs_deb_cs("helper size %td\n", fw->size);
/* "Set the 5 bytes of the helper image to 0" */
@@ -634,7 +646,7 @@ static int if_cs_prog_helper(struct if_cs_card *card)
if (ret < 0) {
lbs_pr_err("can't download helper at 0x%x, ret %d\n",
sent, ret);
- goto err_release;
+ goto done;
}
if (count == 0)
@@ -643,17 +655,14 @@ static int if_cs_prog_helper(struct if_cs_card *card)
sent += count;
}
-err_release:
- release_firmware(fw);
done:
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
return ret;
}
-static int if_cs_prog_real(struct if_cs_card *card)
+static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
{
- const struct firmware *fw;
int ret = 0;
int retry = 0;
int len = 0;
@@ -661,21 +670,13 @@ static int if_cs_prog_real(struct if_cs_card *card)
lbs_deb_enter(LBS_DEB_CS);
- /* TODO: make firmware file configurable */
- ret = request_firmware(&fw, "libertas_cs.fw",
- &card->p_dev->dev);
- if (ret) {
- lbs_pr_err("can't load firmware\n");
- ret = -ENODEV;
- goto done;
- }
lbs_deb_cs("fw size %td\n", fw->size);
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");
- goto err_release;
+ goto done;
}
for (sent = 0; sent < fw->size; sent += len) {
@@ -690,7 +691,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
if (retry > 20) {
lbs_pr_err("could not download firmware\n");
ret = -ENODEV;
- goto err_release;
+ goto done;
}
if (retry) {
sent -= len;
@@ -709,7 +710,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
IF_CS_BIT_COMMAND);
if (ret < 0) {
lbs_pr_err("can't download firmware at 0x%x\n", sent);
- goto err_release;
+ goto done;
}
}
@@ -717,9 +718,6 @@ static int if_cs_prog_real(struct if_cs_card *card)
if (ret < 0)
lbs_pr_err("firmware download failed\n");
-err_release:
- release_firmware(fw);
-
done:
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
return ret;
@@ -795,6 +793,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
unsigned int prod_id;
struct lbs_private *priv;
struct if_cs_card *card;
+ const struct firmware *helper = NULL;
+ const struct firmware *mainfw = NULL;
lbs_deb_enter(LBS_DEB_CS);
@@ -845,34 +845,47 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
*/
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);
+ goto out2;
+ }
+
/* Check if we have a current silicon */
prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
- if (if_cs_hw_is_cf8305(p_dev)) {
+ if (card->model == MODEL_8305) {
card->align_regs = 1;
if (prod_id < IF_CS_CF8305_B1_REV) {
- lbs_pr_err("old chips like 8305 rev B3 "
- "aren't supported\n");
+ lbs_pr_err("8305 rev B0 and older are not supported\n");
ret = -ENODEV;
goto out2;
}
}
- if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) {
- lbs_pr_err("old chips like 8381 rev B3 aren't supported\n");
+ if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) {
+ lbs_pr_err("8381 rev B2 and older are not supported\n");
ret = -ENODEV;
goto out2;
}
- if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) {
- lbs_pr_err("old chips like 8385 rev B1 aren't supported\n");
+ if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) {
+ lbs_pr_err("8385 rev B0 and older are not supported\n");
ret = -ENODEV;
goto out2;
}
+ 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);
+ goto out2;
+ }
+
/* Load the firmware early, before calling into libertas.ko */
- ret = if_cs_prog_helper(card);
- if (ret == 0 && !if_cs_hw_is_cf8305(p_dev))
- ret = if_cs_prog_real(card);
+ ret = if_cs_prog_helper(card, helper);
+ if (ret == 0 && (card->model != MODEL_8305))
+ ret = if_cs_prog_real(card, mainfw);
if (ret)
goto out2;
@@ -921,6 +934,11 @@ out2:
out1:
pcmcia_disable_device(p_dev);
out:
+ if (helper)
+ release_firmware(helper);
+ if (mainfw)
+ release_firmware(mainfw);
+
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
return ret;
}
@@ -951,6 +969,7 @@ static struct pcmcia_device_id if_cs_ids[] = {
PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID),
PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
+ /* NOTE: keep in sync with get_model() */
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 87b634978b35..296fd00a5129 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -76,36 +76,32 @@ static const struct sdio_device_id if_sdio_ids[] = {
MODULE_DEVICE_TABLE(sdio, if_sdio_ids);
-struct if_sdio_model {
- int model;
- const char *helper;
- const char *firmware;
-};
-
-static struct if_sdio_model if_sdio_models[] = {
- {
- /* 8385 */
- .model = IF_SDIO_MODEL_8385,
- .helper = "sd8385_helper.bin",
- .firmware = "sd8385.bin",
- },
- {
- /* 8686 */
- .model = IF_SDIO_MODEL_8686,
- .helper = "sd8686_helper.bin",
- .firmware = "sd8686.bin",
- },
- {
- /* 8688 */
- .model = IF_SDIO_MODEL_8688,
- .helper = "sd8688_helper.bin",
- .firmware = "sd8688.bin",
- },
+#define MODEL_8385 0x04
+#define MODEL_8686 0x0b
+#define MODEL_8688 0x10
+
+static const struct lbs_fw_table fw_table[] = {
+ { MODEL_8385, "libertas/sd8385_helper.bin", "libertas/sd8385.bin" },
+ { MODEL_8385, "sd8385_helper.bin", "sd8385.bin" },
+ { MODEL_8686, "libertas/sd8686_v9_helper.bin", "libertas/sd8686_v9.bin" },
+ { MODEL_8686, "libertas/sd8686_v8_helper.bin", "libertas/sd8686_v8.bin" },
+ { MODEL_8686, "sd8686_helper.bin", "sd8686.bin" },
+ { MODEL_8688, "libertas/sd8688_helper.bin", "libertas/sd8688.bin" },
+ { MODEL_8688, "sd8688_helper.bin", "sd8688.bin" },
+ { 0, NULL, NULL }
};
+MODULE_FIRMWARE("libertas/sd8385_helper.bin");
+MODULE_FIRMWARE("libertas/sd8385.bin");
MODULE_FIRMWARE("sd8385_helper.bin");
MODULE_FIRMWARE("sd8385.bin");
+MODULE_FIRMWARE("libertas/sd8686_v9_helper.bin");
+MODULE_FIRMWARE("libertas/sd8686_v9.bin");
+MODULE_FIRMWARE("libertas/sd8686_v8_helper.bin");
+MODULE_FIRMWARE("libertas/sd8686_v8.bin");
MODULE_FIRMWARE("sd8686_helper.bin");
MODULE_FIRMWARE("sd8686.bin");
+MODULE_FIRMWARE("libertas/sd8688_helper.bin");
+MODULE_FIRMWARE("libertas/sd8688.bin");
MODULE_FIRMWARE("sd8688_helper.bin");
MODULE_FIRMWARE("sd8688.bin");
@@ -187,11 +183,11 @@ static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err)
u16 rx_len;
switch (card->model) {
- case IF_SDIO_MODEL_8385:
- case IF_SDIO_MODEL_8686:
+ case MODEL_8385:
+ case MODEL_8686:
rx_len = if_sdio_read_scratch(card, &ret);
break;
- case IF_SDIO_MODEL_8688:
+ case MODEL_8688:
default: /* for newer chipsets */
rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret);
if (!ret)
@@ -288,7 +284,7 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
lbs_deb_enter(LBS_DEB_SDIO);
- if (card->model == IF_SDIO_MODEL_8385) {
+ if (card->model == MODEL_8385) {
event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
if (ret)
goto out;
@@ -466,10 +462,10 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)
-static int if_sdio_prog_helper(struct if_sdio_card *card)
+static int if_sdio_prog_helper(struct if_sdio_card *card,
+ const struct firmware *fw)
{
int ret;
- const struct firmware *fw;
unsigned long timeout;
u8 *chunk_buffer;
u32 chunk_size;
@@ -478,16 +474,10 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
lbs_deb_enter(LBS_DEB_SDIO);
- ret = request_firmware(&fw, card->helper, &card->func->dev);
- if (ret) {
- lbs_pr_err("can't load helper firmware\n");
- goto out;
- }
-
chunk_buffer = kzalloc(64, GFP_KERNEL);
if (!chunk_buffer) {
ret = -ENOMEM;
- goto release_fw;
+ goto out;
}
sdio_claim_host(card->func);
@@ -562,22 +552,19 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
release:
sdio_release_host(card->func);
kfree(chunk_buffer);
-release_fw:
- release_firmware(fw);
out:
if (ret)
lbs_pr_err("failed to load helper firmware\n");
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-
return ret;
}
-static int if_sdio_prog_real(struct if_sdio_card *card)
+static int if_sdio_prog_real(struct if_sdio_card *card,
+ const struct firmware *fw)
{
int ret;
- const struct firmware *fw;
unsigned long timeout;
u8 *chunk_buffer;
u32 chunk_size;
@@ -586,16 +573,10 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
lbs_deb_enter(LBS_DEB_SDIO);
- ret = request_firmware(&fw, card->firmware, &card->func->dev);
- if (ret) {
- lbs_pr_err("can't load firmware\n");
- goto out;
- }
-
chunk_buffer = kzalloc(512, GFP_KERNEL);
if (!chunk_buffer) {
ret = -ENOMEM;
- goto release_fw;
+ goto out;
}
sdio_claim_host(card->func);
@@ -685,15 +666,12 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
release:
sdio_release_host(card->func);
kfree(chunk_buffer);
-release_fw:
- release_firmware(fw);
out:
if (ret)
lbs_pr_err("failed to load firmware\n");
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-
return ret;
}
@@ -701,6 +679,8 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
{
int ret;
u16 scratch;
+ const struct firmware *helper = NULL;
+ const struct firmware *mainfw = NULL;
lbs_deb_enter(LBS_DEB_SDIO);
@@ -718,11 +698,18 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
goto success;
}
- ret = if_sdio_prog_helper(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);
+ goto out;
+ }
+
+ ret = if_sdio_prog_helper(card, helper);
if (ret)
goto out;
- ret = if_sdio_prog_real(card);
+ ret = if_sdio_prog_real(card, mainfw);
if (ret)
goto out;
@@ -733,8 +720,12 @@ success:
ret = 0;
out:
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+ if (helper)
+ release_firmware(helper);
+ if (mainfw)
+ release_firmware(mainfw);
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
return ret;
}
@@ -938,7 +929,7 @@ static int if_sdio_probe(struct sdio_func *func,
"ID: %x", &model) == 1)
break;
if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) {
- model = IF_SDIO_MODEL_8385;
+ model = MODEL_8385;
break;
}
}
@@ -956,13 +947,13 @@ static int if_sdio_probe(struct sdio_func *func,
card->model = model;
switch (card->model) {
- case IF_SDIO_MODEL_8385:
+ case MODEL_8385:
card->scratch_reg = IF_SDIO_SCRATCH_OLD;
break;
- case IF_SDIO_MODEL_8686:
+ case MODEL_8686:
card->scratch_reg = IF_SDIO_SCRATCH;
break;
- case IF_SDIO_MODEL_8688:
+ case MODEL_8688:
default: /* for newer chipsets */
card->scratch_reg = IF_SDIO_FW_STATUS;
break;
@@ -972,49 +963,17 @@ static int if_sdio_probe(struct sdio_func *func,
card->workqueue = create_workqueue("libertas_sdio");
INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
- for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
- if (card->model == if_sdio_models[i].model)
+ /* Check if we support this card */
+ for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
+ if (card->model == fw_table[i].model)
break;
}
-
- if (i == ARRAY_SIZE(if_sdio_models)) {
+ if (i == ARRAY_SIZE(fw_table)) {
lbs_pr_err("unknown card model 0x%x\n", card->model);
ret = -ENODEV;
goto free;
}
- card->helper = if_sdio_models[i].helper;
- card->firmware = if_sdio_models[i].firmware;
-
- kparam_block_sysfs_write(helper_name);
- if (lbs_helper_name) {
- char *helper = kstrdup(lbs_helper_name, GFP_KERNEL);
- if (!helper) {
- kparam_unblock_sysfs_write(helper_name);
- ret = -ENOMEM;
- goto free;
- }
- lbs_deb_sdio("overriding helper firmware: %s\n",
- lbs_helper_name);
- card->helper = helper;
- card->helper_allocated = true;
- }
- kparam_unblock_sysfs_write(helper_name);
-
- kparam_block_sysfs_write(fw_name);
- if (lbs_fw_name) {
- char *fw_name = kstrdup(lbs_fw_name, GFP_KERNEL);
- if (!fw_name) {
- kparam_unblock_sysfs_write(fw_name);
- ret = -ENOMEM;
- goto free;
- }
- lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name);
- card->firmware = fw_name;
- card->firmware_allocated = true;
- }
- kparam_unblock_sysfs_write(fw_name);
-
sdio_claim_host(func);
ret = sdio_enable_func(func);
@@ -1028,7 +987,7 @@ static int if_sdio_probe(struct sdio_func *func,
/* For 1-bit transfers to the 8686 model, we need to enable the
* interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
* bit to allow access to non-vendor registers. */
- if ((card->model == IF_SDIO_MODEL_8686) &&
+ if ((card->model == MODEL_8686) &&
(host->caps & MMC_CAP_SDIO_IRQ) &&
(host->ios.bus_width == MMC_BUS_WIDTH_1)) {
u8 reg;
@@ -1091,8 +1050,8 @@ static int if_sdio_probe(struct sdio_func *func,
* Get rx_unit if the chip is SD8688 or newer.
* SD8385 & SD8686 do not have rx_unit.
*/
- if ((card->model != IF_SDIO_MODEL_8385)
- && (card->model != IF_SDIO_MODEL_8686))
+ if ((card->model != MODEL_8385)
+ && (card->model != MODEL_8686))
card->rx_unit = if_sdio_read_rx_unit(card);
else
card->rx_unit = 0;
@@ -1108,7 +1067,7 @@ static int if_sdio_probe(struct sdio_func *func,
/*
* FUNC_INIT is required for SD8688 WLAN/BT multiple functions
*/
- if (card->model == IF_SDIO_MODEL_8688) {
+ if (card->model == MODEL_8688) {
struct cmd_header cmd;
memset(&cmd, 0, sizeof(cmd));
@@ -1165,7 +1124,7 @@ static void if_sdio_remove(struct sdio_func *func)
card = sdio_get_drvdata(func);
- if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) {
+ if (user_rmmod && (card->model == MODEL_8688)) {
/*
* FUNC_SHUTDOWN is required for SD8688 WLAN/BT
* multiple functions
diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h
index 12179c1dc9c9..62fda3592f67 100644
--- a/drivers/net/wireless/libertas/if_sdio.h
+++ b/drivers/net/wireless/libertas/if_sdio.h
@@ -12,10 +12,6 @@
#ifndef _LBS_IF_SDIO_H
#define _LBS_IF_SDIO_H
-#define IF_SDIO_MODEL_8385 0x04
-#define IF_SDIO_MODEL_8686 0x0b
-#define IF_SDIO_MODEL_8688 0x10
-
#define IF_SDIO_IOPORT 0x00
#define IF_SDIO_H_INT_MASK 0x04
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index fe3f08028eb3..79bcb4e5d2ca 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -39,9 +39,6 @@ struct if_spi_card {
struct lbs_private *priv;
struct libertas_spi_platform_data *pdata;
- char helper_fw_name[IF_SPI_FW_NAME_MAX];
- char main_fw_name[IF_SPI_FW_NAME_MAX];
-
/* The card ID and card revision, as reported by the hardware. */
u16 card_id;
u8 card_rev;
@@ -70,10 +67,28 @@ static void free_if_spi_card(struct if_spi_card *card)
kfree(card);
}
-static struct chip_ident chip_id_to_device_name[] = {
- { .chip_id = 0x04, .name = 8385 },
- { .chip_id = 0x0b, .name = 8686 },
+#define MODEL_8385 0x04
+#define MODEL_8686 0x0b
+#define MODEL_8688 0x10
+
+static const struct lbs_fw_table fw_table[] = {
+ { MODEL_8385, "libertas/gspi8385_helper.bin", "libertas/gspi8385.bin" },
+ { MODEL_8385, "libertas/gspi8385_hlp.bin", "libertas/gspi8385.bin" },
+ { MODEL_8686, "libertas/gspi8686_v9_helper.bin", "libertas/gspi8686_v9.bin" },
+ { MODEL_8686, "libertas/gspi8686_hlp.bin", "libertas/gspi8686.bin" },
+ { MODEL_8688, "libertas/gspi8688_helper.bin", "libertas/gspi8688.bin" },
+ { 0, NULL, NULL }
};
+MODULE_FIRMWARE("libertas/gspi8385_helper.bin");
+MODULE_FIRMWARE("libertas/gspi8385_hlp.bin");
+MODULE_FIRMWARE("libertas/gspi8385.bin");
+MODULE_FIRMWARE("libertas/gspi8686_v9_helper.bin");
+MODULE_FIRMWARE("libertas/gspi8686_v9.bin");
+MODULE_FIRMWARE("libertas/gspi8686_hlp.bin");
+MODULE_FIRMWARE("libertas/gspi8686.bin");
+MODULE_FIRMWARE("libertas/gspi8688_helper.bin");
+MODULE_FIRMWARE("libertas/gspi8688.bin");
+
/*
* SPI Interface Unit Routines
@@ -399,26 +414,20 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes)
* Firmware Loading
*/
-static int if_spi_prog_helper_firmware(struct if_spi_card *card)
+static int if_spi_prog_helper_firmware(struct if_spi_card *card,
+ const struct firmware *firmware)
{
int err = 0;
- const struct firmware *firmware = NULL;
int bytes_remaining;
const u8 *fw;
u8 temp[HELPER_FW_LOAD_CHUNK_SZ];
- struct spi_device *spi = card->spi;
lbs_deb_enter(LBS_DEB_SPI);
err = spu_set_interrupt_mode(card, 1, 0);
if (err)
goto out;
- /* Get helper firmware image */
- err = request_firmware(&firmware, card->helper_fw_name, &spi->dev);
- if (err) {
- lbs_pr_err("request_firmware failed with err = %d\n", err);
- goto out;
- }
+
bytes_remaining = firmware->size;
fw = firmware->data;
@@ -429,13 +438,13 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card)
err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG,
HELPER_FW_LOAD_CHUNK_SZ);
if (err)
- goto release_firmware;
+ goto out;
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)
- goto release_firmware;
+ goto out;
/* Feed the data into the command read/write port reg
* in chunks of 64 bytes */
@@ -446,16 +455,16 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card)
err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
temp, HELPER_FW_LOAD_CHUNK_SZ);
if (err)
- goto release_firmware;
+ goto out;
/* Interrupt the boot code */
err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
if (err)
- goto release_firmware;
+ goto out;
err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
IF_SPI_CIC_CMD_DOWNLOAD_OVER);
if (err)
- goto release_firmware;
+ goto out;
bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ;
fw += HELPER_FW_LOAD_CHUNK_SZ;
}
@@ -465,18 +474,16 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card)
* bootloader. This completes the helper download. */
err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK);
if (err)
- goto release_firmware;
+ goto out;
err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
if (err)
- goto release_firmware;
+ goto out;
err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
IF_SPI_CIC_CMD_DOWNLOAD_OVER);
- goto release_firmware;
+ goto out;
lbs_deb_spi("waiting for helper to boot...\n");
-release_firmware:
- release_firmware(firmware);
out:
if (err)
lbs_pr_err("failed to load helper firmware (err=%d)\n", err);
@@ -523,13 +530,12 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
return len;
}
-static int if_spi_prog_main_firmware(struct if_spi_card *card)
+static int if_spi_prog_main_firmware(struct if_spi_card *card,
+ const struct firmware *firmware)
{
int len, prev_len;
int bytes, crc_err = 0, err = 0;
- const struct firmware *firmware = NULL;
const u8 *fw;
- struct spi_device *spi = card->spi;
u16 num_crc_errs;
lbs_deb_enter(LBS_DEB_SPI);
@@ -538,19 +544,11 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
if (err)
goto out;
- /* Get firmware image */
- err = request_firmware(&firmware, card->main_fw_name, &spi->dev);
- if (err) {
- lbs_pr_err("%s: can't get firmware '%s' from kernel. "
- "err = %d\n", __func__, card->main_fw_name, err);
- goto out;
- }
-
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__);
- goto release_firmware;
+ goto out;
}
num_crc_errs = 0;
@@ -560,7 +558,7 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) {
if (len < 0) {
err = len;
- goto release_firmware;
+ goto out;
}
if (bytes < 0) {
/* If there are no more bytes left, we would normally
@@ -575,7 +573,7 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
lbs_pr_err("Too many CRC errors encountered "
"in firmware load.\n");
err = -EIO;
- goto release_firmware;
+ goto out;
}
} else {
/* Previous transfer succeeded. Advance counters. */
@@ -590,15 +588,15 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
if (err)
- goto release_firmware;
+ goto out;
err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
card->cmd_buffer, len);
if (err)
- goto release_firmware;
+ goto out;
err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG ,
IF_SPI_CIC_CMD_DOWNLOAD_OVER);
if (err)
- goto release_firmware;
+ goto out;
prev_len = len;
}
if (bytes > prev_len) {
@@ -611,12 +609,9 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
SUCCESSFUL_FW_DOWNLOAD_MAGIC);
if (err) {
lbs_pr_err("failed to confirm the firmware download\n");
- goto release_firmware;
+ goto out;
}
-release_firmware:
- release_firmware(firmware);
-
out:
if (err)
lbs_pr_err("failed to load firmware (err=%d)\n", err);
@@ -800,14 +795,16 @@ static int lbs_spi_thread(void *data)
goto err;
}
- if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY)
+ if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) {
err = if_spi_c2h_cmd(card);
if (err)
goto err;
- if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY)
+ }
+ if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) {
err = if_spi_c2h_data(card);
if (err)
goto err;
+ }
/* workaround: in PS mode, the card does not set the Command
* Download Ready bit, but it sets TX Download Ready. */
@@ -886,37 +883,16 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id)
* SPI callbacks
*/
-static int if_spi_calculate_fw_names(u16 card_id,
- char *helper_fw, char *main_fw)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(chip_id_to_device_name); ++i) {
- if (card_id == chip_id_to_device_name[i].chip_id)
- break;
- }
- if (i == ARRAY_SIZE(chip_id_to_device_name)) {
- lbs_pr_err("Unsupported chip_id: 0x%02x\n", card_id);
- return -EAFNOSUPPORT;
- }
- snprintf(helper_fw, IF_SPI_FW_NAME_MAX, "libertas/gspi%d_hlp.bin",
- chip_id_to_device_name[i].name);
- snprintf(main_fw, IF_SPI_FW_NAME_MAX, "libertas/gspi%d.bin",
- chip_id_to_device_name[i].name);
- return 0;
-}
-MODULE_FIRMWARE("libertas/gspi8385_hlp.bin");
-MODULE_FIRMWARE("libertas/gspi8385.bin");
-MODULE_FIRMWARE("libertas/gspi8686_hlp.bin");
-MODULE_FIRMWARE("libertas/gspi8686.bin");
-
static int __devinit if_spi_probe(struct spi_device *spi)
{
struct if_spi_card *card;
struct lbs_private *priv = NULL;
struct libertas_spi_platform_data *pdata = spi->dev.platform_data;
- int err = 0;
+ int err = 0, i;
u32 scratch;
struct sched_param param = { .sched_priority = 1 };
+ const struct firmware *helper = NULL;
+ const struct firmware *mainfw = NULL;
lbs_deb_enter(LBS_DEB_SPI);
@@ -961,10 +937,25 @@ static int __devinit if_spi_probe(struct spi_device *spi)
lbs_deb_spi("Firmware is already loaded for "
"Marvell WLAN 802.11 adapter\n");
else {
- err = if_spi_calculate_fw_names(card->card_id,
- card->helper_fw_name, card->main_fw_name);
- if (err)
+ /* Check if we support this card */
+ for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
+ if (card->card_id == fw_table[i].model)
+ break;
+ }
+ if (i == ARRAY_SIZE(fw_table)) {
+ lbs_pr_err("Unsupported chip_id: 0x%02x\n",
+ card->card_id);
+ err = -ENODEV;
goto free_card;
+ }
+
+ err = lbs_get_firmware(&card->spi->dev, NULL, NULL,
+ card->card_id, &fw_table[0], &helper,
+ &mainfw);
+ if (err) {
+ lbs_pr_err("failed to find firmware (%d)\n", err);
+ goto free_card;
+ }
lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter "
"(chip_id = 0x%04x, chip_rev = 0x%02x) "
@@ -973,10 +964,10 @@ static int __devinit if_spi_probe(struct spi_device *spi)
card->card_id, card->card_rev,
spi->master->bus_num, spi->chip_select,
spi->max_speed_hz);
- err = if_spi_prog_helper_firmware(card);
+ err = if_spi_prog_helper_firmware(card, helper);
if (err)
goto free_card;
- err = if_spi_prog_main_firmware(card);
+ err = if_spi_prog_main_firmware(card, mainfw);
if (err)
goto free_card;
lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n");
@@ -1044,6 +1035,11 @@ remove_card:
free_card:
free_if_spi_card(card);
out:
+ if (helper)
+ release_firmware(helper);
+ if (mainfw)
+ release_firmware(mainfw);
+
lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
return err;
}
diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h
index f87eec410848..8b1417d3b71b 100644
--- a/drivers/net/wireless/libertas/if_spi.h
+++ b/drivers/net/wireless/libertas/if_spi.h
@@ -25,11 +25,6 @@
#define IF_SPI_FW_NAME_MAX 30
-struct chip_ident {
- u16 chip_id;
- u16 name;
-};
-
#define MAX_MAIN_FW_LOAD_CRC_ERR 10
/* Chunk size when loading the helper firmware */
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 3ff61063671a..efaf85032208 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -26,15 +26,25 @@
#define MESSAGE_HEADER_LEN 4
-static char *lbs_fw_name = "usb8388.bin";
+static char *lbs_fw_name = NULL;
module_param_named(fw_name, lbs_fw_name, charp, 0644);
+MODULE_FIRMWARE("libertas/usb8388_v9.bin");
+MODULE_FIRMWARE("libertas/usb8388_v5.bin");
+MODULE_FIRMWARE("libertas/usb8388.bin");
+MODULE_FIRMWARE("libertas/usb8682.bin");
MODULE_FIRMWARE("usb8388.bin");
+enum {
+ MODEL_UNKNOWN = 0x0,
+ MODEL_8388 = 0x1,
+ MODEL_8682 = 0x2
+};
+
static struct usb_device_id if_usb_table[] = {
/* Enter the device signature inside */
- { USB_DEVICE(0x1286, 0x2001) },
- { USB_DEVICE(0x05a3, 0x8388) },
+ { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 },
+ { USB_DEVICE(0x05a3, 0x8388), .driver_info = MODEL_8388 },
{} /* Terminating entry */
};
@@ -66,6 +76,8 @@ static ssize_t if_usb_firmware_set(struct device *dev,
struct if_usb_card *cardp = priv->card;
int ret;
+ BUG_ON(buf == NULL);
+
ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW);
if (ret == 0)
return count;
@@ -91,6 +103,8 @@ static ssize_t if_usb_boot2_set(struct device *dev,
struct if_usb_card *cardp = priv->card;
int ret;
+ BUG_ON(buf == NULL);
+
ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2);
if (ret == 0)
return count;
@@ -244,6 +258,7 @@ static int if_usb_probe(struct usb_interface *intf,
init_waitqueue_head(&cardp->fw_wq);
cardp->udev = udev;
+ cardp->model = (uint32_t) id->driver_info;
iface_desc = intf->cur_altsetting;
lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
@@ -472,11 +487,12 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
*/
static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
{
- int ret = -1;
+ int ret;
/* check if device is removed */
if (cardp->surprise_removed) {
lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
+ ret = -ENODEV;
goto tx_ret;
}
@@ -489,7 +505,6 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb
if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
- ret = -1;
} else {
lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
ret = 0;
@@ -924,6 +939,38 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp,
return ret;
}
+/* table of firmware file names */
+static const struct {
+ u32 model;
+ const char *fwname;
+} fw_table[] = {
+ { MODEL_8388, "libertas/usb8388_v9.bin" },
+ { MODEL_8388, "libertas/usb8388_v5.bin" },
+ { MODEL_8388, "libertas/usb8388.bin" },
+ { MODEL_8388, "usb8388.bin" },
+ { MODEL_8682, "libertas/usb8682.bin" }
+};
+
+static int get_fw(struct if_usb_card *cardp, const char *fwname)
+{
+ int i;
+
+ /* Try user-specified firmware first */
+ if (fwname)
+ return request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
+
+ /* Otherwise search for firmware to use */
+ for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
+ if (fw_table[i].model != cardp->model)
+ continue;
+ if (request_firmware(&cardp->fw, fw_table[i].fwname,
+ &cardp->udev->dev) == 0)
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
static int __if_usb_prog_firmware(struct if_usb_card *cardp,
const char *fwname, int cmd)
{
@@ -933,10 +980,9 @@ static int __if_usb_prog_firmware(struct if_usb_card *cardp,
lbs_deb_enter(LBS_DEB_USB);
- ret = request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
- if (ret < 0) {
- lbs_pr_err("request_firmware() failed with %#x\n", ret);
- lbs_pr_err("firmware %s not found\n", fwname);
+ ret = get_fw(cardp, fwname);
+ if (ret) {
+ lbs_pr_err("failed to find firmware (%d)\n", ret);
goto done;
}
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
index 5ba0aee0eb2f..d819e7e3c9aa 100644
--- a/drivers/net/wireless/libertas/if_usb.h
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -43,6 +43,7 @@ struct bootcmdresp
/** USB card description structure*/
struct if_usb_card {
struct usb_device *udev;
+ uint32_t model; /* MODEL_* */
struct urb *rx_urb, *tx_urb;
struct lbs_private *priv;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 24958a86747b..47ce5a6ba120 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1047,6 +1047,111 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
}
EXPORT_SYMBOL_GPL(lbs_notify_command_response);
+/**
+ * @brief 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
+ *
+ * @return 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,
+ const struct lbs_fw_table *fw_table,
+ const struct firmware **helper,
+ const struct firmware **mainfw)
+{
+ const struct lbs_fw_table *iter;
+ int ret;
+
+ BUG_ON(helper == NULL);
+ BUG_ON(mainfw == NULL);
+
+ /* Try user-specified firmware first */
+ if (user_helper) {
+ ret = request_firmware(helper, user_helper, dev);
+ if (ret) {
+ lbs_pr_err("couldn't find helper firmware %s",
+ 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);
+ goto fail;
+ }
+ }
+
+ if (*helper && *mainfw)
+ return 0;
+
+ /* Otherwise search for firmware to use. If neither the helper or
+ * the main firmware were specified by the user, then we need to
+ * make sure that found helper & main are from the same entry in
+ * fw_table.
+ */
+ iter = fw_table;
+ while (iter && iter->helper) {
+ if (iter->model != card_model)
+ goto next;
+
+ if (*helper == NULL) {
+ ret = request_firmware(helper, iter->helper, dev);
+ if (ret)
+ goto next;
+
+ /* If the device has one-stage firmware (ie cf8305) and
+ * we've got it then we don't need to bother with the
+ * main firmware.
+ */
+ if (iter->fwname == NULL)
+ return 0;
+ }
+
+ if (*mainfw == NULL) {
+ ret = request_firmware(mainfw, iter->fwname, dev);
+ if (ret && !user_helper) {
+ /* Clear the helper if it wasn't user-specified
+ * and the main firmware load failed, to ensure
+ * we don't have mismatched firmware pairs.
+ */
+ release_firmware(*helper);
+ *helper = NULL;
+ }
+ }
+
+ if (*helper && *mainfw)
+ return 0;
+
+ next:
+ iter++;
+ }
+
+ fail:
+ /* Failed */
+ if (*helper) {
+ release_firmware(*helper);
+ *helper = NULL;
+ }
+ if (*mainfw) {
+ release_firmware(*mainfw);
+ *mainfw = NULL;
+ }
+
+ return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(lbs_get_firmware);
+
static int __init lbs_init_module(void)
{
lbs_deb_enter(LBS_DEB_MAIN);
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index 194762ab0142..acf3bf63ee33 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -574,7 +574,7 @@ int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted)
memset(&cmd, 0, sizeof(cmd));
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT);
- cmd.id = !!inverted;
+ cmd.id = cpu_to_le32(!!inverted);
ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index 41a4f214ade1..ba7d96584cb6 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -54,7 +54,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp);
/**
* if_usb_wrike_bulk_callback - call back to handle URB status
*
- * @param urb pointer to urb structure
+ * @param urb pointer to urb structure
*/
static void if_usb_write_bulk_callback(struct urb *urb)
{
@@ -178,16 +178,19 @@ static int if_usb_probe(struct usb_interface *intf,
le16_to_cpu(endpoint->wMaxPacketSize);
cardp->ep_in = usb_endpoint_num(endpoint);
- lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in);
- lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size);
+ lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n",
+ cardp->ep_in);
+ lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n",
+ cardp->ep_in_size);
} else if (usb_endpoint_is_bulk_out(endpoint)) {
cardp->ep_out_size =
le16_to_cpu(endpoint->wMaxPacketSize);
cardp->ep_out = usb_endpoint_num(endpoint);
- lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out);
+ lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n",
+ cardp->ep_out);
lbtf_deb_usbd(&udev->dev, "Bulk out size is %d\n",
- cardp->ep_out_size);
+ cardp->ep_out_size);
}
}
if (!cardp->ep_out_size || !cardp->ep_in_size) {
@@ -318,10 +321,12 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
lbtf_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
- lbtf_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
- cardp->fwseqnum, cardp->totalbytes);
+ lbtf_deb_usb2(&cardp->udev->dev,
+ "seqnum = %d totalbytes = %d\n",
+ cardp->fwseqnum, cardp->totalbytes);
} else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
- lbtf_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
+ lbtf_deb_usb2(&cardp->udev->dev,
+ "Host has finished FW downloading\n");
lbtf_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");
/* Host has finished FW downloading
@@ -367,7 +372,7 @@ EXPORT_SYMBOL_GPL(if_usb_reset_device);
/**
* usb_tx_block - transfer data to the device
*
- * @priv pointer to struct lbtf_private
+ * @priv pointer to struct lbtf_private
* @payload pointer to payload data
* @nb data length
* @data non-zero for data, zero for commands
@@ -400,7 +405,8 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
urb->transfer_flags |= URB_ZERO_PACKET;
if (usb_submit_urb(urb, GFP_ATOMIC)) {
- lbtf_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
+ lbtf_deb_usbd(&cardp->udev->dev,
+ "usb_submit_urb failed: %d\n", ret);
goto tx_ret;
}
@@ -438,10 +444,12 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
- lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
+ lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n",
+ cardp->rx_urb);
ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC);
if (ret) {
- lbtf_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
+ lbtf_deb_usbd(&cardp->udev->dev,
+ "Submit Rx URB failed: %d\n", ret);
kfree_skb(skb);
cardp->rx_skb = NULL;
lbtf_deb_leave(LBTF_DEB_USB);
@@ -522,14 +530,14 @@ static void if_usb_receive_fwload(struct urb *urb)
}
} else if (bcmdresp.cmd != BOOT_CMD_FW_BY_USB) {
pr_info("boot cmd response cmd_tag error (%d)\n",
- bcmdresp.cmd);
+ bcmdresp.cmd);
} else if (bcmdresp.result != BOOT_CMD_RESP_OK) {
pr_info("boot cmd response result error (%d)\n",
- bcmdresp.result);
+ bcmdresp.result);
} else {
cardp->bootcmdresp = 1;
lbtf_deb_usbd(&cardp->udev->dev,
- "Received valid boot command response\n");
+ "Received valid boot command response\n");
}
kfree_skb(skb);
@@ -541,19 +549,23 @@ static void if_usb_receive_fwload(struct urb *urb)
syncfwheader = kmemdup(skb->data, sizeof(struct fwsyncheader),
GFP_ATOMIC);
if (!syncfwheader) {
- lbtf_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
+ lbtf_deb_usbd(&cardp->udev->dev,
+ "Failure to allocate syncfwheader\n");
kfree_skb(skb);
lbtf_deb_leave(LBTF_DEB_USB);
return;
}
if (!syncfwheader->cmd) {
- lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
- lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
- le32_to_cpu(syncfwheader->seqnum));
+ lbtf_deb_usb2(&cardp->udev->dev,
+ "FW received Blk with correct CRC\n");
+ lbtf_deb_usb2(&cardp->udev->dev,
+ "FW received Blk seqnum = %d\n",
+ le32_to_cpu(syncfwheader->seqnum));
cardp->CRC_OK = 1;
} else {
- lbtf_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n");
+ lbtf_deb_usbd(&cardp->udev->dev,
+ "FW received Blk with CRC error\n");
cardp->CRC_OK = 0;
}
@@ -666,7 +678,8 @@ static void if_usb_receive(struct urb *urb)
{
/* Event cause handling */
u32 event_cause = le32_to_cpu(pkt[1]);
- lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", event_cause);
+ lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n",
+ event_cause);
/* Icky undocumented magic special case */
if (event_cause & 0xffff0000) {
@@ -689,7 +702,7 @@ static void if_usb_receive(struct urb *urb)
}
default:
lbtf_deb_usbd(&cardp->udev->dev,
- "libertastf: unknown command type 0x%X\n", recvtype);
+ "libertastf: unknown command type 0x%X\n", recvtype);
kfree_skb(skb);
break;
}
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 86fa8abdd66f..7eaaa3bab547 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -9,7 +9,8 @@
/*
* TODO:
- * - IBSS mode simulation (Beacon transmission with competition for "air time")
+ * - Add TSF sync and fix IBSS beacon transmission by adding
+ * competition for "air time" at TBTT
* - RX filtering based on filter configuration (data->rx_filter)
*/
@@ -594,17 +595,34 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
- __func__, vif->type, vif->addr);
+ __func__, ieee80211_vif_type_p2p(vif),
+ vif->addr);
hwsim_set_magic(vif);
return 0;
}
+static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum nl80211_iftype newtype,
+ bool newp2p)
+{
+ newtype = ieee80211_iftype_p2p(newtype, newp2p);
+ wiphy_debug(hw->wiphy,
+ "%s (old type=%d, new type=%d, mac_addr=%pM)\n",
+ __func__, ieee80211_vif_type_p2p(vif),
+ newtype, vif->addr);
+ hwsim_check_magic(vif);
+
+ return 0;
+}
+
static void mac80211_hwsim_remove_interface(
struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
- __func__, vif->type, vif->addr);
+ __func__, ieee80211_vif_type_p2p(vif),
+ vif->addr);
hwsim_check_magic(vif);
hwsim_clear_magic(vif);
}
@@ -620,7 +638,8 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
hwsim_check_magic(vif);
if (vif->type != NL80211_IFTYPE_AP &&
- vif->type != NL80211_IFTYPE_MESH_POINT)
+ vif->type != NL80211_IFTYPE_MESH_POINT &&
+ vif->type != NL80211_IFTYPE_ADHOC)
return;
skb = ieee80211_beacon_get(hw, vif);
@@ -1025,6 +1044,7 @@ static struct ieee80211_ops mac80211_hwsim_ops =
.start = mac80211_hwsim_start,
.stop = mac80211_hwsim_stop,
.add_interface = mac80211_hwsim_add_interface,
+ .change_interface = mac80211_hwsim_change_interface,
.remove_interface = mac80211_hwsim_remove_interface,
.config = mac80211_hwsim_config,
.configure_filter = mac80211_hwsim_configure_filter,
@@ -1295,6 +1315,9 @@ static int __init init_mac80211_hwsim(void)
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO) |
+ BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
hw->flags = IEEE80211_HW_MFP_CAPABLE |
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 077baa86756b..b4772c1c6135 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -762,14 +762,17 @@ int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate)
case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
for (i = 0; i < BITRATE_TABLE_SIZE; i++)
- if (bitrate_table[i].intersil_txratectrl == val)
+ if (bitrate_table[i].intersil_txratectrl == val) {
+ *bitrate = bitrate_table[i].bitrate * 100000;
break;
+ }
- if (i >= BITRATE_TABLE_SIZE)
+ if (i >= BITRATE_TABLE_SIZE) {
printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
priv->ndev->name, val);
+ err = -EIO;
+ }
- *bitrate = bitrate_table[i].bitrate * 100000;
break;
default:
BUG();
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index cf7be1eb6124..93505f93bf97 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -589,8 +589,15 @@ static int orinoco_ioctl_getrate(struct net_device *dev,
/* If the interface is running we try to find more about the
current mode */
- if (netif_running(dev))
- err = orinoco_hw_get_act_bitrate(priv, &bitrate);
+ if (netif_running(dev)) {
+ int act_bitrate;
+ int lerr;
+
+ /* Ignore errors if we can't get the actual bitrate */
+ lerr = orinoco_hw_get_act_bitrate(priv, &act_bitrate);
+ if (!lerr)
+ bitrate = act_bitrate;
+ }
orinoco_unlock(priv, &flags);
diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig
index b0342a520bf1..e5f45cb2a7a2 100644
--- a/drivers/net/wireless/p54/Kconfig
+++ b/drivers/net/wireless/p54/Kconfig
@@ -2,6 +2,7 @@ config P54_COMMON
tristate "Softmac Prism54 support"
depends on MAC80211 && EXPERIMENTAL
select FW_LOADER
+ select CRC_CCITT
---help---
This is common code for isl38xx/stlc45xx based modules.
This module does nothing by itself - the USB/PCI/SPI front-ends
@@ -48,6 +49,23 @@ config P54_SPI
If you choose to build a module, it'll be called p54spi.
+config P54_SPI_DEFAULT_EEPROM
+ bool "Include fallback EEPROM blob"
+ depends on P54_SPI
+ default n
+ ---help---
+ Unlike the PCI or USB devices, the SPI variants don't have
+ a dedicated EEPROM chip to store all device specific values
+ for calibration, country and interface settings.
+
+ The driver will try to load the image "3826.eeprom", if the
+ file is put at the right place. (usually /lib/firmware.)
+
+ Only if this request fails, this option will provide a
+ backup set of generic values to get the device working.
+
+ Enabling this option adds about 4k to p54spi.
+
config P54_LEDS
bool
depends on P54_COMMON && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = P54_COMMON)
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 78347041ec40..35b09aa0529b 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -23,6 +23,7 @@
#include <linux/slab.h>
#include <net/mac80211.h>
+#include <linux/crc-ccitt.h>
#include "p54.h"
#include "eeprom.h"
@@ -260,8 +261,10 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
list->max_entries = max_channel_num;
list->channels = kzalloc(sizeof(struct p54_channel_entry) *
max_channel_num, GFP_KERNEL);
- if (!list->channels)
+ if (!list->channels) {
+ ret = -ENOMEM;
goto free;
+ }
for (i = 0; i < max_channel_num; i++) {
if (i < priv->iq_autocal_len) {
@@ -540,6 +543,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
int err;
u8 *end = (u8 *)eeprom + len;
u16 synth = 0;
+ u16 crc16 = ~0;
wrap = (struct eeprom_pda_wrap *) eeprom;
entry = (void *)wrap->data + le16_to_cpu(wrap->len);
@@ -655,16 +659,29 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
}
break;
case PDR_END:
- /* make it overrun */
- entry_len = len;
+ crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry));
+ if (crc16 != le16_to_cpup((__le16 *)entry->data)) {
+ wiphy_err(dev->wiphy, "eeprom failed checksum "
+ "test!\n");
+ err = -ENOMSG;
+ goto err;
+ } else {
+ goto good_eeprom;
+ }
break;
default:
break;
}
- entry = (void *)entry + (entry_len + 1)*2;
+ crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2);
+ entry = (void *)entry + (entry_len + 1) * 2;
}
+ wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n");
+ err = -ENODATA;
+ goto err;
+
+good_eeprom:
if (!synth || !priv->iq_autocal || !priv->output_limit ||
!priv->curve_data) {
wiphy_err(dev->wiphy,
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index 15b20c29a604..92b9b1f05fd5 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -123,10 +123,14 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
bootrec = (struct bootrec *)&bootrec->data[len];
}
- if (fw_version)
+ if (fw_version) {
wiphy_info(priv->hw->wiphy,
"FW rev %s - Softmac protocol %x.%x\n",
fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
+ snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version),
+ "%s - %x.%x", fw_version,
+ priv->fw_var >> 8, priv->fw_var & 0xff);
+ }
if (priv->fw_var < 0x500)
wiphy_info(priv->hw->wiphy,
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 47db439b63bf..622d27b6d8f2 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -429,8 +429,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
mutex_lock(&priv->conf_mutex);
if (cmd == SET_KEY) {
- switch (key->alg) {
- case ALG_TKIP:
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL |
BR_DESC_PRIV_CAP_TKIP))) {
ret = -EOPNOTSUPP;
@@ -439,7 +439,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
algo = P54_CRYPTO_TKIPMICHAEL;
break;
- case ALG_WEP:
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) {
ret = -EOPNOTSUPP;
goto out_unlock;
@@ -447,7 +448,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
algo = P54_CRYPTO_WEP;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) {
ret = -EOPNOTSUPP;
goto out_unlock;
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index 087bf0698a5a..18d24b7b1e34 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -32,11 +32,14 @@
#include <linux/slab.h>
#include "p54spi.h"
-#include "p54spi_eeprom.h"
#include "p54.h"
#include "lmac.h"
+#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM
+#include "p54spi_eeprom.h"
+#endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */
+
MODULE_FIRMWARE("3826.arm");
MODULE_ALIAS("stlc45xx");
@@ -195,9 +198,13 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev)
ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev);
if (ret < 0) {
+#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM
dev_info(&priv->spi->dev, "loading default eeprom...\n");
ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom,
sizeof(p54spi_eeprom));
+#else
+ dev_err(&priv->spi->dev, "Failed to request user eeprom\n");
+#endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */
} else {
dev_info(&priv->spi->dev, "loading user eeprom...\n");
ret = p54_parse_eeprom(dev, (void *) eeprom->data,
diff --git a/drivers/net/wireless/p54/p54spi_eeprom.h b/drivers/net/wireless/p54/p54spi_eeprom.h
index 1ea1050911d9..d592cbd34d78 100644
--- a/drivers/net/wireless/p54/p54spi_eeprom.h
+++ b/drivers/net/wireless/p54/p54spi_eeprom.h
@@ -671,7 +671,7 @@ static unsigned char p54spi_eeprom[] = {
0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
0x02, 0x00, 0x00, 0x00, /* PDR_END */
- 0xa8, 0xf5 /* bogus data */
+ 0x67, 0x99,
};
#endif /* P54SPI_EEPROM_H */
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index ad595958b7df..d5bc21e5a02c 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -33,8 +33,17 @@ MODULE_ALIAS("prism54usb");
MODULE_FIRMWARE("isl3886usb");
MODULE_FIRMWARE("isl3887usb");
+/*
+ * Note:
+ *
+ * Always update our wiki's device list (located at:
+ * http://wireless.kernel.org/en/users/Drivers/p54/devices ),
+ * whenever you add a new device.
+ */
+
static struct usb_device_id p54u_table[] __devinitdata = {
/* Version 1 devices (pci chip + net2280) */
+ {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */
{USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
{USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
{USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
@@ -47,7 +56,9 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
{USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
{USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
+ {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */
{USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
+ {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */
{USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
{USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
{USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
@@ -60,6 +71,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
{USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
{USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
+ {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */
{USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
{USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
{USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
@@ -80,6 +92,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
{USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */
{USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
+ {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */
{USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
{USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */
{USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
@@ -930,8 +943,8 @@ static int __devinit p54u_probe(struct usb_interface *intf,
#ifdef CONFIG_PM
/* ISL3887 needs a full reset on resume */
udev->reset_resume = 1;
+#endif /* CONFIG_PM */
err = p54u_device_reset(dev);
-#endif
priv->hw_type = P54U_3887;
dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 0e937dc0c9c4..76b2318a7dc7 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -275,15 +275,15 @@ static int p54_rssi_to_dbm(struct p54_common *priv, int rssi)
{
int band = priv->hw->conf.channel->band;
- if (priv->rxhw != 5)
+ if (priv->rxhw != 5) {
return ((rssi * priv->rssical_db[band].mul) / 64 +
priv->rssical_db[band].add) / 4;
- else
+ } else {
/*
* TODO: find the correct formula
*/
- return ((rssi * priv->rssical_db[band].mul) / 64 +
- priv->rssical_db[band].add) / 4;
+ return rssi / 2 - 110;
+ }
}
/*
@@ -683,14 +683,15 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
}
}
-static u8 p54_convert_algo(enum ieee80211_key_alg alg)
+static u8 p54_convert_algo(u32 cipher)
{
- switch (alg) {
- case ALG_WEP:
+ switch (cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
return P54_CRYPTO_WEP;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
return P54_CRYPTO_TKIPMICHAEL;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
return P54_CRYPTO_AESCCMP;
default:
return 0;
@@ -731,7 +732,7 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb)
if (info->control.hw_key) {
crypt_offset = ieee80211_get_hdrlen_from_skb(skb);
- if (info->control.hw_key->alg == ALG_TKIP) {
+ if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
u8 *iv = (u8 *)(skb->data + crypt_offset);
/*
* The firmware excepts that the IV has to have
@@ -827,10 +828,10 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb)
hdr->tries = ridx;
txhdr->rts_rate_idx = 0;
if (info->control.hw_key) {
- txhdr->key_type = p54_convert_algo(info->control.hw_key->alg);
+ txhdr->key_type = p54_convert_algo(info->control.hw_key->cipher);
txhdr->key_len = min((u8)16, info->control.hw_key->keylen);
memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len);
- if (info->control.hw_key->alg == ALG_TKIP) {
+ if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
/* reserve space for the MIC key */
len += 8;
memcpy(skb_put(skb, 8), &(info->control.hw_key->key
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 77cd65db8500..d97a2caf582b 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -3234,7 +3234,7 @@ prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
switch (cmd) {
case PRISM54_HOSTAPD:
if (!capable(CAP_NET_ADMIN))
- return -EPERM;
+ return -EPERM;
ret = prism54_hostapd(ndev, &wrq->u.data);
return ret;
}
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 46da03753fd5..97007d9e2c1f 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -43,7 +43,6 @@
#include <linux/if_arp.h>
#include <linux/ioport.h>
#include <linux/skbuff.h>
-#include <linux/ethtool.h>
#include <linux/ieee80211.h>
#include <pcmcia/cistpl.h>
@@ -79,8 +78,6 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map);
static struct net_device_stats *ray_get_stats(struct net_device *dev);
static int ray_dev_init(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
-
static int ray_open(struct net_device *dev);
static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
struct net_device *dev);
@@ -189,7 +186,7 @@ module_param(bc, int, 0);
module_param(phy_addr, charp, 0);
module_param(ray_mem_speed, int, 0);
-static UCHAR b5_default_startup_parms[] = {
+static const UCHAR b5_default_startup_parms[] = {
0, 0, /* Adhoc station */
'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */
0, 0, 0, 0, 0, 0, 0, 0,
@@ -224,7 +221,7 @@ static UCHAR b5_default_startup_parms[] = {
2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */
};
-static UCHAR b4_default_startup_parms[] = {
+static const UCHAR b4_default_startup_parms[] = {
0, 0, /* Adhoc station */
'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */
0, 0, 0, 0, 0, 0, 0, 0,
@@ -256,9 +253,9 @@ static UCHAR b4_default_startup_parms[] = {
};
/*===========================================================================*/
-static unsigned char eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 };
+static const u8 eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 };
-static char hop_pattern_length[] = { 1,
+static const char hop_pattern_length[] = { 1,
USA_HOP_MOD, EUROPE_HOP_MOD,
JAPAN_HOP_MOD, KOREA_HOP_MOD,
SPAIN_HOP_MOD, FRANCE_HOP_MOD,
@@ -266,7 +263,7 @@ static char hop_pattern_length[] = { 1,
JAPAN_TEST_HOP_MOD
};
-static char rcsid[] =
+static const char rcsid[] =
"Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
static const struct net_device_ops ray_netdev_ops = {
@@ -316,7 +313,6 @@ static int ray_probe(struct pcmcia_device *p_dev)
/* Raylink entries in the device structure */
dev->netdev_ops = &ray_netdev_ops;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
dev->wireless_handlers = &ray_handler_def;
#ifdef WIRELESS_SPY
local->wireless_data.spy_data = &local->spy_data;
@@ -575,7 +571,7 @@ static int dl_startup_params(struct net_device *dev)
/* Start kernel timer to wait for dl startup to complete. */
local->timer.expires = jiffies + HZ / 2;
local->timer.data = (long)local;
- local->timer.function = &verify_dl_startup;
+ local->timer.function = verify_dl_startup;
add_timer(&local->timer);
dev_dbg(&link->dev,
"ray_cs dl_startup_params started timer for verify_dl_startup\n");
@@ -1025,18 +1021,6 @@ AP to AP 1 1 dest AP src AP dest source
}
} /* end encapsulate_frame */
-/*===========================================================================*/
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "ray_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
/*====================================================================*/
/*------------------------------------------------------------------*/
@@ -1960,12 +1944,12 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
dev_dbg(&link->dev,
"ray_cs interrupt network \"%s\" start failed\n",
local->sparm.b4.a_current_ess_id);
- local->timer.function = &start_net;
+ local->timer.function = start_net;
} else {
dev_dbg(&link->dev,
"ray_cs interrupt network \"%s\" join failed\n",
local->sparm.b4.a_current_ess_id);
- local->timer.function = &join_net;
+ local->timer.function = join_net;
}
add_timer(&local->timer);
}
@@ -2433,9 +2417,9 @@ static void authenticate(ray_dev_t *local)
del_timer(&local->timer);
if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
- local->timer.function = &join_net;
+ local->timer.function = join_net;
} else {
- local->timer.function = &authenticate_timeout;
+ local->timer.function = authenticate_timeout;
}
local->timer.expires = jiffies + HZ * 2;
local->timer.data = (long)local;
@@ -2520,7 +2504,7 @@ static void associate(ray_dev_t *local)
del_timer(&local->timer);
local->timer.expires = jiffies + HZ * 2;
local->timer.data = (long)local;
- local->timer.function = &join_net;
+ local->timer.function = join_net;
add_timer(&local->timer);
local->card_status = CARD_ASSOC_FAILED;
return;
@@ -2554,7 +2538,7 @@ static void clear_interrupt(ray_dev_t *local)
#ifdef CONFIG_PROC_FS
#define MAXDATA (PAGE_SIZE - 80)
-static char *card_status[] = {
+static const char *card_status[] = {
"Card inserted - uninitialized", /* 0 */
"Card not downloaded", /* 1 */
"Waiting for download parameters", /* 2 */
@@ -2571,8 +2555,8 @@ static char *card_status[] = {
"Association failed" /* 16 */
};
-static char *nettype[] = { "Adhoc", "Infra " };
-static char *framing[] = { "Encapsulation", "Translation" }
+static const char *nettype[] = { "Adhoc", "Infra " };
+static const char *framing[] = { "Encapsulation", "Translation" }
;
/*===========================================================================*/
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 719573bbbf81..71b5971da597 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -540,11 +540,11 @@ static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);
static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, const u8 *mac_addr,
- struct key_params *params);
+ u8 key_index, bool pairwise, const u8 *mac_addr,
+ struct key_params *params);
static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, const u8 *mac_addr);
+ u8 key_index, bool pairwise, const u8 *mac_addr);
static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index);
@@ -2308,8 +2308,8 @@ static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev,
}
static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, const u8 *mac_addr,
- struct key_params *params)
+ u8 key_index, bool pairwise, const u8 *mac_addr,
+ struct key_params *params)
{
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
struct usbnet *usbdev = priv->usbdev;
@@ -2344,7 +2344,7 @@ static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
}
static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, const u8 *mac_addr)
+ u8 key_index, bool pairwise, const u8 *mac_addr)
{
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
struct usbnet *usbdev = priv->usbdev;
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 5063e01410e5..4f420a9ec5dc 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -321,7 +321,8 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
}
static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp)
+ struct rt2x00lib_erp *erp,
+ u32 changed)
{
int preamble_mask;
u32 reg;
@@ -329,59 +330,72 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
/*
* When short preamble is enabled, we should set bit 0x08
*/
- preamble_mask = erp->short_preamble << 3;
-
- rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
- rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x1ff);
- rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0x13a);
- rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
- rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
- rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
- rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
- rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
- rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
- rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
- rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
- rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
- rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110));
- rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
-
- rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ preamble_mask = erp->short_preamble << 3;
+
+ rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x1ff);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0x13a);
+ rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
+ rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
+ rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
+ rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 10));
+ rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
+ rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 20));
+ rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
+ rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 55));
+ rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
+ rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 110));
+ rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
+ }
- rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
- rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
- rt2x00pci_register_write(rt2x00dev, CSR11, reg);
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
- rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
- rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL, erp->beacon_int * 16);
- rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16);
- rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
+ rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
+ rt2x00pci_register_write(rt2x00dev, CSR11, reg);
- rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
- rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
- rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
- rt2x00pci_register_write(rt2x00dev, CSR18, reg);
+ rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
+ rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
+ rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
+ rt2x00pci_register_write(rt2x00dev, CSR18, reg);
+
+ rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
+ rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
+ rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
+ rt2x00pci_register_write(rt2x00dev, CSR19, reg);
+ }
- rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
- rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
- rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
- rt2x00pci_register_write(rt2x00dev, CSR19, reg);
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
+ rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
+ erp->beacon_int * 16);
+ rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+ }
}
static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev,
@@ -1007,12 +1021,11 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt2400pci_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
__le32 *txd = entry_priv->desc;
u32 word;
@@ -1091,12 +1104,12 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
- rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+ rt2x00queue_map_txskb(entry);
/*
* Write the TX descriptor for the beacon.
*/
- rt2400pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ rt2400pci_write_tx_desc(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -1112,24 +1125,24 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
-static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue)
+static void rt2400pci_kick_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
- rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
- rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue == QID_ATIM));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
-static void rt2400pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt2400pci_kill_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
- if (qid == QID_BEACON) {
+ if (queue->qid == QID_BEACON) {
rt2x00pci_register_write(rt2x00dev, CSR14, 0);
} else {
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
@@ -1481,15 +1494,17 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
- for (i = 0; i < 14; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 0; i < 14; i++) {
+ info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER);
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
return 0;
}
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index c2a555d5376b..97feb7aef809 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -327,7 +327,8 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
}
static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp)
+ struct rt2x00lib_erp *erp,
+ u32 changed)
{
int preamble_mask;
u32 reg;
@@ -335,59 +336,73 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
/*
* When short preamble is enabled, we should set bit 0x08
*/
- preamble_mask = erp->short_preamble << 3;
-
- rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
- rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x162);
- rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0xa2);
- rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
- rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
- rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
- rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
- rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
- rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
- rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
- rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
- rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
- rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110));
- rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
-
- rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ preamble_mask = erp->short_preamble << 3;
+
+ rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x162);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0xa2);
+ rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
+ rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
+ rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
+ rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 10));
+ rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
+ rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 20));
+ rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
+ rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 55));
+ rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
+ rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 110));
+ rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
+ }
- rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
- rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
- rt2x00pci_register_write(rt2x00dev, CSR11, reg);
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
- rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
- rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL, erp->beacon_int * 16);
- rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16);
- rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
+ rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
+ rt2x00pci_register_write(rt2x00dev, CSR11, reg);
- rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
- rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
- rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
- rt2x00pci_register_write(rt2x00dev, CSR18, reg);
+ rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
+ rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
+ rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
+ rt2x00pci_register_write(rt2x00dev, CSR18, reg);
+
+ rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
+ rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
+ rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
+ rt2x00pci_register_write(rt2x00dev, CSR19, reg);
+ }
+
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
+ rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
+ erp->beacon_int * 16);
+ rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+ }
- rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
- rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
- rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
- rt2x00pci_register_write(rt2x00dev, CSR19, reg);
}
static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev,
@@ -1161,12 +1176,11 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt2500pci_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
__le32 *txd = entry_priv->desc;
u32 word;
@@ -1244,12 +1258,12 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
- rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+ rt2x00queue_map_txskb(entry);
/*
* Write the TX descriptor for the beacon.
*/
- rt2500pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ rt2500pci_write_tx_desc(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -1265,24 +1279,24 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
-static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue)
+static void rt2500pci_kick_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
- rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
- rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue == QID_ATIM));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
-static void rt2500pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt2500pci_kill_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
- if (qid == QID_BEACON) {
+ if (queue->qid == QID_BEACON) {
rt2x00pci_register_write(rt2x00dev, CSR14, 0);
} else {
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
@@ -1795,19 +1809,23 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
- for (i = 0; i < 14; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 0; i < 14; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
if (spec->num_channels > 14) {
- for (i = 14; i < spec->num_channels; i++)
- info[i].tx_power1 = DEFAULT_TXPOWER;
+ for (i = 14; i < spec->num_channels; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = DEFAULT_TXPOWER;
+ }
}
return 0;
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index cdaf93f48263..93e44c7f3a74 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -355,7 +355,9 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
* it is known that not work at least on some hardware.
* SW crypto will be used in that case.
*/
- if (key->alg == ALG_WEP && key->keyidx != 0)
+ if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
+ key->keyidx != 0)
return -EOPNOTSUPP;
/*
@@ -492,24 +494,34 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
}
static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp)
+ struct rt2x00lib_erp *erp,
+ u32 changed)
{
u16 reg;
- rt2500usb_register_read(rt2x00dev, TXRX_CSR10, &reg);
- rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE,
- !!erp->short_preamble);
- rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR10, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE,
+ !!erp->short_preamble);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg);
+ }
- rt2500usb_register_write(rt2x00dev, TXRX_CSR11, erp->basic_rates);
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR11,
+ erp->basic_rates);
- rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg);
- rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL, erp->beacon_int * 4);
- rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL,
+ erp->beacon_int * 4);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
+ }
- rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time);
- rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs);
- rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time);
+ rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs);
+ rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs);
+ }
}
static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev,
@@ -1039,12 +1051,11 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt2500usb_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txd = (__le32 *) skb->data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ __le32 *txd = (__le32 *) entry->skb->data;
u32 word;
/*
@@ -1127,7 +1138,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
/*
* Write the TX descriptor for the beacon.
*/
- rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ rt2500usb_write_tx_desc(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -1195,6 +1206,14 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
return length;
}
+static void rt2500usb_kill_tx_queue(struct data_queue *queue)
+{
+ if (queue->qid == QID_BEACON)
+ rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0);
+
+ rt2x00usb_kill_tx_queue(queue);
+}
+
/*
* RX control handlers
*/
@@ -1655,10 +1674,15 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all hw fields.
+ *
+ * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are
+ * capable of sending the buffered frames out after the DTIM
+ * transmission using rt2x00lib_beacondone. This will send out
+ * multicast and broadcast traffic immediately instead of buffering it
+ * infinitly and thus dropping it after some time.
*/
rt2x00dev->hw->flags =
IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK;
@@ -1698,19 +1722,23 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
- for (i = 0; i < 14; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 0; i < 14; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
if (spec->num_channels > 14) {
- for (i = 14; i < spec->num_channels; i++)
- info[i].tx_power1 = DEFAULT_TXPOWER;
+ for (i = 14; i < spec->num_channels; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = DEFAULT_TXPOWER;
+ }
}
return 0;
@@ -1789,7 +1817,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.write_beacon = rt2500usb_write_beacon,
.get_tx_data_len = rt2500usb_get_tx_data_len,
.kick_tx_queue = rt2x00usb_kick_tx_queue,
- .kill_tx_queue = rt2x00usb_kill_tx_queue,
+ .kill_tx_queue = rt2500usb_kill_tx_queue,
.fill_rxdone = rt2500usb_fill_rxdone,
.config_shared_key = rt2500usb_config_key,
.config_pairwise_key = rt2500usb_config_key,
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index ed4ebcdde7c9..eb8b6cab9925 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
@@ -639,6 +640,18 @@
#define LED_CFG_LED_POLAR FIELD32(0x40000000)
/*
+ * AMPDU_BA_WINSIZE: Force BlockAck window size
+ * FORCE_WINSIZE_ENABLE:
+ * 0: Disable forcing of BlockAck window size
+ * 1: Enable forcing of BlockAck window size, overwrites values BlockAck
+ * window size values in the TXWI
+ * FORCE_WINSIZE: BlockAck window size
+ */
+#define AMPDU_BA_WINSIZE 0x1040
+#define AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE FIELD32(0x00000020)
+#define AMPDU_BA_WINSIZE_FORCE_WINSIZE FIELD32(0x0000001f)
+
+/*
* XIFS_TIME_CFG: MAC timing
* CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX
* OFDM_SIFS_TIME: unit 1us. Applied after OFDM RX/TX
@@ -698,8 +711,14 @@
/*
* TBTT_SYNC_CFG:
+ * BCN_AIFSN: Beacon AIFSN after TBTT interrupt in slots
+ * BCN_CWMIN: Beacon CWMin after TBTT interrupt in slots
*/
#define TBTT_SYNC_CFG 0x1118
+#define TBTT_SYNC_CFG_TBTT_ADJUST FIELD32(0x000000ff)
+#define TBTT_SYNC_CFG_BCN_EXP_WIN FIELD32(0x0000ff00)
+#define TBTT_SYNC_CFG_BCN_AIFSN FIELD32(0x000f0000)
+#define TBTT_SYNC_CFG_BCN_CWMIN FIELD32(0x00f00000)
/*
* TSF_TIMER_DW0: Local lsb TSF timer, read-only
@@ -735,16 +754,21 @@
#define INT_TIMER_EN_GP_TIMER FIELD32(0x00000002)
/*
- * CH_IDLE_STA: channel idle time
+ * CH_IDLE_STA: channel idle time (in us)
*/
#define CH_IDLE_STA 0x1130
/*
- * CH_BUSY_STA: channel busy time
+ * CH_BUSY_STA: channel busy time on primary channel (in us)
*/
#define CH_BUSY_STA 0x1134
/*
+ * CH_BUSY_STA_SEC: channel busy time on secondary channel in HT40 mode (in us)
+ */
+#define CH_BUSY_STA_SEC 0x1138
+
+/*
* MAC_STATUS_CFG:
* BBP_RF_BUSY: When set to 0, BBP and RF are stable.
* if 1 or higher one of the 2 registers is busy.
@@ -1318,11 +1342,34 @@
#define TX_STA_CNT2_TX_UNDER_FLOW_COUNT FIELD32(0xffff0000)
/*
- * TX_STA_FIFO: TX Result for specific PID status fifo register
+ * TX_STA_FIFO: TX Result for specific PID status fifo register.
+ *
+ * This register is implemented as FIFO with 16 entries in the HW. Each
+ * register read fetches the next tx result. If the FIFO is full because
+ * it wasn't read fast enough after the according interrupt (TX_FIFO_STATUS)
+ * triggered, the hw seems to simply drop further tx results.
+ *
+ * VALID: 1: this tx result is valid
+ * 0: no valid tx result -> driver should stop reading
+ * PID_TYPE: The PID latched from the PID field in the TXWI, can be used
+ * to match a frame with its tx result (even though the PID is
+ * only 4 bits wide).
+ * PID_QUEUE: Part of PID_TYPE, this is the queue index number (0-3)
+ * PID_ENTRY: Part of PID_TYPE, this is the queue entry index number (1-3)
+ * This identification number is calculated by ((idx % 3) + 1).
+ * TX_SUCCESS: Indicates tx success (1) or failure (0)
+ * TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0)
+ * TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0)
+ * WCID: The wireless client ID.
+ * MCS: The tx rate used during the last transmission of this frame, be it
+ * successful or not.
+ * PHYMODE: The phymode used for the transmission.
*/
#define TX_STA_FIFO 0x1718
#define TX_STA_FIFO_VALID FIELD32(0x00000001)
#define TX_STA_FIFO_PID_TYPE FIELD32(0x0000001e)
+#define TX_STA_FIFO_PID_QUEUE FIELD32(0x00000006)
+#define TX_STA_FIFO_PID_ENTRY FIELD32(0x00000018)
#define TX_STA_FIFO_TX_SUCCESS FIELD32(0x00000020)
#define TX_STA_FIFO_TX_AGGRE FIELD32(0x00000040)
#define TX_STA_FIFO_TX_ACK_REQUIRED FIELD32(0x00000080)
@@ -1405,6 +1452,24 @@
/*
* Security key table memory.
+ *
+ * The pairwise key table shares some memory with the beacon frame
+ * buffers 6 and 7. That basically means that when beacon 6 & 7
+ * are used we should only use the reduced pairwise key table which
+ * has a maximum of 222 entries.
+ *
+ * ---------------------------------------------
+ * |0x4000 | Pairwise Key | Reduced Pairwise |
+ * | | Table | Key Table |
+ * | | Size: 256 * 32 | Size: 222 * 32 |
+ * |0x5BC0 | |-------------------
+ * | | | Beacon 6 |
+ * |0x5DC0 | |-------------------
+ * | | | Beacon 7 |
+ * |0x5FC0 | |-------------------
+ * |0x5FFF | |
+ * --------------------------
+ *
* MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry
* PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry
* MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry
@@ -1554,7 +1619,8 @@ struct mac_iveiv_entry {
* 2. Extract memory from FCE table for BCN 4~5
* 3. Extract memory from Pair-wise key table for BCN 6~7
* It occupied those memory of wcid 238~253 for BCN 6
- * and wcid 222~237 for BCN 7
+ * and wcid 222~237 for BCN 7 (see Security key table memory
+ * for more info).
*
* IMPORTANT NOTE: Not sure why legacy driver does this,
* but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6.
@@ -1841,6 +1907,13 @@ struct mac_iveiv_entry {
#define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00)
/*
+ * EEPROM Maximum TX power values
+ */
+#define EEPROM_MAX_TX_POWER 0x0027
+#define EEPROM_MAX_TX_POWER_24GHZ FIELD16(0x00ff)
+#define EEPROM_MAX_TX_POWER_5GHZ FIELD16(0xff00)
+
+/*
* EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
* This is delta in 40MHZ.
* VALUE: Tx Power dalta value (MAX=4)
@@ -1926,8 +1999,17 @@ struct mac_iveiv_entry {
* FRAG: 1 To inform TKIP engine this is a fragment.
* MIMO_PS: The remote peer is in dynamic MIMO-PS mode
* TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs
- * BW: Channel bandwidth 20MHz or 40 MHz
+ * BW: Channel bandwidth 0:20MHz, 1:40 MHz (for legacy rates this will
+ * duplicate the frame to both channels).
* STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED
+ * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will
+ * aggregate consecutive frames with the same RA and QoS TID. If
+ * a frame A with the same RA and QoS TID but AMPDU=0 is queued
+ * directly after a frame B with AMPDU=1, frame A might still
+ * get aggregated into the AMPDU started by frame B. So, setting
+ * AMPDU to 0 does _not_ necessarily mean the frame is sent as
+ * MPDU, it can still end up in an AMPDU if the previous frame
+ * was tagged as AMPDU.
*/
#define TXWI_W0_FRAG FIELD32(0x00000001)
#define TXWI_W0_MIMO_PS FIELD32(0x00000002)
@@ -1945,6 +2027,19 @@ struct mac_iveiv_entry {
/*
* Word1
+ * ACK: 0: No Ack needed, 1: Ack needed
+ * NSEQ: 0: Don't assign hw sequence number, 1: Assign hw sequence number
+ * BW_WIN_SIZE: BA windows size of the recipient
+ * WIRELESS_CLI_ID: Client ID for WCID table access
+ * MPDU_TOTAL_BYTE_COUNT: Length of 802.11 frame
+ * PACKETID: Will be latched into the TX_STA_FIFO register once the according
+ * frame was processed. If multiple frames are aggregated together
+ * (AMPDU==1) the reported tx status will always contain the packet
+ * id of the first frame. 0: Don't report tx status for this frame.
+ * PACKETID_QUEUE: Part of PACKETID, This is the queue index (0-3)
+ * PACKETID_ENTRY: Part of PACKETID, THis is the queue entry index (1-3)
+ * This identification number is calculated by ((idx % 3) + 1).
+ * The (+1) is required to prevent PACKETID to become 0.
*/
#define TXWI_W1_ACK FIELD32(0x00000001)
#define TXWI_W1_NSEQ FIELD32(0x00000002)
@@ -1952,6 +2047,8 @@ struct mac_iveiv_entry {
#define TXWI_W1_WIRELESS_CLI_ID FIELD32(0x0000ff00)
#define TXWI_W1_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000)
#define TXWI_W1_PACKETID FIELD32(0xf0000000)
+#define TXWI_W1_PACKETID_QUEUE FIELD32(0x30000000)
+#define TXWI_W1_PACKETID_ENTRY FIELD32(0xc0000000)
/*
* Word2
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index b66e0fd8f0fa..5f00e00789d8 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1,4 +1,5 @@
/*
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com>
@@ -254,6 +255,23 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2800_mcu_request);
+int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i = 0;
+ u32 reg;
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
+ if (reg && reg != ~0)
+ return 0;
+ msleep(1);
+ }
+
+ ERROR(rt2x00dev, "Unstable hardware.\n");
+ return -EBUSY;
+}
+EXPORT_SYMBOL_GPL(rt2800_wait_csr_ready);
+
int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
@@ -367,19 +385,16 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
u32 reg;
/*
- * Wait for stable hardware.
+ * If driver doesn't wake up firmware here,
+ * rt2800_load_firmware will hang forever when interface is up again.
*/
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
- if (reg && reg != ~0)
- break;
- msleep(1);
- }
+ rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000);
- if (i == REGISTER_BUSY_COUNT) {
- ERROR(rt2x00dev, "Unstable hardware.\n");
+ /*
+ * Wait for stable hardware.
+ */
+ if (rt2800_wait_csr_ready(rt2x00dev))
return -EBUSY;
- }
if (rt2x00_is_pci(rt2x00dev))
rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002);
@@ -427,8 +442,10 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2800_load_firmware);
-void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
+void rt2800_write_tx_data(struct queue_entry *entry,
+ struct txentry_desc *txdesc)
{
+ __le32 *txwi = rt2800_drv_get_txwi(entry);
u32 word;
/*
@@ -437,7 +454,8 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
rt2x00_desc_read(txwi, 0, &word);
rt2x00_set_field32(&word, TXWI_W0_FRAG,
test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
- rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
+ rt2x00_set_field32(&word, TXWI_W0_MIMO_PS,
+ test_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags));
rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
rt2x00_set_field32(&word, TXWI_W0_TS,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
@@ -465,7 +483,8 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
txdesc->key_idx : 0xff);
rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
txdesc->length);
- rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1);
+ rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid);
+ rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1);
rt2x00_desc_write(txwi, 1, word);
/*
@@ -478,9 +497,9 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
_rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
_rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
}
-EXPORT_SYMBOL_GPL(rt2800_write_txwi);
+EXPORT_SYMBOL_GPL(rt2800_write_tx_data);
-static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2)
+static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
{
int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
@@ -490,7 +509,7 @@ static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2)
u8 offset1;
u8 offset2;
- if (rt2x00dev->rx_status.band == IEEE80211_BAND_2GHZ) {
+ if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom);
offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0);
offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1);
@@ -569,6 +588,181 @@ void rt2800_process_rxwi(struct queue_entry *entry,
}
EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
+static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
+{
+ __le32 *txwi;
+ u32 word;
+ int wcid, ack, pid;
+ int tx_wcid, tx_ack, tx_pid;
+
+ wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
+ ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
+ pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
+
+ /*
+ * This frames has returned with an IO error,
+ * so the status report is not intended for this
+ * frame.
+ */
+ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
+ rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
+ return false;
+ }
+
+ /*
+ * Validate if this TX status report is intended for
+ * this entry by comparing the WCID/ACK/PID fields.
+ */
+ txwi = rt2800_drv_get_txwi(entry);
+
+ rt2x00_desc_read(txwi, 1, &word);
+ tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
+ tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
+ tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
+
+ if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
+ WARNING(entry->queue->rt2x00dev,
+ "TX status report missed for queue %d entry %d\n",
+ entry->queue->qid, entry->entry_idx);
+ rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
+ return false;
+ }
+
+ return true;
+}
+
+void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct txdone_entry_desc txdesc;
+ u32 word;
+ u16 mcs, real_mcs;
+ int aggr, ampdu;
+ __le32 *txwi;
+
+ /*
+ * Obtain the status about this packet.
+ */
+ txdesc.flags = 0;
+ txwi = rt2800_drv_get_txwi(entry);
+ rt2x00_desc_read(txwi, 0, &word);
+
+ mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
+ ampdu = rt2x00_get_field32(word, TXWI_W0_AMPDU);
+
+ real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS);
+ aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE);
+
+ /*
+ * If a frame was meant to be sent as a single non-aggregated MPDU
+ * but ended up in an aggregate the used tx rate doesn't correlate
+ * with the one specified in the TXWI as the whole aggregate is sent
+ * with the same rate.
+ *
+ * For example: two frames are sent to rt2x00, the first one sets
+ * AMPDU=1 and requests MCS7 whereas the second frame sets AMDPU=0
+ * and requests MCS15. If the hw aggregates both frames into one
+ * AMDPU the tx status for both frames will contain MCS7 although
+ * the frame was sent successfully.
+ *
+ * Hence, replace the requested rate with the real tx rate to not
+ * confuse the rate control algortihm by providing clearly wrong
+ * data.
+ */
+ if (aggr == 1 && ampdu == 0 && real_mcs != mcs) {
+ skbdesc->tx_rate_idx = real_mcs;
+ mcs = real_mcs;
+ }
+
+ /*
+ * Ralink has a retry mechanism using a global fallback
+ * table. We setup this fallback table to try the immediate
+ * lower rate for all rates. In the TX_STA_FIFO, the MCS field
+ * always contains the MCS used for the last transmission, be
+ * it successful or not.
+ */
+ if (rt2x00_get_field32(status, TX_STA_FIFO_TX_SUCCESS)) {
+ /*
+ * Transmission succeeded. The number of retries is
+ * mcs - real_mcs
+ */
+ __set_bit(TXDONE_SUCCESS, &txdesc.flags);
+ txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0);
+ } else {
+ /*
+ * Transmission failed. The number of retries is
+ * always 7 in this case (for a total number of 8
+ * frames sent).
+ */
+ __set_bit(TXDONE_FAILURE, &txdesc.flags);
+ txdesc.retry = rt2x00dev->long_retry;
+ }
+
+ /*
+ * the frame was retried at least once
+ * -> hw used fallback rates
+ */
+ if (txdesc.retry)
+ __set_bit(TXDONE_FALLBACK, &txdesc.flags);
+
+ rt2x00lib_txdone(entry, &txdesc);
+}
+EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
+
+void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+ struct queue_entry *entry;
+ u32 reg;
+ u8 pid;
+ int i;
+
+ /*
+ * 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 < TX_ENTRIES; i++) {
+ rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
+ if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
+ break;
+
+ /*
+ * Skip this entry when it contains an invalid
+ * queue identication number.
+ */
+ pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
+ if (pid >= QID_RX)
+ continue;
+
+ queue = rt2x00queue_get_queue(rt2x00dev, pid);
+ if (unlikely(!queue))
+ continue;
+
+ /*
+ * Inside each queue, we process each entry in a chronological
+ * order. We first check that the queue is not empty.
+ */
+ entry = NULL;
+ while (!rt2x00queue_empty(queue)) {
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+ if (rt2800_txdone_entry_check(entry, reg))
+ break;
+ }
+
+ if (!entry || rt2x00queue_empty(queue))
+ break;
+
+ rt2800_txdone_entry(entry, reg);
+ }
+}
+EXPORT_SYMBOL_GPL(rt2800_txdone);
+
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -600,7 +794,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
/*
* Add the TXWI for the beacon to the skb.
*/
- rt2800_write_txwi((__le32 *)entry->skb->data, txdesc);
+ rt2800_write_tx_data(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -871,8 +1065,12 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
* 1 pairwise key is possible per AID, this means that the AID
* equals our hw_key_idx. Make sure the WCID starts _after_ the
* last possible shared key entry.
+ *
+ * Since parts of the pairwise key table might be shared with
+ * the beacon frame buffers 6 & 7 we should only write into the
+ * first 222 entries.
*/
- if (crypto->aid > (256 - 32))
+ if (crypto->aid > (222 - 32))
return -ENOSPC;
key->hw_key_idx = 32 + crypto->aid;
@@ -975,19 +1173,23 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
}
if (flags & CONFIG_UPDATE_MAC) {
- reg = le32_to_cpu(conf->mac[1]);
- rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
- conf->mac[1] = cpu_to_le32(reg);
+ if (!is_zero_ether_addr((const u8 *)conf->mac)) {
+ reg = le32_to_cpu(conf->mac[1]);
+ rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
+ conf->mac[1] = cpu_to_le32(reg);
+ }
rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0,
conf->mac, sizeof(conf->mac));
}
if (flags & CONFIG_UPDATE_BSSID) {
- reg = le32_to_cpu(conf->bssid[1]);
- rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
- rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
- conf->bssid[1] = cpu_to_le32(reg);
+ if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
+ reg = le32_to_cpu(conf->bssid[1]);
+ rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
+ rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
+ conf->bssid[1] = cpu_to_le32(reg);
+ }
rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0,
conf->bssid, sizeof(conf->bssid));
@@ -995,38 +1197,149 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
}
EXPORT_SYMBOL_GPL(rt2800_config_intf);
-void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp)
+static void rt2800_config_ht_opmode(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_erp *erp)
{
+ bool any_sta_nongf = !!(erp->ht_opmode &
+ IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+ u8 protection = erp->ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION;
+ u8 mm20_mode, mm40_mode, gf20_mode, gf40_mode;
+ u16 mm20_rate, mm40_rate, gf20_rate, gf40_rate;
u32 reg;
- rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
- rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
- !!erp->short_preamble);
- rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE,
- !!erp->short_preamble);
- rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+ /* default protection rate for HT20: OFDM 24M */
+ mm20_rate = gf20_rate = 0x4004;
- rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
- rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL,
- erp->cts_protection ? 2 : 0);
- rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+ /* default protection rate for HT40: duplicate OFDM 24M */
+ mm40_rate = gf40_rate = 0x4084;
- rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE,
- erp->basic_rates);
- rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+ switch (protection) {
+ case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
+ /*
+ * All STAs in this BSS are HT20/40 but there might be
+ * STAs not supporting greenfield mode.
+ * => Disable protection for HT transmissions.
+ */
+ mm20_mode = mm40_mode = gf20_mode = gf40_mode = 0;
- rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
- rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time);
- rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
+ break;
+ case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
+ /*
+ * All STAs in this BSS are HT20 or HT20/40 but there
+ * might be STAs not supporting greenfield mode.
+ * => Protect all HT40 transmissions.
+ */
+ mm20_mode = gf20_mode = 0;
+ mm40_mode = gf40_mode = 2;
- rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
- rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
- rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
+ break;
+ case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
+ /*
+ * Nonmember protection:
+ * According to 802.11n we _should_ protect all
+ * HT transmissions (but we don't have to).
+ *
+ * But if cts_protection is enabled we _shall_ protect
+ * all HT transmissions using a CCK rate.
+ *
+ * And if any station is non GF we _shall_ protect
+ * GF transmissions.
+ *
+ * We decide to protect everything
+ * -> fall through to mixed mode.
+ */
+ case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+ /*
+ * Legacy STAs are present
+ * => Protect all HT transmissions.
+ */
+ mm20_mode = mm40_mode = gf20_mode = gf40_mode = 2;
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
- rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
- erp->beacon_int * 16);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ /*
+ * If erp protection is needed we have to protect HT
+ * transmissions with CCK 11M long preamble.
+ */
+ if (erp->cts_protection) {
+ /* don't duplicate RTS/CTS in CCK mode */
+ mm20_rate = mm40_rate = 0x0003;
+ gf20_rate = gf40_rate = 0x0003;
+ }
+ break;
+ };
+
+ /* check for STAs not supporting greenfield mode */
+ if (any_sta_nongf)
+ gf20_mode = gf40_mode = 2;
+
+ /* Update HT protection config */
+ rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_RATE, mm20_rate);
+ rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_CTRL, mm20_mode);
+ rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
+
+ rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, mm40_rate);
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, mm40_mode);
+ rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
+
+ rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_RATE, gf20_rate);
+ rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_CTRL, gf20_mode);
+ rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
+
+ rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_RATE, gf40_rate);
+ rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_CTRL, gf40_mode);
+ rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
+}
+
+void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
+ u32 changed)
+{
+ u32 reg;
+
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
+ !!erp->short_preamble);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE,
+ !!erp->short_preamble);
+ rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+ }
+
+ if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+ rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL,
+ erp->cts_protection ? 2 : 0);
+ rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+ }
+
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE,
+ erp->basic_rates);
+ rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+ }
+
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
+ rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME,
+ erp->slot_time);
+ rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
+
+ rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
+ rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
+ }
+
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ }
+
+ if (changed & BSS_CHANGED_HT)
+ rt2800_config_ht_opmode(rt2x00dev, erp);
}
EXPORT_SYMBOL_GPL(rt2800_config_erp);
@@ -1120,27 +1433,23 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
* double meaning, and we should set a 7DBm boost flag.
*/
rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST,
- (info->tx_power1 >= 0));
+ (info->default_power1 >= 0));
- if (info->tx_power1 < 0)
- info->tx_power1 += 7;
+ if (info->default_power1 < 0)
+ info->default_power1 += 7;
- rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A,
- TXPOWER_A_TO_DEV(info->tx_power1));
+ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, info->default_power1);
rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST,
- (info->tx_power2 >= 0));
+ (info->default_power2 >= 0));
- if (info->tx_power2 < 0)
- info->tx_power2 += 7;
+ if (info->default_power2 < 0)
+ info->default_power2 += 7;
- rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A,
- TXPOWER_A_TO_DEV(info->tx_power2));
+ rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, info->default_power2);
} else {
- rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G,
- TXPOWER_G_TO_DEV(info->tx_power1));
- rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G,
- TXPOWER_G_TO_DEV(info->tx_power2));
+ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, info->default_power1);
+ rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, info->default_power2);
}
rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf));
@@ -1180,13 +1489,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
- TXPOWER_G_TO_DEV(info->tx_power1));
+ rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, info->default_power1);
rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
- TXPOWER_G_TO_DEV(info->tx_power2));
+ rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2);
rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
@@ -1210,10 +1517,19 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
unsigned int tx_pin;
u8 bbp;
+ if (rf->channel <= 14) {
+ info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1);
+ info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2);
+ } else {
+ info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1);
+ info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2);
+ }
+
if (rt2x00_rf(rt2x00dev, RF2020) ||
rt2x00_rf(rt2x00dev, RF3020) ||
rt2x00_rf(rt2x00dev, RF3021) ||
- rt2x00_rf(rt2x00dev, RF3022))
+ rt2x00_rf(rt2x00dev, RF3022) ||
+ rt2x00_rf(rt2x00dev, RF3052))
rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
else
rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
@@ -1536,7 +1852,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
/*
* Initialization functions.
*/
-int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
+static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
u16 eeprom;
@@ -1728,8 +2044,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
- rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL,
- !rt2x00_is_usb(rt2x00dev));
+ rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
@@ -1886,6 +2201,14 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg);
/*
+ * Do not force the BA window size, we use the TXWI to set it
+ */
+ rt2800_register_read(rt2x00dev, AMPDU_BA_WINSIZE, &reg);
+ rt2x00_set_field32(&reg, AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE, 0);
+ rt2x00_set_field32(&reg, AMPDU_BA_WINSIZE_FORCE_WINSIZE, 0);
+ rt2800_register_write(rt2x00dev, AMPDU_BA_WINSIZE, reg);
+
+ /*
* We must clear the error counters.
* These registers are cleared on read,
* so we may pass a useless variable to store the value.
@@ -1906,7 +2229,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
return 0;
}
-EXPORT_SYMBOL_GPL(rt2800_init_registers);
static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
{
@@ -1949,7 +2271,7 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
return -EACCES;
}
-int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
+static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
u16 eeprom;
@@ -2044,7 +2366,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
return 0;
}
-EXPORT_SYMBOL_GPL(rt2800_init_bbp);
static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev,
bool bw40, u8 rfcsr24, u8 filter_target)
@@ -2106,7 +2427,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev,
return rfcsr24;
}
-int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
{
u8 rfcsr;
u8 bbp;
@@ -2360,7 +2681,100 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
return 0;
}
-EXPORT_SYMBOL_GPL(rt2800_init_rfcsr);
+
+int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+ u16 word;
+
+ /*
+ * Initialize all registers.
+ */
+ if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
+ rt2800_init_registers(rt2x00dev) ||
+ rt2800_init_bbp(rt2x00dev) ||
+ rt2800_init_rfcsr(rt2x00dev)))
+ return -EIO;
+
+ /*
+ * Send signal to firmware during boot time.
+ */
+ rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
+
+ if (rt2x00_is_usb(rt2x00dev) &&
+ (rt2x00_rt(rt2x00dev, RT3070) ||
+ rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3572))) {
+ udelay(200);
+ rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
+ udelay(10);
+ }
+
+ /*
+ * Enable RX.
+ */
+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ udelay(50);
+
+ rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+ rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ /*
+ * Initialize LED control
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
+ rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
+ rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
+ rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_enable_radio);
+
+void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+
+ rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+ rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+ /* Wait for DMA, ignore error */
+ rt2800_wait_wpdma_ready(rt2x00dev);
+
+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 0);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
+}
+EXPORT_SYMBOL_GPL(rt2800_disable_radio);
int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev)
{
@@ -2516,6 +2930,13 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
default_lna_gain);
rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word);
+ if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER);
+ if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word);
+
return 0;
}
EXPORT_SYMBOL_GPL(rt2800_validate_eeprom);
@@ -2755,9 +3176,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
{
struct hw_mode_spec *spec = &rt2x00dev->spec;
struct channel_info *info;
- char *tx_power1;
- char *tx_power2;
+ char *default_power1;
+ char *default_power2;
unsigned int i;
+ unsigned short max_power;
u16 eeprom;
/*
@@ -2770,11 +3192,20 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
* Initialize all hw fields.
*/
rt2x00dev->hw->flags =
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_AMPDU_AGGREGATION;
+ /*
+ * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
+ * unless we are capable of sending the buffered frames out after the
+ * DTIM transmission using rt2x00lib_beacondone. This will send out
+ * multicast and broadcast traffic immediately instead of buffering it
+ * infinitly and thus dropping it after some time.
+ */
+ if (!rt2x00_is_usb(rt2x00dev))
+ rt2x00dev->hw->flags |=
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -2785,12 +3216,13 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
* As rt2800 has a global fallback table we cannot specify
* more then one tx rate per frame but since the hw will
* try several rates (based on the fallback table) we should
- * still initialize max_rates to the maximum number of rates
+ * initialize max_report_rates to the maximum number of rates
* we are going to try. Otherwise mac80211 will truncate our
* reported tx rates and the rc algortihm will end up with
* incorrect data.
*/
- rt2x00dev->hw->max_rates = 7;
+ rt2x00dev->hw->max_rates = 1;
+ rt2x00dev->hw->max_report_rates = 7;
rt2x00dev->hw->max_rate_tries = 1;
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
@@ -2865,27 +3297,32 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
- tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
- tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom);
+ max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ);
+ default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
+ default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
for (i = 0; i < 14; i++) {
- info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]);
- info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]);
+ info[i].max_power = max_power;
+ info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]);
+ info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]);
}
if (spec->num_channels > 14) {
- tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
- tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
+ max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ);
+ default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
+ default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
for (i = 14; i < spec->num_channels; i++) {
- info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]);
- info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]);
+ info[i].max_power = max_power;
+ info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]);
+ info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]);
}
}
@@ -3042,8 +3479,12 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
switch (action) {
case IEEE80211_AMPDU_RX_START:
case IEEE80211_AMPDU_RX_STOP:
- /* we don't support RX aggregation yet */
- ret = -ENOTSUPP;
+ /*
+ * The hw itself takes care of setting up BlockAck mechanisms.
+ * So, we only have to allow mac80211 to nagotiate a BlockAck
+ * agreement. Once that is done, the hw will BlockAck incoming
+ * AMPDUs without further setup.
+ */
break;
case IEEE80211_AMPDU_TX_START:
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 091641e3c5e2..81cbc92e7857 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -1,4 +1,6 @@
/*
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2009 Bartlomiej Zolnierkiewicz
This program is free software; you can redistribute it and/or modify
@@ -44,6 +46,7 @@ struct rt2800_ops {
int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len);
int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
+ __le32 *(*drv_get_txwi)(struct queue_entry *entry);
};
static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
@@ -126,18 +129,32 @@ static inline int rt2800_drv_init_registers(struct rt2x00_dev *rt2x00dev)
return rt2800ops->drv_init_registers(rt2x00dev);
}
+static inline __le32 *rt2800_drv_get_txwi(struct queue_entry *entry)
+{
+ const struct rt2800_ops *rt2800ops = entry->queue->rt2x00dev->ops->drv;
+
+ return rt2800ops->drv_get_txwi(entry);
+}
+
void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
const u8 command, const u8 token,
const u8 arg0, const u8 arg1);
+int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev);
+int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev);
+
int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len);
int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len);
-void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc);
+void rt2800_write_tx_data(struct queue_entry *entry,
+ struct txentry_desc *txdesc);
void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
+void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
+void rt2800_txdone_entry(struct queue_entry *entry, u32 status);
+
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
extern const struct rt2x00debug rt2800_rt2x00debug;
@@ -153,7 +170,8 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev,
const unsigned int filter_flags);
void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf, const unsigned int flags);
-void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp);
+void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
+ u32 changed);
void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant);
void rt2800_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
@@ -163,10 +181,8 @@ 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);
-int rt2800_init_registers(struct rt2x00_dev *rt2x00dev);
-int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev);
-int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev);
-int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev);
+int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev);
+void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev);
void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 39b3846fa340..b26739535986 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
@@ -196,8 +196,6 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000);
-
/*
* enable Host program ram write selection
*/
@@ -243,6 +241,7 @@ static void rt2800pci_clear_entry(struct queue_entry *entry)
{
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
u32 word;
if (entry->queue->qid == QID_RX) {
@@ -253,6 +252,13 @@ static void rt2800pci_clear_entry(struct queue_entry *entry)
rt2x00_desc_read(entry_priv->desc, 1, &word);
rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0);
rt2x00_desc_write(entry_priv->desc, 1, word);
+
+ /*
+ * 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,
+ entry->entry_idx);
} else {
rt2x00_desc_read(entry_priv->desc, 1, &word);
rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1);
@@ -344,24 +350,24 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
}
rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
- rt2x00_set_field32(&reg, INT_MASK_CSR_RXDELAYINT, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_TXDELAYINT, mask);
+ 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);
- rt2x00_set_field32(&reg, INT_MASK_CSR_AC0_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_AC1_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_AC2_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_AC3_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_HCCA_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_MGMT_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_MCU_COMMAND, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_RXTX_COHERENT, mask);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_AC0_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_AC1_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_AC2_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_AC3_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_HCCA_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_MGMT_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_MCU_COMMAND, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_RXTX_COHERENT, 0);
rt2x00_set_field32(&reg, INT_MASK_CSR_TBTT, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_PRE_TBTT, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_TX_FIFO_STATUS, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_AUTO_WAKEUP, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_GPTIMER, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_RX_COHERENT, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_TX_COHERENT, mask);
+ 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);
}
@@ -399,78 +405,18 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
{
- u32 reg;
- u16 word;
-
- /*
- * Initialize all registers.
- */
if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
- rt2800pci_init_queues(rt2x00dev) ||
- rt2800_init_registers(rt2x00dev) ||
- rt2800_wait_wpdma_ready(rt2x00dev) ||
- rt2800_init_bbp(rt2x00dev) ||
- rt2800_init_rfcsr(rt2x00dev)))
+ rt2800pci_init_queues(rt2x00dev)))
return -EIO;
- /*
- * Send signal to firmware during boot time.
- */
- rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
-
- /*
- * Enable RX.
- */
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
- rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
- rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
- /*
- * Initialize LED control
- */
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- return 0;
+ return rt2800_enable_radio(rt2x00dev);
}
static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
- rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
- rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
+ rt2800_disable_radio(rt2x00dev);
rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280);
@@ -486,9 +432,6 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
-
- /* Wait for DMA, ignore error */
- rt2800_wait_wpdma_ready(rt2x00dev);
}
static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -566,21 +509,16 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt2800pci_write_tx_data(struct queue_entry* entry,
- struct txentry_desc *txdesc)
+static __le32 *rt2800pci_get_txwi(struct queue_entry *entry)
{
- __le32 *txwi = (__le32 *) entry->skb->data;
-
- rt2800_write_txwi(txwi, txdesc);
+ return (__le32 *) entry->skb->data;
}
-
-static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt2800pci_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
__le32 *txd = entry_priv->desc;
u32 word;
@@ -600,7 +538,7 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(txd, 0, word);
rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_SD_LEN1, skb->len);
+ rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len);
rt2x00_set_field32(&word, TXD_W1_LAST_SEC1,
!test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W1_BURST,
@@ -631,41 +569,35 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* TX data initialization
*/
-static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue_idx)
+static void rt2800pci_kick_tx_queue(struct data_queue *queue)
{
- struct data_queue *queue;
- unsigned int idx, qidx = 0;
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
+ unsigned int qidx;
- if (queue_idx > QID_HCCA && queue_idx != QID_MGMT)
- return;
-
- queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
- idx = queue->index[Q_INDEX];
-
- if (queue_idx == QID_MGMT)
+ if (queue->qid == QID_MGMT)
qidx = 5;
else
- qidx = queue_idx;
+ qidx = queue->qid;
- rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), idx);
+ rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), entry->entry_idx);
}
-static void rt2800pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt2800pci_kill_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
- if (qid == QID_BEACON) {
+ if (queue->qid == QID_BEACON) {
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0);
return;
}
rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, (qid == QID_AC_BE));
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, (qid == QID_AC_BK));
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, (qid == QID_AC_VI));
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, (qid == QID_AC_VO));
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI));
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, (queue->qid == QID_AC_VO));
rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
}
@@ -675,7 +607,6 @@ static void rt2800pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
static void rt2800pci_fill_rxdone(struct queue_entry *entry,
struct rxdone_entry_desc *rxdesc)
{
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
__le32 *rxd = entry_priv->desc;
u32 word;
@@ -717,127 +648,74 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
* Process the RXWI structure that is at the start of the buffer.
*/
rt2800_process_rxwi(entry, rxdesc);
-
- /*
- * 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, entry->entry_idx);
}
/*
* Interrupt functions.
*/
+static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
+{
+ struct ieee80211_conf conf = { .flags = 0 };
+ struct rt2x00lib_conf libconf = { .conf = &conf };
+
+ rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
+}
+
static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
struct queue_entry *entry;
- __le32 *txwi;
- struct txdone_entry_desc txdesc;
- u32 word;
- u32 reg;
- int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
- u16 mcs, real_mcs;
- int i;
-
- /*
- * 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 < TX_ENTRIES; i++) {
- rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
- if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
+ u32 status;
+ u8 qid;
+
+ while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
+ /* Now remove the tx status from the FIFO */
+ if (kfifo_out(&rt2x00dev->txstatus_fifo, &status,
+ sizeof(status)) != sizeof(status)) {
+ WARN_ON(1);
break;
+ }
- wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
- ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
- pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
-
- /*
- * Skip this entry when it contains an invalid
- * queue identication number.
- */
- if (pid <= 0 || pid > QID_RX)
- continue;
-
- queue = rt2x00queue_get_queue(rt2x00dev, pid - 1);
- if (unlikely(!queue))
- continue;
-
- /*
- * Inside each queue, we process each entry in a chronological
- * order. We first check that the queue is not empty.
- */
- if (rt2x00queue_empty(queue))
- continue;
- entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
-
- /* Check if we got a match by looking at WCID/ACK/PID
- * fields */
- txwi = (__le32 *) entry->skb->data;
-
- rt2x00_desc_read(txwi, 1, &word);
- tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
- tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
- tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
-
- if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid))
- WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n");
-
- /*
- * Obtain the status about this packet.
- */
- txdesc.flags = 0;
- rt2x00_desc_read(txwi, 0, &word);
- mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
- real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
-
- /*
- * Ralink has a retry mechanism using a global fallback
- * table. We setup this fallback table to try the immediate
- * lower rate for all rates. In the TX_STA_FIFO, the MCS field
- * always contains the MCS used for the last transmission, be
- * it successful or not.
- */
- if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) {
+ qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
+ if (qid >= QID_RX) {
/*
- * Transmission succeeded. The number of retries is
- * mcs - real_mcs
+ * Unknown queue, this shouldn't happen. Just drop
+ * this tx status.
*/
- __set_bit(TXDONE_SUCCESS, &txdesc.flags);
- txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0);
- } else {
+ WARNING(rt2x00dev, "Got TX status report with "
+ "unexpected pid %u, dropping", qid);
+ break;
+ }
+
+ queue = rt2x00queue_get_queue(rt2x00dev, qid);
+ if (unlikely(queue == NULL)) {
/*
- * Transmission failed. The number of retries is
- * always 7 in this case (for a total number of 8
- * frames sent).
+ * The queue is NULL, this shouldn't happen. Stop
+ * processing here and drop the tx status
*/
- __set_bit(TXDONE_FAILURE, &txdesc.flags);
- txdesc.retry = 7;
+ WARNING(rt2x00dev, "Got TX status for an unavailable "
+ "queue %u, dropping", qid);
+ break;
}
- /*
- * the frame was retried at least once
- * -> hw used fallback rates
- */
- if (txdesc.retry)
- __set_bit(TXDONE_FALLBACK, &txdesc.flags);
+ if (rt2x00queue_empty(queue)) {
+ /*
+ * The queue is empty. Stop processing here
+ * and drop the tx status.
+ */
+ WARNING(rt2x00dev, "Got TX status for an empty "
+ "queue %u, dropping", qid);
+ break;
+ }
- rt2x00lib_txdone(entry, &txdesc);
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+ rt2800_txdone_entry(entry, status);
}
}
-static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
+static void rt2800pci_txstatus_tasklet(unsigned long data)
{
- struct ieee80211_conf conf = { .flags = 0 };
- struct rt2x00lib_conf libconf = { .conf = &conf };
-
- rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
+ rt2800pci_txdone((struct rt2x00_dev *)data);
}
static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
@@ -864,13 +742,7 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
rt2x00pci_rxdone(rt2x00dev);
/*
- * 4 - Tx done interrupt.
- */
- if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
- rt2800pci_txdone(rt2x00dev);
-
- /*
- * 5 - Auto wakeup interrupt.
+ * 4 - Auto wakeup interrupt.
*/
if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP))
rt2800pci_wakeup(rt2x00dev);
@@ -882,10 +754,58 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
return IRQ_HANDLED;
}
+static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
+{
+ u32 status;
+ int i;
+
+ /*
+ * The TX_FIFO_STATUS interrupt needs special care. We should
+ * read TX_STA_FIFO but we should do it immediately as otherwise
+ * the register can overflow and we would lose status reports.
+ *
+ * Hence, read the TX_STA_FIFO register and copy all tx status
+ * reports into a kernel FIFO which is handled in the txstatus
+ * tasklet. We use a tasklet to process the tx status reports
+ * because we can schedule the tasklet multiple times (when the
+ * interrupt fires again during tx status processing).
+ *
+ * Furthermore we don't disable the TX_FIFO_STATUS
+ * interrupt here but leave it enabled so that the TX_STA_FIFO
+ * can also be read while the interrupt thread gets executed.
+ *
+ * Since we have only one producer and one consumer we don't
+ * need to lock the kfifo.
+ */
+ for (i = 0; i < TX_ENTRIES; i++) {
+ rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status);
+
+ if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
+ break;
+
+ if (kfifo_is_full(&rt2x00dev->txstatus_fifo)) {
+ WARNING(rt2x00dev, "TX status FIFO overrun,"
+ " drop tx status report.\n");
+ break;
+ }
+
+ if (kfifo_in(&rt2x00dev->txstatus_fifo, &status,
+ sizeof(status)) != sizeof(status)) {
+ WARNING(rt2x00dev, "TX status FIFO overrun,"
+ "drop tx status report.\n");
+ break;
+ }
+ }
+
+ /* Schedule the tasklet for processing the tx status. */
+ tasklet_schedule(&rt2x00dev->txstatus_tasklet);
+}
+
static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
{
struct rt2x00_dev *rt2x00dev = dev_instance;
u32 reg;
+ irqreturn_t ret = IRQ_HANDLED;
/* Read status and ACK all interrupts */
rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
@@ -897,15 +817,38 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
return IRQ_HANDLED;
- /* Store irqvalue for use in the interrupt thread. */
- rt2x00dev->irqvalue[0] = reg;
+ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
+ rt2800pci_txstatus_interrupt(rt2x00dev);
- /* Disable interrupts, will be enabled again in the interrupt thread. */
- rt2x00dev->ops->lib->set_device_state(rt2x00dev,
- STATE_RADIO_IRQ_OFF_ISR);
+ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT) ||
+ rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT) ||
+ rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE) ||
+ rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) {
+ /*
+ * All other interrupts are handled in the interrupt thread.
+ * Store irqvalue for use in the interrupt thread.
+ */
+ rt2x00dev->irqvalue[0] = reg;
+
+ /*
+ * Disable interrupts, will be enabled again in the
+ * interrupt thread.
+ */
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev,
+ STATE_RADIO_IRQ_OFF_ISR);
+
+ /*
+ * Leave the TX_FIFO_STATUS interrupt enabled to not lose any
+ * tx status reports.
+ */
+ rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_TX_FIFO_STATUS, 1);
+ rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
+ ret = IRQ_WAKE_THREAD;
+ }
- return IRQ_WAKE_THREAD;
+ return ret;
}
/*
@@ -968,6 +911,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *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);
if (!modparam_nohwcrypt)
__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
@@ -1011,11 +955,13 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = {
.regbusy_read = rt2x00pci_regbusy_read,
.drv_write_firmware = rt2800pci_write_firmware,
.drv_init_registers = rt2800pci_init_registers,
+ .drv_get_txwi = rt2800pci_get_txwi,
};
static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
.irq_handler = rt2800pci_interrupt,
.irq_handler_thread = rt2800pci_interrupt_thread,
+ .txstatus_tasklet = rt2800pci_txstatus_tasklet,
.probe_hw = rt2800pci_probe_hw,
.get_firmware_name = rt2800pci_get_firmware_name,
.check_firmware = rt2800_check_firmware,
@@ -1030,7 +976,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
.reset_tuner = rt2800_reset_tuner,
.link_tuner = rt2800_link_tuner,
.write_tx_desc = rt2800pci_write_tx_desc,
- .write_tx_data = rt2800pci_write_tx_data,
+ .write_tx_data = rt2800_write_tx_data,
.write_beacon = rt2800_write_beacon,
.kick_tx_queue = rt2800pci_kick_tx_queue,
.kill_tx_queue = rt2800pci_kill_tx_queue,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 5a2dfe87c6b6..3dff56ec195a 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de>
Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>
@@ -100,19 +101,6 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
msleep(10);
rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
- /*
- * Send signal to firmware during boot time.
- */
- rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
-
- if (rt2x00_rt(rt2x00dev, RT3070) ||
- rt2x00_rt(rt2x00dev, RT3071) ||
- rt2x00_rt(rt2x00dev, RT3572)) {
- udelay(200);
- rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
- udelay(10);
- }
-
return 0;
}
@@ -134,26 +122,18 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
- int i;
/*
* Wait until BBP and RF are ready.
*/
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
- if (reg && reg != ~0)
- break;
- msleep(1);
- }
-
- if (i == REGISTER_BUSY_COUNT) {
- ERROR(rt2x00dev, "Unstable hardware.\n");
+ 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);
+ rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+
rt2800_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);
@@ -172,30 +152,10 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
- u16 word;
- /*
- * Initialize all registers.
- */
- if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
- rt2800_init_registers(rt2x00dev) ||
- rt2800_init_bbp(rt2x00dev) ||
- rt2800_init_rfcsr(rt2x00dev)))
+ if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev)))
return -EIO;
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
- udelay(50);
-
- rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
- rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
-
rt2800_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);
@@ -210,45 +170,12 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
- /*
- * Initialize LED control
- */
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- return 0;
+ return rt2800_enable_radio(rt2x00dev);
}
static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- u32 reg;
-
- rt2800_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);
- rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
-
- /* Wait for DMA, ignore error */
- rt2800_wait_wpdma_ready(rt2x00dev);
-
+ rt2800_disable_radio(rt2x00dev);
rt2x00usb_disable_radio(rt2x00dev);
}
@@ -320,21 +247,19 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt2800usb_write_tx_data(struct queue_entry* entry,
- struct txentry_desc *txdesc)
+static __le32 *rt2800usb_get_txwi(struct queue_entry *entry)
{
- __le32 *txwi = (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE);
-
- rt2800_write_txwi(txwi, txdesc);
+ if (entry->queue->qid == QID_BEACON)
+ return (__le32 *) (entry->skb->data);
+ else
+ return (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE);
}
-
-static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt2800usb_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txi = (__le32 *) skb->data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ __le32 *txi = (__le32 *) entry->skb->data;
u32 word;
/*
@@ -342,7 +267,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
*/
rt2x00_desc_read(txi, 0, &word);
rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
- skb->len - TXINFO_DESC_SIZE);
+ entry->skb->len - TXINFO_DESC_SIZE);
rt2x00_set_field32(&word, TXINFO_W0_WIV,
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
@@ -379,6 +304,46 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
}
/*
+ * TX control handlers
+ */
+static void rt2800usb_work_txdone(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, txdone_work);
+ struct data_queue *queue;
+ struct queue_entry *entry;
+
+ rt2800_txdone(rt2x00dev);
+
+ /*
+ * Process any trailing TX status reports for IO failures,
+ * we loop until we find the first non-IO error entry. This
+ * can either be a frame which is free, is being uploaded,
+ * or has completed the upload but didn't have an entry
+ * in the TX_STAT_FIFO register yet.
+ */
+ tx_queue_for_each(rt2x00dev, queue) {
+ 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))
+ break;
+
+ rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
+ }
+ }
+}
+
+static void rt2800usb_kill_tx_queue(struct data_queue *queue)
+{
+ if (queue->qid == QID_BEACON)
+ rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0);
+
+ rt2x00usb_kill_tx_queue(queue);
+}
+
+/*
* RX control handlers
*/
static void rt2800usb_fill_rxdone(struct queue_entry *entry,
@@ -514,6 +479,11 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
+ /*
+ * Overwrite TX done handler
+ */
+ PREPARE_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone);
+
return 0;
}
@@ -549,6 +519,7 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = {
.regbusy_read = rt2x00usb_regbusy_read,
.drv_write_firmware = rt2800usb_write_firmware,
.drv_init_registers = rt2800usb_init_registers,
+ .drv_get_txwi = rt2800usb_get_txwi,
};
static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
@@ -566,11 +537,11 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
.link_tuner = rt2800_link_tuner,
.watchdog = rt2x00usb_watchdog,
.write_tx_desc = rt2800usb_write_tx_desc,
- .write_tx_data = rt2800usb_write_tx_data,
+ .write_tx_data = rt2800_write_tx_data,
.write_beacon = rt2800_write_beacon,
.get_tx_data_len = rt2800usb_get_tx_data_len,
.kick_tx_queue = rt2x00usb_kick_tx_queue,
- .kill_tx_queue = rt2x00usb_kill_tx_queue,
+ .kill_tx_queue = rt2800usb_kill_tx_queue,
.fill_rxdone = rt2800usb_fill_rxdone,
.config_shared_key = rt2800_config_shared_key,
.config_pairwise_key = rt2800_config_pairwise_key,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index c21af38cc5af..94fe589acfaa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
<http://rt2x00.serialmonkey.com>
@@ -35,6 +36,7 @@
#include <linux/mutex.h>
#include <linux/etherdevice.h>
#include <linux/input-polldev.h>
+#include <linux/kfifo.h>
#include <net/mac80211.h>
@@ -212,8 +214,9 @@ struct channel_info {
unsigned int flags;
#define GEOGRAPHY_ALLOWED 0x00000001
- short tx_power1;
- short tx_power2;
+ short max_power;
+ short default_power1;
+ short default_power2;
};
/*
@@ -335,6 +338,11 @@ struct link {
/*
* Work structure for scheduling periodic watchdog monitoring.
+ * This work must be scheduled on the kernel workqueue, while
+ * all other work structures must be queued on the mac80211
+ * workqueue. This guarantees that the watchdog can schedule
+ * other work structures and wait for their completion in order
+ * to bring the device/driver back into the desired state.
*/
struct delayed_work watchdog_work;
};
@@ -455,6 +463,7 @@ struct rt2x00lib_erp {
short eifs;
u16 beacon_int;
+ u16 ht_opmode;
};
/*
@@ -520,6 +529,11 @@ struct rt2x00lib_ops {
irq_handler_t irq_handler_thread;
/*
+ * TX status tasklet handler.
+ */
+ void (*txstatus_tasklet) (unsigned long data);
+
+ /*
* Device init handlers.
*/
int (*probe_hw) (struct rt2x00_dev *rt2x00dev);
@@ -558,18 +572,15 @@ struct rt2x00lib_ops {
/*
* TX control handlers
*/
- void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+ void (*write_tx_desc) (struct queue_entry *entry,
struct txentry_desc *txdesc);
void (*write_tx_data) (struct queue_entry *entry,
struct txentry_desc *txdesc);
void (*write_beacon) (struct queue_entry *entry,
struct txentry_desc *txdesc);
int (*get_tx_data_len) (struct queue_entry *entry);
- void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue);
- void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue);
+ void (*kick_tx_queue) (struct data_queue *queue);
+ void (*kill_tx_queue) (struct data_queue *queue);
/*
* RX control handlers
@@ -597,7 +608,8 @@ struct rt2x00lib_ops {
#define CONFIG_UPDATE_BSSID ( 1 << 3 )
void (*config_erp) (struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp);
+ struct rt2x00lib_erp *erp,
+ u32 changed);
void (*config_ant) (struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant);
void (*config) (struct rt2x00_dev *rt2x00dev,
@@ -651,6 +663,7 @@ enum rt2x00_flags {
DRIVER_REQUIRE_DMA,
DRIVER_REQUIRE_COPY_IV,
DRIVER_REQUIRE_L2PAD,
+ DRIVER_REQUIRE_TXSTATUS_FIFO,
/*
* Driver features
@@ -698,6 +711,7 @@ struct rt2x00_dev {
struct ieee80211_hw *hw;
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
enum ieee80211_band curr_band;
+ int curr_freq;
/*
* If enabled, the debugfs interface structures
@@ -850,11 +864,6 @@ struct rt2x00_dev {
struct ieee80211_low_level_stats low_level_stats;
/*
- * RX configuration information.
- */
- struct ieee80211_rx_status rx_status;
-
- /*
* Scheduled work.
* NOTE: intf_work will use ieee80211_iterate_active_interfaces()
* which means it cannot be placed on the hw->workqueue
@@ -862,6 +871,12 @@ struct rt2x00_dev {
*/
struct work_struct intf_work;
+ /**
+ * Scheduled work for TX/RX done handling (USB devices)
+ */
+ struct work_struct rxdone_work;
+ struct work_struct txdone_work;
+
/*
* Data queue arrays for RX, TX and Beacon.
* The Beacon array also contains the Atim queue
@@ -882,6 +897,16 @@ struct rt2x00_dev {
* and interrupt thread routine.
*/
u32 irqvalue[2];
+
+ /*
+ * FIFO for storing tx status reports between isr and tasklet.
+ */
+ struct kfifo txstatus_fifo;
+
+ /*
+ * Tasklet for processing tx status reports (rt2800pci).
+ */
+ struct tasklet_struct txstatus_tasklet;
};
/*
@@ -1016,17 +1041,15 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev)
/**
* rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to map.
+ * @entry: Pointer to &struct queue_entry
*/
-void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+void rt2x00queue_map_txskb(struct queue_entry *entry);
/**
* rt2x00queue_unmap_skb - Unmap a skb from DMA.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to unmap.
+ * @entry: Pointer to &struct queue_entry
*/
-void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+void rt2x00queue_unmap_skb(struct queue_entry *entry);
/**
* rt2x00queue_get_queue - Convert queue index to queue pointer
@@ -1069,10 +1092,11 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
*/
void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev);
+void rt2x00lib_dmadone(struct queue_entry *entry);
void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc);
-void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
- struct queue_entry *entry);
+void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status);
+void rt2x00lib_rxdone(struct queue_entry *entry);
/*
* mac80211 handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 953dc4f2c6af..54ffb5aeb34e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -81,7 +81,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
- struct ieee80211_bss_conf *bss_conf)
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changed)
{
struct rt2x00lib_erp erp;
@@ -102,7 +103,10 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
/* Update global beacon interval time, this is needed for PS support */
rt2x00dev->beacon_int = bss_conf->beacon_int;
- rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);
+ if (changed & BSS_CHANGED_HT)
+ erp.ht_opmode = bss_conf->ht_operation_mode;
+
+ rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed);
}
static inline
@@ -126,25 +130,17 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
* ANTENNA_SW_DIVERSITY state to the driver.
* If that happens, fallback to hardware defaults,
* or our own default.
- * If diversity handling is active for a particular antenna,
- * we shouldn't overwrite that antenna.
- * The calls to rt2x00lib_config_antenna_check()
- * might have caused that we restore back to the already
- * active setting. If that has happened we can quit.
*/
if (!(ant->flags & ANTENNA_RX_DIVERSITY))
config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx);
- else
+ 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
+ else if (config.tx == ANTENNA_SW_DIVERSITY)
config.tx = active->tx;
- if (config.rx == active->rx && config.tx == active->tx)
- return;
-
/*
* Antenna setup changes require the RX to be disabled,
* else the changes will be ignored by the device.
@@ -209,10 +205,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
rt2x00link_reset_tuner(rt2x00dev, false);
rt2x00dev->curr_band = conf->channel->band;
+ rt2x00dev->curr_freq = conf->channel->center_freq;
rt2x00dev->tx_power = conf->power_level;
rt2x00dev->short_retry = conf->short_frame_max_tx_count;
rt2x00dev->long_retry = conf->long_frame_max_tx_count;
-
- rt2x00dev->rx_status.band = conf->channel->band;
- rt2x00dev->rx_status.freq = conf->channel->center_freq;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index 583dacd8d241..5e9074bf2b8e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -31,15 +31,14 @@
enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key)
{
- switch (key->alg) {
- case ALG_WEP:
- if (key->keylen == WLAN_KEY_LEN_WEP40)
- return CIPHER_WEP64;
- else
- return CIPHER_WEP128;
- case ALG_TKIP:
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ return CIPHER_WEP64;
+ case WLAN_CIPHER_SUITE_WEP104:
+ return CIPHER_WEP128;
+ case WLAN_CIPHER_SUITE_TKIP:
return CIPHER_TKIP;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
return CIPHER_AES;
default:
return CIPHER_NONE;
@@ -95,7 +94,7 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
overhead += key->iv_len;
if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
- if (key->alg == ALG_TKIP)
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
overhead += 8;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index cea81e4c5c82..fcdb6b0dc40f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -334,12 +334,12 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
if (*offset)
return 0;
- data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL);
+ data = kcalloc(lines, MAX_LINE_LENGTH, GFP_KERNEL);
if (!data)
return -ENOMEM;
temp = data +
- sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n");
+ sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
queue_for_each(intf->rt2x00dev, queue) {
spin_lock_irqsave(&queue->lock, irqflags);
@@ -347,8 +347,8 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
queue->count, queue->limit, queue->length,
queue->index[Q_INDEX],
- queue->index[Q_INDEX_DONE],
- queue->index[Q_INDEX_CRYPTO]);
+ queue->index[Q_INDEX_DMA_DONE],
+ queue->index[Q_INDEX_DONE]);
spin_unlock_irqrestore(&queue->lock, irqflags);
}
@@ -382,7 +382,7 @@ static ssize_t rt2x00debug_read_crypto_stats(struct file *file,
loff_t *offset)
{
struct rt2x00debug_intf *intf = file->private_data;
- char *name[] = { "WEP64", "WEP128", "TKIP", "AES" };
+ static const char * const name[] = { "WEP64", "WEP128", "TKIP", "AES" };
char *data;
char *temp;
size_t size;
@@ -484,6 +484,9 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \
if (index >= debug->__name.word_count) \
return -EINVAL; \
\
+ if (length > sizeof(line)) \
+ return -EINVAL; \
+ \
if (copy_from_user(line, buf, length)) \
return -EFAULT; \
\
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 585e8166f22a..5ba79b935f09 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -250,6 +251,13 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
}
EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
+void rt2x00lib_dmadone(struct queue_entry *entry)
+{
+ clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+ rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
+}
+EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);
+
void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc)
{
@@ -266,7 +274,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
/*
* Unmap the skb.
*/
- rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
+ rt2x00queue_unmap_skb(entry);
/*
* Remove the extra tx headroom from the skb.
@@ -383,15 +391,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
* send the status report back.
*/
if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
- /*
- * Only PCI and SOC devices process the tx status in process
- * context. Hence use ieee80211_tx_status for PCI and SOC
- * devices and stick to ieee80211_tx_status_irqsafe for USB.
- */
- if (rt2x00_is_usb(rt2x00dev))
- ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
- else
- ieee80211_tx_status(rt2x00dev->hw, entry->skb);
+ ieee80211_tx_status(rt2x00dev->hw, entry->skb);
else
dev_kfree_skb_any(entry->skb);
@@ -403,7 +403,6 @@ void rt2x00lib_txdone(struct queue_entry *entry,
rt2x00dev->ops->lib->clear_entry(entry);
- clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
/*
@@ -416,65 +415,89 @@ void rt2x00lib_txdone(struct queue_entry *entry,
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
+void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status)
+{
+ struct txdone_entry_desc txdesc;
+
+ txdesc.flags = 0;
+ __set_bit(status, &txdesc.flags);
+ txdesc.retry = 0;
+
+ rt2x00lib_txdone(entry, &txdesc);
+}
+EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo);
+
static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
struct rxdone_entry_desc *rxdesc)
{
struct ieee80211_supported_band *sband;
const struct rt2x00_rate *rate;
unsigned int i;
- int signal;
- int type;
+ int signal = rxdesc->signal;
+ int type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
- /*
- * For non-HT rates the MCS value needs to contain the
- * actually used rate modulation (CCK or OFDM).
- */
- if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
- signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal);
- else
- signal = rxdesc->signal;
-
- type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
-
- sband = &rt2x00dev->bands[rt2x00dev->curr_band];
- for (i = 0; i < sband->n_bitrates; i++) {
- rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
-
- if (((type == RXDONE_SIGNAL_PLCP) &&
- (rate->plcp == signal)) ||
- ((type == RXDONE_SIGNAL_BITRATE) &&
- (rate->bitrate == signal)) ||
- ((type == RXDONE_SIGNAL_MCS) &&
- (rate->mcs == signal))) {
- return i;
+ switch (rxdesc->rate_mode) {
+ case RATE_MODE_CCK:
+ case RATE_MODE_OFDM:
+ /*
+ * For non-HT rates the MCS value needs to contain the
+ * actually used rate modulation (CCK or OFDM).
+ */
+ if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
+ signal = RATE_MCS(rxdesc->rate_mode, signal);
+
+ sband = &rt2x00dev->bands[rt2x00dev->curr_band];
+ for (i = 0; i < sband->n_bitrates; i++) {
+ rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
+ if (((type == RXDONE_SIGNAL_PLCP) &&
+ (rate->plcp == signal)) ||
+ ((type == RXDONE_SIGNAL_BITRATE) &&
+ (rate->bitrate == signal)) ||
+ ((type == RXDONE_SIGNAL_MCS) &&
+ (rate->mcs == signal))) {
+ return i;
+ }
}
+ break;
+ case RATE_MODE_HT_MIX:
+ case RATE_MODE_HT_GREENFIELD:
+ if (signal >= 0 && signal <= 76)
+ return signal;
+ break;
+ default:
+ break;
}
WARNING(rt2x00dev, "Frame received with unrecognized signal, "
- "signal=0x%.4x, type=%d.\n", signal, type);
+ "mode=0x%.4x, signal=0x%.4x, type=%d.\n",
+ rxdesc->rate_mode, signal, type);
return 0;
}
-void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
- struct queue_entry *entry)
+void rt2x00lib_rxdone(struct queue_entry *entry)
{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct rxdone_entry_desc rxdesc;
struct sk_buff *skb;
- struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
+ struct ieee80211_rx_status *rx_status;
unsigned int header_length;
int rate_idx;
+
+ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+ goto submit_entry;
+
/*
* Allocate a new sk_buffer. If no new buffer available, drop the
* received frame and reuse the existing buffer.
*/
- skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry);
+ skb = rt2x00queue_alloc_rxskb(entry);
if (!skb)
- return;
+ goto submit_entry;
/*
* Unmap the skb.
*/
- rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
+ rt2x00queue_unmap_skb(entry);
/*
* Extract the RXD details.
@@ -509,57 +532,44 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
skb_trim(entry->skb, rxdesc.size);
/*
- * Check if the frame was received using HT. In that case,
- * the rate is the MCS index and should be passed to mac80211
- * directly. Otherwise we need to translate the signal to
- * the correct bitrate index.
+ * Translate the signal to the correct bitrate index.
*/
- if (rxdesc.rate_mode == RATE_MODE_CCK ||
- rxdesc.rate_mode == RATE_MODE_OFDM) {
- rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
- } else {
+ rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
+ if (rxdesc.rate_mode == RATE_MODE_HT_MIX ||
+ rxdesc.rate_mode == RATE_MODE_HT_GREENFIELD)
rxdesc.flags |= RX_FLAG_HT;
- rate_idx = rxdesc.signal;
- }
/*
* Update extra components
*/
rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc);
rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
+ /*
+ * Initialize RX status information, and send frame
+ * to mac80211.
+ */
+ rx_status = IEEE80211_SKB_RXCB(entry->skb);
rx_status->mactime = rxdesc.timestamp;
+ rx_status->band = rt2x00dev->curr_band;
+ rx_status->freq = rt2x00dev->curr_freq;
rx_status->rate_idx = rate_idx;
rx_status->signal = rxdesc.rssi;
rx_status->flag = rxdesc.flags;
rx_status->antenna = rt2x00dev->link.ant.active.rx;
- /*
- * Send frame to mac80211 & debugfs.
- * mac80211 will clean up the skb structure.
- */
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
- memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status));
-
- /*
- * Currently only PCI and SOC devices handle rx interrupts in process
- * context. Hence, use ieee80211_rx_irqsafe for USB and ieee80211_rx_ni
- * for PCI and SOC devices.
- */
- if (rt2x00_is_usb(rt2x00dev))
- ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb);
- else
- ieee80211_rx_ni(rt2x00dev->hw, entry->skb);
+ ieee80211_rx_ni(rt2x00dev->hw, entry->skb);
/*
* Replace the skb with the freshly allocated one.
*/
entry->skb = skb;
- entry->flags = 0;
+submit_entry:
rt2x00dev->ops->lib->clear_entry(entry);
-
rt2x00queue_index_inc(entry->queue, Q_INDEX);
+ rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
}
EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
@@ -710,7 +720,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
for (i = 0; i < spec->num_channels; i++) {
rt2x00lib_channel(&channels[i],
spec->channels[i].channel,
- spec->channels_info[i].tx_power1, i);
+ spec->channels_info[i].max_power, i);
}
/*
@@ -806,6 +816,30 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;
/*
+ * Allocate tx status FIFO for driver use.
+ */
+ if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) &&
+ rt2x00dev->ops->lib->txstatus_tasklet) {
+ /*
+ * 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.
+ */
+ status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512,
+ GFP_KERNEL);
+ if (status)
+ return status;
+
+ /* tasklet for processing the tx status reports. */
+ tasklet_init(&rt2x00dev->txstatus_tasklet,
+ rt2x00dev->ops->lib->txstatus_tasklet,
+ (unsigned long)rt2x00dev);
+
+ }
+
+ /*
* Register HW.
*/
status = ieee80211_register_hw(rt2x00dev->hw);
@@ -902,10 +936,8 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
/* Enable the radio */
retval = rt2x00lib_enable_radio(rt2x00dev);
- if (retval) {
- rt2x00queue_uninitialize(rt2x00dev);
+ if (retval)
return retval;
- }
set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags);
@@ -1017,6 +1049,18 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
* Stop all work.
*/
cancel_work_sync(&rt2x00dev->intf_work);
+ cancel_work_sync(&rt2x00dev->rxdone_work);
+ cancel_work_sync(&rt2x00dev->txdone_work);
+
+ /*
+ * Free the tx status fifo.
+ */
+ kfifo_free(&rt2x00dev->txstatus_fifo);
+
+ /*
+ * Kill the tx status tasklet.
+ */
+ tasklet_kill(&rt2x00dev->txstatus_tasklet);
/*
* Uninitialize device.
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index b818a43c4672..f0e1eb72befc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -63,6 +63,9 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n",
fw->data[fw->size - 4], fw->data[fw->size - 3]);
+ snprintf(rt2x00dev->hw->wiphy->fw_version,
+ sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d",
+ fw->data[fw->size - 4], fw->data[fw->size - 3]);
retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size);
switch (retval) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
index c004cd3a8847..c637bcaec5f8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -54,6 +54,17 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
*/
if (txrate->flags & IEEE80211_TX_RC_MCS) {
txdesc->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->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->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
@@ -62,9 +73,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
/*
- * Convert flags
+ * 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)
+ 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);
/*
@@ -74,7 +87,13 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
txdesc->rate_mode = RATE_MODE_HT_MIX;
if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
txdesc->rate_mode = RATE_MODE_HT_GREENFIELD;
- if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+
+ /*
+ * Set 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);
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index dc5c6574aaf4..619da23b7b56 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -86,7 +86,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
const u8 *mac, const u8 *bssid);
void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
- struct ieee80211_bss_conf *conf);
+ struct ieee80211_bss_conf *conf,
+ u32 changed);
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
struct antenna_setup ant);
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
@@ -99,18 +100,15 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
/**
* rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @queue: The queue for which the skb will be applicable.
+ * @entry: The entry for which the skb will be applicable.
*/
-struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
- struct queue_entry *entry);
+struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry);
/**
* rt2x00queue_free_skb - free a skb
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to free.
+ * @entry: The entry for which the skb will be applicable.
*/
-void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+void rt2x00queue_free_skb(struct queue_entry *entry);
/**
* rt2x00queue_align_frame - Align 802.11 frame to 4-byte boundary
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 666cef3f8472..b971d8798ebf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -188,7 +188,6 @@ static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
{
struct link_ant *ant = &rt2x00dev->link.ant;
- unsigned int flags = ant->flags;
/*
* Determine if software diversity is enabled for
@@ -196,13 +195,13 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
* Always perform this check since within the link
* tuner interval the configuration might have changed.
*/
- flags &= ~ANTENNA_RX_DIVERSITY;
- flags &= ~ANTENNA_TX_DIVERSITY;
+ ant->flags &= ~ANTENNA_RX_DIVERSITY;
+ ant->flags &= ~ANTENNA_TX_DIVERSITY;
if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
- flags |= ANTENNA_RX_DIVERSITY;
+ ant->flags |= ANTENNA_RX_DIVERSITY;
if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
- flags |= ANTENNA_TX_DIVERSITY;
+ ant->flags |= ANTENNA_TX_DIVERSITY;
if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
!(ant->flags & ANTENNA_TX_DIVERSITY)) {
@@ -210,9 +209,6 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
return true;
}
- /* Update flags */
- ant->flags = flags;
-
/*
* If we have only sampled the data over the last period
* we should now harvest the data. Otherwise just evaluate
@@ -240,6 +236,12 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
/*
+ * No need to update the stats for !=STA interfaces
+ */
+ if (!rt2x00dev->intf_sta_count)
+ return;
+
+ /*
* Frame was received successfully since non-succesfull
* frames would have been dropped by the hardware.
*/
@@ -415,8 +417,7 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev)
!test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags))
return;
- ieee80211_queue_delayed_work(rt2x00dev->hw,
- &link->watchdog_work, WATCHDOG_INTERVAL);
+ schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL);
}
void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -440,8 +441,7 @@ static void rt2x00link_watchdog(struct work_struct *work)
rt2x00dev->ops->lib->watchdog(rt2x00dev);
if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
- ieee80211_queue_delayed_work(rt2x00dev->hw,
- &link->watchdog_work, WATCHDOG_INTERVAL);
+ schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL);
}
void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 235e037e6509..c3c206a97d54 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -669,8 +669,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
* When the erp information has changed, we should perform
* additional configuration steps. For all other changes we are done.
*/
- if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT))
- rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
+ if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE |
+ BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES |
+ BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT))
+ rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes);
}
EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 63c2cc408e15..2449d785cf8d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -84,7 +84,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
/*
* Send the frame to rt2x00lib for further processing.
*/
- rt2x00lib_rxdone(rt2x00dev, entry);
+ rt2x00lib_rxdone(entry);
}
}
EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index a3401d301058..e360d287defb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
<http://rt2x00.serialmonkey.com>
@@ -32,9 +33,9 @@
#include "rt2x00.h"
#include "rt2x00lib.h"
-struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
- struct queue_entry *entry)
+struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry)
{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct sk_buff *skb;
struct skb_frame_desc *skbdesc;
unsigned int frame_size;
@@ -96,41 +97,42 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
return skb;
}
-void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+void rt2x00queue_map_txskb(struct queue_entry *entry)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+ struct device *dev = entry->queue->rt2x00dev->dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
skbdesc->skb_dma =
- dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
+ dma_map_single(dev, entry->skb->data, entry->skb->len, DMA_TO_DEVICE);
skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
}
EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
-void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+void rt2x00queue_unmap_skb(struct queue_entry *entry)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+ struct device *dev = entry->queue->rt2x00dev->dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) {
- dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
+ dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len,
DMA_FROM_DEVICE);
skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX;
- }
-
- if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
- dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
+ } else if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
+ dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len,
DMA_TO_DEVICE);
skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
}
}
EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb);
-void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+void rt2x00queue_free_skb(struct queue_entry *entry)
{
- if (!skb)
+ if (!entry->skb)
return;
- rt2x00queue_unmap_skb(rt2x00dev, skb);
- dev_kfree_skb_any(skb);
+ rt2x00queue_unmap_skb(entry);
+ dev_kfree_skb_any(entry->skb);
+ entry->skb = NULL;
}
void rt2x00queue_align_frame(struct sk_buff *skb)
@@ -311,7 +313,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
/*
* Initialize information from queue
*/
- txdesc->queue = entry->queue->qid;
+ txdesc->qid = entry->queue->qid;
txdesc->cw_min = entry->queue->cw_min;
txdesc->cw_max = entry->queue->cw_max;
txdesc->aifs = entry->queue->aifs;
@@ -439,7 +441,7 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry,
* Map the skb to DMA.
*/
if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
- rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+ rt2x00queue_map_txskb(entry);
return 0;
}
@@ -448,15 +450,14 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
struct data_queue *queue = entry->queue;
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ queue->rt2x00dev->ops->lib->write_tx_desc(entry, txdesc);
/*
* All processing on the frame has been completed, this means
* it is now ready to be dumped to userspace through debugfs.
*/
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb);
+ rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb);
}
static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
@@ -476,7 +477,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
*/
if (rt2x00queue_threshold(queue) ||
!test_bit(ENTRY_TXD_BURST, &txdesc->flags))
- rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
+ rt2x00dev->ops->lib->kick_tx_queue(queue);
}
int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
@@ -491,7 +492,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
if (unlikely(rt2x00queue_full(queue)))
return -ENOBUFS;
- if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
+ if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA,
+ &entry->flags))) {
ERROR(queue->rt2x00dev,
"Arrived at non-free entry in the non-full queue %d.\n"
"Please file bug report to %s.\n",
@@ -586,11 +588,10 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
/*
* Clean up the beacon skb.
*/
- rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb);
- intf->beacon->skb = NULL;
+ rt2x00queue_free_skb(intf->beacon);
if (!enable_beacon) {
- rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON);
+ rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue);
mutex_unlock(&intf->beacon_skb_mutex);
return 0;
}
@@ -625,6 +626,51 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
return 0;
}
+void rt2x00queue_for_each_entry(struct data_queue *queue,
+ enum queue_index start,
+ enum queue_index end,
+ void (*fn)(struct queue_entry *entry))
+{
+ unsigned long irqflags;
+ unsigned int index_start;
+ unsigned int index_end;
+ unsigned int i;
+
+ if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) {
+ ERROR(queue->rt2x00dev,
+ "Entry requested from invalid index range (%d - %d)\n",
+ start, end);
+ return;
+ }
+
+ /*
+ * Only protect the range we are going to loop over,
+ * if during our loop a extra entry is set to pending
+ * it should not be kicked during this run, since it
+ * is part of another TX operation.
+ */
+ spin_lock_irqsave(&queue->lock, irqflags);
+ index_start = queue->index[start];
+ index_end = queue->index[end];
+ spin_unlock_irqrestore(&queue->lock, irqflags);
+
+ /*
+ * Start from the TX done pointer, this guarentees that we will
+ * 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]);
+ } else {
+ for (i = index_start; i < queue->limit; i++)
+ fn(&queue->entries[i]);
+
+ for (i = 0; i < index_end; i++)
+ fn(&queue->entries[i]);
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry);
+
struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
const enum data_queue_qid queue)
{
@@ -686,13 +732,13 @@ 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;
+
if (index == Q_INDEX) {
queue->length++;
- queue->last_index = jiffies;
} else if (index == Q_INDEX_DONE) {
queue->length--;
queue->count++;
- queue->last_index_done = jiffies;
}
spin_unlock_irqrestore(&queue->lock, irqflags);
@@ -701,14 +747,17 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
static void rt2x00queue_reset(struct data_queue *queue)
{
unsigned long irqflags;
+ unsigned int i;
spin_lock_irqsave(&queue->lock, irqflags);
queue->count = 0;
queue->length = 0;
- queue->last_index = jiffies;
- queue->last_index_done = jiffies;
- memset(queue->index, 0, sizeof(queue->index));
+
+ for (i = 0; i < Q_INDEX_MAX; i++) {
+ queue->index[i] = 0;
+ queue->last_action[i] = jiffies;
+ }
spin_unlock_irqrestore(&queue->lock, irqflags);
}
@@ -718,7 +767,7 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
struct data_queue *queue;
txall_queue_for_each(rt2x00dev, queue)
- rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid);
+ rt2x00dev->ops->lib->kill_tx_queue(queue);
}
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -730,9 +779,9 @@ void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
rt2x00queue_reset(queue);
for (i = 0; i < queue->limit; i++) {
- queue->entries[i].flags = 0;
-
rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
+ if (queue->qid == QID_RX)
+ rt2x00queue_index_inc(queue, Q_INDEX);
}
}
}
@@ -755,7 +804,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
* Allocate all queue entries.
*/
entry_size = sizeof(*entries) + qdesc->priv_size;
- entries = kzalloc(queue->limit * entry_size, GFP_KERNEL);
+ entries = kcalloc(queue->limit, entry_size, GFP_KERNEL);
if (!entries)
return -ENOMEM;
@@ -780,8 +829,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
return 0;
}
-static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue)
+static void rt2x00queue_free_skbs(struct data_queue *queue)
{
unsigned int i;
@@ -789,19 +837,17 @@ static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev,
return;
for (i = 0; i < queue->limit; i++) {
- if (queue->entries[i].skb)
- rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb);
+ rt2x00queue_free_skb(&queue->entries[i]);
}
}
-static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue)
+static int rt2x00queue_alloc_rxskbs(struct data_queue *queue)
{
unsigned int i;
struct sk_buff *skb;
for (i = 0; i < queue->limit; i++) {
- skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]);
+ skb = rt2x00queue_alloc_rxskb(&queue->entries[i]);
if (!skb)
return -ENOMEM;
queue->entries[i].skb = skb;
@@ -836,7 +882,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
goto exit;
}
- status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx);
+ status = rt2x00queue_alloc_rxskbs(rt2x00dev->rx);
if (status)
goto exit;
@@ -854,7 +900,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
- rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx);
+ rt2x00queue_free_skbs(rt2x00dev->rx);
queue_for_each(rt2x00dev, queue) {
kfree(queue->entries);
@@ -891,7 +937,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->data_queues = 2 + rt2x00dev->ops->tx_queues + req_atim;
- queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL);
+ queue = kcalloc(rt2x00dev->data_queues, sizeof(*queue), GFP_KERNEL);
if (!queue) {
ERROR(rt2x00dev, "Queue allocation failed.\n");
return -ENOMEM;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 191e7775a9c0..d81d85f34866 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -268,6 +268,7 @@ struct txdone_entry_desc {
* @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU.
* @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth.
* @ENTRY_TXD_HT_SHORT_GI: Use short GI.
+ * @ENTRY_TXD_HT_MIMO_PS: The receiving STA is in dynamic SM PS mode.
*/
enum txentry_desc_flags {
ENTRY_TXD_RTS_FRAME,
@@ -286,6 +287,7 @@ enum txentry_desc_flags {
ENTRY_TXD_HT_AMPDU,
ENTRY_TXD_HT_BW_40,
ENTRY_TXD_HT_SHORT_GI,
+ ENTRY_TXD_HT_MIMO_PS,
};
/**
@@ -294,7 +296,7 @@ enum txentry_desc_flags {
* Summary of information for the frame descriptor before sending a TX frame.
*
* @flags: Descriptor flags (See &enum queue_entry_flags).
- * @queue: Queue identification (See &enum data_queue_qid).
+ * @qid: Queue identification (See &enum data_queue_qid).
* @length: Length of the entire frame.
* @header_length: Length of 802.11 header.
* @length_high: PLCP length high word.
@@ -320,7 +322,7 @@ enum txentry_desc_flags {
struct txentry_desc {
unsigned long flags;
- enum data_queue_qid queue;
+ enum data_queue_qid qid;
u16 length;
u16 header_length;
@@ -358,17 +360,17 @@ struct txentry_desc {
* @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data
* transfer (either TX or RX depending on the queue). The entry should
* only be touched after the device has signaled it is done with it.
- * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data
- * encryption or decryption. The entry should only be touched after
- * the device has signaled it is done with it.
* @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting
* for the signal to start sending.
+ * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured
+ * while transfering the data to the hardware. No TX status report will
+ * be expected from the hardware.
*/
enum queue_entry_flags {
ENTRY_BCN_ASSIGNED,
ENTRY_OWNER_DEVICE_DATA,
- ENTRY_OWNER_DEVICE_CRYPTO,
ENTRY_DATA_PENDING,
+ ENTRY_DATA_IO_FAILED
};
/**
@@ -399,18 +401,18 @@ struct queue_entry {
*
* @Q_INDEX: Index pointer to the current entry in the queue, if this entry is
* owned by the hardware then the queue is considered to be full.
+ * @Q_INDEX_DMA_DONE: Index pointer for the next entry which will have been
+ * transfered to the hardware.
* @Q_INDEX_DONE: Index pointer to the next entry which will be completed by
* the hardware and for which we need to run the txdone handler. If this
* entry is not owned by the hardware the queue is considered to be empty.
- * @Q_INDEX_CRYPTO: Index pointer to the next entry which encryption/decription
- * will be completed by the hardware next.
* @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size
* of the index array.
*/
enum queue_index {
Q_INDEX,
+ Q_INDEX_DMA_DONE,
Q_INDEX_DONE,
- Q_INDEX_CRYPTO,
Q_INDEX_MAX,
};
@@ -446,13 +448,12 @@ struct data_queue {
enum data_queue_qid qid;
spinlock_t lock;
- unsigned long last_index;
- unsigned long last_index_done;
unsigned int count;
unsigned short limit;
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;
@@ -565,6 +566,22 @@ struct data_queue_desc {
queue_loop(__entry, (__dev)->tx, queue_end(__dev))
/**
+ * rt2x00queue_for_each_entry - Loop through all entries in the queue
+ * @queue: Pointer to @data_queue
+ * @start: &enum queue_index Pointer to start index
+ * @end: &enum queue_index Pointer to end index
+ * @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.
+ */
+void rt2x00queue_for_each_entry(struct data_queue *queue,
+ enum queue_index start,
+ enum queue_index end,
+ void (*fn)(struct queue_entry *entry));
+
+/**
* rt2x00queue_empty - Check if the queue is empty.
* @queue: Queue to check if empty.
*/
@@ -601,12 +618,23 @@ static inline int rt2x00queue_threshold(struct data_queue *queue)
}
/**
- * rt2x00queue_timeout - Check if a timeout occured for this queue
+ * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts
* @queue: Queue to check.
*/
static inline int rt2x00queue_timeout(struct data_queue *queue)
{
- return time_after(queue->last_index, queue->last_index_done + (HZ / 10));
+ return time_after(queue->last_action[Q_INDEX_DMA_DONE],
+ queue->last_action[Q_INDEX_DONE] + (HZ / 10));
+}
+
+/**
+ * rt2x00queue_timeout - Check if a timeout occured for DMA transfers
+ * @queue: Queue to check.
+ */
+static inline int rt2x00queue_dma_timeout(struct data_queue *queue)
+{
+ return time_after(queue->last_action[Q_INDEX],
+ queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10));
}
/**
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index ff3a36622d1b..b3317df7a7d4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -167,137 +168,137 @@ EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read);
/*
* TX data handlers.
*/
-static void rt2x00usb_interrupt_txdone(struct urb *urb)
+static void rt2x00usb_work_txdone_entry(struct queue_entry *entry)
{
- struct queue_entry *entry = (struct queue_entry *)urb->context;
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct txdone_entry_desc txdesc;
-
- if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
- !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
- return;
-
/*
- * Obtain the status about this packet.
- * Note that when the status is 0 it does not mean the
+ * If the transfer to hardware succeeded, it does not mean the
* frame was send out correctly. It only means the frame
* was succesfully pushed to the hardware, we have no
* way to determine the transmission status right now.
* (Only indirectly by looking at the failed TX counters
* in the register).
*/
- txdesc.flags = 0;
- if (!urb->status)
- __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
+ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+ rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
else
- __set_bit(TXDONE_FAILURE, &txdesc.flags);
- txdesc.retry = 0;
-
- rt2x00lib_txdone(entry, &txdesc);
+ rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
}
-static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
+static void rt2x00usb_work_txdone(struct work_struct *work)
{
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
- struct queue_entry_priv_usb *entry_priv = entry->priv_data;
- u32 length;
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, txdone_work);
+ struct data_queue *queue;
+ struct queue_entry *entry;
- if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) {
- /*
- * USB devices cannot blindly pass the skb->len as the
- * length of the data to usb_fill_bulk_urb. Pass the skb
- * to the driver to determine what the length should be.
- */
- length = rt2x00dev->ops->lib->get_tx_data_len(entry);
+ tx_queue_for_each(rt2x00dev, queue) {
+ while (!rt2x00queue_empty(queue)) {
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
- usb_fill_bulk_urb(entry_priv->urb, usb_dev,
- usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
- entry->skb->data, length,
- rt2x00usb_interrupt_txdone, entry);
+ if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ break;
- usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+ rt2x00usb_work_txdone_entry(entry);
+ }
}
}
-void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt2x00usb_interrupt_txdone(struct urb *urb)
{
- struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
- unsigned long irqflags;
- unsigned int index;
- unsigned int index_done;
- unsigned int i;
+ struct queue_entry *entry = (struct queue_entry *)urb->context;
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+
+ if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ return;
/*
- * Only protect the range we are going to loop over,
- * if during our loop a extra entry is set to pending
- * it should not be kicked during this run, since it
- * is part of another TX operation.
+ * Report the frame as DMA done
*/
- spin_lock_irqsave(&queue->lock, irqflags);
- index = queue->index[Q_INDEX];
- index_done = queue->index[Q_INDEX_DONE];
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ rt2x00lib_dmadone(entry);
/*
- * Start from the TX done pointer, this guarentees that we will
- * send out all frames in the correct order.
+ * Check if the frame was correctly uploaded
*/
- if (index_done < index) {
- for (i = index_done; i < index; i++)
- rt2x00usb_kick_tx_entry(&queue->entries[i]);
- } else {
- for (i = index_done; i < queue->limit; i++)
- rt2x00usb_kick_tx_entry(&queue->entries[i]);
+ if (urb->status)
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
- for (i = 0; i < index; i++)
- rt2x00usb_kick_tx_entry(&queue->entries[i]);
- }
+ /*
+ * Schedule the delayed work for reading the TX status
+ * from the device.
+ */
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+ test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
}
-EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
-void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
{
- struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
- struct queue_entry_priv_usb *entry_priv;
- struct queue_entry_priv_usb_bcn *bcn_priv;
- unsigned int i;
- bool kill_guard;
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;
+ u32 length;
+
+ if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
+ return;
/*
- * When killing the beacon queue, we must also kill
- * the beacon guard byte.
+ * USB devices cannot blindly pass the skb->len as the
+ * length of the data to usb_fill_bulk_urb. Pass the skb
+ * to the driver to determine what the length should be.
*/
- kill_guard =
- (qid == QID_BEACON) &&
- (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags));
+ length = rt2x00dev->ops->lib->get_tx_data_len(entry);
+
+ usb_fill_bulk_urb(entry_priv->urb, usb_dev,
+ usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
+ entry->skb->data, length,
+ rt2x00usb_interrupt_txdone, entry);
+
+ if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+ rt2x00lib_dmadone(entry);
+ }
+}
+
+void rt2x00usb_kick_tx_queue(struct data_queue *queue)
+{
+ rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+ rt2x00usb_kick_tx_entry);
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
+
+static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
+{
+ 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;
+
+ usb_kill_urb(entry_priv->urb);
/*
- * Cancel all entries.
+ * Kill guardian urb (if required by driver).
*/
- for (i = 0; i < queue->limit; i++) {
- entry_priv = queue->entries[i].priv_data;
- usb_kill_urb(entry_priv->urb);
+ if ((entry->queue->qid == QID_BEACON) &&
+ (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
+ usb_kill_urb(bcn_priv->guardian_urb);
+}
- /*
- * Kill guardian urb (if required by driver).
- */
- if (kill_guard) {
- bcn_priv = queue->entries[i].priv_data;
- usb_kill_urb(bcn_priv->guardian_urb);
- }
- }
+void rt2x00usb_kill_tx_queue(struct data_queue *queue)
+{
+ rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+ rt2x00usb_kill_tx_entry);
}
EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
-static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
+static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
{
- struct queue_entry_priv_usb *entry_priv;
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
unsigned short threshold = queue->threshold;
- WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid);
+ WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
+ " invoke forced forced reset", queue->qid);
/*
* Temporarily disable the TX queue, this will force mac80211
@@ -307,20 +308,33 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
* queue from being enabled during the txdone handler.
*/
queue->threshold = queue->limit;
- ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid);
+ ieee80211_stop_queue(rt2x00dev->hw, queue->qid);
/*
- * Reset all currently uploaded TX frames.
+ * Kill all entries in the queue, afterwards we need to
+ * wait a bit for all URBs to be cancelled.
*/
- while (!rt2x00queue_empty(queue)) {
- entry_priv = rt2x00queue_get_entry(queue, Q_INDEX_DONE)->priv_data;
- usb_kill_urb(entry_priv->urb);
+ rt2x00usb_kill_tx_queue(queue);
- /*
- * We need a short delay here to wait for
- * the URB to be canceled and invoked the tx_done handler.
- */
- udelay(200);
+ /*
+ * In case that a driver has overriden the txdone_work
+ * function, we invoke the TX done through there.
+ */
+ rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work);
+
+ /*
+ * Security measure: if the driver did override the
+ * txdone_work function, and the hardware did arrive
+ * in a state which causes it to malfunction, it is
+ * possible that the driver couldn't handle the txdone
+ * event correctly. So after giving the driver the
+ * chance to cleanup, we now force a cleanup of any
+ * leftovers.
+ */
+ if (!rt2x00queue_empty(queue)) {
+ WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
+ " status handling failed, invoke hard reset", queue->qid);
+ rt2x00usb_work_txdone(&rt2x00dev->txdone_work);
}
/*
@@ -328,7 +342,15 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
* queue again.
*/
queue->threshold = threshold;
- ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid);
+ ieee80211_wake_queue(rt2x00dev->hw, queue->qid);
+}
+
+static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
+{
+ WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
+ " invoke forced tx handler", queue->qid);
+
+ ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work);
}
void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -336,8 +358,12 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
struct data_queue *queue;
tx_queue_for_each(rt2x00dev, queue) {
- if (rt2x00queue_timeout(queue))
- rt2x00usb_watchdog_reset_tx(queue);
+ if (!rt2x00queue_empty(queue)) {
+ if (rt2x00queue_dma_timeout(queue))
+ rt2x00usb_watchdog_tx_dma(queue);
+ if (rt2x00queue_timeout(queue))
+ rt2x00usb_watchdog_tx_status(queue);
+ }
}
}
EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
@@ -345,38 +371,62 @@ EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
/*
* RX data handlers.
*/
+static void rt2x00usb_work_rxdone(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, rxdone_work);
+ struct queue_entry *entry;
+ struct skb_frame_desc *skbdesc;
+ u8 rxd[32];
+
+ while (!rt2x00queue_empty(rt2x00dev->rx)) {
+ entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);
+
+ if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ break;
+
+ /*
+ * Fill in desc fields of the skb descriptor
+ */
+ skbdesc = get_skb_frame_desc(entry->skb);
+ skbdesc->desc = rxd;
+ skbdesc->desc_len = entry->queue->desc_size;
+
+ /*
+ * Send the frame to rt2x00lib for further processing.
+ */
+ rt2x00lib_rxdone(entry);
+ }
+}
+
static void rt2x00usb_interrupt_rxdone(struct urb *urb)
{
struct queue_entry *entry = (struct queue_entry *)urb->context;
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
- u8 rxd[32];
- if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
- !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return;
/*
- * Check if the received data is simply too small
- * to be actually valid, or if the urb is signaling
- * a problem.
+ * Report the frame as DMA done
*/
- if (urb->actual_length < entry->queue->desc_size || urb->status) {
- set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
- usb_submit_urb(urb, GFP_ATOMIC);
- return;
- }
+ rt2x00lib_dmadone(entry);
/*
- * Fill in desc fields of the skb descriptor
+ * Check if the received data is simply too small
+ * to be actually valid, or if the urb is signaling
+ * a problem.
*/
- skbdesc->desc = rxd;
- skbdesc->desc_len = entry->queue->desc_size;
+ if (urb->actual_length < entry->queue->desc_size || urb->status)
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
/*
- * Send the frame to rt2x00lib for further processing.
+ * Schedule the delayed work for reading the RX status
+ * from the device.
*/
- rt2x00lib_rxdone(rt2x00dev, entry);
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+ test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
}
/*
@@ -391,7 +441,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
* The USB version of kill_tx_queue also works
* on the RX queue.
*/
- rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX);
+ rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx);
}
EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
@@ -405,6 +455,8 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
int pipe;
+ entry->flags = 0;
+
if (entry->queue->qid == QID_RX) {
pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint);
usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe,
@@ -412,9 +464,10 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
rt2x00usb_interrupt_rxdone, entry);
set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
- usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
- } else {
- entry->flags = 0;
+ if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+ rt2x00lib_dmadone(entry);
+ }
}
}
EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
@@ -489,9 +542,9 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev)
return 0;
}
-static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue)
+static int rt2x00usb_alloc_entries(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
struct queue_entry_priv_usb *entry_priv;
struct queue_entry_priv_usb_bcn *bcn_priv;
unsigned int i;
@@ -508,7 +561,7 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
* no guardian byte was required for the beacon,
* then we are done.
*/
- if (rt2x00dev->bcn != queue ||
+ if (queue->qid != QID_BEACON ||
!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
return 0;
@@ -522,9 +575,9 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
return 0;
}
-static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue)
+static void rt2x00usb_free_entries(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
struct queue_entry_priv_usb *entry_priv;
struct queue_entry_priv_usb_bcn *bcn_priv;
unsigned int i;
@@ -543,7 +596,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
* no guardian byte was required for the beacon,
* then we are done.
*/
- if (rt2x00dev->bcn != queue ||
+ if (queue->qid != QID_BEACON ||
!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
return;
@@ -570,7 +623,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
* Allocate DMA
*/
queue_for_each(rt2x00dev, queue) {
- status = rt2x00usb_alloc_urb(rt2x00dev, queue);
+ status = rt2x00usb_alloc_entries(queue);
if (status)
goto exit;
}
@@ -589,7 +642,7 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev)
struct data_queue *queue;
queue_for_each(rt2x00dev, queue)
- rt2x00usb_free_urb(rt2x00dev, queue);
+ rt2x00usb_free_entries(queue);
}
EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize);
@@ -659,6 +712,9 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB);
+ INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone);
+ INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone);
+
retval = rt2x00usb_alloc_reg(rt2x00dev);
if (retval)
goto exit_free_device;
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index d3d3ddc40875..c2d997f67b3e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -379,25 +379,21 @@ struct queue_entry_priv_usb_bcn {
/**
* rt2x00usb_kick_tx_queue - Kick data queue
- * @rt2x00dev: Pointer to &struct rt2x00_dev
- * @qid: Data queue to kick
+ * @queue: Data queue to kick
*
* This will walk through all entries of the queue and push all pending
* frames to the hardware as a single burst.
*/
-void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid);
+void rt2x00usb_kick_tx_queue(struct data_queue *queue);
/**
* rt2x00usb_kill_tx_queue - Kill data queue
- * @rt2x00dev: Pointer to &struct rt2x00_dev
- * @qid: Data queue to kill
+ * @queue: Data queue to kill
*
* This will walk through all entries of the queue and kill all
* previously kicked frames before they can be send.
*/
-void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid);
+void rt2x00usb_kill_tx_queue(struct data_queue *queue);
/**
* rt2x00usb_watchdog - Watchdog for USB communication
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index e539c6cb636f..af548c87f108 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -594,7 +594,8 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
}
static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp)
+ struct rt2x00lib_erp *erp,
+ u32 changed)
{
u32 reg;
@@ -603,28 +604,36 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
- rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
- !!erp->short_preamble);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
+ rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
+ !!erp->short_preamble);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
+ }
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR5,
+ erp->basic_rates);
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
- erp->beacon_int * 16);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+ }
- rt2x00pci_register_read(rt2x00dev, MAC_CSR9, &reg);
- rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
- rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR9, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg);
- rt2x00pci_register_read(rt2x00dev, MAC_CSR8, &reg);
- rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
- rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
- rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
- rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg);
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR8, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
+ rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
+ rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg);
+ }
}
static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
@@ -1050,7 +1059,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev,
/*
* Determine r17 bounds.
*/
- if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
low_bound = 0x28;
up_bound = 0x48;
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
@@ -1645,6 +1654,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
rt2x00_set_field32(&reg, INT_MASK_CSR_TXDONE, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_RXDONE, mask);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_BEACON_DONE, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_ENABLE_MITIGATION, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_MITIGATION_PERIOD, 0xff);
rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
@@ -1658,6 +1668,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_5, mask);
rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_6, mask);
rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_7, mask);
+ rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_TWAKEUP, mask);
rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg);
}
@@ -1766,12 +1777,11 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt61pci_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
__le32 *txd = entry_priv->desc;
u32 word;
@@ -1779,7 +1789,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
* Start writing the descriptor words.
*/
rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue);
+ rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid);
rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
@@ -1802,15 +1812,15 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
}
rt2x00_desc_read(txd, 5, &word);
- rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid);
+ rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid);
rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE,
skbdesc->entry->entry_idx);
rt2x00_set_field32(&word, TXD_W5_TX_POWER,
- TXPOWER_TO_DEV(rt2x00dev->tx_power));
+ TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power));
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word);
- if (txdesc->queue != QID_BEACON) {
+ if (txdesc->qid != QID_BEACON) {
rt2x00_desc_read(txd, 6, &word);
rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
skbdesc->skb_dma);
@@ -1857,7 +1867,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
*/
skbdesc->desc = txd;
skbdesc->desc_len =
- (txdesc->queue == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE;
+ (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE;
}
/*
@@ -1882,7 +1892,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
/*
* Write the TX descriptor for the beacon.
*/
- rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ rt61pci_write_tx_desc(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -1918,34 +1928,34 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
entry->skb = NULL;
}
-static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue)
+static void rt61pci_kick_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, (queue == QID_AC_VI));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, (queue == QID_AC_VO));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO));
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
}
-static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt61pci_kill_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
- if (qid == QID_BEACON) {
+ if (queue->qid == QID_BEACON) {
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
return;
}
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO));
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
}
@@ -1972,7 +1982,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
return 0;
}
- if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
if (lna == 3 || lna == 2)
offset += 10;
}
@@ -2107,11 +2117,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
"TX status report missed for entry %d\n",
entry_done->entry_idx);
- txdesc.flags = 0;
- __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
- txdesc.retry = 0;
-
- rt2x00lib_txdone(entry_done, &txdesc);
+ rt2x00lib_txdone_noinfo(entry_done, TXDONE_UNKNOWN);
entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
}
@@ -2624,12 +2630,13 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
* As rt61 has a global fallback table we cannot specify
* more then one tx rate per frame but since the hw will
* try several rates (based on the fallback table) we should
- * still initialize max_rates to the maximum number of rates
+ * initialize max_report_rates to the maximum number of rates
* we are going to try. Otherwise mac80211 will truncate our
* reported tx rates and the rc algortihm will end up with
* incorrect data.
*/
- rt2x00dev->hw->max_rates = 7;
+ rt2x00dev->hw->max_rates = 1;
+ rt2x00dev->hw->max_report_rates = 7;
rt2x00dev->hw->max_rate_tries = 1;
/*
@@ -2654,20 +2661,24 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
- for (i = 0; i < 14; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 0; i < 14; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
if (spec->num_channels > 14) {
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
- for (i = 14; i < spec->num_channels; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 14; i < spec->num_channels; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
}
return 0;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index aa9de18fd410..9be8089317e4 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -545,7 +545,8 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
}
static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp)
+ struct rt2x00lib_erp *erp,
+ u32 changed)
{
u32 reg;
@@ -554,28 +555,36 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
- rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
- rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
- !!erp->short_preamble);
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
+ rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
+ !!erp->short_preamble);
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+ }
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR5,
+ erp->basic_rates);
- rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
- erp->beacon_int * 16);
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+ }
- rt2x00usb_register_read(rt2x00dev, MAC_CSR9, &reg);
- rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
- rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR9, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg);
- rt2x00usb_register_read(rt2x00dev, MAC_CSR8, &reg);
- rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
- rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
- rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
- rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg);
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR8, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
+ rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
+ rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg);
+ }
}
static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
@@ -929,7 +938,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,
/*
* Determine r17 bounds.
*/
- if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
low_bound = 0x28;
up_bound = 0x48;
@@ -1426,12 +1435,11 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt73usb_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txd = (__le32 *) skb->data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ __le32 *txd = (__le32 *) entry->skb->data;
u32 word;
/*
@@ -1464,7 +1472,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(txd, 0, word);
rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue);
+ rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid);
rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
@@ -1487,7 +1495,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_read(txd, 5, &word);
rt2x00_set_field32(&word, TXD_W5_TX_POWER,
- TXPOWER_TO_DEV(rt2x00dev->tx_power));
+ TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power));
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word);
@@ -1526,7 +1534,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
/*
* Write the TX descriptor for the beacon.
*/
- rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ rt73usb_write_tx_desc(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -1574,6 +1582,14 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry)
return length;
}
+static void rt73usb_kill_tx_queue(struct data_queue *queue)
+{
+ if (queue->qid == QID_BEACON)
+ rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0);
+
+ rt2x00usb_kill_tx_queue(queue);
+}
+
/*
* RX control handlers
*/
@@ -1597,7 +1613,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
return 0;
}
- if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
if (lna == 3 || lna == 2)
offset += 10;
@@ -2047,9 +2063,14 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all hw fields.
+ *
+ * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are
+ * capable of sending the buffered frames out after the DTIM
+ * transmission using rt2x00lib_beacondone. This will send out
+ * multicast and broadcast traffic immediately instead of buffering it
+ * infinitly and thus dropping it after some time.
*/
rt2x00dev->hw->flags =
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK;
@@ -2084,20 +2105,24 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
- for (i = 0; i < 14; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 0; i < 14; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
if (spec->num_channels > 14) {
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
- for (i = 14; i < spec->num_channels; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 14; i < spec->num_channels; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
}
return 0;
@@ -2259,7 +2284,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.write_beacon = rt73usb_write_beacon,
.get_tx_data_len = rt73usb_get_tx_data_len,
.kick_tx_queue = rt2x00usb_kick_tx_queue,
- .kill_tx_queue = rt2x00usb_kill_tx_queue,
+ .kill_tx_queue = rt73usb_kill_tx_queue,
.fill_rxdone = rt73usb_fill_rxdone,
.config_shared_key = rt73usb_config_shared_key,
.config_pairwise_key = rt73usb_config_pairwise_key,
@@ -2345,6 +2370,7 @@ static struct usb_device_id rt73usb_device_table[] = {
{ 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) },
/* CEIVA */
{ USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },
/* CNet */
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 30107ce78dfb..707c688da618 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -783,6 +783,7 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
struct rtl8180_priv *priv = dev->priv;
struct rtl8180_vif *vif_priv;
int i;
+ u8 reg;
vif_priv = (struct rtl8180_vif *)&vif->drv_priv;
@@ -791,12 +792,14 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
rtl818x_iowrite8(priv, &priv->map->BSSID[i],
info->bssid[i]);
- if (is_valid_ether_addr(info->bssid))
- rtl818x_iowrite8(priv, &priv->map->MSR,
- RTL818X_MSR_INFRA);
- else
- rtl818x_iowrite8(priv, &priv->map->MSR,
- RTL818X_MSR_NO_LINK);
+ if (is_valid_ether_addr(info->bssid)) {
+ if (vif->type == NL80211_IFTYPE_ADHOC)
+ reg = RTL818X_MSR_ADHOC;
+ else
+ reg = RTL818X_MSR_INFRA;
+ } else
+ reg = RTL818X_MSR_NO_LINK;
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
}
if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 98e0351c1dd6..38fa8244cc96 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -1176,13 +1176,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
else
reg = 0;
- if (is_valid_ether_addr(info->bssid)) {
+ if (is_valid_ether_addr(info->bssid))
reg |= RTL818X_MSR_INFRA;
- rtl818x_iowrite8(priv, &priv->map->MSR, reg);
- } else {
+ else
reg |= RTL818X_MSR_NO_LINK;
- rtl818x_iowrite8(priv, &priv->map->MSR, reg);
- }
+
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
mutex_unlock(&priv->conf_mutex);
}
diff --git a/drivers/net/wireless/wl1251/Kconfig b/drivers/net/wireless/wl1251/Kconfig
new file mode 100644
index 000000000000..1fb65849414f
--- /dev/null
+++ b/drivers/net/wireless/wl1251/Kconfig
@@ -0,0 +1,33 @@
+menuconfig WL1251
+ tristate "TI wl1251 driver support"
+ depends on MAC80211 && EXPERIMENTAL && GENERIC_HARDIRQS
+ select FW_LOADER
+ select CRC7
+ ---help---
+ This will enable TI wl1251 driver support. The drivers make
+ use of the mac80211 stack.
+
+ If you choose to build a module, it'll be called wl1251. Say
+ N if unsure.
+
+config WL1251_SPI
+ tristate "TI wl1251 SPI support"
+ depends on WL1251 && SPI_MASTER
+ ---help---
+ This module adds support for the SPI interface of adapters using
+ TI wl1251 chipset. Select this if your platform is using
+ the SPI bus.
+
+ If you choose to build a module, it'll be called wl1251_spi.
+ Say N if unsure.
+
+config WL1251_SDIO
+ tristate "TI wl1251 SDIO support"
+ depends on WL1251 && MMC
+ ---help---
+ This module adds support for the SDIO interface of adapters using
+ TI wl1251 chipset. Select this if your platform is using
+ the SDIO bus.
+
+ If you choose to build a module, it'll be called
+ wl1251_sdio. Say N if unsure.
diff --git a/drivers/net/wireless/wl1251/Makefile b/drivers/net/wireless/wl1251/Makefile
new file mode 100644
index 000000000000..4fe246824db3
--- /dev/null
+++ b/drivers/net/wireless/wl1251/Makefile
@@ -0,0 +1,6 @@
+wl1251-objs = main.o event.o tx.o rx.o ps.o cmd.o \
+ acx.o boot.o init.o debugfs.o io.o
+
+obj-$(CONFIG_WL1251) += wl1251.o
+obj-$(CONFIG_WL1251_SPI) += spi.o
+obj-$(CONFIG_WL1251_SDIO) += sdio.o
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl1251/acx.c
index 91891f928070..64a0214cfb29 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl1251/acx.c
@@ -1,13 +1,13 @@
-#include "wl1251_acx.h"
+#include "acx.h"
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/crc7.h>
#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_cmd.h"
-#include "wl1251_ps.h"
+#include "reg.h"
+#include "cmd.h"
+#include "ps.h"
int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
u8 mgt_rate, u8 mgt_mod)
@@ -380,7 +380,7 @@ int wl1251_acx_pd_threshold(struct wl1251 *wl)
out:
kfree(pd);
- return 0;
+ return ret;
}
int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl1251/acx.h
index 842df310d92a..e54b21a4f8b1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.h
+++ b/drivers/net/wireless/wl1251/acx.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -26,7 +24,7 @@
#define __WL1251_ACX_H__
#include "wl1251.h"
-#include "wl1251_cmd.h"
+#include "cmd.h"
/* Target's information element */
struct acx_header {
@@ -37,7 +35,7 @@ struct acx_header {
/* payload length (not including headers */
u16 len;
-};
+} __packed;
struct acx_error_counter {
struct acx_header header;
@@ -459,8 +457,8 @@ struct acx_beacon_filter_ie_table {
struct acx_header header;
u8 num_ie;
- u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
u8 pad[3];
+ u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
} __packed;
#define SYNCH_FAIL_DEFAULT_THRESHOLD 10 /* number of beacons */
@@ -471,7 +469,7 @@ struct acx_conn_monit_params {
u32 synch_fail_thold; /* number of beacons missed */
u32 bss_lose_timeout; /* number of TU's from synch fail */
-};
+} __packed;
enum {
SG_ENABLE = 0,
@@ -1056,7 +1054,7 @@ struct acx_rate_class {
u8 long_retry_limit;
u8 aflags;
u8 reserved;
-};
+} __packed;
struct acx_rate_policy {
struct acx_header header;
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl1251/boot.c
index 65e0416be5b6..61572dfa1f60 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl1251/boot.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -24,12 +22,12 @@
#include <linux/gpio.h>
#include <linux/slab.h>
-#include "wl1251_reg.h"
-#include "wl1251_boot.h"
-#include "wl1251_io.h"
-#include "wl1251_spi.h"
-#include "wl1251_event.h"
-#include "wl1251_acx.h"
+#include "reg.h"
+#include "boot.h"
+#include "io.h"
+#include "spi.h"
+#include "event.h"
+#include "acx.h"
void wl1251_boot_target_enable_interrupts(struct wl1251 *wl)
{
@@ -302,7 +300,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
- BT_PTA_PREDICTION_EVENT_ID;
+ BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID;
ret = wl1251_event_unmask(wl);
if (ret < 0) {
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.h b/drivers/net/wireless/wl1251/boot.h
index 90063697e8f2..7661bc5e4662 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.h
+++ b/drivers/net/wireless/wl1251/boot.h
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl1251/cmd.c
index ce3722f4c3e3..0ade4bd617c0 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/drivers/net/wireless/wl1251/cmd.c
@@ -1,14 +1,14 @@
-#include "wl1251_cmd.h"
+#include "cmd.h"
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/crc7.h>
#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_ps.h"
-#include "wl1251_acx.h"
+#include "reg.h"
+#include "io.h"
+#include "ps.h"
+#include "acx.h"
/**
* send command to firmware
@@ -200,7 +200,7 @@ int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
out:
kfree(vbm);
- return 0;
+ return ret;
}
int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl1251/cmd.h
index a9e4991369be..e5c74c631374 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.h
+++ b/drivers/net/wireless/wl1251/cmd.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -111,7 +109,7 @@ struct wl1251_cmd_header {
struct wl1251_command {
struct wl1251_cmd_header header;
u8 parameters[MAX_CMD_PARAMS];
-};
+} __packed;
enum {
CMD_MAILBOX_IDLE = 0,
@@ -164,7 +162,7 @@ struct cmd_read_write_memory {
of this field is the Host in WRITE command or the Wilink in READ
command. */
u8 value[MAX_READ_SIZE];
-};
+} __packed;
#define CMDMBOX_HEADER_LEN 4
#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
@@ -339,7 +337,7 @@ struct wl1251_cmd_trigger_scan_to {
struct wl1251_cmd_header header;
u32 timeout;
-};
+} __packed;
/* HW encryption keys */
#define NUM_ACCESS_CATEGORIES_COPY 4
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl1251/debugfs.c
index fa620a5e5303..6c274007d200 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ b/drivers/net/wireless/wl1251/debugfs.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -21,14 +19,14 @@
*
*/
-#include "wl1251_debugfs.h"
+#include "debugfs.h"
#include <linux/skbuff.h>
#include <linux/slab.h>
#include "wl1251.h"
-#include "wl1251_acx.h"
-#include "wl1251_ps.h"
+#include "acx.h"
+#include "ps.h"
/* ms */
#define WL1251_DEBUGFS_STATS_LIFETIME 1000
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.h b/drivers/net/wireless/wl1251/debugfs.h
index 6dc3d080853c..b3417c02a218 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.h
+++ b/drivers/net/wireless/wl1251/debugfs.h
@@ -3,8 +3,6 @@
*
* Copyright (C) 2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl1251/event.c
index 020d764f9c13..712372e50a87 100644
--- a/drivers/net/wireless/wl12xx/wl1251_event.c
+++ b/drivers/net/wireless/wl1251/event.c
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -23,10 +21,10 @@
*/
#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_event.h"
-#include "wl1251_ps.h"
+#include "reg.h"
+#include "io.h"
+#include "event.h"
+#include "ps.h"
static int wl1251_event_scan_complete(struct wl1251 *wl,
struct event_mailbox *mbox)
@@ -36,9 +34,7 @@ static int wl1251_event_scan_complete(struct wl1251 *wl,
mbox->scheduled_scan_channels);
if (wl->scanning) {
- mutex_unlock(&wl->mutex);
ieee80211_scan_completed(wl->hw, false);
- mutex_lock(&wl->mutex);
wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed");
wl->scanning = false;
}
@@ -97,6 +93,35 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
return 0;
}
+/*
+ * Poll the mailbox event field until any of the bits in the mask is set or a
+ * timeout occurs (WL1251_EVENT_TIMEOUT in msecs)
+ */
+int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms)
+{
+ u32 events_vector, event;
+ unsigned long timeout;
+
+ timeout = jiffies + msecs_to_jiffies(timeout_ms);
+
+ do {
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+
+ msleep(1);
+
+ /* read from both event fields */
+ wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector,
+ sizeof(events_vector));
+ event = events_vector & mask;
+ wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector,
+ sizeof(events_vector));
+ event |= events_vector & mask;
+ } while (!event);
+
+ return 0;
+}
+
int wl1251_event_unmask(struct wl1251 *wl)
{
int ret;
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl1251/event.h
index f48a2b66bc5a..30eb5d150bf7 100644
--- a/drivers/net/wireless/wl12xx/wl1251_event.h
+++ b/drivers/net/wireless/wl1251/event.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -117,5 +115,6 @@ struct event_mailbox {
int wl1251_event_unmask(struct wl1251 *wl);
void wl1251_event_mbox_config(struct wl1251 *wl);
int wl1251_event_handle(struct wl1251 *wl, u8 mbox);
+int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms);
#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl1251/init.c
index b538bdd7b320..89b43d35473c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.c
+++ b/drivers/net/wireless/wl1251/init.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -25,11 +23,11 @@
#include <linux/module.h>
#include <linux/slab.h>
-#include "wl1251_init.h"
+#include "init.h"
#include "wl12xx_80211.h"
-#include "wl1251_acx.h"
-#include "wl1251_cmd.h"
-#include "wl1251_reg.h"
+#include "acx.h"
+#include "cmd.h"
+#include "reg.h"
int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
{
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl1251/init.h
index 269cefb3e7d4..543f17582ead 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.h
+++ b/drivers/net/wireless/wl1251/init.h
@@ -3,8 +3,6 @@
*
* Copyright (C) 2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl1251/io.c
index f1c232e0887f..cdcadbf6ac2c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.c
+++ b/drivers/net/wireless/wl1251/io.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -22,8 +20,8 @@
*/
#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
+#include "reg.h"
+#include "io.h"
/* FIXME: this is static data nowadays and the table can be removed */
static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = {
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl1251/io.h
index c545e9d5f512..c545e9d5f512 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.h
+++ b/drivers/net/wireless/wl1251/io.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl1251/main.c
index 861a5f33761e..7a8762553cdc 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008-2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -33,16 +31,16 @@
#include "wl1251.h"
#include "wl12xx_80211.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_cmd.h"
-#include "wl1251_event.h"
-#include "wl1251_tx.h"
-#include "wl1251_rx.h"
-#include "wl1251_ps.h"
-#include "wl1251_init.h"
-#include "wl1251_debugfs.h"
-#include "wl1251_boot.h"
+#include "reg.h"
+#include "io.h"
+#include "cmd.h"
+#include "event.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+#include "debugfs.h"
+#include "boot.h"
void wl1251_enable_interrupts(struct wl1251 *wl)
{
@@ -293,14 +291,14 @@ static void wl1251_irq_work(struct work_struct *work)
wl1251_tx_complete(wl);
}
- if (intr & (WL1251_ACX_INTR_EVENT_A |
- WL1251_ACX_INTR_EVENT_B)) {
- wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)",
- intr);
- if (intr & WL1251_ACX_INTR_EVENT_A)
- wl1251_event_handle(wl, 0);
- else
- wl1251_event_handle(wl, 1);
+ if (intr & WL1251_ACX_INTR_EVENT_A) {
+ wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_A");
+ wl1251_event_handle(wl, 0);
+ }
+
+ if (intr & WL1251_ACX_INTR_EVENT_B) {
+ wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_B");
+ wl1251_event_handle(wl, 1);
}
if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
@@ -339,11 +337,9 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel,
if (ret < 0)
goto out;
- /*
- * FIXME: we should wait for JOIN_EVENT_COMPLETE_ID but to simplify
- * locking we just sleep instead, for now
- */
- msleep(10);
+ ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100);
+ if (ret < 0)
+ wl1251_warning("join timeout");
out:
return ret;
@@ -379,6 +375,7 @@ out:
static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct wl1251 *wl = hw->priv;
+ unsigned long flags;
skb_queue_tail(&wl->tx_queue, skb);
@@ -393,16 +390,13 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* The workqueue is slow to process the tx_queue and we need stop
* the queue here, otherwise the queue will get too long.
*/
- if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
+ if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_HIGH_WATERMARK) {
wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
- ieee80211_stop_queues(wl->hw);
- /*
- * FIXME: this is racy, the variable is not properly
- * protected. Maybe fix this by removing the stupid
- * variable altogether and checking the real queue state?
- */
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ ieee80211_stop_queues(wl->hw);
wl->tx_queue_stopped = true;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
}
return NETDEV_TX_OK;
@@ -471,9 +465,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
WARN_ON(wl->state != WL1251_STATE_ON);
if (wl->scanning) {
- mutex_unlock(&wl->mutex);
ieee80211_scan_completed(wl->hw, true);
- mutex_lock(&wl->mutex);
wl->scanning = false;
}
@@ -725,8 +717,9 @@ static int wl1251_set_key_type(struct wl1251 *wl,
struct ieee80211_key_conf *mac80211_key,
const u8 *addr)
{
- switch (mac80211_key->alg) {
- case ALG_WEP:
+ switch (mac80211_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
if (is_broadcast_ether_addr(addr))
key->key_type = KEY_WEP_DEFAULT;
else
@@ -734,7 +727,7 @@ static int wl1251_set_key_type(struct wl1251 *wl,
mac80211_key->hw_key_idx = mac80211_key->keyidx;
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
if (is_broadcast_ether_addr(addr))
key->key_type = KEY_TKIP_MIC_GROUP;
else
@@ -742,7 +735,7 @@ static int wl1251_set_key_type(struct wl1251 *wl,
mac80211_key->hw_key_idx = mac80211_key->keyidx;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
if (is_broadcast_ether_addr(addr))
key->key_type = KEY_AES_GROUP;
else
@@ -750,7 +743,7 @@ static int wl1251_set_key_type(struct wl1251 *wl,
mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
break;
default:
- wl1251_error("Unknown key algo 0x%x", mac80211_key->alg);
+ wl1251_error("Unknown key cipher 0x%x", mac80211_key->cipher);
return -EOPNOTSUPP;
}
@@ -783,7 +776,7 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
- key->alg, key->keyidx, key->keylen, key->flags);
+ key->cipher, key->keyidx, key->keylen, key->flags);
wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
if (is_zero_ether_addr(addr)) {
@@ -1438,5 +1431,5 @@ EXPORT_SYMBOL_GPL(wl1251_free_hw);
MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
+MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
MODULE_FIRMWARE(WL1251_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl1251/ps.c
index b55cb2bd459a..5ed47c8373d2 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl1251/ps.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -21,10 +19,10 @@
*
*/
-#include "wl1251_reg.h"
-#include "wl1251_ps.h"
-#include "wl1251_cmd.h"
-#include "wl1251_io.h"
+#include "reg.h"
+#include "ps.h"
+#include "cmd.h"
+#include "io.h"
/* in ms */
#define WL1251_WAKEUP_TIMEOUT 100
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl1251/ps.h
index c688ac57aee4..55c3dda75e69 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.h
+++ b/drivers/net/wireless/wl1251/ps.h
@@ -1,14 +1,9 @@
-#ifndef __WL1251_PS_H__
-#define __WL1251_PS_H__
-
/*
* This file is part of wl1251
*
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -25,8 +20,11 @@
*
*/
+#ifndef __WL1251_PS_H__
+#define __WL1251_PS_H__
+
#include "wl1251.h"
-#include "wl1251_acx.h"
+#include "acx.h"
int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
void wl1251_ps_elp_sleep(struct wl1251 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl1251/reg.h
index d16edd9bf06c..a5809019c5c1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_reg.h
+++ b/drivers/net/wireless/wl1251/reg.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl1251/rx.c
index 1b6294b3b996..efa53607d5c9 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl1251/rx.c
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -27,11 +25,11 @@
#include <net/mac80211.h>
#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_rx.h"
-#include "wl1251_cmd.h"
-#include "wl1251_acx.h"
+#include "reg.h"
+#include "io.h"
+#include "rx.h"
+#include "cmd.h"
+#include "acx.h"
static void wl1251_rx_header(struct wl1251 *wl,
struct wl1251_rx_descriptor *desc)
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl1251/rx.h
index da4e53406a0e..4448f635a4d8 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.h
+++ b/drivers/net/wireless/wl1251/rx.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl1251/sdio.c
index b901b6135654..74ba9ced5393 100644
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ b/drivers/net/wireless/wl1251/sdio.c
@@ -24,7 +24,7 @@
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/platform_device.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
#include <linux/irq.h>
#include "wl1251.h"
@@ -339,4 +339,4 @@ module_init(wl1251_sdio_init);
module_exit(wl1251_sdio_exit);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
+MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl1251/spi.c
index 27fdfaaeb074..88fa8e69d0d1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl1251/spi.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -26,11 +24,11 @@
#include <linux/slab.h>
#include <linux/crc7.h>
#include <linux/spi/spi.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_spi.h"
+#include "reg.h"
+#include "spi.h"
static irqreturn_t wl1251_irq(int irq, void *cookie)
{
@@ -344,5 +342,5 @@ module_init(wl1251_spi_init);
module_exit(wl1251_spi_exit);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
+MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
MODULE_ALIAS("spi:wl1251");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl1251/spi.h
index 2e273a97e7f3..16d506955cc0 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.h
+++ b/drivers/net/wireless/wl1251/spi.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -25,9 +23,9 @@
#ifndef __WL1251_SPI_H__
#define __WL1251_SPI_H__
-#include "wl1251_cmd.h"
-#include "wl1251_acx.h"
-#include "wl1251_reg.h"
+#include "cmd.h"
+#include "acx.h"
+#include "reg.h"
#define WSPI_CMD_READ 0x40000000
#define WSPI_CMD_WRITE 0x00000000
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl1251/tx.c
index a38ec199187a..554b4f9a3d3e 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl1251/tx.c
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -26,10 +24,10 @@
#include <linux/module.h>
#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_tx.h"
-#include "wl1251_ps.h"
-#include "wl1251_io.h"
+#include "reg.h"
+#include "tx.h"
+#include "ps.h"
+#include "io.h"
static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count)
{
@@ -189,7 +187,7 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
tx_hdr = (struct tx_double_buffer_desc *) skb->data;
if (control->control.hw_key &&
- control->control.hw_key->alg == ALG_TKIP) {
+ control->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
int hdrlen;
__le16 fc;
u16 length;
@@ -322,11 +320,6 @@ void wl1251_tx_work(struct work_struct *work)
ret = wl1251_tx_frame(wl, skb);
if (ret == -EBUSY) {
- /* firmware buffer is full, stop queues */
- wl1251_debug(DEBUG_TX, "tx_work: fw buffer full, "
- "stop queues");
- ieee80211_stop_queues(wl->hw);
- wl->tx_queue_stopped = true;
skb_queue_head(&wl->tx_queue, skb);
goto out;
} else if (ret < 0) {
@@ -399,7 +392,7 @@ static void wl1251_tx_packet_cb(struct wl1251 *wl,
*/
frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
if (info->control.hw_key &&
- info->control.hw_key->alg == ALG_TKIP) {
+ info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen);
skb_pull(skb, WL1251_TKIP_IV_SPACE);
@@ -449,6 +442,7 @@ void wl1251_tx_complete(struct wl1251 *wl)
{
int i, result_index, num_complete = 0;
struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
+ unsigned long flags;
if (unlikely(wl->state != WL1251_STATE_ON))
return;
@@ -477,6 +471,20 @@ void wl1251_tx_complete(struct wl1251 *wl)
}
}
+ if (wl->tx_queue_stopped
+ &&
+ skb_queue_len(&wl->tx_queue) <= WL1251_TX_QUEUE_LOW_WATERMARK){
+
+ /* firmware buffer has space, restart queues */
+ wl1251_debug(DEBUG_TX, "tx_complete: waking queues");
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ ieee80211_wake_queues(wl->hw);
+ wl->tx_queue_stopped = false;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ ieee80211_queue_work(wl->hw, &wl->tx_work);
+
+ }
+
/* Every completed frame needs to be acknowledged */
if (num_complete) {
/*
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl1251/tx.h
index f40eeb37f5aa..81338d39b43e 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.h
+++ b/drivers/net/wireless/wl1251/tx.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -26,7 +24,7 @@
#define __WL1251_TX_H__
#include <linux/bitops.h>
-#include "wl1251_acx.h"
+#include "acx.h"
/*
*
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h
index 6b942a28e6a5..e113d4c1fb35 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl1251/wl1251.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008-2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -274,6 +272,8 @@ struct wl1251 {
int irq;
bool use_eeprom;
+ spinlock_t wl_lock;
+
enum wl1251_state state;
struct mutex mutex;
@@ -401,7 +401,8 @@ void wl1251_disable_interrupts(struct wl1251 *wl);
#define WL1251_DEFAULT_POWER_LEVEL 20
-#define WL1251_TX_QUEUE_MAX_LENGTH 20
+#define WL1251_TX_QUEUE_LOW_WATERMARK 10
+#define WL1251_TX_QUEUE_HIGH_WATERMARK 25
#define WL1251_DEFAULT_BEACON_INT 100
#define WL1251_DEFAULT_DTIM_PERIOD 1
diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/wl1251/wl12xx_80211.h
new file mode 100644
index 000000000000..184628027213
--- /dev/null
+++ b/drivers/net/wireless/wl1251/wl12xx_80211.h
@@ -0,0 +1,156 @@
+#ifndef __WL12XX_80211_H__
+#define __WL12XX_80211_H__
+
+#include <linux/if_ether.h> /* ETH_ALEN */
+
+/* RATES */
+#define IEEE80211_CCK_RATE_1MB 0x02
+#define IEEE80211_CCK_RATE_2MB 0x04
+#define IEEE80211_CCK_RATE_5MB 0x0B
+#define IEEE80211_CCK_RATE_11MB 0x16
+#define IEEE80211_OFDM_RATE_6MB 0x0C
+#define IEEE80211_OFDM_RATE_9MB 0x12
+#define IEEE80211_OFDM_RATE_12MB 0x18
+#define IEEE80211_OFDM_RATE_18MB 0x24
+#define IEEE80211_OFDM_RATE_24MB 0x30
+#define IEEE80211_OFDM_RATE_36MB 0x48
+#define IEEE80211_OFDM_RATE_48MB 0x60
+#define IEEE80211_OFDM_RATE_54MB 0x6C
+#define IEEE80211_BASIC_RATE_MASK 0x80
+
+#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
+#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
+#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
+#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
+#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
+#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
+#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
+#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
+#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
+#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
+#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
+#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
+
+#define IEEE80211_CCK_RATES_MASK 0x0000000F
+#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
+ IEEE80211_CCK_RATE_2MB_MASK)
+#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
+ IEEE80211_CCK_RATE_5MB_MASK | \
+ IEEE80211_CCK_RATE_11MB_MASK)
+
+#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
+#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
+ IEEE80211_OFDM_RATE_12MB_MASK | \
+ IEEE80211_OFDM_RATE_24MB_MASK)
+#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
+ IEEE80211_OFDM_RATE_9MB_MASK | \
+ IEEE80211_OFDM_RATE_18MB_MASK | \
+ IEEE80211_OFDM_RATE_36MB_MASK | \
+ IEEE80211_OFDM_RATE_48MB_MASK | \
+ IEEE80211_OFDM_RATE_54MB_MASK)
+#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
+ IEEE80211_CCK_DEFAULT_RATES_MASK)
+
+
+/* This really should be 8, but not for our firmware */
+#define MAX_SUPPORTED_RATES 32
+#define COUNTRY_STRING_LEN 3
+#define MAX_COUNTRY_TRIPLETS 32
+
+/* Headers */
+struct ieee80211_header {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 da[ETH_ALEN];
+ u8 sa[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+} __packed;
+
+struct wl12xx_ie_header {
+ u8 id;
+ u8 len;
+} __packed;
+
+/* IEs */
+
+struct wl12xx_ie_ssid {
+ struct wl12xx_ie_header header;
+ char ssid[IW_ESSID_MAX_SIZE];
+} __packed;
+
+struct wl12xx_ie_rates {
+ struct wl12xx_ie_header header;
+ u8 rates[MAX_SUPPORTED_RATES];
+} __packed;
+
+struct wl12xx_ie_ds_params {
+ struct wl12xx_ie_header header;
+ u8 channel;
+} __packed;
+
+struct country_triplet {
+ u8 channel;
+ u8 num_channels;
+ u8 max_tx_power;
+} __packed;
+
+struct wl12xx_ie_country {
+ struct wl12xx_ie_header header;
+ u8 country_string[COUNTRY_STRING_LEN];
+ struct country_triplet triplets[MAX_COUNTRY_TRIPLETS];
+} __packed;
+
+
+/* Templates */
+
+struct wl12xx_beacon_template {
+ struct ieee80211_header header;
+ __le32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ struct wl12xx_ie_ssid ssid;
+ struct wl12xx_ie_rates rates;
+ struct wl12xx_ie_rates ext_rates;
+ struct wl12xx_ie_ds_params ds_params;
+ struct wl12xx_ie_country country;
+} __packed;
+
+struct wl12xx_null_data_template {
+ struct ieee80211_header header;
+} __packed;
+
+struct wl12xx_ps_poll_template {
+ __le16 fc;
+ __le16 aid;
+ u8 bssid[ETH_ALEN];
+ u8 ta[ETH_ALEN];
+} __packed;
+
+struct wl12xx_qos_null_data_template {
+ struct ieee80211_header header;
+ __le16 qos_ctl;
+} __packed;
+
+struct wl12xx_probe_req_template {
+ struct ieee80211_header header;
+ struct wl12xx_ie_ssid ssid;
+ struct wl12xx_ie_rates rates;
+ struct wl12xx_ie_rates ext_rates;
+} __packed;
+
+
+struct wl12xx_probe_resp_template {
+ struct ieee80211_header header;
+ __le32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ struct wl12xx_ie_ssid ssid;
+ struct wl12xx_ie_rates rates;
+ struct wl12xx_ie_rates ext_rates;
+ struct wl12xx_ie_ds_params ds_params;
+ struct wl12xx_ie_country country;
+} __packed;
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 2f98058be451..b447559f1db5 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -5,40 +5,6 @@ menuconfig WL12XX
This will enable TI wl12xx driver support. The drivers make
use of the mac80211 stack.
-config WL1251
- tristate "TI wl1251 support"
- depends on WL12XX && GENERIC_HARDIRQS
- select FW_LOADER
- select CRC7
- ---help---
- This module adds support for wireless adapters based on
- TI wl1251 chipset.
-
- If you choose to build a module, it'll be called wl1251. Say
- N if unsure.
-
-config WL1251_SPI
- tristate "TI wl1251 SPI support"
- depends on WL1251 && SPI_MASTER
- ---help---
- This module adds support for the SPI interface of adapters using
- TI wl1251 chipset. Select this if your platform is using
- the SPI bus.
-
- If you choose to build a module, it'll be called wl1251_spi.
- Say N if unsure.
-
-config WL1251_SDIO
- tristate "TI wl1251 SDIO support"
- depends on WL1251 && MMC
- ---help---
- This module adds support for the SDIO interface of adapters using
- TI wl1251 chipset. Select this if your platform is using
- the SDIO bus.
-
- If you choose to build a module, it'll be called
- wl1251_sdio. Say N if unsure.
-
config WL1271
tristate "TI wl1271 support"
depends on WL12XX && GENERIC_HARDIRQS
@@ -74,4 +40,7 @@ config WL1271_SDIO
If you choose to build a module, it'll be called
wl1271_sdio. Say N if unsure.
-
+config WL12XX_PLATFORM_DATA
+ bool
+ depends on WL1271_SDIO != n
+ default y
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index 078b4398ac1f..3a807444b2af 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -1,12 +1,3 @@
-wl1251-objs = wl1251_main.o wl1251_event.o \
- wl1251_tx.o wl1251_rx.o wl1251_ps.o wl1251_cmd.o \
- wl1251_acx.o wl1251_boot.o wl1251_init.o \
- wl1251_debugfs.o wl1251_io.o
-
-obj-$(CONFIG_WL1251) += wl1251.o
-obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o
-obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o
-
wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \
wl1271_event.o wl1271_tx.o wl1271_rx.o \
wl1271_ps.o wl1271_acx.o wl1271_boot.o \
@@ -16,3 +7,6 @@ wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o
obj-$(CONFIG_WL1271) += wl1271.o
obj-$(CONFIG_WL1271_SPI) += wl1271_spi.o
obj-$(CONFIG_WL1271_SDIO) += wl1271_sdio.o
+
+# small builtin driver bit
+obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index dd3cee6ea5bb..8a4cd763e5a2 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -117,10 +117,7 @@ enum {
#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
-/*
- * Enable/disable 802.11a support for WL1273
- */
-#undef WL1271_80211A_ENABLED
+#define WL1271_CIPHER_SUITE_GEM 0x00147201
#define WL1271_BUSY_WORD_CNT 1
#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
@@ -133,6 +130,8 @@ enum {
#define ACX_TX_DESCRIPTORS 32
+#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
+
enum wl1271_state {
WL1271_STATE_OFF,
WL1271_STATE_ON,
@@ -301,6 +300,7 @@ struct wl1271_rx_mem_pool_addr {
struct wl1271_scan {
struct cfg80211_scan_request *req;
bool *scanned_ch;
+ bool failed;
u8 state;
u8 ssid[IW_ESSID_MAX_SIZE+1];
size_t ssid_len;
@@ -313,7 +313,7 @@ struct wl1271_if_operations {
bool fixed);
void (*reset)(struct wl1271 *wl);
void (*init)(struct wl1271 *wl);
- void (*power)(struct wl1271 *wl, bool enable);
+ int (*power)(struct wl1271 *wl, bool enable);
struct device* (*dev)(struct wl1271 *wl);
void (*enable_irq)(struct wl1271 *wl);
void (*disable_irq)(struct wl1271 *wl);
@@ -330,6 +330,7 @@ struct wl1271 {
void (*set_power)(bool enable);
int irq;
+ int ref_clock;
spinlock_t wl_lock;
@@ -349,6 +350,7 @@ struct wl1271 {
#define WL1271_FLAG_IDLE (10)
#define WL1271_FLAG_IDLE_REQUESTED (11)
#define WL1271_FLAG_PSPOLL_FAILURE (12)
+#define WL1271_FLAG_STA_STATE_SENT (13)
unsigned long flags;
struct wl1271_partition_set part;
@@ -361,6 +363,7 @@ struct wl1271 {
u8 *fw;
size_t fw_len;
struct wl1271_nvs_file *nvs;
+ size_t nvs_len;
s8 hw_pg_ver;
@@ -407,9 +410,15 @@ struct wl1271 {
/* Rx memory pool address */
struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
+ /* Intermediate buffer, used for packet aggregation */
+ u8 *aggr_buf;
+
/* The target interrupt mask */
struct work_struct irq_work;
+ /* Hardware recovery work */
+ struct work_struct recovery_work;
+
/* The mbox event mask */
u32 event_mask;
@@ -418,6 +427,7 @@ struct wl1271 {
/* Are we currently scanning */
struct wl1271_scan scan;
+ struct delayed_work scan_complete_work;
/* Our association ID */
u16 aid;
@@ -474,6 +484,8 @@ struct wl1271 {
bool sg_enabled;
+ bool enable_11a;
+
struct list_head list;
/* Most recently reported noise in dBm */
@@ -497,14 +509,4 @@ int wl1271_plt_stop(struct wl1271 *wl);
#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */
#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
-static inline bool wl1271_11a_enabled(void)
-{
- /* FIXME: this could be determined based on the NVS-INI file */
-#ifdef WL1271_80211A_ENABLED
- return true;
-#else
- return false;
-#endif
-}
-
#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index bb245f05af49..618993405262 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -86,40 +86,6 @@ out:
return ret;
}
-int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len)
-{
- struct acx_revision *rev;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx fw rev");
-
- rev = kzalloc(sizeof(*rev), GFP_KERNEL);
- if (!rev) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = wl1271_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
- if (ret < 0) {
- wl1271_warning("ACX_FW_REV interrogate failed");
- goto out;
- }
-
- /* be careful with the buffer sizes */
- strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
-
- /*
- * if the firmware version string is exactly
- * sizeof(rev->fw_version) long or fw_len is less than
- * sizeof(rev->fw_version) it won't be null terminated
- */
- buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
-
-out:
- kfree(rev);
- return ret;
-}
-
int wl1271_acx_tx_power(struct wl1271 *wl, int power)
{
struct acx_current_tx_power *acx;
@@ -269,7 +235,7 @@ int wl1271_acx_pd_threshold(struct wl1271 *wl)
out:
kfree(pd);
- return 0;
+ return ret;
}
int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index 4235bc56f750..ebb341d36e8c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -100,35 +100,6 @@ struct acx_error_counter {
__le32 seq_num_miss;
} __packed;
-struct acx_revision {
- struct acx_header header;
-
- /*
- * The WiLink firmware version, an ASCII string x.x.x.x,
- * that uniquely identifies the current firmware.
- * The left most digit is incremented each time a
- * significant change is made to the firmware, such as
- * code redesign or new platform support.
- * The second digit is incremented when major enhancements
- * are added or major fixes are made.
- * The third digit is incremented for each GA release.
- * The fourth digit is incremented for each build.
- * The first two digits identify a firmware release version,
- * in other words, a unique set of features.
- * The first three digits identify a GA release.
- */
- char fw_version[20];
-
- /*
- * This 4 byte field specifies the WiLink hardware version.
- * bits 0 - 15: Reserved.
- * bits 16 - 23: Version ID - The WiLink version ID
- * (1 = first spin, 2 = second spin, and so on).
- * bits 24 - 31: Chip ID - The WiLink chip ID.
- */
- __le32 hw_version;
-} __packed;
-
enum wl1271_psm_mode {
/* Active mode */
WL1271_PSM_CAM = 0,
@@ -1060,7 +1031,6 @@ enum {
ACX_PEER_HT_CAP = 0x0057,
ACX_HT_BSS_OPERATION = 0x0058,
ACX_COEX_ACTIVITY = 0x0059,
- ACX_SET_SMART_REFLEX_DEBUG = 0x005A,
ACX_SET_DCO_ITRIM_PARAMS = 0x0061,
DOT11_RX_MSDU_LIFE_TIME = 0x1004,
DOT11_CUR_TX_PWR = 0x100D,
@@ -1077,7 +1047,6 @@ enum {
int wl1271_acx_wake_up_conditions(struct wl1271 *wl);
int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
-int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len);
int wl1271_acx_tx_power(struct wl1271 *wl, int power);
int wl1271_acx_feature_cfg(struct wl1271 *wl);
int wl1271_acx_mem_map(struct wl1271 *wl,
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index f36430b0336d..b91021242098 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -225,6 +225,28 @@ 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) {
+ if (wl->nvs->general_params.dual_mode_select)
+ wl->enable_11a = true;
+ }
+
+ 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(wl->nvs->nvs);
nvs_ptr = (u8 *)wl->nvs->nvs;
@@ -251,8 +273,10 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
burst_len = nvs_ptr[0];
dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
- /* FIXME: Due to our new wl1271_translate_reg_addr function,
- we need to add the REGISTER_BASE to the destination */
+ /*
+ * Due to our new wl1271_translate_reg_addr function,
+ * we need to add the REGISTER_BASE to the destination
+ */
dest_addr += REGISTERS_BASE;
/* We move our pointer to the data */
@@ -274,31 +298,21 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
/*
* We've reached the first zero length, the first NVS table
- * is 7 bytes further.
+ * is located at an aligned offset which is at least 7 bytes further.
*/
- nvs_ptr += 7;
+ nvs_ptr = (u8 *)wl->nvs->nvs +
+ ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4);
nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs;
- nvs_len = ALIGN(nvs_len, 4);
- /* FIXME: The driver sets the partition here, but this is not needed,
- since it sets to the same one as currently in use */
/* Now we must set the partition correctly */
wl1271_set_partition(wl, &part_table[PART_WORK]);
/* Copy the NVS tables to a new block to ensure alignment */
- /* FIXME: We jump 3 more bytes before uploading the NVS. It seems
- that our NVS files have three extra zeros here. I'm not sure whether
- the problem is in our NVS generation or we should really jumpt these
- 3 bytes here */
- nvs_ptr += 3;
-
- nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); if
- (!nvs_aligned) return -ENOMEM;
+ nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
+ if (!nvs_aligned)
+ return -ENOMEM;
/* And finally we upload the NVS tables */
- /* FIXME: In wl1271, we upload everything at once.
- No endianness handling needed here?! The ref driver doesn't do
- anything about it at this point */
wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
kfree(nvs_aligned);
@@ -457,17 +471,20 @@ int wl1271_boot(struct wl1271 *wl)
{
int ret = 0;
u32 tmp, clk, pause;
+ int ref_clock = wl->ref_clock;
wl1271_boot_hw_version(wl);
- if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4)
+ if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4)
/* ref clk: 19.2/38.4/38.4-XTAL */
clk = 0x3;
- else if (REF_CLOCK == 1 || REF_CLOCK == 3)
+ else if (ref_clock == 1 || ref_clock == 3)
/* ref clk: 26/52 */
clk = 0x5;
+ else
+ return -EINVAL;
- if (REF_CLOCK != 0) {
+ if (ref_clock != 0) {
u16 val;
/* Set clock type (open drain) */
val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
@@ -493,10 +510,7 @@ int wl1271_boot(struct wl1271 *wl)
wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
- pause &= ~(WU_COUNTER_PAUSE_VAL); /* FIXME: This should probably be
- * WU_COUNTER_PAUSE_VAL instead of
- * 0x3ff (magic number ). How does
- * this work?! */
+ pause &= ~(WU_COUNTER_PAUSE_VAL);
pause |= WU_COUNTER_PAUSE_VAL;
wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
@@ -516,7 +530,7 @@ int wl1271_boot(struct wl1271 *wl)
wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
/* 2 */
- clk |= (REF_CLOCK << 1) << 4;
+ clk |= (ref_clock << 1) << 4;
wl1271_write32(wl, DRPW_SCRATCH_START, clk);
wl1271_set_partition(wl, &part_table[PART_WORK]);
@@ -550,7 +564,6 @@ int wl1271_boot(struct wl1271 *wl)
if (ret < 0)
goto out;
- /* FIXME: Need to check whether this is really what we want */
wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
WL1271_ACX_ALL_EVENTS_VECTOR);
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
index f829699d597e..f73b0b15a280 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -46,7 +46,6 @@ struct wl1271_static_data {
/* delay between retries */
#define INIT_LOOP_DELAY 50
-#define REF_CLOCK 2
#define WU_COUNTER_PAUSE_VAL 0x3FF
#define WELP_ARM_COMMAND_VAL 0x4
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index ce503ddd5a41..5d3e8485ea4e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -94,6 +94,7 @@ 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;
}
@@ -107,6 +108,8 @@ out:
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;
+ bool answer = false;
int ret;
if (!wl->nvs)
@@ -118,13 +121,24 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
- memcpy(&gen_parms->general_params, &wl->nvs->general_params,
- sizeof(struct wl1271_ini_general_params));
+ memcpy(&gen_parms->general_params, gp, sizeof(*gp));
- ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
- if (ret < 0)
+ if (gp->tx_bip_fem_auto_detect)
+ answer = true;
+
+ 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;
}
@@ -170,6 +184,39 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
return ret;
}
+int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
+{
+ struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
+ struct conf_rf_settings *rf = &wl->conf.rf;
+ int ret;
+
+ if (!wl->nvs)
+ return -ENODEV;
+
+ ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
+ if (!ext_radio_parms)
+ return -ENOMEM;
+
+ ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
+
+ memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
+ rf->tx_per_channel_power_compensation_2,
+ CONF_TX_PWR_COMPENSATION_LEN_2);
+ memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
+ rf->tx_per_channel_power_compensation_5,
+ CONF_TX_PWR_COMPENSATION_LEN_5);
+
+ wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
+ ext_radio_parms, sizeof(*ext_radio_parms));
+
+ ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
+ if (ret < 0)
+ wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
+
+ kfree(ext_radio_parms);
+ return ret;
+}
+
/*
* Poll the mailbox event field until any of the bits in the mask is set or a
* timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
@@ -182,8 +229,10 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
do {
- if (time_after(jiffies, timeout))
+ if (time_after(jiffies, timeout)) {
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
return -ETIMEDOUT;
+ }
msleep(1);
@@ -390,18 +439,11 @@ out:
return ret;
}
-int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
+int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
{
struct wl1271_cmd_ps_params *ps_params = NULL;
int ret = 0;
- /* FIXME: this should be in ps.c */
- ret = wl1271_acx_wake_up_conditions(wl);
- if (ret < 0) {
- wl1271_error("couldn't set wake up conditions");
- goto out;
- }
-
wl1271_debug(DEBUG_CMD, "cmd set ps mode");
ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
@@ -412,9 +454,9 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
ps_params->ps_mode = ps_mode;
ps_params->send_null_data = send;
- ps_params->retries = 5;
- ps_params->hang_over_period = 1;
- ps_params->null_data_rate = cpu_to_le32(wl->basic_rate_set);
+ ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries;
+ ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period;
+ ps_params->null_data_rate = cpu_to_le32(rates);
ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
sizeof(*ps_params), 0);
@@ -428,41 +470,6 @@ out:
return ret;
}
-int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
- size_t len)
-{
- struct cmd_read_write_memory *cmd;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd read memory");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- WARN_ON(len > MAX_READ_SIZE);
- len = min_t(size_t, len, MAX_READ_SIZE);
-
- cmd->addr = cpu_to_le32(addr);
- cmd->size = cpu_to_le32(len);
-
- ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd),
- sizeof(*cmd));
- if (ret < 0) {
- wl1271_error("read memory command failed: %d", ret);
- goto out;
- }
-
- /* the read command got in */
- memcpy(answer, cmd->value, len);
-
-out:
- kfree(cmd);
- return ret;
-}
-
int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
void *buf, size_t buf_len, int index, u32 rates)
{
@@ -523,7 +530,7 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl)
}
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0,
- WL1271_RATE_AUTOMATIC);
+ wl->basic_rate);
out:
dev_kfree_skb(skb);
@@ -546,7 +553,7 @@ int wl1271_cmd_build_klv_null_data(struct wl1271 *wl)
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
skb->data, skb->len,
CMD_TEMPL_KLV_IDX_NULL_DATA,
- WL1271_RATE_AUTOMATIC);
+ wl->basic_rate);
out:
dev_kfree_skb(skb);
@@ -623,7 +630,7 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
sizeof(template), 0,
- WL1271_RATE_AUTOMATIC);
+ wl->basic_rate);
}
int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
@@ -746,3 +753,31 @@ out_free:
out:
return ret;
}
+
+int wl1271_cmd_set_sta_state(struct wl1271 *wl)
+{
+ struct wl1271_cmd_set_sta_state *cmd;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_CMD, "cmd set sta state");
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (!cmd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
+
+ ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0);
+ if (ret < 0) {
+ wl1271_error("failed to send set STA state command");
+ goto out_free;
+ }
+
+out_free:
+ kfree(cmd);
+
+out:
+ return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index af577ee8eb02..a0caf4fc37b1 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -33,12 +33,13 @@ 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 wl1271_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);
int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
-int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send);
+int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send);
int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
size_t len);
int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
@@ -55,6 +56,7 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
u8 key_size, const u8 *key, const u8 *addr,
u32 tx_seq_32, u16 tx_seq_16);
int wl1271_cmd_disconnect(struct wl1271 *wl);
+int wl1271_cmd_set_sta_state(struct wl1271 *wl);
enum wl1271_commands {
CMD_INTERROGATE = 1, /*use this to read information elements*/
@@ -160,41 +162,6 @@ enum {
MAX_COMMAND_STATUS = 0xff
};
-
-/*
- * CMD_READ_MEMORY
- *
- * The host issues this command to read the WiLink device memory/registers.
- *
- * Note: The Base Band address has special handling (16 bits registers and
- * addresses). For more information, see the hardware specification.
- */
-/*
- * CMD_WRITE_MEMORY
- *
- * The host issues this command to write the WiLink device memory/registers.
- *
- * The Base Band address has special handling (16 bits registers and
- * addresses). For more information, see the hardware specification.
- */
-#define MAX_READ_SIZE 256
-
-struct cmd_read_write_memory {
- struct wl1271_cmd_header header;
-
- /* The address of the memory to read from or write to.*/
- __le32 addr;
-
- /* The amount of data in bytes to read from or write to the WiLink
- * device.*/
- __le32 size;
-
- /* The actual value read from or written to the Wilink. The source
- of this field is the Host in WRITE command or the Wilink in READ
- command. */
- u8 value[MAX_READ_SIZE];
-} __packed;
-
#define CMDMBOX_HEADER_LEN 4
#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
@@ -313,7 +280,7 @@ enum wl1271_cmd_key_type {
KEY_WEP = 1,
KEY_TKIP = 2,
KEY_AES = 3,
- KEY_GEM = 4
+ KEY_GEM = 4,
};
/* FIXME: Add description for key-types */
@@ -358,13 +325,14 @@ enum wl1271_channel_tune_bands {
WL1271_CHANNEL_TUNE_BAND_4_9
};
-#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
+#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
-#define TEST_CMD_P2G_CAL 0x02
-#define TEST_CMD_CHANNEL_TUNE 0x0d
-#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
-#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
-#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
+#define TEST_CMD_P2G_CAL 0x02
+#define TEST_CMD_CHANNEL_TUNE 0x0d
+#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
+#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
+#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
+#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
struct wl1271_general_parms_cmd {
struct wl1271_cmd_header header;
@@ -397,6 +365,16 @@ struct wl1271_radio_parms_cmd {
u8 padding3[2];
} __packed;
+struct wl1271_ext_radio_parms_cmd {
+ struct wl1271_cmd_header header;
+
+ struct wl1271_cmd_test_header test;
+
+ u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
+ u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
+ u8 padding[3];
+} __packed;
+
struct wl1271_cmd_cal_channel_tune {
struct wl1271_cmd_header header;
@@ -469,4 +447,13 @@ struct wl1271_cmd_disconnect {
u8 padding;
} __packed;
+#define WL1271_CMD_STA_STATE_CONNECTED 1
+
+struct wl1271_cmd_set_sta_state {
+ struct wl1271_cmd_header header;
+
+ u8 state;
+ u8 padding[3];
+} __packed;
+
#endif /* __WL1271_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 0435ffda8f73..5f78a6cb1433 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -595,7 +595,7 @@ struct conf_tx_ac_category {
u16 tx_op_limit;
};
-#define CONF_TX_MAX_TID_COUNT 7
+#define CONF_TX_MAX_TID_COUNT 8
enum {
CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/
@@ -912,6 +912,22 @@ struct conf_conn_settings {
u8 psm_entry_retries;
/*
+ * Specifies the maximum number of times to try transmit the PSM entry
+ * null-func frame for each PSM entry attempt
+ *
+ * Range 0 - 255
+ */
+ u8 psm_entry_nullfunc_retries;
+
+ /*
+ * Specifies the time to linger in active mode after successfully
+ * transmitting the PSM entry null-func frame.
+ *
+ * Range 0 - 255 TU's
+ */
+ u8 psm_entry_hangover_period;
+
+ /*
*
* Specifies the interval of the connection keep-alive null-func
* frame in ms.
@@ -1016,6 +1032,64 @@ struct conf_roam_trigger_settings {
u8 avg_weight_snr_data;
};
+struct conf_scan_settings {
+ /*
+ * The minimum time to wait on each channel for active scans
+ *
+ * Range: 0 - 65536 tu
+ */
+ u16 min_dwell_time_active;
+
+ /*
+ * The maximum time to wait on each channel for active scans
+ *
+ * Range: 0 - 65536 tu
+ */
+ u16 max_dwell_time_active;
+
+ /*
+ * The maximum time to wait on each channel for passive scans
+ *
+ * Range: 0 - 65536 tu
+ */
+ u16 min_dwell_time_passive;
+
+ /*
+ * The maximum time to wait on each channel for passive scans
+ *
+ * Range: 0 - 65536 tu
+ */
+ u16 max_dwell_time_passive;
+
+ /*
+ * Number of probe requests to transmit on each active scan channel
+ *
+ * Range: u8
+ */
+ u16 num_probe_reqs;
+
+};
+
+/* 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
+
+struct conf_rf_settings {
+ /*
+ * Per channel power compensation for 2.4GHz
+ *
+ * Range: s8
+ */
+ u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
+
+ /*
+ * Per channel power compensation for 5GHz
+ *
+ * Range: s8
+ */
+ u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
+};
+
struct conf_drv_settings {
struct conf_sg_settings sg;
struct conf_rx_settings rx;
@@ -1024,6 +1098,8 @@ struct conf_drv_settings {
struct conf_itrim_settings itrim;
struct conf_pm_config_settings pm_config;
struct conf_roam_trigger_settings roam_trigger;
+ struct conf_scan_settings scan;
+ struct conf_rf_settings rf;
};
#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 25ce2cd5e3f3..7b3f50382963 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -41,6 +41,9 @@ void wl1271_pspoll_work(struct work_struct *work)
mutex_lock(&wl->mutex);
+ if (unlikely(wl->state == WL1271_STATE_OFF))
+ goto out;
+
if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags))
goto out;
@@ -52,7 +55,7 @@ void wl1271_pspoll_work(struct work_struct *work)
* delivery failure occurred, and no-one changed state since, so
* we should go back to powersave.
*/
- wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, true);
+ wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true);
out:
mutex_unlock(&wl->mutex);
@@ -70,7 +73,8 @@ static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl)
/* force active mode receive data from the AP */
if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
- ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, true);
+ ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
+ wl->basic_rate, true);
if (ret < 0)
return;
set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags);
@@ -91,6 +95,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
bool *beacon_loss)
{
int ret = 0;
+ u32 total_retries = wl->conf.conn.psm_entry_retries;
wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);
@@ -104,10 +109,10 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
break;
}
- if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
+ if (wl->psm_entry_retry < total_retries) {
wl->psm_entry_retry++;
ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
- true);
+ wl->basic_rate, true);
} else {
wl1271_info("No ack to nullfunc from AP.");
wl->psm_entry_retry = 0;
@@ -143,7 +148,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
/* make sure the firmware goes to active mode - the frame to
be sent next will indicate to the AP, that we are active. */
ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
- false);
+ wl->basic_rate, false);
break;
case EVENT_EXIT_POWER_SAVE_SUCCESS:
default:
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index 4447af1557f5..8044bba70ee7 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -53,6 +53,7 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
int wl1271_init_templates_config(struct wl1271 *wl)
{
int ret, i;
+ size_t size;
/* send empty templates for fw memory reservation */
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
@@ -61,14 +62,12 @@ int wl1271_init_templates_config(struct wl1271 *wl)
if (ret < 0)
return ret;
- if (wl1271_11a_enabled()) {
- size_t size = sizeof(struct wl12xx_probe_req_template);
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
- NULL, size, 0,
- WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
- }
+ size = sizeof(struct wl12xx_probe_req_template);
+ ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+ NULL, size, 0,
+ WL1271_RATE_AUTOMATIC);
+ if (ret < 0)
+ return ret;
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
sizeof(struct wl12xx_null_data_template),
@@ -223,6 +222,10 @@ int wl1271_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;
+ ret = wl1271_cmd_ext_radio_parms(wl);
+ if (ret < 0)
+ return ret;
+
/* Template settings */
ret = wl1271_init_templates_config(wl);
if (ret < 0)
@@ -291,8 +294,16 @@ int wl1271_hw_init(struct wl1271 *wl)
if (ret < 0)
goto out_free_memmap;
- /* Default TID configuration */
+ /* Default TID/AC configuration */
+ BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
+ conf_ac = &wl->conf.tx.ac_conf[i];
+ ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
+ conf_ac->cw_max, conf_ac->aifsn,
+ conf_ac->tx_op_limit);
+ if (ret < 0)
+ goto out_free_memmap;
+
conf_tid = &wl->conf.tx.tid_conf[i];
ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
conf_tid->channel_type,
@@ -305,16 +316,6 @@ int wl1271_hw_init(struct wl1271 *wl)
goto out_free_memmap;
}
- /* Default AC configuration */
- for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
- conf_ac = &wl->conf.tx.ac_conf[i];
- ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
- conf_ac->cw_max, conf_ac->aifsn,
- conf_ac->tx_op_limit);
- if (ret < 0)
- goto out_free_memmap;
- }
-
/* Configure TX rate classes */
ret = wl1271_acx_rate_policies(wl);
if (ret < 0)
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h
index bc806c74c63a..c1f92e65ded0 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.h
+++ b/drivers/net/wireless/wl12xx/wl1271_io.h
@@ -144,10 +144,13 @@ static inline void wl1271_power_off(struct wl1271 *wl)
clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
}
-static inline void wl1271_power_on(struct wl1271 *wl)
+static inline int wl1271_power_on(struct wl1271 *wl)
{
- wl->if_ops->power(wl, true);
- set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+ int ret = wl->if_ops->power(wl, true);
+ if (ret == 0)
+ set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+
+ return ret;
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 9d68f0012f05..48a4b9961ae6 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -124,28 +124,28 @@ static struct conf_drv_settings default_conf = {
},
.ac_conf_count = 4,
.ac_conf = {
- [0] = {
+ [CONF_TX_AC_BE] = {
.ac = CONF_TX_AC_BE,
.cw_min = 15,
.cw_max = 63,
.aifsn = 3,
.tx_op_limit = 0,
},
- [1] = {
+ [CONF_TX_AC_BK] = {
.ac = CONF_TX_AC_BK,
.cw_min = 15,
.cw_max = 63,
.aifsn = 7,
.tx_op_limit = 0,
},
- [2] = {
+ [CONF_TX_AC_VI] = {
.ac = CONF_TX_AC_VI,
.cw_min = 15,
.cw_max = 63,
.aifsn = CONF_TX_AIFS_PIFS,
.tx_op_limit = 3008,
},
- [3] = {
+ [CONF_TX_AC_VO] = {
.ac = CONF_TX_AC_VO,
.cw_min = 15,
.cw_max = 63,
@@ -153,64 +153,40 @@ static struct conf_drv_settings default_conf = {
.tx_op_limit = 1504,
},
},
- .tid_conf_count = 7,
+ .tid_conf_count = 4,
.tid_conf = {
- [0] = {
- .queue_id = 0,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
- .ps_scheme = CONF_PS_SCHEME_LEGACY,
- .ack_policy = CONF_ACK_POLICY_LEGACY,
- .apsd_conf = {0, 0},
- },
- [1] = {
- .queue_id = 1,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
+ [CONF_TX_AC_BE] = {
+ .queue_id = CONF_TX_AC_BE,
+ .channel_type = CONF_CHANNEL_TYPE_EDCF,
.tsid = CONF_TX_AC_BE,
.ps_scheme = CONF_PS_SCHEME_LEGACY,
.ack_policy = CONF_ACK_POLICY_LEGACY,
.apsd_conf = {0, 0},
},
- [2] = {
- .queue_id = 2,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
+ [CONF_TX_AC_BK] = {
+ .queue_id = CONF_TX_AC_BK,
+ .channel_type = CONF_CHANNEL_TYPE_EDCF,
+ .tsid = CONF_TX_AC_BK,
.ps_scheme = CONF_PS_SCHEME_LEGACY,
.ack_policy = CONF_ACK_POLICY_LEGACY,
.apsd_conf = {0, 0},
},
- [3] = {
- .queue_id = 3,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
- .ps_scheme = CONF_PS_SCHEME_LEGACY,
- .ack_policy = CONF_ACK_POLICY_LEGACY,
- .apsd_conf = {0, 0},
- },
- [4] = {
- .queue_id = 4,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
+ [CONF_TX_AC_VI] = {
+ .queue_id = CONF_TX_AC_VI,
+ .channel_type = CONF_CHANNEL_TYPE_EDCF,
+ .tsid = CONF_TX_AC_VI,
.ps_scheme = CONF_PS_SCHEME_LEGACY,
.ack_policy = CONF_ACK_POLICY_LEGACY,
.apsd_conf = {0, 0},
},
- [5] = {
- .queue_id = 5,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
+ [CONF_TX_AC_VO] = {
+ .queue_id = CONF_TX_AC_VO,
+ .channel_type = CONF_CHANNEL_TYPE_EDCF,
+ .tsid = CONF_TX_AC_VO,
.ps_scheme = CONF_PS_SCHEME_LEGACY,
.ack_policy = CONF_ACK_POLICY_LEGACY,
.apsd_conf = {0, 0},
},
- [6] = {
- .queue_id = 6,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
- .ps_scheme = CONF_PS_SCHEME_LEGACY,
- .ack_policy = CONF_ACK_POLICY_LEGACY,
- .apsd_conf = {0, 0},
- }
},
.frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
.tx_compl_timeout = 700,
@@ -238,7 +214,9 @@ static struct conf_drv_settings default_conf = {
.ps_poll_recovery_period = 700,
.bet_enable = CONF_BET_MODE_ENABLE,
.bet_max_consecutive = 10,
- .psm_entry_retries = 3,
+ .psm_entry_retries = 5,
+ .psm_entry_nullfunc_retries = 3,
+ .psm_entry_hangover_period = 1,
.keep_alive_interval = 55000,
.max_listen_interval = 20,
},
@@ -251,15 +229,34 @@ static struct conf_drv_settings default_conf = {
.host_fast_wakeup_support = false
},
.roam_trigger = {
- /* FIXME: due to firmware bug, must use value 1 for now */
.trigger_pacing = 1,
.avg_weight_rssi_beacon = 20,
.avg_weight_rssi_data = 10,
.avg_weight_snr_beacon = 20,
.avg_weight_snr_data = 10
- }
+ },
+ .scan = {
+ .min_dwell_time_active = 7500,
+ .max_dwell_time_active = 30000,
+ .min_dwell_time_passive = 30000,
+ .max_dwell_time_passive = 60000,
+ .num_probe_reqs = 2,
+ },
+ .rf = {
+ .tx_per_channel_power_compensation_2 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ .tx_per_channel_power_compensation_5 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ },
};
+static void __wl1271_op_remove_interface(struct wl1271 *wl);
+
+
static void wl1271_device_release(struct device *dev)
{
@@ -277,6 +274,67 @@ static struct platform_device wl1271_device = {
static LIST_HEAD(wl_list);
+static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
+ void *arg)
+{
+ struct net_device *dev = arg;
+ struct wireless_dev *wdev;
+ struct wiphy *wiphy;
+ struct ieee80211_hw *hw;
+ struct wl1271 *wl;
+ struct wl1271 *wl_temp;
+ int ret = 0;
+
+ /* Check that this notification is for us. */
+ if (what != NETDEV_CHANGE)
+ return NOTIFY_DONE;
+
+ wdev = dev->ieee80211_ptr;
+ if (wdev == NULL)
+ return NOTIFY_DONE;
+
+ wiphy = wdev->wiphy;
+ if (wiphy == NULL)
+ return NOTIFY_DONE;
+
+ hw = wiphy_priv(wiphy);
+ if (hw == NULL)
+ return NOTIFY_DONE;
+
+ wl_temp = hw->priv;
+ list_for_each_entry(wl, &wl_list, list) {
+ if (wl == wl_temp)
+ break;
+ }
+ if (wl != wl_temp)
+ return NOTIFY_DONE;
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->state == WL1271_STATE_OFF)
+ goto out;
+
+ if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
+ goto out;
+
+ ret = wl1271_ps_elp_wakeup(wl, false);
+ if (ret < 0)
+ goto out;
+
+ if ((dev->operstate == IF_OPER_UP) &&
+ !test_and_set_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags)) {
+ wl1271_cmd_set_sta_state(wl);
+ wl1271_info("Association completed.");
+ }
+
+ wl1271_ps_elp_sleep(wl);
+
+out:
+ mutex_unlock(&wl->mutex);
+
+ return NOTIFY_OK;
+}
+
static void wl1271_conf_init(struct wl1271 *wl)
{
@@ -309,6 +367,10 @@ static int wl1271_plt_init(struct wl1271 *wl)
if (ret < 0)
return ret;
+ ret = wl1271_cmd_ext_radio_parms(wl);
+ if (ret < 0)
+ return ret;
+
ret = wl1271_init_templates_config(wl);
if (ret < 0)
return ret;
@@ -346,8 +408,16 @@ static int wl1271_plt_init(struct wl1271 *wl)
if (ret < 0)
goto out_free_memmap;
- /* Default TID configuration */
+ /* Default TID/AC configuration */
+ BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
+ conf_ac = &wl->conf.tx.ac_conf[i];
+ ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
+ conf_ac->cw_max, conf_ac->aifsn,
+ conf_ac->tx_op_limit);
+ if (ret < 0)
+ goto out_free_memmap;
+
conf_tid = &wl->conf.tx.tid_conf[i];
ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
conf_tid->channel_type,
@@ -360,16 +430,6 @@ static int wl1271_plt_init(struct wl1271 *wl)
goto out_free_memmap;
}
- /* Default AC configuration */
- for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
- conf_ac = &wl->conf.tx.ac_conf[i];
- ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
- conf_ac->cw_max, conf_ac->aifsn,
- conf_ac->tx_op_limit);
- if (ret < 0)
- goto out_free_memmap;
- }
-
/* Enable data path */
ret = wl1271_cmd_data_path(wl, 1);
if (ret < 0)
@@ -562,20 +622,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
return ret;
}
- /*
- * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
- * configurations) can be removed when those NVS files stop floating
- * around.
- */
- if (fw->size != sizeof(struct wl1271_nvs_file) &&
- (fw->size != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
- wl1271_11a_enabled())) {
- wl1271_error("nvs size is not as expected: %zu != %zu",
- fw->size, sizeof(struct wl1271_nvs_file));
- ret = -EILSEQ;
- goto out;
- }
-
wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
if (!wl->nvs) {
@@ -584,12 +630,37 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
goto out;
}
+ wl->nvs_len = fw->size;
+
out:
release_firmware(fw);
return ret;
}
+static void wl1271_recovery_work(struct work_struct *work)
+{
+ struct wl1271 *wl =
+ container_of(work, struct wl1271, recovery_work);
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->state != WL1271_STATE_ON)
+ goto out;
+
+ wl1271_info("Hardware recovery in progress.");
+
+ if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
+ ieee80211_connection_loss(wl->vif);
+
+ /* reboot the chipset */
+ __wl1271_op_remove_interface(wl);
+ ieee80211_restart_hw(wl->hw);
+
+out:
+ mutex_unlock(&wl->mutex);
+}
+
static void wl1271_fw_wakeup(struct wl1271 *wl)
{
u32 elp_reg;
@@ -610,8 +681,6 @@ static int wl1271_setup(struct wl1271 *wl)
return -ENOMEM;
}
- INIT_WORK(&wl->irq_work, wl1271_irq_work);
- INIT_WORK(&wl->tx_work, wl1271_tx_work);
return 0;
}
@@ -621,7 +690,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
int ret = 0;
msleep(WL1271_PRE_POWER_ON_SLEEP);
- wl1271_power_on(wl);
+ ret = wl1271_power_on(wl);
+ if (ret < 0)
+ goto out;
msleep(WL1271_POWER_ON_SLEEP);
wl1271_io_reset(wl);
wl1271_io_init(wl);
@@ -766,10 +837,12 @@ int wl1271_plt_stop(struct wl1271 *wl)
out:
mutex_unlock(&wl->mutex);
+ cancel_work_sync(&wl->irq_work);
+ cancel_work_sync(&wl->recovery_work);
+
return ret;
}
-
static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct wl1271 *wl = hw->priv;
@@ -812,6 +885,10 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
+static struct notifier_block wl1271_dev_notifier = {
+ .notifier_call = wl1271_dev_notify,
+};
+
static int wl1271_op_start(struct ieee80211_hw *hw)
{
wl1271_debug(DEBUG_MAC80211, "mac80211 start");
@@ -928,13 +1005,10 @@ out:
return ret;
}
-static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static void __wl1271_op_remove_interface(struct wl1271 *wl)
{
- struct wl1271 *wl = hw->priv;
int i;
- mutex_lock(&wl->mutex);
wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
wl1271_info("down");
@@ -948,12 +1022,10 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
ieee80211_enable_dyn_ps(wl->vif);
if (wl->scan.state != WL1271_SCAN_STATE_IDLE) {
- mutex_unlock(&wl->mutex);
- ieee80211_scan_completed(wl->hw, true);
- mutex_lock(&wl->mutex);
wl->scan.state = WL1271_SCAN_STATE_IDLE;
kfree(wl->scan.scanned_ch);
wl->scan.scanned_ch = NULL;
+ ieee80211_scan_completed(wl->hw, true);
}
wl->state = WL1271_STATE_OFF;
@@ -962,9 +1034,11 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
mutex_unlock(&wl->mutex);
+ cancel_delayed_work_sync(&wl->scan_complete_work);
cancel_work_sync(&wl->irq_work);
cancel_work_sync(&wl->tx_work);
cancel_delayed_work_sync(&wl->pspoll_work);
+ cancel_delayed_work_sync(&wl->elp_work);
mutex_lock(&wl->mutex);
@@ -1006,8 +1080,19 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
wl->tx_res_if = NULL;
kfree(wl->target_mem_map);
wl->target_mem_map = NULL;
+}
+static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct wl1271 *wl = hw->priv;
+
+ mutex_lock(&wl->mutex);
+ WARN_ON(wl->vif != vif);
+ __wl1271_op_remove_interface(wl);
mutex_unlock(&wl->mutex);
+
+ cancel_work_sync(&wl->recovery_work);
}
static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
@@ -1289,7 +1374,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
wl1271_debug(DEBUG_PSM, "psm enabled");
ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
- true);
+ wl->basic_rate, true);
}
} else if (!(conf->flags & IEEE80211_CONF_PS) &&
test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
@@ -1299,7 +1384,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
if (test_bit(WL1271_FLAG_PSM, &wl->flags))
ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
- true);
+ wl->basic_rate, true);
}
if (conf->power_level != wl->power_level) {
@@ -1439,7 +1524,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
- key_conf->alg, key_conf->keyidx,
+ key_conf->cipher, key_conf->keyidx,
key_conf->keylen, key_conf->flags);
wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
@@ -1455,28 +1540,34 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (ret < 0)
goto out_unlock;
- switch (key_conf->alg) {
- case ALG_WEP:
+ switch (key_conf->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
key_type = KEY_WEP;
key_conf->hw_key_idx = key_conf->keyidx;
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
key_type = KEY_TKIP;
key_conf->hw_key_idx = key_conf->keyidx;
tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
key_type = KEY_AES;
key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
break;
+ case WL1271_CIPHER_SUITE_GEM:
+ key_type = KEY_GEM;
+ tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
+ tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
+ break;
default:
- wl1271_error("Unknown key algo 0x%x", key_conf->alg);
+ wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
ret = -EOPNOTSUPP;
goto out_sleep;
@@ -1558,10 +1649,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
if (ret < 0)
goto out;
- if (wl1271_11a_enabled())
- ret = wl1271_scan(hw->priv, ssid, len, req);
- else
- ret = wl1271_scan(hw->priv, ssid, len, req);
+ ret = wl1271_scan(hw->priv, ssid, len, req);
wl1271_ps_elp_sleep(wl);
@@ -1633,7 +1721,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
if (ret < 0)
goto out;
- if ((changed && BSS_CHANGED_BEACON_INT) &&
+ if ((changed & BSS_CHANGED_BEACON_INT) &&
(wl->bss_type == BSS_TYPE_IBSS)) {
wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d",
bss_conf->beacon_int);
@@ -1642,7 +1730,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
do_join = true;
}
- if ((changed && BSS_CHANGED_BEACON) &&
+ if ((changed & BSS_CHANGED_BEACON) &&
(wl->bss_type == BSS_TYPE_IBSS)) {
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
@@ -1776,12 +1864,15 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&
!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
mode = STATION_POWER_SAVE_MODE;
- ret = wl1271_ps_set_mode(wl, mode, true);
+ ret = wl1271_ps_set_mode(wl, mode,
+ wl->basic_rate,
+ true);
if (ret < 0)
goto out_sleep;
}
} else {
/* use defaults when not associated */
+ clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags);
clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
wl->aid = 0;
@@ -1993,21 +2084,24 @@ static struct ieee80211_rate wl1271_rates[] = {
.hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
};
-/* can't be const, mac80211 writes to this */
+/*
+ * Can't be const, mac80211 writes to this. The order of the channels here
+ * is designed to improve scanning.
+ */
static struct ieee80211_channel wl1271_channels[] = {
{ .hw_value = 1, .center_freq = 2412, .max_power = 25 },
- { .hw_value = 2, .center_freq = 2417, .max_power = 25 },
- { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
- { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
{ .hw_value = 5, .center_freq = 2432, .max_power = 25 },
- { .hw_value = 6, .center_freq = 2437, .max_power = 25 },
- { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
- { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
{ .hw_value = 9, .center_freq = 2452, .max_power = 25 },
- { .hw_value = 10, .center_freq = 2457, .max_power = 25 },
- { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
- { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
{ .hw_value = 13, .center_freq = 2472, .max_power = 25 },
+ { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
+ { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
+ { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
+ { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
+ { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
+ { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
+ { .hw_value = 2, .center_freq = 2417, .max_power = 25 },
+ { .hw_value = 6, .center_freq = 2437, .max_power = 25 },
+ { .hw_value = 10, .center_freq = 2457, .max_power = 25 },
};
/* mapping to indexes for wl1271_rates */
@@ -2076,49 +2170,52 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = {
.hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
};
-/* 5 GHz band channels for WL1273 */
+/*
+ * 5 GHz band channels for WL1273 - can't be const, mac80211 writes to this.
+ * The order of the channels here is designed to improve scanning.
+ */
static struct ieee80211_channel wl1271_channels_5ghz[] = {
{ .hw_value = 183, .center_freq = 4915},
- { .hw_value = 184, .center_freq = 4920},
- { .hw_value = 185, .center_freq = 4925},
- { .hw_value = 187, .center_freq = 4935},
{ .hw_value = 188, .center_freq = 4940},
- { .hw_value = 189, .center_freq = 4945},
- { .hw_value = 192, .center_freq = 4960},
- { .hw_value = 196, .center_freq = 4980},
- { .hw_value = 7, .center_freq = 5035},
{ .hw_value = 8, .center_freq = 5040},
- { .hw_value = 9, .center_freq = 5045},
- { .hw_value = 11, .center_freq = 5055},
- { .hw_value = 12, .center_freq = 5060},
- { .hw_value = 16, .center_freq = 5080},
{ .hw_value = 34, .center_freq = 5170},
- { .hw_value = 36, .center_freq = 5180},
- { .hw_value = 38, .center_freq = 5190},
- { .hw_value = 40, .center_freq = 5200},
- { .hw_value = 42, .center_freq = 5210},
{ .hw_value = 44, .center_freq = 5220},
- { .hw_value = 46, .center_freq = 5230},
- { .hw_value = 48, .center_freq = 5240},
- { .hw_value = 52, .center_freq = 5260},
- { .hw_value = 56, .center_freq = 5280},
{ .hw_value = 60, .center_freq = 5300},
- { .hw_value = 64, .center_freq = 5320},
- { .hw_value = 100, .center_freq = 5500},
- { .hw_value = 104, .center_freq = 5520},
- { .hw_value = 108, .center_freq = 5540},
{ .hw_value = 112, .center_freq = 5560},
- { .hw_value = 116, .center_freq = 5580},
- { .hw_value = 120, .center_freq = 5600},
- { .hw_value = 124, .center_freq = 5620},
- { .hw_value = 128, .center_freq = 5640},
{ .hw_value = 132, .center_freq = 5660},
+ { .hw_value = 157, .center_freq = 5785},
+ { .hw_value = 184, .center_freq = 4920},
+ { .hw_value = 189, .center_freq = 4945},
+ { .hw_value = 9, .center_freq = 5045},
+ { .hw_value = 36, .center_freq = 5180},
+ { .hw_value = 46, .center_freq = 5230},
+ { .hw_value = 64, .center_freq = 5320},
+ { .hw_value = 116, .center_freq = 5580},
{ .hw_value = 136, .center_freq = 5680},
+ { .hw_value = 192, .center_freq = 4960},
+ { .hw_value = 11, .center_freq = 5055},
+ { .hw_value = 38, .center_freq = 5190},
+ { .hw_value = 48, .center_freq = 5240},
+ { .hw_value = 100, .center_freq = 5500},
+ { .hw_value = 120, .center_freq = 5600},
{ .hw_value = 140, .center_freq = 5700},
+ { .hw_value = 185, .center_freq = 4925},
+ { .hw_value = 196, .center_freq = 4980},
+ { .hw_value = 12, .center_freq = 5060},
+ { .hw_value = 40, .center_freq = 5200},
+ { .hw_value = 52, .center_freq = 5260},
+ { .hw_value = 104, .center_freq = 5520},
+ { .hw_value = 124, .center_freq = 5620},
{ .hw_value = 149, .center_freq = 5745},
- { .hw_value = 153, .center_freq = 5765},
- { .hw_value = 157, .center_freq = 5785},
{ .hw_value = 161, .center_freq = 5805},
+ { .hw_value = 187, .center_freq = 4935},
+ { .hw_value = 7, .center_freq = 5035},
+ { .hw_value = 16, .center_freq = 5080},
+ { .hw_value = 42, .center_freq = 5210},
+ { .hw_value = 56, .center_freq = 5280},
+ { .hw_value = 108, .center_freq = 5540},
+ { .hw_value = 128, .center_freq = 5640},
+ { .hw_value = 153, .center_freq = 5765},
{ .hw_value = 165, .center_freq = 5825},
};
@@ -2211,8 +2308,7 @@ static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
struct wl1271 *wl = dev_get_drvdata(dev);
ssize_t len;
- /* FIXME: what's the maximum length of buf? page size?*/
- len = 500;
+ len = PAGE_SIZE;
mutex_lock(&wl->mutex);
len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n",
@@ -2273,8 +2369,7 @@ static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev,
struct wl1271 *wl = dev_get_drvdata(dev);
ssize_t len;
- /* FIXME: what's the maximum length of buf? page size?*/
- len = 500;
+ len = PAGE_SIZE;
mutex_lock(&wl->mutex);
if (wl->hw_pg_ver >= 0)
@@ -2306,6 +2401,8 @@ int wl1271_register_hw(struct wl1271 *wl)
wl->mac80211_registered = true;
+ register_netdevice_notifier(&wl1271_dev_notifier);
+
wl1271_notice("loaded");
return 0;
@@ -2314,6 +2411,7 @@ EXPORT_SYMBOL_GPL(wl1271_register_hw);
void wl1271_unregister_hw(struct wl1271 *wl)
{
+ unregister_netdevice_notifier(&wl1271_dev_notifier);
ieee80211_unregister_hw(wl->hw);
wl->mac80211_registered = false;
@@ -2322,6 +2420,14 @@ EXPORT_SYMBOL_GPL(wl1271_unregister_hw);
int wl1271_init_ieee80211(struct wl1271 *wl)
{
+ static const u32 cipher_suites[] = {
+ WLAN_CIPHER_SUITE_WEP40,
+ WLAN_CIPHER_SUITE_WEP104,
+ WLAN_CIPHER_SUITE_TKIP,
+ WLAN_CIPHER_SUITE_CCMP,
+ WL1271_CIPHER_SUITE_GEM,
+ };
+
/* The tx descriptor buffer and the TKIP space. */
wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE +
sizeof(struct wl1271_tx_hw_descr);
@@ -2339,13 +2445,14 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
IEEE80211_HW_CONNECTION_MONITOR |
IEEE80211_HW_SUPPORTS_CQM_RSSI;
+ wl->hw->wiphy->cipher_suites = cipher_suites;
+ wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
wl->hw->wiphy->max_scan_ssids = 1;
wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
-
- if (wl1271_11a_enabled())
- wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
+ wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
wl->hw->queues = 4;
wl->hw->max_rates = 1;
@@ -2364,6 +2471,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
struct platform_device *plat_dev = NULL;
struct wl1271 *wl;
int i, ret;
+ unsigned int order;
hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
if (!hw) {
@@ -2391,6 +2499,10 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work);
+ INIT_WORK(&wl->irq_work, wl1271_irq_work);
+ INIT_WORK(&wl->tx_work, wl1271_tx_work);
+ INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
+ INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
wl->channel = WL1271_DEFAULT_CHANNEL;
wl->beacon_int = WL1271_DEFAULT_BEACON_INT;
wl->default_key = 0;
@@ -2422,11 +2534,18 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl1271_debugfs_init(wl);
+ order = get_order(WL1271_AGGR_BUFFER_SIZE);
+ wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
+ if (!wl->aggr_buf) {
+ ret = -ENOMEM;
+ goto err_hw;
+ }
+
/* Register platform device */
ret = platform_device_register(wl->plat_dev);
if (ret) {
wl1271_error("couldn't register platform device");
- goto err_hw;
+ goto err_aggr;
}
dev_set_drvdata(&wl->plat_dev->dev, wl);
@@ -2452,6 +2571,9 @@ err_bt_coex_state:
err_platform:
platform_device_unregister(wl->plat_dev);
+err_aggr:
+ free_pages((unsigned long)wl->aggr_buf, order);
+
err_hw:
wl1271_debugfs_exit(wl);
kfree(plat_dev);
@@ -2468,6 +2590,8 @@ EXPORT_SYMBOL_GPL(wl1271_alloc_hw);
int wl1271_free_hw(struct wl1271 *wl)
{
platform_device_unregister(wl->plat_dev);
+ free_pages((unsigned long)wl->aggr_buf,
+ get_order(WL1271_AGGR_BUFFER_SIZE));
kfree(wl->plat_dev);
wl1271_debugfs_exit(wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
index a5e60e0403e5..e3c332e2f97c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -39,6 +39,9 @@ void wl1271_elp_work(struct work_struct *work)
mutex_lock(&wl->mutex);
+ if (unlikely(wl->state == WL1271_STATE_OFF))
+ 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,7 +64,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
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));
+ msecs_to_jiffies(ELP_ENTRY_DELAY));
}
}
@@ -96,6 +99,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake)
&compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
if (ret == 0) {
wl1271_error("ELP wakeup timeout!");
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
ret = -ETIMEDOUT;
goto err;
} else if (ret < 0) {
@@ -121,7 +125,7 @@ out:
}
int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
- bool send)
+ u32 rates, bool send)
{
int ret;
@@ -129,7 +133,14 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
case STATION_POWER_SAVE_MODE:
wl1271_debug(DEBUG_PSM, "entering psm");
- ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send);
+ ret = wl1271_acx_wake_up_conditions(wl);
+ if (ret < 0) {
+ wl1271_error("couldn't set wake up conditions");
+ return ret;
+ }
+
+ ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE,
+ rates, send);
if (ret < 0)
return ret;
@@ -152,7 +163,8 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
if (ret < 0)
return ret;
- ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, send);
+ ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE,
+ rates, send);
if (ret < 0)
return ret;
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h
index 940276f517a4..6ba7b032736f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.h
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.h
@@ -28,7 +28,7 @@
#include "wl1271_acx.h"
int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
- bool send);
+ u32 rates, bool send);
void wl1271_ps_elp_sleep(struct wl1271 *wl);
int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
void wl1271_elp_work(struct work_struct *work);
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index 019aa79cd9df..bea133b6e489 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -74,9 +74,8 @@ static void wl1271_rx_status(struct wl1271 *wl,
}
}
-static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
+static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
{
- struct ieee80211_rx_status rx_status;
struct wl1271_rx_descriptor *desc;
struct sk_buff *skb;
u16 *fc;
@@ -88,16 +87,16 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
* workaround this by not retrieving them at all.
*/
if (unlikely(wl->state == WL1271_STATE_PLT))
- return;
+ return -EINVAL;
skb = __dev_alloc_skb(length, GFP_KERNEL);
if (!skb) {
wl1271_error("Couldn't allocate RX frame");
- return;
+ return -ENOMEM;
}
buf = skb_put(skb, length);
- wl1271_read(wl, WL1271_SLV_MEM_DATA, buf, length, true);
+ memcpy(buf, data, length);
/* the data read starts with the descriptor */
desc = (struct wl1271_rx_descriptor *) buf;
@@ -109,15 +108,16 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
beacon = 1;
- wl1271_rx_status(wl, desc, &rx_status, beacon);
+ wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
beacon ? "beacon" : "");
skb_trim(skb, skb->len - desc->pad_len);
- memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
ieee80211_rx_ni(wl->hw, skb);
+
+ return 0;
}
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
@@ -126,31 +126,60 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
u32 buf_size;
u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
+ u32 rx_counter;
u32 mem_block;
+ u32 pkt_length;
+ u32 pkt_offset;
while (drv_rx_counter != fw_rx_counter) {
- mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter);
- buf_size = wl1271_rx_get_buf_size(status, drv_rx_counter);
+ buf_size = 0;
+ rx_counter = drv_rx_counter;
+ while (rx_counter != fw_rx_counter) {
+ pkt_length = wl1271_rx_get_buf_size(status, rx_counter);
+ if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE)
+ break;
+ buf_size += pkt_length;
+ rx_counter++;
+ rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
+ }
if (buf_size == 0) {
wl1271_warning("received empty data");
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;
-
- /* Choose the block we want to read */
wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr,
- sizeof(wl->rx_mem_pool_addr), false);
-
- wl1271_rx_handle_data(wl, buf_size);
-
- wl->rx_counter++;
- drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
+ sizeof(wl->rx_mem_pool_addr), false);
+
+ /* Read all available packets at once */
+ wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
+ buf_size, true);
+
+ /* Split data into separate packets */
+ pkt_offset = 0;
+ while (pkt_offset < buf_size) {
+ pkt_length = wl1271_rx_get_buf_size(status,
+ drv_rx_counter);
+ if (wl1271_rx_handle_data(wl,
+ wl->aggr_buf + pkt_offset,
+ pkt_length) < 0)
+ break;
+ wl->rx_counter++;
+ drv_rx_counter++;
+ drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
+ pkt_offset += pkt_length;
+ }
}
-
- wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
+ wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS,
+ cpu_to_le32(wl->rx_counter));
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c
index fec43eed8c55..909bb47995b6 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.c
+++ b/drivers/net/wireless/wl12xx/wl1271_scan.c
@@ -28,11 +28,43 @@
#include "wl1271_scan.h"
#include "wl1271_acx.h"
+void wl1271_scan_complete_work(struct work_struct *work)
+{
+ struct delayed_work *dwork;
+ struct wl1271 *wl;
+
+ dwork = container_of(work, struct delayed_work, work);
+ wl = container_of(dwork, struct wl1271, scan_complete_work);
+
+ wl1271_debug(DEBUG_SCAN, "Scanning complete");
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->scan.state == WL1271_SCAN_STATE_IDLE) {
+ mutex_unlock(&wl->mutex);
+ return;
+ }
+
+ wl->scan.state = WL1271_SCAN_STATE_IDLE;
+ kfree(wl->scan.scanned_ch);
+ wl->scan.scanned_ch = NULL;
+ mutex_unlock(&wl->mutex);
+
+ ieee80211_scan_completed(wl->hw, false);
+
+ if (wl->scan.failed) {
+ wl1271_info("Scan completed due to error.");
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
+ }
+}
+
+
static int wl1271_get_scan_channels(struct wl1271 *wl,
struct cfg80211_scan_request *req,
struct basic_scan_channel_params *channels,
enum ieee80211_band band, bool passive)
{
+ struct conf_scan_settings *c = &wl->conf.scan;
int i, j;
u32 flags;
@@ -60,10 +92,17 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
wl1271_debug(DEBUG_SCAN, "beacon_found %d",
req->channels[i]->beacon_found);
- channels[j].min_duration =
- cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION);
- channels[j].max_duration =
- cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION);
+ if (!passive) {
+ channels[j].min_duration =
+ cpu_to_le32(c->min_dwell_time_active);
+ channels[j].max_duration =
+ cpu_to_le32(c->max_dwell_time_active);
+ } else {
+ channels[j].min_duration =
+ cpu_to_le32(c->min_dwell_time_passive);
+ channels[j].max_duration =
+ cpu_to_le32(c->max_dwell_time_passive);
+ }
channels[j].early_termination = 0;
channels[j].tx_power_att = req->channels[i]->max_power;
channels[j].channel = req->channels[i]->hw_value;
@@ -100,8 +139,11 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
/* We always use high priority scans */
scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH;
- if(passive)
+
+ /* No SSIDs means that we have a forced passive scan */
+ if (passive || wl->scan.req->n_ssids == 0)
scan_options |= WL1271_SCAN_OPT_PASSIVE;
+
cmd->params.scan_options = cpu_to_le16(scan_options);
cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req,
@@ -117,7 +159,7 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
cmd->params.rx_filter_options =
cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
- cmd->params.n_probe_reqs = WL1271_SCAN_PROBE_REQS;
+ cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs;
cmd->params.tx_rate = cpu_to_le32(basic_rate);
cmd->params.tid_trigger = 0;
cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
@@ -165,7 +207,7 @@ out:
void wl1271_scan_stm(struct wl1271 *wl)
{
- int ret;
+ int ret = 0;
switch (wl->scan.state) {
case WL1271_SCAN_STATE_IDLE:
@@ -185,7 +227,7 @@ void wl1271_scan_stm(struct wl1271 *wl)
ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true,
wl->conf.tx.basic_rate);
if (ret == WL1271_NOTHING_TO_SCAN) {
- if (wl1271_11a_enabled())
+ if (wl->enable_11a)
wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
else
wl->scan.state = WL1271_SCAN_STATE_DONE;
@@ -215,20 +257,22 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;
case WL1271_SCAN_STATE_DONE:
- mutex_unlock(&wl->mutex);
- ieee80211_scan_completed(wl->hw, false);
- mutex_lock(&wl->mutex);
-
- kfree(wl->scan.scanned_ch);
- wl->scan.scanned_ch = NULL;
-
- wl->scan.state = WL1271_SCAN_STATE_IDLE;
+ wl->scan.failed = false;
+ cancel_delayed_work(&wl->scan_complete_work);
+ ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
+ msecs_to_jiffies(0));
break;
default:
wl1271_error("invalid scan state");
break;
}
+
+ if (ret < 0) {
+ cancel_delayed_work(&wl->scan_complete_work);
+ ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
+ msecs_to_jiffies(0));
+ }
}
int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
@@ -248,9 +292,14 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
wl->scan.req = req;
- wl->scan.scanned_ch = kzalloc(req->n_channels *
+ 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,
+ msecs_to_jiffies(WL1271_SCAN_TIMEOUT));
+
wl1271_scan_stm(wl);
return 0;
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h
index f1815700f5f9..6d57127b5e6b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.h
+++ b/drivers/net/wireless/wl12xx/wl1271_scan.h
@@ -32,6 +32,7 @@ int wl1271_scan_build_probe_req(struct wl1271 *wl,
const u8 *ssid, size_t ssid_len,
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);
#define WL1271_SCAN_MAX_CHANNELS 24
#define WL1271_SCAN_DEFAULT_TAG 1
@@ -39,11 +40,10 @@ void wl1271_scan_stm(struct wl1271 *wl);
#define WL1271_SCAN_OPT_ACTIVE 0
#define WL1271_SCAN_OPT_PASSIVE 1
#define WL1271_SCAN_OPT_PRIORITY_HIGH 4
-#define WL1271_SCAN_CHAN_MIN_DURATION 30000 /* TU */
-#define WL1271_SCAN_CHAN_MAX_DURATION 60000 /* TU */
#define WL1271_SCAN_BAND_2_4_GHZ 0
#define WL1271_SCAN_BAND_5_GHZ 1
-#define WL1271_SCAN_PROBE_REQS 3
+
+#define WL1271_SCAN_TIMEOUT 10000 /* msec */
enum {
WL1271_SCAN_STATE_IDLE,
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 7059b5cccf0f..784ef3432641 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -29,14 +29,13 @@
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/card.h>
#include <linux/gpio.h>
+#include <linux/wl12xx.h>
+#include <linux/pm_runtime.h>
#include "wl1271.h"
#include "wl12xx_80211.h"
#include "wl1271_io.h"
-
-#define RX71_WL1271_IRQ_GPIO 42
-
#ifndef SDIO_VENDOR_ID_TI
#define SDIO_VENDOR_ID_TI 0x0097
#endif
@@ -107,6 +106,8 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
int ret;
struct sdio_func *func = wl_to_func(wl);
+ sdio_claim_host(func);
+
if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x",
@@ -122,9 +123,10 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
}
+ sdio_release_host(func);
+
if (ret)
wl1271_error("sdio read failed (%d)", ret);
-
}
static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
@@ -133,6 +135,8 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
int ret;
struct sdio_func *func = wl_to_func(wl);
+ sdio_claim_host(func);
+
if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
@@ -147,26 +151,49 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
else
ret = sdio_memcpy_toio(func, addr, buf, len);
}
+
+ sdio_release_host(func);
+
if (ret)
wl1271_error("sdio write failed (%d)", ret);
+}
+static int wl1271_sdio_power_on(struct wl1271 *wl)
+{
+ struct sdio_func *func = wl_to_func(wl);
+ int ret;
+
+ /* Power up the card */
+ ret = pm_runtime_get_sync(&func->dev);
+ if (ret < 0)
+ goto out;
+
+ sdio_claim_host(func);
+ sdio_enable_func(func);
+ sdio_release_host(func);
+
+out:
+ return ret;
}
-static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
+static int wl1271_sdio_power_off(struct wl1271 *wl)
{
struct sdio_func *func = wl_to_func(wl);
- /* Let the SDIO stack handle wlan_enable control, so we
- * keep host claimed while wlan is in use to keep wl1271
- * alive.
- */
- if (enable) {
- sdio_claim_host(func);
- sdio_enable_func(func);
- } else {
- sdio_disable_func(func);
- sdio_release_host(func);
- }
+ sdio_claim_host(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+
+ /* Power down the card */
+ return pm_runtime_put_sync(&func->dev);
+}
+
+static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
+{
+ if (enable)
+ return wl1271_sdio_power_on(wl);
+ else
+ return wl1271_sdio_power_off(wl);
}
static struct wl1271_if_operations sdio_ops = {
@@ -184,6 +211,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
struct ieee80211_hw *hw;
+ const struct wl12xx_platform_data *wlan_data;
struct wl1271 *wl;
int ret;
@@ -203,13 +231,16 @@ static int __devinit wl1271_probe(struct sdio_func *func,
/* Grab access to FN0 for ELP reg. */
func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
- wl->irq = gpio_to_irq(RX71_WL1271_IRQ_GPIO);
- if (wl->irq < 0) {
- ret = wl->irq;
- wl1271_error("could not get irq!");
+ wlan_data = wl12xx_get_platform_data();
+ if (IS_ERR(wlan_data)) {
+ ret = PTR_ERR(wlan_data);
+ wl1271_error("missing wlan platform data: %d", ret);
goto out_free;
}
+ wl->irq = wlan_data->irq;
+ wl->ref_clock = wlan_data->board_ref_clock;
+
ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
if (ret < 0) {
wl1271_error("request_irq() failed: %d", ret);
@@ -230,6 +261,9 @@ static int __devinit wl1271_probe(struct sdio_func *func,
sdio_set_drvdata(func, wl);
+ /* Tell PM core that we don't need the card to be powered now */
+ pm_runtime_put_noidle(&func->dev);
+
wl1271_notice("initialized");
return 0;
@@ -248,17 +282,39 @@ static void __devexit wl1271_remove(struct sdio_func *func)
{
struct wl1271 *wl = sdio_get_drvdata(func);
- free_irq(wl->irq, wl);
+ /* Undo decrement done above in wl1271_probe */
+ pm_runtime_get_noresume(&func->dev);
wl1271_unregister_hw(wl);
+ free_irq(wl->irq, wl);
wl1271_free_hw(wl);
}
+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;
+}
+
+static int wl1271_resume(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops wl1271_sdio_pm_ops = {
+ .suspend = wl1271_suspend,
+ .resume = wl1271_resume,
+};
+
static struct sdio_driver wl1271_sdio_driver = {
.name = "wl1271_sdio",
.id_table = wl1271_devices,
.probe = wl1271_probe,
.remove = __devexit_p(wl1271_remove),
+ .drv = {
+ .pm = &wl1271_sdio_pm_ops,
+ },
};
static int __init wl1271_init(void)
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 4cb99c541e2a..ef801680773f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -25,7 +25,7 @@
#include <linux/module.h>
#include <linux/crc7.h>
#include <linux/spi/spi.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
#include <linux/slab.h>
#include "wl1271.h"
@@ -63,6 +63,11 @@
((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
+/* HW limitation: maximum possible chunk size is 4095 bytes */
+#define WSPI_MAX_CHUNK_SIZE 4092
+
+#define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
+
static inline struct spi_device *wl_to_spi(struct wl1271 *wl)
{
return wl->if_priv;
@@ -202,90 +207,117 @@ static int wl1271_spi_read_busy(struct wl1271 *wl)
static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
size_t len, bool fixed)
{
- struct spi_transfer t[3];
+ struct spi_transfer t[2];
struct spi_message m;
u32 *busy_buf;
u32 *cmd;
+ u32 chunk_len;
- cmd = &wl->buffer_cmd;
- busy_buf = wl->buffer_busyword;
+ while (len > 0) {
+ chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len);
- *cmd = 0;
- *cmd |= WSPI_CMD_READ;
- *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
- *cmd |= addr & WSPI_CMD_BYTE_ADDR;
+ cmd = &wl->buffer_cmd;
+ busy_buf = wl->buffer_busyword;
- if (fixed)
- *cmd |= WSPI_CMD_FIXED;
+ *cmd = 0;
+ *cmd |= WSPI_CMD_READ;
+ *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
+ WSPI_CMD_BYTE_LENGTH;
+ *cmd |= addr & WSPI_CMD_BYTE_ADDR;
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
+ if (fixed)
+ *cmd |= WSPI_CMD_FIXED;
- t[0].tx_buf = cmd;
- t[0].len = 4;
- t[0].cs_change = true;
- spi_message_add_tail(&t[0], &m);
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
- /* Busy and non busy words read */
- t[1].rx_buf = busy_buf;
- t[1].len = WL1271_BUSY_WORD_LEN;
- t[1].cs_change = true;
- spi_message_add_tail(&t[1], &m);
+ t[0].tx_buf = cmd;
+ t[0].len = 4;
+ t[0].cs_change = true;
+ spi_message_add_tail(&t[0], &m);
- spi_sync(wl_to_spi(wl), &m);
+ /* Busy and non busy words read */
+ t[1].rx_buf = busy_buf;
+ t[1].len = WL1271_BUSY_WORD_LEN;
+ t[1].cs_change = true;
+ spi_message_add_tail(&t[1], &m);
- if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
- wl1271_spi_read_busy(wl)) {
- memset(buf, 0, len);
- return;
- }
+ spi_sync(wl_to_spi(wl), &m);
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
+ if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
+ wl1271_spi_read_busy(wl)) {
+ memset(buf, 0, chunk_len);
+ return;
+ }
- t[0].rx_buf = buf;
- t[0].len = len;
- t[0].cs_change = true;
- spi_message_add_tail(&t[0], &m);
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
- spi_sync(wl_to_spi(wl), &m);
+ t[0].rx_buf = buf;
+ t[0].len = chunk_len;
+ t[0].cs_change = true;
+ spi_message_add_tail(&t[0], &m);
- wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
- wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
+ spi_sync(wl_to_spi(wl), &m);
+
+ wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
+ wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, chunk_len);
+
+ if (!fixed)
+ addr += chunk_len;
+ buf += chunk_len;
+ len -= chunk_len;
+ }
}
static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
size_t len, bool fixed)
{
- struct spi_transfer t[2];
+ struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
struct spi_message m;
+ u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
u32 *cmd;
+ u32 chunk_len;
+ int i;
- cmd = &wl->buffer_cmd;
-
- *cmd = 0;
- *cmd |= WSPI_CMD_WRITE;
- *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
- *cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
- if (fixed)
- *cmd |= WSPI_CMD_FIXED;
+ WARN_ON(len > WL1271_AGGR_BUFFER_SIZE);
spi_message_init(&m);
memset(t, 0, sizeof(t));
- t[0].tx_buf = cmd;
- t[0].len = sizeof(*cmd);
- spi_message_add_tail(&t[0], &m);
+ cmd = &commands[0];
+ i = 0;
+ while (len > 0) {
+ chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len);
- t[1].tx_buf = buf;
- t[1].len = len;
- spi_message_add_tail(&t[1], &m);
+ *cmd = 0;
+ *cmd |= WSPI_CMD_WRITE;
+ *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
+ WSPI_CMD_BYTE_LENGTH;
+ *cmd |= addr & WSPI_CMD_BYTE_ADDR;
- spi_sync(wl_to_spi(wl), &m);
+ if (fixed)
+ *cmd |= WSPI_CMD_FIXED;
+
+ t[i].tx_buf = cmd;
+ t[i].len = sizeof(*cmd);
+ spi_message_add_tail(&t[i++], &m);
+
+ t[i].tx_buf = buf;
+ t[i].len = chunk_len;
+ spi_message_add_tail(&t[i++], &m);
- wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
- wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
+ wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
+ wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, chunk_len);
+
+ if (!fixed)
+ addr += chunk_len;
+ buf += chunk_len;
+ len -= chunk_len;
+ cmd++;
+ }
+
+ spi_sync(wl_to_spi(wl), &m);
}
static irqreturn_t wl1271_irq(int irq, void *cookie)
@@ -312,10 +344,12 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
return IRQ_HANDLED;
}
-static void wl1271_spi_set_power(struct wl1271 *wl, bool enable)
+static int wl1271_spi_set_power(struct wl1271 *wl, bool enable)
{
if (wl->set_power)
wl->set_power(enable);
+
+ return 0;
}
static struct wl1271_if_operations spi_ops = {
@@ -370,6 +404,8 @@ static int __devinit wl1271_probe(struct spi_device *spi)
goto out_free;
}
+ wl->ref_clock = pdata->board_ref_clock;
+
wl->irq = spi->irq;
if (wl->irq < 0) {
wl1271_error("irq missing in platform data");
@@ -412,9 +448,8 @@ static int __devexit wl1271_remove(struct spi_device *spi)
{
struct wl1271 *wl = dev_get_drvdata(&spi->dev);
- free_irq(wl->irq, wl);
-
wl1271_unregister_hw(wl);
+ free_irq(wl->irq, wl);
wl1271_free_hw(wl);
return 0;
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c
index 6e0952f79e9a..a3aa84386c88 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.c
+++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c
@@ -199,19 +199,6 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
len = nla_len(tb[WL1271_TM_ATTR_DATA]);
- /*
- * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
- * configurations) can be removed when those NVS files stop floating
- * around.
- */
- if (len != sizeof(struct wl1271_nvs_file) &&
- (len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
- wl1271_11a_enabled())) {
- wl1271_error("nvs size is not as expected: %zu != %zu",
- len, sizeof(struct wl1271_nvs_file));
- return -EMSGSIZE;
- }
-
mutex_lock(&wl->mutex);
kfree(wl->nvs);
@@ -224,6 +211,7 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
}
memcpy(wl->nvs, buf, len);
+ wl->nvs_len = len;
wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs");
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index c592cc2e9fe8..e3dc13c4d01a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -43,13 +43,17 @@ static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb)
return -EBUSY;
}
-static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
+static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
+ u32 buf_offset)
{
struct wl1271_tx_hw_descr *desc;
u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
u32 total_blocks;
int id, ret = -EBUSY;
+ if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
+ return -EBUSY;
+
/* allocate free identifier for the packet */
id = wl1271_tx_id(wl, skb);
if (id < 0)
@@ -82,7 +86,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
return ret;
}
-static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
+static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
u32 extra, struct ieee80211_tx_info *control)
{
struct timespec ts;
@@ -110,9 +114,9 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
/* configure the tx attributes */
tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
- /* queue */
+ /* queue (we use same identifiers for tid's and ac's */
ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
- desc->tid = wl1271_tx_ac_to_tid(ac);
+ desc->tid = ac;
desc->aid = TX_HW_DEFAULT_AID;
desc->reserved = 0;
@@ -133,59 +137,17 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
desc->tx_attr = cpu_to_le16(tx_attr);
wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad);
- return 0;
-}
-
-static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb,
- struct ieee80211_tx_info *control)
-{
-
- struct wl1271_tx_hw_descr *desc;
- int len;
-
- /* FIXME: This is a workaround for getting non-aligned packets.
- This happens at least with EAPOL packets from the user space.
- Our DMA requires packets to be aligned on a 4-byte boundary.
- */
- if (unlikely((long)skb->data & 0x03)) {
- int offset = (4 - (long)skb->data) & 0x03;
- wl1271_debug(DEBUG_TX, "skb offset %d", offset);
-
- /* check whether the current skb can be used */
- if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
- unsigned char *src = skb->data;
-
- /* align the buffer on a 4-byte boundary */
- skb_reserve(skb, offset);
- memmove(skb->data, src, skb->len);
- } else {
- wl1271_info("No handler, fixme!");
- return -EINVAL;
- }
- }
-
- len = WL1271_TX_ALIGN(skb->len);
-
- /* perform a fixed address block write with the packet */
- wl1271_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);
-
- /* write packet new counter into the write access register */
- wl->tx_packets_count++;
-
- desc = (struct wl1271_tx_hw_descr *) skb->data;
- wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
- desc->id, skb, len, desc->length);
-
- return 0;
}
/* caller must hold wl->mutex */
-static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
+static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
+ u32 buf_offset)
{
struct ieee80211_tx_info *info;
u32 extra = 0;
int ret = 0;
u8 idx;
+ u32 total_len;
if (!skb)
return -EINVAL;
@@ -193,7 +155,7 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
info = IEEE80211_SKB_CB(skb);
if (info->control.hw_key &&
- info->control.hw_key->alg == ALG_TKIP)
+ info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
extra = WL1271_TKIP_IV_SPACE;
if (info->control.hw_key) {
@@ -208,19 +170,22 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
}
}
- ret = wl1271_tx_allocate(wl, skb, extra);
+ ret = wl1271_tx_allocate(wl, skb, extra, buf_offset);
if (ret < 0)
return ret;
- ret = wl1271_tx_fill_hdr(wl, skb, extra, info);
- if (ret < 0)
- return ret;
+ wl1271_tx_fill_hdr(wl, skb, extra, info);
- ret = wl1271_tx_send_packet(wl, skb, info);
- if (ret < 0)
- return ret;
+ /*
+ * 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
+ */
+ total_len = WL1271_TX_ALIGN(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);
- return ret;
+ return total_len;
}
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
@@ -245,7 +210,7 @@ void wl1271_tx_work(struct work_struct *work)
struct sk_buff *skb;
bool woken_up = false;
u32 sta_rates = 0;
- u32 prev_tx_packets_count;
+ u32 buf_offset;
int ret;
/* check if the rates supported by the AP have changed */
@@ -262,14 +227,15 @@ void wl1271_tx_work(struct work_struct *work)
if (unlikely(wl->state == WL1271_STATE_OFF))
goto out;
- prev_tx_packets_count = wl->tx_packets_count;
-
/* if rates have changed, re-configure the rate policy */
if (unlikely(sta_rates)) {
wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
wl1271_acx_rate_policies(wl);
}
+ /* Prepare the transfer buffer, by aggregating all
+ * available packets */
+ buf_offset = 0;
while ((skb = skb_dequeue(&wl->tx_queue))) {
if (!woken_up) {
ret = wl1271_ps_elp_wakeup(wl, false);
@@ -278,21 +244,30 @@ void wl1271_tx_work(struct work_struct *work)
woken_up = true;
}
- ret = wl1271_tx_frame(wl, skb);
+ ret = wl1271_prepare_tx_frame(wl, skb, buf_offset);
if (ret == -EBUSY) {
- /* firmware buffer is full, lets stop transmitting. */
+ /*
+ * Either the firmware buffer is full, or the
+ * aggregation buffer is.
+ * Queue back last skb, and stop aggregating.
+ */
skb_queue_head(&wl->tx_queue, skb);
goto out_ack;
} else if (ret < 0) {
dev_kfree_skb(skb);
goto out_ack;
}
+ buf_offset += ret;
+ wl->tx_packets_count++;
}
out_ack:
- /* interrupt the firmware with the new packets */
- if (prev_tx_packets_count != wl->tx_packets_count)
+ if (buf_offset) {
+ wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
+ buf_offset, true);
+ /* interrupt the firmware with the new packets */
wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
+ }
out:
if (woken_up)
@@ -347,7 +322,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
/* remove TKIP header space if present */
if (info->control.hw_key &&
- info->control.hw_key->alg == ALG_TKIP) {
+ 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);
@@ -422,8 +397,6 @@ void wl1271_tx_reset(struct wl1271 *wl)
struct sk_buff *skb;
/* TX failure */
-/* control->flags = 0; FIXME */
-
while ((skb = skb_dequeue(&wl->tx_queue))) {
wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
ieee80211_tx_status(wl->hw, skb);
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index 48bf92621c03..d12a129ad11c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -139,23 +139,6 @@ static inline int wl1271_tx_get_queue(int queue)
}
}
-/* wl1271 tx descriptor needs the tid and we need to convert it from ac */
-static inline int wl1271_tx_ac_to_tid(int ac)
-{
- switch (ac) {
- case 0:
- return 0;
- case 1:
- return 2;
- case 2:
- return 4;
- case 3:
- return 6;
- default:
- return 0;
- }
-}
-
void wl1271_tx_work(struct work_struct *work);
void wl1271_tx_complete(struct wl1271 *wl);
void wl1271_tx_reset(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c
new file mode 100644
index 000000000000..973b11060a8f
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c
@@ -0,0 +1,28 @@
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/wl12xx.h>
+
+static const struct wl12xx_platform_data *platform_data;
+
+int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
+{
+ if (platform_data)
+ return -EBUSY;
+ if (!data)
+ return -EINVAL;
+
+ platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+ if (!platform_data)
+ return -ENOMEM;
+
+ return 0;
+}
+
+const struct wl12xx_platform_data *wl12xx_get_platform_data(void)
+{
+ if (!platform_data)
+ return ERR_PTR(-ENODEV);
+
+ return platform_data;
+}
+EXPORT_SYMBOL(wl12xx_get_platform_data);
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index ca3f8961fa27..ee82df62e646 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -29,7 +29,6 @@
#include <linux/delay.h>
#include <linux/types.h>
-#include <linux/ethtool.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/in.h>
@@ -1403,15 +1402,6 @@ static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
return wstats;
}
-static void wl3501_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, "wl3501_cs", sizeof(info->driver));
-}
-
-static const struct ethtool_ops ops = {
- .get_drvinfo = wl3501_get_drvinfo
-};
-
/**
* wl3501_detach - deletes a driver "instance"
* @link - FILL_IN
@@ -1887,7 +1877,6 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
this->p_dev = p_dev;
dev->wireless_data = &this->wireless_data;
dev->wireless_handlers = &wl3501_handler_def;
- SET_ETHTOOL_OPS(dev, &ops);
netif_stop_queue(dev);
p_dev->priv = dev;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index b2af3c549bb3..87a95bcfee57 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -973,6 +973,7 @@ static void dump_fw_registers(struct zd_chip *chip)
static int print_fw_version(struct zd_chip *chip)
{
+ struct wiphy *wiphy = zd_chip_to_mac(chip)->hw->wiphy;
int r;
u16 version;
@@ -982,6 +983,10 @@ static int print_fw_version(struct zd_chip *chip)
return r;
dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version);
+
+ snprintf(wiphy->fw_version, sizeof(wiphy->fw_version),
+ "%04hx", version);
+
return 0;
}
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index b50fedcef8ac..630fb8664768 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -135,7 +135,7 @@ static void skb_entry_set_link(union skb_entry *list, unsigned short id)
static int skb_entry_is_link(const union skb_entry *list)
{
BUILD_BUG_ON(sizeof(list->skb) != sizeof(list->link));
- return ((unsigned long)list->skb < PAGE_OFFSET);
+ return (unsigned long)list->skb < PAGE_OFFSET;
}
/*
@@ -203,8 +203,8 @@ static void rx_refill_timeout(unsigned long data)
static int netfront_tx_slot_available(struct netfront_info *np)
{
- return ((np->tx.req_prod_pvt - np->tx.rsp_cons) <
- (TX_MAX_TARGET - MAX_SKB_FRAGS - 2));
+ return (np->tx.req_prod_pvt - np->tx.rsp_cons) <
+ (TX_MAX_TARGET - MAX_SKB_FRAGS - 2);
}
static void xennet_maybe_wake_tx(struct net_device *dev)
@@ -1395,7 +1395,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
}
/* Common code used when first setting up, and when resuming. */
-static int talk_to_backend(struct xenbus_device *dev,
+static int talk_to_netback(struct xenbus_device *dev,
struct netfront_info *info)
{
const char *message;
@@ -1545,7 +1545,7 @@ static int xennet_connect(struct net_device *dev)
return -ENODEV;
}
- err = talk_to_backend(np->xbdev, np);
+ err = talk_to_netback(np->xbdev, np);
if (err)
return err;
@@ -1599,7 +1599,7 @@ static int xennet_connect(struct net_device *dev)
/**
* Callback received when the backend's state changes.
*/
-static void backend_changed(struct xenbus_device *dev,
+static void netback_changed(struct xenbus_device *dev,
enum xenbus_state backend_state)
{
struct netfront_info *np = dev_get_drvdata(&dev->dev);
@@ -1801,7 +1801,7 @@ static struct xenbus_driver netfront_driver = {
.probe = netfront_probe,
.remove = __devexit_p(xennet_remove),
.resume = netfront_resume,
- .otherend_changed = backend_changed,
+ .otherend_changed = netback_changed,
};
static int __init netif_init(void)
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index ecbbb688eba0..f3f8be5a35fa 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -641,7 +641,7 @@ static void xemaclite_rx_handler(struct net_device *dev)
skb_put(skb, len); /* Tell the skb how much data we got */
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
dev->stats.rx_packets++;
dev->stats.rx_bytes += len;
@@ -1269,6 +1269,16 @@ static int __devexit xemaclite_of_remove(struct platform_device *of_dev)
return 0;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void
+xemaclite_poll_controller(struct net_device *ndev)
+{
+ disable_irq(ndev->irq);
+ xemaclite_interrupt(ndev->irq, ndev);
+ enable_irq(ndev->irq);
+}
+#endif
+
static struct net_device_ops xemaclite_netdev_ops = {
.ndo_open = xemaclite_open,
.ndo_stop = xemaclite_close,
@@ -1276,6 +1286,9 @@ static struct net_device_ops xemaclite_netdev_ops = {
.ndo_set_mac_address = xemaclite_set_mac_address,
.ndo_tx_timeout = xemaclite_tx_timeout,
.ndo_get_stats = xemaclite_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = xemaclite_poll_controller,
+#endif
};
/* Match table for OF platform binding */
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 4eb67aed68dd..cd1b3dcd61db 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -646,7 +646,7 @@ static int yellowfin_open(struct net_device *dev)
init_timer(&yp->timer);
yp->timer.expires = jiffies + 3*HZ;
yp->timer.data = (unsigned long)dev;
- yp->timer.function = &yellowfin_timer; /* timer handler */
+ yp->timer.function = yellowfin_timer; /* timer handler */
add_timer(&yp->timer);
return 0;
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index f0037eefd44e..0f4ef8769a3d 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -208,6 +208,7 @@ struct qdio_dev_perf_stat {
unsigned int eqbs_partial;
unsigned int sqbs;
unsigned int sqbs_partial;
+ unsigned int int_discarded;
} ____cacheline_aligned;
struct qdio_queue_perf_stat {
@@ -222,6 +223,10 @@ struct qdio_queue_perf_stat {
unsigned int nr_sbal_total;
};
+enum qdio_queue_irq_states {
+ QDIO_QUEUE_IRQS_DISABLED,
+};
+
struct qdio_input_q {
/* input buffer acknowledgement flag */
int polling;
@@ -231,6 +236,10 @@ struct qdio_input_q {
int ack_count;
/* last time of noticing incoming data */
u64 timestamp;
+ /* upper-layer polling flag */
+ unsigned long queue_irq_state;
+ /* callback to start upper-layer polling */
+ void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
};
struct qdio_output_q {
@@ -399,6 +408,26 @@ static inline int multicast_outbound(struct qdio_q *q)
#define sub_buf(bufnr, dec) \
((bufnr - dec) & QDIO_MAX_BUFFERS_MASK)
+#define queue_irqs_enabled(q) \
+ (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) == 0)
+#define queue_irqs_disabled(q) \
+ (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0)
+
+#define TIQDIO_SHARED_IND 63
+
+/* device state change indicators */
+struct indicator_t {
+ u32 ind; /* u32 because of compare-and-swap performance */
+ atomic_t count; /* use count, 0 or 1 for non-shared indicators */
+};
+
+extern struct indicator_t *q_indicators;
+
+static inline int shared_ind(struct qdio_irq *irq_ptr)
+{
+ return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
+}
+
/* prototypes for thin interrupt */
void qdio_setup_thinint(struct qdio_irq *irq_ptr);
int qdio_establish_thinint(struct qdio_irq *irq_ptr);
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index 6ce83f56d537..28868e7471a5 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -56,9 +56,16 @@ static int qstat_show(struct seq_file *m, void *v)
seq_printf(m, "DSCI: %d nr_used: %d\n",
*(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used));
- seq_printf(m, "ftc: %d last_move: %d\n", q->first_to_check, q->last_move);
- seq_printf(m, "polling: %d ack start: %d ack count: %d\n",
- q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count);
+ seq_printf(m, "ftc: %d last_move: %d\n",
+ q->first_to_check, q->last_move);
+ if (q->is_input_q) {
+ seq_printf(m, "polling: %d ack start: %d ack count: %d\n",
+ q->u.in.polling, q->u.in.ack_start,
+ q->u.in.ack_count);
+ seq_printf(m, "IRQs disabled: %u\n",
+ test_bit(QDIO_QUEUE_IRQS_DISABLED,
+ &q->u.in.queue_irq_state));
+ }
seq_printf(m, "SBAL states:\n");
seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
@@ -113,22 +120,6 @@ static int qstat_show(struct seq_file *m, void *v)
return 0;
}
-static ssize_t qstat_seq_write(struct file *file, const char __user *buf,
- size_t count, loff_t *off)
-{
- struct seq_file *seq = file->private_data;
- struct qdio_q *q = seq->private;
-
- if (!q)
- return 0;
- if (q->is_input_q)
- xchg(q->irq_ptr->dsci, 1);
- local_bh_disable();
- tasklet_schedule(&q->tasklet);
- local_bh_enable();
- return count;
-}
-
static int qstat_seq_open(struct inode *inode, struct file *filp)
{
return single_open(filp, qstat_show,
@@ -139,7 +130,6 @@ static const struct file_operations debugfs_fops = {
.owner = THIS_MODULE,
.open = qstat_seq_open,
.read = seq_read,
- .write = qstat_seq_write,
.llseek = seq_lseek,
.release = single_release,
};
@@ -166,7 +156,8 @@ static char *qperf_names[] = {
"QEBSM eqbs",
"QEBSM eqbs partial",
"QEBSM sqbs",
- "QEBSM sqbs partial"
+ "QEBSM sqbs partial",
+ "Discarded interrupts"
};
static int qperf_show(struct seq_file *m, void *v)
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 00520f9a7a8e..5fcfa7f9e9ef 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -884,8 +884,19 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
return;
- for_each_input_queue(irq_ptr, q, i)
- tasklet_schedule(&q->tasklet);
+ for_each_input_queue(irq_ptr, q, i) {
+ if (q->u.in.queue_start_poll) {
+ /* skip if polling is enabled or already in work */
+ if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
+ &q->u.in.queue_irq_state)) {
+ qperf_inc(q, int_discarded);
+ continue;
+ }
+ q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
+ q->irq_ptr->int_parm);
+ } else
+ tasklet_schedule(&q->tasklet);
+ }
if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED))
return;
@@ -1519,6 +1530,129 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
}
EXPORT_SYMBOL_GPL(do_QDIO);
+/**
+ * qdio_start_irq - process input buffers
+ * @cdev: associated ccw_device for the qdio subchannel
+ * @nr: input queue number
+ *
+ * Return codes
+ * 0 - success
+ * 1 - irqs not started since new data is available
+ */
+int qdio_start_irq(struct ccw_device *cdev, int nr)
+{
+ struct qdio_q *q;
+ struct qdio_irq *irq_ptr = cdev->private->qdio_data;
+
+ if (!irq_ptr)
+ return -ENODEV;
+ q = irq_ptr->input_qs[nr];
+
+ WARN_ON(queue_irqs_enabled(q));
+
+ if (!shared_ind(q->irq_ptr))
+ xchg(q->irq_ptr->dsci, 0);
+
+ qdio_stop_polling(q);
+ clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state);
+
+ /*
+ * We need to check again to not lose initiative after
+ * resetting the ACK state.
+ */
+ if (!shared_ind(q->irq_ptr) && *q->irq_ptr->dsci)
+ goto rescan;
+ if (!qdio_inbound_q_done(q))
+ goto rescan;
+ return 0;
+
+rescan:
+ if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
+ &q->u.in.queue_irq_state))
+ return 0;
+ else
+ return 1;
+
+}
+EXPORT_SYMBOL(qdio_start_irq);
+
+/**
+ * qdio_get_next_buffers - process input buffers
+ * @cdev: associated ccw_device for the qdio subchannel
+ * @nr: input queue number
+ * @bufnr: first filled buffer number
+ * @error: buffers are in error state
+ *
+ * Return codes
+ * < 0 - error
+ * = 0 - no new buffers found
+ * > 0 - number of processed buffers
+ */
+int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr,
+ int *error)
+{
+ struct qdio_q *q;
+ int start, end;
+ struct qdio_irq *irq_ptr = cdev->private->qdio_data;
+
+ if (!irq_ptr)
+ return -ENODEV;
+ q = irq_ptr->input_qs[nr];
+ WARN_ON(queue_irqs_enabled(q));
+
+ qdio_sync_after_thinint(q);
+
+ /*
+ * The interrupt could be caused by a PCI request. Check the
+ * PCI capable outbound queues.
+ */
+ qdio_check_outbound_after_thinint(q);
+
+ if (!qdio_inbound_q_moved(q))
+ return 0;
+
+ /* Note: upper-layer MUST stop processing immediately here ... */
+ if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
+ return -EIO;
+
+ start = q->first_to_kick;
+ end = q->first_to_check;
+ *bufnr = start;
+ *error = q->qdio_error;
+
+ /* for the next time */
+ q->first_to_kick = end;
+ q->qdio_error = 0;
+ return sub_buf(end, start);
+}
+EXPORT_SYMBOL(qdio_get_next_buffers);
+
+/**
+ * qdio_stop_irq - disable interrupt processing for the device
+ * @cdev: associated ccw_device for the qdio subchannel
+ * @nr: input queue number
+ *
+ * Return codes
+ * 0 - interrupts were already disabled
+ * 1 - interrupts successfully disabled
+ */
+int qdio_stop_irq(struct ccw_device *cdev, int nr)
+{
+ struct qdio_q *q;
+ struct qdio_irq *irq_ptr = cdev->private->qdio_data;
+
+ if (!irq_ptr)
+ return -ENODEV;
+ q = irq_ptr->input_qs[nr];
+
+ if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
+ &q->u.in.queue_irq_state))
+ return 0;
+ else
+ return 1;
+}
+EXPORT_SYMBOL(qdio_stop_irq);
+
static int __init init_QDIO(void)
{
int rc;
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 34c7e4046df4..a13cf7ec64b2 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -161,6 +161,7 @@ static void setup_queues(struct qdio_irq *irq_ptr,
setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i);
q->is_input_q = 1;
+ q->u.in.queue_start_poll = qdio_init->queue_start_poll;
setup_storage_lists(q, irq_ptr, input_sbal_array, i);
input_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 8daf1b99f153..752dbee06af5 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -25,24 +25,20 @@
*/
#define TIQDIO_NR_NONSHARED_IND 63
#define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1)
-#define TIQDIO_SHARED_IND 63
/* list of thin interrupt input queues */
static LIST_HEAD(tiq_list);
DEFINE_MUTEX(tiq_list_lock);
/* adapter local summary indicator */
-static unsigned char *tiqdio_alsi;
+static u8 *tiqdio_alsi;
-/* device state change indicators */
-struct indicator_t {
- u32 ind; /* u32 because of compare-and-swap performance */
- atomic_t count; /* use count, 0 or 1 for non-shared indicators */
-};
-static struct indicator_t *q_indicators;
+struct indicator_t *q_indicators;
static int css_qdio_omit_svs;
+static u64 last_ai_time;
+
static inline unsigned long do_clear_global_summary(void)
{
register unsigned long __fn asm("1") = 3;
@@ -116,59 +112,73 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
}
}
-static inline int shared_ind(struct qdio_irq *irq_ptr)
+static inline int shared_ind_used(void)
{
- return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
+ return atomic_read(&q_indicators[TIQDIO_SHARED_IND].count);
}
/**
* tiqdio_thinint_handler - thin interrupt handler for qdio
- * @ind: pointer to adapter local summary indicator
- * @drv_data: NULL
+ * @alsi: pointer to adapter local summary indicator
+ * @data: NULL
*/
-static void tiqdio_thinint_handler(void *ind, void *drv_data)
+static void tiqdio_thinint_handler(void *alsi, void *data)
{
struct qdio_q *q;
+ last_ai_time = S390_lowcore.int_clock;
+
/*
* SVS only when needed: issue SVS to benefit from iqdio interrupt
- * avoidance (SVS clears adapter interrupt suppression overwrite)
+ * avoidance (SVS clears adapter interrupt suppression overwrite).
*/
if (!css_qdio_omit_svs)
do_clear_global_summary();
- /*
- * reset local summary indicator (tiqdio_alsi) to stop adapter
- * interrupts for now
- */
- xchg((u8 *)ind, 0);
+ /* reset local summary indicator */
+ if (shared_ind_used())
+ xchg(tiqdio_alsi, 0);
/* protect tiq_list entries, only changed in activate or shutdown */
rcu_read_lock();
/* check for work on all inbound thinint queues */
- list_for_each_entry_rcu(q, &tiq_list, entry)
+ list_for_each_entry_rcu(q, &tiq_list, entry) {
+
/* only process queues from changed sets */
- if (*q->irq_ptr->dsci) {
- qperf_inc(q, adapter_int);
+ if (!*q->irq_ptr->dsci)
+ continue;
+ if (q->u.in.queue_start_poll) {
+ /* skip if polling is enabled or already in work */
+ if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
+ &q->u.in.queue_irq_state)) {
+ qperf_inc(q, int_discarded);
+ continue;
+ }
+
+ /* avoid dsci clear here, done after processing */
+ q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
+ q->irq_ptr->int_parm);
+ } else {
/* only clear it if the indicator is non-shared */
if (!shared_ind(q->irq_ptr))
xchg(q->irq_ptr->dsci, 0);
/*
- * don't call inbound processing directly since
- * that could starve other thinint queues
+ * Call inbound processing but not directly
+ * since that could starve other thinint queues.
*/
tasklet_schedule(&q->tasklet);
}
-
+ qperf_inc(q, adapter_int);
+ }
rcu_read_unlock();
/*
- * if we used the shared indicator clear it now after all queues
- * were processed
+ * If the shared indicator was used clear it now after all queues
+ * were processed.
*/
- if (atomic_read(&q_indicators[TIQDIO_SHARED_IND].count)) {
+ if (shared_ind_used()) {
xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0);
/* prevent racing */
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index 977bb4d4ed15..456b18743397 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -100,6 +100,6 @@ config QETH_IPV6
config CCWGROUP
tristate
- default (LCS || CTCM || QETH)
+ default (LCS || CTCM || QETH || CLAW)
endmenu
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index 2861e78773cb..b64881f33f23 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -540,7 +540,7 @@ void ctc_mpc_dealloc_ch(int port_num)
CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_DEBUG,
"%s: %s: refcount = %d\n",
- CTCM_FUNTAIL, dev->name, atomic_read(&dev->refcnt));
+ CTCM_FUNTAIL, dev->name, netdev_refcnt_read(dev));
fsm_deltimer(&priv->restart_timer);
grp->channels_terminating = 0;
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index d1257768be90..6be43eb126b4 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -676,6 +676,7 @@ enum qeth_discipline_id {
};
struct qeth_discipline {
+ void (*start_poll)(struct ccw_device *, int, unsigned long);
qdio_handler_t *input_handler;
qdio_handler_t *output_handler;
int (*recover)(void *ptr);
@@ -702,6 +703,16 @@ struct qeth_skb_data {
#define QETH_SKB_MAGIC 0x71657468
#define QETH_SIGA_CC2_RETRIES 3
+struct qeth_rx {
+ int b_count;
+ int b_index;
+ struct qdio_buffer_element *b_element;
+ int e_offset;
+ int qdio_err;
+};
+
+#define QETH_NAPI_WEIGHT 128
+
struct qeth_card {
struct list_head list;
enum qeth_card_states state;
@@ -749,6 +760,8 @@ struct qeth_card {
debug_info_t *debug;
struct mutex conf_mutex;
struct mutex discipline_mutex;
+ struct napi_struct napi;
+ struct qeth_rx rx;
};
struct qeth_card_list_struct {
@@ -831,6 +844,10 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
struct qdio_buffer *, struct qdio_buffer_element **, int *,
struct qeth_hdr **);
void qeth_schedule_recovery(struct qeth_card *);
+void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long);
+void qeth_qdio_input_handler(struct ccw_device *,
+ unsigned int, unsigned int, int,
+ int, unsigned long);
void qeth_qdio_output_handler(struct ccw_device *, unsigned int,
int, int, int, unsigned long);
void qeth_clear_ipacmd_list(struct qeth_card *);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 3a5a18a0fc28..764267062601 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2911,6 +2911,27 @@ static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
}
}
+void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
+ unsigned long card_ptr)
+{
+ struct qeth_card *card = (struct qeth_card *)card_ptr;
+
+ if (card->dev)
+ napi_schedule(&card->napi);
+}
+EXPORT_SYMBOL_GPL(qeth_qdio_start_poll);
+
+void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err,
+ unsigned int queue, int first_element, int count,
+ unsigned long card_ptr)
+{
+ struct qeth_card *card = (struct qeth_card *)card_ptr;
+
+ if (qdio_err)
+ qeth_schedule_recovery(card);
+}
+EXPORT_SYMBOL_GPL(qeth_qdio_input_handler);
+
void qeth_qdio_output_handler(struct ccw_device *ccwdev,
unsigned int qdio_error, int __queue, int first_element,
int count, unsigned long card_ptr)
@@ -3843,6 +3864,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
init_data.no_output_qs = card->qdio.no_out_queues;
init_data.input_handler = card->discipline.input_handler;
init_data.output_handler = card->discipline.output_handler;
+ init_data.queue_start_poll = card->discipline.start_poll;
init_data.int_parm = (unsigned long) card;
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
@@ -4513,8 +4535,8 @@ static struct {
/* 20 */{"queue 1 buffer usage"},
{"queue 2 buffer usage"},
{"queue 3 buffer usage"},
- {"rx handler time"},
- {"rx handler count"},
+ {"rx poll time"},
+ {"rx poll count"},
{"rx do_QDIO time"},
{"rx do_QDIO count"},
{"tx handler time"},
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 830d63524d61..847e8797073c 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -310,6 +310,8 @@ static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
struct qeth_vlan_vid *id;
QETH_CARD_TEXT_(card, 4, "aid:%d", vid);
+ if (!vid)
+ return;
if (card->info.type == QETH_CARD_TYPE_OSM) {
QETH_CARD_TEXT(card, 3, "aidOSM");
return;
@@ -407,29 +409,25 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
return rc;
}
-static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
- struct qeth_qdio_buffer *buf, int index)
+static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
+ int budget, int *done)
{
- struct qdio_buffer_element *element;
+ int work_done = 0;
struct sk_buff *skb;
struct qeth_hdr *hdr;
- int offset;
unsigned int len;
- /* get first element of current buffer */
- element = (struct qdio_buffer_element *)&buf->buffer->element[0];
- offset = 0;
- if (card->options.performance_stats)
- card->perf_stats.bufs_rec++;
- while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element,
- &offset, &hdr))) {
- skb->dev = card->dev;
- /* is device UP ? */
- if (!(card->dev->flags & IFF_UP)) {
- dev_kfree_skb_any(skb);
- continue;
+ *done = 0;
+ BUG_ON(!budget);
+ while (budget) {
+ skb = qeth_core_get_next_skb(card,
+ card->qdio.in_q->bufs[card->rx.b_index].buffer,
+ &card->rx.b_element, &card->rx.e_offset, &hdr);
+ if (!skb) {
+ *done = 1;
+ break;
}
-
+ skb->dev = card->dev;
switch (hdr->hdr.l2.id) {
case QETH_HEADER_TYPE_LAYER2:
skb->pkt_type = PACKET_HOST;
@@ -441,7 +439,7 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
if (skb->protocol == htons(ETH_P_802_2))
*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
len = skb->len;
- netif_rx(skb);
+ netif_receive_skb(skb);
break;
case QETH_HEADER_TYPE_OSN:
if (card->info.type == QETH_CARD_TYPE_OSN) {
@@ -459,9 +457,87 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
continue;
}
+ work_done++;
+ budget--;
card->stats.rx_packets++;
card->stats.rx_bytes += len;
}
+ return work_done;
+}
+
+static int qeth_l2_poll(struct napi_struct *napi, int budget)
+{
+ struct qeth_card *card = container_of(napi, struct qeth_card, napi);
+ int work_done = 0;
+ struct qeth_qdio_buffer *buffer;
+ int done;
+ int new_budget = budget;
+
+ if (card->options.performance_stats) {
+ card->perf_stats.inbound_cnt++;
+ card->perf_stats.inbound_start_time = qeth_get_micros();
+ }
+
+ while (1) {
+ if (!card->rx.b_count) {
+ card->rx.qdio_err = 0;
+ card->rx.b_count = qdio_get_next_buffers(
+ card->data.ccwdev, 0, &card->rx.b_index,
+ &card->rx.qdio_err);
+ if (card->rx.b_count <= 0) {
+ card->rx.b_count = 0;
+ break;
+ }
+ card->rx.b_element =
+ &card->qdio.in_q->bufs[card->rx.b_index]
+ .buffer->element[0];
+ card->rx.e_offset = 0;
+ }
+
+ while (card->rx.b_count) {
+ buffer = &card->qdio.in_q->bufs[card->rx.b_index];
+ if (!(card->rx.qdio_err &&
+ qeth_check_qdio_errors(card, buffer->buffer,
+ card->rx.qdio_err, "qinerr")))
+ work_done += qeth_l2_process_inbound_buffer(
+ card, new_budget, &done);
+ else
+ done = 1;
+
+ if (done) {
+ if (card->options.performance_stats)
+ card->perf_stats.bufs_rec++;
+ qeth_put_buffer_pool_entry(card,
+ buffer->pool_entry);
+ qeth_queue_input_buffer(card, card->rx.b_index);
+ card->rx.b_count--;
+ if (card->rx.b_count) {
+ card->rx.b_index =
+ (card->rx.b_index + 1) %
+ QDIO_MAX_BUFFERS_PER_Q;
+ card->rx.b_element =
+ &card->qdio.in_q
+ ->bufs[card->rx.b_index]
+ .buffer->element[0];
+ card->rx.e_offset = 0;
+ }
+ }
+
+ if (work_done >= budget)
+ goto out;
+ else
+ new_budget = budget - work_done;
+ }
+ }
+
+ napi_complete(napi);
+ if (qdio_start_irq(card->data.ccwdev, 0))
+ napi_schedule(&card->napi);
+out:
+ if (card->options.performance_stats)
+ card->perf_stats.inbound_time += qeth_get_micros() -
+ card->perf_stats.inbound_start_time;
+ return work_done;
}
static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
@@ -755,49 +831,10 @@ tx_drop:
return NETDEV_TX_OK;
}
-static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev,
- unsigned int qdio_err, unsigned int queue,
- int first_element, int count, unsigned long card_ptr)
-{
- struct net_device *net_dev;
- struct qeth_card *card;
- struct qeth_qdio_buffer *buffer;
- int index;
- int i;
-
- card = (struct qeth_card *) card_ptr;
- net_dev = card->dev;
- if (card->options.performance_stats) {
- card->perf_stats.inbound_cnt++;
- card->perf_stats.inbound_start_time = qeth_get_micros();
- }
- if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
- QETH_CARD_TEXT(card, 1, "qdinchk");
- QETH_CARD_TEXT_(card, 1, "%04X%04X", first_element,
- count);
- QETH_CARD_TEXT_(card, 1, "%04X", queue);
- qeth_schedule_recovery(card);
- return;
- }
- for (i = first_element; i < (first_element + count); ++i) {
- index = i % QDIO_MAX_BUFFERS_PER_Q;
- buffer = &card->qdio.in_q->bufs[index];
- if (!(qdio_err &&
- qeth_check_qdio_errors(card, buffer->buffer, qdio_err,
- "qinerr")))
- qeth_l2_process_inbound_buffer(card, buffer, index);
- /* clear buffer and give back to hardware */
- qeth_put_buffer_pool_entry(card, buffer->pool_entry);
- qeth_queue_input_buffer(card, index);
- }
- if (card->options.performance_stats)
- card->perf_stats.inbound_time += qeth_get_micros() -
- card->perf_stats.inbound_start_time;
-}
-
static int qeth_l2_open(struct net_device *dev)
{
struct qeth_card *card = dev->ml_priv;
+ int rc = 0;
QETH_CARD_TEXT(card, 4, "qethopen");
if (card->state != CARD_STATE_SOFTSETUP)
@@ -814,18 +851,24 @@ static int qeth_l2_open(struct net_device *dev)
if (!card->lan_online && netif_carrier_ok(dev))
netif_carrier_off(dev);
- return 0;
+ if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
+ napi_enable(&card->napi);
+ napi_schedule(&card->napi);
+ } else
+ rc = -EIO;
+ return rc;
}
-
static int qeth_l2_stop(struct net_device *dev)
{
struct qeth_card *card = dev->ml_priv;
QETH_CARD_TEXT(card, 4, "qethstop");
netif_tx_disable(dev);
- if (card->state == CARD_STATE_UP)
+ if (card->state == CARD_STATE_UP) {
card->state = CARD_STATE_SOFTSETUP;
+ napi_disable(&card->napi);
+ }
return 0;
}
@@ -836,8 +879,9 @@ 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->discipline.start_poll = qeth_qdio_start_poll;
card->discipline.input_handler = (qdio_handler_t *)
- qeth_l2_qdio_input_handler;
+ qeth_qdio_input_handler;
card->discipline.output_handler = (qdio_handler_t *)
qeth_qdio_output_handler;
card->discipline.recover = qeth_l2_recover;
@@ -923,6 +967,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
card->info.broadcast_capable = 1;
qeth_l2_request_initial_mac(card);
SET_NETDEV_DEV(card->dev, &card->gdev->dev);
+ netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT);
return register_netdev(card->dev);
}
@@ -955,6 +1000,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
card->state = CARD_STATE_HARDSETUP;
+ memset(&card->rx, 0, sizeof(struct qeth_rx));
qeth_print_status_message(card);
/* softsetup */
@@ -1086,9 +1132,6 @@ static int qeth_l2_recover(void *ptr)
card->use_hard_stop = 1;
__qeth_l2_set_offline(card->gdev, 1);
rc = __qeth_l2_set_online(card->gdev, 1);
- /* don't run another scheduled recovery */
- qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
- qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
if (!rc)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
@@ -1099,6 +1142,8 @@ static int qeth_l2_recover(void *ptr)
dev_warn(&card->gdev->dev, "The qeth device driver "
"failed to recover an error on the device\n");
}
+ qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
+ qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
return 0;
}
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index e22ae248f613..74d1401a5d5e 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -103,12 +103,7 @@ int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr)
void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf)
{
- sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x"
- ":%02x%02x:%02x%02x:%02x%02x:%02x%02x",
- addr[0], addr[1], addr[2], addr[3],
- addr[4], addr[5], addr[6], addr[7],
- addr[8], addr[9], addr[10], addr[11],
- addr[12], addr[13], addr[14], addr[15]);
+ sprintf(buf, "%pI6", addr);
}
int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr)
@@ -1825,7 +1820,7 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card)
return;
vg = card->vlangrp;
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
struct net_device *netdev = vlan_group_get_device(vg, i);
if (netdev == NULL ||
!(netdev->flags & IFF_UP))
@@ -1888,7 +1883,7 @@ static void qeth_l3_add_vlan_mc6(struct qeth_card *card)
return;
vg = card->vlangrp;
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
struct net_device *netdev = vlan_group_get_device(vg, i);
if (netdev == NULL ||
!(netdev->flags & IFF_UP))
@@ -2018,13 +2013,14 @@ static void qeth_l3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
qeth_l3_set_multicast_list(card->dev);
}
-static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
- struct sk_buff *skb, struct qeth_hdr *hdr)
+static inline int qeth_l3_rebuild_skb(struct qeth_card *card,
+ struct sk_buff *skb, struct qeth_hdr *hdr,
+ unsigned short *vlan_id)
{
- unsigned short vlan_id = 0;
__be16 prot;
struct iphdr *ip_hdr;
unsigned char tg_addr[MAX_ADDR_LEN];
+ int is_vlan = 0;
if (!(hdr->hdr.l3.flags & QETH_HDR_PASSTHRU)) {
prot = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 :
@@ -2087,8 +2083,9 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
if (hdr->hdr.l3.ext_flags &
(QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) {
- vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)?
+ *vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME) ?
hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
+ is_vlan = 1;
}
switch (card->options.checksum_type) {
@@ -2109,54 +2106,44 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
skb->ip_summed = CHECKSUM_NONE;
}
- return vlan_id;
+ return is_vlan;
}
-static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
- struct qeth_qdio_buffer *buf, int index)
+static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
+ int budget, int *done)
{
- struct qdio_buffer_element *element;
+ int work_done = 0;
struct sk_buff *skb;
struct qeth_hdr *hdr;
- int offset;
__u16 vlan_tag = 0;
+ int is_vlan;
unsigned int len;
- /* get first element of current buffer */
- element = (struct qdio_buffer_element *)&buf->buffer->element[0];
- offset = 0;
- if (card->options.performance_stats)
- card->perf_stats.bufs_rec++;
- while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element,
- &offset, &hdr))) {
- skb->dev = card->dev;
- /* is device UP ? */
- if (!(card->dev->flags & IFF_UP)) {
- dev_kfree_skb_any(skb);
- continue;
- }
+ *done = 0;
+ BUG_ON(!budget);
+ while (budget) {
+ skb = qeth_core_get_next_skb(card,
+ card->qdio.in_q->bufs[card->rx.b_index].buffer,
+ &card->rx.b_element, &card->rx.e_offset, &hdr);
+ if (!skb) {
+ *done = 1;
+ break;
+ }
+ skb->dev = card->dev;
switch (hdr->hdr.l3.id) {
case QETH_HEADER_TYPE_LAYER3:
- vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr);
+ is_vlan = qeth_l3_rebuild_skb(card, skb, hdr,
+ &vlan_tag);
len = skb->len;
- if (vlan_tag && !card->options.sniffer)
- if (card->vlangrp)
- vlan_hwaccel_rx(skb, card->vlangrp,
- vlan_tag);
- else {
- dev_kfree_skb_any(skb);
- continue;
- }
+ if (is_vlan && !card->options.sniffer)
+ vlan_gro_receive(&card->napi, card->vlangrp,
+ vlan_tag, skb);
else
- netif_rx(skb);
+ napi_gro_receive(&card->napi, skb);
break;
case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
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;
len = skb->len;
netif_receive_skb(skb);
break;
@@ -2166,10 +2153,87 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
continue;
}
-
+ work_done++;
+ budget--;
card->stats.rx_packets++;
card->stats.rx_bytes += len;
}
+ return work_done;
+}
+
+static int qeth_l3_poll(struct napi_struct *napi, int budget)
+{
+ struct qeth_card *card = container_of(napi, struct qeth_card, napi);
+ int work_done = 0;
+ struct qeth_qdio_buffer *buffer;
+ int done;
+ int new_budget = budget;
+
+ if (card->options.performance_stats) {
+ card->perf_stats.inbound_cnt++;
+ card->perf_stats.inbound_start_time = qeth_get_micros();
+ }
+
+ while (1) {
+ if (!card->rx.b_count) {
+ card->rx.qdio_err = 0;
+ card->rx.b_count = qdio_get_next_buffers(
+ card->data.ccwdev, 0, &card->rx.b_index,
+ &card->rx.qdio_err);
+ if (card->rx.b_count <= 0) {
+ card->rx.b_count = 0;
+ break;
+ }
+ card->rx.b_element =
+ &card->qdio.in_q->bufs[card->rx.b_index]
+ .buffer->element[0];
+ card->rx.e_offset = 0;
+ }
+
+ while (card->rx.b_count) {
+ buffer = &card->qdio.in_q->bufs[card->rx.b_index];
+ if (!(card->rx.qdio_err &&
+ qeth_check_qdio_errors(card, buffer->buffer,
+ card->rx.qdio_err, "qinerr")))
+ work_done += qeth_l3_process_inbound_buffer(
+ card, new_budget, &done);
+ else
+ done = 1;
+
+ if (done) {
+ if (card->options.performance_stats)
+ card->perf_stats.bufs_rec++;
+ qeth_put_buffer_pool_entry(card,
+ buffer->pool_entry);
+ qeth_queue_input_buffer(card, card->rx.b_index);
+ card->rx.b_count--;
+ if (card->rx.b_count) {
+ card->rx.b_index =
+ (card->rx.b_index + 1) %
+ QDIO_MAX_BUFFERS_PER_Q;
+ card->rx.b_element =
+ &card->qdio.in_q
+ ->bufs[card->rx.b_index]
+ .buffer->element[0];
+ card->rx.e_offset = 0;
+ }
+ }
+
+ if (work_done >= budget)
+ goto out;
+ else
+ new_budget = budget - work_done;
+ }
+ }
+
+ napi_complete(napi);
+ if (qdio_start_irq(card->data.ccwdev, 0))
+ napi_schedule(&card->napi);
+out:
+ if (card->options.performance_stats)
+ card->perf_stats.inbound_time += qeth_get_micros() -
+ card->perf_stats.inbound_start_time;
+ return work_done;
}
static int qeth_l3_verify_vlan_dev(struct net_device *dev,
@@ -2183,7 +2247,7 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev,
if (!vg)
return rc;
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
if (vlan_group_get_device(vg, i) == dev) {
rc = QETH_VLAN_CARD;
break;
@@ -3103,6 +3167,7 @@ tx_drop:
static int qeth_l3_open(struct net_device *dev)
{
struct qeth_card *card = dev->ml_priv;
+ int rc = 0;
QETH_CARD_TEXT(card, 4, "qethopen");
if (card->state != CARD_STATE_SOFTSETUP)
@@ -3113,7 +3178,12 @@ static int qeth_l3_open(struct net_device *dev)
if (!card->lan_online && netif_carrier_ok(dev))
netif_carrier_off(dev);
- return 0;
+ if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
+ napi_enable(&card->napi);
+ napi_schedule(&card->napi);
+ } else
+ rc = -EIO;
+ return rc;
}
static int qeth_l3_stop(struct net_device *dev)
@@ -3122,8 +3192,10 @@ static int qeth_l3_stop(struct net_device *dev)
QETH_CARD_TEXT(card, 4, "qethstop");
netif_tx_disable(dev);
- if (card->state == CARD_STATE_UP)
+ if (card->state == CARD_STATE_UP) {
card->state = CARD_STATE_SOFTSETUP;
+ napi_disable(&card->napi);
+ }
return 0;
}
@@ -3293,57 +3365,19 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
card->dev->gso_max_size = 15 * PAGE_SIZE;
SET_NETDEV_DEV(card->dev, &card->gdev->dev);
+ netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT);
return register_netdev(card->dev);
}
-static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev,
- unsigned int qdio_err, unsigned int queue, int first_element,
- int count, unsigned long card_ptr)
-{
- struct net_device *net_dev;
- struct qeth_card *card;
- struct qeth_qdio_buffer *buffer;
- int index;
- int i;
-
- card = (struct qeth_card *) card_ptr;
- net_dev = card->dev;
- if (card->options.performance_stats) {
- card->perf_stats.inbound_cnt++;
- card->perf_stats.inbound_start_time = qeth_get_micros();
- }
- if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
- QETH_CARD_TEXT(card, 1, "qdinchk");
- QETH_CARD_TEXT_(card, 1, "%04X%04X",
- first_element, count);
- QETH_CARD_TEXT_(card, 1, "%04X", queue);
- qeth_schedule_recovery(card);
- return;
- }
- for (i = first_element; i < (first_element + count); ++i) {
- index = i % QDIO_MAX_BUFFERS_PER_Q;
- buffer = &card->qdio.in_q->bufs[index];
- if (!(qdio_err &&
- qeth_check_qdio_errors(card, buffer->buffer,
- qdio_err, "qinerr")))
- qeth_l3_process_inbound_buffer(card, buffer, index);
- /* clear buffer and give back to hardware */
- qeth_put_buffer_pool_entry(card, buffer->pool_entry);
- qeth_queue_input_buffer(card, index);
- }
- if (card->options.performance_stats)
- card->perf_stats.inbound_time += qeth_get_micros() -
- card->perf_stats.inbound_start_time;
-}
-
static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
qeth_l3_create_device_attributes(&gdev->dev);
card->options.layer2 = 0;
+ card->discipline.start_poll = qeth_qdio_start_poll;
card->discipline.input_handler = (qdio_handler_t *)
- qeth_l3_qdio_input_handler;
+ qeth_qdio_input_handler;
card->discipline.output_handler = (qdio_handler_t *)
qeth_qdio_output_handler;
card->discipline.recover = qeth_l3_recover;
@@ -3402,6 +3436,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
}
card->state = CARD_STATE_HARDSETUP;
+ memset(&card->rx, 0, sizeof(struct qeth_rx));
qeth_print_status_message(card);
/* softsetup */
@@ -3538,9 +3573,6 @@ static int qeth_l3_recover(void *ptr)
card->use_hard_stop = 1;
__qeth_l3_set_offline(card->gdev, 1);
rc = __qeth_l3_set_online(card->gdev, 1);
- /* don't run another scheduled recovery */
- qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
- qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
if (!rc)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
@@ -3551,6 +3583,8 @@ static int qeth_l3_recover(void *ptr)
dev_warn(&card->gdev->dev, "The qeth device driver "
"failed to recover an error on the device\n");
}
+ qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
+ qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
return 0;
}
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 60e6e5714eb9..a0554beb4179 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -279,16 +279,12 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
struct zfcp_qdio *qdio)
{
-
+ memset(id, 0, sizeof(*id));
id->cdev = qdio->adapter->ccw_device;
id->q_format = QDIO_ZFCP_QFMT;
memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8);
ASCEBC(id->adapter_name, 8);
id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV;
- id->qib_param_field_format = 0;
- id->qib_param_field = NULL;
- id->input_slib_elements = NULL;
- id->output_slib_elements = NULL;
id->no_input_qs = 1;
id->no_output_qs = 1;
id->input_handler = zfcp_qdio_int_resp;
diff --git a/drivers/scsi/bnx2i/57xx_iscsi_constants.h b/drivers/scsi/bnx2i/57xx_iscsi_constants.h
index 2fceb19eb27b..1b6f86b2482d 100644
--- a/drivers/scsi/bnx2i/57xx_iscsi_constants.h
+++ b/drivers/scsi/bnx2i/57xx_iscsi_constants.h
@@ -120,6 +120,8 @@
/* additional LOM specific iSCSI license not installed */
#define ISCSI_KCQE_COMPLETION_STATUS_LOM_ISCSI_NOT_ENABLED (0x51)
+#define ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY (0x80)
+
/* SQ/RQ/CQ DB structure sizes */
#define ISCSI_SQ_DB_SIZE (16)
#define ISCSI_RQ_DB_SIZE (16)
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index b6345d91bb66..a44b1b33fa18 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -58,6 +58,8 @@
#define MAX_PAGES_PER_CTRL_STRUCT_POOL 8
#define BNX2I_RESERVED_SLOW_PATH_CMD_SLOTS 4
+#define BNX2I_5771X_DBELL_PAGE_SIZE 128
+
/* 5706/08 hardware has limit on maximum buffer size per BD it can handle */
#define MAX_BD_LENGTH 65535
#define BD_SPLIT_SIZE 32768
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 90cef716b796..8d9dbb33972f 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -2406,7 +2406,8 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep)
if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) {
reg_base = pci_resource_start(ep->hba->pcidev,
BNX2X_DOORBELL_PCI_BAR);
- reg_off = PAGE_SIZE * (cid_num & 0x1FFFF) + DPM_TRIGER_TYPE;
+ reg_off = BNX2I_5771X_DBELL_PAGE_SIZE * (cid_num & 0x1FFFF) +
+ DPM_TRIGER_TYPE;
ep->qp.ctx_base = ioremap_nocache(reg_base + reg_off, 4);
goto arm_cq;
}
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 5af23cc5ea9f..f383cb42b1d7 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -1344,8 +1344,24 @@ static struct usbatm_driver cxacru_driver = {
.tx_padding = 11,
};
-static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int cxacru_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
+ char buf[15];
+
+ /* Avoid ADSL routers (cx82310_eth).
+ * Abort if bDeviceClass is 0xff and iProduct is "USB NET CARD".
+ */
+ if (usb_dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC
+ && usb_string(usb_dev, usb_dev->descriptor.iProduct,
+ buf, sizeof(buf)) > 0) {
+ if (!strcmp(buf, "USB NET CARD")) {
+ dev_info(&intf->dev, "ignoring cx82310_eth device\n");
+ return -ENODEV;
+ }
+ }
+
return usbatm_usb_probe(intf, id, &cxacru_driver);
}
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 861af4a8b79c..4b4da5b86ff9 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -246,7 +246,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
int r, nlogs = 0;
while (datalen > 0) {
- if (unlikely(seg >= VHOST_NET_MAX_SG)) {
+ if (unlikely(seg >= UIO_MAXIOV)) {
r = -ENOBUFS;
goto err;
}
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 8b5a1b33d0fe..94701ff3a23a 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -212,6 +212,45 @@ static int vhost_worker(void *data)
}
}
+/* Helper to allocate iovec buffers for all vqs. */
+static long vhost_dev_alloc_iovecs(struct vhost_dev *dev)
+{
+ int i;
+ for (i = 0; i < dev->nvqs; ++i) {
+ dev->vqs[i].indirect = kmalloc(sizeof *dev->vqs[i].indirect *
+ UIO_MAXIOV, GFP_KERNEL);
+ dev->vqs[i].log = kmalloc(sizeof *dev->vqs[i].log * UIO_MAXIOV,
+ GFP_KERNEL);
+ dev->vqs[i].heads = kmalloc(sizeof *dev->vqs[i].heads *
+ UIO_MAXIOV, GFP_KERNEL);
+
+ if (!dev->vqs[i].indirect || !dev->vqs[i].log ||
+ !dev->vqs[i].heads)
+ goto err_nomem;
+ }
+ return 0;
+err_nomem:
+ for (; i >= 0; --i) {
+ kfree(dev->vqs[i].indirect);
+ kfree(dev->vqs[i].log);
+ kfree(dev->vqs[i].heads);
+ }
+ return -ENOMEM;
+}
+
+static void vhost_dev_free_iovecs(struct vhost_dev *dev)
+{
+ int i;
+ for (i = 0; i < dev->nvqs; ++i) {
+ kfree(dev->vqs[i].indirect);
+ dev->vqs[i].indirect = NULL;
+ kfree(dev->vqs[i].log);
+ dev->vqs[i].log = NULL;
+ kfree(dev->vqs[i].heads);
+ dev->vqs[i].heads = NULL;
+ }
+}
+
long vhost_dev_init(struct vhost_dev *dev,
struct vhost_virtqueue *vqs, int nvqs)
{
@@ -229,6 +268,9 @@ long vhost_dev_init(struct vhost_dev *dev,
dev->worker = NULL;
for (i = 0; i < dev->nvqs; ++i) {
+ dev->vqs[i].log = NULL;
+ dev->vqs[i].indirect = NULL;
+ dev->vqs[i].heads = NULL;
dev->vqs[i].dev = dev;
mutex_init(&dev->vqs[i].mutex);
vhost_vq_reset(dev, dev->vqs + i);
@@ -295,6 +337,10 @@ static long vhost_dev_set_owner(struct vhost_dev *dev)
if (err)
goto err_cgroup;
+ err = vhost_dev_alloc_iovecs(dev);
+ if (err)
+ goto err_cgroup;
+
return 0;
err_cgroup:
kthread_stop(worker);
@@ -345,6 +391,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
fput(dev->vqs[i].call);
vhost_vq_reset(dev, dev->vqs + i);
}
+ vhost_dev_free_iovecs(dev);
if (dev->log_ctx)
eventfd_ctx_put(dev->log_ctx);
dev->log_ctx = NULL;
@@ -372,7 +419,7 @@ static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz)
/* Make sure 64 bit math will not overflow. */
if (a > ULONG_MAX - (unsigned long)log_base ||
a + (unsigned long)log_base > ULONG_MAX)
- return -EFAULT;
+ return 0;
return access_ok(VERIFY_WRITE, log_base + a,
(sz + VHOST_PAGE_SIZE * 8 - 1) / VHOST_PAGE_SIZE / 8);
@@ -957,7 +1004,7 @@ static int get_indirect(struct vhost_dev *dev, struct vhost_virtqueue *vq,
}
ret = translate_desc(dev, indirect->addr, indirect->len, vq->indirect,
- ARRAY_SIZE(vq->indirect));
+ UIO_MAXIOV);
if (unlikely(ret < 0)) {
vq_err(vq, "Translation failure %d in indirect.\n", ret);
return ret;
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index af3c11ded5fd..073d06ae091f 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -15,11 +15,6 @@
struct vhost_device;
-enum {
- /* Enough place for all fragments, head, and virtio net header. */
- VHOST_NET_MAX_SG = MAX_SKB_FRAGS + 2,
-};
-
struct vhost_work;
typedef void (*vhost_work_fn_t)(struct vhost_work *work);
@@ -93,12 +88,15 @@ struct vhost_virtqueue {
bool log_used;
u64 log_addr;
- struct iovec indirect[VHOST_NET_MAX_SG];
- struct iovec iov[VHOST_NET_MAX_SG];
- struct iovec hdr[VHOST_NET_MAX_SG];
+ struct iovec iov[UIO_MAXIOV];
+ /* hdr is used to store the virtio header.
+ * Since each iovec has >= 1 byte length, we never need more than
+ * header length entries to store the header. */
+ struct iovec hdr[sizeof(struct virtio_net_hdr_mrg_rxbuf)];
+ struct iovec *indirect;
size_t vhost_hlen;
size_t sock_hlen;
- struct vring_used_elem heads[VHOST_NET_MAX_SG];
+ struct vring_used_elem *heads;
/* We use a kind of RCU to access private pointer.
* All readers access it from worker, which makes it possible to
* flush the vhost_work instead of synchronize_rcu. Therefore readers do
@@ -109,7 +107,7 @@ struct vhost_virtqueue {
void __rcu *private_data;
/* Log write descriptors */
void __user *log_base;
- struct vhost_log log[VHOST_NET_MAX_SG];
+ struct vhost_log *log;
};
struct vhost_dev {
diff --git a/firmware/Makefile b/firmware/Makefile
index 9c2d19452d0b..74d47cd0886c 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -32,12 +32,14 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
adaptec/starfire_tx.bin
fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
-fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-5.2.13.0.fw bnx2x-e1h-5.2.13.0.fw
-fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j15.fw \
- bnx2/bnx2-rv2p-09-5.0.0.j10.fw \
- bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw \
- bnx2/bnx2-mips-06-5.0.0.j6.fw \
- bnx2/bnx2-rv2p-06-5.0.0.j3.fw
+fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.0.34.0.fw \
+ bnx2x/bnx2x-e1h-6.0.34.0.fw \
+ bnx2x/bnx2x-e2-6.0.34.0.fw
+fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.0.17.fw \
+ bnx2/bnx2-rv2p-09-6.0.17.fw \
+ bnx2/bnx2-rv2p-09ax-6.0.17.fw \
+ bnx2/bnx2-mips-06-6.0.15.fw \
+ bnx2/bnx2-rv2p-06-6.0.15.fw
fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin
fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin
fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \
diff --git a/firmware/WHENCE b/firmware/WHENCE
index ae5f8a47f292..f22c4dfd0733 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -679,8 +679,8 @@ Found in hex form in kernel source.
Driver: bnx2x: Broadcom Everest
-File: bnx2x-e1-5.2.13.0.fw
-File: bnx2x-e1h-5.2.13.0.fw
+File: bnx2x/bnx2x-e1-5.2.13.0.fw
+File: bnx2x/bnx2x-e1h-5.2.13.0.fw
License:
Copyright (c) 2007-2010 Broadcom Corporation
@@ -699,15 +699,16 @@ Found in hex form in kernel source.
Driver: BNX2 - Broadcom NetXtremeII
-File: bnx2/bnx2-mips-06-4.6.16.fw
-File: bnx2/bnx2-rv2p-06-4.6.16.fw
-File: bnx2/bnx2-mips-09-4.6.17.fw
-File: bnx2/bnx2-rv2p-09-4.6.15.fw
+File: bnx2/bnx2-mips-06-6.0.15.fw
+File: bnx2/bnx2-rv2p-06-6.0.15.fw
+File: bnx2/bnx2-mips-09-6.0.17.fw
+File: bnx2/bnx2-rv2p-09-6.0.17.fw
+File: bnx2/bnx2-rv2p-09ax-6.0.17.fw
Licence:
This file contains firmware data derived from proprietary unpublished
- source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ source code, Copyright (c) 2004 - 2010 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/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex b/firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex
deleted file mode 100644
index 8d379bffbfef..000000000000
--- a/firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex
+++ /dev/null
@@ -1,5908 +0,0 @@
-:10000000080001100800000000004CC8000000C8F3
-:1000100000000000000000000000000008004CC8C4
-:100020000000001400004D90080000880800000047
-:10003000000058C400004DA408005A40000000848D
-:100040000000A668080058C4000001540000A6EC97
-:10005000080031D808000000000075340000A840F6
-:1000600000000000000000000000000008007534DF
-:100070000000002400011D7408000488080004002A
-:100080000000175C00011D98000000000000000047
-:100090000000000000000000000000000000000060
-:1000A000080000A80800000000003B38000134F4FC
-:1000B0000000000000000000000000000000000040
-:0800C000000000000000000038
-:0800C8000A00004400000000E2
-:1000D000000000000000000D636F6D352E302E30E3
-:1000E0006A36000005000002000000000000000366
-:1000F00000000014000000320000000300000000B7
-:1001000000000000000000000000000000000000EF
-:1001100000000010000001360000EA600000000549
-:1001200000000000000000000000000000000008C7
-:1001300000000000000000000000000000000000BF
-:1001400000000000000000000000000000000000AF
-:10015000000000000000000000000000000000009F
-:10016000000000020000000000000000000000008D
-:10017000000000000000000000000000000000007F
-:10018000000000000000000000000010000000005F
-:10019000000000000000000000000000000000005F
-:1001A000000000000000000000000000000000004F
-:1001B000000000000000000000000000000000003F
-:1001C000000000000000000000000000000000002F
-:1001D000000000000000000000000000100000030C
-:1001E000000000000000000D0000000D3C020800AF
-:1001F00024424D003C03080024634DFCAC40000049
-:100200000043202B1480FFFD244200043C1D080005
-:1002100037BD7FFC03A0F0213C1008002610011020
-:100220003C1C0800279C4D000E000214000000003A
-:100230000000000D27BDFFE8AFBF0014AFB00010F5
-:100240009742010830437000240220001062000B26
-:10025000286220011440002F0000102124024000D9
-:1002600010620025000000002402600010620026D9
-:10027000000010210A0000948FBF001427500100D5
-:10028000920200091040001A240300013C020800F9
-:100290008C42002010400016000018210E00052B93
-:1002A00000000000960300083C06080094C64DBEFE
-:1002B0008E0400188F8200209605000C00031C009D
-:1002C00000661825AC440000AC450004240400017D
-:1002D000AC400008AC40000CAC400010AC40001436
-:1002E000AC4000180E000550AC43001C0000182163
-:1002F0000A000093006010210E0003BD0000000002
-:100300000A000093000010210E000F810000000081
-:10031000000010218FBF00148FB0001003E0000810
-:1003200027BD001827BDFFE0AFB00010AFBF001819
-:10033000AFB10014275001009203000B2402001AF1
-:10034000961100081462005B00002821322200018F
-:1003500010400008000000008E0200009603001408
-:10036000000211C200021040005A10210A0000DBF6
-:10037000A44300803C0208008C420020104000286A
-:10038000000000000E00052B00000000974201084D
-:100390009743010C8F8500203042003E3063FFFF01
-:1003A0000002140000431025ACA200008F4201009F
-:1003B0003C06080094C64DBEACA20004974301164B
-:1003C0009744010E3C02200000031C003084FFFF14
-:1003D00000641825ACA3000800C230259742011024
-:1003E0009743011224040001000214003063FFFF50
-:1003F00000431025ACA2000C974201143042FFFFCD
-:10040000ACA200108F420118ACA200149342010B61
-:10041000304200FFACA200180E000550ACA6001C34
-:100420003C0208008C420040244200013C010800CC
-:10043000AC2200403C0308008C63004432220002DE
-:1004400032240004246300013C010800AC23004472
-:10045000108000180002282B8F4202B804430008C5
-:100460008E0200203C0208008C4200602442000101
-:100470003C010800AC2200600A0000FB24050001DA
-:100480009603001600002821AF4202808E0200046D
-:10049000A7430284AF4202883C021000AF4202B878
-:1004A0003C0208008C42005C244200013C01080030
-:1004B000AC22005C8FBF00188FB100148FB0001009
-:1004C00000A0102103E0000827BD002027BDFFE0A9
-:1004D000AFB00010AFBF0018AFB10014275001003B
-:1004E0009203000B24020003961100081462006DB1
-:1004F000000020213222000110400008000000000E
-:100500008E02000096030014000211C20002104087
-:10051000005A10210A000142A44300803C02080056
-:100520008C42002010400025000000000E00052B2A
-:1005300000000000974201089743010C8F850020BE
-:100540003042003E3063FFFF0002140000431025DC
-:10055000ACA200008F4201003C06080094C64DBECC
-:10056000ACA20004974301169744010E3C02200000
-:1005700000031C003084FFFF00641825ACA30008B2
-:1005800000C2302597420110974301122404000154
-:10059000000214003063FFFF00431025ACA2000CE2
-:1005A000974201143042FFFFACA20010ACA000142F
-:1005B000ACA000180E000550ACA6001C3C020800C0
-:1005C0008C420040244200013C010800AC22004063
-:1005D0003C0208008C420044322300042442000103
-:1005E0003C010800AC2200441060001A32220002D4
-:1005F0008F4202B8044300088E0200203C0208002B
-:100600008C420060244200013C010800AC220060E2
-:100610000A0001772404000196030016000020213F
-:10062000AF4202808E020004A7430284AF420288D8
-:100630003C021000AF4202B83C0208008C42005C51
-:10064000244200013C010800AC22005C0A00017851
-:100650008FBF001810400013000020218F430104B9
-:100660003C026020AC4300148C420004240301FED1
-:10067000304203FF1443000B000020218F42010091
-:10068000000211C02442FFFC2C420008104000026E
-:100690002403000200031F403C026000AC436914C5
-:1006A000000020218FBF00188FB100148FB0001000
-:1006B0000080102103E0000827BD00208F430100C7
-:1006C0002402010050620003000311C20000000D6B
-:1006D000000311C200021040005A1021A440008003
-:1006E00003E00008000010219362000003E000080E
-:1006F000AF80000003E000080000102103E00008C4
-:1007000000001021240201001482000800000000F3
-:100710003C0208008C4200FC244200013C0108001D
-:10072000AC2200FC0A00019F30A200203C0208001D
-:100730008C420084244200013C010800AC22008469
-:1007400030A200201040000830A300103C02080036
-:100750008C420108244200013C010800AC2201083F
-:1007600003E0000800000000106000080000000026
-:100770003C0208008C420104244200013C010800B4
-:10078000AC22010403E00008000000003C02080065
-:100790008C420100244200013C010800AC2201000F
-:1007A00003E000080000000027BDFFE8AFBF001015
-:1007B0002744010094830008306200041040001BAD
-:1007C000306600028F4202B804410008240500018F
-:1007D0003C0208008C420060244200013C010800F9
-:1007E000AC2200600A0001EB8FBF00108C82002059
-:1007F0009483001600002821AF4202808C820004FE
-:10080000A7430284AF4202883C021000AF4202B804
-:100810003C0208008C42005C244200013C010800BC
-:10082000AC22005C0A0001EB8FBF001010C0000674
-:10083000006028218F4401000E00018F000000009D
-:100840000A0001EA240500018F8200088F43010499
-:1008500050430007000028218F4401000E00018F43
-:10086000000000008F420104AF8200080000282130
-:100870008FBF001000A0102103E0000827BD001862
-:100880003C0208008C420088274301009465000C5C
-:10089000244200013C010800AC2200888C6400184E
-:1008A0000345102190454000AF4400388C62001C85
-:1008B0002403FFF800052E000043102434420004F6
-:1008C000AF42003C3C020005AF4200300000000097
-:1008D0000000000000000000AF450404000000001C
-:1008E00000000000000000003C020006344200014D
-:1008F000AF420030000000000000000000000000D7
-:100900008F420000304200101040FFFD0000102117
-:1009100003E000080000000027BDFFE0AFB20018B0
-:100920003C036010AFBF001CAFB10014AFB00010AB
-:100930008C6450002402FF7F3C1A80000082202437
-:100940003484380C24020037AC6450003C12080098
-:1009500026524D38AF42000824020C80AF420024DA
-:100960003C1B80083C06080024C6062C02401021CF
-:100970002404001C2484FFFFAC4600000481FFFD1A
-:10098000244200043C0208002442016C3C0108009F
-:10099000AC224D403C020800244204043C01080003
-:1009A000AC224D443C020800244207B83C01080038
-:1009B000AC224D883C0208002442025C3C03080043
-:1009C000246306343C040800248406E03C05080047
-:1009D00024A53B503C010800AC224DA03C0208007D
-:1009E000244205F43C010800AC264D843C0108007B
-:1009F000AC254D943C010800AC234D9C3C01080003
-:100A0000AC244DA43C010800AC224DA83C010800D8
-:100A1000AC234D3C3C010800AC204D483C01080093
-:100A2000AC204D4C3C010800AC204D503C0108006E
-:100A3000AC204D543C010800AC204D583C0108004E
-:100A4000AC204D5C3C010800AC204D603C0108002E
-:100A5000AC244D643C010800AC204D683C0108000A
-:100A6000AC204D6C3C010800AC204D703C010800EE
-:100A7000AC204D743C010800AC204D783C010800CE
-:100A8000AC264D7C3C010800AC264D803C010800A2
-:100A9000AC204D8C3C010800AC254D903C01080079
-:100AA000AC234D980E0006BB000000003C02800005
-:100AB000344200708C420000AF8200143C030800F6
-:100AC0008C6300208F820004104300043C028000ED
-:100AD0000E0004F3AF8300043C0280003446007033
-:100AE0003C0308008C6300A03C0208008C4200A478
-:100AF000104300048F8400143C010800AC2300A4C0
-:100B0000A743009E8CCA00003C0308008C6300BC15
-:100B10003C0208008C4200B80144202300641821E4
-:100B2000000040210064202B0048102100441021C7
-:100B30003C010800AC2300BC3C010800AC2200B81A
-:100B40008F510000322200071040FFDCAF8A0014F2
-:100B50008CC600003C0508008CA500BC3C040800C5
-:100B60008C8400B800CA302300A628210000102180
-:100B700000A6302B00822021008620213227000190
-:100B80003C010800AC2500BC3C010800AC2400B8C6
-:100B900010E0001F322200028F420100AF4200200D
-:100BA0008F420104AF4200A89342010B0E0001885E
-:100BB000305000FF2E02001D544000040010108031
-:100BC0000E00018B0A0002C5000000000052102137
-:100BD0008C4200000040F8090000000010400005B1
-:100BE0003C0240008F4301043C026020AC430014EF
-:100BF0003C024000AF4201383C0208008C42003405
-:100C0000244200013C010800AC22003432220002E0
-:100C10001040000E322200048F4201400E00018875
-:100C2000AF4200200E00034B000000003C024000D9
-:100C3000AF4201783C0208008C4200382442000197
-:100C40003C010800AC220038322200041040FF981A
-:100C50003C0280008F4201800E000188AF420020DC
-:100C60008F43018024020F00146200050000000081
-:100C70008F420188A742009C0A0002FA3C02400011
-:100C80009362000024030050304200FF1443000828
-:100C90003C0240000E00032D000000005440000400
-:100CA0003C0240000E000E0D000000003C0240001F
-:100CB000AF4201B83C0208008C42003C24420001D3
-:100CC0003C010800AC22003C0A00027A3C02800091
-:100CD0003C0290003442000100822025AF440020F5
-:100CE0008F4200200440FFFE0000000003E00008E7
-:100CF000000000003C0280003442000100822025F8
-:100D000003E00008AF44002027BDFFE0AFB10014AE
-:100D1000AFB0001000808821AFBF00180E000302A2
-:100D200030B000FF9362007D022020210202802566
-:100D3000A370007D8F7000743C0280000E00030BD6
-:100D400002028024160000098FBF00188F4201F8AC
-:100D50000440FFFE24020002AF5101C0A34201C4BF
-:100D60003C021000AF4201F88FBF00188FB1001491
-:100D70008FB0001003E0000827BD002027BDFFE86A
-:100D8000AFBF0010974201843042020010400005BE
-:100D9000000020210E001042000000000A00034164
-:100DA000240400018F420188044000098FBF001015
-:100DB0008F4201883C03FF00004310243C030400E1
-:100DC00014430003240400019362003E8FBF00100F
-:100DD0000080102103E0000827BD00182402000154
-:100DE000A3600022A76200168F4401400A0003108E
-:100DF0002405000127BDFFE8AFBF0014AFB000100D
-:100E000093620000304400FF3883002038820030B5
-:100E10000003182B0002102B00621824106000033E
-:100E200024020050148200628FBF001493420148D4
-:100E3000304200FF2443FFFF2C6200051040005C9D
-:100E40008FBF0014000310803C03080024634CC8CB
-:100E5000004310218C420000004000080000000008
-:100E60000E0003028F4401408F70000C8F4201443A
-:100E70001602000224020001AF62000C0E00030BF8
-:100E80008F4401408F420144145000048FBF00146E
-:100E90008FB000100A000FB827BD00188F62000C39
-:100EA0000A0003B300000000976200108F43014462
-:100EB0003042FFFF1462000900000000240200011C
-:100EC000A76200108F420140AF4202003C021000B6
-:100ED000AF4202380A0003BA8FBF001497620010B5
-:100EE0000A0003B3000000000E0003028F4401401B
-:100EF000976200128F4301443050FFFF1603000237
-:100F000024020001A76200120E00030B8F4401406F
-:100F10008F420144160200048FBF00148FB00010EE
-:100F20000A00034527BD0018976200120A0003B3A8
-:100F300000000000976200148F4301443042FFFF1D
-:100F4000146200068FBF0014240200018FB000104D
-:100F5000A76200140A0012E227BD0018976200146D
-:100F60000A0003B300000000976200168F4301449B
-:100F70003042FFFF14620006240200018FBF0014FC
-:100F80008FB00010A76200160A000BAA27BD001838
-:100F900097620016144000068FBF00143C02080040
-:100FA0008C420070244200013C010800AC22007019
-:100FB0008FB0001003E0000827BD001827BDFFE830
-:100FC000AFBF0014AFB000108F500100936200005B
-:100FD00093430109304400FF2402001F106200A562
-:100FE0002862002010400018240200382862000AFD
-:100FF0001040000C2402000B286200081040002C56
-:1010000000000000046000E528620002144000288F
-:1010100024020006106200268FBF00140A0004B7E5
-:101020008FB000101062005E2862000B144000DCDC
-:101030008FBF00142402000E106200738FB00010E6
-:101040000A0004B700000000106200C028620039E6
-:101050001040000A2402008024020036106200CAF8
-:1010600028620037104000B424020035106200C12D
-:101070008FBF00140A0004B78FB000101062002B5D
-:101080002862008110400006240200C824020039B2
-:10109000106200B48FBF00140A0004B78FB00010B4
-:1010A000106200998FBF00140A0004B78FB00010BF
-:1010B0003C0208008C420020104000B98FBF001491
-:1010C0000E00052B000000008F4201008F830020DE
-:1010D0009745010C97460108AC6200008F4201045D
-:1010E0003C04080094844DBE00052C00AC62000452
-:1010F0008F4201180006340000C43025AC6200089D
-:101100008F42011C24040001AC62000C9342010ACE
-:1011100000A22825AC650010AC600014AC6000187B
-:10112000AC66001C0A00048D8FBF00143C0208004E
-:101130008C4200201040009A8FBF00140E00052B37
-:1011400000000000974401083C03080094634DBE72
-:101150009745010C000422029746010E8F82002061
-:10116000000426000083202500052C003C0300809D
-:1011700000A6282500832025AC400000AC400004D8
-:10118000AC400008AC40000CAC450010AC40001472
-:10119000AC400018AC44001C0A00048C240400017C
-:1011A0009742010C144000150000000093620005F6
-:1011B0003042001014400011000000000E00030235
-:1011C0000200202193620005020020213442001019
-:1011D0000E00030BA36200059362000024030020AD
-:1011E000304200FF1043006D020020218FBF001429
-:1011F0008FB000100A00105827BD00180000000D25
-:101200000A0004B68FBF00143C0208008C42002084
-:10121000104000638FBF00140E00052B000000007B
-:101220008F4201048F8300209744010C3C05080085
-:1012300094A54DBEAC6200009762002C000424000F
-:101240003042FFFF008220253C02400E00A22825EC
-:10125000AC640004AC600008AC60000CAC60001032
-:10126000AC600014AC600018AC65001C0A00048C73
-:10127000240400010E00030202002021A7600008E0
-:101280000E00030B02002021020020210E0003109B
-:10129000240500013C0208008C4200201040004060
-:1012A0008FBF00140E00052B000000009742010CB8
-:1012B0008F8300203C05080094A54DBE0002140059
-:1012C000AC700000AC620004AC6000088F64004C9D
-:1012D0003C02401F00A22825AC64000C8F62005025
-:1012E00024040001AC6200108F620054AC62001450
-:1012F000AC600018AC65001C8FBF00148FB00010EC
-:101300000A00055027BD0018240200205082002545
-:101310008FB000100E000FA202002021104000200C
-:101320008FBF0014020020218FB000100000282180
-:101330000A00031027BD0018020020218FBF0014EF
-:101340008FB000100A00061827BD00189745010C41
-:10135000020020218FBF00148FB000100A00063851
-:1013600027BD0018020020218FB000100A00065D82
-:1013700027BD00189345010D020020218FB00010F9
-:101380000A0006A727BD0018020020218FBF001405
-:101390008FB000100A00068327BD00188FBF00140D
-:1013A0008FB0001003E0000827BD00188F420278BC
-:1013B0000440FFFE2402000234840080AF44024057
-:1013C000A34202443C02100003E00008AF4202784E
-:1013D0003C04080094844DCA3C0208008C424DD461
-:1013E0003083FFFF000318C000431021AF42003CD0
-:1013F0003C0208008C424DD0AF4200383C02005005
-:1014000034420008AF42003000000000000000003D
-:10141000000000008F420000304200201040FFFD1D
-:10142000000000008F4204003C010800AC224DC0C7
-:101430008F4204043C010800AC224DC43C02002051
-:10144000AF420030000000003C02080094424DC84A
-:101450003C03080094634DCC3C05080094A54DCE98
-:1014600024840001004310213083FFFF3C01080069
-:10147000A4224DC83C010800A4244DCA14650003F1
-:10148000000000003C010800A4204DCA03E0000851
-:10149000000000003C05000A27BDFFE803452821A5
-:1014A0003C04080024844DB0AFBF00100E0005B509
-:1014B0002406000A3C02080094424DB23C03080096
-:1014C00094634DCE3042000F2442000300431804C1
-:1014D00024027FFF0043102B10400002AF83001C4A
-:1014E0000000000D0E0004C2000000003C020800D5
-:1014F00094424DBA8FBF001027BD001803E00008CA
-:10150000A74200A23C02000A0342102194430006B5
-:101510003C02080094424DBA3C010800A4234DB699
-:10152000004310238F83001C0002140000021403E8
-:101530000043102B03E000083842000127BDFFE8FC
-:10154000AFBF00103C02000A034210219442000683
-:101550003C010800A4224DB60E00050F000000005B
-:101560005440FFF93C02000A8FBF001003E000085E
-:1015700027BD001827BDFFE8AFBF00100E00050F04
-:101580000000000010400003000000000E00051DD8
-:10159000000000003C0208008C424DC08FBF0010CC
-:1015A00027430400AF4200383C0208008C424DC47F
-:1015B00027BD0018AF830020AF42003C3C0200056D
-:1015C000AF42003003E00008AF8000188F8200189F
-:1015D0003C0300060002114000431025AF420030DA
-:1015E0000000000000000000000000008F4200002A
-:1015F000304200101040FFFD27420400AF8200205F
-:1016000003E00008AF8000183C0608008CC64DC4FB
-:101610008F8500188F8300203C02080094424DBA49
-:1016200027BDFFE024A5000124630020244200011F
-:1016300024C70020AFB10014AFB00010AFBF001836
-:10164000AF850018AF8300203C010800A4224DBAEA
-:10165000309000FF3C010800AC274DC404C10008D5
-:101660000000882104E00006000000003C020800A1
-:101670008C424DC0244200013C010800AC224DC008
-:101680003C02080094424DBA3C03080094634DC8E4
-:101690000010202B004310262C420001004410258E
-:1016A000144000048F830018240200101462000FFD
-:1016B000000000000E000541241100013C03080059
-:1016C00094634DBA3C02080094424DC81462000372
-:1016D000000000000E0004C200000000160000031D
-:1016E000000000000E00052B000000003C03080075
-:1016F00094634DBE3C02080094424DBC246300013B
-:101700003064FFFF3C010800A4234DBE1482000397
-:10171000000000003C010800A4204DBE120000069D
-:10172000000000003C02080094424DBAA74200A20B
-:101730000A0005A3022010210E00050F0000000082
-:1017400010400004022010210E00051D00000000C2
-:10175000022010218FBF00188FB100148FB000102D
-:1017600003E0000827BD00203084FFFF30A5FFFF05
-:1017700000001821108000070000000030820001E6
-:101780001040000200042042006518210A0005AB49
-:101790000005284003E000080060102110C000068A
-:1017A00024C6FFFF8CA2000024A50004AC82000028
-:1017B0000A0005B52484000403E0000800000000CE
-:1017C00010A0000824A3FFFFAC860000000000006A
-:1017D000000000002402FFFF2463FFFF1462FFFAF1
-:1017E0002484000403E0000800000000240200013B
-:1017F000AF62000CA7620010A7620012A76200147B
-:1018000003E00008A76200163082007F0342102127
-:101810003C08000E004818213C0208008C420020C1
-:1018200027BDFFD82407FF80AFB3001CAFB200185C
-:10183000AFB10014AFB00010AFBF00200080802116
-:1018400030B100FF0087202430D200FF1040002F6D
-:1018500000009821AF44002C906200002403005047
-:10186000304200FF1443000E000000003C0208005C
-:101870008C4200E00202102100471024AF42002CED
-:101880003C0208008C4200E0020210213042007F3E
-:101890000342102100481021944200D43053FFFF2E
-:1018A0000E00052B000000003C02080094424DBED3
-:1018B0008F8300200011340000C2302500122C005C
-:1018C0003C02400000C2302534A50001AC7000008D
-:1018D0008FBF0020AC6000048FB20018AC7300080A
-:1018E0008FB10014AC60000C8FB3001CAC6500100D
-:1018F0008FB00010AC60001424040001AC6000182C
-:1019000027BD00280A000550AC66001C8FBF0020D0
-:101910008FB3001C8FB200188FB100148FB000106D
-:1019200003E0000827BD00289343010F24020010A4
-:101930001062000E2865001110A00007240200129A
-:10194000240200082405003A10620006000030213D
-:1019500003E0000800000000240500351462FFFCCD
-:10196000000030210A0005D0000000008F42007402
-:1019700024420FA003E00008AF62000C27BDFFE87F
-:10198000AFBF00100E000310240500018FBF001030
-:1019900024020001A762001227BD001824020001E2
-:1019A00003E00008A360002227BDFFE0AFB10014F0
-:1019B000AFB00010AFBF001830B1FFFF0E00030240
-:1019C000008080219362003F24030004304200FF26
-:1019D0001443000C02002021122000082402000AF7
-:1019E0000E0005C900000000936200052403FFFEFD
-:1019F00000431024A362000524020012A362003FEA
-:101A0000020020210E00030BA360008116200003BA
-:101A1000020020210E00062D0000000002002021FF
-:101A2000322600FF8FBF00188FB100148FB0001056
-:101A3000240500380A0005D027BD002027BDFFE09F
-:101A4000AFBF001CAFB20018AFB10014AFB00010B0
-:101A50000E000302008080210E0005C90000000076
-:101A60009362003F24120018305100FF123200032D
-:101A70000200202124020012A362003F93620005AD
-:101A80002403FFFE004310240E00030BA362000595
-:101A9000020020212405002016320007000030211A
-:101AA0008FBF001C8FB200188FB100148FB00010D0
-:101AB0000A00031027BD00208FBF001C8FB2001842
-:101AC0008FB100148FB00010240500390A0005D032
-:101AD00027BD002027BDFFE8AFB00010AFBF001446
-:101AE0009742010C2405003600808021144000102C
-:101AF000304600FF0E000302000000002402001226
-:101B0000A362003F93620005344200100E0005C935
-:101B1000A36200050E00030B020020210200202119
-:101B20000E000310240500200A00069C000000009F
-:101B30000E0005D0000000000E000302020020216C
-:101B4000936200232403FF9F0200202100431024FE
-:101B50008FBF00148FB00010A36200230A00030B94
-:101B600027BD001827BDFFE0AFBF0018AFB10014BC
-:101B7000AFB0001030B100FF0E00030200808021E2
-:101B8000240200120E0005C9A362003F0E00030BE1
-:101B90000200202102002021022030218FBF0018E6
-:101BA0008FB100148FB00010240500350A0005D055
-:101BB00027BD0020A380002C03E00008A380002D97
-:101BC0008F4202780440FFFE8F820034AF42024011
-:101BD00024020002A34202443C02100003E0000879
-:101BE000AF4202783C0360008C625400304200082F
-:101BF0001440FFFD000000008C625408AF82000C0E
-:101C000024020052AC605408AC645430AC625434CA
-:101C10002402000803E00008AC6254003C026000AB
-:101C20008C42540030420008104000053C03600024
-:101C30008C625400304200081440FFFD0000000098
-:101C40008F83000C3C02600003E00008AC435408A2
-:101C500090A3000024020005008040213063003F73
-:101C600000004821146200050000502190A2001CD1
-:101C700094A3001E304900FF306AFFFFAD00000C46
-:101C8000AD000010AD000024950200148D05001C6D
-:101C90008D0400183042FFFF00491023000211009C
-:101CA000000237C3004038210086202300A2102BF9
-:101CB0000082202300A72823AD05001CAD040018D6
-:101CC000A5090014A5090020A50A001603E00008D4
-:101CD000A50A00228F4201F80440FFFE2402000200
-:101CE000AF4401C0A34201C43C02100003E000085D
-:101CF000AF4201F83C0208008C4200B427BDFFE867
-:101D0000AFBF001424420001AFB000103C01080036
-:101D1000AC2200B48F4300243C02001F30AA00FF15
-:101D20003442FF8030D800FF006280240080F82118
-:101D300030EF00FF1158003B01405821240CFF8078
-:101D40003C19000A3163007F000310C000031940F2
-:101D5000006218213C0208008C4200DC256800016A
-:101D6000310D007F03E21021004310213043007F3A
-:101D700003431821004C102400794821AF4200246D
-:101D80008D220024016C1824006C7026AD22000CFA
-:101D90008D220024310800FFAD220010952200148E
-:101DA000952300208D27001C3042FFFF3063FFFF8A
-:101DB0008D2600180043102300021100000227C3E3
-:101DC0000040282100C4302300E2102B00C2302341
-:101DD00000E53823AD27001CAD2600189522002011
-:101DE000A522001495220022154B000AA5220016F8
-:101DF0008D2300248D2200082546000131450080F6
-:101E00001462000430C4007F108F000238AA0080E2
-:101E100000C0502151AF000131C800FF1518FFC9A3
-:101E2000010058218F8400343082007F0342182142
-:101E30003C02000A006218212402FF800082202454
-:101E4000AF440024A06A0079A06A00838C6200502D
-:101E50008F840034AC6200708C6500743C027FFF9C
-:101E60003442FFFF00A228240E000703AC65007473
-:101E7000AF5000248FBF00148FB0001003E00008A3
-:101E800027BD001827BDFFC0AFBE0038AFB7003474
-:101E9000AFB5002CAFB20020AFB1001CAFB000183E
-:101EA000AFBF003CAFB60030AFB40028AFB30024E2
-:101EB0008F4500248F4600288F43002C3C02001FD2
-:101EC0003442FF800062182400C230240080A82120
-:101ED000AFA3001400A2F0240E0006C7AFA60010A6
-:101EE0003C0208008C4200E02410FF80036088213F
-:101EF00002A2102100501024AF4200243C0208002E
-:101F00008C4200E002A210213042007F03421821DF
-:101F10003C02000A00629021924200D29363008446
-:101F2000305700FF306300FF2402000110620034CC
-:101F30000360202124020002146200360000000029
-:101F40000E0012AE024028219223008392220083C9
-:101F50003063007F3042007F000210C00003194050
-:101F6000006218213C0208008C4200DC02A2102111
-:101F70000043382100F01024AF4200289225007859
-:101F80009224008330E2007F034218213C02000CBF
-:101F900014850007006280212402FFFFA24200F1A5
-:101FA0002402FFFFA64200F20A0007BF2402FFFF3F
-:101FB00096020020A24200F196020022A64200F200
-:101FC0008E020024AE4200F492220083A24200F06E
-:101FD0008E4200C8AE4200FC8E4200C4AE4200F801
-:101FE0008E220050AE4201008E4200CCAE4201046F
-:101FF000922200853042003F0A00081A3442004015
-:102000000E0012D102402821922200850A00081AEF
-:102010003042003F936200852403FFDF3042003FDF
-:10202000A36200859362008500431024A3620085AB
-:102030009363008393620078307400FF304200FFA6
-:1020400010540036240AFF803C0C000C3283007FC1
-:10205000000310C000031940006218213C02080070
-:102060008C4200DC268800013109007F02A2102189
-:102070000043382130E2007F0342182100EA102497
-:10208000AF420028006C80218E020024028A1824AE
-:10209000006A5826AE02000C8E020024310800FFB0
-:1020A000AE02001096020014960300208E07001C5A
-:1020B0003042FFFF3063FFFF8E06001800431023FD
-:1020C00000021100000227C30040282100C4302371
-:1020D00000E2102B00C2302300E53823AE07001CBD
-:1020E000AE06001896020020A602001496020022F6
-:1020F000A602001692220079304200FF1054000719
-:102100000000000051370001316800FF9222007882
-:10211000304200FF1448FFCD0100A021922200832D
-:10212000A22200798E2200500A00087AAE220070A6
-:10213000A22200858E22004C2405FF80AE42010CB5
-:102140009222008534420020A2220085924200D1D2
-:102150003C0308008C6300DC305400FF3C020800A4
-:102160008C4200E400143140001420C002A3182166
-:1021700000C4202102A21021006438210046102151
-:102180000045182400E52824AF450028AF43002C63
-:102190003042007F924400D030E3007F0342282188
-:1021A000034318213C02000C006280213C02000E17
-:1021B000309600FF00A298211296002A000000002D
-:1021C0008E02000C02002021026028211040002510
-:1021D000261000280E0006E2000000009262000DAA
-:1021E00026830001307400FF3042007FA262000DA0
-:1021F0002404FF801697FFF0267300203C0208009D
-:102200008C4200DC0000A02102A210210044102416
-:10221000AF4200283C0208008C4200E43C03080066
-:102220008C6300DC02A2102100441024AF42002C79
-:102230003C0208008C4200E402A318213063007FB6
-:1022400002A210213042007F0342202103431821C3
-:102250003C02000C006280213C02000E0A00083C97
-:10226000008298218E4200D8AE2200508E4200D8C3
-:10227000AE22007092250083924600D19223008303
-:10228000924400D12402FF8000A228243063007F02
-:10229000308400FF00A628250064182A1060000280
-:1022A00030A500FF38A50080A2250083A225007973
-:1022B0000E0006D5000000009222007E02A0202120
-:1022C000A222007A8E2300743C027FFF3442FFFF7B
-:1022D000006218240E000703AE2300748FA20010C2
-:1022E000AF5E00248FBF003CAF4200288FBE003895
-:1022F0008FA200148FB700348FB600308FB5002C3A
-:102300008FB400288FB300248FB200208FB1001C3F
-:102310008FB0001827BD004003E00008AF42002C3A
-:1023200090A2000024420001A0A200003C0308008B
-:102330008C6300F4304200FF1443000F0080302112
-:10234000A0A000003C0208008C4200E48F8400340E
-:10235000008220213082007F034218213C02000CC1
-:10236000006218212402FF8000822024ACC30000F8
-:1023700003E00008AF4400288C82000024420020C3
-:1023800003E00008AC82000094C200003C08080092
-:10239000950800CA30E7FFFF0080482101021021A4
-:1023A000A4C2000094C200003042FFFF00E2102BE4
-:1023B00054400001A4C7000094A200003C030800A0
-:1023C0008C6300CC24420001A4A2000094A200006F
-:1023D0003042FFFF544300078F8600280107102B6F
-:1023E000A4A000005440000101003821A4C700004F
-:1023F0008F8600288CC4001CAF44003C94A20000CF
-:102400008F43003C3042FFFF000210C000621821E1
-:10241000AF43003C8F42003C008220231880000420
-:10242000000000008CC200180A0008DB24420001F2
-:102430008CC20018AF4200383C02005034420010F9
-:10244000AF4200300000000000000000000000006B
-:102450008F420000304200201040FFFD00000000CD
-:102460008F420404AD2200048F420400AD2200001C
-:102470003C020020AF42003003E0000800000000F2
-:1024800027BDFFE0AFB20018AFB10014AFB000102D
-:10249000AFBF001C94C2000000C080213C120800A5
-:1024A000965200C624420001A602000096030000D6
-:1024B00094E2000000E03021144300058FB10030A9
-:1024C0000E0008B0024038210A00090D000000008B
-:1024D0008C8300048C8200042442004004610007C5
-:1024E000AC8200048C820004044000040000000060
-:1024F0008C82000024420001AC82000096020000A1
-:102500003042FFFF50520001A6000000962200005A
-:1025100024420001A62200008F820028962300009A
-:1025200094420016144300048FBF001C24020001D3
-:10253000A62200008FBF001C8FB200188FB10014BC
-:102540008FB0001003E0000827BD00208F8900280D
-:1025500027BDFFE0AFBF00188D22002827480400E8
-:1025600030E700FFAF4200388D22002CAF880030EA
-:10257000AF42003C3C020005AF42003000000000CA
-:10258000000000000000000000000000000000004B
-:10259000000000008C82000C8C82000CAD02000058
-:1025A0008C820010AD0200048C820018AD0200087D
-:1025B0008C82001CAD02000C8CA20014AD02001035
-:1025C0008C820020AD02001490820005304200FF92
-:1025D00000021200AD0200188CA20018AD02001C0F
-:1025E0008CA2000CAD0200208CA20010AD020024D1
-:1025F0008CA2001CAD0200288CA20020AD02002C91
-:10260000AD060030AD000034978300263402FFFF92
-:1026100014620002006020213404FFFF10E000116A
-:10262000AD040038952300369524003624020001BD
-:102630003063FFFF000318C2006918219065004055
-:10264000308400070082100400451025A06200407D
-:102650008F820028944200563042FFFF0A0009741E
-:10266000AD02003C9523003695240036240200017B
-:102670003063FFFF000318C2006918219065004015
-:102680003084000700821004000210270045102447
-:10269000A0620040AD00003C00000000000000000F
-:1026A000000000003C02000634420040AF4200300F
-:1026B0000000000000000000000000008F42000049
-:1026C000304200101040FFFD8F860028AF88003098
-:1026D00024C2005624C7003C24C4002824C500326C
-:1026E00024C600360E0008EEAFA200108FBF0018FF
-:1026F00003E0000827BD00208F8300243C0608006B
-:102700008CC600E88F82003430633FFF00031980DD
-:1027100000461021004310212403FF803046007F33
-:1027200000431024AF420028034618213C02000C4D
-:102730000062302190C2000D30A500FF000038215A
-:1027400034420010A0C2000D8F8900288F8A002417
-:1027500095230036000A138230480003240200014A
-:10276000A4C3000E1102000B290200021040000554
-:10277000240200021100000C240300010A0009B821
-:102780000000182111020006000000000A0009B82C
-:10279000000018218CC2002C0A0009B82443000153
-:1027A0008CC20014244300018CC200180043102B7B
-:1027B00050400009240700012402002714A200034E
-:1027C000000000000A0009C4240700019522003E11
-:1027D00024420001A522003E000A13823043000378
-:1027E0002C620002104000090080282114600004BF
-:1027F0000000000094C200360A0009D43046FFFFF2
-:102800008CC600380A0009D400802821000030213D
-:102810003C04080024844DD80A000921000000006F
-:10282000274901008D22000C95230006012020215C
-:10283000000216023046003F3063FFFF24020027EB
-:1028400000C0282128C7002810C2000EAF83002432
-:1028500010E00008240200312402002110C2000907
-:102860002402002510C200079382002D0A0009F3FC
-:102870000000000010C200059382002D0A0009F339
-:10288000000000000A00098C000000000A0006BEDB
-:102890000000000095230006912400058D25000C02
-:1028A0008D2600108D2700188D28001C8D290020F2
-:1028B000244200013C010800A4234DDE3C01080035
-:1028C000A0244DDD3C010800AC254DE43C0108008E
-:1028D000AC264DE83C010800AC274DF03C01080057
-:1028E000AC284DF43C010800AC294DF803E0000889
-:1028F000A382002D8F87002827BDFFC0AFB300340F
-:10290000AFB20030AFB1002CAFB00028AFBF00387D
-:102910003C0208008C4200D094E3003030B0FFFF4E
-:10292000005010073045FFFF3063FFFF00C09821C3
-:10293000A7A200103C110800963100C614A300069F
-:102940003092FFFF8CE2002424420030AF42003C72
-:102950000A000A2C8CE2002094E200323042FFFF91
-:1029600054A2000827A400188CE2002C2442003056
-:10297000AF42003C8CE20028AF4200380A000A3A1D
-:102980008F84002827A5001027A6002002203821C8
-:102990000E0008B0A7A000208FA20018244200302B
-:1029A000AF4200388FA2001CAF42003C8F84002849
-:1029B0003C020005AF4200309482003427430400FB
-:1029C0003042FFFF0202102B14400007AF8300309B
-:1029D0009482005494830034020210210043102397
-:1029E0000A000A4E3043FFFF94830054948200345F
-:1029F0000223182100501023006218233063FFFFC8
-:102A0000948200163042FFFF1443000300000000D0
-:102A10000A000A5C24030001948200163042FFFF82
-:102A20000043102B104000058F8200309482001666
-:102A3000006210233043FFFF8F820030AC53000050
-:102A4000AC400004AC520008AC43000C3C02000651
-:102A500034420010AF4200300000000000000000CF
-:102A6000000000008F420000304200101040FFFDC7
-:102A7000001018C20064182190650040320400075D
-:102A8000240200018FBF00388FB300348FB20030B2
-:102A90008FB1002C8FB00028008210040045102553
-:102AA00027BD004003E00008A062004027BDFFA84A
-:102AB000AFB60050AFB5004CAFB40048AFB3004460
-:102AC000AFB1003CAFBF0054AFB20040AFB0003870
-:102AD0008C9000003C0208008C4200E88F86003495
-:102AE000960300022413FF8000C2302130633FFFB1
-:102AF0000003198000C3382100F3102490B20000B5
-:102B0000AF42002C9203000230E2007F03423021EA
-:102B10003C02000E00C28821306300C02402004045
-:102B20000080A82100A0B021146200260000A0218E
-:102B30008E3400388E220018144000022402000156
-:102B4000AE2200189202000D304200201440001501
-:102B50008F8200343C0308008C6300DC001238C014
-:102B6000001231400043102100C7302100463821B7
-:102B700030E300073C02008030E6007800C23025D8
-:102B80000343182100F31024AF4208002463090016
-:102B9000AF4608108E2200188C63000800431021F5
-:102BA000AE2200188E22002C8E2300182442000131
-:102BB0000062182B1060003D000000000A000B109E
-:102BC00000000000920300022402FFC00043102412
-:102BD000304200FF1440000524020001AE2200181C
-:102BE000962200360A000AF93054FFFF8E220014A4
-:102BF00024420001AE2200189202000000021600DA
-:102C000000021603044100290000000096020002A1
-:102C100027A4001000802821A7A200169602000217
-:102C200024070001000030213042FFFFAF82002462
-:102C30000E000921AFA0001C960300023C0408000E
-:102C40008C8400E88F82003430633FFF00031980DA
-:102C500000441021004310213043007F3C05000C4C
-:102C60000053102403431821AF42002800651821A7
-:102C70009062000D001221403042007FA062000DE2
-:102C80003C0308008C6300E48F8200340043102171
-:102C90000044382130E2007F03421021004510211A
-:102CA00000F31824AF430028AEA200009222000DCA
-:102CB000304200101040001302A020218F83002812
-:102CC0008EA40000028030219462003E2442FFFF67
-:102CD000A462003E948400029625000E3084FFFF1B
-:102CE0000E000A0B30A5FFFF8F82002894430034AA
-:102CF0009622000E1443000302A0202124020001AA
-:102D0000A382002C02C028210E00089600000000BB
-:102D10008FBF00548FB600508FB5004C8FB4004861
-:102D20008FB300448FB200408FB1003C8FB00038A9
-:102D300003E0000827BD00588F82002827BDFFD080
-:102D4000AFB40028AFB20020AFBF002CAFB3002457
-:102D5000AFB1001CAFB00018904400D0904300D138
-:102D60000000A021309200FFA3A30010306300FFF9
-:102D70008C5100D88C5300DC1072002B240200010F
-:102D80003C0308008C6300E493A400108F8200349D
-:102D90002406FF800004214000431021004410213C
-:102DA0003043007F00461024AF420028034318211F
-:102DB0003C02000C006218218C62000427A400145D
-:102DC00027A5001002228021027010230440001564
-:102DD000AFA300149062000D00C21024304200FF27
-:102DE00014400007020088219062000D3442004028
-:102DF0000E000896A062000D0A000B5593A2001069
-:102E00000E000A79241400018F830028AC7000D8CA
-:102E100093A20010A06200D193A200101452FFD818
-:102E20000000000024020001168200048FBF002C65
-:102E30000E0006BE000000008FBF002C8FB40028DB
-:102E40008FB300248FB200208FB1001C8FB0001808
-:102E500003E0000827BD003027BDFFD8AFB3001C3A
-:102E6000AFB20018AFB10014AFB00010AFBF002078
-:102E70000080982100E0802130B1FFFF0E00052B7B
-:102E800030D200FF00000000000000000000000041
-:102E90008F820020AC510000AC520004AC530008FB
-:102EA000AC40000CAC400010AC400014AC4000182A
-:102EB0003C03080094634DBE02038025AC50001C07
-:102EC00000000000000000000000000024040001D9
-:102ED0008FBF00208FB3001C8FB200188FB1001479
-:102EE0008FB000100A00055027BD002827BDFFE85D
-:102EF000AFB00010AFBF001430A5FFFF30C600FF19
-:102F00000080802124020C80AF42002400000000D9
-:102F100000000000000000000000000000000000B1
-:102F20000E000B64000000003C040800248400E054
-:102F30008C8200002403FF808FBF00140202102146
-:102F400000431024AF4200248C8200003C03000A9E
-:102F5000020280213210007F035010218FB0001038
-:102F60000043102127BD001803E00008AF820028AD
-:102F700027BDFFE8AFBF00108F4401403C030800AD
-:102F80008C6300E02402FF80AF84003400831821AA
-:102F900000621024AF4200243C020008034240219A
-:102FA000950500023063007F3C02000A03431821AC
-:102FB0000062182130A5FFFF3402FFFF000030211E
-:102FC0003C07602010A20006AF8300282402FFFF08
-:102FD000A5020002946500D40E000B8930A5FFFF06
-:102FE0008FBF001024020C8027BD001803E00008EA
-:102FF000AF4200243C020008034240219502000237
-:103000003C0A0800954A00C63046FFFF14C000077E
-:103010003402FFFF8F8200288F8400343C07602039
-:10302000944500D40A000BF230A5FFFF10C2002423
-:103030008F87002894E2005494E400163045FFFF87
-:1030400000A6102300A6182B3089FFFF1060000493
-:103050003044FFFF00C51023012210233044FFFF3E
-:10306000008A102B1040000C012A102324020001BA
-:10307000A50200162402FFFFA502000294E500D479
-:103080008F8400340000302130A5FFFF3C07602012
-:103090000A000B89000000000044102A10400008BC
-:1030A00000000000950200163042000110400004AC
-:1030B000000000009742007E24420014A502001682
-:1030C00003E00008000000008F84002827BDFFE017
-:1030D000AFBF0018948200349483003E1060001A41
-:1030E0003048FFFF9383002C240200011462002764
-:1030F0008FBF00188F820028000818C2310800070F
-:10310000006218212447003A244900542444002036
-:10311000244500302446003490620040304200FFD5
-:103120000102100730420001104000168FBF001846
-:103130000E0008EEAFA900108F82002894420034E0
-:103140000A000C0B3048FFFF948300369482003451
-:103150001043000E8FBF001894820036A482003402
-:1031600094820056A48200548C82002CAC820024ED
-:1031700094820032A48200309482003CA482003AFF
-:103180008FBF00180A000BCB27BD002003E000080A
-:1031900027BD002027BDFFE8AFBF00108F4A010008
-:1031A0003C0508008CA500E03C02080090424DE47C
-:1031B0003C0C0800958C4DDE01452821304B003F2A
-:1031C00030A2007F03424021396900323C02000AEC
-:1031D0003963003F2C630001010240212D290001C9
-:1031E0002402FF8000A2282401234825AF8A00344E
-:1031F00000801821AF4500240000302100802821E4
-:1032000024070001AF8800283C04080024844DD81E
-:10321000AF8C002415200007A380002D240200207D
-:103220005562000F006020213402FFFF5582000C20
-:10323000006020212402002015620005000000002B
-:103240008C6300142402FFFF1062000700000000DE
-:103250000E000921000000000A000C6800000000B8
-:103260000E00098C016028210E000C0000000000F7
-:103270008FBF001024020C8027BD001803E0000857
-:10328000AF4200243C0208008C4200E027BDFFA0B2
-:10329000AFB1003C008210212411FF80AFBE005866
-:1032A000AFB70054AFB20040AFB00038AFBF005C62
-:1032B000AFB60050AFB5004CAFB40048AFB3004458
-:1032C000005110248F4800248F4900288F47002880
-:1032D000AF4200243C0208008C4200E000809021B4
-:1032E00024060006008210213042007F034218218C
-:1032F0003C02000A006280213C02001F3442FF8031
-:1033000000E2382427A40010260500F00122F02452
-:103310000102B8240E0005B5AFA700308FA2001837
-:10332000AE0200C48FA2001CAE0200C88FA200240F
-:10333000AE0200CC93A40010920300D12402FF80BF
-:103340000082102400431025304900FF3083007FA5
-:103350003122007F0062102A10400004000310C0D8
-:1033600001311026304900FF000310C0000319404E
-:10337000006218213C0208008C4200DC920400D25A
-:10338000024210210043102100511024AF420028B6
-:1033900093A300103063007F000310C000031940A6
-:1033A000006218213C0208008C4200DC024210211D
-:1033B000004310213042007F034218213C02000CE0
-:1033C000006240218FA300142402FFFF106200302E
-:1033D000309500FF93A2001195030014304400FFC4
-:1033E0003063FFFF0064182B1060000D0000000028
-:1033F000950400148D07001C8D0600183084FFFF13
-:1034000000442023000421000000102100E43821A2
-:1034100000E4202B00C230210A000CE200C430215D
-:10342000950400148D07001C8D0600183084FFFFE2
-:1034300000822023000421000000102100801821B8
-:1034400000C2302300E4202B00C4302300E33823E3
-:10345000AD07001CAD06001893A20011A5020014D0
-:1034600097A20012A50200168FA20014AD02001050
-:103470008FA20014AD02000C93A20011A50200203F
-:1034800097A20012A50200228FA20014AD02002410
-:103490002406FF80024610243256007FAF420024EB
-:1034A000035618213C02000A006280218E02004C63
-:1034B0008FA200203124007F000428C0AE020050FB
-:1034C0008FA200200004214000852821AE02007058
-:1034D00093A2001001208821A202008393A2001071
-:1034E000A2020079920200853042003FA2020085CC
-:1034F0003C0208008C4200DC0242102100451021F1
-:1035000000461024AF42002C3C0208008C4200E42C
-:103510003C0308008C6300DC0242102100441021AF
-:1035200000461024AF4200283C0208008C4200E410
-:103530000243182100651821024210210044102185
-:103540003042007F3063007F93A5001003422021AA
-:10355000034318213C02000E006240213C02000C93
-:1035600010B1008C008248213233007F16600019B0
-:103570002404FF803C0208008C4200DC024210213F
-:1035800000441024AF42002C3C0208008C4200E4AE
-:103590003C0308008C6300DC02421021004410242C
-:1035A000AF4200283C0208008C4200E4024318218C
-:1035B0003063007F024210213042007F034220210D
-:1035C000034318213C02000E006240213C02000C23
-:1035D000008248219124000D2414FF800000102156
-:1035E00000942025A124000D9504000295050014E7
-:1035F0008D07001C3084FFFF30A5FFFF8D060018EB
-:10360000008520230004210000E4382100C230217D
-:1036100000E4202B00C43021AD07001CAD060018CB
-:1036200095020002A5020014A50000168D020008F4
-:10363000AD0200108D020008AD02000C95020002E0
-:10364000A5020020A50000228D020008AD02002482
-:103650009122000D3042004010400042262200011D
-:103660003C0208008C4200E0A3B300283C10000A92
-:103670000242102100541024AF4200243C020800F2
-:103680008C4200E0A380002C27A4002C02421021D1
-:103690003042007F03421821007018218C6200D84C
-:1036A0008D26000427A50028AFA9002C0046102174
-:1036B000AC6200D80E000A79AF83002893A30028DB
-:1036C0008F8200280E0006BEA04300D10E000C0021
-:1036D0000000000002541024AF4200243C02080005
-:1036E0008C4200DC00132940001320C000A42021DC
-:1036F000024210210044102100541024AF42002C3B
-:103700003C0208008C4200E43C0308008C6300DCAF
-:10371000035630210242102100451021005410248C
-:10372000AF4200283C0208008C4200E4024318210A
-:103730000064182102421021004510213042007F10
-:103740003063007F03422021034318213C02000E16
-:10375000006240213C02000C00D080210082482100
-:10376000262200013043007F14750005304400FF1D
-:103770002403FF800223102400431026304400FF5E
-:1037800093A2001000808821250800281444FF76A9
-:103790002529002093A400108FA300142402FFFF0A
-:1037A0001062000A308900FF248200012483000196
-:1037B0003042007F14550005306900FF2403FF806C
-:1037C0000083102400431026304900FF9202007845
-:1037D000305300FF11330032012088213C020800E1
-:1037E0008C4200DC3225007F000520C00005294006
-:1037F00000A42021024210212406FF800044102151
-:1038000000461024AF42002C3C0308008C6300DC0F
-:103810003C0208008C4200E40243182102421021BD
-:103820000045102100641821004610243063007FF9
-:10383000AF420028034318213C02000E00624021E1
-:103840003C0208008C4200E48D06000C010020219F
-:1038500002421021004510213042007F034218210E
-:103860003C02000C0062482110C0000D01202821FC
-:103870000E0006E2000000002402FF80022218244D
-:1038800026240001006228263082007F14550002A1
-:10389000308300FF30A300FF1473FFD00060882145
-:1038A0008E0300743C027FFF3442FFFF0062182445
-:1038B000AE0300740E00070302402021AF5700241E
-:1038C0008FA20030AF5E00288FBF005C8FBE005813
-:1038D0008FB700548FB600508FB5004C8FB400489E
-:1038E0008FB300448FB200408FB1003C8FB00038DE
-:1038F00027BD006003E00008AF42002C27BDFFD8C1
-:10390000AFB1001CAFBF0020AFB000182751018835
-:10391000922200032408FF803C03000A3047007F06
-:10392000A3A700108F4601803C0208008C4200E0F3
-:10393000AF86003400C2282100A81024AF42002422
-:103940009224000030A2007F034210210043102186
-:10395000AF8200283084007F2402000214820025F8
-:10396000000719403C0208008C4200E400C210210C
-:103970000043282130A2007F0342182100A8102410
-:10398000AF4200283C02000C006218219062000D3A
-:10399000AFA3001400481025A062000D8FA30014EF
-:1039A0009062000D304200405040006A8FBF0020FE
-:1039B0008F860028A380002C27A400148CC200D876
-:1039C0008C63000427A50010004310210E000A7923
-:1039D000ACC200D893A300108F8200280E0006BE50
-:1039E000A04300D10E000C00000000000A000EA34E
-:1039F0008FBF00200E0006C700C020210E0006D594
-:103A0000000000003C0200080342802192230001D4
-:103A10009202007B1443004F8FBF002092220000CF
-:103A20003044007F24020004108200172882000521
-:103A30001040000624020005240200031082000743
-:103A40008FB1001C0A000EA40000000010820012BA
-:103A50008FBF00200A000EA48FB1001C92050083C6
-:103A6000920600788E0700748F84003430A500FF22
-:103A700000073E0230C600FF0E00070B30E7007F54
-:103A80000A000EA38FBF00200E000C6F8F8400343D
-:103A90000A000EA38FBF002024020C80AF42002436
-:103AA0009202003E30420040104000200000000022
-:103AB0009202003E000216000002160304410006B6
-:103AC000000000008F8400340E00063824050093A7
-:103AD0000A000EA38FBF00209202003F24030018AB
-:103AE000304200FF1443000C8F8400342405003959
-:103AF0000E0005D0000030210E0003028F84003438
-:103B000024020012A202003F0E00030B8F84003437
-:103B10000A000EA38FBF0020240500360E0005D03A
-:103B2000000030210A000EA38FBF00200E00030208
-:103B30008F8400349202000534420020A202000566
-:103B40000E00030B8F8400340E0010588F84003455
-:103B50008FBF00208FB1001C8FB0001824020C8092
-:103B600027BD002803E00008AF42002427BDFFE87E
-:103B7000AFB00010AFBF00142743010094620008EB
-:103B8000000214000002140304410002000080211E
-:103B90002410000194620008304200801040001A96
-:103BA00002001021946200083042200010400016EC
-:103BB000020010218C6300183C021C2D344219EDC8
-:103BC000240600061062000F3C0760213C0208003A
-:103BD0008C4200D4104000078F8200288F83002879
-:103BE000906200623042000F34420040A0620062E6
-:103BF0008F8200288F840034944500D40E000B89F6
-:103C000030A5FFFF020010218FBF00148FB00010FD
-:103C100003E0000827BD001827BDFFE0AFB1001486
-:103C2000AFB00010A380002CAFBF00188F4501007B
-:103C30003C0308008C6300E02402FF80AF85003461
-:103C400000A318213064007F03442021006218245F
-:103C50003C02000A00822021AF43002427500100CB
-:103C60008E0200148C8300DCAF84002800431023F4
-:103C700018400004000088218E0200140E000B1C66
-:103C8000AC8200DC9202000B24030002304200FFF1
-:103C90001443002F0000000096020008304300FF8C
-:103CA0002402008214620005240200840E0009D65A
-:103CB000000000000A000F2F00000000146200093D
-:103CC000240200818F8200288F8400343C07602109
-:103CD000944500D49206000530A5FFFF0A000F1E90
-:103CE00030C600FF14620027000000009202000AA4
-:103CF000304300FF3062002010400004306200407A
-:103D00008F8400340A000F1A24060040104000047B
-:103D1000000316008F8400340A000F1A24060041A5
-:103D200000021603044100178F8400342406004269
-:103D30008F8200283C076019944500D430A5FFFF0E
-:103D40000E000B89000000000A000F2F0000000089
-:103D50009202000B24030016304200FF10430006BD
-:103D6000000000009202000B24030017304200FF05
-:103D700014430004000000000E000EA90000000023
-:103D8000004088210E000C00000000009202000A92
-:103D9000304200081040000624020C808F85002865
-:103DA0003C0400080E0012860344202124020C80EB
-:103DB000AF4200248FBF0018022010218FB00010E6
-:103DC0008FB1001403E0000827BD002027BDFFE8E5
-:103DD000AFBF0014AFB000108F5000243C030800A8
-:103DE0008C6300E08F4501002402FF8000A31821AE
-:103DF0003064007F03442021006218243C02000A42
-:103E000000822021AF850034AF43002490820062FD
-:103E1000AF8400283042000F34420050A08200627C
-:103E20003C02001F3442FF800E0006BE02028024C6
-:103E3000AF5000248FBF00148FB0001003E00008C3
-:103E400027BD00183C0208008C4200201040001DD5
-:103E50002745010090A300093C02000803422021ED
-:103E600024020018546200033C0200080A000F708C
-:103E700024020008034220212402001614620005D7
-:103E80002402001724020012A082003F0A000F7AC9
-:103E900094A700085462000694A7000893620005E6
-:103EA0002403FFFE00431024A362000594A700082A
-:103EB00090A6001B8CA4000094A500060A000B64C9
-:103EC00000073C0003E00008000000002744010058
-:103ED00094820008304500FF38A3008238A2008495
-:103EE0002C6300012C4200010062182510600006BE
-:103EF000240200839382002D1040000D000000007A
-:103F00000A000C330000000014A2000524A2FF8068
-:103F10008F4301043C02602003E00008AC4300141E
-:103F2000304200FF2C420002104000032402002215
-:103F30000A000ED40000000014A2000300000000DC
-:103F40000A000F41000000000A000F5F000000009F
-:103F50009363007E9362007A1443000900002021DD
-:103F60009362000024030050304200FF1443000419
-:103F7000240400019362007E24420001A362007EBB
-:103F800003E00008008010218F4201F80440FFFE8A
-:103F900024020002AF4401C0A34201C43C0210004D
-:103FA00003E00008AF4201F827BDFFE8AFBF0010F3
-:103FB0009362003F2403000A304200FF144300468E
-:103FC000000000008F6300548F62004C1062007D7F
-:103FD000036030219362000024030050304200FF50
-:103FE0001443002F000000008F4401403C020800F1
-:103FF0008C4200E02403FF80008210210043102443
-:10400000AF4200243C0208008C4200E08F6500545F
-:104010003C03000A008220213084007F03441021E9
-:1040200000431021AC4501089762003C8F63004CAF
-:104030003042FFFF0002104000621821AF63005CB5
-:104040008F6300548F64004C9762003C0064182317
-:104050003042FFFF00031843000210400043102AC3
-:1040600010400006000000008F6200548F63004C77
-:10407000004310230A000FF0000210439762003C37
-:104080003042FFFF00021040ACC200642402000175
-:10409000A0C0007CA0C2008424020C80AF42002497
-:1040A0000E000FA28F440140104000478FBF001048
-:1040B0008F4301408F4201F80440FFFE24020002BA
-:1040C000AF4301C0A34201C43C021000AF4201F85B
-:1040D0000A0010408FBF00109362003F24030010BD
-:1040E000304200FF14430004000000008F440140F0
-:1040F0000A00102C000028219362003F24030016C0
-:10410000304200FF1443000424020014A362003F65
-:104110000A00103A000000008F62004C8F630050CC
-:1041200000431023044100288FBF001093620081D8
-:1041300024420001A3620081936200812C420004AA
-:1041400014400010000000009362003F24030004AC
-:10415000304200FF14430006000000008F4401407D
-:104160008FBF0010240500930A00063827BD0018F1
-:104170008F440140240500938FBF00100A0006A75A
-:1041800027BD00188F4401400E000302000000000C
-:104190008F6200542442FFFFAF6200548F620050D0
-:1041A0002442FFFFAF6200500E00030B8F4401401A
-:1041B0008F4401408FBF0010240500040A00031043
-:1041C00027BD00188FBF001003E0000827BD0018AE
-:1041D0008F4201889363007E00021402304400FF86
-:1041E000306300FF1464000D000000009362008043
-:1041F000304200FF1044000900000000A36400806A
-:104200009362000024030050304200FF1443000476
-:10421000000000000A00076F8F440180A364008043
-:1042200003E000080000000027BDFFE8AFB0001069
-:10423000AFBF001493620005240300303042003009
-:1042400014430089008080213C0208008C42002039
-:1042500010400080020020210E00052B000000000D
-:104260008F850020ACB000009362003E9363003F56
-:10427000304200FF00021200306300FF00431025AF
-:10428000ACA2000493620082000216000002160332
-:1042900004410005000000003C0308008C63004856
-:1042A0000A00107E000000009362003E3042004091
-:1042B000144000030000182193620081304300FF86
-:1042C0009362008200031E00304200FF00021400CF
-:1042D00000621825ACA300088F620040ACA2000C5D
-:1042E0008F620048ACA200108F62004CACA2001498
-:1042F0008F6200508F63004C004310230441000381
-:10430000000000000A0010928F62004C8F62005083
-:10431000ACA200183C02080094424DBE3C03C00B06
-:1043200000002021004310250E000550ACA2001C07
-:104330008F6200548F840020AC8200008F6200588E
-:10434000AC8200048F62005CAC8200088F62006067
-:104350008F43007400431021AC82000C8F62006414
-:10436000AC820010976300689762006A00031C002B
-:104370003042FFFF00621825AC8300149362008274
-:1043800024030080304200FF1443000300000000BB
-:104390000A0010C6AC8000188F63000C24020001D4
-:1043A0001062000E2402FFFF9362003E3042004084
-:1043B0001440000A2402FFFF8F63000C8F42007438
-:1043C000006218233C02080000621024144000021E
-:1043D000000028210060282100051043AC8200184D
-:1043E0003C02080094424DBE3C03C00C000020215A
-:1043F000004310258F8300200E000550AC62001C86
-:104400008F6200188F8300203C05080094A54DBEE4
-:1044100024040001AC620000AC6000048F66006CF4
-:104420003C02400D00A22825AC6600088F6200DC2B
-:10443000AC62000CAC600010936200050002160034
-:10444000AC620014AC6000180E000550AC65001C96
-:10445000020020218FBF00148FB00010A360000560
-:104460000A0004B927BD00188FBF00148FB00010D8
-:1044700003E0000827BD00189742007C30C600FF0B
-:10448000A08600843047FFFF2402000514C2000B01
-:1044900024E3465090A201122C420007104000076E
-:1044A00024E30A0090A30112240200140062100405
-:1044B00000E210210A0010FE3047FFFF3067FFFFC7
-:1044C00003E00008A4870014AC87004C8CA201080C
-:1044D0000080402100A0482100E2102330C600FFE8
-:1044E0001840000393AA001324E2FFFCACA20108C9
-:1044F00030C2000110400008000000008D02005092
-:1045000000E2102304410013240600058D0200542C
-:1045100010E20010000000008D02005414E2001AA6
-:10452000000000003C0208008C4200D8304200200D
-:104530001040000A240200019103007891020083D8
-:10454000144300062402000101002021012028213B
-:10455000240600040A0010EC00000000A100008402
-:1045600011400009A50200148F4301008F4201F899
-:104570000440FFFE24020002AF4301C0A34201C475
-:104580003C021000AF4201F803E000080000000008
-:1045900027BDFFE88FA90028AFBF00100080402191
-:1045A00000E918231860007330C600FFA080007C6B
-:1045B000A08000818CA2010800E210230440004D7D
-:1045C000000000008C8200509483003C8C840064C6
-:1045D000004748233063FFFF012318210083202B6D
-:1045E00010800004000000008D0200640A00114FDA
-:1045F00000E210219502003C3042FFFF0122102111
-:1046000000E21021AD02005C9502003C8D03005CCD
-:104610003042FFFF0002104000E210210043102B47
-:1046200010400003000000000A00115E8D02005CD3
-:104630009502003C3042FFFF0002104000E21021D2
-:10464000AD02005CA1000084AD07004C8CA2010803
-:1046500000E210231840000224E2FFFCACA2010893
-:1046600030C200011040000A000000008D0200501E
-:1046700000E2102304410004010020218D020054B7
-:1046800014E20003000000000A0011802406000567
-:104690008D02005414E200478FBF00103C02080056
-:1046A0008C4200D8304200201040000A2402000151
-:1046B0009103007891020083144300062402000154
-:1046C00001002021240600048FBF00100A0010EC16
-:1046D00027BD0018A1000084A50200148F4301002B
-:1046E0008F4201F80440FFFE240200020A0011A5D7
-:1046F000000000008C82005C004910230043102B56
-:1047000054400001AC87005C9502003C3042FFFF42
-:104710000062102B14400007240200029502003CA6
-:104720008D03005C3042FFFF00621821AD03005C86
-:1047300024020002AD07004CA10200840E000FA26B
-:104740008F4401001040001B8FBF00108F430100F9
-:104750008F4201F80440FFFE24020002AF4301C073
-:10476000A34201C43C021000AF4201F80A0011BB91
-:104770008FBF001030C200101040000E8FBF00101D
-:104780008C83005C9482003C006918233042FFFF58
-:10479000006218213C023FFF3444FFFF0083102BCE
-:1047A000544000010080182101231021AD02005C5B
-:1047B0008FBF001003E0000827BD001827BDFFE8E9
-:1047C0008FAA0028AFBF00100080402100EA4823D4
-:1047D0001920002130C600FF8C83005C8C820064AD
-:1047E000006A18230043102B504000100069182164
-:1047F00094A2011001221021A4A2011094A2011080
-:104800003042FFFF0043102B1440000A3C023FFFE0
-:1048100094A2011000431023A4A201109482003C32
-:104820003042FFFF0A0011DA00621821A4A0011033
-:104830003C023FFF3444FFFF0083102B5440000133
-:104840000080182100671021AD02005CA100007CEF
-:104850000A001222A100008130C200101040003C6A
-:10486000000000008C820050004A102318400038DD
-:10487000000000009082007C24420001A082007CA5
-:104880009082007C3C0308008C630024304200FFCF
-:104890000043102B1440005C8FBF00108CA2010855
-:1048A00000E2102318400058000000008C830054E0
-:1048B0009482003C006A18233042FFFF0003184333
-:1048C000000210400043102A1040000500000000C4
-:1048D0008C820054004A10230A001209000210437F
-:1048E0009482003C3042FFFF00021040AD020064A1
-:1048F0009502003C8D0400649503003C3042FFFFAC
-:1049000000021040008220213063FFFF0083182145
-:1049100001431021AD02005C8D020054ACA20108DD
-:1049200024020002A10200840E000FA28F440100A5
-:10493000104000358FBF00108F4301008F4201F8F7
-:104940000440FFFE240200020A00124B0000000097
-:10495000AD07004C8CA2010800E2102318400002B1
-:1049600024E2FFFCACA2010830C200011040000AA2
-:10497000000000008D02005000E2102304410004FA
-:10498000010020218D02005414E200030000000009
-:104990000A001242240600058D02005414E2001A97
-:1049A0008FBF00103C0208008C4200D8304200202B
-:1049B0001040000A24020001910300789102008354
-:1049C00014430006240200010100202124060004F3
-:1049D0008FBF00100A0010EC27BD0018A100008452
-:1049E000A50200148F4301008F4201F80440FFFE2E
-:1049F00024020002AF4301C0A34201C43C021000E4
-:104A0000AF4201F88FBF001003E0000827BD001877
-:104A10008FAA00108C8200500080402130C600FF19
-:104A2000004A102300A048211840000700E0182188
-:104A300024020001A0800084A0A00112A48200141E
-:104A40000A0011BDAFAA0010A0800081AD07004C84
-:104A50008CA2010800E210231840000224E2FFFCAF
-:104A6000ACA2010830C200011040000800000000A4
-:104A70008D0200500062102304410013240600053B
-:104A80008D02005410620010000000008D020054DE
-:104A900014620011000000003C0208008C4200D8A3
-:104AA000304200201040000A2402000191030078E7
-:104AB000910200831443000624020001010020211A
-:104AC00001202821240600040A0010EC0000000048
-:104AD000A1000084A502001403E00008000000000B
-:104AE00027BDFFE0AFBF0018274201009046000A33
-:104AF0008C4800148C8B004C9082008430C900FFDD
-:104B000001681823304A00FF1C60001A2D46000679
-:104B1000240200010142100410C0001630430003BB
-:104B2000012030210100382114600007304C000CB6
-:104B300015800009304200301440000B8FBF001870
-:104B40000A0012AC000000000E0011BDAFAB001057
-:104B50000A0012AC8FBF00180E001132AFAB00106C
-:104B60000A0012AC8FBF0018AFAB00100E0012523B
-:104B7000AFAA00148FBF001803E0000827BD002073
-:104B800024020003A08200848C82005403E0000809
-:104B9000ACA201083C020008034218219062008187
-:104BA000240600433C07601924420001A0620081F2
-:104BB000906300813C0208008C4200C0306300FF1B
-:104BC000146200102403FF803C0208008C4200E0C5
-:104BD0000082102100431024AF4200243C02080050
-:104BE0008C4200E03C03000A008210213042007F2A
-:104BF0000342102100431021944500D40A000B8980
-:104C000030A5FFFF03E000080000000027BDFFE023
-:104C1000AFBF0018AFB10014AFB000108F420180D9
-:104C20000080802100A088210E0012B300402021C6
-:104C3000A20000848E0200548FBF00188FB00010B5
-:104C4000AE2201088FB1001403E0000827BD002048
-:104C500027BDFFE03C020008AFB00010AFBF001856
-:104C6000AFB10014034280218F51014092030084B0
-:104C70008E0400508E02004C14820040306600FF0B
-:104C80003C0208008C4200E02403FF800222102135
-:104C900000431024AF4200243C0208008C4200E094
-:104CA0009744007C92050081022210213042007F4F
-:104CB000034218213C02000A0062182114A0000BD4
-:104CC0003084FFFF2402000554C20014248205DC56
-:104CD0009062011224420001A062011224020C80A1
-:104CE000AF4200240A00130B24020005A060011249
-:104CF0002402000514C20009248205DC920200810E
-:104D00002C4200075040000524820A0092030081D3
-:104D10002402001400621004008210213044FFFFBE
-:104D2000A60400140E0012B3022020219602003CBB
-:104D30008E03004C022020213042FFFF0002104071
-:104D4000006218210E000302AE03005C9202007D97
-:104D500002202021344200400E00030BA202007DFD
-:104D60008F4201F80440FFFE24020002AF5101C04F
-:104D7000A34201C43C021000AF4201F88FBF0018EB
-:104D80008FB100148FB0001003E0000827BD002091
-:104D900008000D9808000DE008000E2008000E6CB9
-:044DA00008000EA059
-:0C4DA4000A0000220000000000000000D7
-:104DB0000000000D6370352E302E306A3600000082
-:104DC00005000004000000000000000000000000DA
-:104DD00000000000000000000000000000000000D3
-:104DE00000000000000000000000000000000020A3
-:104DF00000000000000000000000000000000000B3
-:104E000000000000000000000000000000000000A2
-:104E10000000000000000000000000000000000191
-:104E20000000002B00000000000000000000000057
-:104E300010000003000000000000000D0000000D45
-:104E40003C02080024425AC43C03080024636190D9
-:104E5000AC4000000043202B1480FFFD24420004DE
-:104E60003C1D080037BD7FFC03A0F0213C1008006A
-:104E7000261000883C1C0800279C5AC40E0001A67E
-:104E8000000000000000000D27BDFFE83C0960188D
-:104E9000AFBF00108D2C5000240DFF7F240800317F
-:104EA000018D5824356A380C24070C003C1A800008
-:104EB000AD2A50003C04800AAF4800083C1B800823
-:104EC000AF4700240E000935AF8400100E0008F82B
-:104ED000000000000E000845000000000E0012DC7B
-:104EE000000000003C0460168C8500003C06FFFFBB
-:104EF0003C02535300A618241062004734867C00FD
-:104F000094C201F2A780002C10400003A78000CCBF
-:104F100038581E1EA798002C94C201F810400004B7
-:104F2000978300CC38591E1EA79900CC978300CCDC
-:104F30002C7F006753E00001240300669784002C57
-:104F40002C82040114400002006028212404040083
-:104F50003C0760008CE904382403103C3128FFFF33
-:104F60001103001F30B9FFFF57200010A38000CEAF
-:104F700024020050A38200CE939F00CE53E0000F86
-:104F8000A78500CCA78000CC978500CC8FBF0010F0
-:104F9000A780002CA7800034A78000E63C01080011
-:104FA000AC25008003E0000827BD0018939F00CEC9
-:104FB00057E0FFF5A78000CCA78500CC978500CCF3
-:104FC0008FBF0010A784002CA7800034A78000E6C4
-:104FD0003C010800AC25008003E0000827BD001854
-:104FE000A38000CE8CCB003C316A00011140000E42
-:104FF0000000000030A7FFFF10E0FFDE2402005099
-:105000008CCC00C83186000114C0FFDC939F00CE19
-:105010000A000074240200518C8F00043C0E6000D2
-:105020000A00005701EE30218CEF0808240D5708C4
-:10503000000F740211CD000430B8FFFF2405006694
-:105040000A000075240404001700FFCC939F00CED3
-:105050000A000074240200508F8600103089FFFF80
-:10506000000939408CC300103C08005000E820259E
-:10507000AF4300388CC5001427420400AF82001CE7
-:10508000AF45003CAF4400300000000000000000CD
-:105090000000000000000000000000000000000010
-:1050A00000000000000000008F4B0000316A00206B
-:1050B0001140FFFD0000000003E0000800000000B8
-:1050C0008F840010948A001A8C8700243149FFFFD6
-:1050D000000940C000E83021AF46003C8C85002428
-:1050E0008F43003C00A3102318400029000000005B
-:1050F0008C8B0020256200013C0D005035AC00086F
-:10510000AF420038AF4C003000000000000000004B
-:10511000000000000000000000000000000000008F
-:1051200000000000000000008F4F000031EE002062
-:1051300011C0FFFD000000008F4A04003C08002061
-:10514000AC8A00108F490404AC890014AF480030C9
-:1051500000000000948600189487001C00C71821E6
-:10516000A48300189485001A24A20001A482001AC6
-:105170009498001A9499001E133800030000000050
-:1051800003E000080000000003E00008A480001A0B
-:105190008C8200200A0000D63C0D00500A0000C797
-:1051A000000000003C0308008C6300208F82001880
-:1051B00027BDFFE810620008AFBF00100E0000FE20
-:1051C000AF8300183C0308008C6300202404000116
-:1051D000106400048F8900108FBF001003E00008E6
-:1051E00027BD00188FBF00103C076012A520000AE1
-:1051F0009528000A34E5001027BD00183106FFFF8E
-:1052000003E00008ACA600903C0208008C4200209D
-:1052100027BDFFC8AFBF0034AFBE0030AFB7002C12
-:10522000AFB60028AFB50024AFB40020AFB3001C68
-:10523000AFB20018AFB1001410400050AFB0001072
-:105240008F840010948600069483000A00C32823EC
-:1052500030B6FFFF12C0004A8FBF00349489001897
-:10526000948A000A012A40233102FFFF02C2382B30
-:1052700014E0000202C02021004020212C8C0005F7
-:10528000158000020080A021241400040E0000AD4F
-:10529000028020218F87001002809821AF800014A7
-:1052A00094ED000A028088211280004E31B2FFFF87
-:1052B0003C1770003C1540003C1E60008F8F001CA6
-:1052C0008DEE000001D718245075005002202021D7
-:1052D00002A3802B160000353C18200050780047B0
-:1052E00002202021241000018F8300141460003953
-:1052F000029158230230F8230250C82133F1FFFFF6
-:105300001620FFEE3332FFFF8F8700103C11002084
-:10531000AF5100300000000094E6000A3C1E60120D
-:1053200037D5001002662821A4E5000A94E2000A9D
-:1053300094F2000A94F400183057FFFF1292003BD9
-:10534000AEB700908CED00148CE400100013714097
-:1053500001AE4021000E5FC3010E502B008B48218F
-:10536000012A1821ACE80014ACE3001002D3382362
-:1053700030F6FFFF16C0FFB98F8400108FBF0034D6
-:105380008FBE00308FB7002C8FB600288FB5002459
-:105390008FB400208FB3001C8FB200188FB100149F
-:1053A0008FB0001003E0000827BD0038107E001BFE
-:1053B000000000001477FFCC241000010E00162717
-:1053C000000000008F8300141060FFCB0230F82330
-:1053D000029158238F870010017020210A0001914B
-:1053E0003093FFFF8F8300141460FFCB3C1100202B
-:1053F000AF5100300A00015D000000000E00079E62
-:10540000024028210A000151004080210E00034B78
-:10541000024028210A000151004080210E0014EFB3
-:10542000022020210A000151004080210E0000C707
-:10543000000000000A00017302D3382327BDFFE8F3
-:10544000AFB00010AFBF00140E0000390000000024
-:105450003C028000345000700A0001B48E06000047
-:105460008F4F000039EE000131C2000110400024CE
-:105470008F8600A88E0700003C0C08008D8C003C35
-:105480003C0908008D29003800E66823018D282199
-:105490000000502100AD302B012A402101062021BF
-:1054A0003C010800AC25003CAF8700A83C01080087
-:1054B000AC2400380E000100000000003C0308008E
-:1054C0008C6300701060FFE6006020213C0508003E
-:1054D0008CA500683C0608008CC6006C0E0015B652
-:1054E000000000003C010800AC2000708F4F00005D
-:1054F00039EE000131C200011440FFDE8F8600A8A2
-:105500008E0A00008F8B00A83C0508008CA5003C8B
-:105510003C0408008C840038014B482300A9382142
-:105520000082182100E9402B006810213C0108008E
-:10553000AC27003C3C010800AC2200388F5F010022
-:105540002419FF0024180C0003F9202410980012DD
-:10555000AF840000AF440020936D0000240C0020B5
-:1055600031A600FF10CC0012240E005010CE000413
-:105570003C194000AF5901380A0001AD000000009D
-:105580000E001252000000003C194000AF590138D3
-:105590000A0001AD000000000E000119000000002B
-:1055A0003C194000AF5901380A0001AD000000006D
-:1055B0008F58010000802821330F00FF01E02021D7
-:1055C0000E0002F8AF8F00043C194000AF590138BB
-:1055D0000A0001AD0000000000A4102B240300010C
-:1055E00010400009000030210005284000A4102BC5
-:1055F00004A00003000318405440FFFC00052840AD
-:105600005060000A0004182B0085382B54E0000479
-:105610000003184200C330250085202300031842F0
-:105620001460FFF9000528420004182B03E000086D
-:1056300000C310213084FFFF30A5FFFF8F4201B867
-:105640000440FFFE3C074080008730253C031000EB
-:10565000AF400180AF450184AF46018803E00008F8
-:10566000AF4301B83084FFFF8F4201B80440FFFE12
-:105670003C0740388CA60000008728253C0310001A
-:10568000AF460180AF45018803E00008AF4301B891
-:105690008F8300388F8600301066000B0080402119
-:1056A0003C07080024E75C38000328C000A710214D
-:1056B0008C44000024630001108800053063000F53
-:1056C0005466FFFA000328C003E000080000102120
-:1056D0003C07080024E75C3C00A7302103E00008F9
-:1056E0008CC200003C03900034620001008220253F
-:1056F000AF4400208F45002004A0FFFE0000000002
-:1057000003E00008000000003C0380003462000158
-:105710000082202503E00008AF44002027BDFFE001
-:10572000AFB100143091FFFFAFB00010AFBF001851
-:105730001220001500A080218CA5000010A00013ED
-:10574000240400020E000C7C24060140AE00000080
-:105750008F4201B80440000D000028213C064000A3
-:10576000022620258FBF00188FB100148FB00010C3
-:105770003C03100027BD0020AF450180AF440188E5
-:1057800003E00008AF4301B88CA500008F4201B8C8
-:105790000440FFFE3C064000022620258FBF001873
-:1057A0008FB100148FB000103C03100027BD002003
-:1057B000AF450180AF44018803E00008AF4301B862
-:1057C0003086FFFF8F4201B80440FFFE3C094006CF
-:1057D0008CA8000000C93825AF4801808CA40004C3
-:1057E0003C031000AF440184AF47018803E0000888
-:1057F000AF4301B827BDFFE0AFB00010AFBF001846
-:10580000AFB100149363003E008080210080282106
-:1058100030620040000020211040000F8E11000077
-:105820000E0008710220202193670000240400501C
-:1058300030E500FF50A400128E0F0000022020214E
-:105840008FBF00188FB100148FB00010A762013C09
-:105850000A00093127BD00200E0002870000000069
-:105860000E000871022020219367000024040050DC
-:1058700030E500FF14A4FFF2022020218E0F00006B
-:105880003C1008008E1000503C0D000C240BFF80D3
-:1058900001F05021314E007F01DA6021018D40215D
-:1058A000014B4824AF490028022020218FBF001857
-:1058B0008FB100148FB00010A50200D627BD0020C4
-:1058C0000A000931AF8800D027BDFFE0AFBF001844
-:1058D000AFB10014AFB000109366000100808021CA
-:1058E0000E00025030D1000493640005001029C25C
-:1058F000A765000034830040A36300050E00025931
-:10590000020020210E0009330200202124020001A0
-:10591000AF62000C02002821A762001024040002DC
-:10592000A762001224060140A76200140E000C7C3E
-:10593000A76200161620000F8FBF0018978C003446
-:105940003C0B08008D6B00782588FFFF3109FFFFB5
-:10595000256A0001012A382B10E00006A7880034D0
-:105960003C0F6006240E001635ED0010ADAE005061
-:105970008FBF00188FB100148FB0001003E0000833
-:1059800027BD002027BDFFE0AFB10014AFBF001856
-:10599000AFB0001000A088211080000A3C03600016
-:1059A0002402008010820012000000000000000DA0
-:1059B0008FBF00188FB100148FB0001003E00008F3
-:1059C00027BD00208C682BF80500FFFE00000000BA
-:1059D000AC712BC08FBF00188FB100148FB00010B6
-:1059E0003C09100027BD002003E00008AC692BF83B
-:1059F0000E00025000A02021936500050220202106
-:105A00000E00025930B000FF2403003E1603FFE7EA
-:105A1000000000008F4401780480FFFE2407000787
-:105A20003C061000AF51014002202021A347014451
-:105A30008FBF00188FB100148FB00010AF460178EF
-:105A40000A0002C927BD002027BDFFE8AFBF001430
-:105A5000AFB000108F500020000000000E0009338E
-:105A6000AF440020AF5000208FBF00148FB0001053
-:105A700003E0000827BD00183084FFFF8F4201B803
-:105A80000440FFFE3C074035008730253C031000F2
-:105A9000AF450180AF400184AF46018803E00008B4
-:105AA000AF4301B83084FFFF8F4201B80440FFFECE
-:105AB0003C074036008730253C031000AF4501808D
-:105AC000AF400184AF46018803E00008AF4301B84E
-:105AD00027BDFFD0AFB3001C3093FFFFAFB500244C
-:105AE000AFB20018AFBF0028AFB40020AFB10014B0
-:105AF000AFB0001030B5FFFF12600027000090210A
-:105B00008F90001C8E0300003C06800024020040A1
-:105B100000033E0200032C0230E4007F006688246C
-:105B20001482001D30A500FF8F8300282C68000A16
-:105B3000510000108F910014000358803C0C0800A5
-:105B4000258C58C4016C50218D49000001200008AB
-:105B50000000000002B218213065FFFF0E00022491
-:105B600024040084162000028F90001CAF800028BF
-:105B70008F910014260C0020264B0001018080210B
-:105B80003172FFFF16200004AF8C001C0253282B3B
-:105B900014A0FFDC00000000024010218FBF00288D
-:105BA0008FB500248FB400208FB3001C8FB2001873
-:105BB0008FB100148FB0001003E0000827BD003043
-:105BC000240D003414AD00F600000000920B000E0E
-:105BD000240A16803C07000CA36B00219203000DE1
-:105BE0000347F8213C066000A363002096110012D1
-:105BF0003C057FFF34ACFFFFA771003C960200100C
-:105C0000240B00053054FFFFAF7400848E19001C74
-:105C1000AF4A00288FF800008CCF44480319702643
-:105C200001EE3021AF66004C8F69004C24CD00019D
-:105C30003C197F00AF6900508F640050AF6400547E
-:105C4000AF660070AF6D00588F6800582404005094
-:105C5000AF68005CA3600023AF6C0064A36B0037E7
-:105C60008E030014AF6300488F710048AF710024A9
-:105C70008E020018AF62006C9214000CA374003600
-:105C8000936A003E355F0020A37F003E8F7800744A
-:105C90000319782435EE4000AF6E0074936900005C
-:105CA000313000FF1204022C2418FF803C0408004D
-:105CB00024845CB80E000294000000002406000456
-:105CC000240700013C0408008C845CB8A366007DB6
-:105CD000A36700058F4A01780540FFFE24020002F9
-:105CE000AF440140A34201448F90001C3C141000BB
-:105CF000AF5401780A000373AF8000282CAD003741
-:105D000051A0FF9C8F9100140005A0803C18080052
-:105D1000271858EC029878218DEE000001C0000889
-:105D2000000000002406000614A600110000000078
-:105D30003C1F08008FFF5CB824040005AF5F002003
-:105D40008E190018AF7900188F78004CAF78001CBE
-:105D50008F6F0050122000C2AF6F00700A000373F3
-:105D6000AF840028240A000710AA00842403000638
-:105D70003C05080024A55CB80E00025E24040081E6
-:105D80008F90001C0011102B0A000373AF820028B3
-:105D90002402000414A2FFF6240A00503C09080063
-:105DA0008D295CB8AF4900208E040008AF64004024
-:105DB0008E060008AF6600448E07000CAF670048EF
-:105DC0008E0D0010AF6D004C8E080010AF6800847F
-:105DD0008E050014AF6500508E0C0018AF6C005497
-:105DE0008E0B001CAF6B005893740000328300FFD1
-:105DF000106A01EE000000008F6700488F660040C7
-:105E000000E6682305A000042404008C1620FFDEB1
-:105E100024020003240400823C05080024A55CB889
-:105E20000E000287000000008F90001C000010216F
-:105E30000A000373AF8200282404000514A4FFCCD9
-:105E4000240520003C1F08008FFF5CB8AF5F0020D6
-:105E50008E190004AF79005C921800082410000825
-:105E6000A37800218F8F001C91EE0009A36E002003
-:105E70008F86001C90C9000A312400FF109000108A
-:105E8000288A00091540006C24020002240C00201E
-:105E9000108C000B340580002885002114A0000818
-:105EA0002405400024080040108800053C0500013E
-:105EB000240D0080108D00023C05000224054000E6
-:105EC0008F6E00743C0FFF0001CF48240125802510
-:105ED000AF70007490C4000BA36400818F84001C19
-:105EE0009487000C10E0019400000000948E000CD8
-:105EF000241FFFBF24060004A76E003C9089000EFB
-:105F0000A369003E8F90001C9204000FA364003F21
-:105F10008F94001C8E8D00108F47007401A74023C2
-:105F2000AF6800608E850014AF650064968C001821
-:105F3000A76C0068968B001AA76B006A8E83001C02
-:105F4000AF63006C96820002A762013E928A000E47
-:105F5000A36A003E9379003E033FC02412200167EC
-:105F6000A378003E8F90001C0A000373AF860028C0
-:105F70002414002214B4FF7E240300073C0208000E
-:105F80008C425CB81220000CAF4200200A00037360
-:105F9000AF830028240C003310AC00142405002823
-:105FA0003C05080024A55CB80E00023024040081E2
-:105FB0000A0003F88F90001C3C04080024845CB89D
-:105FC0000E00029400000000936B000024110050AA
-:105FD000316300FF10710151000000008F90001C20
-:105FE000000018210A000373AF8300283C08080052
-:105FF0008D085CB824040081AF480020A3650034FC
-:106000003C05080024A55CB80E000230000000002A
-:106010008F90001C240200090A000373AF8200283D
-:1060200002B288213225FFFF0E00022424040084DE
-:106030000A0003738F90001C1082FFA12405040046
-:10604000288300031060016F240B00042414000156
-:106050005494FF9B240540000A00044724050100D6
-:106060003C04080024845CB88F62004C0E0002944B
-:106070008F6300508F90001C000020210A000373E2
-:10608000AF8400288E1000042404008AAF50002042
-:10609000936E000531C900021520015E020028211F
-:1060A0009378002302002821330F002015E00159C6
-:1060B0002404008D9362003F24190012305F00FF1A
-:1060C00013F90154240400810E0002500200202123
-:1060D00093740023240A0004020020213683004226
-:1060E000A36300230E000259A36A007D8F4B017841
-:1060F0000560FFFE24050002AF500140A3450144A6
-:106100008F90001C3C0C1000AF4C01780A0003F982
-:106110000011102B8E1000042404008AAF500020C0
-:10612000936D000531A80002150000160200282119
-:106130009364003F2407000402002821308600FFFA
-:1061400010C70010240400810E000250020020211C
-:10615000937F002324180012240FFFFE37F900203C
-:10616000A3790023A378003F936E0005020020214D
-:1061700001CF48240E000259A3690005020028211E
-:10618000000020210E000340000000000A0003F878
-:106190008F90001C8E0500043C0F0008034F402127
-:1061A000AF450020910E00002406005031C900FFC9
-:1061B00011260176240400888F5901B80720FFFEBC
-:1061C0003C0C400E008C58253C031000AF4501806C
-:1061D000AF400184AF4B0188AF4301B8910200008A
-:1061E000240AFF8024040004004AF825A11F0000AF
-:1061F0000E000C7C240600300A0003F88F90001C6F
-:106200008E0F00043C14080026945CB83C01080082
-:10621000AC2F5CB8AF4F0020920E000331C90004D0
-:10622000112000022402001224020006A362003F93
-:106230009203001B240AFFC03062003F004AF82589
-:10624000A37F003E92190003333800011700011CA0
-:10625000000000008E020008AE8200083C02080028
-:106260008C425CC01040011B00000000000221C2F3
-:10627000A76400088E0D000C240B000124140014E8
-:10628000AF6D002C8E080010AF6800309605001628
-:10629000A7650038960C0014A76C003AAF6B000C91
-:1062A000A76B0010A76B0012A76B0014A76B00165A
-:1062B00012200146A37400349206000330C7000286
-:1062C0002CF00001260200088F90001C0A000373C6
-:1062D000AF8200288E14000424030081AF540020F4
-:1062E000936800233105001010A001070000000092
-:1062F0008F4401B80480FFFE3C06401F0011382B7C
-:10630000006610253C111000AF540180AF870028B3
-:10631000AF400184AF420188AF5101B80A00037455
-:106320008F9100148E0600043C19000803592021A7
-:10633000AF4600208E07000890980000240F005000
-:10634000331400FF128F0102240500888F4401B826
-:106350000480FFFE3C0D40090011602B00AD1025AC
-:106360003C111000AF460180AF8C0028AF4701847C
-:10637000AF420188AF5101B80A0003748F91001435
-:106380008E04001C0E00023B00000000104000E8DC
-:10639000004048218F90001C240500898F4D01B8D2
-:1063A00005A0FFFE00000000AF4901808E0F001C19
-:1063B0003C1440010011702B00B448253C11100022
-:1063C000AF4F0184AF8E0028AF490188AF5101B8AB
-:1063D0000A0003748F910014961900023C140800FF
-:1063E00026945CB8333800041300008E3C02600031
-:1063F0008E1F001C3C010800AC3F5CB8AF5F002062
-:10640000920C0010240B0014318400FF148B00B890
-:106410000000000096090002312D000115A0014E78
-:10642000000000008E020004AE8200083C0E08004E
-:106430008DCE5CC011C00144000000008F69007463
-:106440003C0E800024040001012E6825AF6D00740D
-:10645000A3600005AF64000C3C0C08008D8C5CC090
-:106460008F88001CA7640010000C59C2A76400129A
-:10647000A7640014A7640016A76B00088D0300082A
-:1064800024040002AF63002C8D0A000CAF6A0030B8
-:1064900091070010A36700348F82001C9045001103
-:1064A000A36500358F86001C90D00012A3700036C3
-:1064B0008F9F001C93F90013A37900378F90001C65
-:1064C00096180014A778003896140016A774003A9E
-:1064D0008E0F0018AF6F00245620FDA5AF84002852
-:1064E0003C05080024A55CB80E00025E00002021D7
-:1064F0008F90001C0A0004B6000020213C05080013
-:1065000024A55CB80E000287240400828F90001C32
-:10651000000030210A000373AF8600283C04080005
-:106520008C845CB80E001574000000008F90001C75
-:106530000A000490000018213C05080024A55CB85E
-:106540000E0002872404008B8F90001C0011302B5A
-:106550000A000373AF8600283C1908008F395CB825
-:106560003C1F08008FFF005024CCFFFE033F782122
-:1065700001F87024AF4E00283C0408008C845CB8FD
-:106580003C0908008D2900500089682131A8007F4E
-:10659000011A282100A78021AE0600D8AF9000D0B4
-:1065A000AE0000DC0A0003C2AE0C0108AF6000843C
-:1065B0003C0508008CA55CB83C0808008D0800501C
-:1065C000240CFF803C02000C00A8A021028C58245F
-:1065D000AF4B00288E1F00143283007F007A5021B9
-:1065E00001427021ADDF00D88E190014AF8E00D0AB
-:1065F000ADD900DC8E180010270FFFFE0A0004152D
-:10660000ADCF0108548BFE2E240540000A0004473C
-:10661000240510000E000335000000000A0003F8F6
-:106620008F90001C8C46442C3C056C6234B0797011
-:106630003C010800AC205CB814D00008240400021F
-:1066400097880034978A002C02802821010A382B71
-:1066500010E0001124040092240400020E000C9AA1
-:10666000240501403C010800AC225CB8AF42002088
-:106670003C0308008C635CB81060000524040083B0
-:106680000E0008650000000010400009240400838B
-:106690003C05080024A55CB80E00025E0000000066
-:1066A0008F90001C0011202B0A000373AF84002878
-:1066B0000E000869000000000A0005978F90001C7A
-:1066C0008E0400080E00023B000000000A00052EA8
-:1066D000AE8200083C05080024A55CB80E0002301C
-:1066E000240400878F90001C0A00054A0011102B1B
-:1066F0000E00086D000000003C05080024A55CB8F1
-:106700000A00063D2404008B0E0002500280202166
-:106710009370002302802021360D00100E000259D4
-:10672000A36D00238F90001C0A0005530000182160
-:10673000240400040E000C9A240500301440002AA2
-:10674000004048218F90001C0A00057E240500832C
-:106750009205000C30BF000113E0000300000000B0
-:106760009602000EA482002C920A000C314800020E
-:106770001100FEF600002821960B00128E03001473
-:10678000A48B001A0A00056AAC83001C8F830038B2
-:106790008F8700301067FE88000020213C09080028
-:1067A00025295C3C000320C0008930218CD40000E6
-:1067B0001285005E247800013303000F5467FFFA4E
-:1067C000000320C00A000505000020213C05080048
-:1067D00024A55CB80E000287240400828F90001C60
-:1067E0000A00054A000010213C0B0008034B202141
-:1067F00024030050240A0001AF420020A0830000BF
-:10680000A08A00018F88001C91070004A08700184F
-:106810008F82001C90450005A08500198F86001C02
-:1068200090DF0006A09F001A8F99001C9338000784
-:10683000A098001B8F94001C928F0008A08F001C52
-:106840008F90001C920E0009A08E001D8F8D001CE1
-:1068500091AC000AA08C001E8F8B001C3C0C080021
-:10686000258C5C3C9163000B3C0B0800256B5C386D
-:10687000A083001F8F8A001C9148000CA088002074
-:106880008F87001C90E5000DA08500218F82001CE1
-:10689000240546469046000EA08600228F9F001CCD
-:1068A00093F9000FA09900238F98001C93140010F7
-:1068B000A09400248F8F001C91F00011A09000255F
-:1068C0008F90001C8F8E00308F990038960D001429
-:1068D000000E18C025C80001A48D0028960A0016D5
-:1068E000006C3021006BF821A48A002A960700185A
-:1068F0003108000FA487002CA485002E8E02001CF6
-:10690000ACC90000AF88003011190003AFE20000ED
-:106910000A00057E00002821250C00013184000FAB
-:10692000000028210A00057EAF8400383C070800DB
-:1069300024E75C380087802100002021ACC00000E3
-:106940000A000505AE0000003C05080024A55CB85F
-:106950000A00063D240400878E0400040E00023B5A
-:10696000000000000A0005A2AE8200083084FFFF8C
-:1069700030C600FF8F4201B80440FFFE000644000D
-:10698000010430253C07200000C720253C031000EF
-:10699000AF400180AF450184AF44018803E00008A7
-:1069A000AF4301B827BDFFE8AFB00010AFBF001480
-:1069B0003C076000240600021080000600A0802131
-:1069C0000010102B8FBF00148FB0001003E00008E0
-:1069D00027BD00183C09600EAD2000348CE5201C5A
-:1069E0008F82001C2408FFFC00A81824ACE3201CA4
-:1069F0000E0006F28C45000C0010102B8FBF001407
-:106A00008FB0001003E0000827BD00183C02600EA4
-:106A10003447010024090018274A04000000000040
-:106A200000000000000000003C06005034C30200DB
-:106A3000AF440038AF45003CAF430030014018215F
-:106A40008F4B0000316800201100FFFD2406007FFD
-:106A50002408FFFF8C6C000024C6FFFF24630004A1
-:106A6000ACEC000014C8FFFB24E7000400000000A9
-:106A700000000000000000003C0F0020AF4F00307D
-:106A80000000000024AD020001A5702B2529FFFFA6
-:106A9000008E20211520FFE101A0282103E000083D
-:106AA0000000000027BDFFE0AFB10014AFBF001829
-:106AB000AFB000103C05600E8CA20034008088212D
-:106AC000144000063C0460008C87201C2408FFFC56
-:106AD00000E8302434C30001AC83201C8F8B001CE1
-:106AE00024090001ACA90034956900028D650014E9
-:106AF0008D70000C2D2400818D6700048D660008C8
-:106B0000108000078D6A00102D2C00041580000EE7
-:106B100030CE0007312D000311A0000B0000000053
-:106B20002404008B020028210E0006F22406000334
-:106B30000011102B8FBF00188FB100148FB0001000
-:106B400003E0000827BD002015C0FFF62404008BD9
-:106B50003C030020AF43003000000000240200018D
-:106B6000AF820014000000000000000000000000E0
-:106B70003C1F0150013FC825253800033C0F600E23
-:106B8000AF47003800181882AF46003C35E8003C9B
-:106B9000AF590030274704008F44000030860020A2
-:106BA00010C0FFFD00000000106000082466FFFF19
-:106BB0002403FFFF8CEB000024C6FFFF24E7000442
-:106BC000AD0B000014C3FFFB250800043C08600E59
-:106BD000AD090038000000000000000000000000C7
-:106BE0003C070020AF470030000000000E00071AED
-:106BF0000140202102002821000020210E0006F281
-:106C0000240600030011102B8FBF00188FB1001451
-:106C10008FB0001003E0000827BD002027BDFFD87B
-:106C2000AFB200183092FFFFAFB10014AFBF002029
-:106C3000AFB3001CAFB000101240002C0000882140
-:106C40000A0007B22413000150B300408CE5000C89
-:106C50000000000D263900013331FFFF24F8002029
-:106C60000232382B10E00021AF98001C8F820014F4
-:106C70001440001E8F87001C3C0670003C0320005F
-:106C80008CE400000086282414A300188F85003CA3
-:106C9000000444023C0980000089802414A0FFEA1B
-:106CA000310600FF240A000210CA002E28CB000380
-:106CB00011600016240C000314D3FFE726390001ED
-:106CC000020028210E000700240400018F87001C09
-:106CD000AF82003C263900013331FFFF24F8002049
-:106CE0000232382B14E0FFE1AF98001C0220102183
-:106CF0008FBF00208FB3001C8FB200188FB100141B
-:106D00008FB0001003E0000827BD002810CC001A47
-:106D1000240D000414CDFFD026390001308EFFFF72
-:106D2000000E19C08F4401B80480FFFE3C0F100014
-:106D30003C102004AF430180AF400184AF50018874
-:106D4000AF4F01B80A0007AD263900010E0006F268
-:106D5000240400841600FFBF8F87001C0A0007ACC4
-:106D6000AF80003C020028210E0007000000202117
-:106D70000A0007CB8F87001C0E000740020020216D
-:106D80008F87001C0A0007CCAF82003C3082FFFFD7
-:106D90001440000300001821000424022403001002
-:106DA000308500FF14A000053087000F246600081E
-:106DB0000004220230C300FF3087000F14E00005FA
-:106DC000308900032468000400042102310300FF1D
-:106DD0003089000315200005388B0001246A000269
-:106DE00000042082314300FF388B00013164000130
-:106DF00010800002246C0001318300FF03E00008D2
-:106E000000601021308BFFFF000B394230E600FF9D
-:106E10003C09080025295BB8000640800109602173
-:106E20008D8700003164001F240A0001008A1804C5
-:106E300030A500FF00E3202514A000020003102766
-:106E400000E22024240F000100CF70040109682112
-:106E5000000E282714800005ADA400008F86000CCA
-:106E600000A6102403E00008AF82000C8F88000CFD
-:106E700001C8102503E00008AF82000C3C06001F8B
-:106E80003C0360003084FFFF34C5FF8024020020F3
-:106E9000AC602008AC60200CAC602010AC65201405
-:106EA000AC642018AC62200000000000000000006C
-:106EB00003E000080000000027BDFFE82402FFFFF8
-:106EC000AFBF0010AF82000C000020213C0608007C
-:106ED00024C65BB82405FFFF24890001000440801C
-:106EE0003124FFFF010618212C87002014E0FFFA4F
-:106EF000AC6500000E0008360000202124020001CD
-:106F00003C04600024050020AC822018AC852000E1
-:106F1000000000000000000000000000244A000102
-:106F20003142FFFF2C46040014C0FFF78FBF001052
-:106F300003E0000827BD00188F8300082C620400BE
-:106F400003E00008384200018F830008246200013A
-:106F500003E00008AF8200088F8300082462FFFF6F
-:106F600003E00008AF82000827BDFFE0AFB10014C6
-:106F7000AFBF0018AFB000108F6B00303C06600050
-:106F800000808821ACCB20088F6A002C3C02800056
-:106F900024030008ACCA200C9769003A97680038AF
-:106FA00000092C003107FFFF00A72025ACC42010EA
-:106FB000ACC22014ACC320000000000000000000A0
-:106FC000000000003C0360008C6D200031AC000824
-:106FD0001580FFF9000000008C6E201405C0002011
-:106FE000000000000E0007FA8F84000C00024080B1
-:106FF0003C09080025295BB8010938218CE4000010
-:107000000E0007FA00028140020220213090FFFFAB
-:10701000020020210E000818000028213C0C8000EE
-:10702000022C58253210FFFF3C116000240A00207A
-:10703000AE2B2014AE302018AE2A20000000000035
-:107040000000000000000000020010218FBF0018A7
-:107050008FB100148FB0001003E0000827BD00209E
-:107060008C6620143C02001F3443FF803C1FFFE865
-:1070700000C3C02437F9080003198021001079C229
-:107080003C0C8000022C582531F0FFFF3C116000C1
-:10709000240A0020AE2B2014AE302018AE2A200087
-:1070A00000000000000000000000000002001021AD
-:1070B0008FBF00188FB100148FB0001003E00008DC
-:1070C00027BD002027BDFFE8AFB000103402FFFF4E
-:1070D0003090FFFFAFBF0014120200060200202113
-:1070E0000E00083600000000020020210E000818E3
-:1070F000240500018F8400088FBF00148FB000109A
-:107100002483FFFF27BD001803E00008AF830008B9
-:10711000000439C230E6003F00043B42000718403B
-:10712000240210002CC4002024C8FFE0AF42002C31
-:10713000246300011480000330A900FF00071840F9
-:10714000310600FF0003608024080001019A5821E5
-:107150003C0A000E00C82804016A382111200005ED
-:10716000000530278CE900000125302503E00008E8
-:10717000ACE600008CEE000001C6682403E00008C5
-:10718000ACED000027BDFFE8AFBF0014AFB00010AA
-:107190003C0460008C8508083403F00030A2F00045
-:1071A00050430006240200018C8708083404E000E4
-:1071B00030E6F00010C4001E24020002AF8200403E
-:1071C0003C1060003C0A0200AE0A081424091000BA
-:1071D0003C08000E8E03440003482021AF49002CD8
-:1071E000240501200E000CE0000030218F830040B8
-:1071F000106000043C021691240B0001106B000E7D
-:107200003C023D6C344F0090AE0F44088FBF001419
-:107210008FB000103C0C6000240E10003C0D0200EA
-:1072200027BD0018AD8E442003E00008AD8D081086
-:107230000A000907AF8000403C0218DA344F009082
-:10724000AE0F44088FBF00148FB000103C0C6000DC
-:10725000240E10003C0D020027BD0018AD8E442006
-:1072600003E00008AD8D08100A0008DB24050001CA
-:107270000A0008DB000028213C08080025085FC43C
-:107280002404FFFF010018212402001E2442FFFFF6
-:10729000AC6400000441FFFD246300043C070800C7
-:1072A00024E760408CE5FFFC2404001C2406000158
-:1072B000308A001F01464804248400010009102779
-:1072C0002C8300201460FFFA00A22824ACE5FFFC08
-:1072D0003C05666634A4616E3C06080024C6610065
-:1072E000AF840058AF88009C2404FFFF00C0182121
-:1072F0002402001F2442FFFFAC6400000441FFFD94
-:10730000246300043C0766663C05080024A560C0B1
-:10731000AF86004834E6616EAF8600982404FFFF14
-:1073200000A018212402000F2442FFFFAC640000DB
-:107330000441FFFD246300043C0B66663C06080024
-:1073400024C660403568616EAF8500A4AF880070C8
-:107350002404FFFF00C018212402001F2442FFFF65
-:10736000AC6400000441FFFD246300043C0D66662C
-:107370003C0A0800254A618035AC616EAF860090FA
-:10738000AF8C005C2404FFFF01401821240200039D
-:107390002442FFFFAC6400000441FFFD24630004AD
-:1073A0003C090800252961908D27FFFC2404000674
-:1073B000240500013099001F0325C0042484000126
-:1073C000001878272C8E002015C0FFFA00EF382413
-:1073D000AD27FFFC3C09666624030400240403DC9B
-:1073E00024050200240600663522616E3C08080070
-:1073F00025085CC4AF820074AF830044AF83006C87
-:10740000AF830050AF830084AF8A008CAF840064E8
-:10741000AF85004CAF860054AF840078AF85006024
-:10742000AF86008001001821240200022442FFFFE1
-:10743000AC6000000441FFFD246300042404000349
-:107440002403000C3C0A0800254A5CD0AF8A00687F
-:107450000A0009AE2405FFFF0004188024840001FF
-:10746000006858212C8700C014E0FFFBAD650000C8
-:107470003C0E666635CD616E240C17A024081800FA
-:10748000AF8D0088AF8C009403E00008AF88007CCB
-:107490002484007F000421C200004021000030212C
-:1074A00000003821000028210A0009C5AF8400A08F
-:1074B0001060000624E7000100C4302124A500016B
-:1074C0002CC20BF51440FFFA2CA300663C090800FF
-:1074D0002529618001201821240200032442FFFF96
-:1074E000AC6000000441FFFD2463000410E0001ABA
-:1074F00024E3FFFF0003294210A0000A000020211E
-:107500002406FFFF3C0308002463618024840001FB
-:107510000085502BAC660000250800011540FFFBDC
-:107520002463000430E2001F104000080008688057
-:10753000240C0001004C38040008588001692821FF
-:1075400024E6FFFF03E00008ACA6000001A94021EB
-:107550002409FFFFAD09000003E00008000000005F
-:10756000AF4400283C04000C03442021000528827D
-:107570000A000CE000003021000421803C03600080
-:10758000AC6410080000000000052980AC65100CF8
-:107590000000000003E000088C62100C27BDFFE82B
-:1075A0000080282124040038AFBF00140E0009F524
-:1075B000AFB0001024040E00AF4400283C10000CB3
-:1075C00003502021240500100E000CE000003021A3
-:1075D00003501021AC400000AC40000424040038EB
-:1075E0008FBF00148FB0001024053FFF27BD001887
-:1075F0000A0009F58C430000000421803C03600070
-:10760000AC641008000000008C62100C03E000085D
-:107610000002118227BDFFC8AFB400208F9400681C
-:10762000AFBE0030AFB7002CAFB600280000B821C5
-:107630000080B021241E00C0AFBF0034AFB50024CD
-:10764000AFB3001CAFB20018AFB10014AFB0001060
-:107650000A000A32AFA5003C504000018F94006838
-:1076600027DEFFFF13C00028269400048E9200003E
-:107670003C03080024635FC01240FFF70283102B15
-:107680003C04080024845CC4028410230002A8C0C7
-:10769000000098210A000A412411000100118840CD
-:1076A000122000260000000002B38021025128248D
-:1076B0000200202110A0FFF9267300010E0009FE30
-:1076C000000000000016684032EC000101AC2021EF
-:1076D0000E0009F5020028218F89009426F7000189
-:1076E0008FA6003C3AEB0001316A00012528FFFF1C
-:1076F0000011382702CAB021AF88009416E6FFE7D0
-:1077000002479024AE92000002E010218FBF0034A7
-:107710008FBE00308FB7002C8FB600288FB50024A5
-:107720008FB400208FB3001C8FB200188FB10014EB
-:107730008FB0001003E0000827BD00383C0E0800A1
-:1077400025CE5FC0028E102B0A000A2DAE920000DB
-:1077500027BDFFD8AFB10014AFB00010AFBF0020FD
-:10776000AFB3001CAFB2001800A0882110A0001F0A
-:10777000000480403C13080026735CC40A000A7AA7
-:107780002412000112200019261000010E000A1513
-:1077900002002021000231422444FFA0000618808C
-:1077A0003045001F2C8217A1007318212631FFFFDE
-:1077B0001040FFF400B230048C6900000200202168
-:1077C00024053FFF012640241500FFEE0126382541
-:1077D0000E0009F5AC6700008F8A009426100001A6
-:1077E000254700011620FFE9AF8700948FBF0020D6
-:1077F0008FB3001C8FB200188FB100148FB000102F
-:1078000003E0000827BD00288F85009C00805821D8
-:107810000000402100004821240A001F3C0C080001
-:10782000258C603C3C0D080025AD5FC48CA6000093
-:1078300050C000140000402100AD1023000238C0E9
-:10784000240300010A000AB30000202115000003F0
-:1078500000E41021244820240000482125290001AB
-:10786000512B00132506DFDC106000062484000184
-:1078700000C3702415C0FFF5000318400A000AB1C8
-:107880000000402110AC002624A300040060282141
-:10789000254AFFFF1540FFE5AF85009C512B0004F2
-:1078A0002506DFDC0000402103E000080100102174
-:1078B0000006614230C5001F000C50803C070800E4
-:1078C00024E75FC424040001014730211120000F88
-:1078D00000A420043C05080024A560401480000595
-:1078E0002529FFFF24C6000410C500110000000078
-:1078F000240400018CCF00000004C02700042040B5
-:1079000001F868241520FFF5ACCD00008F990078B0
-:1079100001001021032B482303E00008AF89007801
-:107920003C05080024A55FC40A000ABB00004021F2
-:107930003C06080024C65FC40A000AD424040001DF
-:10794000308800FF240200021102000A2403000311
-:107950001103005C8F8900A4240400041104005F5B
-:1079600024050005110500670000182103E0000848
-:10797000006010218F8900483C0C0800258C6100B4
-:107980003C04080024846180240300201060000F60
-:1079900000005821240D0002240E00033C0F0800B3
-:1079A00025EF61008D27000014E0000B30F9FFFF88
-:1079B000252900040124C02B530000010180482127
-:1079C0002463FFFF5460FFF88D2700000160182139
-:1079D00003E0000800601021132000323C0500FF86
-:1079E00030E200FF004030211040004200005021F2
-:1079F00024050001000020210005C84000A6C02485
-:107A000017000003332500FF14A0FFFB24840001AE
-:107A1000012CC023001828C000AA6021008C50212E
-:107A20003144001F240C0001008C180400031027AF
-:107A300000E23024110D0041AD260000110E004C73
-:107A4000000A1840110D00368F87006C510E005649
-:107A50008F8C0060240D0004110D005A8F8E00845D
-:107A6000240E0005150EFFDA01601821240B1430D6
-:107A700011400006000018218F8400A0246300013B
-:107A8000006A402B1500FFFD016458218F8A008099
-:107A9000AF89008C016018212549FFFF0A000B0BFC
-:107AA000AF89008000E52024000736021080FFD057
-:107AB000240A001800075402314600FF0A000B1385
-:107AC000240A00103C0C0800258C60C03C0408000F
-:107AD000248461000A000AFA240300103C0C080008
-:107AE000258C60403C040800248460C00A000AF928
-:107AF0008F89009000071A02306600FF0A000B13FE
-:107B0000240A00088F89008C3C0C0800258C6180B9
-:107B10003C040800248461900A000AFA240300044B
-:107B2000000A4080250B003024E6FFFF0160182189
-:107B3000AF8900480A000B0BAF86006C000AC982AF
-:107B4000001978803C07080024E760C001E7202185
-:107B5000000A18428C8F00003079001F032C380473
-:107B60000007C02701F860240A000B28AC8C000035
-:107B7000000331420006288000AF28213062001F38
-:107B80008CB8000024630001004CC80400032142AB
-:107B9000001938270004108003073024004F2021EB
-:107BA0000A000B6CACA60000000A68C025AB0032CE
-:107BB000258AFFFF01601821AF8900A40A000B0B82
-:107BC000AF8A0060254B1030AF890090016018210A
-:107BD00025C9FFFF0A000B0BAF8900843086000720
-:107BE0002CC2000610400014000000000006408077
-:107BF0003C030800246359C8010338218CE40000C9
-:107C000000800008000000002409000310A9000EF5
-:107C100000000000240A000510AA000B000000006C
-:107C2000240B000110AB0008000000008F8C00A0A6
-:107C300010AC00050000000003E000080000102167
-:107C40000A000A9900A020210A000AE700C02021AA
-:107C500027BDFFE8308400FF240300021083000BDF
-:107C6000AFBF0010240600031086003A2408000469
-:107C700010880068240E0005108E007F2CAF143091
-:107C80008FBF001003E0000827BD00182CA20030B1
-:107C90001440FFFC8FBF001024A5FFD0000531C2A7
-:107CA000000668803C07080024E7610001A7302136
-:107CB0008CC900000005288230AC001F240B000195
-:107CC000018B50048F840048012A4025ACC8000075
-:107CD0008C83000050600001AF8600488F98006CD4
-:107CE00030AE000124A6FFFF270F000115C00002DF
-:107CF000AF8F006C24A600010006414200082080DE
-:107D0000008718218C79000030C2001F2406000172
-:107D10000046F804033F382410E0FFDA8FBF00105C
-:107D20000005C182001870803C0F080025EF60C07C
-:107D300001CF48218D2B00000005684231A5001FAE
-:107D400000A66004016C502527BD001803E0000860
-:107D5000AD2A00002CA7003014E0FFCA8FBF00102E
-:107D600030B900071723FFC724A8FFCE00086A0216
-:107D7000000D60803C0B0800256B60C0018B30213A
-:107D80008CC40000000828C230AA001F240800018B
-:107D9000014848048F8200A400891825ACC3000064
-:107DA0008C5F000053E00001AF8600A40005704026
-:107DB000000E7942000F28803C04080024846100F2
-:107DC00000A418218C6B000025DF000131CD001FBD
-:107DD000001F514201A86004016C4825000A108070
-:107DE000AC690000004428218CA600008F98006038
-:107DF00033F9001F8FBF00100328380400C778250F
-:107E0000270E000127BD0018ACAF000003E00008FA
-:107E1000AF8E006024A5EFD02CB804001300FF99AA
-:107E20008FBF001000053142000658803C0A080050
-:107E3000254A6040016A30218CC4000030A3001F35
-:107E400024090001006910048F9900900082F82530
-:107E5000ACDF00008F27000050E00001AF860090EB
-:107E60008F8D00848FBF001027BD001825AC000146
-:107E700003E00008AF8C008415E0FF828FBF001084
-:107E80008F8600A0000610400046F821001F210048
-:107E900003E4C8210019384024F8143000B8402BFE
-:107EA0001100FF788FBF001024A4EBD00E00020D4C
-:107EB00000C0282100027942000F70803C0D0800AC
-:107EC00025AD618001CD20218C8B0000304C001F3E
-:107ED00024060001018618048F89008C0163502557
-:107EE000AC8A00008D25000050A00001AF84008CFA
-:107EF0008F9800808FBF001027BD00182708000151
-:107F000003E00008AF88008030A5000724030003C9
-:107F100010A3001028A20004144000082407000247
-:107F20002403000410A300152408000510A8000F66
-:107F30008F8500A003E000080000000014A7FFFDEB
-:107F40000080282114C3FFFB240400020A000BABAD
-:107F500000000000240900050080282110C9FFFB53
-:107F60002404000303E000080000000014C5FFF132
-:107F7000008028210A000BAB24040005240A00011C
-:107F80000080282110CAFFF12404000403E0000847
-:107F90000000000027BDFFE0AFB00010000581C267
-:107FA0002603FFD024C5003F2C6223D024C6007FC7
-:107FB000AFB20018AFB10014AFBF001C309100FF8A
-:107FC000000691C20005298202002021104000080D
-:107FD0002403FFFF0E000A6B0000000002002021B6
-:107FE000022028210E000C590240302100001821E7
-:107FF0008FBF001C8FB200188FB100148FB000101B
-:108000000060102103E0000827BD002027BDFFD835
-:1080100024A2007FAFB3001CAFB20018000299C2C7
-:10802000309200FF24A3003F02402021026028215B
-:10803000AFB10014AFB00010AFBF00200E000B8E28
-:108040000003898200408021004020210220282155
-:1080500014400009000018218FBF00208FB3001CBE
-:108060008FB200188FB100148FB000100060102183
-:1080700003E0000827BD00280E000A1C00000000D5
-:1080800000402821020020211051FFF3001019C0E8
-:108090000E000A6B0000000002002021024028218F
-:1080A0000E000C59026030218FBF00208FB3001CDE
-:1080B0008FB200188FB100148FB00010000018218B
-:1080C0000060102103E0000827BD00283084FFFF76
-:1080D00030A5FFFF1080000700001821308200014A
-:1080E0001040000200042042006518211480FFFBAC
-:1080F0000005284003E000080060102110C00007C0
-:10810000000000008CA2000024C6FFFF24A500048C
-:10811000AC82000014C0FFFB2484000403E00008CC
-:108120000000000010A0000824A3FFFFAC860000A0
-:1081300000000000000000002402FFFF2463FFFF96
-:108140001462FFFA2484000403E000080000000029
-:1081500030A5FFFF8F4201B80440FFFE3C076015C9
-:1081600000A730253C031000AF440180AF400184DC
-:10817000AF46018803E00008AF4301B88F8500D007
-:108180002C864000008018218CA700840087102BCB
-:1081900014400010000000008CA800842D06400050
-:1081A00050C0000F240340008CAA0084008A482B92
-:1081B000512000018CA3008400035A42000B208050
-:1081C0003C05080024A55A400085182103E000085A
-:1081D0008C62000014C0FFF4000000002403400083
-:1081E00000035A42000B20803C05080024A55A4099
-:1081F0000085182103E000088C6200008F8300D006
-:10820000906600D024C50001A06500D08F8500D005
-:10821000906400D090A200D210440017000000002B
-:10822000936C00788F8B00BC318A00FFA16A000C30
-:1082300025490001938700C4312200FF3048007FA8
-:108240001107000B00026827A36200788F4E0178A7
-:1082500005C0FFFE8F9900B0241800023C0F1000EB
-:10826000AF590140A358014403E00008AF4F017823
-:108270000A000D2931A20080A0A000D00A000D1F25
-:108280000000000027BDFFD8AFB200188F9200B8E1
-:10829000AFBF0020AFB3001CAFB00010AFB10014EF
-:1082A0008F9300B48E5900283C1000803C0EFFEFE5
-:1082B000AE7900008E580024A260000A35CDFFFF81
-:1082C000AE7800049251002C3C0BFF9F356AFFFFF3
-:1082D000A271000C8E6F000C3C080040A271000BD4
-:1082E00001F06025018D4824012A382400E830255A
-:1082F000AE66000C8E450004AE6000183C0400FF22
-:10830000AE6500148E43002C3482FFFFA660000887
-:108310000062F824AE7F00108E5900088F9000B0E4
-:10832000964E0012AE7900208E51000C31D83FFFDE
-:1083300000187980AE7100248E4D001401F0602188
-:1083400031CB0001AE6D00288E4A0018000C41C2EE
-:10835000000B4B80AE6A002C8E46001C01093821B0
-:10836000A667001CAE660030964500028E440020D1
-:10837000A665001EAE6400349243003330620004F0
-:1083800054400005924600008F8300D08C7F007C13
-:10839000AE7F0030924600008F8500BCA0A6000092
-:1083A000924400333082000250400007924E000198
-:1083B0008F8700BC240AFF8090E90000012A402535
-:1083C000A0E80000924E00018F8D00BC2409FFBF81
-:1083D0002404FFDFA1AE00018F8A00BC914C000D88
-:1083E000318B007FA14B000D8F8600BC90C8000D23
-:1083F00001093824A0C7000D8F9100BC8E650014C0
-:108400009223000D2CA200010002F9400064C82450
-:10841000033FC025A238000D8F8800BC9650001283
-:108420008F8700D0A51000028E45000490ED00BC9F
-:1084300030AF0003000F702331CC000300AC1021DB
-:1084400031AB0002156000022444003424440030A3
-:1084500090F100BC00B18024320F000415E000024E
-:1084600024830004008018218F8900AC240A0002B4
-:10847000AD030004A12A00009248003F8F8700ACA2
-:10848000A0E800018F9100AC9246003F8E440004AA
-:10849000A62600029765003C0E000CF630B0FFFFE8
-:1084A00000021380005020253C0342000083F82581
-:1084B000AE3F00048F8500AC8E590038ACB900186F
-:1084C0008E580034ACB8001CACA0000CACA000105E
-:1084D000A4A00014A4A00016A4A00020A4A0002220
-:1084E000ACA000248E620014504000012402000160
-:1084F0008FBF00208FB3001C8FB200188FB1001403
-:108500008FB00010ACA200080A000D1627BD00288D
-:108510008F8600D027BDFFD0AFBF002CAFB600289C
-:10852000AFB50024AFB40020AFB3001CAFB2001849
-:10853000AFB10014AFB0001094C300E094C200E2E9
-:10854000104300412405FFFF3C16000E90C400D0EC
-:1085500090C800D1309200FF310400FF0244382B54
-:1085600010E0004426490001108900378F9800B0C0
-:108570003C0508008CA5005C2414FF8000B8602135
-:1085800001946824AF4D002C94CA00E2318B007F27
-:10859000017A482131447FFF013640210004104018
-:1085A0000048A82196A700003C1F08008FFF005834
-:1085B00030F53FFF0015198003E3C8210319882116
-:1085C0003233007F027A782102348024AF50002CAD
-:1085D00001F69821926E000D31C5000410A00048EC
-:1085E0000000000094C300E294C300E294D800E2CB
-:1085F00024048000307F7FFF27F9000133317FFFA3
-:108600000304802402117825A4CF00E294CE00E276
-:108610003C1208008E52006031D47FFF129200DFBE
-:10862000000000008E720018000028212646FFFF7F
-:10863000AE66002C8F8600D094C800E094C900E29A
-:108640001528FFC2000000008FBF002C8FB6002845
-:108650008FB500248FB400208FB3001C8FB2001898
-:108660008FB100148FB0001000A0102103E00008AB
-:1086700027BD003090CD00D2264A000131AC00FF6A
-:10868000008C5821116AFFF08F9800B03C0508005B
-:108690008CA5005C2414FF8000B86021019468243C
-:1086A000AF4D002C94CA00E2318B007F017A482143
-:1086B00031447FFF01364021000410400048A821CA
-:1086C00096A700003C1F08008FFF005830F53FFFC1
-:1086D0000015198003E3C821031988213233007F74
-:1086E000027A782102348024AF50002C01F69821C0
-:1086F000926E000D31C5000414A0FFBA0000000006
-:108700008E6600100012C0C08E6E003000129140C4
-:1087100002587821036F582100CE6823256C008809
-:1087200024020002AE6D0010AF8C00ACA162008884
-:10873000976A003C8E6400308F9100AC0E000CF6FE
-:108740003150FFFF00022380009048253C03420087
-:1087500001234025AE2800048E6700048F8C00ACF6
-:108760008E7F0000240D0008AD87001CAD9F00180F
-:10877000AD80000CAD8000109265000A30B900FF9A
-:10878000A5990014967800083C05000CA5980016E1
-:108790009271000A322F00FFA58F0020967000080A
-:1087A00024110005A5900022AD800024926E000BDC
-:1087B0002410C00031C600FFA5860002A18D000173
-:1087C0008E6B00308F8200AC8F8800B0AC4B0008FD
-:1087D0003C0A08008D4A0054014820210094482496
-:1087E000AF4900283C0308008C630054006838211E
-:1087F00030FF007F03FAC8210325C02102587821E9
-:10880000AF8F00BCAF9800C0A1F100008F8B00BCFF
-:108810002403FFBF2405FFDF956E000201D0A024D2
-:1088200002959025A57200029166000230CD003FAE
-:1088300035AC0040A16C00028F8800BC8F8200D054
-:108840003C0C7FFFAD0000048C4A007C358BFFFFA1
-:108850003C028000AD0A00089104000D3089007FC1
-:10886000A109000D8F9F00BC93F5000D02A33824D1
-:10887000A3E7000D8F9100BC9239000D0325C024A1
-:10888000A238000D8E6F00348F8D00BCADAF00108C
-:108890008E6E002C8E70003001D0A023ADB4001479
-:1088A00091B200183246007FA1A600188F8700BC45
-:1088B0008E6A00308CE40018014B4824008240246A
-:1088C0000109A825ACF500189263000AA0E3001C7A
-:1088D000967F00088F8500BC8F9900D0A4BF001E32
-:1088E0008E7000308E6400300E00020D8F250084E3
-:1088F0008F8500D0000289400002C10090AE00BC0C
-:10890000023878210040302131D400021280000367
-:10891000020F80210002A8800215802190B200BCC5
-:1089200032540004128000020006C880021980211F
-:108930008E6F00308F8B00BC2406800031EE000368
-:10894000000E682331AC0003020C1021AD6200045C
-:1089500094A400E294AA00E294A300E231507FFFC5
-:108960002604000130897FFF006640240109882524
-:10897000A4B100E294A700E23C1308008E730060EB
-:1089800030FF7FFF13F30012000000000E000D16F1
-:10899000000000000A000E240000282194CD00E20F
-:1089A00001A46024A4CC00E290CB00E290C200E2DB
-:1089B000316A00FF000A49C200092027000441C0B3
-:1089C0003055007F02A838250A000E20A0C700E21B
-:1089D00094B100E202263824A4A700E290BF00E28E
-:1089E00090B400E233F300FF0013C9C200199027CE
-:1089F0003298007F0012A9C0031530250E000D1615
-:108A0000A0A600E20A000E24000028213084FFFF07
-:108A100030A5FFFFAF440018AF45001C03E000087D
-:108A20008F42001427BDFFB0AFB000288F9000D058
-:108A3000AFB40038AFBF004CAFBE0048AFB7004482
-:108A4000AFB60040AFB5003CAFB30034AFB20030BA
-:108A5000AFB1002CA7A00014920600D1920500D05F
-:108A60003094FFFF30C400FF30A300FF0064102BE0
-:108A7000A7A0001E10400071AFA00010920900D006
-:108A80000014982B312800FF0088382324F2FFFFC0
-:108A90000012882B0233782451E000758FB2001049
-:108AA00096180012961900100014F4000319B82348
-:108AB0000017B400001614030282A82A16A00002B0
-:108AC000001E2403004020210244F82B13E0000282
-:108AD00000801821024018210003340000061C0306
-:108AE0003065FFFF2CA200091440000200609821AD
-:108AF000241300088E090008001359808E08000C0A
-:108B00003164FFFF3C0A0010008A3825274A040020
-:108B1000AF490038AF8A00B8AF48003CAF470030DB
-:108B20000000000000000000000000000000000045
-:108B30000000000000000000000000000000000035
-:108B40008F4D000031AC00201180FFFD0013702A12
-:108B500001D110240000A821104001C00000000035
-:108B60008F9800B03C0B08008D6B00542411FF80DF
-:108B7000921E00D00178202100911024921900D07B
-:108B8000AF4200288D4500103C0608008CC60058F6
-:108B90003C1708008EF7005430A73FFF00071980EC
-:108BA00000C34021030820210091F824920B00D03B
-:108BB000AF5F002C9148000033D600FF332F00FF39
-:108BC00002F8702100166140000F68C031C9007FB3
-:108BD000018D3821013A2821316300FF3086007F62
-:108BE0003C02000C00A2B021000389400367C821A9
-:108BF00000DAF8213108003F3C1E000E0236B82191
-:108C00002738008803FE88212D0F0008AF9800AC9C
-:108C1000AF9700BCAF9600C011E0018FAF9100B4D8
-:108C2000000868803C0E080025CE59E001AE6021A6
-:108C30008D8900000120000800000000920E00D283
-:108C4000920D00D00014982B31CA00FF31AC00FF08
-:108C5000008C5823014B20212492FFFF0012882B07
-:108C60000233782415E0FF8E000000008FB2001060
-:108C70008FBF004C8FBE00483A4200018FB70044BE
-:108C80008FB600408FB5003C8FB400388FB30034EE
-:108C90008FB200308FB1002C8FB0002803E00008A5
-:108CA00027BD0050915800013317002012E0020444
-:108CB00024160001921F00BC0000B02133F900010E
-:108CC0001320000D241E00018D4800148E03008423
-:108CD0000103B02B16C00002010030218E06008473
-:108CE0008E05006400C5382B14E0000200C020216E
-:108CF0008E0400640080B0218D4200148E0B00644D
-:108D0000004B302B14C00002004020218E04006470
-:108D10000096B82356E00001241E0002025E202BBC
-:108D200014800148000018218D5900388E2F000C46
-:108D30003C180080AE3900008D5000343C0EFF9F7F
-:108D400001F86025AE3000049149003F35CDFFFFAA
-:108D5000018D20243C0A00203C0BFFEFA229000BD0
-:108D6000008A38253562FFFF00E228243C0600080F
-:108D70008F8700B800A6C825AE39000C8CE300141C
-:108D8000AE2000183C08FFFBAE2300148CF800183E
-:108D9000351FFFFF033F7024AE38001C8CEF000826
-:108DA00002D78021AE2F00248CED000CAE30002CB9
-:108DB000AE2E000CAE2D0020AE200028A6200038DC
-:108DC000A620003A8CEC001401964823013750236A
-:108DD00011400011AE2A001090EE003D8E2C0004D0
-:108DE0008E240000000E6900018D28210000502112
-:108DF00000AD302B008A582101661021AE250004F9
-:108E0000AE22000090E3003DA223000A8F8800B844
-:108E1000951F0006A63F00088F8B00AC24060002B9
-:108E200002C02021A16600009765003C8F9000AC35
-:108E300030A2FFFF0E000CF6AFA200208FA300208F
-:108E4000000243808F8500B80103C8253C1F420003
-:108E5000033FC025AE1800048F8400AC8CAF0038EF
-:108E6000AC8F00188CB00034AC90001CAC80000CAF
-:108E7000AC800010A4800014A4800016A480002000
-:108E8000A4800022AC80002490A7003FA4870002A9
-:108E900012C00210240D000152E0000290A2003D19
-:108EA00090A2003E244A0001A08A00018F8400ACF9
-:108EB000AC9600088F8300D024070034906F00BC6C
-:108EC00031EE000251C00001240700308F8200B84B
-:108ED0008F9900BC906800BC905F000024100004D3
-:108EE00032CF0003A33F00008F9800B88F8C00BCE6
-:108EF000020F7023930D00012405C00031CA000346
-:108F0000A18D00018F9000BC8F8900B800F6382138
-:108F1000960400029526001200EA382100855824A4
-:108F200030C33FFF01631025A6020002921F00021A
-:108F30003108000433F9003F37380040A21800021E
-:108F400012C000028F8500BC00E838218F8600D057
-:108F5000ACA70004241FFFBF8CC3007C2ECB0001F4
-:108F6000240FFFDFACA3000890A8000D000B6940A0
-:108F70003102007FA0A2000D8F9000BC9219000D5D
-:108F8000033FC024A218000D8F8A00BC914E000D33
-:108F900001CF6024018D4825A149000D8F8600B8BE
-:108FA0008F8B00BC8CC70020AD6700108CC50024DF
-:108FB000AD6500148CC40028AD6400188CC3002C6F
-:108FC0000E000D16AD63001C2408000257C8009C5B
-:108FD0008F9000D08F8F00D08F8A00C002E02021B8
-:108FE00091E800D091EB00D091E700D0311000FF64
-:108FF000316E00FF00106940000E28C001A5182145
-:1090000030E900FF0363C8210009314000CAF8219C
-:1090100027220088AF8200ACAF9F00BCA33E00882F
-:109020000E000CF68F9000AC8FB800200002638019
-:109030003C0F4200019840258F8C00B8010F582545
-:10904000AE0B00048D8400388F8B00AC000028210B
-:1090500000053900AD6400188D8E00343C0F7FFF91
-:1090600035E8FFFFAD6E001C9183003E8D69001C4A
-:109070008D6600180003510000036F02012AC02111
-:1090800000ED1025030AF82B00C2C821033F802100
-:10909000AD78001CAD700018AD60000CAD60001024
-:1090A0009184003E241F00052410C000A564001414
-:1090B000958E000402E8402402E02021A56E0016EF
-:1090C0009185003EA5650020958D0004A56D0022C8
-:1090D000AD6000249187003FA56700029183003EA8
-:1090E0009189003D0123502325460001A16600011E
-:1090F0008F8200AC8F9900BCAC570008A33F0000E2
-:109100008F8A00BC8F9800B8954F0002970E00120E
-:109110002418FFBF020F682431C53FFF01A5382581
-:10912000A5470002914C00022405FFDF3189003F72
-:1091300035230040A14300028F9900BC8F8600D0E8
-:109140002409FFFFAF2000048CCB007C2403FF80A8
-:10915000AF2B00089322000D3C0B8000305F007F96
-:10916000A33F000D8F8E00BC91D0000D0218782413
-:10917000A1CF000D8F8C00BC918D000D01A538246E
-:10918000A187000D8F8600BCACC90010ACD60014BE
-:1091900090CA00180143B025A0D600188F8F00BCDC
-:1091A0008F9800B88DE20018004BF82403E8C8251A
-:1091B000ADF900189310003EA1F0001C8F8E00B88E
-:1091C0008F8D00BC8F8700D095C50004A5A5001E1B
-:1091D0000E00020D8CE500848F8700D000026140F4
-:1091E0000002210090EA00BC0184482100402821AF
-:1091F0003156000212C0000302E930210002B080A3
-:1092000000D6302190EC00BC3184000410800003B3
-:1092100032EA00030005C08000D830212409000490
-:109220008F9700BC012A1023305F000300DFC821A4
-:10923000AEF900040E000D16A62500388F9000D060
-:1092400003C01821146000020060B02100009021CA
-:1092500056C000868F9700B80012882B9609001020
-:10926000029550233C14002002A91021A6020010F0
-:10927000AF5400303154FFFF00000000961300107F
-:10928000961F001213F30011000000008E17000C4F
-:109290008E0C00080015C98002F94021001927C36F
-:1092A0000119B02B0184782101F65821AE08000C79
-:1092B000AE0B00080014A82B023580241200FE6BB0
-:1092C0008F9000D00A000F3F00000000960B0014A2
-:1092D0008E0500043163FFFF000370C000AE38212B
-:1092E000AF47003C8E0600048F4D003C00CDF023BC
-:1092F0001BC00036000000008E080000250200019F
-:109300003C16001036CF0008AF420038AF4F003097
-:10931000000000000000000000000000000000004D
-:10932000000000000000000000000000000000003D
-:109330008F440000308C00201180FFFD00000000F1
-:109340008F5904003C170020AE1900088F55040403
-:10935000AE15000CAF570030000000003C060800BE
-:109360008CC600442418000110D800D3000000006F
-:10937000960700123C0508008CA5004000A7682154
-:10938000A60D0012961E001427C90001A60900149C
-:10939000960200143044FFFF5486FFC70014A82B28
-:1093A00030A5FFFF0E000F1AA60000143C030800B2
-:1093B0008C630024960500120043702300AE302316
-:1093C000A60600120A0011450014A82B8E02000008
-:1093D0000A0011583C16001091560001241000019B
-:1093E0000016784215F0001C97A8001E8D5F00142F
-:1093F0002411C00033FE3FFF0111C8243C180800AF
-:109400008F180060033EB82532E53FFF00B8502BAF
-:1094100011400011A7B7001E3C1008008E10005824
-:109420008F8F00B000057180240CFF80020F68212F
-:1094300001AE48213124007F012C5824009A2821B4
-:109440003C02000EAF4B002C00A2302190C7000D53
-:1094500034E30004A0C3000D0E000D38000000002E
-:109460008F9000D0240300018F9700B826B9000127
-:109470000019AC00024390230015AC0326F800400D
-:1094800002B3202A0012882B240C00010300502173
-:1094900000911024AF9800B80A000F6DAFAC001017
-:1094A000955600128F8400B032C5FFFF0E000CEB02
-:1094B000A7B600148F9000D00A0011B10000182147
-:1094C0008D590038A620000824040003AE3900009E
-:1094D0008D570034A220000A8F9800B8AE370004E0
-:1094E0003C0F0080930C003FA224000C8E28000C3F
-:1094F0003C0BFF9FA22C000B010F1825356EFFFFC0
-:109500003C05FFEF8F9700B8006E682434A7FFFF7B
-:1095100001A73024AE26000C8EFE001496FF001228
-:109520008F8200B0AE3E00108EF00014AE20001806
-:10953000AE200020AE300014AE2000248EE90018CA
-:1095400033F03FFF00105180AE2900288EF900084B
-:109550000142C02133EC0001AE3900308EEB000C2B
-:109560008F8500AC001879C2000C238001E44021F3
-:10957000240E0002A628001CA6200036AE2B002CCC
-:10958000A0AE00009767003C8F8A00AC3C0342000D
-:1095900030EDFFFF01A33025AD4600048F9E00B8DB
-:1095A000240200012408C0008FD1003824060034B2
-:1095B000AD5100188FC90034AD49001CAD40000CFE
-:1095C000AD400010A5400014A5400016A5400020A5
-:1095D000A5400022AD400024A5560002A142000192
-:1095E0008F9F00AC8F9900B88F9800BCAFF6000831
-:1095F00093370000A31700008F8C00B88F8F00BC3A
-:1096000091840001A1E400018F8D00BC95AB0002A4
-:109610000168702401D02825A5A5000291A70002A9
-:1096200030E3003FA1A300028F8300D08F8400BCF1
-:10963000907100BC323E000253C00001240600308D
-:10964000AC8600048C6F007C2403FFBFAC8F000845
-:109650009088000D310B007FA08B000D8F8700BC20
-:1096600090EE000D01C32824A0E5000D8F9E00BCE4
-:1096700093CD000D35A60020A3C6000D8F8A00B83B
-:109680008F9100BC8D500020AE3000108D49002419
-:10969000AE2900148D420028AE2200188D5F002CE8
-:1096A000AE3F001C0E000D16000000008F9000D091
-:1096B0000A00112B02C01821960A00123C1F080054
-:1096C0008FFF002403EA9821A61300120A00114517
-:1096D0000014A82BA08D00018F8900AC240C000180
-:1096E000AD2C00080A0010458F8300D027BDFFE095
-:1096F0003C1808008F180050AFB00010AFBF001822
-:10970000AFB10014AF8400B09371007403047821EA
-:109710002410FF8031EE007F3225007F01F05824B5
-:1097200001DA68213C0C000AA38500C401AC2821A1
-:10973000AF4B002494A900109768000690A6006221
-:1097400000803821240200300109202330C300F0BA
-:10975000AF8500D0106200193090FFFF90AE00621C
-:10976000240DFFF0240A005001AE6024318B00FF6D
-:10977000116A002F0000000016000007241F0C00D3
-:10978000AF5F00248FB100148FBF00188FB000109E
-:1097900003E0000827BD00200E000F20020020215A
-:1097A000241F0C00AF5F00248FB100148FBF00187E
-:1097B0008FB0001003E0000827BD002094A200E055
-:1097C00094A400E290BF0113008218263079FFFFB5
-:1097D00033E700C014E000092F3100011600003803
-:1097E000000000005620FFE6241F0C000E000DDBD9
-:1097F000000000000A001277241F0C001620FFDE74
-:10980000000000000E000DDB000000001440FFDC33
-:10981000241F0C00160000228F8300D090690113D2
-:109820003122003FA06201130A001277241F0C00AE
-:1098300094AF00D48F8600D400E0282124040005D2
-:109840000E000C7C31F0FFFF1440000524030003E0
-:10985000979100E6000018212625FFFFA78500E666
-:109860008F5801B80700FFFE3C196013AF4001801C
-:10987000241F0C00AF500184007938253C101000E3
-:10988000AF4701888FB10014AF5001B8AF5F00241B
-:109890008FB000108FBF001803E0000827BD002024
-:1098A0000E000F20020020215040FFB5241F0C00A5
-:1098B0008F8300D0906901130A0012A03122003F6B
-:1098C0000E000F20020020211440FFAD241F0C00C9
-:1098D000122000078F8300D0906801133106003FEB
-:1098E00034C20040A06201130A001277241F0C004A
-:1098F0000E000DDB000000005040FFA1241F0C00F3
-:109900008F8300D0906801133106003F0A0012D007
-:1099100034C20040AF9B00C803E00008AF8000ECF9
-:109920003089FFFF000940422D02004100092980D3
-:10993000144000020009504024080040000879400B
-:109940000008C0C001F85821256701A800EF702168
-:1099500025CC007F240DFF80018D18240065302167
-:1099600000CA282125640088240A00883C010800D8
-:10997000AC2A004C3C010800AC240050AF8500D458
-:109980003C010800AC2900603C010800AC280064E0
-:109990003C010800AC2700543C010800AC230058EF
-:1099A0003C010800AC26005C03E000080000000059
-:1099B000308300FF30C6FFFF30E400FF8F4201B864
-:1099C0000440FFFE00034C00012438253C086000E1
-:1099D00000E820253C031000AF450180AF4601841C
-:1099E000AF44018803E00008AF4301B88F86001C34
-:1099F0003C096012352700108CCB00043C0C600E33
-:109A000035850010316A00062D480001ACE800C41D
-:109A10008CC40004ACA431808CC2000894C3000242
-:109A2000ACA2318403E00008A78300E43C030800F3
-:109A30008C6300508F8400E88F86001C2402FF8016
-:109A40000064C0210302C824AF5900288CCD000453
-:109A50003305007F00BA78213C0E000C01EE28216E
-:109A6000ACAD00588CC80008AF8500D03C07601230
-:109A7000ACA8005C8CCC001034E80010ACAC000C3E
-:109A80008CCB000CACAB000894AA00143C0208007C
-:109A90008C42004425490001A4A9001494A4001498
-:109AA0003083FFFF106200178F8400D03C0A08004B
-:109AB0008D4A0040A4AA00128CCE0018AC8E00245F
-:109AC0008CCD0014AC8D00208CC70018AC87002C06
-:109AD0008CCC001424060001AC8C00288D0B00BC3B
-:109AE0005166001A8D0200B48D0200B8A482003ABB
-:109AF000948F003AA48F003C948800D403E00008BF
-:109B00003102FFFF3C0908008D290024A4A00014A5
-:109B10008F8400D0A4A900128CCE0018AC8E002433
-:109B20008CCD0014AC8D00208CC70018AC87002CA5
-:109B30008CCC001424060001AC8C00288D0B00BCDA
-:109B40005566FFEA8D0200B88D0200B4A482003A87
-:109B5000948F003AA48F003C948800D403E000085E
-:109B60003102FFFF8F86001C3C0C08008D8C0050DA
-:109B7000240BFF808CCD00083C03000C000D51C06D
-:109B8000018A4021010B4824AF8A00E8AF49002830
-:109B900090C700073105007F00BA1021004328213B
-:109BA00030E400041080002FAF8500D090CF000774
-:109BB00031EE000811C0003C000000008CD9000C00
-:109BC0008CC400140324C02B1300002600000000E6
-:109BD0008CC2000CACA200648CCD00182402FFF8EB
-:109BE000ACAD00688CCC0010ACAC00808CCB000C11
-:109BF000ACAB00848CCA001CACAA007C90A900BC51
-:109C000001224024A0A800BC90C3000730670008D0
-:109C100010E000048F8500D090AF00BC35EE00014D
-:109C2000A0AE00BC90D90007333800011300000F2C
-:109C30008F8400D024070020908200BC34490002A9
-:109C4000A08900BC8F8400D090880062310300F0AE
-:109C500014670006240A0034AC8A00C00A0013B25C
-:109C6000000000000A00138C8CC2001490CB000787
-:109C70003166000210C0000500000000908D00BC9D
-:109C800035AC0004A08C00BC8F8400D090980113E8
-:109C9000330F003FA08F01138F8E00D095C500D4E5
-:109CA00003E0000830A2FFFFACA000640A00138D9F
-:109CB0000000000027BDFFD8AFB000108F90001C3F
-:109CC000AFBF0024AFB40020AFB20018AFB1001492
-:109CD000AFB3001C9613000E3C07600A3C146006EC
-:109CE0003264FFFF369300100E0012DF34F40410CC
-:109CF0008F8400D43C11600E0E0009BB3631001079
-:109D0000920E00153C0708008CE700603C126012C0
-:109D100031CD000FA38D00F08E0E00048E0D0008D3
-:109D200096080012961F00109619001A9618001E29
-:109D3000960F001C310CFFFF33EBFFFF332AFFFFB0
-:109D40003309FFFF31E6FFFF3C010800AC2B004068
-:109D50003C010800AC2C00243C010800AC2A004463
-:109D6000AE293178AE26317C92020015960300169A
-:109D700036520010304400FF3065FFFF3C060800FB
-:109D80008CC60064AE243188AE4500B4920800143D
-:109D900096190018241F0001011FC004332FFFFF74
-:109DA0003C0508008CA50058AE5800B8AE4F00BC6A
-:109DB000920C0014AF8E00D8AF8D00DC318B00FF09
-:109DC000AE4B00C0920A0015AE670048AE66004C6C
-:109DD000314900FFAE4900C8AE65007C3C03080075
-:109DE0008C6300503C0408008C84004C3C08080044
-:109DF0008D0800543C0208008C42005C8FBF002498
-:109E0000AE6300808FB00010AE8300748FB3001C6F
-:109E1000AE22319CAE4200DCAE2731A0AE2631A48A
-:109E2000AE24318CAE233190AE283194AE253198DA
-:109E3000AE870050AE860054AE8500708FB100141E
-:109E4000AE4700E0AE4600E4AE4400CCAE4300D0E6
-:109E5000AE4800D4AE4500D88FB400208FB20018B1
-:109E600003E0000827BD002827BDFFE0AFB10014C4
-:109E7000AFBF0018241100010E000865AFB000103C
-:109E800010510005978400E6978300CC0083102BC7
-:109E9000144000088F8500D4240700028FBF0018EB
-:109EA0008FB100148FB0001000E0102103E0000813
-:109EB00027BD00200E000C9A24040005AF8200E8A4
-:109EC0001040FFF6240700020E0008698F90001C66
-:109ED000979F00E68F9900E88F8D00C827EF00015B
-:109EE000240E0050AF590020A78F00E6A1AE00005D
-:109EF0003C0C08008D8C00648F8600C8240A80000A
-:109F0000000C5E00ACCB0074A4C0000694C9000A2B
-:109F1000241FFF803C0D000C012AC024A4D8000A95
-:109F200090C8000A24182000011F1825A0C3000AA9
-:109F30008F8700C8A0E000788F8500C80000382116
-:109F4000A0A000833C0208008C4200508F8400E8EF
-:109F50000044782101FFC824AF590028960B000265
-:109F600031EE007F01DA6021018D3021A4CB00D4D5
-:109F7000960A0002AF8600D03C0E00042549240159
-:109F8000A4C900E68E080004ACC800048E030008D3
-:109F9000ACC30000A4C00010A4C00014A0C000D036
-:109FA0008F8500D02403FFBFA0A000D13C0408008F
-:109FB0008C8400648F8200D0A04400D28E1F000CDD
-:109FC0008F8A00D0978F00E4AD5F001C8E190010BF
-:109FD00024100030AD590018A5400030A5510054A0
-:109FE000A5510056A54F0016AD4E0068AD58008033
-:109FF000AD580084914D006231AC000F358B0010DC
-:10A00000A14B00628F8600D090C900633128007F89
-:10A01000A0C800638F8400D02406FFFF90850063F2
-:10A0200000A31024A08200638F9100D000E01021D3
-:10A03000923F00BC37F90001A23900BC8F8A00D0E2
-:10A04000938F00F0AD580064AD5000C0914E00D326
-:10A05000000F690031CC000F018D5825A14B00D3B2
-:10A060008F8500D08F8900DCACA900E88F8800D8EC
-:10A070008FBF00188FB100148FB0001027BD0020D3
-:10A08000ACA800ECA4A600D6A4A000E0A4A000E226
-:10A0900003E000080000000027BDFFE0AFB00010A3
-:10A0A0008F90001CAFB10014AFBF00188E190004D0
-:10A0B0003C1808008F180050240FFF80001989C039
-:10A0C0000238702131CD007F01CF602401BA5021C8
-:10A0D0003C0B000CAF4C0028014B4021950900D4EB
-:10A0E000950400D68E0700043131FFFFAF8800D001
-:10A0F0000E000933000721C08E0600048F8300C8BC
-:10A10000000629C0AF4500209064003E3082004028
-:10A11000144000068F8400D0341FFFFF948300D6C4
-:10A120003062FFFF145F000400000000948400D63A
-:10A130000E0008C83084FFFF8E0500040220302185
-:10A140008FBF00188FB100148FB0001024040022BC
-:10A1500000003821000529C00A00130327BD002094
-:10A1600027BDFFE0AFB100143091FFFFAFB000108A
-:10A17000AFBF00181220001D000080218F86001C38
-:10A180008CC500002403000600053F0200051402F0
-:10A1900030E4000714830015304500FF2CA80006AA
-:10A1A0001100004D000558803C0C0800258C5A0019
-:10A1B000016C50218D4900000120000800000000C2
-:10A1C0008F8E00EC240D000111CD0059000000001D
-:10A1D000260B00013170FFFF24CA00200211202B42
-:10A1E000014030211480FFE6AF8A001C02001021DC
-:10A1F0008FBF00188FB100148FB0001003E000086B
-:10A2000027BD0020938700CE14E0003824040014FA
-:10A210000E0013C4000000008F86001C2402000101
-:10A220000A00150BAF8200EC8F8900EC24080002B5
-:10A230001128003B240400130000282100003021D5
-:10A24000240700010E001303000000000A00150B94
-:10A250008F86001C8F8700EC2405000214E5FFF6B2
-:10A26000240400120E001370000000008F8500E827
-:10A2700000403021240400120E0013030000382196
-:10A280000A00150B8F86001C8F8300EC241F00032F
-:10A29000147FFFD0260B00010E00132200000000E7
-:10A2A0008F8500E8004030212402000224040010C1
-:10A2B00000003821AF8200EC0E0013030000000004
-:10A2C0000A00150B8F86001C8F8F00EC24060002FD
-:10A2D00011E6000B000000002404001000002821FB
-:10A2E000000030210A001528240700010000282161
-:10A2F0000E001303000030210A00150B8F86001C8E
-:10A300000E00143100000000144000128F99001C50
-:10A310008F86001C240200030A00150BAF8200EC9C
-:10A320000E0014BD000000000A00150B8F86001CF3
-:10A330000E00131200000000240200022404001486
-:10A340000000282100003021000038210A001545B6
-:10A35000AF8200EC0040382124040010973800023E
-:10A36000000028210E0013033306FFFF0A00150B1F
-:10A370008F86001C8F8400C83C077FFF34E6FFFFF8
-:10A380008C8500742402000100A61824AC8300749C
-:10A3900003E00008A082000510A000362CA2008077
-:10A3A000274A04003C0B00052409008010400007E8
-:10A3B0002408008030A6000F00C540212D03008135
-:10A3C0001460000200A0482124080080AF4B003038
-:10A3D0000000000000000000000000001100000963
-:10A3E00000003821014030218C8D000024E700045A
-:10A3F00000E8602BACCD0000248400041580FFFA37
-:10A4000024C600040000000000000000000000005E
-:10A410003C0E0006010E3825AF470030000000005A
-:10A4200000000000000000008F4F000031E8001025
-:10A430001100FFFD000000008F42003C8F43003CF4
-:10A440000049C8210323C02B1300000400000000B2
-:10A450008F4C003825860001AF4600388F47003CFE
-:10A4600000A9282300E96821AF4D003C14A0FFCECD
-:10A470002CA2008003E000080000000027BDFFD0F0
-:10A480003C020002AFB100143C11000CAF45003893
-:10A49000AFB3001CAF46003C00809821AF420030B3
-:10A4A00024050088AF44002803512021AFBF0028B5
-:10A4B000AFB50024AFB40020AFB200180E00157D78
-:10A4C000AFB000103C1F08008FFF004C3C18080084
-:10A4D0008F1800642410FF8003F3A82132B9007F95
-:10A4E00002B078240018A0C0033A702100189140EF
-:10A4F00001D12021AF4F00280E00157D02542821E4
-:10A500003C0D08008DAD00502405012001B35821F9
-:10A51000316C007F01705024019A482101312021C3
-:10A520000E00157DAF4A00283C0808008D08005435
-:10A530003C0508008CA500640113382130E6007F3B
-:10A5400000F0182400DA202100912021AF430028D8
-:10A550000E00157D000529403C0208008C42005881
-:10A560003C1008008E1000601200001C005388216F
-:10A570002415FF800A0016003C14000C3226007FD0
-:10A580000235182400DA202102402821AF43002898
-:10A59000009420210E00157D2610FFC01200000F30
-:10A5A000023288212E05004110A0FFF42412100071
-:10A5B0003226007F001091800235182400DA202115
-:10A5C00002402821AF430028009420210E00157D71
-:10A5D000000080211600FFF3023288213C0B0800A6
-:10A5E0008D6B005C240AFF8024050002017340216A
-:10A5F000010A4824AF4900283C0408009484006202
-:10A600003110007F021A88213C07000C0E000CCA92
-:10A610000227982100402821026020218FBF0028B6
-:10A620008FB500248FB400208FB3001C8FB20018A8
-:10A630008FB100148FB000100A00157D27BD0030C7
-:10A640008F83001C8C620004104000030000000097
-:10A6500003E00008000000008C6400108C65000816
-:08A660000A0015B68C66000C1F
-:08A66800000000000000001BCF
-:10A670000000000F0000000A0000000800000006B3
-:10A6800000000005000000050000000400000004B8
-:10A6900000000003000000030000000300000003AE
-:10A6A00000000003000000020000000200000002A1
-:10A6B0000000000200000002000000020000000292
-:10A6C0000000000200000002000000020000000282
-:10A6D0000000000200000002000000020000000272
-:0CA6E0000000000100000001000000016B
-:04A6EC0008000F58FB
-:10A6F00008000DB008000FEC0800109408000F804F
-:10A7000008000FC0080011CC08000DCC080011F0A3
-:10A7100008000E1C08001634080015DC08000DCCDB
-:10A7200008000DCC08000DCC0800127C0800127C3B
-:10A7300008000DCC08000DCC0800158008000DCCD9
-:10A7400008000DCC08000DCC08000DCC080013F05B
-:10A7500008000DCC08000DCC08000DCC08000DCC75
-:10A7600008000DCC08000DCC08000DCC08000DCC65
-:10A7700008000DCC08000DCC08000DCC08000DCC55
-:10A7800008000DCC08000DCC08000FE008000DCC2F
-:10A7900008000DCC0800153008000DCC08000DCCC9
-:10A7A00008000DCC08000DCC08000DCC08000DCC25
-:10A7B00008000DCC08000DCC08000DCC08000DCC15
-:10A7C00008000DCC08000DCC08000DCC08000DCC05
-:10A7D00008000DCC08000DCC08000DCC0800145C5E
-:10A7E00008000DCC08000DCC08001370080012E022
-:10A7F00008002E9408002E9C08002E6408002E707D
-:10A8000008002E7C08002E88080046B408003F008F
-:10A8100008004634080046B4080046B4080044B4B2
-:10A82000080046B4080046FC08005524080054E41B
-:10A83000080054B008005484080054600800541CF8
-:10A840000A000C7600000000000000000000000D6F
-:10A85000727870352E302E306A3600000500000305
-:10A8600000000000000000010000000000000000E7
-:10A8700000000000000000000000000000000000D8
-:10A8800000000000000000000000000000000000C8
-:10A8900000000000000000000000000000000000B8
-:10A8A00000000000000000000000000000000000A8
-:10A8B0000000000000000000000000000000000098
-:10A8C0000000000000000000000000000000000088
-:10A8D0000000000000000000000000000000000078
-:10A8E0000000000000000000000000000000000068
-:10A8F0000000000000000000000000000000000058
-:10A900000000000000000000000000000000000047
-:10A910000000000000000000000000000000000037
-:10A920000000000000000000000000000000000027
-:10A930000000000000000000000000000000000017
-:10A940000000000000000000000000000000000007
-:10A9500000000000000000000000000000000000F7
-:10A9600000000000000000000000000000000000E7
-:10A9700000000000000000000000000000000000D7
-:10A9800000000000000000000000000000000000C7
-:10A9900000000000000000000000000000000000B7
-:10A9A00000000000000000000000000000000000A7
-:10A9B0000000000000000000000000000000000097
-:10A9C0000000000000000000000000000000000087
-:10A9D0000000000000000000000000000000000077
-:10A9E0000000000000000000000000000000000067
-:10A9F0000000000000000000000000000000000057
-:10AA00000000000000000000000000000000000046
-:10AA10000000000000000000000000000000000036
-:10AA20000000000000000000000000000000000026
-:10AA30000000000000000000000000000000000016
-:10AA40000000000000000000000000000000000006
-:10AA500000000000000000000000000000000000F6
-:10AA600000000000000000000000000000000000E6
-:10AA700000000000000000000000000000000000D6
-:10AA800000000000000000000000000000000000C6
-:10AA900000000000000000000000000000000000B6
-:10AAA00000000000000000000000000000000000A6
-:10AAB0000000000000000000000000000000000096
-:10AAC0000000000000000000000000000000000086
-:10AAD0000000000000000000000000000000000076
-:10AAE0000000000000000000000000000000000066
-:10AAF0000000000000000000000000000000000056
-:10AB00000000000000000000000000000000000045
-:10AB10000000000000000000000000000000000035
-:10AB20000000000000000000000000000000000025
-:10AB30000000000000000000000000000000000015
-:10AB40000000000000000000000000000000000005
-:10AB500000000000000000000000000000000000F5
-:10AB600000000000000000000000000000000000E5
-:10AB700000000000000000000000000000000000D5
-:10AB800000000000000000000000000000000000C5
-:10AB900000000000000000000000000000000000B5
-:10ABA00000000000000000000000000000000000A5
-:10ABB0000000000000000000000000000000000095
-:10ABC0000000000000000000000000000000000085
-:10ABD0000000000000000000000000000000000075
-:10ABE0000000000000000000000000000000000065
-:10ABF0000000000000000000000000000000000055
-:10AC00000000000000000000000000000000000044
-:10AC10000000000000000000000000000000000034
-:10AC20000000000000000000000000000000000024
-:10AC30000000000000000000000000000000000014
-:10AC40000000000000000000000000000000000004
-:10AC500000000000000000000000000000000000F4
-:10AC600000000000000000000000000000000000E4
-:10AC700000000000000000000000000000000000D4
-:10AC800000000000000000000000000000000000C4
-:10AC900000000000000000000000000000000000B4
-:10ACA00000000000000000000000000000000000A4
-:10ACB0000000000000000000000000000000000094
-:10ACC0000000000000000000000000000000000084
-:10ACD0000000000000000000000000000000000074
-:10ACE0000000000000000000000000000000000064
-:10ACF0000000000000000000000000000000000054
-:10AD00000000000000000000000000000000000043
-:10AD10000000000000000000000000000000000033
-:10AD20000000000000000000000000000000000023
-:10AD30000000000000000000000000000000000013
-:10AD40000000000000000000000000000000000003
-:10AD500000000000000000000000000000000000F3
-:10AD600000000000000000000000000000000000E3
-:10AD700000000000000000000000000000000000D3
-:10AD800000000000000000000000000000000000C3
-:10AD900000000000000000000000000000000000B3
-:10ADA00000000000000000000000000000000000A3
-:10ADB0000000000000000000000000000000000093
-:10ADC0000000000000000000000000000000000083
-:10ADD0000000000000000000000000000000000073
-:10ADE0000000000000000000000000000000000063
-:10ADF0000000000000000000000000000000000053
-:10AE00000000000000000000000000000000000042
-:10AE10000000000000000000000000000000000032
-:10AE20000000000000000000000000000000000022
-:10AE30000000000000000000000000000000000012
-:10AE40000000000000000000000000000000000002
-:10AE500000000000000000000000000000000000F2
-:10AE600000000000000000000000000000000000E2
-:10AE700000000000000000000000000000000000D2
-:10AE800000000000000000000000000000000000C2
-:10AE900000000000000000000000000000000000B2
-:10AEA00000000000000000000000000000000000A2
-:10AEB0000000000000000000000000000000000092
-:10AEC0000000000000000000000000000000000082
-:10AED0000000000000000000000000000000000072
-:10AEE0000000000000000000000000000000000062
-:10AEF0000000000000000000000000000000000052
-:10AF00000000000000000000000000000000000041
-:10AF10000000000000000000000000000000000031
-:10AF20000000000000000000000000000000000021
-:10AF30000000000000000000000000000000000011
-:10AF40000000000000000000000000000000000001
-:10AF500000000000000000000000000000000000F1
-:10AF600000000000000000000000000000000000E1
-:10AF700000000000000000000000000000000000D1
-:10AF800000000000000000000000000000000000C1
-:10AF900000000000000000000000000000000000B1
-:10AFA00000000000000000000000000000000000A1
-:10AFB0000000000000000000000000000000000091
-:10AFC0000000000000000000000000000000000081
-:10AFD0000000000000000000000000000000000071
-:10AFE0000000000000000000000000000000000061
-:10AFF0000000000000000000000000000000000051
-:10B000000000000000000000000000000000000040
-:10B010000000000000000000000000000000000030
-:10B020000000000000000000000000000000000020
-:10B030000000000000000000000000000000000010
-:10B040000000000000000000000000000000000000
-:10B0500000000000000000000000000000000000F0
-:10B0600000000000000000000000000000000000E0
-:10B0700000000000000000000000000000000000D0
-:10B0800000000000000000000000000000000000C0
-:10B0900000000000000000000000000000000000B0
-:10B0A00000000000000000000000000000000000A0
-:10B0B0000000000000000000000000000000000090
-:10B0C0000000000000000000000000000000000080
-:10B0D0000000000000000000000000000000000070
-:10B0E0000000000000000000000000000000000060
-:10B0F0000000000000000000000000000000000050
-:10B10000000000000000000000000000000000003F
-:10B11000000000000000000000000000000000002F
-:10B12000000000000000000000000000000000001F
-:10B13000000000000000000000000000000000000F
-:10B1400000000000000000000000000000000000FF
-:10B1500000000000000000000000000000000000EF
-:10B1600000000000000000000000000000000000DF
-:10B1700000000000000000000000000000000000CF
-:10B1800000000000000000000000000000000000BF
-:10B1900000000000000000000000000000000000AF
-:10B1A000000000000000000000000000000000009F
-:10B1B000000000000000000000000000000000008F
-:10B1C000000000000000000000000000000000007F
-:10B1D000000000000000000000000000000000006F
-:10B1E000000000000000000000000000000000005F
-:10B1F000000000000000000000000000000000004F
-:10B20000000000000000000000000000000000003E
-:10B21000000000000000000000000000000000002E
-:10B22000000000000000000000000000000000001E
-:10B23000000000000000000000000000000000000E
-:10B2400000000000000000000000000000000000FE
-:10B2500000000000000000000000000000000000EE
-:10B2600000000000000000000000000000000000DE
-:10B2700000000000000000000000000000000000CE
-:10B2800000000000000000000000000000000000BE
-:10B2900000000000000000000000000000000000AE
-:10B2A000000000000000000000000000000000009E
-:10B2B000000000000000000000000000000000008E
-:10B2C000000000000000000000000000000000007E
-:10B2D000000000000000000000000000000000006E
-:10B2E000000000000000000000000000000000005E
-:10B2F000000000000000000000000000000000004E
-:10B30000000000000000000000000000000000003D
-:10B31000000000000000000000000000000000002D
-:10B32000000000000000000000000000000000001D
-:10B33000000000000000000000000000000000000D
-:10B3400000000000000000000000000000000000FD
-:10B3500000000000000000000000000000000000ED
-:10B3600000000000000000000000000000000000DD
-:10B3700000000000000000000000000000000000CD
-:10B3800000000000000000000000000000000000BD
-:10B3900000000000000000000000000000000000AD
-:10B3A000000000000000000000000000000000009D
-:10B3B000000000000000000000000000000000008D
-:10B3C000000000000000000000000000000000007D
-:10B3D000000000000000000000000000000000006D
-:10B3E000000000000000000000000000000000005D
-:10B3F000000000000000000000000000000000004D
-:10B40000000000000000000000000000000000003C
-:10B41000000000000000000000000000000000002C
-:10B42000000000000000000000000000000000001C
-:10B43000000000000000000000000000000000000C
-:10B4400000000000000000000000000000000000FC
-:10B4500000000000000000000000000000000000EC
-:10B4600000000000000000000000000000000000DC
-:10B4700000000000000000000000000000000000CC
-:10B4800000000000000000000000000000000000BC
-:10B4900000000000000000000000000000000000AC
-:10B4A000000000000000000000000000000000009C
-:10B4B000000000000000000000000000000000008C
-:10B4C000000000000000000000000000000000007C
-:10B4D000000000000000000000000000000000006C
-:10B4E000000000000000000000000000000000005C
-:10B4F000000000000000000000000000000000004C
-:10B50000000000000000000000000000000000003B
-:10B51000000000000000000000000000000000002B
-:10B52000000000000000000000000000000000001B
-:10B53000000000000000000000000000000000000B
-:10B5400000000000000000000000000000000000FB
-:10B5500000000000000000000000000000000000EB
-:10B5600000000000000000000000000000000000DB
-:10B5700000000000000000000000000000000000CB
-:10B5800000000000000000000000000000000000BB
-:10B5900000000000000000000000000000000000AB
-:10B5A000000000000000000000000000000000009B
-:10B5B000000000000000000000000000000000008B
-:10B5C000000000000000000000000000000000007B
-:10B5D000000000000000000000000000000000006B
-:10B5E000000000000000000000000000000000005B
-:10B5F000000000000000000000000000000000004B
-:10B60000000000000000000000000000000000003A
-:10B61000000000000000000000000000000000002A
-:10B62000000000000000000000000000000000001A
-:10B63000000000000000000000000000000000000A
-:10B6400000000000000000000000000000000000FA
-:10B6500000000000000000000000000000000000EA
-:10B6600000000000000000000000000000000000DA
-:10B6700000000000000000000000000000000000CA
-:10B6800000000000000000000000000000000000BA
-:10B6900000000000000000000000000000000000AA
-:10B6A000000000000000000000000000000000009A
-:10B6B000000000000000000000000000000000008A
-:10B6C000000000000000000000000000000000007A
-:10B6D000000000000000000000000000000000006A
-:10B6E000000000000000000000000000000000005A
-:10B6F000000000000000000000000000000000004A
-:10B700000000000000000000000000000000000039
-:10B710000000000000000000000000000000000029
-:10B720000000000000000000000000000000000019
-:10B730000000000000000000000000000000000009
-:10B7400000000000000000000000000000000000F9
-:10B7500000000000000000000000000000000000E9
-:10B7600000000000000000000000000000000000D9
-:10B7700000000000000000000000000000000000C9
-:10B7800000000000000000000000000000000000B9
-:10B7900000000000000000000000000000000000A9
-:10B7A0000000000000000000000000000000000099
-:10B7B0000000000000000000000000000000000089
-:10B7C0000000000000000000000000000000000079
-:10B7D0000000000000000000000000000000000069
-:10B7E0000000000000000000000000000000000059
-:10B7F0000000000000000000000000000000000049
-:10B800000000000000000000000000000000000038
-:10B810000000000000000000000000000000000028
-:10B820000000000000000000000000000000000018
-:10B830000000000000000000000000000000000008
-:10B8400000000000000000000000000000000000F8
-:10B8500000000000000000000000000000000000E8
-:10B8600000000000000000000000000000000000D8
-:10B8700000000000000000000000000000000000C8
-:10B8800000000000000000000000000000000000B8
-:10B8900000000000000000000000000000000000A8
-:10B8A0000000000000000000000000000000000098
-:10B8B0000000000000000000000000000000000088
-:10B8C0000000000000000000000000000000000078
-:10B8D0000000000000000000000000000000000068
-:10B8E0000000000000000000000000000000000058
-:10B8F0000000000000000000000000000000000048
-:10B900000000000000000000000000000000000037
-:10B910000000000000000000000000000000000027
-:10B920000000000000000000000000000000000017
-:10B930000000000000000000000000000000000007
-:10B9400000000000000000000000000000000000F7
-:10B9500000000000000000000000000000000000E7
-:10B9600000000000000000000000000000000000D7
-:10B9700000000000000000000000000000000000C7
-:10B9800000000000000000000000000000000000B7
-:10B9900000000000000000000000000000000000A7
-:10B9A0000000000000000000000000000000000097
-:10B9B0000000000000000000000000000000000087
-:10B9C0000000000000000000000000000000000077
-:10B9D0000000000000000000000000000000000067
-:10B9E0000000000000000000000000000000000057
-:10B9F0000000000000000000000000000000000047
-:10BA00000000000000000000000000000000000036
-:10BA10000000000000000000000000000000000026
-:10BA20000000000000000000000000000000000016
-:10BA30000000000000000000000000000000000006
-:10BA400000000000000000000000000000000000F6
-:10BA500000000000000000000000000000000000E6
-:10BA600000000000000000000000000000000000D6
-:10BA700000000000000000000000000000000000C6
-:10BA800000000000000000000000000000000000B6
-:10BA900000000000000000000000000000000000A6
-:10BAA0000000000000000000000000000000000096
-:10BAB0000000000000000000000000000000000086
-:10BAC0000000000000000000000000000000000076
-:10BAD0000000000000000000000000000000000066
-:10BAE0000000000000000000000000000000000056
-:10BAF0000000000000000000000000000000000046
-:10BB00000000000000000000000000000000000035
-:10BB10000000000000000000000000000000000025
-:10BB20000000000000000000000000000000000015
-:10BB30000000000000000000000000000000000005
-:10BB400000000000000000000000000000000000F5
-:10BB500000000000000000000000000000000000E5
-:10BB600000000000000000000000000000000000D5
-:10BB700000000000000000000000000000000000C5
-:10BB800000000000000000000000000000000000B5
-:10BB900000000000000000000000000000000000A5
-:10BBA0000000000000000000000000000000000095
-:10BBB0000000000000000000000000000000000085
-:10BBC0000000000000000000000000000000000075
-:10BBD0000000000000000000000000000000000065
-:10BBE0000000000000000000000000000000000055
-:10BBF0000000000000000000000000000000000045
-:10BC00000000000000000000000000000000000034
-:10BC10000000000000000000000000000000000024
-:10BC20000000000000000000000000000000000014
-:10BC30000000000000000000000000000000000004
-:10BC400000000000000000000000000000000000F4
-:10BC500000000000000000000000000000000000E4
-:10BC600000000000000000000000000000000000D4
-:10BC700000000000000000000000000000000000C4
-:10BC800000000000000000000000000000000000B4
-:10BC900000000000000000000000000000000000A4
-:10BCA0000000000000000000000000000000000094
-:10BCB0000000000000000000000000000000000084
-:10BCC0000000000000000000000000000000000074
-:10BCD0000000000000000000000000000000000064
-:10BCE0000000000000000000000000000000000054
-:10BCF0000000000000000000000000000000000044
-:10BD00000000000000000000000000000000000033
-:10BD10000000000000000000000000000000000023
-:10BD20000000000000000000000000000000000013
-:10BD30000000000000000000000000000000000003
-:10BD400000000000000000000000000000000000F3
-:10BD500000000000000000000000000000000000E3
-:10BD600000000000000000000000000000000000D3
-:10BD700000000000000000000000000000000000C3
-:10BD800000000000000000000000000000000000B3
-:10BD900000000000000000000000000000000000A3
-:10BDA0000000000000000000000000000000000093
-:10BDB0000000000000000000000000000000000083
-:10BDC0000000000000000000000000000000000073
-:10BDD0000000000000000000000000000000000063
-:10BDE0000000000000000000000000000000000053
-:10BDF0000000000000000000000000000000000043
-:10BE00000000000000000000000000000000000032
-:10BE10000000000000000000000000000000000022
-:10BE20000000000000000000000000000000000012
-:10BE30000000000000000000000000000000000002
-:10BE400000000000000000000000000000000000F2
-:10BE500000000000000000000000000000000000E2
-:10BE600000000000000000000000000000000000D2
-:10BE700000000000000000000000000000000000C2
-:10BE800000000000000000000000000000000000B2
-:10BE900000000000000000000000000000000000A2
-:10BEA0000000000000000000000000000000000092
-:10BEB0000000000000000000000000000000000082
-:10BEC0000000000000000000000000000000000072
-:10BED0000000000000000000000000000000000062
-:10BEE0000000000000000000000000000000000052
-:10BEF0000000000000000000000000000000000042
-:10BF00000000000000000000000000000000000031
-:10BF10000000000000000000000000000000000021
-:10BF20000000000000000000000000000000000011
-:10BF30000000000000000000000000000000000001
-:10BF400000000000000000000000000000000000F1
-:10BF500000000000000000000000000000000000E1
-:10BF600000000000000000000000000000000000D1
-:10BF700000000000000000000000000000000000C1
-:10BF800000000000000000000000000000000000B1
-:10BF900000000000000000000000000000000000A1
-:10BFA0000000000000000000000000000000000091
-:10BFB0000000000000000000000000000000000081
-:10BFC0000000000000000000000000000000000071
-:10BFD0000000000000000000000000000000000061
-:10BFE0000000000000000000000000000000000051
-:10BFF0000000000000000000000000000000000041
-:10C000000000000000000000000000000000000030
-:10C010000000000000000000000000000000000020
-:10C020000000000000000000000000000000000010
-:10C030000000000000000000000000000000000000
-:10C0400000000000000000000000000000000000F0
-:10C0500000000000000000000000000000000000E0
-:10C0600000000000000000000000000000000000D0
-:10C0700000000000000000000000000000000000C0
-:10C0800000000000000000000000000000000000B0
-:10C0900000000000000000000000000000000000A0
-:10C0A0000000000000000000000000000000000090
-:10C0B0000000000000000000000000000000000080
-:10C0C0000000000000000000000000000000000070
-:10C0D0000000000000000000000000000000000060
-:10C0E0000000000000000000000000000000000050
-:10C0F0000000000000000000000000000000000040
-:10C10000000000000000000000000000000000002F
-:10C11000000000000000000000000000000000001F
-:10C12000000000000000000000000000000000000F
-:10C1300000000000000000000000000000000000FF
-:10C1400000000000000000000000000000000000EF
-:10C1500000000000000000000000000000000000DF
-:10C1600000000000000000000000000000000000CF
-:10C1700000000000000000000000000000000000BF
-:10C1800000000000000000000000000000000000AF
-:10C19000000000000000000000000000000000009F
-:10C1A000000000000000000000000000000000008F
-:10C1B000000000000000000000000000000000007F
-:10C1C000000000000000000000000000000000006F
-:10C1D000000000000000000000000000000000005F
-:10C1E000000000000000000000000000000000004F
-:10C1F000000000000000000000000000000000003F
-:10C20000000000000000000000000000000000002E
-:10C21000000000000000000000000000000000001E
-:10C22000000000000000000000000000000000000E
-:10C2300000000000000000000000000000000000FE
-:10C2400000000000000000000000000000000000EE
-:10C2500000000000000000000000000000000000DE
-:10C2600000000000000000000000000000000000CE
-:10C2700000000000000000000000000000000000BE
-:10C2800000000000000000000000000000000000AE
-:10C29000000000000000000000000000000000009E
-:10C2A000000000000000000000000000000000008E
-:10C2B000000000000000000000000000000000007E
-:10C2C000000000000000000000000000000000006E
-:10C2D000000000000000000000000000000000005E
-:10C2E000000000000000000000000000000000004E
-:10C2F000000000000000000000000000000000003E
-:10C30000000000000000000000000000000000002D
-:10C31000000000000000000000000000000000001D
-:10C32000000000000000000000000000000000000D
-:10C3300000000000000000000000000000000000FD
-:10C3400000000000000000000000000000000000ED
-:10C3500000000000000000000000000000000000DD
-:10C3600000000000000000000000000000000000CD
-:10C3700000000000000000000000000000000000BD
-:10C3800000000000000000000000000000000000AD
-:10C39000000000000000000000000000000000009D
-:10C3A000000000000000000000000000000000008D
-:10C3B000000000000000000000000000000000007D
-:10C3C000000000000000000000000000000000006D
-:10C3D000000000000000000000000000000000005D
-:10C3E000000000000000000000000000000000004D
-:10C3F000000000000000000000000000000000003D
-:10C40000000000000000000000000000000000002C
-:10C41000000000000000000000000000000000001C
-:10C42000000000000000000000000000000000000C
-:10C4300000000000000000000000000000000000FC
-:10C4400000000000000000000000000000000000EC
-:10C4500000000000000000000000000000000000DC
-:10C4600000000000000000000000000000000000CC
-:10C4700000000000000000000000000000000000BC
-:10C4800000000000000000000000000000000000AC
-:10C49000000000000000000000000000000000009C
-:10C4A000000000000000000000000000000000008C
-:10C4B000000000000000000000000000000000007C
-:10C4C000000000000000000000000000000000006C
-:10C4D000000000000000000000000000000000005C
-:10C4E000000000000000000000000000000000004C
-:10C4F000000000000000000000000000000000003C
-:10C50000000000000000000000000000000000002B
-:10C51000000000000000000000000000000000001B
-:10C52000000000000000000000000000000000000B
-:10C5300000000000000000000000000000000000FB
-:10C5400000000000000000000000000000000000EB
-:10C5500000000000000000000000000000000000DB
-:10C5600000000000000000000000000000000000CB
-:10C5700000000000000000000000000000000000BB
-:10C5800000000000000000000000000000000000AB
-:10C59000000000000000000000000000000000009B
-:10C5A000000000000000000000000000000000008B
-:10C5B000000000000000000000000000000000007B
-:10C5C000000000000000000000000000000000006B
-:10C5D000000000000000000000000000000000005B
-:10C5E000000000000000000000000000000000004B
-:10C5F000000000000000000000000000000000003B
-:10C60000000000000000000000000000000000002A
-:10C61000000000000000000000000000000000001A
-:10C62000000000000000000000000000000000000A
-:10C6300000000000000000000000000000000000FA
-:10C6400000000000000000000000000000000000EA
-:10C6500000000000000000000000000000000000DA
-:10C6600000000000000000000000000000000000CA
-:10C6700000000000000000000000000000000000BA
-:10C6800000000000000000000000000000000000AA
-:10C69000000000000000000000000000000000009A
-:10C6A000000000000000000000000000000000008A
-:10C6B000000000000000000000000000000000007A
-:10C6C000000000000000000000000000000000006A
-:10C6D000000000000000000000000000000000005A
-:10C6E000000000000000000000000000000000004A
-:10C6F000000000000000000000000000000000003A
-:10C700000000000000000000000000000000000029
-:10C710000000000000000000000000000000000019
-:10C720000000000000000000000000000000000009
-:10C7300000000000000000000000000000000000F9
-:10C7400000000000000000000000000000000000E9
-:10C7500000000000000000000000000000000000D9
-:10C7600000000000000000000000000000000000C9
-:10C7700000000000000000000000000000000000B9
-:10C7800000000000000000000000000000000000A9
-:10C790000000000000000000000000000000000099
-:10C7A0000000000000000000000000000000000089
-:10C7B0000000000000000000000000000000000079
-:10C7C0000000000000000000000000000000000069
-:10C7D0000000000000000000000000000000000059
-:10C7E0000000000000000000000000000000000049
-:10C7F0000000000000000000000000000000000039
-:10C800000000000000000000000000000000000028
-:10C810000000000000000000000000000000000018
-:10C820000000000000000000000000000000000008
-:10C8300000000000000000000000000000000000F8
-:10C8400000000000000000000000000000000000E8
-:10C8500000000000000000000000000000000000D8
-:10C8600000000000000000000000000000000000C8
-:10C8700000000000000000000000000000000000B8
-:10C8800000000000000000000000000000000000A8
-:10C890000000000000000000000000000000000098
-:10C8A0000000000000000000000000000000000088
-:10C8B0000000000000000000000000000000000078
-:10C8C0000000000000000000000000000000000068
-:10C8D0000000000000000000000000000000000058
-:10C8E0000000000000000000000000000000000048
-:10C8F0000000000000000000000000000000000038
-:10C900000000000000000000000000000000000027
-:10C910000000000000000000000000000000000017
-:10C920000000000000000000000000000000000007
-:10C9300000000000000000000000000000000000F7
-:10C9400000000000000000000000000000000000E7
-:10C9500000000000000000000000000000000000D7
-:10C9600000000000000000000000000000000000C7
-:10C9700000000000000000000000000000000000B7
-:10C9800000000000000000000000000000000000A7
-:10C990000000000000000000000000000000000097
-:10C9A0000000000000000000000000000000000087
-:10C9B0000000000000000000000000000000000077
-:10C9C0000000000000000000000000000000000067
-:10C9D0000000000000000000000000000000000057
-:10C9E0000000000000000000000000000000000047
-:10C9F0000000000000000000000000000000000037
-:10CA00000000000000000000000000000000000026
-:10CA10000000000000000000000000000000000016
-:10CA20000000000000000000000000000000000006
-:10CA300000000000000000000000000000000000F6
-:10CA400000000000000000000000000000000000E6
-:10CA500000000000000000000000000000000000D6
-:10CA600000000000000000000000000000000000C6
-:10CA700000000000000000000000000000000000B6
-:10CA800000000000000000000000000000000000A6
-:10CA90000000000000000000000000000000000096
-:10CAA0000000000000000000000000000000000086
-:10CAB0000000000000000000000000000000000076
-:10CAC0000000000000000000000000000000000066
-:10CAD0000000000000000000000000000000000056
-:10CAE0000000000000000000000000000000000046
-:10CAF0000000000000000000000000000000000036
-:10CB00000000000000000000000000000000000025
-:10CB10000000000000000000000000000000000015
-:10CB20000000000000000000000000000000000005
-:10CB300000000000000000000000000000000000F5
-:10CB400000000000000000000000000000000000E5
-:10CB500000000000000000000000000000000000D5
-:10CB600000000000000000000000000000000000C5
-:10CB700000000000000000000000000000000000B5
-:10CB800000000000000000000000000000000000A5
-:10CB90000000000000000000000000000000000095
-:10CBA0000000000000000000000000000000000085
-:10CBB0000000000000000000000000000000000075
-:10CBC0000000000000000000000000000000000065
-:10CBD0000000000000000000000000000000000055
-:10CBE0000000000000000000000000000000000045
-:10CBF0000000000000000000000000000000000035
-:10CC00000000000000000000000000000000000024
-:10CC10000000000000000000000000000000000014
-:10CC20000000000000000000000000000000000004
-:10CC300000000000000000000000000000000000F4
-:10CC400000000000000000000000000000000000E4
-:10CC500000000000000000000000000000000000D4
-:10CC600000000000000000000000000000000000C4
-:10CC700000000000000000000000000000000000B4
-:10CC800000000000000000000000000000000000A4
-:10CC90000000000000000000000000000000000094
-:10CCA0000000000000000000000000000000000084
-:10CCB0000000000000000000000000000000000074
-:10CCC0000000000000000000000000000000000064
-:10CCD0000000000000000000000000000000000054
-:10CCE0000000000000000000000000000000000044
-:10CCF0000000000000000000000000000000000034
-:10CD00000000000000000000000000000000000023
-:10CD10000000000000000000000000000000000013
-:10CD20000000000000000000000000000000000003
-:10CD300000000000000000000000000000000000F3
-:10CD400000000000000000000000000000000000E3
-:10CD500000000000000000000000000000000000D3
-:10CD600000000000000000000000000000000000C3
-:10CD700000000000000000000000000000000000B3
-:10CD800000000000000000000000000000000000A3
-:10CD90000000000000000000000000000000000093
-:10CDA0000000000000000000000000000000000083
-:10CDB0000000000000000000000000000000000073
-:10CDC0000000000000000000000000000000000063
-:10CDD0000000000000000000000000000000000053
-:10CDE0000000000000000000000000000000000043
-:10CDF0000000000000000000000000000000000033
-:10CE00000000000000000000000000000000000022
-:10CE10000000000000000000000000000000000012
-:10CE20000000000000000000000000000000000002
-:10CE300000000000000000000000000000000000F2
-:10CE400000000000000000000000000000000000E2
-:10CE500000000000000000000000000000000000D2
-:10CE600000000000000000000000000000000000C2
-:10CE700000000000000000000000000000000000B2
-:10CE800000000000000000000000000000000000A2
-:10CE90000000000000000000000000000000000092
-:10CEA0000000000000000000000000000000000082
-:10CEB0000000000000000000000000000000000072
-:10CEC0000000000000000000000000000000000062
-:10CED0000000000000000000000000000000000052
-:10CEE0000000000000000000000000000000000042
-:10CEF0000000000000000000000000000000000032
-:10CF00000000000000000000000000000000000021
-:10CF10000000000000000000000000000000000011
-:10CF20000000000000000000000000000000000001
-:10CF300000000000000000000000000000000000F1
-:10CF400000000000000000000000000000000000E1
-:10CF500000000000000000000000000000000000D1
-:10CF600000000000000000000000000000000000C1
-:10CF700000000000000000000000000000000000B1
-:10CF800000000000000000000000000000000000A1
-:10CF90000000000000000000000000000000000091
-:10CFA0000000000000000000000000000000000081
-:10CFB0000000000000000000000000000000000071
-:10CFC0000000000000000000000000000000000061
-:10CFD0000000000000000000000000000000000051
-:10CFE0000000000000000000000000000000000041
-:10CFF0000000000000000000000000000000000031
-:10D000000000000000000000000000000000000020
-:10D010000000000000000000000000000000000010
-:10D020000000000000000000000000000000000000
-:10D0300000000000000000000000000000000000F0
-:10D0400000000000000000000000000000000000E0
-:10D0500000000000000000000000000000000000D0
-:10D0600000000000000000000000000000000000C0
-:10D0700000000000000000000000000000000000B0
-:10D0800000000000000000000000000000000000A0
-:10D090000000000000000000000000000000000090
-:10D0A0000000000000000000000000000000000080
-:10D0B0000000000000000000000000000000000070
-:10D0C0000000000000000000000000000000000060
-:10D0D0000000000000000000000000000000000050
-:10D0E0000000000000000000000000000000000040
-:10D0F0000000000000000000000000000000000030
-:10D10000000000000000000000000000000000001F
-:10D11000000000000000000000000000000000000F
-:10D1200000000000000000000000000000000000FF
-:10D1300000000000000000000000000000000000EF
-:10D1400000000000000000000000000000000000DF
-:10D1500000000000000000000000000000000000CF
-:10D1600000000000000000000000000000000000BF
-:10D1700000000000000000000000000000000000AF
-:10D18000000000000000000000000000000000009F
-:10D19000000000000000000000000000000000008F
-:10D1A000000000000000000000000000000000007F
-:10D1B000000000000000000000000000000000006F
-:10D1C000000000000000000000000000000000005F
-:10D1D000000000000000000000000000000000004F
-:10D1E000000000000000000000000000000000003F
-:10D1F000000000000000000000000000000000002F
-:10D20000000000000000000000000000000000001E
-:10D21000000000000000000000000000000000000E
-:10D2200000000000000000000000000000000000FE
-:10D2300000000000000000000000000000000000EE
-:10D2400000000000000000000000000000000000DE
-:10D2500000000000000000000000000000000000CE
-:10D2600000000000000000000000000000000000BE
-:10D2700000000000000000000000000000000000AE
-:10D28000000000000000000000000000000000009E
-:10D29000000000000000000000000000000000008E
-:10D2A000000000000000000000000000000000007E
-:10D2B000000000000000000000000000000000006E
-:10D2C000000000000000000000000000000000005E
-:10D2D000000000000000000000000000000000004E
-:10D2E000000000000000000000000000000000003E
-:10D2F000000000000000000000000000000000002E
-:10D30000000000000000000000000000000000001D
-:10D31000000000000000000000000000000000000D
-:10D3200000000000000000000000000000000000FD
-:10D3300000000000000000000000000000000000ED
-:10D3400000000000000000000000000000000000DD
-:10D3500000000000000000000000000000000000CD
-:10D3600000000000000000000000000000000000BD
-:10D3700000000000000000000000000000000000AD
-:10D38000000000000000000000000000000000009D
-:10D39000000000000000000000000000000000008D
-:10D3A000000000000000000000000000000000007D
-:10D3B000000000000000000000000000000000006D
-:10D3C000000000000000000000000000000000005D
-:10D3D000000000000000000000000000000000004D
-:10D3E000000000000000000000000000000000003D
-:10D3F000000000000000000000000000000000002D
-:10D40000000000000000000000000000000000001C
-:10D41000000000000000000000000000000000000C
-:10D4200000000000000000000000000000000000FC
-:10D4300000000000000000000000000000000000EC
-:10D4400000000000000000000000000000000000DC
-:10D4500000000000000000000000000000000000CC
-:10D4600000000000000000000000000000000000BC
-:10D4700000000000000000000000000000000000AC
-:10D48000000000000000000000000000000000009C
-:10D49000000000000000000000000000000000008C
-:10D4A000000000000000000000000000000000007C
-:10D4B000000000000000000000000000000000006C
-:10D4C000000000000000000000000000000000005C
-:10D4D000000000000000000000000000000000004C
-:10D4E000000000000000000000000000000000003C
-:10D4F000000000000000000000000000000000002C
-:10D50000000000000000000000000000000000001B
-:10D51000000000000000000000000000000000000B
-:10D5200000000000000000000000000000000000FB
-:10D5300000000000000000000000000000000000EB
-:10D5400000000000000000000000000000000000DB
-:10D5500000000000000000000000000000000000CB
-:10D5600000000000000000000000000000000000BB
-:10D5700000000000000000000000000000000000AB
-:10D58000000000000000000000000000000000009B
-:10D59000000000000000000000000000000000008B
-:10D5A000000000000000000000000000000000007B
-:10D5B000000000000000000000000000000000006B
-:10D5C000000000000000000000000000000000005B
-:10D5D000000000000000000000000000000000004B
-:10D5E000000000000000000000000000000000003B
-:10D5F000000000000000000000000000000000002B
-:10D60000000000000000000000000000000000001A
-:10D61000000000000000000000000000000000000A
-:10D6200000000000000000000000000000000000FA
-:10D6300000000000000000000000000000000000EA
-:10D6400000000000000000000000000000000000DA
-:10D6500000000000000000000000000000000000CA
-:10D6600000000000000000000000000000000000BA
-:10D6700000000000000000000000000000000000AA
-:10D68000000000000000000000000000000000009A
-:10D69000000000000000000000000000000000008A
-:10D6A000000000000000000000000000000000007A
-:10D6B000000000000000000000000000000000006A
-:10D6C000000000000000000000000000000000005A
-:10D6D000000000000000000000000000000000004A
-:10D6E000000000000000000000000000000000003A
-:10D6F000000000000000000000000000000000002A
-:10D700000000000000000000000000000000000019
-:10D710000000000000000000000000000000000009
-:10D7200000000000000000000000000000000000F9
-:10D7300000000000000000000000000000000000E9
-:10D7400000000000000000000000000000000000D9
-:10D7500000000000000000000000000000000000C9
-:10D7600000000000000000000000000000000000B9
-:10D7700000000000000000000000000000000000A9
-:10D780000000000000000000000000000000000099
-:10D790000000000000000000000000000000000089
-:10D7A0000000000000000000000000000000000079
-:10D7B0000000000000000000000000000000000069
-:10D7C0000000000000000000000000000000000059
-:10D7D0000000000000000000000000000000000049
-:10D7E0000000000000000000000000000000000039
-:10D7F0000000000000000000000000000000000029
-:10D800000000000000000000000000000000000018
-:10D810000000000000000000000000000000000008
-:10D8200000000000000000000000000000000000F8
-:10D8300000000000000000000000000000000000E8
-:10D8400000000000000000000000000000000000D8
-:10D8500000000000000000000000000000000000C8
-:10D8600000000000000000000000000000000000B8
-:10D8700000000000000000000000000000000000A8
-:10D880000000000000000000000000000000000098
-:10D890000000000000000000000000000000000088
-:10D8A0000000000000000000000000000000000078
-:10D8B0000000000000000000000000000000000068
-:10D8C0000000000000000000000000000000000058
-:10D8D0000000000000000000000000000000000048
-:10D8E0000000000000000000000000000000000038
-:10D8F0000000000000000000000000000000000028
-:10D900000000000000000000000000000000000017
-:10D910000000000000000000000000000000000007
-:10D9200000000000000000000000000000000000F7
-:10D9300000000000000000000000000000000000E7
-:10D9400000000000000000000000000000000000D7
-:10D9500000000000000000000000000000000000C7
-:10D9600000000000000000000000000000000000B7
-:10D9700000000000000000000000000000000000A7
-:10D980000000000000000000000000000000000097
-:10D990000000000000000000000000000000000087
-:10D9A0000000000000000000000000000000000077
-:10D9B0000000000000000000000000000000000067
-:10D9C0000000000000000000000000000000000057
-:10D9D0000000000000000000000000000000000047
-:10D9E0000000000000000000000000000000000037
-:10D9F0000000000000000000000000000000000027
-:10DA00000000000000000000000000000000000016
-:10DA100000000000000000000000000010000003F3
-:10DA2000000000000000000D0000000D3C02080096
-:10DA3000244275803C03080024637A28AC4000002F
-:10DA40000043202B1480FFFD244200043C1D0800ED
-:10DA500037BD7FFC03A0F0213C100800261031D810
-:10DA60003C1C0800279C75800E0010EF0000000091
-:10DA70000000000D30A5FFFF30C600FF27430180E6
-:10DA80008F4201B80440FFFE24020002AC64000093
-:10DA9000A4650008A066000AA062000B3C0210000A
-:10DAA000AC67001803E00008AF4201B83C03600017
-:10DAB0008C624FF80440FFFE3C020200AC644FC091
-:10DAC000AC624FC43C02100003E00008AC624FF8A7
-:10DAD0009482000C2486001400A038210002130256
-:10DAE000000210800082402100C8102B1040005717
-:10DAF0000000000090C300002C620009504000515B
-:10DB000090C20001000310803C03080024637534B8
-:10DB1000004310218C42000000400008000000007B
-:10DB200090C300012402000A1462003A00000000C1
-:10DB3000010610232C42000A1440003624C60002BD
-:10DB40008CE2000034420100ACE2000090C2000010
-:10DB500090C3000190C4000290C5000300031C00A4
-:10DB60000002160000431025000422000044102586
-:10DB70000045102524C60004ACE2000490C2000059
-:10DB800090C3000190C4000290C50003000216007B
-:10DB900000031C000043102500042200004410254F
-:10DBA0000045102524C600040A000CAAACE20008B7
-:10DBB00090C30001240200041462001624C600026F
-:10DBC00090C2000090C400018CE30000000212002B
-:10DBD000004410253463000424C60002ACE2000CAB
-:10DBE0000A000CAAACE3000090C300012402000369
-:10DBF0001462000824C600028CE2000090C30000FA
-:10DC000024C6000134420008A0E300100A000CAA58
-:10DC1000ACE2000003E000082402000190C3000110
-:10DC2000240200021062000224C40002010020212C
-:10DC30000A000CAA008030210A000CAA24C60001A8
-:10DC400090C200010A000CAA00C2302103E00008C3
-:10DC50000000102127BDFFE8AFBF0014AFB00010D7
-:10DC60000E00130E00808021936200052403FFFE46
-:10DC700002002021004310248FBF00148FB0001039
-:10DC8000A36200050A00131727BD001827BDFFE88F
-:10DC9000AFB00010AFBF00140E000F0E0080802147
-:10DCA0009362000024030050304200FF144300043C
-:10DCB00024020100AF4201800A000D22020020214F
-:10DCC000AF400180020020218FBF00148FB00010F0
-:10DCD0000A000FAD27BD001827BDFF80AFBE00783A
-:10DCE000AFB70074AFB30064AFBF007CAFB60070D5
-:10DCF000AFB5006CAFB40068AFB20060AFB1005C0C
-:10DD0000AFB000588F5001289363003F9362000525
-:10DD10000000F021307300FF0002102730420001A4
-:10DD20000000B82114400066AFA0005093420116D5
-:10DD300093430112304200FF306300FF0342202171
-:10DD400003431021244540008F82001C104000181E
-:10DD5000249140008F4201043C0300010043102441
-:10DD600010400013000000008CA3000C8F620030F4
-:10DD7000146201B5240200018CA300108F62002CF4
-:10DD8000146201B1240200019762003A94834000BA
-:10DD90003042FFFF146201AC240200019762003898
-:10DDA000962300023042FFFF146201A72402000103
-:10DDB00093620000304300FF24020020106200053F
-:10DDC0002402005010620006000000000A000D6CE2
-:10DDD000000000000000000D0A000D75AFA000302B
-:10DDE0003C1E080027DE75E80A000D75AFA0003064
-:10DDF0003C0208008C4200DC244200013C01080087
-:10DE0000AC2200DC0E0013D8000000000A000F0353
-:10DE10008FBF007C8F4201043C0300209234000D30
-:10DE2000004310240002202B00042140AFA4003046
-:10DE30008F4301043C020040006218241460000279
-:10DE4000348700400080382132820020AFA70030A4
-:10DE50001440000234E6008000E0302110C0000BC6
-:10DE6000AFA6003093C500088F67004C0200202148
-:10DE700000052B0034A5008130A5F0810E000C8D2B
-:10DE800030C600FF0A000F00000000009362003E51
-:10DE9000304200401040000E24020004566200068A
-:10DEA00024020012020020210E0014E6022030217C
-:10DEB0000A000F038FBF007C1662000500000000FF
-:10DEC0000E000D13000020210A000F038FBF007CFD
-:10DED0009743011A9624000E9362003532850004A0
-:10DEE0003076FFFF00442004AFA400548E320004BB
-:10DEF00010A000158E3500089362003E30420040AD
-:10DF000010400007000000000E00142802402021ED
-:10DF10001040000D000000000A000F00000000008B
-:10DF20008F620044024210230440014500000000BB
-:10DF30008F6200480242102304410141240400166C
-:10DF40000A000E038FC200048F62004802421023B1
-:10DF500004400008000000003C0208008C42310030
-:10DF6000244200013C010800AC2231000A000EF5F9
-:10DF7000000000008F620040024210231840000998
-:10DF80002402000C3C0208008C423100329400FC58
-:10DF90000000B021244200013C010800AC22310005
-:10DFA0002402000CAFA200308F62004000522023F8
-:10DFB0001880000D02C4102A144001160000000051
-:10DFC0001496000602C410233A8200013042000178
-:10DFD000144001100000000002C4102302449021EC
-:10DFE0000A000DEB3056FFFF0000202132820002B4
-:10DFF0001040001A328200109362003E304200400E
-:10E00000504000118FC200040E00130E02002021A8
-:10E0100024020018A362003F936200052403FFFE60
-:10E0200002002021004310240E001317A3620005F4
-:10E0300024040039000028210E00141124060018C1
-:10E040000A000F0224020001240400170040F8090E
-:10E05000000000000A000F0224020001104000F836
-:10E06000000000008F63004C8F62005402A2102356
-:10E070001C4000F302A31023044200010060A82109
-:10E08000AFA40018AFB20010AFB600149342012045
-:10E090008F6500409763003C304200FF034210212F
-:10E0A000004410218FA400543063FFFF244240003D
-:10E0B0000083182B8FA40030AFA20020AFA500284A
-:10E0C00000832025AFA40030AFA50024AFA0002C12
-:10E0D000AFB500349362003E30420008504000115A
-:10E0E0008FC200000220202127A500380E000CA4BA
-:10E0F000AFA000385440000B8FC200008FA2003840
-:10E1000030420100504000078FC200008FA3003C46
-:10E110008F6200600062102304430001AF6300605F
-:10E120008FC200000040F80927A400108FA2003021
-:10E130003042000254400001329400FE9362003EDF
-:10E1400030420040104000378FA300148F6200540B
-:10E1500016A2001A3282000124020014126200107A
-:10E160002A62001510400006240200162402000C4A
-:10E1700012620007328200010A000E5F00000000F8
-:10E1800012620005328200010A000E5F00000000EA
-:10E190000A000E5A2417000E0A000E5A2417001007
-:10E1A0000A000E5E24170012936200232403FFBDB1
-:10E1B00000431024A36200233282000110400019A2
-:10E1C0008FA300142402000C1262000E2A62000DBC
-:10E1D000104000062402000E2402000A126200070A
-:10E1E0008FA200240A000E77244200011262000868
-:10E1F0008FA200240A000E77244200010A000E7547
-:10E20000241700082402000E16E20002241700164C
-:10E21000241700108FA2002424420001AFA2002482
-:10E220008FA300148FA200248F730040004310219D
-:10E23000AF6200408FA20054936400368F630040A9
-:10E2400002A288213402FFFF00821004006218211C
-:10E25000AF6300488FA6003030C200081040000EA7
-:10E26000000000008F6200581622000430C600FF34
-:10E270009742011A5040000134C6001093C50008AF
-:10E280008FA700340200202100052B0034A5008058
-:10E290000E000C8D30A5F0808F62004000531023DB
-:10E2A000184000178FA200183C0208008C423198D9
-:10E2B00030420010104000092402000197620068FB
-:10E2C0001440000624020001A76200689742007A09
-:10E2D0002442000A0A000EBBA7620012A7620012C5
-:10E2E0000E00130E020020219362007D2403000122
-:10E2F00002002021344200010A000EB9AFA30050F1
-:10E300001840000A000000000E00130E0200202139
-:10E310009362007D2403000102002021AFA300507E
-:10E32000344200040E001317A362007D9362003E86
-:10E33000304200401440000C328200011040000ABC
-:10E34000000000008F6300408FC200042404001806
-:10E35000246300010040F809AF6300408FA2003041
-:10E360000A000F02304200048F6200581051001062
-:10E37000000000008F620018024210231C400008B9
-:10E38000240400018F6200181642000900000000FA
-:10E390008F62001C02A21023044000050000000050
-:10E3A000AF710058AFA40050AF720018AF75001CD9
-:10E3B00012E0000B8FA200500E00130E020020216D
-:10E3C000A377003F0E0013170200202102E0302146
-:10E3D000240400370E001411000028218FA20050E1
-:10E3E00010400003000000000E000C9B02002021E2
-:10E3F00012C00005000018218FA200303042000436
-:10E400005040001100601021240300010A000F0297
-:10E41000006010210E00130E020020219362007D87
-:10E4200002002021344200040E001317A362007D75
-:10E430000E000C9B020020210A000F0224020001A2
-:10E44000AF400044240200018FBF007C8FBE0078E3
-:10E450008FB700748FB600708FB5006C8FB40068F2
-:10E460008FB300648FB200608FB1005C8FB0005832
-:10E4700003E0000827BD00808F4201B80440FFFE82
-:10E4800024020800AF4201B803E0000800000000C9
-:10E4900030A5FFFF30C6FFFF8F4201B80440FFFEEA
-:10E4A0003C020008AF44018003421021AF44002029
-:10E4B000944200483044FFFF1080001924020003FA
-:10E4C00024A200120082102B104000152402000329
-:10E4D000934201202403001AA343018B304200FF22
-:10E4E0002447FFFE8F8200000087182B386300014D
-:10E4F0000002138200431024104000058F830004A3
-:10E5000034620001A74701940A000F39AF8200046A
-:10E510002402FFFE006210240A000F39AF820004BB
-:10E52000A342018B24020002A742018C8F820000CB
-:10E530008F840004A745018EA74201908F82000CB2
-:10E5400030838000AF4201A8A74601881060000E0A
-:10E550008F82000493420116304200FC24420004E2
-:10E56000005A10218C4240003042FFFF1440000648
-:10E570008F8200043C02FFFF34427FFF00821024A0
-:10E58000AF8200048F8200042403BFFF978400023F
-:10E5900000431024A74201A69742010C0002140078
-:10E5A00000441025AF4201AC3C021000AF4201B85C
-:10E5B00003E00008000000008F4700709342011242
-:10E5C0008F83000027BDFFF0304200FF0002288249
-:10E5D00030620100000030211040004324A40003F9
-:10E5E00030624000104000103062200000041080B3
-:10E5F000005A10218C43400024A400040004108021
-:10E60000AFA30000005A10218C424000AFA20004CA
-:10E6100093420116304200FC005A10218C42400007
-:10E620000A000F86AFA200081040002F0000302122
-:10E6300000041080005A10218C43400024A40004E0
-:10E6400000041080AFA30000005A10218C4240004B
-:10E65000AFA00008AFA200048FA80008000030217E
-:10E6600000002021240A00083C0908002529010097
-:10E6700003A41021148A000300042A001100000AD8
-:10E680000000000090420000248400012C83000C54
-:10E6900000A2102100021080004910218C420000CD
-:10E6A0001460FFF300C230263C0408008C8431045F
-:10E6B0008F4200702C83002010600009004738232F
-:10E6C0003C0308002463310800041080004310213B
-:10E6D00024830001AC4700003C010800AC23310456
-:10E6E000AF86000C2406000100C0102103E00008E2
-:10E6F00027BD00103C0208008C42003827BDFFD027
-:10E70000AFB60028AFB40020AFB20018AFBF002CE6
-:10E71000AFB50024AFB3001CAFB10014AFB0001010
-:10E72000000090213C16080026D600381440000254
-:10E730002454FFFF0000A0219742010E8F840000A7
-:10E740003042FFFF308340001060000A2453000471
-:10E750003C020020008210245040000730828000DC
-:10E760008F8200042403BFFF008318240A000FD700
-:10E7700034421000308280001040000A3C02002029
-:10E7800000821024104000078F8200043C03FFFF2A
-:10E7900034637FFF0083182434428000AF8200047A
-:10E7A000AF8300000E000F5E000000001440000761
-:10E7B000000000009743011E9742011C3063FFFFD9
-:10E7C0000002140000621825AF83000C9742010C70
-:10E7D0008F4340003046FFFF3402FFFF1462000306
-:10E7E000000000000A000FEF241200208F424000BA
-:10E7F0003042010054400001241200108F840000B8
-:10E800003082100050400014365200013082002047
-:10E810001440000B3C021000008210245040000EF7
-:10E82000365200013C030E003C020DFF0083182409
-:10E830003442FFFF0043102B5040000736520001C6
-:10E840003C0208008C42002C244200013C010800DC
-:10E85000AC22002C365200053C0508008CA5003483
-:10E8600054A000408F8400008F8200105440003D6F
-:10E870008F8400008F8200043042400054400039F1
-:10E880008F8400003C021F01008210243C03100012
-:10E89000144300348F84000030C202001440003260
-:10E8A0003C0200013265FFFF364600028F4201B88C
-:10E8B0000440FFFE3C020008AF40018003421021EB
-:10E8C000944200483043FFFF10600019AF830008F6
-:10E8D00024A200120062102B104000162402000334
-:10E8E000934201202403001AA343018B304200FF0E
-:10E8F0002443FFFE8F820000304240001040000899
-:10E900008F8200048F8200080043102B1440000403
-:10E910008F820004A74301940A00103A3442000198
-:10E920002403FFFE004310240A00103EAF820004BF
-:10E9300024020003A342018B8F8300042402BFFF43
-:10E940000062182424020002A742018C8F8200007A
-:10E95000A745018EA7460188A74301A60A0010D942
-:10E96000A74201903C020001008210241040000BDD
-:10E970003C0210003C0208008C4200D89745010E72
-:10E98000240400802442000130A5FFFF3C01080060
-:10E99000AC2200D80A0010E22406000300821024F2
-:10E9A00010400041000000003C0208008C42003092
-:10E9B0001040000C8F8200043042400010400009DB
-:10E9C0003C030F00008318243C0201000043102B7D
-:10E9D00014400004364600023265FFFF0A0010E2D0
-:10E9E0002404008010A0000D308201001040000BB4
-:10E9F0003C020F00008210243C0302001043000779
-:10EA00008F82000C00541024005610219042000404
-:10EA1000244200040A001097000221C000000000F8
-:10EA20008F8600003C0508008CA500D00006160269
-:10EA30003050000F38A200012C4200012E03000CC0
-:10EA40000043102414400015001021C02602FFFCD2
-:10EA50002C420004544000110000202138A2000282
-:10EA60002C42000100431024104000030006124213
-:10EA70000A001097000020210010182B00431024DA
-:10EA800050400006001021C0000020213265FFFF29
-:10EA90000E000F143246FFFB001021C03265FFFF4D
-:10EAA0000A0010E2364600028F4240003C11080086
-:10EAB0008E310024304201001040003E322200011D
-:10EAC0000220802110A00014325500043082010081
-:10EAD00010400012240200013C020F0000821024AA
-:10EAE0003C0302001043000C8F82000C02403021D6
-:10EAF0003265FFFF0054102400561021904400049A
-:10EB00003252FFFB248400040E000F14000421C0C5
-:10EB10002402FFFE022280242402000116020007C4
-:10EB2000320200013242000450400001365200021D
-:10EB30003265FFFF0A0010E102403021104000075B
-:10EB40003202000402403021000020210E000F1488
-:10EB50003265FFFF3252FFFB320200041040000713
-:10EB60008F82000030420800104000043265FFFF31
-:10EB7000024030210E000F142404010016A00015DD
-:10EB80008FBF002C274301808F4201B80440FFFE55
-:10EB900024022000A462000824020002A062000BEC
-:10EBA000A46000103C021000AF4201B80A0010E55A
-:10EBB0008FBF002C104000078FBF002C3265FFFF75
-:10EBC00036460002000020210E000F140000000055
-:10EBD0008FBF002C8FB600288FB500248FB4002083
-:10EBE0008FB3001C8FB200188FB100148FB00010CB
-:10EBF0000000102103E0000827BD003027BDFFC83A
-:10EC0000AFB000103C04600CAFBF0030AFB7002CB9
-:10EC1000AFB60028AFB50024AFB40020AFB3001CDE
-:10EC2000AFB20018AFB100148C8250002403FF7FF4
-:10EC30003C1A8000004310243442380CAC8250004F
-:10EC4000240200033C106000AF4200088E02080856
-:10EC50003C1B80083C010800AC2000203042FFF043
-:10EC6000384200102C4200010E001C46AF82001CEE
-:10EC70003C04FFFF3C020400348308063442000CCD
-:10EC8000AE021948AE03194C3C0560168E0219807D
-:10EC90008CA300003442020000641824AE021980E4
-:10ECA0003C0253531462000334A47C008CA2000481
-:10ECB000005020218C82007C8C830078AF82001869
-:10ECC000AF8300143C028000344200708C4300008B
-:10ECD00000403821AF830020006030218CE8000024
-:10ECE0003C0508008CA500FC3C0408008C8400F85E
-:10ECF000010630230000102100A6282100A6302B99
-:10ED000000822021008620213C010800AC2500FC67
-:10ED10003C010800AC2400F88F56000032C200030A
-:10ED20001040FFEE010030218CE600003C05080099
-:10ED30008CA500FC3C0408008C8400F800C830233B
-:10ED400000A628210000102100A6302B00822021DF
-:10ED50000086202132C700013C010800AC2500FCE0
-:10ED6000AF8800203C010800AC2400F810E0016BE3
-:10ED700032C200028F4301283C02000803421021E6
-:10ED8000AF4300208F4301048F44010094420048A8
-:10ED9000AF830000AF8400043042FFFF0E000F0E6F
-:10EDA000AF8200083C0208008C4200C010400008FE
-:10EDB0008F8400003C0208008C4200C42442000101
-:10EDC0003C010800AC2200C40A0012AF00000000A1
-:10EDD0003C02001000821024144001358F8300048F
-:10EDE0003C0208008C4200203C0308008C63003881
-:10EDF00000009021244200013C010800AC220020C8
-:10EE00003C17080026F70038146000022474FFFF46
-:10EE10000000A0219742010E308340003042FFFFE6
-:10EE20001060000A245300043C02002000821024D9
-:10EE300050400007308280008F8200042403BFFF0F
-:10EE4000008318240A00118D3442100030828000A3
-:10EE50001040000A3C0200200082102410400007ED
-:10EE60008F8200043C03FFFF34637FFF008318247C
-:10EE700034428000AF820004AF8300000E000F5EBA
-:10EE80000000000014400007000000009743011E2E
-:10EE90009742011C3063FFFF000214000062182536
-:10EEA000AF83000C9742010C8F4340003046FFFFB8
-:10EEB0003402FFFF14620003000000000A0011A5E5
-:10EEC000241200208F4240003042010054400001D3
-:10EED000241200108F840000308210005040001473
-:10EEE00036520001308200201440000B3C0210001A
-:10EEF000008210245040000E365200013C030E00E8
-:10EF00003C020DFF008318243442FFFF0043102B06
-:10EF100050400007365200013C0208008C42002C91
-:10EF2000244200013C010800AC22002C36520005AE
-:10EF30003C0508008CA5003454A000408F840000DC
-:10EF40008F8200105440003D8F8400008F820004A7
-:10EF500030424000544000398F8400003C021F01C1
-:10EF6000008210243C031000144300348F840000FE
-:10EF700030C20200144000323C0200013265FFFF43
-:10EF8000364600028F4201B80440FFFE3C020008F2
-:10EF9000AF40018003421021944200483043FFFFFC
-:10EFA00010600019AF83000824A200120062102B29
-:10EFB0001040001624020003934201202403001A8B
-:10EFC000A343018B304200FF2443FFFE8F820000E9
-:10EFD00030424000104000088F8200048F820008F9
-:10EFE0000043102B144000048F820004A7430194B7
-:10EFF0000A0011F0344200012403FFFE00431024F4
-:10F000000A0011F4AF82000424020003A342018B22
-:10F010008F8300042402BFFF006218242402000230
-:10F02000A742018C8F820000A745018EA746018868
-:10F03000A74301A60A00128FA74201903C020001DB
-:10F04000008210245040000B3C0210003C020800DB
-:10F050008C4200D89745010E240400802442000110
-:10F0600030A5FFFF3C010800AC2200D80A0012982E
-:10F07000240600030082102410400041000000001C
-:10F080003C0208008C4200301040000C8F820004CB
-:10F0900030424000104000093C030F000083182458
-:10F0A0003C0201000043102B1440000436460002CD
-:10F0B0003265FFFF0A0012982404008010A0000DA2
-:10F0C000308201001040000B3C020F00008210242F
-:10F0D0003C030200104300078F82000C00541024F0
-:10F0E0000057102190420004244200040A00124DEF
-:10F0F000000221C0000000008F8600003C050800CF
-:10F100008CA500D0000616023050000F38A2000176
-:10F110002C4200012E03000C004310241440001563
-:10F12000001021C02602FFFC2C42000454400011B4
-:10F130000000202138A200022C42000100431024CC
-:10F1400050400003000612420A00124D0000202128
-:10F150000010182B0043102450400006001021C05E
-:10F16000000020213265FFFF0E000F143246FFFB26
-:10F17000001021C03265FFFF0A00129836460002D7
-:10F180008F4240003C1108008E31002430420100C3
-:10F190001040003E322200010220802110A0001405
-:10F1A0003255000430820100104000122402000198
-:10F1B0003C020F00008210243C0302001043000CAC
-:10F1C0008F82000C024030213265FFFF0054102472
-:10F1D00000571021904400043252FFFB24840004A5
-:10F1E0000E000F14000421C02402FFFE022280241E
-:10F1F000240200011602000732020001324200041C
-:10F2000050400001365200023265FFFF0A0012979B
-:10F210000240302110400007320200040240302139
-:10F22000000020210E000F143265FFFF3252FFFB59
-:10F2300032020004104000078F82000030420800B4
-:10F24000104000043265FFFF024030210E000F1411
-:10F250002404010016A0002E3C0240002743018038
-:10F260008F4201B80440FFFE24022000A46200087F
-:10F2700024020002A062000BA46000103C021000F7
-:10F28000AF4201B80A0012B43C02400050400020D6
-:10F290003C0240003265FFFF36460002000020219C
-:10F2A0000E000F14000000000A0012B43C024000DF
-:10F2B0002402BFFF0062102410400008000000007C
-:10F2C000240287FF00621024144000083C02006002
-:10F2D0000082102410400005000000000E000D26E2
-:10F2E000000000000A0012AD000000000E0012F83D
-:10F2F00000000000104000063C0240008F43012443
-:10F300003C026020AC430014000000003C024000BE
-:10F31000AF4201380000000032C200021040FE6A15
-:10F320003C0280008F4201403C044000AF4200207C
-:10F330008F4301483C027000006218241064002DC5
-:10F34000000000000083102B144000063C02600007
-:10F350003C022000106200073C0240000A0012F448
-:10F360000000000010620027000000000A0012F4F4
-:10F370003C0240008F4201482403000400021402B2
-:10F38000304200FF1443000B274401808F430140AB
-:10F390008F4201B80440FFFE2402001CAC83000031
-:10F3A000A082000B3C021000AF4201B80A0012F428
-:10F3B0003C0240008F4201B80440FFFE0000000004
-:10F3C0008F42014800021402A482000824020002B5
-:10F3D000A082000B8F420148A48200108F4201449A
-:10F3E000AC8200243C021000AF4201B80A0012F4C3
-:10F3F0003C0240000E00131C000000000A0012F442
-:10F400003C0240000E001C53000000003C02400083
-:10F41000AF420178000000000A0011223C02800087
-:10F420008F4201003042003E1440001124020001CE
-:10F43000AF4000488F420100304207C01040000535
-:10F4400000000000AF40004CAF40005003E0000857
-:10F4500024020001AF400054AF4000408F42010041
-:10F460003042380054400001AF4000442402000103
-:10F4700003E00008000000003C029000344200015C
-:10F4800000822025AF4400208F4200200440FFFE70
-:10F490000000000003E00008000000003C028000C3
-:10F4A000344200010082202503E00008AF44002020
-:10F4B00027BDFFE0AFB20018AFBF001CAFB1001412
-:10F4C000AFB000108F5001408F5101483C028000C6
-:10F4D0000011940202222024324300FF2402000E75
-:10F4E0001062008A2862000F104000122862003764
-:10F4F000240200061062003B28620007104000074B
-:10F50000240200091060001A240200011062002584
-:10F51000000000000A0013D1000000001062007B10
-:10F520002402000B1062005B3222FFFF0A0013D19D
-:10F530000000000010400008240200382862003556
-:10F54000104000802402001F1062007E00000000B6
-:10F550000A0013D1000000001062007A240200802B
-:10F5600010620042000000000A0013D100000000F9
-:10F570008F4201B80440FFFE24020001AF50018019
-:10F58000AF400184A7520188A342018A24020002ED
-:10F59000A342018BA75101908F4201440A0013CC72
-:10F5A000AF4201A41080000A240200023C010800BE
-:10F5B000A02275D83C010800AC3075E08F420144B0
-:10F5C0003C010800AC2275DC0A0013D38FBF001C7D
-:10F5D0008F4201B80440FFFE240200020A0013B665
-:10F5E000000000008F4201B80440FFFE0000000050
-:10F5F000AF5001803C020800904275D810400003D3
-:10F60000000018213C0308008C6375E0AF430184BF
-:10F61000A75201883C020800904275D800001821CA
-:10F6200034420001A342018A24020002A342018B5A
-:10F63000A75101908F420144AF4201A43C0208004F
-:10F64000904275D8104000033C0210003C030800B3
-:10F650008C6375DCAF4301A8AF4201B83C010800E0
-:10F66000A02075D80A0013D38FBF001C8F4201B8A9
-:10F670000440FFFE24020002A342018BA75201882E
-:10F68000A75101908F420144A74201920A0013CE74
-:10F690003C0210001440001D0000000093620005B1
-:10F6A0003042000414400037000000000E00130E2A
-:10F6B0000200202193620005020020213442000450
-:10F6C0000E001317A3620005936200053042000488
-:10F6D00014400002000000000000000D93620000D2
-:10F6E00024030020304200FF144300080000000003
-:10F6F0008F4201B80440FFFE24020005AF50018094
-:10F70000A342018B3C021000AF4201B88F4201B806
-:10F710000440FFFE24020002AF400180AF5001848C
-:10F72000A7520188A342018AA342018BA7510190ED
-:10F73000AF4001A48F420144AF4201A80A0013CE9A
-:10F740003C0210008F4201B80440FFFE2402000179
-:10F75000AF500180AF400184A7520188A342018AC3
-:10F7600024020002A342018BA7510190AF4001A4E3
-:10F77000AF4001A83C021000AF4201B80A0013D309
-:10F780008FBF001C0000000D8FBF001C8FB200183F
-:10F790008FB100148FB0001003E0000827BD0020D7
-:10F7A00027BDFFE8AFBF00100E000F0E00000000E5
-:10F7B000AF4001808FBF0010000020210A000FAD74
-:10F7C00027BD00183084FFFF30A5FFFF000018217F
-:10F7D000108000070000000030820001104000028D
-:10F7E00000042042006518210A0013E400052840A7
-:10F7F00003E000080060102110C0000624C6FFFFCF
-:10F800008CA2000024A50004AC8200000A0013EEC4
-:10F810002484000403E000080000000010A0000899
-:10F8200024A3FFFFAC8600000000000000000000E1
-:10F830002402FFFF2463FFFF1462FFFA2484000404
-:10F8400003E000080000000027BDFFE8AFBF001480
-:10F85000AFB000100E00130E008080219362007D77
-:10F8600002002021344200200E001317A362007D05
-:10F87000020020218FBF00148FB000100A000C9BE3
-:10F8800027BD0018308300FF30A500FF30C600FF01
-:10F89000274701808F4201B80440FFFE00000000AE
-:10F8A0008F42012834634000ACE2000024020001D2
-:10F8B000ACE00004A4E30008A0E2000A2402000275
-:10F8C000A0E2000B3C021000A4E50010ACE0002414
-:10F8D000ACE00028A4E6001203E00008AF4201B843
-:10F8E00027BDFFE8AFBF00109362003F2403001262
-:10F8F000304200FF1043000D008030218F62004431
-:10F90000008210230440000A8FBF00108F6200485D
-:10F91000240400390000282100C2102304410004FF
-:10F92000240600120E001411000000008FBF00100A
-:10F930002402000103E0000827BD001827BDFFC80E
-:10F94000AFB1002C00A08821AFB2003027A5001075
-:10F950000080902102202021AFBF0034AFB00028EA
-:10F960000E000CA4AFA0001010400009024020219E
-:10F970008E220008AF6200840E001402AF600040C7
-:10F98000240400382405008D0A0014DD240600122A
-:10F990009362003E304200081040000F8FA200101A
-:10F9A00030420100104000078FA300148F620060F6
-:10F9B0000062102304430008AF6300600A0014666D
-:10F9C00000000000AF6000609362003E2403FFF778
-:10F9D00000431024A362003E9362003E30420008C0
-:10F9E000144000022406000300003021936200341A
-:10F9F000936300378F640084304200FF306300FF60
-:10FA000000661821000318800043282100A4202B41
-:10FA10001080000B000000009763003C8F620084A0
-:10FA20003063FFFF004510230062182B14600004B0
-:10FA3000000000008F6200840A00148200458023C9
-:10FA40009762003C3050FFFF8FA30010306200042B
-:10FA500010400004000628808FA2001C0A00148AAF
-:10FA60000202102B2E02021850400003240202183A
-:10FA70000A00149302051023306300041060000391
-:10FA8000004510238FA2001C004510230040802158
-:10FA90002C42008054400001241000800E00130E00
-:10FAA0000240202124020001AF62000C9362003E5C
-:10FAB000001020403042007FA362003E8E220004EE
-:10FAC00024420001AF620040A770003C8F620050EA
-:10FAD0009623000E00431021AF6200588F62005041
-:10FAE00000441021AF62005C8E220004AF62001857
-:10FAF0008E220008AF62001C8FA200103042000866
-:10FB00005440000A93A20020A3600036936200369E
-:10FB10002403FFDFA36200359362003E00431024FC
-:10FB2000A362003E0A0014BD8E220008A3620035C5
-:10FB30008E220008AF62004C8F6200248F63004069
-:10FB400000431021AF62004893620000240300507C
-:10FB5000304200FF144300122403FF803C020800DF
-:10FB60008C4231A00242102100431024AF420028F1
-:10FB70003C0208008C4231A08E2400083C03000C9B
-:10FB8000024210213042007F034210210043102125
-:10FB9000AC4400D88E230008AF820028AC4300DCC0
-:10FBA0000E001317024020212404003800002821F1
-:10FBB0002406000A0E001411000000008FBF00345C
-:10FBC0008FB200308FB1002C8FB0002824020001CA
-:10FBD00003E0000827BD003827BDFFE8AFBF0010D5
-:10FBE00090C7000D00C0282130E6001010C0000AA8
-:10FBF00030E200058CA300088F62005410620006FA
-:10FC000030E20005144000178FBF001000002021D3
-:10FC10000A000D1327BD00181040000D30E300123C
-:10FC200010C000108FBF00108CA300088F6200541A
-:10FC30001462000D24020001240400382405008D04
-:10FC40000E001411240600120A0015098FBF0010BF
-:10FC500024020012146200038FBF00100A00143F38
-:10FC600027BD00182402000103E0000827BD00188A
-:10FC700027BDFFF827420180AFA20000308A00FFB5
-:10FC80008F4201B80440FFFE000000008F460128AB
-:10FC90003C0208008C4231A02403FF80AF86005054
-:10FCA00000C2102100431024AF4200243C0208008F
-:10FCB0008C4231A08FA900008FA8000000C2102143
-:10FCC0003042007F034218213C02000A00621821E2
-:10FCD000946400D48FA700008FA5000024020002C6
-:10FCE000AF830028A0A2000B8FA300003542600064
-:10FCF0003084FFFFA4E200083C021000AD260000A3
-:10FD0000AD040004AC60002427BD0008AF4201B878
-:10FD100003E00008240200018C8200048F83002885
-:10FD200000451023AC820004906200633042007FE3
-:10FD3000A06200638C820020938300308F850028AE
-:10FD400034420002AF830044A7800042AC8200200E
-:10FD5000A4A000E490A200632403FFBF004310248A
-:10FD600003E00008A0A20063274301808F4201B88E
-:10FD70000440FFFE8F820050AC6200008F420124DD
-:10FD8000AC62000424026083A46200082402000222
-:10FD9000A062000B3C02100003E00008AF4201B873
-:10FDA0008F880044938200308F8300283C0708002E
-:10FDB00024E779F400481023304200FF304900FC6A
-:10FDC000246500888F860048304A0003112000090E
-:10FDD00000002021248200048CA30000304400FF96
-:10FDE0000089102AACE3000024A500041440FFF9A8
-:10FDF00024E70004114000090000202124820001B2
-:10FE000090A30000304400FF008A102BA0E3000004
-:10FE100024A500011440FFF924E7000130C20003CB
-:10FE2000144000048F850044310200031040000D8F
-:10FE30000000000010A00009000020212482000121
-:10FE400090C30000304400FF0085102BA0E30000A9
-:10FE500024C600011440FFF924E7000103E0000874
-:10FE6000000000001100FFFD00002021248200049A
-:10FE70008CC30000304400FF0088102BACE300006E
-:10FE800024C600041440FFF924E7000403E000083E
-:10FE9000000000008F8300449382003030C600FFD2
-:10FEA00030A500FF00431023304300FF8F8200285D
-:10FEB000008038210043102114C00002244800882B
-:10FEC0000083382130E200031440000530A2000313
-:10FED00014400003306200031040000D00000000D9
-:10FEE00010A00009000020212482000190E30000FE
-:10FEF000304400FF0085102BA103000024E700011F
-:10FF00001440FFF92508000103E00008000000008C
-:10FF100010A0FFFD00002021248200048CE30000DB
-:10FF2000304400FF0085102BAD03000024E70004DF
-:10FF30001440FFF92508000403E000080000000059
-:10FF400027BDFFF82402FFFFAFA200000080382188
-:10FF50002405002F3C090800252975F4240800FF1A
-:10FF60002406FFFF90E2000024A3FFFF0006220208
-:10FF700000C21026304200FF00021080004910210C
-:10FF80008C420000306500FF24E7000114A8FFF553
-:10FF90000082302600061027AFA20004AFA20000A6
-:10FFA0000000282127A6000400C510239044000368
-:10FFB00024A2000100BD1821304500FF2CA200043E
-:10FFC0001440FFF9A06400008FA2000003E00008C5
-:10FFD00027BD00080080482130AAFFFF30C600FF7F
-:10FFE00030E7FFFF274801808F4201B80440FFFE41
-:10FFF0008F820050AD0200008F420124AD02000448
-:020000040001F9
-:100000008D220020A5070008A102000A2402001684
-:10001000A102000B934301208D2200088D240004CF
-:10002000306300FF004310219783004200441021F9
-:100030008D250024004310233C0308008C6331A06D
-:100040008F840028A502000C246300E82402FFFF2F
-:10005000A50A000EA5030010A5060012AD050018A4
-:10006000AD020024948201142403FFF73042FFFF05
-:10007000AD0200288C820118AD02002C3C02100059
-:10008000AD000030AF4201B88D22002000431024A3
-:1000900003E00008AD2200208F82002830E7FFFF38
-:1000A00000804821904200D330A5FFFF30C600FFFA
-:1000B0000002110030420F0000E23825274801807D
-:1000C0008F4201B80440FFFE8F820050AD02000055
-:1000D0008F420124AD0200048D220020A5070008F4
-:1000E000A102000A24020017A102000B9343012081
-:1000F0008D2200088D240004306300FF004310218E
-:1001000097830042004410218F840028004310236D
-:100110003C0308008C6331A0A502000CA505000E6D
-:10012000246300E8A5030010A5060012AD0000142A
-:100130008D220024AD0200188C82005CAD02001CF0
-:100140008C820058AD0200202402FFFFAD02002483
-:10015000948200E63042FFFFAD02002894820060E6
-:10016000948300BE30427FFF3063FFFF0002120025
-:1001700000431021AD02002C3C021000AD00003005
-:10018000AF4201B8948200BE2403FFF700A2102101
-:10019000A48200BE8D2200200043102403E000084A
-:1001A000AD220020274301808F4201B80440FFFEAA
-:1001B00024020018AC640000A062000B8F820028AB
-:1001C000944200E6A46200103C021000AC600030D3
-:1001D00003E00008AF4201B8274301808F4201B815
-:1001E0000440FFFE8F82002C9442001C3042FFFF2F
-:1001F000000211C0AC62000024020019A062000BD2
-:100200003C021000AC60003003E00008AF4201B8CF
-:100210008F87003430C300FF8F4201B80440FFFED7
-:100220008F82005034636000ACA200009382004CC7
-:10023000A0A200058CE20010A4A20006A4A300085E
-:100240008C8200202403FFF7A0A2000A24020002EF
-:10025000A0A2000B8CE20000ACA200108CE2000413
-:10026000ACA200148CE2001CACA200248CE20020A2
-:10027000ACA200288CE2002CACA2002C8C820024C2
-:10028000ACA200183C021000AF4201B88C820020E2
-:100290000043102403E00008AC8200209382004C4D
-:1002A0002403000127BDFFE8004330042C42002056
-:1002B000AFB00010AFBF00142410FFFE10400005C7
-:1002C000274501803C0208008C4231900A0016A8A4
-:1002D000004610243C0208008C4231940046102451
-:1002E00014400007240600848F8300282410FFFF99
-:1002F000906200623042000F34420040A06200620F
-:100300000E00167400000000020010218FBF0014C0
-:100310008FB0001003E0000827BD00188F83002C69
-:1003200027BDFFE0AFB20018AFB10014AFB00010AE
-:10033000AFBF001C9062000D00A0902130D100FFE3
-:100340003042007FA062000D8F8500288E43001888
-:10035000008080218CA2007C146200052402000E23
-:1003600090A20063344200200A0016D1A0A20063CC
-:100370000E001697A382004C2403FFFF1043004792
-:100380002404FFFF52200045000020218E4300007E
-:100390003C02001000621024504000043C0200089F
-:1003A000020020210A0016E0240200150062102439
-:1003B000504000098E450000020020212402001454
-:1003C0000E001697A382004C2403FFFF1043003356
-:1003D0002404FFFF8E4500003C02000200A210240E
-:1003E000104000163C0200048F86002C8CC20014C2
-:1003F0008CC300108CC40014004310230044102B45
-:1004000050400005020020218E43002C8CC20010B9
-:1004100010620003020020210A00171124020012BA
-:100420003C02000400A210245040001C00002021C7
-:10043000020020210A0017112402001300A2102438
-:10044000104000068F83002C8C6200105040001377
-:10045000000020210A00170B020020218C620010EE
-:10046000504000048E42002C020020210A00171187
-:100470002402001150400009000020210200202128
-:10048000240200170E001697A382004C2403FFFFDE
-:10049000104300022404FFFF000020218FBF001C36
-:1004A0008FB200188FB100148FB00010008010219F
-:1004B00003E0000827BD00209383003027BDFFE044
-:1004C00024020034AFB20018AFB10014AFBF001C5B
-:1004D000AFB00010008088211462000C00A09021B1
-:1004E0008F8400340E0015C08C900030120200077B
-:1004F00024020005022020210E001697A382004C42
-:100500002403FFFF104300602404FFFF9242000415
-:10051000104000098F820028022020212402000CB4
-:100520000E001697A382004C2403FFFF10430056D1
-:100530002404FFFF8F820028A38000248E43000440
-:100540008C4400803C0200FF3442FFFF006218240C
-:100550000083202B10800008AF83003C0220202164
-:10056000240200190E001697A382004C2403FFFFFB
-:10057000104300452404FFFF978200428F87004408
-:100580008F85003C0047202310A0003AA78400423A
-:100590008F86002830A200030002102390C300BC05
-:1005A0003050000300B02821000318823071000190
-:1005B0000011108000A228213C0308008C6331A0A8
-:1005C0008F8200503084FFFF0085202B00431021D4
-:1005D00010800010244200888F8400341082000DA7
-:1005E0003C033F018E420000004310243C032500E1
-:1005F0001443000630E500FF8C820000ACC2008886
-:100600008C8200100A001775ACC200980E00159578
-:1006100000003021938200248F8500288F830048BA
-:10062000020238218F820044A387002494A400E4AE
-:10063000006218218F82003C34841000AF83004890
-:1006400000503021A4A400E41220000EAF86004424
-:1006500024E20004A382002494A200E424C3000442
-:10066000AF83004434422000A4A200E40A001792A1
-:10067000000020218F820048AF80004400471021F5
-:10068000AF820048000020218FBF001C8FB20018ED
-:100690008FB100148FB000100080102103E000081B
-:1006A00027BD00208F86002827BDFFE8AFBF0014BC
-:1006B000AFB0001090C2006330420020104000082C
-:1006C00030A500FF8CC2007C2403FFDF2442000120
-:1006D000ACC2007C90C2006300431024A0C200633F
-:1006E00010A000238F8300282750018002002821BA
-:1006F0000E001674240600828F8200289042006348
-:100700003042004050400019A380004C8F830034D9
-:100710008F4201B80440FFFE8F820050AE020000FD
-:1007200024026082A602000824020002A202000B3A
-:100730008C620008AE0200108C62000CAE02001445
-:100740008C620014AE0200188C620018AE02002405
-:100750008C620024AE0200288C620028AE02002CBD
-:100760003C021000AF4201B8A380004C8F830028E8
-:100770008FBF00148FB000109062006327BD001877
-:100780003042007FA0620063978200428F8600445F
-:100790008F8500289383003000461023A7820042F3
-:1007A000A4A000E490A400638F820048AF830044BB
-:1007B0002403FFBF0046102100832024AF8200489D
-:1007C000A0A400638F820028A04000BD8F82002873
-:1007D00003E00008A44000BE8F8A002827BDFFE088
-:1007E000AFB10014AFB000108F880044AFBF001845
-:1007F00093890024954200E430D100FF0109182BB1
-:100800000080802130AC00FF3047FFFF00005821FE
-:1008100014600003310600FF012030210109582334
-:10082000978300420068102B144000320000000043
-:1008300014680007240200018E0200202403FFFB3D
-:1008400034E7800000431024AE020020240200019F
-:1008500034E70880158200053165FFFF0E0015E5BD
-:10086000020020210A001827020020210E0016167F
-:10087000020020210E0016598F8400508F8400281A
-:100880009482006024420001A4820060948200608F
-:100890003C0308008C63318830427FFF5443000FD3
-:1008A0000200202194820060240380000043102471
-:1008B000A48200609082006090830060304200FF5C
-:1008C000000211C200021027000211C03063007F35
-:1008D00000621825A0830060020020210220282148
-:1008E0008FBF00188FB100148FB000100A00179945
-:1008F00027BD0020914200632403FF8000431025A0
-:10090000A1420063978200423048FFFF110000209F
-:10091000938300248F840028004B1023304600FF6F
-:10092000948300E42402EFFF0168282B006218245E
-:10093000A48300E414A000038E02002001005821CB
-:10094000000030212403FFFB34E780000043102423
-:10095000AE02002024020001158200053165FFFF70
-:100960000E0015E5020020210A00184F978300426F
-:100970000E00161602002021978300428F82004449
-:10098000A780004200431023AF82004493830024D9
-:100990008F8200288FBF00188FB100148FB0001015
-:1009A00027BD002003E00008A04300BD8F8200287F
-:1009B00090430088904500BD244900883063003F83
-:1009C0002463FFE024020001006238042C6300204D
-:1009D00030E80019A385002410600010AF890034AE
-:1009E0003C0280003442000224050001240600017C
-:1009F0001500000800E218240000282114600005FA
-:100A000030E200201040000524050001912600017D
-:100A100030C600010A0017E60000000003E00008ED
-:100A20000000000027BDFFD8AFB000108F90003449
-:100A3000AFB40020AFB10014AFBF0024AFB3001CAF
-:100A4000AFB200188E0500103C0208008C4231B095
-:100A50008F86003830A33FFF0062182B8CD3001420
-:100A6000008088218CD20020106000780000A02136
-:100A700090C3000D2402FF8000431024304200FF89
-:100A800050400073022020210005138230420003F1
-:100A90005440006F0220202194C3001C8F82002844
-:100AA0008E050028A44301148CC200100262182392
-:100AB000146500072402001F8F82003C0062102191
-:100AC0000262102B104000088F83002C24020018B3
-:100AD0000E001697A382004C2403FFFF1043006F03
-:100AE0002404FFFF8F83002C8F84003C8C62001055
-:100AF0000244902100441023AC6200108F82002831
-:100B0000AC7200208C4200680052102B104000098B
-:100B10008F830038022020212402001D0E0016972A
-:100B2000A382004C2403FFFF1043005C2404FFFF5A
-:100B30008F8300388E0200248C630024104300074A
-:100B4000022020212402001C0E001697A382004CD4
-:100B50002403FFFF104300512404FFFF8F84002C67
-:100B60008C82002424420001AC8200241253000431
-:100B70008F8200288C4200685642000E8E020000D0
-:100B80008E0200003C030080004310241440000D3E
-:100B90002402001A022020210E001697A382004C86
-:100BA0002403FFFF1043003D2404FFFF0A0018E365
-:100BB0008E0200143C0300800043102450400003C8
-:100BC0008E020014AC8000208E0200142412FFFF5D
-:100BD000105200062402001B022020210E0016974E
-:100BE000A382004C1052002D2404FFFF8E0300004E
-:100BF0003C020001006210241040001F3C020080F3
-:100C00000062102414400008022020212402001A4F
-:100C10000E001697A382004C2403FFFF1043001F11
-:100C20002404FFFF02202021020028210E0016B715
-:100C3000240600012403FFFF2404FFFF1443000ED9
-:100C4000241400010A0019188FBF0024022020215B
-:100C50002402000D8FBF00248FB400208FB3001C2E
-:100C60008FB200188FB100148FB0001027BD00287C
-:100C70000A001697A382004C8F83002C02202021AB
-:100C800002803021946200362405000124420001D4
-:100C90000E0017E6A4620036000020218FBF00245A
-:100CA0008FB400208FB3001C8FB200188FB10014D6
-:100CB0008FB000100080102103E0000827BD00283D
-:100CC0008F83002827BDFFD8AFB40020AFB3001C2E
-:100CD000AFB20018AFB10014AFB00010AFBF002426
-:100CE000906200638F9100342412FFFF3442004071
-:100CF00092250000A06200638E22001000809821DF
-:100D000030B0003F105200060360A0212402000D05
-:100D10000E001697A382004C105200522404FFFFCD
-:100D20008F8300288E2200188C63007C10430007FC
-:100D3000026020212402000E0E001697A382004CB0
-:100D40002403FFFF104300472404FFFF2404002076
-:100D5000120400048F830028906200633442002054
-:100D6000A06200638F85003C10A0001E0000000000
-:100D7000560400048F820028026020210A001962B4
-:100D80002402000A9683000A2404FFFD94420060B6
-:100D90003042FFFF104300348FBF00243C020800A4
-:100DA0008C42318C0045102B14400006026020213B
-:100DB000000028210E0017E6240600010A00198908
-:100DC000000020212402002D0E001697A382004C63
-:100DD0002403FFFF104300232404FFFF0A001989A6
-:100DE00000002021160400058F8400288E230014A3
-:100DF0002402FFFF506200180260202194820060EC
-:100E000024420001A4820060948200603C03080038
-:100E10008C63318830427FFF5443000F02602021F1
-:100E2000948200602403800000431024A4820060A8
-:100E30009082006090830060304200FF000211C287
-:100E400000021027000211C03063007F00621825E5
-:100E5000A0830060026020210E0017992405000184
-:100E6000000020218FBF00248FB400208FB3001C0E
-:100E70008FB200188FB100148FB0001000801021C5
-:100E800003E0000827BD00288F83002827BDFFE866
-:100E9000AFB00010AFBF0014906200638F870034C2
-:100EA00000808021344200408CE60010A062006384
-:100EB0003C0308008C6331B030C23FFF0043102B6D
-:100EC0001040004E8F8500382402FF8090A3000D53
-:100ED00000431024304200FF50400049020020210E
-:100EE0000006138230480003240200025502004429
-:100EF0000200202194A2001C8F85002824030023D7
-:100F0000A4A201148CE60000000616023042003F45
-:100F1000104300103C0300838CE300188CA2007C7B
-:100F2000106200062402000E0E001697A382004CE9
-:100F30002403FFFF104300382404FFFF8F830028A1
-:100F40009062006334420020A06200630A0019CE60
-:100F50008F83002C00C31024144300078F83002CC0
-:100F600090A200623042000F34420020A0A2006232
-:100F7000A38800408F83002C9062000D3042007FD8
-:100F8000A062000D8F83003C106000180200202139
-:100F90008F8400388C8200100043102B1040000911
-:100FA00024020018020020210E001697A382004C94
-:100FB0002403FFFF104300182404FFFF0A0019F662
-:100FC000000020218C820010240500010200202155
-:100FD000004310238F83002C240600010E0017E627
-:100FE000AC6200100A0019F6000020210E001799CB
-:100FF000240500010A0019F600002021020020212A
-:101000002402000D8FBF00148FB0001027BD001800
-:101010000A001697A382004C8FBF00148FB00010F7
-:101020000080102103E0000827BD001827BDFFD86D
-:10103000AFB000108F900034AFB3001CAFBF0020E2
-:10104000AFB20018AFB100148E1200103C030800BC
-:101050008C6331B032423FFF0043102B1040007CC4
-:10106000008098218F8500382402FF8090A3000D16
-:1010700000431024304200FF5040007602602021DF
-:101080000012138230420003240300015443007114
-:101090000260202190A2000D30420008544000035D
-:1010A0008F82003C0A001A262402002450400003CC
-:1010B0008E03000C0A001A26240200278CA20020AE
-:1010C00014620005240200208E0300088CA2002474
-:1010D00010620008240200200E001697A382004C24
-:1010E0002403FFFF1043006A2404FFFF0A001A5183
-:1010F0008F84002C8E0200142411FFFF1451000372
-:101100008F8700280A001A4C240200258E0300183D
-:101110008CE2007C146200162402000E8E03002470
-:101120008CA2002814620012240200218E060028DE
-:101130008CA2002C14C2000E2402001F8E03002C6F
-:101140001060000B240200238CE200680043102B87
-:1011500014400007240200268CA200140066182107
-:101160000043102B504000078F84002C24020022E3
-:101170000E001697A382004C105100452404FFFF77
-:101180008F84002C2403FFF79082000D004310246D
-:10119000A082000D8F8600283C0308008C6331ACD0
-:1011A0008F82005094C400E08F85002C00431021F2
-:1011B00030847FFF00042040004410213043007F32
-:1011C000034320213C03000E008320212403FF80E1
-:1011D00000431024AF42002CA49200008CA20028EF
-:1011E00024420001ACA200288CA2002C8E03002C0B
-:1011F00000431021ACA2002C8E02002CACA20030C7
-:101200008E020014ACA2003494A2003A24420001E1
-:10121000A4A2003A94C600E03C0208008C4231B01F
-:1012200024C4000130837FFF14620013008030214A
-:10123000240280000082302430C2FFFF000213C26B
-:10124000304200FF000210270A001A8E000233C04D
-:10125000026020212402000D8FBF00208FB3001CEC
-:101260008FB200188FB100148FB0001027BD002876
-:101270000A001697A382004C8F820028026020216A
-:10128000240500010E001799A44600E0000020216B
-:101290008FBF00208FB3001C8FB200188FB10014D5
-:1012A0008FB000100080102103E0000827BD002847
-:1012B00027BDFFE0AFB100148F910034AFB0001034
-:1012C000AFBF00188E2600103C0308008C6331B0BD
-:1012D00030C23FFF0043102B1040005E0080802191
-:1012E0008F8500382402FF8090A3000D0043102456
-:1012F000304200FF50400058020020218F82003C05
-:1013000010400008000613828F8200289763000AAD
-:101310002404FFFD944200603042FFFF104300555B
-:1013200000061382304200031440000E000000004B
-:1013300092220002104000058E2300245060001508
-:10134000922300030A001AC7020020218CA2002465
-:101350005062001092230003020020210A001ACFDD
-:101360002402000F90A2000D3042000854400009F2
-:101370009223000302002021240200100E00169781
-:10138000A382004C2403FFFF1043003A2404FFFF14
-:1013900092230003240200025462000C92220003F4
-:1013A0008F82003C54400009922200030200202159
-:1013B0002402002C0E001697A382004C2403FFFF8A
-:1013C0001043002C2404FFFF922200030220282156
-:1013D00002002021384600102CC600012C420001DA
-:1013E0000E0016B7004630252411FFFF10510021D2
-:1013F0002404FFFF8F83003C1060001202002021B4
-:101400003C0208008C42318C0043102B1440000633
-:1014100000000000000028210E0017E6240600014D
-:101420000A001B0D000020212402002D0E0016973B
-:10143000A382004C1051000F2404FFFF0A001B0D73
-:10144000000020210E001799240500010A001B0D41
-:1014500000002021020020212402000D8FBF00186F
-:101460008FB100148FB0001027BD00200A0016971E
-:10147000A382004C8FBF00188FB100148FB00010F2
-:101480000080102103E0000827BD00209383004066
-:1014900027BDFFE024020002AFB10014AFB000107E
-:1014A00000808821AFBF0018000080211062008CEE
-:1014B0002404FFFD978500428F83004430A2FFFF84
-:1014C0000043102B5440007D8F8400480E001558B7
-:1014D000000000003C020800244279F40220202190
-:1014E000004028210E00171EAF8200342409FFFFA0
-:1014F0001049007B2404FFFF3C0808008D087A0493
-:101500003C0208008C4231B03C030800906379F43F
-:1015100031043FFF0082102B1040001B3067003F5A
-:101520003C0208008C4231A88F83005000042180C7
-:1015300000621821006418213062007F03422821D4
-:101540003C02000C00A228213C0200803442000131
-:101550003066007800C230252402FF80006210242B
-:10156000AF42002830640007AF4208048F82002891
-:101570000344202124840940AF460814AF85002C81
-:10158000AF840038AC430118938300402402000369
-:101590001462003B240200012402002610E2003DF8
-:1015A00028E2002710400013240200322402002207
-:1015B00010E2003828E20023104000082402002432
-:1015C0002402002010E200242402002110E2001E68
-:1015D000022020210A001B8C2402000B10E2002DA7
-:1015E0002402002510E20010022020210A001B8C9A
-:1015F0002402000B10E2001A28E20033104000061B
-:101600002402003F2402003110E2000B02202021BE
-:101610000A001B8C2402000B10E200110220202182
-:101620000A001B8C2402000B0E00187902202021D6
-:101630000A001BA7004080210E0019FB0220202178
-:101640000A001BA7004080210E001A9C02202021C6
-:101650000A001BA7004080211509000E00000000B1
-:101660000E001920022020210A001BA70040802123
-:101670000E001697A382004C0A001BA70040802191
-:1016800014620017020020212402002314E2000546
-:101690002402000B0E001992022020210A001BA731
-:1016A0000040802102202021A382004C0E001697CA
-:1016B0002410FFFF0A001BA80200202130A500FF14
-:1016C0000E00159524060001978300428F82004486
-:1016D000A780004200431023AF8200440200202173
-:1016E0008FBF00188FB100148FB000100080102140
-:1016F00003E0000827BD002027BDFFE0AFB10014C4
-:10170000AFBF0018AFB000108F4601283C0308009F
-:101710008C6331A02402FF80AF86005000C31821E3
-:101720003065007F03452821006218243C02000A2E
-:10173000AF43002400A2282190A2006200808821EB
-:10174000AF850028304200FF00021102A382004052
-:1017500090A200BC30420002144000022403003476
-:10176000240300308F820028A3830030938300403D
-:101770008C4200C0A380004CAF82004424020004CD
-:10178000106200308F8400448E2400045080002DAD
-:101790008F8400448E2200103083FFFFA784004214
-:1017A0001060001FAF8200488F8300282405FF804F
-:1017B000022020219062006300A21024304200FF2A
-:1017C0001440000D000000000E001B139790004213
-:1017D00010400010004018212402FFFD5462001147
-:1017E0008E230020020028210E0015360220202121
-:1017F0000A001BF98E2300209062006300A21024CF
-:10180000304200FF10400003022020210E00185B30
-:1018100000000000978200421440FFE48F830028FC
-:101820008E23002030620004104000068F840044A4
-:101830002402FFFB006210240E00154AAE22002095
-:101840008F8400448F8300288FBF00188FB100144D
-:101850008FB000102402000127BD002003E0000823
-:10186000AC6400C030A500FF2403000124A90001DE
-:101870000069102B1040000C00004021240A0001D8
-:1018800000A31023004A38042463000130820001C1
-:101890000069302B1040000200042042010740255F
-:1018A00054C0FFF800A3102303E00008010010213A
-:1018B00027BDFFE03C021EDCAFB20018AFB1001440
-:1018C000AFBF001CAFB0001034526F410000882140
-:1018D000240500080E001C09022020210011808030
-:1018E0003C07080024E775F40002160002071821DF
-:1018F000AC6200000000282124A200013045FFFF57
-:101900008C6200002CA60008044100020002204066
-:101910000092202614C0FFF8AC640000020780216A
-:101920008E0400000E001C0924050020262300015F
-:101930003071FFFF2E2301001460FFE5AE020000AE
-:101940008FBF001C8FB200188FB100148FB0001031
-:1019500003E0000827BD00203C02080024426EB8C6
-:101960003C010800AC2275E83C02080024425430D7
-:101970003C010800AC2275EC240200063C01080082
-:10198000A02275F00A001C1C0000000027BDFFD833
-:10199000AFB3001CAFB20018AFBF0020AFB100144E
-:1019A000AFB000108F5101408F48014800089402E9
-:1019B000324300FF311300FF8F4201B80440FFFEA5
-:1019C00027500180AE1100008F420144AE02000496
-:1019D00024020002A6120008A202000B2402001436
-:1019E000AE13002410620025286200151040000884
-:1019F000240200152402001010620030240200129C
-:101A0000106200098FBF00200A001D468FB3001C22
-:101A10001062007024020022106200378FBF002085
-:101A20000A001D468FB3001C3C0208008C4231A006
-:101A30002403FF800222102100431024AF4200241F
-:101A40003C0208008C4231A0022210213042007F6B
-:101A5000034218213C02000A00621821166000BCF3
-:101A6000AF830028906200623042000F34420030A1
-:101A7000A06200620A001D458FBF00203C04600088
-:101A80008C832C083C02F0033442FFFF00621824D0
-:101A9000AC832C083C0208008C4231A08C832C08BB
-:101AA0002442007400021082000214800062182593
-:101AB000AC832C080A001D458FBF00203C020800A3
-:101AC0008C4231A02403FF80022210210043102405
-:101AD000AF4200243C0208008C4231A03C03000AC3
-:101AE000022210213042007F0342102100431021C6
-:101AF0000A001D44AF8200283C0208008C4231A03D
-:101B00002405FF800222102100451024AF4200244A
-:101B10003C0208008C4231A0022210213042007F9A
-:101B2000034218213C02000A0062182190620063FF
-:101B300000A21024304200FF10400085AF8300282F
-:101B400024620088944300123C0208008C4231A8B1
-:101B500030633FFF0003198002221021004310214F
-:101B60003043007F03432021004510243C03000C38
-:101B700000832021AF4200289082000D00A2102493
-:101B8000304200FF10400072AF84002C9082000DA4
-:101B9000304200101440006F8FBF00200E00166608
-:101BA000000000008F4201B80440FFFE000000006A
-:101BB000AE1100008F420144AE0200042402000274
-:101BC000A6120008A202000BAE1300240A001D4555
-:101BD0008FBF00202406FF8002261024AF42002081
-:101BE0003C0208008C4231A031043FFF00042180F8
-:101BF0000222102100461024AF4200243C030800BA
-:101C00008C6331A83C0208008C4231A03227007F4F
-:101C10000223182102221021006418213042007F83
-:101C20003064007F034228213C02000A0066182429
-:101C300000A22821034420213C02000C0082202124
-:101C4000AF4300283C02000803471821006290219E
-:101C5000AF850028AF84002C0E001666010080219D
-:101C60008F4201B80440FFFE8F82002C8F84002831
-:101C7000274501809042000DACB10000A4B00006E1
-:101C8000000216000002160300021027000237C2ED
-:101C900014C00016248200889442001232033FFFD1
-:101CA00030423FFF1443001224026082908300639D
-:101CB0002402FF8000431024304200FF5040000CFB
-:101CC00024026082908200623042000F3442004061
-:101CD000A082006224026084A4A200082402000DF5
-:101CE000A0A200050A001D2F3C02270024026082EA
-:101CF000A4A20008A0A000053C02270000061C00CA
-:101D00000062182524020002A0A2000BACA3001060
-:101D1000ACA00014ACA00024ACA00028ACA0002C07
-:101D20008E42004C8F84002CACA200189083000DD2
-:101D30002402FF8000431024304200FF10400005C1
-:101D40008FBF00209082000D3042007FA082000DE6
-:101D50008FBF00208FB3001C8FB200188FB100140A
-:101D60008FB000103C02100027BD002803E00008DF
-:041D7000AF4201B8C5
-:0C1D7400080033F8080033F80800337052
-:101D8000080033A8080033DC0800340008003400E1
-:081D900008003400080032E0F5
-:081D98000A0001220000000016
-:101DA000000000000000000D747061352E302E30F0
-:101DB0006A3600000500000100000000000000007D
-:101DC0000000000000000000000000000000000013
-:101DD0000000000000000000000000000000000003
-:101DE00000000000000000000000000000000000F3
-:101DF00000000000000000000000000000000000E3
-:101E000000000000000000000000000000000000D2
-:101E100000000000000000000000000000000000C2
-:101E20000000000010000003000000000000000D92
-:101E30000000000D3C02080024421B803C03080007
-:101E400024632014AC4000000043202B1480FFFDCD
-:101E5000244200043C1D080037BD2FFC03A0F021E4
-:101E60003C100800261004883C1C0800279C1B809E
-:101E70000E00015A000000000000000D3084FFFF3A
-:101E8000308200078F85001810400002248300076D
-:101E90003064FFF80085302130C41FFF034418214F
-:101EA000247B4000AF85001CAF84001803E00008CD
-:101EB000AF4400843084FFFF308200078F8500200C
-:101EC0008F86002810400002248300073064FFF84A
-:101ED000008520210086182B14600002AF850024A5
-:101EE000008620230344282134068000AF8400208C
-:101EF000AF44008000A6202103E00008AF84003832
-:101F000027BDFFD8AFB3001CAFB20018AFB00010B0
-:101F1000AFBF0024AFB40020AFB100143C0860088C
-:101F20008D1450002418FF7F3C1A800002989824DA
-:101F30003672380CAD1250008F5100083C07601CFF
-:101F40003C08600036300001AF500008AF80001838
-:101F5000AF400080AF4000848CE600088D0F080879
-:101F60003C0760168CEC000031EEFFF039CA00101F
-:101F70003C0DFFFF340B80003C030080034B4821E5
-:101F80002D440001018D28243C0253533C010800DC
-:101F9000AC230420AF890038AF860028AF8400103E
-:101FA000275B400014A2000334E37C008CF900049A
-:101FB000032818218C7F007C8C6500783C0280000F
-:101FC00034520070AF85003CAF9F00403C130800C6
-:101FD00026731BC40240A0218E4800008F460000DB
-:101FE00038C300013064000110800017AF8800344E
-:101FF000028048218D2D00003C1908008F39045CB7
-:102000003C1108008E31045801A8F823033F7821C1
-:10201000000040210228382101FF802B00F07021B0
-:102020003C010800AC2F045C3C010800AC2E0458B5
-:102030008F4C0000398B0001316A00011540FFED23
-:1020400001A04021AF8D00348E4E00003C0C0800F2
-:102050008D8C045C3C0A08008D4A045801C8682332
-:10206000018D28210000582100AD302B014B20218B
-:10207000008610213C010800AC25045C3C010800EE
-:10208000AC2204588F4501088F44010030A920007C
-:10209000AF850000AF84000C1120000A00A03021A1
-:1020A0003C0708008CE7042C24EF00013C010800E9
-:1020B000AC2F042C3C104000AF5001380A000190B6
-:1020C0000000000030B002001600001424110F00C0
-:1020D0001091001224070D001087023330B0000663
-:1020E0005200FFF53C104000936D0000240C0010DE
-:1020F00031A600F010CC0269240E007010CE02DD73
-:102100008F8B001425670001AF8700143C1040003E
-:10211000AF5001380A000190000000009748010408
-:102120001100FFE53C10400030B84000170000A24D
-:10213000000000008F5901780720FFFE8F870038CC
-:1021400024090008240508008CE30008AF45017845
-:10215000A7490140A7400142974201048F86000031
-:102160003049FFFF30DF000113E002D5012040219C
-:102170002524FFFE240A0002A74A01463088FFFFFB
-:10218000A74401483C0B08008D6B043C156002C459
-:102190008F8F000C30C3002014600002240400095B
-:1021A0002404000130CD0C00240C040051AC0001CB
-:1021B00034840004A744014A3C0508008CA504208F
-:1021C0003C0200483C19000100A2F82530D800026A
-:1021D00003F9282513000004000018213C04010025
-:1021E00000A428252403000130CA00045140000542
-:1021F000AF8300083C06001000A628252403000138
-:10220000AF830008AF451000000000000000000090
-:1022100000000000000000008F8300081060002311
-:10222000000000008F4B10000561FFFE0000000061
-:102230001060001E000000008F4D10003C030020C5
-:1022400001A36024118000198F8F000031EE00027D
-:1022500011C0001600000000975010141600001363
-:10226000000000009745100830BFFFFF27F8000668
-:102270000018C8820019308000C7282133110001DE
-:1022800033030003122003208CA200000000000D85
-:1022900000C7F821AFE200003C1908008F39043074
-:1022A000272600013C010800AC2604308F6A00009C
-:1022B0003405FFFFAF8A00048CE200001045029A4B
-:1022C000000020218CE5000030BF010013E0027EF9
-:1022D000010020213C0708008CE704743C10080032
-:1022E0008E10044C00E858213C1808008F18047028
-:1022F0000168882B3C0808008D08044800007821FC
-:1023000002046021030F18210184702B010F682142
-:102310000071502101AE10213C010800AC2C044C8E
-:102320003C010800AC2204483C010800AC2B0474BA
-:102330003C010800AC2A04708F8D00180120302168
-:102340003129000725AE000831C21FFF034260217A
-:10235000AF8D001CAF820018259B4000AF42008467
-:10236000112000038F90002024C800073106FFF8D9
-:102370008F84002800D0282100A4782B15E00002CB
-:10238000AF90002400A428230345202134038000BB
-:10239000008310213C061000AF850020AF8200387A
-:1023A000AF450080AF4601788F8B00142567000190
-:1023B0000A0001DDAF8700148F6200088F670000FC
-:1023C000241100300007C602330300F0107100A290
-:1023D000241900401479FF4B8F8B00148F4A017829
-:1023E0000540FFFE30A7020014E000030005128242
-:1023F0000000000D0005128230500003001049005B
-:1024000001307021000E688001B06021000C5880FE
-:10241000017380218E0800001500000200000000FA
-:102420000000000D8F6F000405E202B19203000668
-:1024300092070005920F00043C020001000728806B
-:1024400000B060218D8900182771000825EE000575
-:1024500001226821000E3082AD8D0018022020215B
-:102460000E00058026050014920B00068F7F0004E5
-:102470003C087FFF000B2080009130218CC30004BA
-:10248000350AFFFF03EAC8240079C021ACD8000454
-:102490009207000592090004960D000800072880A5
-:1024A00000B1F8218FEF0000974201043C07FFFFC5
-:1024B00001E75024304EFFFF01C96021018D5823F0
-:1024C0003168FFFF01482025AFE4000092030007B8
-:1024D00024190001107902692406000310660279AC
-:1024E000000000008E190010241F000AA75F0140A1
-:1024F000A7590142920300048F86000024070001BF
-:10250000A7430144A74001469758010430D1000277
-:102510003C050041A758014800001821A747014A7F
-:102520001220000330CA00043C05014124030001CD
-:1025300051400005AF8300083C08001000A8282582
-:1025400024030001AF830008AF4510000000000025
-:102550000000000000000000000000008F8B000859
-:1025600011600004000000008F4410000481FFFE91
-:10257000000000008F6A0000920700043C0508007C
-:102580008CA50444AF8A0004975F01043C0F080047
-:102590008DEF044030E300FF33F9FFFF0079C021E5
-:1025A00000B868210000102124E6000A30C8FFFFAF
-:1025B00001B8482B01E2702101C9602131100007E8
-:1025C0003C010800AC2D04443C010800AC2C044044
-:1025D000120000038F8D0018250B00073168FFF8EB
-:1025E000010D702131CC1FFFAF8D001CAF8C001886
-:1025F000AF4C008497440104034C80213084FFFFDA
-:102600003088000711000003261B400024890007C2
-:102610003124FFF88F8200208F850028008220213E
-:102620000085782B15E00002AF820024008520236E
-:102630000344882134058000022510213C06100047
-:10264000AF840020AF820038AF440080AF460178ED
-:102650000A0002858F8B00148F5F017807E0FFFE70
-:1026600030AA020015400003000542820000000D60
-:1026700000054282310200030002710001C268219C
-:10268000000D6080018248210009288000B380216C
-:102690008E0B000011600002000000000000000D21
-:1026A0008F6F000C05E001F38F87003824190001BB
-:1026B000AE1900008CE30008A20000078F78000428
-:1026C00000181C02306600FF24D100050011308282
-:1026D0002CC4004114800002A20300040000000D7D
-:1026E0008F6B00043C0EFFFF00E028213164FFFFE8
-:1026F000248F000B000F4082000810800047482103
-:102700008D2D000026040014A60B000801AE6024E5
-:102710000E000580AD2C00008F5F01083C0A100000
-:1027200003EA382410E001A30000000097460104EA
-:102730009203000724D1FFEC346500023224FFFF2E
-:10274000A2050007960600082CC7001354E00005F8
-:1027500092030007920A0007355F0001A21F0007DD
-:1027600092030007240B0001106B01BA2409000337
-:10277000106901CD8F88003830CFFFFF25E40002BB
-:102780000004C883333F00FF001F2880A219000502
-:1027900000A858218D780000975101043C03FFFFE9
-:1027A000030360243222FFFF004F702325CDFFFE7C
-:1027B000018D4825AD690000920600053C02FFF638
-:1027C000344EFFFF30CA00FF000A388000F020219D
-:1027D000909900143C1FFF7F37E7FFFF3323000F62
-:1027E0000066782131F800FF0018288000B08821A9
-:1027F0008E2D002000A86021A20F000601AE482403
-:10280000AE0D000CAD89000C920B00068E04000C7E
-:102810000127F824000B50800150C821972600267C
-:102820000148C02100874024AF260024AE08000CD8
-:10283000AF3F0020AF0600108F860000240C001070
-:1028400024090002A74C0140A7400142A7400144CF
-:10285000A7490146974B01042407000130C8000234
-:10286000256AFFFEA74A01483C050009A747014A1F
-:1028700011000003000018213C0501092403000198
-:1028800030CD000451A00005AF8300083C060010C5
-:1028900000A6282524030001AF830008AF451000DF
-:1028A0000000000000000000000000000000000028
-:1028B0009218000427110002322F0007000F102386
-:1028C000304E0007AE0E00108F900008120000047A
-:1028D000000000008F4310000461FFFE00000000B4
-:1028E0008F7800008F8F00183C1008008E10044471
-:1028F000AF9800049751010425E6001030CA1FFF6D
-:102900003222FFFFAF8F001CAF8A0018AF4A00844D
-:102910002449FFFE3C0B08008D6B0440974E0104D8
-:1029200001206821000967C3020D282131C9FFFF7A
-:1029300000AD402B016C382100E82021034AF8212A
-:10294000313900073C010800AC2504443C01080073
-:10295000AC2404401320000327FB4000252300077C
-:102960003069FFF88F9F00208F840028013F3821B5
-:1029700000E4C82B17200002AF9F002400E4382396
-:102980000347202134058000008510213C061000FB
-:10299000AF870020AF820038AF470080AF46017894
-:1029A0000A0002858F8B0014975801041300FDC2A2
-:1029B0003C1040008F4301780460FFFE30B94000B6
-:1029C000132000033C0400080000000D3C04000834
-:1029D000AF44014024080800AF4801788F8B000005
-:1029E000974A0104317F000113E000E93146FFFFFF
-:1029F00024D0FFFE240C0002A74C0146A75001483A
-:102A00008F8F00182405000DA745014A8F71000023
-:102A100025E2000830491FFF0349702130CD00072F
-:102A2000AF910004AF8F001CAF89001800C038219F
-:102A3000AF49008411A0000325DB400024C6000735
-:102A400030C7FFF88F9800208F84002800F83021CD
-:102A500000C4382B14E00002AF98002400C43023D7
-:102A60008F8A001403465821340880000168F82139
-:102A7000255900013C0310003C104000AF860020A7
-:102A8000AF9F0038AF460080AF430178AF99001484
-:102A9000AF5001380A000190000000008F6900006B
-:102AA000974401043127FFFF3088FFFF8F4F0178E3
-:102AB00005E0FFFE30FF0007001F182330780007F5
-:102AC00024E6FFFE2419000AA7590140A758014235
-:102AD000A7460144A7400146A74801488F42010884
-:102AE00030510020162000022403000924030001B5
-:102AF00030AA0002A743014A3C04004111400003F0
-:102B0000000018213C0401412403000130AB000403
-:102B100051600005AF8300083C05001000852025AA
-:102B200024030001AF830008AF4410000000000040
-:102B30000000000000000000000000008F9000086E
-:102B400012000004000000008F4C10000581FFFE01
-:102B5000000000008F780000276200088F8D003C85
-:102B6000AF980004944600089451000A944F000C5A
-:102B700030CEFFFF0011240031E9FFFF11CD00A28C
-:102B8000008920253C0308008C6304443C1808009D
-:102B90008F18044000E85021255FFFFE007F782158
-:102BA0000000102101FF302B03028821022648215A
-:102BB0003C010800AC2F04443C010800AC2904404F
-:102BC00024EB00083162FFFF3047000710E00003EC
-:102BD0008F850018245000073202FFF83106FFFFEE
-:102BE00030C800070045702131CD1FFF034D602123
-:102BF000AF85001CAF8D0018259B4000AF4D0084B1
-:102C0000110000038F8F002024C400073086FFF8D6
-:102C10008F84002800CF282100A4482B1520000213
-:102C2000AF8F002400A42823AF850020AF4500808B
-:102C30003C1108008E3104340345C0213402800069
-:102C40000302302112200005AF860038938300175D
-:102C50002419000E1079000D241F043F3C0A1000B7
-:102C6000AF4A01788F8B0014256700010A0001DD4F
-:102C7000AF8700140E0005A63C1040008F8B001497
-:102C8000256700010A0001DEAF8700143C0A10002E
-:102C9000A75F0148AF4A01780A0004B48F8B001483
-:102CA000240E0F0011EE003D30D10020162000024E
-:102CB00024030009240300010A000208A743014A73
-:102CC0000A0001FBA740014694E5000894E2000ACF
-:102CD00094EB000C8F86003C0002FC00316AFFFF81
-:102CE00030B9FFFF1326003703EA20253C05080012
-:102CF0008CA504443C1F08008FFF044000005021B5
-:102D000000A8382100E8302B03EAC8210326C0219F
-:102D10003C010800AC2704443C010800AC380440E6
-:102D20000A0002698F8D00183C1908008F39047C55
-:102D30003C0308008C6304543C0608008CC60478ED
-:102D40003C0F08008DEF04500328382100686821EB
-:102D500000E8C02B00C4882101A8402B01E47021A9
-:102D60000238582101C860213C010800AC2D0454F0
-:102D70003C010800AC2C04503C010800AC27047C4A
-:102D80003C010800AC2B04780A0002698F8D001802
-:102D9000A74001460A00041B8F8F001830D0002086
-:102DA0001600FFC52403000D240300050A000208D5
-:102DB000A743014A975901042738FFF00A00036B23
-:102DC0003304FFFF8F8C0040148CFFC8000080216B
-:102DD0003C1108008E31046C3C0408008C840468AB
-:102DE0000228702101C8782B00904021010F682132
-:102DF0003C010800AC2E046C3C010800AC2D0468BA
-:102E00000A0002698F8D00188F9900401499FF5DA8
-:102E1000000060213C0508008CA5046C3C100800F3
-:102E20008E10046800E82021248EFFFE00AEF821F9
-:102E300003EE582B020C5021014B18213C010800D5
-:102E4000AC3F046C3C010800AC2304680A00048B0E
-:102E500024EB00088F8800383C02FFFF8D0E000C29
-:102E600001C2682401A46025AD0C000C0A0003799E
-:102E700030CFFFFF0A0003A9AE000000974B01040A
-:102E8000920400048E2A000C01644021251FFFF2E9
-:102E90000147182433F9FFFF0079C025AE38000C34
-:102EA0000A0002D48E1900103C03FFFF8D110010A0
-:102EB0000223282400A47825AD0F00100A0003790E
-:102EC00030CFFFFF97450104920600048E2F0010BB
-:102ED00000A610212449FFEE01E76824312EFFFFF0
-:102EE00001AE6025AE2C00100A0002D48E1900102D
-:102EF0008E06000CAE0000000003C0800310882185
-:102F00000A0002A6AE2600201460000D3050FFFF1C
-:102F10003C04FFFF0044602401846826000D582B08
-:102F2000000C502B014B1024104000020000000048
-:102F30000000000D8CA300000A00023E0064102572
-:102F40003A11FFFF0011782B0010702B01CF2024C5
-:102F500010800002000000000000000D8CB800008E
-:102F60000A00023E3702FFFF3084FFFF30A5FFFF5B
-:102F7000108000070000182130820001104000027C
-:102F800000042042006518211480FFFB0005284042
-:102F900003E000080060102110C0000700000000DE
-:102FA0008CA2000024C6FFFF24A50004AC82000010
-:102FB00014C0FFFB2484000403E0000800000000AC
-:102FC00010A0000824A3FFFFAC8600000000000052
-:102FD000000000002402FFFF2463FFFF1462FFFAD9
-:102FE0002484000403E0000800000000308EFFFF8E
-:102FF00030D8FFFF00057C0001F8602539CDFFFFC8
-:1030000001AC5021014C582B014B482100094402CE
-:103010003127FFFF00E830210006240230C5FFFF02
-:1030200000A418213862FFFF03E000083042FFFFD0
-:103030003C0C08008D8C0484240BFF8027BDFFD03E
-:1030400001845021014B4824AF4900203C0808006E
-:103050008D080484AFB20020AFB00018AFBF0028C5
-:10306000AFB30024AFB1001C936600040104382103
-:1030700030E4007F009A10213C03000800439021B7
-:1030800030C50020036080213C080111277B000827
-:1030900014A00002264600702646006C921300041D
-:1030A00097510104920F00043267000F322EFFFF88
-:1030B00031ED004001C7282311A000050000482180
-:1030C000925900BC33380004170000900000000043
-:1030D000924300BC307F000413E0000F00000000AA
-:1030E00010A0000D00000000960E0002240AFF80D0
-:1030F00000A7602125CDFFFEA74D1016920B0004FE
-:10310000014B2024308200FF10400085010C402537
-:103110003C0F0400010F40258F5301780660FFFE2D
-:103120002404000AA7440140960D0002240400096B
-:1031300031AC0007000C5823316A0007A74A01424E
-:10314000960200022443FFFEA7430144A740014624
-:10315000975F0104A75F01488F59010833380020A9
-:103160005300000124040001920F000431EE00100E
-:1031700015C000023483001000801821A743014AC3
-:10318000000000000000000000000000000000003F
-:10319000AF48100000000000000000000000000028
-:1031A000000000008F5110000621FFFE3113FFFFC9
-:1031B00012600003000000008F481018ACC8000027
-:1031C00096030006307FFFFF27F90002001998825E
-:1031D00000138880023B30218CD800001520005756
-:1031E00000183402920300042405FF8000A3F82491
-:1031F00033F100FF1220002C00000000924700BCB9
-:1032000030F200021240002800000000974B100C22
-:103210002562FFFEA7421016000000003C0A0400D1
-:1032200035490030AF4910000000000000000000E8
-:1032300000000000000000008F4C10000581FFFE20
-:10324000000000009749100C8F51101C00C0202175
-:103250003127FFFF24F2003000121882000328807B
-:1032600000BBF8213226FFFFAFF100000E000595EC
-:1032700000112C020013C880033B98218E780000B7
-:1032800000027400AFB800108FA80010310FFFFFCC
-:10329000AFAF00108FA4001001C46825AFAD0010BF
-:1032A0008FA60010AE66000097730008976D000AA5
-:1032B0009766000C8F8A003C000D5C0030CCFFFF4D
-:1032C0003262FFFF104A0036016C2025960600028C
-:1032D0003C10100024D300080E0001393264FFFFB7
-:1032E000974C01040E0001473184FFFFAF50017875
-:1032F0008FBF00288FB300248FB200208FB1001C35
-:103300008FB0001803E0000827BD003010A0FF7048
-:103310000000000024A5FFFC0A0005CE24090004DB
-:103320008CD10000AF5110188F5301780660FF7ADE
-:103330002404000A0A0005E30000000000A7C821D9
-:103340008F8800388F4E101C0019C08200187880BA
-:1033500001E82021AC8E0000000E2C0200C02021CC
-:103360000E00059531C6FFFF023B28218CAD000001
-:103370000002540000403021AFAD00108FAC0010AF
-:10338000318BFFFFAFAB00108FA200100142482528
-:10339000AFA900108FA700100A000613ACA7000009
-:1033A0008F8F0040148FFFC9000000009742010476
-:1033B000960B00023C0508008CA5046C3049FFFF09
-:1033C000316AFFFF3C1108008E310468012A382160
-:1033D00024F2FFFE00B240210012FFC30112C82BED
-:1033E000023FC021031920213C010800AC28046CD5
-:1033F0003C010800AC2404680A00064D00000000EF
-:1034000000A4102B104000092403000100052840EF
-:1034100000A4102B04A00003000318405440FFFC3C
-:103420000005284010600007000000000085302BD8
-:1034300014C0000200031842008520231460FFFB23
-:103440000005284203E00008008010218F85002C31
-:1034500027BDFFE8000530272CC300012CA4000283
-:103460000083102510400003AFBF00102405007F2B
-:10347000AF85002C0005282730A5FFFF0E0005743E
-:10348000240426F58F830030240402BD004030213F
-:103490000083382B10E000092405000100042040BF
-:1034A0000083102B04800003000528405440FFFCDB
-:1034B0000004204010A0000800C350210064402BED
-:1034C00015000002000528420064182314A0FFFB29
-:1034D0000004204200C350218FBF0010000A4C029C
-:1034E000312200FF27BD0018AF8A002C03E000083E
-:0434F000AF89003070
-:0C34F4000A00002A000000000000000098
-:103500000000000D747870352E302E306A360000C1
-:10351000050000000000000A000001360000EA601B
-:10352000000000000000000000000000000000009B
-:10353000000000000000000000000000000000008B
-:10354000000000000000000000000000000000007B
-:103550000000000000000016000000000000000055
-:10356000000000000000000000000000000000005B
-:10357000000000000000000000000000000000004B
-:1035800000000000000000000000000000001388A0
-:1035900000000000000005DC00000000000000004A
-:1035A00010000003000000000000000D0000000DEE
-:1035B0003C02080024423B603C03080024633D14A5
-:1035C000AC4000000043202B1480FFFD2442000487
-:1035D0003C1D080037BD7FFC03A0F0213C10080013
-:1035E000261000A83C1C0800279C3B600E0002BA75
-:1035F000000000000000000D8F8300383C088000B0
-:10360000350700708CE50000008330253C029000F7
-:1036100000C22025AF850030AF4400208F49002034
-:103620000520FFFE3C038000346200708C450000E2
-:103630008F8600303C1908008F39007C3C0E080052
-:103640008DCE007800A62023032458210000782185
-:103650000164682B01CF6021018D50213C010800DD
-:10366000AC2B007C3C010800AC2A007803E0000889
-:10367000000000000A000041240400018F8400388B
-:103680003C05800034A200010082182503E00008F8
-:10369000AF43002003E00008000010213084FFFF4A
-:1036A00030A5FFFF108000070000182130820001C4
-:1036B0001040000200042042006518211480FFFB26
-:1036C0000005284003E000080060102110C000073A
-:1036D000000000008CA2000024C6FFFF24A5000407
-:1036E000AC82000014C0FFFB2484000403E0000847
-:1036F0000000000010A0000824A3FFFFAC8600001B
-:1037000000000000000000002402FFFF2463FFFF10
-:103710001462FFFA2484000403E0000800000000A3
-:10372000308AFFFF93A80013A74A014497490E1659
-:1037300030C600FF3C021000A7490146AF450148D2
-:10374000A3460152A748015AAF4701608FA4001851
-:103750008FA30014A7440158AF43015403E00008AD
-:10376000AF42017803E00008000000003C03800045
-:10377000346200708C4900008F88000024840007A8
-:1037800027BDFFF83084FFF8AF890030974D008ADD
-:1037900031ACFFFFAFAC00008FAB000001685023DD
-:1037A0002547FFFF30E61FFF00C4282B14A0FFF7BA
-:1037B0003C0C8000358B00708D6A00003C070800CF
-:1037C0008CE700843C0608008CC60080000810824C
-:1037D000014918230002788000E3702100002021B5
-:1037E00001C3C82B00C4C02101FA4021031948219C
-:1037F0002502400027BD00083C010800AC2E0084D3
-:103800003C010800AC29008003E000080000000033
-:103810008F8200002486000730C5FFF800A218211F
-:1038200030641FFF03E00008AF8400008F8700387A
-:103830008F8A004027BDFFB88F860044AFB6004096
-:10384000AFBF0044AFB5003CAFB40038AFB30034F5
-:10385000AFB20030AFB1002CAFB000288F450104EB
-:103860008D4900ACAF4700808CC8002000A93823E8
-:103870000000B021AF480E108F440E100000482108
-:10388000AF440E148CC20024AF420E188F430E18A2
-:10389000AF430E1C10E001252D230001936B00089F
-:1038A000116000D400000000976E001031CDFFFFC2
-:1038B00000ED602B158000CF000000009770001015
-:1038C000320FFFFFAF4F0E008F5200003251000841
-:1038D0001220FFFD0000000097540E088F460E04D2
-:1038E0003285FFFF30B3000112600132000000009A
-:1038F0000000000D30B8A04024150040131500C092
-:1039000030A9A0001120012D00000000937F0008C5
-:1039100013E000080000000097630010306BFFFF09
-:1039200000CB402B1100000330AC0040118001237C
-:1039300000000000A785003CAF86003493660008B5
-:1039400000E02821AFA7002014C0012427B30020E5
-:10395000AF60000C9782003C3047400014E000024A
-:10396000240300162403000E24194007A363000A51
-:10397000AF790014938A003E8F7400143158000709
-:103980000018AA4002959025AF7200149784003C5D
-:103990008F7000143091001002117825AF6F001461
-:1039A000978E003C31CD000811A00147000028216E
-:1039B0008F6700143C0210003C0C810000E22825B7
-:1039C000AF65001497460E0A2408000E3405FFFC6C
-:1039D00030C3FFFF006C5825AF6B0004A3680002E2
-:1039E000937F000A27E90004A369000A9786003C38
-:1039F0009363000A30CC1F00000C598301634021FF
-:103A0000251F0028A37F000997490E0CA769001005
-:103A100093790009272A0002315800070018A823CB
-:103A200032B10007A371000B937400099764001072
-:103A30008F910034978F003C329200FF0244802126
-:103A40000205702131ED004011A0000531C4FFFFD7
-:103A50000091282B3C12800010A000140000A0212F
-:103A60000224382B14E0011B8FA500208F4D0E146B
-:103A7000AF4D0E108F420E1CAF420E18AF440E0019
-:103A80008F4F000031EE000811C0FFFD0000000064
-:103A900097540E080080882100009021A794003CD4
-:103AA0008F500E0424140001AF900034976400106E
-:103AB0003095FFFF8E6800000111F82317E0000920
-:103AC000AE7F00008F6500148F8B004434A6004049
-:103AD000AF6600148F4C0E10AD6C00208F430E1893
-:103AE000AD6300249367000814E000D200000000DA
-:103AF0000E00009E240400108F8900483C0832000C
-:103B000000402821312600FF0006FC0003E8502574
-:103B100025390001AF990048AC4A000093780009AC
-:103B20009370000A330400FF00047400320F00FF9A
-:103B300001CF6825AC4D00048F820048064000EAA2
-:103B4000ACA20008ACA0000C9783003C306B0008CE
-:103B5000156000022628000626280002974E0E1443
-:103B60008F450E1C8F670004936D000231C4FFFF68
-:103B700031A200FFAFA200108F6C0014AFA8001894
-:103B80000E00008BAFAC0014240400100E0000C720
-:103B9000000000008E7200001640000500000000CA
-:103BA0008F6400142405FFBF00859824AF730014B0
-:103BB0008F79000C03353821AF67000C937500082E
-:103BC00016A000080000000012800006000000009F
-:103BD0008F7F00143C0BEFFF3568FFFE03E848249D
-:103BE000AF690014A37400088FA500200A000246E4
-:103BF00002202021AF470E000A0000F5000000005F
-:103C00008F5901780720FFFE241F08008F840000D1
-:103C1000AF5F0178974B008A316AFFFF0144482368
-:103C20002528FFFF31021FFF2C4300081460FFF915
-:103C3000000000008F8E00488F8D003800C04821A2
-:103C40000344202125C60001240C0F00AF86004844
-:103C500000E938232486400031CA00FF11AC00057A
-:103C6000240800019391003E3230000700107A4092
-:103C700035E80001000AAC003C18010002B8A0259C
-:103C8000AC9440008F93004830B2003630A4000856
-:103C9000ACD300041080009701123025974E0E0A15
-:103CA0008F8D00003C02810031CCFFFF25AB000866
-:103CB000018240253C03100031651FFF25390006B5
-:103CC000241F000EAF48016000C33025A75F015AD2
-:103CD000AF850000A759015814E0000A8F930038FF
-:103CE00024120F00527200022416000134C6004054
-:103CF0008F580E108F940044AE9800208F550E18E8
-:103D0000AE9500248F450E14AF4501448F590E1C0B
-:103D1000AF590148A34A01523C0A1000AF46015472
-:103D2000AF4A017814E0FEDD2D2300010076A025C6
-:103D3000128000178FBF00448F84003824160F00B4
-:103D400010960084000000008F45017804A0FFFE5B
-:103D500024150F001095006E000000008F470E1410
-:103D6000240202403C1F1000AF4701448F440E1C48
-:103D7000AF440148A3400152A740015AAF4001603F
-:103D8000A7400158AF420154AF5F01788FBF004494
-:103D90008FB600408FB5003C8FB400388FB300342D
-:103DA0008FB200308FB1002C8FB0002803E00008E4
-:103DB00027BD004814C0FED030B8A0408F420E147A
-:103DC0008F84004400004821AC8200208F510E1CDB
-:103DD000AC9100240A00020E2D2300018F910034C3
-:103DE000978A003C3C1280000220A82131580040F4
-:103DF0001700FF300000A021976900108F92003457
-:103E00003139FFFF133200350000202100804821A6
-:103E10001480FEA000A038218F420E148F8400442D
-:103E2000AC8200208F510E1CAC9100240A00020EBF
-:103E30002D230001936A00099378000B315000FF95
-:103E4000330F00FF020F702125C2000A3050FFFF20
-:103E50000E00009E020020218F8600483C1F41007A
-:103E600024CD0001AF8D0048936C000930C600FFDF
-:103E700000064400318300FF246B0002010B48253B
-:103E8000013FC825AC5900008F67000C97440E1401
-:103E900000F22825AC4500048F450E1C8F670004F6
-:103EA000936A00023084FFFF315800FFAFB8001062
-:103EB0008F6F0014AFB100180E00008BAFAF00146D
-:103EC0000A0001A602002021AF6000040A00013EA2
-:103ED000A36000020A000246000020210000902199
-:103EE0000A000170241400013C1280000A000195B0
-:103EF000ACB2000C8F91000025240002A7440158A9
-:103F000026300008320F1FFF0A0001F9AF8F0000B2
-:103F1000AF40014C1120002C000000008F590E1002
-:103F2000AF5901448F430E18240200403C1F10007B
-:103F3000AF430148A3400152A740015AAF4001607E
-:103F4000A7400158AF420154AF5F01780A00022731
-:103F50008FBF0044112000060000000097460E08A5
-:103F600030CC004015800002000000000000000D71
-:103F70008F4D017805A0FFFE0000000097530E1042
-:103F80003C120500240E2000326AFFFF0152C025BA
-:103F9000AF58014C8F4F0E143C021000AF4F01443C
-:103FA0008F500E1CAF500148A34001528F8400383F
-:103FB000A740015AAF400160A7400158AF4E0154DD
-:103FC0000A000215AF4201788F490E14AF4901442F
-:103FD0008F430E1C0A00028E240200403C0E20FF7C
-:103FE00027BDFFE03C1A80003C0F800835CDFFFD67
-:103FF000AFBF001CAFB20018AFB10014AFB00010DB
-:10400000AF8F0040AF4D0E00000000000000000028
-:104010000000000000000000000000003C0C00FF59
-:10402000358BFFFDAF4B0E003C0660048CC9500081
-:10403000240AFF7F3C116000012A40243507380C18
-:10404000ACC750008E24043824050009AF45000891
-:104050003083FFFF38622F712450C0B3AF80004817
-:104060000E000068AF80000052000001AE20442C1A
-:104070000E0004353C1180000E000EA83630007092
-:104080008F8A00403C12080026523BC8020088215B
-:104090008E0800008F5F00003BF9000133380001FB
-:1040A00013000017AF880030022048218D27000040
-:1040B0003C0F08008DEF006C3C0C08008D8C0068F4
-:1040C00000E8C02301F828210000682100B8302B47
-:1040D000018D5821016640213C010800AC25006C8F
-:1040E0003C010800AC2800688F44000038830001C0
-:1040F000306200011440FFED00E04021AF87003046
-:104100008E0C00003C0508008CA5006C3C040800E7
-:104110008C8400680188302300A63821000010211B
-:1041200000E6402B008218210068F8213C010800BD
-:10413000AC27006C3C010800AC3F00688F490100CF
-:1041400025590088AF990044AF890038AF49002055
-:104150008E070000AF8700308F4D017805A0FFFE6D
-:10416000000000008E0600003C0B08008D6B007400
-:104170003C0408008C84007000C728230165F821E6
-:104180000000102103E5402B0082382100E8C821FF
-:10419000240908003C010800AC3F00743C01080001
-:1041A000AC390070AF49017893580108A398003EDC
-:1041B000938F003E31EE000115C000158F8300384B
-:1041C000240E0D00106E0019240F0F00106F001D3B
-:1041D000000000009159000024180050332900FF0E
-:1041E000113800043C1F4000AF5F01380A0002E7AD
-:1041F000000000000E0008EE000000008F8A004062
-:104200003C1F4000AF5F01380A0002E700000000D9
-:10421000938D003E31AC0006000C51000E0000CE24
-:104220000152D8210A0003438F8A00403C1B08003A
-:10423000277B3C480E0000CE000000000A0003432C
-:104240008F8A00403C1B0800277B3C680E0000CE94
-:10425000000000000A0003438F8A004090AA00017A
-:104260008FAB00108CAC00103C0300FF8D68000485
-:10427000AD6C00208CAD001400E060213462FFFFC3
-:10428000AD6D00248CA700183C09FF000109C02473
-:10429000AD6700288CAE001C0182C8240319782564
-:1042A000AD6F0004AD6E002C8CAD0008314A00FFEC
-:1042B000AD6D001C94A900023128FFFFAD6800100D
-:1042C00090A70000A5600002A1600004A1670000A3
-:1042D00090A30002306200FF000219821060000506
-:1042E000240500011065000E0000000003E0000836
-:1042F000A16A00018CD80028354A0080AD780018EA
-:104300008CCF0014AD6F00148CCE0030AD6E000861
-:104310008CC4002CA16A000103E00008AD64000C0D
-:104320008CCD001CAD6D00188CC90014AD69001453
-:104330008CC80024AD6800088CC70020AD67000C55
-:104340008CC200148C8300640043C82B1320000728
-:10435000000000008CC20014144CFFE400000000B8
-:10436000354A008003E00008A16A00018C820064E5
-:104370000A0003990000000090AA000027BDFFF882
-:104380008FA9001CA3AA00008FAE00003C0FFF8085
-:104390008FA8001835E2FFFF8CCD002C01C26024ED
-:1043A000AFAC0000A120000400E06021A7A0000243
-:1043B0008FB800008D2700040188182100A0582123
-:1043C00000C05021006D28263C06FF7F3C0F00FFF7
-:1043D0002CAD000135EEFFFF34D9FFFF3C02FF009A
-:1043E00003193024000D1DC0010EC82400E2C024B2
-:1043F00000C3702503197825AD2E0000AD2F0004F1
-:104400008D450024AFAE0000AD2500088D4D002085
-:104410002405FFFFAD2D000C956800023107FFFF5A
-:10442000AD2700109166001830C200FF000219C2CB
-:10443000506000018D450034AD2500148D670008E3
-:1044400027BD0008AD27001C8C8B00CCAD2C0028AC
-:10445000AD20002CAD2B0024AD20001803E0000897
-:10446000AD20002027BDFFE0AFB20018AFB10014AF
-:10447000AFB00010AFBF001C9098000000C08821B2
-:104480003C0D00FF330F007FA0CF0000908E000195
-:1044900035ACFFFF3C0AFF00A0CE000194A6001E31
-:1044A000A22000048CAB00148E29000400A08021FF
-:1044B000016C2824012A4024008090210105202538
-:1044C000A6260002AE2400042605002026240008AB
-:1044D0000E00007624060002924700002605002800
-:1044E0002624001400071E000003160324060004FF
-:1044F000044000032403FFFF965900023323FFFF0B
-:104500000E000076AE230010262400248FBF001C6E
-:104510008FB200188FB100148FB000102405000373
-:10452000000030210A00008027BD002027BDFFD8F1
-:10453000AFB1001CAFB00018AFBF002090A80000C2
-:10454000240200018FB0003C3103003F008088212D
-:10455000106200148FAA0038240B0005506B00165F
-:10456000AFAA001000A0202100C028210E0003DC0B
-:1045700002003021922400BC30830002106000034E
-:1045800026060030ACC0000024C600048FBF002007
-:104590008FB1001C8FB0001800C0102103E000088C
-:1045A00027BD0028014038210E00035AAFB000108B
-:1045B0000A000420000000000E0003A1AFB00014A8
-:1045C0000A000420000000003C02000A03421821F7
-:1045D0003C04080024843CAC2405001A000030216F
-:1045E0000A000080AF8300543C03800034620070F6
-:1045F0008C48000000A0582100C04821308A00FFEC
-:10460000AF8800308F4401780480FFFE3C0C8000AE
-:10461000358600708CC500003C0308008C63007474
-:104620003C1808008F18007000A82023006468213F
-:104630000000C82101A4782B0319702101CF60214B
-:104640003C010800AC2D00743C010800AC2C00704B
-:104650008F480E14AF480144AF47014CA34A0152A2
-:10466000A74B01589346010830C5000854A000012B
-:1046700035291000934B090024070050316A00FFD0
-:1046800011470007000000008F450E1CAF45014890
-:10469000AF4901543C09100003E00008AF4901781C
-:1046A000934D010831A8000811000010000000001F
-:1046B000934F010831EE001051C000013529000868
-:1046C0003C04080090843D10A34401508F4309A48A
-:1046D000AF4301488F4209A0AF420144AF490154A2
-:1046E0003C09100003E00008AF4901783C190800BC
-:1046F0008F393CCC333800085700FFF135290008CA
-:104700000A0004730000000024070040AF470814AB
-:10471000AF4008108F4209448F4309508F44095419
-:104720008F45095C8F46094CAF820064AF8300500F
-:10473000AF84004CAF85005C03E00008AF860060EA
-:104740009346010930C5007F000518C000052140CF
-:104750000083102103E00008244200883C0A08007E
-:10476000914A3CD13C09080095293CCA3C051100FE
-:10477000000A3C002528000200E8302500C5182565
-:1047800024820008AC83000003E00008AC80000431
-:104790008F4A002C974E09083C0F000E034F38211A
-:1047A00031CDFFFF000D41C0AF48002C97430908F1
-:1047B00094EC001A0080402124020001318BFFFF9D
-:1047C000AC8B00008CE9001C00A0582100C06021C7
-:1047D000AC8900048CE40020AD04000890E30019CB
-:1047E00030630003106200400000000028650002F2
-:1047F00014A00073240600021066004E00000000A2
-:104800002418000310780057000000003C0908003D
-:1048100095293CC093450934934609213C0E080074
-:1048200095CE3CC630A200FF0002C88294E5002A63
-:1048300030C400FF978700580019C60000041C0010
-:10484000312FFFFF0303102501CF6821004DC8253C
-:1048500000A720213C0640000326C02500044C0090
-:10486000AD090004AD180000934F09203C03000679
-:1048700025090014000F760001C36825AD0D00085E
-:104880008F42092C24E5000130A67FFFAD02000C09
-:104890008F59093025020028A7860058AD1900104D
-:1048A0008F440938AD040014AD2B00048F58094023
-:1048B000AD380008934F09373C0D080091AD3CD04E
-:1048C000AD20001031EE00FF01CC1821000367007D
-:1048D000000D4400018858253567FFFFAD27000C07
-:1048E00003E00008AF4A002C3C09080095293CC0B1
-:1048F0003C05080094A53CCA3C0F080095EF3CBC61
-:1049000094E400243126FFFF00A6702101CF682324
-:1049100000041C0025A2FFF20062C825241808002C
-:10492000AD19000CAD180014AD0000100A0004C849
-:104930002508001894E6002494E500283C090800A6
-:1049400095293CC000067C000005740035ED81000F
-:1049500035C40800AD0D000CAD0400100A0004C8F9
-:10496000250800143C09080095293CC03C020800B9
-:1049700094423CCA3C06080094C63CBC94E4002423
-:104980003125FFFF94F800280045C821032678232D
-:1049900000181C0000046C0025EEFFEE006EC82518
-:1049A00035A2810024180800AD02000CAD190010DA
-:1049B000AD180018AD0000140A0004C82508001C3A
-:1049C0001460FF920000000094E300243C090800FA
-:1049D00095293CC00003140034590800AD19000C9F
-:1049E0000A0004C82508001003E00008240201F4AE
-:1049F00027BDFFE8AFB00010AFBF00140E0000608D
-:104A00000080802124050040AF4508148F830050AA
-:104A10008F84004C8F85005C007018210064102387
-:104A200018400004AF830050AF6300548F660054F9
-:104A3000AF86004C1200000C000000008F44007490
-:104A4000936800813409FA002D07000710E0000583
-:104A500000891021936C0081240B01F4018B500418
-:104A600001441021AF62000C8F4E095C01C5682320
-:104A700019A000048FBF00148F4F095CAF8F005C3A
-:104A80008FBF00148FB000100A00006227BD00180D
-:104A90008F8400648F8300508F82004CAF64004489
-:104AA000AF63005003E00008AF6200543C03800095
-:104AB000346200708C43000027BDFFF8308700FF90
-:104AC00030A900FF30C800FFAF8300308F44017869
-:104AD0000480FFFE3C028000345900708F380000D3
-:104AE000A3A700033C0708008CE700748FAC00000C
-:104AF0003C0608008CC60070030378233C0E7FFF41
-:104B000000EFC82135CDFFFF00005021018D282482
-:104B100000CA1821000847C0032F202B00A8102529
-:104B20000064C021AFA200003C010800AC39007451
-:104B30003C010800AC380070934F010AA3A00002AA
-:104B40003C0E80FFA3AF00018FAC0000312B007F33
-:104B500035CDFFFF018D4824000B5600012A40256A
-:104B6000240730002406FF803C05100027BD000804
-:104B7000AF48014CAF470154A7400158A34601522A
-:104B800003E00008AF45017827BDFFE8AFBF001480
-:104B9000AFB000108F6500743C068000309000FFBD
-:104BA00000A620250E000060AF640074936300052A
-:104BB000346200080E000062A3620005020020219A
-:104BC0008FBF00148FB000102405000524060001DB
-:104BD0000A00056E27BD001827BDFFE03C038000DA
-:104BE000AFB00010AFBF0018AFB100143462007056
-:104BF0008C470000309000FF30A800FFAF870030E6
-:104C00008F4401780480FFFE3C188000371100704B
-:104C10008E2F00003C0D08008DAD00743C0A08008A
-:104C20008D4A007001E7702301AE28210000582151
-:104C300000AE302B014B4821012638213C010800F1
-:104C4000AC250074000088213C010800AC270070EE
-:104C50001100000F000000008F6200742619FFFF92
-:104C60003208007F0002FE0233E5007F15000006D7
-:104C7000332200FF2407FF800207202624A3FFFF22
-:104C800000838025320200FF00408021241110089B
-:104C90000E000060000000008F4908183125000454
-:104CA00014A0FFFD3218007F001878C00018714072
-:104CB00001CF682125AC0088AF4C0818274A09802D
-:104CC0008D4B0020AF4B01448D460024AF46014878
-:104CD000A35001500E000062A7400158022010218D
-:104CE0008FBF00188FB100148FB0001003E00008D0
-:104CF00027BD002027BDFFE8308400FFAFBF0010B4
-:104D00000E0005B930A500FF8F8300508FBF001043
-:104D1000344500402404FF903C02100027BD0018D9
-:104D2000AF43014CA3440152AF45015403E00008D6
-:104D3000AF4201789343093E306200081040000DF5
-:104D40003C0901013528080AAC8800008F4700742F
-:104D5000AC8700043C06080090C63CD030C500106B
-:104D600050A00006AC8000088F6A0060AC8A000882
-:104D70002484000C03E00008008010210A000620B3
-:104D80002484000C27BDFFE8AFBF0014AFB00010B3
-:104D90009346093F00A05021000528800085382354
-:104DA00030C200FF240300063C09080095293CC6D8
-:104DB00024E8FFD82405000410430037240600022D
-:104DC0009750093C3C0F020400063400320EFFFFEE
-:104DD00001CF6825AC8D0000934C093E318B00203B
-:104DE0001160000800000000934309363C020103F3
-:104DF000345F0300307900FF033FC025240500081D
-:104E0000AC98000493430934935909210005F882B2
-:104E1000306200FF0002C082332F00FF00186E00D6
-:104E2000000F740001AE6025018920253C09400077
-:104E300000898025ACF0FFD8934309378F4F09488C
-:104E40008F580940306200FF004AC821033F70219B
-:104E500001F86023000E6F0001A650253185FFFF89
-:104E6000001F58800145482501683821AD09002000
-:104E70000E00006024F00028240400040E000062EC
-:104E8000A364003F020010218FBF00148FB00010F8
-:104E900003E0000827BD00180A00063324060012AC
-:104EA00027BDFFD024090010AFB60028AFB50024FD
-:104EB000AFB40020AFB10014AFB000103C01080047
-:104EC000A0293CD0AFBF002CAFB3001CAFB200187C
-:104ED00097480908309500FF3C02000E3107FFFF9C
-:104EE000000731C0AF46002C974409089344010BDA
-:104EF00030B400FF03428021308300300000B02135
-:104F00001060010700008821240C00043C01080007
-:104F1000A02C3CD0934B093E000B5600000A2E03F8
-:104F200004A0014B00000000AF400048934F010B6C
-:104F300031EE002011C00006000000009358093E29
-:104F400000189E00001396030640016B000000004D
-:104F50009344010B30830040106000038F93005096
-:104F60008F8200502453FFFF9347093E30E600082C
-:104F700014C0000224120003000090219619002C96
-:104F800093580934934F0937A7990058330C00FF01
-:104F900031EE00FF024E6821000D5880016C502157
-:104FA000015140213C010800A4283CC6920500188C
-:104FB00030A900FF010918213C010800A4233CC8C6
-:104FC00092110018162000032467000A0000000D4B
-:104FD0002467000A30F0FFFF3C010800A4233CCA0C
-:104FE0003C010800A4203CC03C010800A4203CBCBB
-:104FF0000E00009E020020210E00049A0040202195
-:105000008F4B002C974A09083C0C000E034C3821AA
-:105010003145FFFF000549C0AF49002C97430908FF
-:1050200094F1001A00404021241F00013226FFFFA6
-:10503000AC4600008CE2001CAD0200048CE40020B1
-:10504000AD04000890E3001930630003107F00D620
-:10505000286D000215A0011C240E0002106E010E26
-:10506000240F0003106F00E3000000003C0908005B
-:1050700095293CC0934E0934935109213C0A0800FC
-:10508000954A3CC631CD00FF94F9002A000D1882E4
-:1050900097870058322C00FF00032E00000C2400DC
-:1050A0003126FFFF3142FFFF00A4F82500464821CA
-:1050B00003E97825032770213C18400001F8682592
-:1050C000000E8C00AD0D0000AD110004934C0920C2
-:1050D0003C03000625110014000C2E0000A310252F
-:1050E000AD0200088F49092C24E40001309F7FFFA6
-:1050F000AD09000C8F46093025090028A79F0058EC
-:10510000AD0600108F59093801203021AD19001467
-:10511000AE3300048F580940AE380008934F09376A
-:105120003C0C0800918C3CD0AE20001031EE00FF0A
-:1051300001D26821000D2F00000C1C0000A31025D7
-:105140003447FFFFAE27000CAF4B002C934B093EBA
-:10515000317300081260000D3C0F010135E7080AA9
-:10516000AD0700288F4B0074AD2B00043C130800E2
-:1051700092733CD03268001051000003AD2000084B
-:105180008F780060AD3800082526000C12C000386A
-:1051900000000000935F093F241600062407000466
-:1051A00033F900FF133600D2240800029743093C6C
-:1051B0003C0C02043064FFFF008C2825ACC50000C5
-:1051C0009342093E304900201120000800000000F1
-:1051D000934B09363C130103366E0300316D00FF1B
-:1051E00001AE8825ACD10004240700089349093496
-:1051F00093590921314BFFFF313F00FF001FB0825F
-:10520000333800FF0016560000187C00014F982527
-:1052100000122880026B68253C0E400000C5502318
-:1052200001AE8825AD51FFD8934309378F5F0948F8
-:105230008F490940306C00FF019210210007208245
-:105240000044C82103E978230019C7000008B4000E
-:105250000316402531E7FFFF010730250E000060EF
-:10526000AD46FFF8241200040E000062A372003F56
-:105270000E0000C7020020213C12080092523CD0D0
-:10528000325000031200000F02A020218F82005034
-:1052900024470001AF870050AF6700508F6800546B
-:1052A0000107302318C0000200E020218F64005461
-:1052B000AF6400548F4C0074258401F4AF64000C7B
-:1052C00002A0202102802821A76000680E0005B9F5
-:1052D0003C1410008F8D005034550006AF4D014C2A
-:1052E0008F9100488FBF002C8FB600282623000125
-:1052F000AF8300488FB3001CA35101528FB2001836
-:10530000AF5501548FB10014AF5401788FB500240C
-:105310008FB400208FB0001003E0000827BD0030DC
-:105320009358093E00189E00001396030642005150
-:105330002411000293440923308300021060FEFB15
-:105340008F8600608F82005014C2FEF800000000BB
-:105350000E000060000000009369003F2407001663
-:10536000312800FF1107000C240500083C0C080040
-:10537000918C3CD0358B00013C010800A02B3CD027
-:10538000936A003F314300FF10650065240D000A59
-:10539000106D005E2402000C0E0000620000000090
-:1053A0000A00068E000000003C09080095293CC058
-:1053B0003C04080094843CCA3C1F080097FF3CBC96
-:1053C00094F800243123FFFF0083C821033F782392
-:1053D00000186C0025EEFFF201AE6025240A0800DB
-:1053E000AD0C000CAD0A0014AD0000100A0006E080
-:1053F000250800183C09080095293CC03C1F0800FE
-:1054000097FF3CCA3C19080097393CBC94EF002434
-:105410003124FFFF94EE002803E4C0210319682320
-:10542000000F2C00000E540025ACFFEE014C882527
-:1054300034A2810024060800AD02000CAD1100105A
-:10544000AD060018AD0000140A0006E02508001C97
-:105450008F6E00848F4D094011A0FEB3AF8E0050B7
-:10546000240F00143C010800A02F3CD00A00068D38
-:10547000000000003C010800A0313CD0935F093ED1
-:105480002416000133F900201720FEA8241100087B
-:105490000A00068E2411000494E5002494F10028EB
-:1054A0003C09080095293CC0000514000011340097
-:1054B0003444810034C30800AD04000CAD03001077
-:1054C0000A0006E0250800141460FEE80000000051
-:1054D00094FF00243C09080095293CC0001FCC0023
-:1054E00037380800AD18000C0A0006E02508001047
-:1054F0000A00072E240800128F7F004CAF7F005453
-:105500008F7900540A000697AF790050A362003FDC
-:105510000E000062000000000A00068E000000007D
-:10552000240200140A000807A362003F27BDFFE819
-:10553000308400FFAFBF00100E0005B930A500FF9A
-:105540009378007E9379007F936E00809368007A51
-:10555000332F00FF00186600000F6C0031CB00FFF6
-:10556000018D4825000B52008FBF0010012A3825FD
-:10557000310600FF3444700000E628252402FF8134
-:105580003C03100027BD0018AF45014CAF44015447
-:10559000A342015203E00008AF43017827BDFFD8C2
-:1055A000AFB20018AFB10014AFB00010AFBF002011
-:1055B000AFB3001C93420109308600FF30B000FFFA
-:1055C000000618C232040002307100011480000588
-:1055D000305200FF9367000530E5000810A0000D71
-:1055E00030C80010024020210E0005A5022028210D
-:1055F000240400018FBF00208FB3001C8FB200185D
-:105600008FB100148FB000100080102103E000085B
-:1056100027BD002815000032000000009343010957
-:10562000000028213062007F000220C00002F94003
-:1056300003E4982126790088033B98218E78002482
-:105640008E6F0008130F0046000000008F64008476
-:10565000241800020004FD8233F900031338007C93
-:105660000000000093660083934A0109514600043C
-:105670003205007C10A00060000000003205007CB4
-:1056800014A000530240202116200006320400011D
-:105690008E7F00248F59010417F9FFD600002021C6
-:1056A000320400011080000A024020218F4209408C
-:1056B0008F93006410530006000000000E00066B7C
-:1056C000022028218F430940AF630044024020217B
-:1056D0000E000600022028210A00084024040001D0
-:1056E0003C0908008D290064252600013C010800C2
-:1056F000AC26006416000012000000008F6D0084CC
-:105700003C0E00C001AE602415800005024020213F
-:105710000E00080E022028210A000840240400017F
-:10572000240500040E00056E24060001024020211D
-:105730000E00080E022028210A000840240400015F
-:105740000E00004124040001936B007D020B5025E4
-:105750000E000062A36A007D0A0008838F6D00843A
-:105760008F6600748F4801048E67002400064E0285
-:105770001507FFB63126007F936B00832644000196
-:10578000308A007F11460043316300FF5464FFB04C
-:105790008F6400842645000130B1007F30A200FFF5
-:1057A0001226000424050001004090210A0008563A
-:1057B00024110001240FFF80024F702401CF902696
-:1057C000324200FF004090210A00085624110001D7
-:1057D0000E00066B02202821321800301300FFAAA9
-:1057E00032100082024020210E0005A5022028214F
-:1057F0000A000840240400018F6E00743C0F8000F2
-:105800002405000301CF9025AF72007493710083CB
-:10581000240600010E00056E322400FF0E00004138
-:1058200024040001936D007D020D60250E000062CE
-:10583000A36C007D3C0B08008D6B005425700001AB
-:105840003C010800AC3000540A0008402404000168
-:105850008F6800743C098000240500040109382584
-:10586000AF67007493630083240600010E00056E89
-:10587000306400FF0E000041240400019362007DAB
-:10588000020298250E000062A373007D0A00084002
-:1058900024040001324D008039AC0080546CFF6C50
-:1058A0008F6400840A0008A92645000127BDFFC8AF
-:1058B0003C0A0008AFBF0030AFB5002CAFB40028E1
-:1058C000AFB30024AFB20020AFB1001CAFB00018DE
-:1058D000034AD82124090040AF490814AF400810FA
-:1058E0008F4209448F4309508F4609548F47095C02
-:1058F0008F48094C934401089345010BAF82006423
-:10590000308400FF30A500FFAF830050AF86004C0D
-:10591000AF87005C0E00082AAF8800601440017455
-:105920008FBF0030A7600068934D0900240B005022
-:105930003C15080026B53C8831AC00FF3C1208003D
-:1059400026523C98118B0003000000000000A821A3
-:1059500000009021935101098F9F005024040010F2
-:10596000322E007F000E68C0000E6140018D28219C
-:1059700024B40088AF5408188F4901048F4A09A441
-:105980003C0B000E034BC021012A10233C010800F0
-:10599000AC223CAC8F4309583C010800A0243CD009
-:1059A00097470908007F30233C010800AC263CB033
-:1059B00030E8FFFF0008C9C03C010800AC3F3CD400
-:1059C000AF59002C974209089710002C8EB10000A7
-:1059D000930F001803749821A7900058AF930044C8
-:1059E0000220F80931F000FF304E000215C001A975
-:1059F000304F000111E0015D000000009343093EBB
-:105A00003066000814C00002241400030000A02126
-:105A10008F5809A4241300013C010800AC383CD87D
-:105A2000934F09349351093731EC00FF322E00FFB8
-:105A3000028E6821000D288000AC502101505821B1
-:105A40003C010800A42B3CC83C010800A42A3CC629
-:105A500093490934312200FF0202202124900010D2
-:105A60003C010800A4303CC4240700068F9F00506E
-:105A70003C010800AC273CCC8F88005C8F5909584A
-:105A800000008021011F282304A00151033F20238F
-:105A90000480014F00A4302B10C001510000000011
-:105AA0003C010800AC253CB08E4200000040F809E3
-:105AB0000000000030430002146000F10040882123
-:105AC00030440001548000108E4200043C0908005C
-:105AD0008D293CB43C0AC000012A8025AF500E003D
-:105AE0008F45000030AB00081160FFFD0000000092
-:105AF000974D0E0824100001A78D003C8F4C0E041A
-:105B0000AF8C00348E4200040040F8090000000011
-:105B100002228825322E000215C0016F000000000D
-:105B20003C09080095293CBC3C06080094C63CC8CA
-:105B30003C04080094843CBE3C1808008F183CB418
-:105B4000012658213C0F08008DEF3CD83C1F08006F
-:105B500097FF3CD2016418218F4D09400309C821E9
-:105B6000246E0002033F282101F860213C01080057
-:105B7000A42B3CCAAF8D00643C010800AC2C3CD87F
-:105B80003C010800A4253CC00E00009E31C4FFFF6C
-:105B90008F870048004020213C010800A0273CD10D
-:105BA0008E42000824E80001AF8800480040F80950
-:105BB000000000008F4B002C974909083C0A000E9A
-:105BC000034A38213124FFFF000419C08F8A005096
-:105BD000AF43002C9743090894E6001A0040402187
-:105BE00030DFFFFFAC5F00008CF9001CAC590004F3
-:105BF0008CF80020AC58000890EF001931E3000346
-:105C0000107300FB0000000028620002144001171E
-:105C10002405000210650109240C0003106C00BC6F
-:105C2000000000003C09080095293CC0935F09343E
-:105C3000934C09213C0D080095AD3CC633F900FF9B
-:105C400094E5002A0019C082318F00FF978C00581C
-:105C500000181600000F74003124FFFF004E382595
-:105C600001A4302100E6F82500ACC8213C03400027
-:105C700003E3C02500194C00AD180000AD09000475
-:105C8000934F09203C0E000625090014000F6E00FA
-:105C900001AE2825AD0500088F46092C258200019C
-:105CA00030477FFFAD06000C8F440930A7870058AE
-:105CB00025060028AD0400108F43093800C02021BC
-:105CC000AD030014AD2A00048F5F0940AD3F00080A
-:105CD000935909373C0E080091CE3CD0AD200010FE
-:105CE000333800FF03147821000F6700000E6C00AA
-:105CF000018D282534A2FFFFAD22000CAF4B002CF4
-:105D00009347093E30EA00085140000F8E58000CBE
-:105D10003C0301013469080AAD0900288F4A007468
-:105D2000ACCA00043C0B0800916B3CD031680010F9
-:105D300051000003ACC000088F650060ACC50008CE
-:105D400024C4000C8E58000C0300F8090000000069
-:105D50003C0F080095EF3CCA3C02080094423CBE50
-:105D600001E2702125C400020E0000C73084FFFF4D
-:105D70003C0608008CC63CAC3C0D08008DAD3CB424
-:105D800000CD38233C010800AC273CAC14E00006F1
-:105D9000000000003C1908008F393CCC372C004033
-:105DA0003C010800AC2C3CCC120000858F8B0044D9
-:105DB0008F480E108F900044AE0800208F5F0E18A1
-:105DC000AE1F00243C10080096103CC00E0000607E
-:105DD0000000000024050040AF4508148F830050E8
-:105DE0008F89004C0070182100695023194000046D
-:105DF000AF830050AF6300548F670054AF87004CEF
-:105E00001200000C000000008F440074936D0081AC
-:105E1000340EFA002DA6000710C00005008E1821D0
-:105E200093780081240201F40302780401E418212C
-:105E3000AF63000C8F4C095C8F99005C01992023A3
-:105E400018800003000000008F50095CAF90005CD8
-:105E50000E000062000000008F8B00508E48001082
-:105E60003C010800AC2B3CD40100F8090000000004
-:105E70003C1F08008FFF3CAC17E0FEFC2407000627
-:105E80008F450024974209088F8A00648F94005040
-:105E90003C0F001F978700588F8300548F93004C4E
-:105EA000304DFFFF35EEFF8000AE4824000D31C0BD
-:105EB00032320010AF460024A467002CAF49002402
-:105EC000AF6A0044AF740050AF7300545640007E78
-:105ED0008EB8000432240040548000328EB1000895
-:105EE0008EAC000C0180F809000000008FBF00306C
-:105EF0008FB5002C8FB400288FB300248FB2002000
-:105F00008FB1001C8FB0001803E0000827BD0038D7
-:105F10003C09080095293CC03C04080094843CCA14
-:105F20003C1F080097FF3CBC94F800243123FFFF7E
-:105F300094EF00280083C821033F702300182C0031
-:105F4000000F640025CDFFEE018D302534A28100C5
-:105F500024030800AD02000CAD060010AD030018CC
-:105F6000AD0000140A0009CE2508001C9347010962
-:105F70008F8800380007FE0003E8C825AF5900806D
-:105F80008F5809A08F5309A4AFB80010AF580E1452
-:105F90008FB40010AF540E10AF530E1C0A0009420C
-:105FA000AF530E180220F809000000008EAC000C60
-:105FB0000180F809000000000A000A7F8FBF00304E
-:105FC000A5600020A57300220A000A34AD730024E6
-:105FD0003C010800AC203CB00A00096E8E42000073
-:105FE0003C010800AC243CB00A00096E8E4200005F
-:105FF0003C09080095293CC03C1F080097FF3CCA9B
-:106000003C19080097393CBC94EF00243124FFFF71
-:1060100003E4C02103197023000F640025CDFFF2B3
-:10602000018D2825AC45000C24020800AD020014A7
-:10603000AD0000100A0009CE2508001894E60024DF
-:1060400094E300283C09080095293CC00006240080
-:106050000003FC003499810037F80800AD19000CEA
-:10606000AD1800100A0009CE250800141460FEEDDA
-:106070000000000094EF00243C09080095293CC072
-:10608000000F740035CD0800AD0D000C0A0009CEDC
-:106090002508001093520109000028210E00060077
-:1060A000324400FF8FBF00308FB5002C8FB4002822
-:1060B0008FB300248FB200208FB1001C8FB0001866
-:1060C00003E0000827BD00380300F80900000000C5
-:1060D0000A000A79322400401200FF690000000023
-:1060E0008F540E148F920044AE5400208F530E1C18
-:1060F0000A000A63AE5300248F82001C00804021F6
-:106100003C0401009047008530E300201060000946
-:10611000000000003C0708008CE73CD48F83001887
-:1061200000E32023048000089389000414E30003A3
-:106130000100202103E00008008010213C04010040
-:1061400003E00008008010211120000B00673823B5
-:106150008F8C002024090034918B00BC316A00022E
-:10616000514000012409003000E9682B15A0FFF11F
-:106170000100202100E938232419FFFC00B9C024C4
-:1061800000F9782400F8702B15C0FFEA01E82021FF
-:1061900030C200030002182314C00012306900034B
-:1061A0000000302100A9702101C6682100ED602B9C
-:1061B0001180FFE03C0401002D2F00010006482B58
-:1061C0000105382101E9302414C0FFDA24E4FFFC82
-:1061D0002419FFFC00B9C0240308202103E00008B3
-:1061E000008010218F8B002024060004916A00BCDF
-:1061F000314400041480FFEC00A970210A000B2D2B
-:106200000000302127BDFFE8AFBF00108F4601001E
-:10621000934A01093C1F08008FFF00902407FF806C
-:10622000314F00FF31E8007F0008614003E6C821DC
-:10623000032CC02127090120012770243C010800FC
-:10624000A02F3D10AF4E080C3C0D08008DAD009006
-:106250003C0400803482000301A65821016C1821FF
-:106260002465012030AA007801424025AF48081C6F
-:106270003C1F08008FFF00908F88004003E6C0217C
-:106280003319000703074824033A7821AF4900284F
-:1062900025E909C0952E00023C0D08008DAD008C4B
-:1062A0003C0A08008D4A009031CC3FFF01A618211E
-:1062B000000C5980006B282100A72024AF44002C3B
-:1062C000952200023C1F08008FFF008C910700857B
-:1062D00030593FFF03E678210019C1800146702143
-:1062E00001F8682131CC007F31AB007F019A282171
-:1062F000017A50213C03000C3C04000E00A328212D
-:106300000144102130E6002027470980AF82002C8D
-:10631000AF88001CAF890024AF85002010C00006A4
-:10632000AF8700288D0200508CA4010C004430235C
-:1063300018C0007700000000910C0085240DFFDFDD
-:10634000018D3824A10700858F8B001C8F890024C4
-:106350008F8700288D65004CAF850018912F000DA8
-:1063600031EE002011C000170000000024090001D8
-:10637000A3890004AF80000C8CE400248F85000CFE
-:10638000240A0008AF800008AF8000103C0108001C
-:10639000A42A3CBE3C010800A4203CD20E000B0104
-:1063A000000030218F8500248FBF0010AF820014C1
-:1063B00090A8000D27BD00180008394203E000082E
-:1063C00030E20001913F00022418000133F900FF80
-:1063D0000019218210980039240800021088005BFF
-:1063E0008F86002C8CE5002414A0001B8F9F0020BA
-:1063F00091220000240A00053046003F10CA0047E1
-:10640000240400018F860008A3840004AF860010D6
-:10641000AF86000C8CE400248F85000C240A000851
-:106420003C010800A42A3CBE3C010800A4203CD248
-:106430000E000B01000000008F8500248FBF0010AC
-:10644000AF82001490A8000D27BD00180008394243
-:1064500003E0000830E200018CF800088CF9002409
-:106460008FEE00C4A38000048CE40024AF8E000CE7
-:106470008F85000C8F86000803197823240A0008F2
-:10648000AF8F00103C010800A42A3CBE3C0108006C
-:10649000A4203CD20E000B01000000008F850024D8
-:1064A0008FBF0010AF82001490A8000D27BD001808
-:1064B0000008394203E0000830E2000191230000A7
-:1064C0003062003F104400278F8500208CE40024B8
-:1064D00014800021000000008D2E00183C187FFF62
-:1064E0008F850020370FFFFF01CF1824AF830008EE
-:1064F0008F9F00088CA8008403E8C82B1720000297
-:1065000003E020218CA400840A000BBCAF840008A7
-:106510008CA3010C0A000B9AAF8300188D2C001875
-:106520008F8600083C0D7FFF8F89002035A3FFFF79
-:106530000183582424040001AF8B0010AD2000CC4F
-:10654000A38400040A000BC8AF86000C8CCA001498
-:106550000A000BBCAF8A00088CA300C80A000BFF1E
-:10656000AF8300088F84002C8CAC00648C8D0014E9
-:10657000018D582B11600004000000008CA2006403
-:106580000A000BFFAF8200088C8200140A000BFF88
-:10659000AF8200088F85000C27BDFFE0AFBF001859
-:1065A000AFB1001414A00007AFB000108F86002414
-:1065B0002402000590C400003083003F106200B642
-:1065C0008F8400208F91000800A080218F8C0028EC
-:1065D0003C0508008CA53CB08D8B000431663FFF64
-:1065E00000C5502B5540000100C02821938D0004A8
-:1065F00011A0007300B0F82B8F9800202404003401
-:10660000930F00BC31EE000251C0000124040030A1
-:1066100000A4C82B172000D10000000000A42823EC
-:1066200000B0F82B3C010800A4243CBC17E0006833
-:10663000020020213C0308008C633CAC0083102B3B
-:1066400054400001008018218F8800243C0108007C
-:10665000AC233CB4000048219104000D308300209D
-:10666000506000018F490E188F8300140123382BCE
-:1066700010E00059000000003C0408008C843CB489
-:1066800000895821006B502B114000560090602B60
-:106690000069302300C020213C010800AC263CB436
-:1066A00012000003241FFFFC1090008A3227000311
-:1066B000009FC8243C010800AC393CB43C010800F0
-:1066C000A4203CD28F84000C120400078F8300208A
-:1066D000AF910008020020218C7100CCAF90000C1B
-:1066E00026300001AC7000CC3C0208008C423CB467
-:1066F0008F8A0010240700180082202301422823DB
-:10670000AF84000C10800002AF8500102407001039
-:106710008F86001C3C010800A0273CD024070040C5
-:1067200090CC0085318B00C0116700408F8D001424
-:1067300014A0001500002021934A01098F4209741A
-:10674000314500FF0002260224A300013090007FA3
-:106750003071007F1230007A2407FF80A0C30083CD
-:106760003C0908008D293CCC8F880024240D0002B0
-:10677000352C00083C010800A02D3D113C0108000B
-:10678000AC2C3CCC24040010910E000D31C600202E
-:1067900010C0000500801821240800013C010800F9
-:1067A000AC283CB4348300018FBF00188FB10014B3
-:1067B0008FB000100060102103E0000827BD00200A
-:1067C0003C010800A4203CBC13E0FF9A02002021F9
-:1067D0000A000C5000A020213C0408008C843CB42A
-:1067E0000090602B1180FFAE000000003C0F0800FD
-:1067F00095EF3CBC01E4702101C6682B11A0000795
-:106800002C8200043C1F60008FF954043338003F91
-:106810001700FFE5240300422C8200041040FFA073
-:10682000240300420A000CAE8FBF0018152DFFC0D4
-:10683000000000008CDF00743C0380002405FF8012
-:1068400003E3C825ACD9007490D80085240E000459
-:1068500024040010330F003F01E54025A0C8008547
-:106860008F8800243C010800A02E3D112403000164
-:106870009106000D30C90020152000030000000023
-:106880003C0308008C633CB43C010800AC233CACE6
-:106890000A000CA5000000008F8700108C8800847F
-:1068A00000E8282B14A0000200E088218C910084CD
-:1068B00024090001A38900048F440E180220282116
-:1068C0000E000B0102203021022080210A000C362C
-:1068D000AF82001400071823306600033C01080053
-:1068E000A4263CD2122000058F8C0020918B00BC86
-:1068F000316A00041540001524CD00043C0F080047
-:1069000095EF3CD201E4702100AE302B50C0FF6EF9
-:106910008F84000C2C85000514A0FFA324030042E3
-:106920003098000317000002009818232483FFFC0E
-:106930003C010800AC233CB40A000C7200000000CB
-:1069400000A758240A000C9A016718263C01080089
-:10695000A42D3CD20A000D02000000003C010800FA
-:10696000AC203CB40A000CAD240300428F8300101D
-:1069700014600007000010218F8800242405000502
-:106980009106000030C400FF1085000300000000E5
-:1069900003E0000800000000910A0018314900FFE0
-:1069A000000939C214E0FFFA8F85001C3C0408007E
-:1069B00094843CBC3C0308008C633CD43C19080024
-:1069C0008F393CB43C0F080095EF3CD20064C021E5
-:1069D0008CAD00540319702101CF6021018D582323
-:1069E0001960001D00000000910E001C8F8C002C0F
-:1069F000974B0E1031CD00FF8D850004016D3023C3
-:106A00008D88000030CEFFFF000E510000AAC82183
-:106A10000000382101072021032A182B0083C02100
-:106A2000AD990004AD980000918F000A01CF682154
-:106A3000A18D000A8F88002C974B0E12A50B000821
-:106A4000950A003825490001A50900389107000D75
-:106A500034E60008A106000D03E000080000000075
-:106A600027BDFFE0938700048F8F00248FAD0014B3
-:106A70003C0E7FFF8F89000C35C8FFFFAFBF001CA5
-:106A8000AFB0001801A8182491EA000D000717C044
-:106A90003C1FBFFF006258252D2E00018F9000186B
-:106AA00037F9FFFF3C1808008F183CD43C0F080052
-:106AB00095EF3CCA01796824000E47803C07EFFF40
-:106AC0003C05F0FF01A818253149002034E2FFFF02
-:106AD00034ACFFFF0310582327A500102406000242
-:106AE00025EA00020062182400808021152000029F
-:106AF000000040218F480E1CA7AA00120560003735
-:106B00002407000030FF00FF001FCF008F8B001C08
-:106B100000793825AFA70014916F00853C08080064
-:106B200091083CD13C18DFFF31EE00C0370AFFFF6F
-:106B3000000E182B3C1F080097FF3CC400EA682495
-:106B4000A3A800110003174001A248258FB9001027
-:106B5000AFA900143C0A0800914A3CD3A7BF001615
-:106B60008FA80014032CC0243C0B01003C0F0FFF26
-:106B7000030B18253147000335EEFFFF010C682495
-:106B800000071600006EF8243C09700001A2C82519
-:106B900003E95825AFB90014AFAB00100E00007622
-:106BA000A3A000158F8C0024260200089186000DFA
-:106BB00030C40020108000068FBF001C3C05080078
-:106BC00094A53CC024B0FFFF3C010800A4303CC0A9
-:106BD0008FB0001803E0000827BD00208F98001434
-:106BE0000118502B5540FFC7240700010A000D85EE
-:106BF00030FF00FF9382000427BDFFE0AFBF001805
-:106C00001040000F008050218F880024240B0005C5
-:106C10008F890008910700008F840020010028213F
-:106C200030E3003F8F86002C106B000800003821F5
-:106C3000AFA900100E00040EAFAA0014A380000438
-:106C40008FBF001803E0000827BD00208D19001831
-:106C50003C0F08008DEF3CB48F9800103C027FFF82
-:106C60008D080014345FFFFF033F682401F8702192
-:106C700001AE602301883821AFA900100E00040E78
-:106C8000AFAA00140A000DD3A38000048F8700244C
-:106C90003C05080094A53CD23C0208008C423CCC48
-:106CA00090E6000D0005240030C300201060002C89
-:106CB000004440258F85001C00006021240B00014A
-:106CC00090A3008500004821240A00013C0F8000A9
-:106CD00035EE00708DC70000AF8700308F58017807
-:106CE0000700FFFE3C038000347900708F380000FD
-:106CF0003C0508008CA500743C0D08008DAD0070AB
-:106D00000307782300AF38210000102100EF302B5B
-:106D100001A22021008618213C010800AC27007444
-:106D20003C010800AC230070AF4B01483C1908003F
-:106D30008F393CD4A7490144A74A0146AF59014CB9
-:106D40003C0B0800916B3CD1A34B0152AF4801545E
-:106D50003C081000A74C015803E00008AF48017838
-:106D60008F4B0E1C3C0A08008D4A3CB497490E1606
-:106D7000974D0E1401456021312AFFFF0A000DF6E0
-:106D800031A9FFFF8F8300249064000D3082002022
-:106D900010400029000000000000482100005021A0
-:106DA000000040213C07800034EB00708D6700003C
-:106DB000AF8700308F4C01780580FFFE3C0D8000CE
-:106DC00035AC00708D8B00003C0508008CA500746C
-:106DD0003C0408008C8400700167302300A67821F1
-:106DE0000000102101E6C82B0082C0210319702188
-:106DF0003C010800AC2F00743C010800AC2E007070
-:106E0000AF4901483C0D08008DAD3CD4A748014472
-:106E100024090040A74A01463C081000240AFF91BB
-:106E2000AF4D014CA34A0152AF490154A74001584C
-:106E300003E00008AF4801788F490E1897460E12FC
-:106E400097450E1030CAFFFF0A000E2C30A8FFFF36
-:106E50008F83002427BDFFF89064000D308200204E
-:106E60001040003A00000000240B000100004821FF
-:106E7000240A00013C088000350700708CE3000004
-:106E8000AF8300308F4C01780580FFFE3C0E800000
-:106E90003C04080090843D1035C700708CEC000065
-:106EA0003C0508008CA50074A3A400033C1908004D
-:106EB0008F3900708FAD00000183302300A6382188
-:106EC000000010210322782100E6C02B01F8602188
-:106ED00001AE4025AFA800003C010800AC270074BB
-:106EE0003C010800AC2C00709346010A3C040800E9
-:106EF00090843D11A3A00002A3A600018FA300006F
-:106F00003C0580FF3099007F34A2FFFF00627824A7
-:106F10000019C60001F87025240D3000AF4E014C59
-:106F200027BD0008AF4D0154A7400158AF4B0148A1
-:106F3000A7490144A74A01463C091000240AFF80E2
-:106F4000A34A015203E00008AF4901788F4B0E18A5
-:106F500097460E1297450E1030CAFFFF0A000E60CA
-:106F600030A9FFFF8F85001C2402008090A40085BB
-:106F7000308300C0106200058F8600208F880008D3
-:106F80008F87000CACC800C8ACC700C403E0000881
-:106F9000000000003C0A0800254A38903C0908001F
-:106FA0002529395C3C08080025082D103C070800FD
-:106FB00024E73A703C06080024C637003C05080068
-:106FC00024A534783C040800248430A03C03080045
-:106FD000246337983C0208002442356C3C010800C9
-:106FE000AC2A3C903C010800AC293C8C3C010800D8
-:106FF000AC283C883C010800AC273C943C010800CC
-:10700000AC263CA43C010800AC253C9C3C0108009B
-:10701000AC243C983C010800AC233CA83C0108008F
-:0C702000AC223CA003E0000800000000CF
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
diff --git a/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex b/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex
new file mode 100644
index 000000000000..e9bbdc3b0397
--- /dev/null
+++ b/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex
@@ -0,0 +1,5815 @@
+:10000000080001180800000000004A68000000C84D
+:1000100000000000000000000000000008004A6826
+:100020000000001400004B30080000A00800000091
+:100030000000568800004B4408005800000000846F
+:100040000000A1CC08005688000001580000A25012
+:100050000800321008000000000072D00000A3A8C1
+:10006000000000000000000000000000080072D046
+:100070000000002400011678080004900800040025
+:10008000000017D40001169C0000000000000000D2
+:100090000000000000000000000000000000000060
+:1000A000080000A80800000000003BFC00012E70C2
+:1000B0000000000000000000000000000000000040
+:0800C000000000000000000038
+:0800C8000A00004600000000E0
+:1000D000000000000000000D636F6D362E302E31E1
+:1000E0003500000006000F020000000000000003C1
+:1000F000000000C800000032000000030000000003
+:1001000000000000000000000000000000000000EF
+:1001100000000010000001360000EA600000000549
+:1001200000000000000000000000000000000008C7
+:1001300000000000000000000000000000000000BF
+:1001400000000000000000000000000000000000AF
+:10015000000000000000000000000000000000009F
+:10016000000000020000000000000000000000008D
+:10017000000000000000000000000000000000007F
+:10018000000000000000000000000010000000005F
+:10019000000000000000000000000000000000005F
+:1001A000000000000000000000000000000000004F
+:1001B000000000000000000000000000000000003F
+:1001C000000000000000000000000000000000002F
+:1001D000000000000000000000000000000000001F
+:1001E0000000000010000003000000000000000DEF
+:1001F0000000000D3C02080024424AA03C03080015
+:1002000024634B9CAC4000000043202B1480FFFD76
+:10021000244200043C1D080037BD7FFC03A0F021F0
+:100220003C100800261001183C1C0800279C4AA01E
+:100230000E000168000000000000000D27470100CB
+:1002400090E3000B2402001A94E5000814620028D1
+:10025000000020218CE200003C0308008C63004475
+:1002600094E60014000211C20002104030A4000203
+:10027000005A10212463000130A50004A446008028
+:100280003C010800AC23004410A000190004202BFE
+:100290008F4202B804410008240400013C02080017
+:1002A0008C420060244200013C010800AC22006046
+:1002B00003E00008008010218CE2002094E3001687
+:1002C00000002021AF4202808CE20004A743028498
+:1002D000AF4202883C021000AF4202B83C02080064
+:1002E0008C42005C244200013C010800AC22005C0E
+:1002F00003E00008008010212747010090E3000B75
+:100300002402000394E50008146200280000202164
+:100310008CE200003C0308008C63004494E6001467
+:10032000000211C20002104030A40002005A102145
+:100330002463000130A50004A44600803C010800AD
+:10034000AC23004410A000190004202B8F4202B8F7
+:1003500004410008240400013C0208008C420060B3
+:10036000244200013C010800AC22006003E00008C8
+:10037000008010218CE2002094E300160000202170
+:10038000AF4202808CE20004A7430284AF4202889D
+:100390003C021000AF4202B83C0208008C42005CF4
+:1003A000244200013C010800AC22005C03E000088C
+:1003B000008010218F4301002402010050620003DD
+:1003C000000311C20000000D000311C20002104022
+:1003D000005A1021A440008003E000080000102112
+:1003E0009362000003E00008AF80000003E0000813
+:1003F0000000102103E00008000010212402010089
+:1004000014820008000000003C0208008C4200FC3E
+:10041000244200013C010800AC2200FC0A0000DD7F
+:1004200030A200203C0208008C42008424420001DB
+:100430003C010800AC22008430A2002010400008DB
+:1004400030A300103C0208008C4201082442000145
+:100450003C010800AC22010803E000080000000095
+:1004600010600008000000003C0208008C420104FB
+:10047000244200013C010800AC22010403E0000812
+:10048000000000003C0208008C42010024420001F0
+:100490003C010800AC22010003E00008000000005D
+:1004A00027BDFFE8AFBF0010274401009483000878
+:1004B000306200041040001B306600028F4202B818
+:1004C00004410008240500013C0208008C42006041
+:1004D000244200013C010800AC2200600A0001290E
+:1004E0008FBF00108C82002094830016000028210A
+:1004F000AF4202808C820004A7430284AF4202888C
+:100500003C021000AF4202B83C0208008C42005C82
+:10051000244200013C010800AC22005C0A000129D1
+:100520008FBF001010C00006006028218F4401001A
+:100530000E0000CD000000000A0001282405000183
+:100540008F8200088F4301045043000700002821D8
+:100550008F4401000E0000CD000000008F42010416
+:10056000AF820008000028218FBF001000A01021DA
+:1005700003E0000827BD001827BDFFE8AFBF001447
+:10058000AFB00010974201083043700024022000F1
+:100590001062000B286220011440002F000010217F
+:1005A00024024000106200250000000024026000C8
+:1005B00010620026000010210A0001658FBF0014A0
+:1005C00027500100920200091040001A2403000184
+:1005D0003C0208008C420020104000160000182148
+:1005E0000E00049300000000960300083C0608007B
+:1005F00094C64B5E8E0400188F8200209605000C76
+:1006000000031C0000661825AC440000AC45000443
+:1006100024040001AC400008AC40000CAC400010C9
+:10062000AC400014AC4000180E0004B8AC43001CF1
+:10063000000018210A000164006010210E0003254B
+:10064000000000000A000164000010210E000EE905
+:1006500000000000000010218FBF00148FB00010B8
+:1006600003E0000827BD001827BDFFE0AFB2001867
+:100670003C036010AFBF001CAFB10014AFB000105E
+:100680008C6450002402FF7F3C1A800000822024EA
+:100690003484380C24020037AC6450003C1208004B
+:1006A00026524AD8AF42000824020C80AF420024F0
+:1006B0003C1B80083C06080024C60324024010218D
+:1006C0002404001D2484FFFFAC4600000481FFFDCC
+:1006D000244200043C020800244204B03C0108000B
+:1006E000AC224AE03C020800244202303C010800EF
+:1006F000AC224AE43C020800244201743C03080096
+:100700002463032C3C040800248403D83C0508001F
+:1007100024A538F03C010800AC224B403C02080004
+:10072000244202EC3C010800AC264B243C010800AA
+:10073000AC254B343C010800AC234B3C3C01080089
+:10074000AC244B443C010800AC224B483C0108005F
+:10075000AC234ADC3C010800AC204AE83C0108001C
+:10076000AC204AEC3C010800AC204AF03C010800F7
+:10077000AC204AF43C010800AC204AF83C010800D7
+:10078000AC204AFC3C010800AC204B003C010800B6
+:10079000AC244B043C010800AC204B083C01080091
+:1007A000AC204B0C3C010800AC204B103C01080075
+:1007B000AC204B143C010800AC204B183C01080055
+:1007C000AC264B1C3C010800AC264B203C01080029
+:1007D000AC254B303C010800AC234B380E000623FF
+:1007E000000000003C028000344200708C42000097
+:1007F000AF8200143C0308008C6300208F82000449
+:10080000104300043C0280000E00045BAF83000430
+:100810003C028000344600703C0308008C6300A05A
+:100820003C0208008C4200A4104300048F84001492
+:100830003C010800AC2300A4A743009E8CCA000022
+:100840003C0308008C6300BC3C0208008C4200B8EA
+:100850000144202300641821000040210064202B63
+:1008600000481021004410213C010800AC2300BCCA
+:100870003C010800AC2200B88F5100003222000772
+:100880001040FFDCAF8A00148CC600003C05080055
+:100890008CA500BC3C0408008C8400B800CA30233E
+:1008A00000A628210000102100A6302B0082202164
+:1008B00000862021322700013C010800AC2500BC45
+:1008C0003C010800AC2400B810E0001F32220002F6
+:1008D0008F420100AF4200208F420104AF4200A8C6
+:1008E0009342010B0E0000C6305000FF2E02001E86
+:1008F00054400004001010800E0000C90A000213CA
+:1009000000000000005210218C4200000040F80955
+:1009100000000000104000053C0240008F4301042D
+:100920003C026020AC4300143C024000AF4201385E
+:100930003C0208008C420034244200013C010800C3
+:10094000AC220034322200021040000E3222000499
+:100950008F4201400E0000C6AF4200200E000295FB
+:10096000000000003C024000AF4201783C02080059
+:100970008C420038244200013C010800AC220038BF
+:10098000322200041040FF983C0280008F42018018
+:100990000E0000C6AF4200208F43018024020F00EA
+:1009A00014620005000000008F420188A742009CED
+:1009B0000A0002483C0240009362000024030050F9
+:1009C000304200FF144300083C0240000E00027B4E
+:1009D00000000000544000043C0240000E000D7571
+:1009E000000000003C024000AF4201B83C02080099
+:1009F0008C42003C244200013C010800AC22003C37
+:100A00000A0001C83C0280003C0290003442000110
+:100A100000822025AF4400208F4200200440FFFECA
+:100A20000000000003E00008000000003C0280001D
+:100A3000344200010082202503E00008AF4400207A
+:100A400027BDFFE0AFB10014AFB0001000808821D7
+:100A5000AFBF00180E00025030B000FF9362007D5F
+:100A60000220202102028025A370007D8F70007477
+:100A70003C0280000E000259020280241600000988
+:100A80008FBF00188F4201F80440FFFE24020002CD
+:100A9000AF5101C0A34201C43C021000AF4201F8B3
+:100AA0008FBF00188FB100148FB0001003E0000852
+:100AB00027BD002027BDFFE8AFBF0010974201848B
+:100AC0008F440188304202001040000500002821B8
+:100AD0000E000FAA000000000A00028D240500018C
+:100AE0003C02FF0004800005008218243C02040040
+:100AF000506200019362003E240500018FBF001088
+:100B000000A0102103E0000827BD0018A360002208
+:100B10008F4401400A00025E2405000127BDFFE862
+:100B2000AFBF0014AFB0001093620000304400FF6C
+:100B300038830020388200300003182B0002102B6D
+:100B40000062182410600003240200501482008008
+:100B50008FBF001493620005304200011040007CFA
+:100B60008FBF0014934201482443FFFF2C6200050D
+:100B7000104000788FB00010000310803C03080084
+:100B800024634A68004310218C42000000400008A2
+:100B9000000000000E0002508F4401408F70000CD6
+:100BA0008F4201441602000224020001AF62000CD1
+:100BB0000E0002598F4401408F420144145000043A
+:100BC0008FBF00148FB000100A000F2027BD00183F
+:100BD0008F62000C0A0003040000000097620010FE
+:100BE0008F4301443042FFFF1462001A00000000EE
+:100BF00024020001A76200108F4202380443001053
+:100C00008F4201403C02003F3446F0003C0560004A
+:100C10003C04FFC08CA22BBC0044182400461024C6
+:100C20000002130200031D82106200390000000060
+:100C30008F4202380440FFF7000000008F4201405D
+:100C4000AF4202003C021000AF4202380A00032209
+:100C50008FBF0014976200100A0003040000000018
+:100C60000E0002508F440140976200128F430144EE
+:100C70003050FFFF1603000224020001A762001299
+:100C80000E0002598F4401408F42014416020004B5
+:100C90008FBF00148FB000100A00029127BD00180A
+:100CA000976200120A00030400000000976200141B
+:100CB0008F4301443042FFFF14620006240200010A
+:100CC0008FBF00148FB00010A76200140A00124AF0
+:100CD00027BD0018976200141440001D8FBF001438
+:100CE0000A00031C00000000976200168F430144B5
+:100CF0003042FFFF1462000B240200018FBF00147A
+:100D00008FB00010A76200160A000B1227BD001852
+:100D10009742007824420004A76200100A000322D0
+:100D20008FBF001497620016240300013042FFFFBA
+:100D3000144300078FBF00143C0208008C4200706F
+:100D4000244200013C010800AC2200708FBF001457
+:100D50008FB0001003E0000827BD001827BDFFE892
+:100D6000AFBF0014AFB000108F50010093620000BD
+:100D700093430109304400FF2402001F106200A5C4
+:100D80002862002010400018240200382862000A5F
+:100D90001040000C2402000B286200081040002CB8
+:100DA00000000000046000E52862000214400028F2
+:100DB00024020006106200268FBF00140A00041FE0
+:100DC0008FB000101062005E2862000B144000DC3F
+:100DD0008FBF00142402000E106200738FB0001049
+:100DE0000A00041F00000000106200C028620039E1
+:100DF0001040000A2402008024020036106200CA5B
+:100E000028620037104000B424020035106200C18F
+:100E10008FBF00140A00041F8FB000101062002B57
+:100E20002862008110400006240200C82402003914
+:100E3000106200B48FBF00140A00041F8FB00010AE
+:100E4000106200998FBF00140A00041F8FB00010B9
+:100E50003C0208008C420020104000B98FBF0014F3
+:100E60000E000493000000008F4201008F830020D9
+:100E70009745010C97460108AC6200008F420104BF
+:100E80003C04080094844B5E00052C00AC62000416
+:100E90008F4201180006340000C43025AC620008FF
+:100EA0008F42011C24040001AC62000C9342010A31
+:100EB00000A22825AC650010AC600014AC600018DE
+:100EC000AC66001C0A0003F58FBF00143C0208004A
+:100ED0008C4200201040009A8FBF00140E00049333
+:100EE00000000000974401083C03080094634B5E37
+:100EF0009745010C000422029746010E8F820020C4
+:100F0000000426000083202500052C003C030080FF
+:100F100000A6282500832025AC400000AC4000043A
+:100F2000AC400008AC40000CAC450010AC400014D4
+:100F3000AC400018AC44001C0A0003F42404000177
+:100F40009742010C14400015000000009362000558
+:100F50003042001014400011000000000E0002504A
+:100F6000020020219362000502002021344200107B
+:100F70000E000259A36200059362000024030020C2
+:100F8000304200FF1043006D020020218FBF00148B
+:100F90008FB000100A000FC027BD00180000000D20
+:100FA0000A00041E8FBF00143C0208008C4200207F
+:100FB000104000638FBF00140E0004930000000077
+:100FC0008F4201048F8300209744010C3C050800E8
+:100FD00094A54B5EAC6200009762002C00042400D4
+:100FE0003042FFFF008220253C02400E00A228254F
+:100FF000AC640004AC600008AC60000CAC60001095
+:10100000AC600014AC600018AC65001C0A0003F46E
+:10101000240400010E00025002002021A7600008F5
+:101020000E00025902002021020020210E00025E63
+:10103000240500013C0208008C42002010400040C2
+:101040008FBF00140E000493000000009742010CB3
+:101050008F8300203C05080094A54B5E000214001D
+:10106000AC700000AC620004AC6000088F64004CFF
+:101070003C02401F00A22825AC64000C8F62005087
+:1010800024040001AC6200108F620054AC620014B2
+:10109000AC600018AC65001C8FBF00148FB000104E
+:1010A0000A0004B827BD0018240200205082002541
+:1010B0008FB000100E000F0A020020211040002007
+:1010C0008FBF0014020020218FB0001000002821E3
+:1010D0000A00025E27BD0018020020218FBF001405
+:1010E0008FB000100A00058027BD00189745010C3D
+:1010F000020020218FBF00148FB000100A0005A04D
+:1011000027BD0018020020218FB000100A0005C57D
+:1011100027BD00189345010D020020218FB000105B
+:101120000A00060F27BD0018020020218FBF0014FF
+:101130008FB000100A0005EB27BD00188FBF001408
+:101140008FB0001003E0000827BD00188F4202781E
+:101150000440FFFE2402000234840080AF440240B9
+:10116000A34202443C02100003E00008AF420278B0
+:101170003C04080094844B6A3C0208008C424B7487
+:101180003083FFFF000318C000431021AF42003C32
+:101190003C0208008C424B70AF4200383C020050C9
+:1011A00034420008AF4200300000000000000000A0
+:1011B000000000008F420000304200201040FFFD80
+:1011C000000000008F4204003C010800AC224B608C
+:1011D0008F4204043C010800AC224B643C02002016
+:1011E000AF420030000000003C02080094424B680F
+:1011F0003C03080094634B6C3C05080094A54B6EBF
+:1012000024840001004310213083FFFF3C010800CB
+:10121000A4224B683C010800A4244B6A1465000317
+:10122000000000003C010800A4204B6A03E0000815
+:10123000000000003C05000A27BDFFE80345282107
+:101240003C04080024844B50AFBF00100E00051D65
+:101250002406000A3C02080094424B523C0308005A
+:1012600094634B6E3042000F244200030043180485
+:1012700024027FFF0043102B10400002AF83001CAC
+:101280000000000D0E00042A000000003C020800CF
+:1012900094424B5A8FBF001027BD001803E000088E
+:1012A000A74200A23C02000A034210219443000618
+:1012B0003C02080094424B5A3C010800A4234B56C0
+:1012C000004310238F83001C00021400000214034B
+:1012D0000043102B03E000083842000127BDFFE85F
+:1012E000AFBF00103C02000A0342102194420006E6
+:1012F0003C010800A4224B560E00047700000000B9
+:101300005440FFF93C02000A8FBF001003E00008C0
+:1013100027BD001827BDFFE8AFBF00100E000477FF
+:101320000000000010400003000000000E000485D3
+:10133000000000003C0208008C424B608FBF001090
+:1013400027430400AF4200383C0208008C424B6443
+:1013500027BD0018AF830020AF42003C3C020005CF
+:10136000AF42003003E00008AF8000188F82001801
+:101370003C0300060002114000431025AF4200303C
+:101380000000000000000000000000008F4200008C
+:10139000304200101040FFFD27420400AF820020C1
+:1013A00003E00008AF8000183C0608008CC64B64C0
+:1013B0008F8500188F8300203C02080094424B5A0E
+:1013C00027BDFFE024A50001246300202442000182
+:1013D00024C70020AFB10014AFB00010AFBF001899
+:1013E000AF850018AF8300203C010800A4224B5AAF
+:1013F000309000FF3C010800AC274B6404C100089A
+:101400000000882104E00006000000003C02080003
+:101410008C424B60244200013C010800AC224B602E
+:101420003C02080094424B5A3C03080094634B680A
+:101430000010202B004310262C42000100441025F0
+:10144000144000048F830018240200101462000F5F
+:10145000000000000E0004A9241100013C03080054
+:1014600094634B5A3C02080094424B681462000398
+:10147000000000000E00042A000000001600000317
+:10148000000000000E000493000000003C03080070
+:1014900094634B5E3C02080094424B5C2463000161
+:1014A0003064FFFF3C010800A4234B5E148200035C
+:1014B000000000003C010800A4204B5E1200000662
+:1014C000000000003C02080094424B5AA74200A2D0
+:1014D0000A00050B022010210E0004770000000016
+:1014E00010400004022010210E00048500000000BE
+:1014F000022010218FBF00188FB100148FB0001090
+:1015000003E0000827BD00203084FFFF30A5FFFF67
+:101510000000182110800007000000003082000148
+:101520001040000200042042006518210A00051343
+:101530000005284003E000080060102110C00006EC
+:1015400024C6FFFF8CA2000024A50004AC8200008A
+:101550000A00051D2484000403E0000800000000C8
+:1015600010A0000824A3FFFFAC86000000000000CC
+:10157000000000002402FFFF2463FFFF1462FFFA53
+:101580002484000403E0000800000000240200019D
+:10159000AF62000CA7620010A7620012A7620014DD
+:1015A00003E00008A76200163082007F034210218A
+:1015B0003C08000E004818213C0208008C42002024
+:1015C00027BDFFD82407FF80AFB3001CAFB20018BF
+:1015D000AFB10014AFB00010AFBF00200080802179
+:1015E00030B100FF0087202430D200FF1040002FD0
+:1015F00000009821AF44002C9062000024030050AA
+:10160000304200FF1443000E000000003C020800BE
+:101610008C4200E00202102100471024AF42002C4F
+:101620003C0208008C4200E0020210213042007FA0
+:101630000342102100481021944200D43053FFFF90
+:101640000E000493000000003C02080094424B5E30
+:101650008F8300200011340000C2302500122C00BE
+:101660003C02400000C2302534A50001AC700000EF
+:101670008FBF0020AC6000048FB20018AC7300086C
+:101680008FB10014AC60000C8FB3001CAC6500106F
+:101690008FB00010AC60001424040001AC6000188E
+:1016A00027BD00280A0004B8AC66001C8FBF0020CC
+:1016B0008FB3001C8FB200188FB100148FB00010D0
+:1016C00003E0000827BD00289343010F2402001007
+:1016D0001062000E2865001110A0000724020012FD
+:1016E000240200082405003A1062000600003021A0
+:1016F00003E0000800000000240500351462FFFC30
+:10170000000030210A000538000000008F420074FC
+:1017100024420FA003E00008AF62000C27BDFFE8E1
+:10172000AFBF00100E00025E240500018FBF001045
+:1017300024020001A762001227BD00182402000144
+:1017400003E00008A360002227BDFFE0AFB1001452
+:10175000AFB00010AFBF001830B1FFFF0E00025055
+:10176000008080219362003F24030004304200FF88
+:101770001443000C02002021122000082402000A59
+:101780000E00053100000000936200052403FFFEF7
+:1017900000431024A362000524020012A362003F4C
+:1017A000020020210E000259A360008116200003D0
+:1017B000020020210E0005950000000002002021FB
+:1017C000322600FF8FBF00188FB100148FB00010B9
+:1017D000240500380A00053827BD002027BDFFE09A
+:1017E000AFBF001CAFB20018AFB10014AFB0001013
+:1017F0000E000250008080210E0005310000000024
+:101800009362003F24120018305100FF123200038F
+:101810000200202124020012A362003F936200050F
+:101820002403FFFE004310240E000259A3620005AA
+:10183000020020212405002016320007000030217C
+:101840008FBF001C8FB200188FB100148FB0001032
+:101850000A00025E27BD00208FBF001C8FB2001857
+:101860008FB100148FB00010240500390A0005382C
+:1018700027BD002027BDFFE8AFB00010AFBF0014A8
+:101880009742010C2405003600808021144000108E
+:10189000304600FF0E00025000000000240200123B
+:1018A000A362003F93620005344200100E00053130
+:1018B000A36200050E00025902002021020020212F
+:1018C0000E00025E240500200A000604000000004D
+:1018D0000E000538000000000E000250020020211A
+:1018E000936200232403FF9F020020210043102461
+:1018F0008FBF00148FB00010A36200230A000259AA
+:1019000027BD001827BDFFE0AFBF0018AFB100141E
+:10191000AFB0001030B100FF0E00025000808021F7
+:10192000240200120E000531A362003F0E0002598E
+:101930000200202102002021022030218FBF001848
+:101940008FB100148FB00010240500350A0005384F
+:1019500027BD0020A380002C03E00008A380002DF9
+:101960008F4202780440FFFE8F820034AF42024073
+:1019700024020002A34202443C02100003E00008DB
+:10198000AF4202783C0360008C6254003042000891
+:101990001440FFFD000000008C625408AF82000C70
+:1019A00024020052AC605408AC645430AC6254342D
+:1019B0002402000803E00008AC6254003C0260000E
+:1019C0008C42540030420008104000053C03600087
+:1019D0008C625400304200081440FFFD00000000FB
+:1019E0008F83000C3C02600003E00008AC43540805
+:1019F00090A3000024020005008040213063003FD6
+:101A000000004821146200050000502190A2001C33
+:101A100094A3001E304900FF306AFFFFAD00000CA8
+:101A2000AD000010AD000024950200148D05001CCF
+:101A30008D0400183042FFFF0049102300021100FE
+:101A4000000237C3004038210086202300A2102B5B
+:101A50000082202300A72823AD05001CAD04001838
+:101A6000A5090014A5090020A50A001603E0000836
+:101A7000A50A00228F4201F80440FFFE2402000262
+:101A8000AF4401C0A34201C43C02100003E00008BF
+:101A9000AF4201F83C0208008C4200B427BDFFE8C9
+:101AA000AFBF001424420001AFB000103C01080099
+:101AB000AC2200B48F4300243C02001F30AA00FF78
+:101AC0003442FF8030D800FF006280240080F8217B
+:101AD00030EF00FF1158003B01405821240CFF80DB
+:101AE0003C19000A3163007F000310C00003194055
+:101AF000006218213C0208008C4200DC25680001CD
+:101B0000310D007F03E21021004310213043007F9C
+:101B100003431821004C102400794821AF420024CF
+:101B20008D220024016C1824006C7026AD22000C5C
+:101B30008D220024310800FFAD22001095220014F0
+:101B4000952300208D27001C3042FFFF3063FFFFEC
+:101B50008D2600180043102300021100000227C345
+:101B60000040282100C4302300E2102B00C23023A3
+:101B700000E53823AD27001CAD2600189522002073
+:101B8000A522001495220022154B000AA52200165A
+:101B90008D2300248D220008254600013145008058
+:101BA0001462000430C4007F108F000238AA008045
+:101BB00000C0502151AF000131C800FF1518FFC906
+:101BC000010058218F8400343082007F03421821A5
+:101BD0003C02000A006218212402FF8000822024B7
+:101BE000AF440024A06A0079A06A00838C62005090
+:101BF0008F840034AC6200708C6500743C027FFFFF
+:101C00003442FFFF00A228240E00066BAC6500746E
+:101C1000AF5000248FBF00148FB0001003E0000805
+:101C200027BD001827BDFFC0AFBE0038AFB70034D6
+:101C3000AFB5002CAFB20020AFB1001CAFB00018A0
+:101C4000AFBF003CAFB60030AFB40028AFB3002444
+:101C50008F4500248F4600288F43002C3C02001F34
+:101C60003442FF800062182400C230240080A82182
+:101C7000AFA3001400A2F0240E00062FAFA60010A0
+:101C80003C0208008C4200E02410FF8003608821A1
+:101C900002A2102100501024AF4200243C02080090
+:101CA0008C4200E002A210213042007F0342182142
+:101CB0003C02000A00629021924200D293630084A9
+:101CC000305700FF306300FF24020001106200342F
+:101CD000036020212402000214620036000000008C
+:101CE0000E001216024028219223008392220083C4
+:101CF0003063007F3042007F000210C000031940B3
+:101D0000006218213C0208008C4200DC02A2102173
+:101D10000043382100F01024AF42002892250078BB
+:101D20009224008330E2007F034218213C02000C21
+:101D300014850007006280212402FFFFA24200F107
+:101D40002402FFFFA64200F20A0007272402FFFF39
+:101D500096020020A24200F196020022A64200F262
+:101D60008E020024AE4200F492220083A24200F0D0
+:101D70008E4200C8AE4200FC8E4200C4AE4200F863
+:101D80008E220050AE4201008E4200CCAE420104D1
+:101D9000922200853042003F0A0007823442004010
+:101DA0000E00123902402821922200850A00078283
+:101DB0003042003F936200852403FFDF3042003F42
+:101DC000A36200859362008500431024A36200850E
+:101DD0009363008393620078307400FF304200FF09
+:101DE00010540036240AFF803C0C000C3283007F24
+:101DF000000310C000031940006218213C020800D3
+:101E00008C4200DC268800013109007F02A21021EB
+:101E10000043382130E2007F0342182100EA1024F9
+:101E2000AF420028006C80218E020024028A182410
+:101E3000006A5826AE02000C8E020024310800FF12
+:101E4000AE02001096020014960300208E07001CBC
+:101E50003042FFFF3063FFFF8E060018004310235F
+:101E600000021100000227C30040282100C43023D3
+:101E700000E2102B00C2302300E53823AE07001C1F
+:101E8000AE06001896020020A60200149602002258
+:101E9000A602001692220079304200FF105400077B
+:101EA0000000000051370001316800FF92220078E5
+:101EB000304200FF1448FFCD0100A0219222008390
+:101EC000A22200798E2200500A0007E2AE220070A2
+:101ED000A22200858E22004C2405FF80AE42010C18
+:101EE0009222008534420020A2220085924200D135
+:101EF0003C0308008C6300DC305400FF3C02080007
+:101F00008C4200E400143140001420C002A31821C8
+:101F100000C4202102A210210064382100461021B3
+:101F20000045182400E52824AF450028AF43002CC5
+:101F30003042007F924400D030E3007F03422821EA
+:101F4000034318213C02000C006280213C02000E79
+:101F5000309600FF00A298211296002A000000008F
+:101F60008E02000C02002021026028211040002572
+:101F7000261000280E00064A000000009262000DA4
+:101F800026830001307400FF3042007FA262000D02
+:101F90002404FF801697FFF0267300203C020800FF
+:101FA0008C4200DC0000A02102A210210044102479
+:101FB000AF4200283C0208008C4200E43C030800C9
+:101FC0008C6300DC02A2102100441024AF42002CDC
+:101FD0003C0208008C4200E402A318213063007F19
+:101FE00002A210213042007F034220210343182126
+:101FF0003C02000C006280213C02000E0A0007A493
+:10200000008298218E4200D8AE2200508E4200D825
+:10201000AE22007092250083924600D19223008365
+:10202000924400D12402FF8000A228243063007F64
+:10203000308400FF00A628250064182A10600002E2
+:1020400030A500FF38A50080A2250083A2250079D5
+:102050000E00063D000000009222007E02A020211A
+:10206000A222007A8E2300743C027FFF3442FFFFDD
+:10207000006218240E00066BAE2300748FA20010BD
+:10208000AF5E00248FBF003CAF4200288FBE0038F7
+:102090008FA200148FB700348FB600308FB5002C9C
+:1020A0008FB400288FB300248FB200208FB1001CA2
+:1020B0008FB0001827BD004003E00008AF42002C9D
+:1020C00090A2000024420001A0A200003C030800EE
+:1020D0008C6300F4304200FF1443000F0080302175
+:1020E000A0A000003C0208008C4200E48F84003471
+:1020F000008220213082007F034218213C02000C24
+:10210000006218212402FF8000822024ACC300005A
+:1021100003E00008AF4400288C8200002442002025
+:1021200003E00008AC82000094C200003C080800F4
+:10213000950800CA30E7FFFF008048210102102106
+:10214000A4C2000094C200003042FFFF00E2102B46
+:1021500054400001A4C7000094A200003C03080002
+:102160008C6300CC24420001A4A2000094A20000D1
+:102170003042FFFF544300078F8600280107102BD1
+:10218000A4A000005440000101003821A4C70000B1
+:102190008F8600288CC4001CAF44003C94A2000031
+:1021A0008F43003C3042FFFF000210C00062182144
+:1021B000AF43003C8F42003C008220231880000483
+:1021C000000000008CC200180A00084324420001ED
+:1021D0008CC20018AF4200383C020050344200105C
+:1021E000AF420030000000000000000000000000CE
+:1021F0008F420000304200201040FFFD0000000030
+:102200008F420404AD2200048F420400AD2200007E
+:102210003C020020AF42003003E000080000000054
+:1022200027BDFFE0AFB20018AFB10014AFB000108F
+:10223000AFBF001C94C2000000C080213C12080007
+:10224000965200C624420001A60200009603000038
+:1022500094E2000000E03021144300058FB100300B
+:102260000E000818024038210A000875000000001E
+:102270008C8300048C820004244200400461000727
+:10228000AC8200048C8200040440000400000000C2
+:102290008C82000024420001AC8200009602000003
+:1022A0003042FFFF50520001A600000096220000BD
+:1022B00024420001A62200008F82002896230000FD
+:1022C00094420016144300048FBF001C2402000136
+:1022D000A62200008FBF001C8FB200188FB100141F
+:1022E0008FB0001003E0000827BD00208F89002870
+:1022F00027BDFFE0AFBF00188D220028274804004B
+:1023000030E700FFAF4200388D22002CAF8800304C
+:10231000AF42003C3C020005AF420030000000002C
+:1023200000000000000000000000000000000000AD
+:10233000000000008C82000C8C82000CAD020000BA
+:102340008C820010AD0200048C820018AD020008DF
+:102350008C82001CAD02000C8CA20014AD02001097
+:102360008C820020AD02001490820005304200FFF4
+:1023700000021200AD0200188CA20018AD02001C71
+:102380008CA2000CAD0200208CA20010AD02002433
+:102390008CA2001CAD0200288CA20020AD02002CF3
+:1023A000AD060030AD000034978300263402FFFFF5
+:1023B00014620002006020213404FFFF10E00011CD
+:1023C000AD04003895230036952400362402000120
+:1023D0003063FFFF000318C20069182190650040B8
+:1023E000308400070082100400451025A0620040E0
+:1023F0008F820028944200563042FFFF0A0008DC1A
+:10240000AD02003C952300369524003624020001DD
+:102410003063FFFF000318C2006918219065004077
+:1024200030840007008210040002102700451024A9
+:10243000A0620040AD00003C000000000000000071
+:10244000000000003C02000634420040AF42003071
+:102450000000000000000000000000008F420000AB
+:10246000304200101040FFFD8F860028AF880030FA
+:1024700024C2005624C7003C24C4002824C50032CE
+:1024800024C600360E000856AFA200108FBF0018F9
+:1024900003E0000827BD00208F8300243C060800CD
+:1024A0008CC600E88F82003430633FFF0003198040
+:1024B00000461021004310212403FF803046007F96
+:1024C00000431024AF420028034618213C02000CB0
+:1024D0000062302190C2000D30A500FF00003821BD
+:1024E00034420010A0C2000D8F8900288F8A00247A
+:1024F00095230036000A13823048000324020001AD
+:10250000A4C3000E1102000B2902000210400005B6
+:10251000240200021100000C240300010A0009201B
+:102520000000182111020006000000000A00092026
+:10253000000018218CC2002C0A000920244300014D
+:102540008CC20014244300018CC200180043102BDD
+:1025500050400009240700012402002714A20003B0
+:10256000000000000A00092C240700019522003E0B
+:1025700024420001A522003E000A138230430003DA
+:102580002C62000210400009008028211460000421
+:102590000000000094C200360A00093C3046FFFFEC
+:1025A0008CC600380A00093C008028210000302138
+:1025B0003C04080024844B780A00088900000000CD
+:1025C000274901008D22000C9523000601202021BF
+:1025D000000216023046003F3063FFFF240200274E
+:1025E00000C0282128C7002810C2000EAF83002495
+:1025F00010E00008240200312402002110C200096A
+:102600002402002510C200079382002D0A00095BF6
+:102610000000000010C200059382002D0A00095B33
+:10262000000000000A0008F4000000000A0006266E
+:102630000000000095230006912400058D25000C64
+:102640008D2600108D2700188D28001C8D29002054
+:10265000244200013C010800A4234B7E3C010800F9
+:10266000A0244B7D3C010800AC254B843C010800B4
+:10267000AC264B883C010800AC274B903C0108007D
+:10268000AC284B943C010800AC294B9803E00008AF
+:10269000A382002D8F87002827BDFFC0AFB3003471
+:1026A000AFB20030AFB1002CAFB00028AFBF0038E0
+:1026B0003C0208008C4200D094E3003030B0FFFFB1
+:1026C000005010073045FFFF3063FFFF00C0982126
+:1026D000A7A200103C110800963100C614A3000602
+:1026E0003092FFFF8CE2002424420030AF42003CD5
+:1026F0000A0009948CE2002094E200323042FFFF8D
+:1027000054A2000827A400188CE2002C24420030B8
+:10271000AF42003C8CE20028AF4200380A0009A218
+:102720008F84002827A5001027A60020022038212A
+:102730000E000818A7A000208FA200182442003025
+:10274000AF4200388FA2001CAF42003C8F840028AB
+:102750003C020005AF42003094820034274304005D
+:102760003042FFFF0202102B14400007AF830030FD
+:1027700094820054948300340202102100431023F9
+:102780000A0009B63043FFFF94830054948200345A
+:102790000223182100501023006218233063FFFF2A
+:1027A000948200163042FFFF144300030000000033
+:1027B0000A0009C424030001948200163042FFFF7E
+:1027C0000043102B104000058F82003094820016C9
+:1027D000006210233043FFFF8F820030AC530000B3
+:1027E000AC400004AC520008AC43000C3C020006B4
+:1027F00034420010AF420030000000000000000032
+:10280000000000008F420000304200101040FFFD29
+:10281000001018C2006418219065004032040007BF
+:10282000240200018FBF00388FB300348FB2003014
+:102830008FB1002C8FB000280082100400451025B5
+:1028400027BD004003E00008A062004027BDFFA8AC
+:10285000AFB60050AFB5004CAFB40048AFB30044C2
+:10286000AFB1003CAFBF0054AFB20040AFB00038D2
+:102870008C9000003C0208008C4200E88F860034F7
+:10288000960300022413FF8000C2302130633FFF13
+:102890000003198000C3382100F3102490B2000017
+:1028A000AF42002C9203000230E2007F034230214D
+:1028B0003C02000E00C28821306300C024020040A8
+:1028C0000080A82100A0B021146200260000A021F1
+:1028D0008E3400388E2200181440000224020001B9
+:1028E000AE2200189202000D304200201440001564
+:1028F0008F8200343C0308008C6300DC001238C077
+:10290000001231400043102100C730210046382119
+:1029100030E300073C02008030E6007800C230253A
+:102920000343182100F31024AF4208002463090078
+:10293000AF4608108E2200188C6300080043102157
+:10294000AE2200188E22002C8E2300182442000193
+:102950000062182B1060003D000000000A000A7899
+:1029600000000000920300022402FFC00043102474
+:10297000304200FF1440000524020001AE2200187E
+:10298000962200360A000A613054FFFF8E2200149E
+:1029900024420001AE22001892020000000216003C
+:1029A0000002160304410029000000009602000204
+:1029B00027A4001000802821A7A20016960200027A
+:1029C00024070001000030213042FFFFAF820024C5
+:1029D0000E000889AFA0001C960300023C0408000A
+:1029E0008C8400E88F82003430633FFF000319803D
+:1029F00000441021004310213043007F3C05000CAF
+:102A00000053102403431821AF4200280065182109
+:102A10009062000D001221403042007FA062000D44
+:102A20003C0308008C6300E48F82003400431021D3
+:102A30000044382130E2007F03421021004510217C
+:102A400000F31824AF430028AEA200009222000D2C
+:102A5000304200101040001302A020218F83002874
+:102A60008EA40000028030219462003E2442FFFFC9
+:102A7000A462003E948400029625000E3084FFFF7D
+:102A80000E00097330A5FFFF8F82002894430034A5
+:102A90009622000E1443000302A02021240200010C
+:102AA000A382002C02C028210E0007FE00000000B7
+:102AB0008FBF00548FB600508FB5004C8FB40048C4
+:102AC0008FB300448FB200408FB1003C8FB000380C
+:102AD00003E0000827BD00588F82002827BDFFD0E3
+:102AE000AFB40028AFB20020AFBF002CAFB30024BA
+:102AF000AFB1001CAFB00018904400D0904300D19B
+:102B00000000A021309200FFA3A30010306300FF5B
+:102B10008C5100D88C5300DC1072002B2402000171
+:102B20003C0308008C6300E493A400108F820034FF
+:102B30002406FF800004214000431021004410219E
+:102B40003043007F00461024AF4200280343182181
+:102B50003C02000C006218218C62000427A40014BF
+:102B600027A50010022280210270102304400015C6
+:102B7000AFA300149062000D00C21024304200FF89
+:102B800014400007020088219062000D344200408A
+:102B90000E0007FEA062000D0A000ABD93A20010FD
+:102BA0000E0009E1241400018F830028AC7000D8C6
+:102BB00093A20010A06200D193A200101452FFD87B
+:102BC0000000000024020001168200048FBF002CC8
+:102BD0000E000626000000008FBF002C8FB40028D6
+:102BE0008FB300248FB200208FB1001C8FB000186B
+:102BF00003E0000827BD003027BDFFD8AFB3001C9D
+:102C0000AFB20018AFB10014AFB00010AFBF0020DA
+:102C10000080982100E0802130B1FFFF0E00049376
+:102C200030D200FF000000000000000000000000A3
+:102C30008F820020AC510000AC520004AC5300085D
+:102C4000AC40000CAC400010AC400014AC4000188C
+:102C50003C03080094634B5E02038025AC50001CCB
+:102C6000000000000000000000000000240400013B
+:102C70008FBF00208FB3001C8FB200188FB10014DB
+:102C80008FB000100A0004B827BD002827BDFFE858
+:102C9000AFB00010AFBF001430A5FFFF30C600FF7B
+:102CA0000080802124020C80AF420024000000003C
+:102CB0000000000000000000000000000000000014
+:102CC0000E000ACC000000003C040800248400E050
+:102CD0008C8200002403FF808FBF001402021021A9
+:102CE00000431024AF4200248C8200003C03000A01
+:102CF000020280213210007F035010218FB000109B
+:102D00000043102127BD001803E00008AF8200280F
+:102D100027BDFFE8AFBF00108F4401403C0308000F
+:102D20008C6300E02402FF80AF840034008318210C
+:102D300000621024AF4200243C02000803424021FC
+:102D4000950500023063007F3C02000A034318210E
+:102D50000062182130A5FFFF3402FFFF0000302180
+:102D60003C07602010A20006AF8300282402FFFF6A
+:102D7000A5020002946500D40E000AF130A5FFFF01
+:102D80008FBF001024020C8027BD001803E000084C
+:102D9000AF4200243C020008034240219502000299
+:102DA0003C0A0800954A00C63046FFFF14C00007E1
+:102DB0003402FFFF8F8200288F8400343C0760209C
+:102DC000944500D40A000B5A30A5FFFF10C200241E
+:102DD0008F87002894E2005494E400163045FFFFEA
+:102DE00000A6102300A6182B3089FFFF10600004F6
+:102DF0003044FFFF00C51023012210233044FFFFA1
+:102E0000008A102B1040000C012A1023240200011C
+:102E1000A50200162402FFFFA502000294E500D4DB
+:102E20008F8400340000302130A5FFFF3C07602074
+:102E30000A000AF1000000000044102A10400008B7
+:102E4000000000009502001630420001104000040E
+:102E5000000000009742007E24420014A5020016E4
+:102E600003E00008000000008F84002827BDFFE079
+:102E7000AFBF0018948200349483003E1060001AA3
+:102E80003048FFFF9383002C2402000114620027C6
+:102E90008FBF00188F820028000818C23108000771
+:102EA000006218212447003A244900542444002099
+:102EB000244500302446003490620040304200FF38
+:102EC0000102100730420001104000168FBF0018A9
+:102ED0000E000856AFA900108F82002894420034DB
+:102EE0000A000B733048FFFF94830036948200344D
+:102EF0001043000E8FBF001894820036A482003465
+:102F000094820056A48200548C82002CAC8200244F
+:102F100094820032A48200309482003CA482003A61
+:102F20008FBF00180A000B3327BD002003E0000804
+:102F300027BD002027BDFFE8AFBF00108F4A01006A
+:102F40003C0508008CA500E03C02080090424B8440
+:102F50003C0C0800958C4B7E01452821304B003FEE
+:102F600030A2007F03424021396900323C02000A4E
+:102F70003963003F2C630001010240212D2900012B
+:102F80002402FF8000A2282401234825AF8A0034B0
+:102F900000801821AF450024000030210080282146
+:102FA00024070001AF8800283C04080024844B78E3
+:102FB000AF8C002415200007A380002D24020020E0
+:102FC0005562000F006020213402FFFF5582000C83
+:102FD000006020212402002015620005000000008E
+:102FE0008C6300142402FFFF106200070000000041
+:102FF0000E000889000000000A000BD0000000004D
+:103000000E0008F4016028210E000B68000000008B
+:103010008FBF001024020C8027BD001803E00008B9
+:10302000AF4200243C0208008C4200E027BDFFA014
+:10303000AFB1003C008210212411FF80AFBE0058C8
+:10304000AFB70054AFB20040AFB00038AFBF005CC4
+:10305000AFB60050AFB5004CAFB40048AFB30044BA
+:10306000005110248F4800248F4900288F470028E2
+:10307000AF4200243C0208008C4200E00080902116
+:1030800024060006008210213042007F03421821EE
+:103090003C02000A006280213C02001F3442FF8093
+:1030A00000E2382427A40010260500F00122F024B5
+:1030B0000102B8240E00051DAFA700308FA2001832
+:1030C000AE0200C48FA2001CAE0200C88FA2002472
+:1030D000AE0200CC93A40010920300D12402FF8022
+:1030E0000082102400431025304900FF3083007F08
+:1030F0003122007F0062102A10400004000310C03B
+:1031000001311026304900FF000310C000031940B0
+:10311000006218213C0208008C4200DC920400D2BC
+:10312000024210210043102100511024AF42002818
+:1031300093A300103063007F000310C00003194008
+:10314000006218213C0208008C4200DC024210217F
+:10315000004310213042007F034218213C02000C42
+:10316000006240218FA300142402FFFF1062003090
+:10317000309500FF93A2001195030014304400FF26
+:103180003063FFFF0064182B1060000D000000008A
+:10319000950400148D07001C8D0600183084FFFF75
+:1031A00000442023000421000000102100E4382105
+:1031B00000E4202B00C230210A000C4A00C4302158
+:1031C000950400148D07001C8D0600183084FFFF45
+:1031D000008220230004210000001021008018211B
+:1031E00000C2302300E4202B00C4302300E3382346
+:1031F000AD07001CAD06001893A20011A502001433
+:1032000097A20012A50200168FA20014AD020010B2
+:103210008FA20014AD02000C93A20011A5020020A1
+:1032200097A20012A50200228FA20014AD02002472
+:103230002406FF80024610243256007FAF4200244D
+:10324000035618213C02000A006280218E02004CC5
+:103250008FA200203124007F000428C0AE0200505D
+:103260008FA200200004214000852821AE020070BA
+:1032700093A2001001208821A202008393A20010D3
+:10328000A2020079920200853042003FA20200852E
+:103290003C0208008C4200DC024210210045102153
+:1032A00000461024AF42002C3C0208008C4200E48F
+:1032B0003C0308008C6300DC024210210044102112
+:1032C00000461024AF4200283C0208008C4200E473
+:1032D00002431821006518210242102100441021E8
+:1032E0003042007F3063007F93A50010034220210D
+:1032F000034318213C02000E006240213C02000CF6
+:1033000010B1008C008248213233007F1660001912
+:103310002404FF803C0208008C4200DC02421021A1
+:1033200000441024AF42002C3C0208008C4200E410
+:103330003C0308008C6300DC02421021004410248E
+:10334000AF4200283C0208008C4200E402431821EE
+:103350003063007F024210213042007F034220216F
+:10336000034318213C02000E006240213C02000C85
+:10337000008248219124000D2414FF8000001021B8
+:1033800000942025A124000D950400029505001449
+:103390008D07001C3084FFFF30A5FFFF8D0600184D
+:1033A000008520230004210000E4382100C23021E0
+:1033B00000E4202B00C43021AD07001CAD0600182E
+:1033C00095020002A5020014A50000168D02000857
+:1033D000AD0200108D020008AD02000C9502000243
+:1033E000A5020020A50000228D020008AD020024E5
+:1033F0009122000D30420040104000422622000180
+:103400003C0208008C4200E0A3B300283C10000AF4
+:103410000242102100541024AF4200243C02080054
+:103420008C4200E0A380002C27A4002C0242102133
+:103430003042007F03421821007018218C6200D8AE
+:103440008D26000427A50028AFA9002C00461021D6
+:10345000AC6200D80E0009E1AF83002893A30028D6
+:103460008F8200280E000626A04300D10E000B68B4
+:103470000000000002541024AF4200243C02080067
+:103480008C4200DC00132940001320C000A420213E
+:10349000024210210044102100541024AF42002C9D
+:1034A0003C0208008C4200E43C0308008C6300DC12
+:1034B00003563021024210210045102100541024EF
+:1034C000AF4200283C0208008C4200E4024318216D
+:1034D0000064182102421021004510213042007F73
+:1034E0003063007F03422021034318213C02000E79
+:1034F000006240213C02000C00D080210082482163
+:10350000262200013043007F14750005304400FF7F
+:103510002403FF800223102400431026304400FFC0
+:1035200093A2001000808821250800281444FF760B
+:103530002529002093A400108FA300142402FFFF6C
+:103540001062000A308900FF2482000124830001F8
+:103550003042007F14550005306900FF2403FF80CE
+:103560000083102400431026304900FF92020078A7
+:10357000305300FF11330032012088213C02080043
+:103580008C4200DC3225007F000520C00005294068
+:1035900000A42021024210212406FF8000441021B3
+:1035A00000461024AF42002C3C0308008C6300DC72
+:1035B0003C0208008C4200E4024318210242102120
+:1035C0000045102100641821004610243063007F5C
+:1035D000AF420028034318213C02000E0062402144
+:1035E0003C0208008C4200E48D06000C0100202102
+:1035F00002421021004510213042007F0342182171
+:103600003C02000C0062482110C0000D012028215E
+:103610000E00064A000000002402FF800222182447
+:1036200026240001006228263082007F1455000203
+:10363000308300FF30A300FF1473FFD000608821A7
+:103640008E0300743C027FFF3442FFFF00621824A7
+:10365000AE0300740E00066B02402021AF57002419
+:103660008FA20030AF5E00288FBF005C8FBE005875
+:103670008FB700548FB600508FB5004C8FB4004800
+:103680008FB300448FB200408FB1003C8FB0003840
+:1036900027BD006003E00008AF42002C27BDFFD823
+:1036A000AFB1001CAFBF0020AFB000182751018898
+:1036B000922200032408FF803C03000A3047007F69
+:1036C000A3A700108F4601803C0208008C4200E056
+:1036D000AF86003400C2282100A81024AF42002485
+:1036E0009224000030A2007F0342102100431021E9
+:1036F000AF8200283084007F24020002148200255B
+:10370000000719403C0208008C4200E400C210216E
+:103710000043282130A2007F0342182100A8102472
+:10372000AF4200283C02000C006218219062000D9C
+:10373000AFA3001400481025A062000D8FA3001451
+:103740009062000D304200405040006A8FBF002060
+:103750008F860028A380002C27A400148CC200D8D8
+:103760008C63000427A50010004310210E0009E11E
+:10377000ACC200D893A300108F8200280E0006264A
+:10378000A04300D10E000B68000000000A000E0BE1
+:103790008FBF00200E00062F00C020210E00063D26
+:1037A000000000003C020008034280219223000137
+:1037B0009202007B1443004F8FBF00209222000032
+:1037C0003044007F24020004108200172882000584
+:1037D00010400006240200052402000310820007A6
+:1037E0008FB1001C0A000E0C0000000010820012B5
+:1037F0008FBF00200A000E0C8FB1001C92050083C1
+:10380000920600788E0700748F84003430A500FF84
+:1038100000073E0230C600FF0E00067330E7007F4F
+:103820000A000E0B8FBF00200E000BD78F840034D0
+:103830000A000E0B8FBF002024020C80AF42002430
+:103840009202003E30420040104000200000000084
+:103850009202003E00021600000216030441000618
+:10386000000000008F8400340E0005A024050093A2
+:103870000A000E0B8FBF00209202003F24030018A5
+:10388000304200FF1443000C8F84003424050039BB
+:103890000E000538000030210E0002508F840034E5
+:1038A00024020012A202003F0E0002598F8400344D
+:1038B0000A000E0B8FBF0020240500360E000538CD
+:1038C000000030210A000E0B8FBF00200E000250B6
+:1038D0008F8400349202000534420020A2020005C9
+:1038E0000E0002598F8400340E000FC08F84003404
+:1038F0008FBF00208FB1001C8FB0001824020C80F5
+:1039000027BD002803E00008AF42002427BDFFE8E0
+:10391000AFB00010AFBF001427430100946200084D
+:103920000002140000021403044100020000802180
+:103930002410000194620008304200801040001AF8
+:10394000020010219462000830422000104000164E
+:10395000020010218C6300183C021C2D344219ED2A
+:10396000240600061062000F3C0760213C0208009C
+:103970008C4200D4104000078F8200288F830028DB
+:10398000906200623042000F34420040A062006248
+:103990008F8200288F840034944500D40E000AF1F1
+:1039A00030A5FFFF020010218FBF00148FB0001060
+:1039B00003E0000827BD001827BDFFE0AFB10014E9
+:1039C000AFB00010A380002CAFBF00188F450100DE
+:1039D0003C0308008C6300E02402FF80AF850034C4
+:1039E00000A318213064007F0344202100621824C2
+:1039F0003C02000A00822021AF430024275001002E
+:103A00008E0200148C8300DCAF8400280043102356
+:103A100018400004000088218E0200140E000A8461
+:103A2000AC8200DC9202000B24030002304200FF53
+:103A30001443002F0000000096020008304300FFEE
+:103A40002402008214620005240200840E00093E54
+:103A5000000000000A000E97000000001462000938
+:103A6000240200818F8200288F8400343C0760216B
+:103A7000944500D49206000530A5FFFF0A000E868B
+:103A800030C600FF14620027000000009202000A06
+:103A9000304300FF306200201040000430620040DC
+:103AA0008F8400340A000E82240600401040000477
+:103AB000000316008F8400340A000E8224060041A1
+:103AC00000021603044100178F84003424060042CC
+:103AD0008F8200283C076019944500D430A5FFFF71
+:103AE0000E000AF1000000000A000E97000000001E
+:103AF0009202000B24030016304200FF1043000620
+:103B0000000000009202000B24030017304200FF67
+:103B100014430004000000000E000E11000000001D
+:103B2000004088210E000B68000000009202000A8D
+:103B3000304200081040000624020C808F850028C7
+:103B40003C0400080E0011EE0344202124020C80E6
+:103B5000AF4200248FBF0018022010218FB0001048
+:103B60008FB1001403E0000827BD002027BDFFE847
+:103B7000AFBF0014AFB000108F5000243C0308000A
+:103B80008C6300E08F4501002402FF8000A3182110
+:103B90003064007F03442021006218243C02000AA4
+:103BA00000822021AF850034AF4300249082006260
+:103BB000AF8400283042000F34420050A0820062DF
+:103BC0003C02001F3442FF800E00062602028024C1
+:103BD000AF5000248FBF00148FB0001003E0000826
+:103BE00027BD00183C0208008C4200201040001D38
+:103BF0002745010090A300093C0200080342202150
+:103C000024020018546200033C0200080A000ED887
+:103C10002402000803422021240200161462000539
+:103C20002402001724020012A082003F0A000EE2C4
+:103C300094A700085462000694A700089362000548
+:103C40002403FFFE00431024A362000594A700088C
+:103C500090A6001B8CA4000094A500060A000ACCC4
+:103C600000073C0003E000080000000027440100BA
+:103C700094820008304500FF38A3008238A20084F7
+:103C80002C6300012C420001006218251060000620
+:103C9000240200839382002D1040000D00000000DC
+:103CA0000A000B9B0000000014A2000524A2FF8064
+:103CB0008F4301043C02602003E00008AC43001481
+:103CC000304200FF2C420002104000032402002278
+:103CD0000A000E3C0000000014A2000300000000D7
+:103CE0000A000EA9000000000A000EC70000000034
+:103CF0009363007E9362007A144300090000202140
+:103D00009362000024030050304200FF144300047B
+:103D1000240400019362007E24420001A362007E1D
+:103D200003E00008008010218F4201F80440FFFEEC
+:103D300024020002AF4401C0A34201C43C021000AF
+:103D400003E00008AF4201F827BDFFE8AFBF001055
+:103D50009362003F2403000A304200FF14430046F0
+:103D6000000000008F6300548F62004C1062007DE1
+:103D7000036030219362000024030050304200FFB2
+:103D80001443002F000000008F4401403C02080053
+:103D90008C4200E02403FF800082102100431024A5
+:103DA000AF4200243C0208008C4200E08F650054C2
+:103DB0003C03000A008220213084007F034410214C
+:103DC00000431021AC4501089762003C8F63004C12
+:103DD0003042FFFF0002104000621821AF63005C18
+:103DE0008F6300548F64004C9762003C006418237A
+:103DF0003042FFFF00031843000210400043102A26
+:103E000010400006000000008F6200548F63004CD9
+:103E1000004310230A000F58000210439762003C31
+:103E20003042FFFF00021040ACC2006424020001D7
+:103E3000A0C0007CA0C2008424020C80AF420024F9
+:103E40000E000F0A8F440140104000478FBF001042
+:103E50008F4301408F4201F80440FFFE240200021C
+:103E6000AF4301C0A34201C43C021000AF4201F8BD
+:103E70000A000FA88FBF00109362003F24030010B8
+:103E8000304200FF14430004000000008F44014052
+:103E90000A000F94000028219362003F24030016BB
+:103EA000304200FF1443000424020014A362003FC8
+:103EB0000A000FA2000000008F62004C8F630050C8
+:103EC00000431023044100288FBF0010936200813B
+:103ED00024420001A3620081936200812C4200040D
+:103EE00014400010000000009362003F240300040F
+:103EF000304200FF14430006000000008F440140E0
+:103F00008FBF0010240500930A0005A027BD0018EC
+:103F10008F440140240500938FBF00100A00060F54
+:103F200027BD00188F4401400E0002500000000021
+:103F30008F6200542442FFFFAF6200548F62005032
+:103F40002442FFFFAF6200500E0002598F4401402F
+:103F50008F4401408FBF0010240500040A00025E58
+:103F600027BD00188FBF001003E0000827BD001810
+:103F70008F4201889363007E00021402304400FFE8
+:103F8000306300FF1464000D0000000093620080A5
+:103F9000304200FF1044000900000000A3640080CC
+:103FA0009362000024030050304200FF14430004D9
+:103FB000000000000A0006D78F440180A36400803F
+:103FC00003E000080000000027BDFFE8AFB00010CC
+:103FD000AFBF00149362000524030030304200306C
+:103FE00014430089008080213C0208008C4200209C
+:103FF00010400080020020210E0004930000000009
+:104000008F850020ACB000009362003E9363003FB8
+:10401000304200FF00021200306300FF0043102511
+:10402000ACA2000493620082000216000002160394
+:1040300004410005000000003C0308008C630048B8
+:104040000A000FE6000000009362003E304200408C
+:10405000144000030000182193620081304300FFE8
+:104060009362008200031E00304200FF0002140031
+:1040700000621825ACA300088F620040ACA2000CBF
+:104080008F620048ACA200108F62004CACA20014FA
+:104090008F6200508F63004C0043102304410003E3
+:1040A000000000000A000FFA8F62004C8F6200507F
+:1040B000ACA200183C02080094424B5E3C03C00BCB
+:1040C00000002021004310250E0004B8ACA2001C03
+:1040D0008F6200548F840020AC8200008F620058F1
+:1040E000AC8200048F62005CAC8200088F620060CA
+:1040F0008F43007400431021AC82000C8F62006477
+:10410000AC820010976300689762006A00031C008D
+:104110003042FFFF00621825AC83001493620082D6
+:1041200024030080304200FF14430003000000001D
+:104130000A00102EAC8000188F63000C24020001CE
+:104140001062000E2402FFFF9362003E30420040E6
+:104150001440000A2402FFFF8F63000C8F4200749A
+:10416000006218233C020800006210241440000280
+:10417000000028210060282100051043AC820018AF
+:104180003C02080094424B5E3C03C00C000020211E
+:10419000004310258F8300200E0004B8AC62001C81
+:1041A0008F6200188F8300203C05080094A54B5EA9
+:1041B00024040001AC620000AC6000048F66006C57
+:1041C0003C02400D00A22825AC6600088F6200DC8E
+:1041D000AC62000CAC600010936200050002160097
+:1041E000AC620014AC6000180E0004B8AC65001C92
+:1041F000020020218FBF00148FB00010A3600005C3
+:104200000A00042127BD00188FBF00148FB00010D2
+:1042100003E0000827BD00189742007C30C600FF6D
+:10422000A08600843047FFFF2402000514C2000B63
+:1042300024E3465090A201122C42000710400007D0
+:1042400024E30A0090A30112240200140062100467
+:1042500000E210210A0010663047FFFF3067FFFFC1
+:1042600003E00008A4870014AC87004C8CA201086E
+:104270000080402100A0482100E2102330C600FF4A
+:104280001840000393AA001324E2FFFCACA201082B
+:1042900030C2000110400008000000008D020050F4
+:1042A00000E2102304410013240600058D0200548F
+:1042B00010E20010000000008D02005414E2001A09
+:1042C000000000003C0208008C4200D83042002070
+:1042D0001040000A2402000191030078910200833B
+:1042E000144300062402000101002021012028219E
+:1042F000240600040A00105400000000A1000084FD
+:1043000011400009A50200148F4301008F4201F8FB
+:104310000440FFFE24020002AF4301C0A34201C4D7
+:104320003C021000AF4201F803E00008000000006A
+:1043300027BDFFE88FA90028AFBF001000804021F3
+:1043400000E918231860007330C600FFA080007CCD
+:10435000A08000818CA2010800E210230440004DDF
+:10436000000000008C8200509483003C8C84006428
+:10437000004748233063FFFF012318210083202BCF
+:1043800010800004000000008D0200640A0010B7D5
+:1043900000E210219502003C3042FFFF0122102173
+:1043A00000E21021AD02005C9502003C8D03005C30
+:1043B0003042FFFF0002104000E210210043102BAA
+:1043C00010400003000000000A0010C68D02005CCF
+:1043D0009502003C3042FFFF0002104000E2102135
+:1043E000AD02005CA1000084AD07004C8CA2010866
+:1043F00000E210231840000224E2FFFCACA20108F6
+:1044000030C200011040000A000000008D02005080
+:1044100000E2102304410004010020218D02005419
+:1044200014E20003000000000A0010E82406000562
+:104430008D02005414E200478FBF00103C020800B8
+:104440008C4200D8304200201040000A24020001B3
+:1044500091030078910200831443000624020001B6
+:1044600001002021240600048FBF00100A00105410
+:1044700027BD0018A1000084A50200148F4301008D
+:104480008F4201F80440FFFE240200020A00110DD1
+:10449000000000008C82005C004910230043102BB8
+:1044A00054400001AC87005C9502003C3042FFFFA5
+:1044B0000062102B14400007240200029502003C09
+:1044C0008D03005C3042FFFF00621821AD03005CE9
+:1044D00024020002AD07004CA10200840E000F0A66
+:1044E0008F4401001040001B8FBF00108F4301005C
+:1044F0008F4201F80440FFFE24020002AF4301C0D6
+:10450000A34201C43C021000AF4201F80A0011238B
+:104510008FBF001030C200101040000E8FBF00107F
+:104520008C83005C9482003C006918233042FFFFBA
+:10453000006218213C023FFF3444FFFF0083102B30
+:10454000544000010080182101231021AD02005CBD
+:104550008FBF001003E0000827BD001827BDFFE84B
+:104560008FAA0028AFBF00100080402100EA482336
+:104570001920002130C600FF8C83005C8C8200640F
+:10458000006A18230043102B5040001000691821C6
+:1045900094A2011001221021A4A2011094A20110E2
+:1045A0003042FFFF0043102B1440000A3C023FFF43
+:1045B00094A2011000431023A4A201109482003C95
+:1045C0003042FFFF0A00114200621821A4A001102E
+:1045D0003C023FFF3444FFFF0083102B5440000196
+:1045E0000080182100671021AD02005CA100007C52
+:1045F0000A00118AA100008130C200101040003C66
+:10460000000000008C820050004A1023184000383F
+:10461000000000009082007C24420001A082007C07
+:104620009082007C3C0308008C630024304200FF31
+:104630000043102B1440005C8FBF00108CA20108B7
+:1046400000E2102318400058000000008C83005442
+:104650009482003C006A18233042FFFF0003184395
+:10466000000210400043102A104000050000000026
+:104670008C820054004A10230A001171000210437A
+:104680009482003C3042FFFF00021040AD02006403
+:104690009502003C8D0400649503003C3042FFFF0E
+:1046A00000021040008220213063FFFF00831821A8
+:1046B00001431021AD02005C8D020054ACA2010840
+:1046C00024020002A10200840E000F0A8F440100A0
+:1046D000104000358FBF00108F4301008F4201F85A
+:1046E0000440FFFE240200020A0011B30000000093
+:1046F000AD07004C8CA2010800E210231840000214
+:1047000024E2FFFCACA2010830C200011040000A04
+:10471000000000008D02005000E21023044100045C
+:10472000010020218D02005414E20003000000006B
+:104730000A0011AA240600058D02005414E2001A92
+:104740008FBF00103C0208008C4200D8304200208D
+:104750001040000A240200019103007891020083B6
+:104760001443000624020001010020212406000455
+:104770008FBF00100A00105427BD0018A10000844C
+:10478000A50200148F4301008F4201F80440FFFE90
+:1047900024020002AF4301C0A34201C43C02100046
+:1047A000AF4201F88FBF001003E0000827BD0018DA
+:1047B0008FAA00108C8200500080402130C600FF7C
+:1047C000004A102300A048211840000700E01821EB
+:1047D00024020001A0800084A0A00112A482001481
+:1047E0000A001125AFAA0010A0800081AD07004C7F
+:1047F0008CA2010800E210231840000224E2FFFC12
+:10480000ACA2010830C20001104000080000000006
+:104810008D0200500062102304410013240600059D
+:104820008D02005410620010000000008D02005440
+:1048300014620011000000003C0208008C4200D805
+:10484000304200201040000A240200019103007849
+:10485000910200831443000624020001010020217C
+:1048600001202821240600040A0010540000000042
+:10487000A1000084A502001403E00008000000006D
+:1048800027BDFFE0AFBF0018274201009046000A95
+:104890008C4800148C8B004C9082008430C900FF3F
+:1048A00001681823304A00FF1C60001A2D460006DC
+:1048B000240200010142100410C00016304300031E
+:1048C000012030210100382114600007304C000C19
+:1048D00015800009304200301440000B8FBF0018D3
+:1048E0000A001214000000000E001125AFAB0010EA
+:1048F0000A0012148FBF00180E00109AAFAB001000
+:104900000A0012148FBF0018AFAB00100E0011BACE
+:10491000AFAA00148FBF001803E0000827BD0020D5
+:1049200024020003A08200848C82005403E000086B
+:10493000ACA201083C0200080342182190620081E9
+:10494000240600433C07601924420001A062008154
+:10495000906300813C0208008C4200C0306300FF7D
+:10496000146200102403FF803C0208008C4200E027
+:104970000082102100431024AF4200243C020800B2
+:104980008C4200E03C03000A008210213042007F8C
+:104990000342102100431021944500D40A000AF17B
+:1049A00030A5FFFF03E000080000000027BDFFE086
+:1049B000AFBF0018AFB10014AFB000108F4201803C
+:1049C0000080802100A088210E00121B00402021C1
+:1049D000A20000848E0200548FBF00188FB0001018
+:1049E000AE2201088FB1001403E0000827BD0020AB
+:1049F00027BDFFE03C020008AFB00010AFBF0018B9
+:104A0000AFB10014034280218F5101409203008412
+:104A10008E0400508E02004C14820040306600FF6D
+:104A20003C0208008C4200E02403FF800222102197
+:104A300000431024AF4200243C0208008C4200E0F6
+:104A40009744007C92050081022210213042007FB1
+:104A5000034218213C02000A0062182114A0000B36
+:104A60003084FFFF2402000554C20014248205DCB8
+:104A70009062011224420001A062011224020C8003
+:104A8000AF4200240A00127324020005A060011244
+:104A90002402000514C20009248205DC9202008170
+:104AA0002C4200075040000524820A009203008136
+:104AB0002402001400621004008210213044FFFF21
+:104AC000A60400140E00121B022020219602003CB6
+:104AD0008E03004C022020213042FFFF00021040D4
+:104AE000006218210E000250AE03005C9202007DAD
+:104AF00002202021344200400E000259A202007D13
+:104B00008F4201F80440FFFE24020002AF5101C0B1
+:104B1000A34201C43C021000AF4201F88FBF00184D
+:104B20008FB100148FB0001003E0000827BD0020F3
+:104B300008000ACC08000B1408000B9808000BE4CE
+:044B400008000C203D
+:0C4B44000A000028000000000000000033
+:104B50000000000D6370362E302E3135000000004D
+:104B600006000F040000000000000000000000002C
+:104B70000000000000000000000000000000000035
+:104B80000000000000000000000000000000002005
+:104B90000000000000000000000000000000000015
+:104BA0000000000000000000000000000000000005
+:104BB00000000000000000000000000000000001F4
+:104BC0000000002B000000000000000400030D4066
+:104BD00000000000000000000000000000000000D5
+:104BE00000000000000000001000000300000000B2
+:104BF0000000000D0000000D3C0208002442588413
+:104C00003C03080024635F50AC4000000043202BAD
+:104C10001480FFFD244200043C1D080037BD7FFCCA
+:104C200003A0F0213C100800261000A03C1C080046
+:104C3000279C58840E0001AC000000000000000D0D
+:104C400027BDFFE83C096018AFBF00108D2C500055
+:104C5000240DFF7F24080031018D5824356A380C5B
+:104C600024070C003C1A8000AD2A50003C04800A46
+:104C7000AF4800083C1B8008AF4700240E00091510
+:104C8000AF8400100E0008D8000000000E000825B8
+:104C9000000000000E001252000000003C046016EC
+:104CA0008C8500003C06FFFF3C02535300A61824ED
+:104CB0001062004734867C0094C201F2A780002C69
+:104CC00010400003A78000CC38581E1EA798002C67
+:104CD00094C201F810400004978300CC38591E1E7E
+:104CE000A79900CC978300CC2C7F006753E000018C
+:104CF000240300669784002C2C82040114400002D7
+:104D000000602821240404003C0760008CE904387A
+:104D10002403103C3128FFFF1103001F30B9FFFFAF
+:104D200057200010A38000CE24020050A38200CEA2
+:104D3000939F00CE53E0000FA78500CCA78000CC46
+:104D4000978500CC8FBF0010A780002CA78000346F
+:104D5000A78000E63C010800AC25008003E00008C5
+:104D600027BD0018939F00CE57E0FFF5A78000CC29
+:104D7000A78500CC978500CC8FBF0010A784002C9E
+:104D8000A7800034A78000E63C010800AC25008025
+:104D900003E0000827BD0018A38000CE8CCB003CA8
+:104DA000316A00011140000E0000000030A7FFFF33
+:104DB00010E0FFDE240200508CCC00C831860001D8
+:104DC00014C0FFDC939F00CE0A00007A2402005139
+:104DD0008C8F00043C0E60000A00005D01EE302163
+:104DE0008CEF0808240D5708000F740211CD000441
+:104DF00030B8FFFF240500660A00007B240404008D
+:104E00001700FFCC939F00CE0A00007A24020050C6
+:104E10008F8600103089FFFF000939408CC30010D5
+:104E20003C08005000E82025AF4300388CC5001432
+:104E300027420400AF82001CAF45003CAF44003065
+:104E40000000000000000000000000000000000062
+:104E50000000000000000000000000000000000052
+:104E60008F4B0000316A00201140FFFD0000000060
+:104E700003E00008000000008F840010948A001AEC
+:104E80008C8700243149FFFF000940C000E8302131
+:104E9000AF46003C8C8500248F43003C00A31023C8
+:104EA00018400029000000008C8B002025620001C2
+:104EB0003C0D005035AC0008AF420038AF4C00301C
+:104EC00000000000000000000000000000000000E2
+:104ED00000000000000000000000000000000000D2
+:104EE0008F4F000031EE002011C0FFFD00000000D8
+:104EF0008F4A04003C080020AC8A00108F4904044B
+:104F0000AC890014AF4800300000000094860018FF
+:104F10009487001C00C71821A48300189485001AE8
+:104F200024A20001A482001A9498001A9499001EE9
+:104F3000133800030000000003E000080000000038
+:104F400003E00008A480001A8C8200200A0000DC24
+:104F50003C0D00500A0000CD000000003C0308009A
+:104F60008C6300208F82001827BDFFE810620008C4
+:104F7000AFBF00100E000104AF8300183C0308000F
+:104F80008C63002024040001106400048F89001049
+:104F90008FBF001003E0000827BD00188FBF00106E
+:104FA0003C076012A520000A9528000A34E500108D
+:104FB00027BD00183106FFFF03E00008ACA60090F3
+:104FC0003C0208008C42002027BDFFC8AFBF003460
+:104FD000AFBE0030AFB7002CAFB60028AFB500248D
+:104FE000AFB40020AFB3001CAFB20018AFB10014D3
+:104FF00010400050AFB000108F840010948600065F
+:105000009483000A00C3282330B6FFFF12C0004A71
+:105010008FBF003494890018948A000A012A402323
+:105020003102FFFF02C2382B14E0000202C020212F
+:10503000004020212C8C0005158000020080A0215A
+:10504000241400040E0000B3028020218F8700107A
+:1050500002809821AF80001494ED000A028088211C
+:105060001280004E31B2FFFF3C1770003C1540002B
+:105070003C1E60008F8F001C8DEE000001D71824AD
+:10508000507500500220202102A3802B160000350D
+:105090003C182000507800470220202124100001F5
+:1050A0008F83001414600039029158230230F823D2
+:1050B0000250C82133F1FFFF1620FFEE3332FFFF0D
+:1050C0008F8700103C110020AF510030000000001D
+:1050D00094E6000A3C1E601237D5001002662821B3
+:1050E000A4E5000A94E2000A94F2000A94F400187D
+:1050F0003057FFFF1292003BAEB700908CED0014CA
+:105100008CE400100013714001AE4021000E5FC31B
+:10511000010E502B008B4821012A1821ACE8001405
+:10512000ACE3001002D3382330F6FFFF16C0FFB9FE
+:105130008F8400108FBF00348FBE00308FB7002CDB
+:105140008FB600288FB500248FB400208FB3001CC9
+:105150008FB200188FB100148FB0001003E0000868
+:1051600027BD0038107E001B000000001477FFCC24
+:10517000241000010E001598000000008F83001419
+:105180001060FFCB0230F823029158238F87001064
+:10519000017020210A0001973093FFFF8F830014D4
+:1051A0001460FFCB3C110020AF5100300A000163B6
+:1051B000000000000E00077D024028210A00015770
+:1051C000004080210E00033A024028210A000157C6
+:1051D000004080210E001460022020210A000157A7
+:1051E000004080210E0000CD000000000A0001797F
+:1051F00002D3382327BDFFE8AFB00010AFBF0014C3
+:105200000E00003F000000003C028000345000709F
+:105210000A0001BA8E0600008F4F000039EE00012F
+:1052200031C20001104000248F8600A88E070000C4
+:105230003C0C08008D8C003C3C0908008D2900388E
+:1052400000E66823018D28210000502100AD302B9D
+:10525000012A4021010620213C010800AC25003C28
+:10526000AF8700A83C010800AC2400380E000106FE
+:10527000000000003C0308008C6300701060FFE633
+:10528000006020213C0508008CA500683C06080051
+:105290008CC6006C0E001527000000003C010800C1
+:1052A000AC2000708F4F000039EE000131C20001C8
+:1052B0001440FFDE8F8600A88E0A00008F8B00A8A6
+:1052C0003C0508008CA5003C3C0408008C84003898
+:1052D000014B482300A938210082182100E9402B06
+:1052E000006810213C010800AC27003C3C0108008C
+:1052F000AC2200388F5F01002419FF0024180C0035
+:1053000003F9202410980012AF840000AF4400205D
+:10531000936D0000240C002031A600FF10CC001279
+:10532000240E005010CE00043C194000AF59013843
+:105330000A0001B3000000000E0011C800000000C8
+:105340003C194000AF5901380A0001B300000000C9
+:105350000E00011F000000003C194000AF59013849
+:105360000A0001B3000000008F58010000802821CE
+:10537000330F00FF01E020210E0002F1AF8F000487
+:105380003C194000AF5901380A0001B30000000089
+:1053900000A4102B2403000110400009000030215C
+:1053A0000005284000A4102B04A0000300031840AF
+:1053B0005440FFFC000528405060000A0004182BF0
+:1053C0000085382B54E000040003184200C3302548
+:1053D00000852023000318421460FFF900052842CD
+:1053E0000004182B03E0000800C310218F4201B80D
+:1053F0000440FFFE00000000AF4401803C031000A9
+:1054000024040040AF450184A3440188A3460189D8
+:10541000A747018A03E00008AF4301B83084FFFFCB
+:105420000080382130A5FFFF000020210A00022A59
+:10543000240600803087FFFF8CA40000240600387B
+:105440000A00022A000028218F8300388F8600304E
+:105450001066000B008040213C07080024E759F843
+:10546000000328C000A710218C4400002463000121
+:10547000108800053063000F5466FFFA000328C04F
+:1054800003E00008000010213C07080024E759FC55
+:1054900000A7302103E000088CC200003C0390000C
+:1054A0003462000100822025AF4400208F45002097
+:1054B00004A0FFFE0000000003E000080000000060
+:1054C0003C038000346200010082202503E00008D4
+:1054D000AF44002027BDFFE0AFB100143091FFFFC3
+:1054E000AFB00010AFBF00181220001300A0802141
+:1054F0008CA2000024040002240601401040000F8A
+:10550000004028210E000C5C00000000000010216B
+:10551000AE000000022038218FBF00188FB10014A8
+:105520008FB0001000402021000028210000302111
+:105530000A00022A27BD00208CA200000220382188
+:105540008FBF00188FB100148FB0001000402021D1
+:1055500000002821000030210A00022A27BD002077
+:1055600000A010213087FFFF8CA500048C440000B0
+:105570000A00022A2406000627BDFFE0AFB0001093
+:10558000AFBF0018AFB100149363003E00808021CC
+:105590000080282130620040000020211040000FD0
+:1055A0008E1100000E000851022020219367000098
+:1055B0002404005030E500FF50A400128E0F0000BC
+:1055C000022020218FBF00188FB100148FB000106F
+:1055D000A762013C0A00091127BD00200E000287C6
+:1055E000000000000E0008510220202193670000F7
+:1055F0002404005030E500FF14A4FFF20220202113
+:105600008E0F00003C1008008E1000503C0D000C66
+:10561000240BFF8001F05021314E007F01DA602120
+:10562000018D4021014B4824AF4900280220202150
+:105630008FBF00188FB100148FB00010A50200D6E4
+:1056400027BD00200A000911AF8800D027BDFFE068
+:10565000AFBF0018AFB10014AFB0001093660001E7
+:10566000008080210E00025630D1000493640005B2
+:10567000001029C2A765000034830040A363000521
+:105680000E00025F020020210E00091302002021FB
+:1056900024020001AF62000C02002821A762001062
+:1056A00024040002A762001224060140A76200142D
+:1056B0000E000C5CA76200161620000F8FBF0018AA
+:1056C000978C00343C0B08008D6B00782588FFFF19
+:1056D0003109FFFF256A0001012A382B10E000067E
+:1056E000A78800343C0F6006240E001635ED00102C
+:1056F000ADAE00508FBF00188FB100148FB00010F6
+:1057000003E0000827BD002027BDFFE0AFB1001473
+:10571000AFBF0018AFB0001000A088211080000AB1
+:105720003C03600024020080108200120000000090
+:105730000000000D8FBF00188FB100148FB0001053
+:1057400003E0000827BD00208C682BF80500FFFE51
+:1057500000000000AC712BC08FBF00188FB1001487
+:105760008FB000103C09100027BD002003E00008A6
+:10577000AC692BF80E00025600A0202193650005AD
+:10578000022020210E00025F30B000FF2403003E03
+:105790001603FFE7000000008F4401780480FFFE3D
+:1057A000240700073C061000AF51014002202021D1
+:1057B000A34701448FBF00188FB100148FB00010B1
+:1057C000AF4601780A0002C227BD002027BDFFE8CE
+:1057D000AFBF0014AFB000108F50002000000000D9
+:1057E0000E000913AF440020AF5000208FBF0014FB
+:1057F0008FB0001003E0000827BD00183084FFFFC1
+:10580000008038212406003500A020210A00022A49
+:10581000000028213084FFFF008038212406003654
+:1058200000A020210A00022A0000282127BDFFD065
+:10583000AFB3001C3093FFFFAFB50024AFB2001828
+:10584000AFBF0028AFB40020AFB10014AFB000105C
+:1058500030B5FFFF12600027000090218F90001CE0
+:105860008E0300003C0680002402004000033E023C
+:1058700000032C0230E4007F006688241482001D9F
+:1058800030A500FF8F8300282C68000A510000100B
+:105890008F910014000358803C0C0800258C56881A
+:1058A000016C50218D49000001200008000000001B
+:1058B00002B210213045FFFF0E000236240400849E
+:1058C000162000028F90001CAF8000288F910014DA
+:1058D000260C002026430001018080213072FFFF4A
+:1058E00016200004AF8C001C0253502B1540FFDC27
+:1058F00000000000024010218FBF00288FB5002457
+:105900008FB400208FB3001C8FB200188FB1001429
+:105910008FB0001003E0000827BD0030240E0034D3
+:1059200014AE00F9000000009203000E241F168040
+:105930003C07000CA36300219202000D0347C8211D
+:105940003C066000A3620020961100123C0A7FFF13
+:10595000354CFFFFA771003C960B00102403000597
+:105960003168FFFFAF6800848E05001CAF5F002820
+:105970008F3800008CC4444803057826008F3021FE
+:10598000AF66004C8F69004C24CE00013C057F00BF
+:10599000AF6900508F740050AF740054AF66007050
+:1059A000AF6E00588F6D005824140050AF6D005C2E
+:1059B000A3600023AF6C0064A36300378E02001461
+:1059C000AF6200488F710048AF7100248E0B001841
+:1059D000AF6B006C9208000CA3680036937F003E0A
+:1059E00037F90020A379003E8F78007403058024E6
+:1059F000360F4000AF6F007493640000308900FFE1
+:105A0000513402452404FF803C04080024845A7861
+:105A10000E00028D000000003C1008008E105A7825
+:105A20000E00025602002021240600042407000173
+:105A3000A366007D020020210E00025FA36700051F
+:105A40008F5F017807E0FFFE240B0002AF5001409A
+:105A5000A34B01448F90001C3C081000AF48017814
+:105A60000A000362AF8000282CAD003751A0FF98D8
+:105A70008F9100140005A0803C180800271856B02C
+:105A8000029878218DEE000001C00008000000009F
+:105A90002418000614B80011000000003C0808009B
+:105AA0008D085A7824040005AF4800208E1F001886
+:105AB000AF7F00188F79004CAF79001C8F650050C4
+:105AC000122000C0AF6500700A000362AF84002896
+:105AD0002406000710A60083240300063C050800E6
+:105AE00024A55A780E000264240400818F90001CC3
+:105AF0000011102B0A000362AF8200282407000463
+:105B000014A7FFF6240500503C1808008F185A7897
+:105B1000AF5800208E0F0008AF6F00408E090008BC
+:105B2000AF6900448E14000CAF7400488E0E001054
+:105B3000AF6E004C8E0D0010AF6D00848E0A001405
+:105B4000AF6A00508E0C0018AF6C00548E04001C1D
+:105B5000AF64005893630000306B00FF116501D8FB
+:105B6000000000008F7400488F6900400289702394
+:105B700005C000042404008C1620FFDE240200036C
+:105B8000240400823C05080024A55A780E000287F0
+:105B9000000000008F90001C000010210A0003622A
+:105BA000AF820028240F000514AFFFCC240520008D
+:105BB0003C0708008CE75A78AF4700208E060004A7
+:105BC000AF66005C9208000824100008A36800215A
+:105BD0008F9F001C93F90009A37900208F86001C79
+:105BE00090D8000A330400FF10900011000000005C
+:105BF0002885000914A0006924020002240A00205C
+:105C0000108A000B34058000288D002115A00008A3
+:105C100024054000240E0040108E00053C050001C4
+:105C200024140080109400023C050002240540006A
+:105C30008F7800743C19FF00031980240205782531
+:105C4000AF6F007490C4000BA36400818F84001CAC
+:105C50009489000C11200192000000009490000C27
+:105C60002406FFBF24050004A770003C908F000E9F
+:105C7000A36F003E8F84001C9089000FA369003F32
+:105C80008F8B001C8D6E00108F54007401D468231C
+:105C9000AF6D00608D6A0014AF6A0064956C0018E7
+:105CA000A76C00689563001AA763006A8D62001CE8
+:105CB000AF62006C9167000EA367003E9368003EE0
+:105CC0000106F8241220014BA37F003E8F90001C98
+:105CD0000A000362AF8500282407002214A7FF7F73
+:105CE000240300073C0B08008D6B5A781220000C2F
+:105CF000AF4B00200A000362AF830028240C00335E
+:105D000010AC0014240A00283C05080024A55A7889
+:105D10000E00023C240400810A0003EB8F90001C5B
+:105D20003C04080024845A780E00028D0000000014
+:105D30009363000024110050306200FF10510135C0
+:105D4000000000008F90001C000018210A00036270
+:105D5000AF8300283C0D08008DAD5A7824040081E3
+:105D6000AF4D00203C05080024A55A780E00023CE7
+:105D7000A36A00348F90001C240200090A00036209
+:105D8000AF82002802B288213225FFFF0E000236C2
+:105D9000240400840A0003628F90001C1082FFA478
+:105DA00024050400288B000311600170240C0004FA
+:105DB000240300015483FF9E240540000A00043B95
+:105DC000240501003C04080024845A788F62004CAA
+:105DD0000E00028D8F6300508F90001C0000202168
+:105DE0000A000362AF8400288E1000042404008A95
+:105DF000AF50002093790005333800021700015F8F
+:105E0000020028219368002302002821311F00206E
+:105E100017E0015A2404008D9367003F2406001206
+:105E200030E200FF10460155240400810E000256A6
+:105E30000200202193630023240500040200202196
+:105E4000346B0042A36B00230E00025FA365007D4C
+:105E50008F4401780480FFFE240A0002AF50014005
+:105E6000A34A01448F90001C3C0C1000AF4C0178F9
+:105E70000A0003EC0011102B8E1000042404008A89
+:105E8000AF500020936E000531CD000215A0001622
+:105E900002002821936F003F2414000402002821EF
+:105EA00031E900FF11340010240400810E00025675
+:105EB000020020219362002324080012241FFFFE09
+:105EC00034460020A3660023A368003F93790005B1
+:105ED00002002021033FC0240E00025FA3780005CA
+:105EE00002002821000020210E00033400000000E1
+:105EF0000A0003EB8F90001C8E1000043C03000886
+:105F00000343A021AF500020928B000024050050D5
+:105F1000316400FF10850161240700880200202100
+:105F2000000028210E00022A2406000E928D000097
+:105F3000240EFF800200282101AE8025A2900000DF
+:105F4000240400040E000C5C240600300A0003EB5D
+:105F50008F90001C8E0800043C14080026945A7888
+:105F60003C010800AC285A78AF480020921F00037B
+:105F700033F9000413200002240200122402000658
+:105F8000A362003F920B001B2404FFC03165003F59
+:105F900000A43825A367003E9206000330C200012A
+:105FA00014400132000000008E020008AE8200089A
+:105FB0003C0208008C425A8010400131000249C264
+:105FC000A76900088E14000C240C0001240300149F
+:105FD000AF74002C8E0E0010AF6E0030960D0016C0
+:105FE000A76D0038960A0014A76A003AAF6C000C3F
+:105FF000A76C0010A76C0012A76C0014A76C001609
+:1060000012200136A3630034920F000331F0000226
+:106010002E1100018F90001C262200080A00036246
+:10602000AF8200288E0400043C0E0008034E30218D
+:10603000AF4400208E05000890CD0000240C0050D5
+:1060400031AA00FF114C00862407008824060009AD
+:106050000E00022A000000000A0003EB8F90001CD3
+:106060008E04001C0E00024100000000104000F4ED
+:10607000004050218F89001C240700890140202105
+:106080008D25001C240600010E00022A00000000DD
+:106090000A0003EB8F90001C960D00023C140800D0
+:1060A00026945A7831AA0004514000B83C10600090
+:1060B0008E0E001C3C010800AC2E5A78AF4E00201A
+:1060C000920700102408001430E200FF144800D6A4
+:1060D00000000000960B00023163000114600165AE
+:1060E000000000008E020004AE8200083C1408008C
+:1060F0008E945A801280015B000000008F7400743F
+:106100003C0380002404000102835825AF6B007417
+:10611000A3600005AF64000C3C0708008CE75A80C0
+:106120008F86001CA7640010000711C2A76400122C
+:10613000A7640014A7640016A76200088CC80008B2
+:1061400024040002AF68002C8CC5000CAF65003041
+:1061500090DF0010A37F00348F99001C9330001152
+:10616000A37000358F98001C930F0012A36F0036A8
+:106170008F89001C912E0013A36E00378F90001C96
+:10618000960D0014A76D0038960A0016A76A003A0B
+:106190008E0C0018AF6C00245620FDCCAF84002874
+:1061A0003C05080024A55A780E0002640000202156
+:1061B0008F90001C0A0004A7000020218E1000040C
+:1061C00024070081AF500020936900233134001070
+:1061D000128000170000000002002021000028218A
+:1061E0002406001F0E00022A000000000A0003EB34
+:1061F0008F90001C3C05080024A55A780E000287E9
+:10620000240400828F90001C000028210A000362F1
+:10621000AF8500283C0408008C845A780E0014E5F1
+:10622000000000008F90001C0A000482000018216A
+:106230000E00025602002021937800230200202144
+:10624000370F00100E00025FA36F002300003821FB
+:1062500002002021000028210A0005A82406001FB2
+:10626000920F000C31E90001112000030000000032
+:106270009618000EA4D8002C921F000C33F90002CF
+:1062800013200005000038218E0200149608001229
+:10629000ACC2001CA4C8001A0A0005432406000969
+:1062A0003C05080024A55A780E0002872404008BC0
+:1062B0008F90001C0011282B0A000362AF85002874
+:1062C000AF6000843C0A08008D4A5A783C0D0800F3
+:1062D0008DAD0050240CFF803C02000C014D1821B4
+:1062E000006C2024AF4400288E070014306B007F20
+:1062F000017A282100A2C821AF2700D88E060014F9
+:10630000AF9900D0AF2600DC8E080010251FFFFEDD
+:106310000A000408AF3F01083C0508008CA55A7824
+:106320003C1908008F39005024CCFFFE00B9C02171
+:1063300003047824AF4F00283C1408008E945A7848
+:106340003C0908008D2900500289702131CD007F61
+:1063500001BA502101478021AE0600D8AF9000D08D
+:10636000AE0000DC0A0003B1AE0C0108548CFE3014
+:10637000240540000A00043B240510000E00032EF3
+:10638000000000000A0003EB8F90001C8E0F442CCD
+:106390003C186C62370979703C010800AC205A78CF
+:1063A00015E9000824050140979F00349786002CCA
+:1063B0000280282103E6C82B132000112404009238
+:1063C000240501400E000C7A240400023C01080060
+:1063D000AC225A78AF4200203C0508008CA55A78C0
+:1063E00010A00005240400830E00084500000000F2
+:1063F00010400009240400833C05080024A55A78B5
+:106400000E000264000000008F90001C0011202B81
+:106410000A000362AF8400280E0008490000000053
+:106420000A00055F8F90001C0E00084D0000000060
+:106430003C05080024A55A780A00062F2404008B86
+:10644000240400040E000C7A240500301440002AB5
+:10645000004050218F89001C240700830140202127
+:106460008D25001C0A000551240600018E04000839
+:106470000E000241000000000A00051BAE82000869
+:106480003C05080024A55A780E00023C240400872D
+:106490008F90001C0A0005360011102B8F830038E6
+:1064A0008F8600301066FE9D000038213C070800F2
+:1064B00024E759FC000320C0008728218CAC000091
+:1064C00011900061246A00013143000F5466FFFA05
+:1064D000000320C00A0004F6000038213C05080033
+:1064E00024A55A780E000287240400828F90001C95
+:1064F0000A000536000010213C0B0008034B202148
+:106500002403005024070001AF420020A0830000B4
+:10651000A08700018F82001C90480004A08800180A
+:106520008F85001C90A60005A08600198F9F001C77
+:1065300093F90006A099001A8F90001C921800078A
+:10654000A098001B8F94001C928F0008A08F001C45
+:106550008F89001C912E0009A08E001D8F8D001CBC
+:1065600091AC000AA08C001E8F8B001C3C0C080014
+:10657000258C59FC9163000B3C0B0800256B59F8E6
+:10658000A083001F8F87001C90E8000CA0880020CB
+:106590008F82001C9045000D24024646A0850021F4
+:1065A0008F86001C90DF000EA09F00228F99001C98
+:1065B0009330000FA09000238F98001C93140010BC
+:1065C000A09400248F8F001C91E90011A089002560
+:1065D0008F89001C8F8E00308F900038952D00140D
+:1065E000000E18C025C80001A48D002895270016AC
+:1065F000006C3021006BC821A487002A9525001863
+:106600003108000FA485002CA482002E8D3F001CB1
+:10661000ACCA0000AF88003011100006AF3F000088
+:10662000000038218D25001C014020210A00055161
+:1066300024060001250C00013184000F00003821E0
+:106640000A0006B8AF8400383C07080024E759F870
+:106650000087302100003821ACA000000A0004F6B9
+:10666000ACC000003C05080024A55A780A00062F9B
+:10667000240400878E0400040E0002410000000084
+:106680000A00056AAE8200083084FFFF30C600FFB2
+:106690008F4201B80440FFFE00064400010430258B
+:1066A0003C07200000C720253C031000AF400180BC
+:1066B000AF450184AF44018803E00008AF4301B84F
+:1066C00027BDFFE8AFB00010AFBF00143C0760006B
+:1066D000240600021080000600A080210010102B6C
+:1066E0008FBF00148FB0001003E0000827BD001812
+:1066F0003C09600EAD2000348CE5201C8F82001C0C
+:106700002408FFFC00A81824ACE3201C0E0006D1CE
+:106710008C45000C0010102B8FBF00148FB00010A0
+:1067200003E0000827BD00183C02600E344701005A
+:1067300024090018274A040000000000000000009F
+:10674000000000003C06005034C30200AF44003893
+:10675000AF45003CAF430030014018218F4B000093
+:10676000316800201100FFFD2406007F2408FFFF90
+:106770008C6C000024C6FFFF24630004ACEC000016
+:1067800014C8FFFB24E70004000000000000000024
+:10679000000000003C0F0020AF4F00300000000060
+:1067A00024AD020001A5702B2529FFFF008E2021BA
+:1067B0001520FFE101A0282103E0000800000000EF
+:1067C00027BDFFE0AFB10014AFBF0018AFB000109D
+:1067D0003C05600E8CA20034008088211440000625
+:1067E0003C0460008C87201C2408FFFC00E8302457
+:1067F00034C30001AC83201C8F8B001C24090001D2
+:10680000ACA90034956900028D6500148D70000CF0
+:106810002D2400818D6700048D660008108000071C
+:106820008D6A00102D2C00041580000E30CE00075C
+:10683000312D000311A0000B000000002404008B88
+:10684000020028210E0006D1240600030011102B9F
+:106850008FBF00188FB100148FB0001003E0000844
+:1068600027BD002015C0FFF62404008B3C03002048
+:10687000AF4300300000000024020001AF8200148A
+:106880000000000000000000000000003C1F01505C
+:10689000013FC825253800033C0F600EAF47003884
+:1068A00000181882AF46003C35E8003CAF59003074
+:1068B000274704008F4400003086002010C0FFFDF1
+:1068C00000000000106000082466FFFF2403FFFFA3
+:1068D0008CEB000024C6FFFF24E70004AD0B000092
+:1068E00014C3FFFB250800043C08600EAD09003806
+:1068F0000000000000000000000000003C07002035
+:10690000AF470030000000000E0006F901402021D2
+:1069100002002821000020210E0006D124060003D9
+:106920000011102B8FBF00188FB100148FB0001012
+:1069300003E0000827BD002027BDFFE0AFB200182C
+:106940003092FFFFAFB10014AFBF001CAFB000101A
+:106950001640000D000088210A0007AA022010211D
+:1069600024050001508500278CE5000C0000000D77
+:10697000262300013071FFFF24E200200232382B71
+:1069800010E00019AF82001C8F8200141440001622
+:106990008F87001C3C0670003C0320008CE5000043
+:1069A00000A62024148300108F84003C00054402BC
+:1069B0003C09800000A980241480FFE9310600FF13
+:1069C0002CCA00095140FFEB262300010006688015
+:1069D0003C0E080025CE578C01AE60218D8B000047
+:1069E0000160000800000000022010218FBF001C81
+:1069F0008FB200188FB100148FB0001003E00008B0
+:106A000027BD00200E0006D1240400841600FFD804
+:106A10008F87001C0A00078BAF80003C90EF0002BC
+:106A200000002021240600090E0006D1000F2E00D0
+:106A30008F87001C0010102B0A00078BAF82003CD0
+:106A4000020028210E0006DF240400018F87001CAD
+:106A50000A00078BAF82003C020028210E0006DFEF
+:106A6000000020210A0007C38F87001C0E00071FAB
+:106A7000020020210A0007C38F87001C30B0FFFFEF
+:106A8000001019C08F5801B80700FFFE3C1F2004FA
+:106A90003C191000AF430180AF400184AF5F018813
+:106AA000AF5901B80A00078C262300013082FFFF8E
+:106AB00014400003000018210004240224030010E5
+:106AC000308500FF14A000053087000F2466000801
+:106AD0000004220230C300FF3087000F14E00005DD
+:106AE000308900032468000400042102310300FF00
+:106AF0003089000315200005388B0001246A00024C
+:106B000000042082314300FF388B00013164000112
+:106B100010800002246C0001318300FF03E00008B4
+:106B200000601021308BFFFF000B394230E600FF80
+:106B30003C09080025295978000640800109602198
+:106B40008D8700003164001F240A0001008A1804A8
+:106B500030A500FF00E3202514A000020003102749
+:106B600000E22024240F000100CF700401096821F5
+:106B7000000E282714800005ADA400008F86000CAD
+:106B800000A6102403E00008AF82000C8F88000CE0
+:106B900001C8102503E00008AF82000C3C06001F6E
+:106BA0003C0360003084FFFF34C5FF8024020020D6
+:106BB000AC602008AC60200CAC602010AC652014E8
+:106BC000AC642018AC62200000000000000000004F
+:106BD00003E000080000000027BDFFE82402FFFFDB
+:106BE000AFBF0010AF82000C000020213C0608005F
+:106BF00024C659782405FFFF248900010004408041
+:106C00003124FFFF010618212C87002014E0FFFA31
+:106C1000AC6500000E0008160000202124020001CF
+:106C20003C04600024050020AC822018AC852000C4
+:106C3000000000000000000000000000244A0001E5
+:106C40003142FFFF2C46040014C0FFF78FBF001035
+:106C500003E0000827BD00188F8300082C620400A1
+:106C600003E00008384200018F830008246200011D
+:106C700003E00008AF8200088F8300082462FFFF52
+:106C800003E00008AF82000827BDFFE0AFB10014A9
+:106C9000AFBF0018AFB000108F6B00303C06600033
+:106CA00000808821ACCB20088F6A002C3C02800039
+:106CB00024030008ACCA200C9769003A9768003892
+:106CC00000092C003107FFFF00A72025ACC42010CD
+:106CD000ACC22014ACC32000000000000000000083
+:106CE000000000003C0360008C6D200031AC000807
+:106CF0001580FFF9000000008C6E201405C00020F4
+:106D0000000000000E0007DA8F84000C00024080B3
+:106D10003C09080025295978010938218CE4000034
+:106D20000E0007DA00028140020220213090FFFFAE
+:106D3000020020210E0007F8000028213C0C8000F2
+:106D4000022C58253210FFFF3C116000240A00205D
+:106D5000AE2B2014AE302018AE2A20000000000018
+:106D60000000000000000000020010218FBF00188A
+:106D70008FB100148FB0001003E0000827BD002081
+:106D80008C6620143C02001F3443FF803C1FFFE848
+:106D900000C3C02437F9080003198021001079C20C
+:106DA0003C0C8000022C582531F0FFFF3C116000A4
+:106DB000240A0020AE2B2014AE302018AE2A20006A
+:106DC0000000000000000000000000000200102190
+:106DD0008FBF00188FB100148FB0001003E00008BF
+:106DE00027BD002027BDFFE8AFB000103402FFFF31
+:106DF0003090FFFFAFBF00141202000602002021F6
+:106E00000E00081600000000020020210E0007F806
+:106E1000240500018F8400088FBF00148FB000107C
+:106E20002483FFFF27BD001803E00008AF8300089C
+:106E3000000439C230E6003F00043B42000718401E
+:106E4000240210002CC4002024C8FFE0AF42002C14
+:106E5000246300011480000330A900FF00071840DC
+:106E6000310600FF0003608024080001019A5821C8
+:106E70003C0A000E00C82804016A382111200005D0
+:106E8000000530278CE900000125302503E00008CB
+:106E9000ACE600008CEE000001C6682403E00008A8
+:106EA000ACED000027BDFFE8AFBF0014AFB000108D
+:106EB0003C0460008C8508083403F00030A2F00028
+:106EC00050430006240200018C8708083404E000C7
+:106ED00030E6F00010C4001E24020002AF82004021
+:106EE0003C1060003C0A0200AE0A0814240910009D
+:106EF0003C08000E8E03440003482021AF49002CBB
+:106F0000240501200E000CC0000030218F830040BA
+:106F1000106000043C021691240B0001106B000E5F
+:106F20003C023D2C344F0090AE0F44088FBF00143C
+:106F30008FB000103C0C6000240E10003C0D0200CD
+:106F400027BD0018AD8E442003E00008AD8D081069
+:106F50000A0008E7AF8000403C0218DA344F009086
+:106F6000AE0F44088FBF00148FB000103C0C6000BF
+:106F7000240E10003C0D020027BD0018AD8E4420E9
+:106F800003E00008AD8D08100A0008BB24050001CD
+:106F90000A0008BB000028213C08080025085D8481
+:106FA0002404FFFF010018212402001E2442FFFFD9
+:106FB000AC6400000441FFFD246300043C070800AA
+:106FC00024E75E008CE5FFFC2404001C240600017D
+:106FD000308A001F0146480424840001000910275C
+:106FE0002C8300201460FFFA00A22824ACE5FFFCEB
+:106FF0003C05666634A4616E3C06080024C65EC08B
+:10700000AF840058AF88009C2404FFFF00C0182103
+:107010002402001F2442FFFFAC6400000441FFFD76
+:10702000246300043C0766663C05080024A55E80D6
+:10703000AF86004834E6616EAF8600982404FFFFF7
+:1070400000A018212402000F2442FFFFAC640000BE
+:107050000441FFFD246300043C0B66663C06080007
+:1070600024C65E003568616EAF8500A4AF880070ED
+:107070002404FFFF00C018212402001F2442FFFF48
+:10708000AC6400000441FFFD246300043C0D66660F
+:107090003C0A0800254A5F4035AC616EAF8600901F
+:1070A000AF8C005C2404FFFF014018212402000380
+:1070B0002442FFFFAC6400000441FFFD2463000490
+:1070C0003C09080025295F508D27FFFC2404000699
+:1070D000240500013099001F0325C0042484000109
+:1070E000001878272C8E002015C0FFFA00EF3824F6
+:1070F000AD27FFFC3C09666624030400240403DC7E
+:1071000024050200240600663522616E3C08080052
+:1071100025085A84AF820074AF830044AF83006CAB
+:10712000AF830050AF830084AF8A008CAF840064CB
+:10713000AF85004CAF860054AF840078AF85006007
+:10714000AF86008001001821240200022442FFFFC4
+:10715000AC6000000441FFFD24630004240400032C
+:107160002403000C3C0A0800254A5A90AF8A0068A4
+:107170000A00098E2405FFFF000418802484000102
+:10718000006858212C8700C014E0FFFBAD650000AB
+:107190003C0E666635CD616E240C17A024081800DD
+:1071A000AF8D0088AF8C009403E00008AF88007CAE
+:1071B0002484007F000421C200004021000030210F
+:1071C00000003821000028210A0009A5AF8400A092
+:1071D0001060000624E7000100C4302124A500014E
+:1071E0002CC20BF51440FFFA2CA300663C090800E2
+:1071F00025295F4001201821240200032442FFFFBB
+:10720000AC6000000441FFFD2463000410E0001A9C
+:1072100024E3FFFF0003294210A0000A0000202100
+:107220002406FFFF3C03080024635F402484000120
+:107230000085502BAC660000250800011540FFFBBF
+:107240002463000430E2001F10400008000868803A
+:10725000240C0001004C38040008588001692821E2
+:1072600024E6FFFF03E00008ACA6000001A94021CE
+:107270002409FFFFAD09000003E000080000000042
+:10728000AF4400283C04000C034420210005288260
+:107290000A000CC000003021000421803C03600083
+:1072A000AC6410080000000000052980AC65100CDB
+:1072B0000000000003E000088C62100C27BDFFE80E
+:1072C0000080282124040038AFBF00140E0009D527
+:1072D000AFB0001024040E00AF4400283C10000C96
+:1072E00003502021240500100E000CC000003021A6
+:1072F00003501021AC400000AC40000424040038CE
+:107300008FBF00148FB0001024053FFF27BD001869
+:107310000A0009D58C430000000421803C03600072
+:10732000AC641008000000008C62100C03E0000840
+:107330000002118227BDFFC8AFB400208F940068FF
+:10734000AFBE0030AFB7002CAFB600280000B821A8
+:107350000080B021241E00C0AFBF0034AFB50024B0
+:10736000AFB3001CAFB20018AFB10014AFB0001043
+:107370000A000A12AFA5003C504000018F9400683B
+:1073800027DEFFFF13C00028269400048E92000021
+:107390003C03080024635D801240FFF70283102B3A
+:1073A0003C04080024845A84028410230002A8C0EC
+:1073B000000098210A000A212411000100118840D0
+:1073C000122000260000000002B380210251282470
+:1073D0000200202110A0FFF9267300010E0009DE33
+:1073E000000000000016684032EC000101AC2021D2
+:1073F0000E0009D5020028218F89009426F700018C
+:107400008FA6003C3AEB0001316A00012528FFFFFE
+:107410000011382702CAB021AF88009416E6FFE7B2
+:1074200002479024AE92000002E010218FBF00348A
+:107430008FBE00308FB7002C8FB600288FB5002488
+:107440008FB400208FB3001C8FB200188FB10014CE
+:107450008FB0001003E0000827BD00383C0E080084
+:1074600025CE5D80028E102B0A000A0DAE92000020
+:1074700027BDFFD8AFB10014AFB00010AFBF0020E0
+:10748000AFB3001CAFB2001800A0882110A0001FED
+:10749000000480403C13080026735A840A000A5AEC
+:1074A0002412000112200019261000010E0009F517
+:1074B00002002021000231422444FFA0000618806F
+:1074C0003045001F2C8217A1007318212631FFFFC1
+:1074D0001040FFF400B230048C690000020020214B
+:1074E00024053FFF012640241500FFEE0126382524
+:1074F0000E0009D5AC6700008F8A009426100001A9
+:10750000254700011620FFE9AF8700948FBF0020B8
+:107510008FB3001C8FB200188FB100148FB0001011
+:1075200003E0000827BD00288F85009C00805821BB
+:107530000000402100004821240A001F3C0C0800E4
+:10754000258C5DFC3C0D080025AD5D848CA60000FB
+:1075500050C000140000402100AD1023000238C0CC
+:10756000240300010A000A930000202115000003F3
+:1075700000E410212448202400004821252900018E
+:10758000512B00132506DFDC106000062484000167
+:1075900000C3702415C0FFF5000318400A000A91CB
+:1075A0000000402110AC002624A300040060282124
+:1075B000254AFFFF1540FFE5AF85009C512B0004D5
+:1075C0002506DFDC0000402103E000080100102157
+:1075D0000006614230C5001F000C50803C070800C7
+:1075E00024E75D8424040001014730211120000FAD
+:1075F00000A420043C05080024A55E0014800005BA
+:107600002529FFFF24C6000410C50011000000005A
+:10761000240400018CCF00000004C0270004204097
+:1076200001F868241520FFF5ACCD00008F99007893
+:1076300001001021032B482303E00008AF890078E4
+:107640003C05080024A55D840A000A9B0000402137
+:107650003C06080024C65D840A000AB42404000124
+:10766000308800FF240200021102000A24030003F4
+:107670001103005C8F8900A4240400041104005F3E
+:1076800024050005110500670000182103E000082B
+:10769000006010218F8900483C0C0800258C5EC0DA
+:1076A0003C04080024845F40240300201060000F85
+:1076B00000005821240D0002240E00033C0F080096
+:1076C00025EF5EC08D27000014E0000B30F9FFFFAE
+:1076D000252900040124C02B53000001018048210A
+:1076E0002463FFFF5460FFF88D270000016018211C
+:1076F00003E0000800601021132000323C0500FF69
+:1077000030E200FF004030211040004200005021D4
+:1077100024050001000020210005C84000A6C02467
+:1077200017000003332500FF14A0FFFB2484000191
+:10773000012CC023001828C000AA6021008C502111
+:107740003144001F240C0001008C18040003102792
+:1077500000E23024110D0041AD260000110E004C56
+:10776000000A1840110D00368F87006C510E00562C
+:107770008F8C0060240D0004110D005A8F8E008440
+:10778000240E0005150EFFDA01601821240B1430B9
+:1077900011400006000018218F8400A0246300011E
+:1077A000006A402B1500FFFD016458218F8A00807C
+:1077B000AF89008C016018212549FFFF0A000AEB00
+:1077C000AF89008000E52024000736021080FFD03A
+:1077D000240A001800075402314600FF0A000AF389
+:1077E000240A00103C0C0800258C5E803C04080034
+:1077F00024845EC00A000ADA240300103C0C08004E
+:10780000258C5E003C04080024845E800A000AD9AE
+:107810008F89009000071A02306600FF0A000AF301
+:10782000240A00088F89008C3C0C0800258C5F40DE
+:107830003C04080024845F500A000ADA2403000490
+:10784000000A4080250B003024E6FFFF016018216C
+:10785000AF8900480A000AEBAF86006C000AC982B3
+:10786000001978803C07080024E75E8001E72021AA
+:10787000000A18428C8F00003079001F032C380456
+:107880000007C02701F860240A000B08AC8C000038
+:10789000000331420006288000AF28213062001F1B
+:1078A0008CB8000024630001004CC804000321428E
+:1078B000001938270004108003073024004F2021CE
+:1078C0000A000B4CACA60000000A68C025AB0032D1
+:1078D000258AFFFF01601821AF8900A40A000AEB86
+:1078E000AF8A0060254B1030AF89009001601821ED
+:1078F00025C9FFFF0A000AEBAF8900843086000724
+:107900002CC2000610400014000000000006408059
+:107910003C030800246357B0010338218CE40000C5
+:1079200000800008000000002409000310A9000ED8
+:1079300000000000240A000510AA000B000000004F
+:10794000240B000110AB0008000000008F8C00A089
+:1079500010AC00050000000003E00008000010214A
+:107960000A000A7900A020210A000AC700C02021CD
+:1079700027BDFFE8308400FF240300021083000BC2
+:10798000AFBF0010240600031086003A240800044C
+:1079900010880068240E0005108E007F2CAF143074
+:1079A0008FBF001003E0000827BD00182CA2003094
+:1079B0001440FFFC8FBF001024A5FFD0000531C28A
+:1079C000000668803C07080024E75EC001A730215C
+:1079D0008CC900000005288230AC001F240B000178
+:1079E000018B50048F840048012A4025ACC8000058
+:1079F0008C83000050600001AF8600488F98006CB7
+:107A000030AE000124A6FFFF270F000115C00002C1
+:107A1000AF8F006C24A600010006414200082080C0
+:107A2000008718218C79000030C2001F2406000155
+:107A30000046F804033F382410E0FFDA8FBF00103F
+:107A40000005C182001870803C0F080025EF5E80A1
+:107A500001CF48218D2B00000005684231A5001F91
+:107A600000A66004016C502527BD001803E0000843
+:107A7000AD2A00002CA7003014E0FFCA8FBF001011
+:107A800030B900071723FFC724A8FFCE00086A02F9
+:107A9000000D60803C0B0800256B5E80018B30215F
+:107AA0008CC40000000828C230AA001F240800016E
+:107AB000014848048F8200A400891825ACC3000047
+:107AC0008C5F000053E00001AF8600A40005704009
+:107AD000000E7942000F28803C04080024845EC018
+:107AE00000A418218C6B000025DF000131CD001FA0
+:107AF000001F514201A86004016C4825000A108053
+:107B0000AC690000004428218CA600008F9800601A
+:107B100033F9001F8FBF00100328380400C77825F1
+:107B2000270E000127BD0018ACAF000003E00008DD
+:107B3000AF8E006024A5EFD02CB804001300FF998D
+:107B40008FBF001000053142000658803C0A080033
+:107B5000254A5E00016A30218CC4000030A3001F5A
+:107B600024090001006910048F9900900082F82513
+:107B7000ACDF00008F27000050E00001AF860090CE
+:107B80008F8D00848FBF001027BD001825AC000129
+:107B900003E00008AF8C008415E0FF828FBF001067
+:107BA0008F8600A0000610400046F821001F21002B
+:107BB00003E4C8210019384024F8143000B8402BE1
+:107BC0001100FF788FBF001024A4EBD00E00021329
+:107BD00000C0282100027942000F70803C0D08008F
+:107BE00025AD5F4001CD20218C8B0000304C001F63
+:107BF00024060001018618048F89008C016350253A
+:107C0000AC8A00008D25000050A00001AF84008CDC
+:107C10008F9800808FBF001027BD00182708000133
+:107C200003E00008AF88008030A5000724030003AC
+:107C300010A3001028A2000414400008240700022A
+:107C40002403000410A300152408000510A8000F49
+:107C50008F8500A003E000080000000014A7FFFDCE
+:107C60000080282114C3FFFB240400020A000B8BB0
+:107C700000000000240900050080282110C9FFFB36
+:107C80002404000303E000080000000014C5FFF115
+:107C9000008028210A000B8B24040005240A00011F
+:107CA0000080282110CAFFF12404000403E000082A
+:107CB0000000000027BDFFE0AFB00010000581C24A
+:107CC0002603FFD024C5003F2C6223D024C6007FAA
+:107CD000AFB20018AFB10014AFBF001C309100FF6D
+:107CE000000691C2000529820200202110400008F0
+:107CF0002403FFFF0E000A4B0000000002002021B9
+:107D0000022028210E000C390240302100001821E9
+:107D10008FBF001C8FB200188FB100148FB00010FD
+:107D20000060102103E0000827BD002027BDFFD818
+:107D300024A2007FAFB3001CAFB20018000299C2AA
+:107D4000309200FF24A3003F02402021026028213E
+:107D5000AFB10014AFB00010AFBF00200E000B6E2B
+:107D60000003898200408021004020210220282138
+:107D700014400009000018218FBF00208FB3001CA1
+:107D80008FB200188FB100148FB000100060102166
+:107D900003E0000827BD00280E0009FC00000000D9
+:107DA00000402821020020211051FFF3001019C0CB
+:107DB0000E000A4B00000000020020210240282192
+:107DC0000E000C39026030218FBF00208FB3001CE1
+:107DD0008FB200188FB100148FB00010000018216E
+:107DE0000060102103E0000827BD00283084FFFF59
+:107DF00030A5FFFF1080000700001821308200012D
+:107E00001040000200042042006518211480FFFB8E
+:107E10000005284003E000080060102110C00007A2
+:107E2000000000008CA2000024C6FFFF24A500046F
+:107E3000AC82000014C0FFFB2484000403E00008AF
+:107E40000000000010A0000824A3FFFFAC86000083
+:107E500000000000000000002402FFFF2463FFFF79
+:107E60001462FFFA2484000403E00008000000000C
+:107E700030A5FFFF8F4201B80440FFFE3C076015AC
+:107E800000A730253C031000AF440180AF400184BF
+:107E9000AF46018803E00008AF4301B88F8500D0EA
+:107EA0002C864000008018218CA700840087102BAE
+:107EB00014400010000000008CA800842D06400033
+:107EC00050C0000F240340008CAA0084008A482B75
+:107ED000512000018CA3008400035A42000B208033
+:107EE0003C05080024A558000085182103E000087F
+:107EF0008C62000014C0FFF4000000002403400066
+:107F000000035A42000B20803C05080024A55800BD
+:107F10000085182103E000088C6200008F8300D0E8
+:107F2000906600D024C50001A06500D08F8500D0E8
+:107F3000906400D090A200D210440017000000000E
+:107F4000936C00788F8B00BC318A00FFA16A000C13
+:107F500025490001938700C4312200FF3048007F8B
+:107F60001107000B00026827A36200788F4E01788A
+:107F700005C0FFFE8F9900B0241800023C0F1000CE
+:107F8000AF590140A358014403E00008AF4F017806
+:107F90000A000D0931A20080A0A000D00A000CFF49
+:107FA000000000008F8700D027BDFFC8AFBF0030A2
+:107FB000AFB7002CAFB60028AFB50024AFB4002097
+:107FC000AFB3001CAFB20018AFB10014AFB00010D7
+:107FD00094E300E094E200E2104300D72405FFFFA1
+:107FE0003C047FFF3497FFFF2415FF800A000DF04B
+:107FF0003C16000E108A00D18FBF00308F9100B068
+:108000003C1808008F18005C001230C0001291402C
+:108010000311702101D57824AF4F002C94EC00E2BD
+:1080200031CD007F01BA5821318A7FFF0176482186
+:10803000000A804002091021945300003C08080007
+:108040008D0800580246C02132733FFF001319808B
+:10805000010320210224282130BF007F03FAC82118
+:1080600000B5A024AF54002C0336A0218E87001049
+:108070008E8F003003785821256D008800EF702323
+:10808000240C0002AE8E0010AF8D00ACA16C0088F5
+:10809000976A003C8E8400308F9100AC0E000CD6A5
+:1080A0003150FFFF00024B80020940253C02420094
+:1080B00001022025AE2400048E8300048F8D00ACC5
+:1080C0008E860000240E0008ADA3001CADA600188B
+:1080D000ADA0000CADA00010929F000A33F900FF84
+:1080E000A5B90014968500083C1F000CA5A5001634
+:1080F0009298000A331100FFA5B100209690000865
+:1081000024180005A5B00022ADA00024928F000B1A
+:108110002410C00031E700FFA5A70002A1AE0001B6
+:108120008E8C00308F8B00AC8F8400B0AD6C00085B
+:108130003C0A08008D4A005401444821013540247E
+:10814000AF4800283C0208008C4200540044302113
+:1081500030C3007F007AC821033F282102458821CF
+:10816000AF9100BCAF8500C0A23800008F8A00BC70
+:108170002403FFBF2418FFDF954F000201F03824CD
+:1081800000F37025A54E0002914D000231AC003F76
+:10819000358B0040A14B00028F8600BC8F8900D038
+:1081A000ACC000048D28007C3C098000ACC80008ED
+:1081B00090C4000D3082007FA0C2000D8F8500BCEE
+:1081C00090BF000D03E3C824A0B9000D8F9100BC3F
+:1081D0009233000D02789024A232000D8E9000346C
+:1081E0008F8B00BCAD7000108E87002C8E8F0030FE
+:1081F00000EF7023AD6E0014916D001831AC007F5C
+:10820000A16C00188F9F00BC8E8A00308FE8001888
+:10821000015720240109302400C41025AFE20018C2
+:108220009283000AA3E3001C969900088F8500BC86
+:108230008F9800D0A4B9001E8E9000308E8400303C
+:108240000E0002138F0500848F8500D0000291403C
+:108250000002990090AF00BC0253882100403021F9
+:1082600031E7000210E0000302118021000290803B
+:108270000212802190B900BC3327000410E00002F4
+:108280000006F880021F80218E9800308F8B00BC82
+:1082900024068000330F0003000F702331CD00034C
+:1082A000020D6021AD6C000494A400E294AA00E2E7
+:1082B00094B000E231497FFF2522000130537FFF57
+:1082C0000206182400734025A4A800E294A400E24A
+:1082D0003C1408008E94006030917FFF123400221D
+:1082E000000000000E000CF6000000008F8700D098
+:1082F0000000282194F300E094F000E21213000F34
+:108300008FBF003090E900D090E800D1313200FFFB
+:10831000310400FF0244302B14C0FF36264A00010E
+:1083200090EE00D2264B000131CD00FF008D602180
+:10833000158BFF338F9100B08FBF00308FB7002CAB
+:108340008FB600288FB500248FB400208FB3001C97
+:108350008FB200188FB100148FB0001000A0102150
+:1083600003E0000827BD003894A300E20066402423
+:10837000A4A800E290A400E290B900E2309100FFCE
+:108380000011A1C20014F827001F39C03332007F4A
+:10839000024730250A000DE8A0A600E23084FFFF66
+:1083A00030A5FFFFAF440018AF45001C03E00008F4
+:1083B0008F42001427BDFFB8AFB000208F9000D0CF
+:1083C0003084FFFFAFA40010AFBF0044AFBE004039
+:1083D000AFB7003CAFB60038AFB50034AFB4003033
+:1083E000AFB3002CAFB20028AFB10024A7A0001893
+:1083F000920600D1920500D030C400FF30A300FFE8
+:108400000064102B10400122AFA00014920900D08C
+:108410008FB50010312800FF0088382324F4FFFFB7
+:108420000014882B0015982B02339024524001260B
+:108430008FB40014961E0012961F00108FB7001004
+:1084400003DFC823001714000019C400000224032E
+:108450000018140302E2B02A52C00001004020219B
+:108460000284282B10A0000200801821028018210D
+:1084700000033C0000071C033064FFFF2C8600094A
+:1084800014C000020060B821241700088E0A0008FA
+:10849000001769808E09000C31ABFFFF3C0C001007
+:1084A000016C402527520400AF4A0038AF9200B853
+:1084B000AF49003CAF480030000000000000000061
+:1084C00000000000000000000000000000000000AC
+:1084D00000000000000000008F4F000031EE00207F
+:1084E00011C0FFFD0017982A027110240A000E83A4
+:1084F0000000B02155E001019258000131130080C5
+:10850000126001CF012020219655001232A5FFFFF5
+:108510000E000CCBA7B500188F9000D00291A023BD
+:1085200026CD00018F9100B8000DB4000016B403F1
+:108530002638004002D7582A0014882B2405000151
+:108540000300902101711024AF9800B8AFA500146A
+:10855000104001BC8F8900B03C0C08008D8C005489
+:10856000240BFF80921E00D001895021014B28244A
+:10857000921900D0AF4500288E4700103C08080033
+:108580008D0800583C1808008F18005430E33FFF56
+:108590000003218001043021012658212402FF809C
+:1085A0000162F824920C00D0AF5F002C92480000CA
+:1085B00033D100FF333500FF0309982100117140CA
+:1085C000001578C0326D007F01CF382101BA282113
+:1085D000318300FF3164007F3C0A000C00AA88212F
+:1085E0000367F02100033140009A10213108003F59
+:1085F0003C1F000E00D1C021005F982127D90088C0
+:108600002D150008AF9100C0AF9900ACAF9800BC29
+:10861000AF9300B412A0018A00008821240E00014B
+:10862000010E4004310D005D11A0FFB2310F0002B8
+:108630008E4A00283C0300803C04FFEFAE6A000035
+:108640008E450024A260000A3488FFFFAE65000456
+:108650009247002C3C1FFF9F37FEFFFFA267000CD4
+:108660008E62000C3C180040A267000B00433025CE
+:1086700000C8C824033E88240238A825AE75000C23
+:108680008E490004AE6000183C0F00FFAE69001474
+:108690008E4D002C35EEFFFF8F8B00B001AE6024B5
+:1086A000AE6C00108E470008A660000896450012C8
+:1086B000AE6700208E42000C30B03FFF00105180AA
+:1086C000AE6200248E5E0014014B182130A400011C
+:1086D000AE7E00288E590018000331C2000443808A
+:1086E000AE79002C8E51001C00C8F821A67F001C1A
+:1086F000AE710030965800028E550020A678001EFC
+:10870000AE75003492490033313000045600000544
+:10871000925000008F8C00D08D8B007CAE6B0030AF
+:10872000925000008F8F00BCA1F00000924E0033E9
+:1087300031CD000251A00007925E00018F8900BC7C
+:108740002418FF80913100000311A825A1350000F5
+:10875000925E00018F9900BC2409FFBF240BFFDF4C
+:10876000A33E00018F9500BC92B8000D3311007F2D
+:10877000A2B1000D8F8E00BC91D0000D02097824AB
+:10878000A1CF000D8F8800BC8E6D0014910A000DE2
+:108790002DAC0001000C2940014B382400E51825C0
+:1087A000A103000D964200128F8800BC8F8700D075
+:1087B000A50200028E45000490FF00BC30A4000317
+:1087C0000004302330DE000300BE102133F9000224
+:1087D00017200002244400342444003090E200BCFE
+:1087E00000A2302430DF000417E0000224830004DC
+:1087F000008018218F8F00AC24090002AD03000413
+:10880000A1E90000924E003F8F8D00ACA1AE0001A7
+:108810008F9500AC924C003F8E440004A6AC000241
+:10882000976B003C0E000CD63170FFFF00025380A6
+:10883000020A38253C05420000E51825AEA30004D5
+:108840008F8600AC8E480038ACC800188E440034C7
+:10885000ACC4001CACC0000CACC00010A4C0001420
+:10886000A4C00016A4C00020A4C00022ACC00024F4
+:108870008E6400145080000124040001ACC4000880
+:108880000E000CF6241100010A000E768F9000D025
+:10889000920F00D2920E00D08FB5001031EB00FF86
+:1088A00031CD00FF008D6023016C50212554FFFF66
+:1088B0000014882B0015982B023390241640FEDDFF
+:1088C000000000008FB400148FBF00448FBE004032
+:1088D0003A8200018FB7003C8FB600388FB5003464
+:1088E0008FB400308FB3002C8FB200288FB10024DA
+:1088F0008FB0002003E0000827BD0048331100209E
+:10890000122000EF24150001921E00BC241F00015C
+:108910000000A82133D900011320000DAFBF001CB7
+:108920008E4400148E0800840088102B144000022E
+:10893000008030218E0600848E03006400C3A82BC3
+:1089400016A0000200C020218E0400640080A8212F
+:108950008E4700148E05006400E5302B14C0000221
+:1089600000E020218E0400640095F02313C0000471
+:108970008FAC001C240A0002AFAA001C8FAC001CA4
+:10898000028C582B156000A8000018218E4F00386B
+:108990008E6D000C3C0E0080AE6F00008E4A0034DD
+:1089A0003C10FF9F01AE5825AE6A00049246003F7E
+:1089B000360CFFFF016C38243C0500203C03FFEF20
+:1089C000A266000B00E510253468FFFF8F8700B812
+:1089D0000048F8243C04000803E4C825AE79000CE4
+:1089E0008CF80014AE60001802BE7821AE78001436
+:1089F0008CF10018AE71001C8CE90008AE690024EF
+:108A00008CEE000CAE6F002CAE600028AE6E002025
+:108A1000A6600038A660003A8CED001401B58023F2
+:108A2000021E902312400011AE72001090EA003D29
+:108A30008E6500048E640000000A310000A6C82183
+:108A4000000010210326402B0082F82103E8C021FA
+:108A5000AE790004AE78000090F1003DA271000AEA
+:108A60008F8900B895320006A67200088F9800AC76
+:108A70002419000202A02021A31900009769003CDC
+:108A80008F9200AC0E000CD63131FFFF00027B80CC
+:108A90008F8500B8022F68253C0E420001AE80256C
+:108AA000AE5000048F8400AC8CAC0038AC8C001845
+:108AB0008CAB0034AC8B001CAC80000CAC80001084
+:108AC000A4800014A4800016A4800020A4800022AA
+:108AD000AC80002490A7003FA487000212A00135BB
+:108AE0002403000153C0000290A2003D90A2003E6A
+:108AF00024480001A08800018F9F00ACAFF500085A
+:108B00008F8300D024070034906600BC30C500027B
+:108B100050A00001240700308F9200B88F8A00BC5B
+:108B2000906D00BC924B00002412C00032A50003DF
+:108B3000A14B00008F8600B88F8800BC240200047F
+:108B400090C400010045182330790003A1040001FE
+:108B50008F8A00BC8F9F00B800F53821955800021D
+:108B600097E9001200F9382103128824312F3FFFC2
+:108B7000022F7025A54E00029150000231A800047A
+:108B8000320C003F358B0040A14B000212A00002C6
+:108B90008F8500BC00E838218F8E00D0ACA7000480
+:108BA000240BFFBF8DCD007C2EA400012403FFDF2A
+:108BB000ACAD000890B0000D00044140320C007FC5
+:108BC000A0AC000D8F8600BC90CA000D014B102494
+:108BD000A0C2000D8F8700BC90E5000D00A3F82413
+:108BE00003E8C825A0F9000D8F9100B88F8D00BC57
+:108BF0008E380020ADB800108E290024ADA90014D5
+:108C00008E2F0028ADAF00188E2E002C0E000CF613
+:108C1000ADAE001C8FB0001C240C0002120C00EE44
+:108C20008F9000D08FA3001C006088211460000288
+:108C30000060A8210000A02156A0FE390291A023C7
+:108C40000014882B8FA90010960700103C1E0020EE
+:108C50000136402302C750213112FFFFA60A00103F
+:108C6000AFB20010AF5E0030000000009617001099
+:108C7000961300121277008F000000008E05000C82
+:108C80008E0B00080016698000AD7021000DC7C36F
+:108C900001CDA82B0178782101F56021AE0E000CE2
+:108CA000AE0C00088FB300100013B82B02378024DD
+:108CB0001200FF048F9000D00A000E3C000000005C
+:108CC0008E4D0038A6600008240B0003AE6D000036
+:108CD0008E500034A260000A8F9800B8AE70000475
+:108CE0003C0500809311003FA26B000C8E6F000CBE
+:108CF0003C0EFF9FA271000B01E5102535CCFFFF54
+:108D00003C03FFEF8F9200B8004C30243464FFFF27
+:108D100000C4F824AE7F000C8E590014964800124F
+:108D20008F8A00B0AE7900108E490014AE60001832
+:108D3000AE600020AE690014AE6000248E470018BB
+:108D400031093FFF0009F180AE6700288E4D000811
+:108D500003CA802131180001AE6D00308E4F000C27
+:108D60008F8C00AC001089C200185B80022B282178
+:108D7000240E0002A665001CA6600036AE6F002C13
+:108D8000A18E00009763003C8F8A00AC3C04420037
+:108D90003062FFFF00443025AD4600048F9F00B8CD
+:108DA000240700012411C0008FF30038240600348A
+:108DB000AD5300188FF90034AD59001CAD40000CC4
+:108DC000AD400010A5400014A5400016A5400020AD
+:108DD000A5400022AD400024A5550002A147000196
+:108DE0008F9E00AC8F8800B88F9200BCAFD5000872
+:108DF000910D0000A24D00008F9000B88F8B00BC39
+:108E000092180001A17800018F8400BC94850002B3
+:108E100000B1782401E97025A48E0002908C000234
+:108E20003183003FA08300028F8300D08F8400BC79
+:108E3000906200BC305300025260000124060030F2
+:108E4000AC8600048C6F007C2403FFBF02A0882145
+:108E5000AC8F0008908E000D31CC007FA08C000DEF
+:108E60008F8600BC90C2000D00432024A0C4000DDA
+:108E70008F8900BC913F000D37F90020A139000D0A
+:108E80008F8800B88F9300BC8D070020AE6700105C
+:108E90008D0A0024AE6A00148D1E0028AE7E0018D4
+:108EA0008D12002C0E000CF6AE72001C0A00103D54
+:108EB0008F9000D0960E00148E03000431CCFFFF7B
+:108EC000000C10C000622021AF44003C8E1F000443
+:108ED0008F46003C03E6C8231B20003C0000000036
+:108EE0008E0F000025E200013C05001034B500089B
+:108EF000AF420038AF550030000000000000000015
+:108F00000000000000000000000000000000000061
+:108F100000000000000000008F580000330B00200C
+:108F20001160FFFD000000008F5304003C0D002085
+:108F3000AE1300088F570404AE17000CAF4D00307D
+:108F4000000000003C0608008CC600442416000106
+:108F500010D600BD00000000961F00123C0508005E
+:108F60008CA5004000BFC821A61900129609001464
+:108F700025270001A6070014960A00143144FFFFBC
+:108F80005486FF498FB30010A60000140E000E1681
+:108F900030A5FFFF3C0408008C84002496030012D7
+:108FA0000044102300623023A60600120A00105964
+:108FB0008FB30010A08300018F8200AC2404000155
+:108FC000AC4400080A000FF08F8300D08E0200002E
+:108FD0000A0010EA3C0500108F8200C08FA7001C19
+:108FE000921800D0920B00D0920E00D0331100FFE7
+:108FF000316900FF00117940000928C001E56021B6
+:1090000031C300FF036C50210003314000C2C8216E
+:10901000255F0088AF9F00ACAF9900BCA1470088D6
+:109020009768003C03C020218F9100AC0E000CD645
+:109030003110FFFF00026B80020DC0253C0442008E
+:109040008F8D00B803045825AE2B00048DA900387D
+:109050008F8B00AC0000882100118100AD690018E1
+:109060008DAF00343C087FFF3504FFFFAD6F001C5F
+:1090700091AC003E8D65001C8D660018000C190037
+:10908000000C770200A33821020E102500E3F82B14
+:1090900000C2C821033F5021AD67001CAD6A001813
+:1090A000AD60000CAD60001091B8003E24050005D5
+:1090B00003C45024A578001495A9000403C02021FE
+:1090C000A569001691AF003EA56F002095B1000480
+:1090D000A5710022AD60002491AE003FA56E000294
+:1090E00091B0003E91AC003D01901023244300015B
+:1090F000A16300018F8600AC8F9F00BCACDE00082E
+:10910000A3E500008F9000BC8F9900B82405FFBF35
+:1091100096070002973800120247782433093FFF70
+:1091200001E98825A6110002921200022418FFDF2F
+:10913000324E003F35CD0040A20D00028F8600BCAC
+:109140008F8C00D02412FFFFACC000048D8B007CFC
+:109150003C0C8000ACCB000890C2000D3043007F77
+:10916000A0C3000D8F8700BC90FF000D03E5C8244D
+:10917000A0F9000D8F9100BC9229000D01387824D0
+:10918000A22F000D8F9000BCAE120010AE1500147F
+:10919000920E00182415FF8002AE6825A20D00185B
+:1091A0008F8500BC8F8300B88CAB0018016C102435
+:1091B000004A3025ACA600189068003EA0A8001C0C
+:1091C0008F9F00B88F8700BC8F9800D097F900045C
+:1091D000A4F9001E0E0002138F0500848F8600D0B4
+:1091E000000279400002490090D200BC01E98821C8
+:1091F000004028213255000212A0000303D1202193
+:109200000002A8800095202190CD00BC31B200045E
+:109210001240000333DF0003000540800088202156
+:10922000240600048F9E00BC00DFC8233327000300
+:1092300000875021AFCA00040E000CF6A665003866
+:109240000A0010388F9000D0961E00123C080800CB
+:109250008D080024011E9021A61200120A00105948
+:109260008FB3001027BDFFE03C1808008F18005096
+:10927000AFB00010AFBF0018AFB10014AF8400B0A2
+:1092800093710074030478212410FF8031EE007F75
+:109290003225007F01F0582401DA68213C0C000AD5
+:1092A000A38500C401AC2821AF4B002494A9001071
+:1092B0009768000690A600620080382124020030E2
+:1092C0000109202330C300F0AF8500D010620019DF
+:1092D0003090FFFF90AE0062240DFFF0240A005092
+:1092E00001AE6024318B00FF116A002F00000000E6
+:1092F00016000007241F0C00AF5F00248FB100147C
+:109300008FBF00188FB0001003E0000827BD0020B9
+:109310000E000E1C02002021241F0C00AF5F002451
+:109320008FB100148FBF00188FB0001003E0000849
+:1093300027BD002094A200E094A400E290BF011396
+:10934000008218263079FFFF33E700C014E00009DF
+:109350002F31000116000038000000005620FFE603
+:10936000241F0C000E000D18000000000A0011ED73
+:10937000241F0C001620FFDE000000000E000D1858
+:10938000000000001440FFDC241F0C001600002227
+:109390008F8300D0906901133122003FA062011336
+:1093A0000A0011ED241F0C0094AF00D48F8600D466
+:1093B00000E02821240400050E000C5C31F0FFFFC2
+:1093C0001440000524030003979100E600001821D3
+:1093D0002625FFFFA78500E68F5801B80700FFFE8E
+:1093E0003C196013AF400180241F0C00AF50018472
+:1093F000007938253C101000AF4701888FB1001468
+:10940000AF5001B8AF5F00248FB000108FBF0018BD
+:1094100003E0000827BD00200E000E1C02002021E2
+:109420005040FFB5241F0C008F8300D090690113BA
+:109430000A0012163122003F0E000E1C02002021ED
+:109440001440FFAD241F0C00122000078F8300D0B2
+:10945000906801133106003F34C20040A06201133E
+:109460000A0011ED241F0C000E000D180000000072
+:109470005040FFA1241F0C008F8300D0906801137F
+:109480003106003F0A00124634C20040AF9B00C8BC
+:1094900003E00008AF8000EC3089FFFF0009404284
+:1094A0002D020041000929801440000200095040AB
+:1094B00024080040000879400008C0C001F8582185
+:1094C000256701A800EF702125CC007F240DFF80C7
+:1094D000018D18240065302100CA282125640088E8
+:1094E000240A00883C010800AC2A004C3C0108001A
+:1094F000AC240050AF8500D43C010800AC290060CA
+:109500003C010800AC2800643C010800AC27005472
+:109510003C010800AC2300583C010800AC26005C6C
+:1095200003E0000800000000308300FF30C6FFFFAA
+:1095300030E400FF8F4201B80440FFFE00034C00FE
+:10954000012438253C08600000E820253C03100079
+:10955000AF450180AF460184AF44018803E00008B5
+:10956000AF4301B88F86001C3C09601235270010FC
+:109570008CCB00043C0C600E35850010316A00066F
+:109580002D480001ACE800C48CC40004ACA43180B8
+:109590008CC2000894C30002ACA2318403E000082E
+:1095A000A78300E43C0308008C6300508F8400E82C
+:1095B0008F86001C2402FF800064C0210302C8249F
+:1095C000AF5900288CCD00043305007F00BA782104
+:1095D0003C0E000C01EE2821ACAD00588CC80008F0
+:1095E000AF8500D03C076012ACA8005C8CCC0010AA
+:1095F00034E80010ACAC000C8CCB000CACAB000819
+:1096000094AA00143C0208008C4200442549000141
+:10961000A4A9001494A400143083FFFF1062001763
+:109620008F8400D03C0A08008D4A0040A4AA001292
+:109630008CCE0018AC8E00248CCD0014AC8D002094
+:109640008CC70018AC87002C8CCC001424060001B9
+:10965000AC8C00288D0B00BC5166001A8D0200B442
+:109660008D0200B8A482003A948F003AA48F003C87
+:10967000948800D403E000083102FFFF3C09080091
+:109680008D290024A4A000148F8400D0A4A9001266
+:109690008CCE0018AC8E00248CCD0014AC8D002034
+:1096A0008CC70018AC87002C8CCC00142406000159
+:1096B000AC8C00288D0B00BC5566FFEA8D0200B80B
+:1096C0008D0200B4A482003A948F003AA48F003C2B
+:1096D000948800D403E000083102FFFF8F86001C4D
+:1096E0003C0C08008D8C0050240BFF808CCD0008B2
+:1096F0003C03000C000D51C0018A4021010B48249D
+:10970000AF8A00E8AF49002890C700073105007F05
+:1097100000BA10210043282130E4000410800039F1
+:10972000AF8500D090CF000731EE000811C000389F
+:10973000000000008CD9000C8CC400140324C02B42
+:1097400013000030000000008CC2000CACA20064CA
+:109750008CCD00182402FFF8ACAD00688CCC001052
+:10976000ACAC00808CCB000CACAB00848CCA001C71
+:10977000ACAA007C90A900BC01224024A0A800BC97
+:1097800090C300073067000810E000048F8500D008
+:1097900090AF00BC35EE0001A0AE00BC90D9000730
+:1097A00033380001130000088F8300D08F8700D06A
+:1097B0002404003490E800BC35030002A0E300BCA0
+:1097C0008F8300D0AC6400C090C90007312600022E
+:1097D00010C0000500000000906A00BC3542000483
+:1097E000A06200BC8F8300D09065011330AD003FB4
+:1097F000A06D01138F8C00D0958B00D403E000087E
+:109800003162FFFF8CC200140A0013020000000046
+:109810000A001303ACA0006427BDFFD8AFB000104E
+:109820008F90001CAFBF0024AFB40020AFB200186F
+:10983000AFB10014AFB3001C9613000E3C07600AD2
+:109840003C1460063264FFFF369300100E00125580
+:1098500034F404108F8400D43C11600E0E00099B78
+:1098600036310010920E00153C0708008CE70060AE
+:109870003C12601231CD000FA38D00F08E0E00045B
+:109880008E0D000896080012961F00109619001AF7
+:109890009618001E960F001C310CFFFF33EBFFFFE4
+:1098A000332AFFFF3309FFFF31E6FFFF3C010800C9
+:1098B000AC2B00403C010800AC2C00243C0108000B
+:1098C000AC2A0044AE293178AE26317C92020015D4
+:1098D0009603001636520010304400FF3065FFFF3B
+:1098E0003C0608008CC60064AE243188AE4500B446
+:1098F0009208001496190018241F0001011FC004CB
+:10990000332FFFFF3C0508008CA50058AE5800B867
+:10991000AE4F00BC920C0014AF8E00D8AF8D00DCAF
+:10992000318B00FFAE4B00C0920A0015AE670048B5
+:10993000AE66004C314900FFAE4900C8AE65007C00
+:109940003C0308008C6300503C0408008C84004CED
+:109950003C0808008D0800543C0208008C42005C62
+:109960008FBF0024AE6300808FB00010AE83007400
+:109970008FB3001CAE22319CAE4200DCAE2731A07A
+:10998000AE2631A4AE24318CAE233190AE28319472
+:10999000AE253198AE870050AE860054AE8500707B
+:1099A0008FB10014AE4700E0AE4600E4AE4400CCF8
+:1099B000AE4300D0AE4800D4AE4500D88FB40020EE
+:1099C0008FB2001803E0000827BD002827BDFFE084
+:1099D000AFB10014AFBF0018241100010E000845FC
+:1099E000AFB0001010510005978400E6978300CCBB
+:1099F0000083102B144000088F8500D42407000238
+:109A00008FBF00188FB100148FB0001000E010213C
+:109A100003E0000827BD00200E000C7A2404000596
+:109A2000AF8200E81040FFF6240700020E0008494C
+:109A30008F90001C979F00E68F9900E88F8D00C8DB
+:109A400027EF0001240E0050AF590020A78F00E639
+:109A5000A1AE00003C0C08008D8C00648F8600C80D
+:109A6000240A8000000C5E00ACCB0074A4C0000689
+:109A700094C9000A241FFF803C0D000C012AC02459
+:109A8000A4D8000A90C8000A24182000011F182535
+:109A9000A0C3000A8F8700C8A0E000788F8500C8A7
+:109AA00000003821A0A000833C0208008C42005036
+:109AB0008F8400E80044782101FFC824AF590028B2
+:109AC000960B000231EE007F01DA6021018D30211A
+:109AD000A4CB00D4960A0002AF8600D03C0E00044E
+:109AE00025492401A4C900E68E080004ACC800047E
+:109AF0008E030008ACC30000A4C00010A4C0001472
+:109B0000A0C000D08F8500D02403FFBFA0A000D14B
+:109B10003C0408008C8400648F8200D0A04400D2F2
+:109B20008E1F000C8F8A00D0978F00E4AD5F001C61
+:109B30008E19001024100030AD590018A5400030D7
+:109B4000A5510054A5510056A54F0016AD4E006812
+:109B5000AD580080AD580084914D006231AC000FCB
+:109B6000358B0010A14B00628F8600D090C9006336
+:109B70003128007FA0C800638F8400D02406FFFF37
+:109B80009085006300A31024A08200638F9100D011
+:109B900000E01021923F00BC37F90001A23900BC5F
+:109BA0008F8A00D0938F00F0AD580064AD5000C094
+:109BB000914E00D3000F690031CC000F018D582564
+:109BC000A14B00D38F8500D08F8900DCACA900E8C1
+:109BD0008F8800D88FBF00188FB100148FB000108D
+:109BE00027BD0020ACA800ECA4A600D6A4A000E0ED
+:109BF000A4A000E203E000080000000027BDFFE091
+:109C0000AFB000108F90001CAFB10014AFBF0018B0
+:109C10008E1900043C1808008F180050240FFF8094
+:109C2000001989C00238702131CD007F01CF602436
+:109C300001BA50213C0B000CAF4C0028014B4021D5
+:109C4000950900D4950400D68E0700043131FFFF3A
+:109C5000AF8800D00E000913000721C08E06000453
+:109C60008F8300C8000629C0AF4500209064003EE5
+:109C700030820040144000068F8400D0341FFFFF64
+:109C8000948300D63062FFFF145F000400000000E0
+:109C9000948400D60E0008A83084FFFF8E050004CF
+:109CA000022030218FBF00188FB100148FB0001038
+:109CB0002404002200003821000529C00A0012797E
+:109CC00027BD002027BDFFE0AFB100143091FFFF9A
+:109CD000AFB00010AFBF00181220001D000080219F
+:109CE0008F86001C8CC500002403000600053F027F
+:109CF0000005140230E4000714830015304500FF0E
+:109D00002CA800061100004D000558803C0C0800EE
+:109D1000258C57C8016C50218D4900000120000896
+:109D2000000000008F8E00EC240D000111CD0059C1
+:109D300000000000260B00013170FFFF24CA002044
+:109D40000211202B014030211480FFE6AF8A001C55
+:109D5000020010218FBF00188FB100148FB00010C7
+:109D600003E0000827BD0020938700CE14E00038F0
+:109D7000240400140E001335000000008F86001C20
+:109D8000240200010A00147CAF8200EC8F8900ECF1
+:109D9000240800021128003B24040013000028219D
+:109DA00000003021240700010E001279000000009D
+:109DB0000A00147C8F86001C8F8700EC24050002AB
+:109DC00014E5FFF6240400120E0012E60000000065
+:109DD0008F8500E800403021240400120E00127923
+:109DE000000038210A00147C8F86001C8F8300EC51
+:109DF000241F0003147FFFD0260B00010E001298D1
+:109E0000000000008F8500E800403021240200029D
+:109E10002404001000003821AF8200EC0E001279FB
+:109E2000000000000A00147C8F86001C8F8F00EC5D
+:109E30002406000211E6000B0000000024040010BC
+:109E400000002821000030210A0014992407000195
+:109E5000000028210E001279000030210A00147C35
+:109E60008F86001C0E0013A2000000001440001298
+:109E70008F99001C8F86001C240200030A00147CAA
+:109E8000AF8200EC0E00142E000000000A00147CCB
+:109E90008F86001C0E0012880000000024020002C1
+:109EA0002404001400002821000030210000382183
+:109EB0000A0014B6AF8200EC0040382124040010E0
+:109EC00097380002000028210E0012793306FFFFA8
+:109ED0000A00147C8F86001C8F8400C83C077FFF1B
+:109EE00034E6FFFF8C8500742402000100A61824CC
+:109EF000AC83007403E00008A082000510A00036C7
+:109F00002CA20080274A04003C0B00052409008095
+:109F1000104000072408008030A6000F00C5402133
+:109F20002D0300811460000200A048212408008055
+:109F3000AF4B0030000000000000000000000000F7
+:109F40001100000900003821014030218C8D0000F3
+:109F500024E7000400E8602BACCD0000248400045A
+:109F60001580FFFA24C60004000000000000000075
+:109F7000000000003C0E0006010E3825AF470030FF
+:109F80000000000000000000000000008F4F0000F3
+:109F900031E800101100FFFD000000008F42003C7E
+:109FA0008F43003C0049C8210323C02B1300000449
+:109FB000000000008F4C003825860001AF460038B5
+:109FC0008F47003C00A9282300E96821AF4D003CE1
+:109FD00014A0FFCE2CA2008003E0000800000000C7
+:109FE00027BDFFD03C020002AFB100143C11000CB1
+:109FF000AF450038AFB3001CAF46003C008098214D
+:10A00000AF42003024050088AF44002803512021CE
+:10A01000AFBF0028AFB50024AFB40020AFB2001826
+:10A020000E0014EEAFB000103C1F08008FFF004C74
+:10A030003C1808008F1800642410FF8003F3A82147
+:10A0400032B9007F02B078240018A0C0033A702112
+:10A050000018914001D12021AF4F00280E0014EECE
+:10A06000025428213C0D08008DAD0050240501202C
+:10A0700001B35821316C007F01705024019A4821AE
+:10A08000013120210E0014EEAF4A00283C080800E0
+:10A090008D0800543C0508008CA50064011338218C
+:10A0A00030E6007F00F0182400DA20210091202102
+:10A0B000AF4300280E0014EE000529403C020800C2
+:10A0C0008C4200583C1008008E1000601200001CEA
+:10A0D000005388212415FF800A0015713C14000CE0
+:10A0E0003226007F0235182400DA20210240282180
+:10A0F000AF430028009420210E0014EE2610FFC06C
+:10A100001200000F023288212E05004110A0FFF43A
+:10A11000241210003226007F00109180023518248E
+:10A1200000DA202102402821AF430028009420219A
+:10A130000E0014EE000080211600FFF30232882189
+:10A140003C0B08008D6B005C240AFF802405000294
+:10A1500001734021010A4824AF4900283C0408004B
+:10A16000948400623110007F021A88213C07000CA1
+:10A170000E000CAA0227982100402821026020210D
+:10A180008FBF00288FB500248FB400208FB3001C30
+:10A190008FB200188FB100148FB000100A0014EEB7
+:10A1A00027BD00308F83001C8C6200041040000328
+:10A1B0000000000003E00008000000008C640010B4
+:0CA1C0008C6500080A0015278C66000C56
+:04A1CC00000000008F
+:10A1D0000000001B0000000F0000000A0000000843
+:10A1E000000000060000000500000005000000045B
+:10A1F0000000000400000003000000030000000352
+:10A200000000000300000003000000020000000244
+:10A210000000000200000002000000020000000236
+:10A220000000000200000002000000020000000226
+:10A230000000000200000002000000020000000216
+:10A240000000000200000001000000010000000109
+:10A2500008000F2408000D6C08000FB808001060FB
+:10A2600008000F4C08000F8C0800119408000D889E
+:10A27000080011B808000DD8080015540800151C76
+:10A2800008000D8808000D8808000D88080012409D
+:10A290000800124008000D8808000D88080014E02E
+:10A2A00008000D8808000D8808000D8808000D883A
+:10A2B000080013B408000D8808000D8808000D88F8
+:10A2C00008000D8808000D8808000D8808000D881A
+:10A2D00008000D8808000D8808000D8808000D880A
+:10A2E00008000D8808000D8808000D8808000FACD4
+:10A2F00008000D8808000D880800167808000D88F1
+:10A3000008000D8808000D8808000D8808000D88D9
+:10A3100008000D8808000D8808000D8808000D88C9
+:10A3200008000D8808000D8808000D8808000D88B9
+:10A3300008000D8808000D8808000D8808000D88A9
+:10A340000800141008000D8808000D880800133458
+:10A35000080012A408001E2C08001EFC08001F1490
+:10A3600008001F2808001F3808001E2C08001E2C9B
+:10A3700008001E2C08001ED808002E1408002E1CF1
+:10A3800008002DE408002DF008002DFC08002E0820
+:10A39000080052E8080052A8080052740800524809
+:08A3A00008005224080051E0FE
+:08A3A8000A000C840000000013
+:10A3B000000000000000000D727870362E302E3143
+:10A3C0003500000006000F0300000000000000013F
+:10A3D000000000000000000000000000000000007D
+:10A3E000000000000000000000000000000000006D
+:10A3F000000000000000000000000000000000005D
+:10A40000000000000000000000000000000000004C
+:10A41000000000000000000000000000000000003C
+:10A42000000000000000000000000000000000002C
+:10A43000000000000000000000000000000000001C
+:10A44000000000000000000000000000000000000C
+:10A4500000000000000000000000000000000000FC
+:10A4600000000000000000000000000000000000EC
+:10A4700000000000000000000000000000000000DC
+:10A4800000000000000000000000000000000000CC
+:10A4900000000000000000000000000000000000BC
+:10A4A00000000000000000000000000000000000AC
+:10A4B000000000000000000000000000000000009C
+:10A4C000000000000000000000000000000000008C
+:10A4D000000000000000000000000000000000007C
+:10A4E000000000000000000000000000000000006C
+:10A4F000000000000000000000000000000000005C
+:10A50000000000000000000000000000000000004B
+:10A51000000000000000000000000000000000003B
+:10A52000000000000000000000000000000000002B
+:10A53000000000000000000000000000000000001B
+:10A54000000000000000000000000000000000000B
+:10A5500000000000000000000000000000000000FB
+:10A5600000000000000000000000000000000000EB
+:10A5700000000000000000000000000000000000DB
+:10A5800000000000000000000000000000000000CB
+:10A5900000000000000000000000000000000000BB
+:10A5A00000000000000000000000000000000000AB
+:10A5B000000000000000000000000000000000009B
+:10A5C000000000000000000000000000000000008B
+:10A5D000000000000000000000000000000000007B
+:10A5E000000000000000000000000000000000006B
+:10A5F000000000000000000000000000000000005B
+:10A60000000000000000000000000000000000004A
+:10A61000000000000000000000000000000000003A
+:10A62000000000000000000000000000000000002A
+:10A63000000000000000000000000000000000001A
+:10A64000000000000000000000000000000000000A
+:10A6500000000000000000000000000000000000FA
+:10A6600000000000000000000000000000000000EA
+:10A6700000000000000000000000000000000000DA
+:10A6800000000000000000000000000000000000CA
+:10A6900000000000000000000000000000000000BA
+:10A6A00000000000000000000000000000000000AA
+:10A6B000000000000000000000000000000000009A
+:10A6C000000000000000000000000000000000008A
+:10A6D000000000000000000000000000000000007A
+:10A6E000000000000000000000000000000000006A
+:10A6F000000000000000000000000000000000005A
+:10A700000000000000000000000000000000000049
+:10A710000000000000000000000000000000000039
+:10A720000000000000000000000000000000000029
+:10A730000000000000000000000000000000000019
+:10A740000000000000000000000000000000000009
+:10A7500000000000000000000000000000000000F9
+:10A7600000000000000000000000000000000000E9
+:10A7700000000000000000000000000000000000D9
+:10A7800000000000000000000000000000000000C9
+:10A7900000000000000000000000000000000000B9
+:10A7A00000000000000000000000000000000000A9
+:10A7B0000000000000000000000000000000000099
+:10A7C0000000000000000000000000000000000089
+:10A7D0000000000000000000000000000000000079
+:10A7E0000000000000000000000000000000000069
+:10A7F0000000000000000000000000000000000059
+:10A800000000000000000000000000000000000048
+:10A810000000000000000000000000000000000038
+:10A820000000000000000000000000000000000028
+:10A830000000000000000000000000000000000018
+:10A840000000000000000000000000000000000008
+:10A8500000000000000000000000000000000000F8
+:10A8600000000000000000000000000000000000E8
+:10A8700000000000000000000000000000000000D8
+:10A8800000000000000000000000000000000000C8
+:10A8900000000000000000000000000000000000B8
+:10A8A00000000000000000000000000000000000A8
+:10A8B0000000000000000000000000000000000098
+:10A8C0000000000000000000000000000000000088
+:10A8D0000000000000000000000000000000000078
+:10A8E0000000000000000000000000000000000068
+:10A8F0000000000000000000000000000000000058
+:10A900000000000000000000000000000000000047
+:10A910000000000000000000000000000000000037
+:10A920000000000000000000000000000000000027
+:10A930000000000000000000000000000000000017
+:10A940000000000000000000000000000000000007
+:10A9500000000000000000000000000000000000F7
+:10A9600000000000000000000000000000000000E7
+:10A9700000000000000000000000000000000000D7
+:10A9800000000000000000000000000000000000C7
+:10A9900000000000000000000000000000000000B7
+:10A9A00000000000000000000000000000000000A7
+:10A9B0000000000000000000000000000000000097
+:10A9C0000000000000000000000000000000000087
+:10A9D0000000000000000000000000000000000077
+:10A9E0000000000000000000000000000000000067
+:10A9F0000000000000000000000000000000000057
+:10AA00000000000000000000000000000000000046
+:10AA10000000000000000000000000000000000036
+:10AA20000000000000000000000000000000000026
+:10AA30000000000000000000000000000000000016
+:10AA40000000000000000000000000000000000006
+:10AA500000000000000000000000000000000000F6
+:10AA600000000000000000000000000000000000E6
+:10AA700000000000000000000000000000000000D6
+:10AA800000000000000000000000000000000000C6
+:10AA900000000000000000000000000000000000B6
+:10AAA00000000000000000000000000000000000A6
+:10AAB0000000000000000000000000000000000096
+:10AAC0000000000000000000000000000000000086
+:10AAD0000000000000000000000000000000000076
+:10AAE0000000000000000000000000000000000066
+:10AAF0000000000000000000000000000000000056
+:10AB00000000000000000000000000000000000045
+:10AB10000000000000000000000000000000000035
+:10AB20000000000000000000000000000000000025
+:10AB30000000000000000000000000000000000015
+:10AB40000000000000000000000000000000000005
+:10AB500000000000000000000000000000000000F5
+:10AB600000000000000000000000000000000000E5
+:10AB700000000000000000000000000000000000D5
+:10AB800000000000000000000000000000000000C5
+:10AB900000000000000000000000000000000000B5
+:10ABA00000000000000000000000000000000000A5
+:10ABB0000000000000000000000000000000000095
+:10ABC0000000000000000000000000000000000085
+:10ABD0000000000000000000000000000000000075
+:10ABE0000000000000000000000000000000000065
+:10ABF0000000000000000000000000000000000055
+:10AC00000000000000000000000000000000000044
+:10AC10000000000000000000000000000000000034
+:10AC20000000000000000000000000000000000024
+:10AC30000000000000000000000000000000000014
+:10AC40000000000000000000000000000000000004
+:10AC500000000000000000000000000000000000F4
+:10AC600000000000000000000000000000000000E4
+:10AC700000000000000000000000000000000000D4
+:10AC800000000000000000000000000000000000C4
+:10AC900000000000000000000000000000000000B4
+:10ACA00000000000000000000000000000000000A4
+:10ACB0000000000000000000000000000000000094
+:10ACC0000000000000000000000000000000000084
+:10ACD0000000000000000000000000000000000074
+:10ACE0000000000000000000000000000000000064
+:10ACF0000000000000000000000000000000000054
+:10AD00000000000000000000000000000000000043
+:10AD10000000000000000000000000000000000033
+:10AD20000000000000000000000000000000000023
+:10AD30000000000000000000000000000000000013
+:10AD40000000000000000000000000000000000003
+:10AD500000000000000000000000000000000000F3
+:10AD600000000000000000000000000000000000E3
+:10AD700000000000000000000000000000000000D3
+:10AD800000000000000000000000000000000000C3
+:10AD900000000000000000000000000000000000B3
+:10ADA00000000000000000000000000000000000A3
+:10ADB0000000000000000000000000000000000093
+:10ADC0000000000000000000000000000000000083
+:10ADD0000000000000000000000000000000000073
+:10ADE0000000000000000000000000000000000063
+:10ADF0000000000000000000000000000000000053
+:10AE00000000000000000000000000000000000042
+:10AE10000000000000000000000000000000000032
+:10AE20000000000000000000000000000000000022
+:10AE30000000000000000000000000000000000012
+:10AE40000000000000000000000000000000000002
+:10AE500000000000000000000000000000000000F2
+:10AE600000000000000000000000000000000000E2
+:10AE700000000000000000000000000000000000D2
+:10AE800000000000000000000000000000000000C2
+:10AE900000000000000000000000000000000000B2
+:10AEA00000000000000000000000000000000000A2
+:10AEB0000000000000000000000000000000000092
+:10AEC0000000000000000000000000000000000082
+:10AED0000000000000000000000000000000000072
+:10AEE0000000000000000000000000000000000062
+:10AEF0000000000000000000000000000000000052
+:10AF00000000000000000000000000000000000041
+:10AF10000000000000000000000000000000000031
+:10AF20000000000000000000000000000000000021
+:10AF30000000000000000000000000000000000011
+:10AF40000000000000000000000000000000000001
+:10AF500000000000000000000000000000000000F1
+:10AF600000000000000000000000000000000000E1
+:10AF700000000000000000000000000000000000D1
+:10AF800000000000000000000000000000000000C1
+:10AF900000000000000000000000000000000000B1
+:10AFA00000000000000000000000000000000000A1
+:10AFB0000000000000000000000000000000000091
+:10AFC0000000000000000000000000000000000081
+:10AFD0000000000000000000000000000000000071
+:10AFE0000000000000000000000000000000000061
+:10AFF0000000000000000000000000000000000051
+:10B000000000000000000000000000000000000040
+:10B010000000000000000000000000000000000030
+:10B020000000000000000000000000000000000020
+:10B030000000000000000000000000000000000010
+:10B040000000000000000000000000000000000000
+:10B0500000000000000000000000000000000000F0
+:10B0600000000000000000000000000000000000E0
+:10B0700000000000000000000000000000000000D0
+:10B0800000000000000000000000000000000000C0
+:10B0900000000000000000000000000000000000B0
+:10B0A00000000000000000000000000000000000A0
+:10B0B0000000000000000000000000000000000090
+:10B0C0000000000000000000000000000000000080
+:10B0D0000000000000000000000000000000000070
+:10B0E0000000000000000000000000000000000060
+:10B0F0000000000000000000000000000000000050
+:10B10000000000000000000000000000000000003F
+:10B11000000000000000000000000000000000002F
+:10B12000000000000000000000000000000000001F
+:10B13000000000000000000000000000000000000F
+:10B1400000000000000000000000000000000000FF
+:10B1500000000000000000000000000000000000EF
+:10B1600000000000000000000000000000000000DF
+:10B1700000000000000000000000000000000000CF
+:10B1800000000000000000000000000000000000BF
+:10B1900000000000000000000000000000000000AF
+:10B1A000000000000000000000000000000000009F
+:10B1B000000000000000000000000000000000008F
+:10B1C000000000000000000000000000000000007F
+:10B1D000000000000000000000000000000000006F
+:10B1E000000000000000000000000000000000005F
+:10B1F000000000000000000000000000000000004F
+:10B20000000000000000000000000000000000003E
+:10B21000000000000000000000000000000000002E
+:10B22000000000000000000000000000000000001E
+:10B23000000000000000000000000000000000000E
+:10B2400000000000000000000000000000000000FE
+:10B2500000000000000000000000000000000000EE
+:10B2600000000000000000000000000000000000DE
+:10B2700000000000000000000000000000000000CE
+:10B2800000000000000000000000000000000000BE
+:10B2900000000000000000000000000000000000AE
+:10B2A000000000000000000000000000000000009E
+:10B2B000000000000000000000000000000000008E
+:10B2C000000000000000000000000000000000007E
+:10B2D000000000000000000000000000000000006E
+:10B2E000000000000000000000000000000000005E
+:10B2F000000000000000000000000000000000004E
+:10B30000000000000000000000000000000000003D
+:10B31000000000000000000000000000000000002D
+:10B32000000000000000000000000000000000001D
+:10B33000000000000000000000000000000000000D
+:10B3400000000000000000000000000000000000FD
+:10B3500000000000000000000000000000000000ED
+:10B3600000000000000000000000000000000000DD
+:10B3700000000000000000000000000000000000CD
+:10B3800000000000000000000000000000000000BD
+:10B3900000000000000000000000000000000000AD
+:10B3A000000000000000000000000000000000009D
+:10B3B000000000000000000000000000000000008D
+:10B3C000000000000000000000000000000000007D
+:10B3D000000000000000000000000000000000006D
+:10B3E000000000000000000000000000000000005D
+:10B3F000000000000000000000000000000000004D
+:10B40000000000000000000000000000000000003C
+:10B41000000000000000000000000000000000002C
+:10B42000000000000000000000000000000000001C
+:10B43000000000000000000000000000000000000C
+:10B4400000000000000000000000000000000000FC
+:10B4500000000000000000000000000000000000EC
+:10B4600000000000000000000000000000000000DC
+:10B4700000000000000000000000000000000000CC
+:10B4800000000000000000000000000000000000BC
+:10B4900000000000000000000000000000000000AC
+:10B4A000000000000000000000000000000000009C
+:10B4B000000000000000000000000000000000008C
+:10B4C000000000000000000000000000000000007C
+:10B4D000000000000000000000000000000000006C
+:10B4E000000000000000000000000000000000005C
+:10B4F000000000000000000000000000000000004C
+:10B50000000000000000000000000000000000003B
+:10B51000000000000000000000000000000000002B
+:10B52000000000000000000000000000000000001B
+:10B53000000000000000000000000000000000000B
+:10B5400000000000000000000000000000000000FB
+:10B5500000000000000000000000000000000000EB
+:10B5600000000000000000000000000000000000DB
+:10B5700000000000000000000000000000000000CB
+:10B5800000000000000000000000000000000000BB
+:10B5900000000000000000000000000000000000AB
+:10B5A000000000000000000000000000000000009B
+:10B5B000000000000000000000000000000000008B
+:10B5C000000000000000000000000000000000007B
+:10B5D000000000000000000000000000000000006B
+:10B5E000000000000000000000000000000000005B
+:10B5F000000000000000000000000000000000004B
+:10B60000000000000000000000000000000000003A
+:10B61000000000000000000000000000000000002A
+:10B62000000000000000000000000000000000001A
+:10B63000000000000000000000000000000000000A
+:10B6400000000000000000000000000000000000FA
+:10B6500000000000000000000000000000000000EA
+:10B6600000000000000000000000000000000000DA
+:10B6700000000000000000000000000000000000CA
+:10B6800000000000000000000000000000000000BA
+:10B6900000000000000000000000000000000000AA
+:10B6A000000000000000000000000000000000009A
+:10B6B000000000000000000000000000000000008A
+:10B6C000000000000000000000000000000000007A
+:10B6D000000000000000000000000000000000006A
+:10B6E000000000000000000000000000000000005A
+:10B6F000000000000000000000000000000000004A
+:10B700000000000000000000000000000000000039
+:10B710000000000000000000000000000000000029
+:10B720000000000000000000000000000000000019
+:10B730000000000000000000000000000000000009
+:10B7400000000000000000000000000000000000F9
+:10B7500000000000000000000000000000000000E9
+:10B7600000000000000000000000000000000000D9
+:10B7700000000000000000000000000000000000C9
+:10B7800000000000000000000000000000000000B9
+:10B7900000000000000000000000000000000000A9
+:10B7A0000000000000000000000000000000000099
+:10B7B0000000000000000000000000000000000089
+:10B7C0000000000000000000000000000000000079
+:10B7D0000000000000000000000000000000000069
+:10B7E0000000000000000000000000000000000059
+:10B7F0000000000000000000000000000000000049
+:10B800000000000000000000000000000000000038
+:10B810000000000000000000000000000000000028
+:10B820000000000000000000000000000000000018
+:10B830000000000000000000000000000000000008
+:10B8400000000000000000000000000000000000F8
+:10B8500000000000000000000000000000000000E8
+:10B8600000000000000000000000000000000000D8
+:10B8700000000000000000000000000000000000C8
+:10B8800000000000000000000000000000000000B8
+:10B8900000000000000000000000000000000000A8
+:10B8A0000000000000000000000000000000000098
+:10B8B0000000000000000000000000000000000088
+:10B8C0000000000000000000000000000000000078
+:10B8D0000000000000000000000000000000000068
+:10B8E0000000000000000000000000000000000058
+:10B8F0000000000000000000000000000000000048
+:10B900000000000000000000000000000000000037
+:10B910000000000000000000000000000000000027
+:10B920000000000000000000000000000000000017
+:10B930000000000000000000000000000000000007
+:10B9400000000000000000000000000000000000F7
+:10B9500000000000000000000000000000000000E7
+:10B9600000000000000000000000000000000000D7
+:10B9700000000000000000000000000000000000C7
+:10B9800000000000000000000000000000000000B7
+:10B9900000000000000000000000000000000000A7
+:10B9A0000000000000000000000000000000000097
+:10B9B0000000000000000000000000000000000087
+:10B9C0000000000000000000000000000000000077
+:10B9D0000000000000000000000000000000000067
+:10B9E0000000000000000000000000000000000057
+:10B9F0000000000000000000000000000000000047
+:10BA00000000000000000000000000000000000036
+:10BA10000000000000000000000000000000000026
+:10BA20000000000000000000000000000000000016
+:10BA30000000000000000000000000000000000006
+:10BA400000000000000000000000000000000000F6
+:10BA500000000000000000000000000000000000E6
+:10BA600000000000000000000000000000000000D6
+:10BA700000000000000000000000000000000000C6
+:10BA800000000000000000000000000000000000B6
+:10BA900000000000000000000000000000000000A6
+:10BAA0000000000000000000000000000000000096
+:10BAB0000000000000000000000000000000000086
+:10BAC0000000000000000000000000000000000076
+:10BAD0000000000000000000000000000000000066
+:10BAE0000000000000000000000000000000000056
+:10BAF0000000000000000000000000000000000046
+:10BB00000000000000000000000000000000000035
+:10BB10000000000000000000000000000000000025
+:10BB20000000000000000000000000000000000015
+:10BB30000000000000000000000000000000000005
+:10BB400000000000000000000000000000000000F5
+:10BB500000000000000000000000000000000000E5
+:10BB600000000000000000000000000000000000D5
+:10BB700000000000000000000000000000000000C5
+:10BB800000000000000000000000000000000000B5
+:10BB900000000000000000000000000000000000A5
+:10BBA0000000000000000000000000000000000095
+:10BBB0000000000000000000000000000000000085
+:10BBC0000000000000000000000000000000000075
+:10BBD0000000000000000000000000000000000065
+:10BBE0000000000000000000000000000000000055
+:10BBF0000000000000000000000000000000000045
+:10BC00000000000000000000000000000000000034
+:10BC10000000000000000000000000000000000024
+:10BC20000000000000000000000000000000000014
+:10BC30000000000000000000000000000000000004
+:10BC400000000000000000000000000000000000F4
+:10BC500000000000000000000000000000000000E4
+:10BC600000000000000000000000000000000000D4
+:10BC700000000000000000000000000000000000C4
+:10BC800000000000000000000000000000000000B4
+:10BC900000000000000000000000000000000000A4
+:10BCA0000000000000000000000000000000000094
+:10BCB0000000000000000000000000000000000084
+:10BCC0000000000000000000000000000000000074
+:10BCD0000000000000000000000000000000000064
+:10BCE0000000000000000000000000000000000054
+:10BCF0000000000000000000000000000000000044
+:10BD00000000000000000000000000000000000033
+:10BD10000000000000000000000000000000000023
+:10BD20000000000000000000000000000000000013
+:10BD30000000000000000000000000000000000003
+:10BD400000000000000000000000000000000000F3
+:10BD500000000000000000000000000000000000E3
+:10BD600000000000000000000000000000000000D3
+:10BD700000000000000000000000000000000000C3
+:10BD800000000000000000000000000000000000B3
+:10BD900000000000000000000000000000000000A3
+:10BDA0000000000000000000000000000000000093
+:10BDB0000000000000000000000000000000000083
+:10BDC0000000000000000000000000000000000073
+:10BDD0000000000000000000000000000000000063
+:10BDE0000000000000000000000000000000000053
+:10BDF0000000000000000000000000000000000043
+:10BE00000000000000000000000000000000000032
+:10BE10000000000000000000000000000000000022
+:10BE20000000000000000000000000000000000012
+:10BE30000000000000000000000000000000000002
+:10BE400000000000000000000000000000000000F2
+:10BE500000000000000000000000000000000000E2
+:10BE600000000000000000000000000000000000D2
+:10BE700000000000000000000000000000000000C2
+:10BE800000000000000000000000000000000000B2
+:10BE900000000000000000000000000000000000A2
+:10BEA0000000000000000000000000000000000092
+:10BEB0000000000000000000000000000000000082
+:10BEC0000000000000000000000000000000000072
+:10BED0000000000000000000000000000000000062
+:10BEE0000000000000000000000000000000000052
+:10BEF0000000000000000000000000000000000042
+:10BF00000000000000000000000000000000000031
+:10BF10000000000000000000000000000000000021
+:10BF20000000000000000000000000000000000011
+:10BF30000000000000000000000000000000000001
+:10BF400000000000000000000000000000000000F1
+:10BF500000000000000000000000000000000000E1
+:10BF600000000000000000000000000000000000D1
+:10BF700000000000000000000000000000000000C1
+:10BF800000000000000000000000000000000000B1
+:10BF900000000000000000000000000000000000A1
+:10BFA0000000000000000000000000000000000091
+:10BFB0000000000000000000000000000000000081
+:10BFC0000000000000000000000000000000000071
+:10BFD0000000000000000000000000000000000061
+:10BFE0000000000000000000000000000000000051
+:10BFF0000000000000000000000000000000000041
+:10C000000000000000000000000000000000000030
+:10C010000000000000000000000000000000000020
+:10C020000000000000000000000000000000000010
+:10C030000000000000000000000000000000000000
+:10C0400000000000000000000000000000000000F0
+:10C0500000000000000000000000000000000000E0
+:10C0600000000000000000000000000000000000D0
+:10C0700000000000000000000000000000000000C0
+:10C0800000000000000000000000000000000000B0
+:10C0900000000000000000000000000000000000A0
+:10C0A0000000000000000000000000000000000090
+:10C0B0000000000000000000000000000000000080
+:10C0C0000000000000000000000000000000000070
+:10C0D0000000000000000000000000000000000060
+:10C0E0000000000000000000000000000000000050
+:10C0F0000000000000000000000000000000000040
+:10C10000000000000000000000000000000000002F
+:10C11000000000000000000000000000000000001F
+:10C12000000000000000000000000000000000000F
+:10C1300000000000000000000000000000000000FF
+:10C1400000000000000000000000000000000000EF
+:10C1500000000000000000000000000000000000DF
+:10C1600000000000000000000000000000000000CF
+:10C1700000000000000000000000000000000000BF
+:10C1800000000000000000000000000000000000AF
+:10C19000000000000000000000000000000000009F
+:10C1A000000000000000000000000000000000008F
+:10C1B000000000000000000000000000000000007F
+:10C1C000000000000000000000000000000000006F
+:10C1D000000000000000000000000000000000005F
+:10C1E000000000000000000000000000000000004F
+:10C1F000000000000000000000000000000000003F
+:10C20000000000000000000000000000000000002E
+:10C21000000000000000000000000000000000001E
+:10C22000000000000000000000000000000000000E
+:10C2300000000000000000000000000000000000FE
+:10C2400000000000000000000000000000000000EE
+:10C2500000000000000000000000000000000000DE
+:10C2600000000000000000000000000000000000CE
+:10C2700000000000000000000000000000000000BE
+:10C2800000000000000000000000000000000000AE
+:10C29000000000000000000000000000000000009E
+:10C2A000000000000000000000000000000000008E
+:10C2B000000000000000000000000000000000007E
+:10C2C000000000000000000000000000000000006E
+:10C2D000000000000000000000000000000000005E
+:10C2E000000000000000000000000000000000004E
+:10C2F000000000000000000000000000000000003E
+:10C30000000000000000000000000000000000002D
+:10C31000000000000000000000000000000000001D
+:10C32000000000000000000000000000000000000D
+:10C3300000000000000000000000000000000000FD
+:10C3400000000000000000000000000000000000ED
+:10C3500000000000000000000000000000000000DD
+:10C3600000000000000000000000000000000000CD
+:10C3700000000000000000000000000000000000BD
+:10C3800000000000000000000000000000000000AD
+:10C39000000000000000000000000000000000009D
+:10C3A000000000000000000000000000000000008D
+:10C3B000000000000000000000000000000000007D
+:10C3C000000000000000000000000000000000006D
+:10C3D000000000000000000000000000000000005D
+:10C3E000000000000000000000000000000000004D
+:10C3F000000000000000000000000000000000003D
+:10C40000000000000000000000000000000000002C
+:10C41000000000000000000000000000000000001C
+:10C42000000000000000000000000000000000000C
+:10C4300000000000000000000000000000000000FC
+:10C4400000000000000000000000000000000000EC
+:10C4500000000000000000000000000000000000DC
+:10C4600000000000000000000000000000000000CC
+:10C4700000000000000000000000000000000000BC
+:10C4800000000000000000000000000000000000AC
+:10C49000000000000000000000000000000000009C
+:10C4A000000000000000000000000000000000008C
+:10C4B000000000000000000000000000000000007C
+:10C4C000000000000000000000000000000000006C
+:10C4D000000000000000000000000000000000005C
+:10C4E000000000000000000000000000000000004C
+:10C4F000000000000000000000000000000000003C
+:10C50000000000000000000000000000000000002B
+:10C51000000000000000000000000000000000001B
+:10C52000000000000000000000000000000000000B
+:10C5300000000000000000000000000000000000FB
+:10C5400000000000000000000000000000000000EB
+:10C5500000000000000000000000000000000000DB
+:10C5600000000000000000000000000000000000CB
+:10C5700000000000000000000000000000000000BB
+:10C5800000000000000000000000000000000000AB
+:10C59000000000000000000000000000000000009B
+:10C5A000000000000000000000000000000000008B
+:10C5B000000000000000000000000000000000007B
+:10C5C000000000000000000000000000000000006B
+:10C5D000000000000000000000000000000000005B
+:10C5E000000000000000000000000000000000004B
+:10C5F000000000000000000000000000000000003B
+:10C60000000000000000000000000000000000002A
+:10C61000000000000000000000000000000000001A
+:10C62000000000000000000000000000000000000A
+:10C6300000000000000000000000000000000000FA
+:10C6400000000000000000000000000000000000EA
+:10C6500000000000000000000000000000000000DA
+:10C6600000000000000000000000000000000000CA
+:10C6700000000000000000000000000000000000BA
+:10C6800000000000000000000000000000000000AA
+:10C69000000000000000000000000000000000009A
+:10C6A000000000000000000000000000000000008A
+:10C6B000000000000000000000000000000000007A
+:10C6C000000000000000000000000000000000006A
+:10C6D000000000000000000000000000000000005A
+:10C6E000000000000000000000000000000000004A
+:10C6F000000000000000000000000000000000003A
+:10C700000000000000000000000000000000000029
+:10C710000000000000000000000000000000000019
+:10C720000000000000000000000000000000000009
+:10C7300000000000000000000000000000000000F9
+:10C7400000000000000000000000000000000000E9
+:10C7500000000000000000000000000000000000D9
+:10C7600000000000000000000000000000000000C9
+:10C7700000000000000000000000000000000000B9
+:10C7800000000000000000000000000000000000A9
+:10C790000000000000000000000000000000000099
+:10C7A0000000000000000000000000000000000089
+:10C7B0000000000000000000000000000000000079
+:10C7C0000000000000000000000000000000000069
+:10C7D0000000000000000000000000000000000059
+:10C7E0000000000000000000000000000000000049
+:10C7F0000000000000000000000000000000000039
+:10C800000000000000000000000000000000000028
+:10C810000000000000000000000000000000000018
+:10C820000000000000000000000000000000000008
+:10C8300000000000000000000000000000000000F8
+:10C8400000000000000000000000000000000000E8
+:10C8500000000000000000000000000000000000D8
+:10C8600000000000000000000000000000000000C8
+:10C8700000000000000000000000000000000000B8
+:10C8800000000000000000000000000000000000A8
+:10C890000000000000000000000000000000000098
+:10C8A0000000000000000000000000000000000088
+:10C8B0000000000000000000000000000000000078
+:10C8C0000000000000000000000000000000000068
+:10C8D0000000000000000000000000000000000058
+:10C8E0000000000000000000000000000000000048
+:10C8F0000000000000000000000000000000000038
+:10C900000000000000000000000000000000000027
+:10C910000000000000000000000000000000000017
+:10C920000000000000000000000000000000000007
+:10C9300000000000000000000000000000000000F7
+:10C9400000000000000000000000000000000000E7
+:10C9500000000000000000000000000000000000D7
+:10C9600000000000000000000000000000000000C7
+:10C9700000000000000000000000000000000000B7
+:10C9800000000000000000000000000000000000A7
+:10C990000000000000000000000000000000000097
+:10C9A0000000000000000000000000000000000087
+:10C9B0000000000000000000000000000000000077
+:10C9C0000000000000000000000000000000000067
+:10C9D0000000000000000000000000000000000057
+:10C9E0000000000000000000000000000000000047
+:10C9F0000000000000000000000000000000000037
+:10CA00000000000000000000000000000000000026
+:10CA10000000000000000000000000000000000016
+:10CA20000000000000000000000000000000000006
+:10CA300000000000000000000000000000000000F6
+:10CA400000000000000000000000000000000000E6
+:10CA500000000000000000000000000000000000D6
+:10CA600000000000000000000000000000000000C6
+:10CA700000000000000000000000000000000000B6
+:10CA800000000000000000000000000000000000A6
+:10CA90000000000000000000000000000000000096
+:10CAA0000000000000000000000000000000000086
+:10CAB0000000000000000000000000000000000076
+:10CAC0000000000000000000000000000000000066
+:10CAD0000000000000000000000000000000000056
+:10CAE0000000000000000000000000000000000046
+:10CAF0000000000000000000000000000000000036
+:10CB00000000000000000000000000000000000025
+:10CB10000000000000000000000000000000000015
+:10CB20000000000000000000000000000000000005
+:10CB300000000000000000000000000000000000F5
+:10CB400000000000000000000000000000000000E5
+:10CB500000000000000000000000000000000000D5
+:10CB600000000000000000000000000000000000C5
+:10CB700000000000000000000000000000000000B5
+:10CB800000000000000000000000000000000000A5
+:10CB90000000000000000000000000000000000095
+:10CBA0000000000000000000000000000000000085
+:10CBB0000000000000000000000000000000000075
+:10CBC0000000000000000000000000000000000065
+:10CBD0000000000000000000000000000000000055
+:10CBE0000000000000000000000000000000000045
+:10CBF0000000000000000000000000000000000035
+:10CC00000000000000000000000000000000000024
+:10CC10000000000000000000000000000000000014
+:10CC20000000000000000000000000000000000004
+:10CC300000000000000000000000000000000000F4
+:10CC400000000000000000000000000000000000E4
+:10CC500000000000000000000000000000000000D4
+:10CC600000000000000000000000000000000000C4
+:10CC700000000000000000000000000000000000B4
+:10CC800000000000000000000000000000000000A4
+:10CC90000000000000000000000000000000000094
+:10CCA0000000000000000000000000000000000084
+:10CCB0000000000000000000000000000000000074
+:10CCC0000000000000000000000000000000000064
+:10CCD0000000000000000000000000000000000054
+:10CCE0000000000000000000000000000000000044
+:10CCF0000000000000000000000000000000000034
+:10CD00000000000000000000000000000000000023
+:10CD10000000000000000000000000000000000013
+:10CD20000000000000000000000000000000000003
+:10CD300000000000000000000000000000000000F3
+:10CD400000000000000000000000000000000000E3
+:10CD500000000000000000000000000000000000D3
+:10CD600000000000000000000000000000000000C3
+:10CD700000000000000000000000000000000000B3
+:10CD800000000000000000000000000000000000A3
+:10CD90000000000000000000000000000000000093
+:10CDA0000000000000000000000000000000000083
+:10CDB0000000000000000000000000000000000073
+:10CDC0000000000000000000000000000000000063
+:10CDD0000000000000000000000000000000000053
+:10CDE0000000000000000000000000000000000043
+:10CDF0000000000000000000000000000000000033
+:10CE00000000000000000000000000000000000022
+:10CE10000000000000000000000000000000000012
+:10CE20000000000000000000000000000000000002
+:10CE300000000000000000000000000000000000F2
+:10CE400000000000000000000000000000000000E2
+:10CE500000000000000000000000000000000000D2
+:10CE600000000000000000000000000000000000C2
+:10CE700000000000000000000000000000000000B2
+:10CE800000000000000000000000000000000000A2
+:10CE90000000000000000000000000000000000092
+:10CEA0000000000000000000000000000000000082
+:10CEB0000000000000000000000000000000000072
+:10CEC0000000000000000000000000000000000062
+:10CED0000000000000000000000000000000000052
+:10CEE0000000000000000000000000000000000042
+:10CEF0000000000000000000000000000000000032
+:10CF00000000000000000000000000000000000021
+:10CF10000000000000000000000000000000000011
+:10CF20000000000000000000000000000000000001
+:10CF300000000000000000000000000000000000F1
+:10CF400000000000000000000000000000000000E1
+:10CF500000000000000000000000000000000000D1
+:10CF600000000000000000000000000000000000C1
+:10CF700000000000000000000000000000000000B1
+:10CF800000000000000000000000000000000000A1
+:10CF90000000000000000000000000000000000091
+:10CFA0000000000000000000000000000000000081
+:10CFB0000000000000000000000000000000000071
+:10CFC0000000000000000000000000000000000061
+:10CFD0000000000000000000000000000000000051
+:10CFE0000000000000000000000000000000000041
+:10CFF0000000000000000000000000000000000031
+:10D000000000000000000000000000000000000020
+:10D010000000000000000000000000000000000010
+:10D020000000000000000000000000000000000000
+:10D0300000000000000000000000000000000000F0
+:10D0400000000000000000000000000000000000E0
+:10D0500000000000000000000000000000000000D0
+:10D0600000000000000000000000000000000000C0
+:10D0700000000000000000000000000000000000B0
+:10D0800000000000000000000000000000000000A0
+:10D090000000000000000000000000000000000090
+:10D0A0000000000000000000000000000000000080
+:10D0B0000000000000000000000000000000000070
+:10D0C0000000000000000000000000000000000060
+:10D0D0000000000000000000000000000000000050
+:10D0E0000000000000000000000000000000000040
+:10D0F0000000000000000000000000000000000030
+:10D10000000000000000000000000000000000001F
+:10D11000000000000000000000000000000000000F
+:10D1200000000000000000000000000000000000FF
+:10D1300000000000000000000000000000000000EF
+:10D1400000000000000000000000000000000000DF
+:10D1500000000000000000000000000000000000CF
+:10D1600000000000000000000000000000000000BF
+:10D1700000000000000000000000000000000000AF
+:10D18000000000000000000000000000000000009F
+:10D19000000000000000000000000000000000008F
+:10D1A000000000000000000000000000000000007F
+:10D1B000000000000000000000000000000000006F
+:10D1C000000000000000000000000000000000005F
+:10D1D000000000000000000000000000000000004F
+:10D1E000000000000000000000000000000000003F
+:10D1F000000000000000000000000000000000002F
+:10D20000000000000000000000000000000000001E
+:10D21000000000000000000000000000000000000E
+:10D2200000000000000000000000000000000000FE
+:10D2300000000000000000000000000000000000EE
+:10D2400000000000000000000000000000000000DE
+:10D2500000000000000000000000000000000000CE
+:10D2600000000000000000000000000000000000BE
+:10D2700000000000000000000000000000000000AE
+:10D28000000000000000000000000000000000009E
+:10D29000000000000000000000000000000000008E
+:10D2A000000000000000000000000000000000007E
+:10D2B000000000000000000000000000000000006E
+:10D2C000000000000000000000000000000000005E
+:10D2D000000000000000000000000000000000004E
+:10D2E000000000000000000000000000000000003E
+:10D2F000000000000000000000000000000000002E
+:10D30000000000000000000000000000000000001D
+:10D31000000000000000000000000000000000000D
+:10D3200000000000000000000000000000000000FD
+:10D3300000000000000000000000000000000000ED
+:10D3400000000000000000000000000000000000DD
+:10D3500000000000000000000000000000000000CD
+:10D3600000000000000000000000000000000000BD
+:10D3700000000000000000000000000000000000AD
+:10D38000000000000000000000000000000000009D
+:10D39000000000000000000000000000000000008D
+:10D3A000000000000000000000000000000000007D
+:10D3B000000000000000000000000000000000006D
+:10D3C000000000000000000000000000000000005D
+:10D3D000000000000000000000000000000000004D
+:10D3E000000000000000000000000000000000003D
+:10D3F000000000000000000000000000000000002D
+:10D40000000000000000000000000000000000001C
+:10D41000000000000000000000000000000000000C
+:10D4200000000000000000000000000000000000FC
+:10D4300000000000000000000000000000000000EC
+:10D4400000000000000000000000000000000000DC
+:10D4500000000000000000000000000000000000CC
+:10D4600000000000000000000000000000000000BC
+:10D4700000000000000000000000000000000000AC
+:10D48000000000000000000000000000000000009C
+:10D49000000000000000000000000000000000008C
+:10D4A000000000000000000000000000000000007C
+:10D4B000000000000000000000000000000000006C
+:10D4C000000000000000000000000000000000005C
+:10D4D000000000000000000000000000000000004C
+:10D4E000000000000000000000000000000000003C
+:10D4F000000000000000000000000000000000002C
+:10D50000000000000000000000000000000000001B
+:10D51000000000000000000000000000000000000B
+:10D5200000000000000000000000000000000000FB
+:10D5300000000000000000000000000000000000EB
+:10D5400000000000000000000000000000000000DB
+:10D5500000000000000000000000000000000000CB
+:10D5600000000000000000000000000000000000BB
+:10D5700000000000000000000000000000000000AB
+:10D58000000000000000000000000080000000001B
+:10D59000000000000000000000000000000000008B
+:10D5A0000000000000000000000000000000000A71
+:10D5B0000000000000000000000000001000000358
+:10D5C000000000000000000D0000000D3C020800FB
+:10D5D000244273203C030800246377ACAC40000075
+:10D5E0000043202B1480FFFD244200043C1D080052
+:10D5F00037BD7FFC03A0F0213C100800261032103C
+:10D600003C1C0800279C73200E0010FE0000000048
+:10D610000000000D30A5FFFF30C600FF274301804A
+:10D620008F4201B80440FFFE24020002AC640000F7
+:10D63000A4650008A066000AA062000B3C0210006E
+:10D64000AC67001803E00008AF4201B83C0360007B
+:10D650008C624FF80440FFFE3C020200AC644FC0F5
+:10D66000AC624FC43C02100003E00008AC624FF80B
+:10D670009482000C2486001400A0382100021302BA
+:10D68000000210800082402100C8102B104000577B
+:10D690000000000090C300002C62000950400051BF
+:10D6A00090C20001000310803C030800246372D084
+:10D6B000004310218C4200000040000800000000E0
+:10D6C00090C300012402000A1462003A0000000026
+:10D6D000010610232C42000A1440003624C6000222
+:10D6E0008CE2000034420100ACE2000090C2000075
+:10D6F00090C3000190C4000290C5000300031C0009
+:10D7000000021600004310250004220000441025EA
+:10D710000045102524C60004ACE2000490C20000BD
+:10D7200090C3000190C4000290C5000300021600DF
+:10D7300000031C00004310250004220000441025B3
+:10D740000045102524C600040A000CB8ACE200080D
+:10D7500090C30001240200041462001624C60002D3
+:10D7600090C2000090C400018CE30000000212008F
+:10D77000004410253463000424C60002ACE2000C0F
+:10D780000A000CB8ACE3000090C3000124020003BF
+:10D790001462000824C600028CE2000090C300005E
+:10D7A00024C6000134420008A0E300100A000CB8AF
+:10D7B000ACE2000003E000082402000190C3000175
+:10D7C000240200021062000224C400020100202191
+:10D7D0000A000CB8008030210A000CB824C60001F1
+:10D7E00090C200010A000CB800C2302103E000081A
+:10D7F0000000102127BDFFE8AFBF0014AFB000103C
+:10D800000E00130200808021936200052403FFFEB6
+:10D8100002002021004310248FBF00148FB000109D
+:10D82000A36200050A00130B27BD001827BDFFE8FF
+:10D83000AFB00010AFBF00140E000F3C008080217D
+:10D840009362000024030050304200FF14430004A0
+:10D8500024020100AF4201800A000D3002002021A5
+:10D86000AF400180020020218FBF00148FB0001054
+:10D870000A000FE727BD001827BDFF80AFBE007864
+:10D88000AFB70074AFB20060AFBF007CAFB600703E
+:10D89000AFB5006CAFB40068AFB30064AFB1005C6B
+:10D8A000AFB000588F5001283C0208008C4231A0D4
+:10D8B0002403FF809365003F0202102100431024DF
+:10D8C000AF4200243C0208008C4231A09364000562
+:10D8D00030B200FF020210213042007F03421821C3
+:10D8E000000420273C02000A006218213084000155
+:10D8F000AF8300140000F0210000B8211480005311
+:10D90000AFA0005093430116934401128F450104C8
+:10D91000306300FF3C020001308400FF00A2282495
+:10D92000034310210344182124564000246740007B
+:10D9300014A001CD2402000193620000304300FFD7
+:10D94000240200201062000524020050106200062C
+:10D95000000000000A000D74000000000000000D2F
+:10D960000A000D7DAFA000303C1E080027DE736C5E
+:10D970000A000D7DAFA000303C0208008C4200DCA4
+:10D98000244200013C010800AC2200DC0E00139F81
+:10D99000000000000A000F318FBF007C8F4201049D
+:10D9A0003C03002092D3000D004310240002202BE2
+:10D9B00000042140AFA400308F4301043C0200402A
+:10D9C0000062182414600002348500400080282181
+:10D9D00032620020AFA500301440000234A600805F
+:10D9E00000A0302110C0000BAFA6003093C5000886
+:10D9F0008F67004C0200202100052B0034A5008118
+:10DA000030A5F0810E000C9B30C600FF0A000F2EDF
+:10DA1000000000009362003E304200401040000FC2
+:10DA200024020004564200072402001202002021B2
+:10DA300000E028210E0013F702C030210A000F3148
+:10DA40008FBF007C16420005000000000E000D2173
+:10DA5000000020210A000F318FBF007C9743011A7C
+:10DA600096C4000E93620035326500043075FFFFE6
+:10DA700000442004AFA400548ED1000410A000156F
+:10DA80008ED400089362003E3042004010400007F0
+:10DA9000000000000E0013E0022020211040000DC5
+:10DAA000000000000A000F2E000000008F620044FA
+:10DAB000022210230440016A000000008F62004827
+:10DAC0000222102304410166240400160A000E21DC
+:10DAD0008FC200048F620048022210230440000815
+:10DAE000000000003C0208008C423100244200018A
+:10DAF0003C010800AC2231000A000F2300000000A6
+:10DB00008F62004002221023184000128F840014FC
+:10DB10003C0208008C423100327300FC0000A82156
+:10DB2000244200013C010800AC2231008F63004018
+:10DB30009482011C022318233042FFFF0043102A65
+:10DB4000504000102402000C8F6200400A000DF2C9
+:10DB5000022210239483011C9762003C0043102B87
+:10DB600010400006000000009482011C00551023A4
+:10DB7000A482011C0A000DF72402000CA480011CE1
+:10DB80002402000CAFA200308F620040005120231D
+:10DB90001880000D02A4102A144001260000000085
+:10DBA0001495000602A410233A62000130420001DD
+:10DBB000144001200000000002A410230224882148
+:10DBC0000A000E093055FFFF0000202132620002DA
+:10DBD0001040001A326200109362003E3042004052
+:10DBE000504000118FC200040E00130202002021D9
+:10DBF00024020018A362003F936200052403FFFE85
+:10DC000002002021004310240E00130BA362000524
+:10DC100024040039000028210E0013C9240600182E
+:10DC20000A000F3024020001240400170040F80904
+:10DC3000000000000A000F3024020001104001081B
+:10DC4000000000008F63004C8F620054028210239A
+:10DC50001C40010302831023044200010060A02144
+:10DC6000AFA40018AFB10010AFB50014934201206B
+:10DC70008F6500409763003C304200FF0342102153
+:10DC8000004410218FA400543063FFFF2442400061
+:10DC90000083182B8FA40030AFA20020AFA500286E
+:10DCA00000832025AFA40030AFA50024AFA0002C36
+:10DCB000AFB400349362003E30420008504000117F
+:10DCC0008FC2000002C0202127A500380E000CB230
+:10DCD000AFA000385440000B8FC200008FA2003864
+:10DCE00030420100504000078FC200008FA3003C6B
+:10DCF0008F6200600062102304430001AF63006084
+:10DD00008FC200000040F80927A400108FA2003045
+:10DD10003042000254400001327300FE9362003E24
+:10DD200030420040104000378FA200248F62005420
+:10DD30001682001A326200012402001412420010FE
+:10DD40002A42001510400006240200162402000C8E
+:10DD500012420007326200010A000E7D000000003E
+:10DD600012420005326200010A000E7D0000000030
+:10DD70000A000E782417000E0A000E7824170010EF
+:10DD80000A000E7C24170012936200232403FFBDB7
+:10DD900000431024A36200233262000110400019E6
+:10DDA0008FA200242402000C1242000E2A42000D11
+:10DDB000104000062402000E2402000A124200074E
+:10DDC0008FA200240A000E9524420001124200088E
+:10DDD0008FA200240A000E95244200010A000E932F
+:10DDE000241700082402000E16E200022417001671
+:10DDF000241700108FA2002424420001AFA20024A7
+:10DE00008FA200248FA300148F76004000431021BE
+:10DE1000AF6200408F8200149442011C1040000940
+:10DE2000000000008F6200488F6400409763003C50
+:10DE3000004410233063FFFF0043102A1040000805
+:10DE40008FA20054936400368F6300403402FFFCBD
+:10DE50000082100400621821AF6300488FA20054B2
+:10DE60008FA600300282902130C200081040000EC0
+:10DE7000000000008F6200581642000430C600FF08
+:10DE80009742011A5040000134C6001093C50008A3
+:10DE90008FA700340200202100052B0034A500804C
+:10DEA0000E000C9B30A5F0808F62004000561023BE
+:10DEB0001840001B8FA200183C0208008C423198C9
+:10DEC000304200101040000D2402000197620068EB
+:10DED0001440000A240200018F8200149442011CA5
+:10DEE0001440000624020001A76200689742007AED
+:10DEF000244200640A000EE9A7620012A762001221
+:10DF00000E001302020020219362007D2403000111
+:10DF100002002021344200010A000EE7AFA30050A6
+:10DF20001840000A000000000E0013020200202129
+:10DF30009362007D2403000102002021AFA3005062
+:10DF4000344200040E00130BA362007D9362003E76
+:10DF5000304200401440000C326200011040000AC0
+:10DF6000000000008F6300408FC2000424040018EA
+:10DF7000246300010040F809AF6300408FA2003025
+:10DF80000A000F30304200048F6200581052001017
+:10DF9000000000008F620018022210231C400008BD
+:10DFA000240400018F6200181622000900000000FE
+:10DFB0008F62001C02821023044000050000000054
+:10DFC000AF720058AFA40050AF710018AF74001CBE
+:10DFD00012E0000B8FA200500E001302020020215D
+:10DFE000A377003F0E00130B0200202102E0302136
+:10DFF000240400370E0013C9000028218FA200500E
+:10E0000010400003000000000E000CA902002021B7
+:10E0100012A00005000018218FA200303042000439
+:10E020005040001100601021240300010A000F304D
+:10E03000006010210E001302020020219362007D77
+:10E0400002002021344200040E00130BA362007D65
+:10E050000E000CA9020020210A000F30240200014A
+:10E06000AF400044240200018FBF007C8FBE0078C7
+:10E070008FB700748FB600708FB5006C8FB40068D6
+:10E080008FB300648FB200608FB1005C8FB0005816
+:10E0900003E0000827BD00808F4201B80440FFFE66
+:10E0A00024020800AF4201B803E0000800000000AD
+:10E0B0003C02000803421021944200483084FFFFD4
+:10E0C000248400123045FFFF10A0001700A4102B7D
+:10E0D0001040001624020003934201202403001A7A
+:10E0E000A343018B304200FF2446FFFE8F820000D5
+:10E0F00000A6182B3863000100021382004310248D
+:10E10000104000058F84000434820001A74601946A
+:10E1100003E00008AF8200042402FFFE0082102406
+:10E1200003E00008AF8200042402000303E00008BB
+:10E13000A342018B27BDFFE0AFB10014AFB00010C8
+:10E14000AFBF001830B0FFFF30D1FFFF8F4201B8E2
+:10E150000440FFFE00000000AF440180AF440020F7
+:10E160000E000F42020020218F8300008F840004E4
+:10E17000A750019AA750018EA74301908F830008F2
+:10E1800030828000AF4301A8A75101881040000EE3
+:10E190008F82000493420116304200FC24420004A6
+:10E1A000005A10218C4240003042FFFF144000060C
+:10E1B0008F8200043C02FFFF34427FFF0082102464
+:10E1C000AF8200048F8200042403BFFF00431024A9
+:10E1D000A74201A69743010C8F42010400031C00D3
+:10E1E0003042FFFF00621825AF4301AC3C02100033
+:10E1F000AF4201B88FBF00188FB100148FB000106C
+:10E2000003E0000827BD00208F47007093420112F1
+:10E210008F83000027BDFFF0304200FF00022882FC
+:10E2200030620100000030211040004324A40003AC
+:10E230003062400010400010306220000004108066
+:10E24000005A10218C43400024A4000400041080D4
+:10E25000AFA30000005A10218C424000AFA200047E
+:10E2600093420116304200FC005A10218C424000BB
+:10E270000A000FC0AFA200081040002F000030219C
+:10E2800000041080005A10218C43400024A4000494
+:10E2900000041080AFA30000005A10218C424000FF
+:10E2A000AFA00008AFA200048FA800080000302132
+:10E2B00000002021240A00083C090800252901004B
+:10E2C00003A41021148A000300042A001100000A8C
+:10E2D0000000000090420000248400012C83000C08
+:10E2E00000A2102100021080004910218C42000081
+:10E2F0001460FFF300C230263C0408008C84310413
+:10E300008F4200702C8300201060000900473823E2
+:10E310003C030800246331080004108000431021EE
+:10E3200024830001AC4700003C010800AC23310409
+:10E33000AF8600082406000100C0102103E0000899
+:10E3400027BD00103C0208008C42003827BDFFD0DA
+:10E35000AFB50024AFB40020AFB10014AFBF0028A8
+:10E36000AFB3001CAFB20018AFB00010000088219E
+:10E370003C15080026B50038144000022454FFFF65
+:10E380000000A0219742010E8F8400003042FFFF61
+:10E39000308340001060000A245200043C02002038
+:10E3A0000082102450400007308280008F820004D9
+:10E3B0002403BFFF008318240A0010103442100009
+:10E3C000308280001040000A3C02002000821024AD
+:10E3D000104000078F8200043C03FFFF34637FFF7F
+:10E3E0000083182434428000AF820004AF83000011
+:10E3F0000E000F980000000014400007000000000D
+:10E400009743011E9742011C3063FFFF0002140076
+:10E4100000621825AF8300089742010C8F4340002B
+:10E420003045FFFF3402FFFF1462000300000000CC
+:10E430000A001028241100208F42400030420100C1
+:10E4400054400001241100108F840000308210001D
+:10E450005040001436310001308200201440000B7F
+:10E460003C021000008210245040000E36310001A2
+:10E470003C030E003C020DFF008318243442FFFFD2
+:10E480000043102B50400007363100013C020800C9
+:10E490008C42002C244200013C010800AC22002CDC
+:10E4A000363100053C0608008CC6003454C00023F9
+:10E4B0008F8500008F820004304240005440001FCE
+:10E4C0008F8500003C021F01008210243C031000D5
+:10E4D0005443001A8F85000030A202001440001738
+:10E4E0008F8500003250FFFF363100028F4201B8A5
+:10E4F0000440FFFE00000000AF4001800200202128
+:10E500000E000F42AF4000208F8300042402BFFFA3
+:10E51000A750019A006218248F820000A750018E34
+:10E52000A7510188A74301A6A74201903C02100011
+:10E53000AF4201B80A0010F5000010213C021000A3
+:10E5400000A210241040003A0000000010C0000F8C
+:10E550000000000030A201001040000C3C0302004B
+:10E560003C020F0000A2102410430008000000002D
+:10E570008F8200080054102400551021904200049E
+:10E58000244200040A00109F000221C00000000085
+:10E59000000516023050000F3A0300022E4203EF2E
+:10E5A000384200012C6300010062182414600073DB
+:10E5B000240200013C0308008C6300D02E06000CEE
+:10E5C000386200012C42000100461024144000155E
+:10E5D000001021C02602FFFC2C4200045440001110
+:10E5E00000002021386200022C4200010046102465
+:10E5F00010400003000512420A00109F0000202175
+:10E600000010182B0043102450400006001021C0B9
+:10E61000000020213245FFFF0E000F633226FFFB72
+:10E62000001021C03245FFFF0A0010F2362600021A
+:10E630008F4240003C0308008C63002430420100FC
+:10E640001040004630620001322200043070000D9C
+:10E65000144000022413000424130002000512C217
+:10E66000384200012E4303EF3042000138630001BD
+:10E6700000431025104000033231FFFB2402FFFB52
+:10E680000202802410C000183202000130A20100F2
+:10E6900010400015320200013C020F0000A21024BD
+:10E6A0003C0302001043000F8F8200082403FFFE8A
+:10E6B00002038024005410240055102190420004CD
+:10E6C000023330252442000412000002000221C05F
+:10E6D0003226FFFF0E000F633245FFFF12000027B6
+:10E6E00000001021320200011040000D320200042F
+:10E6F0002402000112020002023330253226FFFFFD
+:10E70000000020210E000F633245FFFF2402FFFEB0
+:10E7100002028024120000190000102132020004BD
+:10E72000104000162402000124020004120200021C
+:10E73000023330253226FFFF3245FFFF0E000F6304
+:10E74000240401002402FFFB020280241200000BBB
+:10E75000000010210A0010F52402000110400007FB
+:10E76000000010213245FFFF362600020000202164
+:10E770000E000F6300000000000010218FBF002872
+:10E780008FB500248FB400208FB3001C8FB2001807
+:10E790008FB100148FB0001003E0000827BD0030D7
+:10E7A00027BDFFD0AFB000103C04600CAFBF002C01
+:10E7B000AFB60028AFB50024AFB40020AFB3001C43
+:10E7C000AFB20018AFB100148C8250002403FF7F59
+:10E7D0003C1A8000004310243442380CAC825000B4
+:10E7E000240200033C106000AF4200088E020808BB
+:10E7F0003C1B80083C010800AC2000203042FFF0A8
+:10E80000384200102C4200010E001B85AF82001818
+:10E810003C04FFFF3C020400348308063442000C31
+:10E82000AE021948AE03194C3C0560168E021980E1
+:10E830008CA300003442020000641824AE02198048
+:10E840003C0253531462000334A47C008CA20004E5
+:10E85000005020218C82007C8C830078AF820010D5
+:10E86000AF83000C8F55000032A200031040FFFD63
+:10E8700032A200011040013D32A200028F42012865
+:10E88000AF4200208F4201048F430100AF8200009D
+:10E890000E000F3CAF8300043C0208008C4200C015
+:10E8A000104000088F8400003C0208008C4200C425
+:10E8B000244200013C010800AC2200C40A00126995
+:10E8C000000000003C020010008210241440010CE3
+:10E8D0008F8300043C0208008C4200203C030800A7
+:10E8E0008C63003800008821244200013C010800AC
+:10E8F000AC2200203C16080026D600381460000226
+:10E900002474FFFF0000A0219742010E30834000D5
+:10E910003042FFFF1060000A245200043C02002035
+:10E920000082102450400007308280008F82000453
+:10E930002403BFFF008318240A0011703442100022
+:10E94000308280001040000A3C0200200082102427
+:10E95000104000078F8200043C03FFFF34637FFFF9
+:10E960000083182434428000AF820004AF8300008B
+:10E970000E000F9800000000144000070000000087
+:10E980009743011E9742011C3063FFFF00021400F1
+:10E9900000621825AF8300089742010C8F434000A6
+:10E9A0003045FFFF3402FFFF146200030000000047
+:10E9B0000A001188241100208F42400030420100DB
+:10E9C00054400001241100108F8400003082100098
+:10E9D0005040001436310001308200201440000BFA
+:10E9E0003C021000008210245040000E363100011D
+:10E9F0003C030E003C020DFF008318243442FFFF4D
+:10EA00000043102B50400007363100013C02080043
+:10EA10008C42002C244200013C010800AC22002C56
+:10EA2000363100053C0608008CC6003454C0002373
+:10EA30008F8500008F820004304240005440001F48
+:10EA40008F8500003C021F01008210243C0310004F
+:10EA50005443001A8F85000030A2020014400017B2
+:10EA60008F8500003250FFFF363100028F4201B81F
+:10EA70000440FFFE00000000AF40018002002021A2
+:10EA80000E000F42AF4000208F8300042402BFFF1E
+:10EA9000A750019A006218248F820000A750018EAF
+:10EAA000A7510188A74301A6A74201903C0210008C
+:10EAB000AF4201B80A001267000010213C021000AA
+:10EAC00000A210241040003A0000000010C0000F07
+:10EAD0000000000030A201001040000C3C030200C6
+:10EAE0003C020F0000A210241043000800000000A8
+:10EAF0008F82000800541024005610219042000418
+:10EB0000244200040A0011FF000221C0000000009E
+:10EB1000000516023050000F3A0300022E4203EFA8
+:10EB2000384200012C630001006218241460008543
+:10EB3000240200013C0308008C6300D02E06000C68
+:10EB4000386200012C4200010046102414400015D8
+:10EB5000001021C02602FFFC2C420004544000118A
+:10EB600000002021386200022C42000100461024DF
+:10EB700050400003000512420A0011FF000020214E
+:10EB80000010182B0043102450400006001021C034
+:10EB9000000020213245FFFF0E000F633226FFFBED
+:10EBA000001021C03245FFFF0A0012523626000233
+:10EBB0008F4240003C0308008C6300243042010077
+:10EBC0001040004630620001322200043070000D17
+:10EBD000144000022413000424130002000512C292
+:10EBE000384200012E4303EF304200013863000138
+:10EBF00000431025104000033231FFFB2402FFFBCD
+:10EC00000202802410C000183202000130A201006C
+:10EC100010400015320200013C020F0000A2102437
+:10EC20003C0302001043000F8F8200082403FFFE04
+:10EC30000203802400541024005610219042000446
+:10EC4000023330252442000412000002000221C0D9
+:10EC50003226FFFF0E000F633245FFFF120000391E
+:10EC600000001021320200011040000D32020004A9
+:10EC70002402000112020002023330253226FFFF77
+:10EC8000000020210E000F633245FFFF2402FFFE2B
+:10EC9000020280241200002B000010213202000426
+:10ECA0001040002824020001240200041202000285
+:10ECB000023330253226FFFF3245FFFF0E000F637F
+:10ECC000240401002402FFFB020280241200001D24
+:10ECD000000010210A0012672402000150400019B0
+:10ECE000000010213245FFFF3626000200002021DF
+:10ECF0000E000F63000000000A00126700001021E0
+:10ED00002402BFFF00621024104000080000000031
+:10ED1000240287FF00621024144000083C020060B7
+:10ED20000082102410400005000000000E000D3489
+:10ED3000000000000A001267000000000E0012C769
+:10ED400000000000104000063C0240008F430124F8
+:10ED50003C026020AC430014000000003C02400074
+:10ED6000AF4201380000000032A200021040FEBD98
+:10ED7000000000008F4201403C044000AF420020F0
+:10ED80008F4301483C027000006218241064004266
+:10ED9000000000000083102B144000063C026000BD
+:10EDA0003C022000106200073C0240000A0012C32F
+:10EDB000000000001062003C3C0240000A0012C348
+:10EDC000000000008F4501408F4601448F420148FA
+:10EDD00000021402304300FF240200041462000AFF
+:10EDE000274401808F4201B80440FFFE2402001C2A
+:10EDF000AC850000A082000B3C021000AF4201B8BD
+:10EE00000A0012C33C0240002402000914620012EE
+:10EE100000061602000229C0AF4500208F4201B84B
+:10EE20000440FFFE2402000124030003AF450180DB
+:10EE3000A343018BA740018EA740019AA7400190F0
+:10EE4000AF4001A8A7420188A74201A6AF4001AC8C
+:10EE50003C021000AF4201B88F4201B80440FFFEEF
+:10EE600000000000AC8500008F420148000214023F
+:10EE7000A482000824020002A082000B8F420148F5
+:10EE8000A48200103C021000AC860024AF4201B8FE
+:10EE90000A0012C33C0240000E00131000000000E4
+:10EEA0000A0012C33C0240000E001BBA0000000022
+:10EEB0003C024000AF420178000000000A00112F20
+:10EEC000000000008F4201003042003E144000115B
+:10EED00024020001AF4000488F420100304207C0C9
+:10EEE0001040000500000000AF40004CAF40005053
+:10EEF00003E0000824020001AF400054AF4000408E
+:10EF00008F4201003042380054400001AF400044BD
+:10EF10002402000103E00008000000008F4201B855
+:10EF20000440FFFE24020001AF440180AF40018491
+:10EF3000A7450188A342018A24020002A342018B53
+:10EF40009742014A14C00004A7420190AF4001A4B7
+:10EF50000A0012EF3C0210008F420144AF4201A4AC
+:10EF60003C021000AF4001A803E00008AF4201B826
+:10EF70008F4201B80440FFFE24020002AF4401802A
+:10EF8000AF440184A7450188A342018AA342018BB3
+:10EF90009742014AA7420190AF4001A48F42014429
+:10EFA000AF4201A83C02100003E00008AF4201B8E4
+:10EFB0003C0290003442000100822025AF44002032
+:10EFC0008F4200200440FFFE0000000003E0000824
+:10EFD000000000003C028000344200010082202535
+:10EFE00003E00008AF44002027BDFFE8AFBF0014D6
+:10EFF000AFB000108F500140934301499342014844
+:10F0000093440148306300FF304200FF00021200C9
+:10F0100000622825240200191062007630840080E6
+:10F020002862001A1040001C24020020240200085C
+:10F0300010620077286200091040000E2402000BC5
+:10F0400024020001106200342862000250400005D2
+:10F050002402000650600034020020210A00139AA6
+:10F060000000000010620030020020210A00139A04
+:10F07000000000001062003B2862000C50400002BB
+:10F080002402000E24020009106200560200202112
+:10F090000A00139A00000000106200562862002146
+:10F0A0001040000F240200382402001C1062005897
+:10F0B0002862001D104000062402001F2402001BCD
+:10F0C0001062004C000000000A00139A00000000CB
+:10F0D0001062004A020020210A00139A000000007A
+:10F0E00010620045286200391040000724020080A9
+:10F0F0002462FFCB2C420002104000450200202178
+:10F100000A00139600003021106200090000000080
+:10F110000A00139A000000001480003D0200202124
+:10F120000A0013908FBF00140A00139624060001F2
+:10F130008F4201B80440FFFE24020002A342018B6B
+:10F14000A74501889742014AA74201908F42014496
+:10F15000A74201923C021000AF4201B80A00139C82
+:10F160008FBF00149742014A14400029000000009C
+:10F1700093620005304200041440002500000000A6
+:10F180000E001302020020219362000502002021DC
+:10F19000344200040E00130BA362000593620005C5
+:10F1A0003042000414400002000000000000000D86
+:10F1B0009362000024030020304200FF1443001437
+:10F1C000000000008F4201B80440FFFE2402000549
+:10F1D000AF500180A342018B3C0210000A00139A39
+:10F1E000AF4201B88FBF00148FB000100A0012F2B6
+:10F1F00027BD00180000000D020020210000302172
+:10F200008FBF00148FB000100A0012DD27BD001858
+:10F210000000000D8FBF00148FB0001003E0000845
+:10F2200027BD001827BDFFE8AFBF00100E000F3C40
+:10F2300000000000AF4001808FBF001000002021BF
+:10F240000A000FE727BD00183084FFFF30A5FFFF3D
+:10F25000000018211080000700000000308200012B
+:10F260001040000200042042006518210A0013AB80
+:10F270000005284003E000080060102110C00006CF
+:10F2800024C6FFFF8CA2000024A50004AC8200006D
+:10F290000A0013B52484000403E000080000000005
+:10F2A00010A0000824A3FFFFAC86000000000000AF
+:10F2B000000000002402FFFF2463FFFF1462FFFA36
+:10F2C0002484000403E0000800000000308300FFF5
+:10F2D00030A500FF30C600FF274701808F4201B8EC
+:10F2E0000440FFFE000000008F420128346340000C
+:10F2F000ACE2000024020001ACE00004A4E300083A
+:10F30000A0E2000A24020002A0E2000B3C0210006E
+:10F31000A4E50010ACE00024ACE00028A4E6001254
+:10F3200003E00008AF4201B827BDFFE8AFBF0010FF
+:10F330009362003F24030012304200FF1043000D8F
+:10F34000008030218F620044008210230440000AB4
+:10F350008FBF00108F62004824040039000028216C
+:10F3600000C2102304410004240600120E0013C939
+:10F37000000000008FBF00102402000103E000081D
+:10F3800027BD001827BDFFC8AFB20030AFB1002CB9
+:10F39000AFBF0034AFB0002890C5000D00809021B1
+:10F3A00030A400101080000B00C088218CC300081E
+:10F3B0008F6200541062000730A20005144000B5AF
+:10F3C000240400010E000D21000020210A0014BBBE
+:10F3D0000040202130A200051040000930A3001297
+:10F3E000108000AC240400018E2300088F620054BA
+:10F3F000146200A98FBF00340A00142C24040038C2
+:10F4000024020012146200A324040001022020211F
+:10F4100027A500100E000CB2AFA000101040001184
+:10F42000024020218E220008AF620084AF600040BD
+:10F430000E001302000000009362007D02402021B4
+:10F44000344200200E00130BA362007D0E000CA9B5
+:10F4500002402021240400382405008D0A0014B83D
+:10F46000240600129362003E304200081040000F54
+:10F470008FA2001030420100104000078FA300143B
+:10F480008F6200600062102304430008AF630060D5
+:10F490000A00144100000000AF6000609362003E6B
+:10F4A0002403FFF700431024A362003E9362003E52
+:10F4B00030420008144000022406000300003021FE
+:10F4C00093620034936300378F640084304200FFFE
+:10F4D000306300FF006618210003188000432821D4
+:10F4E00000A4202B1080000B000000009763003C5C
+:10F4F0008F6200843063FFFF004510230062182BE9
+:10F5000014600004000000008F6200840A00145D93
+:10F51000004580239762003C3050FFFF8FA300100E
+:10F520003062000410400004000628808FA2001CF6
+:10F530000A0014650202102B2E020218504000032C
+:10F54000240202180A00146E02051023306300041E
+:10F5500010600003004510238FA2001C00451023FB
+:10F56000004080212C420080544000012410008083
+:10F570000E0013020240202124020001AF62000CA1
+:10F580009362003E001020403042007FA362003EA4
+:10F590008E22000424420001AF620040A770003CAC
+:10F5A0008F6200509623000E00431021AF62005876
+:10F5B0008F62005000441021AF62005C8E22000474
+:10F5C000AF6200188E220008AF62001C8FA20010EC
+:10F5D000304200085440000A93A20020A360003685
+:10F5E000936200362403FFDFA36200359362003E7E
+:10F5F00000431024A362003E0A0014988E220008E3
+:10F60000A36200358E220008AF62004C8F62002496
+:10F610008F63004000431021AF62004893620000F6
+:10F6200024030050304200FF144300122403FF80E3
+:10F630003C0208008C4231A00242102100431024F9
+:10F64000AF4200283C0208008C4231A08E24000802
+:10F650003C03000C024210213042007F0342102183
+:10F6600000431021AC4400D88E230008AF82001460
+:10F67000AC4300DC0E00130B0240202124040038B0
+:10F68000000028212406000A0E0013C90000000013
+:10F69000240400018FBF00348FB200308FB1002CE2
+:10F6A0008FB000280080102103E0000827BD00383B
+:10F6B00027BDFFF827420180AFA20000308A00FF7B
+:10F6C0008F4201B80440FFFE000000008F46012871
+:10F6D0003C0208008C4231A02403FF80AF86004822
+:10F6E00000C2102100431024AF4200243C02080055
+:10F6F0008C4231A08FA900008FA8000000C2102109
+:10F700003042007F034218213C02000A00621821A7
+:10F71000946400D48FA700008FA50000240200028B
+:10F72000AF830014A0A2000B8FA30000354260003D
+:10F730003084FFFFA4E200083C021000AD26000068
+:10F74000AD040004AC60002427BD0008AF4201B83E
+:10F7500003E00008240200018F88003C9382002807
+:10F760008F8300143C07080024E7777800481023B3
+:10F77000304200FF304900FC246500888F8600403D
+:10F78000304A0003112000090000202124820004D7
+:10F790008CA30000304400FF0089102AACE3000075
+:10F7A00024A500041440FFF924E7000411400009D7
+:10F7B000000020212482000190A30000304400FFBB
+:10F7C000008A102BA0E3000024A500011440FFF9DB
+:10F7D00024E7000130C20003144000048F85003C80
+:10F7E000310200031040000D0000000010A00009CD
+:10F7F000000020212482000190C30000304400FF5B
+:10F800000085102BA0E3000024C600011440FFF97E
+:10F8100024E7000103E00008000000001100FFFDE4
+:10F8200000002021248200048CC30000304400FF2B
+:10F830000088102BACE3000024C600041440FFF93C
+:10F8400024E7000403E00008000000008F83003C70
+:10F850009382002830C600FF30A500FF004310232C
+:10F86000304300FF8F8200140080382100431021B4
+:10F8700014C00002244800880083382130E20003CD
+:10F880001440000530A2000314400003306200035E
+:10F890001040000D0000000010A000090000202111
+:10F8A0002482000190E30000304400FF0085102B0B
+:10F8B000A103000024E700011440FFF9250800011E
+:10F8C00003E000080000000010A0FFFD0000202160
+:10F8D000248200048CE30000304400FF0085102BDC
+:10F8E000AD03000024E700041440FFF925080004DC
+:10F8F00003E00008000000000080482130AAFFFF5C
+:10F9000030C600FF30E7FFFF274801808F4201B873
+:10F910000440FFFE8F820048AD0200008F420124A8
+:10F92000AD0200048D220020A5070008A102000AF4
+:10F9300024020016A102000B934301208D2200082F
+:10F940008D240004306300FF004310219783003AA8
+:10F95000004410218D250024004310233C0308009F
+:10F960008C6331A08F840014A502000C246300E88E
+:10F970002402FFFFA50A000EA5030010A506001231
+:10F98000AD050018AD020024948201142403FFF792
+:10F990003042FFFFAD0200288C820118AD02002C1E
+:10F9A0003C021000AD000030AF4201B88D220020B3
+:10F9B0000043102403E00008AD2200208F820014D1
+:10F9C00030E7FFFF00804821904200D330A5FFFFC1
+:10F9D00030C600FF0002110030420F0000E238255F
+:10F9E000274801808F4201B80440FFFE8F82004803
+:10F9F000AD0200008F420124AD0200048D220020E0
+:10FA0000A5070008A102000A24020017A102000BAA
+:10FA1000934301208D2200088D240004306300FFF1
+:10FA2000004310219783003A004410218F84001472
+:10FA3000004310233C0308008C6331A0A502000C96
+:10FA4000A505000E246300E8A5030010A50600121A
+:10FA5000AD0000148D220024AD0200188C82005CE1
+:10FA6000AD02001C8C820058AD0200202402FFFF72
+:10FA7000AD020024948200E63042FFFFAD02002870
+:10FA800094820060948300BE30427FFF3063FFFFAA
+:10FA90000002120000431021AD02002C3C021000B5
+:10FAA000AD000030AF4201B8948200BE2403FFF7DE
+:10FAB00000A21021A48200BE8D2200200043102449
+:10FAC00003E00008AD220020274301808F4201B8E7
+:10FAD0000440FFFE8F8200249442001C3042FFFF4E
+:10FAE000000211C0AC62000024020019A062000BE9
+:10FAF0003C021000AC60003003E00008AF4201B8E7
+:10FB00008F87002C30C300FF8F4201B80440FFFEF6
+:10FB10008F82004834636000ACA2000093820044EE
+:10FB2000A0A200058CE20010A4A20006A4A3000875
+:10FB30008C8200202403FFF7A0A2000A2402000206
+:10FB4000A0A2000B8CE20000ACA200108CE200042A
+:10FB5000ACA200148CE2001CACA200248CE20020B9
+:10FB6000ACA200288CE2002CACA2002C8C820024D9
+:10FB7000ACA200183C021000AF4201B88C820020F9
+:10FB80000043102403E00008AC8200208F8600149C
+:10FB900027BDFFE8AFBF0014AFB0001090C20063F4
+:10FBA000304200201040000830A500FF8CC2007CCD
+:10FBB0002403FFDF24420001ACC2007C90C200633A
+:10FBC00000431024A0C2006310A000238F83001400
+:10FBD00027500180020028210E0015D6240600823D
+:10FBE0008F82001490420063304200405040001960
+:10FBF000A38000448F83002C8F4201B80440FFFE95
+:10FC00008F820048AE02000024026082A602000833
+:10FC100024020002A202000B8C620008AE02001057
+:10FC20008C62000CAE0200148C620014AE0200184C
+:10FC30008C620018AE0200248C620024AE02002800
+:10FC40008C620028AE02002C3C021000AF4201B8CA
+:10FC5000A38000448F8300148FBF00148FB0001066
+:10FC60009062006327BD00183042007FA0620063ED
+:10FC70009782003A8F86003C8F850014938300287A
+:10FC800000461023A782003AA4A000E490A40063D9
+:10FC90008F820040AF83003C2403FFBF0046102149
+:10FCA00000832024AF820040A0A400638F82001450
+:10FCB000A04000BD8F82001403E00008A44000BEF5
+:10FCC0008F8A001427BDFFE0AFB10014AFB0001061
+:10FCD0008F88003CAFBF00189389001C954200E458
+:10FCE00030D100FF0109182B0080802130AC00FFCB
+:10FCF0003047FFFF0000582114600003310600FF69
+:10FD000001203021010958239783003A0068102B05
+:10FD10001440003C000000001468000724020001A9
+:10FD20008E0200202403FFFB34E7800000431024F0
+:10FD3000AE0200202402000134E70880158200058D
+:10FD40003165FFFF0E001554020020210A001691B4
+:10FD5000020020210E001585020020218F8400481A
+:10FD6000274301808F4201B80440FFFE240200189F
+:10FD7000AC640000A062000B8F840014948200E643
+:10FD8000A46200103C021000AC600030AF4201B829
+:10FD90009482006024420001A4820060948200608A
+:10FDA0003C0308008C63318830427FFF5443000FCE
+:10FDB000020020219482006024038000004310246C
+:10FDC000A48200609082006090830060304200FF57
+:10FDD000000211C200021027000211C03063007F30
+:10FDE00000621825A0830060020020210220282143
+:10FDF0008FBF00188FB100148FB000100A0015F9E2
+:10FE000027BD0020914200632403FF80004310259A
+:10FE1000A14200639782003A3048FFFF11000020A2
+:10FE20009383001C8F840014004B1023304600FF86
+:10FE3000948300E42402EFFF0168282B0062182459
+:10FE4000A48300E414A000038E02002001005821C6
+:10FE5000000030212403FFFB34E78000004310241E
+:10FE6000AE02002024020001158200053165FFFF6B
+:10FE70000E001554020020210A0016B99783003A9B
+:10FE80000E001585020020219783003A8F82003CE6
+:10FE9000A780003A00431023AF82003C9383001CEC
+:10FEA0008F8200148FBF00188FB100148FB0001024
+:10FEB00027BD002003E00008A04300BD938200445A
+:10FEC0002403000127BDFFE8004330042C4200203A
+:10FED000AFB00010AFBF00142410FFFE10400005AB
+:10FEE000274501803C0208008C4231900A0016D65A
+:10FEF000004610243C0208008C4231940046102435
+:10FF000014400007240600848F8300142410FFFF90
+:10FF1000906200623042000F34420040A0620062F2
+:10FF20000E0015D600000000020010218FBF001443
+:10FF30008FB0001003E0000827BD00188F83002455
+:10FF400027BDFFE0AFB20018AFB10014AFB0001092
+:10FF5000AFBF001C9062000D00A0902130D100FFC7
+:10FF60003042007FA062000D8F8500148E43001880
+:10FF7000008080218CA2007C146200052402000E07
+:10FF800090A20063344200200A0016FFA0A2006382
+:10FF90000E0016C5A38200442403FFFF1043004750
+:10FFA0002404FFFF52200045000020218E43000062
+:10FFB0003C02001000621024504000043C02000883
+:10FFC000020020210A00170E2402001500621024EE
+:10FFD000504000098E450000020020212402001438
+:10FFE0000E0016C5A38200442403FFFF1043003314
+:10FFF0002404FFFF8E4500003C02000200A21024F2
+:020000040001F9
+:10000000104000163C0200048F8600248CC20014AD
+:100010008CC300108CC40014004310230044102B28
+:1000200050400005020020218E43002C8CC200109D
+:1000300010620003020020210A00173F2402001270
+:100040003C02000400A210245040001C00002021AB
+:10005000020020210A00173F2402001300A21024EE
+:10006000104000068F8300248C6200105040001363
+:10007000000020210A001739020020218C620010A4
+:10008000504000048E42002C020020210A00173F3D
+:10009000240200115040000900002021020020210C
+:1000A000240200170E0016C5A38200442403FFFF9C
+:1000B000104300022404FFFF000020218FBF001C1A
+:1000C0008FB200188FB100148FB000100080102183
+:1000D00003E0000827BD00208F83001427BDFFD850
+:1000E000AFB40020AFB3001CAFB20018AFB1001422
+:1000F000AFB00010AFBF0024906200638F91002C5E
+:100100002412FFFF3442004092250000A0620063E9
+:100110008E2200100080982130B0003F105200065F
+:100120000360A0212402000D0E0016C5A382004426
+:10013000105200542404FFFF8F8300148E220018F5
+:100140008C63007C10430007026020212402000E13
+:100150000E0016C5A38200442403FFFF104300498C
+:100160002404FFFF24040020120400048F830014E1
+:100170009062006334420020A06200638F850034E7
+:1001800010A0002000000000560400048F8200141C
+:10019000026020210A0017902402000A9683000AB8
+:1001A000944200603042FFFF144300048F8200201D
+:1001B0002404FFFD0A0017B7AF82003C3C02080090
+:1001C0008C42318C0045102B144000060260202127
+:1001D000000028210E001646240600010A0017B769
+:1001E000000020212402002D0E0016C5A382004429
+:1001F0002403FFFF104300232404FFFF0A0017B766
+:1002000000002021160400058F8400148E230014A2
+:100210002402FFFF506200180260202194820060D7
+:1002200024420001A4820060948200603C03080024
+:100230008C63318830427FFF5443000F02602021DD
+:10024000948200602403800000431024A482006094
+:100250009082006090830060304200FF000211C273
+:1002600000021027000211C03063007F00621825D1
+:10027000A0830060026020210E0015F92405000112
+:10028000000020218FBF00248FB400208FB3001CFA
+:100290008FB200188FB100148FB0001000801021B1
+:1002A00003E0000827BD00288F83001427BDFFE866
+:1002B000AFB00010AFBF0014906200638F87002CB6
+:1002C00000808021344200408CE60010A062006370
+:1002D0003C0308008C6331B030C23FFF0043102B59
+:1002E0001040004E8F8500302402FF8090A3000D47
+:1002F00000431024304200FF5040004902002021FA
+:100300000006138230480003240200025502004414
+:100310000200202194A2001C8F85001424030023D6
+:10032000A4A201148CE60000000616023042003F31
+:10033000104300103C0300838CE300188CA2007C67
+:10034000106200062402000E0E0016C5A3820044AF
+:100350002403FFFF104300382404FFFF8F830014A1
+:100360009062006334420020A06200630A0017FC20
+:100370008F83002400C31024144300078F830024BC
+:1003800090A200623042000F34420020A0A200621E
+:10039000A38800388F8300249062000D3042007FD4
+:1003A000A062000D8F83003410600018020020212D
+:1003B0008F8400308C8200100043102B1040000905
+:1003C00024020018020020210E0016C5A38200445A
+:1003D0002403FFFF104300182404FFFF0A00182421
+:1003E000000020218C820010240500010200202141
+:1003F000004310238F830024240600010E001646BC
+:10040000AC6200100A001824000020210E0015F92B
+:10041000240500010A0018240000202102002021E8
+:100420002402000D8FBF00148FB0001027BD0018EC
+:100430000A0016C5A38200448FBF00148FB00010BD
+:100440000080102103E0000827BD001827BDFFC869
+:10045000AFB20020AFBF0034AFB60030AFB5002C54
+:10046000AFB40028AFB30024AFB1001CAFB0001888
+:100470008F4601283C0308008C6331A02402FF80D2
+:10048000AF86004800C318213065007F034528214E
+:10049000006218243C02000AAF43002400A2282175
+:1004A00090A2006200809021AF850014304200FFCE
+:1004B00000021102A382003890A200BC3042000268
+:1004C0001440000224030034240300308F820014FF
+:1004D000A3830028938300388C4200C0A38000448B
+:1004E000AF82003C24020004106203148F84003C9D
+:1004F0008E440004508003118F84003C8E42001013
+:100500003083FFFFA784003A106002F7AF820040FB
+:100510008F8400142403FF80908200630062102403
+:10052000304200FF144002C79785003A9383003899
+:100530002402000230B6FFFF14620005000088218B
+:10054000938200282403FFFD0A001B11AF82003CA8
+:100550008F82003C02C2102B144002998F8400400D
+:100560000E0014EC00000000938300283C040800F7
+:1005700024847778240200341462002EAF84002C87
+:100580003C0A08008D4A77A82402FFFFAFA20010A2
+:10059000008038212405002F3C09080025297378A4
+:1005A000240800FF2406FFFF90E2000024A3FFFFC1
+:1005B0000006220200C21026304200FF0002108016
+:1005C000004910218C420000306500FF24E7000143
+:1005D00014A8FFF50082302600061027AFA20014F1
+:1005E000AFA200100000282127A7001027A60014A2
+:1005F00000C510239044000324A2000100A7182185
+:10060000304500FF2CA200041440FFF9A064000054
+:100610008FA2001011420007240200050240202191
+:100620000E0016C5A38200442403FFFF104300649C
+:100630002404FFFF3C0208009042777C1040000930
+:100640008F820014024020212402000C0E0016C5E7
+:10065000A38200442403FFFF104300592404FFFF3A
+:100660008F820014A380001C3C0308008C63777CFD
+:100670008C4400803C0200FF3442FFFF00621824DB
+:100680000083202B10800008AF830034024020211B
+:10069000240200190E0016C5A38200442403FFFFA4
+:1006A000104300472404FFFF8F87003C9782003AE5
+:1006B0008F850034AF8700200047202310A0003B27
+:1006C000A784003A8F86001430A200030002102392
+:1006D00090C300BC3050000300B0282100031882F2
+:1006E000307300010013108000A228213C03080091
+:1006F0008C6331A08F8200483084FFFF0085202B5F
+:100700000043102110800011244200888F84002CA7
+:100710001082000E3C033F013C0208008C427778B7
+:10072000004310243C0325001443000630E500FF7D
+:100730008C820000ACC200888C8200100A0018E98C
+:10074000ACC200980E001529000030219382001CD5
+:100750008F8500148F830040020238218F82003C75
+:10076000A387001C94A400E4006218218F82003447
+:1007700034841000AF83004000503021A4A400E472
+:100780001260000EAF86003C24E20004A382001C2D
+:1007900094A200E424C30004AF83003C3442200050
+:1007A000A4A200E40A001906000020218F82004064
+:1007B000AF80003C00471021AF82004000002021A4
+:1007C0002414FFFF109402092403FFFF3C080800D3
+:1007D0008D0877883C0208008C4231B03C03080049
+:1007E0009063777831043FFF0082102B1040001B8C
+:1007F0003067003F3C0208008C4231A88F830048DC
+:100800000004218000621821006418213062007FFA
+:10081000034228213C02000C00A228213C02008057
+:10082000344200013066007800C230252402FF8087
+:1008300000621024AF42002830640007AF42080471
+:100840008F8200140344202124840940AF460814F9
+:10085000AF850024AF840030AC4301189383003887
+:1008600024020003146201C72402000124020026AE
+:1008700010E201C928E200271040001324020032D0
+:100880002402002210E201C428E2002310400008E4
+:10089000240200242402002010E201B024020021DE
+:1008A00010E2013F024020210A001AF32402000B4B
+:1008B00010E201B92402002510E2001002402021BC
+:1008C0000A001AF32402000B10E201A628E200330A
+:1008D000104000062402003F2402003110E2009282
+:1008E000024020210A001AF32402000B10E2019DAD
+:1008F000024020210A001AF32402000B8F90002CE2
+:100900003C0308008C6331B08F8500308E040010EA
+:100910000000A8218CB3001430823FFF0043102B4D
+:100920008CB10020504001870240202190A3000D8F
+:100930002402FF8000431024304200FF5040018118
+:100940000240202100041382304200031440017D44
+:100950000240202194A3001C8F8200148E040028E2
+:10096000A44301148CA20010026218231064000337
+:10097000024020210A00197C2402001F8F820034CB
+:10098000006210210262102B104000088F830024A7
+:1009900002402021240200180E0016C5A382004444
+:1009A0001054016C2404FFFF8F8300248F840034D3
+:1009B0008C6200100224882100441023AC620010D5
+:1009C0008F820014AC7100208C4200680051102B03
+:1009D000104000098F830030024020212402001DB6
+:1009E0000E0016C5A38200442403FFFF10430159E3
+:1009F0002404FFFF8F8300308E0200248C630024C8
+:100A000010430007024020212402001C0E0016C5DE
+:100A1000A38200442403FFFF1043014E2404FFFF80
+:100A20008F8400248C82002424420001AC820024A4
+:100A3000123300048F8200148C4200685622000E8C
+:100A40008E0200008E0200003C0300800043102450
+:100A50001440000D2402001A024020210E0016C589
+:100A6000A38200442403FFFF1043013A2404FFFF44
+:100A70000A0019BA8E0200143C03008000431024BF
+:100A8000504000038E020014AC8000208E0200143F
+:100A90002411FFFF105100062402001B02402021F8
+:100AA0000E0016C5A38200441051012A2404FFFF42
+:100AB0008E0300003C02000100621024104000126E
+:100AC0003C020080006210241440000802402021F3
+:100AD0002402001A0E0016C5A38200442403FFFF5F
+:100AE0001043011C2404FFFF0240202102002821A2
+:100AF0000E0016E5240600012403FFFF1043011534
+:100B00002404FFFF241500018F83002402A030215C
+:100B10000240202194620036240500012442000195
+:100B20000A001AD7A46200368F90002C3C030800FC
+:100B30008C6331B08E13001032623FFF0043102BE4
+:100B4000104000898F8400302402FF809083000DC4
+:100B500000431024304200FF104000842402000DA6
+:100B60000013138230420003240300011443007F6A
+:100B70002402000D9082000D304200085440000411
+:100B80008F820034024020210A001A082402002427
+:100B9000504000048E03000C024020210A001A0875
+:100BA000240200278C82002054620006024020218B
+:100BB0008E0300088C820024506200098E0200140B
+:100BC00002402021240200200E0016C5A38200440A
+:100BD000105400712403FFFF0A001A3D8F84002483
+:100BE0002411FFFF145100048F86001402402021BD
+:100BF0000A001A38240200258E0300188CC2007CDB
+:100C0000106200032402000E0A001A38024020215C
+:100C10008E0300248C82002810620003240200212D
+:100C20000A001A38024020218E0500288C82002CF0
+:100C300010A200032402001F0A001A3802402021DB
+:100C40008E03002C14600003240200230A001A38CB
+:100C5000024020218CC200680043102B104000038A
+:100C6000240200260A001A38024020218C82001437
+:100C7000006518210043102B104000088F840024C9
+:100C800002402021240200220E0016C5A382004447
+:100C9000105100412403FFFF8F8400242403FFF739
+:100CA0009082000D00431024A082000D8F86001456
+:100CB0003C0308008C6331AC8F82004894C400E090
+:100CC0008F8500240043102130847FFF00042040E2
+:100CD000004410213043007F034320213C03000ED9
+:100CE000008320212403FF8000431024AF42002C06
+:100CF000A49300008CA2002824420001ACA200288A
+:100D00008CA2002C8E03002C00431021ACA2002CDE
+:100D10008E02002CACA200308E020014ACA2003473
+:100D200094A2003A24420001A4A2003A94C600E032
+:100D30003C0208008C4231B024C4000130837FFFA4
+:100D40001462000F008030212402800000823024D1
+:100D500030C2FFFF000213C2304200FF0002102722
+:100D60000A001A76000233C02402000D024020213E
+:100D70000E0016C5A38200440A001A7C0040182108
+:100D80008F82001402402021240500010E0015F975
+:100D9000A44600E0000018210A001B0E0060882114
+:100DA0008F90002C3C0308008C6331B08E0500103E
+:100DB00030A23FFF0043102B104000612402FF804F
+:100DC0008F8400309083000D00431024304200FFD8
+:100DD0005040005C024020218F8200341040000B04
+:100DE000000513828F8200149763000A944200600A
+:100DF0003042FFFF14430005000513828F8200205C
+:100E00002404FFFD0A001AEBAF82003C30420003CD
+:100E10001440000E00000000920200021040000585
+:100E20008E03002450600015920300030A001AA7E5
+:100E3000024020218C8200245062001092030003A3
+:100E4000024020210A001AAF2402000F9082000DF8
+:100E50003042000854400009920300030240202160
+:100E6000240200100E0016C5A38200442403FFFFD5
+:100E7000104300382404FFFF920300032402000201
+:100E80005462000C920200038F8200345440000927
+:100E900092020003024020212402002C0E0016C5FD
+:100EA000A38200442403FFFF1043002A2404FFFF11
+:100EB000920200030200282102402021384600103F
+:100EC0002CC600012C4200010E0016E5004630251C
+:100ED0002410FFFF1050001F2404FFFF8F830034F5
+:100EE00010600013024020213C0208008C42318C2B
+:100EF0000043102B144000070000000000002821D0
+:100F0000240600010E001646000000000A001AEB3D
+:100F1000000020212402002D0E0016C5A3820044EB
+:100F20001050000C2404FFFF0A001AEB00002021DF
+:100F30000E0015F9240500010A001AEB000020211B
+:100F4000024020212402000D0E0016C5A382004499
+:100F5000004020210A001B0E008088211514000E7D
+:100F6000000000000E00174C024020210A001B0E5A
+:100F7000004088210E0016C5A38200440A001B0E03
+:100F80000040882114620017022018212402002347
+:100F900014E200052402000B0E0017C002402021BD
+:100FA0000A001B0E0040882102402021A382004439
+:100FB0000E0016C52411FFFF0A001B0F0220182186
+:100FC00030A500FF0E001529240600019783003A82
+:100FD0008F82003CA780003A00431023AF82003C80
+:100FE000022018211220003E9782003A2402FFFDC1
+:100FF0005462003E8E4300208E4200048F83001412
+:1010000000561023AE420004906200633042007F1D
+:10101000A06200638E4200208F840014A780003AF3
+:1010200034420002AE420020A48000E490820063BB
+:101030002403FFBF00431024A08200630A001B5159
+:101040008E4300209082006300621024304200FF33
+:10105000104000239782003A90820088908300BD60
+:10106000248500883042003F2444FFE02C82002089
+:10107000A383001C10400019AF85002C240200013E
+:1010800000821804306200191440000C3C028000F9
+:1010900034420002006210241440000B3062002031
+:1010A0001040000F9782003A90A6000102402021D4
+:1010B000240500010A001B4B30C60001024020211C
+:1010C0000A001B4A240500010240202100002821BB
+:1010D000240600010E001646000000009782003A28
+:1010E0001440FD0C8F8400148E43002030620004F5
+:1010F000104000128F84003C2402FFFB0062102489
+:10110000AE420020274301808F4201B80440FFFE19
+:101110008F820048AC6200008F420124AC62000460
+:1011200024026083A462000824020002A062000B73
+:101130003C021000AF4201B88F84003C8F83001442
+:101140008FBF00348FB600308FB5002C8FB40028CD
+:101150008FB300248FB200208FB1001C8FB0001815
+:101160002402000127BD003803E00008AC6400C081
+:1011700030A500FF2403000124A900010069102B01
+:101180001040000C00004021240A000100A310239D
+:10119000004A380424630001308200010069302BCA
+:1011A00010400002000420420107402554C0FFF80F
+:1011B00000A3102303E00008010010213C020800F6
+:1011C000244260A43C010800AC22736C3C0208007D
+:1011D000244253083C010800AC227370240200062C
+:1011E00027BDFFE03C010800A02273743C021EDC16
+:1011F000AFB20018AFB10014AFBF001CAFB0001009
+:1012000034526F4100008821240500080E001B7233
+:1012100002202021001180803C07080024E7737819
+:101220000002160002071821AC620000000028210D
+:1012300024A200013045FFFF8C6200002CA60008AC
+:1012400004410002000220400092202614C0FFF852
+:10125000AC640000020780218E0400000E001B72A7
+:1012600024050020262300013071FFFF2E230100FA
+:101270001460FFE5AE0200008FBF001C8FB20018A3
+:101280008FB100148FB0001003E0000827BD0020CC
+:1012900027BDFFD8AFB3001CAFB20018AFBF00200E
+:1012A000AFB10014AFB000108F5101408F4801481A
+:1012B00000089402324300FF311300FF8F4201B84F
+:1012C0000440FFFE27500180AE1100008F42014410
+:1012D000AE02000424020002A6120008A202000BC3
+:1012E00024020014AE1300241062002528620015A9
+:1012F0001040000824020015240200101062003083
+:1013000024020012106200098FBF00200A001CADE9
+:101310008FB3001C1062007024020022106200379C
+:101320008FBF00200A001CAD8FB3001C3C020800D8
+:101330008C4231A02403FF8002221021004310249C
+:10134000AF4200243C0208008C4231A0022210214E
+:101350003042007F034218213C02000A006218213B
+:10136000166000BCAF830014906200623042000F30
+:1013700034420030A06200620A001CAC8FBF002023
+:101380003C0460008C832C083C02F0033442FFFFD5
+:1013900000621824AC832C083C0208008C4231A067
+:1013A0008C832C08244200740002108200021480F6
+:1013B00000621825AC832C080A001CAC8FBF0020EB
+:1013C0003C0208008C4231A02403FF80022210213D
+:1013D00000431024AF4200243C0208008C4231A09C
+:1013E0003C03000A022210213042007F03421021F8
+:1013F000004310210A001CABAF8200143C0208001D
+:101400008C4231A02405FF800222102100451024C7
+:10141000AF4200243C0208008C4231A0022210217D
+:101420003042007F034218213C02000A006218216A
+:101430009062006300A21024304200FF104000853B
+:10144000AF83001424620088944300123C02080019
+:101450008C4231A830633FFF000319800222102123
+:10146000004310213043007F034320210045102416
+:101470003C03000C00832021AF4200289082000D25
+:1014800000A21024304200FF10400072AF840024FC
+:101490009082000D304200101440006F8FBF00207A
+:1014A0000E0015C8000000008F4201B80440FFFE86
+:1014B00000000000AE1100008F420144AE020004A3
+:1014C00024020002A6120008A202000BAE130024A0
+:1014D0000A001CAC8FBF00202406FF8002261024C7
+:1014E000AF4200203C0208008C4231A031043FFF93
+:1014F000000421800222102100461024AF42002463
+:101500003C0308008C6331A83C0208008C4231A0E7
+:101510003227007F022318210222102100641821A3
+:101520003042007F3064007F034228213C02000AE1
+:101530000066182400A22821034420213C02000C4C
+:1015400000822021AF4300283C02000803471821F5
+:1015500000629021AF850014AF8400240E0015C8EE
+:10156000010080218F4201B80440FFFE8F820024D9
+:101570008F840014274501809042000DACB100001B
+:10158000A4B0000600021600000216030002102795
+:10159000000237C214C00016248200889442001250
+:1015A00032033FFF30423FFF1443001224026082A7
+:1015B000908300632402FF8000431024304200FF28
+:1015C0005040000C24026082908200623042000F82
+:1015D00034420040A082006224026084A4A2000879
+:1015E0002402000DA0A200050A001C963C02270060
+:1015F00024026082A4A20008A0A000053C022700EB
+:1016000000061C000062182524020002A0A2000BA4
+:10161000ACA30010ACA00014ACA00024ACA0002827
+:10162000ACA0002C8E42004C8F840024ACA2001889
+:101630009083000D2402FF8000431024304200FFFD
+:10164000104000058FBF00209082000D3042007FC7
+:10165000A082000D8FBF00208FB3001C8FB2001836
+:101660008FB100148FB000103C02100027BD00287D
+:0816700003E00008AF4201B8DD
+:08167800080034300800343092
+:10168000080033A8080033E0080034140800343898
+:0C16900008003438080034380800331813
+:04169C000A0001241B
+:1016A00000000000000000000000000D74706136B2
+:1016B0002E302E313500000006000F010000000022
+:1016C000000000000000000000000000000000001A
+:1016D000000000000000000000000000000000000A
+:1016E00000000000000000000000000000000000FA
+:1016F00000000000000000000000000000000000EA
+:1017000000000000000000000000000000000000D9
+:1017100000000000000000000000000000000000C9
+:1017200000000000000000000000000000000000B9
+:1017300010000003000000000000000D0000000D7C
+:101740003C02080024421C003C030800246320944F
+:10175000AC4000000043202B1480FFFD2442000415
+:101760003C1D080037BD2FFC03A0F0213C100800F1
+:10177000261004903C1C0800279C1C000E00015CF5
+:10178000000000000000000D3084FFFF30820007E1
+:101790008F85001810400002248300073064FFF892
+:1017A0000085302130C41FFF03441821247B4000F2
+:1017B000AF85001CAF84001803E00008AF4400842C
+:1017C0003084FFFF308200078F8500208F8600283D
+:1017D00010400002248300073064FFF800852021B8
+:1017E0000086182B14600002AF8500240086202399
+:1017F0000344282134068000AF840020AF440080D9
+:1018000000A6202103E00008AF84003827BDFFD8E0
+:10181000AFB3001CAFB20018AFB00010AFBF0024D0
+:10182000AFB40020AFB100143C0860088D14500024
+:101830002418FF7F3C1A8000029898243672380CD6
+:10184000AD1250008F5100083C07601C3C0860003E
+:1018500036300001AF500008AF800018AF40008064
+:10186000AF4000848CE600088D0F08083C07601626
+:101870008CEC000031EEFFF039CA00103C0DFFFF88
+:10188000340B80003C030080034B48212D440001B1
+:10189000018D28243C0253533C010800AC23042052
+:1018A000AF890038AF860028AF840010275B400066
+:1018B00014A2000334E37C008CF9000403281821EF
+:1018C0008C7F007C8C6500783C0280003C0B08001B
+:1018D0008D6B048C3C0A08008D4A048834520070D9
+:1018E000AF85003CAF9F00403C13080026731C44AA
+:1018F0000240A0218E4800008F46000038C300013E
+:101900003064000110800017AF8800340280482145
+:101910008D2F00003C0508008CA5045C3C180800D5
+:101920008F18045801E8102300A280210000C8216C
+:101930000202402B03198821022838213C010800AB
+:10194000AC30045C3C010800AC2704588F4E00000A
+:1019500039CD000131AC00011580FFED01E04021DF
+:10196000AF8F00348E5100003C0708008CE7045C08
+:101970003C0D08008DAD04580228802300F0602142
+:10198000000070210190302B01AE1821006620214B
+:101990003C010800AC2C045C3C010800AC24045859
+:1019A0008F4601088F47010030C92000AF86000034
+:1019B000AF87000C1120000A00C040213C1808002D
+:1019C0008F18042C270800013C010800AC28042CC7
+:1019D0003C184000AF5801380A0001960000000092
+:1019E0009749010400002821014550213122FFFFC1
+:1019F000016258210162F82B015F502130D90200A9
+:101A00003C010800AC2B048C3C010800AC2A048883
+:101A10001720001524040F0010E40013000000003C
+:101A200024080D0010E8023B30CD000611A0FFE9AC
+:101A30003C184000936E00002409001031C400F0EF
+:101A40001089027124020070108202E58F88001450
+:101A5000250F0001AF8F00143C184000AF5801382B
+:101A60000A00019600000000974C01041180FFD984
+:101A70003C18400030C34000146000A1000000008A
+:101A80008F46017804C0FFFE8F87003824100800BD
+:101A9000240F00088CE30008AF500178A74F0140E5
+:101AA000A7400142974E01048F86000031C9FFFF15
+:101AB00030CD000111A002E1012040212531FFFEBF
+:101AC00024180002A75801463228FFFFA7510148F9
+:101AD0003C1908008F39043C172002D08F8C000C71
+:101AE00030DF002017E00002240400092404000174
+:101AF00030C20C0024050400504500013484000469
+:101B0000A744014A3C1108008E3104203C180048CB
+:101B10003C1000010238182530CF00020070282543
+:101B200011E00004000018213C19010000B928252B
+:101B30002403000130DF000453E00005AF830008F8
+:101B40003C06001000A6282524030001AF830008EE
+:101B5000AF45100000000000000000000000000081
+:101B6000000000008F8300081060002300000000C8
+:101B70008F45100004A1FFFE000000001060001E51
+:101B8000000000008F4410003C0C0020008C10244A
+:101B9000104000198F8E000031CD000211A00016F8
+:101BA00000000000974F101415E000130000000023
+:101BB000975910083338FFFF2711000600111882CB
+:101BC0000003308000C72821323000013223000397
+:101BD0001200032C8CA200000000000D00C7F821A9
+:101BE000AFE200003C0508008CA5043024A60001EB
+:101BF0003C010800AC2604308F6D00003402FFFF6A
+:101C0000AF8D00048CEC0000118202A600002021A0
+:101C10008CED000031AC01001180028A0000000050
+:101C20003C0208008C4204743C0308008C63044CA2
+:101C30003C1F08008FFF04703C1808008F180448F0
+:101C4000004838210068802100E8282B03E4302177
+:101C50000208402B0304882100C570210228782146
+:101C60003C010800AC30044C3C010800AC2F044897
+:101C70003C010800AC2704743C010800AC2E047041
+:101C80008F8400180120302131290007249F00088B
+:101C900033F91FFF03594021AF84001CAF9900188E
+:101CA000251B4000AF590084112000038F830020C2
+:101CB00024C200073046FFF88F84002800C3282183
+:101CC00000A4302B14C00002AF83002400A42823FA
+:101CD00003456021340D8000018D10213C0F100060
+:101CE000AF850020AF820038AF450080AF4F01784C
+:101CF0008F880014250F00010A0001EFAF8F001438
+:101D00008F6200088F67000024050030000776020C
+:101D100031C300F0106500A7240F0040546FFF4C42
+:101D20008F8800148F4B01780560FFFE00000000D3
+:101D300030CA020015400003000612820000000DA8
+:101D400000061282304D0003000D4900012D1821BC
+:101D500000038080020D40210008608001938021F3
+:101D60008E1F000017E00002000000000000000DC0
+:101D70008F6E000405C202BD92070006920E000598
+:101D8000920200043C090001000E18800070F82146
+:101D90008FED0018277100082448000501A9602173
+:101DA00000083082AFEC0018022020210E00059EB2
+:101DB00026050014920A00068F7900043C0B7FFF71
+:101DC000000A2080009178218DF800043566FFFF1D
+:101DD0000326282403053821ADE70004920E0005F0
+:101DE000920D0004960C0008000E10800051C821CE
+:101DF0008F230000974901043C07FFFF0067582428
+:101E00003128FFFF010DF82103EC50233144FFFF7F
+:101E100001643025AF26000092030007241800015A
+:101E200010780275240F0003106F02850000000077
+:101E30008E0500102419000AA7590140A745014248
+:101E4000921800048F860000240F0001A758014457
+:101E5000A74001469747010430D100023C050041EC
+:101E6000A747014800001821A74F014A122000038C
+:101E700030CB00043C050141240300015160000502
+:101E8000AF8300083C06001000A6282524030001AB
+:101E9000AF830008AF451000000000000000000004
+:101EA00000000000000000008F8A000811400004BC
+:101EB000000000008F4410000481FFFE00000000BD
+:101EC0008F6B0000920800043C1108008E3104441E
+:101ED000AF8B000497590104311800FF3C0E080035
+:101EE0008DCE04403325FFFF0305382102276021F2
+:101EF00000001021250F000A31E8FFFF0187482B61
+:101F000001C2682101A9F821311000073C01080035
+:101F1000AC2C04443C010800AC3F04401200000318
+:101F20008F8C00182506000730C8FFF8010C6821C7
+:101F300031BF1FFFAF8C001CAF9F0018AF5F008444
+:101F400097440104035F80213084FFFF308A00073B
+:101F500011400003261B4000248900073124FFF8AC
+:101F60008F8200208F850028008220210085702B21
+:101F700015C00002AF820024008520233C0B08001E
+:101F80008D6B048C3C0A08008D4A04880344882128
+:101F900034038000022310213C0F1000AF84002086
+:101FA000AF820038AF440080AF4F01780A0002963C
+:101FB0008F8800148F5001780600FFFE30D1020098
+:101FC00016200003000612820000000D0006128297
+:101FD000305F0003001F1900007F302100062080C1
+:101FE000009FC82100194880013380218E1800000D
+:101FF00013000002000000000000000D8F6C000CB8
+:10200000058001FB8F870038240E0001AE0E000012
+:102010008CE30008A20000078F650004000554024D
+:10202000314D00FF25A80005000830822CCB00416F
+:1020300015600002A20A00040000000D8F78000461
+:102040003C03FFFF00E02821330BFFFF256C000B52
+:10205000000C108200022080008748218D3F000084
+:1020600026040014A618000803E3C8240E00059EE9
+:10207000AD3900008F4F01083C11100001F13824E8
+:1020800010E001AB00000000974D0104920800072A
+:1020900025AAFFEC350600023144FFFFA206000727
+:1020A000960600082CC7001354E0000592030007B1
+:1020B00092110007362F0001A20F000792030007BC
+:1020C00024180001107801C224090003106901D509
+:1020D0008F88003830CBFFFF257100020011788314
+:1020E00031E400FF00042880A20F000500A8482169
+:1020F0008D2D0000974A01043C0EFFFF01AEF8242D
+:102100003143FFFF006B1023244CFFFE03ECC82576
+:10211000AD390000920600053C03FFF63462FFFF74
+:1021200030D800FF0018388000F08821922F00146A
+:102130003C04FF7F3487FFFF31EE000F01C65821BA
+:10214000316500FF00055080015068218DAC0020F2
+:102150000148F821A20B00060182C824AE0C000C35
+:10216000AFF9000C920900068E11000C03277824A9
+:102170000009C0800310702195C60026030828219D
+:1021800002272024AE04000CADCF0020ADC60024F1
+:10219000ACA600108F8800003C0B08008D6B048CEF
+:1021A0003C0A08008D4A0488241F001024190002EC
+:1021B000A75F0140A7400142A7400144A75901463B
+:1021C0009749010424070001310600022538FFFE6B
+:1021D000A75801483C050009A747014A10C0000361
+:1021E000000018213C05010924030001310C000402
+:1021F00051800005AF8300083C08001000A8282586
+:1022000024030001AF830008AF4510000000000068
+:102210000000000000000000000000009205000423
+:1022200024AE000231CD0007000D182330620007F4
+:10223000AE0200108F9000081200000400000000A1
+:102240008F4F100005E1FFFE000000008F710000BD
+:102250008F8E00183C0308008C630444AF91000487
+:102260009745010425CF001031E61FFF30A2FFFF84
+:10227000AF8E001CAF860018AF4600842449FFFED5
+:102280003C0C08008D8C0440974D010401208021F6
+:10229000000947C30070C02131A9FFFF0310F82BCC
+:1022A0000188C821033F202103463821313100072E
+:1022B0003C010800AC3804443C010800AC24044054
+:1022C0001220000324FB40002527000730E9FFF817
+:1022D0008F8600208F8400280126382100E4C02B3F
+:1022E00017000002AF86002400E4382303472021B2
+:1022F00034198000009910213C0F1000AF87002096
+:10230000AF820038AF470080AF4F01780A000296D5
+:102310008F8800149747010410E0FDAE3C18400080
+:102320008F5801780700FFFE30C5400010A0000361
+:102330003C1F00080000000D3C1F0008AF5F01407B
+:10234000241008008F860000AF50017897440104E4
+:1023500030D90001132000ED3086FFFF24CCFFFEB2
+:10236000240D0002A74D0146A74C01488F9100188B
+:102370002408000DA748014A8F630000262F00089B
+:1023800031E21FFF0342702130C90007AF83000410
+:10239000AF91001CAF82001800C03821AF4200840A
+:1023A0001120000325DB400024D800073307FFF885
+:1023B0008F8500208F84002800E5302100C4382B51
+:1023C00014E00002AF85002400C430238F84001481
+:1023D0000346F821340C8000AF86002003EC8021F6
+:1023E000AF460080249900013C0610003C184000D4
+:1023F000AF460178AF900038AF990014AF5801385C
+:102400000A000196000000008F630000975101044C
+:102410003067FFFF3228FFFF8F4F017805E0FFFE96
+:1024200030EC0007000CF82333F0000724F9FFFE1E
+:102430002404000AA7440140A7500142A7590144BF
+:10244000A7400146A74801488F45010830B8002041
+:1024500017000002240300092403000130CD00020C
+:10246000A743014A3C04004111A0000300001821C9
+:102470003C0401412403000130C90004512000053F
+:10248000AF8300083C0600100086202524030001CD
+:10249000AF830008AF4410000000000000000000FF
+:1024A00000000000000000008F8E000811C0000432
+:1024B000000000008F4210000441FFFE00000000F9
+:1024C0008F7F0000276400088F91003CAF9F0004BD
+:1024D000948500089490000A9499000C30AFFFFF97
+:1024E0000010C4003323FFFF11F100A603032025D1
+:1024F0003C0E08008DCE04443C0C08008D8C04403A
+:1025000000E888212626FFFE01C628210000682158
+:1025100000A6F82B018D2021009F80213C0108009E
+:10252000AC2504443C010800AC30044024E200081F
+:102530003042FFFF3047000710E000038F83001890
+:10254000244F000731E2FFF83106FFFF30C80007D3
+:102550000043802132191FFF0359C021AF83001CA3
+:10256000AF990018271B4000AF59008411000003E9
+:102570008F8C002024C5000730A6FFF88F84002828
+:1025800000CC282100A4F82B17E00002AF8C002417
+:1025900000A42823AF850020AF4500803C0408003C
+:1025A0008C84043403454821340E8000012E6821B8
+:1025B00010800005AF8D0038939100172406000E9F
+:1025C000122600112407043F3C021000AF4201789C
+:1025D0008F880014250F00010A0001EFAF8F00144F
+:1025E0000E0005C400E020218F8800143C0B080079
+:1025F0008D6B048C3C0A08008D4A0488250F00016D
+:102600000A0001EFAF8F00143C021000A7470148F9
+:10261000AF4201780A0004CE8F88001424040F0012
+:102620001184003D30CE002015C0000224030009B3
+:10263000240300010A00021AA743014A0A00020DFE
+:10264000A740014694EF000894F1000A94F0000CB2
+:102650008F8C003C001174003207FFFF31EDFFFF4B
+:1026600011AC003701C720253C1808008F1804441E
+:102670003C0F08008DEF0440000080210308682112
+:1026800001A8382B01F0702101C760213C0108002E
+:10269000AC2D04443C010800AC2C04400A00027A32
+:1026A0008F8400183C0208008C42047C3C03080024
+:1026B0008C6304543C1F08008FFF04783C1808000A
+:1026C0008F180450004838210068802100E8282B2A
+:1026D00003E430210208402B0304882100C5702147
+:1026E000022878213C010800AC3004543C01080069
+:1026F000AC2F04503C010800AC27047C3C010800CE
+:10270000AC2E04780A00027A8F840018A740014694
+:102710000A0004358F91001830CD002015A0FFC5A8
+:102720002403000D240300050A00021AA743014AEE
+:10273000974E010425C5FFF00A00038130A4FFFF76
+:102740008F9800401498FFC8000010213C05080035
+:102750008CA5046C3C1F08008FFF046800A8C821EA
+:102760000328302B03E22021008640213C01080091
+:10277000AC39046C3C010800AC2804680A00027AF9
+:102780008F8400188F8C0040148CFF5900E8C821FA
+:102790003C1808008F18046C3C1108008E31046846
+:1027A0002723FFFE03034821000010210123302BC3
+:1027B0000222702101C668213C010800AC29046C8A
+:1027C0003C010800AC2D04680A0004A524E20008BE
+:1027D0008F8800383C03FFFF8D02000C0043F82473
+:1027E00003E4C825AD19000C0A00038F30CBFFFFAE
+:1027F0000A0003C3AE000000974A010492040004DB
+:102800008E26000C014458212579FFF200C7C02410
+:102810003325FFFF03053825AE27000C0A0002E62A
+:102820008E0500103C0DFFFF8D0A0010014D58244D
+:1028300001646025AD0C00100A00038F30CBFFFF50
+:1028400097430104920E00048E290010006E10219F
+:10285000244DFFEE0127602431A8FFFF0188F825F1
+:10286000AE3F00100A0002E68E0500108E0F000C2D
+:10287000AE00000000078880023028210A0002B85C
+:10288000ACAF00201460000D3058FFFF3C04FFFF88
+:102890000044682401A47026000E602B000D102B4C
+:1028A000004CF82413E00002000000000000000DBE
+:1028B0008CAF00000A00025001E410253B03FFFF2B
+:1028C0000003882B0018802B0211202410800002A6
+:1028D000000000000000000D8CB900000A0002504A
+:1028E0003722FFFF3084FFFF30A5FFFF1080000775
+:1028F0000000182130820001104000020004204234
+:10290000006518211480FFFB0005284003E0000843
+:102910000060102110C00007000000008CA2000021
+:1029200024C6FFFF24A50004AC82000014C0FFFBF6
+:102930002484000403E000080000000010A0000848
+:1029400024A3FFFFAC860000000000000000000090
+:102950002402FFFF2463FFFF1462FFFA24840004B3
+:1029600003E0000800000000308EFFFF30D8FFFFBA
+:1029700000057C0001F8602539CDFFFF01AC502136
+:10298000014C582B014B4821000944023127FFFF1D
+:1029900000E830210006240230C5FFFF00A4182102
+:1029A0003862FFFF03E000083042FFFF3C0C0800E4
+:1029B0008D8C0484240BFF8027BDFFD0018450211F
+:1029C000014B4824AF4900203C0808008D080484CE
+:1029D000AFB20020AFB00018AFBF0028AFB30024E3
+:1029E000AFB1001C936600040104382130E4007F7D
+:1029F000009A10213C0300080043902130C50020BC
+:102A0000036080213C080111277B000814A000020C
+:102A1000264600702646006C92130004975101046C
+:102A2000920F00043267000F322EFFFF31ED00409D
+:102A300001C7282311A0000500004821925900BCBD
+:102A4000333800041700009000000000924300BCDF
+:102A5000307F000413E0000F0000000010A0000D04
+:102A600000000000960E0002240AFF8000A76021EB
+:102A700025CDFFFEA74D1016920B0004014B20241C
+:102A8000308200FF10400085010C40253C0F0400FF
+:102A9000010F40258F5301780660FFFE2404000AD1
+:102AA000A7440140960D00022404000931AC000740
+:102AB000000C5823316A0007A74A0142960200021F
+:102AC0002443FFFEA7430144A7400146975F01044A
+:102AD000A75F01488F5901083338002053000001D7
+:102AE00024040001920F000431EE001015C0000212
+:102AF0003483001000801821A743014A0000000021
+:102B0000000000000000000000000000AF481000BE
+:102B100000000000000000000000000000000000B5
+:102B20008F5110000621FFFE3113FFFF12600003DA
+:102B3000000000008F481018ACC800009603000683
+:102B4000307FFFFF27F90002001998820013888068
+:102B5000023B30218CD800001520005700183402A9
+:102B6000920300042405FF8000A3F82433F100FF42
+:102B70001220002C00000000924700BC30F200023E
+:102B80001240002800000000974B100C2562FFFE49
+:102B9000A7421016000000003C0A0400354900302E
+:102BA000AF4910000000000000000000000000001D
+:102BB000000000008F4C10000581FFFE00000000A7
+:102BC0009749100C8F51101C00C020213127FFFFA6
+:102BD00024F20030001218820003288000BBF82184
+:102BE0003226FFFFAFF100000E0005B300112C02EA
+:102BF0000013C880033B98218E7800000002740007
+:102C0000AFB800108FA80010310FFFFFAFAF00105A
+:102C10008FA4001001C46825AFAD00108FA600106E
+:102C2000AE66000097730008976D000A9766000C67
+:102C30008F8A003C000D5C0030CCFFFF3262FFFF4A
+:102C4000104A0036016C2025960600023C10100048
+:102C500024D300080E00013B3264FFFF974C0104AF
+:102C60000E0001493184FFFFAF5001788FBF00286B
+:102C70008FB300248FB200208FB1001C8FB00018DA
+:102C800003E0000827BD003010A0FF700000000026
+:102C900024A5FFFC0A0005EC240900048CD10000E7
+:102CA000AF5110188F5301780660FF7A2404000A90
+:102CB0000A0006010000000000A7C8218F88003824
+:102CC0008F4E101C0019C0820018788001E8202166
+:102CD000AC8E0000000E2C0200C020210E0005B3B7
+:102CE00031C6FFFF023B28218CAD000000025400DA
+:102CF00000403021AFAD00108FAC0010318BFFFFD2
+:102D0000AFAB00108FA2001001424825AFA9001000
+:102D10008FA700100A000631ACA700008F8F00407B
+:102D2000148FFFC90000000097420104960B0002B7
+:102D30003C0508008CA5046C3049FFFF316AFFFF99
+:102D40003C1108008E310468012A382124F2FFFE6C
+:102D500000B240210012FFC30112C82B023FC02164
+:102D6000031920213C010800AC28046C3C01080038
+:102D7000AC2404680A00066B0000000000A4102BBD
+:102D800010400009240300010005284000A4102B76
+:102D900004A00003000318405440FFFC0005284035
+:102DA00010600007000000000085302B14C00002F6
+:102DB00000031842008520231460FFFB0005284211
+:102DC00003E00008008010218F85002C27BDFFE85C
+:102DD000000530272CC300012CA40002008310251D
+:102DE00010400003AFBF00102405007FAF85002C0A
+:102DF0000005282730A5FFFF0E000592240426F5C4
+:102E00008F830030240402BD004030210083382B22
+:102E100010E0000924050001000420400083102B6D
+:102E200004800003000528405440FFFC00042040BB
+:102E300010A0000800C350210064402B15000002C0
+:102E4000000528420064182314A0FFFB0004204260
+:102E500000C350218FBF0010000A4C02312200FF36
+:102E600027BD0018AF8A002C03E00008AF890030AE
+:102E70000A00002A00000000000000000000000D11
+:102E8000747870362E302E313500000006000F00A9
+:102E900000000000000001360000EA6000000000B1
+:102EA0000000000000000000000000000000000022
+:102EB0000000000000000000000000000000000012
+:102EC0000000000000000000000000000000000002
+:102ED00000000016000000000000000000000000DC
+:102EE00000000000000000000000000000000000E2
+:102EF00000000000000000000000000000000000D2
+:102F00000000000000000000000013880000000026
+:102F1000000005DC000000000000000010000003BD
+:102F2000000000000000000D0000000D3C02080041
+:102F300024423C203C03080024633DD4AC40000004
+:102F40000043202B1480FFFD244200043C1D080098
+:102F500037BD7FFC03A0F0213C100800261000A81C
+:102F60003C1C0800279C3C200E0002BA0000000018
+:102F70000000000D8F8300383C088000350700708A
+:102F80008CE50000008330253C02900000C2202523
+:102F9000AF850030AF4400208F4900200520FFFEA0
+:102FA0003C038000346200708C4500008F86003046
+:102FB0003C1908008F39007C3C0E08008DCE00784B
+:102FC00000A6202303245821000078210164682BE7
+:102FD00001CF6021018D50213C010800AC2B007C09
+:102FE0003C010800AC2A007803E000080000000063
+:102FF0000A000041240400018F8400383C05800051
+:1030000034A200010082182503E00008AF4300202D
+:1030100003E00008000010213084FFFF30A5FFFF0F
+:1030200010800007000018213082000110400002CB
+:1030300000042042006518211480FFFB0005284091
+:1030400003E000080060102110C00007000000002D
+:103050008CA2000024C6FFFF24A50004AC8200005F
+:1030600014C0FFFB2484000403E0000800000000FB
+:1030700010A0000824A3FFFFAC86000000000000A1
+:10308000000000002402FFFF2463FFFF1462FFFA28
+:103090002484000403E0000800000000308AFFFFE1
+:1030A00093A80013A74A014497490E1630C600FFA3
+:1030B0003C021000A7490146AF450148A346015212
+:1030C000A748015AAF4701608FA400188FA30014CE
+:1030D000A7440158AF43015403E00008AF42017810
+:1030E00003E00008000000003C0380003462007030
+:1030F0008C4900008F8800002484000727BDFFF85A
+:103100003084FFF8AF890030974D008A31ACFFFF63
+:10311000AFAC00008FAB0000016850232547FFFFD4
+:1031200030E61FFF00C4282B14A0FFF73C0C8000E2
+:10313000358B00708D6A00003C0708008CE7008426
+:103140003C0608008CC60080000810820149182344
+:103150000002788000E370210000202101C3C82B09
+:1031600000C4C02101FA4021031948212502400072
+:1031700027BD00083C010800AC2E00843C0108007B
+:10318000AC29008003E00008000000008F820000EE
+:103190002486000730C5FFF800A2182130641FFF05
+:1031A00003E00008AF8400008F8700388F8A00405A
+:1031B00027BDFFB88F860044AFB60040AFBF0044C4
+:1031C000AFB5003CAFB40038AFB30034AFB200309D
+:1031D000AFB1002CAFB000288F4501048D4900AC81
+:1031E000AF4700808CC8002000A938230000B02120
+:1031F000AF480E108F440E1000004821AF440E144B
+:103200008CC20024AF420E188F430E18AF430E1C21
+:1032100010E001252D230001936B0008116000D4FC
+:1032200000000000976E001031CDFFFF00ED602B15
+:10323000158000CF0000000097700010320FFFFFD4
+:10324000AF4F0E008F520000325100081220FFFDD8
+:103250000000000097540E088F460E043285FFFFD1
+:1032600030B3000112600132000000000000000DC8
+:1032700030B8A04024150040131500C030A9A000AC
+:103280001120012D00000000937F000813E00008CA
+:103290000000000097630010306BFFFF00CB402B55
+:1032A0001100000330AC0040118001230000000039
+:1032B000A785003CAF8600349366000800E0282113
+:1032C000AFA7002014C0012427B30020AF60000C7A
+:1032D0009782003C3047400014E0000224030016AF
+:1032E0002403000E24194007A363000AAF790014D9
+:1032F000938A003E8F740014315800070018AA40CA
+:1033000002959025AF7200149784003C8F700014D2
+:103310003091001002117825AF6F0014978E003C99
+:1033200031CD000811A00147000028218F6700144B
+:103330003C0210003C0C810000E22825AF6500141F
+:1033400097460E0A2408000E3405FFFC30C3FFFF29
+:10335000006C5825AF6B0004A3680002937F000A3D
+:1033600027E90004A369000A9786003C9363000ADA
+:1033700030CC1F00000C598301634021251F002819
+:10338000A37F000997490E0CA769001093790009E3
+:10339000272A0002315800070018A82332B100077D
+:1033A000A371000B93740009976400108F9100348F
+:1033B000978F003C329200FF024480210205702169
+:1033C00031ED004011A0000531C4FFFF0091282B12
+:1033D0003C12800010A000140000A0210224382B11
+:1033E00014E0011B8FA500208F4D0E14AF4D0E1061
+:1033F0008F420E1CAF420E18AF440E008F4F0000DC
+:1034000031EE000811C0FFFD0000000097540E08C7
+:103410000080882100009021A794003C8F500E046A
+:1034200024140001AF900034976400103095FFFF22
+:103430008E6800000111F82317E00009AE7F00003C
+:103440008F6500148F8B004434A60040AF660014D3
+:103450008F4C0E10AD6C00208F430E18AD6300240E
+:103460009367000814E000D2000000000E00009EE8
+:10347000240400108F8900483C08320000402821B5
+:10348000312600FF0006FC0003E850252539000125
+:10349000AF990048AC4A0000937800099370000A85
+:1034A000330400FF00047400320F00FF01CF6825D1
+:1034B000AC4D00048F820048064000EAACA2000830
+:1034C000ACA0000C9783003C306B00081560000234
+:1034D0002628000626280002974E0E148F450E1C43
+:1034E0008F670004936D000231C4FFFF31A200FF1B
+:1034F000AFA200108F6C0014AFA800180E00008B54
+:10350000AFAC0014240400100E0000C7000000003F
+:103510008E72000016400005000000008F64001449
+:103520002405FFBF00859824AF7300148F79000C29
+:1035300003353821AF67000C9375000816A000080A
+:103540000000000012800006000000008F7F0014C1
+:103550003C0BEFFF3568FFFE03E84824AF69001419
+:10356000A37400088FA500200A0002460220202133
+:10357000AF470E000A0000F5000000008F590178E7
+:103580000720FFFE241F08008F840000AF5F017832
+:10359000974B008A316AFFFF014448232528FFFF2B
+:1035A00031021FFF2C4300081460FFF900000000E7
+:1035B0008F8E00488F8D003800C0482103442021A1
+:1035C00025C60001240C0F00AF86004800E938230F
+:1035D0002486400031CA00FF11AC00052408000118
+:1035E0009391003E3230000700107A4035E8000128
+:1035F000000AAC003C18010002B8A025AC944000C1
+:103600008F93004830B2003630A40008ACD30004D9
+:103610001080009701123025974E0E0A8F8D000002
+:103620003C02810031CCFFFF25AB00080182402520
+:103630003C03100031651FFF25390006241F000ED2
+:10364000AF48016000C33025A75F015AAF85000075
+:10365000A759015814E0000A8F93003824120F0074
+:10366000527200022416000134C600408F580E101A
+:103670008F940044AE9800208F550E18AE9500240C
+:103680008F450E14AF4501448F590E1CAF590148A8
+:10369000A34A01523C0A1000AF460154AF4A0178D8
+:1036A00014E0FEDD2D2300010076A0251280001716
+:1036B0008FBF00448F84003824160F0010960084BA
+:1036C000000000008F45017804A0FFFE24150F00C4
+:1036D0001095006E000000008F470E142402024077
+:1036E0003C1F1000AF4701448F440E1CAF440148FB
+:1036F000A3400152A740015AAF400160A7400158C2
+:10370000AF420154AF5F01788FBF00448FB60040D5
+:103710008FB5003C8FB400388FB300348FB20030C7
+:103720008FB1002C8FB0002803E0000827BD0048AF
+:1037300014C0FED030B8A0408F420E148F840044D5
+:1037400000004821AC8200208F510E1CAC91002457
+:103750000A00020E2D2300018F910034978A003C4D
+:103760003C1280000220A821315800401700FF3091
+:103770000000A021976900108F9200343139FFFFBB
+:103780001332003500002021008048211480FEA063
+:1037900000A038218F420E148F840044AC82002098
+:1037A0008F510E1CAC9100240A00020E2D23000143
+:1037B000936A00099378000B315000FF330F00FF2C
+:1037C000020F702125C2000A3050FFFF0E00009E3C
+:1037D000020020218F8600483C1F410024CD0001BB
+:1037E000AF8D0048936C000930C600FF000644000E
+:1037F000318300FF246B0002010B4825013FC825DF
+:10380000AC5900008F67000C97440E1400F2282575
+:10381000AC4500048F450E1C8F670004936A0002BC
+:103820003084FFFF315800FFAFB800108F6F0014D5
+:10383000AFB100180E00008BAFAF00140A0001A654
+:1038400002002021AF6000040A00013EA3600002D4
+:103850000A00024600002021000090210A000170A9
+:10386000241400013C1280000A000195ACB2000C47
+:103870008F91000025240002A7440158263000083B
+:10388000320F1FFF0A0001F9AF8F0000AF40014C5B
+:103890001120002C000000008F590E10AF59014478
+:1038A0008F430E18240200403C1F1000AF43014814
+:1038B000A3400152A740015AAF400160A740015800
+:1038C000AF420154AF5F01780A0002278FBF004466
+:1038D000112000060000000097460E0830CC004082
+:1038E00015800002000000000000000D8F4D0178DF
+:1038F00005A0FFFE0000000097530E103C120500CB
+:10390000240E2000326AFFFF0152C025AF58014C3F
+:103910008F4F0E143C021000AF4F01448F500E1C0D
+:10392000AF500148A34001528F840038A740015A8C
+:10393000AF400160A7400158AF4E01540A00021584
+:10394000AF4201788F490E14AF4901448F430E1CDA
+:103950000A00028E240200403C0E20FF27BDFFE03B
+:103960003C1A80003C0F800835CDFFFDAFBF001C26
+:10397000AFB20018AFB10014AFB00010AF8F00406D
+:10398000AF4D0E000000000000000000000000002D
+:1039900000000000000000003C0C00FF358BFFFD24
+:1039A000AF4B0E003C0660048CC95000240AFF7F18
+:1039B0003C116000012A40243507380CACC7500088
+:1039C0008E24043824050009AF4500083083FFFF2A
+:1039D00038622F712450C0B3AF8000480E000068D9
+:1039E000AF80000052000001AE20442C0E000435D0
+:1039F0003C1180000E000ED9363000708F8A0040D6
+:103A00003C12080026523C88020088218E080000E3
+:103A10008F5F00003BF900013338000113000017ED
+:103A2000AF880030022048218D2700003C0F08009D
+:103A30008DEF006C3C0C08008D8C006800E8C02302
+:103A400001F828210000682100B8302B018D582191
+:103A5000016640213C010800AC25006C3C010800D7
+:103A6000AC2800688F4400003883000130620001F8
+:103A70001440FFED00E04021AF8700308E0C0000C5
+:103A80003C0508008CA5006C3C0408008C84006890
+:103A90000188302300A638210000102100E6402BC9
+:103AA000008218210068F8213C010800AC27006C56
+:103AB0003C010800AC3F00688F490100255900888F
+:103AC000AF990044AF890038AF4900208E0700004D
+:103AD000AF8700308F4D017805A0FFFE0000000089
+:103AE0008E0600003C0B08008D6B00743C0408003F
+:103AF0008C84007000C728230165F8210000102184
+:103B000003E5402B0082382100E8C8212409080081
+:103B10003C010800AC3F00743C010800AC39007067
+:103B2000AF49017893580108A398003E938F003E57
+:103B300031EE000115C000158F830038240E0D00F2
+:103B4000106E0019240F0F00106F001D0000000000
+:103B50009159000024180050332900FF1138000447
+:103B60003C1F4000AF5F01380A0002E70000000080
+:103B70000E00090E000000008F8A00403C1F40002C
+:103B8000AF5F01380A0002E700000000938D003E9D
+:103B900031AC0006000C51000E0000CE0152D821BD
+:103BA0000A0003438F8A00403C1B0800277B3D0826
+:103BB0000E0000CE000000000A0003438F8A004080
+:103BC0003C1B0800277B3D280E0000CE00000000B3
+:103BD0000A0003438F8A004090AA00018FAB0010B7
+:103BE0008CAC00103C0300FF8D680004AD6C00201D
+:103BF0008CAD001400E060213462FFFFAD6D002445
+:103C00008CA700183C09FF000109C024AD670028FB
+:103C10008CAE001C0182C82403197825AD6F000406
+:103C2000AD6E002C8CAD0008314A00FFAD6D001C5C
+:103C300094A900023128FFFFAD68001090A7000092
+:103C4000A5600002A1600004A167000090A300022B
+:103C5000306200FF00021982106000052405000197
+:103C60001065000E0000000003E00008A16A0001DA
+:103C70008CD80028354A0080AD7800188CCF00140D
+:103C8000AD6F00148CCE0030AD6E00088CC4002CDB
+:103C9000A16A000103E00008AD64000C8CCD001C9B
+:103CA000AD6D00188CC90014AD6900148CC80024D7
+:103CB000AD6800088CC70020AD67000C8CC20014F2
+:103CC0008C8300640043C82B132000070000000011
+:103CD0008CC20014144CFFE400000000354A008040
+:103CE00003E00008A16A00018C8200640A000399C5
+:103CF0000000000090AA000027BDFFF88FA9001C5B
+:103D0000A3AA00008FAE00003C0FFF808FA8001810
+:103D100035E2FFFF8CCD002C01C26024AFAC000067
+:103D2000A120000400E06021A7A000028FB80000DD
+:103D30008D2700040188182100A0582100C05021BF
+:103D4000006D28263C06FF7F3C0F00FF2CAD0001D4
+:103D500035EEFFFF34D9FFFF3C02FF00031930248A
+:103D6000000D1DC0010EC82400E2C02400C3702550
+:103D700003197825AD2E0000AD2F00048D450024D9
+:103D8000AFAE0000AD2500088D4D00202405FFFFDB
+:103D9000AD2D000C956800023107FFFFAD27001024
+:103DA0009166001830C200FF000219C25060000185
+:103DB0008D450034AD2500148D67000827BD00082F
+:103DC000AD27001C8C8B00CCAD2C0028AD20002C26
+:103DD000AD2B0024AD20001803E00008AD2000202A
+:103DE00027BDFFE0AFB20018AFB10014AFB00010B4
+:103DF000AFBF001C9098000000C088213C0D00FF60
+:103E0000330F007FA0CF0000908E000135ACFFFF84
+:103E10003C0AFF00A0CE000194A6001EA2200004D0
+:103E20008CAB00148E29000400A08021016C282492
+:103E3000012A40240080902101052025A6260002A9
+:103E4000AE24000426050020262400080E0000767B
+:103E500024060002924700002605002826240014AC
+:103E600000071E000003160324060004044000039C
+:103E70002403FFFF965900023323FFFF0E00007654
+:103E8000AE230010262400248FBF001C8FB2001820
+:103E90008FB100148FB00010240500030000302102
+:103EA0000A00008027BD002027BDFFD8AFB1001C4D
+:103EB000AFB00018AFBF002090A80000240200019E
+:103EC0008FB0003C3103003F008088211062001455
+:103ED0008FAA0038240B0005506B0016AFAA001003
+:103EE00000A0202100C028210E0003DC02003021A8
+:103EF000922400BC308300021060000326060030CC
+:103F0000ACC0000024C600048FBF00208FB1001C8D
+:103F10008FB0001800C0102103E0000827BD002862
+:103F2000014038210E00035AAFB000100A000420EF
+:103F3000000000000E0003A1AFB000140A0004202E
+:103F4000000000003C02000A034218213C04080063
+:103F500024843D6C2405001A000030210A000080F2
+:103F6000AF8300543C038000346200708C48000032
+:103F700000A0582100C04821308A00FFAF880030DF
+:103F80008F4401780480FFFE3C0C80003586007071
+:103F90008CC500003C0308008C6300743C180800CA
+:103FA0008F18007000A82023006468210000C82139
+:103FB00001A4782B0319702101CF60213C01080076
+:103FC000AC2D00743C010800AC2C00708F480E141E
+:103FD000AF480144AF47014CA34A0152A74B0158D7
+:103FE0009346010830C5000854A00001352910008F
+:103FF000934B090024070050316A00FF1147000766
+:10400000000000008F450E1CAF450148AF49015428
+:104010003C09100003E00008AF490178934D010806
+:1040200031A800081100001000000000934F0108A3
+:1040300031EE001051C00001352900083C04080091
+:1040400090843DD0A34401508F4309A4AF4301485D
+:104050008F4209A0AF420144AF4901543C0910000E
+:1040600003E00008AF4901783C1908008F393D8C06
+:10407000333800085700FFF1352900080A0004739F
+:104080000000000024070040AF470814AF400810AC
+:104090008F4209448F4309508F4409548F45095C6E
+:1040A0008F46094CAF820064AF830050AF84004C50
+:1040B000AF85005C03E00008AF860060934601090D
+:1040C00030C5007F000518C0000521400083102185
+:1040D00003E00008244200883C09080091293D9132
+:1040E00024A800023C05110000093C0000E830252E
+:1040F00000C5182524820008AC83000003E00008F6
+:10410000AC8000049347010B8F4A002C974F09089D
+:104110003C18000E0358482131EEFFFF000E41C04D
+:10412000AF48002C97430908952C001A00804021C5
+:1041300024030001318BFFFFAC8B00008D2D001C90
+:1041400000A0582100C06021AC8D00048D24002007
+:1041500030E70040AD04000891220019304400030C
+:10416000108300482885000214A000622406000283
+:104170001086005624190003109900660000000004
+:1041800010E0003A000000003C07080094E73D867C
+:1041900024E20001934F0934934709219525002A11
+:1041A00031EE00FF000E488230ED00FF9787005887
+:1041B00000093600000D1C003044FFFF00C310252D
+:1041C0000044C02500A778213C1940000319702540
+:1041D000000F4C00AD090004AD0E0000934D092006
+:1041E0003C03000625090014000D360000C32025FD
+:1041F000AD0400088F59092C24E5000130A27FFF8F
+:10420000AD19000C8F580930A782005825020028EC
+:10421000AD1800108F4F0938AD0F0014AD2B0004FE
+:104220008F4E0940AD2E0008934D09373C0508001C
+:1042300090A53D908F4409488F46094031A700FF63
+:1042400000EC1821008678230003C7000005CC008D
+:104250000319602531E8FFFC01885825AD2B000CBF
+:10426000AD20001003E00008AF4A002C3C0D080010
+:1042700095AD3D863C0E080095CE3D800A0004C9F0
+:1042800001AE10213C05080094A53D8A3C060800BB
+:1042900094C63D803C18080097183D7C952E00245C
+:1042A00000A6782101F86823000E240025A2FFF261
+:1042B0000082182524190800AD03000CAD19001464
+:1042C000AD0000100A0004C425080018952600243B
+:1042D000952500280006C40000057C00370E8100EB
+:1042E00035ED0800AD0E000CAD0D00100A0004C441
+:1042F000250800141480FFA200000000952400246B
+:104300000004140034430800AD03000C0A0004C488
+:10431000250800103C03080094633D8A3C05080012
+:1043200094A53D803C06080094C63D7C9539002448
+:1043300095380028006520210086782300196C003C
+:104340000018740025E2FFEE01C2202535A381008C
+:1043500024190800AD03000CAD040010AD190018BD
+:10436000AD0000140A0004C42508001C03E0000886
+:10437000240201F427BDFFE8AFB00010AFBF001466
+:104380000E0000600080802124050040AF45081425
+:104390008F8300508F84004C8F85005C0070182143
+:1043A0000064102318400004AF830050AF63005432
+:1043B0008F660054AF86004C1200000C0000000015
+:1043C0008F440074936800813409FA002D070007B8
+:1043D00010E0000500891021936C0081240B01F48A
+:1043E000018B500401441021AF62000C8F4E095C18
+:1043F00001C5682319A000048FBF00148F4F095C0A
+:10440000AF8F005C8FBF00148FB000100A000062F5
+:1044100027BD00188F8400648F8300508F82004C6A
+:10442000AF640044AF63005003E00008AF62005483
+:104430003C038000346200708C43000027BDFFF80D
+:10444000308700FF30A900FF30C800FFAF83003085
+:104450008F4401780480FFFE3C02800034590070D4
+:104460008F380000A3A700033C0708008CE7007406
+:104470008FAC00003C0608008CC600700303782354
+:104480003C0E7FFF00EFC82135CDFFFF000050211B
+:10449000018D282400CA1821000847C0032F202BB3
+:1044A00000A810250064C021AFA200003C01080054
+:1044B000AC3900743C010800AC380070934F010A1D
+:1044C000A3A000023C0E80FFA3AF00018FAC000050
+:1044D000312B007F35CDFFFF018D4824000B5600A6
+:1044E000012A4025240730002406FF803C051000E7
+:1044F00027BD0008AF48014CAF470154A740015801
+:10450000A346015203E00008AF45017827BDFFE84C
+:10451000AFBF0014AFB000108F6500743C06800080
+:10452000309000FF00A620250E000060AF640074EC
+:1045300093630005346200080E000062A362000568
+:10454000020020218FBF00148FB000102405000549
+:10455000240600010A00057027BD001827BDFFE0F2
+:104560003C038000AFB00010AFBF0018AFB1001423
+:10457000346200708C470000309000FF30A800FFCC
+:10458000AF8700308F4401780480FFFE3C18800024
+:10459000371100708E2F00003C0D08008DAD0074A7
+:1045A0003C0A08008D4A007001E7702301AE282103
+:1045B0000000582100AE302B014B48210126382144
+:1045C0003C010800AC250074000088213C01080073
+:1045D000AC2700701100000F000000008F62007413
+:1045E0002619FFFF3208007F0002FE0233E5007F3C
+:1045F00015000006332200FF2407FF800207202653
+:1046000024A3FFFF00838025320200FF00408021A9
+:10461000241110080E000060000000008F490818E7
+:104620003125000414A0FFFD3218007F001878C067
+:104630000018714001CF682125AC0088AF4C0818E4
+:10464000274A09808D4B0020AF4B01448D46002442
+:10465000AF460148A35001500E000062A740015828
+:10466000022010218FBF00188FB100148FB00010EE
+:1046700003E0000827BD002027BDFFE8308400FFCD
+:10468000AFBF00100E0005BB30A500FF8F830050A8
+:104690008FBF0010344500402404FF903C021000FE
+:1046A00027BD0018AF43014CA3440152AF4501544C
+:1046B00003E00008AF4201789343093E30620008EE
+:1046C0001040000D3C0901013528080AAC880000A3
+:1046D0008F470074AC8700043C06080090C63D90EC
+:1046E00030C5001050A00006AC8000088F6A006042
+:1046F000AC8A00082484000C03E00008008010212C
+:104700000A0006222484000C27BDFFE8AFBF001476
+:10471000AFB000109346093F00A05021000528804B
+:104720000085382330C200FF240300063C0908003E
+:1047300095293D8624E8FFD824050004104300375E
+:10474000240600029750093C3C0F02040006340086
+:10475000320EFFFF01CF6825AC8D0000934C093E5F
+:10476000318B0020116000080000000093430936DF
+:104770003C020103345F0300307900FF033FC02592
+:1047800024050008AC980004934309349359092187
+:104790000005F882306200FF0002C082332F00FF64
+:1047A00000186E00000F740001AE602501892025FD
+:1047B0003C09400000898025ACF0FFD893430937BD
+:1047C0008F4F09488F580940306200FF004AC821C6
+:1047D000033F702101F86023000E6F0001A65025F1
+:1047E0003185FFFC001F58800145482501683821AC
+:1047F000AD0900200E00006024F00028240400040D
+:104800000E000062A364003F020010218FBF00145D
+:104810008FB0001003E0000827BD00180A0006351D
+:104820002406001227BDFFD024090010AFB60028CF
+:10483000AFB50024AFB40020AFB10014AFB000108A
+:104840003C010800A0293D90AFBF002CAFB3001C75
+:10485000AFB2001897480908309400FF3C02000EE0
+:104860003107FFFF000731C0AF46002C974409080D
+:104870009344010B30B500FF0342802130830030A8
+:104880000000B0211060012500008821240C0004E4
+:104890003C010800A02C3D90934B093E000B5600B4
+:1048A000000A2E0304A0016000000000AF40004891
+:1048B000934F010B31EE002011C0000600000000F4
+:1048C0009358093E00189E00001396030640018984
+:1048D000000000009344010B30830040106000038F
+:1048E0008F9300508F8200502453FFFF9347093E5F
+:1048F00030E6000814C000022412000300009021DA
+:104900009619002C93580934934F0937A7990058EA
+:10491000330C00FF31EE00FF024E6821000D58807D
+:10492000016C5021015140213C010800A4283D8622
+:104930009205001830A900FF010918213C01080068
+:10494000A4233D88921100181620000200000000E8
+:104950000000000D3C010800A4233D8A3C01080032
+:10496000A4203D803C010800A4203D7C935F010B06
+:104970003063FFFF33F00040120000022464000A9D
+:104980002464000B3091FFFF0E00009E02202021C6
+:104990009358010B3C08080095083D8A00402021EF
+:1049A00000185982316700010E00049A010728217E
+:1049B000934C010B8F4B002C974E09083C0F000EB7
+:1049C000034F402131CDFFFF000D51C0AF4A002CF5
+:1049D000974309089505001A004038212404000176
+:1049E00030A9FFFFAC4900008D06001C00404821A3
+:1049F000318A0040AC4600048D020020ACE2000881
+:104A00009103001930630003106400EC2879000260
+:104A100017200118241000021070010C241F00033D
+:104A2000107F011E00000000114000DE00000000A9
+:104A30003C09080095293D8625220001935F093431
+:104A4000934E09219504002A33F900FF0019C08212
+:104A500031CF00FF978E005800184600000F6C0001
+:104A6000010D80253045FFFF02051025008E5021E5
+:104A70003C03400000433025000A6400ACEC000415
+:104A8000ACE60000935F09203C19000624EC0014FA
+:104A9000001FC60003197825ACEF00088F48092CC9
+:104AA00025CD000131A57FFFACE8000C8F50093007
+:104AB000A785005824E80028ACF000108F4409387E
+:104AC00001008021ACE40014AD9300048F53094031
+:104AD000AD930008934A09373C19080093393D907B
+:104AE0008F4309488F460940314200FF0052F821A8
+:104AF00000667023001F7F000019C40001F82825FC
+:104B000031CDFFFC00AD2025AD84000CAD80001040
+:104B1000AF4B002C934B093E317300081260000D1F
+:104B20003C06010134CC080AACEC00288F53007419
+:104B3000AD1300043C0B0800916B3D9031670010F1
+:104B400050E00003AD0000088F6A0060AD0A000865
+:104B50002510000C12C0003D000000009343093FE7
+:104B60002416000624060004306200FF105600C917
+:104B7000240700029758093C3C0F0204330DFFFF45
+:104B800001AF4025AE0800009345093E30A4002047
+:104B90001080000800000000935309363C0B01030D
+:104BA000357F0300327900FF033F7025AE0E00040D
+:104BB00024060008934F093493480921312AFFFF46
+:104BC00031ED00FF000D1082310300FF0002B6003E
+:104BD00000032C0002C56025018A98250012208060
+:104BE0003C0940000204502302695825AD4BFFD810
+:104BF000935F09378F4F09488F58094033F900FFF9
+:104C0000033270210006B08201D6682100074400FB
+:104C100001F82823000D1F000068302530A2FFFC9A
+:104C20002547FFD800C26025001680800207482172
+:104C3000ACEC0020253000280E0000602412000497
+:104C4000A372003F0E000062000000009347010BBA
+:104C500030F20040124000053C1900FF8E180000A1
+:104C6000372EFFFF030E3024AE0600000E0000C7F3
+:104C7000022020213C10080092103D9032110003C8
+:104C80001220000F02A028218F8900502533000137
+:104C9000AF930050AF7300508F6B00540173F82333
+:104CA0001BE00002026020218F640054AF640054B6
+:104CB0008F4C0074258401F4AF64000C02A02821FD
+:104CC00002802021A76000680E0005BB3C14100084
+:104CD0008F85005034550006AF45014C8F8A00483F
+:104CE0008FBF002C8FB3001C25560001AF960048E3
+:104CF0008FB20018A34A01528FB60028AF55015455
+:104D00008FB10014AF5401788FB500248FB4002008
+:104D10008FB0001003E0000827BD00309358093E13
+:104D200000189E000013960306420036241100026C
+:104D300093440923308300021060FEDD8F860060FB
+:104D40008F82005014C2FEDA000000000E000060E6
+:104D5000000000009369003F24070016312800FF7F
+:104D60001107000C240500083C0C0800918C3D90B4
+:104D7000358B00013C010800A02B3D90936A003F59
+:104D8000314300FF10650065240D000A106D005EC0
+:104D90002402000C0E000062000000000A000690D1
+:104DA000000000003C09080095293D863C0A0800E7
+:104DB000954A3D800A0006F3012A10213C090800AB
+:104DC00095293D8A3C04080094843D803C060800F7
+:104DD00094C63D7C95030024012410210046F8234D
+:104DE0000003CC0027F0FFF20330C025240F080099
+:104DF000ACF8000CACEF0014ACE000100A0006EEBA
+:104E000024E700183C010800A0313D90935F093E63
+:104E10002416000133F900201720FEA524110008F4
+:104E20000A000690241100048F6E00848F4D094003
+:104E300011A0FE9EAF8E0050240F00143C0108000C
+:104E4000A02F3D900A00068F00000000950E002460
+:104E5000950D0028000E6400000D2C00358981009E
+:104E600034A60800ACE9000CACE600100A0006EE1F
+:104E700024E700141460FEEC0000000095020024FA
+:104E800000021C0034640800ACE4000C0A0006EECA
+:104E900024E700100A000741240700123C02080022
+:104EA00094423D8A3C06080094C63D803C030800BD
+:104EB00094633D7C95100024951900280046F82144
+:104EC00003E3C02300106C0000197400270FFFEEED
+:104ED00001CF282535AC8100ACEC000CACE500100E
+:104EE00024070800AD2700182527001C0A0006EE3D
+:104EF000AD2000148F7F004CAF7F00548F79005499
+:104F00000A000699AF790050A362003F0E000062CC
+:104F1000000000000A0006900000000024020014B7
+:104F20000A000827A362003F27BDFFE8308400FF86
+:104F3000AFBF00100E0005BB30A500FF9378007EC8
+:104F40009379007F936E00809368007A332F00FF7F
+:104F500000186600000F6C0031CB00FF018D482562
+:104F6000000B52008FBF0010012A3825310600FFC8
+:104F70003444700000E628252402FF813C03100021
+:104F800027BD0018AF45014CAF440154A342015264
+:104F900003E00008AF43017827BDFFD8AFB2001887
+:104FA000AFB10014AFB00010AFBF0020AFB3001C12
+:104FB00093420109308600FF30B000FF000618C29E
+:104FC000320400023071000114800005305200FFED
+:104FD0009367000530E5000810A0000D30C80010F0
+:104FE000024020210E0005A70220282124040001F0
+:104FF0008FBF00208FB3001C8FB200188FB1001438
+:105000008FB000100080102103E0000827BD0028A9
+:105010001500003200000000934301090000282120
+:105020003062007F000220C00002F94003E49821B2
+:1050300026790088033B98218E7800248E6F000823
+:10504000130F0046000000008F6400842418000243
+:105050000004FD8233F900031338007C00000000D7
+:1050600093660083934A0109514600043205007C8F
+:1050700010A00060000000003205007C14A0005366
+:105080000240202116200006320400018E7F0024F9
+:105090008F59010417F9FFD60000202132040001C6
+:1050A0001080000A024020218F4209408F93006443
+:1050B00010530006000000000E00066D022028219B
+:1050C0008F430940AF630044024020210E000602D6
+:1050D000022028210A000860240400013C0908007D
+:1050E0008D290064252600013C010800AC260064DF
+:1050F00016000012000000008F6D00843C0E00C0FE
+:1051000001AE602415800005024020210E00082E0B
+:10511000022028210A00086024040001240500045C
+:105120000E00057024060001024020210E00082E0A
+:10513000022028210A000860240400010E0000411A
+:1051400024040001936B007D020B50250E000062C9
+:10515000A36A007D0A0008A38F6D00848F66007427
+:105160008F4801048E67002400064E021507FFB623
+:105170003126007F936B008326440001308A007F34
+:1051800011460043316300FF5464FFB08F64008414
+:105190002645000130B1007F30A200FF1226000436
+:1051A00024050001004090210A0008762411000126
+:1051B000240FFF80024F702401CF9026324200FF5F
+:1051C000004090210A000876241100010E00066DAF
+:1051D00002202821321800301300FFAA321000826A
+:1051E000024020210E0005A7022028210A000860A5
+:1051F000240400018F6E00743C0F8000240500031E
+:1052000001CF9025AF7200749371008324060001D2
+:105210000E000570322400FF0E000041240400013E
+:10522000936D007D020D60250E000062A36C007D71
+:105230003C0B08008D6B0054257000013C010800F8
+:10524000AC3000540A000860240400018F68007428
+:105250003C0980002405000401093825AF6700746B
+:1052600093630083240600010E000570306400FF84
+:105270000E000041240400019362007D0202982583
+:105280000E000062A373007D0A0008602404000180
+:10529000324D008039AC0080546CFF6C8F64008408
+:1052A0000A0008C92645000127BDFFC83C0A0008BE
+:1052B000AFBF0030AFB5002CAFB40028AFB30024AF
+:1052C000AFB20020AFB1001CAFB00018034AD82124
+:1052D00024090040AF490814AF4008108F42094428
+:1052E0008F4309508F4609548F47095C8F48094CFA
+:1052F000934401089345010BAF820064308400FFA2
+:1053000030A500FFAF830050AF86004CAF87005C34
+:105310000E00084AAF8800601440017D8FBF003046
+:10532000A7600068934D0900240B00503C1508004D
+:1053300026B53D4831AC00FF3C12080026523D58CE
+:10534000118B0003000000000000A8210000902144
+:10535000935101098F9F005024040010322E007FCA
+:10536000000E68C0000E6140018D282124B4008821
+:10537000AF5408188F4901048F4A09A43C0B000E52
+:10538000034BC021012A10233C010800AC223D6CD4
+:105390008F4309583C010800A0243D909747090815
+:1053A000007F30233C010800AC263D7030E8FFFF51
+:1053B0000008C9C03C010800AC3F3D94AF59002C27
+:1053C000974209089710002C8EB10000930F001827
+:1053D00003749821A7900058AF9300440220F80965
+:1053E00031F000FF304E000215C001B2304F000115
+:1053F00011E0014F000000009343093E30660008B1
+:1054000014C00002241400030000A0218F5809A436
+:10541000241300013C010800AC383D98934F093437
+:105420009351093731EC00FF322E00FF028E6821C4
+:10543000000D288000AC5021015058213C0108008B
+:10544000A42B3D883C010800A42A3D8693490934D9
+:10545000312200FF02022021249000103C010800AC
+:10546000A4303D84240700068F9F00503C010800B3
+:10547000AC273D8C8F88005C8F5909580000802133
+:10548000011F282304A00149033F20230480014772
+:1054900000A4302B10C00149000000003C010800AE
+:1054A000AC253D708E4200000040F809000000006D
+:1054B00030430002146000F80040882130440001AD
+:1054C000548000108E4200043C0908008D293D7470
+:1054D0003C0AC000012A8025AF500E008F45000015
+:1054E00030AB00081160FFFD00000000974D0E0872
+:1054F00024100001A78D003C8F4C0E04AF8C0034AB
+:105500008E4200040040F8090000000002228825B5
+:10551000322E000215C00180000000003C09080086
+:1055200095293D7C3C06080094C63D883C0A08004D
+:10553000954A3D7E3C1908008F393D740126602153
+:105540003C1808008F183D983C03080094633D9276
+:10555000018A20218F4E09400329F821248F00025F
+:1055600003E32821031968213C010800A42C3D8A8B
+:10557000AF8E00643C010800AC2D3D983C01080052
+:10558000A4253D800E00009E31E4FFFF8F87004878
+:10559000004020213C010800A0273D918E420008D8
+:1055A00024E80001AF8800480040F809000000002E
+:1055B0009344010B8F4C002C974A09083C0B000EBA
+:1055C000034B40213149FFFF000919C08F8B005068
+:1055D000AF43002C974309089506001A0040382174
+:1055E000308A004030DFFFFFAC5F00008D19001CE7
+:1055F00000404821AC5900048D180020AC58000828
+:10560000910F001931E30003107300F00000000057
+:10561000286200021440010924050002106500FD03
+:10562000240D0003106D010D00000000114000D991
+:10563000000000003C0A0800954A3D862542000112
+:10564000934D093493580921950E002A31A300FF88
+:1056500000032082331F00FF9798005800047E004B
+:10566000001FCC0001F940253049FFFF010910253A
+:1056700001D830213C0540000045502500066C0053
+:10568000ACED0004ACEA0000934309203C040006A2
+:1056900024ED00140003FE0003E4C825ACF9000863
+:1056A0008F49092C270F000131EE7FFFACE9000C78
+:1056B0008F480930A78E005824E90028ACE8001074
+:1056C0008F45093801204021ACE50014ADAB000442
+:1056D0008F420940ADA20008934B09373C1F0800D8
+:1056E00093FF3D908F4309488F4A0940316600FF80
+:1056F00000D42021006A78230004C700001FCC00DA
+:105700000319282531EEFFFC00AE1025ADA2000CD8
+:10571000ADA00010AF4C002C934C093E318B00081B
+:105720005160000F8E58000C3C06010134CA080A73
+:10573000ACEA00288F4B0074AD2B00043C0C080031
+:10574000918C3D903187001050E00003AD2000089F
+:105750008F620060AD2200082528000C8E58000CD6
+:105760000300F809010020213C19080097393D8AFF
+:105770003C1F080097FF3D7E033F782125E900028A
+:105780000E0000C73124FFFF3C0E08008DCE3D6C9B
+:105790003C0808008D083D7401C828233C0108001E
+:1057A000AC253D6C14A00006000000003C0308007E
+:1057B0008C633D8C346400403C010800AC243D8C7B
+:1057C000120000708F8C00448F470E108F900044A1
+:1057D000AE0700208F4D0E18AE0D00243C100800BF
+:1057E00096103D800E000060000000002402004082
+:1057F000AF4208148F8600508F8A004C00D01821C9
+:10580000006A582319600004AF830050AF6300544E
+:105810008F650054AF85004C1200000C00000000A2
+:105820008F440074936800813409FA002D0E00073C
+:1058300011C0000500891821937F0081241901F40B
+:1058400003F9780401E41821AF63000C8F44095C6C
+:105850008F83005C0083C0231B0000030000000056
+:105860008F50095CAF90005C0E00006200000000E9
+:105870008F8C00508E4700103C010800AC2C3D94EA
+:1058800000E0F809000000003C0D08008DAD3D6C03
+:1058900055A0FEF5240700068F45002497590908F6
+:1058A0008F8B00648F9400503C0F001F978200582C
+:1058B0008F8600548F93004C3328FFFF35E9FF801B
+:1058C00000A95024000871C032320100AF4E0024FC
+:1058D000A4C2002CAF4A0024AF6B0044AF74005048
+:1058E000AF73005416400080323800105700008615
+:1058F0008EA40004322300405460001B8EB10008C7
+:105900008EB0000C0200F809000000008FBF0030CC
+:105910008FB5002C8FB400288FB300248FB20020E5
+:105920008FB1001C8FB0001803E0000827BD0038BD
+:10593000934701098F8800380007FE0003E8C82557
+:10594000AF5900808F5809A08F5309A4AFB8001039
+:10595000AF580E148FB40010AF540E10AF530E1C7E
+:105960000A000962AF530E180220F8090000000077
+:105970008EB0000C0200F809000000000A000AA81E
+:105980008FBF0030A5800020A59300220A000A5B8B
+:10599000AD9300243C09080095293D863C0608008B
+:1059A00094C63D800A0009F4012610213C0108003C
+:1059B000AC203D700A00098E8E4200003C010800B8
+:1059C000AC243D700A00098E8E4200003C030800A2
+:1059D00094633D8A3C04080094843D803C1F080089
+:1059E00097FF3D7C951800240064C821033F78236D
+:1059F00000186C0025EEFFF201AE2825AC45000C26
+:105A000024020800ACE20014ACE000100A0009EF28
+:105A100024E70018950600249509002800062400B4
+:105A200000091C00349F810034790800ACFF000C91
+:105A3000ACF900100A0009EF24E700141460FEFB23
+:105A4000000000009518002400187C0035EE0800C6
+:105A5000ACEE000C0A0009EF24E700103C07080038
+:105A600094E73D803C04080094843D8A3C03080090
+:105A700094633D7C95190024951800280087F8212F
+:105A800003E378232407080000192C0000186C0099
+:105A900025EEFFEE01AE302534A28100AD270018BF
+:105AA0002527001CAD22000CAD2600100A0009EFCE
+:105AB000AD20001493520109000028210E000602B7
+:105AC000324400FF8FBF00308FB5002C8FB4002808
+:105AD0008FB300248FB200208FB1001C8FB000184C
+:105AE00003E0000827BD0038935F010933E400FF9D
+:105AF0000E00066D00002821323800105300FF7E92
+:105B0000322300408EA400040080F8090000000049
+:105B10000A000AA2322300401200FF5F00000000CA
+:105B20008F540E148F920044AE5400208F530E1CDD
+:105B30000A000A8AAE5300248F82001C0080402194
+:105B40003C0401009047008530E30020106000090C
+:105B5000000000003C0708008CE73D948F8300188C
+:105B600000E32023048000089389000414E3000369
+:105B70000100202103E00008008010213C04010006
+:105B800003E00008008010211120000B006738237B
+:105B90008F8C002024090034918B00BC316A0002F4
+:105BA000514000012409003000E9682B15A0FFF1E5
+:105BB0000100202100E938232419FFFC00B9C0248A
+:105BC00000F9782400F8702B15C0FFEA01E82021C5
+:105BD00030C200030002182314C000123069000311
+:105BE0000000302100A9702101C6682100ED602B62
+:105BF0001180FFE03C0401002D2F00010006482B1E
+:105C00000105382101E9302414C0FFDA24E4FFFC47
+:105C10002419FFFC00B9C0240308202103E0000878
+:105C2000008010218F8B002024060004916A00BCA4
+:105C3000314400041480FFEC00A970210A000B5EBF
+:105C40000000302127BDFFE8AFBF00108F460100E4
+:105C5000934A01093C1F08008FFF00902407FF8032
+:105C6000314F00FF31E8007F0008614003E6C821A2
+:105C7000032CC02127090120012770243C010800C2
+:105C8000A02F3DD0AF4E080C3C0D08008DAD00900C
+:105C90003C0400803482000301A65821016C1821C5
+:105CA0002465012030AA007801424025AF48081C35
+:105CB0003C1F08008FFF00908F88004003E6C02142
+:105CC0003319000703074824033A7821AF49002815
+:105CD00025E909C0952E00023C0D08008DAD008C11
+:105CE0003C0A08008D4A009031CC3FFF01A61821E4
+:105CF000000C5980006B282100A72024AF44002C01
+:105D0000952200023C1F08008FFF008C9107008540
+:105D100030593FFF03E678210019C1800146702108
+:105D200001F8682131CC007F31AB007F019A282136
+:105D3000017A50213C03000C3C04000E00A32821F2
+:105D40000144102130E6002027470980AF82002C53
+:105D5000AF88001CAF890024AF85002010C000066A
+:105D6000AF8700288D0200508CA4010C0044302322
+:105D700018C0007700000000910C0085240DFFDFA3
+:105D8000018D3824A10700858F8B001C8F8900248A
+:105D90008F8700288D65004CAF850018912F000D6E
+:105DA00031EE002011C0001700000000240900019E
+:105DB000A3890004AF80000C8CE400248F85000CC4
+:105DC000240A0008AF800008AF8000103C010800E2
+:105DD000A42A3D7E3C010800A4203D920E000B3217
+:105DE000000030218F8500248FBF0010AF82001487
+:105DF00090A8000D27BD00180008394203E00008F4
+:105E000030E20001913F00022418000133F900FF45
+:105E10000019218210980039240800021088005BC4
+:105E20008F86002C8CE5002414A0001B8F9F00207F
+:105E300091220000240A00053046003F10CA0047A6
+:105E4000240400018F860008A3840004AF8600109C
+:105E5000AF86000C8CE400248F85000C240A000817
+:105E60003C010800A42A3D7E3C010800A4203D928C
+:105E70000E000B32000000008F8500248FBF001041
+:105E8000AF82001490A8000D27BD00180008394209
+:105E900003E0000830E200018CF800088CF90024CF
+:105EA0008FEE00C4A38000048CE40024AF8E000CAD
+:105EB0008F85000C8F86000803197823240A0008B8
+:105EC000AF8F00103C010800A42A3D7E3C01080071
+:105ED000A4203D920E000B32000000008F850024AC
+:105EE0008FBF0010AF82001490A8000D27BD0018CE
+:105EF0000008394203E0000830E20001912300006D
+:105F00003062003F104400278F8500208CE400247D
+:105F100014800021000000008D2E00183C187FFF27
+:105F20008F850020370FFFFF01CF1824AF830008B3
+:105F30008F9F00088CA8008403E8C82B172000025C
+:105F400003E020218CA400840A000BEDAF8400083C
+:105F50008CA3010C0A000BCBAF8300188D2C00180A
+:105F60008F8600083C0D7FFF8F89002035A3FFFF3F
+:105F70000183582424040001AF8B0010AD2000CC15
+:105F8000A38400040A000BF9AF86000C8CCA00142D
+:105F90000A000BEDAF8A00088CA300C80A000C3081
+:105FA000AF8300088F84002C8CAC00648C8D0014AF
+:105FB000018D582B11600004000000008CA20064C9
+:105FC0000A000C30AF8200088C8200140A000C30EA
+:105FD000AF8200088F85000C27BDFFE0AFBF00181F
+:105FE000AFB1001414A00007AFB000108F860024DA
+:105FF0002402000590C400003083003F106200B608
+:106000008F8400208F91000800A080218F8C0028B1
+:106010003C0508008CA53D708D8B000431663FFF68
+:1060200000C5502B5540000100C02821938D00046D
+:1060300011A0007300B0F82B8F98002024040034C6
+:10604000930F00BC31EE000251C000012404003067
+:1060500000A4C82B172000D10000000000A42823B2
+:1060600000B0F82B3C010800A4243D7C17E0006838
+:10607000020020213C0308008C633D6C0083102B40
+:1060800054400001008018218F8800243C01080042
+:10609000AC233D74000048219104000D30830020A2
+:1060A000506000018F490E188F8300140123382B94
+:1060B00010E00059000000003C0408008C843D748E
+:1060C00000895821006B502B114000560090602B26
+:1060D0000069302300C020213C010800AC263D743B
+:1060E00012000003241FFFFC1090008A32270003D7
+:1060F000009FC8243C010800AC393D743C010800F5
+:10610000A4203D928F84000C120400078F8300208E
+:10611000AF910008020020218C7100CCAF90000CE0
+:1061200026300001AC7000CC3C0208008C423D746B
+:106130008F8A0010240700180082202301422823A0
+:10614000AF84000C10800002AF85001024070010FF
+:106150008F86001C3C010800A0273D9024070040CA
+:1061600090CC0085318B00C0116700408F8D0014EA
+:1061700014A0001500002021934A01098F420974E0
+:10618000314500FF0002260224A300013090007F69
+:106190003071007F1230007A2407FF80A0C3008393
+:1061A0003C0908008D293D8C8F880024240D0002B5
+:1061B000352C00083C010800A02D3DD13C01080011
+:1061C000AC2C3D8C24040010910E000D31C6002033
+:1061D00010C0000500801821240800013C010800BF
+:1061E000AC283D74348300018FBF00188FB10014B8
+:1061F0008FB000100060102103E0000827BD0020D0
+:106200003C010800A4203D7C13E0FF9A02002021FD
+:106210000A000C8100A020213C0408008C843D74FD
+:106220000090602B1180FFAE000000003C0F0800C2
+:1062300095EF3D7C01E4702101C6682B11A0000799
+:106240002C8200043C1F60008FF954043338003F57
+:106250001700FFE5240300422C8200041040FFA039
+:10626000240300420A000CDF8FBF0018152DFFC069
+:10627000000000008CDF00743C0380002405FF80D8
+:1062800003E3C825ACD9007490D80085240E00041F
+:1062900024040010330F003F01E54025A0C800850D
+:1062A0008F8800243C010800A02E3DD1240300016A
+:1062B0009106000D30C900201520000300000000E9
+:1062C0003C0308008C633D743C010800AC233D6C2A
+:1062D0000A000CD6000000008F8700108C88008414
+:1062E00000E8282B14A0000200E088218C91008493
+:1062F00024090001A38900048F440E1802202821DC
+:106300000E000B3202203021022080210A000C678F
+:10631000AF82001400071823306600033C01080018
+:10632000A4263D92122000058F8C0020918B00BC8A
+:10633000316A00041540001524CD00043C0F08000C
+:1063400095EF3D9201E4702100AE302B50C0FF6EFE
+:106350008F84000C2C85000514A0FFA324030042A9
+:106360003098000317000002009818232483FFFCD4
+:106370003C010800AC233D740A000CA3000000009F
+:1063800000A758240A000CCB016718263C0108001E
+:10639000A42D3D920A000D33000000003C010800CE
+:1063A000AC203D740A000CDE240300428F830010F1
+:1063B00014600007000010218F88002424050005C8
+:1063C0009106000030C400FF1085000300000000AB
+:1063D00003E0000800000000910A0018314900FFA6
+:1063E000000939C214E0FFFA8F85001C3C04080044
+:1063F00094843D7C3C0308008C633D943C19080068
+:106400008F393D743C0F080095EF3D920064C02128
+:106410008CAD00540319702101CF6021018D5823E8
+:106420001960001D00000000910E001C8F8C002CD4
+:10643000974B0E1031CD00FF8D850004016D302388
+:106440008D88000030CEFFFF000E510000AAC82149
+:106450000000382101072021032A182B0083C021C6
+:10646000AD990004AD980000918F000A01CF68211A
+:10647000A18D000A8F88002C974B0E12A50B0008E7
+:10648000950A003825490001A50900389107000D3B
+:1064900034E60008A106000D03E00008000000003B
+:1064A00027BDFFE0938700048F8F00248FAD001479
+:1064B0003C0E7FFF8F89000C35C8FFFFAFBF001C6B
+:1064C000AFB0001801A8182491EA000D000717C00A
+:1064D0003C1FBFFF006258252D2E00018F90001831
+:1064E00037F9FFFF3C1808008F183D943C0F080057
+:1064F00095EF3D8A01796824000E47803C07EFFF45
+:106500003C05F0FF01A818253149002034E2FFFFC7
+:1065100034ACFFFF0310582327A500102406000207
+:1065200025EA000200621824008080211520000264
+:10653000000040218F480E1CA7AA001205600037FA
+:106540002407000030FF00FF001FCF008F8B001CCE
+:1065500000793825AFA70014916F00853C0808002A
+:1065600091083D913C18DFFF31EE00C0370AFFFF74
+:10657000000E182B3C1F080097FF3D8400EA68249A
+:10658000A3A800110003174001A248258FB90010ED
+:10659000AFA900143C0A0800914A3D93A7BF00161A
+:1065A0008FA80014032CC0243C0B01003C0F0FFFEC
+:1065B000030B18253147000335EEFFFF010C68245B
+:1065C00000071600006EF8243C09700001A2C825DF
+:1065D00003E95825AFB90014AFAB00100E000076E8
+:1065E000A3A000158F8C0024260200089186000DC0
+:1065F00030C40020108000068FBF001C3C0508003E
+:1066000094A53D8024B0FFFF3C010800A4303D80EC
+:106610008FB0001803E0000827BD00208F980014F9
+:106620000118502B5540FFC7240700010A000DB682
+:1066300030FF00FF9382000427BDFFE0AFBF0018CA
+:106640001040000F008050218F880024240B00058B
+:106650008F890008910700008F8400200100282105
+:1066600030E3003F8F86002C106B000800003821BB
+:10667000AFA900100E00040EAFAA0014A3800004FE
+:106680008FBF001803E0000827BD00208D190018F7
+:106690003C0F08008DEF3D748F9800103C027FFF87
+:1066A0008D080014345FFFFF033F682401F8702158
+:1066B00001AE602301883821AFA900100E00040E3E
+:1066C000AFAA00140A000E04A38000048F870024E0
+:1066D0003C05080094A53D923C0208008C423D8C8C
+:1066E00090E6000D0005240030C300201060002C4F
+:1066F000004440258F85001C00006021240B000110
+:1067000090A3008500004821240A00013C0F80006E
+:1067100035EE00708DC70000AF8700308F580178CC
+:106720000700FFFE3C038000347900708F380000C2
+:106730003C0508008CA500743C0D08008DAD007070
+:106740000307782300AF38210000102100EF302B21
+:1067500001A22021008618213C010800AC2700740A
+:106760003C010800AC230070AF4B01483C19080005
+:106770008F393D94A7490144A74A0146AF59014CBE
+:106780003C0B0800916B3D91A34B0152AF48015463
+:106790003C081000A74C015803E00008AF480178FE
+:1067A0008F4B0E1C3C0A08008D4A3D7497490E160B
+:1067B000974D0E1401456021312AFFFF0A000E2774
+:1067C00031A9FFFF8F8300249064000D30820020E8
+:1067D0001040002900000000000048210000502166
+:1067E000000040213C07800034EB00708D67000002
+:1067F000AF8700308F4C01780580FFFE3C0D800094
+:1068000035AC00708D8B00003C0508008CA5007431
+:106810003C0408008C8400700167302300A67821B6
+:106820000000102101E6C82B0082C021031970214D
+:106830003C010800AC2F00743C010800AC2E007035
+:10684000AF4901483C0D08008DAD3D94A748014477
+:1068500024090040A74A01463C081000240AFF9181
+:10686000AF4D014CA34A0152AF490154A740015812
+:1068700003E00008AF4801788F490E1897460E12C2
+:1068800097450E1030CAFFFF0A000E5D30A8FFFFCB
+:106890008F83002427BDFFF89064000D3082002014
+:1068A0001040003A00000000240B000100004821C5
+:1068B000240A00013C088000350700708CE30000CA
+:1068C000AF8300308F4C01780580FFFE3C0E8000C6
+:1068D0003C04080090843DD035C700708CEC00006B
+:1068E0003C0508008CA50074A3A400033C19080013
+:1068F0008F3900708FAD00000183302300A638214E
+:10690000000010210322782100E6C02B01F860214D
+:1069100001AE4025AFA800003C010800AC27007480
+:106920003C010800AC2C00709346010A3C040800AE
+:1069300090843DD1A3A00002A3A600018FA3000074
+:106940003C0580FF3099007F34A2FFFF006278246D
+:106950000019C60001F87025240D3000AF4E014C1F
+:1069600027BD0008AF4D0154A7400158AF4B014867
+:10697000A7490144A74A01463C091000240AFF80A8
+:10698000A34A015203E00008AF4901788F4B0E186B
+:1069900097460E1297450E1030CAFFFF0A000E915F
+:1069A00030A9FFFF8F85001C2402008090A4008581
+:1069B000308300C0106200058F8600208F88000899
+:1069C0008F87000CACC800C8ACC700C403E0000847
+:1069D000000000003C0A0800254A39543C09080020
+:1069E00025293A203C08080025082DD43C0708003A
+:1069F00024E73B343C06080024C637C43C050800A5
+:106A000024A5353C3C040800248431643C03080080
+:106A10002463385C3C020800244236303C01080004
+:106A2000AC2A3D503C010800AC293D4C3C0108001B
+:106A3000AC283D483C010800AC273D543C0108000F
+:106A4000AC263D643C010800AC253D5C3C010800DF
+:106A5000AC243D583C010800AC233D683C010800D3
+:0C6A6000AC223D6003E0000800000000D4
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex b/firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex
deleted file mode 100644
index 627baec7cb5c..000000000000
--- a/firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex
+++ /dev/null
@@ -1,6081 +0,0 @@
-:100000000800011008000000000051F8000000C8BE
-:10001000000000000000000000000000080051F88F
-:1000200000000038000052C00800008808000000EE
-:100030000000528C000052F8080054800000008438
-:100040000000A5840800528C000001C00000A60832
-:10005000080031D808000000000081080000A7C88F
-:1000600000000000000000000000000008008108FF
-:1000700000000124000128D00800048808000400C2
-:10008000000017EC000129F400000000000000004F
-:100090000000000008001BEC00000004000141E02B
-:1000A000080000A808000000000038D0000141E46A
-:1000B000000000000000000000000000080038D030
-:0800C0000000003000017AB4D9
-:0800C8000A00004400000000E2
-:1000D000000000000000000D636F6D352E302E30E3
-:1000E0006A31350005000002000000000000000336
-:1000F00000000014000000320000000300000000B7
-:1001000000000000000000000000000000000000EF
-:1001100000000010000001360000EA600000000549
-:1001200000000000000000000000000000000008C7
-:1001300000000000000000000000000000000000BF
-:1001400000000000000000000000000000000000AF
-:10015000000000000000000000000000000000009F
-:10016000000000020000000000000000000000008D
-:10017000000000000000000000000000000000007F
-:10018000000000000000000000000010000000005F
-:10019000000000000000000000000000000000005F
-:1001A000000000000000000000000000000000004F
-:1001B000000000000000000000000000000000003F
-:1001C000000000000000000000000000000000002F
-:1001D000000000000000000000000000100000030C
-:1001E000000000000000000D0000000D3C020800AF
-:1001F000244252603C0308002463539CAC4000003E
-:100200000043202B1480FFFD244200043C1D080005
-:1002100037BD9FFC03A0F0213C1008002610011000
-:100220003C1C0800279C52600E00026B000000007E
-:100230000000000D27BDFFE0AFBF0018AFB10014F4
-:10024000AFB000103C04800094820108304370007D
-:10025000240220001062000B2862200114400036A6
-:1002600000001021240240001062002C0000000059
-:10027000240260001062002D000010210A00009D81
-:100280008FBF001834910100922400098E300018AD
-:1002900010800020240300012402000914820006BB
-:1002A0008F8200243C0280089442001A000214004D
-:1002B000020280258F8200248C42000C1040001521
-:1002C000000018210E000D52000000008F83002452
-:1002D000962400088F8200209463001E9625000C4F
-:1002E0000004240000832025AC500000AC4500042D
-:1002F000AC400008AC40000CAC400010AC40001416
-:10030000AC400018AC44001C0E000D862404000113
-:10031000000018210A00009C006010210E00043B20
-:10032000000000000A00009C000010210E000C726A
-:1003300000000000000010218FBF00188FB10014D2
-:100340008FB0001003E0000827BD00208F8200243A
-:1003500027BDFFE0AFB00010AFBF0018AFB1001471
-:100360008C42000C3C1080008E11010010400034C3
-:100370008FBF00180E000D52000000008F85002076
-:1003800024047FFF0091202BACB100008E030104F8
-:100390009602010800031C003042FFFF006218258E
-:1003A000ACA300049202010A96030114304200FF3C
-:1003B0003063FFFF0002140000431025ACA20008C8
-:1003C0009603010C9602010E00031C003042FFFF51
-:1003D00000621825ACA3000C9603011096020112CE
-:1003E00000031C003042FFFF00621825ACA3001080
-:1003F0008E020118ACA200148E02011CACA20018DF
-:10040000148000088F820024978200003C0420059D
-:100410000044182524420001ACA3001C0A0000DBA4
-:10042000A78200003C0340189442001E00431025A0
-:10043000ACA2001C0E000D86240400018FBF001822
-:100440008FB100148FB000100000102103E00008ED
-:1004500027BD00203C0680008CC202B824030001A6
-:1004600004410008008028213C0208008C42006002
-:10047000244200013C010800AC22006003E00008B7
-:10048000006010218C83002094820016ACC302808F
-:100490002442FFFCA4C202843C0208008C42005C9F
-:1004A0008C84000494A3000E244200013C01080047
-:1004B000AC22005C3C021000A4C30286ACC40288DB
-:1004C00000001821ACC202B803E00008006010214F
-:1004D00027BDFFE0AFB000103C108000AFB20018A5
-:1004E000AFBF001CAFB10014361201009243000BE5
-:1004F0002402001A965100081462005A00002821B4
-:1005000032220001104000188F8200248E42000029
-:10051000000223403C02003F3442FFFF0044102B06
-:10052000104000043C030040964200140A000124DD
-:10053000008320218E030100240201005462000682
-:10054000964200143C028008904200043042000FA2
-:10055000000225009642001400821025AE020080A1
-:100560000A000157000000008C42000C10400028D7
-:10057000000000000E000D5200000000960201086D
-:100580009603010C8F8500203042003E3063FFFF50
-:100590000002140000431025ACA200008E020100EE
-:1005A000ACA20004960301169604010E8F8200246B
-:1005B00000031C003084FFFF00641825ACA3000872
-:1005C00096030110960401129446001E00031C00BD
-:1005D0003084FFFF00641825ACA3000C3C0220000F
-:1005E00000C2302596020114240400013042FFFFAE
-:1005F000ACA200108E020118ACA200149202010BF2
-:10060000304200FFACA200180E000D86ACA6001C04
-:100610003C0208008C420040244200013C010800DA
-:10062000AC2200403C0308008C63004432220002EC
-:1006300032240004246300013C010800AC23004480
-:10064000108000080002282B024020218FBF001CD0
-:100650008FB200188FB100148FB000100A0000E3B1
-:1006600027BD00208FBF001C8FB200188FB100146F
-:100670008FB0001000A0102103E0000827BD00206B
-:1006800027BDFFE0AFB000103C108000AFB20018F3
-:10069000AFBF001CAFB10014361201009243000B33
-:1006A00024020003965100081462007500002821FE
-:1006B00032220001104000178F8200248E43000078
-:1006C0003C02003F3442FFFF000323400044102B54
-:1006D0005040000524020100964200143C030040F3
-:1006E0000A00018F00832021546200069642001404
-:1006F0003C028008904200043042000F00022500B6
-:100700009642001400821025AE0200800A0001BF4C
-:10071000000000008C42000C10400025000000008A
-:100720000E000D5200000000960201089603010C15
-:100730008F8500203042003E3063FFFF000214002E
-:1007400000431025ACA200008E020100ACA2000400
-:10075000960301169604010E8F82002400031C00EC
-:100760003084FFFF00641825ACA300089603011035
-:10077000960401129446001E00031C003084FFFF03
-:1007800000641825ACA3000C3C02200000C23025F8
-:1007900096020114240400013042FFFFACA20010B5
-:1007A000ACA00014ACA000180E000D86ACA6001C76
-:1007B0003C0208008C420040244200013C01080039
-:1007C000AC2200403C0208008C420044322300046A
-:1007D000244200013C010800AC22004410600008E3
-:1007E00032220002024020218FBF001C8FB200186D
-:1007F0008FB100148FB000100A0000E327BD002065
-:100800001040001F000028213C05800034A2007029
-:100810008C4400008F82000C008210232C43012C9A
-:1008200010600004AF820010240500010A0001EEF0
-:10083000AF84000C8CA301043C026020AC43001484
-:100840008C420004240301FE304203FF1443000BDA
-:10085000AF84000C8CA20100000219C22462FFFCCC
-:100860002C42000810400003240400022462FFFD13
-:10087000004420043C026000AC44691400002821BC
-:100880008FBF001C8FB200188FB100148FB0001002
-:1008900000A0102103E0000827BD00203C048000D8
-:1008A0008C83010024020100506200033C02800896
-:1008B0000000000D3C02800890430004000010215D
-:1008C0003063000F00031D0003E00008AC830080CC
-:1008D0002C8407811080000A000028213C0280003F
-:1008E00094420108240320003042700014430005A4
-:1008F0002783FFA43C02800890420005304500FF9A
-:100900002783FFA40005208000832021000510C05C
-:10091000004510238C8400003C0308002463532C02
-:10092000000210C0004310213C038000AC64009022
-:1009300003E00008AF82002403E00008000010215B
-:1009400003E00008000010212402010014820008C6
-:10095000000000003C0208008C4200FC2442000120
-:100960003C010800AC2200FC0A00023030A200204A
-:100970003C0208008C420084244200013C01080033
-:10098000AC22008430A200201040000830A30010E8
-:100990003C0208008C420108244200013C0108008E
-:1009A000AC22010803E0000800000000106000080D
-:1009B000000000003C0208008C42010424420001B7
-:1009C0003C010800AC22010403E000080000000024
-:1009D0003C0208008C420100244200013C01080056
-:1009E000AC22010003E000080000000027BDFFE882
-:1009F000AFB000103C108000AFBF001436040100FF
-:100A00009483000830620004104000053066000244
-:100A10008FBF00148FB000100A0000E327BD00183C
-:100A200010C00006006028218E0401000E00022084
-:100A3000000000000A000267240200018F82000803
-:100A40008E03010410430007000010218E040100F2
-:100A50000E000220000000008E020104AF82000898
-:100A6000000010218FBF00148FB0001003E00008B9
-:100A700027BD001827BDFFD83C036010AFB3001C92
-:100A8000AFBF0020AFB20018AFB10014AFB000107C
-:100A90008C6450002402FF7F3C13080026735290A0
-:100AA000008220243484380CAC6450003C02800066
-:100AB00024030037AC4300083C06080024C6087035
-:100AC000026010212404001C2484FFFFAC460000B7
-:100AD0000481FFFD244200043C0208002442016C12
-:100AE0003C010800AC2252983C020800244205B8A0
-:100AF0003C010800AC22529C3C02080024420284C3
-:100B00003C010800AC2252D83C02080024420408F0
-:100B10003C030800246308783C040800248409246A
-:100B20003C05080024A52C803C010800AC2252F8AA
-:100B30003C020800244207D43C010800AC2652E0E5
-:100B40003C010800AC2552EC3C010800AC2352F4F7
-:100B50003C010800AC2452FC3C010800AC225300CC
-:100B60003C010800AC2352943C010800AC2052A088
-:100B70003C010800AC2052A43C010800AC2052A863
-:100B80003C010800AC2052AC3C010800AC2052B043
-:100B90003C010800AC2052B43C010800AC2052B823
-:100BA0003C010800AC2452BC3C010800AC2052C0FF
-:100BB0003C010800AC2052C43C010800AC2052C8E3
-:100BC0003C010800AC2052CC3C010800AC2052D0C3
-:100BD0003C010800AC2652D43C010800AC2652DC93
-:100BE0003C010800AC2052E43C010800AC2552E86E
-:100BF0003C010800AC2352F00E0005670000000025
-:100C0000AF80000C8F8300043C0208008C4200205F
-:100C10001062001F000088212792FFA43C100800EA
-:100C20002610532C3C0208008C42002024050001B1
-:100C300002251804004320248F820004004310245E
-:100C40005044000C2631000110800008AF900024B1
-:100C50008E4300003C028000AC4300900E000D1952
-:100C6000AE05000C0A0002EB26310001AE00000CBC
-:100C7000263100012E220002261000381440FFE920
-:100C8000265200043C0208008C420020AF8200047F
-:100C90003C1080008E110000322200071040FFDA65
-:100CA0008F83000432220001104000213222000212
-:100CB0008E020100AE0200208E020104AE0200A8E6
-:100CC0000E0002028E0401009202010B304300FF6D
-:100CD0002C62001D54400004000310800E00021C12
-:100CE0000A00030C00000000005310218C42000099
-:100CF0000040F80900000000104000043C028000A1
-:100D00008C4301043C026020AC4300143C02080008
-:100D10008C4200343C0440003C038000244200012B
-:100D2000AC6401383C010800AC22003432220002DD
-:100D300010400010322200043C1080008E0201405E
-:100D4000AE0200200E0002028E0401400E0003A439
-:100D5000000000003C024000AE0201783C020800A6
-:100D60008C420038244200013C010800AC220038CB
-:100D7000322200041040FFA48F8300043C10800046
-:100D80008E020180AE0200200E0002028E0401805D
-:100D90008E03018024020F00146200073C028008C9
-:100DA0008E0201883C0300E03042FFFF0043102523
-:100DB0000A000348AE0200803442008090420000E6
-:100DC00024030050304200FF1443000700000000DD
-:100DD0000E0003810000000014400003000000002A
-:100DE0000E00096A000000003C0208008C42003C32
-:100DF0003C0440003C03800024420001AC6401B884
-:100E00003C010800AC22003C0A0002D08F830004A1
-:100E10003C02900034420001008220253C02800008
-:100E2000AC4400203C0380008C6200200440FFFEA4
-:100E30000000000003E00008000000003C02800009
-:100E4000344300010083202503E00008AC44002067
-:100E500027BDFFE0AFB10014AFB0001000808821C3
-:100E6000AFBF00180E00035230B000FF8F83FF9C0D
-:100E7000022020219062002502028025A07000251A
-:100E80008C7000183C0280000E00035D020280247A
-:100E90001600000A8FBF00183C0380008C6201F826
-:100EA0000440FFFE24020002AC7101C0A06201C434
-:100EB0003C021000AC6201F88FBF00188FB1001423
-:100EC0008FB0001003E0000827BD002027BDFFE819
-:100ED000AFBF00103C0380009462018430420200E6
-:100EE00010400005000020210E000FDA0000000075
-:100EF0000A000397240400018C6201880440000A60
-:100F00008FBF00108C6201883C03FF000043102457
-:100F10003C03040014430004240400018F82FF9C5E
-:100F2000904200088FBF00100080102103E00008ED
-:100F300027BD00188F82FFA02403000124050001B3
-:100F4000A040001A8F82FF9CA44300163C02800040
-:100F50000A0003628C4401408F85FF9C27BDFFE09F
-:100F6000AFBF001CAFB20018AFB10014AFB000109B
-:100F700090A20000304400FF388300203882003007
-:100F80000003182B0002102B0062182410600005CB
-:100F90003C02800024020050148200818FBF001C9C
-:100FA0003C02800090420148304200FF2443FFFF92
-:100FB0002C6200051040007A8FBF001C00031080D7
-:100FC0003C03080024635210004310218C420000AF
-:100FD00000400008000000003C1180008E24014009
-:100FE0000E0003528F92FF9C8E50000C8E22014403
-:100FF0001602000224020001AE42000C0E00035D46
-:101000008E2401408E220144145000068FBF001C24
-:101010008FB200188FB100148FB000100A000F4675
-:1010200027BD00208E42000C0A00042F00000000A3
-:1010300094A200103C0480008C8301443042FFFFE6
-:10104000146200090000000024020001A4A20010A4
-:101050008C820140AC8202003C021000AC8202385B
-:101060000A0004368FBF001C94A200100A00042F4F
-:1010700000000000240200201482000E3C118000B9
-:1010800094A200123C0380008C6301443042FFFFB5
-:10109000146200050000000024020001A4A2001256
-:1010A0000A0004098FBF001C94A200120A00042F3A
-:1010B000000000008E2401400E0003528F92FF9C1E
-:1010C000964200128E2301443050FFFF16030002A7
-:1010D00024020001A64200120E00035D8E2401408E
-:1010E0008E220144160200068FBF001C8FB200182A
-:1010F0008FB100148FB000100A00039B27BD0020A1
-:10110000964200120A00042F0000000094A200146E
-:101110003C0380008C6301443042FFFF14620008EE
-:101120008FBF001C240200018FB200188FB1001481
-:101130008FB00010A4A200140A00143127BD0020B3
-:1011400094A200140A00042F0000000094A20016CC
-:101150003C0380008C6301443042FFFF14620008AE
-:10116000240200018FBF001C8FB200188FB1001441
-:101170008FB00010A4A200160A000B0D27BD00209E
-:1011800094A20016144000068FBF001C3C02080009
-:101190008C420070244200013C010800AC22007027
-:1011A0008FB200188FB100148FB0001003E0000858
-:1011B00027BD002027BDFFD8AFB200188F92FF9C3B
-:1011C000AFB10014AFBF0020AFB3001CAFB0001030
-:1011D0003C028000345101008C500100924200001A
-:1011E00092230009304400FF2402001F106200AB6C
-:1011F0002862002010400019240200382862000AEA
-:101200001040000D2402000B286200081040002E40
-:101210008F82002404600103286200021440002A27
-:101220008F82002424020006106200268FBF002057
-:101230000A0005598FB3001C106200602862000B81
-:10124000144000F98FBF00202402000E10620078C5
-:101250008F8200240A0005598FB3001C106200D150
-:10126000286200391040000A24020080240200365F
-:10127000106200E428620037104000C224020035EA
-:10128000106200D88FBF00200A0005598FB3001CE0
-:101290001062002D2862008110400006240200C860
-:1012A00024020039106200C88FBF00200A000559CF
-:1012B0008FB3001C106200A28FBF00200A000559E6
-:1012C0008FB3001C8F8200248C42000C104000D68B
-:1012D0008FBF00200E000D52000000003C03800074
-:1012E000346301008C6200008F8500209467000841
-:1012F0009466000CACA200008C6400048F82002471
-:1013000000063400ACA400049448001E8C6200184F
-:1013100000073C0000E83825ACA200088C62001CE5
-:1013200024040001ACA2000C9062000A00C2302527
-:10133000ACA60010ACA00014ACA00018ACA7001C18
-:101340000A0005188FBF00208F8200248C42000CF9
-:10135000104000B58FBF00200E000D5200000000AD
-:101360008F820024962400089625000C9443001ECA
-:10137000000422029626000E8F8200200004260020
-:101380000083202500052C003C03008000A62825B2
-:1013900000832025AC400000AC400004AC400008B5
-:1013A000AC40000CAC450010AC400014AC40001840
-:1013B000AC44001C0A000517240400019622000C0E
-:1013C0001440001800000000924200053042001056
-:1013D00014400014000000000E00035202002021FF
-:1013E0009242000502002021344200100E00035DED
-:1013F000A24200059242000024030020304200FF78
-:1014000010430088020020218FBF00208FB3001CF2
-:101410008FB200188FB100148FB000100A00104373
-:1014200027BD00280000000D0A0005588FBF0020CE
-:101430008C42000C1040007C8FBF00200E000D522B
-:10144000000000008E2200048F8400209623000CF0
-:10145000AC8200003C0280089445002C8F8200245E
-:1014600000031C0030A5FFFF9446001E3C02400E06
-:101470000065182500C23025AC830004AC8000084C
-:10148000AC80000CAC800010AC800014AC80001864
-:10149000AC86001C0A000517240400010E0003524C
-:1014A000020020218F93FFA0020020210E00035D87
-:1014B000A660000C020020210E000362240500013A
-:1014C0008F8200248C42000C104000578FBF0020F8
-:1014D0000E000D52000000009622000C8F830020A9
-:1014E00000021400AC700000AC620004AC600008A4
-:1014F0008E4400388F820024AC64000C8E46003C81
-:101500009445001E3C02401FAC66001000A2282536
-:101510008E62000424040001AC620014AC60001868
-:10152000AC65001C8FBF00208FB3001C8FB2001869
-:101530008FB100148FB000100A000D8627BD00285F
-:1015400024020020108200398FB3001C0E000F2CE3
-:1015500000000000104000348FBF00203C038000DA
-:101560008C6201F80440FFFE24020002AC7001C04E
-:10157000A06201C43C021000AC6201F80A000558E8
-:101580008FBF0020020020218FBF00208FB3001CDE
-:101590008FB200188FB100148FB000100A000E75C2
-:1015A00027BD00289625000C020020218FBF0020B7
-:1015B0008FB3001C8FB200188FB100148FB00010D1
-:1015C0000A000E9A27BD0028020020218FB3001CBC
-:1015D0008FB200188FB100148FB000100A000EC532
-:1015E00027BD00289225000D020020218FB3001C8A
-:1015F0008FB200188FB100148FB000100A000F16C0
-:1016000027BD0028020020218FBF00208FB3001CBF
-:101610008FB200188FB100148FB000100A000EEDC9
-:1016200027BD00288FBF00208FB3001C8FB2001889
-:101630008FB100148FB0001003E0000827BD002810
-:101640003C0380008C6202780440FFFE240200020A
-:10165000AC640240A06202443C02100003E00008B7
-:10166000AC620278A380001803E00008A380001990
-:101670003C0380008C6202780440FFFE8F82001CD5
-:10168000AC62024024020002A06202443C0210004C
-:1016900003E00008AC6202783C02600003E000084E
-:1016A0008C425404908300302402000500804021C5
-:1016B0003063003F00004821146200050000502103
-:1016C0009082004C9483004E304900FF306AFFFF47
-:1016D000AD00000CAD000010AD0000249502001418
-:1016E0008D05001C8D0400183042FFFF00491023B7
-:1016F00000021100000237C3004038210086202379
-:1017000000A2102B0082202300A72823AD05001C77
-:10171000AD040018A5090014A5090020A50A0016AB
-:1017200003E00008A50A002203E000080000000012
-:1017300027BDFFD8AFB200183C128008AFB400201C
-:10174000AFB3001CAFB10014AFBF0024AFB00010A6
-:10175000365101003C0260008C4254049222000C7D
-:101760003C140800929400F7304300FF240200016B
-:1017700010620032008098212402000214620035B9
-:10178000365000800E00140B000000009202004C46
-:101790002403FF803C0480003042007F000211C01F
-:1017A000244202400262102100431824AC830094BA
-:1017B000924500089204004C3042007F3C038006B2
-:1017C00014850007004380212402FFFFA22200119C
-:1017D0002402FFFFA62200120A0005CB2402FFFF0D
-:1017E00096020020A222001196020022A6220012D8
-:1017F0008E0200243C048008AE2200143485008050
-:1018000090A2004C34830100A06200108CA2003C26
-:10181000AC6200188C820068AC6200E48C820064C8
-:10182000AC6200E08C82006CAC6200E82402000133
-:10183000A0A200680A0005E73C0480080E001424FA
-:101840000000000036420080A04000680A0005E762
-:101850003C048008A2000068A20000690A00062279
-:101860003C028008348300808C620038348501009B
-:10187000AC62006C24020001A062006990A200C565
-:1018800090830008305100FF3072007F123200193F
-:10189000001111C024420240026210212403FF8083
-:1018A000004318243C048000AC8300943042007F45
-:1018B0003C038006004380218E02000C1040000D86
-:1018C000020020210E000577000000002622000102
-:1018D000305100FF9203003C023410260002102B0E
-:1018E000000210233063007F022288240A0005F1E1
-:1018F000A203003C3C088008350401008C8200D023
-:1019000035070080ACE2003C8C8200D0AD020000C4
-:1019100090E5004C908600C590E3004C908400C593
-:101920002402FF8000A228243063007F308400FF5F
-:1019300000A628250064182A1060000230A500FFC8
-:1019400038A50080A0E5004CA10500093C028008F4
-:101950009043000E344400803C058000A043000A00
-:101960008C8300183C027FFF3442FFFF0062182482
-:10197000AC8300188CA201F80440FFFE00000000B8
-:10198000ACB301C08FBF00248FB400208FB3001C04
-:101990008FB200188FB100148FB000102402000223
-:1019A000A0A201C427BD00283C02100003E00008EB
-:1019B000ACA201F890A2000024420001A0A2000005
-:1019C0003C0308008C6300F4304200FF1443000223
-:1019D00000803021A0A0000090A200008F84001C95
-:1019E000000211C0244202402483004000822021D2
-:1019F0002402FF80008220243063007F3C02800AA2
-:101A0000006218213C028000AC44002403E000087E
-:101A1000ACC3000094820006908300058C85000C06
-:101A20008C8600108C8700188C88001C8C84002009
-:101A30003C010800A422530E3C010800A023530DD2
-:101A40003C010800AC2553143C010800AC26531897
-:101A50003C010800AC2753203C010800AC2853246B
-:101A60003C010800AC24532803E0000800000000FB
-:101A70003C028008344201008C4400343C03800066
-:101A800034650400AC6400388C420038AF8500280F
-:101A9000AC62003C3C020005AC620030000000007B
-:101AA0000000000003E00008000000003C02000607
-:101AB000308400FF008220253C028000AC440030CE
-:101AC0000000000000000000000000003C03800057
-:101AD0008C620000304200101040FFFD34620400B0
-:101AE00003E00008AF82002894C200003C08080010
-:101AF000950800CA30E7FFFF00804821010210214D
-:101B0000A4C2000094C200003042FFFF00E2102B8C
-:101B100054400001A4C7000094A200003C03080048
-:101B20008C6300CC24420001A4A2000094A2000017
-:101B30003042FFFF144300073C0280080107102BCE
-:101B4000A4A000005440000101003821A4C70000F7
-:101B50003C028008344601008CC3002894A2000097
-:101B60003C0480003042FFFE000210C000621021E1
-:101B7000AC82003C8C82003C006218231860000498
-:101B8000000000008CC200240A0006B324420001B9
-:101B90008CC20024AC8200383C0200503442001059
-:101BA0003C038000AC620030000000000000000038
-:101BB000000000008C620000304200201040FFFD59
-:101BC0000000000094A200003C04800030420001AC
-:101BD000000210C0004410218C430400AD2300001B
-:101BE0008C420404AD2200043C02002003E0000803
-:101BF000AC82003027BDFFE0AFB20018AFB10014D7
-:101C0000AFB00010AFBF001C94C2000000C0802124
-:101C10003C120800965200C624420001A6020000B1
-:101C20009603000094E2000000E030211443000518
-:101C30008FB100300E000688024038210A0006EA03
-:101C4000000000008C8300048C82000424420040C9
-:101C500004610007AC8200048C820004044000048C
-:101C6000000000008C82000024420001AC820000D1
-:101C7000960200003042FFFF50520001A600000013
-:101C80009622000024420001A62200003C028008A7
-:101C900034420100962300009442003C14430004A7
-:101CA0008FBF001C24020001A62200008FBF001C71
-:101CB0008FB200188FB100148FB0001003E000083D
-:101CC00027BD002027BDFFE03C028008AFBF001801
-:101CD000344201008C4800343C0380003469040025
-:101CE000AC6800388C42003830E700FFAF8900282C
-:101CF000AC62003C3C020005AC6200300000000019
-:101D000000000000000000000000000000000000D3
-:101D1000000000008C82000C8C82000C978300165F
-:101D2000AD2200008C82001000604021AD22000432
-:101D30008C820018AD2200088C82001CAD22000CA1
-:101D40008CA20014AD2200108C820020AD22001461
-:101D500090820005304200FF00021200AD22001800
-:101D60008CA20018AD22001C8CA2000CAD22002019
-:101D70008CA20010AD2200248CA2001CAD220028F1
-:101D80008CA20020AD22002C3402FFFFAD260030D3
-:101D9000AD200034506200013408FFFFAD28003848
-:101DA00050E000113C0280083C04800834840100AB
-:101DB000948200503042FFFFAD22003C94830044E7
-:101DC00094850044240200013063FFFF000318C221
-:101DD000006418219064005430A5000700A210048C
-:101DE0000A0007550044102534420100AD20003C94
-:101DF00094430044944400443063FFFF000318C23E
-:101E0000006218213084000790650054240200010C
-:101E1000008210040002102700451024A062005424
-:101E20000000000000000000000000003C0200066E
-:101E3000344200403C038000AC62003000000000EF
-:101E400000000000000000008C6200003042001022
-:101E50001040FFFD3C06800834C20150346304008A
-:101E600034C7014A34C4013434C5014034C6014486
-:101E7000AFA200100E0006CBAF8300288FBF001862
-:101E800003E0000827BD00208F8300143C060800F3
-:101E90008CC600E88F82001C30633FFF000319806E
-:101EA00000461021004310212403FF800043182422
-:101EB0003C068000ACC300283042007F3C03800C0D
-:101EC0000043302190C2000D30A500FF00003821F2
-:101ED00034420010A0C2000D8F8900143C0280081B
-:101EE0003442010094430044000913823048000347
-:101EF00024020001A4C3000E1102000B29020002FB
-:101F000010400005240200021100000C240300010F
-:101F10000A00079D000018211102000600000000C1
-:101F20000A00079D000018218CC2002C0A00079DA2
-:101F3000244300018CC20014244300018CC2001809
-:101F40000043102B5040000A240700012402002700
-:101F500014A200033C0380080A0007AA240700011A
-:101F6000346301009462004C24420001A462004CDE
-:101F700000091382304300032C6200021040000964
-:101F800000802821146000040000000094C2003486
-:101F90000A0007BA3046FFFF8CC600380A0007BAAD
-:101FA00000802821000030213C04080024845308CC
-:101FB0000A0006FF0000000027BDFF90AFB60068D2
-:101FC000AFB50064AFB40060AFB3005CAFB200580F
-:101FD000AFB10054AFBF006CAFB000508C900000A8
-:101FE0000080B0213C0208008C4200E896040032D8
-:101FF0008F83001C2414FF8030843FFF006218216F
-:102000000004218000641821007410243C13800017
-:1020100000A0902190A50000AE620028920400323A
-:102020003C02800C3063007F00628821308400C055
-:1020300024020040148200320000A8218E350038AE
-:102040008E2200181440000224020001AE22001863
-:102050009202003C304200201440000E8F83001C8E
-:10206000000511C02442024000621821306400784B
-:102070003C0200800082202500741824AE63080012
-:10208000AE6408108E2200188E0300080043102151
-:10209000AE2200188E22002C8E230018244200014C
-:1020A0000062182B10600043000000009242000004
-:1020B00024420001A24200003C0308008C6300F4AB
-:1020C000304200FF50430001A24000009242000055
-:1020D0008F84001C000211C024420240248300406F
-:1020E0003063007F008220213C02800A009420247B
-:1020F00000621821AE6400240A0008CBAEC30000C1
-:10210000920300322402FFC000431024304200FF3B
-:102110001440000524020001AE220018962200346B
-:102120000A00083B3055FFFF8E22001424420001B4
-:10213000AE220018920200300002160000021603C0
-:102140000441001C000000009602003227A4001089
-:1021500000802821A7A2001696020032000030213C
-:10216000240700013042FFFFAF8200140E0006FF7B
-:10217000AFA0001C960200328F83001C3C040800B4
-:102180008C8400E830423FFF000211800064182177
-:102190000062182100741024AE62002C3063007FAE
-:1021A0003C02800E006218219062000D3042007FD8
-:1021B000A062000D9222000D3042001050400078C5
-:1021C000924200003C028008344401009482004C9A
-:1021D0008EC300003C130800967300C62442FFFF24
-:1021E000A482004C946200329623000E3054FFFF0C
-:1021F0003070FFFF3C0308008C6300D000701807AC
-:10220000A7A300389482003E3063FFFF3042FFFFF7
-:1022100014620007000000008C8200303C03800044
-:1022200024420030AC62003C0A0008638C82002C1F
-:10223000948200403042FFFF5462000927A400400E
-:102240008C8200383C03800024420030AC62003CA9
-:102250008C820034AC6200380A0008723C038000B3
-:1022600027A5003827A60048026038210E000688FE
-:10227000A7A000488FA300403C02800024630030E8
-:10228000AC4300388FA30044AC43003C3C038000C7
-:102290003C020005AC6200303C028008344401007E
-:1022A00094820042346304003042FFFF0202102B8C
-:1022B00014400007AF8300289482004E94830042AC
-:1022C00002021021004310230A0008883043FFFF58
-:1022D0009483004E94820042026318210050102320
-:1022E000006218233063FFFF3C0280083444010081
-:1022F0009482003C3042FFFF1443000300000000C2
-:102300000A000898240300019482003C3042FFFF39
-:102310000062102B144000058F8200289482003C3C
-:10232000006210233043FFFF8F820028AC5500006D
-:10233000AC400004AC540008AC43000C3C02000666
-:10234000344200103C038000AC620030000000000A
-:1023500000000000000000008C620000304200100D
-:102360001040FFFD3C04800834840100001018C2B6
-:102370000064182190650054320200072406000111
-:102380000046100400451025A062005494830042CA
-:102390009622000E50430001A386001892420000CE
-:1023A00024420001A24200003C0308008C6300F4B8
-:1023B000304200FF50430001A24000009242000062
-:1023C0008F84001C000211C024420240248300407C
-:1023D000008220212402FF80008220243063007FBD
-:1023E0003C02800A006218213C028000AC440024B8
-:1023F000AEC300008FBF006C8FB600688FB500645D
-:102400008FB400608FB3005C8FB200588FB100545E
-:102410008FB0005003E0000827BD007027BDFFD833
-:10242000AFB3001CAFB20018AFB10014AFB00010D2
-:10243000AFBF00200080982100E0802130B1FFFF75
-:102440000E000D5230D200FF00000000000000001E
-:10245000000000008F8200208F830024AC51000018
-:10246000AC520004AC530008AC40000CAC4000106F
-:10247000AC400014AC4000189463001E0203802599
-:10248000AC50001C00000000000000000000000034
-:10249000240400018FBF00208FB3001C8FB20018EE
-:1024A0008FB100148FB000100A000D8627BD0028E0
-:1024B00030A5FFFF0A0008D530C600FF3C028008A7
-:1024C000344301009462000E3C080800950800C6E1
-:1024D0003046FFFF14C000043402FFFF946500DAA9
-:1024E0000A0009228F84001C10C20027000000008F
-:1024F0009462004E9464003C3045FFFF00A6102318
-:1025000000A6182B3087FFFF106000043044FFFF47
-:1025100000C5102300E210233044FFFF0088102B79
-:102520001040000E00E810233C02800834440100F3
-:102530002403000134420080A44300162402FFFF5C
-:10254000A482000E948500DA8F84001C00003021E4
-:1025500030A5FFFF0A0008FA3C0760200044102A5B
-:10256000104000093C028008344300809462001649
-:1025700030420001104000043C0280009442007E82
-:1025800024420014A462001603E0000800000000CA
-:1025900027BDFFE03C028008AFBF001CAFB00018B1
-:1025A00034420100944300429442004C1040001910
-:1025B0003068FFFF93830018240200011462002991
-:1025C0008FBF001C3C06800834D00100000810C2F8
-:1025D00000501021904200543103000734C70148D5
-:1025E000304200FF006210073042000134C9014E42
-:1025F00034C4012C34C5013E1040001634C60142DB
-:102600000E0006CBAFA90010960200420A00093F57
-:102610003048FFFF3C0280083444010094830044AA
-:10262000948200421043000F8FBF001C948200442C
-:10263000A482004294820050A482004E8C82003812
-:10264000AC82003094820040A482003E9482004A12
-:10265000A48200488FBF001C8FB000180A0008FD3C
-:1026600027BD00208FB0001803E0000827BD002020
-:1026700027BDFFA0AFB1004C3C118000AFBF005898
-:10268000AFB30054AFB20050AFB000483626018857
-:1026900090C200033044007FA3A400108E3201805A
-:1026A00090C200003043007F240200031062003B10
-:1026B000AF92001C286200041040000624020004AF
-:1026C00024020002106200098FBF00580A000B08A4
-:1026D0008FB300541062004D240200051062014EB9
-:1026E0008FBF00580A000B088FB30054000411C0BC
-:1026F000024210212404FF8024420240004410249E
-:1027000026430040AE2200243063007F3C02800A52
-:10271000006218219062003CAFA3003C00441025E9
-:10272000A062003C8FA3003C9062003C304200401D
-:102730001040016C8FBF00583C108008A380001827
-:10274000361001008E0200D08C63003427A4003CB8
-:1027500027A50010004310210E0007BCAE0200D0D8
-:1027600093A200103C038000A20200C58C62027894
-:102770000440FFFE8F82001CAC6202402402000273
-:10278000A06202443C021000AC6202780E000932E2
-:10279000000000000A000B078FBF00583C058008AE
-:1027A00090C3000190A2000B1443014E8FBF00584C
-:1027B00034A400808C8200189082004C90A2000803
-:1027C0003C0260008C4254048C8300183C027FFF62
-:1027D0003442FFFF006218243C0208008C4200B41F
-:1027E000AC8300183C038000244200013C01080037
-:1027F000AC2200B48C6201F80440FFFE8F82001C02
-:10280000AC6201C00A000ACF240200023C1080081A
-:1028100090C300019202000B144301328FBF005895
-:1028200027A4001836050110240600033C026000AE
-:102830008C4254040E000E150000000027A400284E
-:10284000360501E00E000E15240600038FA20028B5
-:1028500036030100AE0200648FA2002CAE020068B5
-:102860008FA20030AE02006C93A40018906300C5E4
-:102870002402FF800082102400431025304900FF0D
-:102880003084007F3122007F0082102A54400001F2
-:1028900039290080000411C0244202402403FF8033
-:1028A0000242102100431024AE2200942642004030
-:1028B0003042007F3C038006004340218FA3001C70
-:1028C0002402FFFFAFA800403C130800927300F7FA
-:1028D0001062003393A2001995030014304400FFE6
-:1028E0003063FFFF0064182B106000100000000030
-:1028F000950400148D07001C8D0600183084FFFF1E
-:10290000004420230004210000E4382100001021AD
-:1029100000E4202B00C2302100C43021AD07001C90
-:10292000AD0600180A000A2893A2001995040014A5
-:102930008D07001C8D0600183084FFFF00822023C5
-:1029400000042100000010210080182100C2302363
-:1029500000E4202B00C4302300E33823AD07001C23
-:10296000AD06001893A200198FA30040A4620014C2
-:1029700097A2001AA46200168FA2001CAC6200107D
-:102980008FA2001CAC62000C93A20019A46200206C
-:1029900097A2001AA46200228FA2001CAC6200243D
-:1029A0003C048008348300808C6200388FA20020B1
-:1029B00001208821AC62003C8FA20020AC82000084
-:1029C00093A20018A062004C93A20018A0820009F4
-:1029D000A060006893A20018105100512407FF80E6
-:1029E0003229007F000911C0244202400242102116
-:1029F0003046007F3C03800000471024AC62009406
-:102A00003C02800600C2302190C2003CAFA60040CC
-:102A10000000202100471025A0C2003C8FA80040E4
-:102A200095020002950300148D07001C3042FFFF41
-:102A30003063FFFF8D0600180043102300021100D1
-:102A400000E2382100E2102B00C4302100C2302106
-:102A5000AD07001CAD06001895020002A502001487
-:102A6000A50000168D020008AD0200108D020008BE
-:102A7000AD02000C95020002A5020020A500002274
-:102A80008D020008AD0200249102003C304200405B
-:102A90001040001A262200013C108008A3A900382B
-:102AA000A3800018361001008E0200D08D03003480
-:102AB00027A4004027A50038004310210E0007BCC2
-:102AC000AE0200D093A200383C038000A20200C5F1
-:102AD0008C6202780440FFFE8F82001CAC620240D0
-:102AE00024020002A06202443C021000AC620278A0
-:102AF0000E00093200000000262200013043007F52
-:102B000014730004004020212403FF8002231024BA
-:102B10000043202693A200180A000A44309100FFC7
-:102B200093A400188FA3001C2402FFFF1062000A68
-:102B3000308900FF24820001248300013042007F9D
-:102B400014530005306900FF2403FF800083102424
-:102B500000431026304900FF3C02800890420008E4
-:102B600001208821305000FF123000193222007FEE
-:102B7000000211C002421021244202402403FF80BF
-:102B8000004318243C048000AC8300943042007F52
-:102B90003C038006004310218C43000C00402021A0
-:102BA0001060000BAFA200400E000577000000008F
-:102BB000262300012405FF803062007F14530002A9
-:102BC00002252024008518260A000AA8307100FF7B
-:102BD0003C048008348400808C8300183C027FFF12
-:102BE0003442FFFF00621824AC8300183C038000CD
-:102BF0008C6201F80440FFFE00000000AC7201C0CE
-:102C000024020002A06201C43C021000AC6201F880
-:102C10000A000B078FBF00583C04800890C30001D6
-:102C20009082000B1443002F8FBF00583490008017
-:102C300092020008304200401040002000000000D6
-:102C4000920200080002160000021603044100056B
-:102C5000024020210E000E9A240500930A000B0763
-:102C60008FBF00589202000924030018304200FF71
-:102C70001443000D02402021240500390E000E32BD
-:102C8000000030210E0003528F84001C8F82FF9CB5
-:102C900024030012A04300090E00035D8F84001C72
-:102CA0000A000B078FBF0058240500360E000E32B5
-:102CB000000030210A000B078FBF00580E0003529E
-:102CC00002402021920200058F84001C3442002023
-:102CD0000E00035DA20200050E0010438F84001C4D
-:102CE0008FBF00588FB300548FB200508FB1004C8B
-:102CF0008FB0004803E0000827BD00603C02800858
-:102D0000344501003C0280008C42014094A3000E37
-:102D10000000302100402021AF82001C3063FFFF03
-:102D20003402FFFF106200063C0760202402FFFF10
-:102D3000A4A2000E94A500DA0A0008FA30A5FFFF4D
-:102D400003E000080000000027BDFFC83C0280002F
-:102D50003C068008AFB5002CAFB1001CAFBF0030FF
-:102D6000AFB40028AFB30024AFB20020AFB000185A
-:102D70003451010034C501008C4301008E2200143F
-:102D80008CA400D40000A821AF83001C00441023B1
-:102D900018400052A38000188E2200140000502119
-:102DA000ACA200D490C3000890A200C53073007F8D
-:102DB000A3A200108CB200D08CB400D4304200FF2B
-:102DC0001053003B93A200108F83001C2407FF8048
-:102DD000000211C00062102124420240246300401E
-:102DE000004710243063007F3C0980003C08800AC3
-:102DF00000681821AD2200248C62003427A400143E
-:102E000027A50010024280210290102304400028D0
-:102E1000AFA300149062003C00E21024304200FF97
-:102E200014400019020090219062003C344200409E
-:102E3000A062003C8F86001C93A3001024C20040B7
-:102E40003042007F004828213C0208008C4200F4F8
-:102E500024630001306400FF14820002A3A3001069
-:102E6000A3A0001093A20010AFA50014000211C08F
-:102E70002442024000C2102100471024AD22002449
-:102E80000A000B3E93A200100E0007BC00000000D9
-:102E90003C02800834420100AC5000D093A30010E3
-:102EA000240A0001A04300C50A000B3E93A20010B3
-:102EB00024020001154200093C0380008C62027864
-:102EC0000440FFFE8F82001CAC620240240200021C
-:102ED000A06202443C021000AC6202789222000B15
-:102EE00024030002304200FF14430072000000007F
-:102EF00096220008304300FF240200821462004042
-:102F0000240200843C028000344901008D22000C20
-:102F100095230006000216023063FFFF3045003F94
-:102F20002402002710A2000FAF83001428A200285B
-:102F300010400008240200312402002110A20009E0
-:102F40002402002510A20007938200190A000BB684
-:102F50000000000010A20007938200190A000BB6BF
-:102F6000000000000E000770012020210A000C362E
-:102F7000000000003C0380008C6202780440FFFEE9
-:102F80008F82001CAC62024024020002A062024454
-:102F90003C021000AC6202780A000C36000000000F
-:102FA00095230006912400058D25000C8D26001028
-:102FB0008D2700188D28001C8D2900202442000137
-:102FC0003C010800A423530E3C010800A024530D2B
-:102FD0003C010800AC2553143C010800AC265318F2
-:102FE0003C010800AC2753203C010800AC285324C6
-:102FF0003C010800AC2953280A000C36A3820019B2
-:103000001462000A240200813C028008344201005C
-:10301000944500DA922600058F84001C30A5FFFF3E
-:1030200030C600FF0A000BF73C0760211462005C09
-:10303000000000009222000A304300FF30620020AE
-:1030400010400007306200403C028008344201001A
-:10305000944500DA8F84001C0A000BF5240600401A
-:1030600010400007000316003C02800834420100B3
-:10307000944500DA8F84001C0A000BF524060041F9
-:1030800000021603044100463C028008344201005D
-:10309000944500DA8F84001C2406004230A5FFFF0F
-:1030A0003C0760190E0008FA000000000A000C3608
-:1030B000000000009222000B24040016304200FFA2
-:1030C000104400063C0680009222000B24030017E7
-:1030D000304200FF144300320000000034C50100FC
-:1030E00090A2000B304200FF1444000B000080212E
-:1030F0008CA200208CA400202403FF800043102415
-:10310000000211403084007F004410253C03200061
-:1031100000431025ACC2083094A20008000214003D
-:1031200000021403044200012410000194A20008CC
-:10313000304200805040001A0200A82194A20008EA
-:1031400030422000504000160200A8218CA3001835
-:103150003C021C2D344219ED106200110200A8211E
-:103160003C0208008C4200D4104000053C0280085C
-:103170002403000434420100A04300EC3C02800818
-:1031800034420100944500DA8F84001C24060006B6
-:1031900030A5FFFF0E0008FA3C0760210200A821BD
-:1031A0000E000932000000009222000A304200089E
-:1031B0001040000402A010210E0013470000000080
-:1031C00002A010218FBF00308FB5002C8FB40028D3
-:1031D0008FB300248FB200208FB1001C8FB0001875
-:1031E00003E0000827BD00382402FF80008220246D
-:1031F0003C02900034420007008220253C028000FF
-:10320000AC4400203C0380008C6200200440FFFEA0
-:103210000000000003E00008000000003C03800004
-:103220002402FF80008220243462000700822025CF
-:10323000AC6400208C6200200440FFFE000000000F
-:1032400003E00008000000003C02800824030005A1
-:1032500034420100A04300EC3C0280008C4201009B
-:103260003C038000AF82001C8C6202780440FFFEA9
-:103270008F82001CAC62024024020002A062024461
-:103280003C021000AC62027803E00008000000007D
-:1032900027BDFFE83C068000AFBF001034C7010027
-:1032A00094E20008304400FF3883008238820084B2
-:1032B0002C6300012C420001006218251060002DD3
-:1032C0002402008393820019504000368FBF001003
-:1032D0003C020800904253148CC401003C060800D4
-:1032E00094C6530E3045003F38A3003238A2003F49
-:1032F0002C6300012C42000100621825AF84001CE1
-:10330000AF860014A38000191460000700E020219C
-:103310002402002014A20012000000003402FFFF6B
-:1033200014C2000F000000002402002014A20005B7
-:1033300000E028218CE300142402FFFF5062000B00
-:103340008FBF00103C040800248453080000302183
-:103350000E0006FF240700010A000CA98FBF001011
-:103360000E000770000000008FBF00100A00093235
-:1033700027BD0018148200062482FF808CC301043C
-:103380003C026020AC4300140A000CDF8FBF001029
-:10339000304200FF2C4200021040000424020022B0
-:1033A0008FBF00100A000B2027BD001814820004F4
-:1033B0008F8200248FBF00100A000C6027BD001808
-:1033C0008C42000C1040001E00E0282190E3000910
-:1033D0002402001814620003240200160A000CCA1A
-:1033E00024030008146200072402001724030012BB
-:1033F0003C02800834420080A04300090A000CD738
-:1034000094A700085462000794A700088F82FF9CCD
-:103410002404FFFE9043000500641824A043000527
-:1034200094A7000890A6001B8CA4000094A5000699
-:103430008FBF001000073C000A0008D527BD001808
-:103440008FBF001003E0000827BD00188F850024FF
-:103450003C04800094A2002A8CA30034000230C0F7
-:103460002402FFF000C2102400621821AC83003C4B
-:103470008CA200303C038000AC8200383C0200503B
-:1034800034420010AC620030000000000000000078
-:10349000000000008C620000304200201040FFFD60
-:1034A00030C20008104000063C0280008C62040814
-:1034B000ACA200208C62040C0A000D02ACA2002415
-:1034C0008C430400ACA300208C420404ACA2002472
-:1034D0003C0300203C028000AC4300303C048000F0
-:1034E0008C820030004310241440FFFD8F8600249E
-:1034F0003C020040AC82003094C3002A94C20028F1
-:1035000094C4002C94C5002E2463000100441021B3
-:103510003064FFFFA4C2002814850002A4C3002A5F
-:10352000A4C0002A03E00008000000008F840024EB
-:1035300027BDFFE83C05800424840010AFBF0010C5
-:103540000E000E152406000A8F84002494820012B7
-:103550009483002E3042000F2442000300431804DD
-:1035600024027FFF0043102B10400002AC830000B8
-:103570000000000D0E000CE1000000008F8300240D
-:103580008FBF001027BD0018946200149463001AC6
-:103590003042000F00021500006218253C02800036
-:1035A00003E00008AC4300A08F8300243C028004A9
-:1035B000944400069462001A8C650000A46400160E
-:1035C000004410233042FFFF0045102B03E00008A9
-:1035D000384200018F8400243C0780049486001A3E
-:1035E0008C85000094E20006A482001694E3000695
-:1035F00000C310233042FFFF0045102B384200016A
-:103600001440FFF8A483001603E000080000000047
-:103610008F8400243C028004944200069483001AA4
-:103620008C850000A4820016006210233042FFFF48
-:103630000045102B384200015040000D8F850024BA
-:10364000006030213C07800494E20006A48200164A
-:1036500094E3000600C310233042FFFF0045102B07
-:10366000384200011440FFF8A48300168F8500241F
-:103670003C038000346204008CA40020AF82002050
-:10368000AC6400388CA20024AC62003C3C02000513
-:10369000AC62003003E00008ACA000048F8400247A
-:1036A0003C0300068C8200040002114000431025F8
-:1036B0003C038000AC62003000000000000000000D
-:1036C000000000008C620000304200101040FFFD3E
-:1036D00034620400AC80000403E00008AF820020E4
-:1036E0008F86002427BDFFE0AFB10014AFB00010FB
-:1036F000AFBF00188CC300048CC500248F8200204B
-:10370000309000FF94C4001A24630001244200207A
-:103710002484000124A70020ACC30004AF82002051
-:10372000A4C4001AACC7002404A10006000088212C
-:1037300004E2000594C2001A8CC200202442000159
-:10374000ACC2002094C2001A94C300282E040001C9
-:10375000004310262C420001004410245040000574
-:1037600094C2001A24020001ACC2000894C2001ADC
-:1037700094C300280010202B004310262C42000187
-:103780000044102514400007000000008CC200080F
-:1037900014400004240200108CC300041462000FC3
-:1037A0008F8500240E000D75241100018F820024E6
-:1037B000944300289442001A1443000300000000C0
-:1037C0000E000CE100000000160000048F850024AC
-:1037D0000E000D52000000008F85002494A2001EF0
-:1037E00094A4001C244200013043FFFF1464000233
-:1037F000A4A2001EA4A0001E1200000A3C02800425
-:1038000094A2001494A3001A3042000F0002150085
-:10381000006218253C028000AC4300A00A000DECB9
-:10382000ACA000089442000694A3001A8CA40000E7
-:10383000A4A20016006210233042FFFF0044102BA8
-:10384000384200011040000D02201021006030219C
-:103850003C07800494E20006A4A2001694E300064C
-:1038600000C310233042FFFF0044102B38420001F8
-:103870001440FFF8A4A30016022010218FBF0018E7
-:103880008FB100148FB0001003E0000827BD0020A6
-:1038900003E00008000000008F82002C3C030006BB
-:1038A00000021140004310253C038000AC62003050
-:1038B0000000000000000000000000008C6200001A
-:1038C000304200101040FFFD34620400AF82002837
-:1038D00003E00008AF80002C03E000080000102186
-:1038E00003E00008000000003084FFFF30A5FFFF68
-:1038F0000000182110800007000000003082000145
-:103900001040000200042042006518210A000E0B3E
-:103910000005284003E000080060102110C00006E8
-:1039200024C6FFFF8CA2000024A50004AC82000086
-:103930000A000E152484000403E0000800000000C3
-:1039400010A0000824A3FFFFAC86000000000000C8
-:10395000000000002402FFFF2463FFFF1462FFFA4F
-:103960002484000403E00008000000003C028008FA
-:103970003442008024030001AC43000CA443001037
-:10398000A4430012A443001403E00008A44300165B
-:103990008F82002427BDFFD8AFB3001CAFB2001840
-:1039A000AFB10014AFB00010AFBF00208C47000CC7
-:1039B000248200802409FF803C08800E3043007F71
-:1039C000008080213C0A80000049202400681821E2
-:1039D00030B100FF30D200FF10E000290000982134
-:1039E00026020100AD44002C004928243042007F0B
-:1039F000004820219062000024030050304200FF64
-:103A00001443000400000000AD45002C948200DA4D
-:103A10003053FFFF0E000D52000000008F82002483
-:103A20008F83002000112C009442001E00122400FD
-:103A30003484000100A228253C02400000A2282571
-:103A4000AC7000008FBF0020AC6000048FB2001883
-:103A5000AC7300088FB10014AC60000C8FB3001C75
-:103A6000AC6400108FB00010AC600014240400019E
-:103A7000AC60001827BD00280A000D86AC65001C4C
-:103A80008FBF00208FB3001C8FB200188FB10014BD
-:103A90008FB0001003E0000827BD00283C0680001E
-:103AA00034C201009043000F240200101062000E87
-:103AB0002865001110A0000724020012240200084B
-:103AC0002405003A106200060000302103E00008DF
-:103AD00000000000240500351462FFFC00003021C6
-:103AE0000A000E32000000008CC200748F83FF9C1D
-:103AF00024420FA003E00008AC62000C27BDFFE8E1
-:103B0000AFBF00100E000362240500013C048008D2
-:103B10008FBF00102402000134830080A4620012D1
-:103B200027BD00182402000103E00008A080001A4D
-:103B300027BDFFE0AFB20018AFB10014AFB0001066
-:103B4000AFBF001C30B2FFFF0E000352008088217F
-:103B50003C028008345000809202000924030004D3
-:103B6000304200FF1443000C3C0280081240000861
-:103B70002402000A0E000E29000000009202000537
-:103B80002403FFFE00431024A202000524020012B9
-:103B9000A20200093C028008344200800220202159
-:103BA0000E00035DA04000271640000302202021E4
-:103BB0000E000E8D0000000002202021324600FF82
-:103BC0008FBF001C8FB200188FB100148FB000108F
-:103BD000240500380A000E3227BD002027BDFFE073
-:103BE000AFBF001CAFB20018AFB10014AFB00010EF
-:103BF0000E000352008080210E000E2900000000FC
-:103C00003C0280083445008090A20009241200186C
-:103C1000305100FF12320003020020212402001262
-:103C2000A0A2000990A200052403FFFE0043102477
-:103C30000E00035DA0A20005020020212405002043
-:103C400016320007000030218FBF001C8FB2001811
-:103C50008FB100148FB000100A00036227BD00204E
-:103C60008FBF001C8FB200188FB100148FB00010EE
-:103C7000240500390A000E3227BD002027BDFFE8C9
-:103C80003C028000AFB00010AFBF0014344201000E
-:103C90009442000C2405003600808021144000125C
-:103CA000304600FF0E000352000000003C02800876
-:103CB0003442008024030012A04300099043000511
-:103CC000346300100E000E29A04300050E00035DB2
-:103CD00002002021020020210E00036224050020A2
-:103CE0000A000F0A000000000E000E320000000063
-:103CF0000E000352020020213C0280089043001B6A
-:103D00002405FF9F02002021006518248FBF0014A6
-:103D10008FB00010A043001B0A00035D27BD0018F0
-:103D200027BDFFE0AFBF0018AFB10014AFB0001067
-:103D300030B100FF0E000352008080213C02800859
-:103D400024030012344200800E000E29A043000913
-:103D50000E00035D020020210200202102203021FC
-:103D60008FBF00188FB100148FB0001024050035EC
-:103D70000A000E3227BD00203C0480089083000E0C
-:103D80009082000A1443000B000028218F82FF9CC0
-:103D9000240300502405000190420000304200FF3F
-:103DA00014430004000000009082000E2442000131
-:103DB000A082000E03E0000800A010213C03800058
-:103DC0008C6201F80440FFFE24020002AC6401C0D2
-:103DD000A06201C43C02100003E00008AC6201F8DC
-:103DE00027BDFFE0AFB200183C128008AFB100144D
-:103DF000AFBF001CAFB00010365100809222000906
-:103E00002403000A304200FF1443003E000000007B
-:103E10008E4300048E220038506200808FBF001C49
-:103E20009222000024030050304200FF144300257A
-:103E30003C0280008C4201408E4300043642010067
-:103E400002202821AC43001C9622005C8E230038FF
-:103E50003042FFFF0002104000621821AE23001C18
-:103E60008E4300048E2400389622005C00641823E0
-:103E70003042FFFF00031843000210400043102AA5
-:103E800010400006000000008E4200048E2300381F
-:103E9000004310230A000F78000220439622005CA2
-:103EA0003042FFFF000220403C0280083443010002
-:103EB00034420080ACA4002CA04000242402000165
-:103EC000A062000C0E000F2C0000000010400053F8
-:103ED0008FBF001C3C0280008C4401403C038000EA
-:103EE0008C6201F80440FFFE24020002AC6401C0B1
-:103EF000A06201C43C021000AC6201F80A000FD5B8
-:103F00008FBF001C9222000924030010304200FFE2
-:103F1000144300043C0280008C4401400A000FBCA2
-:103F2000000028219222000924030016304200FFDD
-:103F30001443000624020014A22200093C0280005F
-:103F40008C4401400A000FCF8FBF001C8E22003826
-:103F50008E23003C00431023044100308FBF001C1F
-:103F60009222002724420001A22200279222002749
-:103F70002C420004144000163C10800092220009DC
-:103F800024030004304200FF144300093C02800077
-:103F90008C4401408FBF001C8FB200188FB10014F9
-:103FA0008FB00010240500930A000E9A27BD002050
-:103FB0008C440140240500938FBF001C8FB2001871
-:103FC0008FB100148FB000100A000F1627BD00201B
-:103FD0008E0401400E000352000000008E420004D7
-:103FE0002442FFFFAE4200048E22003C2442FFFF29
-:103FF000AE22003C0E00035D8E0401408E040140A1
-:104000008FBF001C8FB200188FB100148FB000104A
-:10401000240500040A00036227BD00208FB20018A7
-:104020008FB100148FB0001003E0000827BD0020FE
-:104030003C0680008CC201883C0380083465008007
-:104040009063000E00021402304400FF306300FF52
-:104050001464000E3C02800890A20026304200FF4B
-:10406000104400098F82FF9CA0A400262403005066
-:1040700090420000304200FF1443000600000000A0
-:104080000A00059A8CC401803C02800834420080FA
-:10409000A044002603E000080000000027BDFFE068
-:1040A00030E700FFAFB20018AFBF001CAFB1001483
-:1040B000AFB000100080902114E0000630C600FF71
-:1040C000000000000000000D000000000A00102E9B
-:1040D0002400010E3C0380089062000E304200FF75
-:1040E000144600233462008090420026304200FFD4
-:1040F0001446001F000000009062000F304200FFD5
-:104100001446001B000000009062000A304200FFCD
-:10411000144600038F90FF9C0000000D8F90FF9CC1
-:104120008F82FFA03C118000AE05003CAC45000032
-:10413000A066000A0E0003528E240100A200002493
-:104140000E00035D8E2401003C0380008C6201F8A8
-:104150000440FFFE24020002AC7201C0A06201C450
-:104160003C021000AC6201F80A00102F8FBF001C47
-:10417000000000000000000D0000000024000137D6
-:104180008FBF001C8FB200188FB100148FB00010C9
-:1041900003E0000827BD00208F83FF9C3C028000C5
-:1041A0008C440100344201008C65003C9046001BA9
-:1041B0000A000FF5240700013C0280089043000E1E
-:1041C0009042000A00431026304200FF03E000083E
-:1041D0000002102B27BDFFE03C028008AFB10014A5
-:1041E000AFB00010AFBF001834500080920200053D
-:1041F00024030030304200301443008500808821C1
-:104200008F8200248C42000C104000828FBF001867
-:104210000E000D52000000008F860020ACD100007F
-:104220009202000892030009304200FF00021200CF
-:10423000306300FF00431025ACC200049202004D21
-:1042400000021600000216030441000500000000F1
-:104250003C0308008C6300480A00106D3C10800885
-:104260009202000830420040144000030000182170
-:1042700092020027304300FF3C1080083611008076
-:104280009222004D00031E00304200FF0002140085
-:1042900000621825ACC300088E2400308F820024F1
-:1042A000ACC4000C8E2500349443001E3C02C00BAD
-:1042B000ACC50010006218258E22003800002021B5
-:1042C000ACC200148E22003CACC200180E000D8659
-:1042D000ACC3001C8E0200048F8400203C058000CB
-:1042E000AC8200008E220020AC8200048E22001CD2
-:1042F000AC8200088E2200588CA300740043102169
-:10430000AC82000C8E22002CAC8200108E22004069
-:104310008E2300440002140000431025AC820014D8
-:104320009222004D24030080304200FF1443000419
-:1043300000000000AC8000180A0010B18F82002439
-:104340008E23000C240200011062000E2402FFFFE5
-:1043500092220008304200401440000A2402FFFF6D
-:104360008E23000C8CA20074006218233C0208000B
-:10437000006210241440000200002821006028215F
-:1043800000051043AC8200188F8200240000202119
-:104390009443001E3C02C00C006218258F8200204E
-:1043A0000E000D86AC43001C3C0380083462010003
-:1043B0008C4200008F850020346300808FBF00187E
-:1043C000ACA20000ACA000048C6400488F820024E2
-:1043D0008FB10014ACA40008ACA0000CACA000107D
-:1043E000906300059446001E3C02400D00031E0031
-:1043F00000C23025ACA300148FB00010ACA0001890
-:1044000024040001ACA6001C0A000D8627BD002074
-:104410008FBF00188FB100148FB0001003E00008A8
-:1044200027BD00203C0280009443007C3C028008B1
-:1044300034460100308400FF3065FFFF2402000590
-:1044400024A34650A0C4000C5482000C3065FFFF2A
-:1044500090C2000D2C4200071040000724A30A0060
-:1044600090C3000D240200140062100400A2102169
-:104470000A0010ED3045FFFF3065FFFF3C02800869
-:104480003442008003E00008A44500143C03800887
-:1044900034680080AD050038346701008CE2001CF0
-:1044A000308400FF00A210231840000330C600FF34
-:1044B00024A2FFFCACE2001C308200015040000846
-:1044C0003C0380088D02003C00A21023044100122E
-:1044D000240400058C62000410A2000F3C03800835
-:1044E0008C62000414A2001E000000003C020800C0
-:1044F0008C4200D830420020104000093C02800865
-:1045000034620080906300089042004C1443000421
-:104510003C028008240400040A0010D700000000B8
-:104520003443008034420100A040000C240200010A
-:10453000A462001410C0000A3C0280008C440100F8
-:104540003C0380008C6201F80440FFFE240200025C
-:10455000AC6401C0A06201C43C021000AC6201F86E
-:1045600003E000080000000027BDFFE800A61823B4
-:10457000AFBF001018600080308800FF3C02800848
-:1045800034470080A0E0002434440100A0E000276C
-:104590008C82001C00A21023044000560000000082
-:1045A0008CE2003C94E3005C8CE4002C004530235A
-:1045B0003063FFFF00C318210083202B108000040C
-:1045C00000E018218CE2002C0A00114600A2102104
-:1045D00094E2005C3042FFFF00C2102100A21021D3
-:1045E000AC62001C3C028008344400809482005C71
-:1045F0008C83001C3042FFFF0002104000A21021FB
-:104600000043102B10400004000000008C82001CAE
-:104610000A0011593C0680089482005C3042FFFF7A
-:104620000002104000A210213C06800834C30100A3
-:1046300034C70080AC82001CA060000CACE50038E0
-:104640008C62001C00A210231840000224A2FFFC70
-:10465000AC62001C31020001104000083C038008DD
-:104660008CE2003C00A21023044100122404000547
-:104670008CC2000410A200108FBF00108C620004D6
-:1046800014A2004F8FBF00103C0208008C4200D8DB
-:10469000304200201040000A3C0280083462008052
-:1046A000906300089042004C144300053C028008CF
-:1046B000240400048FBF00100A0010D727BD001883
-:1046C0003443008034420100A040000C2402000169
-:1046D000A46200143C0280008C4401003C03800072
-:1046E0008C6201F80440FFFE240200020A0011A6B9
-:1046F000000000008CE2001C004610230043102B39
-:1047000054400001ACE5001C94E2005C3042FFFF25
-:104710000062102B144000072402000294E2005CA7
-:104720008CE3001C3042FFFF00621821ACE3001C48
-:1047300024020002ACE500380E000F2CA082000C11
-:104740001040001F8FBF00103C0280008C4401000D
-:104750003C0380008C6201F80440FFFE240200024A
-:10476000AC6401C0A06201C43C021000AC6201F85C
-:104770000A0011BE8FBF001031020010104000105F
-:104780008FBF00103C028008344500808CA3001CC1
-:1047900094A2005C006618233042FFFF00621821DB
-:1047A0003C023FFF3444FFFF0083102B54400001C4
-:1047B0000080182100C31021ACA2001C8FBF001084
-:1047C00003E0000827BD001827BDFFE800C0402116
-:1047D00000A63023AFBF001018C00026308A00FFAB
-:1047E0003C028008344900808D24001C8D23002C5D
-:1047F000008820230064182B1060000F344701004C
-:104800008CE2002000461021ACE200208CE2002067
-:104810000044102B1440000B3C023FFF8CE20020B0
-:1048200000441023ACE200209522005C3042FFFFE0
-:104830000A0011DE00822021ACE000200086202149
-:104840003C023FFF3443FFFF0064102B5440000143
-:10485000006020213C02800834420080008518213D
-:10486000AC43001CA0400024A04000270A001230E6
-:104870003C03800831420010104000433C03800894
-:104880003C06800834C400808C82003C0048102321
-:104890005840003E3466008090820024244200018B
-:1048A000A0820024908200243C0308008C63002432
-:1048B000304200FF0043102B144000688FBF0010EF
-:1048C00034C201008C42001C00A210231840006377
-:1048D000000000008CC300049482005C0068182370
-:1048E0003042FFFF00031843000210400043102A2B
-:1048F00010400005000000008CC200040048102396
-:104900000A001213000210439482005C3042FFFF41
-:10491000000210403C068008AC82002C34C50080A8
-:1049200094A2005C8CA4002C94A3005C3042FFFF96
-:1049300000021040008220213063FFFF008320210D
-:1049400001041021ACA2001C8CC2000434C601007A
-:10495000ACC2001C240200020E000F2CA0C2000CEE
-:104960001040003E8FBF00103C0280008C440100CC
-:104970003C0380008C6201F80440FFFE2402000228
-:104980000A0012600000000034660080ACC50038E8
-:10499000346401008C82001C00A210231840000225
-:1049A00024A2FFFCAC82001C314200015040000AEE
-:1049B0003C0380088CC2003C00A210230443001476
-:1049C000240400058C62000414A200033C03800848
-:1049D0000A001252240400058C62000414A2001F75
-:1049E0008FBF00103C0208008C4200D830420020EB
-:1049F0001040000A3C028008346200809063000886
-:104A00009042004C144300053C028008240400043A
-:104A10008FBF00100A0010D727BD00183443008054
-:104A200034420100A040000C24020001A4620014E2
-:104A30003C0280008C4401003C0380008C6201F841
-:104A40000440FFFE24020002AC6401C0A06201C465
-:104A50003C021000AC6201F88FBF001003E00008B8
-:104A600027BD001827BDFFE83C0A8008AFBF001033
-:104A7000354900808D22003C00C04021308400FF79
-:104A8000004610231840009D30E700FF3547010025
-:104A90002402000100A63023A0E0000CA0E0000DDD
-:104AA000A522001418C00024308200108D23001CA1
-:104AB0008D22002C006818230043102B1040000F9B
-:104AC000000000008CE2002000461021ACE2002033
-:104AD0008CE200200043102B1440000B3C023FFFEF
-:104AE0008CE2002000431023ACE200209522005C01
-:104AF0003042FFFF0A00128F00621821ACE0002054
-:104B0000006618213C023FFF3446FFFF00C3102B14
-:104B10005440000100C018213C028008344200804B
-:104B200000651821AC43001CA0400024A0400027D1
-:104B30000A0012DD3C038008104000403C0380085E
-:104B40008D22003C004810235840003D346700800F
-:104B50009122002424420001A12200249122002459
-:104B60003C0308008C630024304200FF0043102BFC
-:104B70001440009A8FBF00108CE2001C00A210238A
-:104B800018400096000000008D4300049522005C50
-:104B9000006818233042FFFF000318430002104052
-:104BA0000043102A10400005012020218D420004FE
-:104BB000004810230A0012C0000210439522005C36
-:104BC0003042FFFF000210403C068008AC82002CFF
-:104BD00034C5008094A2005C8CA4002C94A3005CDB
-:104BE0003042FFFF00021040008220213063FFFFAF
-:104BF0000083182101031021ACA2001C8CC2000408
-:104C000034C60100ACC2001C240200020E000F2CAE
-:104C1000A0C2000C104000718FBF00103C02800049
-:104C20008C4401003C0380008C6201F80440FFFECC
-:104C3000240200020A00130700000000346700800D
-:104C4000ACE50038346601008CC2001C00A21023C1
-:104C50001840000224A2FFFCACC2001C30820001FC
-:104C6000504000083C0380088CE2003C00A2102366
-:104C700004430051240400058C62000410A2003E8D
-:104C80003C0380088C62000454A200548FBF0010C3
-:104C90003C0208008C4200D8304200201040000640
-:104CA0003C02800834620080906300089042004C0F
-:104CB000104300403C02800834430080344201002D
-:104CC000A040000C24020001A46200143C028000F9
-:104CD0008C4401003C0380008C6201F80440FFFE1C
-:104CE00024020002AC6401C0A06201C43C021000B6
-:104CF000AC6201F80A0013458FBF001024020005C2
-:104D0000A120002714E2000A3C038008354301007B
-:104D10009062000D2C420006504000053C038008C4
-:104D20009062000D24420001A062000D3C03800847
-:104D300034670080ACE50038346601008CC2001C8A
-:104D400000A210231840000224A2FFFCACC2001CE9
-:104D5000308200015040000A3C0380088CE2003C95
-:104D600000A2102304410014240400058C620004F6
-:104D700014A200033C0380080A00133C240400052D
-:104D80008C62000414A200158FBF00103C020800C2
-:104D90008C4200D8304200201040000A3C028008BB
-:104DA00034620080906300089042004C1443000578
-:104DB0003C028008240400048FBF00100A0010D7B2
-:104DC00027BD00183443008034420100A040000C8D
-:104DD00024020001A46200148FBF001003E0000849
-:104DE00027BD00183C0B800827BDFFE83C0280006F
-:104DF000AFBF001034420100356A00809044000AC1
-:104E0000356901008C4500148D4800389123000C51
-:104E1000308400FF010510231C4000B3306700FF01
-:104E20002CE20006504000B18FBF001024020001A8
-:104E300000E2300430C200035440000800A83023D0
-:104E400030C2000C144000A130C20030144000A356
-:104E50008FBF00100A0014090000000018C00024D1
-:104E6000308200108D43001C8D42002C00681823F6
-:104E70000043102B1040000F000000008D22002086
-:104E800000461021AD2200208D2200200043102B6F
-:104E90001440000B3C023FFF8D22002000431023F2
-:104EA000AD2200209542005C3042FFFF0A00137DD6
-:104EB00000621821AD200020006618213C023FFF4F
-:104EC0003446FFFF00C3102B5440000100C01821DE
-:104ED0003C0280083442008000651821AC43001C6D
-:104EE000A0400024A04000270A0013CB3C03800808
-:104EF000104000403C0380088D42003C00481023D5
-:104F00001840003D34670080914200242442000193
-:104F1000A1420024914200243C0308008C63002439
-:104F2000304200FF0043102B144000708FBF001070
-:104F30008D22001C00A210231840006C000000000D
-:104F40008D6300049542005C006818233042FFFF27
-:104F500000031843000210400043102A10400005CF
-:104F6000014020218D620004004810230A0013AE86
-:104F7000000210439542005C3042FFFF00021040E7
-:104F80003C068008AC82002C34C5008094A2005CF2
-:104F90008CA4002C94A3005C3042FFFF0002104060
-:104FA000008220213063FFFF0083182101031021BC
-:104FB000ACA2001C8CC2000434C60100ACC2001CB0
-:104FC000240200020E000F2CA0C2000C104000476B
-:104FD0008FBF00103C0280008C4401003C03800025
-:104FE0008C6201F80440FFFE240200020A0013FB59
-:104FF0000000000034670080ACE500383466010032
-:105000008CC2001C00A210231840000224A2FFFC46
-:10501000ACC2001C308200015040000A3C038008F2
-:105020008CE2003C00A21023044300142404000579
-:105030008C62000414A200033C0380080A0013EDF4
-:10504000240400058C62000414A200288FBF001005
-:105050003C0208008C4200D8304200201040000A78
-:105060003C02800834620080906300089042004C4B
-:10507000144300053C028008240400048FBF001084
-:105080000A0010D727BD00183443008034420100C5
-:10509000A040000C24020001A46200143C02800025
-:1050A0008C4401003C0380008C6201F80440FFFE48
-:1050B00024020002AC6401C0A06201C43C021000E2
-:1050C000AC6201F80A0014098FBF00108FBF0010F6
-:1050D000010030210A00112827BD001801003021ED
-:1050E0000A00126727BD00188FBF001003E00008F8
-:1050F00027BD00183C03800834640100240200032B
-:10510000A082000C8C62000403E00008AC82001C4A
-:105110003C05800834A300809062002734A501007C
-:105120002406004324420001A06200279063002768
-:105130003C0208008C420048306300FF1462000407
-:105140003C07602194A500DA0A0008FA30A5FFFFA9
-:1051500003E000080000000027BDFFE8AFBF00101B
-:105160003C0280000E0014128C4401803C02800836
-:1051700034430100A060000C8C4200048FBF00107B
-:1051800027BD001803E00008AC62001C27BDFFE04B
-:105190003C028008AFBF0018AFB10014AFB00010E0
-:1051A00034450080344601003C0880008D090140F0
-:1051B00090C3000C8CA4003C8CA200381482003BED
-:1051C000306700FF9502007C90A30027146000095F
-:1051D0003045FFFF2402000554E200083C0480082B
-:1051E00090C2000D24420001A0C2000D0A00144D1F
-:1051F0003C048008A0C0000D3C04800834820100FB
-:105200009042000C24030005304200FF1443000AC2
-:1052100024A205DC34830080906200272C42000722
-:105220005040000524A20A009063002724020014C5
-:105230000062100400A210213C108008361000808B
-:105240003045FFFF012020210E001412A605001496
-:105250009602005C8E0300383C1180003042FFFF54
-:105260000002104000621821AE03001C0E00035221
-:105270008E2401409202002534420040A202002503
-:105280000E00035D8E2401408E2401403C0380000B
-:105290008C6201F80440FFFE24020002AC6401C0ED
-:1052A000A06201C43C021000AC6201F88FBF00187C
-:1052B0008FB100148FB0001003E0000827BD00205C
-:1052C00080080100800800808008000000000C8039
-:1052D000000032008008024008000F1008000F682C
-:1052E00008000FAC0800104408001084800801007A
-:0852F000800800808008000026
-:0852F8000A0000220000000082
-:10530000000000000000000D6370352E302E306A62
-:10531000313500000500000400000000000000001E
-:1053200000000000000000000000000038003C0009
-:10533000000000000000000000000000000000006D
-:10534000000000200000000000000000000000003D
-:10535000000000000000000000000000000000004D
-:1053600000000000000000000000000021003800E4
-:10537000000000010000002B000000000000000001
-:105380000000000010000003000000000000000DFD
-:105390000000000D3C020800244255043C030800B4
-:1053A00024635744AC4000000043202B1480FFFDD1
-:1053B000244200043C1D080037BD9FFC03A0F021DF
-:1053C0003C100800261000883C1C0800279C55044F
-:1053D0000E00029A000000000000000D00A018213D
-:1053E00000801021008028213C0460003C07600000
-:1053F0002406000810600006348420788C420000E7
-:10540000ACE220088C63000003E00008ACE3200C51
-:105410000A000E6000000000240300403C0260000F
-:1054200003E00008AC4320003C0760008F860004C6
-:105430008CE520740086102100A2182B1460000750
-:10544000000028218F8AFD9024050001A14400134B
-:105450008F89000401244021AF88000403E0000884
-:1054600000A010218F84FD908F850004908600138A
-:1054700030C300FF00A31023AF82000403E0000844
-:10548000A08000138F84FD9027BDFFE8AFB000100F
-:10549000AFBF0014908900119087001124020028EA
-:1054A000312800FF3906002830E300FF2485002C56
-:1054B0002CD00001106200162484001C0E0000395C
-:1054C000000000008F8FFD903C0560002402020464
-:1054D00095EE003E95ED003C000E5C0031ACFFFF08
-:1054E000016C5025ACAA20105200000124020004D7
-:1054F000ACA220000000000000000000000000003E
-:105500008FBF00148FB0001003E0000827BD001803
-:105510000A000071000028218F85FD9027BDFFD86B
-:10552000AFBF0020AFB3001CAFB20018AFB1001482
-:10553000AFB000100080982190A4001124B0001C8E
-:1055400024B1002C308300FF386200280E00005B7D
-:105550002C5200010E000063000000000200202118
-:105560001240000202202821000028210E000039EC
-:10557000000000008F8DFD903C0880003C0560001D
-:1055800095AC003E95AB003C02683025000C4C0009
-:10559000316AFFFF012A3825ACA72010240202023D
-:1055A000ACA6201452400001240200028FBF00204C
-:1055B0008FB3001C8FB200188FB100148FB0001091
-:1055C00027BD002803E00008ACA2200027BDFFE0B3
-:1055D000AFB20018AFB10014AFB00010AFBF001CE5
-:1055E0003C1160008E2320748F82000430D0FFFFB6
-:1055F00030F2FFFF1062000C2406008F0E0000390D
-:10560000000000003C06801F0010440034C5FF006D
-:105610000112382524040002AE272010000030219A
-:10562000AE252014AE2420008FBF001C8FB20018BE
-:105630008FB100148FB0001000C0102103E00008EB
-:1056400027BD002027BDFFE0AFB0001030D0FFFF26
-:10565000AFBF0018AFB100140E00003930F1FFFFEA
-:1056600000102400009180253C036000AC702010E5
-:105670008FBF00188FB100148FB0001024020004F7
-:10568000AC62200027BD002003E0000800001021CC
-:1056900027BDFFE83C0B6018AFBF00108D6F5000B6
-:1056A0002418FF7F340C807101F8702435CD380C3C
-:1056B000240A00313C098000AD6D50003C08800A8E
-:1056C000AD6C53BCAD2A00080E0004D1AF88004079
-:1056D0000E00048F000000000E00004800000000D3
-:1056E0003C0760008CE508082406FFF03C035709DE
-:1056F00000A620243462F000108200622419000108
-:10570000AF80004C0E000BF2000000003C0660165B
-:105710003C0760148CC400008CE500A03C03FFFF34
-:10572000008310243C1F535300052FC2105F004F0D
-:1057300034C77C0094E201F2A780006410400003AB
-:10574000A7800074384B1E1EA78B006494E201F8FA
-:10575000104000048F8D004C384C1E1EA78C007426
-:105760008F8D004C11A0000497840074240E00203B
-:10577000A78E0064978400742C8F008151E0000193
-:1057800024040080978600642CD804015300000193
-:10579000240604003C0260008C4504382419103CA7
-:1057A00030BFFFFF13F900033083FFFF10600018C4
-:1057B00024080050A38000769389007651200019B8
-:1057C000A7840074A7800074978C00748FBF0010AA
-:1057D0003C0A600E24EB0388354600100000382197
-:1057E0000000202127BD0018A78000643C010800AC
-:1057F000AC2C0080AF8B0010AF860048A780006CF7
-:10580000A780008AAF87001803E00008AF84001467
-:10581000A3880076938900765520FFEBA78000745B
-:10582000A7840074978C00748FBF00103C0A600E30
-:1058300024EB0388A7860064000038213546001059
-:105840000000202127BD00183C010800AC2C00807E
-:10585000AF8B0010AF860048A780006CA780008A3D
-:10586000AF87001803E00008AF84001400055080E3
-:10587000014648218D2800043C0660000A00010F03
-:10588000010638210A000103AF99004C3083FFFF65
-:105890008F8800408F87003C000321403C0580003A
-:1058A0003C020050008248253C0660003C0A010092
-:1058B00034AC04008CCD08E001AA58241160000526
-:1058C000000000008CCF08E024E7000101EA702509
-:1058D000ACCE08E08D19001001805821ACB9003819
-:1058E0008D180014ACB8003CACA9003000000000DA
-:1058F00000000000000000000000000000000000A8
-:105900000000000000000000000000003C038000D8
-:105910008C640000308200201040FFFD3C0F6000CE
-:105920008DED08E03C0E010001AE18241460FFE18B
-:1059300000000000AF87003C03E00008AF8B005080
-:105940008F850040240BFFF03C06800094A7001ACE
-:105950008CA9002430ECFFFF000C38C000EB502471
-:10596000012A4021ACC8003C8CA400248CC3003C1C
-:105970000083102318400033000000008CAD00208D
-:1059800025A200013C0F0050ACC2003835EE0010DB
-:105990003C068000ACCE003000000000000000009B
-:1059A00000000000000000000000000000000000F7
-:1059B00000000000000000003C0480008C99000002
-:1059C000333800201300FFFD30E2000810400017BC
-:1059D0003C0980008C880408ACA800108C83040C5F
-:1059E000ACA300143C1900203C188000AF19003013
-:1059F00094AE001894AF001C01CF3021A4A600186B
-:105A000094AD001A25A70001A4A7001A94AB001AB0
-:105A100094AC001E118B00030000000003E000089E
-:105A20000000000003E00008A4A0001A8D2A040072
-:105A3000ACAA00108D240404ACA400140A0001BC1C
-:105A40003C1900208CA200200A0001A43C0F005049
-:105A50000A0001920000000027BDFFE8AFBF001060
-:105A60000E0001D6000000008F8900408FBF00109B
-:105A70003C038000A520000A9528000A9527000411
-:105A800027BD00183105FFFF30E6000F00061500A6
-:105A900000A2202503E00008AC6400803C0508005B
-:105AA0008CA500208F83000C27BDFFE8AFB000104D
-:105AB000AFBF001410A300100000802124040001D7
-:105AC0000204300400A6202400C310245044000621
-:105AD00026100001001018802787FD941480000A0A
-:105AE00000671821261000012E0900025520FFF33F
-:105AF0008F83000CAF85000C8FBF00148FB0001097
-:105B000003E0000827BD00188C6800003C058000F9
-:105B1000ACA800240E0001D8261000013C050800A6
-:105B20008CA500200A0001FD2E09000224050001B9
-:105B3000008518043C0408008C84002027BDFFC8A1
-:105B4000AFBF003400831024AFBE0030AFB7002CCD
-:105B5000AFB60028AFB50024AFB40020AFB3001C2F
-:105B6000AFB20018AFB1001410400051AFB0001038
-:105B70008F840040948700069488000A00E8302350
-:105B800030D5FFFF12A0004B8FBF0034948B00185C
-:105B9000948C000A016C50233142FFFF02A2482B73
-:105BA0001520000202A02021004020212C8F00059A
-:105BB00015E0000200809821241300040E00016506
-:105BC000026020218F87004002609021AF80004456
-:105BD00094F4000A026080211260004E3291FFFFAF
-:105BE0003C1670003C1440003C1E20003C17600036
-:105BF0008F9900508F380000031618241074004F3E
-:105C00000283F82B17E0003600000000107E0047EA
-:105C10008F86004414C0003A2403000102031023BD
-:105C2000022320213050FFFF1600FFF13091FFFFCB
-:105C30008F8700403C1100203C108000AE110030E6
-:105C400094EB000A3C178000024B5021A4EA000AA2
-:105C500094E9000A94E800043123FFFF3106000FA5
-:105C600000062D000065F025AEFE008094F3000ACA
-:105C700094F6001812D30036001221408CFF001455
-:105C80008CF4001003E468210000C02101A4782BEB
-:105C90000298702101CF6021ACED0014ACEC001033
-:105CA00002B2382330F5FFFF16A0FFB88F84004002
-:105CB0008FBF00348FBE00308FB7002C8FB6002806
-:105CC0008FB500248FB400208FB3001C8FB2001852
-:105CD0008FB100148FB0001003E0000827BD00381A
-:105CE0001477FFCC8F8600440E000DC102002021E6
-:105CF000004018218F86004410C0FFC90203102302
-:105D0000027070238F87004001C368210A00028857
-:105D100031B2FFFF8F86004414C0FFC93C11002040
-:105D20003C1080000A000252AE1100300E0003FA4F
-:105D3000020020210A00027F0040182102002021D9
-:105D40000E000811022028210A00027F00401821BD
-:105D50000E000192000000000A00026B02B238231C
-:105D600027BDFFC8AFB7002CAFB60028AFB50024E1
-:105D7000AFB40020AFB3001CAFB20018AFB1001435
-:105D8000AFB00010AFBF00300E0000E624130001DA
-:105D90003C047FFF3C0380083C0220003C010800DB
-:105DA000AC2000703497FFFF34750080345200033C
-:105DB0003C1612C0241400013C1080002411FF8006
-:105DC0000E0001E9000000008F8700488F8B00184B
-:105DD0008F8900148CEA00EC8CE800E8014B302B32
-:105DE0000109282300A6102314400006014B1823A4
-:105DF0001440000E3C05800002C3602B1180000B94
-:105E0000000000003C0560008CEE00EC8CED00E82A
-:105E10008CA4180CAF8E001804800045AF8D0014C0
-:105E20008F8F0010ADF400003C0580008CBF000097
-:105E30003BF90001333800011700FFE13C0380000B
-:105E40008C62010024060C001046000900000000CE
-:105E50008C6801002D043080548000103C048000C8
-:105E60008C6901002D2331811060000C3C048000FE
-:105E70008CAA010011460004000020218CA601001C
-:105E800024C5FF8130A400FF8E0B01000E00020D1F
-:105E9000AE0B00240A0002F33C0480008C8E01004B
-:105EA000240C0020AC8E002092AD000031A300FF36
-:105EB000106C00232407005010670026000000002B
-:105EC0003C0480008C8F010015E0000300000000FE
-:105ED000566000143C0440008C8701008C8D01004A
-:105EE0000000982100F17024000E594031AC007F71
-:105EF000016C302500D22825AC8508308C8A010041
-:105F00008C83010025490100013110240002F94071
-:105F10003068007F03E8C8250332C025AC980830FC
-:105F20003C044000AE0401380A0002B20000000048
-:105F300000973824ACA7180C0A0002CB8F8F0010F2
-:105F40008C8501000E0007C3240400800A0002F3C0
-:105F50003C0480008C8401000E001420000000002E
-:105F60000A0002F33C04800000A4102B240300016B
-:105F700010400009000030210005284000A4102B2B
-:105F800004A00003000318405440FFFC0005284013
-:105F90005060000A0004182B0085382B54E00004E0
-:105FA0000003184200C33025008520230003184257
-:105FB0001460FFF9000528420004182B03E00008D4
-:105FC00000C310213084FFFF30C600FF3C07800073
-:105FD0008CE201B80440FFFE00064C00012430258D
-:105FE0003C08200000C820253C031000ACE00180E4
-:105FF000ACE50184ACE4018803E00008ACE301B83F
-:106000003C0660008CC5201C2402FFF03083020097
-:10601000308601001060000E00A2282434A5000183
-:106020003087300010E0000530830C0034A50004F8
-:106030003C04600003E00008AC85201C1060FFFDFC
-:106040003C04600034A5000803E00008AC85201C77
-:1060500054C0FFF334A500020A00034B3087300020
-:1060600027BDFFE8AFB00010AFBF00143C076000D1
-:10607000240600021080001100A080218F830050B0
-:106080000E0003428C6400188F8200500000202113
-:10609000240600018C45000C0E00033300000000B4
-:1060A0001600000224020003000010218FBF00141C
-:1060B0008FB0001003E0000827BD00188CE8201CFA
-:1060C0002409FFF001092824ACE5201C8F8700502B
-:1060D0000A0003688CE5000C3C02600E0080402141
-:1060E00034460100240900180000000000000000F0
-:1060F000000000003C0A00503C03800035470200CD
-:10610000AC68003834640400AC65003CAC67003017
-:106110008C6C0000318B00201160FFFD2407FFFF15
-:106120002403007F8C8D00002463FFFF248400047F
-:10613000ACCD00001467FFFB24C600040000000083
-:10614000000000000000000024A402000085282BAD
-:106150003C0300203C0E80002529FFFF0105402163
-:10616000ADC300301520FFE00080282103E00008C7
-:10617000000000008F82005027BDFFD8AFB3001C85
-:10618000AFBF0020AFB20018AFB10014AFB0001025
-:1061900094460002008098218C5200182CC3008184
-:1061A0008C4800048C4700088C51000C8C4900106E
-:1061B000106000078C4A00142CC4000414800013E3
-:1061C00030EB000730C5000310A0001000000000F5
-:1061D0002410008B02002021022028210E0003330E
-:1061E00024060003166000022402000300001021B0
-:1061F0008FBF00208FB3001C8FB200188FB1001426
-:106200008FB0001003E0000827BD00281560FFF1E3
-:106210002410008B3C0C80003C030020241F000154
-:10622000AD830030AF9F004400000000000000007C
-:10623000000000002419FFF024D8000F031978246F
-:106240003C1000D0AD88003801F0702524CD00034B
-:106250003C08600EAD87003C35850400AD8E0030F3
-:10626000000D38823504003C3C0380008C6B00003C
-:10627000316200201040FFFD0000000010E0000827
-:1062800024E3FFFF2407FFFF8CA800002463FFFF27
-:1062900024A50004AC8800001467FFFB24840004DC
-:1062A0003C04600EAC8600380000000000000000D6
-:1062B000000000003C0700203C0680000120202157
-:1062C00001402821ACC700300E0003780000802177
-:1062D0000E000342024020210A0003B802002021E0
-:1062E00027BDFFE0AFB200183092FFFFAFB100143E
-:1062F000AFBF001CAFB000101640000D0000882199
-:106300000A000427022010212405000350850027DD
-:106310008CE5000C0000000D262C00013191FFFFE0
-:1063200024EB00200232502B11400019AF8B00509B
-:106330008F820044144000168F8700503C06700086
-:106340003C0320008CE5000000A6202414830010EC
-:106350008F840058000544023C09800000A9802475
-:106360001480FFE9310600FF2CCA000B1140FFEB3F
-:10637000262C0001000668803C0E080025CE52A0A5
-:1063800001AE60218D8B000001600008000000005C
-:10639000022010218FBF001C8FB200188FB1001493
-:1063A0008FB0001003E0000827BD00200E0003336B
-:1063B000240400841600FFD88F8700500A000408C8
-:1063C000AF800058020028210E00035A2404000167
-:1063D0008F8700500A000408AF820058020028216D
-:1063E0000E00035A000020210A0004378F87005056
-:1063F0000E00039F020020218F8700500A0004082E
-:10640000AF82005830AFFFFF000F19C03C0480007E
-:106410008C9001B80600FFFE3C1920043C181000C7
-:10642000AC830180AC800184AC990188AC9801B840
-:106430000A000409262C000190E2000290FF0003EC
-:106440000000202100023A0000FF28252406000851
-:106450000E000333000000001600FFDD24020003DD
-:106460008F870050000010210A000408AF820058F6
-:1064700090E50002000020210A00045624060009CD
-:1064800094E5000490E9000390E300020005340065
-:106490000009420000C82025008328252406000AA0
-:1064A0000A0004560000202190E50002000020218F
-:1064B0000A0004562406000B000449C23127003F9D
-:1064C000000443423C028000000820402403168060
-:1064D0002CE60020AC43002C24EAFFE024820001DB
-:1064E00014C0000330A900FF00801021314700FFD5
-:1064F000000260803C0D8000240A0001018D2021F3
-:106500003C0B000E00EA2804008B3021112000050E
-:10651000000538278CCE000001C5382503E00008AF
-:10652000ACC700008CD800000307782403E0000803
-:10653000ACCF000027BDFFE0AFB10014AFB000103A
-:10654000AFBF00183C0760008CE408083402F0007C
-:106550003C1160003083F000240501C03C04800E33
-:106560000000302110620006241000018CEA0808A7
-:106570003149F0003928E0000008382B000780403E
-:106580003C0D0200AE2D0814240C16803C0B80003C
-:106590008E2744000E000E6AAD6C002C1200000421
-:1065A0003C02169124050001120500103C023D6CCE
-:1065B000345800E0AE3844083C1108008E31007CAD
-:1065C0008FBF00183C06600000118540360F168012
-:1065D0008FB100148FB000103C0E020027BD0020C8
-:1065E000ACCF442003E00008ACCE08103C0218DA1F
-:1065F000345800E0AE3844083C1108008E31007C6D
-:106600008FBF00183C06600000118540360F1680D1
-:106610008FB100148FB000103C0E020027BD002087
-:10662000ACCF442003E00008ACCE08100A00047090
-:10663000240500010A00047000002821240204003F
-:10664000A7820024A780001C000020213C0608002F
-:1066500024C655A82405FFFF2489000100044080BA
-:106660003124FFFF010618212C87002014E0FFFAD7
-:10667000AC65000024040400A7840026A780001E47
-:10668000000020213C06080024C656282405FFFFF0
-:10669000248D00010004608031A4FFFF0186582191
-:1066A0002C8A00201540FFFAAD650000A780002865
-:1066B000A7800020A7800022000020213C060800BF
-:1066C00024C656A82405FFFF249900010004C080B9
-:1066D0003324FFFF030678212C8E000415C0FFFA37
-:1066E000ADE500003C0560008CA73D002403E08F71
-:1066F00000E310243446014003E00008ACA63D004E
-:106700002487007F000731C224C5FFFF000518C29F
-:10671000246400013082FFFF000238C0A7840030EB
-:106720003C010800AC270030AF80002C000028217D
-:1067300000002021000030212489000100A7282129
-:106740003124FFFF2CA81701110000032C830080C7
-:106750001460FFF924C6000100C02821AF86002C78
-:1067600010C0001DA786002A24CAFFFF000A11429C
-:106770003C080800250856A81040000A0000202107
-:10678000004030212407FFFF248E000100046880B0
-:1067900031C4FFFF01A860210086582B1560FFFA65
-:1067A000AD87000030A2001F504000080004308078
-:1067B000240300010043C80400041080004878212D
-:1067C0002738FFFF03E00008ADF8000000C82021D3
-:1067D0002405FFFFAC85000003E000080000000076
-:1067E00030A5FFFF30C6FFFF30A8001F00806021EA
-:1067F00030E700FF000529420000502110C0001DB5
-:1068000024090001240B000125180001010B2004BC
-:10681000330800FF01267826390E00202DED0001F7
-:106820002DC2000101A218251060000D0144502561
-:106830000005C880032C40210100182110E0000F42
-:10684000000A20278D040000008A1825AD030000EF
-:1068500024AD0001000040210000502131A5FFFFC0
-:10686000252E000131C9FFFF00C9102B1040FFE7A2
-:106870002518000103E00008000000008D0A000058
-:10688000014440240A000556AC68000027BDFFE81B
-:1068900030A5FFFF30C6FFFFAFB00010AFBF001440
-:1068A00030E7FFFF000050213410FFFF000060219F
-:1068B00024AF001F00C04821241800012419002023
-:1068C00005E0001601E010210002F943019F682A4B
-:1068D0000009702B01AE402411000017000C188035
-:1068E0000064102110E000058C4B000000F840040B
-:1068F0000008382301675824000038211540004162
-:1069000000004021556000163169FFFF258B000112
-:10691000316CFFFF05E1FFEC01E0102124A2003EF5
-:106920000002F943019F682A0009702B01AE402440
-:106930001500FFEB000C1880154600053402FFFF20
-:10694000020028210E00053A000038210200102123
-:106950008FBF00148FB0001003E0000827BD00189F
-:106960001520000301601821000B1C0224080010F0
-:10697000306A00FF15400005306E000F250D00083D
-:1069800000031A0231A800FF306E000F15C0000589
-:10699000307F00032510000400031902320800FFB5
-:1069A000307F000317E0000538690001250200026E
-:1069B00000031882304800FF3869000131230001CC
-:1069C00010600004310300FF250A0001314800FF78
-:1069D000310300FF000C694001A34021240A00019B
-:1069E00010CAFFD53110FFFF246E000131C800FF2F
-:1069F0001119FFC638C900012D1F002053E0001CEB
-:106A0000258B0001240D00010A0005CD240E002075
-:106A100051460017258B000125090001312800FF90
-:106A20002D09002051200012258B00012543000173
-:106A3000010D5004014B1024250900011440FFF4FE
-:106A4000306AFFFF3127FFFF10EE000C2582FFFFA9
-:106A5000304CFFFF000050213410FFFF312800FFB1
-:106A60002D0900205520FFF225430001258B000150
-:106A7000014648260A000587316CFFFF00003821D7
-:106A8000000050210A0005D93410FFFF27BDFFD8B0
-:106A9000AFB0001030F0FFFFAFB10014001039426A
-:106AA0003211FFE000071080AFB3001C00B12823B3
-:106AB00030D3FFFFAFB2001830A5FFFF0080902158
-:106AC0000260302100442021AFBF00200E00056588
-:106AD0003207001F022288213403FFFF02402021D9
-:106AE00002002821026030210000382110430009F3
-:106AF0003231FFFF022010218FBF00208FB3001C16
-:106B00008FB200188FB100148FB0001003E000089E
-:106B100027BD00280E000565000000000040882108
-:106B2000022010218FBF00208FB3001C8FB20018ED
-:106B30008FB100148FB0001003E0000827BD0028BB
-:106B4000000424003C036000AC603D0810A000027B
-:106B5000348210063482101603E00008AC623D0453
-:106B600027BDFFE0AFB00010309000FF2E020006FE
-:106B7000AFBF001810400008AFB100140010308003
-:106B80003C030800246352CC00C328218CA40000DD
-:106B90000080000800000000000020218FBF0018C6
-:106BA0008FB100148FB000100080102103E00008A6
-:106BB00027BD00209791002A1620005100002021B7
-:106BC0003C020800904200330A000640000000002A
-:106BD000978D002615A00031000020210A000640F4
-:106BE000240200089787002414E0001A00001821EE
-:106BF00000602021240200011080FFE98FBF0018EF
-:106C0000000429C20045302100A6582B1160FFE482
-:106C10003C0880003C072000000569C001A76025F2
-:106C2000AD0C00203C0380082402001F2442FFFF1B
-:106C3000AC6000000441FFFD2463000424A50001B2
-:106C400000A6702B15C0FFF5000569C00A00062AD2
-:106C50008FBF00189787001C3C040800248455A8A7
-:106C6000240504000E0005E524060001978B00248E
-:106C700024440001308AFFFF2569FFFF2D480400EE
-:106C80000040282115000040A789002424AC3800CA
-:106C9000000C19C00A00063EA780001C9787001E42
-:106CA0003C04080024845628240504000E0005E551
-:106CB0002406000197990026244400013098FFFF24
-:106CC000272FFFFF2F0E04000040882115C0002C45
-:106CD000A78F0026A780001E3A0200032624010089
-:106CE0003084FFFF0E0006122C4500010011F8C091
-:106CF00027F00100001021C00A000640240200080D
-:106D00009785002E978700223C040800248456A80B
-:106D10000E0005E5240600019787002A8F89002CC4
-:106D20002445000130A8FFFF24E3FFFF0109302BB9
-:106D30000040802114C00018A783002AA7800022E9
-:106D4000978500300E000E5402002021244A0500D1
-:106D50003144FFFF0E000612240500013C05080027
-:106D600094A500320E000E5402002021244521007B
-:106D70003C020800904200330A000640000521C092
-:106D80000A000678A784001E24AC3800000C19C045
-:106D90000A00063EA784001C0A000692A78500226E
-:106DA000308400FF27BDFFE82C820006AFBF00142F
-:106DB000AFB000101040001500A038210004408042
-:106DC0003C030800246352E4010328218CA4000042
-:106DD000008000080000000024CC007F000751C2A2
-:106DE000000C59C23170FFFF2547C40030E5FFFF9A
-:106DF0002784001C020030210E00053A2407000100
-:106E00009786002802062021A78400288FBF00143F
-:106E10008FB0001003E0000827BD00183C050800F3
-:106E20008CA50030000779C20E00031C25E4DF00AA
-:106E30003045FFFF3C040800248456A824060001C6
-:106E40000E00053A24070001978E002A8FBF001418
-:106E50008FB0001025CD000127BD001803E0000809
-:106E6000A78D002A0007C9C22738FF00001878C282
-:106E700031F0FFFF3C04080024845628020028213A
-:106E8000240600010E00053A24070001978D002614
-:106E9000260E0100000E840025AC00013C0B6000B2
-:106EA000A78C0026AD603D083604000600003021A6
-:106EB0003C0760008CE23D04305F000617E0FFFDF8
-:106EC00024C9000100061B00312600FF0064402594
-:106ED0002CC50004ACE83D0414A0FFF68FBF0014DD
-:106EE0008FB0001003E0000827BD0018000751C252
-:106EF0002549C80024060001240700013C040800BD
-:106F0000248455A80E00053A3125FFFF97870024F9
-:106F10008FBF00148FB0001024E6000127BD0018B9
-:106F200003E00008A78600243084FFFF30A5FFFFA0
-:106F30003C0680008CC201B80440FFFE3C08408043
-:106F4000008838253C031000ACC00180ACC501842A
-:106F5000ACC7018803E00008ACC301B83084FFFF70
-:106F60003C0680008CC201B80440FFFE3C0840385B
-:106F70008CA70000008828253C031000ACC70180C6
-:106F8000ACC5018803E00008ACC301B88F83007072
-:106F90008F8600681066000B008040213C070800C7
-:106FA00024E756B8000328C000A710218C44000035
-:106FB00024630001108800053063000F5466FFFA57
-:106FC000000328C003E00008000010213C0708006F
-:106FD00024E756BC00A7302103E000088CC2000063
-:106FE0003C03900034620001008220253C038000B5
-:106FF000AC6400208C65002004A0FFFE00000000AF
-:1070000003E00008000000003C028000344300015F
-:107010000083202503E00008AC44002027BDFFE0EA
-:10702000AFB100143091FFFFAFB00010AFBF001838
-:107030001220001200A080218CA5000014A00011D5
-:10704000240400023C0680008CC201B80440FFFE0C
-:107050003C074000022720258FBF00188FB1001485
-:107060008FB000103C03100027BD0020ACC501808C
-:10707000ACC4018803E00008ACC301B80A000753A0
-:107080008CA500000E0006AA24060200000028219C
-:107090000A000753AE0000003087FFFF3C06800067
-:1070A0008CC201B80440FFFE3C0A40068CA90000D7
-:1070B00000EA4025ACC901808CA400043C03100008
-:1070C000ACC40184ACC8018803E00008ACC301B8BB
-:1070D0008F83FD8C27BDFFE8AFBF0014AFB0001059
-:1070E00090670008008010210080282130E60040D1
-:1070F0000000202110C000088C5000000E00008805
-:1071000002002021020020218FBF00148FB0001048
-:107110000A0004CD27BD00180E000768000000001B
-:107120000E00008802002021020020218FBF0014E1
-:107130008FB000100A0004CD27BD001827BDFFE066
-:10714000AFB000108F90FD8CAFBF001CAFB2001825
-:10715000AFB1001492060001008088210E00073AAA
-:1071600030D2000492040005001129C2A6050000D7
-:1071700034830040A20300050E00074402202021B2
-:107180000E0004CF0220202124020001AE02000CD8
-:1071900002202821A602001024040002A6020012E8
-:1071A00024060200A60200140E0006AAA60200167B
-:1071B0001640000F8FBF001C978C006C3C0B080022
-:1071C0008D6B00782588FFFF3109FFFF256A0001DC
-:1071D000012A382B10E00006A788006C3C0F6006DF
-:1071E000240E001635ED0010ADAE00508FBF001C10
-:1071F0008FB200188FB100148FB0001003E00008A8
-:1072000027BD002027BDFFE0AFB10014AFBF0018BD
-:10721000AFB000101080000400A08821240200807C
-:1072200010820007000000000000000D8FBF001852
-:107230008FB100148FB0001003E0000827BD0020BC
-:107240000E00073A00A020218F86FD8C022020210D
-:1072500090C500050E00074430B000FF2403003E37
-:107260001603FFF1000000003C0580008CA40178AB
-:107270000480FFFE240800073C071000ACB1014069
-:1072800002202021A0A801448FBF00188FB1001454
-:107290008FB00010ACA701780A00079127BD00202D
-:1072A00027BDFFE0AFB00010AFBF0018AFB10014B2
-:1072B0003C1080008E110020000000000E0004CF62
-:1072C000AE040020AE1100208FBF00188FB1001453
-:1072D0008FB0001003E0000827BD00203084FFFFBE
-:1072E0003C0680008CC201B80440FFFE3C084035DB
-:1072F000008838253C031000ACC50180ACC0018477
-:10730000ACC7018803E00008ACC301B83084FFFFBC
-:107310003C0680008CC201B80440FFFE3C084036A9
-:10732000008838253C031000ACC50180ACC0018446
-:10733000ACC7018803E00008ACC301B827BDFFD08B
-:10734000AFB500243095FFFFAFB60028AFB40020E2
-:10735000AFBF002CAFB3001CAFB20018AFB1001428
-:10736000AFB0001030B6FFFF12A000270000A02130
-:107370008F9200508E4300003C06800024020040A3
-:1073800000033E0200032C0230E4007F00669824D4
-:107390001482001D30A500FF8F8300602C68000A56
-:1073A000510000108F860044000358803C0C0800F8
-:1073B000258C5300016C50218D49000001200008EC
-:1073C0000000000002D4702131C5FFFF0E00070C41
-:1073D00024040084166000028F920050AF80006089
-:1073E0008F860044264F00202689000101E090216D
-:1073F0003134FFFF14C00004AF8F00500295282BDA
-:1074000014A0FFDC00000000028010218FBF002CC0
-:107410008FB600288FB500248FB400208FB3001CD6
-:107420008FB200188FB100148FB0001003E0000875
-:1074300027BD00302407003414A7014600000000D7
-:107440009247000E8F98FD908F90FD8C240F1600B0
-:10745000A30700199244000D3C0880003C07800CF3
-:10746000A3040018965F00123C0960003C117FFFE6
-:10747000A61F005C965900103622FFFF2404000569
-:107480003325FFFFAE0500548E46001CAD0F0028CB
-:107490008CEE00008D2D444801C6182601A3302132
-:1074A000AE0600388E0C003824CA00013C0D7F0067
-:1074B000AE0C003C8E0B003CAF0B0004AE0A00206B
-:1074C0008E130020AE13001CA300001BAE02002C84
-:1074D000A30400128E5F001424130050AE1F00346A
-:1074E0008E190034AF1900148E450018AE050048FF
-:1074F000924F000CA20F004E92090008352E00207A
-:10750000A20E00088E030018006D6024358B400029
-:10751000AE0B0018920A0000315200FF125302A66F
-:107520002413FF803C040800248457380E0007769B
-:1075300000000000240C0004240800013C050800A1
-:107540008CA557383C048000A20C0025A208000539
-:107550008C9001780600FFFE8F920050240D0002EF
-:107560003C031000AC850140A08D0144AC83017840
-:107570000A00083AAF8000602CAD003711A0FF99D7
-:107580008F860044000580803C1108002631532876
-:10759000021178218DEE000001C0000800000000FB
-:1075A0002410000414B0008E3C0780003C0B08003F
-:1075B0008D6B57388F86FD8CACEB00208E43000816
-:1075C0008F8FFD90240E0050ACC300308E4A00080F
-:1075D000ACCA00508E42000CACC200348E44001085
-:1075E000ACC400388E5F0010ACDF00548E5900141C
-:1075F000ACD9003C8E580018ADF800048E51001C28
-:10760000ACD1002090C5000030A900FF112E0276F9
-:10761000000000008CC500348CD1003000B1302354
-:1076200004C000F32404008C126000F02402000364
-:107630000A00083AAF820060240F000514AF00680A
-:107640003C0B80003C0308008C6357388F86FD8C10
-:10765000AD6300208E4A00048F99FD90240720001E
-:10766000ACCA001C9242000824120008A322001990
-:107670008F840050909F0009A33F00188F85005011
-:1076800090B8000A330400FF10920010288C000903
-:10769000158000BC24080002240E0020108E000B70
-:1076A00034078000288900211520000824074000A5
-:1076B00024110040109100053C070001240F0080B8
-:1076C000108F00023C070002240740008CDF0018E6
-:1076D0003C04FF0003E4C8240327C025ACD80018ED
-:1076E00090B2000BA0D200278F8300509465000C4D
-:1076F00010A0022A000000009467000C3C198000D2
-:10770000240BFFBFA4C7005C9062000E2407000496
-:10771000A0C200088F840050909F000FA0DF0009D6
-:107720008F8C00508D9200108F38007402582823DF
-:10773000ACC500588D8F0014ACCF002C959100186B
-:107740003229FFFFACC90040958E001A31D0FFFFEF
-:10775000ACD000448D8D001CACCD00489588000253
-:10776000A4C800789183000EA0C3000890CA000846
-:10777000014B1024126001D4A0C200088F92005067
-:107780000A00083AAF8700602406000614A6001419
-:107790003C0D80003C1008008E1057388F8CFD88FF
-:1077A000ADB000208E4800188F86FD8C8F8AFD902A
-:1077B000AD8800008CC3003824040005AD830004AC
-:1077C0008CCB003C12600081AD4B00000A00083AEF
-:1077D000AF840060240E000710AE004B24040006A6
-:1077E0003C05080024A557380E00074924040081F1
-:1077F0008F9200500013102B0A00083AAF820060ED
-:107800002419002314B9FFF63C0B80003C0C08003F
-:107810008D8C57388F8AFD90AD6C00208F91FD8C38
-:107820008E4600042544002026450014AE2600287C
-:10783000240600030E000E60255000308F87005094
-:1078400002002021240600030E000E6024E500083B
-:107850003C040800248457380E000776000000001E
-:1078600092220000241F0050304400FF549FFFE18B
-:107870008F9200500E000E4B000000000A00093FDE
-:107880008F9200502403003314A300323C02800086
-:107890003C1108008E3157388F8EFD90AC5100207E
-:1078A0008E440008240900288F88FD8CADC4003068
-:1078B0008E5F000C24060009ADDF00348E590010E5
-:1078C000ADD900388E580014ADD800208E45001870
-:1078D000ADC500248E4F001CADCF0028A1C90011FA
-:1078E0008E4D000412600031AD0D00288F920050C3
-:1078F0000A00083AAF8600602409002214A9FFB8E4
-:1079000000000000240400073C0F08008DEF5738EA
-:107910003C118000AE2F00205660FEB1AF840060A5
-:107920003C040800248457380E00077624130050C6
-:107930008F98FD8C93120000324500FF10B301694F
-:10794000000000008F920050000020210A00083A39
-:10795000AF8400603C05080024A557380E000719C5
-:10796000240400810A00093F8F92005002D498211C
-:107970003265FFFF0E00070C240400840A00083A59
-:107980008F9200501088FF512407040028870003BD
-:1079900010E001A324100004240D0001548DFF4BBE
-:1079A000240740000A0008F5240701003C050800F0
-:1079B00024A557380E000768240400828F920050D7
-:1079C000000030210A00083AAF8600603C0408003D
-:1079D000248457388CC200380E0007768CC3003CD4
-:1079E0008F9200500A000995000020212404008293
-:1079F0003C05080024A557380E0007680000000069
-:107A00008F920050000010210A00083AAF820060F7
-:107A10008E5000048F91FD8C3C0A8000AD500020F8
-:107A200092220005020028213046000214C0018085
-:107A30002404008A8F92FD90020028212404008DE6
-:107A4000924B001B3163002014600179000000009C
-:107A5000922D0009240C001231A800FF110C0174B2
-:107A6000240400810E00073A020020219245001BE9
-:107A7000240E00040200202134A90042A249001B68
-:107A80000E000744A22E00253C0480008C91017852
-:107A90000620FFFE24180002AC900140A09801448B
-:107AA0008F9200503C0F1000AC8F01780A00094003
-:107AB0000013102B8E5000048F91FD8C3C1F800012
-:107AC000AFF0002092390005020028213327000280
-:107AD00014E000172404008A9224000924120004F0
-:107AE00002002821308600FF10D2001124040081FA
-:107AF0000E00073A020020218F8CFD90240B00120B
-:107B00002403FFFE918D001B0200202135A80020D8
-:107B1000A188001BA22B0009922A00050143102412
-:107B20000E000744A22200050200282100002021A7
-:107B30000E000805000000000A00093F8F92005067
-:107B40008E5100043C0280003C100800261057387B
-:107B5000AC5100203C010800AC315738924600037C
-:107B600030C40004108001658F84FD8C240200065F
-:107B7000A0820009924D001B2408FFC031AC003FD9
-:107B800001885825A08B000892430003306A000149
-:107B90001540015C000000008E420008AE020008A3
-:107BA0003C0208008C4257401040015B8F8EFD90D4
-:107BB000000281C28F85FD8CA5D0000C8E5F000C69
-:107BC000240F000124090014ADDF002C8E59001091
-:107BD000ADD9001C96470016A5C7003C9658001466
-:107BE000A5D8003EACAF000CA4AF0010A4AF0012AB
-:107BF000A4AF0014A4AF00161260015FA1C9001168
-:107C000092440003309200022E5300018F920050E4
-:107C1000266200080A00083AAF8200608E4600041F
-:107C20003C0580003C048008ACA600208E4700087C
-:107C30009089000024110050312200FF105100B83B
-:107C4000240500883C0480008C8F01B805E0FFFE0D
-:107C50000013802B3C18400900B81025AF9000603D
-:107C60003C101000AC860180AC870184AC82018896
-:107C7000AC9001B80A00083B8F8600448E45000492
-:107C80003C0680003C098008ACC50020913F000004
-:107C90002404005033F900FF132400B024060088A8
-:107CA0003C0480008C8A01B80540FFFE3C0E400E6B
-:107CB00000CE68253C081000AC850180AC800184B2
-:107CC000AC8D0188AC8801B8912B0000240CFF809A
-:107CD00024040004016C1825240600300E0006AAB6
-:107CE000A12300000A00093F8F9200508E5000042B
-:107CF0008F91FD903C0F8000ADF000209225001B7D
-:107D000030A900101120007C240300813C04800075
-:107D10008C8701B804E0FFFE3C1F401FAC9001803F
-:107D2000007F10250013C82B3C101000AC8001848C
-:107D3000AF990060AC820188AC9001B80A00083BA2
-:107D40008F8600448E44001C0E00072500000000B2
-:107D5000104000F8004038218F920050240600891E
-:107D60003C0580008CAE01B805C0FFFE000000009D
-:107D7000ACA701808E50001C3C1140010013782BF1
-:107D800000D138253C131000ACB00184AF8F0060E7
-:107D9000ACA70188ACB301B80A00083B8F86004449
-:107DA000965900023C10080026105738333800045A
-:107DB000130000A33C0460008E5F001C3C068000A2
-:107DC000ACDF00203C010800AC3F5738964F000262
-:107DD00031E7000114E000E3000000008E420004DF
-:107DE000AE0200083C1008008E105740120000D967
-:107DF0003C0680008F85FD8C241000018CBF00188C
-:107E00008F91FD908F89FD8803E6C825ACB90018D5
-:107E1000A0A00005ACB0000C3C1808008F1857401B
-:107E20008F870050A4B00010001879C2A4B00012CF
-:107E3000A4B00014A4B00016A62F000C8CEE00080D
-:107E40008F8D00508F8C0050AE2E002C8DA8000C12
-:107E500024070002AE28001C918B0010A22B0011F9
-:107E60008F830050906A0011A12A00088F82005071
-:107E700090440012A0A4004E8F920050924600132E
-:107E8000A22600128F920050965F0014A63F003C7D
-:107E900096590016A639003E8E580018AE380014C8
-:107EA0005660FD4FAF8700603C05080024A5573899
-:107EB0000E000749000020218F9200500000382159
-:107EC0000A00083AAF8700603C05080024A557382F
-:107ED0000E000768240400828F9200500A000922D5
-:107EE000000038210E000E4B000000008F92005061
-:107EF0000A000995000020210E00073A0200202107
-:107F00009232001B02002021365800100E00074458
-:107F1000A238001B8F9200500A000A850000182129
-:107F20009243000C306A0001114000030000000081
-:107F3000964B000EA48B002C9248000C310C0002D2
-:107F40001180FF4000002821964E00128E4D001433
-:107F5000A48E001A0A000A53AC8D001C8F83007097
-:107F60008F8700681067FF4E000030213C08080032
-:107F7000250856BC000320C0008830218CD10000A9
-:107F8000122500C8246200013043000F1467FFFA75
-:107F9000000320C00A000A6A000030213C050800E6
-:107FA00024A557380E0007682404008B8F920050D8
-:107FB0000A0009220013382B3C0B08008D6B573840
-:107FC00024D8FFFE25710100322A007F014790214D
-:107FD00002331024AD020028AE4600D0AE4000D4DB
-:107FE0000A00088BAE58001CACC000543C0E0800C0
-:107FF0008DCE57383C09800C352C0100ACEE0028A2
-:108000008E500014AD9000D08E4D0014AD8D00D474
-:108010008E4800102507FFFE0A0008C7AD87001C28
-:108020005490FDAA240740000A0008F52407100018
-:108030000E0007F9000000000A00093F8F9200506F
-:108040008C83442C3C05DEAD34B2BEEF3C0108000D
-:10805000AC20573810720090000000003C046C62A5
-:10806000348279701462000824040002978A006C3C
-:1080700097830064020028210143482B1120001936
-:1080800024040092240400020E00061A24050200B3
-:108090003C0B8000AD6200203C010800AC22573848
-:1080A0001040000D8F8E0050240C00282404000383
-:1080B00091CD001031A800FF550C000124040001EF
-:1080C0000E00004C00000000104000042404008357
-:1080D0000A000AB58F920050240400833C05080072
-:1080E00024A557380E000749000000008F92005069
-:1080F0000013382B0A00083AAF8700600A000A1EF6
-:10810000240200128E4400080E0007250000000023
-:108110000A000A2AAE0200083C05080024A55738C8
-:108120000E000719240400878F9200500A000A47A6
-:108130000013102B240400040E00061A240500303E
-:1081400014400014004038218F9200500A000A9A0F
-:10815000240600833C05080024A557380A000B7B41
-:10816000240400878E4400040E0007250000000050
-:108170000A000ABBAE0200083C05080024A55738D7
-:108180000E000768240400828F9200500A000A47FC
-:10819000000010218F9200503C0880083C0C8000A9
-:1081A000240B0050240A0001AD820020A10B000026
-:1081B000A10A000192490004A10900189244000597
-:1081C000A1040019924300063C040800248456BC14
-:1081D000A103001A924200073C030800246356B82A
-:1081E000A102001B92450008A105001C924600094F
-:1081F000A106001D925F000AA11F001E9259000BEC
-:10820000A119001F9258000CA11800209251000DD6
-:10821000A11100219250000EA1100022924F000FD8
-:10822000A10F0023924E0010A10E0024924D0011C8
-:10823000A10D0025964C0014A50C0028964B0016A5
-:108240008F8A00688F980070A50B002A9649001845
-:10825000000A10C025450001A509002C8E46001C0F
-:108260000044C8210043F82130A5000FAFE600000C
-:10827000AF27000010B80003AF8500680A000A9A13
-:108280000000302124AD000131A8000F0000302192
-:108290000A000A9AAF8800708C83442C0A000B5A9B
-:1082A0003C046C623C07080024E756B80087902124
-:1082B000ACC00000000030210A000A6AAE40000095
-:1082C0003C0482013C03600034820E02AC603D68D5
-:1082D000AF80009003E00008AC623D6C27BDFFE872
-:1082E000AFB000103090FFFF001018422C62004128
-:1082F000AFBF001414400002240400802403004097
-:108300003C010800AC3000603C010800AC23006474
-:108310000E000E5400602821244802BF2409FF806B
-:108320000109282400103980001030408FBF00144C
-:108330008FB0001000A7202100861821AF8300789D
-:108340003C010800AC2500583C010800AC24005C4E
-:1083500003E0000827BD0018308300FF30C6FFFF90
-:1083600030E400FF3C0880008D0201B80440FFFEAD
-:1083700000035400014438253C09600000E9202531
-:108380003C031000AD050180AD060184AD040188F9
-:1083900003E00008AD0301B88F8600503C0960126D
-:1083A000352700108CCB00043C0C600E3585001086
-:1083B000316A00062D480001ACE800C48CC40004FA
-:1083C000ACA431808CC2000894C30002ACA23184FA
-:1083D00003E00008A78300888F8500508F87FF186F
-:1083E0008F86FF208CAE00043C0F601235E8001031
-:1083F000ACEE00688CAD0008ACED006C8CAC0010ED
-:10840000ACCC004C8CAB000CACCB004894CA0054F4
-:108410003C0208008C42004425490001A4C90054D4
-:1084200094C400543083FFFF106200170000000066
-:108430003C0208008C420040A4C200528CA30018E9
-:10844000ACE300308CA20014ACE2002C8CB9001814
-:10845000ACF900388CB8001424050001ACF80034E5
-:108460008D0600BC50C500198D0200B48D0200B805
-:10847000A4E2004894E40048A4E4004A94E800DA46
-:1084800003E000083102FFFF3C0208008C42002498
-:10849000A4C00054A4C200528CA30018ACE3003066
-:1084A0008CA20014ACE2002C8CB90018ACF9003896
-:1084B0008CB8001424050001ACF800348D0600BC13
-:1084C00054C5FFEB8D0200B88D0200B4A4E2004851
-:1084D00094E40048A4E4004A94E800DA03E00008C9
-:1084E0003102FFFF8F8600503C0480008CC90008D9
-:1084F0008CC80008000929C0000839C0AC870020DA
-:1085000090C30007306200041040003AAF85008C31
-:1085100090CB0007316A0008114000398F87FF1C9B
-:108520008CCD000C8CCE001401AE602B118000327B
-:10853000000000008CC2000CACE200708CCB001874
-:108540008F85FF188F88FF20ACEB00748CCA001059
-:108550002402FFF8ACAA00C88CC9000CAD09006069
-:108560008CC4001CACA400C090E3007C0062C82452
-:10857000A0F9007C90D80007330F000811E0000438
-:108580000000000090ED007C35AC0001A0EC007C08
-:1085900090CF000731EE000111C00009000000007B
-:1085A00090E4007C2418000234820002A0E2007CE7
-:1085B00090A300EC307900FF133800132408003436
-:1085C00090C900073126000210C00004000000001E
-:1085D00090EB007C356A0004A0EA007C90ED007D01
-:1085E00031AC003FA0EC007D94A700DA03E0000866
-:1085F00030E2FFFF8F87FF1C0A000C908CC2001432
-:108600000A000C91ACE000700A000CB2ACA800CCDF
-:108610008F8C005027BDFFD8AFB3001CAFB200183D
-:10862000AFB00010AFBF0020AFB10014918F0015A4
-:108630003C13600E3673001031EB000FA38B0094D7
-:108640008D8F00048D8B0008959F00129599001066
-:108650009584001A9598001E958E001C33EDFFFF3F
-:10866000332AFFFF3089FFFF3308FFFF31C7FFFFC9
-:108670003C010800AC2D00243C010800AC2900445A
-:108680003C010800AC2A0040AE683178AE67317C0E
-:1086900091850015959100163C126012365200101B
-:1086A00030A200FF3230FFFFAE623188AE5000B41E
-:1086B00091830014959F0018240600010066C804E9
-:1086C00033F8FFFFAE5900B8AE5800BC918E0014CD
-:1086D000AF8F007C3C08600631CD00FFAE4D00C07E
-:1086E000918A00159584000E3C07600A314900FF0D
-:1086F000AF8B00803084FFFFAE4900C835110010F9
-:108700000E000BF934F004103C0208008C420060AB
-:108710003C0308008C6300643C0608008CC60058CB
-:108720003C0508008CA5005C8F8400788FBF00207A
-:10873000AE23004CAE65319CAE030054AE4500DC68
-:10874000AE6231A0AE6331A4AE663198AE2200486D
-:108750008FB3001CAE0200508FB10014AE4200E097
-:10876000AE4300E4AE4600D88FB000108FB20018C0
-:108770000A00050227BD00289785008A97830074A8
-:1087800027BDFFE8AFB0001000A3102BAFBF00144F
-:10879000240400058F900050104000552409000269
-:1087A0000E00061A8F850078AF82008C2404000327
-:1087B0001040004F240900023C0680000E00004CCF
-:1087C000ACC2002024070001240820001040004D06
-:1087D00024040005978E008A8F8AFF1C240900500C
-:1087E00025C50001A785008AA14900003C0D0800AD
-:1087F0008DAD0064240380008F84FF18000D660097
-:10880000AD4C0018A5400006954B000A8F85FF204F
-:108810002402FF8001633024A546000A915F000A0C
-:108820000000482103E2C825A159000AA0A00008C1
-:10883000A140004CA08000C59618000297830088D4
-:108840003C020004A49800DA960F00022418FFBF2F
-:1088500025EE2401A48E00AE8E0D0004ACAD0044C4
-:108860008E0C0008ACAC0040A4A00050A4A00054A2
-:108870008E0B000C240C0030AC8B00288E060010F0
-:10888000AC860024A480003EA487004EA48700503C
-:10889000A483003CAD420074AC8800C8ACA8006062
-:1088A000A08700EC909F00C433F9007FA09900C41A
-:1088B000909000C402187824A08F00C4914E007CD0
-:1088C00035CD0001A14D007C938B0094AD48007024
-:1088D000AC8C00CCA08B00C68F8800808F87007C7A
-:1088E000AC8800B4AC8700B8A5400078A540007AF9
-:1088F0008FBF00148FB000100120102103E000088A
-:1089000027BD00188F85008C0E0006AA8F86007880
-:108910000A000D7E2409000227BDFFE0AFB0001061
-:108920008F900050AFB10014AFBF00188E09000443
-:108930000E0004CF000921C08E0800048F84FF18A8
-:108940008F82FF20000839C03C068000ACC70020A1
-:10895000948500DA904300131460001C30B1FFFFCF
-:108960008F8CFF1C918B0008316A00401540000B72
-:10897000000000008E0D0004022030218FBF00187F
-:108980008FB100148FB000102404002200003821A1
-:10899000000D29C00A000C1827BD00200E0000633E
-:1089A000000000008E0D0004022030218FBF00184F
-:1089B0008FB100148FB00010240400220000382171
-:1089C000000D29C00A000C1827BD00200E00005B16
-:1089D000000000008E0D0004022030218FBF00181F
-:1089E0008FB100148FB00010240400220000382141
-:1089F000000D29C00A000C1827BD002027BDFFE08C
-:108A0000AFB200183092FFFFAFB00010AFBF001C34
-:108A1000AFB100141240001E000080218F8600506C
-:108A20008CC500002403000600053F020005140267
-:108A300030E4000714830016304500FF2CA8000620
-:108A400011000040000558803C0C0800258C54049F
-:108A5000016C50218D490000012000080000000039
-:108A60008F8E0090240D000111CD005024020002D1
-:108A7000AF820090260900013130FFFF24C800209A
-:108A80000212202B010030211480FFE5AF88005036
-:108A9000020010218FBF001C8FB200188FB100148C
-:108AA0008FB0001003E0000827BD002093870076F8
-:108AB00054E00034000030210E000CC6000000001D
-:108AC0008F8600500A000DDE240200018F8700907F
-:108AD0002405000210E500312404001300002821C1
-:108AE00000003021240700010E000C1800000000D7
-:108AF0000A000DDF8F8600508F8300902402000251
-:108B00001462FFF6240400120E000C7B000000002B
-:108B10008F85008C00403021240400120E000C18B8
-:108B2000000038210A000DDF8F8600508F830090EF
-:108B30002411000310710029241F0002107FFFCEB2
-:108B40002609000124040010000028210000302123
-:108B50000A000DFC240700018F91009024060002FA
-:108B60001626FFF9240400100E000D20000000005E
-:108B7000144000238F9800508F8600500A000DDEAD
-:108B800024020003240400140E000C180000282105
-:108B90008F8600500A000DDE240200020E000D88B0
-:108BA000000000000A000DDF8F8600500E000C2828
-:108BB00000000000241900022404001400002821F1
-:108BC0000000302100003821AF9900900E000C18F1
-:108BD000000000000A000DDF8F8600500E000C38E8
-:108BE000000000008F85008C241900020040302115
-:108BF00024040010000038210A000E35AF990090BF
-:108C00000040382124040010970F000200002821A2
-:108C10000E000C1831E6FFFF8F8600500A000DDFB2
-:108C2000AF9100908F84FF1C3C077FFF34E6FFFF6D
-:108C30008C8500182402000100A61824AC830018BB
-:108C400003E00008A08200053084FFFF30A5FFFF8D
-:108C5000108000070000182130820001104000023F
-:108C600000042042006518211480FFFB0005284005
-:108C700003E000080060102110C0000700000000A1
-:108C80008CA2000024C6FFFF24A50004AC820000D3
-:108C900014C0FFFB2484000403E00008000000006F
-:108CA00010A0000824A3FFFFAC8600000000000015
-:108CB000000000002402FFFF2463FFFF1462FFFA9C
-:108CC0002484000403E0000800000000000411C038
-:108CD00003E000082442024027BDFFE8AFB00010C7
-:108CE00000808021AFBF00140E000E7500A020216F
-:108CF00000504821240AFF808FBF00148FB000105D
-:108D0000012A30243127007F3C08800A3C042100DE
-:108D100000E8102100C428253C03800027BD00186E
-:108D2000AC650024AF820038AC400000AC65002484
-:108D300003E00008AC4000403C0D08008DAD005839
-:108D400000056180240AFF8001A45821016C48219C
-:108D5000012A30243127007F3C08800C3C0421008C
-:108D600000E8102100C428253C038000AC650028E1
-:108D7000AF82003403E00008AC40002430A5FFFFC0
-:108D80003C0680008CC201B80440FFFE3C08601520
-:108D900000A838253C031000ACC40180ACC001849D
-:108DA000ACC7018803E00008ACC301B83C0D080063
-:108DB0008DAD005800056180240AFF8001A4582170
-:108DC000016C4021010A4824000931403107007F2D
-:108DD00000C728253C04200000A418253C02800080
-:108DE000AC43083003E00008AF80003427BDFFE843
-:108DF000AFB0001000808021AFBF00140E000E75D0
-:108E000000A0202100504821240BFF80012B50247A
-:108E1000000A39403128007F3C0620008FBF001433
-:108E20008FB0001000E8282534C2000100A21825E8
-:108E30003C04800027BD0018AC83083003E0000824
-:108E4000AF8000383C0580088CA700603C06800895
-:108E50000087102B144000112C8340008CA8006068
-:108E60002D0340001060000F240340008CC90060F7
-:108E70000089282B14A00002008018218CC30060F8
-:108E800000035A42000B30803C0A0800254A5480F7
-:108E900000CA202103E000088C8200001460FFF368
-:108EA0002403400000035A42000B30803C0A0800B3
-:108EB000254A548000CA202103E000088C8200006B
-:108EC0003C05800890A60008938400A024C20001FD
-:108ED000304200FF3043007F1064000C000238274E
-:108EE000A0A200083C0480008C85017804A0FFFE4D
-:108EF0008F8A0098240900023C081000AC8A0140C7
-:108F0000A089014403E00008AC8801780A000EFA49
-:108F100030E2008027BDFFD8AFB200188F92009CCE
-:108F2000AFBF0020AFB3001CAFB00010AFB1001452
-:108F30008F9300348E5900283C1000803C0EFFEFC8
-:108F4000AE7900008E580024A260000A35CDFFFFE4
-:108F5000AE7800049251002C3C0BFF9F356AFFFF56
-:108F6000A271000C8E6F000C3C080040A271000B37
-:108F700001F06025018D4824012A382400E83025BD
-:108F8000AE66000C8E450004AE6000183C0400FF85
-:108F9000AE6500148E43002C3482FFFFA6600008EB
-:108FA0000062F824AE7F00108E5900088F90009860
-:108FB000964E0012AE7900208E51000C31D83FFF42
-:108FC00000187980AE7100248E4D001401F06021EC
-:108FD00031CB0001AE6D00288E4A0018000C41C252
-:108FE000000B4B80AE6A002C8E46001C0109382114
-:108FF000A667001CAE660030964500028E44002035
-:10900000A665001EAE640034924300333062000453
-:1090100054400006924700003C028008344301009F
-:109020008C7F00C0AE7F0030924700008F860038F2
-:10903000A0C700309245003330A4000250800007E2
-:10904000925100018F880038240BFF80910A003074
-:10905000014B4825A1090030925100018F90003842
-:10906000240CFFBF2404FFDFA21100318F8D0038D4
-:109070003C1880083711008091AF003C31EE007F32
-:10908000A1AE003C8F890038912B003C016C50242C
-:10909000A12A003C8F9F00388E68001493E6003CA4
-:1090A0002D0700010007114000C4282400A2182544
-:1090B000A3E3003C8F87003896590012A4F90032D0
-:1090C0008E450004922E007C30B0000300107823FF
-:1090D00031ED000300AD102131CC000215800002FB
-:1090E00024460034244600303C028008344300808B
-:1090F000907F007C00BFC8243338000417000002B2
-:1091000024C2000400C010218F98003824190002E6
-:10911000ACE20034A3190000924F003F8F8E00385C
-:109120003C0C8008358B0080A1CF00018F91003866
-:10913000924D003F8E440004A62D0002956A005C0B
-:109140000E000ED33150FFFF00024B800130382556
-:109150003C08420000E82825AE2500048E44003873
-:109160008F850038ACA400188E460034ACA6001CD5
-:10917000ACA0000CACA00010A4A00014A4A0001689
-:10918000A4A00020A4A00022ACA000248E620014A1
-:1091900050400001240200018FBF00208FB3001C4B
-:1091A0008FB200188FB100148FB00010ACA200086D
-:1091B0000A000EF227BD002827BDFFC83C05800825
-:1091C00034A40080AFBF0034AFBE0030AFB7002C76
-:1091D000AFB60028AFB50024AFB40020AFB3001C79
-:1091E000AFB20018AFB10014AFB000109483007894
-:1091F0009482007A104300512405FFFF0080F02183
-:109200000A0010020080B821108B004D8FBF00347F
-:109210008F8600983C1808008F18005C2411FF808E
-:109220003C1680000306782101F18024AED0002C8A
-:1092300096EE007A31EC007F3C0D800E31CB7FFF43
-:10924000018D5021000B4840012AA82196A400005E
-:109250003C0808008D0800582405FF8030953FFF2A
-:1092600001061821001539800067C8210325F8245C
-:109270003C02010003E290253338007F3C11800C52
-:10928000AED20028031190219250000D320F00043D
-:1092900011E0003702E0982196E3007A96E8007A20
-:1092A00096E5007A2404800031077FFF24E3000163
-:1092B00030627FFF00A4F82403E2C825A6F9007AF3
-:1092C00096E6007A3C1408008E94006030D67FFF4A
-:1092D00012D400C1000000008E5800188F8400983E
-:1092E00002A028212713FFFF0E000EADAE53002C65
-:1092F00097D5007897D4007A1295001000002821A5
-:109300003C098008352401003C0A80089148000887
-:10931000908700C53114007F30E400FF0284302BB9
-:1093200014C0FFB9268B0001938E00A0268C00018B
-:10933000008E682115ACFFB78F8600988FBF003470
-:109340008FBE00308FB7002C8FB600288FB5002459
-:109350008FB400208FB3001C8FB200188FB100149F
-:109360008FB0001000A0102103E0000827BD0038D6
-:1093700000C020210E000E78028028218E4B0010A4
-:109380008E4C00308F84003824090002016C502379
-:10939000AE4A0010A089000096E3005C8E440030C5
-:1093A0008F9100380E000ED33070FFFF0002438013
-:1093B000011028253C07420000A71025AE2200041A
-:1093C0008E5F00048F8A00388E590000240B00083D
-:1093D000AD5F001CAD590018AD40000CAD40001051
-:1093E0009246000A240400052408C00030D000FF83
-:1093F000A550001496580008A55800169251000A6E
-:109400003C188008322F00FFA54F0020964E000820
-:1094100037110100A54E0022AD400024924D000BF3
-:1094200031AC00FFA54C0002A14B00018E49003079
-:109430008F830038240BFFBFAC690008A0640030A4
-:109440008F9000382403FFDF9607003200E82824BD
-:1094500000B51025A6020032921F003233F9003FFA
-:1094600037260040A20600328F8C0038AD800034D1
-:109470008E2F00C0AD8F0038918E003C3C0F7FFFD7
-:1094800031CD007FA18D003C8F84003835EEFFFF89
-:10949000908A003C014B4824A089003C8F8500380D
-:1094A00090A8003C01033824A0A7003C8E42003461
-:1094B0008F9100383C038008AE2200408E59002C6A
-:1094C0008E5F0030033F3023AE26004492300048C8
-:1094D0003218007FA23800488F8800388E4D003047
-:1094E0008D0C004801AE582401965024014B4825AC
-:1094F000AD0900489244000AA104004C96470008B8
-:109500008F850038A4A7004E8E5000308E44003066
-:109510000E00031C8C65006092F9007C0002F9408B
-:10952000004028210002110003E2302133360002FE
-:1095300012C00003020680210005B08002168021BF
-:10954000926D007C31B3000412600002000570804F
-:10955000020E80218E4B003024058000316A00030A
-:10956000000A482331240003020418218F90003898
-:10957000AE03003496E4007A96E8007A96F1007A19
-:1095800031077FFF24E20001305F7FFF0225C824FE
-:10959000033F3025A6E6007A96F8007A3C120800D0
-:1095A0008E520060330F7FFF11F2001800000000A0
-:1095B0008F8400980E000EAD02A028218F840098A1
-:1095C0000E000EBD028028210E000EF200000000E9
-:1095D0000A000FFE0000000096F1007A02248024A9
-:1095E000A6F0007A92EF007A92EB007A31EE00FF5B
-:1095F000000E69C2000D6027000C51C03169007F68
-:10960000012A20250A000FF8A2E4007A96E6007AE3
-:1096100000C5C024A6F8007A92EF007A92F3007A8F
-:1096200031F200FF001271C2000E6827000DB1C0B8
-:10963000326C007F01962825A2E5007A0A0010AF5F
-:109640008F8400983C0380003084FFFF30A5FFFF2B
-:10965000AC640018AC65001C03E000088C620014C8
-:1096600027BDFFA83C068008AFBE0050AFBF005426
-:10967000AFB7004CAFB60048AFB50044AFB4004040
-:10968000AFB3003CAFB20038AFB10034AFB0003080
-:1096900034C80100910500C590C70008309EFFFF47
-:1096A00030A500FF30E2007F0045182AA7A0001473
-:1096B000A7A0001E10600053AFA0001090C90008C2
-:1096C0003126007F00A620232493FFFF0013802B68
-:1096D000001E882B0211782451E000848FB3001003
-:1096E0003C1980089736005297370050001EC4007E
-:1096F00002D7A8230015A4000014140303C2902A63
-:109700001640000200182C0300402821001314000A
-:109710000002240300A4F82A57E0000100A0202141
-:1097200028830009146000020080A021241400088E
-:109730003C0A80088D450048001449808D48004C43
-:109740003C0380003124FFFF3C06001000863825D2
-:1097500034710400AC650038AF91009CAC68003CEB
-:10976000AC670030000000000000000000000000B6
-:1097700000000000000000000000000000000000E9
-:10978000000000008C6C0000318B00201160FFFD98
-:109790000014682A01B01024104000390000A821EC
-:1097A0003C16800892D700083C1280008E440100CD
-:1097B00032F6007F0E000E7802C028218E2F001096
-:1097C0008E4401000000902131F73FFF0E000E9003
-:1097D00002E02821922E000031C2003F2C500008E8
-:1097E00052000010000088210002F8803C030800AD
-:1097F0002463542C03E3C8218F38000003000008C1
-:109800000000000090CE0008938B00A031CD007FB7
-:1098100000AD6023016C50210A0010F52553FFFFB5
-:10982000000088213C1080008E0401000E000EAD67
-:1098300002E028218E0401000E000EBD02C0282186
-:109840001220000F0013802B8F8A009C26A9000194
-:109850000009AC00027298230015AC0325450040B6
-:1098600002B4B02A0013802B2417000100A0882125
-:1098700002D01024AF85009C1440FFC9AFB7001080
-:109880003C07800894F100503C0580003C06002015
-:1098900002B1C821A4F90050ACA6003094F40050E5
-:1098A00094E3005203D560231074001D319EFFFF26
-:1098B0008CE5004C8CE900480015618000ACB021BB
-:1098C0000000A02102CCA82B013450210155B82161
-:1098D000ACF6004CACF70048001E882B021178242F
-:1098E00015E0FF803C1980088FB300108FBF005433
-:1098F0008FBE00503A6200018FB7004C8FB600480F
-:109900008FB500448FB400408FB3003C8FB2003855
-:109910008FB100348FB0003003E0000827BD00583D
-:1099200094F200548CEF0044325FFFFE001FC0C071
-:1099300001F87021ACAE003C8CEB00448CAD003CD7
-:10994000016D40231900003B000000008CE2004044
-:10995000244200013C07005034E400103C03800026
-:10996000ACA20038AC640030000000000000000031
-:1099700000000000000000000000000000000000E7
-:1099800000000000000000008C76000032D70020AC
-:1099900012E0FFFD3C118008962800543C0A80002C
-:1099A0003C06800831190001001960C0018AA0211D
-:1099B0008E8304003C0708008CE700443C1500201F
-:1099C000ACC300488E89040424050001ACC9004CD6
-:1099D00010E50259AD550030963F00523C05080095
-:1099E0008CA5004000BFC021A6380052962F00541D
-:1099F00025EE0001A62E00549626005430C4FFFF29
-:109A00005487FF34001E882B30A5FFFF0E0010D3B3
-:109A1000A62000543C0408008C84002496270052A1
-:109A20000044102300E29023A63200520A0010F7EF
-:109A3000001E882B8CE200400A0011983C07005061
-:109A400092280001240700013102007F1447001C06
-:109A500097AC001E8E2A0014240BC00031443FFF37
-:109A6000018B48243C0608008CC600600124282590
-:109A700030A43FFF0086882B12200011A7A5001EEE
-:109A80003C1108008E3100588F82009800044180FC
-:109A90002407FF80022218210068F82103E7C82468
-:109AA00033EF007F3C1880003C12800EAF19002C71
-:109AB00001F2682191AE000D35D00004A1B0000D77
-:109AC0000E000F0724120001241100013C10800039
-:109AD0008E0401000E000EAD02E028218E0401006C
-:109AE0000E000EBD02C028211620FF588F8A009C50
-:109AF0000A0011620013802B8F86009C90C9000120
-:109B00003125002010A0018A241000013C048008A7
-:109B1000348C0080918B007C8F9100340000902168
-:109B2000316A00011140000FAFB000208CD000144A
-:109B30008C8E0060020E682B15A0000302003821F5
-:109B40008C8700603C048008348300808C72007035
-:109B500000F2782B15E0000200E020218C640070F8
-:109B6000008090213C07800834E500808CD90014E7
-:109B70008CBF0070033FC02B170000020320202180
-:109B80008CA400700092182310600003AFA300287B
-:109B900024080002AFA800208FA500200265102B2A
-:109BA000144000B5000018218CC400388E2F000C22
-:109BB0003C180080AE2400008CCE00343C10FF9F87
-:109BC00001F86025AE2E000490CB003F360DFFFF5C
-:109BD000018D48243C0A00203C06FFEFA22B000B1D
-:109BE000012A382534C5FFFF00E540243C02000867
-:109BF0008F87009C01022025AE24000C8CE300140A
-:109C0000AE2000188FAF0028AE2300148CF8001887
-:109C10003C1FFFFB37F9FFFFAE38001C8CEE00083D
-:109C200000996824024F8021AE2E00248CEC000C99
-:109C3000AE2D000CA6200038A620003AAE30002C35
-:109C4000AE2C0020AE2000288CEB00148FAA002838
-:109C500001724823012A302310C00011AE260010E3
-:109C600090F0003D8E2C00048E2A00000010690048
-:109C7000018D28210000102100AD302B0142482128
-:109C800001264021AE250004AE28000090E3003DEF
-:109C9000A223000A8F9F009C97F90006A6390008AE
-:109CA0008F8A0038240200023C068008A14200008E
-:109CB00034C900809525005C024020218F90003837
-:109CC00030A8FFFF0E000ED3AFA800248FA30024FE
-:109CD0000002FB808F85009C3C04420003E3C82502
-:109CE0000324C025AE1800048F8400388CAF0038E0
-:109CF000AC8F00188CAE0034AC8E001CAC80000C15
-:109D0000AC800010A4800014A4800016A480002061
-:109D1000A4800022AC80002490A7003FA48700020A
-:109D20005240018C240700018FAB002851600002D3
-:109D300090A2003D90A2003E244C0001A08C0001A6
-:109D40008F840038AC9200083C18800837100080DF
-:109D5000920F007C31EE000215C00002240700348F
-:109D6000240700308F85009C3C088008350900805E
-:109D700090A300009128007C32590003A08300309A
-:109D80008F9F009C8F9000382404000493F80001FA
-:109D900000997823240DC000A21800318F99003853
-:109DA0008F8E009C31E50003972C003295CB00127A
-:109DB00000F24821018D502431623FFF01423025DD
-:109DC000A7260032932300320125382131080004F0
-:109DD000307F003F37E40040A324003212400002ED
-:109DE0008F85003800E838213C0C8008ACA700348F
-:109DF000358B01008D6200C02E4400012403FFDF7B
-:109E0000ACA2003890AA003C0004C9403146007F53
-:109E1000A0A6003C8F8900382405FFBF9127003C95
-:109E200000E54024A128003C8F8F003891FF003CC2
-:109E300003E3C02403198025A1F0003C8F8B009C14
-:109E40008F8A00388D6E0020AD4E00408D6D00244D
-:109E5000AD4D00448D6C0028AD4C00488D62002C47
-:109E60000E000EF2AD42004C8FA600202407000227
-:109E700010C700118FA300200003202B00048023B3
-:109E80000270982400608021006090210A00114B2C
-:109E90000010882B962700128F84009800009021D4
-:109EA00030E5FFFFA7A700140E000EA1241100014A
-:109EB0000A0011F63C1080003C1980003C0280082A
-:109EC0008F240100905800080E000E783305007FA3
-:109ED0008F8E00388FAF00208FA40028A1CF000004
-:109EE0000E000ED38F9000388FAD002400023B800F
-:109EF0003C0B420000ED40258F87009C010B202584
-:109F0000AE0400048CE500388F900038000050212A
-:109F1000000A1900AE0500188CEC00343C087FFFE5
-:109F20003504FFFFAE0C001C90E9003E8E1F001CA4
-:109F30008E1800180009C9000009370203F96821CA
-:109F40000066102501B9782B0302702101CF58213A
-:109F5000AE0D001CAE0B0018AE00000CAE000010E1
-:109F600090E5003E8FAF0028240E0005A6050014E2
-:109F700094EC00042405C00001E45824A60C00164B
-:109F800090EA003E01E02021A60A002094E60004A9
-:109F9000A6060022AE00002490E3003FA6030002C4
-:109FA00090E9003E90FF003D03E9C82327380001F7
-:109FB000A21800018F8D00383C108008ADAF00085A
-:109FC000A1AE00308F9800388F82009C360F0100C0
-:109FD000970C0032944A00122410FF8000AC382401
-:109FE00031463FFF00E61825A703003293090032EF
-:109FF0002405FFBF2403FFDF313F003F37F9004056
-:10A00000A31900328F8C00382418FFFFAD80003474
-:10A010008DEE00C0AD8E0038918D003C31A2007FE6
-:10A02000A182003C8F87003890EA003C0145302433
-:10A03000A0E6003C8F9900389329003C0123F824C6
-:10A04000A33F003C8F8D00383C1F8008ADB8004016
-:10A05000ADB2004491AF00483C12800001F0702581
-:10A06000A1AE00488F8700388F86009C8CEC00489A
-:10A0700001921024004B5025ACEA004890C5003EE8
-:10A08000A0E5004C8F88009C8F8300389509000460
-:10A09000A469004E8FE500600E00031C0000000064
-:10A0A0008F99FF248FAE002800028140932F007CFF
-:10A0B0000002C1000218682131F20002004028218C
-:10A0C000164000AA01CD30213C0A800835430080AB
-:10A0D0009069007C313F000413E000038FAE00283C
-:10A0E0000005608000CC3021240D00048F900038E2
-:10A0F00031C7000301A758233168000300C820219D
-:10A10000AE0400343C068008A62500383C058000DB
-:10A110008CA4010090D100080E000EBD3225007FF6
-:10A120000E000EF2000000000A0012E08FA30020D3
-:10A130008F8500348CC2003824180003A4A00008C6
-:10A14000ACA200008CDF0034A0A0000A8F92009C1B
-:10A15000ACBF00043C040080924F003FA0B8000C4C
-:10A160008CAE000C3C0DFF9FA0AF000B01C440253E
-:10A1700035ABFFFF3C11FFEF8F98009C010B3024A3
-:10A180003639FFFF00D96024ACAC000C8F030014FB
-:10A19000971F00128F870098ACA300108F0900143E
-:10A1A000ACA00018ACA00020ACA90014ACA0002406
-:10A1B0008F0A001833E93FFF00091180ACAA00287C
-:10A1C0008F1200080047782133EE0001ACB2003056
-:10A1D0008F08000C8F990038000F69C2000E238091
-:10A1E00001A45821241100023C068008A4AB001CE5
-:10A1F000A4A00034ACA8002CA331000034D9008006
-:10A20000972C005C8F8F00383C034200318AFFFF9F
-:10A2100001433825ADE700048F82009C241800011B
-:10A220002411C0008C5F003824070034ADFF0018F3
-:10A230008C520034ADF2001CADE0000CADE000101B
-:10A24000A5E00014A5E00016A5E00020A5E000228E
-:10A25000ADE00024A5F00002A1F800018F8B0038CA
-:10A260008F8E009CAD70000891CD0000A16D003074
-:10A270008F88009C8F84003891050001A0850031F3
-:10A280008F920038964C00320191502401491825D4
-:10A29000A6430032925F003233E2003FA242003216
-:10A2A0009338007C330F000215E000028F840038E1
-:10A2B000240700303C028008AC870034345201008F
-:10A2C0008E5F00C0240EFFBF02009021AC9F0038BB
-:10A2D0009098003C330F007FA08F003C8F8800389F
-:10A2E000910D003C01AE5824A10B003C8F86003834
-:10A2F00090D1003C36390020A0D9003C8F8A009CC8
-:10A300008F8500380010882B8D4C0020ACAC0040AD
-:10A310008D430024ACA300448D490028ACA900481B
-:10A320008D47002CACA7004C0E000EF23C108000B4
-:10A330000A00114C0000000094CD00523C0B0800B4
-:10A340008D6B0024016D8821A4D100520A0010F702
-:10A35000001E882BA08700018F840038240D000187
-:10A36000AC8D00080A0012953C188008000290800D
-:10A370000A00137400D2302127BDFFE03C0D800895
-:10A38000AFB20018AFB00010AFBF001CAFB10014E7
-:10A3900035B200808E4C001835A80100964B00069F
-:10A3A00095A70050910900EC000C56020167282384
-:10A3B0003143007F312600FF24020003A38300A065
-:10A3C000AF84009810C2001B30B0FFFF910600EC74
-:10A3D0002412000530C200FF1052003300000000BC
-:10A3E000160000098FBF001C8FB200188FB1001437
-:10A3F0008FB00010240D0C003C0C800027BD002005
-:10A4000003E00008AD8D00240E0010DA02002021C8
-:10A410008FBF001C8FB200188FB100148FB00010D6
-:10A42000240D0C003C0C800027BD002003E0000838
-:10A43000AD8D0024965800789651007A924E007D9A
-:10A440000238782631E8FFFF31C400C014800009CB
-:10A450002D11000116000037000000005620FFE219
-:10A460008FBF001C0E000FB0000000000A00143C5B
-:10A470008FBF001C1620FFDA000000000E000FB096
-:10A48000000000001440FFD88FBF001C16000022FF
-:10A4900000000000925F007D33E2003FA242007D99
-:10A4A0000A00143C8FBF001C950900DA8F860078E3
-:10A4B00000802821240400050E0006AA3130FFFF89
-:10A4C0009783008A3C0480002465FFFFA785008AEB
-:10A4D0008C8A01B80540FFFE00000000AC800180BE
-:10A4E0008FBF001CAC9001848FB200188FB1001494
-:10A4F0008FB000103C0760133C0B1000240D0C00C3
-:10A500003C0C800027BD0020AC870188AC8B01B8D3
-:10A5100003E00008AD8D00240E0010DA02002021B7
-:10A520005040FFB18FBF001C925F007D0A0014698C
-:10A5300033E2003F0E0010DA020020211440FFAA8F
-:10A540008FBF001C12200007000000009259007D00
-:10A550003330003F36020040A242007D0A00143C26
-:10A560008FBF001C0E000FB0000000005040FF9E87
-:10A570008FBF001C9259007D3330003F0A001498B1
-:04A58000360200405F
-:0CA58400000000000000001B0000000FA1
-:10A590000000000A0000000800000006000000059E
-:10A5A000000000050000000400000004000000039B
-:10A5B000000000030000000300000003000000038F
-:10A5C0000000000200000002000000020000000283
-:10A5D0000000000200000002000000020000000273
-:10A5E0000000000200000002000000020000000263
-:10A5F0000000000200000002000000020000000154
-:08A60000000000010000000150
-:08A608008008010080080080B9
-:10A610008008000000000C000000308008001020BE
-:10A62000080010CC080010E4080010F80800110C15
-:10A6300008001020080010200800114008001178C0
-:10A6400008001188080011B0080018A0080018A020
-:10A65000080018D8080018D8080018EC080018BC22
-:10A6600008001B1408001AE008001B6C08001B6C93
-:10A6700008001BF408001B24800802400800228008
-:10A68000080020CC080022A80800234008002490DD
-:10A69000080024DC08002600080025080800258C96
-:10A6A0000800213C08002AA808002A4C080020E8DD
-:10A6B000080020E8080020E8080026740800267436
-:10A6C000080020E8080020E808002924080020E805
-:10A6D000080020E8080020E8080020E80800298495
-:10A6E000080020E8080020E8080020E8080020E82A
-:10A6F000080020E8080020E8080020E8080020E81A
-:10A70000080020E8080020E8080020E8080020E809
-:10A71000080020E8080020E8080024FC080020E8E1
-:10A72000080020E8080029F4080020E8080020E8D4
-:10A73000080020E8080020E8080020E8080020E8D9
-:10A74000080020E8080020E8080020E8080020E8C9
-:10A75000080020E8080020E8080020E8080020E8B9
-:10A76000080020E8080020E8080020E80800284841
-:10A77000080020E8080020E8080027BC0800271887
-:10A78000080038600800383408003800080037D462
-:10A79000080037B40800376880080100800800808E
-:10A7A0008008000080080080080047C808004800B2
-:10A7B00008004748080047C8080047C8080045285F
-:08A7C000080047C808004B9C8B
-:08A7C8000A000C7600000000FD
-:10A7D000000000000000000D727870352E302E3021
-:10A7E0006A31350005000003000000000000000190
-:10A7F0000000000000000000000000000000000059
-:10A800000000000000000000000000000000000048
-:10A810000000000000000000000000000000000038
-:10A820000000000000000000000000000000000028
-:10A830000000000000000000000000000000000018
-:10A840000000000000000000000000000000000008
-:10A8500000000000000000000000000000000000F8
-:10A8600000000000000000000000000000000000E8
-:10A8700000000000000000000000000000000000D8
-:10A8800000000000000000000000000000000000C8
-:10A8900000000000000000000000000000000000B8
-:10A8A00000000000000000000000000000000000A8
-:10A8B0000000000000000000000000000000000098
-:10A8C0000000000000000000000000000000000088
-:10A8D0000000000000000000000000000000000078
-:10A8E0000000000000000000000000000000000068
-:10A8F0000000000000000000000000000000000058
-:10A900000000000000000000000000000000000047
-:10A910000000000000000000000000000000000037
-:10A920000000000000000000000000000000000027
-:10A930000000000000000000000000000000000017
-:10A940000000000000000000000000000000000007
-:10A9500000000000000000000000000000000000F7
-:10A9600000000000000000000000000000000000E7
-:10A9700000000000000000000000000000000000D7
-:10A9800000000000000000000000000000000000C7
-:10A9900000000000000000000000000000000000B7
-:10A9A00000000000000000000000000000000000A7
-:10A9B0000000000000000000000000000000000097
-:10A9C0000000000000000000000000000000000087
-:10A9D0000000000000000000000000000000000077
-:10A9E0000000000000000000000000000000000067
-:10A9F0000000000000000000000000000000000057
-:10AA00000000000000000000000000000000000046
-:10AA10000000000000000000000000000000000036
-:10AA20000000000000000000000000000000000026
-:10AA30000000000000000000000000000000000016
-:10AA40000000000000000000000000000000000006
-:10AA500000000000000000000000000000000000F6
-:10AA600000000000000000000000000000000000E6
-:10AA700000000000000000000000000000000000D6
-:10AA800000000000000000000000000000000000C6
-:10AA900000000000000000000000000000000000B6
-:10AAA00000000000000000000000000000000000A6
-:10AAB0000000000000000000000000000000000096
-:10AAC0000000000000000000000000000000000086
-:10AAD0000000000000000000000000000000000076
-:10AAE0000000000000000000000000000000000066
-:10AAF0000000000000000000000000000000000056
-:10AB00000000000000000000000000000000000045
-:10AB10000000000000000000000000000000000035
-:10AB20000000000000000000000000000000000025
-:10AB30000000000000000000000000000000000015
-:10AB40000000000000000000000000000000000005
-:10AB500000000000000000000000000000000000F5
-:10AB600000000000000000000000000000000000E5
-:10AB700000000000000000000000000000000000D5
-:10AB800000000000000000000000000000000000C5
-:10AB900000000000000000000000000000000000B5
-:10ABA00000000000000000000000000000000000A5
-:10ABB0000000000000000000000000000000000095
-:10ABC0000000000000000000000000000000000085
-:10ABD0000000000000000000000000000000000075
-:10ABE0000000000000000000000000000000000065
-:10ABF0000000000000000000000000000000000055
-:10AC00000000000000000000000000000000000044
-:10AC10000000000000000000000000000000000034
-:10AC20000000000000000000000000000000000024
-:10AC30000000000000000000000000000000000014
-:10AC40000000000000000000000000000000000004
-:10AC500000000000000000000000000000000000F4
-:10AC600000000000000000000000000000000000E4
-:10AC700000000000000000000000000000000000D4
-:10AC800000000000000000000000000000000000C4
-:10AC900000000000000000000000000000000000B4
-:10ACA00000000000000000000000000000000000A4
-:10ACB0000000000000000000000000000000000094
-:10ACC0000000000000000000000000000000000084
-:10ACD0000000000000000000000000000000000074
-:10ACE0000000000000000000000000000000000064
-:10ACF0000000000000000000000000000000000054
-:10AD00000000000000000000000000000000000043
-:10AD10000000000000000000000000000000000033
-:10AD20000000000000000000000000000000000023
-:10AD30000000000000000000000000000000000013
-:10AD40000000000000000000000000000000000003
-:10AD500000000000000000000000000000000000F3
-:10AD600000000000000000000000000000000000E3
-:10AD700000000000000000000000000000000000D3
-:10AD800000000000000000000000000000000000C3
-:10AD900000000000000000000000000000000000B3
-:10ADA00000000000000000000000000000000000A3
-:10ADB0000000000000000000000000000000000093
-:10ADC0000000000000000000000000000000000083
-:10ADD0000000000000000000000000000000000073
-:10ADE0000000000000000000000000000000000063
-:10ADF0000000000000000000000000000000000053
-:10AE00000000000000000000000000000000000042
-:10AE10000000000000000000000000000000000032
-:10AE20000000000000000000000000000000000022
-:10AE30000000000000000000000000000000000012
-:10AE40000000000000000000000000000000000002
-:10AE500000000000000000000000000000000000F2
-:10AE600000000000000000000000000000000000E2
-:10AE700000000000000000000000000000000000D2
-:10AE800000000000000000000000000000000000C2
-:10AE900000000000000000000000000000000000B2
-:10AEA00000000000000000000000000000000000A2
-:10AEB0000000000000000000000000000000000092
-:10AEC0000000000000000000000000000000000082
-:10AED0000000000000000000000000000000000072
-:10AEE0000000000000000000000000000000000062
-:10AEF0000000000000000000000000000000000052
-:10AF00000000000000000000000000000000000041
-:10AF10000000000000000000000000000000000031
-:10AF20000000000000000000000000000000000021
-:10AF30000000000000000000000000000000000011
-:10AF40000000000000000000000000000000000001
-:10AF500000000000000000000000000000000000F1
-:10AF600000000000000000000000000000000000E1
-:10AF700000000000000000000000000000000000D1
-:10AF800000000000000000000000000000000000C1
-:10AF900000000000000000000000000000000000B1
-:10AFA00000000000000000000000000000000000A1
-:10AFB0000000000000000000000000000000000091
-:10AFC0000000000000000000000000000000000081
-:10AFD0000000000000000000000000000000000071
-:10AFE0000000000000000000000000000000000061
-:10AFF0000000000000000000000000000000000051
-:10B000000000000000000000000000000000000040
-:10B010000000000000000000000000000000000030
-:10B020000000000000000000000000000000000020
-:10B030000000000000000000000000000000000010
-:10B040000000000000000000000000000000000000
-:10B0500000000000000000000000000000000000F0
-:10B0600000000000000000000000000000000000E0
-:10B0700000000000000000000000000000000000D0
-:10B0800000000000000000000000000000000000C0
-:10B0900000000000000000000000000000000000B0
-:10B0A00000000000000000000000000000000000A0
-:10B0B0000000000000000000000000000000000090
-:10B0C0000000000000000000000000000000000080
-:10B0D0000000000000000000000000000000000070
-:10B0E0000000000000000000000000000000000060
-:10B0F0000000000000000000000000000000000050
-:10B10000000000000000000000000000000000003F
-:10B11000000000000000000000000000000000002F
-:10B12000000000000000000000000000000000001F
-:10B13000000000000000000000000000000000000F
-:10B1400000000000000000000000000000000000FF
-:10B1500000000000000000000000000000000000EF
-:10B1600000000000000000000000000000000000DF
-:10B1700000000000000000000000000000000000CF
-:10B1800000000000000000000000000000000000BF
-:10B1900000000000000000000000000000000000AF
-:10B1A000000000000000000000000000000000009F
-:10B1B000000000000000000000000000000000008F
-:10B1C000000000000000000000000000000000007F
-:10B1D000000000000000000000000000000000006F
-:10B1E000000000000000000000000000000000005F
-:10B1F000000000000000000000000000000000004F
-:10B20000000000000000000000000000000000003E
-:10B21000000000000000000000000000000000002E
-:10B22000000000000000000000000000000000001E
-:10B23000000000000000000000000000000000000E
-:10B2400000000000000000000000000000000000FE
-:10B2500000000000000000000000000000000000EE
-:10B2600000000000000000000000000000000000DE
-:10B2700000000000000000000000000000000000CE
-:10B2800000000000000000000000000000000000BE
-:10B2900000000000000000000000000000000000AE
-:10B2A000000000000000000000000000000000009E
-:10B2B000000000000000000000000000000000008E
-:10B2C000000000000000000000000000000000007E
-:10B2D000000000000000000000000000000000006E
-:10B2E000000000000000000000000000000000005E
-:10B2F000000000000000000000000000000000004E
-:10B30000000000000000000000000000000000003D
-:10B31000000000000000000000000000000000002D
-:10B32000000000000000000000000000000000001D
-:10B33000000000000000000000000000000000000D
-:10B3400000000000000000000000000000000000FD
-:10B3500000000000000000000000000000000000ED
-:10B3600000000000000000000000000000000000DD
-:10B3700000000000000000000000000000000000CD
-:10B3800000000000000000000000000000000000BD
-:10B3900000000000000000000000000000000000AD
-:10B3A000000000000000000000000000000000009D
-:10B3B000000000000000000000000000000000008D
-:10B3C000000000000000000000000000000000007D
-:10B3D000000000000000000000000000000000006D
-:10B3E000000000000000000000000000000000005D
-:10B3F000000000000000000000000000000000004D
-:10B40000000000000000000000000000000000003C
-:10B41000000000000000000000000000000000002C
-:10B42000000000000000000000000000000000001C
-:10B43000000000000000000000000000000000000C
-:10B4400000000000000000000000000000000000FC
-:10B4500000000000000000000000000000000000EC
-:10B4600000000000000000000000000000000000DC
-:10B4700000000000000000000000000000000000CC
-:10B4800000000000000000000000000000000000BC
-:10B4900000000000000000000000000000000000AC
-:10B4A000000000000000000000000000000000009C
-:10B4B000000000000000000000000000000000008C
-:10B4C000000000000000000000000000000000007C
-:10B4D000000000000000000000000000000000006C
-:10B4E000000000000000000000000000000000005C
-:10B4F000000000000000000000000000000000004C
-:10B50000000000000000000000000000000000003B
-:10B51000000000000000000000000000000000002B
-:10B52000000000000000000000000000000000001B
-:10B53000000000000000000000000000000000000B
-:10B5400000000000000000000000000000000000FB
-:10B5500000000000000000000000000000000000EB
-:10B5600000000000000000000000000000000000DB
-:10B5700000000000000000000000000000000000CB
-:10B5800000000000000000000000000000000000BB
-:10B5900000000000000000000000000000000000AB
-:10B5A000000000000000000000000000000000009B
-:10B5B000000000000000000000000000000000008B
-:10B5C000000000000000000000000000000000007B
-:10B5D000000000000000000000000000000000006B
-:10B5E000000000000000000000000000000000005B
-:10B5F000000000000000000000000000000000004B
-:10B60000000000000000000000000000000000003A
-:10B61000000000000000000000000000000000002A
-:10B62000000000000000000000000000000000001A
-:10B63000000000000000000000000000000000000A
-:10B6400000000000000000000000000000000000FA
-:10B6500000000000000000000000000000000000EA
-:10B6600000000000000000000000000000000000DA
-:10B6700000000000000000000000000000000000CA
-:10B6800000000000000000000000000000000000BA
-:10B6900000000000000000000000000000000000AA
-:10B6A000000000000000000000000000000000009A
-:10B6B000000000000000000000000000000000008A
-:10B6C000000000000000000000000000000000007A
-:10B6D000000000000000000000000000000000006A
-:10B6E000000000000000000000000000000000005A
-:10B6F000000000000000000000000000000000004A
-:10B700000000000000000000000000000000000039
-:10B710000000000000000000000000000000000029
-:10B720000000000000000000000000000000000019
-:10B730000000000000000000000000000000000009
-:10B7400000000000000000000000000000000000F9
-:10B7500000000000000000000000000000000000E9
-:10B7600000000000000000000000000000000000D9
-:10B7700000000000000000000000000000000000C9
-:10B7800000000000000000000000000000000000B9
-:10B7900000000000000000000000000000000000A9
-:10B7A0000000000000000000000000000000000099
-:10B7B0000000000000000000000000000000000089
-:10B7C0000000000000000000000000000000000079
-:10B7D0000000000000000000000000000000000069
-:10B7E0000000000000000000000000000000000059
-:10B7F0000000000000000000000000000000000049
-:10B800000000000000000000000000000000000038
-:10B810000000000000000000000000000000000028
-:10B820000000000000000000000000000000000018
-:10B830000000000000000000000000000000000008
-:10B8400000000000000000000000000000000000F8
-:10B8500000000000000000000000000000000000E8
-:10B8600000000000000000000000000000000000D8
-:10B8700000000000000000000000000000000000C8
-:10B8800000000000000000000000000000000000B8
-:10B8900000000000000000000000000000000000A8
-:10B8A0000000000000000000000000000000000098
-:10B8B0000000000000000000000000000000000088
-:10B8C0000000000000000000000000000000000078
-:10B8D0000000000000000000000000000000000068
-:10B8E0000000000000000000000000000000000058
-:10B8F0000000000000000000000000000000000048
-:10B900000000000000000000000000000000000037
-:10B910000000000000000000000000000000000027
-:10B920000000000000000000000000000000000017
-:10B930000000000000000000000000000000000007
-:10B9400000000000000000000000000000000000F7
-:10B9500000000000000000000000000000000000E7
-:10B9600000000000000000000000000000000000D7
-:10B9700000000000000000000000000000000000C7
-:10B9800000000000000000000000000000000000B7
-:10B9900000000000000000000000000000000000A7
-:10B9A0000000000000000000000000000000000097
-:10B9B0000000000000000000000000000000000087
-:10B9C0000000000000000000000000000000000077
-:10B9D0000000000000000000000000000000000067
-:10B9E0000000000000000000000000000000000057
-:10B9F0000000000000000000000000000000000047
-:10BA00000000000000000000000000000000000036
-:10BA10000000000000000000000000000000000026
-:10BA20000000000000000000000000000000000016
-:10BA30000000000000000000000000000000000006
-:10BA400000000000000000000000000000000000F6
-:10BA500000000000000000000000000000000000E6
-:10BA600000000000000000000000000000000000D6
-:10BA700000000000000000000000000000000000C6
-:10BA800000000000000000000000000000000000B6
-:10BA900000000000000000000000000000000000A6
-:10BAA0000000000000000000000000000000000096
-:10BAB0000000000000000000000000000000000086
-:10BAC0000000000000000000000000000000000076
-:10BAD0000000000000000000000000000000000066
-:10BAE0000000000000000000000000000000000056
-:10BAF0000000000000000000000000000000000046
-:10BB00000000000000000000000000000000000035
-:10BB10000000000000000000000000000000000025
-:10BB20000000000000000000000000000000000015
-:10BB30000000000000000000000000000000000005
-:10BB400000000000000000000000000000000000F5
-:10BB500000000000000000000000000000000000E5
-:10BB600000000000000000000000000000000000D5
-:10BB700000000000000000000000000000000000C5
-:10BB800000000000000000000000000000000000B5
-:10BB900000000000000000000000000000000000A5
-:10BBA0000000000000000000000000000000000095
-:10BBB0000000000000000000000000000000000085
-:10BBC0000000000000000000000000000000000075
-:10BBD0000000000000000000000000000000000065
-:10BBE0000000000000000000000000000000000055
-:10BBF0000000000000000000000000000000000045
-:10BC00000000000000000000000000000000000034
-:10BC10000000000000000000000000000000000024
-:10BC20000000000000000000000000000000000014
-:10BC30000000000000000000000000000000000004
-:10BC400000000000000000000000000000000000F4
-:10BC500000000000000000000000000000000000E4
-:10BC600000000000000000000000000000000000D4
-:10BC700000000000000000000000000000000000C4
-:10BC800000000000000000000000000000000000B4
-:10BC900000000000000000000000000000000000A4
-:10BCA0000000000000000000000000000000000094
-:10BCB0000000000000000000000000000000000084
-:10BCC0000000000000000000000000000000000074
-:10BCD0000000000000000000000000000000000064
-:10BCE0000000000000000000000000000000000054
-:10BCF0000000000000000000000000000000000044
-:10BD00000000000000000000000000000000000033
-:10BD10000000000000000000000000000000000023
-:10BD20000000000000000000000000000000000013
-:10BD30000000000000000000000000000000000003
-:10BD400000000000000000000000000000000000F3
-:10BD500000000000000000000000000000000000E3
-:10BD600000000000000000000000000000000000D3
-:10BD700000000000000000000000000000000000C3
-:10BD800000000000000000000000000000000000B3
-:10BD900000000000000000000000000000000000A3
-:10BDA0000000000000000000000000000000000093
-:10BDB0000000000000000000000000000000000083
-:10BDC0000000000000000000000000000000000073
-:10BDD0000000000000000000000000000000000063
-:10BDE0000000000000000000000000000000000053
-:10BDF0000000000000000000000000000000000043
-:10BE00000000000000000000000000000000000032
-:10BE10000000000000000000000000000000000022
-:10BE20000000000000000000000000000000000012
-:10BE30000000000000000000000000000000000002
-:10BE400000000000000000000000000000000000F2
-:10BE500000000000000000000000000000000000E2
-:10BE600000000000000000000000000000000000D2
-:10BE700000000000000000000000000000000000C2
-:10BE800000000000000000000000000000000000B2
-:10BE900000000000000000000000000000000000A2
-:10BEA0000000000000000000000000000000000092
-:10BEB0000000000000000000000000000000000082
-:10BEC0000000000000000000000000000000000072
-:10BED0000000000000000000000000000000000062
-:10BEE0000000000000000000000000000000000052
-:10BEF0000000000000000000000000000000000042
-:10BF00000000000000000000000000000000000031
-:10BF10000000000000000000000000000000000021
-:10BF20000000000000000000000000000000000011
-:10BF30000000000000000000000000000000000001
-:10BF400000000000000000000000000000000000F1
-:10BF500000000000000000000000000000000000E1
-:10BF600000000000000000000000000000000000D1
-:10BF700000000000000000000000000000000000C1
-:10BF800000000000000000000000000000000000B1
-:10BF900000000000000000000000000000000000A1
-:10BFA0000000000000000000000000000000000091
-:10BFB0000000000000000000000000000000000081
-:10BFC0000000000000000000000000000000000071
-:10BFD0000000000000000000000000000000000061
-:10BFE0000000000000000000000000000000000051
-:10BFF0000000000000000000000000000000000041
-:10C000000000000000000000000000000000000030
-:10C010000000000000000000000000000000000020
-:10C020000000000000000000000000000000000010
-:10C030000000000000000000000000000000000000
-:10C0400000000000000000000000000000000000F0
-:10C0500000000000000000000000000000000000E0
-:10C0600000000000000000000000000000000000D0
-:10C0700000000000000000000000000000000000C0
-:10C0800000000000000000000000000000000000B0
-:10C0900000000000000000000000000000000000A0
-:10C0A0000000000000000000000000000000000090
-:10C0B0000000000000000000000000000000000080
-:10C0C0000000000000000000000000000000000070
-:10C0D0000000000000000000000000000000000060
-:10C0E0000000000000000000000000000000000050
-:10C0F0000000000000000000000000000000000040
-:10C10000000000000000000000000000000000002F
-:10C11000000000000000000000000000000000001F
-:10C12000000000000000000000000000000000000F
-:10C1300000000000000000000000000000000000FF
-:10C1400000000000000000000000000000000000EF
-:10C1500000000000000000000000000000000000DF
-:10C1600000000000000000000000000000000000CF
-:10C1700000000000000000000000000000000000BF
-:10C1800000000000000000000000000000000000AF
-:10C19000000000000000000000000000000000009F
-:10C1A000000000000000000000000000000000008F
-:10C1B000000000000000000000000000000000007F
-:10C1C000000000000000000000000000000000006F
-:10C1D000000000000000000000000000000000005F
-:10C1E000000000000000000000000000000000004F
-:10C1F000000000000000000000000000000000003F
-:10C20000000000000000000000000000000000002E
-:10C21000000000000000000000000000000000001E
-:10C22000000000000000000000000000000000000E
-:10C2300000000000000000000000000000000000FE
-:10C2400000000000000000000000000000000000EE
-:10C2500000000000000000000000000000000000DE
-:10C2600000000000000000000000000000000000CE
-:10C2700000000000000000000000000000000000BE
-:10C2800000000000000000000000000000000000AE
-:10C29000000000000000000000000000000000009E
-:10C2A000000000000000000000000000000000008E
-:10C2B000000000000000000000000000000000007E
-:10C2C000000000000000000000000000000000006E
-:10C2D000000000000000000000000000000000005E
-:10C2E000000000000000000000000000000000004E
-:10C2F000000000000000000000000000000000003E
-:10C30000000000000000000000000000000000002D
-:10C31000000000000000000000000000000000001D
-:10C32000000000000000000000000000000000000D
-:10C3300000000000000000000000000000000000FD
-:10C3400000000000000000000000000000000000ED
-:10C3500000000000000000000000000000000000DD
-:10C3600000000000000000000000000000000000CD
-:10C3700000000000000000000000000000000000BD
-:10C3800000000000000000000000000000000000AD
-:10C39000000000000000000000000000000000009D
-:10C3A000000000000000000000000000000000008D
-:10C3B000000000000000000000000000000000007D
-:10C3C000000000000000000000000000000000006D
-:10C3D000000000000000000000000000000000005D
-:10C3E000000000000000000000000000000000004D
-:10C3F000000000000000000000000000000000003D
-:10C40000000000000000000000000000000000002C
-:10C41000000000000000000000000000000000001C
-:10C42000000000000000000000000000000000000C
-:10C4300000000000000000000000000000000000FC
-:10C4400000000000000000000000000000000000EC
-:10C4500000000000000000000000000000000000DC
-:10C4600000000000000000000000000000000000CC
-:10C4700000000000000000000000000000000000BC
-:10C4800000000000000000000000000000000000AC
-:10C49000000000000000000000000000000000009C
-:10C4A000000000000000000000000000000000008C
-:10C4B000000000000000000000000000000000007C
-:10C4C000000000000000000000000000000000006C
-:10C4D000000000000000000000000000000000005C
-:10C4E000000000000000000000000000000000004C
-:10C4F000000000000000000000000000000000003C
-:10C50000000000000000000000000000000000002B
-:10C51000000000000000000000000000000000001B
-:10C52000000000000000000000000000000000000B
-:10C5300000000000000000000000000000000000FB
-:10C5400000000000000000000000000000000000EB
-:10C5500000000000000000000000000000000000DB
-:10C5600000000000000000000000000000000000CB
-:10C5700000000000000000000000000000000000BB
-:10C5800000000000000000000000000000000000AB
-:10C59000000000000000000000000000000000009B
-:10C5A000000000000000000000000000000000008B
-:10C5B000000000000000000000000000000000007B
-:10C5C000000000000000000000000000000000006B
-:10C5D000000000000000000000000000000000005B
-:10C5E000000000000000000000000000000000004B
-:10C5F000000000000000000000000000000000003B
-:10C60000000000000000000000000000000000002A
-:10C61000000000000000000000000000000000001A
-:10C62000000000000000000000000000000000000A
-:10C6300000000000000000000000000000000000FA
-:10C6400000000000000000000000000000000000EA
-:10C6500000000000000000000000000000000000DA
-:10C6600000000000000000000000000000000000CA
-:10C6700000000000000000000000000000000000BA
-:10C6800000000000000000000000000000000000AA
-:10C69000000000000000000000000000000000009A
-:10C6A000000000000000000000000000000000008A
-:10C6B000000000000000000000000000000000007A
-:10C6C000000000000000000000000000000000006A
-:10C6D000000000000000000000000000000000005A
-:10C6E000000000000000000000000000000000004A
-:10C6F000000000000000000000000000000000003A
-:10C700000000000000000000000000000000000029
-:10C710000000000000000000000000000000000019
-:10C720000000000000000000000000000000000009
-:10C7300000000000000000000000000000000000F9
-:10C7400000000000000000000000000000000000E9
-:10C7500000000000000000000000000000000000D9
-:10C7600000000000000000000000000000000000C9
-:10C7700000000000000000000000000000000000B9
-:10C7800000000000000000000000000000000000A9
-:10C790000000000000000000000000000000000099
-:10C7A0000000000000000000000000000000000089
-:10C7B0000000000000000000000000000000000079
-:10C7C0000000000000000000000000000000000069
-:10C7D0000000000000000000000000000000000059
-:10C7E0000000000000000000000000000000000049
-:10C7F0000000000000000000000000000000000039
-:10C800000000000000000000000000000000000028
-:10C810000000000000000000000000000000000018
-:10C820000000000000000000000000000000000008
-:10C8300000000000000000000000000000000000F8
-:10C8400000000000000000000000000000000000E8
-:10C8500000000000000000000000000000000000D8
-:10C8600000000000000000000000000000000000C8
-:10C8700000000000000000000000000000000000B8
-:10C8800000000000000000000000000000000000A8
-:10C890000000000000000000000000000000000098
-:10C8A0000000000000000000000000000000000088
-:10C8B0000000000000000000000000000000000078
-:10C8C0000000000000000000000000000000000068
-:10C8D0000000000000000000000000000000000058
-:10C8E0000000000000000000000000000000000048
-:10C8F0000000000000000000000000000000000038
-:10C900000000000000000000000000000000000027
-:10C910000000000000000000000000000000000017
-:10C920000000000000000000000000000000000007
-:10C9300000000000000000000000000000000000F7
-:10C9400000000000000000000000000000000000E7
-:10C9500000000000000000000000000000000000D7
-:10C9600000000000000000000000000000000000C7
-:10C9700000000000000000000000000000000000B7
-:10C9800000000000000000000000000000000000A7
-:10C990000000000000000000000000000000000097
-:10C9A0000000000000000000000000000000000087
-:10C9B0000000000000000000000000000000000077
-:10C9C0000000000000000000000000000000000067
-:10C9D0000000000000000000000000000000000057
-:10C9E0000000000000000000000000000000000047
-:10C9F0000000000000000000000000000000000037
-:10CA00000000000000000000000000000000000026
-:10CA10000000000000000000000000000000000016
-:10CA20000000000000000000000000000000000006
-:10CA300000000000000000000000000000000000F6
-:10CA400000000000000000000000000000000000E6
-:10CA500000000000000000000000000000000000D6
-:10CA600000000000000000000000000000000000C6
-:10CA700000000000000000000000000000000000B6
-:10CA800000000000000000000000000000000000A6
-:10CA90000000000000000000000000000000000096
-:10CAA0000000000000000000000000000000000086
-:10CAB0000000000000000000000000000000000076
-:10CAC0000000000000000000000000000000000066
-:10CAD0000000000000000000000000000000000056
-:10CAE0000000000000000000000000000000000046
-:10CAF0000000000000000000000000000000000036
-:10CB00000000000000000000000000000000000025
-:10CB10000000000000000000000000000000000015
-:10CB20000000000000000000000000000000000005
-:10CB300000000000000000000000000000000000F5
-:10CB400000000000000000000000000000000000E5
-:10CB500000000000000000000000000000000000D5
-:10CB600000000000000000000000000000000000C5
-:10CB700000000000000000000000000000000000B5
-:10CB800000000000000000000000000000000000A5
-:10CB90000000000000000000000000000000000095
-:10CBA0000000000000000000000000000000000085
-:10CBB0000000000000000000000000000000000075
-:10CBC0000000000000000000000000000000000065
-:10CBD0000000000000000000000000000000000055
-:10CBE0000000000000000000000000000000000045
-:10CBF0000000000000000000000000000000000035
-:10CC00000000000000000000000000000000000024
-:10CC10000000000000000000000000000000000014
-:10CC20000000000000000000000000000000000004
-:10CC300000000000000000000000000000000000F4
-:10CC400000000000000000000000000000000000E4
-:10CC500000000000000000000000000000000000D4
-:10CC600000000000000000000000000000000000C4
-:10CC700000000000000000000000000000000000B4
-:10CC800000000000000000000000000000000000A4
-:10CC90000000000000000000000000000000000094
-:10CCA0000000000000000000000000000000000084
-:10CCB0000000000000000000000000000000000074
-:10CCC0000000000000000000000000000000000064
-:10CCD0000000000000000000000000000000000054
-:10CCE0000000000000000000000000000000000044
-:10CCF0000000000000000000000000000000000034
-:10CD00000000000000000000000000000000000023
-:10CD10000000000000000000000000000000000013
-:10CD20000000000000000000000000000000000003
-:10CD300000000000000000000000000000000000F3
-:10CD400000000000000000000000000000000000E3
-:10CD500000000000000000000000000000000000D3
-:10CD600000000000000000000000000000000000C3
-:10CD700000000000000000000000000000000000B3
-:10CD800000000000000000000000000000000000A3
-:10CD90000000000000000000000000000000000093
-:10CDA0000000000000000000000000000000000083
-:10CDB0000000000000000000000000000000000073
-:10CDC0000000000000000000000000000000000063
-:10CDD0000000000000000000000000000000000053
-:10CDE0000000000000000000000000000000000043
-:10CDF0000000000000000000000000000000000033
-:10CE00000000000000000000000000000000000022
-:10CE10000000000000000000000000000000000012
-:10CE20000000000000000000000000000000000002
-:10CE300000000000000000000000000000000000F2
-:10CE400000000000000000000000000000000000E2
-:10CE500000000000000000000000000000000000D2
-:10CE600000000000000000000000000000000000C2
-:10CE700000000000000000000000000000000000B2
-:10CE800000000000000000000000000000000000A2
-:10CE90000000000000000000000000000000000092
-:10CEA0000000000000000000000000000000000082
-:10CEB0000000000000000000000000000000000072
-:10CEC0000000000000000000000000000000000062
-:10CED0000000000000000000000000000000000052
-:10CEE0000000000000000000000000000000000042
-:10CEF0000000000000000000000000000000000032
-:10CF00000000000000000000000000000000000021
-:10CF10000000000000000000000000000000000011
-:10CF20000000000000000000000000000000000001
-:10CF300000000000000000000000000000000000F1
-:10CF400000000000000000000000000000000000E1
-:10CF500000000000000000000000000000000000D1
-:10CF600000000000000000000000000000000000C1
-:10CF700000000000000000000000000000000000B1
-:10CF800000000000000000000000000000000000A1
-:10CF90000000000000000000000000000000000091
-:10CFA0000000000000000000000000000000000081
-:10CFB0000000000000000000000000000000000071
-:10CFC0000000000000000000000000000000000061
-:10CFD0000000000000000000000000000000000051
-:10CFE0000000000000000000000000000000000041
-:10CFF0000000000000000000000000000000000031
-:10D000000000000000000000000000000000000020
-:10D010000000000000000000000000000000000010
-:10D020000000000000000000000000000000000000
-:10D0300000000000000000000000000000000000F0
-:10D0400000000000000000000000000000000000E0
-:10D0500000000000000000000000000000000000D0
-:10D0600000000000000000000000000000000000C0
-:10D0700000000000000000000000000000000000B0
-:10D0800000000000000000000000000000000000A0
-:10D090000000000000000000000000000000000090
-:10D0A0000000000000000000000000000000000080
-:10D0B0000000000000000000000000000000000070
-:10D0C0000000000000000000000000000000000060
-:10D0D0000000000000000000000000000000000050
-:10D0E0000000000000000000000000000000000040
-:10D0F0000000000000000000000000000000000030
-:10D10000000000000000000000000000000000001F
-:10D11000000000000000000000000000000000000F
-:10D1200000000000000000000000000000000000FF
-:10D1300000000000000000000000000000000000EF
-:10D1400000000000000000000000000000000000DF
-:10D1500000000000000000000000000000000000CF
-:10D1600000000000000000000000000000000000BF
-:10D1700000000000000000000000000000000000AF
-:10D18000000000000000000000000000000000009F
-:10D19000000000000000000000000000000000008F
-:10D1A000000000000000000000000000000000007F
-:10D1B000000000000000000000000000000000006F
-:10D1C000000000000000000000000000000000005F
-:10D1D000000000000000000000000000000000004F
-:10D1E000000000000000000000000000000000003F
-:10D1F000000000000000000000000000000000002F
-:10D20000000000000000000000000000000000001E
-:10D21000000000000000000000000000000000000E
-:10D2200000000000000000000000000000000000FE
-:10D2300000000000000000000000000000000000EE
-:10D2400000000000000000000000000000000000DE
-:10D2500000000000000000000000000000000000CE
-:10D2600000000000000000000000000000000000BE
-:10D2700000000000000000000000000000000000AE
-:10D28000000000000000000000000000000000009E
-:10D29000000000000000000000000000000000008E
-:10D2A000000000000000000000000000000000007E
-:10D2B000000000000000000000000000000000006E
-:10D2C000000000000000000000000000000000005E
-:10D2D000000000000000000000000000000000004E
-:10D2E000000000000000000000000000000000003E
-:10D2F000000000000000000000000000000000002E
-:10D30000000000000000000000000000000000001D
-:10D31000000000000000000000000000000000000D
-:10D3200000000000000000000000000000000000FD
-:10D3300000000000000000000000000000000000ED
-:10D3400000000000000000000000000000000000DD
-:10D3500000000000000000000000000000000000CD
-:10D3600000000000000000000000000000000000BD
-:10D3700000000000000000000000000000000000AD
-:10D38000000000000000000000000000000000009D
-:10D39000000000000000000000000000000000008D
-:10D3A000000000000000000000000000000000007D
-:10D3B000000000000000000000000000000000006D
-:10D3C000000000000000000000000000000000005D
-:10D3D000000000000000000000000000000000004D
-:10D3E000000000000000000000000000000000003D
-:10D3F000000000000000000000000000000000002D
-:10D40000000000000000000000000000000000001C
-:10D41000000000000000000000000000000000000C
-:10D4200000000000000000000000000000000000FC
-:10D4300000000000000000000000000000000000EC
-:10D4400000000000000000000000000000000000DC
-:10D4500000000000000000000000000000000000CC
-:10D4600000000000000000000000000000000000BC
-:10D4700000000000000000000000000000000000AC
-:10D48000000000000000000000000000000000009C
-:10D49000000000000000000000000000000000008C
-:10D4A000000000000000000000000000000000007C
-:10D4B000000000000000000000000000000000006C
-:10D4C000000000000000000000000000000000005C
-:10D4D000000000000000000000000000000000004C
-:10D4E000000000000000000000000000000000003C
-:10D4F000000000000000000000000000000000002C
-:10D50000000000000000000000000000000000001B
-:10D51000000000000000000000000000000000000B
-:10D5200000000000000000000000000000000000FB
-:10D5300000000000000000000000000000000000EB
-:10D5400000000000000000000000000000000000DB
-:10D5500000000000000000000000000000000000CB
-:10D5600000000000000000000000000000000000BB
-:10D5700000000000000000000000000000000000AB
-:10D58000000000000000000000000000000000009B
-:10D59000000000000000000000000000000000008B
-:10D5A000000000000000000000000000000000007B
-:10D5B000000000000000000000000000000000006B
-:10D5C000000000000000000000000000000000005B
-:10D5D000000000000000000000000000000000004B
-:10D5E000000000000000000000000000000000003B
-:10D5F000000000000000000000000000000000002B
-:10D60000000000000000000000000000000000001A
-:10D61000000000000000000000000000000000000A
-:10D6200000000000000000000000000000000000FA
-:10D6300000000000000000000000000000000000EA
-:10D6400000000000000000000000000000000000DA
-:10D6500000000000000000000000000000000000CA
-:10D6600000000000000000000000000000000000BA
-:10D6700000000000000000000000000000000000AA
-:10D68000000000000000000000000000000000009A
-:10D69000000000000000000000000000000000008A
-:10D6A000000000000000000000000000000000007A
-:10D6B000000000000000000000000000000000006A
-:10D6C000000000000000000000000000000000005A
-:10D6D000000000000000000000000000000000004A
-:10D6E000000000000000000000000000000000003A
-:10D6F000000000000000000000000000000000002A
-:10D700000000000000000000000000000000000019
-:10D710000000000000000000000000000000000009
-:10D7200000000000000000000000000000000000F9
-:10D7300000000000000000000000000000000000E9
-:10D7400000000000000000000000000000000000D9
-:10D7500000000000000000000000000000000000C9
-:10D7600000000000000000000000000000000000B9
-:10D7700000000000000000000000000000000000A9
-:10D780000000000000000000000000000000000099
-:10D790000000000000000000000000000000000089
-:10D7A0000000000000000000000000000000000079
-:10D7B0000000000000000000000000000000000069
-:10D7C0000000000000000000000000000000000059
-:10D7D0000000000000000000000000000000000049
-:10D7E0000000000000000000000000000000000039
-:10D7F0000000000000000000000000000000000029
-:10D800000000000000000000000000000000000018
-:10D810000000000000000000000000000000000008
-:10D8200000000000000000000000000000000000F8
-:10D8300000000000000000000000000000000000E8
-:10D8400000000000000000000000000000000000D8
-:10D8500000000000000000000000000000000000C8
-:10D8600000000000000000000000000000000000B8
-:10D8700000000000000000000000000000000000A8
-:10D880000000000000000000000000000000000098
-:10D890000000000000000000000000000000000088
-:10D8A0000000000000000000000000000000000078
-:10D8B0000000000000000000000000000000000068
-:10D8C0000000000000000000000000000000000058
-:10D8D0000000000000000000000000000000000048
-:10D8E0000000000000000000000000000000000038
-:10D8F0000000000000000000000000000000000028
-:10D900000000000000000000000000000000000017
-:10D910000000000000000000000000000000000007
-:10D9200000000000000000000000000000000000F7
-:10D9300000000000000000000000000000000000E7
-:10D9400000000000000000000000000000000000D7
-:10D9500000000000000000000000000000000000C7
-:10D9600000000000000000000000000000000000B7
-:10D9700000000000000000000000000000000000A7
-:10D980000000000000000000000000000000000097
-:10D990000000000000000000000000000000000087
-:10D9A0000000000010000003000000000000000D57
-:10D9B0000000000D3C020801244282603C03080183
-:10D9C00024638320AC4000000043202B1480FFFD23
-:10D9D000244200043C1D080037BD9FFC03A0F02139
-:10D9E0003C100800261031D83C1C0801279C82609E
-:10D9F0000E0011EA000000000000000D3C02800053
-:10DA000030A5FFFF30C600FF344301803C08800092
-:10DA10008D0901B80520FFFE00000000AC64000085
-:10DA200024040002A4650008A066000AA064000B9C
-:10DA3000AC6700183C03100003E00008AD0301B818
-:10DA40003C0560008CA24FF80440FFFE000000007F
-:10DA5000ACA44FC03C0310003C040200ACA44FC473
-:10DA600003E00008ACA34FF89486000C00A05021FE
-:10DA70002488001400062B02000510800044482171
-:10DA80000109182B10600011000000009103000034
-:10DA90002C64000950800009911900010003608086
-:10DAA0003C0D080125AD8108018D58218D670000CE
-:10DAB00000E0000800000000911900010119402158
-:10DAC0000109302B54C0FFF29103000003E000086D
-:10DAD000000010210A000CBE25080001910F000172
-:10DAE000240E000A15EE00400128C8232F38000A32
-:10DAF0001700003D250D00028D580000250F00067F
-:10DB0000370E0100AD4E0000910C000291AB0001F8
-:10DB100091A4000291A60003000C2E00000B3C0013
-:10DB200000A7102500041A000043C8250326C025BD
-:10DB3000AD580004910E000691ED000191E700023E
-:10DB400091E50003000E5E00000D6400016C3025BD
-:10DB50000007220000C41025004518252508000AEA
-:10DB60000A000CBEAD430008910F0001250400021D
-:10DB70002408000255E80001012020210A000CBE03
-:10DB800000804021910C0001240B0003158B00162E
-:10DB9000000000008D580000910E000225080003CF
-:10DBA000370D0008A14E00100A000CBEAD4D00005C
-:10DBB00091190001240F0004172F000B0000000032
-:10DBC00091070002910400038D43000000072A0022
-:10DBD00000A410253466000425080004AD42000CA2
-:10DBE0000A000CBEAD46000003E00008240200015C
-:10DBF00027BDFFE8AFBF0014AFB000100E0014E661
-:10DC0000008080213C0480083485008090A60005B7
-:10DC10002403FFFE0200202100C310248FBF001444
-:10DC20008FB00010A0A200050A0014F027BD001854
-:10DC300027BDFFE8AFB00010AFBF00140E000F4EBD
-:10DC4000008080213C06800834C5008090A400003C
-:10DC500024020050308300FF106200073C0980005E
-:10DC6000020020218FBF00148FB00010AD20018072
-:10DC70000A00101027BD0018240801003C0780008E
-:10DC8000020020218FBF00148FB00010ACE801808B
-:10DC90000A00101027BD001827BDFF703C0880083F
-:10DCA000AFB60080AFB5007CAFB1006CAFBF008CE9
-:10DCB000AFBE0088AFB70084AFB40078AFB30074D4
-:10DCC000AFB20070AFB00068350500803C0780003F
-:10DCD0008CF2012890A40009ACE0008490A6000515
-:10DCE000309100FF0000A8210006182730620001D3
-:10DCF0000000B02114400067AFA0005090A90000C0
-:10DD000024050020312400FF10850016240A00504D
-:10DD1000108A008C000000003C0C08008D8C00DC98
-:10DD2000258B00013C010800AC2B00DC0E0015DC4B
-:10DD3000000000008FBF008C8FBE00888FB700846A
-:10DD40008FB600808FB5007C8FB400788FB30074DD
-:10DD50008FB200708FB1006C8FB0006803E00008D4
-:10DD600027BD00900000000D3C108000AFA00030E7
-:10DD7000961F01168E1901043C1E002036130C005C
-:10DD8000033EC0240018B82B00173140AFA6003066
-:10DD90008E0E010433F4FFFF3C0F004002938021FC
-:10DDA00001CF68249213000D11A0004834C4004034
-:10DDB000326200201440000234860080008030214E
-:10DDC00014C00093AFA600303C05800834A8008042
-:10DDD0009107000830E6004050C000063C0680086D
-:10DDE00024090004122900A2240A0012122A002980
-:10DDF0003C06800834D401003C17800096EF011ADD
-:10DE0000960D000E928E0008326B000431F7FFFF72
-:10DE100001CD6004AFAC00548E14000411600031D9
-:10DE20008E1E000834C3008090790008333800400B
-:10DE300017000028000000008C730050029390230C
-:10DE4000064000063C0C80008C7E0034029E80233D
-:10DE5000060200838EA200083C0C8000AD800044C6
-:10DE6000240200018FBF008C8FBE00888FB7008412
-:10DE70008FB600808FB5007C8FB400788FB30074AC
-:10DE80008FB200708FB1006C8FB0006803E00008A3
-:10DE900027BD00900E000D1A000020218FBF008CBE
-:10DEA0008FBE00888FB700848FB600808FB5007C4E
-:10DEB0008FB400788FB300748FB200708FB1006C94
-:10DEC0008FB0006803E0000827BD00900A000D7ABB
-:10DED00000C020210E00163D028020211440FFDFEB
-:10DEE0003C0C80003C038008346300808C6200346A
-:10DEF0000282F82307E00017000000003C1508002C
-:10DF00008EB5310026B100013C010800AC31310072
-:10DF10000E0014E6024020213C0B80083570008082
-:10DF2000920A002502402021354200040E0014F020
-:10DF3000A20200250E000C9E024020210A000DA71F
-:10DF4000240200013C15080126B583100A000D6962
-:10DF50003C1080008C660030028620231880000868
-:10DF60002409000C3C0808008D083100327300FCC5
-:10DF70000000B821250700013C010800AC27310052
-:10DF8000AFA900308C65003000B4382318E000DB06
-:10DF900002E7502A1540FFDE0000000012E7002AC9
-:10DFA00002E768230287A02131B7FFFF326E00022B
-:10DFB00011C00034327F00103C148008369000807D
-:10DFC000920F000831F6004052C000CE8EA2000829
-:10DFD000024020210E0014E624130018A2130009A9
-:10DFE000921800052419FFFE024020210319B824CD
-:10DFF0000E0014F0A21700052404003900002821A7
-:10E000000E001618240600180A000DA724020001AD
-:10E0100092B6000C3C048008348300808C67003882
-:10E020000016AB0036B10081024020213225F0817C
-:10E030000E000C8D30C600FF3C0C8000AD8000440B
-:10E040000A000DA7240200013A6C0001318B000187
-:10E050001560FFAF0287A0210A000DF80000000044
-:10E060000040F809240400160A000DA7240200014C
-:10E07000024020210E00171D020028210A000D5C1D
-:10E080008FBF008C13E0FF743C038008346800806D
-:10E090008D0400388C66000403C610231C40FF6FFB
-:10E0A0003C0C800003C4282304A200010080F0215E
-:10E0B000AFB40010AFB70014AFA700183C1F80002A
-:10E0C00097E301208D0900309506005C8FB900545C
-:10E0D0008FAC00303062FFFF30D8FFFF0047702167
-:10E0E00037EF40000338682B01CF5821018D5025B0
-:10E0F000AFAB0020AFA90028AFAA0030AFA9002421
-:10E10000AFA0002CAFBE00349107000830E4000837
-:10E110001480008F020020218EA200040040F80924
-:10E1200027A400108FA900303128000255000001FB
-:10E13000327300FE3C048008348C0080918B000810
-:10E14000316A0040514000128FA400248C8D0004DD
-:10E1500011BE00BE240E00143265000110A0000C98
-:10E160008FA400242404000C122400D42A27000DBC
-:10E1700010E000CE2409000E2408000A52280001F5
-:10E18000241600088FA2002424440001AFA4002418
-:10E190008FA600143C038008346500800086F821B7
-:10E1A0008CB10030ACBF003090B9004E8CAE003066
-:10E1B0003418FFFF0338780401CF6821ACAD003478
-:10E1C0008FA600308FAC005430CA000803CC582111
-:10E1D0001140000CAFAB00588CA400208FB0005849
-:10E1E0001090009430C600FF92A2000C8FA700345C
-:10E1F0000240202100024B00352800800E000C8DCB
-:10E200003105F0803C0C8008359000808E0B00308A
-:10E210000171502319400070265900803C180800F5
-:10E220008F183198241FFF80033F7824332D007FFF
-:10E230003C0680003C0E800433110010ACCF0090EF
-:10E240001220003401AE282190A3006B54600032EC
-:10E250003C10800824070001A0A7006B94C4007A3A
-:10E260002486000AA60600123C0D800835A5008011
-:10E2700090B10008322C0040158000043C03800857
-:10E28000326E000115C0006200000000346400809E
-:10E290008C8F00208FB3005811F3000A3463010003
-:10E2A0008C7900000299C0231B0000778FA80058CA
-:10E2B000AC880020AC74000024140001AC7E000483
-:10E2C000AFB4005016C00037000000008FA400500B
-:10E2D000148000300000000012E00005000018214A
-:10E2E0008FA900303137000452E0FE920060102107
-:10E2F000240300010A000D5B006010210A000DF9E3
-:10E30000000038210040F809240400170A000DA776
-:10E31000240200013C10800836100080240900010E
-:10E32000024020210E0014E6A609001292080025E2
-:10E3300024050001AFA50050350200010240202154
-:10E340000E0014F0A20200250A000EA93C0D800860
-:10E3500027A50038AFA800600E000CA8AFA00038B9
-:10E360001440FF6D8FA800608FA5003830B0010009
-:10E370005200FF6A8EA200048FA3003C8D07005854
-:10E38000006720230483FF64AD0300580A000E5584
-:10E390008EA200040E000C9E024020210A000EC432
-:10E3A000000000000E0014E6024020213C05800819
-:10E3B00034A30080024020210E0014F0A076000952
-:10E3C00002C03021240400370E0016180000282156
-:10E3D0000A000EC28FA400508FA200185840FFA35D
-:10E3E0003C0D80080E0014E602402021920A002510
-:10E3F000240B0001AFAB0050354200040240202145
-:10E400000E0014F0A20200250A000EA93C0D80089F
-:10E410008CB600308EBE00082404001826D50001FA
-:10E4200003C0F809ACB500308FB200300A000D5BB4
-:10E43000324200043C07800094E5011A50A0FF6AB4
-:10E4400034C600100A000E8992A2000C122E002A77
-:10E450002A2F001511E0001E241900162418000CA4
-:10E460005638FF3E326500013C1F800893E3001BD5
-:10E470002410FFBD2416000E00703024A3E6001BFC
-:10E480000A000E65326500018C7F000017F4FF8DD5
-:10E49000000000008C67000403C7302304C1FF8420
-:10E4A0008FA800580A000EBF000000001629FF3692
-:10E4B0008FA200240A000E70241600102411000EF2
-:10E4C00052D1FF30241600100A000E6F24160016D9
-:10E4D0005639FF22326500013C1F800893E3001B80
-:10E4E0002410FFBD2416001000703024A3E6001B8A
-:10E4F0000A000E65326500010A000E64241600123F
-:10E500003C0380008C6201B80440FFFE2404080034
-:10E51000AC6401B803E000080000000030A5FFFF74
-:10E5200030C6FFFF3C0780008CE201B80440FFFECC
-:10E5300034E80180AD040000ACE400203C04800815
-:10E54000948300483063FFFF1060001D3C0B800087
-:10E5500024AA0012006A482B5120001A240A000342
-:10E5600094F901208F890000240C001A3338FFFF32
-:10E570002707FFFE0067782B39EE000100096B8248
-:10E5800001AE5824A10C000B116000478F830004DA
-:10E59000A50700148F88000435070001AF87000429
-:10E5A00030CC00405580000F3C0880003C0C8000BF
-:10E5B00035840180A485000E0A000F988F8F000C0F
-:10E5C000240A00033564018030CC00408F890000AC
-:10E5D0008F870004A08A000B5180FFF53C0C80005F
-:10E5E0003C088000950301203C08800895180040F5
-:10E5F0003079FFFF272EFFFE330FFFFF01CF682B7F
-:10E6000011A0000301C02021950200403044FFFF0B
-:10E610003C0B800000A4502335650180A4A4000EAB
-:10E62000A4AA00248F8F000C3C05800034AE01802A
-:10E630002418000230ED8000A5D8000CA5C90010F8
-:10E64000ADCF0028A5C6000811A0000E3C04800034
-:10E6500094AA01163142FFFC244800040105182148
-:10E660008C7940003326FFFF14C00007240EBFFF43
-:10E670003C0BFFFF35657FFF00E53824AF870004C2
-:10E680003C048000240EBFFF348C018000EE68241F
-:10E69000A58D0026AD89002C3C071000AC8701B881
-:10E6A00003E00008000000002402FFFE006238249E
-:10E6B0000A000F76AF8700043C05800034A4007088
-:10E6C0008C8A000090A601128F84000027BDFFF005
-:10E6D00030C300FF0003188230820100000038219F
-:10E6E00010400039246600033087400050E00039B4
-:10E6F00030882000000610800045C8218F2F400080
-:10E700002478000400187080AFAF000001C56821B4
-:10E710008DAC4000AFAC000494AB01163169FFFC36
-:10E72000012540218D054000AFA500088FA90008F4
-:10E7300000003021000028213C07080024E70100E8
-:10E740000A000FE9240800089042000024A50001F7
-:10E750002CAD000C0062C8210019C080030778218D
-:10E760008DEE000011A0000600CE302603A510217A
-:10E7700014A8FFF500051A005520FFF49042000090
-:10E780003C048000348700703C0508008CA53104EF
-:10E790008CE300002CA8002011000009006A382337
-:10E7A000000558803C0C0800258C3108016C48217C
-:10E7B00024AA0001AD2700003C010800AC2A310466
-:10E7C000AF86000C2407000100E0102103E00008E0
-:10E7D00027BD00101100FFFC0000382100066080FA
-:10E7E000018558218D6440002469000400093880A7
-:10E7F000AFA4000000E518218C664000AFA000081F
-:10E800000A000FD9AFA6000427BDFFD8AFB2001889
-:10E81000AFB00010AFBF0024AFB40020AFB3001CF6
-:10E82000AFB100148F8700003C0480009483010E78
-:10E8300030E2400000008021104000103072FFFFE5
-:10E840003C06002000E6282410A0000D30EA8000DD
-:10E850008F8800042409BFFF00E938243503100025
-:10E86000AF87000030F120001620000B3C1400049C
-:10E870002418FFBF0A0010380078102430EA800006
-:10E88000154000863C0C002030F120001220FFF8DB
-:10E890008F8300043C14000400F498241260FFF5F8
-:10E8A0002418FFBF3462004030F901001320000F2C
-:10E8B000AF8200043C02002000E2F82413E00005CF
-:10E8C0003C0B80003C04000400E41824106000CFDE
-:10E8D00000000000956A011E9569011C3146FFFF8A
-:10E8E0000009440000C82825AF85000C3C0E8000BC
-:10E8F00095CD010C8DC44000340CFFFF108C00B08E
-:10E9000031A5FFFF308F010055E0000124100010F9
-:10E9100030F11000522000083611000130F30020C1
-:10E920001660009F3C18100000F8A0241680009686
-:10E930003C040C003611000130E801001500000B0A
-:10E940003C0A00018F8800043109400015200008AE
-:10E9500000EA30243C0C1F0100EC58243C0A100053
-:10E96000516A00AE30AD02003C0A000100EA3024DA
-:10E9700014C000953C05100000E520240000402153
-:10E98000108000070000902100079E023272000FE5
-:10E99000001278803C0E080125CE82C001EE402195
-:10E9A0008F9400181280004702208021108000916F
-:10E9B000000000003C0980009539010E9103000021
-:10E9C000022030213338FFFF2705000410600008C3
-:10E9D0000000A021241F0003107F013A240400023C
-:10E9E000910C00011184011830EA00400012A1C00E
-:10E9F0008F92001C52400001362600403C138000DC
-:10EA00008E6F400031F10100122000CB30D1FFFBAE
-:10EA10003C1808008F18002430D20004330600048C
-:10EA200014C000CC30B0FFFF564000013631000466
-:10EA300002802021020028210E000F5502203021E3
-:10EA40001640000D00002021366501803C04800046
-:10EA50008C9301B80660FFFE2419200024140002E4
-:10EA6000A4B90008A0B4000BA4A000103C0510003D
-:10EA7000AC8501B8000020218FBF00248FB4002096
-:10EA80008FB3001C8FB200188FB100148FB000102C
-:10EA90000080102103E0000827BD002800EC582466
-:10EAA0001160FF7A30F120008F8D00043C0FFFFFD2
-:10EAB00035EE7FFF00EE382435A380000A001027D2
-:10EAC000AF8700003C0208008C4200383C0408007C
-:10EAD000248400381040004B2449FFFF3C03800091
-:10EAE000946C010E318BFFFF110000A02573000410
-:10EAF0003C1008008E1000301200000A30E60100C1
-:10EB00008F8A000431434000106000063C0F0F0064
-:10EB100000EF70243C0D010001AE402B110000DF1E
-:10EB20003265FFFF10C000693C140F0000F4282478
-:10EB30003C18020010B800658F99000C3270FFFF7E
-:10EB40000329982402649021924900042527000497
-:10EB5000000721C002002821362600020E000F55B2
-:10EB6000000000008FBF00248FB400208FB3001C72
-:10EB70008FB200188FB100148FB000100000102168
-:10EB800003E0000827BD00283C020BFF00E4182426
-:10EB9000345FFFFF03E3C82B5320FF6736110001EA
-:10EBA0003C0608008CC6002C3611000524D000015C
-:10EBB0003C010800AC30002C0A00105D30E8010078
-:10EBC0000A00105224100020024028213C120800A4
-:10EBD0008E5200D824040080264D00013C0108001C
-:10EBE000AC2D00D80E000F55240600030A0010E8D3
-:10EBF0008FBF00243C080801250882C00A00107C51
-:10EC00003C0980000A0010C5000048210E000FBC1E
-:10EC1000000000000A0010498F87000015A0FF5374
-:10EC20003C0A00012645000430AAFFFF36260002F8
-:10EC30003C0380008C7201B80640FFFE8F850008FF
-:10EC400034690180AD20000010A000AF3C048000BA
-:10EC5000254F001200AF702B51C000AC24030003FD
-:10EC6000947801202414001A30F140003313FFFF80
-:10EC7000A134000B122000B62663FFFE00A3C82BB0
-:10EC8000572000B4241FFFFE35080001A5230014FF
-:10EC9000AF8800043C108000240CBFFF010C482406
-:10ECA000240B000236080180A50B000CA50A000EFB
-:10ECB000A5060008A5090026A50700103C071000BE
-:10ECC000AE0701B80A0010E88FBF00243C0308001B
-:10ECD0008C6300D02E45000C001221C0386B00015F
-:10ECE0002D6200010045F82417E0FF9A3270FFFF03
-:10ECF000264CFFFC2D84000454800050000020218D
-:10ED0000386A00022D430001006580241600004A85
-:10ED10003270FFFF00076A420012702B01AE4024E0
-:10ED20005500006300002021001221C002002821AC
-:10ED30000A0010E53626000234DF0002028020219E
-:10ED400033E6FFFF0E000F5530A5FFFF0A0010ACA1
-:10ED50000000202124040100020028210E000F558C
-:10ED6000022030210A001098000000008C6640004C
-:10ED700030CF010011E0003D30F801003C120800E6
-:10ED80008E52002413000011323400043C1F0F0087
-:10ED900000FFC8243C0502001325000C8F8C000CDA
-:10EDA000022030213265FFFF0189582401641021BF
-:10EDB000904900043230FFFB2411FFFE2527000498
-:10EDC0000E000F55000721C00251902424040001B9
-:10EDD00012440052324300011460005802003021F6
-:10EDE000324A0004114000048F8D000031A8080051
-:10EDF0001500005A3265FFFF1680FF5B8FBF0024AD
-:10EE00003C138000366501803C0480008C9001B882
-:10EE10000600FFFE24062000240F0002A4A600081E
-:10EE2000A0AF000BA4A000103C0E1000AC8E01B8E7
-:10EE30000A0010E88FBF00240000202102002821D2
-:10EE40000A0010E5362600021140FEE90000A0216C
-:10EE5000952E0110950D000231C8FFFF51A8FEE468
-:10EE60000012A1C00A00108B8F92001C3C05080004
-:10EE70008CA5002430B800015300FF3B8FBF002455
-:10EE80003265FFFF36260002000020210E000F55DC
-:10EE9000000000000A0010E88FBF002436260002A0
-:10EEA0000E000F55240400800A0010E88FBF0024D4
-:10EEB000020028210E000F553226FFFB0A001159CF
-:10EEC000001221C091030001240200011062FEEA39
-:10EED00024040001241000021470FEC50000A021CB
-:10EEE00030E300401060FEC38F92001C952B011090
-:10EEF000950900023167FFFF1127FEE08FBF002454
-:10EF00000A00108B000000002403000334820180FB
-:10EF1000A043000B0A0011343C108000321400049E
-:10EF2000168000033265FFFF361200023250FFFFE9
-:10EF3000020030210A0011B1000020210000202130
-:10EF40000E000F553265FFFF0A0011863210FFFBDD
-:10EF5000241FFFFE0A001132011F4024020030214D
-:10EF60000E000F55240401000A00118C000000005F
-:10EF700027BDFFC8AFB00010AFBF00343C10600C1D
-:10EF8000AFBE0030AFB7002CAFB60028AFB500243D
-:10EF9000AFB40020AFB3001CAFB20018AFB1001483
-:10EFA0008E0E5000240FFF7F3C06800001CF6824A6
-:10EFB00035AC380C240B0003AE0C5000ACCB000871
-:10EFC0003C010800AC2000200E00174900000000A2
-:10EFD0003C0A0010354980513C066016AE09537C4E
-:10EFE0008CC700003C0860148D0500A03C03FFFFA7
-:10EFF00000E320243C02535300051FC2108202622A
-:10F0000034C57C008CBE007C8CBF00783C02600064
-:10F01000344420203C05080124A581382406000A38
-:10F020003C170098AF9E0014AF9F00100E0015F221
-:10F030003C11800036F600C03C1900103C18600CF2
-:10F040003C158000AF1953FC363E0180AEB6013C42
-:10F050008E300000320400031080FFFD32050001F5
-:10F0600014A000593206000210C0FFF93C048000D1
-:10F070008C92014024100040AC9200208C8F0148FB
-:10F08000000F760231C300701070013E2C780041F1
-:10F090005300000824040060241900201079000E99
-:10F0A0003C1F40003C088000AD1F01780A0012227E
-:10F0B000000000001464FFFB3C1F40000E001F66B0
-:10F0C000000000003C1F40003C088000AD1F01789C
-:10F0D0000A001222000000008C940148241700044A
-:10F0E0003488018000144C02312500FF8C830140DC
-:10F0F00010B7017024ABFFFA2D6A000651400013CF
-:10F100003C0580008C86014430A400FF30C300FF22
-:10F1100030D500FF2C76000816C0000226A7000498
-:10F1200024070003240C0009108C01A8288D000A74
-:10F1300011A001942413000A24050008108500146E
-:10F140008F980018000719C03C0580008CA701B8F3
-:10F1500004E0FFFE24140002AD030000A50900082E
-:10F16000A114000B8CB701483C0910003C1F400063
-:10F17000A51700108CA40144AD0400243C088000B5
-:10F18000ACA901B8AD1F01780A00122200000000EE
-:10F19000000692020007C8803C040801248482C053
-:10F1A00003247821270E0001324500FF24100001BE
-:10F1B000A1F2000014B0FFE3AF8E0018000719C0E1
-:10F1C0000A001260AF85001C8E3401283C068008BE
-:10F1D000AE3400208E2A01048E29010094C8004814
-:10F1E000AF8A0000AF8900043103FFFF0E000F4E0D
-:10F1F000AF8300083C0708008CE700C010E0002443
-:10F200008F8700003C0C08008D8C00C4258B00010A
-:10F210003C010800AC2B00C43C1980008F24012461
-:10F220003C186020AF040014000000003C06800081
-:10F230003C174000ACD70138000000005280FF8A24
-:10F240003206000226870140268500802409FF80BF
-:10F2500000E9682400A998240013194030AC007F0D
-:10F26000000DB14030F5007F3C0B200035620002FC
-:10F27000006C402502D550250142A0250102F82549
-:10F28000ACDF0830ACD408300A0012283206000285
-:10F290003C0E001000EE682415A000A68F83000429
-:10F2A0003C1508008EB500203C16800096D2010E59
-:10F2B00026B3000130EF40003255FFFF3C0108004B
-:10F2C000AC33002011E000B6000090213C18002073
-:10F2D00000F8B82412E000B330E280008F990004F7
-:10F2E000241FBFFF00FF382437231000AF87000022
-:10F2F00030EA2000114000B5240CFFBF3C0B000495
-:10F3000000EB302410C00002006C10243462004076
-:10F3100030ED010011A0000EAF8200043C0F002070
-:10F3200000EF702411C000043C16000400F698247D
-:10F3300012600135000000009622011E963F011C5C
-:10F340003058FFFF001FCC000319B825AF97000C01
-:10F350009628010C8E2440003403FFFF108300C860
-:10F360003105FFFF308901005520000124120010F3
-:10F3700030E41000108000133653000130EA002002
-:10F380001540000A3C0B100000EB302410C0000DAB
-:10F390003C0F0BFF3C130C0000F3702435EDFFFF16
-:10F3A00001AE602B11800007365300013C160800A7
-:10F3B0008ED6002C3653000526D200013C010800F1
-:10F3C000AC32002C30F7010016E0000B3C060001C7
-:10F3D0008F880004311840005700000800E62824F8
-:10F3E0003C021F0100E2F8243C19100013F9010A45
-:10F3F00030A302003C06000100E6282414A000A26D
-:10F400003C09100000E92024000040211080000782
-:10F410000000A821000766023195000F00155880F2
-:10F420003C0A0801254A82C0016A40218F8D0018DC
-:10F4300011A0006802609021148000033C09800044
-:10F440003C080801250882C0952E010E910300009A
-:10F450000260302131C4FFFF2485000410600008E1
-:10F460000000B821240F0003106F011E24190002B0
-:10F47000911F000113F9002630E200400015B9C0C9
-:10F480008F89001C51200001366600403C16800028
-:10F490008ECB400031730100126000C530D50004EE
-:10F4A0003C0C08008D8C002430D3FFFB3186000417
-:10F4B00014C0010630B2FFFF56A0000136730004ED
-:10F4C00002E02021024028210E000F550260302169
-:10F4D00016A0000D0000202136C501803C048000EC
-:10F4E0008C8D01B805A0FFFE240F2000240E000221
-:10F4F000A4AF0008A0AE000BA4A000103C051000B3
-:10F50000AC8501B8000020210A001367008010219B
-:10F510001040FFDB0000B821952A0110950300027E
-:10F520003148FFFF5068FFD60015B9C00A00132FFD
-:10F530008F89001C2413BFFF0073282410A000072C
-:10F54000240E87FF006E48241520000A3C1200603C
-:10F5500000F2782411E00007000000000E000D34D6
-:10F56000000000001040FF323C0680000A001295A7
-:10F570003C1980000E0014CF000000000A00136741
-:10F58000000000000E0014F5000000003C1F4000C9
-:10F590003C088000AD1F01780A0012220000000024
-:10F5A00030E280001040FF528F8300043C050020B1
-:10F5B00000E520241080FF4E3C09FFFF35287FFF27
-:10F5C00000E838240A0012C9346380000A0012D20D
-:10F5D000006C10243C0408008C8400381480000265
-:10F5E0002489FFFF000048213C0380009476010E2F
-:10F5F00032D7FFFF110000EA26F600043C12080093
-:10F600008E5200301240000A30EA01008F99000447
-:10F6100033384000130000063C030F0000E3402491
-:10F620003C0201000048F82B13E000D232C5FFFF76
-:10F630001140002F3C0C0F0000EC30243C0B02006A
-:10F6400010CB002B8F8F000C3C0E080025CE00380D
-:10F6500032D2FFFF01E9282400AE682191A90004FD
-:10F6600025270004000721C0024028213666000239
-:10F670000E000F55000000000A0013670000102163
-:10F680000A0012EA241200203C0308008C6300D810
-:10F6900002A0282124040080246200013C0108000B
-:10F6A000AC2200D80E000F55240600030A00136791
-:10F6B000000010218C840140010028213C038000BF
-:10F6C0008C7F01B807E0FFFE2402001CACA4000000
-:10F6D000A0A2000B3C081000AC6801B83C1F400021
-:10F6E0003C088000AD1F01780A00122200000000D3
-:10F6F0003C0308008C6300D02EA5000C001521C02F
-:10F70000387800012F1200010245B82416E0FFD618
-:10F7100032D2FFFF26B9FFFC2F240004148000081A
-:10F7200000002021386800022D0200010045F82465
-:10F7300013E0000600075A4232D2FFFF00002021EA
-:10F74000024028210A0013AA366600020015182B71
-:10F75000016350241540000532D2FFFF001521C07F
-:10F76000024028210A0013AA366600020000202168
-:10F77000024028210E000F553266FFFB0A0013E6F7
-:10F78000001521C010930068000768802406000B54
-:10F790001486FE6D000719C00007C0803C190801DF
-:10F7A000273982C0031930210A001260A0C000016D
-:10F7B00034D5000202E0202130A5FFFF0E000F55D6
-:10F7C00032A6FFFF0A001350000020210007A0808E
-:10F7D0003C1F080127FF82C0029F102190570000A4
-:10F7E00012E0FE59000719C0A04000008F8A0018DF
-:10F7F0002542FFFF1440FE54AF820018000719C0D5
-:10F800000A001260AF80001C0E000FBC0000000058
-:10F810000A0012E28F8700001460FEF73C06000128
-:10F8200026A900043125FFFF366600023C03800054
-:10F830008C7501B806A0FFFE8F8900083C0A800085
-:10F8400035440180AC8000001120009B2418000387
-:10F8500024AC0012012C582B11600097000000000E
-:10F86000947201203C138000240F001A324EFFFFD7
-:10F87000366A018030ED4000A14F000B11A00091CD
-:10F8800025C3FFFE0123B02B16C0008F2417FFFEF7
-:10F8900035080001A5430014AF880004241FBFFFF2
-:10F8A000011FC82424080002A7C8000CA7C5000E29
-:10F8B000A7C60008A7D90026A7C700103C0710005C
-:10F8C000AE2701B80A0013670000102124040100CC
-:10F8D000024028210E000F55026030210A00133C1F
-:10F8E0000000000091030001241500011075FF06BF
-:10F8F00024040001241200021472FEE10000B82169
-:10F9000030F6004052C0FEDF8F89001C95270110A1
-:10F910009518000230F7FFFF1317FEFB0000B82117
-:10F920000A00132F8F89001C3C120801265282C046
-:10F9300001B2702100067A02A1CF00013C0B6000E9
-:10F940008D6318202410000100F098043C05080184
-:10F9500024A582C20073B02501A5A8210006640277
-:10F96000000719C0A6AC0000AD7618200A0012618D
-:10F970003C058000366600020E000F55240400800E
-:10F980000A001367000010210003A080028698215E
-:10F990008E7200043C1160000A00120F02512821EF
-:10F9A0008C66400030D5010012A0003730EC010019
-:10F9B0003C1508008EB50024118000133277000436
-:10F9C0003C050F0000E568243C07020011A7000E6B
-:10F9D0008F84000C3C180800271800380260302182
-:10F9E000008990240258782191EE000432C5FFFF6F
-:10F9F0003272FFFB25C90004000921C00E000F551B
-:10FA00002413FFFE02B3A8242419000112B9003008
-:10FA100032A200011040000732A800040240302149
-:10FA2000000020210E000F5532C5FFFF3252FFFBB0
-:10FA300032A80004110000048F8B0000316A080016
-:10FA40005540002B32C5FFFF16E0FEC60000102116
-:10FA50003C16800036C401803C0580008CA301B8B0
-:10FA60000460FFFE240C200024060002A48C000881
-:10FA7000A086000BA48000103C151000ACB501B8A6
-:10FA80000A001367000010213C0D08008DAD002412
-:10FA900031A7000150E0FEB30000102132C5FFFF86
-:10FAA00036660002000020210E000F550000000005
-:10FAB0000A00136700001021A3D8000B0A001436B7
-:10FAC000241FBFFF2417FFFE0A001434011740242F
-:10FAD0003257000416E0000332C5FFFF365F000214
-:10FAE00033F2FFFF024030210A0014B80000202149
-:10FAF000024030210E000F55240401000A0014A01A
-:10FB0000000000003C0380008C6401003082003E55
-:10FB10001440000800000000AC6000488C66010042
-:10FB200030C507C010A0000500000000AC60004C0C
-:10FB3000AC60005003E0000824020001AC600054F7
-:10FB4000AC6000408C6801003107380010E0FFF91C
-:10FB5000000000002402000103E00008AC60004443
-:10FB60003C03900034620001008220253C038000A9
-:10FB7000AC6400208C65002004A0FFFE00000000A3
-:10FB800003E00008000000003C0280003443000154
-:10FB90000083202503E00008AC44002027BDFFD8E7
-:10FBA000AFB100143C048000AFBF0020AFB3001C15
-:10FBB000AFB20018AFB000108C9201408C90014899
-:10FBC0002402000E00108C02322300FF1062005944
-:10FBD000020428242866000F10C00013286A00378A
-:10FBE000240700061067008E286800075100002DCA
-:10FBF00024040009106000783C06800024090001FC
-:10FC0000106900B0000000000000000D8FBF002050
-:10FC10008FB3001C8FB200188FB100148FB000108A
-:10FC200003E0000827BD002811400059240D0038CA
-:10FC3000286B0035116000053C058000240C001F76
-:10FC4000146CFFF1000000003C0580008CB801B886
-:10FC50000700FFFE34B90180AF320000241F00010D
-:10FC6000241200023C021000AF200004A73100085B
-:10FC7000A33F000AA332000BA7300010AF200024DE
-:10FC8000AF200028ACA201B88FBF00208FB3001CAA
-:10FC90008FB200188FB100148FB0001003E000087D
-:10FCA00027BD0028106400232405000B1465FFD62F
-:10FCB0003218FFFF170000203C0580008F93FED014
-:10FCC000927F000533F900041720FFCF00000000E9
-:10FCD0000E0014E602402021926900050240202116
-:10FCE000352800040E0014F0A26800059267000594
-:10FCF00030E2000414400002000000000000000D8B
-:10FD0000926B000024060020316A00FF1546000AAD
-:10FD10003C0580008CA401B80480FFFE34AD018056
-:10FD2000240E00053C0C1000ADB20000A1AE000B8B
-:10FD3000ACAC01B83C0580008CA301B80460FFFEA8
-:10FD400034AF018024130002ADF20000ADF20004D4
-:10FD5000A5F10008A1F3000AA1F3000BA5F0001023
-:10FD6000ADE000248CB101443C101000ADF100283E
-:10FD7000ACB001B88FBF00208FB3001C8FB2001849
-:10FD80008FB100148FB0001003E0000827BD0028D9
-:10FD9000106DFFAD240E0080146EFF9B000000006C
-:10FDA0003C0580008CA301B80460FFFE34AF0180E5
-:10FDB00024120002A1F2000BA5F10008A5F000102A
-:10FDC0008CB301443C021000A5F30012ACA201B8B0
-:10FDD0000A0015318FBF00208CC301B80460FFFEFC
-:10FDE00034D30180AE720000AE6000042412000122
-:10FDF000A671000824110002A272000AA271000B71
-:10FE0000A67000108CD001443C0F1000AE7000248E
-:10FE1000AE600028ACCF01B80A00156C8FBF00207F
-:10FE20003C0380008C6601B804C0FFFE3462018090
-:10FE30003C06080190C68300AC52000010C00003CD
-:10FE4000000038213C0708018CE783083C0580004E
-:10FE500034AA01802404000234CC0001AC47000421
-:10FE6000A5510008A14C000AA144000BA5500010A8
-:10FE70008CAB01440000202101402821AD4B00241F
-:10FE800010C000038FBF00203C0408018C84830451
-:10FE90008FB3001C8FB200188FB100148FB0001008
-:10FEA0003C0E10003C0D800027BD0028ACA40028AB
-:10FEB000ADAE01B83C010801A020830003E00008BA
-:10FEC0000000000010A0000B3C0680008C9801444C
-:10FED000241900023C010801A03983003C010801FB
-:10FEE000AC3283083C010801AC3883040A00156C6D
-:10FEF0008FBF00208CDF01B807E0FFFE34C7018010
-:10FF000024090002ACF20000ACF20004A4F10008E5
-:10FF1000A0E9000AA0E9000BA4F00010ACE0002466
-:10FF20008CC801443C021000ACE80028ACC201B807
-:10FF30000A00156C8FBF002027BDFFE8AFBF00107F
-:10FF40000E000F4E000000003C0280008FBF00102A
-:10FF500000002021AC4001800A00101027BD0018CD
-:10FF60003084FFFF30A5FFFF10800007000018213C
-:10FF70003082000110400002000420420065182178
-:10FF80001480FFFB0005284003E0000800601021FA
-:10FF900010C00007000000008CA2000024C6FFFF74
-:10FFA00024A50004AC82000014C0FFFB24840004DC
-:10FFB00003E000080000000010A0000824A3FFFFD9
-:10FFC000AC86000000000000000000002402FFFFDB
-:10FFD0002463FFFF1462FFFA2484000403E0000896
-:10FFE0000000000027BDFFE8AFBF0014AFB0001055
-:10FFF0000E0014E6008080213C04800834830080D9
-:020000040001F9
-:10000000906500250200202134A200200E0014F08B
-:10001000A0620025020020218FBF00148FB00010C5
-:100020000A000C9E27BD00183C03800027BDFFF886
-:1000300034620180AFA20000308C00FF30AD00FFC1
-:1000400030CE00FF3C0B80008D6401B80480FFFEC1
-:10005000000000008FA900008D6801288FAA000011
-:100060008FA700008FA400002405000124020002D5
-:10007000A085000A8FA30000359940003C051000C0
-:10008000A062000B8FB800008FAC00008FA60000AC
-:100090008FAF000027BD0008AD280000AD40000470
-:1000A000AD800024ACC00028A4F90008A70D001002
-:1000B000A5EE001203E00008AD6501B83C0680081B
-:1000C00027BDFFE834C50080AFBF001090A700092E
-:1000D0002402001230E300FF1062000B0080302188
-:1000E0008CA8005000882023048000088FBF0010D7
-:1000F0008CAA0034240400390000282100CA4823B7
-:1001000005200005240600128FBF00102402000104
-:1001100003E0000827BD00180E00161800000000BC
-:100120008FBF00102402000103E0000827BD001863
-:1001300027BDFFC8AFB1002C00A08821AFB20030AE
-:1001400027A500100080902102202021AFBF00349D
-:10015000AFB000280E000CA8AFA000101440009B08
-:100160003C07800834E400809086000830C5000811
-:1001700014A000698FA700103C1880083710008079
-:10018000920F000831EE000815C000022408000399
-:10019000000040213C0B800891650011916A00121B
-:1001A000356600808CDF0054314900FF0128202192
-:1001B00030A300FF000410800062282100BFC82B7C
-:1001C000132000080000000094D0005C8CCF005485
-:1001D000320DFFFF01E5702301AE602B118000940A
-:1001E0000000000094D9005C3323FFFF30FF0004BF
-:1001F00013E00074000830808FA8001C0068102BEA
-:100200005040004F30E30004006610232C4600806D
-:1002100010C0000200408021241000800E0014E66F
-:10022000024020213C03800834660080240700013E
-:10023000ACC7000C90C8000800106840346701008B
-:10024000311F007FA0DF00088E390004273800012D
-:10025000ACD80030A4D0005C8CCF003C9630000EAF
-:1002600001F07021ACCE00208CCC003C018D5821D7
-:10027000ACCB001C8E2A0004ACEA00008E290008DA
-:10028000ACE900048FA5001030A4000854800032AF
-:1002900093A60020A0C0004E90C9004E2402FFDFAC
-:1002A0003C188008A0E9000890C50008370D0080C0
-:1002B000240A005000A22024A0C400088E3900089F
-:1002C000ADB900388F0F00148DB0003001F07021EF
-:1002D000ADAE003491AC0000318B00FF116A002CF0
-:1002E000264501000E0014F00240202124040038AD
-:1002F000000028210E0016182406000A8FBF0034C3
-:100300008FB200308FB1002C8FB000282402000182
-:1003100003E0000827BD003830E801001100003D6F
-:100320008FA300148C8A0058006A48230520FF938D
-:100330003C188008AC8300580A00166C8FA7001088
-:10034000240702181060FFB100E610238FA2001CE2
-:100350000A001691004610233C188008370D0080D3
-:10036000A0E600088E390008240A0050ADB9003814
-:100370008F0F00148DB0003001F07021ADAE00344D
-:1003800091AC0000318B00FF156AFFD626450100B5
-:100390002406FF8000A610243C098000AD2200281E
-:1003A0008E27000830A3007F3C04800C0064F821F5
-:1003B000AFE700D08E280008AF9F00280A0016C7BC
-:1003C000AFE800D40A00168E2C6202188E230008B3
-:1003D0003C04800834820080AC4300540240202159
-:1003E0000E001607AC400030240400382405008DB0
-:1003F0000E001618240600128FBF00348FB2003092
-:100400008FB1002C8FB000282402000103E0000807
-:1004100027BD0038AC800058908C0008240DFFF7F1
-:10042000018D5824A08B00080A00166C8FA70010BD
-:100430008CD800540A0016890305182327BDFFE84D
-:10044000AFBF001090A6000D30C7001010E0000CE8
-:10045000008040213C0280088C4400048CA30008EA
-:100460001064000830C9000530C5000510A0001C4C
-:100470008FBF00102402000103E0000827BD001810
-:1004800030C900051120001030CB001210E0FFF938
-:100490008FBF00103C0880088CA700088D06000460
-:1004A00014E6FFF524020001240400382405008D21
-:1004B0000E001618240600128FBF0010240200013F
-:1004C00003E0000827BD0018240A0012156AFFE99E
-:1004D0008FBF0010010020210A00165A27BD001806
-:1004E000000020210A000D1A27BD00183C05080055
-:1004F00024A55D683C04080024847B343C02080089
-:1005000024425D70240300063C010801AC258310E1
-:100510003C010801AC2483143C010801AC2283187F
-:100520003C010801A023831C03E000080000000038
-:1005300003E00008240200013C028000308800FF34
-:10054000344701803C0680008CC301B80460FFFE84
-:10055000000000008CC501282418FF803C0D800A93
-:1005600024AF010001F8702431EC007FACCE0024F0
-:10057000018D2021ACE50000948B00DA3509600084
-:1005800024080002316AFFFFACEA000424020001E3
-:10059000A4E90008A0E8000BACE000243C07100030
-:1005A000ACC701B8AF84002803E00008AF85005C49
-:1005B0008C9800048F8C00282409FFBF0305782342
-:1005C000AC8F0004918E00C42403FFEF31CD007F77
-:1005D000A18D00C48C8B00208F860028A780004C42
-:1005E000356A0002A4C000ACAC8A002090C800C4E8
-:1005F00001093824A0C700C48F840028AC8000DC27
-:10060000908500C400A3102403E00008A08200C469
-:100610003C028000344501803C0480008C8301B89A
-:100620000460FFFE8F89005C2407608324060002BB
-:10063000ACA900008C880124ACA80004A4A7000881
-:10064000A0A6000B3C05100003E00008AC8501B833
-:10065000938800388F8900508F82002830C600FFB1
-:100660000109382330E900FF0122182130A500FFDD
-:100670002468007810C0000201243821008038214D
-:1006800030E400031480000330AA00031140000D81
-:10069000312B000310A000090000102190ED000094
-:1006A000244E000131C200FF0045602BA10D000067
-:1006B00024E700011580FFF92508000103E0000888
-:1006C000000000001560FFF30000000010A0FFFB19
-:1006D000000010218CF8000024590004332200FF90
-:1006E0000045782BAD18000024E7000415E0FFF961
-:1006F0002508000403E0000800000000938500388E
-:10070000938800488F870050000432003103007F37
-:1007100000E5102B30C47F001040000F0064282536
-:100720008F8400283C0980008C8A00DCAD2A00A45C
-:100730003C03800000A35825AC6B00A08C6C00A08B
-:100740000580FFFE000000008C6D00ACAC8D00DC6D
-:1007500003E000088C6200A80A0017DA8F840028E2
-:10076000938800493C02800000805021310300FE44
-:10077000A383004930ABFFFF30CC00FF30E7FFFF21
-:10078000344801803C0980008D2401B80480FFFEBC
-:100790008F8D005C24180016AD0D00008D22012401
-:1007A0008F8D0028AD0200048D590020A507000898
-:1007B000240201B4A119000AA118000B952F0120F1
-:1007C0008D4E00088D4700049783004C8D590024FE
-:1007D00001CF302100C7282100A320232418FFFFC8
-:1007E000A504000CA50B000EA5020010A50C00121C
-:1007F000AD190018AD18002495AF00D83C0B1000BF
-:100800002407FFF731EEFFFFAD0E00288DAC00741A
-:10081000AD0C002CAD2B01B88D46002000C728245C
-:1008200003E00008AD4500208F8800280080582193
-:1008300030E7FFFF910900C63C02800030A5FFFFB2
-:10084000312400FF00041A000067502530C600FF65
-:10085000344701803C0980008D2C01B80580FFFEE3
-:100860008F82005C240F0017ACE200008D39012458
-:10087000ACF900048D780020A4EA0008241901B422
-:10088000A0F8000AA0EF000B952301208D6E000850
-:100890008D6D00049784004C01C35021014D6021EF
-:1008A00001841023A4E2000CA4E5000EA4F90010BA
-:1008B000A4E60012ACE000148D780024240DFFFFA4
-:1008C000ACF800188D0F006CACEF001C8D0E0068AA
-:1008D0003C0F1000ACEE0020ACED0024950A00AEF9
-:1008E000240DFFF73146FFFFACE60028950C0070A1
-:1008F0009504007231837FFF0003CA003082FFFF3E
-:100900000322C021ACF8002CAD2F01B8950E007267
-:100910008D6A002000AE3021014D2824A50600720A
-:1009200003E00008AD6500203C02800034460180F1
-:100930003C0580008CA301B80460FFFE2409001868
-:10094000ACC40000A0C9000B8F8800283C04100034
-:10095000950700AEA4C70010ACC0003003E000084B
-:10096000ACA401B83C028000344501803C04800006
-:100970008C8301B80460FFFE8F8A003424060019BE
-:100980009549001C3128FFFF000839C0ACA70000C2
-:10099000A0A6000B3C05100003E00008AC8501B8E0
-:1009A0008F87003C0080402130C400FF3C0680005F
-:1009B0008CC201B80440FFFE8F89005C938300580D
-:1009C00034996000ACA90000A0A300058CE20010DF
-:1009D000240F00022403FFF7A4A20006A4B9000814
-:1009E0008D180020A0B8000AA0AF000B8CEE00000C
-:1009F000ACAE00108CED0004ACAD00148CEC001C0F
-:100A0000ACAC00248CEB0020ACAB00288CEA002CB2
-:100A10003C071000ACAA002C8D090024ACA90018DA
-:100A2000ACC701B88D05002000A3202403E0000816
-:100A3000AD040020938500582403000127BDFFE882
-:100A400000A330042CA20020AFB00010AFBF0014F0
-:100A500000C01821104000132410FFFE3C070800BE
-:100A60008CE7319000E610243C08800035050180B9
-:100A700014400005240600848F890028240A0004FD
-:100A80002410FFFFA12A00EC0E00187600000000E1
-:100A9000020010218FBF00148FB0001003E0000887
-:100AA00027BD00183C0608008CC631940A0018A81F
-:100AB00000C310248F87003427BDFFE0AFB20018B9
-:100AC000AFB10014AFB00010AFBF001C30D000FFBA
-:100AD00090E6000D00A088210080902130C5007FA5
-:100AE000A0E5000D8F8500288E2300188CA200C081
-:100AF0001062002E240A000E0E00189BA38A0058D4
-:100B00002409FFFF104900222404FFFF52000020A7
-:100B1000000020218E2600003C0C001000CC582440
-:100B2000156000393C0E000800CE682455A0003F37
-:100B3000024020213C18000200D880241200001F2F
-:100B40003C0A00048F8700348CE200148CE3001010
-:100B50008CE500140043F82303E5C82B132000059F
-:100B6000024020218E24002C8CF1001010910031C5
-:100B70000240202124020012A38200580E00189B7C
-:100B80002412FFFF105200022404FFFF0000202166
-:100B90008FBF001C8FB200188FB100148FB00010EF
-:100BA0000080102103E0000827BD002090A800C4A9
-:100BB000350400200A0018D1A0A400C400CA4824AB
-:100BC0001520000B8F8B00348F8D00348DAC0010FE
-:100BD0001580000B024020218E2E002C51C0FFEC0E
-:100BE00000002021024020210A0018EC24020017F6
-:100BF0008D66001050C0FFE6000020210240202139
-:100C00000A0018EC240200110240202124020015E1
-:100C10000E00189BA3820058240FFFFF104FFFDC2B
-:100C20002404FFFF0A0018DB8E2600000A001912B8
-:100C3000240200143C08000400C8382450E0FFD40B
-:100C400000002021024020210A0018EC2402001399
-:100C50008F86002827BDFFE0AFB10014AFBF00189A
-:100C6000AFB0001090C300C430A500FF3062002078
-:100C700010400008008088218CCB00C02409FFDFD1
-:100C8000256A0001ACCA00C090C800C4010938241C
-:100C9000A0C700C414A000403C0C80008F84002832
-:100CA000908700C42418FFBF2406FFEF30E3007FC5
-:100CB000A08300C4979F004C8F8200508F8D002826
-:100CC00003E2C823A799004CA5A000AC91AF00C4D3
-:100CD00001F87024A1AE00C48F8C0028A18000C749
-:100CE0008F8A0028A5400072AD4000DC914500C409
-:100CF00000A65824A14B00C48F9000248F8400507C
-:100D00009786004C0204282110C0000FAF850024F4
-:100D1000A38000483C0780008E2C000894ED012041
-:100D20008E2B0004018D5021014B802102062023CF
-:100D30003086FFFF30C8000F390900013131000152
-:100D400016200009A3880048938600388FBF00183A
-:100D50008FB100148FB0001027BD0020AF85005464
-:100D600003E00008AF86005000C870238FBF001852
-:100D7000938600388FB100148FB0001034EF0C0050
-:100D8000010F282127BD0020ACEE0084AF85005460
-:100D900003E00008AF860050359001800200282152
-:100DA0000E001876240600828F840028908600C4E6
-:100DB00030C5004050A0FFBAA38000588F85003C8A
-:100DC0003C0680008CCD01B805A0FFFE8F89005C39
-:100DD0002408608224070002AE090000A60800086B
-:100DE000A207000B8CA300083C0E1000AE030010FD
-:100DF0008CA2000CAE0200148CBF0014AE1F0018B1
-:100E00008CB90018AE1900248CB80024AE18002844
-:100E10008CAF0028AE0F002CACCE01B80A001936FA
-:100E2000A38000588F8A002827BDFFE0AFB10014CF
-:100E3000AFB000108F880050AFBF00189389002C0E
-:100E4000954200AC30D100FF0109182B00808021B1
-:100E500030AC00FF3047FFFF000058211460000352
-:100E6000310600FF01203021010958239783004CEF
-:100E70000068202B1480001B000000001068004355
-:100E8000240A0001118A004834E708803165FFFF19
-:100E90000E001818020020210E0018588F84005CE4
-:100EA0008F840028948D007025AC0001A48C007004
-:100EB000948B00703C0608008CC6318831677FFF38
-:100EC00010E6004F0000000002002021022028212F
-:100ED0008FBF00188FB100148FB000100A001922C4
-:100EE00027BD0020914400C42406FF800086882589
-:100EF000A15100C49784004C3088FFFF1100001CF2
-:100F00009389002C8F8E00282419EFFF008BF82383
-:100F100095D800AC0168682B33E900FF03197824E9
-:100F2000A5CF00AC51A0002A010058218E05002059
-:100F30002408FFFB2403000100A81024AE020020B7
-:100F40001183002534E78000020020213165FFFF76
-:100F50000E00181801203021978B004C8F8700500D
-:100F6000A780004C00EB8023AF9000509389002CA9
-:100F70008F8C00288FBF00188FB100148FB0001025
-:100F800027BD002003E00008A18900C78E080020CB
-:100F90002409FFFB34E7800001092824AE05002066
-:100FA000158AFFBA34E70880020020210E0017E6F8
-:100FB0003165FFFF02002021022028218FBF001889
-:100FC0008FB100148FB000100A00192227BD002035
-:100FD0000A0019D900004821020020213165FFFFD5
-:100FE0000E0017E601203021978B004C8F870050B0
-:100FF000A780004C00EB80230A0019E9AF90005055
-:1010000094890070240A8000012A4024A48800707A
-:10101000908500709099007030A200FF000219C204
-:101020000003F827001FC1C0332F007F01F870258F
-:10103000A08E00700A0019C1020020218F880028AC
-:1010400024030001910A0078910500C72509007862
-:101050003147003F24E6FFE000C318042CC2002003
-:1010600030670019A385002C1040001AAF89003C9E
-:101070003C0A8000354B00022405000124060001D3
-:1010800014E00016006B1024000028211440000F0B
-:10109000306300201060000F240500018D060074ED
-:1010A0008D1900742403FF8000C3102400027940CE
-:1010B0003338007F01F868253C0E100001AE602532
-:1010C000AD4C083091280001310600010A00199743
-:1010D0000000000003E00008000000008D0F007415
-:1010E0008D0D00742418FF8001F87024000E41401B
-:1010F00031AC007F010C50253C0B1000014B382512
-:101100003C0980000A001997AD27083027BDFFD899
-:10111000AFB000108F90003CAFB40020AFB100140E
-:10112000AFBF0024AFB3001CAFB200188E05001093
-:101130003C0208008C4231B08F86004030A73FFF50
-:1011400000E2182B8CD20014008088218CD3002060
-:10115000106000070000A02190CB000D240AFF8042
-:10116000014B4824312800FF1500000C0005638264
-:10117000022020212411000DA39100588FBF0024CC
-:101180008FB400208FB3001C8FB200188FB10014F1
-:101190008FB000100A00189B27BD0028318500037E
-:1011A00054A0FFF40220202194CF001C8F8E002831
-:1011B0008E070028A5CF00D88CCD0010024D30231B
-:1011C00010E6005C2402001F0E00189BA38200584A
-:1011D000241FFFFF105F004E2404FFFF8F83004495
-:1011E0008F880034026398218D0900100123102399
-:1011F0008F830020AD020010AD1300208C670074B7
-:1012000000F3202B14800062022020218F860040F2
-:101210008E0C00248CC5002411850007022020219B
-:10122000240E001C0E00189BA38E0058240DFFFFF7
-:10123000104D00372404FFFF8F8400348C98002465
-:10124000270F0001AC8F0024127200448F990020F8
-:101250008F320074125300413C0A00808E09000056
-:10126000012A10241440003A000000008E040014EB
-:101270002412FFFF10920006240B001B02202021E5
-:101280000E00189BA38B0058105200212404FFFF6E
-:101290008E0300003C0C0001006C282410A00013F9
-:1012A0003C0600800066A024168000090200282168
-:1012B00002202021240E001A0E00189BA38E005835
-:1012C000240DFFFF104D00122404FFFF020028210F
-:1012D000022020210E0018BB240600012410FFFF6D
-:1012E0002404FFFF1050000A241400018F8F0034E3
-:1012F000022020210280302195F2003424050001D3
-:10130000265800010E001997A5F80034000020218E
-:101310008FBF00248FB400208FB3001C8FB2001841
-:101320008FB100148FB000100080102103E000087E
-:1013300027BD00288F83004400E3C8210259C02B39
-:101340001300FFA88F8800340A001A8024020018B6
-:10135000AC8000200A001AAA8E0400148E1F000020
-:101360003C07008003E798241660FFF92408001A60
-:10137000022020210E00189BA38800582403FFFFA1
-:101380001443FFBA2404FFFF0A001AD38FBF0024BE
-:10139000240B001D0E00189BA38B0058240AFFFF8E
-:1013A000144AFF9A2404FFFF0A001AD38FBF0024B7
-:1013B0008F85002827BDFFD8AFB3001CAFB200183F
-:1013C000AFB10014AFB00010AFBF002090A700C4B1
-:1013D0008F90003C2412FFFF34E200409206000090
-:1013E000A0A200C48E030010008098211072000695
-:1013F00030D1003F2408000D0E00189BA388005830
-:10140000105200252404FFFF8F8A00288E0900183F
-:101410008D4400C01124000702602021240C000E1E
-:101420000E00189BA38C0058240BFFFF104B001AD2
-:101430002404FFFF24040020122400048F8D0028C0
-:1014400091AF00C435EE0020A1AE00C48F850044EA
-:1014500010A00019000000001224004A8F980028F4
-:101460008F92FED0971000709651000A52300048BB
-:101470008F9300303C1F08008FFF318C03E5C82B91
-:101480001720001E02602021000028210E0019975D
-:1014900024060001000020218FBF00208FB3001C14
-:1014A0008FB200188FB100148FB00010008010218F
-:1014B00003E0000827BD00285224002A8E050014EE
-:1014C0008F840028948A007025490001A489007047
-:1014D000948800703C0208008C42318831077FFFFD
-:1014E00010E2000E00000000026020210E00192210
-:1014F000240500010A001B34000020212402002DD5
-:101500000E00189BA38200582403FFFF1443FFE141
-:101510002404FFFF0A001B358FBF00209499007040
-:10152000241F800024050001033FC024A4980070FC
-:1015300090920070908E0070325100FF001181C2B5
-:1015400000107827000F69C031CC007F018D58252D
-:10155000A08B00700E001922026020210A001B34AB
-:10156000000020212406FFFF54A6FFD68F84002808
-:10157000026020210E001922240500010A001B34FC
-:1015800000002021026020210A001B4E2402000AD4
-:101590002404FFFD0A001B34AF9300508F880028FD
-:1015A00027BDFFE8AFB00010AFBF0014910A00C420
-:1015B0008F87003C00808021354900408CE6001078
-:1015C000A10900C43C0208008C4231B030C53FFF85
-:1015D00000A2182B106000078F850040240DFF80AB
-:1015E00090AE000D01AE6024318B00FF1560000845
-:1015F0000006C382020020212403000D8FBF0014C7
-:101600008FB0001027BD00180A00189BA383005854
-:1016100033060003240F000254CFFFF702002021FD
-:1016200094A2001C8F85002824190023A4A200D8AE
-:101630008CE8000000081E02307F003F13F90035DF
-:101640003C0A00838CE800188CA600C01106000834
-:10165000000000002405000E0E00189BA385005812
-:101660002407FFFF104700182404FFFF8F85002880
-:1016700090A900C435240020A0A400C48F8C00349D
-:10168000918E000D31CD007FA18D000D8F83004420
-:101690001060001C020020218F8400408C980010F4
-:1016A0000303782B11E0000D2419001802002021FB
-:1016B000A39900580E00189B2410FFFF1050000241
-:1016C0002404FFFF000020218FBF00148FB0001002
-:1016D0000080102103E0000827BD00188C86001050
-:1016E0008F9F00340200202100C31023AFE20010BE
-:1016F000240500010E001997240600010A001BC0F2
-:10170000000020210E001922240500010A001BC040
-:1017100000002021010A5824156AFFD98F8C00345B
-:10172000A0A600EC0A001BADA386004A27BDFFD887
-:10173000AFB000108F90003CAFB20018AFBF0020D8
-:10174000AFB3001CAFB100148E1100103C030800B1
-:101750008C6331B032253FFF00A3102B10400008EE
-:10176000008090218F8600402409FF8090CA000DE0
-:10177000012A4024310700FF14E0000B00116B82A6
-:10178000024020212412000DA39200588FBF002098
-:101790008FB3001C8FB200188FB100148FB00010EF
-:1017A0000A00189B27BD002831AC0003240B000160
-:1017B000558BFFF40240202190CF000D31EE000840
-:1017C00011C000608F9300441660000924020027B6
-:1017D0008E19000C8CD80020173800052402002038
-:1017E0008E0200088CDF0024105F004024020020DD
-:1017F0000E00189BA38200582406FFFF10460033FA
-:101800002404FFFF8F990034240AFFF73C13800E55
-:101810009329000D2404FF803C0D8000012AF82448
-:10182000A33F000D8F9900203C0808008D0831ACC3
-:101830008F83005C972700788F9F0034010310216D
-:1018400030E57FFF000530400046782131F8007F09
-:101850000313602101E47024ADAE002CA5910000BB
-:101860008FEB0028256A0001AFEA00288FE3002CE7
-:101870008E09002C00694021AFE8002C8E07002C57
-:10188000AFE700308E050014AFE5003497E6003A6C
-:1018900024C20001A7E2003A973300783C10080008
-:1018A0008E1031B02663000130717FFF12300027A7
-:1018B000006030218F8F002002402021240500018C
-:1018C0000E001922A5E60078000020218FBF00201D
-:1018D0008FB3001C8FB200188FB100148FB00010AE
-:1018E0000080102103E0000827BD00288E050014A9
-:1018F0002413FFFF10B3001D8F8300288E080018EB
-:101900008C6700C0150700092402000E8E0A00240F
-:101910008CC9002815490005240200218E070028E3
-:101920008CCB002C10EB00132402001F0E00189B20
-:10193000A38200581453FFB32404FFFF0A001C4283
-:101940008FBF00200A001C0A24020024240E8000FD
-:10195000006E682431ACFFFF000C5BC2317100FFE8
-:10196000001180270A001C3B001033C00A001C59DC
-:10197000240200258E05002C10A0FFEC2402002379
-:101980008F8E00208DCD007401A5602B1580FFE7A0
-:10199000240200268CCF001400A7C02101F8202BC0
-:1019A0001080FF998F990034024020210A001C59B1
-:1019B0002402002227BDFFE0AFB000108F90003C52
-:1019C000AFB10014AFBF00188E0500103C03080033
-:1019D0008C6331B00080882130A43FFF0083102B3E
-:1019E000104000078F8600402409FF8090CA000D38
-:1019F000012A4024310700FF14E000098F8B0044C6
-:101A00002410000D02202021A39000588FBF001841
-:101A10008FB100148FB000100A00189B27BD002062
-:101A2000116000070005CB828F8F00288F8EFED0BB
-:101A300095EC007095CD000A11AC00578F850030F1
-:101A4000333800031700001000000000921F00024E
-:101A500013E00041000000008E06002450C0000F7B
-:101A600092040003022020212402000F0E00189B84
-:101A7000A38200582408FFFF144800072404FFFF36
-:101A80000A001CD58FBF001890C7000D30E3000876
-:101A90001060003702202021920400032409000274
-:101AA000308A00FF15490005308500FF8F8B004408
-:101AB0005160003102202021308500FF38B800102D
-:101AC0002CAF00012F0E000102002821022020214E
-:101AD0000E0018BB01EE30252410FFFF1050000E41
-:101AE0002404FFFF8F830044106000170220202190
-:101AF0003C1F08008FFF318C03E3C82B5720000CDC
-:101B00002411002D02202021000028210E00199709
-:101B100024060001000020218FBF00188FB100149F
-:101B20008FB000100080102103E0000827BD0020C6
-:101B30000E00189BA39100581450FFF62404FFFFD9
-:101B40000A001CD58FBF00180E00192224050001C1
-:101B50000A001CD4000020218CC400248E02002422
-:101B60005444FFC1022020210A001CB59204000346
-:101B70000A001CA924020010240D002C0E00189B42
-:101B8000A38D0058240CFFFF104CFFE32404FFFF3B
-:101B90000A001CBC920400032404FFFD0A001CD4AC
-:101BA000AF85005030A500FF2406000124A90001E4
-:101BB00000C9102B1040000C00004021240A000135
-:101BC00000A61823308B000124C60001006A3804E7
-:101BD000000420421160000200C9182B01074025B3
-:101BE0001460FFF800A6182303E00008010010218C
-:101BF00027BDFFD8AFB000188F90003CAFB1001CDC
-:101C0000AFBF00202403FFFF2411002FAFA300105B
-:101C10009206000024050008261000010066202618
-:101C20000E001CF7308400FF00021E003C021EDC88
-:101C300034466F410A001D1F0000102110A000094A
-:101C4000008018212445000130A2FFFF2C45000828
-:101C50000461FFFA000320400086202614A0FFF94B
-:101C6000008018210E001CF7240500208FA300100F
-:101C70002629FFFF313100FF00034202240700FF45
-:101C80001627FFE20102182600035027AFAA00140E
-:101C9000AFAA00100000302127A8001027A70014C9
-:101CA00000E6782391ED000324CE000100C86021F6
-:101CB00031C600FF2CCB00041560FFF9A18D000098
-:101CC0008FA200108FBF00208FB1001C8FB00018B2
-:101CD00003E0000827BD00289383003827BDFFE0FC
-:101CE00024020034AFB10014AFB00010AFBF001C2D
-:101CF000AFB20018008080211062006500A088212A
-:101D000092240004148000488F880028A380002CAF
-:101D10008E2500048D0700C83C0600FF34C3FFFF7A
-:101D200000A3302400E6102B14400050AF8600447E
-:101D30008F870050978A004CAF87003001474023BF
-:101D400010C00034A788004C8F99002030DF0003BA
-:101D5000001F20239332007C309000030206702184
-:101D60000012C082331200010012788001CF682176
-:101D7000310CFFFF018D582B5160005F8F880028C8
-:101D80008F8900248F8200541049007B3C033F015F
-:101D90008E2600003C11250000C3282414B10078D1
-:101DA0008F84003C8F8A003C8F8800288D4B000078
-:101DB000AD0B00788D470010AD0700888F8700506D
-:101DC0008F860044938C002C01276821020628216D
-:101DD000020C1821A383002C950900ACAF8D0024C0
-:101DE00035301000A51000AC1640005024720004DD
-:101DF000AF850050000020218FBF001C8FB200185B
-:101E00008FB100148FB000100080102103E0000893
-:101E100027BD00208F840024AF8000500087402120
-:101E20000A001D8BAF880024241F000CA39F0058BC
-:101E30000E00189B020020212419FFFF1059FFEE0D
-:101E40002404FFFF8F880028A380002C8E25000427
-:101E50008D0700C83C0600FF34C3FFFF00A33024F9
-:101E600000E6102B1040FFB2AF8600440200202194
-:101E700024090019A38900580E00189B2410FFFFA5
-:101E80001050FFDD2404FFFF0A001D5A8F86004416
-:101E90008F8400288F87003C8CF20030908600C42D
-:101EA00030C5001014A000108F8300502C6800056E
-:101EB0001500002600000000908A00C4246BFFFC7F
-:101EC0003149001015200008316400FF8F8D005447
-:101ED0008F8C002411AC0004388F000131EE00011A
-:101EE00015C0002F000000000E001D0A00000000B9
-:101EF0000A001DE2000000008F890024938C002C52
-:101F00000127682102062821020C1821A383002C36
-:101F1000950900ACAF8D002435301000A51000AC41
-:101F20005240FFB4AF85005024720004A392002CED
-:101F3000950F00AC24B80004AF98005035EE200097
-:101F4000A50E00AC0A001D8C000020218C8200DC54
-:101F50001242FF6B0200202124180005A3980058AC
-:101F60000E00189B2412FFFF1452FF652404FFFF8C
-:101F70000A001D8D8FBF001C0A001DCD8F88002810
-:101F800030E500FF0E0017A2000030218F880028E6
-:101F90008F8700508F8900240A001D7F8F860044A0
-:101FA0000E0017CD000000000A001DE20000000036
-:101FB0009383004A27BDFFE024020002AFB200185D
-:101FC000AFB10014AFBF001CAFB00010008088217B
-:101FD000106200B6000090219783004C8F8500505E
-:101FE0003066FFFF00C5202B1480005B938700380C
-:101FF0003C0880009504012010E500528F8A0024DF
-:102000008F84005430A500FF0E0017A224060001A3
-:102010008F82005C3C0B80003C1F4080244E017886
-:1020200031D00078240FFF80021F60253578090029
-:1020300031D9000701CF6824AD6D08000338802135
-:10204000AD6C081002202021020028210E001D4442
-:10205000AF90003C2403FFFF104300332404FFFF34
-:102060008E0C00103C0708008CE731B0920600008F
-:1020700031843FFF0087282B10A0002330CD003F84
-:102080008F99005C000479803C0408008C8431A89E
-:102090002409FF809390004900994021010F2021DD
-:1020A00000897824000F51403C098000309F007F58
-:1020B0003C0B00808F880028308E00783578000136
-:1020C000015F282530860007352709403C031000B2
-:1020D0003C02800C01D8582500C7C82100A3502518
-:1020E00003E2C021360E0001AD2F0804AF99004075
-:1020F000AD2B0814AF980034AD2F0028AD04007448
-:10210000AD2A0830A38E00499383004A24100003AF
-:102110005070002725A3FFE0240C0001106C001C68
-:1021200024060023024020218FBF001C8FB200181C
-:102130008FB100148FB000100080102103E0000860
-:1021400027BD0020314900035520FFAE8F84005485
-:102150000A001E1F8F9000548F840054306500FFCA
-:102160000E0017A224060001938E003824070034C5
-:1021700011C700188F8500509783004C3078FFFFFF
-:1021800000B87023AF8E00500A001E57A780004C85
-:1021900011A6003200000000022020212411000BB3
-:1021A0000E00189BA39100580A001E570040902172
-:1021B0002C7200201240FFF8000310803C0508013B
-:1021C00024A581600045F8218FED000001A00008E2
-:1021D000000000002CB800051700FFE89783004CB2
-:1021E000978A004C3148FFFF00A848232D2B00059B
-:1021F00011600003314400FF24AFFFFC31E400FF15
-:102200008F9000548F99002412190004389F000108
-:1022100033ED000115A00029000000008F85002883
-:1022200090A700C434E30010A0A300C49783004C1F
-:102230008F8500508F8400283078FFFF00B870230E
-:10224000AC8000DCA780004C0A001E57AF8E005007
-:102250002403FFFF11830005000000000E001B7522
-:10226000022020210A001E57004090210E001AFA79
-:10227000022020210A001E57004090210E001C7BE6
-:10228000022020210A001E57004090210E001BD979
-:10229000022020210A001E57004090210E001A51F2
-:1022A000022020210A001E5700409021938500380B
-:1022B0002404FFFD0A001E58AF8500500E0017CD04
-:1022C000000000009783004C8F85005000402021C3
-:1022D0003066FFFF00A660232D8200051040FFA896
-:1022E0003078FFFF8F91002800B87023AE2400DC07
-:1022F000A780004C0A001E57AF8E005027BDFFD0AC
-:10230000AFB20018AFB00010AFBF0028AFB50024C7
-:10231000AFB40020AFB3001CAFB100143C0C800080
-:102320008D880128240FFF803C07800A25100100BA
-:10233000250B0080020F68243205007F016F702496
-:10234000AD8E009000A72821AD8D002490A700EC51
-:102350003169007F3C0A8004012A1821A387004AC2
-:102360009066007C00809021AF83002030C2000284
-:10237000AF88005CAF85002800A01821144000023F
-:102380002404003424040030A38400388C6600CC7C
-:1023900030F100FF24040004AF8600501224000432
-:1023A000A38000588E5300041660001D3C08800076
-:1023B0009387004930F200011240000F8FBF0028C0
-:1023C0008CB800748CA400742419FF80031988242D
-:1023D00000117140308F007F01CF60253C0D20003F
-:1023E000018D582530F500FE3C0A8000AD4B0830C9
-:1023F000A39500498FBF00288FB500248FB400201B
-:102400008FB3001C8FB200188FB100148FB0001072
-:102410002402000127BD003003E00008ACA600CC78
-:102420008E590008951F01208E460010033FC021E1
-:102430003307FFFF30F5000F32B40001AF860024F0
-:102440001680003BA395004835060C0002A610211B
-:1024500000F51823AD030084AF8200548E490004B8
-:102460003128FFFF1100002BA789004C2410FF80AA
-:102470003C1580003C1420000A001F442413FFFE7A
-:1024800090AE00C4020E682431AC00FF1580002A13
-:1024900002402021938400499786004C308F000130
-:1024A00011E0000B026428248F8900288D2300741A
-:1024B0008D280074A3850049007010240002C940D3
-:1024C000311F007F033FC02503148825AEB10830BB
-:1024D00010C000108F85002890A700C40207582460
-:1024E000316A00FF1540FFE6024020210E001DFA70
-:1024F0009791004C1040FFE8938400492405FFFDAC
-:10250000544500058E430020022028210E00177A32
-:10251000024020218E430020307000041600000A83
-:102520002414FFFB8F8500280A001EFA8F860050B6
-:102530000A001F25AF8600540E001A1D000000007F
-:102540000A001F3493840049007498240E001792E7
-:10255000AE5300208F8500280A001EFA8F86005097
-:1025600027BDFFD8AFB3001CAFB10014AFBF002030
-:10257000AFB20018AFB000103C0280008C52014096
-:102580008C4B01483C048000000B8C02322300FF7E
-:10259000317300FF8C8501B804A0FFFE34900180E8
-:1025A000AE1200008C8701442464FFF02406000270
-:1025B0002C830013AE070004A6110008A206000B2E
-:1025C000AE1300241060004F8FBF0020000448802D
-:1025D0003C0A0801254A81E0012A40218D040000BF
-:1025E00000800008000000003C1008008E1031A898
-:1025F00031733FFF001389800212C8212405FF8038
-:1026000003312021264C0100264700803C1F80001A
-:1026100000E51824318F007F30E9007F308A007F89
-:102620003C18800A3C0E80043C0D800C0085102470
-:1026300001853024014D8021AFE6002401F84021BE
-:10264000AFE30090012E9821AFE20028AF90003454
-:10265000AF880028AF9300200E001867016080212A
-:102660003C0380008C6B01B80560FFFE8F8700344F
-:10267000346501808F86002890E3000DACB2000025
-:10268000A4B00006000316000002FE03001F9027FE
-:10269000001227C21080007A24C2007824196082B8
-:1026A000A4B90008A0A00005241F0002A0BF000BD1
-:1026B00000041C008F8B00203C0227000062902544
-:1026C000ACB20010ACA00014ACA00024ACA0002858
-:1026D000ACA0002C8D7300382410FF80ACB3001820
-:1026E00090E4000D02048824322500FF10A00005AC
-:1026F0008FBF002090EC000D3188007FA0E8000D16
-:102700008FBF00208FB3001C8FB200188FB1001450
-:102710008FB000103C0D10003C0A800027BD00283F
-:1027200003E00008AD4D01B8265F01002405FF80DD
-:1027300033F8007F3C06800003E578243C19800ACA
-:1027400003192021ACCF0024908E00C400AE682471
-:1027500031AC00FF1180FFEAAF840028248E00789E
-:1027600095CD00123C0C08008D8C31A831AB3FFF99
-:1027700001924821000B5180012A402101052024AB
-:10278000ACC400283107007F3C06800C00E6202105
-:102790009083000D00A31024304500FF10A0FFD847
-:1027A000AF8400349098000D330F001015E0FFD572
-:1027B0008FBF00200E001867000000003C0380005F
-:1027C0008C7901B80720FFFE00000000AE12000067
-:1027D0008C720144AE120004A611000824110002FC
-:1027E000A211000BAE1300240A001FCF8FBF0020E0
-:1027F0003C1260008E452C083C03F0033462FFFF5E
-:1028000000A2F824AE5F2C088E582C083C1901B0A9
-:1028100003199825AE532C080A001FCF8FBF002044
-:10282000264D010031AF007F3C10800A240EFF804E
-:1028300001F0282101AE60243C0B8000AD6C002427
-:102840001660FFAFAF85002824110003A0B100EC93
-:102850000A001FCF8FBF002026480100310A007FE9
-:102860003C0B800A2409FF80014B30210109202400
-:102870003C078000ACE400240A001FCEAF8600288D
-:10288000944A001232083FFF314C3FFF1588FF8405
-:102890002419608290CF00C4240EFF8001CF482409
-:1028A000312D00FF11A0FF7E00000000240700046E
-:1028B000A0C700EC8F870034241860842406000D24
-:1028C000A4B80008A0A600050A001FB9241F000232
-:1028D0000800330C0800330C080033E8080033BC50
-:1028E000080033A0080032F0080032F0080032F08F
-:1028F0000800331480080100800800808008000070
-:102900005F865437E4AC62CC50103A453662198584
-:10291000BF14C0E81BC27A1E84F4B556094EA6FE49
-:102920007DDA01E7C04D748108007A8808007AB426
-:1029300008007A94080079D008007A9408007AD4C4
-:1029400008007A94080079D0080079D0080079D07E
-:10295000080079D0080079D0080079D0080079D033
-:10296000080079D0080079D0080079D008007AC42E
-:1029700008007AA4080079D0080079D0080079D03E
-:10298000080079D0080079D0080079D0080079D003
-:10299000080079D0080079D0080079D0080079D0F3
-:1029A000080079D008007AA40800809008007F38D9
-:1029B0000800805808007F380800802808007E2022
-:1029C00008007F3808007F3808007F3808007F380B
-:1029D00008007F3808007F3808007F3808007F38FB
-:1029E00008007F3808007F3808007F3808007F38EB
-:0429F00008007F60FC
-:0C29F4000A0001220000000000000000AA
-:102A00000000000D747061352E302E306A313500B3
-:102A100005000001000000000000000000000000B0
-:102A200000000000000000000000000000000000A6
-:102A30000000000000000000000000000000000096
-:102A40000000000000000000000000000000000086
-:102A50000000000000000000000000000000000076
-:102A60000000000000000000000000000000000066
-:102A70000000000000000000000000000000000056
-:102A800010000003000000000000000D0000000D19
-:102A90003C02080024421C203C03080024631FA0C1
-:102AA000AC4000000043202B1480FFFD24420004B2
-:102AB0003C1D080037BD2FFC03A0F0213C1008008E
-:102AC000261004883C1C0800279C1C200E0002E2F3
-:102AD000000000000000000D2402FF8027BDFFE081
-:102AE00000821024AFB00010AF420020AFBF00182A
-:102AF000AFB10014936500043084007F03441821B3
-:102B00003C0200080062182130A5002003608021EB
-:102B10003C080111277B000814A000022466005C19
-:102B200024660058920200049743010492040004B2
-:102B30003047000F3063FFFF3084004000672823D8
-:102B40001080000900004821920200053042000474
-:102B5000104000050000000010A00003000000006D
-:102B600024A5FFFC24090004920200053042000461
-:102B7000104000120000000010A000100000000033
-:102B80009602000200A72021010440252442FFFEF6
-:102B9000A7421016920300042402FF800043102471
-:102BA000304200FF104000033C0204000A000172A2
-:102BB000010240258CC20000AF4210188F420178FC
-:102BC0000440FFFE2402000AA742014096020002D0
-:102BD000240400093042000700021023304200079D
-:102BE000A7420142960200022442FFFEA74201448E
-:102BF000A740014697420104A74201488F420108BD
-:102C000030420020504000012404000192020004E0
-:102C1000304200101440000234830010008018215C
-:102C2000A743014A0000000000000000000000006F
-:102C300000000000AF48100000000000000000008D
-:102C400000000000000000008F4210000441FFFE61
-:102C50003102FFFF10400007000000009202000454
-:102C60003042004014400003000000008F42101862
-:102C7000ACC20000960200063042FFFF2442000270
-:102C800000021043000210400362882196220000D7
-:102C90001120000D3044FFFF00A710218F83003862
-:102CA0008F45101C0002108200021080004310218A
-:102CB000AC45000030A6FFFF0E0002D100052C023B
-:102CC00000402021A6220000920300042402FF807D
-:102CD00000431024304200FF1040001F000000009D
-:102CE00092020005304200021040001B000000006C
-:102CF0009742100C2442FFFEA7421016000000006D
-:102D00003C02040034420030AF42100000000000DA
-:102D10000000000000000000000000008F421000D2
-:102D20000441FFFE000000009742100C8F45101C6C
-:102D30003042FFFF24420030000210820002108067
-:102D4000005B1021AC45000030A6FFFF0E0002D151
-:102D500000052C02A622000096040002248400082C
-:102D60000E0001E73084FFFF974401040E0001F5D7
-:102D70003084FFFF8FBF00188FB100148FB0001098
-:102D80003C02100027BD002003E00008AF4201789C
-:102D90003084FFFF308200078F850024104000023E
-:102DA000248300073064FFF800A4102130421FFF85
-:102DB00003421821247B4000AF850028AF82002405
-:102DC00003E00008AF4200843084FFFF3082000F30
-:102DD0008F85002C8F860034104000022483000F62
-:102DE0003064FFF000A410210046182BAF8500309E
-:102DF0000046202314600002AF82002CAF84002C18
-:102E00008F82002C340480000342182100641821B2
-:102E1000AF83003803E00008AF4200808F820014C7
-:102E2000104000088F8200048F82FFCC1440000500
-:102E30008F8200043C02FFBF3442FFFF0082202447
-:102E40008F82000430430006240200021062000F4B
-:102E50003C0201012C6200035040000524020004E2
-:102E60001060000F3C0200010A00022E000000006A
-:102E700010620005240200061462000C3C020111DD
-:102E80000A000227008210253C0200110082102552
-:102E9000AF421000240200010A00022EAF82000C93
-:102EA00000821025AF421000AF80000C000000002F
-:102EB000000000000000000003E000080000000027
-:102EC0008F82000C10400004000000008F421000B0
-:102ED0000441FFFE0000000003E0000800000000C5
-:102EE0008F8200102443F800000229C224A2FFF0C0
-:102EF0002C63030110600003000210420A00025517
-:102F0000AC8200008F83001800A3102B1440000B2C
-:102F10000000382100A31023244600018F82001CEA
-:102F2000006210212442FFFF0045102B5440000492
-:102F30002402FFFF0A000255AC8600002402FFFFB6
-:102F40000A00025AAC8200008C8200003C03080098
-:102F500024631C5C000211400043382103E0000898
-:102F600000E010213C0908008D291D80000451401B
-:102F70003C19080027391C5C00C0782100806021C2
-:102F8000240EFFFF00003821015940211120003696
-:102F9000000030213C18080027181D983C0D08003F
-:102FA00025AD1D9C000F582B0006118000461021F6
-:102FB000000218C0007810218C4200001582002009
-:102FC000006D20218CA20000544000098D020018E1
-:102FD0003C0208008C421D8424420001AC820000A7
-:102FE0003C010800AC221D840A0002CF0000202111
-:102FF0008F47002000003021000211C01160004AFC
-:10300000AF4200208D08001C3C0900088CA3000082
-:103010000066182100031880007A10210049102151
-:103020008C44000024C600010068182100CF102B3A
-:103030001440FFF6AC6400000A0002CD000000005E
-:103040008C840000008E102B5040000424C6000128
-:103050000080702100C0382124C6000100C9102B57
-:103060001440FFD20006118024020001ACA200002F
-:103070003C0208008C421D7C3C0308008C631D80D0
-:103080000043102B1440002A2404FFFE0159102194
-:103090008C420018104000262404FFFF0007218006
-:1030A0003C0508008CA51D84008720218D06001892
-:1030B000000420C03C02080024421D980082102118
-:1030C0003C03080024631D9CAC4C000024A50001B7
-:1030D000008318213C02080024421DA0AC650000BA
-:1030E000000631C03C010800AC251D84008220216F
-:1030F0008F470020AD04001CAF46002011E0000AFD
-:10310000000030213C020008034228218CA200006C
-:1031100024C6000100CF182BAC82000024A50004B7
-:103120001460FFFA24840004AF470020000020212F
-:1031300003E00008008010213084FFFF30C6FFFF4D
-:1031400000052C0000A628253882FFFF004510212D
-:103150000045282B0045102100021C023042FFFFD1
-:103160000043102100021C023042FFFF00431021E7
-:103170003842FFFF03E000083042FFFF27BDFFC8D1
-:10318000AFBF0030AFB3002CAFB20028AFB1002406
-:10319000AFB000203C0460088C8250002403FF7F05
-:1031A0003C066000004310243442380CAC825000CE
-:1031B0008CC24C1C3C1A8000000216023042000FE8
-:1031C00010400007AF82001C8CC34C1C3C02001F47
-:1031D0003442FC0000621824000319C2AF830018B7
-:1031E0008F420008275B400034420001AF420008D4
-:1031F000AF8000243C02601CAF400080AF400084E0
-:103200008C4500088CC3080834028000034220214A
-:103210002402FFF0006218243C0200803C010800F8
-:10322000AC2204203C025709AF8400381462000429
-:10323000AF850034240200010A000314AF82001499
-:10324000AF8000142403003D240200043C01080068
-:10325000AC221D943C010800AC231D903C010800E9
-:10326000AC231D8C3C010800AC231D883C130800D6
-:1032700026731C5C240400043C02080024421C74D5
-:10328000240300082463FFFFAC400004AC400000AE
-:103290000461FFFC24420020000410C000441021FF
-:1032A0002442003D3C010800AC221D902402000194
-:1032B0003C010800AC221D7C2402FFFF3C010800F9
-:1032C000AC221D983C010800AC201D848F420000F8
-:1032D00038420001304200011440FFFC8F8200148C
-:1032E0001040001600000000974201041040000545
-:1032F0008F830000146000072462FFFF0A00034B65
-:103300002C62000A2C620010504000048F830000E1
-:1033100024620001AF8200008F8300002C62000A4B
-:10332000144000032C6200070A000352AF80FFCC58
-:103330001040000224020001AF82FFCC8F4301083D
-:103340008F44010030622000AF8300041040000869
-:10335000AF8400103C0208008C42042C244200017F
-:103360003C010800AC22042C0A0006D73C024000B5
-:103370003065020014A0000324020F001482030928
-:1033800024020D0097420104104003713C024000EA
-:1033900030624000144000AD8F8200388C44000839
-:1033A0008F4201780440FFFE24020800AF420178FA
-:1033B00024020008A7420140A740014297420104AD
-:1033C0008F8400043051FFFF30820001104000075D
-:1033D000022080212623FFFE240200023070FFFF1E
-:1033E000A74201460A00037FA7430148A7400146C0
-:1033F0003C0208008C42043C1440000D8F830010F6
-:10340000308200201440000224030009240300013C
-:10341000006020218F830010240209005062000107
-:1034200034840004A744014A0A00039A0000000003
-:1034300024020F00146200053082002014400006B0
-:103440002403000D0A000399240300051440000220
-:103450002403000924030001A743014A3C02080099
-:103460008C4204203C0400480E00020A004420253F
-:103470000E000233000000008F82000C1040003E5E
-:10348000000000008F4210003C0300200043102485
-:10349000104000398F820004304200021040003694
-:1034A0000000000097421014144000330000000098
-:1034B000974210088F8800383042FFFF24420006F0
-:1034C000000218820003388000E8302130430001F8
-:1034D0008CC4000010600004304200030000000DA6
-:1034E0000A0003DB00E81021544000103084FFFF85
-:1034F0003C05FFFF00852024008518260003182BBB
-:103500000004102B004310241040000500000000B0
-:10351000000000000000000D000000002400021C5C
-:103520008CC200000A0003DA004520253883FFFF23
-:103530000003182B0004102B00431024104000053A
-:1035400000000000000000000000000D000000006E
-:10355000240002258CC200003444FFFF00E8102143
-:10356000AC4400003C0208008C42043024420001BC
-:103570003C010800AC2204308F6200008F840038C8
-:10358000AF8200088C8300003402FFFF1462000F3A
-:10359000000010213C0508008CA504543C040800E0
-:1035A0008C84045000B0282100B0302B00822021F0
-:1035B000008620213C010800AC2504543C01080091
-:1035C000AC2404500A0006CD240400088C820000BC
-:1035D000304201001040000F000010213C0508009F
-:1035E0008CA5044C3C0408008C84044800B02821BD
-:1035F00000B0302B00822021008620213C010800F1
-:10360000AC25044C3C010800AC2404480A0006CD5B
-:10361000240400083C0508008CA504443C04080070
-:103620008C84044000B0282100B0302B008220217F
-:10363000008620213C010800AC2504443C01080020
-:10364000AC2404400A0006CD240400088F62000860
-:103650008F62000000021602304300F024020030A6
-:1036600010620005240200401062016B8F8200206E
-:103670000A0006D52442000114A000050000000045
-:10368000000000000000000D0000000024000250B7
-:103690008F4201780440FFFE000000000E00023B54
-:1036A00027A4001014400005004080210000000005
-:1036B0000000000D00000000240002578E020000F0
-:1036C0001040000500000000000000000000000D98
-:1036D000000000002400025A8F62000C0443000323
-:1036E000240200010A00055DAE000000AE020000E9
-:1036F0008F8200388C450008A20000078F65000CFF
-:103700008F64000430A3FFFF0004240200852023FF
-:10371000308200FF0043102124420005000288830C
-:103720002E220081A605000A14400005A204000410
-:10373000000000000000000D0000000024000272E4
-:103740003C0708008CE71D808FA800102409FFFFAC
-:103750000000502110E00013000030213C0C080054
-:10376000258C1D9C01802821000018218CA2FFFCC3
-:103770005102002F006C18218CA400002463020861
-:103780000089102B1040000324A502080080482166
-:1037900000C0502124C6000100C7102B5440FFF484
-:1037A0008CA2FFFC3C0508008CA51D803C02080093
-:1037B0008C421D7C3C09080025291C603C03080044
-:1037C00024631D9800A2102B3C0C0800258C1D9C26
-:1037D0003C0408008C841D843C0B0800256B1DA054
-:1037E0001040001A000831400005118000451021EA
-:1037F000000210C000C9382124840001004B302190
-:103800000043182124A50001004C1021AC680000E1
-:10381000ACE600183C010800AC241D84AC44000058
-:103820003C010800AC251D800A0004A88E04001C81
-:103830003C0208008C421D84244200013C01080027
-:10384000AC221D840A0004A7AC620000000A1180AB
-:10385000004A1021000210C0004328218CA3000060
-:10386000004C3821248400010003194000C9302194
-:1038700000691821004B1021ACA80000AC600018B2
-:103880003C010800AC241D84ACC20018ACE400006C
-:103890008E04001C8F8500380E0006E702203021C0
-:1038A0008F6200048F430108A60200083C0210004A
-:1038B0000062182410600008000000009742010414
-:1038C000920300072442FFEC346300023045FFFFFF
-:1038D0000A0004BCA2030007974201042442FFF03F
-:1038E0003045FFFF960600082CC200135440000527
-:1038F000920300079202000734420001A20200076F
-:103900009203000724020001106200052402000354
-:103910001062000B30C7FFFF0A0004DB24E2000244
-:103920008F8200383C04FFFF8C43000C0064182495
-:1039300000651825AC43000C0A0004DA30C7FFFF0D
-:103940008F8200383C04FFFF8C4300100064182471
-:1039500000651825AC43001030C7FFFF24E20002C9
-:1039600000021083A20200058F830038304200FF5E
-:1039700000021080004330218CC500008CC2000082
-:103980002403000400021702144300130000000087
-:10399000974201043C03FFFF00A318243042FFFFBD
-:1039A000004710232442FFFE00622825ACC500001A
-:1039B000920400058E03001C308200FF000210807C
-:1039C00000431021904200003042000F00441021BB
-:1039D0000A000510A20200068CC4000497420104EC
-:1039E0009603000A3085FFFF3042FFFF0047102397
-:1039F0002442FFD60002140000A22825ACC5000412
-:103A00009202000792040005246300280003188333
-:103A10000064182134420004A2030006A202000739
-:103A20008F8200042403FFFB344200020043102471
-:103A3000AF820004920300068E07001C8F860038B8
-:103A400000031880006710218C44000C3C02FFF634
-:103A50003442FFFF0082282400661821AE04000CC7
-:103A6000AC65000C920300068E04000C3C02FF7F44
-:103A70003442FFFF0003188000A228240082202483
-:103A800000671821AE04000CAC65000C9202000621
-:103A9000000210800047102194450012AC45001030
-:103AA000920200060002108000461021AC45001072
-:103AB0008FA200109203000500021140000318803D
-:103AC00000671821005320218C6200048C830018A9
-:103AD0001460000EAE0200143C0308008C631D8CC1
-:103AE000AC8300183C0208008C421D900062102B31
-:103AF00010400019000000003C0208008C421D9498
-:103B0000006210213C010800AC221D8C8E020018BE
-:103B10008F48002000003021000211C01220000B4D
-:103B2000AF4200203C0200080342282100E020218F
-:103B30008C82000024C6000100D1182BACA200002A
-:103B4000248400041460FFFA24A50004AF48002078
-:103B50000A00055E24020010000000000000000DB5
-:103B600000000000240002D424020010A7420140FB
-:103B700024020002A7400142A7400144A742014697
-:103B8000974201043C0400082442FFFEA74201487A
-:103B9000240200010E00020AA742014A9603000A0D
-:103BA0009202000400431021244200023042000728
-:103BB00000021023304200070E000233AE02001054
-:103BC0008F6200003C0308008C630444240400104E
-:103BD000AF820008974201043042FFFF2442FFFEFB
-:103BE00000403821000237C33C0208008C420440E8
-:103BF000006718210067282B00461021004510217E
-:103C00003C010800AC2304443C010800AC22044001
-:103C10000A0006620000000014A000050000000079
-:103C2000000000000000000D00000000240003045C
-:103C30008F4201780440FFFE000000000E00023BAE
-:103C400027A400141440000500408021000000005B
-:103C50000000000D000000002400030B9206000489
-:103C60008FA4001427A50018000630820E00025C05
-:103C7000AFA00018504000068E02000000000000B7
-:103C80000000000D00000000240003118E0200005F
-:103C90005440000692020007000000000000000DE2
-:103CA00000000000240003169202000730420004C6
-:103CB000104000058F8200042403FFFB3442000201
-:103CC00000431024AF8200048F6200040443000903
-:103CD00092020007920200068E03001C8E04000C64
-:103CE0000002108000431021AC44000CAE00000024
-:103CF00092020007304200045440000B920300047B
-:103D0000920300058E0400148E05001C0003188029
-:103D10003C0200010082202100651821AE0400143D
-:103D2000AC640004920300049602000A00621021B1
-:103D300024420005000290838FA200181040000D5D
-:103D4000277100088FA40014000310820242302360
-:103D500027A500180E00025CAFA200185040000614
-:103D60008E05001C000000000000000D0000000097
-:103D70002400033F8E05001C022020210E0006E7D0
-:103D800002403021920400068F6500043C027FFF50
-:103D900000042080009120218C8300043442FFFF26
-:103DA00000A2282400651821AC83000492020007B9
-:103DB00092030004920500053042000410400014F4
-:103DC0009607000830A500FF0005288000B12821D3
-:103DD0008CA40004974201049606000A306300FF99
-:103DE0003042FFFF004310210046102130E3FFFF67
-:103DF000004310232442FFD83084FFFF0002140048
-:103E000000822025ACA400040A00061692030007D5
-:103E100030A500FF0005288000B128218CA40000F7
-:103E200097420104306300FF3042FFFF004310213E
-:103E3000004710233C03FFFF008320243042FFFF94
-:103E400000822025ACA40000920300072402000198
-:103E5000106200060000000024020003106200113E
-:103E6000000000000A0006398E030010974201048A
-:103E7000920300049605000A8E24000C00431021D2
-:103E8000004510212442FFF23C03FFFF0083202461
-:103E90003042FFFF00822025AE24000C0A000639C4
-:103EA0008E03001097420104920300049605000A55
-:103EB0008E24001000431021004510212442FFEE03
-:103EC0003C03FFFF008320243042FFFF00822025B7
-:103ED000AE2400108E0300102402000AA742014005
-:103EE000A74301429603000A920200043C040040EA
-:103EF00000431021A7420144A74001469742010414
-:103F0000A7420148240200010E00020AA742014A0A
-:103F10000E000233000000008F62000092030004D4
-:103F200000002021AF820008974201049606000A93
-:103F30003042FFFF00621821006028213C03080086
-:103F40008C6304443C0208008C4204400065182144
-:103F5000004410210065382B004710213C01080067
-:103F6000AC2304443C010800AC2204409204000449
-:103F7000008620212484000A3084FFFF0E0001E720
-:103F800000000000974401043084FFFF0E0001F59B
-:103F9000000000003C021000AF4201780A0006D485
-:103FA0008F820020148200273062000697420104AD
-:103FB000104000673C0240003062400010400005A5
-:103FC00000000000000000000000000D00000000E4
-:103FD0002400041A8F4201780440FFFE24020800E6
-:103FE000AF42017824020008A7420140A7400142E5
-:103FF0008F82000497430104304200011040000703
-:104000003070FFFF2603FFFE24020002A742014694
-:10401000A74301480A00068C2402000DA740014670
-:104020002402000DA742014A8F6200002404000808
-:10403000AF8200080E0001E7000000000A000666DB
-:1040400002002021104000423C0240009362000028
-:10405000304300F0240200101062000524020070BA
-:10406000106200358F8200200A0006D5244200012C
-:104070008F620000974301043050FFFF3071FFFF53
-:104080008F4201780440FFFE320200070002102335
-:10409000304200072403000A2604FFFEA743014024
-:1040A000A7420142A7440144A7400146A751014845
-:1040B0008F4201083042002014400002240300090E
-:1040C00024030001A743014A0E00020A3C040040F9
-:1040D0000E000233000000003C0708008CE7044497
-:1040E000021110212442FFFE3C0608008CC6044049
-:1040F0000040182100E33821000010218F650000E6
-:1041000000E3402B00C230212604000800C8302103
-:104110003084FFFFAF8500083C010800AC27044451
-:104120003C010800AC2604400E0001E7000000003E
-:104130000A000666022020210E000139000000005E
-:104140008F82002024420001AF8200203C02400008
-:10415000AF4201380A000336000000003084FFFF40
-:1041600030A5FFFF000018211080000700000000AC
-:104170003082000110400002000420420065182136
-:104180000A0006DD0005284003E000080060102159
-:1041900010C0000624C6FFFF8CA2000024A5000466
-:1041A000AC8200000A0006E72484000403E0000853
-:1041B0000000000010A0000824A3FFFFAC86000050
-:1041C00000000000000000002402FFFF2463FFFF46
-:1041D0001462FFFA2484000403E0000800000000D9
-:0441E00000000001DA
-:0C41E4000A00002A00000000000000009B
-:1041F0000000000D747870352E302E306A31350095
-:10420000050000000000000A000001360000EA601E
-:10421000000000000000000000000000000000009E
-:10422000000000000000000000000000000000008E
-:10423000000000000000000000000000000000007E
-:104240000000000000000016000000000000000058
-:10425000000000000000000000000000000000005E
-:10426000000000000000000000000000000000004E
-:1042700000000000000000000000000000001388A3
-:1042800000000000000005DC00000000000000004D
-:1042900010000003000000000000000D0000000DF1
-:1042A0003C020800244239203C03080024633BD42C
-:1042B000AC4000000043202B1480FFFD244200048A
-:1042C0003C1D080037BD7FFC03A0F0213C10080016
-:1042D000261000A83C1C0800279C39200E0004076B
-:1042E000000000000000000D8F86003C3C039000A1
-:1042F0003C0280000086282500A32025AC44002035
-:104300003C0380008C67002004E0FFFE00000000FA
-:1043100003E00008000000000A000041240400013E
-:104320008F85003C3C0480003483000100A31025ED
-:1043300003E00008AC82002003E000080000102128
-:104340003084FFFF30A5FFFF108000070000182118
-:104350003082000110400002000420420065182154
-:104360001480FFFB0005284003E0000800601021D6
-:1043700010C00007000000008CA2000024C6FFFF50
-:1043800024A50004AC82000014C0FFFB24840004B8
-:1043900003E000080000000010A0000824A3FFFFB5
-:1043A000AC86000000000000000000002402FFFFB7
-:1043B0002463FFFF1462FFFA2484000403E0000872
-:1043C0000000000090AA00318FAB00108CAC0040C0
-:1043D0003C0300FF8D680004AD6C00208CAD0044F0
-:1043E00000E060213462FFFFAD6D00248CA700481F
-:1043F0003C09FF000109C024AD6700288CAE004CC9
-:104400000182C82403197825AD6F0004AD6E002C1D
-:104410008CAD0038314A00FFAD6D001C94A900320C
-:104420003128FFFFAD68001090A70030A5600002A2
-:10443000A1600004A167000090A30032306200FF79
-:104440000002198210600005240500011065000EAD
-:104450000000000003E00008A16A00018CD80028D9
-:10446000354A0080AD7800188CCF0014AD6F001471
-:104470008CCE0030AD6E00088CC4002CA16A000107
-:1044800003E00008AD64000C8CCD001CAD6D00187D
-:104490008CC90014AD6900148CC80024AD680008F4
-:1044A0008CC70020AD67000C8CC200148C83007098
-:1044B0000043C82B13200007000000008CC200142A
-:1044C000144CFFE400000000354A008003E00008BF
-:1044D000A16A00018C8200700A0000B70000000091
-:1044E0009089003027BDFFF88FA8001CA3A9000009
-:1044F0008FA300003C0DFF8035A2FFFF8CAC002C89
-:1045000000625824AFAB0000A100000400C0582195
-:10451000A7A000028D06000400A048210167C82161
-:104520008FA50000008050213C18FF7F032C20261F
-:104530003C0E00FF2C8C0001370FFFFF35CDFFFF35
-:104540003C02FF0000AFC82400EDC02400C2782464
-:10455000000C1DC00323682501F87025AD0D000077
-:10456000AD0E00048D240024AFAD0000AD040008A2
-:104570008D2C00202404FFFFAD0C000C9547003269
-:1045800030E6FFFFAD0600109145004830A200FF65
-:10459000000219C2506000018D240034AD040014E3
-:1045A0008D4700388FAA001827BD0008AD0B0028E2
-:1045B000AD0A0024AD07001CAD00002CAD000018B2
-:1045C00003E00008AD00002027BDFFE0AFB20018F7
-:1045D000AFB10014AFB00010AFBF001C9098003016
-:1045E00000C088213C0D00FF330F007FA0CF0000EA
-:1045F000908E003135ACFFFF3C0AFF00A0CE0001D9
-:1046000094A6001EA22000048CAB00148E29000486
-:1046100000A08021016C2824012A402400809021E0
-:1046200001052025A6260002AE2400042605002050
-:10463000262400080E000063240600029247003082
-:10464000260500282624001400071E000003160378
-:1046500024060004044000032403FFFF965900329F
-:104660003323FFFF0E000063AE2300102624002436
-:104670008FBF001C8FB200188FB100148FB00010D4
-:1046800024050003000030210A00006D27BD002032
-:1046900027BDFFD8AFB1001CAFB00018AFBF0020DE
-:1046A00090A900302402000100E050213123003F96
-:1046B00000A040218FB000400080882100C0482128
-:1046C000106200148FA70038240B000500A02021E1
-:1046D00000C02821106B0013020030210E0000F9E9
-:1046E000000000009225007C30A40002108000032E
-:1046F00026030030AE000030260300348FBF0020B8
-:104700008FB1001C8FB000180060102103E000087A
-:1047100027BD00280E000078AFB000100A0001404D
-:10472000000000008FA3003C01002021012028216F
-:1047300001403021AFA300100E0000BFAFB0001445
-:104740000A000140000000003C0580008CA30E1010
-:104750008F840044AC8300208CA20E1803E0000874
-:10476000AC8200243C0580008CA30E148F8400448E
-:10477000AC8300208CA20E1C03E00008AC82002455
-:104780009382000C1040001B2483000F2404FFF0D0
-:104790000064382410E00019978B00109784000EF5
-:1047A0009389000D3C0A601C0A00017B01644023D0
-:1047B00001037021006428231126000231C2FFFF8B
-:1047C00030A2FFFF0047302B50C0000E00E448210C
-:1047D0008D4D000C31A3FFFF00036400000C2C037F
-:1047E00004A1FFF30000302130637FFF0A00017352
-:1047F0002406000103E00008000000009784000E7A
-:1048000000E448213123FFFF3168FFFF0068382BA7
-:1048100054E0FFF8A783000E938A000D11400005B5
-:10482000240F0001006BC023A380000D03E00008EB
-:10483000A798000E006BC023A38F000D03E00008B3
-:10484000A798000E03E000080000000027BDFFE865
-:10485000AFB000103084FFFF3C10800093A8002B05
-:10486000AFBF0014A6040144960A0E1630C600FF1E
-:104870008FA90030A60A0146AE050148A2060152E2
-:10488000A608015AAE0701608FA3002CA6090158A3
-:10489000012020210E000167AE0301543C021000EC
-:1048A000AE0201788FBF00148FB0001003E0000843
-:1048B00027BD00188F8500002484000727BDFFF85E
-:1048C0003084FFF83C06800094CB008A316AFFFFF9
-:1048D000AFAA00008FA90000012540232507FFFF94
-:1048E00030E31FFF0064102B1440FFF700056882BF
-:1048F000000D288034CC400000AC102103E00008FB
-:1049000027BD00088F8200002486000730C5FFF80D
-:1049100000A2182130641FFF03E00008AF840000EC
-:104920008F8500448F8A003C27BDFFB03C04800087
-:10493000AFB70044AFB40038AFB1002CAFBF0048F0
-:10494000AFB60040AFB5003CAFB30034AFB20030FB
-:10495000AFB000288C8701048CA90024AC8A0080A9
-:104960008CA8002000E988230000B821AC880E1034
-:104970008CA600240000A021AC860E188C820E109C
-:10498000AC820E148C830E18AC830E1C122000FB1C
-:104990003C168000936B0008116000F100000000DD
-:1049A000976E001031CDFFFF022D602B158000ECBB
-:1049B0000000000097700010320FFFFFAECF0E0016
-:1049C0003C0580008CB30000327200081240FFFDED
-:1049D0000000000094B50E088CA70E0432A5FFFF5E
-:1049E00030B40001128000E1000000000000000D62
-:1049F00030B9A040241800401338011730B4A0008B
-:104A0000128000DC000000009373000812600008B0
-:104A100000000000976900103122FFFF00E2202B08
-:104A20001080000330A6004010C000D2000000003B
-:104A3000A7850040AF870038936A0008022038211C
-:104A4000AFB10020154000F127B40020AF60000C8A
-:104A50009785004030B14000162000022403001664
-:104A60002403000E24154007A363000AAF75001449
-:104A7000939000428F6F0014321900010019C24058
-:104A800001F84025AF680014978700408F63001439
-:104A900030EE0010006E6825AF6D0014978C00405A
-:104AA000318B000811600165000000008F65001463
-:104AB0003C0B10003C0A800000AB8825AF7100144D
-:104AC00095460E0A3C0981002413000E30C2FFFFF8
-:104AD00000492025AF640004A3730002937F000AFD
-:104AE0003406FFFC27F20004A372000A978D0040F1
-:104AF00031AC200011800157000000003C0780000D
-:104B0000978D004094EC0E0C97910040000D584298
-:104B10003185C000316A00030005130332291000FB
-:104B200001429825000922030264F825001F90C065
-:104B3000A7720012979500409379000A00158182B0
-:104B40003218003C0319782125E8003CA3680009CD
-:104B500094EE0E0C31C33FFFA76300109763001261
-:104B60009367000900E3702125CD000231AC0007F6
-:104B7000000C582331650007A365000B93710009F1
-:104B800097640012976A0010322200FF8F9100385C
-:104B9000979F004000444821012A982102669021F5
-:104BA00033F5004012A000053246FFFF00D1402B34
-:104BB0003C12800011000016000098210226782B7C
-:104BC00015E001368FA700203C1880008F100E14CE
-:104BD0003C058000AF100E108F190E1CAF190E1877
-:104BE000AF060E008CB200003255000812A0FFFD87
-:104BF0000000000094BF0E0800C088210000902132
-:104C0000A79F00408CA60E0424130001AF86003835
-:104C1000976900103135FFFF8E8C00000191202331
-:104C200010800118AE8400009367000814E000D8DB
-:104C3000000000000E0001B4240400108F8E004814
-:104C40003C0332000040282131C600FF00063C0032
-:104C500000E3602525CD0001AF8D0048AC4C00007D
-:104C60009362000997640012937F000A304A00FFA4
-:104C7000308BFFFF014B48210009CC0033F000FFCF
-:104C80000330C025ACB800048F8F004897880040DF
-:104C90003103200010600103ACAF0008976F0012D1
-:104CA00031E8FFFF06400101ACA8000C97900040DE
-:104CB0003205000814A0000226280006262800025B
-:104CC0003C048000948B0E148C850E1C8F670004AE
-:104CD000936A00023164FFFF314900FFAFA9001061
-:104CE0008F7F0014AFA80018AFBF00140E00019A08
-:104CF00000000000240400100E0001C800000000A5
-:104D00008E92000016400005000000008F7900140C
-:104D10002405FFBF0325A024AF7400148F69000C85
-:104D20000135F821AF7F000C9375000816A000082C
-:104D30000000000012600006000000008F6B0014ED
-:104D40003C0CEFFF3584FFFE01645024AF6A001471
-:104D5000A37300088FA700200A0003160220202159
-:104D6000AED10E000A0001F83C05800014E0FF21DE
-:104D700030B9A0400E0001600000A0212E9100017A
-:104D80000237B02512C000178FBF00488F85003C46
-:104D900024170F0010B700CD3C0480008C990178D7
-:104DA0000720FFFE24150F0050B500EB3C048000E7
-:104DB0008C890E14240502403C141000AC89014477
-:104DC0008C9F0E1CAC9F0148A0800152A480015A08
-:104DD000AC800160A4800158AC850154AC9401788A
-:104DE0008FBF00488FB700448FB600408FB5003C9E
-:104DF0008FB400388FB300348FB200308FB1002CE5
-:104E00008FB0002803E0000827BD00508F910038C4
-:104E1000979300403C1280000220A821326A004093
-:104E20001540FF7D00009821976B00108F8500389A
-:104E30003162FFFF104500A2000020210080A02168
-:104E4000108000E500E088211620FED2000000005E
-:104E50000A0002E72E9100013C0380008C7F01785C
-:104E600007E0FFFE240408008F860000AC64017890
-:104E70003C038000946C008A318BFFFF0166502355
-:104E80002549FFFF31281FFF2D0200081440FFF9BC
-:104E9000000000008F8E0048346F40008F83003C7C
-:104EA00000E0A021240D0F0025C70001AF870048B6
-:104EB00000CF3021023488233C08800031D500FF28
-:104EC000106D000524070001939300423272000127
-:104ED0000012824036070001001514003C09010051
-:104EE00000492025ACC400008F9F004830B900362F
-:104EF00030B80008ACDF00041300009000F99825DA
-:104F000095070E0A8F8E00003C03810030EDFFFFF5
-:104F100025CB000801A328253C0C1000316A1FFF97
-:104F2000269200062406000EAD050160026C98254D
-:104F3000A506015AAF8A0000A512015816200008E4
-:104F40003C1080008F99003C24180F005338000259
-:104F500024170001367300400E0001593C108000F8
-:104F60008E1F0E1402402021AE1F01448E120E1C13
-:104F7000AE120148A2150152AE1301540E00016792
-:104F80003C151000AE1501780A000319000000005E
-:104F900093780009976300129368000B330F00FFAA
-:104FA00001E33821310200FF00E2702125D0000A20
-:104FB0003210FFFF0E0001B4020020218F8600484E
-:104FC0003C1941003C07800024CD0001AF8D004812
-:104FD000936C00099764001230C600FF318A00FF0D
-:104FE000308BFFFF014B482100062C00253F0002BB
-:104FF00000BFC02503197825AC4F00008F68000C56
-:1050000094EE0E1401121825AC4300048CE50E1C1E
-:105010008F670004936D000231C4FFFF31AC00FFC5
-:10502000AFAC00108F620014AFB100180E00019AEF
-:10503000AFA200140A0002C502002021AF600004E4
-:10504000A3600002978D004031AC20001580FEABBC
-:1050500000003021A7600012979000409378000A6A
-:105060003C03800032191F000019798301F84021A8
-:1050700025070028A3670009946E0E0C0A00025E43
-:10508000A76E00108F6E001435CD00400E00015940
-:10509000AF6D00140A000291000000000A00031620
-:1050A000000020210641FF01ACA0000C8CB8000CD0
-:1050B0003C198000031990250A0002B2ACB2000C22
-:1050C000000090210A00028D2413000112800005C7
-:1050D0003C0D800095A60E0830D3004012600042BF
-:1050E000000000008C9001780600FFFE0000000028
-:1050F00094920E103C030500240720003258FFFF55
-:1051000003037825AC8F014C8C880E143C0E1000E4
-:10511000AC8801448C820E1CAC820148A0800152F4
-:10512000A480015AAC800160A4800158AC8701546E
-:10513000AC8E01780A0002EE3C0480008F900000E3
-:1051400026920002A5120158260F000831E81FFF21
-:105150000A000356AF880000AC80014C1280001991
-:10516000000000008C8A0E10AC8A01448C830E185B
-:105170003C0C800024160040AC8301488FBF0048DF
-:10518000A18001528FB70044A580015A8FB5003C21
-:10519000AD8001608FB40038A58001588FB3003412
-:1051A000AD9601548FB200308FB600408FB1002C05
-:1051B0008FB000283C04100027BD005003E0000819
-:1051C000AD8401788C8B0E14AC8B01448C830E1C47
-:1051D0000A0003E43C0C80000E0001602E910001E7
-:1051E0000A0002E80237B025000000000000000DB0
-:1051F000000000002400033A0A0003C03C048000C1
-:1052000027BDFFE0AFBF001C3C1F20FF3C07600034
-:105210003C0980002402001037F9FFFDACE23008A1
-:10522000AFB20018AFB10014AFB00010AD390E002E
-:10523000000000000000000000000000000000006E
-:10524000000000003C1800FF3712FFFDAD320E00D9
-:105250003C0B60048D7050002411FF7F3C0E000257
-:105260000211782435EC380C35CD0109ACED4C1821
-:10527000240A0009AD6C50008CE80438AD2A0008FF
-:10528000AD2000148CE54C1C3106FFFF38C42F7193
-:1052900000051E023062000F2486C0B310400007D4
-:1052A000AF8200088CE54C1C3C09001F3528FC002F
-:1052B00000A81824000321C2AF8400048CF1080860
-:1052C0003C0F57092412F0000232702435F0001010
-:1052D00001D0602601CF68262DAA00012D8B000188
-:1052E000014B382550E00009A380000C3C02601CF3
-:1052F0008C590008241F0001A39F000C33387C0048
-:10530000A7980010A780000EA380000DAF80004872
-:1053100014C00003AF8000003C066000ACC0442C09
-:105320000E0004B63C1080000E000E0E00000000BF
-:105330003C110800263139883C12080026523A08F0
-:105340008E05000038A30001306400011480FFFCCA
-:10535000000000008E0601003C0C800A240AFF8039
-:1053600024C7024030EB007F016C482100EA402452
-:10537000AE060020AF890044AE0800243C03800044
-:10538000AF86003C8C6D017805A0FFFE2419080053
-:10539000AC79017890780108A3980042938F00427D
-:1053A00031EE000111C0000F240D0D0024C2F800E1
-:1053B0002C5F030113E0001C000629C224A3FFF0A8
-:1053C00000032042000431400E0001CF00D1D8215B
-:1053D0003C0440003C068000ACC401380A0004577D
-:1053E0000000000010CD0026240E0F0010CE002A71
-:1053F0003C028008345F008093F90000240F0050C5
-:10540000333800FF170FFFF33C0440000E00092F54
-:10541000000000003C0440003C068000ACC40138A1
-:105420000A000457000000008F83000400A3402BF3
-:105430001500000B8F8B0008006B50212547FFFFE4
-:1054400000E5482B1520000600A36023000C29402E
-:105450000E0001CF00B2D8210A00047C3C044000B9
-:10546000000000000000000D00000000240003AD5B
-:105470000E0001CF000000000A00047C3C04400044
-:105480003C1B0800277B3B080E0001CF00000000FA
-:105490000A00047C3C0440003C1B0800277B3B289E
-:1054A0000E0001CF000000000A00047C3C04400014
-:1054B000000411C003E00008244202403C0408003C
-:1054C00024843B6C2405001A0A00006D0000302182
-:1054D00027BDFFE0AFBF001CAFB20018AFB1001492
-:1054E000AFB000103C108000920B01092412FF8025
-:1054F0000E0004B33164007F8F91003C00515021B5
-:1055000001524024AE080024920301090E0004B3A6
-:105510003064007F24060080240700C0240400407B
-:10552000AE000810AE040814AE060818AE07081C3A
-:10553000920C01090051F82133F8007F3C19800AD0
-:10554000031910213184007F0E0004B3AF820044A0
-:105550008E1101003C0C008035850001022278216B
-:1055600001F24824AE0908048E0E010035980002AD
-:105570003609090001C2682131AB00780165502568
-:10558000AE0A08208E0501008E080100360509804C
-:10559000010218212464004000923024AE0608085D
-:1055A0008E07010000E2F82127F90040333200782D
-:1055B00002588825AE1108248E040100952F000C96
-:1055C0008FBF001C8FB2001831EEFFFF000E69C0C4
-:1055D000AE0D0800AE0C0828952B000C8FB10014FE
-:1055E000316AFFFF000A41C0AE08002C8CA30050B6
-:1055F0008FB000108CA2003C8D2400048CA6001CEF
-:105600008CA7003827BD0020AF830060AF82005018
-:10561000AF84004CAF86005803E00008AF87005C01
-:105620003C098000352309009128010B906A001184
-:105630002402002800804821314700FF00A070218B
-:1056400000C068213108004010E20002340C86DD01
-:10565000240C08003C0A800035420A9A9447000056
-:10566000354B0A9C35460AA030F9FFFFAD390000E2
-:105670008D780000354B0A8024040001AD38000409
-:105680008CCF0000AD2F00089165001930A30003F6
-:105690001064008E28640002148000AD240500020E
-:1056A0001065009C240F0003106F00B235450AA45A
-:1056B000240A0800118A0047000000005100003C45
-:1056C0003C0B80003C04800034830900906700128A
-:1056D00030E200FF004D7821000FC8802724000130
-:1056E0003C0A8000354F090091E50019354C0980CE
-:1056F0008D87002830A300FF0003150000475825C0
-:105700000004C4003C19600001793025370806FF09
-:10571000AD260000AD2800048DEA002C25280028C5
-:10572000AD2A00088DEC0030AD2C000C8DE5003466
-:10573000AD2500108DE40038AD2400148DE3001C6D
-:10574000AD2300188DE700203C038000AD27001C2E
-:105750008DE20024AD2200208DF900283462093C3E
-:10576000AD3900248C450000AD0E000434790900E9
-:10577000AD0500008C67010C25020014AD07000880
-:10578000932B00123C04080090843B90AD00001065
-:10579000317800FF030D302100064F0000047C002B
-:1057A000012F702535CDFFFF03E00008AD0D000C83
-:1057B00035780900930600123C05080094A53B804B
-:1057C00030C800FF010D5021000A60800A00053F2B
-:1057D000018520211500005A000000003C08080047
-:1057E00095083B863C06080094C63B8001061021C4
-:1057F0003C0B80003579090093380011932A001979
-:1058000035660A80330800FF94CF002A00086082C2
-:10581000314500FF978A0054000C1E00000524004B
-:105820003047FFFF006410250047C02501EA302102
-:105830003C0B4000030B402500066400AD2800002F
-:10584000AD2C0004932500183C0300062528001405
-:1058500000053E0000E31025AD2200088F24002C37
-:105860003C0380003462093CAD24000C8F38001CDE
-:10587000254F000131EB7FFFAD3800108C45000053
-:10588000AD0E000434790900AD0500008C67010CF1
-:10589000A78B005425020014AD070008932B0012BB
-:1058A0003C04080090843B90AD000010317800FF6C
-:1058B000030D302100064F0000047C00012F7025ED
-:1058C00035CDFFFF03E00008AD0D000C3C020800E1
-:1058D00094423B8A3C05080094A53B8035440AA4C9
-:1058E0003C07080094E73B7C948B00000045C821EE
-:1058F0000327C023000B1C002706FFF2006650257B
-:10590000AD2A000CAD200010AD2C00140A000533A8
-:1059100025290018354F0AA495E500009564002854
-:105920000005140000043C003459810000EC5825A7
-:10593000AD39000CAD2B00100A00053325290014E9
-:105940003C0C0800958C3B860A00058325820001EB
-:105950005460FF58240A080035580AA4970600002E
-:1059600000061C00006C5025AD2A000C0A0005330F
-:10597000252900103C03080094633B8A3C0708007B
-:1059800094E73B803C0F080095EF3B7C94A400001B
-:105990009579002800671021004F582300041C004F
-:1059A000001934002578FFEE00D87825346A81008C
-:1059B000AD2A000CAD2F0010AD200014AD2C001846
-:1059C0000A0005332529001C03E00008240207D043
-:1059D00027BDFFE0AFB20018AFB10014AFB00010A8
-:1059E000AFBF001C0E00004D008088218F88005042
-:1059F0008F87004C3C05800834B2008001112821BB
-:105A00003C10800024020080240300C000A7202353
-:105A1000AE0208183C068008AE03081C188000047B
-:105A2000AF850050ACC500048CC90004AF89004CA0
-:105A300012200009360409800E0005F9000000005C
-:105A4000924C00278E0B007401825004014B3021D0
-:105A5000AE46000C360409808C8E001C8F8F0058D7
-:105A600001CF682319A000048FBF001C8C90001C7C
-:105A7000AF9000588FBF001C8FB200188FB1001478
-:105A80008FB000100A00004F27BD00208F860060F5
-:105A90008F8300508F82004C3C05800834A4008026
-:105AA000AC860050AC83003C03E00008ACA20004CC
-:105AB0003C0308008C63005427BDFFF8308400FFCE
-:105AC0002462000130A500FF3C010800AC22005414
-:105AD00030C600FF3C0780008CE801780500FFFE1F
-:105AE0003C0A7FFFA3A400038FA400003549FFFFF9
-:105AF00000891824000647C000681025AFA20000E6
-:105B000090F9010AA3A000023C1880FFA3B900018C
-:105B10008FAE000030AD007F370FFFFF01CF58245C
-:105B2000000D66003C090020016C50253526200040
-:105B30002405FF803C04100027BD0008ACEA014C9E
-:105B4000ACE60154A4E00158A0E5015203E00008CE
-:105B5000ACE40178308800FF3C03800030A400FFF3
-:105B60008C6201780440FFFE000000003C038000CE
-:105B700034660A008CCA0020346709800004482B70
-:105B8000AC6A01448CC5002400091540AC6501488D
-:105B9000A068015090E4004CA064016D03E000088F
-:105BA000A460015827BDFFE8308400FFAFBF00109C
-:105BB0000E00065C30A500FF8F8300508FBF0010E1
-:105BC0003C058000344600402404FF903C02100055
-:105BD00027BD0018ACA3014CA0A40152ACA60154EF
-:105BE00003E00008ACA2017827BDFFE03C08800874
-:105BF000AFBF001CAFB20018AFB10014AFB00010BF
-:105C0000351000808E0600183C078000309200FF9F
-:105C100000C72025AE0400180E00004D30B100FF73
-:105C200092030005346200080E00004FA202000536
-:105C3000024020210E00067002202821024020216F
-:105C40008FBF001C8FB200188FB100148FB00010EE
-:105C500024050005240600010A00063327BD0020A4
-:105C60003C05800034A309809066000830C200081B
-:105C70001040000F3C0A01013549080AAC890000B8
-:105C80008CA80074AC8800043C07080090E73B90A7
-:105C900030E5001050A00008AC8000083C0D8008E2
-:105CA00035AC00808D8B0058AC8B00082484000C30
-:105CB00003E00008008010210A0006B32484000CD1
-:105CC00027BDFFE83C088000AFB00010AFBF001454
-:105CD0003506098090C7000924020006350909002D
-:105CE00030E300FF0080802100A06021240B00042D
-:105CF000106200792407000294CF005C3C0E02047D
-:105D000031EDFFFF01AE5025AE0A000090C500083E
-:105D100030A40020108000080000000090C2004E57
-:105D20003C1F010337F90300305800FF03193025E9
-:105D3000240B0008AE0600049139001191260012D0
-:105D400091240011333800FF0018708230CF00FF1B
-:105D500001CF5021014C6821308800FF31AAFFFF9C
-:105D600039030028000A28801460002B0205402314
-:105D7000912400123C0E800035D90980308500FF47
-:105D800000AC182100031080004BF821001F840094
-:105D9000360906FFAD09000435C909009126001136
-:105DA000912F0012000BC0828F2B003431ED00FFC9
-:105DB0008DC4010C01AC282100B810210164F82326
-:105DC0000007840000021F000070C82533E9FFFFB0
-:105DD00030CF00FC032970250158202101E86821FB
-:105DE00000045080ADAE000C0E00004D010A802171
-:105DF0003C078008240C000434EB00800E00004FA8
-:105E0000A16C0009020010218FBF00148FB0001098
-:105E100003E0000827BD0018912500119123001907
-:105E20003C18080097183B8630A200FF0002F88259
-:105E3000307000FF001FCE0000104C0003293025F9
-:105E400000D870253C0F400001CF68253C0E800033
-:105E5000AD0D000035C9090091260011912F0012E7
-:105E600035D90980000BC08231ED00FF8F2B003443
-:105E70008DC4010C01AC282100B810210164F82365
-:105E80000007840000021F000070C82533E9FFFFEF
-:105E900030CF00FC032970250158202101E868213A
-:105EA00000045080ADAE000C0E00004D010A8021B0
-:105EB0003C078008240C000434EB00800E00004FE7
-:105EC000A16C0009020010218FBF00148FB00010D8
-:105ED00003E0000827BD00180A0006C524070012C9
-:105EE00027BDFFD0AFB60028AFB50024AFB4002067
-:105EF000AFB10014AFBF002CAFB3001CAFB200189D
-:105F0000AFB000103C06800090C3010B309400FF3E
-:105F100030B500FF306200300000B0211040009D1D
-:105F20000000882134C409809088000800083E00E1
-:105F300000072E0304A000C4240400048F8700502F
-:105F40003C010800A0243B903C0C8000AD80004840
-:105F50003C038000906D010B31A5002010A00007CC
-:105F60003C0B8000347209809250000800107E00C3
-:105F7000000F760305C000C93C1980089169010B28
-:105F8000356A098091480008312400400004102B34
-:105F900031030008241200031460000200E2982379
-:105FA000000090213C108000360E0A80360809005F
-:105FB00095C7002C910300119102001291C50018A1
-:105FC000307800FF305F00FF025FC8210019788041
-:105FD00091CC001801F8682101B1302130B100FFE7
-:105FE00000D11821A78700543C010800A4263B8655
-:105FF0003C010800A4233B8815800002000000003B
-:106000000000000D9204010B3065FFFF3C01080009
-:10601000A4233B8A308900403C010800A4203B8037
-:106020003C010800A4203B7C1120000224A4000AAB
-:1060300024A4000B3091FFFF0E0001B402202021A8
-:106040009219010B3C0E080095CE3B8A3C0D0800CE
-:1060500091AD3B910019C182330F000101CF28217E
-:10606000000D340024A7000200C758253C0C110085
-:10607000016C5025AC4A000024440008026028212D
-:10608000024030210E00050FAC4000040E00069FB8
-:106090000040202116C00068004020219212010B10
-:1060A0003256004012C000053C0200FF8C930000F5
-:1060B000345FFFFF027F8024AC9000000E0001C817
-:1060C000022020213C03080090633B9030710003C4
-:1060D000122000163C1080088F8C00503C0B80086A
-:1060E00035640080258A0001AC8A003C3C058008AC
-:1060F0008CA9000401402021012A4023190000023C
-:10610000AF8A00508CA400040E0005F9ACA4000472
-:106110003C0E80008DCD00743C05800834A60080C4
-:10612000004D3821ACC7000C3C10800836120080AE
-:106130000280202102A02821A240006B0E00065CF4
-:106140003C1480008F9600503C151000AE96014C18
-:106150008F980048344F00068FBF002C271900018C
-:10616000AF9900488FB60028A29801528FB3001C47
-:10617000AE8F01548FB20018AE9501788FB1001424
-:106180008FB500248FB400208FB0001003E000080A
-:1061900027BD003034C30980906F0008000F7600DF
-:1061A000000E6E0305A0003334DF090093F8001BD6
-:1061B000241900103C010800A0393B903313000261
-:1061C0001260FF638F8700508F82005C1447FF616D
-:1061D0003C0380000E00004D000000003C048008DD
-:1061E0003485008090A8000924070016310300FFC1
-:1061F0001067000D0000000090AB00093C0608008D
-:1062000090C63B9024090008316400FF34CA0001A5
-:106210003C010800A02A3B901089002F240C000AA2
-:10622000108C00282402000C0E00004F000000001B
-:106230000A00075B8F8700500E0006B70240282136
-:106240000A0007AE004020213C0B8008356A008020
-:106250008D4700548CC9010C1120FF39AF870050C5
-:10626000240600143C010800A0263B900A00075AAF
-:106270003C0C800090710008241200023C010800D0
-:10628000A0323B90323000201200000B2416000197
-:106290008F8700500A00075B241100083733008005
-:1062A0008E7F0038AF3F00048F380004AE78003C8A
-:1062B0000A0007663C0B80008F8700500A00075BCE
-:1062C00024110004A0A200090E00004F00000000ED
-:1062D0000A00075B8F870050240200140A00083967
-:1062E000A0A2000927BDFFE8AFBF0014AFB00010A7
-:1062F0003C10800092020109240500010E00065C9A
-:10630000304400FF3C1F800893F8000E37E3008004
-:1063100093F9000F906E002693E9000A332F00FFD7
-:1063200000186600000F6C0031CB00FF018D502576
-:10633000000B320001463825312800FF344560004B
-:1063400000E820252402FF813C031000AE04014C2C
-:106350008FBF0014AE050154A2020152AE030178B2
-:106360008FB0001003E0000827BD001827BDFFE82C
-:10637000308400FFAFBF00100E00065C30A500FFA8
-:10638000344600403C0480002405FF92AC86015452
-:10639000A08501528F8300508FBF00103C02100077
-:1063A00027BD0018AC83014C03E00008AC820178E3
-:1063B00027BDFFD8AFB20018AFB10014AFB00010C6
-:1063C000AFBF0020AFB3001C3C07800090E2010982
-:1063D000308600FF30B000FF000618C23204000211
-:1063E0003071000114800007305200FF3C09800822
-:1063F00035330080926800053105000810A0000CBC
-:1064000030CA0010024020210E00068102202821FF
-:10641000240200018FBF00208FB3001C8FB2001830
-:106420008FB100148FB0001003E0000827BD0028D2
-:106430001540003034E50A008CB900248CB80008FF
-:1064400013380047000040213C0E800835D30080FF
-:10645000926D0068240B000231AC00FF118B0080AC
-:106460003C068000927F004C90C40109509F0004BC
-:106470003213007C11000067000000003213007C22
-:106480001660005A0240202116200008320C00013C
-:106490003C07800034EB0A008D6500248CE8010481
-:1064A00014A8FFDC00001021320C00011180000D47
-:1064B000024020213C1080008E0E010C8F8D006068
-:1064C00011CD0008000000000E00073F0220282127
-:1064D0008E0F010C3C18800837100080AE0F005062
-:1064E000024020210E000670022028210A00088C9C
-:1064F000240200013C0708008CE7006424E6000148
-:106500003C010800AC2600641600000D00000000ED
-:10651000022028210E00067002402021926F0068A0
-:10652000240D000231EE00FF11CD00220240202197
-:106530000E000840000000000A00088C2402000140
-:106540000E00004124040001926C0025020C582525
-:106550000E00004FA26B00250A0008CC0220282163
-:106560008E6300188CE401048CBF00240003160223
-:10657000149FFFB53045007F9269004C264400010E
-:106580003093007F12650040312300FF1464FFAF99
-:106590003C0E8008264800013111007F310200FFC7
-:1065A0001225000B24080001004090210A000899E0
-:1065B00024110001240500040E0006332406000106
-:1065C0000E000840000000000A00088C24020001B0
-:1065D0002407FF800247282400A79026324200FFAC
-:1065E000004090210A000899241100010E00073F85
-:1065F000022028213206003010C0FFA33210008292
-:10660000024020210E000681022028210A00088C69
-:10661000240200018E63001802402021022028215C
-:10662000006610250E000862AE6200189264004CED
-:1066300024050003240600010E000633308400FF09
-:106640000E00004124040001926A0025020A482538
-:106650000E00004FA26900250A00088C24020001E8
-:106660008E7800183C1980000240202103197825FB
-:10667000022028210E000670AE6F00189264004CB4
-:106680000A000914240500043246008038CA00803C
-:10669000146AFF6E3C0E80080A0008ED26480001CF
-:1066A00027BDFFC0AFB000183C108000AFBF00385E
-:1066B000AFB70034AFB60030AFB5002CAFB4002890
-:1066C000AFB30024AFB200200E0004BBAFB1001C7A
-:1066D000920401089205010B308400FF0E0008733C
-:1066E00030A500FF144000E58FBF00383C0980084A
-:1066F00035280080A100006B3607098090E6000075
-:10670000240200503C17080026F73B4830C300FF26
-:106710003C13080026733B58106200033C108000B5
-:106720000000B82100009821241F001036110A0033
-:10673000361409808E1601048F8D00508E38002487
-:1067400036190A808E9200203C010800A03F3B9041
-:10675000972C002C8EF50000932B0018024D70230F
-:1067600002D878233C010800AC2F3B6C3C010800A8
-:10677000AC2E3B703C010800AC2D3B94A78C005420
-:1067800002A0F809317200FF304A0002154000E80B
-:106790003045000110A000C300000000928A0008EC
-:1067A0003150000816000002241400030000A0214C
-:1067B0003C06800034C4090034C30A008C6E0024F7
-:1067C00090850011908200129099001130B800FF5E
-:1067D000305100FF0291F821001FB080332F00FFDD
-:1067E00002D85821024FA82126AC0010017268215E
-:1067F0003C1580003C010800AC2E3B983C01080091
-:10680000A42D3B883C010800A42C3B843C010800DB
-:10681000A42B3B8636B609808F8700508F8900589D
-:106820008ED20020240800060127302302472823A7
-:106830003C010800AC283B8C04C000B5000090214E
-:1068400004A000B300C5802B120000B500000000BA
-:106850003C010800AC263B708E7100000220F80954
-:1068600000000000304A0002154000740040802102
-:10687000304B0001556000118E7100043C0D080082
-:106880008DAD3B743C0EC0003C04800001AE602521
-:10689000AEAC0E008C980000330F000811E0FFFD35
-:1068A00000000000949F0E0824120001A79F0040E2
-:1068B0008C990E04AF9900388E7100040220F809FB
-:1068C000000000000202802532020002144000B4E1
-:1068D000000000003C08080095083B7C3C110800C3
-:1068E00096313B883C09080095293B7E3C03080013
-:1068F0008C633B74011168213C1F08008FFF3B989B
-:106900003C07080094E73B923C11800001A920213C
-:106910008E38010C006828212499000200A77021FC
-:1069200003E37821AF9800603C010800AC2F3B984E
-:106930003C010800A42E3B803C010800A42D3B8AAA
-:106940000E0001B43324FFFF8F8C0048004020214B
-:106950003C010800A02C3B918E620008258B0001B1
-:10696000AF8B00480040F809000000008F85005000
-:10697000028030210E00050F004020210E00069FEE
-:10698000004020218E6A000C0140F80900402021BF
-:106990003C08080095083B8A3C09080095293B7E85
-:1069A0000109382124E600020E0001C830C4FFFFAF
-:1069B0003C0408008C843B6C3C0308008C633B74F3
-:1069C000008328233C010800AC253B6C14A0000682
-:1069D000000000003C0A08008D4A3B8C3546004010
-:1069E0003C010800AC263B8C124000438F8C0044D5
-:1069F0008E2B0E108F920044AE4B00208E220E186C
-:106A0000AE4200243C04080094843B800E0005FB49
-:106A1000000000008F9900508E7800103C010800A3
-:106A2000AC393B940300F809000000003C0F08005B
-:106A30008DEF3B6C15E0FF798F87005097940054E1
-:106A40003C13800E321501000E00062AA674002C9D
-:106A500016A00046320300105460004D8EE500047D
-:106A60003207004054E0001D8EF000088EE4000C58
-:106A70000080F809000000008FBF00388FB7003495
-:106A80008FB600308FB5002C8FB400288FB3002450
-:106A90008FB200208FB1001C8FB0001803E00008F7
-:106AA00027BD0040920901098F88003C00093E0083
-:106AB00000E83025AE0600808E2300208E240024BE
-:106AC000AFA30010AE030E148FA20010AE020E1082
-:106AD000AE040E1C0A00096EAE040E180200F8097E
-:106AE000000000008EE4000C0080F80900000000A7
-:106AF0000A000A268FBF0038240E0001240D000171
-:106B0000A5800020A58E00220A000A08AD8D002471
-:106B10003C010800AC203B700A00099E8E71000009
-:106B20003C010800AC253B700A00099E8E710000F4
-:106B300092110109000028210E000670322400FF86
-:106B40008FBF00388FB700348FB600308FB5002C60
-:106B50008FB400288FB300248FB200208FB1001CA7
-:106B60008FB0001803E0000827BD00403C1F8000E4
-:106B700093F60109000028210E00073F32C400FFF0
-:106B8000320300105060FFB7320700408EE500046A
-:106B900000A0F809000000000A000A2032070040A7
-:106BA0005240FFA7979400548EB60E148F93004462
-:106BB000AE7600208EB40E1CAE7400240A000A17B4
-:106BC000979400548F8200140004218003E0000891
-:106BD000008210213C07800834E200809043006965
-:106BE00000804021106000093C0401003C070800BF
-:106BF0008CE73B948F83003000E32023048000085F
-:106C00009389001C14E300030100202103E0000825
-:106C1000008010213C04010003E0000800801021E6
-:106C20001120000B006738233C0D800035AC098033
-:106C3000918B007C316A000211400020240900344D
-:106C400000E9702B15C0FFF10100202100E9382375
-:106C50002403FFFC00A3C82400E3C02400F9782B20
-:106C600015E0FFEA0308202130C4000300041023CC
-:106C700014C00014304900030000302100A978211D
-:106C800001E6702100EE682B11A0FFE03C0401003A
-:106C90002D3800010006C82B0105482103193824AE
-:106CA00014E0FFDA2524FFFC2402FFFC00A21824D4
-:106CB0000068202103E00008008010210A000A97E4
-:106CC000240900303C0C80003586098090CB007C84
-:106CD000316A00041540FFE9240600040A000AA6F0
-:106CE000000030213C0308008C63005C8F82001898
-:106CF00027BDFFE8AFBF001410620005AFB0001061
-:106D0000000329C024A40280AF840014AF830018BC
-:106D10003C10800036030A00946500320E000A78A9
-:106D200030A43FFF8E0401003C180080370F0003A1
-:106D30000082C8212402FF80032260243329007FBF
-:106D4000000CF94003E94025332E00783C0D10007B
-:106D5000010D502501CF5825AE0C002836080980BA
-:106D6000AE0C080CAE0B082CAE0A0830910300697B
-:106D70003C06800C0126382110600006AF870034E5
-:106D80008D09003C8D06006C0126382318E0007F39
-:106D9000000000003C0C8008358B00803C0A80001D
-:106DA000A1600069355009808E0200383C068000E1
-:106DB00034C50A0090AD003C31A800201100001934
-:106DC000AF820030240E00013C19800037300A00E9
-:106DD000A38E001CAF8000248E0400248F85002425
-:106DE00024180008AF800020AF8000283C01080074
-:106DF000A4383B7E3C010800A4203B920E000A7C94
-:106E000000003021920F003C8FBF00148FB00010A3
-:106E1000000F7142AF82002C27BD001803E000086C
-:106E200031C2000190B90032240F0001333800FF55
-:106E300000182182108F003F241F0002109F006263
-:106E400034C20AC03C03800034640A008C990024D8
-:106E50001720001D3466090090830030241F0005B0
-:106E60003062003F105F004C240500018F86002037
-:106E7000A385001CAF860028AF8600243C19800043
-:106E800037300A008E0400248F850024241800085F
-:106E90003C010800A4383B7E3C010800A4203B9242
-:106EA0000E000A7C00000000920F003C8FBF00140F
-:106EB0008FB00010000F7142AF82002C27BD001868
-:106EC00003E0000831C200018C8800088C8D00248A
-:106ED0008CCB00643C19800037300A00AF8B002453
-:106EE000A380001C8E0400248F8600208F85002440
-:106EF000010D602324180008AF8C00283C01080015
-:106F0000A4383B7E3C010800A4203B920E000A7C82
-:106F100000000000920F003C8FBF00148FB00010E3
-:106F2000000F7142AF82002C27BD001803E000085B
-:106F300031C2000190A7003030E3003F50640028C8
-:106F400034C50AC08CAA00241540002234C80900A8
-:106F50008CAB00483C0C7FFF3585FFFF016510249A
-:106F60003C188000AF820020370509008F8E00207A
-:106F70008CAF006001CF682B15A0000201C020215A
-:106F80008CA400600A000B18AF8400208D02006CF6
-:106F90000A000AF33C0680008C8900488F86002096
-:106FA0003C0A7FFF3550FFFF013038243C04800845
-:106FB00024050001AF870028AC80006CA385001C6D
-:106FC0000A000B26AF8600248C4400140A000B181C
-:106FD000AF8400208D0200680A000B603C1880001E
-:106FE00034C409808C8600708CB0001400D0482B0B
-:106FF00011200004000000008C8200700A000B6069
-:107000003C1880008CA200140A000B603C18800021
-:107010008F85002427BDFFE0AFBF0018AFB100147B
-:1070200014A00008AFB000103C04800034870A00B0
-:1070300090E600302402000530C3003F106200BE1D
-:10704000348409008F91002000A080213C0480003E
-:10705000348E0A008DCD00043C0608008CC63B70BF
-:1070600031A73FFF00E6602B5580000100E0302192
-:10707000938F001C11E0007600D0102B349909800A
-:107080009338007C3304000210800077240300341E
-:1070900000C3F82B17E000DD00C3302300D0102B15
-:1070A0003C010800A4233B7C1440006D0200182121
-:1070B0003C0408008C843B6C0064282B54A0000125
-:1070C000006020213C05800034A90A009128003C82
-:1070D0003C010800AC243B74310300201460000222
-:1070E000000048218CA90E188F88002C0128502BF5
-:1070F0001140005F000000003C0508008CA53B74B7
-:1071000000A96021010C582B1160005C00B0682BB5
-:107110000109382300E028213C010800AC273B741A
-:10712000120000032403FFFC10B00093322B000375
-:1071300000A310243C010800A4203B923C0108005D
-:10714000AC223B74004028218F84002412040006E6
-:107150003C0A80088D4B006C02002021AF9100207A
-:1071600025700001AD50006C8F8C002800858823AD
-:10717000AF91002401852023AF8400281220000253
-:1071800024070018240700103C0F800835E6008013
-:1071900090CE00683C010800A0273B902407000126
-:1071A00031CD00FF11A7004A000000001480001834
-:1071B000000028213C0C800091850109359109804F
-:1071C0008E2B001830A500FF24A30001000B8602BF
-:1071D0003206007F306A007F114600852407FF8059
-:1071E0003C04800834890080A123004C3C0808003E
-:1071F0008D083B8C240F00023C010800A02F3BD1DE
-:10720000350E00083C010800AC2E3B8C2405001014
-:107210003C028000345F0A0093F9003C33380020C0
-:107220001300000500A02021240300013C010800F8
-:10723000AC233B7434A400018FBF00188FB100143D
-:107240008FB000100080102103E0000827BD00204F
-:107250003C010800A4203B7C1040FF95020018214F
-:107260000A000BB300C018210A000BAB2403003046
-:107270003C0508008CA53B7400B0682B11A0FFA84A
-:10728000000000003C04080094843B7C00857821C9
-:1072900001E7702B11C000242CA300043C1F6000E8
-:1072A0008FF954043338003F1300001F0000000022
-:1072B0003C0208008C4200A41040FFDF240400427E
-:1072C00014A000198FBF00180A000C16000000005F
-:1072D0001528FFB6000000008CC300183C19800080
-:1072E000241F000200791025ACC2001837380A00AC
-:1072F000A0DF00689309003C2404000400A01021D2
-:10730000312800203C010800A0243BD111000002DC
-:1073100024050010240200013C010800AC223B6C53
-:107320000A000C0C3C0280001060FF7D2404004227
-:107330000A000C168FBF00188F8800288C89006007
-:107340000109282B14A00002010088218C91006003
-:107350003C0B80008D640E18240A000102202821B5
-:1073600002203021A38A001C0E000A7C022080210A
-:107370000A000B9AAF82002C000B5023122000074A
-:10738000314400033C0E800035CD098091A7007C7C
-:1073900030EC000415800019248F00043C01080023
-:1073A000A4243B923C19080097393B920325C02145
-:1073B00000D8202B1080FF658F8400242CA60005A8
-:1073C00014C0FF9D2404004230BF000317E00002F8
-:1073D00000BF182324A3FFFC3C010800AC233B742E
-:1073E0003C010800A4203B920A000BD90060282130
-:1073F00000A768240A000BFF01A718263C0108001B
-:10740000A42F3B920A000C70000000003C01080011
-:10741000AC203B740A000C15240400428F83002822
-:107420003C0B8000356A0A00146000060000102141
-:10743000914600302405000530C400FF108500038C
-:107440000000000003E0000800000000914900482F
-:10745000312800FF000839C214E0FFFA3C0480081C
-:107460003C06080094C63B7C3C0308008C633B94BC
-:107470003C0508008CA53B743C18080097183B920B
-:107480000066C8218C8E00040325782101F868214C
-:1074900001AE60231980001D000000009158004CCF
-:1074A0008F8D0034956E0E10330F00FF8DA90004F0
-:1074B00001CF30238DAA000030CFFFFF000F610005
-:1074C000012C2821000038210147202100AC182B75
-:1074D0000083C821ADA50004ADB9000091B8000A31
-:1074E00001F87021A1AE000A956C0E128F8A00344B
-:1074F000A54C00089549003825280001A54800380A
-:107500009147000D34EB0008A14B000D03E000088B
-:107510000000000027BDFFD8AFB00018938F001CFB
-:107520008FB000143C087FFF8F8700243C0C800044
-:107530003518FFFFAFBF0020AFB1001C35990A001E
-:1075400002181824932A003C000F5FC03C02BFFFC2
-:107550002CF000013449FFFF006BF8253C080800BF
-:107560008D083B948F9900303C18080097183B8A8F
-:1075700003E9582400107F803C07EFFF3C05F0FF33
-:10758000016F18253C1180003149002034E2FFFFD3
-:1075900034ADFFFF362E098027A500102406000217
-:1075A00001194023270A000200621824008080216C
-:1075B00015200002000058218D8B0E1CA7AA001276
-:1075C0000500003A2407000030EF00FF000F3F00E5
-:1075D000006740253C028008AFA80014344B0080AF
-:1075E000916A00683C0F080091EF3B913C09DFFF76
-:1075F000353FFFFF000A602B3C02080094423B84A9
-:10760000A3AF0011011FC024000CCF40031918259F
-:107610008FA70010AFA300143C1F080093FF3B93FB
-:10762000A7A200168FA8001400ED48243C0B01000F
-:107630003C0A0FFF012BC82533F80003354CFFFF30
-:10764000010D78243C027000032C382400181E0021
-:1076500000E2482501E35825AFAB0014AFA90010A4
-:1076600091DF007CA3BF00150E0000630000000046
-:10767000362D0A0091A6003C30C400201080000680
-:10768000260200083C11080096313B80262EFFFFA1
-:107690003C010800A42E3B808FBF00208FB1001C4E
-:1076A0008FB0001803E0000827BD00288F8A002C47
-:1076B000016A602B5580FFC4240700010A000CFA00
-:1076C00030EF00FF9383001C3C02800027BDFFD8F1
-:1076D00034480A0000805021AFBF002034460AC061
-:1076E000010028211060000E344409809107003009
-:1076F000240B00058F89002030EC003F118B000B1C
-:1077000000003821AFA900103C0B80088D69006C87
-:10771000AFAA00180E00012BAFA90014A380001C13
-:107720008FBF002003E0000827BD00288D1F004800
-:107730003C1808008F183B748F9900283C027FFF8B
-:107740008D0800443443FFFFAFA900103C0B8008B4
-:107750008D69006C03E370240319782101CF68233D
-:1077600001A83821AFAA00180E00012BAFA9001400
-:107770000A000D4FA380001C3C05800034A60A00BF
-:1077800090C7003C3C06080094C63B923C020800AF
-:107790008C423B8C30E30020000624001060001E69
-:1077A000004438253C0880083505008090A3006817
-:1077B00000003021240800010000202124030001E2
-:1077C0003C0580008CAC01780580FFFE00000000C5
-:1077D000ACA80148A4A40144A4A301463C030800AA
-:1077E0008C633B943C188008370F0080ACA3014C9D
-:1077F0003C19080093393B913C0D1000A0B901528F
-:10780000ACA70154A4A6015891EE004CA0AE016DA6
-:1078100003E00008ACAD01788CA80E1C3C0B0800FE
-:107820008D6B3B7494AA0E1694A90E140166302138
-:107830003143FFFF0A000D773124FFFF3C04800035
-:1078400034830A009065003C30A200201040001CE8
-:10785000000000000000302100002021000018215D
-:107860003C0580008CA901780520FFFE0000000087
-:10787000ACA601483C0E08008DCE3B94240DFF9130
-:10788000240C00403C0B8008A4A30144356A00800E
-:10789000A4A40146ACAE014CA0AD0152ACAC015465
-:1078A000A4A0015890A301099144004C90A601099D
-:1078B0003C041000A0A6016D03E00008ACA4017810
-:1078C0008C860E1894880E1294870E103104FFFFD8
-:1078D0000A000D9F30E3FFFF3C04800034830A0060
-:1078E0009065003C30A200201040002627BDFFF824
-:1078F0002409000100003821240800013C06800012
-:107900008CC401780480FFFE0000000090CA0109C9
-:107910003C04080090843BD13C1880FFA3AA0003DC
-:107920008FA300003085007F370FFFFF0066102512
-:10793000AFA2000090D9010AA3A0000200056E00CA
-:10794000A3B900018FAE0000240A300027BD000853
-:1079500001CF6024018D5825ACCB014CACCA015439
-:10796000A4C00158ACC90148A4C701442409FF8040
-:10797000A4C801463C081000A0C9015203E0000859
-:10798000ACC801788C890E1894870E1294860E105C
-:1079900030E8FFFF0A000DC630C7FFFF27BDFFE834
-:1079A000AFB000103C108000AFBF001436180A00C2
-:1079B000970F00320E000A7831E43FFF8E0E01006F
-:1079C000240DFF803C04200001C25821016D602479
-:1079D000000C4940316A007F012A40250104382506
-:1079E0003C048008AE0708303486008090C50068EB
-:1079F0002403000230A200FF104300048F9F0020E8
-:107A00008F990024AC9F0068AC9900648FBF00146C
-:107A10008FB0001003E0000827BD00183C0A0800E2
-:107A2000254A36583C090800252936F43C08080048
-:107A300025082B003C07080024E737B83C0608005F
-:107A400024C634E03C05080024A532383C04080074
-:107A500024842E2C3C030800246335943C02080047
-:107A6000244233303C010800AC2A3B503C01080062
-:107A7000AC293B4C3C010800AC283B483C010800C9
-:107A8000AC273B543C010800AC263B643C01080099
-:107A9000AC253B5C3C010800AC243B583C01080091
-:107AA000AC233B683C010800AC223B6003E00008CB
-:047AB00000000000D2
-:0C7AB400800009408000090080080100EB
-:107AC0008008008080080000800E00008008008090
-:107AD0008008000080000A8080000A008000098081
-:047AE0008000090019
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
diff --git a/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex b/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex
new file mode 100644
index 000000000000..7f39b4a7f331
--- /dev/null
+++ b/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex
@@ -0,0 +1,6488 @@
+:10000000080001180800000000005594000000C816
+:1000100000000000000000000000000008005594EF
+:10002000000000380000565C080000A00800000036
+:100030000000574400005694080059200000008436
+:100040000000ADD808005744000001C00000AE5CBD
+:100050000800321008000000000090900000B01C62
+:100060000000000000000000000000000800909068
+:100070000000033C000140AC0800049008000400AC
+:10008000000012FC000143E8000000000000000036
+:1000900000000000080016FC00000004000156E407
+:1000A000080000A80800000000003D28000156E8F4
+:1000B00000000000000000000000000008003D28D3
+:0800C000000000300001941063
+:0800C8000A00004600000000E0
+:1000D000000000000000000D636F6D362E302E31E1
+:1000E00037000000060011020000000000000003BD
+:1000F000000000C800000032000000030000000003
+:1001000000000000000000000000000000000000EF
+:1001100000000010000001360000EA600000000549
+:1001200000000000000000000000000000000008C7
+:1001300000000000000000000000000000000000BF
+:1001400000000000000000000000000000000000AF
+:10015000000000000000000000000000000000009F
+:10016000000000020000000000000000000000008D
+:10017000000000000000000000000000000000007F
+:10018000000000000000000000000010000000005F
+:10019000000000000000000000000000000000005F
+:1001A000000000000000000000000000000000004F
+:1001B000000000000000000000000000000000003F
+:1001C000000000000000000000000000000000002F
+:1001D000000000000000000000000000000000001F
+:1001E0000000000010000003000000000000000DEF
+:1001F0000000000D3C020800244256083C030800A1
+:1002000024635754AC4000000043202B1480FFFDB2
+:10021000244200043C1D080037BD9FFC03A0F021D0
+:100220003C100800261001183C1C0800279C5608AA
+:100230000E000256000000000000000D27BDFFB4B4
+:10024000AFA10000AFA20004AFA30008AFA4000C50
+:10025000AFA50010AFA60014AFA70018AFA8001CF0
+:10026000AFA90020AFAA0024AFAB0028AFAC002C90
+:10027000AFAD0030AFAE0034AFAF0038AFB8003C28
+:10028000AFB90040AFBC0044AFBF00480E001544FA
+:10029000000000008FBF00488FBC00448FB90040B1
+:1002A0008FB8003C8FAF00388FAE00348FAD003078
+:1002B0008FAC002C8FAB00288FAA00248FA90020C0
+:1002C0008FA8001C8FA700188FA600148FA5001000
+:1002D0008FA4000C8FA300088FA200048FA1000040
+:1002E00027BD004C3C1B60108F7A5030377B502864
+:1002F00003400008AF7A00008F82002427BDFFE092
+:10030000AFB00010AFBF0018AFB100148C42000CAA
+:100310003C1080008E110100104000348FBF001887
+:100320000E000D84000000008F85002024047FFF54
+:100330000091202BACB100008E030104960201084D
+:1003400000031C003042FFFF00621825ACA300042C
+:100350009202010A96030114304200FF3063FFFF4E
+:100360000002140000431025ACA200089603010C03
+:100370009602010E00031C003042FFFF00621825A8
+:10038000ACA3000C960301109602011200031C009E
+:100390003042FFFF00621825ACA300108E02011846
+:1003A000ACA200148E02011CACA20018148000083C
+:1003B0008F820024978200003C0420050044182509
+:1003C00024420001ACA3001C0A0000C6A782000062
+:1003D0003C0340189442001E00431025ACA2001CB0
+:1003E0000E000DB8240400018FBF00188FB1001457
+:1003F0008FB000100000102103E0000827BD00208E
+:100400003C0780008CE202B834E50100044100089A
+:10041000240300013C0208008C42006024420001D9
+:100420003C010800AC22006003E0000800601021DD
+:100430003C0208008C42005C8CA4002094A30016AF
+:100440008CA6000494A5000E24420001ACE40280B6
+:100450002463FFFC3C010800AC22005C3C0210005D
+:10046000A4E30284A4E5028600001821ACE6028819
+:10047000ACE202B803E000080060102127BDFFE0F5
+:100480003C028000AFB0001034420100AFBF001C3E
+:10049000AFB20018AFB100148C43000094450008BF
+:1004A0002462FE002C42038110400003000381C23D
+:1004B0000A00010226100004240201001462000553
+:1004C0003C1180003C02800890420004305000FF44
+:1004D0003C11800036320100964300143202000FB6
+:1004E00000021500004310253C0308008C63004403
+:1004F00030A40004AE220080246300013C01080007
+:10050000AC2300441080000730A200028FBF001C03
+:100510008FB200188FB100148FB000100A0000CE07
+:1005200027BD00201040002D0000182130A20080BF
+:1005300010400005362200708E44001C0E000C672F
+:10054000240500A0362200708C4400008F82000C2D
+:10055000008210232C43012C10600004AF82001095
+:10056000240300010A000145AF84000C8E42000400
+:100570003C036020AF84000CAC6200143C02080015
+:100580008C42005850400015000018218C62000475
+:10059000240301FE304203FF144300100000182121
+:1005A0002E020004104000032E0200080A00014041
+:1005B0000000802114400003000000000A000140F8
+:1005C0002610FFF90000000D2402000202021004B0
+:1005D0003C036000AC626914000018218FBF001C4E
+:1005E0008FB200188FB100148FB00010006010217E
+:1005F00003E0000827BD00203C0480008C8301003C
+:1006000024020100506200033C0280080000000D3B
+:100610003C02800890430004000010213063000F6A
+:1006200000031D0003E00008AC8300800004188074
+:100630002782FF9C00621821000410C00044102390
+:100640008C640000000210C03C030800246356E4E0
+:10065000004310213C038000AC64009003E00008DC
+:10066000AF8200243C0208008C42011410400019A3
+:100670003084400030A2007F000231C03C02020002
+:100680001080001400A218253C026020AC43001426
+:100690003C0408008C8456B83C0308008C630110AD
+:1006A0003C02800024050900AC4500200086202182
+:1006B000246300013C028008AC4400643C01080053
+:1006C000AC2301103C010800AC2456B803E000083C
+:1006D000000000003C02602003E00008AC4500146C
+:1006E00003E000080000102103E0000800001021D2
+:1006F00030A2000810400008240201003C0208005B
+:100700008C42010C244200013C010800AC22010C87
+:1007100003E0000800000000148200080000000050
+:100720003C0208008C4200FC244200013C0108000D
+:10073000AC2200FC0A0001A330A200203C02080009
+:100740008C420084244200013C010800AC22008459
+:1007500030A200201040000830A200103C02080027
+:100760008C420108244200013C010800AC2201082F
+:1007700003E0000800000000104000080000000036
+:100780003C0208008C420104244200013C010800A4
+:10079000AC22010403E00008000000003C02080055
+:1007A0008C420100244200013C010800AC220100FF
+:1007B00003E000080000000027BDFFE0AFB1001417
+:1007C0003C118000AFB20018AFBF001CAFB00010EA
+:1007D0003632010096500008320200041040000733
+:1007E000320300028FBF001C8FB200188FB10014BB
+:1007F0008FB000100A0000CE27BD00201060000B53
+:10080000020028218E2401000E00018A0000000051
+:100810003202008010400003240500A10E000C6786
+:100820008E44001C0A0001E3240200018E2301040F
+:100830008F82000810430006020028218E24010048
+:100840000E00018A000000008E220104AF82000821
+:10085000000010218FBF001C8FB200188FB1001450
+:100860008FB0001003E0000827BD00202C82000498
+:1008700014400002000018212483FFFD240200021E
+:10088000006210043C03600003E00008AC626914DD
+:1008900027BDFFE0AFBF001CAFB20018AFB100141E
+:1008A000AFB000103C048000948201083043700017
+:1008B000240220001062000A2862200154400052E5
+:1008C0008FBF001C24024000106200482402600018
+:1008D0001062004A8FBF001C0A0002518FB200183C
+:1008E00034820100904300098C5000189451000C90
+:1008F000240200091062001C0000902128620009F7
+:10090000144000218F8200242402000A5062001249
+:10091000323100FF2402000B1062000F00000000C3
+:100920002402000C146200188F8200243C0208008C
+:100930008C4256B824030900AC83002000501021DB
+:100940003C038008AC6200643C010800AC2256B84D
+:100950000A0002508FBF001C0E0001E900102602A1
+:100960000A0002308F8200240E0001E900102602E6
+:100970003C0380089462001A8C72000C3042FFFF26
+:10098000020280258F8200248C42000C5040001E01
+:100990008FBF001C0E000D84000000003C02800090
+:1009A00034420100944300088F82002400031C009D
+:1009B0009444001E8F82002000641825AC50000073
+:1009C00024040001AC510004AC520008AC40000CFF
+:1009D000AC400010AC400014AC4000180E000DB844
+:1009E000AC43001C0A0002508FBF001C0E000440E4
+:1009F000000000000A0002508FBF001C0E000C9F78
+:100A0000000000008FBF001C8FB200188FB10014CF
+:100A10008FB000100000102103E0000827BD002067
+:100A200027BDFFD8AFB400203C036010AFBF002447
+:100A3000AFB3001CAFB20018AFB10014AFB00010DC
+:100A40008C6450002402FF7F3C1408002694563822
+:100A5000008220243484380CAC6450003C028000B6
+:100A6000240300370E0014B0AC4300083C07080014
+:100A700024E70618028010212404001D2484FFFFAF
+:100A8000AC4700000481FFFD244200043C02080042
+:100A9000244207C83C010800AC2256403C02080032
+:100AA000244202303C030800246306203C04080072
+:100AB000248403B43C05080024A506F03C06080085
+:100AC00024C62C9C3C010800AC2256803C02080045
+:100AD000244205303C010800AC2756843C01080044
+:100AE000AC2656943C010800AC23569C3C010800FF
+:100AF000AC2456A03C010800AC2556A43C010800DB
+:100B0000AC2256A83C010800AC23563C3C0108002E
+:100B1000AC2456443C010800AC2056603C0108005F
+:100B2000AC2556643C010800AC2056703C0108001E
+:100B3000AC27567C3C010800AC2656903C010800CE
+:100B4000AC2356980E00056E00000000AF80000C2C
+:100B50003C0280008C5300008F8300043C0208009C
+:100B60008C420020106200213262000700008821C0
+:100B70002792FF9C3C100800261056E43C02080017
+:100B80008C42002024050001022518040043202483
+:100B90008F820004004310245044000C26310001D1
+:100BA00010800008AF9000248E4300003C028000BB
+:100BB000AC4300900E000D4BAE05000C0A0002C1C4
+:100BC00026310001AE00000C263100012E22000269
+:100BD000261000381440FFE9265200043C020800A9
+:100BE0008C420020AF820004326200071040FFD91F
+:100BF0003C028000326200011040002D326200028F
+:100C00003C0580008CA2010000002021ACA2002045
+:100C10008CA301042C42078110400008ACA300A85B
+:100C200094A2010824032000304270001443000302
+:100C30003C02800890420005304400FF0E0001593C
+:100C4000000000003C0280009042010B304300FF96
+:100C50002C62001E54400004000310800E00018628
+:100C60000A0002EC00000000005410218C42000039
+:100C70000040F80900000000104000043C02800021
+:100C80008C4301043C026020AC4300143C02080089
+:100C90008C4200343C0440003C03800024420001AC
+:100CA000AC6401383C010800AC220034326200021E
+:100CB00010400010326200043C1080008E0201409F
+:100CC000000020210E000159AE0200200E00038317
+:100CD000000000003C024000AE0201783C02080027
+:100CE0008C420038244200013C010800AC2200384C
+:100CF000326200041040FF973C0280003C108000EC
+:100D00008E020180000020210E000159AE02002059
+:100D10008E03018024020F00546200073C02800809
+:100D20008E0201883C0300E03042FFFF00431025A3
+:100D30000A000328AE020080344200809042000086
+:100D400024030050304200FF14430007000000005D
+:100D50000E000362000000001440000300000000C9
+:100D60000E000971000000003C0208008C42003CAB
+:100D70003C0440003C03800024420001AC6401B804
+:100D80003C010800AC22003C0A0002A33C028000A7
+:100D90003C02900034420001008220253C02800089
+:100DA000AC4400203C0380008C6200200440FFFE25
+:100DB0000000000003E00008000000003C0280008A
+:100DC000344300010083202503E00008AC440020E8
+:100DD00027BDFFE0AFB10014AFB000100080882144
+:100DE000AFBF00180E00033230B000FF8F83FF94B6
+:100DF000022020219062002502028025A07000259B
+:100E00008C7000183C0280000E00033D020280241A
+:100E10001600000B8FBF00183C0480008C8201F884
+:100E20000440FFFE348201C024030002AC510000E4
+:100E3000A04300043C021000AC8201F88FBF0018F0
+:100E40008FB100148FB0001003E0000827BD002010
+:100E500027BDFFE83C028000AFBF00103442018094
+:100E6000944300048C4400083063020010600005C5
+:100E7000000028210E00100C000000000A0003787A
+:100E8000240500013C02FF000480000700821824B2
+:100E90003C02040014620004240500018F82FF94C8
+:100EA00090420008240500018FBF001000A010210F
+:100EB00003E0000827BD00188F82FF982405000179
+:100EC000A040001A3C028000344201400A00034264
+:100ED0008C4400008F85FF9427BDFFE0AFBF001C4E
+:100EE000AFB20018AFB10014AFB0001090A2000074
+:100EF000304400FF38830020388200300003182B74
+:100F00000002102B0062182410600003240200501D
+:100F1000148200A88FBF001C90A20005304200017F
+:100F2000104000A48FBF001C3C02800034420140EE
+:100F3000904200082443FFFF2C6200051040009EF1
+:100F40008FB20018000310803C030800246355ACE6
+:100F5000004310218C420000004000080000000007
+:100F60003C028000345101400E0003328E24000008
+:100F70008F92FF948E2200048E50000C1602000205
+:100F800024020001AE42000C0E00033D8E2400003E
+:100F90008E220004145000068FBF001C8FB2001870
+:100FA0008FB100148FB000100A000F7827BD002009
+:100FB0008E42000C0A000419000000003C0480006E
+:100FC0003482014094A300108C4200043063FFFF80
+:100FD0001443001C0000000024020001A4A2001021
+:100FE0008C8202380441000F3C0380003C02003F29
+:100FF0003448F0003C0760003C06FFC08CE22BBC8C
+:1010000000461824004810240002130200031D8229
+:10101000106200583C0280008C8202380440FFF7C6
+:101020003C038000346201408C44000034620200C2
+:10103000AC4400003C021000AC6202380A00043BE1
+:101040008FBF001C94A200100A00041900000000C9
+:10105000240200201482000F3C0280003C03800028
+:1010600094A20012346301408C6300043042FFFFFD
+:10107000146200050000000024020001A4A2001276
+:101080000A0004028FBF001C94A200120A00041977
+:1010900000000000345101400E0003328E24000095
+:1010A0008F92FF948E230004964200123050FFFF6F
+:1010B0001603000224020001A64200120E00033DA6
+:1010C0008E2400008E220004160200068FBF001C32
+:1010D0008FB200188FB100148FB000100A00037C8B
+:1010E00027BD0020964200120A00041900000000EB
+:1010F0003C03800094A20014346301408C6300041C
+:101100003042FFFF14620008240200018FBF001C60
+:101110008FB200188FB100148FB00010A4A2001479
+:101120000A00146327BD002094A20014144000217B
+:101130008FBF001C0A000435000000003C03800043
+:1011400094A20016346301408C6300043042FFFF18
+:101150001462000D240200018FBF001C8FB2001822
+:101160008FB100148FB00010A4A200160A000B1457
+:1011700027BD00209442007824420004A4A200105D
+:101180000A00043B8FBF001C94A200162403000138
+:101190003042FFFF144300078FBF001C3C020800D1
+:1011A0008C420070244200013C010800AC22007017
+:1011B0008FBF001C8FB200188FB100148FB00010C9
+:1011C00003E0000827BD002027BDFFD8AFB20018FC
+:1011D0008F92FF94AFB10014AFBF0020AFB3001CDB
+:1011E000AFB000103C028000345101008C5001006F
+:1011F0009242000092230009304400FF2402001FA5
+:10120000106200AB28620020104000192402003850
+:101210002862000A1040000D2402000B286200081A
+:101220001040002E8F820024046001042862000216
+:101230001440002A8F820024240200061062002637
+:101240008FBF00200A00055F8FB3001C1062006092
+:101250002862000B144000FA8FBF00202402000E09
+:10126000106200788F8200240A00055F8FB3001C93
+:10127000106200D2286200391040000A2402008067
+:1012800024020036106200E528620037104000C3D7
+:1012900024020035106200D98FBF00200A00055FCC
+:1012A0008FB3001C1062002D2862008110400006E0
+:1012B000240200C824020039106200C98FBF002038
+:1012C0000A00055F8FB3001C106200A28FBF0020D0
+:1012D0000A00055F8FB3001C8F8200248C42000C33
+:1012E000104000D78FBF00200E000D8400000000CA
+:1012F0003C038000346301008C6200008F85002075
+:10130000946700089466000CACA200008C64000492
+:101310008F82002400063400ACA400049448001E10
+:101320008C62001800073C0000E83825ACA20008D9
+:101330008C62001C24040001ACA2000C9062000A24
+:1013400000C23025ACA60010ACA00014ACA0001860
+:10135000ACA7001C0A00051D8FBF00208F8200244F
+:101360008C42000C104000B68FBF00200E000D8490
+:10137000000000008F820024962400089625000CAF
+:101380009443001E000422029626000E8F82002045
+:10139000000426000083202500052C003C0300806B
+:1013A00000A6282500832025AC400000AC400004A6
+:1013B000AC400008AC40000CAC450010AC40001440
+:1013C000AC400018AC44001C0A00051C24040001B9
+:1013D0009622000C14400018000000009242000504
+:1013E0003042001014400014000000000E000332D0
+:1013F0000200202192420005020020213442001008
+:101400000E00033DA242000592420000240300208A
+:10141000304200FF10430089020020218FBF0020CE
+:101420008FB3001C8FB200188FB100148FB0001062
+:101430000A00107527BD00280000000D0A00055E97
+:101440008FBF00208C42000C1040007D8FBF002019
+:101450000E000D84000000008E2200048F84002006
+:101460009623000CAC8200003C0280089445002CBE
+:101470008F82002400031C0030A5FFFF9446001E4D
+:101480003C02400E0065182500C23025AC830004E4
+:10149000AC800008AC80000CAC800010AC80001464
+:1014A000AC800018AC86001C0A00051C2404000156
+:1014B0000E000332020020218F93FF9802002021AA
+:1014C0000E00033DA660000C020020210E00034226
+:1014D000240500018F8200248C42000C104000582B
+:1014E0008FBF00200E000D84000000009622000C2B
+:1014F0008F83002000021400AC700000AC62000476
+:10150000AC6000088E4400388F820024AC64000C6C
+:101510008E46003C9445001E3C02401FAC66001005
+:1015200000A228258E62000424040001AC6200148D
+:10153000AC600018AC65001C8FBF00208FB3001C8E
+:101540008FB200188FB100148FB000100A000DB8D0
+:1015500027BD0028240200201082003A8FB3001C0F
+:101560000E000F5E00000000104000358FBF00200D
+:101570003C0480008C8201F80440FFFE348201C0EC
+:1015800024030002AC500000A04300043C02100001
+:10159000AC8201F80A00055E8FBF00200200202106
+:1015A0008FBF00208FB3001C8FB200188FB10014C2
+:1015B0008FB000100A000EA727BD00289625000C4A
+:1015C000020020218FBF00208FB3001C8FB20018B3
+:1015D0008FB100148FB000100A000ECC27BD002878
+:1015E000020020218FB3001C8FB200188FB10014AD
+:1015F0008FB000100A000EF727BD00289225000DBD
+:10160000020020218FB3001C8FB200188FB100148C
+:101610008FB000100A000F4827BD002802002021CB
+:101620008FBF00208FB3001C8FB200188FB1001441
+:101630008FB000100A000F1F27BD00288FBF0020A9
+:101640008FB3001C8FB200188FB100148FB0001040
+:1016500003E0000827BD00283C0580008CA202782A
+:101660000440FFFE34A2024024030002AC44000008
+:10167000A04300043C02100003E00008ACA2027882
+:10168000A380001803E00008A38000193C03800039
+:101690008C6202780440FFFE8F82001CAC62024024
+:1016A00024020002A06202443C02100003E0000891
+:1016B000AC6202783C02600003E000088C425404F3
+:1016C0009083003024020005008040213063003FF9
+:1016D0000000482114620005000050219082004C57
+:1016E0009483004E304900FF306AFFFFAD00000CCC
+:1016F000AD000010AD000024950200148D05001C03
+:101700008D0400183042FFFF004910230002110031
+:10171000000237C3004038210086202300A2102B8E
+:101720000082202300A72823AD05001CAD0400186B
+:10173000A5090014A5090020A50A001603E0000869
+:10174000A50A002203E000080000000027BDFFD822
+:10175000AFB200183C128008AFB40020AFB3001C39
+:10176000AFB10014AFBF0024AFB00010365101007C
+:101770003C0260008C4254049222000C3C1408008D
+:10178000929400F7304300FF2402000110620032FF
+:101790000080982124020002146200353650008037
+:1017A0000E00143D000000009202004C2403FF8054
+:1017B0003C0480003042007F000211C024420240FD
+:1017C0000262102100431824AC8300949245000863
+:1017D0009204004C3042007F3C03800614850007D1
+:1017E000004380212402FFFFA22200112402FFFFF8
+:1017F000A62200120A0005D22402FFFF9602002052
+:10180000A222001196020022A62200128E020024BB
+:101810003C048008AE2200143485008090A2004C65
+:1018200034830100A06200108CA2003CAC6200185E
+:101830008C820068AC6200F48C820064AC6200F0C0
+:101840008C82006CAC6200F824020001A0A2006847
+:101850000A0005EE3C0480080E001456000000004B
+:1018600036420080A04000680A0005EE3C04800873
+:10187000A2000068A20000690A0006293C02800854
+:10188000348300808C62003834850100AC62006CC7
+:1018900024020001A062006990A200D59083000894
+:1018A000305100FF3072007F12320019001111C058
+:1018B00024420240026210212403FF8000431824C6
+:1018C0003C048000AC8300943042007F3C038006DF
+:1018D000004380218E02000C1040000D02002021E8
+:1018E0000E00057E0000000026220001305100FF9E
+:1018F0009203003C023410260002102B0002102339
+:101900003063007F022288240A0005F8A203003C0D
+:101910003C088008350401008C8200E03507008017
+:10192000ACE2003C8C8200E0AD02000090E5004C8F
+:10193000908600D590E3004C908400D52402FF806F
+:1019400000A228243063007F308400FF00A62825F1
+:101950000064182A1060000230A500FF38A500803E
+:10196000A0E5004CA10500093C0280089043000E50
+:10197000344400803C058000A043000A8C8300189A
+:101980003C027FFF3442FFFF00621824AC83001842
+:101990008CA201F80440FFFE00000000ACB301C0BF
+:1019A0008FBF00248FB400208FB3001C8FB20018AB
+:1019B0008FB100148FB0001024020002A0A201C455
+:1019C00027BD00283C02100003E00008ACA201F88B
+:1019D00090A2000024420001A0A200003C030800E5
+:1019E0008C6300F4304200FF144300020080302179
+:1019F000A0A0000090A200008F84001C000211C073
+:101A00002442024024830040008220212402FF80DF
+:101A1000008220243063007F3C02800A006218218B
+:101A20003C028000AC44002403E00008ACC300008A
+:101A300094820006908300058C85000C8C86001033
+:101A40008C8700188C88001C8C8400203C010800C6
+:101A5000A42256C63C010800A02356C53C0108003C
+:101A6000AC2556CC3C010800AC2656D03C01080001
+:101A7000AC2756D83C010800AC2856DC3C010800D5
+:101A8000AC2456E003E00008000000003C0280089F
+:101A9000344201008C4400343C038000346504006F
+:101AA000AC6400388C420038AF850028AC62003C42
+:101AB0003C020005AC6200300000000000000000A5
+:101AC00003E00008000000003C020006308400FF34
+:101AD000008220253C028000AC4400300000000061
+:101AE00000000000000000003C0380008C62000049
+:101AF000304200101040FFFD3462040003E0000893
+:101B0000AF82002894C200003C080800950800CA73
+:101B100030E7FFFF0080482101021021A4C200002D
+:101B200094C200003042FFFF00E2102B544000013D
+:101B3000A4C7000094A200003C0308008C6300CC02
+:101B400024420001A4A2000094A200003042FFFF42
+:101B5000144300073C0280080107102BA4A00000DA
+:101B60005440000101003821A4C700003C02800855
+:101B7000344601008CC3002894A200003C0480007D
+:101B80003042FFFE000210C000621021AC82003C17
+:101B90008C82003C006218231860000400000000E2
+:101BA0008CC200240A0006BA244200018CC2002420
+:101BB000AC8200383C020050344200103C038000EC
+:101BC000AC620030000000000000000000000000D7
+:101BD0008C620000304200201040FFFD0000000039
+:101BE00094A200003C04800030420001000210C0BA
+:101BF000004410218C430400AD2300008C420404F7
+:101C0000AD2200043C02002003E00008AC8200305A
+:101C100027BDFFE0AFB20018AFB10014AFB00010A5
+:101C2000AFBF001C94C2000000C080213C1208001D
+:101C3000965200C624420001A6020000960300004E
+:101C400094E2000000E03021144300058FB1003021
+:101C50000E00068F024038210A0006F10000000045
+:101C60008C8300048C82000424420040046100073D
+:101C7000AC8200048C8200040440000400000000D8
+:101C80008C82000024420001AC8200009602000019
+:101C90003042FFFF50520001A600000096220000D3
+:101CA00024420001A62200003C02800834420100C8
+:101CB000962300009442003C144300048FBF001C94
+:101CC00024020001A62200008FBF001C8FB2001862
+:101CD0008FB100148FB0001003E0000827BD002072
+:101CE00027BDFFE03C028008AFBF0018344201006E
+:101CF0008C4800343C03800034690400AC68003830
+:101D00008C42003830E700FFAF890028AC62003C0D
+:101D10003C020005AC620030000000000000000042
+:101D200000000000000000000000000000000000B3
+:101D30008C82000C8C82000C97830016AD22000070
+:101D40008C82001000604021AD2200048C820018BB
+:101D5000AD2200088C82001CAD22000C8CA2001465
+:101D6000AD2200108C820020AD220014908200056C
+:101D7000304200FF00021200AD2200188CA20018B1
+:101D8000AD22001C8CA2000CAD2200208CA2001001
+:101D9000AD2200248CA2001CAD2200288CA20020C1
+:101DA000AD22002C3402FFFFAD260030AD20003400
+:101DB000506200013408FFFFAD28003850E00011E8
+:101DC0003C0280083C048008348401009482005066
+:101DD0003042FFFFAD22003C9483004494850044D0
+:101DE000240200013063FFFF000318C200641821C1
+:101DF0009064006430A5000700A210040A00075C8C
+:101E00000044102534420100AD20003C94430044BE
+:101E1000944400443063FFFF000318C2006218219D
+:101E200030840007906500642402000100821004E1
+:101E30000002102700451024A0620064000000008A
+:101E400000000000000000003C0200063442004098
+:101E50003C038000AC620030000000000000000085
+:101E6000000000008C620000304200101040FFFDB6
+:101E70003C06800834C201503463040034C7014A70
+:101E800034C4013434C5014034C60144AFA200104B
+:101E90000E0006D2AF8300288FBF001803E00008B1
+:101EA00027BD00208F8300143C0608008CC600E884
+:101EB0008F82001C30633FFF000319800046102111
+:101EC000004310212403FF80004318243C068000B7
+:101ED000ACC300283042007F3C03800C004330211B
+:101EE00090C2000D30A500FF0000382134420010E0
+:101EF000A0C2000D8F8900143C028008344201000A
+:101F00009443004400091382304800032402000176
+:101F1000A4C3000E1102000B2902000210400005AC
+:101F2000240200021100000C240300010A0007A48F
+:101F30000000182111020006000000000A0007A49A
+:101F4000000018218CC2002C0A0007A424430001C1
+:101F50008CC20014244300018CC200180043102BD3
+:101F60005040000A240700012402002714A20003A5
+:101F70003C0380080A0007B1240700013463010014
+:101F80009462004C24420001A462004C00091382B8
+:101F9000304300032C620002104000090080282119
+:101FA000146000040000000094C200340A0007C15D
+:101FB0003046FFFF8CC600380A0007C10080282188
+:101FC000000030213C040800248456C00A000706A3
+:101FD0000000000027BDFF90AFB60068AFB50064F9
+:101FE000AFB40060AFB3005CAFB20058AFB1005403
+:101FF000AFBF006CAFB000508C9000000080B021EB
+:102000003C0208008C4200E8960400328F83001CDA
+:102010002414FF8030843FFF0062182100042180D7
+:1020200000641821007410243C13800000A090214B
+:1020300090A50000AE620028920400323C02800CA1
+:102040003063007F00628821308400C02402004099
+:10205000148200320000A8218E3500388E2200182C
+:102060001440000224020001AE2200189202003C3B
+:10207000304200201440000E8F83001C000511C068
+:102080002442024000621821306400783C02008043
+:102090000082202500741824AE630800AE64081086
+:1020A0008E2200188E03000800431021AE22001873
+:1020B0008E22002C8E230018244200010062182B6F
+:1020C0001060004300000000924200002442000122
+:1020D000A24200003C0308008C6300F4304200FF81
+:1020E00050430001A2400000924200008F84001C77
+:1020F000000211C024420240248300403063007F6C
+:10210000008220213C02800A0094202400621821D1
+:10211000AE6400240A0008D2AEC30000920300326D
+:102120002402FFC000431024304200FF1440000589
+:1021300024020001AE220018962200340A00084250
+:102140003055FFFF8E22001424420001AE220018F9
+:102150009202003000021600000216030441001C27
+:10216000000000009602003227A400100080282101
+:10217000A7A20016960200320000302124070001B9
+:102180003042FFFFAF8200140E000706AFA0001C14
+:10219000960200328F83001C3C0408008C8400E807
+:1021A00030423FFF000211800064182100621821B4
+:1021B00000741024AE62002C3063007F3C02800E5D
+:1021C000006218219062000D3042007FA062000D75
+:1021D0009222000D304200105040007892420000E0
+:1021E0003C028008344401009482004C8EC30000FD
+:1021F0003C130800967300C62442FFFFA482004CE3
+:10220000946200329623000E3054FFFF3070FFFFBF
+:102210003C0308008C6300D000701807A7A30038A7
+:102220009482003E3063FFFF3042FFFF14620007DC
+:10223000000000008C8200303C038000244200300B
+:10224000AC62003C0A00086A8C82002C9482004038
+:102250003042FFFF5462000927A400408C820038FE
+:102260003C03800024420030AC62003C8C8200348D
+:10227000AC6200380A0008793C03800027A50038CA
+:1022800027A60048026038210E00068FA7A000484C
+:102290008FA300403C02800024630030AC43003830
+:1022A0008FA30044AC43003C3C0380003C0200058B
+:1022B000AC6200303C028008344401009482004249
+:1022C000346304003042FFFF0202102B1440000769
+:1022D000AF8300289482004E9483004202021021B2
+:1022E000004310230A00088F3043FFFF9483004E01
+:1022F00094820042026318210050102300621823C8
+:102300003063FFFF3C028008344401009482003CAB
+:102310003042FFFF14430003000000000A00089F42
+:10232000240300019482003C3042FFFF0062102B26
+:10233000144000058F8200289482003C0062102324
+:102340003043FFFF8F820028AC550000AC400004F2
+:10235000AC540008AC43000C3C02000634420010B0
+:102360003C038000AC620030000000000000000070
+:10237000000000008C620000304200101040FFFDA1
+:102380003C04800834840100001018C20064182145
+:102390009065006432020007240600010046100424
+:1023A00000451025A0620064948300429622000E2E
+:1023B00050430001A386001892420000244200010D
+:1023C000A24200003C0308008C6300F4304200FF8E
+:1023D00050430001A2400000924200008F84001C84
+:1023E000000211C0244202402483004000822021C8
+:1023F0002402FF80008220243063007F3C02800A98
+:10240000006218213C028000AC440024AEC30000EE
+:102410008FBF006C8FB600688FB500648FB400600A
+:102420008FB3005C8FB200588FB100548FB0005052
+:1024300003E0000827BD007027BDFFD8AFB3001C24
+:10244000AFB20018AFB10014AFB00010AFBF0020A2
+:102450000080982100E0802130B1FFFF0E000D8444
+:1024600030D200FF0000000000000000000000006B
+:102470008F8200208F830024AC510000AC520004F6
+:10248000AC530008AC40000CAC400010AC40001451
+:10249000AC4000189463001E02038025AC50001C61
+:1024A0000000000000000000000000002404000103
+:1024B0008FBF00208FB3001C8FB200188FB10014A3
+:1024C0008FB000100A000DB827BD002830A5FFFF0F
+:1024D0000A0008DC30C600FF3C02800834430100DB
+:1024E0009462000E3C080800950800C63046FFFFC5
+:1024F00014C000043402FFFF946500EA0A000929B1
+:102500008F84001C10C20027000000009462004E5F
+:102510009464003C3045FFFF00A6102300A6182B52
+:102520003087FFFF106000043044FFFF00C5102318
+:1025300000E210233044FFFF0088102B1040000EF3
+:1025400000E810233C028008344401002403000109
+:1025500034420080A44300162402FFFFA482000E30
+:10256000948500EA8F84001C0000302130A5FFFF15
+:102570000A0009013C0760200044102A10400009AD
+:102580003C0280083443008094620016304200010F
+:10259000104000043C0280009442007E244200145B
+:1025A000A462001603E000080000000027BDFFE061
+:1025B0003C028008AFBF001CAFB0001834420100DD
+:1025C000944300429442004C104000193068FFFFD1
+:1025D0009383001824020001146200298FBF001C9D
+:1025E0003C06800834D00100000810C200501021C1
+:1025F000904200643103000734C70148304200FFB5
+:10260000006210073042000134C9014E34C4012C6D
+:1026100034C5013E1040001634C601420E0006D2F9
+:10262000AFA90010960200420A0009463048FFFF99
+:102630003C028008344401009483004494820042A8
+:102640001043000F8FBF001C94820044A4820042FC
+:1026500094820050A482004E8C820038AC820030FC
+:1026600094820040A482003E9482004AA4820048E2
+:102670008FBF001C8FB000180A00090427BD00207E
+:102680008FB0001803E0000827BD002027BDFFA081
+:10269000AFB1004C3C118000AFBF0058AFB3005445
+:1026A000AFB20050AFB000483626018890C2000398
+:1026B0003044007FA3A400108E32018090C200003D
+:1026C0003043007F240200031062003BAF92001CE5
+:1026D00028620004104000062402000424020002C4
+:1026E000106200098FBF00580A000B0F8FB300540F
+:1026F0001062004D240200051062014E8FBF005889
+:102700000A000B0F8FB30054000411C002421021C5
+:102710002404FF8024420240004410242643004049
+:10272000AE2200243063007F3C02800A0062182140
+:102730009062003CAFA3003C00441025A062003C26
+:102740008FA3003C9062003C304200401040016C7E
+:102750008FBF00583C108008A3800018361001007D
+:102760008E0200E08C63003427A4003C27A50010F3
+:10277000004310210E0007C3AE0200E093A2001038
+:102780003C038000A20200D58C6202780440FFFE68
+:102790008F82001CAC62024024020002A06202444C
+:1027A0003C021000AC6202780E0009390000000003
+:1027B0000A000B0E8FBF00583C05800890C3000133
+:1027C00090A2000B1443014E8FBF005834A4008028
+:1027D0008C8200189082004C90A200083C0260009D
+:1027E0008C4254048C8300183C027FFF3442FFFF6C
+:1027F000006218243C0208008C4200B4AC8300182C
+:102800003C038000244200013C010800AC2200B4DB
+:102810008C6201F80440FFFE8F82001CAC6201C094
+:102820000A000AD6240200023C10800890C300016E
+:102830009202000B144301328FBF005827A40018E6
+:1028400036050110240600033C0260008C4254044B
+:102850000E000E470000000027A40028360501F0F6
+:102860000E000E47240600038FA200283603010045
+:10287000AE0200648FA2002CAE0200688FA200306E
+:10288000AE02006C93A40018906300D52402FF8070
+:102890000082102400431025304900FF3084007F5F
+:1028A0003122007F0082102A544000013929008023
+:1028B000000411C0244202402403FF800242102180
+:1028C00000431024AE220094264200403042007F94
+:1028D0003C038006004340218FA3001C2402FFFF1D
+:1028E000AFA800403C130800927300F71062003359
+:1028F00093A2001995030014304400FF3063FFFFDA
+:102900000064182B106000100000000095040014F3
+:102910008D07001C8D0600183084FFFF0044202323
+:102920000004210000E438210000102100E4202BE5
+:1029300000C2302100C43021AD07001CAD060018D4
+:102940000A000A2F93A20019950400148D07001C99
+:102950008D0600183084FFFF008220230004210030
+:10296000000010210080182100C2302300E4202B39
+:1029700000C4302300E33823AD07001CAD06001867
+:1029800093A200198FA30040A462001497A2001A1A
+:10299000A46200168FA2001CAC6200108FA2001C63
+:1029A000AC62000C93A20019A462002097A2001A46
+:1029B000A46200228FA2001CAC6200243C048008A8
+:1029C000348300808C6200388FA20020012088218F
+:1029D000AC62003C8FA20020AC82000093A20018E1
+:1029E000A062004C93A20018A0820009A0600068B9
+:1029F00093A20018105100512407FF803229007F54
+:102A0000000911C024420240024210213046007FDA
+:102A10003C03800000471024AC6200943C02800616
+:102A200000C2302190C2003CAFA60040000020212F
+:102A300000471025A0C2003C8FA80040950200026C
+:102A4000950300148D07001C3042FFFF3063FFFF29
+:102A50008D060018004310230002110000E2382107
+:102A600000E2102B00C4302100C23021AD07001C51
+:102A7000AD06001895020002A5020014A50000167C
+:102A80008D020008AD0200108D020008AD02000C9E
+:102A900095020002A5020020A50000228D02000878
+:102AA000AD0200249102003C304200401040001A68
+:102AB000262200013C108008A3A90038A38000183A
+:102AC000361001008E0200E08D03003427A4004080
+:102AD00027A50038004310210E0007C3AE0200E016
+:102AE00093A200383C038000A20200D58C620278D9
+:102AF0000440FFFE8F82001CAC62024024020002F0
+:102B0000A06202443C021000AC6202780E00093957
+:102B100000000000262200013043007F14730004EF
+:102B2000004020212403FF8002231024004320269C
+:102B300093A200180A000A4B309100FF93A40018DA
+:102B40008FA3001C2402FFFF1062000A308900FFDF
+:102B500024820001248300013042007F14530005C9
+:102B6000306900FF2403FF800083102400431026F7
+:102B7000304900FF3C028008904200080120882173
+:102B8000305000FF123000193222007F000211C0C5
+:102B900002421021244202402403FF8000431824F3
+:102BA0003C048000AC8300943042007F3C038006EC
+:102BB000004310218C43000C004020211060000BCA
+:102BC000AFA200400E00057E000000002623000199
+:102BD0002405FF803062007F145300020225202468
+:102BE000008518260A000AAF307100FF3C048008F7
+:102BF000348400808C8300183C027FFF3442FFFF46
+:102C000000621824AC8300183C0380008C6201F839
+:102C10000440FFFE00000000AC7201C0240200026C
+:102C2000A06201C43C021000AC6201F80A000B0E65
+:102C30008FBF00583C04800890C300019082000BB5
+:102C40001443002F8FBF0058349000809202000878
+:102C500030420040104000200000000092020008B6
+:102C60000002160000021603044100050240202164
+:102C70000E000ECC240500930A000B0E8FBF0058E7
+:102C80009202000924030018304200FF1443000D93
+:102C900002402021240500390E000E64000030217E
+:102CA0000E0003328F84001C8F82FF9424030012D5
+:102CB000A04300090E00033D8F84001C0A000B0E88
+:102CC0008FBF0058240500360E000E64000030212E
+:102CD0000A000B0E8FBF00580E0003320240202165
+:102CE000920200058F84001C344200200E00033D38
+:102CF000A20200050E0010758F84001C8FBF0058C3
+:102D00008FB300548FB200508FB1004C8FB0004889
+:102D100003E0000827BD00603C0280083445010044
+:102D20003C0280008C42014094A3000E0000302140
+:102D300000402021AF82001C3063FFFF3402FFFF00
+:102D4000106200063C0760202402FFFFA4A2000ED0
+:102D500094A500EA0A00090130A5FFFF03E000087E
+:102D60000000000027BDFFC83C0280003C06800830
+:102D7000AFB5002CAFB1001CAFBF0030AFB400281E
+:102D8000AFB30024AFB20020AFB00018345101003F
+:102D900034C501008C4301008E2200148CA400E491
+:102DA0000000A821AF83001C0044102318400052EB
+:102DB000A38000188E22001400005021ACA200E471
+:102DC00090C3000890A200D53073007FA3A200102A
+:102DD0008CB200E08CB400E4304200FF1053003BA2
+:102DE00093A200108F83001C2407FF80000211C0F3
+:102DF0000062102124420240246300400047102456
+:102E00003063007F3C0980003C08800A006818217C
+:102E1000AD2200248C62003427A4001427A50010E2
+:102E2000024280210290102304400028AFA3001426
+:102E30009062003C00E21024304200FF1440001970
+:102E4000020090219062003C34420040A062003CAD
+:102E50008F86001C93A3001024C200403042007FE4
+:102E6000004828213C0208008C4200F42463000141
+:102E7000306400FF14820002A3A30010A3A000107E
+:102E800093A20010AFA50014000211C0244202401A
+:102E900000C2102100471024AD2200240A000B4577
+:102EA00093A200100E0007C3000000003C0280083F
+:102EB00034420100AC5000E093A30010240A00014A
+:102EC000A04300D50A000B4593A200102402000184
+:102ED000154200093C0380008C6202780440FFFE2A
+:102EE0008F82001CAC62024024020002A0620244F5
+:102EF0003C021000AC6202789222000B2403000214
+:102F0000304200FF144300720000000096220008C7
+:102F1000304300FF24020082146200402402008437
+:102F20003C028000344901008D22000C95230006EC
+:102F3000000216023063FFFF3045003F24020027E5
+:102F400010A2000FAF83001428A200281040000830
+:102F5000240200312402002110A2000924020025CD
+:102F600010A20007938200190A000BBD00000000A8
+:102F700010A20007938200190A000BBD0000000098
+:102F80000E000777012020210A000C3D0000000000
+:102F90003C0380008C6202780440FFFE8F82001C9C
+:102FA000AC62024024020002A06202443C02100013
+:102FB000AC6202780A000C3D000000009523000678
+:102FC000912400058D25000C8D2600108D270018FA
+:102FD0008D28001C8D290020244200013C0108009E
+:102FE000A42356C63C010800A02456C53C01080095
+:102FF000AC2556CC3C010800AC2656D03C0108005C
+:10300000AC2756D83C010800AC2856DC3C0108002F
+:10301000AC2956E00A000C3DA38200191462000A94
+:10302000240200813C02800834420100944500EAF9
+:10303000922600058F84001C30A5FFFF30C600FFDC
+:103040000A000BFE3C0760211462005C00000000D7
+:103050009222000A304300FF306200201040000737
+:10306000306200403C02800834420100944500EA8E
+:103070008F84001C0A000BFC24060040104000074F
+:10308000000316003C02800834420100944500EA27
+:103090008F84001C0A000BFC24060041000216036A
+:1030A000044100463C02800834420100944500EA95
+:1030B0008F84001C2406004230A5FFFF3C076019E6
+:1030C0000E000901000000000A000C3D0000000095
+:1030D0009222000B24040016304200FF1044000628
+:1030E0003C0680009222000B24030017304200FFB0
+:1030F000144300320000000034C5010090A2000B10
+:10310000304200FF1444000B000080218CA20020FC
+:103110008CA400202403FF800043102400021140EF
+:103120003084007F004410253C032000004310251C
+:10313000ACC2083094A2000800021400000214037C
+:10314000044200012410000194A2000830420080D3
+:103150005040001A0200A82194A20008304220002A
+:10316000504000160200A8218CA300183C021C2D20
+:10317000344219ED106200110200A8213C0208003F
+:103180008C4200D4104000053C0280082403000457
+:1031900034420100A04300FC3C028008344201009C
+:1031A000944500EA8F84001C2406000630A5FFFF2A
+:1031B0000E0009013C0760210200A8210E00093918
+:1031C000000000009222000A304200081040000473
+:1031D00002A010210E0013790000000002A01021AF
+:1031E0008FBF00308FB5002C8FB400288FB3002420
+:1031F0008FB200208FB1001C8FB0001803E00008D0
+:1032000027BD00382402FF80008220243C02900069
+:1032100034420007008220253C028000AC4400209C
+:103220003C0380008C6200200440FFFE0000000090
+:1032300003E00008000000003C0380002402FF803F
+:10324000008220243462000700822025AC64002024
+:103250008C6200200440FFFE0000000003E0000834
+:103260000000000027BDFFD8AFB3001CAFB10014B1
+:10327000AFB00010AFBF0020AFB200183C1180000B
+:103280003C0280088E32002034530100AE2400201E
+:10329000966300EA000514003C074000004738250B
+:1032A00000A08021000030210E0009013065FFFFE1
+:1032B000240200A1160200022402FFFFA2620009FC
+:1032C000AE3200208FBF00208FB3001C8FB20018D9
+:1032D0008FB100148FB0001003E0000827BD002854
+:1032E0003C0280082403000527BDFFE834420100AA
+:1032F000A04300FCAFBF00103C0280008C420100E4
+:10330000240500A1004020210E000C67AF82001CA4
+:103310003C0380008C6202780440FFFE8F82001C18
+:103320008FBF001027BD0018AC62024024020002CB
+:10333000A06202443C021000AC62027803E0000884
+:103340000000000027BDFFE83C068000AFBF001072
+:1033500034C7010094E20008304400FF3883008243
+:10336000388200842C6300012C4200010062182581
+:103370001060002D24020083938200195040003B0E
+:103380008FBF00103C020800904256CC8CC4010054
+:103390003C06080094C656C63045003F38A30032AC
+:1033A00038A2003F2C6300012C4200010062182566
+:1033B000AF84001CAF860014A380001914600007BE
+:1033C00000E020212402002014A2001200000000CE
+:1033D0003402FFFF14C2000F00000000240200208E
+:1033E00014A2000500E028218CE300142402FFFF52
+:1033F0005062000B8FBF00103C040800248456C0AC
+:10340000000030210E000706240700010A000CD638
+:103410008FBF00100E000777000000008FBF001064
+:103420000A00093927BD001814820004240200850F
+:103430008CC501040A000CE1000020211482000662
+:103440002482FF808CC50104240440008FBF00103B
+:103450000A00016727BD0018304200FF2C4200021D
+:1034600010400004240200228FBF00100A000B2726
+:1034700027BD0018148200048F8200248FBF001023
+:103480000A000C8627BD00188C42000C1040001E5C
+:1034900000E0282190E300092402001814620003D0
+:1034A000240200160A000CFC240300081462000722
+:1034B00024020017240300123C02800834420080DA
+:1034C000A04300090A000D0994A7000854620007F0
+:1034D00094A700088F82FF942404FFFE9043000508
+:1034E00000641824A043000594A7000890A6001BC0
+:1034F0008CA4000094A500068FBF001000073C00BC
+:103500000A0008DC27BD00188FBF001003E0000888
+:1035100027BD00188F8500243C04800094A2002A57
+:103520008CA30034000230C02402FFF000C210243B
+:1035300000621821AC83003C8CA200303C03800068
+:10354000AC8200383C02005034420010AC620030C3
+:103550000000000000000000000000008C6200007D
+:10356000304200201040FFFD30C20008104000062D
+:103570003C0280008C620408ACA200208C62040C27
+:103580000A000D34ACA200248C430400ACA300203C
+:103590008C420404ACA200243C0300203C028000C6
+:1035A000AC4300303C0480008C8200300043102487
+:1035B0001440FFFD8F8600243C020040AC820030A6
+:1035C00094C3002A94C2002894C4002C94C5002EF1
+:1035D00024630001004410213064FFFFA4C20028CE
+:1035E00014850002A4C3002AA4C0002A03E0000836
+:1035F000000000008F84002427BDFFE83C05800404
+:1036000024840010AFBF00100E000E472406000AED
+:103610008F840024948200129483002E3042000F85
+:10362000244200030043180424027FFF0043102BB0
+:1036300010400002AC8300000000000D0E000D13CE
+:10364000000000008F8300248FBF001027BD0018EA
+:10365000946200149463001A3042000F00021500B7
+:10366000006218253C02800003E00008AC4300A083
+:103670008F8300243C028004944400069462001A64
+:103680008C650000A4640016004410233042FFFF44
+:103690000045102B03E00008384200018F8400240D
+:1036A0003C0780049486001A8C85000094E2000692
+:1036B000A482001694E3000600C310233042FFFFEB
+:1036C0000045102B384200011440FFF8A483001677
+:1036D00003E00008000000008F8400243C02800406
+:1036E000944200069483001A8C850000A482001680
+:1036F000006210233042FFFF0045102B38420001CA
+:103700005040000D8F850024006030213C0780046C
+:1037100094E20006A482001694E3000600C310237E
+:103720003042FFFF0045102B384200011440FFF8E3
+:10373000A48300168F8500243C03800034620400BB
+:103740008CA40020AF820020AC6400388CA200243E
+:10375000AC62003C3C020005AC62003003E00008B3
+:10376000ACA000048F8400243C0300068C8200047B
+:1037700000021140004310253C038000AC62003081
+:103780000000000000000000000000008C6200004B
+:10379000304200101040FFFD34620400AC80000491
+:1037A00003E00008AF8200208F86002427BDFFE0E1
+:1037B000AFB10014AFB00010AFBF00188CC300044D
+:1037C0008CC500248F820020309000FF94C4001A22
+:1037D00024630001244200202484000124A7002047
+:1037E000ACC30004AF820020A4C4001AACC70024FC
+:1037F00004A100060000882104E2000594C2001A1A
+:103800008CC2002024420001ACC2002094C2001AE5
+:1038100094C300282E040001004310262C4200010E
+:10382000004410245040000594C2001A24020001F4
+:10383000ACC2000894C2001A94C300280010202BC8
+:10384000004310262C4200010044102514400007BC
+:10385000000000008CC20008144000042402001084
+:103860008CC300041462000F8F8500240E000DA786
+:10387000241100018F820024944300289442001AEE
+:1038800014430003000000000E000D1300000000B0
+:10389000160000048F8500240E000D840000000037
+:1038A0008F85002494A2001E94A4001C24420001D1
+:1038B0003043FFFF14640002A4A2001EA4A0001E57
+:1038C0001200000A3C02800494A2001494A3001A7F
+:1038D0003042000F00021500006218253C028000F3
+:1038E000AC4300A00A000E1EACA0000894420006E3
+:1038F00094A3001A8CA40000A4A200160062102356
+:103900003042FFFF0044102B384200011040000DF0
+:1039100002201021006030213C07800494E2000660
+:10392000A4A2001694E3000600C310233042FFFF58
+:103930000044102B384200011440FFF8A4A30016E5
+:10394000022010218FBF00188FB100148FB000101B
+:1039500003E0000827BD002003E00008000000008D
+:103960008F82002C3C03000600021140004310250A
+:103970003C038000AC62003000000000000000004A
+:10398000000000008C620000304200101040FFFD7B
+:1039900034620400AF82002803E00008AF80002CEE
+:1039A00003E000080000102103E000080000000010
+:1039B0003084FFFF30A5FFFF0000182110800007B2
+:1039C000000000003082000110400002000420428C
+:1039D000006518210A000E3D0005284003E000089C
+:1039E0000060102110C0000624C6FFFF8CA200005A
+:1039F00024A50004AC8200000A000E4724840004C1
+:103A000003E000080000000010A0000824A3FFFF4E
+:103A1000AC86000000000000000000002402FFFF50
+:103A20002463FFFF1462FFFA2484000403E000080B
+:103A3000000000003C0280083442008024030001A2
+:103A4000AC43000CA4430010A4430012A443001490
+:103A500003E00008A44300168F82002427BDFFD88E
+:103A6000AFB3001CAFB20018AFB10014AFB000107C
+:103A7000AFBF00208C47000C248200802409FF8007
+:103A80003C08800E3043007F008080213C0A80008B
+:103A9000004920240068182130B100FF30D200FF17
+:103AA00010E000290000982126020100AD44002CFE
+:103AB000004928243042007F004820219062000005
+:103AC00024030050304200FF1443000400000000B3
+:103AD000AD45002C948200EA3053FFFF0E000D84A8
+:103AE000000000008F8200248F83002000112C0032
+:103AF0009442001E001224003484000100A22825F4
+:103B00003C02400000A22825AC7000008FBF0020BE
+:103B1000AC6000048FB20018AC7300088FB10014C1
+:103B2000AC60000C8FB3001CAC6400108FB00010B0
+:103B3000AC60001424040001AC60001827BD00280C
+:103B40000A000DB8AC65001C8FBF00208FB3001CAD
+:103B50008FB200188FB100148FB0001003E000087E
+:103B600027BD00283C06800034C201009043000FAE
+:103B7000240200101062000E2865001110A000073A
+:103B800024020012240200082405003A10620006F4
+:103B90000000302103E0000800000000240500358B
+:103BA0001462FFFC000030210A000E6400000000D7
+:103BB0008CC200748F83FF9424420FA003E000089E
+:103BC000AC62000C27BDFFE8AFBF00100E0003423F
+:103BD000240500013C0480088FBF0010240200016E
+:103BE00034830080A462001227BD00182402000163
+:103BF00003E00008A080001A27BDFFE0AFB2001864
+:103C0000AFB10014AFB00010AFBF001C30B2FFFF67
+:103C10000E000332008088213C028008345000806E
+:103C20009202000924030004304200FF1443000CF8
+:103C30003C028008124000082402000A0E000E5BBD
+:103C400000000000920200052403FFFE0043102440
+:103C5000A202000524020012A20200093C02800810
+:103C600034420080022020210E00033DA0400027A6
+:103C700016400003022020210E000EBF00000000AD
+:103C800002202021324600FF8FBF001C8FB2001897
+:103C90008FB100148FB00010240500380A000E64A4
+:103CA00027BD002027BDFFE0AFBF001CAFB200184A
+:103CB000AFB10014AFB000100E00033200808021BD
+:103CC0000E000E5B000000003C02800834450080BE
+:103CD00090A2000924120018305100FF1232000394
+:103CE0000200202124020012A0A2000990A20005D7
+:103CF0002403FFFE004310240E00033DA0A2000594
+:103D00000200202124050020163200070000302187
+:103D10008FBF001C8FB200188FB100148FB000103D
+:103D20000A00034227BD00208FBF001C8FB200187D
+:103D30008FB100148FB00010240500390A000E6402
+:103D400027BD002027BDFFE83C028000AFB0001077
+:103D5000AFBF0014344201009442000C2405003629
+:103D60000080802114400012304600FF0E00033214
+:103D7000000000003C02800834420080240300124E
+:103D8000A043000990430005346300100E000E5B51
+:103D9000A04300050E00033D020020210200202167
+:103DA0000E000342240500200A000F3C0000000022
+:103DB0000E000E64000000000E00033202002021FD
+:103DC0003C0280089043001B2405FF9F0200202135
+:103DD000006518248FBF00148FB00010A043001B93
+:103DE0000A00033D27BD001827BDFFE0AFBF001844
+:103DF000AFB10014AFB0001030B100FF0E000332BD
+:103E0000008080213C02800824030012344200809C
+:103E10000E000E5BA04300090E00033D02002021AE
+:103E200002002021022030218FBF00188FB1001422
+:103E30008FB00010240500350A000E6427BD002055
+:103E40003C0480089083000E9082000A1443000B0B
+:103E5000000028218F82FF942403005024050001D4
+:103E600090420000304200FF1443000400000000B4
+:103E70009082000E24420001A082000E03E00008A0
+:103E800000A010213C0380008C6201F80440FFFE7A
+:103E900024020002AC6401C0A06201C43C02100014
+:103EA00003E00008AC6201F827BDFFE0AFB20018E4
+:103EB0003C128008AFB10014AFBF001CAFB00010BF
+:103EC00036510080922200092403000A304200FF8C
+:103ED0001443003E000000008E4300048E22003890
+:103EE000506200808FBF001C92220000240300500B
+:103EF000304200FF144300253C0280008C42014008
+:103F00008E4300043642010002202821AC43001CED
+:103F10009622005C8E2300383042FFFF00021040E2
+:103F200000621821AE23001C8E4300048E2400384A
+:103F30009622005C006418233042FFFF0003184300
+:103F4000000210400043102A10400006000000004C
+:103F50008E4200048E230038004310230A000FAA6B
+:103F6000000220439622005C3042FFFF0002204006
+:103F70003C0280083443010034420080ACA4002C91
+:103F8000A040002424020001A062000C0E000F5E7D
+:103F900000000000104000538FBF001C3C02800056
+:103FA0008C4401403C0380008C6201F80440FFFE19
+:103FB00024020002AC6401C0A06201C43C021000F3
+:103FC000AC6201F80A0010078FBF001C92220009A2
+:103FD00024030010304200FF144300043C02800020
+:103FE0008C4401400A000FEE0000282192220009B3
+:103FF00024030016304200FF14430006240200147C
+:10400000A22200093C0280008C4401400A001001F9
+:104010008FBF001C8E2200388E23003C00431023EB
+:10402000044100308FBF001C92220027244200016F
+:10403000A2220027922200272C42000414400016DE
+:104040003C1080009222000924030004304200FF4B
+:10405000144300093C0280008C4401408FBF001CC7
+:104060008FB200188FB100148FB000102405009398
+:104070000A000ECC27BD00208C440140240500938B
+:104080008FBF001C8FB200188FB100148FB00010CA
+:104090000A000F4827BD00208E0401400E000332A5
+:1040A000000000008E4200042442FFFFAE420004E4
+:1040B0008E22003C2442FFFFAE22003C0E00033D56
+:1040C0008E0401408E0401408FBF001C8FB2001887
+:1040D0008FB100148FB00010240500040A000342C1
+:1040E00027BD00208FB200188FB100148FB00010D0
+:1040F00003E0000827BD00203C0680008CC2018838
+:104100003C038008346500809063000E00021402B6
+:10411000304400FF306300FF1464000E3C0280084E
+:1041200090A20026304200FF104400098F82FF94C5
+:10413000A0A400262403005090420000304200FF5B
+:1041400014430006000000000A0005A18CC4018091
+:104150003C02800834420080A044002603E00008AE
+:104160000000000027BDFFE030E700FFAFB20018FD
+:10417000AFBF001CAFB10014AFB0001000809021A1
+:1041800014E0000630C600FF000000000000000D33
+:10419000000000000A001060240001163C038008A3
+:1041A0009062000E304200FF14460023346200800B
+:1041B00090420026304200FF1446001F000000001D
+:1041C0009062000F304200FF1446001B0000000008
+:1041D0009062000A304200FF144600038F90FF9463
+:1041E0000000000D8F90FF948F82FF983C1180009B
+:1041F000AE05003CAC450000A066000A0E0003328C
+:104200008E240100A20000240E00033D8E24010034
+:104210003C0380008C6201F80440FFFE240200028F
+:10422000AC7201C0A06201C43C021000AC6201F893
+:104230000A0010618FBF001C000000000000000D8C
+:10424000000000002400013F8FBF001C8FB2001847
+:104250008FB100148FB0001003E0000827BD0020CC
+:104260008F83FF943C0280008C44010034420100A3
+:104270008C65003C9046001B0A00102724070001B3
+:104280003C0280089043000E9042000A0043102632
+:10429000304200FF03E000080002102B27BDFFE0C2
+:1042A0003C028008AFB10014AFB00010AFBF0018DF
+:1042B0003450008092020005240300303042003068
+:1042C00014430085008088218F8200248C42000CDA
+:1042D000104000828FBF00180E000D840000000007
+:1042E0008F860020ACD100009202000892030009E2
+:1042F000304200FF00021200306300FF004310252F
+:10430000ACC200049202004D000216000002160327
+:1043100004410005000000003C0308008C630048D5
+:104320000A00109F3C1080089202000830420040B2
+:10433000144000030000182192020027304300FFC0
+:104340003C108008361100809222004D00031E00B0
+:10435000304200FF0002140000621825ACC30008C0
+:104360008E2400308F820024ACC4000C8E250034D3
+:104370009443001E3C02C00BACC50010006218251F
+:104380008E22003800002021ACC200148E22003C96
+:10439000ACC200180E000DB8ACC3001C8E020004A5
+:1043A0008F8400203C058000AC8200008E2200201B
+:1043B000AC8200048E22001CAC8200088E220058C1
+:1043C0008CA3007400431021AC82000C8E22002CC0
+:1043D000AC8200108E2200408E23004400021400A4
+:1043E00000431025AC8200149222004D240300806B
+:1043F000304200FF1443000400000000AC800018AD
+:104400000A0010E38F8200248E23000C2402000196
+:104410001062000E2402FFFF92220008304200408A
+:104420001440000A2402FFFF8E23000C8CA20074AB
+:10443000006218233C0208000062102414400002AD
+:10444000000028210060282100051043AC820018DC
+:104450008F820024000020219443001E3C02C00CE7
+:10446000006218258F8200200E000DB8AC43001C9E
+:104470003C038008346201008C4200008F850020DC
+:10448000346300808FBF0018ACA20000ACA0000411
+:104490008C6400488F8200248FB10014ACA4000803
+:1044A000ACA0000CACA00010906300059446001E68
+:1044B0003C02400D00031E0000C23025ACA30014D6
+:1044C0008FB00010ACA0001824040001ACA6001CA2
+:1044D0000A000DB827BD00208FBF00188FB100144F
+:1044E0008FB0001003E0000827BD00203C028000D0
+:1044F0009443007C3C02800834460100308400FF75
+:104500003065FFFF2402000524A34650A0C4000C20
+:104510005482000C3065FFFF90C2000D2C42000752
+:104520001040000724A30A0090C3000D24020014C9
+:104530000062100400A210210A00111F3045FFFF85
+:104540003065FFFF3C0280083442008003E0000831
+:10455000A44500143C03800834680080AD05003891
+:10456000346701008CE2001C308400FF00A210239D
+:104570001840000330C600FF24A2FFFCACE2001C80
+:1045800030820001504000083C0380088D02003C4E
+:1045900000A2102304410012240400058C620004D0
+:1045A00010A2000F3C0380088C62000414A2001EBD
+:1045B000000000003C0208008C4200D8304200207D
+:1045C000104000093C0280083462008090630008BB
+:1045D0009042004C144300043C0280082404000470
+:1045E0000A00110900000000344300803442010039
+:1045F000A040000C24020001A462001410C0000AB4
+:104600003C0280008C4401003C0380008C6201F875
+:104610000440FFFE24020002AC6401C0A06201C499
+:104620003C021000AC6201F803E00008000000004A
+:1046300027BDFFE800A61823AFBF00101860008058
+:10464000308800FF3C02800834470080A0E000244E
+:1046500034440100A0E000278C82001C00A210233B
+:1046600004400056000000008CE2003C94E3005C33
+:104670008CE4002C004530233063FFFF00C3182179
+:104680000083202B1080000400E018218CE2002C15
+:104690000A00117800A2102194E2005C3042FFFF72
+:1046A00000C2102100A21021AC62001C3C02800854
+:1046B000344400809482005C8C83001C3042FFFFF5
+:1046C0000002104000A210210043102B10400004F3
+:1046D000000000008C82001C0A00118B3C06800840
+:1046E0009482005C3042FFFF0002104000A21021C3
+:1046F0003C06800834C3010034C70080AC82001C33
+:10470000A060000CACE500388C62001C00A21023F5
+:104710001840000224A2FFFCAC62001C3102000120
+:10472000104000083C0380088CE2003C00A21023EB
+:1047300004410012240400058CC2000410A20010E1
+:104740008FBF00108C62000414A2004F8FBF0010B6
+:104750003C0208008C4200D8304200201040000A81
+:104760003C02800834620080906300089042004C54
+:10477000144300053C028008240400048FBF00108D
+:104780000A00110927BD001834430080344201009B
+:10479000A040000C24020001A46200143C0280002E
+:1047A0008C4401003C0380008C6201F80440FFFE51
+:1047B000240200020A0011D8000000008CE2001C54
+:1047C000004610230043102B54400001ACE5001CB0
+:1047D00094E2005C3042FFFF0062102B144000079F
+:1047E0002402000294E2005C8CE3001C3042FFFFD4
+:1047F00000621821ACE3001C24020002ACE5003882
+:104800000E000F5EA082000C1040001F8FBF001032
+:104810003C0280008C4401003C0380008C6201F863
+:104820000440FFFE24020002AC6401C0A06201C487
+:104830003C021000AC6201F80A0011F08FBF0010BA
+:1048400031020010104000108FBF00103C028008A1
+:10485000344500808CA3001C94A2005C00661823E1
+:104860003042FFFF006218213C023FFF3444FFFF4B
+:104870000083102B544000010080182100C3102138
+:10488000ACA2001C8FBF001003E0000827BD001879
+:1048900027BDFFE800C0402100A63023AFBF0010B5
+:1048A00018C00026308A00FF3C028008344900808E
+:1048B0008D24001C8D23002C008820230064182BDD
+:1048C0001060000F344701008CE2002000461021E8
+:1048D000ACE200208CE200200044102B1440000BBE
+:1048E0003C023FFF8CE2002000441023ACE2002099
+:1048F0009522005C3042FFFF0A0012100082202146
+:10490000ACE00020008620213C023FFF3443FFFF43
+:104910000064102B54400001006020213C028008FC
+:104920003442008000851821AC43001CA0400024C4
+:10493000A04000270A0012623C03800831420010A8
+:10494000104000433C0380083C06800834C40080CB
+:104950008C82003C004810235840003E34660080A2
+:104960009082002424420001A0820024908200242E
+:104970003C0308008C630024304200FF0043102BEE
+:10498000144000688FBF001034C201008C42001C2C
+:1049900000A2102318400063000000008CC3000434
+:1049A0009482005C006818233042FFFF0003184324
+:1049B000000210400043102A1040000500000000D3
+:1049C0008CC20004004810230A0012450002104364
+:1049D0009482005C3042FFFF000210403C068008D9
+:1049E000AC82002C34C5008094A2005C8CA4002C06
+:1049F00094A3005C3042FFFF00021040008220219F
+:104A00003063FFFF0083202101041021ACA2001CB1
+:104A10008CC2000434C60100ACC2001C2402000297
+:104A20000E000F5EA0C2000C1040003E8FBF0010B1
+:104A30003C0280008C4401003C0380008C6201F841
+:104A40000440FFFE240200020A001292000000004F
+:104A500034660080ACC50038346401008C82001CD0
+:104A600000A210231840000224A2FFFCAC82001C0C
+:104A7000314200015040000A3C0380088CC2003CD7
+:104A800000A2102304430014240400058C620004D7
+:104A900014A200033C0380080A00128424040005C9
+:104AA0008C62000414A2001F8FBF00103C0208009B
+:104AB0008C4200D8304200201040000A3C0280089E
+:104AC00034620080906300089042004C144300055B
+:104AD0003C028008240400048FBF00100A00110962
+:104AE00027BD00183443008034420100A040000C70
+:104AF00024020001A46200143C0280008C440100E6
+:104B00003C0380008C6201F80440FFFE2402000296
+:104B1000AC6401C0A06201C43C021000AC6201F8A8
+:104B20008FBF001003E0000827BD001827BDFFE875
+:104B30003C0A8008AFBF0010354900808D22003C40
+:104B400000C04021308400FF004610231840009D23
+:104B500030E700FF354701002402000100A63023A2
+:104B6000A0E0000CA0E0000DA522001418C0002455
+:104B7000308200108D23001C8D22002C0068182329
+:104B80000043102B1040000F000000008CE20020BA
+:104B900000461021ACE200208CE200200043102BE4
+:104BA0001440000B3C023FFF8CE200200043102326
+:104BB000ACE200209522005C3042FFFF0A0012C1E7
+:104BC00000621821ACE00020006618213C023FFF83
+:104BD0003446FFFF00C3102B5440000100C01821D1
+:104BE0003C0280083442008000651821AC43001C60
+:104BF000A0400024A04000270A00130F3C038008B7
+:104C0000104000403C0380088D22003C00481023E7
+:104C10005840003D34670080912200242442000166
+:104C2000A1220024912200243C0308008C6300246C
+:104C3000304200FF0043102B1440009A8FBF001039
+:104C40008CE2001C00A21023184000960000000017
+:104C50008D4300049522005C006818233042FFFF5A
+:104C600000031843000210400043102A10400005C2
+:104C7000012020218D420004004810230A0012F276
+:104C8000000210439522005C3042FFFF00021040FA
+:104C90003C068008AC82002C34C5008094A2005CE5
+:104CA0008CA4002C94A3005C3042FFFF0002104053
+:104CB000008220213063FFFF0083182101031021AF
+:104CC000ACA2001C8CC2000434C60100ACC2001CA3
+:104CD000240200020E000F5EA0C2000C1040007102
+:104CE0008FBF00103C0280008C4401003C03800018
+:104CF0008C6201F80440FFFE240200020A0013390E
+:104D00000000000034670080ACE500383466010024
+:104D10008CC2001C00A210231840000224A2FFFC39
+:104D2000ACC2001C30820001504000083C038008E7
+:104D30008CE2003C00A2102304430051240400052F
+:104D40008C62000410A2003E3C0380088C620004C8
+:104D500054A200548FBF00103C0208008C4200D8BF
+:104D600030420020104000063C028008346200807F
+:104D7000906300089042004C104300403C028008C1
+:104D80003443008034420100A040000C24020001A2
+:104D9000A46200143C0280008C4401003C038000AB
+:104DA0008C6201F80440FFFE24020002AC6401C0E2
+:104DB000A06201C43C021000AC6201F80A00137743
+:104DC0008FBF001024020005A120002714E2000A72
+:104DD0003C038008354301009062000D2C42000620
+:104DE000504000053C0380089062000D2442000101
+:104DF000A062000D3C03800834670080ACE50038F9
+:104E0000346601008CC2001C00A21023184000026E
+:104E100024A2FFFCACC2001C308200015040000AFA
+:104E20003C0380088CE2003C00A2102304410014E3
+:104E3000240400058C62000414A200033C038008D3
+:104E40000A00136E240400058C62000414A20015ED
+:104E50008FBF00103C0208008C4200D83042002076
+:104E60001040000A3C028008346200809063000811
+:104E70009042004C144300053C02800824040004C6
+:104E80008FBF00100A00110927BD001834430080AD
+:104E900034420100A040000C24020001A46200146E
+:104EA0008FBF001003E0000827BD00183C0B8008EE
+:104EB00027BDFFE83C028000AFBF00103442010074
+:104EC000356A00809044000A356901008C45001461
+:104ED0008D4800389123000C308400FF0105102319
+:104EE0001C4000B3306700FF2CE20006504000B1C8
+:104EF0008FBF00102402000100E2300430C2000322
+:104F00005440000800A8302330C2000C144000A117
+:104F100030C20030144000A38FBF00100A00143BC1
+:104F20000000000018C00024308200108D43001CD7
+:104F30008D42002C006818230043102B1040000FF6
+:104F4000000000008D22002000461021AD2200202C
+:104F50008D2200200043102B1440000B3C023FFF29
+:104F60008D22002000431023AD2200209542005CDA
+:104F70003042FFFF0A0013AF00621821AD2000206D
+:104F8000006618213C023FFF3446FFFF00C3102B90
+:104F90005440000100C018213C02800834420080C7
+:104FA00000651821AC43001CA0400024A04000274D
+:104FB0000A0013FD3C038008104000403C038008B9
+:104FC0008D42003C004810231840003D34670080AB
+:104FD0009142002424420001A14200249142002475
+:104FE0003C0308008C630024304200FF0043102B78
+:104FF000144000708FBF00108D22001C00A21023EF
+:105000001840006C000000008D6300049542005CB5
+:10501000006818233042FFFF0003184300021040CD
+:105020000043102A10400005014020218D62000439
+:10503000004810230A0013E0000210439542005C70
+:105040003042FFFF000210403C068008AC82002C7A
+:1050500034C5008094A2005C8CA4002C94A3005C56
+:105060003042FFFF00021040008220213063FFFF2A
+:105070000083182101031021ACA2001C8CC2000483
+:1050800034C60100ACC2001C240200020E000F5EF8
+:10509000A0C2000C104000478FBF00103C028000EF
+:1050A0008C4401003C0380008C6201F80440FFFE48
+:1050B000240200020A00142D000000003467008062
+:1050C000ACE50038346601008CC2001C00A210233D
+:1050D0001840000224A2FFFCACC2001C3082000178
+:1050E0005040000A3C0380088CE2003C00A21023E0
+:1050F00004430014240400058C62000414A200037D
+:105100003C0380080A00141F240400058C6200047C
+:1051100014A200288FBF00103C0208008C4200D867
+:10512000304200201040000A3C02800834620080B7
+:10513000906300089042004C144300053C02800834
+:10514000240400048FBF00100A00110927BD0018B5
+:105150003443008034420100A040000C24020001CE
+:10516000A46200143C0280008C4401003C038000D7
+:105170008C6201F80440FFFE24020002AC6401C00E
+:10518000A06201C43C021000AC6201F80A00143BAA
+:105190008FBF00108FBF0010010030210A00115A8C
+:1051A00027BD0018010030210A00129927BD001800
+:1051B0008FBF001003E0000827BD00183C038008E3
+:1051C0003464010024020003A082000C8C620004FD
+:1051D00003E00008AC82001C3C05800834A300807A
+:1051E0009062002734A501002406004324420001F8
+:1051F000A0620027906300273C0208008C42004810
+:10520000306300FF146200043C07602194A500EAAB
+:105210000A00090130A5FFFF03E0000800000000BC
+:1052200027BDFFE8AFBF00103C0280000E00144411
+:105230008C4401803C02800834430100A060000CD3
+:105240008C4200048FBF001027BD001803E0000847
+:10525000AC62001C27BDFFE03C028008AFBF001815
+:10526000AFB10014AFB000103445008034460100E7
+:105270003C0880008D09014090C3000C8CA4003CC8
+:105280008CA200381482003B306700FF9502007C3E
+:1052900090A30027146000093045FFFF2402000599
+:1052A00054E200083C04800890C2000D2442000132
+:1052B000A0C2000D0A00147F3C048008A0C0000DAD
+:1052C0003C048008348201009042000C2403000555
+:1052D000304200FF1443000A24A205DC348300801E
+:1052E000906200272C4200075040000524A20A00CB
+:1052F00090630027240200140062100400A2102111
+:105300003C108008361000803045FFFF012020212E
+:105310000E001444A60500149602005C8E030038AB
+:105320003C1180003042FFFF000210400062182153
+:10533000AE03001C0E0003328E24014092020025B1
+:1053400034420040A20200250E00033D8E2401409D
+:105350008E2401403C0380008C6201F80440FFFE73
+:1053600024020002AC6401C0A06201C43C0210002F
+:10537000AC6201F88FBF00188FB100148FB000101D
+:1053800003E0000827BD00203C0360103C02080039
+:1053900024420174AC62502C8C6250003C048000AA
+:1053A00034420080AC6250003C0208002442547C2D
+:1053B0003C010800AC2256003C020800244254384C
+:1053C0003C010800AC2256043C020002AC840008F8
+:1053D000AC82000C03E000082402000100A0302190
+:1053E0003C1C0800279C56083C0200023C050400B7
+:1053F00000852826008220260004102B2CA5000101
+:105400002C840001000210803C0308002463560035
+:105410000085202500431821108000030000102182
+:10542000AC6600002402000103E000080000000058
+:105430003C1C0800279C56083C0200023C05040066
+:1054400000852826008220260004102B2CA50001B0
+:105450002C840001000210803C03080024635600E5
+:105460000085202500431821108000050000102130
+:105470003C02080024425438AC62000024020001BF
+:1054800003E00008000000003C0200023C030400AE
+:1054900000821026008318262C4200012C63000194
+:1054A000004310251040000B000028213C1C080080
+:1054B000279C56083C0380008C62000824050001EC
+:1054C00000431025AC6200088C62000C00441025DB
+:1054D000AC62000C03E0000800A010213C1C080096
+:1054E000279C56083C0580008CA3000C0004202754
+:1054F000240200010064182403E00008ACA3000C9F
+:105500003C020002148200063C0560008CA208D018
+:105510002403FFFE0043102403E00008ACA208D0DF
+:105520003C02040014820005000000008CA208D098
+:105530002403FFFD00431024ACA208D003E00008C0
+:10554000000000003C02601A344200108C430080CE
+:1055500027BDFFF88C440084AFA3000093A3000094
+:10556000240200041462001AAFA4000493A20001F4
+:105570001040000797A300023062FFFC3C0380004C
+:10558000004310218C4200000A001536AFA200042F
+:105590003062FFFC3C03800000431021AC4400005B
+:1055A000A3A000003C0560008CA208D02403FFFEED
+:1055B0003C04601A00431024ACA208D08FA300045E
+:1055C0008FA2000034840010AC830084AC82008081
+:1055D00003E0000827BD000827BDFFE8AFBF0010AB
+:1055E0003C1C0800279C56083C0280008C43000CA1
+:1055F0008C420004004318243C0200021060001496
+:10560000006228243C0204003C04000210A00005B3
+:10561000006210243C0208008C4256000A00155B10
+:1056200000000000104000073C0404003C02080099
+:105630008C4256040040F809000000000A00156082
+:10564000000000000000000D3C1C0800279C5608CC
+:0C5650008FBF001003E0000827BD001809
+:04565C008008024080
+:1056600080080100800800808008000000000C8095
+:105670000000320008000E9808000EF408000F88A1
+:1056800008001028080010748008010080080080BD
+:04569000800800008E
+:0C5694000A0000280000000000000000D8
+:1056A0000000000D6370362E302E313700000000F0
+:1056B00006001104000000000000000000000000CF
+:1056C000000000000000000038003C000000000066
+:1056D00000000000000000000000000000000020AA
+:1056E00000000000000000000000000000000000BA
+:1056F00000000000000000000000000000000000AA
+:10570000000000000000000021003800000000013F
+:105710000000002B000000000000000400030D400A
+:105720000000000000000000000000000000000079
+:105730000000000000000000100000030000000056
+:105740000000000D0000000D3C020800244259AC8E
+:105750003C03080024635BF4AC4000000043202BB2
+:105760001480FFFD244200043C1D080037BD9FFC4F
+:1057700003A0F0213C100800261000A03C1C0800EB
+:10578000279C59AC0E0002F6000000000000000D3E
+:1057900027BDFFB4AFA10000AFA20004AFA3000873
+:1057A000AFA4000CAFA50010AFA60014AFA700185F
+:1057B000AFA8001CAFA90020AFAA0024AFAB0028FF
+:1057C000AFAC002CAFAD0030AFAE0034AFAF00389F
+:1057D000AFB8003CAFB90040AFBC0044AFBF004819
+:1057E0000E000820000000008FBF00488FBC00445E
+:1057F0008FB900408FB8003C8FAF00388FAE0034B7
+:105800008FAD00308FAC002C8FAB00288FAA002406
+:105810008FA900208FA8001C8FA700188FA6001446
+:105820008FA500108FA4000C8FA300088FA2000486
+:105830008FA1000027BD004C3C1B60188F7A5030B0
+:10584000377B502803400008AF7A000000A01821E1
+:1058500000801021008028213C0460003C0760008B
+:105860002406000810600006348420788C42000072
+:10587000ACE220088C63000003E00008ACE3200CDD
+:105880000A000F8100000000240300403C02600079
+:1058900003E00008AC4320003C0760008F86000452
+:1058A0008CE520740086102100A2182B14600007DC
+:1058B000000028218F8AFDA024050001A1440013C7
+:1058C0008F89000401244021AF88000403E0000810
+:1058D00000A010218F84FDA08F8500049086001306
+:1058E00030C300FF00A31023AF82000403E00008D0
+:1058F000A08000138F84FDA027BDFFE8AFB000108B
+:10590000AFBF001490890011908700112402002875
+:10591000312800FF3906002830E300FF2485002CE1
+:105920002CD00001106200162484001C0E00006EB2
+:10593000000000008F8FFDA03C05600024020204DF
+:1059400095EE003E95ED003C000E5C0031ACFFFF93
+:10595000016C5025ACAA2010520000012402000462
+:10596000ACA22000000000000000000000000000C9
+:105970008FBF00148FB0001003E0000827BD00188F
+:105980000A0000A6000028218F85FDA027BDFFD8B2
+:10599000AFBF0020AFB3001CAFB20018AFB100140E
+:1059A000AFB000100080982190A4001124B0001C1A
+:1059B00024B1002C308300FF386200280E000090D4
+:1059C0002C5200010E00009800000000020020216F
+:1059D0001240000202202821000028210E00006E43
+:1059E000000000008F8DFDA03C0880003C05600099
+:1059F00095AC003E95AB003C02683025000C4C0095
+:105A0000316AFFFF012A3825ACA7201024020202C8
+:105A1000ACA6201452400001240200028FBF0020D7
+:105A20008FB3001C8FB200188FB100148FB000101C
+:105A300027BD002803E00008ACA2200027BDFFE03E
+:105A4000AFB20018AFB10014AFB00010AFBF001C70
+:105A50003C1160008E2320748F82000430D0FFFF41
+:105A600030F2FFFF1062000C2406008F0E00006E63
+:105A7000000000003C06801F0010440034C5FF00F9
+:105A80000112382524040002AE2720100000302126
+:105A9000AE252014AE2420008FBF001C8FB200184A
+:105AA0008FB100148FB0001000C0102103E0000877
+:105AB00027BD002027BDFFE0AFB0001030D0FFFFB2
+:105AC000AFBF0018AFB100140E00006E30F1FFFF41
+:105AD00000102400009180253C036000AC70201071
+:105AE0008FBF00188FB100148FB000102402000483
+:105AF000AC62200027BD002003E000080000102158
+:105B000027BDFFE03C046018AFBF0018AFB1001420
+:105B1000AFB000108C8850002403FF7F34028071E6
+:105B20000103382434E5380C241F00313C1980006F
+:105B3000AC8550003C11800AAC8253BCAF3F0008DA
+:105B40000E00054CAF9100400E00050A3C116000AC
+:105B50000E00007D000000008E3008083C0F570941
+:105B60002418FFF00218602435EEE00035EDF00057
+:105B7000018E5026018D58262D4600012D69000109
+:105B8000AF86004C0E000D09AF8900503C06601630
+:105B90008CC700003C0860148D0500A03C03FFFF8B
+:105BA00000E320243C02535300052FC2108200550D
+:105BB00034D07C00960201F2A780006C10400003F4
+:105BC000A780007C384B1E1EA78B006C960201F844
+:105BD000104000048F8D0050384C1E1EA78C007C96
+:105BE0008F8D005011A000058F83004C240E0020E3
+:105BF000A78E007CA78E006C8F83004C1060000580
+:105C00009785007C240F0020A78F007CA78F006C55
+:105C10009785007C2CB8008153000001240500808A
+:105C20009784006C2C91040152200001240404008C
+:105C30001060000B3C0260008FBF00188FB1001491
+:105C40008FB0001027BD0020A784006CA785007CC2
+:105C5000A380007EA780007403E00008A780009264
+:105C60008C4704382419103C30FFFFFF13F9000360
+:105C700030A8FFFF1100004624030050A380007EDF
+:105C80009386007E50C00024A785007CA780007CFE
+:105C90009798007CA780006CA7800074A780009272
+:105CA0003C010800AC3800800E00078700000000AF
+:105CB0003C0F60008DED0808240EFFF03C0B600ED9
+:105CC000260C0388356A00100000482100002821B6
+:105CD00001AE20243C105709AF8C0010AF8A004859
+:105CE000AF89001810900023AF8500148FBF0018F3
+:105CF0008FB100148FB0001027BD002003E0000812
+:105D0000AF80005400055080014648218D260004D4
+:105D10000A00014800D180219798007CA784006C7C
+:105D2000A7800074A78000923C010800AC38008076
+:105D30000E000787000000003C0F60008DED080892
+:105D4000240EFFF03C0B600E260C0388356A001011
+:105D5000000048210000282101AE20243C105709F2
+:105D6000AF8C0010AF8A0048AF8900181490FFDF95
+:105D7000AF85001424110001AF9100548FBF0018AB
+:105D80008FB100148FB0001003E0000827BD002081
+:105D90000A00017BA383007E3083FFFF8F880040D1
+:105DA0008F87003C000321403C0580003C020050EE
+:105DB000008248253C0660003C0A010034AC040027
+:105DC0008CCD08E001AA58241160000500000000F5
+:105DD0008CCF08E024E7000101EA7025ACCE08E092
+:105DE0008D19001001805821ACB900388D180014AD
+:105DF000ACB8003CACA9003000000000000000007E
+:105E00000000000000000000000000000000000092
+:105E100000000000000000003C0380008C640000D3
+:105E2000308200201040FFFD3C0F60008DED08E047
+:105E30003C0E010001AE18241460FFE100000000D8
+:105E4000AF87003C03E00008AF8B00588F8500400F
+:105E5000240BFFF03C06800094A7001A8CA90024B4
+:105E600030ECFFFF000C38C000EB5024012A402129
+:105E7000ACC8003C8CA400248CC3003C00831023DD
+:105E800018400033000000008CAD002025A2000166
+:105E90003C0F0050ACC2003835EE00103C068000CC
+:105EA000ACCE003000000000000000000000000048
+:105EB00000000000000000000000000000000000E2
+:105EC000000000003C0480008C9900003338002062
+:105ED0001300FFFD30E20008104000173C0980006D
+:105EE0008C880408ACA800108C83040CACA30014AC
+:105EF0003C1900203C188000AF19003094AE001807
+:105F000094AF001C01CF3021A4A6001894AD001A54
+:105F100025A70001A4A7001A94AB001A94AC001E98
+:105F2000118B00030000000003E0000800000000E7
+:105F300003E00008A4A0001A8D2A0400ACAA0010F7
+:105F40008D240404ACA400140A0002183C1900209B
+:105F50008CA200200A0002003C0F00500A0001EE53
+:105F60000000000027BDFFE8AFBF00100E000232A6
+:105F7000000000008F8900408FBF00103C038000AC
+:105F8000A520000A9528000A9527000427BD0018BF
+:105F90003105FFFF30E6000F0006150000A22025A6
+:105FA00003E00008AC6400803C0508008CA50020DC
+:105FB0008F83000C27BDFFE8AFB00010AFBF001407
+:105FC00010A300100000802124040001020430040A
+:105FD00000A6202400C3102450440006261000010F
+:105FE000001018802787FDA41480000A006718217C
+:105FF000261000012E0900025520FFF38F83000CAC
+:10600000AF85000C8FBF00148FB0001003E00008B4
+:1060100027BD00188C6800003C058000ACA8002457
+:106020000E000234261000013C0508008CA500205B
+:106030000A0002592E0900022405000100851804F7
+:106040003C0408008C84002027BDFFC8AFBF00348B
+:1060500000831024AFBE0030AFB7002CAFB60028CD
+:10606000AFB50024AFB40020AFB3001CAFB200182E
+:10607000AFB1001410400051AFB000108F84004049
+:10608000948700069488000A00E8302330D5FFFF8B
+:1060900012A0004B8FBF0034948B0018948C000A20
+:1060A000016C50233142FFFF02A2482B1520000251
+:1060B00002A02021004020212C8F000515E00002C5
+:1060C00000809821241300040E0001C102602021E9
+:1060D0008F87004002609021AF80004494F4000A52
+:1060E000026080211260004E3291FFFF3C1670006A
+:1060F0003C1440003C1E20003C1760008F99005863
+:106100008F380000031618241074004F0283F82BF8
+:1061100017E0003600000000107E00478F86004424
+:1061200014C0003A2403000102031023022320219B
+:106130003050FFFF1600FFF13091FFFF8F870040C6
+:106140003C1100203C108000AE11003094EB000A9E
+:106150003C178000024B5021A4EA000A94E9000A8F
+:1061600094E800043123FFFF3106000F00062D00E4
+:106170000065F025AEFE008094F3000A94F6001846
+:1061800012D30036001221408CFF00148CF4001052
+:1061900003E468210000C02101A4782B029870213B
+:1061A00001CF6021ACED0014ACEC001002B238233A
+:1061B00030F5FFFF16A0FFB88F8400408FBF00347A
+:1061C0008FBE00308FB7002C8FB600288FB500240B
+:1061D0008FB400208FB3001C8FB200188FB1001451
+:1061E0008FB0001003E0000827BD00381477FFCC03
+:1061F0008F8600440E000EE202002021004018218C
+:106200008F86004410C0FFC9020310230270702360
+:106210008F87004001C368210A0002E431B2FFFF0A
+:106220008F86004414C0FFC93C1100203C10800040
+:106230000A0002AEAE1100300E00046602002021FA
+:106240000A0002DB00401821020020210E0009395B
+:10625000022028210A0002DB004018210E0001EE76
+:10626000000000000A0002C702B2382327BDFFC8A1
+:10627000AFB7002CAFB60028AFB50024AFB40020F4
+:10628000AFB3001CAFB20018AFB10014AFB0001034
+:10629000AFBF00300E00011B241300013C047FFF40
+:1062A0003C0380083C0220003C010800AC20007048
+:1062B0003496FFFF34770080345200033C1512C03F
+:1062C000241400013C1080002411FF800E000245C0
+:1062D000000000008F8700488F8B00188F89001402
+:1062E0008CEA00EC8CE800E8014B302B01092823F4
+:1062F00000A6102314400006014B18231440000E82
+:106300003C05800002A3602B1180000B0000000000
+:106310003C0560008CEE00EC8CED00E88CA4180CC1
+:10632000AF8E001804800053AF8D00148F8F0010C3
+:10633000ADF400003C0580008CBF00003BF900017B
+:10634000333800011700FFE13C0380008C6201003C
+:1063500024060C0010460009000000008C680100B3
+:106360002D043080548000103C0480008C690100B2
+:106370002D2331811060000C3C0480008CAA0100A8
+:1063800011460004000020218CA6010024C5FF81D5
+:1063900030A400FF8E0B01000E000269AE0B00243A
+:1063A0000A00034F3C0480008C8D01002DAC3300AB
+:1063B00011800022000000003C0708008CE70098D4
+:1063C00024EE00013C010800AC2E00983C04800043
+:1063D0008C8201001440000300000000566000148D
+:1063E0003C0440008C9F01008C9801000000982123
+:1063F00003F1C82400193940330F007F00EF7025E6
+:1064000001D26825AC8D08308C8C01008C85010090
+:10641000258B0100017130240006514030A3007F1C
+:106420000143482501324025AC8808303C04400037
+:10643000AE0401380A00030E000000008C99010030
+:10644000240F0020AC99002092F80000330300FFD5
+:10645000106F000C241F0050547FFFDD3C048000AF
+:106460008C8401000E00154E000000000A00034F4E
+:106470003C04800000963824ACA7180C0A000327BF
+:106480008F8F00108C8501000E0008F72404008017
+:106490000A00034F3C04800000A4102B24030001D9
+:1064A00010400009000030210005284000A4102BF6
+:1064B00004A00003000318405440FFFC00052840DE
+:1064C0005060000A0004182B0085382B54E00004AB
+:1064D0000003184200C33025008520230003184222
+:1064E0001460FFF9000528420004182B03E000089F
+:1064F00000C310213084FFFF30C600FF3C0780003E
+:106500008CE201B80440FFFE00064C000124302557
+:106510003C08200000C820253C031000ACE00180AE
+:10652000ACE50184ACE4018803E00008ACE301B809
+:106530003C0660008CC5201C2402FFF03083020062
+:10654000308601001060000E00A2282434A500014E
+:106550003087300010E0000530830C0034A50004C3
+:106560003C04600003E00008AC85201C1060FFFDC7
+:106570003C04600034A5000803E00008AC85201C42
+:1065800054C0FFF334A500020A0003B03087300086
+:1065900027BDFFE8AFB00010AFBF00143C0760009C
+:1065A000240600021080001100A080218F83005873
+:1065B0000E0003A78C6400188F8200580000202171
+:1065C000240600018C45000C0E000398000000001A
+:1065D0001600000224020003000010218FBF0014E7
+:1065E0008FB0001003E0000827BD00188CE8201CC5
+:1065F0002409FFF001092824ACE5201C8F870058EE
+:106600000A0003CD8CE5000C3C02600E00804021A6
+:1066100034460100240900180000000000000000BA
+:10662000000000003C0A00503C0380003547020097
+:10663000AC68003834640400AC65003CAC670030E2
+:106640008C6C0000318B00201160FFFD2407FFFFE0
+:106650002403007F8C8D00002463FFFF248400044A
+:10666000ACCD00001467FFFB24C60004000000004E
+:10667000000000000000000024A402000085282B78
+:106680003C0300203C0E80002529FFFF010540212E
+:10669000ADC300301520FFE00080282103E0000892
+:1066A000000000008F82005827BDFFD8AFB3001C48
+:1066B000AFBF0020AFB20018AFB10014AFB00010F0
+:1066C00094460002008098218C5200182CC300814F
+:1066D0008C4800048C4700088C51000C8C49001039
+:1066E000106000078C4A00142CC4000414800013AE
+:1066F00030EB000730C5000310A0001000000000C0
+:106700002410008B02002021022028210E00039873
+:10671000240600031660000224020003000010217A
+:106720008FBF00208FB3001C8FB200188FB10014F0
+:106730008FB0001003E0000827BD00281560FFF1AE
+:106740002410008B3C0C80003C030020241F00011F
+:10675000AD830030AF9F0044000000000000000047
+:10676000000000002419FFF024D8000F031978243A
+:106770003C1000D0AD88003801F0702524CD000316
+:106780003C08600EAD87003C35850400AD8E0030BE
+:10679000000D38823504003C3C0380008C6B000007
+:1067A000316200201040FFFD0000000010E00008F2
+:1067B00024E3FFFF2407FFFF8CA800002463FFFFF2
+:1067C00024A50004AC8800001467FFFB24840004A7
+:1067D0003C05600EACA60038000000000000000080
+:1067E000000000008F8600543C0400203C0780001D
+:1067F000ACE4003054C000060120202102402021DA
+:106800000E0003A7000080210A00041D02002021C1
+:106810000E0003DD01402821024020210E0003A7C5
+:10682000000080210A00041D0200202127BDFFE096
+:10683000AFB200183092FFFFAFB10014AFBF001C21
+:10684000AFB000101640000D000088210A0004932C
+:106850000220102124050003508500278CE5000C40
+:106860000000000D262800013111FFFF24E2002066
+:106870000232802B12000019AF8200588F82004430
+:10688000144000168F8700583C0670003C0320001F
+:106890008CE5000000A62024148300108F84006083
+:1068A000000544023C09800000A980241480FFE90F
+:1068B000310600FF2CCA000B5140FFEB26280001D7
+:1068C000000668803C0E080025CE575801AE6021B6
+:1068D0008D8B0000016000080000000002201021E4
+:1068E0008FBF001C8FB200188FB100148FB0001042
+:1068F00003E0000827BD00200E0003982404008454
+:106900001600FFD88F8700580A000474AF8000601B
+:10691000020028210E0003BF240400018F870058C5
+:106920000A000474AF820060020028210E0003BF39
+:10693000000020210A0004A38F8700580E000404E1
+:10694000020020218F8700580A000474AF82006083
+:1069500030AFFFFF000F19C03C0480008C9001B8DD
+:106960000600FFFE3C1920043C181000AC83018097
+:10697000AC800184AC990188AC9801B80A00047518
+:106980002628000190E2000390E30002000020218D
+:106990000002FE0000033A0000FF2825240600083C
+:1069A0000E000398000000001600FFDC2402000324
+:1069B0008F870058000010210A000474AF82006025
+:1069C00090E8000200002021240600090A0004C308
+:1069D00000082E0090E4000C240900FF308500FF21
+:1069E00010A900150000302190F9000290F8000372
+:1069F000308F00FF94EB000400196E000018740043
+:106A0000000F62000186202501AE5025014B28258C
+:106A10003084FF8B0A0004C32406000A90E30002BE
+:106A200090FF0004000020210003360000DF28252D
+:106A30000A0004C32406000B0A0004D52406008BB8
+:106A4000000449C23127003F000443423C02800059
+:106A500000082040240316802CE60020AC43002CC4
+:106A600024EAFFE02482000114C0000330A900FFE3
+:106A700000801021314700FF000260803C0D800043
+:106A8000240A0001018D20213C0B000E00EA28049D
+:106A9000008B302111200005000538278CCE000026
+:106AA00001C5382503E00008ACC700008CD8000001
+:106AB0000307782403E00008ACCF000027BDFFE007
+:106AC000AFB10014AFB00010AFBF00183C076000BA
+:106AD0008CE408083402F0003C1160003083F000C0
+:106AE000240501C03C04800E000030211062000625
+:106AF000241000018CEA08083149F0003928E00030
+:106B00000008382B000780403C0D0200AE2D081411
+:106B1000240C16803C0B80008E2744000E000F8B47
+:106B2000AD6C002C120000043C02169124050001FB
+:106B3000120500103C023D2C345800E0AE384408E9
+:106B40003C1108008E31007C8FBF00183C066000AD
+:106B500000118540360F16808FB100148FB00010E1
+:106B60003C0E020027BD0020ACCF442003E000080B
+:106B7000ACCE08103C0218DA345800E0AE384408B5
+:106B80003C1108008E31007C8FBF00183C0660006D
+:106B900000118540360F16808FB100148FB00010A1
+:106BA0003C0E020027BD0020ACCF442003E00008CB
+:106BB000ACCE08100A0004EB240500010A0004EB27
+:106BC0000000282124020400A7820024A780001CC2
+:106BD000000020213C06080024C65A582405FFFF67
+:106BE00024890001000440803124FFFF01061821A0
+:106BF0002C87002014E0FFFAAC6500002404040098
+:106C0000A7840026A780001E000020213C06080063
+:106C100024C65AD82405FFFF248D0001000460809B
+:106C200031A4FFFF018658212C8A00201540FFFA6D
+:106C3000AD650000A7800028A7800020A780002263
+:106C4000000020213C06080024C65B582405FFFFF5
+:106C5000249900010004C0803324FFFF030678213B
+:106C60002C8E000415C0FFFAADE500003C05600065
+:106C70008CA73D002403E08F00E31024344601403C
+:106C800003E00008ACA63D002487007F000731C266
+:106C900024C5FFFF000518C2246400013082FFFFF5
+:106CA000000238C0A78400303C010800AC27003047
+:106CB000AF80002C0000282100002021000030219E
+:106CC0002489000100A728213124FFFF2CA81701E7
+:106CD000110000032C8300801460FFF924C600011A
+:106CE00000C02821AF86002C10C0001DA786002AF6
+:106CF00024CAFFFF000A11423C08080025085B581F
+:106D00001040000A00002021004030212407FFFF2E
+:106D1000248E00010004688031C4FFFF01A86021B7
+:106D20000086582B1560FFFAAD87000030A2001FC7
+:106D30005040000800043080240300010043C804D0
+:106D400000041080004878212738FFFF03E0000886
+:106D5000ADF8000000C820212405FFFFAC8500002D
+:106D600003E000080000000030A5FFFF30C6FFFF71
+:106D700030A8001F0080602130E700FF0005294295
+:106D80000000502110C0001D24090001240B000147
+:106D900025180001010B2004330800FF0126782686
+:106DA000390E00202DED00012DC2000101A2182591
+:106DB0001060000D014450250005C880032C4021BF
+:106DC0000100182110E0000F000A20278D040000A8
+:106DD000008A1825AD03000024AD00010000402109
+:106DE0000000502131A5FFFF252E000131C9FFFF12
+:106DF00000C9102B1040FFE72518000103E0000830
+:106E0000000000008D0A0000014440240A0005D162
+:106E1000AC68000027BDFFE830A5FFFF30C6FFFFCC
+:106E2000AFB00010AFBF001430E7FFFF00005021EB
+:106E30003410FFFF0000602124AF001F00C0482174
+:106E4000241800012419002005E0001601E010219B
+:106E50000002F943019F682A0009702B01AE40240B
+:106E600011000017000C18800064102110E00005CC
+:106E70008C4B000000F840040008382301675824B8
+:106E800000003821154000410000402155600016E7
+:106E90003169FFFF258B0001316CFFFF05E1FFEC3D
+:106EA00001E0102124A2003E0002F943019F682A5C
+:106EB0000009702B01AE40241500FFEB000C188078
+:106EC000154600053402FFFF020028210E0005B51B
+:106ED00000003821020010218FBF00148FB0001075
+:106EE00003E0000827BD00181520000301601821E9
+:106EF000000B1C0224080010306A00FF154000053A
+:106F0000306E000F250D000800031A0231A800FFA3
+:106F1000306E000F15C00005307F000325100004FF
+:106F200000031902320800FF307F000317E000055C
+:106F3000386900012502000200031882304800FF72
+:106F4000386900013123000110600004310300FFA3
+:106F5000250A0001314800FF310300FF000C6940A1
+:106F600001A34021240A000110CAFFD53110FFFF00
+:106F7000246E000131C800FF1119FFC638C9000195
+:106F80002D1F002053E0001C258B0001240D000163
+:106F90000A000648240E002051460017258B0001E8
+:106FA00025090001312800FF2D0900205120001281
+:106FB000258B000125430001010D5004014B1024D5
+:106FC000250900011440FFF4306AFFFF3127FFFF5D
+:106FD00010EE000C2582FFFF304CFFFF0000502117
+:106FE0003410FFFF312800FF2D0900205520FFF24B
+:106FF00025430001258B0001014648260A000602B0
+:10700000316CFFFF00003821000050210A000654B7
+:107010003410FFFF27BDFFD8AFB0001030F0FFFFE6
+:10702000AFB10014001039423211FFE000071080A8
+:10703000AFB3001C00B1282330D3FFFFAFB200185C
+:1070400030A5FFFF00809021026030210044202104
+:10705000AFBF00200E0005E03207001F022288218A
+:107060003403FFFF0240202102002821026030216A
+:1070700000003821104300093231FFFF02201021A7
+:107080008FBF00208FB3001C8FB200188FB1001487
+:107090008FB0001003E0000827BD00280E0005E0B7
+:1070A0000000000000408821022010218FBF002036
+:1070B0008FB3001C8FB200188FB100148FB0001076
+:1070C00003E0000827BD0028000424003C03600002
+:1070D000AC603D0810A00002348210063482101605
+:1070E00003E00008AC623D0427BDFFE0AFB0001034
+:1070F000309000FF2E020006AFBF001810400008BD
+:10710000AFB10014001030803C03080024635784A2
+:1071100000C328218CA400000080000800000000AB
+:10712000000020218FBF00188FB100148FB0001015
+:107130000080102103E0000827BD00209791002A5D
+:1071400016200051000020213C020800904200332C
+:107150000A0006BB00000000978D002615A0003134
+:10716000000020210A0006BB2402000897870024A3
+:1071700014E0001A00001821006020212402000100
+:107180001080FFE98FBF0018000429C2004530219C
+:1071900000A6582B1160FFE43C0880003C0720004B
+:1071A000000569C001A76025AD0C00203C038008E4
+:1071B0002402001F2442FFFFAC6000000441FFFDD9
+:1071C0002463000424A5000100A6702B15C0FFF560
+:1071D000000569C00A0006A58FBF00189787001C2C
+:1071E0003C04080024845A58240504000E0006605C
+:1071F00024060001978B002424440001308AFFFFFD
+:107200002569FFFF2D48040000402821150000409B
+:10721000A789002424AC3800000C19C00A0006B964
+:10722000A780001C9787001E3C04080024845AD8BD
+:10723000240504000E00066024060001979900262C
+:10724000244400013098FFFF272FFFFF2F0E04007A
+:107250000040882115C0002CA78F0026A780001EA3
+:107260003A020003262401003084FFFF0E00068D41
+:107270002C4500010011F8C027F00100001021C0CA
+:107280000A0006BB240200089785002E978700227B
+:107290003C04080024845B580E00066024060001AC
+:1072A0009787002A8F89002C2445000130A8FFFF12
+:1072B00024E3FFFF0109302B0040802114C0001897
+:1072C000A783002AA7800022978500300E000F7543
+:1072D00002002021244A05003144FFFF0E00068DE4
+:1072E000240500013C05080094A500320E000F752E
+:1072F00002002021244521003C0208009042003376
+:107300000A0006BB000521C00A0006F3A784001E80
+:1073100024AC3800000C19C00A0006B9A784001C70
+:107320000A00070DA7850022308400FF27BDFFE873
+:107330002C820006AFBF0014AFB000101040001543
+:1073400000A03821000440803C0308002463579CBF
+:10735000010328218CA40000008000080000000028
+:1073600024CC007F000751C2000C59C23170FFFFCE
+:107370002547C40030E5FFFF2784001C02003021B0
+:107380000E0005B52407000197860028020620217B
+:10739000A78400288FBF00148FB0001003E00008FE
+:1073A00027BD00183C0508008CA50030000779C2F5
+:1073B0000E00038125E4DF003045FFFF3C04080098
+:1073C00024845B58240600010E0005B52407000143
+:1073D000978E002A8FBF00148FB0001025CD0001BA
+:1073E00027BD001803E00008A78D002A0007C9C2C6
+:1073F0002738FF00001878C231F0FFFF3C04080076
+:1074000024845AD802002821240600010E0005B564
+:1074100024070001978D0026260E0100000E84002F
+:1074200025AC00013C0B6000A78C0026AD603D0838
+:1074300036040006000030213C0760008CE23D0469
+:10744000305F000617E0FFFD24C9000100061B00A5
+:10745000312600FF006440252CC50004ACE83D0443
+:1074600014A0FFF68FBF00148FB0001003E00008D7
+:1074700027BD0018000751C22549C8002406000195
+:10748000240700013C04080024845A580E0005B566
+:107490003125FFFF978700248FBF00148FB00010A5
+:1074A00024E6000127BD001803E00008A786002499
+:1074B0003C0660183C090800252900FCACC9502C8A
+:1074C0008CC850003C0580003C020002350700805B
+:1074D000ACC750003C04080024841FE03C030800B3
+:1074E00024631F98ACA50008ACA2000C3C01080066
+:1074F000AC2459A43C010800AC2359A803E00008BF
+:107500002402000100A030213C1C0800279C59AC3B
+:107510003C0C04003C0B0002008B3826008C4026FB
+:107520002CE200010007502B2D050001000A4880C5
+:107530003C030800246359A4004520250123182199
+:107540001080000300001021AC660000240200013E
+:1075500003E00008000000003C1C0800279C59AC18
+:107560003C0B04003C0A0002008A3026008B3826BF
+:107570002CC200010006482B2CE5000100094080C8
+:107580003C030800246359A4004520250103182169
+:1075900010800005000010213C0C0800258C1F986D
+:1075A000AC6C00002402000103E0000800000000B1
+:1075B0003C0900023C080400008830260089382677
+:1075C0002CC30001008028212CE400010083102539
+:1075D0001040000B000030213C1C0800279C59ACD7
+:1075E0003C0A80008D4E00082406000101CA68256F
+:1075F000AD4D00088D4C000C01855825AD4B000C9D
+:1076000003E0000800C010213C1C0800279C59AC76
+:107610003C0580008CA6000C0004202724020001F9
+:1076200000C4182403E00008ACA3000C3C020002D4
+:107630001082000B3C0560003C070400108700032B
+:107640000000000003E00008000000008CA908D042
+:10765000240AFFFD012A402403E00008ACA808D05A
+:107660008CA408D02406FFFE0086182403E000083E
+:10767000ACA308D03C05601A34A600108CC300806F
+:1076800027BDFFF88CC50084AFA3000093A40000C1
+:107690002402001010820003AFA5000403E00008DC
+:1076A00027BD000893A7000114E0001497AC000266
+:1076B00097B800023C0F8000330EFFFC01CF682119
+:1076C000ADA50000A3A000003C0660008CC708D058
+:1076D0002408FFFE3C04601A00E82824ACC508D04A
+:1076E0008FA300048FA200003499001027BD00086A
+:1076F000AF22008003E00008AF2300843C0B800031
+:10770000318AFFFC014B48218D2800000A00080C3B
+:10771000AFA8000427BDFFE8AFBF00103C1C080065
+:10772000279C59AC3C0580008CA4000C8CA2000462
+:107730003C0300020044282410A0000A00A31824DF
+:107740003C0604003C0400021460000900A610245A
+:107750001440000F3C0404000000000D3C1C080015
+:10776000279C59AC8FBF001003E0000827BD00180C
+:107770003C0208008C4259A40040F80900000000B7
+:107780003C1C0800279C59AC0A0008358FBF00102C
+:107790003C0208008C4259A80040F8090000000093
+:1077A0000A00083B000000003C0880008D0201B880
+:1077B0000440FFFE35090180AD2400003C031000A9
+:1077C00024040040AD250004A1240008A1260009DE
+:1077D000A527000A03E00008AD0301B83084FFFFCD
+:1077E0000080382130A5FFFF000020210A00084555
+:1077F000240600803087FFFF8CA400002406003898
+:107800000A000845000028218F8300788F860070C9
+:107810001066000B008040213C07080024E75B68ED
+:10782000000328C000A710218C440000246300013D
+:10783000108800053063000F5466FFFA000328C06B
+:1078400003E00008000010213C07080024E75B6CFF
+:1078500000A7302103E000088CC200003C03900028
+:1078600034620001008220253C038000AC640020CB
+:107870008C65002004A0FFFE0000000003E000086B
+:10788000000000003C0280003443000100832025FA
+:1078900003E00008AC44002027BDFFE0AFB10014B6
+:1078A0003091FFFFAFB00010AFBF001812200013DF
+:1078B00000A080218CA20000240400022406020003
+:1078C0001040000F004028210E0007250000000096
+:1078D00000001021AE000000022038218FBF0018E8
+:1078E0008FB100148FB0001000402021000028212B
+:1078F000000030210A00084527BD00208CA20000AE
+:10790000022038218FBF00188FB100148FB00010F3
+:107910000040202100002821000030210A000845F5
+:1079200027BD002000A010213087FFFF8CA5000498
+:107930008C4400000A000845240600068F83FD9C45
+:1079400027BDFFE8AFBF0014AFB00010906700087C
+:10795000008010210080282130E600400000202116
+:1079600010C000088C5000000E0000BD0200202155
+:10797000020020218FBF00148FB000100A000548BC
+:1079800027BD00180E0008A4000000000E0000BD76
+:1079900002002021020020218FBF00148FB00010B0
+:1079A0000A00054827BD001827BDFFE0AFB0001052
+:1079B0008F90FD9CAFBF001CAFB20018AFB1001498
+:1079C00092060001008088210E00087230D2000467
+:1079D00092040005001129C2A6050000348300406E
+:1079E000A20300050E00087C022020210E00054A9B
+:1079F0000220202124020001AE02000C02202821D6
+:107A0000A602001024040002A602001224060200AE
+:107A1000A60200140E000725A60200161640000F4D
+:107A20008FBF001C978C00743C0B08008D6B007896
+:107A30002588FFFF3109FFFF256A0001012A382B45
+:107A400010E00006A78800743C0F6006240E0016A4
+:107A500035ED0010ADAE00508FBF001C8FB2001886
+:107A60008FB100148FB0001003E0000827BD002084
+:107A700027BDFFE0AFB10014AFBF0018AFB00010DA
+:107A80001080000400A088212402008010820007DA
+:107A9000000000000000000D8FBF00188FB100141F
+:107AA0008FB0001003E0000827BD00200E00087210
+:107AB00000A020218F86FD9C0220202190C500057A
+:107AC0000E00087C30B000FF2403003E1603FFF1D7
+:107AD0003C0680008CC401780480FFFE34C801405D
+:107AE000240900073C071000AD11000002202021EE
+:107AF000A10900048FBF00188FB100148FB00010CF
+:107B0000ACC701780A0008C527BD002027BDFFE0EB
+:107B1000AFB00010AFBF0018AFB100143C10800030
+:107B20008E110020000000000E00054AAE04002067
+:107B3000AE1100208FBF00188FB100148FB000105D
+:107B400003E0000827BD00203084FFFF00803821BB
+:107B50002406003500A020210A0008450000282145
+:107B60003084FFFF008038212406003600A0202149
+:107B70000A0008450000282127BDFFD0AFB500242A
+:107B80003095FFFFAFB60028AFB40020AFBF002C88
+:107B9000AFB3001CAFB20018AFB10014AFB000100B
+:107BA00030B6FFFF12A000270000A0218F920058DE
+:107BB0008E4300003C0680002402004000033E0289
+:107BC00000032C0230E4007F006698241482001D1C
+:107BD00030A500FF8F8300682C68000A1100001098
+:107BE0008F8D0044000358803C0C0800258C57B84A
+:107BF000016C50218D4900000120000800000000A8
+:107C000002D4302130C5FFFF0E0008522404008446
+:107C1000166000028F920058AF8000688F8D00447C
+:107C20002659002026980001032090213314FFFFDD
+:107C300015A00004AF9900580295202B1480FFDC9A
+:107C400000000000028010218FBF002C8FB600289A
+:107C50008FB500248FB400208FB3001C8FB20018A2
+:107C60008FB100148FB0001003E0000827BD003072
+:107C70002407003414A70149000000009247000EB9
+:107C80008F9FFDA08F90FD9C24181600A3E700197C
+:107C90009242000D3C0880003C07800CA3E20018D3
+:107CA000964A00123C0D60003C117FFFA60A005C62
+:107CB000964400103623FFFF240200053099FFFF91
+:107CC000AE1900548E46001CAD1800288CEF000041
+:107CD0008DAE444801E6482601C93021AE06003881
+:107CE0008E05003824CB00013C0E7F00AE05003C21
+:107CF0008E0C003CAFEC0004AE0B00208E13002075
+:107D0000AE13001CA3E0001BAE03002CA3E2001284
+:107D10008E4A001424130050AE0A00348E0400343E
+:107D2000AFE400148E590018AE1900489258000CA8
+:107D3000A218004E920D000835AF0020A20F0008D7
+:107D40008E090018012E282434AC4000AE0C001817
+:107D5000920B0000317200FF1253027F2403FF8058
+:107D60003C04080024845BE80E0008AA0000000020
+:107D70003C1108008E315BE80E00087202202021C1
+:107D80002405000424080001A2050025022020216A
+:107D90000E00087CA20800053C0580008CB001782C
+:107DA0000600FFFE8F92005834AE0140240F0002FF
+:107DB0003C091000ADD10000A1CF0004ACA90178AE
+:107DC0000A000962AF8000682CAD003751A0FF9413
+:107DD0008F8D0044000580803C110800263157E05B
+:107DE000021178218DEE000001C0000800000000A3
+:107DF0002411000414B1008C3C0780003C080800EA
+:107E00008D085BE88F86FD9CACE800208E4500085D
+:107E10008F99FDA0240D0050ACC500308E4C000899
+:107E2000ACCC00508E4B000CACCB00348E43001019
+:107E3000ACC300388E4A0010ACCA00548E42001405
+:107E4000ACC2003C8E5F0018AF3F00048E50001C97
+:107E5000ACD0002090C40000309800FF130D024AFF
+:107E6000000000008CC400348CD00030009030231F
+:107E700004C000F12404008C126000EE2402000310
+:107E80000A000962AF8200682419000514B900666F
+:107E90003C0580003C0808008D085BE88F86FD9C4F
+:107EA000ACA800208E4C00048F8AFDA0240720007F
+:107EB000ACCC001C924B000824120008A14B001906
+:107EC0008F82005890430009A14300188F85005805
+:107ED00090BF000A33E400FF1092001028890009C7
+:107EE000152000BA240E0002240D0020108D000B76
+:107EF000340780002898002117000008240740005C
+:107F000024100040109000053C0700012419008057
+:107F1000109900023C070002240740008CC20018A0
+:107F20003C03FF00004350240147F825ACDF001854
+:107F300090B2000BA0D200278F8300589464000CED
+:107F4000108001FE000000009467000C3C1F8000C0
+:107F50002405FFBFA4C7005C9063000E2407000443
+:107F6000A0C300088F820058904A000FA0CA0009E1
+:107F70008F8900588D3200108FE400740244C823AA
+:107F8000ACD900588D300014ACD0002C95380018B6
+:107F9000330DFFFFACCD00409531001A322FFFFFAB
+:107FA000ACCF00448D2E001CACCE00489128000EB2
+:107FB000A0C8000890CC000801855824126001B6C2
+:107FC000A0CB00088F9200580A000962AF870068B2
+:107FD0002406000614A600143C0E80003C0F080086
+:107FE0008DEF5BE88F85FD98ADCF00208E4900189E
+:107FF0008F86FD9C8F8BFDA0ACA900008CC800383B
+:1080000024040005ACA800048CCC003C1260008164
+:10801000AD6C00000A000962AF84006824110007FB
+:1080200010B1004B240400063C05080024A55BE8C1
+:108030000E000881240400818F9200580013102B39
+:108040000A000962AF820068241F002314BFFFF6F4
+:108050003C0C80003C0508008CA55BE88F8BFDA0E4
+:10806000AD8500208F91FD9C8E4600042564002084
+:1080700026450014AE260028240600030E000F81BA
+:10808000257000308F87005802002021240600034D
+:108090000E000F8124E500083C04080024845BE8FE
+:1080A0000E0008AA0000000092230000240A0050DD
+:1080B000306200FF544AFFE18F9200580E000F6CAF
+:1080C000000000000A000A6A8F920058240800335A
+:1080D00014A800323C0380003C1108008E315BE89C
+:1080E0008F8FFDA0AC7100208E420008240D002867
+:1080F0008F89FD9CADE200308E4A000C24060009F9
+:10810000ADEA00348E5F0010ADFF00388E440014DD
+:10811000ADE400208E590018ADF900248E58001CE3
+:10812000ADF80028A1ED00118E4E00041260003160
+:10813000AD2E00288F9200580A000962AF860068B1
+:10814000240D002214ADFFB8000000002404000735
+:108150003C1008008E105BE83C188000AF10002037
+:108160005660FEAEAF8400683C04080024845BE8DF
+:108170000E0008AA241300508F84FD9C90920000EA
+:10818000325900FF1333014B000000008F9200585A
+:10819000000020210A000962AF8400683C05080045
+:1081A00024A55BE80E000858240400810A000A6A2E
+:1081B0008F92005802D498213265FFFF0E000852BA
+:1081C000240400840A0009628F920058108EFF5325
+:1081D000240704002887000310E00179241100041B
+:1081E000240F0001548FFF4D240740000A000A228B
+:1081F000240701003C05080024A55BE80E0008A444
+:10820000240400828F920058000030210A00096285
+:10821000AF8600683C04080024845BE88CC2003808
+:108220000E0008AA8CC3003C8F9200580A000AC0B6
+:1082300000002021240400823C05080024A55BE8FE
+:108240000E0008A4000000008F92005800001021CA
+:108250000A000962AF8200688E5000048F91FD9C75
+:108260003C078000ACF00020922C00050200282181
+:10827000318B0002156001562404008A8F92FDA004
+:108280002404008D9245001B30A6002014C001502C
+:1082900002002821922E00092408001231C900FF93
+:1082A0001128014B240400810E00087202002021D5
+:1082B0009258001B240F000402002021370D0042B9
+:1082C000A24D001B0E00087CA22F00253C0580005B
+:1082D0008CA401780480FFFE34B90140241F000201
+:1082E000AF300000A33F00048F9200583C101000F4
+:1082F000ACB001780A000A6B0013102B8E500004FA
+:108300008F91FD9C3C038000AC700020922A0005F8
+:108310000200282131420002144000172404008A80
+:10832000922C00092412000402002821318B00FF46
+:1083300011720011240400810E0008720200202135
+:108340008F89FDA0240800122405FFFE912F001B39
+:108350000200202135EE0020A12E001BA2280009DA
+:108360009226000500C538240E00087CA2270005CF
+:1083700002002821000020210E0009330000000027
+:108380000A000A6A8F9200588E4C00043C07800055
+:108390003C10080026105BE8ACEC00203C01080013
+:1083A000AC2C5BE8924B0003317100041220013BBE
+:1083B0008F84FD9C24020006A0820009924F001BBE
+:1083C000240EFFC031E9003F012E4025A08800089F
+:1083D0009245000330A6000114C0013200000000E5
+:1083E0008E420008AE0200083C0208008C425BF09E
+:1083F000104001318F90FDA0000219C28F8DFD9CAD
+:10840000A603000C8E4A000C24180001240400145A
+:10841000AE0A002C8E420010AE02001C965F0016C1
+:10842000A61F003C96590014A619003EADB8000CDA
+:10843000A5B80010A5B80012A5B80014A5B800167C
+:1084400012600144A2040011925100033232000272
+:108450002E5300018F920058266200080A0009621C
+:10846000AF8200688E4400043C1980003C068008FE
+:10847000AF2400208E45000890D80000240D005045
+:10848000331100FF122D009C2407008824060009E8
+:108490000E000845000000000A000A6A8F9200588A
+:1084A0008E5000043C0980003C118008AD30002053
+:1084B0009228000024050050310400FF10850110AF
+:1084C0002407008802002021000028210E00084512
+:1084D0002406000E922D00002418FF80020028219F
+:1084E00001B8802524040004240600300E0007256E
+:1084F000A23000000A000A6A8F9200588E500004D1
+:108500008F91FDA03C028000AC500020923F001BE8
+:1085100033F900101320006C240700810200202191
+:10852000000028212406001F0E000845000000005E
+:108530000A000A6A8F9200588E44001C0E00085DE3
+:1085400000000000104000E3004048218F880058E0
+:1085500024070089012020218D05001C240600012C
+:108560000E000845000000000A000A6A8F920058B9
+:10857000964900023C10080026105BE831280004F0
+:10858000110000973C0460008E4E001C3C0F8000E0
+:10859000ADEE00203C010800AC2E5BE896470002DF
+:1085A00030E40001148000E6000000008E42000468
+:1085B000AE0200083C1008008E105BF0120000ECC8
+:1085C0003C0F80008F92FD9C241000018E4E0018FD
+:1085D0008F8DFDA08F9FFD9801CF4825AE490018D3
+:1085E000A2400005AE50000C3C0808008D085BF06E
+:1085F0008F840058A6500010000839C2A6500012FF
+:10860000A6500014A6500016A5A7000C8C8C0008DC
+:108610008F8B00588F8A0058ADAC002C8D63000CF6
+:1086200024070002ADA3001C91460010A1A6001172
+:108630008F82005890450011A3E500088F990058DB
+:1086400093380012A258004E8F910058922F0013B9
+:10865000A1AF00128F920058964E0014A5AE003CB8
+:1086600096490016A5A9003E8E480018ADA8001432
+:108670005660FD6AAF8700683C05080024A55BE8EA
+:108680000E000881000020218F9200580000382140
+:108690000A000962AF8700683C05080024A55BE872
+:1086A0000E0008A4240400828F9200580A000A4D8C
+:1086B000000038210E000F6C000000008F9200585F
+:1086C0000A000AC0000020210E00087202002021CA
+:1086D0009223001B02002021346A00100E00087C47
+:1086E000A22A001B000038210200202100002821BE
+:1086F0000A000BA52406001F9242000C305F000107
+:1087000013E0000300000000964A000EA4CA002CEB
+:10871000924B000C316300025060000600003821CB
+:108720008E470014964C0012ACC7001CA4CC001A53
+:10873000000038210A000B7F240600093C050800D0
+:1087400024A55BE80E0008A42404008B8F92005837
+:108750000A000A4D0013382B3C0C08008D8C5BE896
+:1087600024DFFFFE25930100326B007F016790211B
+:1087700002638824AD110028AE4600E0AE4000E45C
+:108780000A0009B3AE5F001CACC000543C0D0800E9
+:108790008DAD5BE83C18800C37090100ACED00287A
+:1087A0008E510014AD3100E08E4F0014AD2F00E467
+:1087B0008E4E001025C7FFFE0A0009F4AD27001CED
+:1087C0005491FDD6240740000A000A222407100015
+:1087D0000E00092D000000000A000A6A8F9200585E
+:1087E0008C83442C3C12DEAD3651BEEF3C010800B8
+:1087F000AC205BE810710062000000003C196C6264
+:1088000037387970147800082404000297850074C2
+:108810009782006C2404009200A2F82B13E0001948
+:1088200002002821240400020E00069524050200FF
+:108830003C068000ACC200203C010800AC225BE892
+:108840001040000D8F8C0058240A002824040003D7
+:10885000918B0010316300FF546A00012404000171
+:108860000E0000810000000010400004240400837A
+:108870000A000BC28F920058240400833C050800B4
+:1088800024A55BE80E000881000000008F920058CC
+:108890000013382B0A000962AF8700680A000B49F1
+:1088A000240200128E4400080E00085D0000000043
+:1088B0000A000B55AE0200083C05080024A55BE841
+:1088C0000E000858240400878F9200580A000B728B
+:1088D0000013102B240400040E000695240500301C
+:1088E0001440002A004048218F8800582407008344
+:1088F000012020218D05001C0A000BB32406000175
+:108900008F8300788F8600701066FEEE000038219D
+:108910003C07080024E75B6C000320C00087282187
+:108920008CAE000011D0005D246F000131E3000F18
+:108930005466FFFA000320C00A000B8C00003821A7
+:108940008E4400040E00085D000000000A000BC801
+:10895000AE0200083C05080024A55BE80E0008A450
+:10896000240400828F9200580A000B72000010212C
+:108970003C05080024A55BE80A000C7C2404008761
+:108980008C83442C0A000C5B3C196C628F88005865
+:108990003C0780083C0C8000240B0050240A000196
+:1089A000AD820020A0EB0000A0EA000191030004CA
+:1089B000A0E3001891040005A0E400199106000648
+:1089C0003C04080024845B6CA0E6001A91020007B6
+:1089D0003C06080024C65B68A0E2001B9105000865
+:1089E000A0E5001C911F0009A0FF001D9119000ABD
+:1089F000A0F9001E9118000BA0F8001F9112000CA6
+:108A0000A0F200209111000DA0F100219110000EA4
+:108A1000A0F00022910F000FA0EF0023910E001094
+:108A2000A0EE0024910D0011A0ED0025950C00147E
+:108A3000A4EC0028950B00168F8A00708F920078A6
+:108A4000A4EB002A95030018000A10C02545000178
+:108A5000A4E3002C8D1F001C0044C0210046C82147
+:108A600030A5000FAF3F0000AF09000010B20006B4
+:108A7000AF850070000038218D05001C01202021E9
+:108A80000A000BB32406000124AD000131A7000F3A
+:108A9000AF8700780A000CF9000038213C06080076
+:108AA00024C65B680086902100003821ACA000003D
+:108AB0000A000B8CAE4000003C0482013C036000C5
+:108AC00034820E02AC603D68AF80009803E000087D
+:108AD000AC623D6C27BDFFE8AFB000103090FFFFE7
+:108AE000001018422C620041AFBF00141440000275
+:108AF00024040080240300403C010800AC300060E6
+:108B00003C010800AC2300640E000F7500602821B2
+:108B1000244802BF2409FF8001092824001039805D
+:108B2000001030408FBF00148FB0001000A720212C
+:108B300000861821AF8300803C010800AC25005856
+:108B40003C010800AC24005C03E0000827BD0018CD
+:108B5000308300FF30C6FFFF30E400FF3C08800098
+:108B60008D0201B80440FFFE000354000144382583
+:108B70003C09600000E920253C031000AD050180A0
+:108B8000AD060184AD04018803E00008AD0301B81F
+:108B90008F8500583C0A6012354800108CAC0004E8
+:108BA0003C0D600E35A60010318B00062D690001CA
+:108BB000AD0900C48CA70004ACC731808CA20008AA
+:108BC00094A40002ACC231848CA3001C0460000396
+:108BD000A784009003E00008000000008CAF00189C
+:108BE000ACCF31D08CAE001C03E00008ACCE31D449
+:108BF0008F8500588F87FF288F86FF308CAE00044A
+:108C00003C0F601235E80010ACEE00788CAD000827
+:108C1000ACED007C8CAC0010ACCC004C8CAB000CF0
+:108C2000ACCB004894CA00543C0208008C4200447B
+:108C300025490001A4C9005494C400543083FFFFA7
+:108C400010620017000000003C0208008C42004047
+:108C5000A4C200528CA30018ACE300308CA2001414
+:108C6000ACE2002C8CB90018ACF900388CB80014B8
+:108C700024050001ACF800348D0600BC50C5001975
+:108C80008D0200B48D0200B8A4E2004894E40048CC
+:108C9000A4E4004A94E800EA03E000083102FFFF80
+:108CA0003C0208008C420024A4C00054A4C200521C
+:108CB0008CA30018ACE300308CA20014ACE2002CB2
+:108CC0008CB90018ACF900388CB8001424050001E8
+:108CD000ACF800348D0600BC54C5FFEB8D0200B823
+:108CE0008D0200B4A4E2004894E40048A4E4004AE1
+:108CF00094E800EA03E000083102FFFF8F86005885
+:108D00003C0480008CC900088CC80008000929C0F8
+:108D1000000839C0AC87002090C30007306200040F
+:108D20001040003EAF85009490CB0007316A0008E8
+:108D30001140003D8F87FF2C8CCD000C8CCE001491
+:108D400001AE602B11800036000000008CC2000CC8
+:108D5000ACE200708CCB00188F85FF288F88FF3025
+:108D6000ACEB00748CCA00102402FFF8ACAA00D847
+:108D70008CC9000CAD0900608CC4001CACA400D0F0
+:108D800090E3007C0062C824A0F9007C90D8000722
+:108D9000330F000811E000040000000090ED007C9B
+:108DA00035AC0001A0EC007C90CF000731EE000153
+:108DB00011C000060000000090E3007C241800347D
+:108DC00034790002A0F9007CACB800DC90C2000746
+:108DD0003046000210C000040000000090E8007C53
+:108DE00035040004A0E4007C90ED007D3C0B600E97
+:108DF000356A001031AC003FA0EC007D8D4931D4C4
+:108E00003127000110E00002240E0001A0AE00098D
+:108E100094AF00EA03E0000831E2FFFF8F87FF2CE8
+:108E20000A000DAF8CC200140A000DB0ACE0007057
+:108E30008F8C005827BDFFD8AFB3001CAFB200180D
+:108E4000AFB00010AFBF0020AFB10014918F00157C
+:108E50003C13600E3673001031EB000FA38B009CA7
+:108E60008D8F00048D8B0008959F0012959900103E
+:108E70009584001A9598001E958E001C33EDFFFF17
+:108E8000332AFFFF3089FFFF3308FFFF31C7FFFFA1
+:108E90003C010800AC2D00243C010800AC29004432
+:108EA0003C010800AC2A0040AE683178AE67317CE6
+:108EB00091850015959100163C12601236520010F3
+:108EC00030A200FF3230FFFFAE623188AE5000B4F6
+:108ED00091830014959F0018240600010066C804C1
+:108EE00033F8FFFFAE5900B8AE5800BC918E0014A5
+:108EF000AF8F00843C08600631CD00FFAE4D00C04E
+:108F0000918A00159584000E3C07600A314900FFE4
+:108F1000AF8B00883084FFFFAE4900C835110010C8
+:108F20000E000D1034F004103C0208008C4200606A
+:108F30003C0308008C6300643C0608008CC60058A3
+:108F40003C0508008CA5005C8F8400808FBF00204A
+:108F5000AE23004CAE65319CAE030054AE4500DC40
+:108F6000AE6231A0AE6331A4AE663198AE22004845
+:108F70008FB3001CAE0200508FB10014AE4200E06F
+:108F8000AE4300E4AE4600D88FB000108FB2001898
+:108F90000A00057D27BD0028978500929783007CF5
+:108FA00027BDFFE8AFB0001000A3102BAFBF001427
+:108FB000240400058F900058104000552409000239
+:108FC0000E0006958F850080AF8200942404000374
+:108FD0001040004F240900023C0680000E00008172
+:108FE000ACC2002024070001240820001040004DDE
+:108FF00024040005978E00928F8AFF2C24090050CC
+:1090000025C50001A7850092A14900003C0D08007C
+:109010008DAD0064240380008F84FF28000D66005E
+:10902000AD4C0018A5400006954B000A8F85FF3017
+:109030002402FF8001633024A546000A915F000AE4
+:109040000000482103E2C825A159000AA0A0000899
+:10905000A140004CA08000D5961800029783009094
+:109060003C020004A49800EA960F00022418FFBFF7
+:1090700025EE2401A48E00BE8E0D0004ACAD00448C
+:109080008E0C0008ACAC0040A4A00050A4A000547A
+:109090008E0B000C240C0030AC8B00288E060010C8
+:1090A000AC860024A480003EA487004EA487005014
+:1090B000A483003CAD420074AC8800D8ACA800602A
+:1090C000A08700FC909F00D433F9007FA09900D4C2
+:1090D000909000D402187824A08F00D4914E007C88
+:1090E00035CD0001A14D007C938B009CAD480070F4
+:1090F000AC8C00DCA08B00D68F8800888F87008422
+:10910000AC8800C4AC8700C8A5400078A540007AB0
+:109110008FBF00148FB000100120102103E0000861
+:1091200027BD00188F8500940E0007258F860080CC
+:109130000A000E9F2409000227BDFFE0AFB0001017
+:109140008F900058AFB10014AFBF00188E09000413
+:109150000E00054A000921C08E0800048F84FF28F4
+:109160008F82FF30000839C03C068000ACC7002069
+:10917000948500EA904300131460001C30B1FFFF97
+:109180008F8CFF2C918B0008316A00401540000B3A
+:10919000000000008E0D0004022030218FBF001857
+:1091A0008FB100148FB00010240400220000382179
+:1091B000000D29C00A000D2F27BD00200E000098C9
+:1091C000000000008E0D0004022030218FBF001827
+:1091D0008FB100148FB00010240400220000382149
+:1091E000000D29C00A000D2F27BD00200E000090A1
+:1091F000000000008E0D0004022030218FBF0018F7
+:109200008FB100148FB00010240400220000382118
+:10921000000D29C00A000D2F27BD002027BDFFE04B
+:10922000AFB200183092FFFFAFB00010AFBF001C0C
+:10923000AFB100141240001E000080218F8600583C
+:109240008CC500002403000600053F02000514023F
+:1092500030E4000714830016304500FF2CA80006F8
+:1092600011000040000558803C0C0800258C58BCBB
+:10927000016C50218D490000012000080000000011
+:109280008F8E0098240D000111CD005024020002A1
+:10929000AF820098260900013130FFFF24C800206A
+:1092A0000212202B010030211480FFE5AF88005806
+:1092B000020010218FBF001C8FB200188FB1001464
+:1092C0008FB0001003E0000827BD00209387007EC8
+:1092D00054E00034000030210E000DE700000000D3
+:1092E0008F8600580A000EFF240200018F87009825
+:1092F0002405000210E50031240400130000282199
+:1093000000003021240700010E000D2F0000000096
+:109310000A000F008F8600588F83009824020002F5
+:109320001462FFF6240400120E000D9A00000000E3
+:109330008F85009400403021240400120E000D2F70
+:10934000000038210A000F008F8600588F83009894
+:109350002411000310710029241F0002107FFFCE8A
+:1093600026090001240400100000282100003021FB
+:109370000A000F1D240700018F91009824060002A7
+:109380001626FFF9240400100E000E410000000014
+:10939000144000238F9800588F8600580A000EFF53
+:1093A00024020003240400140E000D2F00002821C5
+:1093B0008F8600580A000EFF240200020E000EA93C
+:1093C000000000000A000F008F8600580E000D3FBD
+:1093D00000000000241900022404001400002821C9
+:1093E0000000302100003821AF9900980E000D2FA9
+:1093F000000000000A000F008F8600580E000D5775
+:10940000000000008F8500942419000200403021E4
+:1094100024040010000038210A000F56AF9900986C
+:109420000040382124040010970F0002000028217A
+:109430000E000D2F31E6FFFF8F8600580A000F0047
+:10944000AF9100988F84FF2C3C077FFF34E6FFFF2D
+:109450008C8500182402000100A61824AC83001893
+:1094600003E00008A08200053084FFFF30A5FFFF65
+:109470001080000700001821308200011040000217
+:1094800000042042006518211480FFFB00052840DD
+:1094900003E000080060102110C000070000000079
+:1094A0008CA2000024C6FFFF24A50004AC820000AB
+:1094B00014C0FFFB2484000403E000080000000047
+:1094C00010A0000824A3FFFFAC86000000000000ED
+:1094D000000000002402FFFF2463FFFF1462FFFA74
+:1094E0002484000403E0000800000000000411C010
+:1094F00003E000082442024027BDFFE8AFB000109F
+:1095000000808021AFBF00140E000F9600A0202124
+:1095100000504821240AFF808FBF00148FB0001034
+:10952000012A30243127007F3C08800A3C042100B6
+:1095300000E8102100C428253C03800027BD001846
+:10954000AC650024AF820038AC400000AC6500245C
+:1095500003E00008AC4000403C0D08008DAD005811
+:1095600000056180240AFF8001A45821016C482174
+:10957000012A30243127007F3C08800C3C04210064
+:1095800000E8102100C428253C038000AC650028B9
+:10959000AF82003403E00008AC40002430A5FFFF98
+:1095A0003C0680008CC201B80440FFFE3C086015F8
+:1095B00000A838253C031000ACC40180ACC0018475
+:1095C000ACC7018803E00008ACC301B83C0D08003B
+:1095D0008DAD005800056180240AFF8001A4582148
+:1095E000016C4021010A4824000931403107007F05
+:1095F00000C728253C04200000A418253C02800058
+:10960000AC43083003E00008AF80003427BDFFE81A
+:10961000AFB0001000808021AFBF00140E000F9685
+:1096200000A0202100504821240BFF80012B502452
+:10963000000A39403128007F3C0620008FBF00140B
+:109640008FB0001000E8282534C2000100A21825C0
+:109650003C04800027BD0018AC83083003E00008FC
+:10966000AF8000383C0580088CA700603C0680086D
+:109670000087102B144000112C8340008CA8006040
+:109680002D0340001060000F240340008CC90060CF
+:109690000089282B14A00002008018218CC30060D0
+:1096A00000035A42000B30803C0A0800254A59202A
+:1096B00000CA202103E000088C8200001460FFF340
+:1096C0002403400000035A42000B30803C0A08008B
+:1096D000254A592000CA202103E000088C8200009E
+:1096E0003C05800890A60008938400AB24C20001CA
+:1096F000304200FF3043007F1064000C0002382726
+:10970000A0A200083C0480008C85017804A0FFFE24
+:109710008F8A00A0240900023C081000AC8A014096
+:10972000A089014403E00008AC8801780A00101BFE
+:1097300030E2008027BDFFD8AFB200188F9200A49E
+:10974000AFBF0020AFB3001CAFB00010AFB100142A
+:109750008F9300348E5900283C1000803C0EFFEFA0
+:10976000AE7900008E580024A260000A35CDFFFFBC
+:10977000AE7800049251002C3C0BFF9F356AFFFF2E
+:10978000A271000C8E6F000C3C080040A271000B0F
+:1097900001F06025018D4824012A382400E8302595
+:1097A000AE66000C8E450004AE6000183C0400FF5D
+:1097B000AE6500148E43002C3482FFFFA6600008C3
+:1097C0000062F824AE7F00108E5900088F9000A030
+:1097D000964E0012AE7900208E51000C31D83FFF1A
+:1097E00000187980AE7100248E4D001401F06021C4
+:1097F00031CB0001AE6D00288E4A0018000C41C22A
+:10980000000B4B80AE6A002C8E46001C01093821EB
+:10981000A667001CAE660030964500028E4400200C
+:10982000A665001EAE64003492430033306200042B
+:1098300054400006924700003C0280083443010077
+:109840008C7F00D0AE7F0030924700008F860038BA
+:10985000A0C700309245003330A4000250800007BA
+:10986000925100018F880038240BFF80910A00304C
+:10987000014B4825A1090030925100018F9000381A
+:10988000240CFFBF2404FFDFA21100318F8D0038AC
+:109890003C1880083711008091AF003C31EE007F0A
+:1098A000A1AE003C8F890038912B003C016C502404
+:1098B000A12A003C8F9F00388E68001493E6003C7C
+:1098C0002D0700010007114000C4282400A218251C
+:1098D000A3E3003C8F87003896590012A4F90032A8
+:1098E0008E450004922E007C30B0000300107823D7
+:1098F00031ED000300AD102131CC000215800002D3
+:1099000024460034244600303C0280083443008062
+:10991000907F007C00BFC824333800041700000289
+:1099200024C2000400C010218F98003824190002BE
+:10993000ACE20034A3190000924F003F8F8E003834
+:109940003C0C8008358B0080A1CF00018F9100383E
+:10995000924D003F8E440004A62D0002956A005CE3
+:109960000E000FF43150FFFF00024B800209382532
+:109970003C08420000E82825AE2500048E4400384B
+:109980008F850038ACA400188E460034ACA6001CAD
+:10999000ACA0000CACA00010A4A00014A4A0001661
+:1099A000A4A00020A4A00022ACA000248E62001479
+:1099B00050400001240200018FBF00208FB3001C23
+:1099C0008FB200188FB100148FB00010ACA2000845
+:1099D0000A00101327BD002827BDFFC83C058008DA
+:1099E00034A40080AFBF0034AFBE0030AFB7002C4E
+:1099F000AFB60028AFB50024AFB40020AFB3001C51
+:109A0000AFB20018AFB10014AFB00010948300786B
+:109A10009482007A104300512405FFFF0080F0215A
+:109A20000A0011230080B821108B004D8FBF003435
+:109A30008F8600A03C1808008F18005C2411FF805E
+:109A40003C1680000306782101F18024AED0002C62
+:109A500096EE007A31EC007F3C0D800E31CB7FFF1B
+:109A6000018D5021000B4840012AA82196A4000036
+:109A70003C0808008D0800582405FF8030953FFF02
+:109A800001061821001539800067C8210325F82434
+:109A90003C02010003E290253338007F3C11800C2A
+:109AA000AED20028031190219250000D320F000415
+:109AB00011E0003702E0982196E3007A96E8007AF8
+:109AC00096E5007A2404800031077FFF24E300013B
+:109AD00030627FFF00A4F82403E2C825A6F9007ACB
+:109AE00096E6007A3C1408008E94006030D67FFF22
+:109AF00012D400C1000000008E5800188F8400A00E
+:109B000002A028212713FFFF0E000FCEAE53002C1A
+:109B100097D5007897D4007A12950010000028217C
+:109B20003C098008352401003C0A8008914800085F
+:109B3000908700D53114007F30E400FF0284302B81
+:109B400014C0FFB9268B0001938E00AB268C000158
+:109B5000008E682115ACFFB78F8600A08FBF003440
+:109B60008FBE00308FB7002C8FB600288FB5002431
+:109B70008FB400208FB3001C8FB200188FB1001477
+:109B80008FB0001000A0102103E0000827BD0038AE
+:109B900000C020210E000F99028028218E4B00105A
+:109BA0008E4C00308F84003824090002016C502351
+:109BB000AE4A0010A089000096E3005C8E4400309D
+:109BC0008F9100380E000FF43070FFFF00024380C9
+:109BD000020838253C02420000E22825AE25000498
+:109BE0008E5F00048F8A00388E590000240B000815
+:109BF000AD5F001CAD590018AD40000CAD40001029
+:109C00009246000A240400052408C00030D000FF5A
+:109C1000A550001496580008A55800169251000A45
+:109C20003C188008322F00FFA54F0020964E0008F8
+:109C300037110100A54E0022AD400024924D000BCB
+:109C400031AC00FFA54C0002A14B00018E49003051
+:109C50008F830038240BFFBFAC690008A06400307C
+:109C60008F9000382403FFDF9607003200E8282495
+:109C700000B51025A6020032921F003233F9003FD2
+:109C800037260040A20600328F8C0038AD800034A9
+:109C90008E2F00D0AD8F0038918E003C3C0F7FFF9F
+:109CA00031CD007FA18D003C8F84003835EEFFFF61
+:109CB000908A003C014B4824A089003C8F850038E5
+:109CC00090A8003C01033824A0A7003C8E42003439
+:109CD0008F9100383C038008AE2200408E59002C42
+:109CE0008E5F0030033F3023AE26004492300048A0
+:109CF0003218007FA23800488F8800388E4D00301F
+:109D00008D0C004801AE582401965024014B482583
+:109D1000AD0900489244000AA104004C964700088F
+:109D20008F850038A4A7004E8E5000308E4400303E
+:109D30000E0003818C65006092F9007C0002F940FE
+:109D4000004028210002110003E2302133360002D6
+:109D500012C00003020680210005B0800216802197
+:109D6000926D007C31B30004126000020005708027
+:109D7000020E80218E4B00308F8800382405800031
+:109D8000316A0003000A4823312400030204182129
+:109D9000AD03003496E4007A96F0007A96F1007AEA
+:109DA00032027FFF2447000130FF7FFF0225C824D5
+:109DB000033F3025A6E6007A96F8007A3C120800A8
+:109DC0008E520060330F7FFF11F200180000000078
+:109DD0008F8400A00E000FCE02A028218F8400A047
+:109DE0000E000FDE028028210E001013000000007C
+:109DF0000A00111F0000000096F1007A022480245E
+:109E0000A6F0007A92EF007A92EB007A31EE00FF32
+:109E1000000E69C2000D6027000C51C03169007F3F
+:109E2000012A20250A001119A2E4007A96E6007A98
+:109E300000C5C024A6F8007A92EF007A92F3007A67
+:109E400031F200FF001271C2000E6827000DB1C090
+:109E5000326C007F01962825A2E5007A0A0011D015
+:109E60008F8400A03C0380003084FFFF30A5FFFFFB
+:109E7000AC640018AC65001C03E000088C620014A0
+:109E800027BDFFA03C068008AFBF005CAFBE0058F6
+:109E9000AFB70054AFB60050AFB5004CAFB40048F8
+:109EA000AFB30044AFB20040AFB1003CAFB0003838
+:109EB00034C80100910500D590C700083084FFFF29
+:109EC00030A500FF30E2007F0045182AAFA4001043
+:109ED000A7A00018A7A0002610600055AFA000148E
+:109EE00090CA00083149007F00A9302324D3FFFF26
+:109EF0000013802B8FB400100014902B02128824C2
+:109F0000522000888FB300143C03800894790052DB
+:109F1000947E00508FB60010033EC0230018BC0092
+:109F2000001714030016FC0002C2A82A16A00002A3
+:109F3000001F2C030040282100133C0000072403CD
+:109F400000A4102A5440000100A020212885000907
+:109F500014A000020080A021241400083C0C8008FA
+:109F60008D860048001459808D88004C3C03800089
+:109F70003169FFFF3C0A0010012A202534710400DA
+:109F8000AC660038AF9100A4AC68003CAC64003013
+:109F900000000000000000000000000000000000C1
+:109FA00000000000000000000000000000000000B1
+:109FB0008C6E000031CD002011A0FFFD0014782A26
+:109FC00001F01024104000390000A8213C16800840
+:109FD00092D700083C1280008E44010032F6007FC8
+:109FE0000E000F9902C028218E3900108E44010006
+:109FF0000000902133373FFF0E000FB102E028210F
+:10A00000923800003302003F2C500008520000102C
+:10A0100000008821000210803C030800246358E4FB
+:10A020000043F8218FFE000003C00008000000007C
+:10A0300090CF0008938C00AB31EE007F00AE682318
+:10A04000018D58210A0012172573FFFF0000882197
+:10A050003C1E80008FC401000E000FCE02E02821BC
+:10A060008FC401000E000FDE02C028211220000F55
+:10A070000013802B8F8B00A426A400010004AC00E9
+:10A08000027298230015AC032578004002B4B02A70
+:10A090000013802B241700010300882102D0102414
+:10A0A000AF9800A41440FFC9AFB700143C07800864
+:10A0B00094E200508FAE00103C05800002A288217F
+:10A0C0003C060020A4F10050ACA6003094F40050EF
+:10A0D00094EF005201D51823306CFFFF11F4001EDD
+:10A0E000AFAC00108CEF004C001561808CF500487F
+:10A0F00001EC28210000202100AC582B02A4C02133
+:10A10000030BB021ACE5004CACF600488FB4001056
+:10A110000014902B021288241620FF7C3C03800838
+:10A120008FB300148FBF005C8FBE00583A620001ED
+:10A130008FB700548FB600508FB5004C8FB40048D5
+:10A140008FB300448FB200408FB1003C8FB0003815
+:10A1500003E0000827BD006094FE00548CF2004428
+:10A1600033C9FFFE0009C8C00259F821ACBF003C4A
+:10A170008CE800448CAD003C010D50231940003B9D
+:10A18000000000008CF7004026E20001ACA200387D
+:10A190003C05005034A700103C038000AC67003041
+:10A1A00000000000000000000000000000000000AF
+:10A1B000000000000000000000000000000000009F
+:10A1C0008C7800003316002012C0FFFD3C1180087F
+:10A1D000962200543C1580003C068008304E000159
+:10A1E000000E18C0007578218DEC04003C070800B3
+:10A1F0008CE700443C040020ACCC00488DF40404FF
+:10A20000240B0001ACD4004C10EB0260AEA4003073
+:10A21000963900523C0508008CA5004000B99021F9
+:10A22000A6320052963F005427ED0001A62D00549F
+:10A230009626005430C4FFFF5487FF2F8FB40010C0
+:10A2400030A5FFFF0E0011F4A62000543C070800C3
+:10A250008CE70024963E00520047B82303D74823DA
+:10A26000A62900520A0012198FB400108CE2004097
+:10A270000A0012BE00000000922400012407000121
+:10A280003085007F14A7001C97AD00268E2B00148C
+:10A29000240CC000316A3FFF01AC48243C06080092
+:10A2A0008CC60060012A402531043FFF0086882BC0
+:10A2B00012200011A7A800263C0508008CA5005814
+:10A2C0008F9100A0000439802402FF8000B1182182
+:10A2D0000067F82103E2F02433F8007F3C1280008D
+:10A2E0003C19800EAE5E002C0319702191D0000D38
+:10A2F000360F0004A1CF000D0E001028241200011B
+:10A30000241100013C1E80008FC401000E000FCEFE
+:10A3100002E028218FC401000E000FDE02C02821B8
+:10A320001620FF558F8B00A40A0012860013802B85
+:10A330008F8600A490C80001310400201080019194
+:10A34000241000013C048008348B0080916A007C5A
+:10A350008F9E0034AFA0002C314900011120000F66
+:10A36000AFB000288CCD00148C8E006001AE602B45
+:10A370001580000201A038218C8700603C188008FD
+:10A38000370300808C70007000F0782B15E000021D
+:10A3900000E020218C640070AFA4002C3C028008F7
+:10A3A000344500808CD200148CBF0070025FC82B33
+:10A3B00017200002024020218CA400708FA7002CDF
+:10A3C0000087182310600003AFA3003024050002AB
+:10A3D000AFA500288FA400280264882B162000BA9D
+:10A3E000000018218CD000388FCE000C3C0F00806C
+:10A3F000AFD000008CCD00343C0CFF9F01CF58251E
+:10A40000AFCD000490CA003F3586FFFF01662024CF
+:10A410003C0900203C08FFEFA3CA000B0089382547
+:10A420003511FFFF00F118243C0500088F8700A4B8
+:10A430000065C825AFD9000C8CE20014AFC000182D
+:10A440008FA60030AFC200148CF800188FB0002C1B
+:10A450003C1FFFFBAFD8001C8CEF000837F2FFFF5A
+:10A4600003326824AFCF00248CEC000C020670216C
+:10A47000AFCD000CA7C00038A7C0003AAFCE002C6B
+:10A48000AFCC0020AFC000288CEA00148FAB002CAA
+:10A49000014B48230126402311000011AFC80010D2
+:10A4A00090EB003D8FC900048FC80000000B5100E5
+:10A4B000012A28210000102100AA882B010218215E
+:10A4C0000071F821AFC50004AFDF000090F2003D3D
+:10A4D000A3D2000A8F9900A497380006A7D80008D5
+:10A4E0008F910038240800023C038008A228000055
+:10A4F0003465008094BF005C8FA4002C33F0FFFF14
+:10A500000E000FF48F9200380002CB808F8500A4DC
+:10A51000021978253C18420001F87025AE4E00045F
+:10A520008F8400388CAD0038AC8D00188CAC0034B2
+:10A53000AC8C001CAC80000CAC800010A48000141B
+:10A54000A4800016A4800020A4800022AC800024F7
+:10A5500090A6003F8FA7002CA486000250E0019235
+:10A56000240700018FA200305040000290A2003D5D
+:10A5700090A2003E244A0001A08A00018F84003886
+:10A580008FA9002CAC8900083C128008364D008051
+:10A5900091AC007C3186000214C000022407003414
+:10A5A000240700308F8500A43C198008373F0080C5
+:10A5B00090B0000093F9007C240E0004A0900030BD
+:10A5C0008F8F00A48FB8002C8F8D003891F200017E
+:10A5D0003304000301C46023A1B200318F8E003820
+:10A5E0008F8600A42402C00095CA003294C90012CC
+:10A5F0008FAB002C0142402431233FFF010388250B
+:10A60000A5D1003291D000323185000300EBF82152
+:10A610003218003F370F0040A1CF00328FA4002C2A
+:10A6200003E5382133280004108000028F850038AC
+:10A6300000E838213C0A8008ACA700343549010005
+:10A640008D2800D08FA3002C2419FFBFACA80038A0
+:10A6500090B1003C2C640001240FFFDF3227007F03
+:10A66000A0A7003C8F98003800049140931F003C45
+:10A6700003F98024A310003C8F8C0038918E003C9D
+:10A6800001CF682401B23025A186003C8F8900A447
+:10A690008F8800388D2B0020AD0B00408D220024C8
+:10A6A000AD0200448D2A0028AD0A00488D23002CFD
+:10A6B0000E001013AD03004C8FB1002824070002D8
+:10A6C000122700118FA300280003282B00058023E8
+:10A6D0000270982400608021006090210A00126FAF
+:10A6E0000010882B962900128F8400A00000902172
+:10A6F0003125FFFFA7A900180E000FC22411000189
+:10A700000A00131D3C1E80003C0B80003C12800898
+:10A710008D640100924900088F92FF340E000F995A
+:10A720003125007F8F9900388FA700288FA4003033
+:10A73000A3270000965F005C33F0FFFF0E000FF4CC
+:10A740008F91003800026B80020D80253C0842008A
+:10A750008F8D00A402085025AE2A00048DA5003874
+:10A760008F8A003800007821000F1100AD450018D5
+:10A770008DB800343C047FFF3488FFFFAD58001CC7
+:10A7800091A6003E8D4C001C8D4900180006190052
+:10A79000000677020183C821004E58250323882B29
+:10A7A000012B382100F1F821AD59001CAD5F0018D4
+:10A7B000AD40000CAD40001091B0003E8FA40030C1
+:10A7C00024090005A550001495A500042419C00013
+:10A7D00000884024A545001691B8003EA5580020E9
+:10A7E00095AF0004A54F0022AD40002491AE003F7C
+:10A7F000A54E000291A6003E91AC003D01861023BB
+:10A80000244B0001A14B00018F9100388FA3003031
+:10A810003C028008344B0100AE230008A22900301E
+:10A820008F8C00388F8700A4959F003294F000121F
+:10A830002407FFBF033FC02432053FFF03057825EF
+:10A84000A58F0032918E00322418FFDF31CD003FFA
+:10A8500035A60040A18600328F910038240DFFFFFD
+:10A86000240CFF80AE2000348D6A00D0AE2A003860
+:10A870009223003C3069007FA229003C8F90003871
+:10A880003C0380009219003C0327F824A21F003CDF
+:10A890008F8E003891C5003C00B87824A1CF003CD1
+:10A8A0008F8A00383C0E8008AD4D00408FA6002CEA
+:10A8B000AD46004491420048004C5825A14B004849
+:10A8C0008F9000388F9900A48E09004801238824B6
+:10A8D00002283825AE070048933F003EA21F004CD7
+:10A8E0008F9800A48F8F003897050004A5E5004ECF
+:10A8F0000E0003818DC500609246007C8FAC003055
+:10A9000000026940000291000040282130CB000283
+:10A9100001B21021156000AA018230213C0E80088E
+:10A9200035C20080904C007C31830004106000032D
+:10A930008FB900300005788000CF3021241F00043B
+:10A940008F910038332D000303ED8023320800037C
+:10A9500000C85021AE2A00343C188000A7C500383A
+:10A960003C0680088F04010090DE00080E000FDE18
+:10A9700033C5007F0E001013000000000A00140D04
+:10A980008FA300288F9800348CC90038241F00033F
+:10A99000A7000008AF0900008CC50034A300000A1E
+:10A9A0008F9900A4AF0500043C080080932D003F60
+:10A9B000A31F000C8F0A000C3C02FF9FA30D000B8D
+:10A9C0000148F0253451FFFF3C12FFEF8F9900A49E
+:10A9D00003D170243646FFFF01C61824AF03000CD4
+:10A9E0008F2C0014972900128F8400A0AF0C001048
+:10A9F0008F2F0014AF000018AF000020AF0F00141D
+:10AA0000AF0000248F270018312F3FFF000F59801F
+:10AA1000AF0700288F2500080164F821312D0001BF
+:10AA2000AF0500308F31000C8F920038001F51C2EB
+:10AA3000000D438001481021241E00023C068008BE
+:10AA4000A702001CA7000034AF11002CA25E00007A
+:10AA500034D20080964E005C8F9900383C0342004F
+:10AA600031CCFFFF01833825AF2700048F8B00A472
+:10AA7000240500012402C0008D640038240700343E
+:10AA8000AF2400188D690034AF29001CAF20000CE2
+:10AA9000AF200010A7200014A7200016A720002038
+:10AAA000A7200022AF200024A7300002A325000128
+:10AAB0008F8800388F9F00A4AD10000893ED000030
+:10AAC000A10D00308F8A00A48F98003891510001A9
+:10AAD000A31100318F8B0038957E003203C27024A1
+:10AAE00001CF6025A56C0032916300323064003FD5
+:10AAF000A16400329249007C3125000214A00002BA
+:10AB00008F840038240700303C198008AC8700345B
+:10AB1000373201008E5F00D0240AFFBF020090216F
+:10AB2000AC9F0038908D003C31A8007FA088003C8D
+:10AB30008F9E003893C2003C004A8824A3D1003C79
+:10AB40008F8300380010882B9066003C34CE0020A4
+:10AB5000A06E003C8F8400A48F9800388C8C00205D
+:10AB6000AF0C00408C8F0024AF0F00448C8700286E
+:10AB7000AF0700488C8B002CAF0B004C0E0010135D
+:10AB80003C1E80000A0012700000000094C80052B1
+:10AB90003C0A08008D4A002401488821A4D10052B3
+:10ABA0000A0012198FB40010A08700018F840038AA
+:10ABB000240B0001AC8B00080A0013BE3C12800875
+:10ABC000000520800A0014A200C4302127BDFFE048
+:10ABD0003C0D8008AFB20018AFB00010AFBF001C32
+:10ABE000AFB1001435B200808E4C001835A80100BA
+:10ABF000964B000695A70050910900FC000C5602E8
+:10AC0000016728233143007F312600FF240200031F
+:10AC1000AF8300A8AF8400A010C2001B30B0FFFFBC
+:10AC2000910600FC2412000530C200FF10520033D0
+:10AC300000000000160000098FBF001C8FB2001832
+:10AC40008FB100148FB00010240D0C003C0C80005C
+:10AC500027BD002003E00008AD8D00240E0011FB8D
+:10AC6000020020218FBF001C8FB200188FB100148A
+:10AC70008FB00010240D0C003C0C800027BD00207C
+:10AC800003E00008AD8D0024965800789651007AB4
+:10AC9000924E007D0238782631E8FFFF31C400C0B3
+:10ACA000148000092D11000116000037000000007B
+:10ACB0005620FFE28FBF001C0E0010D100000000E4
+:10ACC0000A00156A8FBF001C1620FFDA0000000082
+:10ACD0000E0010D1000000001440FFD88FBF001CF0
+:10ACE0001600002200000000925F007D33E2003F6A
+:10ACF000A242007D0A00156A8FBF001C950900EA78
+:10AD00008F86008000802821240400050E0007257E
+:10AD10003130FFFF978300923C0480002465FFFFE1
+:10AD2000A78500928C8A01B80540FFFE0000000054
+:10AD3000AC8001808FBF001CAC9001848FB20018E2
+:10AD40008FB100148FB000103C0760133C0B100053
+:10AD5000240D0C003C0C800027BD0020AC8701882E
+:10AD6000AC8B01B803E00008AD8D00240E0011FB90
+:10AD7000020020215040FFB18FBF001C925F007D78
+:10AD80000A00159733E2003F0E0011FB020020215C
+:10AD90001440FFAA8FBF001C122000070000000013
+:10ADA0009259007D3330003F36020040A242007DC0
+:10ADB0000A00156A8FBF001C0E0010D100000000B1
+:10ADC0005040FF9E8FBF001C9259007D3330003FE2
+:08ADD0000A0015C6360200401E
+:08ADD800000000000000001B58
+:10ADE0000000000F0000000A00000008000000063C
+:10ADF0000000000500000005000000040000000441
+:10AE00000000000300000003000000030000000336
+:10AE10000000000300000002000000020000000229
+:10AE2000000000020000000200000002000000021A
+:10AE3000000000020000000200000002000000020A
+:10AE400000000002000000020000000200000002FA
+:0CAE5000000000010000000100000001F3
+:04AE5C008008010069
+:10AE6000800800808008000000000C000000308096
+:10AE7000080011D00800127C08001294080012A8E3
+:10AE8000080012BC080011D0080011D0080012F010
+:10AE90000800132C080013400800138808001A8CBF
+:10AEA00008001A8C08001AC408001AC408001AD82E
+:10AEB00008001AA808001D0008001CCC08001D5836
+:10AEC00008001D5808001DE008001D108008024001
+:10AED000080027340800256C0800275C080027F4C8
+:10AEE0000800293C0800298808002AAC080029B479
+:10AEF00008002A38080025DC08002EDC08002EA4F3
+:10AF000008002588080025880800258808002B20CF
+:10AF100008002B20080025880800258808002DD06F
+:10AF2000080025880800258808002588080025884D
+:10AF300008002E0C080025880800258808002588B0
+:10AF4000080025880800258808002588080025882D
+:10AF5000080025880800258808002588080025881D
+:10AF6000080025880800258808002588080029A8E9
+:10AF7000080025880800258808002E680800258814
+:10AF800008002588080025880800258808002588ED
+:10AF900008002588080025880800258808002588DD
+:10AFA00008002588080025880800258808002588CD
+:10AFB00008002588080025880800258808002588BD
+:10AFC00008002CF4080025880800258808002C6853
+:10AFD00008002BC408003CE408003CB808003C848E
+:10AFE00008003C5808003C3808003BEC8008010091
+:10AFF00080080080800800008008008008004C6401
+:10B0000008004C9C08004BE408004C6408004C64A9
+:0CB01000080049B808004C6408005050CB
+:04B01C000A000C8496
+:10B0200000000000000000000000000D7278703683
+:10B030002E302E3137000000060011030000000002
+:10B0400000000001000000000000000000000000FF
+:10B0500000000000000000000000000000000000F0
+:10B0600000000000000000000000000000000000E0
+:10B0700000000000000000000000000000000000D0
+:10B0800000000000000000000000000000000000C0
+:10B0900000000000000000000000000000000000B0
+:10B0A00000000000000000000000000000000000A0
+:10B0B0000000000000000000000000000000000090
+:10B0C0000000000000000000000000000000000080
+:10B0D0000000000000000000000000000000000070
+:10B0E0000000000000000000000000000000000060
+:10B0F0000000000000000000000000000000000050
+:10B10000000000000000000000000000000000003F
+:10B11000000000000000000000000000000000002F
+:10B12000000000000000000000000000000000001F
+:10B13000000000000000000000000000000000000F
+:10B1400000000000000000000000000000000000FF
+:10B1500000000000000000000000000000000000EF
+:10B1600000000000000000000000000000000000DF
+:10B1700000000000000000000000000000000000CF
+:10B1800000000000000000000000000000000000BF
+:10B1900000000000000000000000000000000000AF
+:10B1A000000000000000000000000000000000009F
+:10B1B000000000000000000000000000000000008F
+:10B1C000000000000000000000000000000000007F
+:10B1D000000000000000000000000000000000006F
+:10B1E000000000000000000000000000000000005F
+:10B1F000000000000000000000000000000000004F
+:10B20000000000000000000000000000000000003E
+:10B21000000000000000000000000000000000002E
+:10B22000000000000000000000000000000000001E
+:10B23000000000000000000000000000000000000E
+:10B2400000000000000000000000000000000000FE
+:10B2500000000000000000000000000000000000EE
+:10B2600000000000000000000000000000000000DE
+:10B2700000000000000000000000000000000000CE
+:10B2800000000000000000000000000000000000BE
+:10B2900000000000000000000000000000000000AE
+:10B2A000000000000000000000000000000000009E
+:10B2B000000000000000000000000000000000008E
+:10B2C000000000000000000000000000000000007E
+:10B2D000000000000000000000000000000000006E
+:10B2E000000000000000000000000000000000005E
+:10B2F000000000000000000000000000000000004E
+:10B30000000000000000000000000000000000003D
+:10B31000000000000000000000000000000000002D
+:10B32000000000000000000000000000000000001D
+:10B33000000000000000000000000000000000000D
+:10B3400000000000000000000000000000000000FD
+:10B3500000000000000000000000000000000000ED
+:10B3600000000000000000000000000000000000DD
+:10B3700000000000000000000000000000000000CD
+:10B3800000000000000000000000000000000000BD
+:10B3900000000000000000000000000000000000AD
+:10B3A000000000000000000000000000000000009D
+:10B3B000000000000000000000000000000000008D
+:10B3C000000000000000000000000000000000007D
+:10B3D000000000000000000000000000000000006D
+:10B3E000000000000000000000000000000000005D
+:10B3F000000000000000000000000000000000004D
+:10B40000000000000000000000000000000000003C
+:10B41000000000000000000000000000000000002C
+:10B42000000000000000000000000000000000001C
+:10B43000000000000000000000000000000000000C
+:10B4400000000000000000000000000000000000FC
+:10B4500000000000000000000000000000000000EC
+:10B4600000000000000000000000000000000000DC
+:10B4700000000000000000000000000000000000CC
+:10B4800000000000000000000000000000000000BC
+:10B4900000000000000000000000000000000000AC
+:10B4A000000000000000000000000000000000009C
+:10B4B000000000000000000000000000000000008C
+:10B4C000000000000000000000000000000000007C
+:10B4D000000000000000000000000000000000006C
+:10B4E000000000000000000000000000000000005C
+:10B4F000000000000000000000000000000000004C
+:10B50000000000000000000000000000000000003B
+:10B51000000000000000000000000000000000002B
+:10B52000000000000000000000000000000000001B
+:10B53000000000000000000000000000000000000B
+:10B5400000000000000000000000000000000000FB
+:10B5500000000000000000000000000000000000EB
+:10B5600000000000000000000000000000000000DB
+:10B5700000000000000000000000000000000000CB
+:10B5800000000000000000000000000000000000BB
+:10B5900000000000000000000000000000000000AB
+:10B5A000000000000000000000000000000000009B
+:10B5B000000000000000000000000000000000008B
+:10B5C000000000000000000000000000000000007B
+:10B5D000000000000000000000000000000000006B
+:10B5E000000000000000000000000000000000005B
+:10B5F000000000000000000000000000000000004B
+:10B60000000000000000000000000000000000003A
+:10B61000000000000000000000000000000000002A
+:10B62000000000000000000000000000000000001A
+:10B63000000000000000000000000000000000000A
+:10B6400000000000000000000000000000000000FA
+:10B6500000000000000000000000000000000000EA
+:10B6600000000000000000000000000000000000DA
+:10B6700000000000000000000000000000000000CA
+:10B6800000000000000000000000000000000000BA
+:10B6900000000000000000000000000000000000AA
+:10B6A000000000000000000000000000000000009A
+:10B6B000000000000000000000000000000000008A
+:10B6C000000000000000000000000000000000007A
+:10B6D000000000000000000000000000000000006A
+:10B6E000000000000000000000000000000000005A
+:10B6F000000000000000000000000000000000004A
+:10B700000000000000000000000000000000000039
+:10B710000000000000000000000000000000000029
+:10B720000000000000000000000000000000000019
+:10B730000000000000000000000000000000000009
+:10B7400000000000000000000000000000000000F9
+:10B7500000000000000000000000000000000000E9
+:10B7600000000000000000000000000000000000D9
+:10B7700000000000000000000000000000000000C9
+:10B7800000000000000000000000000000000000B9
+:10B7900000000000000000000000000000000000A9
+:10B7A0000000000000000000000000000000000099
+:10B7B0000000000000000000000000000000000089
+:10B7C0000000000000000000000000000000000079
+:10B7D0000000000000000000000000000000000069
+:10B7E0000000000000000000000000000000000059
+:10B7F0000000000000000000000000000000000049
+:10B800000000000000000000000000000000000038
+:10B810000000000000000000000000000000000028
+:10B820000000000000000000000000000000000018
+:10B830000000000000000000000000000000000008
+:10B8400000000000000000000000000000000000F8
+:10B8500000000000000000000000000000000000E8
+:10B8600000000000000000000000000000000000D8
+:10B8700000000000000000000000000000000000C8
+:10B8800000000000000000000000000000000000B8
+:10B8900000000000000000000000000000000000A8
+:10B8A0000000000000000000000000000000000098
+:10B8B0000000000000000000000000000000000088
+:10B8C0000000000000000000000000000000000078
+:10B8D0000000000000000000000000000000000068
+:10B8E0000000000000000000000000000000000058
+:10B8F0000000000000000000000000000000000048
+:10B900000000000000000000000000000000000037
+:10B910000000000000000000000000000000000027
+:10B920000000000000000000000000000000000017
+:10B930000000000000000000000000000000000007
+:10B9400000000000000000000000000000000000F7
+:10B9500000000000000000000000000000000000E7
+:10B9600000000000000000000000000000000000D7
+:10B9700000000000000000000000000000000000C7
+:10B9800000000000000000000000000000000000B7
+:10B9900000000000000000000000000000000000A7
+:10B9A0000000000000000000000000000000000097
+:10B9B0000000000000000000000000000000000087
+:10B9C0000000000000000000000000000000000077
+:10B9D0000000000000000000000000000000000067
+:10B9E0000000000000000000000000000000000057
+:10B9F0000000000000000000000000000000000047
+:10BA00000000000000000000000000000000000036
+:10BA10000000000000000000000000000000000026
+:10BA20000000000000000000000000000000000016
+:10BA30000000000000000000000000000000000006
+:10BA400000000000000000000000000000000000F6
+:10BA500000000000000000000000000000000000E6
+:10BA600000000000000000000000000000000000D6
+:10BA700000000000000000000000000000000000C6
+:10BA800000000000000000000000000000000000B6
+:10BA900000000000000000000000000000000000A6
+:10BAA0000000000000000000000000000000000096
+:10BAB0000000000000000000000000000000000086
+:10BAC0000000000000000000000000000000000076
+:10BAD0000000000000000000000000000000000066
+:10BAE0000000000000000000000000000000000056
+:10BAF0000000000000000000000000000000000046
+:10BB00000000000000000000000000000000000035
+:10BB10000000000000000000000000000000000025
+:10BB20000000000000000000000000000000000015
+:10BB30000000000000000000000000000000000005
+:10BB400000000000000000000000000000000000F5
+:10BB500000000000000000000000000000000000E5
+:10BB600000000000000000000000000000000000D5
+:10BB700000000000000000000000000000000000C5
+:10BB800000000000000000000000000000000000B5
+:10BB900000000000000000000000000000000000A5
+:10BBA0000000000000000000000000000000000095
+:10BBB0000000000000000000000000000000000085
+:10BBC0000000000000000000000000000000000075
+:10BBD0000000000000000000000000000000000065
+:10BBE0000000000000000000000000000000000055
+:10BBF0000000000000000000000000000000000045
+:10BC00000000000000000000000000000000000034
+:10BC10000000000000000000000000000000000024
+:10BC20000000000000000000000000000000000014
+:10BC30000000000000000000000000000000000004
+:10BC400000000000000000000000000000000000F4
+:10BC500000000000000000000000000000000000E4
+:10BC600000000000000000000000000000000000D4
+:10BC700000000000000000000000000000000000C4
+:10BC800000000000000000000000000000000000B4
+:10BC900000000000000000000000000000000000A4
+:10BCA0000000000000000000000000000000000094
+:10BCB0000000000000000000000000000000000084
+:10BCC0000000000000000000000000000000000074
+:10BCD0000000000000000000000000000000000064
+:10BCE0000000000000000000000000000000000054
+:10BCF0000000000000000000000000000000000044
+:10BD00000000000000000000000000000000000033
+:10BD10000000000000000000000000000000000023
+:10BD20000000000000000000000000000000000013
+:10BD30000000000000000000000000000000000003
+:10BD400000000000000000000000000000000000F3
+:10BD500000000000000000000000000000000000E3
+:10BD600000000000000000000000000000000000D3
+:10BD700000000000000000000000000000000000C3
+:10BD800000000000000000000000000000000000B3
+:10BD900000000000000000000000000000000000A3
+:10BDA0000000000000000000000000000000000093
+:10BDB0000000000000000000000000000000000083
+:10BDC0000000000000000000000000000000000073
+:10BDD0000000000000000000000000000000000063
+:10BDE0000000000000000000000000000000000053
+:10BDF0000000000000000000000000000000000043
+:10BE00000000000000000000000000000000000032
+:10BE10000000000000000000000000000000000022
+:10BE20000000000000000000000000000000000012
+:10BE30000000000000000000000000000000000002
+:10BE400000000000000000000000000000000000F2
+:10BE500000000000000000000000000000000000E2
+:10BE600000000000000000000000000000000000D2
+:10BE700000000000000000000000000000000000C2
+:10BE800000000000000000000000000000000000B2
+:10BE900000000000000000000000000000000000A2
+:10BEA0000000000000000000000000000000000092
+:10BEB0000000000000000000000000000000000082
+:10BEC0000000000000000000000000000000000072
+:10BED0000000000000000000000000000000000062
+:10BEE0000000000000000000000000000000000052
+:10BEF0000000000000000000000000000000000042
+:10BF00000000000000000000000000000000000031
+:10BF10000000000000000000000000000000000021
+:10BF20000000000000000000000000000000000011
+:10BF30000000000000000000000000000000000001
+:10BF400000000000000000000000000000000000F1
+:10BF500000000000000000000000000000000000E1
+:10BF600000000000000000000000000000000000D1
+:10BF700000000000000000000000000000000000C1
+:10BF800000000000000000000000000000000000B1
+:10BF900000000000000000000000000000000000A1
+:10BFA0000000000000000000000000000000000091
+:10BFB0000000000000000000000000000000000081
+:10BFC0000000000000000000000000000000000071
+:10BFD0000000000000000000000000000000000061
+:10BFE0000000000000000000000000000000000051
+:10BFF0000000000000000000000000000000000041
+:10C000000000000000000000000000000000000030
+:10C010000000000000000000000000000000000020
+:10C020000000000000000000000000000000000010
+:10C030000000000000000000000000000000000000
+:10C0400000000000000000000000000000000000F0
+:10C0500000000000000000000000000000000000E0
+:10C0600000000000000000000000000000000000D0
+:10C0700000000000000000000000000000000000C0
+:10C0800000000000000000000000000000000000B0
+:10C0900000000000000000000000000000000000A0
+:10C0A0000000000000000000000000000000000090
+:10C0B0000000000000000000000000000000000080
+:10C0C0000000000000000000000000000000000070
+:10C0D0000000000000000000000000000000000060
+:10C0E0000000000000000000000000000000000050
+:10C0F0000000000000000000000000000000000040
+:10C10000000000000000000000000000000000002F
+:10C11000000000000000000000000000000000001F
+:10C12000000000000000000000000000000000000F
+:10C1300000000000000000000000000000000000FF
+:10C1400000000000000000000000000000000000EF
+:10C1500000000000000000000000000000000000DF
+:10C1600000000000000000000000000000000000CF
+:10C1700000000000000000000000000000000000BF
+:10C1800000000000000000000000000000000000AF
+:10C19000000000000000000000000000000000009F
+:10C1A000000000000000000000000000000000008F
+:10C1B000000000000000000000000000000000007F
+:10C1C000000000000000000000000000000000006F
+:10C1D000000000000000000000000000000000005F
+:10C1E000000000000000000000000000000000004F
+:10C1F000000000000000000000000000000000003F
+:10C20000000000000000000000000000000000002E
+:10C21000000000000000000000000000000000001E
+:10C22000000000000000000000000000000000000E
+:10C2300000000000000000000000000000000000FE
+:10C2400000000000000000000000000000000000EE
+:10C2500000000000000000000000000000000000DE
+:10C2600000000000000000000000000000000000CE
+:10C2700000000000000000000000000000000000BE
+:10C2800000000000000000000000000000000000AE
+:10C29000000000000000000000000000000000009E
+:10C2A000000000000000000000000000000000008E
+:10C2B000000000000000000000000000000000007E
+:10C2C000000000000000000000000000000000006E
+:10C2D000000000000000000000000000000000005E
+:10C2E000000000000000000000000000000000004E
+:10C2F000000000000000000000000000000000003E
+:10C30000000000000000000000000000000000002D
+:10C31000000000000000000000000000000000001D
+:10C32000000000000000000000000000000000000D
+:10C3300000000000000000000000000000000000FD
+:10C3400000000000000000000000000000000000ED
+:10C3500000000000000000000000000000000000DD
+:10C3600000000000000000000000000000000000CD
+:10C3700000000000000000000000000000000000BD
+:10C3800000000000000000000000000000000000AD
+:10C39000000000000000000000000000000000009D
+:10C3A000000000000000000000000000000000008D
+:10C3B000000000000000000000000000000000007D
+:10C3C000000000000000000000000000000000006D
+:10C3D000000000000000000000000000000000005D
+:10C3E000000000000000000000000000000000004D
+:10C3F000000000000000000000000000000000003D
+:10C40000000000000000000000000000000000002C
+:10C41000000000000000000000000000000000001C
+:10C42000000000000000000000000000000000000C
+:10C4300000000000000000000000000000000000FC
+:10C4400000000000000000000000000000000000EC
+:10C4500000000000000000000000000000000000DC
+:10C4600000000000000000000000000000000000CC
+:10C4700000000000000000000000000000000000BC
+:10C4800000000000000000000000000000000000AC
+:10C49000000000000000000000000000000000009C
+:10C4A000000000000000000000000000000000008C
+:10C4B000000000000000000000000000000000007C
+:10C4C000000000000000000000000000000000006C
+:10C4D000000000000000000000000000000000005C
+:10C4E000000000000000000000000000000000004C
+:10C4F000000000000000000000000000000000003C
+:10C50000000000000000000000000000000000002B
+:10C51000000000000000000000000000000000001B
+:10C52000000000000000000000000000000000000B
+:10C5300000000000000000000000000000000000FB
+:10C5400000000000000000000000000000000000EB
+:10C5500000000000000000000000000000000000DB
+:10C5600000000000000000000000000000000000CB
+:10C5700000000000000000000000000000000000BB
+:10C5800000000000000000000000000000000000AB
+:10C59000000000000000000000000000000000009B
+:10C5A000000000000000000000000000000000008B
+:10C5B000000000000000000000000000000000007B
+:10C5C000000000000000000000000000000000006B
+:10C5D000000000000000000000000000000000005B
+:10C5E000000000000000000000000000000000004B
+:10C5F000000000000000000000000000000000003B
+:10C60000000000000000000000000000000000002A
+:10C61000000000000000000000000000000000001A
+:10C62000000000000000000000000000000000000A
+:10C6300000000000000000000000000000000000FA
+:10C6400000000000000000000000000000000000EA
+:10C6500000000000000000000000000000000000DA
+:10C6600000000000000000000000000000000000CA
+:10C6700000000000000000000000000000000000BA
+:10C6800000000000000000000000000000000000AA
+:10C69000000000000000000000000000000000009A
+:10C6A000000000000000000000000000000000008A
+:10C6B000000000000000000000000000000000007A
+:10C6C000000000000000000000000000000000006A
+:10C6D000000000000000000000000000000000005A
+:10C6E000000000000000000000000000000000004A
+:10C6F000000000000000000000000000000000003A
+:10C700000000000000000000000000000000000029
+:10C710000000000000000000000000000000000019
+:10C720000000000000000000000000000000000009
+:10C7300000000000000000000000000000000000F9
+:10C7400000000000000000000000000000000000E9
+:10C7500000000000000000000000000000000000D9
+:10C7600000000000000000000000000000000000C9
+:10C7700000000000000000000000000000000000B9
+:10C7800000000000000000000000000000000000A9
+:10C790000000000000000000000000000000000099
+:10C7A0000000000000000000000000000000000089
+:10C7B0000000000000000000000000000000000079
+:10C7C0000000000000000000000000000000000069
+:10C7D0000000000000000000000000000000000059
+:10C7E0000000000000000000000000000000000049
+:10C7F0000000000000000000000000000000000039
+:10C800000000000000000000000000000000000028
+:10C810000000000000000000000000000000000018
+:10C820000000000000000000000000000000000008
+:10C8300000000000000000000000000000000000F8
+:10C8400000000000000000000000000000000000E8
+:10C8500000000000000000000000000000000000D8
+:10C8600000000000000000000000000000000000C8
+:10C8700000000000000000000000000000000000B8
+:10C8800000000000000000000000000000000000A8
+:10C890000000000000000000000000000000000098
+:10C8A0000000000000000000000000000000000088
+:10C8B0000000000000000000000000000000000078
+:10C8C0000000000000000000000000000000000068
+:10C8D0000000000000000000000000000000000058
+:10C8E0000000000000000000000000000000000048
+:10C8F0000000000000000000000000000000000038
+:10C900000000000000000000000000000000000027
+:10C910000000000000000000000000000000000017
+:10C920000000000000000000000000000000000007
+:10C9300000000000000000000000000000000000F7
+:10C9400000000000000000000000000000000000E7
+:10C9500000000000000000000000000000000000D7
+:10C9600000000000000000000000000000000000C7
+:10C9700000000000000000000000000000000000B7
+:10C9800000000000000000000000000000000000A7
+:10C990000000000000000000000000000000000097
+:10C9A0000000000000000000000000000000000087
+:10C9B0000000000000000000000000000000000077
+:10C9C0000000000000000000000000000000000067
+:10C9D0000000000000000000000000000000000057
+:10C9E0000000000000000000000000000000000047
+:10C9F0000000000000000000000000000000000037
+:10CA00000000000000000000000000000000000026
+:10CA10000000000000000000000000000000000016
+:10CA20000000000000000000000000000000000006
+:10CA300000000000000000000000000000000000F6
+:10CA400000000000000000000000000000000000E6
+:10CA500000000000000000000000000000000000D6
+:10CA600000000000000000000000000000000000C6
+:10CA700000000000000000000000000000000000B6
+:10CA800000000000000000000000000000000000A6
+:10CA90000000000000000000000000000000000096
+:10CAA0000000000000000000000000000000000086
+:10CAB0000000000000000000000000000000000076
+:10CAC0000000000000000000000000000000000066
+:10CAD0000000000000000000000000000000000056
+:10CAE0000000000000000000000000000000000046
+:10CAF0000000000000000000000000000000000036
+:10CB00000000000000000000000000000000000025
+:10CB10000000000000000000000000000000000015
+:10CB20000000000000000000000000000000000005
+:10CB300000000000000000000000000000000000F5
+:10CB400000000000000000000000000000000000E5
+:10CB500000000000000000000000000000000000D5
+:10CB600000000000000000000000000000000000C5
+:10CB700000000000000000000000000000000000B5
+:10CB800000000000000000000000000000000000A5
+:10CB90000000000000000000000000000000000095
+:10CBA0000000000000000000000000000000000085
+:10CBB0000000000000000000000000000000000075
+:10CBC0000000000000000000000000000000000065
+:10CBD0000000000000000000000000000000000055
+:10CBE0000000000000000000000000000000000045
+:10CBF0000000000000000000000000000000000035
+:10CC00000000000000000000000000000000000024
+:10CC10000000000000000000000000000000000014
+:10CC20000000000000000000000000000000000004
+:10CC300000000000000000000000000000000000F4
+:10CC400000000000000000000000000000000000E4
+:10CC500000000000000000000000000000000000D4
+:10CC600000000000000000000000000000000000C4
+:10CC700000000000000000000000000000000000B4
+:10CC800000000000000000000000000000000000A4
+:10CC90000000000000000000000000000000000094
+:10CCA0000000000000000000000000000000000084
+:10CCB0000000000000000000000000000000000074
+:10CCC0000000000000000000000000000000000064
+:10CCD0000000000000000000000000000000000054
+:10CCE0000000000000000000000000000000000044
+:10CCF0000000000000000000000000000000000034
+:10CD00000000000000000000000000000000000023
+:10CD10000000000000000000000000000000000013
+:10CD20000000000000000000000000000000000003
+:10CD300000000000000000000000000000000000F3
+:10CD400000000000000000000000000000000000E3
+:10CD500000000000000000000000000000000000D3
+:10CD600000000000000000000000000000000000C3
+:10CD700000000000000000000000000000000000B3
+:10CD800000000000000000000000000000000000A3
+:10CD90000000000000000000000000000000000093
+:10CDA0000000000000000000000000000000000083
+:10CDB0000000000000000000000000000000000073
+:10CDC0000000000000000000000000000000000063
+:10CDD0000000000000000000000000000000000053
+:10CDE0000000000000000000000000000000000043
+:10CDF0000000000000000000000000000000000033
+:10CE00000000000000000000000000000000000022
+:10CE10000000000000000000000000000000000012
+:10CE20000000000000000000000000000000000002
+:10CE300000000000000000000000000000000000F2
+:10CE400000000000000000000000000000000000E2
+:10CE500000000000000000000000000000000000D2
+:10CE600000000000000000000000000000000000C2
+:10CE700000000000000000000000000000000000B2
+:10CE800000000000000000000000000000000000A2
+:10CE90000000000000000000000000000000000092
+:10CEA0000000000000000000000000000000000082
+:10CEB0000000000000000000000000000000000072
+:10CEC0000000000000000000000000000000000062
+:10CED0000000000000000000000000000000000052
+:10CEE0000000000000000000000000000000000042
+:10CEF0000000000000000000000000000000000032
+:10CF00000000000000000000000000000000000021
+:10CF10000000000000000000000000000000000011
+:10CF20000000000000000000000000000000000001
+:10CF300000000000000000000000000000000000F1
+:10CF400000000000000000000000000000000000E1
+:10CF500000000000000000000000000000000000D1
+:10CF600000000000000000000000000000000000C1
+:10CF700000000000000000000000000000000000B1
+:10CF800000000000000000000000000000000000A1
+:10CF90000000000000000000000000000000000091
+:10CFA0000000000000000000000000000000000081
+:10CFB0000000000000000000000000000000000071
+:10CFC0000000000000000000000000000000000061
+:10CFD0000000000000000000000000000000000051
+:10CFE0000000000000000000000000000000000041
+:10CFF0000000000000000000000000000000000031
+:10D000000000000000000000000000000000000020
+:10D010000000000000000000000000000000000010
+:10D020000000000000000000000000000000000000
+:10D0300000000000000000000000000000000000F0
+:10D0400000000000000000000000000000000000E0
+:10D0500000000000000000000000000000000000D0
+:10D0600000000000000000000000000000000000C0
+:10D0700000000000000000000000000000000000B0
+:10D0800000000000000000000000000000000000A0
+:10D090000000000000000000000000000000000090
+:10D0A0000000000000000000000000000000000080
+:10D0B0000000000000000000000000000000000070
+:10D0C0000000000000000000000000000000000060
+:10D0D0000000000000000000000000000000000050
+:10D0E0000000000000000000000000000000000040
+:10D0F0000000000000000000000000000000000030
+:10D10000000000000000000000000000000000001F
+:10D11000000000000000000000000000000000000F
+:10D1200000000000000000000000000000000000FF
+:10D1300000000000000000000000000000000000EF
+:10D1400000000000000000000000000000000000DF
+:10D1500000000000000000000000000000000000CF
+:10D1600000000000000000000000000000000000BF
+:10D1700000000000000000000000000000000000AF
+:10D18000000000000000000000000000000000009F
+:10D19000000000000000000000000000000000008F
+:10D1A000000000000000000000000000000000007F
+:10D1B000000000000000000000000000000000006F
+:10D1C000000000000000000000000000000000005F
+:10D1D000000000000000000000000000000000004F
+:10D1E000000000000000000000000000000000003F
+:10D1F000000000000000000000000000000000002F
+:10D20000000000000000000000000000000000001E
+:10D21000000000000000000000000000000000000E
+:10D2200000000000000000000000000000000000FE
+:10D2300000000000000000000000000000000000EE
+:10D2400000000000000000000000000000000000DE
+:10D2500000000000000000000000000000000000CE
+:10D2600000000000000000000000000000000000BE
+:10D2700000000000000000000000000000000000AE
+:10D28000000000000000000000000000000000009E
+:10D29000000000000000000000000000000000008E
+:10D2A000000000000000000000000000000000007E
+:10D2B000000000000000000000000000000000006E
+:10D2C000000000000000000000000000000000005E
+:10D2D000000000000000000000000000000000004E
+:10D2E000000000000000000000000000000000003E
+:10D2F000000000000000000000000000000000002E
+:10D30000000000000000000000000000000000001D
+:10D31000000000000000000000000000000000000D
+:10D3200000000000000000000000000000000000FD
+:10D3300000000000000000000000000000000000ED
+:10D3400000000000000000000000000000000000DD
+:10D3500000000000000000000000000000000000CD
+:10D3600000000000000000000000000000000000BD
+:10D3700000000000000000000000000000000000AD
+:10D38000000000000000000000000000000000009D
+:10D39000000000000000000000000000000000008D
+:10D3A000000000000000000000000000000000007D
+:10D3B000000000000000000000000000000000006D
+:10D3C000000000000000000000000000000000005D
+:10D3D000000000000000000000000000000000004D
+:10D3E000000000000000000000000000000000003D
+:10D3F000000000000000000000000000000000002D
+:10D40000000000000000000000000000000000001C
+:10D41000000000000000000000000000000000000C
+:10D4200000000000000000000000000000000000FC
+:10D4300000000000000000000000000000000000EC
+:10D4400000000000000000000000000000000000DC
+:10D4500000000000000000000000000000000000CC
+:10D4600000000000000000000000000000000000BC
+:10D4700000000000000000000000000000000000AC
+:10D48000000000000000000000000000000000009C
+:10D49000000000000000000000000000000000008C
+:10D4A000000000000000000000000000000000007C
+:10D4B000000000000000000000000000000000006C
+:10D4C000000000000000000000000000000000005C
+:10D4D000000000000000000000000000000000004C
+:10D4E000000000000000000000000000000000003C
+:10D4F000000000000000000000000000000000002C
+:10D50000000000000000000000000000000000001B
+:10D51000000000000000000000000000000000000B
+:10D5200000000000000000000000000000000000FB
+:10D5300000000000000000000000000000000000EB
+:10D5400000000000000000000000000000000000DB
+:10D5500000000000000000000000000000000000CB
+:10D5600000000000000000000000000000000000BB
+:10D5700000000000000000000000000000000000AB
+:10D58000000000000000000000000000000000009B
+:10D59000000000000000000000000000000000008B
+:10D5A000000000000000000000000000000000007B
+:10D5B000000000000000000000000000000000006B
+:10D5C000000000000000000000000000000000005B
+:10D5D000000000000000000000000000000000004B
+:10D5E000000000000000000000000000000000003B
+:10D5F000000000000000000000000000000000002B
+:10D60000000000000000000000000000000000001A
+:10D61000000000000000000000000000000000000A
+:10D6200000000000000000000000000000000000FA
+:10D6300000000000000000000000000000000000EA
+:10D6400000000000000000000000000000000000DA
+:10D6500000000000000000000000000000000000CA
+:10D6600000000000000000000000000000000000BA
+:10D6700000000000000000000000000000000000AA
+:10D68000000000000000000000000000000000009A
+:10D69000000000000000000000000000000000008A
+:10D6A000000000000000000000000000000000007A
+:10D6B000000000000000000000000000000000006A
+:10D6C000000000000000000000000000000000005A
+:10D6D000000000000000000000000000000000004A
+:10D6E000000000000000000000000000000000003A
+:10D6F000000000000000000000000000000000002A
+:10D700000000000000000000000000000000000019
+:10D710000000000000000000000000000000000009
+:10D7200000000000000000000000000000000000F9
+:10D7300000000000000000000000000000000000E9
+:10D7400000000000000000000000000000000000D9
+:10D7500000000000000000000000000000000000C9
+:10D7600000000000000000000000000000000000B9
+:10D7700000000000000000000000000000000000A9
+:10D780000000000000000000000000000000000099
+:10D790000000000000000000000000000000000089
+:10D7A0000000000000000000000000000000000079
+:10D7B0000000000000000000000000000000000069
+:10D7C0000000000000000000000000000000000059
+:10D7D0000000000000000000000000000000000049
+:10D7E0000000000000000000000000000000000039
+:10D7F0000000000000000000000000000000000029
+:10D800000000000000000000000000000000000018
+:10D810000000000000000000000000000000000008
+:10D8200000000000000000000000000000000000F8
+:10D8300000000000000000000000000000000000E8
+:10D8400000000000000000000000000000000000D8
+:10D8500000000000000000000000000000000000C8
+:10D8600000000000000000000000000000000000B8
+:10D8700000000000000000000000000000000000A8
+:10D880000000000000000000000000000000000098
+:10D890000000000000000000000000000000000088
+:10D8A0000000000000000000000000000000000078
+:10D8B0000000000000000000000000000000000068
+:10D8C0000000000000000000000000000000000058
+:10D8D0000000000000000000000000000000000048
+:10D8E0000000000000000000000000000000000038
+:10D8F0000000000000000000000000000000000028
+:10D900000000000000000000000000000000000017
+:10D910000000000000000000000000000000000007
+:10D9200000000000000000000000000000000000F7
+:10D9300000000000000000000000000000000000E7
+:10D9400000000000000000000000000000000000D7
+:10D9500000000000000000000000000000000000C7
+:10D9600000000000000000000000000000000000B7
+:10D9700000000000000000000000000000000000A7
+:10D980000000000000000000000000000000000097
+:10D990000000000000000000000000000000000087
+:10D9A0000000000000000000000000000000000077
+:10D9B0000000000000000000000000000000000067
+:10D9C0000000000000000000000000000000000057
+:10D9D0000000000000000000000000000000000047
+:10D9E0000000000000000000000000000000000037
+:10D9F0000000000000000000000000000000000027
+:10DA00000000000000000000000000000000000016
+:10DA10000000000000000000000000000000000006
+:10DA200000000000000000000000000000000000F6
+:10DA300000000000000000000000000000000000E6
+:10DA400000000000000000000000000000000000D6
+:10DA500000000000000000000000000000000000C6
+:10DA600000000000000000000000000000000000B6
+:10DA700000000000000000000000000000000000A6
+:10DA80000000000000000000000000000000000096
+:10DA90000000000000000000000000000000000086
+:10DAA0000000000000000000000000000000000076
+:10DAB0000000000000000000000000000000000066
+:10DAC0000000000000000000000000000000000056
+:10DAD0000000000000000000000000000000000046
+:10DAE0000000000000000000000000000000000036
+:10DAF0000000000000000000000000000000000026
+:10DB00000000000000000000000000000000000015
+:10DB10000000000000000000000000000000000005
+:10DB200000000000000000000000000000000000F5
+:10DB300000000000000000000000000000000000E5
+:10DB400000000000000000000000000000000000D5
+:10DB500000000000000000000000000000000000C5
+:10DB600000000000000000000000000000000000B5
+:10DB700000000000000000000000000000000000A5
+:10DB80000000000000000000000000000000000095
+:10DB90000000000000000000000000000000000085
+:10DBA0000000000000000000000000000000000075
+:10DBB0000000000000000000000000000000000065
+:10DBC0000000000000000000000000000000000055
+:10DBD0000000000000000000000000000000000045
+:10DBE0000000000000000000000000000000000035
+:10DBF0000000000000000000000000000000000025
+:10DC00000000000000000000000000000000000014
+:10DC10000000000000000000000000000000000004
+:10DC200000000000000000000000000000000000F4
+:10DC300000000000000000000000000000000000E4
+:10DC400000000000000000000000000000000000D4
+:10DC500000000000000000000000000000000000C4
+:10DC600000000000000000000000000000000000B4
+:10DC700000000000000000000000000000000000A4
+:10DC80000000000000000000000000000000000094
+:10DC90000000000000000000000000000000000084
+:10DCA0000000000000000000000000000000000074
+:10DCB0000000000000000000000000000000000064
+:10DCC0000000000000000000000000000000000054
+:10DCD0000000000000000000000000000000000044
+:10DCE0000000000000000000000000000000000034
+:10DCF0000000000000000000000000000000000024
+:10DD00000000000000000000000000000000000013
+:10DD10000000000000000000000000000000000003
+:10DD200000000000000000000000000000000000F3
+:10DD300000000000000000000000000000000000E3
+:10DD400000000000000000000000000000000000D3
+:10DD500000000000000000000000000000000000C3
+:10DD600000000000000000000000000000000000B3
+:10DD700000000000000000000000000000000000A3
+:10DD80000000000000000000000000000000000093
+:10DD90000000000000000000000000000000000083
+:10DDA0000000000000000000000000000000000073
+:10DDB0000000000000000000000000000000000063
+:10DDC0000000000000000000000000000000000053
+:10DDD0000000000000000000000000000000000043
+:10DDE0000000000000000000000000000000000033
+:10DDF0000000000000000000000000000000000023
+:10DE00000000000000000000000000000000000012
+:10DE10000000000000000000000000000000000002
+:10DE200000000000000000000000000000000000F2
+:10DE300000000000000000000000000000000000E2
+:10DE400000000000000000000000000000000000D2
+:10DE500000000000000000000000000000000000C2
+:10DE600000000000000000000000000000000000B2
+:10DE700000000000000000000000000000000000A2
+:10DE80000000000000000000000000000000000092
+:10DE90000000000000000000000000000000000082
+:10DEA0000000000000000000000000000000000072
+:10DEB0000000000000000000000000000000000062
+:10DEC0000000000000000000000000000000000052
+:10DED0000000000000000000000000000000000042
+:10DEE0000000000000000000000000000000000032
+:10DEF0000000000000000000000000000000000022
+:10DF00000000000000000000000000000000000011
+:10DF10000000000000000000000000000000000001
+:10DF200000000000000000000000000000000000F1
+:10DF300000000000000000000000000000000000E1
+:10DF400000000000000000000000000000000000D1
+:10DF500000000000000000000000000000000000C1
+:10DF600000000000000000000000000000000000B1
+:10DF700000000000000000000000000000000000A1
+:10DF80000000000000000000000000000000000091
+:10DF90000000000000000000000000000000000081
+:10DFA0000000000000000000000000000000000071
+:10DFB0000000000000000000000000000000000061
+:10DFC0000000000000000000000000000000000051
+:10DFD0000000000000000000000000000000000041
+:10DFE0000000000000000000000000000000000031
+:10DFF0000000000000000000000000000000000021
+:10E000000000000000000000000000000000000010
+:10E010000000000000000000000000000000000000
+:10E0200000000000000000000000000000000000F0
+:10E0300000000000000000000000000000000000E0
+:10E0400000000000000000000000000000000000D0
+:10E0500000000000000000000000000000000000C0
+:10E0600000000000000000000000000000000000B0
+:10E0700000000000000000000000000000000000A0
+:10E080000000000000000000000000000000000090
+:10E090000000000000000000000000000000000080
+:10E0A0000000000000000000000000000000000070
+:10E0B0000000000000000000000000000000000060
+:10E0C0000000000000000000000000000000000050
+:10E0D0000000000000000000000000000000000040
+:10E0E0000000000000000000000000000000000030
+:10E0F0000000000000000000000000000000000020
+:10E10000000000000000000000000000000000000F
+:10E1100000000000000000000000000000000000FF
+:10E1200000000000000000000000000000000000EF
+:10E1300000000000000000000000000000000000DF
+:10E1400000000000000000000000000000000000CF
+:10E1500000000000000000000000000000000000BF
+:10E1600000000000000000000000000000000000AF
+:10E17000000000000000000000000000000000009F
+:10E18000000000000000000000000000000000008F
+:10E19000000000000000000000000000000000007F
+:10E1A000000000000000000000000000000000006F
+:10E1B000000000000000000000000000000000005F
+:10E1C000000000000000000000000000000000004F
+:10E1D000000000000000000000000000000000003F
+:10E1E000000000000000000000000000000000002F
+:10E1F000000000000000000000000000000000809F
+:10E20000000000000000000000000000000000000E
+:10E2100000000000000000000000000000000000FE
+:10E220000000000A000000000000000000000000E4
+:10E2300010000003000000000000000D0000000DB1
+:10E240003C020801244294003C03080124639634F4
+:10E25000AC4000000043202B1480FFFD244200044A
+:10E260003C1D080037BD9FFC03A0F0213C100800B6
+:10E27000261032103C1C0801279C94000E001274DA
+:10E28000000000000000000D3C02800030A5FFFFF0
+:10E2900030C600FF344301803C0880008D0901B87E
+:10E2A0000520FFFE00000000AC6400002404000212
+:10E2B000A4650008A066000AA064000BAC67001803
+:10E2C0003C03100003E00008AD0301B83C0560000A
+:10E2D0008CA24FF80440FFFE00000000ACA44FC029
+:10E2E0003C0310003C040200ACA44FC403E000084F
+:10E2F000ACA34FF89486000C00A050212488001491
+:10E3000000062B0200051080004448210109182B4B
+:10E310001060001100000000910300002C6400094F
+:10E320005080000991190001000360803C0D080134
+:10E3300025AD9090018D58218D67000000E0000808
+:10E340000000000091190001011940210109302B42
+:10E3500054C0FFF29103000003E000080000102108
+:10E360000A000CCC25080001910F0001240E000AC0
+:10E3700015EE00400128C8232F38000A1700003D81
+:10E38000250D00028D580000250F0006370E0100F4
+:10E39000AD4E0000910C000291AB000191A400026F
+:10E3A00091A60003000C2E00000B3C0000A71025D6
+:10E3B00000041A000043C8250326C025AD580004F8
+:10E3C000910E000691ED000191E7000291E5000336
+:10E3D000000E5E00000D6400016C30250007220075
+:10E3E00000C41025004518252508000A0A000CCC99
+:10E3F000AD430008910F000125040002240800022B
+:10E4000055E80001012020210A000CCC00804021A9
+:10E41000910C0001240B0003158B00160000000076
+:10E420008D580000910E000225080003370D0008EA
+:10E43000A14E00100A000CCCAD4D00009119000156
+:10E44000240F0004172F000B0000000091070002AA
+:10E45000910400038D43000000072A0000A410254A
+:10E460003466000425080004AD42000C0A000CCC00
+:10E47000AD46000003E000082402000127BDFFE8CC
+:10E48000AFBF0014AFB000100E0015E50080802172
+:10E490003C0480083485008090A600052403FFFE1C
+:10E4A0000200202100C310248FBF00148FB0001081
+:10E4B000A0A200050A0015EF27BD001827BDFFE840
+:10E4C000AFB00010AFBF00140E000FD40080802149
+:10E4D0003C06800834C5008090A40000240200504F
+:10E4E000308300FF106200073C09800002002021F9
+:10E4F0008FBF00148FB00010AD2001800A0010A65D
+:10E5000027BD0018240801003C07800002002021DC
+:10E510008FBF00148FB00010ACE801800A0010A675
+:10E5200027BD001827BDFF783C058008AFBE0080DE
+:10E53000AFB7007CAFB3006CAFB10064AFBF008475
+:10E54000AFB60078AFB50074AFB40070AFB200687A
+:10E55000AFB0006034A600803C0580008CB201287A
+:10E5600090C400098CA701043C020001309100FF17
+:10E5700000E218240000B8210000F021106000071C
+:10E58000000098213C0908008D2931F02413000176
+:10E59000252800013C010800AC2831F0ACA0008423
+:10E5A00090CC0005000C5827316A0001154000721C
+:10E5B000AFA0005090CD00002406002031A400FF41
+:10E5C00010860018240E0050108E009300000000EA
+:10E5D0003C1008008E1000DC260F00013C010800F2
+:10E5E000AC2F00DC0E00165E000000000040182179
+:10E5F0008FBF00848FBE00808FB7007C8FB60078FD
+:10E600008FB500748FB400708FB3006C8FB2006848
+:10E610008FB100648FB000600060102103E000083B
+:10E6200027BD00880000000D3C1F8000AFA0003017
+:10E6300097E501168FE201043C04002030B9FFFF8A
+:10E64000004438240007182B00033140AFA60030E7
+:10E650008FF5010437F80C003C1600400338802188
+:10E6600002B6A02434C40040128000479215000D69
+:10E6700032A800201500000234860080008030217E
+:10E6800014C0009FAFA600303C0D800835A6008066
+:10E6900090CC0008318B0040516000063C06800899
+:10E6A000240E0004122E00A8240F0012122F003294
+:10E6B0003C06800834C401003C0280009447011AE3
+:10E6C0009619000E909F00088E18000830E3FFFF97
+:10E6D00003F9B00432B40004AFB6005CAFA3005835
+:10E6E0008E1600041280002EAFB8005434C3008090
+:10E6F000906800083105004014A0002500000000CB
+:10E700008C70005002D090230640000500000000ED
+:10E710008C71003402D1A82306A201678EE20008A2
+:10E72000126000063C1280003C1508008EB531F4E2
+:10E7300026B600013C010800AC3631F4AE4000447E
+:10E74000240300018FBF00848FBE00808FB7007C40
+:10E750008FB600788FB500748FB400708FB3006CE3
+:10E760008FB200688FB100648FB00060006010212C
+:10E7700003E0000827BD00880E000D2800002021BE
+:10E780000A000D75004018210A000D9500C02021D7
+:10E790000E0016AE02C020211440FFE10000000070
+:10E7A0003C0B8008356400808C8A003402CA482300
+:10E7B0000520001D000000003C1E08008FDE310017
+:10E7C00027D700013C010800AC3731001260000679
+:10E7D000024020213C1408008E9431F42690000160
+:10E7E0003C010800AC3031F40E0015E53C1E8008F9
+:10E7F00037CD008091B700250240202136EE00047D
+:10E800000E0015EFA1AE00250E000CAC0240202139
+:10E810000A000DCA240300013C17080126F794F8EA
+:10E820000A000D843C1F80008C86003002C66023E5
+:10E830001980000C2419000C908F004F3C14080024
+:10E840008E94310032B500FC35ED0001268E0001BA
+:10E850003C010800AC2E3100A08D004FAFA0005845
+:10E860002419000CAFB900308C9800300316A02397
+:10E870001A80010B8FA300580074F82A17E0FFD309
+:10E88000000000001074002A8FA5005802D4B021A7
+:10E8900000B410233044FFFFAFA4005832A8000298
+:10E8A0001100002E32AB00103C15800836B00080FD
+:10E8B0009216000832D30040526000FB8EE200083E
+:10E8C0000E0015E502402021240A0018A20A0009C2
+:10E8D000921100052409FFFE024020210229902404
+:10E8E0000E0015EFA21200052404003900002821B3
+:10E8F0000E001689240600180A000DCA2403000120
+:10E9000092FE000C3C0A800835490080001EBB00C6
+:10E910008D27003836F10081024020213225F08118
+:10E920000E000C9B30C600FF0A000DC10000000065
+:10E930003AA7000130E300011460FFA402D4B02123
+:10E940000A000E1D00000000024020210E0016CB20
+:10E95000020028210A000D75004018211160FF7087
+:10E960003C0F80083C0D800835EE00808DC40038D7
+:10E970008FA300548DA60004006660231D80FF68ED
+:10E98000000000000064C02307020001AFA400548F
+:10E990003C1F08008FFF31E433F9000113200015FC
+:10E9A0008FAC00583C07800094E3011A10600012FD
+:10E9B0003C0680080E0020F8024020213C0308019C
+:10E9C0009063952930640002148001450000000026
+:10E9D000306C0004118000078FAC0058306600FBDB
+:10E9E0003C010801A026952932B500FCAFA00058D3
+:10E9F0008FAC00583C06800834D30080AFB40018B8
+:10EA0000AFB60010AFAC00143C088000950B01209D
+:10EA10008E6F0030966A005C8FA3005C8FBF003061
+:10EA20003169FFFF3144FFFF8FAE005401341021E4
+:10EA3000350540000064382B0045C82103E7C02598
+:10EA4000AFB90020AFAF0028AFB80030AFAF00249F
+:10EA5000AFA0002CAFAE0034926D000831B40008B6
+:10EA6000168000BB020020218EE200040040F8095D
+:10EA700027A400108FAF003031F300025660000170
+:10EA800032B500FE3C048008349F008093F90008F2
+:10EA900033380040530000138FA400248C850004F9
+:10EAA0008FA7005410A700D52404001432B0000131
+:10EAB0001200000C8FA400242414000C1234011A3C
+:10EAC0002A2D000D11A001022413000E240E000AAD
+:10EAD000522E0001241E00088FAF002425E40001FF
+:10EAE000AFA400248FAA00143C0B80083565008079
+:10EAF000008A48218CB10030ACA9003090A4004EAF
+:10EB00008CA700303408FFFC0088180400E3F821CB
+:10EB1000ACBF00348FA600308FB900548FB8005CB2
+:10EB200030C200081040000B033898218CAC002044
+:10EB3000119300D330C600FF92EE000C8FA7003473
+:10EB400002402021000E6B0035B400800E000C9BAB
+:10EB50003285F0803C028008345000808E0F0030F7
+:10EB600001F1302318C00097264800803C070800B8
+:10EB70008CE731E42404FF80010418243118007F5D
+:10EB80003C1F80003C19800430F10001AFE300908D
+:10EB900012200006031928213C03080190639529DF
+:10EBA00030690008152000C6306A00F73C10800864
+:10EBB00036040080908C004F318B000115600042BC
+:10EBC000000000003C0608008CC6319830CE0010D2
+:10EBD00051C0004230F9000190AF006B55E0003F9A
+:10EBE00030F9000124180001A0B8006B3C1180002E
+:10EBF0009622007A24470064A48700123C0D800806
+:10EC000035A5008090B40008329000401600000442
+:10EC10003C03800832AE000115C0008B00000000EC
+:10EC2000346400808C86002010D3000A3463010015
+:10EC30008C67000002C7782319E000978FBF00544B
+:10EC4000AC93002024130001AC760000AFB3005059
+:10EC5000AC7F000417C0004E000000008FA90050D8
+:10EC60001520000B000000003C030801906395296B
+:10EC7000306A00011140002E8FAB0058306400FE56
+:10EC80003C010801A02495290A000D7500001821F7
+:10EC90000E000CAC024020210A000F1300000000FF
+:10ECA0000A000E200000A0210040F80924040017EB
+:10ECB0000A000DCA240300010040F80924040016CC
+:10ECC0000A000DCA240300019094004F240DFFFE9A
+:10ECD000028D2824A085004F30F900011320000682
+:10ECE0003C0480083C03080190639529307F0010A4
+:10ECF00017E00051306800EF34900080240A0001D2
+:10ED0000024020210E0015E5A60A001292030025FC
+:10ED100024090001AFA90050346200010240202103
+:10ED20000E0015EFA20200250A000EF93C0D800826
+:10ED30001160FE83000018218FA5003030AC000464
+:10ED40001180FE2C8FBF00840A000DCB240300012C
+:10ED500027A500380E000CB6AFA000385440FF4382
+:10ED60008EE200048FB40038329001005200FF3F61
+:10ED70008EE200048FA3003C8E6E0058006E682364
+:10ED800005A3FF39AE6300580A000E948EE200041A
+:10ED90000E0015E5024020213C0380083468008005
+:10EDA000024020210E0015EFA11E000903C03021F2
+:10EDB000240400370E001689000028210A000F11D4
+:10EDC0008FA900508FAB00185960FF8D3C0D800853
+:10EDD0000E0015E502402021920C002524050001BB
+:10EDE000AFA5005035820004024020210E0015EF2F
+:10EDF000A20200250A000EF93C0D800812240059D9
+:10EE00002A2300151060004D240900162408000C68
+:10EE10005628FF2732B000013C0A8008914C001BA5
+:10EE20002406FFBD241E000E01865824A14B001BA2
+:10EE30000A000EA532B000013C010801A028952966
+:10EE40000A000EF93C0D80088CB500308EFE0008DB
+:10EE50002404001826B6000103C0F809ACB600303F
+:10EE60003C030801906395293077000116E0FF818B
+:10EE7000306A00018FB200300A000D753243000481
+:10EE80003C1080009605011A50A0FF2B34C60010DC
+:10EE90000A000EC892EE000C8C6200001456FF6D42
+:10EEA000000000008C7800048FB9005403388823D8
+:10EEB0000621FF638FBF00540A000F0E0000000000
+:10EEC0003C010801A02A95290A000F3030F9000101
+:10EED0001633FF028FAF00240A000EB0241E00106C
+:10EEE0000E0015E5024020213C0B800835680080AB
+:10EEF00091090025240A0001AFAA0050353300040F
+:10EF0000024020210E0015EFA11300253C05080149
+:10EF100090A5952930A200FD3C010801A022952969
+:10EF20000A000E6D004018212411000E53D1FEEA94
+:10EF3000241E00100A000EAF241E00165629FEDC07
+:10EF400032B000013C0A8008914C001B2406FFBD32
+:10EF5000241E001001865824A14B001B0A000EA598
+:10EF600032B000010A000EA4241E00123C038000EF
+:10EF70008C6201B80440FFFE24040800AC6401B8B0
+:10EF800003E00008000000000080502130A5FFFFD2
+:10EF900030C6FFFF3C0480008C8201B80440FFFEB5
+:10EFA00034880180AD0A00003C078008AC8A00204C
+:10EFB00094E300483067FFFF10E000423C0D800002
+:10EFC00024AB001200EB482B5120003F2404000327
+:10EFD00034820100945900208F8900002404001A13
+:10EFE0003338FFFF270BFFFE00EB782B39EE0001D3
+:10EFF00000096B8201AE6024A104000B518000491E
+:10F000008F8B00048F830004A50B0014346800016B
+:10F01000AF88000430CE004015C000333C048000AF
+:10F020003C02800034420180A445000E3C07800071
+:10F0300034EC0180A585001A8F85000C310B80000F
+:10F04000A5890010AD850028A58600081160000F75
+:10F050008F85001434EA0100954E001631CDFFFC77
+:10F0600025A40004008718218C67400030E6FFFFCC
+:10F0700014C000073C0480003C18FFFF370F7FFFDF
+:10F08000010F4024AF8800048F8500143C048000E9
+:10F090002402BFFF348301800102C824A479002622
+:10F0A00010A00004AC69002C00054402A465001007
+:10F0B000A46800263C091000AC8901B803E00008F0
+:10F0C000000000002404000335AC018030CE004075
+:10F0D0008F8900008F880004A184000B51C0FFD1EC
+:10F0E0003C0280003C048000AC8A00203C0F800879
+:10F0F00095EA00403143FFFF5060000834820180F0
+:10F1000000A3C02B5700000100A0182134990180F2
+:10F11000A723000E0A0010053C0780000A00100318
+:10F1200030C6FFBF2407FFFE016740240A000FFE20
+:10F13000AF88000427BDFFE88FA2002830A5FFFF9D
+:10F1400030C6FFFFAFBF0010AF87000CAF820014C6
+:10F15000AF8000040E000FDBAF8000008FBF0010F7
+:10F1600027BD001803E00008AF8000143C068000B3
+:10F1700034C4007034C701008C8A000090E500128E
+:10F180008F84000027BDFFF030A300FF000318822A
+:10F190003082400010400037246500030005C8801D
+:10F1A0000326C0218F0E4000246F0004000F6880EA
+:10F1B000AFAE000001A660218D8B4000AFAB000414
+:10F1C00094E900163128FFFC010638218CE6400046
+:10F1D000AFA600088FA900080000302100002821F8
+:10F1E0003C07080024E701000A00107E24080008FC
+:10F1F0009059000024A500012CAC000C0079C0211E
+:10F200000018788001E770218DCD00001180000684
+:10F2100000CD302603A5102114A8FFF500051A0023
+:10F220005520FFF4905900003C04800034870070A2
+:10F230003C0508008CA531048CE300002CA20020C2
+:10F2400010400009006A3823000548803C0B080084
+:10F25000256B3108012B402124AA0001AD070000D5
+:10F260003C010800AC2A310400C0102103E0000872
+:10F2700027BD0010308220001040000B0005588090
+:10F28000016648218D24400024680004000838806D
+:10F29000AFA4000000E618218C654000AFA0000874
+:10F2A0000A00106EAFA500040000000D0A00106FE8
+:10F2B0008FA9000827BDFFD83C058000AFB100141E
+:10F2C000AFB00010AFBF0024AFB40020AFB3001C3C
+:10F2D000AFB200188F87000034A401009483000EA1
+:10F2E00030E2400000008021104000103071FFFF2C
+:10F2F0003C08002000E8302410C0000D30EB8000F6
+:10F300008F890004240ABFFF00EA38243523100047
+:10F31000AF87000030F320001660000B3C1800049B
+:10F320002419FFBF0A0010CF0079102430EB8000B1
+:10F330001560004D3C0D002030F320001260FFF8F6
+:10F340008F8300043C18000400F8A0241280FFF50D
+:10F350002419FFBF3462004030FF010013E00010A9
+:10F36000AF8200048F820028104000063C0E80000F
+:10F370003C04002000E41824146000CE3C06000485
+:10F380003C0E800035CD010095AC001E95AB001CF5
+:10F390003189FFFF000B5400012A4025AF88000C83
+:10F3A0003C138000367401009692000C8E6340007E
+:10F3B000340FFFFF106F00843244FFFF30780100EC
+:10F3C000570000012410001030F9100053200008ED
+:10F3D0003612000130FF002017E000733C031000DC
+:10F3E00000E310241440006A3C0A0C0036120001AD
+:10F3F00030EC01001580000B3C0600018F880004F2
+:10F40000310D400015A0000800E628243C131F0120
+:10F4100000F378243C0E100011EE00AE3094020090
+:10F420003C06000100E6282410A000193C19100039
+:10F430003C0408008C84002430940002168000D91B
+:10F44000240300018FBF00248FB400208FB3001C61
+:10F450008FB200188FB100148FB00010006010211F
+:10F4600003E0000827BD002800ED60241180FFB3F1
+:10F4700030F320008F8E00043C12FFFF364F7FFFD9
+:10F4800000EF382435C380000A0010BEAF870000AB
+:10F4900000F9C0241700004E00002021AF800010AA
+:10F4A0003C0380003465010094AE000E8F91001083
+:10F4B00031CAFFFF108000C62553000430EF010061
+:10F4C00015E000703C180F003A2800022E7003EF80
+:10F4D0002D1900013A1F0001033F282414A0002227
+:10F4E000240400013C0308008C6300D02E25000C8E
+:10F4F000001121C0386C00012D8B00010165102422
+:10F50000144000143270FFFF262DFFFC2DA40004D0
+:10F510001480010300002021386A00022D460001FA
+:10F5200000C51824546000FF02002821262FFFF890
+:10F530002DEE000415C00007000000000007A242E5
+:10F540000011C02B0298482415200109020028212F
+:10F55000001121C002002821364600020E000FDBF8
+:10F560000000000000002021008018218FBF00242F
+:10F570008FB400208FB3001C8FB200188FB100141D
+:10F580008FB000100060102103E0000827BD0028A4
+:10F590003C090BFF00EA40243526FFFF00C8282B5A
+:10F5A00050A0FF93361200013C0B08008D6B002C1D
+:10F5B00036120005257000013C010800AC30002C1B
+:10F5C0000A0010F630EC01000A0010EB24100020B5
+:10F5D00000071602305F000F001F80C03C030801C7
+:10F5E00024639478020320211080FFADAF9F0010A8
+:10F5F000908800005100FFAB3C0380003C0D800070
+:10F6000035A90100952C000E240B00030240302187
+:10F61000318AFFFF25450004110B00D9000050215D
+:10F620009088000124140002311100FF123400BF41
+:10F6300030F80040310300FF24080001106800C8C2
+:10F6400030E200408C8A00048F8B00245560000655
+:10F6500034C60002254DFE002DAC0381558000010B
+:10F660003646004034C600020140202130A5FFFF8D
+:10F670000E000FDB30C6FFFF000040210A00110A18
+:10F680000100182100F8A0243C0902001289FF8F14
+:10F690003A28000290B100133270FFFF02002821C7
+:10F6A000322700FF24F30004001321C00A00115088
+:10F6B0003646000200E6282414A0FF323C0E8000EB
+:10F6C0000E0010543C1380008F8700000A0010E2E7
+:10F6D000AF82000C1680FF533C0600012624000474
+:10F6E0003085FFFF364600023C0380008C7101B874
+:10F6F0000620FFFE8F890008346A0180AD400000BB
+:10F70000112000B23C0D800024B800120138902B6B
+:10F71000124000AF240C0003347001009603002057
+:10F720002402001A30F94000307FFFFFA142000B95
+:10F73000132000AB27E3FFFE0123582B156000A91F
+:10F740002409FFFE35080001A5430014AF8800041A
+:10F750003C0E80002413BFFF0113782435C80180BC
+:10F76000A505000EA505001AA5060008A50F002690
+:10F77000A50700103C071000ADC701B80000182114
+:10F780008FBF00248FB400208FB3001C8FB20018ED
+:10F790008FB100148FB000100060102103E000084A
+:10F7A00027BD00283C1208008E5200D802202821D4
+:10F7B00024040080265100013C010800AC3100D82F
+:10F7C0000E000FDB240600030A0011D900001821E7
+:10F7D0008C65400030B1010012200046325900040F
+:10F7E0003C1F08008FFF002424140004172000028F
+:10F7F00033F0000D2414000200076AC239A400018E
+:10F800002E6C03EF30820001398B0001004B402544
+:10F81000110000033251FFFB2412FFFB021280246F
+:10F8200030E3010050600015321F00013C0A0F0058
+:10F8300000EA30243C07020010C7000F3C1980008A
+:10F840003725010090A900132418FFFE0218802418
+:10F85000312F00FF25EE0004000E21C0120000022F
+:10F86000023430253226FFFF0E000FDB3265FFFF2A
+:10F870001200FF3D00002021321F000113E0000DA7
+:10F88000320B000424080001120800020234302563
+:10F890003226FFFF000020210E000FDB3265FFFF44
+:10F8A0002402FFFE020280241200FF2F000020210C
+:10F8B000320B00045160000D240400010234302595
+:10F8C00024140004561400013226FFFF2411FFFB0C
+:10F8D0003265FFFF240401000E000FDB02119824A3
+:10F8E0001260FF2100002021240400010A001154AD
+:10F8F000008018213C0C08008D8C00243190000100
+:10F900005200FF19000020213265FFFF3646000239
+:10F910000E000FDB000020210A00115300002021FF
+:10F92000020028210A00115036460002130000068A
+:10F930000000000095300010949F000232190FFF64
+:10F9400013F9FF3D310300FF3C04080190849479D2
+:10F950001080FF3D240800010A00110A010018214F
+:10F960005040FF398C8A00040A00124B000000004E
+:10F970000E000FDB3246FFFB0A00114E001121C0C2
+:10F9800090830001240E0001106EFF3C240800014A
+:10F99000240F0002106F000430F30040240800011F
+:10F9A0000A00110A010018215260FFFD240800011D
+:10F9B000952500109487000230A9FFFF50E9FEA1B1
+:10F9C000010018210A00126124080001240C000320
+:10F9D00035AA0180A14C000B0A0011CE3C0E80001C
+:10F9E0002409FFFE0A0011CC0109402427BDFFC0F5
+:10F9F000AFB00018AFBF003C3C10600CAFBE003889
+:10FA0000AFB70034AFB60030AFB5002CAFB40028AC
+:10FA1000AFB30024AFB20020AFB1001C8E0E500077
+:10FA2000240FFF7F3C06800001CF682435AC380CE2
+:10FA3000240B0003AE0C5000ACCB00083C010800C6
+:10FA4000AC2000200E0017B0000000003C0A00109F
+:10FA5000354980513C066016AE09537C8CC70000C6
+:10FA60003C0860148D0500A03C03FFFF00E3202448
+:10FA70003C02535300051FC21082029B34C57C0018
+:10FA80008CBF007C8CA200783C1E600037C4202014
+:10FA90003C05080124A590C0AF820018AF9F001C50
+:10FAA0000E0016742406000A3C19000127399478C8
+:10FAB0003C010800AC3931DC0E00206BAF80001433
+:10FAC0008FD708082418FFF03C15570902F8B02416
+:10FAD00012D5028B24040001AF8000283C14800062
+:10FAE0003697010002E0F0218E90000032050003FD
+:10FAF00010A0FFFD3207000114E0005D3206000295
+:10FB000010C0FFF93C07800034E501408CB90000CB
+:10FB100024100040ACF9002090B8000833030070B6
+:10FB20001070010B286900411120000824080060B2
+:10FB3000241F0020107F000E3C0B40003C0680007C
+:10FB4000ACCB01780A0012B3000000001468FFFB80
+:10FB50003C0B40000E001F88000000003C0B4000E2
+:10FB60003C068000ACCB01780A0012B30000000014
+:10FB700090AB0009241100048CA70000316800FF3D
+:10FB80001111015D2512FFFA2E53000612600016B6
+:10FB90003C0680008CAA00048F86002494A3000AEF
+:10FBA000000A3E02310500FF10C000053064FFFF6F
+:10FBB0002CEC00081580000224E700042407000351
+:10FBC000240E000910AE01A128AF000A11E0018443
+:10FBD0002410000A2404000810A4001A000749C0D9
+:10FBE000012038213C0680008CD001B80600FFFEC1
+:10FBF00034C40180AC87000034C5014090B60008D1
+:10FC0000241900023C0B400032C200FF00028A00AF
+:10FC10000228F825A49F0008A099000B94A7000AC9
+:10FC20003C081000A48700108CB80004AC98002495
+:10FC3000ACC801B83C068000ACCB01780A0012B316
+:10FC400000000000000AC202330300FF2405000187
+:10FC50005465FFE4012038218F990020AF830024F0
+:10FC600027270001AF8700200A0012F20120382167
+:10FC70008FD100283C0B8008AE9100208FC6000475
+:10FC80008FCA000095690048AF860000AF8A000463
+:10FC90003128FFFF0E000FD4AF8800083C03080096
+:10FCA0008C6300C0106000258F8700003C0E0800A8
+:10FCB0008DCE00C425CD00013C010800AC2D00C450
+:10FCC0003C1F800037E901008D3900243C0760208B
+:10FCD000ACF90014000000003C0680003C08400025
+:10FCE000ACC80138000000005220FF853206000237
+:10FCF000262D0140262E00802404FF8001A4282404
+:10FD000001C47824000F194031CC007F00059940D0
+:10FD100031B2007F3C15200036A20002006C502555
+:10FD20000272B02502C2882501425825ACCB0830AA
+:10FD3000ACD108300A0012B9320600023C120010A1
+:10FD400000F2782415E000708F8300043C1808004E
+:10FD50008F18002097D6000E30F5400027130001C1
+:10FD60003C010800AC3300200000902112A000816B
+:10FD700032D3FFFF3C1F002000FFC8241320007E69
+:10FD800030E580008F8200042404BFFF00E43824A3
+:10FD900034431000AF87000030EB20001160007387
+:10FDA000240EFFBF3C0D000400ED60241180000212
+:10FDB000006E10243462004030EF010011E00010AA
+:10FDC000AF8200048F95002812A000073C18002085
+:10FDD00000F8B02412C000043C1F000400FFC82437
+:10FDE0001320016D0000000096E3001E96E8001C41
+:10FDF0003065FFFF0008140000A22025AF84000C2E
+:10FE000096EA000C8E8440003409FFFF10890085BB
+:10FE10003145FFFF3086010054C00001241200105C
+:10FE200030EB1000116000133656000130EC00205A
+:10FE30001580000A3C0E100000EE682411A0000D91
+:10FE40003C190C003C180BFF00F9B0243715FFFFDC
+:10FE500002B6782B11E00007365600013C1F08005F
+:10FE60008FFF002C3656000527F200013C010800E8
+:10FE7000AC32002C30E401001480000B3C06000181
+:10FE80008F880004310240005440000800E6282416
+:10FE90003C0A1F0100EA48243C0310001123010919
+:10FEA00030A602003C06000100E6282410A0003E17
+:10FEB0003C1810003C0D08008DAD002431AC000250
+:10FEC0001580000624030001006010211040FF830C
+:10FED0003C0680000A00132A3C1F80003C0F0800EB
+:10FEE0008DEF00D8026028212404008025EE000157
+:10FEF0003C010800AC2E00D80E000FDB24060003E6
+:10FF00000A0013AB000018212405BFFF0065682418
+:10FF100011A00007240F87FF006F702415C0000890
+:10FF20003C18006000F8202410800005000000004C
+:10FF30000E000D42000000000A0013AC000000009B
+:10FF40000E00159C000000000A0013AC0000000029
+:10FF50000E0015F4000000003C0B40003C06800041
+:10FF6000ACCB01780A0012B3000000000A0013674E
+:10FF7000006E102430E5800010A0FF878F830004FE
+:10FF80003C08002000E818245060FF838F830004A1
+:10FF90008F8900043C06FFFF34CA7FFF00EA382443
+:10FFA0000A00135E3523800000F8A82416A0001F65
+:10FFB00000004021AF8000103C0380003464010049
+:10FFC0009486000E8F93001030C5FFFF1100014E84
+:10FFD00024B5000430EA0100114000553A7F0002C8
+:10FFE0003C0E0F0000EE68243C0C020011AC0051E6
+:10FFF0002EB203EF908F001332B2FFFF31E400FF07
+:020000040001F9
+:1000000024870004000721C00240282136C60002D0
+:100010000E000FDB00000000000020210A0013ABDF
+:10002000008018210A0013812412002000072602F4
+:100030003099000F0019F8C03C120801265294783C
+:1000400003F240211100FFDCAF990010910900007C
+:100050001120FFDA3C0380003C138000366A010067
+:10006000954B000E2403000302C030213162FFFFD4
+:1000700024450004112300EC000020219109000117
+:10008000240D0002312E00FF11CD00FA313200FFA5
+:10009000240900011249001030FF00408D040004C3
+:1000A0008F8300241460000634D30002248BFE00EA
+:1000B0002D6203815440000136C6004034D3000253
+:1000C00030A5FFFF0E000FDB3266FFFF0000482166
+:1000D0000A0013AB0120182153E0FFF18D04000446
+:1000E0003C080801910894791100FFED24090001F2
+:1000F0000A0013AB012018213C0480008C8A01B84F
+:100100000540FFFE349601802415001CAEC7000098
+:10011000A2D5000B3C021000AC8201B83C0B4000A1
+:100120003C068000ACCB01780A0012B3000000004E
+:100130002EB203EF2FF900013A4900010329C02430
+:100140001700FFB6240400013C0308008C6300D0B4
+:100150002E65000C001321C0386B00012D620001D8
+:10016000004540241500FFA832B2FFFF266AFFFCBD
+:100170002D46000414C0001300002021386D000239
+:100180002DAC0001018518241460000F02402821C5
+:10019000266EFFF82DC5000414A0FF9B0000000090
+:1001A00000077A420013382B01E7A82456A0000864
+:1001B00002402821001321C0024028210A0013FD1B
+:1001C00036C60002024028210A0013FD36C600028E
+:1001D0000E000FDB32C6FFFB0A001467001321C0BC
+:1001E00010B0007200045A022406000B14A6FE7C14
+:1001F000000749C0314600FF00065600000A5E03B2
+:10020000056200B030C6007F000670C03C0F0801D8
+:1002100025EF947801CFA821A2A00001A2A00000A0
+:100220003C1360008E631820240D000100CD4804AB
+:1002300000096027000749C0006C90240120382184
+:10024000AE7218200A0012F2A6A0000214C0004BE1
+:100250008F8C0020000749C03C0B8000AD69002056
+:100260003C118008963F004013E000022405000185
+:10027000240500413C0480008C8A01B80540FFFE43
+:100280003496018024120003AEC90000A2D2000BF4
+:10029000A6C0000EA6C0001AA6C00010AEC000285E
+:1002A000A6C5000896D3002636750001A6D50026FF
+:1002B000AEC0002C3C021000AC8201B80A0012F261
+:1002C0000120382114C0FEF83C060001266B000412
+:1002D0003165FFFF36C600023C0380008C7301B815
+:1002E0000660FFFE8F8900083C0D800035AC018060
+:1002F000AD800000512000DD3C09800024AF0012D9
+:10030000012F702B51C000D93C09800096F20020CB
+:100310003C1980002418001A3256FFFF372A01804A
+:1003200030F54000A158000B12A000D526C3FFFEF7
+:100330000123F82B17E000D32404FFFE3508000149
+:10034000A5430014AF8800042413BFFF3C0B8000BA
+:100350000113502435680180A505000EA505001A7B
+:10036000A5060008A50A0026A50700103C071000F6
+:10037000AE8701B80A0013AB00001821000749C07E
+:100380002583FFFF1460FE16AF8300200120382173
+:100390000A0012F2AF8000240E001054000000008A
+:1003A0008F8700000A001379AF82000C240300FF3E
+:1003B0001163FE0B000749C010C00038000B760027
+:1003C000000B20C03C0908012529947800891821D8
+:1003D00024020001A06200003C16080126D6947891
+:1003E0003C0208012442947C00962821000749C061
+:1003F00000828821000AFC02AE290000A0BF000193
+:100400003C0460008C9818202419000101793804FC
+:100410000307302501203821A4AA0002AC86182049
+:100420000A0012F33C06800091030001241600012B
+:100430001076FF272409000124050002106500043E
+:1004400030E60040240900010A0013AB0120182106
+:1004500050C0FFFD24090001954C0010950A0002D0
+:100460003187FFFF5147FE98012018210A00150B24
+:100470002409000130EF004011E0FF1900000000E6
+:10048000955900109518000233350FFF1715FF140A
+:10049000313200FF0A00141E24090001000E6E0311
+:1004A00005A2000F316B007F10E30008000B20C095
+:1004B0003C10080126109478009018210A0014EED0
+:1004C000240200020A00147BAF8000203C0F0801C8
+:1004D00025EF9478008F18210A0014EE24020003FF
+:1004E0000A001523AF8B00200003A080028698210C
+:1004F0008E7200043C1160000A00129902512821FA
+:100500000A0012B0AF8400288C64400030930100D0
+:100510001260004B240900043C1908008F390024A4
+:1005200032D80004AFA90010170000033332000DC9
+:10053000241F0002AFBF001000071AC2386A000172
+:100540002EA603EF3142000138CB0001004B4025BD
+:100550001100000332D3FFFB2416FFFB0256902448
+:1005600030EC010011800016324800013C0E0F00F3
+:1005700000EE28243C0D020010AD00113C1F80004D
+:1005800037E90100913800138FAF00102419FFFEE6
+:10059000330400FF2487000402599024000721C07F
+:1005A00012400002026F30253266FFFF0E000FDBA3
+:1005B00032A5FFFF1240FE990000202132480001C1
+:1005C0001100000E324A00048FAB0010240200011B
+:1005D00012420002026B30253266FFFF000020212C
+:1005E0000E000FDB32A5FFFF2406FFFE024690241B
+:1005F0001240FE8A00002021324A00045140000EC1
+:10060000240400018FB600102403000412430002EA
+:10061000027630253266FFFF2413FFFB32A5FFFF71
+:10062000240401000E000FDB0253A82412A0FE7B5D
+:1006300000002021240400010A0013AB00801821CF
+:100640003C0C08008D8C0024319200015240FE7356
+:100650000000202132A5FFFF36C600020E000FDB8E
+:10066000000020210A0014000000202124020003C1
+:1006700035230180A062000B0A0014CC2413BFFFB5
+:100680002404FFFE0A0014CA010440243C03800035
+:10069000346401008C85000030A2003E1440000844
+:1006A00000000000AC6000488C87000030E607C006
+:1006B00010C0000500000000AC60004CAC600050B1
+:1006C00003E0000824020001AC600054AC6000406C
+:1006D0008C880000310438001080FFF90000000011
+:1006E0002402000103E00008AC6000443C038000E9
+:1006F0008C6201B80440FFFE34670180ACE4000066
+:1007000024080001ACE00004A4E500082405000270
+:10071000A0E8000A34640140A0E5000B9483000ABD
+:1007200014C00008A4E30010ACE000243C078000E3
+:1007300034E901803C041000AD20002803E00008EB
+:10074000ACE401B88C8600043C041000ACE6002444
+:100750003C07800034E90180AD20002803E0000858
+:10076000ACE401B83C0680008CC201B80440FFFE36
+:1007700034C7018024090002ACE40000ACE40004AA
+:10078000A4E50008A0E9000A34C50140A0E9000B77
+:1007900094A8000A3C041000A4E80010ACE0002477
+:1007A0008CA30004ACE3002803E00008ACC401B84B
+:1007B0003C03900034620001008220253C0380004D
+:1007C000AC6400208C65002004A0FFFE0000000047
+:1007D00003E00008000000003C02800034430001F8
+:1007E0000083202503E00008AC44002027BDFFE083
+:1007F0003C098000AFBF0018AFB10014AFB00010CB
+:10080000352801408D10000091040009910700086F
+:1008100091050008308400FF30E600FF00061A0052
+:100820002C820081008330251040002A30A50080F2
+:10083000000460803C0D080125AD90E8018D582131
+:100840008D6A000001400008000000003C038000A9
+:10085000346201409445000A14A0001E8F91FCB838
+:100860009227000530E6000414C0001A00000000C2
+:100870000E0015E502002021922A00050200202129
+:10088000354900040E0015EFA22900059228000545
+:100890003104000414800002000000000000000D7C
+:1008A000922D0000240B002031AC00FF158B0009B5
+:1008B0003C0580008CAE01B805C0FFFE34B101805C
+:1008C000AE3000003C0F100024100005A230000BD9
+:1008D000ACAF01B80000000D8FBF00188FB100143D
+:1008E0008FB0001003E0000827BD00200200202187
+:1008F00000C028218FBF00188FB100148FB00010E6
+:10090000240600010A0015B427BD00200000000DD8
+:100910000200202100C028218FBF00188FB10014D1
+:100920008FB00010000030210A0015B427BD002050
+:1009300014A0FFE800000000020020218FBF001873
+:100940008FB100148FB0001000C028210A0015D20A
+:1009500027BD00203C0780008CEE01B805C0FFFEDB
+:1009600034F00180241F0002A21F000B34F8014064
+:10097000A60600089719000A3C0F1000A6190010DF
+:100980008F110004A6110012ACEF01B80A00163056
+:100990008FBF001827BDFFE8AFBF00100E000FD4B7
+:1009A000000000003C0280008FBF001000002021EA
+:1009B000AC4001800A0010A627BD00183084FFFF5C
+:1009C00030A5FFFF108000070000182130820001D1
+:1009D0001040000200042042006518211480FFFB33
+:1009E0000005284003E000080060102110C0000747
+:1009F000000000008CA2000024C6FFFF24A5000414
+:100A0000AC82000014C0FFFB2484000403E0000853
+:100A10000000000010A0000824A3FFFFAC86000027
+:100A200000000000000000002402FFFF2463FFFF1D
+:100A30001462FFFA2484000403E0000800000000B0
+:100A40003C03800027BDFFF834620180AFA20000A4
+:100A5000308C00FF30AD00FF30CE00FF3C0B80003B
+:100A60008D6401B80480FFFE000000008FA9000023
+:100A70008D6801288FAA00008FA700008FA40000B6
+:100A80002405000124020002A085000A8FA30000B3
+:100A9000359940003C051000A062000B8FB80000A3
+:100AA0008FAC00008FA600008FAF000027BD0008AC
+:100AB000AD280000AD400004AD800024ACC000288B
+:100AC000A4F90008A70D0010A5EE001203E000082D
+:100AD000AD6501B83C06800827BDFFE834C500803D
+:100AE000AFBF001090A700092402001230E300FFFE
+:100AF0001062000B008030218CA800500088202359
+:100B0000048000088FBF00108CAA00342404003930
+:100B10000000282100CA48230520000524060012F1
+:100B20008FBF00102402000103E0000827BD001859
+:100B30000E001689000000008FBF00102402000183
+:100B400003E0000827BD001827BDFFC8AFB2003082
+:100B5000AFB00028AFBF0034AFB1002C00A080219F
+:100B600090A5000D30A6001010C00010008090214C
+:100B70003C0280088C4400048E0300081064000CC2
+:100B800030A7000530A6000510C000932404000122
+:100B90008FBF00348FB200308FB1002C8FB000288F
+:100BA0000080102103E0000827BD003830A70005B1
+:100BB00010E0000F30AB001210C00006240400014A
+:100BC0003C0980088E0800088D2500045105009C12
+:100BD000240400388FBF00348FB200308FB1002C56
+:100BE0008FB000280080102103E0000827BD0038E6
+:100BF000240A0012156AFFE62404000102002021E5
+:100C000027A500100E000CB6AFA000101440007C09
+:100C10003C198008372400809098000833110008A0
+:100C20001220000A8FA7001030FF010013E000A47B
+:100C30008FA300148C860058006610230440000423
+:100C40003C0A8008AC8300588FA700103C0A80083B
+:100C50003548008091090008312400081480000202
+:100C600024080003000040213C1F800893F100117C
+:100C700093F9001237E600808CCC0054333800FF23
+:100C800003087821322D00FF000F708001AE28216B
+:100C900000AC582B1160006F0000000094CA005C8B
+:100CA0008CC900543144FFFF012510230082182B0A
+:100CB00014600068000000008CCB0054016518230C
+:100CC00030EC00041180006C000830808FA8001CFC
+:100CD0000068102B1040006230ED00040066102305
+:100CE0002C46008010C000020040882124110080A2
+:100CF0000E0015E5024020213C0D800835A600803D
+:100D000024070001ACC7000C90C80008001148403F
+:100D100035A70100310C007FA0CC00088E0500042F
+:100D200024AB0001ACCB0030A4D1005C8CCA003CE9
+:100D30009602000E01422021ACC400208CC3003C6E
+:100D40000069F821ACDF001C8E190004ACF900002A
+:100D50008E180008ACF800048FB10010322F000884
+:100D600055E0004793A60020A0C0004E90D8004E4A
+:100D70002411FFDFA0F8000890CF000801F17024D3
+:100D8000A0CE00088E0500083C0B80083569008065
+:100D9000AD2500388D6A00148D22003024190050D2
+:100DA00001422021AD24003491230000307F00FF58
+:100DB00013F90036264F01000E0015EF02402021E6
+:100DC00024040038000028210E0016892406000A99
+:100DD0000A0016EE240400010E000D280000202158
+:100DE0008FBF00348FB200308FB1002C8FB000283D
+:100DF000004020210080102103E0000827BD0038BA
+:100E00008E0E00083C0F800835F00080AE0E0054B6
+:100E100002402021AE0000300E0015E50000000069
+:100E2000920D00250240202135AC00200E0015EF68
+:100E3000A20C00250E000CAC024020212404003836
+:100E40002405008D0E001689240600120A0016EEF5
+:100E50002404000194C5005C0A00172930A3FFFF99
+:100E60002407021811A0FF9E00E610238FAE001C7D
+:100E70000A00173101C610230A00172E2C6202182F
+:100E8000A0E600080A00175B8E0500082406FF8014
+:100E900001E6C0243C118000AE3800288E0D000809
+:100EA00031E7007F3C0E800C00EE6021AD8D00E04C
+:100EB0008E080008AF8C00340A001767AD8800E484
+:100EC000AC800058908500082403FFF700A3382465
+:100ED000A08700080A00170C8FA700103C05080027
+:100EE00024A55F043C04080024846E503C020800E2
+:100EF00024425F0C240300063C010801AC2594F851
+:100F00003C010801AC2494FC3C010801AC22950092
+:100F10003C010801A023950403E000080000000044
+:100F200003E00008240200013C028000308800FF3A
+:100F3000344701803C0680008CC301B80460FFFE8A
+:100F4000000000008CC501282418FF803C0D800A99
+:100F500024AF010001F8702431EC007FACCE0024F6
+:100F6000018D2021ACE50000948B00EA350960007A
+:100F700024080002316AFFFFACEA000424020001E9
+:100F8000A4E90008A0E8000BACE000243C07100036
+:100F9000ACC701B8AF84003403E00008AF85006837
+:100FA000938800448F89005C8F82003430C600FF34
+:100FB0000109382330E900FF0122182130A500FF84
+:100FC0002468008810C000020124382100803821E4
+:100FD00030E400031480000330AA00031140000D28
+:100FE000312B000310A000090000102190ED00003B
+:100FF000244E000131C200FF0045602BA10D00000E
+:1010000024E700011580FFF92508000103E000082E
+:10101000000000001560FFF30000000010A0FFFBBF
+:10102000000010218CF8000024590004332200FF36
+:101030000045782BAD18000024E7000415E0FFF907
+:101040002508000403E00008000000009385004428
+:10105000938800548F87005C000432003103007FC6
+:1010600000E5102B30C47F001040000F00642825DD
+:101070008F8400343C0980008C8A00ECAD2A00A4E7
+:101080003C03800000A35825AC6B00A08C6C00A032
+:101090000580FFFE000000008C6D00ACAC8D00EC04
+:1010A00003E000088C6200A80A0018198F8400343D
+:1010B000938800553C02800000805021310300FEDF
+:1010C000A383005530ABFFFF30CC00FF30E7FFFFBC
+:1010D000344801803C0980008D2401B80480FFFE63
+:1010E0008F8D006824180016AD0D00008D2201249C
+:1010F0008F8D0034AD0200048D590020A507000833
+:10110000240201C4A119000AA118000B952F012087
+:101110008D4E00088D470004978300588D59002498
+:1011200001CF302100C7282100A320232418FFFF6E
+:10113000A504000CA50B000EA5020010A50C0012C2
+:10114000AD190018AD18002495AF00E83C0B100055
+:101150002407FFF731EEFFFFAD0E00288DAC0084B1
+:10116000AD0C002CAD2B01B88D46002000C7282403
+:1011700003E00008AD4500208F880034008058212E
+:1011800030E7FFFF910900D63C02800030A5FFFF49
+:10119000312400FF00041A000067502530C600FF0C
+:1011A000344701803C0980008D2C01B80580FFFE8A
+:1011B0008F820068240F0017ACE200008D390124F3
+:1011C000ACF900048D780020A4EA0008241901C4B9
+:1011D000A0F8000AA0EF000B952301208D6E0008F7
+:1011E0008D6D00049784005801C35021014D60218A
+:1011F00001841023A4E2000CA4E5000EA4F9001061
+:10120000A4E60012ACE000148D780024240DFFFF4A
+:10121000ACF800188D0F007CACEF001C8D0E007830
+:101220003C0F1000ACEE0020ACED0024950A00BE8F
+:10123000240DFFF73146FFFFACE60028950C008037
+:101240009504008231837FFF0003CA003082FFFFD4
+:101250000322C021ACF8002CAD2F01B8950E0082FE
+:101260008D6A002000AE3021014D2824A5060082A1
+:1012700003E00008AD6500203C0280003445018099
+:101280003C0480008C8301B80460FFFE8F8A00401C
+:10129000240600199549001C3128FFFF000839C0B9
+:1012A000ACA70000A0A6000B3C05100003E000085E
+:1012B000AC8501B88F8700480080402130C400FF12
+:1012C0003C0680008CC201B80440FFFE8F89006894
+:1012D0009383006434996000ACA90000A0A30005CA
+:1012E0008CE20010240F00022403FFF7A4A20006E2
+:1012F000A4B900088D180020A0B8000AA0AF000B08
+:101300008CEE0000ACAE00108CED0004ACAD00140F
+:101310008CEC001CACAC00248CEB0020ACAB0028A7
+:101320008CEA002C3C071000ACAA002C8D0900248C
+:10133000ACA90018ACC701B88D05002000A320247B
+:1013400003E00008AD0400208F86003427BDFFE0D5
+:10135000AFB10014AFBF0018AFB0001090C300D4FD
+:1013600030A500FF30620020104000080080882176
+:101370008CCB00D02409FFDF256A0001ACCA00D065
+:1013800090C800D401093824A0C700D414A000409C
+:101390003C0C80008F840034908700D42418FFBF59
+:1013A0002406FFEF30E3007FA08300D4979F00580E
+:1013B0008F82005C8F8D003403E2C823A799005808
+:1013C000A5A000BC91AF00D401F87024A1AE00D458
+:1013D0008F8C0034A18000D78F8A0034A540008212
+:1013E000AD4000EC914500D400A65824A14B00D498
+:1013F0008F9000308F84005C97860058020428216B
+:1014000010C0000FAF850030A38000543C0780005F
+:101410008E2C000894ED01208E2B0004018D5021AC
+:10142000014B8021020620233086FFFF30C8000FC9
+:10143000390900013131000116200009A388005448
+:10144000938600448FBF00188FB100148FB0001036
+:1014500027BD0020AF85006003E00008AF86005C78
+:1014600000C870238FBF0018938600448FB100140A
+:101470008FB0001034EF0C00010F282127BD002091
+:10148000ACEE0084AF85006003E00008AF86005C2E
+:1014900035900180020028210E0018A62406008243
+:1014A0008F840034908600D430C5004050A0FFBA2D
+:1014B000A38000648F8500483C0680008CCD01B875
+:1014C00005A0FFFE8F8900682408608224070002BF
+:1014D000AE090000A6080008A207000B8CA30008B4
+:1014E0003C0E1000AE0300108CA2000CAE020014E3
+:1014F0008CBF0014AE1F00188CB90018AE19002460
+:101500008CB80024AE1800288CAF0028AE0F002C39
+:10151000ACCE01B80A0018DFA38000648F8A0034C3
+:1015200027BDFFE0AFB10014AFB000108F88005CA2
+:10153000AFBF001893890038954200BC30D100FF3E
+:101540000109182B0080802130AC00FF3047FFFFDD
+:101550000000582114600003310600FF01203021F3
+:1015600001095823978300580068202B1480002716
+:101570000000000010680056241900011199006352
+:1015800034E708803165FFFF0E0018570200202164
+:101590008F8300683C07800034E601803C058000B2
+:1015A0008CAB01B80560FFFE240A00188F8400345C
+:1015B000ACC30000A0CA000B948900BE3C08100018
+:1015C000A4C90010ACC00030ACA801B8948200805F
+:1015D00024430001A4830080949F00803C060800FF
+:1015E0008CC6318833EC7FFF1186005E000000005E
+:1015F00002002021022028218FBF00188FB1001483
+:101600008FB000100A0018CB27BD0020914400D4F1
+:101610002403FF8000838825A15100D497840058BB
+:101620003088FFFF51000023938C00388F850034F1
+:101630002402EFFF008B782394AE00BC0168502B8E
+:1016400031E900FF01C26824A4AD00BC514000395B
+:10165000010058213C1F800037E601008CD80004AF
+:101660003C190001031940245500000134E74000F3
+:101670008E0A00202403FFFB2411000101432024D3
+:10168000AE0400201191002D34E7800002002021DB
+:10169000012030210E0018573165FFFF9787005851
+:1016A0008F89005CA780005801278023AF90005CE1
+:1016B000938C00388F8B00348FBF00188FB10014CB
+:1016C0008FB0001027BD002003E00008A16C00D7F8
+:1016D0003C0D800035AA01008D4800043C09000142
+:1016E0000109282454A0000134E740008E0F002097
+:1016F0002418FFFB34E7800001F87024241900014E
+:10170000AE0E00201599FF9F34E7088002002021CB
+:101710000E0018253165FFFF02002021022028213C
+:101720008FBF00188FB100148FB000100A0018CBC3
+:1017300027BD00200A00198E000048210200202148
+:10174000012030210E0018253165FFFF97870058D2
+:101750008F89005CA7800058012780230A0019A503
+:10176000AF90005C948C0080241F8000019F302487
+:10177000A4860080908B0080908F0080316700FFEE
+:101780000007C9C20019C027001871C031ED007FE1
+:1017900001AE2825A08500800A00197602002021CC
+:1017A000938500642403000127BDFFE800A33004F3
+:1017B0002CA20020AFB00010AFBF001400C0182151
+:1017C000104000132410FFFE3C0708008CE7319006
+:1017D00000E610243C088000350501801440000517
+:1017E000240600848F890034240A00042410FFFF9B
+:1017F000A12A00FC0E0018A6000000000200102123
+:101800008FBF00148FB0001003E0000827BD001840
+:101810003C0608008CC631940A0019EE00C310245F
+:101820008F87004027BDFFE0AFB20018AFB10014B2
+:10183000AFB00010AFBF001C30D000FF90E6000D2D
+:1018400000A088210080902130C5007FA0E5000D18
+:101850008F8500348E2300188CA200D01062002ED9
+:10186000240A000E0E0019E1A38A00642409FFFF78
+:10187000104900222404FFFF520000200000202114
+:101880008E2600003C0C001000CC58241560003956
+:101890003C0E000800CE682455A0003F02402021E5
+:1018A0003C18000200D880241200001F3C0A0004EB
+:1018B0008F8700408CE200148CE300108CE500144C
+:1018C0000043F82303E5C82B132000050240202124
+:1018D0008E24002C8CF10010109100310240202148
+:1018E00024020012A38200640E0019E12412FFFFFB
+:1018F000105200022404FFFF000020218FBF001CB3
+:101900008FB200188FB100148FB00010008010212A
+:1019100003E0000827BD002090A800D43504002073
+:101920000A001A17A0A400D400CA48241520000BEE
+:101930008F8B00408F8D00408DAC00101580000B08
+:10194000024020218E2E002C51C0FFEC00002021EF
+:10195000024020210A001A32240200178D6600106E
+:1019600050C0FFE600002021024020210A001A3268
+:101970002402001102402021240200150E0019E16A
+:10198000A3820064240FFFFF104FFFDC2404FFFF3D
+:101990000A001A218E2600000A001A582402001498
+:1019A0003C08000400C8382450E0FFD40000202187
+:1019B000024020210A001A32240200138F850034CD
+:1019C00027BDFFD8AFB3001CAFB20018AFB10014F1
+:1019D000AFB00010AFBF002090A700D48F90004898
+:1019E0002412FFFF34E2004092060000A0A200D4BF
+:1019F0008E030010008098211072000630D1003F45
+:101A00002408000D0E0019E1A3880064105200257F
+:101A10002404FFFF8F8A00348E0900188D4400D003
+:101A20001124000702602021240C000E0E0019E191
+:101A3000A38C0064240BFFFF104B001A2404FFFF4B
+:101A400024040020122400048F8D003491AF00D4B0
+:101A500035EE0020A1AE00D48F85005010A00019F3
+:101A6000000000001224004A8F9800348F92FCB8C6
+:101A7000971000809651000A523000488F93003C26
+:101A80003C1F08008FFF318C03E5C82B1720001E78
+:101A900002602021000028210E00194024060001C8
+:101AA000000020218FBF00208FB3001C8FB20018D0
+:101AB0008FB100148FB000100080102103E00008E7
+:101AC00027BD00285224002A8E0500148F8400347C
+:101AD000948A008025490001A489008094880080B0
+:101AE0003C0208008C42318831077FFF10E2000E73
+:101AF00000000000026020210E0018CB2405000128
+:101B00000A001AA2000020212402002D0E0019E173
+:101B1000A38200642403FFFF1443FFE12404FFFFBA
+:101B20000A001AA38FBF002094990080241F800010
+:101B300024050001033FC024A498008090920080F7
+:101B4000908E0080325100FF001181C20010782772
+:101B5000000F69C031CC007F018D5825A08B00801B
+:101B60000E0018CB026020210A001AA200002021DA
+:101B70002406FFFF54A6FFD68F8400340260202184
+:101B80000E0018CB240500010A001AA20000202133
+:101B9000026020210A001ABC2402000A2404FFFD6E
+:101BA0000A001AA2AF93005C8F88003427BDFFE8BB
+:101BB000AFB00010AFBF0014910A00D48F87004867
+:101BC00000808021354900408CE60010A10900D436
+:101BD0003C0208008C4231B030C53FFF00A2182BF8
+:101BE000106000078F85004C240DFF8090AE000D23
+:101BF00001AE6024318B00FF156000080006C3822F
+:101C0000020020212403000D8FBF00148FB00010AC
+:101C100027BD00180A0019E1A383006433060003FE
+:101C2000240F000254CFFFF70200202194A2001CD1
+:101C30008F85003424190023A4A200E88CE800005A
+:101C400000081E02307F003F13F900353C0A008374
+:101C50008CE800188CA600D01106000800000000D7
+:101C60002405000E0E0019E1A38500642407FFFF80
+:101C7000104700182404FFFF8F85003490A900D47A
+:101C800035240020A0A400D48F8C0040918E000D3C
+:101C900031CD007FA18D000D8F8300501060001C9E
+:101CA000020020218F84004C8C9800100303782BB5
+:101CB00011E0000D2419001802002021A3990064EE
+:101CC0000E0019E12410FFFF105000022404FFFF52
+:101CD000000020218FBF00148FB000100080102161
+:101CE00003E0000827BD00188C8600108F9F00407D
+:101CF0000200202100C31023AFE2001024050001E0
+:101D00000E001940240600010A001B2E00002021AD
+:101D10000E0018CB240500010A001B2E0000202114
+:101D2000010A5824156AFFD98F8C0040A0A600FC38
+:101D30000A001B1BA386005630A500FF24060001E5
+:101D400024A9000100C9102B1040000C0000402104
+:101D5000240A000100A61823308B000124C60001CC
+:101D6000006A3804000420421160000200C9182BE8
+:101D7000010740251460FFF800A6182303E00008BF
+:101D80000100102127BDFFD8AFB000188F90004888
+:101D9000AFB1001CAFBF00202403FFFF2411002FB0
+:101DA000AFA30010920600002405000826100001D1
+:101DB000006620260E001B47308400FF00021E0034
+:101DC0003C021EDC34466F410A001B6F00001021EC
+:101DD00010A00009008018212445000130A2FFFF57
+:101DE0002C4500080461FFFA0003204000862026ED
+:101DF00014A0FFF9008018210E001B4724050020C5
+:101E00008FA300102629FFFF313100FF000342029B
+:101E1000240700FF1627FFE20102182600035027BF
+:101E2000AFAA0014AFAA00100000302127A80010AC
+:101E300027A7001400E6782391ED000324CE0001CB
+:101E400000C8602131C600FF2CCB00041560FFF9EB
+:101E5000A18D00008FA200108FBF00208FB1001C49
+:101E60008FB0001803E0000827BD002827BDFFD071
+:101E7000AFB3001CAFB00010AFBF0028AFB5002457
+:101E8000AFB40020AFB20018AFB100143C0C80001A
+:101E90008D880128240FFF803C06800A2510010050
+:101EA000250B0080020F68243205007F016F70242B
+:101EB000AD8E009000A62821AD8D002490A600FCD8
+:101EC0003169007F3C0A8004012A1821A38600564C
+:101ED0009067007C00809821AF83002C30E20002E4
+:101EE000AF880068AF85003400A0182114400002BC
+:101EF0002404003424040030A38400448C7200DCE9
+:101F000030D100FF24040004AF92005C12240004CE
+:101F1000A38000648E7400041680001E3C088000BC
+:101F20009386005530C7000150E0000F8F86005C9B
+:101F30008CA400848CA800842413FF800093602468
+:101F4000000C49403110007F013078253C192000F9
+:101F500001F9682530DF00FE3C038000AC6D0830DD
+:101F6000A39F00558F86005C8FBF00288FB500248B
+:101F70008FB400208FB3001C8FB200188FB10014F3
+:101F80008FB000102402000127BD003003E00008DC
+:101F9000ACA600DC8E7F0008950201208E67001041
+:101FA00003E2C8213326FFFF30D8000F33150001AC
+:101FB000AF87003016A00058A398005435090C00D4
+:101FC0000309382100D81823AD030084AF870060CF
+:101FD0008E6A00043148FFFF1100007EA78A005876
+:101FE00090AC00D42407FF8000EC302430CB00FFFD
+:101FF0001560004B97860058938E0056240D000202
+:1020000030D5FFFF11CD02A20000A0218F85005C1A
+:1020100002A5802B160000BC938800443C11800070
+:1020200096240120310400FF148500888F8400600D
+:102030008F980030331200035640008530A500FF12
+:102040008F900060310C00FF24060034118600954B
+:10205000AF90004892040004148001198F8E003460
+:10206000A38000388E0D00048DC800D83C0600FF08
+:1020700034CCFFFF01AC30240106182B1460012181
+:10208000AF8600508F87005C97980058AF87003C60
+:102090000307402310C000C7A78800588F91002C69
+:1020A00030C3000300035823922A007C31710003DF
+:1020B00002261021000A208230920001001248807E
+:1020C00000492821311FFFFF03E5C82B1320012001
+:1020D0008F8800348F8500308F8800601105025A88
+:1020E0003C0E3F018E0600003C0C250000CE68240B
+:1020F00011AC01638F84004830E500FF0E0017E14A
+:10210000000030218F8800348F87005C8F8500307D
+:102110000A001D4E8F8600500A001BEDAF8700603D
+:1021200090AC00D400EC2024309000FF1200001688
+:102130009386005590B5008890B400D724A80088F5
+:1021400032A2003F2446FFE02CD10020A3940038A7
+:102150001220000CAF880048240E000100CE20049D
+:10216000308A00191540012B3C06800034D800024B
+:10217000009858241560022E309200201640023438
+:10218000000000009386005530CE000111C0000F02
+:10219000978800588CA900848CAF00842410FF809D
+:1021A0000130C8240019194031ED007F006D382539
+:1021B0003C1F200000FF902530CB00FE3C18800023
+:1021C000AF120830A38B0055978800581500FF8484
+:1021D000000000008E630020306C00041180FF516D
+:1021E000938600552404FFFB006430243C038000E8
+:1021F000AE660020346601808C7301B80660FFFE75
+:102200008F8E0068346A01003C150001ACCE0000DE
+:102210008C62012424076085ACC200048D54000444
+:1022200002958824522000012407608324120002B2
+:102230003C1810003C0B8000A4C70008A0D2000B83
+:10224000AD7801B80A001BC29386005530A500FF87
+:102250000E0017E1240600018F8800683C0580000D
+:1022600034A909002502018893880044304A0007F8
+:10227000304B00783C0340802407FF800163C82571
+:10228000014980210047F824310C00FF2406003466
+:10229000ACBF0800AF900048ACB908105586FF6E7F
+:1022A000920400048F8400348E110030908E00D48C
+:1022B00031CD001015A000108F83005C2C6F00053D
+:1022C00015E000E400000000909800D42465FFFCB5
+:1022D000331200101640000830A400FF8F9F0060EA
+:1022E0008F99003013F900043887000130E20001B3
+:1022F000144001C8000000000E001B5A000000003E
+:102300000A001D8F000000008F84006030C500FFB0
+:102310000E0017E124060001938E0044240A0034C5
+:1023200011CA00A08F8500348F86005C9783005807
+:102330003062FFFF00C28823AF91005CA780005885
+:102340001280FF90028018212414FFFD5474FFA214
+:102350008E6300208E6900042403FFBF240BFFEF6F
+:102360000135C823AE79000490AF00D431ED007F71
+:10237000A0AD00D48E6600208F980034A78000584E
+:1023800034DF0002AE7F0020A70000BC931200D40F
+:1023900002434024A30800D48F950034AEA000EC83
+:1023A00092AE00D401CB5024A2AA00D40A001C6E25
+:1023B0008F8500348F910030AF80005C0227582158
+:1023C000AF8B0030000020212403FFFF108301B4F5
+:1023D0008F8500348E0C00103C0D08008DAD31B09F
+:1023E0009208000031843FFF008D802B12000023F3
+:1023F000310D003F3C1908008F3931A88F9F0068CC
+:10240000000479802408FF80033F2021008FC82129
+:10241000938500550328F8243C0600803C0F80007B
+:1024200034D80001001F91403331007F8F86003483
+:102430000251502535EE0940332B00783330000728
+:102440003C0310003C02800C01789025020E4821CC
+:102450000143C0250222382134AE0001ADFF08043B
+:10246000AF89004CADF20814AF870040ADFF0028E3
+:10247000ACD90084ADF80830A38E00559383005684
+:10248000240700035067002825A3FFE0240C000167
+:10249000146CFFAB8F8500342411002311B100842C
+:1024A000000000002402000B026020210E0019E150
+:1024B000A38200640040A0210A001CC98F8500345B
+:1024C00002602021240B000C0E0019E1A38B006494
+:1024D000240AFFFF104AFFBC2404FFFF8F8E003444
+:1024E000A38000388E0D00048DC800D83C0600FF84
+:1024F00034CCFFFF01AC30240106182B1060FEE144
+:10250000AF86005002602021241200190E0019E14C
+:10251000A3920064240FFFFF104FFFAB2404FFFFC2
+:102520000A001C1A8F8600502C7400201280FFDED7
+:102530002402000B000328803C110801263192EC94
+:1025400000B148218D2D000001A00008000000000E
+:102550008F85003000A7102193850038AF820030AE
+:1025600002251821A3830038951F00BC02262821CC
+:1025700037F91000A51900BC5240FF92AF85005CEE
+:10258000246A0004A38A0038950900BC24A400042E
+:10259000AF84005C35322000A51200BC0A001CEBA1
+:1025A000000020218F86005C2CCB00051560FF60A9
+:1025B000978300583072FFFF00D240232D1800058A
+:1025C00013000003306400FF24DFFFFC33E400FF4E
+:1025D0008F8500608F86003010A60004388F0001C0
+:1025E00031ED000115A00138000000008F84003497
+:1025F000908C00D435870010A08700D48F850034DC
+:102600008F86005C97830058ACA000EC0A001CC6C3
+:102610003062FFFF8CAA00848CB500843C0410005B
+:10262000014710240002894032B4007F0234302573
+:1026300000C460253C0880002405000102602021C0
+:10264000240600010E001940AD0C08300A001C5A87
+:102650008F8500348C8200EC1222FE7E02602021E5
+:1026600024090005A38900640E0019E12411FFFF6D
+:102670001451FE782404FFFF0A001CEC2403FFFF22
+:102680008F8F00488F8800348DF80000AD180088C7
+:102690008DE70010AD0700988F87005C0A001D4E83
+:1026A0008F8600502407FFFF1187000500000000FF
+:1026B0000E001AE3026020210A001D270040A0211D
+:1026C0000E001A68026020210A001D270040A02188
+:1026D0008F9000483C0908008D2931B08E11001000
+:1026E00032323FFF0249682B11A0000C240AFF8000
+:1026F0008F85004C90AE000D014E1024304C00FF31
+:1027000011800007026020210011C38233030003FF
+:10271000240B0001106B0105000000000260202165
+:102720002418000D0E0019E1A39800640040202138
+:102730008F8500340A001CC90080A0218F900048BA
+:102740003C0A08008D4A31B08F85004C8E04001081
+:102750000000A0218CB1001430823FFF004A602BA2
+:102760008CB200205180FFEE0260202190B8000D55
+:10277000240BFF800178702431C300FF5060FFE814
+:1027800002602021000443823106000314C0FFE4EC
+:102790000260202194BF001C8F9900348E0600280F
+:1027A000A73F00E88CAF0010022F202314C401398A
+:1027B000026020218F83005000C36821022D382B36
+:1027C00014E00135240200188F8A00408F82002C0B
+:1027D000024390218D4B001001637023AD4E001019
+:1027E000AD5200208C4C00740192282B14A001568D
+:1027F000026020218F84004C8E0800248C860024E7
+:1028000011060007026020212419001C0E0019E1A6
+:10281000A3990064240FFFFF104FFFC52404FFFF9E
+:102820008F8400408C87002424FF0001AC9F00248B
+:10283000125101338F8D002C8DB100741232013092
+:102840003C0B00808E0E000001CB5024154000751B
+:10285000000000008E0300142411FFFF1071000619
+:10286000026020212418001B0E0019E1A3980064C7
+:102870001051FFAF2404FFFF8E0300003C0800014D
+:102880000068302410C000133C0400800064A024C1
+:102890001680000902002821026020212419001A54
+:1028A0000E0019E1A3990064240FFFFF104FFFA051
+:1028B0002404FFFF02002821026020210E001A01DB
+:1028C000240600012410FFFF1050FF992404FFFF8D
+:1028D000241400018F9F00400260202102803021DB
+:1028E00097F100342405000126270001A7E70034F2
+:1028F0000E00194000000000000020218F850034E8
+:102900000A001CC90080A0218F9000483C140800D8
+:102910008E9431B08E07001030E83FFF0114302B49
+:1029200010C000618F86004C241FFF8090C5000DF1
+:1029300003E52024309200FF5240005C0260202119
+:102940008F8D005011A0000700078B828F85003407
+:102950008F89FCB894AF00809539000A132F00F6D8
+:102960008F87003C322C00031580006300000000BC
+:1029700092020002104000D7000000008E0A0024DE
+:10298000154000D8026020219204000324060002B2
+:10299000308800FF15060005308500FF8F94005039
+:1029A000528000F202602021308500FF38AD001017
+:1029B0002DA400012CBF000103E4302502002821D2
+:1029C0000E001A01026020212410FFFF105000BEEB
+:1029D0008F8500348F830050106000C424050001EF
+:1029E0003C1908008F39318C0323782B15E000B196
+:1029F0002409002D02602021000028210E0019402A
+:102A0000240600018F850034000018210A001CC92B
+:102A10000060A0210E00180C000000000A001D8FAD
+:102A200000000000AC8000200A001E0F8E0300147E
+:102A300000002821026020210E0019402406000118
+:102A40000A001C5A8F8500340A001D4E8F880034FE
+:102A50008CB000848CB900843C0310000207482429
+:102A600000096940332F007F01AFF82503E32825D3
+:102A7000ACC5083091070001240500010260202147
+:102A80000E00194030E600010A001C5A8F85003400
+:102A9000938F00442403FFFD0A001CCBAF8F005C22
+:102AA0000A001CCB2403FFFF026020212410000D2C
+:102AB0000E0019E1A3900064004018218F850034B6
+:102AC0000A001CC90060A0210E00180C00000000C4
+:102AD000978300588F86005C3070FFFF00D048233A
+:102AE0002D3900051320FE128F850034ACA200ECB6
+:102AF0000A001CC63062FFFF90C3000D307800084A
+:102B00005700FFA29204000302602021240200105B
+:102B10000E0019E1A38200642403FFFF5443FF9BCE
+:102B2000920400030A001EA98F85003490A8000DAE
+:102B30003106000810C000958F9400501680009E4A
+:102B4000026020218E0F000C8CA4002055E40005AB
+:102B5000026020218E1F00088CB9002413F9003A6E
+:102B600002602021240200200E0019E1A3820064EB
+:102B70002405FFFF1045FEEE2404FFFF8F8F004069
+:102B8000240CFFF72403FF8091E9000D3C14800E14
+:102B90003C0B8000012CC824A1F9000D8F8F002C64
+:102BA0003C0708008CE731AC8F8D006895E5007814
+:102BB0008F99004000ED902130BF7FFF001F204023
+:102BC0000244302130C8007F00C3C02401147021AA
+:102BD000AD78002CA5D100008F2A002825420001E5
+:102BE000AF2200288F29002C8E0C002C012C68218C
+:102BF000AF2D002C8E07002CAF2700308E0500145F
+:102C0000AF250034973F003A27E40001A724003A9B
+:102C100095F200783C1008008E1031B02643000178
+:102C200030717FFF1230005C006030218F83002CF8
+:102C300002602021240500010E0018CBA466007854
+:102C40000A001E38000020218E0700142412FFFF06
+:102C500010F200638F8C00348E0900188D8D00D027
+:102C6000152D005D026020218E0A00248CA2002810
+:102C700011420053240200210E0019E1A3820064D6
+:102C80001452FFBE2404FFFF8F8500340A001CC9C4
+:102C90000080A0212402001F0E0019E1A38200641D
+:102CA0002409FFFF1049FEA22404FFFF0A001DEBC8
+:102CB0008F830050026020210E0019E1A389006477
+:102CC0001450FF518F8500342403FFFF0A001CC9F4
+:102CD0000060A0218CCE00248E0B0024116EFF2AF0
+:102CE000026020210A001EBD2402000F0E0018CB36
+:102CF000026020218F8500340A001E7C000018210C
+:102D00008E0900003C050080012590241640FF45F7
+:102D10002402001A026020210E0019E1A38200643F
+:102D2000240CFFFF144CFECB2404FFFF8F850034DE
+:102D30000A001CC90080A0212403FFFD0060A0211F
+:102D40000A001CC9AF87005C2418001D0E0019E1A1
+:102D5000A39800642403FFFF1443FEA62404FFFF8E
+:102D60008F8500340A001CC90080A0212412002C89
+:102D70000E0019E1A39200642403FFFF1043FF50EB
+:102D80008F8500340A001E63920400030260202134
+:102D90000A001ED324020024240B8000006B702440
+:102DA00031CAFFFF000A13C2305100FF0011802713
+:102DB0000A001F04001033C00A001ED3240200279B
+:102DC0008E0600288CAE002C10CE00080260202158
+:102DD0000A001F172402001F0A001F172402000EFA
+:102DE000026020210A001F17240200258E04002CF7
+:102DF0001080000D8F83002C8C7800740304582BF6
+:102E00005560000C026020218CA800140086A021CF
+:102E10000114302B10C0FF5A8F8F00400260202118
+:102E20000A001F1724020022026020210A001F1737
+:102E3000240200230A001F172402002627BDFFD802
+:102E4000AFB3001CAFB10014AFBF0020AFB2001889
+:102E5000AFB000103C0280008C5201408C4B014806
+:102E60003C048000000B8C02322300FF317300FF12
+:102E70008C8501B804A0FFFE34900180AE120000E2
+:102E80008C8701442464FFF0240600022C83001385
+:102E9000AE070004A6110008A206000BAE13002422
+:102EA0001060004F8FBF0020000448803C0A0801DA
+:102EB000254A936C012A40218D04000000800008FF
+:102EC000000000003C0308008C6331A831693FFF1B
+:102ED0000009998000728021021370212405FF806F
+:102EE000264D0100264C00803C02800031B1007F5D
+:102EF0003198007F31CA007F3C1F800A3C19800452
+:102F00003C0F800C01C5202401A530240185382404
+:102F1000014F1821AC460024023F402103194821EB
+:102F2000AC470090AC440028AF830040AF88003429
+:102F3000AF89002C0E001897016080213C038000AF
+:102F40008C6B01B80560FFFE8F8700408F860034D0
+:102F50003465018090E8000DACB20000A4B000061A
+:102F6000000826000004160300029027001227C262
+:102F70001080008124C20088241F6082A4BF000842
+:102F8000A0A0000524020002A0A2000B8F8B002C41
+:102F9000000424003C08270000889025ACB20010F3
+:102FA000ACA00014ACA00024ACA00028ACA0002C65
+:102FB0008D6900382413FF80ACA9001890E3000D40
+:102FC00002638024320500FF10A000058FBF00209F
+:102FD00090ED000D31AC007FA0EC000D8FBF002004
+:102FE0008FB3001C8FB200188FB100148FB0001087
+:102FF0003C0A10003C0E800027BD002803E00008BA
+:10300000ADCA01B8265F01002405FF8033F8007FB8
+:103010003C06800003E578243C19800A031920212E
+:10302000ACCF0024908E00D400AE682431AC00FFF9
+:1030300011800024AF840034248E008895CD0012C6
+:103040003C0C08008D8C31A831AB3FFF0192482128
+:10305000000B5180012A402101052024ACC4002826
+:103060003107007F3C06800C00E620219083000D94
+:1030700000A31024304500FF10A0FFD8AF8400400B
+:103080009098000D330F001015E0FFD58FBF002082
+:103090000E001897000000003C0380008C7901B8F6
+:1030A0000720FFFE00000000AE1200008C7F0144EC
+:1030B000AE1F0004A611000824110002A211000B8B
+:1030C000AE1300243C13080192739528327000015E
+:1030D0005200FFC38FBF00200E0020D402402021E9
+:1030E0000A001FF18FBF00203C1260008E452C08A3
+:1030F0003C03F0033462FFFF00A2F824AE5F2C080B
+:103100008E582C083C1901C003199825AE532C0881
+:103110000A001FF18FBF0020264D010031AF007F54
+:103120003C10800A240EFF8001F0282101AE6024AB
+:103130003C0B8000AD6C00241660FFA8AF85003406
+:1031400024110003A0B100FC0A001FF18FBF002072
+:1031500026480100310A007F3C0B800A2409FF80C9
+:10316000014B3021010920243C078000ACE40024FD
+:103170000A001FF0AF860034944E0012320C3FFF5D
+:1031800031CD3FFF15ACFF7D241F608290D900D464
+:103190002418FF800319782431EA00FF1140FF77DB
+:1031A0000000000024070004A0C700FC8F87004037
+:1031B000241160842406000DA4B10008A0A6000517
+:1031C0000A001FDB240200023C0400012484951441
+:1031D00024030014240200FE3C010800AC2431EC5E
+:1031E0003C010800AC2331E83C010801A4229530E1
+:1031F0003C0408012484953000001821006430212B
+:10320000A0C30004246300012C6500FF54A0FFFC50
+:10321000006430213C07080024E7010003E00008B7
+:10322000AF87007400A058210080482100001021C1
+:1032300014A00012000050210A0020D0000000005D
+:103240003C010801A42095303C05080194A5953067
+:103250008F8200743C0C0801258C953000E2182107
+:1032600000AC2021014B302BA0890004000010216C
+:10327000A460000810C00039010048218F86007446
+:103280000009384000E940210008388000E6282184
+:1032900090A8000B90B9000A000820400088102177
+:1032A000000218800066C021A319000A8F850074EF
+:1032B00000E5782191EE000A91E6000B000E6840CF
+:1032C00001AE6021000C208000851021A046000B7B
+:1032D0003C0308019063952A106000222462FFFFDE
+:1032E0008F8300343C010801A022952A906C00FFD6
+:1032F0001180000400000000906E00FF25CDFFFF4C
+:10330000A06D00FF3C190801973995302723000173
+:103310003078FFFF2F0F00FF11E0FFC9254A0001A1
+:103320003C010801A42395303C05080194A5953083
+:103330008F8200743C0C0801258C953000E2182126
+:1033400000AC2021014B302BA0890004000010218B
+:10335000A460000814C0FFC90100482103E0000870
+:103360000000000003E000082402000227BDFFE087
+:10337000248501002407FF80AFB00010AFBF001804
+:10338000AFB1001400A718243C10800030A4007FC7
+:103390003C06800A008628218E110024AE030024FA
+:1033A00090A200FF14400008AF850034A0A00009DF
+:1033B0008FBF0018AE1100248FB100148FB0001021
+:1033C00003E0000827BD002090A900FD90A800FFA1
+:1033D000312400FF0E002082310500FF8F8500346C
+:1033E0008FBF0018A0A00009AE1100248FB10014F7
+:1033F0008FB0001003E0000827BD002027BDFFD0DC
+:10340000AFB20020AFB1001CAFB00018AFBF002CAE
+:10341000AFB40028AFB300243C09800095330116F7
+:1034200035320C00952F011A3271FFFF02328021D4
+:103430008E08000431EEFFFF248B0100010E68218D
+:10344000240CFF8025A5FFFF016C50243166007F0E
+:103450003C07800AAD2A002400C73021AF850070E8
+:10346000AF88006C3C010801A020952990C3000999
+:103470000200D02100809821306300FF28620005FF
+:1034800010400048AF860034286400021480008E8B
+:1034900024140001240D00053C010801A02D950D08
+:1034A00090CC00FD3C010801A020950E3C010801D4
+:1034B000A020950F90CB000A240AFF80318500FFE1
+:1034C000014B4824312700FF10E0000C0000582178
+:1034D0003C128008365100808E2F00308CD0005C6A
+:1034E00001F0702305C0018E8F87006C90D4000A14
+:1034F0003284007FA0C4000A8F8600343C1180080B
+:10350000363000808E0F00308F87006C00EF702304
+:1035100019C000EE0000000090D40009241200023F
+:10352000328400FF10920247000000008CC2005855
+:1035300000E2F82327F9FFFF1B2001300000000004
+:1035400090C500092408000430A300FF106800574C
+:10355000240A00013C010801A02A950D90C900FF32
+:10356000252700013C010801A027950C3C03080118
+:103570009063950D240600051066006A2C780005FE
+:10358000130000C4000090210003F8803C040801EF
+:10359000248493B803E4C8218F25000000A000080C
+:1035A00000000000241800FF1078005C00000000FC
+:1035B00090CC000A90CA00093C080801910895299E
+:1035C0003187008000EA48253C010801A0299514B4
+:1035D00090C500FD3C1408019294952A3111000118
+:1035E0003C010801A025951590DF00FE3C01080173
+:1035F000A03F951690D200FF3C010801A03295171C
+:103600008CD900543C010801AC3995188CD0005875
+:103610003C010801AC30951C8CC3005C3C010801E6
+:10362000AC3495243C010801AC23952016200008F9
+:103630008FBF002C8FB400288FB300248FB20020DE
+:103640008FB1001C8FB0001803E0000827BD0030C8
+:103650003C1180009624010E0E000FD43094FFFF21
+:103660003C0B08018D6B952C0260382102802821CB
+:10367000AE2B01803C1308018E73950C0160202154
+:10368000240600830E001046AFB300108FBF002C3D
+:103690008FB400288FB300248FB200208FB1001C9C
+:1036A0008FB0001803E0000827BD00303C18080068
+:1036B0008F1831FC270F00013C010800AC2F31FCB2
+:1036C0000A002165000000001474FFB9000000002A
+:1036D000A0C000FF3C0508008CA531E43C030800B5
+:1036E0008C6331E03C0208008C4232048F99003434
+:1036F00034A80001241F00023C010801AC23952CD2
+:103700003C010801A02895283C010801A022952B26
+:10371000A33F00090A00211E8F8600340E0020D42A
+:10372000000000000A0021658F8600343C1F08015C
+:1037300093FF950C2419000113F902298F87006C5F
+:103740003C100801921095103C06080190C6950E99
+:1037500010C000050200A0213C04080190849511CE
+:10376000109001E48F870074001088408F9F0074D0
+:10377000023048210009C880033F702195D8000815
+:10378000270F0001A5CF00083C0408019084951183
+:103790003C05080190A5950E0E0020820000000057
+:1037A0008F870074023020210004308000C7202160
+:1037B0008C8500048F82007000A240230502000661
+:1037C000AC8200048C8A00008F83006C01431023BC
+:1037D0005C400001AC8300008F86003490CB00FF7A
+:1037E0002D6C00025580002D241400010230F821B8
+:1037F000001F40800107282190B9000B8CAE000407
+:103800000019C04003197821000F188000671021AB
+:103810008C4D000001AE88232630FFFF5E00001FA4
+:10382000241400018C4400048CAA0000008A482360
+:1038300019200019240E00043C010801A02E950D4A
+:1038400090AD000B8CAB0004000D8840022D802150
+:1038500000101080004710218C4400040164602394
+:10386000058202009443000890DF00FE90B9000B2F
+:1038700033E500FF54B900040107A021A0D400FEE5
+:103880008F8700740107A0219284000B0E00208214
+:10389000240500018F860034241400011254009680
+:1038A0002E500001160000423C08FFFF24190002C0
+:1038B0001659FF3F00000000A0C000FF8F860034B3
+:1038C000A0D200090A0021658F86003490C7000944
+:1038D0002404000230E300FF1064016F2409000497
+:1038E000106901528F8800708CCE0054010E68233D
+:1038F00025B1000106200175241800043C010801CF
+:10390000A038950D3C010801A020950C90D400FD35
+:1039100090D200FF2E4F000215E0FF14328400FF0A
+:10392000000438408F89007490DF00FF00E410210C
+:10393000000220800089C8212FE500029324000B9B
+:1039400014A0FF0A2407000200041840006480212C
+:1039500000105880016928218CAC0004010C502310
+:103960000540FF02000000003C0308019063950E33
+:1039700014600005246F00013C010801A02495118A
+:103980003C010801A027950F3C010801A02F950ECE
+:1039900090CE00FF24E7000131CD00FF01A7882B66
+:1039A0001220FFE990A4000B0A002154000000003F
+:1039B0003C0508018CA5950C3C12000400A8F824D5
+:1039C00013F20006240200053C0908019129950D17
+:1039D0001520000224020003240200053C01080116
+:1039E000A022952990C700FF14E0012024020002C4
+:1039F000A0C200090A0021658F86003490CC00FF28
+:103A00001180FEDA240A00018F8C00708F89007407
+:103A1000240F0003018068211160001E240E0002A3
+:103A2000000540400105A02100142080008990215C
+:103A30008E510004019180230600FECC000000009E
+:103A40003C0208019042950E1440000524580001E4
+:103A50003C010801A02A950F3C010801A025951101
+:103A60003C010801A038950E90DF00FF01051021F0
+:103A70000002C88033E500FF254A00010329202108
+:103A800000AA402B1500FEB99085000B1560FFE5DC
+:103A9000000540400005404001051821000310804A
+:103AA0003C010801A02A950C3C010801A0259510B5
+:103AB000004918218C64000400E4F82327F9FFFF73
+:103AC0001F20FFE9000000008C63000000E3582382
+:103AD0000560013A01A3882310E301170184C02384
+:103AE0001B00FEA2000000003C010801A02E950D65
+:103AF0000A002293240B0001240E0004A0CE00092A
+:103B00003C0D08008DAD31F88F86003425A20001F0
+:103B10003C010800AC2231F80A00216500000000D9
+:103B20008CD9005C00F9C0231F00FE7B0000000060
+:103B30008CDF005C10FFFF658F8400708CC3005C1D
+:103B400000834023250200011C40FF6000000000AC
+:103B50008CC9005C2487000100E9282B10A0FE948A
+:103B60003C0D80008DAB01043C0C0001016C502425
+:103B70001140FE8F240200103C010801A02295296B
+:103B80000A002165000000008F9100708F860034CC
+:103B900026220001ACC2005C0A002220241400018D
+:103BA0008F8700342404FF800000882190E9000AF8
+:103BB0002414000101243025A0E6000A3C05080178
+:103BC00090A5950E3C040801908495110E0020826A
+:103BD000000000008F8600348F85007490C800FDBF
+:103BE000310700FF000740400107F821001FC08097
+:103BF0000305C8219323000BA0C300FD8F8500742B
+:103C00008F86003403056021918F000B000F7040F8
+:103C100001CF6821000D8080020510218C4B00002F
+:103C2000ACCB00548D8400048F830070006450235B
+:103C3000194000022482000124620001010748218A
+:103C4000ACC2005C0009308000C5402100E02021AA
+:103C5000240500010E0020829110000B8F86003495
+:103C600090C500FF10A0FF0C001070408F850074FD
+:103C700001D06821000D1080004558218D6400009E
+:103C80008F8C0070018450232547000104E0FF025F
+:103C9000263100013C0308019063950E2E2F00028F
+:103CA000247800013C010801A038950E3C01080170
+:103CB000A034950F11E0FEF8020038210A0022F32B
+:103CC000000740408F8400348F8300708C8500583B
+:103CD00000A340230502FE9AAC8300580A0021C9C4
+:103CE000000000003C07080190E7952A240200FF2D
+:103CF00010E200BE8F8600343C11080196319532E7
+:103D00003C03080124639530262500013230FFFF73
+:103D100030ABFFFF020360212D6A00FF1540008DCC
+:103D2000918700043C010801A42095328F8800345B
+:103D30000007484001272821911800FF0005308026
+:103D40002405000127140001A11400FF3C12080102
+:103D50009252952A8F8800748F8E006C264F000136
+:103D600000C820213C010801A02F952AAC8E00003C
+:103D70008F8D0070A4850008AC8D00043C03080101
+:103D80009063950C14600077000090213C010801BD
+:103D9000A025950CA087000B8F8C007400CC5021BF
+:103DA000A147000A8F820034A04700FD8F840034B1
+:103DB000A08700FE8F8600348F9F006CACDF00541C
+:103DC0008F990070ACD900588F8D00740127C021E5
+:103DD00000185880016DA021928F000A000F7040DA
+:103DE00001CF182100038880022D8021A207000B3B
+:103DF0008F86007401666021918A000B000A1040D2
+:103E0000004A20210004288000A64021A107000AC2
+:103E10003C07800834E900808D2200308F86003412
+:103E2000ACC2005C0A0022202414000190CA00FFEA
+:103E30001540FEAD8F880070A0C400090A002165FE
+:103E40008F860034A0C000FD8F9800342406000146
+:103E5000A30000FE3C010801A026950D3C010801CD
+:103E6000A020950C0A0021540000000090CB00FF18
+:103E70003C0408019084952B316C00FF0184502B89
+:103E80001540000F2402000324020004A0C2000910
+:103E90000A0021658F86003490C3000A2410FF8039
+:103EA00002035824316C00FF1180FDC100000000A6
+:103EB0003C010801A020950D0A00215400000000DB
+:103EC000A0C200090A0021658F86003490D4000A40
+:103ED0002412FF8002544824312800FF1500FFF40B
+:103EE000240200083C010801A02295290A0021654E
+:103EF00000000000001088408F8B006C02301821F9
+:103F00000003688001A72021AC8B00008F8A00701D
+:103F1000240C0001A48C0008AC8A00043C050801B4
+:103F200090A5950E2402000110A2FE1E24A5FFFFFD
+:103F30000A0021DF9084000B0184A0231A80FD8BEE
+:103F4000000000003C010801A02E950D0A002293FC
+:103F5000240B00013C010801A42595320A002345E9
+:103F60008F880034240B0001106B00228F980034DE
+:103F70008F85003490BF00FF33F900FF1079002BCC
+:103F8000000000003C1F080193FF9510001FC8406F
+:103F9000033FC0210018A0800288782191EE000A1A
+:103FA000A08E000A8F8D00743C0308019063951069
+:103FB00000CD88210A00236BA223000B26300001CC
+:103FC0000600003101A490230640002B24020003C8
+:103FD0003C010801A02F950D0A002293240B00013B
+:103FE0008F8900340A0021C9AD2700540A00221F1E
+:103FF00024120001931400FDA094000B8F8800345C
+:104000008F8F0074910E00FE00CF6821A1AE000AD0
+:104010008F910034A22700FD8F83006C8F900034B5
+:10402000AE0300540A00236C8F8D007490B000FE24
+:10403000A090000A8F8B00348F8C0074916A00FD71
+:1040400000CC1021A04A000B8F840034A08700FE12
+:104050008F8600708F850034ACA600580A00236C50
+:104060008F8D007494B80008ACA400040303782179
+:104070000A002213A4AF00083C010801A022950DFC
+:104080000A0021540000000090CF0009240D000414
+:1040900031EE00FF11CDFD85240200013C01080135
+:0C40A000A022950D0A0021540000000031
+:0440AC000800334491
+:1040B0000800334408003420080033F4080033D8E3
+:1040C0000800332808003328080033280800334C40
+:1040D0008008010080080080800800005F86543757
+:1040E000E4AC62CC50103A4536621985BF14C0E882
+:1040F0001BC27A1E84F4B556094EA6FE7DDA01E78E
+:10410000C04D7481080058D008005914080058B8F0
+:10411000080058B8080058B8080058B8080058D027
+:10412000080058B8080058B80800591C080058B8CA
+:1041300008005830080058B8080058B80800591C42
+:10414000080058B8080058B8080058B8080058B80F
+:10415000080058B8080058B8080058B8080058B8FF
+:10416000080058B8080058B8080058F0080058B8B7
+:10417000080058F0080058B8080058B8080058B8A7
+:10418000080058F4080058F0080058B8080058B85B
+:10419000080058B8080058B8080058B8080058B8BF
+:1041A000080058B8080058B8080058B8080058B8AF
+:1041B000080058B8080058B8080058B8080058B89F
+:1041C000080058B8080058B8080058B8080058B88F
+:1041D000080058B8080058B8080058F4080058F407
+:1041E000080058B8080058F4080058B8080058B833
+:1041F000080058B8080058B8080058B8080058B85F
+:10420000080058B8080058B8080058B8080058B84E
+:10421000080058B8080058B8080058B8080058B83E
+:10422000080058B8080058B8080058B8080058B82E
+:10423000080058B8080058B8080058B8080058B81E
+:10424000080058B8080058B8080058B8080058B80E
+:10425000080058B8080058B8080058B8080058B8FE
+:10426000080058B8080058B8080058B8080058B8EE
+:10427000080058B8080058B8080058B8080058B8DE
+:10428000080058B8080058B8080058B8080058B8CE
+:10429000080058B8080058B8080058B8080058B8BE
+:1042A000080058B8080058B8080058B8080058B8AE
+:1042B000080058B8080058B8080058B8080058B89E
+:1042C000080058B8080058B8080058B8080058B88E
+:1042D000080058B8080058B8080058B8080058B87E
+:1042E000080058B8080058B8080058B8080058B86E
+:1042F000080058B8080058B8080058B8080058B85E
+:10430000080058B80800593808007688080078EC8A
+:1043100008007694080074880800769408007720D6
+:10432000080076940800748808007488080074886F
+:10433000080074880800748808007488080074886D
+:10434000080074880800748808007488080076B42F
+:10435000080076A40800748808007488080074882F
+:10436000080074880800748808007488080074883D
+:10437000080074880800748808007488080074882D
+:1043800008007488080076A40800813408007FC003
+:10439000080080FC08007FC0080080CC08007EA8D0
+:1043A00008007FC008007FC008007FC008007FC0F1
+:1043B00008007FC008007FC008007FC008007FC0E1
+:1043C00008007FC008007FC008007FC008007FC0D1
+:1043D00008007FE808008B6C08008CC808008CA8D7
+:0843E0000800871008008B841F
+:0843E8000A000124000000009E
+:1043F000000000000000000D747061362E302E3178
+:10440000370000000600110100000000000000005D
+:10441000000000000000000000000000000000009C
+:10442000000000000000000000000000000000008C
+:10443000000000000000000000000000000000007C
+:10444000000000000000000000000000000000006C
+:10445000000000000000000000000000000000005C
+:10446000000000000000000000000000000000004C
+:104470000000000000000000000000001000000329
+:10448000000000000000000D0000000D3C020800CC
+:10449000244217203C03080024632A10AC4000008B
+:1044A0000043202B1480FFFD244200043C1D080023
+:1044B00037BD2FFC03A0F0213C100800261004900B
+:1044C0003C1C0800279C17200E0002620000000020
+:1044D0000000000D2402FF8027BDFFE000821024B1
+:1044E000AFB00010AF420020AFBF0018AFB1001452
+:1044F000936500043084007F034418213C020008C7
+:104500000062182130A50020036080213C080111C1
+:10451000277B000814A000022466005C2466005873
+:104520009202000497430104920400043047000FF4
+:104530003063FFFF308400400067282310800009AB
+:10454000000048219202000530420004104000059E
+:104550000000000010A000030000000024A5FFFCE4
+:1045600024090004920200053042000410400012A9
+:104570000000000010A000100000000096020002E1
+:1045800000A72021010440252442FFFEA742101667
+:10459000920300042402FF8000431024304200FFF5
+:1045A000104000033C0204000A000174010240258F
+:1045B0008CC20000AF4210188F4201780440FFFE09
+:1045C0002402000AA74201409602000224040009C6
+:1045D000304200070002102330420007A742014288
+:1045E000960200022442FFFEA7420144A740014672
+:1045F00097420104A74201488F420108304200203F
+:1046000050400001240400019202000430420010D6
+:10461000144000023483001000801821A743014A8F
+:10462000000000000000000000000000000000008A
+:10463000AF48100000000000000000000000000073
+:10464000000000008F4210000441FFFE3102FFFF16
+:1046500010400007000000009202000430420040B9
+:1046600014400003000000008F421018ACC200008C
+:10467000960200063042FFFF24420002000210436F
+:104680000002104003628821962200001120000DD4
+:104690003044FFFF00A710218F8300388F45101C86
+:1046A000000210820002108000431021AC4500007F
+:1046B00030A6FFFF0E00058D00052C0200402021D2
+:1046C000A6220000920300042402FF80004310246D
+:1046D000304200FF1040001F000000009202000561
+:1046E000304200021040001B000000009742100CF6
+:1046F0002442FFFEA7421016000000003C02040006
+:1047000034420030AF421000000000000000000002
+:1047100000000000000000008F4210000441FFFE76
+:10472000000000009742100C8F45101C3042FFFF24
+:10473000244200300002108200021080005B102131
+:10474000AC45000030A6FFFF0E00058D00052C02D1
+:10475000A622000096040002248400080E0001E94D
+:104760003084FFFF974401040E0001F73084FFFFFF
+:104770008FBF00188FB100148FB000103C021000E2
+:1047800027BD002003E00008AF4201783084FFFF1E
+:10479000308200078F850024104000022483000728
+:1047A0003064FFF800A4102130421FFF034218219B
+:1047B000247B4000AF850028AF82002403E000087E
+:1047C000AF4200843084FFFF3082000F8F85002CC1
+:1047D0008F860034104000022483000F3064FFF005
+:1047E00000A410210046182BAF850030004620237E
+:1047F00014600002AF82002CAF84002C8F82002C4A
+:10480000340480000342182100641821AF8300386B
+:1048100003E00008AF4200808F82001410400008BF
+:104820008F8200048F82FFDC144000058F82000419
+:104830003C02FFBF3442FFFF008220248F8200042D
+:1048400030430006240200021062000F3C02010106
+:104850002C62000350400005240200041060000F89
+:104860003C0200010A000230000000001062000556
+:10487000240200061462000C3C0201110A00022905
+:10488000008210253C02001100821025AF4210006A
+:10489000240200010A000230AF82000C00821025C1
+:1048A000AF421000AF80000C0000000000000000CC
+:1048B0000000000003E00008000000008F82000CF0
+:1048C00010400004000000008F4210000441FFFE71
+:1048D0000000000003E00008000000008F820010CC
+:1048E0002443F800000231C224C2FFF02C6303010C
+:1048F00010600003000210420A000257AC82000060
+:104900008F85001800C5102B1440000B00001821E3
+:1049100000C51023244700018F82001C00A2102133
+:104920002442FFFF0046102B544000042402FFFFE6
+:104930000A000257AC8700002402FFFF0A00026051
+:10494000AC8200008C820000000219400062182135
+:104950000003188000621821000318803C02080040
+:104960002442175C0062182103E000080060102157
+:1049700027BDFFD8AFBF0020AFB1001CAFB00018FB
+:104980003C0460088C8250002403FF7F3C066000DA
+:10499000004310243442380CAC8250008CC24C1CB2
+:1049A0003C1A8000000216023042000F104000073F
+:1049B000AF82001C8CC34C1C3C02001F3442FC0024
+:1049C00000621824000319C2AF8300188F42000848
+:1049D000275B400034420001AF420008AF80002452
+:1049E0003C02601CAF400080AF4000848C45000852
+:1049F0008CC3080834028000034220212402FFF007
+:104A0000006218243C0200803C010800AC22042013
+:104A10003C025709AF84003814620004AF850034AB
+:104A2000240200010A000292AF820014AF80001439
+:104A30008F42000038420001304200011440FFFC68
+:104A40008F820014104000160000000097420104FD
+:104A5000104000058F830000146000072462FFFFF0
+:104A60000A0002A72C62000A2C62001050400004C9
+:104A70008F83000024620001AF8200008F8300005A
+:104A80002C62000A144000032C6200070A0002AEE8
+:104A9000AF80FFDC1040000224020001AF82FFDC87
+:104AA0008F4301088F44010030622000AF8300046F
+:104AB00010400008AF8400103C0208008C42042C17
+:104AC000244200013C010800AC22042C0A00058AA3
+:104AD0003C0240003065020014A0000324020F00D5
+:104AE0001482026024020D0097420104104002C8A3
+:104AF0003C02400030624000144000AD8F8200381C
+:104B00008C4400088F4201780440FFFE2402080014
+:104B1000AF42017824020008A7420140A7400142A9
+:104B2000974201048F8400043051FFFF308200015E
+:104B300010400007022080212623FFFE24020002ED
+:104B40003070FFFFA74201460A0002DBA74301487D
+:104B5000A74001463C0208008C42043C1440000D72
+:104B60008F830010308200201440000224030009CB
+:104B700024030001006020218F830010240209001B
+:104B80005062000134840004A744014A0A0002F67E
+:104B90000000000024020F00146200053082002093
+:104BA000144000062403000D0A0002F5240300054A
+:104BB000144000022403000924030001A743014A12
+:104BC0003C0208008C4204203C0400480E00020C09
+:104BD000004420250E000235000000008F82000CEA
+:104BE0001040003E000000008F4210003C030020F7
+:104BF00000431024104000398F820004304200022C
+:104C0000104000360000000097421014144000339A
+:104C100000000000974210088F8800383042FFFFE4
+:104C200024420006000218820003388000E8302188
+:104C3000304300018CC400001060000430420003C7
+:104C40000000000D0A00033700E810215440001056
+:104C50003084FFFF3C05FFFF0085202400851826D7
+:104C60000003182B0004102B0043102410400005F3
+:104C700000000000000000000000000D0000000027
+:104C8000240002228CC200000A00033600452025C1
+:104C90003883FFFF0003182B0004102B004310245F
+:104CA0001040000500000000000000000000000DA2
+:104CB000000000002400022B8CC200003444FFFFDF
+:104CC00000E81021AC4400003C0208008C42043093
+:104CD000244200013C010800AC2204308F62000035
+:104CE0008F840038AF8200088C8300003402FFFFFD
+:104CF0001462000F000010213C0508008CA504542C
+:104D00003C0408008C84045000B0282100B0302BF3
+:104D100000822021008620213C010800AC2504549B
+:104D20003C010800AC2404500A000580240400085B
+:104D30008C820000304201001040000F0000102162
+:104D40003C0508008CA5044C3C0408008C840448F5
+:104D500000B0282100B0302B0082202100862021C5
+:104D60003C010800AC25044C3C010800AC2404487C
+:104D70000A000580240400083C0508008CA50444B2
+:104D80003C0408008C84044000B0282100B0302B83
+:104D900000822021008620213C010800AC2504442B
+:104DA0003C010800AC2404400A00058024040008EB
+:104DB0008F6200088F62000000021602304300F08C
+:104DC000240200301062000524020040106200E05E
+:104DD0008F8200200A0005882442000114A00005EB
+:104DE00000000000000000000000000D00000000B6
+:104DF000240002568F4201780440FFFE00000000AC
+:104E00000E00023D27A40010144000050040802140
+:104E1000000000000000000D000000002400025D02
+:104E20008E0200001040000500000000000000009D
+:104E30000000000D00000000240002608F62000CE2
+:104E400004430003240200010A00042EAE00000007
+:104E5000AE0200008F8200388C480008A2000007D4
+:104E60008F65000C8F64000430A3FFFF0004240250
+:104E700000852023308200FF0043102124420005DA
+:104E8000000230832CC20081A605000A14400005F0
+:104E9000A2040004000000000000000D000000005B
+:104EA000240002788F8500380E0005AB260400141C
+:104EB0008F6200048F430108A60200083C02100024
+:104EC00000621824106000080000000097420104EE
+:104ED000920300072442FFEC346300023045FFFFD9
+:104EE0000A0003C3A2030007974201042442FFF013
+:104EF0003045FFFF960600082CC200135440000501
+:104F0000920300079202000734420001A202000748
+:104F1000920300072402000110620005240200032E
+:104F20001062000B8F8200380A0003E030C6FFFFDA
+:104F30008F8200383C04FFFF8C43000C006418246F
+:104F400000651825AC43000C0A0003E030C6FFFFE3
+:104F50003C04FFFF8C4300100064182400651825F2
+:104F6000AC43001030C6FFFF24C2000200021083D1
+:104F7000A20200058F830038304200FF000210803B
+:104F8000004328218CA800008CA200002403000408
+:104F900000021702144300120000000097420104AF
+:104FA0003C03FFFF010318243042FFFF004610239B
+:104FB0002442FFFE00624025ACA8000092030005D9
+:104FC000306200FF00021080005010219042001457
+:104FD0003042000F004310210A000415A20200060F
+:104FE0008CA40004974201049603000A3088FFFF56
+:104FF0003042FFFF004610232442FFD60002140077
+:1050000001024025ACA800049202000792040005AA
+:10501000246300280003188300641821344200042C
+:10502000A2030006A20200078F8200042403FFFBF4
+:105030003442000200431024AF82000492030006B1
+:105040008F87003800031880007010218C440020E6
+:105050003C02FFF63442FFFF008240240067182123
+:10506000AE04000CAC68000C920500063C03FF7F08
+:105070008E02000C0005288000B020213463FFFF61
+:10508000010330249488002600A72821004310241F
+:10509000AE02000CAC860020AC880024ACA8001046
+:1050A00024020010A742014024020002A74001424E
+:1050B000A7400144A7420146974201043C0400086E
+:1050C0002442FFFEA7420148240200010E00020C08
+:1050D000A742014A9603000A9202000400431021ED
+:1050E0002442000230420007000210233042000731
+:1050F0000E000235AE0200108F6200003C03080073
+:105100008C63044424040010AF8200089742010419
+:105110003042FFFF2442FFFE00403821000237C327
+:105120003C0208008C420440006718210067282BCD
+:1051300000461021004510213C010800AC23044426
+:105140003C010800AC2204400A00051500000000E4
+:1051500014A0000500000000000000000000000D89
+:10516000000000002400030A8F4201780440FFFE83
+:10517000000000000E00023D27A4001414400005AA
+:1051800000408021000000000000000D0000000031
+:10519000240003118E020000544000069202000712
+:1051A000000000000000000D000000002400031CAF
+:1051B0009202000730420004104000058F82000474
+:1051C0002403FFFB3442000200431024AF8200049A
+:1051D0008F62000404430008920200079202000656
+:1051E0008E03000CAE000000000210800050102161
+:1051F000AC430020920200073042000454400009F2
+:105200009602000A920200053C0300010002108091
+:10521000005010218C46001800C33021AC46001805
+:105220009602000A9206000427710008022020213D
+:1052300000C2302124C60005260500140E0005AB6F
+:1052400000063082920400068F6500043C027FFF56
+:1052500000042080009120218C8300043442FFFF51
+:1052600000A2282400651821AC83000492020007E4
+:105270009204000592030004304200041040001420
+:1052800096070008308400FF000420800091202150
+:105290008C860004974201049605000A306300FFE3
+:1052A0003042FFFF004310210045102130E3FFFF93
+:1052B000004310232442FFD830C6FFFF0002140031
+:1052C00000C23025AC8600040A0004C9920300071E
+:1052D000308500FF0005288000B128218CA4000043
+:1052E00097420104306300FF3042FFFF004310216A
+:1052F000004710233C03FFFF008320243042FFFFC0
+:1053000000822025ACA400009203000724020001C3
+:105310001062000600000000240200031062001169
+:10532000000000000A0004EC8E0300109742010404
+:10533000920300049605000A8E24000C00431021FD
+:10534000004510212442FFF23C03FFFF008320248C
+:105350003042FFFF00822025AE24000C0A0004EC3E
+:105360008E03001097420104920300049605000A80
+:105370008E24001000431021004510212442FFEE2E
+:105380003C03FFFF008320243042FFFF00822025E2
+:10539000AE2400108E0300102402000AA742014030
+:1053A000A74301429603000A920200043C04004015
+:1053B00000431021A7420144A7400146974201043F
+:1053C000A7420148240200010E00020CA742014A34
+:1053D0000E000235000000008F62000092030004FE
+:1053E00000002021AF820008974201049606000ABF
+:1053F0003042FFFF00621821006028213C030800B2
+:105400008C6304443C0208008C420440006518216F
+:10541000004410210065382B004710213C01080092
+:10542000AC2304443C010800AC2204409204000474
+:10543000008620212484000A3084FFFF0E0001E949
+:1054400000000000974401043084FFFF0E0001F7C4
+:10545000000000003C021000AF4201780A000587FE
+:105460008F820020148200273062000697420104D8
+:10547000104000673C0240003062400010400005D0
+:1054800000000000000000000000000D000000000F
+:10549000240004208F4201780440FFFE240208000B
+:1054A000AF42017824020008A7420140A740014210
+:1054B0008F8200049743010430420001104000072E
+:1054C0003070FFFF2603FFFE24020002A7420146C0
+:1054D000A74301480A00053F2402000DA7400146EA
+:1054E0002402000DA742014A8F6200002404000834
+:1054F000AF8200080E0001E9000000000A00051953
+:1055000002002021104000423C0240009362000053
+:10551000304300F0240200101062000524020070E5
+:10552000106200358F8200200A00058824420001A5
+:105530008F620000974301043050FFFF3071FFFF7E
+:105540008F4201780440FFFE320200070002102360
+:10555000304200072403000A2604FFFEA74301404F
+:10556000A7420142A7440144A7400146A751014870
+:105570008F42010830420020144000022403000939
+:1055800024030001A743014A0E00020C3C04004022
+:105590000E000235000000003C0708008CE70444C0
+:1055A000021110212442FFFE3C0608008CC6044074
+:1055B0000040182100E33821000010218F65000011
+:1055C00000E3402B00C230212604000800C830212F
+:1055D0003084FFFFAF8500083C010800AC2704447D
+:1055E0003C010800AC2604400E0001E90000000068
+:1055F0000A000519022020210E00013B00000000D6
+:105600008F82002024420001AF8200203C02400033
+:10561000AF4201380A000292000000003084FFFF10
+:1056200030C6FFFF00052C0000A628253882FFFFAA
+:10563000004510210045282B0045102100021C02C6
+:105640003042FFFF0043102100021C023042FFFFE6
+:10565000004310213842FFFF03E000083042FFFF03
+:105660003084FFFF30A5FFFF0000182110800007E5
+:1056700000000000308200011040000200042042BF
+:10568000006518210A0005A10005284003E0000874
+:105690000060102110C0000624C6FFFF8CA200008D
+:1056A00024A50004AC8200000A0005AB2484000499
+:1056B00003E000080000000010A0000824A3FFFF82
+:1056C000AC86000000000000000000002402FFFF84
+:1056D0002463FFFF1462FFFA2484000403E000083F
+:0456E00000000000C6
+:0456E40000000001C1
+:0856E8000A00002A0000000086
+:1056F000000000000000000D747870362E302E314E
+:105700003700000006001100000000000000013614
+:105710000000EA600000000000000000000000003F
+:105720000000000000000000000000000000000079
+:105730000000000000000000000000000000000069
+:105740000000000000000000000000160000000043
+:105750000000000000000000000000000000000049
+:105760000000000000000000000000000000000039
+:105770000000000000000000000000000000000029
+:105780000000138800000000000005DC000000009D
+:105790000000000010000003000000000000000DE9
+:1057A0000000000D3C02080024423D883C03080034
+:1057B0002463403CAC4000000043202B1480FFFDDC
+:1057C000244200043C1D080037BD7FFC03A0F021EB
+:1057D0003C100800261000A83C1C0800279C3D88AF
+:1057E0000E00044E000000000000000D27BDFFB4B5
+:1057F000AFA10000AFA20004AFA30008AFA4000C4B
+:10580000AFA50010AFA60014AFA70018AFA8001CEA
+:10581000AFA90020AFAA0024AFAB0028AFAC002C8A
+:10582000AFAD0030AFAE0034AFAF0038AFB8003C22
+:10583000AFB90040AFBC0044AFBF00480E000591B7
+:10584000000000008FBF00488FBC00448FB90040AB
+:105850008FB8003C8FAF00388FAE00348FAD003072
+:105860008FAC002C8FAB00288FAA00248FA90020BA
+:105870008FA8001C8FA700188FA600148FA50010FA
+:105880008FA4000C8FA300088FA200048FA100003A
+:1058900027BD004C3C1B60048F7A5030377B50286A
+:1058A00003400008AF7A00008F86003C3C03900064
+:1058B0003C0280000086282500A32025AC4400205F
+:1058C0003C0380008C67002004E0FFFE0000000025
+:1058D00003E00008000000000A000070240400013A
+:1058E0008F85003C3C0480003483000100A3102518
+:1058F00003E00008AC82002003E000080000102153
+:105900003084FFFF30A5FFFF108000070000182142
+:10591000308200011040000200042042006518217E
+:105920001480FFFB0005284003E000080060102100
+:1059300010C00007000000008CA2000024C6FFFF7A
+:1059400024A50004AC82000014C0FFFB24840004E2
+:1059500003E000080000000010A0000824A3FFFFDF
+:10596000AC86000000000000000000002402FFFFE1
+:105970002463FFFF1462FFFA2484000403E000089C
+:105980000000000090AA00318FAB00108CAC0040EA
+:105990003C0300FF8D680004AD6C00208CAD00441A
+:1059A00000E060213462FFFFAD6D00248CA7004849
+:1059B0003C09FF000109C024AD6700288CAE004CF3
+:1059C0000182C82403197825AD6F0004AD6E002C48
+:1059D0008CAD0038314A00FFAD6D001C94A9003237
+:1059E0003128FFFFAD68001090A70030A5600002CD
+:1059F000A1600004A167000090A30032306200FFA4
+:105A00000002198210600005240500011065000ED7
+:105A10000000000003E00008A16A00018CD8002803
+:105A2000354A0080AD7800188CCF0014AD6F00149B
+:105A30008CCE0030AD6E00088CC4002CA16A000131
+:105A400003E00008AD64000C8CCD001CAD6D0018A7
+:105A50008CC90014AD6900148CC80024AD6800081E
+:105A60008CC70020AD67000C8CC200148C830070C2
+:105A70000043C82B13200007000000008CC2001454
+:105A8000144CFFE400000000354A008003E00008E9
+:105A9000A16A00018C8200700A0000E6000000008C
+:105AA0009089003027BDFFF88FA8001CA3A9000033
+:105AB0008FA300003C0DFF8035A2FFFF8CAC002CB3
+:105AC00000625824AFAB0000A100000400C05821C0
+:105AD000A7A000028D06000400A048210167C8218C
+:105AE0008FA50000008050213C18FF7F032C20264A
+:105AF0003C0E00FF2C8C0001370FFFFF35CDFFFF60
+:105B00003C02FF0000AFC82400EDC02400C278248E
+:105B1000000C1DC00323682501F87025AD0D0000A1
+:105B2000AD0E00048D240024AFAD0000AD040008CC
+:105B30008D2C00202404FFFFAD0C000C9547003293
+:105B400030E6FFFFAD0600109145004830A200FF8F
+:105B5000000219C2506000018D240034AD0400140D
+:105B60008D4700388FAA001827BD0008AD0B00280C
+:105B7000AD0A0024AD07001CAD00002CAD000018DC
+:105B800003E00008AD00002027BDFFE0AFB2001821
+:105B9000AFB10014AFB00010AFBF001C9098003040
+:105BA00000C088213C0D00FF330F007FA0CF000014
+:105BB000908E003135ACFFFF3C0AFF00A0CE000103
+:105BC00094A6001EA22000048CAB00148E290004B1
+:105BD00000A08021016C2824012A4024008090210B
+:105BE00001052025A6260002AE240004260500207B
+:105BF000262400080E00009224060002924700307E
+:105C0000260500282624001400071E0000031603A2
+:105C100024060004044000032403FFFF96590032C9
+:105C20003323FFFF0E000092AE2300102624002431
+:105C30008FBF001C8FB200188FB100148FB00010FE
+:105C400024050003000030210A00009C27BD00202D
+:105C500027BDFFD8AFB1001CAFB00018AFBF002008
+:105C600090A900302402000100E050213123003FC0
+:105C700000A040218FB000400080882100C0482152
+:105C8000106200148FA70038240B000500A020210B
+:105C900000C02821106B0013020030210E000128E3
+:105CA000000000009225007C30A400021080000358
+:105CB00026030030AE000030260300348FBF0020E2
+:105CC0008FB1001C8FB000180060102103E00008A5
+:105CD00027BD00280E0000A7AFB000100A00016F1A
+:105CE000000000008FA3003C01002021012028219A
+:105CF00001403021AFA300100E0000EEAFB0001441
+:105D00000A00016F000000003C06800034C20E0053
+:105D10008C4400108F850044ACA400208C430018F4
+:105D200003E00008ACA300243C06800034C20E004F
+:105D30008C4400148F850044ACA400208C43001CCC
+:105D400003E00008ACA300249382000C1040001B69
+:105D50002483000F2404FFF00064382410E00019AD
+:105D6000978B00109784000E9389000D3C0A601CED
+:105D70000A0001AC01644023010370210064282360
+:105D80001126000231C2FFFF30A2FFFF0047302B77
+:105D900050C0000E00E448218D4D000C31A3FFFFE0
+:105DA00000036400000C2C0304A1FFF30000302169
+:105DB00030637FFF0A0001A42406000103E000080D
+:105DC000000000009784000E00E448213123FFFF0B
+:105DD0003168FFFF0068382B54E0FFF8A783000EFE
+:105DE000938A000D11400005240F0001006BC023B1
+:105DF000A380000D03E00008A798000E006BC023ED
+:105E0000A38F000D03E00008A798000E03E0000830
+:105E10000000000027BDFFE8AFB000103C1080007C
+:105E200036030140308BFFFF93AA002BAFBF001455
+:105E3000A46B000436040E009488001630C600FFE0
+:105E40008FA90030A4680006AC650008A0660012A7
+:105E5000A46A001AAC6700208FA5002CA469001862
+:105E6000012020210E000198AC6500143C021000B6
+:105E7000AE0201788FBF00148FB0001003E000085D
+:105E800027BD00188F8500002484000727BDFFF878
+:105E90003084FFF83C06800094CB008A316AFFFF13
+:105EA000AFAA00008FA90000012540232507FFFFAE
+:105EB00030E31FFF0064102B1440FFF700056882D9
+:105EC000000D288034CC400000AC102103E0000815
+:105ED00027BD00088F8200002486000730C5FFF828
+:105EE00000A2182130641FFF03E00008AF84000007
+:105EF0008F87003C8F84004427BDFFB0AFB70044BC
+:105F0000AFB40038AFB1002CAFBF0048AFB600400F
+:105F1000AFB5003CAFB30034AFB20030AFB0002833
+:105F20003C0B80008C860024AD6700808C8A0020AA
+:105F300035670E0035690100ACEA00108C8800243A
+:105F40008D2500040000B821ACE800188CE3001097
+:105F500000A688230000A021ACE300148CE2001806
+:105F6000ACE2001C122000FE00E0B021936C00089F
+:105F7000118000F400000000976F001031EEFFFF69
+:105F8000022E682B15A000EF000000009772001091
+:105F90003250FFFFAED000003C0380008C74000044
+:105FA000329300081260FFFD0000000096D8000840
+:105FB0008EC700043305FFFF30B5000112A000E4D6
+:105FC000000000000000000D30BFA0402419004078
+:105FD00013F9011B30B4A000128000DF00000000A4
+:105FE000937300081260000800000000976D001015
+:105FF00031ACFFFF00EC202B1080000330AE0040DE
+:1060000011C000D500000000A7850040AF87003810
+:106010009363000802202821AFB10020146000F52E
+:1060200027B40020AF60000C978F004031F1400092
+:1060300016200002240300162403000E2405400746
+:10604000A363000AAF650014938A00428F700014A6
+:10605000315500010015124002024825AF690014B5
+:10606000979F00408F78001433F9001003194025E2
+:10607000AF680014979200403247000810E0016EAC
+:10608000000000008F6700143C1210003C118000DB
+:1060900000F27825AF6F001436230E00946E000ACC
+:1060A0003C0D81002406000E31CCFFFF018D202520
+:1060B000AF640004A36600029373000A3406FFFC79
+:1060C000266B0004A36B000A979800403308200059
+:1060D0001100015F000000003C05800034A90E00A3
+:1060E000979900409538000C97870040001940426E
+:1060F0003312C0003103000300127B0330F11000A3
+:10610000006F68250011720301AE6025000C20C0ED
+:10611000A764001297930040936A000A0013598203
+:106120003175003C02AA10212450003CA3700009E4
+:10613000953F000C33F93FFFA779001097700012CC
+:10614000936900090130F82127E5000230B9000702
+:106150000019C02333080007A368000B93710009DE
+:1061600097720012976F0010322700FF8F9100384E
+:10617000978D004000F21821006F702101C6602148
+:1061800031A6004010C000053185FFFF00B1102B83
+:106190003C12800010400017000098210225A82B17
+:1061A00056A0013E8FA500203C048000348A0E00DA
+:1061B0008D5300143C068000AD5300108D4B001C25
+:1061C000AD4B0018AD4500008CCD000031AC00088F
+:1061D0001180FFFD34CE0E0095C3000800A0882179
+:1061E00000009021A78300408DC600042413000105
+:1061F000AF860038976F001031F5FFFF8E9F0000CB
+:1062000003F1282310A0011FAE850000936200084F
+:10621000144000DD000000000E0001E7240400101F
+:106220008F900048004028213C023200320600FFD7
+:10623000000654000142F82526090001AF890048F4
+:10624000ACBF00009379000997780012936F000AA1
+:10625000332800FF3303FFFF0103382100076C00E0
+:1062600031EE00FF01AE6025ACAC00048F84004825
+:10627000978B0040316A20001140010AACA400084D
+:1062800097640012308BFFFF06400108ACAB000C96
+:10629000978E004031C5000814A000022628000691
+:1062A000262800023C1F800037E70E0094F90014F6
+:1062B0008CE5001C8F670004937800023324FFFFF5
+:1062C000330300FFAFA300108F6F0014AFA80018B6
+:1062D0000E0001CBAFAF0014240400100E0001FB30
+:1062E000000000008E920000164000050000000033
+:1062F0008F7800142403FFBF0303A024AF7400149D
+:106300008F67000C00F5C821AF79000C9375000869
+:1063100016A0000800000000126000060000000047
+:106320008F6800143C0AEFFF3549FFFE0109F8248D
+:10633000AF7F0014A37300088FA500200A00034F4D
+:1063400002202021AED100000A00022D3C03800073
+:1063500014E0FF1E30BFA0400E0001900000A021FD
+:106360002E9100010237B02512C000188FBF0048DF
+:106370008F87003C24170F0010F700D43C068000E4
+:106380008CD901780720FFFE241F0F0010FF00F6B4
+:1063900034CA0E008D56001434C701402408024050
+:1063A000ACF600048D49001C3C141000ACE9000858
+:1063B000A0E00012A4E0001AACE00020A4E0001865
+:1063C000ACE80014ACD401788FBF00488FB700440C
+:1063D0008FB600408FB5003C8FB400388FB30034C7
+:1063E0008FB200308FB1002C8FB0002803E000087E
+:1063F00027BD00508F910038978800403C128000E4
+:106400000220A8213107004014E0FF7C0000982101
+:10641000977900108F9200383338FFFF131200A8CD
+:10642000000020210080A021108000F300A088211E
+:106430001620FECE000000000A00031F2E9100016E
+:106440003C0380008C6201780440FFFE24080800B1
+:106450008F860000AC6801783C038000946D008A50
+:1064600031ACFFFF01865823256AFFFF31441FFF2F
+:106470002C8900081520FFF9000000008F8F0048CC
+:10648000347040008F83003C00E0A021240E0F00F8
+:1064900025E70001AF87004800D03021023488236F
+:1064A0003C08800031F500FF106E00052407000154
+:1064B00093980042331300010013924036470001C5
+:1064C000001524003C0A0100008A4825ACC90000E0
+:1064D0008F82004830BF003630B90008ACC20004DB
+:1064E0001320009900FF982535120E009650000ADF
+:1064F0008F8700003C0F81003203FFFF24ED00086E
+:1065000035060140006F60253C0E100031AB1FFFC7
+:10651000269200062405000EACCC0020026E9825C1
+:10652000A4C5001AAF8B0000A4D2001816200008E2
+:106530003C1080008F89003C24020F005122000291
+:1065400024170001367300400E0001883C108000C3
+:1065500036060E008CCB0014360A01400240202182
+:10656000AD4B00048CC5001CAD450008A1550012C0
+:10657000AD5300140E0001983C151000AE150178C3
+:106580000A00035200000000936F0009976E00128A
+:10659000936D000B31E500FF00AE202131AC00FF10
+:1065A000008C80212602000A3050FFFF0E0001E718
+:1065B000020020218F8600483C0341003C058000FA
+:1065C00024CB0001AF8B0048936A00099769001241
+:1065D00030C600FF315F00FF3128FFFF03E838219C
+:1065E00024F900020006C4000319782501E3702590
+:1065F000AC4E00008F6D000C34A40E00948B001480
+:1066000001B26025AC4C00048C85001C8F6700042F
+:10661000936A00023164FFFF314900FFAFA9001007
+:106620008F680014AFB100180E0001CBAFA80014A2
+:106630000A0002FD02002021AF600004A3600002F6
+:1066400097980040330820001500FEA30000302179
+:10665000A760001297840040936B000A3C108000F2
+:1066600030931F0000135183014BA82126A200285C
+:10667000A362000936090E00953F000C0A0002953E
+:10668000A77F00108F700014360900400E000188AB
+:10669000AF6900140A0002C9000000000A00034F9D
+:1066A000000020210641FEFAACA0000C8CAC000CCE
+:1066B0003C0D8000018D90250A0002EAACB2000C6E
+:1066C000000090210A0002C5241300011280000777
+:1066D0003C028000344B0E009566000830D3004029
+:1066E00012600049000000003C0680008CD0017858
+:1066F0000600FFFE34C50E0094B500103C030500F3
+:1067000034CC014032B8FFFF03039025AD92000C5A
+:106710008CAF0014240D20003C041000AD8F000449
+:106720008CAE001CAD8E0008A1800012A580001A5E
+:10673000AD800020A5800018AD8D0014ACC4017898
+:106740000A0003263C0680008F9F00003518014098
+:106750002692000227F9000833281FFFA71200180D
+:106760000A000391AF8800003C02800034450140DC
+:10677000ACA0000C1280001B34530E0034510E00EC
+:106780008E370010ACB700048E2400183C0B80003C
+:10679000ACA400083570014024040040A20000129F
+:1067A0008FBF0048A600001A8FB70044AE0000203B
+:1067B0008FB60040A60000188FB5003CAE04001450
+:1067C0008FB400388FB300348FB200308FB1002CFB
+:1067D0008FB000283C02100027BD005003E00008E5
+:1067E000AD6201788E660014ACA600048E64001CB5
+:1067F0000A00042A3C0B80000E0001902E9100013B
+:106800000A0003200237B025000000000000000D40
+:1068100000000000240003690A0004013C06800017
+:1068200027BDFFD8AFBF00203C0980003C1F20FFE0
+:10683000AFB200183C07600035320E002402001091
+:1068400037F9FFFDACE23008AFB3001CAFB1001464
+:10685000AFB00010AE5900000000000000000000C2
+:106860000000000000000000000000003C1800FFD5
+:106870003713FFFDAE5300003C0B60048D705000D9
+:106880002411FF7F3C0E00020211782435EC380CF5
+:1068900035CD0109ACED4C18240A0009AD6C50004F
+:1068A0008CE80438AD2A0008AD2000148CE54C1C9F
+:1068B0003106FFFF38C42F7100051E023062000F41
+:1068C0002486C0B310400007AF8200088CE54C1C42
+:1068D0003C09001F3528FC0000A81824000321C231
+:1068E000AF8400048CF108083C0F57092412F00013
+:1068F0000232702435F0001001D0602601CF6826E6
+:106900002DAA00012D8B0001014B382550E0000914
+:10691000A380000C3C1F601C8FF8000824190001A4
+:10692000A399000C33137C00A7930010A780000EDE
+:10693000A380000DAF80004814C00003AF800000AA
+:106940003C066000ACC0442C0E0005B93C10800031
+:106950000E000F24361101003C12080026523DF0B3
+:106960003C13080026733E708E030000386400015B
+:10697000308200011440FFFC3C0B800A8E26000090
+:106980002407FF8024C90240312A007F014B4021A7
+:1069900001272824AE060020AF880044AE0500245D
+:1069A0003C048000AF86003C8C8C01780580FFFEA3
+:1069B00024180800922F0008AC980178A38F004299
+:1069C000938E004231CD000111A0000F24050D006F
+:1069D00024DFF8002FF903011320001C000629C250
+:1069E00024A4FFF000041042000231400E00020215
+:1069F00000D2D8213C0240003C068000ACC20138E5
+:106A00000A0004A00000000010C50023240D0F00A0
+:106A100010CD00273C1F800837F900809338000014
+:106A2000240E0050330F00FF15EEFFF33C02400030
+:106A30000E000A40000000003C0240003C068000BE
+:106A4000ACC201380A0004A0000000008F830004DB
+:106A500000A3402B1500000B8F8B0008006B50210A
+:106A60002547FFFF00E5482B1520000600A3602303
+:106A7000000C19400E0002020073D8210A0004C461
+:106A80003C0240000000000D0E0002020000000069
+:106A90000A0004C43C0240003C1B0800277B3F70F6
+:106AA0000E000202000000000A0004C43C02400084
+:106AB0003C1B0800277B3F900E00020200000000F4
+:106AC0000A0004C43C0240003C0660043C09080083
+:106AD00025290104ACC9502C8CC850003C0580000D
+:106AE0003C02000235070080ACC750003C0408009F
+:106AF000248415A43C0308002463155CACA500089D
+:106B0000ACA2000C3C010800AC243D803C01080014
+:106B1000AC233D8403E000082402000100A03021E2
+:106B20003C1C0800279C3D883C0C04003C0B0002E8
+:106B3000008B3826008C40262CE200010007502BE9
+:106B40002D050001000A48803C03080024633D80B5
+:106B5000004520250123182110800003000010218A
+:106B6000AC6600002402000103E000080000000001
+:106B70003C1C0800279C3D883C0B04003C0A00029A
+:106B8000008A3026008B38262CC200010006482BD4
+:106B90002CE50001000940803C03080024633D808F
+:106BA0000045202501031821108000050000102158
+:106BB0003C0C0800258C155CAC6C00002402000124
+:106BC00003E00008000000003C0900023C0804004B
+:106BD00000883026008938262CC300010080282137
+:106BE0002CE40001008310251040000B0000302130
+:106BF0003C1C0800279C3D883C0A80008D4E000804
+:106C00002406000101CA6825AD4D00088D4C000C1A
+:106C100001855825AD4B000C03E0000800C0102191
+:106C20003C1C0800279C3D883C0580008CA6000C7D
+:106C3000000420272402000100C4182403E00008F7
+:106C4000ACA3000C3C0200021082000B3C0560006B
+:106C50003C070400108700030000000003E0000868
+:106C6000000000008CA908D0240AFFFD012A40245E
+:106C700003E00008ACA808D08CA408D02406FFFECE
+:106C80000086182403E00008ACA308D03C05601A75
+:106C900034A600108CC3008027BDFFF88CC500848B
+:106CA000AFA3000093A4000024020001108200039F
+:106CB000AFA5000403E0000827BD000893A700016A
+:106CC00014E0001497AC000297B800023C0F80005B
+:106CD000330EFFFC01CF6821ADA50000A3A000008A
+:106CE0003C0660008CC708D02408FFFE3C04601AF4
+:106CF00000E82824ACC508D08FA300048FA20000B0
+:106D00003499001027BD0008AF22008003E000087E
+:106D1000AF2300843C0B8000318AFFFC014B4821EB
+:106D20008D2800000A00057DAFA8000427BDFFE8FC
+:106D3000AFBF00103C1C0800279C3D883C0580002C
+:106D40008CA4000C8CA200043C0300020044282404
+:106D500010A0000A00A318243C0604003C04000212
+:106D60001460000900A610241440000F3C04040025
+:106D70000000000D3C1C0800279C3D888FBF0010C0
+:106D800003E0000827BD00183C0208008C423D804B
+:106D90000040F809000000003C1C0800279C3D88CA
+:106DA0000A0005A68FBF00103C0208008C423D84FB
+:106DB0000040F809000000000A0005AC00000000D7
+:106DC000000411C003E00008244202403C04080013
+:106DD00024843FD42405001A0A00009C00003021BE
+:106DE00027BDFFE0AFB000103C108000AFBF00181F
+:106DF000AFB1001436110100922200090E0005B651
+:106E00003044007F8E3F00008F89003C3C0F0080A3
+:106E100003E26021258800400049F821240DFF800D
+:106E2000310E00783198007835F9000135F1000213
+:106E30000319382501D14825010D302403ED5824CC
+:106E4000018D2824240A004024040080240300C06B
+:106E5000AE0B0024AE000810AE0A0814AE040818E9
+:106E6000AE03081CAE050804AE070820AE060808ED
+:106E7000AE090824360909009539000C3605098049
+:106E800033ED007F3338FFFF001889C0AE110800D2
+:106E9000AE0F0828952C000C8FBF00188FB100147E
+:106EA000318BFFFF000B51C0AE0A002C8CA40050A8
+:106EB0008FB000108CA3003C8D2700048CA8001C10
+:106EC0008CA600383C0E800A01AE102127BD0020A0
+:106ED000AF820044AF840050AF830054AF87004CB2
+:106EE000AF88005C03E00008AF8600603C09080042
+:106EF00091293FF924A800023C05110000093C003B
+:106F000000E8302500C5182524820008AC83000065
+:106F100003E00008AC8000043C0980003523090030
+:106F20009128010B906A001124020028008048215A
+:106F3000314700FF00A0702100C0682131080040E7
+:106F400010E20002340C86DD240C08003C0A8000AC
+:106F500035420A9A94470000354B0A9C35460AA0F0
+:106F600030F9FFFFAD3900008D780000354B0A8005
+:106F700024040001AD3800048CCF0000AD2F0008C0
+:106F80009165001930A300031064009A2864000280
+:106F9000148000B924050002106500A8240F000326
+:106FA000106F00BE35450AA4240A0800118A004D5E
+:106FB00000000000510000423C0B80003C048000B7
+:106FC000348309009067001230E200FF004D782101
+:106FD000000FC880272400013C0A8000354F0900BB
+:106FE00091E50019354C09808D87002830A300FFFA
+:106FF00000031500004758250004C4003C19600038
+:1070000001793025370806FFAD260000AD280004C1
+:107010008DEA002C25280028AD2A00088DEC0030D0
+:10702000AD2C000C8DE50034AD2500108DE400384A
+:10703000AD2400148DE3001CAD2300188DE7002063
+:10704000AD27001C8DE20024AD2200208DF9002820
+:10705000AD3900243C0980003526093C8CCF000066
+:10706000352A0100AD0E0004AD0F00008D4E000C5E
+:107070003523090035250980AD0E0008906C0012FB
+:107080008D47000C8CB900343C18080093183FF869
+:10709000318200FF004D582103277823000B370071
+:1070A0000018240000C4702531E9FFFC01C96825DF
+:1070B00025020014AD0D000C03E00008AD00001027
+:1070C00035780900930600123C05080094A53FE8B6
+:1070D00030C800FF010D5021000A60800A00063C04
+:1070E0000185202115000060000000003C08080018
+:1070F00095083FEE3C06080094C63FE801061021C3
+:107100003C0B80003579090093380011932A00194F
+:1071100035660A80330800FF94CF002A0008608299
+:10712000314500FF978A0058000C1E00000524001E
+:107130003047FFFF006410250047C02501EA3021D9
+:107140003C0B4000030B402500066400AD28000006
+:10715000AD2C0004932500183C03000625280014DC
+:1071600000053E0000E31025AD2200088F24002C0E
+:10717000254F000131EB7FFFAD24000C8F38001C40
+:10718000A78B0058AD3800103C0980003526093C1B
+:107190008CCF0000352A0100AD0E0004AD0F0000B9
+:1071A0008D4E000C3523090035250980AD0E0008F1
+:1071B000906C00128D47000C8CB900343C1808000C
+:1071C00093183FF8318200FF004D582103277823A0
+:1071D000000B37000018240000C4702531E9FFFCC3
+:1071E00001C9682525020014AD0D000C03E000085C
+:1071F000AD0000103C02080094423FF23C0508003C
+:1072000094A53FE835440AA43C07080094E73FE40E
+:10721000948B00000045C8210327C023000B1C00ED
+:107220002706FFF200665025AD2A000CAD200010A5
+:10723000AD2C00140A00063025290018354F0AA489
+:1072400095E50000956400280005140000043C004A
+:107250003459810000EC5825AD39000CAD2B0010DD
+:107260000A000630252900143C0C0800958C3FEEDE
+:107270000A000686258200015460FF4C240A08009B
+:1072800035580AA49706000000061C00006C502523
+:10729000AD2A000C0A000630252900103C03080026
+:1072A00094633FF23C07080094E73FE83C0F080076
+:1072B00095EF3FE494A40000957900280067102121
+:1072C000004F582300041C00001934002578FFEEFD
+:1072D00000D87825346A8100AD2A000CAD2F00104B
+:1072E000AD200014AD2C00180A0006302529001C22
+:1072F00003E00008240207D027BDFFE0AFB200186A
+:10730000AFB10014AFB00010AFBF001C0E00007C86
+:10731000008088218F8800548F87004C3C058008AE
+:1073200034B20080011128213C108000240200802A
+:10733000240300C000A72023AE0208183C068008E2
+:10734000AE03081C18800004AF850054ACC50004CF
+:107350008CC90004AF89004C122000093604098052
+:107360000E00070200000000924C00278E0B0074F4
+:1073700001825004014B3021AE46000C36040980D6
+:107380008C8E001C8F8F005C01CF682319A0000435
+:107390008FBF001C8C90001CAF90005C8FBF001C46
+:1073A0008FB200188FB100148FB000100A00007E59
+:1073B00027BD00208F8600508F8300548F82004CA1
+:1073C0003C05800834A40080AC860050AC83003CAF
+:1073D00003E00008ACA200043C0308008C630054E6
+:1073E00027BDFFF8308400FF2462000130A500FFB4
+:1073F0003C010800AC22005430C600FF3C0780006E
+:107400008CE801780500FFFE3C0C7FFFA3A400037D
+:107410008FAA0000358BFFFF014B4824000627C0D0
+:1074200001244025AFA8000034E201009043000A87
+:10743000A3A000023C1980FFA3A300018FAF0000AE
+:1074400030AE007F3738FFFF01F86024000E6E0079
+:107450003C0A002034E50140018D582535492000C3
+:107460002406FF803C04100027BD0008ACAB000CD4
+:10747000ACA90014A4A00018A0A6001203E0000804
+:10748000ACE40178308800FF30A700FF3C038000A7
+:107490008C6201780440FFFE3C0C8000358A0A00B3
+:1074A0008D4B00203584014035850980AC8B00046C
+:1074B0008D4900240007302B00061540AC890008D8
+:1074C000A088001090A3004CA083002D03E00008CA
+:1074D000A480001827BDFFE8308400FFAFBF001074
+:1074E0000E00076730A500FF8F8300548FBF001088
+:1074F0003C06800034C50140344700402404FF901E
+:107500003C02100027BD0018ACA3000CA0A4001280
+:10751000ACA7001403E00008ACC2017827BDFFE06F
+:107520003C088008AFBF001CAFB20018AFB1001418
+:10753000AFB00010351000808E0600183C078000A8
+:10754000309200FF00C72025AE0400180E00007C1A
+:1075500030B100FF92030005346200080E00007E87
+:10756000A2020005024020210E00077B02202821F4
+:10757000024020218FBF001C8FB200188FB1001471
+:107580008FB0001024050005240600010A00073C06
+:1075900027BD00203C05800034A3098090660008C8
+:1075A00030C200081040000F3C0A01013549080AAA
+:1075B000AC8900008CA80074AC8800043C0708006B
+:1075C00090E73FF830E5001050A00008AC800008BC
+:1075D0003C0D800835AC00808D8B0058AC8B0008CA
+:1075E0002484000C03E00008008010210A0007BF7B
+:1075F0002484000C27BDFFE83C098000AFB00010D8
+:10760000AFBF00143526098090C800092402000687
+:1076100000A05821310300FF352709000080802198
+:10762000240500041062007B2408000294CF005C53
+:107630003C0E020431EDFFFF01AE6025AE0C0000F0
+:1076400090CA0008314400201080000800000000AB
+:1076500090C2004E3C1F010337F90300305800FF71
+:107660000319302524050008AE06000490F9001126
+:1076700090E6001290E40011333800FF0018708289
+:1076800030CF00FF01CF5021014B6821308900FF2E
+:1076900031AAFFFF39230028000A60801460002C03
+:1076A000020C482390E400123C198000372F01009F
+:1076B000308C00FF018B1821000310800045F82159
+:1076C000001F8400360706FFAD270004373F09007E
+:1076D00093EC001193EE0012372609800005C0825A
+:1076E0008DE4000C8CC5003431CD00FF01AB1021BE
+:1076F0000058182100A4F8230008840000033F006C
+:1077000000F0302533F9FFFF318F00FC00D97025E0
+:107710000158202101E9682100045080ADAE000C21
+:107720000E00007C012A80213C088008240B000404
+:10773000350500800E00007EA0AB0009020010217C
+:107740008FBF00148FB0001003E0000827BD0018A1
+:1077500090EC001190E300193C18080097183FEED8
+:10776000318200FF0002F882307000FF001FCE005F
+:1077700000103C000327302500D870253C0F400046
+:1077800001CF68253C198000AD2D0000373F09006E
+:1077900093EC001193EE0012372F01003726098079
+:1077A0000005C0828DE4000C8CC5003431CD00FF93
+:1077B00001AB10210058182100A4F8230008840010
+:1077C00000033F0000F0302533F9FFFF318F00FC4C
+:1077D00000D970250158202101E96821000450805A
+:1077E000ADAE000C0E00007C012A80213C08800810
+:1077F000240B0004350500800E00007EA0AB0009BC
+:10780000020010218FBF00148FB0001003E00008A9
+:1078100027BD00180A0007D12408001227BDFFD099
+:107820003C038000AFB60028AFB50024AFB4002001
+:10783000AFB10014AFBF002CAFB3001CAFB2001843
+:10784000AFB000103467010090E6000B309400FFE9
+:1078500030B500FF30C200300000B0211040009968
+:1078600000008821346409809088000800082E00F8
+:1078700000051E03046000C0240400048F86005429
+:107880003C010800A0243FF83C0C8000AD8000487B
+:107890003C048000348E010091CD000B31A5002006
+:1078A00010A000073C078000349309809272000802
+:1078B0000012860000107E0305E000C43C1F800813
+:1078C00034EC0100918A000B34EB098091690008C7
+:1078D000314400400004402B3123000800C89823A5
+:1078E0001460000224120003000090213C1080006C
+:1078F00036180A8036040900970E002C9083001178
+:107900009089001293050018307F00FF312800FF96
+:10791000024810210002C880930D0018033F78210F
+:1079200001F1302130B100FF00D11821A78E00589D
+:107930003C010800A4263FEE3C010800A4233FF0D0
+:1079400015A00002000000000000000D920B010BCA
+:107950003065FFFF3C010800A4233FF2316A00407C
+:107960003C010800A4203FE83C010800A4203FE4BB
+:107970001140000224A4000A24A4000B3091FFFF50
+:107980000E0001E7022020219206010B3C0C0800AA
+:10799000958C3FF2004020210006698231A700014A
+:1079A0000E000601018728210040202102602821C5
+:1079B0000E00060C024030210E0007AB00402021D3
+:1079C00016C00069004020219212010B325600407F
+:1079D00012C000053C0500FF8C93000034AEFFFF91
+:1079E000026E8024AC9000000E0001FB02202021DA
+:1079F0003C0F080091EF3FF831F100031220001610
+:107A00003C1380088F8200543C0980083528008090
+:107A1000245F0001AD1F003C3C0580088CB90004C8
+:107A200003E02021033FC0231B000002AF9F00544E
+:107A30008CA400040E000702ACA400043C078000E4
+:107A40008CEB00743C04800834830080004B502190
+:107A5000AC6A000C3C138008367000800280202144
+:107A600002A02821A200006B0E0007673C148000D2
+:107A70008F920054368C0140AD92000C8F860048E6
+:107A80003C151000344D000624D60001AF96004886
+:107A90008FBF002CA18600128FB60028AD8D001478
+:107AA0008FB3001CAE9501788FB200188FB50024FB
+:107AB0008FB400208FB100148FB0001003E00008D5
+:107AC00027BD003034640980908F0008000F7600D5
+:107AD000000E6E0305A00033347F090093F8001BED
+:107AE000241900103C010800A0393FF833130002AC
+:107AF0001260FF678F8600548F8200601446FF6516
+:107B00003C0480000E00007C000000003C04800863
+:107B10003485008090A8000924060016310300FF78
+:107B20001066000D0000000090AB00093C07080043
+:107B300090E73FF824090008316400FF34EA0001AF
+:107B40003C010800A02A3FF81089002F240C000AED
+:107B5000108C00282402000C0E00007E00000000A3
+:107B60000A00086A8F8600540E0007C302402821CD
+:107B70000A0008B8004020213C0B8008356A0080CC
+:107B80008D4600548CE9000C1120FF3DAF86005457
+:107B9000240700143C010800A0273FF80A000869E8
+:107BA0003C0C800090910008241200023C01080067
+:107BB000A0323FF8323000201200000B24160001E2
+:107BC0008F8600540A00086A2411000837F80080E4
+:107BD0008F020038AFE200048FF90004AF19003CB7
+:107BE0000A0008763C0780008F8600540A00086A65
+:107BF00024110004A0A200090E00007E0000000075
+:107C00000A00086A8F860054240200140A000944FE
+:107C1000A0A2000927BDFFE8AFB000103C10800013
+:107C2000AFBF001436020100904400090E00076740
+:107C3000240500013C0480089099000E34830080E4
+:107C4000909F000F906F00269089000A33F800FF84
+:107C500000196E000018740031EC00FF01AE5025D1
+:107C6000000C5A00014B3825312800FF3603014033
+:107C70003445600000E830252402FF813C041000F8
+:107C8000AC66000C8FBF0014AC650014A06200123B
+:107C9000AE0401788FB0001003E0000827BD001883
+:107CA00027BDFFE8308400FFAFBF00100E0007675C
+:107CB00030A500FF3C05800034A40140344700405B
+:107CC0002406FF92AC870014A08600128F83005414
+:107CD0008FBF00103C02100027BD0018AC83000CC1
+:107CE00003E00008ACA2017827BDFFD8AFB00010B8
+:107CF000308400FF30B000FF3C058000AFB10014BD
+:107D0000AFBF0020AFB3001CAFB20018000410C218
+:107D100034A6010032030002305100011460000754
+:107D200090D200093C098008353300809268000534
+:107D30003107000810E0000C308A001002402021BA
+:107D40000E00078D02202821240200018FBF002091
+:107D50008FB3001C8FB200188FB100148FB00010C9
+:107D600003E0000827BD00281540003434A50A00B0
+:107D70008CB800248CAF0008130F004B0000382192
+:107D80003C0D800835B30080926C00682406000228
+:107D9000318B00FF116600843C06800034C2010074
+:107DA0009263004C90590009307F00FF53F90004A2
+:107DB0003213007C10E00069000000003213007CE8
+:107DC0005660005C0240202116200009320D00019F
+:107DD0003C0C800035840100358B0A008D65002441
+:107DE0008C86000414A6FFD900001021320D00017A
+:107DF00011A0000E024020213C1880003710010025
+:107E00008E0F000C8F8E005011EE00080000000055
+:107E10000E00084D022028218E19000C3C1F8008FE
+:107E200037F00080AE190050024020210E00077B81
+:107E3000022028210A000999240200013C050800BB
+:107E40008CA5006424A400013C010800AC2400645B
+:107E50001600000D00000000022028210E00077B04
+:107E600002402021926E0068240C000231CD00FFF8
+:107E700011AC0022024020210E00094B000000003E
+:107E80000A000999240200010E0000702404000178
+:107E9000926B0025020B30250E00007EA2660025A5
+:107EA0000A0009DD022028218E6200188CDF000400
+:107EB0008CB9002400021E0217F9FFB13065007F63
+:107EC0009268004C264400013093007F1265004008
+:107ED000310300FF1464FFAB3C0D8008264700010E
+:107EE00030F1007F30E200FF1225000B2407000173
+:107EF000004090210A0009A6241100012405000475
+:107F00000E00073C240600010E00094B0000000093
+:107F10000A000999240200012405FF80024520245B
+:107F200000859026324200FF004090210A0009A6F9
+:107F3000241100010E00084D0220282132070030D4
+:107F400010E0FFA132100082024020210E00078DB8
+:107F5000022028210A000999240200018E690018D4
+:107F60000240202102202821012640250E00096E12
+:107F7000AE6800189264004C24050003240600013A
+:107F80000E00073C308400FF0E0000702404000146
+:107F900092710025021150250E00007EA26A002574
+:107FA0000A000999240200018E6F00183C18800015
+:107FB0000240202101F87025022028210E00077BB5
+:107FC000AE6E00189264004C0A000A2524050004D5
+:107FD000324A0080394900801469FF6A3C0D8008EC
+:107FE0000A0009FE2647000127BDFFC0AFB00018F8
+:107FF0003C108000AFBF0038AFB70034AFB60030E0
+:10800000AFB5002CAFB40028AFB30024AFB200204E
+:108010000E0005BEAFB1001C360201009045000BFA
+:108020000E00098090440008144000E78FBF00381C
+:108030003C08800835070080A0E0006B3606098008
+:1080400090C50000240300503C17080026F73FB0FD
+:1080500030A400FF3C13080026733FC010830003C8
+:108060003C1080000000B82100009821241F00105F
+:108070003611010036120A00361509808E58002488
+:108080008E3400048EAF00208F8C00543C01080019
+:10809000A03F3FF836190A80972B002C8EF600007F
+:1080A000932A00180298702301EC68233C01080011
+:1080B000AC2E3FD43C010800AC2D3FD83C01080059
+:1080C000AC2C3FFCA78B005802C0F809315400FFCC
+:1080D00030490002152000E930420001504000C440
+:1080E0009227000992A90008312800081500000213
+:1080F000241500030000A8213C0A80003543090034
+:1081000035440A008C8D002490720011907000128A
+:10811000907F0011325900FF321100FF02B110218F
+:108120000002C08033EF00FF0319B021028F7021DD
+:1081300002D4602125CB00103C010800A4363FEE9C
+:108140003C010800AC2D40003C010800A42C3FF08D
+:108150003C010800A42B3FEC355601003554098042
+:1081600035510E008F8700548F89005C8E8500206A
+:1081700024080006012730233C010800AC283FF406
+:1081800000A7282304C000B50000902104A000B37C
+:1081900000C5502B114000B5000000003C01080054
+:1081A000AC263FD88E6200000040F80900000000B5
+:1081B0003046000214C0007400408021304B0001A2
+:1081C000556000118E6200043C0D08008DAD3FDC4F
+:1081D0003C0EC0003C04800001AE6025AE2C0000C7
+:1081E0008C980000330F000811E0FFFD0000000034
+:1081F000963F000824120001A79F00408E3900041A
+:10820000AF9900388E6200040040F80900000000B9
+:108210000202802532030002146000B30000000057
+:108220003C09080095293FE43C06080094C63FF04D
+:108230003C0A0800954A3FE63C0708008CE73FDC13
+:10824000012670213C0308008C6340003C080800B4
+:1082500095083FFA01CA20218ED9000C00E9282197
+:10826000249F000200A878210067C02133E4FFFFAB
+:10827000AF9900503C010800AC3840003C010800B8
+:10828000A42F3FE83C010800A42E3FF20E0001E7B6
+:10829000000000008F8D0048004020213C010800B4
+:1082A000A02D3FF98E62000825AC0001AF8C00487C
+:1082B0000040F809000000008F85005402A0302122
+:1082C0000E00060C004020210E0007AB00402021CC
+:1082D0008E6B000C0160F809004020213C0A080068
+:1082E000954A3FF23C06080094C63FE60146482105
+:1082F000252800020E0001FB3104FFFF3C050800A9
+:108300008CA53FD43C0708008CE73FDC00A7202366
+:108310003C010800AC243FD414800006000000009B
+:108320003C0208008C423FF4344B00403C01080002
+:10833000AC2B3FF4124000438F8E00448E2D001072
+:108340008F920044AE4D00208E2C0018AE4C0024BD
+:108350003C04080094843FE80E000704000000007D
+:108360008F9F00548E6700103C010800AC3F3FFC1B
+:1083700000E0F809000000003C1908008F393FD4E4
+:108380001720FF798F870054979300583C11800E77
+:10839000321601000E000733A633002C16C000452C
+:1083A000320300105460004C8EE500043208004097
+:1083B0005500001D8EF000088EE4000C0080F809C6
+:1083C000000000008FBF00388FB700348FB6003038
+:1083D0008FB5002C8FB400288FB300248FB20020FB
+:1083E0008FB1001C8FB0001803E0000827BD0040CB
+:1083F0008F86003C36110E0000072E0000A62025B7
+:10840000AE0400808E4300208E500024AFA30010E5
+:10841000AE2300148FB20010AE320010AE30001C3C
+:108420000A000A7FAE3000180200F80900000000C0
+:108430008EE4000C0080F809000000000A000B38F0
+:108440008FBF003824180001240F0001A5C00020B0
+:10845000A5D800220A000B1AADCF00243C01080069
+:10846000AC203FD80A000AB08E6200003C01080030
+:10847000AC253FD80A000AB08E62000092240009A1
+:108480000E00077B000028218FBF00388FB7003413
+:108490008FB600308FB5002C8FB400288FB3002426
+:1084A0008FB200208FB1001C8FB0001803E00008CD
+:1084B00027BD00403C14800092950109000028214E
+:1084C0000E00084D32A400FF320300105060FFB8C8
+:1084D000320800408EE5000400A0F809000000000A
+:1084E0000A000B32320800405240FFA89793005810
+:1084F0008E3400148F930044AE7400208E35001C1F
+:10850000AE7500240A000B29979300588F8200143F
+:108510000004218003E00008008210213C0780084D
+:1085200034E200809043006900804021106000091F
+:108530003C0401003C0708008CE73FFC8F830030BF
+:1085400000E32023048000089389001C14E3000347
+:108550000100202103E00008008010213C040100FC
+:1085600003E00008008010211120000B0067382371
+:108570003C0D800035AC0980918B007C316A000293
+:10858000114000202409003400E9702B15C0FFF1D0
+:108590000100202100E938232403FFFC00A3C824A4
+:1085A00000E3C02400F9782B15E0FFEA030820213E
+:1085B00030C400030004102314C000143049000329
+:1085C0000000302100A9782101E6702100EE682B1F
+:1085D00011A0FFE03C0401002D3800010006C82B6B
+:1085E000010548210319382414E0FFDA2524FFFC93
+:1085F0002402FFFC00A218240068202103E00008E8
+:10860000008010210A000BA8240900303C0C8000D7
+:108610003586098090CB007C316A00041540FFE963
+:10862000240600040A000BB7000030213C030800B8
+:108630008C63005C8F82001827BDFFE0AFBF00187D
+:10864000AFB1001410620005AFB00010000329C0E4
+:1086500024A40280AF840014AF8300183C10800073
+:1086600036020A0094450032361101000E000B89D3
+:1086700030A43FFF8E240000241FFF803C110080A7
+:108680000082C021031F60243309007F000CC94011
+:1086900003294025330E0078362F00033C0D1000CF
+:1086A000010D502501CF5825AE0C00283608098051
+:1086B000AE0C080CAE0B082CAE0A08309103006912
+:1086C0003C06800C0126382110600006AF8700347C
+:1086D0008D09003C8D03006C0123382318E00082D3
+:1086E000000000003C0B8008356A00803C108000D0
+:1086F000A1400069360609808CC200383C06800023
+:1087000034C50A0090A8003C310C00201180001AEA
+:10871000AF820030240D00013C0E800035D10A00EC
+:10872000A38D001CAF8000248E2400248F8500249C
+:10873000240D0008AF800020AF8000283C01080015
+:10874000A42D3FE63C010800A4203FFA0E000B8D4B
+:10875000000030219228003C8FBF00188FB1001418
+:108760008FB0001000086142AF82002C27BD0020AE
+:1087700003E000083182000190B80032240E0001AD
+:10878000330F00FF000F2182108E004124190002D8
+:108790001099006434C40AC03C03800034640A00A9
+:1087A0008C8F002415E0001E34660900909F003075
+:1087B0002418000533F9003F1338004E240300014C
+:1087C0008F860020A383001CAF860028AF8600247C
+:1087D0003C0E800035D10A008E2400248F850024B1
+:1087E000240D00083C010800A42D3FE63C010800D0
+:1087F000A4203FFA0E000B8D000000009228003CE0
+:108800008FBF00188FB100148FB0001000086142B4
+:10881000AF82002C27BD002003E000083182000158
+:108820008C8A00088C8B00248CD000643C0E800065
+:1088300035D10A00014B2823AF900024A380001CEF
+:10884000AF8500288E2400248F8600208F85002489
+:10885000240D00083C010800A42D3FE63C0108005F
+:10886000A4203FFA0E000B8D000000009228003C6F
+:108870008FBF00188FB100148FB000100008614244
+:10888000AF82002C27BD002003E0000831820001E8
+:1088900090A200303051003F5224002834C50AC055
+:1088A0008CB000241600002234CB09008CA60048AE
+:1088B0003C0A7FFF3545FFFF00C510243C0E8000B9
+:1088C000AF82002035C509008F8800208CAD006084
+:1088D000010D602B15800002010020218CA4006096
+:1088E0000A000C2CAF8400208D02006C0A000C06DC
+:1088F0003C0680008C8200488F8600203C097FFF68
+:108900003527FFFF004788243C048008240300012A
+:10891000AF910028AC80006CA383001C0A000C3AC5
+:10892000AF8600248C9F00140A000C2CAF9F0020FF
+:108930008D6200680A000C763C0E800034C4098009
+:108940008C8900708CA300140123382B10E00004E4
+:10895000000000008C8200700A000C763C0E800043
+:108960008CA200140A000C763C0E80008F85002437
+:1089700027BDFFE0AFBF0018AFB1001414A000087E
+:10898000AFB000103C04800034870A0090E600304D
+:108990002402000530C3003F106200B9348409008E
+:1089A0008F91002000A080213C048000348E0A00BA
+:1089B0008DCD00043C0608008CC63FD831A73FFF90
+:1089C00000E6602B5580000100E03021938F001CF1
+:1089D00011E0007800D0282B349F098093F9007CA7
+:1089E00033380002130000792403003400C3102B35
+:1089F000144000D90000000000C3302300D0282B11
+:108A00003C010800A4233FE414A0006E02001821DA
+:108A10003C0408008C843FD40064402B55000001C6
+:108A2000006020213C05800034A90A00912A003C06
+:108A30003C010800AC243FDC3143002014600003FB
+:108A40000000482134AB0E008D6900188F88002C7F
+:108A50000128202B1080005F000000003C0508006A
+:108A60008CA53FDC00A96821010D602B1180005C02
+:108A700000B0702B0109382300E028213C010800D8
+:108A8000AC273FDC12000003240AFFFC10B0008D6D
+:108A90003224000300AA18243C010800A4203FFA55
+:108AA0003C010800AC233FDC006028218F840024B7
+:108AB000120400063C0B80088D6C006C0200202123
+:108AC000AF91002025900001AD70006C8F8D0028C3
+:108AD00000858823AF91002401A52023AF840028BE
+:108AE0001220000224070018240700103C188008F8
+:108AF0003706008090CF00683C010800A0273FF8AF
+:108B00002407000131EE00FF11C7004700000000FC
+:108B100014800018000028213C06800034D1098010
+:108B200034CD010091A600098E2C001824C4000148
+:108B3000000C86023205007F308B007F1165007FBC
+:108B40002407FF803C19800837290080A124004CAD
+:108B50003C0808008D083FF4241800023C0108007E
+:108B6000A0384039350F00083C010800AC2F3FF415
+:108B7000240500103C02800034440A009083003C2D
+:108B8000307F002013E0000500A02021240A00010E
+:108B90003C010800AC2A3FDC34A400018FBF001860
+:108BA0008FB100148FB000100080102103E0000886
+:108BB00027BD00203C010800A4203FE410A0FF9442
+:108BC000020018210A000CCA00C018210A000CC1BA
+:108BD000240300303C0508008CA53FDC00B0702B5E
+:108BE00011C0FFA8000000003C19080097393FE4BD
+:108BF0000325C0210307782B11E000072CAA0004ED
+:108C00003C0360008C625404305F003F17E0FFE3D8
+:108C1000240400422CAA00041140FF9A24040042BC
+:108C20000A000D2E8FBF00181528FFB900000000A4
+:108C30008CCA00183C1F800024020002015F182526
+:108C4000ACC3001837F90A00A0C200689329003CA1
+:108C50002404000400A01021312800203C01080059
+:108C6000A024403911000002240500102402000154
+:108C70003C010800AC223FD40A000D243C028000D5
+:108C80008F8800288C8900600109282B14A000021D
+:108C9000010088218C9100603C048000348B0E0020
+:108CA0008D640018240A00010220282102203021AE
+:108CB000A38A001C0E000B8D022080210A000CB03C
+:108CC000AF82002C000458231220000731640003F7
+:108CD0003C0E800035C7098090ED007C31AC00046B
+:108CE00015800019248F00043C010800A4243FFAD9
+:108CF0003C1F080097FF3FFA03E5C82100D9C02BAD
+:108D00001300FF6B8F8400242CA6000514C0FFA362
+:108D10002404004230A200031440000200A21823E1
+:108D200024A3FFFC3C010800AC233FDC3C0108000D
+:108D3000A4203FFA0A000CF10060282100C770242B
+:108D40000A000D1701C720263C010800A42F3FFA96
+:108D50000A000D82000000003C010800AC203FDC4E
+:108D60000A000D2D240400428F8300283C0580005A
+:108D700034AA0A0014600006000010219147003058
+:108D80002406000530E400FF108600030000000008
+:108D900003E0000800000000914B0048316900FF2B
+:108DA000000941C21500FFFA3C0680083C04080097
+:108DB00094843FE43C0308008C633FFC3C190800AA
+:108DC0008F393FDC3C0F080095EF3FFA0064C0216B
+:108DD0008CCD00040319702101CF602134AB0E004B
+:108DE000018D282318A0001D00000000914F004CA9
+:108DF0008F8C0034956D001031EE00FF8D890004DA
+:108E000001AE30238D8A000030CEFFFF000E290016
+:108E10000125C82100003821014720210325182BF6
+:108E20000083C021AD990004AD980000918F000A25
+:108E300001CF6821A18D000A956500128F8A003448
+:108E4000A5450008954B003825690001A549003863
+:108E50009148000D35070008A147000D03E0000808
+:108E60000000000027BDFFD8AFB000189388001C99
+:108E70008FB000143C0A80003C197FFF8F870024CC
+:108E80003738FFFFAFBF0020AFB1001C355F0A00CD
+:108E90000218182493EB003C00087FC03C02BFFF7F
+:108EA000006F60252CF000013449FFFF3C1F0800D3
+:108EB0008FFF3FFC8F9900303C18080097183FF255
+:108EC00001897824001047803C07EFFF3C05F0FF44
+:108ED00001E818253C1180003169002034E2FFFFD1
+:108EE00034ADFFFF362E098027A5001024060002AE
+:108EF00003F96023270B0002354A0E000062182494
+:108F00000080802115200002000040218D48001CB7
+:108F1000A7AB0012058000392407000030E800FFED
+:108F200000083F00006758253C028008AFAB0014E2
+:108F3000344F008091EA00683C08080091083FF92E
+:108F40003C09DFFF352CFFFF000AF82B3C0208002C
+:108F500094423FECA3A80011016CC024001FCF4035
+:108F6000031918258FA70010AFA300143C0C0800AC
+:108F7000918C3FFBA7A200168FAB001400ED482494
+:108F80003C0F01003C0A0FFF012FC8253198000358
+:108F9000355FFFFF016D40243C027000033F382421
+:108FA00000181E0000E2482501037825AFAF001429
+:108FB000AFA9001091CC007C0E000092A3AC00156C
+:108FC000362D0A0091A6003C30C400201080000617
+:108FD000260200083C11080096313FE8262EFFFFCC
+:108FE0003C010800A42E3FE88FBF00208FB1001C79
+:108FF0008FB0001803E0000827BD00288F8B002CDD
+:10900000010B502B5540FFC5240700010A000E0E2E
+:1090100030E800FF9383001C3C02800027BDFFD88E
+:1090200034480A0000805021AFBF002034460AC0F7
+:10903000010028211060000E34440980910700309F
+:10904000240B00058F89002030EC003F118B000BB2
+:1090500000003821AFA900103C0B80088D69006C1E
+:10906000AFAA00180E00015AAFA90014A380001C7B
+:109070008FBF002003E0000827BD00288D1F004897
+:109080003C1808008F183FDC8F9900283C027FFFB6
+:109090008D0800443443FFFFAFA900103C0B80084B
+:1090A0008D69006C03E370240319782101CF6823D4
+:1090B00001A83821AFAA00180E00015AAFA9001468
+:1090C0000A000E62A380001C3C05800034A60A0042
+:1090D00090C7003C3C06080094C63FFA3C020800DA
+:1090E0008C423FF430E30020000624001060001E94
+:1090F000004438253C0880083505008090A30068AE
+:109100000000482124080001000028212404000157
+:109110003C0680008CCD017805A0FFFE34CF0140D5
+:10912000ADE800083C0208008C423FFCA5E50004C5
+:10913000A5E40006ADE2000C3C04080090843FF971
+:109140003C03800834790080A1E40012ADE70014EC
+:10915000A5E900189338004C3C0E1000A1F8002D32
+:1091600003E00008ACCE017834A90E008D28001C65
+:109170003C0C08008D8C3FDC952B0016952A0014C2
+:10918000018648213164FFFF0A000E8A3145FFFF46
+:109190003C04800034830A009065003C30A200202B
+:1091A0001040001934870E000000402100003821D3
+:1091B000000020213C0680008CC901780520FFFEBC
+:1091C00034CA014034CF010091EB0009AD480008DA
+:1091D0003C0E08008DCE3FFC240DFF91240C004076
+:1091E0003C081000A5440004A5470006AD4E000C45
+:1091F000A14D0012AD4C0014A5400018A14B002D4C
+:1092000003E00008ACC801788CE8001894E600126E
+:1092100094E4001030C7FFFF0A000EB33084FFFF54
+:109220003C04800034830A009065003C30A200209A
+:109230001040002727BDFFF8240900010000382155
+:10924000240800013C0680008CCA01780540FFFE1E
+:109250003C0280FF34C40100908D00093C0C0800E2
+:10926000918C4039A3AD00038FAB00003185007FA6
+:109270003459FFFF01665025AFAA00009083000A11
+:10928000A3A0000200057E00A3A300018FB8000088
+:1092900034CB0140240C30000319702401CF682521
+:1092A000AD6D000C27BD0008AD6C0014A560001862
+:1092B000AD690008A56700042409FF80A5680006C1
+:1092C0003C081000A169001203E00008ACC8017856
+:1092D00034870E008CE9001894E6001294E4001024
+:1092E00030C8FFFF0A000ED73087FFFF27BDFFE021
+:1092F000AFB100143C118000AFB00010AFBF001838
+:1093000036380A00970F0032363001000E000B8904
+:1093100031E43FFF8E0E0000240DFF803C0420004E
+:1093200001C25821016D6024000C4940316A007F60
+:10933000012A4025010438253C048008AE27083066
+:109340003486008090C500682403000230A200FF2C
+:10935000104300048F9F00208F990024AC9F006869
+:10936000AC9900648FBF00188FB100148FB000104B
+:1093700003E0000827BD00203C0A0800254A3AA85F
+:109380003C09080025293B383C08080025082F44E3
+:109390003C07080024E73C043C06080024C6392C9E
+:1093A0003C05080024A536803C040800248432844F
+:1093B0003C030800246339E03C0208002442377C67
+:1093C0003C010800AC2A3FB83C010800AC293FB47E
+:1093D0003C010800AC283FB03C010800AC273FBC72
+:1093E0003C010800AC263FCC3C010800AC253FC442
+:1093F0003C010800AC243FC03C010800AC233FD036
+:109400003C010800AC223FC803E000080000000057
+:109410008000094080000900800801008008008069
+:1094200080080000800E0000800800808008000096
+:1094300080000A8080000A00800009808000090006
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex b/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex
deleted file mode 100644
index 52c496331de2..000000000000
--- a/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex
+++ /dev/null
@@ -1,424 +0,0 @@
-:100000000000000000000C900000005800000009F3
-:1000100000000000000000000000000000000000E0
-:1000200000000000000000000000000000000000D0
-:1000300000000CE000000CE80000000500000000DB
-:1000400000000000000000000000000000000000B0
-:080050000000000000000000A8
-:0800580000000010B180000659
-:100060000000001F01030300000000080500FFFF5F
-:10007000000000180002000000000008050000FF5A
-:10008000000000180002000000000008AC000001A1
-:1000900000000000050000000000000C2F8000019F
-:1000A000000000002B000000000000002B8000007A
-:1000B0000000001091E0000200000008AC00000108
-:1000C00000000010203F004D00000010213F000301
-:1000D0000000001020BF001C000000188000FFFD81
-:1000E00000000008B1000001000000082C8000B0F2
-:1000F000000000082D000008000000082D8000010D
-:10010000000000188000006C0000000B2FDF0002D0
-:100110000000000C1F800002000000002C070000FF
-:100120000000001091DE0000000000080500555599
-:10013000000000188000FFF00000000B2FDF00021D
-:100140000000000C1F800000000000002C070000D1
-:100150000000001091DE0000000000080500555569
-:10016000000000188000FFEA0000000C1F80000261
-:100170000000000805005555000000188000FFE74A
-:100180000000000C298000020000000C1F8000020B
-:10019000000000002ADF0000000000082A0000051F
-:1001A0000000000805005555000000188000FFE120
-:1001B000000000080224002C0000001800040000C9
-:1001C000000000188000001C000000188000001EC5
-:1001D000000000188000006500000018800000B0DA
-:1001E00000000018800000AF000000188000000030
-:1001F00000000018800000000000001880000000CF
-:1002000000000018800000000000001880000000BE
-:1002100000000018800000000000001880000000AE
-:10022000000000188000000000000018800000F6A8
-:10023000000000188000000000000018800000008E
-:100240000000001880000015000000188000001B4E
-:10025000000000188000000000000018800000C6A8
-:10026000000000188000002F00000018800000F639
-:10027000000000188000012100000018800000EC40
-:100280000000001880000145000000188000004EAA
-:1002900000000018800000000000001880000083AB
-:1002A0000000000C1F80000100000000050000009D
-:1002B000000000188000FFC00000001091D4000072
-:1002C0000000000C298000010000000C1F800001CC
-:1002D000000000082A0000020000000005000000E5
-:1002E000000000188000FFBA0000001091D4000048
-:1002F0000000000C298000010000000C1F8000019C
-:100300000000000029420000000000082A0000024E
-:100310000000000005000000000000188000FFB38E
-:10032000000000188000FFB200000010B1BCB00A4D
-:100330000000000B2FDF00020000000003D80000C7
-:10034000000000002C3C00000000001091D40000D0
-:100350000000000806005555000000188000001736
-:1003600000000018800000BF000000102C6201BADD
-:100370000000001880000006000000082C8000B17A
-:10038000000000082D0000090000001091D40000BA
-:10039000000000082D8001070000001880000024E4
-:1003A0000000000C298000000000000C1F800000ED
-:1003B0000000001091DE0000000000002ADF0000B5
-:1003C000000000082A00000600000008050055553E
-:1003D000000000188000FF9C0000001091D4000075
-:1003E0000000000C298000010000000C1F800001AB
-:1003F000000000082A00000B0000000005000000BB
-:10040000000000188000FF960000001800020000A5
-:10041000000000000682000000000010B18A000801
-:1004200000000010B18C14070000000B050AFFFF4C
-:1004300000000010B18A000300000000860A1800C6
-:1004400000000010918C0000000000082A0000014C
-:100450000000001091D4000000000018000D000002
-:1004600000000000050200000000001091DE000006
-:1004700000000018000A00000000000006820000D2
-:100480000000001091DE000000000010BEE1000539
-:10049000000000188000FF7D0000000105611400CD
-:1004A00000000010918A000200000008B0E1000185
-:1004B00000000018000D000000000000068200008F
-:1004C0000000001091DE000000000010BEE20005F8
-:1004D000000000188000FF75000000010562140094
-:1004E00000000010918A000200000008B1620001C3
-:1004F00000000018000D000000000010B1A0B013B3
-:100500000000000B2FDF0002000000002C20000084
-:10051000000000082C800000000000082D000000F2
-:100520000000001091D4000000000008060055559E
-:10053000000000188000FFDC000000082D80011C76
-:1005400000000010001F0000000000188000FFE6FF
-:100550000000000F476000080000000F060E0001B9
-:10056000000000000F580000000000000A640000B6
-:10057000000000000AE50000000000090B66FFFF14
-:10058000000000000D610000000000188000001352
-:100590000000000F476000080000000B2FDF000282
-:1005A000000000082C800000000000082D00000062
-:1005B0000000001091D40000000000082D80011CF4
-:1005C0000000000F060E000100000010001F0000D8
-:1005D000000000000F580000000000188000FFD449
-:1005E000000000000A640000000000000AE50000AE
-:1005F000000000090B66FFFF000000000D61000015
-:1006000000000000026200000000000B2FDF00026B
-:10061000000000003104000000000000309A0000DB
-:10062000000000000C961800000000090C99FFFF64
-:1006300000000004CC99340000000010B196320292
-:10064000000000080F8000000000000C298000015D
-:100650000000000C295200010000000C295200008B
-:10066000000000080200000E000000080280001ACE
-:1006700000000010B1C40A020000000802000003DC
-:1006800000000008220000010000000C1F80000193
-:10069000000000002ADF0000000000002A0008001F
-:1006A0000000000805005555000000188000FF41BB
-:1006B0000000000B2FDF00020000001091D40000AA
-:1006C000000000082A000001000000002C200000AB
-:1006D0000000001091D40000000000082C800000F1
-:1006E000000000082D000000000000082D80011C03
-:1006F000000000188000FFAE000000082C800006FB
-:10070000000000082D0000060000000030800000FE
-:100710000000000031000000000000082D800006ED
-:100720000000000C298000010000000C1F80000167
-:100730000000001091DE0000000000002ADF000031
-:10074000000000082A000010000000000500000062
-:10075000000000188000FF2C0000001091A0B009DC
-:10076000000000082C8000B1000000082D000009E6
-:100770000000001091D40000000000082D80010747
-:10078000000000188000FFA7000000188000001083
-:1007900000000008AC000001000000188000000B01
-:1007A000000000000380B0000000000B2FDF0002FB
-:1007B000000000002C0040000000001091D4000058
-:1007C0000000000806005555000000188000FF8951
-:1007D00000000018800000310000001880000006B2
-:1007E0000000000B2FDF0002000000002C000E00B4
-:1007F000000000082A000007000000080500555509
-:10080000000000188000FF160000000006820000B3
-:100810000000000C298000010000000C1F80000176
-:10082000000000100CE70007000000090562FFFF50
-:1008300000000010BA6C1405000000002ADF000060
-:100840000000000021000000000000082A00000550
-:100850000000001091D40000000000082C8000B0BF
-:10086000000000082D0000080000000C3162001894
-:10087000000000082D800001000000188000FF7DAE
-:1008800000000018000D000000000010B1A0B00E24
-:100890000000000B2FDF00020000000003D8000062
-:1008A000000000002C2000000000001091D4000087
-:1008B0000000001880000015000000102C620002EB
-:1008C000000000188000000C0000000B2FDF000269
-:1008D000000000002C0700000000000C1F80000139
-:1008E0000000001091DE0000000000080500FFFF7E
-:1008F000000000188000FEF8000000082C8000B105
-:10090000000000082D0000090000001091D4000034
-:10091000000000082D800107000000188000FF740F
-:100920000000000C298000010000000C1F80000165
-:100930000000001091DE0000000000002ADF00002F
-:10094000000000082A00000A000000000500000066
-:10095000000000188000FEEC00000000068200008D
-:10096000000000082C8000B0000000082D000008E6
-:10097000000000082D800150000000000000000071
-:100980000000001091DE0000000000082C80000034
-:10099000000000082D000000000000082D80010567
-:1009A00000000010BEE20005000000188000FEDA22
-:1009B000000000010562140000000010918A00028E
-:1009C00000000008B16200010000001091DE00008C
-:1009D00000000018000D00000000001091D400007D
-:1009E000000000080600AAAA000000188000FF45C9
-:1009F0000000000C298000010000000C1F80000195
-:100A0000000000082A000009000000080500AAAA4A
-:100A1000000000188000FED40000001091D40000F7
-:100A20000000000806005555000000188000FF3D3A
-:100A30000000001091A03C0200000010B1E6620727
-:100A40000000000B2FDF0002000000002C3100002E
-:100A5000000000092CB1007F000000082CD9000024
-:100A6000000000082D000000000000082D80010D8E
-:100A700000000010B1A8000600000010205F000078
-:100A8000000000002C200000000000002CA7000047
-:100A9000000000082D000010000000082D80010853
-:100AA000000000188000FF3800000010B1A6001000
-:100AB00000000010001F00000000000F0F300007B2
-:100AC000000000000A600000000000000AE10000D1
-:100AD0000000000F4B620008000000090B1600FF29
-:100AE000000000000D620000000000090D1A00FF68
-:100AF00000000010073000030000000C0D1A000871
-:100B00000000000C0B1600080000000F4CE300185A
-:100B1000000000000C992C0000000004CC99340067
-:100B2000000000080F8000000000000C2980000178
-:100B30000000000033310000000000082200001611
-:100B4000000000002ADF0000000000082A00000C5E
-:100B500000000010009F0000000000000F200000B7
-:100B60000000000C1F800001000000080500555522
-:100B7000000000188000FEA80000001091D40000C2
-:100B8000000000080600AAAA000000188000FF115B
-:100B90000000000F4722000800000009070E000FA8
-:100BA00000000008070E0008000000080280000195
-:100BB0000000000702851C0000000008828500017B
-:100BC0000000000002854C000000000742851C0068
-:100BD00000000003C3AA52000000000003B10E0091
-:100BE000000000074B071C000000000F0F3000073B
-:100BF0000000000F0A960003000000000A955C0048
-:100C0000000000004A005A00000000000C960A0094
-:100C1000000000090C99FFFF000000080D00FFFF15
-:100C200000000010B1963202000000080F8000059D
-:100C300000000010B1A8000800000010205F0000B4
-:100C40000000000B2FDF0002000000002C2000003D
-:100C5000000000002CA70000000000082D0000107C
-:100C6000000000082D800108000000188000FEFF31
-:100C70000000000C2980000100000010001F00008F
-:100C80000000000C1F800001000000002ADF0000AF
-:100C9000000000082A00000D000000080500AAAAB4
-:100CA000000000188000FE820000001091D40000B7
-:100CB0000000000806005555000000188000FEEBFB
-:100CC0000000000C298000010000000C1F800001C2
-:100CD000000000082A000007000000080500555524
-:080CE000000000188000FE7AFC
-:080CE80000000010B1800004BF
-:100CF0000000001F0103030000000008050000FFC2
-:100D00000000001800020000000000002A0000009F
-:100D100000000010B1D400000000001091DE0000BF
-:100D2000000000102053000000000010001F000011
-:100D3000000000002F80AA000000000C29800001A4
-:100D4000000000080254000D000000002C400000CC
-:100D500000000018000400000000001880000010CF
-:100D60000000001880000011000000188000003909
-:100D700000000018800000DF00000018800000DE86
-:100D800000000018800000DD00000018800000DD79
-:100D9000000000188000000000000018800000F52E
-:100DA00000000018800000D9000000188000000B2F
-:100DB00000000018800000F90000001880000147C2
-:100DC000000000188000005900000018800000C4D6
-:100DD00000000018800000C5000000002A0000008C
-:100DE000000000188000FFE6000000002A0000005C
-:100DF0000000000C29800000000000188000FFE3C4
-:100E0000000000002A000000000000188000FFE140
-:100E100000000018000200000000000005020000B1
-:100E2000000000109196342100000010205F0000A7
-:100E3000000000002C1E0000000000082C800006AE
-:100E4000000000082D000006000000082D800102AF
-:100E500000000000000000000000001091DE000013
-:100E6000000000000D61000000000018000A0000F2
-:100E700000000000050200000000001091963416EA
-:100E800000000010205F00000000000009D80000F2
-:100E9000000000002C1E0000000000082C8000B2A2
-:100EA000000000082D00000A000000082D8001024B
-:100EB00000000000000000000000001091DE0000B3
-:100EC000000000000D620000000000002C13000074
-:100ED00000000018000A00000000000005020000E9
-:100EE000000000109196340900000010205F0000FF
-:100EF000000000002C1E0000000000082C800006EE
-:100F0000000000082D00006A000000082D8001028A
-:100F100000000000000000000000001091DE000052
-:100F2000000000000D7A000000000018000A000018
-:100F3000000000002A000000000000000D61000019
-:100F4000000000000362000000000010234200A324
-:100F50000000000002638C00000000002646000034
-:100F6000000000080204001200000010B906081E6C
-:100F7000000000000F580000000000000A6400009C
-:100F8000000000000AE50000000000090B66FFFFFA
-:100F9000000000000C000000000000000B800000BA
-:100FA000000000080CC60012000000188000FFCEF0
-:100FB000000000080F800003000000000000000097
-:100FC00000000010009F0000000000082711001220
-:100FD000000000006690000000000008A31B001243
-:100FE00000000010B198000300000010001F000076
-:100FF000000000080F800004000000082200000329
-:10100000000000082C80000C000000082D00000CDF
-:1010100000000010009F0000000000002596000066
-:101020000000000C298000000000000032140000C5
-:1010300000000000329500000000000573662C00DF
-:101040000000000031E32E00000000082D80001099
-:10105000000000188000FF9800000000230000003E
-:101060000000000925E6FFFF000000082200000B39
-:101070000000000C695200000000000C29800000F4
-:10108000000000188000FF92000000002A0000000D
-:10109000000000082C800040000000082D00002007
-:1010A000000000082D80011C00000000000000006E
-:1010B0000000001091DE00000000000F42EA001066
-:1010C00000000010004F000400000010B74692001E
-:1010D000000000080249001200000010B5840A0058
-:1010E000000000000D61000000000010BA663457D7
-:1010F000000000088305001200000010004F0002ED
-:1011000000000000034900000000000183068C007D
-:101110000000000083C60C0000000010B187001121
-:10112000000000000B6E000000000010BEE900058A
-:10113000000000188000FF7900000001056914001C
-:1011400000000010918A000200000008B4E90001CC
-:1011500000000010B1E92C4A0000000086692C0054
-:1011600000000000020000000000000902EAFFFF8A
-:1011700000000010000C00020000000002040A0041
-:101180000000000F460C00010000000F0285000166
-:1011900000000010918C01FC00000010B7040E410B
-:1011A000000000000F400000000000000D61000082
-:1011B000000000000A640000000000000AE50000D2
-:1011C000000000090B66FFFF000000000C0000009B
-:1011D000000000000B800000000000080C860012D8
-:1011E000000000080F8000030000000C29520000DE
-:1011F00000000010009F00000000000827110012EE
-:10120000000000006690000000000000264600007C
-:10121000000000002306000000000010B198000547
-:1012200000000010001F0000000000080F800004F4
-:10123000000000000000000000000010001F00007F
-:101240000000000032140000000000003295000091
-:101250000000000031E32E000000000573662C0042
-:10126000000000002596000000000010B187001665
-:101270000000000C298000000000000F0F6B000729
-:10128000000000000D690000000000000A6C000072
-:10129000000000000AED0000000000000B6E0000DE
-:1012A000000000000B800000000000000C87000020
-:1012B000000000080F800003000000102053000011
-:1012C0000000000C6952000100000010001F000027
-:1012D0000000000022C58C0000000000231B00005D
-:1012E0000000000027110000000000002690000010
-:1012F00000000010B8170E030000000C2980000049
-:10130000000000188000FFF600000010B1980002F5
-:10131000000000080F800004000000082200001AEE
-:10132000000000082C80000C000000082D00000CBC
-:10133000000000082D80001000000010001F0000B9
-:10134000000000000D6E000000000003E7CF340035
-:101350000000000C298000000000001091DE000059
-:1013600000000010B18700070000000036140000E4
-:101370000000000036950000000000003716000055
-:10138000000000082C800050000000082D000030F4
-:10139000000000082D80000C000000188000FF2FC6
-:1013A00000000000264600000000000023000000AE
-:1013B0000000000925E6FFFF000000000B6E0000A2
-:1013C00000000003E7CF2C00000000082200001BF3
-:1013D0000000000C695200000000000C2980000091
-:1013E000000000188000FF26000000002A00000016
-:1013F000000000188000FF24000000002A00000008
-:101400000000000C298000000000001091DE0000A8
-:10141000000000082C80001A000000082D00001AAF
-:101420000000000573660000000000082D80000227
-:1014300000000000318000000000001091DE00007C
-:10144000000000082C80000C000000082D00000C9B
-:10145000000000082D800004000000188000FF1725
-:101460000000001800020000000000188000FF15B6
-:10147000000000002A00000000000010001F000013
-:10148000000000000F008000000000080F8000072F
-:10149000000000188000001A00000000280A000068
-:1014A0000000000005020000000000082200000902
-:1014B00000000000290000000000000F6568001017
-:1014C00000000003F66C940000000010B972A00444
-:1014D0000000000C73E700190000000C214200041A
-:1014E000000000003CF800000000000C2980000013
-:1014F0000000001020530000000000082200000837
-:101500000000000C6142000400000018000A000006
-:1015100000000000050200000000000C6142000015
-:1015200000000010014200030000000C33E7001D22
-:101530000000000C6142000200000018000A0000D8
-:10154000000000002A00000000000010001F000042
-:101550000000000F0F470007000000080F80000880
-:101560000000000C2980000000000010009F000017
-:10157000000000188000FEF400000000335100005D
-:10158000000000002A00000000000010B1C6002387
-:101590000000000F0F500007000000000A6000006C
-:1015A000000000000AE100000000000F4B6200088C
-:1015B000000000090B1600FF0000000F4C62001035
-:1015C000000000000D620000000000090D1A00FF7D
-:1015D00000000010075000030000000C0D1A000866
-:1015E0000000000C0B160008000000000CC60000F4
-:1015F000000000000B8000000000000006980000C2
-:10160000000000080F8000030000001006C2000464
-:101610000000000C29000002000000102642000219
-:101620000000000C29520003000000082200000105
-:1016300000000010009F000000000000231B0000BD
-:101640000000000027111A00000000006690000052
-:101650000000000C2952000000000010B197320970
-:101660000000000C29800000000000000698000027
-:1016700000000010205300000000000C295200035D
-:101680000000000022C58C0000000010001F0000B8
-:10169000000000080F800003000000188000FFF326
-:1016A00000000010B1C8001300000010B1C6000314
-:1016B0000000000C298000000000001020530000F2
-:1016C0000000000C295200000000000C2952000309
-:1016D0000000001006C200020000000C29520002A7
-:1016E0000000000022C58C000000000027650000FB
-:1016F0000000000026E400000000000822000016A0
-:1017000000000010B1C600030000000023480000E4
-:1017100000000010B1800005000000002348000018
-:101720000000000C298000000000000F0F5000078F
-:1017300000000018800000120000000822000016BF
-:101740000000000C298000000000000030140000A0
-:10175000000000003095000000000010075000035A
-:10176000000000090B1600FF000000090D1A00FF21
-:101770000000000F31160008000000003162340044
-:1017800000000003F162300000000010205F000044
-:10179000000000002C510000000000092CD1007F47
-:1017A000000000082CD90000000000082D000000F7
-:1017B000000000082D80000C000000000000000068
-:1017C0000000001091DE00000000001005C20004BF
-:1017D000000000080F800007000000003300000038
-:1017E00000000010009F0000000000188000FEA50F
-:1017F000000000002A0000000000000F0F5000074A
-:1018000000000010B1C6002D0000000F4742000884
-:1018100000000009070E000F00000008070E000876
-:1018200000000010001F0000000000080900000177
-:101830000000000709121C0000000003CBCA920040
-:10184000000000000B97A2000000000742171C00D8
-:10185000000000000B0400000000000F0A840003D9
-:10186000000000000A959C00000000004A009A0059
-:101870000000000882120001000000010C1708009F
-:10188000000000000C978C0000000000021800000F
-:10189000000000080D00FFFF000000080F80000698
-:1018A0000000000C290000000000001006C2000427
-:1018B0000000000C29520002000000102642000225
-:1018C0000000000C29520003000000082200000163
-:1018D00000000010009F000000000010B197320CC3
-:1018E00000000000231B000000000000271108007A
-:1018F00000000000669000000000000C298000003D
-:10190000000000000218000000000010205300003A
-:101910000000000C295200030000000022C5360020
-:1019200000000010001F0000000000080F800006EB
-:10193000000000188000FFF400000000231B0000DE
-:101940000000000027110800000000006690000061
-:1019500000000010B1C8000B0000000C298000003E
-:1019600000000010205300000000000C295200006D
-:101970000000000C295200030000001006C2000203
-:101980000000000C295200020000000022C58C005B
-:1019900000000000276500000000000026E40000B1
-:1019A000000000002348000000000008220000178B
-:1019B0000000000C2980000000000010001F000043
-:0819C000000000188000FE6A1F
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
diff --git a/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex b/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex
new file mode 100644
index 000000000000..dcc443e210f5
--- /dev/null
+++ b/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex
@@ -0,0 +1,366 @@
+:1000000000000000000008F800000058000000098F
+:1000100000000000000000000000000000000000E0
+:1000200000000000000000000000000000000000D0
+:1000300000000CF000000950000000050000000066
+:1000400000000000000000000000000000000000B0
+:080050000000000000000000A8
+:0800580000000010B180000659
+:100060000000001F0106000F000000080500FFFF50
+:10007000000000180002000000000008050000FF5A
+:10008000000000180002000000000008AC000001A1
+:1000900000000008078000000000000C2F80000115
+:1000A000000000002B000000000000002B8000007A
+:1000B0000000001091E1000200000008AC00000107
+:1000C00000000010203F003B00000010213F000313
+:1000D0000000001020BF0015000000188000FFFD88
+:1000E0000000000C1F800002000000188000FFF9D3
+:1000F00000000008B1000001000000082C8000B0E2
+:10010000000000082D000008000000082D800001FC
+:10011000000000188000003C0000000B2FDF0002F0
+:100120000000000C1F800002000000002C070000EF
+:100130000000001091DE0000000000188000FFEFBA
+:100140000000000B2FDF00020000000C1F800000E9
+:10015000000000002C0700000000001091DE0000ED
+:10016000000000188000FFEA0000000C1F80000261
+:10017000000000188000FFE80000000802240025AD
+:1001800000000018000400000000001880000000BB
+:10019000000000188000001B0000001880000042D2
+:1001A000000000188000000000000018800000001F
+:1001B000000000188000000000000018800000000F
+:1001C00000000018800000000000001880000000FF
+:1001D00000000018800000000000001880000000EF
+:1001E00000000018800000000000001880000000DF
+:1001F000000000188000008E000000188000000041
+:1002000000000018800000000000001880000000BE
+:1002100000000018800000000000001880000000AE
+:10022000000000188000000000000018800000009E
+:10023000000000188000008D00000018800000B74A
+:10024000000000188000008400000018800000DA20
+:10025000000000188000002B000000188000000043
+:10026000000000188000006B0000001091D4000016
+:100270000000000C298000010000000C1F8000011C
+:10028000000000082A0000020000000807800000AB
+:10029000000000188000FFC4000000080380010077
+:1002A00000000010B73C0E000000001880000000A5
+:1002B000000000180002000000000000068200009C
+:1002C00000000010B18F000400000010B18F140373
+:1002D000000000082A0000010000001091D4000076
+:1002E000000000000780140000000018000D00004E
+:1002F00000000000050200000000001091DE000078
+:1003000000000018000A0000000000000682000043
+:100310000000001091DE0000000000090561FFFFF1
+:1003200000000010918A00020000000830E1FFFF89
+:10033000000000188000FFA9000000010561140002
+:1003400000000010918A000200000008B0E10001E6
+:1003500000000018000D00000000000006820000F0
+:100360000000001091DE0000000000090562FFFFA0
+:1003700000000010918A0002000000083162FFFFB7
+:10038000000000188000FF9F0000000105621400BB
+:1003900000000010918A000200000008B162000114
+:1003A00000000018000D000000000010B1A0B01304
+:1003B0000000000B2FDF0002000000002C200000D6
+:1003C000000000082C800000000000082D00000044
+:1003D0000000001091D40000000000080500005546
+:1003E000000000188000FFDB000000082D80011CC9
+:1003F00000000010001F0000000000188000FFE255
+:100400000000000F476000080000000F060E00010A
+:10041000000000000F580000000000000A64000007
+:10042000000000000AE50000000000090B66FFFF65
+:10043000000000000D6100000000001880000015A1
+:100440000000000F476000080000000B2FDF0002D3
+:10045000000000082C800000000000082D000000B3
+:100460000000001091D40000000000082D80011C45
+:100470000000000F060E000100000010001F000029
+:10048000000000000F580000000000188000FFD09E
+:10049000000000000A640000000000000AE50000FF
+:1004A000000000090B66FFFF000000000D61000066
+:1004B00000000000026200000000000002E00000F6
+:1004C0000000000B2FDF00020000000030050000DC
+:1004D000000000003104000000000000309A00001D
+:1004E000000000100060000A00000008051600016E
+:1004F00000000010BA9A140300000000030000007E
+:100500000000001880000006000000188000FF6C4A
+:1005100000000010B60614040000000803060001E5
+:10052000000000082A000001000000188000FF7190
+:10053000000000000C961800000000090C99FFFF55
+:1005400000000004CC99340000000010BA992C027D
+:10055000000000080F8000000000000C298000014E
+:100560000000000C295200010000000C295200007C
+:100570000000000822800002000000080200000EB7
+:10058000000000080280001A00000010B1C40A0236
+:1005900000000008020000030000000C1F800001A2
+:1005A000000000002ADF0000000000002A00080010
+:1005B000000000188000FF600000000B2FDF000229
+:1005C0000000001091D40000000000082A00000183
+:1005D000000000002C2000000000001091D400005A
+:1005E000000000082C800000000000082D00000022
+:1005F000000000082D80011C000000188000FF9FF3
+:10060000000000082C800006000000082D000006F5
+:1006100000000000308000000000000031000000F9
+:10062000000000082D8000060000000C2980000159
+:100630000000000C1F8000010000001091DE00008F
+:10064000000000002ADF0000000000082A0000105F
+:100650000000000807800000000000188000FF4B29
+:100660000000001091D4000000000008050000AA5E
+:10067000000000188000FF890000000C29800001A4
+:100680000000000C1F800001000000082A00000983
+:10069000000000188000FF440000001091D400000A
+:1006A0000000000805000055000000188000FF82CF
+:1006B0000000001091A0B00200000010B1E6620737
+:1006C0000000000B2FDF0002000000002C310000B2
+:1006D000000000092CB1007F000000082CD90000A8
+:1006E000000000082D000000000000082D80010D12
+:1006F00000000010B1A8000600000010205F0000FC
+:10070000000000002C200000000000002CA70000CA
+:10071000000000082D000010000000082D800108D6
+:10072000000000188000FF7A00000010B1A6001041
+:1007300000000010001F00000000000F0F30000735
+:10074000000000000A600000000000000AE1000054
+:100750000000000F4B620008000000090B1600FFAC
+:10076000000000000D620000000000090D1A00FFEB
+:1007700000000010073000030000000C0D1A0008F4
+:100780000000000C0B1600080000000F4CE30018DE
+:10079000000000000C992C0000000004CC993400EB
+:1007A000000000080F8000000000000C29800001FC
+:1007B0000000000033310000000000082200001695
+:1007C000000000002ADF0000000000082A00000CE2
+:1007D00000000010009F0000000000002C2000001E
+:1007E0000000000C1F800001000000188000FF19AD
+:1007F0000000001091D4000000000008050000AACD
+:10080000000000188000FF570000000F472200087A
+:1008100000000009070E000F00000008070E000886
+:1008200000000008028000010000000702851C0093
+:1008300000000008828500010000000002854C00D5
+:100840000000000742851C0000000003C3AA5200FC
+:100850000000000003B10E00000000074B071C0061
+:100860000000000F0F3000070000000F0A96000381
+:10087000000000000A955C00000000004A005A00D9
+:10088000000000000C960A00000000090C99FFFF10
+:10089000000000080D00FFFF00000010BA992C02B4
+:1008A000000000080F80000500000010B1A800083B
+:1008B00000000010205F00000000000B2FDF00028E
+:1008C000000000002C200000000000002CA7000009
+:1008D000000000082D000010000000082D80010815
+:1008E000000000188000FF420000000C2980000179
+:1008F00000000010001F00000000000C1F8000011D
+:10090000000000002ADF0000000000082A00000D9F
+:10091000000000188000FEF40000001091D40000D8
+:100920000000000805000055000000188000FF329C
+:100930000000000C298000010000000C1F80000155
+:10094000000000082A000007000000188000FEEDEB
+:1009500000000010B18000040000001F0106000F1D
+:1009600000000008050000FF000000180002000061
+:10097000000000002A00000000000010B1D40000B8
+:100980000000001091DE0000000000102053000065
+:1009900000000010001F0000000000002F80AA00CF
+:1009A0000000000C29800001000000080254000E25
+:1009B000000000002C400000000000000F4000007C
+:1009C0000000001800040000000000188000001162
+:1009D000000000188000001200000018800000389D
+:1009E00000000018800000DF00000018800000DE1A
+:1009F00000000018800000DD00000018800000DD0D
+:100A0000000000188000000000000018800000F6C0
+:100A100000000018800000D90000001880000000CD
+:100A200000000018800000FA000000188000014853
+:100A3000000000188000005A00000018800000C468
+:100A400000000018800000C500000018800000D2DF
+:100A5000000000002A000000000000188000FFE4F1
+:100A6000000000002A0000000000000C29800000A7
+:100A7000000000188000FFE10000001800020000E4
+:100A8000000000000502000000000010B99A2C21AF
+:100A900000000010205F0000000000002C1E00007D
+:100AA000000000082C800006000000082D00000651
+:100AB000000000082D80010200000000000000007E
+:100AC0000000001091DE0000000000000D61000039
+:100AD00000000018000A00000000000005020000ED
+:100AE00000000010B99A2C1600000010205F0000D2
+:100AF0000000000009D80000000000002C1E0000CB
+:100B0000000000082C8000B2000000082D00000A40
+:100B1000000000082D80010200000000000000001D
+:100B20000000001091DE0000000000000D620000D7
+:100B3000000000002C13000000000018000A000054
+:100B4000000000000502000000000010B99A2C0906
+:100B500000000010205F0000000000002C1E0000BC
+:100B6000000000082C800006000000082D00006A2C
+:100B7000000000082D8001020000000000000000BD
+:100B80000000001091DE0000000000000D7A00005F
+:100B900000000018000A0000000000002A00000009
+:100BA0000000000822000001000000000D610000AC
+:100BB0000000001021C2002400000010B1C6000295
+:100BC00000000010234200A2000000090B66FFFF96
+:100BD00000000010BA9A2C20000000000A640000F7
+:100BE000000000000AE50000000000000C0000000A
+:100BF000000000000B800000000000080CC600127E
+:100C0000000000188000FFD0000000080F800003E3
+:100C1000000000000000000000000010009F000025
+:100C2000000000082711001200000000669000007C
+:100C300000000010B198000300000010001F000029
+:100C4000000000080F8000040000000822000003DC
+:100C5000000000082C80000C000000082D00000C93
+:100C600000000010009F00000000001091C6000569
+:100C700000000010001F000000000010BA9A2C03B2
+:100C8000000000080F800004000000188000FFFD35
+:100C900000000000259600000000000C29800000E4
+:100CA0000000000032140000000000003295000037
+:100CB0000000000573662C000000000031E32E00E8
+:100CC000000000082D800010000000188000FF9632
+:100CD00000000000230000000000000925E6FFFFDF
+:100CE000000000082200000B0000000C6952000008
+:100CF0000000000C29800000000000188000FF9018
+:100D0000000000002A000000000000082C800040C5
+:100D1000000000082D000020000000082D80011CAC
+:100D200000000008220000010000001091DE000019
+:100D30000000000F42EA001000000010004F000405
+:100D400000000010B746920000000008024900129F
+:100D500000000010B5840A00000000000D610000D2
+:100D600000000010BA663457000000088305001226
+:100D700000000010004F00020000000003490000C6
+:100D80000000000183068C000000000083C60C00F8
+:100D900000000010B1870013000000000B6E00007F
+:100DA000000000090569FFFF00000010918A0002A1
+:100DB0000000000834E9FFFF000000188000FF7504
+:100DC000000000010569140000000010918A000273
+:100DD00000000008B4E9000100000010BAE92C4846
+:100DE0000000000086692C000000000002000000E6
+:100DF0000000000902EAFFFF00000010000C0002E2
+:100E00000000000002040A000000000F460C000170
+:100E10000000000F0285000100000010918C01FC11
+:100E200000000010B7040E3F000000000D6100003C
+:100E3000000000000A640000000000000AE5000055
+:100E4000000000090B66FFFF000000000C0000001E
+:100E5000000000000B800000000000080C8600125B
+:100E6000000000080F8000030000000C2952000061
+:100E700000000010009F0000000000082711001271
+:100E80000000000066900000000000002306000043
+:100E900000000010B198000500000010001F0000C5
+:100EA000000000080F8000040000000000000000A7
+:100EB00000000010001F00000000000032140000BD
+:100EC00000000000329500000000000031E32E0019
+:100ED0000000000573662C0000000000259600004D
+:100EE00000000010B18700160000000C29800000EF
+:100EF0000000000F0F6B0007000000000D690000EC
+:100F0000000000000A6C0000000000000AED000074
+:100F1000000000000B6E0000000000000B800000CD
+:100F2000000000000C870000000000080F80000394
+:100F300000000010205300000000000C6952000166
+:100F400000000010001F00000000000022C58C00FF
+:100F500000000000231B000000000000271100001B
+:100F6000000000002690000000000010B8170E03DB
+:100F70000000000C29800000000000188000FFF62F
+:100F800000000010B1980002000000080F8000046B
+:100F9000000000082200001A000000082C80000C4D
+:100FA000000000082D00000C000000082D8000103B
+:100FB00000000010001F0000000000000D6E000087
+:100FC00000000003E7CF34000000000C298000007F
+:100FD0000000001091DE000000000010B187000743
+:100FE00000000000361400000000000036950000EC
+:100FF0000000000037160000000000082C800050A0
+:10100000000000082D000030000000082D80000CBA
+:10101000000000188000FF2D0000000023000000E9
+:101020000000000925E6FFFF000000000B6E000035
+:1010300000000003E7CF2C00000000082200001B86
+:101040000000000C695200000000000C2980000024
+:10105000000000188000FF25000000002A000000AA
+:10106000000000188000FF23000000002A0000009C
+:101070000000000C298000000000001091DE00003C
+:10108000000000082C80001A000000082D00001A43
+:101090000000000573660000000000082D800002BB
+:1010A00000000000318000000000001091DE000010
+:1010B000000000082C80000C000000082D00000C2F
+:1010C000000000082D800004000000188000FF16BA
+:1010D0000000001880000000000000188000FF14CD
+:1010E000000000002A00000000000010001F0000A7
+:1010F000000000000F008000000000080F800007C3
+:10110000000000188000001B00000000280A0000FA
+:101110000000000005020000000000082200000995
+:1011200000000000290000000000000F65680010AA
+:1011300000000000248A000000000003F66C940008
+:1011400000000010B972A0040000000C73E7001941
+:101150000000000C21420004000000003CF80000E8
+:101160000000000C29800000000000102053000047
+:1011700000000008220000080000000C614200048A
+:1011800000000018000A0000000000000502000036
+:101190000000000C6142000000000010014200034A
+:1011A0000000000C33E7001D0000000C614200024B
+:1011B00000000018000A0000000000002A000000E3
+:1011C00000000010001F00000000000F0F47000784
+:1011D000000000080F8000080000000C29800000BB
+:1011E00000000010009F0000000000188000FEF2C8
+:1011F0000000000033510000000000002A00000041
+:1012000000000010B1C600230000000F0F500007BF
+:10121000000000000A600000000000000AE1000079
+:101220000000000F4B620008000000090B1600FFD1
+:101230000000000F4C620010000000000D62000072
+:10124000000000090D1A00FF000000100750000305
+:101250000000000C0D1A00080000000C0B1600081E
+:10126000000000000CC60000000000000B80000021
+:101270000000000006980000000000080F80000336
+:101280000000001006C200040000000C290000024B
+:1012900000000010264200020000000C295200034A
+:1012A000000000082200000100000010009F000064
+:1012B00000000000231B00000000000027111A009E
+:1012C00000000000669000000000000C29520000A1
+:1012D00000000010B19732090000000C29800000C6
+:1012E00000000000069800000000001020530000DD
+:1012F0000000000C295200030000000022C58C00F1
+:1013000000000010001F0000000000080F80000314
+:10131000000000188000FFF300000010B1C80013A7
+:1013200000000010B1C600030000000C298000007E
+:1013300000000010205300000000000C29520000A3
+:101340000000000C295200030000001006C2000239
+:101350000000000C295200020000000022C58C0091
+:1013600000000000276500000000000026E40000E7
+:10137000000000082200001600000010B1C60003A3
+:10138000000000002348000000000010B1800005AC
+:1013900000000000234800000000000C298000002D
+:1013A0000000000F0F50000700000018800000121E
+:1013B00000000008220000160000000C2980000038
+:1013C0000000000030140000000000003095000014
+:1013D0000000001007500003000000090B1600FF7A
+:1013E000000000090D1A00FF0000000F3116000870
+:1013F000000000003162340000000003F1623000A0
+:1014000000000010205F0000000000002C510000D0
+:10141000000000092CD1007F000000082CD900003A
+:10142000000000082D000000000000082D80000CC6
+:1014300000000000000000000000001091DE00002D
+:101440000000001005C20004000000080F80000723
+:10145000000000003300000000000010009F0000AA
+:10146000000000188000FEA3000000002A00000019
+:101470000000000F0F50000700000010B1C6002D43
+:101480000000000F4742000800000009070E000F8F
+:1014900000000008070E000800000010001F0000F8
+:1014A00000000008090000010000000709121C00EC
+:1014B00000000003CBCA9200000000000B97A200BE
+:1014C0000000000742171C00000000000B04000091
+:1014D0000000000F0A840003000000000A959C0031
+:1014E000000000004A009A0000000008821200017B
+:1014F000000000010C170800000000000C978C0091
+:101500000000000002180000000000080D00FFFFAE
+:10151000000000080F8000060000000C29000000F9
+:101520000000001006C200040000000C2952000256
+:1015300000000010264200020000000C29520003A7
+:10154000000000082200000100000010009F0000C1
+:1015500000000010B197320C00000000231B0000B7
+:101560000000000027110800000000006690000045
+:101570000000000C2980000000000000021800009C
+:1015800000000010205300000000000C295200034E
+:101590000000000022C5360000000010001F0000FF
+:1015A000000000080F800006000000188000FFF413
+:1015B00000000000231B00000000000027110800AD
+:1015C000000000006690000000000010B1C8000B91
+:1015D0000000000C298000000000001020530000D3
+:1015E0000000000C295200000000000C29520003EA
+:1015F0000000001006C200020000000C2952000288
+:101600000000000022C58C000000000027650000DB
+:101610000000000026E40000000000002348000055
+:1016200000000008220000170000000C29800000C4
+:1016300000000010001F0000000000188000FE687D
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex b/firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex
deleted file mode 100644
index fe59d16b594e..000000000000
--- a/firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex
+++ /dev/null
@@ -1,462 +0,0 @@
-:100000000000000000000E08000000580000000979
-:1000100000000000000000000000000000000000E0
-:1000200000000000000000000000000000000000D0
-:1000300000000DD800000E60000000050000000068
-:1000400000000000000000000000000000000000B0
-:080050000000000000000000A8
-:0800580000000010B180000659
-:100060000000001F05030300000000080500FFFF5B
-:10007000000000180002000000000008050000FF5A
-:10008000000000180002000000000008AC000001A1
-:1000900000000000050000000000000C2F8000019F
-:1000A000000000002B000000000000002B8000007A
-:1000B0000000001091E0000200000008AC00000108
-:1000C00000000010203F006B00000010213F0003E3
-:1000D0000000001020BF003A000000188000FFFD63
-:1000E00000000010B1B8B0150000000B2FDF0002B7
-:1000F0000000000003D80000000000002C380000C1
-:10010000000000082C800000000000082D00000006
-:100110000000001091D400000000000806005555B2
-:10012000000000188000007C000000082D80011CE9
-:1001300000000008020000010000001091DE000035
-:100140000000000F42E0001C0000001091840A161D
-:1001500000000018800000830000000C29800002CD
-:100160000000000C1F800002000000002ADF0000D9
-:10017000000000082A00000F000000000500000039
-:10018000000000188000FFE60000000802000001E7
-:100190000000000F42E0001C0000001091840A18CB
-:1001A000000000082C800006000000082D0000065A
-:1001B0000000001091D40000000000082D8001060E
-:1001C0000000001880000072000000188000FFF19D
-:1001D00000000008B1000001000000082C80010CA4
-:1001E000000000082D000008000000082D8000011C
-:1001F000000000188000006C0000000B2FDF0002E0
-:100200000000000C1F800002000000002C0700000E
-:100210000000001091DE00000000000805005555A8
-:10022000000000188000FFD20000000B2FDF00024A
-:100230000000000C1F800000000000002C070000E0
-:100240000000001091DE0000000000080500555578
-:10025000000000188000FFCC0000000C1F8000028E
-:100260000000000805005555000000188000FFC977
-:100270000000000C298000020000000C1F8000021A
-:10028000000000002ADF0000000000082A0000052E
-:100290000000000805005555000000188000FFC34D
-:1002A000000000080224004A0000001800040000BA
-:1002B000000000188000001C000000188000001ED4
-:1002C000000000188000006500000018800000BCDD
-:1002D00000000018800000BB000000188000000033
-:1002E00000000018800000000000001880000000DE
-:1002F00000000018800000000000001880000000CE
-:1003000000000018800000000000001880000000BD
-:1003100000000018800000000000001880000107A5
-:10032000000000188000000000000018800000009D
-:100330000000001880000015000000188000001B5D
-:10034000000000188000000000000018800000D2AB
-:10035000000000188000002F000000188000010736
-:10036000000000188000013200000018800000FD2D
-:100370000000001880000156000000188000004EA8
-:100380000000001880000000000000188000008FAE
-:100390000000000C1F8000010000000005000000AC
-:1003A000000000188000FFA20000001091D400009F
-:1003B0000000000C298000010000000C1F800001DB
-:1003C000000000082A0000020000000005000000F4
-:1003D000000000188000FF9C0000001091D4000075
-:1003E0000000000C298000010000000C1F800001AB
-:1003F0000000000029420000000000082A0000025E
-:100400000000000005000000000000188000FF95BB
-:10041000000000188000FF9400000010B1BCB00A7A
-:100420000000000B2FDF00020000000003D80000D6
-:10043000000000002C3C00000000001091D40000DF
-:100440000000000806005555000000188000001745
-:1004500000000018800000CB000000102C6201BAE0
-:100460000000001880000006000000082C80010D2C
-:10047000000000082D0000090000001091D40000C9
-:10048000000000082D8001070000001880000024F3
-:100490000000000C298000000000000C1F800000FC
-:1004A0000000001091DE0000000000002ADF0000C4
-:1004B000000000082A00000600000008050055554D
-:1004C000000000188000FF7E0000001091D40000A2
-:1004D0000000000C298000010000000C1F800001BA
-:1004E000000000082A00000B0000000005000000CA
-:1004F000000000188000FF780000001800020000D3
-:10050000000000000682000000000010B18A000810
-:1005100000000010B18C14070000000B050AFFFF5B
-:1005200000000010B18A000300000000860A1800D5
-:1005300000000010918C0000000000082A0000015B
-:100540000000001091D4000000000018000D000011
-:1005500000000000050200000000001091DE000015
-:1005600000000018000A00000000000006820000E1
-:100570000000001091DE000000000010BEE1000548
-:10058000000000188000FF5F0000000105611400FA
-:1005900000000010918A000200000008B0E1000194
-:1005A00000000018000D000000000000068200009E
-:1005B0000000001091DE000000000010BEE2000507
-:1005C000000000188000FF570000000105621400C1
-:1005D00000000010918A000200000008B1620001D2
-:1005E00000000018000D000000000010B1A0B013C2
-:1005F0000000000B2FDF0002000000002C20000094
-:10060000000000082C800000000000082D00000001
-:100610000000001091D400000000000806005555AD
-:10062000000000188000FFDC000000082D80011C85
-:1006300000000010001F0000000000188000FFE60E
-:100640000000000F476000080000000F060E0001C8
-:10065000000000000F580000000000000A640000C5
-:10066000000000000AE50000000000090B66FFFF23
-:10067000000000000D610000000000188000001361
-:100680000000000F476000080000000B2FDF000291
-:10069000000000082C800000000000082D00000071
-:1006A0000000001091D40000000000082D80011C03
-:1006B0000000000F060E000100000010001F0000E7
-:1006C000000000000F580000000000188000FFD458
-:1006D000000000000A640000000000000AE50000BD
-:1006E000000000090B66FFFF000000000D61000024
-:1006F00000000000026200000000000B2FDF00027B
-:10070000000000003104000000000000309A0000EA
-:10071000000000090560000F00000010B18A000B06
-:100720000000000005634C0000000008050A0012EC
-:1007300000000010B9621403000000000300000074
-:100740000000001880000006000000188000FF2450
-:1007500000000010B60614040000000803060001A3
-:10076000000000082A000001000000188000FF2996
-:10077000000000000C961800000000090C99FFFF13
-:1007800000000004CC99340000000010B196320241
-:10079000000000080F8000000000000C298000010C
-:1007A0000000000C295200010000000C295200003A
-:1007B000000000080200000E000000080280001A7D
-:1007C00000000010B1C40A0200000008020000038B
-:1007D00000000008220000010000000C1F80000142
-:1007E000000000002ADF0000000000002A000800CE
-:1007F0000000000805005555000000188000FF1794
-:100800000000000B2FDF00020000001091D4000058
-:10081000000000082A000001000000002C20000059
-:100820000000001091D40000000000082C8000009F
-:10083000000000082D000000000000082D80011CB1
-:10084000000000188000FFA2000000082C800006B5
-:10085000000000082D0000060000000030800000AD
-:100860000000000031000000000000082D8000069C
-:100870000000000C298000010000000C1F80000116
-:100880000000001091DE0000000000002ADF0000E0
-:10089000000000082A000010000000000500000011
-:1008A000000000188000FF020000001091A0B009B5
-:1008B000000000082C80010D000000082D00000938
-:1008C0000000001091D40000000000082D800107F6
-:1008D000000000188000FF9B00000018800000103E
-:1008E00000000008AC000001000000188000000BB0
-:1008F000000000000380B0000000000B2FDF0002AA
-:10090000000000002C0040000000001091D4000006
-:100910000000000806005555000000188000FF7D0B
-:100920000000001880000031000000188000000660
-:100930000000000B2FDF0002000000002C000E0062
-:10094000000000082A0000070000000805005555B7
-:10095000000000188000FEEC00000000068200008D
-:100960000000000C298000010000000C1F80000125
-:10097000000000100CE70007000000090562FFFFFF
-:1009800000000010BA6C1405000000002ADF00000F
-:100990000000000021000000000000082A000005FF
-:1009A0000000001091D40000000000082C80010C11
-:1009B000000000082D0000080000000C3162001843
-:1009C000000000082D800001000000188000FF7169
-:1009D00000000018000D000000000010B1A0B00ED3
-:1009E0000000000B2FDF00020000000003D8000011
-:1009F000000000002C2000000000001091D4000036
-:100A00000000001880000015000000102C62000299
-:100A1000000000188000000C0000000B2FDF000217
-:100A2000000000002C0700000000000C1F800001E7
-:100A30000000001091DE0000000000080500FFFF2C
-:100A4000000000188000FECE000000082C80010D80
-:100A5000000000082D0000090000001091D40000E3
-:100A6000000000082D800107000000188000FF68CA
-:100A70000000000C298000010000000C1F80000114
-:100A80000000001091DE0000000000002ADF0000DE
-:100A9000000000082A00000A000000000500000015
-:100AA000000000188000FEC2000000000682000066
-:100AB000000000082C80010C000000082D00000838
-:100AC000000000082D80013400000000000000003C
-:100AD00000000010205F0000000000082C80014092
-:100AE000000000082D00003C000000082D800124BB
-:100AF00000000000000000000000001091DE000077
-:100B0000000000082C800080000000082D0000007C
-:100B1000000000082D80010500000010BEE2000565
-:100B2000000000188000FEAB000000010562140008
-:100B300000000010918A000200000008B16200016C
-:100B40000000001091DE000000000018000D000001
-:100B50000000001091D40000000000080600AAAABE
-:100B6000000000188000FF340000000C2980000104
-:100B70000000000C1F800001000000082A0000098E
-:100B8000000000080500AAAA000000188000FEA5C9
-:100B90000000001091D40000000000080600555528
-:100BA000000000188000FF2C0000001091A03C0203
-:100BB00000000010B1E662070000000B2FDF00020A
-:100BC000000000002C310000000000092CB1007F63
-:100BD000000000082CD90000000000082D000000D3
-:100BE000000000082D80010D00000010B1A80006D3
-:100BF00000000010205F0000000000002C2000001A
-:100C0000000000002CA70000000000082D000010CC
-:100C1000000000082D800108000000188000FF2758
-:100C200000000010B1A6001000000010001F00001E
-:100C30000000000F0F300007000000000A600000F5
-:100C4000000000000AE100000000000F4B620008F5
-:100C5000000000090B1600FF000000000D620000FC
-:100C6000000000090D1A00FF00000010073000030B
-:100C70000000000C0D1A00080000000C0B16000804
-:100C80000000000F4CE30018000000000C992C003D
-:100C900000000004CC993400000000080F80000020
-:100CA0000000000C2980000100000000333100002A
-:100CB0000000000822000016000000002ADF0000EB
-:100CC000000000082A00000C00000010009F000037
-:100CD000000000000F2000000000000C1F80000139
-:100CE0000000000805005555000000188000FE793E
-:100CF0000000001091D40000000000080600AAAA1D
-:100D0000000000188000FF000000000F47220008CC
-:100D100000000009070E000F00000008070E000881
-:100D200000000008028000010000000702851C008E
-:100D300000000008828500010000000002854C00D0
-:100D40000000000742851C0000000003C3AA5200F7
-:100D50000000000003B10E00000000074B071C005C
-:100D60000000000F0F3000070000000F0A9600037C
-:100D7000000000000A955C00000000004A005A00D4
-:100D8000000000000C960A00000000090C99FFFF0B
-:100D9000000000080D00FFFF00000010B1963202B5
-:100DA000000000080F80000500000010B1A8000836
-:100DB00000000010205F00000000000B2FDF000289
-:100DC000000000002C200000000000002CA7000004
-:100DD000000000082D000010000000082D80010810
-:100DE000000000188000FEEE0000000C29800001C9
-:100DF00000000010001F00000000000C1F80000118
-:100E0000000000002ADF0000000000082A00000D9A
-:100E1000000000080500AAAA000000188000FE5388
-:100E20000000001091D40000000000080600555595
-:100E3000000000188000FEDA0000000C298000018C
-:100E40000000000C1F800001000000082A000007BD
-:100E50000000000805005555000000188000FE4BFA
-:100E600000000010B18000040000001F0503030013
-:100E700000000008050000FF00000018000200004C
-:100E8000000000002A00000000000010B1D40000A3
-:100E90000000001091DE0000000000102053000050
-:100EA00000000010001F0000000000002F80AA00BA
-:100EB0000000000C29800001000000080254000E10
-:100EC000000000002C400000000000092952003FF3
-:100ED000000000180004000000000018800000104E
-:100EE0000000001880000011000000188000003988
-:100EF00000000018800000FD00000018800000FCC9
-:100F000000000018800000FB00000018800000FBBB
-:100F1000000000188000000000000018800001138D
-:100F200000000018800000F7000000188000000B8F
-:100F30000000001880000117000000188000016503
-:100F4000000000188000006300000018800000CE40
-:100F500000000018800000DE000000002A000000F1
-:100F6000000000188000FFE5000000002A000000DB
-:100F70000000000C29800000000000188000FFE243
-:100F8000000000002A000000000000188000FFE0C0
-:100F90000000001800020000000000000502000030
-:100FA000000000109196342100000010205F000026
-:100FB000000000002C1E0000000000082C8000062D
-:100FC000000000082D000006000000082D8001022E
-:100FD00000000000000000000000001091DE000092
-:100FE000000000000D61000000000018000A000071
-:100FF0000000000005020000000000109196341669
-:1010000000000010205F00000000000009D8000070
-:10101000000000002C1E0000000000082C80010EC3
-:10102000000000082D00000A000000082D800102C9
-:1010300000000000000000000000001091DE000031
-:10104000000000000D620000000000002C130000F2
-:1010500000000018000A0000000000000502000067
-:10106000000000109196340900000010205F00007D
-:10107000000000002C1E0000000000082C8000066C
-:10108000000000082D00006A000000082D80010209
-:1010900000000000000000000000001091DE0000D1
-:1010A000000000000D7A000000000018000A000097
-:1010B000000000002A000000000000000D61000098
-:1010C000000000000362000000000010234200C185
-:1010D0000000000002638C000000000026460000B3
-:1010E000000000080204001200000010B9060827E2
-:1010F000000000000F580000000000000A6400001B
-:10110000000000000AE50000000000090B66FFFF78
-:10111000000000000C000000000000000B80000038
-:10112000000000080CC60012000000188000FFCE6E
-:10113000000000080F800003000000000000000015
-:1011400000000010009F000000000008271100129E
-:10115000000000006690000000000008A31B0012C1
-:1011600000000010B198000300000010001F0000F4
-:10117000000000080F8000040000000822000003A7
-:10118000000000082C80000C000000082D00000C5E
-:1011900000000010009F00000000000025960000E5
-:1011A0000000000C2980000000000000066600001E
-:1011B0000000000086611800000000090260000FB6
-:1011C0000000000F0204000200000010B60C080529
-:1011D0000000000C1FBF0000000000102866000384
-:1011E00000000008078F00010000000C33660010AB
-:1011F00000000000321400000000000032950000E2
-:101200000000000573662C000000000031E32E0092
-:10121000000000082D800010000000188000FF8EE4
-:1012200000000000230000000000000925E6FFFF89
-:10123000000000082200000B0000000C69520000B2
-:101240000000000C298000000000001028660075D6
-:10125000000000188000FF87000000002A00000046
-:10126000000000082C800040000000082D00002035
-:10127000000000082D80011C00000000000000009C
-:101280000000001091DE00000000000F42EA001094
-:1012900000000010004F000400000010B74692004C
-:1012A000000000080249001200000010B5840A0086
-:1012B000000000000D61000000000010BA66345705
-:1012C000000000088305001200000010004F00021B
-:1012D00000000000034900000000000183068C00AC
-:1012E0000000000083C60C0000000010B187001150
-:1012F000000000000B6E000000000010BEE90005B9
-:10130000000000188000FF6E000000010569140055
-:1013100000000010918A000200000008B4E90001FA
-:1013200000000010B1E92C4A0000000086692C0082
-:1013300000000000020000000000000902EAFFFFB8
-:1013400000000010000C00020000000002040A006F
-:101350000000000F460C00010000000F0285000194
-:1013600000000010918C01FC00000010B7040E4139
-:10137000000000000F400000000000000D610000B0
-:10138000000000000A640000000000000AE5000000
-:10139000000000090B66FFFF000000000C000000C9
-:1013A000000000000B800000000000080C86001206
-:1013B000000000080F8000030000000C295200000C
-:1013C00000000010009F000000000008271100121C
-:1013D00000000000669000000000000026460000AB
-:1013E000000000002306000000000010B198000576
-:1013F00000000010001F0000000000080F80000423
-:10140000000000000000000000000010001F0000AD
-:1014100000000000321400000000000032950000BF
-:101420000000000031E32E000000000573662C0070
-:10143000000000002596000000000010B187001693
-:101440000000000C298000000000000F0F6B000757
-:10145000000000000D690000000000000A6C0000A0
-:10146000000000000AED0000000000000B6E00000C
-:10147000000000000B800000000000000C8700004E
-:10148000000000080F80000300000010205300003F
-:101490000000000C6952000100000010001F000055
-:1014A0000000000022C58C0000000000231B00008B
-:1014B000000000002711000000000000269000003E
-:1014C00000000010B8170E030000000C2980000077
-:1014D000000000188000FFF600000010B198000224
-:1014E000000000080F800004000000082200001A1D
-:1014F000000000082C80000C000000082D00000CEB
-:10150000000000082D80001000000010001F0000E7
-:10151000000000000D6E000000000003E7CF340063
-:101520000000000C298000000000001091DE000087
-:1015300000000010B1870007000000003614000012
-:101540000000000036950000000000003716000083
-:10155000000000082C800050000000082D00003022
-:10156000000000082D80000C000000188000FF24FF
-:1015700000000000264600000000000023000000DC
-:101580000000000925E6FFFF000000000B6E0000D0
-:1015900000000003E7CF2C00000000082200001B21
-:1015A0000000000C695200000000000C29800000BF
-:1015B000000000188000FF1B000000002A0000004F
-:1015C000000000100866000500000000066600002C
-:1015D000000000008661180000000009026000F0B1
-:1015E00000000010B60C0802000000188000FF1474
-:1015F000000000000682000000000010B18F000013
-:1016000000000008878F00010000000C73660010C6
-:10161000000000082C800018000000082D000018B1
-:10162000000000082D8000020000000C5FBF0000D9
-:101630000000001091DE000000000018000D000006
-:10164000000000002A00000000000010286601F5DC
-:10165000000000082C800003000000082D0000039B
-:10166000000000093060FFF0000000082D8000013C
-:101670000000000C298000000000001091DE000036
-:10168000000000082C80001A000000082D00001A3D
-:101690000000000573660000000000082D800002B5
-:1016A00000000000318000000000001091DE00000A
-:1016B000000000082C80000C000000082D00000C29
-:1016C000000000082D800004000000188000FEF8D3
-:1016D0000000001800020000000000188000FEF664
-:1016E000000000002A00000000000010001F0000A1
-:1016F000000000000F008000000000080F800007BD
-:10170000000000188000001A00000000280A0000F5
-:10171000000000000502000000000008220000098F
-:1017200000000000290000000000000F65680010A4
-:1017300000000003F66C940000000010B972A004D1
-:101740000000000C73E700190000000C21420004A7
-:10175000000000003CF800000000000C29800000A0
-:1017600000000010205300000000000822000008C4
-:101770000000000C6142000400000018000A000094
-:1017800000000000050200000000000C61420000A3
-:1017900000000010014200030000000C33E7001DB0
-:1017A0000000000C6142000200000018000A000066
-:1017B000000000002A00000000000010001F0000D0
-:1017C0000000000F0F470007000000080F8000080E
-:1017D0000000000C2980000000000010009F0000A5
-:1017E000000000188000FED500000000335100000A
-:1017F000000000002A00000000000010B1C6002315
-:101800000000000F0F500007000000000A600000F9
-:10181000000000000AE100000000000F4B62000819
-:10182000000000090B1600FF0000000F4C620010C2
-:10183000000000000D620000000000090D1A00FF0A
-:1018400000000010075000030000000C0D1A0008F3
-:101850000000000C0B160008000000000CC6000081
-:10186000000000000B80000000000000069800004F
-:10187000000000080F8000030000001006C20004F2
-:101880000000000C290000020000001026420002A7
-:101890000000000C29520003000000082200000193
-:1018A00000000010009F000000000000231B00004B
-:1018B0000000000027111A000000000066900000E0
-:1018C0000000000C2952000000000010B1973209FE
-:1018D0000000000C298000000000000006980000B5
-:1018E00000000010205300000000000C29520003EB
-:1018F0000000000022C58C0000000010001F000046
-:10190000000000080F800003000000188000FFF3B3
-:1019100000000010B1C8001300000010B1C60003A1
-:101920000000000C2980000000000010205300007F
-:101930000000000C295200000000000C2952000396
-:101940000000001006C200020000000C2952000234
-:101950000000000022C58C00000000002765000088
-:101960000000000026E4000000000008220000162D
-:1019700000000010B1C60003000000002348000072
-:1019800000000010B18000050000000023480000A6
-:101990000000000C298000000000000F0F5000071D
-:1019A000000000188000001200000008220000164D
-:1019B0000000000C2980000000000000301400002E
-:1019C00000000000309500000000001007500003E8
-:1019D000000000090B1600FF000000090D1A00FFAF
-:1019E0000000000F311600080000000031623400D2
-:1019F00000000003F162300000000010205F0000D2
-:101A0000000000002C510000000000092CD1007FD4
-:101A1000000000082CD90000000000082D00000084
-:101A2000000000082D80000C0000000000000000F5
-:101A30000000001091DE00000000001005C200044C
-:101A4000000000080F8000070000000033000000C5
-:101A500000000010009F0000000000188000FE86BB
-:101A6000000000002A0000000000000F0F500007D7
-:101A700000000010B1C6002D0000000F4742000812
-:101A800000000009070E000F00000008070E000804
-:101A900000000010001F0000000000080900000105
-:101AA0000000000709121C0000000003CBCA9200CE
-:101AB000000000000B97A2000000000742171C0066
-:101AC000000000000B0400000000000F0A84000367
-:101AD000000000000A959C00000000004A009A00E7
-:101AE0000000000882120001000000010C1708002D
-:101AF000000000000C978C0000000000021800009D
-:101B0000000000080D00FFFF000000080F80000625
-:101B10000000000C290000000000001006C20004B4
-:101B20000000000C295200020000001026420002B2
-:101B30000000000C295200030000000822000001F0
-:101B400000000010009F000000000010B197320C50
-:101B500000000000231B0000000000002711080007
-:101B600000000000669000000000000C29800000CA
-:101B700000000000021800000000001020530000C8
-:101B80000000000C295200030000000022C53600AE
-:101B900000000010001F0000000000080F80000679
-:101BA000000000188000FFF400000000231B00006C
-:101BB00000000000271108000000000066900000EF
-:101BC00000000010B1C8000B0000000C29800000CC
-:101BD00000000010205300000000000C29520000FB
-:101BE0000000000C295200030000001006C2000291
-:101BF0000000000C295200020000000022C58C00E9
-:101C000000000000276500000000000026E400003E
-:101C10000000000023480000000000082200001718
-:101C20000000000C2980000000000010001F0000D0
-:081C3000000000188000FE4BCB
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
diff --git a/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex b/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex
new file mode 100644
index 000000000000..435203d64305
--- /dev/null
+++ b/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex
@@ -0,0 +1,392 @@
+:1000000000000000000008F800000058000000098F
+:1000100000000000000000000000000000000000E0
+:1000200000000000000000000000000000000000D0
+:1000300000000E88000009500000000500000000CC
+:1000400000000000000000000000000000000000B0
+:080050000000000000000000A8
+:0800580000000010B180000659
+:100060000000001F05060011000000080500FFFF4A
+:10007000000000180002000000000008050000FF5A
+:10008000000000180002000000000008AC000001A1
+:1000900000000008078000000000000C2F80000115
+:1000A000000000002B000000000000002B8000007A
+:1000B0000000001091E1000200000008AC00000107
+:1000C00000000010203F003B00000010213F000313
+:1000D0000000001020BF0015000000188000FFFD88
+:1000E0000000000C1F800002000000188000FFF9D3
+:1000F00000000008B1000001000000082C80010C85
+:10010000000000082D000008000000082D800001FC
+:10011000000000188000003C0000000B2FDF0002F0
+:100120000000000C1F800002000000002C070000EF
+:100130000000001091DE0000000000188000FFEFBA
+:100140000000000B2FDF00020000000C1F800000E9
+:10015000000000002C0700000000001091DE0000ED
+:10016000000000188000FFEA0000000C1F80000261
+:10017000000000188000FFE80000000802240025AD
+:1001800000000018000400000000001880000000BB
+:10019000000000188000001B0000001880000042D2
+:1001A000000000188000000000000018800000001F
+:1001B000000000188000000000000018800000000F
+:1001C00000000018800000000000001880000000FF
+:1001D00000000018800000000000001880000000EF
+:1001E00000000018800000000000001880000000DF
+:1001F000000000188000008E000000188000000041
+:1002000000000018800000000000001880000000BE
+:1002100000000018800000000000001880000000AE
+:10022000000000188000000000000018800000009E
+:10023000000000188000008D00000018800000B74A
+:10024000000000188000008400000018800000DA20
+:10025000000000188000002B000000188000000043
+:10026000000000188000006B0000001091D4000016
+:100270000000000C298000010000000C1F8000011C
+:10028000000000082A0000020000000807800000AB
+:10029000000000188000FFC4000000080380010077
+:1002A00000000010B73C0E000000001880000000A5
+:1002B000000000180002000000000000068200009C
+:1002C00000000010B18F000400000010B18F140373
+:1002D000000000082A0000010000001091D4000076
+:1002E000000000000780140000000018000D00004E
+:1002F00000000000050200000000001091DE000078
+:1003000000000018000A0000000000000682000043
+:100310000000001091DE0000000000090561FFFFF1
+:1003200000000010918A00020000000830E1FFFF89
+:10033000000000188000FFA9000000010561140002
+:1003400000000010918A000200000008B0E10001E6
+:1003500000000018000D00000000000006820000F0
+:100360000000001091DE0000000000090562FFFFA0
+:1003700000000010918A0002000000083162FFFFB7
+:10038000000000188000FF9F0000000105621400BB
+:1003900000000010918A000200000008B162000114
+:1003A00000000018000D000000000010B1A0B01304
+:1003B0000000000B2FDF0002000000002C200000D6
+:1003C000000000082C800000000000082D00000044
+:1003D0000000001091D40000000000080500005546
+:1003E000000000188000FFDB000000082D80011CC9
+:1003F00000000010001F0000000000188000FFE255
+:100400000000000F476000080000000F060E00010A
+:10041000000000000F580000000000000A64000007
+:10042000000000000AE50000000000090B66FFFF65
+:10043000000000000D6100000000001880000015A1
+:100440000000000F476000080000000B2FDF0002D3
+:10045000000000082C800000000000082D000000B3
+:100460000000001091D40000000000082D80011C45
+:100470000000000F060E000100000010001F000029
+:10048000000000000F580000000000188000FFD09E
+:10049000000000000A640000000000000AE50000FF
+:1004A000000000090B66FFFF000000000D61000066
+:1004B00000000000026200000000000002E00000F6
+:1004C0000000000B2FDF00020000000030050000DC
+:1004D000000000003104000000000000309A00001D
+:1004E000000000100060000A00000008051600016E
+:1004F00000000010BA9A140300000000030000007E
+:100500000000001880000006000000188000FF6C4A
+:1005100000000010B60614040000000803060001E5
+:10052000000000082A000001000000188000FF7190
+:10053000000000000C961800000000090C99FFFF55
+:1005400000000004CC99340000000010BA992C027D
+:10055000000000080F8000000000000C298000014E
+:100560000000000C295200010000000C295200007C
+:100570000000000822800002000000080200000EB7
+:10058000000000080280001A00000010B1C40A0236
+:1005900000000008020000030000000C1F800001A2
+:1005A000000000002ADF0000000000002A00080010
+:1005B000000000188000FF600000000B2FDF000229
+:1005C0000000001091D40000000000082A00000183
+:1005D000000000002C2000000000001091D400005A
+:1005E000000000082C800000000000082D00000022
+:1005F000000000082D80011C000000188000FF9FF3
+:10060000000000082C800006000000082D000006F5
+:1006100000000000308000000000000031000000F9
+:10062000000000082D8000060000000C2980000159
+:100630000000000C1F8000010000001091DE00008F
+:10064000000000002ADF0000000000082A0000105F
+:100650000000000807800000000000188000FF4B29
+:100660000000001091D4000000000008050000AA5E
+:10067000000000188000FF890000000C29800001A4
+:100680000000000C1F800001000000082A00000983
+:10069000000000188000FF440000001091D400000A
+:1006A0000000000805000055000000188000FF82CF
+:1006B0000000001091A0B00200000010B1E6620737
+:1006C0000000000B2FDF0002000000002C310000B2
+:1006D000000000092CB1007F000000082CD90000A8
+:1006E000000000082D000000000000082D80010D12
+:1006F00000000010B1A8000600000010205F0000FC
+:10070000000000002C200000000000002CA70000CA
+:10071000000000082D000010000000082D800108D6
+:10072000000000188000FF7A00000010B1A6001041
+:1007300000000010001F00000000000F0F30000735
+:10074000000000000A600000000000000AE1000054
+:100750000000000F4B620008000000090B1600FFAC
+:10076000000000000D620000000000090D1A00FFEB
+:1007700000000010073000030000000C0D1A0008F4
+:100780000000000C0B1600080000000F4CE30018DE
+:10079000000000000C992C0000000004CC993400EB
+:1007A000000000080F8000000000000C29800001FC
+:1007B0000000000033310000000000082200001695
+:1007C000000000002ADF0000000000082A00000CE2
+:1007D00000000010009F0000000000002C2000001E
+:1007E0000000000C1F800001000000188000FF19AD
+:1007F0000000001091D4000000000008050000AACD
+:10080000000000188000FF570000000F472200087A
+:1008100000000009070E000F00000008070E000886
+:1008200000000008028000010000000702851C0093
+:1008300000000008828500010000000002854C00D5
+:100840000000000742851C0000000003C3AA5200FC
+:100850000000000003B10E00000000074B071C0061
+:100860000000000F0F3000070000000F0A96000381
+:10087000000000000A955C00000000004A005A00D9
+:10088000000000000C960A00000000090C99FFFF10
+:10089000000000080D00FFFF00000010BA992C02B4
+:1008A000000000080F80000500000010B1A800083B
+:1008B00000000010205F00000000000B2FDF00028E
+:1008C000000000002C200000000000002CA7000009
+:1008D000000000082D000010000000082D80010815
+:1008E000000000188000FF420000000C2980000179
+:1008F00000000010001F00000000000C1F8000011D
+:10090000000000002ADF0000000000082A00000D9F
+:10091000000000188000FEF40000001091D40000D8
+:100920000000000805000055000000188000FF329C
+:100930000000000C298000010000000C1F80000155
+:10094000000000082A000007000000188000FEEDEB
+:1009500000000010B18000040000001F0506001117
+:1009600000000008050000FF000000180002000061
+:10097000000000002A00000000000010B1D40000B8
+:100980000000001091DE0000000000102053000065
+:1009900000000010001F0000000000002F80AA00CF
+:1009A0000000000C29800001000000080254000F24
+:1009B000000000002C400000000000000F4000007C
+:1009C000000000092952003F000000180004000048
+:1009D00000000018800000110000001880000012C4
+:1009E000000000188000003800000018800001118D
+:1009F0000000001880000110000000188000010FA6
+:100A0000000000188000010F0000001880000000A6
+:100A10000000001880000128000000188000010B71
+:100A20000000001880000000000000188000012C69
+:100A3000000000188000017A000000188000005AB1
+:100A400000000018800000C400000018800000C5ED
+:100A50000000001880000104000000002A000000CF
+:100A6000000000188000FFE3000000002A000000E2
+:100A70000000000C29800000000000188000FFE04A
+:100A80000000001800020000000000000502000045
+:100A900000000010B99A2C2100000010205F000017
+:100AA000000000002C1E0000000000082C80000642
+:100AB000000000082D000006000000082D80010243
+:100AC00000000000000000000000001091DE0000A7
+:100AD000000000000D61000000000018000A000086
+:100AE000000000000502000000000010B99A2C165A
+:100AF00000000010205F00000000000009D8000086
+:100B0000000000002C1E0000000000082C80010ED8
+:100B1000000000082D00000A000000082D800102DE
+:100B200000000000000000000000001091DE000046
+:100B3000000000000D620000000000002C13000007
+:100B400000000018000A000000000000050200007C
+:100B500000000010B99A2C0900000010205F00006E
+:100B6000000000002C1E0000000000082C80000681
+:100B7000000000082D00006A000000082D8001021E
+:100B800000000000000000000000001091DE0000E6
+:100B9000000000000D7A000000000018000A0000AC
+:100BA000000000002A0000000000000822000001F0
+:100BB000000000000D6100000000001021C20024B0
+:100BC00000000010B1C6000200000010234200A285
+:100BD000000000090B66FFFF00000010BA9A2C20ED
+:100BE000000000000A640000000000000AE50000A8
+:100BF000000000000C000000000000000B8000005E
+:100C0000000000080CC60012000000188000FFD091
+:100C1000000000080F80000300000000000000003A
+:100C200000000010009F00000000000827110012C3
+:100C3000000000006690000000000010B198000362
+:100C400000000010001F0000000000080F800004DA
+:100C50000000000822000003000000082C80000CA7
+:100C6000000000082D00000C00000010009F000094
+:100C70000000001091C6000500000010001F0000D9
+:100C800000000010BA9A2C03000000080F80000436
+:100C9000000000188000FFFD000000002596000005
+:100CA0000000000C29800000000000003214000049
+:100CB00000000000329500000000000573662C0063
+:100CC0000000000031E32E00000000082D8000101D
+:100CD000000000188000FF950000000023000000C5
+:100CE0000000000925E6FFFF000000082200000BBD
+:100CF0000000000C695200000000000C2980000078
+:100D0000000000188000FF8F000000002A00000093
+:100D1000000000082C800040000000082D0000208A
+:100D2000000000082D80011C0000000822000001C6
+:100D30000000001091DE00000000000F42EA0010E9
+:100D400000000010004F000400000010B7469200A1
+:100D5000000000080249001200000010B5840A00DB
+:100D6000000000000D61000000000010BA6634575A
+:100D7000000000088305001200000010004F000270
+:100D800000000000034900000000000183068C0001
+:100D90000000000083C60C0000000010B1870013A3
+:100DA000000000000B6E0000000000090569FFFF55
+:100DB00000000010918A00020000000834E9FFFFE3
+:100DC000000000188000FF74000000010569140095
+:100DD00000000010918A000200000008B4E9000140
+:100DE00000000010BAE92C480000000086692C00C1
+:100DF00000000000020000000000000902EAFFFFFE
+:100E000000000010000C00020000000002040A00B4
+:100E10000000000F460C00010000000F02850001D9
+:100E200000000010918C01FC00000010B7040E3F80
+:100E3000000000000D610000000000000A640000D6
+:100E4000000000000AE50000000000090B66FFFF3B
+:100E5000000000000C000000000000000B800000FB
+:100E6000000000080C860012000000080F8000033C
+:100E70000000000C2952000000000010009F00003C
+:100E8000000000082711001200000000669000001A
+:100E9000000000002306000000000010B1980005CB
+:100EA00000000010001F0000000000080F80000478
+:100EB000000000000000000000000010001F000003
+:100EC0000000000032140000000000003295000015
+:100ED0000000000031E32E000000000573662C00C6
+:100EE000000000002596000000000010B1870016E9
+:100EF0000000000C298000000000000F0F6B0007AD
+:100F0000000000000D690000000000000A6C0000F5
+:100F1000000000000AED0000000000000B6E000061
+:100F2000000000000B800000000000000C870000A3
+:100F3000000000080F800003000000102053000094
+:100F40000000000C6952000100000010001F0000AA
+:100F50000000000022C58C0000000000231B0000E0
+:100F60000000000027110000000000002690000093
+:100F700000000010B8170E030000000C29800000CC
+:100F8000000000188000FFF600000010B198000279
+:100F9000000000080F800004000000082200001A72
+:100FA000000000082C80000C000000082D00000C40
+:100FB000000000082D80001000000010001F00003D
+:100FC000000000000D6E000000000003E7CF3400B9
+:100FD0000000000C298000000000001091DE0000DD
+:100FE00000000010B1870007000000003614000068
+:100FF00000000000369500000000000037160000D9
+:10100000000000082C800050000000082D00003077
+:10101000000000082D80000C000000188000FF2C4C
+:1010200000000000230000000000000925E6FFFF8B
+:10103000000000000B6E000000000003E7CF2C0052
+:10104000000000082200001B0000000C6952000094
+:101050000000000C29800000000000188000FF2420
+:10106000000000002A000000000000188000FF229D
+:10107000000000002A0000000000000C2980000091
+:101080000000001091DE0000000000082C80001A13
+:10109000000000082D00001A000000057366000023
+:1010A000000000082D8000020000000031800000D8
+:1010B0000000001091DE0000000000082C80000CF1
+:1010C000000000082D00000C000000082D80000426
+:1010D000000000188000FF150000000806660001EF
+:1010E00000000010BA9A197F000000000A64000096
+:1010F000000000000AE50000000000090B66FFFF89
+:10110000000000000C000000000000000B80000048
+:10111000000000080CC60012000000188000FF2E1E
+:10112000000000080F800003000000000000000025
+:1011300000000010009F00000000000827110012AE
+:10114000000000006690000000000010919B32003B
+:10115000000000100293000000000010B19800038E
+:1011600000000010001F0000000000080F800004B5
+:101170000000000C2980000000000010001F00008B
+:1011800000000010BA9A2C000000000031E32E008D
+:10119000000000000B800000000000008CCC8C00E0
+:1011A00000000010B5CC8C02000000080C8000018B
+:1011B000000000188000FF1B000000080F800003E3
+:1011C00000000010205300000000000C69520001D4
+:1011D0000000000022C58C0000000010009F0000ED
+:1011E0000000000027110000000000002690000011
+:1011F00000000000231B000000000010B198000355
+:1012000000000010001F0000000000080F80000414
+:101210000000000822000003000000082C80000CE1
+:10122000000000082D00000C00000010009F0000CE
+:1012300000000000259600000000000C298000003E
+:101240000000000032140000000000003295000091
+:101250000000000573662C000000000031E32E0042
+:10126000000000082D800010000000188000FEE241
+:10127000000000188000FEE1000000002A000000CD
+:1012800000000010001F0000000000000F008000A0
+:10129000000000080F800007000000188000001BFD
+:1012A00000000000280A0000000000000502000005
+:1012B00000000008220000090000000029000000D2
+:1012C0000000000F6568001000000000248A000084
+:1012D00000000003F66C940000000010B972A00436
+:1012E0000000000C73E700190000000C214200040C
+:1012F000000000003CF800000000000C2980000005
+:101300000000001020530000000000082200000828
+:101310000000000C6142000400000018000A0000F8
+:1013200000000000050200000000000C6142000007
+:1013300000000010014200030000000C33E7001D14
+:101340000000000C6142000200000018000A0000CA
+:10135000000000002A00000000000010001F000034
+:101360000000000F0F470007000000080F80000872
+:101370000000000C2980000000000010009F000009
+:10138000000000188000FEBF000000003351000084
+:10139000000000002A00000000000010B1C6002379
+:1013A0000000000F0F500007000000000A6000005E
+:1013B000000000000AE100000000000F4B6200087E
+:1013C000000000090B1600FF0000000F4C62001027
+:1013D000000000000D620000000000090D1A00FF6F
+:1013E00000000010075000030000000C0D1A000858
+:1013F0000000000C0B160008000000000CC60000E6
+:10140000000000000B8000000000000006980000B3
+:10141000000000080F8000030000001006C2000456
+:101420000000000C2900000200000010264200020B
+:101430000000000C295200030000000822000001F7
+:1014400000000010009F000000000000231B0000AF
+:101450000000000027111A00000000006690000044
+:101460000000000C2952000000000010B197320962
+:101470000000000C29800000000000000698000019
+:1014800000000010205300000000000C295200034F
+:101490000000000022C58C0000000010001F0000AA
+:1014A000000000080F800003000000188000FFF318
+:1014B00000000010B1C8001300000010B1C6000306
+:1014C0000000000C298000000000001020530000E4
+:1014D0000000000C295200000000000C29520003FB
+:1014E0000000001006C200020000000C2952000299
+:1014F0000000000022C58C000000000027650000ED
+:101500000000000026E40000000000082200001691
+:1015100000000010B1C600030000000023480000D6
+:1015200000000010B180000500000000234800000A
+:101530000000000C298000000000000F0F50000781
+:1015400000000018800000120000000822000016B1
+:101550000000000C29800000000000003014000092
+:10156000000000003095000000000010075000034C
+:10157000000000090B1600FF000000090D1A00FF13
+:101580000000000F31160008000000003162340036
+:1015900000000003F162300000000010205F000036
+:1015A000000000002C510000000000092CD1007F39
+:1015B000000000082CD90000000000082D000000E9
+:1015C000000000082D80000C00000000000000005A
+:1015D0000000001091DE00000000001005C20004B1
+:1015E000000000080F80000700000000330000002A
+:1015F00000000010009F0000000000188000FE7036
+:10160000000000002A0000000000000F0F5000073B
+:1016100000000010B1C6002D0000000F4742000876
+:1016200000000009070E000F00000008070E000868
+:1016300000000010001F0000000000080900000169
+:101640000000000709121C0000000003CBCA920032
+:10165000000000000B97A2000000000742171C00CA
+:10166000000000000B0400000000000F0A840003CB
+:10167000000000000A959C00000000004A009A004B
+:101680000000000882120001000000010C17080091
+:10169000000000000C978C00000000000218000001
+:1016A000000000080D00FFFF000000080F8000068A
+:1016B0000000000C290000000000001006C2000419
+:1016C0000000000C29520002000000102642000217
+:1016D0000000000C29520003000000082200000155
+:1016E00000000010009F000000000010B197320CB5
+:1016F00000000000231B000000000000271108006C
+:1017000000000000669000000000000C298000002E
+:10171000000000000218000000000010205300002C
+:101720000000000C295200030000000022C5360012
+:1017300000000010001F0000000000080F800006DD
+:10174000000000188000FFF400000000231B0000D0
+:101750000000000027110800000000006690000053
+:1017600000000010B1C8000B0000000C2980000030
+:1017700000000010205300000000000C295200005F
+:101780000000000C295200030000001006C20002F5
+:101790000000000C295200020000000022C58C004D
+:1017A00000000000276500000000000026E40000A3
+:1017B000000000002348000000000008220000177D
+:1017C0000000000C2980000000000010001F000035
+:0817D000000000188000FE3546
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex b/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex
deleted file mode 100644
index f325e6904edb..000000000000
--- a/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex
+++ /dev/null
@@ -1,499 +0,0 @@
-:100000000000000000000E80000000580000000901
-:1000100000000000000000000000000000000000E0
-:1000200000000000000000000000000000000000D0
-:1000300000000FA800000ED800000005000000001E
-:1000400000000000000000000000000000000000B0
-:080050000000000000000000A8
-:0800580000000010B180000659
-:100060000000001F03030300000000080500FFFF5D
-:10007000000000180002000000000008050000FF5A
-:10008000000000180002000000000008AC000001A1
-:1000900000000000050000000000000C2F8000019F
-:1000A000000000002B000000000000002B8000007A
-:1000B0000000001091E0000200000008AC00000108
-:1000C00000000010203F006B00000010213F0003E3
-:1000D0000000001020BF003A000000188000FFFD63
-:1000E00000000010B1B8B0150000000B2FDF0002B7
-:1000F0000000000003D80000000000002C380000C1
-:10010000000000082C800000000000082D00000006
-:100110000000001091D400000000000806005555B2
-:10012000000000188000008F000000082D80011CD6
-:1001300000000008020000010000001091DE000035
-:100140000000000F42E0001C0000001091840A161D
-:1001500000000018800000960000000C29800002BA
-:100160000000000C1F800002000000002ADF0000D9
-:10017000000000082A00000F000000000500000039
-:10018000000000188000FFE60000000802000001E7
-:100190000000000F42E0001C0000001091840A18CB
-:1001A000000000082C800006000000082D0000065A
-:1001B0000000001091D40000000000082D8001060E
-:1001C0000000001880000085000000188000FFF18A
-:1001D00000000008B1000001000000082C80010CA4
-:1001E000000000082D000008000000082D8000011C
-:1001F000000000188000007F0000000B2FDF0002CD
-:100200000000000C1F800002000000002C0700000E
-:100210000000001091DE00000000000805005555A8
-:10022000000000188000FFD20000000B2FDF00024A
-:100230000000000C1F800000000000002C070000E0
-:100240000000001091DE0000000000080500555578
-:10025000000000188000FFCC0000000C1F8000028E
-:100260000000000805005555000000188000FFC977
-:100270000000000C298000020000000C1F8000021A
-:10028000000000002ADF0000000000082A0000052E
-:100290000000000805005555000000188000FFC34D
-:1002A000000000080224004A0000001800040000BA
-:1002B000000000188000001C000000188000001ED4
-:1002C000000000188000007800000018800000CBBB
-:1002D00000000018800000CA000000188000000024
-:1002E00000000018800000000000001880000000DE
-:1002F00000000018800000000000001880000000CE
-:1003000000000018800000000000001880000000BD
-:100310000000001880000000000000188000011696
-:10032000000000188000000000000018800000009D
-:100330000000001880000015000000188000001B5D
-:10034000000000188000000000000018800000E19C
-:10035000000000188000002F000000188000011627
-:100360000000001880000141000000188000010C0E
-:100370000000001880000165000000188000006186
-:100380000000001880000000000000188000009E9F
-:100390000000000C1F8000010000000005000000AC
-:1003A000000000188000FFA20000001091D400009F
-:1003B0000000000C298000010000000C1F800001DB
-:1003C000000000082A0000020000000005000000F4
-:1003D000000000188000FF9C0000001091D4000075
-:1003E0000000000C298000010000000C1F800001AB
-:1003F0000000000029420000000000082A0000025E
-:100400000000000005000000000000188000FF95BB
-:10041000000000188000FF9400000010B1BCB00A7A
-:100420000000000B2FDF00020000000003D80000D6
-:10043000000000002C3C00000000001091D40000DF
-:100440000000000806005555000000188000002A32
-:1004500000000018800000DA000000102C6201BAD1
-:100460000000001880000006000000082C80010D2C
-:10047000000000082D0000090000001091D40000C9
-:10048000000000082D8001070000001880000037E0
-:100490000000000C298000000000000C1F800000FC
-:1004A0000000001091DE0000000000002ADF0000C4
-:1004B000000000082A00000600000008050055554D
-:1004C000000000188000FF7E0000001091D40000A2
-:1004D0000000000C298000010000000C1F800001BA
-:1004E000000000082A00000B0000000005000000CA
-:1004F000000000188000FF780000000002020000E9
-:1005000000000000029A000000000000060C2C0011
-:1005100000000004C60C340000000010001F0000A2
-:1005200000000010B196180C0000000806960004A8
-:1005300000000009068DFFFC00000004CD051A0034
-:1005400000000004CC9A18000000001020D7000022
-:100550000000000C2B56000000000000000000000E
-:1005600000000000000000000000001020D7000084
-:10057000000000080F80000100000010B18001F4AD
-:1005800000000010001F00000000000C6B5600006F
-:1005900000000018000400000000000006820000B7
-:1005A00000000010B18A000800000010B18C140790
-:1005B0000000000B050AFFFF00000010B18A0003D5
-:1005C00000000000860A180000000010918C000056
-:1005D000000000082A0000010000001091D4000073
-:1005E00000000018000D00000000000005020000DF
-:1005F0000000001091DE000000000018000A00005A
-:1006000000000000068200000000001091DE0000E3
-:1006100000000010BEE10005000000188000FF4C43
-:10062000000000010561140000000010918A000222
-:1006300000000008B0E1000100000018000D0000FB
-:1006400000000000068200000000001091DE0000A3
-:1006500000000010BEE20005000000188000FF440A
-:10066000000000010562140000000010918A0002E1
-:1006700000000008B162000100000018000D000039
-:1006800000000010B1A0B0130000000B2FDF00022B
-:10069000000000002C200000000000082C8000005A
-:1006A000000000082D0000000000001091D40000A0
-:1006B0000000000806005555000000188000FFDC0F
-:1006C000000000082D80011C00000010001F000029
-:1006D000000000188000FFE60000000F47600008DF
-:1006E0000000000F060E0001000000000F5800007F
-:1006F000000000000A640000000000000AE500009D
-:10070000000000090B66FFFF000000000D61000003
-:1007100000000018800000130000000F4760000870
-:100720000000000B2FDF0002000000082C800000FA
-:10073000000000082D0000000000001091D400000F
-:10074000000000082D80011C0000000F060E0001B3
-:1007500000000010001F0000000000000F58000003
-:10076000000000188000FFD4000000000A640000B0
-:10077000000000000AE50000000000090B66FFFF12
-:10078000000000000D610000000000000262000097
-:100790000000000B2FDF0002000000003104000009
-:1007A00000000000309A0000000000090560000F02
-:1007B00000000010B18A000B0000000005634C002F
-:1007C00000000008050A001200000010B9621403BE
-:1007D0000000000003000000000000188000000678
-:1007E000000000188000FF1100000010B60614047D
-:1007F0000000000803060001000000082A000001B4
-:10080000000000188000FF16000000188000FF9E06
-:100810000000000C298000010000000C295200019A
-:100820000000000C29520000000000080200000E29
-:10083000000000080280001A00000010B1C40A0283
-:100840000000000802000003000000082200000170
-:100850000000000C1F800001000000002ADF0000E3
-:10086000000000002A00080000000008050055559F
-:10087000000000188000FF080000000B2FDF0002BE
-:100880000000001091D40000000000082A000001C0
-:10089000000000002C2000000000001091D4000097
-:1008A000000000082C800000000000082D0000005F
-:1008B000000000082D80011C000000188000FFA629
-:1008C000000000082C800006000000082D00000633
-:1008D0000000000030800000000000003100000037
-:1008E000000000082D8000060000000C2980000197
-:1008F0000000000C1F8000010000001091DE0000CD
-:10090000000000002ADF0000000000082A0000109C
-:100910000000000005000000000000188000FEF349
-:100920000000001091A0B009000000082C80010D0B
-:10093000000000082D0000090000001091D4000004
-:10094000000000082D800107000000188000FF9FB4
-:10095000000000188000001000000008AC0000013A
-:10096000000000188000000B000000000380B000B1
-:100970000000000B2FDF0002000000002C004000F0
-:100980000000001091D4000000000008060055553A
-:10099000000000188000FF81000000188000003176
-:1009A00000000018800000060000000B2FDF00028E
-:1009B000000000002C000E00000000082A000007C4
-:1009C0000000000805005555000000188000FEDDFD
-:1009D00000000000068200000000000C29800001D9
-:1009E0000000000C1F800001000000100CE7000751
-:1009F000000000090562FFFF00000010BA6C14053A
-:100A0000000000002ADF00000000000021000000BC
-:100A1000000000082A0000050000001091D400002A
-:100A2000000000082C80010C000000082D000008C8
-:100A30000000000C31620018000000082D80000149
-:100A4000000000188000FF7500000018000D000075
-:100A500000000010B1A0B00E0000000B2FDF00025C
-:100A60000000000003D80000000000002C2000005F
-:100A70000000001091D40000000000188000001554
-:100A8000000000102C620002000000188000000C22
-:100A90000000000B2FDF0002000000002C07000008
-:100AA0000000000C1F8000010000001091DE00001B
-:100AB000000000080500FFFF000000188000FEBFD6
-:100AC000000000082C80010D000000082D00000926
-:100AD0000000001091D40000000000082D800107E4
-:100AE000000000188000FF6C0000000C298000014D
-:100AF0000000000C1F8000010000001091DE0000CB
-:100B0000000000002ADF0000000000082A00000AA0
-:100B10000000000005000000000000188000FEB387
-:100B20000000000006820000000000082C80010C7C
-:100B3000000000082D000008000000082D8001348E
-:100B4000000000000000000000000010205F000016
-:100B5000000000082C800140000000082D00003C2F
-:100B6000000000082D80011C0000000000000000B3
-:100B70000000001091DE0000000000082C800080C2
-:100B8000000000082D000000000000082D80010575
-:100B900000000010BEE20005000000188000FE9C6E
-:100BA000000000010562140000000010918A00029C
-:100BB00000000008B16200010000001091DE00009A
-:100BC00000000018000D00000000001091D400008B
-:100BD000000000080600AAAA000000188000FF38E4
-:100BE0000000000C298000010000000C1F800001A3
-:100BF000000000082A000009000000080500AAAA59
-:100C0000000000188000FE960000001091D4000043
-:100C10000000000806005555000000188000FF3055
-:100C20000000001091A03C0200000010B1E6620735
-:100C30000000000B2FDF0002000000002C3100003C
-:100C4000000000092CB1007F000000082CD9000032
-:100C5000000000082D000000000000082D80010D9C
-:100C600000000010B1A8000600000010205F000086
-:100C7000000000002C200000000000002CA7000055
-:100C8000000000082D000010000000082D80010861
-:100C9000000000188000FF2B00000010B1A600101B
-:100CA00000000010001F00000000000F0F300007C0
-:100CB000000000000A600000000000000AE10000DF
-:100CC0000000000F4B620008000000090B1600FF37
-:100CD000000000000D620000000000090D1A00FF76
-:100CE00000000010073000030000000C0D1A00087F
-:100CF0000000000C0B1600080000000F4CE3001869
-:100D0000000000000C992C0000000004CC99340075
-:100D1000000000080F8000000000000C2980000186
-:100D2000000000003331000000000008220000161F
-:100D3000000000002ADF0000000000082A00000C6C
-:100D400000000010009F0000000000000F200000C5
-:100D50000000000C1F800001000000080500555530
-:100D6000000000188000FE6A0000001091D400000E
-:100D7000000000080600AAAA000000188000FF0476
-:100D80000000000F4722000800000009070E000FB6
-:100D900000000008070E00080000000802800001A3
-:100DA0000000000702851C00000000088285000189
-:100DB0000000000002854C000000000742851C0076
-:100DC00000000003C3AA52000000000003B10E009F
-:100DD000000000074B071C000000000F0F30000749
-:100DE0000000000F0A960003000000000A955C0056
-:100DF000000000004A005A00000000000C960A00A3
-:100E0000000000090C99FFFF000000080D00FFFF23
-:100E100000000010B1963202000000080F800005AB
-:100E200000000010B1A8000800000010205F0000C2
-:100E30000000000B2FDF0002000000002C2000004B
-:100E4000000000002CA70000000000082D0000108A
-:100E5000000000082D800108000000188000FEF24C
-:100E60000000000C2980000100000010001F00009D
-:100E70000000000C1F800001000000002ADF0000BD
-:100E8000000000082A00000D000000080500AAAAC2
-:100E9000000000188000FE440000001091D4000003
-:100EA0000000000806005555000000188000FEDE16
-:100EB0000000000C298000010000000C1F800001D0
-:100EC000000000082A000007000000080500555532
-:080ED000000000188000FE3C48
-:080ED80000000010B1800004CD
-:100EE0000000001F0303030000000008050000FFCE
-:100EF0000000001800020000000000002A000000AE
-:100F000000000010B1D400000000001091DE0000CD
-:100F1000000000102053000000000010001F00001F
-:100F20000000000C6BD70001000000002F80AA0019
-:100F30000000000C29800001000000080254000F8E
-:100F4000000000002C400000000000092952003F72
-:100F500000000018000400000000001880000010CD
-:100F60000000001880000011000000188000004AF6
-:100F700000000018800001280000001880000127F0
-:100F800000000018800001260000001880000126E3
-:100F90000000001880000000000000188000013FE1
-:100FA0000000001880000122000000188000000BE3
-:100FB0000000001880000145000000188000019A20
-:100FC000000000188000007B00000018800000F97D
-:100FD0000000001880000109000000002A00000045
-:100FE000000000188000FFE4000000002A0000005C
-:100FF0000000000C29800000000000188000FFE1C4
-:10100000000000002A000000000000188000FFDF40
-:101010000000000003820000000000188000FFDADA
-:10102000000000010C161400000000008C181400D1
-:101030000000001091980003000000080C960002C8
-:1010400000000010B1800003000000080C960001B1
-:10105000000000000C000000000000000D1900005E
-:1010600000000010205600000000000C2BD70001EB
-:10107000000000080F8000010000000000000000D8
-:1010800000000010001F00000000000C6BD70001E2
-:1010900000000010011301F100000018000700001B
-:1010A00000000000050200000000001091963421AD
-:1010B00000000010205F0000000000002C1E000057
-:1010C000000000082C800006000000082D0000062B
-:1010D000000000082D800102000000000000000058
-:1010E0000000001091DE0000000000000D61000013
-:1010F00000000018000A00000000000005020000C7
-:10110000000000109196341600000010205F0000CF
-:101110000000000009D80000000000002C1E0000A4
-:10112000000000082C80010E000000082D00000ABD
-:10113000000000082D8001020000000000000000F7
-:101140000000001091DE0000000000000D620000B1
-:10115000000000002C13000000000018000A00002E
-:101160000000000005020000000000109196340904
-:1011700000000010205F0000000000002C1E000096
-:10118000000000082C800006000000082D00006A06
-:10119000000000082D800102000000000000000097
-:1011A0000000001091DE0000000000000D7A000039
-:1011B00000000018000A0000000000002A000000E3
-:1011C000000000000D61000000000000036200004C
-:1011D00000000010234200DB0000000002638C00CE
-:1011E0000000000026460000000000080204001273
-:1011F00000000010B906082E000000000F58000083
-:10120000000000000A640000000000000AE5000081
-:10121000000000090B66FFFF000000000C0000004A
-:10122000000000000B800000000000080CC6001247
-:10123000000000188000FFCE0000001020560000C3
-:101240000000000C2BD70001000000080F800003F5
-:10125000000000000000000000000010001F00005F
-:101260000000000C6BD700010000000827110012DD
-:10127000000000006690000000000008A31B0012A0
-:1012800000000010B198000600000010001F0000D0
-:101290000000000C6BD70001000000102056000079
-:1012A0000000000C2BD70001000000080F80000494
-:1012B0000000000822000003000000082C80000C41
-:1012C000000000082D00000C00000010001F0000AE
-:1012D0000000000C6BD70001000000002596000004
-:1012E0000000000C298000000000000006660000DD
-:1012F0000000000086611800000000090260000F75
-:101300000000000F0204000200000010B60C0805E7
-:101310000000000C1FBF0000000000102866000342
-:1013200000000008078F00010000000C3366001069
-:1013300000000000321400000000000032950000A0
-:101340000000000573662C000000000031E32E0051
-:10135000000000082D800010000000188000FF75BC
-:1013600000000000230000000000000925E6FFFF48
-:10137000000000082200000B0000000C6952000071
-:101380000000000C29800000000000102866008882
-:10139000000000188000FF6E000000002A0000001E
-:1013A000000000082C800040000000082D000020F4
-:1013B000000000082D80011C00000000000000005B
-:1013C0000000001091DE00000000000F42EA001053
-:1013D00000000010004F000400000010B74692000B
-:1013E000000000080249001200000010B5840A0045
-:1013F000000000000D61000000000010BA66346AB1
-:10140000000000088305001200000010004F0002D9
-:1014100000000000034900000000000183068C006A
-:101420000000000083C60C0000000010B18700110E
-:10143000000000000B6E000000000010BEE9000577
-:10144000000000188000FF5500000001056914002D
-:1014500000000010918A000200000008B4E90001B9
-:1014600000000010B1E92C5D0000000086692C002E
-:1014700000000000020000000000000902EAFFFF77
-:1014800000000010000C00020000000002040A002E
-:101490000000000F460C00010000000F0285000153
-:1014A00000000010918C01FC00000010B7040E54E5
-:1014B000000000000F400000000000000D6100006F
-:1014C000000000000A640000000000000AE50000BF
-:1014D000000000090B66FFFF000000000C00000088
-:1014E000000000000B800000000000080C860012C5
-:1014F00000000010205600000000000C2BD7000157
-:10150000000000080F8000030000000C29520000BA
-:1015100000000010001F00000000000C6BD700014D
-:101520000000000827110012000000006690000073
-:101530000000000026460000000000002306000016
-:1015400000000010B198000900000010001F00000A
-:101550000000000C6BD700010000001020560000B6
-:101560000000000C2BD70001000000080F800004D1
-:10157000000000000000000000000010001F00003C
-:101580000000000C6BD700010000000032140000C6
-:1015900000000000329500000000000031E32E0042
-:1015A0000000000573662C00000000002596000076
-:1015B00000000010B18700210000000C298000000D
-:1015C0000000000F0F6B0007000000000D69000015
-:1015D000000000000A6C0000000000000AED00009E
-:1015E000000000000B6E0000000000000B800000F7
-:1015F000000000000C870000000000188000FF1EA3
-:10160000000000010C161400000000008C181400EB
-:10161000000000080C9600010000001091980002E4
-:10162000000000080C990001000000000D190000E6
-:10163000000000000C000000000000102056000018
-:101640000000000C2BD70001000000080F800001F3
-:1016500000000010205300000000000C695200013F
-:1016600000000010001F00000000000C6BD70001FC
-:101670000000000022C58C000000000023120000C2
-:10168000000000002711000000000000269000006C
-:1016900000000010B8170E030000000C29800000A5
-:1016A000000000188000FFEB0000000082970E0091
-:1016B00000000000A3120A00000000082200001A27
-:1016C000000000082C80000C000000082D00000C19
-:1016D000000000082D80001000000010001F000016
-:1016E0000000000C6BD70001000000000D6E000030
-:1016F00000000003E7CF34000000000C2980000048
-:101700000000001091DE000000000010B18700070B
-:1017100000000000361400000000000036950000B4
-:101720000000000037160000000000082C80005068
-:10173000000000082D000030000000082D80000C83
-:10174000000000188000FEF800000000264600009F
-:1017500000000000230000000000000925E6FFFF54
-:10176000000000000B6E000000000003E7CF2C001B
-:10177000000000082200001B0000000C695200005D
-:101780000000000C29800000000000188000FEEF1F
-:10179000000000002A00000000000010086600059C
-:1017A00000000000066600000000000086611800CE
-:1017B00000000009026000F000000010B60C0802F2
-:1017C000000000188000FEE8000000000682000013
-:1017D00000000010B18F000000000008878F00019A
-:1017E0000000000C73660010000000082C80001838
-:1017F000000000082D000018000000082D800002E5
-:101800000000000C5FBF00000000001091DE00002F
-:1018100000000018000D0000000000002A00000079
-:1018200000000010286601F5000000082C8000036D
-:10183000000000082D000003000000093060FFF0E8
-:10184000000000082D8000010000000C298000002D
-:101850000000001091DE0000000000082C80001A3B
-:10186000000000082D00001A00000005736600004B
-:10187000000000082D800002000000003180000000
-:101880000000001091DE0000000000082C80000C19
-:10189000000000082D00000C000000082D8000044E
-:1018A000000000188000FECC0000001800020000BC
-:1018B000000000188000FECA000000002A0000009E
-:1018C00000000010001F00000000000C6BD700019A
-:1018D000000000000F008000000000080F800007DB
-:1018E000000000188000001B00000000280A000013
-:1018F00000000000050200000000000822000009AE
-:1019000000000000290000000000000F65680010C2
-:1019100000000003F66C940000000010B972A004EF
-:101920000000000C73E700190000000C21420004C5
-:10193000000000003CF800000000000C29800000BE
-:1019400000000010205300000000000822000008E2
-:101950000000000C6142000400000018000A0000B2
-:1019600000000000050200000000000C61420000C1
-:1019700000000010014200030000000C33E7001DCE
-:101980000000000C6142000200000018000A000084
-:10199000000000002A00000000000010001F0000EE
-:1019A0000000000C6BD700010000000F0F4700077C
-:1019B000000000080F8000080000000C29800000D3
-:1019C00000000010001F00000000000C6BD7000199
-:1019D000000000188000FEA6000000003351000047
-:1019E000000000002A00000000000010B1C600291D
-:1019F0000000000F0F500007000000000A60000008
-:101A0000000000000AE100000000000F4B62000827
-:101A1000000000090B1600FF0000000F4C620010D0
-:101A2000000000000D620000000000090D1A00FF18
-:101A300000000010075000030000000C0D1A000801
-:101A40000000000C0B160008000000000CC600008F
-:101A5000000000000B80000000000000069800005D
-:101A600000000010205600000000000C2BD70001E1
-:101A7000000000080F8000030000001006C20004F0
-:101A80000000000C290000020000001026420002A5
-:101A90000000000C29520003000000082200000191
-:101AA00000000010001F00000000000C6BD70001B8
-:101AB00000000000231B00000000000027111A0096
-:101AC00000000000669000000000000C2952000099
-:101AD00000000010B197320C0000000C29800000BB
-:101AE00000000000069800000000001020530000D5
-:101AF0000000000C295200030000000022C58C00E9
-:101B000000000010001F00000000000C6BD7000157
-:101B100000000010205600000000000C2BD7000130
-:101B2000000000080F800003000000188000FFEF95
-:101B300000000010B1C8001300000010B1C600037F
-:101B40000000000C2980000000000010205300005D
-:101B50000000000C295200000000000C2952000374
-:101B60000000001006C200020000000C2952000212
-:101B70000000000022C58C00000000002765000066
-:101B80000000000026E4000000000008220000160B
-:101B900000000010B1C60003000000002348000050
-:101BA00000000010B1800005000000002348000084
-:101BB0000000000C298000000000000F0F500007FB
-:101BC000000000188000001200000008220000162B
-:101BD0000000000C2980000000000000301400000C
-:101BE00000000000309500000000001007500003C6
-:101BF000000000090B1600FF000000090D1A00FF8D
-:101C00000000000F311600080000000031623400AF
-:101C100000000003F162300000000010205F0000AF
-:101C2000000000002C510000000000092CD1007FB2
-:101C3000000000082CD90000000000082D00000062
-:101C4000000000082D80000C0000000000000000D3
-:101C50000000001091DE00000000001005C2000529
-:101C6000000000080F8000070000000033000000A3
-:101C700000000010001F00000000000C6BD70001E6
-:101C8000000000188000FE50000000002A00000044
-:101C90000000000F0F50000700000010B1C6003018
-:101CA0000000000F4742000800000009070E000F67
-:101CB00000000008070E000800000010001F0000D0
-:101CC0000000000C6BD700010000000809000001B3
-:101CD0000000000709121C0000000003CBCA92009C
-:101CE000000000000B97A2000000000742171C0034
-:101CF000000000000B0400000000000F0A84000335
-:101D0000000000000A959C00000000004A009A00B4
-:101D10000000000882120001000000010C170800FA
-:101D2000000000000C978C0000000000021800006A
-:101D3000000000080D00FFFF000000080F800006F3
-:101D40000000000C290000000000001006C2000482
-:101D50000000000C29520002000000102642000280
-:101D60000000000C295200030000000822000001BE
-:101D700000000010001F00000000000C6BD70001E5
-:101D800000000010B197320D00000000231B00007E
-:101D9000000000002711080000000000669000000D
-:101DA0000000000C29800000000000000218000064
-:101DB00000000010205300000000000C2952000316
-:101DC0000000000022C5360000000010001F0000C7
-:101DD0000000000C6BD70001000000080F80000617
-:101DE000000000188000FFF200000000231B00002C
-:101DF00000000000271108000000000066900000AD
-:101E000000000010B1C8000B0000000C2980000089
-:101E100000000010205300000000000C29520000B8
-:101E20000000000C295200030000001006C200024E
-:101E30000000000C295200020000000022C58C00A6
-:101E400000000000276500000000000026E40000FC
-:101E500000000000234800000000000822000017D6
-:101E60000000000C2980000000000010001F00008E
-:101E70000000000C6BD70001000000188000FE116C
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
diff --git a/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex b/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex
new file mode 100644
index 000000000000..d2f275788f16
--- /dev/null
+++ b/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex
@@ -0,0 +1,425 @@
+:100000000000000000000970000000580000000916
+:1000100000000000000000000000000000000000E0
+:1000200000000000000000000000000000000000D0
+:1000300000001010000009C80000000500000000CA
+:1000400000000000000000000000000000000000B0
+:080050000000000000000000A8
+:0800580000000010B180000659
+:100060000000001F03060011000000080500FFFF4C
+:10007000000000180002000000000008050000FF5A
+:10008000000000180002000000000008AC000001A1
+:1000900000000008078000000000000C2F80000115
+:1000A000000000002B000000000000002B8000007A
+:1000B0000000001091E1000200000008AC00000107
+:1000C00000000010203F003B00000010213F000313
+:1000D0000000001020BF0015000000188000FFFD88
+:1000E0000000000C1F800002000000188000FFF9D3
+:1000F00000000008B1000001000000082C80010C85
+:10010000000000082D000008000000082D800001FC
+:10011000000000188000004F0000000B2FDF0002DD
+:100120000000000C1F800002000000002C070000EF
+:100130000000001091DE0000000000188000FFEFBA
+:100140000000000B2FDF00020000000C1F800000E9
+:10015000000000002C0700000000001091DE0000ED
+:10016000000000188000FFEA0000000C1F80000261
+:10017000000000188000FFE80000000802240025AD
+:1001800000000018000400000000001880000000BB
+:10019000000000188000001B0000001880000055BF
+:1001A000000000188000000000000018800000001F
+:1001B000000000188000000000000018800000000F
+:1001C00000000018800000000000001880000000FF
+:1001D00000000018800000000000001880000000EF
+:1001E00000000018800000000000001880000000DF
+:1001F000000000188000009D000000188000000032
+:1002000000000018800000000000001880000000BE
+:1002100000000018800000000000001880000000AE
+:10022000000000188000000000000018800000009E
+:10023000000000188000009C00000018800000C62C
+:10024000000000188000009300000018800000E902
+:10025000000000188000003E000000188000000030
+:10026000000000188000007A0000001091D4000007
+:100270000000000C298000010000000C1F8000011C
+:10028000000000082A0000020000000807800000AB
+:10029000000000188000FFC4000000080380010077
+:1002A00000000010B73C0E000000001880000000A5
+:1002B000000000000202000000000000029A00009E
+:1002C00000000000060C2C0000000004C60C3400E6
+:1002D00000000010001F000000000010BA8C2C0C61
+:1002E000000000080696000400000009068DFFFCCF
+:1002F00000000004CD051A0000000004CC9A18008C
+:100300000000001020D700000000000C2B56000059
+:1003100000000000000000000000000000000000DD
+:100320000000001020D70000000000080F8000012E
+:1003300000000010B18001F400000010001F000058
+:100340000000000C6B5600000000001800040000C4
+:10035000000000000682000000000010B18F0004C1
+:1003600000000010B18F1403000000082A000001F3
+:100370000000001091D4000000000000078014006D
+:1003800000000018000D0000000000000502000041
+:100390000000001091DE000000000018000A0000BC
+:1003A00000000000068200000000001091DE000046
+:1003B000000000090561FFFF00000010918A0002A3
+:1003C0000000000830E1FFFF000000188000FF96E9
+:1003D000000000010561140000000010918A000275
+:1003E00000000008B0E1000100000018000D00004E
+:1003F00000000000068200000000001091DE0000F6
+:10040000000000090562FFFF00000010918A000251
+:10041000000000083162FFFF000000188000FF8C20
+:10042000000000010562140000000010918A000223
+:1004300000000008B162000100000018000D00007B
+:1004400000000010B1A0B0130000000B2FDF00026D
+:10045000000000002C200000000000082C8000009C
+:10046000000000082D0000000000001091D40000E2
+:100470000000000805000055000000188000FFDBA8
+:10048000000000082D80011C00000010001F00006B
+:10049000000000188000FFE20000000F4760000825
+:1004A0000000000F060E0001000000000F580000C1
+:1004B000000000000A640000000000000AE50000DF
+:1004C000000000090B66FFFF000000000D61000046
+:1004D00000000018800000150000000F47600008B1
+:1004E0000000000B2FDF0002000000082C8000003D
+:1004F000000000082D0000000000001091D4000052
+:10050000000000082D80011C0000000F060E0001F5
+:1005100000000010001F0000000000000F58000045
+:10052000000000188000FFD0000000000A640000F6
+:10053000000000000AE50000000000090B66FFFF54
+:10054000000000000D6100000000000002620000D9
+:100550000000000002E000000000000B2FDF00029E
+:100560000000000030050000000000003104000021
+:1005700000000000309A0000000000100060000A37
+:10058000000000080516000100000010BA9A1403CC
+:1005900000000000030000000000001880000006BA
+:1005A000000000188000FF5900000010B606140477
+:1005B0000000000803060001000000082A000001F6
+:1005C000000000188000FF5E000000188000FF9D02
+:1005D0000000000C298000010000000C29520001DD
+:1005E0000000000C295200000000000822800002D8
+:1005F000000000080200000E000000080280001A3F
+:1006000000000010B1C40A0200000008020000034C
+:100610000000000C1F800001000000002ADF000025
+:10062000000000002A000800000000188000FF51B0
+:100630000000000B2FDF00020000001091D400002A
+:10064000000000082A000001000000002C2000002B
+:100650000000001091D40000000000082C80000071
+:10066000000000082D000000000000082D80011C83
+:10067000000000188000FFA3000000082C80000686
+:10068000000000082D00000600000000308000007F
+:100690000000000031000000000000082D8000066E
+:1006A0000000000C298000010000000C1F800001E8
+:1006B0000000001091DE0000000000002ADF0000B2
+:1006C000000000082A000010000000080780000059
+:1006D000000000188000FF3C0000001091D40000D2
+:1006E00000000008050000AA000000188000FF8D2F
+:1006F0000000000C298000010000000C1F80000198
+:10070000000000082A000009000000188000FF35E2
+:100710000000001091D40000000000080500005502
+:10072000000000188000FF860000001091A0B002B9
+:1007300000000010B1E662070000000B2FDF00028E
+:10074000000000002C310000000000092CB1007FE7
+:10075000000000082CD90000000000082D00000057
+:10076000000000082D80010D00000010B1A8000657
+:1007700000000010205F0000000000002C2000009E
+:10078000000000002CA70000000000082D00001051
+:10079000000000082D800108000000188000FF7E86
+:1007A00000000010B1A6001000000010001F0000A3
+:1007B0000000000F0F300007000000000A6000007A
+:1007C000000000000AE100000000000F4B6200087A
+:1007D000000000090B1600FF000000000D62000081
+:1007E000000000090D1A00FF000000100730000390
+:1007F0000000000C0D1A00080000000C0B16000889
+:100800000000000F4CE30018000000000C992C00C1
+:1008100000000004CC993400000000080F800000A4
+:100820000000000C298000010000000033310000AE
+:100830000000000822000016000000002ADF00006F
+:10084000000000082A00000C00000010009F0000BB
+:10085000000000002C2000000000000C1F800001A0
+:10086000000000188000FF0A0000001091D4000072
+:1008700000000008050000AA000000188000FF5BCF
+:100880000000000F4722000800000009070E000FBB
+:1008900000000008070E00080000000802800001A8
+:1008A0000000000702851C0000000008828500018E
+:1008B0000000000002854C000000000742851C007B
+:1008C00000000003C3AA52000000000003B10E00A4
+:1008D000000000074B071C000000000F0F3000074E
+:1008E0000000000F0A960003000000000A955C005B
+:1008F000000000004A005A00000000000C960A00A8
+:10090000000000090C99FFFF000000080D00FFFF28
+:1009100000000010BA992C02000000080F800005AA
+:1009200000000010B1A8000800000010205F0000C7
+:100930000000000B2FDF0002000000002C20000050
+:10094000000000002CA70000000000082D0000108F
+:10095000000000082D800108000000188000FF46FC
+:100960000000000C2980000100000010001F0000A2
+:100970000000000C1F800001000000002ADF0000C2
+:10098000000000082A00000D000000188000FEE5AD
+:100990000000001091D40000000000080500005580
+:1009A000000000188000FF360000000C29800001C4
+:1009B0000000000C1F800001000000082A00000752
+:0809C000000000188000FEDEBB
+:0809C80000000010B1800004E2
+:1009D0000000001F0306001100000008050000FFD2
+:1009E0000000001800020000000000002A000000C3
+:1009F00000000010B1D400000000001091DE0000E3
+:100A0000000000102053000000000010001F000034
+:100A10000000000C6BD70001000000002F80AA002E
+:100A20000000000C298000010000000802540010A2
+:100A3000000000002C400000000000000F400000FB
+:100A4000000000092952003F0000001800040000C7
+:100A50000000001880000011000000188000001243
+:100A600000000018800000470000001880000137D7
+:100A700000000018800001360000001880000135D9
+:100A80000000001880000135000000188000000000
+:100A9000000000188000014F0000001880000131A4
+:100AA00000000018800000000000001880000155C0
+:100AB00000000018800001A6000000188000006DF2
+:100AC00000000018800000E400000018800000E52D
+:100AD000000000188000012A000000002A00000029
+:100AE000000000188000FFE2000000002A00000063
+:100AF0000000000C29800000000000188000FFDFCB
+:100B00000000000003820000000000188000FFDAEF
+:100B1000000000010C161400000000008C181400E6
+:100B20000000001091980003000000080C960002DD
+:100B300000000010B1800003000000080C960001C6
+:100B4000000000000C000000000000000D19000073
+:100B5000000000080F8000010000000000000000FD
+:100B600000000010001F00000000000C6BD7000107
+:100B700000000010011301F300000018000700003E
+:100B8000000000000502000000000010B99A2C21AE
+:100B900000000010205F0000000000002C1E00007C
+:100BA000000000082C800006000000082D00000650
+:100BB000000000082D80010200000000000000007D
+:100BC0000000001091DE0000000000000D61000038
+:100BD00000000018000A00000000000005020000EC
+:100BE00000000010B99A2C1600000010205F0000D1
+:100BF0000000000009D80000000000002C1E0000CA
+:100C0000000000082C80010E000000082D00000AE2
+:100C1000000000082D80010200000000000000001C
+:100C20000000001091DE0000000000000D620000D6
+:100C3000000000002C13000000000018000A000053
+:100C4000000000000502000000000010B99A2C0905
+:100C500000000010205F0000000000002C1E0000BB
+:100C6000000000082C800006000000082D00006A2B
+:100C7000000000082D8001020000000000000000BC
+:100C80000000001091DE0000000000000D7A00005E
+:100C900000000018000A0000000000002A00000008
+:100CA0000000000822000001000000000D610000AB
+:100CB0000000001021C2002800000010B1C6000290
+:100CC00000000010234200B3000000090B66FFFF84
+:100CD00000000010BA9A2C24000000000A640000F2
+:100CE000000000000AE50000000000000C00000009
+:100CF000000000000B800000000000080CC600127D
+:100D0000000000188000FFD0000000080F800003E2
+:100D1000000000000000000000000010001F0000A4
+:100D20000000000C6BD70001000000082711001222
+:100D3000000000006690000000000010B198000460
+:100D400000000010001F00000000000C6BD7000125
+:100D5000000000080F8000040000000822000003CB
+:100D6000000000082C80000C000000082D00000C82
+:100D700000000010001F00000000000C6BD70001F5
+:100D80000000001091C6000600000010001F0000C7
+:100D90000000000C6BD7000100000010BA9A2C0371
+:100DA000000000080F800004000000188000FFFC15
+:100DB00000000000259600000000000C29800000C3
+:100DC0000000000032140000000000003295000016
+:100DD0000000000573662C000000000031E32E00C7
+:100DE000000000082D800010000000188000FF8126
+:100DF00000000000230000000000000925E6FFFFBE
+:100E0000000000082200000B0000000C69520000E6
+:100E10000000000C29800000000000188000FF7B0B
+:100E2000000000002A000000000000082C800040A4
+:100E3000000000082D000020000000082D80011C8B
+:100E400000000008220000010000001091DE0000F8
+:100E50000000000F42EA001000000010004F0004E4
+:100E600000000010B746920000000008024900127E
+:100E700000000010B5840A00000000000D610000B1
+:100E800000000010BA6634640000000883050012F8
+:100E900000000010004F00020000000003490000A5
+:100EA0000000000183068C000000000083C60C00D7
+:100EB00000000010B1870013000000000B6E00005E
+:100EC000000000090569FFFF00000010918A000280
+:100ED0000000000834E9FFFF000000188000FF60F8
+:100EE000000000010569140000000010918A000252
+:100EF00000000008B4E9000100000010BAE92C5518
+:100F00000000000086692C000000000002000000C4
+:100F10000000000902EAFFFF00000010000C0002C0
+:100F20000000000002040A000000000F460C00014F
+:100F30000000000F0285000100000010918C01FCF0
+:100F400000000010B7040E4C000000000D6100000E
+:100F5000000000000A640000000000000AE5000034
+:100F6000000000090B66FFFF000000000C000000FD
+:100F7000000000000B800000000000080C8600123A
+:100F8000000000080F8000030000000C2952000040
+:100F900000000010001F00000000000C6BD70001D3
+:100FA00000000008271100120000000066900000F9
+:100FB000000000002306000000000010B1980007A8
+:100FC00000000010001F00000000000C6BD70001A3
+:100FD000000000080F800004000000000000000076
+:100FE00000000010001F00000000000C6BD7000183
+:100FF00000000000321400000000000032950000E4
+:101000000000000031E32E000000000573662C0094
+:10101000000000002596000000000010B187001FAE
+:101020000000000C298000000000000F0F6B00077B
+:10103000000000000D690000000000000A6C0000C4
+:10104000000000000AED0000000000000B6E000030
+:10105000000000000B800000000000000C87000072
+:10106000000000188000FF2F000000010C16140083
+:10107000000000008C181400000000080C9600010D
+:101080000000001091980002000000080C99000177
+:10109000000000000D190000000000000C0000001E
+:1010A000000000080F800001000000102053000025
+:1010B0000000000C6952000100000010001F000039
+:1010C0000000000C6BD700010000000022C58C005E
+:1010D00000000000231200000000000027110000A3
+:1010E000000000002690000000000010B8170E035A
+:1010F0000000000C29800000000000188000FFEDB7
+:101100000000000082970E0000000000A3120A00F9
+:10111000000000082200001A000000082C80000CCB
+:10112000000000082D00000C000000082D800010B9
+:1011300000000010001F00000000000C6BD7000131
+:10114000000000000D6E000000000003E7CF340037
+:101150000000000C298000000000001091DE00005B
+:1011600000000010B18700070000000036140000E6
+:101170000000000036950000000000003716000057
+:10118000000000082C800050000000082D000030F6
+:10119000000000082D80000C000000188000FF0BEC
+:1011A00000000000230000000000000925E6FFFF0A
+:1011B000000000000B6E000000000003E7CF2C00D1
+:1011C000000000082200001B0000000C6952000013
+:1011D0000000000C29800000000000188000FF03C0
+:1011E000000000002A000000000000188000FF013D
+:1011F000000000002A0000000000000C2980000010
+:101200000000001091DE0000000000082C80001A91
+:10121000000000082D00001A0000000573660000A1
+:10122000000000082D800002000000003180000056
+:101230000000001091DE0000000000082C80000C6F
+:10124000000000082D00000C000000082D800004A4
+:10125000000000188000FEF400000008066600018F
+:1012600000000010BA9A1972000000000A64000021
+:10127000000000000AE50000000000090B66FFFF07
+:10128000000000000C000000000000000B800000C7
+:10129000000000080CC60012000000188000FF1DAE
+:1012A000000000080F8000030000000000000000A4
+:1012B00000000010001F00000000000C6BD70001B0
+:1012C00000000008271100120000000066900000D6
+:1012D00000000010919B32000000001002930000FB
+:1012E00000000010B198000300000010001F000073
+:1012F0000000000C6BD70001000000080F80000404
+:101300000000000C2980000000000010001F0000F9
+:101310000000000C6BD7000100000010BA9A2C00EE
+:101320000000000031E32E00000000000B800000F0
+:10133000000000008CCC8C0000000010B5CC8C02AA
+:10134000000000080C800001000000188000FF076A
+:10135000000000080F800003000000102053000070
+:101360000000000C695200010000000022C58C0042
+:1013700000000010001F00000000000C6BD70001EF
+:10138000000000002711000000000000269000006F
+:1013900000000000231B000000000010B1980003B3
+:1013A00000000010001F00000000000C6BD70001BF
+:1013B000000000080F800004000000082200000365
+:1013C000000000082C80000C000000082D00000C1C
+:1013D00000000010001F00000000000C6BD700018F
+:1013E00000000000259600000000000C298000008D
+:1013F00000000000321400000000000032950000E0
+:101400000000000573662C000000000031E32E0090
+:10141000000000082D800010000000188000FEBBB6
+:10142000000000188000FEBA000000002A00000042
+:1014300000000010001F00000000000C6BD700012E
+:10144000000000000F008000000000080F8000076F
+:10145000000000188000001C00000000280A0000A6
+:101460000000000005020000000000082200000942
+:1014700000000000290000000000000F6568001057
+:1014800000000000248A000000000003F66C9400B5
+:1014900000000010B972A0040000000C73E70019EE
+:1014A0000000000C21420004000000003CF8000095
+:1014B0000000000C298000000000001020530000F4
+:1014C00000000008220000080000000C6142000437
+:1014D00000000018000A00000000000005020000E3
+:1014E0000000000C614200000000001001420003F7
+:1014F0000000000C33E7001D0000000C61420002F8
+:1015000000000018000A0000000000002A0000008F
+:1015100000000010001F00000000000C6BD700014D
+:101520000000000F0F470007000000080F800008B0
+:101530000000000C2980000000000010001F0000C7
+:101540000000000C6BD70001000000188000FE9521
+:101550000000000033510000000000002A000000DD
+:1015600000000010B1C600250000000F0F5000075A
+:10157000000000000A600000000000000AE1000016
+:101580000000000F4B620008000000090B1600FF6E
+:101590000000000F4C620010000000000D6200000F
+:1015A000000000090D1A00FF0000001007500003A2
+:1015B0000000000C0D1A00080000000C0B160008BB
+:1015C000000000000CC60000000000000B800000BE
+:1015D0000000000006980000000000080F800003D3
+:1015E0000000001006C200040000000C29000002E8
+:1015F00000000010264200020000000C29520003E7
+:10160000000000082200000100000010001F000080
+:101610000000000C6BD7000100000000231B00003D
+:101620000000000027111A00000000006690000072
+:101630000000000C2952000000000010B197320A8F
+:101640000000000C29800000000000000698000047
+:1016500000000010205300000000000C295200037D
+:101660000000000022C58C0000000010001F0000D8
+:101670000000000C6BD70001000000080F80000381
+:10168000000000188000FFF100000010B1C8001336
+:1016900000000010B1C600030000000C298000000B
+:1016A00000000010205300000000000C2952000030
+:1016B0000000000C295200030000001006C20002C6
+:1016C0000000000C295200020000000022C58C001E
+:1016D00000000000276500000000000026E4000074
+:1016E000000000082200001600000010B1C6000330
+:1016F000000000002348000000000010B180000539
+:1017000000000000234800000000000C29800000B9
+:101710000000000F0F5000070000001880000012AA
+:1017200000000008220000160000000C29800000C4
+:1017300000000000301400000000000030950000A0
+:101740000000001007500003000000090B1600FF06
+:10175000000000090D1A00FF0000000F31160008FC
+:10176000000000003162340000000003F16230002C
+:1017700000000010205F0000000000002C5100005D
+:10178000000000092CD1007F000000082CD90000C7
+:10179000000000082D000000000000082D80000C53
+:1017A00000000000000000000000001091DE0000BA
+:1017B0000000001005C20005000000080F800007AF
+:1017C000000000003300000000000010001F0000B7
+:1017D0000000000C6BD70001000000188000FE43E1
+:1017E000000000002A0000000000000F0F5000075A
+:1017F00000000010B1C600300000000F4742000892
+:1018000000000009070E000F00000008070E000886
+:1018100000000010001F00000000000C6BD700014A
+:1018200000000008090000010000000709121C0068
+:1018300000000003CBCA9200000000000B97A2003A
+:101840000000000742171C00000000000B0400000D
+:101850000000000F0A840003000000000A959C00AD
+:10186000000000004A009A000000000882120001F7
+:10187000000000010C170800000000000C978C000D
+:101880000000000002180000000000080D00FFFF2B
+:10189000000000080F8000060000000C2900000076
+:1018A0000000001006C200040000000C29520002D3
+:1018B00000000010264200020000000C2952000324
+:1018C000000000082200000100000010001F0000BE
+:1018D0000000000C6BD7000100000010B197320D22
+:1018E00000000000231B000000000000271108007A
+:1018F00000000000669000000000000C298000003D
+:10190000000000000218000000000010205300003A
+:101910000000000C295200030000000022C5360020
+:1019200000000010001F00000000000C6BD7000139
+:10193000000000080F800006000000188000FFF281
+:1019400000000000231B0000000000002711080019
+:10195000000000006690000000000010B1C8000BFD
+:101960000000000C2980000000000010205300003F
+:101970000000000C295200000000000C2952000356
+:101980000000001006C200020000000C29520002F4
+:101990000000000022C58C00000000002765000048
+:1019A0000000000026E400000000000023480000C2
+:1019B00000000008220000170000000C2980000031
+:1019C00000000010001F00000000000C6BD7000199
+:0819D000000000188000FE0475
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2x-e1-5.2.13.0.fw.ihex b/firmware/bnx2x-e1-5.2.13.0.fw.ihex
deleted file mode 100644
index 651f4346d89e..000000000000
--- a/firmware/bnx2x-e1-5.2.13.0.fw.ihex
+++ /dev/null
@@ -1,10191 +0,0 @@
-:10000000000028B0000000600000068800002918E9
-:100010000000161400002FA800000098000045C042
-:10002000000073C400004660000000CC0000BA2845
-:1000300000009A700000BAF80000009400015570AA
-:10004000000057BC00015608000000B80001ADC810
-:100050000000CE200001AE880000000400027CB049
-:10006000020400480000000F020400540000004594
-:1000700002040058000000840204005C0000000636
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000060400CC0000000418
-:10010000020400DC00100000020400E012140000F1
-:10011000020400E422140000020400E8321400008B
-:10012000060400EC000000040104012400000000AB
-:1001300001040128000000000104012C000000005F
-:10014000010401300000000002040004000000FF70
-:1001500002040008000000FF0204000C000000FF81
-:1001600002040010000000FF02040014000000FF61
-:1001700002040018000000FF0204001C000000FF41
-:1001800002040020000000FF020400240000003EE2
-:1001900002040028000000000204002C0000003FC0
-:1001A000020400300000003F020400340000003F61
-:1001B00002040038000000000204003C0000003F80
-:1001C000020400400000003F020400440000003F21
-:1001D00002042008000004110204200C00000400A6
-:1001E000020420100000040402042014000004197A
-:1001F0000204201C0000FFFF020420200000FFFF7B
-:10020000020420240000FFFF020420280000FFFF5A
-:1002100006042038000000020204204000000034E0
-:100220000204204400000035060420480000007C41
-:100230000204223807FFFFFF0204223C0000003FB7
-:100240000204224007FFFFFF020422440000000FC7
-:1002500001042248000000000104224C00000000BC
-:10026000010422500000000001042254000000009C
-:1002700001042258000000000104225C000000007C
-:10028000010422600000000001042264000000005C
-:1002900001042268000000000104226C000000003C
-:1002A000010422700000000001042274000000001C
-:1002B00001042278000000000104227C00000000FC
-:1002C000020424BC000000010C042000000003E82C
-:1002D0000A042000000000010B0420000000000AB6
-:1002E0000205004400000020020500480000003222
-:1002F000020500900215002002050094021500205E
-:1003000002050098000000300205009C0810000063
-:10031000020500A000000033020500A40000003028
-:10032000020500A800000031020500AC0000000238
-:10033000020500B000000005020500B40000000640
-:10034000020500B800000002020500BC0000000227
-:10035000020500C000000000020500C40000000506
-:10036000020500C800000002020500CC00000002E7
-:10037000020500D000000002020500D400000001C8
-:1003800002050114000000010205011C000000012B
-:100390000205012000000002020502040000000125
-:1003A0000205020C0000004002050210000000409F
-:1003B0000205021C000000200205022000000013BC
-:1003C0000205022400000020060502400000000A89
-:1003D0000405028000200000020500500000000714
-:1003E0000205005400000007020500580000000844
-:1003F0000205005C00000008060500600000000423
-:10040000020500D800000006020500E00000000D13
-:10041000020500E40000002D020500E800000007CE
-:10042000020500EC00000027020500F000000007B4
-:10043000020500F400000027020500F80000000794
-:10044000020500FC00000027020500040000000176
-:1004500002050008000000010205000C0000000178
-:100460000205001000000001020500140000000158
-:1004700002050018000000010205001C0000000138
-:100480000205002000000001020500240000000118
-:1004900002050028000000010205002C00000001F8
-:1004A00002050030000000010205003400000001D8
-:1004B00002050038000000010205003C00000001B8
-:1004C00002050040000000010406100002000020A8
-:1004D000020600DC00000001010600D80000000058
-:1004E0000406020000030220020600DC00000000F7
-:1004F00002060068000000B802060078000001143F
-:10050000010600B800000000010600C8000000005D
-:100510000206006C000000B80206007C0000011416
-:10052000010600BC00000000010600CC0000000035
-:100530000718040000950000081807600014022343
-:10054000071C000034D40000071C800034CF0D3697
-:10055000071D00000A191A6A081D14605D7402253F
-:100560000118000000000000011800040000000055
-:1005700001180008000000000118000C0000000035
-:100580000118001000000000011800140000000015
-:1005900002180020000000010218002400000002E0
-:1005A00002180028000000030218002C00000000C0
-:1005B000021800300000000402180034000000019E
-:1005C00002180038000000000218003C0000000182
-:1005D000021800400000000402180044000000005F
-:1005E00002180048000000010218004C000000033F
-:1005F0000218005000000000021800540000000122
-:1006000002180058000000040218005C00000000FE
-:1006100002180060000000010218006400000003DE
-:1006200002180068000000000218006C00000001C1
-:10063000021800700000000402180074000000009E
-:1006400002180078000000040218007C000000037B
-:100650000618008000000002021800A400003FFFFE
-:10066000021800A8000003FF021802240000000086
-:1006700002180234000000000218024C00000000C2
-:10068000021802E4000000FF061810000000040039
-:10069000021B8BC000000001021B80000000003420
-:1006A000021B804000000018021B80800000000C2C
-:1006B000021B80C0000000200C1B83000007A1204B
-:1006C0000A1B8300000001380B1B83000000138805
-:1006D000021B83C0000001F4061A2000000000B2D3
-:1006E000061A23C800000181041A29CC0001022740
-:1006F000061A1020000000C8061A100000000002B0
-:10070000061A1E3800000002061A1E300000000201
-:10071000061A080000000002061A0808000000027D
-:10072000061A081000000004041A1FB00005022871
-:10073000041A4CB00008022D061A22C8000000203E
-:10074000061A400000000124021A4920000000009F
-:10075000061A14000000000A061A145000000006D1
-:10076000061A150000000002041A150800050235DB
-:10077000061A151C00000009061A15800000001456
-:10078000061A09C000000048061A0800000000020E
-:10079000061A08200000000E041A1FB00002023AD8
-:1007A000061A2C2800000002061A23480000002028
-:1007B000061A449000000124021A49240000000097
-:1007C000061A14280000000A061A14680000000621
-:1007D000061A154000000002041A15480005023CE4
-:1007E000061A155C00000009061A15D00000001456
-:1007F000061A0AE000000048061A08080000000275
-:10080000061A08580000000E041A1FB80002024120
-:10081000061A2C30000000020200A2800000000135
-:100820000200A294071D29110200A29800000000F6
-:100830000200A29C009C04240200A2A00000000070
-:100840000200A2A4000002090200A4FCFF000000B4
-:10085000020100B400000001020100B80000000124
-:10086000020100DC000000010201010000000001A3
-:1008700002010104000000010201007C00300000C0
-:1008800002010084000000280201008C000000002A
-:1008900002010130000000040201025C00000001BE
-:1008A000020103280000000002010554000000308E
-:1008B000020100C400000001020100CC00000001A0
-:1008C000020100F800000001020100F00000000138
-:1008D00002010080003000000201008800000028B2
-:1008E0000201009000000000020101340000000439
-:1008F000020102DC000000010201032C00000000E4
-:100900000201056400000030020100C8000000017F
-:10091000020100D000000001020100FC0000000103
-:10092000020100F400000001020C10000000002091
-:10093000020C200800000A11020C200C00000A0022
-:10094000020C201000000A04020C201C0000FFFF13
-:10095000020C20200000FFFF020C20240000FFFFFB
-:10096000020C20280000FFFF060C203800000002C7
-:10097000020C204000000034020C2044000000352E
-:10098000020C204800000020020C204C0000002136
-:10099000020C205000000022020C20540000002312
-:1009A000020C205800000024020C205C00000025EE
-:1009B000020C206000000026020C206400000027CA
-:1009C000020C206800000028020C206C00000029A6
-:1009D000020C20700000002A020C20740000002B82
-:1009E000060C207800000056020C21D00000000107
-:1009F000020C21D400000001020C21D800000001EB
-:100A0000020C21DC00000001020C21E000000001CA
-:100A1000020C21E400000001020C21E800000001AA
-:100A2000020C21EC00000001020C21F0000000018A
-:100A3000020C21F400000001060C21F80000001057
-:100A4000020C223807FFFFFF020C223C0000003F8F
-:100A5000020C224007FFFFFF020C22440000000F9F
-:100A6000010C224800000000010C224C0000000094
-:100A7000010C225000000000010C22540000000074
-:100A8000010C225800000000010C225C0000000054
-:100A9000010C226000000000010C22640000000034
-:100AA000010C226800000000010C226C0000000014
-:100AB000010C227000000000010C227400000000F4
-:100AC000010C227800000000010C227C00000000D4
-:100AD000020C24BC000000010C0C2000000003E804
-:100AE0000A0C2000000000010B0C20000000000A8E
-:100AF000020C400800000365020C400C0000035487
-:100B0000020C401000000358020C40140000037552
-:100B1000020C401C0000FFFF020C40200000FFFF01
-:100B2000020C40240000FFFF020C40280000FFFFE1
-:100B3000020C403800000046020C403C000000055A
-:100B4000060C40400000005E020C41B800000001AD
-:100B5000060C41BC0000001F020C423807FFFFFFDB
-:100B6000020C423C0000003F020C424007FFFFFF26
-:100B7000020C42440000000F010C4248000000003B
-:100B8000010C424C00000000010C4250000000002B
-:100B9000010C425400000000010C4258000000000B
-:100BA000010C425C00000000010C426000000000EB
-:100BB000010C426400000000010C426800000000CB
-:100BC000010C426C00000000010C427000000000AB
-:100BD000010C427400000000010C4278000000008B
-:100BE000010C427C00000000010C4280000000006B
-:100BF000020C44C0000000010C0C4000000003E89F
-:100C00000A0C4000000000010B0C40000000000A2C
-:100C1000020D004400000032020D008C021500207D
-:100C2000020D009002150020020D00940810000033
-:100C3000020D009800000033020D009C000000022D
-:100C4000020D00A000000000020D00A4000000053D
-:100C5000020D00A800000005060D00AC0000000217
-:100C6000020D00B400000002020D00B800000003F5
-:100C7000020D00BC00000002020D00C000000001D7
-:100C8000020D00C800000002020D00CC00000002AE
-:100C9000020D010800000001020D015C00000001CE
-:100CA000020D016400000001020D01680000000255
-:100CB000020D020400000001020D020C00000020E1
-:100CC000020D021000000040020D0214000000405E
-:100CD000020D022000000003020D02240000001893
-:100CE000060D028000000012040D030000240243E0
-:100CF000020D004C00000001020D00500000000237
-:100D0000020D005400000008020D00580000000809
-:100D1000060D005C00000004020D00C40000000489
-:100D2000020D011400000009020D01180000002945
-:100D3000020D011C0000000A020D01200000002A23
-:100D4000020D012400000007020D01280000002709
-:100D5000020D012C00000007020D013000000027E9
-:100D6000020D01340000000C020D01380000002CBF
-:100D7000020D013C0000000C020D01400000002C9F
-:100D8000020D01440000000C020D01480000002C7F
-:100D9000020D000400000001020D00080000000127
-:100DA000020D000C00000001020D00100000000107
-:100DB000020D001400000001020D001800000001E7
-:100DC000020D001C00000001020D002000000001C7
-:100DD000020D002400000001020D002800000001A7
-:100DE000020D002C00000001020D00300000000187
-:100DF000020D003400000001020D00380000000167
-:100E0000020D003C00000001020E004C0000003208
-:100E1000020E009402150020020E00980215002018
-:100E2000020E009C00000030020E00A0081000001E
-:100E3000020E00A400000033020E00A800000030E3
-:100E4000020E00AC00000031020E00B000000002F3
-:100E5000020E00B400000004020E00B80000000002
-:100E6000020E00BC00000002020E00C000000002E2
-:100E7000020E00C400000000020E00C800000002C4
-:100E8000020E00CC00000007020E00D0000000029D
-:100E9000020E00D400000002020E00D80000000183
-:100EA000020E00E400000001020E014400000001F7
-:100EB000020E014C00000001020E01500000000271
-:100EC000020E020400000001020E020C00000040AD
-:100ED000020E021000000040020E021C000000047E
-:100EE000020E022000000020020E02240000000E6C
-:100EF000020E02280000001B060E03000000001274
-:100F0000040E0280001B0267020E00540000000C59
-:100F1000020E005800000009020E005C0000000FE5
-:100F2000020E006000000010060E006400000004C5
-:100F3000020E00DC00000003020E01100000000F92
-:100F4000020E01140000002F020E01180000000E16
-:100F5000020E011C0000002E020E00040000000121
-:100F6000020E000800000001020E000C000000014B
-:100F7000020E001000000001020E0014000000012B
-:100F8000020E001800000001020E001C000000010B
-:100F9000020E002000000001020E002400000001EB
-:100FA000020E002800000001020E002C00000001CB
-:100FB000020E003000000001020E003400000001AB
-:100FC000020E003800000001020E003C000000018B
-:100FD000020E004000000001020E0044000000016B
-:100FE0000730040000C900000830076800130282BF
-:100FF00007340000334B00000734800037090CD35E
-:101000000735000030161A96083572F051A2028496
-:10101000013000000000000001300004000000006A
-:1010200001300008000000000130000C000000004A
-:10103000013000100000000001300014000000002A
-:1010400002300020000000010230002400000002F5
-:1010500002300028000000030230002C00000000D5
-:1010600002300030000000040230003400000001B3
-:1010700002300038000000000230003C0000000197
-:101080000230004000000004023000440000000074
-:1010900002300048000000010230004C0000000354
-:1010A0000230005000000000023000540000000137
-:1010B00002300058000000040230005C0000000014
-:1010C00002300060000000010230006400000003F4
-:1010D00002300068000000000230006C00000001D7
-:1010E00002300070000000040230007400000000B4
-:1010F00002300078000000040230007C0000000391
-:101100000630008000000002023000A400003FFF13
-:10111000023000A8000003FF02300224000000009B
-:1011200002300234000000000230024C00000000D7
-:10113000023002E40000FFFF06302000000008003B
-:1011400002338BC000000001023380000000001A4F
-:10115000023380400000004E023380800000001007
-:10116000023380C0000000200C3383000007A12060
-:101170000A338300000001380B338300000013881A
-:10118000023383C0000001F40C3383801DCD650061
-:101190000A3383800004C4B40B338380004C4B407B
-:1011A00006321AA0000000C206321020000000C85B
-:1011B0000632100000000002063214000000004059
-:1011C00006325098000000040632508000000005EE
-:1011D00004325094000102860632500000000020C4
-:1011E00004322830000202870233080001000000A8
-:1011F00004330C00001002890233080000000000D4
-:1012000004330C400010029906321500000000B4AF
-:1012100002321DC80000000006324000000000D865
-:10122000063217D0000000B402321DCC00000000CE
-:1012300006324360000000D807200400009200003E
-:1012400008200780001002A9072400002CD100000C
-:10125000072480002AE50B350824DC6062DA02AB43
-:101260000120000000000000012000040000000038
-:1012700001200008000000000120000C0000000018
-:1012800001200010000000000120001400000000F8
-:1012900002200020000000010220002400000002C3
-:1012A00002200028000000030220002C00000000A3
-:1012B0000220003000000004022000340000000181
-:1012C00002200038000000000220003C0000000165
-:1012D0000220004000000004022000440000000042
-:1012E00002200048000000010220004C0000000322
-:1012F0000220005000000000022000540000000105
-:1013000002200058000000040220005C00000000E1
-:1013100002200060000000010220006400000003C1
-:1013200002200068000000000220006C00000001A4
-:101330000220007000000004022000740000000081
-:1013400002200078000000040220007C000000035E
-:101350000620008000000002022000A400003FFFE1
-:10136000022000A8000003FF022002240000000069
-:1013700002200234000000000220024C00000000A5
-:10138000022002E40000FFFF062020000000080009
-:1013900002238BC000000001022380000000001027
-:1013A00002238040000000120223808000000030F1
-:1013B000022380C00000000E022383C0000001F45D
-:1013C000062250000000004206221020000000C843
-:1013D000062210000000000206222000000000C0CB
-:1013E000062225C00000024004222EC8000802ADDB
-:1013F00002230800013FFFFF04230C00001002B588
-:10140000022308000000000004230C40001002C565
-:1014100006223040000000A00622354000000010E7
-:10142000062236C000000030062240000000020004
-:10143000062235C00000002006223840000000309F
-:1014400006223000000000080222511800000000AF
-:10145000062223000000000E0622241000000030A7
-:10146000062232C0000000A00622358000000010D5
-:1014700006223780000000300622480000000200EB
-:10148000062236400000002006223900000000300D
-:1014900006223020000000080222511C000000003B
-:1014A000062223380000000E062224D0000000305F
-:1014B00002161000000000280217000800000002B9
-:1014C0000217002C000000030217003C000000047B
-:1014D0000217004400000008021700480000000244
-:1014E0000217004C0000009002170050000000900E
-:1014F00002170054008000900217005808140000E2
-:10150000021700600000008A0217006400000080DB
-:1015100002170068000000810217006C00000080C4
-:10152000021700700000000602170078000007D0C4
-:101530000217007C0000076C02170038007C1004C2
-:10154000021700040000000F0616402400000002ED
-:10155000021640700000001C021642080000000144
-:101560000216421000000001021642200000000195
-:10157000021642280000000102164230000000015D
-:10158000021642380000000102164260000000010D
-:101590000C16401C0003D0900A16401C0000009C52
-:1015A0000B16401C000009C4021640300000000861
-:1015B000021640340000000C0216403800000010F3
-:1015C0000216404400000020021640000000000106
-:1015D000021640D800000001021640080000000179
-:1015E0000216400C0000000102164010000000012D
-:1015F00002164240000000000216424800000000AF
-:101600000616427000000002021642500000000060
-:101610000216425800000000061642800000000238
-:1016200002166008000006140216600C0000060096
-:1016300002166010000006040216601C0000FFFF86
-:10164000021660200000FFFF021660240000FFFF6A
-:10165000021660280000FFFF02166038000000201C
-:101660000216603C000000200216604000000034BA
-:101670000216604400000035021660480000002396
-:101680000216604C00000024021660500000002585
-:101690000216605400000026021660580000002761
-:1016A0000216605C00000029021660600000002A3B
-:1016B000021660640000002B021660680000002C17
-:1016C0000216606C0000002D0616607000000052CB
-:1016D000021661B800000001061661BC0000001F80
-:1016E0000216623807FFFFFF0216623C0000003F4F
-:1016F0000216624007FFFFFF021662440000000F5F
-:1017000001166248000000000116624C0000000053
-:101710000116625000000000011662540000000033
-:1017200001166258000000000116625C0000000013
-:1017300001166260000000000116626400000000F3
-:1017400001166268000000000116626C00000000D3
-:1017500001166270000000000116627400000000B3
-:1017600001166278000000000116627C0000000093
-:10177000021664BC000000010C166000000003E8C3
-:101780000A166000000000010B1660000000000A4D
-:10179000021680400000000602168044000000058A
-:1017A000021680480000000A0216804C0000000566
-:1017B0000216805400000002021680CC00000004D3
-:1017C000021680D000000004021680D4000000043D
-:1017D000021680D800000004021680DC000000041D
-:1017E000021680E000000004021680E400000004FD
-:1017F000021680E8000000040216880400000004BD
-:10180000021680300000007C021680340000003D8B
-:10181000021680380000003F0216803C0000009C49
-:10182000021680F000000007061680F40000000594
-:101830000216880C01010101021681080000000057
-:101840000216810C00000004021681100000000442
-:1018500002168114000000020216881008012004FC
-:1018600002168118000000050216811C0000000508
-:1018700002168120000000050216812400000005E8
-:101880000216882C2008100102168128000000088A
-:101890000216812C000000060216813000000007AD
-:1018A0000216813400000000021688300101012078
-:1018B0000616813800000004021688340101010177
-:1018C0000616814800000004021688380101010153
-:1018D00006168158000000040216883C010101012F
-:1018E00006168168000000030216817400000001E2
-:1018F00002168840010101010216817800000001F2
-:101900000216817C000000010216818000000001A7
-:1019100002168184000000010216884401010101C1
-:1019200002168188000000010216818C000000046C
-:10193000021681900000000402168194000000024B
-:10194000021688480801200402168198000000054C
-:101950000216819C00000005021681A0000000050F
-:10196000021681A400000005021688142008100148
-:10197000021681A800000008021681AC00000006D3
-:10198000021681B000000007021681B400000001B9
-:101990000216881801010120021681B8000000011A
-:1019A000021681BC00000001021681C00000000187
-:1019B000021681C4000000010216881C0101010109
-:1019C000021681C800000001021681CC000000014F
-:1019D000021681D000000001021681D4000000012F
-:1019E0000216882001010101021681D800000001C1
-:1019F000021681DC00000001021681E000000001F7
-:101A0000021681E400000001021688240101010190
-:101A1000021681E800000001021681EC00000001BE
-:101A2000021681F000000001021688280101010160
-:101A300002168240FFFF003F0616824400000002AB
-:101A40000216824CFFFF003F021682500000010088
-:101A5000021682540000010006168258000000029F
-:101A600002168260000000C002168264000000C0FE
-:101A70000216826800001E000216826C00001E0022
-:101A800002168270000040000216827400004000BE
-:101A900002168278000080000216827C000080001E
-:101AA00002168280000020000216828400002000BE
-:101AB0000616828800000007021682A400000001BA
-:101AC000061682A80000000A021681F400000C0825
-:101AD000021681F800000040021681FC000001009F
-:101AE0000216820000000020021682040000001787
-:101AF00002168208000000800216820C000002001C
-:101B0000021682100000000002168218FFFF01FF7B
-:101B100002168214FFFF01FF0216823C0000001330
-:101B2000021680900000013F021680600000014014
-:101B30000216806400000140061680680000000262
-:101B400002168070000000C00616807400000007B6
-:101B50000216809C00000048021680A00000004889
-:101B6000061680A400000002021680AC00000048A7
-:101B7000061680B0000000070216823800008000C0
-:101B800002168234000025E40216809400007FFFD4
-:101B900002168220000000070216821C00000007C7
-:101BA000021682280000000002168224FFFFFFFFB9
-:101BB00002168230000000000216822CFFFFFFFF99
-:101BC000021680EC000000FF02140000000000017B
-:101BD0000214000C0000000102140040000000018B
-:101BE0000214004400007FFF0214000C00000000FB
-:101BF00002140000000000000214006C000000004D
-:101C00000214000400000001021400300000000172
-:101C100002140004000000000214005C0000000038
-:101C2000021400080000000102140034000000014A
-:101C30000214000800000000021400600000000010
-:101C40000202005800000032020200A0031500202A
-:101C5000020200A403150020020200A801000030C7
-:101C6000020200AC08100000020200B000000033C5
-:101C7000020200B400000030020200B8000000318F
-:101C8000020200BC00000003020200C000000006C7
-:101C9000020200C400000003020200C800000003AA
-:101CA000020200CC00000002020200D0000000008E
-:101CB000020200D400000002020200DC000000006A
-:101CC000020200E000000006020200E4000000043E
-:101CD000020200E800000002020200EC0000000224
-:101CE000020200F000000001020200FC00000006F9
-:101CF0000202012000000000020201340000000284
-:101D0000020201B0000000010202020C000000010A
-:101D10000202021400000001020202180000000288
-:101D200002020404000000010202040C0000004052
-:101D300002020410000000400202041C0000000423
-:101D4000020204200000002002020424000000021D
-:101D5000020204280000001F060205000000001215
-:101D600004020480001F02D5020200600000000F80
-:101D70000202006400000007020200680000000B7D
-:101D80000202006C0000000E060200700000000459
-:101D9000020200F40000000402020004000000013E
-:101DA00002020008000000010202000C0000000115
-:101DB00002020010000000010202001400000001F5
-:101DC00002020018000000010202001C00000001D5
-:101DD00002020020000000010202002400000001B5
-:101DE00002020028000000010202002C0000000195
-:101DF0000202003000000001020200340000000175
-:101E000002020038000000010202003C0000000154
-:101E10000202004000000001020200440000000134
-:101E200002020048000000010202004C0000000114
-:101E3000020200500000000102020108000000C878
-:101E40000202011800000002020201C400000000AA
-:101E5000020201CC00000000020201D400000002D6
-:101E6000020201DC00000002020201E4000000FFA7
-:101E7000020201EC000000FF0202010C000000C899
-:101E80000202011C00000002020201C80000000062
-:101E9000020201D000000000020201D8000000028E
-:101EA000020201E000000002020201E8000000FF5F
-:101EB000020201F0000000FF0728040000B5000046
-:101EC00008280768001302F4072C000035D500002D
-:101ED000072C80003A3E0D76072D00003B471C067C
-:101EE000072D800022BC2AD8082DC770471202F6A1
-:101EF000012800000000000001280004000000008C
-:101F000001280008000000000128000C000000006B
-:101F1000012800100000000001280014000000004B
-:101F20000228002000000001022800240000000216
-:101F300002280028000000030228002C00000000F6
-:101F400002280030000000040228003400000001D4
-:101F500002280038000000000228003C00000001B8
-:101F60000228004000000004022800440000000095
-:101F700002280048000000010228004C0000000375
-:101F80000228005000000000022800540000000158
-:101F900002280058000000040228005C0000000035
-:101FA0000228006000000001022800640000000315
-:101FB00002280068000000000228006C00000001F8
-:101FC00002280070000000040228007400000000D5
-:101FD00002280078000000040228007C00000003B2
-:101FE0000628008000000002022800A400003FFF35
-:101FF000022800A8000003FF0228022400000000BD
-:1020000002280234000000000228024C00000000F8
-:10201000022802E40000FFFF06282000000008005C
-:10202000022B8BC000000001022B8000000000008A
-:10203000022B804000000018022B80800000000C62
-:10204000022B80C0000000660C2B83000007A1203B
-:102050000A2B8300000001380B2B8300000013883B
-:10206000022B83C0000001F40C2B8340000001F41C
-:102070000A2B8340000000000B2B8340000000056A
-:102080000A2B83800004C4B40C2B83801DCD650013
-:102090000B2B8380004C4B40062A3C400000000480
-:1020A000042A3C50000202F8062A300000000048D2
-:1020B000062A1020000000C8062A100000000002B6
-:1020C000062A31280000008E022A33680000000032
-:1020D000042A3370000202FA042A3A70000402FC57
-:1020E000042A3D0000020300042A15000002030236
-:1020F000062A150800000100022A197000000000DD
-:10210000022A197800000000042A19600002030462
-:10211000062A4AC000000002062A4B000000000404
-:10212000042A1F4800020306022B080000000000DA
-:10213000042B0C0000100308022B08000100000013
-:10214000042B0C4000080318022B080002000000BA
-:10215000042B0C6000080320062A3A8000000014BB
-:10216000062A3B2000000024062A14000000000A72
-:10217000062A145000000006062A3378000000D812
-:10218000022A3A3800000000042A3C5800020328C2
-:10219000042A3C680010032A062A5020000000028E
-:1021A000062A503000000002062A500000000002FB
-:1021B000062A501000000002022A504000000000D1
-:1021C000062A50480000000E022A50B80000000104
-:1021D000042A4AC80002033A062A4B1000000042B3
-:1021E000062A4D2000000004062A3AD00000001400
-:1021F000062A3BB000000024062A14280000000A2A
-:10220000062A146800000006062A36D8000000D806
-:10221000022A3A3C00000000042A3C600002033C11
-:10222000042A3CA80010033E062A502800000002A1
-:10223000062A503800000002062A5008000000025A
-:10224000062A501800000002022A50440000000034
-:10225000062A50800000000E022A50BC0000000137
-:10226000042A4AD00002034E062A4C1800000042FD
-:10227000062A4D3000000004021010080000000182
-:102280000210101000000264021010000003D000C1
-:10229000021010040000003D091018000200035055
-:1022A00009101100002005500610118000000002E6
-:1022B0000910118800060570061011A00000001812
-:1022C000021010100000000006102400000000E0C2
-:1022D0000210201C0000000002102020000000015D
-:1022E000021020C0000000010210200400000001C4
-:1022F000021020080000000109103C0000050576CE
-:1023000009103C200005057B0910380000050580F8
-:1023100002104028000000100210404400003FFF5F
-:102320000210405800280000021040840084924AA5
-:1023300002104058000000000610806800000004F1
-:1023400002108000000010800610802800000002AB
-:102350000210803800000010021080400000FFFFD3
-:10236000021080440000FFFF0210805000000000B7
-:102370000210810000000000061081200000000211
-:1023800002108008000002B502108010000000005A
-:10239000061082000000004A021081080001FFFFC1
-:1023A00006108140000000020210800000001A8028
-:1023B0000610900000000024061091200000004A42
-:1023C000061093700000004A061095C00000004AF5
-:1023D000021080040000108006108030000000020F
-:1023E0000210803C00000010021080480000FFFF37
-:1023F0000210804C0000FFFF02108054000000001B
-:102400000210810400000000061081280000000274
-:102410000210800C000002B50210801400000000C1
-:10242000061084000000004A0210810C0001FFFF2A
-:1024300006108148000000020210800400001A808B
-:102440000610909000000024061092480000004AF8
-:10245000061094980000004A061096E80000004A12
-:102460000212049000E383400212051400003C10A5
-:10247000021205200000000202120494FFFFFFFF79
-:1024800002120498FFFFFFFF0212049CFFFFFFFFF0
-:10249000021204A0FFFFFFFF021204A4FFFFFFFFD0
-:1024A000021204A8FFFFFFFF021204ACFFFFFFFFB0
-:1024B000021204B0FFFFFFFF021204B8FFFFFFFF8C
-:1024C000021204BCFFFFFFFF021204C0FFFFFFFF68
-:1024D000021204C4FFFFFFFF021204C8FFFFFFFF48
-:1024E000021204CCFFFFFFFF021204D0FFFFFFFF28
-:1024F000021204DCFFFFFFFF021204E0FFFFFFFFF8
-:10250000021204E4FFFFFFFF021204E8FFFFFFFFD7
-:10251000021204ECFFFFFFFF021204F0FFFFFFFFB7
-:10252000021204F4FFFFFFFF021204F8FFFFFFFF97
-:10253000021204FCFFFFFFFF02120500FFFFFFFF76
-:1025400002120504FFFFFFFF02120508FFFFFFFF55
-:102550000212050CFFFFFFFF02120510FFFFFFFF35
-:10256000021204D4FFFF3330021204D8FFFF3340BD
-:10257000021204B4F00030000212039000000008C0
-:102580000212039C00000008061203A000000002D3
-:10259000021203BC00000004021203C40000000485
-:1025A000021203D000000000021203DC0000000051
-:1025B0000212036C00000001021203680000003FD9
-:1025C000021201BC00000040021201C00000180805
-:1025D000021201C400000803021201C8000008032F
-:1025E000021201CC00000040021201D000000003E2
-:1025F000021201D400000803021201D800000803EF
-:10260000021201DC00000803021201E000010003D5
-:10261000021201E400000803021201E800000803AE
-:10262000021201EC00000003021201F0000000039E
-:10263000021201F400000003021201F8000000037E
-:10264000021201FC0000000302120200000000035D
-:10265000021202040000000302120208000000033C
-:102660000212020C0000000302120210000000031C
-:1026700002120214000000030212021800000003FC
-:102680000212021C000000030212022000000003DC
-:102690000212022400000003021202280000240398
-:1026A0000212022C0000002F02120230000000096A
-:1026B00002120234000000190212023800000184E4
-:1026C0000212023C000001830212024000000306D5
-:1026D0000212024400000019021202480000000623
-:1026E0000212024C00000306021202500000030610
-:1026F00002120254000003060212025800000C8667
-:102700000212025C000003060212026000000306CF
-:1027100002120264000000060212026800000006B5
-:102720000212026C00000006021202700000000695
-:102730000212027400000006021202780000000675
-:102740000212027C00000006021202800000000655
-:102750000212028400000006021202880000000635
-:102760000212028C00000006021202900000000615
-:1027700002120294000000060212029800000006F5
-:102780000212029C00000006021202A000000306D2
-:10279000021202A400000013021202A800000006A8
-:1027A000021202B000001004021202B40000100471
-:1027B0000212032400106440021203280010644037
-:1027C000021201B0000000010600A0000000001687
-:1027D0000200A06CBF5C00000200A070FFF51FEFBC
-:1027E0000200A0740000FFFF0200A078500003E088
-:1027F0000200A07C000000000200A0800000A000F9
-:102800000600A084000000050200A0980FE0000070
-:102810000600A09C000000140200A0EC555400002B
-:102820000200A0F0555555550200A0F40000555582
-:102830000200A0F8000000000200A0FC55540000B7
-:102840000200A100555555550200A1040000555540
-:102850000200A108000000000200A22C00000000FD
-:102860000600A230000000030200A0600000000784
-:102870000200A10CBF5C00000200A110FFF51FEFD9
-:102880000200A1140000FFFF0200A118500003E0A5
-:102890000200A11C000000000200A1200000A00016
-:1028A0000600A124000000050200A1380FE000008E
-:1028B0000600A13C000000140200A18C5554000049
-:1028C0000200A190555555550200A19400005555A0
-:1028D0000200A198000000000200A19C55540000D5
-:1028E0000200A1A0555555550200A1A40000555560
-:1028F0000200A1A8000000000200A23C00000000AD
-:102900000600A240000000030200A06400000007CF
-:1029100000000000000000000000002E0000000089
-:1029200000000000000000000000000000000000A7
-:102930000000000000000000000000000000000097
-:102940000000000000000000000000000000000087
-:102950000000000000000000000000000000000077
-:102960000000000000000000000000000000000067
-:10297000002E0050000000000000000000000000D9
-:102980000000000000000000000000000000000047
-:102990000000000000000000000000000050008D5A
-:1029A0000000000000000000000000000000000027
-:1029B0000000000000000000000000000000000017
-:1029C0000000000000000000008D009200920096C0
-:1029D0000096009A000000000000000000000000C7
-:1029E00000000000000000000000000000000000E7
-:1029F00000000000009A00DB00DB00E900E900F7BE
-:102A000000000000000000000000000000000000C6
-:102A100000000000000000000000000000000000B6
-:102A200000000000000000000000000000000000A6
-:102A30000000000000000000000000000000000096
-:102A40000000000000000000000000000000000086
-:102A50000000000000000000000000000000000076
-:102A60000000000000000000000000000000000066
-:102A70000000000000000000000000000000000056
-:102A80000000000000000000000000000000000046
-:102A90000000000000000000000000000000000036
-:102AA0000000000000000000000000000000000026
-:102AB0000000000000000000000000000000000016
-:102AC0000000000000000000000000000000000006
-:102AD00000F700FE00000000000000000000000001
-:102AE00000000000000000000000000000000000E6
-:102AF00000000000000000000000000000000000D6
-:102B000000000000000000000000000000000000C5
-:102B100000000000000000000000000000000000B5
-:102B2000000000000000000000FE01030103010E90
-:102B3000010E01190000000000000000000000006C
-:102B40000000000000000000000000000000000085
-:102B50000000000000000000000000000000000075
-:102B60000000000000000000000000000000000065
-:102B70000000000000000000000000000000000055
-:102B80000119011A00000000000000000000000010
-:102B90000000000000000000000000000000000035
-:102BA000000000000000000000000000011A0152B7
-:102BB0000000000000000000000000000000000015
-:102BC0000000000000000000000000000000000005
-:102BD000000000000000000001520176000000002B
-:102BE00000000000000000000000000000000000E5
-:102BF00000000000000000000000000000000000D5
-:102C000000000000017601B5000000000000000097
-:102C100000000000000000000000000000000000B4
-:102C200000000000000000000000000000000000A4
-:102C300001B501F0000000000000000000000000ED
-:102C40000000000000000000000000000000000084
-:102C500000000000000000000000000001F002354C
-:102C6000023502380238023B00000000000000007C
-:102C70000000000000000000000000000000000054
-:102C80000000000000000000023B02760276028095
-:102C90000280028A00000000000000000000000026
-:102CA0000000000000000000000000000000000024
-:102CB00000000000028A028B0000000000000000FB
-:102CC0000000000000000000000000000000000004
-:102CD00000000000000000000000000000000000F4
-:102CE000028B029D000000000000000000000000B8
-:102CF00000000000000000000000000000000000D4
-:102D0000000000000000000000000000029D02B270
-:102D100002B202B502B502B80000000000000000D7
-:102D200000000000000000000000000000000000A3
-:102D3000000000000000000002B802E600000000F1
-:102D40000000000000000000000000000000000083
-:102D50000000000000000000000000000000000073
-:102D60000000000002E6036D00000000000000000B
-:102D70000000000000000000000000000000000053
-:102D80000000000000000000000000000000000043
-:102D9000036D0374037403780378037C0000000060
-:102DA0000000000000000000000000000000000023
-:102DB000000000000000000000000000037C03BBD6
-:102DC00003BB03C303C303CB0000000000000000EB
-:102DD00000000000000000000000000000000000F3
-:102DE000000000000000000003CB041F041F04319A
-:102DF0000431044300000000000000000000000057
-:102E000000000000000000000000000000000000C2
-:102E1000000000000443044D00000000000000001A
-:102E200000000000000000000000000000000000A2
-:102E30000000000000000000000000000000000092
-:102E4000044D0453000000000000000000000000DA
-:102E50000000000000000000000000000000000072
-:102E600000000000000000000000000004530456B1
-:102E70000000000000000000000000000000000052
-:102E80000000000000000000000000000000000042
-:102E900000000000000000000456045B0000000079
-:102EA0000000000000000000000000000000000022
-:102EB0000000000000000000000000000000000012
-:102EC00000000000045B045C045C046E046E04807B
-:102ED00000000000000000000000000000000000F2
-:102EE00000000000000000000000000000000000E2
-:102EF000048004ED0000000000000000000000005D
-:102F000000000000000000000000000000000000C1
-:102F100000000000000000000000000004ED04EECE
-:102F200004EE050205020516000000000000000086
-:102F30000000000000000000000000000000000091
-:102F40000000000000000000000000000000000081
-:102F50000000000000000000000000000000000071
-:102F60000000000000000000000000000000000061
-:102F70000000000000000000000000000000000051
-:102F80000000000000000000000000000000000041
-:102F90000000000000000000000000000000000031
-:102FA000000000000000000000010000000204C05A
-:102FB0000003098000040E4000051300000617C03E
-:102FC00000071C800008214000092600000A2AC0D2
-:102FD000000B2F80000C3440000D3900000E3DC066
-:102FE000000F42800010474000114C00001250C0FA
-:102FF0000013558000145A4000155F00001663C08E
-:103000000017688000186D4000197200001A76C021
-:10301000001B7B80001C8040001D8500001E89C0B5
-:10302000001F8E8000209340000020000000400020
-:1030300000006000000080000000A0000000C00050
-:103040000000E0000001000000012000000140003D
-:1030500000016000000180000001A0000001C0002C
-:103060000001E00000020000000220000002400019
-:1030700000026000000280000002A0000002C00008
-:103080000002E000000300000003200000034000F5
-:1030900000036000000380000003A0000003C000E4
-:1030A0000003E000000400000004200000044000D1
-:1030B00000046000000480000004A0000004C000C0
-:1030C0000004E000000500000005200000054000AD
-:1030D00000056000000580000005A0000005C0009C
-:1030E0000005E00000060000000620000006400089
-:1030F00000066000000680000006A0000006C00078
-:103100000006E00000070000000720000007400064
-:1031100000076000000780000007A0000007C00053
-:103120000007E00000080000000820000008400040
-:1031300000086000000880000008A0000008C0002F
-:103140000008E0000009000000092000000940001C
-:1031500000096000000980000009A0000009C0000B
-:103160000009E000000A0000000A2000000A4000F8
-:10317000000A6000000A8000000AA000000AC000E7
-:10318000000AE000000B0000000B2000000B4000D4
-:10319000000B6000000B8000000BA000000BC000C3
-:1031A000000BE000000C0000000C2000000C4000B0
-:1031B000000C6000000C8000000CA000000CC0009F
-:1031C000000CE000000D0000000D2000000D40008C
-:1031D000000D6000000D8000000DA000000DC0007B
-:1031E000000DE000000E0000000E2000000E400068
-:1031F000000E6000000E8000000EA000000EC00057
-:10320000000EE000000F0000000F2000000F400043
-:10321000000F6000000F8000000FA000000FC00032
-:10322000000FE0000010000000102000001040001F
-:1032300000106000001080000010A0000010C0000E
-:103240000010E000001100000011200000114000FB
-:1032500000116000001180000011A0000011C000EA
-:103260000011E000001200000012200000124000D7
-:1032700000126000001280000012A0000012C000C6
-:103280000012E000001300000013200000134000B3
-:1032900000136000001380000013A0000013C000A2
-:1032A0000013E0000014000000142000001440008F
-:1032B00000146000001480000014A0000014C0007E
-:1032C0000014E0000015000000152000001540006B
-:1032D00000156000001580000015A0000015C0005A
-:1032E0000015E00000160000001620000016400047
-:1032F00000166000001680000016A0000016C00036
-:103300000016E00000170000001720000017400022
-:1033100000176000001780000017A0000017C00011
-:103320000017E000001800000018200000184000FE
-:1033300000186000001880000018A0000018C000ED
-:103340000018E000001900000019200000194000DA
-:1033500000196000001980000019A0000019C000C9
-:103360000019E000001A0000001A2000001A4000B6
-:10337000001A6000001A8000001AA000001AC000A5
-:10338000001AE000001B0000001B2000001B400092
-:10339000001B6000001B8000001BA000001BC00081
-:1033A000001BE000001C0000001C2000001C40006E
-:1033B000001C6000001C8000001CA000001CC0005D
-:1033C000001CE000001D0000001D2000001D40004A
-:1033D000001D6000001D8000001DA000001DC00039
-:1033E000001DE000001E0000001E2000001E400026
-:1033F000001E6000001E8000001EA000001EC00015
-:10340000001EE000001F0000001F2000001F400001
-:10341000001F6000001F8000001FA000001FC000F0
-:10342000001FE000002000000020200000204000DD
-:1034300000206000002080000020A0000020C000CC
-:103440000020E000002100000021200000214000B9
-:1034500000216000002180000021A0000021C000A8
-:103460000021E00000220000002220000022400095
-:1034700000226000002280000022A0000022C00084
-:103480000022E00000230000002320000023400071
-:1034900000236000002380000023A0000023C00060
-:1034A0000023E0000024000000242000002440004D
-:1034B00000246000002480000024A0000024C0003C
-:1034C0000024E00000250000002520000025400029
-:1034D00000256000002580000025A0000025C00018
-:1034E0000025E00000260000002620000026400005
-:1034F00000266000002680000026A0000026C000F4
-:103500000026E000002700000027200000274000E0
-:1035100000276000002780000027A0000027C000CF
-:103520000027E000002800000028200000284000BC
-:1035300000286000002880000028A0000028C000AB
-:103540000028E00000290000002920000029400098
-:1035500000296000002980000029A0000029C00087
-:103560000029E000002A0000002A2000002A400074
-:10357000002A6000002A8000002AA000002AC00063
-:10358000002AE000002B0000002B2000002B400050
-:10359000002B6000002B8000002BA000002BC0003F
-:1035A000002BE000002C0000002C2000002C40002C
-:1035B000002C6000002C8000002CA000002CC0001B
-:1035C000002CE000002D0000002D2000002D400008
-:1035D000002D6000002D8000002DA000002DC000F7
-:1035E000002DE000002E0000002E2000002E4000E4
-:1035F000002E6000002E8000002EA000002EC000D3
-:10360000002EE000002F0000002F2000002F4000BF
-:10361000002F6000002F8000002FA000002FC000AE
-:10362000002FE0000030000000302000003040009B
-:1036300000306000003080000030A0000030C0008A
-:103640000030E00000310000003120000031400077
-:1036500000316000003180000031A0000031C00066
-:103660000031E00000320000003220000032400053
-:1036700000326000003280000032A0000032C00042
-:103680000032E0000033000000332000003340002F
-:1036900000336000003380000033A0000033C0001E
-:1036A0000033E0000034000000342000003440000B
-:1036B00000346000003480000034A0000034C000FA
-:1036C0000034E000003500000035200000354000E7
-:1036D00000356000003580000035A0000035C000D6
-:1036E0000035E000003600000036200000364000C3
-:1036F00000366000003680000036A0000036C000B2
-:103700000036E0000037000000372000003740009E
-:1037100000376000003780000037A0000037C0008D
-:103720000037E0000038000000382000003840007A
-:1037300000386000003880000038A0000038C00069
-:103740000038E00000390000003920000039400056
-:1037500000396000003980000039A0000039C00045
-:103760000039E000003A0000003A2000003A400032
-:10377000003A6000003A8000003AA000003AC00021
-:10378000003AE000003B0000003B2000003B40000E
-:10379000003B6000003B8000003BA000003BC000FD
-:1037A000003BE000003C0000003C2000003C4000EA
-:1037B000003C6000003C8000003CA000003CC000D9
-:1037C000003CE000003D0000003D2000003D4000C6
-:1037D000003D6000003D8000003DA000003DC000B5
-:1037E000003DE000003E0000003E2000003E4000A2
-:1037F000003E6000003E8000003EA000003EC00091
-:10380000003EE000003F0000003F2000003F40007D
-:10381000003F6000003F8000003FA000003FC0006C
-:10382000003FE000003FE00100000000000001FF59
-:103830000000020000007FF800007FF80000026F27
-:1038400000001500000000010000000300BEBC20C5
-:103850000000000300BEBC2000000001FFFFFFFFCE
-:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
-:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
-:1038800000000000FFFFFFFF00000000FFFFFFFF40
-:103890000000000300BEBC20FFFFFFFF000000008F
-:1038A000FFFFFFFF00000000FFFFFFFF000000031D
-:1038B00000BEBC2000002000000040C0000061806D
-:1038C000000082400000A3000000C3C00000E480AC
-:1038D0000001054000012600000146C0000167808C
-:1038E000000188400001A9000001C9C00001EA8070
-:1038F00000020B4000022C0000024CC000026D8050
-:1039000000028E400002AF000002CFC00002F08033
-:103910000003114000033200000352C00003738013
-:10392000000394400003B5000003D5C00003F680F7
-:103930000004174000043800000458C000047980D7
-:1039400000049A400000800000010380000187000D
-:1039500000020A8000028E0000031180000395001F
-:103960000004188000049C0000051F800005A300CF
-:10397000000626800006AA0000072D800007B1007F
-:10398000000834800008B80000093B800009BF002F
-:10399000000A4280000AC600000B4980000BCD00DF
-:1039A000000C5080000CD400000D5780000DDB008F
-:1039B00000007FF800007FF800000174000015008F
-:1039C0000000190000000000FFFFFFFF40000000A2
-:1039D00040000000400000004000000040000000E7
-:1039E00040000000400000004000000040000000D7
-:1039F00040000000400000004000000040000000C7
-:103A000040000000400000004000000040000000B6
-:103A100040000000400000004000000040000000A6
-:103A20004000000040000000400000004000000096
-:103A30004000000040000000400000004000000086
-:103A400040000000400000004000000000007FF83F
-:103A500000007FF80000050900003500FFFFFFFFB0
-:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
-:103A7000FFFFFFFFFFFFFFFFFFFFFFFF4000000012
-:103A80004000000040000000400000004000000036
-:103A90004000000040000000400000004000000026
-:103AA0004000000040000000400000004000000016
-:103AB0004000000040000000400000004000000006
-:103AC00040000000400000004000000040000000F6
-:103AD00040000000400000004000000040000000E6
-:103AE00040000000400000004000000040000000D6
-:103AF00040000000400000004000000000001000F6
-:103B000000002080000031000000418000005200D1
-:103B100000006280000073000000838000009400B9
-:103B20000000A4800000B5000000C5800000D600A1
-:103B30000000E6800000F700000107800001180087
-:103B400000012880000139000001498000015A006D
-:103B500000016A8000017B0000018B8000019C0055
-:103B60000001AC800001BD000001CD800001DE003D
-:103B70000001EE800001FF0000007FF800007FF8E8
-:103B8000000004480000150010000000000028ADEF
-:103B90000000000000010001000D0205CCCCCCC1EA
-:103BA000FFFFFFFFFFFFFFFF7058103C0000000009
-:103BB0000000000000000001CCCC0201CCCCCCCC39
-:103BC00000000000FFFFFFFF400000004000000079
-:103BD00040000000400000004000000040000000E5
-:103BE00040000000400000004000000040000000D5
-:103BF00040000000400000004000000040000000C5
-:103C000040000000400000004000000040000000B4
-:103C100040000000400000004000000040000000A4
-:103C20004000000040000000400000004000000094
-:103C30004000000040000000400000004000000084
-:103C40004000000040000000000E01B7011600D641
-:103C50000000FFFF000000000000FFFF0000000068
-:103C60000000FFFF000000000000FFFF0000000058
-:103C70000000FFFF000000000000FFFF0000000048
-:103C80000000FFFF000000000000FFFF0000000038
-:103C90000010000000000000007201BB012300F3CF
-:103CA0000000FFFF000000000000FFFF0000000018
-:103CB0000000FFFF000000000000FFFF0000000008
-:103CC0000000FFFF000000000000FFFF00000000F8
-:103CD0000000FFFF000000000000FFFF00000000E8
-:103CE0000010000000000000FFFFFFF3318FFFFF16
-:103CF0000C30C30CC30C30C3CF3CF300F3CF3CF308
-:103D00000000CF3CCDCDCDCDFFFFFFF130EFFFFF69
-:103D10000C30C30CC30C30C3CF3CF300F3CF3CF3E7
-:103D20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD3
-:103D30000C30C30CC30C30C3CF3CF300F3CF3CF3C7
-:103D40000002CF3CCDCDCDCDFFFFF4061CBFFFFF61
-:103D50000C30C305C30C30C3CF300014F3CF3CF399
-:103D60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA4
-:103D70000C30C30CC30C30C3CF3CF300F3CF3CF387
-:103D80000008CF3CCDCDCDCDFFFFFFFA302FFFFF98
-:103D90000C30C30CC30C30C3CF3CF300F3CF3CF367
-:103DA0000010CF3CCDCDCDCDFFFFFFF731EFFFFFB2
-:103DB0000C30C30CC30C30C3CF3CF300F3CF3CF347
-:103DC0000020CF3CCDCDCDCDFFFFFFF5302FFFFF45
-:103DD0000C30C30CC30C30C3CF3CF300F3CF3CF327
-:103DE0000040CF3CCDCDCDCDFFFFFFF3318FFFFFA6
-:103DF0000C30C30CC30C30C3CF3CF300F3CF3CF307
-:103E00000000CF3CCDCDCDCDFFFFFFF1310FFFFF47
-:103E10000C30C30CC30C30C3CF3CF300F3CF3CF3E6
-:103E20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD2
-:103E30000C30C30CC30C30C3CF3CF300F3CF3CF3C6
-:103E40000002CF3CCDCDCDCDFFFFF4061CBFFFFF60
-:103E50000C30C305C30C30C3CF300014F3CF3CF398
-:103E60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA3
-:103E70000C30C30CC30C30C3CF3CF300F3CF3CF386
-:103E80000008CF3CCDCDCDCDFFFFFFFA302FFFFF97
-:103E90000C30C30CC30C30C3CF3CF300F3CF3CF366
-:103EA0000010CF3CCDCDCDCDFFFFFFF730EFFFFFB2
-:103EB0000C30C30CC30C30C3CF3CF300F3CF3CF346
-:103EC0000020CF3CCDCDCDCDFFFFFFF5304FFFFF24
-:103ED0000C30C30CC30C30C3CF3CF300F3CF3CF326
-:103EE0000040CF3CCDCDCDCDFFFFFFF331EFFFFF45
-:103EF0000C30C30CC30C30C3CF3CF300F3CF3CF306
-:103F00000000CF3CCDCDCDCDFFFFFFF1310FFFFF46
-:103F10000C30C30CC30C30C3CF3CF300F3CF3CF3E5
-:103F20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD1
-:103F30000C30C30CC30C30C3CF3CF300F3CF3CF3C5
-:103F40000002CF3CCDCDCDCDFFFFF4061CBFFFFF5F
-:103F50000C30C305C30C30C3CF300014F3CF3CF397
-:103F60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA2
-:103F70000C30C30CC30C30C3CF3CF300F3CF3CF385
-:103F80000008CF3CCDCDCDCDFFFFFFFA302FFFFF96
-:103F90000C30C30CC30C30C3CF3CF300F3CF3CF365
-:103FA0000010CF3CCDCDCDCDFFFFFF97056FFFFFBC
-:103FB0000C30C30CC30C30C3CF3CC000F3CF3CF378
-:103FC0000020CF3CCDCDCDCDFFFFFFF5310FFFFF62
-:103FD0000C30C30CC30C30C3CF3CF300F3CF3CF325
-:103FE0000040CF3CCDCDCDCDFFFFFFF3320FFFFF23
-:103FF0000C30C30CC30C30C3CF3CF300F3CF3CF305
-:104000000000CF3CCDCDCDCDFFFFFFF1310FFFFF45
-:104010000C30C30CC30C30C3CF3CF300F3CF3CF3E4
-:104020000001CF3CCDCDCDCDFFFFFFF6305FFFFFD0
-:104030000C30C30CC30C30C3CF3CF300F3CF3CF3C4
-:104040000002CF3CCDCDCDCDFFFFF4061CBFFFFF5E
-:104050000C30C305C30C30C3CF300014F3CF3CF396
-:104060000004CF3CCDCDCDCDFFFFFFF2304FFFFFA1
-:104070000C30C30CC30C30C3CF3CF300F3CF3CF384
-:104080000008CF3CCDCDCDCDFFFFFF8A042FFFFF31
-:104090000C30C30CC30C30C3CF3CC000F3CF3CF397
-:1040A0000010CF3CCDCDCDCDFFFFFF9705CFFFFF5B
-:1040B0000C30C30CC30C30C3CF3CC000F3CF3CF377
-:1040C0000020CF3CCDCDCDCDFFFFFFF5310FFFFF61
-:1040D0000C30C30CC30C30C3CF3CF300F3CF3CF324
-:1040E0000040CF3CCDCDCDCDFFFFFFF3300FFFFF24
-:1040F0000C30C30CC30C30C3CF3CF300F3CF3CF304
-:104100000000CF3CCDCDCDCDFFFFFFF1300FFFFF45
-:104110000C30C30CC30C30C3CF3CF300F3CF3CF3E3
-:104120000001CF3CCDCDCDCDFFFFFFF6305FFFFFCF
-:104130000C30C30CC30C30C3CF3CF300F3CF3CF3C3
-:104140000002CF3CCDCDCDCDFFFFF4061CBFFFFF5D
-:104150000C30C305C30C30C3CF300014F3CF3CF395
-:104160000004CF3CCDCDCDCDFFFFFFF2304FFFFFA0
-:104170000C30C30CC30C30C3CF3CF300F3CF3CF383
-:104180000008CF3CCDCDCDCDFFFFFFFA302FFFFF94
-:104190000C30C30CC30C30C3CF3CF300F3CF3CF363
-:1041A0000010CF3CCDCDCDCDFFFFFF97040FFFFF1B
-:1041B0000C30C30CC30C30C3CF3CC000F3CF3CF376
-:1041C0000020CF3CCDCDCDCDFFFFFFF5300FFFFF61
-:1041D0000C30C30CC30C30C3CF3CF300F3CF3CF323
-:1041E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF57
-:1041F0000C30C30CC30C30C3CF3CF3CCF3CF3CF337
-:104200000000CF3CCDCDCDCDFFFFFFFF30CFFFFF76
-:104210000C30C30CC30C30C3CF3CF3CCF3CF3CF316
-:104220000001CF3CCDCDCDCDFFFFFFFF30CFFFFF55
-:104230000C30C30CC30C30C3CF3CF3CCF3CF3CF3F6
-:104240000002CF3CCDCDCDCDFFFFFFFF30CFFFFF34
-:104250000C30C30CC30C30C3CF3CF3CCF3CF3CF3D6
-:104260000004CF3CCDCDCDCDFFFFFFFF30CFFFFF12
-:104270000C30C30CC30C30C3CF3CF3CCF3CF3CF3B6
-:104280000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEE
-:104290000C30C30CC30C30C3CF3CF3CCF3CF3CF396
-:1042A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC6
-:1042B0000C30C30CC30C30C3CF3CF3CCF3CF3CF376
-:1042C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF96
-:1042D0000C30C30CC30C30C3CF3CF3CCF3CF3CF356
-:1042E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF56
-:1042F0000C30C30CC30C30C3CF3CF3CCF3CF3CF336
-:104300000000CF3CCDCDCDCDFFFFFFFF30CFFFFF75
-:104310000C30C30CC30C30C3CF3CF3CCF3CF3CF315
-:104320000001CF3CCDCDCDCDFFFFFFFF30CFFFFF54
-:104330000C30C30CC30C30C3CF3CF3CCF3CF3CF3F5
-:104340000002CF3CCDCDCDCDFFFFFFFF30CFFFFF33
-:104350000C30C30CC30C30C3CF3CF3CCF3CF3CF3D5
-:104360000004CF3CCDCDCDCDFFFFFFFF30CFFFFF11
-:104370000C30C30CC30C30C3CF3CF3CCF3CF3CF3B5
-:104380000008CF3CCDCDCDCDFFFFFFFF30CFFFFFED
-:104390000C30C30CC30C30C3CF3CF3CCF3CF3CF395
-:1043A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC5
-:1043B0000C30C30CC30C30C3CF3CF3CCF3CF3CF375
-:1043C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF95
-:1043D0000C30C30CC30C30C3CF3CF3CCF3CF3CF355
-:1043E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF55
-:1043F0000C30C30CC30C30C3CF3CF3CCF3CF3CF335
-:104400000000CF3CCDCDCDCDFFFFFFFF30CFFFFF74
-:104410000C30C30CC30C30C3CF3CF3CCF3CF3CF314
-:104420000001CF3CCDCDCDCDFFFFFFFF30CFFFFF53
-:104430000C30C30CC30C30C3CF3CF3CCF3CF3CF3F4
-:104440000002CF3CCDCDCDCDFFFFFFFF30CFFFFF32
-:104450000C30C30CC30C30C3CF3CF3CCF3CF3CF3D4
-:104460000004CF3CCDCDCDCDFFFFFFFF30CFFFFF10
-:104470000C30C30CC30C30C3CF3CF3CCF3CF3CF3B4
-:104480000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEC
-:104490000C30C30CC30C30C3CF3CF3CCF3CF3CF394
-:1044A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC4
-:1044B0000C30C30CC30C30C3CF3CF3CCF3CF3CF374
-:1044C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF94
-:1044D0000C30C30CC30C30C3CF3CF3CCF3CF3CF354
-:1044E0000040CF3CCDCDCDCD000C0000000700C07A
-:1044F00000028130000B81580002021000010230DE
-:10450000000F024000010330000C0000000800C052
-:1045100000028140000B816800020220000102407D
-:1045200000070250000202C0000F0000000800F067
-:1045300000028170000B819800020250000102709D
-:10454000000B828000080338001000000008010002
-:1045500000028180000B81A80002026000018280BD
-:10456000000E82980008038000028000000B802863
-:10457000000200E0000101000000811000000118AD
-:10458000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6B
-:1045900000002000CCCCCCCCCCCCCCCCCCCCCCCC6B
-:1045A000CCCCCCCC00002000CCCCCCCCCCCCCCCC5B
-:1045B000CCCCCCCCCCCCCCCC00002000000000007B
-:1045C0001F8B080000000000000BFB51CFC0F00360
-:1045D0008A7BD81818F67020F843015F646260B8CF
-:1045E0000CC45781588099812198918121849178B8
-:1045F000FD71A208F61321A019C240330419184E08
-:104600000B23C40F02D5988830307C878A5503D994
-:104610000CA2D471FF40E375529862AB2510ECF503
-:1046200058E491F10634792E4954FE4602FA071AED
-:10463000DF5744E50B2940E86CA8F803347961A8FA
-:10464000FC79A8BF1E2A6237F702541E005BBBD25A
-:1046500053600300000000000000000000000000A4
-:104660001F8B080000000000000BED7D0B7854D577
-:10467000B5F03E73CE9C9949662627214F1E6112E4
-:1046800020028638BC0228B74E480850691D6C5578
-:10469000B468070810F296A297D6F6CB04428C8035
-:1046A00036F8FB408B3ABC2A2A6AC048510187A7DA
-:1046B000E8F5F606AB9656EB8D68519147E456A5A2
-:1046C000FF6DAFFF5A6BEF9D39673201ECD77BFF6F
-:1046D000FBDFEF8F9FDF619FBDCFDE6BAFD75E6BE0
-:1046E000EDB5F7D86D1EA65FCDD8D7F807CF7A1BEA
-:1046F000632C23F67CC4CE7E18743356B0CEB7C27A
-:104700009D0EEF77E56D4FF63196B37BAD3205DE4A
-:10471000E7AC6F53E615C6BE0FB8A0723CBCDFB560
-:10472000562981F7396FB42973F1E9B0B14E68CFDA
-:10473000345F0AC3270B3096C9D890894CFC05DC3E
-:1047400039C58C0DC47F4217E78C64C6C63196B755
-:10475000D216092BF03E5439937919DB0470E5A485
-:10476000C177EA5FF6D9B16D8376BCCBC998537334
-:104770006A5FE733963B9BD9183C072FE3EFF1EFD5
-:104780006BF83F2F6C2D0F61A6721E963DE92760D6
-:1047900048E6619EAFD544F076EBC151B179CAE7E6
-:1047A000FA465FA65BEBFD5E3E97DCF6897E177CE2
-:1047B000FD18B61BCA5824AE7D6D58D7D815F00425
-:1047C00004B417F6FE7E262B29463ADCCAA6D0B3DF
-:1047D0005EF3DD8878A93F62676180BBBEE1443942
-:1047E00096D92E850DCBEBFDFD2866277A943045B2
-:1047F0003B81F3F5322FCE4FADF13D540E786E482C
-:104800000E9461BF0F2787E829DF67CF9B9E1D02AB
-:10481000784A17158619D0FDDC3AC5EF80CF3F5690
-:1048200022BA1DE851FDFD86A269D0EE6D3D740DE2
-:104830007EB7488DB6D861FCDA390D054001D6A99E
-:1048400073FE19BCABE4530DE83698B1704A1AD226
-:1048500085B1E3263AE0DFF1E1A2ACF68DC78B3DEE
-:104860002BB01F0D7B89D07CE5FBBCF0912143E38D
-:10487000C663C5040F433819EB5212D175F08B256E
-:1048800047B4A2BEC7FBCF9F4798CB21E00EE95BA0
-:10489000EBD123CB01BFA52FD8A357033D6A3728FF
-:1048A0001107946D7B5D01A4CF99CD5006BA443DAC
-:1048B0003AB53F6D38A95CEFE8BCF72A2877BFA06E
-:1048C000B28DD8EDF0241BCADD09013B1B0765C082
-:1048D000C742172FD66ED8772BF657B9CBC15C4895
-:1048E000CF17177DF72A282F027EC326B55B9AF4CF
-:1048F000FE505E1C51DAB17C760A23FE08A7E991CE
-:104900002D30DE596F67E6F5202F271B9DCC07A0C1
-:10491000ACF074667E1FF8A82AB2BD1CBFABDAA645
-:10492000F811EDA52F6C399C83F37A12F80AF8A8D8
-:104930007A6B32F349FCC1FF27602A5743FD129876
-:1049400027CAFF22D656CE541C7FADEEF3C4F075B5
-:10495000B2D1A0717AE4E9491807BEAB7B56F1E306
-:1049600014EB6C2C847275E645D7EC4D6E9C5F930E
-:104970005EE0C179DDA563BB4591B93B5165554505
-:1049800036E8E5505FB57E83BEB010F1067AAF1011
-:10499000E1EA67856B9D1A40FC2E49756E54013F14
-:1049A000CC1DC8BE2E01FF9C6C043556102B57A1A0
-:1049B0007C933E89E8B34CEDCB9554E2D7EAAD2A1F
-:1049C000F359F889D33F7C94D33FBCC713D99217CE
-:1049D000A3DF1283EB4949BF25A9829E5A77712232
-:1049E00078EE457A003C6D882F78AE11F07927B3C8
-:1049F000120DE8E20D30436117E7CF363B9BCB60E9
-:104A0000EC37D982803609CA3ABB8DF91933B4DA4A
-:104A1000401994FFC2826FE07C18F3FB8280E71696
-:104A200085CDC6791F4260613E2D393AE1AF6D6A8E
-:104A3000F126551130A76379E12F57E5D1F76FD1F2
-:104A4000F71A7C3FAAEFEF8DF28996EF8DF24AF9C3
-:104A5000FD7BD88E392FFC7D5BF995D6F1CBABE48D
-:104A6000F71FD1F8EE0BC36F4C9B6C1D7F5A0D7D69
-:104A70005FEFE0F4EA4E75463642B9D9E50F684873
-:104A8000378D45F1BD9656B011DBA9921F5867408E
-:104A900085EFDDDB52C7AC6266BE98F2271CCF0300
-:104AA000D262E68B948949167E4C0DA459CAD093E4
-:104AB00071E2F2981E0A789D048FDE5F277D51D245
-:104AC000DF49F0DEB1D745E53BAEE4F0DED1DF4DA6
-:104AD000728630B01C28EBA12B0CD37A04702A2CE0
-:104AE0009BB12F94904B196F7EEFB3E1FB2495356A
-:104AF000E07C921C8CF4D15D79C59BC226FCB40E7F
-:104B000002FA42395DD1391E055EEF1AB4307BAE30
-:104B1000699C9641FAEC8D85FCFD7C378E17CC5450
-:104B2000500FEADD0586BBF7388EFC8996719CB97B
-:104B300095344E5EDC388EDCCAB8719CB3378AF788
-:104B4000629C21171AE7AEFC2BADF3C9ADA2718AA6
-:104B5000E2E7935B15374E129F0FBC17E3F8117F06
-:104B60007DCE67C864EB7C06D7D03857E138E34D7B
-:104B7000F3195C13378E9BC6C1F7380E18523E9658
-:104B8000057477742F24FABFE2227B4177849EC09C
-:104B90007ED9BB2E46FAC407E366A15E81C519E43F
-:104BA0005753D2689C2F9380FE6E339DB93EA22747
-:104BB000E89F05024416018840FFD4091EADD8368F
-:104BC0002BB7099FBB4AB3E7A25D72BFC73F0C4436
-:104BD000E7CCAE527D7E02FB66419BFD4497857F0C
-:104BE00085DE9BC28637C0F81DA86C4CE513A0BFBC
-:104BF00018E8ADE3A0BFF0F9B1B04F3F02FDC674B5
-:104C000033BC4D348F131AC7E389F57C1DF972ED5F
-:104C1000513B187B38CC5B8500F70D621A0BDAC06C
-:104C2000F833C959BDA047F78B8EC846A2476080AC
-:104C30000DF89CADEB07B812EDC0CEFC83B047E198
-:104C40006F800D6CD99B5BB71FC266EF2873072D71
-:104C500081F9CEEE586B1F00E533F6AE5BFD6E5367
-:104C60003FB3EDC771DE4EF80FFBB92964B7D8A783
-:104C70003FA8B4966F89B3576B947C410F31AE2F28
-:104C800062477ADD90C9E1B9059F63B0DA207ADD29
-:104C90006AF06F253CF577DA5994D6A3AE0C5688A6
-:104CA000F8C820BB2824D79538F86EB53B0341A03F
-:104CB000E7AD3F56098FF1F076ED4D0ED8C05EEAB4
-:104CC0005AF76F76B4BF2F06FF0F9759EB59988F9D
-:104CD00027F12AF9E0C6D925FD3E32B5BB2934A318
-:104CE000DF47267EF941E52C4BF996869B2CED7F1C
-:104CF000B86CAEA57E6E78B1A57E7EEB6D96F28225
-:104D0000B61F5BDA2F5AD764A95F1CB9DB525FBDAF
-:104D100075ADA55CDBFEB0A57DFDAE0D967ADBDE44
-:104D200011D7A23CAE785B65689F7DE13E712FDABA
-:104D3000575F189A1FDBD421AF811C7ED2984DFC9F
-:104D40007DB2D147CF33BBC63AD11EAF4F02798671
-:104D5000B57EAFF28770EB64D423D01E74F87EE585
-:104D6000C370189CA7D7141FF1BDBA4E6751605588
-:104D700085A5F5F075B71AABD7BAA07E6CDFF5EA5A
-:104D80003A2D61BDD6A525ECF7ACD25D80F65DF875
-:104D9000770E8676605FF603FC0DC0F5A2AFFA537E
-:104DA0003656D96ED23B27141BF1C10DCA9413A8F5
-:104DB0009F6B742EEF353B72A6A03F58A3470B1A8A
-:104DC000DC1718AF1D80C9C27EF2695E8B230362B7
-:104DD000F24BF41B6291FBA52CF447D4CFA7F6A9A4
-:104DE000A46759F440EEF746E1F88113F89EEDCA46
-:104DF000A0F5F19DC640BF8FC09F3BD6389D9EBF9A
-:104E00006F0CF6FB0874CD7B8DB3A9FC7E63889E86
-:104E10005D8D95F43CDED840F51F352EA3F289C692
-:104E2000303D3F696CA5E7C9C636AA3FD5B88ECAE2
-:104E3000671A23F4ECF103843DCAD285FD27EC7593
-:104E40005839A87C4ECC41857F73BFD59F8D727D2C
-:104E5000CEFD6501DAB9E78E816192C03F94CF78CB
-:104E60007EEB9B7E015AEF174680FE637BD7BB9299
-:104E7000387D5C36369D81FEB97B98CE34183FE98B
-:104E800095CBC95E86F71A237D19F1CFF224E81F6E
-:104E9000E79C75713AF5F0C723FF5E8CF1871B84A0
-:104EA0003E4C3AA03670BA6DF223DD4CF8E376D969
-:104EB0000B429FC7E1916CB99CDEF83C9D21F1D972
-:104EC000998B7180FB95E0081BF0C1B90E07CDEB03
-:104ED000DCEEE408C36F313832E94278E370546F96
-:104EE000751966FD50DB9E6A58F5458E61D617E749
-:104EF0008E6CF2A2DC2FC9B6191F8D45FE0808FE84
-:104F0000E07C27FBAF6DCF33DC967EACE5736DCADA
-:104F100074F48340B9A77C3F817F209F4BB275E337
-:104F20002390EF935B87A4E0B8E0C71938CEA94679
-:104F3000C3E0E3661B66BEAC599644ED257C7DF567
-:104F4000FBF7860F2D830F9D8C50FFF5906FEE675A
-:104F500033ED4F14CF61BBED5FE2BAE380FFBFA634
-:104F600078804665D96F7DBB1A765C81EFB759C6EC
-:104F700083EF7CD287C6F5AA6FBA6BEC84292E50DA
-:104F80008763907FE4243A87A0C714E8EFACE66E0D
-:104F900055609CE9361FD5D70B7EAC7576E9217834
-:104FA00075BA83D3A3AF714E361EF169A03F2A9D17
-:104FB000E091C13895ED23CA503F9EEE58911902F9
-:104FC000BEAD56CFDD114CF07DAB4DE1F044ECDDD4
-:104FD0005DA6F9C8380A63D0AF33063F72FA0953A9
-:104FE000395E5FCBE77DD82FF047DDB6A3E55701EB
-:104FF000FC75BB3ED7118EE9B6D07DB68CD8FC15BA
-:105000009C3FF453B5F5031DE7F7893D5C70E70558
-:10501000F4546F38DDD914B793F0855927DA31F39A
-:105020007AE28ABE1BDF05D1FCF49FEC6C15C0C18F
-:10503000FE02ADA0DE2E6A2B58D08BF89AD7514DC8
-:10504000F1C54F6DD26E6A2B46FE38CD6CD3717EA2
-:10505000A7D99BDEB126FC75D8B8DDCF5AB91D1390
-:1050600086FF101EB0672D76CDA275D6F242765D12
-:1050700026EA8D85F7DB590450B418ED22C91F309C
-:10508000EFCD366EEF2E620D2D68CF690EEE1FCC80
-:1050900033983600E0AAFDD5A3C568F7BF6CB311FD
-:1050A0007D649C61711A87BB2A3DA207A0FEC38E56
-:1050B000B1375C85DCE788B4E0BACC52987F0BEB63
-:1050C0008DCFF9AD56F82E067F3CBC8C2DB7C02194
-:1050D000FB9570A85B95402401DFBD26F94EE89151
-:1050E00034D56AE767C595DFB389F8A5CA54A4F338
-:1050F00069C319B6A550BD3F8AF1911D0EFF0AA0E4
-:10510000EFEDB66017EA67B00B8A98A9DDEDB6102F
-:10511000BD3FA5BCB110ED53A6458BD0BF8735452B
-:10512000437ED0053FA849DE228CC77A18AC9F2069
-:10513000970E840FFA69F154CE6445187F053985BE
-:10514000FEEEF1961F51A0EC727730ECCF916D8D91
-:105150002FBB7CD6723DFE03E9309C511C2779B8E9
-:10516000B51E162C86FCE6F15BDFFFEF1E3C458981
-:105170006FBDC4D2F074BAA32A8CCF266AA7CC76AE
-:10518000739D93C34F7E39B45F2AECF93AE60B5313
-:105190009C389BF3C1D219368267A9C7E70F43BD7C
-:1051A000A20518CA1FC6AACDEB58FD7910B97EA674
-:1051B000B2D6AD235FD69FD75804F47D912DE4512C
-:1051C000C723FE0264E73A01595F03C89A7BBAC558
-:1051D000EE6503D3C4FA3AD030CBEB40A4F3F81811
-:1051E0009DA55EB00BBD08FA224BCD403DD85D4E6B
-:1051F0007E09EB223D21DBE9B17603118EBEDAB9DF
-:1052000062EDF212F557FBAB67768601FF55CF3D95
-:10521000E005E2B34FB5B64C3FBCAFD9B2D28B7C00
-:10522000FC8916F6E2BC3F8DA8D313F1F30DAA2238
-:10523000FCB1805B417F58D0E9E453ABBF8B78FF72
-:10524000728BDDC026F55B1D510710B1AE6331E7EF
-:10525000A7AD8E0F78F9AECF919EF5BBACF256F5A7
-:10526000C4039918EF040C71BF9145C97EAEDBFCF5
-:10527000C772B447EA5937E989F8EF70FCF369B4AB
-:105280007ECDD5537AD7CBFD977AC1F7F51DAB3FCD
-:1052900057BD58B6CA77A5F047A6A99E748A2B4D6C
-:1052A0006013906E120F2CC2EDE1154F3E54F401C5
-:1052B000C0716AF33F79154BDC88EB8773EDF31F00
-:1052C0007FC9D7B75E3F23FCF9D87711FACEB78BE9
-:1052D000DBEF6C377FD6D8A35EF4976A36D8FD2013
-:1052E00099ACE6994DBF7C04F9FA770E8A33543FA6
-:1052F00073E89D2BA15CBDDD9E3E934FC3AD64C69C
-:10530000E8510FFF2F1B13C37FD5F38774DF28FEEF
-:10531000FEA769313A546FDFA7B351BDF156DABE2B
-:105320004FEF7227A047FB07E5686FAF78F22B1DA0
-:10533000E5EAD3BD0ACBCAEBFD7DE5864364CF2108
-:105340009E887E823E3DF4EA45A7E8775F1A47EDE6
-:105350000C5CBFFAA2D3485CFB32888F9F7D09E3C7
-:10536000F7BF77F871FE95CFFEC88BF3F8586BE066
-:10537000FCFCE8CACC008C5B690F671AF4E4EF2BE5
-:105380001FBB9DF86CD1D1DB33291EC00239365AC0
-:1053900043C33938BF05EBAFA7F92D6421E2B7CA83
-:1053A00047D56004E3591A9BBE3D813CBC21E4E132
-:1053B000E38D0E5C7BD8C7A860D13F7C53A57D02EE
-:1053C000C66EA378C3ED721F822DA1F2174E4EA7B1
-:1053D0004DAA4DC6379C163EDD7C5727D2E7E4A088
-:1053E0004016C627010F61812F05F58E7A746A1663
-:1053F000A70FF369C5E23BD08BA5F81EDB77DA0374
-:10540000AE22CB77621DE3E32F15E303DC49688FFF
-:105410007D9C09F64D82F97DA54ABD0CF68689BFB3
-:105420004C72CDE57CF3DD5CAEA59C47664DC7FABA
-:105430003FBDC5E507BFC3751DE08A6651FDBEEFE0
-:105440002BA4071C2C9A489E37DB853C5BEBE5FEC2
-:1054500024C0ADE1FA14E313E83F8DF04F76DAC2D1
-:10546000FBE13B935EAEC7F1A89D1E7B6F5AD71739
-:1054700009F97F5515FBA342FED97A2EF77DDBBDD6
-:1054800061EE1FD823BF7C04E515E413D7999A6712
-:10549000EC419CF767DB0EBC7333F0F567ED524EC1
-:1054A000AD7A335E4E2B778C6789E4F433B79F2552
-:1054B0009453789F504EDD5DC4C7FFD97A53E2ED17
-:1054C0004C9CDE947AB02FFCC5EBC135AA2FA11EEF
-:1054D00084BFB758716FBE93FC26F9ACEAE9DAC114
-:1054E000143792FC28F9AD871F25BFC5CFD38AB7E3
-:1054F000F8FA1785BE9174B62F67610FC64BF7A8EF
-:10550000E45F9F05985A80BE67B7E54530EEBCD290
-:10551000C5E317678D6E6F1A3C57A6F2727786DE69
-:1055200082FA41BEEF76F1F8F6D960B737D5E45785
-:105530007CB05BF5FAA0BE2BC2A627F23740F3126F
-:105540001C5DACAF7A1E0F9EAABA7397A1DFDEA6D0
-:10555000D27E7645D38D5EDC073EBB7BC8CF513F04
-:105560002D780D0C4C80F72CDA812938BD80867996
-:1055700009F305BD3F61E10727C3FCE6EFE6FE4204
-:10558000C59A38FBDEBD54477D03F6FD716B5C9B0D
-:10559000F34D95E8A772BDB5BE8AAD21BA55C5F1E8
-:1055A0005148F8811334C147A3D968E187F1F885E0
-:1055B000D05753D5C29FA39D71F6088F2B9EDBADAC
-:1055C00012FECF6D532218F7A1F8EE24A47FB7CEB8
-:1055D0004CFEF229E437BD6F393EF5C21F8AEF84D5
-:1055E00026353BDF2DFA053C4FEDFC5DC1CB58FE67
-:1055F000D56F73DF65BDDB97EEFD33ED1F9FDDEBF0
-:105600002038CEEE7D35F74E2CBFE4F0239C679713
-:105610003B68FF2CBCD7131986F58380DEB86EEE8D
-:10562000F9AAA88BD69D66A2D33C8DEF779CDBFDB3
-:10563000EFEF2B987FB0DBE1C379D4EFE57921F56B
-:105640002FB928EE7276CF57C521F7DF6F3E753A36
-:105650000B11FF79D8EC1DC8AFA97C1FA0FEE5494E
-:105660009B9A703FBC639F8EFB2BA5AFFCB508F5E2
-:10567000CBD91DDC4E3863EF7A0CF7416BB5A1CB6B
-:10568000ED28F768B3F507BBD3BE604AB830115EAA
-:10569000381ECE021E705E80974AD48B7DE1A359DE
-:1056A000E3FEE67F3F7C7C7E2B8E5FB37B02C94DA1
-:1056B0000C2F4A80BFF7449C0ACD9FBFDFFB5511DA
-:1056C000DA3D9FB537D13A7EB1796FFA1F376F2532
-:1056D0007A29F3DEFFDF9CFFA76B7C5D8A9783DE70
-:1056E0007CFEAB3BA8FCACC74FF05EA2FC1FFF9F4B
-:1056F00046F71D4077EFC5E9AED8FFBBCEFB62741D
-:105700007F4DD0DD63605EC1D93D7FA578B99CFF38
-:10571000C5E6EDFB7F74DED2FE5965F3B7E543FBCA
-:10572000352CDAE90338570EBFAE0DC34CE0260422
-:1057300013D923413BF78F5485C761D8201E1762C8
-:10574000C29FA014301FC65116925DA7B95BC8CE88
-:10575000649ABF3300F85835729E9F7235D89863AB
-:10576000212C0F9CECA7F8669C5FA58DFCF611B46C
-:10577000EF9B9B003E18A7D9A319602931FB705BF2
-:10578000D45144CF0FF079978867D90DDDE257B82F
-:10579000E3FC0297CF5AEF10FD3BD97E03F3889CC0
-:1057A0007E8D45B01D6B0B9BF3071CCCF41DD417ED
-:1057B0006200D6643F7E53FC35F5E06F4C6700F124
-:1057C00037C246712D4AEA237CF823AB781E85D375
-:1057D0008ACF964EC4A3C6C0FFE3F322BF91097FD0
-:1057E00051135D68C36D0197B59DF08B2E4A1F4E16
-:1057F0008FDC1A419F25167A48BC5F802E167A48A6
-:10580000FC7E53BAC4D3231EFFDFB7F3B89BA49327
-:1058100025BF2383FB2151F0435EDDB689E21DA73E
-:105820009FFAE0BBC8A7D52FABCC09DF9FD9E661B3
-:1058300051945F2DA2A33F55D5A1268CF34ABBBC42
-:10584000FA390FF179D50E4764267C5FB5F3C32290
-:10585000B29B96771F1E807181A7144EBF7057119F
-:10586000EEDB5569DC3F88EF6FBD9DC7054EBD98E7
-:105870003C1BE30FCA569EAF58D57EA3DD61DA7795
-:10588000FE5F769EF70AED489EC34F2AB4DEF4868B
-:105890008FFB05A79E54387CBBEC11CC7BACDABAED
-:1058A000410FA15FB9F5738A63973EF78CB78BFC04
-:1058B00045D5EA3F6F55899EF024BAC5FBB1751DE9
-:1058C000B5E427D4B50B3F31CE8FAA7E6ECFCE3054
-:1058D000A0A6FAF927BC187F39D9B9C54BFEE956FD
-:1058E000EE7F6A6E2DB17F7A31BFB4FDEE847EE922
-:1058F00049FC07F813FBEC71FEFCD67E97B67FF9E6
-:10590000CC178F619CF4D48ECF1E43B86BFEE3DFBF
-:105910001E43FB9EED75195B60BEF54FBD4DF12634
-:10592000F9DDBB424ECF0C62E11C6877E6770ECA08
-:105930001F39B3E7E35CF4E7CE6CFF7326FAF54B4F
-:10594000F74CCDC2792F7DA1348B259077F944BED9
-:105950008C5C429C309E0E073A0E901F72FA988320
-:10596000FCBE9EF8427B2D8FD7F8445C615BE23829
-:10597000ACF487EB3A3E2CE7F131E1175F2C8EF067
-:1059800016D0F18A4BA0D73611278AA3D769FC0716
-:10599000D0E5AB387A7DC1428FE7E03E6447BF3E39
-:1059A000E308D14BC0938CEF1EB6076C3ACAC18E88
-:1059B000E41E3ACD443A3DF3452EC6C33FB177933A
-:1059C000DDD3BDC761A07F5FB5E7B72417675E3839
-:1059D0004AF15326E2AC6758CF1F8F8B29627E9B1A
-:1059E0003D3CFE20F08DF1099F97DE8B3804E75790
-:1059F000199FE82B2E314117794F22EE5CBBF95DE0
-:105A00009DC5C579948948A70F2CF17139EFF8FE2F
-:105A10000CC4C304737C2D71DC47FACD313AF1B864
-:105A20009A8C9F9DD920E26EF07EE018F407791CD5
-:105A3000A33EA2FC96259043195F1BA3C7C961E44E
-:105A4000D2E26A1783F76FC5C7309DAF0B122FA73D
-:105A5000FE92580F7F47E7723DDD169AA99BF6B379
-:105A60007F28F65924BE24BCA7441EDEA9A7548A69
-:105A700007B5B41F207D1A2FCF757D9C83B855E7DD
-:105A8000F1D6BA5DFB8A50EF9CDAFF22F15DDDB6FC
-:105A90000FF430F47378EBF33AB727399FA39E8E57
-:105AA00098F4F4A967F715F1B81FCFBB8DEFBF5A73
-:105AB000F45FBFDBDA7FFDB6CF2DFD5787DB75BE08
-:105AC0005E5E789C935AE0469CEFC94E3B437D77DF
-:105AD000B25D9D1E496407EA76CB3E68CB519DD6E8
-:105AE000AB716F26517EEED2A3D3DF4DC17D3A104C
-:105AF00033B47F3B9A385F75FC2C3000E9D271F4E7
-:105B00006615D78D9D8847931D5CFC5643A907E415
-:105B1000B5F8BDE03864AB783D30E198CD02378C04
-:105B20009385FAB819FAC17C7ACC1FC2FD51D55BB6
-:105B30003E1DE1510D9BE14AB87EF2FEECEE2043A2
-:105B4000BBDC6E58F395B3AF1371B4A8356F3D5BF2
-:105B500067C3711F9CD992FCB81FB0644460F421E4
-:105B6000CCAB5F904D71E29CEFF1EF4E1BEEB0EDD0
-:105B70008AD8BE6DF279E81FF3606C91B573E0BB13
-:105B800064AD5DC17D007832A4CBEDB6D0463D0357
-:105B9000DBE9CC07AAF1315DD128FF429C7B91FD66
-:105BA000C9767DED07CB7348AA807F88D80F1EC4C5
-:105BB000BA14DC0F5EEFE1E79106BBD3E9BCD12656
-:105BC00061AFF970DF15DB3558D7ED8B9E476AB5AD
-:105BD00096D34B4B6E1BEC073F58BFA354037D90ED
-:105BE0007E63C9F60106EE4BDF5F8A79F7E94F94D1
-:105BF0008CCE81F26C475119D5FF4BC9E85C28FF68
-:105C0000A8755219D5572B9417B847EF2E0DBB63C3
-:105C1000F29901C62DE65B80DCEE47B93D1D3CD50F
-:105C200082B5B5D77FA9F3F3302C88F31F3491CF19
-:105C30007FA0FBBDED38DFC1B6AE26E4BFC7F77C61
-:105C4000958AED7CCCA0791AACD9C07D797835F1F4
-:105C5000EB0BE4FFC4E7C1487E7F2E39F41B84E3DD
-:105C6000EE79C31F2A479D5AE3273E8ADF276646FF
-:105C70003AD1A542D005E1749AF2902BF12402E9C1
-:105C80009B3203C751C235EAD7977F73784E487E5F
-:105C900011E7C04CE7A43E45381F4E0ED133FE9CA1
-:105CA000D47E3DF819F253CEC2F3B908BF3CFF547D
-:105CB000BAC84D718173BB59C491407EE4736323AC
-:105CC000CBD086F65DFFB623F4671C37FF15DF8E59
-:105CD00023D0DF1515BA1F53D7AE58362E431BCB32
-:105CE000F884D09E1074CB465AA27CDDC1F8B91C52
-:105CF000871240BFF1EC8F0CD2BF032B66925F710D
-:105D00003639AF1DF327CEDEC9F300608557500E3C
-:105D100006ED4E89A2FF037CFC651C1F7F695D6751
-:105D2000ACE39EFDDAB7AB8BFA33447F60E864A244
-:105D3000DCF0BFB32AB7B3CF36FA080E300BF7E169
-:105D40007A7AA9E3653BACE7F400EFFD1D26BCE7DA
-:105D50003AFAA45F9E83D38F9EF1F45BE86CC8454A
-:105D600039AE0AB697A36BFAF1C23B8A91A9DFD686
-:105D7000439761FB9AD99D8779CE504301EEB3F5E5
-:105D8000A62F3F8F95B97B6E931DE315481F5F6F5C
-:105D90003A5EB1CC9FA1F5B3D0752CC27FC5EECFD2
-:105DA0006D08BFA4E74322CF3FFEFB6F3914316E6D
-:105DB0004D931DE324BB74B267E3DB4DC74355E34A
-:105DC00063E52267318D9B65E3F18EDEEDF9FA170D
-:105DD000EBD749E7B2FAE2C72283F707F8FFB61913
-:105DE000FFDFED1BFFB3B01DE09F9EDF00FF3762BA
-:105DF000FBBEF02FEDE86AA117AA711F05F8E88F26
-:105E000081EB3287C2F8E5AA9BE460F11695E40FB6
-:105E1000DACFCCC98CE991C5931AF6E17C173FAA79
-:105E200010BF568873A69F89BCFEF87CA885B3C3B3
-:105E3000B4BFD32B2F2A12E7D7C5E5BBD7C7F87657
-:105E400030CF53E3E7B6542117A58B0A53D01EDA9F
-:105E50006BF7FD0BD9D9AFA96C6302FC6F402633F9
-:105E6000D1755083CD9227CB2A522DFD962D2AA491
-:105E70007DEF251EDF05FDAAC1CBACEB765ED87A9F
-:105E8000CE6848ABF59CD1B0B6FE96F697ADCBB7D1
-:105E9000D48F888CB4D45FBE758CA53CAAFD4A4BC8
-:105EA000FB2B764DB1944747BF6D693FF6C8759699
-:105EB000F2F8CE9B2DED271C9B67A99FD45565A9B1
-:105EC000BFEA932596F23F74FFC46AA7D818E94742
-:105ED00096A490BE3CD8383117F3B1D938A50CF14F
-:105EE000592AF2090FDEA6DB0C2F3E0B6C06E8AD3B
-:105EF000FD0B66D2BA7FF0B6CC808F9EC501F46BE5
-:105F0000983A795CA27CCDA9C6A45C735E54A9D3EF
-:105F10006ED16F530D6B79A743ECFB0DE67CF372EA
-:105F20009C7CD91B2647C13264FD170FCDC2F140BE
-:105F3000CEF60A3DB7F792F45C6643319641CE0E39
-:105F400026923326D6D912C14FF00CE8981F59E695
-:105F5000A1F538802F7DF43EAC81BC4C71FA071E50
-:105F6000C279D9FCE9C88465B38307797F625D662D
-:105F7000C36DDF645D96729E6D13F96B693C7FEDB6
-:105F8000E1050529CC84DF3F386CC28E6EE34FE318
-:105F900088AB276F35DFFCFE9324CD942FA72C9A76
-:105FA00049F922D97DE8453D3B7FC666D0C77A8E48
-:105FB0008F9EF27DCB6C5BC23CB06EA147A5BD3518
-:105FC00022666F75233D4E67BFF920E629D5CDE9DE
-:105FD000267B2BDBD676DB619CD7EBAA885FFAF8B1
-:105FE000F92A61272F9871DF6D87715FFA9F87917A
-:105FF0007E92E3AC6F9C3E43339D231FD887DF74B2
-:10600000B993C3F358E3F0191594B76DF0F3A2A256
-:10601000FFDC706D39DACD8345BEE983B6C4F92E55
-:106020006ED14F16921CE135DC2427A717BEE7D5A9
-:10603000601E8FC0EAE5C47DDB2B3A8BB91D16F0DC
-:10604000E339D4DCE82D0F62FBDC6C8DF25DE3C735
-:10605000CF9A136ACDC3F8679ACDEFA672B782EDD7
-:106060001D3F65AC1FB46FFE0F95E069DE3F89F2FE
-:106070003F1CEE0686FBA9725E07D21E21FCA81DFE
-:10608000C9B40E32B12F2EE3AD5F645774A2BDF1D7
-:10609000C5FD761AEF0B98A301FD7FD1A1D2BEEB0F
-:1060A000E1B4A4A80DCA6AAB87D6EF5CB43DA1FDEC
-:1060B000C20E4FC49717C38BB66E329D87710CE426
-:1060C000F36F4E7347DC7934EF749CB78453CE7B07
-:1060D000501F7E6689803BE7B29E731A0CF95835D3
-:1060E00034EA77412A3F8719699C28E8659D4F4B20
-:1060F000F675D7DE84E787DE5219A686F8BADA6825
-:10610000FE0B61FE115F6FFC9EF6E57D695309CEC3
-:106110001284535D574EF3A076F05DEDE30A7B24C5
-:106120000FF930349DE8DADF46E7027BD9074E2EBF
-:106130005F339C3C2F57CF2E98B1B91F3E87925C9E
-:106140007CC7D9E7BA1F74727D44CF6F70BF00ADB2
-:10615000FF521FA9019BB073B95EEAB19FF4D00F43
-:106160009C19B1B29AF2D322ECB76FFB6CFB3E1DC7
-:10617000ED333723FB59EACDBEEC33B4CB90DFA42B
-:106180005DB6386E9E30BF1A31BF9A44F3EBA56FEF
-:106190006F6E9076CD12E705ECCA0C3DB13E7A5297
-:1061A000D0A1DED019C59B688D02BDB3D846E78D5E
-:1061B00099167199CF97AF774ABB6EF73E1DF10CD8
-:1061C000F3463C6783FF5C4E7AC79E302FFC62FE2D
-:1061D00048FEEAC21D47B03FB07311FA736DBE941A
-:1061E000B40BD817F665AFBBCC78BDCF29F2B96335
-:1061F000787C40E0F18184784C073CDA2CF6E1CEE3
-:10620000021FE1F117CE0BD887A7BFF77E31AE474B
-:106210006704BEEA7AFC5CAE9FFBC32285F1AA5AF2
-:10622000CC5F76F232EE07E15E0CC6E18A6CC127E4
-:10623000B0FFFA5DD673873F73F2381973F373B307
-:10624000B2BF4CA1EFC1AFFED61F7DA4F7FF11E78F
-:1062500013F3AFBB8AD1BF5AF1C26529689795ED98
-:10626000BCC9C0E7B9F4A1B49E9DDEE908209CA793
-:10627000D378BEDEE99D130E63FCE1B3C623F96655
-:106280007D7FFAD9A3C576E8E7F48EA3C51AE507A2
-:10629000472C7661EDD7BF29C6735832AFBA875FF6
-:1062A0009C7C9DB8DFC5E31A19997A0BE68B9F4F4A
-:1062B0004A257C3D9069BB3751BC06D527EDDB7B79
-:1062C00074DAA75C32C2B7C28DF19A3C83F2705780
-:1062D00028819C05B8CF32CBE9C77D80F47C363C61
-:1062E0002F055118626EC0A7E3601B1D374DEA34BD
-:1062F000F6A17924E3385A29D7B7DDD7EB9437963E
-:10630000ACF91E9A03E5ECD91AAD7732AEE348E654
-:10631000E792655CA7079ED7ECB40E2DC90BB59527
-:10632000C0774B26A5D177DE59EF10BF9CF5D9C2B7
-:10633000769C8FD64DF19D9F370ECF180A78347218
-:106340006C33C8A6F90B60CB94FFEFD5583805EC39
-:106350009BD5C0FF4381FF3B1A9DD4BE05EC432370
-:106360008DEE4988DDF361929B1D8D06B5FB65635B
-:10637000367D775FA38F9E3D7604E3DF5139817EC2
-:10638000FDCF7ADED3C8EF1391E57F1B07761AD0D5
-:106390003B7D025015F0922ECE9FCBFA471A5F1B21
-:1063A0005236542003F0D9BFC6D8B0EA02F0A63B5B
-:1063B00022A978C4F872170B974DC43CBFEE7BCB73
-:1063C00053F17CC45D656523008FB8BF7D2590CAFD
-:1063D000755F339E4FCDA9F13561DC2F6797D28E63
-:1063E000EB57CEAEB525B88F00EDE8DCA0EC37C397
-:1063F000C5F55CF2818795FC51B8B9C0F7E5D99E27
-:10640000E448A2F3A5E35C5CCFF95D7C7F70B5D86E
-:1064100057EF9EE526BD987CC045FC92B3FB72DA2F
-:10642000DF73F7B1AF1CDF4FF2813F531CD8ADB41F
-:10643000EDC37D4AB680DB9F929FFAFA0EDBEB97A5
-:10644000D0FEAC5FA3B83098BD34BFD3B30612BE44
-:10645000B1BD598F9FD513DB650181A795F6C47136
-:106460007A8DF171C67576D37E26DEDB84F8CE791F
-:10647000AB4D417FFDB4C2F331FA033E764039673C
-:10648000721BDDEBF49C3354EE82EFFE641C2B5840
-:1064900009E0B80A7F9F8BDF497CA845BA13F5490C
-:1064A000CEEE0FF8391F5B978EF96F8BEE7E9EE272
-:1064B0008FAA1ECCE3E5952B313E99E10D6E403E4F
-:1064C00061E1E7CB0E029F3C20CE2DE31BD47BABDA
-:1064D0005DA21C6E6F0E009FACB6F3F2A2BB9F23B1
-:1064E000BE596D0F2EC673CF586E86FE57A7B6677E
-:1064F000DBA0EC6E7AA6F9C8202CCBF6CF34872728
-:10650000831DEA92FA39988378EF291B501E652A79
-:106510006BBCCC9CFC29E7577BE0CF870700BFD43E
-:10652000EDE6F7DCF4E06DD75A05D7A35F361EF130
-:10653000356B424EA4FE8075FEB26C467E8A1E51BB
-:1065400022F90ADEF7D19A69CE57F941B222E21652
-:10655000F0BD39FE1877AE8D8ECAE0FADCCCF3427E
-:10656000E2E9FA7652495B52069E470DAD52510F51
-:106570003E633728AFBE4B23BD7D4AE6D537D8C929
-:106580001EAC11E75CEDCB43AB46A05CDCA2F9315D
-:10659000BE509DD75682F650F58B79FE2616CBD38A
-:1065A000AD4E6DCF1CE38EE5E9CAF20A1197CA4AD7
-:1065B0006D484D2DC4FD98B5B9B85F52C7DA6EFD70
-:1065C00009C2FB86CA90DF3FDD372905EF1DAA858A
-:1065D00032C6C16A3B8EEA2168776512BFEFA6AE6C
-:1065E00003F8C6CDEFA1091430B641339250CFFF66
-:1065F00032D030124DE24DAE5F97B9FE81B127F235
-:106600000306D2F995BB8F353BB1AC1B23D8682C60
-:10661000FF6B33F259F5681BE559B2F0BF1E0C0C45
-:1066200015FBBD506E750D9A6A8E7BE7887386F5F3
-:10663000EBDD741E0CD6E58DC8DF75EB6C61DC3FBD
-:10664000B3393BE91CD02B2E26E8633D3F75BFC212
-:10665000F56178018FA72E9D91F66D3A3FB532DF37
-:10666000085F20AE5B793E89CE49C9F295493EEA82
-:10667000BF520BD33E52E5792F9DAFFAFB8DE7B4A5
-:106680009CD7EA3D9E9BE091E3D5C4C623BA1E1871
-:10669000F3FA8343816E4BB7DB6D0E13DF2DDD2ED6
-:1066A000F6E75D812CEC2743E77866E80F02AFD16F
-:1066B0001D37BC1CD6B241FF4BF90E9F6B2E9B8C35
-:1066C000748BD533ABFC07D01FBF274996FFBDB9EC
-:1066D0006C6082F64971EDF365FFEA4AEC3F1E9E5D
-:1066E0008CA458D909EDB5BF3A7ACA08DF5A5B5C69
-:1066F0007F69B2EC5E89E34BBE6ABD3BFD5018F882
-:10670000EA9ED4B612D4FFDD0B980FEFD1427EF58E
-:106710009BF46DAB8BCB75E5F97C0BBD63782FB02B
-:10672000D0E5E3C66CCBBEE7A2394B697FB6D52571
-:10673000E8C5C2FC9CCDFA012C628A07FD7F38FEB9
-:106740005638AEEC038E6FFD17C3E1B38C1783632D
-:10675000A805BEBF158E8D37147C3B0F9A3CA084D4
-:106760009DF9B82EFC8CE7C5A9A965BE26DC97F972
-:10677000994671FD618CE7BBE46BEC883606E5A7B2
-:106780002D807110B69CDB2BF0BED53E86D621F253
-:106790001786EC76CCC5BC8DFCCAC0627CB2818504
-:1067A000B4EF23F749998813CA7D9E61062BC17BFC
-:1067B000FF8E27CDA5752A3F38A71AE3EAAA675CA2
-:1067C00012AE870FD822611C2F7C1F1F2FC31669A2
-:1067D00077A2BDE41D6AE07A97E1E5FA8FAD2AA4BD
-:1067E000F56FA32D7FE46D00C74AA524E935C47376
-:1067F0006A3EC5C7F13DDEB3B351AC5B6AAADFC0E8
-:10680000756AA358B75608FD2EDF27A705E7A21D16
-:10681000F1F355D3A63A27A11E0AB4F683F5E6DEB6
-:1068200055D356664FC2F5C697EF84F5E5DEA469E9
-:106830002B9D30998D4DBEFE466AAC3CECAFB05AF4
-:10684000939E98B632007AA7D9BDA40AED1CA83F42
-:10685000847EE2136952EFF0FA7CA9A7502F811EC3
-:10686000539B7ACA61D44BF93D7A671AE99DCD8F63
-:10687000A9545E0AE3A11D03F308E3FD60DDC33400
-:10688000F28F5C004B12945D23F269FF0CE6CD920F
-:10689000D0FF1FC1EBE57E873ECC46FB1DD81EF125
-:1068A000E8CAE1EDF559FCBCB4EE7193DF26F74F71
-:1068B00054B17F9724F254146316F9C1CE35639610
-:1068C000A01FE51C6ADD9FD6E3F259D4F8FC1677C9
-:1068D00094ECAEB62411BFEEC7B2E9DE04F11E2C73
-:1068E000E531F8CCBCA9B984EED3F33003F3A9B3F6
-:1068F000435166B697E4D301EBA8CF24370E370B8C
-:1069000024CAA75898CCED61F7798DFB890AD8374E
-:10691000B88E7A841D2EEC23BBBCE7286EDD95F67D
-:10692000925DDCA7B774C6942C3C97A4BA034EB40E
-:1069300073F61963689F4665FE6B4B4CF64E737495
-:1069400006C5273523C0D0CE795DD839AAE1676660
-:106950003BA7A5111C7058AB361517D0FD358FB865
-:10696000A2CE2148DF076C7ED41B07C65485158C48
-:106970004F2E6324A79B8A33A7E03EC3062D98724F
-:106980000BCACB5B309E8FD38DEF73AF50309EFE22
-:1069900085339882FAE09E5466F1A3AE4DE6FEC8B8
-:1069A0009624AE7FA49FD002F044010EEDFC48BABD
-:1069B000CF67B4B04BF53965142FC334208C7F3AC0
-:1069C0005803E587CAFBEA1CD9364BFEA376BE887E
-:1069D000E2895B92F83872DCBBC47D83B2EC640D53
-:1069E0003C6E0C3C9EC87FAB15703AC01EF2917D88
-:1069F00012B7FFDFDB3E227B45D2A7C74E51F8B965
-:106A0000D0BEECA3FAF3368B9E8D9D67D7492F9F9E
-:106A100011F705C83C10B7D0672DD9A1B6ABF2620B
-:106A2000F70368221F648DB81780656BDDE673F885
-:106A3000C9188F81FA669117921C77AEDFE55E4A1E
-:106A4000FE826BB8663907E66421FACEE1B3BED7A1
-:106A5000B2E3EF0B08F7E48151DEA2C61E56E872DE
-:106A6000006EEF0E107958A793DFA77823D8BB07E5
-:106A70009CB42FC1CF89CA78D837B58F5F47BB8AFE
-:106A8000FCC2E9A3B1DF45B81E613C9B0573F8A6C3
-:106A9000633BA3BCA1247F17E3778E91BDA54A3D3C
-:106AA000177EBE19FDA80CB37D67B2D72E5FFD7CA3
-:106AB000737321F91D545E74771BE9C1952E595EDD
-:106AC0004D6558AFA2E8F7B09D0E1FF2137C1F4032
-:106AD000B961371490BDACE6834B0B7097E1FD872D
-:106AE000B83FB0D3B111ED59F06BE7B94C71B2D3E7
-:106AF0009E63B9AC30617F614B7FB9DFAC3F18BF9B
-:106B000003F38C647D99775D54E5DFF9F03B36B093
-:106B1000F3FD30F4FFC00B0EBA9744DEB31CCFAFC9
-:106B20005392B9FF8E7AC39CCFA9CFA90820734A8C
-:106B3000F974642759F2BFA5BC6AE787937CCAEF52
-:106B40005E4FE2FBC79A16A0B89A76BE90E47F8BA0
-:106B5000A06B4BA3719171D2FA18670CF5D3F7387B
-:106B6000C5424F30B13FA619E67B64FA92D7F8FDD3
-:106B7000C078FD269F52BFED15FDCF4DB6C697AB31
-:106B8000D6B51F4616FA892D54913C1EF3BEDEF38E
-:106B9000E2525C638B16A1BCDDDEFB7D1D4EEE4731
-:106BA000224E50B0F5B6FDC8AE0DC9A1F54950AEA4
-:106BB0004A16FB00D9B0AEA9B86EF1BCA587B11ECC
-:106BC000F31B42BE87A6A29E9A554EF1EBE7928335
-:106BD000BFC1EFEEBEAE98620512EED58D3CDF4E22
-:106BE000EA4B37E20BDA3BB4061EF77407A2685F84
-:106BF000DC97FCF6540DF950E372B06CF5FE951875
-:106C000017716A7EE22BA7DBE6C3F5DD09FE1DAE38
-:106C10007B4D6E1BC59356E03DC0F0BE599969A0EF
-:106C2000BC2EF1E467B10BE847ED7CA6D0BFD67B64
-:106C300075FEFEE3A4D3F7BDEEEF3930298AFD6976
-:106C40007E46F93388840F4D7A55AEEBF1DFC5F7F8
-:106C50002FF129F1EBD04284571DED8604703D9948
-:106C60006CDDB7CD92FA33F59D8228BCAD55BABC28
-:106C7000689F805E7C12F9A46E54F7AF151FE9D3AC
-:106C80004C6ECF84E57D0596FB91645C5E7573BBAD
-:106C900046C2BFE4B5079CE67DA77878E3D74B777B
-:106CA000A1353FC3393029EEBEE0263E8E1624BE04
-:106CB000B14F0E38514E9A8C3106DA2BCD9AEFB780
-:106CC00001CA2BB193DD0C76B8657CF9BC47DC0FAB
-:106CD0007C54D851F1F51E719F72FCFBCF85FD707D
-:106CE000CFBE9B480FF7453F3C508DF4F5E433038E
-:106CF000CFE7D805BCDE8BF4DB171FDDBB8FC77574
-:106D0000B589CE08BA58F1E3A9F66000CF93A9A3DC
-:106D100019D9BBEA203E3ED0D2C0B8B0775C1A1B6E
-:106D20006E5A67EF1E7A1DBFDF39C3A0F37DAAC775
-:106D3000164C64674A3C1D4C96F75470BEC9967C4D
-:106D400033ECF7740FBA896FBA13F1CDC164AEAFEB
-:106D5000100E333DEF1E9A9F95883E31BDC8F9EA6B
-:106D6000627CD121EE4BAC45DC807F5323CEDB9F90
-:106D700012F704CD4B16F70519DC2E96F75F7468F1
-:106D80008164B4ABE6F5EC5307E85C4A8D2B903296
-:106D900009F9F228B77B3F2EE1F7967D6C0FA4200E
-:106DA0009E3F3EAA2A4DB4CFCFF302659ED5C7764B
-:106DB000DFEA91503FFF176AA089AAADF6DC2916D9
-:106DC00018FBCF68DFEE5269FF28EFBEB9EA2868EA
-:106DD0005F01861EF2D1BC527718D7DF8EDF37BC39
-:106DE0008F7A68FE630EDF7218E7E0BAB15F62F96E
-:106DF000C41A8FCF4171B27C05EF155FBA36CFA0B0
-:106E0000FDA3654CD81943CB4B8732F614FE53C60D
-:106E10009D9D74CFB8A80FB694C1FC466674D8DCAB
-:106E20000053C41D6CC1734E2B9B82D9E8FF5DBB20
-:106E3000A6A005E38F999981CEAB411FAF5833BC13
-:106E40001CFDC18E47447FE1112DE8EFBD6C0BE5C1
-:106E50002950FFD49A29E594973B44F67F03D5CF78
-:106E60007BFCB22F8F1988D3CA728C9915CF91F001
-:106E7000D49697826E5F30599697E8584E4F669633
-:106E800038983DE64F529CADA3C77FBCA31CE3607E
-:106E9000F3A734946AD07F9EE7A72D85201A13DAD2
-:106EA0004A8C005E99EBB9AF3C39036FCD0B54E3CC
-:106EB0007A32D2737F39CE27BD9FB5FF7455C45344
-:106EC000D9BA16ECAF07BEF0D6168CAFCAF66FDE95
-:106ED000F34E4B78608CEFBF1BBB5FE93BEE0CBA07
-:106EE000B7EE3086D8729775EB3C9F57E4DF0CEC19
-:106EF0002AE27945A23CBC8BE75DCB72362F772C1A
-:106F00004FBCCEFFDCCBE5AD232971FDCFDC5C5F50
-:106F100000DCA4E7538EB1C0B6047254E17653BBD3
-:106F20004360E739D362F274AD83B18998DFE4E45A
-:106F300070CA7EE2BFBF538CC3C2D7A6211FCF1435
-:106F40007C3EC4AFF03CA55DC911FC3D06F0B2B477
-:106F5000EFC17CB68A78C45617FBE12C183A338906
-:106F600085F0DE9C8C7E502EA4EF03DBDDB1FEDECF
-:106F7000E022CCA60E096EC6FEA666E58C5E9117D1
-:106F8000EB07E06E768EB1C0AD4D4CC3FA707F8CCE
-:106F900093F4E0B390CF03F884F005C33C8DBF1F9A
-:106FA000D0D139321FF5EF484CBA31E9F9E2CEEBD6
-:106FB000E83CCD52AFD81FF1F1EF334A79DE4BF701
-:106FC0008BC9FCFE4C676781793FEB21B7C833B8AA
-:106FD0006BE643740EBAD3CEE8FCC2F6920BE61D04
-:106FE000D6605CCE6437D66851F2C76A302E371649
-:106FF000FB7B83CE1F623F3E117FC6B85AC68AC450
-:10700000F497EB60CD798385FBF5D697B1FED35924
-:1070100078ECC5E715EBCFEA37F6EE4F17717C81B8
-:10702000774DE05D4F0CE75EC9A7806F9B89BF1667
-:10703000087E93FB8167768ED868DE7F95E7864071
-:107040003F3F8DBF8F10EE4C227FA5580B5C83ED28
-:107050008B3BD3687F40F287E40B49D78EB4068A16
-:10706000B7743FACD039AE78B80E49B8D6F17BFBD7
-:10707000B2E68454F33DE3521EA0FF0ED1FFB8895F
-:10708000243F8F727900B9B905E517EF61C179F82E
-:10709000BB8ACCBF4720E12F425E1C4F74E4F87FCF
-:1070A000C125F25738DE7AE3BFFF45E8994BF42C4F
-:1070B000EEDC4FF3ACE9436EABBC5E9EC7762CEAC8
-:1070C000F541BB3182FF3BDA3FA47BC53A76A94C40
-:1070D000F1F179A3DE2AEED1C7E35F9D02FA38AB66
-:1070E000A70CFAD28774E8D19F51A733D6FE07DEEA
-:1070F000F1D39A515F8A7B7BD355586DC6C4E0F8B3
-:10710000939BDB57134389E3580D5E8F458F3DBC3E
-:107110006C0AFB10E67FA59BE75F4DEC0AD3EFEA14
-:1071200048B98ED753FD3C9C8E86E7FF929E725DD8
-:10713000444FB9A49EE2EF0FA1CD3B06D7D7AE22B4
-:1071400005ECE60A5B2013FDAF8F8EFE84CEA72CE4
-:1071500012F939A3303F07D7CD63415A573EC54A8C
-:107160009EA733D09381F9DAD63C1DB6999F6B8DDB
-:10717000E7AB181F8585FD26E010EBC1B58EAE6725
-:10718000793CC32ACFB20C70D6D98698EADD7CDD73
-:107190009274007A37D33DC7428E8FEFCCDA80FAF3
-:1071A000F64D0FCFB3491F12188DF3977209EBAA52
-:1071B000E013DB0FAF7373BD715D02FE9DECE17AEE
-:1071C00076C13ACE371DFFBBF41AC47BC79B69A9B1
-:1071D000CB4D7AA24CC8B1EC57EA21F99DAC9F2265
-:1071E000FA9BE6E17251E6E67C877024CA272833D1
-:1071F000ADAFC43FAD9C7F60BE61337FBF29FA8DC8
-:10720000E153ACAB02CFB53AE017F0B7D51EEE8F25
-:10721000F949C59D36EAAF629787F2322BDA391EFB
-:107220002BDAF6D9AA4DF889EF6FA987CBD1067171
-:107230000FED211BF01BE2DDCDE13BB33387F4E71B
-:10724000220FB71B2EBE6E5C9A9ED920F23180BEF3
-:1072500094BF58FBD2800D563DCDFB4BEF175A81A2
-:10726000E7F0D21F627ECC29033C451580FB4B8F93
-:10727000D03B7A40C7F3B6DD0F33DA8F1F362730A5
-:10728000DA07E5FAA07B8C02FD15B4713D5C7C3F0A
-:10729000D83128774EB92EBCB6CD3CDE9D1E8FE589
-:1072A0001C61C53A8EBF6160FF3C8D4FE8E759B263
-:1072B000E3393CC71F6CBF0AE34EF2FB5641FF8B1C
-:1072C000C1578CF08D8BC187FD53FE8A3BB81CFBE8
-:1072D000ADFBCD8E01E67E1FE8E977DE1417EAF9F3
-:1072E000B5B0EE9074860EE0B98B8ADDA906DE9308
-:1072F00000F26C437F478E5BA1C9DFCBE92AC67BD6
-:10730000C20B7AC69174FDDD33E6F96FF2B8FFAEB9
-:10731000F4EDD043349FEEED00AF2F86978EF6B993
-:10732000CB5DB84E1C637E5C2724BCC3E674793108
-:107330005FA45EAC1F305F1BFA2FE9BFF0B1158868
-:10734000B7CE29744F423C5F4B3A0D675C7EA49FD9
-:10735000361C03FC50DEED2912FA87919F7BFCA5B9
-:107360003D4FF37B2D385DEAE7703A7679425F7ADC
-:1073700032627208FA9CEE2FAEB8BF471FB5F3F722
-:107380009DB973009FBFF64839B7D2253DD8EEA20C
-:107390004B66055F9F7E71546415A7338DDFD1EE78
-:1073A00089280A9EA36D68427F5BEA0984C79CAF67
-:1073B00024E1E9A123033A8E8ABD1F3687F7570FD0
-:1073C000F28E7C54A33628390AE9018AAF66A11EE1
-:1073D0008072563B6FC776F3FB1B249E6A6E844E09
-:1073E000C1EFFC574F21CD43E22B6B4ED45653884F
-:1073F000F9CAFB077F64A2F311B15F8078B98EFCF4
-:107400000DAEAF6BD4E040F45B599683CEA1C23A87
-:1074100044FAE5908B692EE8EF5578E2BA3455BD11
-:107420008DCE094D1DA2901C830690F11EFA3DAE33
-:107430006BAF4EE6795B7FF9D1509C674632E743EC
-:10744000E8C729FA71D23A28D6837FC905BB4E898D
-:10745000E9E5438A42FD1CFA87CB37AE50627C894E
-:10746000FDA1FD7448993590D6CB8E0C911CD46546
-:10747000C927EBBD9E75E562BDD95F44FF2EE66F5F
-:107480002A774D039E9A30BD3D8A574E3785D56980
-:10749000FF08E34E057FD385FAD3CBF9FA505E5847
-:1074A000F5225CC314BA5FF97052A890DFD3CBC742
-:1074B000C914719B4C91AF8CF6023E235EAEFF4720
-:1074C000A6F0E78FC533D39B38CEB356D4D78B7B8A
-:1074D000AD579524CE671BE8552CF1966BC5BE05BC
-:1074E000DEFFEBE57EA7C8B3E5FB1C60DF137E4B38
-:1074F000EF9A43FB765F745E9FC2EF6FE0FAE04362
-:1075000025F0EB1B157C06E9FEBCF0DB2AE5BF7F0E
-:107510006404BC98DF549B94380FBB44CCAF56CC6A
-:10752000FFE3467EDFC27CDC4F03FD31D6CBE7B103
-:10753000A86D6C39D27BD11A85F6D3E4BEBDA46F99
-:10754000E57AD5124F9F8FFB69FDFE163FCADF8794
-:107550001F35CEE247C971E3FDA9E38DD996B8FF87
-:10756000BCB621E29E0BDE7E3EF313DCF35B0758D4
-:10757000F6FF586BC6A5DD030AFE5338217C3AE9B5
-:107580005BF9FE78A39385CD707C3294F21E067A67
-:107590004337217D637024B3B0190E3699FFEE9501
-:1075A0008BC75DC10EE7FE0B3C37B8C94EA77B6A9F
-:1075B0007BE260A03F8C14D4472573BDE3637E83D8
-:1075C00094AF9AC989FD8771C2CF1DE7E6FE71CAE3
-:1075D00031E94F27F9502F4A7B3CFEBB861EBEB5D2
-:1075E000DA93178B3F00FF86CDFE517CBF2DA2DFC3
-:1075F0006FCE2FF97DF04BC17F89DF5D3C3944F1BF
-:107600003DD6A6502ECA8432AB1FF48897AFE78FC1
-:107610007893E97B695757CCB1B67B0CDB8DC76794
-:10762000F225C573CCF6BB3204F51FEF4FFEEE4ECC
-:10763000DEC93729FFF377E827427F6FA404B6201D
-:107640007FAC11F9F21BFE7A207B3EDA43FF6CA778
-:10765000FDFA924797AEC07C6677BB62D0F9A35D16
-:107660005679F8CEB2F6C115808F7641A71A3F9FA2
-:10767000478D3FAA0F75637E351F7F60FB3E453304
-:10768000F1DBC04ADEEE25AFDD129FD98B65E867DE
-:10769000B7D7907ECBBE19E9D83EA0A11DD01F7FE1
-:1076A000EF06E0E9DFC0C88EEE3F4EA1FEBF336EAD
-:1076B0008382BFBF25E7D96A9B5568C077AD99C95A
-:1076C0007E5C6F328DD0419C67CD7BD1282E8F138D
-:1076D000DEEBD4D0BF1A6E040EA1DCC979F954A335
-:1076E0003FDAEDC9EF71F8DA7AE24A7CBD616CB538
-:1076F000B04337727B4C654718B7C7695DCF5C3EB6
-:107700009CD63D399FCC34B16E64B210E61F43FB6A
-:1077100056B2539C7CDDCF5CCE7F2F4FD233E667D1
-:107720008E18837EE69035516D1E7CF7D27A5BC24F
-:10773000FB353E14788779BC6F9EC7C5F4956C679E
-:10774000EF23CE28F93D797A62FF9DB17BA9BEE493
-:10775000D1F49B492E9B75BA0F51E27FB811FC1CE6
-:10776000E1E9DFBE4141DC1C177905C7573DADA0FB
-:107770001DF9A3C5CC5013F0538FBC2EDB31B8C21A
-:10778000A437A17FA2C786B83C71196F71A570FF9D
-:10779000E71623C852C653DE2EF9CF8B37F3DFDD51
-:1077A000E8131F97882FA592DBE535B3F9EF8E9686
-:1077B0003CAA11BDAB9BF9EF0ED66CDB4EE7ECD8C3
-:1077C0004F991FE5BDA67DBB5201E3566FDBAE2C82
-:1077D00030E16F404D84F2AB2FF3C87D8728D9CDBF
-:1077E000F17C8DF102B4530EBBB8BC9F2A71877136
-:1077F0001FE2943D5483ED4EE524FB719F52E2FB62
-:10780000D5EDD3E8BE03CF0E47149FADB68DD94E4C
-:1078100068D73A52F7231F0D3742C3102F695AB069
-:1078200003BF4F4DF7F8711FC3E7606368BDBE44E7
-:107830003C4C88E387093FE57272638A57C805A309
-:10784000BCA7AB533CD27E22FD74D8CEE7B1837186
-:107850007823DEC0B814E4C323FC7713FAD74415A9
-:10786000CC17891F37C64F812B11FE4B87B35D475D
-:10787000BD5E2DF44CC9A39B950F4D70CF40A30A5C
-:10788000F973DB0605E364504F7A06DA33CC4BEA32
-:10789000BF8DFBA5D550BFC0A457E43C12E897208C
-:1078A000C2E77EAFF320D72F51BE2F20E08DA7E790
-:1078B0009C141F8D5F0EE601BDD7C3C3D12F3E9C24
-:1078C0009F44FD49798F97CF3982CFFBAFDFACD88A
-:1078D000DCB47F4276A4844FB67B23654A08E199E5
-:1078E00030BD93F050BB5EA3F94CD583436F33C9D1
-:1078F000435D0AB7E3F6DFF83EDDFF73FFAF8E129C
-:107900003FD6823F4DFE44DB51FD7A5C57C24FAA01
-:10791000B8DF750D3749D883E25EAC6B3AB8FEAD7F
-:10792000EDD8AEE13D92924FF34EEEA7FBB46ADB89
-:107930001D0CFD28E0BFA548EF783EBD547A821E9D
-:10794000E27E525817F1BC501EFA39523F47843D2F
-:10795000CADCFCFDBD024F31FE09B5A458F4AB8B67
-:10796000E422EFE498FD989759EB57E8BCA48427EC
-:10797000BD34B17D2EF5A2D4D718370C9AF4FA5A3B
-:10798000A4EB782A47B93FCAF2715D9670C6D3E975
-:10799000E514AEBF13F0D3232909D62BB97EE73DFA
-:1079A000B643C37B91249F5C83F435F1C99329FCD2
-:1079B0007EDD275334EAFFC112BEBFF8A09DAF534E
-:1079C0000F3639295FF2D59B78FE96E7663D8ACF60
-:1079D00043B67935587FA83F87A3D5B69CCED781CB
-:1079E000FC3D95427CE2655C0F72BD77FFF35C6FF6
-:1079F000D584DDE4CFD684BE5F4179ADE92E3FDD8D
-:107A0000F7193AA85FEF89E1359E8F7C3BF6D1EFFD
-:107A10001D5FD3CEE50DF426F1510C7F1CCF524EE5
-:107A2000A43C44E4FE0DF001B77BB8BF5428CE3B24
-:107A3000563AFD745EB252C4550BC5B9C7E2630134
-:107A40005A0FE6093A14D982AFE2BC2AD6C4C5550A
-:107A50002FD1EEAF5EF6FA08FC5DB0AAEC23F494E9
-:107A6000F2087EA9456EDF11FEDF1E41EF3F08F9E7
-:107A7000AF1ED74EF256FD5103C9A97B3AD757EE38
-:107A8000F7AC7A96B17BC47CD7D0775393DBCB71BC
-:107A90005F78EAE30ADDABD9179C8BF01C18FA6F0C
-:107AA000EB0F78E7A23C8BDF8792E765CE08393988
-:107AB000B55515BF97D9A05FC8AEBE587F2CFA96B2
-:107AC00042F795089FEFD4B6D2497F44BF736B0A43
-:107AD000FD7EC967DBBEF7E33FA6E3EF835CEDC73E
-:107AE000F53F7D4590F8A53BC3E5DFC8E3ACD33156
-:107AF0000ED5D47EC08BE76B3E7DFA8A31A88FF11C
-:107B0000DE2D9CFFC9E7D5658897E54F3CF72DAC86
-:107B1000AF8E28FDD02E3DB5F5F1FFC0DF81AADC88
-:107B20005C4FBFF3BCE2E957C8BEFF3F75A9C786EB
-:107B300000800000000000001F8B08000000000013
-:107B4000000BD57D0B7854459A689D3EFD24DDA140
-:107B50003BE93CC9A393404025A1131208F2EA2453
-:107B600084872076408620AFE61D20241198591C7A
-:107B7000DD9B8620221767E2EA28F8DA0E838A3333
-:107B8000CE18306A90A0CD43C4195D5B040767919D
-:107B90006DD4419090F446671677B8C3ADFFAFAA95
-:107BA000749F930EA83BCE776FFCFC8A3A754E3DCE
-:107BB000FE77FDFF5FD51A5FF3DF52ED8454EFE9E6
-:107BC0006F3510422EFEF2E1716428218D2D8DFA61
-:107BD000A099902F7FD98CF5C3CFBFF4C67FD3F780
-:107BE0006ADCB14E78EFCB970FE9E1798D47EB6A0C
-:107BF000A125F11CD5CFB2D0D2FB824C1209994AF3
-:107C0000D8DF637B0FE91D79B4DE221142BF27550F
-:107C10007ADFA02CFA5DCB5EED1233BCE123A49891
-:107C20008EFBFCC2511EA8B7251092127EBE554F86
-:107C3000BCC6385AF623C444CB4BA566AFD49F903C
-:107C4000D565E6AD505EFA8DA9CA47BFABD50773BF
-:107C50006D309FA1C405F578AB86900418E76E5D82
-:107C6000AD19BFC77E3ED21102651EF192F34308E3
-:107C7000A16FEDBE361CC6FB2DBE4FDF2B3115129A
-:107C8000327BDE3909E61333B45EB71AE7F96BD6F7
-:107C90004E571DD93E623D1D8F8E7B0DFEC687CB94
-:107CA0003CAB19DFA700C132B5B532CD01EBB71B34
-:107CB0009CB07EB1BED46A4FA3853EBF6DBDC729BF
-:107CC0003B0879FDC289890368FDF921D270195EEC
-:107CD00097A5856EDA7FADD78CE3ACD950463EA32D
-:107CE000F31D6F95F0FB442BB1DF4AD753A12576E6
-:107CF0003394849CD41542FFCF62BBC3405CA488FC
-:107D0000966FCE7E7623FDE4319D27A518FAD91A09
-:107D1000D03BA0DCCDE64FBFB79A0BB13FEBADF047
-:107D2000BD91AC85EFBA364EB36F93B0DF802E2E87
-:107D30003C6F424219B3F2587F4500A7C9DE2A784A
-:107D40009F38F4B8BE2FE115C4A3377F7E1E940F71
-:107D5000B1F96A8807E825514F4B84AB27AB92D223
-:107D6000CD7C6B6995B5385C26F663ED6AB83E0547
-:107D7000ED149E67AC2E2CC99E784246F57E4F943A
-:107D800002FE876777EA8374DC470F9C43BAAD0530
-:107D9000BA85F13D9FEB611D826E9708BADD7F0EBB
-:107DA000E976499B84F454DB56A0077ABDD4E022DF
-:107DB0009F69699DD3DF63527039D0B577BFC9FA27
-:107DC0002C8553A7A0CFEDE7CECB141ED96D290E7D
-:107DD000099EEF6774FA9646E30538BDB5EB96E663
-:107DE0004629729E1B113E5235413EA9AD273E03E6
-:107DF0006D2F7D7AFD8929B4BEA69A380D943E6A0E
-:107E0000557494F5CCA75B805E6C35A4C8E480758E
-:107E10009E9D3880F65F5B438A814F5327B8F643B7
-:107E20009DB4496410D4ABDD4B61FCDBEC2B9D327F
-:107E3000EDDF36C1DD0AE3DD661FEB94697F8FA5B8
-:107E4000B76C31D2766F05B13EEB00FC36956969AF
-:107E5000FDB10A87954292C26D7732B493217AE7D9
-:107E6000B340C79EA535D05F6DF25C27D0492FFE89
-:107E7000DFBF7108CCB7D6D1CF69A2EF4F6D939019
-:107E8000AE88D74C60FEB514BE509FEA1BED83F957
-:107E90005CE6F01370ECD40516C0FC3A5F31102F8D
-:107EA0006D9F3A81D1AB6D420BCA8FB7F74F3A2E17
-:107EB000E587E9D2F2AAC10FF538AD5572825C228E
-:107EC000330D91786DD291856EFA9D6D32EB2767F7
-:107ED0003BC3EF739C9F9E03B981A59EF36F13A3D1
-:107EE00077AB37DF4DE9E132C73FFC3968BFABF113
-:107EF0001F143F4BFDC84F352FB2FEEC0657C1BAD9
-:107F000008FAB59713E4E33D26B2B0923EDF63630F
-:107F1000A59A5EDFE5F3C87A662DE27D09C53BE0F0
-:107F200035753B7D0E70A3740170A378443AB8CDCB
-:107F3000BE02F1B664BB7417E2D13B82403D219E84
-:107F4000AD53DD7F80CBC53D26779144FB0B255893
-:107F50009CBB24988F4B63827A81CDB98BC0F7EE9E
-:107F6000DD305E4292C9D91821AF08711769E8382F
-:107F700017122D0CDFBEF7B533F2801F1DD86F82AC
-:107F80004CFC04E50FC976E785BFABC861FD55F031
-:107F9000FEA63579F349368307C285C3C3B7B15FFF
-:107FA00055A43CFD08E041FBF5DD44AA406EBCA5AC
-:107FB000276623F46FA5E3D0FE12778DFEE5369C8D
-:107FC0005F23BEF7A6D58A6545BCBBA81E44708E4C
-:107FD0007B3DC045AC530D8FF91C1E87672F28D001
-:107FE000001DDF697602DF3D7A405A8C74ED355210
-:107FF000A604BA677C48283E802F88478BF8A8AD36
-:1080000077FBA2D37D25F259ADDDE4344948F72E44
-:10801000D47F5EB38FD13DD37F319399BE0239595E
-:1080200099D75B1E083903FA0DE859F045EDB860A1
-:108030002EE0F7DBCA954E1DE3F34E0A07E023C19D
-:108040003796D719BF6CDBE82885F66D94EF23F1DE
-:108050007D4CEF45FE3D96DDCF09FDC23CDD96B07F
-:108060007C4FB4BAFBD9609E1AFF166D56581ED7C6
-:10807000BEFE60AE270AFD09796CD4323967F4C5BB
-:10808000F858BF6C3C2305B7A5104B2FE8A3980DFB
-:108090000C3EEA7ED26D664E8F46EBE7548F4FA7BB
-:1080A00048EA9F43C8648D27DD46FB5F630C1EA32F
-:1080B0009825191B427A984722E82EE09F5D313EB1
-:1080C000905B8989C4B32F4ABFFD6D8CDE045E9A34
-:1080D000E2181F25C6B2F747D918BD0CB5313E2DA1
-:1080E000E3EF8BF90BFA77683CE788DCB71E13DF08
-:1080F000D17961BB980FFD7E2B61FA17E79BB829F8
-:1081000077D7B6087C84F9E8A642C053CE76BF760E
-:10811000B1393C8ED0A76AFCC3FC817F603D95439A
-:10812000FB7EAFE910E347353D4EE17C62B0112C98
-:108130009B74FE3F235FDD6D21BB607E3B882B9EE1
-:10814000CEABEE8DC18C1F5CA15CE8FF609C6737F5
-:10815000E063E4044EE7F4F90CFA7CB596780D146C
-:1081600027ABF7E87C4123E3996BF4FF62C0139DD2
-:108170004797C5E895299DBF1FE7A982EFBD65C454
-:10818000E907BDF4532A3F80FF88BF18E44B1D095F
-:10819000C6029C6BE5402EA1F8BF1AE3990FF4F8D4
-:1081A000A9269001CF090922BD9E31C5E613DA5FE9
-:1081B000ABDE9FFE4F30EF7764B28BF6D34D5C534E
-:1081C000611DDD014D9C97AEE393B60F7F73807EFA
-:1081D00035FFC0E5F9F70294B6C52C789296F38C7A
-:1081E0001AA37678181E672CD1E5EB8F395D2434FD
-:1081F00032BB2BB4D1E003F8A8DF1B1FC7F05F77B9
-:10820000259578E3239F33395AA70DE9C184ACBB88
-:108210009241BC74DC4F34A4BA258A9DF9A18DE942
-:10822000AB564AFAD1DA4F733ADBA323B93B603E2F
-:10823000CD540E02FCB40E9417D58F6439B7D16AB1
-:108240006B76E818D811A15F4828FFCFE898DCA129
-:108250007F771A4784F5279827601F565BBD7E0DF0
-:10826000951BD5EB2D7E391F9F6BC700EEBC562D9D
-:10827000C8C1C55C2F2EA97FFB1B2996B66B8971DF
-:108280000CFDEE0BF3D258500BCB7FBC2E118CEFB4
-:10829000A4794DC89F844CB0823D2EB9A6C9D7623F
-:1082A000AE67CF69D16E477AA1F82D8F733F09F879
-:1082B0009ED79FC17BDEBA189F3742FEDDC1E1A386
-:1082C000A6B33D40A374BE6725A657D4E3BC1057A0
-:1082D0003609FAFDABC5FD1CF6BFEE32CAB379070D
-:1082E0004C19A0B7565FD1205EBA0A02B91BB28002
-:1082F0009E43197FA0F05BDD6EB07A1DD0AE57E0D3
-:10830000F5D3062AD072C3F5C517064E246680AB96
-:10831000730BE079C9D618E21D129E1F18D240B720
-:10832000B55708F6B3B8FDEDD320A76BB541A48BC4
-:10833000C54633C2BDF68A16E741B6EA3A82E27B09
-:108340003ABFF858573BCCDBFBC018DBF95BE8C3FE
-:1083500024FA1CD7E5390CFCF4784C2C71313EF032
-:108360000DA6F3EF363AFAC75138D4E929DE876112
-:10837000376E6384DD44D22C4ABCB6BFF30DCC67A4
-:10838000A9D1A307782CABAAD703BFCDEBEF2FB6AB
-:108390000E8DC4E718F9DA2DDF1E9FCF73F9F2892D
-:1083A0009ED27B14FE3ACDE5EF782E273E49657CC0
-:1083B000F14906A9DE07E5CDB4A4DF7D92CDEB85BA
-:1083C000ACAEEEE72AE78B4FF2991EF2AE657A412A
-:1083D000FD5E271FAF3CCE751EE0269E0F8F63CF3C
-:1083E0005F88735D043853397799D3A1DF46FB9BCF
-:1083F000F7A601E9906C0EE5021E7BD695CBE79BB4
-:10840000187D5EB670BF5F437FF43D17DAE36F9867
-:108410007CB0BF20D3A8DC0539BB369D809CA5E38A
-:108420005EC5F772E9B8F89E01D741B652F94B190B
-:10843000ADABD88178D9564AE913F8FFA0C10AFC40
-:108440002FE849D0919A7E4C7142AF31FD7A07E80E
-:108450005719F5AB298EE9573DF02FED51CFECBC04
-:1084600081886FA433F9DBE3FBA09170F8BAE3E3F2
-:10847000509FFBF3DC79BDE12CE4DF27FD9474E130
-:10848000E3781CC0DFEB81731C7BCF9EC3F499B0F3
-:10849000FB6FE1EBDACDE5B428857E1A3959696FB7
-:1084A000ECE6F263B72D164B8A97C1B07EA1D77A5E
-:1084B000E1FB29866FFADE5058CF3C4368413CD53A
-:1084C0004B3FA2F68EBE10BF7B1EBEEBE57F98C071
-:1084D000F469DD5A0B017D3F228ED9B1A4289401A5
-:1084E000FD9121B4CC03FEA3F246BA31FE60AF9FEA
-:1084F0004279E4F65807DB57CA7440E09921C40179
-:10850000FD517897C62584E1AD1EEF0C3451FB6E0A
-:108510006A9CA43D0F382A200580AF051F7C659911
-:108520004FBBBC6C357A35543FFC58E3B903FAE9CC
-:10853000B8E71DB4E7CFE8FDB94DE628ED7AFF3383
-:108540008F4BE1F6852FC85E3D9533AD818E5FCCB4
-:10855000A674B938203B61C8C5F7FDF9BD91602705
-:1085600007744ED8AF523B61BB96CEFB8C86E1932D
-:10857000D42BF7FBAB38DEA9BDA42523C2F249E812
-:10858000FB95C43F08EC8225C4A587F2D3BB574CAA
-:1085900023145ECBCCEB516E5D5C3B05EDE0E5C496
-:1085A0008BED4BB6EA3E8DD413CB9A94F5153B94E4
-:1085B000F5953E65FDD24F18BDF5A67B665F259407
-:1085C00047B71B1EE17479491FBDBD318ED169F9D2
-:1085D00003D31E47FE0FE88881D2C9FA83A5492438
-:1085E000CAFBA2ACBB924D7C117A286C57E412DF17
-:1085F00070E8EF2AFAF9A01FD8BFAE37B992609F92
-:1086000071A92CFA3CFE778FDDD2AF8F7E63B1DF8C
-:108610004BD9D75F67DD1523BED7FB7B33F64BED18
-:10862000A7A8DFEFE670B81417BDDDD7D37F32EA15
-:10863000C5F0778C0FC2E3A4A15EADBB6255E8E93B
-:1086400070BB9DE955BEFFA778F5A2BDCBED39AA59
-:1086500010ADE763C2724CD78FCD47F0CD671231B2
-:10866000A6A0BFEC612E479DF960F77E067615F057
-:10867000ED24C71B413AD525F78ECAD56687F94A3E
-:10868000BD1E4A8F5F0623EC82B6388B1DF5B99369
-:1086900038615CC10F0BEEA9E8EFA178FB8FFBCA34
-:1086A000933C4323E9CE8BE3D7EA853D6756E871D7
-:1086B000A2D2F34BDADE417B6DA9D19D0BC2E94F0B
-:1086C00007EF413E594EDC89C01F5D07076778FE02
-:1086D00007FA5DCC67A677918ED9E714A8946F67E7
-:1086E000F0F9CC6C67F6A2C6E8D2E1382EE2B026EB
-:1086F000E2169CCD970A592DAD8FED993F3813099D
-:1087000019C3E72FC1F714BE637949167B9261DE66
-:108710000618978E6722BE64281B47391D508E9716
-:10872000DC5A360F1FE27922A94F83F735C6A0CC59
-:10873000D649679008DFF7C00BEB165EDF7C67F762
-:108740008265F0DC6C41F9A3E7F3F846C84D2331AC
-:10875000C2BA0D66FF4558978597DE32667F7BB3B8
-:1087600089B391BED68FB41018D76CBEEC85C55AAC
-:10877000895582BAC9DAED877DC865ABD9AB198650
-:10878000F2F4FFA03C95DE5D0E78A1F29BF9A5FA0C
-:108790006AD7FA71FF23E4631C9F5F23978F2984B4
-:1087A000C1C14EDC875C94AEFFC5B27C1A89053529
-:1087B000EEC1F177C64E3E0EF305C0A39E9FACFD01
-:1087C0003452CF24B8B50AF99754A5ACA77894755C
-:1087D00023396305FA95FCEEE46BF1B8AF1B027E1A
-:1087E0001A1D973777F663F312F49316AF51D82119
-:1087F0006EBECFAF8DD313F40F261A8D6418DA2511
-:1088000069F1CC2E394B314DF7832194E705E35DB7
-:10881000837E41E1BCE503D9B989E2698BC5B151D9
-:108820000BF6DE1CC9F92C92678B1FFC3ECD0B6C3E
-:10883000CE6DD06E72FDFCFF40FB0732017BAB0EAC
-:10884000FCEDF1F0A2B514BE6BCEB0E27BF6F210F7
-:10885000FA49430F12B4A77AD1E9553A7F0AEF5F7C
-:10886000429DC2B76EA975F58BF4FD14778C538ABF
-:1088700068DF0DED749E12A70B783E7E04EC6BD979
-:108880005F4E7B41C0057E0B978CFAB0AEBDE08891
-:1088900099CE23C753E004B21DD8CEE32A76838F46
-:1088A000C51528D7D279CC32B279D4B597DE514CE0
-:1088B000DB07068613882FC41C77CCAD81260DDD1F
-:1088C0004FC3776531E8CF3AC9FD4A84CB83912AFB
-:1088D0007E1B1DA67F6C2F10756A36B84630770553
-:1088E000D6ED8C0F9C44FC31FEBC9584FFE0FBF27E
-:1088F000707F288F26849BC3FC469756687436D6B3
-:10890000D0F7DEAA9C84745807FB2E8A8F915AFFF9
-:1089100021E0EFD1BC2CE02559DC84F0DCB6D17F1E
-:108920005897052E14B70CF511D6071BA1BFB192AD
-:108930001FCB8CAA871B81AC5E03E30CED4E4F0569
-:10894000F0E3960A6205FBABB1C4E9B4D2A6D955EF
-:10895000CCEF3AABCAE8033FFE2C2D61F12EAD27D8
-:10896000EB4794AF7E348FF97BA13E2FC29F22E26A
-:108970001B27E93E666F147BE0B578A6C7C4F77580
-:108980009BF58A38D2CBF1CCBFB5337EE24FE2D92A
-:10899000FCB280FFEE8BE77265081902722582EF48
-:1089A000BDF05E47E9EFFB920BCA762E1766B91E43
-:1089B000D1A11DCFE58390C36EE043FA5D4072E91B
-:1089C000007E1F9731F89F285D89F26136F1E073D0
-:1089D0004A203A77A41F6972843D44C799E556DA64
-:1089E00047B3AB947541AF62DC391E65FB0C61DFA8
-:1089F0004E56DAB7F3FEE9AA0DF56FD2736BAE658A
-:108A000062DC04F7FF75144F2C6EA2657194CD7A69
-:108A10001FD849756D77BF95007C741FE17CB457F2
-:108A20005A3A14FDB0D2B2083B62408D4F02B93FB2
-:108A300098AE2980780D61BCE8A4CE7708E228279B
-:108A400057D215D3791ED1B378E45113F1823F5A2E
-:108A5000D0A76506F3A75232C6B8489A35C609F4BE
-:108A6000B4555388FED7ADB11667A4BF73DB464A31
-:108A700077117E578781145A39DD44DBFFBEC9E583
-:108A8000E16312F37F7BE71871BF9790E356C41B35
-:108A90001264721AFC883F897788F7D1CF01F1BA46
-:108AA000E1B4F449CC9EE9F95E269BD1EFA8923F50
-:108AB00009F14EF4F727F4CF43BF7D557BC16E9487
-:108AC000376693739014EEBFCAD3AC5D06FE83F68F
-:108AD00066ED527398EE4E00BD02DE62480CD06B1C
-:108AE0008F1F6F9F01FD783FD6B83F02BAACD1FB14
-:108AF000F389929EF1795F7A6C05A7175D997BCE19
-:108B0000323A9FAEF7F4CCAF751F417E7D79BF0D31
-:108B1000FD90DA1904F5C9E65282F4D0D52CA1FDF6
-:108B2000F685AD1AF7019BA526D4139D7113117F0D
-:108B3000ABCC47715F5BFD94EED348BB6BD56E65E4
-:108B40007D3509E0BEBAE6C55EF48CF24BC8C7DAE3
-:108B500056E57764A0523E1670B95FE876CEAC80D9
-:108B6000A9573973D8BE9AF80D741DC5EFEAB9FF3D
-:108B7000771ED39BE43909ECAD2ECB0599F13993DF
-:108B8000C7C5BC3FB51E2AE6F6D4382AB760FF2910
-:108B9000EC23FA3ED68F6ADAE5644D785E45FC3BFD
-:108BA000619709B92DF0525A424809A5FB643B97D9
-:108BB00043D9241BF04AFB477EA0E37AF571D8BF66
-:108BC00017F66DA3F97814EF5ED0B35E8DD10774FC
-:108BD000B445AA47396D245C5E4B1E94CBAF79BD7A
-:108BE00032C07514A99F398DBE37C61888017850D8
-:108BF0007A48B32784E9A491F833F64A0A7AC1F691
-:108C00000EDBEFA3D28BD02FFE8F997D3195AE185E
-:108C1000FAA980400E2D8F4A6C5F38C9FCA816BE99
-:108C2000FFBD660AD2C364E2D3C2FC2AAC4A3C4F01
-:108C30004A56D6A7387AD1810CE3BA383CA70E51F0
-:108C4000B6BB845C234AB99645AE229EC983C77ED3
-:108C50000C7E81980D6408D81DD442447E53CB838A
-:108C60007176B3C23E8A88838CB317F78E83747192
-:108C7000BFEEAD24B8FC45A937BD74BEB5414E8EDC
-:108C8000A02B41C7AFF3BC09E94D1E6F2D62FEC09A
-:108C9000B09E67F43282D76E057AA3EF2F147492D8
-:108CA0004932814EC6B699FC32856B01EFE756A07A
-:108CB0009BC2B03EF76BCC0E7D36D08773AB2CF7E2
-:108CC000B6DB13E31C4827C3352EA49362E28C075E
-:108CD000FC94185B1AB530FFFD230778CC0ABA580C
-:108CE00062473942E902F9AA975E54B6ABE846E01A
-:108CF000EF38B7972711EF40188F8AB1A3602FFB89
-:108D0000B318DD541017D2C9DBD953783CDAA3C5A8
-:108D10007E88521F961B9574A0A62B3AA226725CE1
-:108D2000359DF54537994037421FC6DF986EEEEF07
-:108D30009B6EEEBF1EDDA8E945C893BD266B39D8F2
-:108D4000A575D512CAE1E1EF0D6C84FAE0355998AA
-:108D5000D7B2D7E644BBB5AE9EB517055C32E4BDCD
-:108D6000E4ACE7ED59EE72A8D76D60F187E2932C81
-:108D70002F66E07DACBD6053FD110BE8772FFBFE45
-:108D8000F58B5BE458DAEEDBC2BF2F6D2A877ADD04
-:108D900056F6FD17103FA2F81D71DAD708CF6FDA2B
-:108DA0009EE564DB4F66CF8EE774BA57DA7704BF6F
-:108DB0006B62DFAD3866EC47D00E6676EB38BECE20
-:108DC000F14FB175DA3FBB6DB283D2EFB29017EDC0
-:108DD000A6F39A9A11286FFAD867964A4D695052AD
-:108DE000BA4139E33252BACE66F1C55D7488437632
-:108DF00066078AB81CE40944E6051CB233FFA37871
-:108E00002F318EB038F21316F4078BB8A1FF712200
-:108E1000019FC11AB9FE8F1A479C94538FF1C34921
-:108E200099227E18D42EA6E3165CFB6A62347FCAB0
-:108E3000713EEE059EF7209E57FBB23440177B81B2
-:108E400048520148AB7F0776D35EF0BF32A5E125DB
-:108E500025805756FFC8BE62DBD6340A5F4DBDD6AB
-:108E60000B4A2683EEBF68D7D303C4DF3FB6F7FCB7
-:108E70002769891FF413D1B2F92F6FA47A500ACB56
-:108E8000A55942EC8C19847C7A27C7D367766E6F1C
-:108E90000C27C341DECCE278FB91B15EC7F4659349
-:108EA0004EC5FF5F20FFEFECD36E56B6ABE4433503
-:108EB0001F7739B797579210DA05E7251F9617766F
-:108EC000327B79B5F924DA155D4F303BB18604D198
-:108ED000EE50FB0F57EF51D6D7B428EB756DCA7A19
-:108EE000579E17C7E9DAB96604F8EFAA77BC877E00
-:108EF000E16A21277C4A39410D2426271EBF19FD2E
-:108F0000361A2395134500AE7E9847329CB8E2414D
-:108F10001E8092BD46EB0FC22729B4AE711B1350C1
-:108F20005E4C8EFF5C8C2F639CF63D97238C979E46
-:108F30007DA14A4E14087FCCC038F45709B951C0FE
-:108F4000ED123259BD6F7C14F96F38AFE52428F764
-:108F50003DC2CEA0DFA39D11D0987D1A4DA45DE146
-:108F6000437E2C34523D812CE434B2FD4A1351E14E
-:108F70007730ACEB3AFB2665BB0AFF62DF3282E357
-:108F80007F0EF10C007CDC49DC6F817E38F171B51D
-:108F900062BFF4F11F270A7F0AEE9BBEFB7EC9FF6A
-:108FA000BDF64B3D783751FB9196E533A60CFA059B
-:108FB000C4BD5B4D98CF5927313C27CE399911E973
-:108FC0003F3CD14012B4117CDF38C56084F860A307
-:108FD0008EED27664CFD64C4E208B9F192B1746A63
-:108FE0004231E021F0937F87FDC53B32C17C99F689
-:108FF00004C47B77137D4EE9ADFBA95B9C5EFAF858
-:10900000928EC51BBF90EA97438A9398C7F20DBF13
-:109010003369A91E5B21FBDE08427C55F2BD5A4331
-:10902000DB4EE93D73A0FFD51ABF9EF9ED0218276C
-:1090300015FDF7ED87F4A2BED31F667A3124F573D0
-:10904000323FAE373732DE5495C8F657EFC7B9977F
-:1090500001DE85DE13F18433774FEA0FAAE16BE27C
-:10906000EA0F714E490BB1A7DEE341BEC0E608BF6F
-:10907000F21953F4B8C0DA04265FF7016FD1FFED9F
-:1090800036D73A18F702DFFF5DE0F1AE0BB12CFEE8
-:10909000F5BF7ADE67E5A309CCDF7D81C7C72EC4A3
-:1090A00029F78DE2BDC778F97983D1B839029F8E4F
-:1090B000C70DF53ECC93E27921EB09DB27EDB735FF
-:1090C0006F8B8887362794EE837925E4B8F42900DE
-:1090D000BFFD4C0F433C1AE2C64556CF76C04BADA0
-:1090E00083B820EE4A1C41FD4C883FC2BE13ED07F9
-:1090F000462F5D26568A79352754EE83EFBAEE0E59
-:10910000223E7BEA954C3E3627B871DCAE59A29DD3
-:10911000D71F0A72FC33FF81F067F7150F53C7BFE3
-:10912000A8E26076B689C93175DC7BBE90633CEEFF
-:109130003D8FCBA1F9EDCC3FBEC048B60CA0ED0BE6
-:10914000DB93D87E31D69BAB887B7B63BE531E837B
-:10915000A0CFAEF4404FBCF6898878ED1A1EEF5BC5
-:1091600023D6D7AA5CDF9B097DC66BDF4C8812AF84
-:1091700055E705BC0AFA7D60189E6BAD6CFD157253
-:109180004DB91EE4C45282F9E16BDF59D268A4F5EF
-:10919000B50F82E70FFE98BDBA86C3ABAFF925B80D
-:1091A00035C4A1F013F7238E887D718A274E51476D
-:1091B0000B3822BF724075AAE2FBF4FA6CC5FB992A
-:1091C0001B6E56B467790B15F59CADB72ADE1FD41C
-:1091D00054A6A80FDE719BE2FD0292D31FE3B1C734
-:1091E00065F095909B7C3314EDB7ECB94BF1FD170E
-:1091F000A4FEB131F4BD5613D303C4EB0A0CA57021
-:1092000059CAE79FD7B258F17DA3D432C24FDF5F6E
-:109210001A60FEF6616DAB14FD5D8A9DC8F6113CC7
-:10922000FE584FFF6372DC21A33DD4269127A4DEB4
-:10923000F1C8EAF687B70C20BDED0AFA877A7E15E9
-:10924000D5F36047A9ED0C39D16247FD904A52AF82
-:1092500045F055980ECC6887753F25A33FAD800C2F
-:109260007E7C0CC247477C8EDEF8EA26CCCFD3FD4D
-:10927000A2C509FEB215EF2C41FA33242BE9C0E454
-:1092800050D241CC10251D589C4ABCF72F51E25DAD
-:109290000D679B4B4907028E02CEF193957421E036
-:1092A0005B42FF03F81692D031CC9FF6494E3F89BE
-:1092B00012EF6D6BC675DCC86ECB53C173F8515796
-:1092C000A319E1C4F2A9849D64E0FE69B5DF5CD80E
-:1092D0001F6313B9DDC3FB117EEE2D9217ED9C9E2B
-:1092E0007856893FC39F05F64E3D61FE127769624D
-:1092F0004254BF1A3EEFCBAF26E028EC99D560CFA1
-:10930000D07196110FCAA5CFB93DB3C2FC28C605CE
-:109310002FFD91C1B79AF8505E7FD77839D889244C
-:10932000C2DFA886A3D42EF92DC0075C6EA7927663
-:1093300021B73D983741C9CE3842115F50DAA1C4F8
-:109340002545CA2761978AF1043C85DC12E3194858
-:10935000BD9C0C7CA092636488DA4E55FA3D849FD4
-:1093600004078B88638CEC894FB07D62D8EFC5FC15
-:109370001C7266562301FBDB2AFC1A81B9F05CF8EB
-:1093800035D4FBFB1BC545677AA5E09359BDE3A126
-:1093900022BE4A97F9D9BFD38FC7488E74186FC6BB
-:1093A000EB831388269A5FCE79FA00ED47D684E2E4
-:1093B00023FD65C27FFDB614C479FF88B8EE27117E
-:1093C000F6422D699938370BFC9F546FC542C9FC92
-:1093D0003EA44D6D97B278A286AE04E87B358988AD
-:1093E000176685DBB12EF7AE8B3C971BE97747926A
-:1093F000559C5BC965ED4CBE89FD5B5FFB2511CFBC
-:109400007F4B4F615218CE6B793191EF33F3493E68
-:10941000F44FF9AA2511F7E7940FA548BEEBC983CD
-:10942000C1F65E7CA75ABF88E7CB9622F4BB2C8995
-:109430005CEFB78087B023BEA26B83725BA203CBC5
-:1094400035FDCE7CE482E6A24046A4BD5BA76779E9
-:10945000C1A445693F9F4CD47078B9E46F03A7BE9F
-:10946000F1C0F3C2381EBEAD3D24F2C204FCFE289A
-:10947000E46018DE671572AC67DFD603EFB3D1E4A2
-:109480009C80C7E5E2C0738027D9723211E0FC5797
-:109490008BFB33C04FFAE9E0794903FAAEE3B92711
-:1094A000417FB5C9B83FAA1DCBF2836AF763B09C70
-:1094B00074B61B301E58DD7604EDB28E062A4007C6
-:1094C000F60D9F9E75AAE0DCD73E45ACE3BF557410
-:1094D00026F244E8FAFEA6A0A7DEEBFF5B347A137F
-:1094E000F94915F2D0FEC188FD483BDFF798B46E0C
-:1094F0006D12FDAEE8C3B458804B85DC7E2C15E0C0
-:10950000B05EC2F347E30DC40B7EFE147E0EAD24A5
-:1095100058EFB4527824A799F13CD1E01FCB6E8864
-:10952000637EB27E5DDC125A7ED94087A6FB8DC178
-:1095300092C68D7446F69DFD6911C4D7E661DEF1D1
-:109540007C038BFB67FD24C69F43E5C39B7A6204C3
-:109550003ED365D7E3798B904DC67D865D2613801B
-:10956000AE049CED316C1DE279E9D3BB25C86312D2
-:10957000CFC7378686AFA5E539C07771789DE3CB35
-:1095800043C3EBCD61388BFC40A20D65CC88E08BEA
-:1095900037393C6A13F45B400F761AF9FE8FEF03FC
-:1095A00089558BF2633D8FB39F194477A2D88FDF23
-:1095B00002F958B52657FF91E0E7823C025A7C6DCC
-:1095C00075F5B7E1FA1D682FAFE7765527CFDB5E5B
-:1095D0003FA52C09F6517DE53D952631FBBE86C79A
-:1095E000BFC5F31AAD1FF3956A20DF3822DFE9BB50
-:1095F000E61B8BFCF13EE160D3122D8543AD44DCCC
-:10960000D77BEFC0DFE4A8FBDCEA24CD75F3DF16DF
-:10961000F2F589FCB65AC86FA38FD6EF2F4D2251B1
-:10962000FAEBD133576E55E49189FCE8DA2BE3303D
-:109630008FACFC810E3CF707FD38CCE1FCB6BEE0F8
-:10964000FC66229B472DE4850D8F7CCEE446B87FD7
-:109650003BE2E1570040F073B4C9E88FFDD571CD0E
-:10966000E45D51E6FB501283CFCD095AE48F5BFCD9
-:10967000C4D51C657CF19E38170270AECCEB3DBFA3
-:10968000D6B2E002983FE4AD461BAF2189EDAFC5ED
-:10969000BC5BE382CB399DE3B98C9EBA5589C77F09
-:1096A000E572BFF5B660069E2F9A123D3F5EE07BE5
-:1096B00084B65E0278042D9E03686FCEA6956190F5
-:1096C000D7EFD7B0FC29C6677DE13D0C6F8D229F97
-:1096D000B037BCF58867D19FD88F5CDC2163BCFFB5
-:1096E000E209CE97C46596287F2DE2FAEA226171DD
-:1096F000838B4D12EE43167B08D940E5CBA2DDAB40
-:10970000316EB3FCD9E15B404DC1F3FBA81C599409
-:109710004CC8385A2EDEAC8CDB2EDDDE2B4E4322BD
-:10972000F522353B715FBDFC51E577D564FB7F8247
-:10973000DD53ADB26B06733FD7BE249ECF37828C0C
-:1097400000F9BEF6D9AFF490B2DB17BD7F49F97AC4
-:10975000A016E4A015CBA349AEFD49141E1F26791F
-:10976000DA416E777DC0E0D05DD3CDE4FE5376D490
-:10977000370610CEF49F86B92CFEFA001517107725
-:109780003318985D23EC39595E27C7D2F6517F5ABA
-:109790001F07F8B3FF7AD264B0F7137E1DE3027897
-:1097A0006D2B7515C0FE7F5BA519F3188C0616F797
-:1097B000F5FD6AD46108030C6C79B80CF69FD6F6F7
-:1097C000437EF08F6CD5FC279E2BD93A8EE5B98964
-:1097D00071EADA2BF7C27C32EE647A635B96ABC037
-:1097E0001AD12FE1F6592D8759D7C1C13F1F4DF12D
-:1097F000F8E471348FE9FAB2D10F773361F814F9D4
-:10980000543076A41DDA41F50F24E589FACD2D9266
-:109810005F47D7B3A6752FC62F6A36F913E7829E26
-:1098200079418BF11F313FFB9B296510E711FA65E8
-:10983000AE6445FD2FECEC3944FCB1385115A783DB
-:1098400039DCBE9E1BC3E0BB983833E0BBBB8C2425
-:1098500016FCD373CB5B8A51FFACD6D940AF8B7863
-:1098600047DFF640743F51ED7316763E560AE542E7
-:10987000275FD27D0761FEA2A8E78D4CC99CCF72FD
-:10988000B9BD3790B820BE56FBC6E066F00718FA9F
-:10989000B1382C953BC69242B4778DB08F5979C0C0
-:1098A000E467FE6A1F3F07EB2A807C90BA1969853E
-:1098B0009897709ACA0F0B9C2F0C66209F52B92262
-:1098C00051DD969D1C334D4BE9BB3695DA53B4EE12
-:1098D000DE91CCEAD9C1E51A5ADF905CC8EA3707B5
-:1098E000CF437D53F258562F0C2E9769FDE9E4A91A
-:1098F000AC0E1B3B4A58BF4A9E31CD0BF6848DEB14
-:109900006B6710CF05D7BE3E5813E9A77C2C99C9C9
-:10991000A52FB9BFF5CB2CB27006C07B4810CF9DE8
-:1099200089F77E9A2CEC5B96DF2BD629BE23C9D112
-:10993000FB2FE0DFADE4E779C7C790AD2616A7F2AD
-:10994000C652F81F6D1F8C71B6C4E438E68FB3D2CF
-:109950007E8AC2FD08388AFEC4B8AB40AF82BCD54F
-:10996000317FA9681F97CCE4381D67338E3394C1CB
-:10997000BF76465A01E08DE24BCBF1A565FBCE6682
-:109980001C17FAB5E5A37C1F0EFEEEA357E9FB59A1
-:10999000E179ABE9632AA78F958D2CBE18B2E5203B
-:1099A0001D8D8F61F61E2952AEE3690E87C7926D39
-:1099B0000C8E3DF84892709C460EC7340AF7BCEFF7
-:1099C000BEEEF93FD0BA23F0E592A1BDEDA65D91C0
-:1099D000EB11F9DAA29F2F37AABE2B617953B5712B
-:1099E00039F8DD032662C4E76457CF7759F9CCCE46
-:1099F00004FB53DCD740BCE3D04950C3A546CFFDA0
-:109A00000B2D3C7F70A08B9D3F9E31AD88AFCFCAA0
-:109A1000D7673546DCBBD0C38F274319775A7AD333
-:109A20006F0FDC7BFA1B5AC8FB53F075B4FE803F06
-:109A3000FAC2C7CFFFDEF810F354C1B307CEAAF9BC
-:109A40000978023FE3774395F428E6B92959E40BF6
-:109A5000ABF83AEB7B8E57CABE5B730FCF03762809
-:109A6000E9794D6B9606E2E7E2BBC9E0634F08FB7C
-:109A7000DBF625F37D6B1A49EB23FFEDD5E4E87E99
-:109A80003A7CAEDEBF75D958DEB3DA6FD095E00C04
-:109A9000C0793EEF65763E7DB4CADE80F8CB3E737A
-:109AA000F8BBB03E51D6E514C607BDFD40213C4F82
-:109AB0005B64287BD9E1A47B9DE4EA695A6A571468
-:109AC000F52F5B9745EBA79257A1BC2E1A50F65580
-:109AD0001695DF7F485ECDEAB7947D950DF51DABF9
-:109AE000D9FBE35D2F837C27DED5D326A484ED87C5
-:109AF000D3C90E849B5CAE21404706F96E27E84926
-:109B000001CFBECA2283A63E9A7D7AAE870E587CCC
-:109B1000A284EBE712B13F0F6A15FBF3AE5876DE75
-:109B2000B80BF4295D6F47B2E77C32D829311D0BA1
-:109B3000B268579B62CEEAC11E925C5477819FC384
-:109B40006125F3209FAE639B1BEC23B2CA69D4222C
-:109B50003CB9DF89AEED1AEDE7C01B2FDC3B800D71
-:109B6000E386798CE2FC5FF7C6377F81F868DD9782
-:109B70006627B8F546B5EF5C07F6D5A8F6DF7FC3D4
-:109B8000F42D3BA721E63D0AFC87F479499B01E7C8
-:109B90003FAAFDA665F0FEE80FDB73803EC69EF18E
-:109BA000378238E83AF8DA00C5F90CF285F47DCE50
-:109BB00067F4C0E34FD478EA8FF030A624003CAEBF
-:109BC000629E5467C2892D41B4D394E760A85D8E2C
-:109BD000F1D56ED2CF097102718E5BEDAF3C5D495C
-:109BE000D7479F8F0DD11944D8CBE3AFD0FD7D84EB
-:109BF0009D5D4A6C8A7AB93145F17E85354BD13EFF
-:109C000029F92645FB144781A23E75C828C5FBB734
-:109C10003B4B15F53B4AA628DEAF74552AEA05FEF4
-:109C200016C5FBC38FB729DB4F3A100FC3CFB8CB94
-:109C3000C18E77063C8D508EEC682AEFEF20BDFC7C
-:109C4000B445415F233C1F7DB5BED84FA29C5F59F0
-:109C5000E541FF7EAFF32BA5EC7C7BA7869DDF1053
-:109C60007ED9AB319EB180A7B7250A760AEC71C6C2
-:109C7000503CE0AB62E143982FD51D22E8CF6AD576
-:109C8000077F361AF4FC7C19EDDE569E67D35A9591
-:109C9000E7035FDE6929F82AC4E9BDF3D9F980B189
-:109CA000D4C2C575434C53023C7914EB2E252B5579
-:109CB00078BA5B51AFB0DEA3787F52F24645FB1411
-:109CC000C7832A3C3DACA8DFEEDCA9C253B30A4FE0
-:109CD0002F28DAC77E1E6C04361ADFE1952D74FE3C
-:109CE000B79E6E2A07BC8C3EE39D0FFC52E4F7340E
-:109CF00082382C3E5A7F044A3FDD4F819FEA7043F1
-:109D00003296471B1CE8673AD63004CBE30D4E7CF5
-:109D1000FEBB86122CDF6D7061F96F0D93B10C34B0
-:109D2000B8B16C6968C1F7F735B4614921980EFA8A
-:109D3000C21EDF73AF423AECE73B35C15A88A0AE92
-:109D4000DB7900E56467BF6027D43791D7A74D80E2
-:109D5000F35CB09902FB0A4A8ACFFB525D7F49A1AE
-:109D6000F54D29AC2EF2125A34AE02B0AF1FD8799D
-:109D700064BB369D90FB37BA93AD365637D23A2244
-:109D80001BFAF01ED9EE4A23E437A0326EC5FA342E
-:109D9000A8779958FBA69D47A679513FB0F8F19D49
-:109DA000E1F8F10330AE3A7EFC9B0B0E0BF8534EFC
-:109DB0005C1D6C81759DE0FE231729D02DA265A93D
-:109DC000B640077AF1B4CA8E10659DA6B409FA6D43
-:109DD000D13867615EF06D3A0279E83324B61FED41
-:109DE000B10353991CEFBADD80FB9D931AD732CC97
-:109DF000779242CF00BCF6A49C44BDD265096500B1
-:109E00001C9E4BF990D51342CF48CE88BA8EADF345
-:109E10005F534EE03E22CA3A77A7448993BF90C26F
-:109E2000E3067E573A9EEBE5F59395AE35A0274EB7
-:109E300096BA06C17C4EB80DC83F5EB7C507F99605
-:109E400044EB2A9E15E157C949D5E17777EA199F76
-:109E500091BBE4A8E7CD4B53999D857883FDDC9CAD
-:109E600018B4C34F6AA29F179F93CAF4F5A57ED179
-:109E7000FD2B77F1F6B29916ECAF6BBD09E3B75D38
-:109E8000EEC1680775D5532851FEE8BA507FF91521
-:109E90006C3788D016C629E77239F59BF6757F3E78
-:109EA00045DF3FBB3EC68932DC7A33EAA7BBF8CB3D
-:109EB000F3E38D68B7CC9F915E067A692E8F772D7C
-:109EC000B0681331ECA5B5E9E18AA0A5E6822DA022
-:109ED000FE97DB2BF5365AAF4EBB7B0B94AB063EA1
-:109EE000AC87239A3543F76E01F3710D65AD62DCE3
-:109EF0002F05DF6BA0F35AB84176B0FD933877B8E1
-:109F0000FA3BE557083A3CC9F364287C715F38375F
-:109F100095ED7BC4777339BD5D4CE1765B1EC9BBA3
-:109F2000A68CE35C063AE998FF5E6E1F7E77653B80
-:109F3000B7DB3ED2B371D5F7508871E771BC9FD4BF
-:109F400013970476DC5D16A48FFCAAAF3615D3F503
-:109F5000E7B75B35188717723CC0EE032BFEDC8336
-:109F6000726E6447F0B95304E9BC0DF8E4467A6AAE
-:109F7000A67723EA87515F53FD0372F1AAE7EC2924
-:109F80006CB5473D8FE96FA8E6F2B11EE5DAD186E0
-:109F90000D583FD6E0C5F278C3562E1F9BB0FDDDAD
-:109FA000861D5C3EFAB87CDC83CFDB1BAAB07CA3A9
-:109FB000C183E55F2DEEB8D40420360FE667BEB549
-:109FC000D340E0DEB4EE7603D229E580679EB44349
-:109FD000FE8BC10AE7EED479306A79DB83FFD65E67
-:109FE000F76164A41647E4BD807D96D937FD9C20B7
-:109FF0000E0BC893114F24DD0EF2F984C36101BB2F
-:10A0000075646A32ABBB1C161DAD973C41EB54BE68
-:10A010009CF0382C065A1F959AC2DABD0E8B89D651
-:10A020006F7D2285B5FB0806A9C73F91713BC89F8C
-:10A0300052221D057E2837664D8094D90A6BE9515E
-:10A04000E08349C98B26001FFC36C5817438C5B131
-:10A05000F128D4A70E69D6C2511B97B960337C573B
-:10A0600066AFD4C27713D2EEDE0CDF4D1CF8B036EB
-:10A07000F2BBC943F76E86FA3467B316ECC1DFA6AC
-:10A08000B0F3FDA21F5117ED42BE8A3CAD61ED6EEB
-:10A0900094E3F96D6E94E3022E657756DE0F7EBA77
-:10A0A000BA36C92AC13CEE947A82EF900B577B9561
-:10A0B000720B95B3D39FB8C9B291F2571DD46FC537
-:10A0C000FA431BA3CBDD99A951F4CB1F389F82DE45
-:10A0D000847CE83FE8D97D1E2FF3F5D5B52FB22C4F
-:10A0E000427DE5B1807EDD9FC2F4E541AE1F2FF3D6
-:10A0F000B29B3FAFD3B8E6C3384B53FBE4EB6A687F
-:10A10000A77CAB3A27D0473BE7EB55A95C3FF07BF8
-:10A1100013D610769EE846F95A2B23F76F5990977D
-:10A12000D3720CF245D5F90F3570CE28A7771E30C3
-:10A13000958B2CEFB14D993FDAB3FFE8C7E41E1CB5
-:10A140005F844D4763DFEB7E2035E1BAEB56B6F313
-:10A1500075AF242CBF59BD0EE24940DE12F9CEBDC9
-:10A16000D7138CBE9E5EEBE0F7EEA9F2ACA91DF40E
-:10A1700038CCA762A18580FF26524E9CBA8E9C5097
-:10A18000CB9DBF973CBB8EBC79319ABC11E79DD566
-:10A19000A5B0E7E09C14E4DBC17D2FE0A7FFA74456
-:10A1A000CF6BD04F5759E82F1AD89FD9834867767D
-:10A1B0009BE775782EE959DC5DE4B15ED0787F0BC2
-:10A1C00076D1B12796A01CEA04E540F9F10D5A07B3
-:10A1D000B9536475FB017E6408A39FBEF233DFE6CA
-:10A1E0007AB177C9F849E42976357F93817EAC1B33
-:10A1F000D07B5F70A890C704E13C4077490C9A3C43
-:10A200001D12F14B85906F9D88764447BA5E0BE531
-:10A21000DF7B9FD8919E8BFDABF78B1D29254636A2
-:10A22000EEC4C950B6E93D3B16C13E699401F749F9
-:10A23000EFF3FCBEE99F5EB583BE9A2EFB13F3A538
-:10A24000DEFBCC8E77E69539F27BEF37E9FA26C054
-:10A25000FA6EB4EF741B03710046F5FEB366C35F7C
-:10A2600008E4458FDE7095C07D6437DE8F1219C417
-:10A2700044E169E711288B3F77611ACE880BF547D7
-:10A28000A01CF535DB9EDF289FE8D62B2D47D8F1A3
-:10A29000F0A1CAFB164A7ECFF6ABBCEC754FDB2AA9
-:10A2A000AF324FADD45F8C7914723016CACB5210D6
-:10A2B000FD5EB286DDC320EE5FA0FBD8C401C5B051
-:10A2C000EF65F952E321CF884EAEE2A71F2FB817F2
-:10A2D000F9DE84F64FCF3EF6150DE609B46A5DFD52
-:10A2E000C7C23E76C320E7465AFF8F40C22F0ED02A
-:10A2F000B2CEFA1712797F5BCD866E45BD6363F8E7
-:10A300009E20C883AEF99B8C7AA78690AD80AF1A49
-:10A310007258BF36420F9296FFEC81FB302AE72A33
-:10A320000170B8AFD24C77D1F72AF97E83781B59E8
-:10A330009DEFB308F9EC7617EDB73281BF4F664F4A
-:10A34000C77ABA68AF62F541A2BFD7D8FB29A2CEBF
-:10A35000FBBB49D47FCEEA59E2FB16F67D9E18FF7F
-:10A36000BDDBB1DDC2DE1F3F60FD74900342BE570E
-:10A370000CE0F925FC7E1F2AEFA70C48B86E5E8919
-:10A38000B29DEB03719F4FC54FA7C4BC07FCDC22F5
-:10A3900061EE5BCD7D3AF46F5F8A6BC98F3C9F2C79
-:10A3A000F250DCE51617D87B6B5E1DBC4BE6F93826
-:10A3B000606F6CE3F1E50AD98CF188EEED4CCEF7D5
-:10A3C00065AF2DDFF0BA029FBDDAF93DCA18A8A328
-:10A3D000E35D7E2809F3DBC9C000C6C3570C90C4F7
-:10A3E000F92A3CDF2AF2BDEC39C405FB53FB6B268E
-:10A3F000764FE5E70194BFCB5F63FEDE353B8FA070
-:10A400009E5B2C3B908E0F6779D600DD765AD87D07
-:10A4100084CB37BC81FCBA2193DB09D6D050053CF4
-:10A420007BC3FF9E1BC0FF9E7F24FCD57E66713ED2
-:10A430007AD577CC4BEBB4B038A893E3E9538D636E
-:10A440000487D723B09ECBCB02B9361992860389F5
-:10A450002CEFE8DD62D80775D75BF09EA379EB3E61
-:10A46000C98F3C97224AB5FD7F0EF8A8380CAFE69D
-:10A47000DEF07D16F0731DF82ADB7F60F826698315
-:10A480007A27C44D4FB37BC746043ED547E6BBBCD5
-:10A490003580E9DDFEFC1E6A75DED65B032C0C4FB1
-:10A4A0003C1EB366C6BB63201E23F8617C0C6901A9
-:10A4B000FF3AA56B27A76B27D0B5A0DF705C867E1F
-:10A4C0001785BFC2F44B147969EF0E50DE0B46E1DD
-:10A4D00016B801DD06FE9174DB4AED5F8C63BE6247
-:10A4E00042FF891ACE5F71B80A786BD3AE0F676DE1
-:10A4F000DA0F03676D9A43E17F10F0EE4B3FA9F14D
-:10A5000023E61D854F8BBF0F9F36A67339A50D62BD
-:10A510009EA81AEF3169BDF0DE3FEDFA7857B6FF1D
-:10A52000C07857C34D5DD6F0F8A6FA795E9A88FFD9
-:10A53000FE3070FCFFCD7F3EBFFE90A27DE18677AE
-:10A5400014ED8BBC1F28EA638281722073E10F1F18
-:10A55000772184F6E5F7F5ABF7E54F9FFEF20A0D9C
-:10A56000C4DB4A02CC9FFF65BA67531A85F3FB1A16
-:10A570005FA385C275E49916766F57752EE60FAD09
-:10A58000E373FC6ACC7F9DBD97D2CD57C480FE4E4D
-:10A59000FFA19BB48EBCDE74507A45435C11796890
-:10A5A000A5469BD685FE1AE28A46370F70BAC1FCD3
-:10A5B0001FCAEF5546A2B3533EAFAA9230DFA98A15
-:10A5C000B07C685AFA3DB47DBA96F8E1DEE34AB34E
-:10A5D000D66FC0389FF23CB381DF8B4CECF18A73AD
-:10A5E000CDB24BC6BCB459252C3E7897B905CF9354
-:10A5F000CE39BEE9F2BDB49D6CF616B37C6B71FE2C
-:10A60000EC8F9AEF12F77B208DF17997C4E3C89213
-:10A610000EEFC7527F37378DF1D97479A30CF92E1D
-:10A62000A10F08DADD82EFE8FA8E1B0AD9F90AF8E1
-:10A630005D8A4AA2F30FC6F3CE0F97C3FB35271DE1
-:10A640000897BA928DF980C7BA09D239437E785FEC
-:10A6500053B7E16BECA7427EB111DEEF3ECD5CE17A
-:10A66000233BE83EC511E9AF0C2E00BEBCD1FE472E
-:10A67000CCFB4C831FE9E96CC3712CDF1FF7FB6235
-:10A68000B033820D81A87EC9EFEB1F107E01E12758
-:10A69000107240DCCBB7378DCB05A33400EF53D31A
-:10A6A000B252C8CBD7D27AD92B076E205F0FFC23CA
-:10A6B000E5EBB7A5F39A64A617D5F4ADA66B41CF29
-:10A6C000709F37FC1EC15DD4DE03BD3A9778F36AF4
-:10A6D000A89CAD5AD1A41B2D7D7FBA5E65FE3C833C
-:10A6E000443967F2DDE5B983E54796CBB83F10F909
-:10A6F00009020F9DBDF1D69D767D3B53D9FE0FB764
-:10A70000E33F5FF0FDF41A51D80396F45EEBB6A573
-:10A710005F7FDDCAF61F78DD11E75F16C89AF07912
-:10A720000FC81F063BAECBC7CE33566735E13DF2AF
-:10A73000A424140B76E3CA8332D221D1BAB42911EE
-:10A74000F74D7510FF47408F2BC6ACC07370BDEE40
-:10A750008932B7E2B938F57D51225FB896F7A3BECA
-:10A7600037AA96E709D7AAF27646A4F3FCE042524C
-:10A77000C8F22B9476A9BAEC6C200ABF64E7D50620
-:10A78000F4038C4B6FF999372D8C8709E9BDECB830
-:10A79000C937C0DBE47F24DED4F42A5B76E379A8F2
-:10A7A000EF4AAF57335DF3D313C272781EE47015CE
-:10A7B000C13DEE061FDCF72FEEC7EE92D87D345D6B
-:10A7C000E708FA8D6E74BFF2A8931E3CCF39F25D94
-:10A7D00097CCF20858BE81B05384DD32BA2324B33B
-:10A7E000FBEDF939289E17F46DE5973360453B473B
-:10A7F000F8DFFE5E7E6BA1E70E1A995C13FEC1A224
-:10A80000A01BEDB84E9DBF18EEB3F7EE3745B5036C
-:10A810007E96AEB9EE3DAE7FB5787E06F43293CB30
-:10A8200077719F6B85CCEE7BEE0EC8E8BF5BFFCFE8
-:10A830001FFEF649C78DF7F575D6EEA8FB2251D657
-:10A8400069D87989C27207E6EDC17E09FC77C29F9B
-:10A85000A77EFFF5CC321FCCAF421E83F76B76EF9D
-:10A8600060F3E90B2F751B42387E9FED7CFCBA83A9
-:10A87000C5D6C8FB30CEA5F7ECCFACE78D61BC7E6A
-:10A880005BFC8F0D5529EC9BFFD7F70DD3656A3A1A
-:10A8900052FD9827F9987D4A989D3A8F04B05C4004
-:10A8A00042587A08CBA75F4C9C582E256E2CA76582
-:10A8B0007A4EA5637E4B2811F3215FFDEB50A09BE0
-:10A8C000CBE3463741EEDC0F65A775153870FCAE5B
-:10A8D00057FE9A01792D37E2FFF858D70598A73A25
-:10A8E000AEF16FA532C64F88712DCAFB4A7E4B026E
-:10A8F00099C0E262DB12B390DFC2F22FA959C83FC0
-:10A9000088B7E69DD3B0FC909512DEE7DA16D42026
-:10A910006BE52DCBF2C1FD3C6DADAC3D6F8DCD2710
-:10A92000D17ADE28136BBFDBE683730FF34910F98E
-:10A9300071219C7A90E11C0C936FE2FE736AB167FF
-:10A94000839DB5ACDDC8F2F7497020C8F1FC3EF636
-:10A95000371332189F0FCB66727B5899D20FD18F65
-:10A96000B7AFCC2C5B960171D90C574C065DDFB0AC
-:10A97000B8C0B6478AD02F8FBFB3F2C5A87B307E50
-:10A9800028BE6BCA2CB3C27B2F492CDFDC7B90FF27
-:10A990006E01092546DE273A2DB33C11DE4BCF2050
-:10A9A000DC6E8E0E57F83D3A7794FD9CC8671C0606
-:10A9B0007B2AF48FB37BA95E92583DFF19EB1D9B58
-:10A9C00087A20FDF0B766D53A66730AC63989E109D
-:10A9D00033CCFF69836F17DA9FF519E08F5CF18C38
-:10A9E000410376C1C754ADC2B9927F6F3062F90995
-:10A9F000DDE742F91F749F0BE539BACF85F233BA10
-:10AA0000CF8572D91527251A42DEC970B9603D225B
-:10AA1000DEA69EEF28016F31FE413D8EBF32D3830B
-:10AA2000F0EDC1F77EE28378C84BB6506ADC75E87A
-:10AA3000AD6F39E3E5FBBDE8F959C332D8BE36BF87
-:10AA4000558B7A3CBF2D18BB3CE2BDE9197A6CCF1F
-:10AA50007BE5733C27DA69ED81AF4BA24B9EAE617B
-:10AA6000F5E9CFE4227C5766BA96C1BA297FCF8038
-:10AA700075E4B77DF82F709E87F68F79045D52E8F4
-:10AA800031B4F355EB50C341ACEB255B601B7CFF4D
-:10AA9000D22BD9B0122A6F08E31BA02329DA7A3708
-:10AAA000E27CEF30848AE09CCA1DD7E4A879C32BEE
-:10AAB000334B11CE12D05B42049C38BEBE2F5FF7E1
-:10AAC000C4B3399D1271BF06C84E07E8A1ABB1608F
-:10AAD000D755F2787D5BEBC0F7617DDEE33219E498
-:10AAE00040FA55F0DD0E8E1F51E61DD4BB014F2FED
-:10AAF0001D3C3F10EE5FA5781908F7B16ECD18A484
-:10AB0000F02FE68DFAE68947ECF83EFCB21A95CFB5
-:10AB1000CD15904F32D778E82D58D27CEBB90AC8C2
-:10AB20002759982C1D837291236B22E491887CF71E
-:10AB300025434A8F012B4D7356A23D560AC225422A
-:10AB40001F941B63F865D042FFC42BEA9392072839
-:10AB5000DE9FE2C851B44F1D728BA25D8C3BCD3994
-:10AB60005CF1DEB0B85036ECBFE83AD8FDD7CFCABA
-:10AB7000987797F7CAC9DB6EA1F5E9CFCDC2FBFE86
-:10AB80005EE2EDD3F795E3EF0B765178EAA92175F4
-:10AB9000A1E4C1C71E81CE54F67DCDC15F1E7339BD
-:10ABA000AE63DFDFC0AE17F27575BBB118E4EBB76B
-:10ABB000B5F3D578792583DF1FC2EDFEBEE8A58702
-:10ABC0001F2407A3177EDF969A5E20B394D11F2B14
-:10ABD000A79F60E7C0BEAB1CFB13C8B18873983D4C
-:10ABE000A5CADF364CEF7C7F1DF8DFDF93099EABF3
-:10ABF000E3E7F396C3BFE5309D93A5CDF7C37D5240
-:10AC0000F4B917EC4F3807EAA2FD5FCEE07653CDDA
-:10AC1000A1FB538AC2ED64FD39C5FBE43E698BA2FA
-:10AC2000BE394B59DF5EBA25F2FBBEE4E1F21D8B63
-:10AC3000F41E3CBF2945FD3D57319F8AC326CCCF2A
-:10AC4000BB1DF24EE8A3DAA20FB4106FBDBD0FFD1D
-:10AC500029E4CE1C99D4476BBF92C1E28ED30E9BE0
-:10AC6000309FE5BBF6FB318525E60BBEC6F4E7C792
-:10AC7000FD03DA48BCCB99ACFFCBC50FFFF35F20D7
-:10AC8000EEB99F60FEE6651B93FBF9AD5F6834B4D7
-:10AC90001CD68FD14BBE35A8017DD2551DE385FC56
-:10ACA000FCBA9516CCEB1C961DFAC85840484CE6E9
-:10ACB000B69F1B29BDFD110E3346E8D32ED8E3D035
-:10ACC000BAFD5F1FBC6333FDF7D4C326BFE67BAC80
-:10ACD000C74E6D28D47F658CBF1700DD70BD02BEE6
-:10ACE000F3BAFB498F9E017900EB87FA6D990FBD8E
-:10ACF000FF289D77DD3B8CBF21534EBD6F9F1BB15D
-:10AD00006F274F31BE34D2FFC09E5B75B4490FFB35
-:10AD1000B91BF3770BE6CD7C5BBECECFBC211F9F6A
-:10AD2000984AF152B79FDD33D1DD3E08CFB5F6A585
-:10AD3000BFEB766890FF44BDB35D9E0CF4AA3E273E
-:10AD40002EE049ACB98A7B9CD68EFDAF19A027D7DF
-:10AD50001ED4B2648FBEC6D9AA218E88715E7AC312
-:10AD600050CD7EA792CDBF4BE8E7837F8E2B1DCAC7
-:10AD7000CA8D51F41CD5CB3A3BE8E54AF67B0BA7CC
-:10AD80000E269501FC4F49C4EFC073572CCF78268F
-:10AD9000EB0E9E9BF1FE90E421DAC87B0EC53E725D
-:10ADA000D6C15983C08EFCA875F1298A19B22833FF
-:10ADB00007E96536F1A2DD7BCAE64E077FC3741E44
-:10ADC000EF3F650B75803C3E35364682F83DED7FA2
-:10ADD0003389B8AFEF94CE9DCEEE831079C5377F1F
-:10ADE000AF7BDB2AE4FB4AA742BC7A1EB1C23EF22B
-:10ADF0000E99D9B5E44DC69742DED549813898E71A
-:10AE0000B4CC19EB3221FEBBE167B8AFEC819B9665
-:10AE1000FFDED3B7B46B7BF6AF7B24764F8993D933
-:10AE2000FBB5632EFD62369C73A3FB6C89CE677104
-:10AE3000DB21BC8747BDAFEED9DFFC0FFDA3BDF71B
-:10AE400047EE87607DC2EFADDE27F5D8E5C2BE7B59
-:10AE500096E5B91F19FB78E76A5A5FFF6C0CC2F1DF
-:10AE6000E233062FC8EF8BBB0CB8DFB918173AB323
-:10AE70000EEAFBF29C5E1C2D17CF7709FA5EA171DA
-:10AE8000FC01F40EF99D0EEFDDF8E26903FEBEC78A
-:10AE9000CA5FDEB40BF64F5FA43B7EFD22F8F77E5F
-:10AEA0009D80F7019064F6FDED9C1F81BF1C141F6F
-:10AEB000F2F316B41B56BE9C82F24BE0EFC2D326CF
-:10AEC0003C077FF1F8CCFEE007EBD0EC65BF3329FF
-:10AED0009BBD208757EF32A1DD47F49E9760FDE5CB
-:10AEE000CFDF3E7B388CFF610281F574B5BF8CFEED
-:10AEF000C7307EA3EBF5EEF61C26077AF42CCB9B2D
-:10AF00005D18BEA7F915E87F0D11F720B2BCD94234
-:10AF10005962BF3BF950F473E0C73299BD5823FC26
-:10AF200025F1C4980C7CE821ECDEC78706E33DBB25
-:10AF30006733F9F96512E2E71D05BD9DA93D80FE65
-:10AF40001203CBD7EBE35ECB1399367C7FB9F16B61
-:10AF500085DFA476C315657D28FB1DE6C246C7F0D4
-:10AF6000BB69B98EC3F9BF92DCA7607DAB5A1E7E68
-:10AF7000F55D84CB533FF9238C7BDC8C7E1AF22E5B
-:10AF8000839F7AFFB2DC18E271876685DD7B7EE7FE
-:10AF90001F307FE4FC2BB7E0EF942D9603E7E17EB2
-:10AFA000AC4E4BE0ECBDB4DC77FC04E2453DDF5E2B
-:10AFB000717889C9951A58C770C85F715FCA44BE55
-:10AFC00065FCFEE9B63C849FF0D3765D8CBEBF1273
-:10AFD000F314FD8BF989FEC57BDF707C5DD607F22B
-:10AFE000412FFB200E11B1AECBB1817CF8295C5F03
-:10AFF0003ACBE7BE1C47EB117473A378CDFF055C19
-:10B00000F134E600800000001F8B08000000000003
-:10B01000000BAD580F6C13E7157F77679F1D623BE0
-:10B020008684FC217F383B10D2262447FE786902B3
-:10B03000E39A908822B69AC0B48CC138DA42293497
-:10B040008D97C086E8242EF5C43F819A69DD46A716
-:10B05000D2192618D2404D3340AC02E68256C8863B
-:10B060005A77651ADD2274CB5A16AD2149195B85D2
-:10B07000D42D7BEFBB3B9C73025BABD98A5FBEFBDD
-:10B08000BEEF7DEFFDDEDFEFDA00E26A15C0B3B997
-:10B090006F80A31AE8137667037C05CC4F56A6038E
-:10B0A0004200ABE87F099FD7FDF62EE703580DBDA0
-:10B0B0004E2806B8CE776F130580E1DEEF3B550FC3
-:10B0C0002D5AE2BF590AC0697FE4C7CB00C6E9B375
-:10B0D0007832057000ADA3CFB840BF1AC04CFC6DEC
-:10B0E00084D208F2B9E5F7687C25C02C8973DC743A
-:10B0F000E3742114D23A9C97E33548FB5C7214E563
-:10B10000D9C6878B24DCF7AC18AF0021B96F1BAF11
-:10B11000B2E7C3DCD58D10A4E3E215612FC0E8745B
-:10B1200011B80CA433E58492857CFE01F251E4331E
-:10B13000EA84B63E3CB7A6898FF4313D1C833ACAF7
-:10B14000C703C7E4AB29C3E7E5008BE8B9DB943B51
-:10B1500080CF2BEDEB93FAD8C767249EE95793C9AC
-:10B16000477ACB27E3F1B8391F85B840B8E2679535
-:10B170001B716F307107500440BB3C678E9F737B1F
-:10B18000E24205CAED736B02EAD3700EED82E3066C
-:10B1900047FC4DA29C02B07D06AE3DEB1CBE2707CE
-:10B1A000E1905BE6203EF5A67939E4B506D7EDE2FD
-:10B1B0002240E7BAA187D17D5C82C9F1451863546A
-:10B1C00001BF8328C2CFE8120833DA021146974242
-:10B1D0000FA3CBA097D1E59060141E8E4721402786
-:10B1E0007DC77F331DC9634FF3E3486BBE0A915E91
-:10B1F000CF641CBE4938D43E08078D237FFCAC3891
-:10B20000B4809ACBF8A5E25150CAFC3B150F17F950
-:10B2100023DA2D0D62B94417812E105D4C8E8B7C84
-:10B220001E05C941E32650D8B8F97FC4A14E571D69
-:10B230006AF91478344DED173B4CBF1827DD6726AB
-:10B24000ED745292D8D8B217A09CE1F993ED683D05
-:10B25000AF496FFCBBE407F841AC31ECC8C3717572
-:10B260006357318E8F49ADC6B8A1F117411C1F8FAE
-:10B27000AD0C3B1E21BF6EAC76CA00DDDDABC24B10
-:10B28000705E4DF35500C615B495F0E43F5BFD06C6
-:10B29000FE6AF736D98F71A4167A64D2CFED42CC0C
-:10B2A000103FA158803AA4454BE3179DB86E89A87A
-:10B2B000F6503CB6BBE33E0971DFDADD9C03A8EF34
-:10B2C0006ED158EFC27DEEAAA45EF85C4BC3715FED
-:10B2D0005F591717BCFFF9C8F790544B72CCD58053
-:10B2E000E438CDC986251B73DA304F0C279CB04F4C
-:10B2F0004A9EF3A31CF508C901EE1220BBE7BB0D63
-:10B300003EC37D65656497930412CD6705AA09B7AE
-:10B310000F73C22769FDA8D7F0AF936487DAFBD318
-:10B32000DF4BCACF697DEAF3D10F5100DC7F415278
-:10B330005F27793BD23F2DA1BC34B2E0BD5D7A20BE
-:10B34000E9A71C9EBF06F58E2A1013591E59E8BFA7
-:10B35000897914D006E368CFD10DC80771A809AB6D
-:10B3600051273EFEC29AB1102629E27B8ECEED1007
-:10B37000F5A205B8EFA5953744C3CF0A0C3F33F3C8
-:10B38000D0F90BFDCFE71BC3304C88AB8E0B77FF9A
-:10B39000F927C4AFE3B647A6E5C9787AB90B7CB400
-:10B3A000C863CB1B569CD59F75C5051F8D1FDA4002
-:10B3B000EB16BD37504C7A2D1ED0A35EE273FE0F04
-:10B3C000F9861C665D503EE13E4F5D6816283903E4
-:10B3D000749E16622EC4AB938B5CF2D2F824276B5A
-:10B3E00028FF5FDDE81F19B45EF1E4A15E9B4CBD50
-:10B3F000DAFB8FEEF222DDF4CA93CBA182C2C1C97F
-:10B40000F2B7845F8AFF2DC79DC97CCE7ED110A87C
-:10B410006707589FB8487ED0DE6B5FD701FB3FA619
-:10B42000BCD33131CFA35CC392378BD9CBAC57405F
-:10B430002504F93D6DEE253D3C24F77931E6E29097
-:10B440001EEA92FD3436E3074EBCC0FCD25A0FAF61
-:10B450006432DB5BF1F4CC1E943D338957E53197C0
-:10B4600042B8571ECB5148BF4A11D68519DE31E686
-:10B470007795E81B1CFAD36BD3C7823C9EF3DAF9AD
-:10B4800052193328BCB15381BFCC49CAD769C653BE
-:10B49000B370A249443FB8FD14F83124A1B3FFA70B
-:10B4A00051378E3BF702AD80DBF4837C6E0FF131B8
-:10B4B000E253DF5F9D4BF63E65C6A72B97076902F7
-:10B4C0004E69D234904A93630B5F97699FF4D21907
-:10B4D000B679AF3CCBB63FA32E68DFAF2989F21017
-:10B4E000E56363FF74E561DBFADDBE962BE4978BC1
-:10B4F000121B97132E994BAB6CF32170B3FEA1B6C0
-:10B50000C023C7703FDC31EA791D7E593D808840F9
-:10B51000FA35E8003F467BD40F3B6C764FD3D11F02
-:10B52000715DDAB50976C73F97641FCF0F987E50DB
-:10B53000000513FD2089B3E71E8ECC0FFA7111E1CF
-:10B54000EC1563D8724CC22904733268BEF68A00C7
-:10B5500031867B971CC7E733C376BC73DAEC78E798
-:10B56000A9767CF337D9F12D8CD8F19DBDDD8E679E
-:10B5700040B3E357BCA7DEB67E6E4FA36D3CEFE051
-:10B5800032DBFA8762ADB671D9F1D5B6F5F37B9FA0
-:10B59000B0CD579EDD6C9BB7FC2AD5EE0BE29DB675
-:10B5A00075A976AFBEB2C3C6D7B2B386DFFFA79D7B
-:10B5B00037A7D8F95B281BC5DDDBBEA1FD14865F6C
-:10B5C0004E37F252B3B030A190BD173A65B2E93BA5
-:10B5D00052669397E2DDAC4361B30E417817B37BBB
-:10B5E000D8F41339215FA23C5A753DDCE4C3718D58
-:10B5F0001EB944E93834D4D39421313791FCB89E34
-:10B60000337179BC8E03872D5E709C9DC46DA5D669
-:10B610002D64E0E2864F6351962EC9A9F0FC567363
-:10B620009EAB33F2FA0A250D1C13F058643E072A2C
-:10B63000DAC86FA131052BCDFB00F6E520525FCEB5
-:10B64000BB63D1C054FDA47C50607D92CAFAA6CBE6
-:10B650009CEA24BACA9D28A2FA75285B7D298079C4
-:10B660007E849725D667717A94941A25C558D17926
-:10B6700027AC9453FF8EFFCEC2BCCB5F0D6B1E2652
-:10B68000BE5F47F955539EC301F55000F11FE4FC1E
-:10B69000BBAA71EFDBF51F1551FD71098804E6C1E6
-:10B6A0004C9FF2133A47DBBD703AB35B0EEA8779E1
-:10B6B00054E725D63F683B38761FF888983D3221FD
-:10B6C0004EF73859DD01F37EB4D6C4CBBA1FAD3185
-:10B6D000CF1F44169B304FAF3D7B99E1B2257718C1
-:10B6E0001C99CCDF589FF46481A76A1FE9A454CB4E
-:10B6F000ADF3E9B9755FCA173E4B5D6C16CA33F4FA
-:10B7000029FA458B6EC91D62F7B97BFB4F1875E4AA
-:10B71000FEFC355667937A1BFC07F7A6B3FA32B8DE
-:10B72000B7B0916892FF08E3BF36F2AECD4FD66D49
-:10B730007FDFE67FEBB53FDBE6F5AC31673EEAAF96
-:10B740009FC96BF93AE277EBB42B44F746B4DB358B
-:10B75000B28BC55F3F306F099DF7DFF5FC1BC377E8
-:10B760006067021C73927ADED8799D8DF59D3AA3AD
-:10B77000A97A5AF74C8B8A17A1D481F619E3A6C986
-:10B78000470293CFD91C34FAF08147B31BA9CE0EE0
-:10B79000148A0E839618E3BC3AB7316E594A74D4B2
-:10B7A000E9D943F7CC010E140EFD610DA7BCBA1EFA
-:10B7B000F97E3B5BFD98FCB363F3588503E3A1A3DB
-:10B7C00052FF0647A97FBA7A87F4E7B0BDCB9BC189
-:10B7D000E42CA1BE6388D72A38CC0515C19C15D4AA
-:10B7E000970F4DD346A812971C99618C45233E4272
-:10B7F000C17FB178A8F1ABFF263E1F70429CFC567A
-:10B80000FB25173BCAFC4D175BBD2C9EDAE8DE45D5
-:10B81000F75DBA6F8CA619D419E4987E620AA55E0A
-:10B820009D682868E4B566617F0947FDC1411750EE
-:10B830003CE0390AF515DA7957EC288EB35176EAEF
-:10B84000537E2D1AFD7CD5AF5C71CA1B1BDD77982A
-:10B850009DF28201C62FAB183317F2C97AD1158B2E
-:10B86000927C7AA26805CAD7E3C4FE85E2FA1ACEB2
-:10B8700023DF5B07E61DD937C11E7941E37E084F00
-:10B880000118F3398769BEBD7FF006E5918B01B5DC
-:10B890003088FC0779294479A4DDF7A648F9A73256
-:10B8A00028B17D282FD317F3C1773986B3DBFF0189
-:10B8B000FAEB3A4C3619747FE3D5B9C15ABAA7E806
-:10B8C00022F1438F60FDDFFDF4BFB521F1C372A407
-:10B8D000235EB988CEB1CE45392A898FA5B72547D1
-:10B8E00092CF83FD7AA37BCC16BF375FDE5D4271BA
-:10B8F0005225700C9FD4F52D262E034EA3FF4B9D91
-:10B900005F4FF6AC9DC23EF3007291BAA661AD43A3
-:10B91000BA927042FC6E7D0DF5617D8BB280ECDBDE
-:10B92000DEEA91296F59FC918FFAFA03CEF92427A8
-:10B93000FC25B2C3E6C8F7CE5C9592F3E87FCCAEA7
-:10B94000DA01C35FDA2FBC7FE3793CE5999FCDAF85
-:10B95000A63C6DED4FC579C42BB1F73B4F087186FE
-:10B9600023E2BB9AF8F75DF95D36E162E1FC79719B
-:10B970001D2D4C88C47FF4F0DD2209F7B79FBB7CF6
-:10B980009DFCB6DD7CBF00A7ECEF0D102F8DEE9374
-:10B99000F7EA08E5D6D96C9A9BD8B7B9ACFD050E85
-:10B9A000FB7E6CD0793CEF94796F394BF9628AFB5E
-:10B9B000EDA904CF4AF4A95CEC0BA9FE60BDA77AFF
-:10B9C00063D5FBADEFF22C0EB60680CD935C6457C9
-:10B9D0004E7F8BD51FEBFD4594C3BA8AB8758AEAB2
-:10B9E0000BE497A076B17A24CC46BBE2BEBEDF2C36
-:10B9F00033EF69467DAB35EB592DF121F9CB335847
-:10BA00009DAB31CF0DB9B17F0A52A9D0CCF734E646
-:10BA1000FB8CBD6FD9EE77FF01E91E35E2601400A3
-:10BA200000000000000000001F8B08000000000064
-:10BA3000000BFB51CFC0F0038AD5151818D6293159
-:10BA400030DC5266607055616038278F90A31556C0
-:10BA5000E5A04CFF0B4606865740FC0688DF319276
-:10BA6000AE5F4B18C15EC9CBC0A00DE4D7006955CD
-:10BA70000106062E205B0788F701F9F780F81510FC
-:10BA8000BB08313070F331309802B11810EB02E589
-:10BA90007D81F4373EECE6EB09E3B7FFB9002A5F9E
-:10BAA000521095CF20805F7F97207E796921D2C385
-:10BAB000C44E9DFCF868A240EF40E09B0CA87C0BB4
-:10BAC0005906062F3906861E7908FF1A92FC3CA0FB
-:10BAD00098A52C345CC5816907C8BFCC80DD5C1992
-:10BAE000A0BC36507E15D41C00DF43986568030067
-:10BAF00000000000000000001F8B08000000000094
-:10BB0000000BE57D097C54D5D5F87DF3DE9B2DB384
-:10BB1000852C842D4C58141070085B1094C9860134
-:10BB2000020C8B881675588410208980FD51B51F32
-:10BB3000139688967E0DA2965AB0030D82FDB00D25
-:10BB4000183560A0C366B1451B5C10BB7C1D16D9BF
-:10BB50000C2404A5A3C5FADD73EE7D99F75E664853
-:10BB6000B4FEBF7F7FFF7F102FF7DDFDDCB3DD73F9
-:10BB7000CEBD910D76424613F235FCD07499400843
-:10BB80004989A6F4E79F5FA71232C94CFF2512929C
-:10BB90002FDA081942C8441B099A689D89A3E8C78F
-:10BBA0006442DEAD128222B4A1F502C3082926EC5C
-:10BBB0006792446A85DB0969CE7AB562909B10C1B1
-:10BBC000EB25CB3369EA769199908E3AF085E020A7
-:10BBD000C4996520A40F6BF335FD9BE8B5625F4AFD
-:10BBE0003EA9A083269FE2EBACA9DF71460F4D79F9
-:10BBF000277F3F4D7997A24C4DBE5BD91D9AFADD48
-:10BC000097E768F21981719AFA3DD74ED1E47B57D4
-:10BC1000DEAFA97FEBC6D99AF2BEC1624DF96D3B8A
-:10BC20009668F203AA1FD3D4BFBD76A5A67C50E8C0
-:10BC3000694DF9E0A3CF68F243EB5FD0D41F7E7269
-:10BC4000ABA67C44F8579AF29117766BF27736EDF3
-:10BC5000D5D41F1D39A8C967933F68EAE79ADFD793
-:10BC6000E4F35D7FD6D4BF3BED8CA67CACFB534D9B
-:10BC7000B98207E3FB5CD37C9FE0F987A69D447CF7
-:10BC800014D884184919A6665289A99554636A2361
-:10BC9000F5989E49F7DF8FF8F962A08250BC5B15DA
-:10BCA00068FAEF249ABE9BD5D3E9EF0FBD7909A1BD
-:10BCB000783B91754D269A6D2191E299C94C0216F7
-:10BCC0008A0A8E08C5B7248A771182A92B42F16DA2
-:10BCD00030C5BB8819D30E910EF83D29E2C2343924
-:10BCE000D219BFA744D2304D8DF4C0B463C48D695E
-:10BCF0005AA41FA69D227D30ED1CC9C4765D221E6C
-:10BD00004CBB46EEC0EFDD225998A64772F07BF798
-:10BD100088175377641CA61991024C7B44A660BD1A
-:10BD20009E111FA6BD22F7E3F7DE911998DE129946
-:10BD30008DE9AD113FA67D22C598F68D1461DA2FED
-:10BD4000B204DBDD1629C3B47FE431FC3E20B21C13
-:10BD5000D381919598DE1E0960EA893C8DF50645F0
-:10BD6000D6629A197906BF0F8E54623A24F2027E87
-:10BD70001F1AD988E9B0C8564C8747829866457E15
-:10BD800085E988C80E4CEF88ECC6762323D5988EBB
-:10BD90008AECC5EF77466A31BD0BF02D09F02E8491
-:10BDA000A937F27BFC9E1D398A694EE43DFC9E1B3F
-:10BDB000A9C7342FF227FC9E1F3989E998C8694C1E
-:10BDC000EF8E84312D885CC2746CE402A6E322CD30
-:10BDD000D86E7CA409D3C2C897F87D422482A9C238
-:10BDE000EF4896DC1056F0AF07FC7FA6EBDC6D94B5
-:10BDF0002F11BFE16B9A121BC58311D1FAFA94720D
-:10BE00003BE49332C5AB048ADF899417023F9C5808
-:10BE10002604EFCEA0F8911C3E0C7939CBE436D144
-:10BE2000FC03A44906FC25A4DEEE1B40C88111E7F3
-:10BE3000BB8629BEBE9B12EA46911B7E90DFCA30AC
-:10BE4000A79EC06F1BA430FD3E31F9608ADF06ED6E
-:10BE5000296D64027AD3F101BF293A025F7E402244
-:10BE600001079DEA71E86104D60B99687E6621F1AD
-:10BE700066D2FA15234C3382749C8A4C5F918FA64C
-:10BE80003FCEF0CD80F4F7403C74FE87787A9C1862
-:10BE900030FD32DD85E9CC477A337ACAA340ECD451
-:10BEA000361C1E4865ED88AD291DD6D7DE7612A159
-:10BEB000ED8646EBBF4C7C1FC2F7400EE953668B04
-:10BEC000D6A3DF4F42BD18DFFF1CEB7BAD813202F2
-:10BED0000AFF400763701BC827E2764E867999DD1A
-:10BEE000CE29F6F8F37A7285ABBFD44B3DCF20CE86
-:10BEF000EF4981CCA866FC256DCA00EC1FE561C046
-:10BF00006AC1FE450E7FA5DD67004FDAEE3D8BAFBF
-:10BF100091C9537757848BCDD52EB8D076D7112EB3
-:10BF2000126D676F7FBBF869258333F1BA711EFC10
-:10BF30007BA9890404BA8EA66DF6E0D60CC06137E1
-:10BF4000F2CF221767A0C9141854AE1725C21208E1
-:10BF500039BC3F2164A0F573B6D9B7821ED09813BF
-:10BF600078DE0770DE2A936DB4CACAFD3F3AF173DA
-:10BF70009ACFD9221313CD2F48786E18A170BB55D4
-:10BF800010D8F801EF815EB47F3F517EBC02F43FD0
-:10BF90009FB0FE1B054647816D4E84EB85BCAA8A87
-:10BFA00091340DEF5B5C48281F3F4FC1DA89E2F7FF
-:10BFB000022B9120A51CDC88F009C867C38A7C414C
-:10BFC0007A96A279B1757E3EE415FAA7EB5E1094DD
-:10BFD000A379FA77E10E6D5E052FDCF7268B1CDC6A
-:10BFE0008A78D585C1478197B70B831F87579E45B0
-:10BFF0000E1892115E41E0034EC18D7028B2C82127
-:10C0000091F65344E1082458B4EFA95480D3C21DDB
-:10C0100016D759D5B88BAB1335F9D2DA4EAEB32A51
-:10C0200039DA7CF4970EA0D3256906D759CADF1AEE
-:10C03000567893CED22DBBB2A20053053F16576758
-:10C04000B86C9A7EB4F9E64AA180E1B7DB396D405D
-:10C050007C3C5B9266749DA5A47A690793B797565A
-:10C06000985D304EC30A978B8D9B86A902AF45CB56
-:10C07000AD585F995FBC7EBFEBF9115243CE9881FA
-:10C080009FD3B29EF1EBC7A527E93323D2499D7C0C
-:10C090001DF0C64CFF7E6D403CC2BCD26F69B51826
-:10C0A00030DD0EDF776AC6A3EDDCE754F2253EDD16
-:10C0B0004AE49C0A2F97420748A766DC673FEDD108
-:10C0C00049FB6B946C6B418F9AC0F1A714EA517EC7
-:10C0D000B0D81C36FAE9A7CB356C3FE28D7369C541
-:10C0E0008E2EC0D78ACC9546605645D57DF3809E6E
-:10C0F0002ED7AC4A05F9B2506CFEBE2F46FB1F2B63
-:10C10000741B949BB4F232C8E749FBD5D019B1B582
-:10C11000AC9BE61B0C74285BEB7E7F2A30B953B2D4
-:10C12000F3F8989174FE25B5578D308F0982FFA7DB
-:10C13000424A74FD02AC9FF653BCE39411D677419A
-:10C140000EDCF278C64DE0D96A9EB6B47309AAF93E
-:10C1500005A82249E9757616A757E2BEF7CF943EA7
-:10C160002FFE41264FD379901BB4162D4FE7A573B0
-:10C1700089CF01F09A5DB310F9CF45E03F208749A0
-:10C18000E530C08FCBC45000EBBB4CDE730C56C106
-:10C19000EFA060E4F0A1AA2CE507261C0AE1D6096D
-:10C1A000F895A9A8A25E1C08DFA500E74BC2D7C876
-:10C1B0004F8202F2B322F63D40CCE5B88EB58C1F1B
-:10C1C00005E81FC83F5CA9E54FF3376AF3F3C8944D
-:10C1D0005489F29779CFCAB447CADFD4FC8FC2EF33
-:10C1E0006581C9DDF9A4ACC245E7BFD948F789CE5E
-:10C1F0007FB68B485DE8FA16BFB179D82C9A7F5B81
-:10C200006072ECD20A3AFD5B683F1DD8FA8B970743
-:10C210008DDEFEADD777A666F0F49104FB63F2B134
-:10C220005891BFC42D0D436E4995DCF8EBEF5223B6
-:10C230007A2D0EA847BFABF8F39CB5DAF5B5B57EFD
-:10C24000FD7A097906F1AD78C7640278A6AC47D9C2
-:10C250002F653DF20EC11B8C4107618EAF0A5F6BEB
-:10C26000E2F053F48ECF75F92F75F9AF757905BFEC
-:10C27000654EDF14EF3F1786023D378D6178123629
-:10C28000B2F30CAB678CD6FBF266F54C9C5E68BDD6
-:10C29000AF6F56CF12ED4F32A4B4AEB7F88D575EE4
-:10C2A0000F50FC2EFECD730E42F1F1A25499EAA17B
-:10C2B000DF176D5BE300385D90020EC09B8B41B1D0
-:10C2C0002016BC46180445DFB00974DF4B14FC1F70
-:10C2D000553E11E4FBF56DB2EB69BA2FA53B4C213D
-:10C2E00013DDEF929A05856420E64FB1FC93570168
-:10C2F0003F4A6BE5D3EA7D2DDEFE5CAADB8EFBD0E8
-:10C30000C5003A30097521342DA9FA640CE8D1A58D
-:10C31000A409F159DF0EC687A31DE5D7B38CCED68D
-:10C32000E5CAB9B1947D22A5353FBA0AE7C65222C3
-:10C330009D56E35111E032D5F3FA19ECC9705E2035
-:10C34000C3C970E02B0A1C483005F9F2AA977F3A5E
-:10C35000F0149D4743D51F1C820A3E544342B83413
-:10C3600057CFF95BD24DE4C2158A9FE41675BB2006
-:10C37000B673D7D20974A4D93A962E92438E9114EB
-:10C380009E8BB6C81E8A9964D12BBF7CE9054A777B
-:10C39000E46393A73785F7C2578E9CB883E617EE00
-:10C3A00092930BD9326C426A743F4AE95FB0CB2852
-:10C3B000F02F7EF588D13D807D7FA243741F16EE5D
-:10C3C0003A6024035AC32DB7FA80316C8BB11FD564
-:10C3D000A7C6803EB3EAE5BF1B61BF2FEE1748C773
-:10C3E0008CD6ED8BB61C41FD05E084FBC7F7A76535
-:10C3F000BF5AED5368E2DE2158CF05FC3ADE3ED944
-:10C4000041560F453CFEF55E3A7ED19F4C1E587F4B
-:10C41000D1AF973A601DE7A53286CF9BD7A47AE9C2
-:10C42000B8457220D58529FB5EF4E2A38867F38FB7
-:10C430003F8A7A19C58F4E069419814EB0BE873750
-:10C44000DD83EB9B47FC886F459B455F10F880447C
-:10C450000A76C5A087DF707A38BF95724ABABEF3F4
-:10C46000C01F41CF7D4FE4FCF111D4231FE56BA524
-:10C470009A0CE63F37B37DAA301814BB9C5983A7AA
-:10C48000554F221FBDD4CDDBD1D51FE1A0F04DE427
-:10C49000A7E2F1FC8E6C7F18FFC57614EF72E13BCA
-:10C4A000D4AF97BD96819A769C5FB2F197F1F1E98E
-:10C4B000BCADA07F9C4F657242BFBE3F1914FE48C1
-:10C4C000E5AB0ABF5474CDE8BCEA2946D70A9D07FC
-:10C4D000271740F9671F30FA8176207FE8BC421D9C
-:10C4E000B1FCC03401F980898462D17395CCE959DB
-:10C4F0005B4E3934EA6F74DE92E054E309EDBF031A
-:10C50000C21FF59279CFD2762A7DBA14C6C37AC6F5
-:10C51000E8F78C28DDCEE7F4FF2BA0FF8428FD93FD
-:10C520004D29ED3A9F2D92832FBD00F44AE933E067
-:10C53000067A957DB0EE4F771E3A713FC5EB4FAB53
-:10C54000153AD5F24D3D9D16ED7E94007EEAE9F454
-:10C55000D3AE6524269DD2EF31E9B46BF87F856FA9
-:10C560002A703BAE831BE583BFD8EB8E0F3F3D1F88
-:10C570002C35B863F241FAF30119D61AEF147C5343
-:10C58000F0ACF8BF1677077ED3828F0ABEB5E0A362
-:10C59000826FFA756AE1A62FDF04FC46A51FC82B3F
-:10C5A00049C04EF7B9699F88E7C4467793A3031D36
-:10C5B000778D853C047A76A38BE71359BE29C5583D
-:10C5C000017C41F9DE642133003F1B7D4D8E449593
-:10C5D000FE7CAA4E74B8697938480A62E9D594E3BA
-:10C5E000E2F86112AFBC1CE1972FDAD2970F81738A
-:10C5F00095E801DD6D6EF9BD0E305934D6F59C34E9
-:10C60000837E7FF86D116D1A8D56C74098173DB720
-:10C610004B9D287CE7F07DBE4002CF8FA2EB9A5362
-:10C62000C7F4E2B9EBB4F098675B66043E43F5CF1C
-:10C63000281EA8F045F113146DD296179375B85FB4
-:10C64000C53AFCF1F3F34E2791E3CF2032889F37B0
-:10C650000CD0DF12CEA7F2C5FE936650B8371E1578
-:10C660008989E69BEB445201EBDC290409D0712057
-:10C6700005F1B084F207A23A1736009E19E3D36F92
-:10C68000C36B7F1DF638ADB2E8F53F0FFC394D1B8B
-:10C690005EFFF8963721FFC647E97F26ADEBE7EE50
-:10C6A000FFE241E0EF8DFB4D04ED24FB7F97FE3868
-:10C6B000E4F79A3C68E75869F2A27EBCDF1EEC0DF5
-:10C6C000E5DD987D69D5BEBF0F0CA3BC598DFB94E9
-:10C6D00027B2734473DD3FFE5B488694AE0AE4E8FC
-:10C6E000FE04D4AF4BF75A8270E86CDCF7F7617E3A
-:10C6F000DB77B79E1223F123FED9C98CDD80AF8989
-:10C70000CC9E56FAE6885F96D3F117D71C30CEA19F
-:10C71000E5B9BFFD6A20F095C6DD4C3FB822875FC2
-:10C72000241E422689CF95CB74BFAE80AED699F237
-:10C7300025F14476C0160B2E0C0E8D140EB02E0A69
-:10C740009722E087F1E031EFDF161E571F84F117C3
-:10C75000D50D2762861A2E82977DB707CD02AE9F30
-:10C760007DDFFFF781C0773FAD2E47F9DDD6BAD721
-:10C77000C0BA53FE5F5AB7106ACFBAABFE6DD7CDC1
-:10C78000F0BF9FC8E4919E0E5AE3F91BDFC7FCAFD0
-:10C79000ED1E9C6F3BE9FFF0BFEDFABFE5BEEF1663
-:10C7A000D01FD7D6BE9FF9B75D775BFBFE36DF772C
-:10C7B000BB0BECBD8DFBBE4A27AAF5B7B56E83F463
-:10C7C000EFCADF6EBE6E45EFA93794B986D0F97D0A
-:10C7D0004C2AEFC9A0E91FBDD792E1384A69C017BA
-:10C7E000EBDC9029B1738309EC4C50F11E41B11779
-:10C7F000D56BFCB85D8B50CF98E8FD31EA07442A31
-:10C80000ABCFA6F5EB73E6789EC61A9927FD909FED
-:10C810007627CF6BCF531373C61F05BDEEDD723A7B
-:10C820003F885BE826B9A8A644267945D403698ADF
-:10C83000FADF87E963B0DEA42CED79E23EDD79E032
-:10C84000DE19DAF27B78FFD3C9332960779B3E97F4
-:10C85000D9DDEE25656B5CAA7DBA47D78F4322DC14
-:10C860004EF2EDE037B7057E4B101E245BF46C23CF
-:10C87000ED801F61F0AE9F3628087618227918FCEB
-:10C88000A62FF6A01D949F3365DE5EB6ADAD07BA48
-:10C890009589F67CA99C13DB8233E1E74FECAF4727
-:10C8A00014EEB257C4F3A7AA5F848BB21FDF741FC4
-:10C8B00094FDFBB6FB310CF62386FF6C81D97C0F0F
-:10C8C000F82FCC7D043CB74F5A27621C8CB9BF802F
-:10C8D00070F465C9E8DFF9C4E01B068A73E1E0E1A2
-:10C8E000258FB16E3D009F051C8EF34819EA9DE42B
-:10C8F000C6D75F8F02BF114286967B099940CF2130
-:10C90000F34609212B5DF77C89049C9960D714C8F4
-:10C9100069B55D33A8CDC3CF5DA9D17EDAAA1F8FDB
-:10C920003F7CD7E9DF283F3ADD8B9E572095707812
-:10C93000497D4E7CA88EC1B1749110EC817814921F
-:10C940007D2ABFCEC71CAFFFF6C460E473D93F1980
-:10C95000E0C4F3ABB71FEAFBA55CDF6F0EB89D60C8
-:10C96000AF69AEEBE9047B4CF3D15C879A2F2AE9DF
-:10C97000717E8E7C7F8519D3C63CA15284F31669E3
-:10C980009A887238CF4280EFE8DBED9114BB4B19E7
-:10C99000F333D21F7118EC23FB994F9B3A3BA8F657
-:10C9A0006DDD848BD2C0D6FB003FA7557E927F15EC
-:10C9B000BE706E05B81EB784C7F862ACF70F1C7E58
-:10C9C0008507BF30829D604A5D860C709992276A08
-:10C9D000E26E0E49FC3C35980C8679151E1CEB184E
-:10C9E00001FB7254F458287C4BEBAE1AFD31FC6D00
-:10C9F0007A7842FF60173E237BE6013CCFFCD842A9
-:10CA000002941EDEE1FE1F5AE405FE45BBF2827D64
-:10CA1000EC0389F915FACACC2E3EB5305B4EA1E382
-:10CA2000F6AF710D0211D399D7EF2BBBB1BC0B6FD1
-:10CA3000A7D4EBBC88D53B657495C45AFF04235B2F
-:10CA4000FF7CE2F97E96F0EFB76FD93FB187724075
-:10CA5000BEE709C8475AE33541FA682E1082207FA5
-:10CA6000E11C8BF94201E5FF3B06561E98C2E4A586
-:10CA700082F77A380B3283B3327E86CCF0D92833F2
-:10CA8000F8287056E0AB9FAF529FF2ABD16AFBCA59
-:10CA9000A4DA41BF06FDA4A44E7081E9AF440A1B8D
-:10CAA000810E4B6BD7CBE02FB8CFCDFA25926FA07C
-:10CAB000DA5FDB5796703E873247A2FE786D1DD352
-:10CAC0008FBD73AF3A400F7AC7E0F9E348A0C7774C
-:10CAD000458C278807C73FAFD8312D4F52F79B8130
-:10CAE000F39CBA285B0673D0F7161D903BAAF0A9F9
-:10CAF000AFDC01CB95EF9D17B933E13B1D0FE7117B
-:10CB0000F84F13D946BBE85F5D9F9340CBBF579664
-:10CB1000C8F0B0A8FA8011F319585F194F19474FA0
-:10CB20004FD30A1334F939B9E1AE009742536899EB
-:10CB300027069E1E96153FC93794135E8AB703FFDA
-:10CB40007F901357C77863C06D83DC4A3E748C2591
-:10CB50001F9694BB3B02FC97ECEBD9118863C9DBB1
-:10CB6000F9A9B1E4C3872B983FF023CACF206D9C6D
-:10CB700046E5C3ED2AF930CD82F8A16FF743B99DA0
-:10CB8000F241D9AFFF653EF321C88718745D296B68
-:10CB9000E5C3F4BA59281FA64F13895B658F7B52F2
-:10CBA000E67EAEB8F2213BF53ECCCB9E841878F3FE
-:10CBB000213F97005C218571404EFC96F37DBDBC02
-:10CBC00088C7CFA71805EEAF6E839FFF5F82B3C201
-:10CBD000CF97D0F30BE881ADF19020BF5E721FE5D7
-:10CBE000E702E023E3E74B1EE076491D7FF5017F76
-:10CBF0001DA2E6AFAC7D899FC983D2DA8C9FCEA4FB
-:10CC0000E5F757CA1E33AD7F7F94DF0E53F3DBDFAA
-:10CC1000727E4BE19CEE8AB1BF33662610B7965FF9
-:10CC2000F5023E7566D0EFFABF0A78FF8E887EC4A3
-:10CC30004FB81C3F36E87743C07E9E6C94107F3E11
-:10CC4000E1FCEBCA8AE0B43C4AC7B973993EBC78B0
-:10CC5000A7887028A9617A5E492F6BD04DF36332A3
-:10CC6000BF407FE0C27DCC1F48015598ADDAC78533
-:10CC7000EF842BBA40F91601FD99F33C0BD18E4F8E
-:10CC800036323BB199FE61711D5EB4232FE6F05A36
-:10CC900050B705EDCD0B825A3BF4E25EE32EC2396C
-:10CCA00040E1BF0B77E8CA3D4FA1BF6231D89B5529
-:10CCB000E70F91EB0F0F8BA1FEAF426CE71FD9B9C5
-:10CCC0004ABFFF4ABD96F517FD8BEB3F4ED73FE4B9
-:10CCD000BB5F7F7BD72D1B39BD679221401F9F18FB
-:10CCE000BC48EF81DFD3F5D371E6AEEFDD511D67B0
-:10CCF00094C4E9F21D83BFA213D42B11B0DEFC4D06
-:10CD0000BB8EA4D2FCCC6A3208CCF4F3376AE5625D
-:10CD10008B1CAE71A39C9D59B64B98DD1FE04DCA8C
-:10CD200000CFE6649AFCE04F3D6E6942FEA5E0DD6F
-:10CD30009D4686CF23F9B8673A37E5E139A25670A8
-:10CD4000215D842CEC5C41E16FA1F94323FE3E861A
-:10CD5000C31BED31A5B56C7F4AE97E005D8DA9E36B
-:10CD6000F91D4C0FFB1E9537E80FAB3B2043BB2250
-:10CD70005A3F09F94D3F8D9F0BFC73D9A9AA7DDB62
-:10CD8000778AE1ED36C14362EC5B1FFA27E6BE7D90
-:10CD900047F8AAC0E34E23D7E7F9FE1DB7D4170E14
-:10CDA000463F94E0D90A95EB12D18F72B6B227EEC6
-:10CDB000E3788EBF7ABC06FDDEADB2274D8689438F
-:10CDC000BC658105E3DC70DC1E4CFF51F313FDB93B
-:10CDD000B994D4A31E3341F0FF5552C5B54DE7F1C8
-:10CDE000278A9F5655EFA7F24DEA91349701F8E450
-:10CDF0005225DE12E28753316E097F0E751BF6D184
-:10CE00004CBADE6B6B450FF87FEE35B84F8C02FAEB
-:10CE10007D5A268097D78EC95EA6772620DF9DF59E
-:10CE2000CE19194C21B3284C60BF67FD90F1D73360
-:10CE3000D019FDF6272AB7BCE0AB27D543217E7871
-:10CE40009AE740BE9BEECB3D438EAF013FDCD45C06
-:10CE5000D7891300DFA74402F03DBD3617CF274B1B
-:10CE60001F1110AF4F523842FB7BA6659C3841C75B
-:10CE70007D606D0AFAD5667A8FE4039ECD9964B71A
-:10CE8000817F6D7C1F91F855707C80D4A39D626674
-:10CE9000D923F7C07C8BA81C003B6B51DDF1FC8EC5
-:10CEA00090DF2478DCB4FFD280DFD8916E61FDC6BC
-:10CEB000AB46B0B7CCA3F5607B4A37B17AA55582B3
-:10CEC000C702F858B71EF9CEBC2A81B8A03ED5F7E4
-:10CED000CCACDFA099F65BBF89B6A7F9F9D01EFAF2
-:10CEE000AD4A9C0E7EB4D263226B9F55FE16F0A510
-:10CEF00079B41D2D26F5558F607F0B3609248DF6EC
-:10CF0000579495F19F59D0DF31D903E51F1DF8994A
-:10CF100011E6FD201DAF13ED7F8E18CE87FAE47168
-:10CF2000C1B50DED4D2C4EB691D301F9A013A32F31
-:10CF300081E7B91EA8C8C3F78D3D109FE62D2FAF1E
-:10CF400080758503291970042AADBD6A04BDEE2CD5
-:10CF500085B39FEA6D67781CDBA1C0196358C5A72C
-:10CF60009A8C3DB1FDDCDA6CA4EF87890FFDDDFE04
-:10CF70007226874FADB10405D03F6417CAC9436B11
-:10CF80006E7D1ED67FE51519FDA357BA85D11E7B90
-:10CF90007E934C02748EAB3689C837CEEF64762010
-:10CFA00071B38CF9F98F1A317F68D3D431C00FCFA8
-:10CFB00053F8031EE66ECE37427E3EE5EBA618FC24
-:10CFC000639EBB98F10B1D7F98BF514BFFADF8C519
-:10CFD000B2318CBFEBF8C1E2AE1568E7D3F38952EA
-:10CFE0006253F84326E4EB439D107F4B8EC904F453
-:10CFF000B912C9F5E046C09B9916F01453BA081D42
-:10D0000001BE762D28B803B4FC7B0FED190AF03B66
-:10D0100007F006BA589784FED479C1590857259E5F
-:10D0200070FE462D3E2BF14BF7F945E255CB81A220
-:10D0300004E255D5FBE887142FE9780FD50A418B18
-:10D0400000F9536F3D3A04F32EC0C392E55C9EAEE7
-:10D05000B323DE7EF483AB6B002F1F7C42C0F993B9
-:10D0600080BF02E44AC946C10D76CCF94FB0F6F351
-:10D07000697BC0978F7EC6F087E2B11BF0BC64D39A
-:10D08000FAB7B07E95E086FE3FDA320BE56F51408D
-:10D0900024585E750AF5632A07300EE850404C05A7
-:10D0A0003C2F596D72C13E2AF8A2E0DF2999F9EDB3
-:10D0B00089D933702A6DB7C5E8C675EBF14E9C91DE
-:10D0C00081F855BA5346FC280D307C3AF58A8878A9
-:10D0D0007868CDBD883F57B60971F02FD7D809F0D1
-:10D0E0002FC8CA5BF0EF6581E31FC3EBF3CB183E9B
-:10D0F000E64239E0DF6B5C3F25C4A6D63B14FC5307
-:10D10000F0A92DBC6B2597E2E01BD58DA7C3BC967B
-:10D11000AEB1E0BC732BF64C5F8E7423A37F3EB799
-:10D12000E207A940A7F3241687A1C071B1C4E27435
-:10D130005ACDE3D97263A7F6CC47378F0351B9981C
-:10D14000097211E24A42749CDFEDFC25C6AF5DFE18
-:10D15000D5298C4B5CF826DD775AFFCA4E3B09A1D6
-:10D160003E1D44FE525C23625C289142C3A6AAEE97
-:10D170008F28F1160B7F6347F816EF36050B69FB16
-:10D18000E2D7CF0C447FF8CAA6B7807E02BF1298C0
-:10D190005D3E101E3815E22A2516F7A197BB234CD9
-:10D1A000CC5ED3B0276106E83FC28E03E84F2AAEBB
-:10D1B000BE5736A9EC931E938CE3D27AEC9E0BDD1E
-:10D1C00077F023C2FC260F50CFAF9CF5F732A39B1C
-:10D1D000E25A19F5A2E21D5BD0AE57BAE32AC6BDEA
-:10D1E000E6FEE61507C0A1B456D4C643ED104326AB
-:10D1F0008CD7124F99187FD2C42595D4B07B1925AE
-:10D20000D53CEE471717B3F037FB5E0F50D02C7CA0
-:10D2100075BB03E8E852FD3607C093F687F14493E7
-:10D22000B2E2C41BB5156754FD54CC38A34BF00FC4
-:10D230008A200F9AB4F1996407E35374D787F9628F
-:10D24000D833157D65E12B9FBF0871AF0DBB3F7DC6
-:10D2500011E6BDE89FD75E84B80DB2DFE202FDA102
-:10D26000F4571F62FCA0D26EB9899F7F5EDE8E717B
-:10D2700097573E36A1FE7765DFF974D00FAEECFA12
-:10D280002215E22997EDCB47FBC3B2D7723B921828
-:10D29000E75B2505BC0CB623EE53BF0F876AC4902D
-:10D2A0008DCEF3F24913D2774BBC58F562167FE767
-:10D2B000E671623B63C7D52AF14D25355327DD0959
-:10D2C000FCAD86C9F19678A7B6E2C33EA0FB797B98
-:10D2D0003BF66D278FFFD3EDDB65F807DD9FE74C4D
-:10D2E000DAF8B0CF6B1EFEC50B505613FB3E9942C9
-:10D2F000C76DC14B89DB9D63F2064D4037BBFF0B09
-:10D30000E3F060BF0ADD20E73F4F07BBE505B90941
-:10D31000ED814DFB4C2E88DB2ADEF711D2C795D765
-:10D320008E635C2CE1F1B35748CB0F8B77E43689E1
-:10D33000D22A3B8B2BE37087B833B703BFF3F832A5
-:10D3400086B74ADC59BC78B30F4D3DF8BD0B1617B4
-:10D35000B7D85D6F04F8ABE3D0842CD8A7539AF804
-:10D360003D65DDFAFE5C0087E1EAB8C978F17C5CD6
-:10D370001F6FD927C687AF6CE171942DF19184742A
-:10D38000CD84781F26EF4A83C24724063D2A719335
-:10D39000F57A7A0CB62F5EB2EDF97E3B781C32310D
-:10D3A000FB930297861BB1F9F1A79CBEE9B9E49201
-:10D3B00049752FE5217E2E51E2C894F9565433B9B0
-:10D3C000DBB083E9857A7A2EE1F676FD385FF0717D
-:10D3D0004A6A0F0C04BED370700FC73786CF253B47
-:10D3E0004F19039C3F07D5FC19FA8BC14F4433EB0F
-:10D3F0008F9E6363F657BAF36ACCFE2E49DE7B61DB
-:10D40000FE97EA999E71A95A2C08C6E8FF32973F09
-:10D410002DEBB61BF15C253AACC87F96D9B34E3ADA
-:10D4200093213562FCC2AA721EEFF0434F1AC079F5
-:10D43000957D1C81F9AC01F8A8CE99B2CB4F40CFB5
-:10D4400091D37C43E0FCA4CC572937261B4850BD20
-:10D45000FF5200EF474EECF17709E44BFD0AEDBDBA
-:10D460008E7AC9752489F6579F2778409F6D8D67FE
-:10D47000DAFE277B458D3D0C6CCFB0AE668F01F791
-:10D48000D36E08B9681562B7D4A7E141CE4DDC521E
-:10D490002A8674A35FFBE9153BBAC13D2B07F1084F
-:10D4A000506EF7B4DC6FC1FE9C4417671D201FC08F
-:10D4B0007D481B67264EE23A0076096B1FD207FCB7
-:10D4C000D62E62F5C0FB0A1BF8BDC775763FCADBD6
-:10D4D000B874E361F75E143B91334BD2DC8B49F4B3
-:10D4E0006AF349BA7B900ABFC62B7414FE63F8BB7B
-:10D4F0000F89F96CFD60AFEAAD9A6F620AF184A002
-:10D500007C820DE3996D36363F65BE743EC80F28A8
-:10D5100098D87CFA8703A087D379E9E898E0BD27FB
-:10D520003ABFD3BAF969F4B8FBCC5C3E4844023E3A
-:10D530006233D7130EE7666D9C698040BC81B305EA
-:10D54000AEB49CF693214C3241DC820B4EC13D714E
-:10D550003C5DBBAE2EF57DB15AF8C708F4171D36F9
-:10D56000829FDF2CC0F19974045C032048F54600CB
-:10D57000C64F6D4A3E84FAA2AFE6389E3F17571F4A
-:10D58000C77203E4699A94E0CEEB328890A7D6E69E
-:10D59000E5A5F5857AB3D20C1ECC1F96808E26FBAE
-:10D5A000D30C8360FA79AB0F8F22643B29EB07160B
-:10D5B00025F36AEFE1A3DD00AF083AED48C07B1820
-:10D5C0007073BB92A70C10DE57D86E6DC97BCD94DB
-:10D5D0002F6EEFD1920F40BE0A807F078CE73DBCD3
-:10D5E0001AE27CCCBED5663AEEE4CD06A4BBD111DE
-:10D5F0001B9E3F48B803F26742CAACBE18F7A55B52
-:10D60000EC3CBC5E5B7C7C3B8F479EECF77BE0AAEE
-:10D61000F7702E8F892B3C18EE63379A673F6F5651
-:10D62000D3E1E666B1079DDFF3B0F7B4BDB3C03513
-:10D63000AE0F9D9F739381C5CF9AFD3F87FABD9F23
-:10D64000F01BA0CA68125E2A001FFE4B32CE47199B
-:10D65000A7621F3B5755AC31045722FEBA05906FA5
-:10D66000D1FD0BEBF6AF89ED5FED29DCBF92BA532C
-:10D670006CFF6AB71C30727B3C9C5BB613CF2E30BC
-:10D680003DED5A3B234FA2FB92646AAA807D95C967
-:10D69000F4BCC2BE08D7DFC4842B9F5F5B70DD7E05
-:10D6A00061EB8F06825EDF60F0F426517829F54E3B
-:10D6B00098599CD864ABBF0EC6297D365C01E7DF64
-:10D6C000BD17DE433F70EF86E6D0403ADFDEA3B8F9
-:10D6D00039858FBBBD612BFA33B7031EBBC175EF14
-:10D6E0005F0972323E3C187EB7C0A3E614C2C70081
-:10D6F00079FA7D37BF4791532B78414E2499A81C66
-:10D70000A5E91FCDEC1C73C62CF294D9199D0D3DD3
-:10D7100024D08B73A619F03CE5E46974FD3CFECF80
-:10D720002C69E48BB29F0A1E11529900E79C02A754
-:10D73000FF2F5ABC7926A1072D1F7DF6F452B0EBBE
-:10D7400029EDB6AD209EB9AAFBD0147FF668DAE5C4
-:10D750003F6A057BA8521FF032D63981B6BB04ED73
-:10D76000601C58C79EB3CD22C0BBBDFBAAFF5EBFE5
-:10D77000828ED72B3EFDF8B2D9BD22FDF77F9A15D8
-:10D78000BF23D347BCD17B7FFF047C586C0E3BA6E4
-:10D79000D1FD2DC9BE660438AC4CB8323296DF33A9
-:10D7A000DE3CEA6FDC6A03397D30628A798FA0AF94
-:10D7B00085E917EFAE98E1013FFC532DF704983C43
-:10D7C000CBE37C37AF577121635AAAB83130587018
-:10D7D000B9990F5FE8FC0AB27649203FF3894A5EA7
-:10D7E000323BC504D0479ECA1109C6A9B9648D7CD5
-:10D7F0001B0FF67207BC0B52761886BF3B4D7B0F92
-:10D8000074D2A85312BC5730368B8A6301DEA7D17D
-:10D81000968FD7DD139DEC9DE5C9E3E5D7F0FF4179
-:10D820005CE7A4ACFB3C796A392155F6817D3EFE6C
-:10D830009518536F7CB4053E3E84EB1B160A9FDBA4
-:10D84000619DB3563399747378E8E1A8874BDE5F26
-:10D85000E6317BA10E1E77DFA83C9C14030EADD7EA
-:10D860005DD907E4A6023F3D1CEAA12EEA4DA620A1
-:10D87000E881F55218E1584FE118E07EAB7CF53EA7
-:10D880002BF3E1FAC378FE5D0F4F3D1CA97E81FAB0
-:10D89000C3D80176B4831D0378611C40E50726FADE
-:10D8A000FDED5E32791A785F6834C619DE45105690
-:10D8B000E40DA12C0FFD322EE65FA1F29CE1C35FC7
-:10D8C00098FDAA30C2E63FC6CDE265283C4EEBE0AB
-:10D8D000715A87079A738B7E9E6FC03F46C4C00FF4
-:10D8E0008E078B2CFC7C934EDC70FF7FD8C7439C4B
-:10D8F0008C2FC4968FA323BE967E98DEC1DEE710E0
-:10D9000088BFE5BB8BF613F2CA18FF996B76217DB1
-:10D91000E4126F12BC07014186304F655E8305DF5C
-:10D920000F2D29F07ED3D824F5FB10CAF8CABEE427
-:10D9300072F8E592C0013887E612E933F5BA95FE30
-:10D940002A2C5CCFEA4EBAA39F1C8CA143A3FD29CD
-:10D95000EB4B4A22217C3F4430E33D27FA5FC0D89D
-:10D96000213A9E123F9A689F526941BF4E196171D8
-:10D970001221DCCF1C5E9EC3DF6922E6B8EFF29075
-:10D98000AF13A2F37BD12248F86E029FDFE5A3E636
-:10D9900000C46B3C26F8B7021C1A846303015E5472
-:10D9A0001FBB05EFE9EBCAAF9D3C5C02E5B4DE3C72
-:10D9B000ACC7D7B5506476327AFEC7F7505AF371C8
-:10D9C000664FA3E426C1FC15FCCFB132FA1E4FDC32
-:10D9D0005DF1BD34E297203D6C61F7D0EE3EF90C6D
-:10D9E000EEDF1FAC771F057A2B204109DFF9716943
-:10D9F000F1B04D3CEDA33FFFF2775DA4A67480EB40
-:10DA000041CBADBD408E29FAC27B16DF6F61BD07E9
-:10DA10002D8C3F9FF60E7D17E4C2ECECC12786D01B
-:10DA2000D460F6E1BB0B0F035E517866015ED1B6A0
-:10DA300007A1EB4E88574761DFE6ACD5E19599D950
-:10DA4000D36653B605EBC8592B7FA99E570BBCB8BC
-:10DA50005C6C4B3F2487A9429F0AEF2D30FC3C6849
-:10DA60003105406FCB798AC547CC21FE172B057C49
-:10DA70000740A3AFCFB530BBF7DC9F5990CE69E329
-:10DA80004D65E0E7B2F0F71CFAB077775AC6AB54B1
-:10DA9000B5877D37A7221ECEE5FEC3B3023BB7CCC8
-:10DAA000B5E4B37BBF1BE566353EEAC78FDBAFAE9F
-:10DAB000DD4181D9490ECA6E8C0753DA5DB1303928
-:10DAC000DE6CEEBDC97093FBE0F3CC1DFA4B49D17F
-:10DAD000FC398B65462CBD40E9AFE55CDE729E30BB
-:10DAE000AE39DC357A9E3094CB47B4E709F9C8BF2C
-:10DAF000729EB03F2D1F594DDBBF6DF3A55A617C5F
-:10DB0000C9D717E0FE1CD70FA926D3576D974EB57E
-:10DB100032FD3075790E393338FA3E9B20D199E0C9
-:10DB2000FB1AFE729037D20C82FC9FF2998762C575
-:10DB30000525DA733A5B8746E9EF2983BBAA92C5CC
-:10DB40002BA0BFD7B77C36EA7353971761DA78FA00
-:10DB5000C62D4087391C9EB75A995E5A9AC0E84331
-:10DB600010FCB7427FF55ED10EFED485B522F7D703
-:10DB7000B177ADA64E1053E0FB19B38CE7C08376A6
-:10DB8000B6AF67087B9F26E7B8C95743D31B247BF2
-:10DB90009C55A5EFDD2079982769A9E8BF56EE2BA3
-:10DBA0009E21196CBE6B997FA0796D06C6311F94BA
-:10DBB000B5F6A85156A60F8FB2B2FD9DCDDFB103C9
-:10DBC0007C82F724664B6EB40FCE8E18D93B6A74F4
-:10DBD0001E886F166D3FF956163F91CFE13F1BE44B
-:10DBE000E460A8A7EF4762FD73BCD5C3FD4D4BEEC3
-:10DBF0005880D30DE21D6745BEEE96003E39430EB8
-:10DC00009F04FED6363F0F08C0CF4B6F08A1EE60D1
-:10DC10002FAB91F17CD6C0F5FBCB35875267D3741F
-:10DC2000F1AEF71D700EFC9E95E95397A57A7C77AF
-:10DC300062D16B22DE9BA6689AFA3D6C3F6718BBE7
-:10DC4000F7C1EE2D2872EE8EAF7A76F5613D76FF44
-:10DC500040D1AF72CD8120CCEF60B98876292A07F8
-:10DC600035EF90E4D7B07B097ABDEB11ABCCE3354F
-:10DC7000D93E2E73B171E2D16D4EC44A822ABACD1B
-:10DC800091DC12CC3F27E220410AF7CB17B66E9801
-:10DC900048F13C9026E3398F1E7F0EA3DEA7F8C122
-:10DCA00003344FC739CCD773A466EA34785FE52DC7
-:10DCB00052B67A00AD9317F6273322A6A7B4615166
-:10DCC000BD2BDFA5D5F7F4FA6041DDFAD5F0164B90
-:10DCD000037C80F1CD268C236EA5279AEF8EA91F99
-:10DCE00012B21EF1F08ED77E391EDE9FB8E3A2C1BC
-:10DCF00005F39B6C7533FB62CD357C1FA18484A634
-:10DD00004379498DE80AD1564748CD6D201715391A
-:10DD1000AEC02574E390D903FCDE22BA56C23ACDD8
-:10DD2000F7D820CE626463FF64906707CD32DA21B2
-:10DD3000732CBD6D7354F87C3099BD1B7024B9A74A
-:10DD4000F6BB79C36D20D7F6F0B8B5C3E7EEB7855B
-:10DD5000B1DED464D4CB1439AED357157BD7D8DE1B
-:10DD6000628BBD4BADE71271D3B3165A3EFE561906
-:10DD7000EFBDE58599DFB4951CBFE15FCDCF239A58
-:10DD8000EF055C3F6825D7A370D6E8A16F58B95E50
-:10DD9000E9260340AF0CDDD8B010EFCBD625B8563E
-:10DDA000A23D81E92D8D678B374C80EFC744661FFC
-:10DDB000B921221D1DDCBFB07B5845BF5422E0BEF7
-:10DDC0005D1F74F5CA9B745FAE7F62F504E0B354C7
-:10DDD0007D5B6CBF5890C329D499D9D9039DD93B99
-:10DDE00018ECDC7957F4DCF90EF001784706C443EF
-:10DDF000DAA65346381F5FA6AA38E2175D34E0D78B
-:10DE00005DDEB0A8BE7F738AF3DFC956EFFBC01F8B
-:10DE10000324A70B55424891D59B0D71E04D938982
-:10DE20006B2B5DCFBE0B39824CF3A3B66578049A99
-:10DE3000DF0D8A25F0CDD7C420C493EC867B6BB46C
-:10DE4000DF05F595C60C3A6EA04644BBFE026E1F78
-:10DE5000BF2007D21355F85199C0F8C905D9FF0B57
-:10DE6000E8E7C2C726B4775FF8C41A53AECE48605D
-:10DE70007CF74D2ECF3213DC980F35EC7DAB339D04
-:10DE80005728E21A04702FDE7155847793EEE4FA76
-:10DE900057E1B3F5ABC12E33715393047CC71774AC
-:10DEA000E583489DB2C323831C9AB6D327839A3D4A
-:10DEB000BDA60CE39066D4561E81FCFDA16ACCF78A
-:10DEC0004FF047002E77AD6D3A04E8D2AB9248F898
-:10DED0008ECF674CAF4AE5F3E811F11C7422366728
-:10DEE0001B00BF5BC67FA25E02D57DE26A363EEDB7
-:10DEF000CF9040D77D5759532EC8B5F4E5ACBF74C9
-:10DF000072A0DCE98EF63BFA46BDA0B617BCF898C5
-:10DF1000AD88F15B06F7F4C73B6FC173197159F116
-:10DF20005D454E4F398FDBD00F70FD07CC0F707DF4
-:10DF300010D3A7AFFFC0160CC4D0A7A378163231F8
-:10DF4000FC52F08D9859DE6B067CFBFEF36556A003
-:10DF50009B649FDBA88E3FCCD950D8EF6DE8DF6281
-:10DF600042BB5CCB78EBD97810880B78ADC8B1D9BF
-:10DF70003AFF4B940F30BAA05D04615C2525C24A7C
-:10DF80001751E749280DE6939EC0F85C95D13D13E3
-:10DF9000C6ABB29A5C30DE6C736F23F0AD16FB2615
-:10DFA0008F4F1BC9F5CB7D170E26C1BE5F1F549E38
-:10DFB0000E7A73C8F073E4536DE1DD4FACDEE10916
-:10DFC00038CF00EAF94AFD3DE7ACFD414EBE69603D
-:10DFD000714FC433AB3BAC5769378DA7BBB99F4E6C
-:10DFE000A193E47AE2DDD21F41E5DDAD82C7A4044E
-:10DFF000468F4ABA5B7607189DB1B8CEDDF690B968
-:10E0000027D0F39E9E984FF6119B07E2586A7B7BC0
-:10E01000C05F43F9C0A404955DEA4ECE1F92EB9B0E
-:10E02000902EDB7B1E18C6E11B92AA397D11E453AA
-:10E03000405F8C7F87BAF0F778D0FF077C83EF4F83
-:10E0400027210DE3C1719F95752773BEB08CD33D19
-:10E05000C001CA4B795E295FCCE1952FF677AAE320
-:10E06000C75AC9F5E56904F4C7FCE59D312DE5F310
-:10E070005D605E8FF6D205C9EBD14E9AECADC474EB
-:10E08000415E257E4FDB340BF163C1C6D8EF8C1D9A
-:10E09000E57AD9E50B06F69E94C1DA19F04F297F8F
-:10E0A000C72A737EE97F1CF0E162CD86E707BAA339
-:10E0B00076DFEB96CA89F703FE6F135DE5B03F5537
-:10E0C000F9823B065EA9E107F02AADFA1CFDA62500
-:10E0D00024CCFCA6DC2FAAF84F83558C9F5EE4FA73
-:10E0E000599155AB57562618383FAD1F7F3B1D3F02
-:10E0F000D4DC2B13FC4121292C4A6CFFD06E047C0C
-:10E10000D885F8FE74FA638047821DF51EE0ABBB2C
-:10E1100054F8B170E7968ACEF49F77DD60F77742C6
-:10E1200012B1A9F9B782270A3FD6AF6F2BC75F0597
-:10E130000F4746E5D4D6046E1FED49FB2D59DF8C01
-:10E14000F6D137147A067C037A5EABE0DB20037BE2
-:10E15000374D4BC7C3BF23FEBEE79917D2D1FE9000
-:10E1600045E916DE5903BA8E8117BF6DE103FEBD86
-:10E170000931E4C145C1FF8BA49ED1F67BCE8DEB66
-:10E18000375BD5CFCF389E5F97FDDD5D31E01585DC
-:10E190002BE90CF850447706E04036092E75DC7BFD
-:10E1A000F22666E7AFE7F055BED7EBE03D3AFABEA0
-:10E1B0005C3D8377931144765A90E905C430AE33C1
-:10E1C000C8F90556EF38B4B7AC37107C4F55C84185
-:10E1D0007C4FAE7AEEDC574320B5F440BF09711B8B
-:10E1E000008F163CE5C6F3E0CA972C8897E71258D3
-:10E1F0009CC4CA2A99E1A75C89F875F193E2EEE024
-:10E20000770950B9DE3B86DCF9AD4E9EBFCAE5A862
-:10E2100082773DD631BCAB92BCD644155E6E27DE0C
-:10E220004CE6EF6772251E3E46F1C83548C1A3593A
-:10E23000F47B8FB56111F68BEEE335A0DF9EEB9A90
-:10E24000909FC5DB47C5BFA6ECA7C2E787DBB4F745
-:10E25000FA641B5B4F729C7880A89CD3F26578FFB0
-:10E26000CF36544B0F70E552594F23874B3CBA9829
-:10E270006363EF3E57FC75C38340CF15EBAD9E95AE
-:10E2800024EAA751FCA7CA3C3ADA048D3F47EF675E
-:10E290006934FB536D2ABC023FA01BF93DF3AB2848
-:10E2A000BF8760C93616E7B4078A808F9CB506D54C
-:10E2B000F7776F958857CAA470B565E0BA6F0516F1
-:10E2C00042F3C9CB8DA4173D775D1F71E0B083D6B3
-:10E2D0009FD0142EBC9D2E718F313C6D12D87D893C
-:10E2E000B718F40CB4D103FE37B07E89AB5A33CFE4
-:10E2F000811CDECAFE54FC754E5A2C3F8002C77842
-:10E30000FB3287C3C3C9CBF5F46FE1E59FB69B7EB3
-:10E31000034EA0DFBB48A01CE22FE8011DE3D65A44
-:10E32000E8971ED8A1FF029B967E957C0CFA2DB033
-:10E33000A9E9371266F4CBE9D459257B63E92DD3DB
-:10E340006DEC9CECACCACF0679E4F461D839D00D01
-:10E35000D2FB024AEF40C701A0DB8E004F86673D2B
-:10E36000BC9518EFD8A38AE9E3D713D97A17DCE96B
-:10E370003D00EF252FA0E7018156ADE4F41E1FEE0E
-:10E3800021A7C0E49B13F8CC5DA3C2B92087DD6050
-:10E39000EFE888BFFA023765F428120CD17D77DFE9
-:10E3A000208C7F7CF2C2838F01DF586FC37B4F8A42
-:10E3B0005C4A4DF017DB86C6A76B8A975EB0572D77
-:10E3C000F9C2C6CE8D71FCE2A3971B48AF24C4F3FB
-:10E3D000A56A3C1FED6B1201AE4909FE34399190DC
-:10E3E000D5B69C31E66E747D1954EFA5F9729A5F2B
-:10E3F00007F6B70E61C2F315B64EDFDE5EB77A9D43
-:10E40000F72DB0D7BD94E05D09EB82380048EFEA04
-:10E41000D224227F6BA75FBF14EC77743DA7EFE98E
-:10E42000F7D22CFA75F67DBE0A2855ECC9C3B93D62
-:10E43000B9B46E10DA995576E50DB0FE7876E5B68A
-:10E44000C67570BAA7F88DE73F47569308FC51E1AF
-:10E450002B5B6C1D383E8709BCD7AED017F025D09A
-:10E460007795F802B03BDAD15F11447C85BC333339
-:10E47000CA6FD6551A62C63F55DB6C1A7A51F82915
-:10E48000A9FBC7EB8F29EF2C32FE5AADE6AF5595AD
-:10E49000A75399FECADE2D5BCA6D001B567AFED8C3
-:10E4A0002B397AEF7984C91880F716E981CEED52BD
-:10E4B000C54F0A7542C80E71795FD222C0A32F0DD5
-:10E4C000986EF80F5F4106D8594E1A90FF96F07B70
-:10E4D0004D59DD09BEC353CBEDA3D9676C5EF0FF88
-:10E4E000370A66E49F8DA7AC0190AB8D7603DACF37
-:10E4F0000FEF33215D5CEB65E5F68FA0C64EA2F809
-:10E5000073AE1D9B9304FCFF79EED77CFEBE5BD0FF
-:10E510006EA9D8732589C2BC0384E9B07B9939CB35
-:10E520003BA3BD55B1EFA69A67092C8888F52F99B2
-:10E53000D9BA5225BF00F6F12D6DC43F9CB1191513
-:10E540003DF82F00DFD227C24638E72A7AB022AF43
-:10E55000BB37F438007110DD0B98396D4B83C10067
-:10E56000EBDB42D12831A3355EB5E04FEB38838B2E
-:10E570001AB9B486C519B4E479BB5FF03883D167A2
-:10E580004FBF8AEFE999FD1F6BDAE5A75863BDD34A
-:10E590003D7DF963D83E1EDE4F37B0F779F4DF13C7
-:10E5A000EC9C6F4B655DF07ED4DFBE9FE08E61C753
-:10E5B00099FED7D9F87B24F476B7E8F8FFE1C9A330
-:10E5C000FB26DBB9DF2F9DA4835FAD2D3FA67EDE4A
-:10E5D00027647FB758F2491F67A78CD7BA3D3B978E
-:10E5E000B5D43312FF2E1BEB3753D5EF283BD37F27
-:10E5F000A60B04E3DFC95704E5B4822714EEDDED72
-:10E60000B47CD83B67065BD1CFD324021FB876B267
-:10E610005757F4AFC739872AF321C4DF3B561CC7CD
-:10E6200074788727C6FA46D8997C9E2E333F85702A
-:10E630005F6FB40B4CB7980475DC7E6F65BF74FEDA
-:10E64000D88396E178BF11ECF9B1E0A7F7D3F606CD
-:10E650001FEA5006174F0C7C52FC820A9C2BB2BD5D
-:10E66000D912B3A7E13DB5642FE39FC90504FD6B43
-:10E67000C3052FC263BC3D03E7B785C7C75D3BC673
-:10E68000E2598765BBF1F73C51393116E03A9A847B
-:10E690005F35A8E2AD143CA97885CA638DBD31A071
-:10E6A000394F27723EEC82F72654F5DC4F000F8875
-:10E6B000CA81AEABCD9A7CFA321791547222D19BAB
-:10E6C000A6C977F5B9AC708EEA5AE0D6B453F04ECD
-:10E6D00089F7C39F6458B70BDF3DEAC0E7335CF0AE
-:10E6E00023DE005F033BF202BE9F74BDF371BD05E4
-:10E6F000E16B6ABC51D6DBD6BA4EAF70232F3CBB60
-:10E7000082CE97F28539EB32CAD310EE2E02E78B18
-:10E71000732BCCF8FD61DE3EF1D959788F3671B597
-:10E720001BEDB889DEB2B7E09E4F62991BEF15CCA6
-:10E73000AD1404B0F7503E83ED36AF7061AAECB76C
-:10E740008B960BB6E83BE3F1E4D75A7BBBE5D75A8F
-:10E750007B0CF965307BDE06BFFFE23AD10D78B164
-:10E76000AAB003DAFD3654B3FB6E87EA58DCDD86C7
-:10E77000E94C8E28E35E79CD89F2E28AF2FB54BC43
-:10E780005FA64EC178802F5381CF6EB3F99FB7AB90
-:10E79000F8E586BAA116FEFEB246FED01F17DC7F52
-:10E7A00040DF9C007AD2A0B5524FA4FB1761BE6433
-:10E7B0005E78B0A527E0A9FF7D78A7F4DAC9CFD2AB
-:10E7C00061FF143F9FE20754C651FC8482E0DF6E74
-:10E7D00057F1A9D67E40ADFF4A7498314E374B644D
-:10E7E00071BA2A394B601F57813E48F16CD5292BED
-:10E7F000C263D5578CDEE83C5F85710EDB8721FE56
-:10E8000028F294CE73E0BB243ACF524353BAFA9D18
-:10E8100052D53CEB6E3E4F5D1C2B9F97689770BEA8
-:10E820008DC4EA8179D51A3D27FD2067AF58D19E66
-:10E83000D7E8BDC302EFCD36923B2CF00E6DB5CDBF
-:10E840007F14F643ECD6E4003DFB50DDE0BE30DF44
-:10E8500078FED8265BCE31A84FD7F7474847BBC2D2
-:10E86000D77EED8EAEEF267EDCF7A1FE3758FF5F38
-:10E87000BEC9FA4BE1F767300339EA5302E7BB7AC6
-:10E88000BC12EA0E7C01F143947E306E33904E82CE
-:10E89000AB289C2A0630FC227309FFFD395A3CD86C
-:10E8A00066F335C07C14BABB097C9A609D1B6DBEB3
-:10E8B0006648611E700F84F299CFB8BC7AD568881B
-:10E8C000EA5149498C5F3525128CAFD1FBC913ED54
-:10E8D00053FE01ED52FBF80557FF6F84E792E3A664
-:10E8E000F00B615C84720F7531F87321BEAB466E1C
-:10E8F000D0FE9E1D2D1CAA6D3E8703FC3839EC3DD1
-:10E9000039C02B78FFED26F0E8E04078F85320B5C9
-:10E91000CB145F002859B3D200CE8D666F2AF895CC
-:10E920007697333834BEC3E0B0E7AC01F1F839D2A2
-:10E930000FE92ED3D0FC20F44FF9477758D7A8A67B
-:10E940006A01CEBF1D8BDC06E0B35D9A3CA2E1E616
-:10E9500078DBD381FCDE7F8B83EDC352D887C1C7C0
-:10E96000987DE62678DBCF91F28DE03ED891D27E7D
-:10E97000FE42F16AB8438557ED8D9B12F8FD497D43
-:10E980007FF43C84FE83037B4CC88F4A76B3FBA2A2
-:10E9900025FBCFE3B9BB64AF0991326FAF85DD7B57
-:10E9A000A861E557B263C70178E1978F817CA87EA3
-:10E9B000C4A395BB0166AFF436BB7A8951BF6AD256
-:10E9C00004768F60158F4752FCAB0E8E6749DD7C55
-:10E9D0005E902B49F904EF13386C2CAEB0F57D0135
-:10E9E00046B729BC9DCBE51600DEFAFB0329F09E55
-:10E9F00034F38F23BE8806AB07E47E5281AE9EAD12
-:10EA000000FDAF29BAFB06F31DDCFF6A2469C0478D
-:10EA1000AA2DB1EF097DE650F43A2B9EEB243EAFD0
-:10EA2000C376237BE7C56EC6752F49244985989721
-:10EA3000509EEBFB69C12BAF41730F25A9C0AA798A
-:10EA40006721C5D74193EF38A3B3A67E277F0F4D2B
-:10EA50007997A27E9AF26E65999A7CF7E57768EAD3
-:10EA600067508453E77BAE1DA7A9DFBB728A267F60
-:10EA7000EBC6FB35F5FB06676BCA6FDB51AC291F94
-:10EA800050BD4493BFBDF6314D7D318E9EBD87C3D1
-:10EA90005954F46CFB103FDE3BB29B0593EA3CF704
-:10EAA0002CAF97ED284803FFF76AFB9834386F1EA8
-:10EAB0004E1CE60CC7E85749BFED396CB743D0D8B8
-:10EAC0005773B8FDECCA41CA45E0F7591CA27880DB
-:10EAD000BFBFC9BFDBC1F5A9596EA8CFDFB5903C58
-:10EAE000B88EE90E33DAC5F4FD3FEB706BEC758A36
-:10EAF0005E2F1A3CAE42213EBC3E6B27BCF67E47E1
-:10EB0000F03AA18B1752CE6FFA76571DCC7E4AF998
-:10EB1000ED07C00F5BCE69A449F4E139EDB32B01D9
-:10EB200002FC94A0DE124F0F50C61704DF5FA11F36
-:10EB30003D3FF52D9FC7CE99062FDED78A777EBB46
-:10EB4000CAD71F3DBFE5CFC0FD48346AE0F4B71611
-:10EB50003AF76ACE6FAB1387E1F96DB5EC4D6BCF29
-:10EB6000F9ED6FC0938602DCD9BEB6ECA7D1E3669F
-:10EB7000F73CB5FA4B6B7D9BCA3FBACE0DA0C709D7
-:10EB8000A0972531FD7B377B0F4019B71DFAB6E4FE
-:10EB90006C87BE6D229EB59288FB657532FD7AA9A1
-:10EBA00045FC56FA7592F31BC8BFF7640FC6FFBF4A
-:10EBB000374124F02ECBB582E1788F3A1E3E7EC0DD
-:10EBC000ED2FEF39197CDBB25FBCB7A2E8A6F72FB7
-:10EBD000DE1BCBE22CA7E8DEDF1DE164783095A7D1
-:10EBE00014406887B8FCBA1DE3E52F8FFB107F6FD8
-:10EBF000D2E59AC14302F87BC23CCB20DE2660B34B
-:10EC0000A37D6FCAD8A143CAED2A3CE2BF8F2CF77F
-:10EC10008D771C60BF99B2AB674AC0161F7FA6F202
-:10EC2000F511297C0BC653BF79117F5FCD943DBD93
-:10EC300053987D511B9FA6B7FB4C595E82F8A6E402
-:10EC4000174708C6A3B5E42576DF787144C2F8B546
-:10EC50006ECE96F8F6F49BBD9BD65E78EABF2BF09D
-:10EC60007C6FEC45766FDE125BDF58E1143476245E
-:10EC7000FDBD9578F731E6F1FEAF158CC0FBF7537B
-:10EC80008CEEDEEDB1532970AABF713E01F8C27E51
-:10EC9000B80F13A3FF879C8C9FEDF77E920466E963
-:10ECA0006C73532EE07F36B783C788D75F0A7434FE
-:10ECB0003A52F09DC4EB3FE1D4C6EB1738195FD14F
-:10ECC000C7EBB775DF68B231B67C9BC1E14EE1F7A7
-:10ECD00021D0EBD2CD32C6FBCDA7730880FD6D8B62
-:10ECE0008CF6B7F76F9808F841CE6F927F09F169FB
-:10ECF000459B7B6E7E96E68BC69AD06F337F0B7BEF
-:10ED000087848CB504C12F5BB4E5D1547857FC538C
-:10ED10004AB78BA8D2347FF373180FF3FED9A7310B
-:10ED2000FEFA22D033FD5EF4D593D301FE7B8C95A1
-:10ED3000B70DA2E9A29D82E6FE447195459357E284
-:10ED4000FE94FD2342F45E859BCA91979CDAFB53A7
-:10ED500083A3FEAE979CE8EF0A639C7CC904767F90
-:10ED6000EAD039767E3FD28BC50586C6DE5B388811
-:10ED7000AE636C0A7BBF451F4748C03906EFABF056
-:10ED800038DFB11F4B2DF75C58B9D796AFBA3FF0BB
-:10ED9000D68A32DC97B13F637693B1192CEE3D6E83
-:10EDA0007C615AAB7B007D406EB68A2B8CDEEF39DE
-:10EDB0001D0B6F0EE9E8FAD039164738EF187B3F84
-:10EDC000AB2DBEF9019FF7FB67FB3DF06B0A8FF798
-:10EDD0000B18177FFFC6DD6BF07D1A9F40209EF356
-:10EDE000FC8DD8F7C8529C8ADEE46FB96F03FB3301
-:10EDF000B560414B1EC8F21EDF239AFB38EDE737A2
-:10EE000037E7274F3AD93D4A3D7FD7E3FDFF29FE3B
-:10EE10003E65EC9174B89F4FD397F09EFE2EC61FAF
-:10EE2000F574AEE7E733747C30CAC70D9A78E319FE
-:10EE3000C00786AAF9B911F9FCFF00D1E7EDCB00B4
-:10EE4000800000001F8B080000000000000BDD7D2B
-:10EE5000797C54D5F5F87DF3DE2C496692C96412AD
-:10EE6000B2336189A088C3BE457D098B51080EB8B5
-:10EE7000A1824E02216C21816A456BBF1948C08076
-:10EE800060635D8A8A76A041D1A20D8835D6A01331
-:10EE9000A5086A357EC5AFD62A0D82088812412D95
-:10EEA0006DA5FCCE39F7DECCBCC984A5B5FFFCE26C
-:10EEB000A7BDDC77F7B39F73970914319DB9190B80
-:10EEC0000CD782B50A631BED7EB33395B1A1F66012
-:10EED0004A2163ACCEB921C13F80B1941476ABCF47
-:10EEE000CED869FCBB3C9C76D88BE2B0FEAFE2FC8E
-:10EEF00076E730A8F75666114B646CC8DB4D8A1F65
-:10EF0000EA1F53D8B4A618ED4EC5991883FA5BCD05
-:10EF1000BC7C2BD61B102ECF74169E8A837EB7D94D
-:10EF200020857A8CD99C07FAC1BC988925A98C9533
-:10EF300028FE4C1CB7D2D67E5F29942EDCFDBD0581
-:10EF40008AD843167FBA3614D69369F16ECCEB3A61
-:10EF50006E1F271F376D4911DB3F8431AB8D05E2F2
-:10EF60000633A6682C601E8CE3F8979AA0BD368DF8
-:10EF7000B155008F3D3037ACCFFAA59B581A633F8F
-:10EF8000B131FA0B14319C0C0B7C161FAC85714E01
-:10EF900031FD425CFFBF987E11CEEB13A60FC0BCC3
-:10EFA0001CB74EAC533331FF9618F028772A7C1CDF
-:10EFB000E6CBF739205FC4FC91F090A9CFA951BDF1
-:10EFC000C2876FCC6D87F2CFF7DD94CB20DDF1D017
-:10EFD00088A4F618F565FA8B9A6AEF38687A6F8D0F
-:10EFE0009FD224C6749CCF9A9A39DE717D187342E1
-:10EFF0001EE7556EF1E52747F433C499CC18AC27CA
-:10F0000071D4D6B65E40270756AB4EC503293315DB
-:10F0100063FBFDC1A4E26D03783BB7A11D9FA70A66
-:10F02000E4C57AC3BAEDDA3FDA05EC4E335C2FA3C0
-:10F030007EBB5B67B9C09385796DD8DEF2D9553652
-:10F04000D60BFA537427E6253D8C8211901EEEC133
-:10F050004FA3605CC57FAB93DAE929B2FC741E8EC6
-:10F060005F4C79393ECB763196D13DBC98A2CFC268
-:10F070007E0E31BD1CD3664BE02227ACB7399ECD46
-:10F080008945CFF3117FB09EFE4E412FCCEE3C78E8
-:10F0900091180FE6F76482BE10FB3966F355637A68
-:10F0A000595647AD8A7413E714F5DB19E21DCA6F90
-:10F0B000C77296DECEAE06785F06935D05D9970FD0
-:10F0C0007DC63C00A7C48E03CC03E32722FE62C0AA
-:10F0D0002D2199C3ED0F8C15C7E63B4E670131CF4B
-:10F0E00046E017933BCC2F4F41BB2D0390EFFC82A2
-:10F0F000EFF4AB503E34FED2A5AC82F25EBAC784C8
-:10F10000F4E16E637A10E121E02EFBFFC469A17E79
-:10F11000910F9533F0E143E7C9878DBF9C648AC3A3
-:10F1200079DEC5BC7D3D58EE596683FC138B9DDEB0
-:10F130005590EFBD1A080DEAE72C89DFA042FDA02B
-:10F14000E0A79E0FB26571503B6F5D8786F261D27A
-:10F15000DD6D9A0DEAE7D5B56B289F5EBAEBD15C01
-:10F16000A4ABC39F5FA53AB0FF6F64FF0020E0F738
-:10F17000314E8E4336B2B427E2A709E79D1AC15734
-:10F18000F1FEDF22BF5F56DD31D60AD57297300D12
-:10F19000E5E561C5FFEB94DED86FFCB4E000442FD9
-:10F1A000A7B7970E1EE95F06F9ED92DF95A24C9680
-:10F1B000CE5841A399E059D0F8D02D08EF82C62B44
-:10F1C0003405AA3CA185140DD759AD6B01C8BFEB1E
-:10F1D00034D3F8873F9FD753C1F9FED9CAFAC68006
-:10F1E000EF9BA2FF2681E7972DB1E97667A7DCE1C7
-:10F1F000FC34862952BEEE443A04F99AD81BE0B199
-:10F20000F0CEE3245F9F727A68FC27B4A69D993400
-:10F210002FE60DC0A7799BDE23792FC791F5E66F06
-:10F220005EBF02EB65DFE61CA47AB05D7B1CD2CF2B
-:10F23000F7711C5FDFDF191F5CAA10FD0FF25D1C68
-:10F24000830F59C86A4A270CD878AADB4C2301AF30
-:10F250001D1D8528F7A0CB65C89757257B681DB273
-:10F26000DDFA0E673CF2CBD9F4C14181CF73A5C35F
-:10F270003792B9DC0A74D59B47115EE7A1373B840E
-:10F28000DE3CF16FE94DA12FA5FE94E54A32C7E7B8
-:10F290003DCE6EF5A6923CACABDE74B3E0BD03612F
-:10F2A0003DECA8C9BB91751D3720E4DBD178DD9A10
-:10F2B0000C6981C27C386EE2D1CF98122187160B7F
-:10F2C000BEDE2AE9C0C56E9D12631D95A23FD3F430
-:10F2D0000E4B3BF6D3A210FD775DAF85EA815CEC67
-:10F2E00081F3BEAC27C84DA5ABDC8C818F5CAC9F95
-:10F2F000F5B6FE3A12C9E8E4C60440FF99F0D10B16
-:10F30000EBFF2A4EEF8DEB93F01F7C5ABDD537A053
-:10F310002BFC2F1470BECCA1F7C7767F137CD61DB3
-:10F320005E4625737BE6AA648E97AD0E512FCE58AC
-:10F330006F6632874B45B2912F23F0372A3986DD2D
-:10F3400023E5F0D1785F0196FFE1D0D604A42389AC
-:10F3500027297FA2F115E6B3A5341EC0793CB68FEC
-:10F36000D63FB27DB41E0AB70FD0BCD7231D21BF34
-:10F37000211D79B89E583F203C3F49E77EB1CE1F02
-:10F38000E2F52908BFE8793A8F9A9433CD33B9C3AF
-:10F39000AD20FF27EB4E4A5F3E6452705ECE0E4DAD
-:10F3A000C17939857E8CD683202E045C793F6F0825
-:10F3B000B9B1E2AB99E988E71585FEF46AA83FD9AF
-:10F3C000A1CF4238DCE3D4CB717EA50E7D36E64F6B
-:10F3D000C571FE1F95ACCFC1EFC9C28E8A9E67B5BD
-:10F3E000C01FC0B30AEB258E6301D487979FB40773
-:10F3F00041C4020860DEA01F12756711EAB1C4752E
-:10F40000CC8B749A92D0D16A857CC743CCBB01F275
-:10F41000F9018FC98AFAED367D19A62BBE52C9EEC5
-:10F420005C51C882CBA81F6E87B2BA5E41D2DFC0E2
-:10F430006F91F4BA4CC079593297736087D42473B2
-:10F440007E5A9A1C6187483EEACEAE88E0C3FAF342
-:10F45000E4C35FE078E7C1870F083E7CF05CF8F01A
-:10F46000B1301F3E8AF5CFC687CF083E7CE32C7CA7
-:10F47000B85BC0ED5D513F061F3E138B0FDD821E52
-:10F4800024BD231FA2BE0F2577CACFDFC5A2F77305
-:10F49000E0CBE6E473B00B3BFB3B47FAEFCEFE1B41
-:10F4A000E33AB3FDB7C7EEA4F5487E067E793399FB
-:10F4B000F48EFE16C205F8E56DCE2FB1F9AB53DF21
-:10F4C000747039C1584302D28F9CE7E702AF00AF96
-:10F4D0000FB01FC967D24F91F0EBA40761F71E155B
-:10F4E0006962C7670CE502C06D6F24BD3E25F82533
-:10F4F000309211BF8047558476E54B47C18E44ABAF
-:10F50000CFC5E75BB0B6ED756475A635244C757450
-:10F510000FA72217B773BA83138C7F2C963C6D41CB
-:10F52000BCD9BBDAF3D1F8FA44ACC7E952CE88AF04
-:10F53000B3CD43C20FE77109CDC3635A15A1E7CD1F
-:10F540002E45F2B7E682F4F2711D2AA3798512C026
-:10F5500085EA94A72C1BDA0FEDDADE1E6E6F77C1F9
-:10F560003C2FD7A1FD80707B189FE45DEFDB409EB0
-:10F57000919DAC9B503FADC8E3F4104DF78D683FB3
-:10F580000C88C0574326E1EB3E9B3F13FB6FD43CF6
-:10F5900026B4EB1AEB9D4A80F0581D8FF463B7EB4D
-:10F5A00044B731E490C7757E72A88F8BCBA1BEAEF5
-:10F5B000739043035C9D72E822ACEF3C8B1C1A23D2
-:10F5C000EA17B8B87CE94E0E5D26EA1509F8C69030
-:10F5D00043635C31ECB96D369DFA8DC1A79763FD2D
-:10F5E0004CA7AEBBB85E2B7445E835683716F3F709
-:10F5F00089F6AB1B4CFDC87E66F1DE587E86CF6572
-:10F6000037D829970AFF81B5FCF3F7770D67AC0A65
-:10F610008BF83C7DAED4B03FD1D8F0591AE21FFE32
-:10F620000C7195079679DFED83787B476568873E97
-:10F63000F03FED168477737CE240764978DCAA7F50
-:10F640000041A6005EFE61A254E27161CBD2210CA2
-:10F65000FC88C2FD3FE4A25D796CDF3F283ED261A9
-:10F660002FF3E3F83BB6F338C989B767A6A07D2E20
-:10F67000C75F8CF882798D5707348560BDC777598D
-:10F68000BCA86F55E6F95501CCA76A979905494E74
-:10F69000311BD637F3E932F3AE156D6A22E6B58039
-:10F6A000886F28A7C99FF12421DD9A77A90CF990CA
-:10F6B000B9797980D9969E067F3369A4897922E247
-:10F6C00021C97A3CF344C427528A5D867CAA2FD391
-:10F6D00050BFC7B45E86F20CFF8586F2AC39830D4D
-:10F6E000F99CEAD186FA3DC1DF89CCE705AE32D478
-:10F6F000EF5D3FD590EFDB7093A1FE056BCB0CE582
-:10F70000FD83F30CE515BB9FB7A05F7DD1A6C58631
-:10F71000EF1737DD6568070069EB0374328B71F80A
-:10F720005FD2BCCC507F56FBBC4948B78342AB8C00
-:10F73000ED1ACC07383C030CE1F905F35B90CE34AD
-:10F74000D6B1330BE0BE30A87843506D6E735E6F58
-:10F75000E4872FDF2CDEA50C8479ADE5ED643F73E3
-:10F7600083C6FC7C7533F14F349EAB58AF24CF5029
-:10F77000A40395059530DEE76F32B66718EF827601
-:10F78000F3C57AA2E9E20B56FD7001D247406FEB58
-:10F7900093165EB799350D0FE17741274E412772D9
-:10F7A000FD72FE72DD4EF80FCB41E15B90CE663705
-:10F7B0002BEC51A5EBFAE6B4DCBF222BC63A190BB1
-:10F7C0005AD0DF8E9EFF0E97C37D3001FE91CB7223
-:10F7D000316EC5BAF0879DE4F1F1756AD00A74AD57
-:10F7E00006FA45F18771FDD1703C5F7EF10838580B
-:10F7F000D38DFC12E7898FA6B7E121D615AE09FD9E
-:10F800008C7C24E128E1EAF066C6A42B0FFCC7E15A
-:10F81000ABB31F13BE1D08DF8BC2F03D66F39F40E4
-:10F82000397CE2A36F55A23B7FFB10D463DDE9A5D1
-:10F830006447D1DF44FD5CAC5F9500723109FAF991
-:10F84000EC877CE4B74EB9BCA4CC3B0EE4A2A2F892
-:10F85000594A6AF87B9BAE3A8602BEE637AB5ED465
-:10F86000C3C7347BBD72092DD3E34C43252DF1C6AC
-:10F87000F128F1A6B4BCFE7705E0056DFC168CBF3F
-:10F88000167B6D384FC6A6539C5301F7E67402E908
-:10F89000D9C414D2BF3AA3F8DF71E6AD85FE6A1D64
-:10F8A000BFBFE82CF110570AD90FFEB478B43F3A25
-:10F8B000DA4F3C87DD6B6D4E1C678ADF4FEB198199
-:10F8C0001304BB9A39014E11F12268978DE34E79EA
-:10F8D000FC9709680FBF74E0B84AFAE51337D9C33B
-:10F8E0004F315F7F940F5DEDEB00E93D69AF837FA2
-:10F8F000D43B85DBDB7D5322FDA34EBBFACCFD80E0
-:10F90000DDD10FED99EE52E53595F4698712EFDD03
-:10F9100010439F8E4C31EAF94BC3F1B8912911FA8B
-:10F9200073E1ED2776E23C00DE63709E0E07D8356A
-:10F93000CA39D93597633FBF4A4824BAEED8AD06D5
-:10F940002F8006C76D9E2417DA9142CF2A1AE8103D
-:10F9500057843F6B730DD0866079FF2416C34F9197
-:10F960006911D64B09E75F8B33FAA32B06F3794D68
-:10F9700011EB5C29ECA7F2146EE754611C2E251CD8
-:10F9800087AB9AC6E3CC0F45C52FCB531C547FA53C
-:10F99000BDA81CD7BF224F21BB6985A218F6915282
-:10F9A000530ACB71BDB78AFECBA16F1CF7A95E7C51
-:10F9B0005EEE28FF3D0FEB0FC394F70B9CD41FE9BD
-:10F9C000CFA2AA31E1392F45C4B1E399B4BF896F01
-:10F9D000260ABE9920E4E5957D415E1273E993C63F
-:10F9E00043F93851CED4757BAC503EF10233433AE3
-:10F9F0001B877209E5BCD3FC597BBFB09C9FD0AF7D
-:10FA00007A078A872BD2E17B843C2966BE2CA483AB
-:10FA10002B3DC6EF13F74C388CFC3A9169D40F7D1F
-:10FA2000CFE3704D7085E97D594AA7BCF79C06BEAF
-:10FA30000EC5FB1F28C1F8C39F54EF066AD53624B4
-:10FA4000D22FFB85C0DB6AE1A7E03E12FA1F2E91A0
-:10FA500046C3E717293CEEB0DBEEFB05C2F3214BB2
-:10FA6000DB4F70BE214B7B6D128EF301A37132E729
-:10FA7000E8AD981FE6F3308C13AFC863762FD2E75A
-:10FA80002013C541DC7EE7380BE4DDEB14B4849928
-:10FA9000596301C7E0B05C684EC913F3AA6D4D828B
-:10FAA000FA49EBBE61BDC87F708E73A21C9AC56215
-:10FAB000C6359F167431E5F15E1AFA614936450F75
-:10FAC000C658C7D302CF201736E13A2EB7ED1BA296
-:10FAD000907EE07E07BAB2F47F074CC18D4AD7F61C
-:10FAE00076FBD8E7900E251D5FAAB2EA2D764E5F11
-:10FAF0005322E458B3A4A7738C470F9BC362C64D2F
-:10FB0000DF17782AB7F95EC1F90EDBE3A1FD8E0A93
-:10FB100029EF679998067478A320C31BD7B5FE9D7B
-:10FB2000EC8B1F4E9F56A5DDCEA87F86FB0F150BD5
-:10FB30001C41DC8FA868C90B50BC698E42FB245560
-:10FB40002DEFF9305F3174A893E46482A21CEC4776
-:10FB5000263FE37251630725FDA90248D0FF34A177
-:10FB600067409FAC4E807555AC5BDF9A01457F01C5
-:10FB7000C301F1FF9089FB7FD1EB4A8BE7F059314C
-:10FB800005FCE04128764FACDC918D78AEBE50F19B
-:10FB900082B1B2F4F8EE5D978AB85826961FDFADB1
-:10FBA0004B3F3293A61162309FA7E23BF3BA2D9DE3
-:10FBB000E481CC0730DF88CC361AECB5078EEFAE87
-:10FBC0001B40F44B7A8969200F2E0EF3FB47AAFFE6
-:10FBD000A39FC1BAAF0365BC6430A61A9B4E784A96
-:10FBE000A7755E2BD619F807530EDAC270B9AE6549
-:10FBF00037C1FB23338C07CC632EE2A031DF954461
-:10FC0000FBC9603FD03AAFB7358C47BD7ECCD2310F
-:10FC1000D08BF184ED1FE60460FC4F7F7EC2C18073
-:10FC2000EEFEAA7538F0FBA1BBDF77E880DF4FEF6F
-:10FC3000568B917E6F117A52C22DCECDE9E166B717
-:10FC40008FB9511ED69C1AEE8F8C0B2D4925FD368F
-:10FC50003708338CB097E66F4A400BAE335FD994C8
-:10FC600062C84BBD576965D5B1E2A097BA39BEE607
-:10FC70006E5E6FC9F2E0F87E178E7F08F40BD2CD6E
-:10FC8000A16D8E20FAEF723E659B0759D09EFA6BEC
-:10FC90008B9585D03FD3DACCCCCEE5A602F4EA171B
-:10FCA00074193DCF9DAF24507FE50F71395B0A6316
-:10FCB0002D01B8FA5BE6923C8D5E47F9A79E093D9F
-:10FCC00000DEE52BC172F1F0FA7703DEFC4BEEF9B2
-:10FCD00006EDD3E87596068CF27566BD312FE57E8C
-:10FCE00085C037889B7AB4F3CB1B8CF52A5AEEA5D6
-:10FCF000FE2B502ECBEFB0FE216E61170E67235006
-:10FD00000ED7DA7B25F9CFA0678FD680419ECFD85A
-:10FD1000911A1BA5876A18A5CCED217C2C6879EF78
-:10FD2000A748370B9BB758B09FBAE078279033B3FA
-:10FD3000B600C7A33D8DFBE3D07406EE8FC33C6BCA
-:10FD4000712219B87FEE1BEF067C999D51FBE5628D
-:10FD50007DD305FC99DD45F4351DD73310BF6BDF2E
-:10FD600046AEE7F8AE21361C77B25CD70858977AD2
-:10FD7000EEEB92EB91EB93E595203763C90549DFF4
-:10FD8000CCCDF5CDACC6292B320114B5DBBFA038E4
-:10FD900000137E8826F0A3D957911FA231F033F8C3
-:10FDA0003AB91F12607B58049D45D35105C2019991
-:10FDB000D8C9DBD9847FD2493F2D6B081E12CFD022
-:10FDC000613ADFB70CA5E3BE25D0D181283A32E4F1
-:10FDD000CB1B8CF9AFCDEDB9C8DF402F0722E1FB7B
-:10FDE00075D4791999CE70F7E2EBF7E8139C505E61
-:10FDF000CE7C2B9CB4FE06E2C3435AC3CE9F21DFC8
-:10FE00003572BAFFABC0FBC76E5F2DE29D69FA4049
-:10FE1000946F45CB325437D42B5DAD38919F66D665
-:10FE20000D9A807C3898E9D4DF8C6EECCB8D02FE85
-:10FE300065D5666601E3A0CCC348AE956D53833C9F
-:10FE40004EA7DB4B00BE73041E2A576EB164403AC6
-:10FE5000A7BA82DB3D41CE2F0057B27BE6AD6EA53F
-:10FE60003802F85131F94DEAA9CA266379155B4D7C
-:10FE700078A88AB27F82921EBDCC8BF4E8FFA9C31A
-:10FE8000A6249D7DBDAC6B9C88E248C777F5257B99
-:10FE9000F8B8C7D303EBF901E76D68E76BFE11F81B
-:10FEA0001DE044FAB263694210EDFD7D27C18F4524
-:10FEB0001BD4E91F6101B8B47F9C437A5CD2A75C74
-:10FEC0004F956D35D1671533FAC9A5E09061FCB740
-:10FED00074634A10CF0340FF039BD18EDA68263B40
-:10FEE00029C016A733A033DF7233C9C3B2E664F268
-:10FEF000D3CBEAF8BE51D9E6E4A0CAE30F7B30EEDB
-:10FF000022F1B0AF6EAC2583F094E745FDCB9ACDDE
-:10FF100006FA96F889F673E7D5B7EE4CF7741F0723
-:10FF200089C0CF816EF07320123F7BA2F0C3EE4EEA
-:10FF3000E17266D11FFBE23ED9F1EA38AF1AC36F16
-:10FF4000927A886503010E0FC7138B33393E98E60A
-:10FF50004D437C9E583D8CF0158DA7E27FCD247CCF
-:10FF6000B08F1D0CE3CC337AB35BA7C2F75B15CE21
-:10FF70001F336AAF2C467DFD959033EF827CD22DE6
-:10FF80008CBD07F24907F9F43EC82DCC7F50934E43
-:10FF9000F90F6B3C94FEB9A61FA50784DD27F9066F
-:10FFA00008C08276E309C12F27A4FC62B7A5A3E9A4
-:10FFB00050FCAFF7879930741BB8EBAAF160CF5CA7
-:10FFC000AD1BF5DDB46B8DFAACDDEC9C908E76EE5E
-:10FFD0004A85F653CA7C630CF599E6B14C417FBD66
-:10FFE000DF90F077B25F3D96A9C0EF374E4A31D42B
-:10FFF000BFBE3ECB904F48F5D0FCA614F7367CBF71
-:020000021000EC
-:1000000069FA45867CE94900C210A46617E1E13629
-:100010001B13F104178FF38AF334DF568FE871074F
-:10002000CCF7DBB7CD541E8D0F89D7596B4DCC0F54
-:10003000539BB916D606FD1E68003C41BB2F3F728C
-:1000400030A4E3159B87BC3312F2FB369B295EBBC1
-:10005000AF2EE53EB48FF66D4E4DC438B07F852A85
-:10006000EC08A78545C8ABB1754BE99C4D69D0EA52
-:10007000257B6147E00999F728C8F78CF3CB1E353B
-:10008000887139C01F8F673C63A57D884360B7398D
-:10009000412F1C52581DA6A85892A0FCBBB6D420D4
-:1000A000F273F1BF543D1DE9E99938B1CFA4507FF7
-:1000B00047DEEBBB6115D197A729447C6B25FF6711
-:1000C000663B5F1F53066721FE0F25333D192651FE
-:1000D000B9F8C3BD1AE0696E7EDBC010B49B9E17F1
-:1000E0004ABD01DA1D6D34D3B91BECD709F9CADF5B
-:1000F0005AD77339A2F7407F220CCFE0405CF70C4F
-:1001000093EFF254C0DF91D9C18124CFEE4E25BECA
-:100110008A86FB018B9FE01B403E50C2F231CC67C8
-:100120007CFF10845A06CA9999666F1AEAA703AB36
-:10013000CD647782FE48C4F119DB4A747C40F34CED
-:10014000C0751FA8CF6328AFE4B865AB55F2B39074
-:10015000FEA8FEFDAA1F6C0426F554A05EF1B31E96
-:100160005DE9E6278B46F4C0F544DBB732FD1A782B
-:10017000D51F612FCCDBAEFAD03F6243DBB56B2FCE
-:100180008E5C471DDFB748E7FDDF26E4FA825E6F2D
-:10019000ECB59B50AEF74E42BFE7F01E95E8EC7011
-:1001A000AF86E1E9BDF178CC6BC3EF80FC97258188
-:1001B000831AE49FB0FA17205CE79B563FA140BB2F
-:1001C000632DFBEF1B03ED8E3C6BF6E2B0F39E99C3
-:1001D000DB93F619847DDD556EE9D23E4853D2D1CA
-:1001E0008E7092DEF6D4C120B4FE20CDF366D6B474
-:1001F0001CF1E65CC0BFEF1FE65885719A99C01EDE
-:100200009176F77E33B70BFE2795FBB552BFB7A4A7
-:1002100072F932D3C4E99ABDA2909F8AF64E9F0824
-:100220007D2CE5F29A546E4774EA65D644F26A363C
-:100230009EDB81F52DD8640D06F3A88D13F97C2E75
-:10024000470FDB8D7202C69D6779F661E4A10AD67D
-:1002500046FAF3883938BB2D0FDBAFAF73517BB350
-:1002600097E2C5429FD88081501E5508BEAB6C50A6
-:100270008221E21BAE17CB45FF0CF54C84FCEAAAA9
-:10028000578CFAA45CE8D17216156F6E30EA375FAE
-:100290000277E2E7C1B8A82FC3F302FB186036DB90
-:1002A0001FDC3999E6AD788331E651C13A422ACE56
-:1002B0007B33DF77889E57F43ACE759EB3BD53C625
-:1002C000250F8D18376ADE12DE14B08EC08384FBD2
-:1002D000EC0087E7EC1685F0F5B9B0CBE4BE8BC433
-:1002E0007B05F34DC6F384150F82BCCC0BD341A71D
-:1002F000DEDF12A4FD952F5943A21DE87EC1DA2D41
-:10030000D78FC276EBDE23FF62BA2BD4D794CC58BA
-:100310004AE0F355C53931F655A2EC831F0B3E3840
-:100320007B6DB86807F0286F54F5B881867AD45E83
-:10033000DA077302010BC661E788F8E6D9E659854A
-:10034000F5069FCB7C63DB33FFE9BCBF4F15F1B9EA
-:100350002EF650DF987E54A71D7416FDFB89399444
-:1003600083FAB7234723FDF3ADE6FDB0D08DFAB88D
-:100370002FF905DDC9D7D9420F97A35E86F4E0DADD
-:10038000E713D16FFFFCC1E7693FD7F26C7922DA3E
-:10039000C507D7CEBC2F002C7570F34CD2C3158F78
-:1003A0004A3DECB744EAF7B16B4B7FFD73A4CF4DE8
-:1003B00071B41F317B875FD8DDE0B7A01C5CAB3028
-:1003C000D20B0F72B95781FA6A00E9AB0BB0DE4F5E
-:1003D00067FB2F403A8FF84E7AECA733FD23A83DF8
-:1003E0007386D0EF02C919427D25F5A9D4B39AC905
-:1003F000DF270DE1A5BEFDC19DB0FEAFB6AAE4DECC
-:1004000055AAEB739DB8CFD18DDCFEF7E16DEA8480
-:1004100077DE39C0BB0CE14DF60F87F767F51CCED0
-:10042000FB5773B8AFD8DC3B11FDDBCFEA7B93DD24
-:10043000F3D9E6BE04EF59AB00DE64F77A8C764F51
-:100440003DC01BED7C84378C5BB6C323E0EDE5F04B
-:10045000AE177A67354F6775816BE01694273FFDBD
-:100460008DD58BFAFC505C2815FD91435B5486E7D3
-:100470002C3AED2261BF48387FC71A9E403BAA8BB9
-:100480003D73BF95617C76EE0B8E2083FC11A5B089
-:100490000722E068C31B89385E78FC4E3B665ADA57
-:1004A000B0083BE61CF1B390F9E81EC2C296373E95
-:1004B000423B5ED1B95FBFD0660F21DF82BF73348C
-:1004C000529E2B1E94691827F1DA6C4807D9CCE3A9
-:1004D00023BB46EE77F919EE777DDFF79B5B1613AA
-:1004E0003F77E447C6C9ABE243668C2F756C510871
-:1004F000DF95B715261632DC4FABA679DC9EC6F524
-:10050000B1A2EB1437B402DDC4C3784BD23C24CF84
-:10051000158F93C711D7C1B88EF07CA3BF4F46D2B9
-:10052000437D6E8F1D77DE98C6ED804AD5447EC729
-:10053000020BF73FE47996E5621ECBD3B81F726FCA
-:100540001A3FCF770CCF8340BFC72EB58AF3D9E3CC
-:10055000289ED9193F9170736A5F77CA2BE42BAD3F
-:10056000231BE1B477F47B66946B7BB12D19D380A8
-:1005700080E168C7F0F6EF98EDF56857DE3CF20DC4
-:100580008A83EE8DF379D0DEDA9B6AF3221D05B6FD
-:100590005B89FEEE89E7F16FE64ED2909F6E12F214
-:1005A00076468155C720EFCD05F7F830857102B842
-:1005B00009B1A2F0F5E54847B7A6EFBFDD064B5AF3
-:1005C0006AE2F6CA5217A373409780B98E71583CFD
-:1005D00022733AE54C74638C5B2FC0F8EC68C60953
-:1005E0006A24C1D39007B852FEE587AF9BF8603606
-:1005F00063FFCB3C17239E17204C900E4A93C8FFF5
-:10060000BF1AE3C42E4C35A2AFA91A0B98785A8FA3
-:10061000213519379E2CD679DD48164A82F5857624
-:1006200033435CFD8690297401C0ED6A2DD48AF0B5
-:1006300033D93C66F4037CC5CA60F48F172C3BB7F2
-:10064000F9BEF3B07FE283059037F1C38B1D772AA3
-:10065000C10D00A79B81B9912E6FD1D80E7530C7FF
-:100660001BD25D95CB13A07A8B14B13FC4E3F91272
-:100670002F83A0FB48F8DE2CE607FDD427627B4BD6
-:10068000ECB8D1C769D2FFE576E67CC1A7F3259D1A
-:100690006D36F2E73F249FA03D0B70BB59A4DDD11E
-:1006A000F9DF44FF7F1374FEF9798E576965215A8B
-:1006B000F7762BE1518E7BB548BF4BE3F6B29C87B2
-:1006C000A45F26E24F2690184847071A6AC95E9A27
-:1006D0001315FF6591712A3556BE53EE984E636A25
-:1006E000E99885F3512E8B237EB9D9D2D4B7DADEBF
-:1006F000B51ED8D184A24ABB8DECBF85AC9DC7B3D3
-:1007000084DD2FEDC5B968E761BCB291DBB59AB065
-:10071000C74BC13F43A22BAD8FB077E17F939BB70F
-:100720008CC7783E18267EDAB7B0DBE8DCC6E40575
-:10073000463BC92CEC2273945DC4A2CF85083B29AB
-:10074000FA5C882AF817EA727F459C0BD184FDDB9E
-:100750004947696681CF80611F7E3A6B33F3FB6244
-:10076000227E27F4F378D5DE0FE5CD7425DE8BF6F7
-:10077000FEB14247C09484F125338D371DF800E562
-:10078000C82771FC7CC58CA49F4E463B787AA24555
-:10079000C3F45367AFA41B18CA1B55EC1B0527E213
-:1007A0003E532DCA4D9EBF57CFA62898C86F7C0BCD
-:1007B000F767AEFD01E64BF92727EAE0BF1DFBA373
-:1007C000280F401EE975B9E4DBDFF2FC43B2FC7789
-:1007D0003CBF52966FA3F18EAD91FD8BFCFD51E5B0
-:1007E0004BA3CA1FE1F9F13DB64D0C207CC4BED32A
-:1007F000F4D10AED3BCD41BE02F84D5F16227A9A44
-:100800006E7A8DA7452C84FB8E67ABB7A8876F0ED9
-:10081000EA67D571C081F6C99D19FA1CB4AFAE4D17
-:10082000F5FB7AA05F3845095870FF714F305FE8DB
-:10083000AF98E7E7E7083E5D98EEA3F6D2DE857E47
-:100840006EFC77FA39D5A34B3F653D52CFBF9FDD94
-:10085000E97C7D11FDCCFF77FA1998619C8FB4FF7C
-:10086000DEC8D457E0FAD801B7E15CE4FCFFF1261A
-:10087000A1FDC8F05C24807EFEB2A6DC21D0FFFC86
-:10088000E75ECA9D1D115F5878D2C474B013AB4E99
-:10089000324ABF6CFDB3C503F359B8ADD53201EA96
-:1008A00055413A36625E0BE4B960D6AE4D8DB05F0D
-:1008B000EEED6112FC743FBFC7F5DC61DA3F9E6F5D
-:1008C0006A3AF828F2E3681E678C5EDF4F7AF0FD23
-:1008D000BEBD783E20867F727F0F6E8F6CCFD61B99
-:1008E000709D8B5146423AB636F6F98A8F457FD3D2
-:1008F000E3B93C9F39DC61F35C82FBD9FE5ABCAFA3
-:10090000377B5DDE608C57DF915AF4688F33C67F8A
-:100910003B78FCB785C77FA7BBDA6E0365C53EF899
-:10092000D5FBF7DAC05F9DF82BD6B91F8C71D56265
-:10093000ABE4BB2313C715503C8FF2CD3D0EDC1B3F
-:1009400080F6BBE2F9F99119232E8E4779D09E9754
-:100950006072829C08B84B3FC079CC1871E904FCE6
-:100960005E6875E497F2FD03A28B80DBD784EBC64B
-:10097000FA18BFF15B783CCFFFA64AF13CFFC004F8
-:100980007FACF307CF09387CD083DB67BB00CD6831
-:1009900057C979C8F1C120BBAD0DFA3BB02C63102B
-:1009A000DE8BFCD85DB887E022C6FFD8ED6F8D1CCA
-:1009B0001F963B10BF9FEB3C5E1174B147E0CD57D3
-:1009C000A0323D42DE4F1D9760C85F3B2985E9910B
-:1009D00071E56BB30CF969D37B1BEADF34EB22437F
-:1009E0007989B56D68F579D8F9550E473C9E6FF851
-:1009F000B4E5BBFFBB19EDD746D5ABC07AE66EDFD9
-:100A0000F87F63A0D6713C364CF6A887E27B47F0AE
-:100A1000BC21F29EA66B91FB525FB1363AA719B189
-:100A2000EF61D85F9AEFDC41E7447FAC7DA9133DCD
-:100A3000C4BEC7603C628E7AE8835C3C5FB2D0CEB5
-:100A4000D7F3D54BFB2C74BF03F507D0F715D8505F
-:100A5000453E0F50BC7D6CF33EBA47F7500F2E97C2
-:100A600017662FD2C002655590A2DC9F00F22909BB
-:100A7000E8A3AD955DBC0DCF57E739E83C4CE5C91F
-:100A8000A98CA5201D05062C827AF3EB8B29BFF0DB
-:100A9000643CF5FBAEDA3681CED1BFA8D0BE484962
-:100AA000D68C65682760FD9FC07825BFBBA218E182
-:100AB000B3701B3F3753A2FEEF50EC67414331B593
-:100AC0002F51D92E05ECA18963B97E2D415B06F229
-:100AD000EA70C72AD4ABAA2594FF18CA138B83E403
-:100AE00049D2C99B68FCAA93366A9F95CEED3473B0
-:100AF0003B9FD7F8933EFA2EF19E97DECB70EFD353
-:100B00009CDAA895D9B13EA3FA579DBC9052B9CEB4
-:100B100037FBFDC68D72CC9CFAED043C27FCA65B2E
-:100B200071927915256F4F548F486231E4914CAD25
-:100B300042CEDE7C929F43EF95A98F4887794EBEC7
-:100B4000BB5DC37D2A66B739115E93470EF2CC8E2A
-:100B5000E023F5B51BD1336056778719F5F9CD90B1
-:100B600046CAE35BBB91C797A69B0CF776A47E6150
-:100B7000C11BC9FEBE45DE53167C72A1A82FDBB790
-:100B800091ED04787CC14A76D4984CBF2F1DCADB06
-:100B90000AD9B4AD241FDB72717FE8C79A3FE0D950
-:100BA000A6903FD34EF730268FF498D03EBC2EDD72
-:100BB00064B0D3CEB68E2251FF5D952D417DF2EE0D
-:100BC000E597B7E9D05FEBCF860C41B92FC79D9D64
-:100BD000CEEF9D3367C70FE8B756BD92E041BE2EFA
-:100BE000C1BDD6A161BB1DBE338C7356BD62DD8015
-:100BF000E799AA12C16F87F1C7BE1A17423A6E7DF4
-:100C0000354E43FDF075B67F36E273ECAB178CC3FF
-:100C100073747A8B556364DFE81508B7EEE67B36AC
-:100C2000F9144D67922FFDF59C5F4A059D9609FECC
-:100C3000F30B3E3A51DD83F8F0C4DD30695847D9F3
-:100C4000DDCAC5DBD01EF038E81C96E4CB12F4F305
-:100C5000E07BC945C9E4EF46F01DF1E182934EEA1D
-:100C6000AFF2A447F0B98BF292DFCA04BF48FAF69C
-:100C7000093BE26799FE87111E25B5C0EF787F73A7
-:100C800059C650E4A330BD589C4857402FE9B323C0
-:100C9000E8A1B615E8C541F44272C8076924BD5CF5
-:100CA0002DEF1531E7843498F7E4BA3CC3BDA2C7F1
-:100CB000CE93EEEB05BD94D9437DD15E3557C77910
-:100CC000F19EE47137DF875ABC92C36FB1D93716F2
-:100CD000ED87C58F285EC00CD915288F867F546D8F
-:100CE000898CABDE787220F3C0FAAF39D987D23B5A
-:100CF00052FD4F231C4A4F5E2FE035F0DFDAEF1C28
-:100D0000A6F3389A3968F5AEC7FDC438BF8AF83DF6
-:100D100094C39C0F44C4D130EE87F13FB90F2AE34E
-:100D20006A56DC378ED093DF690DB9E8E77489AF76
-:100D3000151AF70B17B4FEEF7013941FC9D329CE01
-:100D400036C3E47F1DE979DED4E07366C8CF5FF374
-:100D50007C22C6F5253C9BB4505FD4934D00478C54
-:100D6000F735AD568B83DC9E49E0FB7C9CAE251DA0
-:100D700047D3F7BC93BD889E4E545B49EF9C007AE5
-:100D800065117A275ADF483AAED498F05B93E8DCD5
-:100D90008894FF617DB3FEBED148774735A2FFB08E
-:100DA000BE99EA2BE4F44FE7CEA3E9FFC59A743A63
-:100DB0004F24F548B4BE8996EB525F7D92E1FF1E49
-:100DC000E154F4DB7F3EFF317CBA4AE37AEB2ACD73
-:100DD00041F4F3DF92FBFF3C4FFA3F2CEA83FD4ADC
-:100DE0007621CAF5C8FEC66416256640794A06D73C
-:100DF000ABFF6D799F92717EF29E65F0F99F4DDE9B
-:100E0000E76770791F2DDFF1A222CAF763DBFBD3FE
-:100E10003EFC5E06FA00F55E4B8267A390FFA41FBE
-:100E2000E293826792FFDBB367E667C496FF1764BD
-:100E3000FC07F2FF7CF944D26F77FC32F15E6E9FC3
-:100E400031B4CF9448FB8CC365D7855C0F44D86917
-:100E50003C9E027CD55789E49B0DF78D46BE39E652
-:100E6000F6E25940C927926F24BFDC2CF8E356A163
-:100E700017247FBC9AE1BF11E125F963C1D668FD53
-:100E80007066FABAD95DCD503FDC0A69247D593BC2
-:100E9000F583912F6EE9A4AB73E38B4919E766479D
-:100EA0002CCAE0F7DCFF8B74B508E927065D2DFE40
-:100EB0004FE8AAABFDFAE150BCAF766228D0515E94
-:100EC000988E26BEC5B8DDD09BDBFF9D7462C9A19C
-:100ED000B8CEC4D3FC1CAFA45389DF68B9F85CA6B4
-:100EE000EF61C4B7F41BFE5BF2EFB1F3C4F3CA7356
-:100EF000C4F36681E71FD15E7C31165E99D36588A5
-:100F000047007F5F43765C48A32341DDE1D5BC9673
-:100F1000F397CC2F0F6952EFA6A0DE057A69FE4F3A
-:100F2000E8A5642C13F18D4393304E39F11722CF8D
-:100F30008E4E423EBC7EA42C3FBC5AEF837286C9C3
-:100F4000FD038A8FBCAB8A7CE0C8DBE3605E131FC5
-:100F500060E1FD05281F5F90D4194F41D743D6FFAC
-:100F6000F0912FDE5E4DFCCCCFF9307FBBC6F7D5BC
-:100F7000447E28E41D11F99151F975BC7EA2D6CEAC
-:100F8000F8B9CC20D7032A6E3572FAF145D82580FE
-:100F9000C909787E62F236C589F1909B0A8ED1FE2E
-:100FA0007378FDC727E905B82FA888FCF76FE37AA7
-:100FB0006FDAC6F3A71EF9C7EA8026FA4BA37819A1
-:100FC000FD599B145DC5F320239560AFBCAE703E08
-:100FD00015A5F7F04F33B66778CEEA7CDA239EA9E1
-:100FE0007D2F6A1FB29EC7F83714C4BE27E2C8140B
-:100FF000F5445C81FA07585ED314FB1E4CAAA8DFA7
-:1010000086FB4504AFA43508BF368B8467E21AA47B
-:10101000A7F18CE77B3E9A581218C0A7AF47ADFFE7
-:101020004CF35732BBAEDF636C1F3A13FCAC5DDA96
-:101030000BFA9963A4A724CDB7E304CC23C9AD3838
-:10104000D13E5EE88B5B8D7E40983E324A703D6DAE
-:101050009D71FD68FACF2C41FA5FC864FDEC35E460
-:10106000E7983AEB737E90F405EDFBF1F7F7A8FDF6
-:10107000A847B3D6207C003F544E79ED0CFCD01429
-:10108000952F88E21F41FFC4BF28E7013E7D63C85A
-:101090009969023E5F8973E46D45DC5E6C13F7E28B
-:1010A0009664F238AD3F93DB637324DE23EECDB05C
-:1010B000083C3371AF2662DD04A71BDD72DD052518
-:1010C00093605D6D2E5EBE3873E49A4076381FDD06
-:1010D000DF6D990525B83F11EE7FF49F506FDC2836
-:1010E000E0B62473CC9F025C1E2AC89795442080EA
-:1010F000F76D4A80CE61215DC458B7DE95AE0251CE
-:10110000ED75F319DA4FE8DA5E8F6ACFCCEEF3694A
-:101110002FF036290AAFC551781D17959F2EF34140
-:1011200083FC9372B1ACF9FEE5696E8C4F2A74A70B
-:10113000374CCF57113DCF774AFA9DF827A4D730C7
-:101140003D4F22384F6D92F2B0640DCAC329280F6B
-:101150004787F3D7A0BCA0FCE4123D29525F5CBDD9
-:1011600046073CDF502FEBFBA8FE4D75B2BF29545C
-:101170002EF1C802534B70FC1B870A7D11B8E64F55
-:10118000583EAF85B7FFEDA3D7FE29D0E70CFCD0C2
-:101190001005977551F94054FD07CFA25FEAA2DA16
-:1011A000DF1D55BE3A2ABF362A5F6F6C5F3A4B216E
-:1011B0003E2C057A40449C8D2F5FCEECF47F3AF5AF
-:1011C000A96227BBCDC057136B79FE8F8F9696D43B
-:1011D0000F88C867CE2C89E40BB9BF0AB23680FAF3
-:1011E000CADC8DBC7CBE3BBAEC17AD6F79F95FF100
-:1011F0009F19B4CF63B00B5E578DF95655CE7BD196
-:101200009F6E1B10B91F5A5D8271966EF75DD8C232
-:101210009271917649A092E844AE53D69F70EAB499
-:101220008AE3FD25B3B2A411F7758AC47EA48BA707
-:10123000A0D754D49B55222E3301CF0363BDF85061
-:10124000DFC59176086BCAC775B6FE8CDF9308D4EC
-:10125000027E30CEC6BC168CABB426252D7912EAA0
-:10126000BFFE337509EAD1BD4B52E81CD66559DC87
-:101270008E7C3DA9675A39E45B136EB5E0FDF3D669
-:101280007BC653FA9AAAAFE8005EFBFBA37797D818
-:10129000FB637912C1E7BBCC25254B81CE4FE225FC
-:1012A0002568EF7739D3F01E075B6566FC3D24EFB8
-:1012B0001344376BAC83D08F2E5D7A11ED5F953D73
-:1012C000346502DDD3586EA67D0DF8A3FB3AFE55BA
-:1012D000E3E99CD7AC3A9106AEA0F4D57FFDA636E3
-:1012E00011CF2D3CAED0FD904BBF6D7A0BDF5DAAC8
-:1012F000A8EFED45D4BC02763D9EBFFA6CED0574B7
-:101300002F647F5C359D7385FA0CEB57FCE07967A1
-:10131000F250ACAF3AF148C941F88EF6F0C195EA07
-:101320000605E795E888C7733C074F79DE41BB1691
-:10133000CA9DCBE0FBC1E573D3D0CE3AA878121595
-:10134000BCC7F0D8AA92F40C7C3FC12AF0B9CA51AC
-:101350000A7C5D6AEAA417D21FB393793E356B55B8
-:10136000C94698FFC1472EA0736EBFCCD2D3B2003E
-:101370004EB766EB3DB286E13CB99E7AF55F7CDF05
-:10138000F0E5A36569484F79599C8E5F39599656A7
-:101390001661EFCCFE4A23BCBF6AF1DC86F37C35D4
-:1013A0003E47A1F3E8AC2905E3DEB3849F09F4BB13
-:1013B000E4F91876CF0F992AF57BC0BA84ED8779C6
-:1013C000B7DE7BDD5807C0A5F54585F0308BF96B9E
-:1013D00031CF9A63EF8BFE90563410E71FA6FF754E
-:1013E0002467C9DF80FCC8AC47D604D00610E73BB1
-:1013F00019BE3E85FCBA392E1807F09CE5D6276049
-:101400007D96DE943FD511C1A7A2FEA7017E7EF98D
-:1014100053A88FFEDEA781BF3822F72F64FD8A44D0
-:1014200047008D8F2F1C0E0DF1B657AB3988E71E84
-:10143000673F6E263D31FBF1D4BB3B701D405F7DA5
-:1014400059D775D46599895FBADF2F7DDAC8B7ECB3
-:10145000E933F2EDD4C7369534DABBE7DB0AE1D7DE
-:101460004C78DC4CE7F82B863934DCB72C7AFC8FCF
-:101470001BE9DEF1A2B8C1787FA3E2712BE1B7DDF1
-:10148000E10838715F35D1A125632AE8616916E763
-:10149000B3B12AD36C8329A57B1B723FF0F092076E
-:1014A0001EC663A64758F0FA1100BFE3882880CB18
-:1014B00071796F2D6A7FB072F7F396427686FDC11F
-:1014C000B3EC0BE20D78E4DB73DD1FBC232B7A7FDA
-:1014D000D09C8FFB8F15627F70EC3A1ED7A958C243
-:1014E000DF65199BC2E3C4076A02F81832AE37E021
-:1014F000C47BD60F727D54C194A00DFE79C5BA4548
-:10150000F45EED1121874AF15DB501C85FDE5CF440
-:10151000EB673F1E4770AD7862EEFF3D02EDDA9754
-:1015200096B823FDE835821EA07F86F798653F5F59
-:101530002CFD792ECABFB1BF067F18EF4326B3E753
-:101540006ECC433C65E4E23EA6AC57B1EC67F9BC17
-:101550001EF8D3E03797AE54797CEA052BE9479023
-:1015600009E92CE23EFAACBADD16CB80F0FDB8CF2B
-:10157000208F4F2C44DC93B320BCE4BD2DFC4B1FCB
-:101580002EEC730FC91B7A6F7ABA49A1FB5D20E973
-:10159000E85ED4CB593C1EDA94C5EDDED25C2FDD7B
-:1015A0000FAABCCFEA5DC6CF2BB1CE7BF1781ECCA3
-:1015B000D4369BF62D7F6FA5384A555D9C1E97C883
-:1015C000CF536C1D40E7C6350BEEB778B85C795940
-:1015D000D05F9567CA15482F50FE9186E7D51C5CF1
-:1015E0007E56268BF700A1BD09C63986FFEACDFBE2
-:1015F000CD181831BE22BE433F9EC470BFBB4CAC59
-:101600001EE33458BFFF408463CAF5D3707ECFAA6F
-:10161000C4C7B0F8FB46A23DF8AC3A04FDE0D29551
-:10162000AF4F588BF92D83F046072B7DEE7DD22FDF
-:10163000F305FEDBC5B9B932C8E33B057B041FF9EE
-:10164000551E1FDA23E025E9409657AEE4E7A72AA6
-:10165000975BC9DEA95CFA21F55BE9684B43395D0C
-:10166000F98299EE797F28E65DB634A7E023A0AB36
-:10167000327312BD2BBE205062C1FC820685F2E19E
-:1016800076A9B948A75FD6BD9888F4B33F2ED41782
-:10169000F556C7A2382F9E5794F1B92FEBFA6EC0BA
-:1016A00038CE2C679B03EF6BCDBAADB70BE5FC5E74
-:1016B00067C882E57B9BF24C98D79DCE02CCEBDAD3
-:1016C0002594FF529C57A13FA41785E379C1E6D723
-:1016D0002DBD60BC1FC47ABF7AF6FD7CD46B95B972
-:1016E0006DF9A87F800EF2B310CECF28A4B7176E85
-:1016F000E6E7F8251D2C443A00BE9B27E860E1B6DA
-:1017000017EF407E5888F81FDC958E804E77D0F713
-:10171000ADEB2730DE7E07D289D47790AF33BB3074
-:101720005E27F2300EE64F213C8751F9385E1E18D5
-:10173000C0CF03B6D3F9C62A719FB3533E7583E772
-:10174000CC6CB17FB6D44AF236339BAFBB7DE50B90
-:101750008988C7AF9E7D7D27C6892BB78256F7C47F
-:10176000E00B01972A844322AD83EC902A5C7762D8
-:10177000180E9DF42FF8B18AF175CA755769020EDB
-:10178000B25CB4CFCAE6EB5CC004DCB65DC0F94F16
-:10179000F01BF233BDBB24D6E77719DF97D7C5FA24
-:1017A000FA8B7401D005DE5F63787D53CA0928FA8D
-:1017B0006ACB7A8A13497CC9794FCDF6483DA22776
-:1017C000BBC2786C37C57E5F7B54369727FB96F794
-:1017D000C86D06B87D09FE189D37007AD522C693DC
-:1017E0007423C71BFBDB2957E17AA1FF10F62FC733
-:1017F000DD1B48D0B09FBD8CF307D227CA4FC997D5
-:10180000636B675C3508CF4307BE72F4467B5BE0D1
-:101810006F6A367F0750473B01DAEBCD0AC5A9F75F
-:1018200009FF7FDFF21713CB22E0E413F3967486EF
-:101830007F18BF92F3DDE5E271DFE8794B3924E7E9
-:101840003DF69E1BAEC2EF72FE925E257D4A384A7F
-:101850003A95F703A3E995684DEA4FD520EF493F44
-:101860005E91FD8DC56FEFFA3D3ADF6937D5A5EF83
-:1018700088BCF7B65F9C77EF48653CDECF806A2373
-:10188000F48ED4F3117A65B516A157AADC3ABDB728
-:101890003367E8A27CD4632F64F37329475893A578
-:1018A00010FA5B70A86D42A2276CAF5EFA6D48C556
-:1018B000F76E166CE3E7D724DC171CDD41F45F29D3
-:1018C000EE6F95AE7CBF6404D2F9D366DAE72C5D87
-:1018D0003E9EEE69CFDD387338D211DEFB40B97E13
-:1018E000B871D810FE5C9B33ED7ABCFFD1F8C0F51F
-:1018F00037C1F759CDAA97E43BF4837C5B7AFB10A0
-:10190000A6D07ADB4B70FFB4E34ED58976FE988D76
-:10191000C3EEC6FA631C3D93713D7A630AE5752DEB
-:1019200089F483B48FE5B9BE5A33A78B5F67737FA1
-:10193000F5E1CE5411E7F96AF371FFBD637D1CBD7B
-:101940007335DD22EEBB6EEF417E489505AF5ED26A
-:10195000FD59B2C7E658982D839F0FB765C0F7DDD4
-:10196000E6B6DB518FECBEDD3188EE1FA83F0C2FB1
-:10197000E3FE23CDA324C5F8AE949CC71382DEA357
-:10198000FB93ED7789F3D9FBC5FC0FD73D7D3DEA8D
-:10199000C1C39BFABA70DD5F6C8FA3F771BE887A02
-:1019A000AFF37CEFB301FD46DD175B46F36BCAB6C0
-:1019B000F3FB5CC28E93F47ED6FB5C9FB8A3F6115A
-:1019C000CE7C3EE9680DA37BE7B7812D8EEDC72560
-:1019D0009C7A1ECF05CE6EB03AF1DECF01A477DC43
-:1019E000BF7A41E5F7936D9CFE0F6C1914447F7329
-:1019F000F627FC1ED68EFBEFA17309E5605FE2D1EE
-:101A0000CD4E7BF9C1FBAF473638EEF5AFC88076D7
-:101A1000C737F173145DDE77D8FDFCCEC8F71DCE55
-:101A2000D74E3E57FB58C6233EC936BE1F20E12A7B
-:101A3000FDA45701FF230787E1F475CD1CB28F8FFA
-:101A4000D6F8293DA6ECBB6F0CD2AD2389EE37BC8E
-:101A5000DCFC808AEFD1546E1BF403FAC5A3ED4978
-:101A60004EE4D7AF6B96D0FEE8D19A6AFEEE4AE715
-:101A7000BBCA414A2FDDD64AEDBE6E1ED282F78127
-:101A80005FB12709B91FBD1FC4F1D8DD3D67B9AEED
-:101A90002377727CCA791FD9343311D7D5FA584AC3
-:101AA000CB28C463429213EDBC0A714EE4E05A6E37
-:101AB000471FB2253D3909E07368DD3569F85E508E
-:101AC00079EBB5D7E3F7D9DB1527DAFFDEED531253
-:101AD000D13FFB5C6B4FC4FB5F9FAF95F7C682F4B1
-:101AE0007EEFE86246FB55A3431AF3E4D1D633D127
-:101AF000C9A8A31ADDCFFD12F7B1305EF2433CC591
-:101B00004B98D89F2A7F89C7593AFD59E1CF8D114B
-:101B1000EB1E91E392FB0EF47DEC48FEFD8B75CF3E
-:101B20004FC6FE0E379A9D38EFAF1BF93B16F3C038
-:101B30000FC3AB008736713F675E93427EF1E14D84
-:101B4000A0A7615D958BCC3ADD6B8DA2BFB1508EA5
-:101B5000E72225FDCDD38344D7D1EF8C24B326BA19
-:101B6000FFF663D1E3C539467FAD930EBBC3BF809B
-:101B700013F22DD2A1C4F3BCB5FC7D5B57D3A042B8
-:101B8000A42789F7E87B0EB51646F71902A6787ADE
-:101B9000177A8ADD635660FDD7B8DBC7A1F87C24CD
-:101BA00087CB4575AC49C7FB7AAC96BF63D0253E61
-:101BB0009DC3E5E89B398CD2B21C7EDE58DE5B9378
-:101BC000292C2487DE654C707DE7812AD7E46C9A46
-:101BD000ACC1FCA78C71DDDEDBCBD8CD39CF4DD6C7
-:101BE000806EA70C71BDD00BF2331EDFCCF397B81B
-:101BF000869921BF54F9DDE47190BF2B479F9293E2
-:101C00001A1E47F60BDFAFC5EF8752FC37E40C43D3
-:101C100039CEDF2D3BA6740C5C9217AEFF9EC2F648
-:101C2000BEAC84F3ED6646EFE594E1FC53BB4F3761
-:101C3000E4E8FE9C6131CA19A3FB6365017E1F08BD
-:101C4000FE7CB6343AA746F45426EF07D51BEF07BF
-:101C5000312FBF9F26EF6DC97B59FDC3F7CDD69DB0
-:101C6000CF7DB363E27E5CF4BD3FA585DF97AB0D0E
-:101C7000B0F638C243D47D9F04FE7EE3E217BEDA9D
-:101C800081643557DA2BA86C8787DF3960E9FCBCA3
-:101C9000C0ED820EBFA8617DFA002B5FDDD696E80D
-:101CA00081C91E9D1CCA47FEF658FDF508A72FD610
-:101CB000D5662F76E3FD58AB7712D43F14E4F74F87
-:101CC0001708BB9335A60A3E57439743BD5D79FD80
-:101CD000E99D8B5F0A7A3A9A17CAC577870279DC41
-:101CE000CF817A74FEAD78D915A958EFE8967BFAC2
-:101CF0009403DEACF8AE9F8B5286F7C5AE84BE4728
-:101D0000BAE8BD3FA6D2FE6E90FAC37A89A8D73D45
-:101D100033D379FC9DDF2F947892F0EF82179802ED
-:101D2000DAA5261B33E3FCFBB3754ED4C7123FF292
-:101D30007DDBC52FF038CA62A5BD2E05F3CF2A740E
-:101D40007EEE0B1BBF0FD455CF6DB420A8E7AC9B24
-:101D50006978C748BE23FB63C7835ECA11F7C20711
-:101D6000B14191EFF45688B6E3D5E91E7C677471F2
-:101D7000AA8DDE3759FC786FD2272C703BD181AC0D
-:101D8000C7D6A5107DACC85309CE739B19BD4F545F
-:101D9000D29C49E71D2735BB284D3C994EDF0F3FAC
-:101DA000F9D6502E7F381E4A9EEA41EF8A973C753D
-:101DB00041117F74AFCB3B49FC3D6DBB8DEE1B2FBA
-:101DC000DECDF5D2E2EB548A5332710FCC27A6E375
-:101DD000B3D7535CC7C762BF0FEC93EF03EBE63397
-:101DE000BE0F2CE16B15F8897E2FF8BADD43D2D1F6
-:101DF0005F95EF05CBF708DBC47DAFE87783EF494C
-:101E00009C40EF064FD3B91E897E37580BC479D159
-:101E1000BE3567DBF9BB16FEE87784DB355CF7F58A
-:101E200005FC1DE1EBA619EFD3990BBE21396D2EF0
-:101E3000E8F28E9219E9DBEA33D6FFBBD42FFD59C5
-:101E4000FF33BED39C6DA1F7F0347CC71CF2D78B57
-:101E5000779AD18E43FBFCB8CEDFDFB3C6F375B7FC
-:101E6000B1A1E9C8F7FFBFBF4F7EB677C9A3DF2195
-:101E70008F7E7F7CC8AE5F1AF2C3DA1E35D41FF1A5
-:101E8000D10643F9A8F6670CE5630E6D35E42FED36
-:101E9000F883A1FEE5275F33E40BD95B86FA636D17
-:101EA000EF1BF2E39D7F31D4BF227DBFA1FC4ACF5F
-:101EB0009786F289FD4E18D7A3F927E4223F7BFFCE
-:101EC00069683799797E81EF7BDFE036D1BB26C523
-:101ED000B946BA1B97C3E30AAC0FCB45F9355E9DF3
-:101EE00044EF241D6F52F8FBD2DDE8B124B0F7B403
-:101EF000887192751B3882E17C4AB1D3904FF5A569
-:101F00001BEAF798E6319467F8FB19CAB3E6780D37
-:101F1000F99CEA9186FA3D97E8867C5EA0D850BF8E
-:101F200077BDCF90EFDB30CD50FF82B57E4379FF98
-:101F3000E01C43F9459BAA0DF98B9B9618EA5FD2EA
-:101F40001C30940F0AD51BCA87EC6A30E487B5AD04
-:101F500035D41FF151D0503EAA7D93A17CCCA1264F
-:101F600043FED28E6643FDCB4F860CF942B6DB5062
-:101F70007FACED3D437EBCF3CF86FA57A4EF33949C
-:101F80005FE9396C285FF0A597EE4BB397F97ED8DF
-:101F9000C47EDF18CACD6E46EF6057B2782FEE3B95
-:101FA0004ABBA6C4FB7743BF4FE6F2380AD0527B48
-:101FB0001CBE1F19F051FCC7850702514EE13D754B
-:101FC000173F4F339DE2486ED26FA48A3C78BE071C
-:101FD000EC8044F4AEF2F2D04E4E08DB63D9A72376
-:101FE000CED79DCD1EDB96CB681EFB73FD4FE7A6BB
-:101FF000A2FFB16502BDFBCE022B701EF23DC07781
-:10200000A2DEBB96E995B6432CF25DECDD710DD9ED
-:1020100083CFE0BF5F693BCAF0BDEDCE7E45BC42D9
-:1020200081F52D8EE8FF3EF017B43E8C35D400FFCD
-:10203000808DF4CB1A27E51FAC49A7FCC3351E4A97
-:10204000D7D6F4A3F4D11A2F95AFAB1949F9276A63
-:1020500074CA076B8A29DD50E3A3EF8D35D328FFBF
-:1020600024F8C5986E023F19D367C0DFC5F2CDE0F2
-:10207000FF62FEB99A00A54D35F5F47D6B4D03E581
-:10208000B7D5ACA5FCEF6B829436D76CA2F40F35B4
-:102090004D54DE52D34CF9576A42940FD5ECA2FC52
-:1020A0006B356D94DF51F311E577D6B453BAABE6D7
-:1020B00010A56FD67450F9DB3527297F54C45DF71E
-:1020C000E51AF723645EBE5B21EDBFC968BF2371CB
-:1020D0008C347F6DB0DFA3ECE8687C1C11E3E03B3F
-:1020E000BD43816ECD99F91B6A23FCA7AFC478F27A
-:1020F000BD8AE8772798B04FE5FBB0F23D8BD962F7
-:102100005E1582FE87217DF623FA7CFB7CFC05E9C7
-:102110000F5E9BEA3F45F499630A903F6CE7F791A5
-:10212000EF48F5B39EC370DFB07C278DE7F4D2FE95
-:10213000618935947AC3507A079EE272DD8D572506
-:10214000CE89775BFECAE16CB4A78BFFA5D27B6416
-:10215000EF981DF4BB97293D395C527A9A0CE93F00
-:1021600053FDAE9E907EEFA8BEC504F3FFFEB245C0
-:102170004FFE242FEC275F8DAE26F8375398C74CBF
-:10218000E71199FEC73CB49BC0B0C2FC0D2C40695E
-:10219000C0EDCFC275DD080637E6FDA3ADB9B1D6F7
-:1021A000153DAF7C31AF7C311F99F64FF3F7C5FE7B
-:1021B000BE77E834AF77465D918FEB92F39A27DED6
-:1021C0009D98CC3A9EC0F97DBFFD9B834AEF30FCC1
-:1021D000A53F4EEF02A0BFB34811EFFF75797F8096
-:1021E000CAA7DFAE907D3603FC19DC2792EF0D1CE9
-:1021F000AF36937CC4F709701FED78F5E776246756
-:10220000A8C7709FA3160FF64079EDCF15A2AFE9CE
-:10221000F88E08B49F9196C7EF4B339B8E7A787AED
-:102220008B753DD2E974B0F7D07F02FA2844B8CF5D
-:102230001BA5D27DF5774CC17C85F693CB2D0ACCBE
-:10224000ABC2ED35FC8E4434FE178AFB07F23BD05F
-:10225000D54484D7D72F8DE847F1F7574679104EEC
-:10226000B5267EEF28F0A62A7EDF8B8B6675CCC55F
-:10227000145F649AD78B71A212714FA555654B629A
-:10228000BD1F5F29F0F44E3A7F5FB0366A9FA5BC50
-:1022900027F72FCB7BF2B873C96BBBE99DA585BB34
-:1022A000F87B906C68FB80C877793AD7B3E4CDFEB1
-:1022B0007D22D651D5BC8F9FAF60ED0322CF9FAF5B
-:1022C00010E34BFA512D0EFF7A7BE4FC3AE97901D9
-:1022D000D17332D0736FA2E783B8AF38D9EA49BA65
-:1022E00041C15FC7635FE3FB47FE5F3BE93C913C55
-:1022F00057348BF928AD00F423FDFA02F7D37BB7EE
-:10230000F358137D5F387226FD3E6D15EB18970E5E
-:1023100070BBAE7EE91FF1B9C06B1AEE1F8F71D58D
-:10232000A9C1D23F623AA5513988FE29F0C3CF1125
-:102330001FED4AF5723CC279D3E6C2E5B83538598B
-:10234000E5F8606F717C00BDE8AAABEB3A81FE97BF
-:1023500013FD27EBB40E35B1D840FFD397315D7133
-:1023600087CFC777F2C3C8F97FC52D60A675D0BEE9
-:1023700079D52B5617E2791EE3FA3A6CFF493DCD29
-:10238000F5FF7CD0FF58EF88A0E723398CEE211CA5
-:102390005118DD6F97F623CBF5A70FEE1DD6B74783
-:1023A0004CC1E189BD491FAFC3F9EE4CBF86DE0FBA
-:1023B0009AEFB6D1FBB0479283B951EFA1D07B4DD4
-:1023C000327E759F99C793A2E7A58CDCC97FE7C4CD
-:1023D000C202B82F81BFF33D1CF938D3427C568B23
-:1023E000A0C5385891CF13ABFF3AD1EFAE53DCCF35
-:1023F0000DE4F0774BBA8CE314E3C4F371A4DEE888
-:10240000FC5DF13466186F7BCF3CCE070E9DE6BFB6
-:10241000D4944C7226C3E66FC1F5CB788EF4FF7668
-:10242000E57DD187FCF41F6AE93D267ABF00CFF530
-:102430005CC6E5D13B660FBD4BFC4E611EC5EDA5EC
-:102440009CBD7A248F7B5D2DE35C055171AEA8386D
-:102450000B2B881DF762CC6BC671FBB34F247C2815
-:10246000BEF25A8166F83DB1D784DF79BCD83D947D
-:102470007E2FCAC3CF5925A6F0F7463A1C2AD1D9D8
-:10248000EB01AF1D7F9F6495888FAE8E7A177CD548
-:10249000D0C54E3C176075F0F73ED714C5CF893CC8
-:1024A000BFEECEE7EFC33C995F98E18174803D5861
-:1024B000446A59D73C387F45ACE72227C0DB84F615
-:1024C000A64FC439E5EFDC8C23BD2CF17CAE7AF944
-:1024D000192DB82C1ED7EB66C4778EB536929F6A3D
-:1024E000931EC2A3D4B3F2A71E47B9C1345F3F1CE9
-:1024F000A775783CB343FDEF5B2D147F7AC554F686
-:102500006B7C97B8E3CF5686E71C9A1C591A1AB70A
-:102510004DA72E1C47A963CC04FE3E274BC0774431
-:102520000739D96F7E874812F7C92CE9CFF80E809A
-:10253000DC6E52D82EFE0E979E80EFE13599D88939
-:10254000CB617EFF0FA64C086300800000000000F6
-:102550001F8B080000000000000BED7D0B7854D5A8
-:10256000B5F03E33674E66269370327930E40167EA
-:1025700092C98B4CE290F054AA93106840D0E15578
-:1025800083243A58F446854C8AB445AF5F339000B3
-:1025900001F42FA2B548BD7640A568B50D4A6D6C13
-:1025A00023770242B197EA606D8BBDB57FF0F6F7F5
-:1025B0006AAD12C47AB1A5E5AEB5F63E9939930974
-:1025C000A2BD7FFFEFBFDF8D1FEEECB3F7D98FB554
-:1025D000D77BAD7DF28CA3F6FECB18639359C0CCAC
-:1025E0004A18D34A838A96CBD854D641F57B954076
-:1025F000DBEE1C289D565F18FAD58E33F919D4D915
-:10260000C78E48A9C458E0986C313B18EBF3041D01
-:10261000F8DE05FCB90A9EBB4C16C5CBD84685B57D
-:10262000F54299E1B3336665F47301FE05CE953149
-:1026300056C7D858CDC4D814C6BA5DFE985F8ABFB5
-:102640009F5C32551E1AD4DF2FC6FF17AA6FA58BC9
-:10265000BA9931AF23D22061C52F6BEA54C6E8770F
-:102660008DB12A95052D30451A0B30DC0F9BEEB34A
-:1026700006AAB1B1517DAB02FBF9A50BE9179997F9
-:10268000C90CFBE9F3FC6102A3F51EB267D6B031B9
-:102690008C851BB4FB1A2743F953B3AF8B7AA993EC
-:1026A00071FCCC6C1635C1F3A10C73648F9BB1C364
-:1026B00061EDA95EA81F96AB088EF774C266000490
-:1026C0005B3BA1A2C4E7DB3A798DAA013CD332CCB3
-:1026D0005F3A8C702E32A9A5B08FCDF3ED4D1180ED
-:1026E000E3BD0DF6362C73CA2C8C01BC97165B68C3
-:1026F0003D7BCBEABF5D0CF5564760B6A47138B0A0
-:10270000BC381CE001E3FB0D32DC6F8BCA06A5442C
-:10271000B830804B06DF00BE770DDF32BB4666E186
-:10272000314EC65E9EF1F663BD304EC64E587736CA
-:10273000BCDF71460EC23AD8F90B57D901DE01BD94
-:10274000FF4C89BD9978CEF0EFCD0AB13F37C15328
-:102750007D4B6F375F3ADC2D4BD6573058EFA64E86
-:1027600017C1AB47F2F9C7C27872C7A93BF0F94667
-:10277000193A02BCC25E25F238CE23072A703FFA0E
-:10278000782BCB1A6ED0004E19D3FE907E0BF4FB43
-:1027900028CFA42170366A377DDF8EE777329DE13E
-:1027A0007B99D9B1B647A17DE8F572B60786F9E8FD
-:1027B000D6E00415CE630B9CD39B1E5C4D64AC69C4
-:1027C0003A9683634D2E02AE8B9741177FCE447BA2
-:1027D00084EA6FB98BE99C00FEA2FF20F5DFA26CB2
-:1027E000B7DA711EB755DD9380F7579959472FCC4B
-:1027F000F775A40B7CEF7C97B63003EB12D5EFEFA7
-:10280000DC19F89D07D713A1327B7E840501DFEC2C
-:1028100015612D0CFDAC1B5810DF4F86E7DB6E9960
-:10282000DEB71E7A8869D02FDBE39382D02F673E14
-:102830008CA7C399D1B987C7D442BF3D80309311CB
-:102840003EF64838055D5E93DB704CCE1CFDFC9275
-:10285000F180093CD0CFD3FA577310F902632E13DD
-:10286000E2DB5A2BC7D3C6622BA379D729BBD3602F
-:10287000DE27B42C5AF787390D639877F4F91E8157
-:10288000F309033D4580AEB0DCD3A9B230E0C963A3
-:10289000802F58DFDBA951B9AFB382CA273B7DD463
-:1028A000FE54E774AA7FAFD34FF5DECE26AA3FD3FE
-:1028B00019A0FA81CE66AA3FD719A4B2AFB38DCAC8
-:1028C0001F7576507B7FE73AAA5F9506E786FBA9DE
-:1028D00008BB16C179F4DCA9F83580CFA038C7C38E
-:1028E000FEE26C1F9CB7ADC2043407E5F11D0CF786
-:1028F000637399FC1138874DAE1DEC8B505AA66658
-:10290000F448C057363EEDE8918031DBE4FB19F224
-:102910008347A4701BF331F693483020CF60CCE39B
-:10292000FA528313EA3F8BDCB2DD0A785BA62D6C8A
-:102930005E9F50D7326A6FDBAFC6EB13BCBB653B03
-:10294000B4BFAADDBA3D47E2EB60F98CFD26727B8D
-:10295000603DE051B4988511EE436E2582F8B812BF
-:10296000CF4BC6F5ABB4FEAB5997CB04EB9FA02978
-:10297000B54837D03FCA722EBDFFA0A6D1F3E4F709
-:102980002ED6CF34F992FA31F345C6C376E922E365
-:1029900058A5C5D618AC7D9B45F08F5C07F18F1EFE
-:1029A0000BBB310070EFB1F1F2CA6289F8ACB3B879
-:1029B00061B71BE6DDEDE672ABC716561B70FE6A0B
-:1029C000930FF9055BE7FE7931CCF7959FCA6CABA5
-:1029D00016C7CFFF1078503A2183CBCF7FB4464A39
-:1029E000619ECF4F78BADB09F5D2477D3E33F4DFE5
-:1029F000C67C76C493F03D26F638D4BF3BB9C4B943
-:102A000010BA574DF98113F9ED5237E70311C69A01
-:102A100010DFD66FBC65C220941F9DE07C4A71F325
-:102A200079765B621D749E531C6C0F0981EDE9C8B9
-:102A300077D6BBE090A631661AC74BC5A25E8FFD64
-:102A40001410D461588FF29769D6008CD7752EADCB
-:102A500009F90863B174E4638A2DA866C1F3ED61D6
-:102A600013F1852ECD119160DC6D8EDA631AF24F71
-:102A7000D5E42B45387A4D04C76EC7172266E4CFDC
-:102A8000D2FA36942F11F519AB1B9E47BC2615E9D7
-:102A90003CE25FD484F57050F6956A8241607BD049
-:102AA00019D98AE3B2A17FB90CDB5B980FE1B03191
-:102AB000EF4F87D2A1DEB554F599796F4D06B93342
-:102AC0000E7F8329BB2C831BD2711DCB787FF8CD61
-:102AD000B710E5701A3FBFAF0FCC558B49EECB61F5
-:102AE000A14748178010658BCFEA83F61A476D938C
-:102AF0001F4A39A3D6AAC13EBBD55AEB0ADA3F73A7
-:102B0000803284228FF853976A22398CED5F447AA1
-:102B1000EF662F7AF28894A8BDDBB16300E121DF74
-:102B2000CC985BC3F5C17C3ADF0378584B661ED363
-:102B3000601F3DB738691FB2E4A33ABB59A675E7D9
-:102B40006BF628AB013EAF2C38C6807FE45B6F9FED
-:102B50008FF5716DF2EF0613F8F4D8A0B19EDB6C1F
-:102B6000AC6733A85BE3F32E7273FC4D865B323C9B
-:102B7000C6A9DD2770FDE382323D4C5EFF43EA03C8
-:102B800059F50CD7E9A075E6396EAA070801CA0500
-:102B9000D623FEFDADEBAC511759DD307F4D8E894C
-:102BA000D496CBD8D0061C779BC0F71E373FCF38C2
-:102BB0005D9975BADC8A7439619D898513E48E3B11
-:102BC0006C67E184F94A7A9C867AE9F67C43FFF2E5
-:102BD0009DC586F6CAC844437BD5BE5A43BDBAF7E5
-:102BE0007243FFCBFA1A0CF549D17986FE75C716E8
-:102BF00019EA5362D71BFA4F3B7993A17DC6E06D6A
-:102C000086F62BDE5E63A87F6EE82E437F5DDF4E87
-:102C1000968FDD822F7C5A3D3BCD05989D305FB26B
-:102C20001E9FAC875BFFDAA56D407CCE54089F6584
-:102C300094E7505F73A7124943FCBFD2A7217FB925
-:102C40004BE0A3B7DC7F1F9E5B7DA695E482ECE0A2
-:102C5000FD64C71CD253C6EF04BE54875A231B6EB3
-:102C60004F47FEDC190E783CF175DBD4ED0CE9B76B
-:102C70003EB3890D3AE2EFCBAA9F0533703E8DE655
-:102C8000B3AA61EA67D3E0FD847D1D34999803F906
-:102C9000F88042FA7A6F46818CF4D7FB97898D547D
-:102CA000665C3107F17D92CA1EFD3EF4EF95D83186
-:102CB000067A52AF899D059D8D3D936447E9F6D311
-:102CC0007813B363B95B1ABC83A19DD271A2612C46
-:102CD000233BEB59DCF7BDA043E0BEEEADE17AD675
-:102CE000C6BC791AEA653DEEDE63C5B89E5C902BE2
-:102CF000480872C0877A85BEDF37C479CAC53D836C
-:102D000028FFD6645935D49764EBF6C0EF005E8F88
-:102D100058069FE8827AB7A4AE42BB237CA7C3F7CC
-:102D20003843FD91C34DCB30D56D80717BD7FBE52A
-:102D30002C68EFDDC27CDD481F39F51BB2E07969F4
-:102D4000E10A9313E9C1B37E0396AFA01E0BF0AB6B
-:102D5000F4EE3665437BD5E4FA6686B25785F9B260
-:102D600047C72773E64E86FB611EF92DC42BD4BAE4
-:102D70002FC0D2EB9D70DE30AF0DCF5BA292E06032
-:102D80003BE788D8B0EEE170B1F9A5483AD4733C7E
-:102D90007EC9EFC5F776D2F9DAA2463D16ECCF37F9
-:102DA000DC53509F359EAB6C7D80D6B7CDC4E9A275
-:102DB000274B3B8EF2B9C7ED717669F175EA7CE578
-:102DC0006D618FEACF75BE723DDA1453E2FA0DE001
-:102DD000F94E5309EA67DB19F227DBDDDB19E2B5AF
-:102DE0004D0D6B0CF5F0AF8509CF75FDF60E413337
-:102DF0008DC5CD5694D767736A499FB5ADDB4BE758
-:102E0000950C37DBA089F92F02D7CCB25D24DF8186
-:102E1000016B68871FCA73B4ED4EA1F76FD0389D60
-:102E20006D01328E79098FACC8AF2DC2CE004C3007
-:102E3000A17C3BAB326E27F6BAA97E4716AFEBE317
-:102E4000DC915B3BF662FAB70DECC260C23EB6C0E5
-:102E50003C08978DE71736215C994CC4C1B6FDC577
-:102E6000BB7B2BC252D8351B04BCBFAE71F88E574A
-:102E700018D905BE9CF94D24FF5C4FD2F905CE153B
-:102E800093109E56EC24F883116DEEA0F55B74F957
-:102E900064BA7019AD595360FD05F8A4184B2EDFC4
-:102EA000A0CBC00509F97F823CE305C9F702FE3BD0
-:102EB000C803637BF94E63BD3292F47E98BD86F2FF
-:102EC0007F25E3F0AADA676CFF16CA71E01B2B8539
-:102ED0001C67DB2D24EFACB0A20B5CFEC6E521F035
-:102EE000876B7A63F5E9304ED1748B414E1624F628
-:102EF00003F8D5DE6A0AA0DDA0FB5F74B807DA4CE0
-:102F00001685E84123380D3F17FE9664FE3D3E8D41
-:102F10009FCB212523B2C1CDFD12C1326E6707813F
-:102F200024EF957DBF6A417BEC98D907983D7C9E44
-:102F3000C9E7BF6F583F0ECC2F267B77B00EED6FE1
-:102F40009C2F98309FEE37292C0F2E2A86FE1F3497
-:102F5000E54CC6734A2B6416A463DD2FA2DBF9BBD4
-:102F6000115760BC6DBE573B0EC33A369F4C239F32
-:102F7000C66CF3F1639D505F532413DF53A7ADFA82
-:102F800036DAD30DFF0AEDF0CE664D1B4BFAFC315D
-:102F90000BD9F50D02DF1B849DA6FB4F6E2BE6FAC5
-:102FA000F42DA28437ECDC4E8FDA51EFADDA073C1A
-:102FB000DB882FE9BCDD4F7A71756F72BB9F21BD35
-:102FC0004F14F80075473DD427897A2F93B25538AE
-:102FD000E7CB9A070FA1C9E17DE9881DF5B0FD3661
-:102FE0008E1F4F0ABD2F8F49BE28AC3F6F9FC3175E
-:102FF000817E1966B63F06FBF0BD28BF399800CF29
-:103000009A7E63DDCB12EA6E5C87B17E8FD621217A
-:103010005CEE690154842D6F28CEC879AB8A21CC2F
-:10302000CB10FF669B1D93D0EE5A53EF6008D7B4C8
-:1030300053E5DF8C219F396166283FD474EDBE468D
-:10304000785FFD976CDF7A2D7EFE4F76228B67ECE2
-:10305000C10B3ED6ED89FBA99E82F34479F33DB0C6
-:10306000C7B1BD17CE15EBCF803D8EE501B0C7F1DE
-:10307000F973608F63BD0FEC712C7F04F6383EEF5F
-:10308000077B1CEB7BCBEA1F4CF66F25FAF9E2FEBF
-:10309000AD4149F76FA5015C1BD04E9C92E0E70A59
-:1030A000723FD7278FE3D7C721FFE1887186FD885C
-:1030B0005615FD27C5F0C61878FEDE9DBFDE8B7263
-:1030C000658114DC87F8BD7ACA9B0AD7B38714ECF4
-:1030D000FFB00DF01FF854E128FEC32B679DBA2303
-:1030E00017ECF41F15B72E443BFFCADB4FD58D8775
-:1030F0003A2B39C6EBDF39F56C01F0EA5B4AB6F0E2
-:10310000FAFDA7CE1642FB18F6ECC2C619E47724E6
-:1031100039F6B0C49A13F5C09F08FA0CADDB41FC38
-:1031200014E400433874E505488E9ECE19CA5C014C
-:10313000FD43B94379375D84CF87D63D48F2AA2B4A
-:10314000F3F7A4A7740DCB151FC9157D5E5DAE7C8A
-:1031500020704F972B6B6CBC3ADC2F5842CFEF1787
-:10316000FE1F1629A57AB68DD7FF5783F60ADA47D0
-:10317000001FB2870F674EFCFA4CB43F9B645F1A86
-:10318000D4EF77D4DA502E9D15F40BE386D1DE0F01
-:10319000CFB6461EC743CDD1881E9DFAF8391E54BE
-:1031A000CE9853ACE3C5CBED51F40774355AF7A074
-:1031B000DEB9C3514CE3754D57C2E887D1EB1B2EE6
-:1031C000BFDC8A7A4756A6D38D759D3FE9FE5BF832
-:1031D00031E3B80D62BB0D5647D49C89E861F943D1
-:1031E000A23EED6031C21F9F090C17A0B7AF9570CA
-:1031F000BCAA63BE667CAE481D6144C68771EDB84B
-:103200008F0CE1CF44093535611FFE02BE2F7D1FB3
-:10321000194A58EC83F4A91D0E5314F5C21DB02FA2
-:103220001CEFDF8B35824FF2BE18BA6861DC59D3D0
-:10323000C5BAD59907701DB34DFE6E7CEFC8C72D7A
-:1032400039887E7358878CCF4BC0F245FF2DA07410
-:10325000F7858BE827C9FEDB2BFF4DA2FDB0DB1500
-:103260003A17A58CEF7B97127133328423E31665EE
-:103270008C8EBF2525FC7CE3F8EB67484F5D4E3F05
-:10328000C75F7528733DE26FD650DE06DA5734E526
-:103290007924E371F2F9D4206D73396046F87ED257
-:1032A00079EAE7A8E341B2FCFA5A89AA9FAF8BF604
-:1032B000E9AFE074A0EB5B0CECA18C91F0DB04E3D4
-:1032C0006965F1BAE20A901E6DC9F155A09FB7EB8E
-:1032D000AFE6B6547EDE1B049CD667DA49BFEECA61
-:1032E000E4FAF540E63C835DD408769204F861CEBA
-:1032F00066BD4847E631D7939FCC3C1635285C57CE
-:1033000092DE3A663ED75B55D05B53CCAB9732EA40
-:10331000AD29F4D961BDD5398FEBAD990AE9AD0F6F
-:103320006728CDBB53F09BA9255C2F1CC07DA4B0A2
-:103330000BC11E247FA56E0F2A6A90EC3A7D9F5325
-:10334000055DE9FDD3D40E86FE33B3E2D3502F35AD
-:10335000DBB99E9906DBAC4890DFFAFC934A785CB7
-:1033600025AB9CEBFB262BD74FAE7C45EA4805F7F7
-:103370005089EE5F498D777F03DE105FA875287E48
-:10338000D40F6A1DAE06D40F467B0F4CD2F0DBCEB5
-:10339000385FF1FD75AA99E48FEC73219EF55A060A
-:1033A0009F7D05EDBD230E9237BD1985349EAE5F1E
-:1033B000835D1BAE8041F6FF1928D134D29E053BB8
-:1033C0006B4B09C6BFD6E44DE6E3829E573D52AF34
-:1033D0004CF61B0CD37BE65E377F2F320EDF93D685
-:1033E0004C1F8B78954CEF7A59E4FA69D14A5857BB
-:1033F000D1B86354EACFFF8999C90F97DC3F327C7B
-:103400000E5C2E57C26463CC248F23B8EEF7D6BE71
-:103410009AE783A5B4CB67482E7FD0317DCC668DEB
-:10342000F3DB7D2867BE2413BF2DBC7520CB9970BC
-:10343000CEBB3AFB8A640FC61762458D1EF2F7F9C0
-:1034400053ADF7B83E7F7402F1678BC0032D27366A
-:10345000B71CE0AE394C3E542540F81AF840BD9CEC
-:10346000D5A8C2FC459DCCE780BA9BA9E4F72ABA4F
-:1034700060267C2B3ABC8CF07842CE9014F626CC99
-:1034800083AC38217EF2614723D167D1D8617B8F2D
-:10349000E20C1FE64417227D7FF8005F51D1A3C6DE
-:1034A0007690B1E497BE65AD3D8226E384BB5513AB
-:1034B000D68BBE2DB14237AEE3B07B33FA757E9822
-:1034C0004E7E1DF34E0FF965BE2D050F105C23DAFD
-:1034D000574C2562B3D06FF557ED7BB6921C8BCD60
-:1034E0002539F665137B3C85DFE9E725DC8FF19A0A
-:1034F000C0F722D7CB452BEBB03C4EE77DA9F4C4F7
-:1035000004DFDE3C663BC5C5C20DAC02EDC31E0B3D
-:10351000E0550A7AF57B387F19E6C7027E36B45645
-:10352000602CB324F4BC7D4F3EF9641ECA6D46F690
-:103530006472BC36BDA2971AD37D7E86FE0949F51A
-:10354000733EAB865D618C03FDC59C12AFC77804EA
-:103550009F766F7261FF468FCF857430E09EEABA26
-:1035600009E0E770282C2D810FEB78F262C654D267
-:1035700043F471D664145FD42E57801F6B1791D318
-:103580000AFAC7519F3934C3AAC17A37396A63A886
-:103590006F6D72E4D4929FDD017C23C1EFE4701C57
-:1035A000253C74F8B83FCE81FC17FD4E62FF03EE58
-:1035B000A3B47FBDDFBB820F397C511EA7046B060D
-:1035C000FBD9E44018ED0C5B0E23BBD266E5F49406
-:1035D0000EC7614DE023FABCBF2BE1F6DAA6C2DAD2
-:1035E000583DAD4F46CF01DBE4AA75913C4438A36A
-:1035F0003E3A6E581F25FF4AB180B33E4ED700DFDA
-:1036000067609DCBDF988D7668C0E5C1711D375925
-:10361000C3281732265F743CAF4732F887E2E3AD28
-:103620009B25C62BC6F1CC19B52A8E67413E910267
-:10363000FF6688757D56FF19405425BB8D71FD0AC4
-:1036400030DE954A8FD04BABF0838D7C8FF349B73A
-:10365000B05F804FCEF6A0DD52F8E6D17AEAC5ED34
-:1036600016E75CB94286F3FA004ED02CC5EDF8643B
-:103670007DA6DE3C44724D9747BA7CDA85FA8C12FF
-:10368000A7A77CCEB958415B80E4B6941320BC0157
-:10369000FD4643BA31637C3805DCB608F84B99D354
-:1036A00035A497C6F38305F8DEC18CB70B5882BFEB
-:1036B0004DE7872F7EBCD786ED1FB6355C546FD1A2
-:1036C000E3C7A3C58D33EFFAFD9712F596D1E2C893
-:1036D0009F143F3E94A9909FEE11C9C897BA043F2A
-:1036E000FA9AC00B6771F02B88478F48011FE98D4C
-:1036F000C29FE22D0FDE89E733BE47616138CF8379
-:103700001F4F75217E5C2A7C753F7BBED0A7F21DC2
-:103710007B25A4D3FCB688847EF282B65EC97F91F5
-:103720007E8B3C9C9EF5FE1631FE55F29019E5D538
-:1037300055828E0BCEC9AC22410F5CE0E1FA944574
-:10374000E8EF99879EB0E178874C819E32940F997B
-:1037500026EDF1047AB7DC5A6B6D48840FC67F52B0
-:103760009CDF773DC37A17D947BABCB5E8722247C8
-:1037700036C889503AC75B5DDF095DCEED21490A45
-:103780003E86F03E7DF9EFAF4196755AEA55304ED0
-:10379000FE49F18F61BDC61459A1DB31482F3E5956
-:1037A000FDF120BC3FE93BF5440F535890CA698CAA
-:1037B000EB7DA0473DE321FD0E969C70BE0C5D0F96
-:1037C000799FBC8F473C5CDEDD2BC7C8CF7AEF7991
-:1037D00089F878327CFEE8D1FD5AC371BE8BFA4974
-:1037E00035F493BA316E65F463D61D33D6A7C48C15
-:1037F000F5692793FDA2FE5F24FA451F06BA427EB3
-:10380000A0FB410BC3917A15D65BC47A296E58D0C0
-:10381000E634C0F54AB3C8A7607E29D13F5B202FAC
-:103820007807DFFFFDF0B98749CFBA45B4FF43E31E
-:10383000CAAF74A3ED3CEC67D5085EFF3077D16C5E
-:103840003CD7647F6B514742FC918DF4B3DEF2B0FC
-:10385000C5D01EF04F223B60F112A37F96D691CBCC
-:10386000F75B503B72FE4F9E17FE3947CEAF8FBBC2
-:103870000BF80DF251761ECE752AC28DA1C78115A7
-:10388000C95109E3D7F91DCC8FFA70C15AE64F151B
-:1038900007282CE578900C6716BE8AE0374B3CCBA6
-:1038A0007798C94ECF5F6B223D301FF801F2816BD4
-:1038B0005601B940BD6095467AE4B56D26867280A2
-:1038C0009DEF34BC0FCB257FA77EEEBB703CD4238D
-:1038D00057B38809F7D33191E889D6556CF08BBF7F
-:1038E000C9E16525785D3BDD62F06B16A11F3301F0
-:1038F0002E3A1E14243D7FC1A31AE802E45961291F
-:10390000E13F9773A528E76049EFCD38B917F3D9A0
-:10391000AEDCC068BF4359F608CF93188E27982FA6
-:1039200094037FB2CEAA40BFCA36D56EC27C8683CE
-:103930005983DF62598CD594B270E34CC6FED93EF0
-:10394000542541FDF2D24777F4C0A11CB40D7D1778
-:103950009DBD0EC7938B9A3E17AF67661EA43A9B18
-:10396000CE3419E063C719609F7675DE3E33CC6FA5
-:10397000F73AC8096967C3744AFBE9BE5CBB07F341
-:1039800041BA4B4DA427B1C476D8C7774A553DBF3D
-:103990008CF2DD58138FEF278E2FE75C64FC7930B3
-:1039A000FEE44F31BE95AF3F0F1F817CC9C3F5A325
-:1039B0009F1AC7C7F3456751E2FC623C998577635C
-:1039C000FC05E673487C3E15F34DF29831BF6078F4
-:1039D0003E15E6ABFE3BECA779E479582E761ED770
-:1039E0007FBAF3E836F969BDE11A07D93F0C9A4D61
-:1039F00053D1CEE0F3D964F6A25CCBE1DA3D350ECB
-:103A000057D0F7685CE8BEFE8280B305E1AC2A04BB
-:103A1000E7D1E07648E5F94E5B547B64BDFBFFC11E
-:103A200079B9F87925CE877AE325CF773DCC97739E
-:103A3000E9F3217C917E86E10B67B221EFD2E10BA5
-:103A4000AB0A5F0A7C0FC1B8A604B8C6F38A1E523F
-:103A500051FFB75902561FF0DF03A53C5FD19BB35E
-:103A6000C84A7906B98BAC98BFB7D1EB68C278DD8C
-:103A700046CF12AB25414E6FF4B6503BF4A77C28DD
-:103A80006FD48EEE0956CD6264FF6F99D9E85A81E2
-:103A9000F8D3C1F3ABF47C235D1E3211BFA47DC10A
-:103AA0008B633E7760E810F4DFD23199F2C9C664C7
-:103AB000FD89F2A8B6B5F97CD8FE2D8C33813EF194
-:103AC000A0883321A2921FADE6F247312E5B5BBA8C
-:103AD00046C2748EC25546F9949F94A7537B26D64E
-:103AE00080F9586C05CFB772B5C849F2D048B7DB3A
-:103AF00010AE3C2F2A2271F81AC6FB3D32E95CD485
-:103B0000EFF730B4EF9E85B1CC46FA32617E523287
-:103B10003DCA8A5FAD47BD7C8D89D65180217F101B
-:103B200071B5D5F35D2BE079E1CDB24F82E763BD8E
-:103B300077539E1268F5A46F78BDC71BB03E629F95
-:103B40002B8DFB48DE57F2BA4170911EA29F57EDB4
-:103B5000195F3ADA51B5A58B288F8C7E747A372796
-:103B6000ED271BED5F93DF0672CCEE49D81733F4D7
-:103B70001376DA7F6DFD242213D25172FCEB6B01B8
-:103B80005A671AF359157AAF85EC453DAE968FB456
-:103B900083E73E9EF1B844F2FB53F9FBCCC5E36CDE
-:103BA0006976303D81FEA4DBECE4BF4C4B833A9C4C
-:103BB0008FA430EB3878BE4BF8FDD64B4CC67A7CE0
-:103BC000BE28E5A9774981ED3E3796DC5EB26405F3
-:103BD000280F11C3B48976E721CCEF80F635B7BA48
-:103BE000C7A2DF6E0C10440CED661197D2FD24992C
-:103BF0002583CB517E1797952CB6A27C46C7D2E57C
-:103C00008C5DB6B7E8FEF0CC385DA69DCB675A82D6
-:103C1000FD922677509E47DAB9F1067F4A54D85D67
-:103C20007ADD9F2337E27C73D02EC0BC26A676E3D4
-:103C30007BF500142DD13F7ACE6518273E7EA16119
-:103C4000DE28D8CF897180D1C74F675A45E2F8C5C1
-:103C5000A38C5F9634BE9A72FCF8B8D9867137CAC5
-:103C60009C5F8473EC9154FEBC95650D5797E58E6F
-:103C70009E87F6C532E177B302CBC7B893C09BCD20
-:103C8000AE0ECA4B33DB797CD422E2258733DA8847
-:103C90005FB142635E5A0353656CDF9839E798045D
-:103CA000ED0D0EA39E7ED5F937CDC877AE928D7AF5
-:103CB000BA9F75107E5EC98CCF2D85463E40BA36C0
-:103CC000FAFD3326C7287F2DD7417906A3F90F7E49
-:103CD000D3C928AFCA921EE840197777D9B4EC8DC2
-:103CE000D3A13E86E3D7D6B2F98BD11FF41B81C78F
-:103CF0001B81EE118E2D6BC6EE36278CDBA2444B5A
-:103D0000518EB498781E3FFDC0FCBFC9CD277F6A95
-:103D1000F2BC94099CE08F6AED90029E847DFC4683
-:103D2000D0C5F07C7714EC463D7678BEB4E8149AA2
-:103D30006F381F48CC97F7D9E67B43D0B33E5FEB93
-:103D4000578CFB6B5562B4BF561313F9FF7CBE371B
-:103D5000707FEECF309FC8EB1A9EEFABC6FDB5A6C5
-:103D6000C5687FADC3F6A4982FEFB3CD97A6745066
-:103D70003CE63E899FEBA1BD4BEE477FFCD9F96B3A
-:103D800034C437DD3EA3FB3366BA3F4372EFDA42F9
-:103D900085F4067DDC7D9DD3995FE17E1B2C2B662F
-:103DA0004A740FA072BAE4C778D8C340F7FE32F461
-:103DB0004BA9D41EE97451B9A753A3F231B007FD42
-:103DC000E49FF251FD6C19B787EF1BA72E5B89FAB0
-:103DD00042BD9DE741CFBC0234D1B8BD0506D82114
-:103DE0001BE61B7E814DDA8A68BE93C323A7312F61
-:103DF00082E7649FF462AC13EA6933CC1AE677A7D2
-:103E0000B9592095DFE57D913FB359CF9BFF9CC405
-:103E1000E3EDA08FD4C3FE6F14A066E6F912EA5555
-:103E2000D77E358BF491962583192AACE30669D2A7
-:103E30002F3C008FFF2DF4911BC7733A4EB62773AA
-:103E400050B24CC6BC3E732402BF2ECE584CF6E88E
-:103E5000E2A58C39E1FD6BF13D902BAF087DE6E5E5
-:103E6000C13486F65AB891C7996FB8DB6847DE67E8
-:103E70008BAAA8C7DD372987E179B4AC35B66F16B0
-:103E8000F182C54976E5B5497934A065F27C10DC4C
-:103E9000F30CC6DE2DCBC8A13C589147F384F00B40
-:103EA000B1C21C4AB676CEF58CC1F8639A92FA7EFE
-:103EB0008E3E5E8EE03B2CC74F70D0F3CA99F9A9B5
-:103EC00049F4BE984F7F6F97F4D4B88BF935416FA2
-:103ED0007B6BB082CB67D4AF59B931DFE7ECFCE242
-:103EE000AF37B254783B24A35F415FFFFF2D7CFDC9
-:103EF00011EE17CA57667D3899DF432B6489F7CFD7
-:103F0000F47CAAC5C37599A15EB954AFBA86BC78D2
-:103F1000DEAF7D2EDDB795F04FE80FD1D74D17D22C
-:103F20003FFD78C3EB70F98BB83F4EDC1314E38D83
-:103F300006E7E47C07DD6F433F53E3FED8AEDD3C8C
-:103F40002F323FA7E11DBC3F85CFDF34E095F19EC6
-:103F500054D7C01312DA17DFC27B5F727C3EF4D3F2
-:103F600086497F35DEDF1A218F19BF97A3AFA74B94
-:103F70006115648F9A803FC07C0B1C83B2A4A1DFC3
-:103F80007D88EEF3DD59CECF057387F97D18AEE756
-:103F9000990B4C3C7F6382C6F53ECFD0F8C4B8D0B5
-:103FA0000DE55CAE2F487F75AD06F26F49F9938B36
-:103FB000313F69C19857D7BAA17E5DF97717CB8099
-:103FC000470B0A5EFDD00D3ADBB2F2A778BDEAD509
-:103FD0000F8BA1BEBCFC695EBF8211505ACBBFB72C
-:103FE00018F9EA0DE5AAF0F3C50A71BE0512A78F0C
-:103FF000CF5A9AD34C29E3F7FF50AEFB139905E74C
-:1040000009F4FFE424F2A380EE7FF527C51BB12954
-:104010000FEF13899F9C4CD267E6E1EF00CFABE531
-:10402000E800BE6FB24609AEE59837534128F0C0AC
-:10403000858BE44724E39104E8BA0EF5654D652DC0
-:10404000A01F77AD63415B49029E33BFC0739EC71B
-:10405000A3AF479F7FC4BAE0486567E2BA1EA67166
-:10406000F4759D9E9416C67B677AFC545FD7696988
-:10407000E811744644AB0697E2B99ECE181A2F4158
-:104080005DAB5097503D77E811C99750B7F073BCBE
-:10409000B7FC27A4F7AC95FCF79623BF541C74BF5C
-:1040A000AD47E879DB728361C6F57BCA770C17F1FF
-:1040B0007B038D93257F627CFF9B02BFF22A7839B8
-:1040C0003B6D7BC709C0C7D00189AD87FEA1F367EF
-:1040D00015B4C717F49F52D0EE6E3F704A41BBBA79
-:1040E0001DEB304EFBC30AF1AB64781754980D7189
-:1040F00074DD9E385254B63107D6D3BE52F2618A6F
-:10410000EC9AE7B366637DCD0ADC2563D7CFDC3F4D
-:104110001BC9BB3530B011CB1BD9E0118C172C0B50
-:104120001AF5FCE56D46BDBCB5C3A84FDFB81D4E02
-:1041300007E4D78DEB0A0CEF31D490613DCBC47905
-:104140002E73DD1333D7603DE1BE8E44644DFE9D7A
-:10415000E57C07501AFD160BFA25A2E3F6662BF94B
-:104160005F8F14F13CFBD02A33E50585101DB0DECE
-:1041700021097F969FF8A32EBF67F79D395A80EFDC
-:10418000AFB2101C58D81F43FF43B3C0A71B9B9B63
-:10419000DE413C6BD66EE3727CC25E0BF957825CEB
-:1041A0001FD784FFBBA5EFBE4627EA9F6B25F26FA2
-:1041B0002C6F33EAEBADF80BEA6FEBA448D48D70AB
-:1041C00032B6DFB8CE587FBD5CC8DB2A568574F2A4
-:1041D000DB7249A67BC5A2FE87A25FBE1C8589EE65
-:1041E0009202A710EF5629D11A946B774941AAEB96
-:1041F000EDF0BC9DCB1D2EEF4D4051C4772DDCAFB3
-:10420000105E2D113E2E1F21FF13F403F3C87A4ECA
-:1042100005F7B777D9026BC95E7A4152511F69948D
-:10422000FDB2D31BB76793F13157E0F7CB6CD08B5E
-:10423000EB2A43A003FCCB168F89A03FACEC9F5721
-:10424000507E63599DE433113D9BD8BA5A2C65E2E8
-:104250000FA86FDAA02C33F73613BFBE4C5179FE8E
-:10426000A08B25F201FF134C4278E1D271DEAB0B3B
-:104270008F7D8CE778CDCE7BCE20BFF394F86BEFAB
-:1042800083F56DB3F1F9B73D2F91FEDAEE3D4A7C2F
-:10429000712CA009CEDBEE12FCB10FF8A3BEFF62B9
-:1042A000BCD70FFC0A2F8ECCF7D2BCE3F4F8809E6B
-:1042B0005F1B6D305D00BE3356CC5B50A311BCF26A
-:1042C0006EEB9570DF452CBC1EFD44328E991B2F82
-:1042D000753FFED278BCFA9B789EAB5D830AE9DF1E
-:1042E000225E9DA2DFEE94FDFCCCE047986D3E9FE0
-:1042F0008971E5352F945C34AFC26C3519E8D5A2CD
-:10430000DA0D747D758591CE17F88CF47DEDF4127D
-:1043100043FB427F95A17D71539DA1BE347085A161
-:10432000FF75CDB38CF6BE6B9EA1BF4D5B64A8A795
-:10433000575C6FE89FE1BBC9C86F727A297F40B1B3
-:104340008607831ADEAF676CBA33CEAFAB32AD9857
-:1043500064CCEC753607963D93D2A2786E3DF93C5D
-:104360009E9AF6D2975D5184FA98A7ACF5507E5785
-:104370008A3460BCC82AECBC897733033FFFA72A84
-:104380008EE77AB9A42278632594DE7D5A01CF970F
-:104390008E4DC4F3B1A20311F1F8392BE91D972515
-:1043A000E9BF4535F5CB2AF0BDBBFD73C92FD5C795
-:1043B00054BC57BB47E1F94CE1E778FEACB76FD08E
-:1043C000E44FA0B7FF53C1E5FD37020D949FD4DE43
-:1043D0000FD20CF17BE79B0AFAEDDAFB0732516E44
-:1043E000D404DE5450BF8E3F17F2441EB263FCF279
-:1043F000FBBDA9F3D0BE51A1D0F84705BF6DFD327A
-:10440000E7B78070F3D13ED2F967EB7EBEBFD6A589
-:104410000AD1B7CE47817F1AE261C97C79F9CCC84D
-:1044200046A45DE0A306FBE5C62573DE417B0824B8
-:1044300035E931C0478DED859B88BE6F4CB26FBAB0
-:104440002A86F9A9F702D0CBC98029E5BEF654C95E
-:10445000B4AF93C15904EF6F00DCD06EFCC60838CE
-:1044600071F87D127C9E16FE44FD9C92FB7DA78A0E
-:104470009FD3D3A3F0CB77059FDD23C56A919985A0
-:104480000276C2D3E556EB52CC33385AF4D1268C9F
-:1044900027B4FE40425B96FDEBC04B799877A0ECC9
-:1044A0003F9287F910A1DE23790CE0B4CAA2AD4790
-:1044B000BD18F0C0B71ECEA5BD2F4AEB5FDD5B3740
-:1044C00080CF57F7493E6485A10367E6D03ED9E027
-:1044D00026D4E3F78CB2AEFD153CAFADBF42E37915
-:1044E000F7419813E5EC8134B2635BF7031FC275A3
-:1044F0003D2FD13D8C3D5BACCDA9F493A7AAF877B5
-:104500001B5EDCA2308CA3AC82F7711F478B8E2A16
-:1045100056C49BFD12D984A1DE134BD11F1F5A6BC9
-:104520006118B7D5D7F75E51ECB7B8FFD7575A180F
-:10453000DE2FEC5AC9E3B1AFAF35D338E69B2D542B
-:104540005F762BCF133EBCF2DF3615C0B8AFAF920B
-:1045500028BF7ED6CD7F3C8AF565B7723D28197F8E
-:1045600087F135093F97058D7837024FDB3E1B9E5B
-:104570009EAC10F66B15AB41390BE73E7B2CE2CFBE
-:104580009D8CEE37369F3F6C190BEB2DDEA4FA3075
-:10459000B45B6D8E6CCC43BE7098B74F5AB55BE27E
-:1045A000FC45A37BEF053D0A43BBF15D715EEFE285
-:1045B00079E5E2D68624CC6B6372AC18D7E716791E
-:1045C0005CCF5858F37EF423C99CBF54FFD0B53B51
-:1045D000D18FB44BE0A3CEF7AAC0DEDF4F7EE8DE7A
-:1045E0007CBC8FFEB485FBC7C68BF14A4B86E62C9C
-:1045F0008432BD92CFFF47B10EBDFE9CC07FF687CF
-:104600004709BE0BAC1CEEF3D6455B701FB7C8C1A3
-:104610003F23FF9B3FFE97AB50AEF514FFD44BDF1B
-:1046200065611349AE85C4791C9EF1EF0FDF81F9F6
-:104630007695763AC785871E8AE1B9B67B64CA3318
-:10464000B4954E1E1BBC881F21744E33DCEF6BEFFC
-:104650003F33C79F82AEF757F1FD578B7B7CAC9FF2
-:10466000FB0F801FCBD36BE3FDF4FDEB7E0F5BE90B
-:1046700063744E777C894DE2F7FBEFA37196AF3AF6
-:1046800021E1BD94EB2C7E8B03E0FCCB316C29DA6D
-:10469000C13FED64744FED38DE570356F272A74AFE
-:1046A000F598B8B7F66AA746E5754A603CCA95A57D
-:1046B0002F769422BC0E173D18C0EF359C3E2EF489
-:1046C00059A6F2FB8E02F7CEF69B9915DACF1E9013
-:1046D00022E43411EBBFE15C3E0B023FF9B5B81F99
-:1046E000B77ADDCF89CFF9DACECC413B63D2AA537A
-:1046F0009BB01E5AF7C739A837FC16E404E257A846
-:104700004F622E18A7E59C93DE5FDD7742417BFE6A
-:1047100069D3D01C847FF8A044F7AA421D67887F24
-:104720003E2CFC2B37546671BED13FC944E7E99F4C
-:10473000C8ED1371FE0313FF9489FCCBBA4E7BE5E1
-:104740000A3CC763663AC7AD0D43996A8A73390953
-:10475000E3A24FFBD7221F2FB9BD5909935FB6596A
-:10476000E06D72FBF59526DD0EB7883C2526C17AF3
-:104770005A047EB532FE9DA0963E296A07BA6DEDB9
-:104780009F45FE8DD68E8B7F0766347CBBD4B29D51
-:1047900071FF865E47FB2B315F0BED2FE37DF5301C
-:1047A000E1555A91676CF022FA5D68309FE227ED7F
-:1047B0003D8CE225ABCF4DA4F2FDE737D3BD27AB4F
-:1047C0007DE841940BACCC447AFDEAB051BF992D01
-:1047D000E876B6D06FD654827D52C186ED13B043D1
-:1047E000BE5CC9ED90CC43CC609F243F27FBC42A1C
-:1047F000FC86305CF09914EB9E57D57057652ED22D
-:10480000D576C26F06F88D7895BCCF8D959C3E7598
-:104810007A5E76E81D05F5DD505F6A7A5E5A55BF0F
-:1048200011D7B36594FCBBAB05BDAFDEC9085EA173
-:104830009D4E82D37B6C67A001F0F23D5807DE5F8E
-:104840003F1D08A467C1FBA78381748CCFE9F4DF07
-:10485000BED34EEF6DF12CCAC6EF6DECAAE4F1F3B6
-:10486000F7FB665911CE37ECE474A7CFF7DBE8B25B
-:104870006CA49F29962105FD9385FDA73251AF9B1E
-:10488000F2FCE26CA4BFD1D6B975A258E7BAFCA578
-:1048900074EF077ECC40F7B70B3916DA105510FECF
-:1048A000B7AF6384BF03CFFD6B3BD2EFFBFDE92ABB
-:1048B000CAC9F75E480F23BF3F7D302D6282A156E3
-:1048C00089EF24BD6719BC86F4C7E7CD94AF103AD1
-:1048D000F8EE83488FA1E7D2E81ECDEDFD9BCFA077
-:1048E0009C5BD53FF71D19CBA7FEBEF4B07ADDF86F
-:1048F000A589F9C5EF76EECB47FEF9BECCF9C4ED3C
-:104900007DCF923E7BFBF9B335983FF8DE0B7F9E5F
-:104910008AFC2CF4CF67A7221F0BFDF8EC546C0F18
-:10492000FD30BD23957EF2E32AEE3FD1E5A3FB35B2
-:10493000D9E067B959E087BB7B7B137ECF60CA891A
-:10494000251407D0DBA794F27BCC537ED1987D73DE
-:10495000C27BDD3199F225269F684C5F998097D7FD
-:104960005759747FCDA5F947441E82EE1FD9129383
-:10497000F9BDBA36337DBF6E798CC7DF93FD268CC7
-:1049800005AEAEC6F3BE35D787DFF1C1FBEB181716
-:10499000397D676984EEAF87AD473C097AD0B2981C
-:1049A000299A867E90FEB428EA43CB62F2A9B40429
-:1049B000BFC86FD56736A21ABF2C68F46324FB41C9
-:1049C000E027434E889FB4AE8D5A7439B500E6FF98
-:1049D000E546A662DC66847FA4F9F3E48749F69392
-:1049E00068B107ACF89EE6E1DFDDD1F54C3CAF03E2
-:1049F00029E87DC344CEB7743AEA8E99E81CBA63BD
-:104A00000D560F94FF28DA0F80D80C635E50FFE23A
-:104A1000C7D14EEF3E7F5D3AC2ABFBB5450CBF2B15
-:104A2000715A6DB096E27BE73F6F5DEA8DE3C70890
-:104A3000FE3191F3C7617D6014393753CCFBF79297
-:104A400077D3279A84BFE1FF6F790776F55513B9BD
-:104A50005DBD9CFB3DB85D9D2C2774FEAB8F1B128A
-:104A6000F01EC97FDF21FD05EC5FE2BFA1891AF5C9
-:104A70002BEC5F984D76F16B4BB235C7C8F14B64A8
-:104A80009FC9E91D39BEAEAF85C2FE2356B463FC93
-:104A90003CFF34B444A2EF4B850212E9D9A1164B76
-:104AA00004DBF5F5C496F0B8E0529F44DF0BD1F576
-:104AB0003F5D3F1C6E9F0CEDEEB8BEA8EB85B100CC
-:104AC000F78B2EF15BA8FD3A25780BC2E9B7511B95
-:104AD0003D9F32838F0B7CE008FA3FAFFB8244DFBF
-:104AE000F3D2F5451D3F93F5C90FFA4B2EFA9DBA47
-:104AF00087055EEAF4353E892E7439B5AB92C3A7BB
-:104B00001DE57436CAE98F9541C7E87A37C8E9BB15
-:104B100070FDBB2A19BD3FF917722095DD9D21C696
-:104B2000DF8AE7066561ECC57A5C6F118B515ED454
-:104B300068F2F3B62A4E0FA3B5EFAABC343AFE8151
-:104B400098FFEF45C7FB27FEF7D05B87F53F25F5BC
-:104B50003EE755D5FF6822C0D56EEEA0FB51EC5F55
-:104B60002CE4B74EEE1712F218E499018F8F142936
-:104B700026B47B426DDCEEEFC9D25E21FBE4257EDC
-:104B8000EFFE7691AF74DB3995CA1EFC8018B67FB4
-:104B9000D94D7E9BDBF69DB0F8E1FDE56BA549E8BC
-:104BA0000F5ADE66DC4F4FAE7F6EA21FBC675C2FD4
-:104BB000C515C28F9768387E2B6E16FD213DF91101
-:104BC0008C3DB6A31FE7327C9E70DF02E6592D9E16
-:104BD0005F21FC3B2C490FF8F1C0EBE4EFC1B810AA
-:104BE000D2AFD22F515E48E818F777B4F773BEF012
-:104BF000769B44FCE46D919F115A6723FFB6AE4744
-:104C0000BC23FADD7AA744FADE08BDC26F8CBBACC8
-:104C10007EEC17C41793F508E7013E0EC65BD02F54
-:104C200073A468AA84F5D56017E2F74B439A766DB2
-:104C3000015F1F8B107FF11BFC281F1CFB37B22369
-:104C4000973F2FB16CD23B92E22F3DF392E22F4778
-:104C50008F14E03842CF50E13FF41F26EB19ED7D71
-:104C6000272C68177C529C45A91AF6B7905F708272
-:104C7000CCFDAC13FA2515FD4913049CA66DB113A8
-:104C80009CE6BCB1321BE95C3F9FF717F2F37AFF59
-:104C9000F50FEBF1BDA96FC82AF2DB1FBFBEF6E727
-:104CA00005BCAE59357C6F6D3ADA21EFBFB1261DD8
-:104CB000E1F86328F13B4A3F3C29A7F41FAE15FCFD
-:104CC00008E45B4115E6DBDE2DFCC632C8B78CB8C4
-:104CD000FF25F9BD1DC21EEBC1EF1B21FE3DCFE339
-:104CE000DB3DE382F3A8FE5031CF239639BE3EDB95
-:104CF0009FA5A2BE57059BC538ECF7ECAC1BE32B78
-:104D00003DB9C19F127D3C6422FC85F7F97727F6F7
-:104D10006B24EF106418FFA8015963A5BCC61C8A58
-:104D200083E8DF85190776A8F88EC2128CBB5689F6
-:104D300038488D9DC938FE364B706B25C65D0664BC
-:104D4000DF7A7C47F665E3F79292E3317A7C588FFD
-:104D5000CBE871E2D1E23212CE53C3F12CF13B2702
-:104D60007AFC857D81E76F764DEFA0FBAF63B12FB5
-:104D7000F1CF11F194D5686F26C753EEAAD4FB1B6F
-:104D8000E3695B2B9E217CFBB471B41F4C1C6D7ED0
-:104D90008D9E27CF3F39EB833CB25FFEF21F9924F3
-:104DA000CFFACF92DC393D9426EE710E723F75BF7B
-:104DB00085ECF5D36007E526C8B35F55F2710FF5B2
-:104DC000CF227C3C106B4CC7FE7FADE4F0D9F2DA09
-:104DD00092C5A84F876332CFC766DCAE391093A760
-:104DE00070FD60049C364D4C0127AB3D751ED054C0
-:104DF00081D753ABF8BE67BDCEED95D05A1E3F505C
-:104E000005BD859A14E227478BF224DD8F3C365589
-:104E10007CE1F921E2B3ADB7F2F8EE25C717FA0647
-:104E20002CAC3885DFB6690EF19B4BF5D732B482D6
-:104E3000A7C6F9F3769D9F5473FFADAB8AE7F33BAA
-:104E40003B26D5E377F1F47DA78023F35E5A9C2FB0
-:104E5000B3FAD2FA2DACB8B47E9B2B529C5F8A7EFB
-:104E6000DFB8C47E3FB8C479D353D1578A7E7FBCA4
-:104E7000C4795FAAFC9FF8E7703D39BE991C0F4DBD
-:104E80008E73A6BD747318DB364BF70C4511BA99B7
-:104E9000CF35E3F7D3E5ACC7ACC8D7E6CFE0F180B8
-:104EA0002D8DD6C86E291E17D5E1F55135D7BB54C7
-:104EB000EF99307E3F71BC3FD6980D747C7A062303
-:104EC000BBE1B44D7C0F4956C72DA4F353E97B38A1
-:104ED0003DB6D4F1A527C578A3F191A29AFAF3556E
-:104EE00053E8FE50CAEF54DC2FF440B58F91BF86D3
-:104EF000C9DAB84534AF360EE5CC9817F9F3CC28AB
-:104F0000A3FC3E68772F22FD5973E3FA7688B897A1
-:104F1000735E991BFD744E90B71817B90FE323E425
-:104F2000D757A99F3E5F9797CFB7C3C2248C63859D
-:104F30002B795E056BE935C4358E5BA2BF5B2151D1
-:104F40005C632CD2FBCF4C51EF1E373F1784AFF779
-:104F5000804AF19697677CA782EEC58B38C71D2AD9
-:104F6000EF7218ED0C58C71D2FD411FE2E3F34E3FD
-:104F7000572DA80F7A6482F3083D5CD85727857DAA
-:104F8000A8DB5783682726D81B555ED3687CA92ADF
-:104F9000155FDA2171FB37FC336EFFD629BE92C450
-:104FA0007CAA69021E2BA2DC0FABDBB535FE88297B
-:104FB0000FE05077A7399A06B2B76E53B582FCBAA4
-:104FC0006E53919DFC4A2BF79B7478A73AF77AB100
-:104FD000CE2DC786282EF16CF23D732F8FBB0E09A4
-:104FE000FCE9C2B385FA1DA572178ADF3133557308
-:104FF0002ABF782BE8FDB8BE153D7CBD7A1CA435D0
-:10500000AACDC2794E1D19DA84656D9B7B16F90D08
-:10501000579DD984723374FEECD1ABC80FA068A938
-:10502000EE0B586BCCB48E6751114178CD95296F3A
-:10503000B76EAE4CE7ED6CB5911DEEB430337E9F8C
-:10504000D5B990CBB1DAA69C5958674BB2480ED768
-:105050001ED3B26EF6C6ED7CE7DCB5B908A74F8A61
-:105060000FE9FE82EB14FF4D788E9F363EB4FAF8BE
-:105070006B946776C3A0313EA4C77B468B0FE9F1E2
-:10508000D950D387867872481E9A837E95BA174E78
-:10509000517C38D427A92E773C6E143A704621F8FB
-:1050A0008A7811F457F0BD3A38F6714EFCDE008F65
-:1050B0001F3D87F9B80A7E4F4FA5BCDB1F613E6ECE
-:1050C000197E4F8FE7E31EC47C5C05EF7FF07CDC2C
-:1050D0004322BF37D47F86E24D3D5E63BC428F479B
-:1050E000DC2505B679730DF10AAA27C72BCC766E9D
-:1050F00087868E59E8BBE8A1E356E2B3F5FD2B267F
-:10510000A03EA67FAFBC1DE30509FEA5F7FD3E1B33
-:10511000DEEF793FE0B3619CA06EE01D4523BE1336
-:105120002DC014A67639A6A0BD8F70A03CBFFE7A14
-:105130001BC2F513FDFA7DFFE3D7FF347EFD8C38EB
-:105140005D12FFA80D98E85E79ED31BFEDE604FE33
-:10515000B025C0FDC35B3CC5447F0F048AB356260F
-:10516000FAF19BB8FDE69CEBB1253E5F54C3EF0F0F
-:1051700038A5D4F70B5EF7EAFED711FCF6756F4A37
-:105180007D27753C604B13E723BABF7F647CC0F773
-:105190009227C1CFFFFECFACF47717069E4F23793D
-:1051A000FED10B697B50EFAE6D5A392103EAB5276A
-:1051B000D3989BCB23435C617993C96FCB4C154744
-:1051C000F017D0F74293E3054D26E2EFC3F18226B4
-:1051D000F914D5857E7EC3997FCFC04F643F2B45A0
-:1051E0007AD0BE7876B5E41B6023E3073070019B6C
-:1051F0000EBB68E27682AFD94A76C127C5155A0E32
-:105200009CD8887E82496C7B0F7E7F7292C7A48275
-:10521000284A1157E0F99DB5428F48F60F207EA02D
-:10522000DC4FF60B665673399459CDFD983B51AF60
-:10523000CF8D8FA3BF977CEE5F147269343FE3621A
-:10524000D1DEDD54BB05CF2D3CDFC490FF77373571
-:10525000583D09E3B9AB79DECC0E8C53E424C62962
-:10526000783C22393EA1F3A7BA818FE7E0B93FD05D
-:10527000CFFD472117F767D61DACA77B26F17572C6
-:10528000FC7CC0357CCF308BF17D312BF773915F87
-:10529000A176FE8787F0EF12B04016FD9D83D07196
-:1052A0004F9703F9C87C798AA4917F7BD8DF8DFE64
-:1052B000A8C5AFB4CDC37CE0BAA5934EE0B92C6DC0
-:1052C000B150DED1E2579AE9FBE3BABCAA5BBA7BE4
-:1052D00003FEDD9AA51592CFA6617B5303B65FFD51
-:1052E00054143D7B6C01AE0EE825761C7A17937F33
-:1052F000BBBE1AD65BB750F8BD5BB85C5DDABFD0F9
-:10530000C23F6E659473878B3E22BBF96C7F1DF99B
-:10531000B3B331DEEA8DCB99BA1740FE64C4E5CF52
-:10532000DF2A77BE58CDEDC0CB40FEE07A9C0B79EA
-:105330005C30F9FCDDE2FC479327A3F14F941FFC9E
-:10534000EFF2840B24575CEE6A684F4F8BCB5FB54E
-:105350000FEA6347C7BF87847E95358AFEF580C014
-:10536000F751F335FAFE3E7EEFEDD5FF3DE257BA39
-:105370007DA3FBBF757BE8F702CE7AF9AEC08BBF89
-:10538000395F198562CA7C6567EA7CE51B7A25FA74
-:105390000E8BC8573EA2B0FAFD3998A727EE2544D8
-:1053A00002A4DF1CD9F5EB4D4FE4E0BD044945B143
-:1053B000B3BAF704C9E7D5A0CF901ED4FF2EF74BA0
-:1053C000F5F2FCD2D57DC6FB0F7AE9ACE1F1F646E9
-:1053D000D80FF991451EDF9C039CAE437E25A2B9F0
-:1053E000D12FF41539D12F14D262B97A7E6084CBD3
-:1053F000A594797CED6C88F2FDDADB241FCA83CF9B
-:10540000EC27F2F3FCBE4BF513FDBCDA987F7AAEC5
-:105410008ADFFB690E4A12EAA356536015E5F71EB0
-:1054200094D45479A2EF087973B5F0D3EE55381EB1
-:10543000ECBD5CA2BC5ABC1783E7BBF720CF9FDF53
-:105440005BCBF3E775BFAC9E175F19F7CBD27D1826
-:105450003D9F5ECF8FD7EF872EDC698FA27EB1CDC7
-:10546000D2EB423A1CFE4E0FEA22D06E17DF194FE4
-:105470005EE72FAAEB775553BF51F59B3F56A7D058
-:105480006FFCC24EFB73F5A87AF95FAB8D7A39D504
-:1054900093F5F2FF2ABFEC37C43E53F9D552EB67C0
-:1054A00023FABD7889FD7E980A1E5DB6D4DF0B6DA8
-:1054B000AD11FC37E9EF92B011F77BB87CEB91B4FA
-:1054C0005F5D41712E0BC5B974FED293C1C7F78AD7
-:1054D000F1F4F2F3359CCF8CF65DC945A2DF5AC9D1
-:1054E0005F553305BF1F6FF49355F71AFD6497F5A9
-:1054F000390DF549D17C43FFBA63C586F629B189D8
-:1055000086F669276B0DF51983971BFA5FF1768391
-:10551000A1FEB921A39FECAA738B92EE1D71FCAE84
-:10552000078C487C6F96F58B867E056DC67D15755C
-:1055300018F735619D715FFAB8EEB0717F253DC6F1
-:10554000FD39D17FEFFDECFEFB9857E3DFC1E92F7A
-:10555000A1EFFEED68F2D077AEF5FB7FFF09FEEF1D
-:10556000D922F072000000000000000000000000DE
-:105570001F8B080000000000000B53E16760F8512A
-:105580000FC15BF918182EF021F8F4C01CCC0C0CDC
-:105590009C40ACC8C8C02001C4FC40CC06C49E0CD2
-:1055A0000C0CFF81F81B10BF05E22740EC0CC40770
-:1055B00058B09BE3C6CAC0E001C4DC40B378988908
-:1055C000B7DF8917C17ECCC3C0700E889FF1D0377A
-:1055D0000C061B5E27403FBB7E43ED3A2932F0FEAE
-:1055E00006612131609A1447F0A78AA3CA0B8B2168
-:1055F000D8C9D294D9950FD40F00F19321F080032C
-:1056000000000000000000001F8B080000000000E8
-:10561000000BED7D0B7C94C5B5F87CBBDFBE92DD45
-:10562000CD26E44900370960501E4B80C84BDDF0A1
-:105630003252C40411828A2CAF10027914A9A5FF3A
-:10564000DABB0B2804AADE5851A37F6A17041B2D6E
-:10565000DA80D11B6DE02EA208D56A684551AB0DEA
-:10566000888808498C8F6AB57ACF3933DF66E7CBF3
-:105670002E89B6FE6FFFBF7BC3AF1DE79B993367D3
-:10568000CE3973E6CC9999B3268383192E60EC1B2F
-:10569000FCBB9C319B893136A62B6D573A86AB39C2
-:1056A0005DE5B7F9BDCC6B66ACCE6FA5748B3F9D45
-:1056B0007907C3779FA1306867EC5EBF8BF2BFF0BC
-:1056C00017525AEB2FA27A77FA4B287FBBDF47E9B4
-:1056D000667F197DAFF157537E837F0DA59BD4451F
-:1056E000692C05FA66458559C98C553D9393B719C0
-:1056F000725B668D4F504743FE15233366017C9FD6
-:105700004AFD31D5BD69E0E8AE7A1A9E9BD449FDC9
-:10571000104EED128E17B3325B8C7A5938CE3B9710
-:105720000878F6D69A9CE4A8F50623BCDB4B00DE8D
-:1057300050287085AC39D1E15D8CF03697A8BC5EFD
-:1057400072B0263B3A3C0FD6ABB941C04B0F586301
-:10575000D41B83F536DC20F0EBE7ABC98ADEEF78AB
-:10576000ACC75CEADF5AAD8CFEBEC9C6FFB7BB4E04
-:105770005D2CF246CC263136AEAB9D3E652CC0701A
-:105780009C2AF315121FDC995F7F93CFD84D081325
-:10579000DA0726B19011FA0F24B1E0FA2CA9FE4CD9
-:1057A000AADFDAF7EB6F52A5FA014394FA26D6A0E6
-:1057B00060F9CF518E80EFF7F97329DD28E4E7BE59
-:1057C000A106C6B05DBA393808DADDE3F790BCDC73
-:1057D000ED1F4BE5770939FC7721674121670FA25F
-:1057E0009C41BA15E5CC8CFDF95A4B014EFBDE7895
-:1057F000B6D94DF2B598F05419C1DFB077C8F6CDDF
-:1058000000FFBE1B569DDE06F46F6B1EE63142BDE7
-:105810007B866AF2C5BC2CB9ABDE3DB34F38170DA1
-:10582000257A97219CBB3D827F2A0C2CA2DEDD339A
-:10583000C2F52AB0DE5D9E30BC5064BF774D09D7FB
-:105840005B457C56584983BD3B5F763085E623082F
-:105850000AD1D784F48579F9EC80EB9456689F924D
-:105860009C97C6A0DDFD381FCD38EFDC4417AD3D59
-:10587000D2D907DF332CAC1AE10365F71B015FD3E4
-:105880006C7722D2E5F66B8B98328CB1BEA23C3598
-:1058900050A464015CFB9C2205BF9B6643397C7766
-:1058A00089F2E435BCFC762C7774952762397C4FFD
-:1058B000AA8672C8DBE7F2F23BFCC089C15DF5360F
-:1058C000019F7DC4EF74FE1DD88AF4318DE6A98650
-:1058D000F713282440BF83988EE9C27FD3A07B337F
-:1058E00016DABBF0B50DAEA7BC86DFA6C17194D7A2
-:1058F000F0B15DD82F6321A47D97F465DE5C311F84
-:1059000058773A277AB3A5F24CD593A0029D325F1F
-:1059100032B200B02013C413E1E9DB153103E1D941
-:10592000E3FC4BEEDDFC330D95E9A0A547053D34C6
-:105930003A6CEC2FD3C13240A6C3C601321D2C17DE
-:105940009C9F0E3B989BE81C8B1E5ABF9B87C8FDF3
-:10595000C65D24F7BBF922B9DFB88BFF39FDD664E9
-:10596000C9FD5AB3E57E6BB2E57EAD39FF58BF4C39
-:10597000F5C064407DA5FD5D28E9B7AB99EF2CB675
-:10598000473D87F349D373A6641FF3D9BBF809EBEE
-:105990001463F99170064B7A15E07C8AF5008EF756
-:1059A000FC705C3A3883F470BE16F8B0483DDD0DEB
-:1059B0000E1BA81F8749E1ED428688FE99EA6345E0
-:1059C0008EC8761E5DFF39FAFE9D8A1887E1BCFD00
-:1059D000BB7574CDD6E39326F06186F3D183B97499
-:1059E00070B2F470DC029F90725E386EFD382E1437
-:1059F000FD071469FD027A0CEB6AD70EF8D13A95CF
-:105A00006709EE04FD10DAF7E5295C07CE355EEB99
-:105A1000B640FDFD232DA1CBA1FC5CB0206881F236
-:105A2000C94F1E75A21D53F1A451C572C33E1BADD3
-:105A30002F6D3B142AAFB2B4DC3901CA3B9E34B29D
-:105A4000EDD45DA601C7774AE81416E2F9521BCFE0
-:105A5000566CDB7F23B62F6BB2301BC0AB787AD984
-:105A6000CC09905F76C8C4B04AC5CEB5E6BE905F9B
-:105A70001E541A300FF8D23A15C8B3057742FD7597
-:105A8000FBBE6C43FCCF359A06213E67609D70C318
-:105A90003AF192A3257536D0A73CB87B1AB62FDF12
-:105AA000A57840C301FE3B0F6620FE8F281E0BB079
-:105AB00070457D3C7347CC97538D461AEFAA6D4ACB
-:105AC0009001BC65AC761AD2B302898378782C41F8
-:105AD0009BD235DFCEF8EBA83F2D5FF108F407ED40
-:105AE0002B1F573C38E44A03F3E13C6E7BDA56F255
-:105AF000901DC7BBD63CD881E3DC68C67ACB820B4D
-:105B00009FB2B911CF6DE66988EFD66DE6D2A14894
-:105B100047B6A06828E2F77F65FCEA8C5E1CEFAA16
-:105B20009196ED46C083D943036739BAEBD933B0B8
-:105B30005EB923D6CF72067A9FD6EFA0B97858D730
-:105B4000F72F0D89A43F56D41B99DBDAD58F261F7A
-:105B50008123423EF63A88DE1A3F57B9F814D0F84E
-:105B6000B92A51F057EDC89F35AC3B3E77225FC84C
-:105B70009E7651FA0B583731DD02EB3CD2EF5EB026
-:105B80009FDC64977BE8FB03602761BA15EC244C2B
-:105B90001F043BC92DEC24ACB71DEC244C77809D31
-:105BA00084DF1F067B1CD37AB0C7F1FBA3608F6331
-:105BB000BACB1FA0EF8FFB6B286DF0D752BA07F955
-:105BC0000669A33F48F59EF2D753DAE46FA0EFCF02
-:105BD000F89B28BD5DD0D1399115E03AEAF432172F
-:105BE000923D6986B7C004F9A4229E4FBD21506042
-:105BF000867CAA0FF24097BE2B430516C8F7ADE688
-:105C0000E5036E6193AC901F10E0E5D9B77B27D90F
-:105C1000209F5DCBCB076F0D4C8A83FCE0202FBF0C
-:105C2000685768523CE42F6AE0E5C39BD9643BE4C3
-:105C30008787783EEF25EF6407E4F35A783EFFCF7D
-:105C400081C94EC8E7B7F2F6E3CF068DEE28EBEF39
-:105C50001E937B31AA9C03CADB5E3503F266F74DC7
-:105C6000A8128F2AA728DF68F252F9FB4ABB578592
-:105C700075BED1ECA5F22F94CF29FF94C947E5F169
-:105C800006A580F2661F95F737C451BEC914A0F26D
-:105C900011863E3C6F0E507981A15F01C27FC61410
-:105CA000A4F26B0C8378DE1CA4F25FA8C30BA640A1
-:105CB000FDC70DBEBDA8EFD62BBE32B40F99DA904A
-:105CC0008EFA4AB32B77E2E0D0CECC30D33CD8F377
-:105CD00087FC87681EE05F32E64B1F46BB14E01C62
-:105CE0002438268063EC194EDECB632538792F9754
-:105CF00069705E2138B6DEC1D9F3F278199F97CB6F
-:105D00003538C7088EA377E3CA7B65A28CCF2B2BCF
-:105D10003538C7094E62EFF0693C2AD3A7F168987D
-:105D20003E67707D589FD23B7C46BF26D367F46B9D
-:105D300061FA7C4CF864F40E4EE36B327D1A5F0B13
-:105D4000D3E72B82D3BF77E31AFDBA4C9FD1AF873D
-:105D5000E96332209CACDEC179EA6D993E4FBD1DEE
-:105D6000A68FD380F419D4BB71E5BF23D327FF9D41
-:105D7000307DD2089F21BD83F3D43B327D9E7A27AC
-:105D80004C1F37E133AC77E3CAFF8B4C9FFCBF84D9
-:105D9000E93384E08CEC1D3E4DEFC9F4697A2F4C59
-:105DA0009F3C8233A677F88C3D25D367ECA9307DE4
-:105DB00026109C71BD83D3744AA64FD3A9307DA60B
-:105DC000109D2FEDDDB8C6BE2FD367ECFB61FA5CEA
-:105DD00045700A7CF5840F03388ED8709E3927D31E
-:105DE000E7997361FACC213853014E4ECF70C6B794
-:105DF000C9F419DF16A6CF02827365EFE03CD32603
-:105E0000D3E799B6307DCA88CE57F56E5CE3DB6583
-:105E1000FA8C6FE7F4A9B278263BD0BE4B649EEDB6
-:105E2000D0E492930D079C9037D99907C1BEA48402
-:105E300076207C582BC92E543D9A9DE2616887CE0E
-:105E400070BA3DE8F7316AF6086BA1FD827D57A272
-:105E5000E40FFAD230E916C4D701565BA45D923044
-:105E6000364EB28712BD4952BE4F615FA97E4A517C
-:105E7000B6549E567291549EE1CB93F29965E3A578
-:105E8000FAFDAB2749F90BD64C97EA67056649F945
-:105E90009C9AEBA4FA836A1749E517D6954BE5431C
-:105EA00082ABA4FCC5F5FF47AA3FAC619D543EA25E
-:105EB00069B3543E32F40B293FEAD00352FD312D31
-:105EC000DBA5F24B8E3D2A958F6BDD23E5279C7E6B
-:105ED000466707CAFBFFF5058CDB831966B20743EB
-:105EE0000E33E5CDFB6C64FFEFC73CF0D3DC7706E7
-:105EF000E5CDCF2E7627E37E1A01C07A5FD0B7ECCE
-:105F000042F4F7DC3CDE77A10BBEDF6CF68D70450A
-:105F1000F1477854DF3E03F98B5A14968EA9DB8043
-:105F2000699C51ECD72D5CBE3666E53F148890D352
-:105F30009AFE30FF207FD86026FB5593EF8DFD4BF6
-:105F4000D31746F4B3A1BFB964FB50FE7DB11DFB6E
-:105F50002B7A11E75995B96330E2A5EFC7923D5608
-:105F6000EAC73AA08CFA790DFB89F07B590694E9CF
-:105F7000FAB1966C17DF453FC7705CB1FAD9983D0E
-:105F80005E1ECF8072EAE75D5D3F1B0794EBFA89E6
-:105F9000E3E381EFA29FF7CE3B9E9C89F2782E58D7
-:105FA00049FD74E8E866B960A5AE1F3BF583DF17CD
-:105FB000933F17760169C0674B4729C9C17FDA58FB
-:105FC00000E4C29C59FE6BCCB3B76C6C10F6E38650
-:105FD0007EA11ECBE5FEA3A70D49349ECFE280FF34
-:105FE00011766AD77E3640FBE2A5024516048C6026
-:105FF0007F5B296473C9AEE20137B9216D3A30F095
-:106000006EEC678BC33308F26D4D93CD8BA3C8D371
-:10601000D25AD3A9D648BF88B6BF99C472ABA1FFE4
-:106020005D369794D7D2958A8B097F04E54FC0BE21
-:1060300085C17EE0CFB02F6040AA774D7C9FF60EE1
-:10604000EC6F30DF0AFB1B2C676C2DB53B21FCB4D9
-:10605000276E578248EFCF7EF24313E9F1007B357C
-:106060003D15FD6EFC6FC19A78F4F187F15B18E87D
-:1060700023E5415D661AD2695F48FBDF8EA72DC11B
-:10608000ED48D79A4CA0A9A897CDD8EBB0C9CD4878
-:10609000A26CA6612C63B3AB8BA7A6D12C52FAAF2E
-:1060A000023C67358E34410BD6666ABDD163EF8200
-:1060B000CBBCA613481F2BFC4338D714423EA2FF8B
-:1060C0006B8BE4FC5CA676E581DF838DD9826FA2C1
-:1060D0005FB7D7847C2D4AE5F8CCC5340F8BB9BFA8
-:1060E000A3C4C5DB6AF8542D36B110ED4F03290C5B
-:1060F000FDD18164AA779DB6CFD4E15762B27A8B85
-:1061000080AE250B8D44573DBE6FEE8BF71A86434C
-:106110005A73B7095D9B3DE13FCF2797B332DE9FAE
-:1061200046574D5E4E09FE9E40FE43FA3EF21FF07A
-:106130003E29F8DF25C79CFF5516DF4CE47FC7FDDD
-:106140004646FC127C9F23F8BEB456E6FB1CF49333
-:1061500043FD39ABB382EBB17E5D1F89BF307099CF
-:106160000EB5774D05B5DA0DFFB7851C5C57B3FB4F
-:106170007964EFF565BAF1093EDC28F8305F478FA6
-:1061800039826FF305DF96B1C06D19E43F0A9AD0EA
-:106190002F36AF4C61A82FAA7EAAF1AD55E29B4FD6
-:1061A000E39B0EDF1B05DF6EFC09E79B1EEF56C16C
-:1061B000B7D6BA8F4D2CBB3BDE7A3C17ACD18D2BBA
-:1061C000A0E75BAD38777099D1DE29F616F439195E
-:1061D00051FF9AC22BFB9C8CD00BD716154BF9B9EB
-:1061E00025F3A4FAF37C0BA5F2EBCB964BE5F3ABCE
-:1061F0007F28E517ACF989547F6160AD54BEB8665D
-:106200009354BEB4F62E29BFACEE7EA9FEF2E03662
-:10621000A97C45FD23527945C36E295FD5F4B4545A
-:10622000DFB06FC8D5285F2F1D3532F4977DEA792E
-:106230009FFC759F7A4C1EAC538932370EE5D94DC1
-:10624000F27CCA9F4BE969BF87E4FD8C7F2CA56D6A
-:106250004D07ECE87FAC8A03BD9F0876B8F1CDB559
-:1062600035FD70BD81F6E3196B36B6AE0D40FE000C
-:106270001E46C1BC99516766A1510CA4BB6F589EC4
-:106280003B8C11E5AD3D94D7A92CD4A77BF98CD6D6
-:10629000E8DFDB958EC119E8277CC3C27646F8EBB0
-:1062A000BA9F57B04CB42B62959F35B0B2C8F3ACCF
-:1062B00093467E4EE2344E3A698474A599CFFF9599
-:1062C0007B32263127E64383ABA3F85DC2FD350060
-:1062D0003269C8E71C69DE2FABBBB86B9E33EC2775
-:1062E0009BE476797094F47D45FD04A95DAEE27B74
-:1062F000D708F5CEEE37D27ACD4207065C330CF1E3
-:10630000F39EC4EFAC2985ECAE16BFB7CFC9818C24
-:10631000FDD15F48E9ABFE224A5FF397507ACCEF9C
-:10632000A3F44D7F19A57FF65753FA8E7F0DA5ADC7
-:10633000FE00A527FC35949EF4D7527ACA5F47E940
-:10634000697F90D233FE7A4ACFFA1B286DF337511A
-:10635000AAE9CF9EE4EFB4585FCFA0FC459133F398
-:10636000AD6C5DCDC42E398B532DEB50CE34FACEAF
-:10637000A8B308794895E42111D76192B31ECAEBFE
-:106380004C420E63B58F5E8EF2D6F77B9037C6D641
-:10639000911CCC1472F75DE58DA1373E05E52953BC
-:1063A000274FB21C6A72A4E9815CA568B83AA64B73
-:1063B000AE661AB99DA4C9D5CFD14E8C626FDDA04F
-:1063C0002A62FDE3F611F36518D07E5B25FCFECC56
-:1063D0009D4EF94ED1F77A00D782F5D4602EAE23C8
-:1063E0009DB97F1B8CFEF1CE6316867EF858E3D3F1
-:1063F000CB4B6CBA7B69FF501A84456D54F7725BC6
-:106400001CA7ABCDC00A591E9ECFE61FF3013FE388
-:10641000FEF3E23CDCD7C27795915D15F41447F1A9
-:10642000B73394F1B49EE9ABD53FF5C097F9786ED8
-:106430003E53CCF3B803467EAE1D7AC8734DC4F903
-:106440000CECB7D3D1EFDC31C8EC22FB21D457A63A
-:1064500063B0AF44C703833E1B8CE71B9B400E71A8
-:106460007E750E1C9CC0CE231F3DE9F99EE8B9281D
-:10647000D8B797F434333C37027A6EC7FB2FBDA5EB
-:10648000674F7AB227FD786233A7B353D8A7B1E834
-:10649000DC3E09E65D1439BE475565396603F97976
-:1064A00087467FDC9746D0FF52BB9BEA3FB7EFADF4
-:1064B00001ADD04F67E385098C9FE7905DD7F1A4CC
-:1064C000B0DBDD99321F5BFB125C0DCE734FBE3E1D
-:1064D00000F7C9B76106E6D993F145BF5253BAE058
-:1064E000F5F61C3ED6B8767FCBF9D99EAACDCF96CD
-:1064F00001284F9F093D10737C3DC9298E0FE05C38
-:10650000A5F0F16D3016FD0EF54C787CA3537A356D
-:10651000BEAA04335346007E0EB3992530B643F528
-:106520001D54691FE7690DA09F625FBC673DB0A461
-:10653000CA79E6E5901BDBC9FE8C15F536976C3FF2
-:1065400025BA64FB29C315693F751E7AC8E903FCA7
-:1065500056A51B5C2747E13AE715EB1C5F5735FC56
-:106560002A1AB25C76098E9CEFAC550A1B489EDC59
-:1065700009B3A39C9769E9AA74B3EB24AC5767EA03
-:106580007312B0DF337EAB8BAFAF2E17EF37DD1555
-:10659000B9BEAE5C1347F535FC62C1FD67E3C75871
-:1065A000237BD78AEB2294E5C4AE1F939FEA27662C
-:1065B0003A976E367D86F6BB2D57B3DF55CA6B70A2
-:1065C000AB1A8C01CB08FCBE4BEA0FDAB9B53366C7
-:1065D0006C175B6E54764AE327F0DF8A07EFB46FDF
-:1065E000B5129F7D003101E0B5ABF61A94AB132ACA
-:1065F0009FCF55424E2BACAD669F9BC8DD82F2BC4F
-:10660000682CD326CCDCB7404F7FF0A289EE69B16D
-:10661000AF007A7ED7558125ACC8894ECF458D2BEA
-:1066200066E0BAFD8141DB0FD7E6E3B8CF31432105
-:10663000EAA573EC8FCE5111F3758889FB63580D71
-:10664000DFE704E01F8E6F69ADBCEF595627E74BBB
-:10665000D9AC54D4B7A55B4C2C08B82FC77D933662
-:106660006ED0BF1926EED758C6AA37E03EFD5E139E
-:10667000F7F72C72313513F0AAF88F5FE6A3DFC766
-:1066800063E27687769EBC3C89E35D3E3B68F642DA
-:10669000FD771B47CD018D0BED831BC8FE29669E40
-:1066A0009DAC3BDD17D7C8F8F584BF1E5FCD0EEA61
-:1066B00076AE2DF048AE57BCC1287AEE329322F662
-:1066C0007F7C7ECC36C9FE9C7926D9EFA3C981494F
-:1066D000C8C109D577B5690CE73BF251513BCCBE37
-:1066E000887AE6AE7AB3CF57CF82F58C546F9E2965
-:1066F00005EB754CA3FD3103791ADA55CFD605EFBA
-:10670000460E4FAE57F11F8F3D15007929FFED3D25
-:106710004E06EBE6076A6DAA07BEAFDC799BD30B8A
-:10672000E96935E0447E7E10341646A3C796303DB5
-:10673000BC7605FD69423E594D80FC149FED34B98D
-:10674000C8CF5F6F0959404E2B1B97CF60C3297F7D
-:106750009CE7377E64C47C93CCAFF25FDF93EAE6BC
-:10676000F76CB83F8985C8CEADDCF1DE345C2FAA6A
-:106770005807C999BE1DF6FF7912CDEB85E684EE68
-:10678000E58027F913AAC42CAB6AFCF9474627E633
-:1067900065F92813F62AD209F7F9B7991CC9A7E2B7
-:1067A000217B09BB04E7B9460F16E476EBFA47EE06
-:1067B0001B7E1CF039BBE345A73234523F7039EBE6
-:1067C0006C58FC2BAB21B61E6903398CB48F00309A
-:1067D000B57337097BBB99A72B4D2127DE6759B9C4
-:1067E000CDE40109642B1F3332BC07C0DEB004D1F5
-:1067F0002FBAE2B1E75F1B0F745FB1DB943C830FEC
-:10680000C7AEA476F1A50AFEB726AF8B0FE54F3CC5
-:106810006F760FE3DF6F49EAE2C78ADDFBCD6C5884
-:1068200077FA4D6ED86F6EB547E14BC3F169B8CEBC
-:10683000AE7FE4AF66F4277EB04F616959DDDB9728
-:106840006D7B9ED63BA413F151F029CCB76EFC0AA8
-:10685000CD7C6634D573A11E8CC5AF6542EF823CFA
-:106860003FFE0CDEFF79D3E2C1F1973D7E9313C763
-:10687000F1BE5ACDE5FA97B7A5E2FC2E3305525D7D
-:1068800094F2EF650FFE88E46DD9911FA592BDC00B
-:10689000BC1906D2C5810C1CDFD2ADD7D2F84A99FB
-:1068A0008FE4AEEC97C622BC8FF8A9CA0A77479945
-:1068B00017716685F0797F3B183230BEF7717F899A
-:1068C000FAEC8F46BA17C5D80FE9DED88FC45861E5
-:1068D000E5A3FCA756CEA7E3424FE24496E475C772
-:1068E000C616E4CF99FEDE343CE7003A0404BD94BA
-:1068F0006F00AEF1C8D434CE1FE656F3453BD0EF5F
-:1069000093F13BD66F31796DC3A576421FF2FE57E6
-:106910008BFE01EF385CAFDE4F8D6EEF8D11E383A0
-:10692000BF1616215F11F39BCFF71D9BF8FCD6E62F
-:106930007BB0B810CB3F7995CF1F6C87EB03E01588
-:106940004AA3F2FDB315D207B0AF8E36AF7798C425
-:10695000BC96CBC152A4F51EF0569584483901F877
-:1069600049447FDA07976E817611F65715F647F599
-:10697000CC5DDF23D68765420F98CC30FF2FEE9A8F
-:10698000FF6C2B9FF73DD9932B4DC1871FC0F9FAA0
-:1069900086C51370E37C3515E1B83FDC75E0B5EBD7
-:1069A00040AE3F6CD0E6A9AC3FF5F3B46CCF1816FF
-:1069B0006D9E7E6887FD55B4790ADFA3CE537B2B8D
-:1069C000C9F1F7AD3F35BA0D35CB7A13F5E033EEAB
-:1069D000D8F4D3EBC1DF9BDC4447BD1E84BF5759BD
-:1069E0007E77B9D3E44D93B3F2DF545C80FA262C62
-:1069F0008F9ABC85E5519337FD3865BAE9CBFF2AFC
-:106A0000F4CDF5D6C26BD02EB67630DAAF14CC36D4
-:106A100006719F6CFD84D17C9F74433CE5E71A5B53
-:106A20009F409BEFAD8AB9C3701DBF9E054CFCDC37
-:106A3000BCD64476EA57DF7C3311C6739DA0EBF5D4
-:106A400040E6AB800F25AA128A033CE7A92C909060
-:106A500084FE62859D88C0E3FA32398F7F97A576E0
-:106A6000C1E9A9FEB7B5ABBF6B7AC4CFCFAEFE8488
-:106A700029ED2FC0708E90A3E2667E4E51355A09E3
-:106A800066D3FC6B558B22F6098F99B99D7164CA48
-:106A90003563907E05738725907CD70EA17D609528
-:106AA000D05B9D017702EAF3CEE61CDAF7751E5A39
-:106AB000ECF045D15F07849C3D2FCE59DAED4AAD0D
-:106AC00011E4BD9D7590DD12B0DBA2FADDEACC06C3
-:106AD00061EF08BEC19F11FA2F1172380F9A26E498
-:106AE00045F06DF6551FA8CEEE7CC0BF1311FB8696
-:106AF0007F94BE28D748DF03B6D6694551FC338F53
-:106B00000A7D7DD9B35F98719D9BD25CA0221DA7A1
-:106B1000D88D92BF63BB365F87B2A188D765CF2E71
-:106B2000BF630CC871D521A3C706E3AB6AFEC8ECEE
-:106B30008BB27FD3D313E1A3FDD86AE6F6F15153AC
-:106B4000D152A4EBD16BF979EE9FCC9E8A6878CEB6
-:106B5000B6723CE7B1A24F472BFF7AF42D98EB08B1
-:106B60004D027A74DAF9FDE4EEF2C7E77DA74B092E
-:106B7000AE55500E8D3C9FCCEFFF4E63BE3B262A98
-:106B800034DF2F8FD45F054DC58FE17D96CA66C572
-:106B90006580F24AB5D58C725CD5B45B45BBFC0709
-:106BA0006EFECE82A9D5C36647F8B75ACDDC9F7476
-:106BB000E06FD7CD47FA7E3CDBC2102FEFD08F9C21
-:106BC000B8DE7FDC3C8AE641AC71FDC1EFB9660AF4
-:106BD000FAE3CD5C9FE9E5615A72BC94BF7632EB73
-:106BE00087E7BC97595A6FF244E1DF3A0B9FA7BD84
-:106BF000D66FD6FF61FA6D22E8372ED7A648FD364C
-:106C0000DDC2E53E42BFA545D36FABD6BAD3502E09
-:106C100056EDCD4943BEAE3ABC34259A7E7B41EC5D
-:106C20006B0F8B7BD2EDFD40BF8D88D06FFD40BFD9
-:106C300045F1838FB66876670FFACDFADF33FF5ED2
-:106C400040FD1665BC5708B9D3F45B61F35AD26FA7
-:106C500085FD8CD27DA4CB2CC28E8BA9DF16DE7372
-:106C60002DE54D9EF828F2837445FD7658E839EC01
-:106C700007F5DCCF2CDF4ECFCDB3727C7BD473FF16
-:106C80004D74D6F4DCAAFE0AD92FDDE590EBB95598
-:106C9000595CCFADDACBF5DCAA415CCFE9F5DBA4DA
-:106CA0006EFA8DB7AFCC85F6B44FCCBAEF06BCCF39
-:106CB0005762F258A1FE0CB7F6BEA07A4CA4BEFBF8
-:106CC000992586BEF380BEB3F7ACEF5E417DA792F7
-:106CD0001E1B88F3482F1FD307C64BF7D58E7E7136
-:106CE000EA37BFC5F9F20723DD077ADDC0F743FBBA
-:106CF000BE38350AE7DDCB880FCC979D42FEDAFC23
-:106D000063499F4E1ECAE77BC5A1385A272A1B1527
-:106D10003EDE5B94A01BD781BF7D4EFBE4F97BF97F
-:106D20003E79AE85D383FDD8C8DF4500091646C835
-:106D300043C9E7E5E4E72B519915EDD70587A67F11
-:106D40008076EB82CF6BC8DE5D80DFF17EC5EED64C
-:106D50000D99D0EFFCE50AED3798B80FA1DD97B893
-:106D6000BE793FDD5FD1DF83D0F4F9FC6AF9FB0225
-:106D70009D5D7F408C13EC59A20B7BC518D53F77E6
-:106D8000404F0F0F1F7FC56A6E1F87E901F4712BFB
-:106D9000DDE9011C9DB130B56BFCF39F8471257753
-:106DA0008D4BA3877E7CDAFE6481981BB1C6ABD184
-:106DB000AFDB78357AEAC6FDBC45D84517B36138F4
-:106DC000CF5E37F8EE188372F17B183FE03367DE51
-:106DD000A0B4483DFCA2D0E757F98E4F497523BDBA
-:106DE000F8FBBBEBCA763F9F0AE3B8DA9B9587575F
-:106DF00011AEFD9BD9877E8403B60ED26B9A5C5D83
-:106E000068E572FE7701E7685FD7145A3F9A141756
-:106E1000CD97904E6F897B6155404F9C8F554D6249
-:106E2000BD0179C3F9364D5B7F90FEF09F573573F6
-:106E3000FA57552B44FF99ACE320D2B73259F1846D
-:106E400000D4B4A6DDB7E13DAA176CF01DE76D993B
-:106E5000E2D9CEC961CF488D2A976A34B964D54347
-:106E6000C8AFA0AD830BB05E12BE17793D05ED1320
-:106E7000BDBD7199A5E528E271D98F4D6C1BEB6EF4
-:106E80007F68FCCE857FDF44BBCFD383FC0E12F638
-:106E9000E50B486F3BD2B5C38C725F15E2EB8656AB
-:106EA0005EA5BAA7107D347A37C1BA309AD31BDFFA
-:106EB0007DE9E979B5964779C6FACD8A09DB5F099C
-:106EC0007CE80345930D5F1CD4E417DF89E9E98270
-:106ED000FBFF8C88F98E7A29F2DCB1B2E908D16522
-:106EE000FA6A30AB22E88EFAEA7CF4E9361F9AF6A9
-:106EF00047BD07F56DE7C38556793EECB375BC38E1
-:106F000002FD5B7B15D207AC3951DADF5F61E5FB2F
-:106F1000A603361FC96DC76113DDF7D6EB8DB182AD
-:106F2000FEB89F887C0737190782E7BB2E1B7B576B
-:106F3000C3239BCB4FA4BE7EC1E6233EC5823F4DFB
-:106F4000C08F652F85F1C5FEF03CC52DF7A75F2FDB
-:106F5000343F4F4FE3BA46ACF7DF755CE1F349D6F7
-:106F60006266DC9FBFDB1C71CE3447F8F9353F58B1
-:106F700044BD999631B1EBA1BF2504E37E61D743AF
-:106F8000E4D73DF7E8F19928B72B7E676456E073A4
-:106F9000DB2E070BF17B14665C57CB1B8D51CF4565
-:106FA000185B4FF8ADF8AD83F44AF91E4B7006B488
-:106FB0002F7FEADDE1E89F6A5BC7F54BE051211FB7
-:106FC00081D6E1785E5EAEF2F3623DBC1F0B79398B
-:106FD000FB747C09EA47A59EBFEB2C6F986BB2440B
-:106FE000ECCB2BF1C08DD7A37BC8814714F28377FC
-:106FF000C76F2DAFF708D77BE54DA620BE0F2DAF8D
-:10700000DF46FBD9AAFA8FCC68C74DFEED63644713
-:10701000543519653F61BD3164213FA6F138A67A28
-:107020007F5D656305CDC7CA06E10FD3F98B56FCBA
-:1070300076EF530120CD8A277EED443D73A665A7E8
-:1070400093FC70F5DCCFA6DAD5E87EB89EFC6F0D18
-:107050009BA2FADFCEE07FC0FCDB6A95FD6FACBE81
-:107060004FAFCEC1573CF6E983782E7476CF870FA9
-:1070700022DE2BBFFEF8C19FA27DB2CFE6C2F5AEE5
-:10708000EAD1A3E457D7DA3D25E655DB23BF7EF8E6
-:1070900001987F6D6F58E8FE55DBDEF707B8619CFD
-:1070A0006DBBBF4845FFE5EABD5369DFB2FAC9C908
-:1070B00069E7BB47827219ECC579889E0F071A8D64
-:1070C0000CDF419E3B66213B23EC476DA8E07E69C7
-:1070D000B7F09FEE8A7EEEA4F9FD2A1BAFB9FA52F3
-:1070E0005CF71A4D1E377D177EC09EFCA6AF023F8F
-:1070F00047F4826FBB845F5CC7B773F81FC09F3FC4
-:1071000059657FF3A78D4B7FF5009635F689E937F2
-:107110000DF5825EDAB9D636ABF71D2BCE873DBFB3
-:1071200021FF34F20B6C6ED6F6D8A703D0DF70DAED
-:10713000D47123DDBFD86BA17B42E57B5FA7F9D17A
-:10714000F6E4113A2F62E25CA98D85FFF83980D808
-:10715000CB54ED70707FABA03BFA63DD4EFA2EFC92
-:10716000AE5C6E357F6C2C3F6C1F9BB8072ECED962
-:107170002A76BC65663ABFB63216F9745C3A17D403
-:10718000C6AD87E7423A5C12799E10CBCF2DF468EA
-:10719000984FFC1CA16D9B385F089F1B30D62F0FAA
-:1071A000EFBFF3F3EEAAA0F23A8B321FB5F304A7B8
-:1071B0004D371F83BD3B47E819DFEF460FC5C6F7C4
-:1071C000AD1A5DCE7E155D1F0FB129E2FD812FD76F
-:1071D00016B1EE2C10EB4925D08BBF27E3F89E1596
-:1071E000FBBBB38F1A83B80FDED07080F4AA7E5E2B
-:1071F00057B2E8F143C6DBB83EA96CDA3F1CF5CFC5
-:10720000D9679F26B9ABDC75DC1C003807EB9F30D3
-:10721000B70EED9273D4D7C1087D7DF6F1FDC3F9A9
-:107220003907DF47EAE15F21E05735CBF0AB767DE8
-:1072300024C15F116830BBEC3DF77346F5CEC5F154
-:107240009E6931515C94330DC6C268F14A86622052
-:10725000A9942E3A6D70F0F771C62433D991AB1D05
-:10726000638F2524636A76E33E7AFD5A7E1F72FDA2
-:10727000CF3CE9C897F58973E81CA856474757B231
-:10728000AB00F7D7AE2945A351ACF47A20D16B906F
-:10729000F05EED284CC3F7DCB70A7B84A91E7ABFE9
-:1072A00067744E2BC471185D06972DEA3ACAE199AE
-:1072B000EC45142FC2E492DFD37DEFF11FDCFDE437
-:1072C000F80F817EFF68FC07467130FEDFC77F083C
-:1072D000603FFF02F11F42E4B7D1E23F247FCFF1CC
-:1072E0001FD63239FE83E06738FE83E0E7FFC67FB2
-:1072F000F8FF2BFE8331EEEF53303E8316FF21253E
-:10730000CE3C3532FEC38571095323E33F8C8B4B52
-:107310009F1A19FFE10771595323E33FCC8FBB68D4
-:107320006A64FC87AAB8515323E33FAC8D9B48792C
-:107330002DFEC3DD7153A7CAF11F664E9D02F9B63B
-:1073400038DFDF71BD8A15FFE13D9C2C637A8EFF2B
-:107350000070CC716362C77FD0C38915FF01E02440
-:10736000109C18F11FBAE11323FE03C049273831DE
-:10737000E23F74C32746FC078093457062C47FD008
-:10738000C38915FF01E05C1497123BFE831E4EACCF
-:10739000F80F006714E11323FE43377C62C47F00BB
-:1073A0003813094E8CF80FDDF08911FF01E04CA570
-:1073B00071C588FFA087132BFE03C09949F8C488C4
-:1073C000FFA087132BFE03C0994BF8C488FFD00D94
-:1073D0009F18F11F008E8FF08911FFA11B3E31E233
-:1073E0003F009CE5042746FC073D9C58F11F00CE5A
-:1073F0002A821323FE831E4EACF80F00E7A7042752
-:1074000046FC876EF8C488FF00706E253831E23F75
-:1074100074C32746FC07807307C18911FF410F27FA
-:1074200056FC0780732FC18911FF410F2756FC07B7
-:1074300080F32B821323FE43377C62C47F0038F530
-:10744000248731E23F74C3E7BBC67FB085062A3983
-:1074500014FF81E24486E33F247FEBF80FCD88EFF1
-:10746000FFC67FF89F19FFE166BBEFEB38F2837E22
-:10747000B7F80FB6F86F17FFE1667B517C3CEE2F33
-:10748000BF65FC87D4F86F17FF01FA498F1F13BB44
-:107490009F58F11F7274FDF414FF01FA1974DEF1A4
-:1074A000C488FFE0D1D1EDFB8AFFF045DCF9E33F72
-:1074B000FCCBC559806D0A9EFF149328B27F99B802
-:1074C0000BD7C6FF93E32E90B1F0AF1477417BBF8B
-:1074D000DF60C2F5EA4DC1F7D7845CBC25E22F1C02
-:1074E0008B197F217815F94597CBF117A60B3ECE66
-:1074F000F3C9F2309DF1F386E953B278BCCC325D2A
-:10750000FC855CF9FC7A86EFC81400C7AEF2C8E3CC
-:107510003822E46166C947CF217BAE1E1B3DFEC207
-:107520002CC18F621D5DA60BBE158BF47A7C920276
-:10753000F23CA3EC888A749DE96E55C9AFFD038DBA
-:107540007F6E897FB3055C3DBEB304FF665DC9F9FC
-:10755000A7C7FB55E49F13D2B251C43F3DDE7A3C2E
-:10756000F5FC6791FC8E889B51C0E4B80B93AD721B
-:10757000DC85A92E39EEC215E972DC852BDD72DCC3
-:10758000851FE4CA7117AEF2C87117AE1E2BC75D16
-:1075900028F6AED5C57DD8A48BFB70972EEEC3FD23
-:1075A000BAB80FDB74711F1ED1C57DD8AD8BFBF04F
-:1075B000B42EEEC37E29BFB8E6B0547F69ED112921
-:1075C000BFACEE0DA9FEF2E071A97C45FD07527932
-:1075D00045C34752BEAAE90BA97E6FE33EBC2ADE33
-:1075E00003BF26DE031F13EF81DF8C11F7E1AF3FEE
-:1075F000FFE2B6C8F7F85FFEFC9BDBF03DBE41BC86
-:10760000838D15F7215C1E23EE4357FB6F1FF72177
-:1076100025F99FFF0E3FC7CECF3727C44FCAB1A76A
-:107620007CF777F8D716C9EF99E796C8EF9973EC0E
-:107630005C9FCFF3C9EF9AAF2F93DF3597D97CD9F1
-:1076400088873EEEC384786F8E1DF5A5789F1FC294
-:10765000F7A9B0363E8BEF53217D0EE33E407A1002
-:10766000E33E407A08E33E40FA7B8CFB00E94B188E
-:10767000F701D29731EE838A712302226E448D88FE
-:107680001B512BE246D489B811411137A25EC48D3B
-:10769000681071239A44DC8810C139E13F44E949FC
-:1076A0007F0BA5A7FCC7283DED6FA5F48CFF34A583
-:1076B00067FD1D94B6F93FA7B4B7712334B9FC3305
-:1076C000DA0D66EC9FCBB126A733EC033744CA69C9
-:1076D00091FDA20D28A7B1E245CC459AA6C48E170C
-:1076E000112E8F112FA2AB7DEC781169A3BFBF784B
-:1076F00011FF16CFE5F51F8D1731BF5A8E67B060A9
-:10770000CDF9E34594D98A56A35C6AF2F86FF1FC8F
-:10771000BCAAA77811DBEC8A58AF812E6877015D8F
-:1077200068BDEEE1BDFD738E8773713FD1997BD14A
-:1077300079E31CE8E52236BD795C83EBBEE73811BE
-:107740003DD155ABFF66398F5FF06FF1E78F5FD0AA
-:107750002D4E444FF105067D467AB2B771227A5A12
-:10776000177AA2E7ACEF394E444F7AB5277DFAC7B6
-:10777000E99CCE13E2CF1F8F231C17CEDA72901A2A
-:10778000BBBC34B555F10EBC60B68BFC27EDBBC459
-:10779000BD312F73BB52F93B75B437DBF7240C674F
-:1077A000F47EDDC5BCC09F78F15DD9B57F3F9EA753
-:1077B000DFEA64DEC4248A07EF36E6E03E6CA415F7
-:1077C000FD29158D1FBDFC3B806B6B36D27DB276DB
-:1077D000C0A185EC3E6F22F22D9EDD4EFB743CE392
-:1077E000FAA64FE47B66DDEF37609588F39BA946E8
-:1077F0003BED9B3AB7F27B9E4676F17D1347D37DF6
-:107800006A167413FFC84E5D21F0ECC414EBFBAC98
-:10781000643F2E3BFC447E88F1F3CA48BF419F423F
-:10782000D94F5367730EC777952CE06D41FB7B8969
-:1078300080975224FB6F3E5C547808CFE997F84A52
-:10784000E91E425A89ECCF61E2DD386EC7C2F7E526
-:10785000009FD226853DA0747F475ED67CD706DC8C
-:10786000E72C0FEAED6F968B7256CEE23CB8EF5DD7
-:10787000512F973B1CE23E879DD97B45B7D60BEF36
-:107880009B987C5EBA7942587F9783EEC32E3BBCAF
-:10789000D88CCCB2A4CB74B3B965BAC5E7CAF4D15D
-:1078A000D3CFE191E9A3A75FC258D9FFA5D14FBBC0
-:1078B0006FA832715F34C8EF91767B87DFB48DF0AB
-:1078C000D4D34F4FAF510E714FA28B5E45D6545259
-:1078D000F98467861A22F9D6CF874C7B48C1FFEE20
-:1078E0009F1C5C4BAD3C0E15F5563A07CD9425BC5C
-:1078F0005D3CCE078C2BCB3C341F70478FFEDD7870
-:10790000F66721F7EFB26F20BDA9F8B9E38BA07439
-:107910002BCADB08FEFB0BE4AFD27E3781795CB863
-:107920008F6AF05BDD4B543C1764EE2503F13CD0CD
-:1079300045E99DE2DD6FFB5046FBFE86D027A97826
-:107940008E76675EC74CF43F542D6545B87EFDC802
-:10795000C9DF5D6C12E90827F7CF6C2E3230EF6873
-:10796000FC1D1E635041BFABCB7BF872B4479B4DEF
-:107970006E7A47ECEA78F97A2A1F45EFA3330CB503
-:1079800023111FA84FEF6BDB9BDF752E8ED0C36DCD
-:107990004D770FC1FBC5F71BA2BFEB2D7568EFDB61
-:1079A000F8FD8E115D71064A1D63281EC19DD9D058
-:1079B0004F657127F15193CB0982FECF954E27FC7D
-:1079C0009E6C56DCE8AF9B66BCE107C300BF714705
-:1079D00055AEBFC4BDEED1A2FED3CC938EF88EBB04
-:1079E0009429387FC6BDC13C0124717529DDA7FBF0
-:1079F0009D73DA21E4D7946690279C0F67ED1EBC37
-:107A00002A3FA645BE2F9738C57700EF175E728CC8
-:107A1000913EBBE498AABF1F63C4FDFEB856F9FBB4
-:107A200004DDFE739D26774E968A72B7E52B23E11F
-:107A3000D5DEC13CEB006EFB92BE746EDBFE09230B
-:107A40003BB1FD2B6361B4FB25773BB8DFEB7E33A5
-:107A500023FD7D7FA99DDE393C5B5A7E01DA179FAD
-:107A6000FDC47741343F65849D96C0DF9F7B13D86A
-:107A70005894C35B154EEFDA8CA228EB9626779AC2
-:107A80001C6AF297511AE78B765F33D9C9EDA34987
-:107A9000A5B98A19E5679FC290AE6DEB00AFF3AC54
-:107AA000DB01B62E13F1A96AFA98EE61599B95A8ED
-:107AB000BFCBF384C3C9EF03AE0BACC5FB1737C311
-:107AC00024423D9561AECD8A063FC0B6905DFA80F6
-:107AD000C3CDDF0D58451C21B53603EF23B4354D1A
-:107AE000BE7203E0F900CC07E4EFFD260FE11DA80C
-:107AF000608CEE930A7F5DBF996CDBE608FB77AF85
-:107B0000A3E030CAED6107B71BFBF83C0AE2EDF9D0
-:107B1000FB5F9D08BFFD730BF1AFAFB037B57627A4
-:107B20001D9C3E254EEF016CCFCA9249F9787C4EE0
-:107B3000F7923EE837077A47B1AFB4753DC9C7E859
-:107B40007C22C96E089272F27ADD2EE9BE7780E659
-:107B50008D360F584861F85E5FD36F4AB31272805A
-:107B6000DC8FB6DA4378FF2CA90CC69D8CF13CACB7
-:107B70001C5E8B7A56F66B813CE6A371CFE8BD3F65
-:107B80003A5211BEA6F7347D796B22D747B7DEA5EE
-:107B9000523CD0AD6AAB0DFDA9595EF7240C4D9354
-:107BA000A4BAE95E4AFF323E0FE3737E9918B6032A
-:107BB00060928FFCDAB820DA7BA60C94A714A49705
-:107BC000EF4307A4C30F753C8BE682C7C6FAF0FBF0
-:107BD00053424F08BB669A58EFC6BD67E0EF284393
-:107BE00097B3C8F7457A3D0172FF27FCFD9EFBDF86
-:107BF00053294E68583F944EA3F58919871E403982
-:107C00009BF022E3C751423FB8E01FD2E792977C36
-:107C1000EB118DEFAA17F4FC66216B388F3FCD3640
-:107C2000EA10CCB7C875D629D67BA1476E2A1EB8F4
-:107C30001EE797264717DCE231FA22E8A86F1FF605
-:107C4000532AD6F077770EEA91978C783FACBD0037
-:107C5000F80D747912E70BD03BF193E095C8F72D3E
-:107C6000CD57D850BE6F0D4D72CD803689D6226269
-:107C70005E22F3923F270FA8837122D69350C07ED5
-:107C80005D2DCA72A6E03DAE42C9DFA3FD2E1E0CDB
-:107C900094F812E603C871E43D564D3EF5F2A8C9CA
-:107CA000EF7ADC60E1F91D7ACC21352A0DC4200B76
-:107CB000DBEA423DABD997EBC3F65C22ED33560BC2
-:107CC000BB68BD7D9A95D4C0FE645ACF57E3FA04D1
-:107CD000E35F9DC2681E68E3D0CB63D5E706168CD0
-:107CE000D81F54A91D748FAFEA73330BF6C171FB13
-:107CF00026E1B835BA8C1474D1D321DB29F69B82E6
-:107D00001EB1F1CC77E1FDD944AB976D243C27D16E
-:107D10003DE786509E15D7DBDB7478F602BF39D17C
-:107D2000F053ED31F013F1DB2630DFEF5A415EF313
-:107D30006FAACBE0EB057B353D827FFA7933B6A99C
-:107D4000FA803962BE687E5DFD3C19D1CCAE41BA85
-:107D50008F0BA90CCF5F7B9A2F9F88F156C5737A42
-:107D6000B5CFE9188CF2B943F5553BC9BE6835600B
-:107D7000DCDFF6A719CD67CFFE934E8A6FD4D2BB56
-:107D8000FBE99A1DA5D94FFA7A9AFDA4E95DED7E2B
-:107D9000F876A7CF8FFD2B4D209F30FEF52EBE2FFE
-:107DA000DAEBF0ADC3EFF130063C4A62B9A12CFE2C
-:107DB000FE5596FF58F21EAF93E706A013FD4E1630
-:107DC000E8FF414A773CB4FEA73813F9790BCC663B
-:107DD000D443FDF219EFAC92D1FDC97EC3990FD700
-:107DE000A77E79FCDE5F50ACDBDB84BED5D2BD8ED6
-:107DF000A2FB117F93CA0296BCEF8E37A28AF7B11D
-:107E0000B73BBDF7A1FC590BBD348E4C17F3A0FD59
-:107E100099A93628F86E3269A55BE1F7B059D73BCE
-:107E200026809739C35D80729289FB68ACDF1C3D68
-:107E30008ED6134E9364677A58384ED513D82FD800
-:107E40009907CD80779F195ADC2BEDDCC6A3209DC6
-:107E5000DA1C7308E9B64F156E8F27727AE9F703BB
-:107E60004878C44F15F9DBCC4CB525B1AEDFE13411
-:107E700058C98E8F679E06D44B2F3BB3C5B9A8A7B0
-:107E800006F3FFAE7658138776C9F19D13677954D0
-:107E9000A8E2BCB47338EE99409E0F23BE6D133B2D
-:107EA00007DF4AC4E818C0E5C66B94E2E268F46FE5
-:107EB0003249F4B7E13E3B520F3ACCB48F6C53E2F7
-:107EC0003C38CFDA962B1C4FC52AE206A9F2FE5F9A
-:107ED000E8234DBF763AB308FF7816A07D00B37A49
-:107EE000AC748F5DE08F7115C9AFB3373EB81DCF4D
-:107EF000A3747114F57116272FB6D3BD8B2D7B6D2E
-:107F0000B42FED2CE2E7F39DCD16D2BFB1E6691A8E
-:107F10002A83F3C40B04BA7520DDD24CD589A8F7A7
-:107F2000D2E6F3F9AFA7473B0E14F73B7F3005A32A
-:107F3000BD57D7D2F4F4BEC56897A567A453AA7DF0
-:107F4000AFB3AB51EF611B1314294EDF10E851ECB6
-:107F5000738C09F0FD9CEF8FAF7959D7BDF6BA3815
-:107F60004EBF4EDFF8848751AE40E0E8F704B473AB
-:107F70004DB19FD7E22769FD6CF15B8B31E467DD82
-:107F8000A2E9365C075298F7CA793829B798D84ED3
-:107F90006A972BDD77BDD73FB218DF276726F07BC6
-:107FA000B49F6C994AEF9953D93ADB60A043699129
-:107FB000C183FE80738BDE741A407E1665B6E4A31F
-:107FC0009C26987C990963C87545FB8D6525E660FC
-:107FD00008E8955C070A81E818B892E8B8D010D58F
-:107FE0003F9C9DC0F79D6F89F5243D7D40F19251E6
-:107FF00091F97E44574D8E60FE642C19DD150F13E8
-:10800000F87951429479D06E624DF85E42D347C9F7
-:1080100042CC347DA8C97132CE0FB4E38A403F49C7
-:10802000E77D5035B5EBF70C95E617BE403BD679AA
-:10803000E924D237306F6B48CE73B9FEB4A13E8BC2
-:10804000F05BB5EF7DBD3FBE637AFB671F3BF05D24
-:10805000CB5FD40E07EAAFD3B7FCC98171C0DEBED7
-:1080600085EF936FD4D9FF5709F90826144D41BA0B
-:108070002EF0FF3D3FD25E636BB8FF7979507EBF33
-:108080008AF7BF23FD80150DFAFB00011EA74CFCEB
-:108090003EA79E0FEB041F96EFDA66CE7463FFBE19
-:1080A00039D8FF69B1BF39DDE8A0F7141A3E8B76E5
-:1080B0008D34A3CDFF97668B78A7D762E27AD93B40
-:1080C00003DFE7F804DDF4781EDC174FF096DEC31B
-:1080D000DFAF2E84BED6805EF435F3384AFA712CB9
-:1080E0007DDB3D0DFDE84B3729B48FC3FAB7C03AAD
-:1080F000E15BB391DEF1E8C7B93020FB73F4F11A0C
-:10810000B5FDC032C1FF25F86BBC3951E23836F3FA
-:10811000F774CB74F645E7A19C781CFF9A0461675D
-:10812000E7B34B306EE79E43D909D1E26168E95964
-:1081300071DE8FF7FA313DED67944E4970F3785D4B
-:10814000CD476E46B9AA6CDA4DF111F705DFEB3376
-:108150001EAA14347F6144A12A10F6D87C618FEDE9
-:10816000615C6EC08EDE8CF27FF9E73A3B5A8CF38D
-:10817000064DEE0F2591DCDC80E31A8EDFD54FA291
-:108180008DEBEE04F9FD576FC7A58D471B9F565E1B
-:1081900021DE9FEBDB69723E45C8DD921DC51BFAEF
-:1081A0000229D6EF7D7F8088234771B63439D2CB40
-:1081B000C932C1B7B03C34DF41E3D2F806F29E2E9B
-:1081C000DE25A5A33FA327B9D0F3BFCDD43A00E75E
-:1081D000AB9EFF6D31CE7DB627F0738D256EEF34EB
-:1081E000F4AF8079B8C115613F9C566B0FFE14E760
-:1081F000D10E2EC791EB22194B2F9A689D5DE57029
-:10820000A725DA05DFC6E1FB454B00EB69FD9CF2D3
-:10821000D7CC1A48E78DB5B3060EA4771B946AE550
-:10822000A5F77FEC44FBB43D97917FA1CD21E37B83
-:1082300004179B319872FAAF545BBE7E0B75D08EDB
-:10824000168ADF7AEA2BE19FF8CA52186D9C6713F1
-:10825000B81DA8DD3FB951CCA31B9BF97BBB455B87
-:108260008BCDE4075823DFD77849714DCB84A6BE68
-:10827000869166E4B39E1F4B3D57D03BF06E7C6108
-:10828000B7135F97EADFB5897B4C0B847CCC74B95C
-:10829000859DE6A377C44BEA8C64DF2F7357D3FE2A
-:1082A00066851AFD3DD61897E1BCE3D18F6361A3C3
-:1082B000427A4F8FFFB21D6B37F465387E3EBEEEBB
-:1082C000E308F5233D23C6C95A2FE7EF32C5BAFDAF
-:1082D0005F995EED8C008000000000001F8B08009D
-:1082E00000000000000BB57C0D7854D5B5E83E7356
-:1082F000CEFC24334926FF21413C21111212E29089
-:1083000084000171F24BC4080301826075405184FE
-:1083100090207A5BEFABB79990682DFA7AA358CB8F
-:108320006DEDFD062BAD0A4880A08126E9041403FB
-:10833000040D820A96D68014B1053280B5587D8F1F
-:10834000B7D6DAFB64664E92426F5F87D69D7DCECC
-:108350003EFBACBDFED7DA6B9F65ECD94B720E636A
-:108360000FB7CB8CE53356FBACEC65A98C2D63CAFB
-:10837000E9BE0C46BF6BA9F85F67E59204C6EEC57F
-:108380003F5568DB57553278AE5CAE9985CFF56FB7
-:1083900090995982EB1EEF53C971D036498E461819
-:1083A000C71E379EEEB33066817FD746D33C8C25FF
-:1083B000E0FCFCD723B1A75260FEB38AFFBD08786A
-:1083C000EE2CC0E181799678F873F47EF8FF32C71D
-:1083D0008C2F2478DFFDEDF229730E5E5D6D32C0C7
-:1083E000F8A52F496C1D8CBFFF69DD78B12EFD3AD1
-:1083F0001EDAF0A3B9E91981710F7B9F0BE9C3DA8B
-:108400005456C0D87D023EF6EA7F05EE73F84DAEB5
-:1084100008C632ED117167B3A05BC0265D4B63AC3B
-:10842000CE1A99C3A2A03533C2233B64F46E02B8BE
-:10843000D644C08201CE355BA3BD1EC4E3EA68C644
-:1084400046C0B8F68D26B70DE6C4DFED8C9DAB6F48
-:108450009E9B9E0EEBAF7F7A6EBAC2D82CBB9DB1AD
-:1084600089408FB6E7685CB7E29A6487FE2A4BDFE3
-:108470008FEF5683F03899D363995C696286C07C2C
-:10848000FA7659B3F1CBBEA0751621FC56F86312EB
-:10849000C02FFF3DF8D5C4685B006EFDBC7FAADF2E
-:1084A0001002F74A85395B6C81F568E326DA0DB472
-:1084B0001EFDF37A7A30E6A5717ABAAC443A04D15B
-:1084C00017E15400AF3D1D56EF5A89F888E0F67465
-:1084D0008411DC1793D6CD3D93C7D8617C00E0AE04
-:1084E0001DF132F55F515C6E7B3C5EF48F728DC77F
-:1084F0006762199B323CDE6046C6607C2ECE0FE37D
-:10850000768539F3988CD75DB1C807D31BFAAA2CAE
-:1085100040AA3AFBA40A05DE33FDB9BEAA30E83F03
-:10852000629FCCFB9BFA8E5A1C8C35B02915A5F0A6
-:10853000FC63700FE7BB5E9B6F762D66C05735807E
-:10854000534B0CB4C7C6BC8DF256D35B5921454280
-:10855000CB984FCA057E7046FAAC39D4678530AEE9
-:1085600033CAFD1FB8BE55579B2EC938EE98C2E5D9
-:10857000A53B8EF0A000EC61F05C53B853B503BE90
-:108580009A622C8EC654BAEE098BC1BE535583AE87
-:108590006BF4C0E7108E2603734643DB75604C54C2
-:1085A0005FF6F078EBAA57AB14A0FFBEFA0C6AF5A1
-:1085B000F78B4CF674073C5F6460EE16DBE0FBAFB4
-:1085C00022BF109DD414A4736DB789E41C7F12F0F0
-:1085D000FD2AA1876A81405100CFAA63CC171E896A
-:1085E000E3CABF50B06D95D8E910BE6281BE3C3C75
-:1085F000DC37DAD6E27C4A309F703C152BA9554A0D
-:10860000D07B4B6D99217D39D19081EB6172B8633C
-:1086100013E0574E31ACDE01EB976F8616F0A1D810
-:108620001DF212689B4BA6CB4BA16D34B2852DD8A1
-:108630001AD8F2603C750879D2DA4B76D76F90EE93
-:1086400017DEEF2DB0929E1A6927F916EB6D941C78
-:108650003ED4439E2EE6D804D79A6417E37CDCC24E
-:10866000908F7F2FE671980D3B55E0D7F7EC0F12F6
-:10867000FF3AA20C8FA642FFA3E615150AF0AF231E
-:10868000C570251578F478F34ADECF325C190DFDFC
-:108690004F9A6B787F2A4C99CCD8C9E655159E6CB9
-:1086A0009C97EB31B6C59985EF510C12C9A9B2D789
-:1086B000E46D843F9B22393F3519812F6370BC4A9A
-:1086C000E39F6A28DE6C05FE578A9DEA6A1BC73560
-:1086D000F2C3FFB4D5F0285B0DAB118FD822BECF0B
-:1086E00088756B7460ADCEAC39A8175A9C5973234A
-:1086F00010AFEECF11AF793DBDD3510FB77EF0492A
-:10870000813B9BD30BE7C9EB612C12D673E1AD9B88
-:1087100036CA52803E97EC45E7515F4BA0A61F87B3
-:108720007549AA9DDD0372D7E864AA09D695C85E8B
-:10873000B2A3FD30207D4005B532AE5F3AA35C5F49
-:10874000E2736CA48FEC4CB5DDF515BE5FD3CFACF6
-:108750003766483DACD757A69CC765067C1093D2B8
-:10876000767C29EAF3DF9A1DB7A8088F933D0E7037
-:108770006C333085C5107B642870DFCAC21DEB5096
-:10878000DE1D2CC903F2856823E0E01707F6D02828
-:1087900064485B073C5FCAA09D8470DD4AEB929100
-:1087A0009F2630978C7AAB8079ADD8F677BC9584CC
-:1087B000F87A3E8CDDE782D6F22A737A83F4467E1D
-:1087C000B444F89F1563A436DCD83217F934FC1290
-:1087D000B3A31FD0FF0B9382F38360DC89D71DFB0B
-:1087E0000D0CE1FCB5D16B8F82BE3F53515F6681AA
-:1087F000F9FA059DB5799F37A999D1D0AF8A91082B
-:108800002FBF2EE2F6D8FF85C9FB722AE2C7B2DA83
-:108810001B2457E3A3F9B8BAB8E2B1D1F07C4B47B7
-:1088200038C3F74FEA0C3720FE376FC90D433ED8E7
-:1088300086B881F5C798ED8FE07C315700DE54BAD9
-:10884000EE24BC2AEA8428C06BE14C9BBA0EF0FEF1
-:10885000EBB09699C8F7FEAD06F632BC629BC93103
-:1088600007FBDB2EAB76D4B3BF4E6D09A7F56C3595
-:10887000D07AB685FBC7AD01B8D7652815089F62C9
-:10888000650AEA5FC550AC3E02D7A74573FDA8E96B
-:10889000E39A6895FACF4BF0FE5C1C57447253265E
-:1088A000DB48DEFAFDCC6B86F7C4CFEB95911EE179
-:1088B00073809590DF159FCC703E17121A5A9BD18A
-:1088C000AB929E75DA9600DDA70B3D3BFD644D250E
-:1088D0008BC48EE3D854986F9FCDC8705DB7B13EFE
-:1088E000D902FDDBAE32870FF9E7AA427E981DFE62
-:1088F00005FB7B65629E5F494C898271455FAA0AD0
-:10890000F257110BF5DBCA36947F81F6ADC4A2BBDA
-:108910008EFE5C24B64AE03ACCB3285AF861A3D85C
-:10892000A86BA4CF60D6046147555C7FF67FE1BA9F
-:10893000FA2B4C0E5CFF769BF3E3A9A8077B8D6CAA
-:10894000131B5E8E7E550F1A7D0C08C7D570E68D01
-:10895000253EB421FDC76D68F684C17AC7A5F3F939
-:1089600091DF506F8CFD455C2CEAED8868AE4FB40A
-:1089700056E32FE4237B14E723FBAD01F9FB5E7480
-:108980002A8DD3E409F90BE7D963F42E760D61172C
-:10899000812FBF877CB9DDC62A90CF9F1961598886
-:1089A000F2A4BD67B7E07B7DFB54C39A2E23AEFBD8
-:1089B0002FA0FF01EED2E4ABA660FBDD15C7E12DD1
-:1089C00093BF25BFFA62BB44FE7C423BD7D7C17C34
-:1089D000316268BE7801F17A3DBED0C7011A5FEC02
-:1089E000B81E5F74FF637CF18B68E1DF0ECB17DF8D
-:1089F00046E2FA1FEB2849647FC78F69137C30DC9D
-:108A0000FD2956AED7F4D7DB053E779B9AEFCC41D4
-:108A1000B9BFCBE040B906AAA7CC05FBB23B9C3F4F
-:108A2000C794D569D8DFAE703DB2BDDD4C7A64BB6A
-:108A3000CDED267B9D6461E82730C5DDF77DD47FD1
-:108A4000C916755D10DF3E2EF4408BD137E573F407
-:108A50007F0F70FA4EBE2B5736C1B8110F70B9CECA
-:108A60003F67DA28C33CD53145BE6818DF17CDED26
-:108A700062DD1918057C597BC644FAEDADCE23E5BD
-:108A80004E1BF9374EE4AF497B8E941767E378CEDF
-:108A900047DDA2D5FA53704D3164768E25017E5D97
-:108AA000C24E4C615C0FB9903F72027DE634523C7D
-:108AB000A6F1413563596827E6F639CA908DAA2A8E
-:108AC00042E95BED9B4971DFFCE3CEB20858D77CED
-:108AD00097EEBEA07FB58EFEE007FF01E564D5E608
-:108AE000DE4E1BF2ADCAED698B697516F77B56A792
-:108AF000A1FFAFC911FD004F2DBFCF78795D901D4B
-:108B00005763F83A9F752874DFD367F2DE0297FE49
-:108B100037E3CFB5087BF3AD90E3DCC7DE588CFCC0
-:108B20009BB7DCB90FF1BF284EA6EBFFC97C96348A
-:108B3000A48F4321FFABC5A8967C2E05C631C595F1
-:108B40006183FB7BE2C3F3F0FDD531EE6B4827A6D2
-:108B5000F8BBF1B94985B9792857B6094DB1687F95
-:108B600034B801AE8A4DB6001C1A5CE785FEA98EAA
-:108B700059720DF180CFA15E693B75D682CF6B74BF
-:108B80006FE9B8C4E91D447FA47780FED27DD8D7B1
-:108B9000F06011ADD6FFE7E9EF1B89F41896FE18D7
-:108BA000F747FE8FE83F2A6608FA833F958ED73550
-:108BB0007FAAC5047E7576A0AFD1BDDA5E44E31C02
-:108BC000265819FA4F9D1057A21CBAA3D1B9613B80
-:108BD000EDFC5DFDBF3F3B0A5C4036292686CB930A
-:108BE000C93F06FD8D093E89FCBE0920F0F7909F24
-:108BF0003592F49D43E0879D95A4B319DC05BF969B
-:108C000082FE9F2F16E56082B9D287FCBEC33A3D33
-:108C100005FDB75CEBB434E4A737331E3B8426E78D
-:108C2000CDE4E53B5F51037E8EA6D7F68969B5F7A3
-:108C300097C770FADF0E6A16FD3D740D83E1D0F41C
-:108C4000379205E1907CD5866B56D2C7ED7D80AF1B
-:108C5000DB110EC06B97C45A517F17199C7125E820
-:108C60008FC5FB14EED77D3D4A05BEA96C7FF73852
-:108C7000C25B69B1F930DFC21CC6F37D41F912BD98
-:108C80009FABF9259ADFAFF92D5A7C89FE0DDECF17
-:108C9000C7EB00BFDD0C00A2FDF159BC0DF0FEE7F3
-:108CA0002FAB994E21AF0AACA352AC6336EB25B87B
-:108CB000D8B7D7AE4D03FACC12F8A8EC86B8300777
-:108CC000EF337617E0E12E85C78B7739203E0CE233
-:108CD000A3D99343FBF89B9E1098E77AE3F5FA7FBC
-:108CE000AAC817FCB371A6D676831D3A0D0C70B0D6
-:108CF0009EC73485A3658F82F1803BD380FC5827C3
-:108D0000EC1A84C943DB2321AF8586BE1C07E0B77C
-:108D10006BCF3764FFF6EEF9E623F4E7A67CA130CB
-:108D2000333C5FF8457E14EA07E60A9DB7EE8FAD47
-:108D300056C6AF13FFD48AB5EFAFC78C18C267A170
-:108D4000F637E79F5F8FF37D7946E1BC2DDE5F6EDE
-:108D500072A7DB6DD8F2787FBFC4FD1DEDFE7E23C8
-:108D6000C00DD737C568717FAF42F919F89983E80C
-:108D70007C17C6FBB901BADE75AEE20B2567307D04
-:108D8000F0F7FF23DED7E2FCB744FCC0F69D30A924
-:108D900000D78CD64714F4A36724C9CC19F4DE3B62
-:108DA000542B7306C5FB6FC4E8FC907DAFAD9F05E7
-:108DB00076A4AE477684A1BCB66F3F9483FD5ED99E
-:108DC000611D828FF4F89DD1FE8882FC9F10CBE557
-:108DD000E67AEF2F1C077C722BD29D911F77B14052
-:108DE0002239D2D377EF9E9FC7F6650F8FEFE1E868
-:108DF000AFA7C36FCE1747215EAE470F3DDF76C2E8
-:108E00003A3DB03E1FACD303FED6DE7A3BF5DFAE73
-:108E10004FA2BEC6AF751DBF8C457F4DE3D3B25880
-:108E2000CE375376AF8F65B600BD347C5D1474AB1E
-:108E3000668EF9B3E0CF5D922382F48487F5261520
-:108E400004EC55F5B172F233347B552D671B51FF9D
-:108E50006AF60AD3C2A8CFF4F6697E7A9111D5AA30
-:108E6000DE2EC1028DC8BFD50B43AF57F4342B1192
-:108E7000D433109D2449E043F8D51A3C1F3217C162
-:108E8000ABA7A7069F1E2ECD9FAE1674837596E1E5
-:108E9000D2E7AA45B48E417655ACF746EDA93936EE
-:108EA00034CEBA72AEF4FD9C21F87538BED5DFD74A
-:108EB000F44039BE20975A0FFA1109B10944AFF2B4
-:108EC000AB26E6047BC14686B1CF82F3EFAF649256
-:108ED000BD7B54D8DFE1F8A6F6AA81B96303FC6331
-:108EE0006C7BCE8AFCB35B69B662DEF136DB9CC676
-:108EF00028C053E91F8BE7A15F57D76760989A2A6C
-:108F00006BBFB40FE3F6BAE3CC81FAB0B8BDAB04E3
-:108F1000F9ED6DA557A638FA4BC69E0BF20FDBDABA
-:108F20001BADE83FB5C5C914A7EF8FE6FCA8DD6F00
-:108F300089E5FCD776E6F22CE710F73F13F74B4FA5
-:108F4000E51AD148F6C74750BEA1FC6903ADBF542E
-:108F5000B25755A2FF718791FC7A885BFEF07DCCF9
-:108F600037B599B763AABEACED878FD881102DFFB6
-:108F7000E7B30633E60FE6488E97615CB9EAEFC2C5
-:108F80007EF9BC54DA8799F47F65F25FFD774B94E4
-:108F9000F7280776C17EF93DA95ECC3FEC9178DFDA
-:108FA000D3C1F3FECCEE899D05EFF9A03276C23A2B
-:108FB000E229AD7F4BEE3A261838289E7A6C17DFEF
-:108FC0003F7AAC4CA2FDA3327B0AF304F155F9D3EE
-:108FD00040CF3CE0C7F6C462E4DFAA0A997983F87F
-:108FE0007ABECBCABC41E3F7877178FC92D98BF982
-:108FF000124D5E670AFEAE5E181B327E0EE37EE205
-:1090000042D66C44F9AE13F0D415013CF0FC4C117F
-:10901000A7DEED4E09796F256641606856DC68B2BF
-:109020008FB3BFEC23B33A473E796C31BC87657090
-:10903000F9D0E4AC4CAE69223E48921C181FCF9781
-:10904000C0AB9451DF85CAD1ECC9A1FD394EBD7EBC
-:10905000089577BD1ED7E47C7E876CC4387A7E91F4
-:10906000E46043E803BD3FADD703930C8E7730AE89
-:109070009E7BD549FC35480F9CACF887F4C05B203B
-:109080005B93415E7FA4E9839BD84DA80FCAE42D72
-:10909000EB913FFAC1AE9987E00FCD2E68F176399A
-:1090A000C827F2033BCFF725CAAE829CC606E2ED85
-:1090B00001FD007E8363087FE657B16921FB490308
-:1090C000FA22C86F3016FCF37E4319F88BA65C8435
-:1090D0006F24F3E4919EA2FC1EB43ECAB3255DA2A8
-:1090E0003C4A1DC4F114CFB35F125CA8D7A498000A
-:1090F000DFEBFD092D4F3B42E409F4FC3090B79BB8
-:1091000067F4229F69FC506EE772513E4FA6FCB98E
-:109110009E3FB4F75D8F2F7C12F085F477F842C83C
-:10912000D38DF2C5218D1FD259FA8DF083C6071A4F
-:109130005FE8EDC5415DDE65387B71F23AF6E29D90
-:109140000C23E965BD9DD0ECC28138AE7FC7C7F264
-:109150007D8A9999F36DE8578C407D80FE9EB037EB
-:109160000379A30D9C0FDEE95BAA486837500FA472
-:1091700006E15DE44D35BEAB7D9A51FEB052E89FED
-:109180008B1D3C9F56572A7B2DF06749FB73EB796B
-:10919000DF48F9B622A54BB1C0BCB31D9203F3352D
-:1091A0004E917F9B75D5E455293F3FF47E7A95E03B
-:1091B0001B8C7370FC6CA7E4851074901EAABACA4D
-:1091C000EDBE5E1F5589FDF22ADD7EB9294ED0F530
-:1091D0006676F3BFD2EEC7C72570B919868EDAF36B
-:1091E0001A1D35FA4DC0B1283FFBBE36A911DC3F30
-:1091F00046FACDB8AAD03CA3E242FD962FCFE7FEB7
-:1092000027C574627C5DFB25937BFCF0F05FCF2F5C
-:10921000BD59F3C3855FAEBD7726C8780A3A863A52
-:10922000FBA1BDE7BAF6423CAFA7D3E4B8D0784281
-:10923000A387A64707E15BE8D9E1E8753D3DABE9C7
-:10924000B37FB59ED5E6D7EC80F65EBDFE1D2E3E03
-:10925000D3F4E9531B0D9417B94DC4C1B7893CEB46
-:109260008342CE970B7DDBFF178B01FDAC6D9DDC40
-:109270001F7198ED87D06F08E4F3385D9F8C601EF6
-:10928000DC2F674AAF85F62F8B81A4B87F99CCF786
-:109290002FB7283E17E96987C21A405EFE2AF216E8
-:1092A0004FEEF52C463DFDE4E93106DA47577CBD2B
-:1092B00018174FCA55683F28DAAC52BEF76287D9F3
-:1092C0008ECFF5EFFE5E9711E7F90B7360A8F67687
-:1092D0008779603F06F54299DC23635EBEDF0FBEEF
-:1092E000388C9FB6D05782F1CE6DACB711E3EA420D
-:1092F000A4E310F47B55675FF479FB920EEE27959B
-:1093000044F0BA9FE980467CEFF43613F985D7CB59
-:10931000DB177DC9C85F1A94AF6FE37A0606119F09
-:10932000DC68DEBE107D3DE0E39FE8F40E1B267F87
-:10933000BFCDC4F773FC478C0CFD5E762E6EC8BCA7
-:10934000CBF5F2F8BB3BC39D6A24EEBB71FF7C7783
-:1093500067B253CD197E7C4E9FBF18F395DBB6CC18
-:1093600055284E14F9CF41FB223AFCED9058931545
-:10937000F369ED8E528C3F86DBE728F63B69DE1BF6
-:10938000C51B63CD9CCEA27EE9762163DBCE863BF6
-:1093900091BFB79D4D76223CBB057F6AFCBEFBCCDE
-:1093A000E570DACF343955DC07F6475B1C2F13BF65
-:1093B000723E6F1931C68BFBADDB853C6C0BF71F22
-:1093C000CC8A0BDECFE0FB179DF59EAA33E9B4DF14
-:1093D0002D61BE51DB27F680BC505D4E0C237E32E2
-:1093E000B21686EF6D74B29F633B7D9A1A85F8BE04
-:1093F0001CA7ED47AA519467F8F64A816BFC60BC44
-:10940000EFA877513D496BFDC22A05607CB3DE4D64
-:109410006D5BFD726AF7D4AFA6FB6B0F453E8E768F
-:10942000BFCEB9A04A09D21B9FC5F3FC526ED6E944
-:1094300012E473F60D6318EF4C7FA24F463D71FBAB
-:1094400055584748DD887219F14CF9CBB4403F5567
-:109450005A12867C79FB55E8078D97E2A3391D9A4D
-:1094600094A65B0A485A881FC2E29D17E3E0FA0FF0
-:10947000ED2E7F5C3CF241F5BE0B8CFA97F1FA0EB3
-:10948000E96EF9028CCBF31551DE380FF3C6B9340F
-:10949000ED62C4DFC42E13ED7B6BF9DB5C31AFF3FF
-:1094A000ABD03C729EC8DBBEC9FA289F9C6F81C0BE
-:1094B000CA807071FA39A5F94912E6FBE24D0EAC8B
-:1094C000579898E6CAC37C6B573CA3FC695757C2B0
-:1094D0004815F0E054785ED7A9E575D9DFCFEB7673
-:1094E0007F1AE9217D057E0AEAA7EEA3910E1FED02
-:1094F000FF59C8FFDB810F627D4338AF1760F3E689
-:10950000511EFD760B5F07D89FF878CAFBF9F61D50
-:1095100086E77E7B99F17DC4DE93B43F5D62C84CE3
-:10952000EC0338F74963A3B07DF1D3C86C6A8F466A
-:109530009E47FC741AAC2ABEF7C37A56857567CE6F
-:10954000F76DB49F31FD7D9B82EDE1FA3EAA477B2A
-:10955000BFFE1CB547EAFDD41EADBF4AED3B701DF2
-:10956000F9E7103C8F6DEEE2087A6EC7A20813C2CD
-:10957000DB19C9B668EFC17A335FB8AF1593F9EF5D
-:10958000C57FBECE7213D83BB37BBC3481B113F11F
-:109590009FCF54A07F68C6A87FFF0BDCFFDD4F2E56
-:1095A000ACB3005CF38EDA5A7BA0FFE94F2EAEB36A
-:1095B000A19E3D140ECA0EF546FF41907496873663
-:1095C0003D9971053B19FAB1A2EFE99F590A245F51
-:1095D00050D297C580B5A6FCC43FD302785C6075B5
-:1095E000FF1BF64D9E976696DE847DE6C17A2EBF00
-:1095F00064A4F89E8D94E2B07E6599DD7D2C3EC812
-:109600007E3BA53FD2FE51815362D1714457DACFE0
-:1096100062F653B1C1F2B6CC5E760CE971473CDF1D
-:10962000BF9A384D7206D749E8C74D3CA396229D94
-:109630000ACE9537613BBB229AFAAE85939A509E2B
-:109640004B6DC33D5F42CF2F8837127F162B524898
-:109650007D887E5C1E3013FAC7FE03E1941798786C
-:10966000CCDD8875A36549A9B9B2D0798CFAD11B34
-:10967000711F6D62E587A5B1283F36C981E6A180DB
-:10968000F535C5C661FD231644E1BA9E2BC1FA9D8E
-:1096900089AAE440B41539BB5AF1F9224784A308DA
-:1096A000FDF1636A299A9CA3CA84C3F9306E46BA55
-:1096B000ECB0C044477D774CBD00FDA28C28CAE3C6
-:1096C0001629ABAF1CA67E84A341C5756CFC792D11
-:1096D000CD63267BBE6356C97F20FF14BBA228E75B
-:1096E000576A3B3537B82E0CD64D7017D9656F9831
-:1096F00084FCFD83523BF4778C9218CACF515FE60D
-:109700009FE97E77B81A0680EE30D94B71BE1D26D0
-:10971000C9BE96FAAE121CEF196354314F541EF7AE
-:1097200045C8FC334AA5296710FEECA80978AD624C
-:10973000E4A590FB3D8BAC64272ADFCF267FA8678A
-:10974000510AD98BCAF7A71563DB63E07E7AE5FB84
-:10975000951574DFC0E3DFCAC5DF718A3EC5BB95CE
-:109760008B5751BF4B4AFC777CDF95ECA85CCCA3B0
-:10977000CD4CFF7AAE12ECFFADCE24F9CF1579BCFB
-:109780002243E6FA6900FFA307F83E4465B6145287
-:1097900037372BFF54483DA86BDA1721FDB9A59741
-:1097A00042EA43E7557E1DD25F304FAA0A1E5F7A18
-:1097B000209FEC6BBEA85FD2F24B458285DEA9CF1D
-:1097C000A82A05B93C00ED03A01F8A7A45DE55E1C1
-:1097D000717506FC433D586AD3E577994AFBD91564
-:1097E000DD7CDFBA3CCE783AD83E54C84F707F411A
-:1097F000B7FEDC0346B293B9D132E5AB34F82A4662
-:10980000863EAFF95F1502CE1D0677530CE5C79C67
-:10981000BDE87F68F06BEFD7E0AE90EF29A5EDBF14
-:10982000EBC0AF87170025FF4D0FC78178118780E8
-:10983000BF41FE5937AF4B835FDC50765BF3CF2BD4
-:10984000414F4507EB299B1487F576C3E9296DDE67
-:10985000E1FC306DDE6576173DEFDCFAD9D1423997
-:10986000A89F7A2A3626B8FFDA67EB43EEC79FAA8D
-:109870008A0EEE6FFAAC0AEF4F57D4461BF0E34165
-:1098800026393CC89F3DAA82FBCF25C79C4DD89660
-:109890009D746399299B71C6D384EDD4F3DE1E3386
-:1098A000ACEB8E0C59C5B85DF33FF4F09A13781CFD
-:1098B00072F0AA6AC5FDD31D1ED58AFEFB8E275401
-:1098C0002BFA1F3B9CAC02E331679A6135FAF3CE69
-:1098D0002C5E677855E8E16FE2F9F35A7B5A717FA5
-:1098E000837A11EBC2D127A8FDDA4F75E007D1AF1B
-:1098F000CA1EEC571D54BC367CDFC127BCB6E07DC8
-:10990000C21BF5ABFE8C363A1EF96C4E887C96581D
-:10991000EEAE0A96EF32FB9290FB9FC6A904FF8C35
-:10992000A48743C6DDA13E12D2077F3103FD9146D5
-:1099300013A33A598F81D7C9EAF1F8A8C0A3C36627
-:1099400047378619E354AA6BD38F739470FCE9AF41
-:10995000A727F0B86823C80CB6F72470F8F475B1DF
-:10996000FA3EC47C0B713E983909F9DC61355C0123
-:109970005797391392EEA47AD93CC3A369D0AF4E5E
-:10998000C8E2FDA9869D581F7B774236EFDF6AC883
-:1099900033821FF02B36FE4EAC07AF0D13759D0FB3
-:1099A00024D27E9816DF2886532F2EC638738F91C7
-:1099B00061FEFE1913D8BDDCC0BEB9D5CCE352ABF5
-:1099C00089D76D3F957AF429D41B6A987B7A02F97E
-:1099D00051C52AE2EFBCDD42759D8FED2E4B44FA56
-:1099E000DF93C0F35C593BA726A17EF917BC7F56D5
-:1099F000C2C4E1DF8F75BE38CFF91D59E47F67DD42
-:109A00000CE89502F887F098AE87419840E72598D2
-:109A10003309F36C8DD1269AE79E04CE7F37DA0E98
-:109A2000AAFB8D32ACDE0EEDFD82FE0FE07B095FFE
-:109A3000FE51737063CEEE1F35773CEF237D6539A1
-:109A4000D78F7EACFF3B11B4AFC246FA69FFE5E3A6
-:109A50007BB21CE89F7E12CEF1B7D03BBAB14FC5A6
-:109A6000FA0DEF4D582F9191E8AE453C2C327B6FAB
-:109A700021FEB1AD8EC0F96FB41E78F07B21800459
-:109A8000FA544FE1F4D1DE0B38B5A03DF8589C03F1
-:109A9000D1E080F7FF00F9408367000E5D5DB89666
-:109AA00067AEFBA381F20C7512E83DE8EF3CC91CE0
-:109AB0001E98E7A2E6AF8BBC266E45E17BA61C5E36
-:109AC0005A628336BF6D258F737B95903CD7A4E394
-:109AD0008A7EBF83ECD654ED795D9E71AA886BA710
-:109AE000EAE2DA1713849D4966C9C1798035226E8E
-:109AF000B8DC333A0AFD4CD45132E0D5A4CA6C72BA
-:109B00004C40CE5B21EE674171BFC667E38FD9EF52
-:109B100047B8C71F63F7915DD7E61DC82F70BC5CBF
-:109B20003ECEF132A12FE3A7D3A06FEC3632AF1AAD
-:109B3000584F2107955DC6FFE078BBC98B75CB05F3
-:109B4000077E99E7834BE624035383F010A6863300
-:109B500035482F5A336242FAB2866F61CFF3C4FCA4
-:109B6000118EE49079F6C49477A37DCFB32D27FBB3
-:109B70001E357974C83CAC4709B1F3B028DABF9CF4
-:109B80000840FD0CF05A704C09B1E793E23CB86212
-:109B900036F9A4A2B3FFCD32CA41E199D0EB0786D2
-:109BA000A3CB70F863393F45FFEE1FC55FB4331494
-:109BB0007FB115A1F88B7785E22F7161289E46B899
-:109BC00043F192B27C5CC8FD9B56E786F46F7EBC85
-:109BD00030647C2A18A4E07EDAD33343C6DFD23C5B
-:109BE00037A43F76C3A290F199DEA521F7B35E5D5D
-:109BF0007143F41EDFB226649C9EDEB7B6FDAF90C3
-:109C000079357A7BE0DFBF82DEE6C4507AA70AFDB1
-:109C10001AEDE4F565FD46DBD312E8234C13A15E93
-:109C20008B6E7FF76BCC43788A55AA9FF3CC64B4D4
-:109C30000FFD82EC92500FA5C0148634AA5FA7FADC
-:109C4000BB1F1B0C21FBE28989DCBE2726F27CCDE1
-:109C5000CF4DFCDC520AF88F64870C2C102F031EAA
-:109C600022315EA678FAC7CF60BCDC14DD97A14232
-:109C70007C6CC6FE4D017DB9C8AC36F6013E26C8E7
-:109C80005C1F829E4C4B84F93F919E30723FC263B1
-:109C9000443F22C5C23C91B9643F287F1CCDE224D9
-:109CA000ACC78F0AE869F51A106BDF8A2C3A07F502
-:109CB0001E4282FEAF2586ECE8DD9A7E5A9E49FA66
-:109CC000E9B22DD40FBBFC401A5D3F71AF99F6FB92
-:109CD0004F883A446DFDE784DEFA53BD85DAF3F52B
-:109CE000F6103DB67CE3FA08F41F4F64707F51BB59
-:109CF0005E82789B88AD2CEC9AC58EF9AC7BC0381F
-:109D00004701BE5775F7452E62E43716E3BA6B3745
-:109D10005EB9F74DE8D719FC09DC3E7878BDCCC7B1
-:109D20008CFCCFEA6F5888FF343791C7E973C5FCC4
-:109D30000BA0B1039E1600FEA3B17D775A39F2271E
-:109D40005CA7F369B3BB19D59FCC71A7D23EE35191
-:109D5000E6F8701780F89D4495E09CC75CB45FFFFF
-:109D6000D1BDAB2270DCC07CDA3CC028E86F7C1C23
-:109D7000ED312660DC7F1BAF6F80F759F0BAEB9EA8
-:109D80009427D10E69EFFB88B92F7C88FBDDCC418D
-:109D9000F36AF3331613A29F762C5FF9692CBC6F1C
-:109DA000CD0103E513D6749829EEEA5FF1D7AD2F04
-:109DB000C2FDFB52FA6E42BBFCC98A6FC6203FDC73
-:109DC000BD01F410ACB130CAFD7062509C72E281EA
-:109DD0002B11781FECEBA617D1386E36537DEF2789
-:109DE0002B368F09F6471F4D2CAAC5E7D8E41B3B3D
-:109DF0006F58F27A6622D563097E7A58F0D39AD7E3
-:109E0000C6921FB52662809F787F13AFEFD0D6F140
-:109E1000A1E0C715AF7F5D107CCE7407F0913A8644
-:109E2000EF6BA920533B7B2EE7E0FD57147713C25D
-:109E3000D779F57424F677BEF737829FCDBB31789A
-:109E400051063D0581FD65EDDCE5C2F6D83CA43B3D
-:109E5000C85933CEBFE837AF5DF81DE2A763F3A65C
-:109E6000EFE3981B3C7FC9847D71083C807DA1F89D
-:109E7000A09F85F3731D428F2AB8839E86E7991CA5
-:109E80002AF1B3931DC27D97C62E03C3BA9548DC51
-:109E9000B409CAB345CA06CD08392D49A09F855ECD
-:109EA0007925F1E49D4DE4E787FA3DF96FAF08F1BC
-:109EB000775CF08FFC9D97DC8D9807BAAEDFE333BB
-:109EC0002C3145DDB8FF0381B0532A105B38F06BAD
-:109ED0004B14FB22420F77A21C61FD3FCE85F97A1D
-:109EE0005F383F670CA602F5F80F604DF8B02945C2
-:109EF000B4D2C50C0BE8C5BD897F78E669D09396CE
-:109F000074BE5EEC37E2DFDD9CDF06FCABB7C791C9
-:109F10009E62DFC2DB100F225FA1A7533EC8078BF2
-:109F20000D9233F1BC6FFFDF22314FBB35467D1FF1
-:109F3000E9E03F20D33E4D98D2678A1E222E7B1344
-:109F4000F59E89FB4D546FDEC6F38116D5C9300EE0
-:109F500008B3DB27049FB36B17FA6ED5FE4F469903
-:109F6000800E170C3D91D9307FCDAE1D91E8C6DF34
-:109F70006B747F8A7CB7F2C40705763ACFB671144A
-:109F80009D03F08DA6BA83F10AF328B983E1A8DB1B
-:109F9000904BC6B8760325E3D9F8F6BC87501FD599
-:109FA000F9F83A716E2CFCCB6C63D4BFD8D6188309
-:109FB000F3D5FDB62319E567733C8F135FBF3A8E67
-:109FC0003FAF3005C77F99182DF8D96BC03863B300
-:109FD000884F2E5E35D038EDFDE3DB8A643BF043DD
-:109FE000B6AF792FC543ED6615E91AF60AE378682E
-:109FF0000F2339AFEB9CC1309FDF1FCD1C12DCDF7C
-:10A000001AEEFF039D33EB30AB981F0DB337B31837
-:10A01000987FABD80FCD048EC2F34ADA75ED7D611F
-:10A02000ED3FC55802F981F2B4614A33BBCD168CBD
-:10A03000E708C2733CF2533CBEC767C0FC88FF16FA
-:10A04000C65E26B80270327AAF066726F9735B4D9A
-:10A05000FEB3787E05E0B223FD33198793B58F55A3
-:10A0600031BE0FB33B691D6176D5E19106C35597AB
-:10A07000C3BC68BF7FBC960DC82BCA6F5D78A06F4C
-:10A080000119D83A9A09F9B63F5B3A2DB80F8A649C
-:10A0900072E0F9711B629E6D1A49718347C63816CA
-:10A0A000DA88185CA7CACF3B636A2897E301F7C533
-:10A0B000AD167E7F603CF0B70DFB363ECE1165B726
-:10A0C000CE94484E28AF572BE4FD31C977F67690F1
-:10A0D000D3BFF8F6E6A8004BCDBB7B884F571ADA02
-:10A0E0005F1C0FF7375ADCF94980CFB74E1AE81CCE
-:10A0F000E99F5E0BF35662FCB87B63827308F9D06C
-:10A10000CFFFC3E36B9F4F41FAEF9654CC9BF61BF6
-:10A11000FDA310DEDAF6CF4D548FD0768AEA938E07
-:10A1200024B99DF89EC96D0DB46F3C8535D3BE71C1
-:10A1300096387FDD92C4F5C7E563635E6E08C2FFA3
-:10A140008349DC0F637EF7CD2837ED423E3BD12FAC
-:10A15000817697F08F7675DD9DA606E5FD1AD8DE2F
-:10A1600014C4F75AF636B5DAF57E2F3FCF98F5913D
-:10A17000E53E6710FFB993B89FE716EFF327B917CD
-:10A1800024A1DC769D3645AA785EA56514DA911681
-:10A19000F09FEC43E065406E757254A7F84D38BEF1
-:10A1A000EE1C3F770A746EC2FAFFCD1FB58D5B02BD
-:10A1B000D77701AEB1DED373C24C758FBB8CAE14B2
-:10A1C0001CDFF0E15739A8B72A1069F0BFAF3A5643
-:10A1D000DE8C7803BE2F0E47F9DACE488F69F299EC
-:10A1E0008DF209CF6723DFE7633F93F4F056532FD7
-:10A1F0003FF7B98B9FFB04BE273900BEB7A39F90E2
-:10A200006D0739A0E7C7927C6FED35D0F9540FE8A0
-:10A21000F15BA85F5C85FDADBDA576926FCCC3E711
-:10A22000A29CFAF6D23C2D108320E924E60AF61F00
-:10A23000DB1323898F35FD783091EBFF960C350ABF
-:10A24000EBFFADB21C2217417690F7859DECDD50F7
-:10A25000FCEC0BD3D0DE09BB20FC27769CEBF94746
-:10A2600085AD5AF34EE1EC2DB0CE3587E5817A6E9F
-:10A27000F4577D824FF60AFF15ED849AC7EB67F01D
-:10A28000FAC40DBCCEB5C0B9BA04CB38265734EFEA
-:10A29000C3B6D0D55282678EA72DECDDC7CF1EF393
-:10A2A000F3E3AD7BEFC8C27DEAFE136686FB24AD07
-:10A2B0007FF3FFE175C0C3773B01FF43D825580EFC
-:10A2C000F11F58EA149634F87EBFA4E98FF9952857
-:10A2D0006F175BE5401FEC612D3038F67F9D54F51C
-:10A2E000AC07004B1BE17C1D59A230D94D6DFF918D
-:10A2F000BF25A02DD8758CFB4DAD266716F24FEB10
-:10A30000E8D0F3FA5AFB62123FE79C6F6643E625FA
-:10A310000F09BB37C6C39E413EAA6D95ED5EA0FBFB
-:10A320008556D96902FFE6ACD39D806765CE31CFF3
-:10A3300082A968E745DCA87D4F6519FA2760A71E4A
-:10A340007C61501EDF807CF450BBC47E066B5EFED9
-:10A35000D2D0FB0A35629E87DB36EE4F013AAE78EB
-:10A3600025745C8DA813ABD1F92F8792447C98C6D5
-:10A37000D2D02F01FE21BD605458B719F8F5C16441
-:10A380007707C61B9BC5770C407F921C7608BEDC06
-:10A390002AEA04FC5B25DAD7CB7CD52B1BE0F942FB
-:10A3A000C52BA39D62D0E23EC164A7BB1CF10BEBA1
-:10A3B0003E86FB35CB851E5CAEF9655EBE9F01E631
-:10A3C00096FCB229CCDB1889EB7E5572F854FC8ED2
-:10A3D000C8A03A5C5A779D5877CD8623FB318C5BB9
-:10A3E000D5123AAE4EACBB4EB76E6D5FFBCF49BADD
-:10A3F00073C837B86FF16723F7133E10F368F7CDD2
-:10A4000023B83EAC05F0906E355ED9EBE57E9D0D30
-:10A41000BFC373BF80F77E41EF3AE633A5C0B8559E
-:10A420002FF075B26743EB3F1F6C7DC484F1959E9E
-:10A430002F966F31923F0A8833A1BFA8E78B156230
-:10A44000DD2B74EBAE754B3AB8B89F3C18AE960551
-:10A4500048D7555B8C0CEB11F5702D6B59528E7CE7
-:10A4600036985F395D5688F90270AEA6737C370A5C
-:10A47000E7A811822FC7B17144978AD81BA28BDE3F
-:10A480008FDDBE7F9C15E5FB72F7688ADF35BAEB7E
-:10A490009F2F177EF08C0D8CDA0B6D25D6F118A747
-:10A4A000F4181C924AF156E478C0475E87CC2AA182
-:10A4B000DFDF9EB6DE0378CF3D9C5F85F17CDE61F9
-:10A4C000039D77DBD99D4FFBC07907D263D3281F4B
-:10A4D000EDA0EFCDC03C643FFB7B72D7E3B980FEBB
-:10A4E0009ED27C9C57827168E773851D68E8C9B568
-:10A4F000069FEF2E18C1E3F5A7923EFB31FAE13338
-:10A50000B61BE97CC30CA3FF3DAC9FDAD9ADD0BE2E
-:10A5100075CDE1A56BC390AEAF49B46FBDBF774DAC
-:10A52000DC62E4AB76A31DF7A1FBDBFF6D2FDEF74A
-:10A530006C91E87B12751D65595BA19FBB31CF11F2
-:10A540007CDE2B375A25F8D8082BC5C3336E3292E0
-:10A550005D3C9F6CFD25FA372B9C1B498ECFEFD9B4
-:10A5600069A2FAB9AD1243D3BF3F69DF1B888FF3ED
-:10A570006F1E31A1935DD27AC4D4F777ECFD052F1D
-:10A5800004FE1407379B304E59B551EBF799904EA6
-:10A590002EE1FFD4BE728AFA2BDA24D2332B5E92DC
-:10A5A000E93CFBBE8EB74CC8C7B55B2496981A74BD
-:10A5B0007F8314F21D84A58CF3C152A1675632EF3C
-:10A5C00053C9306E6533AF23604F87D6E5AEDC32BA
-:10A5D00087BEDBB4AC79687DF3B0E0EB87301EBC9E
-:10A5E00015BF83143AEE61EDBB5C3A7E7E5CE3E717
-:10A5F0004C9689FCFC55911A950DD7BF3AB2E2E60C
-:10A60000A1CEB1F7083BACD9C1CB3E03D911FDB8FF
-:10A610008B6D5708DEBA9ECB26B483E5ED9708EF25
-:10A6200095ED5D54C7711773D7209EEE6AB7DA5166
-:10A630008E2BFBB85E9AD96EF67A25BCDFD284F4F5
-:10A64000ECEFE4758B9E3D12F92F9ABE7A48E0EF4D
-:10A650002181BF874041A7E4A21FCBE3DE873336C9
-:10A66000EE8F81FBB5E27ACD817D91E8EFCD6497E5
-:10A67000EE457AC07B18BE87BD148AE73B1987E395
-:10A68000CE2DBCDE596FAFFA4764CDA6FC23C49D26
-:10A69000084FCD96503CD7EAE2ED7523B87DDEA495
-:10A6A000C373A59F59B3110E5576786974AF82EFC5
-:10A6B000EDCE9128BFDAADA6450DB5FFA8B5EF09DF
-:10A6C000BF59EBCF16E7AB5BECCDB6E038D894CCF6
-:10A6D000EDFF8A29B207E934103FA4EFCB510D8179
-:10A6E000F801E286DF8C88E771041674BC3B526681
-:10A6F000717181F8E18749EB2B73A15FB785CBF9C5
-:10A70000C5C9301F7EDF4B61E45FD66D31D339C0E0
-:10A710003AA03BC509EDFC1C83AB5D2A437A83FF5D
-:10A72000FDEE888978AE8619E360DD73DA389FCF55
-:10A7300029BD447C72209DAFF7B2A2260EE58F6B37
-:10A740007E389EC35283CF3F805CE2F8DA765E0F9C
-:10A75000D4BAF7EB51A9A8D73AFE3A6A09B45746DA
-:10A76000F0F56B7E9E1FFCBCD1DCCF3986FEE78303
-:10A770009ADCD8F93EDA83C2CE30A989F8BBD6D8A4
-:10A78000F2760CFA4D5BF9BE3DDB6DC46F9CB18671
-:10A790000F5E6F8A81755F7C5DA27A347CFE09E072
-:10A7A000B38B4B5B4EA31FFDD5560BF98F0F828FDA
-:10A7B000383D77B03C6A72AB7D77AA81AD257F7258
-:10A7C0002D6BA27695E0E38B6D8D26CA9B79839ED7
-:10A7D0001F3DD8EF58A5E33B537228BF357C104E80
-:10A7E000FE5FFF01D98EFB2780A7FF4E0EC687F0C4
-:10A7F0002F5AF786113DFB8FD8C85EFC49F0D979F6
-:10A8000091376E982CD3FA0D53789BD5F9D668A45E
-:10A810001FE21BEBDE3777BE358E9FA7F612DE57A1
-:10A82000BE8A49F120385BAC94DBD3FA0D1F2CA211
-:10A83000EFF0D4ED19806B8C292E00D770FC2F49D6
-:10A840003C1E3448A1F160DD6ED9155CEF05EBB913
-:10A850000FF54F929003A6F813D02F1999AC92FDE3
-:10A860006A68E7F43474F016DEBF80E73B8CF4FED0
-:10A8700041F78B3D3578FFAB542BDF4FBEEAA9C4BF
-:10A88000FE7747CB544FF9DD0F568C0DD69B0CE16C
-:10A89000047AD619FD0914371E31107C75472E270E
-:10A8A000A4DB501F6D2CB567A3DEE1FA6EFF68EBE9
-:10A8B00072E4630FBE373130CF6BC2DE325C6F1291
-:10A8C0007A152FF079C57AD7B2B9223EE67C942D5D
-:10A8D000FC3D882B26264F1C1C57DCA83F09F6E0C0
-:10A8E000E86209EB89140FC6B53B8F737DD0D0F1B8
-:10A8F000D0A7C8E7759F98A9BEEABB9D0F8DA53A62
-:10A900005BB7FB56F42BBEEA7CF856CAF3496B09D9
-:10A910002E0FC29784FECB8709580FBAAAE3C3044F
-:10A92000B2AFBB26AEF744A09F927B275E07BF81E4
-:10A93000F80FFC17E2BF9D3DF99ABF62C579571D1C
-:10A94000505C889F5507F20F55A21F71B8381FD56C
-:10A95000B874389FFC953CF4576C01FF455B4F651C
-:10A9600032AF77E9EF0AA33C81C44673FE61E92167
-:10A97000FC53D3FA0ED9F59A3639A46E507BCE9D8E
-:10A98000ACF07D7E8D7F5A2427F1C776DED6B4EDFC
-:10A99000A4F5AD34B610BD1BB618F9FDADBCD5EAB3
-:10A9A000AA3D2CC683F8388497800E334D5EFA6E2C
-:10A9B000C5C154EEBFEBE9F15932CF631C3CE1BE97
-:10A9C00019F9E560917BAC7D08FBE061C53C3E95E3
-:10A9D00004BE5BF97925FDB853C93C8E8F8C0D3DC3
-:10A9E0003F3A605F9239FFCC340DFD3DBD9F69F267
-:10A9F000C4D83306E08BA39546FB3AE1B78F08FA3B
-:10AA00005E42D55D46F20F8E32FB3B5867384BD322
-:10AA1000AF93B95DD5F2DDAE0D2ADFD7197CAE91CB
-:10AA2000F4E47C6D3EFD7969E1D7CCD7F935EB359F
-:10AA3000FD37868D41FDD722CEB9ADC90CF306E7AF
-:10AA4000A3F4ED7EB18F81E775B06DC8FC98F23646
-:10AA500007BB4EBC41756627C2D8689E97A3FCF51C
-:10AA6000AA61F2D70D03F2382F84BF347A5C10DF6D
-:10AA700055D1D3E30D81776D9F2D5CECB39D56DCF2
-:10AA80006F24535DD67913FF8E9A9FE2AB864CEE0E
-:10AA90001F5D2893685F1CE01C650ED2EB1746F023
-:10AAA000B8EABB0B24CA9B76E1788C9F5A24AAABE8
-:10AAB0005EE5EB35211F8D695DF224C9AB871D630F
-:10AAC00041DFA9986DE17671806EDABA07EC568C99
-:10AAD00087EBE1386A713CDAC159C2EEE9CF218DCA
-:10AAE00065BDE51857563B2507EEDBEBE93D77E101
-:10AAF0008477E2FF013A9F4B761F21FDD67B7901D7
-:10AB0000E63F0F667E3E0AED65ED307CFB3BC1B74C
-:10AB1000DAF7591C63D546FC3EC98F12DD9F207EB3
-:10AB2000FB0DDF468E63F87CDF7FAF91902E8CE8C3
-:10AB3000319C9C9C12F39D4A16DF258CE3FB24CBB1
-:10AB4000B18FF26AF48EA4FC42F68DED4B35EC7EAB
-:10AB50003707F5D6C5AE0339A6203A9E5F03F28EBD
-:10AB6000F6A3635F826A0BE63303F1972469FCA6C0
-:10AB700008BB18CA77E791EFB2B1FD30321DF5EE90
-:10AB8000F6A391B7E07CBB783BC09FED328D837814
-:10AB900067CCFC8860F89E24F82EB4F07918EB1B83
-:10ABA00053353EF87EE3707C6B4CE1F584217CAB41
-:10ABB000ADB705BF8783FE7DA799BE8783F9E6E819
-:10ABC00020B9484DE1F230497CFF660AF3D0F70026
-:10ABD0002789EFE04C51984F89C17D2E9FCCF765B6
-:10ABE000F9798602C1BF93145F17D6394C11FB3235
-:10ABF00085AC97C64D677E6A9DCC4EE7148A9983D3
-:10AC0000DAC916DF9D9876C96E69A1FA3F5F821294
-:10AC10007DD622CE430C41B7C0FA15FAEE0DF1A550
-:10AC20008CE76186FE6E4A650A9773FA3807D2F799
-:10AC300002A3FC147EDF0C5F325561155877749BBC
-:10AC4000C22CE100EFF6B70D24BF9D7DAA17EB40A3
-:10AC50001DB1E2B92F18D5BB4E7272F944D382757B
-:10AC600012DA7AF5782884F9303F364981C892F0B3
-:10AC7000E8A3F7DDCEF8398D22A6D207566EC78F2E
-:10AC800027935EF7539C54027112EA7583C543F80B
-:10AC900028C3E4CA44BEBF1109F314364BEC38EEA6
-:10ACA00057A4F1F56AF3170223E0B9BD32B15E4C47
-:10ACB000811E8FE1FB1E9154385C6AE7DF094AA0D0
-:10ACC000EF04DD285EFB13F8772123EFF75FFC7EAE
-:10ACD0007E60FFC781DF0D8A0C7C8FD281E74C300C
-:10ACE0007FE753CE07FBCD77A72CAD4E9918A897D9
-:10ACF000636EA6A25FA1AF9743F49D0B3ADFACD57C
-:10AD00007BBCEA9DABE2B9B98571163A4F9B6B19D2
-:10AD10009587762B23D15D9D42751F5B6EA14914EB
-:10AD2000EF44574480CFADCC3919F11CA8D7E3DFED
-:10AD30004F1A38CF94C0E8FC9FD5CCEB199F01B9CE
-:10AD4000C0EF178154A958D7C29E28A1FAC7A7A25D
-:10AD50002D0E3C87604678AD01781B2DA2EE47573B
-:10AD600077D96833D0F7381B59389DE79E15E6FE32
-:10AD70001EAEFFB188623A2F9DB56D5A12F983B0AD
-:10AD8000DE69DA7A0D83EB10B1FE0F9FD3D7FF692E
-:10AD9000EBC2E3EBF85EBBC097B64EBB76DEC7A94D
-:10ADA000849CF7D1D6FF4C385FA71177E2D3E859DE
-:10ADB00015F5837E7D1A3FFC3FDDFB356D605C0041
-:10ADC00000000000000000001F8B080000000000D1
-:10ADD000000B7B2ACBC0F0A31E818565181826F1D5
-:10ADE000A18AD112CFE066607804C42C3C0C0C859B
-:10ADF000407B23807424101F01E2A340ACC2CBC06F
-:10AE0000100BC471403C07C89F0BC4A5409C05753E
-:10AE1000632B0B03433B107702713710EB30333059
-:10AE2000E832136F7FBE0803C31309045F51126831
-:10AE3000A734FDFC3FD8F00A7DFADA276DC0C0B018
-:10AE4000D502C15703B2B759A0AAD96E81DF8C1DB4
-:10AE500068F23BD1F8BBF0E83FAB87CAB7D540E515
-:10AE60004B693130782285899D067EB7A0E30AA020
-:10AE7000DE4A200600FB72DB43680300000000008E
-:10AE800000000000000000001F8B08000000000010
-:10AE9000000BE57D0B7854D5B5F03E731EF3C8CC9E
-:10AEA0006412420818C2092FA30D382121058AED2A
-:10AEB000400091A206B50A1575C22309794DC0C795
-:10AEC0008FB56D0682111034582C51A39D2028781F
-:10AED000830E3448908003581A7A5183D7FA687BDE
-:10AEE000BD4129200412F185DEB6FE7BADBD4FE6E3
-:10AEF0009C9319E0DEDBFFBFFDEF1FBFF6B0CFD99B
-:10AF00008FB5D76BAFB5F6DA7B648B8B484308F906
-:10AF100016FE7E40C8748910D23FFA74BE4E549219
-:10AF200048485D0E2DA710923E9C848840C8E46A74
-:10AF30005ACE23E4D13B49C89A49C8FE2316FCBE29
-:10AF4000CACFCAB45DD8720DFD3E82BD7F328BB6CA
-:10AF5000A3EF9FBC2062BBE04C12DA4CCB4984F6D5
-:10AF6000368CD021FCF89CECADB78FA2F51BEFB46A
-:10AF700010AB4AC8137418329E1017F1D9096DBA74
-:10AF80006A38EBEFF19996E745013E46D2E6D3F2F7
-:10AF9000EA29C5F9AB69698DCCE06A9853FC7C90CD
-:10AFA000F6EFB10CC379D07A4F3A69BDC7DE2F21D5
-:10AFB000AB69BB0D732D427136ADD7A4CC0E65477E
-:10AFC000E7AF3DE71289B70B5A2DE3E0E9E3CF88FD
-:10AFD00002CF5F4CB4E0386BAB193E683DC592467A
-:10AFE000484BC7019B9FF6B7B6A2E5E834FAFD913E
-:10AFF000E1162FC52079A4E380FD4A3A7E30CFE2E6
-:10B000001D416BA74B11C1E38C8E379E50C0C7D238
-:10B010007ADE1D36D5D9B73EED7712CC7B0DC5BB98
-:10B0200098196D3706E0A4EDD6529285E9B8BF9421
-:10B03000BD8761DC5FDE902C0449B4DEF50024D4CA
-:10B040009B6B21115A8F483D3642C7593DF16DDB4C
-:10B05000085A7F75A1052641D67AB5EF5E3B81FE81
-:10B06000A68E3C3C1CE87A3DFD0EF3C87E7C36CCB7
-:10B07000FBB1290A01FCFF52A0F5288A1B8A941F04
-:10B08000027CAE6AE281F7F4E98B85D756C18670FF
-:10B0900090351B08C9270002FEADF685560E05FE49
-:10B0A000CA235E28A77B697B67DFF69D8215E9D2FC
-:10B0B00020070702FEE2D16F38C7E7EAAC2576A089
-:10B0C0000721F56985A308590F78824125BF3ACB3E
-:10B0D00015ADBF5260F85927139F40E79790A7849A
-:10B0E00096513C5BB23D7360BE4EBF42AEA3E55588
-:10B0F0004270A0087419A590CD2AF2857D042DAF69
-:10B10000BD2AD90BFC572784D324F87E03FD4EBB00
-:10B110003C5038660EF067A357417EA6FC7318F0CA
-:10B12000BDD69F4C56ABF8BD03DB3B877BAC880993
-:10B130000A0FC54B3FCA4B80D79C9BEAAE1F06F453
-:10B14000196BF10085560B93D4F9203F49360F8CCB
-:10B150002F8FBD19E927F74F16888EDE3F077A53E8
-:10B160003C3DAA16FE1C9E4FE77D943482D65F9329
-:10B17000F34A03D0E999FB6D48BF67C6762C06B940
-:10B180007AF242EEFB7E944BC5BB99F6F36CCE8906
-:10B190004C42077C7CFA474980BFC1C3EBEF216E6C
-:10B1A000FA9CD953434653F8487DE1824CE413E1BD
-:10B1B000168AD7C14B15A2DA182DBF25F09DF8C20B
-:10B1C000D9ACECA4F319CCE9DCD2F1B6AD08FA9B0A
-:10B1D0004B2223DDF8DE969A1CD53383F348249561
-:10B1E000F6FFE4C24328E7CF5C9DEA65729E86FCC9
-:10B1F00092C1FB4987FA54BFA4D94830813E07B7B2
-:10B20000F7DC0C700DCE3A3117E0DCFFC62101E807
-:10B21000F6ECE85415F45192BF837452BA0FCE7E07
-:10B22000F741A8E77286D20AB3B1FE5FB19D09FE6D
-:10B2300066D5B709F0B64DA83E0CF409E658BC8CAB
-:10B24000DE4C0FAEB93735047A64B0E34FB3C4A116
-:10B25000C80784A452F83C04E5A44E88D88641BBB4
-:10B260000758BB212424009E076705178B6EA8EFA3
-:10B27000170A5D7DC76D018D08F241391DF875BB58
-:10B2800042CA0A63C8C16B5C9EEB04321BF9994841
-:10B290007F03BE1992C4F8462B3F0BF0D071B7BFA5
-:10B2A0009EFCC36C0ACFAF960ECD11293C8F42BBDA
-:10B2B0001872B396CB81A39D04058AD7FDBFFB9D71
-:10B2C0001DF0B6DD424AA1FEA4ACB0AD93D315E8A3
-:10B2D000B190B0FE1BB337DA505F0859C8770BC77F
-:10B2E000293EFB6890BFE5829FB64FF330BDECF27C
-:10B2F0002A21D0CBAEB4A060A1F0A8D9C4B33193B9
-:10B300007517A4F89B07FF00469758FD356B9342CD
-:10B31000ABE9F779D954D0006F1457163AEE02C250
-:10B32000E639CF5BB718E84748A105F0B9DAC3E8BA
-:10B33000D308E3D0A934A6B37ED6DE4742CB818FB3
-:10B340003CACFD706842E9363CEF95FF25D07ED3DA
-:10B35000793B907B68979016B259683BB5DA4210FA
-:10B360003E29725800BA8F4A55019EC634EFBFCCB1
-:10B3700004F8674BDE8DF4F3708083F6D3586DF1DB
-:10B38000A1BEC8539A404FAFF6313DAFE12B938F2A
-:10B390009BEE8D0874EE2493EA49C4932F62F74024
-:10B3A000399BC19399C7E6D50BFF2825B49C364E2F
-:10B3B000B74508D4D3F050CCFB2BE6F370A68556E6
-:10B3C0004A00771E839BAECB084F7AB6D2047290A8
-:10B3D0009EC6FA53297E34BC035C0E0DAE3C5A1F48
-:10B3E000F4B0576902567070F88AB3193CFB8FBCF1
-:10B3F000DD2EB0FE50AE1C1C5E079F3F017853B996
-:10B400005EA7FD35CB1141A4F5436389BA918DA6A2
-:10B410004AF9D1EF8F57533CD082938F43D65B517B
-:10B420001EE8ABE0B7940FE6D7D37256543E46AC55
-:10B43000B41AE4C5C9E74DEA991C51B68940BB4C22
-:10B44000C2CA1628D379146719E58C7875650A87FE
-:10B450000BF89DEA9F65E315C63F57313B86105DAB
-:10B460003DE0F3B1EA736BF0BB82EB7AC64F150394
-:10B470007C83AB53278BA04FDA9FBAD9027C752F00
-:10B48000B18889C8CF42AFFEA2E3ED5812B1C32400
-:10B490001DED85C980B78CEAE4C90AE0B1DD8F658E
-:10B4A000477BB50F9FB0348D216410D18D9309FA7D
-:10B4B000D553DE4CF14AAA9530E8EBB17A38E9F77A
-:10B4C0008CD7EB6701BD1E5E7C6820C86FAAA9FD02
-:10B4D00068CB5094D3C1AFD35A38FE899F41FD55F4
-:10B4E0005C9F3800E231F87C1D9E839D54CF523D15
-:10B4F0009D4111AC8C89EA8BD557BD9BE37772FED9
-:10B5000049C667049E66BDA2AB7F15AF1F142E5AB5
-:10B51000EF04D6D3E0317F3F2758504FB9C0CEA4B7
-:10B52000F87D8C78E6E0BAECB5E0BA98C0DF87BD6C
-:10B530000726233DC3C42B6482BEFD9B55CF073F26
-:10B540008197A06FA530CA8992E140FB90CA710231
-:10B55000AC7B8D527529BC0FA73B08E88503530FC0
-:10B560000980CFF456FF109043CDCE9DEC0DA7C1BE
-:10B57000FB470EFBAF44F98C63376A76A2793E57DE
-:10B580005CBB1CF5C1107F4F3BACF7CE0AC97B1DDD
-:10B59000F0979FC2E5443DA992EF52F8BDC165A066
-:10B5A00067553F2D0FA0CF0AFE2C65DF57D594E6D7
-:10B5B0001E97A2FDAE1A4EED51AA17D777ACB7DD94
-:10B5C000007646B54505BE5DEB7DDBE673427972DC
-:10B5D0003FC0734BA166F74504182FFD1D1FDA7994
-:10B5E000633D8A0794D6286B64A047B75E344E7DCE
-:10B5F000770CC0416EA5441C189F8E74BEC867F1BD
-:10B60000D61380C5A25B47F667EDC0F5E50D721550
-:10B61000D2455B57B475047BA4FA653E97A347D423
-:10B62000B04D407D456597D2673ED7234EAE37A9D2
-:10B630001E667A8EAF276B17A7E27AA2E94FB0ADEC
-:10B640004149CCE7FA766DCEF3493750989CA06714
-:10B65000412FA591C9B0FE8E003D03FA490A0A3078
-:10B660005EE3580F598DEB98519F8EA8667AF09142
-:10B670003482FC44D7A12658EF1AD3C369D04F6354
-:10B68000F501C1AF5B3FB5F5CE55DD41400FCECBE7
-:10B6900063EBDCBC6C36DE1F00416319BCA057CDE8
-:10B6A000EBDE2F26EE406599C0ED2D33FE050BB382
-:10B6B000031F9BF936E271ED82C7F149EA37607FDB
-:10B6C00069364683555907F0FD1ABF653AD8DDEB58
-:10B6D000A58E95C329FCEBA7CF5382F4FB1A2FF359
-:10B6E000BB564F9CF73CAC6B568BC2E0AA2E457BF9
-:10B6F0003581C3B501FA463F5141BFE8BE3B37AE85
-:10B700001C4AFB49A37E8CA042A590CD4ABF3B8139
-:10B71000A6A0BFFD1106BF974C2631E0FF57C1C15F
-:10B72000FC507F47FB08A4A7C503F026787B6CE09C
-:10B7300027AAD40F53558057B58F42782D9E656A3E
-:10B74000B4FDEFB9BF70172CFC60DFCF79773AC832
-:10B75000D7BA3B995F6686FFBE49A1760B8E43D070
-:10B76000AD73C5C1EB5CD060A07FBC2184CB95C517
-:10B77000E03A2E307A3DD631F97AF4930AE97BDA51
-:10B78000D1E31D43ED20DF667BEF99840F73D0DE9C
-:10B7900031AD33972A0F36E9FB51D6F00CE4B76D83
-:10B7A00016D45384303D27108BFAED305844185C82
-:10B7B000C87A547FAF90237316D0FA2B763A09E0FB
-:10B7C0004BE38774DEE7EA6ACA0731E6DD2E88F1CB
-:10B7D000E8CEEC0C4EF70E18AFFFA5E94FA5D90E39
-:10B7E000765B385437A80CFC8F6AE6EF8623075047
-:10B7F000FFA44FB90DFD942D4DA97316005F65F997
-:10B80000BC800E0D1EB04F62F989332CB68BFAEF57
-:10B81000F1F47043C50AF47B1B3A62CF7FA285F92D
-:10B82000DB61AA27BDD9F1C7CFB7303B3AC9C2F90E
-:10B830006EEAA134FD7AA6ADABDA3A3B582241510B
-:10B84000B71EDECAF1675E3789546F1BC9F81CFD4D
-:10B85000C786052C0EB161A205E32B1A9FD37A6926
-:10B8600080573A0FB4E7281F86C09E7B8CD4A3DC98
-:10B870000469FBCDA42FDC7712CB65CD6F029F5FEF
-:10B88000EF78DCBFBE8BEBAB7539F7DBA12B3A5EF3
-:10B890001AF047C0CDF464A58BD9B1053BE5C80FBC
-:10B8A000281C954D02DA59967D7684F3DC265AA63B
-:10B8B0005D475C0AD63FEBB1613960ED78F47BB44B
-:10B8C000DCB35324684766392CC0AF2738BF923C9D
-:10B8D0005A067BD8CE8A954DFBEF82FE4A5BADC4FB
-:10B8E0004EFBAFDC5D72E3F768B9A45D2650A5722C
-:10B8F000F33265102D2F0A096128774FA60B15E04A
-:10B9000025590981DFDEEDEE48FD119DF7E91A1B8F
-:10B91000512928B5AE8ED45B293ECA42DBA741BB74
-:10B92000B2660134229DC7E64303615E5B052FF8D2
-:10B93000F7E55B120CF6E0093A951FD0EF4BE83CB7
-:10B94000412E4B48FD3458E72A37AF53545DFCE194
-:10B95000748D07C7D1CA955BE938B45DD54B8217A2
-:10B96000A65865217ED043E776DB673FE784F92D53
-:10B970005346BA605E0F2B50AF2454F48A5D05F82D
-:10B980009A9469F47B59639302F1AD8095DC0D7E46
-:10B990006EF9967E46B81A4494D72549B68DA0CF45
-:10B9A00089D39776F3A8BE743E5D4375ECC868B939
-:10B9B0000CF421F2614899A5AB3F444C427E2DDF47
-:10B9C000221AED6CBEFE078F32FA07F7BA30EEA7E7
-:10B9D000D16F09F79735FA2D49E2F4947AF263C1F1
-:10B9E000F328D083C2530FF8A2CF351C3EF7443260
-:10B9F00009E22E6E1FF10831F8DAFCAC974911B05C
-:10BA0000EE3F2D9F35491A88EEC362883C7956CCAB
-:10BA1000993485967F6F29DC6C41FDE155418E3468
-:10BA20003FFB590B93CBBA810AE2AF7E6AFE732CBF
-:10BA30003E4170DDAB9F5AFC3CD805B4FD360BCAC5
-:10BA4000216D3F2A7E7BCFB47186F69E69A55AFB95
-:10BA50009DD8DE76F1F6F5D32618C79F56A6B5DF3A
-:10BA60008BF03B2F0EBFE7BA89C6F1AFABC0F60132
-:10BA70002BA3574F920DED9A1576AF4F6276540473
-:10BA8000DE4BC92337423D51E307D2E103FBDBD94B
-:10BA90009C346635D1F3C5E437000E1795163D5F2B
-:10BAA000248E7318F831C9976C28D39E3C27BEC3E7
-:10BAB000CB3088DB86F0288314D4179306D910DEA8
-:10BAC000FBF7D9B17CFF0406EFFD839C2867B8B66D
-:10BAD000503ADEAFF8AFD1DBADB0324128E94DD1FD
-:10BAE000FF11E037FA5EB5C07B8748AA513F5B097A
-:10BAF000EAA38733F39F0BEAF0B37230A52F2D9F93
-:10BB000005FBA77F14AF0F0F2E4E2BD28D53375846
-:10BB100099BD319BBD9FEF84F10ABB010F01A56761
-:10BB200024D895E671AC43C719C6B16594E238DFF5
-:10BB300098C6B166949AC6B1CDDEC8DFF371FE0235
-:10BB4000F38A37CEC3432718E7935186E35845D38A
-:10BB50007C32CA4CE338D87CE87B3E8E5DBCD87C16
-:10BB6000864D34CE6748058E93222A86B89575484F
-:10BB700085691C278E03EF611C92CEFC1BC5DA532E
-:10BB80008CF47FCD4EC09E56ACFE17A05FF2473BB3
-:10BB9000417DA2D27107805E49C6FD827FB524E354
-:10BBA0007CBE7450FA3BF5740E6A7601DA3B0B39B1
-:10BBB00088245487FE7915E7D105CDB33296C1B3F9
-:10BBC000B520AD08FCECF52E2FC44FCFB51628F3E9
-:10BBD00063D8050BEBE5139D06FEE57A6F32C9AA23
-:10BBE000063F8BDB015AF904D55F84EAAD8FA8FECE
-:10BBF00082E74999EA69FAFE38D56F44D1C3BB0C94
-:10BC0000DB9D90181E4F34B275E4CB7547658CF3FD
-:10BC100005C93B59741EB7F1692CAC4F60BE028751
-:10BC200023C0E9D1B3DB1ADA88F4F05D01760F693D
-:10BC3000E84771C5EB0D057C517149C6E215601FDF
-:10BC4000FD78E5F6DF40B57785A2C14BE87C67B7A4
-:10BC5000AC93AFA0E57372E75D5EA7AE9FD9F247E4
-:10BC6000306F1BFD0FFA99E3A765DDF877941ACBC7
-:10BC70007712295AA6749B2A0EE5F4E0E3AA21194B
-:10BC8000E8755B2A83E74E788E81CF1EA4D75D1EB0
-:10BC9000D6568327F0A04C22B81E75F667C66D7F76
-:10BCA000ACE7D7D615137C77C9365F21A5E75D0FC2
-:10BCB00088884733BC9DFB127C16EA5775367C2674
-:10BCC000837F7929F8EF5E6AFC4E826C3C0DAF1AD7
-:10BCD0001FDC3E7B52BFE3BA7A73FCD7F73BAEE37F
-:10BCE000973B4A6719CA7756CF31D4BF7B6991E138
-:10BCF0007B517091E1FBFC958B0DE585F50F18EA02
-:10BD000097342C337C5F145A65F85EBE659DA15C48
-:10BD1000197ED2503FD0DA64F86ED977D54D208F96
-:10BD2000B5BF1709D8675F384F3C0AF6D5174E09DB
-:10BD3000FDAA2AE0352A87A76AD290BF4FD7A8F874
-:10BD40003CD79A8BFB6301079567BAD66FA83DBCB9
-:10BD50006CE544D023B43ED5E14FD7BEB52C487D29
-:10BD6000F78D10A4A67C2F362824D20FFC98E45E11
-:10BD7000BEEE1175DF3B2FF1BD812E58B97DBF8B13
-:10BD80009DB1DF770B3D23C1BE0B7E60C5FD9B7867
-:10BD9000F603FDBB82C4F01FB46717C437747AE79B
-:10BDA0003591D9D5D788935F13E9B34261F25EB17B
-:10BDB00063E064881754289191D531ECECDEF1C230
-:10BDC000149801D00F939745A12BA2F28BF41B6618
-:10BDD00090FB1B2CFE7DA09FBBF68B6C7F207230EE
-:10BDE00003F669AE117DAFC17BD2DA1FD7C7776B7F
-:10BDF0007CFD8E0F27E4FD9AE9F8FC434D613F88F6
-:10BE00001FFDA96636963FACF1E3B3B3A6149F1F9E
-:10BE1000D554E3F7E3354BB17CA22688CF53352BBD
-:10BE2000F179BAA61EBF77D53460F95C4D089F9AA8
-:10BE30001C68F62849E1F61FB7D7E9CA81E5F37C0B
-:10BE40000E22FD7707CAB5370DE4FABCF3CB91603B
-:10BE5000E79E7FDF8A41F4787832F35B7CFAF970F1
-:10BE6000BD2F0E51FAE7F6FD6E7730FAD82D643A01
-:10BE7000F867AB462804E2EA8ED7BE83F6327D2F00
-:10BE800011D49721AF7E1FB1B77F98F3804BD34970
-:10BE9000AB7FE2A97FCF9F970DF461F4751C14ABC3
-:10BEA00019DD9EF302DD74F86376D94EAECF4D787E
-:10BEB00094B8DC99F179B6BF86CF8E0C88B7548AD6
-:10BEC000851689BE3BDF62C5799D6F4B60FBD89EAE
-:10BED00094CB8AE7956FB17BF4FAA1329CE431EA06
-:10BEE0008B811EBDBE38DFFE9C1BE47E499AC57364
-:10BEF0003C17F8C3C7F983F19DD67F6538D3E33487
-:10BF0000F4632C9FAF17A6B37D4535F1D618FE819B
-:10BF1000F65C92A6788E53BD707ACBB0441897FA2F
-:10BF2000711E18A7ABC6E361E3A679F47C59B1D4BE
-:10BF300081F535F8E2F5FBF7860F76FC3EB6B15891
-:10BF400013C469E2D58F4B0FE97305FC03D2267F3A
-:10BF500009EB8E234B5B77242C6BFD06C262D07AF3
-:10BF60000DBC6F368C47DBA99A0F0DEDE2D35D2235
-:10BF700027347A523D791DCF0FA1CC8C74F6D31E95
-:10BF800013697FDD927325C479332515F55D0006AD
-:10BF9000A2FC5469EB54FC2AA2BB03E39EE334B930
-:10BFA000576FFF2365B94FFE59C67806F90BED9D13
-:10BFB0007E97F9D705A4D00D4EC6BC96F299A0275E
-:10BFC0003FB168F6407D3ECCFB2CB1E07EFE59F2DD
-:10BFD000B63B576797954A3C3EB992ADCF41FA1FA1
-:10BFE000CC8FDA6986F5BAA4C1582E2637A7823CD1
-:10BFF00014AF9761C7962C82F55EB76F325BF2E0A3
-:10C00000BC4B48751DD829AB65B68F3ACF43A42BDE
-:10C01000285C95BB9EC9077B3620317DAFF9CF8B5D
-:10C020009219DC652921C547BF7FDC927BDBF708CD
-:10C03000B40FD5815E0BBA8837563C66FE4A237C26
-:10C040009782DF0C2F21CB0D7068FD6A70885B84AE
-:10C0500098791A3F93041ED761F2B15632DAAF8F46
-:10C06000733C68E50DA672A3A9BEC62732E7934CC0
-:10C07000C9FF38E89F4A5BCF34B4D308E58FEC683A
-:10C080003D255A6FC3C5EA59A19E88F51AA5B1F19D
-:10C09000EBD9A3FD35C5EAAF72D7B65782949FCAD4
-:10C0A0005E7EC20D41DF4FA4FA54887F556C7EC876
-:10C0B0000D783A2505DD40EF4F4262CCB8E07BBDFC
-:10C0C000F8F23905F02390B529DE5F7CE446D0D73D
-:10C0D0005F6E96312F26B0C51AB1523EAE6A593402
-:10C0E00013E2F7B47C8C951FFE14F60D03AD467A6F
-:10C0F00096BDF0442AC489282699BD4D22687754FC
-:10C100006DFAF334D0E301D2837C686E07E35F48B5
-:10C1100046B92F5212FB7ED7F215025CCE022D8F4C
-:10C120007C0A79090113FF94F6AE279D0AC411DA3F
-:10C1300025570AFAE5DF25DF053DA0E18384983D18
-:10C1400051BB75C3E863149EAE4DFFEC160C7E37F1
-:10C15000E3C3F3E1F9BF7A558DAF67CE717F28DA7B
-:10C160002E84EDD45666FF9036F6AC90236EB03731
-:10C170002B9A642FE55052B1EDB9E79F023FED03D2
-:10C180002BFA69E5DB7EF3EE045A2EDF2EA7CC6492
-:10C19000D3710AA951BA04E8FF968E89D2A1ECD7CF
-:10C1A000BF51D451ECFD4F93A3F428DFBE5F21A310
-:10C1B000FAE2AF20BC5FE974C6A04BF8D834B057A0
-:10C1C0006AB77EA580DFF5C93E810CC8ECDBBEB442
-:10C1D000E937B81E029E908E9C4EBD74EB43AFC8EB
-:10C1E0008DAFE6613D0FE8C978F47A91EBE5CA5D61
-:10C1F0002E9204F1CF3F584333818E2FDDE38679B1
-:10C200009C94AA195F3FF3502AECFF95CAC1540FC2
-:10C210003ED9FBD267EF437E2B11AA53D93EA66FBE
-:10C22000208F970F84F92D6CFC11CEAF98F891EF09
-:10C230004A9F110B213EFC8544A66F8F211737C8FA
-:10C240006CFFE9E4462B24F9919360E7837DFDB60A
-:10C250008871564216E33ED87D5A1C972CC1F217BE
-:10C260007C5F6AB86CD1FC439B815F373DDC01F495
-:10C27000393DD83700E0A47808727C09B0DF2F1E62
-:10C280009D3A80D187E51B603BAAFF0BE03DD4EFD0
-:10C2900090719F50D78EEB4B36FEBD7C7C0AB70366
-:10C2A000D6B393A96CBFD23CBFA57C7EF4AF83E824
-:10C2B000F84B27DF4CDE37AD62F2ADC97B68D67430
-:10C2C000F8FEF93B4C7EA01DAC1F14AEC800FCBEAE
-:10C2D000FF5601F581954462C9F52699CBB5F17BEE
-:10C2E00080CA29C40528DC12E43344F984F69F8C03
-:10C2F000F847BFA4783D6DA7B3CF02301ED653A236
-:10C30000EF75EB4709D703D365A3FC93C6FE97658A
-:10C310002F56C82408A665C50756F4BB2BB6C98599
-:10C3200030EF33CD07DFFD31E5EB33614D4E8DFA54
-:10C33000D32CA7A53B360BC09F66393D534A57EB1C
-:10C3400058724ADFC794D3D2CEFF2BFA53C35BC0D7
-:10C350008437AA07872459E2E3CFAC075DB21A53AA
-:10C360000FD2BF77487E5FBED3F84DE3336AA10D8D
-:10C3700001FDDDCB8F1ABFF5F2A3C66FE6791AF186
-:10C3800066FE3E010C350A57E16E19FD928A36B6FB
-:10C390007F43DB1DBA220FF1E3C3E58BD41FBA2222
-:10C3A000455F0E99CA61537D9FA95C68AAEF3795D6
-:10C3B000AB0DF52B5A0F2A2CC92862A8675DFA1419
-:10C3C000F938867DAFAD3381964F9520F0437A8F53
-:10C3D000027A4E5E4E4D33889FED15D1DFEA567BD3
-:10C3E000DCC9F4FD4376E6C7767B783989957BFA1C
-:10C3F0002B75A0E7B4F73D7616E7EC2EEC7127E934
-:10C40000FCFB636DA21BF6833B432C1FB52F3CB591
-:10C4100028379D24DE7716179C2A3A339682FF56DA
-:10C420002F7AC1355CB0EC7637ECBB75B70DBB69C4
-:10C43000367DBFF0B008E633E976B847035C24E800
-:10C440009306E6F3FC09FA778A047F3911F226DABB
-:10C45000987DBD608DC91E76DEAB607ED97A5D5C4D
-:10C460004BC7FF65BC9FD246E3F732B206F9AFCCAB
-:10C47000240F7EEE0F1CD5E42187E4B0FD6DC2FCD5
-:10C4800058AE77A78AD937CDA678EF6E17316FF6F9
-:10C490007C9B48EA609ECD02EE7392607F94AB2A4B
-:10C4A000D283FA4EC34B17C88D125F1F75EDFCD7B0
-:10C4B000FC07813F5EF9E3E8A7E9B3EB950F46EE91
-:10C4C00081F2AEF732FE48FAD62FD8F735EE237652
-:10C4D000EFB3629CAB7BDF6F331E84F2AB568C7381
-:10C4E000752FB7E23E4A709F2B3402BE0F66FE40A6
-:10C4F000EDDEAF46B33CC91548A7BFC8CC1F39DF36
-:10C50000F6EF1F42FEC8F9363A2BB00BF625A0DC39
-:10C51000045EB5A3FFDDBDF7AB7CBFF3EF379F2A09
-:10C5200085F891FF5C64F60EE0D724160F0EEC1927
-:10C53000FF1CE43757B6EC5720CE5EF0DA5F478336
-:10C540009EECDEC1EC9D7372E7B3B01F66553E5D95
-:10C550002E533C9F03E11944C873CA988260762C1D
-:10C56000BC303C74533CC0BC285E4A41BFC7C34783
-:10C5700086F28F8A8F4FEF627AECBB98671FC58B6C
-:10C58000E063EF5D219B80F367EFF77D351AF4CC14
-:10C5900099F032B4472E35EF6B15B6CFF23F67DE18
-:10C5A00042E472E63DF71F96DE8CFF3F82F5B57FD1
-:10C5B0005F39E8CBE7BBEEC7F24B2E2FC27B99F277
-:10C5C000FFD3FF6974DF41E9EEBE34DD9FFE879D36
-:10C5D000F7A5E87E98D3DDE581FDE5EEBD7FC5B822
-:10C5E000A936FF4BCDFBD5FF47E7ADD9EB332CD5B3
-:10C5F0004766D1FA4748647D2185F3F5F4A9EFCC6D
-:10C60000A25F7F1BC71E39ADB0F8C76F09CB130CF3
-:10C61000A6092CCF83FB450584ADEB05592568673A
-:10C6200014643D82F60191AA8FE4507CCCC858E88E
-:10C6300065F96063F01CCA7503AFF5623CD0E41F76
-:10C64000165C7D7D3BF829079751F8E83807078B82
-:10C650001E6A299129E972C43A1A9FC7E079C83D38
-:10C660001DEB4D711AFDA399E0DFE8FCBDEB55E32E
-:10C67000F769BCFFE9E4400AE4934CF7CA2404F5E7
-:10C6800048FD0AFD3EF234533F87C0AFD5C5CBFE0F
-:10C69000A3F84BB7323FF2B764C9911CC05FBA8CA4
-:10C6A000F1C04BE28FB0FCAFEB06E6E079142279E3
-:10C6B000117F330655727C32BF59E2ED25675D0765
-:10C6C000C8AD44A8DFCBEC32F49735BFF7527826DB
-:10C6D000DC9F96F8D01ADEA57419F35675FD225E1C
-:10C6E000347AFC47E9A0D1EF3F4B8F73267AA47FC1
-:10C6F000EE91403E0BB8FD3FE5F30E11CBE95E092C
-:10C70000F7A3B8FD3FC9992481FD7FAD745404B9E6
-:10C710002CB1B5CE8038BDCD2B205F5FD96541FFF0
-:10C72000C6962720DEB31A242C1FB578C682A17DB9
-:10C73000E3F7769D7980407CD8A7A0E14D0A597C2B
-:10C74000FE2FDF7E3B513BAF81DF09B981FA5F0BE2
-:10C750001A49C441E7B75022C1C46488EF0AE423F0
-:10C76000437CD75886BFEFA746FBB954FD787AE4DF
-:10C77000EFFDDC45F5D647942976C313F755282BF2
-:10C78000E8FCE3EFB6317C058E90D050D40B3EB17F
-:10C7900050B76FF68895E98F5D7FDA910B71B149DB
-:10C7A000DDD9894C9F0E47BF20C0FD82F3444D84E4
-:10C7B000FC83F36DC312715FB05D74F963C465B639
-:10C7C00072FFF99F209F823EBB37917A3887D14D07
-:10C7D0007A301E1BDC648BB9BF7BBF558B3771BAB7
-:10C7E000D13F513B6FA462BE4830514FB7AE999FC5
-:10C7F00048A3FBD201FE3ED2ED97FC57F10BFE3A67
-:10C80000E077ABBD735AACF3602B39FE6E3CF0356C
-:10C81000C631AF6E6BB200FF5EBDC962D86F0C5AF5
-:10C82000B9DF35868C01B86E3C6077E5015DDA458D
-:10C830002FE40F06DA3E55FC31F6ADCCF884FE212C
-:10C840002EBECFCAE2FC7BE4F07CC0EB9EB336CCBC
-:10C85000CFD9ADD497C782F34A3BD3730B49F89E27
-:10C86000D199FF78F89DD4ED8C4C063F7313E1719C
-:10C870000C33FF11E4E3F35B089E0F05BF14F4C211
-:10C88000F966760E98A2642DF8D354DE7FA08FCB84
-:10C890005CD9BAFD9FC00EA86A133C903A5B25751F
-:10C8A0002A106F0DB42689B0EEE6A85A5EA567D4AB
-:10C8B000AD3AB9D86765F9C60727ECB903C6FDAC30
-:10C8C0004B21608FF85EEF71C3BAFD595B6E62ACAD
-:10C8D000BC79EDF9EB1A32638A04FD10C4BB991FD1
-:10C8E000B29B1D86F2F744FF2090AF1BAD9DF77AF7
-:10C8F00063D0CF6F637C76D9FA2DF4FF997E7B47A6
-:10C90000D36F7EB150274759B63EFA6D402CFDB625
-:10C9100044500700DE97EC1D3600E8BAE4B0DC3F77
-:10C92000967EDB56C3F6F35EE6F9B0DD2D54BF5DAF
-:10C93000A3D36F2D36CC8B33B74BB659F8BA7809E1
-:10C94000FD16FAEF91BF6DA0DF62CC77848DE90D03
-:10C950004DBF8D6E3B86FA6D748BC590379A6EBB5A
-:10C96000947E13FADF0AF670BBEC4D88C13FDBB84A
-:10C97000FDFD32CFC3837140CFDD6163FB9B97AB7D
-:10C98000E7B2ED8CDE97D473FF4D78D6F4DC929D40
-:10C99000DA3947331F323DB76437D57302F023D3FA
-:10C9A000734BF6B27B1CCCFA2DAB8F7E2358BF2A7B
-:10C9B000C2DA075A3337CCA5FD8DF1C95E1BAD3FF6
-:10C9C00026AAEFC6EAF5DD1D3676EF421F7DD77E3B
-:10C9D00079FA6E27D777548F0D05FD6AE60F6F9BA6
-:10C9E00031EF78CFF893CDBF06797943C47DC3A3E7
-:10C9F000FC5CDA9BE34FE6017F35DB98FEADE5FC9E
-:10CA000077AE2688FD17BCCEE657E964F9C8552DE8
-:10CA1000CC3EAC6A16422AFDE7B4095F2B00FFA2A8
-:10CA2000BD021940CBB3ACAC3E7941DBF722337386
-:10CA300074FCB0605C39C6ED1748C40671F972E742
-:10CA4000B44F201E5F3E8EC5F1CBF9FB45873BEB13
-:10CA5000209EBDE84901F73D09CF07D0F21B4BDA14
-:10CA60009661BCD69C17A0E9F34521E3FB72533EC7
-:10CA700063139FE72CB113F142DE1263E62534996C
-:10CA8000F1D1CEF1B149C475B3171F143F6A665F87
-:10CA90007C508ACECC498DCE7FD11B745E79D17902
-:10CAA00069F830CF4F8B3B97F376F1E6ABE1AFCF30
-:10CAB0007C357C9AE6FD1CE80D5008392417F2629B
-:10CAC000281FA0DE08FE4EC4F3FB8593460CD0EB76
-:10CAD000E1AD5C9FE7D64F2A1848005FA41AF8A67C
-:10CAE000B861F1A18174DE63DF57C7C0F2F8BD09F8
-:10CAF000563FEC8F6EB5F7A05ED3F8EA1BCE57EF2A
-:10CB0000723CEE19548DE75403AD8207EC8A40C4A1
-:10CB10008EF80B50FCC1F995003FBF18A0FC05F240
-:10CB200074F0C92F19BEF60A2AC4C7A769EB0FE033
-:10CB30009FD6CF6D63F80F8404C47F1EE9C1FD91B9
-:10CB4000AA06C11BA1F5AB5A1763DE83A66FE99F46
-:10CB5000534F0F1D3F4AB1F8112BE9D6BF725EEF5C
-:10CB6000466BFDBBC09F37BE2093261D7F66D1FF5D
-:10CB7000BE8D41270D9F97E2CB0B1C4FDB008F4EE4
-:10CB8000C0570FB39F225FE3391AED7B400A1AF0BA
-:10CB900058F0D4858BE269AC8627E053D0536D45BD
-:10CBA00022948B5B05D22FB3EF3C617F522FB78B62
-:10CBB000F61E63FD3F23E0BD2566BED5E6DD876F2B
-:10CBC000E3F02B9C4B03BFE872F9F61B13DFBE6941
-:10CBD000EF39920B7CBB5760F183B624C3FEE22091
-:10CBE0003B5BFFB7DA297FC3BED661D9BB51ED2BC2
-:10CBF000DF097CFD02BB5F7F2EE92A9808E43D6EC9
-:10CC0000B1611E19C23194D9957ABDBACD4EFADF01
-:10CC10009A17BFFF81BCFF78768D561E05E341BE93
-:10CC2000572B1D2F2B3A9E59AF6B7EFEA5E635F292
-:10CC3000BF38AFDE3C4CD281FB4E9992FF31AB2E18
-:10CC40000FEE369E67442140FB4A572FDB76917AE0
-:10CC500024CD83E79FEEF1687CC6F2DD0B791EFBE5
-:10CC60005471E27BB07E7EE663FB7C7916F2FB8931
-:10CC7000A09F27CB788EEFB32332C66B3F9BC2F2C7
-:10CC8000386F7AE3A004F1999B4039517CDC34562B
-:10CC9000407F058E61C1BED92E6ADFF846E27C7204
-:10CCA000E11C57CEA6FA02387F3C664BA8169EDEE2
-:10CCB000829E9437018F93440278ECF0F52B80FB31
-:10CCC00093EEF933C1FB43E83A8BEDC7B493FE50C2
-:10CCD0006F82AF3FBA03E35BD617407C74D641A79F
-:10CCE00013EE67C96AB4509F218ABF0924540B719F
-:10CCF0009BF1C77DB700BCA5D45E80B873695B5358
-:10CD0000AD1BCA8D8257A5FD0782FE696E3A8F6DF5
-:10CD10000D9F4EFB0EC823AD07DD041A59BDC0267A
-:10CD2000B87808DEAFC33C9BE24D021EFCDA161257
-:10CD3000888DF51BB2D17EB735D2F679B04ED0F6DC
-:10CD4000D0EFA64FDFB905E4FD88C8DA37B37DEA36
-:10CD500062DA4E05BEDDB418FB5BD4289034DA5F8E
-:10CD600069335B074A8FC85EF8DEB2FF495CC7666D
-:10CD7000D2F1066682DE8F4C8132C9153C18EFACC9
-:10CD8000188974EBE6724E268E60FA43E065EE3742
-:10CD90006876D3BB7696EF5BEC5DA6F4A3FDBC3959
-:10CDA000AE7F26A405045A3FC5FDE7E314CF7EDA23
-:10CDB000E5519EB77170DCC74AA76E1DFACCCEEE66
-:10CDC000B75AD03A09F319169242CC67B8713CB3FE
-:10CDD000D7DEBAD61E822B0EDE927BD2E1FDC16B6E
-:10CDE000AD68FF9EDB26231F9D1BDC89F1E9938D37
-:10CDF000329E1BAE6D64F7739D6C66EBB8F80CDB6E
-:10CE0000D72F7129583ED878CB3458DF4E6E62E761
-:10CE10001D0B9E99AA40B9A449F0B2FB8B987ED411
-:10CE2000FCB7620FCB47D0F45F259F779FBC45933B
-:10CE3000BEABD4D61B93BEAB847D65373C8DEF0370
-:10CE4000C4C9F420D8FD40F7C8D7C8BF554764020D
-:10CE500076BFF071D734CCC7DA2B603C7F7C9BE087
-:10CE6000837DFDD2F7AD21B457434577FF04F4F835
-:10CE7000075622A890D74EF14EF5C3386BCF9F7E50
-:10CE800041DF7F72D4069930944F8A10CF5AFE67E3
-:10CE9000DE6696C79277747D2A9CB72453FAA1BEAA
-:10CEA0002D6910895FA7373E117CB7FC98E965BCF6
-:10CEB0009F42A35F9E525F0CEBD83007D34BEA66CC
-:10CEC000197244C8611E27A1F6349EBF5DB47B5D14
-:10CED000AA42EBD5F1FC8F457BD7A58AF47D2DAC1A
-:10CEE0005FB4FE2285F5BF689FE069D2F5AFB5D784
-:10CEF000FAD3FA51761BFB19B697972FB31F0D0E75
-:10CF00006DFC78F6F8B87FB9B01EEE8B19F79688ED
-:10CF100049C7E33E9E394CBFDFA13DB5F86BFE3BF0
-:10CF200016E2D3E16DDC9F1CC4A7E38B96B154BE1F
-:10CF300029DD6E681542004ACBD8634A651E963DCE
-:10CF400020CF553C4E5B3585ED5BB5E41C5D01F2B1
-:10CF50003D334F403E2041BFD22F05ED2015F6173F
-:10CF60004AF258FB12DA1EE4AEE5492687541FA8A0
-:10CF7000A02FAA1AD74DC3FA9B0415FA6F692AC2CB
-:10CF8000F5BE749C48F0FBA663687F94B61E4B0107
-:10CF900079A5F2B91ED6DFAA8956BCCF4B933B4D7B
-:10CFA0008EDF92F97D4D36CF28C8EB7F10808A2125
-:10CFB000BFE211C2FCD46619E52C308EC9E55BDBFB
-:10CFC0004494E783D7DE8E72786EB310478E0B14CD
-:10CFD00038977C32C4BEF7CAF15681CB31D30F27C4
-:10CFE0009D4CAE0BE03BC8F14E81FB83CC1E34CB95
-:10CFF000B126979792DFF22D26798E23B71D52E73F
-:10D00000AD30EE3DD7DA11EE82EFEF7EF71ED43F62
-:10D0100032E67D147CFF8154D077C512CB57D2F015
-:10D020005829B17CB63E70AC5FA60CBC2C788C70D5
-:10D030003C6D7745F587087CCEEEE10A6E9291CF84
-:10D04000CD72F85F959FBF973C1FE6FCA3C123EE0E
-:10D0500065ED217F2C42F1F4DBE6E7304FF5EC8BF8
-:10D06000C76E043C97EFA17C4BE77BAED9C5EF7B45
-:10D0700009E13A53D622621E389122F9B7B8F47208
-:10D08000C9F290CA5F76217F94ED60F9A465AF7C08
-:10D090003C1AF34496F7607E55F0456E6F063B47A9
-:10D0A000035F97492C1FCA2CE7B73A98FDD9B53BC7
-:10D0B0006136CC43D8C2CEE997856F97810FB57A98
-:10D0C0003F74C85A3DDCBF0C52BE85FD75804F7F52
-:10D0D000EE5CCB83EADACAE4BEAC55467FA96C4B62
-:10D0E00013C6B1035B3EC53CF78297B761FC20D005
-:10D0F0002A1AF31EB788B87F459FB84F65CE3FAC5C
-:10D100006AA9C4FDB6AA30CFEF33E5BF95BFBCF71F
-:10D110009520454DF9AF5F70831E38DDB1D90DF80C
-:10D12000A4FD61DEE0F73F970C7951F1F37B7DC6FA
-:10D130007CC2F0AA98F984A7E11F94C11F70707E89
-:10D14000D5F230B7F4E379DA91FCC218F1FBDE7363
-:10D150003BDBBE7816F2DCBB769C7916E0AEF8DBE2
-:10D1600067CF423E13D967C77529F0E2EF314F58B8
-:10D170006BF70B07F7F3B7BE80F9D5E73EB0A29F78
-:10D18000736EEFC90CC85F3BB7FDEB5488C7DDBBBE
-:10D19000772AC62BEFDD593080C4D0EFDA13F8328E
-:10D1A0007419F9DD663A1C6C3988795767DFB7A2C4
-:10D1B0003EEBCD0B0D57B23C5B95E78336C7CEA354
-:10D1C000D7F218AB5A6EB9E95AD0CF2DCC9EEBCD21
-:10D1D0006BBC541EE83B949ED75C06DD9A799EAFEB
-:10D1E000896E67E11F943E6113DDBE6859F8ABA7F5
-:10D1F000E05B4BBFB879A091CBC09796A7FF738730
-:10D200006F8F03CEFDED4808A6317A85660A60EF80
-:10D210007D9101E71A4EC93D98EFD1B3D7EA817CE1
-:10D22000C6B2BDEFA17C9CDB7914E3AA84E7C99F59
-:10D2300023BD7F2CAF59E0F3DBE462F9A31CEF9030
-:10D240005FAABAF13DCF23657CABE597C6CB2BED4A
-:10D25000710C6571687E6EA092FA49FCDEACDE7CD2
-:10D2600053611CD0E998214F579BB7B93F0FD79B0B
-:10D27000D1FCE8D879BB5ABE60944E6C1DD1F29FA8
-:10D28000CF35F1BC69FA3E7D0CE4C1B1F53A10121C
-:10D29000DE2331E451CB8F3EE330E545872E2F2F3F
-:10D2A000FA52F0FE67F1F1A183C5AB35BC74FD25E0
-:10D2B000B63E561298DD49FD533901F705987F7A3D
-:10D2C00037F74F357C69F0D68599DDD0B585F907FC
-:10D2D0006679AE8A735F520A1FA7AA75FF68D03BB2
-:10D2E0005D0776737E63FC5CD57C8CE5DD52FD1CAE
-:10D2F000D2EB677EBF84B9BF0CDE5FA02D767F8145
-:10D30000E64F63F6775AF2DD0EF09FEE6076D2E9D3
-:10D31000B0383DD6FD36B604D9903F50E762F76588
-:10D32000886E07DA47F7BAC6BD9F98024F05F37AB1
-:10D330006A97F13CA09F79F15ED15AD70C02F03C7C
-:10D3400004F8D1C519648F9F809D26A715E6896AC8
-:10D3500014DE5E7AA45848484F7F29920EFAFCC327
-:10D360009C9332F4F76FA6F8C8BF49A46E0085EB12
-:10D37000DF828277991ADFAED6CAFE9F8A86784608
-:10D3800095B5E743B0CFC96B76DC0F17F7D9831893
-:10D390001F7B96DDAB7170E757CFE3BD3CBFB21288
-:10D3A0006E170AA00F4A789CE2E4CEAF9EFD77B0DC
-:10D3B00023A1311DBFE4595A1FECE7E604B4F7BBC3
-:10D3C00077248E863840C96B0FDE08FAA204741FDA
-:10D3D000D8992F0F08D5D2FE4EF467E513DB06E38C
-:10D3E000B980F21D2ECC273CB8735715E8FB732F7C
-:10D3F0002710D0F767E5CEBF4139B0279134A9682F
-:10D40000F7A9FA7575119154BD3D570E65437E0B12
-:10D41000C1FC168CBF517E2E6F4DC4F31FBA7A5CCF
-:10D420009E8383F83D518340EEA8DDA81AF39ED970
-:10D43000F705094C7F05AC3DF7B3FB1058FD80D2D2
-:10D4400053CCCAF58398DC7660FDC51ABFF2EF7D38
-:10D45000FB65F503092C1E10ED87B5AFB2B2FB35A5
-:10D46000CCF4FD6982C0CFE3FEF5CA58F74FC48003
-:10D470009FDDCB259020DCBF4AB6DB314FAB428924
-:10D480008C847CF55714B6FF51E18E8C847CF53D7D
-:10D490005CFF55386899BE1FC4E180FA5026B6CEAD
-:10D4A00097F05EA75D76BC0FAFF235970FFD8457FE
-:10D4B000BE3AF1741EE4AB25609E74E56BFF0BE988
-:10D4C0005F698DDC05FCDFB3DD8AF793766D3F9CE9
-:10D4D000017643971CC948BEC8BE4E65D86AD8A716
-:10D4E000D6E671BA66E90438C7AB9D332C8BA32FFF
-:10D4F000DE4860791D4D09BE5F313D67BC5FE67453
-:10D50000CD6CC3BD8965B6D87AAC19F4822E8E274E
-:10D5100046CF153643BF674967DD204A924AA107C7
-:10D52000F7C7CBB664A683BF7BC07E25EE5B1D909C
-:10D5300055F407E1A9D7C7A76ABCB9129EA7CFCAFD
-:10D5400095281CDD4D9F160F22901F689F1D4B3F95
-:10D55000ED4D48407E2AB359639EDFFC1DE7B76D51
-:10D56000206F63D978DEECE8B807E49002704C7461
-:10D57000AA389F32EA07B07BA2E6E4EACF6D2F9289
-:10D58000EAB11E952FC4C722B25EC973F6D52B8BA4
-:10D5900096E6E54AB9A8B0BEE9E537314A27124C0C
-:10D5A000413B49E23424EB071AF2FD25B9D006F8D5
-:10D5B0005248A1471281D4F528A70E12C6A7939A04
-:10D5C000216C1DAA26101F3FC5F767AD92FA18DE21
-:10D5D00037D32EA23EBF14DEDE4B7023DC56A99A51
-:10D5E00078D1DE98E9017B4C08FAC9B7941F6A6BC1
-:10D5F000A6E7B273E1C407796E6EC2E0737B0E7D5D
-:10D600000DF601E533768FD5F749A8968E07C78CBE
-:10D6100031FE3799DD676F1EEF2F9C0E24B8DF7047
-:10D62000DF39FCF568F7E781BF9EF8B771B01FE3FB
-:10D63000F49008D84B094E1249180DF7E449A7F5A4
-:10D64000F2EB26AC3C94B233E835CF44E377335F5A
-:10D6500013AFF479AF5E14B1FDE7A6F69F5FACBDE2
-:10D66000868F806DA3F7786E142F0E3E87E064EFEF
-:10D67000854EC0C768B7B716E8A8F47CF820E06309
-:10D68000B493F983290D44EFAFE53A99BE5AC1EF3F
-:10D690009FA67F854E5D7FC463C3F8E82A8EF7DEC0
-:10D6A000FA5ADCA44F7DBB0478ED53DF1EAFBE23D6
-:10D6B000767D573C781262C39314A7FF60ECFA554D
-:10D6C000AFBDF7664485974C6F40709E9F5BCE75EB
-:10D6D000827F95F8616A11E30AB61F60A29B03F886
-:10D6E0008FF28363B8EE3DFC5FB68E7E4363D09FBE
-:10D6F0004490EF8A383CB4EC1C48E1FB310777CA10
-:10D7000026B65F39F75E1627FAB18DE5971EE3F767
-:10D7100001CD6D607EF5DCA56C1F9194B2733E1E49
-:10D72000FA1F8C77277442E97D67BD108A64C2BDF9
-:10D730003526FBB5F77E9C450AD42F32C55D347E75
-:10D74000D2CE23CDE7F67526E7CF85A4C705726F45
-:10D750003EF7FE3AD76B9ADE0FAE2359706E5FB478
-:10D7600038BCB03F2AF273A6C4CDEEF323BEC1ECA1
-:10D770007E392D8F2B4B4D84F58D84F97BBECFB236
-:10D78000E47A7580FE9C9674C181F783D4CADE3436
-:10D79000D083F2056AD751574DB93094A8BA736453
-:10D7A000D49E43E1963DECBE44C953484AC00EE4C2
-:10D7B000F703909419BD76D75B140F4BD6A9786EFA
-:10D7C00075A193D999BF7015DEE31C0BF6E5382FD0
-:10D7D000BBE7D648C7E04E36BF5A985F665FB86B66
-:10D7E00015AF17EDCE19D462C0388E177FDF41B464
-:10D7F000AAEFA9208FFF2CB3DF2BE8830746BFF3E6
-:10D8000029C9782FFB02F7EA0F814FD7F0FB0857A1
-:10D81000D664E173754D1ADA9D75355E7C6A78B110
-:10D8200079EBF1DE37DB70D69FCDE3677605B56522
-:10D83000209F42F25447A06C4BAF2660EFDA7BF199
-:10D84000538FF8517ACB7E2C5B3DEC7723E486999D
-:10D850008867DA9E94D0EF4B5CFEA7404EECEAD589
-:10D86000867BE4AC69634CF70D9AF0A6F1C7368667
-:10D87000BFB502E30F33FED6CA1D2AEC2BAFBDBEE7
-:10D88000F7DE19C41F35EF19FE7EC7F6D9E2E2CFE5
-:10D89000938CF6EB82FCBABB204FFA11BEBFF87036
-:10D8A000CD38C4D72A7E8FE443353E7C8A803F3A08
-:10D8B0003F6B7690C0FDE8ECB721E8D359E883FBD5
-:10D8C000678177017FA293E1D39A568DFB6B362750
-:10D8D000C397E80C225E6427C397E864FCA6F0B205
-:10D8E00004F8CBC5F6F89EE2EF00F0972D7D82019B
-:10D8F0005F4ACAE4CBC3DF93147F148E142E5F6695
-:10D900003CA428EC7E4A4DAEE2D9714FD0F9C3BA9F
-:10D91000BDA186E0B37F1C7F71A88BAD9B2996EAE1
-:10D92000FD32E02399F0F52448D2F3094B3D84BF42
-:10D93000B42051A12C303848FD60C3BD92A24732BB
-:10D94000DDCBA66E003E587F58B640BEBCB874868C
-:10D95000E13CA838DB97A4223EFD784FF323352A1B
-:10D96000D26F1DD011EE01E5FED7439C9E0FF37BD5
-:10D97000285771F958CBE5E5312E27B5FCDEE435A3
-:10D98000D3599E554A8E85DF571621FA3CA6246F3F
-:10D990009828142EB4A9557CE23D8BE47D6B680475
-:10D9A0006D97904D7CC02749EF3F1062F735160EFA
-:10D9B000043B2849BB7F71A29A34070FC24624E674
-:10D9C000775055887E4C8725D63D55B5DE03368881
-:10D9D00087C68327C1EBCB7C888E97D0E042FBBD06
-:10D9E0009FBF70CE425A76362460FC2F81FF3E8B5B
-:10D9F00093C25DA2A377BC7BA837BAAE4F74517AAD
-:10DA00007A0046FA7CBC6118FE2ECB137221FE8E82
-:10DA1000CB137C3DD5EE39D7DA7DC3F5A33BEF6A56
-:10DA200083DFBA5EF6613BCF44A3FCAFE7FA3679F9
-:10DA30008A91CF357D7BBC57DFFA87023CA917A6B8
-:10DA4000A01E4BB939B6DEAD9515BCB7BC761493A4
-:10DA5000F36091C2CEB5F4D50318A73EEF1FB911FC
-:10DA6000F4A8C657CB09D33B41E2F0E23AC4EFB782
-:10DA7000D1ECE095700F20D7AFF01487B3DF1F48CB
-:10DA80009DCBEEF35DC3EFB17A94F215C17B4FBD30
-:10DA9000F89CE162FB13CB6D63F03EB55AA705F528
-:10DAA00084F48135042687B47FBC07E20592ECED4F
-:10DAB000F041BCCF2585E1DEDC5A671EDEFB2E245B
-:10DAC000E57980FE5FBA160CB9583E1D9D28DE9799
-:10DAD000E94929241F65E36E009E5F913D37138855
-:10DAE0001B6E48A9B603DEC6BB585CBFA1281FF158
-:10DAF00048F17B93AB7FB49F01B367F4DE8305DD10
-:10DB00006E88730EE60E17B397487A900CD7C979D2
-:10DB100083F63B276A9064E9E47DF9886904F68717
-:10DB2000FACA791C3DB699E9B115426C3DA6D9995E
-:10DB30009A1E934DFA417BD60D996E38A7A5A4780D
-:10DB40008177E119B478C1BE7BA5EE8E24C443353C
-:10DB5000E081A4CDE8F55F7F3014ECC7FC98FC664B
-:10DB6000D65F0B7AD7735F2AD0E994AC0E9803FC8A
-:10DB70007438F67A3EE9F1AB1E033E58F03B51D0C3
-:10DB8000EFA7945C5889EB69F18571F82C6D988E3C
-:10DB90007C4F200AAEF3C34E36DEE706B84E36F0B1
-:10DBA0003C80463904F919271BEEC3FB4A20CF5BA2
-:10DBB000D4EDEF933C15ED4BED9EB193A17BDCFAD8
-:10DBC000FDDDE25FD87D60B7C6E3AFE2C6D87E3D3B
-:10DBD0009E35828D3CE2CD027B98DA373D11B07FD5
-:10DBE000365ABD41122D071FB7C7CC4F5CE29AFAD7
-:10DBF00004E07D89CBF70CC83971B27B41E3F3397E
-:10DC00001BF7046C02C37ED3533C4F53F2BBF5F7B2
-:10DC1000BBF5DEC7C9E324C416E7BB43FB7D8338ED
-:10DC2000DFDD2C9F8378627FD7FC8484A89FD00A95
-:10DC3000F3A86C3853F701E289FB091CEE533283D9
-:10DC4000FBD4F356F63B3726BE38C5F34716090C0E
-:10DC5000AF1A7F9FEAB577FC780F8D99FF848D57B7
-:10DC60006D184FFBFDAC5DC6385C05E51FE01B6120
-:10DC7000E378CC5F171E1FFF18E4257D7E44C4EFB8
-:10DC800065176CF8BDEB67DE0D7321CEF3868CF75C
-:10DC9000757FDE3E3591C5798C71E8856EB6CE9F75
-:10DCA000E6725F7C6135F2672F7FD42F5440AE8AD5
-:10DCB0002F3C8AF64CF11601EF8924C19E43932430
-:10DCC000CE8713A0FDD969CB01DF13EB717FA3646D
-:10DCD000B3D5BB5AE84BE7D32ED570AF7A49E71AD4
-:10DCE000EC97507B2A45B7DF7D8AE701975C60F7A8
-:10DCF00003124F90A401DF73BD13E55FE3BDAF5D79
-:10DD0000F6D871F66FB83D537C6182C16F88CEEF53
-:10DD1000FB4C3EF97A5ED2398EC1D53B9F0DE36351
-:10DD2000CD273A8F89D8BE2B29F6F8991CCF276AC0
-:10DD30004AE1E406295558BDE2FAFB14D027C58D07
-:10DD400049C9826E5E250DE5863C8C92C622659E91
-:10DD5000AEDF281D1CBF9D343C4A87CC47E5EB96BF
-:10DD60003B61BD2F74B961BC8D8BF27FA2427F4CA9
-:10DD7000FF7C22D76754A37EB9C71DEB5C43A65B2B
-:10DD800035C4954A1A387DA89D9CA7A38F46177362
-:10DD9000FB134D25F93F8178F293EC5690F87AC742
-:10DDA00044B7CCD8789BD08BB72CCC07BA34DEBE26
-:10DDB00063C8FBE983374E5F0D2FDA7B6A1FE502EC
-:10DDC000BE2640C0A93FF4C3E87F297C45C7E5F4DF
-:10DDD0009F147B1EFEDE792C25416A3F2CB8E43C63
-:10DDE0001E2441DB45E6A1D19F5C6DA0BFFFD11190
-:10DDF000D7811C6AF45E70E049E4DF05541E615F60
-:10DE0000FE64FD7D86F5210A5F1CBA0F0F92ECFCC3
-:10DE1000FF7374FF440E6640DE57701D5B474E6D06
-:10DE20007C24438FE725AE490B812E6453FFCB5AE8
-:10DE30003F8293BDED2AAE4B32C6C376BBFC0137A1
-:10DE40007D5FCAFDEA1549D346C65AF7A95F381166
-:10DE5000E2CFB535D32742BC4DE67623FCB216D8C7
-:10DE60009B70057AACFBB5EA395D1FAAA9C6F835E7
-:10DE7000B10589477FDE9730BBE81BC2E22D5A3BD4
-:10DE800045F67B20FEA908A410ED39C9BF32330F37
-:10DE9000E2182939411DFE1E7533BB6E4DDA010FA4
-:10DEA000E4935A69FF108FB1A54BE78DFB94AC9CAE
-:10DEB000238C97613E724A98603C339BBED7E15BEE
-:10DEC00049A1705EC4DF946C6EDC2F9208B3D3B4AA
-:10DED000F9D337B89E3DCCD7A5E510C74D013BCC53
-:10DEE00082FED07A1EA7FC654D21C78384EB98354E
-:10DEF00089D5571219DC76885B8BB0AE46B0EC82C0
-:10DF00001B7644BC9A0C7F7F3489A8F83B7DFD4882
-:10DF1000A40EEF3199D4793FBCF725F8B7001F7CE8
-:10DF200039B0E34301E2D085FE2B61FD6D108339EA
-:10DF30002AADFF2BB12707EAC1EF7BBD9FCC9E43E3
-:10DF4000206FD9AFDB9762F772AAFAB89EB93C642A
-:10DF5000A964DAAFF9CB95FAEF4D09BE5D0047CA67
-:10DF6000C702EEC3D4DAD9BD3EB5AEDB1261FD3EC9
-:10DF7000CAE985F407FE696776CC79494D4CC6F845
-:10DF80006656EEEB86F1BD86B2C4FDB74D941F25F3
-:10DF9000DDBDACC3259F05F865443D7DAFA75F8C13
-:10DFA000B85AB213AFBF8DB90FA3C147C725803F81
-:10DFB000F1C234B6BE9AF8608FC0E00FBAB8BF4560
-:10DFC0008222D0738E765FB0B48295B5DF8B002A43
-:10DFD00052383ED0F617C80A56E6FB9481796C1F7A
-:10DFE000D20CCF9CB6873B20AE3FA76DE07CD89F7C
-:10DFF0009AE31CF96778EE917B0E24801D789F8050
-:10E00000E73F7EFCFBD7E504FADCF9CE463C6F7CAB
-:10E0100096CBDD5DA407EF61F7130FDF270FE1FB60
-:10E0200079F00373580ECBE0A7CF8D847E74032D57
-:10E03000DDF97AE80630DBEE6AEFF90DA8017FD84A
-:10E04000330DF700B476ADDE43ACCCDA45F160E3D6
-:10E05000F6A80DE7159DB70DF1F0416FDE7810E9D8
-:10E06000D18B277EAF928697DE7927DE3603E2BC1E
-:10E07000F1F4D91C67D69FD9E60783CB8CA7CFE1F3
-:10E0800013B5233F77FBEC8954BF7DECF639E0599B
-:10E0900061EBC99086A2BCB8A15C25FA87A4523C6A
-:10E0A0009C1DECBFB23FE0A3A3DF65E9D10FED4CAF
-:10E0B0000F90BC0C9C8F76EFFBC1074EBAC0EEAC44
-:10E0C000DBF95E063C2BC5CEB5B7637C53447FE8D5
-:10E0D0007CCB95173D1FF621C49DE8FA372251E30A
-:10E0E0004336BFBBF9F99ABB5B12F07CCDDD4B45E3
-:10E0F000C3BDCD772F65797744EA187DABC15E5FEC
-:10E1000011B71F880398FB99BF7432F9B81FECB39D
-:10E110007A26615CE059C65FF3A7F844C8479EB011
-:10E1200052C078CBF8E36A6B272DCF0F25E1EF1DA6
-:10E13000CD7F60492EDC4350D5C1E27B03C4C53995
-:10E140003F83F8C901B68E437931C8B7D3A73A7572
-:10E15000F1FE2EB93A07EEDD0BDEE9F401FF14DD26
-:10E16000EAFB007F2F91C721B47575574311E6B1C3
-:10E1700016CD55C701DD8BC276FCFDC1221B911C5B
-:10E18000548F1549C406CF010A91ECF074101B3C62
-:10E19000F397B37BB28B1B66A17DE01E57A8C0FD31
-:10E1A000B7456D2F7C01ED4BA4C87E76AE85E1A707
-:10E1B000A8EDF0D7C03F0B7D859877F89D2D8AC1DB
-:10E1C000FF1B153696AF6935967322C6726EBBB1CA
-:10E1D000BC15EE38D3D91107F65A719D283FC3CE2E
-:10E1E000E9BD2AC0DA04F1602BCA5341795B3EECE9
-:10E1F000479F79C96581EF7BFECAFCDE9EAD76BC88
-:10E20000EF6DFF1F1CC40179852FDB37C2F7338EFA
-:10E21000703EC4E1687DF63B5B85E191E0BFBD7275
-:10E22000B5E6A78746C3BC5EF91BCB93E9D96AC59F
-:10E23000DF4F39B3FB8597605FECCCD62BD0CE7A1D
-:10E2400055085AA0DFE02A467F339F966F31FAC502
-:10E25000F727327DD32D307C5FD9609CF755216341
-:10E26000F9E789CC9F9A4774EF3361FF5EAD4B832A
-:10E2700075F5B9D8F70D3FC4E5E2C517158D6F45A3
-:10E280007E3F1B5175E797F644F7EFEEBD02F22A89
-:10E29000001743A3EFCB4DE36AFD1726B27DF814B8
-:10E2A000BE3FD3F38688F8396DFADDC25EBBAEA6F9
-:10E2B0007AE014DD3A54DCB03FB508FCA3C6FDA9F2
-:10E2C000F374EB4BC5D683A977605E9284BFCB54C1
-:10E2D00031E7F94727A4C07B310CF0C277887B7502
-:10E2E000857FE3867AD4DE1D23EAF05ED270DFC03C
-:10E2F000293A39FD8FF2A5264F15DC3ED935AE639C
-:10E300001AE4899737B0DF6F2A0FFFE816F8FD454A
-:10E31000D2C8CE99E64BA450A4F253B1FD473F8436
-:10E32000DFE30A3C33D60BF0D02E6E85F7E5CD9FA8
-:10E33000E27982D5A6DF11D09EFB387D69FD888504
-:10E34000D65F7D9BB314F413EDF775281FC8DA88E8
-:10E35000F79BB84FB1382D7DFF3EFC24CAA9C9C137
-:10E3600037EFA04DCF90F0BB3764C2BC8D7C46F92F
-:10E370005600BBAB67B380BF6B4B2DADFC9BC1A4FC
-:10E38000F62DC3BC5BFAFDEE58E79D17858CFD9812
-:10E39000E9FF07CEBFF42F4BCF47E67AFD6606F1C3
-:10E3A0005C62C552AAEF74767EC5F17ABCCFD13CCF
-:10E3B0000E06E174F906B05EAA28DF76EDFE21C1F3
-:10E3C00096CFF36687B132DE5B08FC4A19A5FC6A7A
-:10E3D0003245057CDF4CA6C3F35521F2A828323D17
-:10E3E0008171A06D09A827BA3C9DCF3F0DFCD53C9B
-:10E3F0000AE34F83F879CF2E3582F73C76F3F86441
-:10E40000978795CBDAEC980773E6AC827A7459F863
-:10E41000A01BE8D1F592DD02BF4B7A667BBFC990A5
-:10E4200027D91566F7FF9E0EF7C3DF7F8DB76E996C
-:10E43000F581B64E1E837FC27A9AE8FB06D65BB2A0
-:10E4400082E5910EE8579D13EBF724B476294A75BF
-:10E450000EF829FF1B63EBB5D4008000000000001C
-:10E460001F8B080000000000000BDD7D0B7854D5E9
-:10E47000B5F03E73CEBC92996466324926218F096D
-:10E48000841020E024860814EB24040C187542D173
-:10E49000A2B638804080BC44DB46A55F26244242B9
-:10E4A00051428D08087140B1F48A6DB0A8C106EFE1
-:10E4B00080F86AB537DADE5EB5FDB92370295A1ED9
-:10E4C00023F452DBDBD67FADB5F799993349AABD6A
-:10E4D000F7B6FFF7FDE9478FFBECC7597BADB5D722
-:10E4E0005A7BADB5F744BE6EF1EC2D60F0172850A5
-:10E4F0009C8C5DF2BB3C9BA0BC4482573318333AE2
-:10E500007C465B3A63D672C6BCF0CFF186BC5786B8
-:10E51000FA53B2E79BB6718CDDC57C0686CF72BF1D
-:10E52000818D853E9DD0388BB1650A0B290E782EE2
-:10E53000F4BE2F4DA53263D07FD92E29D801FDEF2F
-:10E54000DA6C64CCC4E8EF33F8B7A217CAC5B1F2ED
-:10E550002A16343019FE63575C3B187F95123A2A0D
-:10E56000A530B6DAC442C930EEEAA7B4FDD6B01081
-:10E57000C1D370E03363FCF8303FC600B4FF64EAF7
-:10E58000BCBC6EDB34C69C0628C3BC236FEB8388FF
-:10E5900087FF907D34AF35CC4FE3DCDE5AC54EA506
-:10E5A00031D67C5F6BD65DF0BCD87A7FD65D5743A1
-:10E5B0003DC201DFB730DE9FC1BCF601CED654B3F9
-:10E5C000502EC0B71CE69B5406E541293405CB26E6
-:10E5D000164829E3EF53CBF87CBD71F0D5B31EFA92
-:10E5E0005EFD2EED7BF68B34C267031BA27AF654D8
-:10E5F0005C3DE0A341E0A1E100BC8FC3C3CC03526A
-:10E60000C07A1596821D19005FD359C63641A9E913
-:10E61000D06746CDF8AC8731C04366126366A0D799
-:10E62000A3125BD45F42FD26D64D8136F8771D9646
-:10E63000DBA9DD0981BF476F5991E587765BEC5017
-:10E64000CE16089E0EDFD0E1C7A91C32C17792AE6C
-:10E650008E96A9BE623D2FD7D98A6BB6E730B64DEC
-:10E66000EFCFB2011297C9BED77480BF271DFE5BE2
-:10E6700090DF96E9BC790ACE97798B7C00076BE531
-:10E680007878ACAC65624B490CAE187C9CBEDBA4C0
-:10E69000FE900EF82C7058F2EC7323DF46F47E4B9C
-:10E6A000AC5DB34DA279A41E0BBF3606E9FEBCC417
-:10E6B000F642BB1DD287AF8D817E3BE6B9590794E8
-:10E6C0005D4027B90CDFB34E09F0527EA8EEEE573D
-:10E6D00091CEE5499EF1F0683C5429375A68FE779F
-:10E6E000FA009ECCE4963D3AA8CFBCB3B80CF91B17
-:10E6F000E67DE702787FAFCD4DDFCBB270BABBD6F7
-:10E70000070AD696E0F77D77BF0ADF8B4C49F2E027
-:10E71000F733015756073DBBCCD88EB54BD8EED159
-:10E72000143E7EBA4EBEB30ECB65BCEC582779F7CB
-:10E7300012F36DA579671A590DC289EF8325B46468
-:10E74000BC07A93EC8E93BBBA514C7CB1CC79F4E5D
-:10E75000432807C7794BA5F760968E6520BCF0DF8C
-:10E7600000CFBD072B331DD0FFAD732645970A4F51
-:10E77000176343D84E0959183E0B8B797B93685F1A
-:10E780003A3B131783334FDBEEA2DE9B7A35E0254D
-:10E79000F08ECC901EBFB37853EDD0EE4B063E8F7B
-:10E7A000443AF6217D603ECD9F02E46971745B744A
-:10E7B000C580E3357FAAB0E0D5B1F7E7DA4C2C5835
-:10E7C000142B37D41F9B8BED1AD9D006E4ABC6FEB1
-:10E7D00064168CE3F72F258DFC5D95BF9B3FD5B16B
-:10E7E000401AB16F8ECF8AF8896C588EF01F91D87D
-:10E7F0003E86F5061688FB7EF3A70E6D390A67067E
-:10E800008D136BC7B4ED067E4FEDD8F4700A7EE72A
-:10E81000822D9CE210F3C37ED9326B41BA5C0CEAC4
-:10E82000027A58C717DCBCFE226335FD96587B750B
-:10E83000BC0B8B0C2C44788FD0B8889700C8B69D41
-:10E84000839F18DC506E183C4A7851F9211E3F8195
-:10E8500038B991D13114D2C19AFE856D55578919B5
-:10E8600048714C5DBF6BBABCB3A05ED669D67372FB
-:10E8700079747D93587954270B79D0D0553D2BBEB0
-:10E88000CCDBC7FA37D654C3FA2F2FE1FD4FD89A05
-:10E89000DE58AFC4E411CC230FF1122D9B12CA161F
-:10E8A000284F892BDB12EA9D09F5AE84720E6F7F2B
-:10E8B000CE1ACA933D8C7D645B5BA3807C3997152F
-:10E8C0005A2C417973C7BD35D520E71ACB87BC32A6
-:10E8D000CACF41C923B118FE9A3CCC1B04FC593C59
-:10E8E00061C3B212C4C3D06BB8FE1B06249B047C68
-:10E8F0006EE93F18A232F673C7F5EB97A85F43FFA6
-:10E9000087D46FD4F18B75B48E37159FA4768000B1
-:10E91000DB69A0D35799C45201A5058AFF8FA8BF10
-:10E920001AFB7FC3F52E8B18F8FCB81CBC90E57D54
-:10E9300085E4E011C986EB2ECA7738AE25C6EF6AAA
-:10E94000FB5F4D19FC571C26F9DE4FDA1568FF7F77
-:10E950001A7F338D01A97E854D66A05C0D4E447DE6
-:10E96000BC93F927A21EFA7AE3F8A33A6877421F0C
-:10E97000DECD005FC5F64D350AB43B610DE74A2098
-:10E9800043266DEDE5E5F4F06EC46760EBA384DF2C
-:10E9900013B9E15C1D94A7DA43BC3C3EBC1BCBB76A
-:10E9A0006E7D8697A7847365E83F3670A0A61ACA65
-:10E9B000FB6C23AFD77C3B97E32A7C97C779B3EDF9
-:10E9C000E9C8765C4FECD603C6401E2E5EFDF1B35F
-:10E9D000FB000F8BEF4F2639B5EFDC57E6FB68FEE7
-:10E9E000019F5201F290B33ED763248F15B203B258
-:10E9F00050773962F4B0E60DB949CE4F6A3988FADA
-:10EA00003E737109C9F94F53BDEDF669B1E7271996
-:10EA1000F00438DAED362E97659D97DA3F6025BB16
-:10EA2000678B99CF07D60DD1D722E8512EE6536ECA
-:10EA3000D7D133CF3687C6FB40F2EE30C9F8640138
-:10EA400033D2735512D91977EC01B90072B957C096
-:10EA5000DDBB75623000E3DF21311FCA8D5EBB373D
-:10EA60000BE5C30B7F91EFC4F9F69642199E3F1652
-:10EA7000F2BEB7CE9B658FD38BBD7B78BD2A777AEC
-:10EA80000B787F55DF6476F0EF646E99B817E791E5
-:10EA9000AC302F96972F2ADADB4E7A7B01CD9B790B
-:10EAA000BD5912CCF7F4AAB13AB42355FAA4157A99
-:10EAB0006FC2F9DC8EE35B627452BFDF8EF346BD3A
-:10EAC0002F83DE87F93EE0F0D3FCC10E984A76A092
-:10EAD000B003DA71BED362F8654A781ABEFFFF0848
-:10EAE0004FF760FDFF144F23C88B00B66B6C0579A0
-:10EAF000A18B9317027FDBA4903E93CB0B0FEA39D7
-:10EB00007CBF00E4E3ED36FF468447FDFEE2071AD2
-:10EB1000C9EE53E14AFED68B355F65C3D759A25D76
-:10EB200076E203D366067AEC84A19FE4E289F9CC0D
-:10EB3000D38EF243C7EA118FAA5D5971FF9AB718B5
-:10EB4000D8B397ED32D1B95BF266E1BCBA81AE269B
-:10EB5000D4C37586E0BE82985EECB50777AC40BA48
-:10EB6000DE52E209B8493FD27A0BB42653BB5E7B32
-:10EB70009829583FC36D034890CE448FC86D86E0F6
-:10EB80005E09E9CDF9A577D5A4604022BA07A8FFB0
-:10EB90006D9C7F7AEB18D9F7BDB7B9886FCC2C681C
-:10EBA000467846E3838C0E467CC414EFD43A6B0C53
-:10EBB0000F3F13EB3AB93CFCFCBFA11DB9D94C7611
-:10EBC00024EA4CDC77B19E4C8217E8F902F187BA4F
-:10EBD0005F7A242BB889F6679E0AA4C746AB7709EB
-:10EBE000C1FFED6437C2BFCBCCBA4C65B8FD609DA8
-:10EBF00024EF043CACE73186F6D99DC23EFBF7FA20
-:10EC00004B56B4035EB573FB0A19C504F26F29E3D2
-:10EC1000F54BD7257F88FB99A5EBE49011F62BAC3B
-:10EC20006B8E371CB7CF208E82F1FC425EB2ED11A5
-:10EC30002BF28D1FFBA5E0F87FB4BA2D5886FE534A
-:10EC400091ECD0BF38D6FF3DB16E17CB1C7ED69667
-:10EC5000EC46FC26CAF5F754F87A1EF3C67F4FFD42
-:10EC60004EE2B8B08F7B1FF105780FA5A23DFF6D76
-:10EC700099E89A08AFD31079C80CF58BDB64FB7A5E
-:10EC8000C0A7BFD54AF355E1BD3333722DEDAF12A6
-:10EC9000C63F93DC54A1E0FCC5FE83ADD3EEBF18A4
-:10ECA00033C4CAC017CB5984F631C3DE8B7D6BE207
-:10ECB000BE8FB1BF18E3DBA9EB85B9A504F8055FEA
-:10ECC000B92505E9E69738DDA2F44E805BC5A7ECCF
-:10ECD00018199F4E433817E595BFD5487848ECAFD3
-:10ECE000EABDC7CCB03E80AFB64B12F1E3F6FB9263
-:10ECF000498F3113A763F3EA2437F2E74E43E469FF
-:10ED00005A372F1919D2F5A239F202C9A342EE37A8
-:10ED1000B8F833790FB6BB90CEF9FAC2613DAD2792
-:10ED20000E0CD83B3F93F752BDC4C7BDD09EECC676
-:10ED3000F5D88C9884EF3707FEAB8D01FE4EE9F8CD
-:10ED40003EB87940BBDFBD00FFEACB6272E122E34F
-:10ED5000DF090C703900335D45DFB923896D82719D
-:10ED60009B749217EDA3A6D593821D9C5F4CB85E51
-:10ED70001A04484D3AD8F795C5D67793EE6411EE4C
-:10ED80009B1A4C9B87E414AA3F8EFB2D86FB25E83B
-:10ED9000B71A3B150CE7E7A6CDBFFD33C2DD7448BB
-:10EDA0004BF786187F489F49D83F8E5F0A627C40A8
-:10EDB000F635CA876A161C2F713F0C96936B8682B4
-:10EDC000E8876916FE89F463E1B9C81FD6F27EB6FA
-:10EDD000149ECD67B97D317370CF2BB8CFB5D70CEA
-:10EDE000E5E2349B5BD75E7DFAEA187D5538670C07
-:10EDF0006E9571FFA6DA2571FBC7890BA6C43FD7B4
-:10EE0000533FDC8FE2F7C2F80AD785C2F5D936A1A5
-:10EE1000CF40EF91DC5DDE3381F41EEA25945FEA9A
-:10EE20007E16E519CA8F271D558B1C30CF92B4AAC8
-:10EE3000AF38A6F1EF901D8F9BA019C3F199A85789
-:10EE4000D476B8AF6DB18CDE2EEAE7D991CAE583EE
-:10EE5000225179C54FF57B36117C0AF1CBDADD05FD
-:10EE6000246F557F4C83F043AD10FE9B15C27FB3DA
-:10EE700072BB91B9E3FD55416DB941ACF74616E659
-:10EE80007EACFD501FEFB7A966212BD6A3FF069FCE
-:10EE9000FDDAFECD2C385B41FA0E7C668C7FCF7A92
-:10EEA000F97CEF1474DF61E67E9B99EBF6C8DC1900
-:10EEB000C5E79B5AE62D7810F5C49B7AF22FFC87A4
-:10EEC000A0938A17A3A3EAEB88EF24DC8F61BB072A
-:10EED0008D8497D3A08F0F0ABFC602DC67B6F9B343
-:10EEE0000A0B113DB6BC05D6E1F8DDF492B91EF966
-:10EEF00065B343A7E1A72A879ECAE4EF41BCB727C1
-:10EF0000935D0D689E8A7C543156D5936C2AFA998C
-:10EF10003ED483BD05E5A65B2D7E1C2F8C76019427
-:10EF20007708F9B5C361A0F1D472741F27F805BE44
-:10EF300043E3A1DFC517C707C168FBADC25EE4723A
-:10EF400061DBAA24924731BED531E2DB129F01FD7D
-:10EF5000452F0939F2122094F651FD662E47142EE2
-:10EF60009F5E3A3B89E4DE1B1FAF26B972695112DE
-:10EF7000334AD4DE2B61FDF3C6E07A28DF25FCA8F6
-:10EF80002F49DC0E0C1CB1D2380D06FF0EF42B34C9
-:10EF90003C37DE0314632F1882DF7F1AEB5F369352
-:10EFA000DFAA2185C3D9F0D21892933FD6079FF9E3
-:10EFB00001F9218C649F3524B953A9FE27690CEB14
-:10EFC000BB92FD8348CF6C23B71B1B0CA1223BE0F7
-:10EFD000F16490DBBF2751D0E0F88356B26B00CCD0
-:10EFE0002CFCFEA9EE4CCF26770C2FA71E9A4CFCCA
-:10EFF000BF4DCFE91638CCFD9A27F5BEB959503E22
-:10F00000F97CA907768EECA2CF1032008CCD5BB8CC
-:10F01000BDB64CE7EE6B45D9F472B247B3DF7C78EE
-:10F02000652DD637AF5E7713CAC1D1D633CAF37810
-:10F030007FED0516C9A3FD66FDD8FE107CF7C2E082
-:10F04000440FA947E60262039FD878DBD37AC03722
-:10F05000F2D7113DF1EF171D1FE78BFB3FD42FF8BF
-:10F060009D6690BF513F32C9DFB8B23C5299D3B3CD
-:10F07000F9A54C619F69EBEF48F55F40B9D6F4DD27
-:10F08000DF9F6825FC4648FEB11EEE1F3FADF72E00
-:10F09000463EB557870C4BE3F6B78634BE8E9619BD
-:10F0A000855E672143FCBA53EB2BAAB47CAE3EF5D8
-:10F0B000697C1F691DE2727C78BD4EAC9BAF185114
-:10F0C0006F71D70DECA7CF727F8621CD4DF533CF71
-:10F0D000860CCBA09CBF2E6458219EB82E00DF2149
-:10F0E00013CCFBF40E2B5FCF80061C67C57446F66D
-:10F0F000C80A19ECD0327CEF1E08035DCE3C6FE7E6
-:10F10000FCF527C00AE07B0913ED8C60B782DC7A3E
-:10F11000B1530AA15DBF64BB71AFB900D7B157B697
-:10F12000223D774B24B796745616ED80F2EA43538E
-:10F1300088FE29D3395FAE0EDA49FFCD147270997B
-:10F140003168203BFA19EEA783F1C91E6E804E5933
-:10F1500065C3F180F25BC30F416D9C6166BF90A7F0
-:10F16000FBE3E20B63E3E47A7F427FB0E3B4FC119C
-:10F1700050F50E9773CC9D89724E95C34687AF3478
-:10F180008DE4526126D217E8C9E5E44189F0DAC876
-:10F190005AB8DE10F23EFA5DA12FCEC801AE978CB0
-:10F1A0005BE93937AD80E8B61AF50DF9CDF9FE6E99
-:10F1B000343E989BA6137271643EB85EF041C35909
-:10F1C00016BA16BED7B08E851AA7F2A7752AE941DE
-:10F1D000AE0F4D229E61E2F18ECFD38B897A70986B
-:10F1E000DE4BD0779906A1DF049DE3FDD9A8EF6738
-:10F1F000AE0BCAE8D7CCB379AFCD4C8FD92FCDEFBA
-:10F20000994CEEABB0EC63632DE89FA97CC685FEFC
-:10F210005DD88FE3BA4A06BCEC81F7BB55FBD6C577
-:10F22000E7EB3270FED52B3E566A41BA0CD17E35E3
-:10F2300092CE6CC88F2A3E775BA15F19F6E3EB2D67
-:10F24000DADFC43A93E2FA57BD6426B97AE5B035FD
-:10F250006824BBC39F6F87F1327E65243BF4C24BA9
-:10F2600056D29F1784FE73AAFB7EB681E8D38A74B8
-:10F270004D476EAA1A83FE5326CD1F832250B5C375
-:10F280001AEDA3F9B3457DC1D0AD9CAF8CB45FBC82
-:10F29000620F7F13CB000F43FBBA05E98CFEF643E8
-:10F2A000B34B1F80F7CD3E8B8763DF5F8AFC6A9488
-:10F2B000EFBD15FD2A73E57591FB601E8DB9169B98
-:10F2C00011BA54E7FFFA97B741F9A3437A66443A73
-:10F2D000EF9BBD888D1D5DFEAE0AEA4F86E3D6CB5F
-:10F2E0009AFDDA7263BFB6DCCC9493E13879FC58AE
-:10F2F0009AD5796632C90ECF67C0DF4663CBD93D58
-:10F3000000AFF1C746D2470D69FE5D69E837D545C4
-:10F310005E433C1BF3CF4D453F4555FE9F28AE73E2
-:10F32000E5DBCC83705F315792FEBEB2C3EC0EC4F6
-:10F33000C9AF66C1FFBD79B554DFBBD3E896787D10
-:10F34000EDB40AB407E9DBF867D201FE9BB7CFFB47
-:10F3500088F64D68B543B917ED4BECF79C146C4734
-:10F36000FB713BD77BE7C17E34A1FE14EBA9591E8C
-:10F370009C6B82FFEC75D44C44F9A2FC59F121FD41
-:10F3800037E25071F6EEE1E8FAE47E9C1BD08F3351
-:10F390008EFC3887516E349AC2864A18E7BA3FFF0E
-:10F3A0008EE4F2CAD6A564D7C7EC5C23C99195F761
-:10F3B000F9E9FD2B3BAEA7799D8179237ECEECE662
-:10F3C000FBB995399620C2779D9DDBBF2BA19F2469
-:10F3D0000DC74B221E7EB3EB7A17D2FB378C7F2FE3
-:10F3E000D0CFED84DFD8865248FEB85B52D0CE6BCA
-:10F3F000DE7EFD4728B756EE963DA8C7D9112BF9FA
-:10F400003D56EE9E3371B905C7B99C568978EB9B82
-:10F410006393E9BDEC0B72FFC9D075F05EE9BBC622
-:10F420008DEBE4F86E2387CF6E7A1AE1BFEECF3210
-:10F43000F1BDA2637EB4577B0DDE89B8DEDCBBF67E
-:10F44000CD45BCFEA62E5B47ED9F95980DF1606FF4
-:10F45000CDC0F72B25C587EBAB7EFBAADA787BA462
-:10F46000334D267C57E6AFCB085B88DF6F453DD731
-:10F47000B85B4F76DDF1051FFCF236678CDF57CAAB
-:10F480003DB7CE8CB3379A77DD28F8013436E06982
-:10F49000A5C093317F5D117EF7F3F87FE5FA9622E0
-:10F4A0001E8FF9EBEB20BABE77F1F5F007D0F7B479
-:10F4B0005FCF7168ECFBD1F641AABFD9E461DE7D74
-:10F4C000168A1B7A719F9BE754A83ECFC9ED6CE565
-:10F4D0000F6BF7BF0DF0F7A7F98D4E789FCFBCA546
-:10F4E000485777C45605E6244E89EC1FB6CBC8EDC5
-:10F4F0004985FBDDB6A5B3A737C5C1998DE3A5D373
-:10F50000FAB43961DC0BEFFFE935C45F53DEB9A90A
-:10F510003C9EF63B8A4F590679DCD2E2F131E48B0E
-:10F52000E6C13A7657494C1E367BB8BC4E9CD77222
-:10F5300027DF67343B23344E753A5F67AABF77678E
-:10F540006B12F9F5763A8366BEBF0D3094E73795B6
-:10F55000CB3CDE22EC129FF09399BCAF308CC730CD
-:10F560008FEC190FE521EFA9CE3428BF5D3EC723EC
-:10F5700043D9E27DB26B2CCEDBA317F5E3C85FF86D
-:10F58000D6AC4AB24F6EF2CAF45D569F42FBF521EB
-:10F59000EFCF9D77C1776F66DEB4D3F08D1A50D66A
-:10F5A00048C721FC36DA018ABFDC19E75FBDD133D9
-:10F5B0002FED74BCBEF472FD8FFBF17E113718097C
-:10F5C0000F2569953311BFD77D99D3E1E367F9FE24
-:10F5D000E36333F763ABED3EB6723D53EB94841DAA
-:10F5E000D89F87723E5AFE5AB1260EEC34F4E7E1FA
-:10F5F0003AFBADA41D6775978EE2B3ABBA18C5632D
-:10F600003FFEFE8B79286F3FDAF762DED238F812C0
-:10F61000FBA9CF5B9D5ABF94EA87748AB8F4528FD6
-:10F6200091FBFB46F143AAEDD976BE1FBB08D21D64
-:10F63000F94EED77B13EC98B76E545662279B67411
-:10F6400050F835BDDE4227EE1FD4FE09E36F41FEC0
-:10F6500001B8A40189F6E7C9251192AFAB4CBED71A
-:10F66000C6B8312FC54BF499877494905FBD069C42
-:10F67000B722F67946C5D788F45CDEA3A56396D396
-:10F6800026E2944EA2BBA1C9A2A07EC8E810F2FA5D
-:10F690001B3ADABF18B25D16944BD715257562DC9C
-:10F6A000DD99943215FDE6B9D9C5D43E50C5F93A75
-:10F6B00090C1C86F95C55A2492B736EEE7CE99CE61
-:10F6C0006C98E7F1A293DB832EE6D92E933DD82FD9
-:10F6D00091BF5FCC5F95EBC82F28E73E964CC42FB7
-:10F6E000D2A044F69DACEB5F8CE38EC63FBD09FC17
-:10F6F000D3FB0FE69F3EF57BC3F8C74F71BAA52E2B
-:10F70000D3C8FC23FCAA5FB8FD6871C26F98543F50
-:10F71000B384F3AD15E3D59A2C21792AC98773F107
-:10F72000FED45D6067E27E448D2B8EE958E2E6767A
-:10F73000FA5018F7E5C9D79848CF7D47375480F677
-:10F740007C629C11286B47798F3286FC8AAD55BE4E
-:10F75000D36971FAFE08DF3734DDE7A5F7B307B9DF
-:10F760007E6F2E3490DDD93C200590CE4D3E43D0A7
-:10F770005440719525A4B71F32BB799CC4DD4E71EE
-:10F78000926FBB791C25EA470DF73D80FC566F212F
-:10F79000BF4362BCE585BFC8FCFBE3197DBFB794DE
-:10F7A000C7777AE7B9C9AF911847635DDAF5ABC699
-:10F7B000512E5A0131F0BDA59BCD44876C99E39938
-:10F7C000A59AB87E192E07C85F9B315D1046C43BD1
-:10F7D000A2EB1A240396B345BD1A9FB196F80AD03E
-:10F7E000C2BD3DEDB93793D2FF967C86D6EFFCD5EE
-:10F7F0007C8680B116F3194C683D8B7A041BF4ADFE
-:10F800005AF69ADD18BF89D52B60379A0624F1BDC8
-:10F81000E76F9853087890D4EFAFDFE4B550BC5849
-:10F82000F3BD78F89484F1F530BEC52DDA070ECC1F
-:10F830009BA3505C52D47FD68DF91B5BF4DAF108A0
-:10F84000A5A23F16D4EF1DCF9CFB9DCD3931BD0F36
-:10F850007680297D5A4CFF6FFCA0B6E72AF856B295
-:10F86000EDB201F5AAAAC79B9D3CBF2171BD3AD25A
-:10F87000F97A05FBD5914E7283DBB5B5223E09F6C8
-:10F88000EC5C5C5ACDEB7C0CE393602F64A4631EAC
-:10F89000C3FBE7CE1C45FA2DF898ECF9E64F15EEC0
-:10F8A0007701BB03ED7393E07336A0277DABF2C104
-:10F8B0006A217F7AEDA0EF915F8F48D302C4172DA4
-:10F8C00079B7000DEE4FF7BA697CB1EF4A847746FD
-:10F8D0003AF793341757ED28C2F19F9218EAFB4D7F
-:10F8E000C52733D02E691EFC3063795CBF55038F6A
-:10F8F000121E56EDD78F38FF19E9DCBE6C3AFC3C7E
-:10F90000F9073F0E4AB496EB9560F74C28D7D7EB32
-:10F91000D04263E5C125B791BF7F91818D87F9E51D
-:10F920000B7DD4BCFF2B8199B83F837F12BCDAE9F1
-:10F930005B417A6FE7229305E30ECDC54BEF263C82
-:10F94000D892BC88874DC55559F89DA6BAB9368A54
-:10F9500013807D85F54DF7DD4E7E1315AE4D03FA10
-:10F960001AB4BB2AC0CEFA11C09DEB985FE381F5B3
-:10F9700037463E587A8F05E3C223CBDF7FC9E0F4D8
-:10F98000EC947C819BCBC94FC8E2FD7EF903DC9EE1
-:10F99000AB4B3768FCC275E9DCCE9C15189A8DBC60
-:10F9A000F7B2124E46BBB799793FC1FD25F359DC3A
-:10F9B000FB884E5C8E38DBDCE43F3239C3DFB90AAA
-:10F9C000EB6729B47F604AF811FCEE856EA76713D8
-:10F9D00013FC8BE5FB4A822847FF39DDBF18F9ACE1
-:10F9E00042D88F170E5F5F8A7E36D53EEADE630E01
-:10F9F000621CB0DBEAFE6E0DCAC13F283CEE6D8A88
-:10FA00000CCD467AFCD141E3769B83DD48FFC0569E
-:10FA10003DD51FB6FA5721DF9CADAB29A2BC1B4BCD
-:10FA2000A008E3BC7A670F433B01B60BE44F3039C3
-:10FA30007D0CE3A1B3034B1409E57C82DD315BE46B
-:10FA40008F92F084F755428C8D072E3863A225D013
-:10FA5000F9595ACC0E79E34F0B157CA9DA273A13E2
-:10FA60008F67552F4A6232F2FD86C86B3AF45F3BCE
-:10FA700087C87E6DEC97E83B8DC5CF513ED81A9173
-:10FA80007714CDFF51C2940FB53E3D59E8F14ECEEB
-:10FA9000EF6C88F6CBEC00A7276361CA938AED234D
-:10FAA000DAA99D3A9E41F8DD1B85DF053418D53F64
-:10FAB00094AEDA07EBC553CDEBE2DFDD260D7965B9
-:10FAC000C46BA9A4F117ABCFA7D2B97D987A2C3219
-:10FAD00017D76FE4B09AA7C9F330774C9BE441D3B2
-:10FAE00069589EE6C02773916FC0D0A6F5DA34F04E
-:10FAF000C5F234BF2FF60DFFEB799A1EC9BB179ED6
-:10FB00003F4AB773BF959AA7E9E1F853E36C89F9C7
-:10FB10009917B2420ACFB70AF7ED43FE1C30521EC6
-:10FB200057EDC0EBEFA17EAC35B17E8C4326DA19E0
-:10FB30006DB6AF0C22DF5F3C7FA6EF418679BA2F0E
-:10FB400078285F23C17E48DC27ECC52659A3DB7BE0
-:10FB5000EF46E9C9EDBD68F97FDDDEE3F67C601FA5
-:10FB6000CF0F50E579B3D89F5DACBF94827AE6445D
-:10FB7000149E843C86A7441EC3E0C8790C8AC8073B
-:10FB8000027B3D407C7290C775DE783A99E4C725C8
-:10FB90009BB217EDA5F3D6C83711598AB0933A8FA7
-:10FBA00018DD282F40DE91FC0E1CD4F3380DC66DF5
-:10FBB000308EF3F24411C711F1A29792C96E6948D1
-:10FBC00071A7627F354EF363A16F1A92787CA62BE2
-:10FBD000D97F397D84B8CD1E617FED81A16C38DE7F
-:10FBE0007B4611C7060181FB9D877279DC41C46D9C
-:10FBF0002E8AB8CDA9625DC8C0FD10E4A77277292E
-:10FC00002C0BEADDEF99836EEECF32E940EF2F53F4
-:10FC1000E3362F733FD532119F39B5602EE5072D9E
-:10FC2000C7FC7719FD18DCCF1CCDC767361DCE6722
-:10FC30000D888B9D28620280F56BE0B5A493D09E61
-:10FC4000707742998C656F4F0D7C7769A78EF6238C
-:10FC5000CBBAB4FEF22B9BEEAE41FDBDB193C71FF4
-:10FC6000035D12E9EF65CCEB427B43E587828C3480
-:10FC7000A273A053E7C5EFCCC8E0FE04407D90E638
-:10FC8000279E9D7AE1671770B4335D089F3A893FDC
-:10FC900037DA949A11F5B218AF53DF62AA443B36B3
-:10FCA00057477EDE2B06EF22F2933A8A886E9DD666
-:10FCB00096AE1A5E4F6BE58A39E2A3FA6B156EE8D1
-:10FCC00031B703E564668688DF24CC77798FB69CEC
-:10FCD000187F5815D4969731FF842C3C87B05FFB72
-:10FCE0003E3383CBA92B9B0A849FDF437EFE4EBD10
-:10FCF000FBDD029453DD0AC9C9F61C8E2F5D2E7FF1
-:10FD00008EB5572F22FBC00E7605C1CBE11F7BAD10
-:10FD100053427DD969E77CF93F853B11DECA8C22CD
-:10FD20006E27A07187EBA85B0A727C71B8BFA8BF71
-:10FD3000626986F01708F9132DFFEFEF37393F7628
-:10FD4000CB62BDD948FE2C15F1C65392E7E910BE2F
-:10FD5000B7805D00702FEB96CBD03E99FD150BCD93
-:10FD6000A3E96573D008F58DEBC279B88E9AAAC263
-:10FD7000452D23E015A15554B905ED963A617F80D4
-:10FD8000EBB64B1B871A1E57F47E2B231DF721A7BA
-:10FD90000EBE8EF43E6826BD04FF75D488FE8EC369
-:10FDA00005642F4D4DF5B765A03E4F0AF57DAF00B8
-:10FDB000ED136E1F350E1AF7A0FDB7B4537B6E8698
-:10FDC0006DD6C6B9589783FC19AC57FB1ECFA768F0
-:10FDD000FA0D8B7B713DBFCDE09F8876DD755FE6C8
-:10FDE000F1F5F3AB740CE9BB4CF6AC403972DEAC08
-:10FDF000B5BBCF5B39BDFAA274F614219DFB46A5B5
-:10FE0000B3A708E9BC4CC7FCF1E334229DAFC6ECB4
-:10FE1000734EE7F3CF5F5384743E77F09A22A4F3D6
-:10FE2000367D8F17D7CD930EFF5EC4CFE9393EB232
-:10FE30009BD4BCC92FCA8F8732B4FA305AFE3BF923
-:10FE40003F46D383A1281C5A3DE834B873501E2E78
-:10FE50003519FFAA3EC4BF11FD692623F9235EFEB2
-:10FE6000D3E58751BF050665B23FD4F15E56FCE38A
-:10FE7000D05FF0F27B2E4F401A7DFC066157B94CE3
-:10FE80002C807E0FD5DE57EDC64479FC0B319FD315
-:10FE900019DE1AB4B355FF6CBD18D314BCCCEDD326
-:10FEA000A724F2BF9ADCFD3C7FFEC8121BFA67CF85
-:10FEB00006B93FB6E9F952F2D7AE0ABE12C2FC2724
-:10FEC0003628D970DFB0EAA90F53309E0DFBD0530E
-:10FED0001971F19539621F7A36782A05E3DEF0FD53
-:10FEE0006AFC7EB2336240FE6D82FD1934614D4A78
-:10FEF00084CE0D353919E9FBF201ED7E4D8D4FEEC3
-:10FF0000F41948DEED1C9482B83FCB30F80B7250E8
-:10FF10003FB11CDB99E4D87AF924C36BCB9C161F44
-:10FF200017F65ECE88CB570AEF48253E0CEB999723
-:10FF3000EC801D56219778BCE63F77D9833C7F89BA
-:10FF4000B7FFCF600195557DBD429CC35B21CEE1DB
-:10FF5000A1FC0E25C8EFF87234DEAC9E3703791E83
-:10FF60001A29FE1D97B714DFBF8945447EDE674618
-:10FF7000CDB8D17C9D965237C0BDE66B163A67D896
-:10FF80000C7CDD5A16E3C3063115950F9B845FB7D1
-:10FF9000B9FE24ED039AF17C05DA551ECE870DB02B
-:10FFA0003FC2FCCDC475CBFAB5F98CA3ADE329995A
-:10FFB0005ABD122DFF83FC98D333B5EB579DBFEA92
-:10FFC000078FCE7350E2EB2B615E89FBCA44FFB50D
-:10FFD000BA2FFCA272EDE64CAD5C8B96FFC172EDC0
-:10FFE0008ECCD1E49A363EF037CBB5C4384121F7F8
-:10FFF0007F639C00E3B6FFD338C147EE9E0C1DCF54
-:020000022000DC
-:10000000C3D7C44FBBA4969B4CE330AEC8E3CB8DA3
-:100010005623C56113E3AACDEEB9228E38F4CB196D
-:10002000A8370FE919EAF37ACB4A8A5736CB070C7F
-:1000300078A470583C51394A76FBDF1A575F9F19F4
-:100040008DAB17605CFD15CBE5347F1C3DAB4AC022
-:10005000C02F193DDF68B3A053B2C88B30290166A9
-:100060008FEB3F5ABFDE4C6E27BF22F2635C069EC9
-:10007000C7BEC50AFB3098BF4BC7F377EE4FF76D8D
-:1000800043F9687273FC3E71F8AB0CCF1D3DA1EFD4
-:1000900027391268B478501EAA7E17757C45F80F70
-:1000A000BE28DFFF2081EF7FF077E6FB447C0CA8C1
-:1000B00072E76F8D876D07DC68D607A3B8D75B182A
-:1000C000CF2918CEC7A38D331A3FFF34D3F75A2652
-:1000D000C947EF54CACBFD82F226B93C720AFD3BF8
-:1000E000EC90D18DFB0D933897C13667893C4A4F10
-:1000F000451DE513F3730DEAF98FD1ECC20FA3721E
-:100100009ADB851F8E2AA7FF7B76E1030EDF299CF1
-:10011000E7E94A6F11EACD8D56801FF77BDF378EF6
-:1001200078CE423D0F00FCC4CF9B3CCBE3E0897C02
-:10013000F58704FDF287BFB37E194D9EEA5D2A1C48
-:100140007F67795AFFC714F47B8E3E4E80E0A8A8E3
-:100150001AF28AB815C3B8913A8FE6219E7F96218C
-:10016000F2AAD4F7116117DEE9F266BAA0FFB9F777
-:100170004D26960A2610F218DA633E0BC5039AFA4A
-:10018000799E48D33A46715FF51C65D3401D43BB49
-:10019000AF3FCD5F8079601B3FB004E454F4932FF0
-:1001A0006068EF5D789F971BD2FCE3294F6C5D5828
-:1001B0001377A8F8ECF206F46700BCE41F708AFC21
-:1001C0004C15BE3A179767EAF32681EFE8BC9C1CF2
-:1001D0004ED62F07D14E4C760F911FA9E91037DE6E
-:1001E0002A642FF9EBD91A079D9F683A54594AE7B8
-:1001F000CDFBCDA568E756FCAAD686FE8973D73A13
-:1002000029CF204F0EAF423BEB9FD3FDB3105E6B67
-:1002100079701EDAA9F960A7A2DD7BEEE0BC527FFF
-:100220009CBF7B1BFABB61DC6D56AD3F9B99789EF2
-:1002300078FD5E9E077CD8EA9F8BF8DD66E6F006C7
-:10024000B68ABC67E1E74E5CFFEABA8F9E73BCC317
-:10025000447169552E6CD3333FEA3D559E94883CDA
-:1002600039C007CFD31BACE3F91EA26C716AF3153A
-:100270004F67CC2941784AD0D13B0DEF518848E8EF
-:10028000775F2EE2F0D78B7C0A357FCAA8F8BE8E46
-:10029000EDD9BA9A58FC7D2CF617F177912793FC8B
-:1002A00029B79FC7DA0CC43756585FE41F01BE4117
-:1002B000FACC8A0CCDC6F34485BDA15988CF973FAF
-:1002C000D5113E94BAB7287E928A648371C66D0EAA
-:1002D000774F403F8AED17D7225DDC3DB62A445D5B
-:1002E0007F9AAF91E0505A8A715F59F5AF7A9E07B5
-:1002F000782499FC03BD790D940778E103E388E73E
-:1003000046D46780ADA7BCBFB1033F273FBEF59081
-:1003100034623E6797CBC2CF0D078628BF8CCD7263
-:10032000123E9423BFA2B8AFD2AD9007A353EFD52E
-:10033000E139A8403B23FFE5F85E9B0EE9922FF2DE
-:100340004B2EBEFC5F53FDB44F51FDF6419E0FA4F2
-:100350000F6FC07D97D21EFE32AC60D678C8AE6BF0
-:100360002AC1F1224D3CAF3D99219FE40F8C5BFFE8
-:100370002528E777D99884F2E7A535F9E42F857920
-:100380008E1F619E77BB78FE8E722459877A4BD977
-:10039000CA28FF50B1675411DC8F4219C65923F89F
-:1003A000468D4702B82ED44777BAFCBB11CFD17324
-:1003B00032AD49FC9C8C3877696DFDE0593C7FD2A9
-:1003C00067E0E70C8FBD3C7901F9EDBA1509E970DA
-:1003D000C5BE24DF06EFF78B756B558698CD128F5F
-:1003E000FF63946F39F608CF4B53F49C4F946EE73C
-:1003F0001EF40B7E9AEAA7BCD26B3B4332C5B36CAA
-:10040000A71FA971C7ED6BB6733DD2B49FEFA713B9
-:10041000F7319FA73F8EBAB47649B4FC0FB24BDEDA
-:100420004AD01B7FF3FE8469F77589F649E23E6E78
-:1004300098DD9D30DE68768A9AD75115FB0EF1C3A0
-:100440002B56D50E0A68F25EAA2CE2DC9B493BFED5
-:1004500053224F47CD83C9E870B7635E79E4DB8CE4
-:10046000FC6C6A3E4EA08AEF1B023A139D8773B163
-:100470001ECAC319C3429244F67F98CE7566623E87
-:100480000EF47BDF3596E0DECD3C5D32C943B784A8
-:10049000709B318F83F236833B56E0776EB1D07715
-:1004A000CC98C7713586E2BD3B507ECEAEE77188F1
-:1004B0006CD0B7C8B7D9859C0FCD8B783E879AAFE3
-:1004C000A1E657A878A812F8CD9EB0A200F707DDE4
-:1004D00092FFFBEA79DAF873D2D1F3D1ABC6D279C5
-:1004E00093E8F9B94226EABFD839E9447CAAF91D54
-:1004F0005536BF2D2B7DF87959953FE2E84670EDD2
-:100500003CC2EDF5AA7A03C17F71D57CF2235E5C13
-:10051000A563B86EAA068D9CDF12BEB7337A0F466C
-:10052000D04CF75D08BA7F9EBD0AF42C463FEDB172
-:10053000B69AAB4F036E8FB7F9E879D12CF5CB574C
-:10054000D179C6C528992E67EDACC57B0A2E5A23F2
-:100550007978CFC1E5EC076FA4727AE404965376FC
-:100560001EBA11EF3DB8383ED287F71E14EEACE448
-:10057000F5C883D98C5D9555716380E6CDFD4EB38A
-:1005800063E7B3CB113F8D2CBC6188FC3B3C7F1FE4
-:10059000F3FD900E2E8B81EC1997C8B364D522EF32
-:1005A00012233050EEC82AA578B585B90F0D617DAC
-:1005B0000E3F2704F5C4BF1DE3B95FD824E8CA7213
-:1005C000543F523880F2A9A3C04EFDA372F490317B
-:1005D000C8FD59FCFBEF3C3F85E24B6AFE2863B641
-:1005E000DC855328DF445356EF37608A2D17ED859D
-:1005F0000EBDB04B45392DD55F97156717BD33E755
-:100600005B25B80ECEBFF04021CAA5EB0D60B78FB9
-:1006100020877E9DCDE5D045BDA54B023BEDE7296A
-:10062000FEDB719CF79217CFB5C3BC16A5551AEC2B
-:10063000086FE0FB32CAC574416FFB420E9FBDDA02
-:10064000272D87713BCCB07EA17FBA5FF1529EBD52
-:100650007FA1740BC0DD2171790B9D52695F52EC53
-:100660004EC5FCE506715E5216EB7E46FF5619ED4F
-:10067000E977DB06662A8531F87E2EE2CB3F2F60D4
-:1006800077D68DB0DF6DCDE2727B81EC9E827CB43B
-:10069000411A78AB360BDFBBE9FD9C94D672CC3B9C
-:1006A000BE3EB9A51CF5CFB0F7A9F0BE24AE6CE4F0
-:1006B000ED1A4C913C3C9FEC4DF6AFCBC2B8D092BA
-:1006C0000F296EF9CDEC774E60DEC13BFA9ED92939
-:1006D000A85F0AC4B97EE1377C6D82EA3734F1F253
-:1006E00064EE378CE6734DE1F964B50BF939C55A00
-:1006F00091AF30D7C6CFF5CC2D2FF074008837B12D
-:100700008882726FEE7BBE14DCB7B385FE72DF9415
-:10071000D1ED19E6D2BBE3D7EB3C775C19FEDD5097
-:10072000AC2DDFE8D1966F9EFEE709F1E53DC9DE0D
-:100730001D38EF1F4B3CFF313083D9689E4E298016
-:1007400076C7E417B3C5F94E9EA7F74F625FF4E290
-:100750007446F519FB4D7B31FF5DF533CBA27EB2BC
-:100760008B99F21DFCBE00D4571149E4FB39299640
-:10077000C25EB8DBC6F1076D0D30CE0B4BDCB43E6C
-:10078000322C3AF6655C43E526B2432AC69892902D
-:100790006F8E09BE53CFEBAA7C58A1301FE62FC045
-:1007A000A717E2F31DBDED28FA97031F31C6E955DF
-:1007B000A950FEA1F81663ED547E4CF0F7310153B9
-:1007C000E0DB0AADE757AD06A2A7FC13790FEA09F3
-:1007D0008CCDA0DFF8D2E649049FBA7E6055173A67
-:1007E00033C8A52DC655740844B1B02754FE460B36
-:1007F00008DB8DC1FF2C203E27791399C6EF4FF8F7
-:100800007901972791AD0E711E8CC7CB724DD171B6
-:10081000BD386E56F43BFCBC51862843554807F35F
-:10082000FE4D560197CB83AFFF81F4B2C5E3C7EF0E
-:1008300018524C744E465D37B6CEDFBE553B03E7CB
-:1008400059F40D9AE77CAB0DE7590C6CBDC8414FCC
-:100850006F1A8DC7D78F9CE471E33AF94ACDE199BD
-:100860004A1CDF40FF46DE3F59DBDF05FD1D71FD01
-:1008700053A07FC9F0FE4F594D21DD541CA7C21D66
-:1008800026791EA2C9CC17F3923378BFF9221FB480
-:100890003005DAA3BE29D6E66BB0E91E13BFAF431D
-:1008A0009B9F71BDB42E0BD7D53C53E36018C67B1C
-:1008B0005DD0ED7A9DFF77783FDDEB8B8B8EE37A11
-:1008C000AB310515DC0FDDC0421B9098172BFD4F97
-:1008D000D8C7913CF80BAE8B26D93FC101E5F3FA9E
-:1008E0009EC2BB0B68BD7C96356D38BC2A5FA8F0F4
-:1008F000227F209F45F92301EE289D6EEAA744B68A
-:10090000DD60F7E053B583186BE1F9C6EEDCD8BCC7
-:100910008089E69A5A0AD10E79BD3D4072E37AFB8E
-:100920002394D7F4E7317E6736C0B5E8AA4FE85E76
-:1009300013E65A3201ED7B80373D3BFDFF1DBCAA1B
-:10094000BD372CDFF6238326DF76B475A57EB799F5
-:10095000F1FB69660FEEA1FCD9E685160F9E836850
-:10096000C6FCCF728A2F911D87E784E99E13C924A4
-:10097000ECAE2F9A97CBD7616FA39BECB7A81C174F
-:1009800079E5BDA51CEEDEBBDDEA3D27DCBE5BC222
-:10099000F83D29EA3D27CB6D54AFE69FF7EEE17EA7
-:1009A000BCDEE727D07929B0DFC85E60A93A0E5FC8
-:1009B00081F67E15FC933262F9D2DBF4DCDEDCA931
-:1009C000F354209E77621CE8AFC47FBF9AADF59BBD
-:1009D000A8E544BFDE930EFFEDC817CB4BBC7912E0
-:1009E000F0CF3203F7DB017FEDC2B31535ACE5295B
-:1009F000BC3F701E6BF9856E1CF1979FF86BF22758
-:100A0000FC5EC1187F2DE1FC1520A1A4F25794AF24
-:100A10008A13F3ABFCABB17DAFBDFF574D68A70E9A
-:100A20001A892E6A9E5CE23A8E83E7B49EC3E394F1
-:100A3000658267ED48F07C113E8FE7AF4CC6F979CF
-:100A4000347ECF5458C05A16E3F73DC9FE76843F32
-:100A5000CAF71BF87E6418DCB285F8E3D6DB649E27
-:100A60003F9ECCF515C62BB2E0FB75E2FBB7767363
-:100A70003EBAD56A20BEAB1B6CA47C2256CDE30ED9
-:100A80001EF81FDF077A09BF8B44BF85CE523DB2E7
-:100A9000ECC25A6D7C6291458D7FF8F4B81E6F5D93
-:100AA000A83F19AFEF17B1CD9F60DEDB228C63A8A2
-:100AB000FDE0BB8F6747E31813308E715CECD32FDA
-:100AC000027F23FFBF9ABE72D7DDC0B7131E2F2946
-:100AD000437FCE9C8C554F6D85F2F7764EA2F2ABDC
-:100AE0001977DCFB0ED6F71551B91A2F71C1FD46E7
-:100AF00023EF5F5C71DBFC02F8EE71B31817D715BA
-:100B0000EEFB92FCBD75D0CE35756C19E623560B05
-:100B1000F970F16E9E0F7FC355569EE2B9D24D7E9D
-:100B2000A3EA2451FF753EEE5BA5FF568679A9D551
-:100B300063238BE93EC6B21F4FC2F271E993C5230E
-:100B4000C54D26174BA189809F6A076F5F5BF6FD35
-:100B50006CDCC75757F1F2644F65F738ACD75D5A74
-:100B60003CD2B9D09F8AF5143DF724D6E98BDE0F2D
-:100B7000E99C93CF2479708ABEE91FF27B892C927D
-:100B80000DFD8F3E6F81827ED2D95E9EB758656A19
-:100B9000CFC2FDEF4D7E4339E69FDA4CA5C7D1CEDB
-:100BA000489D5E390DE93BDBC4F4A89780CFFF85F3
-:100BB000F8FC9A4FF25290B92C5A3E57F9A84EE5DC
-:100BC000EF6A2D1FC3FAFCD7ECF4CF97AFA3F13136
-:100BD0007CFFDFB1FFA22F69F54A74BC84F596381B
-:100BE000FE687200FFE2E55C0C8E7E5A573998155C
-:100BF000360ED75D8FBAEE220887413744E73EF2C2
-:100C000025CF243AF0388AFE57E1CB05D9C6CA86EB
-:100C1000C3857F8A6A9771086CB60CFC2EAF877EFD
-:100C20005EE688C105DF676350EF6FE0F0EC965A2F
-:100C3000B8DC1076B1BA3F6E52E73BA09D6F45120B
-:100C40003FEFEC42FF05F673964EFA6B70370BBD23
-:100C5000B9D0E47BC80873B8C5BE8CF8E1AB2CF002
-:100C60003CDA27C654BF634C3AEEBB0247C205E4E8
-:100C7000CFA5BC01A077DA9838FB44852B111F4D16
-:100C8000A3C8C344B813F110A3CF10D957EAF9A9E8
-:100C9000E8BC12E6D361E5EB3532CDA8DE5F528CBD
-:100CA000EBE26D699227DE9E7E3B416F27C2A5DA9B
-:100CB00011AA5E55E1417F11FF7EA41DCF90DD3862
-:100CC000662CD99D2ADF640AB80C3A69C438EA8DCB
-:100CD0006374AA7F4E43C7C4734E2ABED4BCA044DB
-:100CE0003CA9793DC3E23509F1C8D1DA49603F8FAB
-:100CF000710CC79F1AEF7144FD5C029FA512C93F9A
-:100D000087F073CDF6F0F309B5ADFC9C7C6D0D4C0E
-:100D10000070FFB6F01FA8787EC8EEBF8DF347784D
-:100D20001AEED3BF3BEF698A73A8F7C825E267F9CB
-:100D300028F8198DCF47833F2DD5B712BF7B5E1A98
-:100D4000AAC0CA2DE9E2FE41E62FC07560B715546E
-:100D5000A21F02E4EA679FE1660EAB80AEE50E7F5C
-:100D600033F2F957996F0ED2D751E3D773FF3A2375
-:100D7000FFED5AB1DF9A23F4EDA55D32C507AABD98
-:100D8000131F9B8576E21B7A16A4F5EE25FDB94666
-:100D9000C07F099FD8DEC2F5EECA377F54012B868B
-:100DA0004DD8AE8BDDAF00FF26069334F72B4CDE1B
-:100DB000EFD094A7F4676BDA5F353056535F1A9A19
-:100DC000A4A9BFFA8D324D79DAD04C4DFB6BDEAB66
-:100DD000D2946784E76BDA7FE9EC024DF9DAC8ED6B
-:100DE0009AF6A7C4BE9805BC43C51978BF389FEFD3
-:100DF000759F2ED5F4FB6DCADC37900FEFDACCF37C
-:100E0000972B01339A7B267AB85DD102FFE374F504
-:100E10002988AF15606F63DEF2CAED5ABBA37E70FE
-:100E2000EB0694A5897915AB594B155E49979857F0
-:100E3000516D5BA243BEFBA731C2EEB8865D23EEC7
-:100E400085F9AB742D62E3FF5B7435BAB47435BBBE
-:100E5000B5744D2ED6D2D5EAD1D23575BA96AE76C6
-:100E6000AF96AE69355ABAA6FBB474CD5CA4A56B37
-:100E7000965F4BD731F55ABAE6B668E99ADFAAA56C
-:100E80005F4160B5965E09F456E5E5B8AEB59A7671
-:100E900051BAFBEA291F667CCFFD9A7155BA07E06B
-:100EA0007F9CEE2D94AFFEB7D29DB120F95F13E980
-:100EB0007E3681DEA0AF3E42B90076C6397C2E9ADE
-:100EC00020EC79DFC876862A7FE2F57AFCBE75349D
-:100ED000B9344C8F897DECA87A2C611FFB3E66F1FA
-:100EE000907DB499FC3CB709FEBC8CAF66A01FF5A1
-:100EF00007A49FDF0740A6035CEF23DCF09DF79378
-:100F000026939FE10E16D2D3BDBF98890883DE8950
-:100F100089C932DEE7E3A6E732A1BF970B3F8437EA
-:100F2000D99F92C3FD0FF919F8DD9C217EFFF25B7A
-:100F3000695FE89E8293E887079D721AFDF0F0BC16
-:100F400060E6FC7046950F5EE676C6E16DE96C8959
-:100F5000F4323A7C703FBBF4AB12C51996FE9E3F4B
-:100F6000C7E770BB37F1D9D1AAE28DEF876EC871A0
-:100F700093FECD61FDC27E637ECB381A87FBCD9F89
-:100F8000E4F78F3E2B3165BA838E49111D334D1C1A
-:100F9000AE67F5CC84F87B86F9DD8897EF28209A38
-:100FA000789EFE24E487A5BF7F672CFAB164D975CB
-:100FB00013DE2F3D1DBF0770CCF95A8B847EDD4CAC
-:100FC000578B847EA361EF0FDD2FE1F9C26899F1A1
-:100FD00076F8877850FD73C53A1EA78EDCCDF717DB
-:100FE0004F7D9D91DFA9A3355019C0F8940C0607D9
-:100FF000E6B1E8F979E41B72B8DF2D8B0DD1BDA6FF
-:10100000EC3561178AFBE04B44DEFB0511E759B173
-:10101000C7C4304FA2E4E05107C67556002D875073
-:101020009F297EBA5FA364C7AB0E7ECFB8DE8EE782
-:10103000D8543D3A3ABD1576262E7F1CE8D8329218
-:101040001E5F93CBE3B31D6D35B3302EA3C2F360A7
-:101050009B7716F287AC7818C693F0DE9DF8FC33C8
-:101060008313EAE3D6AF62A9D194F5161F5D66B18A
-:10107000A1AD85F84C2FEE07DA98B3D616FFBB0169
-:10108000AB7374E21EF200433B9B8B7A7C2A675061
-:101090003EFC91F17DA8D105E3C4CBB57BF358BCF0
-:1010A0005FB9ABCD47F06E90FC7E1CC458C842E6D9
-:1010B00014CC5BC0B397F07EC7F56F601E8DC1BACC
-:1010C000D613728F8E37A34BB9122F971EC801B952
-:1010D000941C934BDF6D3B4B78EA685B44DF037CE9
-:1010E000318C9F05B2B87DDAD1B684DEEBC0CE423A
-:1010F0007E7A65C784A36EA83F01FFF09E1CA39370
-:10110000C3C5CAF3483F2D167C803EAB5CE09F13FD
-:10111000AD7AE2B37B722D415C84F7BC3DFE28DEE4
-:10112000F369005E92FF06B8A3DF11783208B904B4
-:10113000FCE4C3F566C856C8FFEBB02D203AFD7736
-:10114000C753F16B3033BA87C6906B21BFCD17857B
-:10115000F37B39097ABE3C8FE4E83D022FAFECE027
-:10116000794727EE6564BFDE731FF7BFDDD3C8285C
-:10117000FF9BB5C25F458C6F54799D8E3781C0CB84
-:101180009E361034458C3DDC66C293572C19FD64A5
-:10119000E36274ECF12A7674C76FAD76D6E1F3E1C1
-:1011A000E9A77B50AC6C99F5BB217CA28F1BBF6F6C
-:1011B0006B6141B43329160BDFB7D74319BE9F22A9
-:1011C000EA53FCBC9C2AEA5317F172AEF739A91A0C
-:1011D000014B8883E45A1CF30A51EEDDC5F8B95B74
-:1011E00071EE7EB790BB632C8EBA6AACFF1AA37CFB
-:1011F0007CB5FE71519F6539D9350EE5F2426DFF20
-:101200001D020F9996933DB3295EA2AD57E31BE9EA
-:10121000964B6F50FF126DFDA3A2BFD57269683661
-:10122000D6176ABFFF90A84FB67079C87CFCFE54F1
-:10123000B5FE3BA2DE8CF5F87D8FB6BE5B7CBF436E
-:101240000A127DE88E585C3FE9DC5FDAD7C6AEC58E
-:10125000F5D3D316A175F470DBA7442709992C3D6B
-:10126000B6AE6CAD6CC4F3E092906729EEB0D73B9C
-:1012700082BC53EB1D367EDE5D7619888F8C16217D
-:101280002FC43A8CCA0BA9C5C3998BFBB13F8F9F62
-:1012900061815D41FB220FFE909F73EED5317F9CF3
-:1012A000DCCA6E4862FEB8F6AEBB1C9A72C6D7B2F4
-:1012B00035ED9D0BC76AEA2DE59334F5CC9B4BEBDE
-:1012C00065ADE0ABA492324DBD7A0E9FF5E46AECB9
-:1012D000677DE14C4DBB4BC56EFAFD9033F3D4DF17
-:1012E00019F198502EACB58ECD44BDF34CDB74345F
-:1012F000B2D9B3B09EF0E8D4013BCF2F3E807159F4
-:10130000B4D7DBBCF47E1FD483E5C29E84F5E686A9
-:10131000F67BDA6C547EA2CD45CFDD6D6E7A3EDE73
-:10132000564CF53BDA3C547E0CC6C7E7A3300EBEE4
-:101330007FA4AD86CA5BDB7C54DED2B688CA0FB50B
-:10134000F9E9F99DB67A7ADFDDD642E58D6DADF427
-:101350007CB02D40CF8EB62EAABF46D0FB8038C7BA
-:1013600078A0929F4B4EA4E3AC5C49732F983596BE
-:101370003F302B17F307FAC39AFBDD71DE349E99D9
-:10138000CF3F71BC3A1C0FBE3B890DB527F3754C9E
-:1013900071C7F1039EF5C9C0EF635A381D0A0622D2
-:1013A000549F55CF695127E065CE00CBA9E0C750C7
-:1013B000B1DD0569A82A99C76129BF8CB9609E155E
-:1013C000E27E1C62BBA00EE152A673BDA9D2353AE3
-:1013D0006F3B8713E73F12BC5F13F397CBFBF9FD1D
-:1013E00017353D2164FB246F0BDD7F615AE40BE16F
-:1013F000EF57387D7E3A8F3FE9D3B9B0B90139F361
-:10140000E997991B9E390DDA7D4FF65D659AFD854A
-:10141000FCE9C3CC7D358C5BA2DD9F2415AED5F4F1
-:1014200033E5DCAFA93738D76BEA97AE29D8E0426D
-:101430007C8E61149F316E6E6718525CDEBB95E046
-:10144000DA24F07E4172D379DEC041353ECFEDF330
-:10145000EF09BDC24C9B693D4CB0F362516A4087B5
-:101460007AE1DC8F52491E3DFD842E88FED7892CFF
-:10147000A8C3F53F19CC3DAC9F8237E8CA74A58A52
-:101480008CE552E696B17C358BD0FE04ECF3F5B9D1
-:10149000DC3E7FC28CF1C15CFFF778DE5288F466D7
-:1014A00091A06791BA1FD9AE24FA65BB72890FB5B6
-:1014B000E7993A859DDE6EAFC8C4B8E88551F2CA97
-:1014C000ACAE9933F177B4AC59D3E9A9BE7FC8ADBE
-:1014D0001BF19CEEE3025F2ADF4F0426177CFF38E6
-:1014E000CEE37CF9BB19B8DD6B2A8C10FF5F90BC92
-:1014F000AE2588D73765CE878359342F45E05539D7
-:1015000058E95A02F853DE1EE709B0D8779E6EF309
-:10151000CE549458B948E445EE6FAB9B591DF7FE85
-:1015200075014F311BAA41FD545CA2F30469649715
-:10153000467E990B7BBC78CE5C29631E146F1359D1
-:10154000CF7AD4D5CA5F64CA73518ECD606ED81776
-:10155000582C21867941AF47E7C934BFAFF43B5BD4
-:10156000752ADD17981D957BA813F1F79486907F57
-:101570007ED7ABE7F33AA6AD2FB6F0FC9D15C58636
-:10158000A05BC2B07A0FDD8BA7F4490C4D7FE52F2D
-:10159000B3090FEC8564E2BFE4ED53E94AED9B1417
-:1015A000FF0F91BEE743EE1774E3042F42BBC6C999
-:1015B00086BD688F4D40BCE0840A8B09AFCBC57CEB
-:1015C000F7B72D213CFD5ACCA33337011EE6F1E2DB
-:1015D000BD912B7A55FF87769E0F9557DD8CF7ECE2
-:1015E000750CC9C256D2E273937E682AFE36DDF9C5
-:1015F00030C025139CBF46FACBDB2BE8F795408122
-:10160000D0FC1A9F80FD7E01C9A31AD2DBD374944B
-:101610009F9AC857A7841C6BC9E5797F56D79767EF
-:10162000E2EFBCC5CAB3883F9FD1B162CA2FD1F1E6
-:10163000FDA59ABF0186831BF775A579BAE83D1A07
-:10164000F3515FDB7594F727EF49A2F389B25DA1EF
-:101650003CE34E4BB56D358E635328AE32579E3505
-:101660008476B3D1AEBB1AEDEEE37BEF1FC2FC1262
-:10167000395761E82FEAB429DCEEC8D1513E9662B1
-:10168000AF36611CA6C872BA12F17974CF37C9BFE0
-:10169000217F43E488087F925E90AC93B5D0F881B7
-:1016A0001C45DCE7E1AD2DCD10210437EE7F6A3E0D
-:1016B000423FCA71DB2533DA2B6ECB0AF2A715E65F
-:1016C00015D07CF4186F83F213EB2ED9516EBDB98F
-:1016D0006783A300EDE7A0423648F19F3BB2E9DC07
-:1016E000F91E039D8B57F19A1F503471BBDC566D68
-:1016F000D99810BFD3279C4BCACA2B107A6E110BF6
-:10170000C5CD47EFE2FB35E6B4D07EA7304F629FF0
-:10171000E962E531A2BC5F1FC8F6007E8EED5991EB
-:101720008FF3BA72D84F79BEA3D9FB1FE7BAD5DFC2
-:101730004332EBE87ED59019F37E9F6A63E968DF58
-:1017400099820AE55DEF13F2ACD0C2F9DF90CFF9D0
-:101750003CF159D8C3D79D722029988C74B3F59762
-:1017600005804F26BF328FB941FF15DABCE43F2C0C
-:101770006C35A463FEC0DC1F5A884F2E5992C84FA7
-:10178000A8B42679F07DC7DE8A62771CDCC1365B9F
-:101790003AE6E5EC6D33A5A39C0A8E225FC7D975A6
-:1017A00094AFECD6F17CBAF9791CAEF979FCBE970E
-:1017B00079A2FCA4125880703E09F4C43CE9A39BB2
-:1017C000B93DBCB6DD4470AC7D731CD955A3E1EDC9
-:1017D000E936573ADE0FBF77B32E1BFD4795DD85FF
-:1017E0009BF09E84B5567E4FAC9C3AE9314C4567E0
-:1017F0003FD533B4DF3B52667A96C5C97739755603
-:1018000031F2952C07B2D12F7267DEFC9B315F124B
-:10181000E8B713CB2BFB4A79D91AC8C6FCCAE6BE77
-:1018200069BC9C1ED889F995DFEA9BC1CBB9816C54
-:10183000FC1DA9B6BE6B79797C60279637F655F208
-:1018400032FA9E40766EE99B7333CAD90E83A71E87
-:1018500005F20F00FE1280BF5F3CB70ABCA8F5CFAF
-:10186000E17BC0F321F14CAC7F41F41B18A5FE25B0
-:10187000513F38CAF82F8B7EA151FA1F13FD8E8F6E
-:10188000D2FF35D1EF8D51EA7F22EADF1A65FC9F46
-:10189000897E43A3F47F57F4FBC528FD7F29FABD59
-:1018A000374AFD07A2FED709E39F10EDC3E2FD58BA
-:1018B000EBE60F42C07763418EA05C2AB66E76E0FD
-:1018C0003ADFDB554EFCDF51C1E33B2ABF8FC5DF5A
-:1018D0006F827A5D3EBF4F4A97CFE33CCF88F1815C
-:1018E0000FB720DFAD7D5BA63C9B0E9DE76C10E53E
-:1018F000E8261DD9036BDFE4FBF3B5DD4A30FEFCBF
-:10190000C53309F06F10F0750A789FCCE3F139A365
-:10191000CB955E1BEF47B269CB9896857217E4377B
-:10192000E5ED167757751597638C4C471688D26886
-:101930000AE17D0D8A55E8055B794F31C26751E8B0
-:101940009CBA625742FBB1BFAB9CEC3B15BE4E8BC1
-:1019500042F775C956AE07E6FE70960DEDAC4EE641
-:101960001FF2627F9742F6FBD1AE321BCA3D83F570
-:101970002E1BAEDF76379F5775537112CA6BF92154
-:101980001DC9EFE336BEDEFB5C3AF25B805EA1F37D
-:101990002C20AF3DA82326B0503B9D8F78F885259D
-:1019A000DCAFC7ACA515745E448D434B4A9CFD7FEC
-:1019B00059E0275FE81105F50B3C9F2C17E71C0247
-:1019C000DCFF0464738D893BAF79394FE6E740D47F
-:1019D00038A25C4BF716E5AD5334FEF79C7BB5653A
-:1019E0004382DE5012F4CAB82E9093717AA7206019
-:1019F000D3944FE609BF8E8779D07E9DFBC3CD245B
-:101A00000F2FA17E9346977B51F92BE4F193E21EB1
-:101A10009E2703FC1CF1D1CD653F417AAFEDD6D1B5
-:101A2000BDD35F548E3E93C7B87FDA0F7A07ED19A6
-:101A30008565E37EE9F3F0305EEF73D0BD0A9F83E6
-:101A40008FF18F963B50DE8EF72BA47786E98DCFF2
-:101A5000C1D7B392E73D3FD2D19EC4ED6A1B9F77B9
-:101A6000678693DF4724CE1FCAC25E7B50F8C195BC
-:101A7000D4B96EFC89904E7B0B9537489ECC1BA049
-:101A8000FD46C96FC3F21B8E24AE777293880FF7A1
-:101A9000A32D43F71C16F8D03FD21F34A8F71486A5
-:101AA000F0FF0E627E8E7A0FA28BEC33710F63EF24
-:101AB000CDD5D85EB14D469373DA138F6DD1830DBA
-:101AC0007AD0C0A2EDF13CD533C775E29EC4DD5B90
-:101AD000D05E3D98C434F7401E443F3A8D17DC82F7
-:101AE000F73EC2F76E90610F767DFEF7B658B26290
-:101AF000F054B90F6C69A73C59BE2FB1337E4FF734
-:101B000079773805970BEC4FAECAC77DF99ED3198C
-:101B10009ADF5D13ED5345FBA6C148D30137B59F4E
-:101B2000960FEBA07120925242EB2B5211DF3E45F3
-:101B3000ECF7E3DA7F89C61FA57DB10ACF81776F05
-:101B40002DE1ED2B71FC0BEE7006E5BC24C0933645
-:101B50007CFCEBFF1A3C9344FBF3A177A9FD05162F
-:101B6000CE985240FD6EC27E17DF7AB742CC3B035F
-:101B7000ED64908A37E37B34B7F8EFB1B490FDDCC5
-:101B80006FEAB1A1BD66D6F7F850EE16E2BD4ED3AE
-:101B900063CF05F985DCAE4A78DF6F6269B5C88F1F
-:101BA000AD3ADABFF49B86CA4AD09E7ED102320F8C
-:101BB000F5C23A0FCAC181F05A4F09B4EBCB99452F
-:101BC000FB8A8386967E3ADFBBC442E74FFB6C3DBF
-:101BD000365C3F667B8F0DE308F27DDC7E52965AC1
-:101BE000FC4F213F85D6162F8F5BBF556E3DC1DF61
-:101BF000FDAA6533EE03BAF59E9E0968675B15CAB8
-:101C00003F57960ECEA7F3823FD03192EF30AF2AE6
-:101C1000287736EAE8BEFA87DD4BEF413C30C5E76E
-:101C2000AB827E79E98A84E72F1E547C268C5F186C
-:101C300085DDD6E7E1BFF7AA7E7787B02F77E4F39B
-:101C40007BABBA971C287E0DFAF5B5AEEDC7EF99C0
-:101C5000279A18E699F5E59CE9C6F3A28FBB60C701
-:101C60000B78B034E8E8F75A1EAF8536A9E8CF30D4
-:101C700068FC15CF4AFDD43ED0A8A37D82A5C4A0A0
-:101C8000F16FA435E8BCE8773CE0F66F427EBBFA22
-:101C90006DE506FC9E6BBC6243FDF490EB17261DC0
-:101CA000C09952AE1DD7364B3B8EA35A5BEFACD5D5
-:101CB000D6672CD4D6BBBE6648F0D768CB29C847B8
-:101CC0008847900116D04349BC8A2559AED0EF858C
-:101CD00075FB77F54C8036C6E440E96B006FD2A403
-:101CE00024DAEF6F7C3509171FC81F467267E314AB
-:101CF0004679AFC772BFE9427D9A889FBE1C03CD6B
-:101D0000D75208F82CC0FDFA59FA5D2F0B8B6B5790
-:101D100080F8F13E93CFF7EFCC5581FE394672F053
-:101D200059D57F7C0B3F4FD5D7CAFDD20F2DE27915
-:101D30008134830A5CDFBC7D0AFECED854F4DB77A5
-:101D4000DD8DF98E8978CDC4FC3239C61F1BD4F3E2
-:101D50002B787AB2828B655C7797DCFCFECD970599
-:101D6000DF1C14F72D44DB23FE3218DFCAC2786F64
-:101D7000E6ABFE077E1E609B1A8F1165BCC610CBBA
-:101D8000078F3B6EC0F5B46DA1A30CD7D346619706
-:101D9000A5E618BC1301DE47DE3004A4ABA0ACB04E
-:101DA000E37AD0E7071DFCBB86379302789EEA11E1
-:101DB00057399DCFFA389FFBF39EABF4FCBC96D607
-:101DC000A342E7DF1E717ACC65DCDEC0BBAE19A58D
-:101DD00016816971B4B68CF6A98F783D665CAF8FB9
-:101DE000E478CC989F6CCE526CB88E1D2E85EED1C7
-:101DF0007AC4E4B7A1DDE2000588BF1F67C8ED998A
-:101E000047E7920087BA0A1E1260228F0FF3E8D2CA
-:101E100004BEFA5C77D9F0FCBAB3F0D0B7D0AF9E6D
-:101E200086E3A5F07E8827BBC0D3A57C37CF4B16B1
-:101E3000E3A7DDF51CB5C7BFCE8AB8F13C9CBF0C4B
-:101E4000F358907E074D7C5F1D273A3EF392DF7E6C
-:101E5000C34F38DEDA73F9FD4186358CF661CF5514
-:101E6000FAF71F45FC6425D13E3BDB955D85FC916F
-:101E7000FDC6CE05780E61C34FB8FE342CE7F1A63F
-:101E80006C8599BE8CF34EF7DB108F89EB30EB78C5
-:101E90004F1D32DBFF054658D4C60080000000000D
-:101EA0001F8B080000000000000BD57D0B7CD4C503
-:101EB000B5FFFCF6954DB249360F424248D8CD8B5E
-:101EC000401E6CC24344D4E5114445BA913722FE0A
-:101ED000420204482080F6A6D69AC50445C51A2AAF
-:101EE0002A5AD48D02C58ABA5440ACE85D1E5AAA5B
-:101EF00056D3AAB7542B4D842AC82B86F65EDA7ABD
-:101F0000ED7FBE676692FD2D89D2DEDBCFE7FEE373
-:101F1000A71DE637AF33E79C3973E69C33B33B9399
-:101F2000D82D3E076349136DCC6567F4F777FEBF84
-:101F3000740B5B674E622C650AFF5E10F63D2D65E3
-:101F40007C7E0963A9D38DF5D35858DECDEB1DEE09
-:101F5000BC8DC53336A0DA58EF89D8A3A5CC845CF4
-:101F6000D877F3B7E79BB5F67B078F60CC9F6EF110
-:101F70006C75319619311E635F4721AF3193EBEFDA
-:101F8000398C8D772532D60FDFEB5DBE62C676DAEF
-:101F90009C131C298C75AE649EA779FBF12FAF9F13
-:101FA000FB36CFFF67A6C319C56B651C6E692BE2B4
-:101FB000DFD95E7D30EA6FB6E84FC5F2F2CD47FA61
-:101FC00033BFC658542CAB0F723CD94C4C47FA77F0
-:101FD000FC5D8D71AC34CE78179FD448C67817015C
-:101FE00053DA3F9F06070E2C747AD09FBBCDCEFBF1
-:101FF0000D5A9C85169E1FF9D4A30F5A33310F0E2C
-:10200000E3189AB6978D66ECB9437CDC013CE77F18
-:10201000E2C189165E1ED35DEE47F94E9349E4FD99
-:102020008107278E656CE0A1E01A8793B18AA7B675
-:102030003F68E7788BFE9528F7F1BCDF02BCD40E31
-:102040006AE7F33B90B594E6DFF4BB2816C5EB15C1
-:102050009B3D9B90671F47B3AD3CBF7DF7D8D92E02
-:102060005EAF296E944B2F626C9A4BA3F95720ED0B
-:1020700077F1BCCC368FEE715CFCFD7A8937C63CBB
-:10208000475A397D8B9FB1B1FB786101E006BD5A9B
-:10209000A3034F83BE2D8F72A663ACDA29685EBDA1
-:1020A000E7BEACFD3C7D25AEA2CAC5DB57C74D4C93
-:1020B000053C191718D39339DD1AED4CE7B8CA4817
-:1020C000F999C6387C03530E8D630EF04DDB1A2749
-:1020D000D2FA18A687F165C6050BD387A33F2FF563
-:1020E000873F7B2AB850FC3527E96C0D87C7CF7135
-:1020F000BD15DCE98CE9D04AC0F813BDED6A7D64FA
-:10210000834FD9EC6011B84EE0C1C6716A2DE3A9C6
-:10211000C3128AEAA5FE6DB29ED9EE089987F1D462
-:10212000F9E611EAD76139DD6EEFA9670F58081F8C
-:10213000AC9605F234C2933F0AF98424CA33AFD770
-:1021400095920AFE6784DC0C0B3B14C5C725EEE5AF
-:10215000EB279D85287D82A3C791834A99899FC5D6
-:10216000327C62E0E3A7199B1CCED72A350D3211D1
-:102170007CB90DA67EC7397E0A0F46131C96752CB6
-:1021800010CD07CB053D38DD72D7B380C58D7AB64B
-:102190007EC793D1CE25F9C06962345E7028D6D54A
-:1021A000A6371DEB5902D197E4CEA61856037CA999
-:1021B000F1185B43FC10907CB1B9D1497454E5032C
-:1021C0006B0F44D031C94047552FE3C200A2674F7F
-:1021D000BF01EA2FA36117F143C6852CC927AE6F53
-:1021E000E93FBB8FFED3A87DDFFD0FA4F19F087DE3
-:1021F000903895A3E2C79DBB127D3C8DB6B6F83CE6
-:10220000BDE039E356A39C1CB6D72877155EA2AD76
-:10221000DE940A8EFFE8DB4C9E56DEDF65478CF5C8
-:1022200026BB3F4CC47AECA91F4A9986FA75A2FED8
-:1022300015278CF57DE37647D417F05D7DC1582FC7
-:10224000923E91F072B8FACD08836B823DCAD07E7F
-:1022500076E54570F59B1506D73569C6FAFA9ADE1C
-:10226000E1BABE20EA1BE152F5BE33FAD2EA45CE0E
-:1022700063DAE4A83EF02EEACF9A7D69FDDE54F3DE
-:10228000CDF56E69881CC72FF72BBEB6F83A4EC63F
-:102290003FF812486E3079A3F93EEA649D0CEBA832
-:1022A0004BAEAB24E6A4F5CC17BE8675F53EFE9981
-:1022B000CED810B7EF2BC8AF0976EFBC8779D58998
-:1022C00072BF6253788F97A3735FF18DC517F31FA9
-:1022D0006377115CAF6ABACE689FB57BB6F2F55DE5
-:1022E00098C1ECE95C0F606981EC1BE3188B752BDE
-:1022F00079CD450D8773A8C4DDF30382AB12699DC8
-:10230000079200CF3F3A6E7FB737C9DDAFA77E6433
-:10231000BD9EFA024F365B7025E0ECAC7378B03F9F
-:102320007C8022DEEE9999512133C7D739AB639D6A
-:10233000C6E5CC91D8F96FF6E378783F5E77A1FFD8
-:10234000D9B3AEBD1B79ED40B26B1587EF5C65FB71
-:1023500028E0D51BABE7BA391CB5767D502A9FE241
-:10236000994C7D7002F0EB4B26BCF27F14FB7A8512
-:102370005FC0335113F84F4ED08B31CE4453DB93B3
-:102380003E7CB3B48D423BE6EC47F09DB17179D70A
-:10239000CBFA5778182FFBD96FF57CD5C9E7B77FF3
-:1023A0004382A789C35B9D3C6BFE0A5EB4D0E44BBD
-:1023B0000D990D705F81F16A1D9583D201B755C2E9
-:1023C0006DEF27F1EECDFD26B89B301EF6B51F68E8
-:1023D00081AD6E414BE45FF62706EEE3F928D3F9B1
-:1023E0000F203F3A8B4D1EBE47B0CD5CBFB0F37D92
-:1023F000E53D89EF27B8FA634FA2EFEBF03D2D469C
-:10240000B44F7BC41468E2ED7DE35F213A3DB3DC59
-:10241000E131F3B12A99CB06BEAD625E1BE0FFE36A
-:10242000B8BFBDD6CEE737C7AD4FC73C6E4936659E
-:102430007D4070E885159CDFD85881FF6FE307C6A3
-:10244000D69BD828C66E94FAC14289C769CC6BC5A1
-:102450003833986EC5B8BF396BF3422FFD0D7450F9
-:102460000EEF2CE6A7EF735880D29B5888EADFCC9A
-:10247000DA29FFEBD892CC060E5FC5A383F3B01E1A
-:10248000C3F0BE54F2CB2D29825F3EEF0FBC6FEC40
-:102490007749FC5BA109FC0D71EBABDDB45E5D29F6
-:1024A0001EC0E49C30D01717B67E26F613FC677169
-:1024B000E67DD3FA69EB8A2F61C3481E38D2391EF4
-:1024C000AE91A4BCC6BB6C0AE60B0982F5FA1DB935
-:1024D0005ECBCD0E96C2E9D2E63207A2382C93C766
-:1024E000AD4CC37C7FB186FD6A38A7DF2FC69959F2
-:1024F00013D5F452BBA9B2BFA903279D847EF20E67
-:102500000BA58CE0EDCA2FE88712387EA69A7734A7
-:10251000738D9B4D1E68FDB43D4CAE5D9BB2D3C226
-:10252000B8FE725DAEF1FB94229E0F93BB5399A54A
-:10253000A79CD37F3FF003B9C35ACCE0DF47DD71DE
-:1025400029D057D85036549C0F3835C2E6D365FF92
-:10255000DA768EB77BCBAD3F093E5A9578763EE969
-:102560001D16319FE5EF9A49AFFCB49181F3D87104
-:10257000AE1F7AF319FB8CEB17C89F684CA3F40BC2
-:10258000AE0F203DDD5840E5671B3D94FFD2EDFBCB
-:1025900009E8B460DD9716EC4BF7442B7C0B3856FA
-:1025A0004BBEBB2773D4A37FE578BDE71DBE303893
-:1025B0003C35C19649007B75E6A777417F5EFDAC4F
-:1025C000E641BD65FBBC36078767E121FD6E90796A
-:1025D000F13BED532126EAA0BF72BDE15EAB6F3740
-:1025E000C61BF9E1F1549D57F0EEEB783399D7FF14
-:1025F000BC7134C175B2D14B709D6A9C4C694CB6AC
-:10260000EF55D4F7B22F6DA87FC38E0E4B06AF5F88
-:10261000EED5BC588F57795920C0E1D96415F27DA9
-:102620001397EF589FE38A6F7CE25606F9ABBF81A0
-:10263000F63392AACA93F9F7A9A32B2DA837EB2B4F
-:102640002ED3DC3D7CF8EDEB50E0A34ED2E5CCEB95
-:102650001AE1E9CC9EC2EF5CC1FB7BFDB0999939D0
-:102660005C5D174C0457D79198009456556FD56E02
-:1026700033E993AB326D01E06FD5EEC2FED0A74EC9
-:1026800071BAB1FC9EF14E3DFF6F2E3D4C8E9E4ABD
-:102690000AFEE74790539F0839C5F5CDCF1E871C2A
-:1026A0001B38C003BA9FB572BD1C8866F5B1D8C788
-:1026B00096DBE4FAE27206F95331E21C3CEA858CBF
-:1026C000F1582F18CF65EB9143F92F3C9AFD7D57B8
-:1026D000CF78DB830B3F7A9CE7CF044C7E2BDF6700
-:1026E000CEB0E0D99F438E6E7178703EB847E3F06C
-:1026F000601FDD3A80F2059A25A681F83940EBB5D6
-:102700004073591AB8FCA9FDD96303C04FAF721CBE
-:102710008CE6E5AF6E8825F9F4AAD573B401FD3DCA
-:1027200021FAFBC90FBFF7E95EA40FD4957D0F48CE
-:10273000CE4E227C57FF68C950B4E7FB344BE7FD0F
-:102740003DF7B2168AE6EBB378E3FEBBD2397CC321
-:1027500036779806F0B4748BD684B430F3BAC36677
-:102760005E6ECF76111CC377B8CD19585603021F81
-:102770005D4DFBB7715F2FDAF8E5781C2FD5FE3E73
-:10278000540B7ED18AF370D691329DF0D742FDEC86
-:10279000DE37EDFD9B18E6C13507C05D69F3D07EDD
-:1027A00012F0B782CE67F402CF7D58D33EFF63A00C
-:1027B000EF193DD583FD658FC91F3F06F58F5A6818
-:1027C0009E2F6FF975BC95E713765959342FAF2BAF
-:1027D000ED9C84FA75992E3A87673E79CD64E0675F
-:1027E000F9AEDDADD44FADDDA3619DED3EFF6606D4
-:1027F000CE43D7324F1EF86E97C8DF3FD1EB01BFF3
-:10280000D5B4FE59E4DB7C94F799FD6E0BEA5709C9
-:102810003DE751B98FB1F6129277C4CAAE1E7ADD88
-:10282000CF8B51BEC9ED4FAF77F4EC7F7CDF2ACC64
-:10283000E6E5E936D9DE392DCBF70FEC5B36B90F7B
-:10284000A9FE1EB5317F34EF27937FD7B0AFDAC42E
-:102850007EBB95CB17F08BDA6FF9B857648BF65EB9
-:10286000C8C90CBEB996F2F9643C1A15A03DFD1218
-:10287000C7577AD28A1821CF94FE313BB9E9B57691
-:102880008ED73FC5EBD7607E0BE57ECD2C9E34CC3A
-:10289000EF58BC7732C6AFB57766610E7C3F9C823D
-:1028A000FC7233D79F72C2F427FBA5ED875109DE76
-:1028B0001BD1FE52EB8F8DE95DFE8EED1A4DF2F7C6
-:1028C00035297F57FFD9C44A797EF5C351244F6813
-:1028D0004FEB052FAFF1F5AE73F9F2EFB01BF0F44B
-:1028E000CA3FB59BE9FC71C854FB26DF4F69E86C11
-:1028F000FC5F6753C208CA7B41E6ABFE64EAF57C25
-:10290000A8524EA77ACCCBFB95D1DE70F5574E1B63
-:10291000F5EF48BAA4F99AFB98AF395ECC771FE679
-:10292000CB69B7FACB329297FB2E719E9951DE3567
-:10293000A06FE43C38DCF7E07B24DCDDFCDD79696A
-:1029400070DFA631BF09EBEC4B5B00EB6C1F07138C
-:10295000EB76DF92A200D6F31E9BC8FBE36DA47F4B
-:10296000EE8B637EC88F7D15A901BF1B729009FD98
-:10297000B41F13E5D1B2FD9C546A3F208AF33FCFC8
-:10298000B39B6264FFF56F17A37C4D868743C0F548
-:10299000DBC0BA6CD26FCD64373C22E5F5C6C4D03B
-:1029A0004D66FE7DE397F90CE31C61A18C15A857D9
-:1029B0001343726863A2373D89E371CFD766DA1794
-:1029C0003696F2BC83E434D977365678D313797EC1
-:1029D000AEA4CBC6D6C0D647D05F4581C7CFC719F6
-:1029E0006066F554CF2DFAF9C82ADAFD4ED285AFCC
-:1029F000635AE7EF672F0801CFFAD4580BEC221C7B
-:102A0000E3E91A87FFF1EA3C46F252DABD664B1A57
-:102A1000CCEDE103AF7D14F45AF13767E1D668C815
-:102A2000E31935D164973A5273579C8B8F374337EC
-:102A300087A2A0FF4D2F37D89DDECFF6D2B8FC601D
-:102A400021CF09A12AE0F1F54E3B835CEE8B9E7508
-:102A5000C171C9C7C3F8A1C626E4C709A90FBD1231
-:102A6000A7BF0B7E5FB1F7DAE4E361FA5EF5C2F26D
-:102A70007CB2FB565FDAF9AE09741A46EBD56F02E9
-:102A80007F04A389FE936FB413BDBB1CA6A76197F7
-:102A9000BC45CAAB261C84F9F7A6DD5181BBF8B74B
-:102AA0001551A19990579CFECF6E035D5F8B26FA5E
-:102AB000D7DA043FD5FEBC90F86B8FCDEB5E8BFE72
-:102AC0005F8F22BAD7C6BB12A8FCAD6426F98FF47B
-:102AD00086DA98507E22C7E7BA58FD24F0C6F98EF0
-:102AE000ECC1B536F1FDA8E4ABA3BC0FC0E1AF8FDC
-:102AF000237E6432AF7F3F99CE535C1F25FED51FE6
-:102B00002CA4BC6EF3A62FC4FA58154BF01D95F6F5
-:102B1000B4A3B589C4DFF31E5CF60EE3F43CEADB34
-:102B2000766F3EAF77749FD5837DE9F70DE6908D84
-:102B3000D3F5EC1DC7466DE2F9F6BB3ECED2C3EC31
-:102B400068F3EEAA9B8276F396DE3115FB655FF89B
-:102B50009E571BC5656E0F9D5272BCE61C8E7F4F43
-:102B60008E6ECBE1F35C51D4BE0872EFACADED4993
-:102B70009C0F3E4AD0A3F1FDDC2B9F6F237968E9BF
-:102B8000CC877EBEDCC2F9007C29F7CF15922F5F7F
-:102B9000CCD113509FE38FF4F1D8A23621F7EEB8D1
-:102BA0003439FFC5BEAD7B343ECEB2987DCB2935DE
-:102BB000074AD0CF292D14AFE5007F5C8FE3FD9D40
-:102BC0007686E241075D9E9B966D37CE0B7FB0AB5C
-:102BD0002CC33F78BB654133D955F8FE6E03FCCB5F
-:102BE00060E935F813845CE1FD3C4DEBD0F1FBF975
-:102BF000DFE7F85FFAEC9032E893CB12F7FEF00AC9
-:102C0000AAC7DB293E375F9C57F3B9181E31BFD3E3
-:102C100092CF4F33290767DBBACFE1D083CE3EDFB7
-:102C2000DFC037679F1D42F92FB44E2D86C37556FE
-:102C3000CA23E6098EAAC001C21B1C057DF611F944
-:102C40007D59727014E48F9247CC1E2CA17375418C
-:102C5000B004E74925CF982F984FDF03C17CB4DF3C
-:102C60006312760AFAC3BC9FCB68253CD8C57A5C50
-:102C7000FA5C21E1458D1349BFC8F94ECD11FE0123
-:102C80000EEF2D3E5E7FF0269BA17C48C0989F29C9
-:102C9000EB0F8AA0CB0073E7FE28C8FB6718ADD7FF
-:102CA000C8716FCE11F6F49FFEB49B0E66795E6418
-:102CB0002E457F97D0B7ADC0F7EFBAF17D6B069781
-:102CC000A7CB30C7EC9EF9EF29D53320F7CF9A84F4
-:102CD0009D7A4F22CF1741CF11F8547985C7483ECE
-:102CE000BAEB778B32E04F5997D3EDE7E80F7E6B65
-:102CF00082BCE4F2A2C92AF0F14563CDF0E3169C50
-:102D000047EBD3AB2D3DF359B4A9D48EF5B278730C
-:102D1000A97D41D879A769FBF0C32E4E97D3DB2D4F
-:102D2000643668B2047E083DBA69BB39E867546E00
-:102D3000F7F2FAA71D07DE45BD459B13CBA0F7AA06
-:102D4000F68B37DD965E1D86EFC2ED46FC17078DCC
-:102D500079D8A3C3F33F822E38F21F6F571A32E699
-:102D6000871F36E63FFFE0D69960E397470B7E3F2B
-:102D700011880BC04F55F3F1A4C3D8D74EEC793965
-:102D80001EF459F649F59B38B72CDE64E4334E3710
-:102D90000D7ABD7F9B46FCB12410B9EEE47ABF6882
-:102DA0003DAE5176CD82703E89A4E729169CE9E5B7
-:102DB000FC54DBB06A38FC21355338E372782E0FAF
-:102DC0006EB0C16F10395E5FEB9E39BC2ED8AB2A56
-:102DD000478BB2310DE3D931187DD7FF7A12D65B1C
-:102DE000E5FD1AEDFF952F0D3E04F9DDB173CE75AB
-:102DF00094CE9C4C7850F6B3C5FBB4501CCF3B47E7
-:102E0000BBF6B6F3760B031AED0F0B9AA37AE41018
-:102E1000FF5FF5FA083836869573F817EFDDFF1770
-:102E20008DF75FB3D9D86E09C717E4FED22D7F8F17
-:102E30000AFFAECE7D63F6B59A31EF850A7EFF5567
-:102E40000CF3122E482E3AA4BE721C192EEFA39238
-:102E50007C6DD85FC66C14EDB8C0AAC47CEB1C3680
-:102E600017E65B6767A1580EC7E1389BD7C9BF9FBC
-:102E7000DF1447F6A945515C2F2CA3944597A19DDB
-:102E800087F6E9CFDE3393BE5287B1D1CF531A9D77
-:102E90007FEA606C44FE19915FC242340FF08B37B9
-:102EA0007C7E01639EB5887353AD25B41FF858CA64
-:102EB000DAC5B987D3D11BE68FABE5F33C92047D2D
-:102EC000C8D87E050B52FD157BFF1E15FE3DCC4E6E
-:102ED0004AE73975AE34DB9817FAB1F9CE18DAEF54
-:102EE000B9208E017FAED5BC8FD9CD48C5BCFC1BA7
-:102EF00084FE33B755EC175C3FCD077E366E18E283
-:102F0000819E3297EBD9D1D02396C450BD8D898C48
-:102F1000EC2B1BE7E40B3DFBEB974218A7F3618D0D
-:102F2000EC231B4B45BF1B1F1842E590871A8D13DE
-:102F3000457ACBC60A559E497AD247002D1D7AAEF6
-:102F4000FCDECF45DF0798BDF9D0D7D943D174DE79
-:102F5000577AED33497A7C6EBF9EF92A3D98D55C4D
-:102F60009AFEB755EE779D1B84FFF7B8E67BD31426
-:102F7000A6970ECA15FBC3A8F1DE6DB21EF901AA11
-:102F80004D15F75DCDE1A97EC4E46A72F7E09D7945
-:102F9000BDF998FFF10DD165E0B351E385BDE76858
-:102FA000A990DBB1239837C0D3825CB17F14E49A37
-:102FB0000C695A0CE73FDECFF172611F8E1BE123D3
-:102FC0003B1BD7D9487E47CE638484AFDAE67BEBE0
-:102FD000CA5EE0E9E6838942CF38BE527B5AC0C55B
-:102FE000E9CAF3A37E144DF6B9E3725F51F8E77CAA
-:102FF0003392F66929AF36483ED900FA633F5B2227
-:10300000CE413D7C62E483B99AC02B7B40E8A71B8C
-:1030100013455EF1013FEFB0BF824FCA19E1BDAF6A
-:10302000738F9AE7C65651CEE93D05F48E3CF728DA
-:103030007A334B6024CE8D7DD17BC1E8C4519A890F
-:10304000FCD67EF8ADB1D7115EEEB504EEE2700CA1
-:10305000B408FC675A047F71A9EC8F29A3FA5E1BA0
-:10306000CF573EB4987979FDCA0C46F6205E9F256D
-:10307000A03EEF06712CD82BD0AE3241F45BD99F25
-:10308000D13981FEB8BCCA459A4DFD7A4D49A27D21
-:103090007C19B5F79B447BAF85A78372843EDFB96B
-:1030A000362AF034E4F33D99F9E08329E38D7CF08E
-:1030B000EFB962BF57E9D03C97342A79D2B0BE1736
-:1030C000340FA1FDA229DA57B71B747B5EE8FF9588
-:1030D00077DF7CC348C0F742B207E07D317527F93E
-:1030E0001B1634CFB9ED439C1BB647D3F76BF2F4F4
-:1030F000DB7347420F74CDDFCD3F2C9871D096C65D
-:10310000DBEBC18A333FE7E954FFCE77A10F4C9D3B
-:103110006EA6FA5399B08FB26631CE0DFE2F2D698F
-:10312000BCBF1BC66A1433D011EDCC5AC9E1AF94B1
-:10313000F4BB5BF26F53349BFD3307E0CACCCFE6A0
-:10314000DF6F8086D98BFFEA90AA3F4EDB0CBD660D
-:10315000D004B1BE547DF4837EDF92EB6983C48BCF
-:10316000CA73BC52FDEA75511D39F148ADA1C13C8D
-:10317000EDCC1FFF30F86A4A369BB40978FF9E19E0
-:10318000B10A1CDECE4A5AF771F92EF0A9CE588842
-:10319000E223024388AF3BC67576DCC3F31DAD83E3
-:1031A0003D64F391E7E885385FB9502EE498922F9B
-:1031B000479DED71C4AFF25C5D2559E38F0D131E81
-:1031C000B98CD7AF72D83AB01F2C7C785A3CE24CFD
-:1031D000AA369A453CC77AE3B99A9F7F5F045D227D
-:1031E000CFC991E761F00CF8A87ABD467C38A8C930
-:1031F000634B2739A63931BF6A472817F2BDDA1366
-:10320000ED41F9E9466FF2F15CF8232653CABEE2BC
-:10321000781F057B2CA3208E0379FA3EE0A9B2A586
-:1032200092CE8BB1453AC9A7BFE5BA08CF53604FDC
-:1032300084BCB1B4A7631DD6A9EF49CE7C07F17356
-:1032400034031E3AACCE7CC0D5B136DA847D73CA65
-:103250005D82AFF93AB35B78FB7B2D2C06EBFD3E2C
-:10326000D97EDE1A8BAF95E707DA99252E097C55B2
-:103270004A7C5D3658DF003C9CF8011B8DFDBF6A1F
-:10328000FD068247F105B3B44D4C867EB7D55D7619
-:103290001FEBE1A3B2C1E3DF47BB6E7E98AE111F07
-:1032A000F0747F0EF1C38D47503E657C2877551131
-:1032B000FC58B5CC0B3F421AF3C01ED0C53A499F0B
-:1032C000E8E2FA04E49992274A6E703EF022AE4793
-:1032D000D157C98F6D8D1C248ED7ED8D764A7FDA3C
-:1032E000E864162E037634A651FE854617A5C1C69E
-:1032F00002FAFEB3460FE577358EA6FC9E462FE513
-:10330000F7364EA6F4E78D3EFACEF1427248C91563
-:10331000258F143F29B914C947F3397AAF2AA3F688
-:1033200024F794BCC33C4C653DF248D1375BF3F9BC
-:10333000D3DC9063ED73202FCACDA79F7F197692BF
-:103340001A8727CA05BC08B9D7E5B0939CCFB2B19C
-:10335000BD38AF37ADF476DC13B6AFDE54A3314BD6
-:10336000189FDE5C1FCD2C617C7C4B43A2213FAFBC
-:10337000E1FD37FAF3FEB544DD91C7E1387AE7673E
-:103380004FFC967F7FEACE2FF2406F0EC7D64731B3
-:10339000EE1D31DD702421DF6C25FD61508C380776
-:1033A000E10F7459C0C4FA7CEACEBFD2FAEE688845
-:1033B000729979BD050D5184AF8F40278ED7DF4BB1
-:1033C0003A55AE3DF6FCCB58E777D848CE2D6896F7
-:1033D000EB721DC76798BEF6693A23BD4CF33206FF
-:1033E0003FCCA73FB085F89ECF3ED5EC010DBA0F7C
-:1033F0003F24CDE3DFF575BFA0F82BADE130E9C385
-:103400003AE2B26027F05B0DF1585A838CD36A1F01
-:103410006888A38A1DE1B5413E80A741B70505072D
-:1034200018D6356BD19CD802AAE5F7EA751AE91BC4
-:10343000DDFA429E99E8589F6BA1F45DAC71DA2FDA
-:103440005A687F52FCCAE585378075D1526A5B1491
-:10345000268717C8EF5505264AD5F7FA5C1BF5F302
-:103460002E8403EFF7BE826CDB4292732E1BE48046
-:10347000AABFA0A0ECEEEC11E8675C0A0B5B8FDE44
-:103480003C0BB5AF47A017CE477661FFAFED631F8A
-:10349000507AC909FCF372829FCE5B4B5F78EE05D0
-:1034A000F8C7967E1C45745A3A4CDA238A02A3A6C2
-:1034B000913EE375687C9ECB25FD273EF7497C3B1A
-:1034C0002F5FB14BD82F79DA8174F91D3564D75A43
-:1034D000EEE1EB230972D5E8473EF4C2C7F1ED7483
-:1034E000AEF06720BE906F0B192C0DFEA2639360A7
-:1034F000175FC13AEF465C5764BB15DA57F1C2BE9D
-:103500002FFCE4CA7F59FEDA9F53098EDDE7532171
-:10351000D756BCB63655EF65DE2B22FCD7CA6FAE48
-:10352000EC602BD8FA2FE1778BACB72A4FFAB52F86
-:103530006397919DC2C2288E61955DE0A12B909703
-:10354000C07A19AF7BDC4D5CB0F3736897C595E02A
-:10355000E1709EEB238EEFE53CB13F9F917ED473EB
-:103560003BCCA4179EDB1147FCBF7CC7436F5EC1F9
-:10357000F3CBB7681896D5B136C2D3F25D66660F45
-:103580003FDFC06E93DC379CCB9E8BAB073F2D0992
-:103590006ADEAD45F0CBBB12FA85EB8B929F964568
-:1035A0000547111D24FCF749FD48D55BB2EF211BEF
-:1035B000E8C5EB9D25BDE5C558E8DAFCAFF35DC075
-:1035C000796AF370F2EB2E09EE5C4EFBFE8E582703
-:1035D000A6F885D5688F0AE489F514C813FAC629B8
-:1035E00069FF3DF58299E40FE0C43AFC4213765E30
-:1035F000D56E9B6CB74DE2ED863CB11E55FD25C1E5
-:103600008EF85C5EFFF3BDEF531A94F35AE2682B19
-:10361000C17EF9F9AED8C9014A7F3CE9553EDE9931
-:10362000E0B8142D6C5DBD9627E286CF6C364F0650
-:10363000BE5840C51905693EA776646874AE05BEDC
-:10364000397E4EED7A29DE44EBD62FDA493A9AECF0
-:10365000C29EEAB6B8A4FDC2EE849E31976B75098E
-:103660005CDED5ED12F10091DF557D5A6FE9E0F790
-:103670004E9BE07FE9BF97FE25C489903F3ECE1662
-:10368000C0FE3A7F986BD64D90676F5B053D06BADA
-:103690001EC5B96AFE7BC964AF586575F547FE4F14
-:1036A000EF58C97E3E7FB85CE769ED23619FEC70FF
-:1036B0008B7DBD761D5F217CCA0338FDFD7C7EB508
-:1036C0000113C5531ECBCB26B81EAF31796DE4E78D
-:1036D00008E5C34E79D4C6FC66E8C93F8B26FDAE2B
-:1036E000365BD8DD1F07BFF3B43629949F0C7B9758
-:1036F000A463ED8DBC3C8C9EB54F87F2A1B79CB600
-:10370000093B1ECA9D48CB44BD26C937E807FD7654
-:10371000B89D6749BFDC1DC7A0E79B5E8E13F6848A
-:103720009F4493DF41F57B5EF25593F473F9B70A3A
-:10373000F80017F4E625B6967CE8956ADC25F12DAD
-:1037400034DE6939DE929816E13F907161A84FE34B
-:103750005B9917E7F1CE67A3483FFD22BD6D0FC609
-:10376000FFE2D921E407EF700716EDA572AEB7713D
-:103770003A2CFD695408F09E7C368EFC9C27AD42A5
-:103780000F3A19974A7AD0E1B847E6A3BFAE2D5158
-:103790001AEC292735664B43F9D67EE4AF5ADAD8BE
-:1037A000407E82A57CB9C31FCDD3C9F02B9FDC3AE4
-:1037B00084EC2C277F6926FF22FFBE0EDF75D632F0
-:1037C000FF76ACBBEDB16467FBE2A77F1B12EE7F17
-:1037D00050E9D22D467B92A2BF2A4FC917EB2B2569
-:1037E0005FE0312D5FEC3375B1C147B2699E62BDB8
-:1037F000723AD0798BAF8F54D8A78F065F49D51C0A
-:10380000C07328FFC7C0FB7671AEF9628795FC22B2
-:103810004B5F8EF392FDE69ECB4CD82F969A85FE99
-:10382000BB94B39B48857D68697C3ED98738BEE9E7
-:10383000FCD8B9D52CC711E39EDC9629ECEF219971
-:10384000DF531C009F4F4962B7DC48FACDE612E017
-:10385000F5FC965813F8828FE385DF7EE9EDDF17DC
-:10386000F84C5844FA38431CF428F8CB85BCACBB60
-:10387000E78A04C4C3B0F7CC0CA2EFBCC5D31FF2D7
-:1038800030125F8BF3A5BCDCF3840DFEB35ABE5E31
-:10389000101FB44CFA4D97FD54237D6ED9DD573C73
-:1038A0004A72F05D2BCBE3709C0E3E141F4E8F0AC4
-:1038B000D94F4F7B0FD55FC6EB8BF66FC7133CDB41
-:1038C000AC1EC01349C74B6EFF53F325B5EFE68F0F
-:1038D00020DFD74B2E9EF779D6F6DD8F2147764431
-:1038E0007BFCF435487EE753D6E022CCFBD4F3D101
-:1038F000245F4E258AF5FE3997877E1BE0B8FE418E
-:10390000B26FFC661A83E85E1C30F6ABC69D992F39
-:10391000E46F5DB22701FE8C3A4E07F4C7E9F21D51
-:103920006AFF9E95DA47CE63A46CD7BD3E9F8F2574
-:103930007E393540D0E3D40B83695FE948147CCEEF
-:10394000E1CDC239E554A2487153067CB0549E4380
-:103950004F8D0BD2B9FB94B693D20EAB68B7B4417E
-:10396000FA6D39DFA5816FC093F05BD9D7B7418F6E
-:10397000807D7A5419A5A1A8A48BEDCCE04FEC432F
-:103980002FE40B7B16D41AC875F26F907E12B441E7
-:103990001EEB528FABDD71B1BF8CFCA03B34F2FB50
-:1039A0003C20D729A04E51F671CE8FCBFC9A17F14F
-:1039B00046CB9A572E01BF2FABDF7013F85DCD6356
-:1039C00099854DC6F9AA4333133C1DD17CDD000F08
-:1039D000E1E365F7E07793821720A7929E49CAF545
-:1039E000E67CB15F21DFC2FBAB6DD6D6D3386E75F6
-:1039F0009E14F35378E268B1C14EC6CFF9A2BC8FD2
-:103A0000F92B3823E7AFE009E60BFB4487DBF5E051
-:103A100058D0FB5766B29F9EFF6A7842D237E8655E
-:103A200038B175DB8B39FCAFF1BD1AFDF821DFB081
-:103A30009E618FE670E66F36FA3F0AB618F3437759
-:103A400018F345BB8CF9927DC6BCE79031BF558E0B
-:103A5000ABF084732EE2DA70CE458A73AE2B5F9C96
-:103A60007391C7391729CEB9F88E732EF238E72231
-:103A70008F732EF238E722C53917DFCF4AF95D2B55
-:103A8000ED8EA003C557BD12ADFCE0B45ECECD49AE
-:103A900025F9A9FC99E7961451BEDB9E5361277B5B
-:103AA0008E8AD3B929413F924F7EC3B6BBD34137EB
-:103AB0004B3BD97157FC5CD8716BCBA21DB02FB4B6
-:103AC000AFFDFC6EA84F2509FA27F914D7D4B94DDC
-:103AD000C42B85486EB4AF71BD77B5A01FD93954DA
-:103AE000DC4D25F6BBA4BEE918E94761EB8D7E935A
-:103AF000483F4AA4FF24920F94DFE4296B673AE41D
-:103B0000FDB167EDEB01FF31691F63B39DA47F2910
-:103B1000BDBA5BFF7A407B1AFBF6D7F949D4BEEBFE
-:103B200030D7B77BD96F555A75A18CF4C6EEFC7AA5
-:103B3000CD44712369F1B40FAD963065699D1DF7D1
-:103B400040DEC599681F3FEF30D1B9E0FC0766D26F
-:103B50002306433F0F9BCF90408C81BF0AB7274578
-:103B6000F8FF0618EA0FDB9B1DE1FF1B6AF44B4DC3
-:103B70005FB31FE7EB69EB871BEA55FBAE88C0A379
-:103B8000845BEAA54D776CCA82FC591DD745F0AF1E
-:103B9000DE1D4D71B5D51C5E2FFC72C87014D4D8D3
-:103BA000BD5381BF9AA03511FB7C95DC7F58837192
-:103BB0003FAEB130BF33A987EF6A9CCC9BC8DB9F77
-:103BC000296DD966E2743B63DAFCC85817FC4AAD2C
-:103BD000594ECE57B76AC1D4CB797F7FB3E84583BE
-:103BE00039BF6559433F9C0779B93387ADE1F58EFD
-:103BF000AD7F299EF46EC9675956670CE8DDDA621D
-:103C0000A67301EC52E6A41E7E686D498EC975F458
-:103C1000CCB387FE5FD1FC385D3CB8A7D8E538301F
-:103C20007035F4B8A0986FCD38CD4F7AB29CCF2ABA
-:103C3000B9AFB05CD1CFAD327F5C9E17D4FC4E0FD4
-:103C4000D95FE2821FB3716F961972DCB4631BEE09
-:103C50000FDC19A35F337824E225F37E3B968FBBFC
-:103C6000F44311AFFBC78D13E22F87FEF9BCD533A8
-:103C700085E7EF6979C68673F1524BC0867367CDCD
-:103C8000B3AD362F4FAFD9DE4ADF176DAFA4F3F6D1
-:103C900062564FE7C8132AFE56E2A366BCB6D9C9DE
-:103CA000E17E61B0901B3531226EA3DC3CF60DC481
-:103CB000A59FDFAE9562BED37D3B6D95B03FCB7ABD
-:103CC00091EBA3EB9D69E5FD604F0A0ABF675FEBCF
-:103CD0006146A880D6C3B40B2E4AA75F184AE7D81E
-:103CE0000F99AF98E44451C479F61D1187DCB54FA4
-:103CF000AC831A5B28651AD6C9EB565A27755C7EC9
-:103D00008D2EC33999B1313CF58D351BF875C5C47D
-:103D100058033FCF6649063FF24C5CDA0CCB4F9F0D
-:103D20009263A83F6B7A6104FF97F594931C196323
-:103D30008833A9BBC3EFD2289E65BCF13B4FEF206F
-:103D40003EBBCED0BE8EDDD8530FE7E02DBF263C64
-:103D500033D666C379ABC624E26A66EB1DF27B3BC1
-:103D60007DE71331ACC341399EDF8A7DD14A767934
-:103D700065979E8D7FE7F4B62F7242CB71111F0AB3
-:103D8000FB8221BE900340E74F26E85027ED3D75AA
-:103D900005C2DE53E76FB321FE96E3DF92C151B255
-:103DA000BC45237B1EAF6FCF4812F93BF07D97F1E6
-:103DB000BE01FABB80F2C3E64AAC97C8F2E57CDEEE
-:103DC000D03396C34E033B93EA5FF6ABF873F1260C
-:103DD000A3DD6839EC396174FC72B08BF874E9F6D4
-:103DE0009D6F0EE07899E64B2CC5FAA90D56582B1D
-:103DF0008B2EE63325DFCFD798C8CFDDF5CE41E255
-:103E0000B3AE1A0BF1F3B7E163B957D83323F96FA7
-:103E1000119F0FFCB28B76699E8026EA012F03C0AA
-:103E2000971178C9E8055F0A4FDD788B285F8C7F92
-:103E30008C40DC801608B97BC38BC4A3EA3F024FD9
-:103E40006CB4110F8B74D77B90378B0E9B59E0129B
-:103E5000E6BD18F3C3F87C7E18FFC60BC24EA2FC69
-:103E600006332F5828DFCD273E113F3D7D8A715DF7
-:103E700076F38D4FAC93191752A9DDFF36FF7C1BEB
-:103E8000DF28B823E393D5FD9EFF1A2CED8423D9B8
-:103E9000485AFF971837ACF67B85E741778EA678AE
-:103EA000A22E4736E90FDDFB8DD358BE2A2E9BE2AA
-:103EB0008875699F53725797F5D43895BCDC351CCB
-:103EC0007C3C301576D7BB9B73B2DAC3F4127DAD60
-:103ED00095ECA6596B9229AD8C76A662BFA85C635F
-:103EE000F6611FFCF4DEFEA9A361875F6B4D99C2EA
-:103EF000BBFEF47B23B25831F2E5941EDB10353B58
-:103F0000DC9EAD525781D80FEAEE3C42FBD719D365
-:103F10003BF1B3B1CED6EE8E4748CDB2B5EF8F723E
-:103F200072D5A3D5A20F2A401CA1D6BACD09BC399F
-:103F30005B4B608F1E06DAF5EBD11396AE2DEF0FBB
-:103F4000FB57EDD7079FC4FEAEAFB1A642CF3CF9F9
-:103F500001DFFF34DABF483F3881F8E314F8AD627F
-:103F6000E97EDB098D79E1BF5962DE5FE234ECA7BF
-:103F7000FB66028E5762F46105E4A70D6C4BC3F833
-:103F80001E3FC54BEA6BF2127AB397A874C526A1FF
-:103F9000BF6D53F65A69D785DE8E3CF4763885A01E
-:103FA000B7230FBD1D29F4767CAF90F6FA414D9DE5
-:103FB000A53877FAC7B3827ADA5F1D05D0CB576B85
-:103FC000311EC89BD59AA73FEC606C4BBAD85723DB
-:103FD000E8ABD22B3BB96E15C6EF575FB0B3F0F824
-:103FE000B1712CD1909F604F37D42F77BA0DE5D7A0
-:103FF000A40D31945FEB2A35E4AF2FB8DC50FF06F7
-:10400000CF3843FE3BA3AF35D4AFF05618F2D326DA
-:10401000CF31D49FE1AB3494CF9ABDC4503E475FBB
-:1040200069C8DF54F33D43FD9BEBD718CABDCC698B
-:10403000C1FEB60FE7298EF7D7719EE2E9EA5FE588
-:1040400039C2E93A7682A9BE377BFC7725FF6E1A22
-:10405000E25D09FECC94F74032E57D8EE60217F171
-:104060006706EEEDD379B62D1D7C13592FB27C6C0B
-:10407000EC81F32E4EC33F6C9F39DDC2E5C3D8CB34
-:104080000E0CCFE1F9A421F74FB770B932F68A03CD
-:104090002F65F3FC80216F88F26107CEA3FCFE211F
-:1040A0000F8AFC3446AA45F690F1D3FD7C1E63AF1F
-:1040B000CE5EEF11F6905EE32D550A3C206E11782E
-:1040C000401AE2FC89F400E74FA487387F56E732B4
-:1040D000F626E74FA487F9B912DFDFE2E74AA4EF3B
-:1040E000F07325D277F9B912691B3F5722FD4DE3D2
-:1040F0006C4A3F68D4A9DD7F34D6507AA4B19EBE05
-:104100007FD4D840E9EF1BFDF43D50A0EC0721B26D
-:10411000B3287FD272F8F16087DB6B3D1DEE6755E7
-:10412000FE40E5FF6BAA67EDB158A7ED96C4CFEC52
-:104130003D7EBDBEE5AC857D16A66FB5C67A9F2BCC
-:10414000203BC94027C96BF97DBC362DB38CA77FB6
-:1041500071E93B41EF1965556B13DCB807526F05E8
-:10416000BF7C68EAFD5E707381B03FAC1AE2DD434C
-:104170007C22FDD8CA8FDC1D9F12E6E73685C5C5B7
-:10418000D05F587C8BF237AB789AABEC223E4FF97C
-:104190009355DC8CEAAFFC02237977E53A0BE927EB
-:1041A00071161642FF2A3EE64A7BB014F10257D63A
-:1041B0003A280EAD3FFF6E2BA37A5E334FB7FC99C2
-:1041C000D72FE9F15FF797F0F37282BFFC824E764A
-:1041D000D72BA5FF1EEDEDA2DC8FF6889D829EC138
-:1041E00053B2AB3D8138A7B21E7F3AEAC78AFA21A3
-:1041F000F497FB9F7CBCF89EF59399142C453C5595
-:10420000E67207C5536D1E17A2FB5B2BDCFAA7A055
-:10421000932FCAF9492CAD9F9C4CD8092AA4DEFBE8
-:104220000D74F81CED147E149E155D147EC3E28E91
-:1042300008AF7DD129923E917451F428BFD0836795
-:10424000E0E9623AF4D009F6D8FF2B74186109D27C
-:10425000FDBFA85ABB07707D1B5D6EE96493709F1C
-:104260007870B6DE0C3C575E70BD897C151B370933
-:104270005B932AF77C4BF92C94F7EBBBFCB63ECA58
-:10428000DF8E56F1085E4729A7CB04293F56970BCE
-:10429000FC4E769B09BF138A16933ECA1C42AF732D
-:1042A000F1FF204F267DE56B467F93528CFAA1F2F9
-:1042B000075F27FB9B1CE107BE4EEA8DD745E885CB
-:1042C000A38648BDCFCDDCE2DC27EEB94F94FB746A
-:1042D00086A4730E3FCC8F051D996E81D03A847BE6
-:1042E000EE25B807EEA7FCB52C40E9F52C44FBD62B
-:1042F0000D5CC021FF1DC6289EF160ECD4792B789F
-:104300007F13864FC8C5F7B07B7DD70CE947F7FA16
-:10431000FEE00CBBD77760A28BF48603F61CD26359
-:10432000B00EAC6176B45F72B98F5086837C5F400B
-:10433000FA06DF17723993FF82EF0BC85F57B0861A
-:10434000A1DD249731DE44B5BFDE399E5986F72DB5
-:1043500077AF2F796520EC2B6F270E9E08BBF3DB20
-:1043600089974DC47CDF4EEC6F1269948DD2E29731
-:10437000737BD3B3141FF68C378959922FC6AFC203
-:1043800067241E157EFF097CAEEC0D9FCDC001ECAD
-:104390007AF6F7E3D3B2E1FF12EBBFEEE5E2FE807F
-:1043A000FF2440435CB25DE025D2BEF379231B08B5
-:1043B000FCB22D09F4FD36C94357368CA1FA5735A6
-:1043C0008CA6F95D11A3DF35848F73BA2C94CF3599
-:1043D00007F6F9E626BA7F7BE605B307FA77ADD98B
-:1043E000B5DE83B5FEB6B82FC7BE3A98057F1BDB96
-:1043F000D27BDC6EAD5DE1CD4FF8F4667B9BC5FEF4
-:1044000027EE11ABFD776094887755F759FBDA8F6B
-:1044100047C508B932304AC8414527DE8EF219BC7B
-:104420009F515C6E643C1843FAF78824EF63C0A781
-:104430003A4723BE09FBD455A1C204E427E33CC993
-:10444000F36FC9FB696F0DAD4FC9E6F83E68D39FA6
-:10445000413B66FECA8C75DD94A7D13DF7AEC339EA
-:1044600029C0F756B5EE4A5849F87B034A3FEE1E7D
-:104470002FC54C7EF155F08FA6E0DC64277BD1552B
-:104480002C9FFCA613E5F8E5BFACA27710D4BD8F36
-:10449000A83493F1FD1C578CE13D98D88224433E0B
-:1044A000CE33C0503F6174B6A13CD13BD4509E3C4A
-:1044B000B9CC90EFE71B63A8DF7FF678E3BB6EFA19
-:1044C0007586FA1935371AF24A7E65884F2CB37E05
-:1044D000AEA1FDA0860586FA6EFF52E3FB367E6F25
-:1044E0005B412AE49EF8CB59B7CA50FEE37871AF1E
-:1044F00061B26311BD5791D772BB717C49A78C041F
-:104500004127E612F2D5CFFF03DF94A719E5ED04AA
-:10451000A7F1BCCDF5410DFB7B46BDC5F0FDD3FF3A
-:10452000219D23F1D2C5B7A610EA431FE2F9ABF4EF
-:10453000A10FC2AE3131C5EA0930614F0F9F17ECB0
-:10454000E9E178803D3D3C0F7BBAF15D2823DD61D8
-:104550004F0F2F1F7ED848F7916D46BA5F76C4483B
-:1045600077C58F91F4B9BCDDC80F91F4B9E244046A
-:104570007F487ACCE6FFFD5DDC93267A4D7268ECCD
-:1045800071F73F4F9FD4A19C3E853DF4F9EF0C3D60
-:104590007D683FDC4F3F9F6503BD3AC57B7D2BA502
-:1045A000FC54F184FCBC2BEED3DD6E26FFFE515390
-:1045B0000BBD9774C0A9BBD1FE96A27A0DFE8334C1
-:1045C000E6DBB988C337FFDFA3C89F307F90B8D739
-:1045D000C98ADA29CE5EC9B9F919228E65C850791F
-:1045E000BEF0887896A2A1422F8CF33829EEB5B29E
-:1045F00048DC23E0C782ACF9C5E09F77A2F16E6189
-:10460000D74661BF6FB78AFBA57ECE47F08B414F7F
-:10461000841E9729F5A8A6DFD9ED807FF02666D8FD
-:10462000178704EC86B8CBC2ED4E43BE389866A817
-:104630003F6CAFCB505E1A2A30940F3FEC31E44709
-:10464000B68D36D4BFEC88D790BFBC7DB2A1FE1525
-:10465000277C867C06EB7C0CF81DA489F368F5505A
-:1046600011C7C3D710F993E6DF9328EE0FCA73AAD8
-:10467000D283553CAE2EF92E529F1E64D329BEB76D
-:10468000299D79E81E805D9E4F9851CFD6653CAD3F
-:10469000D24799DF184FABE268BBF571A97F2B7D3C
-:1046A000382C8ED61B1E473B5FDEF38DDCF7EA25E8
-:1046B000DD23E11F6413F36DFA9E8DEE2D28B822E1
-:1046C000E1F99B8CEFDC6AEFFDFEC89D4385BFFDE1
-:1046D0009739BEEF825F9F84F8C8E96D3C4FBB9F5E
-:1046E000F357D30F6C9EBB5CDF3EDEFC61623EF392
-:1046F0004CA65B2A8A286E69F6CFC2C6FFA11C773A
-:104700007591D6EBFCE62788B822966073817FFB13
-:104710001E4FE033CDC69AE99E8B8C3BBF797DF06E
-:104720000198C8E7D95AACE2FDB28015FC30653C6F
-:10473000D79F4A61B7FAFA2107D7339E6CB0901D14
-:10474000E2E1A137CCF0E7F6DC2318C4CF17E00F85
-:10475000E82A3897D88B44DCEC9EA162FD979BBF7A
-:10476000EA8EFF267B3A63527E8B734B2FFC467C8E
-:10477000A8E6F1AF8E038FC4933A1732B9EFE44A3B
-:10478000B814FEBACFF1127F2A1EDFB5D2EA7BDA67
-:104790004171FD9311CFA4E837B048F0E589A182BB
-:1047A000DEA80779D457BD72735102ECB55DCC9584
-:1047B000E0FC067BE4BF0A2F0AFF7DDDEFE94B3EFC
-:1047C0005C2417FAB8EFD3177FD2DF3F70EF274C86
-:1047D0003E88F812498F40AE89FCB9F7C419D771E9
-:1047E000FF4281DF7D6ABFF0F3F3A4514E30D897CA
-:1047F0009BD69AA59C10FB2AF40D7C5FB8D64AFA8A
-:10480000066B10F1C835521633E64B1D3302FE58C5
-:104810002BBD67759597913EB2C0610BB4F2FA95C6
-:10482000FEC87DD54BEDC95FE3C2BB259EBB617F52
-:10483000AF5A67ACB7D821DEF55A18712E5D2CCF70
-:10484000A58B23CEA5D185725FF6300FE94DD2FF3F
-:10485000ACE0ECE6AB400EC505E39C6A16F6128AA6
-:1048600057EAB6E3C3BF10F68E26C7674C01F6EDD4
-:10487000664BAF7164DDF8ECC34F7E1A7E7217D6BB
-:104880007F17DDFFE9DA152DFC68CA7F21EB9FF663
-:104890009FA772D4476F674ADB4AE047EAF677443E
-:1048A000F84DBA1CA6F8D1E86F87787F41C5012C76
-:1048B000FD6BA0C419E6E7D4DB4D86B88BC8545F06
-:1048C000B39BE2025A2D7A59219FC7298BC78EF7D5
-:1048D00022EF751C48C57DED29D25E13096FB71E06
-:1048E0003A56137E42BFD043BB266BA48772B9C829
-:1048F000B08E943FBB828552902AFF81BE6E34E118
-:1049000059F90F2A43A309CE194D8BAD78B2AFFDEB
-:10491000B13BCA635C3D7E85F64C118FD2977F61B7
-:10492000DA050FF537FDC218EAA7A2D02DEE7135D2
-:104930003FB0127C34743BB3629EED11F1D82ADD96
-:104940005F28ECDF470B95DC96712E6B34A1676B0B
-:104950004CC5BD90DC56F9F32D325F2EF2ABD78AF1
-:104960007CBB7CC7689BB437609E48311F9C8B77AB
-:10497000487B04E68114F3C077C829E421A7908717
-:104980009C421E720A29E414BE2F60BEAC52B3F0E2
-:10499000834C0C5B37F0834C0CD383E00709CFC307
-:1049A0000F125E1F7E90F072F841C2CBE10709CF73
-:1049B000C30F125E1F7E90F03C1B7D6D4F1E72CDAB
-:1049C0005B61C84FE3FAF8C4B0750B3F4878FFF05D
-:1049D0008318FAD3571ADADFC41A0CEDE10709AFCE
-:1049E0007F4B8366F093DC22EFA5576D4A22FE9839
-:1049F000E3F6FDB090D3F70FB15FDF66C539CDBCEC
-:104A00006F099D9FEA623C82CE2D9305DD4D4CD00F
-:104A1000B9730ED1F90E9BC8978BB8D8DEFC0D1375
-:104A20007385BF0129FC0D48E16F400A7F03DEC397
-:104A300086BF0129FC0DF80E7F0352F81B90C2DFE0
-:104A40008014FE06A4F0372085BF01EDE06F400A18
-:104A50007F03BEC3DF8014FE067C3F0ABF476E0F94
-:104A60005CD0DB730DE73BCE8786F39DD39087DE6A
-:104A70001E5E1F7A7B7839F4F6F072E8EDE179E892
-:104A8000EDE1F5A1B787E7DB86BA685D427F0F6F7E
-:104A900007FD3D3C5FDCE27F0336A61B369F3D846D
-:104AA000B43D4E7B52E3A2E0BDE78ECD80DFA83D52
-:104AB0005ACB4AE44BDEAA9D9C3191EB67BA8C2F0E
-:104AC0002B619DF4BEB32EDFADD1438CE2618BFF31
-:104AD0009226E482BA37843F4EF7D25D8CCE011520
-:104AE000723F55ED3DCC6926B925EBF7E47BAF1756
-:104AF00039BEAA47F2320C0E7E402C451C44E91DFB
-:104B00008E32C4716F3369220EF22E11871AC95783
-:104B1000E6222197B699761E88415C4BA546EFC5E3
-:104B2000E75BD861BCE35DDC525F067DE15461A2C6
-:104B30009C57FD18C4C528B8951D90CB09BA5735A8
-:104B4000B693D9AA8BF09E18B32D847CB7093D018A
-:104B5000ED707E2CF46BDEA7C3F8FBCF85627FD3AC
-:104B6000FD2BC754F3EF853BEAC7E0BED69418D1BE
-:104B7000EE274FC5131EA7366B4FE35EDCD81DCC66
-:104B80008BFB975F4B795AB8C369ABA6719D74CF05
-:104B90004BF55BB9398BEEA555B2F6896964CBD775
-:104BA000E81D7385373EBF43981F17F187ADA48F6B
-:104BB0008AFB2231F2BE88BA27E2B6F8424347F6B2
-:104BC000DC17B972446239E2B5D83EF1EEDE0D234E
-:104BD0002AD7F6E3FDEB01F1EEDE957FAA7F83F2A3
-:104BE0005BC4BB7BC406A3681CDAD706FB357AEF2F
-:104BF00061AABFD594E2C2FDD135D654D4DFC13C01
-:104C0000507F0633710F52C157C4DA4C78779C6FCE
-:104C1000310793C3F8884B80E9A07BA9C74AEF41CD
-:104C200054589C56C88DC87DFCE278BA083D2122B4
-:104C30001EA2E98E2359E66CD87B4C9E10E4D6EE7A
-:104C400058D21794BE5329E3A0CE37BF41EF59572E
-:104C5000EE14FA81CEE500E49F8A8FA8CB0964990F
-:104C6000A02F0C682D49328BFDBF08F791FC2FCD8A
-:104C70001CEDC23DC637285EBF72EDC804715F47A8
-:104C8000F81FAA259EAA65FC0B2B72A642EF54EFD3
-:104C900098969BC726D07DB716A1CF29FB4BE5AFD1
-:104CA00086BF093A573E21DF03595749F78022E36F
-:104CB00050947EA8DE3B59D26CA5F89625117AE077
-:104CC00032A9072E8BD003AF2B8AD003D5FB74B249
-:104CD0004EE5AF0ECE203DA55EBCC7376F8DD05BD5
-:104CE000D84EF18EFDBC35134C78B762DE6EAF47FF
-:104CF000EB853FDE93FACB140C9A8C389F0194CE4F
-:104D0000BC9046E9AC0B052407701703F46F7F8550
-:104D1000913EFDBED4576620CE0FF7E3FC51329E84
-:104D20008F91BE54CA9CE5901B43BDDA4198AFA752
-:104D300058F5B588239CD2CAE83ECC0DD06B78C11B
-:104D40006CE839C3C1E7EE72BA173059A3FB1537C7
-:104D50008C5829F99AF339039FFB25DFFA28DFBD28
-:104D60001F48FED6FD1D167A97D5AFD9F02E9B2E83
-:104D7000CFB38A7F23F97CBEFCBD09E61076A66E10
-:104D80003B1480A5C755AE9A097D713E6C7703240C
-:104D900021398AE28A447973D155339B71B8F91F5E
-:104DA000DA27E6A9DF61E07A16E4E9CDB796DA16EC
-:104DB00084C9958A92F1CF14F7EBA1FB82EE7B6355
-:104DC00045FDA1FFAFBA37AFFF37DD5FACE278C674
-:104DD000FA989FD07E1B5EC6DD52C4BC1347E33DEC
-:104DE00066354F1642BCDA5C99FF75D1E2FF585721
-:104DF00044F8A17C60C794997E5A2F425EDD047905
-:104E000065869CD29F2CC2FD0E7BFB24D023B6A8C6
-:104E100053DE8797FB51843DE2D745820E91768918
-:104E2000AA2221C799C5957513DD5375915D4FC1B0
-:104E3000FFA9D5786F50A5BF54FB48E3BF26DEFE1F
-:104E4000CB54FDE7901F8F98C4FDED01E61626EDCB
-:104E500043E27732E4FA61F23D831EFA73A901FA64
-:104E6000DFAB39C3E9AFAFD3C4BDE93EEC38ACA08A
-:104E7000F3B1ADB0E3358ADFE7782A5FF0D153B7FD
-:104E8000DB48FF9E676B7B03EF34293C7EDCF0231D
-:104E9000ABF89D97501EDE9F9A5B1F4DEFBD569459
-:104EA000F8DA4097D8220FD1E319C494F2FAED4E04
-:104EB000DFFB984FDDFAFD4FE2FEF88A7D6EBAD730
-:104EC00058B9B7F46EBC6B5151A21F4179A5C369A3
-:104ED000C3FEBDBC3991F6B3F9FDE5FD42D6497E6E
-:104EE0002A85FFCE2261C7DA5622FA3F27CF21104A
-:104EF0009415867A32AE38629D28FB60A49D21F21B
-:104F00003D81BED68FB227C07E600BB32F2AFB84B3
-:104F1000B5E0D339D83FE7D98CF7E154EA2E96E7CC
-:104F20005C790E5CD8BD7F154DEA0F7D798346BF55
-:104F30005B53ED70CDBA9CE7AB0F5B1129C8A6247B
-:104F4000B9C43B12F78A772416F0F50A79334FC6B5
-:104F50000D556F1A4DEBAD3AC0D3E4BED7E54D1BEE
-:104F60000E66BE02FE0979E99E78B5D36B4B0A5BEB
-:104F7000F7552D9AE19EB9CA27160B7BDC3C3C61A4
-:104F80005E0679E1B6E12D97795CAD401C9ABBD8FD
-:104F900065F0BBF27A14C730259BBD29DEF1E170C4
-:104FA000BBC5786561FD2F6831DE97E7F5C5BB1499
-:104FB000C571D45FA593CF1BF60FA793E0E47820CB
-:104FC0003C753EC0FB73D138448FAA50C08AF3F6BB
-:104FD0003CC44FF0FC5C67C08A7116348B772BF4AD
-:104FE000F5621C7D5DA2AD18FA92C569CB04FEE4A2
-:104FF000BBF61C3E9283D51C2FB8FFA3EE0146E200
-:10500000A752C25BDD9268D4C35A3658418F397DAE
-:10501000DC9FBF41D27D41F338BAFF5C6DF1527C19
-:10502000BD2EF1FBC795D1F7C13F3067E3A35637DB
-:10503000CF5F592CF8F70689D729D9A13C7A9F660A
-:1050400065B40770CE71B6D0FCBAF1FB30C7878665
-:1050500077507C845FCE177EC491556F34D2B307EE
-:105060001E81DFEA8D95B4DE1659749B331C8E4D7C
-:10507000FBF370AF670E5FDF7877873975BA6FF330
-:10508000D9C3B3B2689E1C4EE035CEE39A84F7666E
-:10509000389F101F2B7E51F783D5780B8BC53DC1F0
-:1050A00085C5BDDBD77BD6A597F49B264E5FD8BDC3
-:1050B000FB5A97365C34E2E3DAAAC53B6091EB54C5
-:1050C000AD4FB52ED53A55EBF749AB2F94A6F5C8A1
-:1050D00019BEDFD6FFAC173C3D23E19D2BE9CAF199
-:1050E0007A28FC5ED1FA62218FE6651BD73BFA4332
-:1050F000BFB7ABF2F1A13CDC0354F5D5B8F3E4EF54
-:105100007481EFC16FB74BBAA3FE2AAA6FBC1F51BF
-:10511000D52D2F76AC4D85BCD8A991BEBBEA818335
-:1051200099FF063DF679A1C79EAADDBA3C1D76031C
-:105130004B202BFC7DA6EA90900F0BB9FE0379B1B2
-:1051400048EED3D7E4E9F7168F0CABF7D0F3F9BAF2
-:10515000902F21C897DF3FFFEA87635C3DFBA78262
-:105160007FC1BA5F5B2B1DE1F8127C7E5F4117DDCA
-:10517000FBAA72D85C88B3AD6AAE2479CBD2F87939
-:10518000420B8B938AE083CA668DDECDAA6A18151E
-:1051900030FF2FCAE5AAF515F4368FA2937A7F4324
-:1051A000EDA70AFE1D12FEB9928F5F94EB6F6E8D14
-:1051B000DBB688D6BDDB5605FE97E573AA8DDFBB4F
-:1051C000E9D4ED672EBA3B4DDE63A173C97AABB06B
-:1051D000EFED88237DF5D4AA97DF9DC9EB7DF148DB
-:1051E0006B16F41305C76269C75B28ED718BA4DEEB
-:1051F000CAE9F47A71989C5DFC94A053D50BBFFA70
-:1052000004EF43CDCB96F2EC0171BF7C417027D106
-:105210006DCEBA0D5637AFF76EB1DB20A7ABEA4BB8
-:105220009DB04FCF5DD76A851C78B758E02D92DFCF
-:10523000E7C9B8548557EC3B5A98FF42D587FCDB49
-:10524000C9C7B97565743CE232D438FF25F9B8AAEC
-:105250003E3109E355D557FE10E71E25EF23D7DD74
-:10526000B168B11E16F0FEB02E8F8DF3D03DDB7904
-:10527000F2F7A522EB9F9574FBB155BC2398111B47
-:105280007C96E20A56C478201F7273DB031817FC61
-:105290000CB86D26F1EE606E6DFB978083ABC51484
-:1052A0009F8214EF1D414D4EE5F9A74DE23E10627D
-:1052B0004B90A694087E80690AE52CA59DDE3F0BE5
-:1052C0008BCF34F0AB8D6D5987F7576C298C7EEFFF
-:1052D00045F1A7EA47F1A7E2DFBEE6E728B9B4F94E
-:1052E0001D734B3B4481270BF728E63F3898DEE7D8
-:1052F000FFB679DAE43B78DDF38D12BF5B70D17CC9
-:1053000073C5B9A5EFF96E2C4FED65BE91F354EB63
-:1053100044C55E77FB155A845FE198C6F72FDEEE31
-:10532000D8CA688AFB52F35276EF4B8D97F79424D4
-:10533000493B427B1CF4C879F2F7205848E4F1BDA0
-:1053400022ECBBDAF7D5BB614A3E1FAF97FB226B5D
-:105350007F00EB9935E4D03B19475B8EC5E1FD8EAC
-:1053600063E3047CAADDAD5671EF95C5D95C783F47
-:10537000919FAFE8771F1636F7A773E4CD0D392458
-:10538000176EF6270ABB83D4EF174939187B6BE5F4
-:10539000DD97A1FE26B753E3E32C74783EDB44EDA2
-:1053A0000B3DD007633756D8B249EF15E700E50744
-:1053B000BA55633EBACF043989F565DA9F8B7D67AC
-:1053C000F126710E986262EBE02F1CD4E49B940EE0
-:1053D00039F1987837926D36BEAB7420CF777D095E
-:1053E000F016F11ED9ADD6A0B73FE438D7376067C5
-:1053F0005AE8F091DEFE969493473776D0FBE40AA4
-:10540000AF17DD53B1897BA99D7126B2BF5DEA7DDF
-:10541000956AE94F527CA3FC518FE3FF2E079E4C07
-:10542000B4AF959BE7D1BB3E776F9C4069F586F2A0
-:1054300047FCC5B80FEB4B1D43705BC93E565D374B
-:1054400041DC1F7D3A2A11E79B2CAB3F2B5C2FAD33
-:105450006EBD87EEA99C688DA67B2A139D1513133C
-:1054600053E8BD5DBAF7A5EA7D5FAECBA575130C19
-:10547000F74C16F23E1107FBE7602CC595AAFB23FB
-:1054800077C6E8DF2DE927EE915CEE12F747D2A947
-:10549000BEAB577BB84A3F6B14F711C2EEC54C9DAB
-:1054A000C3DBD7D6BD148F7E963DFCFE288E19D85F
-:1054B0009FEE02DDBAEFC56C12F7629A705E821E33
-:1054C00099E49B3907F8FFA599F0DFD77835F851B3
-:1054D00092B073C4CD8104D25BF510B3C19FAC3BD5
-:1054E00019E9C527CCAC017A80D25FD4F747245E96
-:1054F0004E24B464813F966C7B340BFBCBC938914E
-:105500009FB76DD65B9057FA9628A19F5B18E9C3A9
-:10551000557EA15FB39A24F52E66F47CF8634B6246
-:10552000C53B3CF2FE8C824BBDB77AD222DE8BC1EA
-:10553000BD18F0FBC796D042D0F763AEBFE21CFBAC
-:105540007D29C73E6E31D3EF8EF8F942811EF2718C
-:10555000CB4B71B89FABF4B572F3EFBD788F66D5C6
-:105560006E714F15EF9AD39B95D20EB25CDA41560D
-:10557000BD629D84DF1DE1FA177DA9B5846CBDD1A4
-:105580006FA9D4AFBAF3BB76D2B9AD7687D01F6A14
-:10559000831DA43F287D44DD8B5BB6A383F409D52E
-:1055A0006EF92E8197BA5DE27B25E2D6E5EF856A3A
-:1055B000B9384F6B94FFA468C1AC3596F07C25E5F3
-:1055C0003F2952F6914ED207EF2BF80D9DC3EB9A6F
-:1055D00065BF3C6F0D1BEF0D30693FF13DC781F694
-:1055E00062DF57E575BB12A97DA82E661DF679EF1F
-:1055F00072870569539D83F6FDCDF5A602CB0800A1
-:1056000017E3811EB74FC66FF55BF61FD1B01FA41D
-:10561000B3CE8378F7F580533F027E55BF67A9EE7E
-:10562000BD9C7BEDF3E1E8FFAA41EDE7F1C6837590
-:105630004DDD2CF827DA4BE43C8ADA8783AFFB1D7B
-:1056400010F2F9092B5B47EF075B7C0C76FB90F4BB
-:105650002BFAFF6212BF2FA1859E09D7AF52860990
-:105660003DDC1725FC8B5EB77E12707C47B3169726
-:10567000E24CED32E7A17FF53B2A4A4F1D2FE5733F
-:10568000A63C5FD906A439C0C79AD74BF710EF2ABA
-:105690003A50857DF9FE4E3BFDBEAA8AC31BDF1939
-:1056A000437A6BE680C9B49FA97B29078A4C7EBCEC
-:1056B0007B7E3FB38BB8007B845E6B8AA678646D7B
-:1056C000DF2FFE02799E61FEF2207EA724E3DF3405
-:1056D0007AFF727ED7674FE03766E6B14029BD8317
-:1056E00097A89B86410E774DEED039C9EE7706ED2F
-:1056F0001EB14FB070F8F77DEF2FF149A61EB8CE5E
-:10570000757E46EF0A9EEBB493BD76FC3EF9DE5EF5
-:10571000043CE7D25C1417CDEB85F0BECA3987890B
-:10572000DE191BBFEF20BD9B375EBDAB6737BEAB3D
-:10573000C7DA3213614F261B2A570A529B04DDAE8B
-:105740004A309E13F38689F356DE30213F14FEBAA9
-:10575000EC67DFD6B59E75B842F9EFD5EF4DD5446D
-:10576000D1EF4D75EDCBF9C6F713DE87FEC0F5829C
-:10577000F5D9DEE261FD7AF6CF19122F6A1F36CB1A
-:10578000FE6748FCCC7098043E227E6F43F187A2EE
-:10579000BF8257D157D18DDDDEF606EE05717A1541
-:1057A0003FC8884E97119DFEF2CE5A5CF31F60F6FB
-:1057B00076E8EEFF8B740A450F869EF0B0F8FDADDB
-:1057C000C8B84656C0689DCF37C7901D5097EF8226
-:1057D000F3F5FD06D6B75AD78326B717637F3CCAC1
-:1057E0008FDE80ABDD14A4EFDF1D26E20907B2B621
-:1057F00074197F33127A59937CFFB8FB770C973872
-:10580000E8BD917301F5FE71E0B1457CDC8D338A12
-:10581000C8AE7F8EC9F55ED3FD4EB678FFB8FB9D4E
-:105820006CB39FEC247362C8CED3FD4E769E78EFA6
-:10583000FA558DE5E31D5A7F859DE2E323DFC9E636
-:10584000FBCCB3F0673C5E13437E28F53EF278A7AD
-:105850005E0F3A46BE8FFC88E69BB310FD153BA851
-:10586000BFF639312F6C13680EC18E73B4218EDEF2
-:1058700085567CA9ECD783FC1D8F014FEA5EE71F9C
-:10588000247F29BCAB7B6D0AFF8ACFFC5646F73FCD
-:105890004107BC2BABDE67D7EE907243DD277CDD82
-:1058A000E342FA40A2BE0E7037ADE47283ECE2ED43
-:1058B000B761BE4F7C2FCE0BB88E9A8CBFDFABD2B8
-:1058C0008786990CBF133A5FEE57F355DC7F83311F
-:1058D000EE3FF21DCDE404DFC3C378FB33DAFBA354
-:1058E000F0F19DFF36F71A47F2A45CFF2362F5271B
-:1058F000505FDD7F50FAE13BA59F67D2EF8D7C754D
-:10590000907E5771AED31740BDE85CE10FF8437A43
-:105910003BDDD7F8C39CBF66923DF90EF1FEE7A5CB
-:10592000C279F17D5AC10FAB178A78C30C564FFC70
-:105930009BD6734F331A70FCFF769FB6E7BEEBE43D
-:10594000E1C729EEC247BF5711498FB151075E72B7
-:10595000F193CA6F877D318BEE93261C58EDE6F9E3
-:10596000A32F9E15F98C03E7DD9C36ED2F9E13F9CE
-:10597000C203E7711FF5D3173B45FE0A46FEACE3B1
-:105980002F7E390BF74FFBBBF53F825E332FD4BF21
-:1059900081EDF5C335372E74D37DCA8ACC02719F51
-:1059A000F26394CF485DB03641EBB94F69F2F8FE2F
-:1059B00008BE3DF7A5E06F3787157CF2CFA6EA3E1B
-:1059C000A992B77DC945B5EEFE55F761D53A66DBBC
-:1059D0003CEBAC6042FF3F7D4F9579F8BCFE1F9BCE
-:1059E0004A017000800000001F8B080000000000CA
-:1059F000000BB57C0B7854D5B5F03E73E6994C920C
-:105A000049C80B02E104420C18D299BCC05BEA1DE4
-:105A10002089015A1B6CB52018068D90D76442A8C6
-:105A20002DB5D80C0611A8DE0B5754B068274000DE
-:105A300035E8A0012718EA00922252BF98FB37F2FE
-:105A4000FD5FE10B3E90979310B557EF55B96BADE5
-:105A5000BD4FE64122DAFE7FF8DAEDDAEFBDD77B03
-:105A6000AD7D86B1B196F3D18CFEAEC98C1D3FFCE5
-:105A70009EA249646C4681D16A90A034772BC602FD
-:105A80000EBB01DE7595F935B1BC9F36B45FA2D768
-:105A900066C17E7566EA973908FD72B1DF9F476B74
-:105AA000B1BE416F356430F6B48EB94D098CC5680E
-:105AB0008EC8B84ECC2063CDD07FAC8131631E63DD
-:105AC000297AC6B01DFA312394BB06F97AE3121A7B
-:105AD000563098675C85D9DA9C81BBF53056C8583A
-:105AE000DA28FF68DC5FDA4A3DD5C7687A94063366
-:105AF000638126FFDC0F33192B8E8ACD653F8052E0
-:105B0000CFB2711F4C13656D85F54AE4AFBAD20070
-:105B10006EEC906CB0342B36946F671319ABD702D0
-:105B20009088FF33795A711D6D77F51EE8D7939CE5
-:105B300066DD08E0D8D4832C331FC6BBCA72D804F4
-:105B4000C68E5A1C39D62468679B241C1F9DC3C768
-:105B5000FFAC2C7A870CE3FB0FDF54E880BA3B0CD8
-:105B6000CA0166652CDF3B7A81F61680E39442C950
-:105B700002B075EC02ED688053940312B41BDDA3F0
-:105B80001714DF82E7335A3ECC66EC174C62718003
-:105B9000970CAD63BA15CEEB2CFB44CF34D83EA0A6
-:105BA0002F9F0AF76A854960FDA4A3704FB0CF818B
-:105BB00039319E1D703E96A314627BBA6E20D602C8
-:105BC000F7D1FF95B6CC63A671B13F87FA6BF8F7B2
-:105BD000AF8C3DD72953BD0AABE5375689EED79533
-:105BE000697E0CEFAF3ED568A4B2F36A29C379B4DD
-:105BF000E59977C03C763D5B529E73FDF801AB861C
-:105C0000F695B10E103A86C8CBCE14F8BF28A6C2BE
-:105C10006E369DB1965F41C5BFF0763809D34FD23D
-:105C200008F896ADC5DAB0FE76EC1F6C6776230BEC
-:105C30008E775AA76E5D9B29D6433C2F639E497091
-:105C40008434D62031B8BF54E627FCBC644BA07323
-:105C5000D11FE0E9D94453CB46A45719E8328F4A03
-:105C60006681322D1AD683F6B4374C1EA4AB5D265E
-:105C70004EB7991A5EEED2F0FEFA28E6463A1D07B4
-:105C80003083F26D9BE377B6249AC74FF3C8FB6D60
-:105C9000488FA39997D64F616EDA8FDA6F2CEB3667
-:105CA00021CCB40359844F5933EC7D26D9666E4616
-:105CB0003A0B34D9D947DA607D203A765528FEEA86
-:105CC00071BC3974DC2C1AA78E77AED2B08F46E146
-:105CD000E1FD443FCE4C8DDD9383E3D89B521ED62D
-:105CE00077EBCB6382E37A9B8CEC23B8D7FFD3C4EA
-:105CF000A83CDD64A1F5FF6F532A957F6B52A8FE87
-:105D00006C5336957D4D56AA7FBF693A95772D8A9B
-:105D10002940FA77F966B28F8C42CEC0FF9C5E9D17
-:105D2000A32F04EE9D393C1DBD26E8A83763F8F685
-:105D30006E6C077CF6DECAF1D97F3FF3ECC820BA5F
-:105D40005C6B49B81EFF30C284E7EB8F610BBC70FF
-:105D50004F6F1748347FFF680EEFB7EA683EBB8687
-:105D60006DC5F16F17E8F9FC133455D86E4FE0F3A9
-:105D7000F666010CFB59307DE6CBC897F664A8CFD8
-:105D80000BC2BD5378BB7D0CAF57F7ABB6FFCE66E9
-:105D9000E17428F0DEAF83F57388DE697EB5FFD746
-:105DA000459C0F23FB7B3235659E61EE23C1C6FB0C
-:105DB000135FC07DB8910F3242F8A25E21BE50E958
-:105DC00050A5BF976CFC9E330D82CE4127D0FDA11C
-:105DD0006E40F99A027C20D1BDD8199C679724F8AF
-:105DE00025921FA04439AEF283CA072ABDA7019F9E
-:105DF0004909C173FC28825ED5F2B495E3A53B390D
-:105E0000E601C26BA7CE02A210FA03221310BEB3A2
-:105E1000C00EE34A1E35370C27BFE2FED97B50E5A2
-:105E2000C108F770DDF9F5BCFCBEE727F986721BE7
-:105E3000E9761879F5B53581F6A3D26D92CDFE5F7E
-:105E4000483FFD92492BC54169E2741379FEB70BB7
-:105E5000F83954FA79C9C6B8BEC4734EBC5EDEA91F
-:105E6000E7193AE77246722F338AD747E2573D5710
-:105E700088DC8BB11506EF93316E0F8C057B606368
-:105E800046907E03495F2E43FDB5CDAAD0FEFEA00D
-:105E90009109FFAA3E19AA97E425F373C2F40CB343
-:105EA000001E070E1B88BFFD1A56F50A8C6B255580
-:105EB000113CF76D362E0F06174CD2AC827D05FED5
-:105EC0006E76A3DE0A8C19382BC1F8C0563040C854
-:105ED0007EB0FF584A66EC7ED029A897AE809C63BE
-:105EE000598CC9DB3E3F2BC1BE976D9319DA350142
-:105EF00010DB328C733D19E331F2718CC1B83A3149
-:105F0000AE79EBA777217D9D07FA44FBE62353FD8D
-:105F1000040676CFEC6D3ABAC765317A0FD61FDB2F
-:105F2000FAC48945009F6F9714B4374A6533B5D7D3
-:105F30003C2F7B709D3A73E94509EC9C407BCB5329
-:105F40005150EFDCAB63261857DA2E59FD30FF7243
-:105F50006F0CDE0C5BB645F77E5F76506EDE26F486
-:105F600058D52EC90314C3AAB687B7D7EC0A87EB56
-:105F7000983608C3FCB36C318964FF4D6636B4FFB4
-:105F8000D89604545643723B92AE506D237EEC8DEE
-:105F90005C1E33F659F21D4097F2E1CFD3DF377321
-:105FA00078BE80CF01FCC9E7FCFED57BAB1732FF82
-:105FB00093D1ACC00BE7AC3F6CB2B8E160F51D32D9
-:105FC0009D23E08DA37B7645F5DD4E7C7A48B6A017
-:105FD0001DB6C127BBB1DDD969DAA98173D61F907F
-:105FE00018DA9F4E9FC1C3EFE9EA326C5FEE335976
-:105FF000146C3F6460328C0F00DE4C88C7717D8466
-:106000007FC42BDAA7F0F763A928887F19F19518C8
-:10601000C457F356BE9FF37B397E4AE5D55AC25723
-:106020008BC45242F0FC67CD8B43F8C27EB3B7FD00
-:10603000B50BF1BC0CF6675010EF32E1F93CE0070C
-:10604000E7D51FFE28BDCF1CC4B70CF8FEAD3A1E25
-:10605000FA2FBF01BEAB987B1DDA73DF17CF69C87B
-:10606000FF4964F79EFF03DABD31608F23E908FB27
-:1060700038A9B6F778222C589170D9B902EA27A529
-:10608000BEC232C14E90E21D8F225F9F9DF39747A3
-:10609000101D3D735FB4215D34EBFA5A9F860A7779
-:1060A0007CB41579B03F63FEF6D7609DE2842FD3B0
-:1060B000F723BFFCC96041727A42F023FE1901FF49
-:1060C0004EC6EF1BF0780ECFEFEC34F80D708FACAE
-:1060D000BDC43E640F4C407DECD5A39C2AD10F5427
-:1060E000AC407B1CE6C375242023E4EBDACE3F9F53
-:1060F00096609CA424B2C5081BCD7E19E769D35DC8
-:10610000193A37CC2359FE42FDDA6C13E8FC1353DD
-:106110007EA4A0FC695EC81C5113BF4DCE3392F320
-:10612000CF0A7F6544FB6F0479AFDA7DCC3D361E24
-:10613000F90BEF82F30F973BCBA733F127F842C05F
-:10614000556BDCB146E8BCFC666B2A9EFF63A4B3CA
-:1061500058A4BF53DA51B0AFBA5689F0568FF483C2
-:10616000FE15EA37A8EFF70A39F27C77F1A8442C3C
-:10617000252B702AABEE94AD7E68AFF6717ABA8E9D
-:106180006E84FCA869E3F2E33A3A6A0338C44EAB82
-:1061900047BA5261C0F7C9A0FC987A0DF6FBF234F9
-:1061A00026F4955BD05B4E5C1FD0CB2053E22C399C
-:1061B000217A4BE2F6962A576EDA0AA23E64DDC9CE
-:1061C0001E23D386AC7BF35E4B183CD59B1AD6FFBF
-:1061D000073E25ACDDE6CF0E6BCF3F610D830BBBD9
-:1061E000A787F59F76DA1E06DFD25716D6FF8717E8
-:1061F000CAC3E0C11C38CF3076C7901E4A95C2FA98
-:10620000CF514C61F3CFCB8E0F8307CDE27E841D3F
-:10621000A8DAA75FD8B81D1459AAF7FB136BF83A90
-:10622000AA5FFCD3E9E1EBCDB787AFF75DF1B21B15
-:10623000EC7E2DD8F57B413F62F902D8FF5AB0EBD6
-:10624000DBC0FE47F825B0FFB1F482FD8FF5AF80CB
-:10625000FD8F703BD8FF081F047F05615F531995C0
-:10626000879ACAA9FE46F7D725D63D21D63D29D61D
-:10627000FD47EF492D9D6593345F009FCE4CB8A834
-:1062800047396C6FEC2BC538C0C05B32DB810CE248
-:10629000F09C684A447D348AA1DDC2CA07DEC63854
-:1062A00045FD8189968D0AEAA1FF7C07DB03EDB2EB
-:1062B00082F2FCA8EF83589CE7CA17C087F938EE32
-:1062C0008358F48FEBBE64046F847605E039FB419C
-:1062D00030903D03720DFB67AAB047CFA02C6FDB57
-:1062E000AF477CD4EEDD4FED6F7975E1ED7B5BC29E
-:1062F000DA2DD81FCA5AAD87FCFB4B3E753E3FF5E1
-:10630000AFCB94EC68175FDAFB9FC9CBB05FDBBB08
-:10631000C9F77DCB7D7F72F0C51C94EB4ED0C37E58
-:1063200073701E67874EC07CDF7599FB4B1350114D
-:10633000B4496C121457D826B60AE45DADAFB50E59
-:10634000E5506DF6221DCB207924E20D206DD15E43
-:1063500042E71EEEEF8AF7D3D8FB60DE37BCC76F8B
-:10636000B723FE3A8FC5E2BAFDED72983F73771EF0
-:10637000B75BEFCED313DEAEB41F8B55A07D83F792
-:1063800018BF6FAD9FCE7D54C0FD50D23DFB643A27
-:1063900077F5171ABA7F75BEFBF3649A678E6F5252
-:1063A0000C9EABC7CBD773E529B4CE9CCCA595B8D2
-:1063B000FF93A90B0B65B2F34030A35C9D32AF1580
-:1063C000E303B55ED93E9CBFB546CCDBA5E374F8CC
-:1063D00056E6AB5D63803E4E968DB291CC17FD7E46
-:1063E00093C7EDF152BD2313F5428F5989413A7E8F
-:1063F000B86C620CE2F52896585FB653EF80B2A6EF
-:106400009DAFD763E98E457AEB69CF97D16E51E79F
-:106410005B89EB1686D0F510DEDC84A72A4F8B193A
-:10642000E709E28FD7BBF2B81D7ED2F3EE5D68A715
-:10643000F464475B112F5D7A46FE6D2DE015F54142
-:106440004F675A0BDE83BA9E4BE0A33F5B43780D48
-:10645000F874A2DFA25616D64FC7F1B52B7C3F16B3
-:10646000CFB97F5B847AE959B0ABA1BA4ED7908C93
-:10647000E7FF787BF8FEAAC43DD7E9FCC9C921F43F
-:106480005AD731C42F66A2EF0E953F14C2A78AC710
-:106490009E6C6EB7F5A41A3CE82FD6ED6F25BABEF8
-:1064A0003EBED39D81767EDAAF8D1437BC913FAB73
-:1064B000DA01217E0F433F4E5736B1503321A8EF0A
-:1064C000AFD9EC2FE615A23F544EFE5E0F1B588647
-:1064D000CADF8976701CCADDBF3D85EB0EB683BD71
-:1064E00007EB3A8DBEB91F829D35680546817D0F49
-:1064F0006ED779847F6246FB7499B04F3F561C4536
-:1065000032E857E71A0D9DAF2E278ADBB5424E7E43
-:10651000B23FE3A748AF7527648B11ED50F05B08DD
-:106520006EE37641BD37E3DF67A0BDDDA6233B40C8
-:10653000B53B9CC2EE382FECD9F36B06F464AF1E6A
-:1065400096D813B08F2ADFE6AE346877E6CC257B89
-:10655000D529B751FC71F9D670BBA0DA130ED7EE6E
-:106560000D879D117683EAB7F5E40DD90F93D1FF1E
-:10657000289167A4201F7C2CF0A9FA232BA75A533B
-:1065800090DF376895B96A3C00EFC975F8D56ADCC9
-:10659000AFA72ECA4A7EC1AA43749FFD9F71BFA3B5
-:1065A0003F9571FB88F17BEDF771FA76E924EE6790
-:1065B00000B9D27C46C9B3069AFADD83B124971894
-:1065C0002B437E685CC8FD483BC65CA1DC9727E294
-:1065D0004511FAF2566D9F1C1F221F3ECB9B40FBBC
-:1065E0002FD63307EAA9953156D25BE38DDCDE2E38
-:1065F00059EDB5211D8C07FFD81012CF1E6F1E90CC
-:10660000B0DFAE8778FC5CF5EFE76B2DBAF810BD14
-:106610000792276C7E90247CFC8DE6B7C0FCE6E0F8
-:10662000FC70DF7178DF9F1658491FA7CF67AC9BBE
-:10663000F8B181F8513DCF15A0B362A0338C9920F9
-:10664000DEEAB61FA138B09375933F521ACBF751CB
-:106650008AFB41388A97967C2E37CAF3F9BD350BF1
-:1066600058955B6FE5DBE3F3A1DC9BEF48CAA77AA3
-:106670000BD1E54A412B60A7A4F40D23771BFFC281
-:10668000FDAA4F810F90CFEF699094CC303B88D317
-:10669000B78B57B1CBCCDB3B03EFC16DEFCE4E4692
-:1066A0003F8AF3D59255262533844E5D48E7702FF7
-:1066B0005596EA1FA3DDED5895AC60BCDF85743FAD
-:1066C00001AF91D37522FC43FFE23A3AF786C3F05B
-:1066D000B71DE9AB9E19ACA8475CBEC876AB16E304
-:1066E0003AF9F9C0073707F9205DD0658B43F2A06E
-:1066F000DC6FF94ACBE3588B258A5BDD0995489717
-:10670000F487FDAA667A70FE3B01447F886D4924B8
-:10671000BEA14690233F17E7BD53EB3F827C7C5CD4
-:10672000E7CDC078CA7127CFEB2C646070807C59AC
-:10673000CCBAA9EC8DAE3FE0A7C9DDE3D06F7ECF28
-:1067400061A0384ECBDA1D31284F73D95ACBF96C82
-:1067500054EE6CEFB5FC91ED0A2024765EC50BC5B6
-:10676000853611FE55BCEECDB7CF47FC8F34BEF653
-:10677000AF076E4797A2F681567D0A279BEEECA2E3
-:1067800020FE5CCC9B8DFB55F135843FD8F358B887
-:1067900087056CA008FD1A156F46F8371CDED4FB80
-:1067A0004CD70DFC0CAF0CF412C997487CAAF75BD0
-:1067B000CF1A743CCED5F0CE42E87FF75A8D82F6E0
-:1067C000E175F8BD011EFC26DEE48F91C8DF1C09CF
-:1067D0002F2A3E54FC9C8EE7E34EDF23539CEEFFB2
-:1067E000355EDECA773CFA6DFC18C97F23F1DB9277
-:1067F00055117C19C17F2ABE1CAB6289CF543CD68F
-:10680000298CFCD6BACE18AB8705F167867F883F06
-:10681000CC53503CA65D62CF48DF850FFB28AF11FB
-:10682000891FA00D3BCAF59D11FCA7E26D24F9A3B9
-:10683000CAAF33CC7FDC22517E80F3E7AF0C1ECC95
-:106840002FAAF901350F704CC8BFC8F20CD81D989B
-:1068500077D998DD9384F65AAF5E9D87E71FCFAC5A
-:10686000E91EB702C69F99C9CB5EB4D342607B14C0
-:106870008FC39D196D70E3BD9D9126CF423D7E462D
-:10688000FAF5ED1C4ED12B082F4C996501B857A78E
-:10689000C6ED1E1672D843E59985D38AA99FC4DE3A
-:1068A000C4FB5024564EEB48524219ECE7CC0393FC
-:1068B000F29A59F0FCAFE4737BD62BE4F9501CFB41
-:1068C0003712C5B197800AB060BC7DD6D36513A0DE
-:1068D000FEEC83136D94FF6B0C5F1FF56806C50714
-:1068E00037D37CB77E31A05B9A13DCD790FE2BBEEA
-:1068F000CAEB2B27913F512570684F98CCFD58CF9C
-:10690000C438D447AA7E1A3CF1AA39347E7911F4EE
-:1069100017D387C0931F4F0FD56F4776FF3E0BE706
-:10692000A9D2BB73AD507FA1E50FE9680754ED7E96
-:10693000348BECD2DD1BB2D0BFA8DAF1FB2C3BC10B
-:10694000D10EF26FB4FCDC97F7DDB27363881DFCE7
-:106950006021F70B161B8F94A07D3AF7E64F1EC1FE
-:1069600078F8A407258A8BDDC3BA1F41BD5991CDA4
-:10697000F9886D31925C87F928EFD83AF927BB5036
-:106980009E9FCCFE405709FD4C055ABA8F0AE67906
-:106990002C05E361EB258A8705FB8FA33CE6D2B586
-:1069A000923E3511F561BC4D56705C3CEDE3DEF571
-:1069B000B62EACAF58CDEBE71A3CED3D38CFD37ACD
-:1069C0006BAB8213954F280FC90B9B0AB8DFB5E458
-:1069D0003189EC71759D494F25B7849ED35420F4BD
-:1069E000F98C6EE2FF9F0ABCFC78F5BB6FA62A9873
-:1069F0004F72C41540FB3B4F9ECF44F9559C7031FC
-:106A000007E97C92DEF14C359E7B8781E28705B9F0
-:106A100069720AF4CFFBE5CC27B05CB27AE933D5D2
-:106A20001807DD6A243F4ADD5FA3A468D0DF3CD6A7
-:106A3000F28B7BF1DE2E3C69243BBAB1E5A614361D
-:106A40000C9FAAE51EC0BF92C5D8F34D462A5F6CC5
-:106A5000B230058EB8AF2995E0979B142AD9024E23
-:106A60005F8DC25F1D69BE7CF0F715905705EB6125
-:106A70003EB0376D26FB143CE7A429CE1D1BC4B9DC
-:106A800026C1789B3B6336DE43C186155D688A2646
-:106A900017F0FCE2DB3DEBD3C98E5E7DEEB96A6890
-:106AA0005F5A509E5F00F76DDC7E95FCFC631D8F86
-:106AB00056505C7F87819F4F9CFBC2935929CF60C2
-:106AC000DCF52D1DF9DFAEEDE79EDB00E57D8FAD3A
-:106AD000D087D2FB773DAF4DECE7467C35D23D7C8D
-:106AE0007FBEFA7D3AF1CF0EE0AB9C7F9CAF5CABF2
-:106AF000D7D0FD3D5A507E37DEFB059D3B1DF9E9A1
-:106B0000C2E41F119DBB0F4B74FFAA1C57C72F1067
-:106B1000E7ADD5781F237B50C8F1CFC1F3C3FB3D50
-:106B2000D2F17116DAC39FFB167EEBB90F36610600
-:106B30001DE35A462A23DB8BF48E8956385F9186F3
-:106B4000DBC191ED0F17A871719E6FC73F8C0BD7FA
-:106B500009FDE9848DC525A0FE93FC51B998E7B8DD
-:106B6000EDA216FD2FF0EBDE0FB72FD9FB217A7CBB
-:106B7000A4FDDEA8ACC779B441B93BEDB486F943B6
-:106B8000F4F62D7D51CC1FB2EE90DF01757ACCB3B7
-:106B9000748C26B98078C3BC4CA063F20E842FEAB3
-:106BA000391E0307C1BFE27115261705CF79B1E37E
-:106BB000722ECAD9C8F3D61FBA4CF451E77BF4AA97
-:106BC00044E79F73519B7BE3F31FD97D3917F1771E
-:106BD00051D757847E5440DF978B78A87F9DCBF3A5
-:106BE000EF7B0F6A7DF57A3D8FEF4916F2074BE494
-:106BF0002BE4C7074E703FBEBE6327C9D3C14E1EEC
-:106C00004F7169BA4B5330FED070AE0BE5D9602A94
-:106C1000F7AF607E3BDEDB8C89420F6A07D2E783E9
-:106C20005C3B2AF2B5AA5F7701F9578FF378EBE85E
-:106C30003D526E3443BBE212F233D457ACCA58878C
-:106C4000747EC193849120F676EEFFD453FCED8DD3
-:106C5000688B4C762BD486E06FE81C1E993F9C61B4
-:106C6000AA9F1ECDEC21FD5C7AE5A7E41F9FE47985
-:106C700032D714CE4FEC10E727E7DA23FAD490F995
-:106C80005E52E587B01FE7BEF13FC497A76CF6538D
-:106C900028CFA25116E27CA9711E4912FD8A827981
-:106CA0004073A7F0C7CB646A77F964361AC7A4C6E5
-:106CB00050BEBE8C6DD2A2BD3B977967F077327D16
-:106CC000FFF643689FF7869C8FEFB1C07EA6FC71EC
-:106CD000699423B311ED238D24EED55B303F549F8F
-:106CE00015727B6B862C911E1B181D4D76CA9C0558
-:106CF000CEC5B85FB55F9996EB339887EC2CE61953
-:106D0000C8C57C26F30FE4629E53ED77D71BD10DE7
-:106D1000A41799B7E0AE9075C61472BDF929E69F25
-:106D2000419EB844FEB344FEEA29F4A31A0FF33C93
-:106D300061AF26E33D7CAFE5867B46BC5E06BCDAF0
-:106D400051FF3898DD8EFC3335C983FCE3DA2731F7
-:106D50007CB756DF61D881719D7A5D5F32D2F306D0
-:106D6000DF5FF548CFAE03EFEA95A9389EC781C033
-:106D70005ED7E0FDBA84FE72FA6E7A0FE36ECE1330
-:106D80005C8B3AB5EF925F5FDBBE9FFCF73AE6277C
-:106D9000FFBDAE2D9C5E0653799C3D923FC6142AE2
-:106DA000617C31672BE78BBB64D680728E89B8E932
-:106DB0009CD414B24782E3849D285F7E04ED97FE45
-:106DC00009925582A9FAA3DC6BD12E7267717BA65A
-:106DD000FF4F2F162C23B9E229F819BE8B11F6EEBE
-:106DE0009CF59BB572C87EE674F238617F14AB3AAD
-:106DF00048F8768C453CA4E7958F2DE4EF6472E962
-:106E00009D8F86C73523CFF1AC88E39CC4384F4EA5
-:106E100070DFF3D2D2B81C631EA29F2E0D5F5F7D80
-:106E2000F7A28E5F21E869C81F92787C6A24B98234
-:106E300079944A9147A91479944A9147A91479946D
-:106E40004A9147A91479944A9147A91479944A918F
-:106E500047A9147914AC3F895BA5F7703B9F417A31
-:106E6000E8421E1B13847B1322E031E1FD7B13A457
-:106E700070788C44FD8B0B773EE3CEC138A645C8B5
-:106E8000252506EDAF0B261E5FEA8871CC2D84FA0E
-:106E9000CA39CDBBF97B443BBD67294E58B818F9B8
-:106EA0006B30D1C0500EB90B1DF3111F274ECCCE45
-:106EB000DC4CF2D164C53C77EFDD37C7515CEE2D79
-:106EC00099C9B0E4CCECFCB50500CF344B44B720F5
-:106ED000277E50AEFA9330CFEC4E9ECF2891EB2A0E
-:106EE00071FEC6D1A67C8A6BE53B161586C40F4A97
-:106EF000C72CCF443BA84BA7BC87F154F75F740C59
-:106F0000FD2835FEA6F6EBCD9B598DFB9A933D717E
-:106F10006D1ECA1B602E946F763D6BC37DD935D133
-:106F20005233C92B458BFC5F2DF03D4BE1F6B05F32
-:106F3000AF6813D06F8F9A99E85678BEAA52E4AB27
-:106F40002A45BE0AF1730AE36650BE03F55876433C
-:106F50003D9691EFB9761794AF24BA6503E9A1EF96
-:106F6000C1E6225F7139938EF4FC8288C367178A69
-:106F70007769F9E50FF2715E9AA756C4DF2EEBC26E
-:106F8000F378EAB8E07846E51D3FE0F299C5E9F903
-:106F90007BD7B1CC8DEF69EF786D34C593021E8D30
-:106FA0005B170730F038CA2FF61AF76F592AE797A0
-:106FB0003B5E4DA17ECD220EEA4CE8CE4A40BD2B71
-:106FC000F84A850F7EC3DFF938F30086F275899F92
-:106FD000CF794777563CC001C9A4C1F8B873076F91
-:106FE000EF117CE79C20E613E761466F3AE2A3FFCE
-:106FF000F06BE9F702BCD1EC5FC6E5BD3F8BE43432
-:10700000F367E17BA1CB92F72CBEB7FDF5C17F59A9
-:1070100084EF6B2FEBBCCF21FCDB8333382CED3FAF
-:107020006B096D4FF2A6E37BDC5F1FFCE1227C9FC6
-:107030007B3969FF73F1D61058F7CA596CD73F3CBA
-:10704000635131F49F67F09C6842BA7999D397698C
-:10705000DF81F3783FB51DDC5E9FB5EFC0955750DB
-:107060001F1F88A17CBDAF3083EEBBB963CF6348DF
-:107070006F81FD3AE2838D6D7F7DEEB7D4CF4061A5
-:107080009479066F01865CDC457FBB1BF7352FDAF0
-:10709000FB19C29B8B6EA37DCE1BC5F9F9A9A2B9C2
-:1070A0008B903F0307F6FD0AF96F5E1C18B2B89F7C
-:1070B000174D849F9A572717631C2010D35D81F3C7
-:1070C000D7BF60B0229DD6BC9A320BE302C70B79C2
-:1070D0007CBA7ACAA674D4AF9A43CFEFFE2DC629E4
-:1070E0005F30517EC695C0EDBB1AB9A56805E16F4A
-:1070F000E76E7C371278DE4479D26A9803D7ABDE2C
-:107100003D89E2EAAF7FFD4105E2A144DEBE1BEB13
-:107110003FDB65D2E03DF4E8ED713F423EECD191BA
-:107120009F592DE0EADE517C3FD17DA584BFC44D3F
-:10713000E9A85F6B46FDE676DCF73C79D373E8E7B8
-:10714000B03D06CA155C7C1EEE0DC65D6CD5D12B1C
-:10715000D5C0F3315AA497CBD2A68A6770FE56DE0B
-:10716000EFB26913DDA7BBF52686EB413F86F2EA55
-:10717000B2B439ACFE62EB9E5CF4432FBD308FFCA1
-:107180005195CE557EA9D96508D387240992C57B30
-:107190000952B36E66063D5B2DC04B07B7059E6175
-:1071A000C1F197DA747E3DDC51B581ADC5F7C12AD6
-:1071B0003FD4A4DD5686E7ABD1B464A1BD529DDFB8
-:1071C00057817C71D1C48CA9F88E4EE8AB9AF63504
-:1071D000F3D1EE1D693FB1E25DDFE7820F3FF79922
-:1071E0003CA1F9C1C8F26F4D4C3915F26EF89E06FC
-:1071F00003D9EEEA7C6FEBBD75E89FD52770F97176
-:1072000016FAB7811C331771B9B76455787FA9880E
-:10721000BF4BACD7F765A1DE53E7FFA650956B7D5A
-:107220005928AF22C7CD9385BC7951227953D32EEB
-:107230009D93E19E6A8C6E0FBEDFA94167929F53BA
-:107240007B4DE2E3528BC4BDC3D8A78B3268DD9A75
-:107250003693DD04E36AA3FA62D11EAA8BE98B455B
-:107260003B277048663B04BA1293057E2608948536
-:10727000C41DABBD3ABB2977183CA3DD84EF73F086
-:10728000BF61FDB622CE2755BE685A8F59FA8A9043
-:107290004EABB6878FC3735942F82FE0DB991CEAD7
-:1072A0008FDBC4BEFBA573C427FD5FBF9F8E78AF85
-:1072B000D1B0B59847BC24F1EF1E00A6EF1E2E8971
-:1072C0007C64CDDFCD51482F973EAF23BE0D487D66
-:1072D00024D7CE1C5C407229A0EB23B9D65354416D
-:1072E000F22110DF578172EACCC17ADE3EBAAF429A
-:1072F00081F64E84B17D1C237D7FB9E801921FF396
-:1073000064FEBE81EDD459781C687D6F13F9153A7F
-:1073100025D4EFBE52A4E66DF4C173CB41BE093053
-:10732000655F3BF2619599E239603FB5BD8276DEDB
-:10733000C2642BC6C5AB701CA7037D68FE2F31E16C
-:10734000CB65889F45718E3B8B308F9DD347FE0365
-:107350005035D9E9F57F32901FD9AF1BD88D722AED
-:1073600037CEB1B008F651A7EF5E87A1A72BBABE02
-:107370002ECCFBCD95B93C627B385D057276F2EF81
-:107380002444FEB0BA88CB5FD05BAC05E942E2F89A
-:107390003DE67BF514CA9540F74492C7917C73D1C2
-:1073A000F7442CCA87D3A0C7DD217EFEE9A57B2840
-:1073B0004FBF00DF654079EFDA707A18FCEA67E4C6
-:1073C000EFB1C742EA910EB784C3917484F4E80F19
-:1073D000933B6EA29B3D82AF6A6775D7E33D0CC1BC
-:1073E00077002C87C04723E088FEAC9CDB097BF04C
-:1073F000BF61DEBA71FE5EF2CFF7F177B1CDA0BF0B
-:10740000083E104D7963CD3ED04F895C3FA15EA808
-:107410008DEDA6B854E08081F2230F777C4CEF19F4
-:10742000810E29FE52DBF15A32FAED3EF4139248F6
-:107430000F26D33B95031DC9E86FA8F5751A6F9603
-:10744000788F4F76BA5AEF94FD59B8FF5AA93B1777
-:10745000DB7D8516D11F60196146E7A89338BFB35D
-:107460000E99E47924DEF60A7A05B9904BEF2C0EDA
-:10747000F1B8802A07AA853C398AF5399CEF2D6A34
-:107480005E49C2F772D1C3CA879B8A547BB881E236
-:1074900036BB8A147EAF623CCDCBE34AD45EFFFAA2
-:1074A000E5DC0939384E11E342E4D0C4A05C41FE6A
-:1074B0004F25FE7F58970CE7AA794EB236A39C5A07
-:1074C000BCA614BAB3E5DA15A5142F13EF3F23F7C2
-:1074D000154947F6228EDF1A4D7C4962C87C97C059
-:1074E0005D4FCD233943EFE8EF4F7CBC14E313BF6E
-:1074F00058BC99E87948DF84F2399E673B97E3C826
-:1075000036D734D7D3F1F286967529C3EC23729F10
-:10751000D58E96D264E5FA7A75BF974CEAFE66E995
-:107520009242EF61C19AD22428971BFFD17BE0E7FA
-:10753000BDD461F0A35EAD5EBC625DDC3074739D52
-:107540003ED81EA2BF26207E3D94D71869FF9165C4
-:107550009DE4EFC5381103BE6A25FE027E09D10BFA
-:107560006542BF0EC51BAA968E47BF9339968E47BC
-:107570003D037C55611DC6AFC42F4B34F476C34D1B
-:1075800065E47E3E2BE271D2B222CE2FA76CF66F5D
-:1075900050BE8EF4BD85619AF4ADDF5BA46906DF51
-:1075A000417E4B4B8E51300F54323B9AF73B6CB2BD
-:1075B00060DCA6FFF09714D7ED7FC4BC80E70BCC4E
-:1075C0006C34B477A54EDD11AA473CD3385F46171B
-:1075D00070BBC595ADFBF6B8504ECC505C88EC86C0
-:1075E0009C68CA93047C9F92DEEAEF2CB4603E2331
-:1075F000D00DDE21F093EBEBFF4A46FD1AE8FC8844
-:10760000DE8305BEFA98DE896D10EFF48EFAC43B76
-:10761000AB6E2586BE8B2BFBA014FB6D1465303E34
-:10762000C0E35A6AA9FAFF21FEEF946985C3FABF45
-:10763000090E73685C4049192E8E121A17C8D4F2CD
-:10764000B800961817C8CCE4710184312E8025C685
-:1076500005B01EE30208635C00618C0B208C710195
-:107660002C312E80F59F89EF1FFA4130F178A599D2
-:10767000E4FA4A7CDF0EF7B7F230CF3BAD6C9529C8
-:107680007F8BDF3FA07EBBEEDD4CBB7837E3DD4C6C
-:10769000793CD701D98A2872E9068E631CC7B55F89
-:1076A000B2AE41B9D2B480D6DFD059F8DE62AC6F49
-:1076B000D559350AD111C7638B44EFF46B3A5B2976
-:1076C000EE549C72584FF56D12C338E95D06EEE733
-:1076D0003A65A8CDA33C28D9C14E4337F91FB57BE5
-:1076E00025A532F49DC6F4AB2407D47CF232DEC467
-:1076F0009C5E935239CC3B90A177E7E2DDF432CC2B
-:1077000033E37B71F92B7AD7EF04877414D2E156F7
-:10771000FEFED902FF88DF23DE35D574EE5F87EFEA
-:10772000A122F3CD43DFD345E49DEBA789BCB28D05
-:107730007F5F51F664E5BE03B0DEE02603D91BEEA1
-:1077400042C703D39230EF6FA7F8C8F1C326F28B7C
-:107750003EDC7C53587C84E53B1E9C46F9F9B11411
-:10776000AF68D449A48F67974D4CC17B9C7D42473D
-:107770007AA737AF7C35F66B9CAA503CAAC4C01ED2
-:10778000A079C47B29151F25CD924703F05266A529
-:1077900077F64BE09A305ED9AF33AFC7774D4B18D1
-:1077A0007FE7A0D24DE36689E8060304789F15E2DF
-:1077B0003E9774FEF94B7CC7709F81DBAD691A9EC2
-:1077C000BF4EDBC8DF33DCCF1C7AD4B3CB91BA64B5
-:1077D000D28F7FEA837A47F4D8746E972B2938FFCB
-:1077E000D2933A7A6F5B92F2932C07E9E9627AC7F7
-:1077F00020F917C9D76E1E997F22DF311CD771B9C6
-:1078000002F748FE5017D225C5651C549E6CAAA2EB
-:10781000F277E27B88EBDFFF0F9C453F312D25C6D9
-:107820008A726EC4EFDDA2BEFD7BAF17C4FBB53418
-:107830004D4FBE82F7F177B315EF437D2778CA56D7
-:10784000BE1FF1648F656E0B7D0F061210EEB5142E
-:107850000F22615CDB6BC7EF8E060E4B167A977CAE
-:107860009D7CDCFC08BE1371654A1649C1F8F7A679
-:107870009264D877E9840CDAB7CBC7E3A37443C921
-:10788000183FE7F84ACF731C9B5618AC9F27F82681
-:1078900000FD399DFCD083F4F61DE2A6BBB0BF9B72
-:1078A00099E87B6AFA83FDCCBB791CC54F55BA19A0
-:1078B0006C4BD98174F39E90FB8B17BFAB43FDDFFC
-:1078C0009BEFE8C17D54545E7D2499CE377CFC4A01
-:1078D0007DA71E19BF0A959FFF3FDEA79F6A6AA07A
-:1078E000F29DA655547637B9A93D44FE5F1A41FE74
-:1078F00047C63FAF227F47C63F99518923FD09FC08
-:10790000CDE3CD11F1CEB251F7AE87FB9BBD456FF4
-:10791000C52A35FE89EF87579A491EFCF7B461E303
-:107920009EEABD99294E3AC84C7978FFB3B2276ACE
-:1079300035D0AE9DCEF1A7C61D913FF07CC81F5833
-:10794000227F68B541FE78560F2C5CC0F5BC9BF4D5
-:10795000BC89F0BA6E0DC80F80EF639630F97125BF
-:10796000427E80C371377D57D56960182754DF5137
-:10797000CE82E28BBC61E48997CB937151DEE7E95B
-:107980007BFFFA287A9F7B5CBC873BBE81BF87ABBD
-:1079900064E5B4EE30722516F171DFA881B37F8003
-:1079A000FEF7FDDE4CF6CABAD1CB8AFE19B9724D8C
-:1079B0007CD7F234FEAE80F6DB7E57E03109F3A1CE
-:1079C0008DF7301BE259FD5D811491CFFE1EBF2B58
-:1079D000306D7AE177FF5D815BA78F5F1CFABB0298
-:1079E000B7FA3238ACFEAE001BBF7884DF15983D85
-:1079F0003DE9FADF15B86D3AF71747FA5D01B02790
-:107A0000CB705C92CD3E07CB34B1CFC8EF694F8AC3
-:107A1000FC5D97C6B118CBD258B796EA359E02FAEC
-:107A20000E5EE3FD25F981F98E9FE3794B9FB04D02
-:107A3000C90638CDE02539D99B67BF13EBAFD9EC28
-:107A400077E13A917173C42DFAF7B09FBBB13DF263
-:107A5000DD958ACF15D3B9DC6814E58CE6E1BF2744
-:107A60006F9CCEF3F237DA37ECB706D71BDAFFA6F6
-:107A7000A505B81FD86F2DD6C37EEBB064E684B0E1
-:107A8000EF53AFA73337D155E3744E5F20CFE67D78
-:107A9000C8ED412AB3B49E78B41FC73CE489C7FD42
-:107AA0008E691930E177107F740F9850BFFF71F520
-:107AB0008009EBFF68E7EF9523E77F793AF703B298
-:107AC000660CD0F8F168E3937D3E108FF65356D5DF
-:107AD00087EB28DFB27732E997F142BF8C7F68826B
-:107AE000AF0FE86DFCB638CA67B3E2446AAF3172D3
-:107AF0003EAD79A8F2E00185BEDB9AF76188BD331F
-:107B0000D903FB0EB3BFB483FCDD25C0784F7B7572
-:107B10000423CDA27DE564FCDDE5182137D04E5B62
-:107B20000C72C159F5E69794F7C7F1381FE66891D2
-:107B3000FE7CBA41F17D9A05FDD0E50BD674915FCC
-:107B4000B875A85EF899FBD7A1DF0CF65B587D4DA0
-:107B5000E5912ED437B57BC3EB9D0D57C97F05FB4F
-:107B60002DACFE9E5F9ED3F3DF2F08AF07FCEE45E2
-:107B7000BA54F17B5CE79D8C7EDE71679495BFDF24
-:107B8000F7D2EF95EC10DF3FEFFC8F599C6E04BEEF
-:107B900061BC3774FCC8F4D14CFDDDB35836F2C378
-:107BA0008D4A552E0DFDFE899EB929BE373786E4D4
-:107BB0008E4BF855F59516D2F369F546925F25720E
-:107BC0009415E1A1DF3F2993859CF212FFF7DC1E9B
-:107BD0004F713C3A00C2095329EF93DCCCE1812478
-:107BE00003C987124D79DD1E28DFD4847FC7FE2CA0
-:107BF000CA0719F9977F87E9D27BF977E25AA5106E
-:107C0000FDDC66C9BE0DBF7B6C96441CB1DA4CF935
-:107C1000827E8C2FC279B6C47BB62D8375B6DC9973
-:107C200043F6713FE3F2D4BD80E7ADB6C4972F5E53
-:107C300081ED0BA750FBC16F263E5E80F653759415
-:107C400015EDA72D366E5F6F999F4DEDAF4BCA1A9C
-:107C50003CB7FB2146EB6C99CFCFBDE5F171E2FB60
-:107C60000B8F09F9794B8B7D34E6A366591C1710ED
-:107C70005F63443E6E4B06D443F99454BEF07E9C41
-:107C8000672ADFEFEF6C0AC98FE30BA73CBE5B21CD
-:107C900035E2C7BC906B6E0CF9C1FF0BB81F749432
-:107CA000704700000000000000000000000000001D
-:087CB00005020D0000000000B8
-:00000001FF
diff --git a/firmware/bnx2x-e1h-5.2.13.0.fw.ihex b/firmware/bnx2x-e1h-5.2.13.0.fw.ihex
deleted file mode 100644
index ea3e254335b1..000000000000
--- a/firmware/bnx2x-e1h-5.2.13.0.fw.ihex
+++ /dev/null
@@ -1,12849 +0,0 @@
-:1000000000003BE8000000600000068800003C5053
-:1000100000001968000042E0000000AC00005C50E5
-:1000200000008DF800005D00000000E80000EB001B
-:100030000000E3140000EBF0000000940001CF0882
-:10004000000058E80001CFA0000000C40002289082
-:100050000000F9640002295800000004000322C0D7
-:10006000020400480000000F020400540000004594
-:1000700002040058000000840204005C0000000636
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000020400CC40100000D0
-:10010000060400D000000003020400DC0010000020
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000020400EC4214000053
-:10013000060400F000000003010401240000000098
-:1001400001040128000000000104012C000000004F
-:100150000104013000000000020401D00000890603
-:1001600002040004000000FF02040008000000FF79
-:100170000204000C000000FF02040010000000FF59
-:1001800002040014000000FF02040018000000FF39
-:100190000204001C000000FF02040020000000FF19
-:1001A000020400240000003E0204002800000000B9
-:1001B0000204002C0000003F020400300000003F59
-:1001C000020400340000003F020400380000003F39
-:1001D0000204003C0000003F020400400000003F19
-:1001E000020400440000003F020404CC00000001AF
-:1001F00002042008000002110204200C000002008A
-:10020000020420100000020402042014000002195D
-:100210000204201C0000FFFF020420200000FFFF5A
-:10022000020420240000FFFF020420280000FFFF3A
-:1002300002042038000000200204203C00000000DE
-:100240000204204000000034020420440000003575
-:10025000060420480000001C020420B80000000131
-:10026000060420BC0000005F0204223807FFFFFFE5
-:100270000204223C0000003F0204224007FFFFFF6F
-:10028000020422440000000F010422480000000084
-:100290000104224C00000000010422500000000074
-:1002A0000104225400000000010422580000000054
-:1002B0000104225C00000000010422600000000034
-:1002C0000104226400000000010422680000000014
-:1002D0000104226C000000000104227000000000F4
-:1002E00001042274000000000104227800000000D4
-:1002F0000104227C000000000C042000000003E840
-:100300000A042000000000010B0420000000000A85
-:1003100002050044000000200205004800000032F1
-:10032000020500900215002002050094021500202D
-:1003300002050098000000300205009C0810000033
-:10034000020500A000000033020500A400000030F8
-:10035000020500A800000031020500AC0000000208
-:10036000020500B000000005020500B40000000610
-:10037000020500B800000002020500BC00000002F7
-:10038000020500C000000000020500C400000005D6
-:10039000020500C800000002020500CC00000002B7
-:1003A000020500D000000002020500D40000000198
-:1003B00002050114000000010205011C00000001FB
-:1003C00002050120000000020205020400000001F5
-:1003D0000205020C0000004002050210000000406F
-:1003E0000205021C0000002002050220000000138C
-:1003F0000205022400000020060502400000000A59
-:1004000004050280002000000205005000000007E3
-:100410000205005400000007020500580000000813
-:100420000205005C000000080205006000000001F9
-:100430000605006400000003020500D80000000665
-:100440000205000400000001020500080000000190
-:100450000205000C00000001020500100000000170
-:100460000205001400000001020500180000000150
-:100470000205001C00000001020500200000000130
-:100480000205002400000001020500280000000110
-:100490000205002C000000010205003000000001F0
-:1004A00002050034000000010205003800000001D0
-:1004B0000205003C000000010205004000000001B0
-:1004C000020500E00000000D020500E80000000742
-:1004D000020500F000000007020500F80000000718
-:1004E000020500E40000002D020500EC00000027DA
-:1004F000020500F400000027020500FC00000027B0
-:10050000020500E00000001D020500E800000017E1
-:10051000020500F000000017020500F800000017B7
-:10052000020500E40000003D020500EC0000003779
-:10053000020500F400000037020500FC000000374F
-:10054000020500E00000004D020500E80000004741
-:10055000020500F000000047020500F80000004717
-:10056000020500E40000006D020500EC00000067D9
-:10057000020500F400000067020500FC00000067AF
-:10058000020500E00000005D020500E800000057E1
-:10059000020500F000000057020500F800000057B7
-:1005A000020500E40000007D020500EC0000007779
-:1005B000020500F400000077020500FC000000774F
-:1005C0000406100002000020020600DC000000010A
-:1005D000010600D80000000004060200000302200B
-:1005E000020600DC00000000010600B80000000068
-:1005F000010600C800000000010600BC0000000069
-:10060000010600CC000000000718040000A900004B
-:10061000081807C800070223071C00002C2C000044
-:10062000071C800038930B0C071D0000293119317D
-:10063000081D686052F40225011800000000000047
-:10064000011800040000000001180008000000006C
-:100650000118000C0000000001180010000000004C
-:100660000118001400000000021800200000000122
-:1006700002180024000000020218002800000003F5
-:100680000218002C000000000218003000000004D6
-:1006900002180034000000010218003800000000B9
-:1006A0000218003C00000001021800400000000495
-:1006B0000218004400000000021800480000000179
-:1006C0000218004C00000003021800500000000057
-:1006D0000218005400000001021800580000000435
-:1006E0000218005C00000000021800600000000119
-:1006F00002180064000000030218006800000000F7
-:100700000218006C000000010218007000000004D4
-:1007100002180074000000000218007800000004B5
-:100720000218007C00000003061800800000000290
-:10073000021800A400003FFF021800A8000003FFF9
-:100740000218022400000000021802340000000019
-:100750000218024C00000000021802E4000000FF32
-:100760000618100000000400021B8BC000000001EE
-:10077000021B800000000034021B804000000018B3
-:10078000021B80800000000C021B80C000000020C3
-:100790000C1B83000007A1200A1B83000000013806
-:1007A0000B1B830000001388021B83C0000001F4B0
-:1007B000021B1480000000010A1B148000000000CE
-:1007C000061A1000000003B3041A1ECC0001022711
-:1007D000061AA020000000C8061AA00000000002AF
-:1007E000021A1ED000000000061A1ED800000006E3
-:1007F000061A36E800000004061A36E0000000027F
-:10080000061A500000000002061A500800000004FA
-:10081000061A501800000004061A502800000004B0
-:10082000061A503800000004061A50480000000460
-:10083000061A505800000004061A50680000000410
-:10084000061A507800000002041A404000020228F4
-:10085000061A400000000002061A400800000002CC
-:10086000041A62C00020022A061AD1000000000209
-:10087000061A200000000124061AB000000000281B
-:10088000061AB1400000000C061A330000000014E4
-:10089000061A33A000000068061A81080000000252
-:1008A000061AD1C800000002061AD1D800000020A4
-:1008B000061A249000000124061AB0A000000028A7
-:1008C000061AB1700000000C061A33500000001424
-:1008D000061A354000000068061A81100000000268
-:1008E000061AD1D000000002061AD25800000020DB
-:1008F000021A292000000000061A30000000000241
-:10090000041A30080005024A061A301C00000009CB
-:10091000061A320000000008061A5000000000020B
-:10092000061A508000000012061A40000000000263
-:10093000061AD0C000000002021A2924000000009C
-:10094000061A304000000002041A30480005024F29
-:10095000061A305C00000009061A32200000000868
-:10096000061A501000000002061A50C800000012BB
-:10097000061A400800000002061AD0C80000000253
-:10098000021A292800000000061A30800000000228
-:10099000041A308800050254061A309C0000000931
-:1009A000061A324000000008061A5020000000021B
-:1009B000061A511000000012041A401000020259D9
-:1009C000061AD0D000000002021A292C00000000F4
-:1009D000061A30C000000002041A30C80005025B8D
-:1009E000061A30DC00000009061A32600000000818
-:1009F000061A503000000002061A5158000000127A
-:100A0000041A401800020260061AD0D80000000242
-:100A1000021A293000000000061A3100000000020E
-:100A2000041A310800050262061A311C0000000990
-:100A3000061A328000000008061A5040000000022A
-:100A4000061A51A000000012041A4020000202679A
-:100A5000061AD0E000000002021A2934000000004B
-:100A6000061A314000000002041A314800050269EC
-:100A7000061A315C00000009061A32A000000008C6
-:100A8000061A505000000002061A51E80000001239
-:100A9000041A40280002026E061AD0E80000000284
-:100AA000021A293800000000061A318000000002F6
-:100AB000041A318800050270061A319C00000009F2
-:100AC000061A32C000000008061A5060000000023A
-:100AD000061A523000000012041A4030000202755B
-:100AE000061AD0F000000002021A293C00000000A3
-:100AF000061A31C000000002041A31C8000502774E
-:100B0000061A31DC00000009061A32E00000000875
-:100B1000061A507000000002061A527800000012F7
-:100B2000041A40380002027C061AD0F800000002C5
-:100B30000200A294071D29110200A29800000000E3
-:100B40000200A29C009C04240200A2A0000000005D
-:100B50000200A2A4000002090200A270000000002E
-:100B60000200A274000000000200A2700000000059
-:100B70000200A274000000000200A2700000000049
-:100B80000200A274000000000200A2700000000039
-:100B90000200A27400000000020100B40000000185
-:100BA000020100B800000001020100DC00000001A9
-:100BB0000201010000000001020101040000000127
-:100BC0000201007C003000000201008400000028C7
-:100BD0000201008C0000000002010130000000044E
-:100BE0000201025C00000001020103280000000075
-:100BF0000201607000000007020160800000000137
-:100C00000201055400000030020100C40000000190
-:100C1000020100CC00000001020100F80000000108
-:100C2000020100F00000000102010080003000001D
-:100C3000020100880000002802010090000000006E
-:100C40000201013400000004020102DC0000000186
-:100C50000201032C00000000020160740000000784
-:100C60000201608400000001020105640000003000
-:100C7000020100C800000001020100D000000001D4
-:100C8000020100FC00000001020100F4000000016C
-:100C9000020C100000000020020C200800000211CD
-:100CA000020C200C00000200020C201000000204C4
-:100CB000020C201C0000FFFF020C20200000FFFFA0
-:100CC000020C20240000FFFF020C20280000FFFF80
-:100CD000060C203800000002020C20400000003406
-:100CE000020C204400000035020C204800000020C7
-:100CF000020C204C00000021020C205000000022B9
-:100D0000020C205400000023020C20580000002494
-:100D1000020C205C00000025020C20600000002670
-:100D2000020C206400000027020C2068000000284C
-:100D3000020C206C00000029020C20700000002A28
-:100D4000020C20740000002B060C207800000056D6
-:100D5000020C21D000000001020C21D4000000018F
-:100D6000020C21D800000001020C21DC000000016F
-:100D7000020C21E000000001020C21E4000000014F
-:100D8000020C21E800000001020C21EC000000012F
-:100D9000020C21F000000001020C21F4000000010F
-:100DA000060C21F800000010020C223807FFFFFF9C
-:100DB000020C223C0000003F020C224007FFFFFF14
-:100DC000020C22440000000F010C22480000000029
-:100DD000010C224C00000000010C22500000000019
-:100DE000010C225400000000010C225800000000F9
-:100DF000010C225C00000000010C226000000000D9
-:100E0000010C226400000000010C226800000000B8
-:100E1000010C226C00000000010C22700000000098
-:100E2000010C227400000000010C22780000000078
-:100E3000010C227C000000000C0C2000000003E8E4
-:100E40000A0C2000000000010B0C20000000000A2A
-:100E5000020C400800000411020C400C00000400C9
-:100E6000020C401000000404020C40140000042195
-:100E7000020C401C0000FFFF020C40200000FFFF9E
-:100E8000020C40240000FFFF020C40280000FFFF7E
-:100E9000020C403800000046020C403C00000005F7
-:100EA000060C404000000002020C40480000000A0E
-:100EB000020C404C000000F0060C40500000001FE7
-:100EC000020C40CC00000001060C40D00000003AAB
-:100ED000020C41B800000001060C41BC00000003F8
-:100EE000020C41C800000001020C41CC00000001CE
-:100EF000060C41D00000001A020C423807FFFFFF29
-:100F0000020C423C0000003F020C424007FFFFFF82
-:100F1000020C42440000000F010C42480000000097
-:100F2000010C424C00000000010C42500000000087
-:100F3000010C425400000000010C42580000000067
-:100F4000010C425C00000000010C42600000000047
-:100F5000010C426400000000010C42680000000027
-:100F6000010C426C00000000010C42700000000007
-:100F7000010C427400000000010C427800000000E7
-:100F8000010C427C00000000010C428000000000C7
-:100F90000C0C4000000003E80A0C400000000001B7
-:100FA0000B0C40000000000A020D0044000000325B
-:100FB000020D008C02150020020D00900215002089
-:100FC000020D009408100000020D0098000000338C
-:100FD000020D009C00000002020D00A000000000B5
-:100FE000020D00A400000005020D00A8000000058D
-:100FF000060D00AC00000002020D00B4000000026B
-:10100000020D00B800000003020D00BC0000000249
-:10101000020D00C000000001020D00C80000000227
-:10102000020D00CC00000002020D010800000001CA
-:10103000020D015C00000001020D016400000001CE
-:10104000020D016800000002020D02040000000110
-:10105000020D020C00000020020D021000000040F2
-:10106000020D021400000040020D022000000003E7
-:10107000020D022400000018060D0280000000127C
-:10108000040D03000024027E020D004C000000014C
-:10109000020D005000000002020D00540000000884
-:1010A000020D005800000008060D005C000000045E
-:1010B000020D00C400000004020D00040000000145
-:1010C000020D000800000001020D000C00000001EC
-:1010D000020D001000000001020D001400000001CC
-:1010E000020D001800000001020D001C00000001AC
-:1010F000020D002000000001020D0024000000018C
-:10110000020D002800000001020D002C000000016B
-:10111000020D003000000001020D0034000000014B
-:10112000020D003800000001020D003C000000012B
-:10113000020D011400000009020D011C0000000A4C
-:10114000020D012400000007020D012C0000000721
-:10115000020D01340000000C020D013C0000000BE8
-:10116000020D014400000007020D011800000029D3
-:10117000020D01200000002A020D012800000027B6
-:10118000020D013000000027020D01380000002C84
-:10119000020D01400000002B020D01480000002755
-:1011A000020D011400000019020D011C0000001ABC
-:1011B000020D012400000017020D012C0000001791
-:1011C000020D01340000001C020D013C0000001B58
-:1011D000020D014400000017020D01180000003943
-:1011E000020D01200000003A020D01280000003726
-:1011F000020D013000000037020D01380000003CF4
-:10120000020D01400000003B020D014800000037C4
-:10121000020D011400000049020D011C0000004AEB
-:10122000020D012400000047020D012C00000047C0
-:10123000020D01340000004C020D013C0000004B87
-:10124000020D014400000047020D01180000006972
-:10125000020D01200000006A020D01280000006755
-:10126000020D013000000067020D01380000006C23
-:10127000020D01400000006B020D014800000067F4
-:10128000020D011400000059020D011C0000005A5B
-:10129000020D012400000057020D012C0000005730
-:1012A000020D01340000005C020D013C0000005BF7
-:1012B000020D014400000057020D011800000079E2
-:1012C000020D01200000007A020D012800000077C5
-:1012D000020D013000000077020D01380000007C93
-:1012E000020D01400000007B020D01480000007764
-:1012F000020E004C00000032020E00940215002085
-:10130000020E009802150020020E009C0000003022
-:10131000020E00A008100000020E00A4000000331E
-:10132000020E00A800000030020E00AC00000031E8
-:10133000020E00B000000002020E00B40000000423
-:10134000020E00B800000000020E00BC0000000207
-:10135000020E00C000000002020E00C400000000E7
-:10136000020E00C800000002020E00CC00000007C0
-:10137000020E00D000000002020E00D400000002A5
-:10138000020E00D800000001020E00E4000000017F
-:10139000020E014400000001020E014C0000000199
-:1013A000020E015000000002020E020400000001C3
-:1013B000020E020C00000040020E0210000000406D
-:1013C000020E021C00000004020E02200000002099
-:1013D000020E02240000000E020E02280000001B74
-:1013E000060E030000000012040E0280001B02A281
-:1013F000020E00540000000C020E0058000000090C
-:10140000020E005C0000000F020E006000000010E1
-:10141000020E00640000000B060E006800000003CE
-:10142000020E00DC00000003020E000400000001B8
-:10143000020E000800000001020E000C0000000176
-:10144000020E001000000001020E00140000000156
-:10145000020E001800000001020E001C0000000136
-:10146000020E002000000001020E00240000000116
-:10147000020E002800000001020E002C00000001F6
-:10148000020E003000000001020E003400000001D6
-:10149000020E003800000001020E003C00000001B6
-:1014A000020E004000000001020E00440000000196
-:1014B000020E01100000000F020E01180000000EC5
-:1014C000020E012000000000020E012800000000B2
-:1014D000020E01140000002F020E011C0000002E5D
-:1014E000020E012400000000020E012C000000008A
-:1014F000020E01100000001F020E01180000001E65
-:10150000020E012000000000020E01280000000071
-:10151000020E01140000003F020E011C0000003EFC
-:10152000020E012400000000020E012C0000000049
-:10153000020E01100000004F020E01180000004EC4
-:10154000020E012000000000020E01280000000031
-:10155000020E01140000006F020E011C0000006E5C
-:10156000020E012400000000020E012C0000000009
-:10157000020E01100000005F020E01180000005E64
-:10158000020E012000000000020E012800000000F1
-:10159000020E01140000007F020E011C0000007EFC
-:1015A000020E012400000000020E012C00000000C9
-:1015B0000730040000E50000083007D8000502BD30
-:1015C000073400002EF7000007348000311A0BBEEC
-:1015D00007350000356F18050735800038C42561D0
-:1015E0000736000014C5339308363400398002BF33
-:1015F0000130000000000000013000040000000085
-:1016000001300008000000000130000C0000000064
-:101610000130001000000000013000140000000044
-:10162000023000200000000102300024000000020F
-:1016300002300028000000030230002C00000000EF
-:1016400002300030000000040230003400000001CD
-:1016500002300038000000000230003C00000001B1
-:10166000023000400000000402300044000000008E
-:1016700002300048000000010230004C000000036E
-:101680000230005000000000023000540000000151
-:1016900002300058000000040230005C000000002E
-:1016A000023000600000000102300064000000030E
-:1016B00002300068000000000230006C00000001F1
-:1016C00002300070000000040230007400000000CE
-:1016D00002300078000000040230007C00000003AB
-:1016E0000630008000000002023000A400003FFF2E
-:1016F000023000A8000003FF0230022400000000B6
-:1017000002300234000000000230024C00000000F1
-:10171000023002E40000FFFF063020000000080055
-:1017200002338BC000000001023380000000001A69
-:10173000023380400000004E023380800000001021
-:10174000023380C0000000200C3383000007A1207A
-:101750000A338300000001380B3383000000138834
-:10176000023383C0000001F40C3383801DCD65007B
-:101770000A3383800004C4B40B338380004C4B4095
-:101780000A331480000000000233148000000001BE
-:10179000063220000000010206328020000000C84E
-:1017A000063280000000000206323DA8000000045E
-:1017B00006323D800000000904323DA4000102C150
-:1017C00006323D00000000200632500000000400F8
-:1017D0000632400000000004063240D00000000243
-:1017E00006326B680000000204326B70000202C215
-:1017F00006326B1000000002043274C0000202C402
-:101800000632DA40000000020632E0000000080064
-:10181000023308000100000004330C00001002C66F
-:10182000023308000000000004330C40001002D610
-:1018300006322450000000B406322AD00000000214
-:1018400006321000000001A002323DB80000000086
-:101850000632500000000020063251000000002037
-:101860000632520000000020063253000000002023
-:10187000063254000000002006325500000000200F
-:1018800006325600000000200632570000000020FB
-:1018900006325800000000200632590000000020E7
-:1018A00006325A000000002006325B0000000020D3
-:1018B00006325C000000002006325D0000000020BF
-:1018C00006325E000000002006325F0000000020AB
-:1018D00006326B780000005206326E080000000CE1
-:1018E0000632DA880000000206322720000000B429
-:1018F00006322AD80000000206321680000001A03D
-:1019000002323DBC00000000063250800000002082
-:101910000632518000000020063252800000002074
-:101920000632538000000020063254800000002060
-:10193000063255800000002006325680000000204C
-:101940000632578000000020063258800000002038
-:10195000063259800000002006325A800000002024
-:1019600006325B800000002006325C800000002010
-:1019700006325D800000002006325E8000000020FC
-:1019800006325F800000002006326CC0000000526A
-:1019900006326E380000000C0632DA9000000002B9
-:1019A00002322A300000000006324010000000021F
-:1019B0000632D0000000000602322A340000000087
-:1019C00006324020000000020632D0180000000657
-:1019D00002322A38000000000632403000000002C7
-:1019E0000632D0300000000602322A3C000000001F
-:1019F00006324040000000020632D04800000006D7
-:101A000002322A400000000006324050000000026E
-:101A10000632D0600000000602322A4400000000B6
-:101A200006324060000000020632D0780000000656
-:101A300002322A4800000000063240700000000216
-:101A40000632D0900000000602322A4C000000004E
-:101A500006324080000000020632D0A800000006D6
-:101A6000072004000093000008200780001002E611
-:101A7000072400002ADE0000072480002E050AB893
-:101A80000824E4A061D202E8012000000000000068
-:101A900001200004000000000120000800000000F8
-:101AA0000120000C000000000120001000000000D8
-:101AB00001200014000000000220002000000001AE
-:101AC0000220002400000002022000280000000381
-:101AD0000220002C00000000022000300000000462
-:101AE0000220003400000001022000380000000045
-:101AF0000220003C00000001022000400000000421
-:101B00000220004400000000022000480000000104
-:101B10000220004C000000030220005000000000E2
-:101B200002200054000000010220005800000004C0
-:101B30000220005C000000000220006000000001A4
-:101B40000220006400000003022000680000000082
-:101B50000220006C00000001022000700000000460
-:101B60000220007400000000022000780000000441
-:101B70000220007C0000000306200080000000021C
-:101B8000022000A400003FFF022000A8000003FF85
-:101B900002200224000000000220023400000000A5
-:101BA0000220024C00000000022002E40000FFFFBF
-:101BB000062020000000080002238BC00000000166
-:101BC0000223800000000010022380400000001269
-:101BD0000223808000000030022380C00000000E3D
-:101BE000022383C0000001F40223148000000001DE
-:101BF0000A231480000000000622100000000042AA
-:101C000006227020000000C80622700000000002BA
-:101C1000022211E80000000006223000000000C08F
-:101C2000062240700000008006225280000000045E
-:101C30000622670000000100062290000000040058
-:101C400004226B08002002EA02230800013FFFFF84
-:101C500004230C000010030A022308000000000007
-:101C600004230C400010031A06228100000000A08B
-:101C7000062286000000004006228C000000003C86
-:101C80000622B0000000020006228800000000804A
-:101C900006228DE00000003C0622404000000006C5
-:101CA00006228380000000A006228700000000407A
-:101CB00006228CF00000003C0622B8000000020062
-:101CC00006228A000000008006228ED00000003C20
-:101CD000062240580000000606228000000000088E
-:101CE000022211480000000006223300000000021A
-:101CF000062260400000003006228020000000081C
-:101D00000222114C000000000622330800000002ED
-:101D1000062261000000003006228040000000081A
-:101D200002221150000000000622331000000002C1
-:101D3000062261C00000003006228060000000081A
-:101D40000222115400000000062233180000000295
-:101D50000622628000000030062280800000000819
-:101D60000222115800000000062233200000000269
-:101D70000622634000000030062280A00000000818
-:101D80000222115C0000000006223328000000023D
-:101D90000622640000000030062280C00000000817
-:101DA0000222116000000000062233300000000211
-:101DB000062264C000000030062280E00000000817
-:101DC00002221164000000000622333800000002E5
-:101DD0000622658000000030021610000000002876
-:101DE00002170008000000020217002C0000000388
-:101DF0000217003C00000004021700440000000825
-:101E000002170048000000020217004C000000907A
-:101E1000021700500000009002170054008000904C
-:101E20000217005808140000021700600000008A22
-:101E300002170064000000800217006800000081A3
-:101E40000217006C000000800217007000000006FE
-:101E500002170078000007D00217007C0000076C12
-:101E600002170038007C1004021700040000000F65
-:101E70000616402400000002021640700000001CFC
-:101E80000216420800000001021642100000000184
-:101E90000216422000000001021642280000000144
-:101EA0000216423000000001021642380000000114
-:101EB00002164260000000020C16401C0003D09085
-:101EC0000A16401C0000009C0B16401C000009C4B0
-:101ED0000216403000000008021640340000000CDA
-:101EE0000216403800000010021640440000002096
-:101EF0000216400000000001021640D80000000158
-:101F000002164008000000010216400C000000010B
-:101F100002164010000000010216424000000000BE
-:101F2000021642480000000006164270000000023F
-:101F30000216425000000000021642580000000045
-:101F40000616428000000002021660080000042409
-:101F50000216600C00000410021660100000041449
-:101F60000216601C0000FFFF021660200000FFFF49
-:101F7000021660240000FFFF021660280000FFFF29
-:101F800002166038000000200216603C00000020AD
-:101F90000216604000000034021660440000003564
-:101FA00002166048000000230216604C0000002466
-:101FB0000216605000000025021660540000002642
-:101FC00002166058000000270216605C000000291D
-:101FD000021660600000002A021660640000002BF8
-:101FE000021660680000002C0216606C0000002DD4
-:101FF0000616607000000052021661B80000000171
-:10200000061661BC0000001F0216623807FFFFFFC2
-:102010000216623C0000003F0216624007FFFFFF0D
-:10202000021662440000000F011662480000000022
-:102030000116624C00000000011662500000000012
-:1020400001166254000000000116625800000000F2
-:102050000116625C000000000116626000000000D2
-:1020600001166264000000000116626800000000B2
-:102070000116626C00000000011662700000000092
-:102080000116627400000000011662780000000072
-:102090000116627C000000000C166000000003E8DE
-:1020A0000A166000000000010B1660000000000A24
-:1020B0000216804000000006021680440000000561
-:1020C000021680480000000A0216804C000000053D
-:1020D0000216805400000002021680CC00000004AA
-:1020E000021680D000000004021680D40000000414
-:1020F000021680D800000004021680DC00000004F4
-:10210000021680E000000004021680E400000004D3
-:10211000021680E800000004021688040000000493
-:10212000021680300000007C021680340000003D62
-:10213000021680380000003F0216803C0000009C20
-:10214000021680F000000007061680F4000000056B
-:102150000216880C0101010102168108000000002E
-:102160000216810C00000004021681100000000419
-:1021700002168114000000020216881008012004D3
-:1021800002168118000000050216811C00000005DF
-:1021900002168120000000050216812400000005BF
-:1021A0000216882C20081001021681280000000861
-:1021B0000216812C00000006021681300000000784
-:1021C000021681340000000002168830010101204F
-:1021D000061681380000000402168834010101014E
-:1021E00002168148000000000216814C0000000425
-:1021F0000216815000000004021681540000000203
-:1022000002168838080120040216815800000005D3
-:102210000216815C000000050216816000000005C6
-:1022200002168164000000050216883C2008100197
-:1022300002168168000000080216816C000000068A
-:102240000216817000000007021681740000000170
-:102250000216884001010120021681780000000169
-:102260000216817C0000000102168180000000013E
-:102270000216818400000001021688440101010158
-:1022800002168188000000010216818C0000000403
-:1022900002168190000000040216819400000002E2
-:1022A00002168848080120040216819800000005E3
-:1022B0000216819C00000005021681A000000005A6
-:1022C000021681A4000000050216881420081001DF
-:1022D000021681A800000008021681AC000000066A
-:1022E000021681B000000007021681B40000000150
-:1022F0000216881801010120021681B800000001B1
-:10230000021681BC00000001021681C0000000011D
-:10231000021681C4000000010216881C010101019F
-:10232000021681C800000001021681CC00000004E2
-:10233000021681D000000004021681D400000002C1
-:102340000216882008012004021681D8000000052A
-:10235000021681DC00000005021681E00000000585
-:10236000021681E4000000050216882420081001EE
-:10237000021681E800000008021681EC0000000649
-:10238000021681F0000000070216E40C00000000B5
-:1023900002168828010101200616E410000000043E
-:1023A0000216E000010101010216E4200000000015
-:1023B0000216E424000000040216E42800000004D1
-:1023C0000216E42C000000020216E00408012004BA
-:1023D0000216E430000000050216E4340000000597
-:1023E0000216E438000000050216E43C0000000577
-:1023F0000216E008200810010216E4400000000860
-:102400000216E444000000060216E448000000073B
-:102410000216E44C000000000216E00C010101204D
-:102420000616E450000000040216E010010101014C
-:102430000216E460000000000216E46400000004DC
-:102440000216E468000000040216E46C00000002BA
-:102450000216E014080120040216E47000000005D2
-:102460000216E474000000050216E478000000057E
-:102470000216E47C000000050216E0182008100196
-:102480000216E480000000080216E4840000000642
-:102490000216E488000000070216E48C0000000128
-:1024A0000216E01C010101200216E4900000000168
-:1024B0000216E494000000010216E49800000001F6
-:1024C0000216E49C000000010216E0200101010157
-:1024D0000216E4A0000000010216E4A400000004BB
-:1024E0000216E4A8000000040216E4AC000000029A
-:1024F0000216E024080120040216E4B000000005E2
-:102500000216E4B4000000050216E4B8000000055D
-:102510000216E4BC000000050216E02820081001A5
-:102520000216E4C0000000080216E4C40000000621
-:102530000216E4C8000000070216E4CC0000000107
-:102540000216E02C010101200216E4D00000000177
-:102550000216E4D4000000010216E4D800000001D5
-:102560000216E4DC000000010216E0300101010166
-:102570000216E4E0000000010216E4E4000000049A
-:102580000216E4E8000000040216E4EC0000000279
-:102590000216E034080120040216E4F000000005F1
-:1025A0000216E4F4000000050216E4F8000000053D
-:1025B0000216E4FC000000050216E03820081001B5
-:1025C0000216E500000000080216E50400000006FF
-:1025D0000216E508000000070216E03C0101012098
-:1025E00002168240003F003F0216824400000000B5
-:1025F0000216E524003F003F0216E5280000000017
-:1026000002168248000000000216824C003F003F84
-:102610000216E52C000000000216E530003F003FE6
-:1026200002168250010001000216825401000100CE
-:102630000216E534010001000216E5380100010030
-:1026400006168258000000020216E53C0000000059
-:102650000216E540000000000216826000C000C0C3
-:102660000216826400C000C00216E54400C000C02B
-:102670000216E54800C000C0021682681E001E0057
-:102680000216826C1E001E000216E54C1E001E0083
-:102690000216E5501E001E00021682704000400027
-:1026A00002168274400040000216E55440004000CB
-:1026B0000216E55840004000021682788000800033
-:1026C0000216827C800080000216E55C800080009B
-:1026D0000216E56080008000021682802000200043
-:1026E00002168284200020000216E56420002000EB
-:1026F0000216E5682000200006168288000000020D
-:102700000216E56C000000000216E57000000000F3
-:102710000216829000000000021682940000000061
-:102720000216E574000000000216E57800000000C3
-:1027300002168298000000000216829C0000000031
-:102740000216E57C000000000216E5800000000093
-:10275000021682A000000000021682A40000000100
-:10276000061682A80000000A021681F400000C0878
-:10277000021681F800000040021681FC00000100F2
-:1027800002168200000000200216820400000017DA
-:1027900002168208000000800216820C000002006F
-:1027A00002168210000000000216821801FF01FFCD
-:1027B0000216821401FF01FF0216E51001FF01FF5E
-:1027C0000216E50C01FF01FF0216823C0000001317
-:1027D000021680900000013F021680600000014058
-:1027E00002168064000001400616806800000002A6
-:1027F00002168070000000C00616807400000007FA
-:102800000216809C00000048021680A000000048CC
-:10281000061680A400000002021680AC00000048EA
-:10282000061680B000000007021682380000800003
-:1028300002168234000025E40216809400007FFF17
-:1028400002168220000F000F0216821C000F000FDC
-:102850000216E518000F000F0216E514000F000F16
-:10286000021682280000000002168224FFFFFFFFEC
-:102870000216E520000000000216E51CFFFFFFFF26
-:102880000216E6BC000000000216E6C000000002CE
-:102890000216E6C4000000010216E6C800000003AC
-:1028A0000216E6CC000000040216E6D00000000686
-:1028B0000216E6D4000000050216E6D80000000764
-:1028C000021680EC000000FF02140000000000016E
-:1028D0000214000C0000000102140040000000017E
-:1028E0000214004400007FFF0214000C00000000EE
-:1028F00002140000000000000214006C0000000040
-:102900000214000400000001021400300000000165
-:1029100002140004000000000214005C000000002B
-:10292000021400080000000102140034000000013D
-:102930000214000800000000021400600000000003
-:102940000202005800000032020200A0031500201D
-:10295000020200A403150020020200A801000030BA
-:10296000020200AC08100000020200B000000033B8
-:10297000020200B400000030020200B80000003182
-:10298000020200BC00000003020200C000000006BA
-:10299000020200C400000003020200C8000000039D
-:1029A000020200CC00000002020200D00000000081
-:1029B000020200D400000002020200DC000000005D
-:1029C000020200E000000006020200E40000000431
-:1029D000020200E800000002020200EC0000000217
-:1029E000020200F000000001020200FC00000006EC
-:1029F0000202012000000000020201340000000277
-:102A0000020201B0000000010202020C00000001FD
-:102A1000020202140000000102020218000000027B
-:102A200002020404000000010202040C0000004045
-:102A300002020410000000400202041C0000000416
-:102A40000202042000000020020204240000000210
-:102A50000202042800000020060205000000001207
-:102A600004020480001F032A020200600000000F1D
-:102A70000202006400000007020200680000000B70
-:102A80000202006C0000000E020200700000000E46
-:102A90000602007400000003020200F400000004BB
-:102AA0000202000400000001020200080000000110
-:102AB0000202000C000000010202001000000001F0
-:102AC00002020014000000010202001800000001D0
-:102AD0000202001C000000010202002000000001B0
-:102AE0000202002400000001020200280000000190
-:102AF0000202002C00000001020200300000000170
-:102B0000020200340000000102020038000000014F
-:102B10000202003C0000000102020040000000012F
-:102B2000020200440000000102020048000000010F
-:102B30000202004C000000010202005000000001EF
-:102B400002020108000000C8020201180000000291
-:102B5000020201C400000000020201CC00000000DB
-:102B6000020201D400000002020201DC00000002A7
-:102B7000020201E4000000FF020201EC000000FF7D
-:102B800002020100000000000202010C000000C867
-:102B90000202011C00000002020201C80000000045
-:102BA000020201D000000000020201D80000000271
-:102BB000020201E000000002020201E8000000FF42
-:102BC000020201F0000000FF020201040000000008
-:102BD00002020108000000C8020201180000000201
-:102BE000020201C400000000020201CC000000004B
-:102BF000020201D400000002020201DC0000000217
-:102C0000020201E4000000FF020201EC000000FFEC
-:102C100002020100000000000202010C000000C8D6
-:102C20000202011C00000002020201C800000000B4
-:102C3000020201D000000000020201D800000002E0
-:102C4000020201E000000002020201E8000000FFB1
-:102C5000020201F0000000FF020201040000000077
-:102C600002020108000000C8020201180000000270
-:102C7000020201C400000000020201CC00000000BA
-:102C8000020201D400000002020201DC0000000286
-:102C9000020201E4000000FF020201EC000000FF5C
-:102CA00002020100000000000202010C000000C846
-:102CB0000202011C00000002020201C80000000024
-:102CC000020201D000000000020201D80000000250
-:102CD000020201E000000002020201E8000000FF21
-:102CE000020201F0000000FF0202010400000000E7
-:102CF00002020108000000C80202011800000002E0
-:102D0000020201C400000000020201CC0000000029
-:102D1000020201D400000002020201DC00000002F5
-:102D2000020201E4000000FF020201EC000000FFCB
-:102D300002020100000000000202010C000000C8B5
-:102D40000202011C00000002020201C80000000093
-:102D5000020201D000000000020201D800000002BF
-:102D6000020201E000000002020201E8000000FF90
-:102D7000020201F0000000FF020201040000000056
-:102D80000728040000C00000082807A8000B03491A
-:102D9000072C000032FC0000072C800035780CC0A6
-:102DA000072D00003AC11A1F072D800039E228D0F4
-:102DB000072E00001C3E3749082E3710391E034BE2
-:102DC00001280000000000000128000400000000AD
-:102DD00001280008000000000128000C000000008D
-:102DE000012800100000000001280014000000006D
-:102DF0000228002000000001022800240000000238
-:102E000002280028000000030228002C0000000017
-:102E100002280030000000040228003400000001F5
-:102E200002280038000000000228003C00000001D9
-:102E300002280040000000040228004400000000B6
-:102E400002280048000000010228004C0000000396
-:102E50000228005000000000022800540000000179
-:102E600002280058000000040228005C0000000056
-:102E70000228006000000001022800640000000336
-:102E800002280068000000000228006C0000000119
-:102E900002280070000000040228007400000000F6
-:102EA00002280078000000040228007C00000003D3
-:102EB0000628008000000002022800A400003FFF56
-:102EC000022800A8000003FF0228022400000000DE
-:102ED00002280234000000000228024C000000001A
-:102EE000022802E40000FFFF06282000000008007E
-:102EF000022B8BC000000001022B800000000000AC
-:102F0000022B804000000018022B80800000000C83
-:102F1000022B80C0000000660C2B83000007A1205C
-:102F20000A2B8300000001380B2B8300000013885C
-:102F3000022B83C0000001F40C2B8340000001F43D
-:102F40000A2B8340000000000B2B8340000000058B
-:102F50000A2B83800004C4B40C2B83801DCD650034
-:102F60000A2B1480000000000B2B8380004C4B4088
-:102F7000022B148000000001062A29C8000000046A
-:102F8000042A29D80002034D062A208000000048A8
-:102F9000062A9020000000C8062A900000000002C7
-:102FA000062A21A800000086062A20000000002032
-:102FB000022A23C800000000042A23D00002034F85
-:102FC000042A249800040351022A2C500000000017
-:102FD000022A2C1000000000042A2C0800020355CD
-:102FE000042A300000020357062A300800000100BE
-:102FF000062A404000000010042A40000010035937
-:10300000062A6AC000000002062A6B0000000004C5
-:10301000042A840800020369022B08000000000053
-:10302000042B0C000010036B022B080001000000B1
-:10303000042B0C400008037B022B08000200000058
-:10304000042B0C6000080383062AC000000000D88F
-:10305000062A24A800000014062A254800000022A1
-:10306000042A25D00002038B062A266800000022CD
-:10307000042A26F00002038D062A27880000002279
-:10308000042A28100002038F062A28A80000002224
-:10309000042A293000020391062AA000000000281B
-:1030A000062AA1400000000C042A29E00002039334
-:1030B000062A502000000002062A503000000002BC
-:1030C000062A500000000002062A501000000002EC
-:1030D000022A520800000001042A6AC8000203956F
-:1030E000062A6B1000000042062A6D200000000432
-:1030F000062ABCD000000002062AC360000000D8E7
-:10310000062A24F800000014062A25D80000002210
-:10311000042A266000020397062A26F800000022EF
-:10312000042A278000020399062A2818000000229A
-:10313000042A28A00002039B062A29380000002246
-:10314000042A29C00002039D062AA0A0000000282E
-:10315000062AA1700000000C042A29E80002039F3F
-:10316000062A502800000002062A503800000002FB
-:10317000062A500800000002062A5018000000022B
-:10318000022A520C00000001042A6AD0000203A1A6
-:10319000062A6C1800000042062A6D300000000468
-:1031A000062ABCD800000002022AC6C000000000A7
-:1031B000042A29F0001003A3062A50480000000E3C
-:1031C000062AB00000000006022AC6C40000000063
-:1031D000042A2A30001003B3062A50800000000E93
-:1031E000062AB01800000006022AC6C80000000027
-:1031F000042A2A70001003C3062A50B80000000EEB
-:10320000062AB03000000006022AC6CC00000000EA
-:10321000042A2AB0001003D3062A50F00000000E42
-:10322000062AB04800000006022AC6D000000000AE
-:10323000042A2AF0001003E3062A51280000000E99
-:10324000062AB06000000006022AC6D40000000072
-:10325000042A2B30001003F3062A51600000000EF0
-:10326000062AB07800000006022AC6D80000000036
-:10327000042A2B7000100403062A51980000000E47
-:10328000062AB09000000006022AC6DC00000000FA
-:10329000042A2BB000100413062A51D00000000E9F
-:1032A000062AB0A800000006021010080000000165
-:1032B0000210105000000001021010000003D000A6
-:1032C000021010040000003D091018000200042341
-:1032D0000910110000280623061011A00000001894
-:1032E00006102400000000E00210201C0000000076
-:1032F0000210202000000001021020C00000000287
-:10330000021020040000000102102008000000014B
-:1033100009103C000005064B091038000005065056
-:10332000091038200005065506104C000000010069
-:1033300002104028000000100210404400003FFF2F
-:103340000210405800280000021040840084924A75
-:1033500002104058000000000210800000001080A1
-:10336000021080AC00000000021080380000001045
-:103370000210810000000000061081200000000201
-:1033800002108008000002B502108010000000004A
-:10339000061082000000004A021081080001FFFFB1
-:1033A00006108140000000020210800000001A8018
-:1033B0000610900000000024061091200000004A32
-:1033C000061093700000004A061095C00000004AE5
-:1033D0000210800400001080021080B00000000184
-:1033E0000210803C00000010021081040000000068
-:1033F00006108128000000020210800C000002B5B7
-:103400000210801400000000061084000000004A32
-:103410000210810C0001FFFF06108148000000022D
-:103420000210800400001A80061090900000002412
-:10343000061092480000004A061094980000004AC6
-:10344000061096E80000004A02108000000010807C
-:10345000021080AC00000002021080380000001052
-:103460000210810000000000061081200000000210
-:1034700002108008000002B5021080100000000059
-:10348000061082000000004A021081080001FFFFC0
-:1034900006108140000000020210800000001A8027
-:1034A0000610900000000024061091200000004A41
-:1034B000061093700000004A061095C00000004AF4
-:1034C0000210800400001080021080B00000000391
-:1034D0000210803C00000010021081040000000077
-:1034E00006108128000000020210800C000002B5C6
-:1034F0000210801400000000061084000000004A42
-:103500000210810C0001FFFF06108148000000023C
-:103510000210800400001A80061090900000002421
-:10352000061092480000004A061094980000004AD5
-:10353000061096E80000004A02108000000010808B
-:10354000021080AC0000000402108038000000105F
-:10355000021081000000000006108120000000021F
-:1035600002108008000002B5021080100000000068
-:10357000061082000000004A021081080001FFFFCF
-:1035800006108140000000020210800000001A8036
-:103590000610900000000024061091200000004A50
-:1035A000061093700000004A061095C00000004A03
-:1035B0000210800400001080021080B0000000059E
-:1035C0000210803C00000010021081040000000086
-:1035D00006108128000000020210800C000002B5D5
-:1035E0000210801400000000061084000000004A51
-:1035F0000210810C0001FFFF06108148000000024C
-:103600000210800400001A80061090900000002430
-:10361000061092480000004A061094980000004AE4
-:10362000061096E80000004A02108000000010809A
-:10363000021080AC0000000602108038000000106C
-:10364000021081000000000006108120000000022E
-:1036500002108008000002B5021080100000000077
-:10366000061082000000004A021081080001FFFFDE
-:1036700006108140000000020210800000001A8045
-:103680000610900000000024061091200000004A5F
-:10369000061093700000004A061095C00000004A12
-:1036A0000210800400001080021080B000000007AB
-:1036B0000210803C00000010021081040000000095
-:1036C00006108128000000020210800C000002B5E4
-:1036D0000210801400000000061084000000004A60
-:1036E0000210810C0001FFFF06108148000000025B
-:1036F0000210800400001A80061090900000002440
-:10370000061092480000004A061094980000004AF3
-:10371000061096E80000004A021205B00000000101
-:103720000212049000E383400212051400003C10D2
-:103730000212066C00000001021206700000000078
-:1037400002120494FFFFFFFF02120498FFFFFFFF25
-:103750000212049CFFFFFFFF021204A0FFFFFFFF05
-:10376000021204A4FFFFFFFF021204A8FFFFFFFFE5
-:10377000021204ACFFFFFFFF021204B0FFFFFFFFC5
-:10378000021204BCFFFFFFFF021204C0FFFFFFFF95
-:10379000021204C4FFFFFFFF021204C8FFFFFFFF75
-:1037A000021204CCFFFFFFFF021204D0FFFFFFFF55
-:1037B000021204D8FFFFFFFF021204DCFFFFFFFF2D
-:1037C000021204E0FFFFFFFF021204E4FFFFFFFF0D
-:1037D000021204E8FFFFFFFF021204ECFFFFFFFFED
-:1037E000021204F0FFFFFFFF021204F4FFFFFFFFCD
-:1037F000021204F8FFFFFFFF021204FCFFFFFFFFAD
-:1038000002120500FFFFFFFF02120504FFFFFFFF8A
-:1038100002120508FFFFFFFF0212050CFFFFFFFF6A
-:1038200002120510FFFFFFFF021204D4FF802000E8
-:10383000021204B4F0005000021204B8F0001000AC
-:1038400002120390000000080212039C000000080E
-:10385000021203A000000008021203A400000002EC
-:10386000021203BC00000004021203C000000005A5
-:10387000021203C400000004021203D00000000082
-:103880000212036C00000001021203680000003FF6
-:10389000021201BC00000040021201C00000180822
-:1038A000021201C400000803021201C8000008034C
-:1038B000021201CC00000040021201D000000003FF
-:1038C000021201D400000803021201D8000008030C
-:1038D000021201DC00000803021201E000010003F3
-:1038E000021201E400000803021201E800000803CC
-:1038F000021201EC00000003021201F000000003BC
-:10390000021201F400000003021201F8000000039B
-:10391000021201FC0000000302120200000000037A
-:103920000212020400000003021202080000000359
-:103930000212020C00000003021202100000000339
-:103940000212021400000003021202180000000319
-:103950000212021C000000030212022000000003F9
-:1039600002120224000000030212022800002403B5
-:103970000212022C0000002F021202300000000987
-:103980000212023400000019021202380000018401
-:103990000212023C000001830212024000000306F2
-:1039A0000212024400000019021202480000000640
-:1039B0000212024C0000030602120250000003062D
-:1039C00002120254000003060212025800000C8684
-:1039D0000212025C000003060212026000000306ED
-:1039E00002120264000000060212026800000006D3
-:1039F0000212026C000000060212027000000006B3
-:103A00000212027400000006021202780000000692
-:103A10000212027C00000006021202800000000672
-:103A20000212028400000006021202880000000652
-:103A30000212028C00000006021202900000000632
-:103A40000212029400000006021202980000000612
-:103A50000212029C00000006021202A000000306EF
-:103A6000021202A400000013021202A800000006C5
-:103A7000021202B000001004021202B4000010048E
-:103A80000212032400106440021203280010644054
-:103A9000021205B400000001021201B00000000192
-:103AA0000600A000000000160200A0EC5554000023
-:103AB0000200A0F0555555550200A0F400005555E0
-:103AC0000200A0F8F00000000200A0FC5554000025
-:103AD0000200A100555555550200A104000055559E
-:103AE0000200A108F00000000200A18C5554000063
-:103AF0000200A190555555550200A194000055555E
-:103B00000200A198F00000000200A19C000000004B
-:103B10000200A1A0000100000200A1A400005014B6
-:103B20000200A1A8000000000200A45C00000C003C
-:103B30000200A61C000000030200A06CFF5C000055
-:103B40000200A070FFF55FFF0200A0740000FFFFFD
-:103B50000200A078F00003E00200A07C000000005A
-:103B60000200A0800000A0000600A0840000000564
-:103B70000200A0980FE000000600A09C00000007D3
-:103B80000200A0B8000004000600A0BC0000000372
-:103B90000200A0C8000010000600A0CC0000000336
-:103BA0000200A0D8000040000600A0DC00000003D6
-:103BB0000200A0E8000100000600A22C00000004A2
-:103BC0000200A10CFF5C00000200A110FFF55FFFE6
-:103BD0000200A1140000FFFF0200A118F00003E0A2
-:103BE0000200A11C000000000200A1200000A000B3
-:103BF0000600A124000000050200A1380FE000002B
-:103C00000600A13C000000070200A15800000800C7
-:103C10000600A15C000000030200A1680000200073
-:103C20000600A16C000000030200A17800008000E3
-:103C30000600A17C000000030200A1880002000031
-:103C40000600A23C0000000400000000000000008C
-:103C50000000003100000000000000000000000033
-:103C60000000000000000000000000000000000054
-:103C700000000000000000000000000000310032E1
-:103C80000000000000000000000000000000000034
-:103C90000000000000000000000000000000000024
-:103CA000000000000000000000320056000000008C
-:103CB0000000000000000000000000000000000004
-:103CC00000000000000000000000000000000000F4
-:103CD000000000000056008C000000000000000002
-:103CE000008C009000900094009400980098009C34
-:103CF000009C00A000A000A400A400A800A800ACA4
-:103D000000AC00B100B100B300B300B5000000008A
-:103D100000000000000000000000000000000000A3
-:103D200000000000000000000000000000B50102DB
-:103D30000102010A010A01120112011B011B0124E7
-:103D40000124012D012D01360136013F013F0148BB
-:103D5000014801510151015A00000000000000001B
-:103D60000000000000000000000000000000000053
-:103D70000000000000000000000000000000000043
-:103D80000000000000000000000000000000000033
-:103D90000000000000000000000000000000000023
-:103DA0000000000000000000000000000000000013
-:103DB0000000000000000000000000000000000003
-:103DC00000000000000000000000000000000000F3
-:103DD00000000000000000000000000000000000E3
-:103DE00000000000000000000000000000000000D3
-:103DF00000000000000000000000000000000000C3
-:103E00000000000000000000015A015F00000000F7
-:103E100000000000015F0160016001610161016259
-:103E2000016201630163016401640165016501666A
-:103E300001660167000000000000000000000000B3
-:103E40000000000000000000000000000000000072
-:103E50000000000000000000000000000000000062
-:103E60000167016C016C0179017901860000000095
-:103E70000000000000000000000000000000000042
-:103E80000000000000000000000000000000000032
-:103E90000000000000000000000000000000000022
-:103EA0000000000000000000000000000000000012
-:103EB00000000000000000000186018700000000F3
-:103EC00000000000000000000000000000000000F2
-:103ED00000000000000000000000000000000000E2
-:103EE00000000000018701BE00000000000000008B
-:103EF00000000000000000000000000000000000C2
-:103F000000000000000000000000000000000000B1
-:103F100001BE01E9000000000000000000000000F8
-:103F20000000000000000000000000000000000091
-:103F300000000000000000000000000001E9021A7B
-:103F40000000000000000000021A022102210228E5
-:103F50000228022F022F02360236023D023D0244A1
-:103F60000244024B024B02520252028A000000003D
-:103F700000000000028A028E028E029202920296D5
-:103F80000296029A029A029E029E02A202A202A631
-:103F900002A602AA02AA02FA02FA031103110328D6
-:103FA0000328032B032B032E032E03310331033489
-:103FB000033403370337033A033A033D033D034019
-:103FC00003400381038103880388038F038F0393D6
-:103FD000039303970397039B039B039F039F03A3F1
-:103FE00003A303A703A703AB03AB03AF03AF03B064
-:103FF00000000000000000000000000000000000C1
-:1040000000000000000000000000000000000000B0
-:10401000000000000000000003B003C20000000028
-:104020000000000000000000000000000000000090
-:104030000000000000000000000000000000000080
-:104040000000000003C203D703D703DA03DA03DD5D
-:104050000000000000000000000000000000000060
-:104060000000000000000000000000000000000050
-:1040700003DD040A00000000000000000000000052
-:104080000000000000000000000000000000000030
-:10409000000000000000000000000000040A050D00
-:1040A0000000000000000000000000000000000010
-:1040B0000000000000000000000000000000000000
-:1040C0000000000000000000050D0514051405188F
-:1040D0000518051C000000000000000000000000A2
-:1040E00000000000000000000000000000000000D0
-:1040F00000000000051C055C00000000000000003E
-:10410000055C05650565056E056E05770577058017
-:1041100005800589058905920592059B059B05A4E7
-:1041200005A405FD05FD0613061306290629062D1F
-:10413000062D063106310635063506390639063DA7
-:10414000063D064106410645064506490649065014
-:10415000000000000000000000000000000000005F
-:10416000000000000000000000000000000000004F
-:10417000000000000000000006500656000000008D
-:10418000000000000000000000000000000000002F
-:10419000000000000000000000000000000000001F
-:1041A0000000000006560659000000000000000054
-:1041B00000000000000000000000000000000000FF
-:1041C00000000000000000000000000000000000EF
-:1041D0000659065F0000000000000000000000001B
-:1041E00000000000000000000000000000000000CF
-:1041F00000000000000000000000000000000000BF
-:104200000000000000000000065F066E066E067DDE
-:10421000067D068C068C069B069B06AA06AA06B996
-:1042200006B906C806C806D706D70748000000002A
-:10423000000000000000000000000000000000007E
-:10424000000000000000000000000000000000006E
-:10425000000000000748075B075B076C076C077DE1
-:10426000000000000000000000000000000000004E
-:10427000000000000000000000000000000000003E
-:10428000000000000000000000000000000000002E
-:10429000000000000000000000000000000000001E
-:1042A000000000000000000000000000000000000E
-:1042B00000000000000000000000000000000000FE
-:1042C00000000000000000000000000000000000EE
-:1042D00000000000000000000000000000000000DE
-:1042E00000010000000204C00003098000040E4029
-:1042F00000051300000617C000071C8000082140BD
-:1043000000092600000A2AC0000B2F80000C344050
-:10431000000D3900000E3DC0000F428000104740E4
-:1043200000114C00001250C00013558000145A4078
-:1043300000155F00001663C00017688000186D400C
-:1043400000197200001A76C0001B7B80001C8040A0
-:10435000001D8500001E89C0001F8E800020934034
-:10436000000020000000400000006000000080000D
-:104370000000A0000000C0000000E00000010000FC
-:1043800000012000000140000001600000018000E9
-:104390000001A0000001C0000001E00000020000D8
-:1043A00000022000000240000002600000028000C5
-:1043B0000002A0000002C0000002E00000030000B4
-:1043C00000032000000340000003600000038000A1
-:1043D0000003A0000003C0000003E0000004000090
-:1043E000000420000004400000046000000480007D
-:1043F0000004A0000004C0000004E000000500006C
-:104400000005200000054000000560000005800058
-:104410000005A0000005C0000005E0000006000047
-:104420000006200000064000000660000006800034
-:104430000006A0000006C0000006E0000007000023
-:104440000007200000074000000760000007800010
-:104450000007A0000007C0000007E00000080000FF
-:1044600000082000000840000008600000088000EC
-:104470000008A0000008C0000008E00000090000DB
-:1044800000092000000940000009600000098000C8
-:104490000009A0000009C0000009E000000A0000B7
-:1044A000000A2000000A4000000A6000000A8000A4
-:1044B000000AA000000AC000000AE000000B000093
-:1044C000000B2000000B4000000B6000000B800080
-:1044D000000BA000000BC000000BE000000C00006F
-:1044E000000C2000000C4000000C6000000C80005C
-:1044F000000CA000000CC000000CE000000D00004B
-:10450000000D2000000D4000000D6000000D800037
-:10451000000DA000000DC000000DE000000E000026
-:10452000000E2000000E4000000E6000000E800013
-:10453000000EA000000EC000000EE000000F000002
-:10454000000F2000000F4000000F6000000F8000EF
-:10455000000FA000000FC000000FE00000100000DE
-:1045600000102000001040000010600000108000CB
-:104570000010A0000010C0000010E00000110000BA
-:1045800000112000001140000011600000118000A7
-:104590000011A0000011C0000011E0000012000096
-:1045A0000012200000124000001260000012800083
-:1045B0000012A0000012C0000012E0000013000072
-:1045C000001320000013400000136000001380005F
-:1045D0000013A0000013C0000013E000001400004E
-:1045E000001420000014400000146000001480003B
-:1045F0000014A0000014C0000014E000001500002A
-:104600000015200000154000001560000015800016
-:104610000015A0000015C0000015E0000016000005
-:1046200000162000001640000016600000168000F2
-:104630000016A0000016C0000016E00000170000E1
-:1046400000172000001740000017600000178000CE
-:104650000017A0000017C0000017E00000180000BD
-:1046600000182000001840000018600000188000AA
-:104670000018A0000018C0000018E0000019000099
-:104680000019200000194000001960000019800086
-:104690000019A0000019C0000019E000001A000075
-:1046A000001A2000001A4000001A6000001A800062
-:1046B000001AA000001AC000001AE000001B000051
-:1046C000001B2000001B4000001B6000001B80003E
-:1046D000001BA000001BC000001BE000001C00002D
-:1046E000001C2000001C4000001C6000001C80001A
-:1046F000001CA000001CC000001CE000001D000009
-:10470000001D2000001D4000001D6000001D8000F5
-:10471000001DA000001DC000001DE000001E0000E4
-:10472000001E2000001E4000001E6000001E8000D1
-:10473000001EA000001EC000001EE000001F0000C0
-:10474000001F2000001F4000001F6000001F8000AD
-:10475000001FA000001FC000001FE000002000009C
-:104760000020200000204000002060000020800089
-:104770000020A0000020C0000020E0000021000078
-:104780000021200000214000002160000021800065
-:104790000021A0000021C0000021E0000022000054
-:1047A0000022200000224000002260000022800041
-:1047B0000022A0000022C0000022E0000023000030
-:1047C000002320000023400000236000002380001D
-:1047D0000023A0000023C0000023E000002400000C
-:1047E00000242000002440000024600000248000F9
-:1047F0000024A0000024C0000024E00000250000E8
-:1048000000252000002540000025600000258000D4
-:104810000025A0000025C0000025E00000260000C3
-:1048200000262000002640000026600000268000B0
-:104830000026A0000026C0000026E000002700009F
-:10484000002720000027400000276000002780008C
-:104850000027A0000027C0000027E000002800007B
-:104860000028200000284000002860000028800068
-:104870000028A0000028C0000028E0000029000057
-:104880000029200000294000002960000029800044
-:104890000029A0000029C0000029E000002A000033
-:1048A000002A2000002A4000002A6000002A800020
-:1048B000002AA000002AC000002AE000002B00000F
-:1048C000002B2000002B4000002B6000002B8000FC
-:1048D000002BA000002BC000002BE000002C0000EB
-:1048E000002C2000002C4000002C6000002C8000D8
-:1048F000002CA000002CC000002CE000002D0000C7
-:10490000002D2000002D4000002D6000002D8000B3
-:10491000002DA000002DC000002DE000002E0000A2
-:10492000002E2000002E4000002E6000002E80008F
-:10493000002EA000002EC000002EE000002F00007E
-:10494000002F2000002F4000002F6000002F80006B
-:10495000002FA000002FC000002FE000003000005A
-:104960000030200000304000003060000030800047
-:104970000030A0000030C0000030E0000031000036
-:104980000031200000314000003160000031800023
-:104990000031A0000031C0000031E0000032000012
-:1049A00000322000003240000032600000328000FF
-:1049B0000032A0000032C0000032E00000330000EE
-:1049C00000332000003340000033600000338000DB
-:1049D0000033A0000033C0000033E00000340000CA
-:1049E00000342000003440000034600000348000B7
-:1049F0000034A0000034C0000034E00000350000A6
-:104A00000035200000354000003560000035800092
-:104A10000035A0000035C0000035E0000036000081
-:104A2000003620000036400000366000003680006E
-:104A30000036A0000036C0000036E000003700005D
-:104A4000003720000037400000376000003780004A
-:104A50000037A0000037C0000037E0000038000039
-:104A60000038200000384000003860000038800026
-:104A70000038A0000038C0000038E0000039000015
-:104A80000039200000394000003960000039800002
-:104A90000039A0000039C0000039E000003A0000F1
-:104AA000003A2000003A4000003A6000003A8000DE
-:104AB000003AA000003AC000003AE000003B0000CD
-:104AC000003B2000003B4000003B6000003B8000BA
-:104AD000003BA000003BC000003BE000003C0000A9
-:104AE000003C2000003C4000003C6000003C800096
-:104AF000003CA000003CC000003CE000003D000085
-:104B0000003D2000003D4000003D6000003D800071
-:104B1000003DA000003DC000003DE000003E000060
-:104B2000003E2000003E4000003E6000003E80004D
-:104B3000003EA000003EC000003EE000003F00003C
-:104B4000003F2000003F4000003F6000003F800029
-:104B5000003FA000003FC000003FE000003FE00138
-:104B600000000000000001FF0000020000007FF8CC
-:104B700000007FF800000CDF0000150000000001BD
-:104B80000000000100000001FFFFFFFFFFFFFFFF2B
-:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
-:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
-:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
-:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
-:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
-:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
-:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
-:104C0000FFFFFFFFFFFFFFFFFFFFFFFF00000000B0
-:104C1000FFFFFFFF00000000FFFFFFFFFFFFFFFFA0
-:104C200000000000FFFFFFFF00000000FFFFFFFF8C
-:104C3000FFFFFFFF00000000FFFFFFFF000000007C
-:104C4000FFFFFFFF0000000300BEBC20FFFFFFFFCF
-:104C500000000000FFFFFFFF00000000FFFFFFFF5C
-:104C60000000000300BEBC20FFFFFFFF00000000AB
-:104C7000FFFFFFFF00000000FFFFFFFF0000000339
-:104C800000BEBC20FFFFFFFF00000000FFFFFFFF92
-:104C900000000000FFFFFFFF0000000300BEBC207B
-:104CA000FFFFFFFF00000000FFFFFFFF000000000C
-:104CB000FFFFFFFF0000000300BEBC20FFFFFFFF5F
-:104CC00000000000FFFFFFFF00000000FFFFFFFFEC
-:104CD0000000000300BEBC2000002000000040C017
-:104CE00000006180000082400000A3000000C3C0FB
-:104CF0000000E4800001054000012600000146C0DC
-:104D000000016780000188400001A9000001C9C0BE
-:104D10000001EA8000020B4000022C0000024CC09F
-:104D200000026D8000028E400002AF000002CFC082
-:104D30000002F0800003114000033200000352C063
-:104D400000037380000394400003B5000003D5C046
-:104D50000003F6800004174000043800000458C027
-:104D60000004798000049A40000080000001038064
-:104D70000001870000020A8000028E0000031180FB
-:104D8000000395000004188000049C0000051F80AB
-:104D90000005A300000626800006AA0000072D805B
-:104DA0000007B100000834800008B80000093B800B
-:104DB0000009BF00000A4280000AC600000B4980BB
-:104DC000000BCD00000C5080000CD400000D57806B
-:104DD000000DDB0000007FF800007FF80000192ABA
-:104DE0000000350000001900001000000000000065
-:104DF00000000000FFFFFFFF400000004000000037
-:104E000040000000400000004000000040000000A2
-:104E10004000000040000000400000004000000092
-:104E20004000000040000000400000004000000082
-:104E30004000000040000000400000004000000072
-:104E40004000000040000000400000004000000062
-:104E50004000000040000000400000004000000052
-:104E60004000000040000000400000004000000042
-:104E7000400000004000000000007FF800007FF8C4
-:104E8000000005C700001500FFFFFFFFFFFFFFFF49
-:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
-:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
-:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
-:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
-:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
-:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
-:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
-:104F0000FFFFFFFFFFFFFFFF400000004000000029
-:104F10004000000040000000400000004000000091
-:104F20004000000040000000400000004000000081
-:104F30004000000040000000400000004000000071
-:104F40004000000040000000400000004000000061
-:104F50004000000040000000400000004000000051
-:104F60004000000040000000400000004000000041
-:104F70004000000040000000400000004000000031
-:104F800040000000400000000000100000002080F1
-:104F900000003100000041800000520000006280EB
-:104FA0000000730000008380000094000000A480D3
-:104FB0000000B5000000C5800000D6000000E680BB
-:104FC0000000F700000107800001180000012880A0
-:104FD000000139000001498000015A0000016A8087
-:104FE00000017B0000018B8000019C000001AC806F
-:104FF0000001BD000001CD800001DE000001EE8057
-:105000000001FF0000007FF800007FF80000112E73
-:105010000000350010000000000028AD0000000076
-:1050200000010001000D0205CCCCCCC5FFFFFFFF45
-:10503000FFFFFFFF7058103C000000000000000060
-:1050400000000001CCCC0201CCCCCCCCCCCC0201F9
-:10505000CCCCCCCCCCCC0201CCCCCCCCCCCC0201BA
-:10506000CCCCCCCCCCCC0201CCCCCCCCCCCC0201AA
-:10507000CCCCCCCCCCCC0201CCCCCCCCCCCC02019A
-:10508000CCCCCCCC00000000FFFFFFFF40000000B4
-:105090004000000040000000400000004000000010
-:1050A0004000000040000000400000004000000000
-:1050B00040000000400000004000000040000000F0
-:1050C00040000000400000004000000040000000E0
-:1050D00040000000400000004000000040000000D0
-:1050E00040000000400000004000000040000000C0
-:1050F00040000000400000004000000040000000B0
-:10510000400000004000000040000000002625A0F4
-:1051100000000000002625A000000000002625A0B9
-:1051200000000000002625A000000000000E023252
-:10513000011600D60010000000000000002625A087
-:1051400000000000002625A000000000002625A089
-:1051500000000000002625A00000000000720236BA
-:10516000012300F300100000000000000000FFFF1A
-:10517000000000000000FFFF000000000000FFFF33
-:10518000000000000000FFFF000000000000FFFF23
-:10519000000000000000FFFF000000000000FFFF13
-:1051A000000000000000FFFF000000000000FFFF03
-:1051B000000000000000FFFF000000000000FFFFF3
-:1051C000000000000000FFFF000000000000FFFFE3
-:1051D000000000000000FFFF000000000000FFFFD3
-:1051E000000000000000FFFF000000000000FFFFC3
-:1051F000000000000000FFFF000000000000FFFFB3
-:10520000000000000000FFFF000000000000FFFFA2
-:10521000000000000000FFFF000000000000FFFF92
-:10522000000000000000FFFF000000000000FFFF82
-:10523000000000000000FFFF000000000000FFFF72
-:10524000000000000000FFFF000000000000FFFF62
-:10525000000000000000FFFF000000000000FFFF52
-:10526000000000000000FFFF000000000000FFFF42
-:10527000000000000000FFFF000000000000FFFF32
-:10528000000000000000FFFF000000000000FFFF22
-:10529000000000000000FFFF000000000000FFFF12
-:1052A000000000000000FFFF000000000000FFFF02
-:1052B000000000000000FFFF000000000000FFFFF2
-:1052C000000000000000FFFF000000000000FFFFE2
-:1052D000000000000000FFFF000000000000FFFFD2
-:1052E000000000000000FFFF000000000000FFFFC2
-:1052F000000000000000FFFF000000000000FFFFB2
-:10530000000000000000FFFF000000000000FFFFA1
-:10531000000000000000FFFF000000000000FFFF91
-:10532000000000000000FFFF000000000000FFFF81
-:10533000000000000000FFFF000000000000FFFF71
-:10534000000000000000FFFF000000000000FFFF61
-:10535000000000000000FFFF000000000000FFFF51
-:10536000000000000000FFFF00000000FFFFFFF34F
-:10537000318FFFFF0C30C30CC30C30C3CF3CF300A4
-:10538000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FF
-:1053900030EFFFFF0C30C30CC30C30C3CF3CF30025
-:1053A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D9
-:1053B000305FFFFF0C30C30CC30C30C3CF3CF30095
-:1053C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B3
-:1053D0001CBFFFFF0C30C305C30C30C3CF3000141B
-:1053E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF29A
-:1053F000304FFFFF0C30C30CC30C30C3CF3CF30065
-:10540000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6D
-:10541000302FFFFF0C30C30CC30C30C3CF3CF30064
-:10542000F3CF3CF30010CF3CCDCDCDCDFFFFFFF748
-:1054300031EFFFFF0C30C30CC30C30C3CF3CF30083
-:10544000F3CF3CF30020CF3CCDCDCDCDFFFFFFF51A
-:10545000302FFFFF0C30C30CC30C30C3CF3CF30024
-:10546000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DC
-:10547000318FFFFF0C30C30CC30C30C3CF3CF300A3
-:10548000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FE
-:10549000310FFFFF0C30C30CC30C30C3CF3CF30003
-:1054A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D8
-:1054B000305FFFFF0C30C30CC30C30C3CF3CF30094
-:1054C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B2
-:1054D0001CBFFFFF0C30C305C30C30C3CF3000141A
-:1054E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF299
-:1054F000304FFFFF0C30C30CC30C30C3CF3CF30064
-:10550000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6C
-:10551000302FFFFF0C30C30CC30C30C3CF3CF30063
-:10552000F3CF3CF30010CF3CCDCDCDCDFFFFFFF747
-:1055300030EFFFFF0C30C30CC30C30C3CF3CF30083
-:10554000F3CF3CF30020CF3CCDCDCDCDFFFFFFF519
-:10555000304FFFFF0C30C30CC30C30C3CF3CF30003
-:10556000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DB
-:1055700031EFFFFF0C30C30CC30C30C3CF3CF30042
-:10558000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FD
-:10559000310FFFFF0C30C30CC30C30C3CF3CF30002
-:1055A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D7
-:1055B000305FFFFF0C30C30CC30C30C3CF3CF30093
-:1055C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B1
-:1055D0001CBFFFFF0C30C305C30C30C3CF30001419
-:1055E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF298
-:1055F000304FFFFF0C30C30CC30C30C3CF3CF30063
-:10560000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6B
-:10561000302FFFFF0C30C30CC30C30C3CF3CF30062
-:10562000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A6
-:10563000056FFFFF0C30C30CC30C30C3CF3CC00060
-:10564000F3CF3CF30020CF3CCDCDCDCDFFFFFFF518
-:10565000310FFFFF0C30C30CC30C30C3CF3CF30041
-:10566000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DA
-:10567000320FFFFF0C30C30CC30C30C3CF3CF30020
-:10568000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FC
-:10569000310FFFFF0C30C30CC30C30C3CF3CF30001
-:1056A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D6
-:1056B000305FFFFF0C30C30CC30C30C3CF3CF30092
-:1056C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B0
-:1056D0001CBFFFFF0C30C305C30C30C3CF30001418
-:1056E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF297
-:1056F000304FFFFF0C30C30CC30C30C3CF3CF30062
-:10570000F3CF3CF30008CF3CCDCDCDCDFFFFFF8ADA
-:10571000042FFFFF0C30C30CC30C30C3CF3CC000C0
-:10572000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A5
-:1057300005CFFFFF0C30C30CC30C30C3CF3CC000FF
-:10574000F3CF3CF30020CF3CCDCDCDCDFFFFFFF517
-:10575000310FFFFF0C30C30CC30C30C3CF3CF30040
-:10576000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3D9
-:10577000316FFFFF0C30C30CC30C30C3CF3CF300C0
-:10578000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FB
-:10579000302FFFFF0C30C30CC30C30C3CF3CF300E1
-:1057A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D5
-:1057B000305FFFFF0C30C30CC30C30C3CF3CF30091
-:1057C000F3CF3CF30002CF3CCDCDCDCDFFFFFFF6B4
-:1057D00030BFFFFF0C30C30CC30C30C3CF3CF314FD
-:1057E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF296
-:1057F000304FFFFF0C30C30CC30C30C3CF3CF30061
-:10580000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA69
-:10581000302FFFFF0C30C30CC30C30C3CF3CF30060
-:10582000F3CF3CF30010CF3CCDCDCDCDFFFFFFF744
-:1058300031CFFFFF0C30C30CC30C30C3CF3CF3009F
-:10584000F3CF3CF30020CF3CCDCDCDCDFFFFFFF01B
-:10585000307FFFFF0C30C30CC30C30C3CF3CF300D0
-:10586000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCC
-:1058700030CFFFFF0C30C30CC30C30C3CF3CF3CC94
-:10588000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEC
-:1058900030CFFFFF0C30C30CC30C30C3CF3CF3CC74
-:1058A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCB
-:1058B00030CFFFFF0C30C30CC30C30C3CF3CF3CC54
-:1058C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFAA
-:1058D00030CFFFFF0C30C30CC30C30C3CF3CF3CC34
-:1058E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF88
-:1058F00030CFFFFF0C30C30CC30C30C3CF3CF3CC14
-:10590000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF63
-:1059100030CFFFFF0C30C30CC30C30C3CF3CF3CCF3
-:10592000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3B
-:1059300030CFFFFF0C30C30CC30C30C3CF3CF3CCD3
-:10594000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0B
-:1059500030CFFFFF0C30C30CC30C30C3CF3CF3CCB3
-:10596000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCB
-:1059700030CFFFFF0C30C30CC30C30C3CF3CF3CC93
-:10598000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEB
-:1059900030CFFFFF0C30C30CC30C30C3CF3CF3CC73
-:1059A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCA
-:1059B00030CFFFFF0C30C30CC30C30C3CF3CF3CC53
-:1059C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA9
-:1059D00030CFFFFF0C30C30CC30C30C3CF3CF3CC33
-:1059E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF87
-:1059F00030CFFFFF0C30C30CC30C30C3CF3CF3CC13
-:105A0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF62
-:105A100030CFFFFF0C30C30CC30C30C3CF3CF3CCF2
-:105A2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3A
-:105A300030CFFFFF0C30C30CC30C30C3CF3CF3CCD2
-:105A4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0A
-:105A500030CFFFFF0C30C30CC30C30C3CF3CF3CCB2
-:105A6000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCA
-:105A700030CFFFFF0C30C30CC30C30C3CF3CF3CC92
-:105A8000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEA
-:105A900030CFFFFF0C30C30CC30C30C3CF3CF3CC72
-:105AA000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFC9
-:105AB00030CFFFFF0C30C30CC30C30C3CF3CF3CC52
-:105AC000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA8
-:105AD00030CFFFFF0C30C30CC30C30C3CF3CF3CC32
-:105AE000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF86
-:105AF00030CFFFFF0C30C30CC30C30C3CF3CF3CC12
-:105B0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF61
-:105B100030CFFFFF0C30C30CC30C30C3CF3CF3CCF1
-:105B2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF39
-:105B300030CFFFFF0C30C30CC30C30C3CF3CF3CCD1
-:105B4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF09
-:105B500030CFFFFF0C30C30CC30C30C3CF3CF3CCB1
-:105B6000F3CF3CF30040CF3CCDCDCDCD000C0000B9
-:105B7000000700C000028130000B815800020210B3
-:105B800000010230000F024000010330000C000051
-:105B9000000800C000028140000B81680002022062
-:105BA0000001024000070250000202C0000F000086
-:105BB000000800F000028170000B81980002025082
-:105BC00000010270000B8280000803380010000002
-:105BD0000008010000028180000B81A80002026021
-:105BE00000018280000E829800080380000B0000F4
-:105BF000000100B0000280C0000580E80002014002
-:105C000000010160000E017000038250CCCCCCCCAE
-:105C1000CCCCCCCCCCCCCCCCCCCCCCCC00002000D4
-:105C2000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB4
-:105C300000002000CCCCCCCCCCCCCCCCCCCCCCCCB4
-:105C4000CCCCCCCC04002000000000000000000000
-:105C50001F8B080000000000000BFB51CFC0F003B9
-:105C60008A59051918AC84117C7A607E4ECAF43BBF
-:105C7000F232303803B12B103700F1616E06862303
-:105C8000DCC4EB3F298F607BCB32309403F1766923
-:105C90000606133984B8AE0203C33C203F012AF63E
-:105CA000144867CB53E6EEC182155431C564951193
-:105CB0006C452CF2C858094DBE461995AF4C40FFB3
-:105CC00040E3781D547E8F16847EAD0DA113D0E481
-:105CD0007BA1F28E507F25EA6037D789487FA7B233
-:105CE000A0B9078DDFCA88CA37E340E52741D5034D
-:105CF000000749300AC8030000000000000000004F
-:105D00001F8B080000000000000BED7D0D7854D5BE
-:105D1000B5E83E73CE9C9949CE4C26BF4C20C04975
-:105D2000082168A4C70069B0584F2060A8D40E1499
-:105D300069AC8A032244082452EBC3ABFD328100D4
-:105D4000010204B13414A44300A5B7B43752B4D44B
-:105D5000523AE0A7C5D6F7BDE0B356AFB66FB4145C
-:105D60007F8A12F3AED6BE6BEBDB6BEDBD93734E49
-:105D7000664810BDED7DEFC6CFEFB0CFD93F6BAF1A
-:105D8000BFBDD6DA6BEF71BBFC246F34211FC3DFBC
-:105D90007584FC2F8D1092DBFF747B4934FD738476
-:105DA00064E698D1441921C372CC389944DF075571
-:105DB000DD23F5B713CF9399334350AF25D70C119B
-:105DC000DA474BE67C1281BE227584E411A2780981
-:105DD000FE89FAEEE05C2F29C3577FFB587C9709B8
-:105DE00059172CCA8076CEFE09891132D95A7611FC
-:105DF00022FAA4EDBC006F068557A72F289C699353
-:105E00005CB1EB0B29DC7A0CE14E2FA070D3F2C908
-:105E100091CF78C7D0F2A66B5D86075BDF4D480552
-:105E200021ABA02FDA76D35571FE5D31A03C433E05
-:105E3000DCAC427B9D181E5AF65FD51857B19DA960
-:105E4000E5D37641C2DA054B97CC261308C930D585
-:105E50007EB8583D9C7F3AAFE7D1E9F7D2FEEFE933
-:105E6000A4ED3D3900A50409FB69FF958EEFA5332C
-:105E7000DF807ED389A55F3A8FEDF08F7C42BE40F4
-:105E8000FC39E7A0F3CF93CF031E487516215306C4
-:105E9000E2AF1F6F51A42F217536B8041D3418636B
-:105EA0000C21D7B7265E72E550784C17013CCD9493
-:105EB00035DF185ADE765A463C6CABEDF106359C60
-:105EC000DFEC7CDA6E34EF677425C5039DCF9E2628
-:105ED0005AF60CC46FC1A46E13F8C33FA95B22B479
-:105EE000BF0283906C3A9F60232D17D176247E6683
-:105EF0000CE52FF2009B6F94FEF771513F1E331992
-:105F00000A88E6C07326E091E2A9E01EC7FB4A8634
-:105F1000BF4C62C16B217213E2E90EC0DF95C8F37A
-:105F200063117FD12CC4EB50F127E011F80B723EC6
-:105F3000BEBE2651AB00DF4CA5F8037C513CA6D376
-:105F4000F9F6BEE489C985D08DD91D027C8BF95440
-:105F500032FED9C2E1DA08F81B879F5CAE1021BE81
-:105F6000B22E93C94B5C82727A199D01EDCF6732D4
-:105F7000FCCD903509C6DB5CCAF8940E20B92A071F
-:105F8000C245FFB0FD660A8F668167B3B7CB2BD1E0
-:105F9000F2760A6F14F04F8E04811FC5BC3DBACB58
-:105FA00086572594E6E07306A7806FBBC9E4D80244
-:105FB00007BE27DD5DAD1285F383192EB2491ABCE9
-:105FC000DF6D7DFDD8FB77F63B287C89A0AF98CEAE
-:105FD000EF8367656313C5CF66BDABD545E1D85682
-:105FE000CDE63B90CE97395E4F8FB77892653C8374
-:105FF000C9CBA73E0EC9B4CFAB32E80B965DFE38D5
-:1060000024B87034D03F153D3E35F8750ABF054FB2
-:10601000BEE2A004FDFBAE7AD04B50EE8F78010EAD
-:10602000E73803E0758CEB1C47298D9A0A96ECFA49
-:10603000C8138C1162D12F58478727D3CBE9865DCF
-:106040009FF84AEDFAD9A9CF15D03701686FD7D795
-:106050003D42CF083D3D69887AC6AC43788B48DF26
-:106060001FCAF3182ECFD30F253ABC147FC57B84EB
-:106070009E7EE057A5941F0E829EA6E5831D04D741
-:10608000C38347498CC935D3D713786713B8DEF972
-:10609000419FBEB1E3E7CA76731AE89D3262BA7CCB
-:1060A000B49F31878911A7EF0F93F8DCF1A0C78E59
-:1060B000B1F97BE97F563D7D05C7E395871B5D40C0
-:1060C000CF317BEC78BC82E3B7ECA8E33DC7DF15AA
-:1060D0000EFC6D837F507CE54B1C8F634909E27198
-:1060E000EA10D73B8E47A7BEEEC3E31EAAAF29DE58
-:1060F000B2830C8F2D6D2E02FAA137E642FD585A5D
-:10610000D8E842FDC9F5F6783EBFF17CBD3BC0F151
-:1061100027E02C9E6D5401DEC612E324E8E5CC7620
-:106120008A37027ABAA00ACA3B1E22489FB10FE9F9
-:106130002EAEDF109E4CBEFEEEA82E7F16E4A2F718
-:1061400021C590E9380789B1C62BF5E3379B8F9FAE
-:10615000CDF1F86543B6F1A1938ED91CAF4EFC94F6
-:106160001EB0E37FAC834E63DAEDE56C075D6E90A5
-:106170001CF6C710E9E15148D49305E518DA755EBD
-:106180008AFB5C5A967FFC940978D63AD8BBCC3609
-:1061900057AC908EE36F6165A54D8955513CDC0687
-:1061A00086172D8F6B2531B047E56A9324281EC7CB
-:1061B00005E344A678CBAE268837E2B02F05FD8AEA
-:1061C00039131473FECFF872B90FE8B52348F10EF6
-:1061D000EBE26C85B7377CE1ABFAF1EED40F5FAB45
-:1061E000B5E3FDA670BA0D5FB3F46C5B79E2E9E14B
-:1061F00017A593D01F828F04DE06D0A1D55EF65777
-:10620000DBCB4EFD13951CFA678874524F91529068
-:106210008B71AE34A3B37060BDED928BDB43DED8DF
-:10622000593ADE4222910CDAFF0A921805F83EA68E
-:10623000E9F87DA52B9107E50BA467E7C831FDFDC3
-:106240008F52C83189DAED1245EF6A0AD2702F8970
-:10625000A7A33D4CC2DE3C4401E245A2FFDF8AFC1D
-:10626000A2B8005F2382EC3D896628500E11F1A789
-:10627000239D3CFC9FF9AB9FF98B44E92BF1A70CC4
-:1062800074A4E3BB4904F9C14BDAB19C46BAF0A946
-:10629000916E7C06A8C68667900425786611039FD8
-:1062A000E48AD8637194C30782C8F7BE3F908FD346
-:1062B000FBE7B38ED36D3809FF48CA053AC4895746
-:1062C000EEE7433FE7436AAFA15ED64A19FF6A9300
-:1062D000E8BA5A86F28F7E17F988E2B702C665F5EA
-:1062E00005BEB772BB7A4B9317F5CDE6A6203ED517
-:1062F000A98D61002FB33AD17107A55786AE1AD781
-:10630000D3F90FABEE89839CF85B99DF966630FC7E
-:106310009EDCF8C44B8BE8FBB6428DF9412DCC9E38
-:10632000CDE0586C9B9C88ADA5F06D2DF41A56FFFE
-:1063300040E8A7ADD7260EEDA7DF3B75DA23FDEBCE
-:10634000AC3E9258037253A08226229B27FC930EE8
-:106350007A2DADB8A7C9AA77B40F65A6BC0AA25119
-:10636000E02B3ABF282CEF4EBE6A2BBF02F562DB52
-:10637000A967894E2B14D5C44DC0977F2A3565E98E
-:106380003CFC35BA2BAA8154465E053C67B4062511
-:1063900093E22FAB5A9F0632AA119DE96BA53B04ED
-:1063A000F23BA0FF91F1D01DB4BFE8B5AA7110D99E
-:1063B0004A77CDF7A796872D1BEFFDBA99C4AE0A91
-:1063C000BA24A4FBA96BF3F2C1FFF591607EFA2415
-:1063D000902F951C8475EBDA25A32349DAF5CB5968
-:1063E0005CD835499FA9DAA5CBA4B1CBD26F898BF4
-:1063F000C9A1CBE5C5676619E3A3A252EE17B71290
-:106400003396040E93C3AF2971C2FC39DDF559E20E
-:10641000EB6DAE2FB648A4B62BC9F74E0ECF0C7954
-:106420008F09EB6FC646B64EFA28A85D14BE2285CA
-:106430003E2DED66F1FA87F8F312F450DE4320307A
-:106440003943D3833EC7B8E259FE09C6DD46C79536
-:106450005D415CF704DE9DF4144F97CB87F53EB8A1
-:10646000F6C5101881A9E0D4414687D167017F861F
-:1064700050D713BD943D9DE35D6A7F5F74B1793859
-:10648000FB2507985D95C1D7AF93534A9AD1EF9DED
-:106490002DFC50BBDE007F18F451E701BAF01782E3
-:1064A000DE60E5CD318276566F1965E42288277467
-:1064B000A3BE2D20119463FA09CBAD5CFFAD07FD9F
-:1064C000479FEF93F02DAEC9A04762A7145A69F613
-:1064D000A4BBA7258B1FDD09F231F9D2D6A92FD293
-:1064E000E7426F7829F4AF19674C505B99F3249415
-:1064F00027A75C51F60CCDB5C80D91055F30796AC0
-:10650000E1FC0E723387966B8A93C3D9B9B1223FEF
-:1065100082FDE9C3D1EE50F4E1D67E3BBFCCE46A04
-:1065200087437E3AB8FCAF017EBCB479E6D5D0672C
-:10653000D08899A02EE7471B9F06BACD93221B5CFB
-:10654000B4DEBC7BC26E903FED40375D23F1FD268B
-:10655000C0478DDE0E94239AD91D85E7E6B245A883
-:106560009F7B436CEAA9F82ACD74D9FD27A73F3851
-:1065700044791C6F44A701BC7AED7B277375A05347
-:10658000E461806B64F86415A05DD3CF9859167AE6
-:106590006597327DB882F371E66C4A37D0778A19F5
-:1065A0009AE387688EB91FE63BD4F153F13DD89D3D
-:1065B00080AF6CCEE72D06E3732107195C0E5AE01D
-:1065C0003BE06B12E3FB96607930D93AB187AFF3C9
-:1065D000DFE37C5F4092EBA193AE4BB7C3C6D367BA
-:1065E000095DC1009EF749E469987F1697B3CCEA2C
-:1065F000980BE011F234DB38539D9D03768A5E0ED2
-:1066000076B118F71DCE6F0BBDE6AFA17D4D71B30E
-:106610009245E735AE8C18A05E6715674A563EFF77
-:106620006D5FFDF0F3505F2BEB46BF7CB076DD7CF9
-:106630007EF3A4F0CBC87F0FB42B5EA47BF815ECDF
-:10664000E7816EE2B5E89B228E6779E3A92AA04331
-:106650006F2309025FCED71B9F9680BF43E1752E43
-:10666000CB3C66E9763B9EF2F99BD0EFC8463B7F78
-:10667000D69076855CC2BA314A8AF400BCB31FE872
-:10668000467833AB993F4CE1EE45BDF2E9C3FDF1ED
-:10669000C5E07E13843517E47D1FEA330A9F225339
-:1066A00038C6CD8E2B5988F7330AC047F1ACCA16CD
-:1066B000391FAA7CEF00E0260F2EE72DF08F29600E
-:1066C00027477264E03B61F7264E12E66FD9E396E6
-:1066D000C25E0E84A8BD4CE525B32641C03FCE3E28
-:1066E0002D1BD7D32AC36A8804FE9FB063B3B85C5E
-:1066F0000AB8B6723B794B5308E5285BEB390D714C
-:10670000FEADF92E630D01F9AD40FB6D4755220436
-:106710007E60B0B262E31DB47D5B938EF5373619AF
-:10672000D87E4353253EDB6B5E47FB776B88D9BF32
-:106730009B9B4AB9D3C1E0CE1276728D885FDAE1B5
-:10674000A2ED6DFB1FA23E0959E25A4596F63AD3D7
-:106750003783B54F9F648F8BF5B53787D6DE67D803
-:10676000DB57998956F087833CEE2FF45E80D7097A
-:1067700056BAD06F1678F694DAE9DE5E937C3F471E
-:106780003C9DE3113DCD367F12AD43F85671F85272
-:10679000F5B38EC75F44D9CDED4567BD15325F1F98
-:1067A000F9BE54908FB5C3A4F8B0C461B239DF6D9F
-:1067B0009DCDFC321264F13AE197B909B1F9656EE9
-:1067C000BE1F8565D4F751A68F1DF08BF62A6F9FEB
-:1067D0000A0ED5D9DF59DA4F85A51F079CA9E073AA
-:1067E000EE939137EDFDA4D65F8E76E7874687015D
-:1067F000EDC06A28B596B31CE5E18EFA458EEF57D9
-:1068000038BE973BCAD738EA4F7394BFE4A83FD746
-:1068100051FEBAA3FE22C7F7658EEFAB1CE57FB22F
-:10682000D72FBBEB93E1F7FF333C09B91A88979850
-:106830006D9FD7295745243E2A0E7E43E6734BE0D1
-:106840005342969473CC1761712D129F60F55FFFD0
-:10685000A845FE00EB58E747665A98CAD581F6E787
-:1068600003A08FC4FBF3D2AB81F13A21F56A7C25FA
-:106870008B03B5A3DCA411E5F544295049C2F8996E
-:10688000575B8C28F716D3F7567DD5CEE4AD18FCB0
-:1068900022DA2EBA5D45BB2F3A92C4C6D2766A81FF
-:1068A000BDBE9BF74F7258FFF89EF65BAE307F215E
-:1068B000146EAF02D91D5EDB75129E4EFC84A64796
-:1068C000AF7E06E20B3B981F7E6006F5032C7AEE46
-:1068D0006685E9B7DB944BF64B5F9C28F7F77FE0C2
-:1068E0005B9AD14CAB1C0020C0EFFF963706F18CB1
-:1068F00051109F639B07189F1B49F81F8FC381BBD3
-:1069000008EBCB48ED34C6DBF4BAE029D0757395BB
-:10691000121CEF7B52CF7818CF957EFE6AB62EFE02
-:10692000ED63B47B38FE429B2B12518A3FB24D354A
-:10693000C61258520D94238F425A3CE5C01E0CDFFC
-:106940006B61D565EF157F16C4D9C2585641EFC2A9
-:106950003A067C24C3FE761CCB7E92C07206B76FCB
-:10696000C781B3087E00D125A6270D09F6994237C5
-:10697000503F3CC9BA1196AAC62993FBE39492CE24
-:10698000E29152DB337F91205E594A74B64FC5E3E2
-:10699000821B65E96388B70687B6CF13BAC54E5721
-:1069A000A2B49339163EBEA58F9E0C5F63426CFE67
-:1069B000A16D6A23F8310766D9F940D497954BF653
-:1069C00007774E18F3D9F141A63206E119C807B787
-:1069D00006213E2D4529DED2878EB7A06C7E5DC193
-:1069E00079122CFF40326F053A89B242CC05D6F2BB
-:1069F0006FE5F0422847A791D246ADBF1FFA7E71DE
-:106A00008AF74B93BD1F27ECD5B36CFD2EE1323EC8
-:106A10006C4FD005766461C7AA34AB7D55C2D7E907
-:106A2000473B8EF860BEBBEB93EB3FF1DCC2FDBD94
-:106A300054F502527718E841262BE460127BFC499A
-:106A4000E06F8B1E0D38ECC2EA966815B4CFAA75BC
-:106A500011880BD3F51DEDBA426E1FEE9C1A9554AA
-:106A60002A873B7611B48FB35A16F9ACF3C9E7F312
-:106A7000D9393B2F0DEC957D8B177D09FD156AF7F4
-:106A8000CB181F8F6C82FEF36BD83EBF13BECD7C3C
-:106A90007EED8B199E9CDFD355124926874F2ADC49
-:106AA000CF55A212C9EBDF37D97CF2BE5F8DA7E3C9
-:106AB0009554BA0C9FDE0FE7B83E7B2981F84ABF98
-:106AC00046096E027BAA43B5D999FBF63CB86B31F7
-:106AD000F837F43DA88347AE6D1C1EA6703DFAE55D
-:106AE00025CFDE057CBFCE45401F0938B432BB9DA3
-:106AF0007BB24F3EEDE3D27E991F47970F39C9FE17
-:106B0000C9E5E2A3838F9B8A4F9CEBA9930F2E6567
-:106B10007DB851BEFCF9FD18E490C293C7F3B58669
-:106B2000D5EACC6FE37294ED158A848D93C7F92C66
-:106B30006BF6833EE0B35DB5E5283FBDB31749A0D2
-:106B40004F441E54AAF152C193EE6EF7411C74D704
-:106B5000E207A56478CB8FB0F890F3BDE966FAB48C
-:106B60004D6997A07DAA7AA3DC9C1FB85CE5F379F8
-:106B700085A6C6C380AF3C43216B28BE76CC5E544D
-:106B800055027C47E510E22AD53504ED877C93ED6C
-:106B90000B0529BE9EA4EBDECEC5C488D37A3B4D3F
-:106BA000D5B61F23E4D0C98F3B175F5CBF10AB7F06
-:106BB0004EF95F716B6C7FB09814831DB523857D92
-:106BC00076A9F80D2D76B1F86875F920FABCF9525E
-:106BD000D7A9F9D7023F0E35DFCDA12FC853BB6629
-:106BE00095805F6B507D4192E1C7AE1F06C387134E
-:106BF000FF13009FE99F1D3E9DDFB3DD3CBE3D447A
-:106C00007CB4D516FD0FDC034F51DF391FD14EE4A4
-:106C1000A77D91F4C820FF2670E818F0260C7C565A
-:106C200093303EBB95C857DCB4FE4CD28865117FCB
-:106C3000AA53828C1E3CFF45EC732BD319DF8F9B2C
-:106C400048629DB07E4C9DCB377F15F39C178C36E8
-:106C50000A47127F8A903538EF118EF558C427867F
-:106C6000D5B7CF2EA7FD8E98EDC2F8C588CA23B63A
-:106C7000752CC0E547F4B7BB7268EBF3238EF5F9CA
-:106C8000112581F95D8F54AE6986E546C97A339442
-:106C9000ACFDB80E3B5EB77ED4E50B278167F7E20B
-:106CA0006398C7B5BBF2E2F1934706E19B7172723C
-:106CB0007BF68B1EB6AFB43BD37B334B2E5A6DCBDA
-:106CC0004320B256681D77F74724337C517D629785
-:106CD00097AD6E9E6FE0277EE0FF54F810CFCF1A7D
-:106CE0000F8F4E6B5C164ED2BEC4C3EC89759924CF
-:106CF0002A533E79F4652506790E84EBE18A9BF5EB
-:106D000018D80BEB404950FDFB6815C1EF1599FCF5
-:106D1000FBC33AE6558DE8205195AE67235E5ABC19
-:106D20002393D66B5B4C3DC7C2FEF76DC6A956D800
-:106D3000177EE20517C6732B7C71AF41E755C9D7A3
-:106D4000C1DD8B4F61DE71748F628C45FD2E11A900
-:106D500002BD785B1CF3845B61EBBDF1A04FA7ED36
-:106D600077E909ECE79B534E7975D82F2FE8F6C2E7
-:106D70003CB754B2F5F2C8E2A2AF96205AED79269C
-:106D800033E5A9DD261D6FCB62B65F9199E8F67AEF
-:106D9000E87C02B50AB99EC217D0D87CDBD6911820
-:106DA000AC53E53C9F442273D01FCE77E409E5390C
-:106DB000F24D82C6CCB760DF3F08FBFB3009B97EDD
-:106DC000C755A06F1B5C3C0DD54439F5F3F9F90D9F
-:106DD00013EBCF948FFB60DF77578B12C4F5CFD1C5
-:106DE000AF731E411239694AD80F8EB3EB21B64EEC
-:106DF00006276B06D558B429873B48E1CEA643B693
-:106E0000D8E11678758EE37794DF14FC3C828C050C
-:106E10003D24E2CC027E27DFE654C48E3E4FE7BB22
-:106E2000FB050DD7EBDD95CFDFD200EB7CA907F397
-:106E300023BEF4C1A1FA7FA1CF5FBF77AC189E3704
-:106E4000E41F98D4007880FC8889A42F8E97073D92
-:106E5000A3FDCAF59A18AF6C5F8B3B075F45FDB485
-:106E6000BCE5D4CB75108FCEAF2768FFE62B8C3FE7
-:106E7000FD2DAE5833853FE79A76E48711B571044E
-:106E80005AABED92A29678A7C8FBF6D747308FE2AF
-:106E9000FADA76CCF7F6F3B8AF7F523BDA4933E44F
-:106EA00057BD68AF71FA89FC77217F4EFA942CEEBA
-:106EB000AE817E46B42806803DA2BED105709554B1
-:106EC000D2358BD2ADA4A34B62FE1FCBA76729CFCF
-:106ED000F419AEC3BC2CB287E5178A3CF040BD9DC7
-:106EE0007EC1BEFCF9880BFCEFC20EC7F770CD1B4C
-:106EF0008C0FEDF42C52393D4B781E21C7C3088E00
-:106F0000872DF57C7F4EF3C62E66D7BEC0F7E75EB1
-:106F100084F98F1BF8FDA614FAF746D0BFE0B7BA84
-:106F2000BA5B011FE41A17FA714E38B6D633BD7733
-:106F30004075D9ECF8CB1DFF36AEFF6557E2EF3256
-:106F40007E7DDFFCFF3EE3DFFF771E7FD3DF19FF8F
-:106F5000BBFECEF33FF41F3CFFF9A592CD4FEB549F
-:106F6000BDD8DF4F3C223E66D7DFB22BB9BFFDBA9A
-:106F7000EAB2E5138BFCC4E9B5E6428897F80D76D2
-:106F8000DEC3D9DF0CF9B956D083BB785E36D5A302
-:106F900026E4A9664C1179324CFFD570FD57C3F534
-:106FA000DF91147AB5BC92E9776A5FC4F442583233
-:106FB000DAD19F099C56303FFB08A1CB0CE835DDA8
-:106FC00093343F3B8FC3EDD4A7795C9F963FE7781E
-:106FD000CFF5A8739D2FEC8B9F128C9FFE7795E7C2
-:106FE000033BF4AAC0C3AE4A662FE7CC4D6E0FB682
-:106FF00039E8A84D6AC4FC03273D5E57997F2DE808
-:10700000B1D06BBEA2E6A6A67782D3FB3A4EEFDFE5
-:10701000A83C1F8AE789A4A277A5878DF379FFD9B9
-:107020005033CC265C857490399D64D2D68DF15F47
-:10703000F24D62F52FB77E44ED1058FF35CD584321
-:10704000CB9FCF212E9174FF91D89FA37FEE6E1618
-:107050004795735487BFE5B483BD513837B3DB74AC
-:10706000C5A285604F74EE5E09EBD30B6998A7BC8F
-:107070003BB3E339F4E7DA272A0087B01B098FCF47
-:107080008249C1F2509CFB4E76BB7FF7475D71B0E1
-:10709000BF828512C6FD5AF50773929EC773D8FB4F
-:1070A0009AC76FF377C9F543B3DBD7727A537F3151
-:1070B000D76391EFB5FE9913591E547510F67724D6
-:1070C00073A60BE2E9A9FA8148EF39CB7E539D62A2
-:1070D0008E84FE24F01F4BFBFD47420A587C5ECC99
-:1070E0007FA8E707EAEF62FBDE1CAF39D7747D2A81
-:1070F0007EA4F0FB453D919FE7ACE7F4C7AF779BDB
-:1071000053607E43857F2F301CC4B3CBE49A64F177
-:107110008304D7AF5AF8B1676FA25527CD93587C37
-:107120009F9A6DD6FDB4B61CA52659BCEB975C4E54
-:107130007EA3EA5CAFC7499684F92404E625E4D12E
-:1071400039FED57CDCAB2F73FC17B85C5FCDE59ABC
-:107150001003F763528D5BC5F586787ED271137C80
-:10716000DE552A8F6B0C32EE1C3ECF399739DFF398
-:107170007CDC39439CEF423EDEC2CB1CF7433EEE43
-:10718000C2218E7B37C7EFDD978967C52BF17E86DD
-:1071900086E7663E5EF3658E1BE4E3360F71DCED39
-:1071A0001CBFDB2F13CF057CDCED0E3CA792DFCE9E
-:1071B000CB1CAFD4CBE4E700975FA75E13E36BF97A
-:1071C000AE30B4DF1DB2F77383878D2F9E24FE315E
-:1071D000FAAF23F8BEEE9495F72E32938C2BEA3B50
-:1071E000D7E354E3DCC2E335E229C609F0FDD02938
-:1071F000D7D07192E047D4BF5A657A3055FFCB386B
-:107200003CCB2E711EA27E15F43F3975FFF7713805
-:10721000EE73C03F58FFA2FE9C41E06FE570B45E84
-:1072200022FCA2FEC241FAFF0E87E33B9708BFA8EB
-:107230007FF720F87984C3F1C825C22FEA370FD22F
-:10724000FFE31C8EC72F117E517FFB20F8798AC384
-:10725000F1D425C22FEA1FE89377BBFC69E23E0612
-:107260008394429EF1289266E0FD0646E224F801EE
-:10727000DA6A76BF01E9729E87B29CA3A2227EF2EF
-:10728000BE9228D4DF7B178BFBEDBD9AA01FB137D0
-:1072900097E729F3B896C6EDC1BD57B338C8DE10DD
-:1072A000FD6EF1CF44BC68AFC1F29C7B0B581EB39E
-:1072B00056D68E26260E97C74D441DF269D8B92A98
-:1072C00061EF89F3556B799C6AAF49304EB5B78C45
-:1072D0009577579398ABD072EEAA348EF9A760D801
-:1072E000423CB6FFDC984956975BF23156C731DF16
-:1072F00040E179231421C49697E138AF25F60F6F4A
-:1073000032CC19A0E60A27B1FDBCC2B0DD7FA88748
-:10731000435CB4FEEFB99E0C4E4A7E9EE6B05761C8
-:10732000F4E3F99AF3F8FC05DECA393DB7CE79AF3C
-:107330007B3A9DE7B353DD983FFAEC698EC7A9729B
-:107340008CED9F1377B27338A9E26C5A47E3293862
-:107350009F7BD373C40032FAF798EB748CAB7D84B7
-:10736000FC8771353AEE4D7BDA15E0BF591DFA7492
-:107370008807CE7B4E5FAB41DE7507314C40EF474F
-:10738000DFC07EB25A881163A46A0EA29DEB88CF3B
-:10739000F17393223E07E16AAB7F398BCFBBBC25EB
-:1073A000B80EB6EECAAB3D36FB7516F733BF627A40
-:1073B000ECE725F9F9C7590E3FB3C36B8FD7691DA9
-:1073C000E11910FF96E79D31E1FCF3B8B0141C46BB
-:1073D0003FDF16DEAE407C72D69E46CC5F4FB5BF17
-:1073E00095F1F05CBFD57E17FBD9BFD973717B5D7A
-:1073F000C41944DCE134E4157BC04F0F71BA30BED0
-:1074000012FC91354FB2F1498797E9910E2F8BE32A
-:10741000FF179F7CBA7CF23BAF3DFED001DFA83C5A
-:107420009618C9F7E9EBBCEA7FC9EB674087802F64
-:10743000391D487D862D8F58E45539F1B681E34DCD
-:1074400094BD29CEBD14F8F83AEBF4EB5F8D54C12E
-:10745000BC449C8690FB1DFB9B538D8BC5256471A2
-:107460005F8CEB5519E653EAE3FA47210AF6EF98E9
-:1074700007CA7D1E9E53643038FA5BC7CFAB89794B
-:10748000B98BC326DCB742C7C0FD3EC8573F520682
-:10749000EB63D0366FD3C7D69B4DA58CDF36952ACC
-:1074A000B174965F65BFB7A8B8D39BCCAE104F62DE
-:1074B000BDB7A26820BC6A71246A8547E5F038FB35
-:1074C000999B129E3A5BFCEB52E1F18C27A41BF8CE
-:1074D000568911A697BF61EBCF551AC3F3FDA9FAE0
-:1074E00051743E2F075D528DEF2DB0E741A93969E8
-:1074F000367E57B42C479E9483BFFAE242431BCF9B
-:10750000796EB1859F4771B6F729EDC44882779FA0
-:10751000EECCC788211D9CE76ADC4107DC8EFEDBD0
-:10752000E05D923C1C71DFD006BEAE6D5462686FA8
-:1075300045299890EFB98EF3A5128CE1BD5EDFF678
-:107540004949E74F8CE4EBAD529C1C7E6F811DEFE7
-:107550006A4E969D0E4AF2731C1B85DC070F98F647
-:107560007BAC9C727EDCB8D87ADE77AF96F43BF9C0
-:10757000633AA5833EC73D0943A4AFF261369E6BD3
-:10758000EF2B53BD0AF15A2A2398CFEBAC7F46E08C
-:10759000EFD54E845FE8E9F43D22AFF693CD4392F8
-:1075A00008DF27B7B74F29875CCFC99CAF9F1E6400
-:1075B000FEA9E89B56ECCC2B1C1A7D7D20F7B0EE83
-:1075C0002926BF0CCB2EF7A9C6234136DF4B95FBEE
-:1075D0004F0A67764D84803E53431112A1EB7C7EA7
-:1075E000A81DF7C935A9270AFE1895291DE8BC3B37
-:1075F0005B67F76658EA4DA3EDDC85AEA81BF24049
-:10760000F87D30D110E982FA108FE92CEBAFA74951
-:10761000240CFCAEE52A61782FFACB986AEF8F9A9A
-:1076200009B2F51C96C817405787CEDF3D85FAA7EB
-:10763000B4BD4AEDD07DC9F4491AB343D39FF29942
-:10764000982710D662C092F9936298CF995F470C41
-:10765000F0E74A3ABA498476FA6D8063327CA7F340
-:10766000D620FFA31DF7ED733CECDC7A7E7DBBB426
-:10767000D0324E691AE3EF6973BDB84E7CA38A9D80
-:10768000DBEB0E2D6AAF82F12AF97D7A390A194EA9
-:10769000F1E17FC9C3FCCF490902F809F2BC863782
-:1076A0009B48F9E2B184BCDDE4C5E7F9A6203E833E
-:1076B0001FFDCF10E4B9AC9B5CA143BEF507FEBA39
-:1076C000D1B06EBCDB14C2EF5BBE65E8904F249F67
-:1076D0007A19EF8FE8E7F7A84C2A210F366102FDEF
-:1076E0002CF3EFF459F6F9FBE645E7BB908EB3595E
-:1076F00072DD0EE3417911F2A957562DF91F2AF7D1
-:107700001BDDEB48F8B132B8C72426DD5D6679EFA2
-:10771000A3761BACAF938348F77E7CC69A39BEAF85
-:10772000067F37FF398ED7B99517DD37696B8A77B2
-:10773000578FED2F6B29CEBBCD714FBB2E0DE2467F
-:1077400070D8938E377D6EE930C0D743EEE4F72FC3
-:10775000C8C1894631D48DE6BB500EF93D2BABC66E
-:10776000EBC3322DFDCFE17C299FFA29E237BD8C96
-:10777000E587D0BFD9F996FCFF82481DDE8F441AF9
-:10778000D93918B10F39FAD644336C498C5E6D3F44
-:107790001F33939FF32C5CE7C2FCD7C229A843494F
-:1077A0006133BBBF6ABF6C94037F3F4C5EC88403E8
-:1077B000EB0514BE9154540BA3F67EF62F99FD0CE5
-:1077C000C401C4B9D1B52DACBF51BA715A87F849BB
-:1077D000990BEDE5D1C4F042FFA3351781734563E2
-:1077E00088A59F4238476BEFD7096FA1DFE5827804
-:1077F0008780671439EA3573B07F12A3ED0BA89B1D
-:107800003722097CCE71C6887A579597C7499271FD
-:10781000494F33EC0B0D187F907E9BD2B81DEE279D
-:1078200001D0E77B2436FFE8B3B27110E87AF72184
-:107830008CD714ACEAC075BD238DD977EBA93DA0D8
-:10784000B9C14EA1CFB1A9F9500E52C465E0FA9169
-:1078500094FF1E4DABDA9606F1B0B469DB800FD30E
-:1078600014FD6B783FE76937817DCC34B31DE50F9C
-:107870002E64023B6373595106C85B5AA39AD45FC6
-:107880006B4973237C7BD22405F242296FE1BC94BF
-:107890007AFD3B3369B13BD7FC1E8CF397DC083E85
-:1078A000C5FBD0A25A1DF873FAD2328C7FF5764808
-:1078B00018FF7A438AA990AABD7C5EE304B82F67BB
-:1078C0004E66E41168B7548EAF77537856DCDA58B9
-:1078D00002F8990DF97EB9305C94F98305AF1B0A63
-:1078E0009C072B50E26ECADFDEE0A997D8335A0519
-:1078F000FCEE859330949E8162F32DF09BFCFC1C82
-:10790000924C7AA2901718984AC8EB16BA814F6722
-:107910002DC39EAEB59C0AFF833D17D3B6AF8F85AE
-:1079200055DE3025B40B62883F35684C0038E5D011
-:10793000E9BC62CB3AE7E1F3F34C5FC4EF4932B9FB
-:107940007F6310AB7FEBE1F3021DFEBAA5BD3B6484
-:107950002FCBC14F771EC2EE967EF1D77340C7B5CD
-:107960008FBB31EE39FD7177FC3A5A5EB14FC2756B
-:10797000C67582E9F5770F4828F771BF8A7AE09DCE
-:10798000A017CB0D9EEEAD5FA0E59EC765D28968BE
-:10799000A9C57BA5CE89F5F4182B2FE10ED28A7DDF
-:1079A0002717407F75C73C04D689153F5D7AE317DA
-:1079B000687929E563A8B2E260B33A9C96EF8A49F8
-:1079C0005D50BE308D209F45B3D418E4B55C08747B
-:1079D000E7DDA4E13A46F471B0BFDD9D378FF2E3F5
-:1079E000B2D86333A1DDB2C3124452E93C0E3E93D8
-:1079F0004FE15AF17D09D7C7E587D2D95D2B1C7FAE
-:107A0000E7E854AEA3DF57D179823E5C4ADA6702D9
-:107A1000BD561CDCAE5AD7B9B79B4A31F5439457D3
-:107A20007C9F8E43DBADFC9164C0145742BE03AC17
-:107A3000973FF5D5EED7607ECD6A891FE6B54185C3
-:107A40007A4B630B9FF0E900DF3E7526FDBE6CCFDD
-:107A50003E754919E08DDC0EEBEAF2435712DD4228
-:107A6000D7731D32FA0BAB32BD9D78BFA966BF0F2D
-:107A7000A51F2E62836B19D71BD4EF53ADE7DD9E94
-:107A800048CF443E5D7E48B68D23E81F3D43D879FC
-:107A9000B49FFBF13C9AA09F58AF04FD56890BFFA1
-:107AA000949E8A64F06C057AC0B91BEADFC0F3C10A
-:107AB000A6103E1F6AD2914E3B018FE3585E0ABC6E
-:107AC000A7725B05F756054CB8180CCEA5985590D3
-:107AD00087991566E5BC5B23927E113B5D3C77BAC6
-:107AE000230BC1C8999AFEDD190AF5C776AA91BB86
-:107AF00021641D543A6754D335AF3E3D5C916ED935
-:107B0000F75B2FB1F37D9F4BD771FEEBF355C4F7B5
-:107B1000CEDB2AF6F3F813AE933B6F5BF208C4C7D3
-:107B200069FB2FA6837FC1F7FF52B5CF5B50696B0E
-:107B30009FB7A04EB49F89EDBD176FBF73C135F6D7
-:107B4000F1172C13ED6F44F8B58BC39F77FB54FBF3
-:107B5000F8B7D763FB060FA36F4FA617F3AD5B7C97
-:107B6000461CF4315EA83609F2C94B3AA19E5877FB
-:107B7000A8E637217F5B3B9C59BE8958F968DA0239
-:107B80008003F2B2AC7C9451996693AB4C33CB56E4
-:107B9000CEAE196EAB9F1B2EB27D1F567B85832FF9
-:107BA000353CBF8865000A0C730AA73A5C457D54D2
-:107BB000359CD9C1F79EF061F9DE6BD8FCEE1DAEA5
-:107BC000A11C03CCE097DFAB463E67BDBF95C03D2F
-:107BD0004854A7DEA945EE8379F4BFD75DF03E8D0A
-:107BE000E73BA57908EABB0D8515FBA3167CB68E8D
-:107BF000A4FC40CB2DE92AC33BA7C386914B425638
-:107C00007B7DFD48B516FC0D787F8706E385D7C3DD
-:107C1000780D6A4F09D81DCE713C4595B671BCA34D
-:107C2000EA709CEDE92C9E2AC6F18CAA738CE3AD18
-:107C3000EDE4EFF9383B80CF528DB3A1E81AFB7C1D
-:107C4000462DC371F63AC6D9306A99639C34361F03
-:107C5000FA9E8F13BBD8389E3153EDF3195D8FE335
-:107C6000FCC0399FD1F58E71341C07DEC338D4F0C7
-:107C7000D5E1BE2CD5D3B304E9FF0B1FDA39AA270F
-:107C8000F228DA39AFF8D0CEA1B54CA8474A997F8F
-:107C90007B4F7A16D2E783344A7FCD4AE728CF3B21
-:107CA00088A25F7C270791C4284454BFADE43CB848
-:107CB000F8F09C51CDF03C363DB410FCD187FC1857
-:107CC000C77BF7D874F58E24FAE8CE76F7B98485A9
-:107CD0009FFBF42A8FC786D2D93EA4289FE3F19F49
-:107CE000D7214E449F6FB809FA436779BCA81FDEBD
-:107CF000666C778EEFEB9DDBC3D6A90FB69F71A3A1
-:107D00001D11252F9451B8E7F369DCD96EBF2FB34D
-:107D100081D3A3E7A71E760E889823F03EBC8E6C15
-:107D20005BBCF07727BEFC0CCBBB2323E0DEDFAFD0
-:107D3000B73EF634547B515A3872159D6FEDD1ED34
-:107D4000EE11B4FCAE3BB1C0D02CFDD4BAF1DCBD19
-:107D5000F0436E8EB86DF6F32D75F6F26D0E7BFA6C
-:107D6000D5F422B13FCBC6D5636EA0D77CD863A52E
-:107D700024BC0D9E987C17447A2D08B2B6029E86CC
-:107D8000FBDD248EEB5D2217E39CD15C8CD344C4D5
-:107D9000BAE5806F81DB6B86293D17DC27231E9DAA
-:107DA000F0264EA49B2EEAE7243AFEB71BCEF10C38
-:107DB00006FFEDABEDDF49D46DBB8740F0C1D76A5C
-:107DC000ABF69FB5F0C7CD9159FBCFDAF034C7566B
-:107DD000BEADF1665BFDDB572FB47D5F18BDCBF602
-:107DE000FD8ED6BB6DE53BDBEFB3D55FDAD16CFB27
-:107DF0007E576CA3EDFBF243DB6DE5155DBB6CF5C7
-:107E00001B8EEDB37D779D18FF15F4037F23E37977
-:107E1000E7F7B5735BC17E7B3FA8E07ECE9B7CFF1E
-:107E2000EE6D7EDFCF4AE0BD29203F13BDE0373441
-:107E3000A45179A6B6C4042D777DEB54D02304AFAA
-:107E4000D428D746AC8F5267770A3F9F2877A8245B
-:107E50009E0DDB2BFD71D81EB9FFBB92A0DF27A6BC
-:107E6000FE2E772849BF2B092569BF17A49E12B0A3
-:107E70001FA32F7B929E03EF974B32825CE43EC997
-:107E8000F32E5267F5DFE66B2C3EF44CFAB4F95A48
-:107E90002EDC8FC1E4BDFE48FE34F01BEAD57849E4
-:107EA000B27D9BBEF1BA24BC3770BEC6E4E5AED845
-:107EB000085B3C6DF9A13136B97F292D729346EBF1
-:107EC0009D3F29A39E25F1A7467DF52A18DF9C0F2B
-:107ED000EFC9B15C5C1F5F6C32F79FA57EC04B4D54
-:107EE00035F8FCD7A6F0FEB3D4257CB5A916CBBFD8
-:107EF0006F8AE033D15487CFD79B1AF1FBD9A6D52F
-:107F0000583ED714C5E79B4DADF87CBBA91DBF9F5C
-:107F10006FEAC0F2BB4D317C0A3910F62E09737B33
-:107F2000526C981056EEE57390F3441CD3C0FBA33B
-:107F30007AB50F4AC08EEE7DC98379B7A9F0E4E423
-:107F4000BBD4F43371BD5F12B3C799C5D397C6E8EC
-:107F5000E373911AC891D83856C5385ADA2FAE440F
-:107F60007B9CBE57D865B231634E927B3BF142E4B5
-:107F70006183D349D43FF7DD7FAF585406F42942DB
-:107F80003CA53D253732BAED37BE7AD5E0F8439BA4
-:107F90002F7F201EA55FFC6E14C4A7DEC915F8EC68
-:107FA0001E05C12D450BEF023EEC3DEAC179F51EE1
-:107FB0004F67F92810541B42FEEBF243BE98553F21
-:107FC000ACE8CA8CD9F5457ECCAA2F7A4FEF0F804A
-:107FD000DCAF0AC9B1B313813F4CCE1F8CEF44FF15
-:107FE0002BBA0A639AAD1F7BB9B75DAAC17B1F8903
-:107FF0009E312F89FF219EAB422A8EF3F6A1319844
-:108000007F40FDC4D85916EF8CB17143312B5FD638
-:10801000AF4E8F9DCDEE872F55BF9F367C841C259C
-:108020007FF0A63E8F3BD89328FFA6E2FD6EC7DD0A
-:108030001FC0BAE3A1FF7F8CF9420A9645BF0D5DD0
-:1080400072D403E779C961DB78B49D2E7C7458AF94
-:1080500052D3DD9E0FFE7BE0255CB7D9F9F2089C78
-:108060002FA7FD5D50B456E973FDE7CB1B385FAE1B
-:10807000F026D4087DF5CED13117CD0779BBE97450
-:1080800050190B7904ED7871445DD7F86AD08FEF01
-:108090001C5D9B07F1B4E572EFBDC9CECD7EA8B1E2
-:1080A000381B89B97B1296F988F80C21B45F6F3FB1
-:1080B000FCC0E9E72C65A7BE164F979FC5DD571E8C
-:1080C0003E33F30B14FE95C7DE53018E635AC4E5AD
-:1080D000B7CC5FE2E7EB971D7A4D85F9BDE98E9647
-:1080E000DC7F113D35104E2D64DB0F8D926E90E3D9
-:1080F00045EC3718809FBEF60A15CDB77EED26F009
-:10810000BB0E62BF429C7B584CC201C0D7A2A3CB1E
-:10811000313EFCD61337707BAEBD02F8E31DE2AAF8
-:1081200081F9BD439E0F4CB4E0AFD8CFFC18D2CA42
-:10813000EC18712E90DAB336BB666987BDBC84CC6F
-:10814000CD03BDB1E42137895114DD452CF72FD182
-:1081500079E7F899BDBB9434AE077B4EF130FF60F0
-:1081600051902823A83E5DF193872BC0EEBFD2CF5C
-:10817000F61D451CE3AE2C66EF2DCB89A9B09FF010
-:1081800087A313E77F01B8CF135B0FEB32C948BE5B
-:10819000FF7747AB1DBEC1E077C22BCEBD0F88A7CE
-:1081A0007038E44352D2FCB4297ECE775C8FACF1B8
-:1081B000DBEDFC0D8EF26C3F8FB3CA44063ABF1361
-:1081C000F4465D19F81DCFD9468F788CB53ADCA7F7
-:1081D000150E037F51BB6002B1D4FBA316C1F7E7B4
-:1081E000A5E796E03973253E01F3F1BC04F314557D
-:1081F000CE0F725A6002F91CC4491BD1A95FEB0B68
-:10820000744279BD9F9D836A0039A5FD6D09CC3C00
-:108210000D717D2F698F9B85B0FF6D8F7FFB747B08
-:10822000391DE409F409BC007A1804E345E9A5F610
-:108230007A7EC35E5ED687A7B86C3DF711F06A718F
-:10824000F89D2152A99CB7DACD2BBD0C7EB8111C2C
-:10825000EADFC3EDF995448F62DE6288F1C13DB378
-:1082600058DEC43D7EDD88D2EF9262E2F9880DD0FF
-:10827000D4B28E357C28919845AF37283D2AF065D9
-:10828000C3870ABEDFAB45BE057855898976AE97B0
-:10829000220DF6AF15ADC666F792027E2FA0237FA2
-:1082A000A1CD1FB4F97B422FB8B95EA4FA62833F17
-:1082B00017F460CF4CB6AF9E50D9FE0EABA7F6D7E1
-:1082C0006B033852D5F3F5D7DB9EACDE8A9FFCF00A
-:1082D000892895F765FFF2ED006CA6BDA5B4E741CE
-:1082E000FE43FDC17501E0E337956800E6FD562CBD
-:1082F00079DEFB2FB9BE837C27382FBF92D3E9EDFF
-:108300007FDE7C23E0FD83836E3C6FDF70C813F754
-:108310005022AE3C7A17E3A7439ED7587903FE6EEE
-:1083200054C331BBBC2D7BF4DB793A6EEE4547F08C
-:10833000FBD8D17E5E79E08F33C11E69203DA8272E
-:108340009CED60FC0FB370FD5A08E7FE9DDF45BE53
-:108350005503E7FB86A39B31AFAAE1E82CCCA36AC7
-:1083600070C8791DF7438EF9EDBFB321F04162CC9F
-:108370002E5EFBFDEF4C788DC273FEC0AF03922DD5
-:108380007EC4F4446FD71DDF7B524FADDFDFE57E47
-:108390007D7FBB18B6D38F313B9E1C67CF7A773C6D
-:1083A000007E53FD3EB7413508A9FFE1FE47BE0BF5
-:1083B000FCFDB207E30DCB7FF8F48BD7D0F2F2C708
-:1083C000DC39B3D93434C80316748133EE90AF2B43
-:1083D000E8B0ECC74FABFA55ECFD0359FDF458FE7D
-:1083E000D849955C35107FD3BB4EAAECFCB9832EDF
-:1083F0005DAFCD04BB7BEDF7FFAC827CBD75422247
-:10840000C30A07B6AFDBF734DA758027A423A75376
-:108410001FDD06D02B7EE39393B05E10D6B1C1E88A
-:10842000F55DE0995CE4EB1F3D09FB05FFEA3100D7
-:108430000F753FFA4600E6F386D2C8F8FBE175797E
-:10844000B08F5EE78EE605F1C9DED7EDFD26F2DDE1
-:10845000D233DFCC637950663EFB5DA3683EC60134
-:10846000F7DC84F35C4222C87F750FCB9887FEBE91
-:10847000426A1E4B221FD705981E7BA3D38397DF2A
-:10848000BD010A17FCC5E7E5183B6FCBF212BF2907
-:10849000F63DE0DE465A7EDFCBE8951B70897BAD6A
-:1084A000BC36BE3DB0A11BE8F4F6487318C42B29B6
-:1084B0001EA21C6F12E821F9CC8C618C4E44572A05
-:1084C000783BAA27A7C37BA8DFED367D136CEDF8B8
-:1084D000BAC6C6BF878F4FE14E03FBEC8D3C6AEFF7
-:1084E0002499DFF280907F6A7F58F8CC22E74CEE27
-:1084F0000F6C64722EE43E36A706BEFFDB0B4C8E7B
-:10850000A01DACF314AEF830FC7E729E847AC14399
-:10851000E2C9E4FB809BCBB7FD3BF5CAD1BE157C1D
-:1085200042E15760DDEAE717B6CF4BE980F6DB9210
-:1085300087687BAB7D0EE3623DB5FFBD65BD5FCA5D
-:10854000F5C13501C7EFEEECC91DD27D79F5EED846
-:1085500023DF05F9A5F20AEB4FFD0FDD9827F2A7FF
-:10856000C34FBDF875CAE77FEA12726BD7A74EB941
-:10857000AD3B32992493DB3F6906492AB7F47D521B
-:10858000B9D512C8CFFF51FA54E06F51C09EE7240D
-:10859000F4632A3C3AF5E3DFFC3AE2D3A91FE9DFB2
-:1085A0000BA462201F0AFE137CB7EC072BF0774167
-:1085B000FAF853F05F1F7F0AFE73CED78E3FE7F7BE
-:1085C0002BC15011F162FA74AF21513FC4537F2E79
-:1085D000633CF50285693DA5F385C385788E789D5A
-:1085E0008FF9E717823D81AC32BC0707CB3DB9EA72
-:1085F0007AD017E27D8F8FC5BF2F847B02D63C9047
-:10860000D78ECB01D8EF4AC4484D327F846A648448
-:108610002341527D67F1E20B60FFC17869A362409C
-:10862000B719B2366A35F8F9EDECBCFCE2E6AF05F5
-:10863000601FFEC2F131DB407FDDF9AC4CF8EF2862
-:108640002A906F7207A7FF9B24BA732A9DE71DC764
-:10865000995FB1B82D39BF2CE3F59768F7A8A097BB
-:10866000A85FF0BA351EBE8CFF9E64DD1EC7FBE31B
-:1086700037205F2D73F05584FB8D3F147C7535B921
-:108680009AFB6D2E6B3EDB0CB96C1BD825174EB3D5
-:108690003864EF7119E9D17B5862F94F100F9E02CF
-:1086A000FCD0A35AF3D8CE03FF25B9DFA0EFFBE33C
-:1086B000BFABB89F56A97FE29509BBE9F3FC132F26
-:1086C00097FC0CCA3FF9EDA857C8C0FAD34FFC0578
-:1086D000F7B32F9CF0201C174EFC72D4FD507ED2B5
-:1086E00083F7D55C58E361F99F27FCB1B1F07D2495
-:1086F000CB175AFBF33F4F48E0BAD482747B29C0B2
-:10870000FCB1DEE3FFFE7BC81FEE3DEED1611E0D26
-:1087100027D2717FABE1491FC6692EFCFCCF15D66D
-:108720007CA6CB9DCF4A7E1FE2053FA9853CE50B89
-:10873000996CDFA0E16753F6C339A215474FAAB081
-:108740001F33FD177F9D007AE7C211664FBCEB4EC9
-:10875000EC857DD63F046EDFE086F82EACD7C309EA
-:1087600069CA885D0FF7E10CC40BC3C3058A07987B
-:1087700017C54B1DE8CB54F8F83FFFB0F8786F01F0
-:108780008C5F7FFCF32837FD78914CF6DE1F83A3C6
-:108790004D74FEECFD893F4F00FBE84F5DCDB8CE38
-:1087A0000F36EFFC8CFFD7E62DC58732EFCA7FD896
-:1087B0007933FE3F11D059DE9F430E06F2F94FEE9A
-:1087C000C5F28FFC06C23B44F9AFFD879DFF27A48D
-:1087D000FB114AF7C0E074FF6F196C5FF81F6FDE82
-:1087E00083D1FD594E777F10F2102EFCFCAF185F3D
-:1087F00017F31F6CDE3BFF93CE5BD8439B5C467B3D
-:108800005121E461C7BB750AE7BAD2B9ED1096925F
-:1088100079DEB513AE6732987F214B2C6E4346B29A
-:10882000F811E1FE46DFEF416AEC7C95A2AD67F7F7
-:10883000912906DEAFB7E98A4506E67690F29722DF
-:10884000502E988ABF73EBF4BB942BBE741AECFEC7
-:1088500096660A1F1DA7C5AF04A9E544DCA5AEB8FE
-:1088600067023E5F83E7061EFF7207559BDFA13953
-:10887000FC059F6EFFEEE1FD7BC9A920E42F790D79
-:1088800005F3537DA43D6ACD37F0104B3BFABD1381
-:108890007E10D0624F5E2AFEFE9CC1FC4F592AEF2B
-:1088A00086BC5832DEC5EE3727EC5CF1A60223B653
-:1088B00089E55D78EDF85CDF0D785408F50FD9BCDB
-:1088C000D0AF24DC9F5478174AA9CBF4D9EB717F41
-:1088D0006950FA307A8CAAE7F45965A387C0FB4542
-:1088E000E862A387C0EFA5D2C5490F27FE7F95C1D7
-:1088F000E274824EB67C905CE697C4A981FCCBC33F
-:10890000FB312EF2CE3FBF7623F0E9F29FC9C44B74
-:10891000DBBF7BD84FE220BF4A4C053F6BD95119D2
-:10892000E3C2FF174BEE49A70080000000000000E3
-:108930001F8B080000000000000BED7D7B7C54D5F0
-:10894000B5F03E33672633999964F29ACCE4C52496
-:10895000811834E0248480823A218020F43AA008EF
-:108960007AA38E10209827485BDAEA8F09411A1EF5
-:10897000B641E5A1453A2028ADD8061AB9A0A8838A
-:108980003CC4566FA3E5DEA2450D8A82C823A51715
-:108990003FDACF5BBEB5D6DE3B73CE6402DAAFBF43
-:1089A000FBFDF3E59F937D1E7BAFBDDE6BEDB5F761
-:1089B0005CBE0C7FB73076595C196B652C83B1BAFD
-:1089C0005F3B184B67ECC19D09E1C9F970DDF5E922
-:1089D000503684B1734B7A0E65C3FDD02F15DF5628
-:1089E0007C3DD43DF40EB8FFA0CAEE0F9444FB9139
-:1089F000D754A781B1E18C9DD9639B11B633A66C86
-:108A0000DB771FF5DB31DD94A044DFB33A4D342E24
-:108A1000BCE7C7E7A15F28E1414ADFFE186BE1FD33
-:108A2000FD42E1F0ED3685AD08DFB64DE620C0D160
-:108A3000B4EDCF663FC051F5EB1793BA61BCA6DD2C
-:108A400046162966F47799E173632461285D8FE304
-:108A50009531BF5DA960AC11FFF5C2B5B361324B72
-:108A6000826BC7CA3F1B93F07BD327DD96E8F7756F
-:108A7000BF7E7557085053F79BE793BC703DDDB53B
-:108A8000358995507F0F98931953EDAAEE7DECF739
-:108A9000526ADF7E605CC65C709FDF624D1DCBF961
-:108AA000789DDF39C9103E06FD48B8617EA7F11FE9
-:108AB0000F63239D8EF4CFAF83FF47B011978D7066
-:108AC000DD96C6D80D7DF114C55788D3F3C58B1B31
-:108AD00043809F333BBFDC88F0D7FFFD2F1B7F0413
-:108AE000F863AF599D5B61DE4DBFFC8F24A4AFFCE2
-:108AF0006EAA53A1EFCEE5B29007DE3BF77E423877
-:108B000004B7CEBD7A32CF0BF33DB7E3AF2E2FBC07
-:108B1000BFF0D5719938FF852F5565327BFF709C6A
-:108B20005BCC5838410B5798E8E8DD0D9D664273E1
-:108B3000AFB8C6D0637FE7FE3C84F3ECD1045F029C
-:108B4000E209EE2D2A43FA009D86F2F6C380DFC6C5
-:108B5000ED3FFEB371683C3C87B20D6EA4EBA7E31A
-:108B6000114EC622D9CC8DF8ED59E6B4F77DBF97EA
-:108B70005E47809ED77F03BA6D5FCEC7ED00BA25F2
-:108B8000F5A5DB59FC07E8D38474B345E976910574
-:108B90007FEE298476671AD1351EBE22DF005FB5CD
-:108BA0000AEFFF26A7FF874E949F9DB65E7A4D463B
-:108BB0007ABD78318F01BD4F997AEE63E58CF5BCB3
-:108BC0009AE0DC0CF71F7CF58F2427E75E7AD78CC0
-:108BD00074843FBB02F33AC77AFFBA709E8D8A98BD
-:108BE000E716472421298AF7C6F09409DE24BA7FC4
-:108BF0009CEE8739FF22FEB2913EE17D772A71E833
-:108C0000D1E12CA079B07006CDBB61CB9FCCC83729
-:108C1000924E481F6524D2EBF878BC2FE924E71D5B
-:108C2000DB9F13F1304243B72D5C0EFBD2B5C7CCAE
-:108C30000AE3D10BE0C5EF105E689FDB94A02AC960
-:108C4000FC7E0ECCE39C89CDE84038C2CA1FE3D13C
-:108C500097B125349F1762E552CCEF6A727935B827
-:108C6000FF51BC3CE37452FF123F67BE8EAF9F0FB3
-:108C7000A19C03FCBBEDC183C83F8C59C227A09FB8
-:108C8000FB99C2920BA37893F09E5119E9DD33BF93
-:108C900034864330FF651DFB49CFC6CA37CCCBDFD6
-:108CA0001167BC3F8AF11A77EF1B8A7AE8CC1B7BED
-:108CB00088FF1AB71F3787A09F43DB7E63EE2E899C
-:108CC000F23BEAEFB0467F9FF9D5BEA1A46FB1FF9A
-:108CD00038FAE684E8BF69AFBEFFA6ED7FD6F55F40
-:108CE00017EA303BED571FE7B4EA9F8EF33DDD6591
-:108CF00062A8FF4E77182784E38CFB96B05F124F73
-:108D0000CBDE35931D2B7F2F319C00785AF8EE84F3
-:108D10003F25A7E3D5EC05D4B2CE16CE579D8FF8EC
-:108D2000B3912E9DEFDE63447BB20BF1784DB4DF3F
-:108D30008A23CD550E90DB8A63817264AB587D30F7
-:108D4000E2A84107378C9389FA7929F4E3857E9864
-:108D5000EA7307A05F63D2F809088FD169705AE3FC
-:108D6000DA55DE9FC91E604180CB0476DBABE1277C
-:108D7000F7D4A4A12C19A7E731A05E5800EC85FA1E
-:108D8000D96D66C52AC0C70C89BEADD0EF82C1FEC1
-:108D9000D283D05E30DBED0BC173CF1DFCBBB34E75
-:108DA0007BC8703DB6F3C22847B64B46E605D5777B
-:108DB00046797B0E039560137C95DD61233B6353FD
-:108DC000BDEBAAA16DAB557D8051F6993D989B9264
-:108DD00081DF99E93B4F8AA27E8EF34E6249286F6C
-:108DE000B27FF99EEC97A991A1387F66612A03BBF7
-:108DF00092C338DC46319F42D6A5207FB74E49DA70
-:108E00008CED0D8E5AB2FF79AC679F1FE8F66CD2DD
-:108E1000F8C3A8C7E05F03BE97DBACB7EF0316E962
-:108E2000DBF92135467EBD8600F05F619BFE7E7AD0
-:108E300055E5FC013EC6EE4BE99CA082FE4E9F5ECE
-:108E4000B9231B703A69C57BBCFD7C65A907DAFFB5
-:108E5000B1BA61A20A7A24FDF795A579D0BE90FA3D
-:108E60008389F4BC0E907423A8FED54327864AA2BA
-:108E7000729B0160261B499E6F463C9C0D9C598647
-:108E80004F1BA67D658647F817403CE48EE478C802
-:108E9000B11FDBC1E0FD0186EE16E4CB9FBFFABF38
-:108EA00052F03D2F73D27C9D6CA9F3730B4E9E8DB7
-:108EB000BC3CEC4AFA4C659F4B3E3446E520D91544
-:108EC000BC3D05F86AD9CCE275E351D7D6FB88BF23
-:108ED000606427D943F9BE339DE85323E883705A71
-:108EE00080CF66F357582D6B177A68AC13C7514281
-:108EF000F5C6CBD77D7B78664ABE713007DE57EB6F
-:108F0000BD045757867F36E2EBAF1941BACAFBEE74
-:108F10009933BC41C0EFCD2981B9380FCF9C4B7933
-:108F200008FFE41446FD55CDB5FBD1AE5ED80BEA83
-:108F30002F8E5CC9EBE6C5CCA70EEAFFF9D4D4E0CE
-:108F400077B1FF82D7BD3B0F437FD7D7987D5618A7
-:108F5000E2FA45E53E358DF109A1DF21E8E6465A02
-:108F6000A2DC7D8F8551EECE27287E3FB4CF3FE433
-:108F700024BD9C5333F930DAB3F3B6FC8E08DEFF20
-:108F80009197E4113C0005E521776F72C49A44FC87
-:108F9000FC550C3F7FA5E75FFDB8E72F7B77775344
-:108FA0007F4ED11F3844F03C57D0E9BC91FBE5E738
-:108FB000177B090E701FF7A1BDFDA6E33D9922FCAA
-:108FC00024419F47ACFE35480FC0FF3A2DFE7FD6A7
-:108FD0003F1D37E27B4047BAC6D2718EA5390FF5E7
-:108FE000C283818EF1A0B1D9C939DFAB40E69E9230
-:108FF00012DC82EFD7CFE83A6422689A8B506EFB7E
-:10900000D259217DEEDAFB408B09DA4D48276F5F9C
-:109010007A5EBFA894E8A6A16F07F67FFDDE3F1B2E
-:10902000107E49D7750AB703B1DFBF92A28871EBF2
-:109030005B4C80CF0BBBCDE4FFC6BE7730C54BEF9A
-:10904000C9F6504B854F0539CD34B060BC7E0FF664
-:10905000E9D7E24B88037F6F7F4EDE1FE0FF4D2D87
-:10906000FE7FD73FFEFF5DE0FFDFBF25FE8F209D27
-:10907000FBC3BFF4BBEB847EA863ABC8DFFCCC3F73
-:10908000D53510C61F6FB4933CCCDB6A243984F706
-:10909000277B5C517D32EF86E67D38DF79CF28C4AF
-:1090A000B73541AEE7BF9C33F910EAF7D9ED7AFF47
-:1090B00069CE8C9019E19CBB5E7F7F5E38261E6472
-:1090C0001ABD0E7C7126CABF03B8DE7193BD340A87
-:1090D000F9A89A5B928CFED26B26EFEFC91F7FCB6B
-:1090E000C836C7C17F5E6A3ED963D9CE6D06246992
-:1090F000EC3CABB11A505FCA7EC7CE2DC944BF66E7
-:1091000081C37BC5386CC022BD5DCF0F2532AFA6B1
-:10911000DFC2B6545D7B507B96EEFD6BD617E89EA2
-:109120000F0E5FAB7B7EDDB6325D7B48C78DBAF735
-:10913000AFDF3D46D72E8DDCA67B7FD8E1A9BAF6FE
-:10914000F0AE7B74EF8F383A53F7FC86EE0775CF9D
-:10915000479D5AA06BDFD4F343BD1F6360A427591A
-:10916000A2427AF3C0E253152790E1CA95B188CFA5
-:10917000AA91FCDD03F3CD0667125E8B0C4EE08FE7
-:1091800037664F263FE0C07C97DF4BD70A3FC63F8C
-:10919000CC38BA3C18C7CF1DE7FCA2E28466DC2AB3
-:1091A0008B49A7E7C639F5ED61A9227E18C0F9669B
-:1091B00064AA5EBE8CCD9323666866CD1B9889E356
-:1091C000819C8D4AE57246D7ABCA59527305B641A8
-:1091D000CE2A53E3C81913F6B652F0135CFDE632FB
-:1091E000642C07D9653FDEF4D2FD900AF1CA188BD2
-:1091F0002FE720CECBE04B47261C3B237080F72780
-:10920000EC332B367C1BFB2CE5DC6DF086C8AEA561
-:1092100032CA2F3D35BB289969F07B4FAA41E883BC
-:10922000761E473AB70D53251E0BB4F7270C578B04
-:10923000A3F795B9933351EEDCFDE845B3BB70F06D
-:1092400016D0C7664F3E5DE5FD65330C13C271E86D
-:10925000DB90CAE30CE9770D8EFA5D0D88DFB3EE83
-:10926000F7D60E027C3556F790DFE536B4CF3F8453
-:10927000F3FAAD91E7CDC0B342BD305BF8D1B3276F
-:109280003E3EFF10E8A7D9EF0C22FD24C7D9B03825
-:109290003258EB37E4F413576D13F06C5CEC1F5C41
-:1092A0003388E022FD20FDF4BC50C3788C7706B0F3
-:1092B000668A1BD71A586DBC7E968B7E3291E40865
-:1092C000AFD34E727276CEB12415E691E8082E47E0
-:1092D0007E9B797D5705F7C7FCBEA9C03F79917B7E
-:1092E000D7E2FB796E958595BEE3675607DBF261A1
-:1092F0007E4B530D3E3BB57B147C3FE161C6D2E013
-:10930000FDA57F37123C4BDFB88161BC96606F666C
-:10931000E8D7CA79ED4F7D9AF063ECB4911D64E80B
-:109320009202FEBE2B687FD15DD3857EC7C5274DD7
-:1093300034DE4598A313FABFD8690CA3F37E283511
-:10934000316280B6B1CD41F63B0F7D50787F4EA79C
-:1093500023ECCD8FE2455D3F9A45C0DE25E4F0F970
-:109360002F4DB587EDF934EFD5386F09A79C776E8F
-:109370003F71682495DB59E62FD6D1D903315917AF
-:109380008EAD82F30FFD189F34519C383BC54E7053
-:1093900086178706D798FACE6F997BEAED77033C5C
-:1093A000AD478CCC08FD78BBDB091F73001F616FD4
-:1093B0005F7C9FF5E67F653012DC11E447E3FAF14C
-:1093C000342F867E3D7CD7F073853D9D8F7C199C24
-:1093D0004074CE32B0ADF97DE7F1662ACFDF1E4E84
-:1093E00075D2D5EC2EE272E21E38780BF4F736EA2D
-:1093F000290B8BE707FC3E95FBD3748DD54F600797
-:109400004308C785F50AD1F3A412369B006575772A
-:1094100036933F20F593D16F24FF43EA290917E8DB
-:10942000B10F5235F6D198FCF050ECB77F7F6DC785
-:109430003E33FA6B4E46FE9AD4A3FDF96BE8A721A2
-:10944000FF493FED54CC3C617E5F8AF97D196F7E08
-:109450007DF4EF3DCDD2CFF973EA15FCCC0C737CD3
-:10946000FD744D1AA74393D3CC283F85F132FA0FF0
-:10947000F30CE1CD988752C3D6291AFC64A5493F65
-:109480008FFB1BFDE9BDABC525052B4B48FF5EE8F7
-:10949000F226A7C235FD53A5395E3FC6452F0C43C2
-:1094A0003ACDB356DAD2004E679A1E5F4F2DEF6366
-:1094B000BFD2D238FEE8DA077F76C09F41E727EEB9
-:1094C0002AF212FE3C6957F013CFDEF15105DAA5FE
-:1094D00073024F8DBD712FD7D35960AC30AFD5C05B
-:1094E000FCCF9E28E6EDCB0AAD7A50BE6EA33D3090
-:1094F00008FB6FDA3DF159ADFDFE3A95E7D3983D93
-:1095000095F2ADB23F97D0FB1067DFFC9997F4FF5F
-:109510005748DF68BCDD5D81F156EB4BD724A37F54
-:109520003676D7DD4EBC5E481F48783DBB2BC18FD9
-:10953000709E4D057D6CC7F688439887F872F1E1FF
-:10954000542D5DCEFEEADD0A13F47376E7BB152ACF
-:10955000E63344BEA6D71E5DFE434500BE0F8D61B7
-:10956000C5CD760D9F58B8BD78D2CAF31D192EF31C
-:1095700032763DC4231929F4FD1A97E12778DF6874
-:10958000F943DE0994B398FCCE93266FAB1DF80C1B
-:1095900062391FAE132C18ECF7CCC6FCCE1437E59D
-:1095A000655A15AE4743B3791C9A5EC08AF3A13F52
-:1095B00093C168C4EF7A3CCCB7195E4938D01E41DC
-:1095C000B597D8D5E147F0CB1353099FA3CE3815F3
-:1095D0008C27643E48ADE2FDF54C3387376BF24093
-:1095E000EE192AD9459BDAC1504F3F90914AF0CBF2
-:1095F0007C50D5D419814A84EB5103C533A078152A
-:10960000D487D9621EF99E9DCBA56FA3BA902D1960
-:10961000267FD84AE0FF8180E724AFC18FF9D7A425
-:109620009CC85113F877D94B19FB44E347DACC4275
-:10963000DEDE3192BC39BEBEC53203FC235B22CFD5
-:10964000AB260596CDC7BC38DEFFD732A40BFF9EF4
-:10965000E863C434150B2503C88E91FA7E25FD3AC4
-:10966000175B7C0381A1772E76D2F5B9C56E82EBAC
-:10967000F1C55EBAFE747131DDEF4F4EAF767D6C91
-:10968000318CABE1A7F4118015986FBA91913C3FF2
-:1096900036BC2279661C7F405E9F5E7CD835769012
-:1096A0004020D023ABDEB969453ED119850866F765
-:1096B000CE72FF68C61E35F9E73360ADD5695F8F9E
-:1096C000C5BCD54AC54079AAC7D3DE5C1ECAC1ABAA
-:1096D00097E86EDBFF3EC37CA7A7BC5D4179F7D45A
-:1096E000B7131F947775B1A0B8EF87B6E708BFFF2F
-:1096F000A895E379156313105EBBC202783D67E558
-:10970000FEE0E756AE1FBF10D72169C18D28C7FF05
-:10971000E53C5AF42880672DF9200FD73B6CFBFFFE
-:109720004AF960E350B305E5C3B3F738AD83180DCC
-:10973000DD660626F9F5273EA6FC9AD11CC8E7EDA2
-:109740009756603B2329B0095D3616FA78E2013757
-:10975000C80DF2C38D848D10CAF14AAB68878E1193
-:109760001E569A78FBF527FE44F35E690ACC43BC8B
-:10977000607B29F4B732A5C36D80B6BDE5FDE587F2
-:109780006FC2B67CFFFDE521F8FEE534A96F021E2D
-:10979000D41FBD6D27B48768DA2A6F330BBFCAF9AF
-:1097A00035ECFFEBA16CE0D7C6BD4A0782E6D9BB1A
-:1097B0005AC1797A76AF267CD31FC8074E83F2A4AC
-:1097C000969019BF7F6EF161E752A0B39ADAE64234
-:1097D000BC5FE30EFAFDF1F21319D2FF85F7B579FC
-:1097E000B6B0A9A75BE38F7B18971BB614F4431C94
-:1097F000FF626846E517E9D0CF934A708511F5CC32
-:109800008B2627EA11D6C5F5D019D1170B67917FA2
-:10981000536FE54DD392E08AC1A827EE557D183FDE
-:10982000D7E5B757A27DAFDB93EF6B61517EA94BB4
-:10983000E9709521FFA4E8DBAD22EF9299D29C92CA
-:109840005282EB11ABF370BDA091B5DFF74384F703
-:109850006D23433FFD8B7D37248F827603B4D16F18
-:1098600068E87CD78CFCF9443AD79F8D9DC03FD0E7
-:10987000CF2A902F3F38329B546722EAA7E7FCCDCE
-:10988000D7A28BF7F5137F9B6805FA3E5FE077223E
-:10989000BDDDE9A61516701A9F373B07B3526CDB86
-:1098A00089BFEA4A0D5C8E98FDB77E55AC7F42FBBE
-:1098B000F813136FD3E6773DB82E03786EDA600F96
-:1098C0001992C9DEFC6FB4B78DEB0D21D45F064B46
-:1098D0009719E9EBC6B55DA28F93F0B650EAF3187D
-:1098E0007DBD7062EA6DD85EF86881337485FC6571
-:1098F000ED251B0B6BFCA327D2B91CD7AA215A4715
-:10990000A9BD9444CFFF79E3595978D895C6B3D30C
-:1099100073395E7D743CA2EBFEB2DFAE1D08745B52
-:10992000B8C36448D0F0DDC21D62BDDAEACFC47EA0
-:1099300032CC4CE01DFC7DC0AF9ADFDB0EA920E7E6
-:109940008FF5CAF98015634723DDA2CFD9489D1E44
-:10995000F063BCF958A2D403D7C47F3F31E6FD02BF
-:10996000D9F6AD189BD3179E8CC468DB02EFABFF12
-:109970009DD0DB46F8561B62FA4B95E38FA4FE247C
-:109980005F1D4FABFC6D68203C4F69AFC4FA8D9EE4
-:10999000D9CC8B7619F9D5A7D1FBC7D3B85CD75EE4
-:1099A0002AD4D13B8AF722DDFD938BDDBA75BFB98E
-:1099B000D50B697DF238EA79EC878528AEAADD906F
-:1099C000CDC21A7FEAFFC3F18FC231AA1F386EFEE3
-:1099D0001F86235F279F513806EAEEFFA3706CBEF7
-:1099E000ABE8B67C78658D12B214A05D78C440797E
-:1099F0001363CA586F0BAE3F3CA2929F872E09D6C5
-:109A00007F14A8ECB05A86F2D3EEC7389F2DE1F947
-:109A100023B8DF662A233B447E70E1DE8407D04F03
-:109A20002BA8F5CFC32BCB29A1F50DB92EC8441E09
-:109A30004CAE670C72B24A159CB751190F909D2A13
-:109A40000854D7A13367749427A27D5C630887709C
-:109A5000BCD0E37CBC0C43B8C382BA3769A013ED19
-:109A60005D4612D77F6C4509D9BFCD86826BE7036F
-:109A70001C8F2A95896F219E530A28FF8BF717C0E8
-:109A8000FDCDC26E19537C4EB4539B85DD6A15FA29
-:109A90005DDEB7A5061E407FE254FAC2DB2C37A07C
-:109AA0001EF2B7A581BD3999BE7085DB83F6C65B12
-:109AB0006001FB72F2C987C8DE6C6EF1663953A291
-:109AC000ED41FF0DD69AF4C4432BD05F596A5FF085
-:109AD00020FA3BF0FCB716D0B3CFA70ABD239E17E0
-:109AE000F4EA29D04BA0C78C2DBDED10EAA5825E0B
-:109AF000BDF310E99D2D1B8DD47E07C643FF07E6FD
-:109B00001132E27C07A9E4D75B019644685B071732
-:109B1000D03A11CC9B25A27F3D983F97F97CF3204A
-:109B200003E5F3F17DC4A3D5C3DF374F613E5CD7B6
-:109B3000323BEC1487C8F501A358A74A14751A8A5A
-:109B4000730AC5779655650B301EB30CD4AFC39A14
-:109B500063EA398CB1F51DF608F95F5FA48BBC7E12
-:109B60001A735F2E8CDE07BD5D8657D7DD4B2B1138
-:109B7000DE050EE634625E2518A175CE58BB66017F
-:109B80003BEAD5C887C5CEFCF1EA090E65703FD621
-:109B90007E49A5F8E64905FC1BB4A30ECE67D23F6B
-:109BA000323925DFEAEDAEF4974C297C2E0B278E57
-:109BB000C9C4F8DD68F75BD0CFD9E72CA3BC80918E
-:109BC000F96EAFD4F83B4B231329FFA63AFDE48787
-:109BD000178A38D1E8F431AD9FB36C310496D73091
-:109BE000F66C45D1189487A7AD114B21D2778D81A2
-:109BF000E2BDFD650F8614CCBF2D6224A7CF56B8F9
-:109C0000C6601E7D931A48BE17E5E5088CE7E5742B
-:109C1000E3EBB9AD0AE68B2F5A02C9A80F1E43BE6B
-:109C2000D7E0E5D7021F7F4FE7FAE75113978B651F
-:109C3000004F04E0502F5D47F9ADD5193CEF61AE00
-:109C40001E4BF91F33E003F37B09AC39E4A4F9F2AE
-:109C50007C5D82DBA0AB0B542F0DA5EFFF9E6ED079
-:109C6000C5D56D304FAF467F595988F27588E3AD41
-:109C700071FC977732783C62017FC84BFE49CC3A41
-:109C8000775FFF88FC15499F5E3F4501FFE40AF1BD
-:109C90005813C4CB5A7DDFA4F690FE6D827818EF7E
-:109CA0009F735AC83F94750F76A1CF96B983EDA3E1
-:109CB00090CF139386621E40651D84945558F7809B
-:109CC000FAD0ADF6F4F23FC87CAB356933BEB75479
-:109CD000D441D87C7AF94964ED113FCA67B1466E28
-:109CE00018E23B44FD2678F5F7190B328C33547794
-:109CF0006C9D44A8B71E8AEAF954F614AE5F4BBFB8
-:109D0000375BD4239DB57D447934F07B2BD3681D1C
-:109D1000A087E21699EFF9B67E7221F68179844523
-:109D20007FA938817236657C3EDEB7A99C4FC0158D
-:109D30005713CA30BC1A3F2F05E67FB7B07FE9C67C
-:109D400076AA1B795DC4B3FFE59CE1A1380AF0490E
-:109D5000F53689BE6E8A17859F66ECD58F1F2FF763
-:109D6000EBFDCE90D6CF5BB9E6E3E54B79BC42ED97
-:109D7000D79F8890FE7CD42ADBAF501BEC5C04E3B9
-:109D800025B62BC18B7C08DFFB51DED85D45E4672F
-:109D90001B0B5816E2636C9285F4A67157C266F4E9
-:109DA00083212E7E394DB35E7CD671340FFDE138B0
-:109DB000FD8574FDE57DBBFE60FC4EACC791CFC751
-:109DC00026AD8F18F9775EFC8EE5747D1482FED780
-:109DD000BC94C056000A9F36E9E55D5E370B7946B4
-:109DE0007DA3AD873457D7F891A9A55C27B813593F
-:109DF00044C34F52CED54B835944232785197C5DEC
-:109E00005555FD9447522F95D0F3BFA34CD338CE70
-:109E1000AB8C93DACF38C3487FF43F4E85D02F4CBC
-:109E2000AC5FA9545723F5427F721EBB4E16AB1789
-:109E3000E555EAC5CC0CDEFFBE0C7DFEF5C1F51D77
-:109E40008790854EDB830732A83EEA58129AF07A53
-:109E5000436428F2F1677DEF37E2E4DE4EE379FFF9
-:109E6000A26DF3DF4076EDCA085E443FE8B71962A1
-:109E70007DD20DF6D088F60EEC4509E5732FA6636A
-:109E80003E37E85D378EA13CDD45F9DC6457A00420
-:109E9000FB5F36B582720E12EE958B799D9AD4B324
-:109EA000763548F8B2A8217E7506C186337621C37F
-:109EB000344955109F5C8E8EAEB940726055FDC41A
-:109EC0005756A7C18B7E8115E242D4BB2D4E035F4E
-:109ED000BF715B28FFBF4C810811F4C68294822BAE
-:109EE000AE8F9B2FB9C8DE02246EADDEFEE78F93E6
-:109EF0002EEC837E1CD5C9FD06B69FDB6144C2A74C
-:109F00001A7D2CFD81D8EF62FB97F894F8B5205E9E
-:109F10004BC81EC6F537AC2EFD7A66A6D4B71947D6
-:109F20008B2270B741E94E42BF06F4A8D5857A7AF4
-:109F3000484F92C14BFAD7C5FDA090E06B66D7F2AF
-:109F4000B5CC53CB7949F817BC35DBA25D7F898549
-:109F500037D6CEDA4BF4750B56AFBE6E41EE0B30F2
-:109F6000AA01E21BD368BF05E5A4C559E6443F67D3
-:109F7000A9EAFDA39FEA2D4CE46F83FFAE1B5F5E51
-:109F80001F03F947384A5D065D5D8DBC3A701D259B
-:109F9000CE77535C5C4F3DB6EF6ED2C3AA8FAF3322
-:109FA000C5D28FB176E21747117352FE54C09B742D
-:109FB000957EFBE3A39FECB3929FAC8EB484B1AECD
-:109FC00033763CA329E05750EF9632F2938DB97C5B
-:109FD0007CE3204675E049E5A9AC5883C765EEA946
-:109FE000F47C41869321BD8D0E43201EBF483C0D5D
-:109FF0007419747CE3967CE3F9A008E540C33781CB
-:10A00000787C33D0C5F515C2A1A5EF327741663C07
-:10A01000FA44F522E7ABABF1C54C1BF7733ACD5CC4
-:10A020006F36208E205EAACF302FC3FCF7190B7F2E
-:10A03000CEFCC5DC2FB3709E9B69CB0BA33FD4A98C
-:10A04000FA6DE897CDEC5DB7F5D37E8F7AAB3FF92B
-:10A0500006B48FEF72BFF964A5BD4D817E4E9AFCA8
-:10A06000C988EF93EF1A95165A07E7F573B20EE910
-:10A07000A4C9BBF25A783EEB67467F0B3DD6FB8303
-:10A0800067987FD83BE81FEF36D27A4BFEE30F1874
-:10A0900087C0FB35E028223FCDACB287D00E777E5B
-:10A0A000D0FC11EAA3591B13BC4BB08E65FDB0AFB9
-:10A0B000B0FDF92A873781F26C058A07F35FABF3AD
-:10A0C0009DB46EB2888978EECE4955A0437F89430E
-:10A0D000CBFC35CCF973269F87568E85795E9BD154
-:10A0E00069B0034CCABAD04A0BD0EFD196801BE3BB
-:10A0F000C70ED7F495183FBA5CFEAE5B205E3CE11C
-:10A10000BA7B12B63B9F96FDDDB3D20F7AF91543A9
-:10A11000305F81E7B6CC872651FD6AA1EC7F193DFF
-:10A120009FF9F36BBE3A0AFD97AE5B3F09736E155C
-:10A13000D5E2FBD03304DFECD1B2BDD9563510BE29
-:10A14000B7315D1ECD148D47294FD7D9EB5F3D3711
-:10A1500009E3CF59639AAB54E87FC9BAED2B4B4062
-:10A160004446B4573AFDD0FEF1BA3726D980DF3ADB
-:10A1700099BF0EE3DD95EB0E4CB2DC04FDA7E9FBC5
-:10A180004F378A7C6CE8F04ACCE3F5C2C7DE5FE962
-:10A190001F187D7F983B61552827CAFFFF22F81FB3
-:10A1A000F8FD572E5C07B4741FC2145DDEA21E3387
-:10A1B000AF7B15F52939DD4379DD8D681777F33AE3
-:10A1C00065D976F376E792F8F6FECF6E2E779D8905
-:10A1D000F19F7F24F439C0EDC7FA95E4A3CCBF3DCD
-:10A1E0008E3C1D74D949FE0E82BF67498DCAD5EDDC
-:10A1F00020DB23B1FEC7C2E194FDC47E7F4CE8277B
-:10A2000016BA3D15F978B2E0F3429FC2EB7876DBDF
-:10A21000C283D0DF6311F50E98CF3691CFD8666533
-:10A22000F74F81A15D892CB803FDCF346897D0F733
-:10A23000FE1DF6687F6F735166E30A035BB0BF7162
-:10A24000999ED2D6FC683F00F7524B990E6E75640A
-:10A250002A3E0F65CD2FD1E0B384CF03F884F005FB
-:10A26000C3BC700BC84B67D7B5052B600A2B5D5E6E
-:10A270005DDC57D13595F6A5FCA79BFB3FCCCBBF4A
-:10A28000CFA8E275213D7B6C94A76096AE22A49383
-:10A29000FCEE92C047D58F27AFC3F7EABB4C8CEAE0
-:10A2A000FF77545ED11FA8C7BC9EC67FAC5723144E
-:10A2B000CFD5635E6F18F6F7B619ED18F6E315F90A
-:10A2C0006BCCCB65B4C6A7BFB487F5975258685816
-:10A2D0005FBD19ED3F9D9E5F6D5ED1FEF47167DF3E
-:10A2E000FECC621D40E05D157837C7877340A6E05D
-:10A2F00053C0B741C35FB305BF81F6243FE0DCAE76
-:10A30000C19B57E46BC7E5FB6E403FBF700BEACBC8
-:10A31000AE448A5B2A54FF247CBFA22B95D6172417
-:10A320007F48BE9074ED4C6DA67C4DCF530AD9C1C9
-:10A3300058B88A245CEB158223B33A687C40039FAB
-:10A340009407E8BF53F45F3E92E4E7192E0F2037DD
-:10A35000F7A2FCE27A25CEC3D73D74EA90BEF0FFA7
-:10A3600014EDDF70A223C7FF4B5651CFC1F1D617B2
-:10A37000FFD957A1671E3DAFE87A83E659DF8FDC2E
-:10A38000BEED4E2238338F4692BCF0DE1382FF3B87
-:10A390003B3E4D1A8572B1DBC8142F9F37EAAD0AD8
-:10A3A000A98FD99CB7C780FECBEC6D83BEF4221D6C
-:10A3B0007AF567C46289BEFFAA7BCEE4A5F02C3D86
-:10A3C00081CB6BBA11AC4D59148E6999DCCF1A1937
-:10A3D0008CEF97BEE776D07389EFA71655B14F6122
-:10A3E0007E3F73F1F5CF91DD2105E922E53A564F25
-:10A3F0002DCCE4F2383FF3FF919EB25E454F59A554
-:10A400009EE2F70F427084EFB95CDD4315F09F6B5D
-:10A410000C7E17C66127DEFD21EDE3982BEA5686F8
-:10A4200060DD0ADACDA301B22B5FE0435EBFF20824
-:10A43000C680B3DBF5F52B6C0BDF271ACB57513EEB
-:10A440000A09FF5DC021ECC1ED09DDBFE245C67A16
-:10A4500079966D80B3D150A8796EE7764BD201E83A
-:10A46000BD94A546E5F8935D999B50DF0E73F3BC50
-:10A47000627AA1BF14E72FE512ECAAE013C3FD53E3
-:10A48000ED5C6F4C8DC3BFCF08F99CBD9EF34DE7CB
-:10A49000DFAA2621DE3BDF4B4D59A2D1135B851D80
-:10A4A00094FD4A3D24BF93CF9F15FCB12D3389DA2B
-:10A4B0005B5D0E91E731C4DD37B755635F897FDAA5
-:10A4C00038FFC07C435AFE1EE65674F6B5D7AE0A76
-:10A4D0003C379801BF80BF6DA65016D6ED54741955
-:10A4E000A8BF9ADD0EAA07ACE9E078AC69DF67A8DF
-:10A4F000D3E027B6BFFFC8E4FEC02603AF233A6807
-:10A50000007E43BCDB397CE77679487F1E16EF5D21
-:10A51000DD6E7C333DB3C9CCEB4881BE54CFD7F060
-:10A5200072F626BD9E6E11F80FB6E23EB6F475CCFB
-:10A5300087B55680A78802704F770BBD63F69B7175
-:10A54000DF6ACF538CD6F30755FB4BBDD06E0AD8CC
-:10A55000CB14E8AFA89DEBE18A27C18F41B9B3487E
-:10A56000BBF0D676ED78C7321D221EE1FC5CB39EAF
-:10A57000E36F10F83F2FE015FAF915F9F11C9E4F23
-:10A58000D6768CC2FC93FCFE0B41FFABC15781F029
-:10A590009547E1C3FE919F983DB004FB6DFCC3CE8F
-:10A5A0006C6DBF5F65727D9B6E9C39C68A7A7E3505
-:10A5B000D81D92CEE07EDC9750B337C5B982913C6E
-:10A5C0001B30EE91E3D6883C24C85DC514985A51DF
-:10A5D000EF3892AEEFBFA89DBFEAE6FEDC3F8BBE30
-:10A5E0009DE620CDA76707C0EB8DE2A5B3E38125EB
-:10A5F00056B41347990FED84847750757712D69D22
-:10A600003409FB01F33560FC92FE332F6B45BC75BA
-:10A610008D3163FC14CBD7924EC58CCB8F8CD38AF3
-:10A62000718100DAB9EEA142FF308A773F79F9D51E
-:10A630001756507CC5E9D254CDE958E90E4E7767DC
-:10A6400044E510F47905EAAB9A277BF55107BFDFA3
-:10A6500095570DF8BCDE2DE55C4F97F4408715D774
-:10A6600035245F9FDD3324BC82D399C6EFEC708420
-:10A670001505F7A136B760DC2DF504C2A3ADC39470
-:10A68000F0F4D291011D8744EF0FAAE6FD3581BC9D
-:10A69000231FD51B9B158F427A80F2AC99A807A087
-:10A6A0009DD9C1DF637BF9B908124FF5D3A1538857
-:10A6B0003BFDEE129A87C4576675C4500FB72658F3
-:10A6C000AAFC2734FEDA61B1DE8078994AF106D718
-:10A6D000D7F5C6400EC6AD2C3381F671821D22FD22
-:10A6E00072D0CA542BF4F7265CD12E8D33CEA77DC1
-:10A6F00034E30A159263D00032EF13417FFAF65B20
-:10A700006C24FFECEB8706E23C336C9C0FA11F8BA3
-:10A71000E8C7427650D883DFE7815FA744F5F2416E
-:10A7200045A17E0EDE74DD66AA2D147C89FDA1FF95
-:10A730007450999243F6B23343141771F8FBB7671C
-:10A74000DD79F85C1B2F627C178D374B57DD0A3C97
-:10A7500035624247C4E044E9289FFC7D807F1CC4E9
-:10A760009B5698FF0382AF0FE6878C4908D7209845
-:10A7700037DC3A94182C69B647C77189FC8D4BD4E5
-:10A78000EFA2BF80578387EBFF9F78B8BDF8505C7E
-:10A790005D49F1F33D17C5F38FED5C4FAFA88CBF5A
-:10A7A0006FFB11615764DC79BB58EF80B8F3113748
-:10A7B0008F3B45FD295F1F01FF9EF05BF5E36A5A61
-:10A7C000F7BBD8352D999F87C0F5C12C51FF79FF74
-:10A7D00023D37E8A7C7602EBCC010F9F0A7E39E17F
-:10A7E000F427619D544362FC3AE267053C0D020F79
-:10A7F0002717F3F30B66E1BA1CF0DF1A37F7F3E61D
-:10A80000B60F1B8F749FBB4AA17539B9FE2FE95C47
-:10A81000BBC1A8CBAFCFC275B9B47F249E2AED27A8
-:10A820009E2AD7C55372DCD8B8EA93C56EDD3AC00C
-:10A83000CCF642717E047F7F16F311DCB3DAB27579
-:10A84000EB88AC2DE31BEDFBC7382A14173EB3EEA3
-:10A85000FE278B2D2CA485E3D440AA9F78C41D7CB1
-:10A86000C5AD83C3C642BA7CE86827ED27B2F23C87
-:10A870002CF8E33C8E81EB263BF9EB13D09FEDCD1A
-:10A8800087811E7126A35EAADCEF1E1E8D1FA49C6D
-:10A89000D58F8E1F47AC117ED01A178F93938FCA16
-:10A8A000B83AD18BFA51FAE5B1DFBDD7CBBF7ABF49
-:10A8B000F26A7908E0E390364E8AEDF794FB1F8D3B
-:10A8C000BF0BFBE197A2FF91F8BB627490F27CACE6
-:10A8D0005DA19A961163F5F1D0D768D787E3D5A625
-:10A8E0008B876AAAF5EF310FB7FFCC63D3F9F1FD7F
-:10A8F000E153EBC72B85A807797F8D822FF24FBFDD
-:10A9000047F5A4A33DDC2FF265F9133C705D25EA01
-:10A91000C95759F97EFE4DFFBDDF3D0BFDA3774CB6
-:10A92000B4FECF7673BEA97C66612B9E0F60EF509C
-:10A930009CDAFDABDF59A4F86B40AED3847EACF754
-:10A94000F1F9D4FB22E68176AC2FE670E474EC5387
-:10A95000540DDFE5D4F2F7723D265D5E3C5FB4072F
-:10A96000789C328ED937311DDFF7ABE81764752834
-:10A97000643FB39A19F9D559E50AF5FF9DF24DCA1E
-:10A98000AC92E87CDB0C534A9CF05D9BCBE643FB2E
-:10A99000F3C3ACE0351E84EF582482E672C4B12EB6
-:10A9A00015E3AD5559FE62C4839CA7D7E8CC423F5E
-:10A9B000DE768CC3D7DE9B67E2F687B195C22FDDCA
-:10A9C000CCFD33233BCCB87F4E76DEB5A498ECA00B
-:10A9D0009C8F2B55D811170BEEB4D3FB6DE4B758F1
-:10A9E000B81FE05A5244FEBCA46B34EE1C5C867166
-:10A9F00067E1AA883A13BE7B798321EE7915E305D6
-:10AA0000DE611E95DA795C4D6FC9F74CFDE41D25BA
-:10AA1000DFDB26C48FE7C112D2F3CA67D2EF21F978
-:10AA20005C6A6698AF96F85F9515B813E1C9EAD8E5
-:10AA3000A4206E3E11750A9F24F27CFC272B5E50E9
-:10AA4000D0BF7C681E731A59FF70D72F32FA6BB4CF
-:10AA5000F2BCD44C7491F14A141E9E8769F070FBCD
-:10AA6000B42F2B5083E337EE5E4D71F5BC2DC7CD6F
-:10AA7000575C87F88678536AB9BF5E3FC342F54C8E
-:10AA800095CFA844F7BAA5665A37ACDFBE83F6A7C0
-:10AA9000B187990FE5BFBE63875203E3D66DDFA18F
-:10AAA000CCD6E031BB3E4CF5DBD738E47A4484FCAD
-:10AAB000E958FEC63C02FA2F87AC5CFECF54DA435D
-:10AAC000B83E71C614ACC7F7CE786C3E5CC79478BC
-:10AAD0007F73C7AD745E8063674204AF6D86CD6ED1
-:10AAE0000BBCD776ADD987FCB42A2BB81CF192AA3F
-:10AAF000063AF1FB9474870FD737BC09AC8CECF79E
-:10AB000037C4C38818BE18F130979757847E813FA9
-:10AB1000AAA77AD6C3FD725C5E427D75C8C4E7B150
-:10AB20009371780D1EFF7A944B763895C6CDAA8F17
-:10AB300028587F113B6E94AFFC1B3D19DF06CE0EEB
-:10AB400033EAF93AA16F2A9FD9A27CAA81FB458FEB
-:10AB500091E0CBDABE49C1FC193C277D03EF33AC51
-:10AB600077CADACEE3D53A783E5BA35FE43CE2E80D
-:10AB7000994E84CF7EACEB00D73311BE5E20E08DC2
-:10AB8000A567C4E3A5F1C783BB40F7CDA1628C974D
-:10AB90000F1524527F52EE63E534E2E17E65D686DE
-:10ABA0002D8AC14EEB2AE45F4AF8E47BBEAC310744
-:10ABB0003C84872EC243C30695E633CE1C18385F0B
-:10ABC000230FEF89FEDE98FE119DABF3E4BFBD4B72
-:10ABD000FCD8007136C519EDEF9AA7A19D09FDC2F9
-:10ABE00088EB6093B88BC2D68A73A72675723DDC5A
-:10ABF000D0B9439D658FF269FEE937E8BCAA868E1D
-:10AC00000486F115F0DF518427964FBF293D411F7F
-:10AC1000F1F829641679BE603EC63F524F1B84FC92
-:10AC2000333BBF7F41B4A3FC133CEDD1E9592BC9A1
-:10AC300045FEE9B237B0DEB3C1A7D0791D129EF44C
-:10AC4000AAF87EBBD48F526F633E31A0D1EF1705B7
-:10AC50005DA11DE1712A2B403B2DE18CA5D3802CF9
-:10AC6000AEC7E3F0D3DF11DE58BB25ED79FEC69DFC
-:10AC70002AEEBF917C3209E9ABE113479699E07067
-:10AC800064A9D4FFDA4ABEEEB8D6C4EDD5DA160B05
-:10AC9000D561BE7937AF0B73DC638EE0F5A06166DA
-:10ACA0003D3E3F98C5E168332CA1FD68207F49599E
-:10ACB00019C827498CEB41AEF79EFC0DD75BF521F7
-:10ACC0003BC5B9F5C13B6B68DD3FDDEAC37A591678
-:10ACD0003C609EE688E235968FBC3BF799711E93E7
-:10ACE0003AB8BC81DE243E8AE22FAC9313290F864A
-:10ACF0005E3F2198CFFD201E479588FD81B5161F28
-:10AD0000ED2FAC15F9D612B14FB0E2A89FECC14CB3
-:10AD100041878DF6C0755998A75915936FFD8671B7
-:10AD200040DDA2DF51DCF5A0FB2DBA4A79847855CD
-:10AD300027B73766713F3B5F5C2BB3389FD495775D
-:10AD400090BCD59D682639B54FE0FACA7E2CC62F37
-:10AD5000648F09BE5B45E38EB3758CC7F5E2713F26
-:10AD6000579CADAC7F38E7E23E2B8CE736EC4F7A50
-:10AD700000E5F96B882634FB70A666713939B30D8E
-:10AD8000104EF6A8D97C253FFB6AFDB1C81185CECF
-:10AD9000F910B83CB3BDEA86CF707D675BB20FF7A0
-:10ADA000D37FB9FD8E1F7C06709FD9728B0FED7F0C
-:10ADB0007A6B80F8A527C3EADBCCF3AF13303FD51D
-:10ADC000D2B13F09F7ED7CF1C2F565A88FE7657157
-:10ADD0003D75FA37C645889725CFFFFA667C5E1722
-:10ADE00056D2D02F3DB3EDE77FCF827E6AB734E1F4
-:10ADF0000962ACF585D7C9DF378437F1FBDB92C92F
-:10AE00007FFDE2D9D53723BE5B3B5AE9F9E96737C5
-:10AE100051FB8DE77FFDDADFE0BDFA4012ED673EC2
-:10AE2000FD9B7D4497FAA04A75E7BD7C1CAB077774
-:10AE3000ECE37A10ED37F2FD0CAE9F241F4BFEFDC4
-:10AE4000E2F9FB6FD0DA0379BF4DE469DA12B97D1C
-:10AE5000F852C869DD187B1B5EBF7CD14AE76E36AD
-:10AE60009ABB8B307EAF2FE17CF17D818FFA8EF91A
-:10AE7000A6463B7D4FFDFC27303D5E87007F627D0F
-:10AE800017BCB5E532D529FD8AEB99443612F33863
-:10AE9000D3AB8FF37D9B25CDA63A82F305FE1C66CE
-:10AEA000AD7D5EB1307EDCB83ACBAECBD366754EAD
-:10AEB000C9F192DC27F80669FCDAACDA60AB03EE84
-:10AEC000DFB630E8C37DEF2F9F7A6F3CEE4F78BE40
-:10AED000581946F4372ADC7E85EC344E03AE0F4118
-:10AEE0005CF1AC9013084BD36F84F98C53593A6ED4
-:10AEF000DD1DC7D81113E985ADF41CFC17F2CBBCDE
-:10AF0000AF4FDF8AFECC5A53D0331CFB6913766FE8
-:10AF10000B871FBE77DACBA83FE78DDC0F5F80DFA2
-:10AF20009D6F999C8E7E3BF4DB65D2C459C09179AC
-:10AF300068F7B0BF72C4D384D00CB23F5E33CD4F3C
-:10AF40009EE709F31F7AEF90A87CC6E691503F6117
-:10AF5000DE775F56E55ED433F2EAEA270FC3B2F933
-:10AF6000737FB69FAEDFF47CD037A69FE3F6FB95E8
-:10AF7000E3C4B78DC8B7387EF084CE7ECF927CBB59
-:10AF8000E738F1EDACDDDC7E37EE2E3523BF7EB940
-:10AF9000D8CF3E0507B651F0DF5AA57B0EEDFFDA9C
-:10AFA00063A57D7DE7247FAE3AFE39D69B16ECF68D
-:10AFB000509EE0DC1ECEA7070D068AEF0F6EBE6E18
-:10AFC00053ABD2D76E821F4D72D2D8CC841FBDF046
-:10AFD0003DF4BB1A6A799D79630C1FE56FFC641917
-:10AFE000F24B0A78BD583F037ECA78DA1759CF86EC
-:10AFF000A39C668DF5EFC9A6F53F1E7767D5823E07
-:10B0000081F66DE9F37C789455CA58F07791FFD2B8
-:10B010006FF2613E6C6D6EC732F48B43E3189D9BFB
-:10B02000BAD6D43E06E3DBB5E3BC4EC024E06D0BDC
-:10B03000F9CDACD82CEC570DF9DB8DEE7FF551BE78
-:10B040003A56FEF7B490DFD6E84DF4E139B6937680
-:10B050002B0BB89F6267087F23E017DB93C2A3C264
-:10B0600008CF59813F89C773A62E3A4FF7DC4B09A9
-:10B07000743EE1A4B19C5F53C67690FE7873CFAD69
-:10B08000649F255F3A7625909D4E559D0AE62F18C0
-:10B09000BB23414BD77651879B22EC48E12A4EDFF8
-:10B0A000C46CEE6724661BC4D52CF85C9EB712A254
-:10B0B0007CC259417FFCF36ACE6B6AA889903CD56B
-:10B0C0006FE7FDA527F84B1FD2F0AFF497E47A2B7A
-:10B0D000AEBF4E89C3DF3E0147FEC60544F759B5F2
-:10B0E000E23C8755DC8F60C0178837A023F1C16D23
-:10B0F000E973896EB35629F7101D431594D7947ED2
-:10B10000576CFFE5D95C2F6EB306CAB18EAF27C36B
-:10B11000E1C3FA806D297E03AD0F94A6507E2323F0
-:10B120008DFB8119C20F8CCA7DA0DC00E39C7239B3
-:10B1300038BDC3BF57316FEDCFF6C6F5EBFAC6EF9A
-:10B14000BCBFC9EDA1A118CFC8F563898F704BE2D0
-:10B150000CAD3EBD51E0233C98CD40BD0171829DB8
-:10B16000F2EB4E1807F3049B473DCBF304FC5CE77E
-:10B17000C26C9EA71B97162847BF2CA330B090DB4C
-:10B180004F3ECF587CEC13F6FD8DE9F795627CDAE3
-:10B1900078A7DD8772F7E42BCA4CE2EB90050FFB32
-:10B1A00001BEE772080E13D5ADB1A04AF4686C0E6B
-:10B1B00084E3F3FD1492B346F0F3D0BF9F847C9EEA
-:10B1C0004E7C1FE67CCFED9FCC23A09ED4AEAB4837
-:10B1D0007D20F50CDA37E46729178D377717217D45
-:10B1E000BFA95E3967E2727E0EF0807224E5C6F177
-:10B1F000329797152DDE4A7CBE02E45E4BEFD8B83D
-:10B200000BE1C4F855EAF71F66051AB3318E3044D6
-:10B2100096D1DE52A18F1B5F5E5E146F7F90D4C704
-:10B2200016711EA6256C0B6BD741B0B6C25146D71E
-:10B2300010DA23DBA2F87996966C695FFBD4A5B58A
-:10B24000640FEF5B97E642DB85F2B3D946FBD4642B
-:10B25000DE29B6DF87B2155D7E47C625B89E81EF31
-:10B260003F23E4A75DF0E573D932CF1BD6F1BFD7FA
-:10B27000103C8E7505FDD931F9DD3F2B0F26C791A6
-:10B28000F63496FE723D06E733A5A4FFF7DAF731F0
-:10B29000B1CEA7E7C717859CD46533BAB69B2217F2
-:10B2A00049AEE63B18D5F3AC67FE345CE77BED1A9C
-:10B2B0002E0FFE9E22EC7F606ED09A9311CDF7E2A6
-:10B2C0007D8C3FEB54164A009AD46D3385B5FB64F0
-:10B2D0007E86B58600C779872564043EAFC80DEE2B
-:10B2E00045FE0A8DE1FBE1423FB4D2FA1438D2C3E5
-:10B2F00051BF34B1EE24C473A3B1AB08F393D5AE00
-:10B30000E03EA4FF2786AE3C5ED7C1D7CF8E897CB6
-:10B31000EE3191CFED344772BF9F1E3D9FEE02E3A9
-:10B32000755517BA0CA918F77DB8FB0F2FBE025F31
-:10B33000DFFBCAD97B7F84D85A61BBEF6770ADB69B
-:10B340001803AA26EF76CC115FCF7E20F8A8B7EEBF
-:10B35000A925216E3E7F6B0E7FAF2966BD7A6B0EED
-:10B36000D7A7D17D4F7CBDFAC37ECEB5BA2147D4D5
-:10B370004B8A7AACD8E737E7707EDB666245EB1123
-:10B380009E4D0E5AE7672A3F8FACF6897C1FAECFE1
-:10B390007716F0F3EF7BD62864078E99B8FE81BF4D
-:10B3A0003B2D15513B8A6E0AFA89B5CE50C400FA7E
-:10B3B000A376A12382E760C27D7534CA5AC8497555
-:10B3C000C133857D9CD5FCE65F319F51AB32CB68A4
-:10B3D000F8EEA4BD2609CDC39CEF3E8447CCB0CC8B
-:10B3E000EA76513F2ACE57F34F365EB65DC9AFD3EA
-:10B3F000EF1BF9454E80E5C0FCAB9339BEAB1FE2B5
-:10B40000E7ECCAF77F23E43696DFB621AF02BC1F14
-:10B4100029DCBEC48EE3CC1DF302F253B53B60A31E
-:10B42000FE1F3A4B7AADFA152B9D7F5487EB5CA03B
-:10B43000F2CE9776152DCA47BEEEC9FB23E6C9F6B4
-:10B4400026505D721DAE7769D6A7FB5BEFEA7F9D44
-:10B45000CB6B46FE6DBCA410FD67EE7DF328EAEBD6
-:10B4600046B59BF862A6C54E786FBCA4D273D6666B
-:10B470003AA3DDDFB6D0EDCF47B8433F1E9D42EB88
-:10B480006599709FF0574CE7632C10F5E0CEDC60B7
-:10B4900031BEB7CE96743FC67D172CFC3CA4263334
-:10B4A000AFFB6662DFB0A43FCB71E8E9BBF7ADBF8D
-:10B4B000225C3596209D2B397B06C4C946A447647F
-:10B4C000B8B3444BD7D1DFEA5C5B7B0ED7371F9A0A
-:10B4D00079DD4F5FBEE67A69AB7C2F8BCBC787796E
-:10B4E000AC76275EAF852B7CF761816897F1766C2F
-:10B4F0003F33857C7C3894DBA5D0025BDCF33CEEEB
-:10B5000014E3FD22C73F19F125EF3F25E4CF99EB66
-:10B51000BF1DEF83DEBB03F51EF0632405FAAB7E8F
-:10B520009DFFBE005BDA4375A7BDF32A12F0BAE2B5
-:10B53000C3F5FD68BFF7607FF09E9FFCF3D7ACB406
-:10B540006F8D4D063D8C7A77412E43BD0BE3CEC403
-:10B55000F1A1DF480ABD9740F3606DA08F41E0CEB6
-:10B560000FF7125D5654029F968BF3F2BD51BE92B7
-:10B57000FC14CB474D424FC5598F6F42B862D7E399
-:10B580000112A237F1DBB7D8FF352A8DEB7F90E7A8
-:10B590001FE4905D8D0CD1D6F3493C4B3DF861A280
-:10B5A0009E2F4C02CE16F15E2F9EC5F953E985DC25
-:10B5B000BEC93860B5A0BB557C27AFD25EC5E6F3E7
-:10B5C000ADA25F6B4E92A4CB6308A7B4737DE8BDB8
-:10B5D00081D31BDE7B9CF44742CF7D6960A7EE02DE
-:10B5E000FF07CF9F84EFECF85D9F7CC4586E5F9B94
-:10B5F000163818DAFF0D39A24EBBBC87AFB715C39A
-:10B600007508CA1FE81DE5EAF4C3D8DF037AEED750
-:10B6100058EF01E329583F944A6AC08BFD01BE9F51
-:10B62000D7E23B76BC63F808FCBD1D39625F5C293C
-:10B630002B457ADDF7EE5F1CF77AF17C72BE1FF7BF
-:10B64000337BF025ECE7CC0FDE22FFFE983952D495
-:10B650006E8FF3DC1CD9B84E893EBFFF17C610FEB3
-:10B660001E4567D79935D3812F6776197D38E4CC8D
-:10B67000872FBE3302FDE62E13AD1B81DFB00ACF4C
-:10B68000E73C26EA0059B33EFE7F57D047EE0B96C3
-:10B69000FA49DAFF79CCC7F552223F0FFD93F973CF
-:10B6A000695F700D0B1CC2F3D0BF583091FCE2B93A
-:10B6B0002C48E771CF6AD39F871B7B8E6EECF9B95C
-:10B6C0009880477CC59EA3FBE5F7AE9C2F97F52B92
-:10B6D000B1CFFF26F8F1CB7EEACB4F0BFE95F500FC
-:10B6E0004DB21EE0D52BD70334C5D40344FD0C590D
-:10B6F0000FF035AF0778555F0FF0E598F8705C10E4
-:10B700007034E1393A71FB4DA2FB5F165C799E4DB6
-:10B71000782E4EDC7DDF76BADF5F3D822D57E0A9C3
-:10B720009F7A8C845CD9BF47678F6DB9DE183F2B39
-:10B73000879E37C5D435449FF37A06991700BA52CD
-:10B74000FD9CF4EF62F7C3CB7CBC949F4F1566F170
-:10B75000501E6DB5881B7C43D11FFE14FD2C94DF59
-:10B760005BBDAF7503A8B37E7443915A1095AFD8F3
-:10B77000F9005F9ED6EE3B1F902BCE6FF0311FED90
-:10B780004B147271DF0FC625633EFFE387AB74FB7A
-:10B79000CD7AF7A39BA57F67D7D9731663EF67EDC3
-:10B7A0007E8BFCB71A4B80F6BD7DF6EA0FC8CECF74
-:10B7B000610117CAC9F957AFC90BFE5FD87909CF24
-:10B7C0001DA1074CDC6F4F27FF64AA80E78EBDDC0C
-:10B7D0007F3458FC261AC7CFBC4E1785E61C5E5036
-:10B7E000B678EEDD4DBDF097D07919A305FC0A7E41
-:10B7F0000FF8BD495CD9CCA01BE196FBF881EBDCCE
-:10B80000786DBDC1E7C5EB2D4A40659AFD9DE359B2
-:10B81000730EBE6FB0741BC5F962742E7C42145F48
-:10B82000D47688F6D23B2FDC371BEFDBF9F9C26602
-:10B8300001473057EC5BB6300BCE3BC11EF982D6C8
-:10B84000FBC4353486FBE3A1025E479C88E717C042
-:10B85000B876FBD9104ED6C99CB42FDFEABC10C114
-:10B86000B844F3BB1035B9C335BF0BC1223C5FD51B
-:10B87000DFF398DF8D4815F0B50A3DE9C1F3050BFC
-:10B88000E91C05D2938F3BE6D079E219F685B40E18
-:10B89000FD54D2045AA77421E2B13E7E82E61C0414
-:10B8A000789E11D09F7F903943DFF604F56D0B3BF6
-:10B8B00046F55C4A24E0BE9C163DE7D124F4CD9DBC
-:10B8C000891CAE3B1379FCD69AABDF971990BFE782
-:10B8D00092CACF4938E7B258B0AE02FC93D65CEEBC
-:10B8E0009F7C0494863891FFDE4BE92DFE416BCAA4
-:10B8F000F1774C8CBE2540A7650E6F8B8A7EDFDD0D
-:10B90000E277BFD40EAA57D8745F8A0FEB6B9659B3
-:10B910009D9598070DE5F2FC4F93D8A70114A9DB7C
-:10B920000EDF6D9A9A4DEFA557F550FEB467392397
-:10B93000BFAA0F9F7E0DFC0FF87E16DB787E438D2D
-:10B94000AF0BF7ED7AFC46AA3396CFB7E07380537E
-:10B95000117C81F76FA988FE2E53E1DED2FD78FEBF
-:10B96000240B2A3E9E8EF412BF4F13FE7CD3DECAF8
-:10B97000DB87035C855DC3888D07EE15EB2FE90936
-:10B98000627D989FBF1BFBFE407C1FDAB6C3DE7F43
-:10B99000ADC7470688BBF1BB31369AF711917F627C
-:10B9A000423F8C8891BF515179A0E7A5A2DD24EADE
-:10B9B00001F1CC087F054F6FD07BE95C3E7C4CFEEB
-:10B9C00071B9BD9145FFB09FAA68BFA4A7C6461F25
-:10B9D00047E510A65866F1B5D6C37B07A7F075F406
-:10B9E000116A641FCAFB28712D155736B39DF0BB31
-:10B9F000A225F286291F532D0123B62B9CCB5BB1C8
-:10BA00009F9B94085DF366AC6E4535EDCD2B14FC21
-:10BA1000161C87F2B96C1CDFDFDC3AD2E773C2A3D5
-:10BA2000E933787E76DA0C0BD54D4F53F9794C4CCF
-:10BA30000DE6DF0572765735CF0B63BB5A937791CE
-:10BA4000EB204720BED911C73FF0E671BB25BF6F81
-:10BA500012753EF2790E1EF40C001AF2C67F9C4B52
-:10BA6000F684AFF77E962BFCB462561CF3FB315F75
-:10BA7000901EA8FC5D7F7A42FF5CE88969FE274C36
-:10BA8000E4DF0B7D21F57240D42F75897354DE1FDE
-:10BA9000C3F1FE5EE53CD21777B266D2E777B1908C
-:10BAA00009F1DBABFF2768FC2318675A40EF2F4DE5
-:10BAB0009F11EB57717E95E3DE1DD43F9F2AFDDE7B
-:10BAC000097ABFB7FAFB5FA7905DCC7CAEE1F2804C
-:10BAD000689D52534C9D52A3A8536ADA3DFF60867D
-:10BAE000A64EA9692FAF536ADC7DB53AA51E5A57F9
-:10BAF0003A620AEFC3F59623F3402400CEFDA2AECE
-:10BB0000E500D6B59445F9D23195E75D817D69FDB3
-:10BB100024C769F3213FB519CA284FDB96E4F069C1
-:10BB2000F3A22B5A80EF34F959599774A49FB8B8EF
-:10BB3000388FC7A96B159E270FDD6DA13830A33054
-:10BB4000A05B97C830B2A3986FFC58F8416B451EB4
-:10BB500004D7F586C135AC70FFA6F77BDCEF84F91E
-:10BB6000C9187D9491E6A375818CE42194DF9FB17F
-:10BB7000B7740BE91BBBD587F5FCB2FF19C14D2A81
-:10BB8000D60B35EDDDA4D6D8A37C372A4FF0AB8D8C
-:10BB9000D9905F7BF37D3B1328DFF7993D704B1EF7
-:10BBA000CCA7DE1C19CAF4FC4CF7FBB36B7305BFC2
-:10BBB00098C604EE9E0DF09C7FC7CCF35E0F3392C7
-:10BBC000D7DFEC49A17CA53A95917D595AC9F8EF88
-:10BBD000BB6C52C89F3B99C2CF0D5A3A85911D3C10
-:10BBE000973A9EE8378F850FE1B940B51B4CBAF301
-:10BBF0007F1EDCA26FD7B30EB237F5DBFBF033E963
-:10BC00002DA91F1B98D7887AA8B153FF3D1BA8D731
-:10BC10008FA5C21E0C9B36B6D504DF0D3370BDC593
-:10BC20001EF6654FA5B8BB9ADB51F61C9D3775DE35
-:10BC300071CAC8E59CEBE3E151ADA9B34BC3857F65
-:10BC400075B3CA7F1741FA4BC3C5EF241C30EC35DE
-:10BC5000D26FF20878CAC577D24F93FA5AD2A5723A
-:10BC600024FEC603443779C2DF2960054857E89FA0
-:10BC7000E441C140891F714CBFB7304A8C0774E75B
-:10BC8000E7CD192C61E4A3654A33E9690B13FA5A2D
-:10BC900009925EFEB750C8887C70036BBE037FBFFD
-:10BCA00073B4A5CB467EA93DF868DEF0289FB4B2F8
-:10BCB00048DE0E45C72FF4FC4CCAEFE2F28BB42BE2
-:10BCC00091F7B9BF3189811F08E3FA3FE07ED001C7
-:10BCD00085C78BE00F1EC078F1778689C40F13618A
-:10BCE0001AF8DE38A79ECEB7BAF5ED89DE3E7C6045
-:10BCF000D4FEFE04489C8AF04C2AD6BFE797FA8D02
-:10BD0000E9F55B3EFB9AD7C12F3FF45DCC1BD816FB
-:10BD1000B162F463C073F4C5FB7DD16DC25EC459DA
-:10BD200037D99697D177DDE4BCC8FFDEC8BAE76C97
-:10BD300057FAF2CDB9838B8C6E0D7F497E7E59D434
-:10BD40005928AF8BF5D9729E2F8CDA79CE3715A290
-:10BD50007523F21DBCFF96E417F13B2137EDB64683
-:10BD6000F077704A453F3722FF9445ED7AC460F77B
-:10BD70009A0B904F7C6D46635F7FDE95EA257E19B6
-:10BD800066F013BF0C67BE34A4D3484B47AB8AF0B0
-:10BD9000EF19911DB4EBF8E31DE20F05F883F2599A
-:10BDA0007DECA3FE790CFF483A1E167EF4ADCC4B19
-:10BDB00071C404E14747F239FF54D9EF54F1FB371E
-:10BDC0000B78BE612C2E28D23E53BD5DACB2E8F993
-:10BDD0002096BF60448376DC587EEB8F6F0620DFB1
-:10BDE00048BB987675BE39DF3FDF9CBF12DFC4F2D7
-:10BDF0008BD42B3BACCE2A3BE6B76A15D2C7C3DE49
-:10BE000019D88AED6B1AF2A90E66478A6F3F3D6F0B
-:10BE1000E6CFCBBBFC46AC93295C289EE707AAB0D3
-:10BE2000DDB488AF530C3FC2EB68063ECC9F972E23
-:10BE300069DE8FFBFA9A42FCFB97BF5846FB9BC218
-:10BE4000CBC4F795ED55D86E6AE3DF9FC4F5A6EB3A
-:10BE5000B1FE2DDC8AF707AFCAF7F1B094FBB5B796
-:10BE6000083EDDA1ECDC4FDFB5F3EFE61EB224D2D5
-:10BE7000EF060ABFF56631CF5B36F079A67F7A1BF5
-:10BE8000FD8EE8EC9E10F94F9F1BEAE9776AFA8B6A
-:10BE90003F2B95F61CBCDE8AFA040FDFB2005F1759
-:10BEA000F0F5C8CD30C47503B83F28D7F1B0AE4027
-:10BEB0005B4770DD001E17C9F75CA97C1F1A7BDA8F
-:10BEC00041F962B9CE1859C71494339CA3F003E228
-:10BED000AE3BDE5AD84CEB8DB70E90EB8DDD2A9E33
-:10BEE000A35E7AF92FE3E3E559CA06F03CD0295165
-:10BEF0002721EFD786F3E977C1762093D03EFAF079
-:10BF0000EFA92DCE056762DFDA8E7CDEF60FD8F062
-:10BF1000D3B61CC0AFA159C573D4589E42FBF6FEE0
-:10BF2000A58B459293FAC27FABCA2266BEEF8EE024
-:10BF30009FD36ADECCF74F72BD344DAA9DD18348A2
-:10BF40004EEF1474FACE00E1770C63C350DF4C134C
-:10BF500074BBCB027E2BE9B576538CFC4F1980FE67
-:10BF6000C653FDFACFFAE731FAA1568C3B47F8CD1C
-:10BF7000F3F0F7478D78BE3BF79F4F3DC5FDE607D1
-:10BF80005907E523CF3FCDFDC506981EF24B9FDF35
-:10BF9000E7DAA66F3774C4FE2E6C88FAEFF3BBABFA
-:10BFA000253CAF7BFEA9860ACCEFD5AE7F87F2C7D2
-:10BFB000B5525F84F5FA021C0CAE2FD65D4B791D8D
-:10BFC0008385FF2EE630D017586F320CEB48A1FF67
-:10BFD000A162DFFE72FC84EFD77F6800E98D09540F
-:10BFE000674AFD19697DF71DBF374A1F693762F53A
-:10BFF00045A9CCD70C4CA57C96D41FA5C24F611384
-:10C0000062E3C727490E8789D64F06E8E320E97720
-:10C01000C0F7E4777419EC618341EB6784492ECB58
-:10C020002C602F48947C1626F6FFC7D0F971A273B6
-:10C03000FF7194FE790C1FC838A642F0C1DDCC4FC9
-:10C04000F1D12EC107EFBDCF7FBF6D9A7D21F1E108
-:10C05000FB1F70BF53C651DF3E7E8AFC43F1532F56
-:10C06000DDADE04FDAF07728260E5A83EBE49D56DB
-:10C07000FE7BD50AA7B3EBEE2379DAFCE27BF8BBB3
-:10C080002B9ADF73689D9860C175C456138F2FA6D5
-:10C090004EFAB062A6467F0C49ABDC85F85AA6740E
-:10C0A0007DEF4F186FBC25CE4FDD9B4174BFD0C5CF
-:10C0B000EF5FD8709D2F04B7BF3489F3A894E63999
-:10C0C000581A25E198237EA765AE31FC5A37AEC7D2
-:10C0D0002AE15DF50AFDAECA01ECBFCE1031F3BC1A
-:10C0E0005E17E5E965FFFDE72943A4CFCC6F70FB40
-:10C0F000D8A324FA789E37A4FBBD9E035E1E6F551D
-:10C10000E406BA060C8FDABFD8BA8363F36FA57D55
-:10C11000A9FFC5FCC9B82EAAA8FCF79963C7C53A00
-:10C1200083A59A3CF5316BFCF5838F849ECF435CED
-:10C13000C1F88BB2FD1FE33C4F89B8F094581F3B08
-:10C1400095C4D7CB4E0BFD9CE715EB79E27A4AAC50
-:10C15000A79D4AD5C793F23D83977F7762B125B0FB
-:10C16000544357EFBA8466CC4B64148ABA92858CD8
-:10C17000C74F7B5274E72438BC9579DE0C7C4F9C0A
-:10C1800033B087DB655CC7C675E6F559C14B88B728
-:10C19000462FF3E33A2DF3769BEFC0F54AB13FF714
-:10C1A000BCE09BF3567E957039BC53F2BC88EFF926
-:10C1B000DD44D7DEF6946ED297FF072EE42C97006D
-:10C1C000800000001F8B080000000000000BD57DE0
-:10C1D000097C54D5F9E8B973670B9909939040101D
-:10C1E00088938D246461B261D86492808A22262C5F
-:10C1F00015651B50C2964DA0FDA5D5BE0C06117944
-:10C20000DA426B5BFCBBBC01C16AB52562B0B126EA
-:10C2100076544AA1D53A22286A6A4754D69044A057
-:10C22000567FF2FBFBBEEF3BE764E6DE4CD89EFA9E
-:10C23000DE4BFC7972EEB9F72CDFF9F6F37D07BB24
-:10C24000B322C999C058F7ECA099A98CD965FD21F2
-:10C250005E871F031BCCD862FCCB09A5D5E657F33C
-:10C26000E0EF0DA6CE6026B5B36F52185354E665C5
-:10C270007150C964CE0A3B3E9DE0389A0D4514B416
-:10C28000433F7566DB066534BD5E6185FEE68BFE69
-:10C29000D870BB11FB9FC7BB62F3DBF67FA5C43030
-:10C2A000B6C0CAD60F83F6856D43CC3003B62CC614
-:10C2B0003BD291836F4C761C8571156FB4FA4D3467
-:10C2C000F48D3F93FA968C19D951393F5A8797319B
-:10C2D0005CD78800AD6B63694FD27F1531D6D36EC2
-:10C2E000716C83716ADAFE7A588175D5C8F5B568C4
-:10C2F000D797ED54182BC69AD5F7A995B15B98C27C
-:10C3000006423FAD364F36C2ABC61AA479428FE61D
-:10C310008A5C18EDFE09B1B4FE21F03DCCE7C546BC
-:10C3200037FBC41482E72A075FFF14B5BADC1CCFC1
-:10C33000D8993B99C3028F56EDBFA3C90AF5550F93
-:10C3400030071FDD6D6063A07F01AFFEE69750618F
-:10C35000604EABA8E3B07306306766A83ED413A75F
-:10C36000A943BF0CE7B152F43B6CD9559AEF47D4BF
-:10C37000A768DEBFBA6194A63DD95BA0A9A76E18D5
-:10C38000A7793F7D5399A69EB1E546CDFBF92C7563
-:10C39000208375D6ED53990F409BE59BA169CF7E15
-:10C3A000FA76CDF7C758FDAF27C07B2D5131790CF8
-:10C3B000F0A8292A661B96CCEB0EE4007CEE14EB69
-:10C3C000C86D5EACE9E754CC75FB705FEF0C544D63
-:10C3D000638057A35B5768FA5DA956F37DDB643A27
-:10C3E0001284EFEAE117E159C07AF60E03FCA8F5D2
-:10C3F000292E3F342FDDC2DBE577CB5BB7D277CB7D
-:10C400007DDAE72B9FD6D6BD652CB3DE06EB74DA5A
-:10C41000E38F02BEB2ABD855DF84D155080FE025BB
-:10C4200018EFCC63AACF928CF0C9F8CD04828F8923
-:10C43000F99C7DF7EB0C632E3FBEFF9CDDE585FA92
-:10C44000D2FD77D07C2C895A3C88726AF1203A530D
-:10C450008B07769776DF079668F75D0FDF58F7A8AA
-:10C460000BC277D00D5ABC90702D81DF6F13AE8F49
-:10C47000E8E059B8C7DD642338B159D631083F3EEA
-:10C480005F0BAB50592AFC1D0F7C069EBB7817EC46
-:10C49000B4C3E63500FE3CE3548CC427443FF94660
-:10C4A000FFABB89EF58A97E17751CC9788FCA2A99B
-:10C4B000C49FE4877D29B0D6E3CEB1CF6C15BF47CA
-:10C4C000BAAF36FBF3B05DF6F799CD43CF3B953766
-:10C4D000AA18AC9719FD79C40FAD8CC697701C33A0
-:10C4E00080E3F14A5661C6715E14F8FCE9FBCB08A3
-:10C4F0008E55AC7EAF1BC63BF50187EF72E6A5F704
-:10C50000966CD2C2A10FFC747003B471E2B875626C
-:10C51000DD2B18F31952FBC2536953FCF63C04435C
-:10C520009BE4DB9E6F0A39DA213CC7B1DE1FE2DFF4
-:10C5300012BEF08212CE9F703CC7E0D078129E925D
-:10C540006FC9712CAC5E4D443AD0F13196A9DD270C
-:10C55000864C620CFD473F7F021E6A8D13830DC619
-:10C560007E70F28C5D23C6618B3D8908272BDB44EE
-:10C57000FBB751716D50611CF5EAE42606F02C748E
-:10C58000B855DCAF6216988BCF4BACCD4D46E8EA80
-:10C590006A76DE41F834E4A99A6F0685D6A1C8759B
-:10C5A00079156684FA44519FE955828F26E37AFE15
-:10C5B000FA158E3B519433B184FD83657EF2217C64
-:10C5C0003C41718EC0F166FC292301F166BD52CF5A
-:10C5D00074F33BFC32F4A31A7A06E17B5398C7C884
-:10C5E000E5AE8FE4CD5F9520CDFB07CC7D1F965245
-:10C5F000BED5B2E6EBE642BDB605E4560C96517EDA
-:10C60000154AD6AA8327331EC1BA015682F8BD1235
-:10C61000EB72DF9343ED5457FBD6D7C21A86C65D43
-:10C620005CBE3F98EC10F2B167246FE7FC6D998017
-:10C63000D73229B77CDAF975E01F4319FB8B1960F3
-:10C6400052807464F51A063296980C7489F3CC63A0
-:10C6500079D83FD0D5F064E87F701CD0A1124E7716
-:10C66000FC7DD9DE87EE74EB67F5B0B96301DEF6C9
-:10C6700022B30758EE1DE1EBBD0478483D6221BEB0
-:10C680000BE37DE174525933A0E35D373617059211
-:10C6900050FECB7DAA33334F33EA2DCD0934AE7C27
-:10C6A000EE4E360878013E5E029CFADF8734D28770
-:10C6B000E43E5CAA3E347E109FBF84DF75C9820FC2
-:10C6C00086E07DA3069E0CE099AB81F78D91E02D6D
-:10C6D000E171BA38F014EE936A3F3818E13C2FB19B
-:10C6E000E2966400C188C3C1A38A01E55DE7538F68
-:10C6F000A2FC6A555D48C3B513397FAB7D492592CD
-:10C70000EF6AB3F814F87E59EBEBA4977536020381
-:10C7100035F50F9FDE75EAE0DC170E7CFFE43AAAE0
-:10C720007478B6E0EDB3F6F94E5ADF8AE4840BAEC6
-:10C730005FDB2ED67FEA476C61450EAE2F67603017
-:10C7400027346E26EE37BCFFD3988A7A845BD13BC0
-:10C75000C363102E53D4B6BD57211CD6282E0B8C84
-:10C760003BC9C2BC51B0BF431BCAD927B04725C182
-:10C770007A9703E09138DCE652011E193F542B7C76
-:10C78000D0EF3FD7AC8EBB03CA938D30743A3C5781
-:10C790000C1584676CD7473F81FE32ECF35C1BA11C
-:10C7A00036DF02F38171927F14ED4F05FEF067339F
-:10C7B000B3229D9952EA0F4C857E7B625517EABFE2
-:10C7C000F12A9B8C7825E11C1FCDD7219F973EBE77
-:10C7D0005D09DA42CF2735F514AE82F2E66427AD63
-:10C7E0004BAE7352794F21EA3B12CEF1A9FC7D6624
-:10C7F000EC499A114617D9021E1DA8CF013C6B13B4
-:10C80000CCEB51FE7559799DB93349EF5D63E57401
-:10C81000D11195E443B9D8016B0D507F7E3BB385B0
-:10C82000F1C328F7C06B60DDEC6D95ED80E29CC331
-:10C830003D3096E0E1E0FD083DAB8BB11B104E6B47
-:10C84000A6960D898332A189C3478F273B93159AFA
-:10C850005FF597407085A1E7D546BFD961C3E7660C
-:10C86000CDF3230037AF25545F7C3CED3A46FCC541
-:10C87000B51EDFBF634334F386E9552D621EFDC14B
-:10C88000A536D6C88C008F5A85555CE8BD97FF5BEE
-:10C8900025F8EAE7FFAEE02F09E591D7F76632B752
-:10C8A00067CAEF9FF61BD43B6B03266681476B5E1E
-:10C8B0002A1DC222F4D70BE72FC733DFA0B0BA314D
-:10C8C00048F0A8FDF25A7A5E7E7FA719F11EFB712F
-:10C8D000C2F33551EE21AE0BC0395BC0B9F6CB586F
-:10C8E000E61D14FE9CE355A8FF786AFF1D0210F0B8
-:10C8F000D6DBAAFA76C0A7BFDB67B8615B84F97E96
-:10C900002DD63F2AC148F492ED67EEAD11C697EFE0
-:10C910000D8E033E6DE370AECCED3BBF96B2E002F0
-:10C920009CFF3593993BD278A7C57B72DE2D71C1F0
-:10C930002A81F7232BED617587761FA3C5F82D3764
-:10C940000693B0FFAEA96C4E7384FEE57E8F31D6A0
-:10C950002B088FD2444F06F291EA5BA10278326431
-:10C960009EDFE0C909D15D7FFB1E8237D85D851748
-:10C9700082B799DA657F270E08BA646E9B02F4B419
-:10C9800048C8AB45DB574E03DED96BBF9CD802F6D7
-:10C990000B0C7182D5BF6EC7FA2685EC93C51EC6F7
-:10C9A0001A80EF54ED285C8F626B512263D7C6F179
-:10C9B000E7F760B9CE1492B3F47F370B978B72FC14
-:10C9C0003B1FD4EAADCBD8839FA3DE73E200E70F11
-:10C9D000A09E92FD5DF5B0B6BF65DB6F3A86F35C55
-:10C9E000A6D37F3250C103FD233545D81363D81831
-:10C9F0009403AB769C35C738FBA7839340EF69E976
-:10CA0000C82F1D548E49718F4A81FDE87E9BCF73DC
-:10CA10004A8A272F05FD0D6FF3799DA93EC3E5C412
-:10CA200063F1249F2CC8CCE14FCB5CABAF09E6711E
-:10CA30003FB09328808FC5C2F520A9FFA9EA6A35C7
-:10CA400006DAC77EB6260EF737FED9EB6FC0FE12A8
-:10CA50009E8D76E37A3696BAF3D15FB0B1D2E66AAC
-:10CA6000822EADF03DCA0FDFEFC6BE76156A07CD48
-:10CA70009BCB8621DAB5BDEA477FCA06C3E77B8731
-:10CA8000C1FB1BAE65AE26161AA7AEADF2799C4F60
-:10CA9000D22C2E673626BBF31D61FD32A1CFD50AFD
-:10CAA000D875B767FC7C3CECEFA3FB489D86F5A5E9
-:10CAB0000C44BE318AF17D66E7014E80273876B896
-:10CAC000DEDA09F28A6584EAA39A15BF09D653D340
-:10CAD000F2BC01E561F5BDFEC173512E3D63746D7D
-:10CAE0000B9B5FFC9F8796396342F268AEE2207D24
-:10CAF00041EAE5B731F99343783347E0CD6D421F02
-:10CB00009F1BCDE1BB98B992F0BBDBAD2CC60024D6
-:10CB100035B7BCB998E4D54A532CEA3FB89648FBE0
-:10CB20002DCBFEFC4AB54FD9BD0AEC7B97D2331210
-:10CB30003B3989BE1EEE5FF26D4BEEDBCFDD298205
-:10CB40000E470AFD308DB9EDB0EEDA5732B66E847D
-:10CB500026CB00D8C702E24BD69202D28FAD68F73F
-:10CB60002C7F39CAAFC484E0C21CEE7C03FA09668C
-:10CB70000C2FD8883AE961E02F40605DA66012D1A1
-:10CB800031F01D0564DFC329932B8D80E7B55781F4
-:10CB9000FE05F5D7B655F27A4AB0CA00F593292BAF
-:10CBA0002B8D8097B5A38247B17E2EE547BC5E10E2
-:10CBB000AC52A13E30751D7F1F0D4140ACE1A9FF75
-:10CBC000B3D20BFD9F8C15F2DD155C80F853FBA7EB
-:10CBD0000CC3C6B0F55A5339DF3A19C5DF3B99CCBF
-:10CBE00016CE4078670647E23C7BF12245EAC39BBC
-:10CBF000A894EB94DFB1C4C8FD3F99C2FB5F5E2EE1
-:10CC0000F49268B601E106DBE48D01F8EF69CBD858
-:10CC100086EF6F488913F0827E8A42FD4838CAFE4B
-:10CC2000E4B82B50EE223F36013F0EE3A3CD295C42
-:10CC30006EC238EB689C1C0EFFDA19C3F371DF601B
-:10CC4000BF8C62BF8CDC4EDDCAE707FDC6E611FF74
-:10CC50002F34C2FB7BCEC3FBC9A179EBF1A35DE00E
-:10CC6000C7F2266084A4A7A5121E4D8AE6FA212BDE
-:10CC7000D2AE63602A879F353596AFB3773F86285B
-:10CC8000344E9380E370807BEEE5AFFB2D319F6FD8
-:10CC90007BDD61FBE556B1BD356B5BF87A18DBAC2B
-:10CCA000E9E7E45ADD77254080388FB854FAEEFE84
-:10CCB0002866A5E76C5BEF77C9795C2F457DB546A3
-:10CCC000E8D5CC7B2D3915AA05D7A8D910303BB1B2
-:10CCD000BD5971FB103FD3607D08DF19D38AC4FAB8
-:10CCE0001C627D0EBE3E9F064FD9C19EA459F6BE62
-:10CCF000F8DB0BF7DEFE720A447F1ABA8ED41FD21D
-:10CD0000477FFBA1A47ECBFB21E7A983672F9C75FE
-:10CD1000F393F0447AA6EF72B4F828E779AE3FBAFD
-:10CD20004EBEC2F14AF977353F867D44FDC4A9C5A0
-:10CD3000E79A9664C3E29CD077ADB897C521FF5CB3
-:10CD40005AAAB07387B3E1C8BFBD65DC8FEADD6561
-:10CD5000713539C9AF97995A1CD1AF47CFF5F65EF7
-:10CD600077AC9929A41769FD0CDD09AE801BF5D4B9
-:10CD7000D3CCB503FA1DAFD33BBA613F77D942DFBD
-:10CD800085E489B6FE43C13FFBFA8D7A92707E45F9
-:10CD900096B2179C2EC6CA52B712BF2E1A58B63A70
-:10CDA00019EAD7A73E49FCBA6858D95974CD4C4DF9
-:10CDB000DDCEEBD9656753B0FEE476FEFE24F70BBB
-:10CDC000C8DF99777BE5E4A121FDE1C654278DAB4F
-:10CDD000961B18E29145BDCB857252C2B3BFB2C853
-:10CDE00062A88FA4BFCEECA5677E9E5122E4738912
-:10CDF000B4E783468D3DDF1D63F5AA00D76E94A787
-:10CE0000B0DE05A99E3908FFBAE8CE05A80ADF1BE7
-:10CE1000FD9119F521C50DFA06FA459C0E360FE66F
-:10CE2000A9746EAC203D7085CB6A24780A3F15AC9E
-:10CE3000ED1BE8E7E5579EB97B181FA602E73156C0
-:10CE4000D07FDD2B5F7DF121CAD1933617AA816394
-:10CE5000DB1E598DFAD5D8B6BF7FC5E5AD8DCEA9FD
-:10CE6000E4BCC7A2BF119E97B45A68FE63DBB296BA
-:10CE7000E0FBE3DF694B45FC98D8E16F4276D0DDFB
-:10CE8000FEC7619EF0732B764CF926FBF2F58B5EA4
-:10CE9000787C6666A85F023C7EC2E171BE0AFD8AAC
-:10CEA0005D0907D607494F1BCEFD98E27BD0CB33F7
-:10CEB00091CECFB0012E3C57E8B6F37EF4FECDC341
-:10CEC00095B03E783EB1076610A6374FFAD20A0CED
-:10CED00024542F65B19A7AB975A8E6FD298E644D60
-:10CEE000FBF589599AF6A9CE7C4DFDA6CCB19AF7EF
-:10CEF0006F76956AEAB7944CD5BC5FE9AED4D4F3AB
-:10CF0000FDCD9AF70BF7B56ADB0F3A691F0A3B2A8A
-:10CF1000CA519F77053C4D585ED3B9A97CA093F5C3
-:10CF2000F1EB16057D4DF87CFCF9FA623FEBEBDF87
-:10CF3000652B3C741E60C17D51C3CE074A03448FEC
-:10CF40005D069733DC8F3B6FB067672AF97101ECA0
-:10CF500000EC6BAD3D8370BFA62C7C488DC17DE994
-:10CF600061E4FF6A31077F361EE5FC7C95F4DE162E
-:10CF70002323FDB1654EAE0F7D7F8795E08B1F2289
-:10CF80009F9A1F4DFC642268B8B46E3C0355709F95
-:10CF90003C9A7597B2E5BA7DBA4B539FE2F8B1E679
-:10CFA000FDEB13D76ADAA73A1FD0EDD3664DFD66C5
-:10CFB000D723BA7DDAAADBA76734ED133F0D3621FC
-:10CFC000194DEAF4AA7698FFB8C39BCA715FC67779
-:10CFD00078E723BD14F93D4DC442F6D4BF8EA51F9A
-:10CFE000EC2AF46BBDD69848E59E4627F9A5F6369F
-:10CFF0006652B9AFD145CFFFD65842E51B8D6E2A98
-:10D00000FFD178039581C60A2A9B1B9BE9FD5D8DA4
-:10D01000AD54020447A0BC881F24E40FD4D1DEEF36
-:10D0200032046BF1C4F5B327CF115FEC1A10ECC2D8
-:10D03000FABDEC2CF1C5401A233AB4A633E2635D85
-:10D0400069EE6569509E4BE5F56E936D03CA816686
-:10D05000833B1FF5EBAF9E3CBFD93882B1FBD65660
-:10D06000243A6279DD0A75DA6C34CCBCE737BB87C9
-:10D0700033F67B1419E3A85E89F5EE28DE7EEEC94F
-:10D08000F3955E9A1F3F6F9E153A6FFE2A35C2795F
-:10D09000F3EF8F3BEDE86F39703EC38EEB3A20FC27
-:10D0A0004B6E966F5A0465A931DF8472F1B04E8FD2
-:10D0B00090E5BF6CA5065C4FB3C1351BF514EF8D31
-:10D0C00026B603F8C50C85DBA3BD7A601A9747DD49
-:10D0D000375BC8DE3968702F413C073EFD04C2EB68
-:10D0E000AA34FB0C845FB7BD2709E1909866E3F58D
-:10D0F000849E27145758DDC4D7199B163DA39F75EE
-:10D100000E4E8BB0CE61690E1A9FF9DD2350FECA18
-:10D11000FAC14A770DCA8983A5EE749CCF810A0BA8
-:10D12000D18FB7C2EE4B4726677417CF0EF3BBFC07
-:10D130002ACD44FB36CBCCE98CDDAEFA7644B0D3B5
-:10D140005E48E3FA3EED1BDA73B745931E7ED0C00E
-:10D1500096ED8A00C7BFA77139776A4064FFCB1B81
-:10D16000027E6533EDD45FF79A283AEFEDAEC82022
-:10D170003DA8BB1EA004F4D17DBCFEF46E6AB7C806
-:10D18000A3303AD79C2BF8D4EFDB56FFFB10BCFF43
-:10D19000D19A6817F170C728924FB78B97E70FB2F3
-:10D1A00092DE327FC68832944B73C5F9D802BB71C8
-:10D1B000301D931963CD0EE8E74E5BFE7A14FF55E0
-:10D1C000F195E658A82F1B7ED77A2C57A46D36C749
-:10D1D00041599DF3FC7A541F6B80B48AC95E0ABE24
-:10D1E000D908F35AD8A03AB9FD24E49A7BE565C57D
-:10D1F00063483C4438229E027CC92E7C53C05B7E2F
-:10D20000F7A680E7DC34A1B7E5B2DC6FB4E73E0BEC
-:10D21000114F3AE7BF39B21F3FBDB65DE86DEF9AD7
-:10D22000F9B82B9F36F9C2FD4972DC7F88791C342E
-:10D2300033B7827ADCED76C28FBC3967EF2D86F585
-:10D24000E7B5390C746E2FF9788091FFBEF8530F53
-:10D25000F1B96B3A834F1D6284E7AD4827179353AA
-:10D2600033BD6B493E8C3D07F207F9E279CF478722
-:10D27000880F2E137CB09EF8D79EC606AAEF6DF4D9
-:10D2800052B9AF7183E0839BA8FD8DC62D820FFA42
-:10D29000041F7C9A9EB735CEA1F295468FE083FCA1
-:10D2A0005C7586C0A779899E7548FFF2FC7296D599
-:10D2B000634278FDE5110B53F17CA2CD42780A144C
-:10D2C000F0C4A3F1182F63716C74F68D9BD1F3DB5E
-:10D2D000DEFDD79DF3AE49746FC27DE98D9341FDAC
-:10D2E000ECEAFEF1E70073DA919F3CBDBD82F8C71E
-:10D2F00001A7D38E7AEB3369953350AF3DE076DAF0
-:10D300004D50FFDDF64ADEEE71DA2D507F366D06A8
-:10D31000AF7B9DF628A83FB75DD47D8C0EB59FDF0F
-:10D320007EEB0CF4639432650FD243B9357932B099
-:10D330006B908FA57B900EAE4F5C3419E9C099E6D7
-:10D34000247C98EA5CBB07EB37656E350E72A2371A
-:10D35000347F1D7E57165F69C4EF260FBF6B1D7E9D
-:10D36000775DDA6663F87737E43CBF0EEBD35C5B3E
-:10D370008DA80F3AD3F879A9EC47D665BBE4AF681E
-:10D3800027209E8E6EAB203E9ED75A417C5CC2A564
-:10D390006C56E57DE8A7AB6B551C0ACE6396D27B35
-:10D3A00058AF800E517B1EA805F8AC7FFBE2B8B5E4
-:10D3B000188782F57154FFC5DAC87CF72F88077A81
-:10D3C000BEFB9EA053949B95D0CF7B403FBBA09EBD
-:10D3D0002ED657D7B6C8BE88EC198F1DE56B761AC6
-:10D3E000978BA385DC5C28EA778AFABF6CEEB7706E
-:10D3F0009C77FBA7EB0FB01DE8B68ACFA30F5D6B40
-:10D40000DB055D770838B2A29E24ACD7B04DE42787
-:10D41000BC587CD7F270FB2D19E3249A29FE421FD9
-:10D420002751CD02BCBF665D9C050B9AE93CB63521
-:10D43000EC39F123617F0CE07C6F0E326BC0BF7F53
-:10D44000A78973C7BEEBFE4AF0ABFED6AD6D17EBF6
-:10D450005ECE7C14D7A65F07F324106DADB41DA477
-:10D46000FDECBB9E60E4F5F45907B7DF651C8BF457
-:10D47000CB831E14955E8C7CD0CED07F13CE270E2E
-:10D480005D804FE8F9D1B7C5E72EC06F92709E7AE4
-:10D490007E23E3B3F4A5D4E7A0EEC5F83CEF2B510F
-:10D4A000E4A7FFC4E9C9C27EBACB7ABE30A07D161C
-:10D4B0001F243C6B002B0F9F2B667E4E0F5F8CC48E
-:10D4C0007D3B6EF0FE01F5A2921D8F119FEA42E1B5
-:10D4D00000F4E8823AF29D2D575514E0772C93E33F
-:10D4E0004FB7C2E5A2A47BD007A91C9BCEE551DFB4
-:10D4F0009269E21ABBB77E95447EAC8BE07B7F706D
-:10D5000098A24E087A91DF974493CAD3A930BF02FC
-:10D51000FA5F67E960D2233A47988D587EDB7662DE
-:10D52000E78891D4BFDE5EEC1C5A62E5E35E7703C8
-:10D5300096AD66CF964568278DB5909DF496880781
-:10D540009C1ECDE3A7DEC27362786FFA91F3F128D7
-:10D55000BFF4F666E7FE7965CEBCBE7627AC7332C3
-:10D56000AEB3FA63C37DF8EC72EDD0EA862F987102
-:10D5700010C8ED86F3CC587829762953915D141C98
-:10D5800076BD8E65F1A781B83C27DA9F527F10F6F1
-:10D59000E945E2904A7AB8BE30E93CCB3416A19F07
-:10D5A00069009DDF28257FE776AB28E5B9C8043EF2
-:10D5B00005B6C060F39953347148894628E7A9C17C
-:10D5C0003158EF62013A27D1DBB37F157E28B06B6B
-:10D5D00037A6935F8AC727C18E0C42FC9DF293F752
-:10D5E00017DC4D7C208AF4A15EBB76B781E20C5A31
-:10D5F0008CEE8113D1AE6D4877AD85FABF0209BFBD
-:10D600007A19CA3AC717043749BFD50D67099EBDB5
-:10D61000E703C2EFBBC904F207CAEAFF56490E5539
-:10D6200033B681F68DBD665E15261759F3E7BDF05A
-:10D630001F0D7CAF12014876D684996EF8AE52D891
-:10D640001FCCDBCEEBC2EE626CC44C37F453992096
-:10D65000DE679B79FB08D9FE0B5E4F97FD7D3E830D
-:10D66000EA43655DF49725EBFB793D598E7792F798
-:10D670009F2BEB165EB7F3F75F48FFC34CE40B92AA
-:10D68000DFBF942EE4443ECB177139EDE9C5178C0A
-:10D690004BD1B60BF9B0F019D56B1E8DFB3335FAB3
-:10D6A0004DA4EF668562E7AAEF3191BFFB545C732E
-:10D6B000DEEA307B45C6B15494DBDDA8FFD5BC98CB
-:10D6C000B14D15F13CA87F7CE1E47AF914D546E729
-:10D6D00013671EE47CBF3FFDADAAE165CD7EF66910
-:10D6E00057156E8FE3C11D8C77FAA1215BC9BE4827
-:10D6F0000BD0F9F98782DF0D06DE5A12178A178BD5
-:10D700004F656EB457E3FF08FC19F7F8D300F1E357
-:10D71000AA3F72FF6FCD23AF93DC5BAC3AC99F5B2E
-:10D7200096E3F918E1D3650F905FB1AAE1159AD796
-:10D73000992C61573A7A72C2E179A22FFC4F5F04AB
-:10D74000FEA7BF4FF8EBFDCE2B6C7B68BD2B2E33B5
-:10D75000AEADCBCECF455D629F8E189C6304BC2CD2
-:10D7600023012EA7970446C6AA18741C18CCE3966A
-:10D77000DE2846BBE84CBD9DE1BECF5BFDCF3C4FF4
-:10D7800004BFAFDE1EB80DC72C0EC12B61641FF89D
-:10D790000EC5F12E005F6DFB770CDF21C6A0D98589
-:10D7A000E7A88719F5332670C41C1E1F337624C7DB
-:10D7B000CB81ADFCDC481FF73576A49DEF93389FF5
-:10D7C000A999F1C6043C9F91F430299A35A3BF1D55
-:10D7D000F0DA25F0DA85782DF137744E03DF45A0B5
-:10D7E000AF10FE6AE1EAEE0BD7C9232F8CB7DAF649
-:10D7F000EF18AE2DA00FD3B9E6EE28F2A7E8E1BCF2
-:10D8000074243FDF92F06EB8089C1BBE2338378C1F
-:10D81000746AFC1112DEFDC927FDFEC87947A0D34A
-:10D82000E22BA1D3AF33847D630C529CA97EDF1B16
-:10D83000FBEE7BD345E8A9E9FBA4273DDCF465B505
-:10D8400038EFD43FDF3A92FBCDBE2B38FEFFE64FD8
-:10D850009F5FFFAAA67D61C37E4DFB22EFDB9AFA94
-:10D860008460A01CD15CFAC7AF3DDEF33AD6AFD4DA
-:10D87000CFDE9F7F7DFA0B4B0D78FE5612E0FEFD4A
-:10D88000C5999E2F90AFBC65F035D901AED77434E1
-:10D89000AB741EE6CBA773C0D5628E6727FCE7A3E7
-:10D8A000BB016FCE320BF93FFDAF66199DB97DF11B
-:10D8B000A0F44B95B9C3F4C4526BAC11F5A75260F8
-:10D8C0007991F0E66B8137140F04F43EC7CA4CF12E
-:10D8D00040E773E62814FF3487F1786A28FD1E6854
-:10D8E0009F6E647E0BD42B6D46BF85CEFD78BEC384
-:10D8F0006C3E4D663182C686F65DFC20B28367E1E0
-:10D900004398AFEA56299E6D76093F2FBCDDD66C51
-:10D9100042797ADBBE7B4FDF0DED6C9DB798C76B0C
-:10D92000CBFCB50F0C97730EF8F5484EE7DD8A383F
-:10D9300057564C2E8C73D57FF7D6484E67D3D5B546
-:10D940002AC6BFF4BCCD48EF967407EBDB6729E02D
-:10D95000F919E3709DCCE4CF8841FD797339BE5F3E
-:10D960007DD04970A92B599B87FB583759F9D8921C
-:10D9700017B26FEA1ACE919E3E457DAE09DF3F7326
-:10D9800098BBC6AFE9F4AA68AF84FC97C105489775
-:10D9900017B383E4BC3B1AFD844F1F35EEA3F2ADF1
-:10D9A0006BFF5E8C7A46B03110D17F79A5FE02E91B
-:10D9B00027907E03C907FE754FF910C4CB74C917B1
-:10D9C000ACCA30E40BCCC84BC92FB333FAF0D7D173
-:10D9D000191796ABDAF6EF98BF5E2A9E572772B9F1
-:10D9E000A8C76F3D5E4B7C86CF8A1518F776D0F7B7
-:10D9F00050AECE65DEDC6AE0B373966E328D57AE04
-:10DA00001CAF57D83E4D6211F2542E9F9F3B79BCFC
-:10DA100064B94AF6818C5790FBB03843F81943FB40
-:10DA200056957161B9A86DFFDEF5F84F175C995CEA
-:10DA3000639AFC86B57DF1F5BE8BE0EB7DDF27BEFA
-:10DA400086E5CF2C500DA17C118C27463DAEDBC75F
-:10DA5000F32197256F8AA1E0CC929E18D41B97B72B
-:10DA6000AB8487CCE8360E057C5D2AF0B593F9DFF0
-:10DA7000457C5C3A6129E5D12D7B2C725C71AD78D7
-:10DA80007F85ADC58CEB5CB15DFB5EAD882BAE7E5A
-:10DA90004EEB17AD9D70FD31ECB75617CFF36C868A
-:10DAA000881F2E60053CEE42AB9FEACBAE46A6F146
-:10DAB00057769D6F247FC00BBF3DF94BEF8430FB41
-:10DAC000BF2FDEB65F046FDBFF6FE2AD6ADF4E791A
-:10DAD00055978BB73F1AE53E80F396FC781EF226E9
-:10DAE0001877DECB169F17CF478B9DDCBFA9F89A1E
-:10DAF000F0BCADFB2B46FEA3C5C2CFD95F5EBA8C8E
-:10DB000037187BD0D7C4E30DDC2AE6898ED957516C
-:10DB10008EC715856FD4933ED2EFB995CCAF12F175
-:10DB20004397CAD7A45F6FCCF17AD2B35C0107E9FF
-:10DB300043E3BE6C7E1DE5E3B7E5EF96F270FC2093
-:10DB4000EEBF280A56909ED765F217BF877AC24B60
-:10DB50005111F5047326D78B667A179978BE619FA9
-:10DB6000F34073269E070AFE6FB0BA4D08A7296AD4
-:10DB7000E7AF6E45FC09A8E4DF5BF3D377FEF0A8BE
-:10DB8000F3E2767F9DE32CE90DFDE9FF75069E7FAC
-:10DB90005150EEA4383FB4A7D0BF27FD7DFAF78BD4
-:10DBA0004695256692FF6942C08DF3D9C2E7D3DF5F
-:10DBB000FED4357CAEF12FF6377E5D7BB1637118F4
-:10DBC0001DDC96A948BBC371D41ADADF4BC5838923
-:10DBD0003D7334FACFFFEB76C57415544B909FB963
-:10DBE0008A8FEBAF8CEBB1F35880CA05AC874A0F34
-:10DBF000E3F1F78B998BCA3B451EF3DE2CCFCD9911
-:10DC0000781E61EA194CF1932F7E9D837873FADABE
-:10DC1000F19B30D6EEBBD2E3BAF39D347EF7EEAF84
-:10DC200093300EE6627C614DA2DB9319E1FCF91F93
-:10DC3000A52A9DB7B0C38F929CA814B730B0C9FC79
-:10DC40001CED0B6732E143882F0ED92AF9229ECFB3
-:10DC5000E67E6CE0F124CB155F3ABCDA1A34106929
-:10DC6000E52E49F6A9586FE1EDB935B13E05EAB99F
-:10DC700063A378FB5DB13EF4A3CF6741A2C78540A3
-:10DC8000A2582E629CEFDDC1DC3CDF81F5A4A01E12
-:10DC9000B6A4CDCAE3FD59300DF97B5E3FF64F5B6C
-:10DCA00026E7D3A353383F1F5DA6F553DC2BF8C0FE
-:10DCB000275965FF447A3A96E96EC272745C60E354
-:10DCC0002F8BC86FCFD07E3836F6C774DE28BF1BC7
-:10DCD00030AA6C03C26FA7C2E3D3BDED168A8F8052
-:10DCE0002F065784C5F5EFCD2AFF19F6F72BE1F77C
-:10DCF000EB0FAEF09D266F36444F5E9ADF68B4B9E5
-:10DD0000C8FF0E0F4A685CAA3FF5F4B459EB72C81D
-:10DD1000C7EF45BD77C028CFFFC2798D363366C3C4
-:10DD2000F93F6EF16D23FDB43E09FD954B9FB01890
-:10DD3000506F781FC42DE6A17CD868A5F29F6007BC
-:10DD400063F92FB083B1FC18EC602C3F013B18CB7A
-:10DD5000255FE683B060AC2CCBDD9A591C3A9FD38B
-:10DD6000CFF77901CFDEF1DBCD34FE27591E826F6C
-:10DD7000EF7EBFC47C78A8B333B6E7AAB80BE05BEC
-:10DD8000FF7C86C3459E17EADB7F2BF63DAFC54877
-:10DD9000F23DAF35185315F6DEDE4C33B5E7EEFE37
-:10DDA00094F250BB1CBDF0752BB0E4E9065EDFFBBE
-:10DDB000F46282EF2759EE7F225C81BEFF86655EAA
-:10DDC000EB3BBFC0FC1FE89FE20EBA959E5F931D20
-:10DDD000A05B871E0E725D3B63031BF1FB9DBB5373
-:10DDE0007025C06F18A71BC42325D27AD7D27C6FA9
-:10DDF000B1F414615ECB2DDFA811E38C3FC92A2555
-:10DE000038FF18F12D210C4E62BFAE94AE7BCFBF10
-:10DE1000059E32797F07F24E27CAA1F331A8EF554C
-:10DE20008AF3FDD696B4B7707DDE7D2A4B7712FE5D
-:10DE30006AE8CE91C5F14496B9EDE60ADCA79DEDFE
-:10DE400047D3EEB4D1BEA42DC171B3D235FEC7DC29
-:10DE5000B15FFDD72FE3E97D070E751BDB3A05E3C4
-:10DE60004FE65A5FFD0B2E69BEE3E329187FB230FF
-:10DE700051D98BE52267F275187722E3E3EFC82CBE
-:10DE8000DD8BA434CD55497A5A2932973079506EBA
-:10DE90008DC643C1DEFA14C7204DFDFAC4619AF75E
-:10DEA000A73A5335ED3765666BDAE5B8D35C859AEA
-:10DEB000F746C7F5A4A07D06EB207A603B548AD3D1
-:10DEC000CBDD7DF0C66CA84F7F6AB60BD5929DA2C4
-:10DED0007DFAAE721FEE4737C0D30C0AD4F1920719
-:10DEE0007EFD4BEC4CA7FF57B73FB9D7EDBC0CFDFF
-:10DEF000BF1FBD5FF2D9956DD662E4B3976A07E89C
-:10DF0000F7272F4B6B17F48737BD74A13839DEEC38
-:10DF100057D98E08788311A91C0F7939FD00CF1FBE
-:10DF2000BB5C7EF619F2B34121FAE82D757EB9D1BA
-:10DF300066D75BABD14FFFA6CA281F4FE4F555E16A
-:10DF4000DF6A08DFD99D5BEF1B1A4FCFBDA8E762E0
-:10DF50007EA91BFAAFCA12FEEFEA57EF1B5A146AEA
-:10DF6000676B3ED6BCCFEE51D66BEAEB92B5F507A8
-:10DF70004BD7877FDF1F5FACDAB2C8ECA1FC4FC57F
-:10DF8000ED8BC01FE47CA6BC1645717D3763BC0ACF
-:10DF90003CAA2D7ADB88E7B437F7234725FFB94D34
-:10DFA00065F591DAEF12FD4E7B2D8AE2602EB7DF28
-:10DFB000F701961467F8472E47DF1F183086EFFBEE
-:10DFC0003D595C0F3D5DBCF9A75FE0F9E84B8CE281
-:10DFD0003E4FC772FE9FD772CC608072F4008E2FC6
-:10DFE000798EA001E54AF7B2682FC6F5D72DB75351
-:10DFF0003CE8E8949E77ADB0F5EB9ED9FBB015F602
-:10E00000ED034C820C93ABDD681441FDA1ACBDB3B4
-:10E01000D6C1DF37BD16E5375CC17A1EC2730994DD
-:10E0200083659CCE1720DE08F9823EF6BAFB58AF16
-:10E03000BC41BE80EBC7FA9E67F61F7C18F5F0FD69
-:10E040009CCE31C24E6FDFCF0DB3EFD9639C2EADA6
-:10E05000F0CBE39474F4BD6793D976413A6FA6B8D8
-:10E060009B4BA5EFA7919EB32F48CF076E82FDA9CA
-:10E070007B89DF6B71A62D9DF262FB93E7755B5484
-:10E08000A24359EF6A536F40BCD5E7A14BB832B7F2
-:10E090008BE853DE1BB56AE27F66A0DC5CD56EE4DC
-:10E0A0004122FD8DB34165CEB07176BE625946798D
-:10E0B0006E62FEDD525EB7FF3BAE3487976B23C8BE
-:10E0C0003D90D3A67894D3950AD99587DA87942181
-:10E0D0009C0E29CCEFA4BC2D1EA73C937787CF6D57
-:10E0E000745F496226C5274BFB52DA95B3DB67A7FD
-:10E0F000A35EF96ECBE243B073ECC3AC541AEF5697
-:10E10000E6253DF8506CC508F44B4C17F1018762C9
-:10E110007B3A912F1F9A18ADE0793FF4BF0EFB9721
-:10E12000EB3A64AA18C1EF9F9071C9A3AEE89EB8FC
-:10E1300029EA3DA537E1F9F63CE640BBF21695EB3E
-:10E14000B9ECCF9C3E25DFAB53027138CFBD5933BC
-:10E150004E67C177431A7E26FCAA026E461E877858
-:10E16000A97A6EAF3DFBB4C2EF457171FDBF76C2B7
-:10E17000A95FDD8A797260772B309FC5ADAFD2BDC4
-:10E180003F7A3BBBD7DEF93FF4A7F6B5972A2CA31D
-:10E19000C2FCE47ABBA9574F97FADE0E1E27FFFA9E
-:10E1A000C4DF74AD84FA9A1DD104C7134F58BCC89C
-:10E1B000C74F6CB390FD7322AEA76335D677E5BA2F
-:10E1C000BC349A4B732FDA5283F33D943FEC6F26A5
-:10E1D000BAD7E3D8E3163FC67B2C7F326B1BDA53EA
-:10E1E000C746389F7D0EFD81CF26D03D03CCC3BFEF
-:10E1F000BF59D023D29713540FF5B776D22396BFC9
-:10E200003094F898DCBFE38F47511EFD897D3307BA
-:10E21000A2BFACD3F03CE5F130D5E6457EBC725BE5
-:10E2200014E9810D0E4FD628585FF96F6FBEB510F7
-:10E23000C77F2781E17ABADB5E207F65687F23CBC9
-:10E24000F7336DA99C0FF4CA5B1E77BB10E36E53C6
-:10E2500029EE7634C2B786C97B1779DC6D81AAB8FE
-:10E2600029EFE0A1C879E4EE515C7FAC96FE9341C2
-:10E27000CC9A8874E861B4DEEE8732B6A1BD33670C
-:10E28000545CEFFD4C3C5F52E25B47EDCBE43FB1A9
-:10E29000F078BFA8C8E7D8D346F1BCE22AEB398DA5
-:10E2A000FFA6B6E12B8D5FA5368791DC2D6872162F
-:10E2B000DE05E56A01E7E52915B7E0FA56346F7E19
-:10E2C000F10D82CB633FFA00C7DD6723BF0D7B836F
-:10E2D000C34F6FCF54593F17F4B45573CFCCD147C8
-:10E2E000DEA37893A3BBB3F370DF16AB81A3781FD3
-:10E2F00057973DF0D1DD50EEDA7780F6453FDF3EAF
-:10E30000E7F60AE72BD5B88E4118EF52B16414D165
-:10E310002DA7F7231B73097ED29FDB7D22B2BD257B
-:10E32000E729FB97F393FDCBF7568BFD3A6D0EE48F
-:10E33000A17C4ECC746AD6753A2690176BC3E7DC85
-:10E340009F773A0EEA6178F35D9DEFDC2EFC3C8707
-:10E350000D6B7F6806FCEB6CFEA5C913CE472FF34F
-:10E360005C47CE57C695CA3CDA874789F388116C5B
-:10E37000443FF9B75B90CEAAFBE6DFD2F3FEF26F23
-:10E380007BF36DFFCDF36D657E6D51B9A13E3CCF42
-:10E3900056F2C3A26C789E83E7FE5AF95E345AFBAC
-:10E3A0007E7FFCB1209BDBD7458322E7BBEE1FC5F8
-:10E3B000DB9B989FDF3F28E4E278017779EF97D4E1
-:10E3C000536A05DF96799EE3DB78DCE67891B70344
-:10E3D0005C80F25CFBDCEF96984D7255DECFA74077
-:10E3E0005FF3E222E50B07681ED7B21E2ADDCC617F
-:10E3F000C412C04FE5645641E575AC9ECA1BD826D1
-:10E400002A6F64CD544E63012AD928BF88F7BC8790
-:10E41000E7994E5D6A40F95A746B64BDF8D445E1E2
-:10E42000E0A5FB032F170ED7317ECF5F1F780CCFEF
-:10E4300024FCD6C3439FAF399105E9E2924988B8DD
-:10E44000A968073B29BEB59CB9A93EE512E1501267
-:10E45000F418797EAF0E1EE591F1E29CA0FF9FA219
-:10E46000EC2C0EED5356B693DFDF20F60B0CB144C7
-:10E47000E4FFFA7D94CF8BA2CBCE3A8145389E6DD6
-:10E480009C4D79DC8565AB53A19E92BD6936E579DB
-:10E490008F2F7B01F3BCD39EDDCCEBA3CB0A4D2E9B
-:10E4A000D022D7FE6236E6337A44DCB447C44B331D
-:10E4B0004FBEE69E2CCFDA1FD2BD639E113617AE3B
-:10E4C00053E685ABA9FC7C35E906FF6B2678AFDD0A
-:10E4D000E189CE46B965F5C738514F583B85EE8F77
-:10E4E000BADFCCDF97F7D9C8F5C97B6E76EDCA5E87
-:10E4F000ADA45C7C1ED0FF50ECDFB3369DF2E33C54
-:10E50000BB15910F5736640EF08DCE8089617E81E8
-:10E510001CCF94E249C2F71926C5035D0C1372B8EB
-:10E5200073577636EE5356B638DF8F4F2E4438DEAB
-:10E530009A529185EFCBBCE82CDC9784FECBCA6C59
-:10E540007706BEAF7F2EF3B2C7657B72B1BD2EFAE0
-:10E550003CE59B75E5BFB33E98DC374FBDC9CD7C2C
-:10E5600066E22BDAFCF4EE2566BACFA9A8C2D38402
-:10E5700021CAD7CCEB1983FA31F45B929D80F7095D
-:10E580000693F2E1BB8767F2FC777DBE77FB2BFB3E
-:10E5900035F9ED92CE7AF3DBCFF0FCF6107D3DB28B
-:10E5A0009A85E5B74BBA9174370EF3DB63B09EB52D
-:10E5B00004DF9BF84E07E5B74FEA088AFCF6F7B48C
-:10E5C000F9EDEEFF5C517EFB3171EFDB312BBF2F9C
-:10E5D00049DE27B56A373FFF5DA5F0FBA456FD9ED7
-:10E5E000DF2725EDC265627D35FB77ACC773BE655D
-:10E5F0008FDD41F75131710FAA137EC3ED42792FA0
-:10E60000A93E0FA60EED41D29BFDA477E9F361EA86
-:10E610001E2B277BB04EA747AFC816F6A090674CBD
-:10E62000E87F4BC5B7B80E1BD96766D23B573DBED6
-:10E63000DAE5C0BAA02BF6D87374EE26DF678F0D2B
-:10E64000225C9074B67C8342FAAB84DFE8A72C6E20
-:10E65000BAC7F8A921A4B782BE2DF2987DDCCF0FEE
-:10E66000B882F1F03B637B52504FDED99EE9020E37
-:10E67000CBFED4EFFDD3CFE9EE9F7E5273FFF419AA
-:10E68000FC1FEA69C70D3EEC670CCBFCF904A81728
-:10E690001F37BA7CCED07DCC17BB7758C2DF22F6AD
-:10E6A000EB72EF21D6DFF72CF31FF4F711DF2FEE1B
-:10E6B000239ED8CF7DC416B54D25FDE19C51732F07
-:10E6C000F135629D254EE6C37B7EC7751A35FB5F2B
-:10E6D00012DCC4501F8A3A68D4F8112C4E6DFD39F3
-:10E6E000890FE27E91BEF0B6F5C2D342F04CFB0D2D
-:10E6F000C15377CFB38453EF3DCFC36D84F7E3F6B7
-:10E70000BFA0223FB8DCFBBEBFEFFBBD2F769FB79B
-:10E71000FE9E6EFDBDDCFDDDF32DF73DDFBF4AF350
-:10E72000BE7EDF0BF7FD447B0FB5D86F2FFC7E9BC1
-:10E73000FB7D325BF877C57EF7E00568C0CFFE1140
-:10E7400073FC4124CBE9D1E23E3869D74F30919D2B
-:10E75000F5967350B91DE95FC8A90A21A75845333A
-:10E76000AF0B7C7105781C41C1617E7F455190C71C
-:10E77000138C391E393FE896124573BEDBF7DE6213
-:10E780009E673CFE3C8FD3D39FFBCBBCA14A7794C2
-:10E79000F6FE867EF288A41F07F47866463DDEC04A
-:10E7A000EFB38B70CFF11635353C8FC843FE9D59C2
-:10E7B000D64012E27354B2273E2721946F3409F3F6
-:10E7C0008A14B20785501AF8038CF3ECC624DBAB2D
-:10E7D000307FD4F603CC9381E93B8263B8B98B3F99
-:10E7E000C9399E1139C0078F288EF585F0ED3FC6D7
-:10E7F0009D4A42F964C173ED023AF7BD3A27FCDC49
-:10E8000057DCCF1F343849BFF0FE4421FBE11476BA
-:10E8100036368C5E3798445EA3EEDF2F10F694FCFC
-:10E82000F70B8E4017CB806FCF6FE579D42B133B5E
-:10E83000851DC6EF71BD63B88DEE7F62EE4217B7DE
-:10E84000C3A57D354CBD1CB979B1F8A29589273493
-:10E85000762E7B6ED0259D2786D6CDFB3FF24034A9
-:10E86000C99B230F8C203F5FA8FF2EB2FBE7D76B1D
-:10E87000E38C1736BCAFC1BF45DE8F35EDC1F81E46
-:10E88000D330587FF0C5A1D7CD05F89DDE6D198333
-:10E890007406FB362B27CC0E0E3E943199EB0117F4
-:10E8A0005BE7299A4787881395EBFCA8F130D5835D
-:10E8B0008D415D3C8F576397CAD2FC1AA37B727A55
-:10E8C0009401AE487E9693395C6FEF1079901D22CB
-:10E8D0000FB243E42D76883CC50E91A728F3473B41
-:10E8E00014E6C6788A798AFB8945C9943F7A17AEBF
-:10E8F000B36E454F1EE6DBD58D0E2E5054CA1F5DFC
-:10E9000083CF23E48FE661DEFB1F726EFD01EAF91F
-:10E91000C70778E95E92A79E9BC1EB664E1F2FE664
-:10E920004CFC01CF27F5FC0FECE75345F5D3FD1761
-:10E930002F29749ECADC41F38C0BE497DE97C3CF7A
-:10E9400017D6EB4AF2452760FF4CE47B3D3892F244
-:10E950007EB65828EF07C6A1FC2B79FEAFCFCF2A91
-:10E96000F8B3C58F7C43FA611EC94996F702937FBD
-:10E9700025FEE7169EB7150C24619E17C6FBE0BD69
-:10E9800019EC2073F33C307E7F9FDC87477244DCB8
-:10E99000195EA45F14CA13ABD97FE423E42365395D
-:10E9A0009EC771FD327FA926E6558A9BD899E3A4BC
-:10E9B000EF60BEB45EE007EB1482731F3FDC0EFC19
-:10E9C0005E9FFFDEDFFA4F2F09FC3A2739943F158F
-:10E9D0009637B53327CC5F26E711EAE7C2782DFDDD
-:10E9E00049217FD7FD23914E0AD00F1EC1CEDE2BC9
-:10E9F000E0D2618AECBFFB384789983F5790C11835
-:10EA0000FA0BE57D93EF209CD0EF749B8BFB4119B3
-:10EA1000BFB7AE6686CD857C4BF68FF7E53E7F812E
-:10EA20007196A754BC89EB5F51CFFD7DB2BD5BE110
-:10EA3000FBEA7D88E34BCD2BEF7F74378CB2FCB7BC
-:10EA4000B985C8A7E5F77A3877D979FEDE62D54F60
-:10EA50007004F87E80FBA4F7F35D295C2F377F1AE2
-:10EA6000E045F730F6F583032285E96F16F9FD706E
-:10EA7000EDFD6616FC771860BC1661F7B408BBA7FD
-:10EA8000D524FE9D1C9D1DDC12E071442D89668AF3
-:10EA90001362E2DF7590727FCDDB3CAE684D32A32E
-:10EAA000769C1FEEAF12DC4B72A8F79E2A05E42B72
-:10EAB000C0EF94C3A3E6A21FDAB39AE4927A35ECCE
-:10EAC0002FFA4DFF76A3B0E7B89C2B1672AD18FB5A
-:10EAD000C175E40C24795724C61D63AD277D7A2CBB
-:10EAE000F30AFF8EF0833CB097ECC0FF0D9F4D61A1
-:10EAF00077606800000000000000000000000000D7
-:10EB00001F8B080000000000000BFB51CFC0F0037A
-:10EB10008AF92C181856593130DCB0666070B4612F
-:10EB200060D86C8E90BB218E6053133F97A74CFF2B
-:10EB30003C4906860540BC0888974892AEFFB71648
-:10EB4000825DACCAC0F007C87701D25FD519186ED4
-:10EB500003D97F81B803C85F03C43B805804C8BF92
-:10EB600009A499D518189E00E97F40BE34907D44D1
-:10EB70000DBBF9FFB5F0DBBF5D0395FF128D7F4143
-:10EB80001DBFFE284DFCF2AF09C863C35EF6E4C7A3
-:10EB9000471F057A0702AF474BD7E2A60C0C7A66EF
-:10EBA0000C0C85D0B4BF0649BE192826610A617FC6
-:10EBB000D103E617207F258E7CF11528CF0F94EF27
-:10EBC00037C76FBF38335A7AE1C154F39609C1AEE3
-:10EBD000174295DB248CA9FEA708030300E92850FF
-:10EBE00078D80300000000000000000000000000D2
-:10EBF0001F8B080000000000000BE57D0F7454D54A
-:10EC0000B5F7B973EFDC9924772693106042024E72
-:10EC100012D458038C18302613B821098424E0003C
-:10EC20007E34565A07E421B640A3B5ADEDF395E125
-:10EC30008F315AACD0F2FAD4767DDF40D5D5F6B913
-:10EC4000DE0A8A4A43422790502488112DD66AFB57
-:10EC5000A276D9F81AED80C1C6EFA38FEFEC7DCE76
-:10EC6000C9CC3D994942F5AD7E7F64B537F7DE7377
-:10EC7000CFD9679FBDF7F9ED7DF63963B7B988E75E
-:10EC80000A422EC17F0B09F95C2E21645EFC2A9E8C
-:10EC90002F729270C61C42B29C077A67E710B2D8F6
-:10ECA00050FD4B7C844C75AEED26A5840488C3E7EB
-:10ECB0005008E9525EE89D4DEF8FBBEC7E0781FF67
-:10ECC000EE22643E21773BE99FB4FCF173F40AEF36
-:10ECD0003FB145082D5FAB361205BE772A7E870F00
-:10ECE000CA9BC6B22984D410F6DF8273A446A1CF92
-:10ECF0006BBC773492D984547B68AD4EF6EE12FE2D
-:10ED0000BF49082D5F4158FDA6D3FABE82EC3AA751
-:10ED1000BAE12EA60667D1FA2EEAD6F7DE257F24C1
-:10ED20006E2897F0BC80F603FEA03CB88AB872DE6D
-:10ED3000CBA07FDF406EB8A4D2AB3689901BE37CBA
-:10ED400091AF848409994C483BFF5E23C1D9704F31
-:10ED5000C833D87EB6E0635D3FF1D27EE79411FF01
-:10ED600012CA87A9756617A17CADA8D1191F6BE7D8
-:10ED7000E7F61B84FCE083B63C52423F8F6C423E78
-:10ED8000E6703E767DF0FC9B5B806F7504F976D86B
-:10ED9000EECF0D968CA62750979D46683D7B824707
-:10EDA00033B01E42FEF3D2145E4F11211DC1C2CCFE
-:10EDB0005092EFC4F591AD1E421CF1FBDD26A96B0C
-:10EDC0003346977B1E06731E54BF06E9ACE0BCFCBD
-:10EDD00081429ADAB0DD261CA7C39CFE6EF368461A
-:10EDE0007F09BC8F66D8683FC2E76CE4495A45C7C3
-:10EDF000E0A274A077BB698BC2F38E413D02FC2078
-:10EE0000DEB6BC15B346D37FF8DCBAB9D8AFD0268E
-:10EE10004BBBDF1FA4FD35A07FCF642CA6F59C1F44
-:10EE2000B479543AAE7BF8F3C3A1B60C0F7C37909B
-:10EE30008DE3F9C856FAF7D5A9F9F1C8822F1786DC
-:10EE40000C28E7B4F263F0FC89223A6E1D7B353F53
-:10EE5000F46B3C7E7E9FB723EEB3FDD16A0FAD37D6
-:10EE600010F32BA017D983844C2A00BDE838E6861E
-:10EE7000F16D24A84781E0A2B42B593FFCAA0FDE14
-:10EE80009F52413E029E28F663841EA0EF6AA0D3E3
-:10EE90008BD747797B3F8471C4FE6D4FBB8AD27B91
-:10EEA000BE4CC37AF69BDBAB34ACEF62540579DC25
-:10EEB000C4E429C717DA6607FEAF27FEB00FEA25BC
-:10EEC000D8EFFFCEFBFF635E9F68A76330BB4A03AA
-:10EED000FA9A881FD4A456BDAF0BBE0F6C64F4CF52
-:10EEE000B8B75901FE5D715F3F5E239CCEDDF03DFA
-:10EEF0002D90DF1C53806FD3EF89E275EFB6B7BA60
-:10EF000080BECC9D240D6CC19E1A5B167CB767F148
-:10EF1000B43478EF0E52C5A7F620E0F7DCD54DFBF0
-:10EF2000B3B746433AF70E52FED372EEB0C70F7A2C
-:10EF3000ED0EFBF8D5EF87F2BFE4FC38CCDBEDE457
-:10EF400074B8C3262FD75C02E5DCE1305E23BC9F9A
-:10EF5000C4B719E5EE6E2E77BFB4873E077CCF1994
-:10EF6000245E42F5F9F087F5B9D0AEA85F2EFFD444
-:10EF7000E3FFF37A783F7990BC6D9F0DD7E85A682C
-:10EF8000EF6AE8871BEEFBD62A68A722A847E6456A
-:10EF90001B21C5713B95331C5C7A13DAC75AD42305
-:10EFA00061072A06759B9299A86735A8077BB91E49
-:10EFB000D40C46514EA89E1DB3513E853FA07A46C3
-:10EFC000E5EB70D086E3FD444C473B4C8AA3792B9C
-:10EFD0005CA3F5A8E3DC86B9C06FA14FA3EDC7FF22
-:10EFE0001BFAB597F62394C4AE89F684BEC9EFC761
-:10EFF000D5374F18F5AD83EA5B18F819B4A5CD04E1
-:10F00000FD6BB5A19E786BDABA98BE6C427DCB5988
-:10F01000CFE899BA26827A309EDEEDF579AA34A837
-:10F02000BF89E969C7E03BDB1C301E6B08B71317CB
-:10F03000BBE03E702FD36B59CF643DCC0CF4A17E66
-:10F0400016EC8C11B8FA7634A25CD356D250FF522B
-:10F05000E86107E861E9FF3F7A5823E671CA982C16
-:10F06000CAFFFA186178C8B30FF150AD8FE3A182DF
-:10F07000D76FFD2A7DFFA23D03C7F5C5C9F421DE88
-:10F08000AB110238E3CA7F5973372D5F9F23F0CF4E
-:10F0900046D4EF3AAEDFC7E011D59FAA7E85CCCF2C
-:10F0A0008672EFEEAEA6E54F0E103FBC3AE9531163
-:10F0B0004F750F12AC4FE8671DEF6F37BC07791B18
-:10F0C0002611D04F81236AB97E9FCC61EFBB2F12EE
-:10F0D000B403A2FC49A244547A7F9CCBDFF9E2DB63
-:10F0E000FF87BB90903F6F8BCD8ED2E7FF6E8B7DFD
-:10F0F000DD468BFE7E99EF69B81FE0E5FE83CBE924
-:10F1000020C70D27AE0DDDA450FC5349621BEE86CF
-:10F11000EFBC458FCC2550DF47330865ED57AFFE78
-:10F12000CB7BA4102869D383AEB85E89FA443D2F07
-:10F1300078434D0A1D8F81C8BB6E18BF0F0E7E34F9
-:10F140001BAEC49884386B3C3C1610E315EBDB0116
-:10F15000B883D450B9981F978BA9B1BE63886387D1
-:10F1600018FE22759B711C2A3D8C4F5D17CEE6C19F
-:10F170007747385D9DE7FAF2D01ED659EBE9B4F730
-:10F18000AF09B2FAF1FB80878DA3A0A75DD8074530
-:10F19000E025365E01FE7DB9D637690EE57FF909B7
-:10F1A000D5BF8D7E573EDC5F4392D89D889285FD0A
-:10F1B000AA18B0CA67E785E32AF085D2AB02BD95ED
-:10F1C000B13E95D96D2657012E5795B133167B2E3A
-:10F1D000DAEF8C9D699803F66380D9A7547CEDE63D
-:10F1E000FD38CAC7FB88D04F12C900FA7B28FD0F33
-:10F1F0008DF17DAD47B5D02DF4ADDA9961C1E70B46
-:10F2000087B325BC6FA5778116457E2D007E91D4EE
-:10F21000FCFAB6928DF52F1CFEDBF825DB11516F41
-:10F2200027F0B164345D04845BD0ADFE9FCFD74E30
-:10F230006E67A8BFD20DFA4AFA0FA8A08FB5AA81AF
-:10F24000F6A5E26625E248B02FA29F0BB95E4DBD40
-:10F2500048D06E980304CB1D8E31FB9F8ACEA35BF2
-:10F260004DEC5FD645DF4E98571719C17CD09BAE49
-:10F27000C97F647AA69C43FD322FBED7FB55CAFFD7
-:10F28000535CEF0E6FADC3EBCB5B9B912F014371D2
-:10F290005D0F54CD64FA562DEC1A9F4F4E70FB71E2
-:10F2A0009CCF33AF6E0DE1F357B66EE47C65FD592C
-:10F2B000C4FB1335AA0D18CF6E6711CEFB0B355367
-:10F2C0004BE65755C4AC7274CC47F18E0178EBA86D
-:10F2D000713DCCC7D43F46BCC2EB19F92E5F6953D0
-:10F2E000E6C4EFCF0A5CC4CBFDCAFF2CF3EB6ECEB5
-:10F2F000C0F9A02216AA05BED63629C4097C9D3EB7
-:10F30000AB318B3EFF7C93759C457D3D39EF4E02C2
-:10F31000BE5704825A905E6BA3B7683E57EA71E805
-:10F32000D1828DD7E1F832FDA988F5D798948E2542
-:10F330009E8246F44787351BD8C3463ACFF5A35E75
-:10F340007890CF62FE3895A3D64500EF0DEECF0042
-:10F35000FABB3DEA64B86E87C981CA51ED458A4F50
-:10F36000E78CD1FEB046794E2BD2A2CC5FA3F5C07C
-:10F37000B5C750F9F3208E470FAD179E77FDF5877F
-:10F380008D737300F7ABC89F00F9DAA9EB60FEF24A
-:10F39000DB91DF426F851C741B6C7EEC8959E7475B
-:10F3A000C4B7F455CFE0F76F5E09F323B1235E12C3
-:10F3B000F8577C7FC4B87DEF0AD03BA2FA0919FD4B
-:10F3C0007DF066D5A247E57EAB9ED5974EB2DCF7C1
-:10F3D0000CAEFBF15DD05E2C9DB517DE64A1F78805
-:10F3E000C1E6DF9E08C30762BE16EF0344D66FB9BD
-:10F3F0003F8B4EF9C1CE50F9043B53FD49A951430F
-:10F40000EBABC9513DA097C73CDBCE82BE7C10F868
-:10F41000F53760DEAD2BB1D2DF3138977DEF5591F6
-:10F42000BEF69CEBF1FEB0D72EFA6F2C037AE02FDC
-:10F43000FAFE08E97F7536AD7755C44AD78A6086EB
-:10F44000E57E73DD24896E6B5CA8FAE2068CEF2CF6
-:10F450002AEDDA914DEFCBC11415419CC961F92E0B
-:10F46000E0B4DE97437C877EB78048CF2F2EC6B8A6
-:10F470004E39C475C473E0A764C7E93DD221E6796B
-:10F48000593EC57C9D4A7EDB6D6423C443C8D0CA07
-:10F4900071E242DB93CEF744DBABC0F897739CD0AC
-:10F4A0006E6FCB80E795E798FD2443D949F18D3CF9
-:10F4B000EF13F2359423C14FE209939CF9C8C7A416
-:10F4C000FD127C69A5C37209F00EC749F87112FDDF
-:10F4D00096BF9F02FA4DFBB3B8E9408687CA5775BD
-:10F4E000CC86F2D561EC41FD6CF7AB5C1FFB2F25A0
-:10F4F000CA674353D529880FD2F204F4B7C3B80BB7
-:10F50000F537781DD35FAADFA88F01AA8F897858B5
-:10F51000C8BF2CEF03247CF67A68977CF4DA2AC003
-:10F52000C10759BBB2DE53BD433D3E4FD4547A8E22
-:10F530007AD943F532593B97AFE73613DA3F7FD09C
-:10F54000C570F7283D7FB56612B4E754587B9FB16C
-:10F550009E1FE1FA23CBF7687D5F6480FD3F6FC893
-:10F56000FACEECDD62D7BBAFCE66C52D7AFF59E986
-:10F570007BA0789F0A5049E8F178FAFEB7EA794A09
-:10F58000FD9DA07ECBCFB7D814A62F29F433AEF7BC
-:10F59000612CB7C3458A213ED6AEA4FBB717809E27
-:10F5A000B3788D5C3E5DE5F51267F80FB43F6BA94B
-:10F5B00053964959BD99F4CF808156737DA8775BE6
-:10F5C0006CFD53E0FECF2436E55A15FC067208E2C6
-:10F5D000408A49C8BD9424C5E7216BA8A3D5A2865B
-:10F5E0002ED968796520FA890203790FF101AEBB43
-:10F5F0005A09D954FADC41F963D0F2443B83788F3D
-:10F6000022201CA7E55C09963B8D28C6CFCBEC8356
-:10F61000FD426ED05F5BE379EF5A5A2F892A97AE8D
-:10F620008DF7F3297B24CF6F403F233FDA02F1A609
-:10F63000C774FF93BED1FDFCC426FC9FCBEBE7272C
-:10F640005456909F36C6CFB02DDD0FF12CB97E53A6
-:10F65000BDECFACFA6D36B05F071CE683E2A839439
-:10F660007FC007ED3F2F81BF57E16572A5FE593777
-:10F6700021BE425467E4CA2474ACE774B4A8E66CB3
-:10F68000E0B75ADD86FC390CE36F00FF72C8371211
-:10F69000E4AB52D5B17F6A0369C67985446D6037A2
-:10F6A000C61B0FBB463415C6B1EF12DADB164E9FF0
-:10F6B000833E37E6A61E2FB5C11F8BD271227F660F
-:10F6C000E37478A9552EBFC6E9FF32D0358F992152
-:10F6D000A8BFDCCBEC90FA27BD3992448E7708FEA8
-:10F6E000737EC9E50FDFC2FA2FCA7F87CBFD372FA4
-:10F6F0005FFE574F2D4A3D6E42DE95C1E3A9C6AF6E
-:10F7000039D9FC364BB5713AC2CA44F4A15265727C
-:10F71000A956D37183FED55AF9F86DCE8F55BCDE4C
-:10F720002F2A6633C8C3D54AF06E15DAA9E943FD1E
-:10F730002B847AE8F36B89790F3CA7EFBF01E5488A
-:10F740009DF53D7DFE2D7CDED487EB4AE279976204
-:10F75000FE23FFEE9FB05ED3FA9ECAE156784EE5D7
-:10F7600085A873E1B90FE9A172429C602FF6DDFE16
-:10F7700005E02BFDFE7EAC9F9CB17C6F070391CD15
-:10F78000AECA5C767D1CE48EFB993B9A4CE4AB4E92
-:10F790009AB91FCCE6AD057CDE728202C33CECD187
-:10F7A000715ED4D2CC48945EB33D5113E278934855
-:10F7B0005F18FCA8D5D27CDBB4C63ABF7C61BD75AE
-:10F7C0007E59B329CF72FFA57B8A2CF7A1FBAEB57A
-:10F7D000D4B76EE7F596FBF5BB2A2CF71BF6565B04
-:10F7E000BEDFF8E306CBFB2F3FB1CA72BFE9E95B8E
-:10F7F00093AE4B8AF9EE41DBDB9BC01FDB01AF12FE
-:10F80000E60B2DBEEE686338CCFA1D153F9F361F00
-:10F81000CA110C29C872AA49EB96AF8FE8CFDD96C2
-:10F82000F9F668B820C74B596A166806C6DBC26687
-:10F83000DFCC29F1F9BCDA47E76337F8E1C9D757DC
-:10F84000355EAE8AF457C3B8999AB59CC6D7590DA0
-:10F850007F0CE329F23AABE663F3B44CEF19D5958C
-:10F86000037689D6EDC3F555237B42EBABE3F68FE8
-:10F870005AC209F58FB75705FD2C4ADDAF05A531F2
-:10F8800015C89B68BFE2745A718F58DF5EC68A92B2
-:10F89000F282273280DE653E86874829C3374EFADA
-:10F8A0008FCDB38CFF0DBC7CF01E8F1DE2C8C11A3A
-:10F8B0002B9D0D1C3F513DD4C04E94174BEF81CE74
-:10F8C000D950CE8A93BAB93CAA1A5FE79E4FE6E3B5
-:10F8D0003870BD5D21F4B696C5278827F9FA77FD03
-:10F8E000302D84819888256FE06471513A7CB7ACE3
-:10F8F00095F81C149F3C386F9B6711D5FF46D3EEDB
-:10F90000AFA3A5ABFD2C1E5E6FAAB8CE7B4531BB65
-:10F910006FAC51224B287DF5A13E8CE735AE8F6C44
-:10F9200083EBB48D510DE990F8FAB82F926553E34B
-:10F93000FCCDE3FCCA137CE57C14767CDA26EB383C
-:10F9400036965AF9B59CF353E6F372CEC7E5121F0B
-:10F9500045FCAC44E3F22CF17119C7A1CE794563A3
-:10F96000FA758FF33897901F4D9AD784FD1899DF59
-:10F97000B8FCB6801D079CE7E13885CF7B55331571
-:10F98000F4836ABD0AF2B776E63E4B7C73C9885CA5
-:10F99000323A6BF97897E7BF8A71CDCE1C3EEE9470
-:10F9A000AFB5F3E372D83093E563ECE4FDEEE038F5
-:10F9B000BA9DC72D5BBC67D4C4B857C78CBE7C3F0B
-:10F9C000BD7FE942DF9AAF517A1AF3157F1DB41B50
-:10F9D000E271565EEFE1EBB6E5037D27CEF561DC23
-:10F9E000E7A59CA231E38802BFCBF250EE0FD6C050
-:10F9F0007CB224FA0B15FA5F1EA36C53002747351F
-:10FA0000C05F8DDEBB358C73E5DFA541BCB1367FB1
-:10FA10005F35B41B20A1DD5510F7CAB1FBA33E88AA
-:10FA2000FB8477BA419F4B985E6EA4FF12F552D0CB
-:10FA30005D31D8AC019D4B7C92FFC2E5A8D62B3D31
-:10FA40009FB904E52820C9D13D420FAF245726CAEB
-:10FA50008F8817E8E70AB91E26971F310EFFCEC719
-:10FA6000E1773C7EFC268F7FBEB1D587D75F6D2DB9
-:10FA7000C6E73D5BFD78FFFAD632BCFF358FCBBEC3
-:10FA80000A71568C930679BCB509EF7B79FC54C892
-:10FA9000E7037CBDA356EDC0F860833FE4F424ACDB
-:10FAA0002B3470BA51A4015F9414255DBF75CC3816
-:10FAB00084FC3B3322FF04EDC0CAC682FD0F51BE59
-:10FAC00038BE434280171D477FA15D45E5BAA1AE10
-:10FAD000C0BE01DA0BB769D7D3FA1AA2BFD08AE049
-:10FAE00079E375F6DB93B42FDA49D5BE6CB756D5FA
-:10FAF000A9921F2AD68F4261E8E7D458280AF40554
-:10FB0000BCBACF9104F777E56EF0825CB59C0B79B7
-:10FB100041AE5A72D93A032059901B9DCBA9281F98
-:10FB2000F05AD7D7754E77077D0EF476C4C65EF7C8
-:10FB3000167A20CA55686DAAC748DD3F397EB4538E
-:10FB400049EE8F5ED46CF89D1BFA4FED37B5851AE0
-:10FB5000E8198828D03F958A0DE8976110B42F19CD
-:10FB6000FE10B7B7D6F939AB2C18AC827239C4BFC6
-:10FB700004CC96D1EF05B951CB16BF0FF327294915
-:10FB8000B0C7E0CFC8FE7CE2BD8A262AECCA86ABAD
-:10FB90005C8EF1D7E022D47A1DA3EF7B03D6F8AFB9
-:10FBA000C1F95BEE3BF11BB097DFF3DB58B91CB634
-:10FBB0004E7ABE6C1DE2AD728EF71D6437964F27EC
-:10FBC0006D78DDC1F97DBEEC0C81F95BD5281ECEC8
-:10FBD000017A9C9130FDDE2DD96DCDB0F25BA13C58
-:10FBE0005903B87940B3F8114A19B3DF4EF0C3C1D5
-:10FBF0003FE1B824EEBF85C82560FE0471D24EBB3C
-:10FC0000D5CF12D7DF6ACC0FB1D9A5FCB6FFEBF97F
-:10FC100077FC33E59FF0FF46F0DBB13B09ACA788EA
-:10FC2000FC3E51FE57521C49CF7FBBC64CC2F72A3F
-:10FC30003BE3FB7576096F05E476D2C2C04F9DFAAF
-:10FC40004969CAE87A52B54706E68E138FDAC6FCD0
-:10FC500044CDC3FAC7F373A8BBAD58FC0EA7E905A2
-:10FC6000BF6FD4F75E9B454F47D3CDF8F359D3BB55
-:10FC7000903A9A705D2EEC7019C3892B7C1427D2B0
-:10FC80003F57184C4E4F572991ED28A7A6C58FAA6C
-:10FC90002B5BF23EDA25EA67E8F339FEA6F4B742B9
-:10FCA000BDB49E5772C57723F6C47669CEE87A82D2
-:10FCB000350CF790F0CF9726C60582545C8AE74250
-:10FCC000BDEC7B5AB4EB52323AB8DD0A96DDB5DCB6
-:10FCD00070C3BDA93C0A38AE24011F005F673AAC6F
-:10FCE0007C96EC5FCD28BB67B5B78BA9FC1EA2ED57
-:10FCF000D4A9CD8D35B4FC923DEB0EBE88E408FF4F
-:10FD0000C297B4DE53F0C78D80F6AC7885F8599E63
-:10FD10004575D887EB822B7214122900FAAD742C2A
-:10FD2000CE97FCAB1CB91FBB711C8F6A741EA1E37C
-:10FD300075948EE36EF47B93FB49C27F5B583084ED
-:10FD40007E92F0E308F7E33CF45F221EABE4E5AB00
-:10FD5000EEF169B07E5025C58F2B47F28109FA4933
-:10FD60000B8995DE4AEECF554AFE9CD0F79F0ABD1F
-:10FD700015FE2AB78737093FA93239BE10D70E2999
-:10FD8000BF8DE247B3ED32F4800055B4BD4632C2B8
-:10FD9000278B7C75155CD516A57CBDC99FC6F2AFB7
-:10FDA000299D9AB0E7C82786B797F3F237F974947C
-:10FDB000FF804741FBDE384E3C2250C6D6555E36AA
-:10FDC0001496371826AFE17A11A7A786FEEFDEB9A1
-:10FDD000D09E552EF27D7DD59939306F28FE0819B9
-:10FDE0002DAFB57C5CE1FBFBB2C14FA1BE7636AC5A
-:10FDF00067C8F1883E0899527F9CFA4A05A3FDF92D
-:10FE0000057C7CABFC04C47E943FBF808FEF8251A5
-:10FE1000FEBA1567BF1C7B07F3ACCE9728B82ED26D
-:10FE200055F031FA09629D26CEBFE3E84F05CA3E80
-:10FE300062790323FE08AB6FB9A8AFEC18E617DEB2
-:10FE4000EF3986791CA74FB0F5EBD35ACC007F640D
-:10FE5000A9C05794A35191FF5E007912ACBE28CF80
-:10FE60006778D9F96A06D84D9117D21948BE3EB7BE
-:10FE70005065F16371CDD7198E2BD6D9FC23EEC511
-:10FE8000F88EC8937AAA94F97BDFB68CBB5C3F945A
-:10FE90006FC2B85FB42438467E41A3C4678F6EC575
-:10FEA0001BE3E15AD14F990F723F47E98BCEE260D5
-:10FEB000ABEDE6747D72BC1D31DFC9E5573893E7C1
-:10FEC000CD549559E38E72DECC6A7BA804EAAFD696
-:10FED000949D993EB46BA84F472F1A8863CEC78E66
-:10FEE000EE8461ED196271CF4AA2F23C1AB311D6C9
-:10FEF000D3C43E871A1EA790E918AFFDCAA17EF4AD
-:10FF0000B3AB866335207F3705BAD0AE2EA37675A6
-:10FF10005212BBBA581DDC3909F4D7AFA07D78F96D
-:10FF2000ADBE9A494C9F313FD5AC2CD226811C786E
-:10FF300092C7A116703949A577F4430D70C344F5F3
-:10FF40006EA53E82836EB85434FE38A59287F3B115
-:10FF5000F35F4B161F15D7EA14E3BB8548FCEDB0E1
-:10FF6000C695E57A449C87A81DF9A0CFC2FF95CB22
-:10FF70007D5B67F1FE9E597790FE04BF4ED803BDAE
-:10FF8000ACCD80F8446FD9D8F3859CAF5645ACEB27
-:10FF9000CED54EEBBA73AB66FEA36EC1496B99BF6B
-:10FFA0005AB616FDD5E5250EF457BB66DD81FEA9D0
-:10FFB000F0AB5B6E3C807117914725FC5399EEDEE8
-:10FFC000DC670C28371EDDC28FEF74B03C20F0DBFD
-:10FFD0007DE8B7BF8DF94572F9430EC6AF2735F3FB
-:10FFE0000740FF4EBBE95D0BEB87B31CFE27938CEC
-:10FFF000C31B0EA6DFBD29D6514FC382C664EC07D2
-:020000021000EC
-:10000000F2419E6F841F2BF60D4DF532BD6DE07EE3
-:100010006C45C95AD4C72C2FF55B816F7EE6B79229
-:1000200041AB9FBADCE8CB83F197E73B7588FBB522
-:1000300013F45B1F48637214F210A797BE4FD328C6
-:1000400034A5F3E82E75D173C08F07B208FA03A761
-:10005000B3F4C8FE24F18617B9BDAB553759E4ADEA
-:1000600092E312BDA6DF8078C0E9A1B1F3F21E923F
-:10007000707A6131A972B8E11AAB027ED07BD3816C
-:10008000D718E64B7F77D686C264F5ED6FD592CE52
-:100090004B6FF1715BC9E7BBAC3A169FDC52A263B0
-:1000A000BC776ADDDBC7514E1BB99C2E7360BF7BEA
-:1000B0006769382EBD3716B4C17A65EF2C27E6275D
-:1000C00074CD7AE1ADBBC1AE96297CBFD9468BFC1D
-:1000D00056525C9D0EF57B55C42B5BA8FF920EDF3C
-:1000E0007BED0CBFF03C90CD7C4C4F1F64F8E64399
-:1000F000816F381F5709F96F14F1502B8EA2E6C497
-:10010000B24E43F8FAC312562DB5534C1F3E6C64E1
-:10011000F1CC2DA2FF870EEC043D6CE072D475612A
-:100120008317F5F5D0018CA7B5CC5A8BF1A3AEDCC3
-:10013000B33ADC6FF6BEA7C3BD8C33C4386F297BDE
-:100140001671482F1FE7CD1077A7F2BFC4CBF0552B
-:1001500074CAB5769F11CF6396F1DDCA681AF67F2F
-:10016000D5451BFA9D2BF9F747A6FC4987EFB64406
-:10017000A91E53FBDEA0F5CF00DC9221E1C50F9F45
-:100180003B900FFADD33FB8F58EE8AB2B75B80EEFF
-:10019000696507308E9F77E8407736AD7F7931F11A
-:1001A0009BBED1EDD7F2F9694B0EDB07B1C51F0934
-:1001B000C33EB00F8608CE4F0B9F3B56ADF892ADB5
-:1001C000B79804708858AFD1BC7CBD83AF3B908B8F
-:1001D0009794C4F16AD0424EB0BF2D65AFBA81DEAC
-:1001E000C283EA5A90EB9AE7AEFF22C81FB9D1E169
-:1001F000B992F6E703CFAFDD5719ECFD1DACBE0594
-:1002000021CA8F869203F91B668DB62B237A53F28F
-:1002100097AD214AC7E9A52FE4035E7B95DA5B1F02
-:10022000B4C7ED95EC272D94E6D3C090B4CE24F559
-:10023000D7A5ADB8D1310FC6F347DE820479A2FA53
-:10024000BF0EE8DFFCA8D303FA9275E8155D05BB85
-:100250004671FB920479DECCE5A5C16076AF6516E8
-:10026000896C5740CEDE6BAC007D7B5165FB500E38
-:10027000BDCDF23EA579A197CF1742AE7B73DF715A
-:1002800083DC7D7890EB47D8A624C6918CB2D8CD7C
-:10029000301E823F1D929D0990E4F3C22907C3A935
-:1002A000951A7B6F50BB0DEBD4F27B13FC28C04139
-:1002B000DC9F12EFD73B18DE15D7CBC82BF8E177C0
-:1002C000A8BE77ED3AEABD1DED9381787DF3A103D9
-:1002D000C5B00633E5E0811A9EF78DFE98CAFB395A
-:1002E00095F8D03E2D379CB87E20CBB7BD6C5F14FF
-:1002F00060B3989FC111D7A6C4ED869A187F48E2D3
-:100300007F91B0F9DACC843C2C3AAF13B01FD55EA4
-:10031000167795E524ABECC04E361F50294C58C7D4
-:1003200095E5B6C10879617D9AEACDFB6C3D93CE27
-:10033000531097501BFD389E5C3E6DF41FCC7B190B
-:100340007EAB7CDA8B750B4E91E978C4C1D7C5388A
-:10035000EE17F37296B71FE95B6EB4E543FB53BD2E
-:10036000FDE86751BB9E0F572167C24E8FC8DFACB7
-:100370001BEAC14E815CC392F7E9B2EBD3C1DE3513
-:1003800078193E21521CBDD73BB69FD12DC9E369D8
-:100390000FF3AB1ACA48BA2713F49DC59B7A1FCE38
-:1003A000DE9791108FDB630FFDAB6372FCDE5DF2B5
-:1003B000F97A8F1BEC0BCBC72AA766CB5E148F6331
-:1003C0008A78A958BF13F1D15171CC922ECCD7B2F3
-:1003D0008B3C0ABE9E372A8F6782F9678EED6D9A35
-:1003E0009FAF93200E6BE4F1B7A1B9E3C441B70905
-:1003F0005C76DC31797C5CF628F72BDF00E341AFDB
-:10040000B7383C783520BF8492DA9B961CAF1DE04C
-:10041000F8E572F4F3840ADFB176DE7458FD4AF130
-:100420003C8E83991E4C2D3BD09D88832B5B296F7E
-:10043000E838E9AD6406C94C2D77CB47ECDEB3163E
-:10044000F91AC1C5E3E061215F83AAF967C7BCD48B
-:10045000E51A381DA9DEB7CC723441FE142D47A62B
-:1004600066B2EBD5F4DA3DFB40BE8D3E3F09B82BBA
-:10047000818EDEC70E613F5ED6D9FE97DE0B1B0A6A
-:10048000611EEFD24CE29C3771F991F5C939CFF476
-:100490006DA3FAD799EFC4FD7E9D5E86375E81928B
-:1004A00009F2B45E0F799C93718A304936377242F3
-:1004B000CEC168D64C6CFFD66D19FDF70413ECFA6B
-:1004C0002E78958BE70660BF1ED4FB31BFE6365A07
-:1004D000BB83B673CC50A7ACA3F7454E66F78F85A8
-:1004E000ED16BE886B9193C9DD7A3D58047492B6BF
-:1004F00066D4B3B58A1A04FD27FE89C5E576B4270C
-:10050000CF132D8DD73F07EB3F48EB07DCE0E771BA
-:1005100077E2999234CECEFB1D25A40EF4E57B59EB
-:10052000563F739693E9D99C78FD1589F5CF7132C2
-:10053000F9A7CF17E0F3A7D9F35CFEBCAA88E5A919
-:10054000093E8A7A6BE3F5D5E27787D877939D7C6D
-:10055000BD80D32DF0BD9CCF74431A1B8F2AA17789
-:100560009A8278BB9CE26FC4F7DABE6318BF73F25D
-:10057000FD91690E7CDF916B477CDFF10941FCD96D
-:10058000E962F1C8AE0B676FFD2ABDD78689251FCA
-:10059000DCC165481B7A0AE36FE5F97C3F1BD7573E
-:1005A000B16FEB486CBF655D55ECF3E974F23C0C40
-:1005B0005EDF025E1F9170BBE897C039ED7C9F4EF5
-:1005C000B9E8DF407407DA958128F6ABD2C3D68349
-:1005D000BBB2BE81FEF503179ABD8971C1AEE9C7F2
-:1005E000D9BEFD7C4A77499C2E8DE3B1F261DBA632
-:1005F00003C00F4DC18CEDAAE88B1905B4FF8B4EDB
-:10060000A8FE34E8BFE4672CC9E779D41CE7A6C28A
-:10061000F5BF54623F80FA6D19178B80FE2353FE9D
-:1006200055053C5A1E7D43059C5EA9B1BCDD851273
-:10063000FE6887F33A809EBFDA2236DAAF9EF3EF88
-:10064000A9307F5C311CC17E4F1BEEC3BC89BC014D
-:1006500016DF5D30534985EB7764421E868FED735C
-:100660002DF7EFAEC9867A87F8BEE5D8F94940D7AD
-:10067000685C6FC529015F15F67B04E7E7B3B8D264
-:10068000E5E2E94AEED708BF408C3FE503EEE36AB6
-:100690001FBEDB09F36315E76B61BE8DF907D30B52
-:1006A000D7A07FF089EE817CDF073C5F77A27F4097
-:1006B000DF837F5009FE4126C4E5FAF236B846F7DB
-:1006C00047C853E1D0C75B43B4FC11FBEB79806BA7
-:1006D0008F5E782A0FECB2C80B17B85E9477695515
-:1006E000CF83BD16790802E73B04CE8F3513D8CFF0
-:1006F0005F396CB3E07C0797AB4A83E955FB5F0930
-:10070000AE7375BDFF5E6F01FDBEF34516879E1A81
-:10071000EB5713717E39E777E7277D78FE8890FFE6
-:10072000CEF7D939221DF97C7F0AC7F98B092BBF77
-:100730001870BEFBF271FEEC3466774C8EE317F353
-:100740007C54F1BE9FDB7119DFCBEF2F17DF138EC7
-:10075000DFE3B8D82AB75DBB0A713DA5DCE364FBD3
-:10076000CD0662CFDE45AF5362A127F600BF2FA6AC
-:10077000FBE13307F7BFC6CDE794F0FE5412D79BD9
-:10078000287D9495DF8F7A5249F504F6938FD2072E
-:1007900019FFE7C78E41F90584E955F57088AD8FDB
-:1007A0008D83F72B8DFE3CC4FBC38BDF677EC3D8E4
-:1007B00078DF94F297EA663AC6F64FD3AC786C814C
-:1007C00088770C37B378E47033C623170C717B79C4
-:1007D00081D94B319E0F70B913F65CE867E785B39A
-:1007E0006A28C16E8EC8F730DB872BBEEFCC6778E6
-:1007F000FF275A1FEA73E7D0DCF4C438958CF73B27
-:1008000001EF97401C89E2FD39A0BF04ED5E27E0AF
-:10081000FD04BDA578FF9AB404FCE61E5A5DEF8185
-:10082000F5E009E613083F7631F8B1D909F152A78E
-:10083000D58F4D25DF67F9FC1DE7671F9B7F86FB82
-:100840008E25F253E3B8D60178724E7CFF7A672A80
-:10085000BE7E62DDC72CF2B53B8727E637515C5B75
-:100860009F363975B94A4E47AAF70F5CD011D702A7
-:100870001E9F3A875DAFA6D7EE8FFBF212712D3126
-:10088000181EEB7CEC37B83FB8338BE2D992443E6C
-:100890006F1B077FB0FB055E3B5F87B1E20922CD8E
-:1008A000FFED2E260747291EC1F848DAAF908F1DAD
-:1008B0009F9CC5F6657C22F0888C4388843F04BDEC
-:1008C000EDF98CEF476267BEEB877D7327C43E531B
-:1008D0002B2E91F9353E1EE9437B2ECB7987CBC475
-:1008E000BCAB383ED1116F3C60677843E0138A3B64
-:1008F0008EAD05DC3140481A89D32F708AC01D6245
-:100900007E6C1FE6E72D79F8BC20E19411FBFF29EE
-:10091000718AA847C629723D9D3CAFA39DE2966DA2
-:1009200088638EE33C3B51FC22E395F17049E54C32
-:10093000864BDAFDEC3C268167645C52E7EBC23CF7
-:1009400040815F268A5304CE91F18A4C5727E09765
-:1009500092387E91F18A2C4785F9642DC4F7058E73
-:1009600049A59F50EE0E771CDFA42A47ED33E29E87
-:1009700094F50CC52E17F7FC1AEC4A6ADCC3C6B90D
-:10098000F222C13CA05478E4017F3F3B8F489A3764
-:100990008EE49F7913F7690EE83E157111B5934601
-:1009A0006A3C24F46EA4BF60074AE2F3524ABE0CCC
-:1009B00070FDC81F7BFD65A27849CC17B3D3D87CE6
-:1009C000906A1D323D9DE1AA070B997F2CBF8FE7EE
-:1009D00095587113C99985F2FD55BE2F39158E2290
-:1009E00024E66671A930B683F9E480C34037E7F3A3
-:1009F000BC024A6A70269909718D20BC8775AC7952
-:100A00004A244C495B01CFE9B856D5B075A033B341
-:100A1000D83913A7AB1C38AEA73E6479875D2E1674
-:100A2000573D7D5D9A7F3F25E143A897CEB767D2BA
-:100A3000FA4A615CA78B7E66B37E2ECB886EC27548
-:100A4000F0EBAFB5850B46DB8707D3391DD906AE72
-:100A5000A735F0F814AC07E6CD1DBD1FA035BD00CD
-:100A6000FB0DF9EF79B4DC4E5BDF770BE9A3341BA8
-:100A70005B3F95F9FADB7445E4EB841D097C689CC7
-:100A8000E934D3A83CA67D8EE50374D638709D2941
-:100A90000D96CC69BD0F1517BA92C987E897FCFC73
-:100AA00061DEEF33D363787EC6CB3C8F77B3A68409
-:100AB00081DF6880617E9A346DDF43B4E8D274765A
-:100AC0006ECCCBCFBD8271A197B2381F4C05F31508
-:100AD0004EFB983E853D4604F655D2EFEDABC7D0B0
-:100AE000E7BEAA25C51C8F1105D6C9E08FC2D1FC6F
-:100AF0005E55A762BF577976DD05F3C699BA5733BD
-:100B0000E0DCC7E54336027AB7CA537E073CEF7292
-:100B10003139063E03FE5F55F3F9AFC0F3C646EB2D
-:100B2000781C4C2F44FE56686C3C60FCF2E68E6EDE
-:100B3000977848489F92C0FFC00BDF5412D62144DB
-:100B40007E8A3345BE5EAA7E2B8976578DC719A74C
-:100B500096EDDB0DFB5B82A5ECFCCB061F09C37A8F
-:100B60006E839F440BB87C61DE4CF74CB6AF87EBCD
-:100B70005756D9BED642884B0E696C9D599A5F2A4A
-:100B8000E858E567439C9C8DCFE9792AE2910AC831
-:100B90006BC4F32B197E6F30D722FE6F7CB87B5766
-:100BA00021BC57F36BAB7C6C1DD492477588C5DDB7
-:100BB000564872EE92E2FA157E290F90E7EF75160D
-:100BC0003FE101F979309BCBCF5C05F5E815C5F71E
-:100BD0007061C23C7363BAF0CB88CF9E201F23F2B2
-:100BE000C0C757E67B2A7ECA7C92E542E6F7699742
-:100BF000C4AF14FC4FC5EF8AB2AABF2B7F3FB03BF6
-:100C0000EC20B75DF63FE6B37815B5C109F644E6CA
-:100C1000DB0786CF0576E2CC108B87BD34DDF74548
-:100C20003C8F8AEA319E9FC9F5213E0E541FDC8914
-:100C3000FAFCFA0CD0672A6776A8A7D154CC34D036
-:100C4000BF830FDC85FD063D75C7F548E6FF28FD2F
-:100C5000A3FFD304BD45A3F548CE0FFB5BF5EF4ED4
-:100C6000B0E7946F73D37D7815F6B49178BE98B8D9
-:100C70000F55AC937715B40461FF78C3808DC07CA9
-:100C8000D33EF48CB60EF6A5D62938AD19A40FE9DB
-:100C9000355A59FEC3558FDF4B203FFDE1E9C40FA4
-:100CA000F6CA6865F910F43DE64308BC2ECE4DA4A3
-:100CB000EF4DE687B376EB79BB2EBF359F67E5E056
-:100CC000225C4FE82EE6F148EE37883C5622ED6371
-:100CD000698127B9F1FD1EAD1722E83FB4A7D8D727
-:100CE00022AEB21F205F7B8EFEEC2BE00754CED4E9
-:100CF0003D00292A87A24EA8EFBB2547EB105FD500
-:100D0000291E5867EBF9B86D07A172B4B2E49DA42F
-:100D1000B8E4F0073FF4433F0EDB77FBB3C13E6C12
-:100D200067F356DAD525D3D78D817B427555750586
-:100D3000B353E78DDC9AC1E7F7AE3BF73F08EBD939
-:100D4000833AC643EB393E6ED07637ADA3E3D9BDC7
-:100D500054F16FA3CFBBAFD9D37C14E2C8EFEBC083
-:100D600071D27BE1A97CF0234E3EE66C82FA7B3E99
-:100D70007EEAC7983732A8CF87FE8ED07FA5C1DE26
-:100D80007FF8FC09B0332B8B5796423B691AD90D7B
-:100D9000F274C550DB9B70AE41C3803E0FECCFCAEE
-:100DA000BA7DCE7F003ED53DEBBC925EA70DF96AC1
-:100DB000613C33D243733228BD792505F7E7403BC8
-:100DC0007EE23791AF7D04F8BA528A3F5672B96914
-:100DD0005F5AE04A8C639C192A74617E421DCF4F92
-:100DE00058AA06C10F3EE3B9D28571C73A9697203B
-:100DF000F36B25C7E92BEB0AA627C3E385757F4173
-:100E00001CDE7E8DA32919BF6FE2FC4EFBD386FD4D
-:100E1000D0DFB41F393D00AFD352E45B6667F07C8E
-:100E200052EFC4E22002CF50BE3AED0971108AF7AA
-:100E30006FCE4888AF5C6EFBF519CC0E0CAAA12FC3
-:100E400001FF2B781C64BCF843F938EB6E548E908C
-:100E50004F2B797C62A5884FD4174CB7C42788E9FB
-:100E6000053B7B06D6DDC0CFD6566C013A7A3F6093
-:100E7000EB6EA9E477E5CCA76E3D9A60EF7AED269C
-:100E8000EE97ECBE86F949FF55F23B226775CFB667
-:100E900096D2E70F95AC9C0CF62F418E5B613C2EF1
-:100EA000578E65FEB52F2D7211232ECF428E47CB64
-:100EB000A582FEA890EF54E301E5C01F5D398E3F87
-:100EC0007A66E9D549E53F5ECFB931F5A086CBD545
-:100ED0004D5CAE2A89E9C173A9F2DE44BFF557DC47
-:100EE0001E8FC889AB0FE341E1279DB83EDE7941F3
-:100EF000C7F3CD3B9FD8F8139837BA871679DEC36E
-:100F000079BCCAB38AD2750DF80F25383EDD5A4236
-:100F1000BCFB8D0CB11E6ECDDFFD37CF1FB2ABD841
-:100F20003C6B54517ECFE1F3C4E70A9E4887F97CBD
-:100F30000ECFA39FDDA1279D973984202539AFD8F7
-:100F400000FA971CB4963346F691B7D960DDEF737B
-:100F50004F4BEFF9FE6739DFB13723F9BE6731DF59
-:100F60003A2F8C1D47FC39F7AB9FE6F9BCFFC6CF83
-:100F7000ED6BE3E7DC3E03FB56E9F520EC5BA5CF28
-:100F80009F877DABF4FE10DFB74AF227762EBB3881
-:100F90008749E77C68CD8D58D607C53EEDF652955A
-:100FA0009D53E1D5F11C548A9B6C987FC2F1A22D10
-:100FB00023E0D4E9B8EAFF4130FFE4EBEFF7A13CCE
-:100FC000ECE2F3AC8C633A243911573DCE470DE285
-:100FD000589DD3434DC1123E602037F3A6EE7B28C7
-:100FE000014FFF2F2E172DDC6F0B5F209127957877
-:100FF000F9972E90A71E421C45C22AE00EF88B8A54
-:1010000070FD00411C575FFA00FA5F80030197E111
-:10101000F96085101F7D1EF15CFDD0FC3BF8FAC124
-:10102000281C37C23715F9C4F079E92B1827A91FF6
-:10103000482E6FF1BCA5A6EE9909FB0C1A87C43A9D
-:1010400005A5644A7C5FB92EC9955C4F56A982E319
-:10105000B2AC98EDFB12EB1C623C7734F7617E4733
-:101060006FA9C307F1051927CA385F2F65FBC2B402
-:101070001BD9FED4FA0B2CCF1005664AFCFC349D1C
-:10108000E7EDB67B427E38AFA4C12FE1DE189BF7B7
-:101090002A8BAD785EC6FBFA802EE1FD309B0FB740
-:1010A000B3F13CFD21413FEAC9BD2C3E70D8EB6352
-:1010B000F24722E8F72CF4DAAE7BC807EB526CBF9C
-:1010C00065F9103B6FB37CC087FBA7170E92E855FC
-:1010D000B3213E4A5AF13C20897F0B095B7758E8DF
-:1010E000F5754F86F8A34676C23930539C6B4DD0C8
-:1010F00003DDDB8CFB6BAA9D0A9E934DF8FA98E00A
-:10110000AF9E7E6A07A8C0429ECF277E1762AAF3D1
-:1011100000CA813E4E5C56AC7FE95CEEC47A56153F
-:10112000AFBF6A90E5B1C97290E53CF7269CA3BCBD
-:1011300068C8C0753179DCE5715D64C4DE7D04E2A8
-:10114000F617D2FDDB619C9D6C9CC538EA6A870A64
-:10115000FB3588C6C64BAC7355CABF0F21ED8393D0
-:10116000E912E71F7CC590F685711CBF8853D79A9A
-:1011700076C0B2BE22AF031CE6F9083FD1D839A22F
-:101180008707C75EAF3ACCD7AB886782E70EF2F32A
-:10119000022ACA483AE09C8A41C2E4EB615B2471AE
-:1011A0007D4BDE27EE1E5C5D8FE7AB793C789E427F
-:1011B00005A1D7523CE715F31B4D72C0B21E6772F2
-:1011C0007BAFF3B898AEB07E093EC9F4DD3664F566
-:1011D00087BE18B6EE6FB8F55EEB7E8C5B9AF32C8B
-:1011E000EF976C2CB2BCAFF55D6BB9FFBCD77ACE74
-:1011F000CF7F0B59CFF959D5542D9D63673DE7E754
-:10120000A63AEB393F0DE6AD92FE9AD67507A58F4B
-:10121000AF5FBC5534569C37617FE198E7FEA01F55
-:1012200098645F8BBC3FF1AC21E28D563DE80E57D0
-:10123000B17371067C7BABE8FD51E2D7D0C1E5E725
-:10124000FF887D7BB55EB69E337ABF1DA34BD84128
-:1012500079DF8F38B7AF62B00FE5A0523E9FCF9BCA
-:10126000FC7CBE570C8E17C4391729CEB318357FB6
-:101270004FB47F7C1D6FDCFEF176CB49DF3138E760
-:101280002355FF26DAAF91BC2D383790F2A30F1EFD
-:10129000E5B2F706D5B79D59C5789E85DDB92866B4
-:1012A0004C8EC73B8979FDC4F66DF3383E31578DBE
-:1012B000539EE9BDDDE9637261327CB45331237022
-:1012C000CE5DFC3C0B827640E7F3A97CAE45DA4E5E
-:1012D0006296501685179128E28D42676407AC83A9
-:1012E000E6B27DA32DD7D870FE693967EE86FC93F0
-:1012F000D66B34DCB758AB1A585ECF67F35300D6C1
-:10130000A0203FE2A4D964398FC3BBDD037AA2FFDA
-:1013100098BD4FD59F8E5CB63E2C3F2F72313CD48A
-:10132000A505F35C281FA697AD4744F0DC32916F0A
-:101330009B2ACF9602470FDA6D22F0011BBFFB619B
-:101340003D2589FEFA5D4CCF02254AC40E79A337AC
-:1013500093887D0CBFB2C36B4B1ACFC875F1B8E848
-:10136000C54B781E9D2ECEC7CB63E7E37549E74E8C
-:10137000E6F27E1E7039991C143CC5F6A34AE79428
-:10138000D7FB3690443C5BCEE7193DF60EC6994E2E
-:101390000F8C8DC3C5FAD32EBE4FB9FA822D988C0F
-:1013A000FEDFBB3496176CD893F66F3DA7B7638604
-:1013B000FFB5209583967FB6E1F9D2016FCB34DC7F
-:1013C000C7EDFA07C2E25D8CFE7AAEA7016F640733
-:1013D000A1E31788BEF128FC3E875EE6C0F5E7D39F
-:1013E000D7507C426568578CE2C58278FF5C7CBE32
-:1013F00009EC3D5A5754CACECD8778CF9201964713
-:10140000BEBC6C1F3F77A51FF725CABF0F525E17E2
-:1014100032615E5EDE18DD81F8C7EFABC2DF0B2103
-:10142000FE6D6CBD50DE3F6920EEEA186272DFF19E
-:10143000537F17FEFE8657E046B3B1764AFC7CAF79
-:10144000CA734777C2128C7CBE977C8E90F0CB74A7
-:1014500009570A7FAC81448E69CAE838732A7FEC49
-:101460009F5C1C8F5C43FD313AFEB73958FE6CE03F
-:101470003EA50C9CC6B4FB945CB05F2D7C9C5EAB1F
-:101480000C615E404B8AFD747FE472FF5A6514F76D
-:1014900029751484BCFE31CAE7BA542CAF5F64E7E7
-:1014A00078E84E96D73272E5795C42AE0BDD0E7667
-:1014B000AEA19BF9DB0B2F3D9D37D6FC591E0811C1
-:1014C000E80FB52F49F365F689F6A3EC3C0ABDF5A4
-:1014D0009D9A64FA2CF470BD1EFC890BF61D2ACD72
-:1014E0009134B403133F7F728EFAE9EDCD9F0CF374
-:1014F0001968FFA4FD5F7CA01F3B42D6DF7512D7A1
-:101500009346C889FCF71ECD007FF377E9A1C3603D
-:10151000F720DE0DFB053B62CF38D19E4A7C97EB6E
-:10152000B9CDCDC653F7B1F7E437A66F65429CE459
-:1015300006371B17BBD3EC81FA67DACDE340DF83B4
-:101540008B92AF43BAB44527A1DC7546F01494EBF7
-:1015500088EDC7F8F12769E64BF0BC54334FC375EB
-:101560008FDD7C99D9E91ACF7BC5F17D0CA9C6190D
-:10157000162EDE2B4EE4D7A7E3B3DD19EC87F6E990
-:101580003C18322E739CDDF45A07730BFDBEBF323C
-:10159000F97A7B0B9727AA67989F25F6B904BCC4F4
-:1015A0004C367F89F274FCCF035D0FEAE120ECD763
-:1015B0003A3DCD46F627D839712E414B8CF985E757
-:1015C000EF51F633BF90E0FD4FEF2CD80FEBBB3758
-:1015D000CFE07ACCF759DC7E8F75DFB368F7CA4C61
-:1015E0006542FAF9CD4C260777673AF0BA2D93D1C8
-:1015F0003B61FDCC61F5083DD535765DEE61ED9F33
-:10160000E1F57FCCEFA91EE6B8991EF6BB2E6F7CE4
-:101610007EB8AAE8D3CB87D007DD6FCD33FD16D7D0
-:101620000761AF289DD7B8518E9A43E99747E79451
-:10163000F2CF408EC57E033543B1C4C303DC7EDEEA
-:10164000E416B8C8AC7433FD5D00D731F477919BD4
-:10165000E96F8DDBAABFB56EA6BF8BDD4C7F97B857
-:101660003F85FE9E05FD81FC3C1EC727A7AC768703
-:10167000E2E255D07EBDA6F07DDBE40F4A82FF5149
-:101680003F1022269B2C9F48C40D14BF9AB85FE3DD
-:10169000356B7D3D7CDEA276EC4B506F0FD7DF1DA6
-:1016A000BF65FC033E3E93442F051F55C75A2FE4E8
-:1016B000C5A79AE7026EB6BFBDCAC1F6539013B470
-:1016C000FD5996FE6C067E8DF4274C3DBBE4FD096A
-:1016D00027ED4F9FB5BE84FEDC0BF58AFE2CBC7453
-:1016E0006A4C7D0C087DF4445598B7035AF279A1F1
-:1016F000DDCDE6CDDF67983BA17E59BEC475179757
-:10170000AF54FB5EBAB445BB80DFE51AB383C4882F
-:10171000F6AB09FD2B2F5E2BFA1DB225C6D906921A
-:10172000DBC947DD237AF728CADF5EB64F87CAF5E3
-:1017300063D0CE6D933CAB715FD747CC6E9EFDEB13
-:101740007D76F89D94A69C3DF7C3F5A49BE5BDACC2
-:101750003D57E88661E8AF64FB1D5B72D9F9682DDF
-:101760008AF59CB4937C7ECCCD147EF5C4CF11C792
-:10177000B392FF4EF31BE54F07B74BFD69459767E3
-:1017800097E67D06EDDF3C83203E6ED9A7E33E035E
-:10179000A137B7C1D8B2730D4CC8A3F812BDB7D1E9
-:1017A000FB7E70BA291DA17C42BC73B15C58C77323
-:1017B0000FCCD7983D327F0DE34BEDD0596E875E4D
-:1017C000877B6A877EF369ECD0336EA637AD54868B
-:1017D000FA400EB508DF8FC3FD11DED7F2E2639643
-:1017E000B89DF0A73A06F61B61C81B2C66FB4F5349
-:1017F000B52BF205C7FB3D82AA7F5EE70427600791
-:10180000C575104715BF5FD701ED1BD09EAD11F810
-:101810007A92A8B80E2FD7D7329DCFFB2E2ECFB9F4
-:101820001BD0BF927FBFAEDA1BD93597D613387164
-:101830003B3B2FE1E2ED64F52CC0272102E76AEA89
-:10184000F40AFBDA05DDAECCAB2CF1409D28DAE2E0
-:1018500092B81DA98E91E8C252C437B87F0BEAF145
-:10186000F17A42B360BECFC273564F1627CF4FD81E
-:10187000A58672322727F041FADD0B3AFE93E13D4F
-:101880001DFF2999F370FCA766B279C80BF7BFE179
-:10189000E3B84B0DE6C1F3500E5B82A6E5F379F990
-:1018A000E9999F819CEC20EC776F417E13D7ABF7D1
-:1018B00070FBF0B3C9A11268AFE6A72BBAA7D14F4E
-:1018C00036B5ADC5738A175E11FBE865CA1F92A7CE
-:1018D000E37A60CBC3D679E4071CFFFC3C53ACF73A
-:1018E0005D1E8EA0F6EFC64CA48FD9BFB097FDBE8B
-:1018F000E7DADCC2EF31F8481DCC29F1736A6B3CA2
-:101900002B6AE0F70ABFFC74C15C38D74AE7F67966
-:10191000B1B74B5F07E30ABFFF94C49E378ED8412F
-:101920006ABD2DF354F2FCD42F65B2F993EAF1B2FB
-:101930004CA6BFCB81CE7D93CD9B32E7FDFDECA3C2
-:10194000B043218DD91BEA3785C16F5A3DDCDC03DA
-:10195000D35413D9530BEB1B542E3700BD5F701EAD
-:10196000E8613F9D129E06ED5279BC83CBE3462E83
-:101970005F777279FCF2A7E9D76A687C5E6AFC2916
-:1019800070B8C0DFD4CE7F2B93E1649FFBB399374F
-:1019900076F0FA42EECB9C376EF90CDAA778E3FBCF
-:1019A000C0C7924C3226BE7D94CBD5639923F8F6FE
-:1019B00031F86EA1D37C3C33116F949CF803E4C9D9
-:1019C000C5F14697CAF1869618CF0E50FCC5F3EACA
-:1019D000D6DBE6C7F5448F25C7216599237ECACF9C
-:1019E000D0AEEC6238A46C846EFF4004F4701AD759
-:1019F000F737983D5EABF7AF07FB7C3E8B7D1FCB87
-:101A000062E3F81CAFEF6DC59534BEF942E608EE0F
-:101A10007901DBBB8FB5A7665CC77EB743D815BB22
-:101A200082ED88F87059B6B59D79D9360B4E95DBA5
-:101A3000E98EF7AB1BE5F81EB1EFD7EC81760371A9
-:101A4000BE4613F90AF6C5363F819F1CD7A5C27161
-:101A500009FC7B05FBD3CADA19E15F28B99DC5DF14
-:101A60003564B8F475A02F957CBCC5E5E37771F9B2
-:101A7000F81D978FDFC37737CF60E370DB24EB7EF1
-:101A8000F277F977F7723E89F192E9FF7A362B37D0
-:101A9000C20FDF892712716DA0386B7513C42D5BDF
-:101AA00055BFCD375ADEE87F336D09F6581F88E001
-:101AB0003C510FF296C4EEFE25CEAFBFE0B8D43055
-:101AC0007E75A5F0E3EECC66FDBE257F5FCD646834
-:101AD0003F7CC9F27B2D5FD8D8A526FA09FF1BBE33
-:101AE0005F0B5400800000001F8B08000000000006
-:101AF000000BE57D0B6014D5D5F09D9DD9D94DB275
-:101B00009B4CDE1B48C224040D1A708110A304995B
-:101B1000BC780688BC4445591E86F04A22624BAB0D
-:101B2000FE2C2684A76DB43EB045BB2054AC682380
-:101B3000A64A31D00D08E2B3A1ADA2B58F2008A806
-:101B400008216A5DAB7EFCF79C7B273BB3D905D4AB
-:101B5000B65FFBFFF1EB77B977EEDCC7799F73CF08
-:101B60009DBDFEC3E373350721E7E06F44B0AC4A87
-:101B7000B010924C48FD0CF741359F10AFCBE2DE20
-:101B80004A7AF65B1E2F63BF51D93E298EF67BE35E
-:101B90002C5136D37E374C11345F1E21233B89E60E
-:101BA000A3E37F192F103294104591B0FF1509ACB3
-:101BB0003E4AEE985B1966FEBEFCF9689568CD74E6
-:101BC0009CD10AD17684E977295FE7A8E8F0E38C15
-:101BD0008271E8F331848D13FA7C1C7F3EAA24FCC9
-:101BE000FB97C1F8741DD35DCF94271058CF26AB57
-:101BF00087F6CBB16AB90A6D5F53D2B128DC7B4E50
-:101C0000A9240F9E4751D059071372337DD742073D
-:101C100098494B9996EB45CF6085CEEBA1E070D10A
-:101C2000E7B45BAFCA01840C726843A0FD8B282D1A
-:101C30001FCA7C491B0AE3DC6BD50AA04E889F9023
-:101C400002422610F637C1EEF08BB1F41F85D65351
-:101C50001D76D6762E1BFEFF0CE5F8E58408C42F12
-:101C60009CBB1CEA3E11C6BF5A3DF8B640FB5FADB7
-:101C7000BF77520A792F5D391EC3EB22AE0BE1B359
-:101C8000CBFA90EAB0F4DCA75EEE7278EC0087BF86
-:101C9000447BC6C33AEB5D9B1D2A85F72B9E66BB32
-:101CA0009BB61F8E2308C7BFC66813613FF5BB48AC
-:101CB00075336D176384BA6603FCA6280C9F531511
-:101CC00086FF36499B0AFD47D8B56930EE944C8AA9
-:101CD000273AEECCC48EA546B8CFE474309DE3EB32
-:101CE0006699F50B5DE754DEAF4812BC31B026C7EC
-:101CF000C163620A8507E9FECBB1D0FA58F8974A6A
-:101D0000FB9D54A64D4FA2385B2DBA2DB42EE70A89
-:101D100048CFA1E32EE2EB9D2B572E82F512B54E54
-:101D2000AD7452FA90C3D3C731DEBF3C025D66F199
-:101D30007596C1F330EFA771FE284B6A13097DBF7A
-:101D400088F35B68BF490922E36337191D6E9C7AEB
-:101D500085D13F5D773DD297C2D69D63AD5C09FBCF
-:101D600098A11C2A8FA7CDC5F7244D2349000F0B3E
-:101D7000B165219CEC84C249E270A2CB24505F6221
-:101D80006775297A1189A365A6CBB76E20C0AFC14C
-:101D9000EA5669FDBD93EF8984D2D9D6FBBB0442D4
-:101DA000E5C5AE4E4212B3601C1946843FCB39A143
-:101DB000E778F4992AE9F351D05C739268364ABF08
-:101DC000D714764E22B1A6F7C9393A9EA3B3DD2BBC
-:101DD00000FEECC41B730592F11F735270541C2F4C
-:101DE00095CE0BFB913F253ED88FE6F2549081842F
-:101DF000C47776FCAC16DB1DEE51B82FE2007E0BEB
-:101E0000EE7309F29FBE2ED9D1F1D88F69FFD6CFDC
-:101E1000A2DD77C3BE3B477EC0D643BC4EE06BB16C
-:101E2000C2EDC983F76CB83E0BFD0FF86C7880AE3D
-:101E30003797AF1726C937AC9FF4DCCF7AB1F27968
-:101E4000C0C74C3BD16207A37CD809F5BE56DA81E6
-:101E5000C2B151117C5EDAAFF1FEB9ABB3405EAFF7
-:101E600097DCFD08D039D929503A1F46E75D46E591
-:101E70008E5C481C0AADCB2EB6FFC67B9236C508D9
-:101E8000F05C2233E8F3619DFE2F040A8758575512
-:101E90008542F721F3F7050A38785F501532633031
-:101EA000D06DBB48503EB8101E3AFF689712E1381B
-:101EB0005D373C02FA2A9388D74EFB0B2E36EE355F
-:101EC000A453247D010F5411D0B284B8B16C143DD9
-:101ED0006F02FDD9658A57BA7EBBC5EE5B2100FE55
-:101EE0002A5F1B8D702F538EE706E5592439049025
-:101EF0003BAEC355FCEE72AF7C6978BEFA30C83792
-:101F00001F32B94CF986CE33259BC99DFDCE8E1963
-:101F100046BE5FAA30B9B494F33D91189FCD95B5F4
-:101F2000B380C7487CBE8CBF9706CA07F89884E781
-:101F3000E39FC7B3F54CB9DBD7D88BC26F4282E0C1
-:101F4000063D5CBE7D96D45B0DF693B9BE3B97AC67
-:101F5000917894C3EE93BE24D03E32EAF7C677C898
-:101F600074187F16979F27F8B8EFC7B375C4703DF4
-:101F70007E44704E0F0717677CB71C74C2F8C4C349
-:101F8000E022C60CEAF4D379486F3E8F55C079DA67
-:101F9000B2997C8C4F30CF13CBE53895FBC9F12833
-:101FA000F77DE9D0EF152B5B5FE8BCE9C179D37110
-:101FB000DE456CDEB120E781FFD5832F829C2FE2C6
-:101FC000743AB6D343C0EE011EB61404E5BDACFAB4
-:101FD000C53ADA5E1441CEF70FCED31FE7A9637876
-:101FE000DC9EA25D06EBA476C1E550B6652B282FDA
-:101FF000DFE865219B295FCE4ACBFE11884D7D9C91
-:102000004D7C9F6D598DAED9145F722771DB90CED8
-:10201000AB51EE1571F952BFCB43E0B9B7179599A3
-:1020200086F7E5CED976E2C0ADFCCF39BD3FF051A1
-:1020300067769C270C5EF472DD72268A88BA18DFF8
-:102040005BC2DF0BEDE778606F0C8CBF16FA5F4A5E
-:10205000F996EB1BBA615CDF58CE3BF59D9B633A6A
-:1020600068BF5DB9734CEBC1E7948F1A731F8B0186
-:102070007BA93583EA0190532F8B28271B9D0C8F5A
-:102080008D6955C4638073A9CB2F1E8771BE9A4397
-:10209000A651FC15B93CE4126770DD45B9555E21C7
-:1020A00009DB9F8BA2E3CC89BF04E946CEF3909174
-:1020B0000E804B33A9A2FB9715BFE8A6656927F1EF
-:1020C0008FC887FE54CE0B6C3CD5691C8734C3384F
-:1020D000B29BD203BCD7E9C7F5EC3A797E383AF225
-:1020E0002C26F9ADF325B5EB6A802ECA946BCBE2B2
-:1020F000E9F80BB6670D16E9F8235D6DF2EC3C9438
-:10210000DBB5401F9B92B53AA49FFF257B6E3AF149
-:102110005901EFA332991E985023F83653F83486AC
-:10212000D8098D9C4E2F0DDA37AB61FDA450B71343
-:10213000B435F1E7B783EF893FBF1DFC93F8F07624
-:10214000F0FDF1CC0E7E209ED9C10F4249EDE08713
-:10215000E2BF831D3C5C21BA1DEA43F8C7B37AFD98
-:102160009F983D1ABAFEF9F1CC0E5B4DF7DA0E746A
-:1021700029F92446E78C4FAFE67C3AF624E597BC74
-:102180009EF4DF4AE9DF4BE9AF8BDA4D6256647AA1
-:10219000F25F245F163FC0F8BEDEB517F9EEB79CBC
-:1021A0003F5BF9FCADB96205E0F315222AA2D073BA
-:1021B000BCC60C8F0BE47A28FF695F99E9B9D4E5B6
-:1021C0005B3F18F8E6E01C372C2B941F655A560D20
-:1021D00008AEFBF79C0FBBE51311A49117C1873024
-:1021E0008E6700D819F112F05F3D61F37A0F8AA86B
-:1021F0002722F111A59B77E30DF31503B00DEBA793
-:1022000074F367C02FE5B3BF7C177AF93EA70FEAD6
-:10221000871C87F192787D5604FFE2E3F86EBBE0FD
-:10222000639C7706D343CE7895BD479264D02F9AAE
-:10223000989109F2858E7B16C6DD1377FE710341F6
-:10224000BD1340BA5DC6C67D1E8CECE49EE38E4A8B
-:10225000A0F6479871EC5C8EDF10C15F50B85D430B
-:10226000F2BAED136B02FAED6C7D4F246BB684E489
-:1022700020DF1471BBE525C1AC9753B93E57B83F79
-:102280002726B0FE646EF7B80A8CA3C353B7036663
-:1022900071F9A08F93C4F92F2E4161EBAA66EF1359
-:1022A0005E1FC9FD270A97DEB82E3B7B7E21BFE863
-:1022B0002E85C52D2671BBAA1336C8F41BC27574B2
-:1022C00024BF2B68F7F507B81037EB9FC6E143DB57
-:1022D000F3B0BD82ADE352450D1B3F88841F1DFE48
-:1022E00052025F4F2E1B9F78BBE17625EC53A797D8
-:1022F0004870DB13C7E056A0C3AD818F13220FD601
-:1023000049CD7625CC3E47727AD5EB31B966F910C6
-:10231000299E9215D413E3111FF96CDD91E22BFD78
-:10232000F87E2FE378A0EF4D41F839D87AEF52BA12
-:10233000DBAFC3F67436DECC60FB0D388F8BF58FC8
-:10234000E4F7CFE4EB9A9AD08DA759385E127B2F31
-:10235000349EA09737F2F54D0FAEAF1ADFCB61EF89
-:102360004941BC2FC4F6D1ACFDFAF44D65C92AE051
-:102370008D8E037AC2C5F4C10DD56DA2D1DEB93EF2
-:1023800042FC4DE2F35605D7FB7DDCA7C6F67F2263
-:10239000AEBBFD87386F119B3792FC3811C7C6BBA7
-:1023A0009DEFE31AF08BE918F101922B2581D714E8
-:1023B000ED1E45BBA406343FE88F924F6515E474CB
-:1023C000B9E8F00A541E4BAA1DFDE4288968E0D73D
-:1023D000B67DF63D57471ED6FDA0D7574515DBC144
-:1023E000EF5C9D25B9411F16DF2B31FFFA9405E5FF
-:1023F000FD4871118EB357D1EDDC5B4D7EB4AAA8B8
-:102400001551B00EBB4854E6FF578CA7CF477079E3
-:10241000BDD79E6881F18665B078C108B50AFD75A3
-:10242000F215F3A335FA1F93DF1AEA6599BF27A5C2
-:10243000D711014BB3BF2D93F567C581A817D08E77
-:102440001AD669F6BF6575E409185F2686F7E8BCF9
-:10245000DB129C49684FE5907EE728FFD872056241
-:10246000BB02FC6CCF76C0CF18B54A29A1FBB1A541
-:102470007BEC208773ACFEDE104F684897DD5E6012
-:10248000C3FBCBEC59E06F3551FF1CE1A0255C3B51
-:102490002088275B9146800E294E90BFBA4B072BB0
-:1024A000854486C7B7136C580EE275FD7928DEB3F4
-:1024B00013A319FF13BBF7582EC80981C4513A5C06
-:1024C0004C3A32811EC534C6E735968E14A89F213A
-:1024D0009D2949B4AC6F924687F37FD6F1B8D41AE0
-:1024E0004B787BE95EEB9857010E12C40DAEC0B875
-:1024F00080C7D637183FD0ED553D8E10C96E6D148C
-:102500002BDF04BA1614FF17D0BFA7FDEB65FB4EF7
-:1025100067725A2FF5758C4F64FC6E4BB463BF3DE8
-:10252000779692D92AE2E908C7D3C12B012A5973B9
-:1025300015C0D3CB590FE6405CCA9E757F12F0E7F9
-:1025400068C2ECD372FA8E8B962B1D9E9309067B84
-:10255000634CCE2CB49B8A32EBD09E5A15C12FBD52
-:1025600085AF43E27432C8E1390BFBDA7AFF123BE4
-:10257000BC2F2995D150EE094CC292DABD9FC0F311
-:1025800055E9AC7E213CBCC4F939D2FA47815E8062
-:10259000784D7AF73E84C4647CEE950707F761585E
-:1025A0009F3531CCFA3EE5FA485F9794C3E932D7BC
-:1025B0004C77457CBFA989BABF78D174F7D6C5D00E
-:1025C0005DE87EC7642D1DDD9F04D7AFEF57DF3F69
-:1025D000DD6F1FD86FB9C4F6BF55F168300485B3FD
-:1025E0000AFBECB12F7B78BDEF48B47CD3FD3C985F
-:1025F000D0F7E2F7F30DC69D96F80DE0B47FB8E68C
-:102600000279D2904CE993E2A94160A5DEFF0B6EFE
-:10261000A7FDFC9BE32BA5DF37D85FB14B7811F406
-:10262000E108CF9152D86E59D120503BC08F930111
-:102630000F2579F74AB369BDF1CE39283FF70FAFBF
-:10264000C375AF729AD7AB9742228FE3676AC87F90
-:102650000D9CFFCA09F323F57E4F72F918CA1FA11A
-:10266000E385F2F54A873617D62524323D1BF4FF61
-:10267000DA45A3FF57C2F5D770FB6DA6F8C770EE19
-:10268000FFADFA34DBE1A51BEDA27AED9FE2FF7D01
-:10269000419F809F945E6237FA7F0DF6526C5F9582
-:1026A000A18DBE2209F4B1E8BE9B20FCD01FF40A24
-:1026B000A2B2358C3FB82A43F68FA0CF6D0AF90538
-:1026C000ACAF94EA4B88BFD8148D5C32A0A75FB83A
-:1026D000D75E4A206ED2A590E7C01FBBD07E1E48B1
-:1026E000BCC464474AE017F2F1D12F54EA4807C648
-:1026F0007B4A09D835D0AEA25DA5118F13F408F539
-:102700000B0DF2A9CB7E1BF27BE87C546E3D027C64
-:10271000DEA0303E0EF507BB389FEB7236941ECA22
-:102720005D8C6EA2E8D2AD4C6EFC2271684FBAF897
-:10273000E6F2696E19B800D79115FBC1559B1AE8EE
-:1027400094C0E59993C8F8A9D2F14C033CD7C70FC0
-:10275000C50FDDB906F174B06758FC86DA6BD48E0C
-:10276000B2527B6DAD109C7F0DA78348F888A4AF53
-:10277000F775CBB5D038D16DE6F317C54B920A5833
-:102780005C9F8481BFC8EDA4D5945FE0FC668DD5C5
-:10279000ED02BFA2BE5FD1DB1EA0BF7E32B377A425
-:1027A00026D7B561FC90B511E2DAEF2526203CA3CF
-:1027B000732C26FB8C7A0626FB31D2BE095F9795D7
-:1027C000EF4B0078E61AE119B2EF3205F70D663DDE
-:1027D0008C1B6B71133FE58BD84CE24681156BC1A6
-:1027E00038ACCEE70AE7735D1E3814F6DEB0A4BE3F
-:1027F000EC7C4F74748A145FEB92A83D4DC7A9D747
-:10280000F6A25ED5DF8FE3FB770C67F14687D3AF87
-:102810002861E4DD8F2F80DF264D8A2FA3EBFBB1EB
-:10282000C2EC6F69B8A5D287F12816AF5538ECC451
-:10283000E27C3BD8ED05E0780F85F5EC508C712BF0
-:1028400091AF27C649D7731E39B98AF3B75EB7A9C6
-:102850001D65B07E294B53E20DEB1F94A4EB9576DA
-:10286000E4EF48E3DDC3E5BC2DDD4DAAE8BC768787
-:10287000DB0FE75A36ADAA00FC05BBEA26730CED68
-:1028800076AD6088CD80F7A67EF2F4707CB92089A1
-:10289000C97FA7A455C27B4E4522704EE6E4F6726E
-:1028A000A47123ADE342F38D8A349F1ADEAE884DC6
-:1028B00062FC270DDF5109729A0C9048BF307A42B2
-:1028C000E0FD62E50E15F88AD2A327DC7867126571
-:1028D0000EEF7F117FE8767771CBC16CBADE7A8715
-:1028E000E416407E159E6C570D7281EAF509490683
-:1028F0007B59747850BE892A3B771F6D63FEF6FEC4
-:10290000E1E673B2299C5E5EE56524B97079928533
-:10291000DB4DFF9A7D7E53FC0D4A2226B834015CC4
-:1029200008F0D77D0DF561E42585CF926F039F6593
-:102930009CBE1EB9007C32FECDF0B9105F07F9CC09
-:102940004B8E86916FF54E396D8E89FFA91D12A1B0
-:102950005F95A13D121FEAF4310AF002FCD0A49960
-:10296000E2027292B79DF995B79BF59CB8C8CDE588
-:1029700033F9AA808539E12FDE41FC31B1C1F1E59F
-:1029800032733CE1C9241E17882251009F2EF72480
-:1029900001F214A22C3306410834853409A02752D1
-:1029A000609C81D44FE6F23C540F266BCC4FEE4D29
-:1029B000EA04A657D2717D497C1DA17A308DFA3583
-:1029C000108F0154833FDD5B82182F3CD5F01C5CD7
-:1029D000F05AD05F76119F00E3A7930E2CFB402A9C
-:1029E000021D3F8BB40B39147FF796570D02F9FD8A
-:1029F00062C83E2E648FEAA56E7F2CFB37C1FB9D1B
-:102A0000FF5E78AF2835C0BBEB3BC27B0A973BA18A
-:102A1000F1BC31DDF1BCA617310EF715B33FDABEBC
-:102A20009631BED790C5E279E562C506B0E7C7A882
-:102A30003201FD26E576AC833C27DDEE049704E207
-:102A40005C7ADCCFDE6F4EE560782E9D4438E1D9AC
-:102A5000908AF2CC998CF286D91123F8FAC7A8553E
-:102A6000F62CD5E83F3599CECF644E07635C25E858
-:102A70003F357C757EBBE362FDA43DD2030EB06B97
-:102A800074FFA83E670EDA3DA1EFF9A5A63F435CAF
-:102A9000D29F6353575078BCCCE5D5CBFD1E928CAA
-:102AA000E7BFA17E906E578DE0EB2FCD997510FC9E
-:102AB000AE31CA6C06130E0799CFD3E0EAC273F0A9
-:102AC000DF7E65417FAB8BFB5B63B89F05FE4E9558
-:102AD000B3E73E87279BCFD574FF694CB7FFD4245B
-:102AE00019FDA73111FCA7D1B6CE57AF80BC9057C6
-:102AF00045CC0B8904DF50BF2954FF8C4E667A67A2
-:102B000076323F270A81A71EEF0B3D976ED4F94F0F
-:102B1000F20A46FE0F9D5FDE3B06CF05896288C73D
-:102B20006607E38982E625CB0607E38761E2863301
-:102B3000920D71435D8FE9746CA37DED78CE1C3EE0
-:102B40009ED89A75A02FF30B5F4C04FC972B2C6E2C
-:102B5000A4AF8FFA85F3930D7E615127D3DBB6FFC7
-:102B600053D7B182C297241037F30FEA547B3EBA91
-:102B700013896B591C1DF3B4C638048C874BFE288F
-:102B8000AC979D72FBA268DDB6F76109FC84524ADE
-:102B90003F5142907EC670FFA221E7E83AA0AFAE57
-:102BA0005392FB7C7E7799430CA1D3E8601DE55BD3
-:102BB00082A9BE5AF2AC647CDB2B086F11F2C1B261
-:102BC0004DF9675B25AD11F63DCAAEAD4AFECFC4E7
-:102BD000FBCF605D8272E05BE13D380FD30760B3ED
-:102BE0009134C37C0EDA7815CCA322FD77C7A59764
-:102BF000123C8FD90638033FF763E28338CB0BD6FC
-:102C00009744D0478D7C9CAB49932AF765EB857E32
-:102C10004F6C756D5A0BF238390BC77BC1E1590FF8
-:102C200036E4C12DD22088DBD4ABCFDA217F76EF1A
-:102C3000D6C6F40E03FF1D7CC2D3279C7FA897F451
-:102C40002FCE5288FB8A65A5265A5CD82E42BD87B6
-:102C50007DB6A54581799ED86A0F6B4775713EBFD9
-:102C60007A0BB36B47E75ADC1402A48878A50438C2
-:102C70008F7113B79F36C40CD8D15E02BA284B446B
-:102C80003F9FD6F7C5D27ACC500DFD83FE0376E088
-:102C9000FBFD3F2E71B33C4AAF6330ADAFCB2D1976
-:102CA000BA16FA477BDE04FC513DD324A13E6D8E5B
-:102CB000813C8098019392A98D4B620452192E0E8B
-:102CC000F84132B3F39EB0EA7095300F72EF5619A7
-:102CD000F9EB609A88FC46E1B608EA7F4F8B2194B5
-:102CE000124999E62D03389693E67AF0A7CAD46B79
-:102CF0005F8C25DF027EF93B14E0FF756087875902
-:102D00005F1B5F1F0A114A3F07B634DC40C2E45123
-:102D1000EB74F88B18ED1380C31A7EAE4B5C939066
-:102D20007E22E3FB6EA41F67B3BF3E9AC2F1EAEDB9
-:102D30004DBD8CE3EF4F564DF1371DDF90FF4CAE8C
-:102D400080FC5B0FE6D3D69FB420FC5EC9137C02E7
-:102D500085CF815C91DA6C745539765F3F5A5FCFCD
-:102D6000E9B862FBA1865E00A494245CEF2BB98FC6
-:102D7000D9597EEBC5C7AF87503E5800E7C9141F2D
-:102D8000A394689F4AF1B51086C887FC1CBBCF4F3F
-:102D9000E76B73B697C6D1295E4816DC9B815E72DD
-:102DA0008902F2035D100B439442EB2032909E9215
-:102DB00008E673AD2BC8DB0CF2766DBADA0CF98637
-:102DC000BB07D831DF2C349F78B750F7623CE499C9
-:102DD000C40B28AF0FE4FE1ECFE90EA4DB08D02BF6
-:102DE00026FCD2E70D098C4F63F2CDF6677E4A16BA
-:102DF000F7B389D756105C574C8E5D8BA284F45282
-:102E00003C7BFF608EE0037A3BA872F940F7BB156C
-:102E10001201A91D346D4064BCBEDC6F94AADBC5F1
-:102E200082BE4F4BCF7DBC20F85667C33EFAD37DA0
-:102E3000D0BA3357C0F99DCADA5B099685F3E01C16
-:102E40003374FD35298C2E654A76B920DF9A578F69
-:102E500031E6C7C885B74E70C4621E13DA95A9B9AA
-:102E600002D35F27D9796E8FFC6C857864137EA8B6
-:102E7000D591121C2FE6D3E7BE0FF9BFE30A057FF9
-:102E800014AC87E737D3FF6B03FD22E7CC62F9D799
-:102E9000B99B703F630BAD6E38CB19EBF03595D015
-:102EA000FACB1F4818CF1E97330AF3AB43E75FAB4B
-:102EB00010FF680ADF97F3248477D4258FE1386FF9
-:102EC000E45950DE8C837C6CC85F36E655A33E34F3
-:102ED000E7738F13FFAC1543B39BF12B91BCBD403F
-:102EE000BE4F7099E1E73C693E2FAEC8B799EAE35F
-:102EF000F2E49078A597C58733185DBCD45FF06D78
-:102F0000CE0AD2D9D893093EA033F8130B4C7034B3
-:102F1000ED33A653D6007E07FB3FFE1338278951B9
-:102F200057DD8AE7E01CFE3A9DC470BC3BD39FFF8F
-:102F30003EE8291DFEA17470F1F8BFB6B218F09FEB
-:102F4000AF9FDF87E03F04DF1883D4F7D1B727DED8
-:102F500071FEAC9EF8D6E9A0C7BEEF69599D4DF150
-:102F6000FA8A933E003C6F927D770B413C5D10AF37
-:102F700039C548376B952607C8FDA84B8E3AC0DF88
-:102F8000D0E98288ADF946BFE39F85EF92F50273E1
-:102F900026DD820FE27ABF83475705E77936A53BE6
-:102FA0009FE8D914D013952C8FA35E1BCCEE5DE562
-:102FB000337DDA433EA4B07B1D6DD697D2CF97A761
-:102FC0005AE1F010381FAB877C3BBA3F79FD2CB833
-:102FD000D140E429B3505E92F5028BCB17FD01E599
-:102FE000FB5C976FA510663EB464709D2A937B4589
-:102FF00089D89F4CD7F3922A5FC5F54F61F58B5D59
-:10300000D7EBFFA4751DA0B4420CFEE7446E37EB6E
-:1030100076F70407CB3B9C5024223EDED822F830C2
-:103020003F92F6F3523A59C0C97622B703BB0A9FC2
-:103030006D1CA4823DA899EC4EA1A80DEDBEB8422E
-:10304000B33F18AF459BF09F383AC1544FAEEC6583
-:10305000EA9F3A3DDB1C57F05C667ADEBB7AB0A98A
-:103060009E5177B5A97F9F6525A67A9677ACA97FF3
-:10307000DFD5934CF57E4D3798FA5FBA61B6E979A2
-:103080007FDF02D3F3CBB72D31D50734FFD0D4FF88
-:103090008A9D779B9E0FF2AF353D1F72F03E537DA8
-:1030A00068FB4F4DFDAF7C7BB3E9F9551DBF343D47
-:1030B0001F767287A93EBC7397A9FF88C05E53BD77
-:1030C00098BC6AEA5F6AFF83A95EAEBC6BEA3FCA3E
-:1030D00075D4F47C8CFA91E9B94E07E3723F31B5AF
-:1030E0008F777F19724FA712E59B0CF180BEF0A875
-:1030F00009CB68D2CCCE75483B962F1578DCA94019
-:103100009F8F7A1B2121A9DEDBF957389A7EA3B065
-:103110006F1CB39F3462949F7A7E2AF55BBC5194F6
-:10312000146203946E8750BA0B08582A012A591367
-:1031300021DE138565422011DB1303F15826057A41
-:10314000637B72200DCB94405F2C53035958BA0215
-:1031500097639916E88F65AFC0107CAF77601096C3
-:10316000E98161D89E11B80ACBCC4029B6F7091481
-:1031700063A906C6619915188365766032F6EB1B64
-:10318000B816CB9CC08DD8DE2F703D969704E660B4
-:103190007969601696B9818558F60FCCC7F2B2C02E
-:1031A0006DF8DEE5815BB1CC0BDC81ED03023FC045
-:1031B0007260A01ECB2B022BB07407D661BF418179
-:1031C00035580E0EFC04DB8704EEC5323FF0336C3D
-:1031D0001F1A7818CB82C063585E19D8846561E0E5
-:1031E000492CAF0A3C81E5D58167F1BD618167B0AB
-:1031F0002C0ABC80EDC303BFC1F29AC03E6C1F1104
-:1032000068C3520BBC8AEDC58197B12C09FC01DB68
-:103210004B0387B02C0BBC8BEDE58177B01C1938C4
-:103220008AE5A8C0112C47073EC2724CE0032CC7A8
-:10323000063EC1F7C605CE625911F812DBC707BEBC
-:10324000C0B25BDE45CC57F658D09FE57E6A647FFE
-:10325000C18B72D2CAEFC5416E35E6FFD709BE51A8
-:10326000943452933A305E682DB461BCF026D26932
-:1032700065E7D0ED4ED04B6D579D488738DA1BC9B6
-:10328000FE0C63BE8395C701CAC553188F9A90B4CC
-:103290003719F4E94DB419F28C88760EF32027F033
-:1032A0003CC89B24EA60D1A51E8211AEC27E7E1B63
-:1032B000ADCFA820DA60DABFF12A1BDE2F6A1C4CE2
-:1032C000FD205ADE93C5F2657DA94C5F3ECCCBC78D
-:1032D00053D9F9CB5F0B589EEB8C5BFB317E2A4BAD
-:1032E000BC80DFC4E0307420CF8F757466627EECE2
-:1032F00045BEF7A714FE1EEFBF3CB5F2C954BA0E87
-:103300006F09C9AD7304FBD1F6A723B43F03F220C4
-:10331000B47DAF85E1C3FB96C8FD84CAB849E7F127
-:1033200013DE58DE7ED98BFD82F5DF45F043095967
-:10333000C1CE0FF77E50711DD587130B4537951CF5
-:10334000E4CFCB770E3FD68FCD0B71506F8988F1CC
-:103350008B194587F627D2FA8CA5F19877DFBDAE99
-:10336000122B3E9FE07AEBB217E9D66FAAFBCDF0A5
-:1033700063A6789307EDAEDB388D12CDFA8F0EFD84
-:1033800039D22B8BFBDE0693AB20FFAC386EBB66CD
-:10339000F59D2F3F866836A299E89EC16B1DAC1F34
-:1033A0007C7F62B7C0BCB1BC0F852BEA7D6FACECF3
-:1033B000AB17C07957E380EE62F23AC9F9E2CB006D
-:1033C0004F092E4E920E07D83191E029B8581C347F
-:1033D000AE487379297E1ABE16316EBC2FBE4001ED
-:1033E000FAFF91232715F843E2FD1ADADEC1F856F9
-:1033F0005C7E27F13A58FC5EB5C139BA1DCB95CB3E
-:10340000DD58362C2FC4726DFA7D76889788C9985E
-:10341000094CA232E6623C489FDF1A3FDB5EEC2695
-:10342000E4CB87BE1E07212411E20CD444F89AD6BF
-:1034300057509FE2642AA3CF375CC71CC00F2753A5
-:103440005596876F61E7C631F97E0DE28D316EA525
-:10345000445283EDF89784ED9BC11F798374AC9F30
-:103460000C70D4D87D8C7A7EDFB4BEB81F87ABFEDB
-:103470005E08DE43F02CCA6E3CB716A369FFBCC8D9
-:103480007875B9585E02D09744E9EB6FB06EB037EB
-:10349000B5180B8CA7E3B74BEAC47CAA7A217CDE73
-:1034A00065B68BC987064553CE778E4214E91F4611
-:1034B00079EAC8DB1942CF0E94AF58877C2E2EAF25
-:1034C00076A46AB92E3A7EF3355C0EA427A01CA020
-:1034D000EDF75D4DD7BBD3C2FC146F828CFC4281EB
-:1034E0001087792F76356ED279F220562D5734C950
-:1034F0000AE7036A1CC06B15CFD7831BCA4639F095
-:10350000AFEA1794173E961719D27FA785F3557423
-:1035100014EE4BE4F0D0DF9BEE62F2F8C1ACCAF1DE
-:103520002E8C8FA8E92057697D22C08BEE3F1DF8B5
-:103530008AD6AFC5BAD25D9F8CFD5DAC3F26D25C0A
-:10354000841CA6EFDD80EF49DDE3CCC0BAA37BDEAF
-:103550009B719EA4EEBA079FA7B3FE173B8F5E76C2
-:10356000EFFFF74C4E7E2A697109143E95CBE65465
-:103570009651BD3D79D97C2CDF5BDEAE815C3D4E42
-:10358000E54903856B6571DF24F073268FEFEB50FF
-:103590000DF43A8FC735F7AEB68E067D57B246ACFE
-:1035A000DC82FCB4C214B7FBBECBCAE34D6C1D5524
-:1035B00094C7EFA424376FC3A1CB1A0CF6E86CE2D2
-:1035C0009681DEE7ACB606E99A18F853616D3B2D9B
-:1035D0009E1F5D0FFB582BF2F30ACEAFF184FBF375
-:1035E0006A4AE579F40E596D239E30F2B8277C08BB
-:1035F000F907E5834F1D391897A5969A3DDCB83A2F
-:103600009C22CD372F42FC5787930E6FBDFDE8FA01
-:10361000210AB3AB7D2638CEB96728C62BE7F178EF
-:103620003D89B773FE64FDAAE83C3BE03D49538108
-:10363000DEA11E4EBEE8F356D17FDD39381C7C3941
-:103640001CD65A991E0F81EFF10DFD62410F85E2E4
-:10365000EF62E15C6B23789FA273AB93C59192A656
-:10366000E3F8D57C7E923403D753CDE77B714F8C42
-:10367000DF42FB976C756E063FF84C89F7C14A90A4
-:103680004F9BAD98CF76F79E756FFD0CEE7D6CB2BB
-:10369000E299C9FC98070AE0FCF42F5C8E5205D031
-:1036A00006DF4FF010FD4F1360FC79848D7F463F9D
-:1036B000FFD81A87F03C59B6A571182D3B762FAE6E
-:1036C00080B8CB893DE30F80DF3C3F9A4878979DD7
-:1036D0002832F29FD77ACC6C1F48C1BAD8B33E0FBC
-:1036E000EA86F8D17C9FF59891CE176E33D78DF08E
-:1036F000B218E1A59699E1A5969BE025FCD6E917BD
-:103700000DF02A8BEA97047A7DBF4BC5F1AAA35628
-:10371000A6007CAA77AFC172E1B628EF31C3BC8B9B
-:103720009BE34DF5DA9D695EA35EE93AF8582CD02B
-:10373000E11297E83D46F5DCA9E55A3DD831A79757
-:103740008FC652C7FFE2E62CAFC3348EB9DED52454
-:103750008C66F2598D9B721E7E5DE292719E0FB750
-:10376000317FF3C3E5762FCC736AB9E265F3BABC57
-:10377000CC8E62F05AB42CC67B6C48707D91C6FD2D
-:1037800067AF8F901672D44EF0CECEB9F3E8ED88C5
-:103790007249FA5446FDD16AFD3BD08D9DFEEF1C67
-:1037A000C65125ACEBE3D6368B5EC8272664BB69D1
-:1037B0003EFA9E7ADCC06F91F582F93B13FD21162B
-:1037C00086F2999D8378E01C848E774672AC8638A9
-:1037D000827E0E520B13D1BE8BED1DB287367DDC7F
-:1037E000D2F7BCF7CC299EB2402F57DB9B6450B672
-:1037F000D5CDFDCB809F3E6EA94F01F9B150ECFABB
-:103800005EB8FB5EA5699C6F7DD64EB3BFE8D3D78B
-:10381000992599F88C38BAF74DEBA722E40B8F4F16
-:1038200063F66CCDF6432387D1F5D7EC3C2B63DEF2
-:103830005A9A677C9A61FF023F075AB0ED888CF66E
-:10384000A7D57BC91DE7B3EF7BACD3E132E51D7A89
-:10385000493BF0E7EC42A233EC75EF5279F3C1AB90
-:103860005602E787E42BDA8B3ECFE44FE792CA5843
-:1038700080D7EC9685287F3E786EDC01967FD45405
-:1038800000F4F131B160DEDCC7E4F7B1430CF05B6A
-:103890009626EB7144BB31BF852E300DF3D3AB1BA5
-:1038A000DBE1DE988D485E2E9704F6BD1A9F80F20C
-:1038B000AC9AB57B897D05EE633593475EFA1FD4DC
-:1038C0006F6932CBA7791BCCF52A322905F2BBAB45
-:1038D000EEB7420611996F947F147E33D3581EFBC6
-:1038E0003C52D708F6DC2332C5135DFF6C8548BD1A
-:1038F000A91E5AFCFC2305B3687D791A3BDFF990B9
-:10390000FB19F3C13CA5CF172CF3C95A5ECFFD1D9F
-:103910006D19326D18C1F198DE5AA0DBAD448538BF
-:103920007E6FF85776E4FDF76E11F1DCA937B41B12
-:10393000E4F39CD5E6FD5D68FFA1FB25E43EDCC712
-:10394000826DD7A2DFA6EF47C797BE1FEBB6F0F791
-:103950007C1FE4F4DA7DBECAE1A7FBDD4FA631FB94
-:103960005DAF3787D47F1D52D7E9DBCAF99BD2FD03
-:103970009369C9C0CF9D23199D74C8C6F35039D827
-:10398000AFF97CFD6C9C5F68BF5F9FAF5F5470BCFC
-:103990005DE1FA2D7EFEA9E7C01F5DF0AB0762E195
-:1039A00030E803A92905F284166D5D190B703A29D8
-:1039B0007963816E3EF089A3C3C1ABB31B5E9A43AA
-:1039C000A078AFD1E9BF68C504D0EF7FDF6A55C0EA
-:1039D0002FACDD66F3C3F7976A5AE6E3790DAD1FA6
-:1039E00061F55578AFB276A7F53D235E173CFE40F2
-:1039F0000AE677106F6F769EEEEF0D9F0EAAD9F252
-:103A0000FE48F0936B4927D273E87B307F2001E5B5
-:103A1000F52C39AEE7733D6E5ACB9A486DCBBAB3ED
-:103A20001037AD6D197302F8BE9648EF19E9A91A5F
-:103A3000689AFA2B47D278DEDD95E44A902F3A3C1B
-:103A4000882F19E573FD130F0D3C42D7736ACBAB7A
-:103A5000B182D15FE5E7ED5DCD73FE96781EFD7016
-:103A60009AD2A9313F5E97BBEA4EBA80545A6D652F
-:103A7000E522AB3F761885EBA24D56BC1FBAE8A9EC
-:103A8000C77EF153C8237AC786E71F0B9FDAFFD69C
-:103A9000D5B4BEF0196B5205DB8603CE8375BCD45A
-:103AA000D2FFC1F9848E8705CFEE9721FF0BDAC1D3
-:103AB0003FD0F1B1F09936990CE809BFD2E636B99A
-:103AC000C311062FCD4746E23DA3273E9701EF1FC6
-:103AD000EC11486A56CFF7AB37ED473B06E08478E8
-:103AE000E478EAC65B0F7CF927ECCAC77E0AC8ED0A
-:103AF0000BE16B1FE8D564A4EBA777D17554FFC920
-:103B0000E60638543F7D5B2CECE78454C7E8FB9114
-:103B1000952990E7566DF5A62858B2F6EA476F4703
-:103B2000BA9B77E8F61476CF414BE3F91D69B0CF25
-:103B30005B364EC57D56110FD25FF5236225E4C179
-:103B40007C2691D1CF84E18FEA5E4CAF9ED84C9118
-:103B50004BF77902E46552D0DFD1EF35DFDE1D0788
-:103B600061E7909FF173C86B7A594CFAA59B6EB7C9
-:103B7000AC42B9FA6186960AE793140EBA1C45F96D
-:103B80002A1E2A4F657862F218DFA3F4570AEDD097
-:103B9000BFDD8AE7C286F7B8FC64F32FE5F3D3757F
-:103BA00047833D722285E98DD0FDDDCFF747E0C226
-:103BB0008681CE0C7CCEF87ECB1AC6E73ADFFBAE10
-:103BC0001D0DCF3FFD23E323780FF4115D973F15C3
-:103BD0009FB74D11502ED8883F1C7F6FB172FE36B3
-:103BE0003FA71209ED399D4EE8FA25F81E59905E5F
-:103BF000E83C098807B457AAEEA7EF1BECEC5A98EB
-:103C000017FBC9C1F6AC201FCFE3F2604E2FB33CC7
-:103C1000201B932F2A2EB0C8EAFBC54F817F29BFF6
-:103C20007A55E05F2BDEBBF968FBBEB76EA074FE71
-:103C300051B3CEB766791ACAB7D53B6EC7F86028BC
-:103C4000DF7E945E47C2F26D3ABF3717CAB7E91DEF
-:103C5000FF5679AAC36F5D08FCA87CFCF92E3532AB
-:103C60001C43E5E3A5BDD4B0F291FEFD9114F4A48C
-:103C7000439DFE74BA5BF0E4E23E2087BAE953A7A5
-:103C8000BF6EFAD4E92F74BF66F8853E9F02C94E15
-:103C900006FBC17A37F13A29BE3B778BF8BDA433D6
-:103CA0006A672CC47F5646919960879F51783D9EE4
-:103CB000D53B93E54690137A7B67148B579EA9EC0E
-:103CC0008C8D37D8D7475AC55888EF76F8C2DFE7CA
-:103CD000C08C443A7F4784FB1E7A3CE24C74EC4033
-:103CE0009C2F3AD307F82A171D99CBF2C10F13F175
-:103CF0003B3E73575C170BF921675AFB4E9C4EDB1A
-:103D00006F79997FC6CFAB496914CE7338DE4F12F5
-:103D1000EF8345747F735A99FD3C777D783AD1CF14
-:103D2000CDAB1C4B659047D46E0DD20781E7EC3BC1
-:103D30000BD51B43DA5BC7213D2D08A1270FF78F59
-:103D4000DE047A82B8EB203288FB2716633E48B93E
-:103D5000983711BECB79E6A08879EB5DAD226984F6
-:103D60007D6E177C04F8DB9B8C745943E58731FE2C
-:103D70007B0AE8EE3CF7E84EFDFA2F0577D02E8B54
-:103D80009E7B77E0CF6879EAB9772E7901EACF1F79
-:103D9000CE7C9784F1B3F67C7133C8FF337B6C041F
-:103DA000E32A7B5ECABC03EABB6C987774E66E9B21
-:103DB00086F6F41E27E6D19DC960F1D4FADD9F0F87
-:103DC000C47C74D2C0E8AB37BBB7D5D5FAE55FF198
-:103DD0007E6D2BDD15E8DB3D31688FD7EE8AF281F1
-:103DE000937A66F7E705C6F38BEFBA9F1A99C5EF8A
-:103DF000CF38C974887B9D896771EBDA17AE7A0C6E
-:103E0000F2E117B7B4C9706FA7F4B75F0F04797305
-:103E10006607B3234E5B3B1E256E42627ADF768FC8
-:103E200095C2F934D87694571EEFDD321ECE377A1C
-:103E3000C285C1E10C8503EC8BC2A51AE464247829
-:103E400064FFC7C2E3ECCD30FFA2D62BF1FC210802
-:103E5000174163ED4E9F5DC0FDB3F63D9F0F0479A2
-:103E6000FC51F30AD4EF17DA77F1FF73FB16FC1756
-:103E7000B36FCF7FECBE19FD1F07FD94DC930F7A63
-:103E8000D2F9F3DFC3FAD34E37AEF722F9DFDB9B6B
-:103E9000C51DFEF3F6FF2DF1BE43C0FC950BE1FD01
-:103EA000E7FFB5787F99E3DDA9409EC499DD5F67A0
-:103EB00012C3FE2FB4EF3DFFA5FBD6EDA0764B9DC0
-:103EC000924FD7F70E699A9A45CBDF699F2481DB21
-:103ED0006A8B704E73BA37F32B6C02CBFB265305FB
-:103EE0003DBED46ECA7B4AAF467B6382760FFB3EF3
-:103EF0009354D70E79A7ED2573DC6BB1C7E0B73DBE
-:103F0000509F329CD7CDFED684927107C1CE7B6381
-:103F1000055D1FE4F965480ADCE598A8896817D2B1
-:103F200012EDC137334762BF8985667FE3FA103FE0
-:103F3000E1BAE9E6E753F9F8D3C87DC910A79B3683
-:103F400097C5E9AE23752B8DDF519B1A32CE2B100E
-:103F50004033D891DF147E6ABA0EBF25080F52ACE9
-:103F60009FDB5D007E84C1BB7DCA20965F2CB919A2
-:103F7000FCA62D7663DC94FBA156FEBED5B1BA1D1E
-:103F8000F8D64ACCFEA7EE475E08CE84FBA7385E83
-:103F90007610EE564D44FFD4302EC245C7C737C504
-:103FA000838EBF6F8B8F2EC087E15C572FE7DB6757
-:103FB0002D8473083BE4BBD37D4D5CCFEE8FD8F3EB
-:103FC00004846365A115EF4DBE6FA92C00C3B962CF
-:103FD000C895353F64C3BA013EF3391CAB481DDABE
-:103FE0009DE4AB73E78A0AF0F40FEDD6F91A21E3EA
-:103FF000A95F525524F8A3E9BEE749C41B3718E26C
-:10400000A00279CF1807F599EBF0774D4A709C0B19
-:10401000F58F241FFED9E5DFA83C7A8F22FB089498
-:1040200098374324A3FF38B395C1B17691E0CB46CE
-:104030003AF25B8DE7BF0FA4B378E3DFEE1C827228
-:10404000AEF8C703E2985F9B8FF93CB5DCDEEFF278
-:10405000AA7110CFE96AED1B07F19AAE83A5B1E111
-:10406000F2780E71BFF20FCBED589E29139AC43827
-:10407000BC773201F570591401B913FADEEDE97A13
-:104080005CA68E9D4B1296875FC5F7318FBE1A973F
-:1040900060C0DBFAF11F48037BE201FEDE339CAB1C
-:1040A0007C57F8821F0B703D14D53132DCF709576D
-:1040B00071F855ECFD4286F8C1A4D62CFCBEE4A4F0
-:1040C00032D194A7BA3C9DFB5343C8105857C5DE64
-:1040D00031B157015E0E8AEE280ADFDAD6B3B22775
-:1040E000CCF95C283C617C88231FB5BAAB009E47A5
-:1040F000EF89C2FBFFAFF3F3A23CFE5D48F87410FA
-:10410000C4CF9AD2593EC8FBE92C8E3EB9A2D89AA8
-:104110004CE7CD6B5106415E592FDEFFFD74159FB4
-:10412000F7E6EFE9FD7A2D62FD8EC84A4DB8FDC76E
-:10413000640AFC3CC4FDBD42E13F0F6FC53F76FA07
-:10414000E15E5C5799C0EFCD84D23541FEE81A2D6F
-:10415000F840FF821F8BF50A01F5FFEB7ADEDD24C4
-:10416000A62F75BA0F85F36E0E677DFEBFF0FA5E5F
-:10417000AE377438EBF00D5DAFDE9FCAAB11C67879
-:10418000CBC49D839E06FBA4A655502C74A81AA9E7
-:1041900043063EACDD79AF15CE17AEE7BFCF42A4E4
-:1041A000CA81C6F3DDF7D3D9EFBCEC1B3C0CEDC7DD
-:1041B0004FD633FB589B7B3616ECA0D72DEEDF0D88
-:1041C000037E7C43347DD73CB47C77B9B2A0CC6A03
-:1041D0001C370BD7397951B115C243372E6AB3A6B4
-:1041E0001AE8E97DC8C31A1A6CEFB548C5FC453A10
-:1041F0001FAEC3FB231B817C8CBCE6F69218FAFC35
-:10420000C6BA784687D5CD6D32D6D97786F5F9F41A
-:104210007942F9694A458CA93EA7B4231DE0526151
-:10422000F32F7587A1536F867EAEF20DF58446E9B4
-:1042300076E0FF0F7AE2ECC870DF419D98D1433FF2
-:10424000A486D30F4B56A8A900FF25BBFBA602737B
-:104250002C79B93C259C7E7873393B3F3CCCF32EBE
-:10426000CF4CA1FAE10A837E981285F411FADE554B
-:104270001917A91F747CFD9BE5CC9BA01FC2F0758C
-:104280004586593F4C6B9D85FA61DA1491A8867872
-:104290005C69068FDF46D40FC529D763DDEA8E0936
-:1042A00043376F72BF04E00A25CC037AE28E0C26F6
-:1042B000F743F5452479AE5CAC3CFF5F82B32ECF6B
-:1042C0009750FF85FD0E4E281D1294D74BAE17F068
-:1042D000F74B96EC66F27CC94D3C2E19225F2B41C0
-:1042E000BEE61BE52B7BBFC6C3F441EDCEAC8766B3
-:1042F000D0E7373459DD76DAFF86A0BC2D30CADB33
-:104300003B32241DCE994A18FC4E9F114354B3BC36
-:10431000CA01397574D04B79CF02DDBFCEEE99BD9D
-:10432000CFF5F86B835ECA8778FAEFF9B89B391D31
-:104330009D5E4E1694513894CE65F6F0E2ED22C2A1
-:10434000A1A685D97935DB04BCCF3B72F017786E16
-:10435000B870373B3784EFF9161BF0B8F0F58EC60E
-:10436000DEF07C9380E79E55EE85ECDEDF061627B7
-:10437000B6D3FF205F624D74EC6682793A1AC69B11
-:104380001773B855D83A0FC0FB158F0BEE4D28D7D1
-:10439000CCF1E9C539633F00BF60E1B69076F71A0A
-:1043A0003CCF580C7167831FD2C6F7778BE8CF7B61
-:1043B00016F2027F2786FDBDB3B65038547F4738CA
-:1043C0001CA270C8FFF670A86DBD17F36FBEEBFEA0
-:1043D000F76570FB7030C9077E79DFA221FF7B5F34
-:1043E00011F15EF1DC7BFBA51AF3940E6530BBE2A4
-:1043F000758BA7310DFAD5B0FBC7F3363EB31FAEB0
-:1044000086CF682683206C3F6F83594F76EBE51685
-:1044100015F5EE8CBA6704F89EFF2D22C1DF019BD3
-:1044200033D8E681F3D743519D28CF743AFC12E884
-:1044300090C2FD0B3EEFD15E9D65E857EC1414E48D
-:1044400013F89E06D4291EA2603F577D3E92C31DDD
-:10445000E333B53B199E6A295E80CF46527B17F441
-:10446000C88D54EFE079596B9B15FA57D37E892894
-:1044700077DCE8EFEAFA09CEEF8A530C78DB7D842B
-:10448000D1EF56C14DC2E02D97FE773EBC45C29795
-:104490006E3F5C2CDE74787CA9CB6F8EBF4351EDF0
-:1044A0001543F09C8AFD0E10698DC77395634D7D91
-:1044B000118F519982E9BB32DD7805FD68882F5D47
-:1044C0000B0BC70FD747619E1CCE9BCDEC21A37C65
-:1044D00009F5A36B493BDA35629AE7E174435ED88C
-:1044E000349EBFD27DAE1BEC37392339723FE22AAE
-:1044F000C1F31F3DBF167E390AF3C1787D5F46C107
-:10450000E11974BF9FAC16F17EF27516F5AD22E08D
-:10451000E3B5560274F9C96B568DD9A13128876766
-:10452000BD7ED40AA19159905F40FBCDBA8BC9DB07
-:10453000A330186DFB13D5631A7CB784340F85BC88
-:10454000FD29EEB672C8DB9E9A7F68259CD34D2E5E
-:1045500055DE7A0BE0BB462400DFF75697A2BF7208
-:10456000DBAD02D2F5DBCBF1B7B0C8D429596FBDB2
-:1045700045E7BD6975329EB3CDD0F69703BDCD99A1
-:10458000E874C039DDB85C91780C70BC89B463DC28
-:104590006246DDAD5361BDD5542F40DCB5BAF55050
-:1045A000792AD4370AF83B6AB55E8F0C57A0DA3700
-:1045B0009C9521FE5245FB017A6A37B27EB55B04B9
-:1045C000BCDF5345E503ECAF6A8B40E022493BB5C5
-:1045D000FFEC6C5C9F9D8EDBBE91BE4FEBF3E07DEC
-:1045E00018774B3CFEDE5DED6BEC7E5055E18A03A7
-:1045F000209FAAE87BF43169DF722B8E377FA340BE
-:104600002035B8BA30EB478530DE6B56FC2EC8E15A
-:10461000B6876558F7CD74BE343AFE1CB1A31CF3BF
-:10462000ACEF1014CC83FEEA07C80767381F90D799
-:1046300096313E13789DDB85BA7EBC37339BE5BB54
-:104640002F5BD108FBEAF02667814B54BBF3AC0C1F
-:1046500076DEB1E5F0E1198A379E07B7CF7B54EEDD
-:1046600030C8A9A733FBB2EFE4EF2C463EBF855418
-:10467000E2B9B86705D3CB475646F904B047AC0A50
-:10468000EACD7D2B2F7D10F67FFA292B9E979ECEAB
-:10469000E8C0F8EC898D56FC6E48FD4611E5C889E6
-:1046A000ED2C2E243E3275641AC08FCA01A0BB7D4A
-:1046B0001B4B659087277C02BE5FFAC8ED292CEE64
-:1046C0006B961F55EA0294178F4431F9306F43F807
-:1046D000F3D588F262E94826DF43E4C1E2F4468C70
-:1046E000FB85CA895AE2D0E5C360A8B7FBD3907EA8
-:1046F0006B5EB312B0EF6A24E5E60D403733A2E0FB
-:104700002499F2857F3FC8B74F7C82EAA5CF6F9C82
-:10471000F99BA100BFE3006FE08BF58978BE5AE5F5
-:104720009B8570D5F311E76D30D3B39EF774BD4709
-:104730000CDEF3A1FFBBB13A8668867E87EFA274D8
-:1047400049E79BB953C0EF211DBEEBC881DBF3B134
-:10475000AE001DD62CE37A75BD13E9F6F00FCEAE90
-:1047600004BABCF94E01D74FBC9E46D02B351B0472
-:1047700015E29AF3EE64EFCFA3EF03BD1C7E98D150
-:104780000FA56315E8BC66E3BD07B0FF164185F1D0
-:104790000F6F9A857AB8DA2B127CBEE508DACB5413
-:1047A0001F60DED03EAF9802745ED3605300AF3A14
-:1047B000BDE8F477847F7F9AD8DD0327C3EF536485
-:1047C000AAECBE7C08DD89D3B390BE6AB75B915E6C
-:1047D0006ABD8C9E8E3C25221DEE5B79DD48A09F34
-:1047E000D35B8508F447E92B3F485FE223567C7F83
-:1047F000DE132CBEB06F23A3EB132DCC3E2D7DA476
-:104800001FFA35F35EB712167F200EA3FD71213A11
-:104810000CA5BB1E7A89D36124BAF3589BA741FE2D
-:10482000C1ACA7E9FAD520BC4A1B7F807180D2C6F3
-:10483000EB71BF3AFFC0BD16C8DB98DBB482E5332D
-:104840004A2CBFE71BAF2B641DCB339D41FA175990
-:10485000FE899FAEE3A5ED8FA11DF0F12F8F607E45
-:10486000E3C21728FE69FFD3DB9DC48F76B60FE540
-:10487000CC821611F34B89E42F986CB8BFA5E7657D
-:104880002CFC9513E1BE6087CD5741DF5FF0DCD192
-:1048900081784E7E37B353BDBF64DF9921DE8E81B0
-:1048A00093213F5362F921A1FA3790C9E230A77EE4
-:1048B0001383DF6312B6B5E139D382E6EBAC36433E
-:1048C000DCF24CA615E7A5FDD83D338A7F385F841E
-:1048D000F5197F4F42CF0B39F504E39F053BAD68D7
-:1048E0001F2DD8B609E37DB5DBCE62FE6CE9AF9E25
-:1048F0008A0538D4EE14CDF953DB44BF0DF3BCC4A4
-:104900002336F65D0E531E534D0BBBDF51D3CCF354
-:104910008442F26716FE6AF7735E0A9A85CF3E1EDE
-:104920000BFCF461FBD65880271D0FF38F2616462B
-:10493000C84FBA505E52F31A9E97341E7FA7233495
-:104940002FE943F807D5E3997D42F2BAB631B9456C
-:10495000B15F10EE1E926EBF2C7CEAB347218FF63A
-:10496000D48E8F1E85F52FFA9F4F1E85BC0EB22761
-:104970004A017BA2F6976F62FEA1FE5E611F664F41
-:104980009D7EE271CCDF3CFD8E0DEDC2D3BB4F644A
-:1049900082BD70FA992F52202F73E9EE728C4F2C42
-:1049A000FD7529DE0F8DE46F027DFA2E227F34140F
-:1049B0001FFB5A44BF83AEF3E3B76DC8FFDD7966D2
-:1049C000CD8B59FE9ECAF3CBB687CFD3D5F3A16A60
-:1049D0005A264F1C0EF2AE85E9F5EEFCA80BE595C4
-:1049E000FD91E2F58A8BC0DF769E3FD83C3E6C5E3F
-:1049F000D9C7F00F8AA76921F8FBACE5969FFF1491
-:104A00009EB584BFA7ADF3F585E0A6E701F7EDA35A
-:104A1000CDEA037CB4E349CCE303BC55A8A0FF3F37
-:104A2000CB84F8E6496B27C60D3B77DB14C8F75AF1
-:104A3000B0FB30F2CBE95F1FC23C5BC2F3714F9316
-:104A4000EE3F9637C96317B55B9C2C1F8DC31FF2D1
-:104A5000D5D4586CE779698C8EF57CB548796A0FA6
-:104A6000F5C966F1439E9FBC586D971547105F804E
-:104A70001FA110F075C494FFA7EF3B743C05E070D4
-:104A8000A531FF32523E20B7D37BE08BC9E5D39BE3
-:104A9000783E66779E2521E983213F88E9C35A9FA6
-:104AA00070381C7EF5FCCBFBFA70BF53E74FDFC5B7
-:104AB000E55D5E78DDDF0E2E0D7DD8FD001D3EA785
-:104AC000BE0A2FA79FE2FC4EFD96ED7D0CFECD4C5D
-:104AD000EEB7E87967FA7A1B9B995E3EB58DD98D62
-:104AE000A1FC5D13E1F7B45EE8C3E20D353BDB06E4
-:104AF000821C3AB5F7379CEE7CFC1ECE11D9CBE573
-:104B0000B6CF28B723FC7ED97E3E1EF577C38E57DD
-:104B1000BBFD6CD8F13E94B4EB60FD1FB6333BE4B3
-:104B2000C36631ECEF20FCAA8FD5E407363A65F472
-:104B3000BBC4D86894474B9D856FC377DD963A65B3
-:104B4000CC77A85FC1F323EE72E3EF78D43BC7E2E2
-:104B5000F74B57027C0C7EA855F1E0EF4E585D955F
-:104B6000F9E05F85DEEB94932CC467C4BFE4C5FB1A
-:104B7000BD13B23F9740EFB42F37DF1B699794FD09
-:104B80008974BCF632C10DF66E4F3A338F7FAD2675
-:104B90009AE26710AB867D75B9D9F7D09C16BF42F3
-:104BA000BB106754BB0B1D3D95FD5E35FC4C179C3F
-:104BB00083AF5D6ECF817B5CB1C48DDF1976BABBEC
-:104BC000EFCFE0787124246F9BFF5EB5830B95389F
-:104BD000A2B441DC223A97FDFE8342A2DDF0FDA2A1
-:104BE0009FC46A78AF69BDD3837A3822DFB8D9BD54
-:104BF0001A3D9E1457C8EE51FE5FBBEBC4160080F1
-:104C0000000000001F8B080000000000000BB57DB5
-:104C10000B7854C5F5F8DCBD77379B6437D9900421
-:104C2000C2FB6EDE0921591E09A82837E16110D0A8
-:104C30000511505137E1FD4AE2A396AA9505621A83
-:104C4000296D8380528BBAD050FD5AB480B4828DC6
-:104C50007603D162AB36A0566DD52E101194C70ADB
-:104C6000948FFAC3F29F7366267BEFCDE681ED3F0A
-:104C7000FDEA30F7CE9DC779CF3967660921E40A8E
-:104C8000FD7F92A6B485EC04FFA09E4C747537FCA2
-:104C90005723A4373CA77F2A211365072123E977EF
-:104CA000132C811809DF4FC9A2EF1DEC1392944A0F
-:104CB0003C41783FD5E1F1D3F60E876F0A49206475
-:104CC0004382F6A6444BE2518E8672A12B955C4935
-:104CD0002724B120E4B7D0C789A3E973DD3CE89F5E
-:104CE000E475E2FC8E9AE677543FBFFEAA33E5787E
-:104CF0003CAD2844B922D3F1ECAD84D0D2E951CEF9
-:104D0000C13891FEFC4429A1E3F0792612FA9EF6FF
-:104D1000E396362A57E83A5CC425910C1CCFF4DDA3
-:104D20000017F60F75DAEF5EF8C73584F45BA6B6A8
-:104D3000D8E83ABD76C90560E843E7DA0A40505A38
-:104D40006D008CA71CA21EB49102DA6ECF215B8885
-:104D500096CB771EC2F716A8D332395E1DDF7F18B7
-:104D600021930359DEB43C68579166F160BD554903
-:104D700025A46E9A2FCD320CA69FD5D0328090E715
-:104D8000494DBE44DFDB6BDDAD07AF27005A3A1952
-:104D900078EF6ED50AE03DAF131224741DCFC7B56E
-:104DA000D7357B1AADA7B7D7FD506F04E05F0BE393
-:104DB000B95B6BE9F7BB54EF44958E3BED190B9152
-:104DC0005208197BC91190800E42BD08E90B9FD58E
-:104DD000C4015EAEC0DFD84809F025A99176E6F798
-:104DE000E676749EE53BE9FAA7F92ABCE347103260
-:104DF0004A627025AED088E94E9847E56CB538F226
-:104E0000DDB467CEC9E9747EB3294D11FA3CB1DC3B
-:104E100075532E9D5FE2160A2D15DAFBEE82796737
-:104E20003DE2B300798C25A1FB258A4FF2490ACED9
-:104E3000478C53F79A8CF45BF79825B01AE957958D
-:104E4000BC43F5F80B99F01766F8DB7B04F157D5F6
-:104E50007484E16FEFD666C07F5593E48A51613D5B
-:104E60009E5D9488C8FD816BBCCA408AD798701D2E
-:104E7000E0D54A4679A7C4225CEF85F574802B9F64
-:104E80005F77707DFEC4B61F17D2A6FE53164F166D
-:104E900089C04BB4DBACDA102E7DD27D8F021CAA08
-:104EA0003786EA62E9BC5E3D7138C147E79B75EA27
-:104EB0005CB090CE376B0CB271FBB8CF9FDAD66C7A
-:104EC000A3FF7C1EE898BEC826BED52E4757F060CB
-:104ED000F4DD0E8F3D47103E16A8D3E7BB6D64117D
-:104EE000E0B56CAFA40580BE63C83D5E5AAE572DD9
-:104EF000B88EEDAACC4B89E1F154BAA2D2EFCB66C1
-:104F000058B4002D137919597F2DB6DBAE2A580AF3
-:104F100078087C0A3A22A4217E1AC5635A8EEF597A
-:104F200023DD3C119F4EDF8F6D3B7A3FB144BEDBEA
-:104F3000BE9278E75923ED28FD3C6CF86EC2F7E28B
-:104F40007C0591F64097402766FCD0EF7630BC3E5A
-:104F5000110FEBD8D7764E0678F714AFE6E7AD2BF6
-:104F60007DDEF1D6CEF9C75B2A7B01AEE6E7418054
-:104F70002FC2C7EE6FCB05A92D91440A6AB9AF2F96
-:104F800008F35B6E0F25CCA0F8AD2A3D6F0338AC5B
-:104F90008E3F739D2F4A3F9DCDA3F5728EC34BD795
-:104FA000B7FF520CC2DBDCFE2B8ECF7757CEF68ECE
-:104FB000A704FA785C42210A5B3F793F93EA87F1C4
-:104FC0005CEE8ECF5C3285092DC5CFE5B8742586A1
-:104FD000A0425068BB09F084CEAF7CF42E85A44378
-:104FE0009DB613F2D88DFD6E2345800F6B1B3CB729
-:104FF000D3FF811E999C79D349D02FAD4A684D22A9
-:10500000057D6B9A84FAE7C6CB0D2DA0BB6E4CB321
-:105010001AF4DC24D5589F0C7A4F37CE348DE29D9C
-:10502000BF3F8FFF0DE0FA6E56296869FF3767C6EC
-:1050300005FC74C9B78CBEDD3B5EA72F0E7D2BDF50
-:10504000E32DE8089FD16E011F2FC2F595580A9FE6
-:10505000225867452DD3495DC3C30C47335CC67FD7
-:10506000B2600A29EC08979EAEBF1DAE84FC04D640
-:10507000375993C95A7704AE66F8D0BFA9D0EE501D
-:10508000296D27815D704AB1D0FAA46B2422EC828D
-:10509000097ABCF3F999E16A869FB03726F3EFDE0F
-:1050A0000678517A9A2C6F71003D4CFA61EBF864E6
-:1050B0002AC7260D64F825410A5CAAD76F20083359
-:1050C00080EB36A43B9715ED0CAAD7197D7C32F105
-:1050D000A444C79F7289BEA3F39CA84A01CA2200B8
-:1050E00097A326B81C35D1C551FDBACDF37D05FE79
-:1050F000714D147A511A7281EF8BDCDC3E1944D465
-:105100002B541F957C3C3291C987E87A72EC256F4D
-:105110007B3F0C1E0D483712F1B53F77D17E829A46
-:10512000358582818CB3BB904FC6116D4D9B1D4060
-:1051300021E33CC5BC4EA6793537FDBE944C5AD30D
-:10514000A687F327429F33788FE3F01B47FCCD728D
-:105150000294CA05FDBA457F93C47A0693C1600FD5
-:1051600035AB2AD3FBBC3FB1BEE4641294E804C360
-:10517000923DB04D82F913BFAD57643C2BC7EFC7CA
-:1051800099D36F75A3DCAA21002F305B009F65FCCB
-:105190007D99DD1184F910BBF5543B5EC086217307
-:1051A0005CC787205CC895F8C8FC2ADC92723C3743
-:1051B00032BFD307ED7E99D2B5A7AF6FBE9BCEF3BA
-:1051C00094F47621C08BDA65D920CFCDEFCF7FD490
-:1051D0005205EF69BB05D88EAF6BA92C21DD845F2A
-:1051E0008B096C734793E7AB98FCB5534BB42442DF
-:1051F000F765718CCF2713AF02F6E5FE58C6672D11
-:10520000B18B911F26929ADAA1B4BFBFC4DD78108A
-:10521000F86C12F163BB092E231D7647A73791F076
-:10522000DD60F74ECEB59AEC683FE2677F6C4E26A4
-:10523000E8B3FDB14C2E0BFBE149B7778D1BDF0FB7
-:105240000A805C3EAA15BF0B7AA2B274C4DF46D2B4
-:10525000D262F7DA009FF381BE285C47037DD16FED
-:10526000F743D77D91BED601FEE6D69BE8CB9E8C58
-:10527000FD7BA91883799569D66FF476753BDCB808
-:105280009EECCE5E242D0AC9A5709DC7E9747F6C83
-:105290008C1FECB8B2C7291F53F8CD25BE671B245D
-:1052A0009887D560BFCF8BB5A2BD37EFE7B1C8EF08
-:1052B000F4E32D3574C805F4F95ADA0FC95507E837
-:1052C000F53A69D07D0FF8B7AB488FF35CEC591B0A
-:1052D000EDA36F2FE8974A370A4FB2D97A4E4F970E
-:1052E000E6F13BEDD7F4DD7E89CC06BDBADFAA0E30
-:1052F000F0E8F4C76E37B39BCED9B3B658D23B872C
-:10530000D3027BB2A68C88D48FC7C6CE8E66278880
-:10531000FE045C23FB8B130D2D6322FB0BCBAA2F0A
-:105320004CFB8B2FFEABFDC5A1AD5FB4D6D2F934DB
-:10533000647AFF0EF446146F1EC07D13B71729A5BB
-:10534000E44DD3E1E1EF6E66CFF45E318E1CA3A491
-:10535000146327FED8E194DF15E2B70E87F6BE5539
-:10536000168A57653641FD43E50DDA99E6F57E9CD0
-:1053700059F6198C27F8B02C8ED239E5BBC72D6AA7
-:105380006303D8D37F96A96D49475F3117EDBC5BA6
-:10539000572CC6F2ECD1CBD9C0FF651CAEA7417F1C
-:1053A000835D1DCFF8A73A9EF1CB2B69BED340FF9A
-:1053B000AD9AEC1C49FB5BBA57F6C4E0F2C38360BC
-:1053C0007DB74E9553E1F931BB15F789FB9D0CCFA5
-:1053D000C78854BE13ECDE4331DE3DB45C9056EA20
-:1053E0004AD7D9830BD2C6639D9453C38ED2DF7D37
-:1053F0007646F7C7889BCDBB5EF26CA78FCED5BB38
-:1054000013810EF75B89C1EEB0A4337BD992CEE055
-:1054100058798932E108465F3574FC4A45B5819D6B
-:105420005F79C986CF611E487FB1C67EE2793FF1C0
-:10543000EDFD48E80CD81F6BEE4761CF391D9BF19D
-:10544000F0A87B5C22AC67419AE64A4779AF2A0014
-:105450009FB2912D1F81DCEB5ECEFB2590F3D5979B
-:10546000A5E060BAFE537BACB87F3BC5EDFFD37BB4
-:105470000EF4AEA4E5F25DEF25C03ED19DCEF075F1
-:105480005A694D80F92DFB1DB59B0B906C7BDF8914
-:10549000DFCF2D59CB86B1EBF5DFB5DF660CF062BF
-:1054A0003B3AC19288FD35CEEE0FC0FCF6AF926755
-:1054B00003DEA87E14F69704F270C21E598B2DEC01
-:1054C00068978D4AB7727E63787CC0C5C6E98C8FB9
-:1054D000CB2EC593808E8FCB145581F9975D4AC032
-:1054E000E7A74F6CDB7033A57B7F9A15F781747B40
-:1054F000D48276A1C4FAA56CDD9249C769E1EB7943
-:1055000063CFAD33AEA3FF7C13F40C6D333EE44B9D
-:10551000614C4D777125113B6B82CB680F9AED453D
-:10552000A1B7CA9BD6D7F62700F7C0ADD7011D9EFD
-:105530005008D061077BDA7E632776E37A84C7ABB5
-:105540007B7E89FBA53EE92AE3AB3DE727021D5799
-:1055500091E04CE8B76A8FEC0AD2D66F903D434099
-:105560007F08FDDEBEDFB97CC0EE01F91F2BBB5604
-:10557000C33AEDB739540AA7EBCE16A4A09EB35B8D
-:10558000CB41FE95C56639E6EAE8797F8A5C0E7400
-:10559000F0464A86F1B97DC310D073FB2C4C1EB582
-:1055A0001CBFC311C276B7A6A0BD26F4BBC93E1569
-:1055B000FEB0495972209ADD4BE42D1B63E9FBC90B
-:1055C000395622839D1E5A827ABF837EBFECC37DEB
-:1055D0008059CF0BB8534823BF74B04F237036D8CF
-:1055E000A98FA6533B6D08D2C050B03B8397372C90
-:1055F00085799E6D8A77AD46BF03B36BCEB62DD944
-:1056000030159EBF2DA31FE5EC6519F969FFEB4B23
-:105610000787747C4C3505E2E9E2B0AFCFFC81E24C
-:10562000E7E2E7711E3F3C56760E89B62F16FB2542
-:105630003A723F4B1ACEBF9F6534B21BEE4F6F8854
-:10564000EC4F37A6E3FE343C11D446DA962336A05D
-:105650008BD3D45487F9FA29F2B753B8DEA0856406
-:10566000976E3E2FA44BDCDFA13D0D72C54FCAFAE9
-:1056700053E3842C8AD34AAF03BB731A716DA3EB37
-:1056800079ED449964A5F531DBDD1E89D67783E198
-:105690000974FB3B39B09DC2613795C7BB69BF8BAD
-:1056A0005B1B6C6E3AAE7F0F9DD4285AA7880438D6
-:1056B0009CB0FA0725E9E8645606932B27ACBEE7B1
-:1056C000A09F131FC710D8079EF83C2EAABE1D9C92
-:1056D000C1F4ED1FB89EFB37A7F7E0A957DFEC47F1
-:1056E000E715BCE41A06705FF2C2D772051DE77AAF
-:1056F0006E974DD9D85A0BFE9B9BB78415903FDE11
-:10570000806B02A8DAE92F78ACA09766ECF05AC15A
-:105710000C9FB9A7C60AEF67EF6D7803EA770477A5
-:1057200062FD7CBAEF8F00971BEAC307805C321BD7
-:1057300088027C412E307BEB533E8FF44B9EFD89DB
-:1057400048D5A516A0F3F6F11F6955C0F4B9B9966E
-:105750008D4FFB7B0BF074434D781CE8B7412B5801
-:105760007F8348F3AA4435D2EFD8CBAD92DEAFF0B9
-:10577000EC438E454CEE32B80F7AB8DFD6B5C82769
-:10578000AE38D0F782AFCA1E766880EF8B3F880BA9
-:10579000C4B881CE98BD7DF1078E803F8ABD1DA122
-:1057A000B3600CA32F416FC4CEEA9A1DE8EDC12768
-:1057B0006BE2407EA478559B4F87C7B20D53F2DF52
-:1057C00082FE6363D07FD73EDE7A361EFD3E1FE841
-:1057D0005AE8B34AA007835F4AC803C617B48B00D0
-:1057E0008C2B4A22AD76117D9D04D3603E9F03DC55
-:1057F000E9778D36750E8CD71817E382F12AED59AB
-:1058000036905FED7E5070265239721DB73B5F3B7C
-:10581000B13F19F07E71D8AA41B03F085A7E81F29B
-:10582000AA3BBABB2D5DFB0FD3B7FE41B0BF12ED53
-:10583000F71D8F2B007DF9079077801F4FC56058AB
-:10584000AFF8AE7F06D3F7945F70FD824F525A894E
-:10585000B6B50041A5EDD6C1A337E70B51EEB6AA08
-:105860007EC667D44E01BE7306ED19C0CFFB32B0C1
-:105870009EE2250E0F7D5FBD37CB23AB28077A67ED
-:10588000A446E4C3F55C3EA4B486912F7BBA4FF8DE
-:1058900096C337A8ECE4FC45504E017F31391EEC2D
-:1058A000CFE490BF3FE005E406C74F5F89960B3910
-:1058B0009EC5BA53B85CB84EAC0BEC375A2FC960D2
-:1058C000F247BC1FC9E136412E480C45F1FFB4D365
-:1058D000DD8ABE04ECC9092BFA635992C1E6BBD834
-:1058E000BE1EFDAA8B53D6A33F35456BC072F1F89F
-:1058F000067C9EB6A502E963F166C9E01F15E5CFF7
-:10590000B87D76FA8405F51BB1C4F503FA13EF37B9
-:10591000723BA44FBAAF0CE07C72CF86270BD588C0
-:105920007FF8626CC3CD7700FD6F975DAB003F8D54
-:105930001324350A5DE9E107F0AA6EFCD744985FAD
-:105940001509D5817C569B24949FEA5E5AF6A1C422
-:10595000DFC8E4E9496EA72D8A33DA97B338DC4E05
-:10596000585B2717D1F183E73287835F27A88464C8
-:1059700085E18F007F801C7621BDAF1DF410D09192
-:10598000E444FB07E4EA2E1D7D2CDDB1B5AE1FFD1E
-:10599000E70D975DC364EC8738F4F25BD08990C75C
-:1059A000E6F52DE6781574785D444F2DCEE07E54F3
-:1059B0004059D5FA73E8477D94E3AF11E80DF8B983
-:1059C0005ED0DB300BCA5B131F8FFA1FC9F77D4F08
-:1059D0003C3D08FD13A329DF52BE3E097C1D852EE8
-:1059E000EADAE5806F5546147D7052F23D979C11BE
-:1059F000F97EDFF19BF22B75FDF8383C2E5A7D8342
-:105A00005D51E015812BE907F4B0886206E040B6ED
-:105A1000482EB00BC5FB942D2C1EF014E723F15C2F
-:105A2000D405BCC702BC3310DE4FC17CA95D600346
-:105A3000959D16607601B1DCD40FF4FCE238ED26BA
-:105A4000F4C7ACB710F02F11A90CE93DA571D3F143
-:105A50006F4742199B8EF1156A77031D2D7E5CC539
-:105A60007DE2EA5FC5225DBE98918EEB5ADD6865E6
-:105A7000F4696D40FA3AF9F992C1109FF153BD9E55
-:105A80001545EFD499F4F943194C8F0ABA4B5FC707
-:105A9000E8AE51D1E2927474F93CD18683DC167A77
-:105AA000A5337A8CD0916B98A0A30AFA3CBD3E2412
-:105AB00003BE281E5F053ACC58174679D6191E45F5
-:105AC0001C4EE053C8F9FFF0F98BF1DFE6723E851A
-:105AD000DB3B1DF1BACAC00FD747F8E12F0C3F11CD
-:105AE0007EB0AA91F5FC9EC3A533BEC8CF7461BF3A
-:105AF000759F6EB81BF8B96E7D9C673589C4734479
-:105B00009C55CCE3334E879DC56376A9BE4F334C7D
-:105B1000F14215E53D8BBF4CE076FA7DDB63D0BEEC
-:105B2000D807AF408EB4C505C0BE14DFE528445386
-:105B30008613F255861BE79F032284D65356D84816
-:105B4000261DF7E235CD2D09B4FDD470684A115DEC
-:105B5000E23E5B68C62DE01726DA12B033D0970F0D
-:105B6000F47F8AF54B5C3B0DF3FC1787B7C04FDD24
-:105B7000A773D3A2C50B041C3BC34B7E268F9FF19A
-:105B8000F766FE6F15FAAAC7FCEB4F04FEBD81F85D
-:105B90005741FC845C262ED0D3EDFC7B99B0F85C99
-:105BA000A6917F453D0AFF2666EAF9F75288F12F54
-:105BB000E7D3C446AB16CD6E19986965EB6A9C5065
-:105BC0000AFA28D14BD06F429789FCBE98F23BF07D
-:105BD000B11FF8B60FC093C9DF74ADE16E789FDED8
-:105BE000C8ECF18B496CBD8BAFD79A65E07FBA1FCB
-:105BF0009068D306CEEF9DC33D982831FD9608727C
-:105C0000E68631A171A08755881BF481F531FC8EA1
-:105C10001D4302418A77F53261F2E3F3A7EF7E0874
-:105C2000E4C67A87274B8DE8A54FD37DC332533B1B
-:105C3000E76B4A971AF8B1EEFBB783ED1F3B899FDC
-:105C40008F5D2123FD513ABF365307FFB1DEB00C03
-:105C5000704D8EF7A55993E83EB0316BBA7D205D4B
-:105C60009F9BDABDB45E4EEBEBC02FD72B4478FD83
-:105C70000947DFFF224F2033F330F8F1966768932E
-:105C8000328B31AE3D19E67343FFB08CF2AD87F134
-:105C9000FF6AF0EBD1F51CBD2DFF5715F469E5ED5A
-:105CA000DE3A782BFCCCA3B89FB9BA6918FA9F7575
-:105CB000FEE63B60BCCEFCCDDD8D9BC0F99ED237AD
-:105CC000EEFF12468765908F42AE2CCAECC5E939CB
-:105CD00044A60F8DF017C825B077451E02F8239D06
-:105CE00018CF0820FD413D717844DEAC6BB094477D
-:105CF000A3EFEF673AA2CA53D2F47FBF7FA884AE66
-:105D0000175E31F9FAFD4C9D7C6D6C38DA9BD9AF8A
-:105D100054FB537BE27EEE03D8B0DAF3D74CA0BB42
-:105D20007765F4C35C1363F34BE02FD088EAEACDC8
-:105D3000FB03B66B9282CE425AFF46221AF837BF57
-:105D400091B1DCF0A8B7DC0DFE968F2C287FABC09C
-:105D50007EA3F0193D9804ECF49F7BB9DFB4F4986E
-:105D600043833C81B3921DE5E7D923717ED0AB67B5
-:105D70009D16F4ABB7BC16837C713E338EFB41029B
-:105D8000067F8988F79C7F7B6E32C8FF2779FCF3FA
-:105D9000C958E68F7DF2F66CF4630A7FAFA250D843
-:105DA000F782B41E0AD75E6037F7473FACF0FFF6C4
-:105DB000B657482CE9888DA3D8D9FA7A2B3E09FC2E
-:105DC000E75BBBC997F84DA64DD8C38D00E7EA47FE
-:105DD0004236D8EF0A7B58E8EDC1A7D29B216F620B
-:105DE000703973AF6D3D65B1C03AB752724A727780
-:105DF000A42F41475B3BE625ECCAD4EBA7C7585E0E
-:105E0000427B9D7FF71CCF4B18DB76F465B0F328FF
-:105E1000BF6F357C372135CE17456ECD5CF1307EB6
-:105E2000DF19FDCFB4105F343DF21ED72344A9E93A
-:105E30000F7A8AFCF3C178358A3F67E6A795A900F7
-:105E400017B31F2E32FEA338FE3B99EDF1CE411061
-:105E50007FEB2EDE699EF7DFACBE81D1F494C0B338
-:105E600079BC8EDFB3FD597B3B1BF1ED72B07E87B1
-:105E7000EBFA55B2981D345362F17CF22D417D2D21
-:105E8000E884C2FD0BA08B92778E8D88C338505862
-:105E9000067970FEA3CC01188FEF643F2AE6432DEC
-:105EA000E7AC68791F743C6F343C48594C8FCEB4D2
-:105EB000B23886747B16FA0766C6C648313AFBE4E8
-:105EC00074BBBED50C71DBFDB1A346A2DFD3AA0E15
-:105ED00088063F733CF774264178025C3C51E849E0
-:105EE000C49D059CEB4AB55285F9D5C83650811A38
-:105EF00093A329E504E36FA3240DE1910C467331CC
-:105F0000D03FCBA73BFFB68C72A1A4540D4008959F
-:105F1000EA8BA4AC62CCCF7AD9A2CBCF127452F761
-:105F200022D5CB06BFA3DFB0AF4EE2F2985A8FDA8C
-:105F30002E5D3BF5119001117D30A0D66EA80F7A31
-:105F4000C045149DBE48D2D20CF5015E571CECA78B
-:105F50000694AB86EF04DD89FC40FC4B8175BB02E7
-:105F6000901FD18BCF6794E443BA01F9067EE561B7
-:105F70001C9F74BD4559B41C5B1E3AAFA71BB1DE14
-:105F8000EED67574259D0F15606D2BE97CA95C9884
-:105F9000BBCEBD2A0DE1EE22B0CF38BED28ECFE708
-:105FA000F3EF933656D4F5A54324D5AAE8CF4DD2C6
-:105FB0006ADEEC0BF99835B44EFFE6354812F87DF1
-:105FC000A89CC1EF9E59E9C252E0DB45DF4BF4BD0E
-:105FD000BF8CE4427CA7333DE6CD7218ECBE2EF4B4
-:105FE0009837ABB8A31EB3D83D6F417EC0F2265997
-:105FF00005BA5833A517FAFF36EC943CE08F3BD036
-:10600000C4F2F436CC64FA448C7BE67789A837CEA8
-:10601000488CCF494B12F2417512C74D6D12C66BB9
-:10602000CFF2FDF6B24C9F2F4B672F6D682A8EC5BD
-:10603000B8AD492FD13F9744BFC3D89D04F6D3B024
-:106040007A2503E5C022F89E2C088D88CD00BAF58C
-:10605000BD37460239706110E0D31C0F1471431133
-:106060004F7C25CD77AF7EFC8E7142637C4B4EB06A
-:10607000E7029F8D96E33CB251FF12C0EB1AB013BA
-:1060800029DDAD391287F059F32DE33F3ACF1F02D6
-:106090009C5B9C25484F42CFD27916BE4B3ACEB37B
-:1060A000DA12463FA26E9E7559C55DCDD39407CBDB
-:1060B000E7D50E7F1ED7929D0ACEFF2C89F3C03CF8
-:1060C000F7DA3C1FF9400F9F8943BF9FC04F15E788
-:1060D000B1B3141F129DE7D9BD23622D0EB08F7C82
-:1060E0004F02BCE481E104B0CF0F348DC883F57456
-:1060F00016DFDD9B59F67416F299EF19E43357E871
-:10610000FC4B6A64FD5DC485B742FBAB80CFAFBB7F
-:10611000C6A3113ED58AA35E628E75B4C3242EA792
-:10612000CD74273535FF1BF29228BF615EA87F1022
-:1061300009ACA170AB1BCAE88FCC232AEA65139D7A
-:106140002CCBF4BE0AF8127CDA057C5E8779DF93EB
-:10615000E90D4209F3E83F1CE5D2FE2CA6DF5EB64E
-:1061600059F07B96DF9244305FC71C77FF38B3F25B
-:106170002DFC5ED85FB93EC95570557C70B86BF880
-:1061800005912E9673382D877830E4B3EDB19E32A9
-:10619000E44D98E0F0FD4CEF270C0E94CE46323AD9
-:1061A0005B43BA844708DADF93E93B06A5D34AE9A3
-:1061B000058032BA220DE0BC4BD5303F61F72A068C
-:1061C0008FB3EF3078EC6BB3205D6F22F9C897C3C3
-:1061D0002DE7EE86FEA97C390DEB1A13DE29C1BE30
-:1061E000B9CF22D50272B97FD8235BBAA6DBAFB391
-:1061F00070FFE4BBC0F1703FE061C4DBCCAFD305FE
-:10620000DD5EE274DB53B84BD95DF27507BAB26656
-:10621000A746E8AAA7F958942E48FF5E1DFBA3FBEA
-:10622000288C3B34EF8B417955B55B42795EF5FAAA
-:1062300017B85FAF7A35068972FCABB1F8FEDC1E89
-:10624000F6FE4C69F43C8284EC5EA8A796EFBCD7BE
-:106250006BD4D37ED4473FD3CEB932E5485C367990
-:106260002A3BA7B086E73D89F86C02A7B3E4815EBC
-:106270000DF450F20482F984090E96A7D8F13C027D
-:10628000E3DB54FE9DCBA54A0067F3F904398EE5A4
-:106290001FA692755F039C92CB8DEF531DE518AF3F
-:1062A0004D359D6310F02ECEE6F6B38DA4811CD93A
-:1062B00069CAC710E5FE6C6E07D626E17E50E1F391
-:1062C0006A71DA906EEF73DA71DDF72591E429587F
-:1062D0005750FF9BFB1165926621AAFE9C45791CD5
-:1062E0005175F651AAB797A1DE67763F43FBBEBE54
-:1062F00074C3FBFE8BF20DEF07D60C37D407AFB893
-:10630000D6D0DE4D01A0AF67D4DF64689FD530DD05
-:1063100050CFD97C87A17D5EA0D2F07EC80B4B0CFC
-:10632000EF87EEBCCF502FDAFB90A1BDDC895DFE7C
-:10633000A36CB63F92855DEE1CE903BA929D762967
-:1063400046B7FFABE4F8284D284F83B879AD7362A8
-:106350001AEC4F5B92A83EEEC2EFF65DF76D7E81C0
-:106360007F6E7F9571BFDB99FD548A50FAAB3A403E
-:10637000E9A008ED2F7F36F72354A8D03E6C437D6B
-:10638000A278701D3313ECE84F33F75F99AD1AFC18
-:106390007C621F205B3CAE2952E7F01274D91DBC11
-:1063A000EA395CFF5B78FDCD946F24F67BE6EFFE67
-:1063B000986DE1F6B86F5BB67E5F47C2B217F775AE
-:1063C00017CEF809C85182764D75BC0BFD12663B9D
-:1063D000408CFF4A9AF7372057CDF2D4BB62016B4D
-:1063E00067A11B0CB9F3FDDE1FB3CDFBBD09B311D3
-:1063F0001F4936039C5E6CC7B366D8EFD52695E07F
-:106400007EAFD6AAA5F564BFF762364178D7035EA2
-:1064100075FB3AD9E6515D28E78DF64B47FB9CEAC0
-:106420003FBACE0D60D749609725337B7DB784EBAB
-:1064300016E37E07FBFCFDEC1ED8E731C453AFC862
-:1064400088BFBF67337BFCFE58F93BD9E3C7AE4634
-:106450001F1EB67A30CFFDF05499ACA2703C5F3E5F
-:10646000AA0F89228F45F93EF7DF6CCB2188B7EE62
-:10647000FC1F87572EEAF2BCC7E1492C8F733AD034
-:10648000916EDCD81C46171939DC7F13C3FC18A7A2
-:106490007FEFC47309A76FFA208138212F6EC4489B
-:1064A0003FE43913CF0390B7E37738D14F387D52AB
-:1064B000F1C8554E1D5D8D66701EF7CA3B09E0FFA1
-:1064C00099BE2B23D5EFE89C9E32F8FA8812CAC6F3
-:1064D000BCED3F9CECADD272FABEAC54E6A734E6FC
-:1064E000BB99FD46D3575419F878F925890492755C
-:1064F00075A515F30A975F52F0F9E96CA35FA953EC
-:1065000078F5109EE6E7029E87279D1C04FEF43373
-:10651000B1D1ED8F5B38BCDBE9C7744EA6B3F31F76
-:1065200025BCFFF3E5D7F4013937DDA666F5C4CF06
-:1065300025E0D47AF98B789013AFC3F99B28FD1727
-:10654000E5B0B8D2EBDAE7703C8294DAC3E380EED0
-:106550004BB93F3DCAB9807139E087B954FE3F3924
-:10656000173025C7782E202D478D7A2EA0BBF34DEE
-:10657000D36CD1F55D6E047E1F00BFDEFF8CD505A8
-:10658000F35A08B613F8EFB65AD17FF7DEE51802D2
-:10659000F1942FB6587F09796E8B9EC9786623AD2A
-:1065A0002F9A1483F19F855BAD2C3E37293600AEC0
-:1065B000AA455BBFD77B2E1DEF2BCAB7CBB2E8FB3A
-:1065C0006736615ECD7B6D6B31BFFB24F0337DBEE2
-:1065D000E8DB1FCD04F8EFB3350C190676FF0EC9C2
-:1065E000704E634963ACA12EF20805FE881439BFD2
-:1065F000A1527DF2608EF1BCD68848DCECC11CE66D
-:106600002FC13CFCAAA9ECBCD681E36CBFFF462697
-:10661000CB330C4E9A3565185DC7A4542BFA4BCC7E
-:1066200079898420D2C9029E373CE96305CFE54EC3
-:106630001AEA443BF0CD95358807FA9D6382EEBC9B
-:10664000C2A49F33BFCB2437CBABEF345FD194A729
-:1066500028CE0F75C84F8C9C1F3A1A8D6E36E4F009
-:106660003C45CED7078EB37CC4056FCB6C5DDDC8CF
-:10667000CDF7F93ADE6BCBBFEB250A8FF7CA991439
-:106680007FEFF28D8F81DFEB0BAF44203FF48BCB9C
-:10669000D1CFAD7DDEAE5F7DEDE77A003FB7962FBF
-:1066A0006EAF035BDEE6BDD770EEA7E7F2A66B79AF
-:1066B000322B87C521CCF2DD4CF7FFBFE4FBF44958
-:1066C0006F0CF23BB1FC1594A77631F968E673B311
-:1066D0003C17F332CF77F925D990BF9CCBE54044E6
-:1066E0009EDBF03D35F7713DFE1225B046423BE0A2
-:1066F000831CDA6EA423905C4A87A8756D8BEFCA61
-:106700007F43F7CF1F43FB3BDCBE4FA04CFE4BBF8C
-:1067100032D0F723DEDE89F987673BC9436F769B6A
-:10672000F2DA2463BCE0CB9CD266C8E77F50A5A513
-:10673000CEBE1E499990E73D7CC9F9F3A710B7ACCE
-:106740007AEB22F2E7269B2F0DFC03FE7E36CFF676
-:106750002879231772AEEE3CC316EE9F27B9B9868F
-:10676000781FF889306FE1681CFA89D6A669DFC006
-:106770007C9E4BD3FE0FCA2169DAE51C1D5E6AF9C7
-:106780003A154B74BBB83857D0BF17F5F8FC322A0E
-:106790007FA3D0A19ACBCE01943E79FB20F0C77D98
-:1067A0007EE48E41201F5B368DEA32DFED67C09FAD
-:1067B000547EFE18E47E56249EFA13CE37C2DF3D87
-:1067C000DFE6CDD6E769C9B949385EC235BB5BD3D0
-:1067D000299DB4AD93517EB739587EDB318752DEA7
-:1067E00058C0BE4B317CA7B0FD07D03DE563C5A1C5
-:1067F0007CA39747C5B90CAE9DADB33897ED136C2C
-:10680000C46387EF6D476FB2831E9525CDC5FCFF2E
-:106810008C1EAEA123003DFC88CBB19369BEA2DCE7
-:1068200062F88EE9DB6BB8BE551C26FD3AA0EBF88A
-:1068300078639A3632978E3F314D2B86FEF6DAFC1E
-:1068400043806FF6C645CF57BB2E97D923FFCEE1C5
-:10685000F4421C68BFE27832C6E96FC865717A0DF0
-:10686000CA1BFA87D7401E7AB3DBC5DB87F0DC1D75
-:106870007D3F01DE93B410B905F2E7E864E17CC422
-:106880001F4E1C2520BF12C26D04F269124C79B054
-:10689000A2FC0787DBAB3CEED991EFD83CBD1CFED8
-:1068A0008D945FE0BCA8E01788AF43BEC483AA8F75
-:1068B000F31DCBF7687CA297047196744DB5007DEB
-:1068C00040FE29C827737ED08E5C76FE1DF850EA04
-:1068D000820FE7F379F6940F1B9F98628985793EC2
-:1068E0004430AF8372C26A3BAD3F7B9FCB03E7C7A7
-:1068F00032D611DC070D5C11B70DF649351C1F832C
-:106900003792D5B1B4B59BE7F7897C6A776D48C1FA
-:1069100073060FB1FCBD939FDF243BA1FFAF45FF82
-:10692000C67C4191DFE7CFB518ECC2DBD27D0F23E7
-:106930003E4DF9D89DE7817D9907790E3F11FCCE38
-:10694000F370C6F03C9C318D9BD01F37A6F14645B5
-:10695000A24D9E558212ECF79EADD114D037CFE5F3
-:10696000B2BC9CEEF2E39EE6FDFB01CFA99DE75988
-:106970003ED92E773AE4593E999BAACB2BFB01CB0B
-:10698000B3FC7E2ED323CFF23C9A676B98BF6EC9BF
-:106990000B8750DE8B71443B918F37E001968FF768
-:1069A000AC128A05FAB9184BDAF3CC57A1533E342E
-:1069B0002CFAF90591576ECC271F1C0E97623E10DA
-:1069C00021784F42BF3CD5A007B7865D71C02FDD4F
-:1069D000E983DFE75E9D3E782A8FF14D14BDD9949F
-:1069E0007B757A33087443F5E60128AF5A6F727DE0
-:1069F00029F4A7787F88E373562ED39F51F4E621BC
-:106A00008E5783DE4C2101CCD320A72C1E7DBEA83F
-:106A100028BDBCDF97D3B50F61BE63B83F25E1D475
-:106A20005122E9E45019E76B71FFC4F3BDC83DD3AF
-:106A3000A2ACE37ACE9F963961BCAF22A1498A9A73
-:106A400087D6ECB689F8ED1730EF1B0653B92975D8
-:106A5000949B51F07106E6D9FF6DED0010C9B54960
-:106A60008DF1603E75818F73B968C768E7A114F036
-:106A70001F7EC5B88F14F0FF86C3C396A5FD1BC645
-:106A8000F913E7B3CEF0129BC7F0D12F8FD9332281
-:106A90007F7DB7C91E1D91C7E0322ACFC8973AFC47
-:106AA000C5E645B17B841C7E39DDEB80F7AF9ED80F
-:106AB0001D0F7424F024E48F195F113E5B85E352AF
-:106AC00038A7E6A576D43FE27BB31E8A7CEFC7F9F0
-:106AD0006E053A1AC9F27DF07C013FA720E627E84F
-:106AE000DCC3D779205D73E715779CA7EB9445EA63
-:106AF0006A9E49E11409F83F497361F98713160941
-:106B0000E6E50A2B982FEFE2FAD1AC07A9B8E074BA
-:106B1000C3FA798ACB8DBAD32C0FB1AED49706FEC7
-:106B2000FFDE59DAC83CE423AD18CABC2CAD04E63C
-:106B3000D9EC66788ECDD346435DE40B98E7A9E5A2
-:106B4000B5E71D8C857609E3891FF421DC370371D5
-:106B500096049EC790A0B9CA408F256C21982790B3
-:106B60001C1F6E8E81F8DF26E2817353D97ED50219
-:106B7000FBAF8C07B4D550D69DE6F7E694123C7770
-:106B8000D99E47579B8E7974C06F7A7A9DCEE73134
-:106B90003D8FF125B5436EC963F39A06A5B0430452
-:106BA0001F756657E8F87076DED5F1E13DD0FE2A14
-:106BB000F8706E1EE3C379793DE0C3A579ED7CB82A
-:106BC00004DA77C7870F71FE7BAA1B3EFC39A7CF7B
-:106BD000E7F23A95A30FE54595A38C1E04BD031F6C
-:106BE00082BE6FE0FD51F9B9321ABDF7802FEBF389
-:106BF0007A6017B6F7D743FAEFCCFE8BCFEFDAFE09
-:106C0000DB0279E3BAFD1EE597A7617E945F7E0102
-:106C100025E5972D8C5F54965F6EE2AF767D136607
-:106C20007202F2F3F4795ABFCB6BD737DB01CEE6B1
-:106C3000BC9C31267FFE3B9CBE9B7899103E4A400F
-:106C40002E50B8BDA4A7D7E739BFF847B3BC53AAA5
-:106C5000D9CAC0AEDC778ADA91003E2E0FC66C6EC0
-:106C60003D007623511AE2E11EACCEE0D42B5F1535
-:106C7000F99551E144C7FF633479DA04787374B449
-:106C8000E7CDF8DA91C7E83CC4E1F15DE721E00720
-:106C9000F328C279A896B53A3DFF41445EBD0F780E
-:106CA0001B3B3E2C139C57301EE227429E9201F460
-:106CB000FB911DBFFF24F2FD27B0DEB11AFDBE20FF
-:106CC000F27D12B8F233408E51798676B286E71C97
-:106CD000EBDC8C1ECC74DF6863E724DAF1D5D00FCF
-:106CE000F1E5557D5F42FF8D0A3B4FD258EF92D8B8
-:106CF000394196EFFB5E8686FC1A450E85AF520E33
-:106D00005DC843FB4CFB1794DDC9A1CB9CBFA91CFC
-:106D1000FA3F681FCAE95A0EC5E7337839F2997C01
-:106D2000E94C0E25F076BDF225839F522787E2F3CA
-:106D3000A3C8A107550687287C9A985F0CFE15CD3D
-:106D400095CFF834295FA7D7E877C9D09F17BE4FF2
-:106D5000C5BC33CCB7F093384FB47D869AEFE86961
-:106D60001EB59A9FDA31FF8C749347BDE1D1900D27
-:106D7000E02DF29CC4B8E6FC6981C7AAA65523C8D9
-:106D800050C8D3BA3C08ECCAB347BE41FFC8DECCFA
-:106D90004A0FACB3E5B55186BC2C31FE7DDC9F3685
-:106DA000412ED809FED973076DE8F79489FAD418F3
-:106DB0003A9FEA8356124039C5EE2910F130EBC1F3
-:106DC000BA56F0C75B89EEDE28DCCFA88940B7D67B
-:106DD00083ECFE2692C2DEFB897D15DEB738DA1819
-:106DE000E74FD28C71FEE4F25EA6B8BF31CEDF670A
-:106DF000B631CEDFD7678CF3F75F34DC14F737C6D4
-:106E0000F907AF2833C5FD8D71FE8CFAE9A6B8BF2E
-:106E100031CE9FB3D918E7CF0B18E3FC0BDF7AD93B
-:106E200006FBEA212FDC678AFF1BE3FD1420AD99E6
-:106E3000BAFB648AF6AE36B49F1762F7940D0BAEB8
-:106E4000357ED7C0EE39F0D3FF013CBF203E1BD0CA
-:106E50009942C26FF687FC9680E409D2668BF7EE02
-:106E60002A817238F78B2FDC6CBC1F6171C058FF10
-:106E7000EACFE507210FAC1A9888F653FD82140873
-:106E8000B83BC7FBD2178CDF0B3FEF52BE9E73DCC3
-:106E90002838B745C6F3CC663A59F8D6ADFC5E3112
-:106EA000AD15EE8F107010F4E2E2F422E625E0B1A9
-:106EB000545E867C2EE020EED7AA32ADBFC37AF7AF
-:106EC0006EC5EFCCEB36AF6353BE31CE473AF08997
-:106ED00083E509D175419C5CF6E79AF8C40887CE32
-:106EE000E0D753BE51391C62D28C7C13ABC699E9F2
-:106EF0000EF16D86677CAE919FCCF0747AFA45A551
-:106F00002F713F2AAE07E2217B25F2B4D411AE8B5C
-:106F10009AD6D7F58F424F840430CFC30CDFE67C7E
-:106F200063BC6597EA6B01F978FEA30B32E2D517D3
-:106F30001A01FAAC8BFCB383BC7D4FE3ED87F2758D
-:106F4000FE1173BCFD2CE449EACEAB48ED78D34C7E
-:106F5000799207FE0D7124FA8DCF067ED8728F9D2F
-:106F6000DD1766CE5FF3FD331FF5B046D00F788E88
-:106F700078D6D0FED6387F3FA41BBFC8B1FC62963E
-:106F80005F00FA6B6C3874FE25E85E6975C138D114
-:106F9000EE29359D3F3C0DDF77760FE4F3C49B4728
-:106FA000A2C4ADC5FE55D8ED749F74219FD9331787
-:106FB000A1BFF67D52BB7DDD753F228FACB352DAA7
-:106FC0002FA35E0D4B719E68F798C50E31EEFF75CD
-:106FD000E73D6387E8F468D5F7CEBF09F3A0F07604
-:106FE0000CA1F3743AA97D23F5C8BE71413F4FC58A
-:106FF00027205D87DF9203396EB8DF4A4DEC55D00C
-:10700000F19E2691575803F73025C3F3BCC4AEF266
-:107010002FCA4CF76099EF33AA1BCEE695CED7392D
-:1070200085DB5125BC2ECEA5097F5CF56CE66FDEB5
-:1070300064F263960C71627B6F665909ACBFCE2D0A
-:10704000A1FD5427498678D2F1FC527CEFE1FD97EF
-:1070500000EF15E3F93A9C578A691F7F8EB73F9777
-:10706000CFFA857BB180FE6CB21C159ED70D61F303
-:10707000FF3BB7A3BEC3FD34EFC78CEC783F8DF95F
-:10708000FEC489B9352D201ECC71DFDF75773FCD69
-:10709000FB13A3C67F01BEF1BD22743F6388F19E3E
-:1070A000C4609C6FC354F047BC237BB6E157AD234B
-:1070B000F4FBB48A21CC2E5DC7F72D1057C2FD0812
-:1070C0002FCD70AAE0706AC8F45600FD6DB2B5DE2F
-:1070D0000FF41BB4B1FB42C31F101CA7DF22AD1974
-:1070E000EAC55E15CF57D4B98903EE190A0FB3A0CC
-:1070F0005F24C5E71A0FF7FEA66C917A0138855C0C
-:10710000B02AC4EFA4F4B276881BF1B08EAC6986C5
-:107110007B5112B77C4DD2713FE11AEF0279348F67
-:1071200044F5733ECCE963DA33E90AECCB12EDD1D6
-:10713000EF79787888C863F33E04F431D67E6484AE
-:10714000847A82ED43606B8BFF69B318CE358BF286
-:10715000BD8C717EF84ED0F3F532A9D9E56074A6E6
-:10716000BF7F6DED90ABF34F172F2251FDA8DBF9D8
-:10717000BA72546F03C0BDF87D15E31F0B85DC9F09
-:10718000672170CFE9ED9C1C6FDFC2F2E1C9E52BEE
-:10719000576461C713EC9F403C62E1326700E21321
-:1071A0000B9BDC78FF1F592461DCA4BAE99017EA35
-:1071B0000B478E74A1BC8C9724B807124C08261F6D
-:1071C00015725CD09FCC8144FB9FCDF50DD52BEB88
-:1071D000E2E9BA166ED9DA0CE72CFE410D08C0FFC1
-:1071E000267E6EDEBC2E713F5DE4FEBC4F36E9EFBD
-:1071F000E7B6ACFAC707C6FBF3FEF1C17F737FDECB
-:10720000BEDFFCE303B89FDB7C7F9EE0FB8F64DF87
-:10721000470FD37FDF4695F28AE1502A640EE229B8
-:107220000DD73983AFD3FF0D918EDB2370B9ADE954
-:107230002D84F747563A1E651E6B19038DF5A14440
-:107240008C2F8B7CA499F68609A0D7CFDAC28570E3
-:107250005EECEC6B1F0E84BC834F7F78DE097908EF
-:10726000FF54C24E787EE291F79C1AC5EFA78FB00B
-:107270007BB6EEE6FA52C0ED1F9C1E0A0BBC87815E
-:107280001EEE59F96D89FEBE20B22215F5DCE280B2
-:107290008C292C428E2C7D211E2CB9F6FAF29DC928
-:1072A00086BAD07FCB63484D34BFA8AB80F1CDE226
-:1072B0001D5B6DFD5518DFD706E39F80C4694A3713
-:1072C00027F638D14E16F3A9DC31CC0676D53F9B94
-:1072D000624810F66B4AAB959D37D5A648945E7D03
-:1072E0009C2ECDF37CF3F578EC6FFE26266F2BE811
-:1072F000582B285C7D4DECBE4FF33AE67FAA4EEC4E
-:1073000043E13DFF716AC1A8ACFD23146FBE153F78
-:10731000C2FC71F33A2BFCE6FB3D3594F70B397E4A
-:10732000E7D61BDF2F6CFA31F6338FA8EB204F72B4
-:107330007E83F9FDA42F8048179AF2D16D055C1E5B
-:10734000979051208FF7DB3312A39D3B15E5A9954C
-:107350002E64A22F57DAB13CB192607978888A7096
-:107360005FD674E841A09FAABDBBF01EA696C0845C
-:10737000144AD6E4C6A6DBF1FEDA1B79DCFCAE8E3D
-:10738000F78BA6151443FE91E9BC375FF71C8E07F7
-:1073900071FE7B0EACB7109E2B17F4EB397730C320
-:1073A00001E3BAC5BA46D175C93D5F97588F589F5A
-:1073B00078BF9CCACFA8F1704EE787B9BC9ED7387A
-:1073C000ADAE1F05C59AD7BE40FF00E1FB92F6FBAC
-:1073D00091ED3F6E85798F27A67D899FBC4F74F410
-:1073E000B69068783FAC99AE049EA9DEC6EFED7CFE
-:1073F000DFD24E4F4D3F41B8087CC30D82FA7BA9C6
-:10740000285D19F609948E0CF5F90DC6FA196B680A
-:1074100010F0FB42D3EF459C31E5D388D25390CE98
-:10742000E0A06A13E1DCD07CE2AD6379C7ECDCE17B
-:1074300009A5E1CD87810F1B191FFC93E37F6781AD
-:107440007716E09F285A21DE17B9BAAF0C171F57DD
-:10745000AC935CC05F736B87E1FD43C38986FDDD40
-:10746000D589DDF910E7FFCA1A2BB15163A1928EBD
-:107470000172AE728F2CEEFB724CED0DF7D7303EE1
-:107480005AFEF82E5B5F5A2EAA59C8ECA100E31BE6
-:1074900071AFB6A03FA19F96AC6B46BF03DD6F19DD
-:1074A000F8AB1ACE8114021F9B9ED7DC8878A836D1
-:1074B000D945DF2BE0FB330FF1007DFA1E74DAE1D2
-:1074C0001C5977EB261DFD49E86F3A77300BEDE547
-:1074D00073AADA07DAF912D83DFE92E21B05CF292A
-:1074E000BC508F8657C5E3BDC6472EC944C5FB5562
-:1074F0007CA3E0BC7FE8EF0309BBAF8DD1AB586F35
-:10750000B57D1DEEA3AB4DF45A41376CE027AED8E4
-:107510009E8C796AB4FFC2BD605F6DB7A2FDE4279F
-:10752000F7A5C1BD1ADEC7D8BDBC957B93701F5FA0
-:1075300059CBE24B953B92F09C30DD47BF0FFE19D3
-:10754000818F23B5E36C7D115F6EBC2F8CECB5FA97
-:10755000F93DE748E7024F1DF7C1263CD537BF99F3
-:10756000A676DC17EBF0D4D6099E0CF758FE5AC865
-:10757000118E27F208973FF7BE910571B57335B1AB
-:107580001E39CAFEAAFD3EE379D7623E9DF03F96C2
-:10759000F713BFAFE0E90D783DBFAE18F166C657EF
-:1075A000F97FE6225EC8DF9D04FCD27765907BA65A
-:1075B000D3E7F7488C5FEE5A33A91CF4F9810266D1
-:1075C0001FFF95CA2D2D879043546E69546EBD4799
-:1075D000E519D43F589986F50F57AA587EBC321743
-:1075E000CB366E170A3EA2846003BBF2AD0266EF93
-:1075F000BC5520FCC10FA4816951FE9FF78A2DE084
-:10760000EAF5CF9F3981DA3BB768467D387B8651F2
-:10761000DF85ACAE89707ED9FF38BB17AED27B9DBB
-:10762000A13D5154DB34D8D7E78E883C477E536D5B
-:1076300070FEFEF629C986F633EBFB1BEA470A54B7
-:10764000764F507986E1F91D738618EA15FCDE5BEA
-:10765000A28E46BE7980E7C912329AE185E7DF5CE7
-:10766000A819D5E7FB74BE17DEB6E27B333E045E95
-:10767000E76D96898FF6377733955F748A6D0D14B1
-:107680004FF4BBAF3E72C2591952B763C4BBA36972
-:10769000FDC80E96AF7BA436F9A7603F1DD9919A1D
-:1076A000007E635F9DCCED0C17DEF726FA1D57BBFD
-:1076B0000AF3722A023178EEA2A2C5FFACA8C34F2A
-:1076C0002EA089077CF3BE1C084A883FE6F7F875B0
-:1076D0000CC62D4E50BBCE45F5C40989D4420907CE
-:1076E000C512E9FB7FB5A60680AFCBFF236B6940CF
-:1076F0004FBF8EE5712909FBFBF250D6B6B5485F46
-:10770000EACE20F26F0CEE8FE686D8FA8834BC3FC2
-:10771000E0FF4412D192E82496DFF7E1670AC5D36F
-:10772000E2ECD642B817678E3B983A8B7E77AAD1A7
-:10773000CAEEE9A7FDBA687DF96F62F8FD8F5A1F9E
-:10774000D86F44E019288475A7F6F3A60EA5FCF1BE
-:10775000E5824021CAB5475291AFCC706FB3F910A2
-:10776000BE7EE003292227237CC6E28D54B8F505AE
-:107770007933D7EAE90DFAAA6D9D95DD8FA76809DF
-:10778000ECFEC9DD48C76D8A3A11D6DD56EFC6FB5F
-:1077900083C4B895EB648DDD5F49E912DAAF977D5C
-:1077A00070DF8FD05BFE7AC907F70299E9E6FE7BAE
-:1077B00047619EBFD9FE15E519CAAB3E9D1DB1E4D8
-:1077C00035197FD7838C0C29330CF783B1DF3F2128
-:1077D000BED186FCDB65E97FFACC6141BB2611F6A0
-:1077E0004527DF9791CE4EA63794A465403ACDFE4B
-:1077F00092EFD3FA5753FDC7E11CF13D837D65003D
-:10780000D7A59675CF4A1638777DECA770CFEE973F
-:107810002F5A3D30EC925F2F1E8C71096E7F77944A
-:107820005B9AB0177AC33D5115AA0BF5B85A2B11C4
-:10783000B6FE00CEF34EB2F331C09B6B197B7EAC2B
-:10784000D8B916FC03734DE7D88EF17B3A660C6508
-:10785000F244E8FB0D4399DD34D7C2E89ABC2EB15F
-:107860007BB4F8EF5F087D20E4B590FBF38632FB34
-:1078700042C86B6A39A0DC5A00B747D1752E7B210C
-:1078800086F9D355E202382E6668225B873279B1D9
-:10789000C4F6E293C04B0B492BEAD32FAD8105AD63
-:1078A0006EF87E6B6D2FFCDEEA41FF32D72F70CD74
-:1078B0003FC8A5859CFF963748781F14E17A723E31
-:1078C000EF9FBC608DE88DF428FAC5A457E673BD20
-:1078D0003A9F98ECC006A3BEF3C6B3CDFE123A2E73
-:1078E000E8CFC8BCA8FD4C61B7C01778F3669CB759
-:1078F000E4094499C742120EC2BD58CB77307FBD10
-:10790000795EE675F4749E0B3CD3C6278DD48D6BDF
-:107910009AB780373AB8757810705FE067F05CD03E
-:10792000C4E21F9F737B4DC46BCCF85F48BC3743E8
-:107930003EE2C28D547EBA23F420E860F1AE00C668
-:1079400067BE220D090ECA07CB36EF9A798D0AFB66
-:10795000FC43B80F99D32B9865492224D97FE8C9F5
-:10796000F281DDC727FE577022FC7E71FC8EC26556
-:107970007E23BB3F5CD78EE7DDFB91AE17F9FD366A
-:10798000F0DF2EE2FED0EEE659ADB073FEDDCF970C
-:10799000C1F17F3DEF778776661F6545DD6FB5DB0B
-:1079A00045DDE8E34FACC181A08FC30315D4471771
-:1079B00014CF87A529A09FB370DFD099BC5DC0F517
-:1079C000F27CD0D3B43CBEF965BCE7E9F38D2F63FC
-:1079D0003CD8F6E2FC04B0978F6F9EFB53380771DA
-:1079E0007CC75CD4CB0B9F167AD967D3EBFB719B1A
-:1079F0002B9EFB21D0E90BB118C758D0E2E3F63833
-:107A0000DDD7805CA4E3A19ED8C8E4E042D05F0546
-:107A1000A8BF72A0DD830B7C3940EFBAE7A8D71E60
-:107A20009CEB1B85DF135790DDB3EA0A82FE12FA46
-:107A300055E8DD57FBFA2E0F053E92DFFEE0077496
-:107A4000FDA777CBE8D3592E6F1D04BF0FD3991C28
-:107A5000FFEEF0B6B4C3DBDD03785702BCD11E6283
-:107A6000F03E5ACFE07C6C1D837BDD8E8C04D80702
-:107A70001FADCF403BE8E88E2C84F7BCB514DE6820
-:107A800007AB463BA89EC21BEC7F80371DB7B245B3
-:107A9000E5F0F63078D7733DB48E95F33AC0D57FD4
-:107AA00037C895077F19E3C1FBBA6383A9B04F3983
-:107AB000B14B2690A7D16E27717B46C0F95FA4E138
-:107AC00059B0AB3AD837EB6308F87317FFCE89E7A4
-:107AD000A4BE944AFB00024E35FC2901C68B8CDF04
-:107AE0006ED7780A8B75764D0FF15345BC788EA111
-:107AF000AAE94F1F815D0FD72CC1BEBF4ADC8FB1F1
-:107B0000D7783F86A4824CC3F3B2763BD0C100F352
-:107B1000FD213EFCBD9C8B595FDF7D1FF273385BFE
-:107B2000EF57AF8E0B5AC11F15DE2521BE973F5070
-:107B30009A504A200E5783F3985AC8F4B3A469E8C0
-:107B4000678CA1741347C7F3C265C2F05C7531BF7F
-:107B5000E3163AAE33325FF3F39B4110817E7744F4
-:107B6000F753FF908FB35CB6E03E64998DED4744C8
-:107B70003ECC5D85CC6EB8AB90ED4BE616B27C93F7
-:107B8000B3903C45FB3D7B7D0CCFEF1E8FFE4F71CC
-:107B90003F8222E0E652CE187E674209E3EFC07CC6
-:107BA00076ED21BC7FF733F8168D6B8A8012B06BAF
-:107BB000D8F7EF5AD9BD2E778EFE13FA4D3F8BF5CD
-:107BC000AA607F7D966AF7001DF9E11E3C4A7F3F5F
-:107BD0008A63FE729292A8007FDDC1E5ED5D63626B
-:107BE00034D04B778EF991174A3A8E1F821675A5BD
-:107BF000071E033ABA27EDD8F7EC7449AB2CCC6ECC
-:107C000059D58B601E511135DFC16F4B5FEDB992B5
-:107C1000DC15DD18FDDCCBC09F7B2D6104351AE13E
-:107C200069A853B8627DC34BA5B3360E20E430512A
-:107C300087029E97014C800E2A12D12F700BF89567
-:107C40007B41A9207D4D5788DFC2CA7A07DEFBC180
-:107C5000FCCC37F375DE369A0413E9FA826F118390
-:107C60001F7E56D012CCA170BB45093603FC2C7682
-:107C7000D50AFB026FB9341CF6CBCB56F76CBEBFEE
-:107C80007A69CAAC8D6368DDC2F21CC23F90F09E77
-:107C9000963B2973035DDEAD90167938C31BD05D2A
-:107CA000752F761F79F85E89C79398FF5FE0651896
-:107CB000ED5E0FDF3BF9FC683FF509F0BD2DBA5FC3
-:107CC0006937A753616F2EE57CBA54D0D90E237F54
-:107CD0001E167C02F62D85DB9DBCEC8CCEFFCAFB0C
-:107CE000FF6B21F35FBD7695E32D8F2141FDEF56AC
-:107CF00089716FE1E53B85CC6E16F310F44BB85FEC
-:107D0000CA422506D0515BC31AB4971699FCC444E5
-:107D1000EFBF92A3D5DBE58EE50A94B6F03C988FD1
-:107D200074432CF2CB9DB69D59EC9E1963BBE50DB7
-:107D30008CFE973BEC68078AFBC5C53E40D88D8B0F
-:107D4000C1DE037BBF91D9B70AB7CB2BE87E0D8884
-:107D5000CE4A42B5FD61DF5CAFB37F519E717FCFEC
-:107D60009E613E18E74E871DE39F372F33DA4B564F
-:107D70006E475A3BFEFE9D31AF84DB4BE6BC129949
-:107D8000F3316DCBF6313CAF44E1F6B0A0A30F0B5D
-:107D9000ADDCAFE237C4F1E790562BBF778EF9F731
-:107DA000B89E9E203BF03E863912BB67EB6CA9D390
-:107DB0006FA172E9137ECFCDB91A76CE79CE0FD8E6
-:107DC00039DEBB121FBC19ECE239093605CA4FF87F
-:107DD000EF7D7DEA4A4F9C4540FEC83CEEF4935946
-:107DE00010BF59037294D59FD2C6A0178DD79FF8A4
-:107DF00010DECFB84CE78DF50DB3343ADED937F845
-:107E00007B3FAD437CE831C1C79B597D9378BF85EB
-:107E1000D51F17EFB7B2FA4F44FFBCBEDEF47E9514
-:107E2000E9FDCF597D70D1D6597EB0E379DC6ACEB9
-:107E3000B512C6AD34E0330ACF39AB83485F732C3B
-:107E4000FB5959468210B7ECAEDDE422AF06FA5A70
-:107E500076B639C15E99314CC37AFE505F7E11C54A
-:107E6000CF926992DF06F1CBF703D95C9F45CFC76C
-:107E7000E7FA699287F527EC5FDACF88A2E2ABEFE9
-:107E8000E7A3A20EFD8CF92EFD34769CCF84EFB2D1
-:107E9000AED861C67E843DB86DB8E6837991F1D7DE
-:107EA00019FC9C4B1FF524823D49DE65BFBBB574B0
-:107EB000F5CE412368FF4B5FDA376881CEFF5075FE
-:107EC00049261A95C3D597242CBF6AFED806F74BCE
-:107ED00054ED69B64D2C80DF0B6AB68DD3CD6B990E
-:107EE000C833262165BACE9E995F64E17CC57E7752
-:107EF00068E94B2731FEBCD4B2F3F8D3C097D73230
-:107F00003FA4797D53F9779F417E4194FDCAD222E7
-:107F100026879F1EA92D01B84D0198D1F6E3D644BE
-:107F2000CFD3D8C3FB9B13C7E4FBDC12A75D2D8224
-:107F300078B86F0D9CFF5BB0C53D1CFCDA5387968B
-:107F40003D50D4A57F38CCFCC34DCC3F3CA757EB6C
-:107F500003547991DFFE36F814DCFB3CF929D21E7C
-:107F60004F06BF2B1E8747BEFB70D6F831E8EFC324
-:107F7000FA1345879E82F3DF07F9EF31DC356A6833
-:107F80001CC885903BDEE2A2FC3CA3A0E2B780BF08
-:107F9000BB465D3F119E97C638B32B589C01E962E2
-:107FA0004681772DBC87F6E0DFF1D998BFCFF76720
-:107FB00019FD7DBEC2785FB4FC857A0E87DF16B1ED
-:107FC000F31B072D749EC323F310E35303ED815677
-:107FD000DA5FDBEABEC3E09CE5CE82D297909EF8E2
-:107FE000F83B0B7CBFD08F0F1409CF7B3A8FCD4568
-:107FF0004C9FBEC4F1E61D43E94D27F7A78F8F378D
-:10800000D4674C49269ADEEF3CA3BFA13E7B4E8647
-:10801000A1FD1DF38618DE4F8D691D597315767FFE
-:10802000B5D31907F9119F36FDEB6F77823DDB2839
-:10803000E3EF172D7E6DFBDFE0F7BCCED10527A364
-:108040007DAAA2FFEFCB83EC775889A229FA38D614
-:1080500069D2FA24C47D75F191A8F163111F59EA20
-:108060006AC13CCDFF368EF56E118F630D87D475D6
-:10807000D0471F0C823C952A075BD7E97D47F0F774
-:108080004C20CFE34A09C47F091A89D59756E1EFFE
-:10809000C88DE3BF275D5DC4E473D5807B15B8B799
-:1080A000A09A9620FF2752399548E9A4B5990CDD8E
-:1080B0000379DB6E27E6D52CBF742BFAF50FC6F9D2
-:1080C0000BEEA5ED96D64FC27AD5A578ECF7AF7238
-:1080D000EB44CCCF7F45C2F8C9D4FE77AD86F943D7
-:1080E000FBFBE978537F7B6339C0A96A0FCBBF994B
-:1080F0002A1F1E09FD2C6B9884DF4F95C94189DA30
-:10810000498997EEC47EA7828D43EB7289732DE86F
-:108110005DD916CCFE05C8159B13E54AF5A558FC9C
-:108120006EF238A69F2F16B17D8B35C4E635E1D2AD
-:10813000347C2FF07FB928DD709ED49ADAA8C07DF8
-:10814000ADD69084ED6FBA34044BB1CE3FE7FE124A
-:108150007F9FCC9A7A6122E4DFFE394572A1D9650E
-:1081600092BBE76B4625EAF7D3FF0F762BD097003B
-:10817000800000001F8B080000000000000BCD7D78
-:108180000B7854D5B5F03E73CEBC9299C9E4C9843E
-:108190002470024908106032791042209310109127
-:1081A000C000550906199047401E21BEE295FB67A5
-:1081B0004212088216B5BF45453A205AB4B6372256
-:1081C00056DA224E006DACFE366A1F786B6D502F6A
-:1081D00082458DE0B5F416E5AEB5F6D999394382FE
-:1081E000D0DEFEFF1F3EBE9D75F63EFBB1D6DAEB3C
-:1081F000B5D73EB978117ECA19BBA895E6F332F31C
-:10820000263276D37989790B18FB3ADF9BE04E66EC
-:108210006CD6861EC592C418B3599C4F66025C92F8
-:10822000AF2ECF0BBF271FA961EA18783FA9D7E867
-:10823000B5C1FB504EB185EB1731E6ED0098B11E8C
-:1082400065AE3DFCDCE53630968CCF9B192B827EEB
-:10825000FBDAFD8CB114C66E7632FED3088D52194E
-:10826000336AEDC5FBDD12D4C1BC022F98834FC227
-:10827000EF291EFF6837F4D35DC1E6EFC77E94EEA9
-:108280002173ECFF73F3AF9699454AA0757871DCC2
-:108290005925AAE15EE8CFDDB78E0095DFB68E0CDA
-:1082A000ADFDAF65D6D801F3F8757979B717FAEB5C
-:1082B000BCA7A04056C3E356B84D8417E6ECBDC03A
-:1082C0000A195B773856BD17D6590D3442B8F725D1
-:1082D00073704F263D67521296E63D12D4AF73F489
-:1082E000E6F860FC292F5B436C2CF4FBB25561303F
-:1082F000CE1B85FE0AA4E794974754490E98E421C3
-:10830000B3C2A0DD75E3BC9588B781E67B318A4FA7
-:108310004429D6CBAA261A583163B759F86BD3E64D
-:108320004881B838C6FCEDD73206735D7C7E1E638B
-:10833000C04F4BCEC712ECDFCE9F9FAB1F340DF169
-:10834000786E034C1AD6B1648334E600AC8BA97600
-:108350007736E0A13A6DE146E640BC1B68BDD5A387
-:10836000E3832DD0F4BA29F680218EE8D185F45824
-:108370007D3E9EFA5B733E93C6597B3E91E075E766
-:10838000AD542E393F9A9E0BFEF6217F437983C769
-:10839000BF1EF151DD72CD741CC7BF31B5D06F8BDC
-:1083A000E4179313F90AF8C5B53C821F5A3A815F66
-:1083B000ECC42F8A17F0EA8332925F6623FDF31034
-:1083C00013CE692930EF59AD99867B59B8FE4EA47A
-:1083D0007FD195F3FD2D1ABF2CB185B20DD09FB181
-:1083E000DEEADE08F33A9BA44E43BC346CE1F86B42
-:1083F00030FAA6D861DE0D8F486EA00CBBA5D86EF2
-:108400006180A7E2E3F5267F04BFD79C1FCB54C051
-:10841000C7BCF35954568FF1B722FD179FBF41A334
-:10842000D3582A995A62C0F9DC8E74557142259C42
-:10843000CEDAFCBEAC1F3FE82E18FFCB378C545F62
-:10844000E40DDC8CF33106CDEEDD309F5356BF8C4E
-:10845000F43D95C19C0FC1144F1959C009F4BA6578
-:1084600087CC02D0FF5228FD509E8A67DE780FE24B
-:1084700013D699CBFBBE08FFFF53D93E840D07BA34
-:1084800036FCFE7D6518632B73BAC786A0DFDA8AD7
-:1084900050F28DD0EF99BD467700C65DDDF976B11B
-:1084A00001EA3FC9F40E6232A06AB07F17D275D5D7
-:1084B000DCE04F8C00DF7ADFF38E096A189F1D4ADB
-:1084C000285B81F73B008F019857C736797A90F087
-:1084D000CF62E78C09F3B5E0E368FE5E757E38E1B4
-:1084E000E75CBD79CC01E45FE0577CBE46E3F35B1B
-:1084F00091EF890F39BF0B3E5EA37079B5C6161791
-:108500000CC03A8C3DBC5DF5BF01FF01CAD71ED837
-:108510007D7F29F2DD1985F87FB5B64FAAE5B9BE92
-:108520000ACEFFEE1678FE62930B9015E6FFA9E7E0
-:10853000E750BBB8F337517F82EFA3E579C4BE6142
-:108540000CDE7B31DFFF16E2A9F2477F7BFEDFE125
-:10855000D10C2594F358129676E29F7F96DCFFDDCE
-:1085600055F2FF31ADFD74335BE4CBE3723DB2BF36
-:10857000144FE5695CC7676E89CBDF7FB2BCFFEC47
-:108580002AE5FD1FAE50DE4BF95CDE47CB7706FDDA
-:10859000A17CFFFCA5914194FFEF33D007A8F70E13
-:1085A000C5AA4F6AF29FF4434C5CF072F2FFD1C24D
-:1085B0005BA4FCFEE5BF21FF1F90FF7FEF3E11FC97
-:1085C00018BD5FAEDBDA4D7A81BD283194BF62FF02
-:1085D00074C570BC748DE27A20BC6F24DA570CF637
-:1085E00055B614B96FF6DC5F8AFBE6F324770B1BF4
-:1085F00078DFDCA4ED93459A5E10FBE3D17C7F61CC
-:108600007EC4FE58BD3F5A3F5C9EBF6E4AAA67A813
-:108610001F164119C95FE63EFDA0DF1713F2AF6ECA
-:108620005F8CD0DA7F1B5FCDFCE7F3D5CC01F8AAD5
-:108630003A3FF9EFE7AB687E3A57FFFB4215E67326
-:10864000AE10F82833CC3FD7BDCEB8DD30DCEE7E9F
-:108650009245F0892923D882ED2EB27AC463B43CC6
-:10866000147CBB05EC009CA7A07B574C206F7DDEE3
-:108670003F4FFEDD997F7576EFD2FC2B931F9B91C8
-:10868000CED8EFFF9CBDF8607F74655E6E1784E9FD
-:10869000629E47765C08149C34305D8D3BF8FE1278
-:1086A000705B48117A3711F52EF0CB43FF08BF54A9
-:1086B0004F815F0723FCBBF9DE74E8EFBB1A1C781F
-:1086C000773ED2E7861251FFFB1DDE2C9433F06B10
-:1086D000298DE06516C2AF061F3F5E85FCFB505F2B
-:1086E0007D00EBA796C569EF332FBA1EA2FDFEFCF5
-:1086F000DF1EDF46FB793BDFBFFE1EC53726022E9D
-:1087000004D81E019744C13B797B87D2C39C848FD8
-:1087100020DFAFD0BFE4E1FCE38BB04B8092D3E22B
-:10872000D1AE3C2039EF05FA2F28FBDC84F40AAFE8
-:10873000BF87D6BFF690A4C11F1DF70269161CE0C3
-:10874000F0F1FC533B028AD61FE079B58666738749
-:10875000E495818EAB4BA4E0B0CC4BF17CBC4F3E9A
-:108760008979802AD6BFCF4C8557F73EEE6F7A7F46
-:1087700018BD1F325FC5F83796316FD07669BB538D
-:10878000A2DD058045FF80CB79B0BE60DEA5ED7B24
-:10879000B5F6DD068386AFAF7720FEBA4D029F1790
-:1087A0007678CB80FE8CC3FF957F617E208F4FDF74
-:1087B0001BB5FECBCDFFBD7CBDDD803FAAFEFDD04D
-:1087C000E5F0F7C125F8D3F8A74ECF4F718AEFD85F
-:1087D0003998475C92E444FB78ADCFBA0DFD803008
-:1087E0007F986B703DDD56D6C7CF7AFEB7D454C1A3
-:1087F000FAD632511FF308F93986BEF67C3FF4F100
-:1088000017F3E6023FA10980EF2779AC8F046C448F
-:108810001FAA2738EB32FBA1230A2E8BDA3F1AFF5F
-:10882000D3FE45390FF8C9EE47CE1478387E3E9511
-:10883000D87C9493DD95DC5EEC1EC6CB791E89EA6C
-:10884000277A381DA66865774C041ED2C374869FAC
-:1088500010FA2311EB263CD52469EB0E8CAC990958
-:10886000EBEE4EE0F5D5FBB31F099485E1E8FE661B
-:10887000EF1F59837CD3D77F60C4BB88D71A0D6F95
-:10888000F3F6E7BE1BE0F250C27DB9861804A87566
-:10889000400AC8B0EE35C817FDAC3BCD73C9BE0A5F
-:1088A00044BDEF355EE6FDCC4BDFF746BDCF8C49CE
-:1088B00057F3BE46B79951749D1E45D7AA28B8569E
-:1088C000C0419DFC137271C9C107DA52601EB7EE38
-:1088D0009350CD44F07309F1F3AD4EC1BF13DE45A3
-:1088E000791FE6E75282E776087E9DF808CAFF39CD
-:1088F000280F4BC3F03C94170497D578C745EA8BF3
-:1089000049547F63BB683F99E005ADA2BFF2475071
-:10891000BE0A3A02FA6A70BC9A42A12F2ADEC5F654
-:10892000AB0EF1F737792ADFBDEC7ED81E85979D17
-:10893000517020AAFDF7BE45BFB446BDBF21AA7E37
-:108940005B14BC230A6ED7BFBF78A944FB7031F01B
-:108950000312E2DBF6E5C39E3E3BB54F9F4A36B2BB
-:10896000DB74FBEABA160E073DB36BDA6D11F07ECD
-:108970005F8D266F695F1819FF01591B407D651CCB
-:10898000405EDE3F105FE646EB5B5EFF27FC351581
-:10899000ED60A6B30B8ECA7AB853D6E61DB8F9DDE2
-:1089A000DBF3F0A18017D6A07F70DDF7F5EB02BFF7
-:1089B00055ABBFA9A6AA2CC22E6137119F88758A14
-:1089C000F6D3BEBE28E3783FDDBFA0662FD4D756CE
-:1089D00086B2EBB14CE025E83519F5E63A2D2E3399
-:1089E000ED25D9877AAD362694DD106987B08E1CC7
-:1089F0005C67E73D32D127D002F4C1381B739B304E
-:108A0000AED21917D7F814B43F7A8FDC887AF4FD08
-:108A1000C6C4149C7F6A01B7238FC60D4D590670DA
-:108A200067EC22930AED3A374FA5F288ECDDD40BC0
-:108A30007BED379E5535B691581F47F8E9DEBFAC40
-:108A4000A619F6C13B1E95DEF72738530EA2FD7C12
-:108A5000AF913DA9E27CDCBB886FEE33E7A31FBD7D
-:108A6000B879740ADA934BFEF79C69A9D06E499BDA
-:108A7000D12D513B3616E7EDBF77AA09EB97B66AC1
-:108A800065E01A2A5FFEE6891607B4EF7D5C72EF97
-:108A900081F693BEEC787D2CC02BDA87BB913487AE
-:108AA000CF1B9813C6F960C788A00CFCF8A1B5FECF
-:108AB000D559BC3DC3F62B2EA86FCE2AC4F6B2738F
-:108AC00023B43F09CFD11E3EB945DE23E1BC1CF6DD
-:108AD00018099674F26BF54DB46BA1DEB9119E9F27
-:108AE0006C5B998276D649497548B0FE5E4F638DBE
-:108AF0000BF865C50EB346BFC6D4C5B0AF171BFA99
-:108B0000F885F4C7F2780EF7EEBFABE64998FFC9D7
-:108B100047463810CF6B0BBC5F78501F157ACF7A61
-:108B200092719E5C4FBDFC8DBC08EDF15F9C59922B
-:108B30008271BB0B1A1F1F3EBF24654984BDB3FC65
-:108B40005385E8FEB249BD1DE7F9724C8684F12CCD
-:108B5000A07B22C6BD976A7E26F06FE3F3FDD83D69
-:108B6000BFF7C844A78FCC8DEC43D8549D5BAF9F13
-:108B70006207BC74BE28111D96327F0BC2ECA0E4C4
-:108B800046FA45BFFF9BB195D682A248FEDF4272EE
-:108B900096FC0D80139FDF44FA906D800713A03C74
-:108BA0006A253FDDF8AC3568057C2E4DF24EC3F6E4
-:108BB000CCD59133D71EB14FB5F67F0CD8A9FD1F88
-:108BC000A13DFA7B7F0CFCC1CE6C97DAFD2B1CF625
-:108BD000001A1F1FDBED0AD2ED7DA5E9E4DDF0DE12
-:108BE000F2C78DA427963F9EBCA117D701FC95CD57
-:108BF0002E5D87BFC048F81D70DFB2EFD754E9FC87
-:108C000089872FBB6FC7143C5CB3376FE07DBB42D5
-:108C1000F36BA63D6EF4E1BE5B51645718E89BCA46
-:108C2000C75F7912F7C78AF5568F1926BEE27133EE
-:108C3000D1B7C76E0F38A1DEEFB02BF1504E2CE04C
-:108C4000FCB0B040A5728ACC148B87CA568CAF9EFC
-:108C500085F924027CBAF1A187C7C3389FB0E00D23
-:108C6000E3017F6791508097B307648A3F32C5ABB9
-:108C700054833CAD635C8EAC79ED795305FC5A5757
-:108C8000BF6226FA812B83C60F7A341FEFA2B64C3F
-:108C900094BFEBF823D0C3FAFA756CDB17F2586275
-:108CA0007B13EEDF351D51F5F5D77C8C719C754C2F
-:108CB000F9A047C479611EF30AEC49274703E06134
-:108CC0001EC0103B5B6FCC61B0C41536D887B0DED8
-:108CD000293B797C6745A31C3443FB29893C5EFC16
-:108CE0005113D07F04AD3BE00478C5F7B85E5AC19C
-:108CF000A4A0057EBD66E77A05F7CF2B1E8EA7C51B
-:108D000012F3E17EF8D0EA1E82FEFDF2C7AD84DFE9
-:108D100015BB56FEEE1178AFA7B93A29D29F5EA9CE
-:108D2000F105F4CF2C09E17E3E6EFED7212807A77E
-:108D3000FC00FC6258EF8A78F6939A4CA457EA102C
-:108D4000D5166EB762E33D39BC1DF8D5B0EEC55BF4
-:108D5000641EA77AC14C7A1264838BE4B886CFA5CF
-:108D6000ADAF994C7928D7B775CBD0FE0380651B82
-:108D7000E12BA0E1D184F85A84EFA6F2775CC59A82
-:108D80009DAE92DCF1E3FA6A0DD2A2B9A4077A4D46
-:108D90002807BE5FC0EDDE6D5AB97888FB668A434E
-:108DA000DF6F76A35CC31F59CC03FCB03586EEE5BC
-:108DB0001807663F35533C655DABD56B75909FE2F8
-:108DC000DD8FF3539862C2731795CB97EF6B7CB826
-:108DD0004E9D730DF20DD41F57A07E8D9DCBD135C6
-:108DE000F180776ED77A0D30CEE7F8DB70DE6FEA70
-:108DF000D888F125ED39F4A33AC2FD7619583BC65F
-:108E000065B0FDC8B188C7C41BE6E3FC7E2CD37EE9
-:108E100086C5DF5F8276E18FE502F487176F393A06
-:108E20006D07C2CFE53BB1CBC53F7987F4CCAD1A16
-:108E3000FD7BD03F40BD03F073507668FBC92FF334
-:108E40003851878627C107A27ECD16238FDFB799B9
-:108E5000C9EE59D3FC7BEA778DBD3B05E5F59A1742
-:108E60008CC528D79FD7E6BDA439A3EC38F0D5121E
-:108E7000639C538247AB03D52684576F97080EBF78
-:108E8000973C04F9F4CFAD2F3A907F3EB486B251AF
-:108E90007FF5AEB7BAF7E002B438DD9F5BB3F76099
-:108EA0003C67A9B3DB2E41FDD2DB8727A0BC7FDF67
-:108EB000193261FDFB1D990684BD4E6719C25E65BE
-:108EC0001CC17F0651D6A1F9ABC86F6B254EE7D503
-:108ED000CF1E350D83F18E17F0B8F9A73F7E270717
-:108EE000F5DB9A21DD39A887800F72D210CFCF48E9
-:108EF000A4BFD73E2B7BAD63C37CB016F900F6DD73
-:108F00002A8D0FD61E78F12EDC0F6B91FE9E4BF949
-:108F100008F8F4183DDFBF7B1AE3EF1F433E117AD8
-:108F20000FE05623C6DF4C1A0CE320FCAE864FA898
-:108F3000AFE2F581BC7A1E5733A19DBAEEA031D0C5
-:108F400013716E34109DBF2AD0CED19ACD2477BF35
-:108F5000D2D6DDB3E50507D2F1D31F1F7D15E3C5DA
-:108F60006BF6837657FBD9171A5ED6211E1CB40EFA
-:108F7000B247D6E1BA1D613CF4F1BFB61FD731BE8E
-:108F80004EB1EE758A860751AFBDFF176D9DAB9947
-:108F900086B70323F8FED3F61BEE6794AB627DFE23
-:108FA00004FEBEE0D3F442BE3E6321E7D7D5C0172E
-:108FB000EE3CE21FAF49C809A8FAF4B9DD142F123C
-:108FC000F412F31E5BA80A79E78D4F08D3B1C7C02E
-:108FD000EA3AFA89B3241772FC9D681B34E420E056
-:108FE000EDCFE097A1FD85FCAA448C27F8468C378D
-:108FF000E5477366E07AA1FF10F62FC67D3F10AB00
-:10900000603FEF33BE3F903F517E8A7D39A565E1D9
-:109010008C7C07B6FBD43E3C0FD7CBC71F5BE8A4C4
-:10902000F7BD682FC0FBDE8312C5AB4F687180139C
-:109030006D2F3A9644E0294F7B4FF019FE601C4B90
-:10904000CCB72B81C77FA3E72DE49098F794CD3759
-:10905000CEC0E762FE825F057F0A3C0A3E651B9236
-:10906000C9AE89E657E235A157659DBC27FD784D0D
-:10907000FA1726BFEDD2E7D1709FFDD4EA3A9615D4
-:10908000A1D73FC4380FCA93A7E520C913065C1BBC
-:10909000A17784BE6F5E7F8D13CF198DCF4A6E345A
-:1090A0007D22F4CC362542CFD415AECF417DF6607B
-:1090B000E1302EF793BCA7919EAB4F754F73A8611B
-:1090C000FB75D29721390EE36107323D917A75F530
-:1090D0009963B40FD6B0EE4DE87F2DDEF24EF578F1
-:1090E000E4F7A78D74EEB9B86DAA09FD81954FDE3E
-:1090F000528CFCF441FB7092EFA7F71615107F31EC
-:1091000067CA0DB00F96EE7DE88605F07CE941D97F
-:109110004D721EFAC1FDBBF88E0226D1BA7BAAF1B0
-:109120003CB5F76ED98976FFC4278B3660FB89F68C
-:10913000A1F1B80EEFDE4482BD4A1CE909612FBFE0
-:10914000AFC9CB1623E78F0DDABEBAADAFE4FC335F
-:10915000A5A52507CFE37B77839CC6736993DA11B6
-:10916000C2F15E1A447EC93A70A35C40FF5312B745
-:10917000CFEA4CCC92EAA1E7965478FE9AB1FB0E66
-:10918000D427AFDD61CF6FC609C8178A97707F9269
-:10919000E60176348D2FF026E6714F21D74FD1FDB1
-:1091A00089F7BBD0FF40B9AACDFF74EBD337A03EFF
-:1091B0003CBD2F3B01D7FDF14BD676B4AB3E3672AA
-:1091C000F9D867EF048D1F45DA6B60DFE960B0E71F
-:1091D0007430F0F1477AFB7023CDEBBE429BCE9EFC
-:1091E000137C5FBB3E3B2E320F21DA8E6759D1E7ED
-:1091F0003DE3E3583F724794679A0051C0A873D08B
-:10920000B68771AB62BF7EBE1BEDFEED66A719D6B9
-:10921000F911F23D9E67BD2007F1FC066D74DC0775
-:109220001F3D971F44FF73F97BFE69D8FFB10736D6
-:10923000539EC232B033074911F6F3F71EB801D975
-:10924000FFACDBBF2915DE3BBB8FE75540B52DCA10
-:109250006E7E3555FDC7EDE62BB597459CE2E7855B
-:109260009ADDEC666EC4B3C0AFF09F5E063E28F197
-:1092700084F1F559531DD9CB679AFC547E2E9DB8C5
-:109280007F22F2AF3DCEBD075EFBC5C187E434A4AB
-:10929000F381FC0BE82F97DAE29CB86F3F6B6AA46E
-:1092A00043CB334DF5540A3A8B38DDA4039DF4DEED
-:1092B00067070B0E4D84F70EDBE2B81EB8E49C88FE
-:1092C000D3333A8FE4B6F5E307E173B1AE4FEEE680
-:1092D0007415F3FE64DF2D0E5C57E7638987262043
-:1092E0003D63E39C68F7ADD0F2474EEEE076F5299A
-:1092F0004BDC533331EF64E7BC1406F27659E77761
-:109300006EC0E7CB5F929CE80FB85F9AE3C078EB42
-:109310007F283D0E2796F05E08E7A304659447A5D5
-:10932000D3199D63958614A666D2D130F1CB8433D0
-:109330004A10F34EFE8CE75B1847B910437114A630
-:109340009D5B2DFB198FBFF4F9B99A9F37515B775D
-:109350004A5102E76FEDF99412FEFCE39DCFCFC2B4
-:10936000FE4EEF353A71DE9FED3552FFABC03F3315
-:10937000C07C4FEDE37ECFAA0E89FCE5D3FB406FA6
-:10938000C3BAD6AC377A4D7197F2E114A8EFB18524
-:10939000F970953748FCCD347EB4C0BF8BC32EE541
-:1093A000C778D6B109F1F18FF2A5AD48EFC7F5F155
-:1093B000E3407CA0E10BF731F2A3A0F72AA00B9EBB
-:1093C000CF2674E457205F09FA0B3911A864B9A8B5
-:1093D0005F5B4C2C17F37802861837EEEF3936D5E1
-:1093E00028011EE625F554A138BDBB88CB49798AF2
-:1093F000C16B40FDD2622639102D47B28BB8BDF447
-:109400002CF234FCAF2872723B8AD5933F224AD0AB
-:109410003B19A8C7E7C426FCA70A4D3C2F7C7F81D7
-:1094200002F39F3331E18EE16EE09B171E5FA000D7
-:10943000FFCE2948786118C065453B393C2EA1C84C
-:10944000087073F3AE055500D71479DD45C9E17195
-:1094500044BFF0BC009FFF7CB4BF18CB75261BC96E
-:10946000E9CFA5DEB18D99E1F66F49ECFD5F48616A
-:10947000B8C7C886A09D57D137FFFECB8D45DE7299
-:109480003EAEFEF912C6DA28FF2EF0CBE312F7C784
-:109490007C9614CA6323BE5A62B185C8AF6F379EEB
-:1094A000E9A337F2913B4E41BACED2F868B612EA40
-:1094B000C4F747B256E7490B99523B2F260E2CBFF3
-:1094C00061E3B193A23FE097CF8DB05EE06B09D826
-:1094D000B311B68C0448AE05F9251DFAE55FB1DF7E
-:1094E0009600EBB1121D6A9DC86712F31B2E42B99C
-:1094F00026D63116E3276B62870491EF1B5EF8F4E2
-:1095000018B2D74A61BFF84B88DF6F77F2F5307F2A
-:1095100029F1E31D1A3F7EDCC4EAB360EBCDEEEE29
-:1095200076A830E933B34239B8DFFF34C45F5784DB
-:10953000FEFECE96F406E09F4FF79BDD33A1FDA91A
-:10954000E0F314BF5BADD9A56C6FB2B6EFE550394F
-:10955000B4EBCA1CB907F54B4311D7D76732434365
-:10956000EE41B991C9FD2068477972D3375E938C7B
-:10957000EDCE3CB7396B19D0CFACB0803D814AE617
-:1095800080755F0B7D97006C0458A673E020D10BAB
-:10959000DB3950DFABB7B8789C9EF950AE087A093A
-:1095A0003A5C421F9802DAAD060B33E2FC47B29DEB
-:1095B000CE93B1613A7D6C013C621CCD027884FD92
-:1095C0003D15830F85884F1E7769907A5A1311FED7
-:1095D000B144797797EAC1274D88F2BA9DB790FCDC
-:1095E000117247857FFDC99DAB8E1FED9CD2AFDC0C
-:1095F000790CE50EAC83E5B3FC8BDC4024FAAED0ED
-:10960000DE9D2AD7AA0ACE3BD9E2C6B85AC3E3C325
-:1096100049DFB00BBF217F58B4633B13895F3665C8
-:10962000CA84F79507259E1F79308DA95035F360C0
-:1096300022958EF3A9F4FCF453AF1772B9C4E95222
-:10964000FDC3419594AFFAC311548A7934687C37CD
-:1096500055CEEB08A11D61837900DCF01AD75B0DB4
-:10966000D7CB14DF6428A2539098FCC7676BA73848
-:10967000908FF5D9F9D245B2DFD538A48BAF4B66C0
-:10968000C83FE07504389E2DCD8867B3CBC0D47E2B
-:10969000EC0FB34627AB1AC3D408FF43098CFC6E0A
-:1096A00019C665BF637407A1BEC5EAD883FB8905E7
-:1096B000BCDDE847CCD7DEEBB672FE88CD4DD0BD21
-:1096C000BFD931AD0BF96DBE97EB1DBB7BB06E7C86
-:1096D000B3BCDA884CC6FCDC5E14FC407C09E3CEEB
-:1096E000F649A45FAF9F0FF511FD1ACBBE20396E6E
-:1096F0002CD3DB99669FBEDD1F84DE19C94646D296
-:109700003F8C779B17EDF4B35E3BF13168F7EF9731
-:10971000017C439791E17ACD317C5D671153181F2D
-:10972000F5CA418C9B6C463CC0F3B8123D3EE3BD8C
-:109730007AFC254ED7E323D9A75FFFA0F9C374F5C0
-:10974000A9FE51BAFAB43A8F0ECEA82FD5B51FDABA
-:1097500058A98333033374ED87B7CFD5C1D9DB174D
-:10976000E8DA8FD8B144573F32B84A573F7A5F831F
-:109770000E1ED3F12FBAF6E30E6ED4D5E787EED5E1
-:10978000D517743DA8838BBA1FD5B51F7F7C8FAECC
-:109790007E42CF33BAFA89A7F6EBE049BD3FD7B591
-:1097A0002F3F7F440757B0D775EDA758DED1C1537F
-:1097B0009D7FD0B5BFC6F5A1AEFE5AF5CFBAFAEB84
-:1097C00072CFE9F93586CBBF6AF7DF74EF7D9EE68D
-:1097D0001F558C3A533EA320DFB62C945822C6D591
-:1097E000BBE659500EE4156B7248E3C3E1453C2ECD
-:1097F000C1B2D810946753E5990CE376673BB87F04
-:109800003D90BE8B0375A5448C1BEFB58003198674
-:1098100013A73B7570B2CFA56B3F68BEAAAB4FF5DF
-:10982000E7EAEAD3EADC3A38A3BE44D77E68A35716
-:10983000076706A6EBDA0F6FF7E9E0ECEDF375EDDD
-:1098400047ECF0EBEA4706EB74F5A3F7D5EBE03114
-:109850001D8DBAF6E30E0674F5F9A1765D7D41D74C
-:10986000761D5CD4BD43D77EFCF1A0AE7E42CF3ED8
-:109870005DFDC4531D3A7852EF415DFBF2F3211DAB
-:109880005CC15ED3B59F62794B074F75BEAB6B7FF2
-:109890008DEB84AEFE5AF5B4AE7EF59FDD213A071E
-:1098A000F8053F57BB2EF70B5DBD3109EC5A8C43D1
-:1098B000B218379E5F0AFBA7DAFD575DBFF7160F98
-:1098C00023FB0278A9C72AA37DE4A3F85102261638
-:1098D000025FC6811043BE4257A196E25049A4EFF1
-:1098E0004835A99827047602000986CC4CB4A763B2
-:1098F000C3765BFAC5822BB7DB76409F388F5F1645
-:10990000FBEF2B4E467FE5B96968B7AF64814D38F0
-:109910000FD07B713DB03FDEB4EAE319A2BCD602A2
-:10992000F88918EF35EBF674CF65FCFE6B2D67A850
-:109930007D5FBF5A9C4382F53544F47F3FF8150A9A
-:10994000D875DB9B60FF80C3F8609393E0EF35B977
-:10995000087EB849A57247532E958F36B9A97E6700
-:109960005309C1BB9ABC04079BA653B9A7C947CFEB
-:10997000F736CD27F829F0A3B1DC077E3596CF80E6
-:109980007F8CF5CF82BF8CF04F9A02547634B5D3DA
-:10999000F3FD4DDB093ED0B483E09F3605A93CD8EA
-:1099A000B48FCA9F377550FDA1A683041F6E0A119C
-:1099B0001C6AEA22F8485337C1C79A8E13FC6A53CF
-:1099C0000F955D4DA7A8FC55532FD5BFD1749EE0D0
-:1099D000335ADCF6956249776F4AC08C55113F08BF
-:1099E000FB7016DAF9C81C25C6CF74767E94BD1DAF
-:1099F0004D8F4FB4718C95602E62FC7070CE9E9628
-:109A0000083FEB2D6DBCCD312C6005F9D66CE07EA6
-:109A10006D7302A33C6EA6D9AF2B34BE6449DC6ED5
-:109A20005DAECD6B85C6FF45C89FB9C49F6F5C8D89
-:109A30005F21FCC65163FC27883F330C01F29F6D08
-:109A4000C11CB49FABC7F83F42B97EB67ED9AB34D8
-:109A50009ED34DE78FD5E650F28D181F794DA6782D
-:109A6000DE40E3ADD3F2CD07AC3F7C3A1DEDEDE92E
-:109A7000DFC87EC4D39B46FB7C8C17FCA598FBA754
-:109A80007F2936E8CA77C6F8BFC2797E65AFBFD9ED
-:109A900000F3FF6AF2FAA76ECB0CFBD3B3D1250516
-:109AA0003F680E538D94D7C8BCAF644257D78381AB
-:109AB00085F08D2C40E577F2FC17715D35608823C9
-:109AC000EC2F350FE96F5DD1F38A19CFE71533DE3F
-:109AD000A02BA5B17EEBF8229C9797E6F5E6846B68
-:109AE00072705D625E956355ED3E44EF2E9CDF57CC
-:109AF0002F7D71521A1EC6BFF0DB375568F928EB6F
-:109B0000251E9713F69A96CF22FC8EDA3BA420DA14
-:109B1000EB0BC1DFC173A6F734FBF33D2BD7CF6747
-:109B2000EB8D24276BA518379EC79DADFF0F1BB289
-:109B300035B467785ED282894250DFF2AF12F159B4
-:109B40002DF463807E8AC666D27A6A99C58BFAB88C
-:109B5000F6907937F26B2D987FE867019FE48C4788
-:109B60003E9920074C6007BF6908E648742EBDCCBB
-:109B700024C1FC5624017F0C1B980FD66AF719C428
-:109B800073E02F37F6F7D9CFC6E7521CFFF0041564
-:109B9000F1D562E0F79802BF92DD3C3F868B687991
-:109BA000E2188A4F32C5EDC6F852B576EFA5536676
-:109BB0008DCFF5233FE78EE7FBEB4D97717A90FA57
-:109BC000D59FD7CC18CFFDD0195ABBEA23AF65E09B
-:109BD000BDADB55D46F24358614F9ECFDECF7A1AD8
-:109BE000B7DE9915C1D7EB0E9EE0F91AAC272F32DC
-:109BF0009FFD56AD5FC147B2C9EEDF6D8B9C1F1F45
-:109C00001FF87A0EE2E1AB78E0EBE1C4D727D1CEC2
-:109C10009E6556E36E84B207501482D2FF0327E597
-:109C200027893CA5A5CC47E50A6003E4635FE00112
-:109C300013E27F15EBA0E76B4B6E1982F03AD65B0F
-:109C4000E5423FA2BDF91517CC72DEF607A6625CAD
-:109C5000766E70F12B58CED92B9D44BF15F6C512E8
-:109C6000E4E31EA9BE6D308CB7E0D98AB634783EE5
-:109C70004BE6F460AF737A00BF78E5844BD709FBFD
-:109C80006015ED83782FAD43764CD7ED83DA8DCC1C
-:109C90002B2585F3EDFBF645C9AD7F4A433F48E9E7
-:109CA000A5F3F77587CD0948E7558CEBEDB01D2876
-:109CB000F435B7036E053B00DB7DA2F1F327198C69
-:109CC000EE357C228163E709DB916C88DFE5191EA4
-:109CD000D6BB9F1882C58EE1A4979B71BEAFBAE632
-:109CE000A9182FBB35C9E296B13E3E38849FA3F632
-:109CF000C9777631361CEFBADFC8E34FD1F3924A09
-:109D00005EFD2BDA0D66130BE0B906EC6B568CFB8F
-:109D100079B089F6590BA216E366953EB5BFFE5B96
-:109D2000B57EBBBEE6FE6F00D683F77C2E19C7A9B1
-:109D30008D13C3C711FA03C723F991C274E3ED1958
-:109D4000CFF7F59B762FCDBFD9104FF2E60F43FD2D
-:109D5000BB91EF44DC47F8855D991F6791FF7EA1B9
-:109D6000251DED73E05F9EC73899CBA5378D6A003E
-:109D7000E1372B3229EE2FE4EDEC121E279B2DE26A
-:109D800062655171B1A8780C2BEB3F4EC698DB8809
-:109D9000E38E64EF09FC501CE6489942740F00DD25
-:109DA00031CE7C44F34F2B62B95F9E509248EB4C0E
-:109DB000B8368BF8CD91C842740E659789DF8EB2A4
-:109DC0007C5B42849CB8578BAF6E033B8845C4D5FF
-:109DD000EF2D6CB060BEC1661BBFFF785F654C5D48
-:109DE000647E7CE2649EFFF2C3C915AC04F0976701
-:109DF0000B5692BAF62A2AAE47D2D637DA09F83786
-:109E000060D73E2D4EEAB6F0B85415E96B41F72BFA
-:109E1000D5D7CF28C18D31B8FE2446FBD0BEC34A6A
-:109E2000F254EEF08630557BD9E4B9EF223F33C5CA
-:109E3000978BE37416C7301BB4FFAAD344FEFD61B1
-:109E4000C3921F9870FFBD6B6678DED9614F535087
-:109E50005F747C3DAA8A4AFBC4698CC739630D20B4
-:109E600028F29DEC897F43A269F7D54CAEA3933EBF
-:109E700002147748AC8B51DCCD1B6B009FACC3C088
-:109E8000CE95C3FCF6DB3C0F8D2316F4C9B8DEA1DA
-:109E900093FC9F227F15B37A82EF33F9EA76C3F8F9
-:109EA000F72558886F3CA906BA3FC8FE6AA3BC1FB5
-:109EB0005F97624415F76299FFDCF808BBCCE73284
-:109EC0001831FFA7CD04F23B0FE32831FCCC8A7197
-:109ED0007BDF773E87E6F78D264F5B5DDE6EBC88C5
-:109EE00032205E9D4A6F5FDC84F8329DE27D02CFB6
-:109EF00091F47416EBE8E93746D2B304E8392692B8
-:109F00009E5EE96AE8F90E26A1155DCAC7814AF589
-:109F100081AA42AEFF30952E9A8F2BCC936C980776
-:109F2000D3E9900D48D7CE98B43C8CDB093E167C23
-:109F3000DD0F3FAF3F8A72255D71E279B2B93A8693
-:109F4000CE67047F0BBE9E5EDAC7DF8F95023E1799
-:109F5000DA7C5351F644F337C6CF22F9B876407E07
-:109F600067CEC87D3E0BEC8DB804B4934EEDED8802
-:109F7000E0E3DAFA2F142E772E96C71487E37DB329
-:109F8000CA24F64124BDE1FF07B9DAFAC84E52C827
-:109F90003F1378BD52FC1BBFD39C8B76DF26BCFFE2
-:109FA00008F86A97DCDE411807AB3F711B3E6FD3A0
-:109FB000EE2507F24CDC1ED3F695E86FD9E4CA69AA
-:109FC000B8FFEDE3CFC42E87765FA51854444E9BAF
-:109FD000BAE4DF689F1E8F65F89E23B1BBEE09DAF5
-:109FE0007723189E277EB5D23F14CFF7B7009D3E4A
-:109FF000A0A4EDE020039D7DF50CC27D07C875F19E
-:10A00000D2EFE2CF99561F24F80F138669E78C5ED2
-:10A01000AD7D0FB5DF62DA6E89C171322DCE3D1193
-:10A02000FC5FAEC5E35B4BC4FD9F1615F3DF5A4BD7
-:10A03000B83DFB50D3BE491F65E37C3A267D04F34F
-:10A04000499C19647EE0EB98DC808AA923966FA670
-:10A050004878CF818D621D18A7C7E7CD63C2FDAFD9
-:10A06000D4FAB5A09D03F4B36C0CA89172D662909B
-:10A07000FCFDE5C9FC718242FBD5B29151BDE5C83A
-:10A0800023F4FD80C42CB784F9D5968DDB199EDFAF
-:10A090005843FC795296575A1AD16FD24C9877048C
-:10A0A0005F007F05E2402E59F6006316221D6228EC
-:10A0B0005E193DEEACE4CA2EC531309F44F31BD38C
-:10A0C000F84DF08D5827DD8089F80E40D5300BE92A
-:10A0D000C9B646D36EB4CF7795C4135EBE4CAA8C76
-:10A0E00063FDD8A7A2DC057C1030A33F6DA1720FE1
-:10A0F000F8E38111E84FBB087E0AFC712CF7813F21
-:10A100008EE533E08F63FDB3E08F23FC13F0C711BE
-:10A11000EE007F1CE1FDE08F237C00FC71847F0A50
-:10A12000FE389607C11FC7F2E7E08F63FD21F0C735
-:10A13000112E37037FE07A7203AEB940D7F6BB4DDC
-:10A140005ECC33FC6D0997A747BDC312DD407F6B22
-:10A15000AE8162E5D6371E64B81EABCB40F7CC3675
-:10A16000B91E64B7A09F5B6C277BABEDC7DC8EB1DB
-:10A170002A0F31943BBBA4401D73C3782537D5E229
-:10A18000B960966B7D6502C0474A16EFB4C0FEC841
-:10A1900051E7CC6F8E8055BB67D573CE303C346FA2
-:10A1A000B7029E0CFBE5C15B76E215239C07E61720
-:10A1B000BF55B2BC16F3EA43C318D923BD9926CACA
-:10A1C000E3598AF4CAC6F9F373C0EB588B0BCF3945
-:10A1D00087AAE02D49D49EE24C57DAFEB7252A3DE6
-:10A1E0008F7EEF72ED0C8557D48EC997E90FEBA5E2
-:10A1F000CBF46391E659BA61EE5B8D9A9C4AB691B5
-:10A200009C6AC7B80FE0BDDDCACBFC52BECF8DA59E
-:10A21000950F4F80F2E1099CAEEDD680B312C71FB7
-:10A2200063A03C07D698F9CE3018EFCE5F290CF327
-:10A2300045057F9ED1F8207BA89DEBEB7B2C74CE4F
-:10A240007FCDD01FB726009CFD84DB8DF9105B9974
-:10A250003B06F924B0CD4079913F2A1C9E30079AE5
-:10A260008F2E7A2101E5FA8C097C1E412D8FA8B929
-:10A270006DF9508C537DF51697877FD3C6D96DEC59
-:10A28000AE277A16D918CFCBDA4EF648B30B880D25
-:10A290003AD390CA4B93D1B900DB99C030C0BC6DA2
-:10A2A000D3D7E32DE80FB69C374FE779B5DD649F30
-:10A2B00098AC7E673C3CDF1E30905C68516D940723
-:10A2C000B7D5E6E9C27BD301A781F265B7E61908E5
-:10A2D0008FADB61B82E8072852731DEAB1A073BF89
-:10A2E00025139E07F30C94FF18F4CE9D8E70C0CFFB
-:10A2F000BF47413F58EF4FA0FBE25B59EFEBE3B0A4
-:10A30000BE96DB696D29FF752416E3E2D73BDDFCC1
-:10A310001886A9983746296406F4C77B36C6E23CFE
-:10A320006A98E6EF06C8BF759839FDBEDB79AD7354
-:10A3300018D91911E75D668CE1B92D6EA81F6BF372
-:10A340004C47FF53B17B2C9817D8EAF45816D3FA30
-:10A35000793E1BE56B40BF2D4E03F9C1587F0BEED4
-:10A36000F75646F97083B5FA56DB839D880F651959
-:10A3700063992ACE4F09449E275A869775A9B08EB5
-:10A38000F6E509B40E457213CC962934EFC16A0C78
-:10A39000DD937EC854DD85F6E460CBAD74EE955A4E
-:10A3A000A7E8CEA506F9F570F27C3D9CC894F0B9FB
-:10A3B00016F2D9041197D3E32D1A1FA9CED6B77080
-:10A3C000FEA97EBAC47BC9FC1F717E2FBE82E13C10
-:10A3D0006D34CF14DB920AB49B9299AF19F9EF1F39
-:10A3E0009DE758E75C4B268C3F36C940E6D138D60E
-:10A3F000BB11FBDDAAF17B7B26A767785FC9625F93
-:10A40000364D48C6F305033874E1FE3303E0D8E95E
-:10A41000CE17127470F6F6C1BAF623760CD3D58F28
-:10A420000C8ED2D58FDEE7D1C1633A4A75EDC71DD8
-:10A43000ACD4C1F9A119BAF6055D73757051F70274
-:10A440005DFBF1C797E8EA27F4ACD2D54F3CD5A025
-:10A450008327F5FE8BAEBDB0EFA3F5E3DD13B87D2A
-:10A4600071B576BDD93558F7DD9C68BF21DAEEB7F6
-:10A470007CD3A26E447E7698889F15D4E7780E7DB3
-:10A4800037F79F2C93DD2AE5396BFC5854EEDD84B9
-:10A49000F2B4C26121BDA0D8783BC5368DEC9521C0
-:10A4A0003B4CF43D1FC5C9FAEA63513E37052665AA
-:10A4B0006587E76D756E67B87F2B1CD319E6298910
-:10A4C000F715A797F9318F1B3FD28376923340ED72
-:10A4D000AC2ABC1FB18EC30603B3A11C073F0FFDFE
-:10A4E0008381FC3AE1CF09FF6D20BF4DF86B430C2F
-:10A4F0002C06CBDD52CF6DE8DFE7D5BF553988910B
-:10A500005FB70FF9F53EBC078EFEDC586E67B5A548
-:10A51000CC5031DED39ED9D1350CE7936CA0382ACC
-:10A52000D8CDEEB911F6E2DB9AFE5186B5F7A0FE62
-:10A530006B88B7A8682F2996DD933E027CED32F632
-:10A540003C8DF18B56C9B9BA03E5E2DD36CA0F7905
-:10A5500048C39B6A37146C847E3B9ABD0ADEF7EFD2
-:10A56000D8C2DCADB83F922A36C6C3F3ECF4C506B8
-:10A570000C138DC86ADE88E5B109FC3C6864DE6EA8
-:10A580004322D48F2EAC988F7131D9B99BFCD981DD
-:10A59000F84976EC60B81E96A59C44BE42EBFE22BC
-:10A5A0004CBD2201E80DE35A91DE12958407EB7948
-:10A5B0005BD08A7016C78BD52B0563256EB7627E7C
-:10A5C0005D45C20EA2AFB067D1CEF5737FF76DE4E3
-:10A5D000A3A4997ABA2A96BD848FAD06BE2FDAE37A
-:10A5E000D537503FB7676625B4A8E1790AB9F24775
-:10A5F000CD0E17CF855C998D3938C961FB06F87C83
-:10A6000007C6E7ACCA76BAE769DDB09D215F5BF1AA
-:10A61000563CD9FB01D547FAC3A7CB4FAB1A36DF5F
-:10A6200082FAFA5C9287EC596BE34F697ED178B37A
-:10A63000F6F03CB581F0EAC87994F43B086015FD6A
-:10A64000FE2329B6BAC8B8A828EFD2FC13A3C8279E
-:10A65000024F02F5D93991AFE48DE5F38BE7F0D1E4
-:10A660009C0534BFDB923D832E676F5BC1DFF447EF
-:10A67000D07D8BE2B3201EDA2ECC994EEB56683398
-:10A68000B0AD5FE7EDA678B3E62FDDA5E1B7B58401
-:10A69000E3738889DF337027CDA4EFA40DC6F84893
-:10A6A00041385E32AA94E737BA034CE6F1BEBEFCED
-:10A6B00076C3C571346715EF1FE09920F2631AE382
-:10A6C000FA0C9A74623ECBF076459F0FAFE9F334F3
-:10A6D000FE3BC87F7DFD881D7A786430EAFD00FB73
-:10A6E0000DEA7BB477299EB14F5FFF18EA6D901396
-:10A6F0004B35BDCDB6F3FC120BCCE822D7B761FDCC
-:10A7000007F260564777452CF49351A2CF3B498B13
-:10A710006C07F8F3AC34D0BD1211DF1178F7D519FE
-:10A720008C26E27F55770E27E239D1F25ABAE7CC70
-:10A730007ADC5715B1B12ACA598C77F8CDDC7FF78E
-:10A74000833F739FE2FE7D2DFA5F5D32E561097AFA
-:10A7500046D37F6F9F3DEC2B2F253FBAA700FD7A94
-:10A760001CCF1F319E88CB6497FBA7623B119F399A
-:10A770003B5D794552C3F116113F7818F719B4DBE8
-:10A78000EA7EBBFE28CCE3E87133C54AA6CA6F74E3
-:10A7900035619E55864272CE397EF50FD04FAFFCA3
-:10A7A00003D4635C52550791FDDE65A47841A5C6CC
-:10A7B000EF959A5F26E2320BB579D7940A7B281081
-:10A7C000C3FDFF500CDAB9A3F7818CD6F34B2CAF45
-:10A7D000E771BA311DD1F55ECA7F1AA5F103E6AD66
-:10A7E00055A460BA18873B9894E8043A8F9BDF73AE
-:10A7F000045D8CBCD75E8941BBEB392BE78F673496
-:10A800003B2F85496ECCEF4FD9677307A19D5D66DD
-:10A81000CF75C33ADCC7145D9EDAD8437A388F45CA
-:10A82000C099380F3DBC4DADC7A36BB6AD165811DE
-:10A83000967C47A9964792C37290FFA6CAB67CF44D
-:10A84000B31A2A6C0CF16A3E31E2FBDD2857DE9226
-:10A8500019EA0B67ACFA4015BCEF7C3DD1DDAC8644
-:10A86000E9FF0CF8DBA8471EBEE866ADC670FCEB3E
-:10A8700059A067169D4F3BA9BE03E88AF07EF0BF42
-:10A88000B3E87C3A979EFF14FC6F840F82FF8DE53E
-:10A89000CFC1FFC6E787C0FF46F887932B1EC4B819
-:10A8A000D97BD00EF92226FF806538C6CB6D32DD0C
-:10A8B000DF89E6C7CDF51FDA6E049936CA953C33B9
-:10A8C00019F9E17699EE45432733D1BF8D8CBF4509
-:10A8D000C623C3F1B71E49C4DFCC409F519A7FD92C
-:10A8E0001787F3F338DCB7F7E315FD509CF3927E3E
-:10A8F000FAE29D96C047B928B2241607CF3FBDFBA8
-:10A90000DF9F427D24A7FAF7E23E5953F48189DBA9
-:10A91000E7FC5E56BAB68F765A793E6ABA96471405
-:10A920001DE79C3CE5C46DC980B2177F7ED3428C85
-:10A93000134CBEF544C11080BF29FD25877F78E206
-:10A94000F934C0D3D289ED1C7EE8C4B97437E671FE
-:10A95000EC5F88F9C38E44AE07776AF79B047E8F5D
-:10A9600069FB665DE313A4EFC11E61888F96141F17
-:10A97000E9E1CF937A1D8BD1AE4BEE4D597219BDE3
-:10A98000B1AEF1297A7FA7E43E15C4794FB0F0BC8F
-:10A99000554D2F9DD57857E8A5062B07C57C187314
-:10A9A000D1F387B47811F3A6D17B89560E1F759425
-:10A9B00092FEBABF52FDB5CACF3FC98F3EEA18F525
-:10A9C0005DCCCB6B99AED0B9E443368F15F5DBE7A0
-:10A9D000DABAA0FF00C60902532D745EC492E6D312
-:10A9E000BE4E10E324D5523E4382369F63A53121EB
-:10A9F0008C23B45459F6A01C7DD0368CFA6B2931C7
-:10AA000005307E23E08DA5301FC067BC2321136174
-:10AA100021E7447C99E1E91CF45BA92DBB52E44990
-:10AA2000588C6722ED701BEB26FE711B5419EDC884
-:10AA30000D13395F1530F77C7C6E92EA03C88CB831
-:10AA40000E43E43AD42AFD3AD4A9BA75480D9610BB
-:10AA5000DA8F2D53611DD0FE98BD98E61B4D37B19E
-:10AA60009E0F4B55C257F43A99762E25EE1F543A55
-:10AA7000CB0EE0BCA61ABCAD38AF57FE5A9B841F64
-:10AA8000E89BC6EA157C3E3C9C0FD47A35F91693B8
-:10AA90003F94F839DAAD265A9F71329FCFA3A66052
-:10AAA000265D0C5182A9787E3C101F674E8CE663B0
-:10AAB0002FC3FDD592E0E57CECEC7534231FC7F77E
-:10AAC000A66CA47585FAA54F343F47D32B6F22138C
-:10AAD000DF079111FFDF465F41D7E8F334C12F1B39
-:10AAE000263A05BD5DB4CED010DD7923F4A0F6770B
-:10AAF000CEBE09FA5323CEE54C2E1FD9E3C62477E8
-:10AB00002EC6A55BBE91FBBD7F59ABE1A9D9114310
-:10AB1000767A8B83DBE99D8E193AFFAA0AFC2D3CDD
-:10AB20008F96135907EE2B396E01C5DBE441689906
-:10AB3000115BE8EDDFB899DCFE757A2E7BFF4AE900
-:10AB40009175DF73BBC4FE4D98C1ED5F8789ECDF63
-:10AB50009D76D3FCDDFDC89DC289DC4FEAC475F447
-:10AB6000E35F825F49714FE1579A9C7EF20FC53ACD
-:10AB70000BB57D26DA9B9DF50CE370B2C9ADA2BD85
-:10AB80002B6BF764312F3A37C22E10E38F9BC8ED41
-:10AB90008EC1E53C5F53E4C74FFEB554DF1FDED7DF
-:10ABA0004C147649FF7CF70FF00DC9098FCDE445B1
-:10ABB000BBC36373511EF940EFE151F8A984B09C07
-:10ABC000717F532C933E52DC742FA0C3D8F3FCAF9B
-:10ABD000D16F7CC5467AA7C39E4EFD09BBBD2296A8
-:10ABE000517E33F8C9815CE8ECB9BFC18E3484FD75
-:10ABF00063F0D7364F8C38D73CD27092CE8BA2ED13
-:10AC0000D5E8F843DF7E773C95C9E7134CC5FD2BAB
-:10AC100035940C42BE8ADEEFA2CC70158C5A0AF332
-:10AC2000CA48CDA7523C7F9CC9D3FBFB6EDBAE3E2E
-:10AC30003A703D3D12068B93493FEFC2797F7AFB14
-:10AC4000DB296E15EFEB7E417AFA6C7D49DC66E418
-:10AC5000F7DC0492AFE9DAFD33319FF4959DF109F9
-:10AC600036CC03EC1D89F973C126DFA82A23C50D54
-:10AC7000BDFDCDF757DAFE63A1A12CF2BB446A52A9
-:10AC8000F7B52300EFAACDE056697F3949FF0939AE
-:10AC900050A1C4573981CF339A98DBA6E2A79B9D78
-:10ACA000143FCBB82813BF651CE5DF971E9AD42B41
-:10ACB000E1778FFAC6D1F2A4C439CC97F555B43FE9
-:10ACC000330631D68D7210F43DCAF92F934273705A
-:10ACD0007F7FF93D3EA38C27F4F5A07329BEBDFC10
-:10ACE000F698A00A5D0FDD00F3C3F9FC4062E99914
-:10ACF000388FA3999B313EF4622CC587E41D59140B
-:10AD0000DFB93ED5BF7F22CCE3D3A07AA761B8B626
-:10AD10005868B7E6AE18FA2EC14EA9FB5ACACBB88E
-:10AD2000C340DF6D8DC6D75B13B95FF9F644BECF64
-:10AD3000325CC59CDEAEC2514B13AF7C3F7D83DFDE
-:10AD4000D601FA6E8D0BD2799EC82BDB66EC9FAFD5
-:10AD5000CACAB87CE993C71AFE2CE80521BF489AF5
-:10AD6000DDB7EF99679E4961FC8AE2307E6E197902
-:10AD7000BE1C9315A4CA18B797E48FE4F47239EB9C
-:10AD8000AC770580BF377F2DF73BBEBD4C93D31901
-:10AD900077BAB07D95EAA6B233A3F8F862C09FCD2A
-:10ADA0006662E608392CF8245ACF37D8875DD6DF9B
-:10ADB00037813C562F138F306979649B8E4CB0E0FD
-:10ADC000774B37D93CDD687F6DB22579285E6F03FC
-:10ADD000B91111BFB2D95E253EB4B9795CCF86F204
-:10ADE00017E357B8FE3C9CFFABB47ED1EEB4268788
-:10ADF0006CEE109DAB5ADDDBA99D45F1D1FD3B4BBF
-:10AE000012A37C088B937FEF3426CBC02CFDC8E3C4
-:10AE10000F501E433F9BF23CDD95343F05AF65B1BB
-:10AE20004D2E8F8BF421E219DE3F6A2F8E8BC4CF1B
-:10AE3000500DCF2D9D7C7DBEC654675501FAB5BE21
-:10AE400094B222EC678905BFAF27DB0B2FDB4F6E77
-:10AE500019972BE17E1E49A94AA47E86623FB2DD86
-:10AE6000E3C47E8CDA775BA3F15CA4BDFFF7C6DD9B
-:10AE70000083940F447821C2847474892E6D183F26
-:10AE80004BECEF3D2E173335FF05E4624519CC6BD3
-:10AE90004DDE07AFF23DC6FD96846B79BED1592DCC
-:10AEA000DF3C3A4F23DA8E11FA47E823E847C67EA3
-:10AEB0001E453B6644781F0DE6128BA5D5F9F87E3A
-:10AEC00049F211BF805DA3E27E91B57CC1E8F56CCB
-:10AED000D6F027394A54D41755177AD2F0BDC3F6A5
-:10AEE0005369DC8ED59F471FFBEB5356ACFFB2AEC8
-:10AEF000F2B2F68A387F1EE8DCD9F12F9FAC8FB40E
-:10AF000057063A87FEB6F3E7230E13C5F97649FADA
-:10AF1000FBF5CD9A1CDA5026E232FEDB901EBB24F4
-:10AF20009F9B5F98E6F199A272FF9DF87C48BB89D0
-:10AF30000580AE87FF5AECF247F473A57816F1FA54
-:10AF4000C19A3D35D8F69484FB74705D50C2787B0D
-:10AF50005A5D87E4BD4CBBD9655C8F8BF646ADFF6F
-:10AF600072A557467D55EEE47A31EDBCC27223E4FA
-:10AF7000CE8C32BE7F8D9AFDEE38F2B415FB3B626B
-:10AF8000F0B5E7A07E7018D42723F6BB71A5C75291
-:10AF900019B1BE163C47EA878ECF94F5D95DA4BFA0
-:10AFA00085BE350A3D91A4E8F4C4BA58CEC7C2DEC6
-:10AFB0005957CAFDA175B1DC2F7FD1E57F02F7F3A8
-:10AFC000E7A59FCC1AAEE23DDB0E139EBB7FDB797B
-:10AFD0004A9F7D63082E16FE0CF2BF5B71FEA2072E
-:10AFE000DECFFF6105D97B45F8E512198F70B9FDF9
-:10AFF00007F6D473385E014E3D82DE2CEABB860331
-:10B00000AD67277E4BAD08E37FDD14C7BDEF82D46B
-:10B01000EF7D8A2FCB84BDD0776E78D938AC8A711A
-:10B02000D84C3C07D3C7490BBAF47051B71E1E7FEA
-:10B030003C3AEEEAFD6D64DC7527EC33941322CEC6
-:10B040009A1E0856E03DF30CD641E7906975093A1F
-:10B05000BC4E96B5FC0CFCBC7244FC374DA93E8D31
-:10B06000EF9FEE5B5780E9EE07542DBD133FC519E6
-:10B070008EE3AA84AF15D7CE9D8A748D8EE766D4F1
-:10B080002BBAFB84D171DCE53BF5F70D7DDE7CF25C
-:10B0900007E67D471FFF1579EDB8DE34CFA5E37FC6
-:10B0A000FBB8F03FE1D2F145BF8F82FC21F9AA7DC8
-:10B0B000C73803ABB01F2524E179F8E07A46DF33C7
-:10B0C0004EBB9D79FB3B57489BC4F1158D671628F5
-:10B0D00027FC4DD19E0DB6F1BCD7C1B71BC81E1CB5
-:10B0E0000C7281FEDEC16AC612014E5BAD923D3923
-:10B0F000BBCEC0503FB00B4DBAF761BA144F1574B8
-:10B100007FD4C6F37A33D6B0A001D7533F8AF61363
-:10B11000CD6B982EEEAEFB2EC1EC12FD7DDF8CA820
-:10B120007BBE820FD2A29E1F2A73EAF605E8B9B44D
-:10B1300049C4275CFF65A3FE83297D3AE1F8539853
-:10B1400087377923E3DFC3898FD1BE87D3775E2129
-:10B150005F047E3D6299928BF6CA56678C01F32399
-:10B160000EC7F73CC6E2191B338905F0FB9D2FC7BC
-:10B17000F48E96009EF0D29E5DED4094C3D6DE1F05
-:10B180006130D9B6EDE99BA747C08EFB5F22989549
-:10B190003015BF2F84B9ABB8EF629C33F6E1F77C72
-:10B1A00063F26C149C8C61FAEFF8B496AADB30BFA2
-:10B1B000A435DBA0DDB38EA887753C35C929F2E242
-:10B1C000284F8F4DE7F90291FD639EF780FDCF80F8
-:10B1D000FE0BAFA27F0B9F7F0A3E023D9382F3C717
-:10B1E0003838F68FF4C5A051E4F85A7F0A0BECC644
-:10B1F000F31D18CF26F1F19C98BF92C2F4F90A7D95
-:10B20000E33961BC31FF17D633FF527A182F478FCD
-:10B210000557478F568397E61B186B233F08BF8758
-:10B2200085DFBDB36AE359B5EF7F215E5B8BC378E1
-:10B23000053B90FA85E6CD17353C633E628AD344E0
-:10B24000781E086F479C3C7F6A8B3326D89CF9FF99
-:10B25000805E2E4EAFC8F1D09EBCE2F116C0784998
-:10B26000573E1EE217F74F1F7E81261B53AE1CBFB1
-:10B2700030ABC095E0F708F46B88C06B384FE9112C
-:10B2800027FA0556A3CF82799BCF4FE2F98F7949F0
-:10B29000732D94B7903C97F290DBF26C9457DF9645
-:10B2A000F51D8B31424FB7E5D5523DB4A7FCAABC82
-:10B2B000500C8629D818D64D71802D65552EF40B6B
-:10B2C00003F53C5F4BE42F097DC8B4F3515A17BC1A
-:10B2D0001837E940EF1168BFA5BE90F2D3E2E2FF54
-:10B2E0008BF2B2B6D6B9DD58FF189E63813DF1B03E
-:10B2F000768E858C4AF1B4B1A54FE0B9AF27BB413A
-:10B30000C2E3A6F4D57AFD34382AEFC7F345772592
-:10B31000E677B1C53C7FCB55AB44E943FDBEDD8A42
-:10B3200078E579564189E357D7DFE949C9A4E7B6FB
-:10B3300064ED6115D0EFF3D097ACDF5F06CC778A70
-:10B34000DE8F8AC94BDF29630D069A471AA6108043
-:10B350008AF38C99E95A0CCFD39729F4FDDA417915
-:10B360001B28EF09AC7CB237F2F2DEA844F89275E4
-:10B370002ED5AF237A5DD1F316DF5716F4F27CE1B8
-:10B380008E45FFCA933D97F2D2E847EC77396A3D84
-:10B39000600F5B930CF45DB998AC8875315D3BCD63
-:10B3A0007FFB9F857F3F8971FB39FA5CEC7FF1FB66
-:10B3B0004766E6B698E83D715F879FB70DC6BD83C7
-:10B3C000741FC2787E78F4FBC5FC7DE6E2E76FE689
-:10B3D0001866C1FB3AD2AA188A639ACD00E37D1E93
-:10B3E000ED7B658F6AF1B6668929A99EC8F1429402
-:10B3F0005F2F5BAECB42BFE188659E93EEC9697E4D
-:10B400009431DE47F98D2C3741E78F1ED1EEBB35E5
-:10B41000ACCC1C84F1BB38A8EB46BF5A715B90DE04
-:10B42000226EE218DE7313EAF16193872FB2002EC9
-:10B430000EA3135CCAD8B8C3193FC0EF148BFD69C3
-:10B440003ECFBFF7D1072BF5943F623E3F44F73C18
-:10B45000A4F96102F626295538DE34F40F92F1DEA4
-:10B46000B8B315DFAB00E4E8BE2FA07D3FE4D2FE09
-:10B47000D375CF43E05F479E0B0CDC7FACEE3B0502
-:10B4800066F077FAEF3F27AA7F67BFFD87FB4DD4B1
-:10B49000F5DBA670B911488A09F617DF5B36B9F2F9
-:10B4A000BAC94503E7B72D9DACC5E12C20FAF11CC4
-:10B4B0004AE39FCDAE7ACA779363F8B9A911C4085D
-:10B4C000F2D3517B1DC92D96AECF7713DF2769C309
-:10B4D000EF8E407DA54D6FAF57B0DEA3E324F4534C
-:10B4E000F5F6FA645439783EC5A2EDF87A3A273574
-:10B4F000A6EBE5C2456DBF18EC85DD941F976CA3E4
-:10B50000BC8681E20BEF3531CADB32C6FAEA51E77D
-:10B51000FDEBE1F143DB4A008EE37CB6F5F0CC4570
-:10B5200018377A4FE3E736900374CFB561D06E39A0
-:10B53000A2DF5A53281BF54AAD81DF17A01F18FF61
-:10B54000BDE4C114678D1E577C7F46C00BEBA54937
-:10B550005911EB7B4FDB1F7DE3DD96B61BEDDABEA9
-:10B56000F1CCA1221AAF2FFF481B2FE5EF1BEF8F65
-:10B57000DAFE16E32DBC53BFBE85A66E5ADF42ED40
-:10B58000FBA762BC3FE2FA32FF8EF1B4BCB1BEF160
-:10B59000EED2AF6FA1B99BD6B7B0CFBFD4C64BF92F
-:10B5A000FBC613F90E66737D1DF2D340790F22DFBF
-:10B5B00021C795A8CB77C09B2715598C3D2071BE1C
-:10B5C000787D72CD0F30CE7F6E66839BEC14CDDF1D
-:10B5D000A37B4432DD23223D3A3B9DDB21A2FF7D4C
-:10B5E0004D25CC3B82C783B0CC2D93E89EC2C812B8
-:10B5F000C98BE76C3B417EE077F476C13EC7FA60C9
-:10B60000938BCA3D4D2A957BC1BFF452FCCB4DF0C4
-:10B6100085C9DC5F7C20D559B314ED8F8A189EA7AD
-:10B620005D36112CDBB0FF06FBE58815F3216F605A
-:10B63000F9F8772D7376707C2655A5D0F7F663F26E
-:10B640008F753701BCB9445631FF7CB3DA7F3CE7D4
-:10B650002F5ABECF662DBF3280F72E49A9803F59A1
-:10B660004C7F3F8BFFC833E95ECEECBBE2C9BEA97D
-:10B67000FD4E8FDD09F3B859CAFF6D16E0E34F9A0E
-:10B680007DB368C80C9207D1FE69126AAA42CC3B0E
-:10B69000948341F8759E7D1EF9B7F3AE672C01DEE9
-:10B6A0009F8DEF819EFAB5661FBDD96366E8FF05E1
-:10B6B000AAF8F9F5CD1BF47EE903D69013EDC20785
-:10B6C000F29318D2A3F6767DFD6613DF6FF3A2FC2A
-:10B6D000D4D951793FE23B8A9BF1D7098C7D395906
-:10B6E000FB8E9196F7B35F8B33B1F4044A0617F7DC
-:10B6F0003DCD66D6EFB9A4E82F11041DBD97E42512
-:10B700003C88BC77263F9B8FEF8BF1C47B8F4ACF61
-:10B71000A65E2E6E0A76E0C99E5CAEEFD15EB7964D
-:10B72000EBE7796EE6B0EF56B1FEF8B657C1388553
-:10B7300098FF3F8B5F8FE27A414EFF7ACA9785FC74
-:10B740003E5E3A8BBC8727F2BFE6F5C10A7D9FF8C3
-:10B750007A01BA7AF390DEBF9914EBBE97F84FB333
-:10B760004742EF1A2EC65E7D7F7DF370793374F702
-:10B7700060B5FE06C2F340DFADA09FE2709CB7A5A6
-:10B78000D9EDA27B77C9FC9C6D7052E569BCE78559
-:10B79000F51FE8F84B7F9FABA5F36909FD96C7F04D
-:10B7A0001E9C31224E54D721B5D9B0DF208F2B8576
-:10B7B0009EA6F86F7A5D486ACD0BDF1B8A968BE9EF
-:10B7C000ABF5F7D2A2BFC7586DEB512415E3FDBD11
-:10B7D00074DFB1AD5C3B9F411C63BB646E4FCA69B3
-:10B7E000069E2F3254E5F66556EF90C8F38E55E568
-:10B7F000DC6EA88E7DFB761544AFBFBC6311E645B9
-:10B8000055C7BD7D7B26C0B7943FB708BFB3589DD1
-:10B81000F6F69799206F9795EFE7F0E8B7BF1C060B
-:10B82000F08AF2E7398CF91E80A495E50716A1BCD1
-:10B830005D552EBEBFD84DF7BFE554CE477F776923
-:10B8400036F4BB2F6F2B17714B46F7BD7D877E7982
-:10B850001CE5944FC479BDFAF34DA67D7FF13AC142
-:10B860005E490EB29766E0EF80CFEBB4EFF6182C8E
-:10B8700021C2EB88F07751BE7735DFED09DFB7E7FE
-:10B88000DF9D6A69647EFDF715BD1AFFF3BC2131A7
-:10B890001F31FE25F3C2EF0B2644CE6B27F523E6BE
-:10B8A000F579BE39208D0B9FD78A797D2EF5EEC2B2
-:10B8B000A047CF94DEC548D7CFEDBD43F0EFAB94A2
-:10B8C0008786FA094EEEDD25B9236023A7E323E539
-:10B8D000FF87ECA951A9DE47CA317FCFC4BF83D00F
-:10B8E000AED9915B93FD01F4EB81DF286F3390C1FA
-:10B8F000EF3B5415EAFF0EDC131A7F1579F9F9F4C2
-:10B9000054F3F6FAB70AF1BBEC126B86F6EB2E9CF9
-:10B9100033A1DF5F7DE88409FDFBB5074E98D07F3A
-:10B920005F8B30F4B376A7A9DFBF4357EA95C5FE16
-:10B93000D5F92BAF64E4B425C17CD62EE5DF016BCD
-:10B94000F859FC54841B16E32AF1EFF93D37155FD3
-:10B950005BE8EB6CC37211EB7905CF256AFC7A3F8B
-:10B96000E2A63ABDDDBFB05E6FAF2FDA0ED401BDE7
-:10B97000B6A8312DEA7B80FC3B83351A3D6B5CDB3E
-:10B98000BAF13B06352CEA3B83011E47BA89AF006A
-:10B990004A7D7CA41AFF9E15AE63B54C71DE57320A
-:10B9A0003629784F6E5DBD44F97B530F7E61A27AD4
-:10B9B0006887E74A2983F9F7F484FC14FAFDA6970F
-:10B9C000761B315E10FDBDC145F3A7D377C5E7AB4C
-:10B9D000ABB87E1FFABBA909F03CFA3B82B507B9A8
-:10B9E0007EAF6D9482F8DDDE9BEAF4FEC042D6DDC8
-:10B9F00086FECCC27AFDF3458D7AF823A1D746B3F3
-:10BA0000D1B83F4E974B0AED170D3E93F1BB37432C
-:10BA100030BE3BD5C7BCC027AB4DA1B1A8E7DCA960
-:10BA20007E82453D3C5F8BF27FA07DF8FF4BF9DFC6
-:10BA30005818855400800000000000001F8B08008B
-:10BA400000000000000BED5A7D70545596BFB7FB07
-:10BA500075A7BBF341E73B31045EBE58244D68D265
-:10BA60000441778AD7DD494FF8723A40866008343E
-:10BA7000B350152549478953B1CADD341063072DEA
-:10BA80004B59B4C0F28F06C5D51ADD0D92C1CED286
-:10BA9000301D302C3A387676D08171B582CB3A524F
-:10BAA0008E9088A3B8CB167BCEBDEFD1FD3A2F8AFE
-:10BAB000B353FEE16E527073DFFD3EF77CFCCE396E
-:10BAC0009710E1A3B1D984E8082537F484EC344811
-:10BAD00056E7024202EDD47E5024A419DB4D84FDCA
-:10BAE000DC28C1FF797F56D74FAE3B244A480DCCA6
-:10BAF00063F676119CE718B51E844FB5822464D98D
-:10BB0000E03B254D0369D0177F96C4CB05928E90FC
-:10BB10005C427E43C66CA48C90592930610E94AB74
-:10BB2000A78502B0EEAC5F6D0A50986F9683DA7508
-:10BB3000B0AFE5B0E3EE6A2C05B21ECABB0542CC3D
-:10BB400050CED20F34E1BA649ED17A90EDB7809096
-:10BB500085842CC33F619CF432A11FC37970EBB87C
-:10BB6000EEF2E9A7BFA619307EEFE3137A28CBCB1C
-:10BB7000A4EAA7607F8F99F9FA8F0DD1D07698A7A4
-:10BB8000C376EA1CF6CB97085BB7A3202D8AFD4944
-:10BB9000D8F0C79BE72F8576D14AD6674165858D5A
-:10BBA000AD5B28D30E56261F433F1A75E96E5442EB
-:10BBB0003F79DD1F794476EEBCFB06289EBB9804D6
-:10BBC000B65358AF0CD6413A2A2521A6C04518DFF6
-:10BBD00008F7340DFAE90B7DCF2F8171ED0563462F
-:10BBE000528AEDE346EF5CCD7EAF2EA9D1E8270166
-:10BBF00001617F0F58395DEAF4D73380F2E4816345
-:10BC000065F9C436F97E94526FD21151E107F86795
-:10BC1000B05A88383B5E5F3E3B5B555F692F52F5FB
-:10BC2000FFC9A232557B8354A96A5F5DEF50D51BD3
-:10BC3000BD77A9FAAF6D72ABEA2905CB54FDCDE211
-:10BC40002A553D75F63DAAFEE9F69FA9DA49CE4090
-:10BC500081379D10A32930E6033A04815717C1FDAF
-:10BC6000A518D382741A219519D0194A8BC39C86C2
-:10BC700065707E4A14EF2D785B4615D653DE7CB096
-:10BC8000208A549FF68AC909E52F68C8950D73006C
-:10BC9000997C0340C7390F13299440CF636E1DBBB5
-:10BCA0004FA5DC26F9FECE09A5ED25B1086E047E70
-:10BCB0006273F07E4C16F813F9F88829847C3C0FE7
-:10BCC000E6248BE3F32CF138BB251CF7B0B414F950
-:10BCD000948489B502FA1D30C2CD423D70C4C8C6F5
-:10BCE000D9C2633A2941DE042797CFA7BDAEA53854
-:10BCF0007F47845A09F2F7DE8F8CA20DEBC319122D
-:10BD00009455DE8F8C242DF1FB05237EEF10C62D7C
-:10BD10005628FF69405F1FD2E09341C9C8F8F95423
-:10BD2000B191C94FCB83FA500A65FCBFC209FCD65A
-:10BD300024CB61CBA1F1A81ED66F013D13804F4DDE
-:10BD4000E27D2B08CA93CFC0F48D097E519E9E2EB2
-:10BD5000CC3840E671F92179846C94A5E99E45516F
-:10BD600003D2ABB9D510D74FF06FE31ACF255A05E0
-:10BD7000F376267D9FDEC7E47B63A2BE427A49E963
-:10BD8000391F833C924A62BB01F272CEABD33CD7DF
-:10BD900009B7C0CE75CEE766F47E1AE8A6A748C7F5
-:10BDA000643A71FA7D1B7D5EC5BB4EB8A7E47EFF89
-:10BDB000E2A6BCDF14FAD2E2E4ED0768AC1A95996A
-:10BDC000DF6B617CDA6CDAB4F5A203E9FF651F452D
-:10BDD000FAFF92921498FFFDE137F344E4F3432312
-:10BDE0007963309F7F60248F009FB519C4ED420EA8
-:10BDF000E303FB76B8978E7094EDBF7DC0318CDF86
-:10BE0000DBC3D48EAAD03F38E161E724637DD6340A
-:10BE10005C577B5F31598FBF2F898CCFFC3E5833E5
-:10BE200007C7A7844214EF1DF410EE6B889227A178
-:10BE30007EA0DFD414D298E70CD21BC6BFD16F24EA
-:10BE400002F0491B8CC7739C2A3E653421DF1C829B
-:10BE500073513CC768632ACEDF6520228DEFEFB3B4
-:10BE6000E2D88778FEF39B0D2400DF776ED6337A15
-:10BE70009FEFD2B379F45BFEA3AF08EAEB80FF52E9
-:10BE800060AB27375F3D5504F39E6F853A9CD7BD65
-:10BE9000C5C0E46FDDFD94F54FE65F855F9F95F9C2
-:10BEA000739D4FCD6FC9FC3A894F5BBF1B9F7E15B9
-:10BEB000E7D32AB4B370EF75F9C83F0F11FB419473
-:10BEC0009FEB270DF9B0DFD23EAB7D07D4E7EA4305
-:10BED0008FE4A15E38C9DBE7B7EDA75CBF88F7E068
-:10BEE000B98A8246B28B221FF1FBB23845568A646A
-:10BEF0009CA6A2BC0AB152D443B0B484F7FC9A8188
-:10BF0000341DB2E177AE5FE6BE5EB07F5702DF0E52
-:10BF1000499C1F15BD576924BE4369D87FE0B6060A
-:10BF200098E755188FDF67C8F355948D7B1AA09C4E
-:10BF3000E3E47A3047DE87527F4FE67FD22A50A46F
-:10BF4000E34A13A7FBB2EEE87A3C47E974DF6DA839
-:10BF50003757CC78AF0DED5AB0F42D9B0FF747EC67
-:10BF60003AECEF97E97E72F11F9EDB06E735DF6E54
-:10BF700061F7DA70625F0CEFB9A35C2078EFE68AB4
-:10BF800005F93E0DFE534AFFB512E2CB8ED73B2298
-:10BF9000131E4943AE47DD5CAFCE35F2F393081074
-:10BFA000A990E963615175BC9F727E4276B0FEE64E
-:10BFB0008A17D83D6DBB9FCC67708A3CC5CEDDDC4F
-:10BFC000364A37C13C6B0D92210DE8FCDEB4A6ADBC
-:10BFD000172B0879AB0754241CE44C8F89F8FE0A10
-:10BFE000F0528F95D5633D05ACFEAF3D222B7367B4
-:10BFF000787F84F4697CA3B302E975B2F819AF0BBA
-:10C00000D6B972C6C0E840888BD1699BCC7B5723D8
-:10C010007A6282F6AB833444687CFF1BAE15111F35
-:10C02000E893DFE37A30B0BDFBB74CCFD95B273C58
-:10C03000621AF2D5853EACFBBBFFE441DCF021D8AF
-:10C0400009E42F7F9892029867FDB56C36BE3D3C9F
-:10C050006A14910F74E31EA47FE03825C897FECEC2
-:10C0600009A63F9F837349B0EFBF756672BD1199F2
-:10C07000AFE3F7B980E314F9FE87E7FC6706EA2F20
-:10C0800053B7F8CE5D788FA7F5EC1E77B9C633AC01
-:10C090001AF7720EE625297CFF5826B737190315C3
-:10C0A0007618D724F36D72FB43323F02850D881357
-:10C0B000F08702DDD6CBFCD50247990678617D98E2
-:10C0C000462D20B72D11F72501CB4E4A3E52E903EC
-:10C0D000423E4AC0C953F1DBAD961D385F45BCBE38
-:10C0E000CE079326E09CE6D65434A209EB07185FEE
-:10C0F000A51497E7FBBE01DFF9C700AFC17D75004E
-:10C10000101281EFDBAF55B2F2F2D0A322CA89C977
-:10C1100032FE0CDA05324BC7707D7B408D6F36CB1B
-:10C1200072BBD9CDE5F929271510F782DEAAC473B1
-:10C13000DB0B7D7B902FFF58FC5EC609F8DC668C1C
-:10C140005611EDEF1D88874D284FB06E25DCCF6B63
-:10C150001AFBBED7EDDAE7CC45B97A92F13701FE8A
-:10C1600046BE4A3EE70B32EE51E479DD894B46C4C8
-:10C17000BBFEB0B63C77B99D2FE07EFA09A9D7B2D5
-:10C1800073F7C9F2DEBE97327AF9F766333A7D4625
-:10C19000F67A5DC0979FC13E0E005F5EF17A533321
-:10C1A00061FC159F37352B2D2EFF1D7B53D9B8FE13
-:10C1B000F255D99BA03E847C0FE7B81C769B90CEAD
-:10C1C0001BF672B953D6FB30BA2E1BE5A7C6306EEC
-:10C1D000B443FBF4C8850CC4753543ABB351FEA61C
-:10C1E000DAE7CB2E7E1FEDDDDBB65ECCE6FCA007EA
-:10C1F00079DA2ADB31FF8EA811E9BFB59B30FE1D2D
-:10C200003EF27E07CAEFE548AA15EDDE67C7520386
-:10C21000A8EFAF1C4F09E960AA36E477D0679F19F1
-:10C22000C6EE66F871486F45FFCC7FFCD367501EA1
-:10C23000FD47401A61DEAD914727D0BEB545965EF9
-:10C2400012B07CE5FB9587F6EE9FB3F32AF54F7BA2
-:10C250004C22EACFCB02D7135BC387199EDD7AFD50
-:10C260006A95D786E7FCAF85A8CFFCBFBABA10F5B0
-:10C2700098FFE8D585D8EE7F3DB5530B9FBCEFD630
-:10C2800033BA2AF6B1E4AC2025F6EB95F9A3A4F76E
-:10C29000C9FA52A05FCDE81ABB5E8CB7D754E8BC90
-:10C2A000D8BFE6DDDAEC2D89E362423D7E5F305A8D
-:10C2B0009BBA39812F1F721B643D04520DFA679D92
-:10C2C0004CC375058FC7F455581702328EA0371826
-:10C2D000DE26A2B010FD7782CE3DE98F090CCF0497
-:10C2E0005AF5A10A686F8EE9247315F3EF038938B4
-:10C2F0008310EFF2B978DFF7E6DA7789CCDE931EA8
-:10C30000AC3F5411427B4F02A691F2041CB42EA6FE
-:10C310008BA600DF344552A28887D6C5840BAC2E8D
-:10C32000E3A30FADAF3D826E27E0A38B893807F002
-:10C33000D045355E22E9B85F052FBD87B80AF06C9D
-:10C340004B57D480F60A7092AAFFC6A61F5F423FE1
-:10C350006C63B7FA7B494CD0AD84739680BA433294
-:10C36000F4C7F698503E149C89F735A821EFFB5D81
-:10C37000FCBE1439EA8DE9D83DF4C65CA672289F4C
-:10C3800095E568D0AA230198BF37B2FA20FAE9BD33
-:10C39000D7D7A622BD7ACFAE223B50DEAD2E5305B5
-:10C3A0008EBBFE6353A32DCE1F93F4878BEBC73850
-:10C3B0001ED0B673CDF2BEBE2F7BB7D6F5C3B07715
-:10C3C000E0576F70E532BFBA99C73DB85F9D6C27E3
-:10C3D00014FDABCCFB847CCF93F5EF25865FC0FFCB
-:10C3E00065FAF70997C8FA4D8F346433BFF8EC9AB1
-:10C3F0006C316DF2FC65825D97659B3CBF82D7FC1A
-:10C400000169C4847E8CA467F2E95F434314EB5E48
-:10C41000CA70B67FBD2184EDCA7E626B28EBD768F7
-:10C42000A721338DE33F051FDE6C5F00ED2571BC56
-:10C43000A8E0C29897323F688D6460EDB9337C8F75
-:10C44000B86AF07C66F6BD66319F17F4C008FA47FB
-:10C450006B7F4A09D303325E54F833194F7E1E298D
-:10C460009BF64D71A3E764BE54E46B46925C28765C
-:10C470006A48B6D31D68A71D68A7BF36A21C4C85A5
-:10C48000BBC14EEF73B171848D5FF0AEE0D5F2BBEE
-:10C490006DB21CBDACDC5BEC0D27EEB798C4B6A347
-:10C4A000BF3895FDEC9771CC54ED43323EFC3639E4
-:10C4B0003E2B9FEFFB92E3D80F448E6FE23FA3F633
-:10C4C00039EF753BCF23FF5AF49D3127CADDAF0DFD
-:10C4D0002C6E9DDCEF09D91E833D53DDCF48B15151
-:10C4E000877E8FBF95C7018299E23BCC3F79534F3E
-:10C4F000709EADD70A194EBBEF5A262B838584DB7D
-:10C50000D1074B58DCE6BE97460D128C6FEEA2F3B6
-:10C51000311ED4DCAA3E4F30575A9A18070F160E18
-:10C520009C42B90A1C2C1371FE163C2CC6435A338C
-:10C53000433B317E81719C79F8DD12A703ACD32E89
-:10C540007FBF4B8EEF90241C7074F83C8BF7F8077C
-:10C550002941F93546407FA03E39CDE31D1D11AE7E
-:10C56000173EE936337DF289C0CFE1EFA6A1ED3465
-:10C570008E232E459ECA43399B842724C01379718C
-:10C580003CD1FEC2BB4C1F26E387AC41BE8EBF4DE3
-:10C590001FC278CC48F1428AF576F007F311278A5A
-:10C5A000E24F8AF8BE4888E91549152739701BB74C
-:10C5B000FB9F9FFE77E647360F5192CD7087142B75
-:10C5C000CF8BE38E8DC165CCFE2B3863E3CC532338
-:10C5D00045389F8C33ACF08BF1C3649CD1111E3570
-:10C5E000A05F30094F24E1880AB73A2E3853E07132
-:10C5F000D699116AC578D24C999E77F45B182EF6BD
-:10C600007CB0391BE55CB99FCB0DFCBE2E9FFFC2F1
-:10C6100089E3167E205851DF1E3DDFF5DB225E17D1
-:10C620004D228EEB4A453FE4F2070FA4223D8F4294
-:10C6300049405E5F3F2768C60FFF3E1E37BED38D61
-:10C64000F6ED61396E2C807D4B8FC75F92C7BD269A
-:10C650008F0B829BC1E28E4384F16FB0D0B78CD533
-:10C66000F79592832CEEC3F9F57024D38A78AF1234
-:10C670000EDB0D7AE21F2DA417F32BC15CDF5B4CA0
-:10C680003EF6E918FFC2789697091C1299BD4392AD
-:10C6900061FEA3CA087BA9267C3190B739F2BD158B
-:10C6A000821F8AF917D8CD9A1B40A74A390F5265C5
-:10C6B0002102CEFF98C1B7EB76CCBB0C0BF6ED3860
-:10C6C00046B06737A44FCEC70077B37D2979198A62
-:10C6D00079976FC8CB505CA78AF31BCBC31089DE58
-:10C6E000488DE75FC84FBD2C29B473512741BF73F4
-:10C6F000B187F0EF93F3298F3B35F229FBD0FE3061
-:10C700007DABCEA7ED9AFD1AE3B7EF9A473BEB520C
-:10C71000E64B5E5FE47E67D2FA0B323FCF63FECB1F
-:10C720007F7F95C1EC59E42AB33B57C653488CC56B
-:10C73000EDC6789C3A6260FEFA15F0837213ECD96C
-:10C74000974E4E87131137E3C7C1586D2AF62F96BF
-:10C75000ED65FFD935AB57229FC4047B05DB25F778
-:10C760006B0663420DC70793E874D0A5919F3259B9
-:10C77000B83E4FE6CF46993F1BDD9CEEEEF3DC5F03
-:10C78000F177F1FC815596377F27657AE554711E64
-:10C7900055E2C8F95AF985A171A6675BEEA5F68046
-:10C7A00038757E61B7EC6724EBA18EF0217E6FC9EE
-:10C7B00071DB7A0FD33BB71AB725E80D2F8CEBE965
-:10C7C0000145AFCCE571DC3BDC5676DEACCEF9CE74
-:10C7D0007C123FBF063DC55AAD3CDEE47EF3EA6EF7
-:10C7E0002D2FD829DD5ABF17A55B5B77F016FB9D6F
-:10C7F000BDC57E73B4E44CA35F8EF3D6CEF18966DB
-:10C80000BFFFA379D0E43C67725E3439DF99F2E66A
-:10C810009600B63D4A1F1F8F2275338E3451105932
-:10C8200021F30513CAC98AC53C2FD05F6B0AEDA757
-:10C83000F1FCA842AF020FC75F56DB44201BE83C67
-:10C84000438AD566833C5F594C98FF70C5CCF3038F
-:10C8500044B01636B0FBB316AE02BD1F346BE79979
-:10C860007E5D27E3E929F4C9128F733ACA8B1571EB
-:10C87000B9C63D1E96E394D63061711B228885AB04
-:10C88000D8BA6221DA9B696FF0EF195122ED67FB8C
-:10C89000124B56311C2D96E0FE76CBF9AFAC65B34A
-:10C8A0004A305E97057617F3234F619E84F901564F
-:10C8B000D64F59EFF95ABEDE6E03A198CF0ADCCEEF
-:10C8C000DF57907FB3AAF21B670CD18B9B28CB6FED
-:10C8D000DC81FB7F5B17B51D28E1F782F4B50D5AAB
-:10C8E00059DEE5378BFF61B68FADC3F31DDBACBC02
-:10C8F000CB49F437601FDB8E3918FF369F58FCBBDD
-:10C90000F5880BCB0546E749785CF6B3CEC97EA225
-:10C91000E2678DA1BF98E0772CAFD54DA59796D74C
-:10C920006AC8D56ECAFDE0C0DBDC0F7618ED659DE8
-:10C9300009F7B4B696F3C3A6288FC72AFE6D9514DF
-:10C94000D2E5011D1C0FE9A32960AF1D7D738DA8E1
-:10C95000B71D7DC516165FDA7C48A7D05BEBDE37C6
-:10C96000D5723BD27F7A9CE5270E27E5299FAF350C
-:10C97000B2F62C991F9FAF251C4F55083BD10C4F89
-:10C98000FB6BAB5E2B3EDE02F81FF7B729C8F7AB97
-:10C99000E4435AA2A21BD7B93032DE8765756B8992
-:10C9A0009BC50FDB26FAD07EFAAF5F3DB584C50389
-:10C9B0008C22E2ABE479E778F46CFDC30848905E22
-:10C9C0004B8510F6732C15D87D67B598993F9E65F9
-:10C9D00020FA34AC37707B565D9FE3C63A5993C951
-:10C9E000EC71F56931738B2DEEEF672DEDCA453A89
-:10C9F0007D5B9E48891BE4CE907620BF7DD73C515D
-:10CA0000FB99B3463CF78631759E48C9FB4C952788
-:10CA100052F2B4FEFA2F547965BF30EEC1F88AE3C2
-:10CA2000D8059627F687A9B5A0249E3FF20F4E1889
-:10CA3000197DE5BC11F437E2B8C11E9E3F3A02EB06
-:10CA4000631986F34AB08F7F86F3621981F3E2F7A8
-:10CA5000E33DB35919EDB1B3F244CF22563A806D9C
-:10CA60000AB330EF34C1F24E2FD5AAF3164A5EC294
-:10CA70005EE8FD05D229216FC1EAC9790BBD85FBAE
-:10CA8000A3FED306FB01F8EE3F63627AD619D934D0
-:10CA90001371D997A3BE99569607C8667EA5C20F93
-:10CAA0009725BB3913FD01AFDD8CF902C7F025A333
-:10CAB000C8F44EB4089F3275083123FAFD4807893F
-:10CAC000E139A719E9FAADF1FDF0FFC7F7BF4B7CDB
-:10CAD0007F5E5C2E99FEA8F6EAA4FD589E96CC5B7C
-:10CAE00012F443BF97C789FBCB4B99FCEDF19666D7
-:10CAF0006E4E8CE7D7733F2E6B69B939F17B97C7C0
-:10CB0000C0711F255E2D3DF6F5D4FAF66B2D7D4BD9
-:10CB1000A6C80BF4D7733DA2C4FD27E709EC6F96B6
-:10CB200027C4FB2FBF0D7C0A7EEBF0500AB3E75FF2
-:10CB30001E4B3980F8BBBA7EF3CC74A8579F4B21AB
-:10CB400025DC1EA9F20BCDF53AC99CA1954F908A20
-:10CB500074C0B793F206F53AA6DF6FE60DEA850BCF
-:10CB6000AC2EE3F40D137F482FA148FF5010FD8C2D
-:10CB7000C3EDD43E4C26E71160E222B2084E517F4D
-:10CB800096E595ED9DD42E8ADF9E5FC893E30C1D3C
-:10CB9000E14C3DF279CB1B84E0BBADC979867A8646
-:10CBA000F7ABC993C15A7C8F55AEB3A23D4B8E17DC
-:10CBB000209FA0FD4F8E13CEABE3F7384FC62B61FD
-:10CBC00019DF57CBB84419977CFFBD75EA7C4472D6
-:10CBD0007B97DCDE5B5FDD8FF71758A12368077A50
-:10CBE000EB5DA6F284F95C75FC1DCD6ECC5BE42494
-:10CBF000E62D787E22395FA1E829C7F0D71EBCFF59
-:10CC00003D111E4FF217F0F8A6E3B8F334CA7D7C4D
-:10CC10009FDCDEEE813B8E311C65CF24FC5CC4C4FE
-:10CC2000E35E2CCE50BDE28B13A9483F2FD82BD406
-:10CC30004B67CA77A6A13E5921D45091C5BB6FC698
-:10CC4000BF313EB5FA9DD66504ED7FE3FC51A47B70
-:10CC5000E37A037B87A4D8ABD5EF347978FBFE1D4C
-:10CC6000166C9F4DED6611BFD7BBF0FBF257A218B3
-:10CC7000E9232B91DA2037B13317059497DC19BEDD
-:10CC80009FA17FE46890E3E0EBB97D6D8C34184898
-:10CC9000DA647B77B2F84BE6475F8D38587C3B1BF4
-:10CCA000F3AFB6B8BD701C033B94FE97B343BD759C
-:10CCB0005646CF796087703F590D3C4F987CFF2EC8
-:10CCC000F9FEA7B22B53E951B423BA455C6E684113
-:10CCD000DCFE8AE85FDF11B7C3D630D4F3BF21EEA4
-:10CCE0002DE3ACCC2970D82F657E9FF2FD46F8FB72
-:10CCF00089831FAAFB81C4C1653F4789872B7E5169
-:10CD00009A8C639532DDC3E9FEBF7EBF8CC651F3BA
-:10CD1000FD7296F6FBE50D03147186F27E79C44828
-:10CD20009C8772F0DD1E25DB51BE430D0CE78C3C69
-:10CD3000FBFBBE97E17BC720B5A2F9691F1865769A
-:10CD4000BA1D700DC343914F799C6A80BF376D0F38
-:10CD500053492B0EBA40B6CFB512617AA35D7ED788
-:10CD6000E719E4721D8F13FD5C488C13F9C558AEAA
-:10CD7000F25E30C4ED93E6BBBE0E32CEDE0376B477
-:10CD8000527B14BE27C78D92E3454FCAEF00A78C94
-:10CD90001B49DFEDBDDF9FEAD2733E061650E2CF9E
-:10CDA00005B53C4ED4E4A314E737E9BC6DECDDEFE8
-:10CDB000716AD57A3F9AEAE17667B91CBF7DD1C81E
-:10CDC000F9E1C53B297B4FBF9CF038ED8BC7F9BB20
-:10CDD000FA17ABF9BB7A255EABBC97BF3D1EAFDD42
-:10CDE00083F15AE59DBDF26E9E9010BB8786BD967D
-:10CDF00028E28DC70C0305288FCA7BA3A375DCDE50
-:10CE0000595248A7967C7E55E73C5AC7FAE9A6884E
-:10CE100077FAF23D1A71209FECB7157BA6C4E9A200
-:10CE2000275785D3593D19A7FFA5E2B547EAC8544E
-:10CE3000FBBF5F1BAF4DEA77F116FB9DABD3A0C7DD
-:10CE40004E397E924CDF1E8FA287A75B193FDDDC37
-:10CE50003FE1F95C39EE3522DBB920157F7717CB3E
-:10CE60007F1958FE4BD133C1743EFFDDB29E51CACB
-:10CE70007BE53268D08ED374C9ED730AA595788F9F
-:10CE8000952FA9E3667307D471B379E12C557D7EA4
-:10CE9000F436557FC7E952557B4D6C8EAAFD8E73D3
-:10CEA000D5AAFAE2B13B55FDEFFAC4A5AAFF685C2A
-:10CEB0001D375B724D1D3753F8DB091C9138CE6D61
-:10CEC000FA1B55BFA256F5B98A3BD5E79AD9AD3EB4
-:10CED00097326F49407DBEB2A0FA7C5918D7B7FD92
-:10CEE000F971FDF15A518EEB979971DCEEFA7233BC
-:10CEF000E2183DE631E1FBFF001DADB367003400F1
-:10CF000000000000000000001F8B0800000000006F
-:10CF1000000BE3146060F8510FC1D3F9191836F310
-:10CF200023F8F4C0C79819188E83302303C33E201A
-:10CF3000DE0AC46B80F83D0303C352203D078827F7
-:10CF400003711710BF048AD5B1623787858D81813F
-:10CF50000D884F02CD3AC54CBCFD8A7C08F6215E97
-:10CF60000686B5407C9497BE6130D8F00C41FAD962
-:10CF7000F50C6AD76ED181F73708B38A3330304A5F
-:10CF800020F8FD12A8F26CE20876960C6576950101
-:10CF9000F50300295128158003000000000000005F
-:10CFA0001F8B080000000000000BED7D0978544540
-:10CFB000B670DDEE7B7B49BA3B9D90952574802051
-:10CFC0002A4BCB1201113B2189010306440928D2C7
-:10CFD0006C2184249D01661E3EFDFF6E0842C4D173
-:10CFE000898A1AFC195F83E004079DE0A0139DC0A5
-:10CFF000348B8833E804C70597795F401E204212BE
-:10D00000A338E8F3C9AB73AA6EBAEB763769B7FFFA
-:10D01000F97FFF840F8ABA55F7D4A9B3D5A9537500
-:10D020004F149D9524DD40C825F8A1E5AB0A2124C5
-:10D03000255876489DC3E581C1F6B55E177119097B
-:10D0400079C06BC272BD379DB8AEA0CF47EB8AFCEA
-:10D050001642EEF7DAF1F9E3DE122C1FF59662F9CB
-:10D0600088D78DFD1EF29663F92B6F0D96F77A8B9C
-:10D07000B0BDCEBB0AEB372A0BD2605C425CA6ACDB
-:10D0800064423C2F0F1CB981D6D6678E4F9047D390
-:10D09000FA5FF5449F45DF1B2D17F987D206B9A427
-:10D0A000286B74B09F8AE78D4A5E5F80F3F8581D45
-:10D0B000EB67AA792D3B72BF2C3286E2395646FCCB
-:10D0C00089A564727672C47E8301DE2343D93C89CC
-:10D0D000DDF9DAA0C8F0AE06780F0DE5F825DB27FC
-:10D0E0000F8A0CCF09FD7EE5E4F0D23B0F0F8CDCFC
-:10D0F0006F0CF4AB7372787D7DA60191C71D0FFD97
-:10D1000062E013C589105F8BD19F9DF5FDF9455CE9
-:10D11000F42FC5A763AF79EB0609F9370DE8B4D64C
-:10D12000BEFCCC163A4E7BCB30A7DE41C8672E67DB
-:10D1300082DD1213DF6E8179C4C0B752182706BE94
-:10D14000CD8D916F0BA05F0C7C5B02FD62E05B6597
-:10D150008C7CFBD94F846FF7021EDF836F1B62D478
-:10D16000B75FC5C8B78D31F26D538CFAF6648C7C0D
-:10D170007B2A946FEA73B5DC4124B48B372A253BB4
-:10D18000A09F27B3CD3620EB27C1BF3DDF53EFF67D
-:10D19000C7C8BF5763E4DF11A04F0CFC3B1A23FF45
-:10D1A000DE89917F1FC4A8776DB8CE58E4AFDA86C8
-:10D1B00010FCB93400FEB5D84F5DCDEB7AC03B8989
-:10D1C000908C7039504BCA51940799B8DBD9BA5535
-:10D1D000F0CDA51C425698E87FE9FBBE3C12D0D3A7
-:10D1E000F17D36E2AF9584FE9F039E84E47F732930
-:10D1F00055E8EFD345EC4F74D0FE30C815E5FF6617
-:10D20000EF102CEBB91C6D2ED2A13CF8920D285FCB
-:10D210004F789DD8DEE01D8BE5635C2E3772397A3E
-:10D2200000E4EE0A90C3522E574CEE082971945335
-:10D23000BA76EC89271B1C28576609F09499BCDD47
-:10D24000BBE7CAAD1B28FCCD35BA2BB785C8D913AF
-:10D2500045AA7C51C94C0EF67BA2FC846DC150A43A
-:10D26000B70DE03414EBD47EBED07E0DEEEE7EBD65
-:10D27000A0DF63C55CBE6412081DF7B1D2EE7EE983
-:10D2800012A5CBBD12296DB284F3658AC4F4942A29
-:10D290000AF243E6F4DD9F7796B4D1F76DF6916913
-:10D2A00084964F827EA2FE39B054DFAFA7747653C6
-:10D2B0007A641A494D13E04B5A2585E22B8F752469
-:10D2C000821C3D34CE45242B21FDA19D8EDF677449
-:10D2D0001BC9A265E2F836220D837EB49DD6537831
-:10D2E0007BC650DA4EE13C04EDD6607B2A6F4F736B
-:10D2F000F0F7AF63ED0F7B098EAFF6BB8FF2D94D20
-:10D30000F15B47F1C5E7C5C4057494293BFD21F3E2
-:10D310009F2DE971DE95BC54F1BF2FFB54C6FCA1D3
-:10D32000417CCD832F66CC0FC1EFBEC173B0AEE29E
-:10D3300063BEA212EBFD57F5A69E18D707124EE763
-:10D34000D49903847687EC443FCD71444F7C945F3D
-:10D350000E2A9E91F8F30515E71F54FF5C8C1EDA28
-:10D36000F6BB3574589721D2C1D05BA4C3BADE2274
-:10D370001D0C7D2E4F87299203E147A3873AEE8645
-:10D380002BC571E3AE12C7DD7095386EDCD53FCC8E
-:10D39000B8EBFB89E31A33C571D7678AE31AFB7FC1
-:10D3A000BF7189ECA40F99B9200EF8679E60DF2E3B
-:10D3B00010F7C3A0DF60E7F4C9413B27DB4B88DBF4
-:10D3C00012E42791E9CB39A170EE14EC2A85F37FA2
-:10D3D000381CD7E5E1D83570E66AE16CE37048A8FF
-:10D3E0009D0E8343EED0CEE3B7FCBD802E647CBAA5
-:10D3F000BE92126BE87B4ECDF8B76BC7DF0D760C93
-:10D40000E6A1BBECF80E0D5DE768F1D9C3E110DDD4
-:10D41000E5E841EC1A38B3B5700E713801E9B27025
-:10D420004AB5F3785DE5AB24AC5F941EC382EF751B
-:10D43000E4759E423FE845C5B19DB64B7FB2066E8E
-:10D44000A0FD8F6C91FC465A0FEC8DC7F5E3FCB63E
-:10D45000E958DF778D11D789F3CEC97E23B527939D
-:10D460005E78DB06F6A5EA05BD0C75DDDE8F6D6D19
-:10D47000142F8FB1F5C1EBE8F3CE17F4642B4A6398
-:10D48000A10EE87E8ACB2659C5EA656656ADDAB2AA
-:10D49000EF4E805BDE6C24660AA7EAA525D3AEA317
-:10D4A000F5258715025DAAB6AF36F4A6F5A57EA9C7
-:10D4B00009EA1D79A41CF469CDDEFF6C87F5E8FC50
-:10D4C0006E251BC63F4BD70907B5C747ACADA9337F
-:10D4D000291E15FE5D85F05EC54EC9492D1CC57718
-:10D4E000FBA10CC07787E434527A2F6B8C270ED5C2
-:10D4F000DED1BFA776EB71FECBE9FC0985B784D4FA
-:10D5000017023DAB803830BED3E8374B417D3BEB53
-:10D510003D8CE3A9F5AA1D743CFA7EF5739213A61F
-:10D520005AAD236EC0B3FD2573E9531698E76AC35D
-:10D53000602BCC6FBD01FA2DF1CF7FD1EC003CB751
-:10D54000180A01DFCD5B0C6543817E645EC950C063
-:10D55000EF2F227E0D7A17CC77F935C6AD7AE0A78A
-:10D560002530688635DCCE9EA5EB952364FDAC2086
-:10D57000CCEE13D96F983E2CF8FC257D22CAC1B29F
-:10D58000463D7184DA0D2E1FBEA384F9317BACFEBB
-:10D59000ED59413E2EB77379E57C5C9EC8F92A7738
-:10D5A000E6CC18168ECF83C01723F38FA07C98AEDD
-:10D5B0009B0EF47F1C48BFC7A8FFE440FFC889CF7B
-:10D5C0009FA07E12949BA99F04E593D44F82D24FD3
-:10D5D000FD24E8B795FA49506EA37E123C7F9AFA73
-:10D5E000E7503652FF1C9E3F43FD7228777A7DF844
-:10D5F000FC396F1D964DDE7A2C9FF73660B9DBEB58
-:10D60000C77E2F7A1BB16CF636E1F397BDCD58B6C5
-:10D61000780358EE053ED332E06DC572BFF7189619
-:10D6200007BD6DF8DE21EF192C7FC9E96E9B4072B2
-:10D63000652A2F3617B1039B928A5DB9E0AF249516
-:10D64000B07AEA1DBE5C03ADA7BA699DD2B1776519
-:10D6500020D748EBBD6B587BE63D24CF44EB993E89
-:10D66000D63EE097AE3C33AD0FA867ED8337FBF2B3
-:10D67000E2687DB09FB55FB53390174FEB5735B17A
-:10D68000F6E12D649285D68707587DE411D7242BC7
-:10D69000AD8F6C65F59C0F7D936CB49ED3C6DE1F79
-:10D6A0007F2E302981D6C777B2F6895F937C3BAD58
-:10D6B0004F2412D6F32CB9F989B49E6767F5C2BE20
-:10D6C000F3654784F57DAFD2B6104CDACF7539B922
-:10D6D00032F513F61ADA5680C95DAFBB21571E47E3
-:10D6E000E9A79045D0BE4957C4EA06B212DA7FAB2B
-:10D6F0009B8EF5FD8A03DBF7E8E6B0BAC181ED7FCA
-:10D70000D52DC4FA41C585EDC77595AC6E7061FB2A
-:10D7100067BA9FE378871437B62BFAFFCDEA06374E
-:10D72000B63F2CAFCFCDA7FD2BF56E8F8ECA75AD52
-:10D73000E42E2703415E9BD2C11EAEE37EEB2C9DFF
-:10D7400003E57E5D8601F56CEF7FE53C857A063F5B
-:10D75000C9502F7B1AFC5E0A6715C251281C7DCF69
-:10D7600070267E33568033F19B7215CE6A84638EA9
-:10D770000DCEDE6FC68BF87C53A1C2D9A0A3F6BE36
-:10D78000D61ADBBC265E9A20E273A95285F308E222
-:10D7900093181B3E01E55A014E4059A2C2D98C7024
-:10D7A0005262C3C7651827C0711996AA70B6239C28
-:10D7B0008CD8E0040CD789F81896A9709E43FAF427
-:10D7C0008B6D5E2EE3F5223EC62A15CE1F109FAC50
-:10D7D000D8E0ECB78AF4D96FEDA64F00E164C73604
-:10D7E000AF3C9B489F3C5B377D5E433857C606671E
-:10D7F000BF4DA4CF7E5B377DDE4438C3629B575E4E
-:10D8000082489FBC846EFA7C8070AE890D9F83290C
-:10D81000227D0EA674D3E724C219131B3EF9A92258
-:10D820007DF253BBE9731EE18C8B0DCEC154913E4A
-:10D830000753BBE9F305C2B93EB679E5A789F4C938
-:10D840004FEBA6CF258493EB6E447C0885638D0E49
-:10D85000E7503F913E87FA75D3C7A407380514CE29
-:10D86000C09EE114668AF429CCECA64FA21EF46295
-:10D87000726C700E658AF43994D94D9FDE88CFD4CE
-:10D88000D8E655D85FA44F617F461F8FB173921DB4
-:10D89000FCC644E2DC4A5F9994FCB383B0EE2816E0
-:10D8A000E204B047A4C036804FD756F44B65A7EAD0
-:10D8B000073909F8B9C5368713E2017AD5DF21ADFA
-:10D8C000B81FB1EC4C14E24D2FE9F38603BE56EAC3
-:10D8D0001586FA3D0963E3047F2BD19524D47B158B
-:10D8E000F516FAA7940C10DAD34AAF12DA33DC2318
-:10D8F000857A9FF2F142FF7E357942BDFFAA294227
-:10D90000FF2CDF0CA13EB06E8ED03FBB7E81D07E5F
-:10D91000454385D07EA57FB950BFBAF15F85FEC370
-:10D920009AD608ED239A3708EDD7041E16EAA30EFF
-:10D930003F21F41FD3BA5568BFF6D83342FBB8B6BF
-:10D94000E785FA75675E16FA5FDFB95FA8DF70F1E9
-:10D95000CF42FF5CF237A13EC9F481D0BFC0FE9137
-:10D96000D07E63FA271A3F568C5FD4E612E6CF6664
-:10D9700018D09F0D580D5837EC35B3FD0DD49321B9
-:10D980000E518C75C3FE858E6488070000EA4FE453
-:10D99000F62EBF02E255BF18EFBE02E2B8BF30B8A4
-:10D9A00047D823F841EDB2FB1E3DC6135B25920E0E
-:10D9B000A54307659C9EC7138C4C7ED767E53CE565
-:10D9C0000BD183BA7ED4BFA0F5F57A8AC798A0FEA2
-:10D9D000ACEF57963E3F649C75FD0CA55B87B2E7A4
-:10D9E0000B2D305EC97D309EC7D03918F0D28E63C2
-:10D9F0001C305618C794598EE36C84715282E31818
-:10DA000033CB35E3984AB7F2E77C9CC7406FA28DD1
-:10DA1000B37EC078713E991538CE16CD38EB332BD6
-:10DA200034E3C4B1F9D0E77C9CA72E378E71E004B3
-:10DA3000713EFD2B719CE7B4F3E95FA919C782E33E
-:10DA4000C0731887F4A5BB9834CA67636719CAC145
-:10DA50009FCC182733F4A9F80DD4C90766920DE3BB
-:10DA600038E8B8B41F199244859A907FD127217F56
-:10DA7000BE88A3FC0F89A705F7E33EDCD72FE62875
-:10DA8000123FC588EE93AAB96C2EDA393D738583AF
-:10DA900096CD07063D02E36CB43AB369BDBD7992F9
-:10DAA000616104795A5CAF9C6A0B91F3EEFD591EDB
-:10DAB000195243C75F1167477CD4BA5A26E9C4E7B5
-:10DAC00027E8BE8BD0FDC987749F42E87EE5238599
-:10DAD000ED33FF9DEECFA0DE46F767D04EC86A7CDF
-:10DAE000EF048F339FF8A5E4077A7F71D7CF145CDA
-:10DAF000277CE4ADF4548826B09F79ABE2291382E9
-:10DB0000F8CDF7F512EAD41CF7D1A5E3BE16E3076A
-:10DB10009D2F19FD5B81AE757D284D79BF0184BCB9
-:10DB2000BB77EA21C986D53EBAB184CCAC995E9068
-:10DB3000865A24F55B4EF19CB1FB1A85BE41DA95FD
-:10DB4000B63B9D96205CE2524E007D4CF40FC0B96E
-:10DB5000A588D643C6BFB544ACCF2272B04EF97D7E
-:10DB6000523F80B0F83F1FD7E15280AF25748E1925
-:10DB700094D5B3A01C09CD2C5E536A67EFAAF87840
-:10DB8000162A2480FB6B5F0AC4B1892F19FBCD5183
-:10DB9000F7C91AFC4A1593AB84D2B574BE1EE9AA24
-:10DBA000C5F7FDBDF12EDD705AD63DA24068B627FF
-:10DBB000FC67BBC57652CEC653E9AACACB29CEDFD5
-:10DBC00013C07F5A9E06FE53BC4F72FE07E598F1C4
-:10DBD000DF63744F03FE776ED213E417E7FB6D9C8F
-:10DBE000EF8BEB45BEDF06E771B4FF6D2BB358BC7E
-:10DBF000A9A197C05F3A71910EF50F1550B31A861F
-:10DC0000FFDFB91CCCA9DBF50AB0F7F672CDFC3802
-:10DC10001FEEE47C98ABA1C76D9C6F7339DF961043
-:10DC2000DFBD1918BFF02B10D79B5D2E11B0179ECA
-:10DC3000BB55BEB5097C73AB7CD3E07B27E7DB9D8E
-:10DC40007731BE69F16EE37C6B6BF84C2103C2F156
-:10DC5000D6E2396F95665E3E2DDFEAB95CDA0DE0FB
-:10DC60004F4D77E5AE3819D2FF96A2C92B4E86D814
-:10DC7000855B4BA60BF559A5B385FEB3DDF385F6A1
-:10DC8000DBCB970AED736B7E26D4E7ADBA4BE83F4A
-:10DC9000DFB75A685F58779FD0BEB8FE21A1BEA4F7
-:10DCA0006193D07FA97F8BD0BEAC7187D05ED5B495
-:10DCB0004BA87B9A5F12FAEBF65E7933C8D791B71F
-:10DCC000F504E27D179CA731CE78C1A938A1CF49D0
-:10DCD000AF03E5F89477089667BC4E94F3B3DEB1D2
-:10DCE0005856834C8E033B7BC002F1534F1CB5FB4F
-:10DCF00089741D97C7ADA99B00EB0D6D1F4FC8BF61
-:10DD0000CA37ACF1F5A55A00716F4AFFE206030964
-:10DD10008C2254BA7B77CB73A73EA4BDAD87F606A1
-:10DD200099047A85B717B7457EDE21750ECE80B887
-:10DD3000EC7B46B23D24DE187EDE42FA805F11ADF8
-:10DD4000FD9C8E94879EF76C95D939CF117DDE5658
-:10DD500099E2556960FA5FF97C461EB1413D30B8E1
-:10DD6000C67299F19A283269C0E78182DE2F69B8BC
-:10DD70003AA8E704C661F674A97F94F07C59E3756C
-:10DD8000C27B6F48EE2D80C7B97D7A5CAF49E04019
-:10DD9000E62DC3003FD75619D6D1E614F4BB5ABDC1
-:10DDA000AE15271542DEF41661F996B704CB77BCA1
-:10DDB000A5581EF3BAB17CDF5B8EE587DE1A2CFF17
-:10DDC000DDBB0ACB36AF0FCB13DE3A2C4F7AEBB16B
-:10DDD0003CE56DC0F28CD78FE5596F2396E7BC4DBB
-:10DDE00058B67B9BB154ED674FF27786AFAF674172
-:10DDF0000E8DE1727670EDBC35757D837276582E8E
-:10DE0000433953E95BDC60E4F2902AC8C35F611DCB
-:10DE10004E0179E9A1BD41E17218EDFDC8ED206F19
-:10DE2000BD7F047923640DCA8105E4EE7BC81B81A4
-:10DE300053841490A73E1A7912E550952355CFDFED
-:10DE4000904ACE817CA9726591993FA4CAD5FDE024
-:10DE50002746F0B77A2B125FFF987F4402B93A2029
-:10DE6000D9727E5E417C2EAC77F1B16B29B856E851
-:10DE700027FB87C03AD235E4ABC110DFEF3A4685C5
-:10DE8000202BFAFCB4F2129DEE2EDC3F94F929F31C
-:10DE90007B85B79BE3185DCD3A524446C2F972CEFA
-:10DEA0003137E567DC9FAE1E09FB66FA5C26490048
-:10DEB000C7EF9C1EE1BC800C2248E79EE8ABF63F12
-:10DEC000F5C47FE6C0B9BF05F49CCE3DEE80BE86AA
-:10DED000E9EF53CE5B42CE973C46673AC4C13BB3B1
-:10DEE0000D76E63F4C12E94826E1F9814AC703D98D
-:10DEF0005F0C86F399FBA81C827E750D1A9C402E40
-:10DF0000231F3DD9FB9EE8B900E61B133D0D04CE4F
-:10DF1000B9283DB7C27DC758E9D9939DECC93E9E4B
-:10DF2000D8C0E87C84FBA7D1E8AC9E8769F1B845EE
-:10DF300091391FB81C933B34F42F15E8DFD7EAC0A2
-:10DF4000FE07F77E9009E7785DBBAF48204343DFCB
-:10DF50002F60E73DDDEFE70B7A20FDE9EF99B03F59
-:10DF60003EF8C2BB58AE254C0F375A4AE62A6382A8
-:10DF7000F062BD47106D5E1E4512E7D5837E76A424
-:10DF8000AAFAD99A09F2B49BDB81B0F9F5209FEA8D
-:10DF9000FC0EC0FC289CA920D3741EF972C95DC276
-:10DFA000FC46A7E0BC7B9A9F27C140A411143FAB5D
-:10DFB000C14012A83C2AEEB50AEEEB9C6D3E885398
-:10DFC000EC8D77D65296786C67DF0838E03D319E4D
-:10DFD000B1ACD15C23FA4F8935A2FF945113EA3FCB
-:10DFE000751D7ECAE6A6F82D4FD7D79CEC05EB9C95
-:10DFF0008BAF736C5D55F1AB6ACAAAB10870C47A75
-:10E0000057BD54C4EEE13812664638EF53CBE5E90C
-:10E01000061CE76CE3C00418F7ACD754C3D6577B93
-:10E020000D1B37BD26747DAD5C155F73725410BF38
-:10E0300068707F68FCA844908F4CB02ED2B681D116
-:10E04000FB47E5A7FCB901CFD55B942FC07F370F05
-:10E0500051FD7719EB2A5C4F93DE671C01CF770ADD
-:10E06000E3D1F71CEAD938BC175D6E64724AE5A7A4
-:10E070001ECEBB08DF1F9890CF6E0A3181C2EB9095
-:10E080002D7520577E85E9B387CB6995A9CDE076BC
-:10E0900020B95B41AE178C55E5DC31EB036AA73F35
-:10E0A000FE8B82F7CCC8D7147A4EF0AAC3225262F4
-:10E0B00083A0EA82DDCB8A61DDFEF8C59BF83EBD18
-:10E0C0003E07E67D9EE88AC02E9D276FDA4685E8EA
-:10E0D000EB6985C5B1481DDBE7F8E81F98DFE27AF8
-:10E0E00071DFB3A441AC979119A9606FCB362AC4F4
-:10E0F0004F715F0AFB2675DED4FEBEABD811B92581
-:10E10000A4661DECD31F5358BC67819DC87DA8BD74
-:10E11000AEFAC3AF7320EED3AE307F573D0F5F9A98
-:10E12000C4F6831533FD0617EDFFD1EE51B7518BC1
-:10E130004BDFF7AF43FF673A716E27E1745F5827F3
-:10E14000E2D713FE5A7C553F28EC5C9EE391DC2815
-:10E1500045BC2FF535B773AA7E2419EC42DC274D58
-:10E160005357E540E172E057DC56430AE33BF05178
-:10E17000923B0DEE907E8660BF24C398E8FD8CD064
-:10E180004F8FFDD258BFCE42DC1F132A4F4383FD71
-:10E19000CC41787DD9B862BFAA3F3CFBA28FCA4B65
-:10E1A000C5EF1EB511BA6E7E2CD7A73AE9F3CAEDBA
-:10E1B000F7DA5CB43C23FB6CC0CF8FFDFA88F77DA7
-:10E1C0006F31A8F470592488A771F924753E8C53D7
-:10E1D0007CB15DB1E33942A33160A4F259BD7B69E2
-:10E1E00031198EF5E3ACBEFE533DD49B457E55FC04
-:10E1F000E6D15407BB27C4E24924807E6EF5B6FF02
-:10E200002884F5C2433A51CEB4EFC1F8179350AF0A
-:10E21000E71B12C2DBF162702ABCCF7E3CBBEFFF72
-:10E22000546F8372F269D0238F464ECAB9DF0AF465
-:10E2300082FD7EBEC19A8CF6FE5A722DE8BB4A174B
-:10E24000E267FE6BED8EC7871FA7789DDBF6179BF5
-:10E250003434D44E3079EB6A5AF86F265D747BD231
-:10E260004EE531D44FA280F13D4733F7BB5B58599F
-:10E27000A9046C701FA7728BE2A492482A9FD51341
-:10E28000B89F40DE33FA213EBAECD957DE194FE988
-:10E29000BF6C97925CCCA663915283FCF1D0BFAB6C
-:10E2A0004606F951F1FB570C8E61ECF93D4941BE30
-:10E2B0002CDBB5CF408685D37152D33E439B2502DC
-:10E2C0007F9A8E17C27A5BBBE31F06882B7EBC57F2
-:10E2D000226959E1EF976F7905D73DA013F293F3C7
-:10E2E000AB9B7F617C0B4C7B7934F6B3833DEC892F
-:10E2F0006FD9B09F4B41F97EEE65B8C7F4BED10926
-:10E3000074287F6E850DE6735AAE6172FEEB7B5307
-:10E3100041DFCB155FAA1D4BF6BCFCC99FA3FC2DAA
-:10E3200039FAF354F41F882B4387B6D99701F35C6D
-:10E33000BCF9569C671971A31C96FF5A5F02F74CF3
-:10E340002FC8A46857043DF98B81ED5F4E6FA5CCB3
-:10E35000A5F33C0DF8817D7B53EFDF8E71F39FE1D8
-:10E360003DB89FF339D39510EB174C8C5F5B0C3A9B
-:10E37000351E6A12E477DBFA56E0D3D97EAE343824
-:10E38000F7A074F071BA4997285CFDD18234C62792
-:10E39000E29073F87BD4DE4F82E7D0BF5571998746
-:10E3A0000BEF71FBC8C65FC9C7A778C7C1FA753A3A
-:10E3B00035B2FFF70F3E3FFAD34A42E42C44DF99CF
-:10E3C000FE6FBB8FE9BBAAFFFEE945D0FEF95B4CAF
-:10E3D0008FE03D582F285E81346CDF375342FB407D
-:10E3E000F7D991F47C9BC2F55C6CA73B1C5CFF5594
-:10E3F00039A1F8CB5242A8BCD07192900FB83F2EF1
-:10E40000DB48DF0FF1CB3C302EF633049F87AC1B8B
-:10E410004BB85D38A4B10764734A4C7E74A5E27FA3
-:10E42000FA09D0DFF78C4E9F03F4572981F97FB2A8
-:10E43000F3C03B73A89C7FD2A4EAAD6857B57A5B62
-:10E44000FEFC1812496F3FB1D07D5724BDA5CF23E4
-:10E45000EAADA50DE5F9FF965D55E9D7AEA11FD848
-:10E46000C7971DD1E9A8B58F1B0C8E88F691FEBC0D
-:10E470004572C2E550953F55EE2A7E5BD51FEC50A4
-:10E48000B77CAAF2D72D9FAAFC69E72BD24FDBFEFF
-:10E4900007D06F8AD7EDA64DD3C07F3675128CC3D7
-:10E4A000E7CED4E33D4DD3E784DDD3B8231EEBB3F1
-:10E4B000F46DBF079FF083AA59C3609DBF9DF814F8
-:10E4C000766E5FAFA01FFBF5A54B13E87CE670FAF4
-:10E4D000DE4EC93D95F2A35496027114CFD932F1A4
-:10E4E0002524413C59222742F0B8BD5CACC3CFC4BF
-:10E4F000D4209C9EFA7F5BBFFBBB9647295F4F648D
-:10E5000013F2372871FF411DEB10799ADEC2CE312C
-:10E510003CA325FF00D4C336B924641FE13132FB8C
-:10E520007334FF963140BFDC59C312989C0FC6FD6F
-:10E53000A287DBB12E9F2301EC7B57CB40DC177603
-:10E540001D5E687547B06707B89CBDC2CF613A2CA5
-:10E5500052BD9ECA7D07E944BFC66731478CCBCD0B
-:10E5600031AA769AF38DFEE8E9F8A55C0E67D357D9
-:10E57000134686F06DE6D48F655B381FE0E744C82C
-:10E58000BEE2FBD217E41AE87BC0DC565812217EAB
-:10E5900053C9E93771FF970658F7F25B7265A063BC
-:10E5A000BE452FC4431619B9BE0E254301AF89FBE2
-:10E5B000973E3086CAB1E7B0DE69A6F3F3B47C6A51
-:10E5C0007047D8DF69E909F0C1BFDC6A64FEF2DB9D
-:10E5D0004AC962A0EBDBB7B2F3DEBF199C5591F0DC
-:10E5E0004C37337F733629B9305AFAE9D1377796E9
-:10E5F000359047E9D16561F7B5C3E58FE97D975D52
-:10E60000F2AF96400EF5AC9ECCEE371712F703131F
-:10E6100024D4F71B42ED576EF3F467E13E4D758B42
-:10E6200064D7D1F66AB9CD0072EC69DE2583DF7E4E
-:10E630009383B8707F2DD70C9B1912FFA2CB1ED2EB
-:10E64000EBC05773E6027D3F9B692480976BE8A778
-:10E650003658FF3F6B19857A106D5EAF7BC9B47C6D
-:10E6600005E0307BA69587C2E478A17EEB24D21723
-:10E67000CE81271ADB563823F02FDFC4E42C66FB4B
-:10E6800066FAFFCCBE4DA0F68DC9B5126ADF2CA686
-:10E6900030FB9616C9BE2D5FED4803B958BE672002
-:10E6A0007EBFB5FCB5C52991ECDBAB7CDFFB1ABFA7
-:10E6B00007DED197DAB71121F6AD2FB56F11E2E47D
-:10E6C0005FC46ADF4CFF33FAF72AD8B708F3359BEB
-:10E6D00044FB56D4B21AED5B515FBD705F8998A8B8
-:10E6E0007D8BBF9C7D9BFFE8AD58579CF111E407E3
-:10E6F000E80AF6ED356EE7601CB0733798587C3346
-:10E70000563BD72F563BF73F4467D5CE2DEF27A179
-:10E71000FF122E87CCCE2DCF62766EF91E66E7965D
-:10E7200067333BA7B56F7961F68DBD5F3D84BE8FC2
-:10E73000FBC7ACC7EF80FB84A58AD344FB173BD44F
-:10E74000EF276AC684DABB1B4C32D239CCDE393FA4
-:10E75000C5EF607AB2777F057B978D766C10E89174
-:10E76000563EA60C8A17EEB3BDFDE5A9DFFE0EF4FA
-:10E77000E5753DDE177A57C7F6477BBF3C350AF48F
-:10E78000EE2113B3BF4B4C8C9FED5E1FDAD3494390
-:10E7900099BE57DDC3E857BD5B62F35DA9F73B60E7
-:10E7A0001DF8EA22EE9FE7EE61FBE759C6D69478A2
-:10E7B000B897F42F0A61DF7D90E2F921F2507AB127
-:10E7C00002E380CFC7D9B6C2FEB2542626F063E773
-:10E7D0001D9EF231F8AFF32ED6A1DF3B0F9EC33959
-:10E7E00009BF27A1DEA398D3BCEB953E24FC7EC4D1
-:10E7F0004423E3C3C415927F4B16DC4710DBE76963
-:10E80000FCFA757C9ED49F45BA90BFEA23C6EFD62A
-:10E8100069E9E164F3AF5AA917E9512345A407E573
-:10E8200068F1FCD4E0FCE7BED0B6AE0FB42F957013
-:10E830003FA5D2433B4F953EEA7E651ED7114FCB95
-:10E840002E05F8A59DBF4ABFB079ABF4D4CCBF4E1E
-:10E85000B51F579361A06FEFEADC0F8C01F9F83315
-:10E86000A503C5EBB6D9D969A1F6F8416E97A6BA4A
-:10E870008FE7A73A806EECBBC439E5BB5E49A5F3D0
-:10E88000B9D9953512BE1FBEF52B831BE20B07CC01
-:10E890009D68DF54F9FA84CB7B80C379BBB73D1FF9
-:10E8A000D79166C98E7A13D0D82F7E7FCC730FD3C1
-:10E8B000AB03D23FD6F5198D7485658014AAEB1091
-:10E8C000F081FE776A0BE38307F840FF3B8D741EEF
-:10E8D000023A57274BCE00F46FDE752FC8CDAB66DA
-:10E8E000FA1CF4B75C72B2EFCB882523F5B2F2299B
-:10E8F00047924F0C4EE404D7C579D02F29DCEF980E
-:10E90000686C7D1BF09848F5610B09F74354BE0F06
-:10E91000A17F2E45BAF7D3831C7FCCE5F355A0B772
-:10E9200005E8DA69007FC61360EB87DAEE911DF91E
-:10E93000481F95DECD747D18CDE8AD8B40CF9BD5BB
-:10E940003AA7A7A74552E0FDC974FFDA4B82D3ADC1
-:10E950002F0FA9720CDFC369E901F1808C10BD078C
-:10E96000FB147A3E59DD7C14E932652575AF42E827
-:10E970000E76EB72F489A617D5CD3F8C5E7CA2D1C2
-:10E980008BBDE6CEBF8C80F8D71E09ED0369491414
-:10E99000F6FBF166E6671C30BB517E3B5F53F0FE31
-:10E9A000B9D68E7CCDE51EF617A1DFFD4D8289809C
-:10E9B0009DB39BC9472A1E03981C85DAEF57CD6E7D
-:10E9C000E45734F8717C1D8EE63FA9F51B613CB815
-:10E9D0008FE810C70BF32F78FCA7A779A5F171BFBB
-:10E9E000EBBCBACF3349AB81B0F8FF0A63C8B9D4E6
-:10E9F0006DFC5CA03B4E16EC67375DA61FC45F0242
-:10EA000074DEAFEE7C0AE3BFE79F393E0DE477D9B1
-:10EA10001FF5C444F9DCBED34A02ECDE8501D6D929
-:10EA20008ADDFA88E72884D4B2EF1C7F6745FB5261
-:10EA3000F1BCD15F4CDFAF78F1A3E110B76A5FC3DF
-:10EA4000EC8CEF192E1FBEB6E170BE5E21B3736170
-:10EA50002DBCEBB8BC9C7B29BE14ECA4D4C8BE5F13
-:10EA6000AD689AA51843F6E923CD0A8E4BFBE1BDAC
-:10EA700065DF0E09E3E5E1F8AD66F07630FB57D1CE
-:10EA8000ACF8E13BD88AC62DB8BFF5347E6A00BF2A
-:10EA90006ED2EF9E65DFD736EBC5F861A33E60C44A
-:10EAA00038A7FEB87138D35B49884755A15E563701
-:10EAB000F13899267EB4EC777B5EF451D22CFBFDC5
-:10EAC0006F6C606FCEB66EB7617CAE91C5DF648B44
-:10EAD0001C393ED7535CAEE93E1E979B7A9A0C0FC9
-:10EAE0008FCB9D85FF503D9C6FE6FAAAC6351B7BF8
-:10EAF000C5747EBEECD90B4FC279D2B9E73F79120B
-:10EB0000F0AFFCE6B327EF867389BD663BAC7F9E12
-:10EB100067DEC6F8BBFADEDD5CCEDB77FCE6E92714
-:10EB2000A81EB6BF67C47B5BED7B4E67C2F78CED5A
-:10EB3000BBBE4C85F8E6CA3D05B89F59F9C2A4B4DE
-:10EB4000CBDD3F01F9F4C7707EA2E5C781DD7A0213
-:10EB5000DF739E3F6644FFA33BCEDA54C5E2D70E77
-:10EB60001E5FDD19F9BC4A8D0756EFBEE5E6EB6185
-:10EB70001DDCAD381DF89CC7077B8AABBE45F93A52
-:10EB80002206FEEDE4F1F3A6A911E3AAE7E13F9422
-:10EB90004F9BCC625CF5C2EEC5FFF604B4EDEE15FA
-:10EBA00035AE1A88816EEA795899D9B5CD0CFAF14B
-:10EBB000FC6F318E0D7CA33E39697FF64226C4235B
-:10EBC000CE289D77E23DE53D46BC6754B1E75DD474
-:10EBD00097F6178EE23913E1E751EDA4FB879D1BF1
-:10EBE000F0BD8E679B95C56339FD215EEBB0E17387
-:10EBF0001E976572ACC66BA3C569DF37B3FB50EADD
-:10EC0000F95CD5B60F0C4413FF96C602BF8E0BE716
-:10EC10008AEABCB5F0EC40876B43CF1FA2C5C3B9ED
-:10EC20005D0DE3173B7768DFC2CF23BACF1908E940
-:10EC30003B12CEC7D9B9B9C72FBD1B89BFEAF9C3EB
-:10EC4000DB5AFDF4C776EED033DEDF8D2EAF9AD9D6
-:10EC5000FE56A5CFB9AF23DBE94EAEEF749DE93088
-:10EC6000E3B9315B67E6F175A69AD28D7DF7C6F000
-:10EC70003DC7F781E79ED1FB61BFBCAEE900DA5B1F
-:10EC8000AD9E571316FFD28E27C531FFA0BA79DF8C
-:10EC900070B047E7F6BF84F257BDF3B8C147E11C37
-:10ECA0006AFCBDA16D6850DEC18EFB43ECF8B9E78C
-:10ECB000F60D67E72291F3B4D8387C4F8B08DFB3A9
-:10ECC000F35301FE325F93C16EE9799CB3B26B16C8
-:10ECD000CCF76CAB42E03EFBD9267D913FC2B89F9A
-:10ECE000C13A362648A77556F61D9F3EC9807EE676
-:10ECF0004AEBD863F0FDF84AABC101FBEDDAD5EC85
-:10ED00005E65EDFF72A6035F6A136FC373A37A0D8E
-:10ED10001DEDC9F65CD887DBF34B46835869ED419E
-:10ED2000A24B27E0BDD25A94E6B0405E2FE6A71072
-:10ED3000D989DF19EA6D8545300FBD5D6737475CBE
-:10ED40005F193CC5C2F2662876F1BBBFEF9007831E
-:10ED5000403E8E6F9D07A3539307A3FCC6FFD7F2D7
-:10ED600060F8609C9F401E8C00C677D43C18C93F59
-:10ED7000721E0C882F8D0EC983D1A9C983C1F9F8E1
-:10ED8000CF3C18FFCC8301A59A07E39D0D65059044
-:10ED9000A742CD83716683A700F252A87930BEDA0C
-:10EDA000B08AD5791E0CCBFDAB0B42F36064DEBF9D
-:10EDB00001DBD53C18CEFB1F2908CD839177FFE6F8
-:10EDC00082D03C1833EFDF5E109A07A3ECFEE70A0F
-:10EDD000843C186BFF500079305E8F77B7C6A5442E
-:10EDE000CF83D11CE788290F0685F31EC2899207BD
-:10EDF000430B275A1E0C0AE744DC98E87930C2F02E
-:10EE000089920783C2F904E144C98311864F943C77
-:10EE10001814CEE738AF287930B470A2E5C1A070DD
-:10EE2000FE0BE144C983A185132D0F068563884F2E
-:10EE3000899E07230C9F287930289C048413250F72
-:10EE400046183E51F2605038E908274A1E0C2D9CA6
-:10EE5000687930289C2C8413250F86164EB43C18F4
-:10EE600014CE55F163A2E7C108C3274A1E0C0A67F6
-:10EE700014E213250F46183E51F260503813104E1D
-:10EE8000943C185A38D1F26050380538AF287930A0
-:10EE9000B470A2E5C1A070A6213E51F26084E113D6
-:10EEA000250F0685330BF1899207230C9F287930B3
-:10EEB000281C37E213250F86164EB43C1814CE5288
-:10EEC0008413250F86164EB43C1814CE7284132575
-:10EED0000F46183E51F260503877239C287930C293
-:10EEE000F0F9AE7930CC8141D240CC8381F938BB86
-:10EEF000F360247FEB3C18BF027CFF9907E39F7906
-:10EF0000307E8C3C18B75ADD7F8FC77DE377CB838B
-:10EF100071265E9337A2873C18B75A4BCE823C7F4E
-:10EF2000DB3C1817E2BF5D1E0C3ACE3F2E374EB4C5
-:10EF30003C183ACBB7CB8341C7912D632E339F2822
-:10EF40007930122C62FE901F2B0FC6B1F8249C4F13
-:10EF5000B43C183FB97C13749B05FBB4E9288AE4E0
-:10EF600027937F62B485C70D7FA8FC1330E99C9F6F
-:10EF700052FE09358F419302EBE1FB9CEFEF70B934
-:10EF8000F880E7A13816350F857F2AC677978A79EA
-:10EF900028A6703ECE768BF23085B0739429F9594D
-:10EFA000FE5AD8AF976BF2500C11CFE98BDD47F3C7
-:10EFB000293832D529CEE328978769A59F1E04F604
-:10EFC000DC3C36721E8A199C1FD3357499C2F936FF
-:10EFD0009D97B7C3A739549E8BCB8FCA40D7698EF4
-:10EFE0003619E3F437A9FC7308FC9BC9E16AF19D6B
-:10EFF000C1F9376332E39F16EFB7807F14EFB7CACA
-:10F000004721FFB4786BF1D4F29F84F23B247F4810
-:10F010002E11F34F4C3289F9270AEC62FE891BD37B
-:10F02000C5FC13931D62FE899B8688F927A63AC505
-:10F03000FC13378F15F34F4C77ADD6E4BFB84F9321
-:10F04000FFE2214DFE8B4D9AFC175B34F92F766859
-:10F05000F25FECD2E4BF784993FF629F505F58F7AC
-:10F060009AD07F71FD51A1BEA4E13DA1FF52FF7175
-:10F07000A17D59E3C7427B55D3A742DDD3FCA5D080
-:10F08000BFA7FC036FF1EFA1DFE1DF431FE3DF4325
-:10F09000BFDF43FE8B772C4BD785E6BF78DFE25985
-:10F0A0000779098E5B1C3CAF40E4FC16DDED51F2A4
-:10F0B0005F04DFFFF6F92F52927FF87C043A2BFBB6
-:10F0C0001EB0B7254F674DF9EEF9086E2D11BFEB55
-:10F0D0009E552A7ED7ADB3B2EFB567BBC5EFBB6F08
-:10F0E0002F17BFEF1E11E796000F6DFE8BDE1697F0
-:10F0F000CE0AF692E72908C077BAD9106F2BC2F270
-:10F1000020E4BFC886785B29968721FF052DFF0C78
-:10F11000F92F687904F25FD0F20DC87F910DF933B1
-:10F120007C3C7F461DCF9F51CFF36734F0FC197EA6
-:10F130009E3FA391E7CF68E2F9339A79FE8C00C233
-:10F1400039E13D8CE5496F2B96A7BCC7B03CE36D18
-:10F15000C3F2ACF70C96E7BC9D58B67B2F62196BD7
-:10F16000FE0C552E3F04BFE10A189FC9B32AA757CA
-:10F170003FF0C8BAD0FC19231ED884721A2D6F46EE
-:10F180000E7CD397123D6F46777B94BC19C1F7A3D1
-:10F19000E7CD481BFDE3E5CD986BF961F266CCAD98
-:10F1A00011F33ACC5B75F9BC1923E24A6E41F9E3DD
-:10F1B000F238D7125BDE0C9F55E2DFE553BA80DFF1
-:10F1C00045E982EB750F79070E5A9F1E02FB89AE47
-:10F1D00021575D36DF83562EA2D39BE57798F32324
-:10F1E000E7CBE889AE6AFFF72B581E87B9966F996F
-:10F1F0002FA3877C0B07B3BF403B196BBE8C9ED6F9
-:10F20000879EE839E347CE97D1935DEDC99EBE391D
-:10F2100085D1B9770F7456BF97AE34B51EC297ED3E
-:10F220002E546D997F0F9F3BD38EF1998E9DFC5E7E
-:10F230009C8B38ECA9EC7B7DF0373B9E4F184EF051
-:10F240003B7E3B7151FEC4F3E7D2CE7DFBE05EC056
-:10F250005A1B71252681B3471CFA81B00FBBC60427
-:10F26000F19AAADD9FBEF1470AD7DCA2C7FB721D47
-:10F27000148756F4FB5C89C0B778F24BDCA7C3193E
-:10F28000DDA55EA1DF756B7E0F0774490D9E3F15EE
-:10F29000E82DB86FEADACCEEB3EAC9D58F4F188DF6
-:10F2A000F7C689DF81FC433F7519C7B38B10670030
-:10F2B000FAEFB4E2FDD525AF2D34C0A070DE1A1AE6
-:10F2C00037E85524C6811ACCB6E1706F2F5DBDBFFB
-:10F2D000E773B5821FBE88C34D2911E3449F2C28D4
-:10F2E0003A0CFEF3227719DEAB482B15E346847FF8
-:10F2F000470FDB32F03365C2EF75FAD97DCFB0EF3F
-:10F30000EA9BB7209E4BFD9AFB4B8D625DA5DB39D6
-:10F310002BBF9762219698E8D676C5E31392BF3D3E
-:10F32000DD8CE922DDCC0E916EF14344BA68E966CA
-:10F33000758A74D1D22D61AC185F53E9A6DEA7FCA3
-:10F34000A1E89664E3F73C82F42A31A5A2C9473CC0
-:10F3500033E400CAB7561FFA5802F01B7E48BF6458
-:10F36000FF6A7CCB6995C16EA533D0445AC4DE8B4D
-:10F37000077D80FCBDC489FAA0FE3E8A78F2219701
-:10F38000FB8FC8255AAE987EF0F802DABA19E46D00
-:10F3900004FB3D1A18AF4A22B89F5388D30EFBA82E
-:10F3A00026AFC9B94881734DE25C940DE799762C7C
-:10F3B0001FE4DF3B770C25B8EF6F0A7C9E0AF70647
-:10F3C0001E1CD9390DE20F9EC5A404D6AF59096C95
-:10F3D0007D5DC64B5B028BCF6C28D111D768F87D61
-:10F3E0004A7ABF44C76BB7BB5EBB01FCD116763F00
-:10F3F00080D83BDFB81DDB47E1F7E119BAFA6B00B3
-:10F400001FDA1FBF2BEE68F9C8B630C40EB7373FFE
-:10F410007225DC6BDDA48BFC3D73818DFFFE1D7EB0
-:10F420003F654430DF42816D0CE6657870001DA7B2
-:10F430007A7A17F25195CBEB38FD0F964D41FC5E71
-:10F4400068911C10AF2BD4DF71D3308ADFB8B76559
-:10F450007EAF97DD5F1FCDFBD79AA9FEA2FDAAFF65
-:10F460001BFC9E95974ECA980F71744D19DE13FCC4
-:10F47000A3ADF030F02BC7D5340AE429BF2511CF56
-:10F48000713D1F12277E9AD52ADE07CCE1F7B673AD
-:10F49000DA881F84E2DA6362FBB836B17E9D66FFCC
-:10F4A00039DFC6F5D4465241EE367EAD9760FDE8B1
-:10F4B000E824CE3514DF8E45BD71FC8ECF09FA8964
-:10F4C0001D5FEB8B22DD8F596E63FCDB642068BF10
-:10F4D000379559F0DEF9FEB28AFEE05F7C7197BB8A
-:10F4E0007FA43865889F96C0BEBB772590B12087E2
-:10F4F0006B2546EFFA8C9208EB962A77AA1CAAF2A3
-:10F50000975116E78E740FF5339B847296573644E5
-:10F510003280FCEC9530FCD5BE86E2759975DB47F0
-:10F52000D6F4017C3CCD9FE17D32538BE48A744F4D
-:10F53000E7619B8DDD6F5CE35B0DF7467E419508CF
-:10F54000EC5486A13E2B127C1FD9887EE95D3607DC
-:10F550007BCFC4F320C9F519709FA2BD79D2E475A1
-:10F5600014CF27A83EC07AB5497122DEBE2A42F0E8
-:10F570009E2C8FD7F59D46B66C08F17F37DB721B4A
-:10F580006D145EA38D7D6FD9CBED94006FE77FFD89
-:10F59000C306F03B2E1A917FBDB9BFA9BE7780D3B9
-:10F5A000675C826B2BBC4FE0979F51E3E374DB9C5D
-:10F5B0008B46415C9ED23BC40E06F9E663F951DCF2
-:10F5C00004CF3F922C3A9443E27239ECC27D761F0D
-:10F5D000EA8DAA07242011C853A0DA37A9450A5892
-:10F5E000A9DC8F365902708F2EA99CCE3B19F29A56
-:10F5F0009818BC56F99C18D7A2F29803CE3DC1AB1F
-:10F60000F3104805F8AADD53EDE5DA44668FD63EDF
-:10F6100024635ED4CD729B19E2A9592E471EA4889B
-:10F620004C921D78AFA65F3971520C49FCC05F2720
-:10F6300076FB0154C9AFF9463F2FD2775B176DCCEB
-:10F64000DF1E97E0FE33D06BF8E1CEFDE02E38CD23
-:10F65000A417BBFFC5ED04F76B0AF97A37EE3F74C8
-:10F66000EC7BD1C00D24F43B2AAD9DD86466EBFC45
-:10F67000B8EBD9BA37EEBC05D7BD6E3B515688EB17
-:10F68000D4C8965107E09EC5C80F997E126E1FEC34
-:10F69000F40FD029E7B04F0FF4F9B67641CB6F12D3
-:10F6A0003075D787EAE01C86EA5BC8FB673576646D
-:10F6B000C5F441B5185EE672D4FF1EA7DE1D4247B1
-:10F6C000EDFBDD714AC9D4FDDC3110ECC8113DDC25
-:10F6D0000BE9C8A5F3A3F3DFC8F525F173FF649820
-:10F6E000D7C6961BCD20DF6B0379F662FA4EA2A92E
-:10F6F000049997485C18CF19493D32C88F518B4205
-:10F7000041FD41A58424A4C03DB42221DE432C49FF
-:10F710003CFF4B00F9D22DA7548E43EFE5AAF2A986
-:10F720009547557E6BE1A005CE0721624E4BBDD4B7
-:10F7300084878146B2D90EEBBBEA5FD6727FAED624
-:10F740009CE9C7EF977C19E81FADE4FE51ADA5D049
-:10F7500084E6605F32AEEB2B217E42E9B03285D980
-:10F7600079753E5AB9F45CD4137FC83EC12377E261
-:10F770007D44CF45033E5FA7B807C0FC55FA5CC384
-:10F78000E9A3A58794C0F79D9C2E3DE39B63877BEF
-:10F79000C1892617598FF8E6E13DEEA6C04813ACA3
-:10F7A000BFF76AF08D01CF6B13C684E3295BA2E03B
-:10F7B00099CCF0BC8EB8FFD846E53767455D6D3C07
-:10F7C000EA15792B3D275CAFB47AA4EA8D1AE7BD20
-:10F7D000B6B2FE005EBBED416F3CF18C2E4EA5042F
-:10F7E000EF5739F7C4A31DD1EAD3E77CFE9E7846D4
-:10F7F000BF058A7B06CCCFA3EBCC043919EE20BD24
-:10F800008A2992C39BF5A8E7A435B67BF8AA7FA501
-:10F81000FA55DA7EAA5FA5DA63F51EFCDA04F77CF6
-:10F820009003A999CA2DC5A7D6CEF64B9B6DEE4580
-:10F8300080573CC53D0EF68D430259ECFB5F512FBE
-:10F84000A2E941BC46CE9B0232AE0B3EBA2E644BBF
-:10F85000E178A8E30F4A48647CA45A0EEB7DDF1CD4
-:10F86000C206AB269837A7EF70E28675ABEF4876F5
-:10F870009F714D02B3BFB5096CDD52CBCDB692BBC3
-:10F8800051BF65E2338EFCEE7803AA70DF7C6D8297
-:10F89000EB2EA087A9C885F3E863274EF04BFBC881
-:10F8A0004D127C379A54E990D83D7312FC7E8BC27E
-:10F8B000EB53ECC8057DED03FB6BE8DF1239CFD8C5
-:10F8C000A309EAFD5EE67F3A49771EAF471398FF2A
-:10F8D0007908529FF42A56F382A9E7394E09E8D4F1
-:10F8E0006EBD0D916EBF20313F3D91D14BBB4F009E
-:10F8F000C287FEFEBD7B0D44362791E0EF59D599B6
-:10F90000D0BF8F27CE26B057BB1206F0734C671DB1
-:10F91000D47F25779A128706E55D95E30727CC709B
-:10F92000422A52DBF55DC3614F45E57A27D0BF7DA2
-:10F9300042D760CC41493A3399FCB8F442BE209595
-:10F940000FCD8AC00733ECC343EDA4D53004FCD1FE
-:10F950007629CE09F72CDA974A0C5FC9C4F329C976
-:10F96000C23CD3E3997FDDC1EDD53B09592827AAD5
-:10F970003DA6F3AB83523B0F8F11EF7490CE3DF158
-:10F98000FEAD706EA5C93FA9CD4F3969A105EF7FC6
-:10F990006CDC63C6FD6B57093BC7EF6A31A27D8EF5
-:10F9A000A6B7696DE688711CB5A4F47B0BE897A631
-:10F9B000D424823D4C9B7BD2067CD7D2A543F25DFA
-:10F9C0007308F645AF2B11BFBB55CBF4F49B121750
-:10F9D000D1FEE91993B1549F3758E488F7CD4F739E
-:10F9E000BD52E5F14A3A22DF0F9D06793CEF7EF3E6
-:10F9F0001D1709DEDF6F8863746C886374EC728F87
-:10FA00004F781AE4CD9781FAB0583D07E5FB7F3572
-:10FA1000CF943ADE46AF2951A62AD0B0608A19D6D3
-:10FA20008914E29A3C1B9475A342E03BA2C7BC3BFD
-:10FA300012F3318E6D12EFF9DAD9BDE1CF3716E04E
-:10FA400077DEA9648D7930A5475989CE09F183F312
-:10FA50000BDEB7E9A83C2DE8D39A03F2FBBAE22605
-:10FA6000F63118EAC2FDC99252833F40F996DC4054
-:10FA70000D05A5CB7F03D85B39A8008000000000EE
-:10FA80001F8B080000000000000BB57D0B7854D5DB
-:10FA9000B5F03E73CE3C92992433794E1EC009E1F5
-:10FAA0009D108724BC1F4E9E448830BC0485EA808C
-:10FAB00028CF2488D6DFB6DECBC444F4A2B745E90C
-:10FAC000AFF4D6DB7FB0A2A8200182069AA413402F
-:10FAD000E4113408A8A8AD5129620BC908EAC5D6BB
-:10FAE0007BFDD75A7B9FCCCC4922D8DE4E3EBFED62
-:10FAF0003E8FBDD75EEFB5F6DA872EC977134B641C
-:10FB0000CCB7D8C0B64A8C7D87BF1B43ADD96E60D9
-:10FB10002C89B196383BB54EE70CC7D284F07E8570
-:10FB200063693E63D5D6D85C16876D7F3F8B85F1C0
-:10FB30008A58EAD202685BACAE5A95B12546AFDD71
-:10FB40000ECF774EBA3CA48EE12FD8DF3392B12E80
-:10FB5000236B94E2B01F606C0C4350F8CFED56ED70
-:10FB6000D097F0FFE1FD448B2D20C3B8CCA35CEC13
-:10FB7000B0F047BE1B281E4D66CC285E939ADEF877
-:10FB800046CA652C7672116370DFCA5C8FB22CB8DE
-:10FB9000318CA99E18C6A2D833F6F3D98C19F07D02
-:10FBA000584757F3BBFD7C00C71FFEE54A0C83FB9B
-:10FBB0001F29C118570E63171E3C15E3B6C1F50780
-:10FBC000E5723FF46F4740C687F0926F870BA31929
-:10FBD0007BC4EE1981EBBA63DD7F8FF1DA42F7D98E
-:10FBE00003703195B1157E19E7E6F0C27FABB659C7
-:10FBF00019B384FA95F509117DC018E1B5D2CCD6B8
-:10FC0000D4DB7AD26305D203E65DB17D8B295DC575
-:10FC1000F9BD93ECD0BFA0C0AB80EF0B0D317E5F80
-:10FC200066089E25DB4799D2E1D6474D661680755A
-:10FC300030A5DDC86C84B50A09F0E61578D3C37920
-:10FC4000B8C54AE3DDF57F65BF1996BA18E67A2094
-:10FC50001E9E6F5A51C1727BAEE3AE3FA86529402C
-:10FC6000BCBBFE4D623E953FFF601E3CFFC0235F64
-:10FC700020DDF4EB5CEC337ED211B16E376300CF44
-:10FC80003241EF3B1F8DBCBFACE9311A6729F39AB3
-:10FC9000909E776DD4DFBFE933E4BB654C095D0707
-:10FCA0003C5C3E9265453CDC618F493C0F20038FF4
-:10FCB0008DFD0EDEDF7D64609C37A7277EB5F6E202
-:10FCC0003AE06F33637F5E67A1F6C23A46ED08BB48
-:10FCD0004AF459DD74F27EE4AFAAC65D261CA7C5BE
-:10FCE000FFA78409F04861D3373232572173DF7B95
-:10FCF0000EF0F92326B3EF007FBB19E79FF546CF3F
-:10FD00003D48AF1BAF96D37DFDFA1769FC7F249E5B
-:10FD1000F86711AE3B17AF2B5FF6B6AE9FE2BA8025
-:10FD20009FD95858977CFDEBD2D6A3AD4FBB5F2926
-:10FD300003DFF5F2BEC6EF23843E58FADCACF5696A
-:10FD4000808ADAE6CFFA77103FB1D328BF1A3F2D69
-:10FD50001374D2F38D46C76EFE68FA775A9F463FFA
-:10FD6000E07FA7C1896DC06918D7934FF47CA1E7E4
-:10FD7000834E63477F945F3D1F744A6C416FEBFA7B
-:10FD800037FB405AD752D55D6687FB7731CF7A3B38
-:10FD9000AD67235DBFA06C3CFC3394ABE7385F7765
-:10FDA000EB3933973776DCE847BDB936464D71D825
-:10FDB00004FD80CE9DBBCC3E7C4E9BE7FC3AB77BDE
-:10FDC0009011F15E4EED9FD779DC830687EEDFFD63
-:10FDD000AB2BB12ABCDF358C95A3DC77C644C2BB04
-:10FDE000CF2E133CFB900EC87F4AFBFF7C803AE984
-:10FDF000B9F631A847CF7FFB5FB11E78BEEB5B73CE
-:10FE0000796FEB3C2DE807EAE5B413F8EC7621674F
-:10FE1000B73755125D963C33CB84FCCC1EE0F8B46A
-:10FE2000C01FEAD7B6A8D867711D8B1B24D2237ACE
-:10FE30007ADCE59AFA39EADB3BFD85F47E0FFAB00D
-:10FE4000C789BE77213D8685E831D6A1727854F8FE
-:10FE500003BEB943F0CD79658DC9007AE4FC3380E7
-:10FE60006F007995C2DCBDE9C1FE0ECE877DAD473E
-:10FE7000BF8EBEE05FF65CCDFA3486EB1F654AEBC1
-:10FE800045EF68EBBF8BB96249EF88F5B28E1B492D
-:10FE90005EAB2D7C5E6D9D2B9AEE9C817C51B519DD
-:10FEA000E895D973DDA87717F7026F997CD168813F
-:10FEB000F7BA1E905CA86FFBA283A627EE12F85A31
-:10FEC000B96DF10C349A8B613E3913F5D1176FC6B9
-:10FED00024A25C415FFA1E7A35C91F9B711D8CE319
-:10FEE0007B09E07B8374FDF45BB6B9D03D28ECB9A7
-:10FEF00015FE9BDC83C2F5998EAE6CDBACD0F3644F
-:10FF0000B7DD26B4C7F10EA1BF845EEE5BBE60E133
-:10FF100000E7DA1D0EB26F6C8D83F46375D3165350
-:10FF2000B8DDD5E44B93B7B10E3BF15955E313F46B
-:10FF30001CE85FD501FD4A4BC7CF6F55C3F0394E62
-:10FF4000D051AE30A1FEEE4B7F82BEF9B2236C9D44
-:10FF5000231CC2AE08FD7B2DFDA0C1AD1F57D307EA
-:10FF60001ADC1ADF6BEBD1F37D5FF0E9E9C2989FF1
-:10FF7000FB0B3AFAAC427A84F5115E05F0DBD66CE5
-:10FF8000F53F04F0B6491C7E5F7314C1DFE92C769F
-:10FF90009F033FAF2A7521B527F0C554F4EB3CD33E
-:10FFA000109F9A3FC70A1222FC247DABF93779C211
-:10FFB0009FDA1BE5CE0713093F4F02F2C3949A8ED6
-:10FFC000391620D9AD8EEDE50A8C3FE5898E395181
-:10FFD000D05FE8D8C1FB5B3B4E595C8CD5B057CAAB
-:10FFE0004BA07F3BA013C7BB565B60F62C44F95D6A
-:10FFF0000D7E9205ECD1EAD3430EA1DCAD6EAF28A5
-:020000022000DC
-:1000000097C0EEAC068323813DAA74C706ACB9D471
-:100010006713E0B9E7EDDE65C42F57EBC86EAD3E60
-:10002000AD70B9399248EB5700F62878AF2E1AFC1C
-:1000300055C0575DBCC5559B49D77D51F1D877ABAD
-:100040006AD8758D1EF81EC25167606E07B4AD4741
-:1000500087C4757C8FDD6E5DC72A14E08383EB2C2B
-:10006000D4EAEF179AEC83D0EE151A98B7377DF9DA
-:10007000A483FB8DC0E4E948E7AA23269277FCA17C
-:100080001F5829F4511510280EE0A93CCD02D1B11A
-:10009000F85CD9E70AB60D12FB24C25F61A1BEDC91
-:1000A00037DCD7DB56E17883C3F984E3A948912A8A
-:1000B00094B0794B6C51117D39C5300CD7C3E468CD
-:1000C000D756C0AF9C6E58B31BD62F0F8016F0A129
-:1000D000D85DF2626837164F9197405B6BE476B556
-:1000E000D6C09687E3E905811FADFDC0E1D98A74CA
-:1000F000BFF456FB182BE9AB0C3BC9B9586FADE404
-:100100000A50DCD4CA5C5BE15A9DEC619C8FEB1910
-:10011000F2F11B621C97D9B047057E6D747C40FCE0
-:10012000EB8A33DC9B09FDC0131FF17EBAE14A263E
-:10013000F0F781273ACA15900757B6E1CA40E81F81
-:100140007AE2637E7F220C0906EAF0139F94FB6C2F
-:10015000382ED7676CBB3B1BE7510C12C9A972C084
-:10016000E4AF85FFAD8BE5FC54073C82FCF786B01D
-:10017000B3EB6B8A5EB602FF2B456E750D8CE3C741
-:100180008069F4DFDF6A7894AD068A53B0457CBF9E
-:1001900029D6ADD18135B8B367A15EA87767CF8E78
-:1001A00041BC7A4F225EF3DBDAA7A03E6E78FBFDFE
-:1001B00031E8AF22BD709CFC3688DD603D975EEB78
-:1001C000B7450E8B473F7014BEE3003996DCDC9FC9
-:1001D00094543B5B047257EB66AA09D695A28BEB4D
-:1001E0001A18D72FCFDB3D7FC4F7584680EC4DA1BE
-:1001F000C3FB31CEAF8F57597B7CAF7A59AFB74C29
-:10020000B90FC8E8E7C4A737BEB704F5FBEFCDAE1A
-:10021000C12AC2E5660F003C3B0D4C61F1C426C308
-:1002200094028C3FA35D1B50EE5DCCE90339C330D3
-:100230008D80845FE298B0B855AC07DE2F61D08E18
-:1002400045F86EA0F5C9C857A3984746FD3586F90D
-:10025000ADD87635BFE644BC3D19C5EE40BFCFB240
-:100260008DB9FD61FA63403CF7F726251809EE6861
-:1002700063FD6CE4D7E82F981DFDAAAEFF34293842
-:100280003E08C874BCEE3A6C6008E70B46BF3D0EF2
-:10029000FAC1E18AFA2C0B8DD725E8AD8DFBA44974
-:1002A0001DEE407D93C0FB2F1472FB1CFCDCE47F31
-:1002B0003613F16359E30F932F673CF75BBD494554
-:1002C000F1F1D0D63747339C7F6C4BB401E9F0F2A3
-:1002D000F6BC28E4879D881B587FBCD97E0F8E17FB
-:1002E0007F05E0CDA4EB6EC2ABA28E8A03BC4E9814
-:1002F00066533700DE5F88AA9F86FC1FDC6160CFF3
-:10030000C2143B4DAE59D8DF7959B5A3BE7D21B398
-:100310003E9AD6B3C340EBD9191D1CB116E0DE30AE
-:100320004C2947F8142B53500F2B8622F51EB83E4C
-:10033000349EDB574D2F2F88E7F2F3A404F3E7E157
-:100340007385243FA5B28DE4AE2BC8FC669827695F
-:100350006EBB8CF4889E05AC847CAF046406FD49BA
-:100360001E46498D4936A35F257DEBB62D06BA4F53
-:1003700011FA76CA87AB2B78DCE33A3D11C63B68AD
-:1003800033325CD764D621A33F38F92A7305907FB6
-:10039000AEF278C60E7FE83F3DAFF3074BC578EE6F
-:1003A000A0BD042F17B2483FAE7473D9E712CDA396
-:1003B0002A68A78B2DBAFBE8E7C5621B193795C5DC
-:1003C0000BFFA63FEBFF1DE937E05E98EF3E3B9F3A
-:1003D000AF54CEF915AEAFABDCE4423CECB2B9DFC2
-:1003E0009D887AB1DDC8B6B2BEE5E979883FFDE007
-:1003F000730CBB6A65FE7CE2471BAE67C4E68DBE2C
-:100400002858F788417C7CE43BD42343FF333101F7
-:10041000F5F855A15FB456E333E4277B1CE727FBCF
-:100420000D2139BC333E939ED3E40AF90CC7D96F32
-:10043000F42FF4F46227813FEF44FEDC6563144738
-:100440003D966A598072A5CDF3BCE0637DBBBE6664
-:100450006DAB11D7FD15D80380BB24EDAA29DC9E16
-:10046000EF49E27C552A7F4BFE766793C4D0CF4F8D
-:100470006EE2FA3B9C3F527BE78F5F225EAFC51F67
-:100480005ABCB0FB87F2C791BF8F3F365C933FBE2B
-:100490008D453CDCD75C9CC2BEC7BF6914FCD0D77D
-:1004A000FDF156AEE7F4D75F1178DD67DA383D1716
-:1004B000F5C0CD0617CA39503F7D36AC635F347F37
-:1004C0008F296BB2B0BF4BE17A65579399F4CA2E6E
-:1004D0009BD74B76DC6961E83F30C5DBF133D487CD
-:1004E0006916754318FF2E8DE7FC566F0C8CFF0CB8
-:1004F000FDE2A39CCEE36ECE934DF05CEA522EE774
-:1005000005174C5B300E2B4D28DC817C7402751670
-:10051000B4D5E7E029407CD53913E9BBD75A4E96CC
-:10052000617E11FC1E37F2D9D8FD27CB8A72F07993
-:10053000AE4FF78A56EB8FC735C5B3EE78D723ECAD
-:10054000C678C6F59207F92437D4676E23C56B1AAF
-:100550003FD447033F805CCC67AA3116869C73CE9C
-:10056000F330984336A73C92CEF303D3283E9C7BCE
-:10057000BAFD55D0CC6C9E47775FF0C17C1D1F80C3
-:100580009D3D1E8FFED2F180C980F399D664737FA2
-:10059000684D16F293264FF4033CD5FF61D8B31B88
-:1005A000C2EC7B6C0297A3C75D0ADDF77598FC83EC
-:1005B000E1D2BF33FE5EBDB03F9FA33C63FC70DF62
-:1005C0002B0BD18EE62F771F44FC4F4F92E9FA2F69
-:1005D00058C09285F47129E497D51BD5E2CFA4D0F9
-:1005E000734CF10CB3C1FDFD49D1F9387F6982F735
-:1005F00022D28929C123F8DED80979F9285FB651BA
-:100600007509688F34B801AEF2ADB6101C1A5C677C
-:10061000055F94262CBE88EBC7F750BF347E7CDE86
-:1006200082EF6B74AF6FFE82D33B8CFE48EF10FD00
-:10063000A53BB0AFE1E12BA157B4FE3F4A7F2D7F30
-:10064000704DFA637E20F6EFA2BF352129447FF07A
-:10065000B3E2B1AFF7B3EA4DE077E7F4BC5EE82868
-:10066000A4E75D265821FA552D1077A23C7A1DB4D7
-:100670002FB0C7CEE7EAFAC3F9FEE022B2C109F112
-:1006800084F76A537008FA21A30212F985A340F097
-:100690001791FF95417ACF25F0C4CE4BD2F961DC9A
-:1006A00045FF2E1DFDC34002FA51A3CC1501E4F70E
-:1006B000DDD629E9E8D7E5592765215FBD3AECBECB
-:1006C000E368825E4D5BBEE73935E4FF68FAEDA072
-:1006D00018569BBF2081EBA11B41DDA21F882E6312
-:1006E000381C9A3E47F2201C5260BEE13B2BE9E5E4
-:1006F000A60EA0C78D0807E0A155620DA8CF0B0D6F
-:10070000EEC462F4D392020AF7F7BEE98FF9C18A08
-:10071000A637DE43782B703F04E35097F162773EB3
-:1007200062604F3F58F357B4B840F367B4F813FD15
-:100730001EBC3F405CB79B0140B447018BBF06E63F
-:100740007FF2B23ADC2DE4568175548875CC64EDA5
-:100750000417FBF6BBEF26017D66087C541C81B8AC
-:100760003117EF337633E0E16685C79337BB207EE0
-:100770000CE3A399E322FBF89B921C1AE75ACFEBF8
-:10078000EDC044DDFECC3FDA1E017BF409B8CEC7D4
-:10079000D6F1B874C240D9A7A0E11C9769407EACDD
-:1007A00016F60DC2E85EEDD24BC22F9E60E8C8750A
-:1007B000017E5BF7FF8DECE081FD7F7B07FDBCF1E7
-:1007C0009F2BCC0CEF4FF8BC200EF5041BA7125F3B
-:1007D00069E356FFA9C1CAF875E2FF2AB1F6C30062
-:1007E0008F7B28C267A1F677179FDC84E37D794E63
-:1007F000E1BC2DE62F337907611EBBCCC4F3018722
-:1008000025EEFF68F70F1B016EB8BE2941CB0BB474
-:1008100093DDC79F398CCE37633E202F44D79B2F63
-:10082000947FAEE4F6A40FFEFE37F2015A1E60ABD1
-:10083000C01F3B78D6A4025C531BEE51D0BF9EEA8A
-:1008400094993B6CDE9B542B7387E5039E49D0F94A
-:1008500023075FDC3403EC49759BEC8A42796DDA3F
-:10086000753C17FBEDB2CBDA0B1FE9F13BB5E91E86
-:1008700005F9DF98A8927C5F6BFE0923804F6E40DC
-:10088000BA33F2EB3AC74824477AFA1ED8FFEB8412
-:100890008E9CBEF1DD17FDF574F8DDC522DAEFB9E7
-:1008A000163DF47CDB02EBF4C1FA02B04E1FF85D9A
-:1008B00007D6D9A97F689D93FA1ABF5637FF36012C
-:1008C000FD368D4F4B1338DF8CDFB72981D942F4C9
-:1008D000D2F0F5A1B0577BA3347FC3356F065C3AE5
-:1008E00005768718D4C7DA9D6342F66BFEE932F2CB
-:1008F0003734FB355F5E544A6A53D82F4C23A35ECE
-:10090000D3DBA9B9EA6223EBCD3E2D88EC97B76D16
-:100910005462A867203A4992C087F0B33538CE3088
-:100920000FC1A9A7A706971E1E6D7D9A7F3D5FD0B8
-:100930006FCEA04C23C2DFC3AE8A75E2409887B861
-:100940005EBBFAB58E9FAF5C28792BB717BEED8BD7
-:100950007FF5F7357D508613E451EB43BFC298987D
-:100960004C742BBB6A626EB01B2C238A7D1A6657AF
-:1009700058C550E29F7B851DEE8B7FAAAECACC9BEB
-:100980001FE22363E31356E4A37DCA462BE6272721
-:10099000DB66D5C6019E4AFE543417FDBCEA0E0341
-:1009A000C3145669D3170731AEAF7E8FB9502F16D7
-:1009B00035B51623DF1D52DA658AB3BF64EC893082
-:1009C0007FB1B1A9D68AFE5463A24C71FC6107E7DE
-:1009D0004BEDFE9644AE3F1ACF5D9EE1EEE5FE196B
-:1009E00071BFE4E33CE2A3B24741AE310E4D8AA1B0
-:1009F000BC4489649F53817EC84D46F2F3218EF931
-:100A000023EE035E6A34EFC2D47E69E323F7D88114
-:100A100010F5FFFD698D19F30BB324D7B3F05C9982
-:100A20001A6CC57ED9DC4CAA7B18FB3F32F9B3C1E6
-:100A30005B25CA8B9401BB60BF6C51A61FF313FBEF
-:100A400025DEF735F37D0266F725CC8079DEAE48EA
-:100A500018B581784AEB0FCEDBC0042387C557F762
-:100A6000ED9549CFDC572AF971BFA9D49ECE7C61A0
-:100A70007C55F6A889D635BB29A508F9784EB9CC9E
-:100A8000FC61FC1D107EE13C0FC4E161EF1D8EE2B4
-:100A900070051703DC52486EA7093E9FC5B89F3802
-:100AA0007F4142C47BF0C62D688F6E6D8238157A07
-:100AB000D344FC7AAB373D625E0FE37ECD09162C42
-:100AC0008983F1FB250D24FE9B11B48F0EA8A87716
-:100AD000CE24A25E63C3B89C6872572AAFAE237E51
-:100AE00070F27DB2791248938CFA2F529E668E8BEB
-:100AF000ECCF72F7A83788907FBD5ED7E47E5EB3F7
-:100B00004CFB72F30A2517EB453FE8FDECB1D17DB4
-:100B1000E8856FD587E37AD30B1F96FF5D7AE135C1
-:100B2000082BC681FCFE3451E8877EAC1FEA875251
-:100B300079FB26E4972EB077E65EF845B3175A3C6A
-:100B40005E06F24AF27E91EF67945E4D65BEFC5000
-:100B50003CDEAD2FC09F70F5E2E73C9D984572D416
-:100B6000AD5F34FD11E64F18C7FCE3FE4429F89150
-:100B7000A63C842F83E02B633C1F588685439897BF
-:100B8000737E41F9966A88F329DE67BF25B850CF96
-:100B900049F12139D0FB195A5ED72AF2087ABEE80A
-:100BA000CEF3CD35521D8CC61765762E1F65736545
-:100BB000CABBEBF9449B4FCF1F015D5EE69AFC2157
-:100BC000E4EC87F24773A2D8571DC4065D0F5F6837
-:100BD000FCA0F187DE8E1CD3E567FAB2236FA21D5D
-:100BE00019DDB71D797D9891F4B5DE7E68F6E27760
-:100BF000495C2F6724F27D8E69C3E7D9D0EFB02618
-:100C0000F13A0DCD0E75E79736737E78BD63892274
-:100C1000A13D41BD9019867F916FD5F8AFEA51890A
-:100C2000F28D15422F7536F3FC5B7589ECB7C0FF6A
-:100C300016373DB189F78D949F2B545A150B8C3B79
-:100C4000D325B930AFE316F9BA196E89E7EB5C9199
-:100C5000FBF42D3AFACE117C349305EBD01FD7EB81
-:100C6000A53957B95FA0D74F73C4BEFB1CDDBEFBCF
-:100C7000554DDE07B001FF4C7FC09CF4FDFE80F6B1
-:100C8000BE46478D7E2AEEC5A11C1DFCC6A4C670BB
-:100C9000FF19E937F5AA42E3D893045F0A7FE6CB50
-:100CA0008B79BFA0984F3C5FDDF485C93BB26FF8EC
-:100CB000AFE5B7C6A29F3E3AE4B76BF34E53184B6D
-:100CC00047C74C674F6689EB3FD47E0CD7AD43A333
-:100CD00083A6477BE059E8D9BEE8742D3DABE9B364
-:100CE0007FB69ED5C6D7EC8036AF5EFFF615B769E6
-:100CF000FA74FD1603E54B268BF878B2C8C3CE4FC5
-:100D0000E2F1C1AD493CEEECFACA62407BB9B38571
-:100D1000FB272EB3FD38FA05A17C1FA7E7C331CC12
-:100D200087FBEC4C69B7D0BE67119012F73DD3F842
-:100D3000BEE77625E0213DED52580DC8C9397C0F3C
-:100D4000E679F8806F21EAE9873F1962A0FD7725EF
-:100D5000D08EFEC9D83C85F68F1C6695F2C19DCD1C
-:100D6000663BBED7B5EFFFB41A719CAF980B43B882
-:100D700043CDE6EEFD1BD407A5729B8CF9FBAE209C
-:100D8000C8083C3F6941A018E3A0C9ACBD16E57B8B
-:100D900002D2B117FAFD2A498BB37BCFEF17377315
-:100DA0003FAE3846263F6E8AAFBD18F7ADA62892F3
-:100DB000AB169FD5E5F75FD1C51FA1FCBEAAF0FA1F
-:100DC000435DFEBE91EB99EBCDEB4F40DD067CBC65
-:100DD0005EE373A16F581FF9FD9D26BEEF133C69BA
-:100DE00064E807B30B89BDE663AE95E7DFD712ED84
-:100DF0005663719F8EFBEBFB5AD2DC6A6EDFCFE746
-:100E000076048BD03CEEDC3E5BA1FA35911FEDB150
-:100E10007FD2C7FE88BBD17E08D5695FFB21C55F45
-:100E2000AA94F6B95EBC69750B4CD43FDDC8B49F7B
-:100E30009BE474E7F96837F2F9CEF3696E84EB79D5
-:100E4000C1A71ADFEF3B77399AF6414D6E15F78F40
-:100E5000830E8BEB59E25BCEEFF5A943FCB84FFB59
-:100E60001B21173BA383C7B213C3F73DF83E47CB03
-:100E7000BA47679F33D27EB984F9486D7FD907722C
-:100E800043753DF18CE20F23AB67386FAD9BFD1AC4
-:100E9000DB2993D438C4FBE5446D1F538DA33CC4B8
-:100EA000B757A8CE508FFFDDEB9807EB511AD659F4
-:100EB0003C0AC8FFABEBECD46F5CE7A476FF3A9535
-:100EC000DA878EC73E8076BFDA6DF22861FAE39D3D
-:100ED00064EE77E5657F524CC5DF7F6354873EE55E
-:100EE000C10E19F5C58D57611D117527CA65C43727
-:100EF000E537B342FD4C69710CF66FBC0AFDB0E7F3
-:100F0000AF2439B83DAA53EA462793B4105FFC2DAD
-:100F1000C9DD9104D7EF71783EC176B734FFE02583
-:100F200046FD73BC7FAB7C099ECB0F14525E391F0C
-:100F3000F3CA7934EC42C4DFE85613ED976BF9DD60
-:100F40003C4DFEBE8ECC33E78BBCEEABAC83F2CD1A
-:100F5000051608B40C0817A79F5B9AE794301F98F2
-:100F6000647261BDC3E82C4F3EE6635B9318C547CE
-:100F7000ADADC9196A0E720FCFFBBAB5BC2FFBFE1F
-:100F8000BCEF918F627DA4B7AE9A687FFAC8A9586A
-:100F90005780F60B2DE4FF69F5C82DD1BCCE8065D6
-:100FA0002CA03CD38DA29ED162F69A93495F050E88
-:100FB0009E80F77E7F99F17DC7F60F695FBBD830C1
-:100FC0003C05EB7E0F4A43E3B07DEAA3D81C6A4F91
-:100FD000C55E44FCB418AC2ACE7B669D5A82756D02
-:100FE00027D6B112AC637B6B9D85DA93EBECD49E74
-:100FF0005AE7A4F675B88EFC731C9E477E71BF65D8
-:10100000A37D92296FD9146CF316C650BBFBB6189A
-:1010100013C2DB12CBB66BF360BD5A203AD080C945
-:10102000FED6A7BC8F59FA81DD337B474AA3186BE4
-:101030007BCA3B5D990CE34EEDFF93AFE0FE9BC98D
-:10104000CB1EB3005C734FD91ADAA0FF76F2F2C759
-:101050006CA86F8F4783D2C3F5AE38EE1E0474437D
-:10106000A590C605978D837E82D65F31BD641263DD
-:10107000B71477643360ADECE495D32D80C75BACD7
-:10108000DE1F63DFE44B9A5ED20FFBCC87F5604135
-:10109000C948713FCB9012B1FE65A6C3FB4672589A
-:1010A000FD9E5BFA13ED338D714BCC41871F8CB4E1
-:1010B000EFC5EC1F2784CBDB4C47E91B488F89C960
-:1010C000BC0E78F424C91D5E5FA17F6EF439B504AF
-:1010D000E934E642591DB633CB1DD4F72C185B8793
-:1010E000F25C62EBEBFD627ABF3C99D78D1429521A
-:1010F000445D89FEB97C6026F48F8347A3294F3075
-:10110000FAB4B716EB4F4B9D9979B2A6FAA8EFD86F
-:1011100082FB6DA32BCE9424A0FCD824179A89318E
-:10112000ACA32E01EE17DAB1A00AD7F54431D6FFF1
-:101130008C562517A2ADD0DDDA80EF17BA625C8538
-:10114000E88F9F564BD0F49C52469D2880E7A60E10
-:10115000925D1618E854E0A68997A05F382C8EF2AD
-:10116000BC85CA9A2B27A81FE3AA51711D5B7E5D1F
-:1011700045E398C9AEEF9E51FC2FC83F459E38CA43
-:1011800009023E4AC2EBCA60DD0477A15DF6474919
-:10119000C8DFFF5A6287FEEEFE1296CBC37CC3FF08
-:1011A00042F78F44AB5100E86E93BD04C7DB6D92EC
-:1011B000EC0F51DF538CCFFB861855CC1F9525467D
-:1011C000458C3FB5441A7F0EE1CF891B85D7CA33C2
-:1011D0001C11F7DB6EB3929DA8782B87FCA2B6DBBF
-:1011E000D2C95E54BC35A908DB3603F7D32BDEAA7F
-:1011F00028A7FB061E07572CFC915BF429EEAD587F
-:101200005849FD5629E52738DF959CB83CCCAF4DB1
-:101210001B945AA244F8810349FEF3447EAFD030B8
-:101220007CD32480FFDEA37C9FA2222733E2F9191E
-:1012300005524978FDA8675254447F7689A324BC9F
-:101240000E756E456A44FF96B99911FD92A3056427
-:10125000BF410F5494801E380AED5260C1025107FD
-:10126000A5E59F0A054B15B68BBCACC2E3EB61F05C
-:10127000877AB0C41669A77747733B5FCED6D0068E
-:1012800049F911BEBF5D9668FC24DC4E94CB15363F
-:101290005E97158987BCA346B2977931921FE3FA0E
-:1012A00092A34BEBD0F4966744BEAFF961E5023EE2
-:1012B0006D5EE673B7A33FA2C1ADCDAFC15F2E2F68
-:1012C0002AA17CF735D6A18797C17A503FE8E1681B
-:1012D0004A16FE1AF81FE4AF897324F04BECCD7E5A
-:1012E0006BFE7A05E82B47B8BEB2498958B7D79745
-:1012F000BED2C6EDCB2FD3C69DE9F0D0FBEE1D9F2D
-:101300009E9A2087F5333F4E880FEFBFF8E9A688F5
-:10131000FB491FCF7184F7B77E3A07EF4F51D45A7C
-:101320001BF0E53126B97CC8076DAA1203F4283EEC
-:10133000EDAEC3B6F4432F96ABB2A9E77C75D84E99
-:10134000BCE86F33C3BA6E1A26AB18BF6B7E881E1B
-:10135000DEBF26F3BCC3B1ABAA15F75977FB542BFC
-:10136000FAF3BB1F54ADE887EC76F37319EE2C0348
-:101370009D8F7167F37AC5BF24F3BA834EF1BED651
-:10138000FA8DDE4E841BEBCCD137A8FA264875E5E2
-:10139000C7D0BFCAE9E95F1D53FC369CEFD8837EF6
-:1013A0005BF87EE2F5FA577F041E43380A99E40998
-:1013B000D723C596284FB8DC96DA1D11FD93C20FCE
-:1013C00099EA4C8D78EF263533E239F01B87A15F1F
-:1013D000526B62546FEB33F07A5B3D1E57A4F0F80A
-:1013E000CE65B3A33B83FB66726FE7915CC5865EF7
-:1013F000CFB7A5A4707FF03F5218C1352B85C3A786
-:10140000AFAFD5F76BF17C0FE293B99CC8E72EAB79
-:10141000E10AB8BCACE0E927A6535D6DBEE1DE2C65
-:10142000E8573CBD753AAFAB35ECC13ADB194F3FDD
-:10143000CFEFDF60C837823FB0CDF7C274AC2BAFBF
-:101440008AE2F5095551A23EB46E7444DCA3183EFD
-:101450007E6A21C69FFB8D0CF3FC8F99C00EE6853A
-:10146000F6D9AD661EAF5A4DBC0E7C7DE6A9F5A837
-:101470003F3E8BF2E6A5509EB148453C5EB45BA86A
-:101480003EF4BE7DA529C807B35278DE2B7BCF443E
-:10149000279D2FFBE7C151FC7D7060FD308E73717D
-:1014A0007736F9E5D903189D27D1E801E1335D8F3F
-:1014B00082F081CE6330B713F36FB50E138D332BEB
-:1014C00085F3E3F5B63DEA89E30C6B7641BB2085F5
-:1014D000C7CDB7E2BC046FB0FF2CDCD0B307FBCFA5
-:1014E0001EC9FB486F59CE0BA27F1BFC510CEDC3EC
-:1014F000BC1FCDF1C63282B46FF3EEA26CD706BA30
-:10150000CEF1B8C03FB0B643C5FA0F7F3FACB718B5
-:10151000E8F42E457CDC66F60F26BEB2AD89C179B3
-:10152000AEB7DEB8EFF921E0047B327F3CA79736F7
-:101530003FE0D882747C579C3BD1E001387E8C70B0
-:10154000687075C3A3AB3FEF147E7B278E971BCAD1
-:101550005357FFC940798A6A09F424F4F77CC85CC0
-:101560003E95E8437950DCD2C2F9C69F58526C834D
-:10157000B6A071158F8FDB9588BC9866CF268AE759
-:10158000C7BEA744D8A38922FE1DAFCB4F4E6C9C8B
-:101590004EE7F826EAE2E25FA488BC651A4B0BCF5F
-:1015A00023AC15F1C6E5B68171E89F2A10E7CA8021
-:1015B0006F932AB371F121BDD0B08E459C53D4F8FE
-:1015C00070E469FB9D38DFC8D3EC0EF207B471BB41
-:1015D000F3131C2F97DFE37819D531ECE949D037A5
-:1015E0001E3132BF1A5AE7040E2A833087E2A4CB99
-:1015F000176C645FC61C9D43F5DE66A781A961EB8D
-:101600008F52A3991AA62FADC3E223FAB2A04F5D61
-:1016100054A41F902FE68971A5458CB73FBEEC08F6
-:10162000FA05F9B6E5E417C48D1B18311E6B532279
-:10163000FC833CE67163DCE802FAE27ED998D34A87
-:10164000841F302EB091CEA18EFB30F2FA847391BC
-:10165000FD037DD1A52FFCB1DCA7D12FFCA1F87330
-:10166000B823F197501E89BF244F24FE521644E23E
-:1016700027D51B898FF4E52322EEF75B9317D11F43
-:10168000F0C08488E733C18085F7B31E9D16F1FC56
-:10169000E08DB323FA4337DF16F1FC70FF9288FB2D
-:1016A000D9DB56FE207A8FAC5F1BF1BC9EDE37344F
-:1016B000FE34627C8DDE3EF8FBDFA437730AFF50F8
-:1016C000D03B51D859879BD7AD75196D8FE2797C86
-:1016D0003C3682FACE81E7E963D1FEAB5497E79BB3
-:1016E000C6685FFB97B24742BD940EA8356451BDF2
-:1016F0003CD5F5FDDC6088D867B73BB93F647772AD
-:101700003DFE6B133F2F950EFE26D929030BC5D93D
-:1017100016AC77648299AC8F639C5DE7E818A63AB3
-:10172000306F07FDC921BDAAE9D1DBCC6A6D07E89E
-:10173000975132D793A03FFB39619EF7A5078DDC07
-:10174000FFF019D1FF48B7305F6C1ED919CA433B6F
-:1017500058A284E700E2427A5CFD0E887570653617
-:101760009DC37A134140BF5975D17ED3AD9A9E5A1D
-:101770003E9CF4D4655BA4FF767969165D3F7BBB24
-:1017800099EA07CE8A3A470D0FFAF3D6DA396CEDAB
-:10179000FEF22D9B62D0EF3C2BCEFF6AD7270BFCCD
-:1017A0004D76CAC2FE59D6603E6C1118F138C07B26
-:1017B000E5918ED8DB18F99B9370DD555BAEDCFEAE
-:1017C0002AF4AB0DC1646E377CF4DEFC77F9B9EE18
-:1017D000F97F8BFCAE408593C7F91562FC5BA0B125
-:1017E000039E6E013A38B07D635219F2275CA7F36D
-:1017F00071338F3023CAF32C6F26D54D9C62AE33E4
-:101800007B01C4F94E95E09CCB3C46CC5BBD737B21
-:10181000650C3ED73D9E360E300CFA25EF3A7CC65D
-:1018200064CC1B4CE67513309F05AF7B16A53F8C2F
-:1018300076499BEF1DE6BD7406E83B9BB9685C6D7D
-:101840007C86E9F9303DB57BF9AA8F1260BEB547B9
-:101850000D948F58DB6CA678AD6BE57FED780AEEC2
-:10186000DF91DED10FEDF6FB2BFF3604F9E1D6CD8B
-:10187000325381DEAADD7BA7336C5FE5ECD22B31DE
-:10188000781FECEED6A7D058BE6CA63AE2F757BE4A
-:101890003C24DC8FAD74162EC7F7D8B8EB3BEF585D
-:1018A000FCD2F014AAF712FCB442F0D3DA178792F4
-:1018B000BFB536A69B9F787F2BAF1BD1D67146F064
-:1018C000E3CA97BE89F8CEC46EE023D5CCF7C5D461
-:1018D000A160EFDB2EE7D2771F8CDE7F75C2BC2DB7
-:1018E000573F89C5FE9E37FF4AF0B3B9D7072FCAC5
-:1018F000A26F4C687F5A3BEFB9A029211FE90E72F5
-:10190000B601C7BFED772F5EFA00F1D3FCF2D69F88
-:10191000E133D779FE7397967714F6C625F001F672
-:1019200086E28B2E16CDCF9308FF46C11DF92CFA07
-:101930009E874A7CED66C7711FA7B6D5407526B154
-:10194000B8091496AF8B950D9A51725B9CA0AF8528
-:101950009EF97FCEDB2AEAA83E20D21F2A38B43275
-:10196000C20FF2C05FAF7ED033DE5ACC2FE9FDA1AB
-:10197000F101C36253DCF7F84587A6F5EA17414049
-:10198000ED96C688AD21F835E8F4F37E2157F53899
-:1019900016E6FF03D1FCFC33980EF47B7F9ACAF560
-:1019A000B72D83F1F36952E7300BE8CB16E7A2C7F6
-:1019B0001F856B96417CDDD8AFA53335F9C47FDD3B
-:1019C0007ED7A111A4B7D8B7301BE243E43DF4742D
-:1019D0002BC0F3ECF9617227DE0F1CFE6B2CE67D49
-:1019E00077C4AB6F213D824765DAFF89523A4C8E4E
-:1019F0005EE2BB57510F029FCAA9DC1E581A797EBE
-:101A0000D1A2BA19C60F5176FBA8F0737F8D4E1E76
-:101A10004F561E7EBFBF09E871C9D0169B03E3AFC6
-:101A2000DEBB3B16DDFF0C93F703E4C35567DF1EF7
-:101A300063A7FCCD96FE180FD607F87730462ACC60
-:101A4000A7E4F584A37A332C2601CFE927503BB2D3
-:101A5000297F19F2597580AF13C7C642BEE18D12B6
-:101A6000F53B1B6BE371BCEADF37A7A13CBD9CC40F
-:101A7000E3CD97AE66F3F715A6E0F341A74310D385
-:101A80006FC0F8E46511D7745E95E9396DFE918DEC
-:101A900085B21DF82127B0F100C5514D6615E91A30
-:101AA000F51CE378688A22B9AF6E99CAD0EE77390F
-:101AB000984B82FB3BA2837FA4F36ECD6615F3ADFA
-:101AC00051F68D2C1EC6DF21F659870347E179298F
-:101AD000EDBA365F54D3D31873203F50DE374AD95E
-:101AE000C826DBC2F11C437876A4723EDA111D30A1
-:101AF000609E253898B16709AE109C8CE6D5E01C35
-:101B0000EEC7F3843B4CC1F3786E06E0B223FD8749
-:101B1000330E276B1AAA629E20CAEEA67544D955C9
-:101B2000974FEA0957752EF3A35DFFF943AC5B6E3F
-:101B3000518EABA3437D0BC8C08E814CC8F9CF1F1B
-:101B40002FC908EF836219177A7FC8AF363E5E3718
-:101B500089E2099F8CF12FB431F1B84E95D6A76078
-:101B60008A298FE301F7DBAD167EBFFB79E06F1B9F
-:101B7000F66DFC39579CDD3A4D2239E1F5B8421F2C
-:101B8000DC2705CEDF08A4FD2A702057055856BF74
-:101B9000B19FF87495A1E9A99170FFEE28AF2B15BC
-:101BA000E67BED43039D6BFDF38B51FE0AC0C7B08E
-:101BB0007D5B92DDBDC8877EFC47DE7BE8C974A4EF
-:101BC000FF3E49C53C6C973148DF37A96AFACC44DF
-:101BD000F50D8D1F53DDD39BA9DE4938CFB8C61A4A
-:101BE000DA8F1ECF36D27E74B6380F5EEFE4FAE39A
-:101BF000F2E921CFD684E17F492A972F16F40E40CF
-:101C0000B96912F2D9827E0AB47B85BFB4B7F5D622
-:101C10002C352C7F58C30EA423BE1F6287A8D5AED7
-:101C200077F9F9B9CAEC772C77B8C3F86F9190F7C8
-:101C300045A9224F96EA9D8DF0AE6AFDC414ABE231
-:101C40003999FAFE6857EAC19FB2F782976EB9D503
-:101C5000C951B51234E1F3D517F8F957A0731D9E99
-:101C60003778F99DC6118BE1FA5EC035D695FACE6C
-:101C70009AA9BE72AFD1938ECFD79CF93A17F55679
-:101C8000090201F07CDDBC6A00E20DF8BE281AE50D
-:101C90006B17233DA6C9670ECA27BC9F837C5F8054
-:101CA000FDE1A4877798DAF9F9D3BDFCFC29F03D72
-:101CB000C901F0BD1DFD861C3BC801BD3F94E47BFE
-:101CC00047BB81CEC9FA408F0FA67ED11CECEF68CE
-:101CD0002FB1937C635E3F0FE5347080C6A987D82F
-:101CE000044927314FB83FD9E88C25BA69FAF1B0D9
-:101CF00093093BA1C6E17903AB2C47C845983DE465
-:101D00007D612F4FFC2AF0F82FD176B8855D10FE4B
-:101D100014F3E6939EBF57D8AAB5AF4F98B91DD616
-:101D2000B9F684DC5D3F8EFE6B40F0C901E1CFA2C5
-:101D30009D5013783D0E5E1FBD99D7D58E71AF298A
-:101D4000C6B3CFE3CA371EC47682A7BE18CF3E4FB4
-:101D50005AD07E909F81E6E7D91B0EDC948DFBDE86
-:101D60005D67CD0CF75D1AFE1AFCE34B8087FB5BC9
-:101D700000FFBDD825580EF11F58EC74E6EC79BF72
-:101D80004BD2F4C7A90AE4C7CE0639D40740AA80CB
-:101D9000C1B1FFDBD4938FFBA09F95E67E3E15FD7E
-:101DA000ED742FB55D27FF9A8CB660EF69EE47356D
-:101DB00098DCD9C83F0D0323BF1FA0B54FA61A89D1
-:101DC0000E057D7CBFEB482ACF6F0EF1B1C7908F17
-:101DD000AA1A64BB1FE87EA941769BC01F3AEFF6A2
-:101DE00026E3D99C0BCC77CB44B4F3228ED4BEF738
-:101DF0007217FA2960A7EEFE65EFFB0FAB99F65B51
-:101E00006340BE5AD624B1FF001C2C7F26F2F9D5C0
-:101E1000DAF76A1AB71CC6EF88AD7C4E771FFD153E
-:101E2000FA0E46A41F732455F827592C0BFD13E016
-:101E300023D20F46851D3103DFAE48F7EE437BFC0E
-:101E4000B2F8BE02E85192C77D4E615744FD417021
-:101E500007AF2B1EBECD2F1BE0FD098A5F467BC559
-:101E6000A0C57D87716E6F197D87C9E73E8DFB3EEA
-:101E7000CB853E5CAEF9697EBE3F026637C24FAB92
-:101E800016AB1FCFFCB5B1B8FE6D12C5CBABB645D6
-:101E9000EEA7548BF5AFDE7CF2309ABCCA7ADD7DBA
-:101EA000B1FE6ADDFAB57DF3CF5323EBBFAE773FCA
-:101EB000E42F46EE37BC2DC6D1EE9BD2B87EAC8265
-:101EC0006520DD56FB65BF9FFB7936FC5ED09D62C9
-:101ED0005D770AFAD33AE1B9CA6D923F803CFE7849
-:101EE000649DE95DF58BCB90AE7A3E5929D6BD7CD9
-:101EF000BB91FC55FCFE0FCA9D9E3F568AF5AFD4A0
-:101F0000ADBFCA2BE9E0E37E744FF8EA6F413A5760
-:101F10006E37B2DEE0D3E8B552E3EB3EE0D5E0D475
-:101F2000E0FEA1F0F64F13F9AD116C04D1A93CE12C
-:101F3000BAE8A4F773771D1E41DF5BBB7C6420C544
-:101F4000FB1A1FE8DF2F137EF2D4CDDC6FBCD45810
-:101F50006C1D89F14C9BC125A9149FC58E04BCE45E
-:101F600037CBAC02FA5D4D599BF0FB8379270AE62B
-:101F700060FC9F7FC240E7EFF61C29A07DE7FCA331
-:101F80008312B228CFEDA2EFE3C038645FBBDAF270
-:101F900036E1F984AEB692021C5782E7D00FC8131F
-:101FA00076A2A62DCF1A7EFE7C4C1A8FEFD73B3F30
-:101FB000FD39FAE9537719E99CC55463F04DACDB60
-:101FC000DA7344A17DF2D527963C1485F47D51A2A5
-:101FD0007DF2C3ED6B1317229F3519EDB8EFDDD5F8
-:101FE000F4E30378DFB75DA2EF5E54379766EF80C6
-:101FF0007EDE967C57F8F9B33C874AF0B1542BC586
-:10200000CF53FB19C96E5E4CB3FE16FD9F95EE2DA6
-:1020100024DF17F7EF3151DDDE0E89A1293BEC3CBF
-:10202000F80AE2E3E2AB274DE88417379C34757C6D
-:102030008F3F70C92FB300C5CD1B4D18C7546ED14B
-:10204000FA1D26A49347F84755CF7D4CFD95E8CF60
-:10205000C37C2B9F91A97EF760F36B26E4E7AAED82
-:10206000124BC90CBBBF598AF85EC312C6F960890E
-:10207000D03FAB987F7D1A3CB76A23AF5B608F4639
-:10208000D6016BFCBD42F0F7AAEDB3E8FB533DBEB1
-:102090005B8871E30DF81CE7EF659B23EFAF107CC5
-:1020A000BD42C7D73F4913FA67381B8E7CFD75A127
-:1020B0001A9703D7BF3EB972406FE7ECDB84BDD6F9
-:1020C000ECE5E58081EC8DFEB9CEC62B046775DBAF
-:1020D0006513FAA7654D5F10FE2B9A5AA97EE46638
-:1020E000E65D8DF8BAB9C96A47B9AEE8E07A685AD0
-:1020F00093D9EF97F07E3DD53977B5F0BA49DF7EB9
-:1021000089FC1C4D8F69DF775C26F0B80C14787A57
-:102110001EFABB3C6EAE1271F28A615B0EE33E7B2F
-:1021200095B8BFFAE8C158F40FA7B12F6E47FAC0AF
-:102130007C0CE763CF44E27DBAD08BD3B773BDA8E4
-:10214000B76B5DA9D933298F09712AC2B57A7B246F
-:10215000BEAB74F1F963693C3FF6820EDF15416650
-:10216000CD413854D9E5A7A7DB159CF7482ED85B9D
-:10217000B4936AD6F77E87F14DE1676BFD99E21C57
-:1021800078BD7DA32D3C6E8E4AE7FEC2CAF1B20F28
-:10219000E9D51D6F0C3A98AB1A42F106C419CD6906
-:1021A000493CEEC082923732649698188A371E7185
-:1021B0006EAAC8837EF5762EF79DE3603C3C7FAD2A
-:1021C00030F247ABB79BE99C6235D09FE28A267E0E
-:1021D0009EC2D3249522DDC15F3F9A86FBB19852FF
-:1021E0008575CF6AE47C3FABE40BE297A383F87A72
-:1021F0002F2B6A4A6FFEBBE6B7E3F93035CC7FAFD1
-:102200000239C5E7AB9A783D52C3816FFA67A29E47
-:102210006BFEAFFE8BA1FD5AD845CD2F0C825F38E7
-:1022200090FB45F4BDC9BB857C2DB3F37DBABB855E
-:10223000FD61521DF17995B1FE503CFA593B78BDD4
-:1022400000DB871F8503FDF8F64B75F1B0EECE97E6
-:1022500024AA87C3F7F17B949D4BEA3F41BFFBEB78
-:102260001D16F237EF06BF654A5E4FB9D4E45BFB3B
-:102270006E560D7B88FCCF87581DB595829F3B1B02
-:102280006BE9FBA09ABF42EF0FECE98F540ABEAF97
-:10229000D4F15F547A24DFD5BC1D4D7E63D751D96C
-:1022A0008EFB3180AFDFA485E345F8210D07A288BE
-:1022B000AE5D276D6447FE2CF8EDA2C83FD78C9326
-:1022C000090F86F1BCCD6E796D20D211F18EF5F734
-:1022D0002FB7BC36829FFBF613FE576D9323BE0FBC
-:1022E0005B591FF9FDD79AB76FA3EF0855EFEF863B
-:1022F0006B88293104575F7220493C8E34489171B4
-:1023000064F53ED9135E7706EBB903F551BA900731
-:10231000A6049331FF35009D0680AFA689D3D5D0A2
-:10232000CC5B98FF169E2731D2FC3DEE17F956E3A1
-:10233000FDAF33AD7CFFFAAAAF02FBF70F94A9AE55
-:10234000F3FEB7570E0DD7A30CE104BA561B83C991
-:10235000146F9E34107CD5272F270FB2A15EDA525E
-:1023600082DF0F9D2EF4DFE181D6E5C8CF3E9C379A
-:102370002534CECB69BC7E8FE17A9DE86DFC928FCF
-:102380002BD6FB109B2DE26ACE4F39697CBD108F96
-:102390008C4BEF251EB95EBF13ECC3A98512D63353
-:1023A000293E8C87F7BCC7F5424DF3B28F90DFAB67
-:1023B000DF37539DD7FD2DCB8652BDAFD77B03FAB8
-:1023C0001B5FB7ACB881F283D24304970FE173A2CD
-:1023D0005F732619EB522B9BCF2493DDDD3B7A9361
-:1023E0002F06FD97BCE9781DFC09E23FF06B88FFE2
-:1023F000F6B415687E8C15C7AD3CAA78103F95479A
-:102400000B8E57A07F71A2A800D5B974A280FC984A
-:102410007CF4636C21BFA65B4FA6733FA6AB358AE5
-:10242000F20B121BC8F9870D8AE09FD50DAF93BD43
-:102430005FDD2847D42F6AEFDD99AED038CB34FE6C
-:10244000A997DCC41FBB78BBBA710FAD6F95B19E65
-:10245000E85DB3DDC8EFEFE0ADF67D581F8BF721E7
-:102460003E8EE325A0C334933F03F3D3C732B99F15
-:10247000AFA7C7E7E93CFF71ECAC7700F2CBB14204
-:10248000EF507B2F76C2C78A785C2B097C37F073BC
-:1024900053FAE73E4B97C4774222CFB76AEDA9744F
-:1024A000AE3FA7997AFF2EE06FD2B57309EC3143A6
-:1024B0000146C546FB06E1D7A7867DD761CECD464E
-:1024C000F2174E31FBEB58EF3843D3B3E3B87DD569
-:1024D000E7CBE789F73C9B55BE5FA43B3F334F3BBF
-:1024E000DFA43BEF364FF83BF374FECED3E9C28F47
-:1024F0001FC286A01EAC17E7EFD60E8FF287E7B398
-:10250000F4ED61B12F82E787B0AD19FE2EE57D8E27
-:10251000B59E7D85EADDCE46B1813CAF47F9EFCA75
-:102520003EF2DF35DD72393782CF34BA5C12DF8399
-:10253000D1D365B7A6AFC4BE5DB4D8B7F31BBDBBDE
-:10254000519E2B2D174DBCEE3068427D56339CFBBF
-:102550004D974A25DA6F0738FB9BC3F4FBA5541E41
-:102560007FDD7F8B4479D7567C1EE3AC7A89EABC49
-:102570002B03ED26E4A7210D8B1F26B9F5B1D32C33
-:10258000ECBB1A332DDC4E76D34F5B77B71D8BF740
-:10259000717D9C482D3E8F767186B083FA735143CE
-:1025A000597B593AC033DF2DB9B01EA02F3ACF5E08
-:1025B00030EA7544C3F5D2BB33DDFB4E3ACA79FB32
-:1025C000E55B308F7A6CF867FDD18E56F5C1C71F79
-:1025D0000B3CEBBF2BE31AAAD6E2F7556A9DDE0E41
-:1025E000D29F866F6347301CA7E3376B25A4132364
-:1025F000FEEF4B7E3E13E37E96CEBF770FB8A77DEE
-:102600009755E9BC4EEB98D19F41798A9CEBDBF75B
-:10261000AAD9F7462EEAB3CED6A3B9A630BA5E5CE5
-:102620000B7A00ED4AF3C164D516CE7706E237493E
-:10263000D2F84F11F632920F2F221FE6607B2676DA
-:1026400010EAE35DA76207E3787B79DBCDAF4DFC51
-:102650007BF6101F0D9917130EDFC304DFA57A3E1A
-:102660000E631D43E68C0CBF5FDB171F5B33888F47
-:102670003B22F8585B6F3D7ECF07E38016337DCF5A
-:1026800007F3D78E3039199AC1F5CF58F1FD9EF175
-:10269000CC47DF391C2BBEE3335E6101251EF7CD2D
-:1026A0000232DFF7E5E72DC6087E1EAB045AB18E75
-:1026B00062BCD8E799C0DAE9B9292C48AD9BD9E9C1
-:1026C0001C451173513BCE12988EEE544E7D3DD574
-:1026D00025069215C7798B38AFD10BDD42EB57E851
-:1026E000BB3DC49F329ED7E9FDBB2FB333B8DCD3CB
-:1026F000C74590BE9718E5B9F07B6D38C9448595FC
-:10270000637DD3648559A201DE5D870C24CF2D1D26
-:10271000AA1FEB535D09E2BDCF19D5E18E75737920
-:10272000459383F518DA7AF5789800E3619E6DACED
-:10273000029128E13140F3DDC8F8399242A652FDFA
-:10274000736946A6D0F7418AA38A218E427D6FB075
-:10275000F8081FD33354BA8FFB25B130CE848D12C5
-:102760007B0FF73FB2F87AB5F1270023E0F9C2E911
-:1027700019DC9E614AF5BD78BE8F124B05CD2576DA
-:10278000FE9DA364FACED1F5E2B52B997FEF32F628
-:10279000CE60E7CF0A42FB492EFCEE516CE83B9B32
-:1027A0002EEDDF830844FE7B1077642CF911F2A331
-:1027B00056AFC7BCFCDF7DD0D7EB85D5E7B10B6149
-:1027C000E7B0B5BA926DFED92A9EF35B9068A1730B
-:1027D000BF7996FEF968C7063ABD34FEFBD2F6C152
-:1027E0003498E21FED8909F1BB95B9C721BE437545
-:1027F00083FC3B50DDE7AE92199D57B49A797DE595
-:1028000063201FF81D26902E15EB68D883C5548FC2
-:10281000B9DE6171E1790933C26D0DC15D6B11DF04
-:1028200005B5F07D717D3D68ADCD40DF1DAD65D155
-:10283000740E3D29DABB2E03E0BA2FA688CE776747
-:10284000EF9CE444BF317CFD93B4F51B7AD647C2BC
-:102850007A1FC9E8A51E515BA7F6EF76D805FEB42E
-:1028600075DBB5734A6E25E29C92868FC7A2F9BAD2
-:102870008DB8F39F45EFAAA837F4EBFDFFDC29BC28
-:1028800016A064000000000000000000000000002E
-:102890001F8B080000000000000BB3D36660F851E6
-:1028A0008FC0C19A0C0C5DD2A862B4C41D120C0C6E
-:1028B0009780F80B106702EDF5926460F006E26D08
-:1028C00040BC1D88C5A518180280381088FB80FC04
-:1028D0007E204E07E224A81BB30519187281381F09
-:1028E000880B815848808141588078FB8B151918D6
-:1028F0005EAB22F85A6A0C0CC91AF4F3FF60C3816C
-:10290000B6F4B5EF16D0BEE56E08BE0490BDC20D9C
-:1029100055CD4A37FC66AC42935F8DC65F83477FD7
-:10292000810D2A7FAB292A7FAF3903C3072435DB0A
-:102930004CF1BB051D2B00FDA788274C9730A2F258
-:102940002732A1F2F9A17C00BE1E313CA803000091
-:1029500000000000000000001F8B080000000000C5
-:10296000000BED7D0D7854D599F0B93F736726992A
-:1029700099DC24433260126E7ED0A001879860B04B
-:10298000586E20E147A30E082CB440262888166D07
-:10299000C49FC6DD500609BF0921E14F70D11D104B
-:1029A0005DEA63FBC5565B75BB7682D646AB356880
-:1029B000D787767765A015BFBA761BD96D976EBBA2
-:1029C000F57BDFF79CCBCCBD9900FEECB7BBDFF30A
-:1029D000C5C7E770EE3D3FEF79CFFB7FDE73C725BC
-:1029E000FB59701A631FE31F9413731963B5A9B2DF
-:1029F000C5C362D9398CE576488CD530B6B25D89CD
-:102A0000CF827F1676B4BC82F5E56D6EC35DCA5881
-:102A1000FF036E7F0DD44F6F57C26EE8DAA8F8A897
-:102A2000BEACCB15761BF07CEB472FE7E3FB8D525A
-:102A300098419DB1BB199BCCD81A0FFC13EACB2A45
-:102A4000921DF8FEDD2D523886AF99E99B04EF6F99
-:102A500065FC7DF3038AC664A8EFBBAD894D64ECC9
-:102A6000961E98C5430DD9C7BC3D63058C45F82318
-:102A7000D6B205DE57A6DE4758D7470AF46B8E3923
-:102A80009EEF9BF53E0BE07B2DF51CD6730CFF31C2
-:102A900085B14B993F783A1BFE1D66E18F15281BC7
-:102AA000F2191B9DC297B3640CA01FC5D85CC65C0D
-:102AB000AC1CC6A9BDCCC5CA607D161EDB381E97EE
-:102AC000354984C7653E46F577E74AF1074BA91FAC
-:102AD0009B5E0D253C2FC88332C8CC4228231E960E
-:102AE000C806F8E7B65DF61EAE7F034E359ADA27C4
-:102AF00002F07E018BBA18C0F7672C46E56216A774
-:102B0000F2CB2C41702C6543252AD4EF52129B182E
-:102B1000CC130E45A7E3FEFEAEFED8BB12BCBFBF72
-:102B20005AAA9D0225F3E5D1BA2FB43E6B7E954596
-:102B3000AEC37118935D113F63E3AD751E66B18A34
-:102B400020637A8F8FD3CB61D6CFA03EBE41D04BCE
-:102B5000E3FB7208D6DDF33C0B633D049B3905EAC9
-:102B6000A1AEACF806A8F73C1EAB47BC1C6B01CC71
-:102B700043FF638D6E295A05A54B7745A00CA98CA0
-:102B80002980A7FA86F59202EDE646F938E34D4D25
-:102B9000665742FD704C52C573ECAFEB314987FA72
-:102BA00078A83F28E17BDDC5609C86865C57B20A29
-:102BB000F1DD334687B2E2B0969001BFF5A64ECF65
-:102BC000195B4474355ED0DA5C93F79B7B38CFCFCA
-:102BD000E83DFBD3C7D67BC0EF25457CDF8E1D2E9D
-:102BE000CB417859D4DEBF4865314F5E0ACF3BD721
-:102BF000C10B770ABFBB0E976D45BC1DEB53C3825B
-:102C0000946DE3C3B8BD0DF0FE4C951C560CE4B3B7
-:102C1000220E7F85EED77DA97176AE83F697A5E06B
-:102C20006854A6F6133E4C46FC38B706DA57A5DAC8
-:102C30003F81ED018E3D080FF55B73D48BF3441893
-:102C4000CD33123DBCB04EA77E83621DD7FCEF3062
-:102C5000EDD3DC861689CF2BE06BB0C36795167C6D
-:102C6000238D7F4CC0658D6FCDF7C4BA10958D4A0A
-:102C7000D523F7E2BA8E687C5DF38DC77723FE8E8D
-:102C800078C231A83F79DDDF8CB91786B862FAF3D4
-:102C9000973FC370BEE50FDF8EEB7A2E8BD6F5D44F
-:102CA00087675EBB910D9FF72D81879F9E9B3F4459
-:102CB000756BFEB9A63446023AAB34A5840BE8E541
-:102CC00058FD571EBED7C07ABF89F2A4D23C664ACF
-:102CD000504E846168BF99FAA78F419E554277E4B0
-:102CE000C7490D520BB67BE2C687BE741F3CFAA9DA
-:102CF0008BC37DC55F72B82FBB7EED9308EF653740
-:102D0000AEFDF93350BF028520F0DDA537ED5FF34E
-:102D100077F0CF6F2CFCCBE57B18C9855836C09176
-:102D20006B4A0CF777D9F7DD36B972EC793FC99564
-:102D300042B33486FCB7AC4F22F9DCDFE866417C55
-:102D4000FF3377DC8DFCF5806452FB67DD71940FF7
-:102D5000C75C8CA13C5E76DC1B477E61AB9691BC68
-:102D60008E58F2DACC5F7A2F8CF76E8325CF399D9F
-:102D7000D27B58DFBBE62FB65F0DFDCF98AE308A11
-:102D80004D4B5E38F1FCAEC06FA4BE9CE860999AD2
-:102D9000748533D043739B6293DBF50D2789AE9620
-:102DA00041C9D2F874AEE0B3650DBF10FCA9935CC5
-:102DB00072C2F3466D617126BA3B25E0490A7A7BFF
-:102DC00017F7FB32840F7A21DD742971254D4EC32C
-:102DD0009F2B3281EA3164E95BB6D8E1B4E4764BEB
-:102DE0002CDBA6AF40FEFE0BCACDE6B67CDBF3B90A
-:102DF00039AC76EAA793C37F20399C94081ED0BFD4
-:102E0000B4FF91B81447B968EDCF1D627F22158CCD
-:102E1000D6F3AB03523C06FBFBAB23627DFBA4B8AD
-:102E20002211BD9AA73D382ECC599EDAFFDBC5FE94
-:102E3000A7F68FE3C7C2574ACFE56E4A02082DBEF8
-:102E40004809CA6B8B7F2CFCF6EFF95109EE5F61E4
-:102E50005B69771DC2794021FEFDB0FE6431EEDB77
-:102E6000BB2EC02BF48F1C7E2CC07C29F85B841CED
-:102E7000FCA003E8059E4B0867651A9C026E17D6F6
-:102E8000A1DDED0D521FF2E92FC5BC56BF1F6D9994
-:102E90003113F173478FC4103FB71FE95DF6E7B0F8
-:102EA000FED5F1EC304EF1ABC6E2C02500CF8A1E54
-:102EB000FB7E9EDA727300E9E6C3BEFC021CE7F6F5
-:102EC000A9090DE15C9D78553380CE6699BD5A32D3
-:102ED000035D7DD8B72180ED3F547B6EBC06E7D9FA
-:102EE000A784D7C3F8AB8F94CE34399D12FDAE16AC
-:102EF000F83DA9F6CC1C03F0B57CA39CE4C17B7D16
-:102F0000CAEC7806F9F97549213A58DDE696719DC3
-:102F100023D1CB871D2E96C079D404E173A4761FEC
-:102F2000F4B5D0FBFE070A6F40FBEDF67617C98BB0
-:102F3000DBDBDC444FAB1BA4389352FCB642C0BB76
-:102F40007AB742EF4F9A12C90F6BBF6E17F476F241
-:102F5000F055AFA0BE3F03F207E5EE8C8D3FD42EB7
-:102F6000013CACD8C2E5D1C9DDB94BEF413922F4FF
-:102F7000E51D62DCDBE28A8D3F56B667DBF623DABD
-:102F8000956FAB9F3E927F631DD2759742FAF39681
-:102F90008D8F6921924F767B13396C5241CABE3CAA
-:102FA000C186165C23A5E8C9A29F5BDBC0DE0C0CC2
-:102FB000B7375B8E48648F5EB49DD90676E6C4E170
-:102FC00076A6254722689F95A7E4882537EE52A26A
-:102FD000638300C7AF5DD1CBF2CB496E3C20D522D5
-:102FE0009DE8BF45BB92C5945A946F172B2F68B1CB
-:102FF000161FC1DF7B1D405719E87506D215CC336B
-:10300000B3A73F233DCF900C1A2F4537B704886FE5
-:10301000715080A3D96376219C97C0C4DE6A2A9937
-:1030200092C74B15EA9B1166A087536BA5F8A15276
-:10303000DECE87F214E0BA069E37775D1EDF26A14A
-:103040005D087FA83FDBB8DD0DED4C7F1E3D3725C9
-:10305000288BDA4B5FC6FDB904048056CDDBE33C18
-:103060006067114AA07DC25D4D5D6301288BA19F01
-:10307000CCFBD37B6C1720391EA7F5E2F8384E85C0
-:10308000125F8372C6A2E36542EE805CAD5481BEDE
-:103090009A595618F566735BF979ED971BC276F964
-:1030A00071539D5D0FCC35EDF2FFE6D997D8DA2F3D
-:1030B0008894DBDEFFD9A22B6CEF1747AFB2D5BFE8
-:1030C000BCEA0BB6F64B5B67D8FDA49FE6D27AD676
-:1030D00008BE1C09EED785BCFC89C33EB5CAA6EB69
-:1030E00013356FC33EB175EEF0E3509C98C316F5EF
-:1030F000A5C9159F2C113E7F036CC2FD833F7D4CFB
-:10310000780CF1799BFEC2DD9A89EE34D10FCD2582
-:10311000B4979CED4F2C8679D2FAFD9B24111D9E0D
-:10312000EBC73C3DBF04905B80937300F577B264BE
-:1031300009EE9B3BD7A0F777C9C902ACFF860DED1E
-:10314000CDC7FDF5258B917F9A55F69C9483FDC2E2
-:103150001E37CC07D6106B03FA6869FBD171B4E354
-:103160002423C89660DDE34B207FB30ED787490B3D
-:10317000EFC087BDA1E88712C021B5F7FF5EC2F797
-:10318000DF6706EA61962CCA45FF11A74AE7C3A686
-:1031900019AC15F175A2D18E37AF58C7CF2599DA82
-:1031A0003DC7CCDF221F9D9474BE3E01EF36C93C63
-:1031B0008BF35970BF9BAB6BECD3C1ADC8B508F7AF
-:1031C0008F08EE0DAD2C99AD8C0CF715CC74CBA3FC
-:1031D00086C373969959999ECF0276CDF4FC7237C7
-:1031E000AB447BF58494155E5F8AE5D03F7E0DF895
-:1031F0002AF60D5FF87163385D4C957369FE666160
-:10320000EF16B64B896CB44F9987EC57D6F390E91B
-:1032100041B926445C4B9B7412D7CF3A1ACDA427F0
-:10322000B55E66482CBDDDB97D6F73537B4BDE58B0
-:1032300072CBC2A725572CF965E1D539FE48720635
-:10324000C753F310FEE824399D4E74C0C70484C7E9
-:10325000ACC6FDB3F60DDCC898A77AE47DB3E414E0
-:10326000B463E8FF8FB45F8027B2EB5C6146787A85
-:103270003738B4F42958F7401BD7D7EF1631B20FBF
-:10328000CFB45D359083F8F1782A103F857C2A56BB
-:10329000181C5A87F2D5A726FA11AE42A1BFBC8CE2
-:1032A000EBAF4266ECB81AFDFBF6934BB09DB53F11
-:1032B000B9627F9A617FD01F69F60D15A39DE44620
-:1032C000BD06EDDC2077512E17B6BFFF1FA8170BE8
-:1032D0001D7A112161E9706455EDB8DA481FFFA32A
-:1032E0008D685F5AE35287F4FD0F6A2711BF85EDA1
-:1032F0009BEF5602B6F1A58F110F426EA3D9756EE2
-:103300009E52B457E5843B90A20B275C56BF91E8D0
-:1033100084A5CF536EAB933DE1ACBBC39A4D3EBF8A
-:10332000FBC7F29C56DF79E8CD399E93BE9D7C2089
-:10333000F0F029E87413A7532E172CBEFDCFA2D3AB
-:10334000A8B5AFB1DC3B8EA07EEDD2C2B30CB413F6
-:10335000867EC8ED04B77108E92C266555C2FB6866
-:10336000874A76A36557F4AFFDEB2D65F0FC44ADBD
-:103370004C7EC489F59CEEF73CC0ED514B6F478500
-:10338000DE46BB00F10A76C3809B971E1CC7BFFEBA
-:10339000E65209E0F61843FD6E6CDF6690BD9A5365
-:1033A00017D71BA18C571CF28C3352722919CBCF23
-:1033B0005B0EFBF5AD5C635984ECEBE8E8B9FED439
-:1033C000FB1FCB5C3F4D2B6179B361BCE45639FCEC
-:1033D00020F44FBAEC7ACC2AD7285C5F26BDAC0427
-:1033E000FDE091DA0D29965ED535DA97F903C771BC
-:1033F0009F46DA07D8019DE298E7E890E31DE6A131
-:10340000F1937EBB1E3A29F49005FF27D0AB0B8BBE
-:10341000813EF64A99E1FE488C177D0E0080FD8EB4
-:10342000AACCCCD4CEB9EE7F10FD12B24AF3EDA8EF
-:10343000D8391BF73B1653C2E9FB61957FA170FD9C
-:103440009933B721B711DAB1F599DBE589768FDDCC
-:1034500097B508FD2B409D8AF19A504C9F371BE38E
-:103460009153F326A18FFD63D43F30EFEEC819BD11
-:10347000C5F789F051105246C6C79BB2CCF7D1C1EF
-:10348000B77BC05D43F999943C147F6989B933F2E5
-:10349000B125A79CF2C8A9E724D3646DD5C3E58AFA
-:1034A00035EE27D567201FB2945129BBFD9C3EBB4A
-:1034B000587A1C410E94C82CDA97C13FBD5AE17866
-:1034C000EA8FF138856ACAA4B7662A4D4C023C6D72
-:1034D0000832920779B8D7C8B70D2C0E2860F92C9E
-:1034E0003CE0437912945982FC56A71F6836A11F0D
-:1034F00018E4A0317D54597F213C0FCE5F49E70C81
-:103500002CC2E5AD0EFF713E32495FB8055EA3B136
-:103510004914E7CC6BB2CB7137FA81201FF506C78F
-:10352000F3F933E9BCC1CDD29EC33AAE52FCC1D34C
-:1035300060DAB36A5683FC59BDFFAA5D8B61FC9AC1
-:10354000476E7E1BCBC907EFC9FF1294758FEFBA88
-:1035500019CB92D7A26333C553AD123885C9750014
-:103560009F8F19EE9C91DB19EB9508DAD5B08F1D72
-:10357000480FC9587916D2F72A85F37FFF022D80AC
-:10358000F119750B97ABEA7C401ED13FF7D39B53E3
-:10359000FE34F915AAF093947685E20849BD8CE2D1
-:1035A0002D87B6C81A96206763388F357FAF88534A
-:1035B000778A78AB13BEDE92A162948327D67F44CC
-:1035C000F6A1A2678567C37C5D7E5642708878410C
-:1035D000B3D8BFE4DA7A4F7ABC48117E4EC7D139EE
-:1035E0000306D2C18012F61AC4371A8E1BDD329D33
-:1035F00061FC65961E66684F740ABF47F1990CF727
-:10360000355B6733D1AF85575A08FB57B17002FB62
-:10361000B7F7236E61BDE6EDC8073FB896DB2127FB
-:103620004AED721B48A80BF694CD2A5AAF226D368C
-:1036300005275D8534FF7BA540C8554EAF6FD44E3E
-:10364000796C1BD0C1736EF31E65D427E023875CB1
-:10365000FF01B009EEDBA3925D9E5BE541271FB53C
-:10366000496417AA265FE74CE5C346D4931BC16E95
-:103670002C3486F3CBC6D719D98D1B81FF62A5994F
-:10368000F8A75A421971B1FC93D79E2B611CE3B382
-:10369000F2CF5F2AE29C4EF00FD05902ED984725F9
-:1036A000A3730AACEF3BFB1A7F3C055E3F7B604592
-:1036B000F635507E2FBEF1FA6B60FEDB1FDF938D77
-:1036C000FBFCE8ABC04FE7F1E32D7E6A461BF63CFE
-:1036D000713663AD9D9F8CF515C44F6F295C7FF5E6
-:1036E0002FF8DD1B57FF7F7E3A1F3FBDAD007D4E9B
-:1036F000FBD3D9E2E879E45B7311D3D0DE823626BE
-:10370000D27934682F7D6A16E17B9D8BCB31BFCB9C
-:10371000CBED8E107FEF1CEF6FD44F1E3F5850FE45
-:10372000D9F9749DCFFCE8F3E077903B246F4E8C81
-:10373000B3F37DA78BD3DDAF5C9F787DEF7CE17326
-:10374000581FD8F564DF5DA73203FD80892F7848C4
-:1037500058BC3A6EE311648969F03C94C7DFBBF34F
-:10376000485EC6D18E19522AA9BFC9B81DDF54B30D
-:10377000F9083F9718AC5804FEF21CF817DA23D763
-:10378000F9B85F01E3B0108CBFDA1B2D5647D17832
-:10379000E45FBEFAFCBE20CA97D73D66093E674982
-:1037A0003517CF072CBB63647E57D9E9343FEB69EB
-:1037B0008D111CA72ED5285E89622C00F5ADA5972A
-:1037C000529C928563C725AC8FD219CA71251859AE
-:1037D0004C76489BDB9805F5AD6040C58244B72424
-:1037E0003795F6DE5000E500D825F85E8DCDF568FA
-:1037F000E8BF8C923108CDDC6D1F91DF7DA298CBA4
-:10380000DB8E298CCE69061EF8B7A532DA3BED6E49
-:103810003AB700BB91F8352AE44632383DD4827E6F
-:1038200046911696A0BE29F68BE35FE3F2C4F44CF2
-:103830004E8F8FF078474B88FBBB4EBB6FF3D72F73
-:103840007BD3C0F17EF85AD7E550BEFEE4CF5FBF10
-:103850001CDEBDF1ADD76A30EEEDAED36C714737EB
-:1038600033DE447B0B7CA68486F2397672096E6661
-:10387000CAAF9362889F688D3F8EEB45DE46FC247D
-:10388000A728FC7C11FE42005F40C0D71D3C554577
-:10389000F3C4DEFF8F4CF29EFE260B3D02ED36E7B1
-:1038A000DD1F4739929A6F12C9A728C827F423A3AE
-:1038B000BE9E256B683E7FF841ECF347D8D5C9A979
-:1038C000F3C2435BE6B5209EE72EF0E84867EED8EA
-:1038D000E6BB91CE9DEB3CE37BF0520CCDD9E607E5
-:1038E0003E715768A697EC5F7698F64334B1E0D600
-:1038F000418160DC01FA2F5BC132F437A03FAE1387
-:10390000E419DADB563F206313D77BC637FD528AB2
-:10391000F78B7885D5EFA69844E7043795031B9479
-:103920000FC7D3069FFC93AFE1B94B4CD1154E079F
-:10393000A18A34BCE19F3D6EC6E9E2B27D76BD0B43
-:10394000F32F2CC5F73185E8C5C92FE3E3F6F61B45
-:103950007CE73FD71FBE9F1CCF1305BF59FD2DF835
-:10396000085E29537CDD7E2E73539DBD3E77183E45
-:10397000CE0FD774D57E6ED3E0B38F3733687F3FD9
-:10398000BBC85EDF80F19B4FB26E07DF3D3DC6FCDA
-:103990008EFA19FC7A4BEEBEEF89FC2D8DA38619A9
-:1039A0008ED3BF60EFFC794007853AB73B0AE72F1B
-:1039B0006CC8AD4139C5449E4966FBA350E87BA560
-:1039C000FD252507FD5193B74F2E796B460E9E17A7
-:1039D000D7313A4F8FAAF7C4728C943DD2AF966715
-:1039E000219E3F7F7BE46E6F7ADE4DCA1E79E055E3
-:1039F000A326833DA2DE239930CEAC25608F54A54B
-:103A0000DB23AD12CAA0EC25608F90DD117D0FF194
-:103A100035925DF263CBBEF767B6ABFFA0723D0B8C
-:103A20007AE69F3E8B9E19E735FF45FD1CEC8169C8
-:103A300025C6CA48063AFC40E5F10E4B7F36061310
-:103A40000A9E9D83DE545DF0FCDABAE44B288E3B7F
-:103A5000F49D415C37ACC7E5AAFDF4EB39A372785D
-:103A600026AA3C0F66A47EDF1AC15FF16A5E61B7C9
-:103A7000D8F7BB7FC13BBA8CFE0BF831E8BF247D81
-:103A800065DB302E7826A652BC4E9DBF72F75CA433
-:103A900027B0B3393D9FDFBEBE7648B6F1F1B4B36F
-:103AA0005936BEAF67F673BA191EFB395DA36E3F78
-:103AB000A79B15B29FD3CD31ECE774D757DACFE986
-:103AC0009CF6FDCCD1AEFF9EF67DA891113F5DC066
-:103AD000BE077EBA09E969247EBA2EDFB83F92613B
-:103AE000BFAB356EA7AEF6461620DD4D33B85D1779
-:103AF0008DADA77CC0BC28C89B528A1B52DCCB8AE8
-:103B00006B59712F2B2FD08A6739E35756DCCB8A3C
-:103B10006349311EB76AF6445720BCCDED27659442
-:103B200023FA73300F3282758E372C3EC7E5414B36
-:103B30007BE6B89C33FE3662BB4FC9579F837E58E5
-:103B40008FEBB5F403F0F9839F85CF416E6DC3F120
-:103B5000FE05F97D14C9936EDABF0AC035DAE9B003
-:103B60000F1AC6E9179CDE8FF138F5B89BF8F6629C
-:103B7000FD5F4C749061D3A2E083633C2B1A2B252C
-:103B8000FD62F18DC5274EFF78187FFC57F3CF45B6
-:103B9000FAC7C03FDF739D471F017F3C8FF89E56D9
-:103BA000C9F1EBE4078BFE8124125235EE773481A4
-:103BB000ED2D7A672F864D8473A2F06B4E8CD6C89C
-:103BC000BF38F1FCBFF373D8E73DE171628DF87E39
-:103BD0006277417C5B698ACF2C7E6AF7447FEC4A2E
-:103BE000CB03B1F21D0F7BCCD7F17948ED4BA0BFD1
-:103BF000129ACDC21B0CE2B363FC39E7535F9851B4
-:103C0000FCF433FB657B5D713C1F6A91869632F252
-:103C10005B99867CAB0A79F26256F424E2B3797A36
-:103C2000A484D3D3D0381FC0F58B0E85FCB5CFCA82
-:103C30004FCD23E1FF1C3EA243AEDAE1F901E97268
-:103C40000BE55B28A4C5374819E495C0579C85C788
-:103C5000E0FA603FFF1DF19857C5245A8EE0E366F5
-:103C60008FF907D767B33F14AD36C5C780378F8646
-:103C700072B11AF0563E1C6F275D7CFD4EFA0BA9FF
-:103C80004919E93F0472748394764E2AF062AD6755
-:103C900024F96CD169DA7943484B5FEFFFA372D9FD
-:103CA0009297977BA293711FDC6644C83F93F6D727
-:103CB000296786DB41329D339E01BB07BB5DAC7C2F
-:103CC0009D76D68B87256CEA5985CA6BCFD2E109E0
-:103CD000FBE2D96C2ACDB3F954D69FCDA572FAD99F
-:103CE0004BA89C717634950D67011830711ACF96E8
-:103CF0005239F3EC1554CE3A3B9ECAD967AFA2763F
-:103D000073CE4EA2F2BAB35FA0F2FAB353A874DA3C
-:103D10003FC67A95E4B725BF2CF9EE94DF96FCFBFD
-:103D2000BF26BF630D1765FF80FEFBAA761EF93D17
-:103D300092BC00BEBE4F4B971329FD7CBFF619F80D
-:103D4000FAB8E053E0DFF7300EE3012F8EE2546162
-:103D50001EA70A189A81791AFBB0096CA9BF3472A0
-:103D600012E306CD0B3C7A0CE01E28D5483E6D0BC5
-:103D70006A74EEB659D2477379904C20FDED0C6908
-:103D800034DEB63F2A5ECC5F7869544100E7E9F63D
-:103D9000CB3AB6FF566E72DF2D788E3F85850FC108
-:103DA000782BF6ECF1A4FBE1FBD13800F802B1A7C7
-:103DB0001903BEDE38EA774B713EDF5446F118280E
-:103DC000CD4CF962DF748BF36975288478DAEA9355
-:103DD000491F74EB1E91879A1C68413FB74E66DB02
-:103DE00060DE0DA3DFD98260ABE3CA7694417D67C4
-:103DF0005D991737E9E9573E08913D01EF10142806
-:103E000013A23473607F3ABD61E37CE76D8A31B4FD
-:103E10000E8915FBBBAB476EB7C93F1042FAE89855
-:103E200034B9F21698BF7752C1689C7F7BCD511B85
-:103E30003E14DD1E4F5130E0887E785D92E26A1BB1
-:103E400064634719AC2F20F2AD01CCCA485ADE8119
-:103E5000058712867570B8120A5F0F2B80E7B97557
-:103E6000895892AFD7C4B8ABCF970CA1BFA8D49D47
-:103E7000A6785BA73FB988EA0E38ACF17FAB5979D9
-:103E8000019C6F7C826F9A277D7B11E5915769B405
-:103E90006FDDAEA105588FAD75B1C733C46F36085D
-:103EA0007EDE5679FEB88CEAB3C3D1EDB5FB8B1636
-:103EB0003CEF8BD20947B36B6854A6FDFBB4F35FAC
-:103EC00068DD9FF77C9D23E40F5CEEB6EF4340C8AE
-:103ED000F3E629DF0EE1B9B8054FA704FB50F3F96B
-:103EE000EF43F3142EAF3FEFF5FE4F1BF7F71A8F9A
-:103EF000AB009FCE2EC738E398C9218CD7FAAC7897
-:103F000074384EF949018C47532F83F490AAF3314A
-:103F1000149525900FE5EC0F13B84F4AB566282489
-:103F20006733EFBB12DE44796D4EFEB4E0A6BFC925
-:103F3000C274A0F343AF159F36D4C9FCBE04C67F3C
-:103F400015669DCFF2F8B4D55FAD90291E4D81EC7A
-:103F5000B47154D0C3788EA3609C3A6FF8FCDF4DE7
-:103F6000D1A37DFE221E1F5754EE07BE27717CC4CD
-:103F70005E5528DFB3EB792EDFD87146F2BBABD6A6
-:103F8000A073951DF03FFA0FB15A5F1CE95671E41A
-:103F9000E39DA99C1E42396AC5C5693E7E3E4071BB
-:103FA0006ECC53A4B8B9C12AF07DB700CD1A47B57D
-:103FB000E2F2956B26613BBFC13CCFC1FAFC752C88
-:103FC0007109C01B74B76EBDBC34433CBC72CD37A5
-:103FD0009E8479773F35FD574F427D971C7EB50E05
-:103FE000DAE57FB98EF0EA8C876FAB944D1DE583DF
-:103FF000CF7708F7156C68A28B5B7BA4183ECFF6D1
-:10400000F90EF2FD6E0D298817D0938817AF332F64
-:10401000321DDF6508C7CE8179F06FEFD679CB709E
-:104020005E841BF32B57F4D66BA867824BECE71723
-:10403000FE267BDD5B658773ABD8BF0BD1BF330F2B
-:10404000B1C79CB708E9F64C5063286F36AEBDFA8D
-:104050004692FBDB1536AE3403FD3AD6D5A9B948F6
-:10406000FF771BF57B2B506F346894D7D31DF7C6B1
-:1040700031C57B7B5DEADCC466BF1B1A3FC7AA91D2
-:1040800013EE4C76BC381F0B8867CC710ED63D5BA7
-:1040900026BBA6BB87CF638DD75DF79607E5C448DF
-:1040A000E33E3DC63CE2467B2A9A7751F72EEEDB93
-:1040B000E8E2743D458B4BA5688FEA0B17417DF311
-:1040C0003899EC2126FCBFEE6BF979E2C39A61BB0B
-:1040D0005FB169CA4AB21B6E72EB82BFC02E9C9060
-:1040E000BA6F71C06BBEE086E7EA733012D803EF97
-:1040F000E5866F44BA680C7E4476D4AD45B28EF442
-:10410000B5624F23AD6BB32EB304DABD6A2B19A988
-:104110004DACD5C4F3004CD444BA9B036F64BA17BA
-:10412000913CD40970CE195738691BD4DC45AD9445
-:10413000C7D26848E4875D07984179D0521C51A5E1
-:104140002AEC37FF1DB4FBE6044B65F4F7AF535977
-:104150008396669F835D7CCC9DB6AE13E3F604E543
-:104160002A9C1FE6C1F91779E83E811BEDE32B532A
-:10417000F6F14444649A9DFC6B342A319E5194F8C4
-:104180003DE5797F3F29E3BCEC0556BD4DFAE47E61
-:1041900035F897BFC4FD8C33A31F530D3F6B5CE212
-:1041A000EB9AD827716FE5B027F21B1CDF8A074C0A
-:1041B000D4F8FDE6CD2D2C1C4B8BAB6C7EFECF8F47
-:1041C000A3BD6AC55FCEE5DD09382DB837492C8B14
-:1041D000F4BC27FA0777BA5FCC926573277C7E70B0
-:1041E00067C897F3D5023F8D15FC93575BE145B93E
-:1041F0003916F37D701FDAB93C31E1BFF47C1F45FD
-:10420000305F30DCDA2F1BC3E59222EE4D015D4BAF
-:1042100068C73AF38114CCFB99385C6E1C10F47FAC
-:104220008947E4FF4C6693B91F6E3FBFF22FE57AD2
-:104230009FB5E665BC87FA7DA1F75F147E6542DC19
-:104240006B3C2AEE2DBEBCCE203FEF957595540EEB
-:10425000AC0BD3F3D7D6D55199BA5FC5E7CD177656
-:10426000988A41353CE7F7B1B801F0FA47AD192813
-:10427000453EAFE3F7BBBB9B4E6D2927BB919F5BD0
-:104280006C2EAA4E14A2FF02B0E643DDE5EBF3F07C
-:104290007B5EE6606501577388F7FFEAF30A275DE6
-:1042A000E8D6FE3BF6DBC75A19CABB8069DFEFECE4
-:1042B000B0D3BFE1FBEF2ABAB87DEFC57FC03E7E29
-:1042C000C9DAF7ABD9D5FCFB0C17278F918F2A855C
-:1042D0001C1803FC7400FC79B7C2F3D5F3799EABCC
-:1042E00019E2FC66AABC1E1B2FDABB3809B1813C5F
-:1042F0009ED75ECCCF13A81FE695E37B0C4BBEC0C8
-:10430000E35B2C47E4BF8F15E3AC16E34EACA67B12
-:10431000BBFCFC9FF5E958FA5892EAB9C007580669
-:1043200059AB84C81CC306C9DF2E9686A86E487A8E
-:1043300016D6CBA47019F7C3E3A43FCB15F3DB1556
-:1043400084FC88CCE345C9C5644F825E46B91857E2
-:10435000238B50BE6C68D3C28089737972787F0ECC
-:10436000CB0D7D350378FE118BC9247F94E75896D9
-:104370007E25D97BA4BF36ACCF3B984DF91A49CAEC
-:1043800073DFEF29B5E9A989BE85D7E9B05F1B4581
-:104390003E9D0BFAB30CF9A7563E1D8C5B92E9BD0E
-:1043A000556EF46B8B32F9FD0F7B2411CF488EA62E
-:1043B00038A0D8D7F85439E37DC67D1E6ED73C5A55
-:1043C0009AD99E66EC411A6FBF47778C9B6CA1FB14
-:1043D000333A8F6F64B94CCAAFD9D8C6EFE95BF8EE
-:1043E0001B0D762DDAC31BFBE6CF46FE8E55AA9435
-:1043F0006F0EEBF721FE5C222F79E3F8E0C16C1E13
-:1044000097284539DD8FF8AB4DC35F706513E2AF78
-:10441000E3559EDF0BFADCC732E41B5AF873F9D878
-:104420001733BDB7CA8E51DAA24CF7868F7A2C3B70
-:104430003D59CAE984E32FEB5A3592A97D42E0BB8E
-:10444000A48C45CF87BF7E8F6E1BD73AF755468821
-:104450007749BE04C5B9266ADCCED8B098E375C3E7
-:10446000F3D71C8FA69D43FC12879C928A075B7131
-:10447000634B6FB67BA2FFE81995D297ECFB8CE4F7
-:104480002E7BC17310F72DC339C4294F6D867388F5
-:104490009E8BFBBECB58C1B787B61C9D87F3FC55DE
-:1044A0001D23FB2AF00C9F37576771B914BF536067
-:1044B0004A1867B926A2D7A3FDE66A6726E6CF8C1D
-:1044C00015719BC2F63E05E922087B5928E1BDA67D
-:1044D000640CBF67327637233F512D9CB96ABD21EA
-:1044E00044695A7E94C286FA697DED9AF1782981F1
-:1044F000F553D40F63C4FB40FBCC5FA1DC1C1389D4
-:10450000521E2EF48BF9D1BE10782CF072BE5DDEF7
-:10451000109624681F0C26293EE994EB63003F9710
-:10452000A4D96F015167ABB89C96E13FD4F3F91160
-:10453000BBDC1EE7B8171D70E4BDE47A45BEBB25A1
-:10454000B78BF8A64E5007E54C7E794ABF3AE04358
-:1045500019569DEA1FB0EA9F113E2004A2670B1E68
-:10456000BC4A8972778F4BFFCA53A89FEB359E4791
-:1045700026EECB650BBCFBD061867603535E3171B2
-:104580005F7784F97769CE4C9D477E68769D759FED
-:104590008EDF5786328671BA6C31BF75AF2E9B198C
-:1045A0006F96033D649B49BA57A75BDF55305902AC
-:1045B000F370749F4C7974BA2F42F2A9678147C790
-:1045C000EF7C68E29E9E4BDC1FCF364FD3FDBAECEA
-:1045D00061EBE3F7EB2CB8B3B3AADE2C376CF3AC8A
-:1045E000C7F836AC7D74C6FB7575DC4FCA36791CCE
-:1045F000226D7CBA5FB7636A99ED7E1DCD837E9C88
-:10460000A03FEB9E9D13AE73FD6A32DB6913C27649
-:104610003BE242F7EB5C217BFB1D17C8CFFAC4F7E6
-:10462000EB041E86B573D8832ECB0E1D2533DCBF5D
-:10463000330D327D4724F7A3646486447109D2F7B1
-:10464000969D97C787FA6F67E7E55979FD0E3BCFCF
-:10465000B2DF7267DBF1EDB4FBDC5511EA73B176C2
-:10466000DE2EFC07D0CB435E879DD794993E9CF20B
-:10467000229F0DEEBE12C6395AFB2305F3D576E50F
-:10468000F2EF1FB161FEC15B33685F7CFC7B47BB0F
-:10469000A6F4ABF8FD9BDF2D656427597104B78044
-:1046A000795791BC9EC2EE5D0F117E82020F4DF8CC
-:1046B00001B21AC2557C1CF199E9C5BC85FC26469D
-:1046C0008D0A2BC2B4EFF85902992E6DC554D4E36C
-:1046D000F58895343CCDF0D8BF13D0A8E73BF6D190
-:1046E000BECFE7CEC11FE4DF539863D8F7DDF29366
-:1046F000D09CC5F9AEAFB4D3C1092932A84097A761
-:10470000B34A85FD33A8A3BEEC5EEB22BBF1A12525
-:10471000655BAF447F3528EBFC3872681CDA47CD07
-:10472000474D2FDA79DB23D3BDE3E0FD431D4A1863
-:10473000CDC3A796AC7915EBB1DD2EB2839EEA9B73
-:1047400057B0228DEF36EF5EB07031BEEF70917EC4
-:104750005FB1E7BE81D220F677D5A67F6FAA65E369
-:104760007D3AFA6D6FD47A33DA31576771BB64A33F
-:1047700096A4F8D3C6791A43976B6349FDE8156888
-:104780003F5CA365BC4F7E57969BDFE773B54A2815
-:10479000DF0BA399EF0558EDC6D6FC96CE3182B358
-:1047A00065867E9CEBFA7932D61F827DD5A5143DB5
-:1047B000E5097ADA5874EFD60A5CDF40E67B875663
-:1047C000B9366B1CA7D3889DCF5D854DA371DD2EB7
-:1047D0007764A01E89AB50D6312EE272B7466E4682
-:1047E0007BF46A175238DBDCF1C38645B82F614988
-:1047F00097609EA01A59457416CC62A80F1A964469
-:104800005A112F85A0FF30B45758F44B3AA728AC63
-:10481000D39817EA9E253D0917BCF75444AF42BC14
-:10482000BFB4967FE7A530E8A37B4185117E0E5784
-:10483000D8EE6668326C0417D845FE814471222791
-:104840001F59EB6A5ECAE5F8EEB5BF1D95E97B33EB
-:104850001559658457AF615FB707F52E8C33D51CAA
-:104860005C42F8AE71B338F1AF9BE87B57AD8BE09B
-:10487000DA35E5E45710AEDFFD3E8BF6FB5A664AAB
-:104880000857FE103F67B5E6C96F1A54783C9CF391
-:10489000A193EF2C7E70C2B773F63C3A8FDBCC0647
-:1048A000E723BE636765A2A3CD456BBCE971D15612
-:1048B000417FB00F245F623AA3FD56FE95ADC77CE1
-:1048C000D88D5F8C54227FBCEDE5F756EF5BAAD103
-:1048D0003A1E9AAB51BCF1217F2BD1FDA98DAEF0D0
-:1048E000210447D517E27EEE2EAE0863BCEDEFF053
-:1048F000F039CD3FD83DEA4B9588CF2FFE218B8FE5
-:104900003345B5C6F919D17BAD97E09CA1B4FF6CD6
-:1049100005DAA14BE4C9943BBD6A09C92F9790E31E
-:104920002F2FC9AB473F2570C372C6E5218F5304B3
-:10493000D656F3FB0C0EB99FA85377CFA05DE2F1DA
-:104940009F7A21EFC6DE30BD1ED7592FF482A966AB
-:10495000FE2E63AE685F381441936C58FC2757E80D
-:104960008FB1BB1DCF855EC81D16071FACB819E4FB
-:10497000CF97B2841D3942DC67D79279C40F678024
-:104980001F282E5D7292E83F067202EDE637A4649E
-:104990006845DA7998F59DB99F887850C42CA53C74
-:1049A000E1B7443CE8A7E2BB73EF8878D071110F00
-:1049B000FAB98807FD03C683F0FB61DECB69DFC669
-:1049C000D57DD48F719C9D350B3C068C33551F7C57
-:1049D0000981FCA239E813F9F7046FD0D24373CFF1
-:1049E0001FA74A205C6E8C4B71385F16DFA37B4596
-:1049F000C03520E07A4DC065E941941B48676CAC36
-:104A0000AA67928741B555C2F35E9417FD4192178C
-:104A10003C4F3CB84632260C971330DEE8743BDD41
-:104A2000A2BF53A37C44C7CEF11FCDE2F70E5F5A5D
-:104A30003B6B3F0BA6C9A3C8C2554877F9B03F28C6
-:104A40008FA24D5C8E47F1DE459A5CB5E269B023DA
-:104A500061D23B37703C8D245F2E24570A1D72654E
-:104A600037CA15A8EF46B9124C972BADFDB8EE200A
-:104A7000CA1596D243C1C827932B3FF396D9E22497
-:104A8000967CB91AD898ECC430E853FFA7D7A76F23
-:104A90000B397121BD6AE57F044C467A7D0FE685AE
-:104AA000A03F339ED13D1CC51CA47CA2DC7617C35D
-:104AB0007C90ADD86534FA330B291F64C77C8F8E88
-:104AC00074F1B09408213EF7493D5EBE2F7A3FDA7B
-:104AD0000BDB26F038C98E3FDEE3453BFBA5DB0B45
-:104AE00002788ED39B6BE581E88B6F85FAA94646E9
-:104AF00074B262CF0A5BDEC3CFB3F2081FB9319044
-:104B00003F808F876FE7FA4737781E089419F34084
-:104B1000DC3E110F526321A48F6D52D4437198462D
-:104B200099F4546F98E7AFF4825F8EE783BD0D3B35
-:104B3000E7A07EDE70ABCC285FBCB2E71E94331DCD
-:104B400013161AC897AED1656FA239BEC1277BD3A1
-:104B5000F348F13841ABE6E786A2347300E4CD5E5A
-:104B6000D338DFFD5155F87DD8DF7D9E3CF8CEDC93
-:104B7000D0688C13F4362E0CE1BCBDA322A13CCA34
-:104B80004F1943F6C0C6519B1663FCA963B9C6D240
-:104B9000EDA461F305EDF6B51567541B78FE488763
-:104BA000CCFDCB5C713E0D7C5589784B5F27C2A94B
-:104BB0009A3C7F04D7ABF0F5D2F74D731BC03FACE6
-:104BC000E2EB47FF55F7E9A3517EA80D3C7F64B3A4
-:104BD0005F5F8C7EA3130E6BFC6BB3259B7FA45B86
-:104BE000790BF56BF8396211CF5BE8759D3F6FA1CA
-:104BF00043C843CB6F1C091F2EC73975AFD71E079B
-:104C0000B4E0B952944E3846CA17F8B4F35F68DD81
-:104C10009FF77C23E511ACC9966CF72B72AD7C969F
-:104C2000C635219413163C9B2F903FF269E16A6EC2
-:104C3000E4ED3FEFF5FE4F1BB73E9BEB47E0D301A2
-:104C4000BC47D931716608E5502A1E3334508EF6C0
-:104C50009CB8CF68E58FB874FE4F55E5DFB993B3C4
-:104C60008BE83BCBEA749E3F427F19F240363136E7
-:104C70001BFD1D55C46F9C7C7A21F89D792337FB61
-:104C800084DF1875CC27F2449823EF440DF1FC1211
-:104C90002B9FA44B82F50553F92023CEEBC0DB7884
-:104CA00021F7DF73F41FB6EE30BF5F69E59F0CCBD1
-:104CB00023992AEFC72D18964722F2517A728D3820
-:104CC000CF13E77925A836319E372C8F64EAF4108C
-:104CD0007E53725A89E87703A3EFEFF67879BD77B0
-:104CE0000E8BE3F7CE7AB18EFC54CB28AF65587E9D
-:104CF000C9D43584278D4596F1F31D7EDE6FE1C161
-:104D0000995F72417ABB401E49D0677D8F2242F382
-:104D1000F4F8C33FA923F8643A8F2FF8D2F170FA60
-:104D2000F897F8B89CEC1179783DB9F67CBCFBC4D7
-:104D3000BE548876CEFDD58B385D77D5EB1477776A
-:104D400037F078E5B0EF40D4D8FD01673CEF8490B0
-:104D5000D7175ABF33AEB76D84FB660B7C3C8FEB25
-:104D6000A12587282FF6CC2AD0B380AF87319FA505
-:104D7000E6E2F3595ECFE2F92CBD46FDC24B518FFE
-:104D8000453586F2B417F359E0FD868611F2594491
-:104D90003CD18A8F8E94CF927BEE3CDE9ECFD27B2D
-:104DA0002BCF67E9EDE1F358E3F53654939D35D207
-:104DB000B84F8F31651FEE7FC5C59D9F4E2B89FC77
-:104DC00019E6AFF4946AFA8306D20BA7E7AE468DD4
-:104DD000E8BBCBC5FDD8D868EE3733351E5A086D11
-:104DE000B6F8138B289E2CF2327AC5FDF9BFCF326C
-:104DF0006CF67167E3774368D7031DBEAC733EA1C1
-:104E000071F2D5D2F5600332B7DE62A24F3990CD90
-:104E1000E308AED0B181BA343ADD22F41DE2470690
-:104E2000FCE44AE7F015950B28BA4F7F6B047DBE72
-:104E300091CDE7B7E890A993C2FCFC8F55A01CB1B7
-:104E4000FCD761ED3CBCDD30F9E390233D98DF8673
-:104E5000154B9EDC60C9133B5D5AF28339E4CC39B3
-:104E6000793287DBE9E7E409C80FFCD499530EF5E2
-:104E70007AB9BEB0E071A3600639F29E2B6C8BD379
-:104E800038E5CE85F8E8F3963B2F65E70BFB83CB3F
-:104E90009D20D206F24DB6758EC8EF3D9C99FA2042
-:104EA000C9438FCAD7ED8930FA9D00ACA33CF7E027
-:104EB000394A46B95E2D51BC419C8BE48BEF0F3EC5
-:104EC000EC0A537EDAC3C0CFE8E74D309CF6D9F93F
-:104ED000CF159CE7490FAFFD1AF7CF00DFE8775DEC
-:104EE000AC1CB2E4C487D97CDDE7E8CBE4705AF4AB
-:104EF0009546CFF47D018B7EAD712D3A66C8A00535
-:104F0000E7A15741D7188EA638754C8A631CC4CACE
-:104F100023B3C67BC3C7ED9191EE5759EDBE63F93C
-:104F20005DE7E2C17A40A77CB21EBA6FCEBA38FD07
-:104F3000CD61BBD53555944FA032CA278894A03F88
-:104F400073D867F78BAD7CB06925E110CA890DC2B3
-:104F50004EB7F2C8ACBCB4C3BE5CEB9CD9969FB64E
-:104F60006184FBD96F9EC3CFC57FFF04BFDBB6DA78
-:104F70006B3E8E7211F0658AEF39511E9A35EE77CD
-:104F8000059E5EF7984FFA3EC3FDC917B3EC7957FB
-:104F90009D3EC31117E0789DA8C7EAE93E5E94DF05
-:104FA000AB729EAB8F74FFD5796FEFDCFD5771FE4E
-:104FB000DEEC89BE4CF0BFC8F3DFF470F46027FB71
-:104FC000FCD673C06BFE04C7EF14FC3D2DC8EFED9B
-:104FD000BCEF89BE8DCFAF63DCAFB6EC9CC3D80EFF
-:104FE000FAFB5F06A90DF4B2A996D36B5125A3EF86
-:104FF0008F4F6FE5F51D4BF9774DFB5FE7F73EB639
-:1050000045F9F74CA15F9F0C78D9319EEBC3FD5554
-:10501000BCDF7EBCDF847C5AC1EDAE3C8CDE2B282D
-:10502000AEA3544EAFE9F14E80F70796CA1417DDD0
-:1050300023F822C04C8A736CABE4F3ECAA909F1067
-:10504000DFA359740BD43B67AF9C8CF74BB68B78BE
-:10505000CABEC52B9FC0BCBE0F02E582EE1274EF24
-:10506000B5E7F86D141F7968499EB412D6B8EF60A1
-:10507000E6FC962ABF2AFAC5DC229E24CA8486E56D
-:105080005653E4ADB632F13DF69886F1A76706793E
-:10509000DE6AF7EA678ECD447D5C29539E59D7E0DE
-:1050A00051EF65B8EE3A9ED753A426A474FFC5EB22
-:1050B00077713BADE6A8C7A81ADEFE99C1A3447775
-:1050C000DB01EF4A9AFF270B38BBD19F807E7B5DC7
-:1050D0003D0333A1DDDE717952CC48B51BEDE7FC11
-:1050E000D7BD4416DFA167F41D874EF39407E5662C
-:1050F000279E7F40FBEE1A2B2FB587EE65ED9D3383
-:10510000790EE6896FBB81074BBBC287C84FEE990A
-:10511000CDEDB2BD12B4837DD9D7A25D4FF7985AB9
-:10512000799C08CA8C71A25E4C0446BC8A733B4AC7
-:105130007D81793B1BFA06709EA23AFE7D8BA29A76
-:10514000CCFD5F08B8A9FF3E578CE29F23EDDFBF7F
-:10515000FA383E3BABF8790163718A4BED167E1746
-:1051600053A346FA77425B021C3F3B5DCCC478995F
-:10517000AF4E23BD2E870DB243FD603F623C6E9B58
-:10518000145B8CF921B1491A7B9C30627AC761FCAF
-:105190006E425E18E96F939408E1779563E3787C3B
-:1051A000FB686427DDBB3A00763485835982F4546A
-:1051B00077348FEE431D8D540F527F5F85EEB634EA
-:1051C0000AE6CDD38722199B74D9A6AD68D7744E51
-:1051D0009175CCDBEC94EAA3385E2CD7437164D78D
-:1051E0009479B47FAE517952BA3EBAD1CFF5C2D0DC
-:1051F00084C88D7E585768CAA95C8C5B6EAF7D658C
-:105200001FEEDF23F77B888E1EA91DBC1BE7D97F0D
-:10521000F6AAE351E24B7E5EF768EDE952B47B7685
-:10522000359DCA45FC15637C0EF46171058FA3A101
-:105230000624FB4CED6137031E8BDB3466A4E96367
-:105240002FE3E779F8E79B4C728FFE9E193CE569E6
-:10525000C1F196B0C4A5017AEEC1789625678AEBB4
-:1052600058A200E4E1FE15EFC4304FEE91890574B9
-:105270008FB248BC27C909E39588F1FADF78653D0C
-:10528000B67BB4BAC04079513C30340F954471D5E7
-:10529000698AB385ACFB1F5163FFAD449F327DA784
-:1052A000B238FCCE5FE03A02BE3ED273D09EE266D8
-:1052B000CE7504269AF7F9018FDF945A5F1D174CBB
-:1052C000F963F487FC782FBF975D9CF50F7395B455
-:1052D0007CDB121117D8240DCE26BBF4016E878F0C
-:1052E00065719273C555B1BB79BE6D94F26D9DF336
-:1052F0006EF79FD3AF12DDA3CE6F12F74AF8EFD847
-:105300009488DFB171D27D28945FD57155AABE2FE4
-:105310007A8AE8FF69CDB82BD3F71EF609B9B049F0
-:10532000F863D6F86373F9F856FD519DD3E3D32F94
-:10533000E75D5F05EBF9ABB6B24918FFDC31821FC0
-:10534000B732C0E92F7B002C1CD003FDAFBDE6C5F2
-:105350007C96A765B60AE5547D55C293AC12788455
-:10536000F1C91783F10F84BFED41B9F4D54025C1D0
-:10537000B5622A8F1B74563D48E740219DEB1DE422
-:105380004F94EFBE504CC2B8F7F21AA61F12F19616
-:1053900018E09FEECECB2C95D7BF3D97FC1CE015B7
-:1053A0007EAF067393268BDF9F28C773A24D778B42
-:1053B000FC5919F1DD29E601BEA5790E148971EEBB
-:1053C000E3F63FFA17D8BF5CCC535EF7DDAFA11E02
-:1053D0002FD2395DA4E0EBF3107CAD3223F8D4C4B6
-:1053E000ABE8876E9F546020DD1C0885DF6E82FA73
-:1053F000F2452AC5E3CB6B381C075A65FA3D207F7E
-:105400009D7690EE8F99A02FD2F06588798B6A12E5
-:10541000129E6B19AD7C5DD0CE8B72D108033C50CF
-:1054200037C4BACEC13F4923F88B3C83985B740ED6
-:105430000F2B713CA0DF9575BC9F3FD4B705E5D815
-:10544000F23A0E37E87782A728AC1D447D5F14E25C
-:10545000E32D07FC1C925270655B70D5C9947F5593
-:1054600054A31D443F385BC0B732CCE1E97FFDD483
-:1054700080C4C73370BC6C016FB6583F25EC16086A
-:10548000FD00E33DE54AD4E3BD9C5353987188CFBA
-:1054900046F12CEBFDAE56C003E0C72FE661BBDD45
-:1054A000C44FB0C4D8C732FFFD10232D6E51B15B7D
-:1054B000B3D5FD62FF58177F4E7E1CA9445E9785C9
-:1054C0005FB7B2CADE8FD5A4D5CBF07E19A7F7F5AA
-:1054D000D7F2F38E0313B87D847EC739FE463A9F18
-:1054E000623CD615C4F71AE9BB9276FBB8C5AD0588
-:1054F000D3513E140F3C3C4F86F514DDCB64258719
-:10550000E8593A27FF60BE6FAF49D0FDD9EC81481A
-:105510001ECABB92D6BCE9F8FDB7EC8128D5B3070B
-:105520005A4D9E7F062E4C1EE6EBA5CD538A729AED
-:10553000E7D3B156AD0FE55A6D3A9CF0BEE4E59E57
-:10554000B9D87FF3DDAF8C46FE2D70F4F7E470FF21
-:10555000A1F8656815C0F94FAFC5F6567C271B2129
-:10556000CEA3F2652C8B7D208FA12C11F97796BCF0
-:10557000E89CF0CEA4A84FD00FE5E3B144BA9DEF6C
-:105580002CA1FD78D13E269DB7DD696A3752BC69F2
-:1055900020C0E34D0161AFF630633FE9F71A9EEF9B
-:1055A000E1C3E7A03FFA6A8E4EA7FDEC6361A4E772
-:1055B000E2B63FB9D3E5F5CD8152710F3A4174AFF0
-:1055C0009564D1F91EF0317DDFF480DA4AE7AC7DD5
-:1055D00045FC5CF3E89C5724C467D1733C4FDBB2B5
-:1055E00097A7D72442F8BCEBD5E865C49F23D89F82
-:1055F00096BDE95CCF25F50F923C181B655E3C5FBC
-:10560000F3AF56298FB5240A7055A15C00922E0481
-:10561000F86B62EB916E8C28AF1BAB45B90ACAAB35
-:10562000C1BE5D3750FE4B576ADCAD1560D7A2FD99
-:1056300034B8DB7303DA2BAD608D18682F9EF2E06F
-:10564000F754BA5BA7E7239E9F8958F66542C2F1DB
-:105650008B7E6A92BD58AB6B3AC66126B813A3D352
-:10566000CFE90ECC79A79ABE2736FFE2F2C946D21F
-:1056700027088B9CA647FAAB8E927E79C23F9EF498
-:1056800090A5572C3D4223827CB945F0519791F06B
-:105690004824AF807701CE5B508E001DFB8BB83C59
-:1056A0000739CCE59CA54FEEE67ADF929F15629C08
-:1056B0005B50DE42BFEEDA27726F40B922E4AC3FA6
-:1056C00064CCC4F3B90A215F991A9370BE0353F8EE
-:1056D000F72A030E795AD1CAC7E90A31A227D04363
-:1056E00007916E0E1425E89EF881D6A352FA3D5319
-:1056F0004BDF055A930CF77F5C1D9783E3845CFDB9
-:105700008EDFE0F4E9E172F59CDE13F276AB79947A
-:1057100089EFC266CCC3FA7BA1CF7B2A0E915FB022
-:10572000EDD653844F2B1E1A12F1D0EEAAB7E8FD26
-:10573000F628BF07B0CB9C3E87E08F2CD728FFB45C
-:10574000E6E89C32F4379A966B68D79D0C1458E7BC
-:105750005FDE85684FB6AE22FBD727F6F1A1301386
-:105760007EA7467ED67D4BBF3D80FD43E0174906B0
-:1057700036EAF3B891CEF17B0A88EFE82075F6D5CA
-:1057800018F41D08E73ABE17E0DFA5F5479303E3D9
-:10579000685F65BAD2E3AB61E4772E07BF0E87DDA1
-:1057A000AD86BD13E0FDEE26595FCF52FDFF578059
-:1057B000E7A34DF4F37B0A3B179FDE8271BE9D4B3E
-:1057C000C577CE1CF0DFD7D8E751681E8C09501E74
-:1057D00073C6EFED57F9B3F8F7176AFA06D09E0FC4
-:1057E0005471B85E0C181CEF831C8F3D1199F8683A
-:1057F000D760B517F59DD36E7C24FBDD493CAFC562
-:10580000AE6F2E542F76C8FD09EEBEEB48DE7D53F9
-:105810002679C518977712930DFC5D8D9600A7A782
-:105820002A21AF3B5C89FD9857D0F1AC8FAD375240
-:10583000745124C6EC6C9533FE7EDAA180C2F77FEA
-:10584000F8BE73FB41ECFB93020F17DA7F0CB3A099
-:105850003DDD17DF34E60E94E3ADDC7FEE4BBC4557
-:10586000794745B31792DF73E4E0A5E40F14559927
-:10587000B6DFD7CC1EC16FADC8F19C371E30923C4D
-:10588000DEB7BA83FCEC7D8399EFC514E4F0BCB4B9
-:105890003E9097F87D9391E6D77338FFFD5340D043
-:1058A000DD9C77E87B19697AF665A16749DF16AB5D
-:1058B0002CA6A4E5394C10F873EA4FA6C63D97D63E
-:1058C000109D13FEF689F38B874C99F06ED1399EAB
-:1058D0001F205E611DA6A0433ADFE861710FF24D03
-:1058E000AC89E77938E19EE0972F6A7DC11CEE878D
-:1058F0009C9B4FF8EB13FD1CEE9DB5F7D33D4798ED
-:105900002F84F421FDE03F4ED37DA8675DF47BB684
-:10591000339E752530A675E741FE7B8BF28B5E8248
-:10592000F39F0FF3EFAB27FCDC1EFBB5CE7FAFE898
-:10593000ABEEC1EE2F407DE85985913D1907C505B5
-:10594000F47A5AD02B7B8ED7577A79F5CE83FDCB5C
-:1059500070BC55CFF13CCC3B9FBFEDC62F40FDB690
-:105960000117DD19B8F3F1F5DA18A8DF1E97FAB0C0
-:10597000FE9BE98C7EEF3396A7519CEB3781C18269
-:105980000580EF0FD679987119C649070BE6031EFB
-:10599000EE883F3D13FBDDF1941446B69DF1ECE338
-:1059A000AF8C06B8EEFC8644F95F5F39926DB30B9D
-:1059B0004FC352A6C1FB3507F9EF46DEC67A662211
-:1059C0003EEE7CBC977EFFD0C2E707EB2A9991F6AA
-:1059D000BB61777EE369FA3DC3BBBE25D1EF2BDE09
-:1059E00025F37B44FFFCBC77D1633E5CDF7AED524C
-:1059F0003FAE6BB386ED6E8BB77C17539AEE881F64
-:105A0000D466C2FB3B0E1CD456A25FE666CDA87FCF
-:105A1000BE72E40A9BDC39BD4F21FF604DAE87EEBC
-:105A2000D7339F199A3761F83E7FB08ED9E0BAC359
-:105A30008A13A8716D6E5A7B97CEFDDFAF1C516C37
-:105A4000F3587640EC18D70BB1BFF553FCDCDABF46
-:105A500035C2EFB6F66F8D15885787266782A71B6C
-:105A6000F703E0E959A753B9735D88CADDEB0CDA97
-:105A7000A7BD884728BB04DC81A9AC1EBFCF1F305F
-:105A800079DA715E93598F77CBF222BC5EB0244AEB
-:105A90007EC848768C55EE75455BD087ECDCD13FEF
-:105AA0004B05BB67AF16BD1B235F7AC7ABB31AA00C
-:105AB000FE3739918D39246FC206F29DE59F7F3DF7
-:105AC00087CBDD4DA335C2F7DEA5931F532CFF0B0B
-:105AD000E37E4B573E81F604F4DF9E437C1BA6EF2A
-:105AE000748DD4BF60599DAD7FC1B25556FF3DD472
-:105AF000DF73FEFE7B975D639F7FD91D56FF4708CE
-:105B00007EDFF9E12F689E6A9FBF7935F5FFAA9B7A
-:105B1000EFEF50AE87F2E93BBCE1848BFC6746DFD8
-:105B2000E750F32E3D44DF4F3A17671A3451CFFA4E
-:105B30009ECAAD463996A2A3E9DFC475F881BBD2EF
-:105B4000E928A72ECBC657B9669EAD9E3F7B8CAD8C
-:105B5000FDA84899ED7DE1A2CB1D74E9D3290F96EC
-:105B6000717D6A629C13E0D4C6F0EF35D58FF1D019
-:105B7000FAEE7FD14BF5FBAFE1EBBB7F8C8FF89852
-:105B80007417ECFBFD5AF4CA74FB18D62561C8EBF8
-:105B9000193D3A90539BFEDC90F17996C27FC72E57
-:105BA000CBCDF5E5E6D2C98FC5D2F0B9A518E8018D
-:105BB000EA6FE768B638CFE6E295A196B479361574
-:105BC0006B8B0E55F1E7B7A01DAF47FE0EE7FBAAA2
-:105BD000367429DAAFCE79DC6575B6793C25AB68C9
-:105BE0009EA4631E77C92AC73C9E4587C47331CFE4
-:105BF00029A49391E6D95C768D7D3D2577D03CBF75
-:105C0000C6796AD3D6537287639E2CBE1E782EE661
-:105C1000F9CD79D7533ED5BE9EB1AB699E7F77CC87
-:105C2000E31EBBDA318F8FE6C1E7380F2BE27E949B
-:105C3000E61E5A49FBFF032FC33890E68EFE355D02
-:105C400052F97B2FC585A19589EDFE0FF9438DD2C1
-:105C500000800000000000001F8B08000000000012
-:105C6000000BE57D09785445B670DDBEF7F69274F9
-:105C7000773AFB420837801034C40E840CE0320DB2
-:105C8000411E3A80C1155CA0C3923DE988380F4798
-:105C90009D34041111B551D4A0C034080EF840034E
-:105CA000132040C006D4C119D438CF7199059B4543
-:105CB0008210930651F1CDE25FE754DDF4BD9D0EF5
-:105CC00030CBFFBF79EF8FDF4C51B7F6B3D539A793
-:105CD0004E55939C0442461172308EA62308F92635
-:105CE000C67DB5C34AC8F7F0F74342FFBC8424F32E
-:105CF0003485903984FFF9170BA490905A33CBCE9A
-:105D0000DE3C256B01A42D45692505F41F2B6CCEC7
-:105D10002B14423A5B8A8CB372C3FDA9E91C9F7CA9
-:105D20003298C3DA7E4FC2E378C7929C3A3A7E59E2
-:105D30009C03E7A3E64FD6D3BC899063F504D376E2
-:105D400099CC28A6DF4FD4D3090CD6CE7701B63B29
-:105D500029D17F26D17495E0F70A745DCB3F90C9B5
-:105D6000001CE6C31CBA8E3BF832E6F862093187A4
-:105D7000E7E1311117B40BED32F9D709F0D5D5C7EA
-:105D8000904693C64442D4F9F627E48FFB26BD2DF6
-:105D9000D831DBC7309290BB966C7D0BAA7D2494E2
-:105DA000F49D4BD73BB579B9DC87E63BE5E074A7BA
-:105DB00055D3CF54F918ACDB4CFF837EA6B9695E8E
-:105DC00033FEDDE5FAFCBD440AE7B309B9CAD19F49
-:105DD000E3838FABF865C0D71D744DE91485F74296
-:105DE0003A0C8A1D88AFE90ED6569D8FE72199049B
-:105DF000603E523099E4424932D673433DA5E7FCF8
-:105E0000A6CB665731C5E7F407458463E47C83FB82
-:105E1000625D863C9A367E2593FE979EFF8CF9FA4A
-:105E200072E265E3A97055E9E0CEA9639E3DA1A1A8
-:105E30008F69EE1B9F3DA183D3145DFEDEBA69BA64
-:105E4000FA33E697E8CA4BBC15BAF2594BEED3E5E4
-:105E5000E7F81ED4D52F6B5CA02BAFF03FAE2BAF75
-:105E6000DAB85C97AF695AA9ABEF6959AB2B37EC3D
-:105E70001B7233A1706CF8AD484C148E5F5B4F3EC3
-:105E8000754D12A49213E07EAA3E0DE9FA74BD820C
-:105E9000692DD0DE28E09FE16637C5932726544A56
-:105EA000E20979C477ED9225D7D2BC91968FA6D41A
-:105EB000EE1BBBC49B49C8128782742F361A4980D7
-:105EC00092AA4012BAE93A246ACA8397286F944882
-:105ED0006078CF723118FD7B97101A9441D7E1FD9D
-:105EE000D44436083DF93CCC97A40F49EBBDBCC364
-:105EF00040CA9B34726783C380F349768CDDE0A08F
-:105F0000F4506D64FC5EBD2D7D2CB1433E30A8CEB7
-:105F10007A91F19AE86452A11FC62F15FE3E61FEE8
-:105F200045FC0DD0F1FDE038F77A071DAF63BF38AF
-:105F300015E6410207B36E1D0AE3BB36C077D242B5
-:105F40003B49A7FC5DEF7AF6C415847C523F01D330
-:105F5000DFD5173F7B4226E40FF553317FA4DE8D5A
-:105F600069B0BE1CD363F575587EA27E3EE64FD65F
-:105F70007B313D55BF04D3D3F53E2CEFA86FC47CD5
-:105F800067BD1F53950FA83C9A510C7C5A5C6C005E
-:105F90003E9D6B21FC8FE5CFF13588F4DF6DC8D7CE
-:105FA000CE34E0EB73D66F0665507A3BF70925A631
-:105FB000ECDEE1144977BDE3CF6500FC95FA29F1E9
-:105FC00024F62CB7C430FC580C6402A1F2E7F12B84
-:105FD0008C44A2E3C7BC71D53A311BBF4B403A7425
-:105FE000E3704EB145E97F20417C5D0A4F6AFD9325
-:105FF0002FFEA970662EE0A73FD249CC41B18EE1B9
-:10600000ED6527E0ED52F093387F45C25178E38F7C
-:1060100059415AFFCB64159E6D5984A6B73A8A4FF1
-:10602000011D9C6B36E1BACEB5C6FA09F4E14842CF
-:10603000BAE81D6E6C1E551B2D3EAD7CA8698AF713
-:10604000E9E545BA4F2B2FCE1D7AD90E7C3F374D4F
-:10605000F49D180EF4E1E2F4C1E84EEDBFA629DB91
-:1060600067D5F5A3CF9FF309139A50CE2B71B70DC7
-:10607000ED7D9E73D38C38CEE98D03E260DCD3F5E1
-:10608000661F8CD351EFF0B171D37C5ABAAC9E1F0E
-:10609000EB3B91189E5F6FFDFEB3E7474833396EC7
-:1060A0002608FAEF07F45EBF577C48E78DC5401F0E
-:1060B000ADF237B0EFC4E4A8FB8E8479B55F4F939F
-:1060C000E8355D0DDF37EBC6A3ED94932A9EFA5FAA
-:1060D0000CEF1239A9AE93CAC9A15476039D52623E
-:1060E000463CBB698F71B4BF2EC9BA44A0E398E2A5
-:1060F000152CF7C040949E6ACC41A35B4170B781D8
-:106100009E3573A4CAF7CA9DBFA724F7C5AF65B271
-:1061100014CAFF4C7BA7E5322F9D4D8AED848E3744
-:10612000B3B96A22C8C92F76FC88EB29BE4258F75A
-:1061300097C43001F8E44BF21BFB708D5E3639DEFC
-:10614000C8E6B784EDCF5EFA1FAC8FEA69BAFDBA34
-:10615000AC519F2F25B7A4003F94AE90899FCEBD30
-:1061600002F67B75DD94EFAF8F677A5C19A95B0C43
-:106170007ACA52994C057CCF7410A90F9513353B00
-:10618000571796D0FCEDF106A4ABD354BF53A81C0F
-:10619000AA48607A4C6592DFE8A2E5C79B87DF7169
-:1061A0000D81F6FEC520D7BC36E2DC407AC27DD632
-:1061B00012FDFC2E35FFC8F912B210E7ABCE43ED4D
-:1061C000579D87B85170F9A3E8B3B3E285B09E4CF0
-:1061D000D3FBE3F5FAEB7CC86BF4DB4722F20B232D
-:1061E000F22A9DC89C4E4CF1EEF9F1C94017A1F17D
-:1061F000A8A7114A1FB9E17AC670BD472E56CF0431
-:10620000F544ACB7F062F52CE1FE1E8B56AF66E7A5
-:10621000961D5E4A4F95AF3F6727549E7F21F952E6
-:106220009CF47BF58647ED00A75392D70EF8FEC28B
-:106230002F4E8806AF7DDDF0725905B02390B4294A
-:10624000DC5F7D6232E849DF6C901D22ADE2D968E7
-:106250000A9828FDD636574C2479983FCAF28F9D6C
-:106260001521DFA2C767E5CF9F4B516C8807A66F4A
-:106270009300EA1DB5EB3F1F0F72DC434248879144
-:10628000ED60FC0B09C8F725C6B89EE5749EA827EB
-:106290007B389F799A9F382BDA21BDB11DF8CC133A
-:1062A0004147E5DDFB4BD0584CE7F37ABC2DE9E4E0
-:1062B0005534FB03F20390072A5C889FE9150D9B78
-:1062C0005EC83B4AE7D5B1FED77621572B47183D2C
-:1062D0009E6B9AF5B3DD4AEFF2A693DB45E1767E3D
-:1062E0006CA7B4303D88B4B2B45A0ED841EFAC5E5E
-:1062F0002B3B29A592EA2D2FBFF222D86B9F9AD073
-:106300005EABDAF2D647A369BE6AAB9C34912DC767
-:106310002AA484F1E3A1FF9B3F2C8C8FCA5FBC654C
-:106320005486B2EF0F2784F152B575BF910CED0979
-:10633000C7A2A6FDC6A0350A7E9A8E8E07BDA561AE
-:10634000D3B746B0BFBED82790D4EC9EEDCBD7BE16
-:1063500085FB22C009F1C9F1D58DBF1E780B4CDE3B
-:106360005D80F51C202F2F85371F97D3353B6D247B
-:106370009ECEA3FC7726FF44C0E76BF7DB613DEDC3
-:10638000521DA3F3D58FA6B8E8F8E5B237C5812929
-:10639000FB5EBEE601A4BF32A12EC581FCE44A37F4
-:1063A000A0ECF6A6C33AE7ACBA1DD7594ADC488739
-:1063B000E5ABC5623F4DBF96C884AD51F8A43081AE
-:1063C000F149FB3A8A5CBACE76D0FB41DFFE8DE81C
-:1063D000DF80F6E97D04E4FF037CCD74A7C4FCD71D
-:1063E00066862F6B8241B517CD3AFA5DFF581BE0E8
-:1063F000E9745F572ACC93C2C1CBE1267C4FFB15D1
-:106400003FB82195E1892852216F47F78322F80E82
-:10641000F5DB6497254FD78ECB4F36FE3C3E3E9D35
-:10642000770CEC6FED2954BF8FB2BE99B03EDC17EC
-:10643000E93EA7A1330DBF33FE5FFF38E37795FF39
-:10644000FD532640F9F90F191F413BD84FE8BC0214
-:10645000A958BEFF3601E5838904A2F1F97A99F3C0
-:10646000B9BEDC43F915FC042A9DD0F94B429C9639
-:106470005EE838098807B4574A57D0F65AFD06C671
-:10648000C57AC6F077CDBE52C6E5427E029507B109
-:1064900061794056255F961E592D132FA89CD59FD4
-:1064A0009AD01EAFDE2217C3FACF6C3EF8D15D94AE
-:1064B000CECF34A97CAB97AB917C5BBE6D8300746F
-:1064C0001AC9B767CAE92E1E8D6FE9F7A87C5B1E53
-:1064D000FC7F2A5755F84D4BD0CB532A1FFB810A1E
-:1064E000D11B1C23E5E3D7A06F25F7948FF4EF436E
-:1064F00052D8930E55FA53E98E6A70FD40AE77D3A9
-:10650000A74A7FDDF4A9D25FE47AF5F08B2CEF0F78
-:106510003612A593E25D54A3A3F8AC6E15FC26E4F5
-:1065200073EFDB7D0A104E2EDCDE88EFED3E49DA9C
-:10653000BC3F22DF1451DF15912F8EA8EF8EC8D7F4
-:10654000E9EA57B71C3412C47F4057CF34FF257295
-:106550003C8A3DA8EE3F9EE6B3462FD04566C8086C
-:10656000724F5E485537F0AFED15D1BFD6A584EC1C
-:1065700009F4FBA31666A77539783E9EE543C9C6A4
-:10658000C520F7D4EF210B41FBBCAB38648FD7D8C3
-:10659000FF475B45BB42CB837E3241EB4708CFA729
-:1065A00001F11D24BD9533BF61578C3D0FC78BC9C9
-:1065B000F203FDDD205AB3E683BDE7139D947CC84A
-:1065C000EC0577DA09A5B3AED601374FA5DFE7BCF6
-:1065D0002382BA4DD1E392D229DDCCE2747C8A7851
-:1065E0009FBF96AE6F562BD3C3672F8B4EF795BCCC
-:1065F0007EA9759E11E42BD5A38F69FDA295641920
-:10660000D25DF9AA88EFAD3F42FEA88CE00F37B704
-:106610001FF6AAFC914FF251BE10C2EC5F2E976F8D
-:1066200010736F9E4AF1D07548242605EC59912CC1
-:1066300086756E16FCE02F20DE64E4B35A124279B0
-:10664000A8C2A903F86870EF72AA63FB1F0B1F02B0
-:106650007AD9F1FBBC9768DAB1E3D3417B20BFF371
-:10666000E3ACDF939EF58BF67D371DF6B3AE7D264A
-:10667000F48B75EDFB65D64390DF6D42BF58D74272
-:10668000930BF8C0BBCFE6BF02CAFB32FBA161EFA0
-:10669000B77941DC5F1721DE4E2530FBE55CEB9FCF
-:1066A0008E084990D25581FEB02F16F9C8B3DB820F
-:1066B000F67AD7DE6F0BDDD67FDE7A6A8DC48DF475
-:1066C000682353B701FDC633FFB167CFA89717D032
-:1066D000F16B9AF71B67D1F2A237FE9207F2B36B08
-:1066E0001BD38B3AE5E01AE224E4AB84B2C765F031
-:1066F000F301336510F274E2C61BBDB9D1E0C2E00C
-:10670000D045E100EBA2702907B9DF1B3C62128D76
-:1067100048EFFF7AF0383B9DC9B51F10F00B85E1BB
-:1067200022B8D8779BDF2CE0FAD9F77DDFE681DC51
-:1067300039D3B400F5954BAD7B48E2BF2A1DFCBDB3
-:10674000EB160297B3EE09FFB2F866F4FF5E8282A1
-:10675000F38CE4839E74BEF3C7987FCDE6C4F95EE4
-:1067600026FF97FF6FC3FB368A77FBA5F1FED8FFA4
-:1067700058BCBFC3F16E7398409EEDFD0BFA59D51E
-:10678000F55F6ADDAFFC0F5DB7AAC7DF64A83B3CCD
-:1067900085D63F4C022B8AE93CDFCCBCE1C329B44F
-:1067A000F497BDE8271F25323BF097A07C80FD972A
-:1067B00026F837A05DC1ECA622C2F6F5A29C32D421
-:1067C000378A729E40BD81487587F3293C6ECA9A0C
-:1067D000E35C8AD5877DE2A6F97F4BBFCE89FEC3F5
-:1067E00008FBB1E8CA1B0F81FD7270019D1F1DE7F8
-:1067F000605FD1413527322E530E98F2303D0AE9C1
-:10680000DBF609586F9C556F3F4D04BB47630FDEA5
-:10681000A8E8CBC7F3FE2790034912ED7F825326E9
-:106820007EA8477C8BB4E7CEE323FAD946754CADFE
-:106830007FED6F859F3989D999BF24730FE703FCDA
-:106840003265F41F5E127E006F8457BE7F29E856C2
-:106850009213E17753460D8727B3AB25DE5EB22E48
-:106860006E03BE9508B58B995E86F6B46A175F0A0B
-:10687000CE84DBDB121F5A85BB9449ED6D7DBF08CA
-:1068800017151F7F2B1E54FCFDBDF8F81DE0634457
-:10689000181F99E71D12F06711B707C69D6F1331D6
-:1068A0009FE994F0FC85DB0363ACF112D803D74970
-:1068B0001F88C09765E65D95708E60760A48D7831D
-:1068C0003B0C68EF980B04847B4EA384F90F0C8E6D
-:1068D00011A0684FBE66E7990709F8935D46A67850
-:1068E00017337FFE9FBFFFFEDA42F0ABB0BF32FA34
-:1068F000BF49D41E9BBD8A0462E8FAE648C40B2156
-:106900000E737C0239A6F307EBF3F0777D4AB89F4C
-:106910004BD5EF4D8EFCB3D39D546E1DBB82905D65
-:10692000903267BFA4B59B7FD0CAE0E5394CFCFD2F
-:10693000512EB8C462CD39DBBF2731F9B1F30FDB7B
-:106940008683FF6C4C576E1C93A70506A04B0FB7B0
-:106950000BCE11250EE215CEB50E88C373C443A22B
-:10696000CD1DC56FB389DBD3FF518F4E65D2B59E68
-:10697000F844B09B4808FDB7DEF5E6A8E7C13393BD
-:106980000C9C6E38DEE89F5808E7166CFC39B46939
-:106990009C166F1D13BF90F27AE201FE8E69CE57EE
-:1069A000FE51F882FD0EF0DD64098E2F8E223FE647
-:1069B00071F84D3EF01DFA3BAF6C5D6B00FABD7295
-:1069C000BD41773E599DC4EDAE616418CC6BF201B8
-:1069D0008BAD00F07248745AE8FA3CAD678DEE2832
-:1069E000E75C91F084FEC18FFE6A123B17D8233713
-:1069F000CD02B8EEF9D24CBC14BFBB8CBEAA68F372
-:106A00004C4A61726E0E69BA3F2FFB5F0FBE63BACC
-:106A1000AC81B16067AE27DCAF11497F04E9F8DCD7
-:106A200046E287FD14EC52900BE73613DCCF294881
-:106A30009E04BB9AF2FB0FB57E9AC12D5BFF03F457
-:106A400080DA56C161A0E5B552D008FE584F4BBC64
-:106A500008FB6EBE425C783E2C3986DEA6E18B5781
-:106A6000932484EFC1D17BEE8671BFEA3012D04708
-:106A70005C6F86ECB06F7FD53A1CF9A0B775FDA2AC
-:106A80009E548E93A11F260F23E92177738C2E7FAE
-:106A90008DE8CE00FE9A6C0ACE7346C1DFC4644610
-:106AA00067972DDFFCFF9FC9B70F55F9E6168B35A9
-:106AB0007C9494CCE85E23DF52A3C9B7B982920AD2
-:106AC000709FBB77402AE075EE3B727234F9B6A531
-:106AD0009E9DFFBD4EF911D2AE662ADFAED6C8B775
-:106AE000662ADFB27BB6FBEBE5CA37FF7F0FFF6D8F
-:106AF00001F91665BDF11C7EAA7CCB6B3D8AF22D97
-:106B0000AFD940148DDFC99C7C29F92624DF06FA11
-:106B1000F021D9191B857EB670FDFB751EB707E302
-:106B2000809CFBB764765E7AB9722E3D85F1C925EB
-:106B3000E5DC7F139C553937773B9573D9D1E890C5
-:106B4000C9B9B9BBA89C13801E999C9BBB9730FF09
-:106B50005B847CCBE921DF08D6AF0DB0F69E96ECC6
-:106B600017EEA1FD0D73C94E33AD3F2C2CEF4668D7
-:106B7000E5DDBF254B08E71EF2EED0E5C9BBED5CB5
-:106B8000DE5139D61FE46B247D385B6374F93DA375
-:106B9000DA37FF02F8E55D11CF173F30B073A0F789
-:106BA00046B517007DADE4F3F170FAEBACF762FF88
-:106BB000456FB2F5D56C66FEEFDA66A61FD6AE1746
-:106BC000FD0AFDE7F8D1DF1961FE157B05924AF356
-:106BD000534CBEE7AD20837F2E13762E4626E66B00
-:106BE000E861F6C82AF4E33758ECEB08E5E3D9127C
-:106BF0003183BFBECA3AFE0BF0D3578D64FEFD2A27
-:106C0000FE9DF0B801350EB2B4E5BEB7FB909EF123
-:106C100003934D0C8F935F16FC6BB3217E495F5E2F
-:106C20001511FFF8145FE71431887021EF8B51E3E1
-:106C3000189E8A84C7210E0FBA7E1D3CFC425478F0
-:106C4000508C4ECC4F09AFBFE2DDE062F0E757ACAD
-:106C500014F0DC578547E43A55F8A8FEE92ADEDE51
-:106C6000D37A1F9EFB47AE5F855F8F75ABF08C5864
-:106C7000BF2F999F7BE593E1104F43E901E587F72B
-:106C800057140E749CE23157A46AE5F1F31C0EC34D
-:106C90007D638AD209C08DD401FD9436DEF7763A41
-:106CA0005DFF884F9461B04D5E33DAE48673D44D56
-:106CB0009610CA3795BEDA557AE7FDECC9A81B8B4A
-:106CC000F67A8BE000FDC213B0201C3D94CE2CB4AC
-:106CD000CAC195DF8CE770749890AFF8BE43E16E3F
-:106CE000A0F5C7ABFB10853BF0CDF0D6B3789E5B2B
-:106CF0004042785E52DB283803741DB52D0C5EAA25
-:106D0000BCA57F562D3EA2D0A3148D1E0938890B39
-:106D1000C3FB6015AF37D9E4FB08CE6126537A5F19
-:106D20004BC278CCA1FF011E23F1A4C2F352F4F9A7
-:106D300039D73FB6001CAD00AF10D3A302745FB0CB
-:106D400085CB3D925707C7A2172F30FADA2B287050
-:106D50009ED00D27A0575A3EA295D12BC04D01B809
-:106D6000B79688902FA5F04DCCEEB94E38BFD4F22F
-:106D70006FC5DEA3ACFFD5829344A15F75DDBDD1A5
-:106D8000EF3F4AB7ED1174FB9E25747838D0ED5E65
-:106D900081F9115AE375E78EA61476EEBEC942E971
-:106DA0001BCEBBDE919DEB949E7C7E81C313F47F52
-:106DB00045E3971A020B80B3C08D668C3FC379F40C
-:106DC00067FAA556BE6EB190E4DB0A7AEFDFC8ED34
-:106DD00081DEF41B353F14C603B9D742C7CB098FF8
-:106DE0001729DF557BFF52EB4A4CF9C7D6D51DBF9B
-:106DF00049DAF0FCC914EF7E2809FD3F2C3EE90E6C
-:106E00001E9F4467807A96A65E5AF288DEEB913424
-:106E100033EEC3F7F3B8F81B442BF1D2757CE5923F
-:106E2000914EE92EFDDB6B412E8FA5FB084DBE3A3E
-:106E30003CE2E37BB05CC4F3A89BDF4DAC8173BA4A
-:106E40009B4118D1EF37E70BB8FF7E009D8D023DC7
-:106E5000D64C5C264EC2B47CE40FE2D16F94BFDE08
-:106E600057A4507E1AB6D1DF00A9B32894F41EC0EF
-:106E70006F8C48007E6DAEC422D8BFEEFF9CE48BC1
-:106E80000AEEB3D8CFB0432419EA8D7625A3393062
-:106E9000AA794511F847A71CB45A81CE73561988B0
-:106EA0005B43BFA389BF01FC36A34EB86E05FE2B22
-:106EB000A7FA02F89DCB5BD736D821BF4A702AB417
-:106EC0007F8FD73DDE4EE7B5A5F1ECF8AB800F69BB
-:106ED0003DE8C6B38AD5F3AC179C102A5BDABA1C1E
-:106EE000E3714AD70BC401F5FD0231B37EFD66DACA
-:106EF000EF9655B43DCD97417BE877FDD90F6F05EF
-:106F00003E3F2CB2F69BD9B975296DA700BDAEBF27
-:106F10000FFBAB58259034DA5FF96626FFCB0FCB19
-:106F20004E286FDEBF12F7B18974BCF46C90F78104
-:106F3000719027C30507FA3B33EF42BEEEE27C4D6A
-:106F40003AA632B921F03CB71B54BDE9400A8B0F79
-:106F50002E752E3026D27EDE1B999C0D61029E96E8
-:106F6000B3781E7D82C2D94DE1FC018FE73838F23B
-:106F7000B831A8D97F3E4B19807438BB650CC6392F
-:106F8000CC21C518E7307914D3D7DEBFCEE217E89D
-:106F9000BCDE974399F0FDE07526D47F3BB7C878F7
-:106FA0005EDCD93788FEE9F6553281788D86552228
-:106FB000CAC5F6CD6C1F1757DF3E3E1DE0B74170C6
-:106FC00082DC3CB8AAC808FB5ABB5FC0F645AB1FC1
-:106FD0004861760C9387AADD56EAA8D0ED1F91F29E
-:106FE0004D957F351C0E9172AE46DD6722E45C0D37
-:106FF0009C37DB21D57FF7102B937FA0F703DE03AF
-:10700000DF21FDD61E9609E8FDC2F18EF118B70505
-:10701000FB262D1FD52AB8E09CBFFC13931FF55506
-:107020007FC98C9F80FCFED4440405E2E029DCA9E2
-:107030005C18690AFDE159FAFD8B0FCC102143E978
-:10704000A404E1ACC68B166C60F12D051FAC482979
-:1070500005388C4B44395BD62812B7465E7C21B884
-:107060006EBD8BC963C7068D3C2A30FA4A61FF7238
-:10707000A43239A86C902166846CE7F289EAD32E99
-:10708000D01B2A762D4F31D27A8B793C48C5DEE56C
-:107090002954349006D8B768FD0A23EBBF629FE0FD
-:1070A00058ABE95F6DAFF6A7F663DCA5EF67C05E8E
-:1070B0009EBFCC7ED479A8E3F7A68F8FFCCF0B2B95
-:1070C00004DADFC8F7450C521E797CE200ED7987BF
-:1070D0009AAAFED7C20F0DC4A581DBC83FC4109782
-:1070E000862E9A4750FEA6789BD4C2F4A1E611479B
-:1070F0008D35059877003FD7723F6DED38766ED5A8
-:107100009CFFC122E0EF890502D201F1BA8D8949C5
-:10711000A8072970BE5056C0DA97D1F6C077CD2B9C
-:10712000191F5279A080BCA85DB57C3CD65F2F2882
-:10713000D07FF3DA12DCE7CB478A04CBD71F45BDFB
-:10714000A3BCE56812F02BE5CF15B0EFD65E6B72ED
-:10715000007FA87CA7F2F1FB328B0F2166C750B8E5
-:10716000075096A244E55FF1306176EA6619F9CEE0
-:107170003392F1E5FB5B44E4E783D7DD391EF8B0D9
-:107180007383D00B1F533E2D08F3A9B89AC5EB9417
-:107190006D62F6CAC1554C3EB437333DB168B53C5B
-:1071A00009F265EFCA84F9BD983E78B9FCDC434F1B
-:1071B000D9189D9F7BE3DFC972D347F7D3F9DDFC74
-:1071C0001A9DBF128657D1F50FDAD14F7FFD345C7F
-:1071D000AF2A874A2516CF34DBB780C5FB4A2CEE91
-:1071E000ED6F9E57C43C1E4BB185E58808F41ECF59
-:1071F000E2A4D7CB48EF91FCF88FF2D13F8BAFB729
-:10720000733A52E723EE65ED21AE2C40E1F8CBCD89
-:107210002F635CEB97AF1E9D0C78AEDA43E997AE17
-:10722000B773B38D04406E497EDC6F2A9B458C1F7B
-:107230002752A0F0569B963F597C52D5EB36A49B23
-:10724000CA6D2CEEB472C7F13C8C175918C2B82B1A
-:10725000EFAB5CDFF406F380BE2B25162715C9EFD4
-:10726000635299FED9B12B762AAC43D8B81FCF5BB5
-:107270002B9BEE9481FEBAE547AAACD6C3734C2F84
-:10728000A55F386787F94D19AA9DDF02C453C72649
-:10729000C6FF952DB2DF02F3DBB816FDD99E8D67D0
-:1072A000313EBEE8F52DE847F0B488FAB8C88D2223
-:1072B0009E63D114CFAB22E3136B9B6BF0DCADB6B6
-:1072C00089C7FF45C4C555BDBE77879782A6EA1713
-:1072D0003FB7833C38DDB6C10EF0A4FD615CE1F53B
-:1072E000E7255D7C54EFF1C02E7DBC61D3E33CDE2D
-:1072F00070523BC9EB196F781AFE01FB4D6A44BC12
-:10730000E6C6441EDF1D282C8EE2CFEFBEF7B3E5A4
-:10731000EB351027DFB1EDCC1A987FF55FBF5A032C
-:10732000F14D649F05F729CFABBFC5B862B5DD82CB
-:1073300054466F9D9B7E8E71D99D9F9AD0DEE9DC6D
-:10734000DB9E05F16D9D5BBF4B01FFDCBCBD37A033
-:10735000FF72DEF6A2541245DEAB29D0A7FF32E25F
-:10736000C223F171B0F920C6617DF98909E55B7727
-:10737000FC68530D8BCB5578DCE8E6E871F86A9C25
-:10738000636DF3AD375F07F2BA99E977DD718F97D7
-:107390008A17FD90E2F5EACBC0DF661E17DC3429C0
-:1073A0006ABCE897F00F8AA79FA5EAE345BF6E9EE7
-:1073B000F3B317A1AC39B1D778D1C065C04D8DF307
-:1073C000AF4E75BD9A0A7CB42DD69BC6F0E69F28B9
-:1073D000801EF87516DC8F382587300E24B4D7E46C
-:1073E00080B8C7CABD1F23BF746EFF00FDAD84C740
-:1073F000D97792EE3F160F2DF075AEB7B138530E18
-:107400007F884355ECF89DC79B323A56E3507B8BFF
-:107410003F0DA6F2FBC3FCDE410DB59B589C7A38AC
-:107420002E551809F83AAA8BEB55D71DD99F83CB57
-:10743000D1705C75F4385F358EB027BED8BEA2C659
-:107440004D77AEE5F1D6F47BE630889363FBB9C7A0
-:107450002F7C1C0DBF6A5CF5EF23F0ABAEAF37BEDF
-:1074600050F9F352F3FE7BE1F26E2AF367ABF0E9D9
-:10747000F8737439FD0DE7776AB77E9DAAB16F671F
-:1074800070BB55859B3ADFC54D4CAFE8D8C8EC873B
-:1074900048FEA6EB71458BB397D298FE5BDBB23FFB
-:1074A0000FE450C7815D9CEE185DD76E3ECAE27452
-:1074B000A9DCF66BE536617EE4C8FEECBC3F4F6BA1
-:1074C000F4FE3C9BCF46EDEFB4E4BA13E67FBA8DF1
-:1074D000E951A79BC409FE28FD5FE0FB52F7BA6D96
-:1074E000468C9712ED31A84FCDB38DFC242E095256
-:1074F00023C6FD342CE071428F38D300CE0DB69BED
-:1075000008CCE751808FC6FF203BDC04F43839AD4E
-:10751000B84054C2F355CB8D4906E2D7E25F0A6406
-:10752000827C3F92DF2E437F9F45F84D3E93C8E219
-:10753000543AAFCFBC827381D2BBDEADE6DD0F8B98
-:107540003A3F47AD297404F477F28605FDD6E23E52
-:107550008B17FD666B2CB8CE83DBBF7D05E0D5F9BC
-:10756000331361E7089430A85C28E3FE8BF6EDDF67
-:10757000AEF913E899D0988E5FB686D607FD7A7378
-:107580002CDA035DDBE2F2509F7CE3A1C92037CA0D
-:10759000600F033DEFF5547F03EDEF6432CB9FDCCA
-:1075A000D217EF13546DB361BCE1C1ED3B6B41FEEB
-:1075B00077BE1E0BC7D1E44B39F857C87BF6C49190
-:1075C000B50AEA818A76BFAD2092A2D5F3AA20AF90
-:1075D0008B7F2168A7A33F8ED273554B1CDE1FD132
-:1075E000D4E3FCECCD60F7650219C077549FD48DCD
-:1075F000A396DF96D69FDFEF0DFD98BDAFC0EA7B67
-:107600008CA15296F76530BE6DC3FA252ABDF2F201
-:107610009EFDB2FA33D2FAEBEAA9ED6B4DA42E1A15
-:107620001F54A709FC7EEF5F06477BCF22CAFCF1FF
-:10763000FB0302F11A400FD86AC138AE6A636010CA
-:10764000C4B7EF30B2F3916A7B6010C4B7EFE1F2D8
-:10765000AF3A86E6E9F70C3E0FA80F79620EBE0638
-:10766000F8AED969214BC17E7FC3E6023CD7ECF866
-:10767000F6E44B0510CF168B7EAB9A37FE1DF15FFB
-:10768000630A4C07FA0F6D359175B47EC7D677B291
-:10769000408FE8900359091739F7A96932E9CEB14B
-:1076A000D5759CAEF70F84FBEBEABDC5CA5EE4C599
-:1076B000DE34A68F2E4F733D9D867C6D75A0BC86F3
-:1076C000FE44E8A76580F65E73A5125D8EAD4A9311
-:1076D00075F768C5F03DC555D0EF9724B83883A23B
-:1076E000A44608E1F979E5C6B343C11EFEECA757ED
-:1076F000E1B9D667C6D05090DB9F6585866AE5F113
-:10770000A97AB322C9E897C0B46BEDD9D20C02F1C3
-:107710008396A9D1E4D396B4589C47E5C3B151EF01
-:1077200083EEE6F4B61A6830998D0B7E0875DCCFCF
-:107730008C7E23CC23375DC1F2CA4CBF11BE576D7E
-:10774000DC3540F7EE84E4C37A94BF101E156485DF
-:10775000B1C0DA53AE54CCB72A12DE8F96FEAB9B83
-:10776000DEC4309ED0C909716A1C877467423FA885
-:107770007A1F40928BCD002F2329764822A0DA87EA
-:107780007C1A439A30B5527584ED437504E28A4EF3
-:10779000F1F35B93A43C0DF2C3744844797E29B89D
-:1077A000FD32CD8EF3364975C4897AC74407E8D5D2
-:1077B00082D74DBEA7F4D050BF71C00976FEEF82CC
-:1077C00038383B61F3B33BDEFE0EF4034A6768676B
-:1077D0007BAF27FE063A9E6464793296F8A39DC774
-:1077E00077703C10EF7E943F5612FE0BD17C2C4AF2
-:1077F000283A6EDC5F47829D6B759000E84DB1566C
-:107800001288A5A935573AADE55F3B61F9FE949C16
-:1078100041AE39AED59747D235714AE7BBE5A2886C
-:10782000EDCF47B43F7FB1F62A3C3CE601D9ECFEF0
-:107830003B834B0C5F8377ACF34210E09167773664
-:10784000001E8DA1230F013CF2ACCC4E4C6A245A91
-:107850003B6E403A93578B04B65FD2BF62ABA63FF4
-:10786000E230A3FFF4710EF7EEFAAA5FA5477D8B15
-:107870000470ED51DFD25BFD98E8F56DBDCD273684
-:10788000FA7CE27BE9DF1BBD7EED1B1FBF1750E0DA
-:1078900023931B1231A8F7A007A483BD157724A555
-:1078A0008451053B2788C05B0CD01FA58798819A1F
-:1078B000EFF07FB91AFCF58F827F1240BA2BE1F30B
-:1078C000A1796B3A9DDF5D7CBAE3D6B373CC7BE6DE
-:1078D000313FD25D0FB3FB42477FCAEEEDDFD3C825
-:1078E000ECED7BE6B3733352CEEE0139E87F30DE48
-:1078F000BDD009C5F7BD3EC11FC886777022F4D739
-:10790000EEF7761E90A07E49843F46A527F5DED28D
-:107910002CAE5F6773FA9C434236E0FBC87BF4CD24
-:10792000692C2E8D9A632E58DFDD7C7DEA3EE05D6A
-:107930004E72E05D00D110E384F31191DF5B257698
-:1079400023BBB77A5B824EFE9CCB51E260BF236FB4
-:10795000F2EFFC3DA2B9372AA9DA7B5ED285587CCA
-:107960007FA44176A6815C942FFC8828942F8C17E5
-:10797000061045730F8DEA77C8ECB283A01F4772DB
-:10798000149332D00BE3399D25DDD4AD87BD4FE193
-:107990003277B982F760EF4C67FBCBD28CE239408B
-:1079A00017A27DA4D36DED8957EF76B6BE06585F5A
-:1079B00076CF7937189D4ED4436FA21A04FA7B9C78
-:1079C00066988F68523E56803F7F2D13B0FF7BC272
-:1079D00081E1F35C52821FE25F66DB971E01BA5DB4
-:1079E00056EFC073B425F539982EAD4F433D7471F1
-:1079F000BD1353152E66A7CF2552389B07B2FECC78
-:107A00000E37D333E83E04F11792A32E0079736644
-:107A10001D01FDD7D20D1F1FC2C7D89D7763DE049D
-:107A2000799ACA8D1311BEB43D29033F6A867B192A
-:107A3000C0C7A25C49140D5D98D286E9F23DE0A66C
-:107A4000D2C71606BF2705461F91F07B526E53E042
-:107A5000FCF9C91BBBDFB541F851759FC1EF57EC6D
-:107A60007CAE57F83912509F9D5DB8783AC4553FA7
-:107A7000C1CF211FAB1F89F07A1CE2BA06837DE0DB
-:107A8000C25404F8513A32E57A8948DB9B143667D0
-:107A900093B5D8652860B40BF013AD0C9EA6B43A2C
-:107AA0003C8F335B19BC44AB17E1225B19BC442B00
-:107AB000A33723CF4B00BFE1D81EBF53F835A78FA4
-:107AC000003C8CD6C1CB9834F6F2E0B792C28FCE90
-:107AD0002389F357241C92E09E426E98AF7AD3EB31
-:107AE0009EA3EB877DFC050A1F48937BB11F933350
-:107AF000981C4D32D4ED97011E0984EF2F5E9259E8
-:107B00004858A822FCA57989027981CD83ACD7E3B6
-:107B100055744811EFBE292F001DAC784736C03987
-:107B2000A938FF47BAFBA4E25457BC82F0740BB0EB
-:107B30003F3F51AF20FE96031E07C3FEC8ECB1477E
-:107B4000393E1F033E41FC32FE7892F3CBD39C4F6B
-:107B50001A9CECFEC4B2092C2E2B29DFC0DF430B8C
-:107B6000106DDC53BCB38918E9BC50C756300DA06A
-:107B70009EF189C97F056D179B4B5C4027F19F3CA7
-:107B8000E8C7B592E274D08BE2B9FE4BAE55E2A7DE
-:107B9000E145DA80C4EC102A0AD1AE6933447B0790
-:107BA000ABC179C00C7ED3DEE6B37FCA0EA4CBD2C4
-:107BB000AB313C9824BA8BA7CDA1796B632CFA0723
-:107BC000639DEEC24781CF1B6D48A7563AFF320D29
-:107BD000DE637BC1EB8B19371A32281D8AA0B451A2
-:107BE000FC3ED338C002707E4E2E4E07F9FA1CDFE1
-:107BF00067290E14ED3954079793F6822B75F6EC2E
-:107C00000AD985ED1CD7EAE5C00A2E7713C6E9E943
-:107C10005D95BB1F75CB5D7732CC27E5C238E4C7D5
-:107C2000A45BA2CBDF06D9E88577051A86327EF7FA
-:107C30009618D97D989EF200FDDAE7DC83D6813C68
-:107C400055E96B2161F2C74B629CB81FF177745400
-:107C5000FD7809BC37C8E52CA4E24023D24DCA3DCB
-:107C6000068CCF5BC6DFCB7A8AD217A43E4A5F90E0
-:107C70005E97C1CE33169A87E1BB6D0D5603CA0BD2
-:107C8000E95393DF0AFAEAFE510EF02348B2B3CD6E
-:107C900005FE409BD4B48E40BD0233BC2721C417DF
-:107CA00038800EBEB1CDEE77B1383C8A4E01E8C8BF
-:107CB00091544C8EE5E2E901DE7B911DB710F02B6B
-:107CC000BE90546701B8E56630BBABB1A410E14883
-:107CD000E13B362339DC4FEAD49BBADFDB826E5FAF
-:107CE000E8E5FECCE40CAE47677AC9400DBF370A21
-:107CF0005C0F53BC2447C3F70BAF184FE05CA927B8
-:107D0000BFF722CF363079B648882ECF54FD539531
-:107D10006772849C50D3C5FD26E8EE7719939C408A
-:107D2000BB907A0D144592F7EA27EF8E4738CC02C4
-:107D30003890B49BBAEDDA1FF607BDB2302ABD45C4
-:107D4000CAB1D9DDFBBA2B05F0744A5652A7013DE2
-:107D5000BDD3DBBEEE2A453AF4F551605FDAFFCCC5
-:107D60008FD0AF73E2199B0272A8ECC2E3B83F94C4
-:107D70005E18856979E38DB89F0BCF4E2A047A6827
-:107D80005F7543DEA7E0E7F1D970DF6E6F2C1A84D0
-:107D9000E791BE5805E23BDA1B697941B81CE2C5A0
-:107DA000454DBC0001EFBBE6FE372950502F55DF93
-:107DB0003DA3769D7D34F885568B782FACF4599B86
-:107DC0000BF4CFDEE8AF7455747F00DE614AC70163
-:107DD00073408FDE6F1F1D0AD07E67AF63E7080D0B
-:107DE00046D7C900E84DCF58F01CB22121FABB207C
-:107DF00073326E580672604E86EB39C49395BD534C
-:107E0000DA3B3FB0F14FC221339C63BDC8DF4791DD
-:107E1000DCF629BA7336768E7592FB5988B997F2DB
-:107E2000185EAEF4526E67F122C411BD5CB53362C8
-:107E3000C3764613ACA3A6F1CCE24F115EDCCEE0D4
-:107E4000F33E25B3799F7AC5E45F1885FE4FF1F8BC
-:107E5000940A81C157E58353DDFA911BDFC389A4DE
-:107E60005361DD901746D17EBF3A24E3BE514DE900
-:107E70000BE96ADD288C8F179E19F534C40D9F3FDE
-:107E80002C6279E5050B96773CE27C01E29E42EF9D
-:107E9000CA04E4D3F94337C4313F91DE8F7D6F1FAD
-:107EA00026178E71F9507AE109A4DF6E3AF1CD31CF
-:107EB00002FF955E788AD1F74601DFAD24DEEA77CE
-:107EC000C70CE4F4391ADA574C5A08F0BED687E7E3
-:107ED00024651B4C4ED00722F17C2C43D1F93DCABE
-:107EE00082CBB05F42F5AF24CD79FA291E675C766C
-:107EF00081BD57481C5E9206FCC0E553988EF5EF95
-:107F0000D07658A2FBE9CF71FDA7F4C2353A3B23E6
-:107F1000BCBEEBF17B29DFFFCB82A3301F5ECF0B12
-:107F2000A3A2AD27BC8E6BB17E477CF4F1D3399C04
-:107F30004FD6971317956FE54656AFD4F78011E4E7
-:107F40004EE9AAF80441B3AEB2C62A5D9C47D9AA4D
-:107F500012E34C4DBF613C2C7E778C14C643FA4B28
-:107F60000B262DB4825E502CF7017E5A5751F81320
-:107F700005FA63F2E90BD99705F2BABDF17E7BB43D
-:107F80007B13E97D22F0D3C8F143F5EA020D7E545C
-:107F9000BC44B63FB9B6ACF027E08F5EC95E21E9BC
-:107FA0005DFE44E02D3B3ADC8675C32D07E38D2E44
-:107FB0000DB7AB7471453DE0C6F1ABC245FD4EF562
-:107FC000A8ABFA8C80F108BBBFD3C8F07F297885B5
-:107FD000C7E5F81F137D1D53BBD7319F7829A3CE6A
-:107FE000BEE43A1E225EF345D6A1E29FBCA2C3FFC7
-:107FF000D497D6221FAAF89E7D6025D2EF6CCA8F37
-:1080000070DEDFEE7BC01E2DBE686A6F781FE8252C
-:10801000B985FFF7F0FE85ECCD82B832EF720BDA4E
-:1080200023A7D63D91A585F39C8C31F7025EC8FA53
-:10803000E4CBDA3FBC639D87C0BEF43E23A33F6D13
-:108040006B86BB0CDA97733B7C51FCF841D1F4830F
-:1080500047EB0F0D013F5D437D1BA632D72F09E88B
-:1080600097D9A82FB9A2BDEFB5A40F932B8FD6B780
-:1080700031BFA7D94B1CDAFBC484E94FFF4598BF39
-:10808000466D6794DD0EF09F1A05528C7A9FE45E70
-:10809000925D007E8FA47CAF067E8BFBB0FB48CB4D
-:1080A000D20E38E03EB189F60FFE1C73A6744E7FE7
-:1080B000CEC9F2F9C2A722C437CB494D04FDA1B9FC
-:1080C000F4BB06DEC6A4369D7F3A120E92D98EE727
-:1080D0004D1261FA9CBA7EFA05F7A5C7F8BEB482C4
-:1080E000FB359FAF6F42BFFFC2583BEE7F8BFB1942
-:1080F000983D6596F0BD1A533CAB6F8C63F3B68028
-:10810000DF5B847D3580791BBCE823E2D36802E421
-:10811000E38922403E910416E33B2963823F86EFC8
-:10812000CE34B71FF0F84D7ADB1101FCD8C5EEC193
-:10813000B0FF368ADE7C85D6FF9918CA877A59B493
-:10814000E8930496F6837868B7E65C8BBD13AA685B
-:10815000FD8291F97EF3A588F39E3F0FD6962F4FAF
-:1081600073BD0EF368B0B07786928E0B789ED360A5
-:1081700061EF0D35D8EE88837DFC577D98DE8E74D7
-:1081800000747488E933E724252E81F94995377501
-:108190007E7EB3F2A6661C89DB7BEB295D4A9A736F
-:1081A000958192CB007473858F7ED7CE338A3F2E14
-:1081B000C18ACFF2463DCF51E70771FB0047F1C2BC
-:1081C00078B4D722E9614FB79FD92B023EA7A9EF18
-:1081D000174B8B583E9EA87F687F7DDAAD8F2E624D
-:1081E000797ECEE999C9CE311B4AE2303E4E9DC719
-:1081F000B4D6C7DA404F9DD69A3E0BCEB7A65907E4
-:108200007D0EE91E39742016F4C00704BC5772D7DE
-:108210006FDF946369BAFDC375789FF9732E4FA71A
-:108220009310BE0BEF260E7ECEEEC7EF338993E799
-:108230009B64B0EBEF09F86F9F4473F7BEE99F04AE
-:108240006ADBF443A1B7400CB89B1CE3F10C416D11
-:10825000D7E27C9BE559BBEEF54B665C4F78BD667B
-:108260005CBFBA3E3A53847F377CF87B4D2A3CC4CE
-:108270009974DD945EA6C5DD7113B9885E3ECD9A12
-:10828000F3393B3461F38984CF7928A2FA63471F1D
-:1082900017C9A4F8FB7D1F970069B5399425F547E8
-:1082A0003E91215F2BBAFB41E8F3977DDD8393017B
-:1082B0000E6D8997253F8F5818FF1F017A8638AFBA
-:1082C0000B49B82EF51DFA830FB6DB40EF5CBCFD01
-:1082D000637C67B9460C3E7927FA4345B49BCE359B
-:1082E0000FBEE8FDB323E0A7A2FB5FDF4CF59E25A0
-:1082F0005BE70C89F1C98CE6588CC79F315FD4BD10
-:10830000233D633E8BE723525BDE6D3A7D7D51AFAB
-:10831000FD80BF20B29F59F38BC8F1E1704EEB187E
-:1083200083FE83358CBE668D738910EF3C7A89801D
-:10833000E7ADA34E282D419A9FE58F77027BCE7A39
-:10834000F03F07C03B07B56DCC1F982ADE97FF08AA
-:10835000F8590EB07D1CF2F7019D585D8A55735E89
-:10836000D021D7E5C37B7FDE7BAD2EE0FF92DB5CC7
-:108370009FE27BBEDC5FA1EEAB3B1B4B304EB6E415
-:108380001E6524E0BFA4C9E2C2D44CA4182AC74A7F
-:1083900024628634D548240BA431C40C69E142F62A
-:1083A0006E7769E314D40FEC238B8DF01E6F49EBCD
-:1083B000CFBF86F6655260BF9017864F49EB3BDF13
-:1083C000015EE7B88A319EF1AA8D469D1D38B449F9
-:1083D0009FBFBA459FCF0FE8F3C30FE9F31B3209E4
-:1083E000D2D14CF3ADB900AF037B4D742F82F83F6F
-:1083F00013C6BB1C13187EBC9B2C280F8BAA5A0BD0
-:10840000C10E3EF39ACD0076F49EBFFC02CFC3436B
-:108410005B6209C459EDFF5D0C898178C5D72DEBEE
-:10842000A0BC8AE20EFC9755AF5BD6821DBEE34A24
-:10843000D58EF7E7C17A76FC95C5D7843699FC705E
-:108440003E7E66D7CF5F83F3B4339BFAA07E754C34
-:10845000F01A6260FC2F98FF33C8DF8B0BF2F7E253
-:10846000AA36EAEDE2B9994CCE04175E13174D6FA8
-:1084700052D39CB4C4DC71746E5D8F9B66801F68A0
-:1084800070A31E2E6ABD217EFDF78778FFA3893178
-:108490004CA7D91027E06FB0C3FEFB72F477921798
-:1084A00072FE79F5D5EE76227F278E289A7B53616E
-:1084B000F94DE6F581F80D807FFFF0F72AA2998F3C
-:1084C000463F99C0FBFFCACCE29993F8FBFDA7EBAE
-:1084D0000FE1BEDFADF7D5BB5CE334F9D2C6FD29B1
-:1084E00025603FADDA9F325303AFEA4D0753EEC626
-:1084F000B827093CB8A47ADA2B4F81BFA27A93D867
-:1085000004F38472805B47D35B76A847F5E161E0B2
-:108510000709EBA337B8C669F8F86FA55B95DFAA22
-:10852000B9FEB27364DB788853AF6A149C50ADAA6D
-:10853000E9F65B2701BC57B17BAE85122916297F6E
-:10854000556FBDFD4743216E66F50827CC877671D0
-:108550001B7CAFDA7C16EF332C8DF8DD0335DD9D07
-:10856000C9F4425A3F60A0F597DE612D07F945FB3B
-:108570007D13F20772D6E1FB2AF653ECFC817EFFF5
-:10858000C440F5965363BDEFDD4D9B9E214D1F4DBD
-:1085900002BF52A39E1E297D0BA097853608CE757B
-:1085A000F87561E12DA072BB1660BC2F2D9F11EDF7
-:1085B000BE75855FDF4F24DE3FE2F3A57F395AFAAF
-:1085C00089AC9738D18BF1E4D5F3A93CD4F809AA4A
-:1085D0004FF8F07DC9C8718896AE993E41149087D6
-:1085E0005B2CEAFB4782B990C7E90E60797C571192
-:1085F000E894124AD595649C02F0BE854C80743490
-:10860000C815784F7F64531ED4DF2D045F7909FBB2
-:10861000B3A11CEF7004F09DC90C7ECFB44361F987
-:108620002EEEE754CB2B5B2D186773E64B23CAD98C
-:10863000054D07318EBEE3358BC140E5C199AD894B
-:1086400063211EB3A389BD537CBA2971ACF122FB0F
-:1086500076A4DC50F7D3A3F04FBAEFFE29D3F54D43
-:1086600026EC538B58BC6A6A625D7EB4DFBF50DB78
-:108670002519EBF2C18E09DD6B75AE433879B32550
-:10868000F483A739214EA84460FD1AFB158B7D6940
-:108690007D1BAD0BFEE8844322FE5EC371D1F963FE
-:1086A000C7007C4F1EF5A0D9056E7C9F922C62718D
-:1086B00095B324129028BDCD82FD280FF32897672B
-:1086C000AD1230AE6CF632FD7AE09D5CED3E5A4163
-:1086D000FCEC7D0BAD1FB13FC4BBD0FD06DEB53455
-:1086E000B3F88BCAF5FA76552480F3A9DEFCBD29D0
-:1086F0001ABCBE26EABA5C99B02EE11633CEEBFE68
-:10870000E7E2D8798F91B8603F0D3D6743F95E4548
-:10871000DCD8DF5D7C5FF73C58E29A0D7278FE2C66
-:10872000D7EC44B86FCBF63F34F990BF05DC77AA9D
-:10873000C691405FF6EE06817DB5AA55080C85BC52
-:108740009978EDC3D877787F00D6ADBD5F534E7C66
-:10875000385EF92AFD77F221C36B35BFC748D66B67
-:10876000CAFB837EC6E051BDD9A4F3EB8CDE2C7826
-:108770006D78DFD5DF9042E7577B8ACA0A0271AA7B
-:10878000DF9B74FD433CCF08DCF78985E2EDB96ED1
-:10879000B9EE1F122DCEFF0887E373B797A603BF6C
-:1087A0003E0D7A6B0607F448945BDC7F4002663A24
-:1087B0004ECCF0EE3C96172E64F9C9AB5F99DC788D
-:1087C0002DB5F364379E0BCD128BDF86FB602FF740
-:1087D00073DFD2978E33CBE0CA92906F5D83D01F48
-:1087E0003A9FC1E185617543EAA2E8812A9E9F17FD
-:1087F0009A02702EEBDDC5F42F5B4148D6EEAFD563
-:108800007D993C8A3B10C47B13A1ED02DEB35C2949
-:108810001CC5FB882B6F5408D8F769144F208F575D
-:108820000A649140E152D03CE5BEB700CF05314E1D
-:10883000F8B98B9AE631628D15D7CFF4B4D8BAB5B2
-:10884000709E933A236718D0395DF78C5BE8F7FB8D
-:10885000FA2A385EBA95E13D6DA1371B7E072AEEF4
-:1088600040F17D6F011F0E8DC17BB2A91456B60475
-:108870004C9780FE9546160850EF393BEB3FD920C8
-:10888000CE9802F9612C9FF0B0E05A87C4B71CFB68
-:108890004F359109304FF80E7AA419FC0A58EE674B
-:1088A000F82DAACB87FE5207B034C918C8847E0EB3
-:1088B00077E3DB8D76C53CBE8FCDDB3A2615ECBC6D
-:1088C000C31DD4E0A672EB709AAA0F05ACF8FB505A
-:1088D0000373587D6E17CECB67F70D92B2F4F5BADD
-:1088E0006457DC7090A31F303DFEBCD585FEE96B5C
-:1088F0008CD1FD592FF5657A8BE78240FC9A7DC0BB
-:1089000033F51BD42B3D1724DDF78E7AB32ECEB969
-:10891000BAFC00DEBBAF216D18875DD314AB8BDBD7
-:10892000BD2626FAB82A7D7B2E88C41B755CA3FE63
-:10893000FB8544E24D8C562F45FF9DAE43976FF962
-:10894000B67B1DF09D8C0CDAC11E9CC8F5DA2EBFDB
-:10895000C12B5F1DC64BA723A8DB773A1596EFE224
-:10896000E7716AB9DA7FE75423BF57C4DE5506F8CA
-:10897000780713F262EB59F44757B7EE1FCF7EDF4B
-:108980008BD185164E5E8DFC4869680B18286FFFE9
-:10899000A6EFA9A7728750123BA0F2F1E9A75C9459
-:1089A0006F5344838EAF630BBAF91CC5CB7306912A
-:1089B000CB85334F8DBB569B67F5C3ED3B268FA30D
-:1089C000BA7D412E6BFF87BE5FBEB77060582ED157
-:1089D000756415DB34797344DE4AF34335794744D3
-:1089E000795244795A443E93D5EFB005B2442721D9
-:1089F000ED7DCF4E9646C13976603ABC28B0ACE1E9
-:108A0000ABC9E368BEA6A00DE3676A5B05271EEB52
-:108A1000ABF1F14EA667599D41FC3DBBD882B6B77C
-:108A2000410E54B7080E81D2BBB5692BC6D554434D
-:108A30003B45D3AE89D99DD54D47B15DAFFDE71814
-:108A4000909F97E61CC37AEAF9D19DA4FBF73A2ED2
-:108A500080BCAC696A67FB70C4F95167BAEB20CA85
-:108A6000C388FBAF1EE8D71AA67BB5FEEF87B6FE1C
-:108A700016BA899D77768144EBFFB1A67D04E84B59
-:108A8000F0C625C8FDE705FF10D89F5F24EE21B092
-:108A90001FDD5B73C57E03AD77440EAE86A71A0655
-:108AA00065596E96A89C3E620BF615A82CC9599381
-:108AB0007833C0F34872105F68F8E99A2456DE37BD
-:108AC000D817CE5D73B37EC8F257045743FEB63550
-:108AD00057B2FCD0605F91B6EFEFBDEA6680FF064B
-:108AE0004774BEED9BC5E4B93ABFB27C575A16E84D
-:108AF0009BD56CBF80EB97662A17A7579EDEB28185
-:108B0000C261FA4F62515E6DE8B8F5A6625CBFB70C
-:108B100018E2DCD813EF7C3F43B92CA11E900E7BEA
-:108B20005842181FB6AC3605E5FD95755B61DF4F01
-:108B30009D9E8BF2FE7CA6AB3E6B4438FD76004BCF
-:108B4000EBB3D87D8F54D180F106A90FD9500F7A9D
-:108B50009A9F2751BE41FC5A393E866531F9372C20
-:108B60008BD949197D6FA887F5DCC5F5D3158FFB27
-:108B7000375928FC7F07449284FE6DD477EF5E4B13
-:108B8000E5461CC453B8D2411EDC0DFEDFDC705E2E
-:108B9000D5DF57E4D3BC356CA7AD98E24AD7C60100
-:108BA000AD58CBCA5579B3229BB557F79DD406066D
-:108BB0009FD4A787AC8375C44A04EF5FCC993A6809
-:108BC000DD02DCBF6FC1F912972B1DECEF1315FD11
-:108BD0000DA057AAF8792CDF3511D723B278751577
-:108BE0004FEAF8F57CDDB344BAFFD3753ED4CF8DA0
-:108BF00070A4FA401E0B2E60FA403D386293C3F019
-:108C0000255270047CFF5F04A7FB60DDFF289CA257
-:108C1000C88B9FC2B835F3A9BC3068E40587DFF381
-:108C200042404E2DD0BC5F42BF831D78675FF7A3E3
-:108C3000599A739CE90FD5A0FEA7CE2BF6DF774E8D
-:108C4000B893F4E4B348FDECC8EFCCCBD00F686C1C
-:108C500042B978E426E25C00F2839FCBAAFA65E190
-:108C60004FAA0E831D752E4BC4761615AF42F1D652
-:108C7000520AA7C7E9B60AF7D1BD53587C8FBA6F1D
-:108C8000AEE0EFEEAE78F02A8CF3EB2241FC5D36DD
-:108C9000EF4882F2AFBB7CDA202CA7F8F65A80DFCF
-:108CA0002B62F0770756E413BC67B362DA9558BEBF
-:108CB00047F52B4D33E3382BA6307A5A51C1E230B9
-:108CC000611F01B8F5460F290DCCBF4124579E36D0
-:108CD0001EE05D8EBFD882E0F68F41AF5C6641BD7D
-:108CE00012F64E3C1FF1A5E27814AFDBB390BED96B
-:108CF0003C663D9BEE5F8AE33AD13E7FCCE62A415B
-:108D000079F548AC02F35F65214BCCC3C01C218BC5
-:108D100050EEF1F910DF0B18E73183EB6B9F959F55
-:108D2000B3813EF02697374030602FCF24AC7CE6ED
-:108D3000C3B147C1BE99F9B088F70BC9921B5CFA61
-:108D4000F30E3AD714F08FF3BFC6900DE0E08676AD
-:108D500076E8FFBF6CF09E89FB6176BF9778697BF0
-:108D60004D3CF4C7C0BFE06717D9FC497DAC12ED9C
-:108D70005DD08FB97CA7F37769C753C789EC97DAC1
-:108D8000779F00BC28DC03700F2CF488C87FAF5598
-:108D90003FDF2463E8490B2D9F5E2FC62FA4F0749C
-:108DA000CFB7E17AD5F9CE480D5DC77E1756DFFF04
-:108DB000C9D8DA42F087ABF60879586F8F815FA285
-:108DC0003B2F629C34DA353DBE737B36D20E24E4F1
-:108DD000AF266DBDEE7B1A8A10317F4E578A200177
-:108DE000DEDC3C7EA11BDF11F356E169E8171D9E16
-:108DF00049C6605F905BEEF9268443647B75FF7B18
-:108E0000C142BC6027360A02D263E383B1B89F1126
-:108E100033C3A3A7324601FA7CD118C23826EF6EBD
-:108E2000F6FB9F5D96D00E944B03993FA1EB3D71ED
-:108E30002DD4EB4C6674DDB94BE6FC44D83B12EF05
-:108E400089EBB05C60FD762E88C5F828B8FF698490
-:108E50007B99DE3FD5837F45B5E38FEF60EF29C077
-:108E6000EFF668ED60B8375B3E2C2C1FF07D18E004
-:108E7000E79658EE277257E07877C71088C3A83571
-:108E80000818D75B5B7925DE2321FC1DE76A3EB518
-:108E90005A03B5078785F9BCD6706C10D853D5E650
-:108EA00065F8BE332D7F13EC30F899DDEEDFF1C8A5
-:108EB000EE49D7B5CBCEFC05EFB537EBF15F1DA67C
-:108EC00013BC1F57A9A59BEC303DA0BE0D72621CC0
-:108ED000C17BF9369E8F9DD0E6073F8D87FB2D9293
-:108EE0000FB0776B6D054D04FCA69E534CDF18DD6B
-:108EF000BAF620D8BFF113DAC0E2A2F599DF2DF25D
-:108F0000FED0A8D6E522D875AA9EA2B12B87DC3266
-:108F1000549BB2FBB660A7C27841F804FC21B1FDB6
-:108F2000ED79BEBFD17D10E5F11CDF60DC07619FEC
-:108F30000239A6DAB920D7408EBCDC6FECD47E743F
-:108F40009D79CAD85BFBB1739821A8D77B2FEFBC62
-:108F500049AD07F6EEC5FD610C6EA195714C4EC092
-:108F60000F80829FF8D7F25A7CD71B042F9DEFDC2D
-:108F7000D5D92877553F4D35F7539572BF4E29F710
-:108F8000EB805F551BF70A7E4B6DBE9AF37D0DFC9F
-:108F90009E14BE17600AC7BD823F671C09D8A01C7B
-:108FA000FC3A7676BF4EDBDE43FC4512D2F9F7265B
-:108FB000DDBB582BD87A6770BCAFB4307FCEE88762
-:108FC000D78ACC49C5D61B37CC95FD6841F87DAE14
-:108FD000CF399E54B818FB8DBD17E01E23B2F7CDD4
-:108FE000438FB2DFBB3E41F7E7ADDCDF718B15EF9E
-:108FF00017BB06425C82E4C8BA25CAEFB62EDD6D07
-:10900000C177FA97F563E7C1EAF7B1FDD8FD5DF4E2
-:109010000301DC17C4A29E4DC19C077454D85FDDC8
-:109020002F491EF89F8EF2F8CEDA3BAC6EE82FC8BF
-:10903000FDE22BFBB17D6B653FF6DEBF9AEFB6EB31
-:1090400038BDA8E758E08FD1FAAFFDDDF599FF44B0
-:10905000DD5F9FAF8841B914A65B03DE9F8CCD2DE9
-:1090600036821F6937972325DC5EDF0D07B4204F5A
-:109070009AB8DF59724C87DF05DA7D2A17E325930A
-:109080008C4CBEECBE2B8640FCDEA1D3AF3EF11E65
-:109090002D3F77CA88EFE1CDE6FED6DD0271C178BB
-:1090A000DEED26F423561B99BE58BD6F28D3538C92
-:1090B000EE9510D7EDDD26A35FABDAEEDFF40A966E
-:1090C000A73B2966E13E28D37377C5B2F631FEFF90
-:1090D000780DECCE7DA94E2FAD3F3FCDBD0FF09A60
-:1090E0006152E2887AAE2A84EF8B1EF333BDF81802
-:1090F000081E18A7D5C67F47CE953E87F673FCF1AC
-:10910000545C0F95B7A83F1D7FCA84E766CF778F61
-:10911000CBFC9FC7E4627C2FE6D8F67C27B52C49B0
-:1091200057B13100FE6DCFD34C9F9B6550D6007C6C
-:10913000C8BE58A7CE1E7DAA8CBD1F51F9F0E48B86
-:109140009D63837CD7FA773B49280BEDD1F2FE4D26
-:10915000104FDAD93AC4C98EABD2F090A4969F2FA3
-:109160009F90197C437B65A4E7CBED1FE8A2FB77BA
-:10917000EE4482BFDFA63D4F8B3C87E8996778F4C9
-:10918000EC4EE57A9BBEFCD64C7708E45BED33DF12
-:109190001E99AFC078219487C4C7FCE92764D774AF
-:1091A000A0DBF871015D9C9659617C35CBC4F77BDF
-:1091B00012306AF9502D2F1C4BA29EDB9814A60783
-:1091C000D8F8B97364F9FF014BC990C00080000062
-:1091D000000000001F8B080000000000000BC57D90
-:1091E0000B7854D5B5F03E73CEBC92996426992481
-:1091F00093F7C93BE4014308112DEA24040C98D2EB
-:1092000009A062B538BC41C943B0BDB1C5662011E3
-:1092100002A2861A1128E0848762D5367801A34617
-:10922000EF8048B1D5FBC7475BB4F7F78B4A2952AB
-:109230008188964BEFB5F55F6BED7D92394322D86F
-:10924000DBDB3F7CB0D967BFD65E6BEDB5D65E7B0E
-:10925000ED1DB36A602C81C1CF4C334B64EC1AC650
-:109260007F324F316FD0C6984555A9FC9A5321D310
-:109270007CC867AE0C991689D40FE909230B59CA2B
-:1092800021DD620FEECCC2965E86FD2C9A00FF8532
-:10929000A68B64D66629C3EF6A4FBF8BB193079C38
-:1092A0009EF5F09D7DF995CC2A189BCB443D336B00
-:1092B000B7C431F67C9B14B240BDB99BCD3BADD059
-:1092C0005FC56AAF6C87FCC076C9B313EACD6DABDE
-:1092D000CCDF02F93BF7977A64681A83E3603EE8D3
-:1092E0000CCA50FF9AE649ECE3718CCD37074D0A62
-:1092F0007C674F4B6C0FA3FEDBB0FF65D02819E0F5
-:10930000F90A7FAE1F4A176F36C364F9DCBFC27F0C
-:109310008261F96CE8B7BB4B66305FB617BE170EBB
-:109320007D5FA6840E49318CD57747B4677F330FB4
-:10933000D643405980F0E832B13B7C369A74525D96
-:1093400029637FC0FF263366CAF48D53C76326376F
-:1093500069861DE65DC5E735B04F22BCD6B326133E
-:10936000C37E3AE319BB3A6C5C0B0B45437A520E51
-:1093700050F922F3464A6BD42C1AEF4ED66F62395D
-:10938000D8EF80C907E3D9FB80AE2597CEBF06F999
-:1093900060FCC87C3055F0C1B2532C742D8CB76C76
-:1093A000250BD58FE6A91DD2450A0BC4005E170117
-:1093B0000E62451A55C6F1AA160EE16569509F471F
-:1093C0007CAA6178463C869737F67C650ECF279954
-:1093D00018B3C60DD119084570274D6A1ADB047001
-:1093E0005EB3322833985F4ABA77522EC01B5DCEE7
-:1093F000E7DB78DC6251C760DEC7B2A1DE17699592
-:10940000CFE54179A3C2BCDD501E0D78E982EFDBC8
-:10941000AD2C80FD3F9EA752BF6E13E75FA3E263B2
-:10942000636D4897BE9001E992C01CC88F1A3EB781
-:10943000DBA15D19B693A8DD607B0B6B8B0A6B5FBC
-:10944000F5A29531582F175EB007CD509529FE4CE7
-:1094500027F497F87B335B0FF9B32FDA97607F67B8
-:109460008D6C7637D477C9ACA99BF8650DE1FF8781
-:1094700048D7F1C84D55A90C795F9A96CADC58BEF9
-:109480009ABED73B81BF86A1EF607956DFCD9CAFF6
-:10949000CCEA4E18EF82B3FF079807785800F2CB5A
-:1094A000550E77E3FE49637F04DF1B7D360FC7BE91
-:1094B0007F2CF2AB59BEE7660BF0D71479E5C0BD3F
-:1094C000308FFA749BC30C4DAA33FFE3B7B742FE4B
-:1094D00093FD4666463AEF99349B655F0A87962E60
-:1094E0000D1A3FEA0F5B2F77EDD5E7EBBBF5F94699
-:1094F000A67CD4AFF101A0608B6A779D8C26D9E160
-:10950000F90AF8DB6C6E3AD505F09A5F327B56C1EA
-:10951000E706D5BF03D7538361E028E2D99CF9E978
-:10952000683FE0A52AF3CBA3A988FFFB9807E1BE1B
-:1095300060AD9C4BF4D862550361F2AB51F07F678C
-:10954000462D95776E35AB122FAF1D0F726B092D1F
-:1095500061AA623100FE1B374FFD441A4DE516A487
-:109560004727F029B57B4E0AAE82764B362FAE6583
-:10957000507E86054D1680E70F623D35CABD532CDF
-:10958000F0DFCEB89A51285F94BF2A3EA4FF5AEC70
-:10959000EAEA217CBD34B83E2D1D27002F373289E1
-:1095A000C5E2BC9DFE97709EF5967E5325F473FD33
-:1095B0005FBF20B9BCB8F9D59C13E350DE78E71241
-:1095C000BD617E284716DF7B88BE4B332C04DFC984
-:1095D000745BD00CDF5FDD62E679A789F227B74BB9
-:1095E000945FDC2D052D5958FF627C25CAEFED46AE
-:1095F00087995D8AA748BCFC71DBEF621880FC4745
-:10960000102DB8BE98A329C667C7B2A69819A58819
-:10961000AF1B3E41F9B578BBEC09A19C7ED9EEC9E0
-:1096200063989F3C6AA10DDB7F1E5F89F8DB31D90F
-:1096300021D377D987728829DEBEEBE1BBB2E32A5A
-:1096400015D7CB91ED1CEEC54ECB1348E7EBFF2AA7
-:1096500013FF2B06E6DF67433A7847E1BA53B7EDCD
-:109660009982F8FD635D8A81EA3F2B3107E2C3D915
-:109670009C88DF174B8A0FD7D992CD4B6B59CC10F2
-:10968000DED7A832E1BD32736562BF8DF8FE66D4C5
-:1096900077F5DB81CF71FC19EFFFF656D710DF4B62
-:1096A00033364FBF06FB7FD248FCA5F5D3B8EDDBC0
-:1096B000823F180B019E160B3C993357E6E3F8974F
-:1096C0005B0F8B5737E53B6C975F1783EB7D1BACCC
-:1096D0008F62C6FEAA4AEC2BA0034B8B233D33D2EC
-:1096E0007AD4F493ADD0C0F5BE8779F7409A64661A
-:1096F0005E09E457769642E5D95926C287F297E586
-:109700007BDF04F89F53FDD15990CF64DEB1A86789
-:10971000D40147552CF4664306294738CCC13D2473
-:10972000E7200F78DA94C09E581F066786E80FD6A8
-:10973000AB0BFB39FBDE9747118F0D199F8E46BD92
-:10974000DD78F10B930AF4B4F54A24676D1E1F43CC
-:10975000FE68ECAD630B4A86E463A387CBEF4BE472
-:109760004C9691CB33D700F533359BCBB74E275F63
-:109770009F5B9BA38228F7B6BA8256043ABA3CC0D4
-:1097800050BE4F2F973D08B666A7F82C9C5E16EF8B
-:10979000AB4C467EF5C81E14F17DDE8FDBE221FF67
-:1097A00066F9648F0C799B77577B36CEDB6314E5C3
-:1097B00039019CF71B132BC95E99EE95695CB624A1
-:1097C0002688AAA2CFFB8E6B018CFB1DE67DE404EC
-:1097D000D0B1069437D2B10FC7067A9D71F8272011
-:1097E0005EB4F97CDB33F59113E1768697DB03F009
-:1097F00089EBB1F2E1F1305AADBC0EFBB9FE3A4E45
-:1098000087D3CF9A83AB61FCD356D03361FAE2B4ED
-:109810009DEB1D5F9624ECC2EE0C94FB837965945E
-:1098200001D7FD3D0E8E0F97A93B03D7DB9F247D0B
-:109830003F77B6CB2C08726669BBC48200E2E9A709
-:109840009ECF40F9FBC99EE733E685C117D94E4B41
-:10985000BFAB8DD7F198D702E3CD63DA78A1341C82
-:109860006F9EC7FC21CA0FD63ED9DB1F663F90848E
-:109870000CABCF367B497E9F83D5887CA7B53BB7A1
-:1098800024CA8B76E63966094A30D4BC5E3964C690
-:10989000FEBCDE5C17D0BB416B1FD17FA7E01FA9C8
-:1098A000470AD9A17E74C900C9DBA516DFD15428A7
-:1098B0005A8A7484FA53918E12F2ABD784F35624E9
-:1098C0002ECFCF387C7767C1BC1676E8E9989EE545
-:1098D000E0F375B8B83DD86053505F24B6326E07D8
-:1098E0007EDF10447DED8A8A19CDC08E31A5B86D1A
-:1098F00028A7AECF8F6A33C4E2F78C20D64F4F290A
-:10990000A476812ACEDF8144166C95B0CB2689ECF3
-:1099100040473F53E07BDA04E6580FD9DE2C6E2730
-:10992000BA9967B34C7662B78476A286074DBE2398
-:10993000DFA0DC3B2D59886FA45E89EC3ED9D03D79
-:1099400007FB1D898FB644F0D1967F321FED1A9127
-:109950008FFC2AF191DB323C1F81DCFC46F559C0BB
-:10996000A700BE9204BE1E16F265E0FB16A21BFC09
-:109970004838DF5AD15FADC5169247939CF87450B2
-:109980007E433FDBC0FEC47D4A32DACF90A6B6CE1E
-:1099900055B9FDDED72F417FD1575948EF3D60E8DB
-:1099A000CB423B3FA9A8691FF247D29C92B256B264
-:1099B0004FD29C28F751D6E0FC1B9A27F9B81D001E
-:1099C000FD221FD599683FD1706FA58FDB0135B49B
-:1099D0003E1A375855D467937AB356217F34AE0474
-:1099E000FB08E56F4FD79645906F9865F3A09D6291
-:1099F000B5CC2CC176AC5DBFCED649DD641707A6C9
-:109A0000320FCAED734143C03806E56CFF8E1FA1CB
-:109A10001E5F5AE209A8B8DE045FE632D20B9D4E03
-:109A20006F721CE0F5E0DF64DA17758E853CA42FB9
-:109A3000097A76D679939D909FB7C14A78EFECE288
-:109A4000E5E7EC8020E83F45E6FDB1580BD73397BA
-:109A5000CA030BE23D7102D37E36633E45CB773CB1
-:109A600046768CB6DE3BB3383CF6125F165ABEB76C
-:109A7000ABE3FAA260BD27CA066D531440BB3B1A84
-:109A8000C7E4792F0EF7A8010049C1EC7F6FAC9EA7
-:109A9000189EE7F587DA3F30A33A8DF4EB60398200
-:109AA0000D7A57CB7BAD00C75AFB50B902F6A4A57F
-:109AB0004712ED27CC980CAAF89C24C60F281BBD92
-:109AC000808F87AD4C375E387C4A44FF46E8DFA67E
-:109AD0008AFA8152DFE45C80B74C6BBFAAC30BF0FB
-:109AE0003D6CD4F7472815ED31A38DF7EBDCD73764
-:109AF0006E481BD2FF600FD8B3C70FD9016BDFAF21
-:109B0000ED180363453B3E37A17ED5F479A34B2284
-:109B10003B2372BD2665F3F50A766D5236C90D6E8C
-:109B2000EFD6A2BD2B939D3B059756E34A1F43FBFF
-:109B300012EC86D46CB21B3E3D7908BE77CE384D10
-:109B4000767EE34585EC8F46B03FD06EB7F4727BEE
-:109B500096F51849EF6A74BF53C89F4E27E87DE415
-:109B6000D397A5F1C8A78C3565DC043468C9F6E63F
-:109B7000211CDA7E2C12DEEBB2B95DDE5858B52519
-:109B80001FFBDF2D31D4FBEB0B3F4A44FBA4B1F7A5
-:109B9000C3C48561ED96F63C4A7858BAD738ECFCD8
-:109BA000AFCB9669FE0D2F1CF0E27A3F1D94682D15
-:109BB0002F5182EBD0AE5CB2C480961A2B0FCEBD73
-:109BC00015D73D9B6D627930BF5CD44BB89FD83BB5
-:109BD00033700DEEDBE0AF049FB6FA16D1FADE3A31
-:109BE000DB62635908E7BCBB090F8E282FE2617D59
-:109BF0006155328ED35037C581FE9346B0B3B0BCA9
-:109C0000E1DEEF923F45836B7D8FB106EDAF0AB089
-:109C1000B7FE15E04E8F9B56E381F5982AEF1BBBEC
-:109C200002F29B4690BFBFC9E1F46C937C81EFE0E8
-:109C3000BA7F41627BD4A1F2CC1E6ED7DD9CCDED04
-:109C400040EDFBCDD9DCDE9C18E89B84BCF78AD2C2
-:109C50001F8DF66F23F37E86FB4EE6B3A97B884EFD
-:109C60005CEEB85A54F22B595CFD0F8CC1F2890A94
-:109C7000ED2798D2FF088E7B769DCBB39E09FEC55B
-:109C8000FCBD2541DA3F64FBE7237D2B841D79F67B
-:109C9000851BC6CE2B19B293D6755983AB010FEB3A
-:109CA000ECEA4F6A50BEFD4521F9C62C037D939026
-:109CB0001EFF1547FDAEB306D721FD031B8D54BE15
-:109CC0002FC5DF807C79AAAE261FF7C1CC16C8AF9E
-:109CD000037E32BA3A18DA0BB07D203F83C5E563C4
-:109CE0002AE42705E62A12CAF908FB6312FA796802
-:109CF000DF0083C3F72A21B6F2800B4E5A6809B4FD
-:109D00007D153F648F1CFB7296821F353BC560F149
-:109D10002FC5A6D5B3A3988C7CBF66E0A801E61337
-:109D2000EDEA233BB6BE5BA271EA0B9F33A1DFE4F1
-:109D3000AE6EBE2E1BC53E00F09781F6C0DAEC6811
-:109D4000A1C7DB38BFB33EDA47B367383D19837A22
-:109D5000F6F0FDC42AAAA7F5675ACDFD5EF5C21F2D
-:109D6000037290CA7F922D897DED6A9176F0548CB2
-:109D7000BB49EAF3CA88D7B192279C6FB4F4292172
-:109D80002F620F0F4CC1F53B00FC857E992D52DDF3
-:109D9000DDAFC1FCB68C2FF2A009E5067692CBF0C0
-:109DA0003BB022E0BDBCE7B329C8376070D37A6D01
-:109DB000E8A994EB6DA4B769FF9814DDD485E54953
-:109DC0007714925E8D1AC7EE9801DF7F2EF09A6CA1
-:109DD000E37E2EF7EA40D6F2121CDF77F76B387E6F
-:109DE0006914F929938036F6384ADBD12FE466AB43
-:109DF00024ACF7680CEF3FC120DF5157427297F255
-:109E0000711EC9BB13D29E6C27F76799590DC28981
-:109E1000DF693F069C81FB59F473613F49393C3D42
-:109E20009B1C5250406C65FD3BF6207FF6981D88C8
-:109E3000A7DA9E5F1E477D596B61DD32DA2B117602
-:109E4000C6CAF49987903FCF9D39B9E37EF8F6E80A
-:109E50004D073D7EA28BDE7E88DC2FECC42AC92311
-:109E6000DB7BBFCBD6DB7B83F97FB8BDC7EDFAC008
-:109E70009E68754F983C6F14FBB4734BCEC7A09E81
-:109E8000F97890BF404F570CD92BF376477F88EB7A
-:109E90006AD0EE8FB01B8E3D111D40FA9FEFB69237
-:109EA0009F4E41BB07E039631FF80122C765F27975
-:109EB00025DC3FEC337A56437F8D779EFEB901D681
-:109EC0009DD205764F2CDAFB6A2CC9D9D765B60727
-:109ED000ED32C5EB40BF8706BFE29CE2F696A05C80
-:109EE000E4F35F660AE5931D64624B281F13CA47BB
-:109EF000BBE725A1779645411EBE37BBFD7F41BA22
-:109F0000A598B9BCC276F8BD4BD85B5D801207E25C
-:109F1000E538ECBBB384FEC6FDCF83E9C1F5E4C7E9
-:109F2000B1103D3F7EC5BC13FD3C1F171A4226EE03
-:109F300097203F96DAAEB064A8AF1EB70655EEEF95
-:109F4000B21840FFCF7FF8AE37705F31FF15EEC714
-:109F50009A7FE7CAE9B8FFF878C61413CA9B85CC84
-:109F60004F7EE7C58CFBA197B220F757338701C717
-:109F7000BB0BC4C656143501C0FE55F059324868B3
-:109F800057A86D9027A3D9DB5103E3CE6B33D0BE26
-:109F9000647EBBDE9F7E61FDDD35A8C7D7B619B8EC
-:109FA000FDD82E911E9FCFBC6EB43B34BC16E4C4CA
-:109FB00073FF689BC18BE35C9F6322FE03120569FC
-:109FC0007E226D330A3FBC80631533843035483CB4
-:109FD0005DEB506A86D3CF5A7F6DC6260BFAC30657
-:109FE000D20DE407BE60F2CE263F6A5C3E433F627C
-:109FF0009BBDA9BD8697D39AB9601DF051F9B50AEA
-:10A0000037F8981A87F2323D87DB0F91F35DD8A1BC
-:10A01000CF479E4F2C0DEAF3F399BF203907FD4639
-:10A02000FAEFE9395C5E5D589F25CE013C740ED095
-:10A030006654DFCE4279B54E2179B92A8DE3CB90B3
-:10A04000CED36C67F56CE25F27D817042F873FFBF0
-:10A050005A97847AB3CDC9F9F27F0A7724BC37E4E2
-:10A06000E413BC6D68E4C1786DEBA420C71787FBCF
-:10A070004AFD174B72F4726830FF8FDF77727E5C97
-:10A08000278BF5E6203934CFC1E7F4B1E479228497
-:10A09000DF6D601F00DCF3D7C96568A74C9A69A320
-:10A0A0007934BC62257F6BFDCAFE0CB267ABFAF354
-:10A0B0009B86C12B42AB68F20BEACD73C13E01D740
-:10A0C0006DBBFE9C0A342D0B3F779A99E6BD2F2776
-:10A0D00001F7231FEFFB25D27B9F95F413FCEF9034
-:10A0E00019E5D70B596437E5A7F9EFCF41BD1E1528
-:10A0F000DAF16416DA29DC4EAAEF3577A11D38AF04
-:10A100002DECDC0BFFD9A03F0763ED71E4DF609D10
-:10A11000FAEF4BB645B4BBE45C8CEBFB4D26FF2855
-:10A12000B4EFAEBFCE9B8C72F5CC520343FACE9700
-:10A130003D8B508E9CB1EAEDEF33764EAFDD8374EC
-:10A14000F6E4239D778F48674F3ED279BE81F9C3ED
-:10A15000FBA9473A037D97093A9F3970553ED2F9DA
-:10A16000D37D57E5239D37193BBCB86E7665FAF76A
-:10A17000221E4F4CF691FD04F22AFF9BF0E38B1157
-:10A18000FCF8E2FF1E3F52BB91F4E1D19CE1F5A146
-:10A19000CBA4A6A13C9C67317FAD5EC49F61FD6BE3
-:10A1A0001633F9255EF9F2F3879E403BA457263B10
-:10A1B00044EBEF15C59F837E85578EBB3D0169E457
-:10A1C000FEEF16FB18B78505D0FFA1D9FD9AFD1843
-:10A1D000298FDF17783C9DE3FD36ED1785BF768923
-:10A1E000E8D312FC9CDBA9BB25F2C75AD46E2FDA48
-:10A1F000BD0D2FCF75A0BFF65490FB671B0E8C25AD
-:10A20000FFEDD2E0ABA154B40B7B2507EE1F96EE19
-:10A21000FE3006CFBB613FFA494ED87E74B2D88F6C
-:10A220009E0A7E1C83E7E230FE54D4CBD1AE0113EC
-:10A23000F26F03ECD3A00A6B50068E627F0D2EE600
-:10A2400009A0A8E8D1EFDBB4F3CBAD3E13C9BBAD99
-:10A25000BD5210F76989267F561AEA2796E6A07341
-:10A260002EB15EFE33C79B983B3EFCDCD8FB971CAF
-:10A270007EAE4CEDFBB7C4121FF61B9997EC802DF8
-:10A280007621971492537FDEE6A47D0FFD40FD3FBB
-:10A2900007B328AFE9EB450A0B2980F745B3BCEFBC
-:10A2A00021DD507E8722E477787EF03C9AF571FDBF
-:10A2B00002F23C34DCF9B838A7C6F3DDF0F60D6CD9
-:10A2C00080DAE139AFAE5F6D1FC09AC6AA00F75DB4
-:10A2D000B7DB3C68BF34025F37970DF1E1323115CF
-:10A2E0008D0F1B849FB771C947B41F68EC911CE8A0
-:10A2F000DF5DE6E17CB80CF649E6D197AE5BD60DA2
-:10A300007C1806F748EB785CAE7E1D0FE6FF49FE31
-:10A31000CCEB72F5EB579BBFE6171F9C67AFC4D71A
-:10A3200057C4BC22F79791FE6C6D7F78A572EDA69D
-:10A33000087CDCF4BF8C8F91E4DADCDC91E49AFEDB
-:10A34000BCE01BCBB5C873835CEE07C773033CD777
-:10A35000FD9F9E1B7CA276241A480F7A75E7A96898
-:10A36000A7E338EDDB65B20FA6C8FC1CBADE6E268B
-:10A370003F6DE4796BA33A459C2FF6FDF66AD49FB6
-:10A38000FB8D0CF5FA12DB623ACF6C949F3139D415
-:10A3900061CE19954364BF7FD3F3F775B983E7EFB7
-:10A3A0005978FEFEAAEDF3787F185DAB4AC0D02F36
-:10A3B000A1389661E5F623824FA245FC8445093019
-:10A3C0006758FB91DAFD3497DBCBAF8A381AB7892F
-:10A3D000B5637CC6C3F6682FEE4BDC061EE7D3924E
-:10A3E000EDDB8E72D2A2723C3FFEC22DCC00F37F19
-:10A3F000DCD84DF224506FF3A05CD4FC305AFF56E9
-:10A40000B15FBD52FE3F30C8779CFF07F3FF247950
-:10A41000F06FDA78DFF49C6C33E046B74E189D8716
-:10A42000BD81E73B5997F2F348FD8CC4D76FE7FA3B
-:10A43000DECC25B9E01D4DE7FE572877A2CB073EBD
-:10A44000467F0FDB6F5671DF817E0FD2971B92B96B
-:10A450001E533C158867B0F72A304EEA03FCEFD54F
-:10A4600023DB87A706E513B70F4F8D289FFE3EFB22
-:10A47000F04799BED3C867272ABDF9A83FD7DA01AC
-:10A480007EDCF73DC5E36BB659397F6E93385FB21A
-:10A49000E678CD7F42F30A3CCBCFC723F98AE5E9C2
-:10A4A000F96A30FF4F96ABB64138FE97E5EA92FF66
-:10A4B0008A413FE8C8FD04886E15557D84B78197B1
-:10A4C00025B633CC3FDDD8C7E3D4D205BCDAF70BD1
-:10A4D000C2DE5D94E7CDC078AF4FDFB358582C98FB
-:10A4E00042C8636897F96C743ED0D0CDE3481A56E1
-:10A4F000323A0F6E40FF6709FA05EB18DA7FCFA9F1
-:10A50000FEC2BCF1789E610BC8B1E8379FC1D0EEA6
-:10A510003BFB1ECF37A8FE122C6F5CD9AF3B87A840
-:10A52000F8EAF335E8D70078C94FE042BF4D189DEF
-:10A5300066E7F1F84B2DBD29027EF4E313FF77CBDC
-:10A5400041B417A3D53E3A1768D8CF8DB80AD94B76
-:10A55000FE7B76571C433E6AD85F39F635AA6F1DDD
-:10A560008BF66EC5EF6B1DE8A7F8F45A17C51F648C
-:10A57000C8FD4BD1DE3A92ED9F84F8B09707A7A2B1
-:10A58000BD9A09F62ADABF9FEE9B3A16E1D6E4DFC0
-:10A5900026F47F43BF9BEC7AFF36B378B3EE47FFD8
-:10A5A000F7CE24DA3FEE4BF17F1BE7BFC9CAE10DBE
-:10A5B0006CB4F2F52AFCDE91EB5F5BF749B281C621
-:10A5C00049BACD42E7D49A5CD864647E4BCE903CC5
-:10A5D0001927E2E9001F3C9EAFB78EC78188BCCD2A
-:10A5E000A58F6B3C9D33791CC2332E4FA1760B2D6A
-:10A5F0000312FAE1178AF3F91B449C85166775C6A6
-:10A60000E15B80F8602B6B86CEE5B3B1BD83F3BF11
-:10A61000889F89BEC8EDE86C8789F8C6DECEF8B998
-:10A6200012F00DD267E240DFA458984F6E6768229F
-:10A63000E2F3958B06C28752F7069DA7C422D9A0E4
-:10A640009F9C0DFDEB0AD09FE278F75AA48BDAE1CC
-:10A65000A842D43DA7FAEEC9A375DE5488FBCBAA65
-:10A66000DF1879BCE0CBD1640774662CA378C1B342
-:10A67000EF03BF665DAA0FB434C056537C6076CF3B
-:10A680003BE4D7B7EF97868DFB7C38CFC6E36F02EC
-:10A690007D1487C626BA081FCACBBF0FA0FDA1AC88
-:10A6A00053C893D166F41AAC48D7558CFCF0799D09
-:10A6B0000E03D22553C49D9C7BE5BF47FB69BFA217
-:10A6C000F9F1833C4EC8D8BF06F75FCAAAFEEB601B
-:10A6D00005B3FAFD4E4303FA3D8D030DE437793996
-:10A6E0009AFCA3993D39ABBF05F9CC76079350FE90
-:10A6F000BC785726F27500E69937CC3C9BF38CB4B6
-:10A700005E9497A30DA8B7948D8CE214156762151B
-:10A71000C1FD28E4A19FE5826FB4F34900D78DFA0B
-:10A7200068519E7F37D23B5AC801D61C45FE44BBB8
-:10A73000C2FD1EF6E6F79F5D05F91DC21F7BF89569
-:10A74000E219E4BF5BA74848870BCEB9990EF8FE23
-:10A750008B3C6E8FD8953EE6B085E3FF30C56566CD
-:10A76000BFCCE3D61423E713659DAB0BFD835FA439
-:10A77000F929FEF4DAB6904CE75B8E138FD4A8610A
-:10A78000FB9BCD5C8F34ECE5FBEAC8FDCCE5F4C760
-:10A79000B13CBD5D3E98FF27D925EF0C8EFF77EECB
-:10A7A00053987E7F17699F44EEE72EB1BF23FA1BB3
-:10A7B000C94ED1E23CAA86C6217E78D5AED94101E8
-:10A7C0005D1C4C958D8FCB2CFAFE9F12F13B5A5C91
-:10A7D0004C62ABBA0AE3CF07EE63E46FD3E276B420
-:10A7E000389D4015DF47040C20F7B2F07CA883E2C7
-:10A7F0007352594892683FD0CFB07D12C6E940FBF2
-:10A80000FEBC6C827F3BF3B4CB24175509E1B762E1
-:10A810007C473CC21DDCB208C7BBC946E35931BE08
-:10A82000239EF611B48E537C3CAE73D2121E0F9A47
-:10A8300002FA17F329B99C2FADB34D14E7A9C56DE2
-:10A8400068F11D1A5EAA04BE530A1665E17E418BAB
-:10A8500003D914157CCA2A63FC8790FB4B0D24F79F
-:10A86000B5F8BACE3C3588FC7E0EE3406D571EEF3E
-:10A8700011895F2DEEE3FA747F72FE788AFB203D2A
-:10A88000AAC56B68FC1246C78015C6DFFA32B7DF6F
-:10A89000AB969808FE734BA7917FF1DC5203C3750A
-:10A8A00054D56BE6FC1731DED6D92616C27E95A0AC
-:10A8B00015E5A7C60797B35F81AE85E8BF3DDCB25B
-:10A8C00037E704ACF9232DDD949EB34ADDF2184C32
-:10A8D00007E6A0A41AFD64C64CE56A8C6319C8900B
-:10A8E0008075CAF6E6CEA27CC2C007989FF6E4AC9B
-:10A8F000590AE8897379033B24A8EF2FF87026E5FD
-:10A90000912753189BF0C46F660668DEDC1F35493B
-:10A91000F8A3CC4EFFB5F909785FA07F4D1FF97DF4
-:10A9200078DC3FC605223DDC3613D9376E118FC95E
-:10A93000AA457C269ECC40BE35792C9D67DB98BA13
-:10A94000BF0FCBD3CC5CDF33CECFAD79DC5F4C2AED
-:10A950001265679AE65FEA0FA0BC6ACD7252FB41AE
-:10A96000B9BADF1CE47E2E3EFE5B074AE91C4A8B27
-:10A970003365CC913EAB94E25174F987ADFC5C94A5
-:10A98000298E74B41F5A8DC24E15F9A834FF77F37F
-:10A99000C3ECA4B726FF4B09AE8733077F948B72B5
-:10A9A000EA0613D8F1C3C8A5D4422E97CE196DED8F
-:10A9B00012D86D6FA4FAE723BE8E47CF99E284794F
-:10A9C000CD8EAF343911DEC05332CAC904416FE7AE
-:10A9D0002C0E9FB3DA272D847E5BADB09EA17D82C5
-:10A9E0005FF192BDEE9F25DD0470B74AC27E676AB3
-:10A9F0002CD9ED856A2C9EFB2D6B7E87E2AE6521FE
-:10AA000007642107DE6EE9CF55F240E5766F94D1F9
-:10AA1000DE7E479C3FBF93C5EEA81B66FFBB299F08
-:10AA2000DB873364B514F9C875FFC4776A812F6476
-:10AA3000932748F44BB7ABC8EF87EC15EE7EE84799
-:10AA4000CABCAF1CE3965BD3EF2BC7B81339CEE378
-:10AA5000F685E537E5733EAEC67A88B7E8A672D4C8
-:10AA600063FFB0FE62A1BF92BFBFBFC17ECC1CAE70
-:10AA70006596810C05D6A7C7EDDF8A74BB30F74316
-:10AA80003A8FFD41CA5B1F60FCC45BC68E4931280A
-:10AA900087B224C1B7DC5E3B5AA0F93D79DCFBD11B
-:10AAA00062EEF70439C4E32B4BF93D9BDA598CD69F
-:10AAB00073AD88BB98E2E0F796A69467795A616A0D
-:10AAC000D3D98082727ACA715F0CD28FCDF297FB94
-:10AAD0004A47B6C398DBA886CB95A96A581EFEDE06
-:10AAE00058A8CF7FDBA3CF7F67C25F0BC2F31BDD0C
-:10AAF000DEE771DE2F493C8E33703573D03C5D52FA
-:10AB000000EDA5E2E753BA847F97E20D7F26F67346
-:10AB1000CF4F60549EB8D7B213EF1F687E7259941E
-:10AB200017BB9925338EF0417A764012718B2E3AFD
-:10AB30000B6207EF7670FC415D13F47370AE4AEB65
-:10AB400038D16660D7E15A2FB790FDA4AD8B562B54
-:10AB5000F037E0B122D51285FCDE6AF46CC6BEE4A3
-:10AB600028B38A7AB532C6427DCB3F56482FADB264
-:10AB70009A29F4F5F0835194AF50980FE33500C44F
-:10AB80005998BE65F4049B70BE500FE7DBEA64245D
-:10AB9000AFE40A13E969E897E87A78A321C868FE68
-:10ABA000950AC5630A98B5750723D1F7C7C4BA9645
-:10ABB0000D2C44722CC54272EC08F48FFD1E7E5D94
-:10ABC000EE223F5BA17A3B969FB714D0FD9CC6C195
-:10ABD0007B478A01812B147694B397DF0FD3D6B3CA
-:10ABE000265F22D73348C15C5722E320AAF80F4CD6
-:10ABF0002311F53E237B5E3B3F4CB768E58A17C7C0
-:10AC0000491EACCFEF67258A7C6A4116AD37A81282
-:10AC10003294A1FDF1CBBF20DF6AF261C7DA1F9346
-:10AC20007CB814FF85DFA7FC34BB83E3BF200DD7BE
-:10AC3000A11C559086FAAED5E9517D61F94258467E
-:10AC4000B3E3103F500FF2336B3ECC55C2FC83A9E7
-:10AC5000052A094BA8E78D07380E5BD5345CAFC3D6
-:10AC60008C5BCFC78DFEC78EEB8671A1DE613B8CFE
-:10AC70000BF5765BCD2143CC70E34F5071BCCB8D8F
-:10AC80000BE824A44E137806BE08A05FEAB0DD40AE
-:10AC9000FC394DC4EF1E4EE0E3B1427D7C4D6E1495
-:10ACA0008C4FFE587D3CCD0DD2B636D4CB8F596338
-:10ACB00076223FFE52F0C9D1E81FE7A25DF5CB39FD
-:10ACC000F94750AE4C895DD5864C328D7593BCD119
-:10ACD000E4DE85E40F2B300FF2EF9A02A0FB0FB2F7
-:10ACE000DF9A839D1F713E968BFA0FE4C3B70A1259
-:10ACF0002E855FE3470D6EE4435C07837C1801BF3C
-:10AD0000C6476C7A3705206E07BB1453CD4E65AC31
-:10AD100089C789ABE943F303269E6269E2F35815BC
-:10AD200020B86F703E42F168D78EF2FB10DED96317
-:10AD30003ECB50B0B27B6E01EEC300DEBAFF9FF097
-:10AD400046DAE5978B97D6E08A5CC7DAF8D28CBDF5
-:10AD5000142FDD38CB46F1D39344DC69E31203C5ED
-:10AD600011C1FE8DECFE066609A21CBE46D8D15A62
-:10AD70001CFF8B12F77F060E98D53D61F6F8A57182
-:10AD8000D42AC5690756F278EB417BBB9EDBDB8397
-:10AD90007A4DDC1BE81CCB6579E7DD2AC553BC2462
-:10ADA000F1FA81B98CDBEB75A27CA143C45BC05C7A
-:10ADB0001287E2D93BBB18F17FA73D9BCA5364AE13
-:10ADC0007FD8B7B8FEE9CCE2F664E7ADF9540EFBE4
-:10ADD000825188F7F932D8CFFCFC9EEF0FF2F87859
-:10ADE000917EDA4D05DC2E1BB473443ED22FBB2B73
-:10ADF000D3BF05F9656189374302BE9A6FE27E577A
-:10AE0000E0BB6D7867A68635ED5672F0FE45D3BB84
-:10AE1000861CE2BBC789EF8A81EF72747C172C18FD
-:10AE2000CFE52F0A538DEF06F9AD30325ECEFF1419
-:10AE30008EDBE9ECFE7D03EE2B7ACD44072DEE315F
-:10AE4000729D87C173C2C8E171C932C1B36F3878CE
-:10AE5000AE84FFC3F92D89713E1F691D24292C6022
-:10AE60002F1B5A071BDDFE10C23FB81ED6F07DE433
-:10AE70002570CB36E28B9B6F9539BF46737D8EE78D
-:10AE80004DC9307E9D18FFE675BE6A27D6AB930884
-:10AE90000F75BDF51417C6AAF9B99107FE203CAD90
-:10AEA00042CE69E75BB345FB998E3A23FAE366D558
-:10AEB000EACF9966DBF839D6CDB38C1F85DB3DB37D
-:10AEC000D986CF308E71369E4369F5818FDE2F187B
-:10AED0003C872AC073A823C2CF720EF81AF9FEB5B8
-:10AEE00084C5DBEE06BE2BF8694919FAE326272E46
-:10AEF000DDBD11F24F6E2DA2FC6B89B7DDF3169606
-:10AF0000EFC8A77CB541223E3D57CFDB1756DC3A50
-:10AF10002D2B06E5BFE817D713EED7A3FC9D755080
-:10AF2000CF3D3ABB0CE34BAB85DFE0DCDD8CCA6F79
-:10AF30001C63E721BB8B55F2FB554789F2EFF17E8D
-:10AF4000DF18FBBB328C33AECE1E9883FCFD46D996
-:10AF50004B45983F227D3667B873AFE24229340AE9
-:10AF6000F0521DC7EBD7963D95827E98EA2A9E2F18
-:10AF7000F654AECBC172C3F939C3DDFF8D12FB9E0F
-:10AF8000C1FB6C625D3FEFFD90EEAFF92C9207A71D
-:10AF9000E89BF021F91D984D72A0EBCCE7CD52D083
-:10AFA000CF3DC9CBE350AB2CAB92517E4DF79BCA42
-:10AFB000319ED861197B04E30C6227548E47BA4E48
-:10AFC000B230A22BF0794C21FAB5AFFA2C230699B6
-:10AFD000CBA6E7738D8FEA34FEAED6F331AC4F5774
-:10AFE000E1F8CBCBDB91F818C6CFC0F6B3BFA5D73D
-:10AFF0003783FD45ACB7C8FE479203F8132E178779
-:10B00000E0E8A6759586D17D39B8EE3AB475370675
-:10B01000E13019FAE81E4FA6E429A20BAD133C1645
-:10B02000D24711706BF0A5836C636597C2853F8A28
-:10B03000662F72081C8E441C9797433B2F8B1B82F4
-:10B040000BC6BF1EE9C0D67078B64B4D5C6E88FD4E
-:10B0500081E6CF68D0E6DBA39F6F4514BFD7EE46ED
-:10B06000BF13B6738D2DFA3AB81B853E9D65F13D31
-:10B07000688639DCE49C4FFC700B683427CCFF6F8A
-:10B08000A9FE3AC447AB1478B93F8BFCF114FF0119
-:10B09000F49E51186607687045E2A36104791809A7
-:10B0A00077241E86E8D3978CA9761F6E705E11F305
-:10B0B00069B5F3F53A30DECCDFB550C01485FC9BA2
-:10B0C0005211C5A16870BD2971BF6440E2F78F3489
-:10B0D0007B2212BEC87B7A1A5CE8EFE3700CACC22C
-:10B0E0003B820F166A7E3E4EAF24019FC9200D7B26
-:10B0F0001EFE60A141F3B3EAE819797F4DC39B16A8
-:10B10000E715892F2D4EEB9273B78873E591EA49C5
-:10B1100060A7A7C65D8A47EDDC2E6ED04FC9FD4003
-:10B1200003F7DA490EC60DFA298F2968DF4FF21CA2
-:10B1300052D02EAFAD8109000DDE147E1F0DDF0F42
-:10B1400064F8B71492DEEE1F8FFE959F4C7D82CE81
-:10B15000AB3E30703F7D247EF68C809F91F87D243D
-:10B16000F8A3D27C4FE2B867A4BE0A2CECCC16E759
-:10B1700042CC9F85EBC1E9C8AA44FF11C8D7AFBE36
-:10B18000C24D2B16015DCB33FDBFC076B730DF64F7
-:10B19000A46F5C8DDFC8CF4918F9E1978BFDE3649C
-:10B1A000A177CF6FE3F11ED5DE518F4D44BBF198EF
-:10B1B000910569DD7B497FDE25E03F0F2A3684F566
-:10B1C0009FB193FE5DFCFA7C8AE328D86C187A4F15
-:10B1D00003FE8E0A46E9DED328DE1BA7CB9776A7AF
-:10B1E000E8EA8FE9C9D6958F0D15E9CAC71D2BD39B
-:10B1F000E5C7F75DA3AB7FD5F12A5DFEEAFE69BA2C
-:10B20000FADF3A354397BF76E0BBBAFA1F0FFA0F61
-:10B2100084DD10F0F615C2BC1788795F7F719EAE91
-:10B22000FD9F62A61C437E5CB081C7A55702867451
-:10B23000EF8B7470FBA209FE207D27B3018A076C97
-:10B24000084A9E10C3F836BDFDB1B4A78BF078B99B
-:10B25000FBF805AEB90634B94F170AFBE32A761599
-:10B260008F67FD7ABAE6B3BCBF8BAE66B79EAE56AB
-:10B27000554FD7E8423D5DED1E3D5D6327E8E9EAA5
-:10B28000F4EAE91A5FA3A76B824F4FD7A4D97ABA21
-:10B2900026FBF5744D5DA2A76B7A939EAE99CD7A8D
-:10B2A000BA6505EED4958F446F4D9EE6B42FD7D581
-:10B2B0001FA4BB6F09C537E575FC50D7BF46F70023
-:10B2C000FC41BA17301187F93FA47BE1283DBD410D
-:10B2D0006F8D1A359EEC8D124C671708BBDE37BC9C
-:10B2E000BDA1C99F70FD1EBEAF1D492E5DA2CFC47A
-:10B2F0003E77447D16B1CF7D8F81BEA5413690DF6C
-:10B30000EA56C19F87A338DE3FC7A2ABA11ED499DE
-:10B310000070BD8770C338EF4515933FE2BBACDBCF
-:10B3200088FDDFCEFA289DC30628F53307E9EF79BB
-:10B33000CC43E902E63309FFC4F45109E8B7E8AFAA
-:10B3400040FD7F61EE5B1FD0B9D61BF157F40EC5EF
-:10B3500047787E92C7D849210F4EE0390AE4CF5A88
-:10B3600007F5ABEA0AC3DB49E16F9C3749223DCDC3
-:10B37000E4288AEF9A778B44E744F3FE93A78B4641
-:10B38000493C1E24226D6DD6F0C7F7473B47A90400
-:10B39000471AEB16F61CF3DB72A81F7EEEB1CB4406
-:10B3A000FB58B785C3F7ACC4940971741D8EE8EAE5
-:10B3B000B670789E35320BE2F369E65791180F2884
-:10B3C00020A2F83D8C22E48F79FFF95636FAE9A2E3
-:10B3D000A25E98557D359ECB0456919FFC7B4CEF29
-:10B3E00027BFBD49223FF9F7004E48DD0E8F1BED08
-:10B3F0007C2DFFB080B71AEBC1F7247793847EA928
-:10B400007F587FFB7FC8EBFD9DFD0DF6C3385CF8D0
-:10B4100083F4D3FC9E85061E27317037DF1FEDFEB7
-:10B420001EE3FEBBE6406500CF45653094308ECA12
-:10B43000C8EFC7EF1CC5FD9EC9AC8FFC0BECA8661E
-:10B44000D7FA49FE9688FB1767C5B9E2A22E0BC34F
-:10B45000389D927D87E2F01C7111F0601FEA61C592
-:10B460004FEFBF946C792D8EFBFD8C4EBC57A9E934
-:10B47000FF91F9546127C3EE3100DF350D677FBCC2
-:10B480005AC4E3035A5BFA46E139A006CFFD2DC743
-:10B49000282F2B1E86E797F83E5478FCA3C905E5B4
-:10B4A00061F24EB141FB303964B4F9E89195352D24
-:10B4B0007D74BE6814EF58AD4D5BEEF087D9898777
-:10B4C0004609FBC71260B84FE02A0A53E524CAB503
-:10B4D000FF627C1F6D76433FE1F2F362020B3F1F78
-:10B4E000686F394EF0AE91FC7EECC49CCB4256A006
-:10B4F0008F59C1BBC0F07DCB0DC7308ECB645FEEE2
-:10B5000009A923E3CDEC562E84CBD3B723E4E94F2E
-:10B510005A068A719CD6967E0D5F0CCF6B03C9DCF0
-:10B52000BE6E6DF984BE1BC03E447E7B754BC1214F
-:10B5300015CA3F80BFF8DE8ED9C5E162175DA457FA
-:10B54000E7083E405F5C3AF0CF07CD46E2B315E92D
-:10B55000363A2758F166DE212FAC67134C57FE06AA
-:10B56000700F8DC3F16412F214F8C987F2C194A26E
-:10B57000D079419C6306D1E9EFED4FC3AFC9CAE86A
-:10B580009D2453BA8DEC822B85F36FA3F83B408347
-:10B59000F6C94517C9FF15022FDABB4F1FDCC3C818
-:10B5A000DFB3E25EEE375C51CFE81E026B869F8A06
-:10B5B00021BED1F44C02BE50031F3B5A60C5411757
-:10B5C0000FB55898BF00EC108CDBCF19A2638757DA
-:10B5D000716288C1C66A571DA60F4D38D181E2EF4E
-:10B5E000E1895FF4618A670438BEA38905D13EA66C
-:10B5F000B37F18DFB904F2307E8C288FF1F37CAC76
-:10B60000288F9DCDF3E9DEE7A46A042CE23C2BDD14
-:10B6100016373517E5F402C6EF818B7720B60B7D20
-:10B62000916A8BABABC6F2DB19DD0BD1CA7F2ACA9C
-:10B63000936D1FB5E7A01E99A56FBF45E021C9F620
-:10B6400051C7243AF7D2976BE74A09B6F3C7A87DEA
-:10B6500089BEFC51D1DE6E3BDF3709CB73F5E33F8A
-:10B6600028CAA36D5C1E321FE3EF1588F20744B9A8
-:10B6700015CB717C0F2F97B5773944BD75020E8CB1
-:10B68000A923BFEB28EE77DDD1622921BAB45C246F
-:10B69000FA3CD4C2287F6B511CC909430DC7779C63
-:10B6A0008BF383A3990DFB4EC1AD42AEC5A8FD5EE1
-:10B6B000EF30724F2B8F73F0771864B789F8C96C2D
-:10B6C000137243ACC741B92135793893713FFDE519
-:10B6D000F81A16DA05B48F32E007F93AED1E03F3D3
-:10B6E00087C9CB946551CC1F56DFBD204E974FBC08
-:10B6F0003D4557DF352B5B576E2B2FD295B35971D4
-:10B70000B46E960BFE8A2A29D3956BEF43B0DDA267
-:10B710009E58BFC6DC6B74F5CE17AAB1C8E327A745
-:10B7200082FEA178068F05E5C3727B7612EA9FA799
-:10B730005B2610729E857505462B7BC6C9E3DC9F90
-:10B74000C1F34328FF598B97BEEF817215D25DB0CC
-:10B75000EE54A8DFD5E2A0FCE32D6E4AB7B7A8945B
-:10B76000FEB4A590CAB7B47828FF18F48FE9A3D027
-:10B770000F7E7FA4A586F21B5B7C947FB86536E5BF
-:10B780001F6CF153FA40CB12FABEAEA589F26B5B87
-:10B790009A29BDBF2540696B4B3B6F57C4F5CC332D
-:10B7A000E25EED3395FCBE7C241D3B8B841F52C4AE
-:10B7B000ADD887E2563A8B306EA5BB9FEC702D6EEC
-:10B7C00005E74DFD59F9FC23FB7BAA88DB6F45ACEF
-:10B7D0006F55345FCF743E9CD7E3591D0D7C9FDAC3
-:10B7E000C4E990D53340E5C94B382D9E12FCC95CA5
-:10B7F00001965641510254EFACD45715CDCFD529FF
-:10B80000CE91B9619E15E2FD2662BBA001E15226F0
-:10B8100070FDA9D17570DE4E0E27CE7F3878F70BFC
-:10B8200078E5F26EFE2E4B4D4708D93ECADB44EF59
-:10B83000B25866FB420AA42E9F9FDE8928BA3805BB
-:10B840003667206F2E5EC75448D396E9F76D290BF3
-:10B85000CA74FB22F9E2434C0539602BD1EFAFA249
-:10B860007297EBDA59D27EA82B37B956EBCAE7DDCF
-:10B8700095B5C68DF84CE5E74BE60DAB5832C0B533
-:10B88000B07323C1F59198C75949A5FBE5817D5A4D
-:10B89000BC05DF5F3C29F40BB36C207BACC0C9B3A3
-:10B8A000F9B10103EA874FFF3596E4D2138F1B826B
-:10B8B000E84706F164C0F55F0C661F9697B27ECA32
-:10B8C00063A80CE6C73255C6FC383640FB2BD85F60
-:10B8D000BC5F8471ABB2FF712BE4CFA4FB9FE4711A
-:10B8E0007321D29FF9829EF9DA7E6AB312E95FEE84
-:10B8F0002F22FF8DFE7E5D9BD85FB459B99F6E9558
-:10B90000B32209EDD6B323C439DADDAF1E5D00F8EA
-:10B91000B6271FA274D02FA71A86BD3FFE4504FF8D
-:10B920008F026617FCFF05F2FF99F2B713D10DD510
-:10B93000903B40EBE0ACE475CF45FCBE2E737E84BB
-:10B940001D17CE4F11F855F655BAE7021E953773FD
-:10B950003C013634CE132DC773300E41CBE78B3804
-:10B96000DDBD2DC9B9D561DFD5624EC742D657833B
-:10B97000FAAAB0C4E00962C75E87CE8F61CDEDF050
-:10B98000E27B084A19F3A0981BC53A56A3EE56FE6F
-:10B9900026539C9572F86AA6C27EC6660B318C4B04
-:10B9A000D3FA65C21F728F909B5F38AA63E99DCB63
-:10B9B0009441F9873A927D61F3F6211F7DD169E4C4
-:10B9C000F33AAC2F2FB471BFE1A242535095F05D12
-:10B9D000B50E7AC751D921B1B42C846312E1811D0F
-:10B9E0008C263E8CDE3C9A0560BD943BFD9662F44D
-:10B9F000DB85D483861CC19350AFBED8B413EDB39E
-:10BA000002C48B0DF1726B6E350E9D5B48F85D289C
-:10BA1000E63DBE98D3AB2D3D021EE6F1E27BA78B3F
-:10BA20003A353F8E7E9E0F96577D07DF856CED93EE
-:10BA3000B95A8BC0E77A63DFE8B9D0F5997E804BBD
-:10BA40002638C717A30DBAB98205488FF3F9D53F39
-:10BA50002EB1AD5924976A488F8F37B0F0F3532D2C
-:10BA60009D58CCE5EFB1221E876A771F257E1CCA40
-:10BA70001F39BA00F0F1B48115D2B9B181EF8FB599
-:10BA8000781D19FD0078AFA158C845D6C6A6A1DE1D
-:10BA9000761A28FE54EE8AA27BB3B253A1B8F736C9
-:10BAA0005BB5E34EECC7A1D039D11479621FDAD16E
-:10BAB00066A7611CDAE14776FEB00FE386E4748581
-:10BAC000A1DFABCDA1703B24CD40F1808AB3DA82F7
-:10BAD000E74AF9B6139588CF435D3FA07722E4EF9C
-:10BAE0008B981DE117330A92B5B126EA3F90A688DC
-:10BAF000F766BCB56313C591888AFBA19A4F70BFE6
-:10BB00007DC471DE8AFB02D5B688FC81F715F37D12
-:10BB1000A211CF0F21FFF8CAF34E945FAF77AD8922
-:10BB2000CB427B3AA8902D52F8D7D6147A0FA1CBEE
-:10BB300044EF356878CD0C28BA73C8F4667DDE1CF6
-:10BB4000711E698CB827B75C8C8F2797A1B0F91844
-:10BB5000DD7CFFC65C36DAFFDC572CDEE914F97BAE
-:10BB6000447EAF3190E201FC1CEE5A9489F3BAF0A6
-:10BB7000829FE2CE47B2FF2715AB62BC80D540EF73
-:10BB80000287AC1887BEBB8579D0CEB30415BA073F
-:10BB9000B047C8B35C1BE7FF3B4AF87A8D4C733B58
-:10BBA000F8BA539E890A4623DD1CDD650158E7C5B6
-:10BBB000AF4E652AE8C15C87D780FEF7DC66930745
-:10BBC000EDCF29BFB0119F9CB7F1382EA5F9011513
-:10BBD000BFB7EEAC2854C3E00EB6383C289F76B60B
-:10BBE000583C181B1F1C41BEE6380D143FAF1A7895
-:10BBF0003CE72EB11E7715F3F788760A39B34B0967
-:10BC0000CC403877013D316EFFD0066E1F2F5F6547
-:10BC1000213896BF9E43F6D548787BA2C5EDC9452D
-:10BC200078361852D05F55B92E773DBEDFB1DCCEE5
-:10BC3000DF3796638B1EC3AB11ECD74686F67C6B61
-:10BC4000CC359EF961F25D8E9D58887C25CB8114A0
-:10BC5000F4E7F43C7DE1268CE705FA6DC57CA8F895
-:10BC6000839B307E77AF3D9082F1BDC78A3FE2E58E
-:10BC70000981AD18DFDB577C9297A707520C903FE4
-:10BC80005E7C9A97E705B662BEBFF82CCFE3D91B5E
-:10BC9000C8CE53C5E76F0AA0BFC5E4598202F9E7D1
-:10BCA000007F092CB16E919E1678D1CA9FC3EFB068
-:10BCB00001DB2FD2C8F283A25DCF08E52F8AF2DE26
-:10BCC00011FA7F45B40B8DD0FEB068776484F647D7
-:10BCD00045BB632394FF4A94BF3142FFFF2EDAF540
-:10BCE0008DD0FE6DD1EEDD11DAFF56B43B3E42F948
-:10BCF000FBA2FC3F22FAFF40D4EF17DFB3ED1BDEBF
-:10BD000047FF7D36C811944B85F60D71B8CE77B6D6
-:10BD10009713FFB756F0732A8DDFB32546EF0EDF7A
-:10BD200056C2DF3BBBAD84CB71A584F339F0E1C3D0
-:10BD3000C877CBDF94299EA8D5E039154439BADEFF
-:10BD400040F6C0F2D7F97E7DF93A25187E1F486B80
-:10BD5000AFC1BF06E103C66DC314D6DB97C5FC9C1B
-:10BD6000D1EC767B6AC3E499D1A1CF83BC602877FC
-:10BD7000417E53DC78E1BAAAF6C2723CEB339005FF
-:10BD8000A2D45B42F88E8862177AC151DE5188F0E6
-:10BD9000D9147A3F4193F3CCE6D6F935DA6C0ABD73
-:10BDA0002727DB79F9945F4C74A09DD5C6FC7D5E96
-:10BDB0006CEF56C88E3FD45EE640B967B22F70E094
-:10BDC000FAFDB894E3BDBAA1300AE5B5FCA081E460
-:10BDD000F711075FEF3BDC3CCE0AF40ADDAF0279D6
-:10BDE000ED411D51C042AB506EEE7DE8E05CEEE7E8
-:10BDF00063F6B115747F493B579794B07D406D0948
-:10BE0000C74FA6D0230AEA174877958B7B3701EEF8
-:10BE10008FCA54983B35ECFE706D89CCEF3D69E7D5
-:10BE2000A1722DBDAB95B152D19D23A4DDA3CF9BB3
-:10BE300022F48612A15772DA414EEACE4F1CBAFCA8
-:10BE4000B74A849FC7C33C68C74EF9C5069287E7C7
-:10BE500051BF4923CBBD41F92BE4F12E4400CAD197
-:10BE600000BFDF7E6843D9AF90DECBD719E83DEB4A
-:10BE70002B95A30AE218F090E797482FC0845270E0
-:10BE8000DF74393CE4197D71F4DEC765F091F76821
-:10BE9000791CCADB3CBF42FD5FA2372E83AF67250A
-:10BEA000CF713FD2D11925EC6A6000F4DBC545752E
-:10BEB000E1F9BE49F853B438652549E1EFF58B7BCC
-:10BEC000B2B2E0E3FB99578DCBC1F78A9AC8BFBFE6
-:10BED00062DF3D6EB4DBD71AFC0ECC1F8B9B368025
-:10BEE000E32C874D3FE26F2FF641EF72BE7D33FAB0
-:10BEF0004DBA8326ED5DCD10FEB30FE38FB4773BD3
-:10BF0000DD64AF897CD5CDD530DF6EC5518C266818
-:10BF100047C9E44D46B049F799D8607DBCEFF7F4C6
-:10BF20001183E8EFC64DD52097F64531DDBBA5FB63
-:10BF3000D0CF4EF9E99BF09D5218EF4619F6663BBB
-:10BF40009F99B5C976F5103CBB9FFDEEA655E8B0AC
-:10BF500013FB1427E3EFCD9F51FB6390B4B05F59FF
-:10BF60005F82FBF5AE1389E1FB75AD7EACA8DFD037
-:10BF70003BD0F08C4AF53B4A801FEA7B06624A08B8
-:10BF8000DF0315E1F563841F20ACFEA6AFAB5FA80D
-:10BF9000C1F3CCDB3797F0FADBB0FE59B53F9162C5
-:10BFA0007A22E089BFB4FF9D04FF08FD1789FA6774
-:10BFB000426F53FDB3AC3FB1348BDA3D85E39C7BDC
-:10BFC000E3ED0A31EF443CC779D7E6FD197E6FC136
-:10BFD0003E707FA734A9F8BDDBD2E140FBCD6AEC0F
-:10BFE000F0A11CCEC5F7C7260CA5CFA2F2187FE999
-:10BFF000F7487EEEB6B0F85AE4D76603ED6F7AFAEA
-:10C000000D0F205FEE489BE8C0FDF33E535F5909DA
-:10C01000DAAF076C64BF1A323FB5A2DFDC5CC0D771
-:10C02000BFD5D9E42981BC35BD84DE0F95EF5DDE37
-:10C030004DEF98DFC7DFF7527E6CF2EF46FE0A2D18
-:10C040002F5C18B6BE7797F27B96EB5EB36DC0FDA2
-:10C05000C13AA3A7A300ED70BB42719FCA8F0F4ED8
-:10C0600023FBF0E70646F21FE65905FDB6CD55E87D
-:10C07000F7300C94CEEB2B217CF87C55502F2341CC
-:10C0800091F07ED0FD8ACF82E71D6661D7EDF0F09A
-:10C09000FB61DAB81784FD79A184BFB7B623EDC27E
-:10C0A0007B8B5DF8FE8389EE75DA961942A618BC83
-:10C0B000E7B6F3D462A46774FF3ABCE71C95A238D4
-:10C0C000707E3FAD85323A97EBA6EF817A03ED1B88
-:10C0D000E29719BCE87F8CCA35E9FC1D361827DCCD
-:10C0E0001F1233DAFF47A4E7B837951B11CFEEBB19
-:10C0F0000DF43EEA83EE772D068033A65CDFDE3159
-:10C1000051DF3EAE5A5FEEAAD59727CED297BB6FCE
-:10C110003745F875F4F9268DAF4026D8404F45F1E4
-:10C12000221665BBD082FB9EB5AF4531A2CFCA4D6A
-:10C130001D05B83EA307085F514551E417589B6C95
-:10C1400022B9BEB694FBF50FA79B6EA43CCC0BF9AD
-:10C150006347DA51DA8F5C8217DBA9BF62FF3616BC
-:10C16000F61DFDF2A3BD96521E57C3DC15E8C7634A
-:10C17000240F9F95BC9E4388EFB7B8BF624733F743
-:10C18000633F388BC741D20C2A70BDF3FA31960D4C
-:10C190007DB82F8BB1B5DF8DF19D91784D14E70DF2
-:10C1A0003BF0762FF29D9FBF1BBD46BB6785DF2B03
-:10C1B000E8D604BD8B366BB478EF4FD809B1EEF8F2
-:10C1C00092B6B0FB1A89C26FF2F0C47956D41FFB45
-:10C1D000C43B2283FDA934280F79457F54A9E6AFDB
-:10C1E000E1ED3769E73C229FE0E4F97D47E26EC468
-:10C1F000F5B569565C19EEF7D70AFB2E36CDE41D6E
-:10C2000005F37AE49829208D81BCC28E18C12ED8FE
-:10C2100017C7C735BD1E15C07B818FB8CBE99E619E
-:10C22000AD80FBB94ACF3BB8DE07601DED84FE1F31
-:10C230007179AC65E2DC3400F051A8159828876A62
-:10C24000CB68BFFB88D76345BDF9489AC78A71DAC6
-:10C25000D664C581716B716E85DE897BC4E277A07F
-:10C26000FD13078AD484E749E91D53E97E1DE0DA0E
-:10C2700050C18F1A98886FC4F8C27881CF1DEE051F
-:10C280000E7C97C195BBFF5FD04F1F8FFDC5F07629
-:10C290008827A7C0D3AC5295E07689FEE3173C47C8
-:10C2A000F5F1A7AD22AC3F4147D35416C47D9A3671
-:10C2B000BED6CF60FFCC4BE7006B7EC5F1B62A9DA2
-:10C2C000BF8F65BA8BD17EEEB94AFF5EE4B381E4DD
-:10C2D00028927729EE942AE4A394635B67E0BD8BF0
-:10C2E00035BF8AE2E32CE4FC9EA230CB7538EF0424
-:10C2F000BF03F118B95E938F74D421536A74895CBB
-:10C30000BFC90A6B97E32E5DC7C96E5755FEE8613A
-:10C31000D673C47A493E36F07DEC3F725D6F8FFE76
-:10C32000602CD72361DFE5CBE7DBA4FE7524879380
-:10C33000155A67E911E3E13B7B98979841C5B8E846
-:10C34000DDA54EC1C7A0974A91EF1D936CFCBC9D23
-:10C35000F8ABEAF90DDFFD35E42FE0EFF3815AA9E0
-:10C36000C73AFA482FF6F80BB0FE36C5FF38FAD3B5
-:10C37000B71D4FA2F72BCDD1FCFD5153C47B299A99
-:10C38000BED85DCAFD486AC4BB9BDF34ED4E4B2B63
-:10C390007678B0BFB77F6B49F8C7DB3F6947BA57BC
-:10C3A000D9604D3F5372F326BCFF6C7D93973F0DD0
-:10C3B000F980827859467E97C31977D2FC5BDF33C8
-:10C3C000933FAB54F66CC63CFBBD95FC717B0F4CA8
-:10C3D0009C8DEBA4D55EA1A2BD7F40ACE37F156927
-:10C3E000E4BC6493C78FF640E4F7674B35FF9BE7E7
-:10C3F0007817D0B7749789DE711A8C8FE8B2F2780B
-:10C400005461872E10F26CC1C1F5198718BEC35153
-:10C41000F75A29B45F60AF4E4478522F4ACC0FF2DE
-:10C420006F9B389F4D753D27A19C49731DA9447989
-:10C430009FCEFA56A1DC486FD29F97A55E54A8DD27
-:10C44000BE142FF5873F18076A62624DC7F9D92AD3
-:10C4500094F329FCBCC5E488E271A1EE6ADD3D6A73
-:10C46000ED7DDBB7851C35014E8D6590DA147E6F4E
-:10C470003FA2FEEF443D19FDF6E8FC771C3D4EFD62
-:10C48000DA944FC3E34D715F4A426B193FFF043C9E
-:10C4900005701FCA62E3F879A9D7AB86C7DFA68209
-:10C4A000DC359761FC4980E24492C5BD082DAE079A
-:10C4B00030E044BF9B16F7B193E9ED112DD5F6E7B7
-:10C4C000B9CD32ED3B8A5FB5F2FD413B0B5A25F405
-:10C4D0008731923BB91BF8F9B4E617BB0D1713EA85
-:10C4E000257C0F97C6EBA6386ACDAE02FA92DC59CE
-:10C4F00017F1CE94F68EB66134E78B6D2D0EA2A3A4
-:10C50000569EE68FA4A3FE9C53AB977A3195F9E330
-:10C51000C3FB0D527FA9CDFB891F522F6650F9B680
-:10C5200016F532FD678FD07F32F1CBC8FDA751F9E8
-:10C53000F6D0BBCEE9808A9F0EEC77FA54942BA1FB
-:10C54000A99E61F09C7A8F5E4E8EE9D1CB5D0D2F56
-:10C55000DB14AFAB0EF0BDED1E83A78B61FCA9BE53
-:10C560005E4DD66F9CFC5D6BAD7EC83513EB2FE343
-:10C57000F5BF754A5FDF577920B23EC177FD457D33
-:10C58000BD48FA44C20B7025DC1406D7248BFEF795
-:10C59000DACD9E7B095C09B784C175835B5FDFBF21
-:10C5A0006A78B86E2C347F2D5C5ABDEF4CB8B27AE5
-:10C5B00091F39859631E01EFBCFE2DB3AFACDFDBE6
-:10C5C000967C7DBD3B9A23C7096871DB3A7B24BE0C
-:10C5D00099DBEF0E364071269ADD11C71C22FE8BC7
-:10C5E000DB0DEFE07F93197B60B46FCEE804C4BF2E
-:10C5F000F7F64755BC1FC3F515ABE5EF56C2BEA411
-:10C6000034FC5DEE21B85653BF2F61BC13E9598B42
-:10C6100007EDCEE254664946E3CB1DCCC6F7C7EA28
-:10C62000476BF29AC7971709DC3D9BD2BDDC49EBFB
-:10C630003C1887F07CD371EF1DEDBD67F4F8A1FACB
-:10C6400023F95B343C994CDDF47B1D06EA6D1ED466
-:10C650000FEF6211B4DB75B3398476B516877A3C77
-:10C660007ACED10495DE3D588DFDCFBE65EA1ACC59
-:10C670004B87E3D5E536BC37D5AFDD2F5D83785BDF
-:10C6800066F167261AE87CB500F7C3CC172F2E2376
-:10C69000FB4A878BD3D0E0A99638FEA3D2FC0FE3E8
-:10C6A00038D586BE1D3EFCA6F4F17DB62381BFBB06
-:10C6B00084EFEB0CB3FE353C54897E0E193D5F0EC2
-:10C6C000C0FC0E6D8CA57BF80BE26F99836FB22CCA
-:10C6D00034F812F1003D0CEEED04B76D6E6632C217
-:10C6E0006D14705B1204DEBDB95F07F760BCCC7DD2
-:10C6F00092F67E3AE59F0F38E9BEBBD9F0F9BB331D
-:10C70000510F971A3C68776E03FB02DF77FB3F02FD
-:10C71000DFDBF18C258EBED3BB6F6E71EFCBBDC955
-:10C7200040EFBCF8AA5E203AED6AB07970DF3E9720
-:10C73000A9F4EEEA7C710FE60F95FFFD723FCCEF96
-:10C74000A5D1FE83388F3BE20D19EF121CFE627AF1
-:10C75000476BE295C5CF6AE7F033847DB050E07156
-:10C7600026F352DCEE4DCC6FC471DF3E6BF2A25D5E
-:10C77000FAB68847BE8505E8FBAD2C48E96D2C4428
-:10C78000F5BF872FCA42FEADE8D1E9CD005FDD637A
-:10C790000579B81EC3F0FE06D219F8E50E17E79723
-:10C7A0003F2621DE3B13AE887FEB248EBF0746FB7E
-:10C7B0007FC3D7ABEAF2204C8E4969E847195C3F4A
-:10C7C000D5099CFF1447DED7AD9FBEF3DA7D7FAF5E
-:10C7D0002DB902DFFBE23F3778EFA278718CCB777F
-:10C7E000011DFA547ECF11C4863D0074AAA9942974
-:10C7F0006E6FED67E27E363A31A0DE2FC7CAF43E97
-:10C8000099762E395DF4373D8DDF57ACAD9CD91646
-:10C810000B7899F2657F7908D29A34FDFDC5A9AEEF
-:10C820002E7AD27C5AAEFEFB8DAC830E886B4BF415
-:10C8300071E6D323FC9F87706CE0AB8BA345BC648F
-:10C84000112B0ABF6FF01DD1F67CEDE7A673307E89
-:10C85000C918FF57488FE5DFFEC31CDAD729ECCD96
-:10C860007130BF867F97C99EFCA80566528071D53E
-:10C8700016E60583FF24D815983FD5E2A6F434D8F0
-:10C8800001987EDA5248E5675B3C949F35C667198C
-:10C8900003FDCE6BFF4C417DB4568BC7167068719B
-:10C8A000856B45FCC40AFBF2E318BFB08202DE19B7
-:10C8B0002CF68E2908FE9D3DDD473185EF32EE4393
-:10C8C000566C94C8AFB3F0887F0D9279F11BFDD3FD
-:10C8D000514C8CFFCD8944DCA7D7A31D0BACBF22E4
-:10C8E000CE9B340658C0DBFBE1D178A8FFC7960980
-:10C8F00004DF272D5E82EF4F2D3594D68FF1A5539F
-:10C900003DF619BDF3F4ED673E54F0F7B34DF64A2A
-:10C91000E4BFBFCECB8241C0EB662397EF9B41BE05
-:10C92000E3FAAC2C9DB1FD1E86F2D75F80F3BC29E3
-:10C930006EFEE478F83E7DC25C05EBDDF225E8A0F2
-:10C94000AC213EBC1C5F9F794522FC9C79C549F80F
-:10C95000D0F0542FE875E660F177F0DDB3578EC95B
-:10C96000147F7AFEA281E03B7F3C8AE25323DB2FD7
-:10C970003F909384F6D89F807E78F0B1FC4031F9E7
-:10C98000E3FFF4ECBFA8E171BF7F8AEBBEF03ECAC3
-:10C99000A9FFCBE514D89B27B7A21C4B4BA1F77B73
-:10C9A00006E3D5585334EAB10693585F206730FF49
-:10C9B000A728BE0FAEF8796A15AE171C0FE3BDCCE1
-:10C9C000E2F760407F1FFC10FA3BB8D54DEFFD7CCD
-:10C9D000BAEFB16C1C7F6FF7C2F7B742FF6782FCFA
-:10C9E000F7609C61DD675F4479BADB467ECBB512A8
-:10C9F000C085FA744F0AE50B2525AA999C19411E9A
-:10CA00008722A90ABE7FB6ECB92D29C85F784F1DD1
-:10CA1000E3EA5FDA184D72EA25A3E78366EC6F3B21
-:10CA2000EFEFC987EEFDA807D307EBCBEE4539370B
-:10CA300086C7312EF8C9D2226C0FFA9A7EDFF3D363
-:10CA4000CF4B21F48394761E5A8D714C63B67D686A
-:10CA5000488174EC6EA915D3E2F469C7D07F70D712
-:10CA60001895DA8F7B264BC6D8F4A294E0FBD7F357
-:10CA7000B8119D7E2FE9FCAC0AB7999A9E2F92BA05
-:10CA80004F77E1BE38E37819BFDFC5DFAF3ED03B5B
-:10CA9000F39DDB18CE032C08847BAE89E22E583040
-:10CAA000D085743EE32FF4D0BB2ABEC016E4AF336A
-:10CAB000FE44BA5F78D01088C1DFE314F880FFBE6F
-:10CAC000A1E777BF1583F114B1FB8D0C7F2F76FDA5
-:10CAD000D88129141F92AED27E3C7DC70D35889F28
-:10CAE00086FD07BAA89F65160FFA63971CF89CEE9F
-:10CAF000BDB0A93C0EF5CC7E9E7FA0DA4BEF9D2FFA
-:10CB0000E9FA33CFF7F928EF930359747F623EB700
-:10CB1000771E13FA8CF58F66E1EF2169F47A008AAB
-:10CB2000B17C73562019DFBDD2F420E8AF8770FDC9
-:10CB3000A1DB91DA3B66F27BF257A8BF4C421F693A
-:10CB4000FD3D66E2EFF4A218C1DF8BB3CDC4F5EE74
-:10CB50001E9037C82F9ADE857177E0BA3589FB328F
-:10CB6000A9A064C7C27C521F3373F97D85E347DEF9
-:10CB700067D5EC90D9F1AD746FF5D354FFCF701C2D
-:10CB8000EDFE2A533CF4AEE0EF53BD4F8F49E0EF8A
-:10CB900075E01C402FFE02F30D32D85139617694B6
-:10CBA000E5CAF4E2DF52BD07709C2BAD1F29872731
-:10CBB0000AF857D80D8487158F9AC91F3651DC4360
-:10CBC0009D78FE7834CA93157F2E23B9D2CAD8B087
-:10CBD000F879B985C779FF1BFA1120BDF68B7E99CC
-:10CBE000F623470CCB8E827E2510C87F38D01A5B87
-:10CBF0004E792F92FBBA2F0CC3EE17B514E8F52E21
-:10CC0000C9E92FF5FE87EBBF74D0EFCD64B6B82B22
-:10CC10009AF7D0FB3EFAF96BEF6CC1FCFA51BFAF4B
-:10CC2000F8CC40FCBBE2B332929BBD57385FABCB34
-:10CC30007B12E18C9C0FC0FF29D22712FE417E1F80
-:10CC4000B832F8BF2F31FA7D43A0AEC8BFDD2BDE6E
-:10CC500031E85D5A42EF691CC4F748506ECEE0F7E8
-:10CC60008E7AC5FDE4DE0407BDF7F19291E703B7C4
-:10CC70008AF6E27DC8DE5B53F87B1DE6A65F97620D
-:10CC8000FFAD3C3EAED718A4DF53FBFF00D94A30BE
-:10CC900097008000000000001F8B080000000000CB
-:10CCA000000BE57D0B78D4D5B5EFFECF2B33C9242F
-:10CCB000998490072161F220040D3879F10C3040FD
-:10CCC0008268D10610058C71420284BC088FF6C4BC
-:10CCD000969AC100A2C51A8E886851070A14156D6C
-:10CCE000A888A8C13382505A5F69B51E5B2D4D04D8
-:10CCF0009F3C1282F6620FB7BDFBB7F6DE99F90FC3
-:10CD000089DADED3EFBBE7BBF1D3EDFEEFF75A6B69
-:10CD1000AFB5F65A7BED69FFD12097D7C998D13AC4
-:10CD200037E7743E63EFF90C5E7334632D9AFF5658
-:10CD3000630163DE0B16B63B8DB12D31FEE4E53C9D
-:10CD4000BF65D95554FF3DC666B6E5E0BB3B2996A5
-:10CD5000A707FF66BCBDD4CEF3B93CCFD39734361A
-:10CD60009FCA67BB9362787E6178D468760DCFEFF7
-:10CD7000F0EDDE1A87EFD9D4CF10236BA47A69A225
-:10CD80009F3F9A45BB3F30FE97C4D8A366E6B5C522
-:10CD90003236DEB568B8AB9031CF8D1126168D4294
-:10CDA0007792C6E7F348D57076AFC6B3AD0F3116AC
-:10CDB000CFD87C2BA33F351E2A5AC730364F7C660E
-:10CDC0000B16EFB679F87CE655DBBAB4D17C1DD5ED
-:10CDD00077453AF978F33C467F5814AF705389BBD6
-:10CDE000335BD4FD7B3AC675D3B8AC6A10CFF0D4B0
-:10CDF000E4AF647CDC977BACEC5E0E97BFE36F4ADC
-:10CE000020E510636C30639FDAC4F8F56D531F386A
-:10CE1000ADFAE3FF565BEC1BB56894A7FA181F7FC9
-:10CE2000FF104F01FA5F7EE8BA074E5B03F5AA16C2
-:10CE30009764314360DCD07142C76B01DEF878C380
-:10CE40008047DEA485171880BF369B0FF863A69E27
-:10CE50003F2CE5F996F957B9EEE5D99973AC6E8D8B
-:10CE6000E3A1F740982F4CC3F77037D6D57238D26C
-:10CE700067E0F9DB3501FF168DD177EF7EB36F37B1
-:10CE8000FF5667F13DB187B7AB7B79A48B8FCC0E92
-:10CE90005AF87F50FE6284288F72A7AD2F40790226
-:10CEA000E1F725B3339ACA7F6D64541EEECF8AE151
-:10CEB000F06E4AF4CC71F1790F09E3F8B7A35FF192
-:10CEC000FDA4A4BF93BC5BE0D7DB1849FD3299F702
-:10CED000FC7090EF5E5A8F3B6931F2ABAEA6F578ED
-:10CEE000300F3E2FD6A0D17A4F3A7CF764F1F293FF
-:10CEF000ED83691E71921E4E96FEE58DB1BCDEC9B2
-:10CF0000434617FAFCA0C9E8B744A15CE0439B6321
-:10CF1000CDDAC6DB9D7A31D215C6CBCBEEAF7D1D07
-:10CF2000DFCBEEAA9F4569CD9A1B19AFDF79D7FBFE
-:10CF3000A99E9C2BF15156C75B05E1F14E97BB1E94
-:10CF4000F87DC4E569C47A97E7742E619CAECE5B28
-:10CF50003A1E6346C6DE1DEA5985EFDD2F7CB20717
-:10CF6000DF399EB24A47F16598389D807E3B471372
-:10CF70005D2F97F49B9EEBB903FD713896B30CC6F9
-:10CF800022723A2C98075B33F85BD1C9E7EDBB0FEF
-:10CF90006A7C9CDAF0F6064A8DBED1E8E78CE68F13
-:10CFA000D232088E1EECBFB30E7F14F0E131F03C9C
-:10CFB000C74FED5EFDBAF067E2F3AAC5FFF076B5A4
-:10CFC0006D46B70DFB87F92C987F2DB304EAA7892E
-:10CFD0007D083AE0FDECA4FD6AFFA0FC871C0F353C
-:10CFE0004F8CCCBB97E3A736E6D04F26523DDE4EA2
-:10CFF000ED17E39579B59E2BE723D67756EE83B3ED
-:10D00000FC8B19F4B32F4CD03F13F471FE892449E3
-:10D010003F826ECF3F31C287F9C4CB7D735EF31A76
-:10D02000C2D1EE47CCB59BCF8BB9DAC6CC1E85D921
-:10D03000B78D9913C9D856C9D76A07B58D01BF52A4
-:10D04000FC8B59DB46CFE6E52CBB6DF49C5101FE11
-:10D05000C74ADBB2E8BBAF2D0BED0F1A5835E0A97C
-:10D06000E653F354F20E828755ECD79AA7AE26F812
-:10D07000A8715AC047C08FC12FA2AE5CF7CB2E4D0E
-:10D08000ECFFC83109E06B03E13F3B71500E58C91A
-:10D09000F90596DBDDBCDF11DB2CBA7E54BD913E79
-:10D0A000FDF75FA17F4E6FC342F039C4D8F34A1831
-:10D0B0009F2FFB198713BB72BC3765BB279FECC33F
-:10D0C0009F51E09331A7A21B27C149E0E90F1685C4
-:10D0D000A7D5C99C5FD70226E901781DCCF524436A
-:10D0E000AE9C471EF22686E779DA20E1AFF20AEE1F
-:10D0F000A1F477D71F962477F2F6FFE532D0BC4231
-:10D10000E1BA96C30FE52D66767B296FFF79F38927
-:10D110008CD3E6C07A3E6E76BBB9A8E9CB2FD99600
-:10D120006BC5BE5BBA3DD7BA2808EE2D7BF34F38EE
-:10D13000395ECFEE356124D662F2FD64421CBE1B1F
-:10D14000DBBC8CCAAD6E5EFFACFDC89BA8B7647B30
-:10D150004C9ED11968BF745B89BB2A08FE57EFD576
-:10D16000E363549B3E7FCD217DDE9CCB881EFED1A8
-:10D1700076B97E7D3EFF843EFFC93BAB6FC63678F5
-:10D180007E9CD8379FFA227D560ED7EAF7679C809F
-:10D190001CFDF4E0F351C057ED9FAA8E2733AC433A
-:10D1A0004FA71C8F9A89AFD7BB47237A59E60BDD6F
-:10D1B000BF926F5CB1AFD712BEB0B382E92614BF85
-:10D1C0006758DBCD6E4E5F754D6F67408FA99EC56A
-:10D1D0000919F2BB6DB385D9AF1C6F20FEC1EC6E8F
-:10D1E00027E3F457314E944D689ACE4EF1FED8A6FF
-:10D1F000DFCEC07EADF8B146FA46C5B3235E05DD8D
-:10D2000074ED5F703DA537CF24385432B705FC70FC
-:10D2100069BBE68FE479C738E7A14EDE6EB14F7384
-:10D2200061DE8BD68505F819FFB76A53C83CB60492
-:10D2300095F3F92F3DF4CA571AEFBF7ABBBEDD3222
-:10D240000E2FC88F9A5D7F0F0BFECE152182D784DB
-:10D25000F61D46AC7BB19CBF927FCC3B99617D13A0
-:10D260004413761AFFE172C332CC539C5B1890834F
-:10D2700013B688F69CF15560DDF5768B13EBAEB7EF
-:10D28000327F049FCF89488BDBC1BF5FDC1649FA30
-:10D29000C39230E6B5E651CA6C7968E78A46BB8F1F
-:10D2A000DF32929E54CF790FF5F3B8E66B413F46DB
-:10D2B0004DE47F26F2CB989FD603BA7107AFD3A770
-:10D2C000CFB3D641A497D499FCAF002E35AC93E0F0
-:10D2D000CD383EDD0A8E1C6E757C9DEFC542FFD2B7
-:10D2E000B75FCEDAA8FEF2437F0F0BFECEF54C6699
-:10D2F000E5F5B787F394E6EF23381A2DCC6DE0F30C
-:10D3000034DE19EEF3921E521A0E3A354B7D79CB6C
-:10D310003DEE2CCC7BBDE6CE72808F6DB6B9C0C71A
-:10D3200016EE1072684B0CD75FE3486FA6F60BA1A0
-:10D330004F414F5920F8DD9698363FF8FE9607D3B7
-:10D34000843EF53723C1A5E73E9B6FA7067D5AE8CB
-:10D350003D5B368FA0F6E097A44FDD1729DACF1694
-:10D3600070DD32D8E1F3F2FC1F31C524E8D9EE2C90
-:10D370002BB5E37A5A5A404E297DFA67C33C7701B0
-:10D38000DF6ABD4AFF66D5DF4EDFDC2DE567CF667D
-:10D390003E4FDEFF69ADF4B821481F7E2057F0FFF5
-:10D3A00031D3DC7B643D17EA551966DF3B85CFB787
-:10D3B0006AABC1D99216803B73BBB300E7D39B6DB8
-:10D3C00079A0B331D3189D274EE60A7E1E51C0DCEA
-:10D3D0003E9E6E97FD6ECF35E8D2C4704E7FBC9FE7
-:10D3E000D3257E33F01B59506A813CE4329CF87996
-:10D3F000E83AF6E60AB9596529FDCDA47EE6D34799
-:10D4000007C5426F39BD42DB29E625F03CE6DF6DFA
-:10D41000AE165AB7989F823BA79B4292F7926FC570
-:10D42000F4D189EF091B47ED66A54F03FF9A8E4E95
-:10D43000089E5BEE1B45785C28F1CCEEB3493A615F
-:10D44000ECAF282F7152F9379DB7D43A391D5039B6
-:10D45000C7B71FF80E3D6F297C3393AFB0347260AD
-:10D460007C2F1A173346E3A04E36316F18870B64B2
-:10D470001EC1E51E93EF2E3E9FA12601FF1493A02F
-:10D480002FCE9DBDE17954DF6DE1F98A07963237E1
-:10D49000AF5F91CC5C9AA8CFA2519F7763E42964D7
-:10D4A00006DA55448B7E2B1298EF2EA9F7835F6521
-:10D4B000224DA77EDD8658D13E2A8FDA7B0DA2BD94
-:10D4C000DBC4D3611962BFF4AC0FA3FD5371774A7B
-:10D4D00016E860D6343D1DE4E709BA51E9E3794E18
-:10D4E00029675C89D8DF8BD68D24B9D1622BAD7FBB
-:10D4F0000EF87A3A82F4C18A0DB7DD5088F93D33CF
-:10D50000081A0EFBFCC6FD63406F8BD62DF8DEEFCC
-:10D51000711ED96BA3EFED799EF3B9D0B73567F9DA
-:10D5200073FCC3A279472D89BCBDA76DF6B91779E5
-:10D530007AA377FF9BD00B6EBCC948F56F646D7FF3
-:10D54000F923F8C23A31CE0DDE0BA644DEDF0D45DD
-:10D550001A437997CD91BA82CFBF42E2EFAF721FE3
-:10D56000B4D8D8FC5FDA31AF94AC74FEFD0668AA7B
-:10D57000FDE881E3F2A49E3855DB0EBD67D874B197
-:10D58000BF547DF4837E27031EBC9E59C245E539F6
-:10D590005CA97ED5C6B0AE8C28A466FF089E2E2E50
-:10D5A0009866CBE3F566A5B3193837F5DC61643BC3
-:10D5B00069BE3D15B4EF23B39CD8F71EC6FCC4F773
-:10D5C0007C2389EEBBA6F674DDCDF35D3B46B85AED
-:10D5D00088AF8BF3FB620723F9DE3555F035C55F65
-:10D5E0004E3A3A23895EE579BE5292C6474DD3B78B
-:10D5F0008EE5F52BED962EC883C50FCE8D72F27990
-:10D60000566EE1E7792EC7D826FD799E9FB733F293
-:10D61000065F792E0F3D7F83664047559B34A2C33A
-:10D62000612D2E4B12F131CD81F555D9FD99907FA9
-:10D63000552E9B0BE5679BDD0F9CE6FAE1F9E69919
-:10D6400094B2CB1CEE7C9E5701797CDF8FCDF7B86E
-:10D6500000A78AD60A3A4F46E478883F2D97743758
-:10D660008B835903BF317526611F76E5CAEFB18EF2
-:10D670002C3BD1B38D010E5D664716E6D5B5DE664F
-:10D6800080DC9C7597A06BBECFAC26DEFE1E130B14
-:10D69000C77EFF1BDAF37596AD3595EEE0F9A1561E
-:10D6A000668A8C055DE5125DFFBCC063061C3EFD0D
-:10D6B000111B07BDA072D3669A8FA20B66EA281EC3
-:10D6C000043D6F775A1ECED78A8E7E5E30EDDABC6F
-:10D6D000607AB849233AE0E92B19440F7366113D8B
-:10D6E0004CF367AEE4F32A31D63137EC0C89CC1514
-:10D6F000C6E7DFCB7A489FE8E5FA04E499E2278A97
-:10D700006F703A705BE303F8DDD3CCA7C279F2DE29
-:10D71000662BA54F363B9889C3775F7322E59F69D7
-:10D720007652DAD69C4DDF7FD9ECA2FC81E671946B
-:10D730003FD8ECA6FCA1E69994BED85C4ADF155F01
-:10D74000E270213EA4F88AE2478A9E145F0AA5A3EC
-:10D750007227F606B527BEA7F81DD661C80BF023C1
-:10D7600085DF74ADD49B98063ED6B900FCA2C47880
-:10D77000F6E9E7397C7BABEDAE3027E022F85EAF0F
-:10D78000DD4A723ED5C20EE1FCDFB2C2DD75779094
-:10D790005CBDB55A63A620BABDADD1C64C41747B01
-:10D7A0007B538C2E5FD6F4F6B104DEFFDF533C5E74
-:10D7B000E0E5E49D1F3FFA9FFCFBE3777E3E1CF80B
-:10D7C000E6F3D8FD10C65D13DE378F58E4D79949CC
-:10D7D000CE0C0B17E7A461E1E29C843FE0671113D4
-:10D7E000FBF4F13BFF4AFBBCAB29CC6984FE017C16
-:10D7F00071F87E20F1B5A8298CE058B1FED4D3CFC2
-:10D8000063BFAFB110BF5BB44EEECF8D1CAE417A9B
-:10D81000DB87498CF433CDCD581387DF873FB2F8CF
-:10D82000B9EC671F6A569FC61B6AFCD054C6BF7B03
-:10D8300036FEEA3DE8DB5AD309D28F3D56BBDF887E
-:10D84000F979CD6783FBD39A8E533DD63934E6E31D
-:10D8500008DA8A0C708C28705BC02740DBC0DFA21E
-:10D86000EC230CFB9BB56A8EE17C5D55F27BD546C3
-:10D870008DF40E05FF27F28CB4AF4EE79A08AFD3B4
-:10D88000B0670713032339A5E896F30DB70FFBA381
-:10D8900035D7B224881F2F92DF2BB30D94AAEFA7A0
-:10D8A000F9B6443FD3B0B978BFF766A75B1613BF8C
-:10D8B000735AC00F54FD45D9791BD20BD0CFD43841
-:10D8C00016B42F9FCB33C97939841CB37239C6DBA8
-:10D8D000D50D200F947EF229FE773CCD9FCE5F358B
-:10D8E000CF3CF5CC8BB04BBC1F4678AAB946DA3793
-:10D8F000727C63E6925EE3B66B7C9D0D12FFC54FB2
-:10D90000FD29AA93972F3F20ECA73CED42DAB0A661
-:10D910009AEC650D2EBE4FB00F0E993FEC0CA2CBCA
-:10D92000579F793FAA93CE17DE644322527F32E39A
-:10D9300069C381533318FA633D1B1CF62BDB2DD7CB
-:10D940002ED33953ADA3E4F097F134BE76299EEA85
-:10D950001F5E1FDF9F1D6439337DD8B77FC9CEE0BE
-:10D96000D6D9D596B34D178C7CBECBD7CCFC0474DE
-:10D970001E5AFF93BCC838D00F1BCBC6921DC3C420
-:10D980000CC0F74AAB8043AF6F7834FB1AFBCBF285
-:10D990006DBC1157B57A4DCE68179F6F37ECE7FD18
-:10D9A000D4CFC91772FD1CDF478C9FA5BAF719E9C0
-:10D9B000BCD0BD2F92E8BF61DF03C727F27CC32E26
-:10D9C0000DC3B27AD641706A386064D6607906FBBE
-:10D9D000CEA081E759FB546423E869599BE6DECD6C
-:10D9E000E7D36B75460F0E9A8F2D5FD0536D58DBC2
-:10D9F0001882AB9CFFDF253F53F596B53F6001BE13
-:10DA000078BDF3A4BFFC228291DD8CF5BC89799EA0
-:10DA1000D99EEF827D6F59DBFE0692FFFB221CC36D
-:10DA2000F93A3E97767ED5CFE07CB19F06E70BBDF5
-:10DA3000E38CB4E79E79C6487C08F3C43EFC1C7AAC
-:10DA40006ED03C93E53C93F3857E7304FBB130507C
-:10DA50007F595B575426AFFFC9A1B7291D2EC7595F
-:10DA600066EF180DB9F9C98188993E4A7F3AE325D6
-:10DA70003EDEB9B6A9715AD0BECACB3753BFE7B69E
-:10DA80001B67025ECC3748EAF96DB49E33FB9235D2
-:10DA90003ADF02DE5CCF3F73E0D92803ED5BAF686D
-:10DAA00027F168B00A3B6D588C53EA99D656E81BAB
-:10DAB0000BB97617CDF95DFD810B247F43BFABFA1F
-:10DAC000B4DF9270FEEE21BB06FF33807EEB1D02B9
-:10DAD000E725C69C04EC83F26B9CB7DC0A3EF69A01
-:10DAE00059E061A8F3219CABCADF1A44768B956696
-:10DAF0006702F25FBCCE0F827CDEE5F9727F27768B
-:10DB000016C2CED99526E47ADD467E50E1EB19C2E5
-:10DB1000F1EEE54BAEF31999273FE0279A9F9F4E10
-:10DB2000EB7BA4DAE0B6909FC59F05BBE7490BF3FA
-:10DB300092DFE89736E10F481776FD47A4BFA82E7D
-:10DB4000D69F3508F62F89C7BA39BC3C089F753B6C
-:10DB5000FD59D05FCE5A849D0FE50EA479A25E8B4D
-:10DB6000A41BF4837EBBD21CE749CF7C2E9241DFFD
-:10DB7000373C1F29EC0A3FB7ED0C0B929BD592AEB8
-:10DB8000B8CEE4C5FABDBBC5FC302FE8CFCB2CAD79
-:10DB900059D02FD5B8CBA25A69BCB372BC65E1ADE0
-:10DBA000C23F6111F648D4A7F1CD8CFC283D4F84CB
-:10DBB000919EFA7952C7418CFFF9132319E47857E3
-:10DBC0009A6FC9212AE7FA1BC747CD93617ECCF72C
-:10DBD000B327227D8CD7FFCC2CF4A1CF22E3491FA1
-:10DBE0003A11B9B59CFC32BBC234D8553ED3982506
-:10DBF00011E5BB851FA3A6B989FC0F357CBBB33CDF
-:10DC00004A67B258948F247BCB67BFE6FB54A3EFDF
-:10DC10001BF1DDC35ACB7F807DB73782EC6E9F3F0F
-:10DC2000F95F23FBF35BD4ECD2DB97141DA8F27BE6
-:10DC3000245FBA47C2F1BE7C07E1BF3EA26D6B3ADA
-:10DC4000AD53EC578E073A77F1FD110F7BF7C9B64C
-:10DC500017E2353BE0ECCFFA29E0BE579C6F3EDF80
-:10DC60006726BF4BCDF3916EB2E3DC3DD600795110
-:10DC700063147A708D81838FA7DA9D7BB3A067B719
-:10DC80003C61CB033C38BCE91CD9B3DB28C711E3AA
-:10DC90007EB62745D8F5FD327F7014D9F567C5B239
-:10DCA000DBE7909EB37D34E07A7157840174C1C77D
-:10DCB000716B1C3E353FF8A18067F412D2CBF9FEA0
-:10DCC000237E5927F965FDDD13A327623FBD6564F7
-:10DCD000D00B2E9A5C09E087A1F0FA40F295DA8326
-:10DCE0008F5AE0B7ABE3FBC6C3F74DADF48FD53E1B
-:10DCF000A9915E57BB61E243C407DF34B3E17C1EE8
-:10DD000067DB1E880AC6C771C9CF02ED5D54BF9696
-:10DD1000D717ED5F8BA2F9EC31BB309F503C7EEB07
-:10DD2000F64F1ABF55FB3EFA68E3727DF495EBBEE1
-:10DD3000C83ABEFF3EF8C93E1BD9AF38DE53A177C3
-:10DD40009C31B72DC1BACF3C6D233E732646ECF70C
-:10DD50004F383FF48EC03CBE733FD9377E37974172
-:10DD60001E2CF5E9FB55E3BE26F96FFD205734EC78
-:10DD700064F51C0FE88FE3E5BBD4FE2D33B50F5DD2
-:10DD8000C793685718B43F9F8E207A393344E0E335
-:10DD9000CC332348AE74C5083AE7F34DC579E54C5A
-:10DDA0008C481994114E0735F23C7A666A1B9DBF68
-:10DDB000CF68FB29ED328B76354DD26FCCE92E1131
-:10DDC00074039A843FCCBAA903FA04ECD563F22811
-:10DDD000F587C55E6977067D420E651408F9C53082
-:10DDE0005EBCF47F909ED266015FF6483DAE6EDF6A
-:10DDF000957E38E0B76E9F467E2483EA87CF3A4E01
-:10DE0000D9CB393DD67A35B70DF359B76219F991A7
-:10DE10001A37DF0A7A57EBA835B199380F7569467A
-:10DE20009A4F978DEF1BC02178BC20BD2B32300E4E
-:10DE300073C4939E49CA754C819057C8B7F2FEEAE5
-:10DE4000D6699B689C3475AE14EB5370E260B1C028
-:10DE50005EC6CFFBA27C80F5AB7986AE5FCD6778DE
-:10DE600081B05374A539EF2F02BEDF30BA704EBFB8
-:10DE700078393F3AF66BF4329CDCFAECC67CFE79DA
-:10DE8000A0293EFF2F257FAB855D9ACF336BBBDE8C
-:10DE90001F92BD4B9FBF6A9F3E9F73409F1FDDAE89
-:10DEA000CFBB5ED5E787C871159C70EE758E10E705
-:10DEB0005EA438F73AC3C4B917799C7B91E2DC8B36
-:10DEC000EF38F7228F732FF238F7228F732F529C7F
-:10DED0007BF1BDB240F0EF3A6977041EE097612F05
-:10DEE000D8949F9DF64BF78278E29FCA4FDABD2CFB
-:10DEF00087F27D769DD956B2EB90ED86EB25738740
-:10DF00007A6E282884FFB4634312F066EA247BEE1D
-:10DF1000F217853DB72ECF66879DA173FD271BA005
-:10DF20003E650DF5CC41FD6E73CF1EA203939FF8A5
-:10DF300046E75AE75B5304FEC8DEC1ECB1743EA964
-:10DF400080BC8B1D188FA17E15B649EF4709F5AB34
-:10DF500084FA5342E940F9511E37F72481DF9F7A52
-:10DF6000C2BA09F33F25ED646CBE95F42FA557970F
-:10DF700018ED04A795F7693B21A75615C452FBDE9F
-:10DF8000135CDFEE47DEAAB4F252BED0AB557E93EF
-:10DF900066203F8DC74D7268959C53AAD6D37537BE
-:10DFA0006824D24072FCA2DD40E7828BEF18498FD3
-:10DFB00018B1CDA05BCF485FB88EBEAEDE1B1BE2B2
-:10DFC0000F1CA2AB7FCDA1F4107FE0557A3FD54D59
-:10DFD0006B5FC1F97AEEA67C5DBDAAD289217094EF
-:10DFE000F3967A69CB9A6DA9E03FAB227B69FEABD1
-:10DFF0009EB3D1BD8B2A2E5FDC7CDDD5C870FE5868
-:10E000006D75DF08F855B7996360D7AA94F2873524
-:10E01000E9E571B589791DB101BAAB7630770C6F3E
-:10E020007F2EB7758F81E3ED9C61FBD62227FC4BD9
-:10E030003B521D9CAE566B6DF1E3797FA7623C3B72
-:10E040000AF87E4E35FB7F52067EB93F83ADE5F57B
-:10E050004E6D7A368AF46E4967A9664738F0BDA3DB
-:10E06000D548E702D8A7600F52F4B0A3755078A640
-:10E070003DB0CE00FE2FD3FA385EE8DE48AFFDC8D3
-:10E08000D055D0E3DAC47AABA76A5ED293E57A566C
-:10E090004AB9C2D6897E56CBFC69795E50EB3B3BD0
-:10E0A000F295D14EF8359B0FA51AC1C70DFBF6248A
-:10E0B00041BF48F0B463FF54EF18FE9F457CDC9AE3
-:10E0C000DF1B19FCC81F6D991E351EFAE7D366D7F2
-:10E0D0002C9EBFBBF567169C0B6A4C3E0BCE9DD5A4
-:10E0E0004FECB0C0FF7FEDDE1DF47DC9DE0A3A6F54
-:10E0F0002F658D748EFCD42CE4B48247F5346DBB4F
-:10E1000083CF3BB350F0D7EA70711FA4C458742C6E
-:10E110000EEBDDABE562BD3795EEB754F0EFEF4A9D
-:10E120003E1CBA3F7A5F9F5B321876A536E1071D29
-:10E13000683FCCF38FA4FD30F7521AA5375DBA9A29
-:10E14000CE55BF67A5A3884FE4849C675F370ABBA1
-:10E1500059BBD807D5167FDC5CEC9397CDB44FEA5A
-:10E160004DB07DE39CCCD8049E96161975F4BABCCC
-:10E17000384247CFF359ACCEAF7C331BA2CBDF3450
-:10E180002B4357FF969BAE0EA1FFBC4039F191097E
-:10E19000BAFB2BF56BBC4E8DEC68D3F4DF79BA86F5
-:10E1A000E8EC7A5DFB7A3627500FE7E05DBF253853
-:10E1B00033D661C179ABDA20EEEBCCF774C9EF9DB1
-:10E1C000F49D2F44B70F8765B8FE53C84533D9E790
-:10E1D000957D7A3EFE3FA33FB9C8112DC78D360A03
-:10E1E000FB8247AF7774D0F993093CD44B7B4F7DCA
-:10E1F000B6B0F7D47B3B2C8D7682BF299983A4A13E
-:10E2000055237B1EAF6F4D8E15F935F87EC01CB0BF
-:10E21000B330D1DF25949F305660BF849637F075B8
-:10E2200043CF6880BD86EC4C333F213B931A47F6C1
-:10E23000AFE874E936BDFDA801769D207C2E2B74D5
-:10E2400012BDD6ECDD7F7C0887CFDCD2985CECA3D6
-:10E25000BAB6D9E68A9C2BE94DF1F98BD506F27B4B
-:10E26000F7BE7E94E8ADB7DA4474FD4D7069700B6B
-:10E27000BB66281D2EE1EBB2F2F1971CD05C3E4D3F
-:10E28000D4037C86803E43E093DC0FDC14BCFAE0D0
-:10E290001752BE14FF5380FB049ACF9FD61F5C42D7
-:10E2A000E0A9C60981171BA787C7128FF32DF09F1E
-:10E2B00025278CCCF72DD6BF14EBC43CF83A318F10
-:10E2C000399784DD44F9136EBE64A27C1FDD94721D
-:10E2D00078E561DFE9F7691F1D958A7D33EF523CD0
-:10E2E000B5FB57D1D337D1919ABFE2DB817D74174B
-:10E2F000C98DE58591711F7356C1FFBF90F882E407
-:10E30000AF03EBA55EC1473D7A3933ECCE7174EFB4
-:10E31000A8D79E4E7A459F1C72E8CB5746A627A0E9
-:10E32000DC23ED768A1F7B643D354E052F770E0288
-:10E330005D0F8D873D76C3BA8CD4CE207DC5B3DE0C
-:10E340001C0F7B61EADA419456D81CF19023156BBF
-:10E350008DA5908F1FDE93103F0EF6F9F5E6B859A4
-:10E36000BCEB0FEF284865A3902FA1F4D4E6B0F9D9
-:10E37000C1766E956E2B147A68FD9DEF915C3B67BC
-:10E38000783D6A3EF6DDFAE7A270F5A676FDDB631E
-:10E390001C5C25B93BC6F35021F95177EC71006E36
-:10E3A0008E1DA361A7FE396C688303FA43CDFA92F0
-:10E3B00004D8C5EAFE76F431C87DCF5A733CF4CF59
-:10E3C000CFDEE1725123B9467AC3A73646E7A54F9F
-:10E3D0007747F8E0BFFF54636EF87796195F19ED41
-:10E3E000D0C9D9F69B318FBD099E9F1716627CDF7D
-:10E3F0009E448CEFF2D2FD4CCFDAE1D1FDD95154DD
-:10E40000BA7C9BD0EBF6283BAEB4F7429F471EFA8E
-:10E410003C1B21F479E4A1CF23853E8FEFC7A41DD7
-:10E420007F584B4F2ECEA3DE692CBB91E4AE3D1B33
-:10E43000FAFA2A2DDC457AA6E64A807D8CBD1323A4
-:10E44000E46D087E553AA987EB5C41743FE59295EF
-:10E4500005DF339BCA6274F9E9D6245DFD12479A41
-:10E46000AEFCDAC491BAF2EB9CB9BAFC77B2C7EB56
-:10E47000EADFE09AAACB7F77DC75BAFAB3DDB37531
-:10E48000F9B93317E8EACF2BADD095DF327F99AEDB
-:10E490007C8167852E7F6BF51DBAFAB735AED595B1
-:10E4A000BB99C304B9D78E731687FBCB3867F17459
-:10E4B000D51BC3EDC1782D9A6E68ECCF4E7F5EEA16
-:10E4C0004313C7BA3F037DA418041DF2D40D15E20F
-:10E4D000B2942BC9CCAF89736E4712E826B45E683C
-:10E4E0007951C4918B4E8EC32507636F35713E52AF
-:10E4F00034F6487E06CF3F336681C84F3CF26C3A13
-:10E50000CF1F3CB8F55613E71F45D71CB988F2D189
-:10E5100063CB457E2E2395E3C898BF2DF4F2751486
-:10E520004D49DFE41276927EEF69AA1470C0FD4671
-:10E53000C001A99FD327D2239C3E91BECAE9B3CA8A
-:10E54000CCD8714E9F484FF0F326BEFF869F37917F
-:10E55000BECECF9B48DFE4E74DA41DFCBC89F47719
-:10E56000CDF3297DA7D943EDDE6DAEA6F4BDE64619
-:10E57000FAFEC7E6264A3F68F6D2F7C431CAAEE0D3
-:10E5800027FB8BF23335C0BF07FBDC21F3D9603F9B
-:10E59000ACF2132ABF604B23EB8CC03EED34C57C3C
-:10E5A0006C0DF8FB06E6B326F671901EB639D19DC8
-:10E5B0003186C61FEA207F8FFC3E4D9B9B02D7DF32
-:10E5C000ADA33D23C7707CCFCBAB5C1FCDF9C79407
-:10E5D000CB8D66D0CBEFE53DD5D0FE2F4B3A891BD6
-:10E5E000EB1E8D7693ADE21EDE64ABB86737D9D4EF
-:10E5F000D9027ED4F22573E21ECD2B9116E24F2D67
-:10E60000F7987CB0536A5F30CA4F8A63946FF9B24F
-:10E6100083EEE54D76B81249DEC87C9FFF1C7F4132
-:10E62000F765943F5BDD9329FEA2733AF480497647
-:10E630008B332CC4FF0EBFF52B91EFAAF9308CA7BA
-:10E64000FCE4BBBE647EC3E8803F7CB2B5230D769C
-:10E650008249ABADAEE0FB3FCAEFAD7DD161843CFA
-:10E6600051F77CD4386ABE9126DE5F5EE01ECF642F
-:10E67000475B2EEE35B4D4DBA9BF04FEDD9247F52F
-:10E68000DC466AD7960B3BF0A43ABB0BF66DE56F00
-:10E690004F90EBE6F5689DC55F78E8BEC12479DF51
-:10E6A00000FD5845B917FD4C8AF32799B0FE468BFB
-:10E6B0000BF6D04735DE3E2FE0FF47FD88A0FD8BEF
-:10E6C00079A2DFCCBFF0F9426F77BB09BE73D5F9F1
-:10E6D000CD29F3523E33EB34B25F1965FEB7A33D4B
-:10E6E000CB81F7D230C79F22689F67A4C0CE315B31
-:10E6F000EAED5F432FABFF7BE8C52DF03D94913DE4
-:10E700002D946E145E149E07A22385F7A0FB5A84F5
-:10E71000E7BEFB57B29F50FA1A88AE143D4DB60AB9
-:10E72000BC03AFB847A3E848FBA26D07ADA3CE4A30
-:10E73000724ED151281D5C4947822E5BBE67A5FEF3
-:10E74000AEA4A300FE018F7F9E8E3A8C90BBFF2863
-:10E75000FDDCDEC36644F3A27BAFF15C86DCA8B8C7
-:10E76000E43C8E7C259B3A0324A5CA1F40F9E02B8C
-:10E77000CB43E94BD57F7180FE3C5FF498A383E8DF
-:10E78000729294817F18A0FE6BF25EFC6B3675DF8F
-:10E79000C36DCFE574305DF2E1552582BE66A619E2
-:10E7A000C99F313D6729E9F7CC2EF46327FF87EC39
-:10E7B0006DD2BF7EBD6C37E372E93A8C33234EAF26
-:10E7C0007F5F2FF5EE9921FEF6EB73AE253DFCFA47
-:10E7D000103DFBBD31528F4E6369E27CBD89F4DF91
-:10E7E00062B91F9325BE339C4656C4E15EC23C26E7
-:10E7F000088157CF5BDCE8EF5AE6A5FC75CC47E90A
-:10E8000077989FF4801BB8C040FEBB8CD1FDD1A38C
-:10E810001137962DE7FD4DCF9F9E89EF75D69E54FB
-:10E820008B01B7033D9F413E34183D7F869E792E74
-:10E83000C53302E7E323C54ED2C38E5833482FC4F5
-:10E840007E3207D92B7FCDE56826977347B99C4563
-:10E850007A8CCBD94C2EEF7EC5E52CF2D767AF650D
-:10E860006837C3A9BFDFA3DA7FC7319D99060D2C96
-:10E87000C7BE33FA85A1B063BD1633A218787B2DCD
-:10E88000666C31D6FB5A4C8241A461164A473D9FC3
-:10E89000D99FDEAAE83530DE0C1A2F14BE0A9EA1DD
-:10E8A0007054F0FD27E039686CE195F0BC0CFD1E5A
-:10E8B000F653EBDB5189E9F033CA78BA08C107EBAC
-:10E8C0009F1F958075D459055C26354DA47472D36D
-:10E8D0007866CA273F9317F0FD0C4B80C139C4CE30
-:10E8E000C64CD328FF3D495BD9099EE198C7D93C66
-:10E8F0007F16D7C8D827DB5BA2703FF3DC334617FF
-:10E90000CE357546E72617ECE4AF19455CD0E5A394
-:10E91000A9F06FB25DFDDF97AEB32AF87909AE3F7B
-:10E92000BBC64DFB8DC13B1B1FD06B8686897BC64A
-:10E93000E45EC81B58CF19132EF8CCD030C11F1578
-:10E94000BE783B2177793F63385F4BBE3F9CCE3525
-:10E9500005C3DC45580F3F2F505C516F7604D92B0F
-:10E960007E23E31227FBAFA6B8BC9938B7F3EFC6F6
-:10E97000F0A89DD8F7BF917189BF18E4B916EDAF23
-:10E980004DCB4B043CA630E157B9CE6A76F9F99CE1
-:10E99000AE1B2BF7E168365AC6F5E8CE1FCA4ED239
-:10E9A0001B6724393499653D043B41F10933D9098A
-:10E9B000FAEEBB250ABF68EF898B46F09592488D29
-:10E9C0000D4A0BC4E784251A9833486FB739C399A9
-:10E9D00033687F4464C7EAF291AE21BAFAD1E3D238
-:10E9E00075E531EEAB74E58366E6E9F2834B27E823
-:10E9F000EA27CC9FA6CB2779AED7D54FAE9EA3CB27
-:10EA00002BBE972C3EB194C685BAF6C39A16E9EA96
-:10EA1000A7796B74E50A0FCCEBEEC88E075F147F05
-:10EA2000191B57EAEAFD344AC49BCCB42F9985FDE3
-:10EA30003EBCF507FA79195FD7287ED429F8AD973F
-:10EA4000FF033A2A49D4F3DFE90EBD5D23B9D1A40F
-:10EA5000CB6FF847F1ECB94A87E7507870BCBBFC44
-:10EA6000A8CFE5B797E74B7E5D69827E01FF45F051
-:10EA7000FCE1BF085E2FFC17C179F82F82EBC37F42
-:10EA8000115C0EFF457079FE093D9E0B3BF4781E2C
-:10EA9000FB9E1ECF8AFE06C2C7F84E3D1D84E26370
-:10EAA000E2A7217421F1309FFFD31F1EE828C2E99D
-:10EAB0007F7A2323FBDC37E1E58510BC4C1AE9693A
-:10EAC000C77E9D3FE862AA0578EAF18CC079F233EF
-:10EAD000692709BDC7E9E5EA00C521FCC048F1374F
-:10EAE000270DAD1AF8B23FC5736C2CAF7F7B4E2358
-:10EAF000D14F222BDDBF84CFA7FC3FC2C88F533E2E
-:10EB00004CC4EBB29C4E8A7350FCAE3C59DC237A69
-:10EB100063AC3CBFB9C47DA28EB1429F8D7439E80D
-:10EB2000DE71458E88E3E0C7AED4F251A09FD76D69
-:10EB300023400F5B84DFA413F1C271817861E89BED
-:10EB4000D0EF52A47ED5F207AB15EB18B18DE9E4F6
-:10EB5000E4489F5577EFF5EABD0E5D7E545BA2AEAB
-:10EB6000FE35879CBAF25C7FB6AE3CFF844B972F94
-:10EB7000EC18A7AB3FF63DB72E3FBE73A6AEFEC462
-:10EB80004F4B75F964D6F330E03B4C13E77D2BE730
-:10EB90004B740FCC29E281CAEF8E1171A0D20EA066
-:10EBA000F469751FDA23E92E544F1F66117A6A4BF8
-:10EBB0001213E730AB3C6F31BDBEEE91F799959ED5
-:10EBC000CABCFAFBCCEA1E739F5E2FF576A51F0721
-:10EBD000DD637607DF632E97F1DBA1F22F6E9CB029
-:10EBE000EF85CE7F9845ACB7E50E0BC58DA879852E
-:10EBF000CE67799EA0DBDDD6FEE377D2C769D47FEE
-:10EC0000516EE99071BCDE6366978FEC28578CE7F4
-:10EC1000EAF4E25CF9238BEB2EE7378F577E8D58B1
-:10EC20004F99C170FBEC1CBA2F36FF9741E3E78D7B
-:10EC300013F41D3F41EB777DE5D1E23E178BB638EB
-:10EC400041BF038F27E0996861EB28CE48DEFBBF08
-:10EC50006D53DB7D23785199A5D54CC60BE63383E4
-:10EC60001E664DE3FA542EEC822F3E62E7FAC6632D
-:10EC70004D26B2F38C1F37AC8C6B627D711CC3F8D0
-:10EC80007903F4019D05E79427C71B699C85E3C4BC
-:10EC9000FA4A8C97FBEEDF93FF8231C9BF19DD87FB
-:10ECA000E987DE880ED53AFE55F7F115DD86C249B3
-:10ECB0009D2F99943B99725E0A7E6A3F28F8A97845
-:10ECC00008E70A73E94E3BC555CCC43D3285BF9772
-:10ECD000C70B7EB409F02814F5C08F06AA5762CC82
-:10ECE00089863DBC9739A31D5F63EFFD17C62910C8
-:10ECF000FC078AAF1A883F5CC1170688B71A883E9E
-:10ED0000E9EF1F88BB0AE20FE25E8FC4872FD34072
-:10ED10007EF4BB23F5FBF8857102BE1EB98FB97C6A
-:10ED2000B5E7EAF90483FDBE65BD51F2092157A19B
-:10ED30006FE0FBE2F566D237182BDD8A38A28FB67A
-:10ED400098E97EEB64B773864BF8E749EF20BF176D
-:10ED50009F5A85572F4FB97CDF093D780A736D8024
-:10ED60003FA372A3BE7CA97DC66790E78B43CEA567
-:10ED70004BE5797569C8B9F4A971521EBB988BF43B
-:10ED800024E9E7AF9675FAE8C897112DED2EB43F48
-:10ED9000794AF7C2145C9CF0D7E407F21C7EE1D9F3
-:10EDA00090D3EB4CFDDED7EB83DF00F711CEE23ED4
-:10EDB0008213FBBD97E2AD7A0FD8849F52F983642A
-:10EDC000FDB3DE8B548EFAE8ED5C6EC768E8217DFA
-:10EDD000FEA3103F54AFDD10350EFDED33537FEA37
-:10EDE000BE45CD5F7DA31D41FE644FA75177BFE5B2
-:10EDF0008AF9AF7D8EEE5FDC1DE379077CFC8CC960
-:10EE00006505FEEEB11F89479CFC2C69B7099D6F13
-:10EE10009FDE59A4093FAC57C4CDF6CED4E81E00FE
-:10EE2000E7830CFB46DD1B98CDFC7148953FC6B3CC
-:10EE3000713CC159F9632AFCE3699EF35A969AC35F
-:10EE40007995CE87D794843B037E9ACE1471EF6771
-:10EE5000207FCDDC4BB9D4DF4D9726523F17C7A595
-:10EE600009BD6BDD7D2B404757ED6566ACB333E4E0
-:10EE7000DEBB4A2B25BFF18E577C5ADE275AAB11D9
-:10EE80009DAFD498BA5F447C5AE52FB6CA7C89C836
-:10EE9000AF5A2FF29D66F1CECC1E696FC03A9162D7
-:10EEA0003D3817EF93F608AC0329D681EFE04BC845
-:10EEB000832F210FBE843CF81252F0257C5FC44A98
-:10EEC00053738DC2AF541CB46FE0572A0ED27BE04F
-:10EED000570ACEC3AF145C1F7EA5E072F89582CBB3
-:10EEE000E1570ACEC3AF145C1F7EA5E03C1B775DE3
-:10EEF000200F3EE69EADCBCFE5FA7771D0BE855FA1
-:10EF000029B87FF89574FD7956E8DADFCA9A74ED6E
-:10EF1000E1570AAE7F7B93A6F33BDD2EDF03A8DC2F
-:10EF20003688E8E3A5D1A5AEF17CBFFE39E26FDFFC
-:10EF300033E31C606C5F06BA5D591FEE12786E9D5C
-:10EF400029F06E6002CF3D0B08CF6B2C225F22EEC2
-:10EF50001FF7E7BF29360BFF0D52F86F90C27F8372
-:10EF600014FE9BE2E1C27F8314FE1B7C87FF06290F
-:10EF7000FC3748E1BF410AFF0D52F86F90C27F8312
-:10EF800076F0DF2085FF06DFE1BF410AFF0DBE9F5F
-:10EF9000841F29E8DD0CE8E999BA731DA743DDB9A0
-:10EFA000CEA1CB434F0FAE0F3D3DB81C7A7A7039DE
-:10EFB000F4F4E03CF4F4E0FAD0D383F3ABC739893E
-:10EFC0005F425F0F6E077D3D383FAAD57B0CB6A32D
-:10EFD0001BB69F7F156967A4F698C659C18A170E9C
-:10EFE00094C1CFD669D3526338A7346B2F9615F3EB
-:10EFF000BC47DEE31BCD7A0CC037F9D939DE3C7E45
-:10F0000046F78E477D9544E5CAAF4B7F1CEFB907A5
-:10F0100018E9FDC764BCA76AEF620E2352553F9002
-:10F02000EFBF5EE8F8AA1EF1CBA079F083612EEE67
-:10F0300099E4AEB1E7E1BEFC1E8326EE9BDE25EE31
-:10F04000FB86D2D56EC997F618F61F09C7FDA10A2F
-:10F05000CD8538862C133B61CE039C1AF3A01FDCB0
-:10F06000373E46AEAB7102EE1FA9792B3B20E7136A
-:10F0700014BF56D4C32C557C9C495F30CB62F077CB
-:10F080008BD00BD00EE7C5ABBD9A7B67107D3F34AC
-:10F090005EC8378F77C5842AFEFDEA7D8D13101771
-:10F0A000372B5CB4FBF9E35104C71BD7693B117FD5
-:10F0B00058B48FB911EFEA93F3BE7A9FC35245E378
-:10F0C0003A289E4EF55BB13D95E2FF2A586731E242
-:10F0D0002B5881C6E01F5570E3EB7B15EBCBE25B51
-:10F0E000C54CFAA788CB099771392A1E272CA6B4DC
-:10F0F0000A724BC5E54C2A8829C1BD38D6CE5C08BA
-:10F1000003BEA1A062FD60DEBFC7E776E15ED1A4C9
-:10F110002F1A8F517E5729E5890CC6D03824D7463F
-:10F1200078357A5FE346EF0E439C13F1BA6BCDF16D
-:10F13000A8BF8FB9A0EE70514371A76A7E39ACC3E6
-:10F1400060D38077767450101D710E7013F09EEBB3
-:10F1500032D3FB1BB34D0E33F846A81CBFF2DE6260
-:10F16000889E1072BFA465CD7BA9C674DC2F31B810
-:10F17000FCE05BCF4590BEA0F49D0A79DFECE2BADB
-:10F1800063836FE1E515FB857EE0D9A611FF53F798
-:10F190004DEA337CA906E80B43768C8E350AF90FCD
-:10F1A000BE78C6FBECCDD8A215EB8F515C44C5FAF6
-:10F1B000C268111725FC1055124E55F25E11CB7125
-:10F1C000C443CFFC90F31DF708BA97184D7185AD75
-:10F1D000429F53F616A50FAAF7632ADEC83F0EBC5E
-:10F1E000573C2ADF65D95841F157A1F77C6AA5BE83
-:10F1F000B76C9D99EE0F2D0BD1076BE57DA1DA1051
-:10F200007DF0DCF8107D509E5FD47DDE8A378ECE97
-:10F21000237DA5D14C7EB9B2B5427F61FB990FF138
-:10F220000C656BA71BF06E48D9736E97D60F9DBC0B
-:10F2300025F598599D3682EB9C4BC994DE7C298933
-:10F24000D25B2E897B94887D011D74BEC0488F7E61
-:10F250005BEA2DF370AF12F188DE30797F9291DE98
-:10F2600094CB1C25E01F57B9B5A350FB66993DEB25
-:10F27000716F73D60E46F1473740BF41FC17F41D3E
-:10F28000D8DD0BD24A280E63A646F12C3714AC9079
-:10F29000F4CDE99D81DEBD927E4B29DF2717249DA9
-:10F2A0007BBC5D26C0FD06AF66C13B7C1E798E55DA
-:10F2B000741C4AEFE511D2FE6417F6A53EFB132637
-:10F2C0008B476DBCD1B7E17E6B396C764398403C7F
-:10F2D0008779648E281FF162F46DEB70A8F9BFB4D2
-:10F2E0004B94190C22DE89EB5BE0ABB7ADCEB52CAD
-:10F2F0000AE22F5F4C9C3663626100EF8B42E2F4BE
-:10F3000056DE333CE1EBE2452B399CB14FCAA33BBF
-:10F31000BFC729945D3B81B98BF999750163EAF107
-:10F320001E3FEE052E94F9D52F8EFBD3463BC187A9
-:10F33000F2D327A4DEE625BE2AF8D6ADE05B46F080
-:10F340002BCFD409C4AF3A67001F11393DF21D021B
-:10F35000299742EC10AB2738C57A43EC11953982D6
-:10F360009F339333F5568A0B76923D4FCDFF43B3CF
-:10F370003E4EB3CF2F3241CA93E67F4D7CC3FFCAC6
-:10F38000F0DC86F56D3588B8F921C65626ED42B415
-:10F39000FF15FF60F21D8900FEB99E467E74CD11F7
-:10F3A0008C7FCF464DC4A90F60BF61D93D0FEF865A
-:10F3B000FDAED9C210E7FA7896A0A3C77F60213DC1
-:10F3C000BCCCD2710CEF642938BEDFF4EF66B2CB4F
-:10F3D00033FF70BCFFB5B0D1E6027FFE6262E92A5E
-:10F3E000CC3B22C745F898C1B719FA3F9952FA7D2C
-:10F3F000C2D7A6571E43DCFEF2F6348A23AD3894FA
-:10F40000BB01EF897C31D1F3C309F0E3DA1D16C8E3
-:10F41000F186753124D7CA13645C27EB213F9582AE
-:10F42000FF031384FDEABA2241C7DDF23C028639AC
-:10F430005B574FDEE30ED927CA2E186A5F087DC7D7
-:10F4400061A0FDA3EC08B01B5882EC8ACA2E61CEE5
-:10F45000FE7001E46899451F7FA8D25795DD4D9E47
-:10F460000717F7C9B19C1909D09B376B0EC8B12A91
-:10F47000BBF396F13C5F75C28C1B986C56AC53BCC9
-:10F48000DF718F78BF6311DFAFE03765F23E56D58D
-:10F49000B6F1B4DFAA7C3CCD1F785FDEBAF968CA4A
-:10F4A0000BA01FBF9BE2F2AB1C6E4B6CD0BEAF6CCF
-:10F4B000D57471FD2A7F6082B0C39571351DF0BB94
-:10F4C0006D759A056FE89471F502F7FB5E9DE0D4C7
-:10F4D000C555F37A74AF61563A3B2EDE4FE2F34ED8
-:10F4E00013E3E505F5BFA855FF3E01AF4F7AD1CB39
-:10F4F0001322097F150EBEEE34A40E9A278703C18E
-:10F50000A9E73EDE9F93C6217C54FA7D669CBBCB67
-:10F51000709F82E7173A7C668CB3689D782FC4B3DE
-:10F52000498CE3D918631905BDC9E4B0A4007E383D
-:10F530002CC7D1FC880F5671B820DE4AC55D86C243
-:10F54000A742CEB7AA3546AF8FB56E36031F0B065E
-:10F5500078AFA047D2EDA2755329DEBCCAE4A678E5
-:10F56000068F84EF472B6CF7C22FB060CB43E63495
-:10F570009CB32708FB738FDC77B3D2FDC3E95DA092
-:10F58000153617E6B9C0D14AEBEB83EF831C1E1A80
-:10F59000DE9F2925F872BAF0E27E5ED5163D3E0365
-:10F5A000F311F0ADDA5241FB6D89C9637104CF6389
-:10F5B000DB2BC3710F6501DFDF78EF88393C14DF87
-:10F5C000F4F183B7A4D23AF93CE91E94CB3903EFA6
-:10F5D000FC703A213A56F4A2E2B2D578D689222EAE
-:10F5E000D33AF19BF6A59BF49A168E5FD8BB07DA47
-:10F5F00097160476F1712D55E2FDB5D07DAAF6A7D8
-:10F60000DA976A9FAAFDFB98B9D49FA805F80C97D2
-:10F61000B78DBFEC074E33E47C174ABC72B8BE1AF4
-:10F620001CC775CD4481D7B274FD7E477FE837652E
-:10F63000A2D8EF65D3FCC31177A9EAAB71CB6245C1
-:10F640003BD03DE82D65A2A1AFFE4AAAAF8F47A9E6
-:10F65000ECE317FBD6C7835FECD748EF5D79DFD1CA
-:10F66000947F833EFBB4D067CFD4ED6E4882DE68D2
-:10F67000F2A506BF8B55E517FC6131D77FC02F96E9
-:10F680004839DD9EE7C99918B47FAB1E783ACB2381
-:10F69000F88B1FFCE583A75FFAFD0467407EAAF99B
-:10F6A0002FDAF85B73853D185E627DF766F7529C32
-:10F6B0005DA5DDE2C4FDE5CA7515C46F59223F574B
-:10F6C00068017C87D241C53A8DDE17AB6C1AE333F3
-:10F6D000FE37F2E5CA4DB3E94D248527F5DE899260
-:10F6E000A76AFEDF95F35F28E978CE44B1FF16568E
-:10F6F000A75996D0BE4FB35482FE65F9822AFDF712
-:10F700003E3CF5F9977336607F206E88CE279BCC00
-:10F71000C2CEB72F92F4D5332B9F7FF3665EEFF303
-:10F72000AD3B52A19FA8792C95F6BCC5D22EB7440B
-:10F73000EAAD1C4F15C1785AFAB8C053E5336FFCD7
-:10F7400009EF7295A54B7E769F88E75FD4B69FF050
-:10F75000B660E366731AAFB762629AEE9E4C652399
-:10F760003FE872782EDCB8C30C3EB062A2805B2802
-:10F77000BD97C9FBBE0AAE903B5A90DF42D507FF4A
-:10F78000DBCFC759BDC21605FBB41AE71149D7959F
-:10F790008D31B118AFB2B1E2273877287E1FBAEFAA
-:10F7A0004ED9C47E58C4FBC3BE3C35D54571CDF09F
-:10F7B0006BF52757374BBCFDD42CDE6F4C8E687B26
-:10F7C0000270485E1EEE027FC8CCEC24BF31E819FF
-:10F7D000F3B618C47B8F99759D17300FAE52D3FDC9
-:10F7E00014A478670A2A763CCFEF3488F8AB74A368
-:10F7F000489F97F0E1E57E94B3B84E7A77AEEFDD9F
-:10F80000A4107AB5B05D1BF1DE8D258EB95A9C012E
-:10F81000FA54FD28FA54F43BD0FA7E21F9C837ADEA
-:10F82000EF549AB44764BB5211A7527EFF0817ECFD
-:10F8300033DFB44E8B7C7FB06FBD9C58C7C5F6B329
-:10F84000DE4C716E1978BD5B4AE2FB596FE83AD520
-:10F850003E5177DAFBFC0BADC2BF704AE3F28BB7C7
-:10F860003BB5C246F7BFD4BA94FDFBDBC621BC3D15
-:10F870003156DA133A23A1479685CBFDEF17797CF1
-:10F880009F1DF45DC97DF55E9BE2CFA71BA55C645F
-:10F890009DF7613FB3A60C7A9FE464EBA948BC973F
-:10F8A000726AAA989F6AB7DA2CE28C59A4C589F7C4
-:10F8B0000FF9F9EA6413FC3EEB12E81C795B53067E
-:10F8C000F185DBBC31C2FE20F5FB25920F46ACAEC4
-:10F8D000D88077BE176F4B73687C9CC576D7C7DB23
-:10F8E000A8FDD52EE883115B665BD249EF15E700D2
-:10F8F000E5275AADB1528A1B039FC4FE32BC920960
-:10F90000B9B3749B3807CC32B08DF0130E6B299DC0
-:10F9100091043EF1B04671E66CBBFE1DABB1F9A59A
-:10F92000E7E9FC17F20EDC6A739B3B017C9CEB1B46
-:10F93000B0372DB69792DE5E2FF9E4C92D5DF41E27
-:10F94000BD82EB15F13F161107DC1369203BDCB7D4
-:10F950008D03AA927E254537CA2FF508FE331E7007
-:10F9600032925C2B3196D17B4A1BB64CA7B46A739A
-:10F97000C956EF28C41F97C64FA0799BC94E56554C
-:10F980003F5DC4EBEE0C8BC1F926D5EC4D0DD64B8B
-:10F99000AB76DC4DF13F9FEEB051FC4FB163767119
-:10F9A0004C1CBD774CF175AA5E6A91E03B35F5D3EE
-:10F9B00075F13B8B799F7867F3CBB608BA1FA6E247
-:10F9C00072EA123C494583457CCE78A788CB49A290
-:10F9D000FACE7EEDE22AFDB859C47904C51BDDB824
-:10F9E00080B7AFAB7F360AFDD43EF8F6188781ECBE
-:10F9F00050C3D17F5FBCD136116F9425CF4BB3621A
-:10FA00004B6F5E00F8FFDA48F01F68BCEA439ACEFD
-:10FA10008F779B2F9AF4568F9F59E047F63818E955
-:10FA2000C59F1A5913F400A5BFA8EFE3255C3E8DCE
-:10FA30006E4D057D2CDBF3502AE4CB6791225FB637
-:10FA4000E796DF805F79768509FDDCC4481FAEF458
-:10FA50000AFD9A55C7AAF7486DE59C8EA6174588FA
-:10FA6000778FB6E9E3CDD53BB79F99C4FB3C883788
-:10FA700002BDBF6FF22F067EDFE7FA2BCEB1A9459C
-:10FA8000823EDF6F35CEA07B437CA3400F79BFF56C
-:10FA9000D948C4432B7DADC4F8811BEFFFAC7C4E2D
-:10FAA000C405E37D7A7A2B54DA411AA41D64E50B70
-:10FAB000E619C971A47FD1973A93DFD21FFE6AA4D9
-:10FAC0007ED5973FB09FCE6D75FB84FE50D7D6454F
-:10FAD000FA83D24754DC61EDBE2ED22754BB860395
-:10FAE000022EF507C4F78A6C83B2A3B8B54C9CA765
-:10FAF00035CA7B5FCC2F5F6B0ACEE795AF05B39F0E
-:10FB0000A0EC233DA40FDE9BFD3B3A87D7AF93FDCE
-:10FB1000F2BC3968BC6A1051A1F89E61477BA7EE20
-:10FB20007C577F2086DAFBEBC33742CEBB1BEC262B
-:10FB3000A42DF57692FBDB1B0DD9B8A7EED6C25DDE
-:10FB4000D0E3DAE5FDADC1B5EFDA603F48623D478D
-:10FB5000F1DEAE3FC5F3C322DE6F025E773106E20F
-:10FB600089BA0F7F928FFE270FEBBC883735CCDA2E
-:10FB70009472F8295A8AE43A723AF341D7838F088B
-:10FB8000FEFCA8996DA4779B4DA50CF67BBFF42FC6
-:10FB90007ABF32D0FBB3ED9AFF67C1FAD521499FF6
-:10FBA000A561C2CFB873B46713E6F15DCD3C2A9767
-:10FBB000EE1D1A87A3FF6EE987547AEA34C99F5372
-:10FBC000E4F9CA3224D10E3A56F7ED34B79BE23D40
-:10FBD000EFCA395209F9FCE31E2BC50B4CEB092780
-:10FBE000BD3565C84C9267EADD7615F77324C7E02A
-:10FBF000C57BF43F6656712FC01AA2DF1A6C743FA2
-:10FC0000596BFFD557E0EBC9C60B47A3715FF6DF11
-:10FC1000347A7FB4BCF7E347DF62380FFB72291EEA
-:10FC20003AC5B307EB39D93BB3CBC351F763479B15
-:10FC3000D525E4050B5E47FB1D5F45C51A02F3EBB6
-:10FC4000EEF998DE75ECEEB192DD765ABB7CE730CA
-:10FC5000643EDD894EBA27CDEBD1FBCFDD7603BD07
-:10FC6000EF36ADFD28BD57384DBD6768D5BF67C8B5
-:10FC70003A52626057265B2A570EE25B04FE264723
-:10FC8000EBCF8BAF15097DF1B522ADDFF7EE55DC7B
-:10FC90008A922B2FDBF7DC26EC52629F2E577EFEDA
-:10FCA0004BE9A44FF4B6677CED3B166F43AFE0FA27
-:10FCB000C2856BDC6F171506E4EA3C0927259F55C2
-:10FCC000DCC23C09AF797683804FC8EFAE28BA0911
-:10FCD000A58B50BC2B7CB21F741C433C16C7E3A8F9
-:10FCE000FB19E1EF24E1EFABD7D7E3D985214677C4
-:10FCF0009727EDFF45FCF96D23A0473C68203D4266
-:10FD0000DD77F4C8F7DAD5BD4796CD881F941BC3BD
-:10FD1000C95EE891EFB4733E700C7C40EDFF613337
-:10FD20003B47418E9EE44774CCAFD3D046DF532788
-:10FD3000A5D37E1DCA3A92E4FD9C42E86FC6C0FB83
-:10FD4000D444F72D9AEFE125B87F39CF4EF7DCBBCD
-:10FD50007D21EF53CB77CCBB99E40FF3D53BE67C09
-:10FD60003FF3765B1688F2BE77CC87333A476DC98E
-:10FD70006559D0BFD4EFFE0CF88EF9B258B29B3E55
-:10FD8000F2886F24E4817ABF7A4A8A2771D2E02B05
-:10FD9000DFAFDEAA952EC0EFC0784789F9762E082E
-:10FDA0007F668F00B71FF69E934D91F46EB7A253F6
-:10FDB00065E71EE6ED7A18705271B57F96F4A6E0FD
-:10FDC000AFE20AE342F0A0E8CE6B6614870B7C201A
-:10FDD000CEA8EFF763D648FEA2E23A5F763991FEED
-:10FDE00038D5933B09FB70058733D9D13BBF87F5E5
-:10FDF0003E7A47A41BF33B297FD722745F154D320F
-:10FE0000287F31C50D944BF956AEE2049AF4710285
-:10FE1000A1EF9C860F2D9D0CB89DD3DE1E838FAF66
-:10FE2000FF6F63BFF74FAE9D24F84466A267C624F8
-:10FE30009273D374FAE4EBB99FA4D0EFCC5C3E3A52
-:10FE400014F2EF9694D2EBD0AF2D53F80FFE9CD462
-:10FE500049711E7F5EF0D714B23FAF11EFB37EDB66
-:10FE6000795E19D72CE861D562712F319935121D51
-:10FE70002706E2656D98C7FFB4B8E640DCF15EFA8C
-:10FE80007D91979BDB324E0FEF07EF61479E75F236
-:10FE9000938DF7F0CBE514F71B7D64551ACF6F3CBB
-:10FEA0007CB49CE27C938F5C4CE3B8B9F7F0AB2256
-:10FEB0007FF5918B880BDE74F898A80FFFC110C6F0
-:10FEC0007E72F878B997E3E38ED19EFB81AF9B2FCA
-:10FED000351E8338FEFDDA398BD328AE75764AB6E7
-:10FEE000886B5D07BCCF8B5FB43E5A0BC4B5EE9BED
-:10FEF00024DA755F10FBA0FB82A0F330F083C1FF12
-:10FF00007CAAE27B151F1E885FAA7DF8AF8A4F5638
-:10FF1000FB99ED716D348318BDFF74DCF093936829
-:10FF20005DFAB8E16E73CF63E457BAC09CE013AFDB
-:10FF300044BEEB84BC682914718D5A4F8713F73186
-:10FF40008A0A44BEE54287137C1E79D8B7BA634457
-:10FF5000BCA38A8B6DB9E04FC23E2942FC22AF5F41
-:10FF6000DCD3530E3E5A84FBBC69E8FFF851391EBE
-:10FF7000437FBB2E88B8C36E5B87D321C7413F7CCC
-:10FF8000DC34F0C7A2D556BA77D472A17105F55307
-:10FF900066EF1B570B19D7FAF5E34ED782C6CDECA7
-:10FFA00015F19D18D7A91BD74F71C1BC3F8A3FEDF2
-:10FFB0008E7125E2DCAFF2C528E7F987E4EF54142F
-:10FFC00039FD46C8011527956091EF71CB730BAFD2
-:10FFD000477199BB7AC53ACF37FB6BB09F8A25DF53
-:10FFE0002EB608B9C90CE12EDCC72E315E3E9E8CC0
-:10FFF000F3C90BE27C521C56BA1DFBB1C124F80DAB
-:020000023000CC
-:100000008B53BF97D6B1ECE7BCDEEFE293E9F7C5BF
-:1000100086261E6499381F2F9F9903B9C1F5EE33C8
-:10002000C0F7EF58AB267E874BB49F3B3382EEA1DF
-:10003000741F1E5188FD3327CCF91CE3FBB677D221
-:1000400057B44FE7443B0B71E2E93DFC5F229FE070
-:100050007C0EFE5D2BFB8AF473E5AFBD25E0AFFDA2
-:100060005F18A77EE6398BD0CF7AE89DE6FF9A2409
-:10007000DEA7E3FA3BE91F3DD7C97737739C852894
-:100080004F35F744016EDD974DE2DD5AD6137553B7
-:10009000907FF6B176F19E6D285D1F9E2CE4C0F234
-:1000A0004C3BBD77D69068B552DA7E6106FD1E8C5A
-:1000B000A93413E703B7A57FBBE32F260B7995B6C9
-:1000C000C112F0BF73F9E10E672AEF65E318DBF1A7
-:1000D000FDF0BEF317448C65B83C8F79131F2F36A3
-:1000E000E9EABB51BFAF9C8967DA54FB9C97ED8F5F
-:1000F000AF33C9F180E725E2FE44A8BC689812DB63
-:10010000F75E21C9DD381BDDBBCA344A7B1EAFEB6D
-:1001100020BBA0F0DF26FF878DE2E876D9041D66BC
-:100120001A44BACB20E37DA5BD4F9D637E3CC53309
-:1001300069CA60EAC74FFD18F7E742AF48626D34FD
-:10014000BED2CF543DAE87D988C9C8DF7B2B321AC7
-:10015000FA85E73B93A7964E2E045D7BD947417203
-:10016000E27C44545330FE1A8C7ABBE73B93A75190
-:100170003BD5BEBE693AFB88E211FD443FF59906C6
-:100180003AB73618D9ABF4BB03AC83FC99AADDBBF4
-:100190009C4F7E44EF36B8297D8FF3CB8FE8BEDFCE
-:1001A0007C4A3F68F6D0F793CDD594763637D2F7B0
-:1001B0000F9B9B28BDF9D6C802D0FFF2436BD947ED
-:1001C00041F2B1BECDEC09BE5FF3EED4FEE9E8FB2F
-:1001D0009385DFE6DDB4FECBEF57E593053EBB1715
-:1001E0000B3D93D3E53A47ECC0FA4277A4B897F0B9
-:1001F000D234717EED4E12F9C6C9E2BD50B7816DA1
-:1002000043FB97A65928FF6EBA81DE7570C78A7EB8
-:10021000DFCD32909E76FD8CA90D80933B9E7FCFE3
-:100220000BE4DFBD4A94BB8788EF6ABEAA7CD294F8
-:100230003E3B4296381F0BFF3BA777EABF0FBFC577
-:10024000627EA1F5D57DFA5078FC56EE5BDA17D0C8
-:10025000DFB10FD282F6458393F685A243457F0D29
-:1002600053C47ECD0C9374CE6517C10F320CE7E3F7
-:10027000041BF907DDF05FF0F5EC92F1EE57EC07A7
-:10028000E90F50FB41ED0345EFC97C9F097F87587B
-:10029000C72463FF76FA87268B7577C447927EDC86
-:1002A000DD6E7640DE4C320ABF4377FBBC02DC0BCE
-:1002B0002FB9DBDED81FFF7A53B6FFA7E1A0F8C144
-:1002C0000070B862FD1669B7FF07D74FFC0D7C7B45
-:1002D000B1B897194AAFED9395DD5DD0ED3B93DD55
-:1002E00007413FDD9ACD84734AB7ADFF7BE42F4DC4
-:1002F00013FB42D14FC31426DFA1E1EBCCB892DF50
-:10030000A9F5F4AD732923BE9729E38D43F1ABD64C
-:1003100015C4F75E9F3C38004FC6B8BEC2FB195AE1
-:1003200067A773AAA2DFF383BF5A02F9357FB253DE
-:10033000F8990C46F91EAC90277DDF3523C55D0585
-:10034000C91906BDA5E7B0F0C7F9F93909FE2CD8DF
-:10035000A083E3AE2D53C4BA7BE7171A602738FF9A
-:1003600017BB1772EBFC909E93D04BCE6F13EF9D93
-:10037000F31E6769B83782F81F277EB745F8418CAE
-:100380000F7F7912FAD092878DA4BF9CC7B199B71D
-:100390005BFEA0F89D3B757FB04EB66BD976F166DB
-:1003A000FA7D334E9FD07F3EB235A4432F9EFEF0A0
-:1003B0008327F0FEFA92E734989BD951D8DD79FE75
-:1003C000E3BD46F13BAB32EE6486BCDF5FB35BDC82
-:1003D000EFAF43BC09F497033BB6E2F727EBF79A7C
-:1003E000998D7F9F8177D2F8384BDB22F94192F7C4
-:1003F000BB451F377A2DF36E803DB97ABBFE7BCDAE
-:100400002E7DBE2EE4DEA23645FE9EC148964BF7F9
-:1004100013B7087BB1E2DB57EABB5E82AF7BA5BABC
-:10042000AFFB05BDEF6D3CFC65EA8776919F2DF330
-:100430005D3C7FEE4B017F05B706C9F3CF25B18246
-:1004400036BEBE86C33607EC000D2F083BC1F9B699
-:100450006882F3F2F04EF22BB0178D0EE861F71CB4
-:1004600032925DA1BEDDF633FC2E6DC3731ABD570B
-:100470005B7F28CC27E0736109CA971EB2399C289C
-:100480007F318CC1FE7C9EE30DF762CFA77412FE14
-:100490008157D825F8DF2CFC7E85C2BFF161E14F82
-:1004A0005EF284C4CFB65526C2AB4F63096957E2EA
-:1004B00049E1F95786A7FAF08476D31FFEFD7189CA
-:1004C0007786789BA3DB2AE9773114BE2D873F4AD4
-:1004D00085DEABF06CE478FEA16AEF94EFE17D0D70
-:1004E0009EAB8167FB3F8EE73F423E1692DEFBF1FB
-:1004F0004FA1F7465AC88FAEEC1ACA6E31B8F6DD76
-:1005000063717CE0E189CF929E5B1E7BA67E052312
-:100510003BDAB5536047BBEE0DFCAC2FFBDDF54F6E
-:10052000E5823E5ACC9DF4BB31DE18F1AE7C77DA21
-:10053000ECEDCFF3F18A63BF4ADD8F7DF37218B91A
-:100540004FE6CA7D893F6BF0BB80ED36B2B7D5B7B9
-:100550008709FBDA01BDFFAC3B49FC4E5F89A5A7CB
-:100560007C05F472DE1FC651E7C1DA76F9FB2FF283
-:10057000FC56ABEC0CFB42DE8772BC41F5EAA68868
-:1005800078DB8C84494EF0A19605CC139EF175FC66
-:100590009E11BF57BF9737A01E3800DF57FA1FF3D1
-:1005A000EAED1C8AFF2C95BF2FD9B73F64BE7AAD08
-:1005B00037CA6A24BAA3771BEA1E15BFAFF809E849
-:1005C0002E2A404F0D323EEDD8F77F63C2EF3475CF
-:1005D000EF12F7233887DC8A7BFA67DB443C5C4DFB
-:1005E00041D718BF13BFD321F8D0B27D9ACF99D687
-:1005F0000F1D31DF06F1AE7D083DEDFBFA770FEF01
-:100600000DF091517FE7F0DC51C2A4DCF2F61B3F04
-:10061000D927BF427EC7E37F5A3C776F0E5FCFD7A3
-:10062000F81BAF4DD4BFE3729D53FF3B4DDFC9D6DE
-:10063000FF4E53AF5DC247EA834A4F3D3445C8F190
-:10064000D054C1F706977E1C752EFEEE38FD78B3A8
-:10065000DDFAF1BE2D5EFE5571ADDF04BFE372DC45
-:100660001372DCDFC871FF5938A974A0F1FE7F4D09
-:10067000FF0F822563C60080000000001F8B08006A
-:1006800000000000000BB55B0B7C94D595BFDF7CB0
-:10069000F3CC7308210904C2242421608803245464
-:1006A0002B94C9D300D6065C2D68840152C83B80C8
-:1006B000B5D2D6FE3208222F5BA8D1A2224E82E10B
-:1006C000A1613B118289863A286411AD1B698BFDBB
-:1006D000FD56DCF828F23213A374E5575DF6FCCF23
-:1006E000FD3E321942B5DDDDE4A737E7BEBE73CF6C
-:1006F000FB9C7BA929CE317C394588DC9873E69E2A
-:1007000008215CAB7A8A12B385E87B43154D0E2134
-:1007100084DB7BBC3E5688DA8EE1625332C1257D94
-:100720006F1A00B78DB36FA2F18DED7F781BE3BD1B
-:1007300007558785C65F6BFF280AFB5CFC325C8827
-:10074000E158F7519420B8FAB2C2F0261A77103C5B
-:10075000AB5515FE4CDACFE83363FC62AA0E7BCDB5
-:1007600082DA929656730FB5557B5B79FC0D9F69C3
-:10077000F0F8DEC641E376CCA7B6CAE88DB2537B6B
-:10078000BE5DDFCFCFF3AB53159717FD7BFF10B7DF
-:100790000CF35ADE895B4AED15FCCCBCB6FDF4D0F7
-:1007A0000B996E5A57D341FB440CEC53D361D26082
-:1007B0008977756A6B510CD14BB428228D9A8B6264
-:1007C000AB584DF4AC6A6FAE16D45F95718F49107B
-:1007D0005D023EB518DFA71F8388A37576FA8BE804
-:1007E00077D1F779D452DAF755DFB1DB5DD4063A29
-:1007F0005F8FC2770307697EE6003ED35D44BF1C6E
-:10080000B4662146D0BA83AF4739687CA3EF7549F7
-:100810006FA39FCFFD9A0607A8653AB7AB7CEE8A17
-:100820002F55A6BFBEDFAD2E95F799D59E168973BD
-:100830009DF4C9EFCD7539647FEAE232E07F226131
-:10084000418E9ACC78BB000726CE69DE44A854F9C5
-:1008500068DFCC6BE9B654DBB7CB24E6FBC0B7D47A
-:10086000035DA3483E4E140F9F4C2357E7DDE33250
-:10087000F0BC22B33B7505CD3B19E188B4D37E0FA4
-:10088000158F8B045F5F438BFEE25D6637B595077E
-:10089000E5F74EDABBA3206F270F4E553DCAC07E49
-:1008A000776ADF15C2C3ED00DF3CCCA7726F63042B
-:1008B000F619E09FEC9FEBB2F3FC13DE77EEBA87FC
-:1008C000CE773223DC09BE749945B98FE5843E8228
-:1008D000EF752636820EFAF7E6821FB42E9061601D
-:1008E000BEF6B69BB479F7348B41F34CCCB78BCFC3
-:1008F0000DC6C7EEFDE097F7D0FCEA675461A1EEA4
-:100900006AD38A389CFF931D83F12BD7E85C6DF284
-:10091000C7C505C96B75C7557D8960F9EED0F5C3AC
-:10092000C1FCD4F978324395782558BC8250AE6E1C
-:100930006D66B92675F3D8A6702BECD4268677277A
-:100940002B74FEC407ACCEB584FF738A366EA03616
-:1009500086608384CDD45AA97DC624FBA1B6583FB6
-:1009600086D8A9106C2A1E976348A17DD4D6C9E009
-:10097000EBAB335D8FBA088FCD334B66CC043EA210
-:100980006F99A06FD65C8AF08868210AD5F79EC05F
-:1009900077FB0F9A04EC478DB5A3F26392D37E27C1
-:1009A000290AE1DDBFC3E4F5B0FCB9229469422C09
-:1009B000BB49EACD270EF734751CCD5F63E0F355D4
-:1009C000B7A85E1BCDEBAD271210C93F6D4DFE01E0
-:1009D000E4B5FAB86AB7D2B9F37DC9BF9A0EB8C503
-:1009E000E4B4D0FA5A1F75125CBB57F13AE4FE0228
-:1009F0007A597313CBBA3863AB4D1159D4AEE9337E
-:100A000063DE99C38A788CE66D0E8B6A02DE3599B7
-:100A1000B3CF2951D4AA5BD627D27ECBB79B3EEC6D
-:100A2000B1CAB557E8BFBACE6D2CB715DEC1FD55BA
-:100A30007B07C335C23800D3FECDF8E36621DA5C0C
-:100A400091B1676EA0BF2788095754D0697A3CF4EA
-:100A5000E104F84AF2241A88D82385B86F92331E2D
-:100A60007ABFD1E8980D3A043A4D76D0ABEEF081DA
-:100A70000AE0EDAD0E731AE8A8B5AB5F61BA06BE29
-:100A800020BADF486D82E0F30784A46FA05DCA79C5
-:100A90009D49F15AB19E68C8FB5915EF1A1A0A7898
-:100AA000FAA3D83E09510CBD58B520C7003B073505
-:100AB0001684CAAF747D506C46251AADD4FFEF1969
-:100AC0007BD4614176E23F5D298C7F8159B87DD42A
-:100AD0007F5FA4331A723FD61A9505BCC65A93BCE1
-:100AE000A0FB5863DF1A7C7FF328C5F1106D7D24CD
-:100AF000EBE5C90AE0DA0827E44449586C043D36BE
-:100B00008F5A6C84BC8FB5FB324A3207E0028C43AB
-:100B10001F8497BF5714E136E23BCF8D54FC06DAB1
-:100B20003F6023FCA02746BB09F8054C121662CD96
-:100B300020FCC82231FCFF8E9F9DF08B18C08FF8DF
-:100B40001D8DF59F67137DA84D9A2B4437DB8515C6
-:100B50006C17747A5E24792F205EA529526EAA77CD
-:100B60001C29C2788DE85E8F754551F21C45380FFF
-:100B7000E030D9AAB9925FB95A7B7FAEF42FBAFDA3
-:100B8000ECC8751973A9DD9E5B62465BA866C6F763
-:100B90000C61EF5729569693CF49FF608FEF5DA107
-:100BA000D8533306E45BD7AB3AD975557FAA7EBFDD
-:100BB000CB2C52F0395777068D970BA9D78B56DB84
-:100BC000ECA9C17A043D237A94DB2B6E13A46FEE5B
-:100BD000D571F6D4A9D4AF5E340BC89EA65FB1F42C
-:100BE0007B256508FDF285E865FB60D86F9372EEA2
-:100BF0008F54BC6B09FFD4DCC17A97A4E941A35B95
-:100C0000E1F3357E6564D853AA7841F33BA9737547
-:100C10008C7638CC2BCFF5C23FDE496029FA1B62B7
-:100C2000594F7990ECD7BF68E7BCD3E83F02FB711E
-:100C3000CCE44BB6D3D0B11AAB13FB2F1014E89011
-:100C40005D2B15DDDC9E0AAF6DF3F3E69E3190AFB0
-:100C500077DD1627E2B0C6754D91B0E359629DFD70
-:100C60004C06820AB1F7CAD4EBC7332438E28CCEE3
-:100C70001738628A53C06F9DAFDB735D79B939D77E
-:100C80005F5FF5A7B6DBBF03FB757FB3395E8A49AB
-:100C900077C6B401BEE97CAD131EC65BE7D755FE2F
-:100CA00011EEA3410FF5E25CB633CFAA82E30A8DC1
-:100CB0007F56FA1D8A7F3A7D676A7C58DE21ED51A6
-:100CC000285F757AFF9036C4F7C98FEE607E080BF7
-:100CD000DBBF50BE7F135F28C22CC5507EAC458061
-:100CE0009F8906691F1397919C10DEF708F7E11E94
-:100CF0006AEF0A7FCBC472A8F1E75EF087A6BE2B2D
-:100D0000BCDFCF48FEBFE34F476EC903C17A18AAC4
-:100D100077D7D3B36A87F3DF75BF479686F42B4442
-:100D20003F43F44FE7977B7514EBD9553EAA2D52FC
-:100D30005F357E45D0EF90FA863FE87B35ED8AD768
-:100D40009FFC2DF44F21C4896F8F85E89DCE9FEBCA
-:100D5000D91DDD4E9D16FE63763AFFA9141907785A
-:100D60007E62F136034E3794C3EE9D9A28DB039AD8
-:100D70007D0B6D4F539CA3901FDB94717204FCF5A7
-:100D800029B3BE8FCDDB4CF89F5ED33D6625AD3FCA
-:100D90009D2BDB53880B836057985804BB7E7AA445
-:100DA000C5033A9D5626E4C13F9C561EB85DC2F16C
-:100DB0006607E005F17976824F99E47CDDAFE8F6CD
-:100DC000FFF482EF14F03C451C053D1C8A28E1EF3E
-:100DD000284A4C31E173FAFEB4296BC5C0F99B7205
-:100DE0000DBCCEABD96FC283E9DEF753C5DB445DE2
-:100DF0008BE05208FFE4BCDF14A750FFFB3F1B371A
-:100E000019FC75AD1AFC7DF8EBE41B016FE37DBEA8
-:100E1000F7659F6971905FBAEA270B3E93FD6539CC
-:100E200006E84BB9C64357CC8468F0A7DF3B2E1ABF
-:100E30007E47F743FDC70F44B883F8768EFC9418BD
-:100E40001F044F783429D88F1DD9BD391DFB949BC1
-:100E50003D594EEA3FDBF87412E28DF2DD8FA47348
-:100E60001CBC7B633AF299F2A6CDE92E86C3DD9CC9
-:100E70004F19E5B92FECBF79D7A6A0B8BB2A5F659B
-:100E8000FC4BAD470AE16F67DFF0E9C3769A97F64E
-:100E900033C50EF1BA57743F0CFFB810F131F2B7F9
-:100EA000062BDB73DACF05FE374FF8FE73D0E31362
-:100EB000191F99CA68DEE55C23D367A1F06E89A784
-:100EC00071B141B1378BE0F9631A317FF13AC59CBA
-:100ED000003BB062D864D58175C3188F251B267777
-:100EE000A17FE183B27FB6C57BF024F6F98DD9D915
-:100EF000EC607B9352326900FFCBB9665EB7688BBA
-:100F0000C2F1BFFE9DB427E21A83CF7959E3BFF83F
-:100F1000CAA2802F3FD0F872DB83EF1C4DA07DED7D
-:100F2000B1EE2BB01B6F3F7E26D54FFD0531E7326A
-:100F300021E76966F75315387793C5897364672588
-:100F4000AAF1347FCA8F731F43BBE8C1C54F55C098
-:100F5000DE6EB772DEA6E3B74A711A608F5F6FFC70
-:100F6000E112D0EDECE3568EDB57358E8F1743E858
-:100F7000A9DEEE21FE3B28D1D9576FE5F6857ABB75
-:100F800070903CECAF4F60F8B7F50E6EC57C295FF2
-:100F9000ABB4FCF87AFB4DFD325C38289ECDDE60A8
-:100FA000130EB2534971AE517974CEB489354D1BCD
-:100FB000B573A5D1FAC99EE47CD0217BE3CA2E8407
-:100FC000BCE63C998FBD797243128CF2F2073FD890
-:100FD0005941E373F34AC6E551BF75C7675C57785B
-:100FE000BDE39185A0777993459E4F3BF7D9C7D351
-:100FF000E39FA2FD3D6F9838DFAFDBF1C1CE8DD40A
-:101000002EDDB2D21C2CEFDFF6BCC91A3EDFA4578E
-:10101000D7A3C33FAE579B93587F9A48AF32FF790F
-:10102000BDAA7B700DD3EF81BC92D9A0FB59932749
-:1010300009FA7476C20C9673CF6185E9AFDB717DD6
-:101040007DB176DE2A836FCBF4E4013B7E496433C5
-:101050007D8F747C928EB8F752FB82BF7BEE437417
-:101060006E3F9DBB9DE8EB1F7FEDF834B37B9C93F7
-:10107000CE37CD20E3DD6BE2D63C83562FE83697A2
-:10108000444A9A2BA8CB68FE93FC98279AF0A9EEC5
-:1010900054FC6159F067B79E3322DFA3BCF1C3E073
-:1010A00038827E3E0CF2DBD7C3F79BDA5AEC9336DC
-:1010B0006077BFF36783F007F9E99B7BC2843FE861
-:1010C000BB57F313EA33139F7A3B46B25D00DF8CC4
-:1010D000A8C7754C68027CCE2CF9D87B88E22659CB
-:1010E000C711EAB481739EEBB890053B1B7ADEDA38
-:1010F000972FB07C54B73FF299C2E79F75CE98F511
-:10110000CDE73FB2FB4216F877CED4330DF956AF98
-:10111000B9270B7CA87D45DAF37F940E7A7FC5064C
-:101120003A08E979AD62653929542F72DDA0F7B824
-:10113000AC1BD476EC627BDADF29EB377586EEA246
-:1011400078D43B567CD0057BD69F20F328DADF0588
-:10115000BA4D1FA7F941635FD25CB26B2F5E950752
-:1011600099FF9D85FE8EC73EBE6AD80191152E104F
-:10117000579C873E53FFC2D5C9EB21E767BD23A625
-:10118000C03EBE99F5B75AAEF7BD1A6E5739EEA1FB
-:10119000DE20FE5D3D875715AE41F58070E10A9A6D
-:1011A000576776FC80E3E313AA405C573751EA9314
-:1011B0007859EA53CDBA23E684A0FD76429F186F92
-:1011C000192FCE7EF56FAC975B66BA3AA197E1B066
-:1011D00085D82F21DAAB28DA3CE27FAD864344A7DD
-:1011E00096F717AB3C5ED7AE8A91589310E94DA3A2
-:1011F00073148BAD46C4D3B3856F3AEA36C2D8F3C5
-:10120000CB5B687CCEABEAD44D82F3A745259C57D7
-:10121000BA5357213E32281A5D7DD97383FD599EFA
-:10122000F453D35585FD58DFC8708E5366CDAF2972
-:1012300005BEFABCAC61721EEDC37196F0F665CDC9
-:10124000857EFAFBB2E6450ECCBBEBD5F015EC176C
-:10125000852FFBAEA0EF84E5CBFAE8E7E447202733
-:10126000759764BDA350FDEA09C4E7AB0E93BC209B
-:101270003E3424BF6B801D273A83AF1788AF2EF80A
-:101280001FB770B9A03F934678A13F75FB15614425
-:101290009DA8C3D2843A52ADA9270EF2BCB1FD4F2E
-:1012A00066C8735DDB3B66C724AC9775275248B6AA
-:1012B000E3759AFFAA691FFF2EEA7C35C7A517AD13
-:1012C00031BEC3F97BD5C156CED3AB859FF3F4EACB
-:1012D00096C1F2D29FE0E0BA48A87E84E53B06E9D9
-:1012E000C5ACED522FEE52C50AD839A1D569672594
-:1012F000C4733C32B04EC6BB2EF5C2C3885F022910
-:101300008A53A1AD02619E75888B3CE9329E09FC2F
-:10131000EE85EC656C57BCD977D0B9025ABC3B6BF3
-:10132000C336A31A84CFAC4E59970C8489F243CCB0
-:101330006FF768F041B84A22F27358AFB2605703B2
-:101340000659470D3D47BD562F3A817A52E600DED9
-:10135000731213A51D135E969F2E83FCBECB40E334
-:101360005306D62FC997EB07F2215907BB9E5DD9CB
-:101370004DFC2923FEEC253EA37D9EFC7119D999D5
-:1013800016F2C780FF95FC315A5F7D06F7BF58EF14
-:1013900064F860FD4D0C1FAA7731DC5E5FCCEDCBAD
-:1013A000F525DC7F02A87E17FF7BBA11F2D0051D60
-:1013B0001B35009F8A0981470D9E7F2A46190C8F95
-:1013C00052787E76FED38D1ED48B66DA35FD764458
-:1013D00022FE3A6B9375A8B33659876A1DE5BE2580
-:1013E0009FC6CB66ADDD2DF350573AE615C42CE011
-:1013F000FCB59FF257D8A395F9EE3CF0E5F8F1FC67
-:10140000D46D6C276D5C073D75F70DD15C077C834F
-:10141000F271FA746EC6D475D904E746282CBF64FD
-:101420002F6E2CD1F34ADA27BF53DEA314AAD56559
-:10143000D87FD548DB54D8DFCF5DEEDB80874EEF19
-:10144000A251CB53110F75991CEFA28EEBF9BD4938
-:10145000209FD2EB7DFABC0E57EEDD58372B63DCB4
-:10146000BA29B03BA464B0732EB368015E2E43B8B2
-:10147000B296ED96C3083B70B726C7790E1917FBD5
-:10148000CD0E630CEA3761B9B11E5AD7A5F1F9B890
-:10149000C6E7131A9FDF429D8CDAB7A91F6D37F597
-:1014A000A39D01FA4A7965BA3D915752C6F22BFACB
-:1014B0009200EB75C1D9D02F696F9220D75B34F9B8
-:1014C0004DD0EC4D576E49955CE7E37DAAB47ADBCD
-:1014D00005ED1E443FAFBE6E60BDE076DE8DC2639B
-:1014E000859D7F49E69D6234C52304CF7B299EED0F
-:1014F000906ABD23F363D2F37953651E200E58E43E
-:10150000BC04470EF464AD566FEDF51A3C26D4A723
-:1015100063BAD363E07F35FDD2E143FFADB2BDAE28
-:10152000994230B5AF28F27C35F3BAD38761BD62FA
-:1015300033707DBB498E9FD4F4AF2645DB4F3B8F84
-:10154000B0FA92C08FC0E197929610BC29C2BF4CEE
-:10155000DA7D7F3ADB6BE14F9F07BBA8F8DE174EC1
-:101560008A2B0BA62E318E043D7C3B015717E42CB1
-:1015700031DE8CF1D6F7EDC1E3237C498A1D70B6CC
-:101580001C1FD1BA7398330836BDF83EC6CD869C71
-:10159000250504CFB1788FD7436E7E2BE5CBB6BF40
-:1015A000ED0CE856D521E3F6BCFD6D175F845F6E48
-:1015B0008B74C2BCEFCB4F667AAFEDD8B305F2D6D1
-:1015C000DB2AEF0336B5FC69E7CF799E05D724B453
-:1015D000AF2F5BD077561EFDE362E03527DCF705C1
-:1015E000E0878ECE643CE70C977AFDC8D1BC25D04D
-:1015F000D3DEB6FD3F81FECD89A68016F8BC60E340
-:101600003A44E5810905D0D3DEC8EE85D8BFF67926
-:101610008B13725A79203E0FF58143F9B21E5E3169
-:10162000716B12FCACE1E57DBB7F8EFBD5E76D7C79
-:101630002F541723E3BC4AB571DA4AE6DFAEDD4F1B
-:1016400003EF7D36BE9FAD40AD8AE08ADD695CC7A1
-:101650007FE5EB8F16820F85EA8EDDE8FFE2399B8E
-:10166000017438697645CF801E9E3471BE59A1C180
-:1016700015A7864B7CC27B8A987FB15B93E0672B72
-:1016800087FFF476E03D47DDBA13F98ED863E1BBFE
-:101690008973FB886EB4EE5CB3690AB8DCBB2FD2E9
-:1016A0000879B9A06C5DF814F66F96F32ED8B632AF
-:1016B0003D3DCDE305BE47F304ECD60565DBA0FE5A
-:1016C00073CD7BB2908F9E7F7E0EE7A5BAFCEAFABF
-:1016D00052F99C65905F644B40F6A852FB5BD83D85
-:1016E0002282FC6D85069E3FF464EF536260FDF933
-:1016F0001693DF4C34AAB08875D698017DA84CBCEF
-:10170000B518E7AB3434A6236EA998DAB3107A7112
-:10171000CE26AC0934EF4DCD6F551E5C3317F1EF7B
-:10172000F5F0B9A2D9A34B09D27F5D6AB77983EFEF
-:101730002543DBF7EA85FDADB401F8DE15168EE131
-:10174000F5FDDE34FBAA91A7D5C648FBF13ECD6F6F
-:10175000213BF6B5E6EF16AD1E3CBF3F3F86BF5FAF
-:101760006BEE4987FFD3F70FE46B7EC3D8930E7BF4
-:1017700015BA6E0EC211D8911714B6239507950F9E
-:1017800054A253A5D5E355411761D6CF69BCA2C871
-:101790007509D334BAD3DA0D05C9FCDDCA169BCB63
-:1017A00046EBAAC27AA210175547F64421DEE97D1E
-:1017B00059154D1ABB62E334FEA4682C0BAA3756A8
-:1017C000F84C2E5BD6107C46FC44F396E36FFAFE91
-:1017D0003305297C9EF2F670FE9EB0F74C839C96F2
-:1017E000EF18BC0EE7B207E95F6FFBAEB8E0BC3C98
-:1017F00045C33BA07CC07A12F8FAC324F0BDD220C6
-:10180000D6E1FEF23CADC1BD26C1C22A61BEF7AC35
-:10181000FC6B4418E4E5FCA56AD6DB5EA587EDDA2F
-:10182000DB0573D92EF59A7AD8AEBD7EF42EB60FAD
-:10183000BDC37A16C24EBD5DB05C8E8FEC59E8A078
-:10184000F1FD3A3C46B0DF7FEF680DDB8F39AA7CB3
-:1018500057217699ECB21EB4E1543DE71726477044
-:10186000FE7DBA40ABF70CF087F32E5D6F7A85638F
-:10187000FF41E8617904D775288E6A7911F1DE821B
-:101880003827DE6B94639D940373F07D636CCCE525
-:1018900065E0CF1DA3DD450539B8DFECE13C82A44E
-:1018A0009AFD4DEDEF2C9C4F064C7DBB61A7D247B6
-:1018B000BB6717101ED5E6EEF5D984D245534F17F6
-:1018C0004AE4B355698FC41E2957BD99BBE43D8DC9
-:1018D000765F79B7467F41494C23E44291FC7DBD58
-:1018E000FDC05BB02BBDDDE3D81E87EACDB9F6C7DE
-:1018F000A2601FFE4C7EDC1394EFFF79F11EBE67E1
-:101900009D8FF720D42E5937581EFABFBA83F33E65
-:10191000B125A81F72D830180E9523C8A37F90DD7B
-:10192000F130DDB76B7A5595D75D0B3A5C85E711E1
-:10193000AC06C1AF85C021F345898C13B6C3FF1334
-:101940003DAAC7F84F719EBEDF2460C7D792FF62E1
-:10195000B82DDC8B7CC5B09FFC53ACF44FF00B551D
-:1019600051DD5C9FEA6DB3F07DEF431D9F24E1FCE8
-:1019700024875C87A9EA78290EF9FB3E2D5F203F7A
-:1019800018C7EF63DA3AE29077E8FDD5065F3AF0E0
-:10199000A28888E375BDBF46F5A703FF2AA53B0BC8
-:1019A000E3FBF2EDDA7C8255C082CF51AD487D1762
-:1019B0001D2ADBF350BE3DA9C92BD9852C7EDFF152
-:1019C000B2AC0FE876A042B327AFA13F53EABD5DAA
-:1019D000BF57A2A515D0F721EC4342811E17AFE0F7
-:1019E000FACDE3050E096BEB795F595FE2F1DA5747
-:1019F0002E64A564629D362FD80E8D1BB02BD0FFB0
-:101A000004D6FF874C7174AECA9D8A732DEC54E9DD
-:101A10009A229A2E961B571671DD4C78386F0BC59B
-:101A20002B548E2617483A551A8615C606ED779E12
-:101A30006C7AC214B6337ED89D1FC53E5A843AC50F
-:101A40000F4BE5BB81ABFE2658CF719E1DD28E4356
-:101A50006DAE18AE95E3E52B1AD7C70F8147289EC8
-:101A600015EEC6A238C7B5FD3ABEE76D3A7E79A637
-:101A700011C17498BFA66804B5CBADFF2C1DE479E5
-:101A8000CF7758FCF0AB15A52BD7470F2137D7F8E8
-:101A9000831D41FE2B05FCF5F2FDC6F5F00F6DAB85
-:101AA00015FF29D48B04E95533EB17E94B905FB848
-:101AB000B920A4EE50BE782CE26AE15E3C167E8628
-:101AC000F46AA17388FC920CE42803BF19F1701B1F
-:101AD0008ACF5F0AE4BBA49B0BA49E6F99E90AC05E
-:101AE0006ECE500D1C8787EEF765818C27BAE322F6
-:101AF000EFD7DF7380D9335449B74443FFDBD0B706
-:101B0000C4B84807EE830AF3C3E5BCC3363BEA37E3
-:101B100081C397B9BE1B783862BEBC378810236971
-:101B2000BC2B615253B01FF975A13C6F78B68C5B2A
-:101B3000EA324C7FBF3E941979B53EC47143663892
-:101B4000DF97F4B67FCE7E2BD09963C7BD466F3743
-:101B50006587A44F755FFF571CFC6B6FE75FF81D2F
-:101B60005AEF579FF0FBB48DDAFBC0D7DAB5F75DBB
-:101B7000DD8E48F4078A3F2AC2BC4D5A3B5027905D
-:101B8000F562BDD5F35FBD1E1094078F2E1C3A0F72
-:101B90008E714704D7091CF143D55582EB04A9691E
-:101BA000B24E801675825493AC1300469D002DEA08
-:101BB00004E8479D0030EA04805127008C3A015A1E
-:101BC000D409D0FFC57CF95E2640422CEB97116CFE
-:101BD000DFEF6B56BD88CFEF3B2CEFA1EE6B54F8D7
-:101BE0009DD645FA3EFCDC35EF750E6AEF757CDB61
-:101BF000F85EAFAE4D75825575A6BE63A8EBD4B541
-:101C00002ACE35B02FF5F3F9FB1B3B73DE2D457F54
-:101C1000B3C96970804F97E250AFAAEC6CE6FA53F3
-:101C200041FC6133F3B74511A897DE6591796E8D5C
-:101C30004ABD53F83E94E3E01A4B37E71F557B1536
-:101C40007B59F07DEE4D9FB11D586B8B6A029E351E
-:101C50003E9BBD6C88F71F7C2FEC1057EF9B97C9FC
-:101C600029A226A288EF9B97E19E995AA17E65E45E
-:101C7000FB634A4C87431EF1AE2A0366DD2EF53E18
-:101C8000E43D556567EBFA4471ED3D342A03E07F8E
-:101C9000E8FDB3BB3032F64C380C85988CB8A9F807
-:101CA000F1B2FD6DF4BDFEAD168E3B56E6BB97431B
-:101CB0008E8E995C5C273976D8C6F9D1C7DBC60F02
-:101CC000AA937CEE725717F2FDFC68AE5BAC32292A
-:101CD000EC97F38BC7C5F3BB81E326F63F1DAE92AD
-:101CE0005ACC5B35C9C1F5A9428BB89FF7D1DE69E3
-:101CF00051CBFA54B856F11A085E2C9C66E8CF22F4
-:101D0000221BCB8B296203DE532D12F27D832E37EB
-:101D1000ABB6291C1770A1200EF79292BE8B3AFF2A
-:101D2000ED32DE2F2CB5C8F835D120EFB31337C90B
-:101D3000F72D3F126E33FCED72F28B68C94FFEAE89
-:101D400087FADDE1A393647CEE88C7FE8B4F98F899
-:101D5000BD6F61FCF7D3DDECAF0BF81D83E2BF472D
-:101D6000BD72C3F5F527F41DC33193B42F4447CE9C
-:101D70008BBA20975C9F71737BA2BE9CDB1933A545
-:101D80009DBEFA2E91786407FEE17DEF235F4C8CB7
-:101D90008F74C2DEE97A7FCDFBC430D9EAEF13C776
-:101DA000502B82DE276E713978FF44C3C9A90ED04B
-:101DB000E3AF114ED0437FA7B86566C92EF0C915B1
-:101DC000253CF82EEE51B6125D8B701005756E9F96
-:101DD0004B45DDFAB062E777D1D7D8C96D0FE31D67
-:101DE0004F5DAA62571CA8876F2D8C23BC8B529223
-:101DF00019EFBA76592F650AC5A19EAEE983CBDDEE
-:101E0000563862A07F8EA617BD345FCAC92D5EC842
-:101E1000DBB7A8A33E87F91E6173366BF91AF83E4B
-:101E2000E786315C4FD5E5A6BF25BE0972F346A112
-:101E3000F433A5A5EF98100774E5BA8FE2FC0BCB3D
-:101E40003E7B388ECF37741D8BEC28DF4B86D6B1A6
-:101E500074BBBC5BAB83C37E1AB53AAB51ABB31A50
-:101E6000B53AAB51ABB31AB53AAB51ABB31AB53ABD
-:101E7000AB51ABB31AB53AAB91EB772BB87DBB7EC8
-:101E800035B7DDF51E1E0FB2FFEF5DC7FE87D641E9
-:101E90003FC2BCD03AA8B03AA2D98F927ECBFA7397
-:101EA00048DDB378F8920D44BFFC06B3135D7A1D8C
-:101EB00014EF97EF8B607B70B170C8FAA74EB7082C
-:101EC000AE97F60BDB14D03F2F639CD140E37FD558
-:101ED000F8A0D71FA11F381FF4032DF4C39836A014
-:101EE0001FCF984985B3A5BFF7B0BFB7315FD7AF54
-:101EF00021FB41F052611F643F2E86D80F4A3CEE11
-:101F0000061ECB3AE5BB26FDFD661E355F4E19C2A7
-:101F10009EF8A43D1913E6DB87EF8CA90DE3F7C10A
-:101F2000C7B4F758C736CA777165A284BF3B845DD2
-:101F300089023F960EEF7BFF699ABF747304C72D29
-:101F4000EB472E9BF6BFB12B9F150AA6DB6FEAFD70
-:101F5000951F132E056152FE0ACC2203F735C210DD
-:101F6000C67A50A86E51703FBAEA5E31197C2EB025
-:101F700094EC009EF1DAFDB688D5EAADC6EE8A3D56
-:101F8000049F8C4B74E25E6B74C22181F74F8575A0
-:101F9000C599B08BFE31EE09453978BFBC55C1FA01
-:101FA000F04C79FE3B8AC39B205781C3E373C0EF9B
-:101FB0007916471BEA00CEA284A5C8F3E7453B7219
-:101FC000500770768D9270BCA34D7122944D585A73
-:101FD000C0EFCFAC5B3FB6E2DD9A22A2E95C96612E
-:101FE000EE1C7CA7A6F85399378B3EF6633717C9CA
-:101FF000FC6BC46BC28F7BABBE59917C7F26321DBC
-:102000003918A7B8F2BB45241F7FFC9EEB16AC4FD6
-:10201000D4F08CC72DA20AAE76DBD09ED0EEF3BAF8
-:102020000CEE52B445511E23F71BBCD968DF34F8BF
-:102030007E8C7E92E722EC57F4D8E4891904275A63
-:102040007C6C273B5CAE5BB1FFAB335DC5180FAD5D
-:102050009F83B7C8F3099FDB302FF41D96CECFA521
-:102060004552EECB8AA4FD98BE56DEC786F2BDACC3
-:10207000C8A0D9B7BF8F37E15B8AEFE9F88BAD8B8A
-:10208000B3810FE17B2FF0247C17625C44C470BDE8
-:10209000E3FA72E6E1EF951549F9227B56F5B1B402
-:1020A00067DCA61BBDC3103F8EFA857718F01DD5DF
-:1020B000D867C3BFC378D6D367837F7FF6C13E1B83
-:1020C000FA9F75C977D2A1FB3716C9F713E9D3FB7D
-:1020D00078FD58FA5637C7E97DC31047A5977FBCEE
-:1020E0005EDEBB64B07F19ABF997B1BF4869EF21E1
-:1020F000791BFB6434DF6F8B82581EAFB44A3DAD51
-:10210000FC45D9A1366AC76F277C83E2AF095EC25E
-:102110007B505C64EC97EF2D09069DF69A1886CCEF
-:1021200022BEAA11F2BDE528CD6E206E2B25BB5034
-:10213000537EF432BF03C07AEC8F3B5BC85FBB4970
-:10214000C2E4AE918F2E9FBFA68BF3C3ED57FBB5B4
-:102150007CB3753DF2678ADF06F557961DE982BFAD
-:10216000A9DA3BB8BF66C5679CC752FC36A8FFDE3C
-:102170001F7FC0EF6CEADA07F7137F9F029F75FE9F
-:102180001E33F92620DF3B5613E694FF7EC0B712BC
-:10219000FADE541DC1EF6777FD3A8FE546E737ADAC
-:1021A0006FFA76F2B196E77BF24406F4E19BDA5ED1
-:1021B000D8A7B441F6C9C375BED9916C77EAB4FC0F
-:1021C000AAB6CCCE7E3EB1D6CAF6AB500D7302AEE7
-:1021D000354A3B238A55CD4EF958FF4FDE3E8CEBF6
-:1021E000797C00C03193F8DD71DC5A09F78DB0B00D
-:1021F0007D28349454EFA1F6A86105DB8104BCB8B6
-:1022000024BE3F03FBA0427F655DB5CEEC53E4FDE9
-:10221000BE2307F9AE7EDFD4B0D1DB7A10F9B2E28B
-:102220007D7219EA8A7746F0FD4100F5463A4FC3C0
-:102230003069471B16A4B31F088892D2958843E6DD
-:102240008771FDB16198E351DC2736544CE438FACC
-:10225000D07F4BBFDB37D7EA441CD530D9B106EF6E
-:10226000551A7EE1E0F15714B99FE751499F86B9AD
-:10227000F2FC0D15319CF7E87C6868748DC4FDD4C0
-:10228000CC31EEFF00DF4769F7730DC9D44FED1372
-:102290004AC9821F619F4912DF19331DAC77C716E7
-:1022A0004C7C74B783DD891FF74475B32307E5C5FC
-:1022B000FF033C759D8B10370000000000000000FC
-:0822C00005020D000000000002
-:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex
new file mode 100644
index 000000000000..33b584c7c1ab
--- /dev/null
+++ b/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex
@@ -0,0 +1,9476 @@
+:1000000000003BB0000000680000070C00003C202E
+:1000100000001AF8000043300000007C00005E3051
+:10002000000079E800005EB0000000B40000D8A035
+:100030000000800C0000D9580000008800015968B9
+:10004000000039C4000159F800000090000193C07D
+:100050000000ABA80001945800000FFC000240080B
+:100060000000000400025008020400480000000FD5
+: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
+:100530000818076000140223071C00002A1E000090
+:10054000071C800031E60A88071D00001DDD170228
+:10055000081D4470577202250118000000000000B9
+: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
+:102020000730040000B00000083007680013037692
+:1020300007340000332700000734800032520CCAF6
+:10204000073500001A8C195F083539A058CC037881
+: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
+:1023B0000724000031A500000724800008190C6ADA
+: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
+:10325000072C000033FC0000072C800038B20D0062
+:10326000072D000039171B2D072D800005D9297364
+:10327000082D8A204EBC04560128000000000000E2
+: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
+:105140000000035F000035000000FF000FFFFFFFBD
+: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
+:1054800000007FF800007FF80000021A00003500DD
+:1054900010000000000028AD00010001FFFFFFFF29
+:1054A000FFFFFFFF00220006CCCCCCC17058103C9F
+: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
+:105E40008A5B591918EC39107C7AE0A58C94E95FCB
+:105E5000C3CCC0B019882F00F12E66D2F57F9642D0
+:105E6000B0CF483030BC03E29D620C0C2B2411E211
+:105E7000D1D20C0CFF81FCD350313BA09EDD52945B
+:105E8000B97B140F0E7C471D957F5C15428740C57A
+:105E9000EFA2C99F80CACF5780D0F7D4B19BBB0077
+:105EA0002A0F0001FE3753600300000000000000CD
+:105EB0001F8B080000000000000BED7D0B7454D513
+:105EC000B9F037E735672633939390C704123C83C4
+:105ED00001820618303C54AA93F068E8A53A3C04C5
+:105EE000E447195034822411D39AB6FC7F4EC8E49B
+:105EF0000102C617A52DDA81E2BDD185BDD1466B61
+:105F0000FB6B5710A5B9B5772DA4A8B4451BD06B72
+:105F1000C10237DA72A1FFB2977F7F7BEF939C7348
+:105F20003293876257EF6AC3D2937DCE7E7CFB7B30
+:105F3000EDEF754E141803CA8D0097F0875CD7B942
+:105F40000020BBEF6ADE073556095900154145DFD1
+:105F50004A9EAD17237A7D09B97F85107E0AF0FE2F
+:105F6000B839300940C671790053F17FD300A4CC11
+:105F7000969C988FDC1357A6E3D59CCFBC5648005F
+:105F8000DA547CBE6D5CB2E7BDEB27E49E6E15E88B
+:105F9000CFA53100B5C76F9DFF9AD926FF8D027F2F
+:105FA000D68757935F66C08C4B22C027F98BD23BB4
+:105FB000F5D4F37D54D7A54963012ED42D9FFFDA84
+:105FC000D8FECFD78B50DD5EDCFFFE75A052BC80C3
+:105FD0006A28D1897DFB5E0FD0E9CE0468CEDFCC84
+:105FE000F69B4590752DB9DFF66F9A54D407E77A82
+:105FF00089F49BDA7F3F00069DD79CA7777CA2CBD4
+:1060000036DE39AE773E3E1E24F26F3A00ED42F6A0
+:106010003FCD15BB11EFBBF3171923497BFDFE5292
+:106020008815A786BF975E9F117E735C4A3AF27E01
+:106030009FEC6B6822AC071F2AAD375D47F8E8F785
+:10604000CF89E1CDC847BBC7CF8100B90F8C8F4C3A
+:106050003A9DDED790938C3F52D1E97F8387F29FA0
+:10606000C95F15C2CAF44EF8ECFC7537F2579A8531
+:10607000BFDA170F38DF67E5AFB893BF383ECEB44D
+:10608000B3FDC3AE118C2E9C5E4EFAA4A4CB671D4B
+:10609000D79F9FB6205EDDED8B8D9190849F38BC9D
+:1060A00026BD3E2FBC83F111402BA5334054C4F5CF
+:1060B000FBEEB3ABB7447381409B87711F23F83E5F
+:1060C00046C49AEE13089C7E682D1F1722EDEED56C
+:1060D0000B500EFCC7E79FC66B6371595719E997C0
+:1060E0001ED616CE23576F11B8709F5B70B2EB703F
+:1060F000BE4AA3B418E905B4FD8C7147C4403C40C6
+:10610000042007E06B7C4F00822E91B682BF8E493F
+:10611000B60F053A193E5C97DCFDC7A7DABFD23748
+:106120000E2E85F0FF1B01F737D8385840C6A988D6
+:106130000E83E23BC3314F7A843D37E9E3074B9B43
+:106140003C3F8ABF507CDFF757594F8347549DA887
+:1061500014A550D012D81FB40C89B4BD7388222264
+:10616000678D16EC31047D70BA340294B7FB28C3F6
+:10617000C1427F1F7CA7C145F7135C130F3591798E
+:10618000CF97F8C2943F34F2DFD4FEFB79B00E19FA
+:10619000D9D22EDE0BC8E771C24763C878A3989C9A
+:1061A00087084FE1F39A555FA5B95C9C2F9DFC01D0
+:1061B000BA341DC50C59855C0B858827F0F9F94365
+:1061C00072E071A8FC91B6C0421F183EBD82DC6E21
+:1061D000182A7F7CDEF54CBAF697AB7A4ED71A15A3
+:1061E0007C782E2F4A6A7FA4A6EB2394AEDE4288E9
+:1061F0002492E8E902978BCB8161D337F44AE823F4
+:10620000F692F77E1BBDC4DCE9CBF70C800F31CBD7
+:106210008E0F735E4FADA87F80CA4BD2049C4FC1D6
+:10622000F990CF828F1840CECFF3C8DB041F62EB0A
+:10623000944E6C432150BB8CFC74BA48DB138C2405
+:10624000B68618FF235D4CF8DCBA60C3AF94E5B5A1
+:10625000B561B9E1B2C2EFA955281C0AB511C83C15
+:106260001A9990A042F24127F2ADC9AFC80697AE85
+:10627000C4F6B76C7CD0A24F85647430F915D1CACE
+:10628000F8F55B43D32FCEF596D8E11DF2389FA4E5
+:106290007F683987528F93E043933E048915388194
+:1062A000850F9A6578C93519A0217F29C4C8DD6694
+:1062B0007C44CEB126BCE6211F4ED5E879D9E692C2
+:1062C000104EF35C856026ED37CDA5D3F904B59A61
+:1062D0009EABA22FC2CE57FE3C355C6CFD1CBD357B
+:1062E000A211FCE6426B4420F4914A20DC09A84745
+:1062F00023807C0061C61722B7D3CDF171CECF1EAB
+:10630000384AC713ED6A68F43CB3CBF15C913C2486
+:10631000F36C2982849BD2A955C5B6542401FA0591
+:10632000443FF9F2A6A39EE63FE28230C29F8EE789
+:106330002BF2C72CCEDF2EA2CF089E7D2576F9F654
+:106340003AE45FE2E7713F7D96C29F30AF4EFBEDCE
+:10635000FB2E6EBFA5818FD29B8F075F727BD5B45A
+:10636000DB4CBC660B40F109BF90134F85F8DE484B
+:106370007BE3BB1909DCB751165DDD48F0609C7406
+:10638000851B909E52A4279D3CFFF09F45EA2F65F8
+:106390002FADBD02D7DB5E678C2DB4D883DB25CD56
+:1063A0008B78DE139FAAC62C7AE66688BDE8B2F821
+:1063B0005FA160D3D8C26B28FF9DEC2EC2A3C2455B
+:1063C000F9CFE38B075F47B9E4F77BF1636D8BFD92
+:1063D000DB59B9C0CE4BB8A93442D66D41DD3592F8
+:1063E0003E365C04CE963CD6FE797D4E299E9F2D8E
+:1063F0007ED6FEA4FEFD483DE58B981A25F76A81FE
+:10640000E3A58BE085D25FCF5D3831355D9CFBDF46
+:10641000211DF6E0FE9FF01D993F1ECFCF99421837
+:10642000D1FE44CD116DB5051F2DEEB2B7111FA3DE
+:1064300020E102A45F3C8BCA4F107A7F22D8CEE3C2
+:10644000F2940F8769BFD1D19E52196F2DD75EC5C7
+:106450006B53F0F90C2A4F3047FB90CABFE8BA746F
+:10646000F5D0E53DD57E032E8826B3E7378A9954CB
+:10647000AE022564DF36BD9EAF517EE4F37E0D692A
+:1064800044F6B72783C04484678FDCBA3C9A84BF44
+:106490007FEE1268BF787C5E742DE533761E8CE645
+:1064A000E741E3E2DBC3C80F50A8E7227D242D4675
+:1064B000F5AD84E707E11F398BE915498DB48C27C9
+:1064C000FC1A3A2A8241C6855A33CA54D40F1A504C
+:1064D000FB05D1B96422DB2F9EAF6EC2712897995C
+:1064E000E47AC9B26F087AFBE4750CAEA3D0752EBE
+:1064F00003BDB3846983D37924B497E261968ADEBD
+:10650000979BCEA9C63BE91B7031F9DAD87021629E
+:1065100010FC351D7709222AC5D6424A2F95EBA6D5
+:106520000B724C45BB71CBD704D84BF130B09D12E8
+:1065300077D82992168DB8C8F89115DA5464A15409
+:10654000E3765608E58924F3960B4CEF6FA978A4FF
+:1065500095AABBD7ECFE9EBC3242ED52E2F79523E2
+:106560003DCC719E42C647B08FEC87F49739FF5DF2
+:10657000C85E940E49E4C0BC7E0FE11FDFD71EC584
+:10658000F9CBD9AF5AE4F6D5636C7ED3DEB9903738
+:10659000F0FC267E2E960B7018E1937A3C40E53D88
+:1065A0009BDA61A3391349B5846FC8BA3274D7E353
+:1065B00079B753808AF662BE69D2CFCDE9F3FDFC8C
+:1065C0004F3CD8EF3651A0F08C8AF46C41BD3F6A45
+:1065D0009300E88F548A3ABD9FBBB2FA804CEEB765
+:1065E0003442D8A7E33A6CDE96031E7A5E2A5990AD
+:1065F000F090FE8742399B915EEE3844DCA49FFB0D
+:106600005E2272D82E84844E9ECBB53103E19582F2
+:1066100051746FE060E82EB59BFA2D60E39BA64DA8
+:106620001B55ECD7AC6FEC0AA1DF522851BF45D106
+:10663000AA23945D3F25F830FD0A2217A138740A79
+:106640002554CF277CB483CAE8A67139DA350B3AD2
+:1066500089DCB6647CBD13E133A601954BB403D04D
+:10666000340089D813647CFC4E2DBC15F922CB7004
+:1066700059F97437C4B659F943D2DA297FB4FC45C5
+:106680005C9E4C2FDE2B307C5673BD77414ECC4741
+:10669000BC6EA92772E0EADFFF7A8EFFEF1A8B6EDD
+:1066A0001E4FF5133B7FCCE75D2EDD16AF1C7951F5
+:1066B000A1FB71DA2FF3B8FDD2944FEC178A07587B
+:1066C00080F64A1A277D5318E8737706240C428F08
+:1066D000341E178062667FA8E41FEAB9DCE576BB4A
+:1066E000C5EDB04F52D92DDF7445DBA95E232A09D1
+:1066F000E1DFE56A9D3F0EF19DC7FC46E7BEBBB8F2
+:10670000DF3857DC166A22703D992584DD7A1F3FF9
+:106710001470B978128C1397C83C7BF2059D58C051
+:10672000B0A746A0F6C9799DD9E7F08187F6BF8268
+:10673000C3D2B86911F58B7AF532979B6D75AA4D66
+:10674000BF38AF3EA53596EC5CF273FAA4CD8AD083
+:1067500038872F9CA0E70EEE33993DFE6071993A81
+:10676000909E938A94D5147FF965A725BCCE74FAC0
+:1067700045C9E7755EC16A4F8AA9FB0DF5BA85E088
+:10678000E9A46C9D3FAAE239E121E728CA85274C9C
+:106790008EA4005EB51C84DF130EFBE8B5BBB49C71
+:1067A000DD8F6EC5AB3AABE7F06CEAA74994EE7BA0
+:1067B0005462075AF031490C517CF6E2B750B0ED03
+:1067C0005F95AACB914FD57C01904FD5D8D7BB2EE2
+:1067D000E17C84FE6343C9F848E2FEA99D6FF69010
+:1067E000F30606A0C3E7E58B5F08A69F6CA717FD1D
+:1067F000B1C63D389D7BE9DF2F7EF1B7416F75163D
+:10680000A137E299D09BF9D7DA569433292E50FF5D
+:10681000C7EC77411863A39F74916852E237EF2A5F
+:1068200085A4FAF082A0D0FE443F94882CEEEAC200
+:1068300078E65C71533930B906F4B754E22F50BA98
+:1068400093F550CE9B3FAD5311EF6A4CA1F679976B
+:10685000ABAEB45E1A8E9E6470C16E66978C32CFFA
+:10686000D90D433B672F9043829DB3D5F43C92BA38
+:10687000ABD55202EF15F7B2F3116DB04CD21E4DED
+:10688000CEB7CE501FFF85F83A7271EBE17149CE59
+:10689000A3EFC53F39E046FD950FEC5CAB6D8FA0D3
+:1068A0005EF1E777E2B6F1BC5921127CE5151AA535
+:1068B000B8A591BBE6D17D7C57022A47177061824B
+:1068C0008F9D9B9FA8376611B98B443B0511FD62D4
+:1068D000A07A91D8B9DCAEB3AFFBFD4D4204F1EB29
+:1068E000C910F6A008FAEFED34DC16BD4CD6BD0792
+:1068F000D735CFBFBCC276C0F59D76414A7BE02F2D
+:1069000022F7B3A6D7A3DF950F0CCE873727EAD19E
+:106910004E2C7547EEA7F477F807BDF1251EC75E2C
+:1069200033D314227DD96FC93AF774C9B0159B9F30
+:1069300092DE96F8CE3D780E117DB3869F63774246
+:1069400034800FCF8240E36667E148E01A0B9D1F59
+:106950001215B64E8B7CB2DB12B75DDBCADAA6FE2F
+:10696000B97B97BD7D172CCA9108DEEE7A4C460F95
+:106970000DEE71F8A375A246F9FB6EA86E423C3489
+:10698000CA4C0ED668208D202ED2861F3F311DEDB9
+:10699000FF9D22F36F3E22FCA55BF4CD3A5F42419E
+:1069A0007CBDDF71CDD2EB01C7279A46A2BF9D0106
+:1069B00049CFCD3B5AECF00D06BF135E80CD14DEFF
+:1069C0005470486DAE48327B7A9F69B7727AD5AA07
+:1069D0008149180CB9E06157A30CA87D61BCE74957
+:1069E0003490750E70FB9158429359FEA27A065E60
+:1069F000071B7748D4B93E1FDEB83752ACB741ED1C
+:106A00005690FFAB24A3DC25F4C5A154B93A328AD1
+:106A10006C497EA9B493D8EAD67E2D43EC572E0C50
+:106A2000D0CF09EF694D3584C9FDE1BE1962C75069
+:106A30002E2E08B14AEAFF73B8DD886711AF12A5A0
+:106A4000278D8B84705D5F0BFAD11E5F07B5473CC5
+:106A5000BA64A37795A9078A80C673D28AECCF9DC2
+:106A6000F1923F8866FCBE93CA170D75922D0554AE
+:106A70005FA788F6E14CE94C6F7FB25E25EE6B3282
+:106A8000ED44F54B0DD72F95A03F34AB84CA178D3D
+:106A9000C3D5CC1F63201C35D97A18FD7009C211EB
+:106AA0003A8783AFAA2EBA2061F1ABABA41E05E5ED
+:106AB000A88AE86FEBFD8D4116274EA5B765507586
+:106AC0005F11DAB102C593A891B665DF9FB4BACA67
+:106AD000B91F94BE64007F776390C581D76C199B02
+:106AE000CEE229767D758E9F0F3FDFFF0305FD9770
+:106AF000B3CF9CB809F7B9FEFF8AA09275CFEDF726
+:106B000043273D37120A9E1BEB3AC4A471768006D8
+:106B10009617FF573FA5D7BAE7DD890564FCBA177A
+:106B2000DF9F0404BE739B7B0E8D42FBF919178B0C
+:106B3000771BDD931693FBEB2458154D325FA1C4F0
+:106B4000ECD4333F495B8EF2EB6A3B703B9DB77DE3
+:106B500099ECB69CDFA32499AE4BFA45F0B9F1B499
+:106B60002B3136895F62E619CE3CED62F0BD2453CD
+:106B70003F6F5DDB1E2546E0A86AFB98EA8BD9FFD4
+:106B8000FA6C00F150F59268B3E3AADAC44EF72428
+:106B90007A3D81578C9FBAA6239F707EE9D840E347
+:106BA000A695ED0F7E2C0670BC5D6F11BC843B1169
+:106BB000AFEF88E105D8FED1BF047482AA8F0E3FE3
+:106BC0001540BC9279572BE9189FB7F337CE7F3128
+:106BD000B3FF7C003D348F5BD5BE85ADE7D08B1F06
+:106BE000E12F79FDE3ABFF24D9F3E3D036B4FCED1C
+:106BF000FA67CF3F6990F5CE3CFF87270D02F7BDBE
+:106C0000FFFDC727BF8572F9338F867ABDEA99B732
+:106C10000260E1C3B512D3AFE70A88CB44FA9DFB0B
+:106C2000B53B8106C1B9577E3F5A27FB3DF7DC9F34
+:106C30007374D2BFE695B9B9B8FF9A1766E70E64C8
+:106C4000DF229F26DC56B812747EFD251733165EB0
+:106C5000E657075D0E761C1C8D709E3DE60E635A4E
+:106C6000AE8ADCAB9D8A74DA40CF596C6F22F8ADE6
+:106C7000DCDFFC31EA87FE7836460934A845D4606B
+:106C800010E9FCFE3C4A2FE8A1E7A3B37FD55142AF
+:106C9000C7C9A9E9761E3E5550CF55EDDFC2D67360
+:106CA000D0ED2CFE726D7FBA6D76D0ED3CDCFBFD35
+:106CB0003CCC97778CB0E5077AEDD4DEB878343DDC
+:106CC0003A807E30E57F30BCD2FC09812B2A451EFC
+:106CD00091508E9E4FEBA5EB02A4EBB3E74703E187
+:106CE0008B5372CFED781EF4BCE2D6303EB0EE95F9
+:106CF00077A85C9D7BE14D45A7E718F85CC4AE3CE6
+:106D000007BD3F87D1CEAC643E3E54EDF377BA0366
+:106D10007DF4A94C2C2CD703F4FE097A3FC1F8BDB1
+:106D2000327160892B09BD7E298D61FA3F914DF149
+:106D3000B261DF6F15F0D9E9E89A89743C310FEF41
+:106D4000A7A2A3B97F0DF73FC342CF7D4C4E9DFD57
+:106D50002B893CE279D74BD784EB1D482297E7F685
+:106D6000B8253CEFCEA15D95341FCAEC99E1E64D04
+:106D70000E39E5DACC9B703CA4E60F26DF83ED6F7D
+:106D8000B8F8EB90741B1F99783CF369727D7F9281
+:106D9000EB8B4A30CA475ED9DF0E91206A8C0AF528
+:106DA000C17B061D52C27F679E1169FCA7A9FD2009
+:106DB000D5DB4E3D518971CB24EBFDD15CEFA503B2
+:106DC00093509F9D79F527943F2BF79F50D0BE3F5E
+:106DD000D4F623A5BBB84F1EF03C4858CE83333FB2
+:106DE0003C3089E981E471515A6047E0AC7AD93E80
+:106DF0007FD5FE8F6DF3AF37DAA97D30D83A1F49C2
+:106E00009165B8DF8F0ECBD49FFCA85D4C1A27FE8E
+:106E10000F3C0F2D766DD39BF37E8BF9AD92235EE5
+:106E20001DCFCD8ECD91DCED68AF1D9181E60FA415
+:106E3000C81FDCA4DDF1A657C7BC73C791A5A26E1D
+:106E4000F1437FECC0E78CA3C66C3F996F4637F1E6
+:106E50007FF5FE7A63E671E25759F8A0E6CDF25C61
+:106E6000D4F7E887EAE371BD7010FD5C3130AF9C68
+:106E7000E5A505CD93F4BC66F3C9BE288D4FC99A2C
+:106E800000BA65DE5190A8C73C3AF87CCEBC4354AA
+:106E9000B5E697961F3E802E66D6E297F3709E0069
+:106EA000C4B50FA9FD09E14B03D85FCE3C8389CF60
+:106EB0005EF94B917748D36E0F1E80FEF3F5CFAF8E
+:106EC000C454CCAF34F9D6B4842CF995A660BFFC79
+:106ED0004A4426786871258F478C91CBE6E073E2AF
+:106EE0001DC7923D5F2E333EBF11BAEF5F8D7046D6
+:106EF000599E6696035F5FE2F8FAD964B271A242C6
+:106F00004B41976482DFD94B227199DC9FBBB2E77A
+:106F1000EA5769779EA731C60B97D2868EBFE1E606
+:106F2000E34ADD8B56CBD983E7E352E585FBE030BE
+:106F3000B83F9E69CB4F1C7CF7011AAF97A1BA25C9
+:106F4000648913E5747A208271FE2C9DDA87399D5D
+:106F5000F77C672DC699B3F2C31EE83F8F74F17AB0
+:106F60001ACF30F3F4527E84C6E5254D2F15E93A49
+:106F7000CB2298CF6FD681DA1FCDC181E33553E4A0
+:106F80009881F4942EDE40E715545E5730C47D7E20
+:106F90007B7180E23940F08CF24EFD1FDCDF71170F
+:106FA000CF87771B22E6C34F64D0FC404082228CFF
+:106FB000075C7079C39B43D02F1F9E8A7FB74B8697
+:106FC0004AE3247ABF7CF82ED9124F53311F4E8BDF
+:106FD000F9ECF970D557137C5D47FFC662EF86FA6E
+:106FE000FAF5C99D231F8E73615CC6689E8D764538
+:106FF0007306F0FC38CB8737F37CF8B38DD366A3E8
+:107000009E6DF698CF67B0FE66DBF8F5AB111FAD4D
+:1070100003A1EDD372CF66EC9F350AAA69FD9914DE
+:10702000855B2C7AF0B82CB13A5539F2BC6CAD279F
+:10703000E2FC60E67B0EBEFB7BCA57781D8374279B
+:107040007C8571A99CCED360D5ABE6D5E49F667DE7
+:10705000E0F8AE7C710ACD9398ED40562C1249C2EF
+:107060004757BAD9B963F271200809D4AF8199B1F1
+:10707000EFAC45BE0EFAC26914CE07689DC90E0D6D
+:10708000749AA770EC6387BE91F2EDF92CC2E516F5
+:1070900079E90FFF0D1C7EE61F9FD7781C306840F2
+:1070A0002C097CF2C512BA8F2972E4B7563C665D92
+:1070B00091BCCEF60E85EDA731BA92E5D12BEC79D5
+:1070C0004F4C335BE3A6D35CB153A837CCFCB9A0DB
+:1070D00046797EC330E3EAC1DE78B68EF580F71AD2
+:1070E000A8DFE495ED860BAF592C1F22AAB18FAD16
+:1070F0007C2C69DD4C0E1DF9BDB9E2198A971D8300
+:10710000D06F5B1DCBA76EADD3A8BDBDA52E48DB50
+:10711000CD753ABD36D545E8FDFEFCF4F3E01DC85B
+:10712000473E2FCD270DC6270FD585E97CF1BA99AB
+:107130006C5E97C9EFEE06E4774530E5C74FDB3E5E
+:10714000D1948F2CDADEEE62CFAF514653F931F98C
+:1071500079B0FD8989E994AEC39D3FE57E67F986E4
+:10716000B4DFF44EB6EE50D7713BD6D9314BA57A89
+:107170007947FE20EBB4B27506879FE16BDB81D3C4
+:10718000B45EC04DE4DF43F6E1D62249E5C1949FE9
+:10719000FEF3B8A9DE6ECE62F94FB9D0174165DEB5
+:1071A000ACF37C21916BB47FE4A29C32BC2F87AFFF
+:1071B000A2F5DC72B18FE6E3E4C29C3BB0BDEDC04A
+:1071C00016AD8CEA01819E5FB5D00D58974BC486F1
+:1071D000C663E5C2A2B5D85F43B9247064BA99FF0B
+:1071E00024175E77378E3F30E590DE9085E716E313
+:1071F0003FE8966CFCEF94FB94FA2B68AF5F04E9D0
+:107200004E40BF74DB94BB8AA87CAA967AC62475CC
+:107210007DA63E217A638D62A9E354608E8179D385
+:107220009DB7DE154EE62F91F3749D92DD7F1E73A0
+:107230007C851CDDA0B0BA74B0D7A527CF4737072F
+:10724000CD7C74B58AE7A814ECADA75B9047F0C27B
+:1072500052A9D05B4FE733EBE9C22CDFD54AFE25BC
+:10726000CB4B3BEBC42F573DDD16A5B79EAE00EBD5
+:10727000E97E2A43B813F3EA6F89E1BD7A7FBE73D2
+:10728000CEE77C2FC23C0752C965A762CF87E6C50F
+:10729000ECF950B8D3635BEF359497E2C1F5CBA816
+:1072A0000AFB3C05D5F6FAD72B6A336DED9031D247
+:1072B000D6FFCA9631B6E7635BAFB23D1FBF6BAA7C
+:1072C000AD3D21719DADFFD56D65B6F6C4F6AFD865
+:1072D000FA4F7E6991AD3DA57385ADFF355D6B6C51
+:1072E000CFA71D5E677B3EE3D8465BFBDAEE6FDA25
+:1072F000FAD712F34641B9CDE2F5C259B98235CF7A
+:10730000DA924DCE25E2B7EFC8260C43E3D9ACFEA6
+:107310004A618F7BF380CE7192AE44349AB71F37A7
+:1073200007AF20D5D0F354D273CA747A7FFA3CBC2D
+:107330004289BD0E56D1591D31FA65F67CBFBD1E7E
+:107340005811B7D1B206F7F12F77B926F5A7AB924E
+:107350006F9783A1D613CBBA63DC30E5E28C291793
+:1073600005442E683CED5311FD1E98E3A7F685C534
+:107370003FA27834FDA31B5488A3C968CA45E9CA53
+:107380009E51B48EAFD72F720BC3A95F33E52F6028
+:10739000D1FB91AC3E3DD33C7368FA554C5C63B372
+:1073A0000F9DD786C0BA54FA31E01E403F4E91A3DC
+:1073B000196EF42FA5880196F80B54CB36B8870ABE
+:1073C000E7673D07561386B3EA15134E85E86DCC83
+:1073D0002B352DBE893AF55003363ECD591EA5FEFC
+:1073E00009B10BAF76DBC633FBF06FCD4EFE8D6C73
+:1073F000DFA7692F9B780F84C2B49E04F204407FFC
+:10740000AE69562C88F1B416EC62F10F1F705F491B
+:10741000E7690C2A02D6B93776B1387B835ACDE2B8
+:107420000E72358DBF34640B5AB23AAE3BDD2CBFC1
+:107430002BD63E3876DF007C252AC9E30E0D7C7CF6
+:10744000C3816F74B17352D1D19F06E234BE6FC94C
+:10745000BF8970381A72E13A3BE83A010E57A040F2
+:1074600080FAD0E070DECCFD1DA976CB80704A0892
+:107470006712BA9870C611CE92D470FAB3CB687EF8
+:1074800052AADD46D731F1BACACDE8E584DBC4B7EC
+:107490000C91F2D9D83EF1E5284D8712B223BFEF07
+:1074A00098C9FC66A2D86DFC6AFA2D845FEB915FE7
+:1074B000258DF92FE6FB055F716B0CAF9C8EA067E5
+:1074C000D2B8432016A775E7FE18F3B7FBF40DE317
+:1074D0001BBF1C01EC2FF9049ABF5378BCC2ECF718
+:1074E0009E9BC5891A667547711FCDD74AB019F59D
+:1074F0000FD63763FC2E9FED378EFB22F0FCCC9D20
+:10750000C1F891AFEB8525E9B41052DC1F1C480F80
+:107510007B117F23FAEBE327DDFCBDE03CC863FA77
+:10752000B87819E6A353CDE3B44BCCFAE7E1D7B56D
+:1075300057D33846B36F6317C681CC381C044B92BF
+:10754000C6CDFBF0CAF2897DF45DA67712FA49D365
+:10755000A6523E69CEE7F4AD76D4E99A75DD9CAECD
+:10756000669C1B822CBE63D2D9D38BCFDD03E2D3C2
+:10757000C3E5C689CFAEFFA1F8FC11DA28E4EAF72B
+:10758000B3F7C2E1E03780E68DF2EDF2688E33F9B1
+:10759000DDB9FF536E7EBEFF0FDDBFC90FA9FB1B18
+:1075A00049FD1433FFE9E7FCA6E2DB4D44F1BC3EA4
+:1075B000F364CB955978FE32BFDA3F334EDFAB959B
+:1075C000C1D0502FF8CDFAD912FB7BA0DE62BB9D53
+:1075D000A53AFC1185D72DF57BCF95DB63CEF797C8
+:1075E0007AF1EBA0D7683545FE6A88EFFDECE4F947
+:1075F000B4BC9AD67AF46FF3EE6475F6BB65588521
+:107600007577232B0CC19B85F995D0736964FF793D
+:107610002F3F5C3F0A4972A71E42B3E17BAA6E8BE3
+:10762000EFE7DDDB5AEA65CFA7E03CBB54A677F372
+:10763000CA5B693D59C30BE3D3D16F79EDDD651AA0
+:107640009EF79F6415D2B8EED917DD11CCEF9DCD12
+:10765000840A5AB7F5E28C436897FFA1AE2B53B268
+:10766000F0C9D91FBE395D26443AFBFC9BD3254A9D
+:10767000AC84EDDCDF70E957D3116EA30C8AAA311C
+:10768000BFA629F47D932A95E5B3CC7A9C9D394A0F
+:10769000135E7FE261FA382757D881ED5A0C70A14A
+:1076A0009DC0E3EDD79FD197613D644697ECC27AC8
+:1076B000B9875D86E123D70B271EA6EF5D2B9DD5ED
+:1076C000183621F7C30711E5C658E6675C08415133
+:1076D00088E87DEFE1EAF1D43E76D42399FC2FCD02
+:1076E000061A97E8B9554DEC0D617C58FFF64AB281
+:1076F0005EC34A89D6CB6C970EAB5A123DF68667AD
+:107700008C0DEF7E1E2F3EF8EEDDADA564FCC62984
+:10771000AC8EDA77624A3A2491DFED7533E9FA816B
+:10772000BC93E5A508D6A7E4EEF43EBFC727819138
+:107730004E8E4839241832C18B6F26C0490BDF3575
+:107740000910D1C8F317EB80CED351A7D26B5B9D44
+:1077500036B69018FADFAD0BD2EB63753ABD3E52E8
+:1077600057449F3F5417B6C93DAE77B288B743A977
+:10777000E5F6725FF17DD8931638764E24524FE8C5
+:10778000B593E78B1E2C9E9ABE66807CC3EEBAAE84
+:107790001173C6726411FAE5D7687BB60E00FFEE6E
+:1077A0007AD7AA459837B94F8AEEA5FA3196B7C865
+:1077B000A21F1BE5581E1056BC5FC99C33278FCAF9
+:1077C00023959792C331C03A9BBC60AB0BE3D6794B
+:1077D00047D97DF3FD074A2F22683FCE9AE39251A5
+:1077E0006F16433B82A514C7A08CF49F91BDA414CF
+:1077F000EFC344FBFDE90A936F9CB78C5CA7AAD149
+:107800003615EDA6CC5DC6B3643F7FEA70EB988772
+:1078100079E8D53F2B187F8FFF5A51D18EC97BF95C
+:1078200004AD4B88BBBA156292C11B2D6BE748446F
+:10783000CFC4793E802A16C22771D4B1349EF9FB99
+:10784000F89C627CFF2476DADA7FA737761FB65180
+:10785000F1AA41C2471EB3FF9A78249FB4797DEB09
+:107860001B2DABE3066D93FE53583B4EC6BF9811DC
+:107870001B25107CF9EA57C5BBBE846DB3FFAA383F
+:10788000D6C31E52593D26F8622194B7DEB646DAB9
+:107890007E4B5B626D50D9D5DCEF86837F3E847A68
+:1078A000AEF265573B8246F41EC3FF4B0FD3EF2465
+:1078B000B4D575697199D3DFA40311C90941A07EBC
+:1078C0008A927025C610FD31817F1722AF24A2D77E
+:1078D000A37E4DC861D49B577899DD382141E6B12C
+:1078E000C8D58414DF1FA17959A4E33656D7DB8F9E
+:1078F000BF3CCC9EAF05632BFA0DB05FD668BE903F
+:10790000C71DCF98E71CF73FEFF5B0A6BCD9F05ED6
+:1079100085FA67B544E35AEB43ADA50A5967FD4FB5
+:10792000426172B242A387D51DACCF68CF994AF8A5
+:10793000A431C3DE7E98D7B906338C8CCC62AC0BF5
+:10794000787834E6ED2BA1F5F66F22BCBF64F9C15F
+:10795000D307AE4DBF9EB437FC92C5753774BCA932
+:10796000C4483FC1C3EB093AA67C05F757B94D009F
+:1079700021C4E433329EE039D27A9544F864A27788
+:10798000C45C4F01C0D363229A40F860FED68246A1
+:1079900015DB8A3601E566FED6C246E4ABF513CDAB
+:1079A000EF2414BE1E29E4F54C23719D07E21877DD
+:1079B000DEB7A2FC2B78CCE6084C6E0923D2FC9EE5
+:1079C0009811A779A7FF6C14685C1B53EE9BA66205
+:1079D0003D1D7449E4BA5361F4339AD8FB0CE47E3C
+:1079E0008B3C15E9C2DE1B228E24D5FB635F76D368
+:1079F00038726175E41E6A1768C592F5BD2CE0798E
+:107A0000E32BF03732CF780D4AF1BD80A73D2CFE35
+:107A100057B87CE97A1C27FA977851CE73C4844111
+:107A2000E7FF1E8B3BEF1412EDF81EA31128A4F400
+:107A3000DD19607C613C524CF9629F5076D57D84A3
+:107A40000E8DAED55BFF0DE99A51084857BCBF912A
+:107A5000DCDFC7E929668435A4DF3E4ECF784230AB
+:107A6000B07EC5BCFFA26BCD3D286FB76ED93F4736
+:107A70002578CD71475A47103A2CDFB23F1EBC968D
+:107A8000D2618C4AF0BEDCB33F8E74D8571F19A95F
+:107A900059DAE3FF42AC115A07BE9FCAB394F1C84A
+:107AA0003A9477F2FC3595F0E9D399A6BE60CF0BF6
+:107AB000C7F4EA8F0890B346ACEFD3272A391F0AE0
+:107AC0002DFDE710F9FEE727599DF997C87A28EFB1
+:107AD000641F343FDB33414AA0BFEB25B0A0DDE299
+:107AE0009D3886D6CF917D03DA253D13257ACE9A2F
+:107AF0007169F70481BEE78DFD911FBC05AC3F1194
+:107B00009428EA4D295F02D4EB92B83B3241C7700A
+:107B100030CBBBBAB485F43D514F9125CF0A7D756A
+:107B2000BAB41DA29F97B1B5C7BABBF3046257663A
+:107B30001D5FE81A4DE65BEAE1FE4616B1B7C9FDE6
+:107B4000151E662F3D1035BE8C210DD0BBF3A87ECF
+:107B500082E854BCE6DE56989B2C1FD277AE3BEDF4
+:107B6000EA6E6A3FECF009E5C9EA4F0BBD3CDEE086
+:107B70003B42BFE7510B44FE512ECCF764B9FE30B7
+:107B8000DF1F70D6FB9AFA44CE607BAC995F968B70
+:107B90007A40E2F5439216D6B0FEB1D45F42EDBE14
+:107BA000C7B99E120F5C7B33BE47A1A03E00D45FD5
+:107BB0003103F3FF3D79D08EFC2A052360CDD39AA3
+:107BC000FAA0A94EA5D7A7A68E2B4339796A6A4E8B
+:107BD000994664E0E0A49F7661DEE8FC6E26BFE78C
+:107BE0000FAF35687CC960F122642B1A67EC7C9476
+:107BF000BE27FB0329FA10AD7BC5FA0502D2B60CED
+:107C00007B7DD5082FABA3ADE2F036CAEC79731DAE
+:107C10008B072B17AFA671A9F3FCB93B76277DAF75
+:107C2000C24DCE327CCF5105C360DF196078C0F7FA
+:107C3000986C798B8B93E8F82A0FC3BF59CFE1ACCE
+:107C4000DB30E119CBE1E9FFDE849D1EA6FF65D2A2
+:107C5000C11C5FE38AE46A03F04DD545111296F822
+:107C6000475FFDB542EF9FC3BAF574ACB389B55E0B
+:107C70001F42394850FFC8E3AB01E0DF35A27C1A50
+:107C8000947AAC75E2698EBAF57EF2A2DBDBCEBAED
+:107C90008515C81CD3981EA7F5A6127CC745E87D9C
+:107CA00036EDBDE968D75611F5A062804832345CE4
+:107CB000FF1CB7F7A597EF8B8CD2FBF663C60BCCF6
+:107CC00076E54B0B691CA16A9F8FD6E357A2FE9BFA
+:107CD0008C75FD4697DB56CF1FE9C4FA39F9253676
+:107CE000DFE31C9E3F691579B8EF37B8FF9323C4D3
+:107CF00044F652CA618A87B827720C34A6CF24C2D0
+:107D00001371B3DEC2581B478761A702367B69A790
+:107D100097B5FF73CBDA789C9DB3DC9EF984DA3F8C
+:107D20008D1EB37D96EABB9D4A6B27EA3BE345B7C0
+:107D30008EE717194FDF93365614D173201E8291A8
+:107D40008887D73214AAE7E22FB8F7A29E9BAAC66B
+:107D50000EA916BFE16CC6DBA3D1FF4A329F619B1F
+:107D6000AF6078F391F53B10AFE6F3D73276768AC1
+:107D70006C9C4EBFAB917F78F46AD2CE79D14DDF47
+:107D8000EB31FD4D275F2A5E265F4D8EF7F314948D
+:107D9000371FEADB6A2A67EEA03DAF65CA9D7271A4
+:107DA000822DBEFF383F67152986A14AF2BC983E56
+:107DB000AFE2746DE27506A9D7C94CB1CE35549EB9
+:107DC00053AF339DCB3B703996B4DEEFB10CF01E50
+:107DD0009F33EFE1D453BDF2CAF5D0169C1FE3BA2E
+:107DE000101BE325D77589F6795E3A3A3609EDE03E
+:107DF0005F737FBCA8EDE157F1786E7147EEF24CEE
+:107E0000A3EF657D17AFC39587F95EE0F1947E7AA5
+:107E100088D95777327BB566FE546ADFD56C1FA3CD
+:107E20001903F8491517D36C7A48F0E8FC3B77063C
+:107E3000D547151703F4F9E55BCF637BBFA4FF7A41
+:107E40003EFADC5CEF5E879E3D38E9173B0BC9BA12
+:107E500035CFC982DBB24ECD73BC3EDF43F4AE5D9D
+:107E6000DE2328EF52087ABF4782FA619BC2DBC645
+:107E70008CC639F968D75AF4C34CB4BFFAC6E3F7D5
+:107E8000E5B679CDF19146B487FAF54F73F41F63E7
+:107E9000CE5F4EFB3BE131F50FB6D1DE92FEE2360E
+:107EA000E1A3FAEB61C1315FA6B9FE423A9F69775F
+:107EB0009F6BB9F57543423E6D2D45FFA9672DE8CF
+:107EC000F8DD871F48616FD8C2B7E75466F7575C83
+:107ED000BCD246EF3EBC8FB3DDFF7D5DD0564F7BFD
+:107EE00077AC86D6519F5339BD88654EC7ED1E6568
+:107EF000ABA3FD071C9F158EEB53C071C35F198E9A
+:107F0000904D3EFBE028B4DDFFAC704454A68FE7F3
+:107F1000F1EB5C8DBDD73A5777851BC8ADB9E4BE90
+:107F200087F0FA97C95525D7B912183EFA3DD20401
+:107F3000EB4FDAE8DFDFFC97FB3FB89126AA82B669
+:107F40003A0191D7613BF50EBE77CDEAD854DBF705
+:107F500042CCAB5764F594CEFBDD3C6EF0EDAB2B21
+:107F600001ED6962AB277DAFACD1C7FA811A146C01
+:107F7000716EDE36EB702F175C7FE4E7F4B7AFBEAF
+:107F80000930AE2B215C49FAB573B89AD408CDC339
+:107F9000C5B581BF07F359E191D34C3CDD40F124D5
+:107FA000A6C0D32A1FB72FB418F5939A825F0C3C52
+:107FB000B9BDF00C8C9F6FA43178E0E215948F442A
+:107FC0004EA7265FF2EFDB98F98F26F58B857F723F
+:107FD000DAD0E8BB87F7FBA2E95B3A44FA8E30F9C6
+:107FE0004DFB62E1593C4478AE35F92D18A1F4FA05
+:107FF000A2E0593B44787E6ED24BFF62F1F3C01091
+:10800000E139CBFB29692C3EDB54C4DEF7F08AD181
+:1080100087B0DE6130B9F016DAFD6C35DF6BAFB3D7
+:10802000FAC05EC7956A9FBFE1FB4C254F2BE44425
+:1080300036D2EF581D8B07BCCDFD93DF5434F86961
+:108040007CDEB14E5370AF7FA0B8CDFFAAB0BF3772
+:108050003B981C17A4B1FCCFAD31FBB865CBD31C4A
+:10806000756106FB4E30C75FAAF9FE5EF0361993C4
+:108070009843C01BC1577A6800BFE172E32B95DCBF
+:108080000D175F716D78F81A4CDED722BEA60D1D54
+:108090005FA6BCFEBDE24B1926BEFEDEF9ABF41FA7
+:1080A000F81A16BE160F571EB95DFBF78AAFA1CAA4
+:1080B000A3D36F23FE5D78A0F7FF2F37FE9CEB7FE5
+:1080C0005E3C9AF3AD48E1E7A5C2E7607098D76ED1
+:1080D000EF10F1EAF43FFFDA7875ACFFB9F1CAE7C7
+:1080E0001B365E0781C3BCFE11F13A0CBBAE4D617D
+:1080F000DFF574CE93ED67DF5B1BEFAA3E321FF313
+:10810000C75F15697EFAC8EE391BACF540D97E66AB
+:10811000FF1F299FBD81D65747D368EDD95121FC58
+:10812000EF2598575EC4C639E73FC2F1F55FBE0C34
+:108130001ECFD6B391AE47A38B07944728B7EC8BDD
+:10814000E68D2CF415FBE3FB08E8DB4B300FB12088
+:10815000391C269D53AD3B5CFA1E8DFE6058FA67B4
+:10816000B0FDFE876FA8767A82E2310B7AFFDECD12
+:108170005588CF3681D5C31DC75B79F8DD35A09D05
+:10818000962DCFDD83748AF9595EB043D13760FEF6
+:10819000C4BD78C1837E42B7A3B764B8DC167C5DEA
+:1081A000E3677ED5F495C9FDAE08E783BEF12E18CE
+:1081B0009F84BF27F37EB7AC64DF07032952B0C8A2
+:1081C000F21EE90ABE8EF9DC397EBE3F40C71F4D64
+:1081D000F15EFEF57CFE654B061E0FD5ECFB3B8485
+:1081E000EF0AACEFB1F6F219978FE3BED81C3F81CE
+:1081F000E76D57EC89AF211F4DF0B1F7802408617E
+:10820000FD95394F96049D0AC1FB07B25E8079CD7A
+:1082100024F37C75A07952E1D5DC8FB90E8A227ED9
+:108220004767AECAE28825118059183F7487EF630B
+:10823000F943C60799BC0E7146755AA21EFD5E89A8
+:10824000ECD3026FC7FF9BFD4FF8BCE388A0D1F7CA
+:10825000CF1D78184C3F6CE47C9325C6367B306F7D
+:10826000B2CA95F43B73EBFDECEF0C15F87BEBA574
+:10827000E83AE31E8BC9F87D8AA512CB7F114E2CFC
+:10828000B0FEDD9102CE07CE715922AB37827798CE
+:108290003CB7ED5D57904C7E7EC5E5B4C05F64ABE6
+:1082A000735C12BD4F46F95CB260A1ACFBF0B9CE75
+:1082B000F88DC3D1A6C40AA6F8FAF094520F71FC47
+:1082C000741C8B35E0773956D5BA689D40F126C6C7
+:1082D00077AB361D103690EB1E2E7F0B910696F96C
+:1082E0009EE0746DDBEB1D8DF0B799F91B9C98C077
+:1082F00071FB2EA0F990C7FD1F34613EA4DB053C45
+:10830000FF1B2DC7FC6F37AF6F7B8E3CAF4778E705
+:108310006453F91EB7E9E31AD4CF1D0AD0BF7BF12D
+:10832000BB2DEE04BE4F60F24BAF9ED874A10EEB96
+:10833000871F553A2722DF6437547F2D59FE743F3B
+:10834000A7C39F7CD1F46476A07935F5B9D96F9134
+:10835000A4CBC9FA2F2E779C6B1CEE11EECEB390F6
+:10836000248FD9CB878981EDB4B7B81EFF9523CF71
+:10837000BBE458F23863975FE0F396ADA7E796E168
+:10838000D669CD3487C7C45796C1F0B4748968D311
+:10839000B7AB16A439EC1E86D79BDDFA93B88F478E
+:1083A000F7FE62227D2FCA713E78C59882CFEF8694
+:1083B0004E19F5C42951A7D7B7EBECDFFD7E1B6240
+:1083C000DBA7E1F9592B2695ABF739FFBCBDFC8E35
+:1083D0005B28FC715143F84FAC1C71D34CD42FCBAC
+:1083E000E5F05832EE44FC7EFF5ACBFE7BED1A07D7
+:1083F0005CBFA9B863C0736BD9723BDDDA14661732
+:10840000185F6172780FE1D15994BFBAB7CF20EBF2
+:108410001F49644ED9CABA03FE7DA7C5FCF7534273
+:108420006CC70CA26F4E0B2C4F627C9DE98D258F83
+:10843000451B31757ABAF69A57BA49BF8B7C7FEFE4
+:10844000D50E7C3E3AF969DC63767B6FFA31507069
+:108450007CAC26F979B0554BE37FC72B3C1AF5CBA2
+:108460006D9B92F7FB213233A1EFE9FF162B92C5EA
+:108470002727680CDE55D1E4E327687EF61CCFA5DC
+:108480002478FE2090C6F59C361AF5F4AA14F076EE
+:1084900007D8F9F57EE303B7A11E3825D8F5F39187
+:1084A0000093D7F600E3EFD37B57C8D948A72697A8
+:1084B00086FC7032233C01F96D75FC047DDFE55FBD
+:1084C000020CEE43DEA81E9886F2B2686E36A14B0F
+:1084D000C74A08BBF4D4FABF2860EA7F16AF25E785
+:1084E000DF0778FE91A11F50FB438A8CBE75229D49
+:1084F0009AD6819F168C75B4CE70AF97D595427879
+:108500009AD58E9FCEE13EBD6F78F4BE25EAB0834A
+:10851000FAD97FAD9574DD7D691AD6A51C29173B64
+:108520006F24407EB82F8D7EBFD62917A9D61FAEE7
+:108530001D787ADFF0ECC0C1F6BD32101A921D78BA
+:10854000BEFCD11D2528474AEBA464FAD7D4D347F3
+:1085500079FCDDC93FE6B582F3C5A9C4C070DDBDB5
+:10856000CB0ECF6DD576784C79399568F0AE463C18
+:1085700041E744AB5D0A73A60D72CEB2FC542A38B3
+:108580003705EC7A02390FE9700FD737EFD53E1A6D
+:10859000B0D2C1B9FFD302F70F9E6475B963A3AB24
+:1085A000CBB2F53EFEDCC2E7BFDC7C699E33CE7900
+:1085B000FED6F9D03CE706E3C3AC14799C027C718B
+:1085C000998C5F2D690AE6EB0B023A6B83360F5FDD
+:1085D000D58299E6DF57D147E3FB5FA7F77AE97BBE
+:1085E000C0C6567702BFDB7E6AEFF513ACFBE9E24B
+:1085F000F459B524837E9EE294109E9F4BEBCE44AB
+:10860000FA9DB5B78F65CEC3F6A38705D4D0705B4E
+:10861000CD6A11F7F77A80BDB7B36AD39BD41E1C1D
+:108620002E9FAFAAB69FFF13701FD9163B4BEA29A6
+:1086300041FE49858717100FE8074517CE45FD7C99
+:10864000C72617D5B72FF279EE9022546F439C9D21
+:108650008FA0127C9023E4046E02F1F138FFAE94F7
+:108660001455ACEFC9ADDDF6C05CAC7B75CACB97D9
+:10867000D3199EA6A433BD7DC81B7B2F90DDA79F79
+:108680004FBAAA0FE4922EEB039AF91D5F2AA7E6D0
+:108690007ED673B8889DF62CFDBE30DF1FF438F807
+:1086A0004D68ADFC29E2BF4CA57681D74DF43ED68E
+:1086B00045FFC04BEBA84CB932ED1DE7F8A552CCF5
+:1086C00066377ECAF59ED976DA21FF382F92F71FDA
+:1086D000931E1A929C5EAEF36252FAE5392F04CED5
+:1086E00067CE73A357AE9BD8FB20278E7D32379978
+:1086F0005CDFF819E170CAF3A9BD5EF65DE31BFC0F
+:1087000054EFF4F953B909F4979D7281FE147EC7B2
+:10871000E3D1BD6F4CC4BADE13DB1FB82D193DAFDA
+:10872000D6781D7677AE2D9EB72600B4FE1BC87A8C
+:108730004F59E637C7F5CACB20F1CBA52BAEA5FE26
+:10874000E4DB2BAE1FBDBAB8BF5FD1AFBF2BF6F8CD
+:108750002DB86E3DF7A777B82BF626F303395EFBED
+:10876000C789EDF6FD2D9B4A1BD1A5DE9C76C397EC
+:108770006249D6EFF56B36258FC7FD9F74875F631F
+:1087800010BF86E0A37BA5189859D2E7D7741B5F6A
+:108790008C5FF33BE8F9F71954FE93C3F7643AB3DF
+:1087A000534F29B11DD712F84E13FFC740F911C816
+:1087B00038E497EF26F7D71EE1E37EB76998FAEA27
+:1087C00098DD9F49257FBD707D4EF96B537A0A5025
+:1087D0000FFC6ECFA7EF3E80FBD9E3A5F876CE73F2
+:1087E000A32672FFC24BF9D63C9F3B14A6FF7FF72E
+:1087F000D591F4EF553BE503A0F5A6EBC8F3E37B79
+:108800008529F81DC4B6BD6915C9FC9C159A8BFB5A
+:1088100017F6780F70FBEE16CE6FDADE67AAADF1B1
+:10882000E877B8BE32E300AFA4B37376C982850A95
+:10883000C67BD6F6C69B803A2BDA55F97BF03B52C5
+:108840006FF1F7B98C35FEA4EFC7FD82F3E56071D7
+:1088500088E52BED7182250B063E6F3E4C24AFCB95
+:1088600032F939D57AC33D5FDA12C3CB8B0DB64FDF
+:108870008F36347FE416A8FE12C63B964258C6EBEC
+:1088800012A89EF85382CA0F772DA6F0BC65FEDDB4
+:10889000E14FEF9F68B563FE8BE3FBFC92FBBF8A61
+:1088A000EAF21DA57A62B2F3C919F7792B053ECF1A
+:1088B00070BBE71DA433F2EB5231299DDDDC8F7FC5
+:1088C000672593A3FF0F425212950080000000001D
+:1088D0001F8B080000000000000BDD7D0D7C54D5CF
+:1088E00095F87DF3E62BC924992433934FC2840075
+:1088F0002206984008A80813422428950904080A6B
+:108900003A7C88817CAAD8B25BB74C0860A46E1B05
+:10891000566A5DAB74A0C152C536D1D422A638A028
+:1089200028FEABFF06EBBAB845775017F9924456CC
+:1089300017BBEB963DE7DC7B336F5E6620B6757741
+:108940007F1B7FEDE3BE773FCFF739F7DC3B972EF8
+:10895000C1DF0CC62EE99E8BAA5516B232FABB04B3
+:10896000FFAB9E9B145576D9ED8C3919FBC7A5AD8D
+:1089700089FE22C64E19E065096381C7D4E06E0501
+:10898000CA41FE5EF6E7B22B54FF547041AADF36AF
+:10899000783CF9BCEB5118774C649C65CDD1E386EB
+:1089A00059602D73C038C144FBEE0286FF0C592676
+:1089B00046DA77DA0D340E3B9569602EC6EE936D7C
+:1089C000E38CF7BB0DD0C15583EB571BBD26BB66AF
+:1089D0009E2B52DD8C4D8E94ABE746CF3335C54E82
+:1089E000DF19B3E7FB92193BBD2BD14BF0989E1CCE
+:1089F0001C05F3ACB0B2800DE6F9F093D7BCCF46BE
+:108A0000305625E051EDFBD484F0386DE8DF9C8CC6
+:108A1000EB7ACB60DF0D43951EF39AB4F05B9BA21B
+:108A200050FFA73B2E0FBFB5297C9E0B2AA3E7B7AB
+:108A3000F058625459BFDE7FFE9B072662BFFFFCE1
+:108A400037174DDAFE177D91CB421991F21D358A09
+:108A500037583478DC8E54F390E0DEA183E31D5F59
+:108A6000E453FF0E953577C65897C76EA5FA0B7D70
+:108A7000652627C073E5FD8A47812E8AED6E1A6F41
+:108A8000A591793B613ECCE8CEAF02B83B5B9BEF52
+:108A9000F3C5E8678D9DC3EF339B2FD57E19F8BDD5
+:108AA00023E841D65B64F49B62D55F5C130DDF3035
+:108AB0006395B1E67FFF57A44739BEBEFE50E7512C
+:108AC00097C2F932C312FA84A9F0E21CF453FA15E2
+:108AD000C6D5D5D78FFBD702EEF1C63FFD47B536D9
+:108AE000161CF60AF8FB7D403F31BF27D3F7B75875
+:108AF0007BE37EE2EF24CF6E0443C7CAEF01DAD9ED
+:108B0000EA39F7BD0AAFD91F920B68FCA5BEA315C1
+:108B10000856F6E5C3E311EF9F573EFCBD1298DA05
+:108B200069B3BF35191A9CDEA87802EEC1E3BC8593
+:108B3000EBB430F6F6062BADF70FD096F0330BFE04
+:108B40002F9BB131AAB70E850AFBB6C5BD5BC3B773
+:108B50008EF51737B0F18CED31FB36E21446DFFFAE
+:108B6000E93A86328F0569DE1F983C6B08DE8C116E
+:108B7000DF1FDF65DBB915EAFD3199E3032839DF33
+:108B8000374E23278C762A0F153FBF8B839FAF2A42
+:108B9000A7E43AE38D0390A7F9CE9F696B5352196E
+:108BA000EB36BBEFC4F5F4CF49B0EF0214CE377B00
+:108BB0006F46F8BC75D4606829A06E8D48A70BF885
+:108BC00010ACE09682EF8E2D41F963F226C054AAD4
+:108BD000A00DBB16E868A62D80FD95FC6EEED3882F
+:108BE0009F876B2C6E15FB9BEE7E4F85F2FC9B2CBA
+:108BF000EE8DD05F69EF88830EE87FE15CC5CEA083
+:108C0000FDAC39A39C61585FD27AE82707A7F79D8E
+:108C1000CAF2918C3D85835DC7F8840116F3155126
+:108C20000E3CD5360BE4C15867B7C106A05EB8ED5F
+:108C3000A9362BF4BBB9C597654F83C9A6B5B459FE
+:108C400087813E72797B6778189B9AD65A69BD01F5
+:108C5000D6F998EC6F539B378FB1170DFE0205BE06
+:108C6000DF91F644A511E6EF2894E377D2F7453774
+:108C7000ADD9BD0EFADFBCED50A511E7BD548EFF96
+:108C80005A65B911C69D26CB6F58B1EC4812ED71EB
+:108C9000BE5319338D88CCDF9805E3A7CBFABD9579
+:108CA000B3A0ED3B65CDE54618FFDD6DEFB41525AE
+:108CB0003036656E99DD0BE5F7D3CE5726017EBAC7
+:108CC00019D029943F48EBA7F93B5483E8FFD336EA
+:108CD000EF349C4F602C7E57029FB5551633D660FB
+:108CE0000DBF8AE4DAB43E6075C13F262B9C4EACC2
+:108CF000A6666F2EC0CEB4AF2C944BD369E7F4991F
+:108D0000171A877A6CA03C06CAE334E52C5EEEDEC7
+:108D1000C8EE88256F83E95CEE7527C6FE3E318D6F
+:108D2000CB03801BE993D463CCBB37865EC94EB3BB
+:108D3000513F871359C09A1EE1B779C0C353812FA1
+:108D40009995CF53F633487FA4713DCB02F3D2916E
+:108D50006FE66217B0F4428F1240BA66CD49C15136
+:108D6000483B2C645C80FA4335D07C9DAA72471541
+:108D7000F4E74A64FE2E783A331895A1BDB7CB16B6
+:108D8000E9EF0D41F71585BE0EECAF2233BBB8B548
+:108D900020D20FCC7B937562D4BC8D53D3F1FBFCF6
+:108DA000E2BB8B34F02CE2EB003AA07630CCD3332C
+:108DB000800FBA7BC78ED80AF3FB5027774B7BE72F
+:108DC0009B18D4DB9C2EE4899BB7779673F9D37FED
+:108DD00077527017F2A7D5538C7892EDE60AB897C0
+:108DE0003F30F78758AFBED7C42C506F5D57592618
+:108DF000BB8C5EACFFE27A169CA4291B4366943BB5
+:108E0000F55F4CA7F7E50FBC61463EC57EDCB0AE12
+:108E10007509DE4C0FC2AD3536FE196BA179D47FD2
+:108E200091C60293B4EF399C22FD3BE8FB95D61521
+:108E3000E94F65C18CCBF567A6EF0370370AB89B85
+:108E400063CFF35E49A7006F8386BE160A7A03E9F3
+:108E5000E7457978FC96A25D28EF23E36EA476DDE2
+:108E600046C023DA81BD896EB48B4B8D5C7E96F64D
+:108E7000A6DB034A843E245D48BC76A73797D17AA7
+:108E8000AB14FBAE82C1F3FA6B392FA14F3397FAC3
+:108E9000D5E59AF9497E80FEBB45FF2553897F9E23
+:108EA000E0FC007CB30CF917ED165C8727346E7E6E
+:108EB000F2E0F97F0CE485F5018F1CFEDFB005516F
+:108EC0000F48B80D867FEE15F0994FDF4B7B0F9959
+:108ED000719DF571F8F6DBE929346EE6B1508A1B15
+:108EE000EA9DB57379D5DD3929E17AE48BB9068637
+:108EF000220CD78DF66AE980BCBDE1F599A01F323E
+:108F00006519E5AD1BF130207F43566BA47EC3DFAE
+:108F1000DD306713D4775800FF4564875A99C69FA0
+:108F2000F8591A976353FD2CA6DDD2929E4CDF258B
+:108F3000BCFF7E7D39FB10D6F7AF76CE9753C301C9
+:108F400005F122F95A2FA78E083C1EFE1F9353CA23
+:108F500015E454959053FCFD6130F3B19ECB151A86
+:108F6000A7804E5CF1FAA451E8CFDC93A5BA3F028A
+:108F7000BE5AA078863D03FD565BDD9B93DD113A1A
+:108F8000A96656B70DE10E46D325D4FB7313A88C02
+:108F90007F68975C6857381D32776AF5B8F8724871
+:108FA000CEE39E2C338DB7E2C151A97EEDFC849EA9
+:108FB0009867093DC30A07F3B92CC3FC1B0CAAE64A
+:108FC000BB8DEBB3AC64EF87698087B7145643F36E
+:108FD000D1D94BFF21FC36BDBDB449D8914E342FB9
+:108FE000898F0DE49C66B659828C3709A09F9AD967
+:108FF000C904BF860CF51A3AB8989647F358BA18C0
+:109000003E4E00A6B4BE3CE1230D1F1DC1F9905E8B
+:10901000084D463E05B119358FA5AA2F4F41BB35E6
+:10902000D3E24139037822381C4E60C60418F73564
+:109030007822DE2AD4BB0F9A1C48078AA795A0BFC6
+:1090400053D8A72C84FA66DE8C24B25BD997F78EAE
+:10905000AC0278389338DD423F56D18F95E844C84A
+:10906000BDDFE65FBD0BF593949F120FEC4B95FAB5
+:1090700093DF0F2B557976281F765E55DCAA44DBEB
+:109080003F680F45ECA7C40767033F4EA9EC0C19D6
+:10909000EC285592E77C0BED70B09F12603D19E90A
+:1090A0005C0E1C2E08A829D8DF285807BC7A35D1B9
+:1090B0005FD46C8BE0036C1C3FE2CF6586A78DF319
+:1090C000073EBBD23932AECFE0CFCDE2E94AE1F57F
+:1090D000F5F4F6830CCE9F6B150EEFAD655C4EE894
+:1090E000EB8D17FD36580395AE115AFBCAC7900E8B
+:1090F0008D8CDB5913D2059D947378953FB0341550
+:10910000F5E6E7BD0B535951448E6E56FC760FD4ED
+:10911000DF6CF27D9FE21DFFA032F447CC697E7BBD
+:109120003AD4CB488AED2F57A7F3F966A03F0DF547
+:10913000BE27FC1DD317D7909F7D23DA65F03D2510
+:10914000AB9AE439C2D00DFDA6B2FE805D83BFD4D8
+:10915000A98628BFC1F4C5786AFFD5ED86E23876C6
+:10916000434994DD20C7D5DB0FEF6DC8A2F9CBF6DC
+:10917000CBB2DEAE609AFAB7B3F066ECEFF675B933
+:109180005171A27876C75A8127B4130231E7658EF0
+:109190007AFF1EF88901EDF8A7F8F891719380D154
+:1091A00022E34E48F7D6A5133F4DB39FBC061E6081
+:1091B000BB5F5249DF90DC07BDE4DD69237D548944
+:1091C000F25AFA47C8F7F654E4EBB27BD3276BF4B4
+:1091D000A368A797439F087FFA13A167528F497B23
+:1091E00031D1AD28117D33585F093DA3938B57B220
+:1091F000AF815E035AFDAFEFF787E97FAA5D59188B
+:10920000873E46FFB7D895A5D3FCEA38949B950ACC
+:109210001B058F29B3A2F5FCD3E9DCFF783A3D2981
+:10922000CA5F99BF34BADE2FB0DE647C260DC95FF9
+:10923000D1EA21454579C7FB6B14F45070E62DB394
+:109240001BE4EF19B483A0DED10CEFF348579B1257
+:1092500053C6A37ED8F99FE56376C2BCFBDF3479A1
+:10926000766177FB387D942D59D76A84F7A64EC571
+:109270006E6191F9D9D6774D5805EB3D28F054EF42
+:10928000E0EBA87784CC2361DC9C7A3E7E5EE741EC
+:10929000C5A8916F79B5BCDE6FD24D51FAE6B758CB
+:1092A000867EDE94FE070BB65494607DAF712B88EA
+:1092B000BE9C4E85E2C139CD0000A0831C0FEFDFBC
+:1092C000E6092A2B8B22EB6C335415A15E687325BB
+:1092D00079502F6439FCFF80EBAC3F1E0A2198A621
+:1092E0001CEF35A27D37D1E17D87F84AACD3ADDAEA
+:1092F0007350AE261DE7F36BD7D13B63DF15F3DA6E
+:10930000C5E5ADCA8E30C407CA0E18CFB5710CE9D9
+:109310002559DF952EF4848BF99F25BB8AB531C280
+:1093200017A375B8368E26FB5EE23362475D3D11AA
+:10933000EDA8C28742C615D06EFFE386CA5876E212
+:109340006702EEB08E3EED3AE2F185D463B29E291B
+:109350008E1F2DE93DA932B67D0A1A80BE972D7168
+:10936000DC8AEBAEDF6466162502FF890E9F21C3FF
+:1093700089F8DAA9206C247D6D4A7F4AC985F5DD1C
+:10938000BB86D955167FBEF5EB9F9BB04AE36F4174
+:10939000FF848F9D6656ABD5A7D29FC8C9E0F6F46F
+:1093A0006A872F0DC76DDCB7CD8CF85DD371C2AC69
+:1093B0008D770F5AC710E1A5D4723FA5BEC61AC457
+:1093C00075962D3112FEEA369983288FEAF7768555
+:1093D0000C684FDFCF3CC8EFF59D5DAFE6005C72D7
+:1093E000EBBD935577A4BFDCFAA082F3710111F6AF
+:1093F000929F1732A37ED6D335DAC36897BC9AC042
+:10940000F9FD5C992DA000FCCE99FCF558EF5C7637
+:109410009227501081F76B5DB38F28C0D2C9CF5A05
+:1094200042F86C33ECCAB242BDB6B1660FD2D14439
+:1094300087BF3403E0946EF47563FB3447B2A7052D
+:10944000DABA2D6C22E9E721C2618A8E1EA6DCCF32
+:10945000F9A4362345DA7B13510EF93278DC156313
+:1094600042289F5E35F1756C627CBE5DE9DE0AC400
+:1094700013B3A7D3B839F52105ED7DFDB8117AF204
+:10948000DE9CF115E81BEC3C33CAF53A2167CA961D
+:1094900074281F6AE8E0563064B05ECEDE9D0AFA9A
+:1094A00081F0BDA5C241F59905E5CC5EBE1F51070F
+:1094B000DFEFD4C815B98E18F26539C2D776BCF77C
+:1094C000152E5F42447F72BE7A7C3664B869FC1BFD
+:1094D000C12CA0F7E6C01837F4F7EA8844EA4FF247
+:1094E000BB9E3F1B049DE7D474281837702471BBC2
+:1094F00051CE4FD63B9A31F36E9CCF94CA5E8243D5
+:10950000438D91F026E75361F68D44FF6B83E8EFBE
+:10951000D0E2F7CD61286FFFD551A2C78676C54B43
+:109520007E41FB51F3428CCF057EA6623CF6666E0F
+:1095300092B0477E7994F4C8CDDD3C4ED0D0DD6545
+:109540005C698BD069C19943B7239D35745A5882A1
+:1095500082F8E376AB9E4E41BE10DDB38099F6B340
+:10956000403E06489E327F01FA2352FE7689B81F9C
+:10957000B3F1F77F27E62DFB8DC8CD04A2F7823328
+:10958000130F59019E0D1EC503A612D8DBBC1EF495
+:109590001F22F9CBD808F4CB64FF7AF81D10F679B6
+:1095A0000C3CEF40B8EAF588D4AB053B66327C4A08
+:1095B000FC1905DC65BFCF6498A9DF67328CDCBF7E
+:1095C0002BE3F1EB4D26AE3F36B55883C8D7AFA598
+:1095D000DD7844190F704A3787F079D8B0A21EBFE2
+:1095E0001FCEE1F368336C1CD3CCF5D7CF713E8727
+:1095F00016A7302E9FB83CDAFE1C9727F5011BF901
+:1096000089F5FEEA55B4FFE048F0A0BDCFFCAF9865
+:10961000172647E8418F5FF7B307CD6EF87E7327B3
+:10962000E78308DCB89E92740B728EF0DE952EF7FD
+:1096300023FC050857F0DF5B30CE20FDF794A5BE74
+:1096400040B27B30BF6608FF7DB2F0DF4D53AD7F87
+:1096500051FFBD6EFD6FB2B1BC36EB757A4A7E012B
+:109660003F318AAF7E2FF01D12CF0F04BDD4957409
+:10967000123FD47DD44C7C64ABE4F2C4763C5A0EE9
+:1096800032F6B7C22E7888E05091D479A38AFEF0E2
+:109690008F157B2B8B3FEFBB94E6FF7F2DE2A54B15
+:1096A000A57D29F62558F5A500D704010351EF3310
+:1096B00041EFE7F60022902F8DCDE6CBD9BF57EAD8
+:1096C0009785DE5610DF7502D6E7F6965FFB2F18FA
+:1096D0004FDC93EA19054B3FBB77C15FFD0BB43FED
+:1096E000D731C3837ADAD1EA23FAE9772678306E64
+:1096F000E850C1B2057A68E97C39E57ADC177B7AF3
+:10970000C244949B490EEE079E794E5D8FF0D9F8C6
+:10971000D35F4CC7EF75412503EDC6737B7EFC47D5
+:10972000D48BB51D4DE869B0D6A75F223BDC10DCB9
+:10973000C9DFEF4925FBF2F44FB64D47B8B776B60F
+:10974000D2F7333FD949E5433FFDC5817F477BC30E
+:1097500097E2C17A679EDBF69D7F473AAF4EF1E014
+:109760003AEAFD46BE6F2BE95B2FB7BA0E129F4A4D
+:109770007AB919F52EC2A986CB1F49CF1F887DA5BE
+:1097800015E5B63694671F6C4DAE8D154F9C20D6EF
+:109790008B31179263350AC5D3DA806A30AED19621
+:1097A000C8A6E233A92864CE8571162FED9A4E76AD
+:1097B0004FE0C46AACBF605F02DB4AF1370CDE8267
+:1097C000FD4FA4CED838108327C14F86DE3B2E81B3
+:1097D0007DFD0EC807D23B3AFB7F41DBEB7F403972
+:1097E0005A6D0D1F74BA23EFDB449C06EA93DE2901
+:1097F0005D173B1E3AC561137CCBF5664E77559ECF
+:109800009BE484C5334A63970E3BD6BC15C410CB8A
+:10981000A9EDBD11D771D398E593882E30CE87FA84
+:109820002760A3FE1B304E097C56E910F10F3B73F5
+:109830005C07E3571899C3864FC6DE36911CD94D95
+:10984000FD82FD417695FBA5C5BBD11E79C4E4CF51
+:109850009E8CFDB409BDD5C1E70DEDEDB85F0AFDE5
+:10986000D9AF9B48FDF49AD2A97D80B79FDDD1A2E4
+:1098700044E60B949A8F7A0BFB2BB1A19E09D4106E
+:109880007EDC665AD719AC924DEB1EBF6C5C847FB0
+:10989000F5F11D9467B80FBCDA51B6DCE18C3C657C
+:1098A000DC470FCFDDE2FB470EEF7207CE634F467A
+:1098B000945E8967AF1C5A7C9EEBDF174F90BC69A2
+:1098C000443AC6F1FD1F45E9DF95928E5F38417439
+:1098D000BC721FD7BF8DFB8ACD48B7673778D98751
+:1098E0006080368A7DD64794F06A8AF3BC9060C760
+:1098F000F8DD79A16FEA1E3A7112F74747ECCB26E3
+:10990000BFFEFC0B0935D8CF618381E07978D7356C
+:109910003B5B15ED3CB93F007630916A23D8A9DC5A
+:109920000E5EB50DFDB3865AE641FE6FD4D14FE30E
+:10993000BEA3442FD20E2ED8317F15B73F133C095A
+:10994000E8BFCDE2F628037B14EBA7CD0AB69889D1
+:10995000BE8A4B91BE0E2D3EB005F578E32C66C74E
+:10996000FE1F19E67D2197D6A330CC6779C4D43E7B
+:10997000D308ED1FA970DB019200B70EB27BD91896
+:10998000B3D073ABC85E6ECCBACD437CA697072F1D
+:10999000B490DDD5E84EA4F9DCBC4FB987DB2336A3
+:1099A000C6E7AF107DDE1CBC3E88FBCA9F08F849A5
+:1099B000389E37F5DE8EF038FF4B2044F87EF32CCE
+:1099C0004EAF69B33A498EBCF6C26CD2E3922E9385
+:1099D0009FB7903E4F37DA150FE9B505162D5EDBC0
+:1099E0004D5C2FA5093D53F810C7EF2F043FFDC272
+:1099F00061104FB3A073116FB107C6A3DEFD44E041
+:109A00009FC408CA77214F1A5685889FEAF7F2FE4D
+:109A10001C166FF1BD1AFA759473BD28E3FEB80FDA
+:109A20005015435EBC2DE651B063C536B4976F0246
+:109A3000BCA34AC91923E428D005C22DA7D6477470
+:109A40007093E32E8F5A40FB07E427F6B79859AC82
+:109A500038CF31B12E6786AF04E3CDCECC64B2737C
+:109A60009C6A992101DB152B9E5D6EDADF243BAFEA
+:109A7000DF99EDD915C5EFBE1203D43BE54AE67870
+:109A80000EFED6387F1CF2A15BFAE95176DF607FCB
+:109A90009BDB8D73DB03E3D10F91FB17120EC19695
+:109AA000C41AADFC7C5FC02178358FE7837D6FA33E
+:109AB000F8B51DC641BF7ED7F53FE17E7D2BD57B36
+:109AC000CDC1E31915B03EB4DB9C85BE755C9F2605
+:109AD0007B62C163B543DAE5B717A35FD9586DF36D
+:109AE00020BF6D7F515941F48CC141F4B7FDAB08E3
+:109AF0000F0CF080FCC0FCDC2F6D6CF60563D37B93
+:109B000015F15F23F29F42F44EF176A0F720A7777C
+:109B1000AEFFA4DF8FF2B12AC67EA8942F8DE6F0A7
+:109B200068A463C90F8DD3C3A3116E439527E74D76
+:109B3000C0FFC83F0007E41FC92FC9FB399F6C6DE8
+:109B40007197E1F7AD15CCDEAAD1477A7F09E78995
+:109B50007EA794EB590E5FBA13E30086D016CCA310
+:109B60009072B871FF83A363E5B949396C3572F916
+:109B7000660D26055B35F4857B7BC913E949793B86
+:109B800049EB63C745463979BC6EA879112ED4E5F7
+:109B9000286F762505515EC93891BEDF4CA7121596
+:109BA0008F917E0BEE2F60FD3227B7434A9C9C2E8F
+:109BB0006F72CA786C30CAEF711BFC27309F289EE9
+:109BC000FE92EDFE52712B398ED4A37AFCCBFD119F
+:109BD0005C4F5551FC7AED07B97CD2D3E37C617FB1
+:109BE000A5E25AE17F3F17FB5983F1CBFB6135C6F4
+:109BF000A8FCB73643576DACF8D7C10D222F6ABB0E
+:109C00007148F9753F17F5BF27F2BFD85263543E2C
+:109C100095CDE36EC1F8E9841E77B14AE3F2385678
+:109C2000F274F629EAE194A9ED63304FC9E98BDEBD
+:109C30001FC9AC498CDA7FC8F6A74795736B73A22E
+:109C4000EA0F6B1E11F57DF8FAB151DF0B0213A379
+:109C5000CA856DD745D51FD53E33AA7CD5A33745D8
+:109C6000D5BF3A383FAABCB5A5B306F172CD9E5B0D
+:109C7000A3DA4D30860DC5F07E5CE78AE83C311DE5
+:109C80003C67FE518D49873F7016103E27EC8B864E
+:109C900047EAD46878605A1CF697CA447F897FF0F7
+:109CA0005C2E8F3595193F0BCBF60583E98159ED75
+:109CB00025DAFC8308FD04A3F2DF661A55DD3C02B9
+:109CC0007F12FDC59BA7DC5F8BBB8E3870DB27E462
+:109CD00084848B492C2B757ACD65E162BA125C586D
+:109CE000D83314B8E8F7F706E2CDBAFE3626355277
+:109CF0003EF0DB58D0D8C761C147B2BC2890CAF546
+:109D0000906FC115EC681E07F65BF8FEA4FEFB45DC
+:109D100021D79C300782CF10F9FA7D8187E3C8D71D
+:109D2000E870EAF97AFDA78733517E5732F29BED4E
+:109D3000CD2D9FA2DEBAC31862C530EFED623D8F14
+:109D400008B9F0E8063BF5F398D87F7C7C839BDE6E
+:109D5000EFD830869EC10D1E7ABF6BC3547A7680D1
+:109D60003D87CF273754D273CF061FD57B6A430D6B
+:109D70003DF76EF0F3790DC2172B253BC7971133D2
+:109D80005EBA3CA00E094F4CCD8BA92FE3F6A32E53
+:109D9000BD6C1EF9FAE34BE6BCA2E11B8B2BD9414B
+:109DA000FB9953D814DCCFBC52FB8B1B6AE6BC3248
+:109DB0006AE87C24E9897D9931DA17237EE417F972
+:109DC000936F3B2F6E0DD8E2C32B4267B1E1546D08
+:109DD0003D9F83CEFA78B41934ED8FE9F8B8DA9F55
+:109DE0001AD36E287771FAACB1F0FDF7253AFEEE82
+:109DF00010DF3B5CDC2E7C378E9CB9CE6510FC1FDF
+:109E000030D17EE020BEFBDE0DB1E0DBED7247F12C
+:109E1000F112BF0EAFBA7EDE35B50FF3C4E0B32B3F
+:109E2000F523D7A76FB7C9C5E5D6AEFFA3FCF9EEFA
+:109E30009DC9E43F20DC9C9AF5BF7B67524DACB8CE
+:109E4000CC5E17DF1705EB9C15A493A91F30A3ADBB
+:109E50003886B9F93EEF483BC687641E407C7A35A8
+:109E6000521C8960A80E862BE0C36D2E84FE8D03E4
+:109E7000E3848C388EC710D16F9853C334E73CD439
+:109E8000C1F400ED0366CADF09E750DEE357A427FB
+:109E9000A63E3EEA72FB7483DA7F4539B3FD6B96CA
+:109EA0003392CFD9970F8F8AA5276B50CE5C07646A
+:109EB000E82AFE6EA0E8CAFD7E55F8D5A861DAB79B
+:109EC0001E32FCF6398614975A6F4D198FC6D5C5C8
+:109ED00004FE0CCC64FC3CD6FB0941B4F343629E07
+:109EE000E0F84FE07E75F3147CF664F90EB9A0FD3E
+:109EF0000A33F713F35CDE975D502F51EC039B336D
+:109F0000CD5BF0C9EC7C1DE3311F14BADA6270E757
+:109F1000E33A3E523C57A39F6237043DF84C61A19F
+:109F2000713CEF2EE847FF2CE39A4437FAB789A338
+:109F300019EBA578B82701E366E6A4F05B23D19F6F
+:109F40007DD148F1A1F198CF06E5F17F9F1B0C90E0
+:109F50003FE726F99021E0B615ED70683F8FF9DFF5
+:109F6000C5F99EB65B030698D7C3951313301F2A15
+:109F7000B4470D98F1BC42EFB9BFBB19D63DA1570C
+:109F8000A538F30436E9F59128577A4DB4DF5B67BD
+:109F9000640F21DFC483E7D96FC6CEEF2ACAE4720B
+:109FA0004FE66DE9BF2789EF67E3E411FF87D00B28
+:109FB000323FC624F3639CDECBE6C79874F93126A2
+:109FC000A38FE13EB069203F6629A3FC18E8479BB8
+:109FD0001F737666EC79A8997C1EA62F92E2F49BFB
+:109FE00042EFCF8EB8FC3A4D5F2444E55947DADBA7
+:109FF000E87DBCFC9C3C09A738F9495903F3CB66C2
+:10A00000810C6D3B4EBF9171F2E8BB4997E713F9A4
+:10A01000CEF37B36A5713A399865772C87AE97B326
+:10A02000B009E9F40E9BC384F1231FF374D1B91D69
+:10A03000A3A93F2CF96E04D6337E8076B601242D79
+:10A04000DAD977AC377D10D6C8A92A6F7499617DAB
+:10A050008DDC5D9FC568BE8963C7505EDF05E64E37
+:10A06000B55F466E2EB5AA56A366BDC7E3D80D7E72
+:10A07000019FE3D9B1E13727D31095A734B87D4AC2
+:10A08000D479B47BED979797085F7F86B67F3D1EA6
+:10A090001CF4FD4A7076B672FEEE2F5378FEFE5F1A
+:10A0A0001CDE69229F8D9F0B30E9F2D0D767B9394A
+:10A0B0005D0DCC9BE7A1BF6CF7ADC8A476EED1DAFD
+:10A0C0007300DD466FD244781E1772470F973D022A
+:10A0D000CEFA75778B7CFA4495357769E0AF5FEF00
+:10A0E000E3028FB2FE2613DFBF823F9F15F0B28CD2
+:10A0F0007139DB9A3942E485A719511E2EE55DB00E
+:10A1000065F657693F49C27910FC04DCF570F431FB
+:10A11000F7ED98B77D25782E3F9A6846B97FBBB595
+:10A12000FF30FAA6E15EC33B23E179C236F2640751
+:10A13000C37DB731CF1F62180FF1F0FC09368BECED
+:10A140001C2590AB5EBA66E876CE9614FF18E48BB9
+:10A150008F44BEB5D4435B72CE8CC6BCF9D4F4B286
+:10A160009A2C27C5DBBD19483FBFB670FA79147A1F
+:10A170008272D381AB77A27E69C9F22FCA9A1CC9B9
+:10A18000DF63DEFED1987FF055E1037F26A49F2B8D
+:10A19000C1675B26E37C98129B3E8EC4A10F3D5F96
+:10A1A000D0B9B292AF8F2F243CE57E859CDFA22CE4
+:10A1B0004E7FF229E1A6CF1B5A946510F5B8DC68F2
+:10A1C000C9F2119CFB867D7A3201E67E5C97E73509
+:10A1D00020BF86B87E09EFAF4BFE1E4F8C3DBFFE01
+:10A1E0004CBEAEFFA9F92D91F31B1F7B7EA6ACA13F
+:10A1F000CDCFC7FADF4FFB1AF417E07909E2996D6A
+:10A20000EA27B9783C3DF63C470E799E7ED3D7A12C
+:10A2100067257DB3C0F25ADAA7CF4A8CB94FBF0881
+:10A22000FC26F47BF4FBF5725F1EE407ADB7DADAC7
+:10A230007F7B06E27D9658B78B85D2701FF38085B1
+:10A24000E2FEFAF55F23D60FF02A4639C5E6F6534B
+:10A25000FCE2F8E8D872A1388BF3C540FD363E4EDB
+:10A26000BC7305D70AFEBCD2B90256E2A7B85F9903
+:10A27000D51652010FF7087C9873D77AD02E2CCBC5
+:10A280007AE318AE13E07F6E009E9A3CBE331B8EBD
+:10A29000D8479AE2CBED3AF5D9D2E618EB99E7F434
+:10A2A000CFC5750CD4DBF3BA7DA4065FE358D8C0E4
+:10A2B000CF45F71BA2FCE14CF695FC61AF95F34B43
+:10A2C0006ABA8FF401EA07D43B5BF65F5B8CC84443
+:10A2D000FB02F378FA9313498EB6E65C37C6AD817C
+:10A2E000676396B45BD538F6E29F97F71FB19794F2
+:10A2F00028BB35D2BF91DE4BFC94D9FE5F4C7CCCA1
+:10A30000737AEF453A1C9DEE5D874F3DFC020F4C82
+:10A310004B23FF18E13723D2DF00FEE3E0F9C74EFD
+:10A32000EF77B0BFDBC4F91945E6EF0DC4298CF611
+:10A3300093D608BC878A97EFE13FC03FDD91E5DD0A
+:10A340008A78315B043F321B9D0B97F60AD3D935CF
+:10A350006C2ACF275D96F5C61F30CEB32585B3ECAA
+:10A3600096EF24505EDD1D8ADD8CEB06FBE3BD1FFE
+:10A37000417D3F0BBDF76DDAC7927646927A296927
+:10A38000E8F3947EF295F2A80FA11D06F39969B047
+:10A39000D1BEE621209B6C901B33CDFC59361BA807
+:10A3A0000AFA9BA9E6F584615E9FB373E93740EB37
+:10A3B00044114F5C77747202D2E54CA3E98C566E5F
+:10A3C000E9E31C5D59D1718ECFD9DCEFD3DEEF18F4
+:10A3D000EEEF3F3C7766A636CE3210E710EB581012
+:10A3E00058CEE5A94ECE497966B0F2FB439897B9AD
+:10A3F000ED2E8A1771B883736D84F20DB28CCE097D
+:10A4000094A7092429D81ED67D8378B215FE2C94F2
+:10A410003398BE83E381D79785CFD66B3D6E7CCED4
+:10A42000507C463E8F20CF3764CD7958DF600DAB2E
+:10A43000FC5C1ECCC085EDE578BC9C2CCA9BAA2F89
+:10A44000DC7EA77B70FC82D992C9DE358B799DB604
+:10A45000DB0206786FB1854E535EAA78EAE31C17DB
+:10A460000D8100E6657F4B0DD27C935828D48B710B
+:10A47000092B80C040F1831348A7E0D534E23C1398
+:10A48000EC1742DF6698DFE855B09CA1D3474EDB5E
+:10A490003ACA7776FA8C3A3DE457906F326BF4EF14
+:10A4A000A3F593951DA773404AC8977529E3CA7110
+:10A4B0001A7D7CC63493A3B87F0DB77BDF49E4EDEA
+:10A4C000245D28D95CFF34A69B19E5B9B8AC56B415
+:10A4D000DBCF279FC2A396A837DA506F584D5E8214
+:10A4E00087D41F0DDD7733C44FE3BE2A86F4FA4FBD
+:10A4F0000ADFF70C2C53283F41DED75053C4DE84CB
+:10A50000966C59F6086AB7F0887F593D94ABDF60C6
+:10A51000E34250AF7886AF02EF65691DC73C1BA1CF
+:10A52000DC9AE07FE697B89EA32AF5D324CEC33207
+:10A5300066AFDB0BFDEFBC7598672B2EA9BC7F0BBC
+:10A54000E6FFF43FC8EC982F32884EBF84F501FE39
+:10A550007F82659877D32AFF13F741FDEC37988700
+:10A56000EA88EFE88B20DE14410FF87E06BC6F12FC
+:10A570007453D8A3F07D7B8785F226D8B14CE2973F
+:10A5800085563E4E534FD9BCC930AFC2DE4944C692
+:10A5900023A13EE635616601CFAB63E427EBEB8F89
+:10A5A000C4FA6E8A52F17C9A1C33DD7BC4849C9B76
+:10A5B000A2E3B7EB23F44FDF8B45B949E8A3283E6C
+:10A5C000C17EC02FF796F26D7C6AE7E0FCE061F295
+:10A5D0008FF3ED752CF287FD9647C621F93B4B7C36
+:10A5E0003BBC640EE5734F31860E225F5F2F9EC524
+:10A5F000E2897C6D05382E36361F76C27AD2D63384
+:10A600004F0B8EB2D4DD8AFD95309F8A702EB53FF8
+:10A61000D88AF3BB76E9D10CA4AFEDD985447FD3BA
+:10A62000AC9EC2042091D6A91E8F1D5ED52C550864
+:10A630002E0B6BAC41CC5B5B38704F8FBF6011F061
+:10A64000CD62BF22CECFFB0B966AE2B0329F6F91F4
+:10A6500005FCE718727A7B36B78764FB2671DE4407
+:10A660007E6FCFB6D1F76F66DFB82C9BF22A789E4B
+:10A6700033F0BD3F7B72448EC0B89487B280794D71
+:10A68000B8AE05826F25DF2FF4DE4B76EB425FB468
+:10A69000FDF94F0AC777608942F6E0E29ACBDBA763
+:10A6A0004DD9729F37CF7E3229F25ED29594DBF37B
+:10A6B000518FA3BCAD04BDADB18F977EEBCB346A97
+:10A6C00097F964C3A5E191F32D4DBAF32D8DE27C8A
+:10A6D0004BD3BE16930BE95D9C6F69EA39B1459B7C
+:10A6E000D727E134F87C4B3FE5332E32070FE2B930
+:10A6F0009F456B618D50FF65711EE2153C0F313136
+:10A700004247C9B7268478BE9C97F2F6F2EC491E00
+:10A71000CC3369334CA43CA1B694648F362F676B5D
+:10A720004B7305D693F941F23CCBA238FBC08F673F
+:10A73000733BF91185E76905965809DE4E951DD3DF
+:10A740009ECF7716FA283F6E59B69BF0FE88882375
+:10A75000603EE9247806C11CE3F8E2EDF5F201FA67
+:10A76000DB84FD95177A282FA63C95E79739337C33
+:10A77000C5F71445FAADEEE1F978D5BE4F5FE5793E
+:10A78000B55525084FBD3C97F4A597EB407F9D48F4
+:10A790008F170D5CEF44E4BB6FC99DD05FDF9B66F4
+:10A7A000CA9B63F77B1513B47BEE75BB07CFD16DE6
+:10A7B0002AF35555D077239DF373D5B09005BE97F6
+:10A7C000BC61DE85F97AB5ACDD8CFDD5EAF4D65AEC
+:10A7D000DB2B66E4CFB51DA6083D32CC33F414A2C2
+:10A7E000A0ABDF3B28EE41F247CA253D1DB391D116
+:10A7F000F2A758CA5B900B5C5F2DE57A8E3DA9608D
+:10A80000FCA72FF9942AFC67927793A590D2C9F9F7
+:10A81000C93DAF91BD321DE403FA670A96C7537D67
+:10A820002A83FC1C8379A3D7B344A2AF41768298D4
+:10A8300057C9C0BCB93D24E562D9546E6A4ABCC050
+:10A840003844CF729F6E32DEBF03CFEBC5B8DF3224
+:10A85000788B420AE289050D856847F8C9DED1DBAD
+:10A860003FA5D6E6242BAC6F2A6B27B938E5F02B31
+:10A87000242701CF9FA09CF9359378F65851CE54E8
+:10A8800060C29F8ACF683CCDB66D37229C6667E96F
+:10A89000F11130225CE7B807E189CE0778E3E0C91F
+:10A8A0002BE5088B962305EC4B7E1EF9C157EF4331
+:10A8B000BFF74A76C821A7DF9C43F233DA1E899797
+:10A8C0004F979A63137EEAD0F2E9FA4CDC4FB88EC8
+:10A8D0008557EF5506D3C5F9C3EBD52C0DFD48BA06
+:10A8E000DC2FF2EB959744BE6E4932E9B9885EE4FD
+:10A8F000F82F15A5EB90AE34F8BF615F4248057A9A
+:10A900002B16EDAF437A9818D18B2183CD6D8671CC
+:10A91000B7289E363506DE5DE96ED27F930C5E95D4
+:10A92000EC29E6C9403C03DE8B105E53AD9DAD467D
+:10A9300098E749B3E747E8AF943137E1BD4CA75FEB
+:10A94000CA6DD546E4CF72AB1EBF5EC27B857DD09B
+:10A950007BC39F82F7E18877A93F86607F02DE2B69
+:10A960007262EC13C6C3FB2D7F22DEF5F8967CDF06
+:10A9700095602FB7615CB796E7114F7A73642B9699
+:10A980005D0D0574BEA52BCDF3327D6FE6DF4B7AEE
+:10A99000BD2ADE9B58B80EBE43B9ABC0578EE5A6A4
+:10A9A000F50AC9CBC96FFB5BB13CF27EFEBD786393
+:10A9B000F3CB78FF585380B7DF7F7A0BDD2311DCB0
+:10A9C00022DA97B59763B9A98DB7FF38D91A40FF36
+:10A9D000BAF458B015DF5FFD109F87B4EB66083AF4
+:10A9E000EB529E7D99DAB5F37677BD6A4DE4C96E78
+:10A9F000DC4E9B2ED639E371BE4EC7873755BA81E0
+:10AA00000EEFEC0F98900E4E1AEA4B495EC6F1B766
+:10AA1000CA94F63C7CCE06B9C008DF409F23789EDE
+:10AA2000E92E18626B0EB78B647E26E6895769F0B3
+:10AA3000B53587FB09B29E2B9DF17CE2C792C96EAA
+:10AA400095F9A3A11F3205E300B846D2AF71F249D0
+:10AA500067173693BE9C3D5CE691868D2B60DCE2E9
+:10AA60004BFF7A632CFF7A9B18F794C87B97EF6BA8
+:10AA7000830506F43FBA9078E87EB5796FA25DD27F
+:10AA800085FBC19AFB41BA0A78F9C78FDDFCB76D27
+:10AA9000E0ACDE6568360650E8E72B74DFC92DBDF3
+:10AAA0002C949A3278FEB38D2CC4F31DF8FC57B762
+:10AAB0009A776DD5D8E90BA5D898368AF448B5C0F1
+:10AAC0009394170B05BE80BFF7207F2FB236935D9E
+:10AAD000B844C8F7352C48718A353AFEAEB37DF6D6
+:10AAE000BEC180F1B0683E6E80E970BDD0BFE35D4D
+:10AAF000807FEDA3C976D4F30D9DD1F56A1F7DF358
+:10AB000018B7AFA2F9BC56F279309ACFF1A649E254
+:10AB1000F31F8EA5FD17799E2FC1DAFF7E8045D6E3
+:10AB20003BA0DF75FC9780E7FBC6A0DF62E079857C
+:10AB3000A22CC7BDD0CEF57000F4B0F07348D45E3F
+:10AB4000383E2788F4502CF857F271B1D0E783F4DF
+:10AB500075A5DE8FD94EFC31499424DCA57E867E16
+:10AB6000483FCBF382A097DFF4927F0FFE27CE738E
+:10AB70006C34BF6C55403E1744FC15C0DB3F23DEF0
+:10AB8000401E5B799CA29DA13C8B6BF7DBD6C5B4C4
+:10AB9000FBC18FA07D80C1F67E28CA8ED7E32B9E95
+:10ABA0005D3F80AF04B09792D08F67242FF7E17399
+:10ABB00008F91C20A7FF3D967E361FE2F5FA77269E
+:10ABC00050BC40C6C725BFF5E572BBFA57595E9623
+:10ABD0008BFB57A2FFE377CFA67DEACF9897F6A924
+:10ABE00031CF2837469E04EE536FD2C4498FA7C594
+:10ABF0008E5B27E772BFE71BB97C5D794E6F4A2EEB
+:10AC00003C4F99795CFC54A278A6F07D85EC81FAE2
+:10AC10005C4E4C10E55322FFFA547A743C5DD62BFF
+:10AC200016F53EDA60B56ED2C815F70F2DCDA8AF78
+:10AC30009C85225F7D1DA7D7BE17D2766AEF699BE0
+:10AC4000965BF60D9C97B3D06BCEC638CB0B5C2FC2
+:10AC5000341AC366CC2BB9C1E1BF0AE1D4E866DE81
+:10AC600067B11F77D8BC00E0DC27F6E7FB4CDCDFE0
+:10AC7000E84BE04F39AF69B955DFC0767D7787493A
+:10AC80003E0C94ABC2C4FFD3727D346EDF42F95DDB
+:10AC900094FF969799F00FCB045F509C37465C77F2
+:10ACA000701C37FADE992673EC7D6596971C159F0C
+:10ACB0005DD6C3E386B75BD9965CF87E474F26F92D
+:10ACC0000FB52981D1768AE3FD7971D7BE61BDB414
+:10ACD000AEAD65FDF98F95D03E2EC57D1A7A5E2307
+:10ACE00039D720F9A43B9A4F96E40E6DFF431F1706
+:10ACF0001F02FFACC88DC13FCFA37E3245E07F8FDE
+:10AD0000C877AA50EBCB312E746115A373AFF7BC93
+:10AD1000AE123DDDF38C42F74048FBAC41C037DE5C
+:10AD20007AF0DC805B233FF0DC805BE39FE1B901DC
+:10AD30006D19CF0D68EBE3B901ED773C37A0FD8EBF
+:10AD4000E706B4E562B6B215E36C4D6DCC1E74F344
+:10AD50007304DAF6788E405BC67304DAF6788E40B8
+:10AD60005BBEC0381C2F3CAE529C1ECF1368DBDF8D
+:10AD7000F5FAA42CA49BEE049E3FC602DEDE2280E0
+:10AD8000CB2A01173C67A0EDEF6CCA8D4718D0DDC8
+:10AD9000AADED573F13961DFDAA8FEEAD47AA243DC
+:10ADA000D6CEE56E33FC47F2532D52711E9FEF5302
+:10ADB000584601DE1BAED39F3DDBB6A0E859138C8D
+:10ADC0007E5FC734F1DA82C171F98EDC64C7499EB7
+:10ADD0006B9CA38DD344E8C0E609E1FADF563DB190
+:10ADE000E8A0985D954AF199232AC61ED8C7ACF908
+:10ADF00091698A267EAF8387252B9A1E12DCD1F4B7
+:10AE00009034269A1E923DD1F4903A359A1ED2BCC7
+:10AE1000632F0BDF8CCA68FAD0C3772AFC87F09DBA
+:10AE2000883742625C09D68971DEBF147C7B75F07D
+:10AE3000FD9C4D2BB7B9E973B5B534629F941C697D
+:10AE4000A64D5A7DDC53C251DA09327E3999713FE1
+:10AE5000DD8AE72C0BD10EE0FE1BEA7F94AB27CDF9
+:10AE6000DC6F430A42397927F3933CBA53A7FFEFCB
+:10AE7000B26D37A3FE1FB45EB0B8F0BE40FD7AD10C
+:10AE80008E629A78925EFF2B3D4A28793C2EB74716
+:10AE9000CA65FF253276BCCA50E4C5719BF7739C26
+:10AEA0003F3A7ED6D2A8786F4C7B4ECE43C2458EB9
+:10AEB0006F61CD6A16D2F318BDFD15ED2F4BFF9AC9
+:10AEC0003AD5C4A3A57F2CFD133D9CD5E10564773D
+:10AED0004DB24BBFB8F7367C2FFD61BD1F7AA57D03
+:10AEE000A9050125FCA382883D7983782E10F122E3
+:10AEF00058D687BF87C6D314F7301C6FFEFEAB9CB5
+:10AF0000482F5B9466A69BDFB117A11FD5D09FC1C8
+:10AF1000E32FFEA8FDAAD79430CD7B11F36EC66750
+:10AF2000A388A73576BF46FBA88DDD3C5EC0F645FD
+:10AF3000E3456FEFAF659DE60265B0BD5FCF7AA9CF
+:10AF40003FBD7D3F884EAEA0C777E4C97B3B78BE4E
+:10AF5000001372A956C02B9E5F6044005F1BB9B7F7
+:10AF600013F8A12C6F72247FD6950E7E8C8A7918E7
+:10AF70006E73AC3C298697AA804DBAD2564D726248
+:10AF800065DBA0B88499F8A9FDF2EB9376C05FE584
+:10AF90003182FB883C37DF874A9C7BC48B9F4B7A8E
+:10AFA000F3B5E73E9ACCFCBC216B8E3E97BF3ACFFF
+:10AFB00020CF4DA94359FF60B8FE69F9F832FF0070
+:10AFC000E0B7460B3FB98F20D7F3C9E4DE27317EC7
+:10AFD000A826CFB2A25F9B9AEE6FCA73E2BD0CE1C6
+:10AFE000930ACA339B9BF243CEEF3BFD0EFAEF72FE
+:10AFF0007D8C851FC17B6D6BF7A9E40FD6EE7B9925
+:10B00000ECA2F8FE5EFBC0FD09627FE37E1C473FB9
+:10B010002F99CF5CA116A5863576FABC3C1E0F1879
+:10B0200035DCB711DB95FC2E2F05E76B1AD149F7FC
+:10B0300061F5DFC7ED6087CA6621FC40EF71BD6F27
+:10B0400033D2BE832329A0A6A01DB79CF1FBE73C09
+:10B05000CD1E2415755811C5695DF7A93EB4BFDF33
+:10B060005BB7320DCF29BB9257A515C2738685DF1A
+:10B0700047E3520C3E7EDE74451ADEFFB1CCC2F7C8
+:10B08000E50BBE99142A047E7BC9CCEF197524F90F
+:10B09000E9DE82FE3495E67366032C6D14EE7B7C4C
+:10B0A0003609EF1BC8F9D23611E7932DEEB3A8CFBE
+:10B0B000E3E7B7CF3E737112FAABEA251B9D6B979E
+:10B0C000F4E7288CEDAFCC17F06874F27CF7F3C28C
+:10B0D0007E3C2EF65B65FEFB3AB10F787CF4C0BD7A
+:10B0E000604ECC0B694CF0A62EC678C451156FCCBF
+:10B0F000609FD9BDA9696437F33CF675C27E382FCD
+:10B10000F23DD7CD999989FE45BC3CE997F2B8DD6F
+:10B11000FB75DD5329F34EE3C221CDC88C13E8BE85
+:10B1200025DFE5EABDF84735263C4F8AEFF1F2E529
+:10B13000DFCBE37E9BCC876FC47C7878B5EE85B29D
+:10B140004C76993CE946BC875C935F837E1AAEAF30
+:10B1500011EF21A7FB49CFD1FD1CD80FDE1776A533
+:10B16000FB22E70B3837621E7986F6BD9BBF1FE8CE
+:10B17000DF41DF9F12707BEA88A172578C79260E1F
+:10B18000E3EB1EEB34FA705FF29A10BFEF335E3DD3
+:10B19000797E3BDEBCBA67866FC779637E66ACF1A9
+:10B1A000BE147094F3ED4E0FAFF6F1FDBCD155C94E
+:10B1B0009AB2BD3F7FBE46BE4E11F8E9BE299C4FF4
+:10B1C000F700CCE1FE6B3C3C971A9B1584C31769D2
+:10B1D000FE5B50FEC97B8AF11E639EE711B82CBE50
+:10B1E000237056A3CE1D0C86B399BECBFEA4DC39CA
+:10B1F000FDA84A72E7F45B821F99D7A694A2BEE22B
+:10B200007C759AF1B8EEE976FEBB1F2BFC607B8261
+:10B21000FC58DE5137177FB763F5EE495B50FCE30E
+:10B22000FBFB41FE2CCF626C3A3C576C8ADE1FFB65
+:10B230009C3D447A6ED5437A7DE633A39C5DBD3D4B
+:10B24000BA7E2D7BE853B40F6A7576AF4BE85DBDCF
+:10B25000FDEB1926F27E4A59E95739DFF428F34EFF
+:10B260001946FA9FEFB74D16FBE9FAFA4FB8399C29
+:10B27000EFD9FDAF66FC29A078FD9E01793112FA65
+:10B280003DB7C14ECF6F0CF3CEC4FE970DF3570CF4
+:10B29000C338C4510EE70BF51756535CBA86DB0171
+:10B2A00016BC5C05FE69B9CD4A7EF40378BF18C0B0
+:10B2B000D962E1F685B4AB54F55E3505BE5FFB2F70
+:10B2C000ABD2707D8EA76757A2FFE17C3AC98BF89D
+:10B2D000D85AE62D46F9BDB5CA46FBC43B0DFCFE67
+:10B2E00041AB85EFCF059FBAF610868347766E9BFC
+:10B2F000897E86BDE76008E3126D06BEFFDA369DE3
+:10B3000089FBABF9784D3D555D38AFFC6A90F7D0BD
+:10B31000DFD6026FB15DD33F13F652A3C045DFAF56
+:10B32000AFFA3EDE77F5A32364AEC23A4750FC6B1A
+:10B330002CE37423F34BE8373134F1A273A07F98E8
+:10B34000E6DCF3D84E25644AA17BF5288E5DBF313B
+:10B35000E4BA0DF5E7CFF87EAD9C9FE3A5EC991814
+:10B36000EF97FAF436CC6FC338B0B07B9730F9C79B
+:10B37000F70B6A045D2F11F6EE6D491CCE2B9887F2
+:10B38000CE5DDD6A6529185FBEADBC7332DD7B5DC5
+:10B39000674A437B45C6BDE3E13D5E7CA6F1C964D7
+:10B3A0007E4F8ED23F1A3B398331909248BEBDBE4C
+:10B3B0009F8787097E1E2DECB491CC8BFB2C8D07CB
+:10B3C000AEA27C7C4B22DF5703F96645BC1E467D4E
+:10B3D0000EEB5EF3624288EF1B07C57D382C40FB05
+:10B3E000310732695FC151E8A57DF7F3A6703EC908
+:10B3F00003905F0AE8CEBDC37A6FC1DF6169CC01FB
+:10B400003B0ACAEF3EF1DE2D46A0C7C611E1D57852
+:10B410004FB8B2E3DF78796CF82496937628F3A8D6
+:10B420003C31BC5A85F2E81DA9F3A83D3A5040587A
+:10B430009376B8E6E139E233227EC93C61BA1FA8AF
+:10B4400071FF55066D7C70783EB737CF24F07A6770
+:10B450000AD81DF311DE63C2A3B5BF97A0E61B98FF
+:10B46000F65E65B94ED98E65C5EEFF45A107D68853
+:10B470007B7D6624B1B604BE5F1140FBEA959EABAE
+:10B48000082EC161E9025E61BAAF51F6A33FD72F22
+:10B49000C75D8B7A1BE5BA29FA1CD191615C5FC04C
+:10B4A000389B689C226F31DEC7D3383FAF18F10656
+:10B4B000F8320A7C19B91FB893CF0FFA4D1B4F7A97
+:10B4C0006412E689BDF225D42F88CC5B4F1F6F0B29
+:10B4D000FA58D3CAF799FAD30A898E662471FB8F7A
+:10B4E0009500FC408E8D16F01D9E9FC6E13780872B
+:10B4F0004C85FA6F15F0CBE3F5BFEA7A4F7E4DEB42
+:10B50000D5E0C98B79C7AFECBB9AF024D7C3D8B6C6
+:10B51000A87ECEB4E8DA4DE579298DE985D4EE012F
+:10B5200071BFBEBCAF18DB1540BB19E5FD93901F82
+:10B53000E47D6D2C309D9CF57A212D06EE5FEBE4C9
+:10B54000F9296CA497DF43347F6E89589F5DACCF97
+:10B55000AEBD8F6E800FDFEECFAFD6DC472DDF0F95
+:10B56000C07DA0BFA289A2BF287E8ED51FF2453C18
+:10B570007C64E573BAF88BE143CE5307CF0138EB17
+:10B58000E627E1897C4CED8AA2F949CE3369008F28
+:10B590003A7E2EF813C713F9FD0D7F25F221DDD178
+:10B5A000F4DCD05D60C0FD53D9AEADB3C587725E2B
+:10B5B000C6BB2DDD5501D47F4D3D6594B7D9F0ABA9
+:10B5C000679E0F40FBB5BFF8410A26D39E36B6BB37
+:10B5D000D0CEADDFBD39C58BFB25C6400ACACFD35F
+:10B5E00041B532D639C0C67C45FAD16447350A7DAB
+:10B5F00073E6A9EFDE82F0F8B7DD263BEAD1A63D7F
+:10B60000969085E2206BC88E82F2095E7EE053F44C
+:10B610004B9BF645DB496B7FFA03979BE829906BC0
+:10B62000C0332E2C94CBE0D9D861F2841C3C9E0808
+:10B63000C3B026D6BF05E7A76F8FF3F802F0DED4BC
+:10B64000A92EC7F3BCFAEF2049C80E6BEAFE2ED92B
+:10B650005D4DDA3803E0A1368EDD75477E74BEB5E8
+:10B66000840B0B3AC9AE69FDD90FC79FB0E13D9A73
+:10B67000BF49518AB4FA7223C1E942E7CA1FEF7782
+:10B68000C7D7ABE7D12EB068DB71BCBAF729B427B6
+:10B69000C17AF8B3DE144A413FBF7EA7C9039A9727
+:10B6A000D53FF39327713F84BD6BA17B0FEA9E3991
+:10B6B000FCCE7550AEEB3239E6F2E9DB1457043FAD
+:10B6C0004D6E6E9F487CAC7DEE30DD2F88EFD1AEA5
+:10B6D0009578A9EB3A6866E306C3AFBCF3A0F8BD62
+:10B6E000051D7E3A4FDC48F778FEECA219E9FAF422
+:10B6F000018565160C6E5FBBF3700AD21FC209FD8F
+:10B700004B89A701BC0DC257E896FD25548FE21A5C
+:10B71000F1F0E6CD677C9FE757CFFC1C7FFFAFF6CB
+:10B720009F2C1E5C7FEDCFEF4DC1757C6C6CE6F4F9
+:10B73000FDC4669717C6AD35055C767AF2F7B53B62
+:10B74000EE23BABBEBE87D2EFE3B1ADE6CC3545AE7
+:10B750006736AEEFCEC717D2FA56333FD15DED1341
+:10B760003C3EF1B9F81D063D3E4F0AFEF87897853C
+:10B770002E2DFA1813D1318FF02D55E4F9DECDB40A
+:10B78000F75780C54DE5CF457CE0C5017B805999D1
+:10B79000262EDBD4F1402FE2E7CC306F26EEAB0152
+:10B7A0001C02025E0ADEABAB1EADC8E4F8616EA3FC
+:10B7B0008C2B83FD5D8EEFB17EAFC99B303EAA9D81
+:10B7C000D8AFE7E3CBF804CC3B11F7FD3E76C53E9E
+:10B7D000B7E5182EF99FF5322D7DC5E3F78E078961
+:10B7E000AE3E7B9BF34D63B0AA92BEF79A4278A41B
+:10B7F000B83178B05A21796089BA6F69802E3A4C95
+:10B80000829FA3BFC33C8D8A16BE07785EEDEAED2A
+:10B8100096A87B102274638EBC2F88F0A7F4A3EE49
+:10B8200012FCAF5FAF5E1E9CD0C903F6B87348F739
+:10B83000C9D49B824F3E86FC0BFC8A7E66FD332674
+:10B84000F2F3CFEE7DF99D5B81CECF764ABE8D9629
+:10B85000AB7ABEAD7D76328BC5B7676D1E16936F22
+:10B86000E17D4CBEB545F669DCECEB93AB77C59159
+:10B87000AB89C3C57ECEC03996A254CC753FF35474
+:10B88000DD708A0BE8E02AFD59BDBCECC877C7948F
+:10B89000970CAF9ED2C051C24FD2E3DAA71B689C6F
+:10B8A00001BA957429E976802E07E55746C151FF04
+:10B8B000BD57C8A38173431BC14F413BF6D72AFD37
+:10B8C000FE491FCC650BC0BD6F6F01ED836E167610
+:10B8D0007E9FBD3F05E37A9B855FD18FF1C4D4C8BD
+:10B8E000FBFE049137E0EB4F49D3D845277AD414B7
+:10B8F000B4E3C2C1D8BF232BEFA70CC7F99D597978
+:10B900007EA942B5E5AFC7386D3BDF9F5CD5B23845
+:10B9100005E3197D3D85F43B4277BE0EFE2ECCB784
+:10B920004FC635035E637669E45ED3532C40FB95C6
+:10B930002B7BEA68BF501F07596DAB4EC5FD407D9C
+:10B940001CE42ECC83C23CE4C7A3DFAFC5F808E2F9
+:10B9500049474F7EA4A7ECC1F4543D5CF065312B00
+:10B960008EDA7F1572AD422DFA3EDA277DE0B7639D
+:10B970003C88A945BF457DFA39FAF1C8000127D1B5
+:10B98000699DFF94CCB322BA9674A7F7DFF5CF7305
+:10B99000BF7CAF14CF03D53FFFFBF13F82E7B9E790
+:10B9A000DF1DFD22967FF58FF9BF6783EB971FF8A8
+:10B9B00003F92B7D072C349FBE03AFE57F1BCBFB28
+:10B9C0002D1E9C6FDF460BFF1DE803C974DF74DF7B
+:10B9D000301E676BFDF5C5F161D2539B7812F27092
+:10B9E0007E4FEC859EFF781FEF55BDD0637163DC01
+:10B9F000A1E94012F9E14DFB13E87EF8BE5F5F2C30
+:10BA0000D5C68BFEDCF5348AF3167DC9AC06F35B34
+:10BA1000FAD2B8BFD6F4E2B53F692940BBF420DDC5
+:10BA2000575CFED27F8E47F9D3F72CB72BC03FDF90
+:10BA3000819B88DF1DFEDCF74DD978DE88915F7D24
+:10BA400095FB33F2AB07C385C3A10FE080EB02B8CF
+:10BA5000D03DDDF1E0B1EB7F2D3C3E257FA1BE67FF
+:10BA60000AF151042E0AFFDD919EE4A055A1F5F3E1
+:10BA7000F7072E8E473BE96C670BE9FD2BADFBE02A
+:10BA8000FFB9752BA1A1AC3BFCBF76DD9CFE570F27
+:10BA9000E7FA49CF0783E9FC57DFA4F2CF933D349F
+:10BAA000DF21F23F6EBFA27CFFEF5EFF7F01F65207
+:10BAB0009D150080000000001F8B080000000000A2
+:10BAC000000BD53C0B7454D5B5FBCEBDF3493249C0
+:10BAD000261F2008C19B2F51F2194802E1A7938429
+:10BAE0005050C409488B157000955F4822D89A566B
+:10BAF000DFCBC4440CD4D547D5565BD135A0509E7E
+:10BB0000CF3E530C96564207540AADD5D142054D4F
+:10BB1000E948AD480D6404157CA5E5EDBDCFBD99A0
+:10BB2000B9378988ABAEF55EB2C8F1DCF3DB67FFED
+:10BB3000F73EE7586F035F8713A03711E6EF28C47D
+:10BB400032053C900ED0F0E2C4A75AB20056777E80
+:10BB5000B408CA00EA764F0019EBD5BFFE477198CA
+:10BB6000FAEF903CE27B62C021E1F73D9F89EF7BD9
+:10BB7000CE1503961FEE90827212D6EFB32F0FD020
+:10BB8000BC9930BF03CBD6AE73C5612C01DA00CAB5
+:10BB900001AE546D5C9ED9FDF763523A95761570EF
+:10BBA0009D863D0940F337FC2A2E00387F6FD7B9B8
+:10BBB000F13E9CF722FD5C0BD0D38C538C8ED6CDFE
+:10BBC00065CFCE3F8DBF07BBD4BDF04EF1E358F635
+:10BBD000BC7034FF45AAFFE2AD51EF60597FC97DCB
+:10BBE000EFB52DC5F63BAE5419BEE8BEF7DAA08816
+:10BBF000F67B7011F5EFDD93E8B267117CFF180555
+:10BC000031FBBFD4BEAFF97FBA6F003FC01000ABAD
+:10BC1000EC7564237C0F4230A462793FC08C0E67C0
+:10BC20007F785651E3101A0721180A2083F891D320
+:10BC300057CE82242A377C2417D3F83933B2100E1A
+:10BC4000BF6A716F55A98785F1D03ED21DD880702B
+:10BC500081E25DBE19EBD62BEBDC1B78863B01C67F
+:10BC6000037CCBA1CD3774D60C09E76B6D41B8705E
+:10BC70009ED62116572BCEA3A896A0BD98CB77A908
+:10BC80007C60E87507685DC56983A036F622FE739F
+:10BC900002D60BB43AAE179F1B53C77F71B0CFA526
+:10BCA000E0FA716E0502B8253BC48CC7FE33551708
+:10BCB000EF331E027E97F3F2F1F4F825F064C68F9D
+:10BCC0008EB77E780270D07885FE8BF69FBE2144B9
+:10BCD00072A880E20F8BFD481725C2A73BC381F3F2
+:10BCE0005993EF706F90F8BBAA8CD7C659E8CF1A5A
+:10BCF000037E117F9EB8E2289E63E6E3FD9BF17C04
+:10BD0000B9F8D5E912077398CE71239DEE00C27F72
+:10BD1000BF2AF07E3FE25D92A2F8D5F166A6433DD0
+:10BD2000F14E7914FFD1728AEBFD314C48B888C8C6
+:10BD3000F557414123CE53234F09FB71FE331509BB
+:10BD40006E3BC98B0441691C969543AB00F7D193B8
+:10BD50006953A89C1AC13DC5C07BED79072831FB0A
+:10BD6000AB841443BD27339FC7573B861BC6F50CD6
+:10BD7000AF70D0F71A5796A1FFEB7149C55042E357
+:10BD8000A6CFA0F6AF655C651837FB78CFA6C5587F
+:10BD9000DE2885CB88397A0E2EA8227CCD54C71A8E
+:10BDA000FAED42B542F21CA991035B101FB5527027
+:10BDB0006831E2EDFA828946F8249846FBACB3205C
+:10BDC0006B61BF1BDC9586F61B2B661AE6ADF5D4BE
+:10BDD0001AEA754D9F82920630B9E90228A50063E0
+:10BDE000831D86F1A5077619FA27BD0A722296638C
+:10BDF0000FA9AD5496768752897D6D690EBF2519BE
+:10BE00005938ECADC6EDC0F80F1A5FA2B2C981F87F
+:10BE1000C0EFE7E24489F4623EF71F8B0BB422BC0B
+:10BE2000E72C011FE1E16E39504065FC883B8A2117
+:10BE30001BE064C6837232C10FBE632AF2C1C48F95
+:10BE400003AD54BFF64287EC233DBC5DF6DB4A8868
+:10BE5000EEB3127E4F7AB74302A27B9DD3E20990E4
+:10BE6000DD4AED285E1BC35F1F7E1B6EF516F6973D
+:10BE7000D74D7995119ABF2DC3B3712FE9CDAA3F44
+:10BE80002D92B3FBF703971209EB78C9A671DEEC8C
+:10BE900091384E4E9CE620BD1E5F2DF3BEE06BD662
+:10BEA000C0569C679DC51DA7093FDB57D774EB663D
+:10BEB00092EBF62CA11FE27F07AA84F0C7A7F9E452
+:10BEC000221AF71F126C85E87A4B2B80F791926546
+:10BED000117CAFB8862C2CA2F1895C1F5F21F00881
+:10BEE000B32C813C9C72EFD413FE44C443FC8D966A
+:10BEF0004CB4409054E1F95D2ED6C787DECC94490E
+:10BF000096A0C042FA640DAA37D227C31ECC7A7419
+:10BF10001F8D3F60853C2C962EF09CCDC5FAF767AF
+:10BF20005940C2F6CE8AAA84A218FC259D97402DBE
+:10BF30008DD6DBB3548623490903C971D27985DBD9
+:10BF4000A129DF42FA465F276981FAD6DA9875405F
+:10BF5000F1AC22B8375CDDAD92BE4A3A22F6091048
+:10BF6000CEF0E2D6FE86765125422AE18C8589FD07
+:10BF7000E9F0B7EDE5292AD231ADD29DE2A6F2670C
+:10BF800088E4498C673FA9BFEFD39F2BA8F6686868
+:10BF90001AB66F271D28DA83807CBCC1A6B5930A28
+:10BFA000C17A9AA4B5FB1FF54E233ACAC6FE25D91D
+:10BFB0007DFD3D8E8CE8FC53363F1A6A2BEC8FD703
+:10BFC000BD53ED6C87E3910FECD877CD5585C360F9
+:10BFD000003B11C56BC225F09A24F07A01B53DAE45
+:10BFE000739743ACF39EA48E22FE7AD882529F03AD
+:10BFF000F092CB579D554EF0078BE8FB9224CFB0C3
+:10C00000A9C86F9D36CFA8EF901EE98A736FC171E2
+:10C01000B5777EF85813C9F1ECBF15A007039D8AC8
+:10C0200027611CAED3E0FA94E5BF462E4C26FFA64E
+:10C030000F8FC4BFB8E6F72DD13AE983A4285E3D3F
+:10C04000B9D8BE2106CF0E07E92B51FFF7AC67BC6C
+:10C050006D44DFDB1C8CA7B59A0CB5A5C0460BF26E
+:10C06000FF59D7B6AF133F9CDD6E05F2933AA99105
+:10C07000EC638183E508D2C319B5C8F7456F58BC96
+:10C08000E48775237F78883F1AF30DF39D9DF25660
+:10C090006A118E3B9BAEA4127E56866D8CB7850AC4
+:10C0A00004EDA81F3BD36FABAEC4F6CE232AB777FF
+:10C0B00068F33C9BE7599EC576659AEB7DDC97E477
+:10C0C00099245F1C3338BDC862BEAFEB43C4730311
+:10C0D0006D3375703E68AB7404C8AF6CA8682924D2
+:10C0E0007BB026257F18E03E1AA6496C5F1B9A3E5E
+:10C0F00066BCEBF32BE76550D3A275778ECA7650FA
+:10C10000513CCC0FCA791BB7D7359D65BD8DE06416
+:10C1100091DCF4B408FDB6D10AB7D66259F74FF9ED
+:10C12000D65AEC5F872CC5F601F6D9D6C4E83FE8AD
+:10C13000F8A84FCF9720ED1E9EF5663CE9D55AC969
+:10C14000350F700F87B36DB5CA70ACC7B9E64958E3
+:10C150000F6CE9F5723DD335CF82F58EACDA5A65B6
+:10C1600022D687BB7E687103FC69CB4AD13FCB7571
+:10C1700098EA07B31E10ED89820F7E98755BADBFFC
+:10C1800090F8CBC97839D39EC0F231189E9735BD4F
+:10C1900068C04BBF7659BAD54B7C355FE8C153EBCD
+:10C1A000476C66FF2737944F6B6E273D8B781B8A51
+:10C1B000B4A9C07FAFA0DC3B100FE939E0B160FF4C
+:10C1C000F45FA0FDA1FEEF854611FE96FD222E280C
+:10C1D000213D563FF1928DECCF1259CD27B9FAF59A
+:10C1E00068DF7F935C9D4E0C717D59D31E86EB1FDB
+:10C1F000B92EE19FB822855EE4CFE5B0D146EDCB04
+:10C2000041394E7602B528FB312B9D2FDBC80F5BE1
+:10C21000F9B4F57838C68EAE82F03192D3BA67ADF4
+:10C22000C7C331F616687C0C7F1DB70838140D1F84
+:10C230004BE4D0229B806B2FC1B53A15FD7999CC88
+:10C240004368A88FFDA0BA028E4332E281F86EDD0A
+:10C25000156F17FB06B07B1DCD68E751E47634EF10
+:10C26000E2B21DE724BD334C09DBDC384FBDA69795
+:10C27000C7878EDB2066FC31CD7E25EF92B85DD777
+:10C2800017D176619FA0D033D68270AC9EF3EA14AA
+:10C29000A28B4ECF6B13A0232E95E9E2D6E8E226BF
+:10C2A000BAE8F8477C962A38EEE50B382E6B20BEAC
+:10C2B000D0F12FE0ED8C17FA22B2338EFD2433FC3F
+:10C2C000E7343ED0F791902DEA83C19F909D28E8F6
+:10C2D000FA2F863F215BC8B1791FBA1CF7C57D2DA7
+:10C2E00003FB293ADC97CF6721DB17E1335DCFD41D
+:10C2F00083AF80E6D7F58A8E671D4E1D5F9D14FFC4
+:10C300000C00A7D2F44BC37E945015050D50909DA0
+:10C310002DF458C74C203A284DBBB9DFE5EE47D77E
+:10C32000B783ED4BD7B3E6FDE9FA56DFA7AE77F555
+:10C33000FD4E4545C2FA10C3768AABAE3DEF33F8E9
+:10C34000BD95B0C2E017573BEE34D46B5CDF31F4DF
+:10C35000FF5A468BA17DA6BADED07E7DC10F0CF5BB
+:10C360001BDC3F36F9ED9B4D7EFB7F1ADAA7844339
+:10C37000EC67BFD63C031474ACAEF920C2FE76B0B5
+:10C38000D9C5F57DCD195CBEDCACB27CEF6F2EE07B
+:10C39000F240B39BBFFFB6B982CB579B3D5C869AF8
+:10C3A000BD5C9AF5C2ECE7BFA1507C5211DA584D42
+:10C3B000AA7C5B8EEFEE6CE487D72D81D644C4D384
+:10C3C000846EE18FC372B33D3E77EC1EB2EB2E9BC1
+:10C3D0009BEC61DBDE89923A803F9784F6CE13C3F3
+:10C3E0002F49B3C2E021BF07CDF340FC756FB6857E
+:10C3F000E9476A1F50EEE63BC09A8EF2367FBEE4F4
+:10C400006E15E6C00FA95C067DD83E5B013FD9FFE3
+:10C410005AA712B42731685E07C2394F8009766A7D
+:10C4200027FB9D9EA690DF7A137D4478658F0CD7FD
+:10C43000E0F77915BFFB8CE2E46F3A3BACC42737D9
+:10C440001FB8EFD43DD80E6DFE72928F3EBFC1FF74
+:10C45000B6E572FC867BB3855CF54AEE9087FC9D61
+:10C4600014C51DEBFFEBA5375BF8FFB35BFD721244
+:10C47000E233F206B01FA7CB23EEAF9DE0D7E5A2D3
+:10C48000D6A504472791BDFF4135F5AF3BA4325EE9
+:10C4900074B9D0E5408FFB7439A8919F6DA5FE67F4
+:10C4A0008E00C7CF137A7C1F3C4FFB34F99D15914A
+:10C4B0008DD514875D2A4E9C74BEE325EAB7A7D9B3
+:10C4C000C77CB4BB793E97C1E6E51A7F3672FDE5BD
+:10C4D000E626AEEF6FF67379A0B95DE3CF8DDCFE93
+:10C4E0006AF3635C7FAD39A0F1E976FEEECE11F61A
+:10C4F000F7E350F530E2BFA7B245DE061C951C47B6
+:10C500008022CA2FCA2775192F0A7FCAC41F66BE88
+:10C51000D0F901506F4888AF6FA29D25FB700BF8D2
+:10C520008B1663397FD946EB64E9CBF3C54A671BA9
+:10C53000FB1F667DB80282ACEFFAEB77E1FF5F4A42
+:10C54000BFCB189F92BDD2F5DF6A08F37C76F94E17
+:10C5500037E54FBE3ABBE2D2EC0A2CA6FE7D7176DF
+:10C560007CF722D972E9383B7BA418AFC7D9E83FE2
+:10C5700002D9E5DE80CC7EF5F2AC8D491C675744CC
+:10C5800092C80F58D125333D30CE548623DD9669AD
+:10C5900074EB81E01F892ECBA62CE33CDCF24DC668
+:10C5A000FDAC74DE941C5407F4D306DC673D3CF804
+:10C5B00011E5E3EA357CF17784A7A9FBE6992FC75B
+:10C5C000F4FB243B319DF355136002E103E177074F
+:10C5D00049CE0EC92C6783F1C5698C4F88CFCF3502
+:10C5E000CF9FF932F2FDE90BCD1C7FFD33FB811F9C
+:10C5F000F8477E75F45A97E74DC8E1BC5BD846F220
+:10C60000A3D36F1DE948847B5D95234081766FB984
+:10C610004BA1F57B258F4C7987DE77C1DD82F8ABA6
+:10C62000DCFD9B23241F950E279F1BE0267A62E9E1
+:10C6300039F190AFD589FD26BCEA91C97D2F7F39AC
+:10C64000DC4ADD747BA3DB9FC93D11D9C779815CCE
+:10C650009623C0D8E262CE17972373BCD94AF1263D
+:10C660002AA4B3CEE90CEFD920B8E97B348F25F2A8
+:10C670004B932F78E424846F9D161F4E7CCFCB7094
+:10C68000781C2AEB17BB164FDA332CF82D8A479704
+:10C69000CDB79DF29DF0AB38CEEB9AE19B9023F4A1
+:10C6A0007872AA7702E3D7A9E653DC5023F76C7BB4
+:10C6B0009CF8A133C14D791BB3BED5F5DB607E7B01
+:10C6C00083EBEC807EA45E3658C439C1B86AB59459
+:10C6D000E23FF22F292ED4E34473FF9ABCAAEB0861
+:10C6E000BE1A794AC84370B92C9FCBA70D4D1F7D48
+:10C6F0006E9CA6AFDFD055EE5A12930769CF91B466
+:10C70000FCAEE27ADF11A5DB17A5EFD4C87C83FD70
+:10C71000F9BFEEAFCD46374742192A9202C28F00C9
+:10C72000E14F2C8010978B20C2A50F3989CA25E0D4
+:10C73000E6F236F07219CEF535E790BF608D0C2524
+:10C74000393EF5C2DF0B892F4E5D33D995A546EDF5
+:10C75000AB6E6F2FD7AEC6D379D200FCF090C6B7C0
+:10C76000BADE1E943E26BDDD3B16F5834C79A1C88A
+:10C77000A21729DFBBC7EEDA1AA31FC06FF4170791
+:10C78000D317358A88DBB75BDCAF531ED1FF5A1A4B
+:10C790000C245F7A399BFC49E4C7E40561251BF949
+:10C7A0002D3FD5F334F1B3FF812929AC87498F5C44
+:10C7B000897478579CB7C00A299087FBDAD529EA93
+:10C7C00045B7A70424B6E741A6C742085B691FB76F
+:10C7D00002B0FE5C0C2A974BC1C374C199138A51F5
+:10C7E0009FDCDEA98CDB807095A446B249CE8A26F8
+:10C7F0001E4D9570FD62F2639D9C6369277F4387A0
+:10C80000F3448EF0632FE67876115D4B52431B1E86
+:10C8100026FF6EA705C8BF3B31F13B77408C7D1CDE
+:10C820009157D545FB784E12E77CFE2EBBC88F4151
+:10C8300064A837C6AF0EE756BF44F3FD568BE7A199
+:10C840007B3D9FFFD4BA044E61DA10C6018E1B45B2
+:10C85000FAA7BF9CF9795C09E97B91EFF34305AF37
+:10C86000CBF577724ED4B689FDF8C9AF1A91E73B84
+:10C87000447095D850A511FC4FD8035BD8FF691CB4
+:10C88000457988654FDA2D648F8FA23EA5F3CE7768
+:10C890009A1D5CFE09E3142AFF8C710A95EF629CD5
+:10C8A00042E55F304EA1F2F6F3635129231D723D3C
+:10C8B0007F617D39C83E06D7177ECDBF86F9039DBF
+:10C8C000D3756B7C5DDCF9DE7D09C407BB64771E24
+:10C8D0008250B453E17CC2E9DD130272562C5E7DB6
+:10C8E0001182A378D71F1E9A5C46E3149784FD4FEC
+:10C8F000EF3A3B94E31F137C7DF8E8B2097C68F0C3
+:10C900003E9712DA40E39FDB994D10A23E00C187AB
+:10C9100044CF01F261002DCC27CFE708FFF6467B1C
+:10C92000A42CF65C12C8F453DE51B31735F285A47B
+:10C9300070A1967F9D487C9DFB3AADE73F20431E4A
+:10C94000F3A731BF50902BF0A097455D362FE545FA
+:10C950009EEBFAE39CEB110FB327CD2C9763E42DEC
+:10C96000237788E837F1B39F3C9CCEFD5DB4D4CDEE
+:10C97000B0B9C685FD6E71EC7D8550B0D0F56E4DB9
+:10C980000AD66FCD90F653B958CD9A9EAA12B80127
+:10C99000DECFD282CAFDC462B3DCB536B2AF952415
+:10C9A0005431FAB3DA914027A07DF51A579AA1FEC7
+:10C9B000B58C1186FE33D51C43FBF505630CEDFAEF
+:10C9C000BAB3DCA5867E24AFE4FFE23E98EEB05514
+:10C9D000E6F394A29D1FBFBD8AF77F7319EDBF17C1
+:10C9E000F1674307E1838AF53F7A98D4C6CE7D4943
+:10C9F0007CBE6AF233EBBA9EDAEF5107F7333F8120
+:10CA0000DD03FA67F583F8675FD4CF44FDF110E9E1
+:10CA10008F92176EE2F3F2E7267E76854AFE722E3B
+:10CA2000FA9F884AB3FFD9ABF99F66FEE9E3534901
+:10CA3000157C7350667DABFBA166FE01B84FB3E376
+:10CA4000A2BC5C399FFDA6B03B7F25794F8BE56B7F
+:10CA5000AD34E5154A6C680728DFF77B19B6D08737
+:10CA60000B08878EFF9C28DFC36D9B5F195EC6DFB6
+:10CA7000FD89B864BD966768CED5FC8EBABDAF0C93
+:10CA80004F8FB6C35DEF1AFAC3BDD27E43BD2DCB27
+:10CA9000587FB0727FECF8C1F4D0B24D77DA7C9455
+:10CAA0005F7E44E41BCDED3A3C35FBE23CA42F9580
+:10CAB000DD768E6BEA5D1ECE832883E44174BD7003
+:10CAC000B30C8D03E9B70DDABCB3F6C581FC25E6DE
+:10CAD0003D8ABC42F0F87F21ECCCD1640F7863D65C
+:10CAE000F961AEC8039F4AD9F86F9F62BF53BF0474
+:10CAF00037A1FE548AD0B7C59D272C16B213F182F8
+:10CB00005F8A5D614B2ADD53599EE0A773E086156D
+:10CB1000897E3AFF29C98EFCD181A47F2277EE431A
+:10CB20000EE4BBB72D1683DDE9255D87F56D4FCF8C
+:10CB30009943E76DD7EF8B0B5ABEC47EB6511E9357
+:10CB4000EC549590F745C437FAF916CA47C3FD600F
+:10CB500038EFA2FD53FD58EED7DF7C84CE6B0E0A72
+:10CB6000F9C766A739AEBC2526AE844D427E1DF8B6
+:10CB70004BFECBCA9737DA28DEF9AAE47E6FAE33D4
+:10CB80001A5F8EEE2FCFBABC371C16F27E66F727DF
+:10CB90006F925E3F83F62E56DE757CE972DEF0986A
+:10CBA000CCF2A87F3FBD5B9E111800BFCF6A7C000E
+:10CBB000AE7CC3F9D79AA9E7E6905D5BD3A5F0B93F
+:10CBC000DE60F6BAA1DD78DEF5DC1EFB72711E2C8C
+:10CBD000F6D1ABDBD3AE4F522B0B45D9C2E7AE1B20
+:10CBE00035BD23FC18B4A3D674B2A3B512E7D10E99
+:10CBF000770DE37B15872508AAE3788A9B1C48B745
+:10CC0000B9623AFAEE247F0C320A145A678E46CF84
+:10CC1000B95A7E675ED7BC3CA2D71F3B971CF66013
+:10CC2000D327B939BCCF6F809FFDC1C329DE4CBA71
+:10CC30005F30BB55F0F7E194480FE5830E4F4D9000
+:10CC4000E85C09E76F8BF5F70E5BBD998DBC2FFD96
+:10CC50009CF16AF962C265C4B39A3E447AFA25111E
+:10CC60009731FF2BC31F64BE5A0181FD1E5CB7DEE6
+:10CC70001D64BF741588F8DCEC97D74FF9D0467661
+:10CC8000C11C4756EEDA7B84CE2FFAE5134CFC7AB2
+:10CC9000A9FC81397E1DCCAFCF4FF566E4C5E4EF2A
+:10CCA000CCFE799F1FAAFB515B13F87CE7A5A98FE7
+:10CCB0009E5E85F5BBB626B8285E3EF9A4DD4F7AA8
+:10CCC000F9E4167B40C2F693A9916E8A134EEE28C2
+:10CCD00072E30CB0CCA2FED7B364D79FB1325FE051
+:10CCE000CA86FB096BA6DECDF7F6D66C4D94E8FE3E
+:10CCF0000C6488763D76937F9AC87EC18AE787F375
+:10CD000079A56E5F483EE87CF98327E23CE4E49F26
+:10CD10003C303799F2763D969FF3B93CC8F71EA395
+:10CD200073F755DB12C7F1FD8B4260BA2DDF721528
+:10CD30009F536E547C9368FFD53FBD6118DD075B40
+:10CD4000F1872140FBE9DDFD3C9FE345FDF481FDDA
+:10CD5000BB33BB7392A1308A273D9FD7FE748B975C
+:10CD6000E85E2EA9E2BC051A3D23882F76D502CDB8
+:10CD70003B4E16F73D23EB13D82F35F35D6D9EF038
+:10CD800003EBF4BC411A3832487E7CC078E85D3F42
+:10CD9000660B9D6BADC84BD5EC74247F4ECC7DC229
+:10CDA0001AB9BB9EE2BD339BEC9CCFE8891BF83CD3
+:10CDB0006B615E0AC3B7CC613CFFAE6FFACC582FF3
+:10CDC000040FE99D71AD6AE99D58AED5F0DF92E997
+:10CDD000F5E5E17A2B3B7EF0C2AB8C974DDF7E9B75
+:10CDE000D63DE01479945705FECCFEFF3287C85734
+:10CDF000006C6678F5EF279E788BCF494FEC1C933B
+:10CE00002FCE7F43EF3F9EC5E7BEC7EEC172C781FD
+:10CE100037992E6678FB9DDF4912EFB78EF6914663
+:10CE2000E7B4DE6FE7F1FD1D11B72DD950C4F8D37B
+:10CE3000CFD17A4F0E1C9FE870EAF3EBF0E9F3EBE9
+:10CE4000FD5A357A5DA7C507A76CA1D37C1EFEC22B
+:10CE50001889F2747DDF5343C52931FCF255E5C5CD
+:10CE6000BFA9E5358E585ABE65A3FB6D1D0F5B7DCE
+:10CE7000B17AEF32F3E17D7EA00754D750614AD8F2
+:10CE80006EE1E694A1746EA7D54918B03E45034FF4
+:10CE90002278E8BE9F56C24A5F06E7BB693E99AE5C
+:10CEA0000F06B8DE5AE956A9BC56F22AE2BE5680F1
+:10CEB000F9723A348EA47D581C613EDFD2EFABCCC0
+:10CEC0004B59774316AED73604D6911FD3661572E9
+:10CED000E15F9CC0F19B8E27DDCE80ABD0605FDA36
+:10CEE0005CA02A38CF7C05DAADA9A2DF9588E7C31C
+:10CEF0000796BC427EC25B4AE3105AF7A8F3912220
+:10CF0000C942FE5D209162C4B7DF7CA6FCF7D8F76A
+:10CF10001DF04C7522FFDCF41B07EB7D733EE276BF
+:10CF2000F0717D1984AD1FE3B83F4FFC9FADFB202E
+:10CF3000BAAF3F4FFA7427C507B7A4DC574EE3F5E5
+:10CF4000FB93E67B7A275D4EBECF67BEAF7723F8B3
+:10CF500042C4CFE72CBE7A91FF689C40F6B737C534
+:10CF60000612F6EF1DA2E1E314303E7AADDAF88F37
+:10CF700054AE97558FE3BC229C53591F4F36D99B13
+:10CF8000B2311611875D14FDA7461483BD292BD13C
+:10CF9000F2367F57D92FBDF6BCF2B9F6A82E5FE462
+:10CFA00059CAD22C8D03F98756ADBD1582B2D88FE0
+:10CFB000F01326F7F1954726FAD56BF57AB267C8D4
+:10CFC0004FBD490E3F5D509CBC5BF0D76425B897C0
+:10CFD0004AD4AED0447EC52EB4773A1C74D697316D
+:10CFE00086F96092CE9F38D702ECB74E6AE4B8C596
+:10CFF00041FE0C961BA410C3710D44B8F46876BCB6
+:10D000000ADC5C4E032F97C89F5CCE404B42E5750F
+:10D01000D0C1E52C0809BB7F75B095ED19DCEBE2BA
+:10D02000F86FE6320BF91B65DF18385E187D493C56
+:10D03000A0C08DBF7C3C4C0794BB9C01F031B280FA
+:10D04000F587191F66F99C0A6199E59314430EE56B
+:10D05000095496D36AF070BDE60BE2A122EC533876
+:10D060004F63C647F5C07CE1D6F0F1E77C10E71FBF
+:10D070001A9D96E6AB5CD7E985729541FC6FA6A335
+:10D08000FEBD2CA1EA2C5D29BF7E5BE65CBA1F5574
+:10D09000565AB59654F282FCA2B9743FAA6C72D566
+:10D0A000F37474B9685BB1A89754955ADD68DF5A78
+:10D0B0004AE64EC3FE3EED3E31CC17FEF55D9ADFEB
+:10D0C000E26BF996DB8572E2CB74BA697F0E74EE7F
+:10D0D000E95E8A9C23CEF946CD08EEB362BFA38AEF
+:10D0E0006F7A3E9DF73982492AE2FDAE961ABE7FDD
+:10D0F000F6804DF4B7DB457E55DF177EF7C7617DBF
+:10D10000C78E316BA5ECC1D7C779E7E60F2138F29E
+:10D11000FC24AFBE9D925B50B26AD87C94CF9E90A7
+:10D1200015281FAAAF939EE99B4F7080239FF3643D
+:10D1300023347FA667C798314497A5F9DA7DAAF40E
+:10D14000AC52C25B43A67729CDDF9B28F86B29D16F
+:10D1500061C8E0E5F7F23D8B697EF3F7DEBF2200A0
+:10D1600038FEAE7CDF329AAF21E102DBF7D363FFFA
+:10D17000B02E9C15E5530989B400F7DDEA81808D56
+:10D18000ED8076CF5C3B77EABD1DE7413C94797D2D
+:10D19000ADA4D2262C888C27FD89F3AEA1751B6C1B
+:10D1A000E1516371DC23738FD9049F8D147CA6E950
+:10D1B000A1AE3D07EF1921AA5E8891AB863D9F7D08
+:10D1C000FA0EE2AFE18CD34DDDA3F2F4E3B51C4FD0
+:10D1D00082D3A03774399BB4CBCE7EF5E4DD57DD26
+:10D1E0004EFDA6FEA13B87F6756D7798CFB37ABB4F
+:10D1F000DE1A21E0D0E38D73D297B1BB74DECA7121
+:10D20000DC4E71DEBA466A7C2991EA3F93DC7E846B
+:10D21000FF846637F4B878B9B6AFD507B7AEA3BC0C
+:10D22000C8F24D4B67F17D9C80881B54FC25F9FFAB
+:10D23000045EE573EE55DBCDF144C446F45FDD6179
+:10D24000BAD743F130DD5F88D5EF03C4C34FE56B38
+:10D25000F9AE4CC8E47DC80B927D03E83B73BCFB80
+:10D2600018789EC9677FD62BD3FAE5CAC0F9842700
+:10D27000A2EF3B581E96696B139E9C1CEFDAC4BD4F
+:10D28000DF27D6BA5D54D7E47333F24A05F9D16D7E
+:10D290003F66FED7C7E9F2BAA25DDCAF864D69CC26
+:10D2A0007325DBEC1EA26BC9B6611C5F601CC47EDB
+:10D2B000DFE66DF676AAB7DE1FEF974B289F1CB905
+:10D2C00082F22AAD71E27D129947BAEF59922DF29E
+:10D2D0001CC774BDAED975FDDE6C5FFC9398CFF7AB
+:10D2E00093FBDAC38A21DE68D5FCE732828FFCC06B
+:10D2F00046AB889FE204FC7BDFF87A02F9B13B156C
+:10D300006F02E5A5CF1CCA4E8601F0A697E5685EC0
+:10D31000E073CE0BCBDF9A95F379F42A7B4CBB6795
+:10D32000AEF1E7AF9A3DF0176B941EFABE6AE46760
+:10D33000AB6D94E7B80D5C94F75873F0A9567A2753
+:10D34000B3663D7046E10CFDA178E1030B9F674F8A
+:10D350003A589A41FCD8A9E93B3ADF5563F86A3C50
+:10D360002585B07FF94808D0BBA138351ED498B8C0
+:10D3700038A120D5504F745F61189F5C916D68078C
+:10D38000BF2754383EEABFA678AE36F47F20693A0C
+:10D39000BFA3991ABA83F34A6933C619DAEDC8D71D
+:10D3A000745F013E16FE4F05FEB25D854699E09C16
+:10D3B0001C06F809F2DDA41EA37F5411DEC87160BB
+:10D3C000DC21C510D7DB2F91674A1AADC9D54818A3
+:10D3D00029F48319DFC67B0D6B0ECAECC7ADC944B7
+:10D3E000C7336B707CEBF2A7E37D88D788F761F3D6
+:10D3F0008D781EEE33E279C472239E331B8D78BE86
+:10D40000B2C988D72CBF118F39ED930CFDF3365676
+:10D4100019EAA31FBBCED0FFAAC01C437DCCF66F78
+:10D420001AFA17752C31B497EC5AF9B9741F1B5CB2
+:10D43000636837D3BDF4C0774D7CA8309ECBB577F9
+:10D44000553AFDFDF84BF49F0CDEE4A044E9407F23
+:10D450002BC9E3BF8AFEB3476BF75874FA7F41BD0F
+:10D460005AA8F94FE6F759B31384BE79EDC0994332
+:10D470001EACBFAE965A33C86FD2FC03AF7E1E619E
+:10D480008AFBF438E5C60AC974DE1E67386FBFD45C
+:10D49000FDB4F250D0501F7B48BC6B1A77C4FD120C
+:10D4A00095E5EF79E4D8774C133F66B3DC2FEED4E3
+:10D4B000EFB9E97113643CC971E8021D7E1282F173
+:10D4C000FDF38B7A7C6A8E5BF578B5FF3B29E1979B
+:10D4D000DC2D0F16C78AF8558F5BBF0E1E7E0F56C8
+:10D4E0003ED2B76E34DD9FB244D2A85D8F6709B1DA
+:10D4F000746EDC4B8865E7E2E05C4F21BF23E5BC3E
+:10D50000F7CA9657E6D27D7D04DF151E2FD23FF471
+:10D51000F3E468DFC6D1A8778F4BAE75A538F6B5B2
+:10D52000491F8EA2F91E1E2DF20C76193184F66762
+:10D53000D8020FD0F7FC54CF23A387F4BF676D2E1A
+:10D54000CDF77F3A9B835C2A2E37DFBF31E707C3D5
+:10D550001695FD4EFF7725BE6FF321013731EAAFF7
+:10D560009C69B7B2BF025A3CBE50C3BF9EB758A019
+:10D57000EDE7384EB11CEDEFC25DBF61BAACCAE851
+:10D58000D1F21D8DEC5F2F1DE91CC7F7C93CA56EBC
+:10D5900091E7D2F318232EEB9DC8A5F6BF2AE3A48A
+:10D5A000218F04CFA67DA1F3EDE8BEC5FCC7D78BC4
+:10D5B0007CE4F1F5999CFF8ECE7F9AF3490B1BDF3B
+:10D5C00030C8C5AD4D470D72B0D8FFAEA13D9C1E11
+:10D5D000B152FE30FCC2F0E9B720FE4EEDB4F33B91
+:10D5E00066E4833746C7E4CFC2EBC74CE3F79097B6
+:10D5F000DCE7870C47777388E9ABEFF358F311AE9C
+:10D60000879BC35C9AF7A9E729F4D2B60F0AE89E74
+:10D610007D448A77535ED89CBFB8DBA2BECFF72289
+:10D620000BB2B57382C6122FD34FE42BBAB577A1D4
+:10D63000DDDABBD06EED9D67B7F6AEB35B7BBFD9CD
+:10D640006B75B6535EA35B12F77716489E2717E3F8
+:10D650007AC9237D1F915C35AC8C142BB84E43499D
+:10D66000789184741E39C4F731E145C2706138BFC6
+:10D670000BF2F33DAF0F2CFE627A47E32EC8B88958
+:10D68000E2BC0FE2FDA7C91329D89E26EA362187FE
+:10D690001505FF60B97B0F27A3FDF97F2989BC928F
+:10D6A000336CA3775053D37D503044DCDFE2F72F47
+:10D6B000F89DF852CF73F65A851FD8ABF983F6025E
+:10D6C000710EE83095D944F3725A0F343FFFC17C94
+:10D6D0007E37B2C90EE4BFE2FAFC4E46BF67627EF7
+:10D6E0004733EED7767EEFA0E743471464F17CF42E
+:10D6F000BE86E432FD7B09ACB7201C1A45EF71FAF7
+:10D70000E03D24DE439EA23C724CFE794481F6CE7D
+:10D71000F13630BCE7597DF0F8318AB37E3DDA77D7
+:10D720006501CEBFC4A28E27BAAE4EDACBF9AEB138
+:10D73000052AAF8BF08AFDCAD046745AED08737E75
+:10D74000EC52F9F0C1F67FEAF6D08F0A39FFAB163A
+:10D75000F37B3A6D5D84636C414CDE5A87233ACF8C
+:10D76000E7F3BF9ED7D5EB279E78205FCBCBDFEAD0
+:10D770001DC09ECED0F0D26D1D388FBEB440C423E4
+:10D78000FDE8331A4D11DD538C471B81E53CC21374
+:10D79000E5816FC6FD707EC23396E8BB7A8E93DF5B
+:10D7A0008DEBF3E33CBE9F7FCE3A2D99DE1B89FFC4
+:10D7B00056368ABCBBDEDE2B09BAFAD78B3CE8EAC8
+:10D7C0003D478FD1FFBF60C54F8B4A39BED7C69B3F
+:10D7D000F18CF8E5F74D4B64716E85F85D40F39B75
+:10D7E000F3ED5F16AFBD99E27CB577F367A3E8DD93
+:10D7F000E86ABA7F46EFBCB4FC15741AF352882F5E
+:10D800003FE52BFA9F47019F6BD9353B62D7C78F06
+:10D81000540CE3BB9DDEB5C41F2F687A03FB072CB5
+:10D82000B87EA71E279BF2289D2191EFECCCB0B1CA
+:10D830009F4CFE0ED927DDDFB9EB0D91EFBC2B4BD2
+:10D84000F8D1041FD1573AB29FFD843EFB2FB95542
+:10D85000C29FDDEABB9FD607DF5AB65FF295485FED
+:10D860003ABFF8ED755A3E40D8C372CDFE95D33C11
+:10D87000E4E01426B35D2CD3D645FF91F36E13C1BB
+:10D88000D72A80D1F266EBF7731EE17F01BC43AE6D
+:10D89000E0704400000000000000000000000000F4
+:10D8A0001F8B080000000000000BFB51CFC0F003ED
+:10D8B0000917B0A1F2AFA1F1933951F93F5951F9CC
+:10D8C00017D0F884B02E1303C30A46D2F420E39D88
+:10D8D00040FD0780F838109F6322DF1C103E28CCE3
+:10D8E000C0F0458C816116906E01D26781F82B10D3
+:10D8F000DF06F245441818948178BE28034314903B
+:10D900005E0AC40522107D8780748D287976AAF37B
+:10D9100050E6E6514C195E298DCA2F55616058A614
+:10D92000CAC0F05A0DC25F8824CFA0CEC050A60254
+:10D9300061EBC931307400D5CC94C66EAE3E50BE9A
+:10D9400013282FA00EE10300D191FB3B68030000D8
+:10D9500000000000000000001F8B08000000000015
+:10D96000000BCD7D0B7855D595F03A8FFB7EE424E6
+:10D97000B9819B90C049081834E0490C0F11F12679
+:10D98000441A6CC41B8C1A6768BD606B231588C869
+:10D99000687C4C7381248497066D2D83FEF462AD00
+:10D9A0004329ADD16287A98FB9202D689D1A2D56C4
+:10D9B000ED4FFF46C6B1D42A7F44F1552CB3D7DAD8
+:10D9C000FB24E79CDC04D0CE7C838FC33E673FD62C
+:10D9D0005E7BBDF7DAFBBAA104E0128053F8873D05
+:10D9E0006F9000206FF0095EA3092200CD9A5B5F63
+:10D9F0005F0CF04DC538A857B1F7A365E3073ABEF1
+:10DA00009F580B610005EBE70318F83FD66E4D7089
+:10DA1000F5A84490BD531666E1D3ECDF7C36AB002D
+:10DA20005A257EDF3831D377F30929577F9F17E8CE
+:10DA3000CF29066AEBE1D727EF37CBECBF020845C9
+:10DA4000DE0AB0BF4C87E9A71480E3C10559691805
+:10DA5000BEBFB7DBBACF5327007CD4F6DAE4FD13A0
+:10DA6000867EFFA6022D3DE543DF4F0736E854C40E
+:10DA700047D21D9F3C38EF81790619922E64ED0143
+:10DA8000D29E1CF6DCB1F93CB56C104EE73C00921E
+:10DA90001CBF9FB39D2752932E60A50A29318BE0AE
+:10DAA00052D93FD300A82A5B97253B1A80E072C069
+:10DAB000DB11F9DBC03BEC7A897AC783AB3B91B4CD
+:10DAC000D6B838BDB4E7C9C66A184A2FE67A98783E
+:10DAD0003CD3F5B81D7C348E4947CDF2C211D7FD39
+:10DAE0007474743DD2D179FFFD7494FCDF4B471DF3
+:10DAF000D4CFFF323A02E8E6F8823E15C71F7CCF4A
+:10DB00009F91853D12D2192BF622DC457C28286A8C
+:10DB1000EDBC599EC2C41418CF9DC3E45651DFA278
+:10DB20007A847BF4E1797FC26767634DDDA56C7E03
+:10DB3000F94D3D2F7D893D23F1949460EB751FC80D
+:10DB40002854587F3725ABD9FCDAB1B399008F241C
+:10DB500017C592385F88018C02F8073127005957A2
+:10DB60005939447FCD340F37A4393EA4539EA1EDDB
+:10DB7000879B7F08DB99758AF1FF2B00E777BA76E0
+:10DB8000B0928F9764FF20BEC70C8E4FFDE4375BC9
+:10DB9000CA80F8B17FEFC5BF107E6FFE1F19AF00BE
+:10DBA0002A7D281F42F5B296C2FAD093ADB272E434
+:10DBB0002615D24C461454754B2EFDF4EBD2095069
+:10DBC000D7C3D7476A080DC2F79F2011FD8CBDE36C
+:10DBD000CDED6B19C99D581834883E3480DC9CA16A
+:10DBE000F3F94E1B12B2A5DC582325683CE3B95269
+:10DBF000D63ED9C8F5DE7DF50BB2ADF2CA23490297
+:10DC00006F4EFA005D9D866CC5E943AD9763BE29F2
+:10DC10005F9C3ED4CF491F792B2DEDE0ECD72B62D2
+:10DC2000DA0567481F5F743C735D87F2D52AB1AE91
+:10DC3000A53E607C7B6FDD828C76C6F0EB5A49FC9A
+:10DC40001EA987582A43BBFC81F54C0E7DB2F551C5
+:10DC50000696F716DB7A29A3A7356D1F011F4AC464
+:10DC60003E5FB35F5FABA2BF99CB8AAA26637F6E8C
+:10DC7000EC8FD1D9BAE8BD4960FC7002699BE143E1
+:10DC8000E9AE4863194AC1F881804066655F349601
+:10DC90005A4F7490A27531E1F3E8B20DFF6AC46F78
+:10DCA0002B435352B2C2EF6B75131C6E1C8FD1BB4A
+:10DCB000A2B10E192AD420A47D61ACC1E14732384B
+:10DCC000351ECB77DAE8A04BAF844CEB60D22BA2A9
+:10DCD00095D3EB9D67265F9CE335DAE13DE3764122
+:10DCE000557FCBA287866FA7C25BE6FA30247E0DF4
+:10DCF0003B983AB84E6B5DB0473A9FE9EBC2AB2117
+:10DD0000C1DEAEC54F17129D923DB3B6B05243BAB5
+:10DD1000821D928A709A7A14A23954AF42D2A91FF6
+:10DD2000D9DB02584F09C6E8697E1F1E2E417FC904
+:10DD3000D8DE52D6EFE5627D2F177A0DAA5C6FF61A
+:10DD40009970939E5507CB6C1EEFDECEFEC7E8247C
+:10DD50005921A57E200DFD5E8F7A91C9A57A7C6F31
+:10DD6000912B5B06F8204AEB552FBE3DFBC4AB134D
+:10DD70002F60F4D16B2880626BF5139E582DEBFF5A
+:10DD8000A58BA5944712F03238E70B385F88E5166B
+:10DD9000219DF6D67A888EE77FE9A30892F1B13DFE
+:10DDA000BF5133D1CBFC59AE4138D87FCBADF363F3
+:10DDB000FFFDF3C0BA14D238265C4B2B1582A37733
+:10DDC0009694C271F6FFFE8F775FC4E07CA14A3261
+:10DDD0003C3AC11B02365E6FECFDC8887E8739BEB7
+:10DDE0000E1AE2D339BEB91EE1314078853F30BC0E
+:10DDF000B2F19235FD7D6B10CF4724630D1B2F6B65
+:10DE000076EB381CA7589609DE75B3BCB2C2E8079A
+:10DE10005E1B25233E8382CFB3DCDDDEF10CCECE4C
+:10DE200009323CC45EAD2B1D599EB53BE499AAC591
+:10DE300063126BAF27B54A6504BE48C5E4BA4CF21D
+:10DE4000EE7989EBC98EE402AD14A7B7DF6E07A2A5
+:10DE50005E8A5BF42AB3179F97D8FC5D114EC7D931
+:10DE6000B5716E27F68E22F91510EB9135654116C6
+:10DE700064B083879D071B2893DD9C2D73F8E030E9
+:10DE8000EF5F35FBCF19B9FFB5A2FF8F9B25E845A2
+:10DE9000F8D4B817D71F621544CF7E419FB03287A0
+:10DEA000CAA6DCF594C5BB8AD93A7AA232E83ACE42
+:10DEB0002F49EBBC81AD712103C55FCBBEB3AA1B5B
+:10DEC0003E53C82EC9964F24930C8E0D7B6F049D34
+:10DED000D9A9FE680AA83CF9062FE26703530A7C19
+:10DEE000FC1EC0F1038C6C51BE06987CD551BEEA75
+:10DEF0003D699995D53A3062EC534833243F2399D4
+:10DF00007DD192552A7BDFBE10887E01AD080B7E45
+:10DF1000DBA32FC71406576713905DD319A9A1F986
+:10DF2000B597D7788BD1DEA957E93D9C64F830EDE1
+:10DF300010260FFD6510C3F136E4432A88BC549BBC
+:10DF400047F4E8D6F8FCF52DA590BE807DCF9EB6AF
+:10DF500017C74FFE231813F89024D754932ED44498
+:10DF60005242FFAE5533D667A0BB2D90C892A7DAB8
+:10DF7000E894F4AE136F596EB80CF1DB59C1E8BFE9
+:10DF800078683F85C83F8CDE52C6822B4A328C535C
+:10DF90002CEB441F6659FFD84DF00F577FB01EB3CE
+:10DFA0003373B1EB98847881DA08CD2F0706FEC46D
+:10DFB000B09C2BE63B0A5AA85E7446F75EE4B38237
+:10DFC000584F35E2E23BA1AB5FA2758307358C4722
+:10DFD00030684B4FE50ECA895890CB89E3864CF2E6
+:10DFE0003124A7B518EB20E4EB8D92B2D681FC88E2
+:10DFF0002C6CC2005EDFD63D19FDCB3018127E0FAF
+:10E00000196AD22A7FB280956DF61F1C2A9D46A4FC
+:10E01000C5F902B4BDC8325A59CB39D8DF7D0C20BE
+:10E020001FF393378612A42F3EF285A7E0601FC925
+:10E03000F1AC346F5F8676F76D8ADF588FF46070CD
+:10E04000FDE065FFA0FCCB9AA1DAE47176CC5ECE50
+:10E0500075E88DB94A90E69B7D39087D10AB9F30FD
+:10E060006A103E065903D2CDE65A1570BC6090C3C3
+:10E0700065C299AB9C4CCB40701C4138187A088E15
+:10E08000701990BFC7E039E280E788039E23567875
+:10E090005ABD7CBE4EBF7FB12CFC7EE6F7A21E3C73
+:10E0A00001EFC4EA90606245A457C21AAF1BF4F6B0
+:10E0B0009251A58146EBEFF4FBD9FA1CB7E9871919
+:10E0C000A2AC33BBBE84E0B37F8742A2132A2B30BD
+:10E0D000E0BF2E9E61E247BFE6FF32BEBBF1A00B60
+:10E0E00090AF18FF2AF8DD25BEDE28FCD8C5A8FFB2
+:10E0F00099DEFE1AC4C308DFBB2093BDFC2EBC1CF6
+:10E10000BEC02217EF93DD428FB305B5F22F185131
+:10E11000F4ABD56067AF1226349874269DA2753390
+:10E1200080FCEE20A7B7247857917DD1C5F5A3E9EF
+:10E13000F77DBDDBAEAFBFB1C55EBE01168C42FA46
+:10E14000BAE1DB2E48B17E6FB4DA1F6C7DEE9035FC
+:10E1500082EF1BD0D2A905C9CE6AC2792CD6404520
+:10E160003F6DE9BFFC9F698BD87CB60A3DFA3693B8
+:10E17000EBBA456F2C89A4DCB1F2A1F35B2319F350
+:10E180002F92869FDF5A57EF7CB40F929B5CE4D7A7
+:10E1900081D35FDBAD90BF666947F05EDF659FDFCF
+:10E1A000E9E6EF9C2FF35868BE4B762C22BD39DC94
+:10E1B0007CDC3BA4582A837E7BCCD48742BE98F477
+:10E1C0006DF275B206B8BDF7FF7CA9356CBC57502F
+:10E1D0003ED2FAB79CCFE3282DD3F179BA76BFFBB4
+:10E1E0009CEDFEF039DBBD29E4B8B3DD526F9F1B17
+:10E1F000D773B99AAC93E4413BDAEB6A898D61A895
+:10E2000070EDA94EA32966A9D77586F50E4A256734
+:10E2100054AF4E1EA1BF63C2CE38B0EBFBEE3EE45E
+:10E22000BF9D6FCC47FDFECD2715F0B2791DDB15E4
+:10E230008234D2A79A72A3BDB284D1558ACAE96941
+:10E24000575AEC2A46B1D4FF371F0D917DB0E471C7
+:10E250004FAA9EB55FF2B3FF98020C0FC756F7FFA7
+:10E26000720CD2EB4E89FB7FC9BE2957B2F74B54D3
+:10E27000B82E9E814E6485F3CB3BFF1A6842BB4F9C
+:10E28000DAB1F7ABD46FCF352E94CB66BD4F6417A0
+:10E290008DCBEAC5F07BF287526A82C4E16B983C71
+:10E2A000D4EF7EE78712876F8F2BE543F8766C7784
+:10E2B0002758BDE53BDE23BA9DF3E88FC38887E589
+:10E2C0007B149BBFBB7C8792F64CA1E71BF844CD27
+:10E2D00028317E5B26F875D9EEA5A40796F56C78F3
+:10E2E0000FF975F91E974DAE33BC1869C4EBAB8AB4
+:10E2F000518FE59FFE735867A87A3BBA33AC9553AC
+:10E30000BF8BDC8CAEAE98616F87FD7F9C33B43FD2
+:10E31000807E8A6B2EEF59C7C703AE6F4C3E7D1BC4
+:10E32000FF923F546F4C52ECFB0E27E08569148737
+:10E33000DC919BD18F33F585C9AFDFFCF1896D4945
+:10E3400036EE3B8FFF795B92C17FD35FDFDF7627AD
+:10E350009B173CE3D3500E2DDFF94A182C78AF55AC
+:10E36000B81F76EC87FFFCC856C62FC75EF7905DD6
+:10E3700077ECE93F8ED5D9BC8F3DF6C928B43B5721
+:10E380003E7DE968A4AF954FCC190D23F80F48AF37
+:10E39000298F755D53B4AEFA1E098330004F89A7EB
+:10E3A000637D9EDDADA43174FBEE6B9E9487E167C7
+:10E3B000397BD75A89EBB594F41096EF62785EB644
+:10E3C0006BED7BCA944CF84E8E91A3F8646C13C528
+:10E3D000F5BEF28A8BABF0E93274A40FE827F9EFAF
+:10E3E0006CB7FC105BD7F3875FC71370D28DF85FF3
+:10E3F000BE6B1D1FD7B18EEFE25F2ECCA0FF87ACA6
+:10E40000E34DDFDB8A1F77E7D2BA0FB78E4B9FB899
+:10E410006A44FFCC9407A7C36FB3C4E13A5F89ADE8
+:10E420005090AF1EFFD1235B237C7DEB19428EFD04
+:10E43000F8C4580C2E1F75F57F15E564FFD31EED4B
+:10E4400021D666C9D3AF129F1D7BE225B74E72124B
+:10E450008212D37BC760E04F2FEAC165122F2C7F59
+:10E460003894F68407D76959AAA14E0FD3FB37E831
+:10E470007D8AD3FFB2D4DE4629C3BAED544AB85CD4
+:10E480004EE5115E96EABD6E2D685F4F6906AEE3FC
+:10E490001B7391EE865B4773FE1ACE7FBA653D1FF4
+:10E4A000E67C3B1C7F1EDBEE51A5ACC1F53D26ECA6
+:10E4B00083E529E955C8C0B700AB39BCC3EC3F9A26
+:10E4C0004F273D3CECA007B3BD39EFD3F1F5E9E7A9
+:10E4D0007376F8FAB6A2DBE8C6C4DB3B2733CBFB86
+:10E4E000B49013CB205957307EA8BE52219E1C53A6
+:10E4F0003C086F678F4272FC9D1D0AD9E94EB9B086
+:10E500006C187FFCD70AB73F96EDD93B05E5D73BA2
+:10E51000FBFE55D021A7F365BBDE702785FC4F5964
+:10E52000E53FF697613D5E13702F7F2A737FCB77AF
+:10E53000BD97B1BFB7D5D83508FFDBBD2E48B22E89
+:10E54000DEEE5132C637F6292E5B1CB73334EDB5FB
+:10E550002C8C6F86FD3ACE7BCDEAD8AB49B4435EB6
+:10E560007601D981AA71D4C3BEAF09F969DF7B4DA9
+:10E57000F806D02D7ABADD8127351A273F588DC489
+:10E58000AB78EC3565F3475D9A6C831BD46421C688
+:10E59000537E5DFC4715FB7D11EDBF7306EBBFA8F5
+:10E5A00042472EEBEFC59864AC820CF12947FFF18E
+:10E5B000590AE8563A8B95C9D6F86A78DFED149770
+:10E5C00068859634C689A0107A7E60E9F7C1360D59
+:10E5D000D26C7CA82B93ADF1554F4B4BCCC3E028AC
+:10E5E0005CA995A06936DCF8452DB23DAE2DC65F1D
+:10E5F00021E209B063E7CE9DACDF3AFC56827E0C87
+:10E600008F5731778AEC9839420EFE9BB083F749D9
+:10E61000F1FDE867C5F4CD2ACA39A974B38AF6C4F6
+:10E62000BC93DDEA620B3DCE2B5D5588F472F0336E
+:10E63000A529135D35AA9CAE5615AF2DC4F6077DEE
+:10E64000B7157227344AF32C10F3DC5FF48D601F8A
+:10E65000EB776FF137364E6470D54515C0784B5D5A
+:10E6600064D1C60A36FF82438AE163E582E6A49A52
+:10E67000983C749C6D28EF19FE1E423C32F81F6EC8
+:10E680008B52F991369D9E3BDACAE8B9B3CDA0EF23
+:10E69000BBDA6650B9A7AD8E9E8FB7C5E97DF80E7F
+:10E6A0007F02E977775B13BDFF595B829E352AE7CE
+:10E6B000B779021F9679D33E58637B7835C6514CA3
+:10E6C000FC39F15DCB282E87F60D241DF13D5AE56E
+:10E6D00072C589D7D6D620D9A5DB24B0E1739ACAF2
+:10E6E000EDC8B880E3696FE23215F7F9EB4ACBC9A0
+:10E6F000EE81B881727A9B14BFA782F1CB81A2E927
+:10E7000051ABDC0D051371D5422F63BB787C66BA23
+:10E71000CAE5531DACDA9FC5E08B9D041DE9CC9C76
+:10E72000E7BE6ABD10E5E2BE550C9E72FC2E439911
+:10E7300085CECCFE660AF82098594E0FD22DE7FF01
+:10E74000E8CCB2CD1827668EA7314127ABDBD66E59
+:10E75000B36AC6BD75A263934E18FF1C288A503752
+:10E76000DC5F6C2EE6DF7D9CCE5BFBDEA3F856748F
+:10E7700014D8E28D1DCD32F9395B0FF3B8F489E678
+:10E7800092CD1359FD6A8637F4DB73E69566252C26
+:10E7900074BD51D0D3566F3C4B1B417F758A7A664E
+:10E7A000F9902FF12D5C97EF8EFB493ED2F356572F
+:10E7B000EA5A948FAD873DFA6A36A593817812BFE5
+:10E7C000C70BD97B06D289BA951E9A5A90EF3FB4EF
+:10E7D000DEA56F3EC7C2E721C3CED7DB5A478E4BBB
+:10E7E0009B706F43B84788CB9A709BEB71A2AEB118
+:10E7F000FF1B30140FCE7E73E6358E38FE83C8774C
+:10E800001EC2C3362BBD15B668B4CF60B637E7EB72
+:10E810006CEF9CEF60BEC299EDCFF4B82017D7F330
+:10E82000B1BF8CFDE98B804B1E57508E5DA7267AB9
+:10E8300010EFD3A085CAA0F6E723BFFCD6CFF970AE
+:10E840006BE723F9C4476AAA18F5C2998ED701F17C
+:10E850007835EA2D4336ACF2DC7CFE4235E30469C0
+:10E860008A1FD116331B520EDC15CD84E781FE0BB7
+:10E87000D577ACFB491B01B89F9EF6D23E070644F4
+:10E8800034562E3E0895EB597F3B853CA956B95F1F
+:10E8900078C1417DBBC2E3474A43C88247114F3527
+:10E8A000E3581D701768ACA95BADD88BD54D3EBC45
+:10E8B000C29DF82DE2CB1DD569FFDD1549105F81A2
+:10E8C000887FCF1271FA4B95C301945FADD01B388E
+:10E8D0001FF9F99002E41727C6135F5E34CC3EE1BE
+:10E8E0002E619FEF10F2FA1141370FA3BC66CFEAF9
+:10E8F0009EDE34B2F4AC875373F0F99090DF292197
+:10E90000BFC355FEB4C4ECCEBBA71D4DB43038BA5E
+:10E910008F1E5770294D793153C067CA87993E0EB3
+:10E9200047B8BFF366B4BFB7A1FC473DE73A30FE36
+:10E930001E86AF8E84DBF0907C89D7B5E03C0A65FB
+:10E940009AC7CF0B6B641F2B3F658081FD3DD816A6
+:10E9500023389EF2F6BFFF22C6F767B98D247B1FCE
+:10E960003E79FF2DD86F58FDD13FE0135213F8FCCC
+:10E97000855C32F9ED59D70109F5F9D38540E38576
+:10E980004FEEB90DEDE7F0C9E76FC77697A4A03653
+:10E99000C0EA072B767FF97CD67FD6E532A0091A2C
+:10E9A000ECEE4F74B3FAA5AD2DD538B57F93D201F7
+:10E9B000FC9E9CA7921C1C0BB15518E7C8DB9890D5
+:10E9C000F07BE8418EB78BB6F4FEAA1A109FDA3EB0
+:10E9D0001C6FBCAB98CB5FF9B939B8F7E2297AD391
+:10E9E00087EBFAECD11580F2CAF3814CFBF14F7F33
+:10E9F000B002BE61CDAF38AA668C838D7779F8BE40
+:10EA0000D5070BBAA7E89CBC907F66FEA9D64B7CC5
+:10EA1000FE02D8F661CDFD2AB37D859418EFCAA316
+:10EA20007D09BE7F25DA5FA4A02DC78A7F96F97E77
+:10EA3000693C15B0C641827F92E399ECCC2A974A93
+:10EA4000F0B41BB5477FCDC653A75F4DFA17BAED9B
+:10EA50007038DB3138AA381C1C3E138E2246EF3E3C
+:10EA600036FE53C77F978FF07D5C67EA95DE00FA2C
+:10EA7000F97B4FC8C46F9BFA81F4CABEAA7D5EC4FD
+:10EA8000E3C6AA1A3FB773383DE6087A7CB88ED73A
+:10EA90003F51C5F7F5E1E429DAF77289EF3979FBDF
+:10EAA000BCB457918C05ABA7A17E32FF58F2081871
+:10EAB0006E8A93F63C02B935C7562E8202477E4ACB
+:10EAC000C9A05C453FBB2EF2FC38064A48EC3B57D8
+:10EAD0009BFBD8CA6103E7FF80A9FFDABCF4DCDE48
+:10EAE000F25000E31CBF30E9A4B9670ECE6FD64DDB
+:10EAF0003DCF86D97C2E3ECAF7CD9C792928F75088
+:10EB0000CE6ED4D2B9563D0AAA87E031F7372E3EF1
+:10EB10006ACF5399E5C84319928F75967EE572972F
+:10EB20003DBFF0046C9C4474D15B625B9FED173277
+:10EB300037E6FCA1FEE540BFC27F8228976F3942CD
+:10EB4000AEDC7D87D28CF651F8B2CA6CEB7E68BB26
+:10EB50008BEF9BEDFFBD0730FEBEB6D64B711B732E
+:10EB6000DFDC5CF70D986485F90DED3F0B205E9FAF
+:10EB70008C94F8F0F9ECCC9D245FCDFD7F8F98D379
+:10EB8000EA993BBFDC8C72294F269DD251B86F0C9D
+:10EB9000EE27DE5BEBA5FDFD70A0AFE759560E7EBC
+:10EBA000E436703FFBE9EA7493D55FFDB18BEBA5CA
+:10EBB000FB5DC2CEDA68DF6F66FC70BF8B7DF70449
+:10EBC000E3B45F297B459E84C3AF31F111DE972FFB
+:10EBD000174FE6CF92C983F6F883827EB60AFF66A6
+:10EBE000A3B0CB9DFD14376BFBDC68E7DFA4552A8F
+:10EBF00019F8735CABDD2E286AB1D3FF98663BFD34
+:10EC0000878C02871D9126BD65EADFB5BEE078B42A
+:10EC1000BF2A997EE4F680265BF7D79DFA77A71A7C
+:10EC2000FB99EB2CEC907020DE82F876DAB5FB04D1
+:10EC3000DEFFA2C4D288DF801ADF47FDAA719237B7
+:10EC40004E3B61089CC0E09C3C229CBF3A1B384F65
+:10EC5000B71FF0911CDFF22203797616883C8B10E7
+:10EC6000D91F1D21EE9F74B8B85FD02FE8E80D972B
+:10EC700042F33B26CAB303D092397F8CC7878EA359
+:10EC80002182F54667CED7450B85BE8FC9FCFDB8FE
+:10EC90008BEFABCD1E37F2381F88717EADC6FEBF3D
+:10ECA000CBB26FF3A42BF69EB5FCA18BEF830DAC1A
+:10ECB00087C8C735EDA53D6AEC235786BCB49C795F
+:10ECC0002AEDDF9E00BFA130FC3C930FBB81C991B0
+:10ECD000672481CFDFFB488F99F81EB0A7517EA033
+:10ECE0003E381C4861FCC45C0773DFC59C87693FE4
+:10ECF00094B9B93C6174E37313DC71BE3F08699247
+:10ED00000F05826EB6FA16DE53CB9E77CF7CFB35AD
+:10ED1000CC4F78F7099F8E706DAA3A12B6CA4D682B
+:10ED2000B6D38FF9DEF5F118DA97BF554A8C765BCA
+:10ED3000E328917E37B67F46D2C97F4BBEA290DDD5
+:10ED4000FB8C949A44FBE82AD0FEC533374653EB3C
+:10ED50002DFB1B4EBB3EC7D7F7C0729C7733B39FCA
+:10ED600060E8BA9976B959C63C106BFBF96CD9B911
+:10ED70005DCDA6CBF8BA42CCDB50630A100926E879
+:10ED8000391D747A32FBDF7033BC5D00FDF9C84772
+:10ED9000AB03632FE2F6C67F1BDE66E378FFDBF092
+:10EDA0003648B74E3DCDF719F2041E42D042FBED76
+:10EDB000BF685ABC6E021BCF5D18247B35AFA9FD1E
+:10EDC00066398CD97DBD1AFA977962FF1B1AB97E14
+:10EDD00036F7A373EAEDFADCA9BF3DC2EEF00CA34F
+:10EDE000D79D727338BDBEC46DD7EB03F1E261E409
+:10EDF0009F335E7C7AF9A7DF535B8C7919B1576B2F
+:10EE0000D9BAEC9BA5527C333C1EAE8B5BE8E1B0DB
+:10EE10005BA1FE0EBB791C643DE3D7D4399CCFE1E6
+:10EE20001CD4074C01E1FE41919CC2FC9AB5C95427
+:10EE30001DE69BAD552768D675AC2E62762DC3EBCB
+:10EE4000A61A7FB3D5DE7ED3EFE271D840F541E458
+:10EE5000C7F260AA86DCBB1873FC46F13C4B5CB77A
+:10EE6000F334E8C37D570F70BDCD38C2CBF54AAD42
+:10EE7000F616E56326E0546024BD60CFBFDCA9A68A
+:10EE800056FB111F111E6F096D91281947E989A5BD
+:10EE9000D17F981C58B095E4901A2FC371F64E6339
+:10EEA000662FABFFE15E37D9393DA1312ADA95CF24
+:10EEB000C88BBFE766F3ED7FDD03B87FD2F3D9B926
+:10EEC000748EA12774D15CA4831E099827CBE6CF4A
+:10EED000F88727FB4000E3F4E13931C03865FF2FA4
+:10EEE000C078888DEF8AFE344E79BA100BC833583B
+:10EEF0003B1F7461BE8AF1A9FFFD4B18DD3D1EACBE
+:10EF0000BCEF7C18F4FB4D7FFF627FE231E4C78EDB
+:10EF100051BF6B463EEB62702A6487C5A2087765D5
+:10EF20009E4CFC0779C1D404F6BEFA60A416F3CF58
+:10EF3000AAD50A94340C0EBEDE877C892771BEB533
+:10EF40005A436D36AB5F7548277B656EF4E6FD5816
+:10EF50009E7698973BDC40F620F22F58F8AFFAE304
+:10EF6000B134BF5F0A39DE1E8DF5C6A411D64353F6
+:10EF70001DE737EC792B563AD0A6D9E820E1B2D27A
+:10EF8000C10C460793AD741093CE860EBE8D5838D3
+:10EF9000237EE17C729BC2F96628DDB77873CA874D
+:10EFA000F28739EEFAAA9C08FA19261F68D3EFD225
+:10EFB000B0EC59E4267FCFE40B931F4E7AF9BE02E2
+:10EFC000E38B3A1F7B3606F54B33F105FA7356FA9D
+:10EFD000BF72183E990FFDFB31C77EBE0AC92C26B1
+:10EFE000427E7DE1D1D2B116BA77E269FE2C098E5C
+:10EFF00058E4D1A953BC6CC1A33690F7AC9C39BE80
+:10F000005F56F58E8885EF3A99FD8C4661976C4086
+:10F010005E31F2DD62BF07FDD5FAC7A214CFF7C497
+:10F020009B294F6DFA3B811B181D7E384AD671F221
+:10F030001DFAE247897F5F0B00DA6D9BA62D1987C9
+:10F04000FEC9873726C6A13FB68EE1FF081937A94A
+:10F05000D132E53EF58DE6FB637A943F1351FE1EF7
+:10F06000C4F79428C744BD3EAAC7D6D9260F377B1C
+:10F07000397D6FF6723B709DBBDB8BFCD55FECA5D9
+:10F08000FD53B3DE250AB7DB6678787D38B946C70D
+:10F0900078D50C0F6F775F5B2AFEE6048473073D1B
+:10F0A00073EB5380F17F7F5952C7F8BB7735243219
+:10F0B000D97DF779791CC0BBEF9F68DF28B7D4A052
+:10F0C0003856A49EF56759AFF90C35594C7E30700F
+:10F0D0006348C71DBA9FECB0F9919A3FA95386AE19
+:10F0E0002FFE39625927EF5F95440FC50BF87EC696
+:10F0F0004AE1CFD59678892F3A5ADDDB712A0B3C4D
+:10F10000D9DC0E8DD48C982F8B7E53D283712E2F09
+:10F110003D713F23790EDFCF487AF87E46D2C3F7A0
+:10F1200033F089FB19F81DF733B0FC93B6189571CD
+:10F130005F03CBB8AF8165DCCFC032EE67E0734FC1
+:10F140005B333D7FDED642DF9F6A6BA5F2251E6EE4
+:10F1500067435932BA80E1B9EB76770CF7A9D789C2
+:10F16000F5793656926BB075F445B8DFE97BE15E10
+:10F17000C0F9F8A23C6ED419BD17AE67CFAEA9A1F5
+:10F180002EDC2FF63E1AA4A74FBD0FF420EE4F241D
+:10F190009B3153B6C5F3C41C95E9F7D2E8CD353998
+:10F1A000AC7CABE7C93518BF9AA8AF32166B836544
+:10F1B0003D54B9E4314B795CF976D5CFEADFB9F645
+:10F1C000E935C8A708071A6F1D9EF49C556CC9D372
+:10F1D0002540E735FA8BDD29A4B3AFE17A21FD782C
+:10F1E000B85DFF655813453F799CEEAE44FE60F56F
+:10F1F000D39C2ECFACFE3ADC94CA1BDA6EA47A7292
+:10F20000D519D5036584FEF0BB34423F1DB046C31B
+:10F21000B3631B9097312EE80B909FD6E5E27CD923
+:10F22000E5E3CFA35E73FFA8669E978D3B4FF06921
+:10F23000972F5E87F9CAFD93658A17F4B858179817
+:10F2400084DB5AFC9B1236EEADCFAB8071E694871F
+:10F25000DB3713C685B8BEBCD34BFAF24BE37EDC7A
+:10F260009EC3CA13BE6F18A8FF3680E1473A496EA5
+:10F2700094693FF74755E3731A58F5F3A63E918317
+:10F280007184CF047FA7F07C112BAFEAB8611CC654
+:10F29000953E7C89CBA547C538DB5DBD2DB49E531B
+:10F2A0008364370074935DB02AAAD23EBC9CCF9F82
+:10F2B0006E97F67758CFCD146F92C1E3FE6CBA9774
+:10F2C000FCEF8F3DE25C5A2FD90B6E5F42CB66EFAD
+:10F2D000BB9332F1FB1ACD9FC2D4FB0DC14A3A2732
+:10F2E0009B2C5729CF7A43398FD3054257A7D04E4D
+:10F2F000B867AF8FCB87A097F2AD52E5BB0FD6446E
+:10F30000F0296BC8EFA9D8823AC2BB266B94B7C567
+:10F31000FE46DF9B239497BD01C4BA34F37866C7D9
+:10F32000A84F7F85F1DB355FD70C715688F21EC977
+:10F33000B491F1DC6EFFBE00C2F315F39C51DFEA1D
+:10F3400000ABDFBE5833701DA66835751827ECD0AA
+:10F350006ABCC85781C9B5DE45248706F292E93CEC
+:10F360005B7B39B757F13BF225B4C37E3CBF3246D5
+:10F37000C8B24076A584764E473D858D306FD796CE
+:10F3800067D99E7319E5B12BF37308CE0E8879B156
+:10F390007EB29EC79DC704BD69B4E3C698F1434CD5
+:10F3A00031B6F811B937D9F394F39B55DB398ED1C7
+:10F3B000097B394FF805798E7CE64F3DE63E8A1D84
+:10F3C0004FCEF9E6461ECA467873F160B23E743EEF
+:10F3D000F7452A1B709E63343FC11DD55657A3FCC9
+:10F3E0001A0D2DAB90EECE1A5E079C53CADB7B71D3
+:10F3F000DDA7E82A9D5B381FFA5763BF1B049D7782
+:10F4000015DBF564CAC3FD06C68F95C88F18E74A99
+:10F410005AC6C7386FD232DEF8AE1C5B79427781AC
+:10F42000ADFE395B4A6CDF27A5CEB57D3F6F47A5A2
+:10F43000AD3CB967A6ADFEF97B6A6CE58AF465B6AA
+:10F44000FA171C5C602B4FEDFD3B5BFDE9AF2DB661
+:10F450007DBFB06F89EDFB454757D8CA17F7DF610D
+:10F46000AB6FDACD4EBD58EEFD7CF6B207CF75D945
+:10F47000E282767BDC694F7BFFBA465F8D722DECB2
+:10F4800026FA56518FB3F28ADBB93FE39D6DE82827
+:10F49000574A841C0D056317E2BA5587BDA40FD4E3
+:10F4A00020AFA706E792DD31760B934717A015082A
+:10F4B00003DF032897DB92F152D720DC3EAD9BCED1
+:10F4C000285487EB00E3BD667B558B412284E3E93A
+:10F4D000DC9E61DE22D6F3E9ACBD651ECFC8321DCD
+:10F4E000E9EE677ED74316BF6B383FCBE9579DA93E
+:10F4F0001F3556063F3EB74BF1167C96B7BC54837A
+:10F50000E974CCBFFA0AE261933BDEBC1DF7434AC3
+:10F51000FCB42F66FA575DC53DC417FDC52AE9172F
+:10F5200050F5F20596F8569797CBFB80F701F2EF6E
+:10F53000D492190775C4FB2A95E20E1B241E1F499D
+:10F54000B27540BDB66DE6D1F7FE91BDF79678C7AE
+:10F5500078993C329E75C770BFF33E81D712ADA239
+:10F5600086595CCCBE68D887CF893AB333D8B3AC60
+:10F570006CF33E7CDEE1E5F974E71A8FD5A02CF13F
+:10F58000CEE6F69F32C59D5A8DEBA7713886A33320
+:10F5900035670BDFAF2A55DF427A436BFB943C485B
+:10F5A000073EA403899E443FBE4890F4860F0F7720
+:10F5B0006159955201F63D521A9330CFA23ABC855B
+:10F5C000F6557C69BBBDCAFCCD2EC46BA4DEBEDE85
+:10F5D00001EF3682AF5DE2F1D7AE6CFD851A067F92
+:10F5E000575E490EC64E303ED16091379B85FDD6A1
+:10F5F000E4934DFD4FF24646DE983A68EF30FADF6D
+:10F60000228F47F8BA01E596EFAE6E407AF7696C43
+:10F6100035D1DEFE5692E8DFB4776F11BC555BD270
+:10F6200044FB5EEF472AC9BEF5B5FE2423FE7C7D70
+:10F630000AC42E181EAFE1895B49DF43895B47BBD3
+:10F64000A25577C7B667900786D007EB30CF03E1A6
+:10F6500011791E5D021FE6BEDBFB66FE93D807BE76
+:10F66000251B6CFB7FB7E4558E1EC91EF731BF2FDB
+:10F670006181771D1B07F1D271B2A12E4EFB80C0B4
+:10F68000CFA57D56BE9DCEFF0AFFC510F6CB0C0F51
+:10F69000C7EF5837909F3007E31717A0B7F9E53A3F
+:10F6A000E44B33DE71C49B43F83792A0B490BDE2C3
+:10F6B00032F5967CEA7C8259779B714A3279B95E41
+:10F6C00063FFEEC57314E3BBECE7932674DBCBE773
+:10F6D0006CB19727A5EC6566351F42BBA001387E4B
+:10F6E000CEDB61FFDE60C6F96AF9B90A2F1BF91497
+:10F6F000D7BFB673AC20F4BF194F2DEA4957A37892
+:10F700002D5C69D7AB0542CF1738F4676548213FB8
+:10F71000BFFA60643FDA8F66FCE510267F59E2A9E4
+:10F72000661CC529CFFD873703FB42FE72C2C3E3C7
+:10F730000B09E6DFB4168AB845117FBA14FDC585FA
+:10F7400064A7B59C83F2E9696FE2032F192DF67364
+:10F750000FC7EBD45F483A1F276119E7B6B2E497A9
+:10F76000F8F453944762C6314C3FFD642036CFCB4A
+:10F77000D67D83F172CBB318477ADD03D8CFA5CA03
+:10F780000B07DB587945914A798FDAF49BBEE7C7BE
+:10F7900038207E67E5EA627D34D1FF732EF2D7D739
+:10F7A0000A7A36CFE398718F6C1FB79F433ED32EF2
+:10F7B0004AFA455EAB1FEDDCF37630D96CD3733C6F
+:10F7C0009E66C6CD26F7D8BFF78094ABB1F53BBF98
+:10F7D000292573BB2A16ACB6C4D5CF15EB356561A8
+:10F7E000FADE85ACBC0B5295783F4485A00B63BF15
+:10F7F000FDFCD72890E89CC0A8438A9162F5A73CFD
+:10F8000065FF5EEE381F76AEF3BC9823CE1B52E048
+:10F81000BD456CBC8D7A8B84F273E34266C3B3F250
+:10F82000B93E912F3C112622FD5DAA048D34E2F7EA
+:10F830001585F486E78D735E5D84FAFC259E97A29C
+:10F840008DD737D7B2B2F62B85F49316808A8AE02B
+:10F85000605CF8FE5306B4BB06E34C3BD9BA964E47
+:10F8600040FFDA0BA8577EC2D617CB3DCC1FC7F29C
+:10F87000E3CC1FC7E76EE68FE3FB9F317F1CCB7B9A
+:10F88000983F8ECF9F337F1CDF3FC5FC712C2F0F1D
+:10F89000545FE28C5359E3768371AA3EC98C53A11D
+:10F8A0002839EED6699D07E255091EAF3A7D3F31F2
+:10F8B000B31F8A070EE947C405DFBDFD778FE079E6
+:10F8C000E9A5535777E1B957AFCB8C8BF13C08339F
+:10F8D0008FD9E4BFA5BB6FA6FD6077FEA1165C8F34
+:10F8E000DD5541BA53C8ED4A68281F9DFE97E97758
+:10F8F00039ED5FF3E9D4477EB4032E403BA99BE288
+:10F900003EEB5D5046E76025BF817CE18C439A7CED
+:10F91000FCA2AF24E3F9A5817C58119FF140CA8B6A
+:10F92000F132B724E629F2354984B12E36203F5B07
+:10F93000F28B83E5698A73048331B2BF24669791A1
+:10F940009DA625A21887EA1C26FFF541C1A7ABF2A8
+:10F95000DD746F44673EDFFFAF2D34A2D87E4DFECD
+:10F96000B4A8351FD6CCD7DD1F9AE6EDB3F4B72285
+:10F970005432A29E52985ED547D0AB8A87E7ABAF90
+:10F98000D977A117F390D70717F7A27DB53E1AA133
+:10F99000F3EA7BF3A791FD31503F3A83F29595202E
+:10F9A000B75B95A897EC5615E75F3E58DFACD72AB2
+:10F9B000E433633F8ACF05823D54CFA3C629FEE1DD
+:10F9C0008900ED5779BC3C5F20C8FC6BAF2D6ECA37
+:10F9D000C7BDD9C7E5DB7A3D11C776EBA3AA8EE296
+:10F9E000687D5925E1798DC0F39A3C53EF1B646F14
+:10F9F000F4083968F6B346F8EB6B9ADD6477C55BBB
+:10FA0000B363B5B9947FF903E4BFF5C187BC98CF60
+:10FA1000EECEAF1AB1DF27C5FA0DDFEF1B35B517F4
+:10FA200050BF3D3E36BE3BB458C37E5DC3E4D91FD4
+:10FA300014707E5EFB92614EA3FD2E30F56D2A6A36
+:10FA4000DD27763EFD68275E30B4DD52BD6F2EE6C1
+:10FA5000F9AA90ACF32B43CF292CDBC3EF9DDAA49A
+:10FA6000F692BDB3E9A494F1BC43965F12CEFE803A
+:10FA70001F6EB357C6087E1A23BEEB68AF14A35F90
+:10FA800069B72F2E38682F4FEDB597A7BFE6B4574B
+:10FA900062AFA0BDD228E45D2F93CF3C69A25F4541
+:10FAA00039104FA6AA11EE06E85985FB942E11676E
+:10FAB0006E14FAEA0AA1CF5C7E1E971DD3ECB7F94B
+:10FAC00089E6FD1985A2FFA2DAFD37B7A3708D9BE9
+:10FAD000F68F4EFE65D1BCC7AB494C3AECA0869878
+:10FAE000FDFCE9150E3BC7690F55ABDB29BFB2C062
+:10FAF000117F30F729719E780ED739FED98E6BF6BB
+:10FB0000B795E92DB457CC7B09E8DE2ED6BE484D1B
+:10FB10004B06C353410B50BEDF989510DB9E818E80
+:10FB2000A789751F82B7E42584B739E25D4190DF6C
+:10FB30007B5250ABA4F462CCDFEF21FDBDE0263652
+:10FB40001FB2974FD13EB4593F27BB672FEE136EBC
+:10FB5000AD97B8FF9804B243CC75DE1AE4E7651A96
+:10FB60002E965232B66F29A1F109AE92C1F5657891
+:10FB70003AC2F1C4F3CBAEACB39FEB6970D81B268D
+:10FB80003D5CE178FFBA4F23FA30F9E0DD0B5F9B73
+:10FB90003896C1B1544AD6059433D79316FE709D5A
+:10FBA000423EC4BF8FA2A9107FECF3FE54A3FC8099
+:10FBB000ECBE078091E4657E48D6CE02F8377FFF21
+:10FBC00079122B37F8CB3BBA2EC6E389FD3F42A30F
+:10FBD000CCE3A9B8B4AE68B0ECF75F4CE588188701
+:10FBE000B91649BEDE967B0A18BCDF15F9011B6207
+:10FBF000B059C11C4B59DB6C140FB6CBC176D2087F
+:10FC0000EDE2B059CDD02E68B663E8EA34EFF528BE
+:10FC1000C127FF2E0B78ACE3AB88374D0FD2B99DCF
+:10FC2000B9AA86790F5F148E51A79B770236BBC69F
+:10FC30000F6DC7C05E65C22F67863F85DFADE3BB32
+:10FC40004680FF6F8D8FD3F5E716DFCF1A3E567DC6
+:10FC5000F5A8E1E78B70B9E87E0C3D285BFAB9673F
+:10FC6000EF2714BF56AF053A97A3BA629AC1E8BC12
+:10FC70005CFB36F9E16A76AD8676C03A56463B6063
+:10FC80005D4F37C5A9CB4BEFED42A22F4FFB01E5EE
+:10FC9000C164D0B277B17E276B2A66E2807AF17EAA
+:10FCA00019E3DE7039D0B990ACBD7E7E8F45F1CCC2
+:10FCB000EFA37F949DEDA53850207BDAF7B9B1CB47
+:10FCC000E3C126FC81EA43351827571BC040565430
+:10FCD000A5145423934D02DA87F0C776DF86E72B0D
+:10FCE00099E223FD44773BA05E1571F1D19C64A09D
+:10FCF000CBAD35A09F907C5EA5F8FB68BCF2861169
+:10FD0000657979CE6684A73CC13A90107E1ED79A59
+:10FD10009C908D34EBBFF23DDE0EFE9D9F0760BED2
+:10FD200044D313C141BC9A7265B488974717DAE38C
+:10FD3000C9D0CFE6CCDA57FEFB821F603C61D410FD
+:10FD4000F9CDFD6BF3DE9CACF720FE04ED6BDAF52C
+:10FD5000865FDC4FE177DC7B302E683F8737C46FEE
+:10FD6000F8569CF480070CAF9BEC8B85643798FEAB
+:10FD7000C856AC88F1FF22E079D9CEF6D3787B88DB
+:10FD800072FFC4E367665E25FBBEC41FA37C1F0F22
+:10FD90002B333C4A6EF0E6B3F705328F8BAC9240C2
+:10FDA000C5F2E07869DAA75F2B195D8634E8FFAE0B
+:10FDB000D10CCA1F809539367BD9CC435D7163F174
+:10FDC000E81CF6CC1A3CFFA3213DAEC82B25FB391D
+:10FDD0009CDBF7F7285F8FAF5F7FA917E529E62F38
+:10FDE000CC04F8ABBFA323C9E4ADE7E331A05BECDF
+:10FDF000328FDA427130CFC7636DEFD36DF6F38285
+:10FE0000B1A05C8BE3E461F23EC683416BC776D55B
+:10FE1000603F17E8F938DF66A70FF65F687B9F66DB
+:10FE2000F68CF53E8AE1FB0F805E66ED7FFC30FDCF
+:10FE30004F74F4AF65EC7FB0DF5C5BBF1D2A8F8F22
+:10FE400026237E5A77A73D3039505310C81B217E98
+:10FE50001FE0F1C7B5D1168ADFD700637846279730
+:10FE60009C3CA2F0F36B40761B14DAE3F735827EFC
+:10FE700065461148BF97A8F67BC06683F35E30BB2A
+:10FE80003DD48B8C827E65A8AA97E2F89F0475F416
+:10FE9000BF86B3977BDB80E2C7B3037DB7E03EF557
+:10FEA000A51B1E7075CC10F9AF05CC8ED8D0732968
+:10FEB0009EF3EB15E7F33A2232E1255E339ACEDB6F
+:10FEC00098FDC4DD3001E5615CE6F909F4878DDF5A
+:10FED0009B57F0D0FA0CF8739EE76C8849F1520BEF
+:10FEE000DDF4CA0CAFD6F1E68CD9AE58E611F7C0F6
+:10FEF000541A4FD8B903E38DFA7CE3BD24E24EE6F1
+:10FF0000780D73EDF36B706B34BF06C1BFE6782FCD
+:10FF1000E1FC32E0F7B4E3C99C6E06C6FB927D7E3D
+:10FF20000D1E8DE6D720EEF51D186FD4E71B6FADC3
+:10FF3000AB258176DB6689F3FFDD817FED40BFED88
+:10FF4000FDFA1551D207C22EBE021BB07A57A87C0B
+:10FF5000BCF985DED42ACB785B991C88893CF7985C
+:10FF600007F337342AA7DAA2F47C88D9D931CADF5B
+:10FF700028A3EF8FB41954DED136839E663F6533D4
+:10FF8000F83D3393664919EDED5F06B8DFB8395F88
+:10FF9000BBF66BA897AAFDFCFCE38C8B2066B17FB7
+:10FFA0009941BCCF87FB2F574305EAB6895B38DC04
+:10FFB00091DA51295C3F7FC5FEDE3656F6B85C3AD1
+:10FFC000EA53C60BF14C7EEADE00F7C33D6E2EEF1E
+:10FFD0006126BFB770BED02BA0D44B2EC4C715D995
+:10FFE000B4DFBFA03116D218DE1A25E99552A1A7B9
+:10FFF000F0FCCA5562A99C767E043506EB37125395
+:020000021000EC
+:1000000052781FD15585079B502FC74357927F10B9
+:10001000670D73583F57093D59FD860730DF012EA4
+:1000200075131C8D8D767B7EB32FADA17DB2B92269
+:1000300002B83E0BEAEDDF3D6ECE8771C73D05F39A
+:100040004F736F01DD9D95218FD4199F7C32608F96
+:10005000439E80F27B6AF1636164C47B0B5604C0EB
+:10006000BCD73263FCC884E74D94635391DEF650ED
+:100070003CCC84AF404D4928AFC734EFB1E53531B2
+:10008000C492316CC6E141D955817E88733E5BA52F
+:100090005DF923DD535200EA5B7D65E21E4F69E89E
+:1000A000BC7F1710F9B703F39EF5622964E21F1EA7
+:1000B000779D7F503156E9837831F1F03FCD479DF0
+:1000C000018ECF17E77C50C5FDB742DB7D99E63D39
+:1000D000C0570E9455502DF47CC51237D93310EB10
+:1000E0002F47BA3B747180DFDB66DA2FE9D765B43E
+:1000F0005FBE78FFB1225BDEA6E877B8F572E61145
+:100100005ACE7D0EE6B9637E89C4F7B10A30CF2D91
+:10011000CCDF1FB1DB99B63CB7357B7F28619CEF04
+:1001200001CCC7B3EC5B8F61FE3CCACDC29BEC79BE
+:10013000754EB8CCBCAA8173B3B31AB55D3ADD93E2
+:10014000D88D17CF746D49C6C1921F699E1334FDB7
+:1001500069E7F94025C8EFCB8B8AF316CE78F06DAE
+:1001600072522B96301F35E5AD66CFF29C848147E5
+:10017000D36F539275F85E193DB319F1B0B0F54ED7
+:1001800003E3775A6EE6B8F442A1BF2F0A72BA3978
+:10019000EC4A17611C3B91537351302F43FDD66FCE
+:1001A000517FB387B97FBE51F4F380D0E7CEEF978C
+:1001B00007795CE59AA532DD67E183504A2AC67D5E
+:1001C000E3EE19742E6FD95623D3B9B783E144BD3A
+:1001D000151E5F293F6F0DD07321E26BDD5F1EECB2
+:1001E0007994A132E72F4192A3390AEFD7D2BE31D9
+:1001F00053FB673EF92D9D537E06CFA9CCC4FEB6B6
+:10020000CEC5F8F7A6813224252C678B72F2B6B9D9
+:10021000E8EF0D962BE6566319699011D9ABC1DA58
+:100220004EA4974D120862BC94D777F1FABBC5F77C
+:10023000D997BDF37D3C970BD3DCE4076E12F688AB
+:1002400009DFEB419E37F3FA69F079ABF81E447C85
+:1002500046CE0A9FB766C2C7EB39B1DB8253B19F66
+:100260001EBA17D2F717EF4ACC23FEA73630BEC608
+:10027000E6F080B1FB87F700B5FF5670EAD0F6F3E1
+:1002800072626DD86F70E9119A5FA83488EE0DAC78
+:100290009B0ED44F0638D666EAC75CD774169763B0
+:1002A00027D076CEC375E5F69FE2E98DE2FEBF5614
+:1002B00075FF2D1A93239DC5DD4D99E8FB3B21BEAB
+:1002C0004F9D3D4CBC7A97A0C757B5F877118E76F5
+:1002D000ED5EBA4FD52D71BB61DD8C3E902CED7E6D
+:1002E00015E2F519DCDFC3FAEE0BF93DA72186779D
+:1002F0004C300B5571F8D7E98700F3BA43D14394DA
+:10030000171AAAEA237EA7A30A059CAED05FF30AB8
+:10031000FB6C57F0DAB94817398A49777FEE443ACF
+:100320005406CB4497DB7378FB97427FEE4C3291B7
+:10033000BB8DD92F78EF46B280E78D38E7F72F21B4
+:100340004E1FF787638F23BC43F0E9E9FBFE3DAC0A
+:10035000FDA609FCBCCD6CB9B7E97AA4CBCB82640D
+:100360007FB1F74DD673C86F0A7CBD19E4F6D3A6EA
+:100370004FBCF4DDB91EC3D1EB0BA2FDE7A0D7172C
+:1003800032D109A3D77F477AB3D0EB0790995E0F9C
+:100390000D43AFAF607B275E9C6505625B707F5647
+:1003A000FD74EE0EEC4FFDF2AC2D8FB2A7F2E95DBD
+:1003B000495A4D43B29D2F35C7A99012FF11B4C8B9
+:1003C00077F33EEE1B83BCFF21FD4E9FB605E5D8BB
+:1003D00019F47B2C387568BF4F0539BCB32F0B2639
+:1003E000329D1FDF1252E9FB43213EFE707C7330C9
+:1003F000C4FDD9E1F8E65141578C6FFE7A267CF3B3
+:100400008741BE7187F2CE846FBE4D4F5F29E71BD7
+:100410003A863C7328DF40F2D54E94AF9DC59C2FA1
+:10042000466F7AB313E31C037C943C41DF95C132E1
+:10043000C963938FFE73D309E22367FBF030F75251
+:100440008D15F33E188E17E13C62E769EDFC9C4D7B
+:100450001FE9EDEDD0BFD74379B63CAFD59F4CC671
+:10046000B8D9D00B78BE7FA2C0C336F4C1D0CF9923
+:1004700026E24C6A2F2C080DE5E75055BACA7A9F40
+:10048000C0D362FC0F43F1C9A1A9385EDF24B4BF19
+:10049000865BA74A31DE3DD9B1CA5006FE3F9D1E9C
+:1004A000BA26C4CFBB5E23FAC9F98BB705ED4F2737
+:1004B000BFCF5EF6F33F3D32423F8DA27D7DE873B4
+:1004C000F37F7D2833FF5F1EB2F37F15DEB799817E
+:1004D000FF1B33B567FC7F55E86FCBEF8B4219F8F4
+:1004E00072E619E2FB6181EF87BF20BE570B3AB974
+:1004F000E3F3E3FB8E61F07DE719E27B7528837DF2
+:10050000C1F0BD2644F6CAE3047F480F521CBB6B02
+:100510003AEC964A32C2B1C1DA8F57E7FD30BC7F60
+:100520002031BA9FFD699791E99E19D6EE5E2BFCAA
+:1005300066BBCA9066266FDF8CFEF9035F0E52BC65
+:100540009FE9C7FBFFC674F050263A982D7339F423
+:1005500041F0B14E8CB37D81FE7F92A9FF6621D719
+:100560004F6717EC1574C1E6FD4468EA50F9B75DB2
+:10057000FC2ECAFDE1C45321C257DF3C9457DBEE89
+:10058000C891301E55184B4BE8273C2EF4D87921E2
+:100590009D9F6710EDB6A96909F359B6B568129E1B
+:1005A00037B2F4F74B1C6FB8FE9C7030F89EC3F165
+:1005B0003F0CC59EC767A598DFD9DA490DD9B19719
+:1005C00043A47FE287486E9F6397DBE63CE478377D
+:1005D000E5BDF86664FEDD96C783AAD063F1DF5BF4
+:1005E000E5FF2B0374C5FB3B5BFDC3E07B2BC4F530
+:1005F000CAD14CF039F1723A38F34203701EC77E0B
+:100600009D7ACAD99FE9B79AEBE4469D648DEB0CBD
+:10061000E8BDC45F897F3B643A87345FC893F93390
+:10062000B285DDAEF9B1FF07449CFC819BEEADC6FF
+:10063000FDEEED77691588828266AEF7F49BC652AF
+:10064000FCD317966C714CF339D0DEDD3309EF190A
+:1006500067E386C2ACDE25B3208D7E6316DA0D1407
+:100660008FD0E877BB723CDD518C9FAE93BA9B165E
+:10067000A35E9D17E4E74AA28DA7B9AF6DB58D6E55
+:10068000215A759AFAABA8BE16E8A6FB2FCEB8BEC3
+:10069000A7BB29537EC994B06CE275527824BC463E
+:1006A0002314D732F13B741CBE7ED5F11609F11D1F
+:1006B000AA92343C7A15627482F6925CDA4BF94C59
+:1006C0009757717A01E6978C7C7F46A769AFCD0A70
+:1006D000E77D71B8CC7AC38F27EA39CE2BE0BE17FD
+:1006E000C567835C8E5145563E7E303763DCDF7CC8
+:1006F000AE6DD30A5597B5FF14E179ED40FEB41104
+:10070000457BAB15383D42D44B7618DDCB6E59CFC7
+:1007100084589FEF66C5FF3E4CF019740F2168DACC
+:1007200019CD87B55B4CED54D62E74E6ED867F9AD5
+:10073000BF5767E871CBBD6726BF8E4E2401EF9986
+:10074000F1978326B1F58F84CC7D424E07DF0E9A58
+:10075000E5246D92C74BBB795EBE6ED209972B5ACA
+:10076000A0272657006CBEBBEE4BD149ACBFD2448C
+:1007700014AFD067E5032AF9E1BC0CC9BA03FB0B3F
+:10078000917FB4732583E9A9F6DA03072F067E5417
+:100790008A7E4FADF600C93BB38C175294B1B27F3D
+:1007A000A01CF34659B964A09CC4F236A12737DFD8
+:1007B0005D7BA03D48726CA3953FAA051DFEADE987
+:1007C0006FBBDEAEE13983645425BB6A9D831EF6A0
+:1007D00084F97D2C93B5C4365CD7F977F5AB787482
+:1007E000C55B1C09213F8C8B7E90C4FBF2C6CD12E9
+:1007F00069AAA5FC9E86EDD195C497DB715D80A7A3
+:1008000025607C72707D5299D7A72C45EBE3D7F910
+:100810007719CBE46FF3F85BA08CF3B3E6E1F1BD9D
+:10082000C704BDA6C33C7E9416F2352BDA4EFE9467
+:10083000B74EA6F871569D6CD31BF48B77D44EB58A
+:10084000DDFBFF7A4EE2A9B0452FB01AF132360F28
+:10085000FFA4480EEEBF5497A92BD1DFFE9EB0FF38
+:10086000D83A3D40EB5411F127486EC79FB5CA8F67
+:100870008175137839DDBAFDB62D61D4BA865FB7BC
+:10088000ABAF5532DE93F6DB30F75F8F35FDE7FD1A
+:10089000389DA5DE7EBABFBBAB7415C561CDB8ABC4
+:1008A0006777757A8C3E980FB83A109E854FE7B8F7
+:1008B000BF3DF95D8DCE897CE2C9B89F7452E0F9E5
+:1008C000505B13B5630B4CBFB7721D4E85E7B1D9B2
+:1008D000CEF199E711BE0A9C181AE38B2E4739B462
+:1008E000B849A17B1BAE037B3EC557CDBCAF563389
+:1008F0003F8EE77D25207B2EB2E1A2A4E3F722C044
+:10090000988BE7E887FC8E84D8DFFABA236FE29AE7
+:10091000A64546ADA8F73EFD3F45F369D4B9FC6D49
+:1009200034F8FD3D57C5AF356A2DFBD1AF7EA664C7
+:10093000CC9B9C9765E2236ED44E188A8FC571C9F3
+:10094000ADE9A7C7CB99E261915A31374F1F8A07AA
+:10095000E7FC19C636219EBFCEF08C76E770F860B2
+:10096000F5683D5EBD56A1DF8F99ABD4BB701FE427
+:10097000FA0689F698187EC3222FAEFE520BBC4EA3
+:100980003C3AF175FDD340E706AEFF4E88E26D2F8D
+:100990009BF8495F42FB17E6FE89659E4778FE9605
+:1009A00046F35C30A3E217786F42A25DA2FB1AD92E
+:1009B0007C6DFB808B219E85E716D8BC8F0CB3EE37
+:1009C000B6FD40277C4EF87D42AF38F7C5404D97C5
+:1009D000A31E9C9D25F605A78021F6C7B2281DB74A
+:1009E00034B3BC75DE3767D2D975AD0D03E362FF52
+:1009F000122406CA1A9ED77A4ED97415FBFB8A2890
+:100A0000FF1DC3F8B5B91DF86D3E98BF2F14A3FDA7
+:100A1000A6EB04FE1A98C787BF7D7609134EB8AFC0
+:100A2000373FE6D38396791EEF96EAC439AAACC65F
+:100A3000C9D82EB957993214DE1551FE7B858C0E1C
+:100A40003FB0D2A16F02BF47D68917135F8B06F163
+:100A500032E56CF0F22A2ACE3CDAAF213BB75FF2E6
+:100A6000D27978731F87FD35E966A2F3D6AC62614F
+:100A70000FF0799BF77701B4907DBF509CC73AEC9B
+:100A800082A6C7827C5FA7D222B76ECBA9BE35CB28
+:100A9000E2579BFB3AE67D51263D7FD51B4C2B9CB4
+:100AA0000E6DF7410DE63125288F49C9BA49477CBB
+:100AB00074E1A70BC9EE5985FD2B01BE5FE57BEE06
+:100AC000A75D57E983EBB7FE6B4F744F6565FFD7A2
+:100AD0007F93A44EF51CC25B48AC5BB55837133E00
+:100AE0007F397F6F593F1E3F2B13F133B18EC3E91E
+:100AF00009731DCD75433B0AE9D757A67E9AE9775E
+:100B0000F7607F553FF26922AA520E5D427AB383A5
+:100B1000EED9027D1BEEBF5FD7EAB2FDDE5202CFF7
+:100B2000E963FD753EE19718D47E713E6F0F65DC79
+:100B30006E1CA0FB246B6FC903026F7814AE5B1FA1
+:100B40006B8B7962ACBF51A8EFA1CB324EC9D0718B
+:100B500087EDCFD14E19D837310CC322AF1FCBE26E
+:100B60007AF278B4AA47CE107F319F8BBDB985AA9F
+:100B7000253FEC48BEB729E3EF0689FE06EE8D1B44
+:100B8000B013DF39B07FD6A09DB8C1F5C703078B7E
+:100B90002C7622FCF100F9ED03E5B3B3135FCFFA35
+:100BA00023D9891FFDDE43FAEA789D9FD621B775C8
+:100BB0000EFC079EB755F1B7FCC8BEA77B6FBCAD56
+:100BC00063683E92CA3087BF07A61B12E2FB4896B5
+:100BD000CEF7637548871870B9AA2121BEEE15FEBD
+:100BE00028A3B349D6DFFF3D22E66B8EE3F1421224
+:100BF000CF199BFD323A584579A5F5407AC4DC8778
+:100C000035F9D9ECE7589664CBAB3E03FE3D9635FB
+:100C10007528FFBE20B7FCE11FD17E7D5EA17CD090
+:100C2000AF446FA7F757B75E4FCF6B5B6FA4E7C7B3
+:100C3000423FDF2A253E463EED6DFACD576E63F406
+:100C4000BA7CB787CE952DBDF54F77237F7A5BD9D8
+:100C5000BA63BBAF5FFF9DA9ECBB7B824CF66B57C1
+:100C600011CFE770AF9278BC5F77D7ED66CFE670B3
+:100C7000F544CD02D77F01C39B58310080000000AE
+:100C80001F8B080000000000000BE57D0B7814D5D9
+:100C9000F5F89D9DD94792DDCDEEE6B5900713C2DC
+:100CA000230AC44D202128D60D011A2B81A0A8515A
+:100CB000826C0884008104B4B2552C1B021830D613
+:100CC00068B562B57C8B85D6B6DA06A52D6D23DDB9
+:100CD000085AA81463B50A562020B5286A228FB294
+:100CE000B6B6FEEF39F74E7666B21B82EDEFFBF734
+:100CF000F7FDE2D71EEEDC3BF771DEF7DC7367EB46
+:100D0000EC5347390A09216EBB811411B2CA42FF64
+:100D10002D1372F1E8FDEE05C984C45BAD1EFA84A3
+:100D2000989AB21F32D0323920921D148809647EFD
+:100D3000C5580ACD0CBA1D122185000D081D00539F
+:100D400008B184054292A09DC7D368A56529401CBF
+:100D500000C3123E370942453B7DFF0BF8BB2E0214
+:100D600095FE2C619190F1309EFE7D133EDF249B19
+:100D7000CAE07D3189CD43793F9BBF9FCDE76309B1
+:100D800027B07924E9FBB1B3E722696CB7F69FC7B6
+:100D90007D89A5231D741D7576EF288084741B2B17
+:100DA0006C84DC61FDFD61218F428B35245248FC4F
+:100DB000C68FBA7309FE7D311CFEBFCAF1FE184210
+:100DC00004D22D7C41879EF9B9101A46F11757229B
+:100DD00006D765532838CA274CA0CD4A8C1EC06759
+:100DE000D78864DB70D5F8C50E01F1F7BAE4B0C15D
+:100DF0003C2BA68915C1B1D87DCA1CE8675A4DD1D4
+:100E000066369C85A412329FFD9BBC2E6F6F194ED7
+:100E1000EB0301A36724A5E37C4B2008F39B4FA4BD
+:100E200040B7059B085F080865A988BF47E73B7F77
+:100E3000AAE88DB36BDA912FE83CC97AB26F04ED62
+:100E4000FF0E810F10A065FADE315E3C3EF5DCCD71
+:100E5000B08C6EE2300DA7EDEFE8AE9E41F2B0CA65
+:100E60000AFCB488B79BEF379EEAEB97FEAF3AA037
+:100E70002D2F28CE7F859281E225583601F8EC0A85
+:100E800003F2594D8BB6DDA277AFFF80D8A15FE9A1
+:100E9000541FBE619EE461C66FD39A1D32C5D3381C
+:100EA000878C749F39F5BDA9849667117233F43B22
+:100EB0006BAAE808D1D6AD7E03F1D2891FF28A4130
+:100EC00081AEED506EF781EB006FC5467907AC350A
+:100ED000973C785332D48F77009E2BE0D9106C4F1B
+:100EE00008B4735B8223E9B32EEF7BD61A15DF1D9E
+:100EF0002A7EEF0A1FA5D75603A98BC64F8434E17B
+:100F0000BCF6DD138FFD1C7F54089AE9FCA7899F6E
+:100F1000FF61229D4FCD7D468F59C6651980AE3346
+:100F20003C4C1E09F15AA7517CDE4158F93D525103
+:100F300014A2E3D7E41F2D31D37E6A360828A70A0E
+:100F4000FE29BE4FAAF1E66BAC480CC98877CD7379
+:100F5000DA9909F899E2F9640C3C9F54E3D9FFEE61
+:100F60009171FB54ED363B6CC9C0E7A480147C4101
+:100F70005173814C4E1C4FFAAF5B8117D71E1EB7C1
+:100F80006F24218F12EFC3A87748B754318ED2490E
+:100F900022DE687A60BA9DC9C134F123A4CFD96238
+:100FA00051067C1DF27F68A51C460E7D2E96019E83
+:100FB0008997369A1479EF870E13E279AB89780115
+:100FC000CF5B875A824DB4ABCE7BAE4CEB46FAC8B2
+:100FD0008F4F063AFEDE4876C8B1E76BF38B6404A8
+:100FE00065CC72BF8050A1DF307F1C91C647DA0DFF
+:100FF00023D1E7BF1BE498B64F59430C321DD719D4
+:1010000020DE6014BE50DA2DB7F44E9708B60F39C3
+:10101000E9FC56C886A040D79B2FC88CBF8D8DDEBB
+:1010200074DA54EA981D4827300F11E721D3F949A3
+:10103000747ED9FE042C0FF72721CCF13B118EF0E2
+:10104000A763FD487F0EC251FE6C7C3EDA3F06CBA3
+:10105000B9FEF108AFF0E723BCD27F0DC231FE52DA
+:101060006C37D65F82709CFF067C9EE7BF09E15516
+:10107000FED9083DFEB9589FEFAF4158E0AFC6E733
+:10108000E3FDCBB03CC17F27960BFD2B1116F9EF8A
+:101090004538D1DF8CB0D8DF84ED26F91FC0F2D5FA
+:1010A000FE6F23BCC6FF30C2C9FE27B11E1410E07C
+:1010B000219ECBE303F242079514E07019F83896AD
+:1010C000DC5DE4F668BEC37B1CF84E696732109F96
+:1010D000BABDD2EE1CB71B4EA06B94FE3EE1F4FAF3
+:1010E000C473F23BA349846E2DEEA60A2246E8653E
+:1010F000DE55124AA7FF5CB17B3601BD40729335C5
+:101100007CDA5F3FB0F51DE3FA6BABD4E515817F68
+:101110001B8927401F954F785D807EB6C952593094
+:101120000ABF8D761AF1BD710EDFBFC05E25649FC8
+:10113000DA07FA6456C0F18729C02F63937F3F8591
+:10114000F6376CBD0146A0AAC4D13985EA1D792ABB
+:1011500041BDB88D1094A76DF15A7B3ACCC9F041CE
+:1011600048FBFEE1284F230A98FDE9BE1EE4CB743C
+:10117000CF70B2391BE42D2448B4BFC02A42762870
+:101180003603DA6F5CF003A88FF467C2750E6B212B
+:101190002F59E844B2DBE4297114E66CF1BE144720
+:1011A0005F1919F44D89A7E5D1CF045E0278457B1C
+:1011B000704A02856376875EA2E6948C0B754FB108
+:1011C000D2F255FBC95E406B7E975C6AA3E5F1875E
+:1011D000BD7B291B90C26E5FA95D86F9049BED74EF
+:1011E0003E5B8F114F132D177FD426261215FD4D10
+:1011F000C4B7534517DB84AEA949F49F197739F278
+:1012000045785FEA8E738EED4F9F6DB06E5827B5AF
+:10121000233BE8BA32BC21C1A1E2931B9C4C6F5125
+:101220003A5CE5043BB4A65782756E5BEFB221FDD4
+:10123000E21D253064EF34E2785A063E96104FA640
+:101240000DC351DE15BEA3F8BD62B64D8D3741D139
+:101250006B75ED6363E3F70627D37FFF2DF87DC73A
+:10126000C1E421167E2DC02B932E2DC755CE3E39BD
+:10127000AE74A6C46ED7C4F1AFC7F33603D94F6DB1
+:10128000151D97F229932B12A04DD770FEBE145E48
+:10129000EFFE2FE3DB9B9C03E395C8C9A82729BF7A
+:1012A0005E417262EB1BE82F9AFD7A80E351A5E75D
+:1012B0004CE02FB638A89ECB89ADE76E755E427FB5
+:1012C000713D63E27A5C196F0BE7EFFDF68AEF8000
+:1012D000DC58371802206725C4867241DCC99C4F50
+:1012E0001CF1C02733444709E81B329AA01F9D30E8
+:1012F0003618807DCAB0805C20423350CA80C7A1B6
+:10130000B9C1CDB4EB6CEA674894FEB4AB10408B26
+:10131000EC302CA0EB4E54E4CD51ED56CB9B62EF5C
+:1013200023F2A8F0856BDBE66CC6AFB3A9FFF236FB
+:10133000C753A41F01DB6DFCC6D06D9B557A709B13
+:10134000DB8D65A57D2CFEBDA0F0EFFA75C407F21C
+:101350003139BADFF0BA53E47CDBEB053E0F7C8514
+:1013600038C09F71AE3F89FAC949F59380FA898DDB
+:101370009FE18FFF418096BB9CA95C9F3BE26FB1D0
+:10138000FDFFE3E71D4EC2F4D46447A748EB875145
+:101390003B24839C4EA6739F00F83221DD65C2E892
+:1013A000284F2641F07B29DE4206D0BF065B10ECB9
+:1013B0008CC9D4E60579262627AE7FBFDD77DC39D8
+:1013C000805C3812E47C206AAF335C66A5FCB731E0
+:1013D000DB110FE58F69B9D54DC77575135E6EB119
+:1013E000A2FCD0BFA148C510DD1B807D54CA5E0B96
+:1013F000B41FDE570E40792BF82457D3FE1FFEDBB7
+:10140000FEF51431B39DDE4F9C8CAF7B017A47D340
+:101410000D6A4E849F2FE50F28F219912747BE22AF
+:101420004FD563511FFEDD5918E92F967FB38BEB23
+:10143000CF04D7C0FE8DC2F797EDDFF0F97EC6F579
+:10144000522CF98F3BF0C696EDB4BCCA2DCAA7A8A2
+:101450007F671BFA569744CB16EA6FBE47CB064B05
+:101460009704EDCAA9845A29BEBDD4C983FD8765F6
+:10147000022BC31FEC3FCEB609654C5FCB8973C608
+:101480000D84C720AE6795DB84E3C58D1C9108727F
+:1014900065E77C4524210876DC5EEC9016607FDDF4
+:1014A000E446DA5FAECBA0916BD05BCF8F05BDE495
+:1014B0009260BF6EB69080CD15E91FCA890511FDF7
+:1014C00044F83EEE4EBE676A5BE7491C01727A88BB
+:1014D000C551DABEC9E4B23C8304D7819EF012D96B
+:1014E00041DBC711E58F0A2E2D1B7969C6DF05E2A6
+:1014F000A5F33FF87711A13082846C74BF57EE11C9
+:1015000042B00F34192C41B0A525432DC40465BB4E
+:10151000216806F93829E03A4D050941507E538784
+:10152000162776D3759C3BB8D7EA8B42FF5B7DD5F7
+:101530009EA9E363E3B1AFDDBC971D80C727E5F546
+:101540000EF023036E09E30E9BA0A94AAFDFEA3237
+:1015500029FED06C17F8430B7BD79B80DED9C9E8F6
+:101560000F91112EE4DB21EE5D9B4AC064D533FF61
+:1015700074280936A9FD2A85BF8EB87C73A19F27E0
+:10158000B91DA162D9350AE2555724BBC02F2D6978
+:1015900018DA01FEEE136B8967A111F5C14C68EFF3
+:1015A0004D6ACF07FE7DD2B3EB470F013ECD745F8E
+:1015B0000C7A7CFC51AB4CE95555B83705D6F3078E
+:1015C000DDFCFBFC0FFF37112FFA7DF03217DD0732
+:1015D0008342CC2379B00F3EE7B9293184BC9514FE
+:1015E00055BEABFCF7623FCA7EF85D6328D3115548
+:1015F0000EB5F856C6AF12D8BE961805A6FFB81D90
+:10160000A5FAE53E58277D0DEDA6D72C3C0DF6E654
+:101610009C67BC07EC762C7DA3CC87E27164852D9A
+:101620004ABD402AA2E989C75DCC5E5719E97E818F
+:10163000D60B2B0B1B615E5536AB007CA7B46BE65B
+:10164000ED147E56E25562E2E785407F880F465BE7
+:10165000FF7C229D57C7A39A41D65218BE3C51FC2D
+:101660009558F83A6C6C2B87791D5E249226DACF58
+:1016700039DFC43412E57D05BE037C43E9B21CF6B4
+:10168000FC852A7A8E888EBFC36BEB3C538D117A12
+:10169000F6ABAF8EAB04FB5D0978548DBB9FE3E5E1
+:1016A000848BD97B62F6C90E5A6F5AF098838C03EB
+:1016B0003D75BE306083B858EFCF9B80DEF7D930E0
+:1016C0005E51597DA1B0699C0A9FC5048DE4FCBDA3
+:1016D0004F3864FABC72E4FA948035361E4FB8D89D
+:1016E000BA1E800793301EB3D77519F11832D6850C
+:1016F000FC46F6C67942108FFC93E801BF01C6F59F
+:10170000A1FE64F1E4BB1C6C5E713A3FAFD2BF42F4
+:10171000A35F12C2020926A9CA523BC66713C212AE
+:101720003ED7CBDB0E178F3B717953F01F8B9E0A90
+:10173000FEF5CF431CEF87AB97C8103734C547F78A
+:1017400083D392040D5FBDB5D6A719EFED7F8A9ABA
+:10175000FDB202CF73FA9EF34D4A837855A5293026
+:10176000723072AEE0E7ADCF1F7740BF719F99A393
+:10177000CADFC7DC3E517BDA72B3ACB2A7B789EBE4
+:1017800001EF0912D76F3AB9F3825DA5F8BC0EECF0
+:101790002A9D62C225ECEA7C12E88438B27E7CC5C0
+:1017A0009EEAF94BB1AF7ABA297CE04CD2EA4B25DC
+:1017B0006E184BBE14B93AC2E55F8F7F3DBCD5A40D
+:1017C000F57B14F87E1F3DE24880EAC73B4BC420FE
+:1017D00011903FD03E1E7E4C407F33546D46BB5C23
+:1017E000531D87F1D99A7C11EB6B1E14D17E86A80C
+:1017F0007EA8A7F3F903D713FAF86C09113C5355E7
+:10180000EB9E39214E53BE6DD1B7FFB016E2CBC56A
+:101810004619C63B24B37873C02BA2FF4AFBF08461
+:10182000203EFDE8B51EB0670A3F1CF28A286F8192
+:1018300037450F0CDBC5E3D1875AF28322D059F02C
+:10184000F58D23E740FF3532D0E1887B8B03F45DD3
+:10185000DC3F1FAFA8C0FDA34FCE47BB499D553A03
+:10186000EF382EA7A5438B6F013B7EBCD548206E79
+:10187000747CCD3994E7EEB58D9EA92323F16525BF
+:101880003EAC8F33EBE3CBFDE2CABA78B2C20F7A3B
+:101890003EB939067F28FA2A167F503D5695947234
+:1018A000F97A4CD11FEFF075960EDDF26013C54347
+:1018B000C24211F1A0F0E591CFEFFF1EE8E138CA76
+:1018C0001FEB809FFFF9C397611F42960851E3C841
+:1018D000DFEBB37B942EB911BADCE65BD25706F18D
+:1018E0009F5BB7B2AF0CEBD7DB95D87A6D60BD3597
+:1018F0002C89C581F476472F0FFF69BB5359FD58DA
+:101900002EBC5F59BD280870D3504B1DE85FBD9EAB
+:10191000D0DB09653EFA79268445121CAF9EB78C50
+:10192000ED2276C284F57E8B3D0F9CF58B710C0603
+:10193000C00904BFF4585CB019C76BBCAA02E7DF4A
+:101940003811A09F78BA03B03E773CC60FDA325800
+:101950007BF1FA78E68F4F70E13A45C5213FEFC43D
+:1019600072335FC35897EFD9243A8F66AF210ECEFA
+:10197000154A6DD20108B9B44D31103389E049F1EF
+:10198000DF094406E87AB14E807D67BEC59483FEC8
+:10199000E92EE4DB6FD27D21E5F78307C55DDBE847
+:1019A000120F7AC62746F3CF1538CFFD0DD40BB7EB
+:1019B000F86B101EFDFADB5920AF770BBEDFC2BCFF
+:1019C000BA2A6B1E2CA4F369D82DE2B9D2BCBB8F06
+:1019D0008C62FB34EDF9A468B7E4421CA55988F782
+:1019E000801E51F0D86933A17E693ECAF460F309C4
+:1019F0008197D93E621FAF3FF7AE0DF7190ADEE9B6
+:101A00007A0EC1F8DE6F3B713DCA3EE3DF58CF91DD
+:101A100081D793E1407D017C2546E62FDA245C578F
+:101A20000F89F7C0FCFD3C1E44DE8D43BF59A16FFA
+:101A300003E73F85BE2B387D7B3A2E7CEB1ADABE5E
+:101A4000CDEBC253063193E07A7BDE4D40FE50D69B
+:101A50004BF9E06398DFDE0E6627DA8ED918BE6C8C
+:101A600045B9303FC5BF7624313F59BFEE2ABE4F3E
+:101A70000F27097DFE2DC4297CAE29E1A428F2A000
+:101A8000F8B514CFFF80FA1207391F24113C2BE35D
+:101A900028E32AEF9993B5F255C5E30AEF1A4925D1
+:101AA000C41361DC02D5FC56BB4ACCC929FDC7FD75
+:101AB00037E8E84ABE0C3A3648D6162191F4ED8B49
+:101AC000319426F79773BD9C091D9D9FC1F9BC5E9B
+:101AD000FE2F1A1A8940FB5D2DFA0EBB286CF69179
+:101AE0006E734E7F79B8941EA1F4BE32B9B0BF3E7A
+:101AF000192C9D0B93FBD1B93079003ACBAE8A8972
+:101B0000500FEB4F2FC07DDE2428839E300DC7F190
+:101B1000902F7B9D24F8346D94C4E328CA7C202E3A
+:101B20001147DF2B4BCE46FA0B120918693929D71A
+:101B30002380DE1F041F94A9E7F71FE0839B06E6BE
+:101B40008310FA25CB39BD972B7916BB06CEB31877
+:101B500004DDAA61DC8B064FAF2FFBF2E956DF9F55
+:101B60006EF503D3CDD700F2D36C22E7D10F2FAEA1
+:101B700076C378FBEDDE9389F4F99E26AE4FB22949
+:101B8000DD68FDCBC922EAAB47C895A887BF6230A4
+:101B9000E0FC7BA8FE7D3A3B1ADF0724177DFFE2BD
+:101BA0008D04CFE3E8FABE998CFE4F4080E7ABE7A7
+:101BB00013033C77CB4DC470197A6813D713AA75F9
+:101BC0006E52EB81287AA815EA293FDE05FC689160
+:101BD0001DD2407A68CBE5EBA12DFF613DF4FD817C
+:101BE000F9EFB2F9EA598677AD3E50F858D917C4E3
+:101BF000CA17A2F248D25DFDC725C483E7612576E6
+:101C00000BB3BB3B05B4B3CD27F27D58B659502971
+:101C10002876F8EC2E562F4E89EE0FFE3CD985FC27
+:101C2000BBBC7DA547D2E48104F0F943DEB38E113D
+:101C3000542F4E17ADB8BEA472163F54D64FF5ECD4
+:101C40008C69A93C6E4AD79394C9F09044FD013841
+:101C500047B3F3FD4162B1A4F1FB15BCAD162B04F3
+:101C6000887B3B9309A4DD50BF7ECD6838BF777A6F
+:101C7000B5ED5348EBA7220E42501E5CD47E431CA8
+:101C80002BA94CD70EF62179D05EF53CBBFF7EE246
+:101C90007832DF4F98881BEC0A11AB06E41BD57E27
+:101CA000E2FDE441EC273E4A56CEC7B5F6AB3D8E89
+:101CB000448D0BDC93C2F71FE79DE8FF8ADC6E4D75
+:101CC000EDCEC6FC94553619E305A2E8B1CCC8EEBA
+:101CD000FFBED36B20B26A7D4965F14456ED1F52B9
+:101CE0002A5C9A725AE5504DFB21BEE19AFAF4BA89
+:101CF0002B35F5998D059AF230FFD59AF6D9540017
+:101D0000D4E59C96AF69DA8F6CBB51531EBDE57666
+:101D10004DFB2B820B34F5639E59AAA91FD7BE4AEF
+:101D200053BE6AF73D9AF6CD3CEEABC7CBB51CAFC0
+:101D3000CD12D33B4DD6028C47365BB5F1C8B414F7
+:101D4000A67F4A1227E7421CBCF9647E2EE07B9FE7
+:101D5000FD6A8C8BC7E20BBD1E8BA53FF5CF8BF8C0
+:101D6000789FBC6432801CACD84BE5F52A5AB6BECD
+:101D7000B311D6D432969DA74A84E5F728E72BCA3B
+:101D8000FB7DE72B9287C557ED56B2390A5FA4A5B4
+:101D9000C851E39F0A1FC5C2DB3D83C4DB5778BB34
+:101DA0007F176FEF0AA4523D8F2A7E9EAD7F6F751D
+:101DB0008A819F07FB2A5398BF33211E3D7107CAB2
+:101DC000E3E5EA7F651E54FFD7A4A480FE7F63DEAF
+:101DD0006AD0FFBBCC1ED8937D52F946EDE332B4F6
+:101DE000AF65ED0D9E5CA04BACF8F7EA947EF1EF89
+:101DF0003A16FF8ED7E06D514AF4F877B3FDEF182D
+:101E0000FF6E3679720713FF5E043A2305E8C0F8C7
+:101E1000A38FBE3C7E1E6B1FE427E48000FB1EAB3D
+:101E200024C339D7A5F6B5743F9B0BE7A96DB06FF6
+:101E300052ED73E8FE96EF6FE2D02E50BBD79A8238
+:101E4000FA911C90E9F38B74DFBB5986A262FFBC48
+:101E50001ABFDC4C3C169388F47C04E849BE49EE7A
+:101E60008A13215E163A3839FBDFB2E7DF4BB90C33
+:101E70007B4E2E7D2E8776A79CAE7F5D14BF4B7F59
+:101E80000ED7E77F839F26E0791CE26903B58B704C
+:101E90001ED799C2ECF386A36C9FBCE1C46C37CA11
+:101EA0004D4AD180E77083D537BF4DE9E797FE36BD
+:101EB0006500BF5459FF2ABEEF9D268E6D8778E3DB
+:101EC000D9B009F12612961FD9B0DF4882484F9643
+:101ED00067ACD0D118DED805F6D948F479C572229E
+:101EE000ACDBB85F44FD4492597D80589AC0CF491D
+:101EF0002CD6DA2DA7576BB792CA5C3A3BA6B55BD6
+:101F000069955ABB35C4A7B55BE975053A3BA6B5DB
+:101F10005BC3FC5374764C6BB7725A6ED4D931AD37
+:101F2000DD1ABD456BB7AE086AEDD6986756E9EC89
+:101F300098D66E5DB57B9DA63E3FB459533F7EFF5C
+:101F4000239A7261D77735ED171F7801F36F261E3C
+:101F50007E5AD36E52F78F35ED28C2BB204F7B21BE
+:101F60009284906B4E3FAFA95FC8FDB46B7B7FAD91
+:101F7000E987B4B17CEB00FD0FE8F557E2338173DC
+:101F80002291DE57D2295D5704054F88365BB27B1C
+:101F90006711CCE3CCB1EBF7433F8BB768F3B49751
+:101FA00004B5E506323C11F44303E58B20E5936567
+:101FB00090BFADD26BCB48A31DF32106C9678B0F31
+:101FC000DC4430EF33E0ED82FC74659D0ABF793963
+:101FD000BF29F353D6BB8CFA7D2139B24E2FFD8F2A
+:101FE000ED23BB4DC0B7B5BB05F25DA1FF7AEA3A60
+:101FF0001EDE981E655DFA75E8FDCEBC546D1C7B37
+:102000009A68C5B8FED937450F8B0F6AE570D501C0
+:1020100016CF5FF59C80F1353D3E14BF34165EC48B
+:1020200000DB273424936050257F32C787D9AD95D4
+:10203000BFB3F00F98CF536210F282E2E4783DBF55
+:102040001585487F3C27E46AE5548F679B67685491
+:10205000BE92E97F308F5AC2CEA5F47CA5C7FB8A19
+:10206000DD0F9B402F5E2EDEE7A56ACF0795F38339
+:1020700012BA5A53943C3805AF745F5E935A187B7A
+:10208000DFDA907AD9FBD686D4FFECBEF59ED40178
+:10209000EC5C0FC4CBA85FA98F97F58F8FEDFD4C3B
+:1020A000B0631C9AC5BF7C1E0BCB57D1D9C95CB796
+:1020B000C64EF6ED7B4F0AC166DAF912BB7713CC38
+:1020C00067A9DDBB196099DDFB807ABDCD142F783F
+:1020D0003F87DAA99D51FCC3975315BFA802E3229D
+:1020E0001B4A587B7DBB9FA5B2FB3C9D29456EF4E6
+:1020F0003B4FE433FB692B1AD0EF7C889FE73C0011
+:10210000E7852323793C0FF273152A765EA0DB0660
+:1021100063855B9DE7FB48AA13C7B34F7ABE0BF2FA
+:102120009D9B1D06872083FF6CC073D1F55E6BD924
+:10213000AEB1ECBD64CD7B12DA6111F00DFEBC5581
+:10214000FABB9A6F5FA6B884FA58EB7C3995F9BB55
+:1021500046E2B580DE55CE738D27F32DA06F25C1E5
+:10216000E38896C769E4795253F879AEE860E7BB33
+:102170007D727E893CA97ABB6F9F9A6ECAB9EE1CAC
+:10218000BBF765A0AB5F0A98C1BFF45BA2EF7F5FAE
+:102190004D65FE470B5F1F7534918F707C7150F158
+:1021A000933753312E17C07CC5D5A2E734C4E70658
+:1021B0001BAF3A9EDACFFF399E3A70DCFC64229C5A
+:1021C0004F240E95703B21797281FF5BE0DF9330E5
+:1021D000BEFA3EBCDF2FFF5476F17C5A79C07C5AA0
+:1021E000A59FD94EEFC78057DA5F4F2ACBFB5B2FF5
+:1021F000AAFAB15FA21F8AA7DC46EBA0F0F739C3A9
+:102200009FE7340B265C5E5CD39CD62FDE674E1BAB
+:1022100020DE77F1E8E844384F56E256FA76167F2A
+:102220005286FA7E4C8B533BFEC6025676A531BAD7
+:102230002D4E647C3F8ACF43C90354E2D69619C41D
+:102240000BF71D1EE1F9D94A3FA3D26CD83ED13518
+:102250006514CC7763B680FBCA8D4E41B3BF3C9901
+:102260005A322A8DB69379FFA3D2189F6E1BCEE205
+:1022700033FA3CC833BCFD99D42908E99B57003E8A
+:102280004DA218158F63D2581EC64988911546E293
+:1022900067358FB1FB5D4ADC4C890312E2792B81F3
+:1022A000EA95F75A8D04E25A8B44EB46E0C3BEFB35
+:1022B00073FC5CDD41FF037B593DB602F38FFEDD0D
+:1022C000FB5B80CF04577F7B599AD6E7A7782EF324
+:1022D0001ED7D7D22EE3BCBD3B9EF16DAFCD8AF1A8
+:1022E0006C7DBB859C3EAD3C4E01FA1AEC864B24BE
+:1022F0008DD1ECC7C234C637178F9ABDE8C794C5D5
+:10230000633E8772FE2149C01B98061E0068F1A734
+:1023100067C07DA2BEF30F99E07B49562BBE27C94B
+:102320002464832BA1924780FCB26E53F7863498C5
+:10233000EFB58207EE0FA455393AD392E11EA18C76
+:1023400062B6319BD88BA13EDF80F5CE398E8D46AB
+:10235000C8BB96099C6413231DC746C7694DCBC6ED
+:10236000F5B7066EEA4CA3ED12E55E327C2CE8115F
+:10237000C77437C87125CB5FD7AFEF3E2E1FD60D80
+:1023800074DF00F890A3E781DFC7F98FEA99354041
+:102390008F1299EC62F7A2581E2AA45963BEA08737
+:1023A000E54B2740BE510ED33350FF90B3741DF060
+:1023B000B9225F22C737F0BD3A1FBE95E33B4927DC
+:1023C0009F0A3EE9004D900F21CD20C8D7B3AAA2A5
+:1023D000CFF7879CCECBED158FC07C674D6EC23C8E
+:1023E00077F2F9175F8845E0F43239A1EF1388439B
+:1023F000C42533FD1B27CBA88F8943C03C538BECEE
+:10240000A983729CF56A870876CFCCCF0B171A8800
+:1024100044E5AD94F7E3AD24C2FBB92CCECAF4ABCE
+:1024200044DE57E442E4C82902FBC9FEA85FD49AFF
+:1024300040D7536A3D88E78871231A4BE05EC1CBD1
+:10244000F3591F8FC4C8DB3F99C8E8E0127D6E03C3
+:10245000F8F4E4E4ABFB26239DAF841B9A0F6C7861
+:10246000F7D5FD993C7E0EF9E281775FF55ABF7C86
+:102470007EF9BEC7DF7D15F2CBBF3CFF7B04D0E306
+:10248000272963C1BCF5FCAFE8B3C3A2EFF0BD14CC
+:10249000FF3753A6F21700944815D29BE50FCDE104
+:1024A000780EFC9DE2D912C1F3CD1D07107F878DF8
+:1024B00074DE747CE314866AE33D893C1F2388FD47
+:1024C000DF62699B06FE4D8FA9370FC6ED79F1EDEE
+:1024D000CC00D52747EF3B672394FF8E4BBD367862
+:1024E0007E7ACD1B36C0D7D13522DE7FC37BC9AA09
+:1024F0007CA0F7395F95BA2B8E025FCD5FFBCF22B0
+:10250000B59F4DFC296877970445B8E3DBA7FF9694
+:102510003D93C0998E9597B72769CA8A3D5E6E8EA6
+:102520007E4F3CDDCDE8BEE4D96D26C8872F75FB14
+:102530007A409E4EF37C83D3BB6CB8BF52E6B3E0C7
+:10254000D97C13EC278F77984908F85EEA32128C11
+:1025500053796708946F7D9C0FF5F37C654F02F605
+:10256000B7E83111E348D5742C3FC5ABAF6309DB45
+:10257000DFEAD6B1E8A83C1DF4D5A24D0209C8ACEB
+:10258000FD1A4A379FFF7E3C5FD1AF536F5F2E909D
+:102590003526D0237AFBB290785A2683DD6AD33E63
+:1025A0005FDCF100F6BBF812E7314E37DF9F159183
+:1025B000895FE4409C7938E60BC6B237A7D732A1D1
+:1025C000FC70AD05E1476B1D088FA631BE5DB6BB43
+:1025D000F3957414EBAE22B04371074A2DB793887C
+:1025E000FF2C6DBB29F4A40C7CA9CD87ACE27856F6
+:1025F000FCE7C5FC9EC1A5FCE72A58E700F9905509
+:1026000083CC873CBB7FBC059E8F57F03191E203A2
+:10261000EDEFD8D7647269FB1B0B2FB1DE5B0EDFC9
+:1026200039888267456E8E723BB270FBEC8D43E950
+:10263000049A5FFC6B5637F2258B4328E754A27B44
+:102640006317AC5F24BAF85F80BC4954FCABE7CF9A
+:10265000C5C4C3EC8E95BD67E171893EBEEC7810B0
+:10266000F1AAF011DC2830B80186DC86E2FEDF0D2D
+:10267000E8F77D80366DF913637716E88DC5BA7873
+:10268000C12742F4FDD734F770B67ED93B1DF22244
+:1026900016918A8D2CAEDE86F8392DB5BD722FC805
+:1026A000F376264FCB7FF9DC2F404F2DFDD9637693
+:1026B000D0531F486DA9305EFD8E0D762FE82B2973
+:1026C0006087F73F088A51EFEB06DDFC1C9078AD80
+:1026D0009017B602590C042C3013F4E4DF76181D61
+:1026E00010476D78C61C32537CACD8C5F048CB2758
+:1026F00058F97EC457C36EAD1C2EFDE163A932EEBE
+:10270000E703E91C7FE9A0AA576C3762FEE88A3725
+:10271000450F0CD3407A717DFAF7611E614AB78686
+:1027200076B1DA94D8BF9E7A3C2690B3865D8C4E03
+:102730000D3A3FB38EEB653DBFB7E9F89CE205E388
+:10274000614A3E2B0932FDDCFCA3C7F34ED0797DF4
+:10275000B4FD55BB3036C2EF04B22E291DCEB6D71C
+:10276000CC873C83587CFE09978B3EBDCFED8CBC5B
+:102770009B4E0C7CFF0E06EB8D21FB35141FF5DB09
+:102780008C9E007D5CFF9CE8B5829F74C48CDF77D3
+:1027900058F6DCCB6F5D4DE7B76CA73179065B86E9
+:1027A00015F4B342A706E0EF82085D96BEF0B209C9
+:1027B000F220E1F91A57843ECB76769A20AF528FF9
+:1027C000C7D2F64E13932F1D9DDA4F4C07BBDCFC8E
+:1027D000A38B26E0830FF608045C48FDFB75DB5EE7
+:1027E000B683FE003C81FD50E8D547BF7E740BCD1B
+:1027F000FCF5046CE780739A58F45B09732944FE76
+:10280000FEE9AFE9F875EF983DB0FEBA9FDE698743
+:1028100075FC556A647CFEBD0DA9608FEB8C8154FC
+:102820000742F6BC6EEBD791FF16BFFEF554827AD5
+:10283000D33B04E497AE7308AC6FD15337E3FA6A25
+:10284000890FF9AFEE7B6205F88917245216CDCFB8
+:102850001F3284C9C95F9F36E3A6E0AF26C2BEC35C
+:10286000F14791E5F19195E8877C9DAF956A622CDF
+:102870005FB0303A7DCCED33E17AAC81B76AD87E77
+:102880003FEAB10F33BD6920EF140FDA78EAEBD3DA
+:10289000D2B8FEC3EFA5E07B94EF4AE139B4EF3242
+:1028A0007AE3F234EFF1BC5636FE5D7C7C3AEF7889
+:1028B00088CBFD3555BB7F55E05787287130D24511
+:1028C000D4FC154BEEB76F42BE3AFF26D32B2B82BA
+:1028D000B3CBB0BECB184A83FA60E71C01F502F512
+:1028E0002FA2C9F57623976B6D3D9DA724A8F1BB58
+:1028F00087DD8BAB7D94B653F92111BE31459E67C0
+:1029000047E453C9AF58ACF3CF14A8D70B4943B42D
+:102910007A41799F3C9512F51E56441F0490AEF5FE
+:10292000C6E00FBE0B727CC48CF70CEB9F33E2F752
+:1029300072CE3CBBF7ADDB29BF9F6957E457AB674D
+:10294000F5F25BF7FCCD249AFC9E49AE2051E59749
+:102950003E8F2ABFC92C7FFF7F5ACF2E8EA167AF33
+:102960001DD2CF9F48BC86163FFCF1B261B8CFD2D2
+:10297000E155C1A75E6FBEE596A3EA4DFAF7265171
+:10298000E151C19FC2974B7FB21CC7E9E35F853F0E
+:1029900015FEEDE34FFD7AB578D4D71BE0CE51613B
+:1029A00084EEC675747F0DE7AE2F8A78EEDA23F7D2
+:1029B000DA5D1097E579373D0E5E76B2726F8A69FF
+:1029C00023E80FE5796F1CCB43E8A9E8B53B557EBA
+:1029D000FD890ED10E79F5DDC1E8F912984901F1B2
+:1029E0008C18F914CAFDD969A235CB0FFBB2367623
+:1029F000DEB3B0E9563BF8D33D1D39B32AC18F3F52
+:102A000020A24FD513CFF3AB025E6908C56B0D5BF7
+:102A100032394D02DF013FBBA663D90CD8342E6C8E
+:102A2000D5E2A3D63A07CFB36A1F3546F88280BFF6
+:102A30001334819F55F794F6F952C8AB02FAE8F8BF
+:102A4000C8077C14E51EC646858FF2493EDB27F396
+:102A5000F32AAED7A68963675542FEE27E764FE23F
+:102A60006C874836C27A9FE5E7578114E4CF159406
+:102A70008FD571CE8F80CF46C7B6DF1FFDFC68D1E2
+:102A8000BDB449FD2FFE9CF724851FFDE2C8A8DFD9
+:102A900040F9976F67FD99F46F5FBAE7B33B308FEA
+:102AA000728F99C0BEA867CFEFB2EE85F2AFCD1E90
+:102AB0009867CF3AB63F0EECB1A15DEFC964FE5FF7
+:102AC000F38B17F3BAD13EAD477AED1CC2EEA99E47
+:102AD000EDF8C73101F2E93AE8AAC0EEF27D57C33A
+:102AE000AFE3707FDDF3E245CDBEF2DF5DCF0A7E5E
+:102AF0005FA9C7462AE17E718F93DDEF6CF8CDA404
+:102B0000EFC37DC5E5BB3A4D35B4BEF4B7FFCC038A
+:102B10007DD3F33CF327A87FBB155CEA8E275E6D5F
+:102B20003552FA7D023EDF50BAEFFE6E4239DCC309
+:102B3000E88F1786871E8A075817C54B1DE8C958A6
+:102B4000F8786308BB3FF2DF878F4FEF80F1EB3BF4
+:102B5000261288A747F02278D9731BE65DD0F5B31B
+:102B6000E77B2EE6817F74A9F57EFA7F6CBD8943F1
+:102B7000FFBBF9FDF12132CE4FCFF7FDF9FA977780
+:102B800063F9A7360FCE7790F27ED5D0FF5BF42E97
+:102B9000FF5F4BEF039CDE36079CA7F4BCF8CF2CFD
+:102BA0007219EBAEFF5FBAEE3E3FC7E0B14CA0F347
+:102BB0007B87046F2E1162E7713E3154BB8F98C939
+:102BC000FD8899C9B5E83FCCF4B2F84A3329D80F4B
+:102BD000F7D4025E11CF1D309986E2A16B4E7E10B4
+:102BE000F3B6A4C0C8EF401ED72DCB3DEC3B5FDA57
+:102BF000FDD5CCD4B232F0DF0E35D179D176876CE9
+:102C00000647335DC22CAF88FE1E85E8E7FD69CA22
+:102C10000D981732AB58BBCFB85DB76FB8B5525BE4
+:102C20007F0B793A05F2EF6EA93362BED0CDBAF6CA
+:102C3000AB873A709DB792C60D2C3E7379783AC037
+:102C4000F1D41F0F03E3AD1F9EF87E127379E4FEEB
+:102C50007833FBD8FED24C2BB8BFC5F3E4560D0A2F
+:102C60009F84EF3BCD7C6805BF662FFB5EA7AA5F04
+:102C7000C48B82F7CBC5B742273DDE15FC2A78D33B
+:102C8000D3E12938934889E03F02953C121F51E770
+:102C90005BCEECF31BAD88C7D7B6B3FB0AAF15D735
+:102CA000B4E643F95901FDB50B93C7130B5DEF2152
+:102CB00023D9CDEE7F79654751249F4528FE1D9E7F
+:102CC0002B403EA17A5F0AF984EA75413EA1BA0C15
+:102CD000F984EAF6904FA8AE877C42753DE413AACA
+:102CE000CB904FA86E0FF984EA32E413AADB433E7F
+:102CF000A1BA0CF984EAF6904FA8AE877C42753DE4
+:102D0000E413AACB904FA86E0FF984EA7AC827542F
+:102D1000D7433EA1BA0CF984EAF69047A8AE873CA7
+:102D200042753DE40DAACB902FA86E7F5DF8254D2E
+:102D3000B984BCAA695F6A7943539EE6F8B3A6FDDD
+:102D400057DDEF69EAAF97CF68EA15FADF907B4E5F
+:102D5000F31CCE2C0245B08F617FE59E7F68FA910F
+:102D60004805C6994DA411A105E2B714C69376840F
+:102D7000562AE6004B47F972D2815FB706360273D6
+:102D80001D9A74310BF4FF6B936F62F1077E4E3026
+:102D90000BFE2953264EF83C03F6B5CAB9A73D2CC5
+:102DA00092D078CA876101A1239C404249940FC305
+:102DB00071085DE1247C9E1476224C0EA7E3F39407
+:102DC000F01084A9E11C8469E16C84EEF01884435E
+:102DD000C257201C1A1E8FEFA587F3116684AFC15E
+:102DE000E799E14908B3C2A5F87C58B804A11CBE14
+:102DF000016176F87A84C3C33761BB9CF06C84238D
+:102E0000C273F1F9C8F06D0847856B108E0E572319
+:102E1000CC0D2F4378457809C22BC377E27B63C280
+:102E20002B118E0DDF8BCFC785BF81302FDC8CF04F
+:102E3000AA7013424FF8016C971FDE84B020FC6D1E
+:102E40007C3E3EFC30C209E127F17961F8098445F6
+:102E5000E1EF239C18DE86B038FC138493C23F4216
+:102E60007875F8057CEF9AF04E8493C3BFC1E7D71D
+:102E7000867F85F02BE1BDF8FCBA7027426FF855CC
+:102E80007C5E123E80704AF80D7C5E1A7E1DE1D495
+:102E9000F09FF1F9B4F01184D3C3EF21FC6AF80478
+:102EA000C2B2F01984D7873F40F8B5F0397CEF867D
+:102EB000F0A7086784FF81CFCBC39F21ECDBEF4FE6
+:102EC0008E752FD167F802F6CF56D7A0BEF345C84E
+:102ED00016CDB9D4E30976D493B3D6B03C928D2500
+:102EE000E7A6A25FBBD22CF3EF6BEAF4EAE756F059
+:102EF0001F3640CD10D607E401CEE3FCFB5AF1DECD
+:102F000014F097361674D7433CE4C1ECEE2A84E9FA
+:102F10002CBEBA9EC307D259BCF4F651CCCE56ADE6
+:102F20001C89E757247970EBF803D8E79448FBFA3B
+:102F30004C5EB6F666E1BD8041F633D87697CA8F0F
+:102F40005A95EE0BA6A35FA4BF9F37E8F79F413DBC
+:102F5000F1E5DF6F1FE8FDE39C5EF68C8A5D384F7C
+:102F6000C99B07F553D60D1193693FD5AD8203EC8C
+:102F700064CDFAFCE940BF02E2C578E2BC18795D95
+:102F800047D2599EC682462381B8E20299603C77B7
+:102F9000C12E96E70B71D072CA17759C2F966FDA07
+:102FA000690217B4AE7131CB3F0AB2389385FE0780
+:102FB000FCBCB47536E61F2D7B461B7FAA87B88EF6
+:102FC00008E7C8DAE70D3CCEA48F57EAE34B7F4C05
+:102FD000E7F1250FCB3B226206AEF7025D2FE473CB
+:102FE000F8EEB65940FF533CE03989B27E255EA920
+:102FF000E081F4BFCF8079A167F78FC43CB5B3B24D
+:103000009C06ED7C549CBAAC90FFE09B08CF29FE57
+:10301000309FA4B72901F3914E507D2E43E293C314
+:103020003711BE9FD6FD4E26E1DF6FD49E1B585A46
+:1030300031FFBADA4807A6EDAA7724E1FD47DA5F47
+:10304000DE6E8847EE30623E5080AC7293E2FEE75F
+:103050000A151B8CC81F0B763B597E58C0FB26E413
+:10306000EB2BF438B13E673AE4152D68C9CEC7B0F2
+:10307000DB6E23FA79CA79A942A7FE79D11589F0C6
+:103080007DC4A52DAF233D29BD34F5F5AD9FE2FDEF
+:10309000014AAF5331E8756A207A5932B4F482B8E4
+:1030A000F2AD50B92609E5B46A5D6864A38A1FF5DC
+:1030B000717A9261C5FB8E4A3E71D950460F2279D2
+:1030C0005281AEE75A0B915E7A3A95FDAB06E94123
+:1030D000DEB1E1F776E7E590F937D2E7F379DC7214
+:1030E0005EF3F5E83F676730BFFEB5B5906B49C842
+:1030F000EB6B2DC44B9DE737D63AB0FCA7B56E2CD1
+:10310000BFBD564678646D2EC2532696CFA3C81312
+:103110006500CCAB1B9DC1E4687486B2AFBACB0D21
+:1031200071E9B27FBD5108F93D2981E499D3AE45DB
+:10313000BF5B93A75139479B87D16DE4795E9B04B0
+:103140000F7C476541C5359AF624777CA40CF6833D
+:10315000E78D2C6871E2F7DB6E9B91A4697F4B4B86
+:10316000BAA67C5D868CF39B5D96A3797E7BD51891
+:103170004DB99AFF6E02B1C41BD4E753D4336279C0
+:10318000DE0ED6F67CE3C4B4D574FCF3078D58AFDD
+:10319000A7C7295300F7E381A7CD1EB043A7E11EBF
+:1031A000192D9FFE9388FAEEB491041C54759F1656
+:1031B000C87A804462F274E13093A7B27F8904F642
+:1031C000E1E4C7663CBFABD9229000DCA1EAA59838
+:1031D000A7E3DEF52333AE7BE11691F8F0BE92DC77
+:1031E0000EE7D677ED18ED8173CB7939A14CB8B7DE
+:1031F000D7FBF338CFD3B4B6A69BBD7F9AEEAF9D75
+:1032000090972414E0F9C1C7E56DB506C837100FD3
+:10321000A6809C7EFCBC88F194252BFF54E400BD65
+:10322000F64AFB5BC5749C536D228E7BE619F33620
+:1032300011E5DD9B06DF758DAC3B8871867DEE8ADE
+:10324000BA0CCAC71FD606F350EFAC61F1EDFEF819
+:10325000A1EB057A03BFAAF458C46EB17332AA7CFD
+:1032600086807EA8317AF0DCF454AB11CFF3A8FE4F
+:10327000C7F3FF536D4906A67F9E47BE5B20C92654
+:10328000F5B80B5A452FFB5D08D904F3250F8B3E8B
+:103290003211CA2C5F21D022F8D8798D96BE77AE34
+:1032A0009C88F78BF5F9530AFC84CA944F750EB4C9
+:1032B000F445763E4B26744BEAFC7125BE42DCACED
+:1032C0007FE53B3EF5C31FFFD6640ACF7AD92707B7
+:1032D0002F6CB7A17EFCC8F052D16A0ACF9407DEEA
+:1032E00097285D1A45DFA380CF6586D6AD029E8BF9
+:1032F000BCF72D388FFFF039A307C590E76B2DFD84
+:10330000F1926103E507C10CD8F972285570C357D3
+:103310007909E66FCC25ED3C3E1064E75830098A08
+:103320001F473D3BC77AAFD0B619EEE1D6E8EEEDC8
+:10333000BEC7EF2DFC3043D0D8E7BFF0728D81C9F6
+:1033400027D9C3BEBF08792F2354F654D1A7BFC8CD
+:10335000188EE3F6D955D28E7AA5967F1FB8FE193E
+:1033600033BBA7231307C8E312461E7216E4998ED7
+:10337000B3D4F4DC77809D17932EB4731F1A83B5F2
+:103380005DD9F0FEB6F52E7CDFE80982FC723B6069
+:10339000A18A03F4C762C2E6B7BC4D088654710A1D
+:1033A000E5F73808D80595BEE96F0FB4766011B718
+:1033B000778B882EDFA74D6B972A126CB8AEA56D60
+:1033C0003CEFB96F5E22F982E2ACD6177C6526CE5F
+:1033D0005BF004A3CC6331E90DC17780973FCBEE5E
+:1033E00003E9E7A55FC760E759EB993D15BE27DC08
+:1033F00037AE6EDE0ABE095C5052D141C17B6D8092
+:10340000E1B3B643407AFD85FB55CA3D3B85EE8B63
+:1034100049C54CD06B8B1FA5FBC2EC081FF4D9EB40
+:103420009D41F497CE9036BB95F27FFD969DB74CAB
+:1034300082F79E7ADD04FC5DE50A8D3438E1276968
+:10344000EEF956596614FBAEB3E7FF29FC101E6770
+:10345000C2F7283E166D1731AF41D58E9FEF07108A
+:103460004F7501827944756F8A9E66FAB40E7ECEDE
+:10347000A7E0F2E7ABE0E77F7ADE7A3F263B7360B6
+:103480003F46AF5FFAF9313AFB09F726C05EF6A670
+:10349000B03CF0F39237D1857A59A777530AF0BB45
+:1034A000A38ADEADE5764F196711D83B5A7E7FCBF4
+:1034B0000B76883FFCE5D11752318F02ECCBD888D0
+:1034C0007DB9BB868D77F72FE3306FE9E3F2AE3C31
+:1034D000F0FBAABEF73BBBFABBA6756EDF75993051
+:1034E0005F6E0F978BDBB21C600FFDD1F32AFAEDF4
+:1034F000BF62ADD3768975DAB4EB5C00EB54DD07BF
+:10350000A9E1EB3CD9C2D6F75E2B5BEFC27EEB0C98
+:10351000E039C8DDDF377B02E86784D08E9FDE2983
+:1035200012B87FD6E767E8ECFE05D2B615F0B17C9D
+:10353000D5DBC724CA174B4651FC503EA87AD88C1D
+:10354000767EC9CFD9F9E78742491A1EC0EF0BD959
+:10355000BF419F2FA5FE01F8179179F4D9FDC599B8
+:10356000852ABB3F48FCADE071A8151DBFC3DF8BAA
+:1035700012BC2C1F7285F21D98DDBAEFC0C8A003E3
+:10358000D83D790BD02983C86C9FA88DA7FE6DE428
+:10359000A777AC42FEEF1DA5FE5E6F437CC808F91D
+:1035A000BEBD3B05F48B96DF55622F2190DFCAE24A
+:1035B00060EB3399FD12BC5ECC7B3153BAC6D3F1BC
+:1035C000EECF94D973D9C1F2BA9F22F8DD1965BE46
+:1035D000FAE7101FB780FDB31AD0FEE9D7FF8B4C76
+:1035E000E62F2F170DE84FD79B985FDDC3BFFBF089
+:1035F00028AF7F3493F9D7DFE5F1811EF023E17C1A
+:10360000FA5A33FE5E0F2153314E2E11C67F92823D
+:103610003787F4499F7CA3BFDC9B0178BA83741978
+:10362000819E338B67CB706FE058AA05BFA344FF20
+:103630002AA09FB9BC9F4346764FE0188C41D735EE
+:1036400097C7938FC16740E9F8C78698D08F0DBCA4
+:1036500068463FE1FE7816EF23C98912F0F9ED5C68
+:103660004FCD9B6CF6C2F9C0DCC9F75700A4FD052D
+:1036700008C55795A577433E1DA7C9C0EC7C938B21
+:10368000E07D49B2BEBB10F07715758B214F9EAE21
+:103690007ED7174903F191F69E423DC415AE268CA4
+:1036A000C18A11BF9A72BD89D51FCC3C36F3D10CAB
+:1036B000BABF866C26B0338023E08BEA44DCE7CEC9
+:1036C000823C7E174009F9ED4689040C0CB658F18E
+:1036D0003B442CAF5F3907B9B9988412E9FA420725
+:1036E000B4F7286E0D1942A3E17C470A7502FE0C5F
+:1036F00016D9E8A0E35494090580F7FA75839BEF87
+:10370000F1CC0F70BEF5F0BD2B98E73704CCE799EC
+:103710004B851EF8F40E89EC130B18FD800F1B5C13
+:103720007200DBAD647CAEDCDF50E8924FBB57E348
+:10373000772E9F1FEDA7C50EEF9BA2C74DCE70F948
+:1037400050FCB4655C6E97297CF7AC565E6D5932BF
+:10375000FB9E1AF883146F73398CC5F7F159ACFFCF
+:10376000F82C165FFBDB658EB7DC4C42B8EE17CD4C
+:10377000484765DC591C5AB258FEB2320F857F6B40
+:103780004923E6DFD4F2788C816A12CCD36DFB3EFC
+:10379000E6F7EBF384A8838479674BB7EB9FABE242
+:1037A00039A2462F619C5330F52E84F9095F89F3C5
+:1037B00000BFCF35B5633C40DFCED826A09C1B5B55
+:1037C000A83F25F0F32D5A36B70AF8FB0E73337A6B
+:1037D000C7E1F7CAB95F5DCBE94AB5F774B80754DA
+:1037E0000BFE149E7FF1EF446D617EA4C4FDDF05E6
+:1037F000AD5A3F63EE7A959FC980E65EBD59971F2B
+:103800006EE4FEC67153EF38D0F7FA7BF6C70D6C45
+:10381000FE815482F991CA3D7B89FB930A3F0DC911
+:10382000326ACEC594FB9C55A0A7D8F70E74F95404
+:1038300056FCEE4A95C0BF57C9E38A67A9BF89DF26
+:1038400095391A87764B8933F694D8028644F89CCA
+:10385000252BCF4BBC7B26F89955769304F0A2A17B
+:103860001BC7592D76D9B2B32371DC8D25E3B74040
+:10387000DED0ACADA3675932F19483DF471AFB1A4F
+:10388000E4ADCFF99CCE1FCBE36679E9FEA8E7E56E
+:10389000DE3B2C54452FCACA9B25517BDEF358EFE3
+:1038A0005628AFCE9A384BA276B0E7C1DE2CF88608
+:1038B000F0EAADD7B0FA26A5BF6B66417E70CF1394
+:1038C000AC3C87D607C0CFE5F780AAAE1650CFAE86
+:1038D000E6F647891F55195E62700AFB9D8F4BB54E
+:1038E0000B6455AC063F47B49DC2DF13D82C7BB1A7
+:1038F0007C5F866F7E16ECA3660B0113DC8B7F3337
+:10390000388ADBAFA8BF7BB13A93C9E5BA61AC3F57
+:10391000055FB49FBAACC2CBEFC701FD146AFA5978
+:10392000F965E673B4FF7CEEF932F3F1CADAF928EF
+:10393000FE99F29DB957B2BDDF81F92DFB26DB0F51
+:10394000935356CDFDFF738DBF1C0576FFDCB3E6A8
+:1039500024E0C3653FFD55562DF87FDC1F3AD3792F
+:10396000C40479DF2BC2ECBB380D61F69D9C15BBFE
+:103970003A4DD3C7421E6BA7A95435BFFAC8EF5CB6
+:103980004937AAFC9827B30C3CDEC67ED771D94FC5
+:103990003FC0EF092E33B4BF0F79BEE46A1647D398
+:1039A000AFB399BF770CCEFDA3C40BB66531BFE3AF
+:1039B000628E3708EB5C9745B02CC6F86ED787BC93
+:1039C000BFAA78A6C76B8A6C1699E2BBF04D5F332D
+:1039D000E49DD63E955D20D2790433A6FC386BC0B9
+:1039E000F8662F8B6F76B0F86695ABEB2E6AA4C89D
+:1039F0005FB6CE7DC8722D21373C4EFAEEFB41DC1E
+:103A0000B0CCACC8CFAA595327B3781994F767D56F
+:103A10003F04F2B39FFF3EDBBC89E3E241CEBBB380
+:103A2000130C0E2AFF3BD3ABFF027C316FE2B5D300
+:103A3000E17989D936AA9AC5C7913F76A65784A05D
+:103A40001EDA43DCC3670AA5DC4AD7E1FBBD8879EF
+:103A5000D3BEBC045FB47B2A7BB8BDFA4B163B0FC8
+:103A6000DA6FA0F32C88CC43199F72FC5D5D10B710
+:103A70005A37241FFC687B46C9A9ACC2C8F8F60CAB
+:103A8000DFEBEAF1E972F3E0F960E77188D3E31460
+:103A9000A75BC56411BE94D0A7D76F9C9AA029CF0D
+:103AA000999144BCEAB8E99C744DB9B22A47D3FE57
+:103AB000F6856334F5E5E6AE098D97E1EF37D89EDC
+:103AC000C1FCDEA31D17DE9A0B7EEC76D123D0F568
+:103AD0002C7971C75B907F7D167E82A480C5C5D886
+:103AE000F71AF9798CE49534E731075E3081DFAE5F
+:103AF0008AF3EBEEE51DC438BEFE3C46C917FFB2A3
+:103B0000E731D230FDEF797EF40A5D1929DDDD89D8
+:103B1000F4693EC0F2989BA9DF02DF13FBEA2E7323
+:103B200010BEE1FEF1AF4E9864D5B94C43B8097FA1
+:103B300057B774F7093CB7D991C5F4F68A8E4F4D43
+:103B4000704FEAAB1D2B519EA753FD9548F9A6ABCC
+:103B5000938CDB05F1E46C1BE6E12C6BB91EE3D41E
+:103B600089E1B908EBDBAEC7FE96876FC2F20AFEA9
+:103B70007BBEFBE3BBA6831DDEFF0B27EE075F13B7
+:103B800043A39E847ECC36D40FE5E9F3D6819FB063
+:103B90003F3E30F64E3A5EF9CFBE8A79E82B760981
+:103BA00018372D17C97E01F2EFC371D85FB9F8C776
+:103BB000092BE9F31B4A995D2D071F87D68B45B664
+:103BC000CDF83DE918BF93E619C6F48AB19BCD7BC9
+:103BD0005A7836F6A7D4170D1BAEF99E9F3165BBF8
+:103BE000B4C01A598FB15B40F8B5F018840DBB66AC
+:103BF0004B907FFEFBDCEF27039E687BFC3E587FEB
+:103C00007D3C319144D15B0A34733D3C17F4309CC8
+:103C1000DB677B670C4B81DF23EC962CA047AD164E
+:103C200007F82F338BF3E55AD5BAC4976EC37B10D0
+:103C3000E6E45E23D8EFB914AAF5F6FC1876E6C6DA
+:103C400061CA3D9B26F6FBBB8A7E7FF7EBEC3BA867
+:103C50003C3EA0C8D375C30C9AEFE974094C2E0200
+:103C60003F67E702D3B37D0B61BE5D25A4F279D433
+:103C7000A35D59701FFD3F357F4A5F0BD0DF2E7566
+:103C80001388632C19A6D81D26CF979AFFAD7CBD4B
+:103C9000AF89C40F7CF1DA75D77579E9BC3AEF1DAD
+:103CA0003F1EEC8232DE3DC3589E2971F47E8EF9B0
+:103CB000867B126488EB97C399C784883F0FF98885
+:103CC000103F6CD8637E1A3E90DA60A7FB7B2BE432
+:103CD00005C685806F3B7F1B2781FD1833C277CFD8
+:103CE000B042783E7A2A7CC7C7DB619608FA41DE8B
+:103CF0007B015FB1E67B29FDA5C8A39ECF7C2D4C3F
+:103D0000FE7C5C0EAB39DF2EE072582D7912E13C5F
+:103D100066FE4111EF452E58238CDB05F101D98653
+:103D2000F7F4153954E4CD087C391EF893F1657D1C
+:103D3000D8C9E53B9BF7CBE4A05C64F976E5639CCE
+:103D4000B87F5E114EC2768ABC2A72BA3EDBF76338
+:103D500058777933956F3A8E6FDD9009202F113E99
+:103D60003139809F289FB86B557CD0DCF999047C51
+:103D7000629C2C209F98292C55F151459F7FE298F9
+:103D80009E4AE731737D367E4F59A9FF591FBF0CFC
+:103D90008EDF9FE2ED17584323C1AF3536C679E079
+:103DA0003BF2679365D463AB3609F8E384AB8C15BB
+:103DB000A5E05FAC7A42C0F81EF81DA07F8A0E37DE
+:103DC0009AD4E720B785F3F0BCFAA6F00884C10CBA
+:103DD000DF8BC017D5E15B381EF3A29EF79D6FBC49
+:103DE0001FE36AE783660FFBCE98367E57E8F5E05F
+:103DF000F99FF1A0916C9321EEE613F17C2F93389B
+:103E0000BE2DB0F81DC4F394F89B724EA7C4E1CC4C
+:103E1000F03D5C951DBD20B565C13EA45F3CAE8400
+:103E2000D9FD8FB61BD9BDADCE3F161968FD87D918
+:103E30005E8CCBED73FBDE86F52CBD31F853232D64
+:103E40002F7BF0053BC4CB157CB64BA191B05F6ACC
+:103E5000A77884F8607BAB581664FE4EC26C557E22
+:103E6000452CBE5E1ACE41FC28F646D1DFBF5CEB86
+:103E7000C64DA9A2C72F658714FE5ECEE56039C87E
+:103E80000151DB9BD915F0BB662457C07BAE117B7B
+:103E9000C3E441D1D394DF516ECA733231AEAEE880
+:103EA0006DBD3DDA2BB67FFB6A3847937D7132C515
+:103EB000CF949FFCE385776855FDF33F9A0A742AF7
+:103EC00019231038C7BC949EFC7FD95BF3F900809E
+:103ED000000000001F8B080000000000000BB55B15
+:103EE0000B7854D5B5DE67CE9C9949322FF28020ED
+:103EF000249C993C0825E0F08884879F0702018470
+:103F0000E0046F1135CA2422CF840494CF28F4CE64
+:103F100009090894DAA0D6528B7642C1528B6D788B
+:103F200058D38A303CA441AD1DAF7DD02A7450CA0D
+:103F30004B9088F582B754EE5A6B9F939933495052
+:103F4000DBAFE3E7B7B3CE5E7BEFB5D7FAD7DA6B7B
+:103F5000ED73100F7E2EC94318B3AE2C678A9DB146
+:103F60007BA12D81F63AFE6E634C624C69059AB1D5
+:103F7000A879A623F6DC299B18CBC0E70D8C153158
+:103F80003643E77B7F3963B73076BF9BF15F3D30C7
+:103F9000F565ECDA0013F14DB1B239FE42786E8E60
+:103FA00064C7CF57EA9920CBC09A270B34EF8C9582
+:103FB00051B32D1DF8EC36F7360FD0C5C3E4798523
+:103FC000317EF12BCA5D26329B900AF29AA32CB562
+:103FD00010E7D7E556F93A5F22779AC6FF3B91D5AD
+:103FE000B7C2F8DFDD765B4401B90EAC18314294FC
+:103FF00063EB15CB16DA5F591A8C1DC958C76BD6FF
+:10400000D016909BC17C02F05F7A6D50683D6CEDDC
+:1040100004EBB8C68056F7A6C8B8AFDA7D29C45FEE
+:104020009BEC0A09D05FEBECC8F7833C25FB93C2FD
+:104030006C28ACB33FC9CC60DD2B390F14CB45F8ED
+:104040007CE044C10942EFB59A19F0A9D9CA68D4F5
+:104050005B4FF2EBF225B6FAFE4BCB05D5E5626C71
+:104060005A89433541BBE86A0E6323185BBC762A44
+:10407000B5AF043341C98C4DBA5A0ECA60ACE6EAFA
+:104080009DF47CC9D514A2A77D3B528AFB61AF0881
+:104090006C1BC85FD6EFBE550CE46B4F6643F6C091
+:1040A000BEDABD59BE46E8AE6E9E4AFC65BF983C7E
+:1040B00005F7B5640F30E3B8022194877A3A653783
+:1040C000B1DE8C3D64E3E27F5AF7A791328CFF7436
+:1040D000A4631803D64362EB536304B2673BDA73FD
+:1040E000C2CFFEB1FB2FC0275D159902F258AF0A6F
+:1040F000D446E4C022D407F031067CD5BBFA8E0C3E
+:10410000D8BF0A9E7E25C98047A9FA1309F16485A4
+:10411000B624AE7F8E8693443DD6CA1CD75FD50F9A
+:10412000EEFB8A785A8578CAF88FE26915EAA91BEE
+:104130003C3522CEFE553CDDC08E3EE689E16CDA90
+:104140009B1C1F2CC7E1DBC6082F2477BB252BD473
+:10415000087CF7A25D115FD7591DEA730EDA372D7F
+:1041600086D7973C819FC4DBB93D592D5C5AF855E1
+:10417000EC7C37C3B8716F7A1D53E0F91C68E3E338
+:104180008615ED57D8757F3BBEA69D9FD5F8BFCC51
+:10419000CEAF6976666EB0E348B29F8C764DB43B85
+:1041A000DA15ED5EBBCFBAE546761D9C1B68EF2E97
+:1041B0004E3077B209E58CD9C57A27E2E6D3B099BB
+:1041C000A17FF564576913D7BB4EAF0E9BA784E858
+:1041D0003C6069E543082F47FF9DF85356D2FA77B4
+:1041E0005B2FC6CEC8757E33F0CF2A86AE9BB07FDC
+:1041F00069B362C6F8027F8EA1191566237D6AF441
+:10420000B2C844D8EFB4A73AFB55EC9F34CEA58D85
+:10421000670A6CAB93FFB45C1BD9407237733B06E3
+:10422000A266FF90387A24D08E38BA3881DECCF975
+:10423000F11C71D33C211EEF617E6138D2FA7C9A69
+:104240001FB08ED25E60BF197B04F77AB0F73DE3F2
+:104250002E59D03E6525D123FD60BFFF273FEAB729
+:1042600027C1738C83206FB2A7A159356BE3C17F3F
+:10427000AA35355A5B0545043B55170B21AFA7AB53
+:104280001E933DC6F30C7F66E3786619F9F5C6A365
+:104290001D69BC97C687AD5F63FDBBC63125D44D94
+:1042A0009CCCD4F9AE01ADCF0FBABB13F617EAC65A
+:1042B000DF640FF79F88C954C3405F059EEF35DB6D
+:1042C0006E05FB328E8F6F789EF6AB855C5C256148
+:1042D000BF3792D7E9D1FD38B65FD9383E7C237D10
+:1042E000A577D197868F0546BCB8CCFEC39F821CAC
+:1042F000AE74C1AD82FD97F893363017DA5FC7F719
+:104300008FFC4A7FD85F12EBC4AB11DF21FF44D092
+:10431000E312A6F76F69C673C96FEAE4E778DF2B8B
+:10432000748E2F00FCB8181F3FD1D3D2ACDAC91E4F
+:10433000D44F74EE0DF0DE9A408F4BF00F0DDFE49A
+:104340009F18B7413F79DDC48D4A4DBF1705361B15
+:10435000E35E6402CFF7225EDE3678787EB750D314
+:10436000E352AD8D24C7E9A17FCCCEF00BB302C3DD
+:10437000BE494F77A76BFB56C3FEE9B0AF482A1B77
+:1043800022004E56B4EC6D6ECA8A8DFF564BD88F04
+:104390007AE89C4FDD17C1B87FB7A6A78696FD11B6
+:1043A00095C73301FDAE86000138D823A822ECB3AF
+:1043B0000671D0CD3EA775F51B3561BC22DD607C52
+:1043C00079571C2A09E39994FE75C66B769A9E600C
+:1043D000C72909769C984057E874C810CFF438571D
+:1043E000D5B671756F9063F176018F098CD7166120
+:1043F0001863CF78DEF0DB47235E65A91FC4FC6736
+:104400003D6F456C80E5728C6784DFDF362B6097EB
+:104410003BD1DF897EDBAFB8103F75AB33813FE422
+:10442000F95DB30D58EF69DA28614EB3D5F34EB399
+:1044300019EC77F7C85F1CC1F9CCC2BB91E9C20D7A
+:10444000F0DA9CB08FCD09B49AC0FFF497C4F7A6F8
+:1044500084F12B13FA3724D09B12E8B5C6F195737B
+:1044600005F2934AB01F2AEECBFCE6D79ECE7CA184
+:10447000F33C13EC942719703FAD91D3873D27FD92
+:104480006B0BE3E8960FF47848389618FFDD9BCE67
+:10449000543C3FA41EE2D9AE9EE25941E279C7FBEB
+:1044A000FF8A7FF6C5BC9319CEE543A2913E20EA70
+:1044B000FED61179D88E0F75FA921FF3F169DF37A6
+:1044C000EE0BEA42ADFFA27F22F8FFB4EFEAFD1740
+:1044D000FD4ADC3E75FED27F5E1771BDBFB45CF055
+:1044E0006F85F92A2684F3EAB04DE52D9C33229E90
+:1044F00063B536EE4FA5AF897E3C672A92C379CB70
+:104500000AE3F6C95AF3719F075688641FB591D71D
+:104510002355CC6761500A1D70B9EA5F00FE432B3A
+:10452000C47A3CD74ED4A7F546F9077B79BD77C846
+:1045300035A0F783401F4899639181EFC0E393A8AA
+:104540003D282A6B3A00C7573DD7FCF641D8EF22E9
+:10455000FDFCBDE58ABF01E2F4158F4CE303A9EE33
+:10456000DE6D98AFAE97D83619E5F13D4FB8F98EAC
+:1045700075D87A90A3B261706FCCDFAABE575EDAAD
+:1045800017F8AA564B3E81F8D850943BB07E92055E
+:10459000FBE73669AD3A99DAFD5FEC7E7328F07778
+:1045A000AC137D5B8079DF55AFB30AE4FA3089C77D
+:1045B000E10F2EE43A51CEEF7A03A217EC5AE974D8
+:1045C000240B7878B865E74C9877438E62F616C569
+:1045D000F8F77F21CEC17CF3D50B55BD03403BBD21
+:1045E0001CAFFBAE56F5AE8A3BEFE75D34939EF70A
+:1045F0005BE48731BFDC9F9C25A8E4C7AD69E5E09B
+:104600002F73B5FC1AF052BFBB9B73FF1F1E917036
+:1046100076CA5ACF3E04101FF876C63894531F57F7
+:10462000F4FB40A303F1DC5F1E1E9F47BBB227DCF7
+:1046300084FB88E12CF51D3C2F298F063ACFEBDA5D
+:10464000A802AED821C8FF518E74A514FBD94A60C8
+:104650008038C6325BF3E3EF236279EA2A2D1E70BD
+:10466000BEE3AA83EAD6E33B924258CF1C57DF73DE
+:10467000307B3C3FF793F94E878A87F11987C38CCB
+:104680007A3D610E9E7E14C6CD7B4EA2383AEFB9BC
+:104690008C951D180FC09E79ACEBBAFFED9568DDC7
+:1046A0001EFD84C9E513C7C5F9893AA01CF7D39349
+:1046B0009FDCE61D50BEB5B0673F99AFE5EDA5CFD5
+:1046C000497EC4F9FC228799DD0C75F673AF6F4300
+:1046D0003CCE5F9A34DC0A82CF7FCE4AF68D3A1CFC
+:1046E000AA1BFA034E87B917B4FFA5E121DA90445B
+:1046F000758AD8DB42714F5C5324A37E4A4466B668
+:10470000C1B9223A7DB29FD34D6EA8DB563B8A6574
+:10471000B4EF0AAF4C7AEBEC77CDBE5D80BAE632EF
+:10472000EC230DC69DAB7FEA995120DF79169A35AF
+:104730000AF47E190D0DEB5CDE238654AC8BCD8A1A
+:10474000B90CE2DE02C6FDBDE6E86ECB78F8734137
+:10475000DDFCE9581F2D0C491F44B5DAE73AFCFF90
+:10476000197BCB82F9EDE2EDC6E7E03116F4AB9AA6
+:1047700056E3F35AB6E1137128B6E60FA205DA73D1
+:1047800058B7FEFD3F0F391CC757ED75A49F1E0C8F
+:104790007F0C67C341B3B04EA1EB2E845DBD48F2E0
+:1047A0008AAB9242A847319B9F0F9399104A42408F
+:1047B000B861DFB0EE95E0B121870110E2632348D4
+:1047C0002FA78280A781A00FA78DF8C5C7C4901519
+:1047D000D62D49634A2FD4E733E58C39489FAA1B6D
+:1047E000E8C9E975668C4FE7B4F85229307F2BF998
+:1047F000BD2F1BEBE379CF2591FDE63FBFF08F3F47
+:104800001889F62A4B8FF7A3C735DCC17CCC961AE2
+:104810009BE74CC3B7B2519E921F415D89F5A61824
+:1048200078E66E8A97293E8A5BEEE87746214E1A33
+:104830005286AD678893BED9DEC2D8F8F9AB56E48C
+:10484000F3F150AF3A315E25D17EAAF7580927958A
+:10485000EB4485CEC72C0B9D8F1F3425115DDDBF2A
+:1048600098FCACD2C402B80FC8053329AE7395B317
+:104870006A3B5376DB31CE6F88884EB28FAAD9CD92
+:1048800082F6D9E24DA3F5E7A08EE1DC3AE8D5F453
+:1048900062E2F861FB84D0368A4F7532FA7F85492F
+:1048A000A03897E88FBB3109C371D9BEFB715CCDCD
+:1048B0001356DF2A0F9741D4E5013CD59822F37EA9
+:1048C00088F3FED24AF71AB5B08F2427D517CA2E1F
+:1048D00090BFD6CCCC16BC9792793CD3E5A995CBAA
+:1048E00027234EA1FF9819FA6B1C3C1ED7F4E2F760
+:1048F0003DCC610B6D8B5F0F65CEE1E36427FAD988
+:1049000068C20BFABD09FA2F31DE5FE22C96A3F0E4
+:10491000BCDDC4D6E23D09CA336868DCBA40F71D85
+:104920008A785C6AF63AD00E69B366E37A2F891406
+:1049300097C0999E28C6FCEF257104D6B195EB0E61
+:10494000956E427AE730378A50F9F377E97C5AACB2
+:10495000E12C8A793F9E5740EF84F63D2FCF2F02FE
+:1049600022BFC779CFCBF37F5DAF7A7FCD3A89EC99
+:1049700051B39AE3A1A6E14F346F8D23D21BED51C1
+:10498000F3B2740BE2FA941627AA1AB2C61D037C7E
+:1049900054492EB7008FAAD5320BD2D5CD02D1FA09
+:1049A0007A35EBFED0DB54C8E7C3D6AAE128366FD0
+:1049B00046369E671FED48CBAE8CB3FB474DAF38F4
+:1049C000653BFA4D38CF8DF7304B937C5BC84FB9C0
+:1049D0003D3E6ACADB82F73473DD118700FD731F29
+:1049E000CE49C573EE843B6CC1FE13AD1E13D28A53
+:1049F000DB3D0E69C57C33D11F41086FD5EA56C433
+:104A0000F11281E3A67AC7218B17D64BCAE138BBD6
+:104A1000F8D2BBF9785F50931DC9C7F3177095DFC3
+:104A20000FEDF2A24079C2921DA292343486AB25DA
+:104A3000882BF0FF451AAE96EC79E511F4D3258862
+:104A4000A7E15D710975E5617ABEABA594F1F187C7
+:104A50001177FA790F749384F76A168D8675904EE4
+:104A6000CEE1B881FE89BC5F2DA47384452D980FDB
+:104A7000D78A3C4F007FCAC43CA2B64D523BE325C7
+:104A8000AE8BFD85B1FE9E703338879F27550D563E
+:104A90003A8F066B7A89AE7BD989B8B8F8D2A12350
+:104AA00063B0BEDA25B831DE77F1434D6FB5A82784
+:104AB00027ED93F2A25AD48B33A6A74E7FD3705121
+:104AC000CBB81E74BDD49A353DE9FDDAF8C21C8E10
+:104AD000C36AA6E975CF40EEEF9A7FEBE788BEBFC9
+:104AE000402A1FAFE3EBBE1C8EFB31DA3EAB013731
+:104AF000BE42C29762B945ABFBA1EBE2CE16BA3714
+:104B0000D2EDA9CBBD5C5B1FE2B4D22B3566E7A822
+:104B1000892DE8EE9EDAAFE94FB2F3B872B2A1DFA9
+:104B2000FDF5A0BF453B441F290F6BAEB875ADA680
+:104B3000A883F2D2C74437EEABE467E5B7E3BE75AE
+:104B4000DC49DB0573DB48AC337A91FE75F94AFA30
+:104B5000F86FEFC57117467974394F0A61B297BA89
+:104B60005370F33C376AC1FB43DD4F13E5BD2F475C
+:104B7000D0F201618C7033CAE393D1BF199C8324B6
+:104B80008FFDD80A5A4F3DBEC23334B6CE09D56127
+:104B900046BE138CC7011D9727B5FB8893AB5FA159
+:104BA0003C585FE7A1AEEB04EAD3BBAEA3F32FD62C
+:104BB000F875BF684FE5F82F69FA13F1E971167FB0
+:104BC000780FA7EB53D75B9C5F1AF4A3FB97EE4FCC
+:104BD000BA5DFF55BF622B33285F7D5CDB37F94838
+:104BE000EFD8B980F8C4F3CE6A015CDA0DE726E5A8
+:104BF0003593FB7F620974F35CD753E2F3583DE5CC
+:104C0000CE46FD4FB6679A300F604D998773E3F239
+:104C1000B20FF1BE0BE36906E3EF33187865DC7978
+:104C2000AEE76BFA790DBF0D9DB884F1B5E9CA39CD
+:104C3000EC5F3072693EE6119772BCB4EE79D66AC9
+:104C4000190FF3559F8D943AE558BD72EBDFC3A25F
+:104C50000BEF03F7780CF542F585C3E4DF352CB292
+:104C600006EBDBCA75EF968D42BBFF14F271E09B39
+:104C7000DBECA173EFDCD6074660295BB93A8FE81D
+:104C800085DB1EE4F43A9ECF55AE2E7A01EFE33F6A
+:104C90004C524A11DF1D1B0537D65B63B715ADBCFF
+:104CA00007FAC73A06F442B98F6FFDB06C0CD60D07
+:104CB000F522F98BB2F5A959D8AFB4893EDCEA5C8C
+:104CC000E65E790FE2DBEC227F3BA19D138D12C7DC
+:104CD000D91B5A9C38A8C58D831A0E4B1A1BF34D4D
+:104CE000B86E0B9C4FB0FF0A8BDC1AC6BAEFB53E0C
+:104CF000BE2DA82F285333014767059E7F2FB03064
+:104D00001BE2EAA814598EF21F5DEE18D6800288C5
+:104D1000D76E41BF50B43A0BEA265A57D797BEFE1A
+:104D2000512D8EE8F3E8E3DA319FC2F34393F75C49
+:104D3000D34F67619E706E7B5E2A8BD3FB39DC1785
+:104D4000E87B21C4C55DDDD47F7FCCD1EF23427CDD
+:104D50001DEDDEF0A8D4DC1FDFDF421E7F2A3E2FD0
+:104D60003FD39264433C421E6F7C2EF1F304F278F1
+:104D7000C373F09B53C67C5FABEFC40A57A09B384C
+:104D8000A4B78979FEB91C7BFAE914D625CFD7FDE3
+:104D90002E71BC9ED777DEB3BC6F4F781F33CAC568
+:104DA0006EB0FE852018066ABF16F45D907762CA61
+:104DB0003F7747B09E6CB6BAADA0DF53E857F81EF8
+:104DC000F06591E78936E60B032E4EFD61840FFDF9
+:104DD00070DEFBDCEFE6B50A217CC57E78E3E322DA
+:104DE000F23FB859607D84B83AEBE98DB3D0ED2E2F
+:104DF000FB026BFA02FFE5ED824F2509157B427D30
+:104E000075A4AFDC737DF5EFD655FA3D53A2DE33C2
+:104E100073B5FACAC77C46BDF3FA7C3FC0A7787861
+:104E200057BD5F0806A88EFA38B880DAD1AD2D25B7
+:104E3000FD40FE4BC2C927C6A2FF385C744F7221E9
+:104E400058472F013F6E1B716D06E8E755BBCB8DB0
+:104E500071E3E3603D3DEFC48B86CF5BF71C10FB35
+:104E600031E2DF3B16F8F7D95DF85AA39BF76DDC0A
+:104E7000BE9041F1F7A35ABDFDD0D2517DF0B9BE2D
+:104E8000DFF38F723BEBF29FDFFE8013F3D3033F20
+:104E90004CDB3B1AED9BE272238CE66F12596004E7
+:104EA00063A737F13874D6E67A613AE8EDECE63B71
+:104EB0007B633DF8A0D461F1C1BCBED7CA9D787FA9
+:104EC000F63773D4E9C616F8C32887392462FC1B69
+:104ED0003385D17BC0316133933DF48A9E7032FAC1
+:104EE00082391406FA237C3F88E7F6B564FE9E5E9D
+:104EF0007BEFF7E0AFF87D5AE7FD89768F3056DB20
+:104F0000EFC3B9A95C4FDAF39262FEFCCCE6DD3365
+:104F100070BE735B2537CAFBF15689E65F0475BC2A
+:104F200009707816F086F16BD1EF451F42FADC76F6
+:104F30005E272F02DCE27D71CD5249B1B8BAE2B1F1
+:104F400044E7DB2B507DADE37291122A25BD6BF84F
+:104F5000B4C17FD7E1C8E8C55AD7A03E1271FAAFF5
+:104F6000D6FD8B1197DDC583041CE8FAD2F110C37E
+:104F700027235CEA764F6D1D36BE1F0D50295EA8B3
+:104F8000135801E6058D165660461C98927DE8E799
+:104F9000F536E750BC67BA92C4DB474CEED7B15E3A
+:104FA000BE62922501DA13B91EB2C323A26F12D2D8
+:104FB000527A94EE07C4129362C2F3AED14AF12240
+:104FC00031DE3C9ECBE3703F041BB43FCE75532BC8
+:104FD000B13ACA1FF416369885F949794AEA673218
+:104FE000B03CBD75CA4C33ECAF7C6CEAF21CC82CEB
+:104FF000376F9D3113DFEB968F487DD90BF4F3B9F2
+:10500000659CBE39B54802BAA1E18E991381FFD5DE
+:105010005CE5C9DCA2D83AFABCF0FC7BB940BFDE43
+:1050200027B009DB5A8B7D2DC6FB4B42C712931864
+:10503000E37F4760275E1562745462D9984FFF186A
+:10504000DF7915F5DC9EC9555A72BB795EC5D86A01
+:10505000D46395FA9B6398AFC1CF6F03BCDDA1E128
+:10506000ADCA660F232ED85AE942272EBC18975C8A
+:1050700066F4EF199AB9EF30870FE0F841ACC97DBB
+:10508000DA46A9E0E6EB693DC779704C765A9F0F86
+:10509000F6774982FD825D05056C0D2E2580922BE9
+:1050A00020BE097B7FF339CEDBA8B26812D9A1C23A
+:1050B0008D71516001D375686B52000FA0A7652FE9
+:1050C0005F3C8CF05FA8E75399FCFB8CE51A1EEF60
+:1050D0008828DF6F01A1CE04597A2ED8FA223BF836
+:1050E000B119D63D670AFC06F55D6D7A2B7B998C6C
+:1050F0007EDBE8C4FCE5E2CF45DF741857ADE5ED93
+:10510000EC9A18BE0D9EB77B066D591F87A3482EDB
+:10511000CF172E78C2D92B307E7878DDC9AE1DCA64
+:105120005E01FC53BC538BF05C7A9A29FF931BF70A
+:105130007E7186B9FBEF2FDEBC89E73B6C2B3F5FAE
+:10514000AD66A63A52A9654ED0C75490A518680915
+:105150006891DEC787687DE473629E223F90C9DF55
+:10516000D7303FFAA36E47DD3E5DEC0622637E6ECC
+:10517000B23109FD6510DBEC46FFD6ED3749B4537B
+:10518000BC59F632BF8F5B26449BD2907E09CE4B32
+:10519000D497E6975DCFCD6D1634C582CD0F507C88
+:1051A000D2E3920CFF217EFE53F792D7F57373186A
+:1051B0001B86B8FAB27C478F4B601F4B5EC6D7B0D8
+:1051C0000FAA08F63B5F5B7B9258219B512F193643
+:1051D0001FC6E565CFE5D079C79A9E64F17C6C73F4
+:1051E0001AE1738D47243B96B5F563323C5AD826B5
+:1051F0003019CEB9E96D69443BAFF625BAEC277D8D
+:105200002660FEDFF9DEF22703893EF7C29B230307
+:10521000FC7EC586F3FB992E47612BE64397ED2074
+:1052200007D8C16F5F4BF7857ED659C708D705A44D
+:105230000125E84F8AA472BBD81AC8AFB57D2D737B
+:10524000733B2E3BCACFDD65E3F9FB3DB33AC8851E
+:105250007890DA451602FA9B47C5A230B0366A71DB
+:10526000D99A6962729C3D92E46426C7D56F4C5509
+:10527000225827CDD6709252906AE87F5C08482861
+:10528000D76CFB3CC28DC3779361BE4876693BE91E
+:1052900023C0F35B1D4F4CBC6046393F1B27B03425
+:1052A000C0C53767437FDCBCD2B84F260AD41AF397
+:1052B00062D0CBA91BE1696A9E86A7416C10E129E7
+:1052C000413FE01F947F5E86731CD326C82EBE3FED
+:1052D0000EE859ED120BC9946F92FF5C5652E8FE2E
+:1052E0007EB5A6271D77FE81CCA1C0BCAE62A3DE31
+:1052F0007A2946BDA54D31EA29C36FD44B9FD95EAB
+:10530000437FDFC0370CFDFD160C37D05975630C99
+:10531000FC03EA2718688F7ABB813F67ED4C039D39
+:10532000D77C8F817FE0A62A43FFA0D02243FFE0F5
+:10533000EDCB0CF490D6C70CFC37B7AD32F40F0BA5
+:10534000AF37F48F687FD24017459E35F08F3AB65D
+:10535000C5D03F3AFAA2A17FECD95D06FAD68E5F9E
+:105360001BF86FBB7AD0408F676F1AF84B6CEF1A3F
+:10537000E849EEF70CFC93333F34F44F953F32F499
+:105380004F2BF8D44097F9FE61E07FF6A6C0268C3B
+:105390003FB34D1B8EAB0CE3B3FCDD7180E7BBD29A
+:1053A000CDBE30327DCDBA2D94A7E5691A6E3F632C
+:1053B000F6FB4DDE2F8F83AB312FC8405C4F6778F3
+:1053C000DF7BB955205CF7743EBB20DF35C7EDA30A
+:1053D000976283023C46A74D711BE80C7FA681BFF4
+:1053E000CF6CD9D0DF375060E8EFB7C067A0B3EA21
+:1053F0008A0DFC03EA1503ED51A718F873D6FA0DD0
+:10540000745EF36C03FFC04D0143FFA0D00243FF65
+:10541000E0ED75067A486BBD81FFE636D5D03F2CAE
+:10542000BCD6D03FA2BDD94017453619F8471D0B51
+:1054300019FA4747B71BFAC79E6D35D0B776B4192E
+:10544000F86FBB1A36D0E3D951037F89ED1D033DB8
+:10545000C9FD6703FFE4CC9386FEA9F239437FF5CB
+:1054600047003FCC9F5F15E8FDD7B4824F0CFD523B
+:105470003AE4E9783FCD927DA2D0354FD7F3B732E9
+:10548000DFE786751E31D5D17771574C3CAFB3E459
+:105490007B097790BFDB6C1467E1841A42572D0DAE
+:1054A000989FBA54817087A94605DD17A6D37B055E
+:1054B0003A1A65FC0E0DF21B20524D1E0FD60F2915
+:1054C000B13CB4FFF5115F3D0F4DCF67FCBE293FE6
+:1054D00090949F81F5D8CE52AC4F1632750DCA010B
+:1054E000E7AB0BDF33BD9D64BC37D2DBA936D05FA1
+:1054F000DC7A47939AFB0FBF81DF4EB55D20FECE6D
+:1055000079B57B2501F6B72C6EFE27A06E324309D4
+:10551000D91C04FF023F7D32E826FAE96026D1CF8C
+:1055200004656A37050BA87D36E8A3FECDC162A2EB
+:105530009F0F2A44878253A8DD12F4D3F3ADC1D95B
+:1055400044BF100C50BB3DB880DA178375D4BF231D
+:10555000584FF4CF832AB5ADC1B5F47C57B099E864
+:105560003DC14D44FF3218A2B62DB89DDA5F075BEE
+:10557000A97F6FB08DE87DC130D1E1603BD1078359
+:1055800011A20F078F117D2418A5B63D7896DA3742
+:10559000821DD4FF56F02AD117B4FBFEF1F9FC5E50
+:1055A0004ED78B4E333691F0A0E7B533B06E4170D5
+:1055B000144B1F1BEA9684FA21D11EE7B575A40986
+:1055C000706C639E7353FE96C6B87CBF4C5BEFF164
+:1055D00064A62641FC6BC0621EA0D890CA428DF41E
+:1055E0007E95E7DDF3355CB2749E6FCFD3E49AAF5E
+:1055F000F94311E2B380F0F9D6D7A993F43AF95BF5
+:10560000FD03F7113EB34C2ADD13D843F998F78711
+:10561000FA0702F920DFE5BA078FD07A6E5F3E2ED7
+:1056200052660D67DC85F73F4745BA2FED69BD5AD5
+:10563000EDDF2FF4D8BFEF5C7F3C87A67C21D27DC5
+:10564000FADB926336DE8F2CD3F4B22CDF6468076A
+:1056500066F997A29C67F2EA5E7808582A96E6B93E
+:10566000306FBD034B6BF0FB72264BF47D2C535E09
+:10567000C74F26BF09891DD2773195DA9DFD028F6C
+:10568000E17EEE860202E9C0186B7677FB4994A7AB
+:105690004993A74993436F2766F91B71BE53798AD3
+:1056A000419E47B364ED7BF78EE751AEFF7DED93EE
+:1056B000D3424E4CDFFABDC49AF1DAF7534B05FDE5
+:1056C0003D35CF076D4CCF07A9BF6239BF9FB90FDA
+:1056D000EA327C5FF9BE160F2FD749142F2B846452
+:1056E0001FE6D397EB960FC4FD24C6CD0A18678238
+:1056F00071158C7F0F51F17E0AE10BE663F8DEAD88
+:10570000023277ACFFAAB3F47B8FA83D83CBA3E032
+:105710007BD8397BAD2D58A7024EB6104E468BAACA
+:1057200005EAE4B74DA17C41247C580490777E3A89
+:10573000E0A39BBC40C7C112EDDFC7E8CF015F3BD0
+:10574000507F1FFF6A5401BD37D9375A46FD359A3D
+:10575000C01E785FF386C8BF93C02B76FC8EC355FE
+:10576000D842DFF9631281F61AEDA0F721074456FB
+:10577000BFB39BF8F9DB7C5E5FBD9D294D09D1BCB1
+:10578000C6F77C47343B1ED1EC5B76F068D62330FD
+:10579000EF927689EA1D36325AE8EFE6FBA6DAFA8E
+:1057A00037FBE6C6EDA3B6ED24FF2E8A450BE3BF1B
+:1057B00087FA9BB6BE8E27D1E208B4D8E3E5E3F7BB
+:1057C0004580EBB7345C9FC6BC7E865576DD0543CD
+:1057D000A3A09A30B4811FB9E9BB3AFDFBBAB9CC9A
+:1057E0004FED7C8003E2D8AF6EA4FA77116BA5E78A
+:1057F0004B8A1FC846BA96754CCCC4FA656DC3EB8C
+:105800009920DD9DCD1B27E1FDF3CC50E5EBD8962B
+:105810006F154E63DD0D7E711CD78F0A75ABB124F9
+:10582000BD67C7F8D578CF3B43E476606F723B0025
+:105830008E1431B5EBFEC00F4EE178F003925FF7A6
+:10584000838A551C3FFABFC7E8F48BE2C57FED871A
+:10585000EF3ECC1DF45D48ED3E6B2AE26B11569E87
+:10586000627C5EA89FCF3C2F580C7901F29D97B8BF
+:10587000FDCF1F4FA27FF7725E007C0CEF8A7B3D4D
+:10588000CFBC62E2F76E8F88B04511EBE5A7484FB9
+:105890000B6CA1A1A827389FBF401C2EFAB075CD74
+:1058A00030BCEF9B10CAC67C557AD1EA6BF418E283
+:1058B0003CBB9E12BBC77B42E2F76A89F276C95BAA
+:1058C0008A8F7C8EF984D5C2547C9F04FECFFDFE66
+:1058D0000497FF8A2990798BC8F315AAA3FBFBA92B
+:1058E000FE67BD6DBEF542D7F59BB475DBFFC9EB16
+:1058F00069358BD1F7388972086EBE6EA23CD664CA
+:105900002E877EEE749587DB4197277FA087DF5334
+:10591000642BB4EF06532F8A5F97C440DE403C2FC0
+:10592000B5FB31BD8E6DF79CA1B8CEAE35F6E7DF85
+:10593000F7867B3A4F2F74D6CFDED879A7DF33B105
+:1059400071DDDF0BFA6D6E09ED3693F928EE0F620B
+:10595000EFEBFAA17BA6FF0732EFAAC6A039000041
+:1059600000000000000000001F8B08000000000085
+:10597000000B7BC8CEC0F0A31E82C539106C6271CB
+:105980002D0B03C37B56D2F5C17005507F3110E754
+:1059900001712610A700713C104701712810BF0249
+:1059A0009AFD14881F00F16D20BE06C41781F80C03
+:1059B000101F47B277291B03C31A36D2EDFF8DE4BF
+:1059C000E70940761910CF20231C46F1F0C0723C45
+:1059D0000C0C5ABC08FE5E5E5479791E047B99203B
+:1059E00065766D05EA070050DE58A18003000000CF
+:1059F00000000000000000001F8B080000000000F5
+:105A0000000BD57D0D7C54C5B5F8DCBD773FB3BB2D
+:105A1000D97C10120870F3014608B8240141B05E29
+:105A20003E8CD1A206B4482DD505F908494822DAA2
+:105A3000CAABBC66490209883628225AD4054141BE
+:105A4000898D7CD8D406FECB4731F6A98D1615ADCD
+:105A5000B641FB14154844119FB57FDF3967E666F0
+:105A6000F7DE6C08D6DAF75EF8F19BCCBD7367CE33
+:105A70009C39E7CCF99A898D6532CB10C6BEC69F9A
+:105A8000CB18BB59668C8D8994A3EFBCAEACA90032
+:105A90007EFF9BCDBF558DB4D3CB214CA2768CA578
+:105AA000323696B1CB1CF02BB49BF2FC893F5D944F
+:105AB000CCD87E26333B3C0A2B5392AE867EF67FB3
+:105AC000C5FCF8DEF2BC3BBDC38DDF05194B61ECB4
+:105AD0007B8C7F17CE50D37DB95861167CAE39E8E8
+:105AE00077E8276B63157C7FE60B377D6F86432F46
+:105AF000D957161616DF7C9D89FD2A9F75E4887A92
+:105B00000683C19980379DC6D5E13DF4CE0704EFE9
+:105B10000105E055638CEF00F89323F0EF67D7C5DC
+:105B2000B35C0EBF363602FF378587E6DF8FB1FAEA
+:105B30006AF5FBD956C6EEAE66DFCF1ECAD85DD574
+:105B40000EAAAFA8F651BDB63A95EAF50A7C0278DE
+:105B5000A8DFC64241F8DE5B00EDF5FEE0BF3BD7B3
+:105B600061A8DB92E17B47A4AEB8530D7547BA6AD2
+:105B7000A80338475261DE23F823181F7060C7F16D
+:105B80001D4CBB00DF0F25BC3805DE6A3DC36EC867
+:105B900004BC34BC22332419ABAACD42F886BA6DBA
+:105BA0006A08E01BE15E308D79615C6F8031685777
+:105BB000FB2063F7C2F3E1EEC20FF1F913D07F03CC
+:105BC000F42B7B1B8EDAE1FDAA0C9B2A235E762840
+:105BD000EF229E1CF00FF196B391D723F332D687B4
+:105BE00033A8EBF380EF7F9FB0FEA80470D466DB90
+:105BF00054BB1419A77B5DFAE87FD8BA73F73F54FA
+:105C00002D9E8C74AAF73B8C056A7CEEFFBDFD8E41
+:105C100000DC26E545FAD5C7E9B35F58FE62F876A1
+:105C2000D846160A4B3DC719AAFA8B82B8DE1B1557
+:105C300016CAE0CF93811F860A7EA84F9FE10AB85B
+:105C40007BC2C3A2C7C98CACCB50D536C7320ACAF7
+:105C5000EC996512D0075B17F55D262750E4975F36
+:105C600054FB881EEFAECEA1726BB54F433EB9FB1D
+:105C7000EFF2ACE6DC9E7CF8579453F0DD3D5646DF
+:105C80007418DCCE425B25ECAFEAE81CA8AF199D86
+:105C900092B75A25A02D28C774FA5E23A944DF4184
+:105CA000A06F947F66FEB8DB5A7C15D2FBAAD11692
+:105CB000A906F19CCDE97DA835ECC882E76BD665D5
+:105CC0008E0688D91AFFAB1D38EED0A1C388BE87D7
+:105CD0006773FAFFFD98F50E9483DDF35F9AA26572
+:105CE0002731168FEBE38EAC97EF3CE9C037310AD2
+:105CF0005F31E8401FE79FCD0FDF1D7D359E93BECE
+:105D0000D6F8333FB4C3FBADC0E7B2D413AEC42161
+:105D1000E1D4E2DC9EF436341BE80CD7C97F6E3A3E
+:105D200033976BAB43EC3D187C7D752AD1DDBA6AA5
+:105D300095CAD54887202751D6B0F150473AC4F5C7
+:105D40004A2FA07AAFFB155B4EFB51C2D410433EE5
+:105D5000598FF479093E5FA169B045F5CFD1EB2C9D
+:105D60006C01D9BF0EDF0FA0BA865BD85D925E7F53
+:105D700026A8C1F7FD7278BD507A26589B0DFD39D3
+:105D8000F9F745D2292D981EFDFD5D9A3631D21EB8
+:105D9000EAE1C9D9D1FD41FFB9D1F01CA4F67A7F5F
+:105DA000F3A4635A10EAEB9CBC7D8374F45FD2FFCA
+:105DB0006AA93115379A5552375EA89FD57A3DD8D2
+:105DC000A869B9917132963FAD05A3DFB3A70DEF76
+:105DD000C72E6F0C06016F0FB0E22C09D637715633
+:105DE000552AA844CC393BA459D568F838BE23F3CA
+:105DF0005B4FF0BAB2F9FB5CE98F5A6DD4FA4C9262
+:105E00005E0E22FCBA7E63E5A4057A4FFA6D2F027E
+:105E1000BD5BFBDBFCA467A443250DC69B1A642A6B
+:105E2000C06151830CE5815555DE8FE6039DFE0070
+:105E3000CE71046771D5AC5EE00C46C3A9C3D1171F
+:105E4000DC3A1CBDD3291FDF4C4F936F1CF78789A9
+:105E500040E2CE76AB1FF53C54995822FCF2D57D3A
+:105E60009A025DA6DC04B85769DD66B1AC9EFDF60A
+:105E70009F358085A2E6F9CF5ED72CAC8F21BCDDA3
+:105E80002C8D89AC2FD4E744E3719C6867A63F7DD5
+:105E90007E0E9C9F1A3DBF5A4D2988CC8F298DA913
+:105EA000C59EBEE7B7CE593CABD8DDB3DDEF25AE1E
+:105EB000474F9E31EE5AC6C72359928CE3E545C63B
+:105EC0004B9EA98F178A395EBFE2EF169F667ED47C
+:105ED000E17522BC19D1F0F2F5D7E15D6D05BE8DFB
+:105EE000B1FEDF35BCE7CB7F2E90BF2A7C6FC901A6
+:105EF000FECBED9DFFFED9FD25E3AF404F9F2A2C41
+:105F00007C19E0F1F6E98E50508AC8B97F35BE524F
+:105F1000F015ACDFED2FDD72EC320B5680AE47464C
+:105F2000C6AF905482BB37FAEE6D3E8C850CFDFCFB
+:105F30004FCDA737BC7ED772E87CE56BCDEB2E6EDC
+:105F4000DF65B310F27F7DDBE5F10CBEAF7F714AF8
+:105F50007F84C3DE308269F98CDD8F9F805E512F94
+:105F6000F45D767DDE79E919ABAB995607FACB1E65
+:105F70006F15E945F512A3EFD780DE16023DA6E0C6
+:105F8000952D8E396ED4ABEEA5B2DECA488F297836
+:105F9000E5906F0A4CC135347134DA79F54EFDF96C
+:105FA00091A22C787E57363C07D2A8F7F0FEE07914
+:105FB00031B68F1BCA9FF706571CA84D75517877CD
+:105FC000DA428158F2F17B160BE1E75ED4BBECA814
+:105FD000F7AB543A5D8D01243AD7609BBA39A3E7F9
+:105FE00077B32C5CEF5F3BF4D9306E73AB84FE76F5
+:105FF000E0F2C7892F5DD98D9A05BFF773D7C0BD71
+:1060000026FDCA9DABD753A529B067BA4CF5BBF5A1
+:106010007D37A84E427DCD2BF49D4935974EAA8DF4
+:106020007ECF2E9A84FBAEFEFEA69A31F43ED1516D
+:106030007574228C9F08F2B316594751A52AA4976C
+:10604000EB1363D2CBDA2B1DB342F07EEDE5C33206
+:10605000E6C7B0736015699DF57A529191AEEF1560
+:10606000FAEADD427F4D451E8F926B4EDEB45BAE89
+:10607000392FE072CD95A32E47BA4C2A627ED4B355
+:10608000D702FE0251EBE4CC01F9166577242AC64B
+:10609000797D57F37980693FB4F4EBBD7F337F3D61
+:1060A000C00273B07DA2D8A75C397E2990DBF7FCD3
+:1060B000CDF3ED6DDEDF17F884712A628DF3AFC288
+:1060C0004BA21BC629F8E78FE3C271A2FD45E78901
+:1060D00077D84784DF8DC9B80F98ED2A57814F6272
+:1060E00016AAB6A3FD9D84AF00EF1ED658340CF857
+:1060F0003AA978E5AD68AF79DEBEF243360AEA1D0B
+:1061000073A66159979BD73619DAC5FB7DD30B89E6
+:106110004E19E1791576467CB768F924981FE1009D
+:10612000F8EE51CB4D9382B99CBD71BD7F22E682C2
+:106130009AB7A2EFEB99B1E66163618E5FE96B7B81
+:10614000CFEF7B9BBF35F29DF0F72D213F695FDFDD
+:10615000B16936F21B06E11FDAA309A67EE2355BC0
+:10616000C4AFC8104F517578FF42375FDFFA2F195F
+:10617000CFC7EE75A8A807655B7C68A7C7335F0229
+:10618000EA7FAEA9A00880BCF02577052D6ADFEB79
+:106190005207A605ED674077D3A3F4DB3F5BB87EDB
+:1061A0009C3C636AC60AE8F74C01F70327F9B8DF9D
+:1061B000C13C9FBB603F0BDBA3EAB99B897F6B812E
+:1061C0009E32812F82B916F267AFCADEE98BE66B89
+:1061D000264B026F66FA60AA027894057DC8D9162C
+:1061E000CD39EADBD387FC0FD247DCB4A8EFD83730
+:1061F0005F2F8FFCCDE8E3DB8EA7AF6B4FBE5A2E2F
+:10620000D6759E03F59B95A933E263C9D9DED7F510
+:106210005E5A57B067B5508CFE13BBD733D8B34C1A
+:1062200011EB493FB719D64BEE3F76D6A673AD5B5F
+:10623000B2111F7ABFCEA5B2FA57145E8A8FFCE462
+:106240000ED1DF2AF5DE20EA2967706F077CC88D42
+:10625000A3C3B89FB26CE6DFCA9B901EE254B5D0D0
+:106260006AAE2FD3BAE8F0D9D22D86F194649701A3
+:10627000DF6C1668D951F03B97DA080E078E07E3FA
+:10628000C83EE85042FF3F0B3BBDD423F587437D1A
+:106290009D85F53B0D74509F9E1773BF53C4BAA2E2
+:1062A000B9CAE9F5CEF3932FE6F1AE37C27BDEDF54
+:1062B000B915F5FD283F5DEFDF29EC7D1D5F80C43A
+:1062C0001F77D33B5FA79556D622C5833C489DC90F
+:1062D000022AD4F115EC630D588E473ACCF3915E47
+:1062E000B04D52104E626915FFF3FD6E382AB5406D
+:1062F000B7164780F024BB3546EDD5F3DB0FCF5AF8
+:10630000B99E9C2C3143FB65B28DDE2BAC98A1BDB0
+:106310007CF69D2B52A95F0D1E8D8DC061EE77B866
+:106320001C58268F41B2E3F0E007E81F601D39E4F6
+:10633000CF4E13383B3B7F06D913BDC1F7A089BFB1
+:106340001E14F6012B2EE8635E9C8FCFC298EDD809
+:106350005E515D380E3B9E437CA08AF1370733E9DE
+:10636000F9E68673F3F92F110ED04F1FAD7650F971
+:1063700058B58F4AFDFD63C2EED922713B447FFEC2
+:10638000B9CCED845699EF179B1D8D4EF2431F7CBF
+:10639000F0CA61C05F038EC87E27E02F6B913F314A
+:1063A00010435EE865F61A23BF3179F639E15DFAEC
+:1063B000F6A4E987A2F8B149F624BF1F07BF5CCC59
+:1063C0002E46FAEBEBFBB3D5DAF44343BF3D5EB6A2
+:1063D000083BF4F3DA9797939E13BE8CF87380A072
+:1063E0009B01E55C1EA8752CA422FF7EF5358BA6CB
+:1063F0000FD8A92DE84F1F58C2D843D07EF33C8B4D
+:1064000086726BE05A5BC842FCAEAEC67ADA11996E
+:10641000ADA6BAE69E13E58F4F93DF5E0E14CC86D1
+:106420000AFD4CF7ABEBFEFF4141637C62208BF22F
+:10643000CB437F6942BF4B33F9F1BFED7AFCE57F77
+:10644000683D1E53FC2E5FD4F759122B8EB50F9E5C
+:1064500011FB54D6DD5BB83D52E266EF45C52BB665
+:1064600048FE44DC0C1E5DB373BF0DE35125CC3FE9
+:1064700014F09D5EE5B344C3A72871D48F9569E1FC
+:106480000BA0CB15736676EC45B9359119E4580C21
+:10649000F9A128F85D32971F8FAD99C1CBAF647217
+:1064A000EAA4055908E35B53E755EDB7A22828672E
+:1064B000E4EF4D2B094A08CF802AE65755A22BA2BC
+:1064C000AFB4D92CA4F178CD9154A08FC182BA0673
+:1064D000235DE0FEB3D418171A5865A48BB4126379
+:1064E0001CA83FD2057CD7DF442FE67E06A87E8A13
+:1064F000C765042D3C5E34CB18D749635D1F3E81D0
+:10650000F01D72FBC3384E9D715C73FF0A0B5CA0DB
+:10651000801CD9F3F3896002C3AE1C9C9C8478D99B
+:10652000EC288E27B982C1AB187E971EF4AAEB1D0A
+:10653000BDB48FC8D1A0C1BF662E1B86A6DC36179E
+:106540005AADF204188D1FCC20F96E15F1CA8319CB
+:106550003F75A05FA33E398FF213F6631DFD38EA45
+:10656000B0FED172DF8A7EA4A4487D85885799C782
+:106570002B54385DBECFB442C4C3687B3015E9D913
+:10658000AEA6E4231CF654D0BB627C374E71717BFF
+:10659000CFA77C698CABB97DEF8BE029F16172E20A
+:1065A00079E1235F09FC10C70F4E067302E93F91A2
+:1065B000856A717DAB1AF93E17697713D231B40B36
+:1065C00062FCBFBB5D00DA8D34B4BB45F4A719DAB9
+:1065D00015F7685722FA638671B51EE32E16ED484B
+:1065E000AFEB6EE7EFD1DF12312EE983DDEDD41E84
+:1065F000FDDDA1C36768E7EBD16E990E9F615C6614
+:106600001CB7FBFD705BA896F4CB62F2C71EE8577F
+:1066100048F472A85F6111C6C16F7BC1CA65C436F8
+:106620009EE7210BBADA2FDAD5B9395DD556B371A9
+:10663000E5201F1B44BE4AAD7BAE2310F55C5F3FD7
+:1066400078EE8BFD7C8983EC31F15C6970925F138D
+:106650009E933D56F777596C5A3F9B8C71CD0674CB
+:1066600054613D78758D960DFC9EA618EAABD2F963
+:10667000FBAFEBAEAE09A2A34F29A6F808D0E7F70F
+:1066800073A3F8B07BFC7F19FCDC7F1C81FF4735CE
+:106690009A120D3FAFEBF0EB75E720FE5EB6CE9E93
+:1066A0008CF35921F6F5CF946535E44FFE5F3BBF7F
+:1066B00045A6F55964581FBDAECFCF6A2DFD3F36B4
+:1066C000BF3B4CF3BBC334BF3B0CF3B35B974E0EE5
+:1066D000669FFFFCCCED565B8B49DEAEE8F7782A6F
+:1066E000C2B542F8A79D56AD6639C61DFA75EBDBFB
+:1066F00024DF4733ED6F2837FAFA6EA3A2927C7637
+:106700007A2C3C68D3CF161A9AC1E19A0172A1453E
+:10671000F171F92DE03C62AA7799EAF0CB97B86F56
+:10672000FA986E4F9AE47C1FFB5A7D06DF4F1A3CA5
+:106730009A44792E625FB3E9FBDAA099B48FAD4831
+:10674000CD23FB65FFA005248F56A60FEBCFF3F0FA
+:1067500052495ED9C55EF34035CF5BBB5FE407AD00
+:1067600048CFA376F7EBF19250BA61DF3CF0830596
+:106770004519201F4F1FE1F98AABADDC7EA8AF663B
+:106780001ACFC37350B90FFA0D408356D0F7B07CBF
+:106790000EF43D2C5BAA53A97CB65AA572278C8BAC
+:1067A000E5AFAAFD5436558FA352D7171F14FAE24E
+:1067B000F7D22DB47F3E56CDC62BD0FFA66A0795E3
+:1067C0008F56FBC62B40970F57A752795A9A31CE56
+:1067D0004AFED38EDA7858AF3DAF6653BED2C4744A
+:1067E00085FC1E4C09CBF10591E73A5E4F4B932F88
+:1067F000B502DE2F512DBC9D2354EB8DDD6E32F69C
+:106800003F4E55081EE60ECADEE498EDAEC0766334
+:106810009339DCCC17A8F5C4EE6F1A8E9B972CE049
+:106820004B566BDDB1FB9B8EED2E4A15F0A5761D08
+:10683000888BDD6E268E3B3255C097DE3E392EF6B4
+:10684000B83FC2FEFA2736521CE932B477A03F7B2C
+:10685000BABA897C16A2DDE64155CC0274DB3FA9A9
+:10686000B10ADB5D5A55CC32A1CC4C296616A07F0B
+:106870007B32BC077852453F13E6F1F79BF1BD2709
+:10688000EABDF87E7C09BC877A667FE37B7D3C7B32
+:1068900023D3E54998813CB0AF61DD793D584FB1D4
+:1068A000F0FA9DD60393296E69E3ED1FC13AF463B4
+:1068B000AF337E9FE2E2F57BF4F65EFEFDD3A27D70
+:1068C000FF443E6FE78D8E10C6C51EFDF79FA6CD17
+:1068D000CD8DCC77C8CF975E38376A7E8FFE7C35FA
+:1068E000BDD7E733A47A0DBDEF8D5F53675B981674
+:1068F00025B7521A73499F1C6DAF22B9337AC8CCA1
+:10690000F01C58176B31876BDF8A553535D9045722
+:1069100090F205045C0FFFC408D7A09F1AE17AF833
+:10692000A746B806DD716EB8565BB95CEB0D3E1834
+:106930005F8B1E3FB4DC38BE5A631C3F54631C5F40
+:10694000ADFDD6E387A3D7E5917F338E3FF867C6C9
+:10695000F11FF99971FCC1777EBBF1FF59FAB8D7E5
+:106960001AF80FABD0C7E568BDB32A68D03BA15D6C
+:10697000BB681794A3F5D840D0A0C742BBD7443B0F
+:10698000CDD0AEB847BBB7443B661857EB31EE5F8E
+:1069900074F82CD1FDF97BF4F757ABB0172CD1FD6F
+:1069A000A93DFAFB5087CFD0CED7A3DD29D11F3325
+:1069B0008CCB8CE3C24F0EE6F3DCC15C7EF4F72E89
+:1069C0009DDA40F1AFFE2C20A1DFCF97C4461FC255
+:1069D0007D398BE7DD27142E1D82FB784382D1DFC2
+:1069E000D5CFC6F729C52653BFBE38564579878E01
+:1069F00060DAF4A87C8B32D1AEFBBD3B98765DD4D7
+:106A0000FB14F17D83885727AD1C538B72C537105B
+:106A1000DAC7A0B7541BB70BF5F72CD9DFAE01BC12
+:106A20001B7E3C63CC6A163DAE95B71B22C64D8FCC
+:106A30000D5743061FB714C7CDC5E7BA7E114C23C7
+:106A4000BCF978A93F5FEFF9A9F457C04BFD548713
+:106A5000458E87F76BB89F53F7B727D8AA1C98B70E
+:106A60005B3BC8C236AB94877C4E3F4E5DB5D1EFE1
+:106A7000A9F88A35B4F70694F8F264D6FB770F15B7
+:106A8000598A62C51D0AC4BCEA4A263766C3F8ECB7
+:106A900090D17F0B84CDA2F36186CB81025B2CFF6A
+:106AA0006D1DF79FEA7A50C28073FB6F6B857ED1B4
+:106AB0003D0FE828D6FACD12F0B10D1C6F8A8EB7C3
+:106AC000C41964DF25D45CE9F0C5F86E95A97F2769
+:106AD0009BA161BBB8E446662179C2CF4DE87A55E7
+:106AE0009D6F33DF87D280A6300E94BC338CFC734D
+:106AF000A6809FA35052434189EC513E4F542BF145
+:106B0000274E0907D1DF386083C2C220B7D65A02A8
+:106B1000B36C185FC96E24FF98E2D324C4D3596BB9
+:106B2000E84A3A5700EAE266A927BCB7D8B83FF866
+:106B30002175C61F3262AC63894D35C4B7077C61CD
+:106B400063E1FCDEDB47DA71B8BAE93415E8732497
+:106B5000C90DA2D34A592BB7119FA7FBC8EFA8CBE9
+:106B6000579DFF459C7BEE38267ED41BFE04F358D0
+:106B7000D46665C83FEC2B681D15FF5924FC5F7374
+:106B8000855F751E2BF6E2CB93CC52847C7592BD4B
+:106B9000EACD8F5AAF069B8DC3D56025FF961ED7D1
+:106BA0009DDF6835F8BB166E30D617B019292897C7
+:106BB00016ACB3B210E07391C91FB614E70BF02FF7
+:106BC00064552B7DDCAE207D7AAE8F2949B0752CC3
+:106BD000FEF5C363E740FD17887718FF23A017353C
+:106BE0008AAF4ADD211BE647BDB73B7FE60486DF5F
+:106BF00087560E40799AC0629E2FBAA5C1085F5F82
+:106C0000F09BE165ACE69C7028DBA498FEAB877531
+:106C1000FE10EBB5D4E11DC540CE9C75F2B2DB9FF2
+:106C2000F26727C9F7BD4847B4DE5517F1FDA0EA62
+:106C3000622CFBFAEE80A03FF3778B1D1D36E48FAC
+:106C40004AA5AA48B244E24D766B401B08DF595B67
+:106C50002685073243BB86F36CD726659E57BB2239
+:106C6000CB39FA3B25E4E5F33B1EB3A15D76F2C9CF
+:106C700063D7201F96FD56660E68776A878785C999
+:106C80002E09D9509E94EE9663C667290300F056EC
+:106C9000F62B0FC989D29DF6D034F8BEF4D9F74649
+:106CA00031C0C3A99AAEC303711F7D52E271D26095
+:106CB000C728DCB74A157673718CFE3A04DD9DF85F
+:106CC0004D1CE5B548DBF6DF44FD36DF60B547C94E
+:106CD0008737705FE2EDB87F6DBB141A1A437EE808
+:106CE00071AD13DB250E5F8B35E444F8B66DB2054C
+:106CF000008ECA6D9F101D4DF9559317F150D92282
+:106D00001BFCBE95DBE4B07D1495C7B0C478890444
+:106D10007C5DC1B87CACD8BD98FCE115CD777D22F7
+:106D20007BF17B233D035EFC61C4EB1BB27F1AD673
+:106D3000773DE15501551FB56FF5225EA1DF39B6EC
+:106D4000788CEB1AFDD8D8FF17893DFB03CBDD8685
+:106D5000F455D9BC8A8F67E2978FF097B49EF113F0
+:106D6000BBDD934C7AA21E3FD996745E7A6259D3EA
+:106D700099478230DE899D1F3F1204B8CBFFFFA7E1
+:106D80008FDC897ACD3EA70FF9BDF2C9D7BC2C6A3A
+:106D90001FCCB073BE3BB5FD89C71F023E39F5A6B7
+:106DA0009DF2F24EEDFD6030E6D39E7AE6BF52547E
+:106DB000687FFBDECBC99EBF7DCF94FEE7DA0F91E3
+:106DC0004E43F668B842D4BFDA22A1B20586BC2889
+:106DD0004DEB7270B7CC9C00E7C9A3F610E63557AF
+:106DE000C2B3A579B84E8B49FE627D19E0B7624700
+:106DF000FD27F2A858780E0EB4A46209EC928AEB33
+:106E00007CDDB597166069F5AB4817AC8BE4A7F944
+:106E1000BBCA23B09E17F5BE7E67D85736CC3FA9B4
+:106E2000DCB18A8F6B5ABF93F8CBF89EEB7799DD74
+:106E300018FF3AC3CA1F7D085FEE4E8A19D7D5E303
+:106E40005F8BF7FCE09C7A932E07FAC26F89C4E14E
+:106E500072DBB56BEDC84F3B9F7AFCA164BEBED31D
+:106E60000021A79ACE0C66401FC7AD5D37A17CEC10
+:106E7000DA6BF7E17E5EBAF70DE2AF537B5EB1A944
+:106E8000241F995B023DE114EBFE6947BDA142E27C
+:106E900095CA2D9EB0DD1B59A78AD0F422D54BCFC1
+:106EA0008FD1F310A7FB8AD0FEEBA518EBB6D29ECC
+:106EB000C9E571A81FE165F1963FD9288E1DB59EE1
+:106EC000D2385CC76385F8BCB775D4E7EFC3F95F08
+:106ED0001CB59E5B38BFF6C697A736D915CC4BD0EC
+:106EE000D7F794C8BFAD0C496FB018FCAAEF6FDF9D
+:106EF000341EBADC440FFA7CFBE2E7BEE7F1CDF0CA
+:106F0000742B26578EE989AF135FC596EF1B857CDE
+:106F1000A860554503B27AEE4F0A188C033322F06D
+:106F20009EC05800D0D98927653A2FBBB2F920C935
+:106F300069B35CA8E8454F6EB2733BA7A265FF2812
+:106F4000945F270EFC86E8B062C7311BDA4787B72B
+:106F5000EDB275E446E81EE57F741EE689A7F78F5B
+:106F600022398DFDC7589FE744FF95ADC6FE2B77AC
+:106F70007C62E8BF2CD86C23BF681FE37CA4683711
+:106F8000E07C3F6AB732CCBBFFA8592E8AA5DF3C14
+:106F90006AB71AF3613C638FA25F514EB4A928EF20
+:106FA000EA966B6F04715F7CC5CACF3D2ADA51CC7B
+:106FB0000BA84DB0A968AFD6796632354A6E379ABC
+:106FC000F0E94BF64DC2B89A6F6A7141B4FDA4C3A3
+:106FD0009FA0590CF0DFEE29EA8FE79FD00E53F106
+:106FE0009CB1E227BFB2EC2D2CC2F9C83E8BCF1961
+:106FF000737FE6FD59DDC56437597D96EE5C13EC71
+:1070000077F4949923D075A630D5A0E7AF9DCAE355
+:10701000B8FAFCD70E621B19C8DDB552571BE6B390
+:1070200007AFE4F9814CD8E95EB4D3337AEA734C04
+:10703000D354943F247E787BA6459D0FB903C0B1FD
+:10704000601E8FC54FCAFC1DB246793D361C370BFA
+:10705000EDA7103D8F6361AA5B1C5CFE7858153D5F
+:107060008F671D8DD9D0F9DBF6E2B32837EF2D4AB3
+:107070009438DC61CADB4810E358E2D2D3CEC5FFB6
+:107080006CAA7222DAEF63671BC92E41B7E3D749B6
+:10709000113CE879717ABF6B9D1325DC6F707E031C
+:1070A000F15C8F3837EFEB9EAF46F57E7ADD340E1C
+:1070B000B6F48D155B2CB162405264BC2DA091FCDE
+:1070C0001C03583395E9AC9DCA44874F5208BEB79C
+:1070D000C92F6561EFB2AFE34CF09D873E7ED6A22B
+:1070E000BD1980B2D62A9EBFE3096D85FABA04663F
+:1070F000381F9CE9E0F264ACC3A2E72707A2EDAE1B
+:107100005A564E737726F3632CFA773F7004863B0A
+:10711000A2E219B2BB9DE77F09FB57B7D72F97971C
+:10712000F1F87B2AB7AB7B5B9F15D5C506BBDA5C54
+:1071300036F673CCD9C4087EEEA7921CFCFCB2C60E
+:10714000545F34FD61AECDD8E8BC464D23FB5EBC38
+:10715000B7C2F4F0A51DF128F7A4BF62A4BF7E4812
+:107160007F1DA2932EF25354CA81229C6F6A76959A
+:10717000C49F0724EECFD2649C6F8AE8DF12579E2B
+:1071800076AEBC2A360BE8232AAF659DB01F158565
+:1071900029AE3C8467A35877335D1AF354757DCDCF
+:1071A0002D6A76912FF7BB8257E93C8A92ECA6FCB8
+:1071B000147741DDAD789E5C61553E949F6E3DFF36
+:1071C000C4CFF30A75BBD89963CCE7B49BF257AD33
+:1071D000C2FEEE91CF2DF6DD7BF0410C7DD8BCEFE9
+:1071E00056394C7AB4F89E8D8B9D37A8EB61E74BEE
+:1071F000F7663BB2DCD17E9806F769946FA9087FE9
+:10720000C3A4EB7DE407EFDC21F1736B263AEADCE3
+:10721000193F0AE521F22FDE6F11279E4B3BF6EF57
+:1072200047BDA9CECBB484449273AA0C785F298D54
+:107230007648502EDEFDC9CBBF45FF7AABCC706BD4
+:10724000EE84B9B5E3FC142D01172B8EAD31ACEFF4
+:10725000379D4FCFB822E7B7253E9DDFDCF4FDE92F
+:107260001D129D9F92D98807F01C44659B9585E06F
+:10727000FD69C6FB3FBD91EB030B5F805160FD379D
+:1072800088F1715F8ADE3F928A5C4C8DCEE3096A99
+:10729000ED78FE7F9EC047BFE244C3FB8FE716B583
+:1072A000917F26B080F44F3C5716DD5F99BCEC020D
+:1072B0001C8F093F860AFF90FEF4F99FB5046C7C91
+:1072C0009F288E0F933E03F62FDA0D2189F295CC7D
+:1072D000FE8E8A1689F6A745B03FE1BD028B422695
+:1072E000FBD19447A7E3DB4C97071D421F7433770C
+:1072F0002F78F587797C94F86AC90B3C2F6C4993F9
+:1073000014A27CE68E0BE219E15926BFD107AC6AC4
+:107310003DEC1C11FA35E1CD9E6AC4B35335E23918
+:107320002EC788578FDF8847339EE3C7651ADA97E1
+:10733000C9E536223281E71CF88778063948F3A878
+:10734000807984D59EF82C695DBB12FD1B7DE2D14E
+:1073500084BF8F4DF83BC35AF7F3B720525388B51B
+:10736000797EA41226FE31F39B8EA7745FFB247AEC
+:10737000E6F790BF38557422CDE3DF0D703473E625
+:10738000C9F313BFE979C271DDFBE57BEC6B286FB4
+:107390009B7EE818C6D3CDFCB5114BE0EBE66A87BF
+:1073A0006F1E8CF77435F3CDB362BCDA47658C7D04
+:1073B00094FA077AA4FDE01E8C4B26235F2BA1CD07
+:1073C000DCE68A9B86E7FC5AAD3EF45BDE93D7751C
+:1073D0000DEAED95F3799EE38F5D7C5FBDD5C5FD2C
+:1073E000B08A8BE737AF2EB6300DEDFB563924A1AE
+:1073F000BFC8A7BD7019EA5DAD5695F6355FD7CB0E
+:107400003FA2F7F93E8CEFA6591A47231CD09EFCE9
+:10741000ED9DADEF796F89D2774EB5DC7721EE3BEC
+:107420000F5A58492C3D3EDBC9C73F95F36E0A926F
+:10743000E3624717D9D1F51D55C5382FDD8EB0ED64
+:10744000E6FEAD8A96E9A44F1E5AC0CF63EE39C15D
+:10745000CF6316CAB3BF3F12EAE35F53B8DC64DA06
+:10746000B43929D484D6711DE64B221FFCD512AA4B
+:1074700021FC34FE11E354B5FFA950BE6C4115BF89
+:107480001FE4B7DEC2362CC76ACDF9C8D7535B13E9
+:1074900026E17999CAB7795EE59876A33F87C9E571
+:1074A00007D10F76E628DF962F3EAA98ED2E19F722
+:1074B000E3F11DC6E713FAA0DBC94EB11F7959CA23
+:1074C00037C98BBDDBA25DE9E4712C3ACFE5576289
+:1074D000DB4F0FBBB87E057891504E7576317F0D2E
+:1074E000E0A973DE009A6FE767FCDC65E75772512D
+:1074F0002CFBE82627A797076D3C6EFBE002776818
+:1075000039FA4D17940E41BBE8F37F0B0C8915A790
+:1075100088D8072CDE427B9E16CFC6215FD4F1733C
+:1075200066AC312DD6F9799D1F74FED0F9226D819C
+:107530002B10CB7FF9AE93DB6F9317E44836A4D7BB
+:107540007D12C5784ED5005CE7C06390D50C4478B9
+:107550002A5B3E25FF82A335B61FFAE7785803E978
+:10756000B626B87C02E0EBA7C0D441E4075B6346D3
+:10757000ACFE836C1DF99BE663923B7EE7E07634BC
+:10758000531AD36678904FA65CB912E07C08F80FC6
+:1075900049FE41AB9FE00E2E668CFCAB0AE7FFF480
+:1075A0006BD8A6D551F6568373D23A5CEF754E1E52
+:1075B000EF480AF82584DBFFF7B35EECBFF30B3B23
+:1075C000ADDF00E1E7D1BFFB958E1F97760FD14B62
+:1075D000493209437FC0EB9B07FBFF452D80EF2815
+:1075E0007A8CAC5B90BE4B0C80EC2BC0F38C163AC3
+:1075F000BF82F616DA13954CFF0992F2A9F31F1E0B
+:1076000036C3735ABABC955AA5B007E46681C31D48
+:10761000467F4A6209CC1BE351CCC1FB6B37EAA31E
+:10762000287951EEA20CA07D5AD83BBA1CD6E5773A
+:107630005D029783756B15CAA7DCA87438D17F9C4F
+:10764000A1A99331B52A515129CF615009469C41D6
+:107650003E663D9CD0ADF74C60EC99BFCB31FD1B35
+:107660001F74E32BF02CE26B545BD701549FFC4E4C
+:107670009684EB5D28F49BF127B93CD2F3FB2B8574
+:10768000BD619647BF013A478131FE52BEEF8D3F43
+:10769000E9F623FD74CBA10585B48FE6B5E61FC4DA
+:1076A000FC9CBCB7393F32217FC07A23BC8C6D0B68
+:1076B000CA880FB3DCE94BDEE8F2C4BCCEA05C772D
+:1076C000D731752EBF0DF82C6AFF36CBA9374C7217
+:1076D000EA0C9BD8FF7235424F794BFD07ED51F410
+:1076E000A3CBA9083D85886ECDE348CCD15DF76575
+:1076F000A17C7951463F48E7241E9F0C221FA1BF61
+:10770000E2B3D09538FF75AD573891EE77B64D712D
+:10771000205B2D49E5E7BD94FDD70799209FE8B888
+:10772000AE953954770EE2C542F8907D508F9AD7C6
+:10773000E946499C7754E3AF8F713F825E2E49E55D
+:10774000E7B976B665C6733B334CEBDE4DF7C20F37
+:10775000A1F3854EEF66FAD6F9A19671BF84AE3FCC
+:10776000C852B3B00B8D7E815ADDCF1174529CF894
+:1077700076A10FD6BA87DD85D7DBD48527FB302EDF
+:1077800071BB2793F2996FEFC7F166C6835E567E91
+:1077900001FA6154DE79A5D2457EADCA2F6C86E729
+:1077A0003A5E7BC3878ED74B10AFD23F8ED7B36282
+:1077B0007DCDF8FD47E79DBE645CCC7373FF57E653
+:1077C0003D81057EDB4176173FB7A1D3972E2FC6AB
+:1077D000DEB6218D88A3DD78AE479723E35AAA0E43
+:1077E000A28A68961317B5B2EB104FE3C30A1DB116
+:1077F000ED4B6E7C86BFA4D1F98B592E8073F4F3C8
+:10780000B3CA76C0A3512A4B9A06408D6A57488E58
+:10781000B1F6F38B4335873F4B41FFA2AE979ADB1E
+:10782000E97AA9BEBFE871A0D5AEC0421C5F6A016B
+:10783000BE81F9D7FAB8BDDBE00C94E2F33880D909
+:1078400085B97639E10C6E9F1AF9B2373E8C33F167
+:107850005933E085CE21C03E3754EA09873E7E96F3
+:107860002B81C309D486FA4BFA58C607ABE0F7D987
+:10787000A58F6201DC87F1F826CEB3C1C5F7935519
+:10788000420FD3CB0667F17284DFAAB0A03DEF1F91
+:10789000875BF70BAE7669D52E18C751A4D13C068D
+:1078A000FA981FF5FA814AB3E4073812CB55A9DBE1
+:1078B00059A3EFDF78EE679A3A89CE9765333A1786
+:1078C0003B10F5A018EBF34B17F7572F76741CC637
+:1078D0009079E5B4AA22EF39E2D391FB06FCC24FBE
+:1078E00065CCC3E8DCFBC6208C4BBEF3EF9F7A303F
+:1078F000EEF417A5CB83701E5FF6470F9E377867AF
+:1079000019B7336E32E9333B053E7D71C5DB117F1C
+:107910003757FF7DACE1FCF8521E47591492D1E86D
+:10792000ECA6EFB26D71E49BD3EB8B9B930C759D32
+:107930004E17DB799E9479FEC785FDB468C726DBB8
+:107940004015C70FFC16C73F2EF4B5E3BB3DE4CF8F
+:10795000D0E199BB63B40DF1F09756BB88C3B75B18
+:1079600039FEB569183F0B88A530C379785F1CF5DF
+:1079700037FF7E99F48B3930D652A0EF40EB22B21C
+:10798000B3CDF398FF8E5AD81FD66FFE2A89F452D2
+:107990006CBF0CE821B0B49EE26CE679CE099AE3A4
+:1079A00099CBC84E37E779CC63EA5D133362E47B49
+:1079B000B4F238F9C23EEC9A775C425F18CB2EC61F
+:1079C0007CF4332CF717B96ADF76CDF16A46495A51
+:1079D0001F553BA83C51EDA372BB4BE5F1EC96FD66
+:1079E0008789BE94F6B1C8EF3BDBDE8BBB518DC8F7
+:1079F000EDEF6DFAF4E02FA19ECFB8FF46F78FCFE1
+:107A000016F8BE4CC8EF85421FC8FFE2DCF27B3699
+:107A1000CE77544F7875B93D1BEF938DC2832EC737
+:107A2000CDF838DD9615477EC638731CF8DBE1A526
+:107A3000B7EF16CBB1F30675FED92EE879DE96E9DD
+:107A40002B07C0F8B57B3F18CCEF036647503EE8E4
+:107A5000F469A63FC6AA6CC8CFDD74D67A37E14771
+:107A6000A70BE0A354117F4C45BBCF4C6F7DE513B2
+:107A70009DB2760C463960A6AF53128B79AF68621F
+:107A80001CF797CF53B542B443617B59C9E3745C8B
+:107A9000FE1C571A0FDF89FCB985F3C7E25F373D3B
+:107AA0008B72A7F457F77B51EE7CA834A6E078E5FB
+:107AB0005B577831CE7D5C097AF1FB0F4372CCBC09
+:107AC000C2057192906BC67C05D610BC06F9F6F320
+:107AD000AD561FFA192AB7D9791C7C37C71BD47940
+:107AE000FC7B77EC7C85D227EE4F51797EAA316FF3
+:107AF000618B95F24FD05F86C3F416C7ED8E0B37BE
+:107B00009F3BBE5DB9FBAE9879277A7E80996E6700
+:107B10009AE815F042764C10E021B7B8885BD76E32
+:107B20007F60D43180EBC496FFF04AB9D17E731EDA
+:107B30001F3FDD7CCBA318E2E98D5E4F09FA8EE88A
+:107B40000DA198790CE5D6B017EDF0F24D56B2EBD9
+:107B5000CA9B64E6C07C9637EDB46F9735FDEEF5B1
+:107B60004B00BEB267ACC9D3F834285F415FA7EEC3
+:107B70003C12B12EA5BB7EC7E3BDAAC82711EB53AB
+:107B8000F6CC7E1BE6C598F138A579BFADC3948FBE
+:107B900040EBD47CAC90CEE56D3F6BC3FDF4C37D70
+:107BA00012EB9FD1F3FB924DBFF3A27C403C515CA2
+:107BB0005EAC57EFF942E16B9E2BA076E487EB6D4C
+:107BC000FD2EC6351A43F4FDF473307EC95B76CAC8
+:107BD000572A79FA36CAEFF940A9E274FEF08A14FE
+:107BE000DC5F4BACC1141F95FC79C9233F21FA5BC4
+:107BF000F8CA4F52F8791E2D8DFB6D8269E4CFD8FB
+:107C0000F8039ADF021620FA2B79582E467FC919FD
+:107C100085153D13834FFE2CF8E483CD760CA2B27C
+:107C20000F84DF32F8AA2CEEFD35C793F8BD2B6721
+:107C3000841DBD2BCEA2E7693BA2EDAACA2DF5EDAE
+:107C4000B83E1F0DD2FAFB28AEAF0405BE24D2C742
+:107C50005FB9BCBF9063745F8CAEE74CC1E7D8BE20
+:107C6000DD4AF7C6447D67B8F7E576313EC0ED9250
+:107C70002E823225B63FD3ED9674F878FE8B4E5F98
+:107C8000BDF1FD169E4FF2D9112E57302F86DEB76B
+:107C90005BC3FD0DF93076C3BD22917C0FABE06B69
+:107CA000E37B8093F255BAF1BB4FA238EB82757635
+:107CB000631E5C37DD98EFBB31E6AF2C34E95B7AAD
+:107CC00069960B6FC699E2681BCF2F7FA5DC1AA2BD
+:107CD000BCA3F237ED643F9437598B111F1FEF3867
+:107CE000F8FA8D40E71F37EB7C6B94AF66BE2DD959
+:107CF0003986C5E2DB8FDD7E16936FE1794CBE7568
+:107D000047E2112AFBEEE4EBC25EE4ABC5DD431FA4
+:107D100088C7BCDC8F9E2C1B427E06135E75B96A39
+:107D200096971BE3D45EF2EAF87E1EC977E4F8D397
+:107D3000E9B1F4A9C5344E37DDEA74A9D36D2F79C2
+:107D40005A663C9ADFB7097964F6670427B31CBC0E
+:107D50005FAFD6C672D0FF1CB4B8FC5B3362E4756B
+:107D6000B0AA0B50CFA87167C4CCCFF5BB7D68C655
+:107D7000326BB22AC78A77FBA75862EAF1F96E71B3
+:107D80003F09D202EA936E8EB73A115F014B90F22F
+:107D9000FEE98C36C297E0257EB2C27346E72AFD23
+:107DA000746EDB1F67F9540515ECDA35430A15F4D8
+:107DB000A7E65B6ECB82FA823579850AACB37F8207
+:107DC000655726D44BD6E4F3FA45967C2B90E6E330
+:107DD000C182C2A9D0BE429FE7BC78837F43B11C59
+:107DE0005B8F7117E5392BAB85FA5DC0D78EBC4828
+:107DF000BC37CECE824EA8C7D9A084FACA8C3FAE7B
+:107E00004423F03E7BE06A37C9A3C92AE2F584CF58
+:107E100041F932B7FFE672CACF2C7373BFF1885DA8
+:107E200013E8FEDDEF60FC1FBBC7F43E7E9D95F7B7
+:107E30007362E7882988D71143F8555F3AFEF31437
+:107E4000959E3B9BF1E829F17F2A9EFFA84DB051FA
+:107E50003F65DDEB757E65ADC86B90E3381DC8F1FD
+:107E600096AA67A05C22D6FF36810FFC417BB973CE
+:107E70006FFFCDFCDEA7AEC1B8BEB27CFACFA8378B
+:107E800076FD38CE8FE757DE72717CDD10BFC63AC3
+:107E90001CEA798EC1B72151BF25EDF80996D77834
+:107EA00002FFCEF1CFC2D8DF8D37C9BC3F7795072F
+:107EB000EF519334AE474B4034B3010FB51A536DB5
+:107EC00059C8A2C67C0B59CEEB0AD3B81EC3B82C36
+:107ED0001DF64158A71BC6F375029CD2BEF8C638E2
+:107EE0005E9F15CAACED50098EBB118ED1F6D02025
+:107EF000B47F6E04B588D3B5D1FED6E3F495FF699F
+:107F0000213BB352526BDD50DFF53623B97CCAE515
+:107F100015F907FC7E19DD2F31FEA5B95370C90A8A
+:107F20005ACA781E87F043E971F433AC55C6C9F4D8
+:107F3000F0539BE4E104B686E4645FF1B1C7DD620F
+:107F40009F19C0067CC3F85893FB3CE263E96E5D61
+:107F50009F17F176B1FF9F7E3193F285140573F27E
+:107F600018B3A932A588E8DFED36C95F9D8E471E9C
+:107F7000F1DD8278197984DDCCEDA55EF2238E33B4
+:107F8000CA6B1EDD9143F91156737EC4510B253C1B
+:107F90008D7D215F457CD689B8F1378DDBEB71FF94
+:107FA0007CFEA8471CFF396F11C541F37DB1E3F892
+:107FB00097C8B329EEC05EE4EBA7C7F1999C2B23C9
+:107FC0009C67C28C25219C478CF7C55C9C1C94291E
+:107FD000ADE66DE3F34BCCE7594CEBFD57F37A9FDD
+:107FE0006F1EC487FC7EB5D16C14E54158451EC494
+:107FF000B32C705F741E848EC7BEF24CCC7925E61C
+:108000003C92B480114F034B861BDE0FAACA33D4B7
+:10801000872CBDC4D03E0336C2E87A56C35586F6D7
+:10802000431B6718EA176CB8D1D0FEC2D05CC3FB03
+:1080300011DB4ACFB9EE239B9718DECB96503EDE7C
+:108040000BA9AFFB452D3F8B4917FABAEB795A982C
+:108050006E84F81D03EBFE5006F98FA6486ACFF533
+:10806000F78783B42F7FD3F5CFF6087DE81BF2BBEB
+:108070001F898DF25AB99ED8697537A05E9C00B0F1
+:10808000A1BC35EB1709ADCFFF17FEDD899EF916B0
+:10809000EA72A4A33B646D3CEEF7FD447E649D450B
+:1080A0009C279DEC207DE01E8BE5E6E87B922FF57A
+:1080B000707BE0520FDF5F7E09FB26EE9303E358EF
+:1080C00090F64F0B8BDC6701F3F52631716FF1A64B
+:1080D0009553D3319ED991A326007F637D5044EE02
+:1080E000DF68576B311E305AE6721CE4FB959E7EAA
+:1080F000B8EF2CB372FD2768453C0F74B0A0378FE2
+:10810000F63D8A6B26B06469492E9A5EDDFB8BFAD8
+:108110003510C3C1D211F16807BD8C906090D6E1D3
+:10812000A2FDFF87BADC2BB990E4DE69B79E37A6C3
+:10813000D279C7D3F3B2E8F99B3701D701FFBC6905
+:1081400033DA457DF9A74A36DDE741FFFF9B39CC9D
+:1081500090675026F056861762E2B993D07FA6202A
+:108160005A3AE7FF6D18025D29B5AF44115DBFE1D2
+:10817000D662CADBDD3D3D88FE3FDDEFACF753D96B
+:108180003A8975DF230CFDDDF006F77FDDF037A3BC
+:108190003FF7671E7EEEE86762BC9950F8006F33C8
+:1081A000613D12B07C7E6221F2033C0F4B50BFB6A2
+:1081B0000D543FA0FBE9810C2BC2F347E67F6D0F06
+:1081C000C0B3C2A3D238D7B3622BC2F5FA4D8B3DF0
+:1081D000D8AEBB3FBD9F8178A613F6E984A03505D4
+:1081E000E8A7EB5289F67518CF81CF8B670F5C81BA
+:1081F0005B873EDEEB2C70F23558EF19CC4FFDEA71
+:10820000FD33E632C8C19D25657F49CA44F967211F
+:10821000FFC792BD76927F9DA5679BD6C3FB9B0748
+:10822000760C42FDE2ADD2BF0D43BCFC7083CC5452
+:1082300058FF475D81B59E28BCBD39EF530FBE077F
+:108240003D61EB7ADCE49FB2D339AFB74A9F1A168F
+:10825000AD57FFD233693DD21D1B777EF19E294F6A
+:108260005E48F6B64E5F8B047D2DD97E01E9834BC7
+:108270003CDDF4C5EB5BB3E83CD15889C5B423F1D0
+:10828000DE0FCC4BDF097485E708F77DC1F3C777B4
+:10829000BD98984FE751596047F4BC76BD7CE30820
+:1082A000F2B71E4D3E2F78912783A85F310EE74B22
+:1082B000823F66B526E50BFDAE05FBBFF1B7DB4F90
+:1082C000FE09F1B3F7A9AD77629B82F3C30713FBF5
+:1082D000985FE001F631B27F3A99CB6F8F61FF3C36
+:1082E00023F4AF3B2C1AD925672DC5227F9DDB21B6
+:1082F000B2C59F8A79DCCDAD721CE2CD8B068B2E88
+:108300005F4027F4E23D8CE2FE7C07D8672384FCC3
+:10831000F9C3DD9F16D671FF8E41AF2B38546AD05A
+:10832000E78AE11FCAFB8B37066AF14EEE5EF5BAAB
+:10833000B085ECE17F54BF7BF71F94F7273D9CFF8E
+:108340009B73B8FC6E0EBB42DC6E60F9A8EF35790A
+:10835000F97E7025E68900FE6DD2A91C07FCFEC9D6
+:10836000DD6756364C84E5CEE6F8C03AFDFD95361D
+:108370004EA7DDFADFA1E1FCEFCB8973C005E25C1B
+:10838000B4199E02E02BBEC9BA0CFA63F8F09774D8
+:10839000CEA52951FDC304D4E7414F41BE772A1D24
+:1083A000B68418F37B16E527D0F7382FDF3F1C2D56
+:1083B0003C0EE75035BAF7CCE9F38D467B496FFFA9
+:1083C000B187EBAD8B0FBF35D806EB74D2F2A21795
+:1083D000E308E57B767AD14C1E1517F07A51AEBED4
+:1083E000F9EA581FE55B6D1A8C766D7398C72746BE
+:1083F0002A2CA8C4B8B7B972433E5DFE5DB121898D
+:10840000CA0BD19F008F2AC37C9EA75A6A63DEDB0A
+:1084100059F9FFF60EC0757BAA1F3F2F35B2357F85
+:1084200021CA3F84C50A72EEC92F46507F43BDDC86
+:108430009E87F1157CCE58C882F71D3D25ECB553BB
+:108440005FC8D44EEF7764CB24D9076B991B6E3C81
+:1084500040F661AB5DC575766EE1F7C1395B9D2471
+:10846000F72AF75DC1EDB8041EF76C7275FD599CD3
+:108470006353314FD2E96B6489D07F938DEF8F17AF
+:108480000203EC74479EEBE3395B1FA0A4764736EA
+:10849000BF57CFA934B24BDDD178F710FC8582BE2F
+:1084A0009A5C610BE6ED74E15D950457044E46E37A
+:1084B000EA705E48FA7C93ADEB7D3C7F49E7EB5474
+:1084C0008483C3C95A2F5051AF70FA78FCD6E95350
+:1084D000FD41A9275C95A340CF057EBBA78645FE3D
+:1084E0003E06E6B1B9227507F044532613F761E55D
+:1084F000D4A37ED15D4781342EF2FD8FBC23EAEBFD
+:1085000026929D1394D1AE87D29388F3E4FC85F72D
+:1085100017F4CBE378403F719C83BFEF6E0FF4EE0E
+:108520004EA47B8DA99D3FDE177795C4BAEF35D554
+:10853000FD4EB74BE1F72F43FF56F8C028156029D1
+:108540007FFE39A2DB324BEBFA912A9E4B0CCCF723
+:10855000C278BF7EDB827F53917DB4DD49E79073A3
+:108560007EB389FCD5E6FEEA8FD6DC8B79D99DBF38
+:108570009154CC03EDB47651DCA8A2F5033AAF7860
+:1085800045CB313AB765890F5462BFE35A964F41E4
+:10859000FC8D678DB5E8DF03794871FAE6542E3F0C
+:1085A0004E1F19B6797914BEEFF70ABBB02B300411
+:1085B000F9A655F0E73ED46FA0DC23F4AC3DFB7F79
+:1085C00098157D0E2BC80E903FAC861DA2FC42FD77
+:1085D000796748A17360235E77DCAC45D1DB2F045B
+:1085E000BFFFC2CBF5A0ECF8C00A84B76CFFBB3666
+:1085F000AF8A79ACCD8351EE36831E76AE7CC64A07
+:1086000013DF74E7B71CE7F772C3BAD6C5C33A3DA8
+:10861000F57ACB70FCBB22003FA3FBAADEB493DC4F
+:10862000DC93C1F96FF96B9F8F42B9F5F9DEB22186
+:1086300088AF3BBC3CEE0F743ED985FCF40C23396B
+:10864000A6F3632EF223809EEBE37E945CA473E496
+:108650003F5B3BDD03DAB587DF0B01744E740F74AB
+:10866000EE43FD22D707744FDF5F40FCDCD46EE1A0
+:10867000E7C0418E0FA5FA64CA57696A9FEA237E54
+:10868000B6006AF3902FC307A89F667EE76D81E965
+:108690003ED78F3149634C443EFE9787CBFFE61CA3
+:1086A000351E6D84385936F041D43EC9EB621F95B2
+:1086B000E26FAC5F878946ED625F107AD73EA1E733
+:1086C000B2A35CDEDF26F6B225BFBBE4DA1D30DFE5
+:1086D000252FC95CFE0B3A3920F4E043D5A954C7D5
+:1086E000FD4285751A0325DE773756AB9A82DBCFBC
+:1086F000B8A2C683585E52DC3C058F4C4D9CD57E9B
+:10870000909F61D34620FDED3E70E508CADF7DD322
+:10871000CE304571F7975D7F7E12F351F701FE630E
+:10872000EC4BE89F6514BF29267AEC8D6E3AA58E36
+:108730006B26F8613ADEF22B14D8E82B9030001F3C
+:10874000AF794BEB8300D00FE3B5A3488F77FA02E4
+:108750005476BEF2650ACAF43D47DEF5A2BCDF6D71
+:10876000D346209DEDCE047B20067DFE4ED04F41AA
+:108770002F79155F7A797EFAB020BB0BE9A762B733
+:108780004C7FBFE0E46E59C373D8EF6B8114D47390
+:108790008EB3E0CC09B8BF0BBB763E473B9B8F7ACC
+:1087A000CB28BA2FC3606732799985EE7B6F95C865
+:1087B0003F5162D243CA59E3CA81B86FB46EB2E185
+:1087C0003C4AB718BF2F47FD651496E7B657BFF46C
+:1087D0000AFD258B65A1FE02F443FE89AED764FF36
+:1087E0006646F93D6D98DFF39485E307E425F1A132
+:1087F000AEC73CE1D34EA05E7DC223F613618F76F7
+:10880000354994DF7FE1369E777DC9717513E3F3B7
+:10881000A7BCB01221072F5178FCE2922359140F04
+:108820001DA731F2872C68954288C7125DAF13E708
+:108830002960DB25BD6E3C0BD5E2FD720BB7497498
+:108840000EA36C9BD17F5FBEE195C3681E2E6E3672
+:108850009D8F177831C73776E22F31E21B83E3858E
+:108860003F67301B6C386FD5767EE7AD3E16E7AFBD
+:108870005F15FDEBED26C473BAA910F32D0FC921C6
+:10888000F1F729DD987F7B8BA08F5B047D54B2B01C
+:108890000DF3F717AFE3F3656BAC867B8B17ECBE7C
+:1088A00095CE2398E9A864078FBB010229BE53B275
+:1088B000D1F8BE54E0A3D4848F8A8064828BEBDB32
+:1088C0003DE16A9E89EBBB788795FE4E8719AE33F2
+:1088D0006C36E511FDB3E133AFD375FA3A0D67C3DA
+:1088E0000DEB5474EEFB0922F68D51FF7DE6F0701E
+:1088F000CA7739DD9649FE039D3ECCFD140AFDF989
+:108900008A0D5CCF3CD932256E24DA452F2A7E09A8
+:10891000FAC97FE9332F9EF7C8DB2B338C0B76B671
+:10892000E6DF85E7B477B5655F87F751E4BDA4D08E
+:10893000BE91FF521EDD0B92F7525E5C16E551A808
+:1089400049880FE887F6DDCE17B3FF988BF2B36D39
+:108950006A01A279F98B7971A81FEC62DC1F21BD35
+:108960005490D411B58F94C773FFC0CAD4F7EE41A9
+:10897000FDFD8A67F8DF1FBCC2DAF532E61FEC6A3C
+:1089800053FCCBA15EFED2DC1ABCA7A27CBBE447A1
+:1089900035FB70FB92E41F219DB55A7D7682F72747
+:1089A00007F07D708744F78557EEBD7C4413E67968
+:1089B0006FCAF7479FCBCE4B50EFC3BC4A961647C2
+:1089C000F6F71583ACB49F9E1810F718DDC7A26D9B
+:1089D0002A44397BE2B95D363A37D824B15498C875
+:1089E000E1D4834FD3FD1ECFBE42F90A5376BF4276
+:1089F000F909BDC9FB93219985C9EE6EA47B611667
+:108A00006FD2EB1D740EA258E84D155B8E51BD144C
+:108A1000F57F18AF74A31C52E1D7837B7F4DF90D0E
+:108A2000153B787E03BC27F9538AF1533542E7732F
+:108A300019A783B942FE94317ECF5059233F47A7EF
+:108A4000DF8BA4D3F9FC1D73280FAD47BE19DA974D
+:108A500014876824FAEE79DF10A7EF1EF72499E84F
+:108A6000FB573A7D5FC82E44FAFE7C12CF0FFBFC09
+:108A700015575C2ECCE7F31764CABB3F079DD37E26
+:108A8000FAA2D8FF4F872DB43FE9ED4EB57C4AFBE3
+:108A900048E58BA76DA8AF16B67E42EB30AD75FFEB
+:108AA00054C4F3D52C508E78BBBA35CE877C3EADFE
+:108AB00083CBADAB5AED21F4535FCD9AEB707D3B88
+:108AC000F73D519788F4F238A7175D9E2D14F85C96
+:108AD00028F0B950E1F73D95E6EE5F8F6ACA558CF4
+:108AE000CB9BAB9A85BCD968C46FA7B55921BA197D
+:108AF00029B1C68C9EFB5D19EBA0738F9D6923E89D
+:108B0000EF4906C15E453DAC7C87390ECEEDFA0AD1
+:108B1000D37E7A205EDC67F00DEFC178D7B42ED318
+:108B2000BAF87E7615D013C643DAC235B928F77481
+:108B3000FC98D7A54DCD8A3FD779E79785DEAED78C
+:108B4000AF15F74C34FB1ADDD176F8153EBE9F9475
+:108B50008E9783B8AEDDF64AF6C151AA2562AF8082
+:108B60009DF2657C3F6EB78C86AE9F4F97597272AF
+:108B7000C45EA94FBD6F5A5E32DE1FC1E5C5A97143
+:108B8000D01FE60B288CE454E50E7B08ED0C3C77F7
+:108B90008476C07F03EEF3D8290080000000000037
+:108BA0001F8B080000000000000B8D577F6C14D74E
+:108BB000119E77BBF7C33EFBBC87CD116AE2AECFF7
+:108BC000BF3018B3312636A449D62E6928B8CE193D
+:108BD0001A429BB45C4814D284B351845C242AB1F9
+:108BE000B6898A42AA466AFF88AA28DA448A94A8E3
+:108BF000343A84514C655BE7C424B6532408D0183A
+:108C0000D4B427FEA069656383149C5691E8376F3E
+:108C1000F7B833366ACE92E7DE7BF3E6CD7CF3CD50
+:108C2000BC778F0E5EF7A5EB886283E21182AC2CD5
+:108C30008AFBB4A5441D44DE9246C80161A40872B3
+:108C4000D3755FBC8068BCB2A2280EBD1BAABE4C07
+:108C5000C3F8167F1ECECAAEAF15A262A24E48BDA3
+:108C6000383BDFA9A67DACDF39284C1BB2FFC3FF20
+:108C700094951712CD0CCD953D0DD9A8798896F213
+:108C8000FC0F57AB3877F6929FA2E538D8322FD039
+:108C9000FD44CF91F3D9A3111D5882F1E80B6D5417
+:108CA0008F0971B8949A61D74B460AFB3A2F2A86EE
+:108CB000A563FE9497A889A8E7B33F8F2E2921BA10
+:108CC000F6BE30FCBAB3FF570D18EFB60F2F81FE7A
+:108CD000CDF7846141FDB97B881EC2FC9ED7BD578C
+:108CE000D201E7AC5BF27FF2CA41E8258E05F4576A
+:108CF00030EAA1DE52826E2F1D963241AF5E57429E
+:108D0000B037D0E7635CC8CED91F257AF1DDF9F61C
+:108D100012A466C788EFC0DF5A3A4673D61FD50A39
+:108D20004BAE06F1A5966A6F29EC7FFE5181F36781
+:108D3000C615CD2F246E6F7E27179F3180B19CE71B
+:108D4000F34C429C33E70AEC3CE8FDFB10D66A8802
+:108D5000A60EC1B81F769A158987678323570F7FA0
+:108D600010E57C32FEF135447F1CFE6095C9FE9310
+:108D70004DB49EFD86DECA1CBF93702AC74FF865AE
+:108D8000A4705ED75F1503E6D9AF6A5F49D6AF938B
+:108D90006A3A64E4F063EE90D9315A8574890F65BC
+:108DA000BE3C6254CADBBC39A5C4ECBAEC18F1EC89
+:108DB00032B1FF27CC0BF843EA6C24063F7FA6E9CB
+:108DC00092273D834E7E3D438EC4F93B8871C19806
+:108DD000CF5FB0DE6AEDE5F59BE541B218B7AFAD08
+:108DE000361E7747157A05E3EECF5EA8A19CF3897E
+:108DF000FD447EBBBCB311E66DD7398FF4AFEBDC1D
+:108E00008D4825C65BE8AD4D1AC65B297998D73FDA
+:108E10008E069F675E5B7CEEB2AC9D2F8B14C77F86
+:108E20008E17F62CFABD63D78DB797B6491C7A5DBD
+:108E30005EED2E72E23DA8C5BBB90E67CEFD37824E
+:108E4000B0E9E4852B21CE5726DF77D6DD6DBF71E3
+:108E500002E373B3453FFF2478D030AE5A4588F320
+:108E6000C4649EDDC6B80CEDF9C741CEDB653F7129
+:108E70003D740FEFA921B61B8FAF8DA10E6F0EFFB2
+:108E8000622DE340A257FA65B17FF06B7AE062444D
+:108E9000C77C62E86284D71327D7FFCE82FEBA333D
+:108EA0000D5B79FEC4982AF9D770A651F2EFC45F22
+:108EB0001A8B2BD87132826C3731AEC6189FC478AA
+:108EC000E3A76DD04B9C696D147CCC99C662EE3FD4
+:108ED000EB04C5925817E395729C89E7379A22E311
+:108EE0009919011F302F28EAF0872AE7F1676FFFF1
+:108EF000691FC7B1774031737994D9F796A64A3B79
+:108F0000EF307F806F4F5298921FC71DB977E08472
+:108F10008CEF456F52E6BBE798D759FF9323895EE4
+:108F200093FB2C5A62311E9FF214F2B0C567AF203A
+:108F3000B838514E3B938BF4C3AAB090FB262EC594
+:108F4000BFCB7C996889D768750BF52C6A95F19031
+:108F500070F1EEF76EB617B157E1DA0B15D3AED854
+:108F600022EB5AD8E1CF161FC517F3E78B4C3D1102
+:108F70001DF58017E7DBBC1AF39FC82C588E3EDB2B
+:108F8000EEF6D9ED3FF29ABEB55827ED741ED6DB4A
+:108F900033FDB619FD0C7D21863FEE6FB1D76345D9
+:108FA0002940DA61CEEF73DB28E6A50AD8D93C7FE9
+:108FB000FE71EE97F52C5569E76E7DF022F7C1D56D
+:108FC000F8524DD5DC074929080AF0E6AB31AFA6C7
+:108FD000487FED4AEE0777C697E9331FA3FFE9E81C
+:108FE0007F63E87F2C7B6A3FAF4F038F89914BEF04
+:108FF0008765FFCCA32813F01B5847DC09CD3DFB48
+:109000000E7B3DB7EBF3C7F3F896C9CF34D1E664D6
+:10901000DDC2FC5C77EFB34460CA07B25217ED3B88
+:10902000E2411CAB14877F7E6FDC2C451CDE8196F1
+:109030005429F7D35A7451C437FD88B0B9CFC3CF80
+:10904000327F4E9F9F5E2EE47AF70E615BF83A52B4
+:10905000FBB9BCB713A9B33EE65375FFD32FCBBA08
+:10906000B5E80245B2797C2CE0DC97B7F397899795
+:1090700017758E0F7C96FDB8444AD6E7FBB1DDBD6F
+:109080000F1F6B9E9FBF1A3AFB8352F8F184290C85
+:109090007BB1BCEFBCEFF452FAF6795F158E1787FF
+:1090A00081C7CCD91B3BD6C0DE44ED3FCBF81EEDCB
+:1090B000BC0B7FEF0D3BB8760543F55484EE52A30D
+:1090C000F7A581C7F1C2F80A69C7F34D6815F1FE2B
+:1090D000F49B2F09CE0749FDBBD54B855B2F15614E
+:1090E000CDA98B125AC7BC7A4F73C6135E7B05F7A6
+:1090F00003AAC36366C3FFEFBB3DA73EA9E7BC5C01
+:109100001B19AFF7E5E46FEA25D43DDF23431F4584
+:10911000F4825C7E795C7EA9520AB1CDBD1FE7F373
+:109120006D8AF9C6F93EFE51FB93CC93FEED2542C4
+:10913000CFB93F4F9E0F55E5D89D1E54A43EA9E9D7
+:10914000EAC70B73FD7C59FA399D74EC11A5ABB7D6
+:10915000AFC95DEF73799B96BCFDF5CA7D31AEE377
+:109160000C6F557278DB39D041F23E72E34EFAF063
+:10917000057E59C37EFB1DACCF7867CBC23975F134
+:10918000AC8B73534A483E6E204B61BB4DB0F81414
+:109190008F554AA9900F504ACE13AD20E6F1FD2E0F
+:1091A0008F9BD4D488A8977A960A5E6EA4B352EFA8
+:1091B000219A95D2243478C85632A46C0EA4B67283
+:1091C000FBA84B2615E6532AA286AF828FDC4A16EF
+:1091D000CB5F367E95AE66F809653C6E76C516E9BE
+:1091E000D7BF75EBDCE0B71AE7799AECB731F52019
+:1091F000A5153EE40195362B88E7419502F9F0F775
+:10920000F8A847D6EF705AB7B97F19C5EEBE7F618F
+:109210001FC64DA653A77CD53CD5908DF74E1C3666
+:10922000C25E11EBA974C42B714CC9F31E66C71141
+:10923000770BE92A8F7BC3E56E9F9FFD399FF3FD76
+:1092400041BF7CE7780296C4E3485897790B02CF78
+:1092500010EC6C7C4DD024CE352A9C7833F637E266
+:10926000D557D4C0FA42EA634C93980F069C7D44CC
+:109270009B34C64BA4229E5BC16F8FEB4C84A4DF52
+:10928000A16766AF1D94EF36BFF6365C32063F9994
+:1092900014784F0BD3A403EC4FA020C5EF6BB06341
+:1092A0002AF75DFD4678F71FC2F047E89AC48BE2C3
+:1092B000A4F33B6319BDA1F1BDE161BD6207BE2FFF
+:1092C00081DF136EBFBB9CEFF48D77ED6DBA07F9AC
+:1092D000D8591230381F0D81B27504BBED85716904
+:1092E000F7B23856258DA8F67AB69BE17990CC6610
+:1092F000C659B8F93A1070ECCDE539926B92F91C69
+:10930000443B0FC0AFA3A88B00C656AB936FEBEFE7
+:1093100079761FCE9BF3C424197FA91801C9F76879
+:109320007CB209526D35F57D05FC64471CC16C1C8F
+:109330007D7C0EEE637A160F449061BFE6C4D3576E
+:10934000E059C9BF97FA28DFC0E388F6173A3CDB3B
+:10935000FF459E4DE50BFD1BF1C74738BE398F31E8
+:109360003921EFD17D4DDCEF18A7EF6570F2647104
+:10937000DA6947FBD2BAC4658CFBEB7D7EFBDE1459
+:10938000F6FDD46F57B1FF193C90204952CDC53935
+:10939000838FC6F9631E9BC85F26FFD12C4E47F30F
+:1093A0001D7CF0F3CDC141471ED72C8C3FC3A3FFDA
+:1093B000010A95CE3EB00E00000000000000000043
+:1093C0001F8B080000000000000B7BC9C7C0F0A382
+:1093D0001E81BDD0F8E8B89917BF3CA9588601C1D5
+:1093E000CEE6626008E060600804E2DD40BC078809
+:1093F000A539191842803814882703F95380380793
+:109400008893816A1B981918B6B13130EC05E223B4
+:10941000407C9A8D74FB9F8A3330A4C920F85B800E
+:10942000EC4D72D4F5E3281EBC38C600953F4713B7
+:1094300095BF449B81E12E929AB99AA4992F68C84E
+:10944000C02004C4008B7A89656803000000000016
+:1094500000000000000000001F8B0800000000005A
+:10946000000BED7D0B7854D5B9E8DA7BF6EC994921
+:1094700066263B0FC2248664E70501031D6288400F
+:10948000D14E5244B4D48E685BF478740848781393
+:10949000F09556BCD9900709093058AC81224E107E
+:1094A00011156AA4F8AAB40E88163DB64D5B5BD1BF
+:1094B0005A1B11410139296A9D5AAD67FDFF5A3B7C
+:1094C000B3F7CE4CC0F6DC73BFFBDD1BBF8FE5DA14
+:1094D000EBFDAFFFBDFEB5462645442A20E40BF860
+:1094E000FB1A21B9222164423C254452FB9C901274
+:1094F000ED8B62539E7C613B9FFC67A3CC798D9082
+:1095000061907E9F906C426EE365F42F00F9A93C58
+:10951000A3CF474F895F26D1B2783F5309CBABA287
+:1095200040BE10E0ABB95C1FA7C1E91D47D208F9E6
+:10953000C4C552AD861655D2F42D57A4A9901097E4
+:10954000102A66EBACFF4A702CA61743DA24905918
+:109550003DEE04F320AB195C76E788A42A3E7F6BCE
+:109560003D3D6D6A24243A2A9EB749FE288C4FA6B9
+:1095700010FF8309DA4DA4EB40F8B88904F0903964
+:109580003CDE154213E1BB9D04A2365CAF9FC03C9C
+:109590000F78AA8E84B208E99C22FB1DF079530E45
+:1095A00081797975B8CE2AC0BC0C799590AFC33F4C
+:1095B000B8DE685B319D47AA5F246BE9A7A69C0AC9
+:1095C000271D93AC9FF4575F88A6A9520F512075B1
+:1095D00093404FF9E0790689C8F7F12E723E70B0DA
+:1095E000EE8F1DD680ED6947D9F1F96EB0D379D1F0
+:1095F000F568134402F0595739332D94601FF47401
+:109600000DC0972EBCA5D18969D3C49969A41C7AD1
+:10961000EA9F05705E3F295B5C2BC4E1A2C3E1C0F9
+:10962000A4179D7DB45E3BDF9F4EDF4127B46BE7FF
+:10963000FB6E85DB7A800F2DAF2102CEBB6558CA49
+:10964000AC4802B8D4102F96AF77D176B08E1C12EA
+:1096500079B010E6D3D73587E6BD13950A80B715E4
+:109660007FA60E93B0BEDB4D220EDCDF803B8796DB
+:10967000A71236BE3B8FF8A3743D2EB7DBAFD2BC2A
+:10968000345124511DE6F8EF72D33E7849BD835022
+:109690007A4D9D326F061947F36AFF1118DFF9A65C
+:1096A000C31F800AE532B657E87F5F14D1FDF8DBAF
+:1096B00087584EDE16FC0FC2FC767078296C7C67EA
+:1096C000896C1ACFFEF93541806F47F98A9455426B
+:1096D0007CFDB2719FE9BA6D96BC7DECCC6F15AB89
+:1096E000C9F7D3DEE725D18B6865DB0D43EE7BC37D
+:1096F0009BE32F3D54169FCF8F8827EB3800EB62FA
+:109700007231D2FF39DA7FD2E8BFF4901DD7291A1F
+:10971000F950B2FA6D1CCFF47C7B21C513C4B33E63
+:10972000DFD563E3DF5FE5F841B46AE46F12DFBFC2
+:10973000F64B48BF8DC2B769ACACAEA67090DC7278
+:109740005418C7C6ECAF02BAA67FF0BDBCB557F03F
+:1097500042E636137F6C29BE8A328EE4F393B2CC94
+:10976000FBF365E1F73CC0EFC238FCEC249816052A
+:10977000BC0DFA103E1E7D1E977C478DAA09E0782D
+:1097800031A53B3A9E3D2B42128DABF341BF10F801
+:1097900035F01F9BEC47BE4526CB09F9A05D109123
+:1097A0004FC5E1EC94101F09FFDB1F42B8C30C9DAD
+:1097B000D91C7E8097252FFE0DE027A9249AEAC5A3
+:1097C000EFCD5205A5039568A994FFCB129120FF18
+:1097D00029007B02964F9533804F4CF38780FEED36
+:1097E0007C3C65B6EF6A4F7C3E9FF27D8D97877C0F
+:1097F000DF3695DBD97C3D9C7F28734C7831D03E99
+:109800009DB5B7AEF723C2D6FB29A547863F737C2B
+:10981000410FF4434CEB6E516F08D6AA280F3E85DA
+:10982000FACD5F09F4CC017AE5F2C02A5793F263CE
+:109830008B3CB5FB0C79F84731E05311FC9BA7201A
+:109840007D11AB1CE76960C43F270F69CB4472767A
+:109850009C203039A565E1FA753A225C4FD0F79B20
+:10986000F27593FC90613E94EFB948043B4F25514B
+:10987000CC7B483DE63F9E581115683F0EA9AF0DC1
+:10988000F89783F251AD70F0F81BB83C49B68E0DD5
+:109890009724E6FFF9807C80DFEE7A1242BCBD415E
+:1098A00001BA12B410F902E88B84B9FCF5FB60BF71
+:1098B0005A1B1BC83BA584A41CBC8EA863611FEA6D
+:1098C000038172D04B6815CA824949254B25BF6A6E
+:1098D000C4C7817D24ABF87841A43B8A17970AD08E
+:1098E000BFD38C3703F85142896E12E6D560C2FEB1
+:1098F000F87EF27A49F16760FFF5F5A832E2AB0530
+:109900002F5C958A00A84DB3BD309FE17C36C343E0
+:10991000ADCBC571B02FDAF49174ADC3FB66CF0047
+:10992000D1E979F38AF7415E3597571CAEA1FB94D4
+:10993000E657AE9E4653570911009E6DD0592EF43E
+:10994000F7A2564DD7DB049DD1FCF5AB9E0D686E9A
+:10995000861E66BD5254251D5F8A86D44B842F1CFB
+:1099600083DB275BBFDD22D70859717E7AD00DAC2F
+:109970009D46FF03BA4AB7F4931630F3710F31E4F2
+:109980006979F380DEB4FC7F643C85AC76AA14056B
+:10999000EDAAA844E8D869444997286AB8A64A2499
+:1099A0004AF34A567F4054CFBD2FCD844C677C3C50
+:1099B0004C8C78BC99D3B9AFB6B9B095F6FB71A50C
+:1099C000DB0F743E9CB2C1CC8CC1EBE9B0C8E18E18
+:1099D000F2BB11EF9B88E62C02BDBE5C44FDA54D99
+:1099E000DDAB18E5D0B33A3F19841F4495AA9035F2
+:1099F000207ED85431E0F2FEEBF861D57BCE173FE4
+:109A0000526F30EFC797DDAFC3801F13CE1F3FFEED
+:109A1000D5F1F47D4DC6977CB5B7A25DB1266F68D0
+:109A20003D7EF0BEAE46FEE952492092A0DD2F05F4
+:109A3000C12C7F8C69B6515EDC62DA2FA960DA91A5
+:109A4000EE21E021A91639A8F3B1069B7A2C133A2E
+:109A50005050DE38797FEDEADD1AE8ED1FE7018628
+:109A60005079125E1E1540AF2961F61D742002BDAB
+:109A7000A88108DA212097E8BE38F8FCEC3EB31E36
+:109A80006F5352CC7ADC2C4D30CEDFD520E33C9C9A
+:109A9000301EEDD741ED0518D79647A22E6F1C5FFB
+:109AA000612866AFDF795E78A0E32B8095E1ABB9E2
+:109AB0005DABAF22A15E3768BC6BCDF34DCA97ACEE
+:109AC000EDDC927ADCA06F246F2791E306BDC50719
+:109AD000B2C5B0FFAD76F2B440F5BC26DF77349C5A
+:109AE00037FC9303FC89A03CB3E5D490900A7252F2
+:109AF00065EDD40C265F7709267B5BFF9E7C1E6C90
+:109B0000BCD8CD84F482DC9154D47F93D56F6AF4B1
+:109B10007D55A242C8DEF0C06489EE5FF3AAC0ACF6
+:109B200020ADBFB671D764F8AED7AB11454EBF5468
+:109B30006C56811EC3F196D07A4EFC4ABE00FB885B
+:109B40007266D580472ED233592AC3AF7CFF883046
+:109B50004007B4CB25225BAF833C8DF5A023A847FB
+:109B6000B938CBD386906FB10702414A776BA5888D
+:109B700073054D5B5C3CAFF27C3ACF2B3C5FC8F386
+:109B8000643BE6ED32CDD375A5D8230AE65378BE03
+:109B900090E733783E9DE78B785ED88EF91699F57D
+:109BA000D721F5B0FE53785EE5F90C9E5778BE8854
+:109BB000E7C95E36BE83E553ED3DACFF549E2FE40E
+:109BC000F94C9E4FE7F9629E17F6623E299F2C637F
+:109BD000F08FF305066F1D0F09C0D5E4E78A5AF22E
+:109BE0000C5F32058687B16FEA78E347FE48DCF9FF
+:109BF000486FC3B9BFA1E906E66F20DC3F62F87E7B
+:109C000058057E334BF40F455F8F707EBA8BEBB1F6
+:109C10003B1B15D4BB7734FA30DDDEA8E2F748638E
+:109C200019A6DB1AFDF87D6BE3444CB7340630ED22
+:109C30006A9C8EE9A6C620A61B1B6761FD0D8D21BF
+:109C4000CCAF6B9C8F6947633DA6ED549F85744DE7
+:109C5000A386694B631BA64D8D614C7F7843C54B32
+:109C6000A0D27EEC1651CE279BFF85BB44131F1E4E
+:109C70001D31F3C5515D19A67C6938D754BFB8AD05
+:109C8000C8545EA88D319517345498F223EA279B67
+:109C9000EA5F30BFC694CF095D69AA3F2C38D394E0
+:109CA000CF987ABD29AF4CA935E5BD950B4D797795
+:109CB000F90A53FF2925DF37E59D79AB4DF53B5C6C
+:109CC000A19F8A942FC8596B4DF524F7DD6679352D
+:109CD00023EBBCF816F948CB06BCD2F98795DFDB3D
+:109CE000F2492080728BC99726C05BF0678D209166
+:109CF0000705F0235D7E18FC178E1226771C83E47F
+:109D0000A6B93FD9BDF38846C7A9F61EF6F519E8EE
+:109D10008C18ED4ECAF7FF2C32BFE2DABB989DDCFF
+:109D20007957627B19393BADD7F979623FED9F4492
+:109D30009B452F60764AE75D02D6FF57FBD7CBAD38
+:109D4000FDC6C7A37B5C65B05341EE4F60FFA7190A
+:109D5000F4137B5FFA1CB07B743BD6C6E9BCBACC6B
+:109D6000FF763385778B42FC0E9A6F71D710D02B1C
+:109D70003E5618DD931DF9686FEBF507CFCFA0575E
+:109D800020FF4931D9FB927B26F29796ACA1F532A0
+:109D9000396623512AAF6C3101FD72B2149C5E48C2
+:109DA000E9577ED5E65F45505E26B4DF09B91BE171
+:109DB00060B3E837CD732D7C6FEA085CB75DE76F61
+:109DC0005935F8BD59197A5E0E9817CC87CFCB1E3E
+:109DD0004BC5D41673E17C27C532313F31968EE9ED
+:109DE000C5B10B30AD8AE5603A21568C6965AC107F
+:109DF000D38B621762BB8AD8684CC7C72EC2EFFEEE
+:109E0000D8784CBF12FB2A7E1F179B84E9D8D8D77D
+:109E1000F17B79AC1AD30B63DFC0EF636257603A12
+:109E20003A760D7E2F8B5D8DE9A8D8BF613A3276E8
+:109E30001DA6A5B1399896C466635A1C5B84ED8A49
+:109E4000620B302D8CDD82DFD5D8724C0B627762CD
+:109E50009A1FFB1EA623624D98E6C556617A41AC57
+:109E600003DBE5C6DA31CD89FD00BFFB621B31CDD6
+:109E70008E6DC6343DF600962BB16E4CD3628FE2E8
+:109E8000776FEC614C3DB19FE07777EC714C536399
+:109E9000CFE2F794D83398BA62CFE37767EC00A6A5
+:109EA000E7DA2739CFCCC76D5929A6FCC463663ED3
+:109EB0005EF5A6998F57BE6AE6E315AF98F9B8FF2D
+:109EC00090998F8FDB6FE6E3E5FBCC7C7CCC6E3327
+:109ED0001F2FDB61E6E323B75E6FAA5FB2C9CCC771
+:109EE0008B3A179ACAD566331FCF5FF97D53FDBCF5
+:109EF0005B579BCA7317AF3595FBE69AF97736D94E
+:109F000062B6BFA76E37CB91298F98FA7357EEB51B
+:109F10009C034490CFA494FFD4D4CE597230A15D59
+:109F200063F57F0348244ADF779014FF5A61F07E7F
+:109F300066707E90097447D32C4E77C380EE689A82
+:109F4000F18DC5787EF4C937DB7E416D4392710196
+:109F5000FD673274BBA12640BFB7E6E879A209903D
+:109F60001F4198DF80BC5F8DE5852CDFD574AC5A2E
+:109F70002B477D9EFB154E57835FACD5C5F20FD99D
+:109F80005E59057E858CB440AE9FA63BEC89F9F8FE
+:109F9000633619E1714A0C6CB3D1F5FE6775DFEDDC
+:109FA000E00FFCD411DA6EA3DF173B4305E06AFE35
+:109FB000C01E7A4802BE48020FC0F73412D861436F
+:109FC0007E6DF67B36828140FBF98B187C18CA3394
+:109FD000AFDA857691BEEE56CFD0F3B9CFC6E45254
+:109FE0006B3A41BB51BB4746798A7F55713FD5BD1E
+:109FF000A9DE009477DE236F87F320BB3F9BC9095E
+:10A0000062911F9B5A9783CBD101FB6933FA3D7B49
+:10A0100031F5927EF47F2A441120D5D73FB0EE115E
+:10A020006CDD141E87603D32F84B697E75EA55136E
+:10A03000613D141E2F7078BC681B961C1E044E0ACE
+:10A04000AAB82A01FFEC164CFEC7778550AF8D9D4C
+:10A050005FE27C54CD8F707BC4C6FCDD3AFCE8DF48
+:10A06000AD19BA3F86B53B82FB60E94FEFA7D7C673
+:10A07000C7E7F250C7E34C918412C1BFA591F99F85
+:10A08000C9AEFC2FE5AFFECC2E261CC72E05F19CD9
+:10A090007410DFCBB2D8F5592138D385F38784E724
+:10A0A000A99364EECF900ACEEB3C4AF79790DDF986
+:10A0B000E755FF217DDD70BE908DA063FB74281FE6
+:10A0C000F3A5BC7D31D7EB9EFFD353D125940F74FC
+:10A0D0005230B3F348B33ED7B949C473F4E2114CDC
+:10A0E0003F6CE07A80839A0DAE710639DD69D60B3C
+:10A0F000DB7438EE37C3B19822F44F2BE8FFB80B6E
+:10A10000D8FC14F37A9AF5F55AE6D152EE2746BBFD
+:10A110005B1A1B1421EFD8C4E6611D9FF0F3035DA9
+:10A12000EF75B8B9DF4429C07EF571ADE310DB4AA5
+:10A130003C1F4AAA8F58C7F992E76F174989CF2F5A
+:10A14000E9FE209C4AB87E441AE81FCD8FE4F3D77D
+:10A15000FBD3CFE1F4FCF37FAAC3F3EDD6702DEA75
+:10A1600079AD3E26A7C967B477E88F24C617FD3CB2
+:10A170007C0DD88D60CF95D438B15D568169BF5CB8
+:10A18000A59B9C008F66E56E05D2B565AC5ECAE8FE
+:10A190001DFCFB76FCEEEAAA3F0CFAA28BEAAD129C
+:10A1A000C07BC4AD58AF595981FED9942EE6B74D46
+:10A1B000E1E5B925AB9D10A2911B0E38A11D5125DB
+:10A1C0007F29B4EB0A4F2F027F571BF14B6C0A4ECD
+:10A1D000D8C7ED1C0E7925520DB4CB0B6B9A0BDB57
+:10A1E0009100B4D3EB45F87AF3CBC45570AE901F11
+:10A1F0008E846BC04F574FFCA5F8FD60B4D0507FE4
+:10A200001BEF5709B3F993F9AC9E5EBE95F7E70EC5
+:10A21000D7F756433F9B58B92FAF12D837C9566B63
+:10A220004598CF3A8EB7CE424960E741ACFD161D46
+:10A23000CD2CF45E1A66FE4EBD5E179F870DBE974D
+:10A24000C7E97E0DB7E7F57A3FE4DD8DB4B40FF3CF
+:10A25000EF8E4AD6BE89DBFFFA7E97CACC2FAEE3DB
+:10A2600047327C256D067E060BD452CCF9860C93C2
+:10A270001D47EA73CDF9F945E6FAA131E6FCAC0ACF
+:10A2800073FDC06453F92703FE92880BFD22DC5F47
+:10A290003292D7D9D2C5F03CEE8FEB7319ED8B3CDF
+:10A2A0005E6F5B3D8B7369729F5F5C4918FC16C8DB
+:10A2B0002C981F46D1FB69ECC2EFAD81DA141877F8
+:10A2C00067D7D0FDFD84D3D5E39CAE1EE3FBB787F3
+:10A2D000EFC7A3DC1FF330F7C73CC4FD310F707F1D
+:10A2E0004C37F863E8F7FBC11FE3003F4D10D32D57
+:10A2F000E08F413F0DF3C7FC90FB6336803FC60102
+:10A30000F8D780E9C6F1E1EBC0CFD6C1FD32EDDC74
+:10A310002FE3B5337FE3C6CB02B950BEE3B2C4F638
+:10A32000AED7CEF024171414CABFF389164D01BA64
+:10A33000E82404CE5B9CAF680137CD8FDEC589640D
+:10A34000BF1648A5F9511196CFE3E3809CC0F8A74A
+:10A35000061617E3C8D3C86CD8A73CAAED50F8AED0
+:10A36000E1F8FA9AC4C68372A41B95F88C7CFB0DA5
+:10A370002170449A00FDB2F9B8422101CA86DFDAA1
+:10A38000AFC9B45C59DC1B80ADF2B6F544C17E5652
+:10A39000B528EA1B1BABFD87E13C6BF3EF6D7EE458
+:10A3A0001D59C4841FB4EF8476757E6C1BEAB7AD6B
+:10A3B000F53CBEA892D5CB4F627F8FD96196FF65E1
+:10A3C0005BCD764F6BC3CC21FDC5C36789167F92E9
+:10A3D000E55C608A191F5B036C5EC9FAF3569AE765
+:10A3E000E32E37F7D7EA1E7A3EAED855A8EF27C33B
+:10A3F000F332B1D66D9F10CF17C72EC5FA56FD4E5A
+:10A40000227E543EA4A97200CE79A5A94A00F45A2E
+:10A4100069AACA533FFF1EE0F920CB2B03E7DBB943
+:10A42000F661087FCBF97680C0F9F3C6D184D917DD
+:10A43000DA9CD5812934FF6D82F6C2EBD2B21A2D97
+:10A440008FD2CB0CA768FB0AE01B8B57D0E3BB3243
+:10A45000E5487B21E5E39B378A643BCDEF080F4D50
+:10A46000CF83E218DC01F4CF14772A1520BE93B510
+:10A47000DBD4294E4F14377031A72F728858F5E678
+:10A480008B61BD2D9D33159067D2B57EB40F88CA00
+:10A49000E6AFF3BFCC2D43EF5FBB65BEAE247E9B22
+:10A4A000EFE9F328637C53C7EFCCEF0F8D5FBA7EE3
+:10A4B00016EB114CFE9D61D706ABED142EAD9B89BA
+:10A4C000DF4DFB69FDDCC6FC64FB597C998EBF4DFA
+:10A4D00081A3C8AFF5F1739568B500F50F4C222A3A
+:10A4E000DDD791EE9088F6E001CADF81FE24AA75DF
+:10A4F000D2FACAFC6880FBC905D87FA5DEAF411E31
+:10A50000F603F806D89BBC3ECA8D7003550F29FD93
+:10A5100037815FB330CED7753C68F271FF3AD53BD7
+:10A52000B0F433BA3EDD1EA1FF8CEC62FBDC3A8C4A
+:10A53000F8719965F5C486FDB0382989EB8FAD9E19
+:10A54000DBF11C509BC0F4026A350704A82769445C
+:10A5500084F1E72AFEB5345BDC350EF98AA4680283
+:10A56000E0DB0C21741BEC771CAF7AD83A38DCACFA
+:10A5700070BF96F3D59424FB9922337D3B53F65F4D
+:10A5800009F6E4E67B287E2788779164D6CF039B83
+:10A5900066A68D56E3F4AA973F6253B19F387DCBF0
+:10A5A0002C4E2F6AB63FFE5FD7E377DBCD7174FF89
+:10A5B0005F8FFFBF5B8F5F3780AFE7D2DBD9FAC910
+:10A5C0002C73FF71FD5D53709E5DAC5CB7073A2C38
+:10A5D000FDEB7ABCAEDFEBFABCAEB793C17A3D9728
+:10A5E0007781D5010AD0516E961FD51A58AD419981
+:10A5F000C5CF61A36CCDE8AFF8C042D792DBAC7792
+:10A600009C3F3F9050DE13FF08133FCDCC1D5A6E88
+:10A61000E872F49311BADE1E427D9A949411A37EDF
+:10A62000B5B3A18608743D5B7DC4CF978EE3E4F299
+:10A630007539FB029A884E0D331FDE3AFFA06B94EA
+:10A64000819F3BDC3D01380F77FB7A217CC9C877BD
+:10A650004BE409C08FAB90AF39D530EECF5DA05F32
+:10A660004E180C57E073BE0CE8D1C25F48B017E239
+:10A670003D8AC7138CAB77409414E5030E3FE34F3C
+:10A6800049F9CC79C669E87113F9F40FF8CB2A209F
+:10A6900022D0879E36C7931385E289213E80BCD79E
+:10A6A000448CF17E3ADCADED9A951A2511BF7B43BF
+:10A6B000085D210F8127563F14B1F067AAB08910B9
+:10A6C0007F583C633AFA9706FC5192995F3B227A95
+:10A6D0001CCBFF2CDF9E2327E6DBC9DA0FC43D7FAE
+:10A6E000497F5D3B3F8FD7E97B80AE2DFD88E53DFF
+:10A6F000A42FC1F8EE7233DC534ACC76C53F802ECE
+:10A7000027C0F97186E9BBE4CE4DECFFE77199B53E
+:10A7100013F56D53BFFB478ABF0B0EDB09E827BA61
+:10A720009CD1FDB10B203E93EE4F2DC46BD27D9C8E
+:10A730004B825E28FC8088D341FFF880FCD67B9159
+:10A74000619F36CBCCFF4EDAEC47E11E901E877836
+:10A750007398E5F5F9D47599F3F3C8CC6C388798FC
+:10A76000B7C94E20EE7001918EF6E9F3A7FA4B3B84
+:10A770005C4CA0FDD691FA56E0672DDCDF5EAB1095
+:10A7800009E206973C755FD56C9A8F70FDE72485CA
+:10A79000BF6A882F5BE88EC8709EF0CEBE8BBEF37A
+:10A7A0005502ED23ADB9103F984E307ED00AF739EF
+:10A7B0006DE6F99D6BFED6F9EAF78692CD43DA2570
+:10A7C000248C73FBB1ACC72D6AE7759FE9B760FCB9
+:10A7D000A23FDE7C9FE95CED5EFB27DBBD29AB245D
+:10A7E000D1FDA973B57B3BC9784B9C7D32F08B655D
+:10A7F0005268BA50148FD392EDC1C0051414D2D34D
+:10A80000E3A370A464A8D7769EF50EC379C779D464
+:10A810009B2E0ED1DF194EC7BFD8FD800CF4F9C1B5
+:10A82000236F5F057AF5A2676D54A6D3F2DD1E1281
+:10A83000457B2322831C5BB8CF867E372245ABAE97
+:10A8400031F05F8C90A5FD2F7ACC8371150BF73A10
+:10A85000223368FB854FBE338E50389C59DDFFE2B2
+:10A8600005603F3C22B03842AD6FDC35F4FB4289D5
+:10A87000DC144CC407399E9F7E267516E091B0EB20
+:10A88000C08DD86FCF77ED0EC339DE5F65764F810F
+:10A89000D6C3F325ED6121522AB0F919EF2BE8F167
+:10A8A0009BA71F16D8FC9EB6475C30BF5DDD728843
+:10A8B000D65BB6EB2F88B75F7F6C8F17E0B0EC6983
+:10A8C0009B89BF2CDB658B3AC661FAB603EFB904EE
+:10A8D000DC02E5234B91C5D074DF128CF75EDAD32E
+:10A8E000F1179B17DA9BE987C2C51F05B8BE66F34F
+:10A8F000CF80FC4F1EF2821D78B2F7412FC095F633
+:10A900003B5BA67875E947063A23ACFF58C6E0FEE4
+:10A9100008E99701BF96F5B4B3F12CF47912FE273C
+:10A9200067B05C18E930CB858FC92B55A818EECAE3
+:10A930004C181F3F201738BD2EDAF3F1368D8E7B71
+:10A940007AEFA96D1A9DFFE27F7CB8ED4ED0037FB0
+:10A95000EE5280CF2C7BE4F75E62807BB583D1FB27
+:10A9600099871FDAB985D2CB99D71DA8B79CF9D999
+:10A97000897C95AEFBCCE37FCB867B02B7FEECB245
+:10A98000E100875B9FF8FAF0A1EC7EC0D788C3B8DE
+:10A99000AF11EC5F7D5A60C1F8FB796AD99FE7F788
+:10A9A0003D9F0FF3FCE08803EF152EA3DF1A2A600A
+:10A9B000BF9620DF87FC4A0AE7A5BBD7FCC5362E29
+:10A9C00011BCB50B441FA4946C7CB0DFD77CEB9218
+:10A9D0004A48ED7E15FA23FDC8B7ADED96BD4AF79E
+:10A9E000F52BC9F7F163F2990CF05FB6BB9D8D6B47
+:10A9F000D9C70FE07F260DDEC79B1CE6F3958FC9F4
+:10AA0000E2FB5197DF9799305E4ADFC7254F7C7B89
+:10AA1000483D40E707E782EF7C1EF757EE082C73AE
+:10AA2000005DED4DD57C6C7F233368D9993D1FE7E0
+:10AA3000138A1FEFD9FB6F043ED9FF3387B29D7E87
+:10AA40005FF8B3D790CECE3CF11B5965F79DDC0281
+:10AA5000D513CE9081BF5ED01B96F233E4653B3CAC
+:10AA6000518737BE4F4B23574F57BDF8FD6DFC1E26
+:10AA700061F8BF3472E05A21C1BE3DEC28627C39D6
+:10AA8000320CE1B284F4CA4AB9793F8589B08F6F3C
+:10AA90004F03BC4BB68FFAFA1558FFC586FDDCC1D3
+:10AAA000E8D65A7F29A54FF00B0EEC6B44788D2425
+:10AAB000A0D333DD0E09E27BCFD8CF713FF74BEA4D
+:10AAC0007F0F38929CBF71389C8BCECFB5BE2F0BB9
+:10AAD000BF8DE0B41E36188EA73F4BCCFF9F730886
+:10AAE0007C1EA1E9B9B6C1F2CB4602DA0585F1F9BF
+:10AAF000B6F6D890AF9FDE65C3FBA6563EB1942450
+:10AB00003EA7FEA53ECED307C6013F3B7DF0198E82
+:10AB1000970CEF97EE7E5BD6B83C8818E54112FFA4
+:10AB2000D46B9CDF2DDB9FB8BF65BBFF92B0BF939A
+:10AB300052E0BB30FF93BD76A2D12E4EF6D8A627A9
+:10AB4000D29F0E38EC26FDA9D55375248DB6B37966
+:10AB5000535418BA6975E035B0E7B4DFDAF11C83F5
+:10AB600048FEF71C704FD393A2AEA5F06AF2CE4315
+:10AB7000FFA3DE5FB3054E922FA8815D2A65052BEA
+:10AB8000998ECCE6AD97DB15D1346F2A67F3400E72
+:10AB9000BD35FE841DD6F9678B3EF86789B40EA7D4
+:10ABA000FDFD5913FCABD444F86DEE3FB4D24654CE
+:10ABB000A3FC73F4BF05F321CFB908C495D87EEE8A
+:10ABC000D2809F2CDBE68A38E87A9E7FE2939D0054
+:10ABD000B733F73B88C310275EC7EDAF134F7CB286
+:10ABE000EDEFB4FC0434A6E3D76DA3F5410FDF9D70
+:10ABF0008AC1FAFFB9376D1CA1FCB9EEB93BAF02AF
+:10AC0000FE52073443EBD73D361CF5BAE3C358FE7A
+:10AC1000F89E1111D897C53FF9D95290238B7E9C8D
+:10AC20004AC03479FE89D76E84FC99E73C18D778FE
+:10AC3000E6B91397021D50FD5935CAF105C67704D0
+:10AC400068BF8B20CFCA852F0CF1328B20A57C6387
+:10AC5000D1D36901F0131AEA61BB658EFEDBD151D5
+:10AC60004BB45C116D9C682ED0E1A25DE6F1F29CC4
+:10AC70004C7F5A26F7CF63F5C3B98C5E7BB1DD6894
+:10AC8000A7602AB7B6D7EB8F721659FA61ED973ADB
+:10AC9000487D22FCAFE4FD2EDAF5F928737F1AFF18
+:10ACA0006E1D877DBF4D60F74AC8E32E3C475B2C85
+:10ACB000474766507A7D5226F3816E177BA323D3D4
+:10ACC000E978CF723EB93885E6E9F75C3E0FA80F08
+:10ACD00079E2ECFB31ECEF92A75C04F07DC9731EC6
+:10ACE0003C6F59F2E427C77F44BF9F7E2215E3B42F
+:10ACF000973C7707EEF71247F446F06BF73FEE40CC
+:10AD00003FF2E9C75FCA073DE4B43D9A9F31847DB5
+:10AD1000BEA4070EC107AF83DA0565F5743EDA46B7
+:10AD20001677D64052FCAB68BF0DE0D7003C7ED30F
+:10AD3000C5E2A3F839EE0AEE0F3A3B574DC3F99737
+:10AD400033FFD60A7E4F7DC537D5E1E98679405C71
+:10AD500028B988903BE4FA51C0676DB16F1015FCBB
+:10AD6000EDB1624CF57A3685AA59706E90C5CEC9A0
+:10AD7000ED597E52570EED581C11715F394067BF77
+:10AD8000A65BBC62B33A1CFAFB7727E32F1DAEC06B
+:10AD90004227F21937DEF7C4755286A03DC1D6F5B9
+:10ADA00089C0D6659DEF2776CD01FC3C7EBECDCE19
+:10ADB0004D1A24F53538A72487395F1AB47E4667C3
+:10ADC00067950CA4337D1D1D8D0AF293F6461FA6D0
+:10ADD0006B1ACB888A71F87ECCDB383C1CE51AB143
+:10ADE000C1FD5795CDD5E10E06E05C02FA047FABBC
+:10ADF000CD1D42FC72F8EAD1F677BA991FD2E6D699
+:10AE0000481D4DED6E0627B8770A7092795EEA9A72
+:10AE10008170A5EDF1FB025768A313FD11634C7C13
+:10AE20004ACEAA30E507C14DC78B3DFFD3F02308BA
+:10AE30002FF0D3A8E83F9F88706B690C60FEFF007D
+:10AE4000FC9E61F09B4C5403FDC85935A67C52F81A
+:10AE50006DA6F0CB8AD395150E0D3C1E4DA7A764A9
+:10AE6000F4FBC34682CEBCBB1BBB30D5BF6724916D
+:10AE7000EB392E819FF78756C1F91F51985F856482
+:10AE80006924CFE04F223E0DEF31E19B2650EE6664
+:10AE90007E447D7F6D8A74DCCCFFD4D7603D77BC67
+:10AEA0006C17815FD91A1E20EF641AE87846D0A586
+:10AEB000229CFDE8BF6DE2F2B565603FCDF4D1D1D3
+:10AEC000A862BA8ED3C9064E271B61DFC13FE717C0
+:10AED000714F3BA713949FF7D03CB3EFA3C4E8D7BF
+:10AEE0004EF7F744ED74FF9127A998B2775E8E383C
+:10AEF00022A5B45D6A390900BEA41FF95E84BDDFD6
+:10AF0000D283F7FBD339FCC8FEA2F4EBF0FE34B1D8
+:10AF10003339456C2C0DDBC17EB2C2B7C97FD00975
+:10AF20007677B2F964FB35473E1D2FFB4D07F2EFF4
+:10AF3000AC1B7A8ED4D275B83B53D19ECCF6337C01
+:10AF400074FB43429D61FFB293E87D9B5D57385C83
+:10AF50008087107F4BF9F6DD5DC52E3CBFB0F7F85A
+:10AF6000800F76A43339A3CEA2A35D1C6F7796F32E
+:10AF7000476FA599FE757EAC4CA930E1B1CE6F3319
+:10AF8000A69AF15DE7B76F0EF0DB608E0BCE3563EE
+:10AF90005B911EADF8DF649735E12BF0DE06617E34
+:10AFA000A7B705F60ECB603E80F12867FB0AB7C352
+:10AFB0003B00AB79FCB346E905E50EF77FEA77B9CC
+:10AFC000F690609B5A08EF81500485776328FE0055
+:10AFD0003DACA7F843305EC8CFE96422A63A7E565E
+:10AFE00083F3C4A0B7D94A5E14D9FD0B11640E9146
+:10AFF000A81DE8063FD381494ED00B253B8B53E972
+:10B00000F7883D7036D6E29EE984F86821BD12F7D4
+:10B01000FDAF9EDA82A1CE5508C4F152BC51DC7E50
+:10B020007214C6817BBA40174A05017B728FBB3709
+:10B0300005EC1BBF4B349DE374B842D35C86FC58CF
+:10B04000189DEFDBD770FDAC1FEB783339BD933C17
+:10B050008D9418E85B8F0B25AA46CA0C74BEBA748F
+:10B060001A8173CDC1F49D848F3DF8DFC3C79A0A5E
+:10B0700022B86F762BDFC8A2FCDD8DA9262A30FF0F
+:10B08000BDCDFF361EF1AC0EE041DCDB07F497AF1F
+:10B09000150D9EA7956FC5E5918AFE2A2A8FEE9D14
+:10B0A000087C30893C3AF0A751DF9269F93B2FD9EF
+:10B0B00004A3BF6E7EAC1DE5415D6C1251E97C6B53
+:10B0C000BB7E80E9BCAE6EC4FBF7222D5ED8C7F70D
+:10B0D000DA983DF75EC41EC17884CFBEF8C2067E02
+:10B0E0007DC2FA7F6F6B13D623E07D318CFBDE5679
+:10B0F000D69E54AAA84F9FE56BACDDE008405CF9F2
+:10B100007B5DB4DD10F0AC056328817E8AF7FF21FA
+:10B11000D69FD48F023EA7D3FB1D32E54B0087B7E5
+:10B120001C09FDEC0B5C97AD03782F70053601BF51
+:10B1300021EE8CF37A87E21D91EABD08EF90F76A61
+:10B14000939F95F931DFE17A31712629F7F2F64ABA
+:10B15000E2F2259DA75EBC8BE65ACB434162B0AFBD
+:10B160006D84D9D74B9FAEE6EF7DB0F924C04FA6D2
+:10B17000CF763A900FCDE5FE201D5FE3F812F2F294
+:10B18000FBA0267C5A10DB88FB2D748CBD771285C2
+:10B19000DF87148FC02F27745C321CE868D5DAAFC4
+:10B1A0006EB881F6FFD12B36FC3E3FE6C2FAEFDFE8
+:10B1B000E5BFF706D0D77F69C733F68F0E5F86E706
+:10B1C000B1EFDBCD7E841B5318FDFED1C5EC917928
+:10B1D000B10E937E3CAF6D8E0CFEC779B1F5F87D54
+:10B1E0001E1CCAB07B1B87AA4BE0BC86E0F9E81F97
+:10B1F000DBDF9DBA1AE55905FAB1EAD63912DE232A
+:10B20000F9A34B35F19DBABE4EEC9750FD282B9B10
+:10B21000F767E01F7531B87402FBA311B867308F70
+:10B22000F39181F96DB59BF8C8FBAEC47E925303D0
+:10B23000EBFB2AD2D1E0F55DCAE84B1FB78FD15D99
+:10B240007C3DF74E4AB49EF83AA660FDF7D3138FC3
+:10B250009F91C2C63FDE389F04281FAA75D07A6E20
+:10B2600018FF96D68960676F4DCF100CEBAAEB5A8A
+:10B2700044028675D56D9D2DD71AFA8DEF83ED05A5
+:10B28000E33E64A4FC63EAEA7290DBC17F003DD533
+:10B29000765C322E847636E327EFD8FDF9C0574F1F
+:10B2A00074DD9290BE33522CFBD3C5F787EABD956F
+:10B2B00086FDD1F7C5DAFEF89FEAFE7A17F8013667
+:10B2C00033A52619BC06ED5B6162B89573FC3C4E54
+:10B2D000E56C08E1A63E7904F07A5D2AC6712687FE
+:10B2E000DF85243414FC92E8AF54DF294D9900E344
+:10B2F0001284435D17C38373C12D3E2EC783EAC4F6
+:10B30000EBB97E000F1A884609F6A87C2E3CB8934C
+:10B3100068CE21D6318007A34C7870FDDAFCCB8053
+:10B320001EDF033D65D4E0FD3F2A6BDEC9700EB41D
+:10B33000D686E74C4753B4ECEB597E3CF0E7A3DEEE
+:10B34000F055932BE3F9050F967A671BC63DD1762E
+:10B350008B37919FF5FA64F853A291F2AAFF7DF81A
+:10B36000F34E927B570B5CD537A6005F0E27F6E7AE
+:10B37000EAA9CEBF6D69EE01BB13E4E95177D15F55
+:10B3800023B4F451576801F47387A88E9B2DC4ED44
+:10B39000CF41FA67E3F44B8E9582BF3078C9313BD9
+:10B3A000EA43D81F01BDB290DFDF42FF460ECA0359
+:10B3B000EB79E9FA94C284E7AA2D8DF5171DC30035
+:10B3C000228D28867B6012617AD4A784F9BDF4F5BA
+:10B3D000C8F690E207FB522041C073BB146A833861
+:10B3E00028BB2F6BBC66806B670A8BFF731D3AD43A
+:10B3F0005648DBBBDE7D45C1B8153A0EF8D79C79BF
+:10B40000D259A37FDA9EC5E2124989E17B11C42794
+:10B41000D0BCC9CEA7F31DC24E7D566070D03C0E85
+:10B420007E0F4EB381DCBB4E7FF8024047F1E575DD
+:10B430003D0E446A66E5E97A71332BE7FECB65B5CC
+:10B44000CC3F69DDD7EBF6AFC177F5AEDB9F3307B5
+:10B45000FC58D7B947BD0BE70BCF820F1FF03D9DBE
+:10B46000C9656BBBC7389DFE5BB7A8D9E9BE1CB2E6
+:10B47000F71F84B876ED36F64EE2F5BF3F644FA570
+:10B48000E91BAF1EB5435CD14D10A043D7359BA837
+:10B490003253822308D739A4C7C3F23DC3667A8CDE
+:10B4A000FD515315FA5BCECE79AFFFFDAB9781F816
+:10B4B000A4FDB5407AD32B4486FE67EF535BD9B524
+:10B4C0003BDEDF7EDA9F18EF2F0E4799D9399213B2
+:10B4D000E112879313E1F6FA405CA4867E14039C84
+:10B4E00051DFD0E13C00B7B459579271C9E9E53A50
+:10B4F000F7C877C9B8F8BCAC70FE088A28BD3D9380
+:10B5000012F815D04D2425F06B48173BFBF3A5220C
+:10B51000BC77F83BE0B34B6DA182EC62BC8F386A1C
+:10B5200018C471F5263E5FB5D2E95B402F10CFCD30
+:10B53000E32B6FE4EB7BFE7B273C1837F9C46BF9F8
+:10B54000902EB1F5ADFB2ED0DB7FD850FF3EBB6F08
+:10B55000D49071696F717FC7C914FD3D16B6BE9B4B
+:10B56000B81E77D3BED408BC7B795383CDA4FFDE4D
+:10B57000D4C0E23888D43BEE5A931ED99CB41FB095
+:10B580003BADFDE8EB3B989F7B21D887F74F90556B
+:10B59000F03F1C78E5ECEB75349F32C289E7B2EBE3
+:10B5A000D239FE568BB8EFF7A70752C782DF696D15
+:10B5B000865FA3EB5CFB02E911297C0E8EBE3D5237
+:10B5C00043C75B7F89883EAB0DB107306E522B6756
+:10B5D000EF14295C1FDDD07BB40BF0F1C41107FA26
+:10B5E000FBED1E765F75AD3D980FFAFBBBDD72C2B9
+:10B5F00077EFFEEE96705DDD421FC6BBCD21612761
+:10B60000F08D7DBD3387C37CBC7EA200FA9FD86AD3
+:10B6100013F93D28EEE7884ACCCFAE492C1FE0A9AC
+:10B62000E232C6ABB54F9F8AF114733B7F8371C280
+:10B630005E7E9FC93A8F0B53D97C3DBD1957007C64
+:10B640003D53457CD3C8E3EFC778F182DE1A19DB9E
+:10B65000878521DB17AC54AE00B8427BE0FF05E7DD
+:10B66000D9BE3895C53B6DE47672B7DDDF3A95F605
+:10B67000D3BD2E5D80FDD0EB4D4965FACC89A9BACA
+:10B68000FF268CFE9BFC12C505EFA3E40790B8894A
+:10B69000A7328C71B8DBA11EF36F221CBA473F1989
+:10B6A00085F3E3B5201B609FED0C9FD6AE13D09FB2
+:10B6B00049E1970BF2E2DD7B1CDF807514B4090AC7
+:10B6C000D8DE344D38EF5BDD4E66B774DE8B762006
+:10B6D000B847A1DFFCADBFC3797992AC779B9BC122
+:10B6E000EBDD73E0475AAA9DDD1B6AE8E57652144C
+:10B6F000DF3F0CEBEFC2052AD9BB84524035C6A10F
+:10B70000C4E987D961749D0138DFAA9D2847C00F1D
+:10B7100020B675E33BBF73C20E72395D5FA7D01BC5
+:10B72000007AD12688FCFDADC05B00A7F51B8763BE
+:10B730003CDB1A31908FFE9DFF25E3F9D8C1C0D9BB
+:10B74000CD73687EDB4419E9E26080DD6BBD7F6507
+:10B750005137D8E19E861A7CB737A2E04BB8A4A92E
+:10B7600092BC0CF1A44D2B4545A0F5C341FD7E8153
+:10B7700092027831DEF6E11565707E9623822F897C
+:10B780009C10D8BB202D2B6B14D8D716254B30DA44
+:10B790002DB7A432F9F2ABF4E02DA934F5DD75B77D
+:10B7A0000231DD1B62991782BF506B9355F67E30D4
+:10B7B0007B4F2493EF4B66AF189DE7C5BC7B3E35AE
+:10B7C00091374C617ECA1F5C1962FE453893AC42CA
+:10B7D000FF22FFF3E1BE66F1DCDA312998D9B47AB1
+:10B7E0001ED6877EB2693F999562B48AF6BB3D3D0D
+:10B7F000B00DE5C9654E841391FABA004E91CB7233
+:10B80000FD10D77AF7A491BF8127A5320FF7CF0497
+:10B81000391A1991F24637F0A91659053ACF5C79D1
+:10B82000FC06F89EEEFFE12D906636FFE14E900794
+:10B83000E97D7F69C4EFD365937F2FF3CDF73F8711
+:10B84000F2CCA06CF2139E4E0FFE3095EEFBB6F2DA
+:10B850007018DE3DC51DCD8EAF63CFAADEE9F08E38
+:10B86000F589AB45FF765E8EEBDAA444D632B85547
+:10B87000825CD3E1B646547BE01D65ED2A27E247A2
+:10B8800009E9457E9503A7C8C5F17DC97CB37D391B
+:10B89000C44958E7F308A75BF883772531FE9ECAB1
+:10B8A0003139676A0AE0F5E315BD3ED0E3D7A52735
+:10B8B0008E4F38E966ED1D49EEA71FE7E5C012BBC4
+:10B8C0002A300D8C85D44DB43448F39CF83EE1E326
+:10B8D000A2FA47C4F3BB6D2AEC0FD4B7D3FD3BF0FB
+:10B8E000F249F40F1E08FF0ED317DC657A7FD16C86
+:10B8F000DA7E7DE551F6CEB7C270A4AE8DF18B3AFB
+:10B900005F9F13CE2BEACA89B29DE39BA6C319FCA5
+:10B910005D5C5ED55ECBE09A554EF0BC157C62F066
+:10B920004E5936D4A3F0CB6A5BB51CF791F46AC5C7
+:10B93000B4DE7AE817F6A799DD3B21A4CF89F41B82
+:10B94000B6E17923A5F75FC179626DE7703C6F8737
+:10B95000EBE9D05F061F3783F7D74DFB01FFDF8987
+:10B96000361BD98EFCAD97405E5D497119F1B3BFAE
+:10B97000BA8CF6AB562ACA5A1D0F743E4649632E3E
+:10B98000951700B7B99AB61CF0EFA8537919E6914C
+:10B99000BAC9A1C2FAE76E7AEA0ED05B527D7D6D1C
+:10B9A000C01FEA26B2F96674D2EFA8DFA8BF82FAF8
+:10B9B000759D0E958DC7E157C9F18CC3E1663EEFC9
+:10B9C0009BB7B279A78C8884013FEB5652B8425995
+:10B9D00088E13DB834BF1091AE0EC3FA3D5A36F639
+:10B9E0003B6C96852E2CF8A7AFAB96AFAB76255B5C
+:10B9F00017E1F444A715857E6B2BD93AE712D65E82
+:10BA000084EFB4FF9BF97A6AB52731BDB9CD61EAFD
+:10BA10007F5BD98E5E984F61B9AC0A0867F63E66C7
+:10BA20003E5F577E331B2FBFFC4984176930CC170C
+:10BA3000FDA2863CA5AB132F51C2A27AAE0081FCB9
+:10BA4000B4DFA3DF93F11CA56493795D27DA473D4A
+:10BA5000D009FECF7B643CAF785CF4BF558076A8FC
+:10BA6000AC32FEE3FFDD0CE0D33737E3BDA93DD5B3
+:10BA70000CFE27BE4922800FA587831900EFD2C391
+:10BA8000219ED6E33936DE13AB8AE331359DDA04E5
+:10BA9000E097B1E247E7031FA0FB0CFAE008E3BC24
+:10BAA000E9FC32DBB26B200E296B62468D8C4FFABB
+:10BAB0005ACA0F6F9909EFD7661DDA720B8C934340
+:10BAC0000CEBA1E5459E62A4BBCC43B414EA351C43
+:10BAD000BF0BF6A393BF2F5F0A33CBC0F410A4991A
+:10BAE00094BE3B32609E12995A11E7070FDE533520
+:10BAF0001EF80ADE29A9C0344A2A06F30D43FDD1F7
+:10BB0000BCBE2624A837DAA39AECF207EF99361ABE
+:10BB1000ECF7F5A027D27D6A27CA87101FA3F94545
+:10BB200084FB7A7BD4594EF36BA8DE08FACB86B23D
+:10BB30003F884077EBF7113FE04766F01F0EE33E8A
+:10BB4000CE71A7E3BA25997400FD1F1C7D7C3AECE9
+:10BB500053E48088EF48D4FCC2BD2515F4A1D75921
+:10BB6000FC49F74BF528BF6FCF9713BEC34CCEA14E
+:10BB7000275AEB6794CE443F5EC1A68DD3E13E4E7B
+:10BB8000DD74C97F39AD9DB5A9BA1AF4183548B12D
+:10BB90006B389DF7D6F1AB8008D519ECBC4A9DCE29
+:10BBA000BEAB5359DAD138FF22B0DBC3BB24173CFC
+:10BBB000853CA69DBD57D7517ED619A27A6965F5F9
+:10BBC0005EE737E9F76395540AD2EFC7A69C75C1C3
+:10BBD000F9CCFD95359900CF7D6D66BD8EC0636A49
+:10BBE000D40E1AEB08073C745E9DBF27084F9B23B9
+:10BBF000DA554BF3B6A7DCA0E10CB26FDA3BBB67BA
+:10BC0000019ECE2DC3F0E441EB3DCBE5C59C867E85
+:10BC1000BC5755A811768E1ABE1799F2CD9C6514A3
+:10BC20006ABDC8743C9B987D1296022F025F0E97E6
+:10BC3000876468A2F3B3CED2DA9DC0CFFE067A1D28
+:10BC4000C8B9FAF978FF11E9DF06FA507F7522BB0F
+:10BC500029989A82F33DB1F59AD7C03F3DB781E963
+:10BC6000FB055B3F14703FA8DE9743FB2FA8C4275A
+:10BC70002AC9DC9561E758D89F1291A82ACCA787DA
+:10BC8000809D10A6F2C70807BDDF7FB6FD3AB70357
+:10BC9000DB07C1781E165F8F9BAF27DF4FD793401E
+:10BCA0004E5FC5C7BDEDBE0F0F4C02F8AF64265204
+:10BCB00041F86DC169984781767EF3F816F447E143
+:10BCC000B9D3CDEE437B2AFBF0DE9195BF833A0FCB
+:10BCD00074BB2DF5CC7866DF9BF9E9A03CC72BEB54
+:10BCE000F77C0BBF1AEBE8B912F7770F7BEF9C10CC
+:10BCF0004AB74E7C065465EFC446F477C9EBA1DE23
+:10BD0000188F5B013CE81CFD870A80CF3AAE2FDC20
+:10BD10005C4ED05EBD39AF17F58539CD5C5F90FCC8
+:10BD2000ADC06453B7A693B506FD0143FCE188B1ED
+:10BD300099EB0BBAFCE772BBCED7DB867215F40326
+:10BD4000835CADD5985C2DF031B95ED746C75139CB
+:10BD5000325719F51226C7D54D5C7FE07238938FA4
+:10BD60009BD5C6E45526E8115E083FD0502EE35916
+:10BD70005E765C6F1956CEE46566E7E328D75E0110
+:10BD8000A7CB04E01B4C5E8EF8CDAB1A80C9473FB1
+:10BD900077513EFD142FF729543FCB88EB676B4456
+:10BDA0007ECE44987E88B1F5749E8FF1FAFAF71D25
+:10BDB0007C7E8F1FCAF806F0D707C345E36D06BA2D
+:10BDC00045AF27CDE757B273FAFC06764EEDF1CFBB
+:10BDD000DB69339C3F34BB99BDD9ACE35543D407F1
+:10BDE000FDE2FD40E4E3EC7DA976FE1E946E5F7DEE
+:10BDF0002795FB3538FE2493273A1FF29080B79C95
+:10BE0000C2F7586427F26B8DDA4BB0B663E1A6DC5B
+:10BE10008540EFE1AB2B61FEEB27FD15E32E0A9287
+:10BE2000D88B7F073B93C1E14BF175CFF457991D38
+:10BE3000DA2B26BC2733D123E13C7B24920AF07411
+:10BE400085D9FB84AE8972C2FA177A18DF943DEC6B
+:10BE50001ED1FA493BF17E6352F92C11CD96409EDA
+:10BE6000EAF2B613F6793221D5EE59AD1AF2FD4851
+:10BE7000D086FC95A0DD19E6BFFFA295C9E837EC96
+:10BE8000B4879DB01F1B2AF9BE2ACE6EB88FFEA5BF
+:10BE9000F785C203F6B93D2046E07E793BB554C72D
+:10BEA00032BF0EFE7ECE096ABF1BCF292EF3881C3F
+:10BEB0004EAA08F189056D0CBFD64F92711E6BC753
+:10BEC0006777DB0A8DFC97C12998CAE0B476D28BDC
+:10BED000885FE73BBF790D774E3E6638473CBEF939
+:10BEE000A1228073FC9D96C090F717E635FC66F2A0
+:10BEF0008E04E70303E56047B9C10E8C5C6F3C67B5
+:10BF0000F9770FB3AB431EB3FF0EF8AB1D8D8B4813
+:10BF10002EF897F65C12F1A2FF7E313BAF5DC0CFE9
+:10BF20006B4FEEB806DF53184BD1CA9E60DFDF6F50
+:10BF300034BFA7F0FE830FE532BF46C414E7B160FB
+:10BF4000E73363D8BB661AFF9D0CA26655B177AF85
+:10BF5000514EBFE8D71CF8EE5C10F9900CBF5301AE
+:10BF6000FE76A0E062B8D7DF83A91BE8B778F07B44
+:10BF70006E19540D43BB8B0431CD26F598FA481841
+:10BF8000D35CD283691ED8B9C52017FA31558922EE
+:10BF90001203DF2F227ECC979020A612EC5B66FC6A
+:10BFA0005C42DAE5C4F80B38BF00BAD7CF29F4F306
+:10BFB000FD199EDA4E0F327BF379C5524F609D0713
+:10BFC000E11F45BE3D87B3F0C33F1ED303F77B5649
+:10BFD000AC63F74B74BE8E760DEDFFD10C2607B423
+:10BFE000BB05E45FAB53AFBA14E1D8693F6D3C6F5A
+:10BFF000204E6709FCFE8BDEEF1CEE5F98C3E51F49
+:10C00000B8B7D9FD3B3FDEFF99037E0643391928B7
+:10C0100067F7AAF57EC4D42923873ADF33B4C778FB
+:10C02000E45A8BFE7F4EB96DC9CFB5B6FF8C4E2852
+:10C030003BEE877BF452359F9D3331B94D1149C595
+:10C04000766D8EB7D10E0B5F1630C2E510C77F5DDF
+:10C050009ECCB5F8F5ADE95C89D385A51F2AF9D248
+:10C06000E15E04BE6962A06BFDDD5BFD77D2160464
+:10C0700042720E6BE6C3773DF8BCC3646B4D0E4D48
+:10C08000DF83BCC19F7FD81BFAADC7608728817A48
+:10C0900091BFFF8774388FD3E165B6CE6AE06F2712
+:10C0A00042C40FF6C30252BF1EF431F2AA0DF9DBEF
+:10C0B0000574DE7205D86F44133330AFC1EFF97CDD
+:10C0C000D0C8EEE51CE7EF56EFE4EF249DE2EF5415
+:10C0D0008FEDBAE32AC08393FCBD6A9DFEF571C75C
+:10C0E000F6A4CE06B93FB6E7923AA8377697230A68
+:10C0F000702EDBD71E04BF10BCCF9242C7C9A3E38A
+:10C100003933808F1094B7A73A5322ABE93C4F756F
+:10C11000D9902F7F5C2EE23B23F0CCA58DCF2F2D25
+:10C1200003FAF9FB8DA0879CE47C447FEFF154B5C2
+:10C130008AF6F10B7BD608702FE1D46C15D77D2AD7
+:10C14000A7273F83C2C7E765F1E525BB1DD1223A8A
+:10C150008F858FBC5E540BFCAF28BC30D13973BACD
+:10C1600097F1BF534F108C873BE5E2BF4FE4ECF1F2
+:10C170001AFDACA95EC164179EF2F0DF39CA3B47D5
+:10C180003D1E5F4EDC3D5E46F73D5E388FBA37F5AB
+:10C19000C7787FEDF813EC9CE285CD75F9E08F1A36
+:10C1A000EE55D939FE9E9F60DC38AC03EC683A3F0F
+:10C1B00015E6776FEA5B27C1FF40DBE1FD0CBDDDD3
+:10C1C000F13D75AC7E17ADEF45B8136F05E0038305
+:10C1D0003BD9CDF884AE3F2E8A64E3EF2DC4CB4526
+:10C1E0002C8729BA28FCC7EEBE1ACFB5467B3398F8
+:10C1F0007C507AC6CCC4F987F3611D7B2E09E58398
+:10C200001FEFB8FE7B4E52381FE030C3131AED35D6
+:10C21000F0F7F7DF7E0AF97B9958FFE7BB002FF7AD
+:10C22000B2DF1FB9E3CD8DA2917F4CF432FFFABD8E
+:10C23000A94BBD701E757CE09D9C308BF7D9CFDE7D
+:10C24000615DC469EF7837B59F283CDEDFFD032CC4
+:10C250003F3EF08E4D0FC693BDBFFBF90C486B7986
+:10C260003C3F895C83F445E1D2E64C20AF06EE45C5
+:10C2700045D87DB733027F7FF43E1D6EF5F24CD377
+:10C280007915A3EFBCAD8587505F8E24BE276795D7
+:10C29000F7D6F764CF750FF828A7D363FC9D92A556
+:10C2A0009ED0B7BD09E4486DC7927C80732DDCA990
+:10C2B000C33887AF5E0EF636DE3761EFC946114EE2
+:10C2C000FA7BB1643C2B4F67F9C5DE2BD7804E74E7
+:10C2D0005C7F7F56FB1A2B2F64E56DBCFC254F70ED
+:10C2E0002E1B9FBD2744B9623AFC2E85CEFF92AF2C
+:10C2F000DFFCBB143F029E3C01FB5B8AFD49B4BFDF
+:10C30000B1FF7A7F3ABFF997FB71FEF7F6A3F361AD
+:10C31000A04B08D9237EFF98FF0EF8FDB3EDC9AC02
+:10C3200002133FFF6473712B9C037DCCDF0F71748C
+:10C33000AE2220976EDEB4D1F4BB26D677BD9A78B4
+:10C340003C895C4CE9CC40CFFBBD4C8FDECFF92162
+:10C35000FCB90DEFF9C05F673686DCA0FD378ABFF8
+:10C36000F35E46C2A85F8D213D9896935E4CC791BF
+:10C370007E4CF198B4185C7D7E1B7FAFB70A16BF68
+:10C38000D819BA1F42753F75849E017C82777B0560
+:10C390001BE8454B27C3FC7FEE55F4DFF52496DF01
+:10C3A0004B8BFF0E880A7ACD0CDF507A0D51A4D347
+:10C3B00003F11B45F8EEEF0B5EEC37D9EFBF2DB75D
+:10C3C000BC7FC2EE11EB7058427A300EE285AD2B85
+:10C3D0005E1E4DE1BF70B707E5C1C8ADCDF8FB5F8C
+:10C3E0000B496F36DC2F1DC9DF93205DECF785F418
+:10C3F00077224677394CEFD42DB1FCFED022FE7B5C
+:10C40000618B2CDFF5FB9B1DF021411C81F5FEE7C4
+:10C410003BDE24EF369527FE1D18EBFDCFDD3D22D8
+:10C42000C6F7AC80782121CEF746EFA87798F1AB1C
+:10C43000E7D212C3FB4E4D829FD9D39E94C083C2D4
+:10C44000E071462A0CBFF60842C238B26FA6897C5A
+:10C450001F9AC995B49FA6C59202F666532405CFCC
+:10C46000419B1466175EE0A971829D4ED2457C47C0
+:10C470006E9A6D0AC697CB4BA48BE0DCF3D0F685A1
+:10C48000BD707FA1C927A19FF68274760E4A7244BF
+:10C490007C1FA059D99B3E07F6C9CDCE1947282449
+:10C4A0000271F007BA6F1721DF44CD96E1308E108C
+:10C4B000EAC57B373912E1E7AF33C653FC2BE0F80E
+:10C4C00020914EBC7F3C75C93117C8F502BEEF13F1
+:10C4D000D20A99DF98EFE7B686A3E980A72F75B750
+:10C4E000FE761AEDCF1E9130AEB5ECF3A637A6D18D
+:10C4F000F1FABB658C67D5E190BF5232DD9FCDBBB1
+:10C50000D59C972DF788256228A7F9517C7C78C0A7
+:10C51000296A8CABCA0A3067A1E246FCB8284D20D4
+:10C52000786EC3F3A3214FF174973D5C03EF61EE86
+:10C53000FA93807E8783DDF30A304EFF995001E045
+:10C54000B78E0FD6FDFB1BD7872806B8F8FD6017FE
+:10C550001CD659F1A7B99194823FDA193994722106
+:10C56000ECE3613BBE23D5C2F56F89FF4EAF8E2F42
+:10C57000D6B4C582772D9F5F8378D74FF16EFB10BD
+:10C580007827292AEA09F63CE207F2B767F5E62A96
+:10C59000B4DD854FC97E3705D9B4C7CAD3409FB92A
+:10C5A000F0F9EBF09E2CC00BDF796C904BC1EE776D
+:10C5B000346495C2EF1D4D7BCC8DF878D6CDCE7FFF
+:10C5C000A486543F94377557F954035EB7362AA5AD
+:10C5D0005229BC6FEA2C85DF456A4DF23BCC23D251
+:10C5E000C520F897646EFFCF4B63F39D97968AE959
+:10C5F000CD3C7F9FA4CD84F9DF47F107E2050EDC37
+:10C60000CAF077458E13EF3DAF78A978F8507140A6
+:10C610003B1B7DA500B7ADB7D6A2DFA37AF921D722
+:10C62000E540E71EA702F868F38EBC770AE0FBCB73
+:10C6300076BCF7D5E4A952E718FAB37927A25FC907
+:10C64000266AB96014DD9976E4722907F045DB02A9
+:10C6500092A869C373974B943FEDF268B9022DEF2E
+:10C66000D8F03CCB0FD3B608B4FC071B7EC1EA8FD1
+:10C67000D072E1973F7EB4E13F5879A9B605F20F39
+:10C680006CF835CB836E41F5984737FCEE72B82FC6
+:10C69000DD64F7CF02FFCE8FE9FCCBE9FC7B78BAF3
+:10C6A000278DF973F4F2BDF09DC27B1F4FADE54FAE
+:10C6B000F2764F2729FF292FDF9FA4FF9FF376D122
+:10C6C00024ED0FF2768792B47F91B73B9CA4FC6572
+:10C6D0005EFE4A92FE7FC5DBF52669FF5BDEEED586
+:10C6E00024EDFFC0DB1D4952FE062F7FD3D2FF5B36
+:10C6F000BC7E1FFF9EE7697B43A37897D7CD5EF68C
+:10C700002CF3B4A1FEBEB5BE12F1BF6902D33374DF
+:10C710007CCF83784D9A2F52585C5591C2ECB85F0C
+:10C72000F0FEAB97976C00BC5BF14B1BCA532A47DA
+:10C73000F0F774B5E52CEE65C54BEC3EC88AE51202
+:10C74000BECFAEE3E32F2CF3DFC6E7D7CCE7FB5C2D
+:10C750005A113F6FF195CE30C67B2AE6BC93D213B7
+:10C7600084EC346731F952B6BCC6390AE407952F18
+:10C77000C0375BDC7214EED1B72812963767D52824
+:10C7800050AE2912CA9F96AC1AE71CF4E764A07F4A
+:10C79000A280C7ED352B12DEE397D2A762F9B4C7AA
+:10C7A0006628C0479B497F3ABCCFA7AD94F0BCF642
+:10C7B000407D0D7E2F48FF281DF8F38174B6AE43EF
+:10C7C0009E175DF08EAB749B88F26224C08F8E5BE7
+:10C7D000B4528CA8B4CA21658508F9079A99BCA2FD
+:10C7E0007F9EF186771477DD5EF532C4EF34AD932A
+:10C7F000F077B6E14F32C88312FE3BA5994A8649CD
+:10C800005EDDC7FDB89ACF8971782512F1197FBF17
+:10C810003253E1E769B619F88E5971D82C9F0ADBBB
+:10C82000CCEFD81458E493555E8DA8A7FCD150DF07
+:10C83000E1534CF9CFD3F87B167EE2077D66C5E362
+:10C840002B2E8750769D5FEBF2E5BF005F71521291
+:10C8500000800000000000001F8B080000000000A6
+:10C86000000BDD7D0B7854D5B5F03E67CE3C3349E7
+:10C8700066263393C97B1220040838811023BE2614
+:10C88000216044B403A2E2A338E11920C9044A2B71
+:10C8900056BC4C48C440B186DB8840810E2A8AF5DC
+:10C8A000D1A1458D18EC808878ABBDD1D25ED4D6AD
+:10C8B0008EC855501EA3B648BDB5FC7BADBD7732C2
+:10C8C000E724516CFDEEFDBE3FFDEC619FBDCF7EC8
+:10C8D000ACBDDE6BED3DE7CFD3BF2B09695D19BD64
+:10C8E00062A89E902D2B4DC314FA6CFD72DC4C5245
+:10C8F0004E4822D5E27F482264F54ADB3065182194
+:10C90000E779FB621B7DE92264AB129E4E9CF41911
+:10C9100051484B2121FB96C904CA4BB34C11236DDE
+:10C92000B2F4D5DF5D3D1CCA4B641FF1F67DAF7DCF
+:10C930003EBAD2330CC67F259D60BFFAA034ECD836
+:10C9400038FA6F25E809A41232A443391A3711FCCA
+:10C950003B4FFF2B6CA7E592BEB25E1FB0D9AC84F3
+:10C960001490A476743E8AA6AC771DB6074BA17FBF
+:10C9700005FBD7CE23AF99AE3FA95FA3C7A62AAFC9
+:10C98000969A4BC810FAA47305F8845D7264075D2B
+:10C9900067EEF2BB261CCB2024E7A0A58DC01A3A77
+:10C9A0001E24C44D880EC6A6EB5624BF97E808691E
+:10C9B0002B2CF349F479E8690B83539E15E16490BD
+:10C9C0007C99D7D0A7510ED8A07FFAE787FEEFCD8C
+:10C9D000B36C5F5B08C5A009E090BB9376984D8B64
+:10C9E000E1DC35FEA1749F28B8C904A8EF69F7D32C
+:10C9F000F5EF947ACBB5508E460CAC3D2131F8BFA3
+:10CA00005DB2C4EB895FF110F29424F1FA91B5356F
+:10CA1000B9B4BD621BA5F80899DD31BA5D7F39D480
+:10CA2000CBE27B3FA9A4EB83F17819E0F2C4015E6D
+:10CA30001FBEB4BD86CE6797418C4FC2D07E972C67
+:10CA4000B372B8BCBDE632DA5F35FF3E9CBFC69F0D
+:10CA50008BF3B9466727A4D97665BBF592BEF9B6C4
+:10CA6000D827B5B728849CF2C6D3E87691C6EDC71F
+:10CA7000DC8476B57A6630007024C44702A309F9D5
+:10CA80006FC98BF822F64FBFBB2A9C435F9D39F8D4
+:10CA9000455A297D8674F18329147E8D5D4193BEAC
+:10CAA00088C259EF0FE714F67DD7B87B1A095238C0
+:10CAB00085BACBF039C0778714F99FFACE64B88075
+:10CAC000F14EC5DE6C7A925635EA82EDD621D89EBB
+:10CAD000B0FD1F787DE2FB534FBE79238C77DA1BC4
+:10CAE000774F01BC8C51B80CF09D68DFD4554500E0
+:10CAF000EFFF62F1AFB48D27E4263BA333A234FBF2
+:10CB0000A07DD4D461F3D17AB3BE23E0A3EDE9567E
+:10CB100046E4CABEE72ADB506CAF7DAFA59FA8896B
+:10CB2000644CA5781D6E507C3B0894C329636879DA
+:10CB30005DA332AE854E6955D91FC69642F9192BB1
+:10CB400031D2726BC3014F29D091CF40287B21EBAA
+:10CB50002E8966011DB7351A663E42E7138D2DF505
+:10CB6000CC2BEDEBBFC54E098FCE7FCDCB94CE2E17
+:10CB7000A24F7DD42EC1F7C314027468B6D37DA62C
+:10CB800065739683840BA19D751DD0E31A7DB0B6A5
+:10CB90001ADA65C964071DD73C6C466D359D87C799
+:10CBA000254B3A9C47CD91F9B4BED56600CE467E62
+:10CBB0006B9FBD13E0F484E26B063A7CC26AB585D4
+:10CBC0006905E58D7EA05B6598330265A38E3447C9
+:10CBD000E9FC72CA48206AED9BE76F397FFCADCD56
+:10CBE00080F35D678E4EABA2FD5896CAB6301D6FBE
+:10CBF0004DE3869EC9749C9F363EFB460B7DBFD697
+:10CC0000AD109887D5A9C40C69148FAFA573A4F390
+:10CC10007EAA256003FE997029E4215A6F196A20C3
+:10CC2000DE243E682DA5E524FE94E154FC66FAFD61
+:10CC3000497BF0D7363AFEB8D70F9BE07BCF7859C7
+:10CC400006B2892A6C9FD3CAD5FDD82E53F7E3A824
+:10CC500051D73BA7AAEBDD33D4F59EDBD4E5ECB985
+:10CC6000EA722DE0DB786848E75C41D7C1AA8825E5
+:10CC7000FEC94A9286F0790BE06F29967D001F73FA
+:10CC8000E323C7E7D3FA1CE02774FE640C89ECA009
+:10CC9000FBB93FFF87DE3885B3D1D1ECB597F68776
+:10CCA000474E9EE91AD82FEB50C546687BEB1F4FC5
+:10CCB0007C09FD5B4952BB42808F3F0EFB0B7F1E00
+:10CCC0003A9F54F88717E0DDFCE7BB41EEBDA1F3C6
+:10CCD00001BC731A151CFFBE19DE88AE903527B44F
+:10CCE0007D1A6F9F665AD7A31B439F7F5CB34497FF
+:10CCF000D61FAE6ED22C015D52FC407941EA08CAC3
+:10CD00008B7B65520F7843C995407F36F880F29946
+:10CD1000890E03E2CDE71C7F28A6C950EFB6B13ECD
+:10CD20000D5973CD40CFF71C64F87F8F81F5D3DBAD
+:10CD30009F17074511047C52679755FD6CB0F1367B
+:10CD4000BCECB2B3F2AE038E6B802E37CC708C0588
+:10CD50003C31CA2408FDA5E79AFC23E8FACCAF1AB7
+:10CD6000C212ED345D2107F40EDADE426E0FD07987
+:10CD70006C3A6409EBE87BF3BC7FB711E01B7636B5
+:10CD8000EF5DAB7CBF033E90A853108E6657876D56
+:10CD90006C295B4398CECF01FFA0FCB16A58A70D68
+:10CDA000F6D35CD581F2DB5CD6D10170DA3455461E
+:10CDB0007DC23157467C36E745DF184ADFEBE7C9CD
+:10CDC00036E8CF4105BB8176F293DC8E4000FAA5B0
+:10CDD00030972B18AA40BFB8423A4E0687ABD3B95A
+:10CDE000FB0E89F69301FD8D61ED014E760EA75283
+:10CDF000BB17F1D3C9FBCD184ADB8F61FDB455F4E5
+:10CE0000F523F671532D89C0FCC4B8A29FDEFE89BC
+:10CE10005F02BEAAFF0D851BDD2729DF8493BB6758
+:10CE20001189180B013E81E6ED48D756F210D08BE0
+:10CE300033B71AF028FBD0E6E9F218F8CE82E3E81F
+:10CE4000E79108E071B6424C5738407F09201CB585
+:10CE5000F49A75A0E37A4A23BDFBA2A5DF2C85B422
+:10CE6000EB1CFDE938CBE9AC2E1E33003D6BE82509
+:10CE7000EB50E2FB80F45ABADE9672BA0CE04292B2
+:10CE8000DBEBBEBEACD345DF980C9B9549E50405B2
+:10CE90007DBE663C42FE6184B24464EFF921C0F776
+:10CEA000ED8C7F102AAF28B1EE1A6B9B68053A5DB6
+:10CEB0004210BFAA9F5B77CB6F687F6787196C2092
+:10CEC00057F20E75F4807C245DC1E1B00F5B94E0F5
+:10CED000CF5268FD96239904F8F61A339909F8ADF4
+:10CEE000703CD7CA97164E375E90739E7FFE29F42A
+:10CEF000C1E850F7281BA5BD96F5B14326D7FFA280
+:10CF00009E4586A19E957BA0A7C50AE377F8DB4DD9
+:10CF100014BEE6D759FB302D8715805F4301D0E161
+:10CF2000FEBCF90827E56D23013C1DADF347A04C7D
+:10CF3000DE3113E0BF3B9FB9ADDE0BFCC73DC50B37
+:10CF40007CE8DF81DE29BC3A38DD6BD7AF18FC41C5
+:10CF5000D027B4EFD7027C713F03C7EBE83E8E7E4B
+:10CF6000D840D6D2CA1279767B21D0C51ACA7F6939
+:10CF7000ED6C9DB7E94752DFFE3C61AE8AD8C1EE49
+:10CF800058692241235DD73989042971E639DFAC1C
+:10CF900002FE934F6212C8D9FC66AAF0025E2DB35E
+:10CFA000906012BEE79E53B0FD13667FC4CEF9BFFA
+:10CFB00089F2013DFB2779C21120754EC6A3407F3F
+:10CFC000D13F69790FF80671D6F87BED8D22C05FED
+:10CFD0002AF7E9784FF1F5EB290CF563E97F56392B
+:10CFE000661CD3BFFD2F397C14933506FC52B1BEAD
+:10CFF0007604F98B4D3999DCCE1461F2863490C8F1
+:10D000003089C105CBDFB3613987F25FE358D4FBC8
+:10D01000C34698671AB33F88DFEF75BA815E08028E
+:10D0200039D744DA4DB41D623BA5B72CD26346BD57
+:10D03000F900F1023D5088D93F4841964500AE5B6A
+:10D04000A8884EA603F12CB2B17D5296EBD05E1AA1
+:10D05000F59219E7A36F261133E84330370A6F655D
+:10D06000198928606F2D3760BB229B17BF339066EC
+:10D07000D4679FFAF2DD6CE0D39683541FBB08F6A9
+:10D0800059463E65B1A8E98F62287E17E7F8B17569
+:10D09000A50DF7B9D73E0B1EE6FB1C6F017991BFBA
+:10D0A000CCA1DA5FD12EF75C0E098E4BEE3782FDF4
+:10D0B000E50E3D209152A8CFC7FAAD2BBD5FD37FBF
+:10D0C000D120FD67211E0DDE7F2ED66F8D1DB65F30
+:10D0D0004741B12571C01EF0F6E9D75A38E72E5303
+:10D0E000F3E58BBAD4650117B3DEEF9C46616EFEA3
+:10D0F000BEECDB4EFBBBF888BA5D6DE1EFD1BEED57
+:10D100006B1F735E0FEDA9FDBD9DBEBDF4B8BA7D6A
+:10D11000A0EA653BD0715F7B36BF2BCFA9DB69F7F7
+:10D12000473B5F3A2FD70D49F39A6832AAEA67D690
+:10D13000F59B97EBA6A4795DE551B70FB60C3CAF14
+:10D140006B4A8C5F392FD1EE3B9517D64EBB8EEBD9
+:10D150006B8D83C09DB5BF69E685F57B6BFD57B7C9
+:10D16000BB7DB9769C30F2875AC93FCE41EB67C38D
+:10D170002BD017AD16D47BB5F812E1F26902E87333
+:10D18000F43935D53FC1419F954077F46978FC0F5C
+:10D19000B7007F39F4F4C84CE0EB3920E7109ECC9F
+:10D1A000AFB0ABC1837E8500A7532A4FDA805FEC16
+:10D1B000DA49BF4B63F34AD69F321A985D6123095F
+:10D1C000A467A12F39884D62F638D377061B47DB59
+:10D1D000FFDDDC1E98B37C22799FD2E1B3065B951C
+:10D1E00002F6D93609F58139357E5D2AC58F09EDFC
+:10D1F00012FA8DE6DCF9BD71C0572E39E6ED8AD3FF
+:10D20000F77322761F0CDBD443FC118A5799BA2599
+:10D210006577D3E703FBA9FEC3CB4B00DFAC7E2FC2
+:10D22000D81B753023DACF497D73990DF8E677ADB9
+:10D230007EE09B7533FC6FE17AFF4EB512DA6E1E0D
+:10D240005B3A79AE739AC14BF58CBADBBC95A0F70B
+:10D25000D445CD7E7C9A8862A1EBA8A3FA183C3312
+:10D260000D4431C3D3424CF0AC58C5F4AFB4CA80BE
+:10D27000A18E8E5FD7FDD85FE1BB054A6C1FD32717
+:10D2800023B8EEBAEE57FF06FADA3C7FC000FC6224
+:10D29000D44E03D349393E8C8EAACBC00F92CB65B6
+:10D2A000317579DC2175F92D07C38B3D526414EC7F
+:10D2B000CF1E2AE0C02E0E3F654479B17FAF11F733
+:10D2C00067F1C796EDE07F9AB8D88A7CFDE39F9B13
+:10D2D000D11FB5478E3E0DE5F0D3296857EF7B7B14
+:10D2E0004F8544CB8B7E912A43FD0B5FEA10CEB075
+:10D2F0001C3D7DBFF8E911DBD7D2F78BC7452B6CFE
+:10D30000F4FDB32309E9817A253206D6F7EC3F74A0
+:10D31000D87FE27163E4218A0F1F3FFFD8D377D112
+:10D32000F13F7E3CC721D17DB914E4016D37E16145
+:10D330009305EC8C091F3F3904F8C5E29D46D5BA28
+:10D34000B63A24AE3778D300DF06F3271E5DF31814
+:10D350007E5F72FC08E2DB1E7D58B6C0FAD730FC57
+:10D36000D2B67FC4C1E48D98077C5748F7E7CC0953
+:10D37000CBED7E5A1EBE510DDF111175F949079391
+:10D38000EFB349D2FB42E8AF68B507F4D4ED04F53A
+:10D390009992E37FBCA510F46823D31FB4F3788679
+:10D3A000CFE3E73FA7FD30FEA063FA335D31A5C7A9
+:10D3B000C51C8F5F9098FE4AFF96E550BC5D0C82BD
+:10D3C000BFA8EFFD62CD3C44FF4B1C8C6F38B95DAC
+:10D3D0009D785D87FBF1D1CAFA71C786F59FCF07AB
+:10D3E0002B9B47D4E8FBCAF3372E399845BF6BD83F
+:10D3F000E5423B51BC6F78FC25F7ADF4FDC99D8A31
+:10D400000F54D7869B1FFDF10468F7B82E0AF385E9
+:10D410007AF0479E8CBE9C06EDE66FB18FD525ED68
+:10D42000C3828DDF1F5193C40FBF293D08FA6DE001
+:10D43000F6ED73953D937300BF374A3E68B6387A70
+:10D44000C3F5D782AEB245E71B46EB2B1412D08D45
+:10D4500045D37B063C1B763D73309BD687F68EAF5B
+:10D460008075AD9503D78C06FCDFA6473F96162E38
+:10D47000A7F97ED3EF6332FD7EED8DD6FA8815FBDA
+:10D480003D00E5FD250FE9E2E067394EF9137B7FAA
+:10D4900044A63479BCFB9E31E04FDCA3B7B6039EB3
+:10D4A000EF4965FB107E4A877C9EC4D83A2670BF40
+:10D4B000F1E23F751A14FA3C7E7C555A15A323E419
+:10D4C0002FC0949D747DF50F8F46BA5BB0514D27E8
+:10D4D000A29D98EFC288BA5E8B1F6919C2DF404ACD
+:10D4E00092F14CDB2E636AD80074D5B09CF2E32431
+:10D4F000FDA7E1588701F426ED38A00112B1AF3A3B
+:10D50000C44FE2C5F59AD97AA9CA6AA2EBFD08FE12
+:10D51000C5FCDE12D8E58B245C22593C92D47829D4
+:10D520003C174F27B5F0DC23C57EACE3FC0CFDEFC8
+:10D530004FA5203F3B698B3FFA53C0BF27F37C6167
+:10D540005A95CDFD7227BDB134077D9E01BA00FC0E
+:10D55000B3B1F2A26ECACF297D7F7CCA807CBD2583
+:10D56000FA521AECD7C9A7CDB24CF7E5E35D19D54D
+:10D57000E0CF3919FD4D1AACEBA3684635F8E50646
+:10D58000E3375A3E25E4F97BF0CF4B287FCEF08F6E
+:10D59000C900F8B66580324E32339ACB9A07A07F25
+:10D5A000F19DD3D05CE605BEF15DAB0FE8F3D20C84
+:10D5B0002FBEAF93587FF0E7A7F59F1ECA7808F6F5
+:10D5C000FFD0BEE27490F39F126F3AF0DF29AEC035
+:10D5D0001519948F78AA7BFC3AF0FF4D21BE56FABC
+:10D5E000CDFB3ADF0F6C14CE7309953BF02C0F1A6C
+:10D5F000D05FD2E6C279CD51484CA1783A07E4E237
+:10D60000182C239CE76C9122AD741E73D7A9D739CF
+:10D61000BFD3D8B7BFF4BF8584324620A02D49EDD3
+:10D6200068FF0B41FE51F82D3291580AED77D12356
+:10D63000EAEF169318CEA7E1C9F3C681E0F8570EBA
+:10D64000C7292EFF4D192AFEA547FEB59804AE80C6
+:10D65000711773393BCFB80FE711BAF3CE1173A925
+:10D66000DE7066F95D23E666801F907D47364A8846
+:10D670007F8B6B482C8FCE6B71B7141B0D7AC061FA
+:10D68000B63FA27FB28DB5BB85EB29F3283C40EEB7
+:10D690004F78520AA7523B669E899A60C03FF8BAFB
+:10D6A000A03E9D96EB4907AEA791C4711EDFE3FB38
+:10D6B00007112980E75F0FB37D9B50BF5D07933A49
+:10D6C000B4AF221DF0EF33E2C3FDA3FA04313BFAFD
+:10D6D000E307C0DB9F049FFA2DEA327924A95C049A
+:10D6E000F0A4E5243837ED3E6FF40F00DF077AE54C
+:10D6F0004964C4B4D1A49FBEFA2E87FF0337CCCFB0
+:10D7000002FABF1FF4B76CDE4125F04B22FC113149
+:10D7100013EDDF328EA8FC13542FC272C74F5EB9CF
+:10D720007A632E211BF441F4F3CFD1050E4248EA6F
+:10D73000842BD809F83A47F6E72BC807FCC568A739
+:10D740002E67FBF1E0D8E611CD03D8A762FE1BA43B
+:10D75000684C067EF03C93EFA9E5097D3089BE9EBA
+:10D76000E6FC2D7D7FFC600EE0CD3312FAD3374905
+:10D77000A44DA270F6D06D0139B0497AEF20C88D62
+:10D780004D577B492BAD2FDF3D6DC9CB68E35A7CEC
+:10D79000109F68DC5DA56BB4E2FA999E99D2BC5DDE
+:10D7A000A6F599B7978C05FAA0EBBE7D3A7DFF2BC5
+:10D7B000BEDF5956860F9E55E1C2A5E04FDD1F58CA
+:10D7C000F232D0F5680BFAAD3229AC521DF86C0775
+:10D7D000FDD1435A2468F7401AEBDF25EB6E9F0614
+:10D7E000E5B1ACEC5821F91F42245E8FFD671AA900
+:10D7F000C9E060EF410FA6DDF977617D04F72D7375
+:10D80000627319F49739843D9D86582EF4F39AD8A3
+:10D81000EFEE2C19F8ED322E3797EDAACA74D0EF3F
+:10D820005F3B6952800FBEE6117A5CCC0A7A1C1904
+:10D830005AC2DA73F9B4AC6C6226E0AF335FDDEE46
+:10D840008CDE9F3E0EF8FC1B3A8CB7FCC5EA4FB746
+:10D85000D376971AD83AB4FBF8A70CA6D785CE4949
+:10D86000249264B787669E45FD38744E51BD3FB91A
+:10D87000D2442249767B43FDFEC9D0AE91F4AC067A
+:10D88000BC6A8CA69048129E5F6A19785C81DFA101
+:10D89000733A121E87E89B0BFEC5D7F489D5F300B7
+:10D8A0009FF64AE8070A517B389C3CAF7319249CC9
+:10D8B00031D03CDDEAF7743DAA72D7E7D88E54C662
+:10D8C000D3609CD3B6789A9DAF0FDA09B97526223A
+:10D8D00087F517617C8FC92FF0CF58997E3A0DF6E6
+:10D8E0005749A44D4FEDEB57D4437F8EA4759E9EB0
+:10D8F000692031DC97048E0B700B0F276473F727B8
+:10D90000062FC8F1EE7D0837812FC9F00B27C77BA2
+:10D910005A7B6232A5F9CC4ECBDAD21114F5F673EC
+:10D92000FA0E5BD7827FD1AD9355F49E52DE4BFF4A
+:10D93000C86E1E80E813FA2F53D7429CB9B7CCDBD0
+:10D94000F77E1F4E9B02F5E5A5ECFBC2CEF4FF5817
+:10D950000532887430BD5F49E4075293CA264DD919
+:10D960004ACBA393CA364DBD5353EFD1947359FBA1
+:10D9700093A9B17C9D8FDAB99D195314CA7F4E6665
+:10D98000C566514B94ACD3B9A7D4D072633993AB6D
+:10D990004DDD920F7D6E1C7E4D3EA6EF597D71C30D
+:10D9A0009C528043CF41E00F0D5D924DA274608D7B
+:10D9B000EE8A6119BEF3267D1795F0BB86E87BF8E9
+:10D9C000DDA0FD97C848E76B4B8EB276D10F517E34
+:10D9D000AF6EABC3B8B888FBEA48C09F23F5C57DDE
+:10D9E000059F3C9DE57F4966786D4BB68342D06FBD
+:10D9F00092BF45B47F6774F7EF413D4859F6490B34
+:10DA0000E8A17F6AFC703CE865EF7079B0418A8CD0
+:10DA100080713793E0089077DF6D1CB64FA6EDDE7E
+:10DA2000D5C7B7426C6B71E7A8290A6DF76E6A3CDF
+:10DA30004FA23CA6D15981F07CD715DF0AF07CC9F2
+:10DA400079312BE7C5F3645A5ED259C7DA0F8B6F71
+:10DA500085F226E7B5AC3C3A9EA7B38189731DC217
+:10DA60007F876D607A9EED647C44CCAFABC8FF5D70
+:10DA700027ACA781C991AD546F34517E396BD14722
+:10DA80004FEDA07098F5C314E4633B4E5E3F85E90B
+:10DA9000D5E18052017E53F687720EF9B5827A463F
+:10DAA00016C83647DF7EA4E6F778510E8C6CDE058B
+:10DAB000FA42E6AC529403A519FE0330AE78CECB01
+:10DAC000A64F0ACF034E1BE3CB3A19E3C89977A5BB
+:10DAD000A25E75BF99AD87D20DEEAF95EFC71D4E13
+:10DAE00026B7EE7032BBED868C49D8CFDB927F93A0
+:10DAF00089C2FD6D3D099B81CF2EB4A01E7CEB76C3
+:10DB0000CA3728DFEEE4F3EE5C9F158138F8AD12DA
+:10DB100009005F11FCA3D3EECF7224D9139D65B425
+:10DB20006CEDB31F3BA7F9B32C4E78BA6588970804
+:10DB3000BED459C8BE13F228B3958D9379FF888758
+:10DB4000601D290AF3FBCC9B59FC500BCAF5E9B8C0
+:10DB50007EE2F76781FFE0D8C22219FC41627FDED6
+:10DB60002AF2AF87F5DCC2FDE9629FC47E1E7032E7
+:10DB70007B788E8EEA0574BDFB5C415C3FD513C695
+:10DB800070BF13EA0907404627C19728F1F1F0FE5C
+:10DB9000FF23383DFB6DC0A97139E517F205F00B85
+:10DBA0000EBF0D524C9FC9F805DAC1F01EE4CEA697
+:10DBB0008CE07F3893F25266DDD5887AA19857CAF7
+:10DBC0001DCFD5DE44FAD399566F3B0CFBE5EAD363
+:10DBD0002F7DC27FC8C779F76D13C60BDE35449120
+:10DBE0006FBE4BED9816E02F3CDE5DF1C3C5AF81F3
+:10DBF0001D27FA9DE0D2617F6B247F16AC6F0DDD8F
+:10DC00007713CC7F9A01F57821573BED914D906FBA
+:10DC1000D079432EE61B9C212CAF23BC3C05DB5D59
+:10DC20002A1F25E08F4C5C62C37833C513ACEFBC70
+:10DC3000B918F33E283E84CD504FF109F2E33ACBB8
+:10DC4000E882A0BF9B47623DD8B9689FDE6CC2FEE8
+:10DC500006C013E6DF1DCEF21A3A0B391E2E2C42F7
+:10DC60003C74B7323F2251FC63A625C979B78BF1CA
+:10DC70008194F2F833FF0538BFCE8C7A29C8588CCE
+:10DC8000C57464627F74FFCF3B597C0BF16CEE8FDF
+:10DC900053791E99AF02E07A6F2AC3CB2D661627FF
+:10DCA000DA42F560E48B1C7F45FE5A90EB79F17AFD
+:10DCB000390DF4855457AF9FC00F763BFAA969FD23
+:10DCC000ECB8F41ED85DB3C3BA9811ECA8F649FEBF
+:10DCD00078921D027F1067BB9DF355B291A0FFEEB5
+:10DCE00076F82E0DFAB7A4415CF176F81EFCA42B51
+:10DCF00026A9E2670530E6F8BEF969F97E819857F2
+:10DD0000C783FEE47144FFDAFEA81DE975B910CEA1
+:10DD1000B174B0075A74B88FDA79C637327F737C22
+:10DD20006301E29DE86FB079FE5997F8BE44E5E0E3
+:10DD3000FC89CCBE16F6CB3C6EFF92156AFB0CFC40
+:10DD400023BD655DFFB2D6DE83B8B8BA3DD35B5262
+:10DD50004A13068C977825D5FC05BC0683C3E46F6F
+:10DD6000083721F71E34537EEA00335A42BCDD786F
+:10DD7000670ACA31A7213202F06A9ACB8BFD6E8600
+:10DD8000FC1494ABCCEEFDEC35E1AF50DBBB214B8A
+:10DD9000621BC02B646174747A6F2AD201191A9FB6
+:10DDA00005F95D67F61809E06F93142F06BA3E2D4A
+:10DDB000F9EBB05D4B8A17E8E97DB907E11D020870
+:10DDC000D27985C2FF837945A12EB5FD7B9AFE5796
+:10DDD0004FF1FDB41CAF807E043F00FA47BDA89E02
+:10DDE000C55B9A641206BBEA5279F64294FF376724
+:10DDF0009387F0FD7BC56047093E4FDB1D901C0CEF
+:10DE00006D805E1A38FC9AE4A3D8AE01F283008ECE
+:10DE1000605F815F0B2A93FCB14DEB3EC6FCA4A66C
+:10DE2000DDEA7D6EE8C303E9BC04DF25E105D271BC
+:10DE300098F301C2FC14352C5E9CCACB29B53D98E1
+:10DE4000AF14E27E0BD7FEF864E027A9E551329BC0
+:10DE50003E43C7999E31A17BFB4B600FDB6B7BF28E
+:10DE600000FD43DCAF27F659CCF392EEF5E8A7109E
+:10DE7000FA49929D3962BACA5FB00ABF03BB15C6A0
+:10DE80008BC3AB2CD87E26D73670B946E51FF2D7A8
+:10DE9000791DC351FE817C02BE24EC5EE053C01F9D
+:10DEA0004EB8AAB7009DB6B8AB1F74B9D878A8CF42
+:10DEB00083B174C9E0FE38011FD10EECDFAFF2B7B9
+:10DEC0003DC6F1D569E07C9730FFDAD2575DC2BF1D
+:10DED0008671B4A5923713F0F5035D10FD680B4809
+:10DEE00018FD3B0BC17F459F0D9CCEE773BFD07CD7
+:10DEF000EE0F02FF6C72BC0FFCA4C9E54584E12F54
+:10DF0000D969ECCB8301FF4D0D89A5D2FE1AC1BFA3
+:10DF100004CFA8FABB26926078DF75DEA88A277640
+:10DF2000B275DFCEF7DF5E13D1017FD864667E2540
+:10DF3000C13726AC60FEA7F4B1FEC27B00CF5FD52F
+:10DF4000A35FE2BFF9BE09384D71556F77D1F61660
+:10DF5000B0D3A0DD3D46E497C7A81CDEC5FD21D3A4
+:10DF6000C1FE5C191C0179DC44B1E527DBA7E2B9ED
+:10DF7000768FB91EF0E74D97ACC2AFD52E9677835A
+:10DF80007E22E4C729A86F53B63106F0ABA248C879
+:10DF9000433206FC53EFE9993FB7E9466B10FA8B21
+:10DFA000CB8CCFFC99F3B33FBB58DEE59F7BE515E7
+:10DFB000B7EF38FE88381DF86B92FDE41FF4B65FAA
+:10DFC000CFF36309AE77C3429E87DD8BC732F2A3DE
+:10DFD00094D200F2DD4BE56AE4478913562FC0A5C1
+:10DFE000F6E38685B08E4F675A08C4CBE672BFED64
+:10DFF0005948B873F5F969BF2E8E55BB7604F249BE
+:10E00000D1FE6F3027577F7FEF1ECEC7F61036DF69
+:10E01000709B91F9D7F9FCF71C1F19013CA67A6D8A
+:10E0200018F85C629799C93BAA87027FDDB37B78B9
+:10E0300004D6F39E9EE90B61CA7FD9F7C14DE00774
+:10E04000D9F34B970FF273428B3E1A03FAE39EE328
+:10E050003FFFD56FE1FD5EA30FECBD3DDCBFDE6091
+:10E060008815A3BECCF3121BD262C5E0F77981EF0D
+:10E07000578385964B4179083ADCAEBE38187C0749
+:10E08000EF8F46985E7E94303C08AF63F14A0ADF1A
+:10E090002C9847624D26C6D1605DB00FEFEF1D8D05
+:10E0A000F3DEA0E7EDEF63FADB515E3EFA7C19E6A2
+:10E0B000E99D091830AF36743FD317E7C8DE6DCB42
+:10E0C0008157BE9882FEC2799D6F605C23F4E305A0
+:10E0D00053A13EB468C575E42BFCFD205792FDD4D6
+:10E0E000A749221FEDE0FAA2688C8E7BBA7B848F51
+:10E0F00085ED3C18246AE2F99BC7287C61DE89BD66
+:10E100007A84FF85F60FEB05BB14E41BFAB593E3A5
+:10E110002A280FD47196AF2B9FD6C78BEFA4E3AFFD
+:10E1200070046BDC497A62E8C52CE477EFDFF7799D
+:10E130003EEA131D2C2E704CEF9F057462AF8919B7
+:10E140006627E95FB7B9B9DD61E47A23E583C9746D
+:10E150002FEA2BAAD574269EB7BA19BDA5F2387E30
+:10E16000FF7A91BF7ABD11E427732941BF5EECB7F6
+:10E1700080C7D7261C4FEC837CA8866819C6EF0A97
+:10E1800056C4902E29BC63A0FF1FDB94CAF8095D1A
+:10E1900026F433BF92A0DE3A5FC7F212E61BA91E37
+:10E1A000CCE438B6FF605326C2A16215D3FF12CF6C
+:10E1B00048C817459CB18EB0EF9F6B7B2FACA3ED89
+:10E1C000EB764A6594B592BAB62ACC5B58B4A510E2
+:10E1D000F77F02E7BF738CFEE24D806FCFA522BEB2
+:10E1E000D1F150DF6E80DCACB1C8970C200FEB771B
+:10E1F0004A642D498E8B6AF020A28EAB4C8832FE89
+:10E200000D728324E969420E81BC201AFD518D17DD
+:10E210006195DC6BE77015FC1F21F6157290EAD151
+:10E220006B808E2BAA19BD25764908E746D2CCE231
+:10E23000405C0EF5CE87CBB10F744C6ECE37AEC7B7
+:10E24000E73677218EBB08E225E8FF4F18802F0EB6
+:10E250008617DB06C10B810F3FE3EB68384E6297F0
+:10E26000D3F11A569058E318F64C1D837299C9677A
+:10E270001393CFF0B45C809CD6CA67AD3CD6CAE19C
+:10E280004C0393B7020F92FDF2A08F4C5811D1317D
+:10E29000FF6BAE0DF2F1C4BEDC90E17F227B7C9F70
+:10E2A000BE153A6232792F8272801459C1AF54552B
+:10E2B000914BD71FA2FC1BE82E85C2693B7DBF9501
+:10E2C000EBE54372BD081F0FCFBBD12B0152668512
+:10E2D0007DEA413B3AE12268D70AF86E4DA5DF8D11
+:10E2E00085EF183DF67E6F226D96A4EFABF798513F
+:10E2F0009E9C7D3E15F344A87C28B0D3FEDCEF50F5
+:10E30000FD9C964FEF4945F97E9AF37BA7F0579015
+:10E31000D5D8DF9BB0CF2EC0BAEA1CF0FB12694AF9
+:10E320000EB048A13736DA07F3D3F3FAC29E1B19B1
+:10E330009E1951CE9EB5C77F00653A1FCCEBFD0FED
+:10E34000BEEFA1DD13CBEE82787EC0EA63500D965E
+:10E3500081DE60D42DBB11FC4193752B1277D275F1
+:10E3600034E659315FB8A6E08F7FB899964FECD666
+:10E370001323ECFB8EEBD363F099E2F70C249F1789
+:10E3800046F4AAF3688B77AACB8D5175394492CEA7
+:10E39000AB51102CFF63D9150792F0E43377AA1321
+:10E3A000F7DF4B7C90EF4C74B7A50707E097E2F9D5
+:10E3B000F94ADF1507F4982FF6851BE9C06B00BDFD
+:10E3C0006636E0C300DFED7233BFA8D1D87C1CF203
+:10E3D000CE8D2F187D2DF4AB83EEA02ED305F64AFB
+:10E3E000E220ECA7B1E0E4189083D5057FC738D8C8
+:10E3F000D9BB890FE073D65C85FACDD94D662FD88D
+:10E40000659DF956E6AF78518A484C7F9F3ABE0227
+:10E41000E29EB80612DA78F5097648829864DC5FE5
+:10E420006ABD7880CFF8D19EFA609AC5B68A7E57C9
+:10E43000BF91C9DB06D293067CA03693E15D48F715
+:10E44000A4C144FF59D8E61FD142E7BB3860C1F3ED
+:10E4500031CA974A00F0EB5EE83249FF2FC8647278
+:10E46000A6D1143754C1F87F9F5BEB2AEAF36F19EA
+:10E47000F4CCBFA57495C572E8A70B96CF413BA716
+:10E48000378EBC89E5252DB8B30EDFBFB4C988EB44
+:10E49000FB60AF8478FEC156B6FE051BCD5EC89FFB
+:10E4A000BED2CEECD905F4BB81D77FD50958D7872A
+:10E4B0005BEEF0817FFE43C2C609DB981FEA431B77
+:10E4C0008B77435BE8E7C3DD43508FA9DFB8702A41
+:10E4D000E68B6DD5F9408F207B53D1BFB360EBF74E
+:10E4E0007F7B09F88FA6DF520E70B8D2BECC0DFE2E
+:10E4F00012DA2E10617A31CBC375543E0A7478E576
+:10E5000097137BAE047D692BA5934296E70E7AFAAA
+:10E5100081AD57A15EBA609AC50EEBF26ED9311982
+:10E52000E4C787D3B2655CCF5312B1011CECCBDDDD
+:10E53000F07E81A40406C2A777DDCCCF565560F5E6
+:10E54000C5E0BBDFEB104F285DDD08F2B371AB1EF9
+:10E55000F5DE03D3DFFEC3CDCE3EBA5AA0EBB871D1
+:10E560004292DE13DA72ADC01312AB007B8AC14453
+:10E570004B5FC68215C5301F2D9D2D58D55CCCE252
+:10E5800055DF8CDEC8164A6FA3A8BCCE94985FE313
+:10E59000C2E9AD3EF31BD01BC975A8ECA8FE7C2DCB
+:10E5A0008C7014FE7E938FF8775831AEEB9728DF8E
+:10E5B0005D9FA9603FEB33D9B920E56F4B77BE4E25
+:10E5C000E1E3CE0CFE3013F41FE22F033CF2266C85
+:10E5D000D570E6C7CAF538B285E9CDA0DFC37E6F36
+:10E5E000709147D726F91DEECB64F611A5FF56E8CA
+:10E5F000E7F45B7F3F08FBD3947F720C8B77FE05BB
+:10E60000E383D66E1657B6FA121837D73B03887FC6
+:10E6100082AF877C4CEE68D7753893D97321670237
+:10E62000FBF98587D1A1F0B76F5E6E413FE9666760
+:10E63000C4CCFC0A610272696AA58EC5C5B89E7514
+:10E640002DF73F9ACA5F22100F2397B1FCADD7CBAD
+:10E650005F523268F9B795937C786EAEFCE1F62292
+:10E6600058F7657A5E3F240CEBFE4F7F15D62FF5E9
+:10E67000E8BC40D753CB591E22A94F437FC9EBE5D5
+:10E68000EF3BE726CD3F404C5E2BC593E9D4C8490C
+:10E69000CE9BBBEE32B3D79A845F9F7648B54CDFF2
+:10E6A000F5A6CF18CDFC212887CBD5F058EA31E06C
+:10E6B000B82DEEAAA701CE575EC1F6E3A3A78C1131
+:10E6C000E07F1FF173285AF8EDCDE476E86D25AAB6
+:10E6D000F8BCD310CD07F9F8B1A4FE6E51BB0EE320
+:10E6E000E30BDB2512A1E37DF4F873F9C0C74FEC0F
+:10E6F000782E7F76D27CB4DF89E72B991C5FB91F17
+:10E7000050EBD71DCC9F2BDA9DD94882A6217DEDF9
+:10E71000CFD47F81FEDCD9DDDC1FECF70F75821DC5
+:10E72000C4DB6BFB4B70FC90BA24F477087FE6D116
+:10E73000430F43E4A477FFCCDD857272DEA1784EEF
+:10E74000E0FB763DEC1B5D8AB99D9507DBAFC1E828
+:10E75000711DC89FF17DFB76B47D483AC0D1D0646D
+:10E7600055083B0F56027AFA5662F1013D19B23D47
+:10E7700056E05FCB4D6963E09CCFE766F6745AE8DC
+:10E7800093EA6B79D925F8DD1D7200F3DB3E973BE8
+:10E79000F03CE01DBA66CC9BFE8CCBBB5C5B60D7CB
+:10E7A0007CB44FA298474DDAD5F075B732F991A8ED
+:10E7B00033A09C1270BE74F60FD04E1D607F3602DF
+:10E7C000DE6457B277A59E42AE2FC7314E60AE24AD
+:10E7D00036B0E75B2F09E37CC4FE84587322754B87
+:10E7E000A827437E4A8A03E3A161FE245607E98DE8
+:10E7F0000FA470BB9668E201946D85A19D9827B027
+:10E8000031C873B9DF1EED282EC7782AEA9FD02FB2
+:10E81000BC9F5DAAA03F1DDA19C67E3DBEF5E2256C
+:10E82000CF179C2ADED75B068C3F4C857337B47DAF
+:10E830001E9583A0FF119F5E75EE660BD59BC11ED2
+:10E8400013F15D9D1C2DF3A01DD21307FF88A1C2FB
+:10E85000E405B99AA28B96C0BE69E3BDB45D21CB35
+:10E8600033C8B5835C11E76A9A964F0C40DE7AAFE5
+:10E870009EB197D9474D7756E1FB89DDCC7F1E6A63
+:10E8800037E2B9C0509784F1AAA6802162423F8640
+:10E89000B705F62B4CF530B01B3BED2CCFA9F36A36
+:10E8A0009B2F4C92FDD7F16D77A1FFDA8A71BA7F69
+:10E8B000367E79269502E0A2A4F854BA89C911EEF1
+:10E8C000DF76737C12FB2FE859C43B534B0385A0C2
+:10E8D00071EF76DFFE1BCBF86F901742C6DEF7951F
+:10E8E000792164EFB570AECD04DA3CAF876951B9D8
+:10E8F000D97B4ECEECC5B8566F3DDC6F60EA92F81E
+:10E90000F78BAE9DA4601E282F57AE83BCEEFBCDC7
+:10E9100044355EF2FC144DFF7ADABFD5CBDB876F4E
+:10E92000BE66D2508CEFF272D78FFC747EF7EBD5B7
+:10E93000FD210A8A737DA6BEF12A72E4FBD65DD65C
+:10E9400027BFA93C5FE671F5C9F17BDF9EDA7191C3
+:10E9500017E8EB33CCAB15F238E46479225ABEB534
+:10E96000D22309FD773288D8D533EBF03E80DEF82C
+:10E970006EF7343FDC8B20E2BBA11501CCAF05F96B
+:10E98000EF41F97FF2837D04F4CB8F50FF0F9D534D
+:10E99000983F88EA1112C543537715FA3D216D144B
+:10E9A000E4A6D8FF455C2E81AE0EF81DDA72D30EB8
+:10E9B0001DAD7FC7E35F87FD723B503BDF1D1E66C9
+:10E9C000BF874AAA37013F208F4804E4F6DA924F06
+:10E9D00051CF687A7ED2F8E4FCF0855D0FB0FCE29E
+:10E9E0009DFA01D7BFC3A363F931CF3F83FECC8F1C
+:10E9F00022EC584ABD12593301FC2AF532685AA458
+:10EA00003C527733CAFF99741D745D3FE27227B49C
+:10EA1000F3FA30E4AB87E87F00B2CD81F9A8EF6F5D
+:10EA20009E69B242BC2654327B09D283CDE287F57F
+:10EA30006BE7D91B1FBED382FEC6B55DFA5AD09BC9
+:10EA40002AA89EF42B3ADF3CC7945A1FE54B39BAEB
+:10EA50005D65DFB3425C7D60395C9DCDF6B14D0AEA
+:10EA600084BF538EF98C24394FA7A08BE963DD1E38
+:10EA700083EA5E886E0FD3132F0BF74C049C7B51F7
+:10EA800089A7805E1C22FE4FC0CE2501AB17FA81FC
+:10EA90001B1540CF72AEF4A23FD7E48CFFE822D41E
+:10EAA0009B14B433841D71FA79E6FF1A9E157C1508
+:10EAB000F0B24217FFC977006E3F62E77589C2F86E
+:10EAC0004DFEF5D6B1E0AF323BE33FA9F5627E0DD6
+:10EAD000FA1FD22F6FC37D78D1496C009F89E13A2C
+:10EAE000454A9233826F4CEC3D17E3443F693567EA
+:10EAF0002FC3E86E7D6042146D3B9FD1A7171CFAAF
+:10EB0000FB0C055E0A7D413605D19EA99949ED436E
+:10EB1000C0CBD5898332F8E59D3DA82F3646251C0C
+:10EB2000A7B1E49798FFB698E759F5E63B2971CC71
+:10EB3000FF7ADF93C2E3036D4C6F253D68FF922798
+:10EB400019FCA9DCC4BCB03EBDBD05DB89FE0C3C94
+:10EB50009ED0C8FD351450587FDA23E209AB78FF08
+:10EB6000228F8D8D4B146F45B27F61C3342A49705B
+:10EB70005EDE3498EF13E6C0E7404747EB65E6CF2B
+:10EB80006E4F89C021CF0D528F1FFC8EE1B281CF15
+:10EB9000B358B3181EA5EF4F4C467FFFF383E5BB78
+:10EBA000B2FCD64DE347627E7879D72793013F4880
+:10EBB0002D417AA4FCE282F25DED595E1CEF5BCF41
+:10EBC00077F549FE87E83327CBAECE77F531B88BA2
+:10EBD00038A436CFF574564C617969F16D3B407EAF
+:10EBE000761931DF6D6AD72B47C00F39D544A2188B
+:10EBF00097D5E8012F665C3F348BAEE3CCA90FB606
+:10EC0000DD4320DFF9591FCB9F53CBF5C1F4788C3E
+:10EC10004D24D97B157C1FBE2D3D5EF0DD10B78BDA
+:10EC20003E96123F2E86F5EDD5D9063AA732314BE6
+:10EC3000E0DF20F91ADD03E76B887350B5F1425528
+:10EC40009CE95AB19E6F18B70A802F7980B895C297
+:10EC5000F3B01489B100926750C5AD147BF16071B7
+:10EC6000AB18D63F331CEBEFED17B762F9016D7BA4
+:10EC700033BDA0A737B8128F3EEA85FE0CD84FDB14
+:10EC8000F32911C83B6FE3F06FB8F0B8D5C2AC01FF
+:10EC9000E256DBB91EF67E891C3350B86E276CFE37
+:10ECA000E16E11BF92D11E4DDC9727E68FF567EE1E
+:10ECB0001B857E9F39222EF522F387CDE1F1A7F740
+:10ECC000A71763BED660709ED3AEF6EFDFC5E17CBA
+:10ECD000D65C857EF51FFCFB34F433CD077FFC90BA
+:10ECE000BE730984FBE5BCEDECBCB977A714F1B2A7
+:10ECF000F88849461DCF26C3FBC5941D6E06161A1B
+:10ED0000A65873317D2D51A8D17A6F1B2D53E55D27
+:10ED100059A3843DB4DDF62329E807BBD7E9C5F93B
+:10ED2000DEDBC6E2C4E175526418EB17EFF10AB7F7
+:10ED3000C97EE8E7A7594C5EFF2A8BF921BC9AFBF4
+:10ED400001DAF43CDECBC76B21720C9EB2C49EF795
+:10ED5000DA94DA81F400D15F9BBED95405F0CE631A
+:10ED6000F7859C35F867A29FD8518CF702B5A53678
+:10ED7000B7D7B27AA4D9B3E64400EB2F57986249CB
+:10ED8000BC0E98EFFA2CA6A768E13CAF435DD6C64F
+:10ED900069B4E7A0E690E0F0AC21FDCF09ADCF6209
+:10EDA00072ECECDA42BE2F3E8C7BB4E9BD6F1602EA
+:10EDB000BEAF61F7FEB4E432B8C979EC5964AFC1B3
+:10EDC000FBD9889DEB6384CDBFE872A704F4D066BD
+:10EDD0006778FBAFCE5B3BDF17B28A197CED8C5EA8
+:10EDE000DBD64811062F36EF0BF56FBC25F8D2B7EE
+:10EDF000C417DF977C8FC60AF13BE40BE1FBF448B4
+:10EE00007747492487E53FDA906FCEE6F6EA512E40
+:10EE1000AF36D717A5413C73CEF1D5787FCFC4EB81
+:10EE2000AD38FFA617CD688F35AE88E7033E6BE19E
+:10EE300008B355043F9521EF98B07B5FDAD5F139DF
+:10EE40006DDC7585239000F9D2541D2F86F8CF0311
+:10EE5000F2FBBB5E617C0DE563D38AC4A3E02F0E99
+:10EE600038829F43BB9377BE3D59F2E2E7C8DFCEBD
+:10EE7000EC1D8EE7FD66B7A9CF4F9175EAF81F69C3
+:10EE800077B073629DEAF7705E48F55DBF7820D376
+:10EE90004F36188223407FBCF20A96EF706AA14C6D
+:10EEA000603F4F99098FB30B3EEB2B4E9603CEEC90
+:10EEB000C1E41D6D0770E6F99DA27D23EC2BDDCF2B
+:10EEC00006BEAFA79EB9B818F6F5E4AE8B8B615FAE
+:10EED00037E83BFC4017275C414F36C597639302E8
+:10EEE000A8DF897CD60BC5B7E183CEEB7F470E97B1
+:10EEF00067FF737218FE92FD1E2FFE9DE59D86BB77
+:10EF0000D979D13E7FDB4778EFD59973B2047C780D
+:10EF1000B0FE5EF730BCF7984818FC1C15D571FCA4
+:10EF2000AEE20B99803E27F458EDFCAFE2F09B99DE
+:10EF3000EDFF15E8A3C23F5BCFFB36453E63FAF217
+:10EF40002312FA5F4DDE70DA04B48FE68DD3215FB1
+:10EF5000F9159E6720DD920DEC8C858FB460FDE97C
+:10EF6000AE39582F9B6231B0A71A693D94575FA6FE
+:10EF7000CE4FD6EF2E8B25DBAF741EBF00BB24C552
+:10EF80009930007E36817E4CA7D8A4303F7593938C
+:10EF9000A07FA4BC4B6DEF89F8EBE600BB5765730F
+:10EFA000B784F72BB90DC1C25CD8574D1C765EB63D
+:10EFB000BF0DF04EC4C3A7B8FC0BB259BC3C1FE058
+:10EFC000D494CDE617D78BF373EAF37D87F6DD880B
+:10EFD0007AD05F49207DE0BCB1882A4E3E9F9FBF1A
+:10EFE0009CCFCF5F027F8E69F87372B921296F2C95
+:10EFF0003650FC3F296F2CF9BBE4BCB1988AAF7541
+:10F00000F0F3094B313E1DA278BE7C6C1F1E3610FA
+:10F01000FEB731F13E9E4FD96944BF5803CF170D5B
+:10F02000D51F457B2304E75D183DB2BC6A7EEF40E7
+:10F0300003B5E3306F36AACE2BFD69F6B72B0F442C
+:10F04000BBC1FCDD8F0A7EC0E951AC4BACA3A15B18
+:10F0500062F4A399A7D67ED5FAAD85FD79A17C6926
+:10F06000CFB7BCEE6FCA975EF996F8523FFFFFD05C
+:10F07000449AEF5BF0FF9FF076B8C125D82E317C23
+:10F080009DACB3FA597C51C7F20FB47157EF648C41
+:10F09000270A7FABE9595D645521B6C7786AE3DE7C
+:10F0A00054CC07A8F7D6A39EAD8D332E22BB26C322
+:10F0B00016FC95BC86E7AAFED5B8FEE9ECDEB87E64
+:10F0C000E1378CEBFF35FB1BC4195FB27E96114C08
+:10F0D000C293EA52AAB0970E9E77A5CB61FB9EC25F
+:10F0E000F33F4C4A98D893BE1FECBB941C16677F25
+:10F0F00089E70BDD9F9A82E7E83D06768EC023B351
+:10F10000BCA677A8B69FE30239C0F6F167CFDF440B
+:10F11000204FF067FA289E6B0F375A7D20BF84BFBF
+:10F1200048F4DFCCFD98174A3F4539FFBB7CA33438
+:10F1300047FA6671B28D14064974A5A583C1BE1B3A
+:10F140008CAF5C9E13A8CC41BEE51F83F1860BE417
+:10F150004729E5945F837CDE6DF482BD60E2E75D64
+:10F16000C8BA2C95BD3DE7FE3C945BA7CCCC7E1085
+:10F17000E772C4FA0383C2FB9FD3EFF6B902D3014F
+:10F180004F8E55F931AFFFDE542657128FB3FC1E58
+:10F19000EDF914AD3C11E72BC47873C5FEFC1FF1EB
+:10F1A000D325023EFF223FA5F215FD2B83C653FB5C
+:10F1B0007D1F66F79154F7F8799C09CF2B887985E4
+:10F1C0007A585E5C0B9F5F2FBC38FF3F98E35F056A
+:10F1D000FB70F22D9309E297E5E58C7F3605ACE8EC
+:10F1E000FF6F8AB27C98A61504ED7C710ED59D192F
+:10F1F0005C07F878EFDB56BC07B4A96B7B7B11E6A4
+:10F20000090451AF3BFD167B7FD01DEC80FE432BE4
+:10F21000E2AA3843C5F9CF56D796E37CD14E771A88
+:10F22000D5E77B7E99C3EC6FF1FC452F7CA95D424D
+:10F23000BF3B59CFF2B0434EBFAD0AF303981F3B1B
+:10F24000C5DB83FEE7A6DD282408268542FD5DB9DF
+:10F2500088374DBBABCAF05C7FD45C86F7C1BC631A
+:10F2600045FBEAE49DD9111DF37B3F06EB4A2D8F48
+:10F270005C0DFA65011D07FCD827775D5D86FE40B1
+:10F280000DDD097AEB3DD779AB29D22AF5D1E3061A
+:10F290003D938F42AE3D08CA2CE647F0FCBEEE69B6
+:10F2A000649EB5AF6C75AAF31E67664F7A10E6F3DD
+:10F2B000608EC2E3D32C1E5E68A2D667517F3C2CC1
+:10F2C000E4F1F0693C8F81844D7DF90B455F1F0FA0
+:10F2D00017F31365110F4F39C7F4DB229B01F1229D
+:10F2E000B59DF10D42F102F4EBCB123D13E13CD59B
+:10F2F000D0CED86500AF74003FE691C67F7411C4CC
+:10F300001D3294CB20EEB06DF9D8FD2627F88F7A08
+:10F310002E87ADF176D8AAC1B47467060E039E108D
+:10F32000A5B904F0BFFAF77A966FB82605E57D67B0
+:10F330007E03E61B9E7EDBA83A47A37D86C92A0F83
+:10F34000F8898ADA7F877EFFD4DDD28079A419A07C
+:10F35000F48F67EDC1EF94DADE13AE043FCA7D127D
+:10F36000BB4B91CE5EF280FDAFC8A077CCE962E7DF
+:10F37000B1E774D8AB4DC84F251637B9CC897C524C
+:10F3800059738D0CF699D242F0DE324B2EF35B0F9F
+:10F39000EBB4C9B0EFBFFE5237603CEC6F1CBF212D
+:10F3A0007F0DC0D5684C1C8490BD88E389BCB5C175
+:10F3B000EE0317F248ABC7F6D35FB93CEAD5E335A5
+:10F3C000783CD87702BF053EFF5A4F500FFBB5641B
+:10F3D000C2735A02AFDB441EFE97CC8F5BC0F36250
+:10F3E0008EAEFD9F31EC3E3F110789B07B25F5F1D4
+:10F3F000D53908AFF8156158F76EBBDC548AFEAFFB
+:10F4000026EC670DBB7FACA07DC8AACA7278DA086B
+:10F4100080E0E89EC5054097618A07C306C0832344
+:10F42000392CFF48599382FBA6ACC79B968962771B
+:10F43000E3BE290FB0FD793387AD47C461859FF2E4
+:10F44000604EB004F26B7BCF572DB7B0F355FCDCA8
+:10F450006EEAF2B79F82734BDBB8BF78FF8BA3F0E5
+:10F460007710CEAE5124F01B9DB5D71580BD372E39
+:10F4700097E94BA94A0FB15993F1733FE6BD16EDD9
+:10F4800065F97B0ABFCF4859E3DC0EF02CCD08624A
+:10F490007EEFE56D31FC0981176DC730BE46F52260
+:10F4A0003CC7FCD1F392D08B54F250D86B5A3BEC52
+:10F4B000AADC6F572E7E9D9E343D572D072FD8BE58
+:10F4C000226A3BB3B7BDB01BB57684E6FBC1F41F1F
+:10F4D000E20FABF25BE6E57A851E87F23D9BF346D1
+:10F4E00091F7D27B0E9944CC709E017209C4FD58ED
+:10F4F00090FFB351B2F8404FD2E6FDF4E6E390E658
+:10F50000E12C1FA4F92276BF44F3C5F014794166BB
+:10F51000C80B49CE3F4D65793D66C80BA1EF5B072F
+:10F520003DB7EC6D81F13BEFB68973CBCCCF5E4B31
+:10F53000789CE1213CD79CB82117CFC94CAC65FE23
+:10F540003B47C020035E3EFB0F9D1FF86E82D22D0D
+:10F55000E8578EA1FE2CD0B7CCB41EF24D7ACF2D39
+:10F56000D79101CF2D8BBC2411A7CD1EBE4102F92E
+:10F57000D39B2F12EA3BCF0CE3762EF1A27FB83754
+:10F580007FE9BB04D7592DF88C49BD7F697ED62E03
+:10F590006DA601F50CB71C7C1CE3789B7BCC78BF77
+:10F5A000446E11EE5B6B6504EFB3759476A0FFB506
+:10F5B00025C3BF39D7D5873F627E64235BFF1938E7
+:10F5C000AF25F58D7B66E117F9A04F55771B191E06
+:10F5D0006AE6B1B9F7DE143A0E7DFE2297EDBF4F11
+:10F5E000A3DF8AE72F047D713E2CC61F6C9D021F8E
+:10F5F000BF4E6FD7E257B89AEFCFBBE608CB3B526E
+:10F60000E3D7FE95B5E38E515E726065009F67CCCF
+:10F61000525407F941E6C42CE08077E6CDBF0EEEE8
+:10F62000D338939AC887FB385AF2A77E07EEDF38A3
+:10F63000E34ABC0BE5CEBC7F63E561896D703FC7D3
+:10F64000CFF3145686B1B2097965CBB9EBC2A57870
+:10F65000AFD5EA1E904FE59A3C13CD3D02900F893D
+:10F66000F71E58D97E66F27C5452C3F577882CD1A8
+:10F67000726B56990FF208ACC4BBBB07EA738DECF2
+:10F68000BE01C2F29F5A8715B27C058EEF2497FB0C
+:10F690009F493C0CF8DB5A68C7EF7BF9F56E238F66
+:10F6A0003BB1F1DF78869D131379B684D8F240EF31
+:10F6B000B17A89AA2CEEE1208A2D0FCEDDB70ABFE0
+:10F6C0001E2F1FB1044FE426E9456F4CBAA3147FE7
+:10F6D0008FE3D9BB86C27AAF32A8EF33EEE5A7F944
+:10F6E0008C1F9EE1F7FE7558829F423F4752664D40
+:10F6F00086AB5467665419ECA8A73DAE037EE4E2DE
+:10F7000078619FC1E667AF0948F03B18E2DE3D57DC
+:10F7100050417F000976EA407EBA8E05309FAFC126
+:10F7200094C857287E7D610CFE03E8E16CDD7B3FC9
+:10F73000C03860F61BEF42FEC51BFA8E8969202F88
+:10F740000AF97D0ED4F00B3B41DE15A0DDD77B4FCF
+:10F75000E73009F9C3D419ECFCE9141255D0FF6263
+:10F7600063E7A1269717FA5AE9785379FEC6E4238E
+:10F770008134F0034CBE29AEB0784B4249CE97108D
+:10F780004FE2D17B93E9E06A6F5299C0FDBEEAF285
+:10F79000B53E75F93B955F0E4F2EA7533B206F3C4E
+:10F7A000F0AD389E270E5F426C6C5D2C2FF0E7DCCD
+:10F7B0006E1BE521A602C85B744A61B00B463D97FB
+:10F7C0008D7194E72A0996DD3B4D0F9992D7BF5E64
+:10F7D00066715AEEE716BFE3037520579F7DCB8D08
+:10F7E000F0725B65E4A7E001077CABC8315980BFCC
+:10F7F000EB389F17E7AF27A599F0FED5D625ECFE8D
+:10F800007FEDFD93AD7ADB3ED8C7D613740D749CA3
+:10F8100047520D31390DF68B1083B38F1F0BFC81CE
+:10F82000FEAE00BC1FCF7E678962F9D0E4FBBF5BF0
+:10F830005D6CAEAD772B3C3EC77EEFA1A4F7F71F02
+:10F8400028D9D1F6A05312A413161FCB13EB248A88
+:10F850001FDA67115166E7ACDCBC2CEEBD24A44A6C
+:10F86000C1FB7224D1AE05CB0FF27652F72B7F038A
+:10F87000FC189A46D7439F4BF2189F78587E632313
+:10F88000E28935E8053CF1A50C7CEEE7B63C46374D
+:10F8900093D22A3D9037D09AE5F3805E25E023DEAF
+:10F8A0008B7E45BD18CF973170BF4B78BF517E6EB0
+:10F8B000585BBF388FE96DBDE3EA69BFD6AF18D793
+:10F8C000A51EB7F7BBBC81BF13EF457BFC79A60A29
+:10F8D000A03306B7293C5F9594A8F35348A5CFC43D
+:10F8E000F8BD3A1FE52A694516D0E7D5A6C6EE3819
+:10F8F000FDFE158E2757C9C1BF40BCE19559C5070C
+:10F90000803E6BE18279DACF3524B61A90E54C550A
+:10F91000F067F621C82FDAF2E83A9A74C1E10E5A7C
+:10F920003EA5EF18BAA410E9EB9EBCF1FDE727F065
+:10F93000B0779E14FF60DF05FE69E72DF0805C174D
+:10F94000C5C4BCAD24864F0F61F9D0547EB1BC67ED
+:10F950006F5EDFBA28724E36350F05F9FE4A4B1836
+:10F96000F9CF55F69F60FED78305C1CD30AF99170B
+:10F970007D82F7DD104F1DEA5B74BE3FFDBF9C2FFB
+:10F98000A5AB2C782FF440A1EFF5CB033E6150E5F9
+:10F99000018BF969E958CC2344D83D4613BBB7A382
+:10F9A0007E179A61F5C1798D10E4B79663FC0BF36D
+:10F9B00085F770BB2C2CB1BCDD7EFAE2E0F9C2EC1D
+:10F9C0005C7FA38DDD6723EE45FA7E91B8EF86CD8F
+:10F9D0009BF22F7EDF0D963BEBBC68FFF5EA8DF3C3
+:10F9E000981E7A65B1A50DEE0FEC7FEF0DF3EF9148
+:10F9F000E78C5EAE27A2FCEE4C65E39C32B3FCF4D0
+:10FA0000243E4E2477DF7D5C1BF44C1FFC635E219B
+:10FA1000BB5F44F655C07E6C86B895AEBF1FF284BE
+:10FA20002BF867C0EB79A5FE7CF8898D3906E6676F
+:10FA3000A478B5A587409A5BF32370DFE4D5A4F9D9
+:10FA4000B03C04F1EABFA1FDCC519FB07B28FBF094
+:10FA5000EA0386576164825F47A72F6604CF40FBA5
+:10FA60004E7BF49DA67288331A11FE228F504BBF35
+:10FA700049F339A667F371C23DB7743E9F0F349FB7
+:10FA80000BC1EF643CCA240C8F07C373C8D74F1D4A
+:10FA9000DB87E7E92468C81F9F84EFAB7DEDBA21BF
+:10FAA00003CC5B67C57DBFF166168F09A5303D1598
+:10FAB000E232596EF03FB1F16F5CC3F0E346B3112F
+:10FAC000F1655A7723C65F480D8BA7F8E8FF603EC3
+:10FAD00033897F12FC54C6F5B66978FE72C6547538
+:10FAE000BC65A6E92A8CEFDC40983FEDC6197AD5B3
+:10FAF000EF000A38CC24EB3E817C8E999ADFFFD34D
+:10FB0000C2451BAF11F068ADFC6ABA1F91DF1BD76D
+:10FB100019FE0DE33ABE7C963F7741719D03FA04CE
+:10FB20009EBB7FD9B560CB124A17C37F5A8AF7664E
+:10FB30004F722F7C643D2D3FB67924965F76DFBAF5
+:10FB4000EC0DA8DF568CE51AF99359788F79C5CD5D
+:10FB500053E0BEF10366D68FC712EC84DF8FF08CC2
+:10FB6000291A0B26598D2181EDAEB9A8711CE4C16B
+:10FB7000D45858F9B5B2FF1A8BE5225E1EFBC24875
+:10FB8000281F903E9935505C6854891483DF89AAF8
+:10FB900071B0F653C73E9E0D7E829A6A561EE5AB43
+:10FBA0005A3304EAE54F670D248F67E573FB89EB51
+:10FBB0005B014EEFCFF9DF6B83735E01ABE483FC37
+:10FBC000FE40E57BEC9E2B13CB2308F8CB14B80743
+:10FBD000B1DACFFC7B13AD2D59C0FFAE0B1ACAC1F1
+:10FBE0008F6BB316B6C17DFFE99555E361BF275210
+:10FBF000350CE41FA5ABD9F94057177F929F867A41
+:10FC0000889AAE04DE4E13F454A3A61BCA0FEAD999
+:10FC10003EAAE981F6DB88FD5EAA964BBDFC5D43FA
+:10FC2000B75A7C1C54EE13351FEC954FABA3889745
+:10FC3000B9849DE3D90A78CAE8F7DF607E06B9C7C0
+:10FC40000BEF0B24DF484CAC18447F10F303B5874F
+:10FC50008CED3F2FF85384BEC86660B3B9615C5623
+:10FC60004FBFF3C38F7A8979D1F17F8CF059CDE6FC
+:10FC7000B3556AE6BF13C1F47261F73689F576A908
+:10FC8000D75B6161E7D13D84F21DF4DD978DFCAA5D
+:10FC90007987B89C9D610ADC67A46BB8C13E07F701
+:10FCA000F926127E06F49BD72CC108CC472787F78C
+:10FCB000C625F89D073FC693E93E6ECF4FD217C4C5
+:10FCC000BCB4F0681A84AF6AE7AD8543DFFEF4A0E8
+:10FCD0007E96C57F0FAE775D9AF5B4F2FBE01365B3
+:10FCE00046559EE86B752C0F56CCEB358994A09C3D
+:10FCF000942C1847EDF53B69F9DB20E7D2847C169C
+:10FD0000F3BC839F8BFA5C667CEF0E5D0CE7595069
+:10FD1000DB630638C6F38BD87DC67CFEAD95616C7F
+:10FD20006790A501E3C4F17C59E457A8F65BDC4F6A
+:10FD300026E25C02AE4E833717F33D35F09C6D3200
+:10FD40000E1C57D5C65F07692751F8E538FAC35925
+:10FD5000C4CBAED5FAE1AE66FEA96BB91F6E622DBB
+:10FD600083BF63792ADA6D8EF2371432BAEFFE64FC
+:10FD7000B11F3DCEE049C423253E1EFC04AF8F7F5A
+:10FD80000CE344E29E422D7CCE0D029FC1E861B09F
+:10FD9000F91FB104BE80714F493D789F59C263E39A
+:10FDA000CE836021D08BDD565805FE05CA57CF9F04
+:10FDB000076313AAE8FE2D770565B853EF2612985E
+:10FDC00004B9D78EDAA09EF9E709FA8797723B71DA
+:10FDD0001297EF9F3EC9CEC1D7F8473C7819E89FEC
+:10FDE00087F424E2853C6E069F4FB7E850AE2F782B
+:10FDF000759C07F4F3F739BE0DDF28AB7E2F6E44F8
+:10FE0000C4A2BA2F63D44E87AA3C3A9AAD6A7F51F6
+:10FE10005791AABE2C3652553FEED05855797CCF1B
+:10FE20000455FB8B8F54ABCA97C4A7A8DA5F7A7CC2
+:10FE3000BAAA7C79E216F57D1F617F4F891BEECB54
+:10FE400067F0B8F2DC6C55FB8FD3261F02BA9BBB60
+:10FE50008EE56D5791C5AAEF17EB1A301F9A7430D3
+:10FE60003DA699FE8F9F3757304F8CEAEF1900B7A8
+:10FE70008D6A3DA7BE7BFD6AE0B5FDEE99D0E83303
+:10FE80005AFD65B8B30EAE69269717B0F3EDE4627C
+:10FE90007231FFFD10EDBEE2B9FD4F0FEBD08E5871
+:10FEA000FA2AD3EF973EC5F2E18AC9B0743CCF7508
+:10FEB00048472212DC5FD0BCE132A94F8FD1C2C5C6
+:10FEC000E851EFB3D9ABDEE79412F53EA7FAD4FBC5
+:10FED0009C5EA9DE67BB5FBDCF19B5EA7D7605D410
+:10FEE000FB9C3953BDCF5941F53EE7D4ABF739AF51
+:10FEF00059BDCF05CBD5FB5A185EA4AA177C734811
+:10FF0000FB52D5FB56295A413925991BA8C77B1BA3
+:10FF10008675FC7040FC10FB1FA6FF63F4DC8CF9B7
+:10FF2000F5F3E9FE437EFD5FC9BA83108AD2E24150
+:10FF300053D77A8CAB7D533CB8BB80EBA762FF2FC5
+:10FF4000503FA5F2B015F802D5635617807D3D9C51
+:10FF5000DB1D8181F518C1B792F58664BB7A307ECE
+:10FF6000D64F4E723B7B5039A9B1B3DF82EC26D419
+:10FF7000C7D7A15FEB668ED79FC1AB4BC0AFFA343A
+:10FF8000CAFFB7E8442AE9BCDE8279D371DEB28CBD
+:10FF9000423FC8AD24A6C77802646EEAF0DE4BCCBF
+:10FFA000C3ACA37A393CE770FD601EF7937C610C0B
+:10FFB000EE2C60FE9102378C9BDBC3CE6FBD967139
+:10FFC00041F73BFC0EFE49DBFDA92010857E6A4C03
+:10FFD000DE650FD057FBB9FF894C65F99F44098C4A
+:10FFE0004EBE4FB1AF1F16377D410A06D1CECE327D
+:10FFF000F9C0CE1E95434C5920DF3C91228853FD19
+:020000022000DC
+:10000000BA4016712A942B23398E3C951D5D6A47A0
+:1000100078451C1827F886E3FEA6C07F10F041B48F
+:10002000FFBAF51A0CD125CC9FC07EBFE430DF9714
+:10003000876F34C6C02E1378742465D6419717FD98
+:10004000E187012E336FBA7A3594A5FD19DEA574C8
+:100050007E67EAE268DF53F81F81F11B4C14FE74DF
+:1000600089A7F282C3D301190219DC4919183DD0BE
+:100070007924319F8912C70B4BF03D1867BFDC9381
+:10008000EF0378283D78FE8E5851B921A70C03FB69
+:1000900003051CAA53F26EC3FB748D461FD817D5F7
+:1000A00012DBD76319B7CF82D8E23C39E08EE9542E
+:1000B000F33E03E335D8EA0AB28AC0AFC6E70D3F84
+:1000C000028A70F7960EE827E7F3861C128CEFDEA3
+:1000D0002D89DFCBC1F273613BC6338CF26787E1B8
+:1000E000F7FD12A3658CF76DB1D0AE29BEFF27874F
+:1000F000B7B8EF9CBE67F97916F6BD67838CF1A39C
+:10010000FF07EF54F02D0080000000001F8B080057
+:1001100000000000000BE57D097C94D5B5F8FDE6F4
+:100120009B2DC924992C6421102609598010266121
+:10013000111471588251034E006531E24C12206453
+:100140008100DAC64ACD40D854A8A122A2A20E0846
+:10015000141568B008A8D1372C527CDA8AADB52EB8
+:100160009597002A3B3168A57DBEFA3FE7DC7B33DB
+:10017000F37D244F7CCBEFD7F7FBC7D777B9DFDD13
+:10018000CF39F7DCB3DD3BEE31AF2E6043187B7E19
+:100190009ECDA92A8C7999C3CC54C6CA99CBCC32AE
+:1001A00018FB7CF4BFBFD1EA602CD2E1B13A8632B1
+:1001B000764F9C21F58334067F9E012591908C8C8F
+:1001C000632C99B1EFF1EFA6AB53C67C8CF5C074EC
+:1001D000B5810D636C929DD1DF2C180BDB4D662E23
+:1001E000138E7307F39870DC3F5C34BB5814A4067D
+:1001F000282F606C2AF3D1F7E9CC4FE95D2C40F54C
+:10020000EF66AD947F3F22AF773DCCAFE489EC4CF5
+:10021000066D2E795B8761F9DF2D9E549C6F8DD51D
+:10022000734F3C7CBFD0DBF36522D467EB60322395
+:100230007E78BE25383FA8F7591F779603F2E3ACC6
+:100240008E21F9E98C1D34B0CA661B948DEB41F305
+:1002500067467BE6A4815DF5B3943118FF58475497
+:100260001E1B8479972D19D67F335F3EBBD9555D10
+:100270008CEB2C546D2C1EE07FCCA1FA2D3066D176
+:10028000686F4F5C17FC45FAE2199BE852D9C3002E
+:10029000EFDF2E812F50EFB7F9AABF11EA4DDC3006
+:1002A000FE0CB62F1E3D795934AC7FFC77AD43026E
+:1002B0009016F5329D68CDE1637C0FFFFB866D1CC7
+:1002C0001703E9AD49BB8D0CE67F6B5F6D79712E2D
+:1002D000E4ADC1FC44660C96C3B807100EB18CD5D2
+:1002E000FF257FD4E190768C35A96E58F7AD8EC886
+:1002F000F82F0640B63FEBFF3DCE5B2D8DF6D8BA0A
+:1003000087EFB70DCE51874D304FC55582F861400C
+:100310006F6EA0A33223733577D1EEE94C45D00F31
+:10032000603781B1DBC55C3B8A2F9B2FC17A57397F
+:100330003CA5D8CFC2099FCFC4F53123FBDD608037
+:10034000DBBCDF03DCA0FC4403403E9BB1530D56F5
+:10035000E6B230F645839DF2A71B92283DDBE0A074
+:10036000F47C430E955F6C7052FED70EF72CECB701
+:100370006CD557464F2E632BC3241EF93C16093A01
+:100380005ED97BD89F9D30DECA774D94AF6C6E1AD4
+:100390001F01E9A2DE279646C0F7452F284EFC5ED6
+:1003A000DDE232DB603EB30E7B5620F9CC79B775C7
+:1003B00022808FD55E519807B690A5AF7B11D2D918
+:1003C000D03F9D4A40F87DD9309CE673A6C145F3E5
+:1003D00071B5B41D8983F6E71A8A287FD4E1BE1F60
+:1003E000E7E7625F99B1FE841D6DC614282F74295A
+:1003F0002E06E38E7231BF1FF0B7C1E4F120DD6C31
+:1004000048B63A1B213F7AE0A467EE8571DFE9E345
+:1004100069C4F677C49617C6C1F789C3BD46AC3721
+:10042000F53BC6302FE9FB87F7358747ADC0CB8555
+:10043000371582D385BD036EBF01FA7BF3A8CA547A
+:100440009857C71503CDABE3A3703F5382F516BE93
+:10045000A2125D2F1C68F6B334CC0F4864B9B84EB5
+:10046000E80CD69FA338583DD0DFB99D3F4D423CA4
+:10047000C8F1CFC536FFF513E8AFFD338373338D75
+:10048000DCFCC55390DFD72BC9F930E42E9AD83461
+:10049000DAA7AC2E6212D0D73C33F3F0BC6700E68B
+:1004A000CF85B37BDC901FB62B650CEE231CCF9160
+:1004B0001DE46B59BB9E487FC0111C6F7BF3AC4F92
+:1004C0009E82FC05BFC1678A8694355F7C0DC6F3AA
+:1004D0006DB139B7329CA7311CE7F98889CFCBB70A
+:1004E00035DCB9D581FDF9890F40B919CB6B5E7E3A
+:1004F000B227AEE37580C170C8BFBE3682F8DDEBAF
+:1005000026E7F17A6CF70CEFEF57BFB8FFC47E4CCB
+:10051000D7D416DC0F69C0114BF0AEF8E5DCFED87D
+:100520007E400AA007F8E34BFB9440581E6303D7B4
+:100530001D589A0CE30DDAD866E80969FE16A51174
+:10054000D301BD8B8EAAD0FF118783E63178479AFD
+:100550009A82DBB5A7FF939B3208700AE2AFBFC057
+:100560005FEEBAAFC6F4847467CFE6853150DE5FC4
+:10057000693EBB240DE9FCC3020FC1AF89FA79A51E
+:1005800065F21FEF62B80E5FB215E7ED353BB7A617
+:10059000F1E59A207F614FC6A687618D7B0DBE4D28
+:1005A00088775F99D5B915F1EEF63D89F8AE85FAF1
+:1005B0003EC8D7E6FBA2AE87F2DACFFA3A81A2585C
+:1005C000EF676F2E4278CCDBF3F8F89E50EFC2480D
+:1005D000E604126095AF5C1E8FED586FC690255CE7
+:1005E000D8D3983003DA3D923B6628D2975B6DA64C
+:1005F00071D87C3ECE13B01DAD0032D60AC0491072
+:10060000A40AF51E81CFF83DB625E6400A0BE26745
+:100610007ECB923423B41FE2B13A55DC3769BEE495
+:100620003A58EF7B5865049D7FA7717F269B45BF95
+:10063000F6C9A9EE1F71FE99C57926FB7BC2CC7C59
+:1006400061D04F6FF8AE40BA11FB85F2ADC057EAEA
+:10065000217D46CC1FC6BD82FB14DABB900FA7C01C
+:10066000219D0FF34C79C242E7C0B58E7FC9645B10
+:10067000A500DDCE0FE77C6C8C387FA7C535BED1D9
+:100680000AEB7D35DC634C83716689739F199D0E7F
+:10069000E4EFFE709729AD079EA3EDA9B806385781
+:1006A000C3303F4FF5F449C8A073353B1AF9BEF586
+:1006B000DACED577C35DD1D8FE5AEBEBF9EDA26F58
+:1006C0000C2C1FE860D1E316E2178DC897615D8D91
+:1006D00091C3ACC837D86143CD1138676FE42D3B67
+:1006E000FB5B1459407CA591B12EE1F526EC7F0F00
+:1006F000F09B009C131EE003A3AEB4AB9CDE8F1DE9
+:100700008A1E827C96B922817E6EBA62609E907348
+:1007100050DF0FE02B0FE1389A45304FC8B9EA623D
+:100720003166DCB7CC16FB5F5BB798FF4881BF91A1
+:100730001D1F45301BC203BEDBBA5FD71B625DFFC6
+:1007400082EB82745DA6DB85F0BFF16BBB11D777BE
+:10075000A3B12415E51A98F778FC3EEA6B8376DEA0
+:10076000DF856BF2D73AFFFB14E633E07EFCCAEC80
+:10077000C7FDD882C723C0B1656EAE1FF7FD5E33DB
+:10078000CFFBA2A01CF0D812C97CC8475A4A12FC61
+:10079000BE34E487508E7CA307E3E561A2FDF40438
+:1007A0006ADFD30220457E7057B8E8BFEE9D8158BE
+:1007B000BE2485F848A3C9BF2A1DFBFFB94A7CF8AF
+:1007C00023C1B7D7C504EE52A1DF755F25301CE702
+:1007D000231648998FE3548613DFBDC160B8A7C4C0
+:1007E00086F55CC9B100EFBDFF50E99C58970F79C1
+:1007F0001BF1ED69CDF07D5D892B391CFB2949305A
+:10080000D07C545647DFD378BB4F4CBCDE0C81AF55
+:100810008F057E605FD3BEF74C8C3022DDAE492B56
+:10082000F3A5911CE44A5660BE4F556432E49B33F5
+:10083000AA6E49237A697A82F8D7348103D91F36A0
+:10084000B00E43B999FF4D9FB5350CF17947655806
+:100850001B9CACECA3CAA5910E687F87470D5880FE
+:100860009FB22985AE4EB92E1DC775D1B8B5CDFD45
+:10087000324E85D0739905F804F4FF52986725ED40
+:10088000D3FDF954BE1F849AEF613F9DA8C8DC8553
+:10089000FB8A55C4111D3063A01CF1F066BB95E4C2
+:1008A000D4EEE8A111E13F48D029E26531C73BC849
+:1008B0006B946F9CD6DF8FED9F3371BAF1ED0E23F1
+:1008C000BC164DB2129E3BA6856FB240F93D826FB9
+:1008D000354E0B772950AFF1158BDF807C40E1F46A
+:1008E000E07B2392FAAD31F37CCDCB99444F7BCDA5
+:1008F000FE17B661F99B61440F35517CDC9AD752E3
+:1009000004BDB9D296E3B86F58880E6AC21DD1549F
+:10091000FEAF7144272EAB673BC203E8AE0EE588FD
+:100920001A73202B06E07B5CD0D5716883F8F3D571
+:1009300045D2BC69CB43DED3D87B33E2D363E6E553
+:10094000EC672A951FB7F3F18FAFE6E3973E5AFDA8
+:100950002E03BC1D778F4F9E05F3385E174172E35F
+:100960005FEAD580390AF59EF6F55950EFE2E29339
+:10097000C336C0FC5B977E9A8AF451BAB4B618DBD2
+:1009800095562D9E88E76677FBB2B406367FC83E43
+:100990007E3FCD15C0F55C48F31C423A989FDB3A88
+:1009A0001BE5E78BE663CFA2FE1115E73982DF2F47
+:1009B000BDFAE5362E57B767E17930CFC8E9439ED7
+:1009C000ABF305FDDD97EE7997CE89F0C04C3C3F47
+:1009D00022728F717EB7F8DAF8FCD996AD7B1518C4
+:1009E000A73ABC651EA5AA3F0FFB39A704A2940C29
+:1009F000829F07F7D3797B200AE1EE317079AE7AD6
+:100A0000BB765DF867847955E33FA05D75B3EA0A6C
+:100A1000435C33BF19E75FCDCCC1FA69413C413F2C
+:100A2000842766FBCBCC0700FE552FF42B40FDA19D
+:100A30003A66FF2F6EA07AD04EEE13F5EABC5CCF7B
+:100A4000D5F3E1EB3B2FE8FFBCA4FF6982FEC5F8BC
+:100A5000175F4DA4F1CF95F8B310FE171551EF05B0
+:100A60000BAF07D460C479FE9AD3D37A93CF80FCBE
+:100A7000C7F77346F45C1DD73C0CE122F910CCC1DA
+:100A80006780FAE776A5507DC9B7989B316C57BD52
+:100A90002B793397CF843E8B1385FA552FF1FE3196
+:100AA0008FFBF0EC8B29623C2E4FEBF1A75F6F447C
+:100AB000BA81E4A9F5927F47CA7DEE4C2A01F86716
+:100AC0006F306BEA5F8C34DFE3827EFBF9B5DF6564
+:100AD000FF89E95CFFEBA3C35B4FB5FD8005F7D34E
+:100AE000F38CF6AB7E5EA9A2DD8B2F76E249E5782A
+:100AF000033150D28783CBE12684F3C79DF8B83702
+:100B000005F86A35C2203D089FBDF99E14E4FF1721
+:100B1000318FE7420CE473510EE2F0967909673D9C
+:100B20009D2DFD78764A2BB4BF45C007109A88F4F6
+:100B3000D829BF98401FC9457DB472F0A94CD45341
+:100B4000EBFAC151D0B99ED91BF2ADB89FE66CCC7F
+:100B5000B79685E0A171FBE0A30E80F3F9ED46277F
+:100B6000B2E546A3FF17284F376E579B7D8CCAAD61
+:100B700008DFF3B683BFC77AB337C614A0BC2CDB3B
+:100B8000CFD9705FBF8A10B80FD8AEC5C3C0666D2D
+:100B90007ED07E6D7E32F286A13FBE5D7E409B1F81
+:100BA0007C549B67ED802DC0836AE578DA37DC7969
+:100BB000D40178EAE3579DF8A98F6DD2E409285F44
+:100BC0006C549D9950DE67B1FBB681903FBD719624
+:100BD00013D15CA9FAE63D0038ACFC74FC513C0F23
+:100BE000CFB1E60F27001E66B7AC351B1DB86E2DC2
+:100BF000DDEE35087A7D51213A98EBD7965FBDAF8F
+:100C000097083CB29C507AD2E31DC6BDD30513AA07
+:100C1000A95F34F8141C9995C540E800B311CD6B59
+:100C2000CD28B7FDF0383E2E0FDA5C0E848777387A
+:100C30002FBBBE7E2C3B3918FEB1FAFDF1386FEFA9
+:100C4000230AC90DDEDF641FC673A06DF7F45B29AC
+:100C5000BDB388D62FED79735A944024E4EDC31DBB
+:100C6000FB5BA1DD2CBFE2C479972DB304F919FC1D
+:100C7000AF62B56E1EEB42CA61FE73F61FF89B02AF
+:100C8000FD576ED4B69B0B7C16F957D596EF2DA168
+:100C9000DFA5DE787DCB2615D73D4BCEDF378AE149
+:100CA000BAAEE75559BC906F4E6106CE8D5B7BB8EE
+:100CB000D7A763BB75BC1DB04B2FAEB7D66676E029
+:100CC0007A6BAD2C1001F3381A6976D9E1FBE50D8A
+:100CD0009164479B6D0179B28052165680ED9CD18C
+:100CE000D8EE8BF7B83DAD368EE3BBF63985F4A868
+:100CF0005A347E62FE799E9FCB02B40EA41357E84D
+:100D0000FAFCDA3C6BE2FA578D317000E151C55ABA
+:100D1000B9FE04787449F801BC6A609D1FC5A2BC85
+:100D2000A56BCF9C1E1C77BE8DCB4FF3F77F6F0951
+:100D30002D977AA0D4533786733DF1B92C77388E2E
+:100D4000B35C713D6985792E17F2B56F6D18D1EFDF
+:100D50008C4DFCBC0139360BE1B26E6DB213E58CE3
+:100D600019209787E1BE991B4EF540DE25BB4C3B11
+:100D7000C8D59BD3B07E7300CF8D758FA7911C0D06
+:100D8000F22FC1A57D4D987FB38272309763D6ADA7
+:100D9000CD2639FC75794EADE1725717723195B396
+:100DA000442EC77F824B099183CFF4F07C901EB212
+:100DB000AE8AA5AE643C772A26990D68AF6295711C
+:100DC000D7243F6C1572643BAC1FD7714A711F3139
+:100DD00084C8A39FE37900E30C1BE3DA26EA39B168
+:100DE0005E85A1E4E19B70BCF506078ED7096F977D
+:100DF0002B0BE7716A6D5801D2D9B031DC5E743CBF
+:100E00009FF3F78821CCE587F4A238672E225F0F85
+:100E10004993C281FEA09F5385DC5E1D39C44D7687
+:100E20003A38AB89CFEBD7F177D14F85D9FDAF37C2
+:100E300076311F091F368ECB0BA716289BF9BC00F5
+:100E4000BF901FF6CB30B2EF9D12E78F8433D0CD29
+:100E500050B2D30B7EB556D0CB5A13A703DF5CAE8E
+:100E60003F05E985113DAC137AD60C815FB686CB80
+:100E7000B5402F1CCE6B9205BDC0DC911E0A1D5CD7
+:100E8000CEBE467D09F01E9BD1E36ABD49E29B19A7
+:100E9000FD43D1BED21DBE6BF7EDDCEB83F3B3EAAD
+:100EA000D78F4731A877C6D894E084F6355B97474B
+:100EB000B9203D6DF445D961FC337EB5C8DF05BC72
+:100EC0006FCF907665974D01FE330FFFE94079E7CC
+:100ED0009189B8BEBF6E35D99125CCDF6E21FD69F1
+:100EE000DE9EB9246743BE8DE7577EA5627EBFD6DE
+:100EF0007E5EF5ABC7131C046F5F8A2109D3400ADD
+:100F00008374DE1693338076E90F54270C037273D3
+:100F1000FB0A9C9FBE3DCEE30AE07B7EB3EA3547E9
+:100F20005F5D3E5FF097F97B1EF90AED7AF375F687
+:100F3000FA4AE1B7D0DBEB6FCA888CFF020DD3D73A
+:100F4000B1EB500E02B83803B86F613E994426DC0D
+:100F5000DEDBF8C213796D282F6C79274AC90DDAC8
+:100F6000EBA53FA3A3B9FCB9D71CDDEFC78BC26EBD
+:100F70001BC417E75B8EFD0AF20050D0795A630A52
+:100F800044DD00F0A8D964223E53B3F3F96D4F213C
+:100F90009D7D6CA1F3BC7AE75B1F5E8FF2EE6E5312
+:100FA0007C315F864D4908E269BE83DBC9245EAAB5
+:100FB0007EF396D931907F5F1C1BC44FF5EE03661C
+:100FC00036F06A388E6D3E606EB57581A7E6B6F173
+:100FD00064277AE15B33EE83336F2A2C31EDEAF636
+:100FE000959BDE8A42790CE184E792C45727FE7410
+:100FF000F5A1FF89AF0DA17A76D42BBAC39F03CF99
+:101000000ED4CBF745B21818BFF2138BBF18F1BA44
+:101010006B5114AEE34B631DA7F3679627A05C5793
+:1010200069F225D829E5DF2B9FBD8FE86F8E529797
+:1010300060CF25FA4E3690CCE04BC6F5CDDA780776
+:10104000AD6F36F310FD553EA3BAFD907E63644547
+:10105000BBBBD8276F6770BEF9E566402AACEF4B83
+:10106000B4DB20DFF8832AF4DC05747EDF27D6CAE0
+:10107000D842CA7F23E4B68D1952DE056922445F47
+:101080009CBF65E531C4CFD9DEAE449C27C0C127E3
+:10109000E0A57C0FFDAAEF172672FC3087719868D7
+:1010A00007E7E858FC8EF58F995C68F70E6927F41E
+:1010B000393EFEBD627C987738EAAB5F2670B95D39
+:1010C000BFBE6F3BF9003BC642E9ABBB7DBFE5212C
+:1010D000A2ABAF3FE07C659EBFA488CA8F9902890E
+:1010E00058EE3F304521BE606181AEF6F51693D8CB
+:1010F000D7DA7298A7510985EF9B5C0E9D0D725748
+:1011000020641F07E9C61CFC4EEBFEA558472BF9CF
+:10111000D3A41F6E8EE007FA75EBF9C3211D7F90F3
+:10112000EDD9C6AEFD4041BEE0A3716BE03C413954
+:10113000A3E6630B9D1B353B4D6E84CFB91D873EE7
+:101140009C817A68B3DCC75A7EABDFC7952F0FED61
+:10115000721F9F5B9DDFF53E86EF5DEEE3D50AF1E2
+:10116000B7FF2EBF85938EEC06DDEDD739DDF0DBC2
+:101170000B3A787EC372A36FC042BBB70FE147073B
+:1011800057094F3DFF5C9EE120F8EAF927FC7DC03E
+:1011900042E028E127E993310F8DD349C7924E25CC
+:1011A0001D77D2A97EBD5A38EACB77237F82F9B862
+:1011B0005F3571FB598B42F236B43B923284F6A90B
+:1011C0008B8E3FD67424253E34EFD7E59B75F55DB5
+:1011D000BABC5B57DFA3CBD769EAD7EC3F64E6FA2A
+:1011E000414053CF527F1BE91957CB117EEEF7D9FF
+:1011F000F395D98774D1ABDD8C7CD1B494F92251AD
+:10120000DE7D432579F792A33D0AE592E5615C6EA8
+:10121000BB6417F9189E6FEF615E817C517E6F0F82
+:10122000E376924BEEF6A898103DBDAD458D427B1E
+:101230006CAB9F1575654721CB28C0B5957557CE0A
+:10124000E5B742D5965A8FF6D026D50964C22A96BC
+:101250004C8DA2B887968CDBA7C1F7596FAB143EB3
+:1012600070299CDB1598CF65C4B883728E42769A3C
+:10127000F9D68F847595B7F0F8838AD55AFCCEB627
+:101280004D890E3890EF68E304E6A05E9781FA9EE0
+:10129000F67B155B4DF456A5DB171E61A7D5EF0B4A
+:1012A000775F112F90CFF2853D86FC1C0B05BF2E7A
+:1012B00054736F9F06F0BF74546516C877B4A86C5A
+:1012C00005AE778742FE1E7408E07E9B07FB12E79F
+:1012D00023E1731EF74D76F772C9F9573E1BF600EE
+:1012E000D2C9DE4FF39E86F4FCDE8FB35EC7FCBE30
+:1012F0003FA77ECAAEAE3FF6CDBFCD443E7CE94DA2
+:101300000B43FABEF4E66F53D12E78E9350BE9CBE7
+:1013100097965AB8BDF9CD483FFA232FF5E6726E7D
+:10132000E31BDFE6B5D2B9BB8CF0F5405F33979B8A
+:101330005AFEFD38DAAB3B5A6055284FBC1941FBC9
+:1013400067FE6B61E40FBFF4C6B7C342E326FEBB82
+:10135000EB91FEEE4B916CDACB48B742AE9FFFFAB1
+:1013600088E7D19F5BBBE780B91CCAC7FECB7FE48F
+:1013700021FFBCF43297932E9A5A9F455BE38A2D46
+:10138000CE5F9A92D13E079DF564ACCFD6BA49B8EC
+:101390004FAE860B87C3258003AE0BE052897CBF1E
+:1013A0003B783C83F0E8F1CF088FAF66727E761D04
+:1013B00043FF6F102E0AF723B444FAAD0AAD9F7FA6
+:1013C0007FF3DB3CE4373FB4DED7FF69F1FFBFB307
+:1013D000DE8FFF69F1CBE9DDDBD741F3D4D3FDD557
+:1013E00074BDEF2794DF15E9A4F95EE37EFFDBFF10
+:1013F00067F84ECCFCBF8AEFB705BE23EDE857BCBB
+:10140000F4C67FA4B21FB1EE61FF47D72DE5F531D9
+:10141000AAF3683ED47F87357FE04C23E9A34BB91C
+:10142000A33C5391FA1BE94763193FA7C75AAB493D
+:10143000DE1CDB6B0DC9C58DAC80FC10BE5E2AF9CD
+:101440006328F802E0F0DBA47C3FF9938C815E8B8B
+:10145000203F26A596E2B3F47AE3D8F00945288F19
+:101460001E5A02F3827E0E451AECE82B1ED74B0D56
+:1014700058F2286DC3F448EA6D47516E1967D3EAF4
+:101480004FB7E9F4A15B1CDAF222F6723CFACF8A7C
+:10149000724DCC0FF3198FF543F4C6D199765AE704
+:1014A0002DAC6999DDF6E3E1F49880D3D570F8CFDF
+:1014B000E176159C849E6C14F5F57033DA1E3E8639
+:1014C000ED8C0CF45EBE5ED297A5DEFB43F0644269
+:1014D0009F368AA1257C8DBDB89F34A45F828B8402
+:1014E000FB8F85B7C4931EEE12BE126E7A3CCC46BB
+:1014F00063548F20FC7B19F38DB8EF6E1472FC38A7
+:10150000630CCFF73AA6BA693FFA399D7FED34A252
+:101510007C32DA1643F19ACCD13B06E54C1431BF4C
+:101520004F61AC6C78CC3005D69B62643E0BE89B77
+:10153000E843233BEA4346FFD2341C87DB6B7B1B2B
+:10154000B95D1A76B72FBC80EABBCC90F73E3687E0
+:10155000B9A0BE378539155E9F45C752381A533139
+:101560002E0B526CE78DE6FD7A13997F29C727E190
+:10157000A52FA6E9D4AFCB10CBDB4715507B9F81BD
+:10158000B7771921ED93C1EDEBEDCB2DA47F785703
+:10159000F6CE42FE513C466B378EC8E2766699FE27
+:1015A00024CB41A96A7026A15C5CB6AC1FE9436AF2
+:1015B000B8BBF615B4F7EF8A207AF4AEB87BC25008
+:1015C0009CDFAE38274EEFECC4DDC378FDE9F7FDB4
+:1015D00009BE7BB687D1F7A7B23C473201AE67158B
+:1015E000C7CC57E043D91D87CC493084A7B9E40262
+:1015F000DAFF26FA76FF1EFD8C13A7A8547F22E39C
+:10160000718F6C5904F9A327F8BE3226417F13402D
+:10161000D9C0F2B6307BEA0298BF57D87BFF20F6DC
+:101620008B1ACE3C2F23BF5AD13B2B1DBE4F605D82
+:10163000C701DBB3B89D461DA36C44FF509FB1DCCE
+:101640001E2FEB633FD86F8280C76799DCEE24F3CF
+:101650000057AA5FB1CAD296817ACF2A53201BE3E2
+:10166000A773C6B4E13A8BD3D9F80D08F7FB55B68A
+:1016700099E6DBEE253B77648E03F1E00192A6F854
+:10168000C2A63407DABDDA463707D03FD0F6649AEF
+:10169000B3D14158A6781CA967B58D0EF445BB7C23
+:1016A0007B3EF7331CB7B746A27E586EB3527C8E92
+:1016B0008CEB9965E7FBBC4F63EB9AEB50EF7C5CDE
+:1016C000756E86FCACC7B9DFE5739BD5AFA0BEB61F
+:1016D0008EEF53B65A1BC7C3EC4EB2F794378D3614
+:1016E000A37E59617399719DC9D99EEF715DEC3BE1
+:1016F00080DF308CE364B419BC4D5E8A3351A36043
+:10170000DFE13E313AA250EFD5C701CD17713F322C
+:10171000FF5298C79A05702C8B76EC427A39519F0C
+:101720004176CF9B91EE107E18C788FE09636B321D
+:10173000CEE7D54C4E8FC5B1F62C1BD1731843386C
+:10174000B4990093906F5B1E66403F5BF1524ED799
+:10175000B0CFAC4668FF909185A3DFE043D1BE7463
+:1017600089D1BD09F2BDACCC18198B74954F74FDAD
+:10177000688EE7335CDFE99FB3E1480FE5ABD792B2
+:101780007F45D205331E1B1707E39CDE9A56807CEB
+:1017900053D2D1A33963FA6485D2C31485E800D249
+:1017A0000319440F93FA6279F19840DF85B9A88F45
+:1017B000D630179EEF49CC897242076B27FF6387AB
+:1017C000CDEC403B97E427926F005E5DD684201DF0
+:1017D0006C83F3DE68626C7B8395D2171BECCC08BC
+:1017E0003C6E474312E5773538286D6EC8A1EF2F60
+:1017F000373829BFA76138E5F736B828BFBFA188B9
+:10180000D2D71ADCF45DF225800BF121C957243FB1
+:101810002AB799DBD01F29F9929E6E660278471588
+:10182000507BE27B92DFE13A0C05417E24F19BAED6
+:10183000B87D4969C8C75AA723FE0BD5F33BF7A16A
+:101840005E5E6973929ECE38DFEB007A45B8A49A4B
+:10185000D97EB4BB362E70B5AD4C0BC2FFAE4A85F7
+:101860001943E8EAEEBA30660C3937EEA98FD1E4B5
+:101870004BEBFFF85622F43F2EDE332D0BE671FCC6
+:10188000C12F9EF9337C7FEEC1B399886F98C7D67C
+:101890002770DCC5E19DF388C5FC3213F9A3FA4833
+:1018A0003B08FC215ECA18DF6FCF3DF877DADF6DA9
+:1018B000F51607CAC39F209E00AE7F11782AABB7EA
+:1018C00010FCBCCB4FEEDC87FB7CB199F85CD932C5
+:1018D000B10F57013C43FCBB279219D923409AA66C
+:1018E00078F5133F370722A0FF130ADFBF0A080568
+:1018F000A518F7B7EAB71FE1FE57EA8F92FFDC633E
+:10190000B505480EF099CE87F6A7D41FA17AACB5DD
+:10191000570CDA11E91C43BE3FC46576C0BA91A6E4
+:10192000116F6539075932FA4D9A143B6E990AF1D5
+:10193000BD629542FE498CBB9902729F2F4B253C9C
+:10194000B6641A695FF5CC6242AE6BA2F349D26B02
+:10195000C56A6887FBA229DF3C3B840F9789EFE5C6
+:1019600039064AE5F726EC17FB5B953F0DE5899EA6
+:10197000589E8B69C134846F4FDB78A31282FF8736
+:10198000B3F8F82D997CFC9EB8D9E0FF1ECE4937FC
+:10199000CFCA45FCF0F34B8E539653B002E338CBDD
+:1019A000568F46EECB1A4DCEA478A8F718F643EB27
+:1019B000B17379C1CAE3956BBA393FA4FDEC34FE2B
+:1019C0007304AD9BECBA55BB5EDA8571FC559F5A2A
+:1019D00008BF558344FC54AE7FD86432346AEDD5D9
+:1019E000E35EFA2C8AFC0F7B785C25A4DC9EBAB8F7
+:1019F00092DB5F9DB0AFBAF0FF1CDEF569549776BD
+:101A0000EA3DEA35D9A9E72BDF45A1FC20D753F8F9
+:101A1000C63709340FE50AF97FE6BFB13CA1AB7BBD
+:101A2000377A7B75A73D5BD8EDF4E57A7BDD912CA9
+:101A30009D5FC0C8E81E97B4D73135371AEDFBDF7C
+:101A4000887B1EDDE935D2BE3D7F03741207FBD3D0
+:101A5000E888467FD5A56EE4E9A86C2E1F5C10F6D9
+:101A6000F04B3B54D2732EED88A4FD346FC763470F
+:101A7000D07F386F8B42D3A865C7086E004F660DC4
+:101A80003DC730DE2CEEEA7977F833A3F11CA97E4E
+:101A900029B20EE96C6EB3E2DA0AF3E9B03AA27B3E
+:101AA00084CCE7ACA0D76A4BF33082B3987FAB907D
+:101AB000B764BDB92D8F91FD18EA5D2439E8D711BF
+:101AC0008CDFFF68FF3DCEF3DCC6C14EF4FBCD6D6D
+:101AD000DE3D8FE4881D11761481CE8A3861D9CF1E
+:101AE0005F055DFF358BCB2FE7843FE8DC2E95F853
+:101AF00019CE13F7D759451B8FF79D68F75D1687E9
+:101B00009B1FF7778F60FDB9CD6D517DA1FE97FBCF
+:101B1000FF48A9399BAF6BAEED581E9EBF5FEE89A3
+:101B2000207FD6977B9E1EFF3A8C77A179743CEE7E
+:101B300007D97F7CB689E363A35A84F0627E1EF7DF
+:101B4000528BF01D1C3ACFB84DBEB4D07DC7E37E9A
+:101B5000CEEDF94D94213788CF5AABC79A9C8EFBB6
+:101B6000C7EB46BEF1B9C2E169DA33DA87F798E626
+:101B7000B7E433A467DA77C9547F9521A49ED9E4EA
+:101B800024A668DC5FE24A21388B7B48225E1EEF88
+:101B9000D5D1BDA2122BF927660E724CBD0BF9E40C
+:101BA0003B268E975E8E27507E9BF95E1CC54D2D81
+:101BB0004C734CC5F92F7A5FA578DF9983051F48D0
+:101BC0006A1D8A718B35AB14E68275B6A571B9A111
+:101BD000C6AF320FE47B023DF8001423B3D3053FB8
+:101BE0000D64E17DC0A72A0D2E339C7FC7CDCCA705
+:101BF000A2DDE8651ECF5C93CEE3869F42BA87B430
+:101C00002636901507FD9D17F8AC9914C8C238897F
+:101C10009A9793294EE2BC99FB2DF13BFA496B0A46
+:101C2000A03DD48B17F1B0D83E26847E6ACA9C0EA4
+:101C3000ACA7C63A1DF9369CAFFD22C9B1AF4432FC
+:101C400094630DFB22799CD3AFC2365B42F0E4CEA5
+:101C5000E67272BCC0239BC1E321D78B78ECF55BA5
+:101C600093FDA8BFC9FAEB4D9EE908075C07CAEFD0
+:101C700073CD4D5928DFCAF9CE8D6AA2799E17F42B
+:101C80003D37BC89C74B9B793C25D6C77C9B895186
+:101C90001C77FB0B168A27399B7C6C2F8E7FF68571
+:101CA0007E0CD7DF96E69FBD9FCA417E04BC55BD22
+:101CB0006809E07ACEBCC0EDCD674C5C1E3B539208
+:101CC000E440BC154DDA3093EC315B2C0AE2FD8C1C
+:101CD000C2CC4958BEB587D387ED1BEA294EBA0A54
+:101CE000D804DEC781B408EFD59CD9DA8FE2C3CE21
+:101CF000BCADE28D28FCBE0ABF7B58D3CC9F213CF3
+:101D0000B673FDE9EC8BFFDE2FF41E9A4CABB66880
+:101D1000E3E0249DC8F205D95C7F5920E07C5F3662
+:101D2000B737D44634AF4FA77572B8039E48EF0358
+:101D30000E13F9F4108C83C854906F3C0574F5347D
+:101D4000DA15B673FDEAEC0E13C58557ED8B7451A9
+:101D5000DCD9CAEB0C1407A17239BCCA00E0A35449
+:101D6000A17EAB26E5F81B49FE66A4C7B66F55C534
+:101D7000388CD970DDDB789C6F31CA8A543E90CAAA
+:101D8000CF88FC99BD0349AE83FE5D785FA9EA6701
+:101D90000F70384EAE7C97911DC34AFCB5A6D38F09
+:101DA00033321ACFBBDA953744E33D40F69ECA5032
+:101DB0003ED1C3E9B2D199887CF57036E75FD57B17
+:101DC0009F31233FA816F743AA5F54B83F19F6196D
+:101DD000DE93AC5E71C313449FBF37B14C58CFF94B
+:101DE000E6C7A242F1B14BF4D359DFECA4FAD550C7
+:101DF0001FFBA95EF14E14CD679B89E24CF478BCC1
+:101E0000E6F62FAAD7D4BE933E9AB91DE5AAF5B33C
+:101E1000633FF914FAFF7A4798D3475F9BE95ED98D
+:101E20003953F36C5CFFB99D61C48FCEC570FEF071
+:101E300025F04F5F36CEE3B647292EEB0F93E93EF0
+:101E4000DC1CBFB65F39EE6F906F63BC549C331AD5
+:101E5000E3FA6ADFE3FC0DF0723BB57FCF44EDF5AA
+:101E6000EBF8A568D7B93F7746103D9CEBC9F172F6
+:101E70006E57369D476D319CCE61BEA9787FEEDCF2
+:101E8000CEEC7CBA9786C20DD04395D06FCFC534C7
+:101E9000A7DA43CADB4C424F0B404DA41B6C0372C4
+:101EA0005F553D97ABAAADAB293E04E36A87155059
+:101EB0001AB0C45E1D1F0BF44AFA63780EDF5F0C84
+:101EC000C74B10F1DB24EF349B917F7B845C58B3CC
+:101ED000431F5FCBCBCF6477DA391DF1329E17E910
+:101EE000D0A7509C49F5B2057391CEABEBD6DE85F9
+:101EF000FB4CCEBFDAC88A500F6B53549A475B181D
+:101F0000BB67129E1BA1E384C86D5F07C761F6041F
+:101F10009257E91CBB92EDE074832726DE135DA681
+:101F2000ACA671D2A43ECBD725E104E030635C5F60
+:101F3000DB6851DECDBAE53CF5EB96F3B1E5707E9A
+:101F4000D496E6787424E2F9772ADDA7BDFCDDE0BB
+:101F5000E8D82EE4B2E0B96E0EC6B7C2FC9391F693
+:101F6000D0EE92CDE5F16A8C9F8579666DD4C67509
+:101F7000E76CD1E6FBEFD0E673F768F3792DDABCB6
+:101F8000F3B036AF887151CFC6FBBBA867638A7ABE
+:101F9000B6C3C2F56CCCA39E8D29EAD9F81DF56CA9
+:101FA000CCA39E8D79D4B3312FE18DFA36E651DF83
+:101FB000C6F25B73B83C5623E224110F48EFECD510
+:101FC00030CD7D9F4B6FF07B1C40077CDF4C37D3BF
+:101FD000BE790A6B90DEC1ED4A3D275B1D18EFBB51
+:101FE00038D633246728DEF738B62219F1666CA597
+:101FF000B8D3F9AFF1B8D39A82301BDA375A977F4A
+:10200000B902C339DDB19E1158FF92A97D1BC2B739
+:10201000B6FE10DD7B6F5DE278EF268E3FB2B3B087
+:10202000CA58929BBC78CEC5768F477DDC375BADB6
+:102030008DF3D6C77DEBE3BDF57420E5BDE74CED30
+:10204000C9C8D74FBE605D8DF33F1926EE9F4CB3D4
+:10205000EAFCFD424E5BA36CC6F37A464E2CF79F1A
+:102060001D05F9BC8B7356A6E55706931CDE995FD8
+:10207000AD18E85E5C52029D438BC49C5295F6B647
+:1020800095C8E7E61AE8DCBC0C72198E77F903955F
+:10209000E487EC0D06CD7AFAF9C335F435607BACF4
+:1020A000EE5E434F4DFD41FBD375F71AFA6BE3E843
+:1020B000A72C3980FAFDE4D58335F52ADC37E8E032
+:1020C00028E62DE4D70A383F5CB0BEA7166F484516
+:1020D000FC2E9ADBD1B612E5D357C2E85E5825FE36
+:1020E0003FE08B95D027DE67ACDC23EE03D76BCFC8
+:1020F000E172710E551A99CF1E1BA4C34A3B73C5DA
+:1021000040FBB9FD8FE50550AF78FB8FC3ECE9A824
+:10211000578C4E447E946A72511C6CCDEECC98253F
+:10212000D0EFA20CCF4339B0CF4E351DFA45299ED2
+:1021300087BBB9BE7772F56FA2284E4CD05BAAC997
+:102140001E8E78DFD4C4E3E3D03EA6C606E9625310
+:10215000535C785F5B70BD413AF88EF004F8E1762D
+:102160009CCA83E4F7E86816EB1DADF8509E96EB29
+:102170005B28CE15D697F773AFC89F12FA855CE738
+:10218000F97E07F21C78FFA2617FAA8AFCDCB063AB
+:102190005B32A4B916CF165C4FE5A6CC3F8F847195
+:1021A000AAFEC4D7F3F9BAB1512350FEDC69721606
+:1021B000437E65D3F366D4B3AB8C7E33C557BEB0D4
+:1021C000C98CF1C5376FDF44DF676FF7523CE51C00
+:1021D0005647FAE769F9EE808047E51865A31DE6E2
+:1021E0001DD68FF38FCA70EEBF03F9E82D7CF7E39D
+:1021F000F276251FE378A6B8779BBDF0FD0DC18F61
+:10220000F5FBA4E3DDC9853D081EFCBEC69F18682A
+:10221000F11957EF8BC957D2685F4CB93280F4B2CD
+:102220003B02FDB8FE9BABD37FDFE5EF2E74B4F02D
+:102230007D50690EC44FC67DF2A689E4DC5A386F22
+:102240008617A05ECDD8F590BA47AA1A7A9D3F2E80
+:102250004243CFD358C83E81FEEEC4A09190FC9477
+:10226000E20C4DFDA95306E8E8BF20584E7CE47A05
+:10227000CDFDBADAC53E874272E618ED77C6E304B3
+:1022800081436BDAD7B249C17A48DF5BB81C5CBBCB
+:10229000276633DAFB2A0D5C7F9AE6E1DFE7EDE79C
+:1022A000DFD934A6D9877D329C7FE6E7A289FC027C
+:1022B000D29E3E0DFFDD05FC4112E9BC1F8EF7E208
+:1022C000D11EA1B93F2DFC81386FC443ADB01BD5E1
+:1022D000E670BB51ADEF9819DF1D00F81BE362A952
+:1022E0009E350EE3239B14B22B62BA98E225B5719A
+:1022F00058D81FC631CE3BAA7A719FE8CB81EE78C1
+:102300001CFF6B3CAE74CE067D1CE46AF247CE43E4
+:102310007B5008DE6EE9E710FE38FF8A9E08BF6238
+:10232000259FEE45EE3860C638BB295362F271DF57
+:10233000E8E94BF275D8CFA47F77BC7B88E8ABA3E4
+:10234000D248F4FB437098E7E276543DDDCD66C792
+:10235000CC784F7CF61EC589FA28D64378F4447AA7
+:10236000D4C1232EF66A3848F874C26B8F3ECE8DE6
+:10237000C369CE7EC51FE8024EFA79770737B99E4A
+:10238000D91ECF78E40B725D7370FED83FCC1FFB73
+:10239000977E08365CBF3F33C83E35CFCDE363F54B
+:1023A000F430E90AB7BBDC79C548E99462ED7EC434
+:1023B00076B82FEEB89240E53F965EE6C13CF9FD57
+:1023C000A76BA313B90EC97783FB81DF1BF8A17735
+:1023D00081F476C73BFA09BBE3503654138F2CF8CF
+:1023E000AABEBD3E1E59CA01FAF3C51B69A0B8C9F1
+:1023F0000E5B3AC91792CF7AC4F9E159FE0DD5F3B5
+:10240000403D3E9B04CD79E311F6BF8591E9F41E72
+:1024100043EA92B804C49337CC4EF1F7DE252AC5BF
+:102420003D7BA19E23443E59B12C2315CF8B130F26
+:10243000653FEB03B9FDC4FDF109C3619C93CB4D2E
+:10244000F15647B0DE89E585A918A77172AD659A86
+:10245000BF0B7835F4E3E743ED831FD17976C1F004
+:102460006ED434685FB3FC95280CF3AF5ECECFF129
+:10247000C40CCF83FDC87FBB699B1DE167DF9487D8
+:1024800076DF35701C607B293F542D2F4C44F9A218
+:10249000E61F879EB5E33DEB25A604943FCF7C0065
+:1024A000E7A142E719C90DA7C3A00BF2A745921DEA
+:1024B000E1B4C25CE8573A6F38F0D795A817E63711
+:1024C000670520ADB578D6F443F97FF9F324B75406
+:1024D0003DBC244B55B1DFCCE8AEEC2632DD26CE38
+:1024E0006D94DF3145F91DE364507EC73CCAEF9817
+:1024F000A2FC8EDFE76FD0CA7FCF087FA1B427F799
+:10250000696CCF47FF9D6F0CCBA9A3F3D69683F2DE
+:10251000FA2225DC89FC6811CA4A98FF2C8CF458F1
+:10252000B625999FB702CFF556EE37FA56DCCFBDE8
+:10253000B11D64B210FABCE98A9585DE9B1DCD629F
+:1025400034F9B1D6644DFD427B9AA6FCE6A47E9A8E
+:10255000F25B1CF99AFC6D392334F52738476BF28E
+:10256000B70FBF4553BFC455A2C94F2E9AAEA97F1E
+:1025700087DBAB299F3A6DAEA67CBA6781267F5771
+:10258000E5FD9AFA77D72DD1947F6B008D14E8A5DD
+:1025900005F52E0BBE9F62A5F4A7AADD887C63D14A
+:1025A000EF326D88EF91630D755DD9F73F14741CA0
+:1025B00037C0F53ED24B6FF13E4E6FF1CECD293C88
+:1025C0007786A21F12A88AF4DD63C948BFFA7AFA97
+:1025D000F29111072F3B0087A35E34DF61043E3484
+:1025E000F2BA83833320FFD3176FE4F91B0EFE2664
+:1025F0001DF20D2F2EE5F941072F63B9F9A5313CE6
+:102600003F9991E8F148FF8E29184F32F2A6F4D590
+:102610004E6E27E9F29EB94C110E785F1BE180697E
+:1026200000E817D38340BF981E06FAAD00FE74047D
+:10263000E817D3A3A07FE2F77F05FD13D37741FF0F
+:10264000C4F4F7A077627A0CF44E4CFFD0308DD2F0
+:102650000F1A3CD4EEC3864A4A3F6AA8A3EF9F34C0
+:10266000D453FA97061F7D27473FB74333CDFD006C
+:10267000F433A23F71BFE97CA81F58FA2BA57FB2A3
+:10268000B18EB54620BF6835C67C610DFA1DBBB75B
+:102690000318D91721F258347345F42779A1979D6F
+:1026A000F8B7F8BEB38FC7DE1FE6F5A7B4C99983A4
+:1026B000553CB7EADE42B7EC9FC4FD7A7DBFA784E4
+:1026C000BCFC657F570F6C27FDEBD2BFDD193713BC
+:1026D000E27F3784C4EBD05F48DC8DF483CB389F36
+:1026E0001BADFC9EB1F473CB781ED95FE1D78CF89B
+:1026F000C3A85546925F228D2C80FDCBB89D51D644
+:10270000E67C8C63185563A37BB589F0DD5C40F5EE
+:102710005C2AA45BFE06F5F3827EF544317F28A790
+:10272000F9177EED213BEC28115780EDADBCDC871D
+:10273000ED47A16D6108A5C49F9EC17BBB05413FCC
+:102740003FD68FE0F503D85FDFBFC37851C17DD39B
+:102750003BB6391FF975EF7936BA17BA717480DE56
+:10276000B322A313C065B2D49FAC222FFD79DB1333
+:10277000C98E3456ECF50C87E766C4A7DB62FF2CE4
+:1027800082F659466FB44F9608F9F93FC15B31E2C2
+:102790004DC253E245E251E223247E8AF0D01D5E11
+:1027A000F5F8D4E351E2AFF0EB205E10AE57E32D25
+:1027B0008857B4E7FEB3E06D8891BF5F66A9B1D2D8
+:1027C000BB683F84C77BDAD9F868A872CAE139854B
+:1027D000E7BCF78AE308E6CBD9E8F1885A597EA12D
+:1027E0009B72CFD7EDA6E8107CDF28F01D9F06F581
+:1027F0007B5C5D5FD693EF31C8FE077753FF9D305A
+:102800001977E1B2E50F0BC63F2E2AE4F02F4A53A9
+:1028100009FE6373E7909CCC6C5CCE74C07FC89754
+:10282000C67FE7A6772DBF613BD073CBC6C76BE5EC
+:10283000D3229DDFFA562197DEAA934BF572A5BFEE
+:10284000BF902BD358DA8F7CAFF257FD89AF5EEB88
+:102850007B95FCBDD371629FA5083ACB70A86C2410
+:10286000D211F3D0397918DF3BCDC377417D94BFC6
+:1028700085F929BD8D05E87C9D008C18F3B733469A
+:10288000F7C80F454C2CC5BB7163078FED8BDF4339
+:10289000DE656BC17D3A4FF5FC9B3DE45DB683E39D
+:1028A0001C74BFF2A03583E42FDC87A6107BE0DB2D
+:1028B000703EF585F3E3109C5F98BE05E7575F58BF
+:1028C000EF6FE1FCC2FCAD394B18B61BEFD0C6ED83
+:1028D000C8F6B7D9C78262D23DFC6ECB7BB517C2B2
+:1028E000F79D98EC71683F7F27E6BA71B8DE776292
+:1028F000120D3CB598291DB8AF6F57F2A1DC07C186
+:10290000F1C6D3787AF84A78EAE128E1FB5F80E7FC
+:10291000175DC1F394909F3BAC7F8C4A4A47FF5DA3
+:102920009478C7F277792AE4CFE0D492315EF50645
+:102930009AE7A8FA11CC3898FC36B908D71A2B8731
+:1029400097DE6EC5B6241A42E377BF307BBEC5F171
+:10295000BFDCA8D2BDF10B2F87913DEAB49FDBDB32
+:102960008A14CF77488F35AA6335BE3FCADEE1EFC0
+:102970009CB1EF0EA54E8AFC1174BA85DFB7AFB1DA
+:102980008EEF128F529FFA0F878BF80813EF454A8C
+:10299000B9A29785BF4B20DF2FEC4ECE1816CEF98B
+:1029A000602F8B781741E015DA513E05FA19067C45
+:1029B0002EE5D170D22FEA7BB8E2070C0DDA113A7E
+:1029C0007A45F891DF8E0A0CA077B98A8EAA144F47
+:1029D0007C50C477DD3CA0CE960E78BA29D3933ACA
+:1029E00000D7A57EA7229F7917D61987F687A383DC
+:1029F0006DA43FFE483D346B80E017792C4F735F28
+:102A00004DD29D6AA3F89D8E0FF87DBC856FF3B8FB
+:102A1000CD853D548AFFD7C7C58D62598FA2BD7140
+:102A20006CBCC9E97704F98B7C07C89264608E108E
+:102A3000393BCC11CE1C21F389C889D5E4239D3DB7
+:102A400035F5A387A76BCA635CFD35E57145059A2B
+:102A50007C0FF7F59AFA89D3C668F2C99E5B35F503
+:102A6000532A2769F3B8EF00EEBDEB6668DAF5A9E3
+:102A70002FD3D44BF35569CA99CF752C2701F93858
+:102A8000FFCB58B55053FE7454118F1FB7CDA67BA2
+:102A90008A994D3FD3F427F19B12C7F1CB1CFC7CE4
+:102AA000F0C17FE4B710782E4CD29E1B63EDA30FCC
+:102AB000DB29D5DA35527E200E6ACE7F950E6A99D3
+:102AC000960EE2791C4FE1DB831D28C7E8F18FFEEB
+:102AD00088D075A23F22142EE88F08CDA33F22B4E0
+:102AE0003EFA2342CBD11F115A3EF8A816FF438F5E
+:102AF00069F17FDD4763FE533C8D68D5D2831E4F5D
+:102B0000379CD6D2C7284F38C1652CC86348EF120E
+:102B10004FD3E03F3AE7993B1AED06373117DD0B0B
+:102B2000F89FC2D7333A7C7DC3560FC5772E2F79D5
+:102B3000391FEFEE9C7FA28FEB79E41FEF0B3EAFC6
+:102B4000B703C87852DF188E4FDFF130E257DF1A33
+:102B50005A23F1FCF8A9DA4A76F964D6FE16BE3F8C
+:102B6000638AF7FC1AF95822460F40F95373EFCCE9
+:102B7000C7736EE6BF585251AE99D987BF27C87246
+:102B80005BE99D16399F99293CFE68DF00C1A79D2E
+:102B90003C0EE9B5015CBE8E74DA290EDA9BCB449B
+:102BA0009C274B9D3910E9F0DDB06CA4B375DCCEE9
+:102BB000D56A72505C8B0FE811FD94286FA33CDC42
+:102BC0005BC8A38D1F5BAD9CEE98E67CEFE7B76A10
+:102BD000E270076CB76BF2039B9334F507ED7768EF
+:102BE000CAF303399AF2C1479D9AFCD063C335F505
+:102BF000AFFBC8A5C98F682DD2D4BFE1B45B934F9A
+:102C000061ED4F223CBF1A90CEE3FB156107707057
+:102C1000BCCCFC6902DDA7917A848CCBF6083AD64D
+:102C2000EB237DCC1E8AF36E4C664EBA0F6215FA0A
+:102C300020D3EA291E11572DE579E6D3C655CB7866
+:102C4000EA4E7D46E82F529F0889A776E1FC653C55
+:102C50007527DEC5FB927AFAFC87C0BB7E1D7DCC52
+:102C6000FCFE57E3FD66BAC722E7A79FD7CD221E19
+:102C700070ABB5EBF7876CB9DC6EF068BADB980B1C
+:102C8000F59E85E389E079D578CE561FC0B7F1E788
+:102C900066E752C70F8F3773105F4F29BEAB9A4B51
+:102CA000EF74D2BD35396EAF5C4EDF863CA5CBF5F7
+:102CB000CD8CE6F15D2CDA4CF72EBA1F8FC335C9E7
+:102CC000CC96D13B49E21EC2DDAB9BD7606845A9DB
+:102CD000B9C9C4DFD5F79BD04E543C06E4C07CE0B4
+:102CE000135B77AEB381BCF66CBD91EC3E19B9F1C4
+:102CF000778204D979AFA40FE8694827C5887FE8AF
+:102D000077C3401EEF3C2E97AFAF50FDAEF33E8031
+:102D100045C3E7B9FED705DD113DCA75FC6FDD0F70
+:102D200090F4AB8793D4AF9938BFFA8A7949F87594
+:102D3000DA4F04FCE4FD0CC702937BB38DEE7914EB
+:102D4000615C99C4DF4B03395DFE04E13194D743E4
+:102D50007ED45DBD4235371AEDE01DCC116DFF010B
+:102D60007BF0FFD2BD09827F77F7BDBAE31357F13D
+:102D7000876EEE7F75479FF4F723EE8185F0091E7D
+:102D8000EF23F0E1EF6B20BFFACA48ED3EDE9ACBAD
+:102D9000E17BABD84F706EDBF2B57C82A15DBF7179
+:102DA000B92AF8C4ECCEDF9FC0EFB3969B48BE664D
+:102DB000CCBD1EE30C3E5F67A2B8D8512E46724CC4
+:102DC000D946C5BF49C173746412CEDFEBD39EC729
+:102DD0003731E70AF47F94AFD27E9F63E3BF53316C
+:102DE0004BFF6E8AD0D7E7FC80BEBE3E579CE34EB9
+:102DF000E624B94BF8FF2B451BBDDCD5E1E77E335C
+:102E0000D4B7556E77A2B83179BE3BD07F13F21E8E
+:102E100008C0333C07CFF165C62EE3F93AE1D94D3E
+:102E2000BCC2799B8857B0F1F88C8E3D61DCBF291C
+:102E3000FD4AA2FE79DF652AC7FAD8DB857C1E77BA
+:102E400021FD497A7F5587CD40FE968E3D91E49FC6
+:102E5000473F4E34D0C159C3EE84E169C1F9795A74
+:102E6000558D1F449F7A96BC42FA62628627908BEA
+:102E700071D846A7D509F9876C07E9FDA86261F703
+:102E8000D2CFB753EF1AC9DF77E9F07179B6A388CB
+:102E9000BFC3017C91E13E927108250CB45448BD3A
+:102EA0008111349F1FEBCF997C259FFB31AFDC4014
+:102EB000ED3DAB4650BECFB2350BF01ECC1D8D7331
+:102EC0004CE8C26E7D72716138346DEDED5F1A8E23
+:102ED000781BAD7469976F13E759AB2EBE5EA625BC
+:102EE000821FCD1B28F9B888435AA2D03E58A8307B
+:102EF0001997447C5CE62F37897C21CF2F5ACEF37B
+:102F0000ADE27DFD6DC28E82EBC614D78D7AFF0EC9
+:102F10006167C175638AEBC6EFC8B7308F7C0BF36E
+:102F2000C8B7308F7C0B53E45BF8BD8CB953F355B5
+:102F3000EE871A17BAEFAE58D9B890FD827EA8D0A6
+:102F40003CFAA142EBA31F2AB41CFD50A1E5E8877F
+:102F50000ACDA31F2AB43EFAA142F36CF82DC13C5E
+:102F6000F2395789263F19E4FC7121FB1BFD50A162
+:102F7000FDA31F4AD39F6781A6FD5DAC5ED31EFDF6
+:102F800050A1F5EFA957347EAA7BC43BA7E51BE20D
+:102F9000887E221DEED48180E77F8BF8C77DA674E2
+:102FA000C473CB5CAE97853B399E9B8A38DE0D8C13
+:102FB000E3B97D3AE179B199E70B797CB29E7ED095
+:102FC000DF33CEC4FD3D98A2BF0753F4F7608AFEFD
+:102FD0009E7199DCDF8329FA7BF03BFA7B30457FD9
+:102FE0000FA6E8EFC114FD3D98A2BF0753F4F760A8
+:102FF0003BF4F7608AFE1EFC8EFE1E4CD1DF83DFA1
+:103000008FA3DFC9149C17CAF17D35FA23D0A146DE
+:103010007FB46BF228C787D647393EB41CE5F8D099
+:103020007294E343F328C787D647393E343F33D7FA
+:1030300041FB0BE5F9D07628CF87E60736F9DE426B
+:10304000DBD9848D170F63DA1AA93CAB00CBB867C4
+:10305000E74B771A413E6B0D53526380739A94DDB0
+:10306000778E83BC47C4FFE5B17603E2DB23DE53F2
+:10307000F70418C55B0EFC5B32953F23EF87E11F19
+:10308000E03D7F0FA3DF2591FE62D9DEC9EC2AA6C1
+:10309000B27E30DF753DFDF8B21EF1CF9079E00DC4
+:1030A000608C57C95F6C2BC078CF6D0685E224B663
+:1030B0002DE571C27ABA7A6C20F78B6E33EC3E88BC
+:1030C000F740DABD0ADD07CE32B2A3A60284535D13
+:1030D000019EBF0F0C8C117EBEBAEBF1BE899CB76E
+:1030E000B46F029FA0FB7323DB8F8D8D867E3CBE69
+:1030F000D1F43B29C5662E37603BD42707F814D797
+:10310000E610FA5E3E90F34D8F8F8FFFABE726F20D
+:1031100076E1BCDDAF9E8B22384E5CA650BCD4C895
+:103120001DCC85F7737F21E63D604740C5F1BCCBE0
+:10313000F878B25FEFC654BAB7E865ADE392C84716
+:10314000A230E4DB126EB0BEC3B83E501B8EA27D2F
+:10315000FA5AEFFDDC3824A610E3E8580BA3772CCD
+:10316000270C795FB35E42FB30EA97CEB56C9F4285
+:10317000EF054FF42D598A6431C1B7E0AD1E587F79
+:103180000B73A639E828A27BB1723EFD5DBB0D70C2
+:103190002CB25C76CC10A620BED9A1B810FA819DC5
+:1031A0003F05F19DEF34D1FBBD2546BB89DE8FE89D
+:1031B00026FEE4B24DC69FE8E4055D9C49E3E28F3C
+:1031C00052D19EBC30D240F6DF85AFF0DF03F06C09
+:1031D0005088AF4939C82BE2D42E2F7BABC754841B
+:1031E000FB6E13F527E34F6A33FCA9068CABEFB9EE
+:1031F000292F562539E000F2C373BEDFDC391CEB02
+:103200002DE7EF585E5E764774807AE2FE9A0A01F7
+:10321000AF0A11C7E4C507BDD5E0EF69C9FB1DAC16
+:1032200089CB7BD29EE3FDDDE023885FEF33E25D57
+:10323000E9555EBA97AD8F239ABBCC44714773753D
+:103240007261B5900BAB7F402EFC78A04E2E94BFE0
+:103250009722DA30B5D78718B727EF25969AF8FE68
+:103260002FDDCDC80E5BBA64AC81DE417E85D34DC7
+:10327000E9122EDF94BEEAA2FB85525E7C4FC83174
+:1032800093AEA410DCFF28E4963B30BE12E05BDC7A
+:103290001A26E2B092299D7A85C75B4EB2713ED064
+:1032A000FA067F07A2C367E1F2D461C6DF31D3D14A
+:1032B0006589D16FC00B77CE914097909F80721037
+:1032C000F4370DE5A238A4F3B4428ADF2B52E8DECE
+:1032D0008B9ECE8B4D756F617C68F156E6F4B150D4
+:1032E0003A07FAC5FE7C0ABD0FE0117AADA45F3D36
+:1032F000BDCF8C10F6281BB73775DA255046C54769
+:10330000BA7DA6A918FF3A137D7B3D39C160DC590F
+:10331000642E2F8FDB659ABA0CEF2A7463A7507F57
+:1033200066267878E43B08DDD80DD05E807CF2EE2E
+:103330007BF3CD65217CF2E4A0318307F508E2BB85
+:10334000ACF3BE5F2EBD0BBAF0A14CFA3D9CEEE48F
+:10335000E172802BEE8B99D1ADF7E12FB315E431FB
+:10336000D7B824FC7D41261F210F601CE10C91BFC2
+:10337000272FEFCFAB6C0417CAE7ED8A9B8A712128
+:10338000B5D6D6F14876F3733D45788F31C89FDCCA
+:10339000AE1405F9537E0075C29BB3F83D2FBD3DB9
+:1033A000E29E3C5E5F6F9728CFE57C5BFE2ECA896C
+:1033B00087F6EDC2F34ACEFF4437BFC330358FCB1B
+:1033C000B3FF53F720F4F71F66F5F414E5C17CD77B
+:1033D0001BF87DFE9E6A1313F621F20B4B7EC1C4CF
+:1033E0003B1841BCBBE81DDDC687147BA87DCAB372
+:1033F0004AE1F7E8BBB1E3B09CF627B742BB990DB1
+:1034000066FA1DBFE7B238FD3C07F443BF97623E42
+:10341000F696352D08C74FEB7F69A2DFA561814C79
+:103420007C7F67465D9813F9F1C941EE9938EF88C2
+:103430005C27F1A1C183387D65C4BBBD7978FF6E7F
+:10344000F58167F13D81F92D69F47B25DEFDF92BCE
+:10345000F09D9393833CB3B1DC6BB3D37B1AF396AB
+:10346000C5D0F9353351DC0B65EDE46793F07F305F
+:103470008FEB89D73999F8BD2D71DF01186489A6C2
+:103480009E88EFD6ED0F6927D4DB19F4EF4B7467F4
+:103490005F90F604B41F9843EC8CD23E61CA393178
+:1034A0001DE58652B3F65EA24C7F2DE62FF5C0597E
+:1034B0009DE756EEF844948FD72A767A6FD2E69835
+:1034C0003A02F215474D18D9C98A631D667C7FA060
+:1034D0001DF08BF1D165B05F91CF948A38AD8A0D24
+:1034E0002368BF55F821EDE21D4E99DEB5F650EF89
+:1034F00057917E022EF25B56D85DE6D8907D5FDE56
+:10350000A468DE1D90F9E7F2545A672988E308BFE2
+:10351000BBEF4D33E3DB3EA5204660FCDFAF057D0E
+:10352000C876508FE2418AD3D911FE0E3CCC3B8D38
+:103530008F5710D27F5913BF372DF3509FE49F1739
+:10354000F222A93FAF1DD69D86A99DE609702038BD
+:10355000B5AF81FE1C340EE1A33CE037A1BE5D8A0D
+:103560007128909F61F79B709CB265FC1D13CF6A18
+:103570003E8E67558C7920CA4746BBB937C22F9C0F
+:103580009F57303F92232B002E781F0BEFBBE1D9C2
+:10359000A2878F57CCB7A22986DE51087E5F6B4287
+:1035A0007C4CEFE65D844F05DECB968DA6FBEB15DC
+:1035B0004617DD73F008F87EBE20EC61F40F4C5F17
+:1035C000F784290DFDF882CF7C2AE05A9C1EC8A4FE
+:1035D000F78A168439719ED3ED4DB4BE4EF83E0E77
+:1035E000F050F09D1B37C117E8C287717B15EBB413
+:1035F000F80CCE87C3B7629D97F6DB6CA3C76C0F40
+:103600009DC786039978AF6A3AEC6F7C5782D93DA3
+:10361000745FF28BC7A7A6D23A619E08D748A7630A
+:103620003CBE3F0474C2EFC188F5C87BDD72BCCBE1
+:1036300079FC1EFCE51FDC972E926B1A01BF68F720
+:10364000EE6E5F9A9171C3B8E60AFE3B12FA7D2ACC
+:10365000F7A7DC97729FCAFDFBACC91D4852827C5C
+:1036600006CED9BA97BB80D3E0411C0F33045E016C
+:10367000AE8743EF79F51AC4F15A9AAEDDEFD81F41
+:10368000F66B95E5630299F82E93AC2FC72D8DE567
+:10369000ED90EE91DEAC830C9DF517527DED3D95DE
+:1036A000F24E7EB1637902F28BDD0AF783AE39D434
+:1036B000FBA728BFEEE4F2EBB99AADF3F0BC644689
+:1036C0007F6AE8FBFEB340CE413E315B9CCF158163
+:1036D000AEF9C553599EE44121FBB9E2B19D591E93
+:1036E000CE6F02C86FFEB2F3F53F5DEF089EA77282
+:1036F0003D65ABDE37796DA1F0E37ACEC3391D7439
+:103700001FAFDC667660BC73F9322FF15F960472EE
+:10371000A112127FA6A30BEF3285EE9195D70FF37E
+:10372000ABFF837CBA7C7509BD7B20F126DF6791F6
+:10373000E7AB9CFF4831FF9B06F1F633047DCFA831
+:103740001C6D4E8E27B91BC32CD974F17D7A85F67A
+:103750007B27DE3AFDD7B92B70BFE0FD22D24F5652
+:103760009BB8BD6F07B73F9E5BB8EFF77742BDB31D
+:10377000EB37A532558B379453670B79758EB0FFB5
+:10378000758137F7A090389E39CF71BC95EFFADD7F
+:1037900067F89E5869BAE0776BF83B0065CDBB09C6
+:1037A0008FD357AD35A5213F1A94A6E1E3E575F90E
+:1037B00076B42BCF58B5C9847CC223E1A0DB0FA51A
+:1037C000224E58C219CF2525C4BF21EB237FC4F751
+:1037D000EFEF5D101685F13C729C87049D97D7C56D
+:1037E000C4E278E575DE5FA03E24CF03FD3A4F8644
+:1037F000F1FD5206FDE1BE3D39DA99BA303728CFE6
+:10380000EAEBFBC4BE7BDAC47FA72625A2F9058AB2
+:103810006B981FEE44FED1B76FAB1FC745FAC67950
+:103820009B0DFC776DFAD6B47E85F3E8CB785C0D02
+:10383000A6F83E16FA171220BFD9C0EF6FA5AB3C11
+:10384000DD26E003E5012C67F1ADF4FB1A2171B32D
+:103850001AFA35B32DF4FB89E67846EF9B497A9541
+:10386000FD487A95F4DCDDFA9EBDC6F59D4CE3F08B
+:10387000348BDF4DB9E6F559F8EFE8CA75C9F9811F
+:103880000CEFA2F73D1E1848F69E934B9CA91837E3
+:10389000D9FD7AD7152674B15EFD3AE5BE91B1F037
+:1038A0009DFEAC26EE7738A9C0F906ED4E2E08A392
+:1038B000F836B9AE1F6B0F3F382856D8775A2351C8
+:1038C000CE2C0D0FDE9747F81DAFE7BFAF2BBF4BD8
+:1038D000B940BE3327F9F7A93A716EB2D635B8BFF1
+:1038E000597D06BD7F72BCE96424BEC77272349FE5
+:1038F0009F6C77AF89DF4F66916607DE138BB8F751
+:10390000FDC244F40FAD4BCB57A0DDDDF5838FE353
+:10391000FBE3772F4B24FD7E96CDB102CFC559BE78
+:1039200034F20747ACCBFF02DFD19BB56C00FD6ED4
+:10393000EFBD0A73933E29F484D9ACF38FF4843934
+:1039400082AFCD417E89F7A5EA0FD1BB79B39D61E6
+:10395000F978BECFD9C0F58462035B85FEC43E8D85
+:10396000EEF1C8C7DA9F54F8EF3E6FD4BEC3959C02
+:10397000EDFE0CF98CFEDDBB7B4DCD2E5C07037993
+:1039800004ED4EB36C6E92EB4B05BD1C5FD746BF8A
+:103990009789F0A6DFCBD1D96FFA98F93DE2F648C6
+:1039A00003D9E300EFEFE1EF91E17BEB163A6FB45F
+:1039B000F69B3E0F0EA7DF6B93F7842A84DF49D274
+:1039C0008FF45FCDDA3499EE0FCD427BCDE0E0FD90
+:1039D000A915EBC6D2FB4E156B0BD7E3EFDCA40A9F
+:1039E000389E32B696207E4E6F4A8CC57BB915B58F
+:1039F0008D59785FA862D34ABA37747A5318DD1BA1
+:103A00001A672F1987BF1F327B23BF9F27F7A3CDCC
+:103A1000C9F76355ED58BAF7F3FF00B910AD8C0044
+:103A2000800000001F8B080000000000000BCD5636
+:103A30005B6C1465143EFF3F7BEFECA5ED527AA161
+:103A4000EDB6E5B2EAB69DA51403189834802412A9
+:103A50005D0805368176088114686B4593164364CA
+:103A600061951088711F5AA104CC52A1BEA8D986B5
+:103A70004621AE66A541A236B18117129266FB526D
+:103A80002E11BB564D69A2E039FFCC660997C44799
+:103A9000E7E5ECFFCFB97FDF39B3ED0F473EF1D457
+:103AA00000ECAA02F02C01F82B91178F3080F6431E
+:103AB000972A240E10B06A56650EC03E9EDCBCCC20
+:103AC00007708FC5074B84BE6FAE47067844CFAAF8
+:103AD000A7E5E421009F15A0E3BD9BC2CF7D3EFA80
+:103AE0007A18EDDB3B2EBAC8CFBEBE1B4B3D783FEC
+:103AF000B7462B541AC9EFB9418F0400A7CED5851C
+:103B00006A01BC0AFEC6FBF505A1CD61CC2BF3A36F
+:103B1000A40CF89E1FAFED1226DD903B6F8FBB2DDE
+:103B20001000D05260F190F480A500E51D097A12D2
+:103B300028D75743EB463977BF48417BACF38E3BE0
+:103B40005611C2FB3D83272B7C28EF3AF5F3B6C113
+:103B50002D3F810BF5CF5B2D407626B02868B7331B
+:103B6000C2D4384A682B0028C9C50F2A7922FF3DE4
+:103B7000A730A9C2DC3D405CDCDF35C13ACAA332C4
+:103B80009A09BE85F29629B50BB0CE5B5D7625828B
+:103B900058C88A4FE4732B26ADA5FBC83B0C1630E2
+:103BA0003A5F74CEC7F82D6EE8227BE792448A7B99
+:103BB000B1CFC3F98BA97DF8702802E8F4E8873506
+:103BC00092BCB60CDFEF1F621E2BBADC7FF9EA5AFB
+:103BD000D0CF00ECF9FDDCFB6005F81ECB7BEFF0ED
+:103BE00090C587F1DA3FC77A317E7B62E88752F46D
+:103BF000D3796947831E3706B014F3A09F18A773C3
+:103C000058EF4BC7F084656720E76787BFE0681906
+:103C100062BB29D1B8A50FF576106ECB910F752F29
+:103C20006C3D6C22E911FD0153A622E40438EEBF7D
+:103C30006ED1C8CFFB863FFFF5A3D5A2DE0D85F080
+:103C4000181F9A15B3B0CBDA633F845DAAC3710C19
+:103C5000EA01D44ED94432DA21BB489EE9E27E1310
+:103C6000F655650E45C27EF7D85C75E00698B1EB57
+:103C700032E9D065370F0DEDC61467F8981D90F73F
+:103C8000DD528C915C15E862D869307BB57D341FBC
+:103C9000C59060201A916294F7D4B7B71B28FECA6A
+:103CA000CAF41F802999D9CB5B57233FDE568CFA83
+:103CB00002E906E2F99C2BD04AFC3A6B8663F6C512
+:103CC00054770836D69217FC4DB8CFF2F805CC2FB2
+:103CD000C9529F92FF6CBD9F115FD14FC82A1F63CD
+:103CE00098E79F95DA41CAE30D66AE0D72C2405A5D
+:103CF00040FEA7CCFA7B889D546DC88B269D16503C
+:103D0000CE210248594B69B14CBC66AA0A3D18FF46
+:103D100048E0CA4EE2C7898C0DAC18376AF4A32973
+:103D2000E39860A8575EBA8E431DEAFBBCB00DED68
+:103D3000AF0478C48A799E005B9CF4C1B6464DFB03
+:103D4000F5188FAAD13FB7AB423F796D96A12C935E
+:103D50007E1F71A37E593753A2A8D3323D79F6173F
+:103D600094DB201EA4BEAEF66A7DB40FC6A7D74D65
+:103D70006888EF094FC2467346CFE3F9270FCCBAE4
+:103D80000A782EAFA9CCE4175F2F21695318DA35D2
+:103D900025A594B5EEE97CA68A7D268A837A294EEC
+:103DA000FA328F3346FA233729BF269B9C925C64F4
+:103DB00067FE356DCBD9C15879FEE44B20207E5487
+:103DC000065014D5715B69CC611697CB0A17B85CA5
+:103DD00036F0C9F64F248FF3B1DFA6CFC777F2E0F4
+:103DE00076E24F765EDF34EEA71F54BB69BF4C27E7
+:103DF0006BDC1078FE7CDEC0FD0A8B005EAB52BF30
+:103E0000A77EE1A3DAD07FB3D11FC41BC8AF64F88B
+:103E10006D36FAD42C73BD2F9B9EE88BC1932C0F6B
+:103E2000B2796771CEE207EF8E5D755709DC6A3FA4
+:103E30000281D7CFC4BBF1D9D10F70ACA0545227A7
+:103E4000B4AAFF235E29FB22E475A68F2B03C47F4F
+:103E50006AFC6221558EF5811FC43E68911CCAF12F
+:103E600067EC038DF6413DED839898F3199EB9CA2E
+:103E700019ED832E712E86CC61139EC779DA49F92C
+:103E8000A6EDC87A94EE60B5D8E36534D1353A4EE4
+:103E900034D7670F38078EA37E94A9FD36B48F9A66
+:103EA0008D79DF23C72FE0FD549C47CC18AF373FF7
+:103EB000DEBF1BEF7B9BE72911ECD314187A6D0E44
+:103EC000B11756702ECE9970517CA08AF471AEB1A4
+:103ED000CEDEF08BE23BFED543744E752F00FD7DA8
+:103EE00010169EA2F71BFCC2DF37D93DF3A153F891
+:103EF000EBDDA09638C4FB224EF6870B357BB091E4
+:103F000070D5F5F08F80D03B7D5A2D213C4E6FB49B
+:103F100008BD8F5928BC8BFCD4CACA05F49B0E3B44
+:103F2000BE1CD4E14831BC1FEFD1EBCDF2F7D585F3
+:103F3000FA1EAC8C4CF403B628D204FE2EE4FD38F5
+:103F4000F1B03E870F53118B821C4E593E46CC88F0
+:103F50009757C7EB087B1A2FAF8117EB41DEBA08E2
+:103F6000B784E8FF0CD771E896209D8735495C2916
+:103F7000B6A21CF36AF3F53AC74AE87D8B35DD1823
+:103F80000B109ED09678C61CD6D3929D23EA63343C
+:103F900067AD06CF5BB37C3CF8041FD3F3F227F385
+:103FA0000C3EA2FD4D472848F1EEB31B4BE972F4DD
+:103FB0001F69EBB3E22C0FEA7BE437ABB68CF4E17C
+:103FC000FC5C2EF688479FEBD1E0ED72FACEC0DFA5
+:103FD00023F3E8BBD35F187A85F4ECF333168DFA3C
+:103FE000599231533DE3E17BE5F47FA6B5E79A981A
+:103FF0009BFF9AE7BF3AB4AF4B200A0000000000D5
+:104000000000000000000000000000180000000098
+:104010000000000000000040000000000000000060
+:104020000000002800000000000000000000001058
+:104030000000000000000000000000200000000060
+:104040000000000000000010000000000000000060
+:104050000000000800000000000000000000000058
+:104060000000000000000000000000000000000050
+:104070000000000000000000000000000000000040
+:104080000000000000000000000000000000000030
+:104090000000000000000000000000000000000020
+:1040A0000000000000000000000000000000000010
+:1040B0000000000000000000000000000000000000
+:1040C00000000000000000000000000000000000F0
+:1040D00000000000000000000000000000000000E0
+:1040E00000000000000000000000000000000000D0
+:1040F00000000000000000000000000000000000C0
+:1041000000000000000000000000000000000000AF
+:10411000000000000000000000000000000000009F
+:10412000000000000000000000000000000000008F
+:10413000000000000000000000000000000000007F
+:10414000000000000000000000000000000000006F
+:10415000000000000000000000000000000000005F
+:10416000000000000000000000000000000000004F
+:104170000000332800100000000000080000333069
+:1041800000100000000000020000332800100000B2
+:104190000000001000003A78000000000000000855
+:1041A000000000000000000000000000000000000F
+:1041B00000000000000000000000000000000000FF
+:1041C0000000000000003120000000000000000896
+:1041D00000003360000100040000000100003368AB
+:1041E000000000000000000200003370000000002A
+:1041F000000000080000337400000000000000020E
+:1042000000003A70000000000000000800003A4082
+:10421000000800000000000800003D880040000089
+:104220000000004000003A500008000000000008B4
+:1042300000003A60000800000000000800003A8812
+:1042400000C800000000009800003C180098000022
+:104250000000002800003C580098000000000028E2
+:1042600000003378036000300000036000003EB0BF
+:10427000000800000000000100003EB1000800003E
+:1042800000000001000020080010000000000010E5
+:1042900000002000000000000000000800000000F6
+:1042A000000000000000000000000000000000000E
+:1042B00000000000000000000000000000000000FE
+:1042C00000000000000000000000000000000000EE
+:1042D00000000000000000000000000000000000DE
+:1042E00000000000000000000000000000000000CE
+:1042F00000000000000000000000000000000000BE
+:1043000000000000000000000000000000000000AD
+:10431000000000000000000000000000000000009D
+:10432000000000000000000000000000000000008D
+:10433000000000000000000000000000000000007D
+:10434000000000000000000000000000000000006D
+:10435000000000000000000000000000000000005D
+:10436000000000000000000000000000000000004D
+:10437000000000000000000000000000000000003D
+:10438000000000000000000000000000000000002D
+:10439000000000000000000000000000000000001D
+:1043A000000000000000000000000000000000000D
+:1043B00000000000000000000000000000000000FD
+:1043C00000000000000000000000000000000000ED
+:1043D00000000000000000000000000000000000DD
+:1043E00000000000000000000000000000000000CD
+:1043F00000000000000000000000000000000000BD
+:1044000000000000000000000000000000000000AC
+:10441000000000000000000000000000000000009C
+:10442000000000000000000000000000000000008C
+:10443000000000000000000000000000000000007C
+:10444000000000000000000000000000000012C892
+:10445000008000000000008000000001000000005B
+:1044600000000000000040000490000000000490E4
+:10447000000019C8000000000000000800004948C2
+:1044800000080000000000080000492800080000A3
+:104490000000000800004938000800000000000883
+:1044A00000002008001000000000001000002000A4
+:1044B00000000000000000080000401004900040D0
+:1044C00000000040000049980008000000000001C2
+:1044D00000004999000800000000000100000000F1
+:1044E00000000000000000000000000000000000CC
+:1044F00000000000000000000000000000000000BC
+:1045000000000000000000000000000000000000AB
+:10451000000000000000000000000000000000009B
+:10452000000000000000000000000000000000008B
+:10453000000000000000000000000000000000007B
+:10454000000000000000000000000000000000006B
+:10455000000000000000000000000000000000005B
+:10456000000000000000000000000000000000004B
+:10457000000000000000000000000000000000003B
+:10458000000000000000000000000000000000002B
+:10459000000000000000000000000000000000001B
+:1045A000000000000000000000000000000000000B
+:1045B00000000000000000000000000000000000FB
+:1045C00000000000000000000000000000000000EB
+:1045D00000000000000000000000000000000000DB
+:1045E00000000000000000000000000000000000CB
+:1045F00000000000000000000000000000000000BB
+:104600000000000000000000000040000018000052
+:1046100000000018000043000040000000000040BF
+:1046200000004300004000020000000100004301C0
+:1046300000400002000000000000300000400000C8
+:10464000000000400000000000000000000000002A
+:1046500000003000000800400000000400003004AA
+:10466000000800400000000400004B00002800008B
+:104670000000002800004B50001000000000001057
+:1046800000003800008000000000008000003800BA
+:104690000008008000000002000039000020000037
+:1046A00000000020000020080010000000000010A2
+:1046B0000000200000000000000000080000510879
+:1046C0000008000000000008000051200008000061
+:1046D0000000000800005130000800000000000841
+:1046E000000051C00008000000000001000051C19E
+:1046F0000008000000000001000039400010000424
+:1047000000000004000051D000300018000000102C
+:10471000000051D800300018000000020000000026
+:104720000000000000000000000000000000000089
+:104730000000000000000000000000000000000079
+:104740000000000000000000000000000000000069
+:104750000000000000000000000000000000000059
+:104760000000000000000000000000000000000049
+:104770000000000000000000000000000000000039
+:104780000000000000000000000000000000000029
+:104790000000000000000000000000000000000019
+:1047A0000000000000000000000000000000000009
+:1047B00000000000000000000000000000000000F9
+:1047C00000000000000000000000000000000000E9
+:1047D000000000000000000000000000000023E8CE
+:1047E00000800000000000800000000100000000C8
+:1047F0000000000000002008001000000000001071
+:1048000000002000000000000000000800002DA0B3
+:10481000000800000000000800002DB8000800009B
+:1048200000000008000024E802D00028000002D0A8
+:1048300000002E58000800000000000100002E5962
+:10484000000800000000000100002D90000800009A
+:104850000000000800000000000000000000000050
+:104860000000000000000000000000000000000048
+:104870000000000000000000000000000000000038
+:104880000000000000000000000000000000000028
+:104890000000000000000000000000000000000018
+:1048A0000000000000000000000000000000000008
+:1048B00000000000000000000000000000000000F8
+:1048C00000000000000000000000000000000000E8
+:1048D00000000000000000000000000000000000D8
+:1048E00000000000000000000000000000000000C8
+:1048F00000000000000000000000000000000000B8
+:1049000000000000000000000000000000000000A7
+:104910000000000000000000000000000000000097
+:104920000000000000000000000000000000250062
+:1049300000400000000000080000250800400000C2
+:1049400000000028000009C001200010000000083D
+:104950000000000000000000000000000000000057
+:1049600000000000000000000000402002D00028ED
+:1049700000000008000030000000000000001000EF
+:10498000000050990000000000000001000050B03D
+:104990000000000000000002000045A00090000898
+:1049A00000000008000000000000000000000000FF
+:1049B00000002960000800000000000100002961DB
+:1049C0000008000000000001000029700008000439
+:1049D0000000000200002978000800040000000424
+:1049E00000002FB0000800000000000400002FB4F9
+:1049F000000800000000000400002FC000000000BC
+:104A00000000000800002FC800000000000000089F
+:104A100000003000000000000000001000005040C6
+:104A20000001000100000001000050000000000033
+:104A30000000002000000808001000000000000432
+:104A40000000080C0010000000000001000008B782
+:104A50000000000000000001000008B60000000097
+:104A600000000001000010000030001800000004E9
+:104A700000001004003000180000000400001008BE
+:104A800000300018000000020000100A003000187A
+:104A9000000000020000100C0030001800000001AF
+:104AA0000000100D00300018000000010000100E82
+:104AB0000030001800000001000010100030001845
+:104AC0000000000400001014003000180000000472
+:104AD00000003000010000800008000400003004E5
+:104AE00001000080000800040000000A000000002F
+:104AF000000000000000306801000080000000019C
+:104B00000000306901000080000000010000306CEE
+:104B100001000080000000020000306E01000080F3
+:104B2000000000020000307001000080000000045E
+:104B300000003074010000800000000400003066B6
+:104B400001000080000000020000306401000080CD
+:104B50000000000100003060010000800000000241
+:104B600000003062010000800000000200003050B0
+:104B700001000080000000040000305401000080AB
+:104B80000000000400003058010000800000000414
+:104B90000000305C01000080000000040000307C58
+:104BA00001000080000000010000307D0100008055
+:104BB0000000000100001C180010000000000004AC
+:104BC00000001C30001000000000000400001C3831
+:104BD00000100000000000040000000000000000C1
+:104BE00000000000000000000000000000000000C5
+:104BF00000000000000000000000000000000000B5
+:104C0000000000000000000000004C100008000040
+:104C10000000000200004C1200080000000000022A
+:104C200000004C14000800000000000400004C20AC
+:104C3000000800000000000800004C3000400008A0
+:104C40000000000800004C00000800000000000206
+:104C500000004C02000800000000000100004C04AD
+:104C6000000800000000000200004CD00008000016
+:104C70000000000800004CE00008000000000004F4
+:104C800000004CE4000800000000000100004CF0AF
+:104C9000000800000000000200004CF400080000C2
+:104CA0000000000200004D000008000000000004A9
+:104CB000000050000010000000000004000050043C
+:104CC0000010000000000004000050080010000068
+:104CD00000000004000014000008000000000002B2
+:104CE000000014020008000000000001000014048D
+:104CF000000800000000000200001410000800007E
+:104D0000000000020000141400080000000000026F
+:104D1000000014160008000000000002000019B88E
+:104D20000008000000000008000014200008000037
+:104D3000000000020000142400080000000000022F
+:104D4000000019C8000800000000000800002C1036
+:104D5000000800000000000100002C110008000005
+:104D60000000000100002C120008000000000001FB
+:104D700000002C13000800000000000100002C00BF
+:104D8000000800000000000200002C0200080000E3
+:104D90000000000100002C040008000000000002D8
+:104DA00000002C30000800000000000200002C323F
+:104DB000000800000000000200002C340008000081
+:104DC0000000000200002C2000080000000000018C
+:104DD00000002C21000800000000000100002C222F
+:104DE000000800000000000100002C230008000063
+:104DF0000000000100002C24000800000000000159
+:104E000000002C25000800000000000100002C26F6
+:104E1000000800000000000100001400000800006D
+:104E20000000000200001402000800000000000161
+:104E3000000014040008000000000002000014122A
+:104E400000C00018000000020000141000C000188C
+:104E5000000000020000141C00C000180000000840
+:104E60000000141400C000180000000800001427FF
+:104E700000C00018000000010000142400C0001849
+:104E8000000000020000142600C00018000000010D
+:104E9000000015900008000000000008000015A0A8
+:104EA0000008000000000008000015B00008000025
+:104EB00000000008000000000000000000000000EA
+:104EC00000000000000000000000000000000000E2
+:104ED00000000000000000000000000000000000D2
+:104EE00000000000000000000000000000000000C2
+:104EF00000000000000000000000000000000000B2
+:104F000000000000000000000000000000000000A1
+:104F10000000000000000000000000000000000091
+:104F20000000000000000000000000000000000081
+:104F30000000000000000000000000000000000071
+:104F40000000000000000000000000000000000061
+:104F50000000000000000000000000000000000051
+:104F60000000000000000000000000000000000041
+:104F70000000000000000000000000000000000031
+:104F80000000000000000000000000000000000021
+:104F90000000000000000000000000000000000011
+:104FA0000000000000000000000000000000000001
+:104FB00000000000000000000000000000000000F1
+:104FC00000000000000000000000000000000000E1
+:104FD00000000000000000000000000000000000D1
+:104FE00000000000000000000000000000000000C1
+:104FF00000000000000000000000000000000000B1
+:105000000000000000000000060022000000000078
+:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex
new file mode 100644
index 000000000000..54f36f1d256d
--- /dev/null
+++ b/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex
@@ -0,0 +1,13178 @@
+:1000000000004F48000000680000070C00004FB8D7
+:1000100000001ED4000056C800000094000075A027
+:1000200000009EFC00007638000000CC000115386E
+:100030000000DC6400011608000000940001F2706A
+:10004000000040180001F308000000A4000233285B
+:100050000000F378000233D000000FFC00032750AB
+:100060000000000400033750020400480000000FA5
+: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
+:10061000081807D800050223071C00002BDC000087
+:10062000071C80002DE90AF8071D00002F521673E1
+:10063000071D800015DB2248081DB0B049EA0225DD
+: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
+:10268000020E012C000000000730040000C800000A
+:10269000083007D8000503B207340000332C0000CF
+:1026A0000734800030AC0CCC07350000353318F807
+:1026B000073580002A7126450736000018DA30E217
+:1026C00008364670373203B40130000000000000C5
+: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
+:102B0000072400002B0B00000724800015080AC3CF
+:102B10000824AA10692403D001200000000000004E
+: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
+:1040E00002020104000000000728040000A10000F3
+:1040F000082807B8000904CA072C000034F700009C
+:10410000072C800039250D3E072D000037CD1B8878
+:10411000072D80003292297C072E00001AF33621E9
+:10412000082E4390378E04CC0128000000000000C8
+: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
+:1066000000007FF800007FF80000069200001500EF
+: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
+:1069F00000007FF800007FF8000003400000150051
+:106A000010000000000028AD000100010022000677
+: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
+:1075B0008A37B231306CE344F0E98159181818F871
+:1075C00099C8D7BF0668C01620BE0CC47B5848D7E0
+:1075D0007F5E1AC15E20C9C0700488BBC51918EA55
+:1075E000A510E296320C0C3780FCC5503109A09EE4
+:1075F00069D2E4BB79140F1E9C648ACA773586D0A1
+:10760000374D2074329ABC1B545E500F42A79862CB
+:107610003757488F38FB1354D0EC57C1AF3E5D034A
+:10762000951F8EA6DE0FCA0700DCEC914ED8030032
+:1076300000000000000000001F8B08000000000098
+:10764000000BED7D0B7815D5B9E89AC79E3DFB99E7
+:1076500049086127049C8400C1F2D84280A0142705
+:107660001030B6D46E5E12BD081B1F95872411D34F
+:10767000635A39CD401E2401243E4AE92DD50DC55B
+:10768000367A6D1B6D6A698FF66C442D9EDBD303D1
+:10769000942AADE0096A2D58A0B1A71C68BFB6DCDA
+:1076A000F5AF47F6CC64761E3EFAF57CB7F193C988
+:1076B0009A59CFFFBDFEFF5F2B0A2A443957217428
+:1076C000057EAE47C8101042D3534F744F86887260
+:1076D00010FABC8AC8CF255F7832CA40A84EA5CF21
+:1076E000FBFDE17DF06CAB4728391EBE8F4EA0300C
+:1076F0004201848AE56C68E18F3E5100CF9A29B13E
+:1077000049E439139E594844683894F3B57703B473
+:10771000EF2B12FEE764BC0CC693E82B24A3D268BF
+:1077200092B47F00A119A979A09ACF6AB1506ADEFC
+:10773000CEA7A42928C9EA5E817FA41519F160FAB1
+:10774000FA752785EFBE64A93F1685B2C9BC6424CB
+:107750009379B1F60899C83A3F673F97EAD1775FC6
+:107760001ADB176EE9C6E5706BA957C9B3B95E435A
+:10777000492F42B899D139113F83C8D837B16FBB6F
+:10778000722430F8B1F9C0383AAE8FFF4718EE8D49
+:10779000D92811001CA2B80D6E8DC1C5AAE1D21F57
+:1077A0007FA26C0CB76236E7C2BEEBF5C1BC301CE1
+:1077B0007C302F17782E87794DEF3B2F5F91735ECA
+:1077C0006B90153E439D977F024247001FB2811088
+:1077D000C1CB7DB6FE44CD30BB5DFA438C2E649D9B
+:1077E000AD6F90780A148BA9F1010EBADF465FDE07
+:1077F00048969DDE9C740DF020F86A67F0894994E4
+:107800001FCC141EF13350AA0BA890148F00DE2257
+:107810000CEE913B9BEF15315F8551A2651CE6870D
+:1078200048F7EA85C067E193379E459331FCA25340
+:10783000D579784D5A89FED002FC0C4CD404A0D7DF
+:1078400036E0B36BA1BF5BCC325C6E80CEF270D100
+:10785000BCC93009DC0C1BDC30E47419973DF06BBB
+:10786000A10BFC502F1E842BDEBEEDD3C1CF832C89
+:10787000F823FCBCD1469769F11EA7ED4CFC1FE034
+:107880002BCBD18F566EE7F330B294F1F7A7E01708
+:1078900002EF7BFF26E365A27DAA5E82D75B2C6A9E
+:1078A00009A88FF44C1997031532023996998D0E59
+:1078B000628C0C889746842A80FF11EA448B26A5A7
+:1078C000E6F7AF8CBF723FF7E8EA66CC4F174B8301
+:1078D00051E0AF8886D0B0ACBEEBD9CEE44B6F3967
+:1078E000FA2C8A4F84F1122D85785E66548C3E0105
+:1078F000F3297E518B5BF8E574AF7C71D207D2E53A
+:10790000194C1E60F848C5A2E19BFCE1E943FA80EE
+:10791000F4118C2B36BE1C2ABE2E0C913E3EEC7808
+:107920001CAF7DF96A33C36BA30AF2AC455FDCAFD1
+:10793000BEEA8BD77D08EA078A91917069F75F5696
+:107940007DE17C5AE4BB538E4A236654EEED0F6F03
+:10795000D97678F07E7D7592FECE305C9435225FCC
+:1079600015A6075A230F9B08D3DD45903D181E52DC
+:10797000FB354928A32244E810FF24055CF6458C1A
+:10798000441BA18304C10B9F9F57176DF095B3ED66
+:107990007218559A8275FEBE3A85CC4381F1B2C108
+:1079A0002EC01D6250C84194F485A1069D3FA8A435
+:1079B0002B63A06CB7335AF4A9C80D0F32C3AB20A8
+:1079C000707A7D6070F2C539DE52FB7C07DD2E28AF
+:1079D000EBEFF2362E723AD54E46EF72FC6020CEB7
+:1079E000E1761DC3D3560F3A204CC1F220FF66B09A
+:1079F00014D056F8340BDB21F0CCC5E5FCA9442E9D
+:107A0000A00E4186799221311E11D677502F20E8A1
+:107A1000A41F51AD2172450A1AE4C9BFA79F171DC3
+:107A2000BFB7ACC6AB003F6B228ADE86E7B85E32DA
+:107A3000F4CD4017D3B07CD2E1FDB872D0731E8173
+:107A4000CEEB4B422E59879CD59243ECB234F6DDF7
+:107A50001A19F3E454F8BE7D5C7FFC84129E9E6E7E
+:107A60000B3C9DF6E0DD02B6073F817F99896602F7
+:107A70001C7F1F5D9C91EC075FEFD51FD6E4B129F9
+:107A80007BD0F97DBD846ADCE440B3A052BE544D86
+:107A900005EC03BEEEF5982FBC59C0E75BE87AB35E
+:107AA000B3097CD777BCAAC916FE5B8FD58C776AE1
+:107AB000DFF57078F37E7ADB270EDBDA3BDBF5F659
+:107AC000C7E505B68781CE391D0484F83601BFF7B6
+:107AD00046179B7930FED36514FF69E6DF8BAF0F45
+:107AE000387FDE6E20BAFAFDFE8666D04FEF2AEDB3
+:107AF000375D8BE9E837CF48D12DF8EB9A3DE3CBE2
+:107B0000C16E7A97D137C7D3D9FD0D396EF4910E76
+:107B10004FAF0A3E320EA7AF35E28A7EE96120FA06
+:107B2000FA9E93BE3A977C2CF475C4495F0C1EE70D
+:107B30003AE9FAD1EE61142F0C5F4EFCA4C5CB07D5
+:107B40006DD7979E7E2160BEF6762E71A727365F91
+:107B50008EAF0F3BDF81E82847370C0D8F3F02DBEC
+:107B60003102E88F12144DEA60D745A9DE8A52BD72
+:107B7000C5E5126F7F41A0769A8C8E93F6124A9AD1
+:107B80001AB1B7ED76C67C09BFC4FD3416A384973D
+:107B9000EC8B0C95E8A9621951FD67047371FD0C1B
+:107BA000C47EA4D951587706B3FFD16CA67F056C6B
+:107BB0006FE1F5054BECF687DF619F48B05F08BBCE
+:107BC000D85B43DC1FFB44B63F0EA020D1477C7F2F
+:107BD0009C863F7BF7C50CAEC315648878DDCA610F
+:107BE0004F628B00DA0D11FD8C4E0A09EA2F40C559
+:107BF00060376F14F2A2A00FF03EAF27037F7FF72C
+:107C00009B12D10F75919A554DB0EC9BEBC677E363
+:107C1000711FAE47D38A3CA9F11E96DB5580776B66
+:107C2000D146CDBAAEAF09F102D1A2777C11655A27
+:107C3000D134184E7EAB1BC343C48004FEF3071F30
+:107C40008DBCAC03FCE8FB5E3859CB52DF7236D8F2
+:107C50003C79A498043BAE3584A89D8F460A65986C
+:107C60000E5A3DFCFBEB65B0DF6DF5D1F29E2DB3F6
+:107C7000369B501ECEEA9B95F47B2E2DDF273E517E
+:107C800006DF139978CD5380AC13953117FEBE4FA4
+:107C9000A47E95067346EC2E323D6A7F5DC5F7D90A
+:107CA0004B6E8ABE0CBF14E923C07F220563C4BE9D
+:107CB0009198BD266B26D5E36AF4F0780CEF51C796
+:107CC000256462388C6A3F5AE6057A0F723B2D8A2A
+:107CD00096E2F675CC1FA022BA3F06BFCE1542C76A
+:107CE000FA08D8B720B0CF2CFB7689D963BD78725B
+:107CF000E0ED11B986E06D6B7EEDE1023CBEB9505E
+:107D00008C02D96CCD2FCC5C6DC1E3B7D4B9952270
+:107D1000D8318DD9C42EE1FB64601828E792290080
+:107D2000683BCBC078CCC7920F613A1D1DEB29038D
+:107D300014E895DA8B648F8BCAB577895D2509576E
+:107D40003E31783B0AD62D02BD62FA7DC2B2DE61B9
+:107D5000028AB9C9DD157216C1CBB00ABCDE7EFC41
+:107D6000049FC7FA84DA677135164A3F4EBA797EA6
+:107D700008786E01BE188912044E03C1351D3C9B64
+:107D800023CF661279FD11C3355D7B273C870994AB
+:107D90005F56C8A5845F06EBDF6981FD14DEAF3650
+:107DA000811F0E3F1B981FCED9DE27B7A3A80B7EDD
+:107DB0007DBADD3FA458E91EFF5F2BEA541F049DE6
+:107DC0007E228A67A75E58C0F4425304EB052A0F4F
+:107DD00017821E0830F8374511F9AE8450C2C4DF4F
+:107DE00003A00FB09D852652F9AFE2FF80DF465415
+:107DF000DAF58132487DF08E107B99F0174621CC60
+:107E00006FB7D07EE338A09F5C6A8F476E6F89584A
+:107E1000FD05B522D5775C9F3D56D43B6F023F2FC1
+:107E20009BC36358A4023D26F2176710BFDD9D0176
+:107E30009B7C8A7C6931D9FF5AE899EC73DB997F86
+:107E4000341DFE342511779387BA249279858D9E4F
+:107E500024F8FC0821E7309721236B0A7F64DB8735
+:107E600085A7F61C1E83D7FBF83522B11BE5D97216
+:107E7000D283E12B97BE5229E0E7E3B03680C72CCE
+:107E800044E834A82F382B813E96BBD122DC5FB06A
+:107E9000C2B92FB69425E8A76725D1DF563F753FB5
+:107EA000FBB8C13E1B30BCDEB2F03F42B10AD0B3DA
+:107EB0003296E36D88B84BF3605CD9D072805E6413
+:107EC000231A24CFEEB20A5A8EB5C177DFECE8D17F
+:107ED00072E0434D26F23EA152BCF17EE74805B662
+:107EE000FD5BA6E6F08FCA6625D0814F5710D0A75C
+:107EF0002FAE180917FCD48A329377763AE1F4D181
+:107F00008F9CFB5074714AE47E6A3BDE6DF451989D
+:107F1000C22B6F17ECE3A7B2E3D559FEA8F1E99B9A
+:107F20004DF189303E99BFA40DE01C344504761113
+:107F3000AF17900A6DF8095EC61B2B6CE7EC2E4359
+:107F4000956EFA292029A43EE6FB7289DAE502D86B
+:107F5000DBF3A53D06D079A208E306F7DFE2C126F0
+:107F6000112EB76C16395E89BCADDDD252B619D769
+:107F700069392988D214A09BE5049F3EE6F7B9E44D
+:107F8000312B0A71BBB65122DAA783FEE9DFBFD5D8
+:107F9000506FF76F815F01ECEFFC1A6D2A80395D3D
+:107FA000BB5D3562859BFFEB2E89FABF76D41C6BD7
+:107FB0002766E84BF67D876785011408FB8FBBA415
+:107FC000E9A976A112EAD74071BC1E5CDFC3D733A2
+:107FD0001CD3673FF18AFFCDF4092FE7B1788EB348
+:107FE000DE4F2446873A8597CAE8F05241FFF4CF26
+:107FF000E173B9456271901E1F227A7738F1DFE98B
+:108000006C5D9279A40CFA9151F766D887EC12D185
+:108010001AEA578E117D1366E33D5EFA7B1FD4BBCF
+:1080200041A6F27294D1D30A781EB54944E0C77EC6
+:108030004AD249D72356D41CF4E0F7AD9B5134887B
+:108040005F8D867E71BB57C62A44EEABD954EEAB2A
+:10805000B59804703D15EF6B745C6E3DD88A40AFE7
+:1080600087F1C6094C5EBD1489E0E7F6D4759B30F4
+:108070006EB8344AECD0436367907DD583D928EA43
+:10808000D5537281D3D1839B161B40072D781F06D1
+:10809000E596A22D2AF8B12F16CBA48CFE8CE1C355
+:1080A000FD85F81FDDA474D35A40E72B4FEC462220
+:1080B000E15B95E053D6E8FA5B43DF34617EE65A34
+:1080C00044EC23B06F497C468EAA20CFF377CF26AD
+:1080D000FC236BED02D0C346147FCA4A27523049B5
+:1080E000E6DFFA1789D9EF2F6D06FB7D247485CB67
+:1080F000AF4AE7370FC51EE171416E8FB4C99D8449
+:108100000F4DCC63A06FB87DE22BEA24F4F9DF8C2D
+:10811000BE07DBBFAFD8EE4775DA2B4E3BA556D472
+:108120006C76A9735D973CC91B617E6DB998BF0BD6
+:10813000FA8E775CA2FB923D91C5FF51A0A7FAE1B0
+:10814000DFB97DC4CBF9971502EFC1D7C7F20DF6A1
+:108150005E06E5A3D19C4FBFD03F9F723EBA84918B
+:108160007E04F0239B2AE123A398F011E70FA9DBFB
+:108170006C1983E94CAF13C1238DC04CCFC2E5AB62
+:10818000307D2785149D8E62E3CA1313EDE35DE80D
+:10819000ECB15AD120FEEF28EE067F0F9B4788995D
+:1081A000E92F4E70BABA0874C5E92C7FF702B2AE57
+:1081B0005781A0A7835E7597233F62760ED2F61B88
+:1081C000563FAD0F35BAC7CF6B1FEF377EAE167D6A
+:1081D000B8F87948B6FBB3066A3FD4B8B9747918D1
+:1081E000A18FDE32DB873AEBC565265F4FEEB3C168
+:1081F000A50F3CA4EDD1783F74A27E487F3FD159B2
+:10820000838083138E3364E667F998E0E88C6BBF54
+:10821000CCE4FC40F2C06F1849710CF8C510F5DBD6
+:108220000411F3DBD8E9FDF14D94DEFD21712F88B7
+:10823000A870ED11D36B990FA6F725F2F014BDE7E6
+:10824000152793801FA7FE49A7770692B72B55E302
+:1082500036D925CF84EFB3537904988B5DF208D2D9
+:10826000E2B5E6A3C923182CBC7BFD962C2FE0F6C3
+:108270005246B7D8707803C365ED610FB1EFB1FE18
+:1082800093ACF1B2B56C7F773BDB1FDE896261F89E
+:10829000781E8915C02FE7D1B1F0340BDDEF9415AE
+:1082A000CA2F2D9EB7C06FCAE3E077B5D3329FCFF8
+:1082B000DDBBEDE5CFA1C539E0AFFBDCA31EF020AF
+:1082C000A0B50EBF593D10049EFFDDA8A619F0D63B
+:1082D000E4A176E8ED1A92216EBDE1075F9FB11A25
+:1082E000EC13667FBC87E5B26EB19FD605130AE03A
+:1082F000F7EDAE69375F87A07DA2390FE2D7998885
+:10830000EC479D70BEA3C53EBF81E6EF9C2F425B4C
+:10831000FA9D87DC21B8C659F7CBF6386BBA7C29B1
+:108320009E27F5924CF16FCE45C47E32DF0C241AA5
+:10833000883EA1795203B57F15DA4FFFE0ED7F3615
+:10834000C0F81BD49E05C4CECA3663E0EFE1F1BE8F
+:108350002A54638CC4BFCACF2F3281E77AEB45061B
+:1083600059AFA8FF7AE9E67D56534D714A6AFE5F20
+:1083700013E2276597F5DF2FC5ABA07F2FE0418281
+:10838000A74CF04DFCBB18BFD572B045C8803CA6C9
+:108390002EB2CFF3E9B28D1EAAE117906BC554AE91
+:1083A000058AEDDF9D7EDFDFF5E23D49F88F84969B
+:1083B00075B01F824909FC32A5F2B9DEFA78BC2AF1
+:1083C0005817EC93508CC88D5A8DD6AF42FACED93F
+:1083D0002584FFC8BEBBB6750C8997D70ED7A3E01E
+:1083E000879551D4207D38E8AEFAB28012167D58B8
+:1083F0002DF728C067D5D82EB2BEDF18916CFE5776
+:10840000E7D383543D584CFDB9C43FA4E1B265DDC8
+:10841000BF6F17585E8A9EB1B41FBFDCC608F5F364
+:10842000DEDE3A3683FA03EDF2F702DB1FFDE4E904
+:108430006F28E0BF3FFFD4E99B00DEEBFF45422AF7
+:10844000E4653C1D4249628F2514B0C7D67549AE1C
+:10845000FE0392390371CDEF8608BED63DEB4D2C5D
+:10846000C4EDD73DF7F66484E777614BCF2B23C18A
+:108470006E7E4AA07E6BB37BF212FC7E9D8C56B959
+:10848000F9058A3DD44E3DF7C34025F0B7D0717051
+:1084900025E9B773B9C76BD95F5FE5F1F07AD42EE0
+:1084A0007F52488C15DCE647F33ACE3D29D0F91DC2
+:1084B000F0247C30BF8EBD4A1CCFA3BAE37D224F8F
+:1084C000E67DF7DB618043F501C9A607AA3BA4A4BA
+:1084D0007732799E8627C483841940278C5EBA360A
+:1084E00090385055E7B6F7C14F517DC02ED7305C5C
+:1084F000A24980EBEB52742194BFF7ADB08E41F5E9
+:10850000DE9127C20057DCEF6A2503F48D9DBEA1E2
+:10851000FFCB597DFB43A887C4E1AA3B5BE9785DAB
+:108520009FF90DE8956A87FC7C0F7EC9ED6BCFC47F
+:108530003C0EBBB0637071B8F5DFBEF89889C73DDB
+:10854000F7EC6F1F33F1FCEFF9EB7F3DF600F0E73E
+:108550008F7D1AC8FFEAA77E1146167A5CE7A1FC58
+:10856000786114327371BD0BBFF4264CFCEAC20B68
+:10857000BF19ADE3755F78E68F393AAE5FFBC2FC99
+:10858000110087DAEFCF1BD1DF7E1BE835E1B5CED6
+:108590002B41F0AA1F10A811F43C7B3AF073A8EB12
+:1085A000D06898E7F913DE28D83DD5F85DDD54C0D2
+:1085B000D706A28FA1BC09C3B9EAE9ADEF839CE855
+:1085C0000B6F73A4489CF0C991E08CAFEA7A7B01F1
+:1085D000C11BEA217AD459BFFA38C6E794F4F8BB34
+:1085E00088FEAC80BCAB7EBA958ED789F117EE8B36
+:1085F000BFF3F0CBACBEF86B71E0EF22BAE7F15CF1
+:108600004868EB1A668B7FF2672AEE17CB88F52352
+:108610002FB83C1808BE6B043AAF651E63B707F865
+:10862000EAD9402F7E17027EBF7D7134C2F471C635
+:10863000D3B312E466CF0B5E6D1F7EBFEE85D70904
+:108640009F5DF8FE51452779972828E4B0FC2FFA62
+:108650007304E47015DDCBA1EAFDA1A4379CC253DD
+:10866000556251851E26EF4F93F7094AFF558983BE
+:108670004B0517BC1DF314523B2A319CC065C3FE49
+:1086800037146A5FA6F02994023E4F2F80F7E9F075
+:10869000C9D7AFC1FA675AF0BA9FF2ADB37E15E6FB
+:1086A0004FD07B7DF09B105E87E785BD5E19F4DEC1
+:1086B00005B0BF827DF19E823FB57F86BA5FF9A982
+:1086C00093BF795C98C1213D7D98CC0EE87F7D43B6
+:1086D00085DF8F3CBA8D8E381CCFFDD95DFE9F6142
+:1086E00072A30A99157916FB44F560FB04F2C65093
+:1086F000CC1C59909AEF39D84760FA3BF79444E282
+:1087000030CD9D87881C77CA8BAA34FEBF3FF2F11B
+:108710000E1C9C0C72EDDC8B3F24F459F5F46905BA
+:10872000FC63AF747C4FE99E98E207D00F098B7E03
+:1087300038F79D8393A93C70DFFF2A0AEDBFFA79D1
+:108740007BFFD54FBF6FEB7FBDD9A9D0FC84FEC79F
+:10875000794F3696C37ADF3BE241204FDFEB945CE2
+:10876000FDADBF05FD68C9336B3EBAE00D88DF97EC
+:108770001CF3EBA047BBB618237680BD76CC8340B4
+:108780007E23D9F82DC497BB8EFA75C87BE83A765C
+:10879000B3A45BFC133F70C073E671735E08F737D8
+:1087A000B33B56025B28A7DC283D2942CCA277FECA
+:1087B000B5472B4680DC6F047B7E3C8C178D90F890
+:1087C00077784105CD0B14359FABFEA6FD79589CFB
+:1087D000DCA38948B7D223DF6F31BF4F73D0DDFFF1
+:1087E0005CA670FB108F6B9183D856AD74C35B8908
+:1087F00042F741E9BE970EF07DB6C2F200D27CEF9F
+:10880000E56F861F2524C6DCE63D99F5E3F4ABA6AB
+:1088100093071ED6CF144567FDD3F502BC1759F256
+:10882000DD47A2C466F07FA160D019678EA9D63853
+:1088300073E591831057CE5EF27C2EC03F8C1AB543
+:1088400077891D8FA257FAB1639D716567BE61BAC2
+:1088500038B31AAC3A91447DFBEB1B5737485CBDEB
+:1088600031BF5CB5C6D51BB53E71F50D0A1EB729E3
+:108870000D1E3EABCCBD17BE63B333EEF6BD49A1B2
+:10888000FEABEB51F7F756C33CA3342E3FDB01AFF1
+:108890004F3278FD780C5E38563D6548973D18BEDE
+:1088A000F3961A8D2002E7AFE8597F10F88CC7E5E0
+:1088B000CDF1E295C0E0E137D47C8795EAE20795F7
+:1088C00041E43B202DCB552FA4E66132BE89907D3B
+:1088D000128FBF1C3A75B70A724B46F18A024B3CA5
+:1088E0008CE4D1E3FE72923E64E0F92A9A4EECEDFC
+:1088F0009CE4DAAFDE05F1722D9FC41FA4CBD71123
+:10890000FFA1B35F291235499E57502F932CE334B2
+:1089100067D3788CACC55CF381572AF1A761BDD2CF
+:10892000E539A45F51A5F10C141C5C1EEC5796842C
+:10893000097C550C5F908F0464B02E960FF5D09291
+:1089400030D133BEC39EBDF0DD17A4F951F78BFEC5
+:1089500028E44F39F3A3CADEA4F196E6D30289A333
+:1089600070FA6D2EA8B90AE4783FF9512F2B16BF83
+:108970007ABAFC285FF04E921FE5FBC0F951917264
+:10898000B0C79A337919AB133C8F6696EFF42BE599
+:10899000F03CD04FCD2C3F0A99AFCE23F57919D5B5
+:1089A0001C32E03BCBA7CAD9DADC00F5B347A29A68
+:1089B0004EE2CF33D0328B9CF579699CF9CB8AF1AA
+:1089C0009F8A45EE71FCFB7AE96AAB0AFA1B3F49C4
+:1089D000BCB219D315D8ED39C95664D547FCC9E9DD
+:1089E000A8B9A8FF789D7CF91AE2C7E765554B182E
+:1089F000864B7D43A57A82D32FC4D3402FA97AFC1E
+:108A0000AB77013D6707A3014A97244ED61224EEA7
+:108A1000A93EEB6829BA9DC4BD2E6AD4DBCDE9B866
+:108A2000EFFCE7B0F9179A405F1783288A5CE45F90
+:108A30006A1D25641D2B1543F55AE0987D957BBE74
+:108A4000E9762F5D4F536C45EC2E98C91A7BDC9567
+:108A5000E75FF0FA01213E1CFAF564D3B8ABA852E7
+:108A60007E4BE10BAB0A8B7FB301AD308104E41583
+:108A70009DE4C8A2AC2548FD31BEF868AF2D3ED7B5
+:108A80004DE3B88E78E27CE91ECADF03E06F07DBB6
+:108A90009F6C83B8DB7888CF45D8B93D9DC5E90C7C
+:108AA0009A2F94869E5A8AFA8F43B5D74749FB9DE1
+:108AB000F5A5340F4940CCAFFDF506A013704B501F
+:108AC000BADFDF007C1092385F3C45CA0F0AB41C45
+:108AD000DFDA45F8E6D0A9D72BEFC0F4D16CF8095E
+:108AE000FF0FB43E2D3183E075A8E3F45D2F1DB771
+:108AF000C50892FDEE40EBD69274DCC18EC3E3E371
+:108B0000A9F5A9649C667D8071DAE93803CF9FF2EC
+:108B1000C98E836B2B20AEAC62FEF7E1F7EAEC1E48
+:108B2000E4161FCA60FC73E89497C8EB966C9AC76A
+:108B3000EB290E1AD40968EFDF3331672E39C7509D
+:108B40007235C98BDF71B095C81905C6C1553CD1C6
+:108B5000E06ADA2E6EC0F9D970398A825FDF539CE1
+:108B60007307BCAF43EDB1B9A0874BE9B92D4F7185
+:108B7000F15DD04F26F0259EC73495E67D788AAF0B
+:108B8000BD1BEA1F9CFE5ABC01E0544AE9001DCE01
+:108B9000B5C1B1592FE4E771FAE57B4FA93D6E816C
+:108BA00054BF2D6F09C94B49BC1CCB856D5E8BFF33
+:108BB0001BEBC59D50F6A01213ECBD5DB7DC1CB5D8
+:108BC000F2F39795D8C3548EF03C2CCEE7EEF970B3
+:108BD000CDD93CAF2CAE4A2570FEA8374F7A61AE96
+:108BE00035AF8BE54907799E7494C6E1DAF17F6E63
+:108BF0007971CEF3891F559EF477BC6C3F1C40A35E
+:108C0000204FFA471E144DE279B7FD428A421E8C6E
+:108C1000933E9CFD39F3FB7BED9134FCFC6B008EA5
+:108C200045EEE5C61D78BBD347E2737CBC97403E5A
+:108C30004D1C984F47AEB1F733AAC67EEEEAAA3A6A
+:108C40007BBCAAC0CCB3D51FD35268FB3EB6FD6A2D
+:108C5000DBF7F1BBA7DACA1312D7DAEA7FA263AE59
+:108C6000AD3CA9F353B6FA530E2CB695AF49DE6A64
+:108C7000AB3FEDF0EDB6EFD38FACB37D9F7962A340
+:108C8000AD3CABFB8BB6FA75D83C51483E1C8D37DA
+:108C9000A1ED23452B7DB66662BD9281E1988909DD
+:108CA0008626EB937833CD314EE51938DB49458A7A
+:108CB000A161FE95F471E51AC91FBC93F09154941B
+:108CC000335727EF672C00BF132AA1E7AF7CAC3FD7
+:108CD0004F114AC2B94B39E8C0AF232EED91B6937C
+:108CE00078AA72F286C342B82F5E3D11679EE2E019
+:108CF000E2DAB2EE683744BEC854595C7B14E60B26
+:108D0000E247FCB344CE3D9787887D60D9DF1038B9
+:108D1000F2FDCD1C1535024C395F94ADE81949F2CE
+:108D2000D97BF7355E7128F9C67DF58A97D85D5CE9
+:108D3000CE0CA457A4C4345B1E82F389E5DF14155E
+:108D4000F6E1E15B893CEADD17F4CAC7D854F8EED6
+:108D500091A3443EF6CABF8E3C9B5C18AC7DE69462
+:108D6000D36D20F4C9791F77791D863C302C971E6E
+:108D70005C72138983A15A643BE79753195341EFFF
+:108D800061BBAC42B5EC9FC3A5D43EFB7BB353BDE6
+:108D90006CBDBD74CAEC550ED76105353112D70BC9
+:108DA0008908F6550DB3A311F003B64015CB3E6DFF
+:108DB000973A86C8D1C6A02282BFB4F1F07C121FB8
+:108DC000F0FA622AE4D135786215B0AE864C517360
+:108DD000CB77DAA252FF8C521798B6BF1FFA501405
+:108DE000BCEF7759EF3E95FA5D1AB5C58741CF655F
+:108DF00085141D526E9B0FCE5A04E3CA0B650DF607
+:108E0000B5086FE2DEB6C41521DF1711F88B442FC9
+:108E10002A756132FE40F3BD47A57E066F9DAFDF28
+:108E2000F97A15773F45BAF96E85F9660F3C5F6FA1
+:108E300036CD5FF5D605C9F8FF0C1759B8C0DF83EA
+:108E40008C96725CAFE9F40DED458462689EDE237A
+:108E50000BA7123AC582DA46BF7C1F81E937A10E03
+:108E60004FEDDFF939D5BB559A97C0F18A74EA8F77
+:108E7000181697C9BE372B4EF7BF29F941E928CB01
+:108E80001345E45C57BE4CE292E0A6B1FA31FECA4B
+:108E9000F671DE4F4609BE5A3F23A32D406F457839
+:108EA0003D70DEF6308D3BB57AA295B1606A3CDE4E
+:108EB000FE4D860F192DCD20F95BD2C2889BFDD9BE
+:108EC0004BE70C6E4E39FB632E6773512E95B3132F
+:108ED00097C311A174FD38ED0D7EBE67E8E74EDA49
+:108EE000093C5BF31F257634F78FA148C900FE1EAD
+:108EF0001A2F4DE179B99EC478946F9C4A9C7EAD3F
+:108F0000450CCF358EFC5D86678E5FEEB747916C62
+:108F1000C2D71CDF12C0137025CD8EF4A7AF24C6B4
+:108F2000374E789EF91F0ACF9FC31AF0336B145E39
+:108F30003FF0CDA11B11898339F891B7E374EF5C41
+:108F4000BFEAFB9FBD7E4E0FE9EB9BAEFB0F1ED72A
+:108F50000D317A5399DE7CB9F4AD1638272267D3E8
+:108F6000FD6EA8B491DCD322235303FF5A889FCB14
+:108F700061E732793E957FA27DFFC1F30B4919F37A
+:108F8000BB87ED3FFADC9BC2EC2C7E4EDF397F279E
+:108F9000BEE6F8DCF30751BEBBDFD5198FE3F10D58
+:108FA0009E07CBE300040E78FD9E59628CC8BF1269
+:108FB00064EC75914FCB7C542F74BDE8237912A1DA
+:108FC0004A85F863F34A926550CEAB4151D013D72E
+:108FD0009E3982E2B8D3B17E2AF7F34A1202F83DF5
+:108FE000F2CED1BCD85D2C5E99579B10565BC679EA
+:108FF000C047E5ECA553F713F9F8E2289A877E5F9E
+:1090000019B5DF8E446E6F2F83714B693E7908EF7F
+:1090100017216F2C74C24BF26F514937023F2AD689
+:109020000266087F3F538FA6DE3916F2BE54F23C2B
+:1090300057AF91E7A151CAC1EB71BD8D057E1DFAF5
+:109040006D2AF4D373BB2195ECF7FF3BF373C4AFE8
+:109050007AA13E42EAB77CC9207645E3C1B3C46F2A
+:109060001830A645A91FD5905029CCE788017E0E5F
+:109070002447F5C5F0FDD02F493D4989FFD204FBB7
+:10908000E45685ECEF010E104F68F0D17CB9ADBE0F
+:109090009A48263C0BD0AA452EF0BED5C7E34CAA71
+:1090A000A4E4A4F29094D2A49401FEE412D439165C
+:1090B000E46553A20CF4345AABE9304EBE9A28034F
+:1090C000FF71FE1A2D0A3E74A594DE23C2F1E1F170
+:1090D000A1D83341A89714EEC5E316FAA9DECC3B1C
+:1090E0009120F70C5D3A35D3D5FEBFFF6419F9BE68
+:1090F000BDBEE258B9859F8369E2950F14CD7DD43A
+:1091000087FBFD196C7486A7EF973F07DBEFCF7CD9
+:10911000549F1E3A357E04D8977569F2A8250DE351
+:109120006918954FE08FD838561F9119B4F643E16E
+:1091300021BDF8438AD789943E1BBE3F3E03FA7D8A
+:10914000E9D4720DFC7DBFCF2E22FB86F3CF790DC3
+:10915000B05FCE67A13524DFF2B999AFC0FEF0B79A
+:10916000F587B3648B5C3CFF9DA3333CB8BFF3CF62
+:109170001E9D2113E64AD8F6F11BAEFC7C06D809E9
+:10918000E65C545C839FD59A82A0DF6A95AE83E744
+:10919000C9EDCA519AE1393F9049DAE78C101F8432
+:1091A000B2A4FE7CF43BD3C8BA695C81C571F0FA05
+:1091B0001A8284AE35BC018178A1E91D0DF1AC5352
+:1091C0005E427F970A5071C114F00B4AA45DCF5ADA
+:1091D00094807C0A255903EC897C3F4D20E09BC09C
+:1091E00071ED20A13576CF5BABAF90D121CD23DCE3
+:1091F0007CEAFEF1001F2ED7E57988C4337A6E51E0
+:1092000013608F3E2CEB5F590176E06D3299072E8B
+:10921000FB34173C2E0F14DAE092C5E2131CAFE9C1
+:10922000E8645B3D8A166178FFB85E8DC2F8CFD7DF
+:109230006BA4FCA3FA08291FA8D7C9F3B9FA62F2F4
+:10924000ECAA8F92EF1DF5A5E4C9F3FAC8D65E2209
+:10925000F674AC0CF4D032EA87D374D1807C850CE0
+:1092600019A9C3B0A9A29DFC4925ECB741AE64641D
+:1092700011BE17A07D36CBF31B9E3BB7B54C4FC933
+:10928000572E4F1B3C48007964CEA27E8610F4878F
+:10929000DB672F45E82D8B5CBF82FF79AB98AD0F64
+:1092A000CF27C3B07F77D60FCB7801597DDB61B96B
+:1092B00048CAA97EDDE137D427F8CBDFB2D0F7AEBC
+:1092C000E978D5988E7609548E3DC8BEEF983E2336
+:1092D000E37628CF9A9141F27F67215DC370DCA9C4
+:1092E0008BA62723557F4FFDE19CF2B14C07819C53
+:1092F000AAD5F6B659F631F9265A15B3D0CBCE1AFF
+:10930000B9621FB133E2B98B27917C63E6D7DE5790
+:109310006ECC26FD927241DBA17293E915903373F6
+:109320002E533DD4AB7FFE4CDF73BDA730FC6F9F47
+:10933000BD450A039F803C057959124773F13C8370
+:109340009FA4F1EF59EF2411E4F72951FC1EEC51D1
+:1093500085E69BE4451202949FF4C5A6FA613F920C
+:10936000B53BB90FE3FB0F5D5E1DE28D5D2FFE91F6
+:10937000E46748931515F83BEFF9D3246F4912BB06
+:1093800015D8F12E6BBB7ABE0CF62C4C84DC2B80EE
+:109390001535C6B394C3D667763695031CC5F85900
+:1093A0006BFD5DFEF8BD74C78C0C3582F9C1C7DA60
+:1093B0009BE39B8C7C5CF6D0F2B2B6714DE66C28D8
+:1093C000E3FA99B4DC88ED846D999D111197839B24
+:1093D0008B9A0E8F8232AF5FD464E2F631A60F50C3
+:1093E000305E00FCDE5BD670396429CBB48C54FA55
+:1093F000E4EBDD70E88FAF8CC470A87A5EE82421BE
+:10940000BEE7F70AB0EEBC037BE9B9800422FBFE9D
+:10941000BC849080A39B1DF587B546EE5CE378C1C4
+:10942000A2614284DE1BA4243C51D85E4E60F782C8
+:1094300070BA782640F5C084046E6F8D4B3BEE0900
+:1094400099C0EEA1212403F2723B3DE7EBA4F3F1B6
+:10945000ACBF3A64B649A0B79FF668243ECEFCEC98
+:10946000E7B8DDC4FC39F730079E678BE9BF1AE423
+:10947000DF6A99F881D7172436631B0AADFF614173
+:10948000145BACA8C947E9657D6667CE544C2F4D87
+:1094900099F67203CB9F8F649A995913217FE8A1A3
+:1094A000D190DF5385DA577E11E6FB531A0F3F7BCD
+:1094B0007056C675B8BCE1A7348EB1A1EBA802F412
+:1094C000BDC3CFF28EBAAEF914ACAF6ABB48CEC5FD
+:1094D000015F1AE3F1748DF6AB654C2FFF1A383932
+:1094E000DF87F1FD64A1A189D720F4C6B6779BD4AC
+:1094F0004FE2B2A24D00FA7863DBF926A0AFF5B3D4
+:10950000F87D76E75F368A58FE2306DE8EB6D94DA3
+:10951000700E63FFAD159F02732B47A4FC8B09925D
+:10952000C4B5A5CC46727EEF774D22B19FC145BA36
+:1095300009C3BD48468765FCDCA5607C029F35CB2E
+:10954000441EE2F72D1E829776727F086AA1F751BA
+:109550008C7DDEBB1AECECA21A632DB1B7B589C4C1
+:109560000F301AF5FE903C89AB1095BFE3355426B9
+:10957000E37A2501EA2F2FAABC793DB493424BFD33
+:10958000C0EF3952C224FD7F8DCAE15D62A253054E
+:10959000B91C2E24F8DD15A674613E3C91D0C57E21
+:1095A00071EED560173509ABDB5E05BC66169273AC
+:1095B000AEF07E23AC9FE1B3418BAA80BFFD0C9F30
+:1095C000D25ED1847C4DFE7E9B70FB5A80EB3BFECD
+:1095D0008DF3550CD71CAFD1320CE3E16DFFC6A65D
+:1095E000C82C828742157F7FBBEDDE2615E365FF21
+:1095F00066234FB394C7FF054B752207EE257CDD2C
+:10960000187C741D2821FCFD65F07F3C99C5F99EEE
+:109610007E2F2AEC952306D8A50D664AAEA8582FB2
+:109620001459EA9763B9F0CDC72482D7C3783C9028
+:1096300013781D26D07DCF0499D8057E3C173F2E88
+:10964000FB2715927C5BBC6EE407BB61924CF43C3B
+:109650008FE32813446237437DA0077F6E21C99FA3
+:10966000C3F23A06E77CA4088DEB48D21E03F33020
+:109670000AB0FC7D415B44EE17F1155BF20A40FE37
+:109680003AF210244779ACB73B17CE2B659F5C2488
+:109690008CC67839ED6771996CBC8FC5EF7FEDA7EB
+:1096A000E71BEF8F993740BE0CD2BB73693C2A365B
+:1096B000159E236E2B1AD19FFFA5EF7E354AEC979E
+:1096C00047F265D77CB0E702745FE41D5544EECBEA
+:1096D000A84398FF812FF8FD2A4C7E7898BDE03C86
+:1096E00027C0E5892793AEB1B675DE88AC60EA1C69
+:1096F0009C143454900707B5A919608FEA01CAEF8A
+:109700008DC9599F05BB4566F2608F8F9E8FEDC94D
+:10971000449DFB10D8BF5164CD4BE0F2607BBD4A45
+:109720009E4FCC1947E2974FCCC9990BF18A43D78A
+:10973000BE47F6BF17F750FEBD78E465B823095D54
+:1097400034E9F95C202BE2974F3E42EE01F9861C8A
+:10975000DB49F2E5215F074F6967A63D0FF38900FA
+:10976000F59BFE89C927ACB7C9777E3F877CF91383
+:10977000C40FBC95C95D355E4EF695E0C6D3812E0B
+:10978000503BB96789C3C1792F877C793269FF273C
+:109790003F853FCF5F72E629F1F9FC80CDA7EF7DD1
+:1097A000AE767C70BF06C7036F5F2B1823B47EE8CC
+:1097B000A6FAB2841296BC90D4B90D85BCBF00E75E
+:1097C0005D32E05E9578FB7505C007096227FA8275
+:1097D0008DB6FB595144EEB19E2F0938CEBB38F9F6
+:1097E00005EE05063DADE8FD9F6BF935DEE6F2BC02
+:1097F0005C92A72EA3AF825D7B3EF0E60CF0C755CE
+:10980000633101AE72249BE43CE905B62F919FBF02
+:10981000979CE7E1F3E3FE385EAE3AB088F8E9AA38
+:10982000F707C9799EAA0495831B54F3B057B4E691
+:10983000DD1A49C8B7F51CA0FDE980038C8F3F688D
+:109840006B7261FD81BA3133E19C498E5873D568E2
+:10985000808F4CF100FBE56783E49CAE0C7A9C8F13
+:10986000FB4BB60F5CC6EC9100324580A7E48F76C7
+:10987000237A66D190B17D24F5CABDAB9B801F765B
+:1098800039ECAD5D7E5ADEBCEDEAA646AA9F895C46
+:109890005CD6F62FC41E6AF2F1F273444EEE52DA31
+:1098A000932027CDE7BC3AE83DDC9E9C63376F2DC3
+:1098B00026FA432A447900B77270B480FC7BCEBB91
+:1098C0000FFC0C4FFAE231BF65BF733E746234EC9B
+:1098D0002B5DFA336DFD8D1E5A7F78FC2EC003FF81
+:1098E0005E1EDE4DFAC7ED88BF03E51F7913DBBAB4
+:1098F00028E7392F3967B8C763B7B7F97337933398
+:109900002D8E7B39D478A3019B73CE9FCEFB9339E8
+:10991000BFCA9727D8F2A474A69F65D9005725FE21
+:109920003E917CFF939FD2410BCBC7493F4E569A45
+:1099300071EC71BBBEE3CC60720231FE97B5DEFB09
+:1099400036FBC97F75C6179DF28D3FB97CCB0E5093
+:10995000FE8A09F1AE001E675DA273819FF2E76483
+:10996000E0CF3B995E2AEE78E84550EBDF528DF769
+:10997000013F2B55636C60F8D0F9E70D369E8BFCE8
+:10998000A276D91A6AE7D6B64EFB14946B77146A9E
+:10999000A64BBC883FD75C0ED8E4D70EBFCEEE45B1
+:1099A00034891C5B73394CBE7F74E3F96CE7D9FAD8
+:1099B0008E1724DFF978F738E4F3A16BFF6D572990
+:1099C000A6E3DA673CA2D7324EED33EC1C900FCB06
+:1099D0006B3BBF1BC0EF7201EACD5304F9B053617A
+:1099E000651335835DF4A4553E9482DD966A0FF7C6
+:1099F00011EEF4F3F6BEE6F27C97FA0147FD42DE83
+:109A00007F26E9DF391F2E7FA00C769AFC172F9F47
+:109A10001F915F0F898EFEB2F8F879A43F6EAF7F79
+:109A2000A1ADF01553063A4D948DA4FE1D1DEC809A
+:109A30006FC851BFF59EAB2FF8A9DC5C73798C0D14
+:109A4000DF29B88FB3BDFF4D7DC496AF7F77BC963D
+:109A50009CD3F802F327AEC1163D69B767A42D4F1A
+:109A6000FF1FF3F8A0F3B82ECD3CE6FC8DE7516064
+:109A7000E3CFD43C8A6CEF3FE83C7EE0A3F2F805EC
+:109A8000F69CAFD17B01E6EB02F15BCFC7757D9809
+:109A9000D66FC04F153FE7CBC80C92FB6B13B43E9B
+:109AA0002E833FE0B37FB9EF9DEBC97DCF06C9C7D9
+:109AB000E1F74EF1FB1007BA9FC8F9771B9CDF0353
+:109AC00069EE5FFD6290C2E9A129372192BF1E8C29
+:109AD0009338C1C1DC0511B0D3BF32A58A3C1B73DA
+:109AE0006744401E35843E67CB37C77B04D773B0CD
+:109AF000EFB17ED1E51B44EB7994AD701EC5A53E58
+:109B00008F8B6D55F9FD801FCF7A777F4CEB2D0D34
+:109B100051FDB9558D93B86073E4E399FFB3413AB1
+:109B2000CE4353E6203ADF39491AF75174EB796096
+:109B3000FE3C189A11817536642E88003D3766CE3A
+:109B4000B0AD474AB39E957C3DDAC7BB9E7FEFC55B
+:109B5000C7075DCF02D73C5839DBFDDEF9C6101DC3
+:109B60006F6B244EE8ECE35AD7990F8DA7A1AD2B6C
+:109B70008BADEB8E20DD476CD5291F05A4D87F1453
+:109B80000803F3E1407F4F0415E9E260F2F07EC57F
+:109B9000E0958E7F6FF52486C3BC4ED4D3FDF36B66
+:109BA000EC3EA95FAD690811BFB6639CADF9FB42FD
+:109BB000FDF939FED71AFBF9F481E48619A471A0E6
+:109BC0005BE2F676CB2B03AEF79B60F8ED2C2848D2
+:109BD000C1B30FFE3F62B8A5A3C7A1C2AD393234ED
+:109BE000B80DC40777C0253783801BA7B774FDFC69
+:109BF000FF4267BB83D46E1804BC087DFDADE0F561
+:109C0000F74A5FCF0E9EBEFE012FA23707475F5C6B
+:109C10008E7528F49E45673FEF84E83D9BE3859A67
+:109C20006337427CE13312F1F71EDB53BE0189D664
+:109C30007A54BF1CAB98B781E4BBC60208EECF3A9A
+:109C40002E46FFBD04E20E8B693B67FFC7187C5EA2
+:109C50000E65B27DBE3E1CFC08C7634BFA5D1FAAB1
+:109C6000B0AC8BE4655AEEA392FAC2F718D277949F
+:109C700080BF69A1FB3C383ED38D3B547C1E8F7D59
+:109C80006348F81C68BD5DA1C1EAA504C14336EA7A
+:109C9000FD3B1857033C3B449ACF710A5ECD82FBD3
+:109CA000C910A9B4BC7204B9E76C4A98E53D29FA19
+:109CB00006F09379972CDC16C2783BBE2C53B0DEAD
+:109CC0007F2686A9DD326385BB5D9811A674906AF4
+:109CD0002FA0F17ADF7A7F65F6E3B215F45E2A24CD
+:109CE0001BA3165BCED54D08DBBF3BDB47C2613201
+:109CF000CE71C1FD7E583F9BC7F2A5FDB747B5C3E6
+:109D0000D8E16D6D92DBFD829C3FFE4F283E2C8C8E
+:109D1000EBBF26C4BFFE79A0A309411AF7905101F9
+:109D2000C4EB793FD9324A2A18EEEF78B449E0A75C
+:109D300075E927BFBF7ED2C195AF878F03AC08F707
+:109D4000B2E0FD23D92F961808CD867DA2377A2F51
+:109D50003D6C48E9208BE5CFCCAC092436839D27A8
+:109D6000E3755AE6DBF5A7799F86EF5DC7446D4B37
+:109D7000415F380C241FCAC234DE902DC5B7F8C02D
+:109D80003FB64A70BDDFECDA30FDFB23E742BD7120
+:109D9000F55130CEB847E31EB8E7E06696DF845051
+:109DA0007CD422CBF8E7189D38DB654B341E8D5EE2
+:109DB000A7FCDCB16FDD2837FEF939E3D373A1626C
+:109DC0005B1ECED2D8BD1EE0CFA50B1779F4207C48
+:109DD000D729BDB1797428F151D70453704A2B8724
+:109DE000187CBA4EC41BE07E8755750289234DDC72
+:109DF00044E96ED5A683E206FCDCCBF86F91806C5B
+:109E00007990F730BC76ECF38F86F977703F1D744C
+:109E10008CE7B17237227EAF3B1FFCF456B84BB5CE
+:109E20005B40CC4F76A002F20DBA599E8889BF6F75
+:109E300006F8950F27F31DB7E9FD5A90CF5D0A226A
+:109E4000E7E5FEB3D54BFE6E05A7975E39B1E95243
+:109E50003D24DD3DA2242701DD0C6FA8F9BC9B9FAA
+:109E6000FC0136CF3F0463196E762E7F7279CEEBFC
+:109E70002D96758F5BFD25157639C6E73DCC9B3C4D
+:109E8000EF765F432F1D26FAD77BBF60729CE3BD40
+:109E900017DF27DCF7455F6172AF2331773DD15B78
+:109EA000A6570779C8E7C3E1956D5238DDBC54B2B7
+:109EB000C9DB550B038EF34814AE9FF5EA8FC13A08
+:109EC0001ED9F76F93000F4EFDE097E20A7CBF1B8F
+:109ED000253D2027CE483A79BE566FBF47FA351444
+:109EE000DF311DF4679DE4CA57CF32BCBC5679C739
+:109EF0003232FF464983F99F5E31ECA652902F958E
+:109F00009E28E44F9E6EBC2F749765FD5CDF39E799
+:109F1000F5AB3577F4ABB79657DAF1D6A150BBC0A5
+:109F2000FC14E5C3B558DECC26F4D5BD63261EFF70
+:109F30005822EB9A365A1DC1DF695CC27E3F23C6A8
+:109F40001F9C89E5CD5991FAC3CC7FA27263E9A326
+:109F5000B12688F39EAD9BF64237AEF713A607DE17
+:109F6000ACEB5F3F3AE969DCA3F6FB29679C400A4A
+:109F7000B48FD7BAEB835B32034CBE4447837CB9C2
+:109F80006D937BBD7F86E44A0CEFB37F95D6B8E531
+:109F90006D5ED6E87C57C5DCDB5FD642F43BE82536
+:109FA00017387F2F2340E5BCAC8D0639BD2ACD7C08
+:109FB000BF9B1126FDBCDD74FF6D10EF3B23DAE57E
+:109FC000F3DE0C4A17F519543E9FDD77AB6738E096
+:109FD000A959D0801EDECA8C4E007A5BDD789AF8D3
+:109FE00011FE89D5AF0CC67E171E0EFCB278FE702E
+:109FF0008C97AE15282AE8E9E5FF25C63FD912BDA2
+:10A00000C700EBBF7740FFE1A6EF10FB433646DF0A
+:10A0100032895ED90879856745731DC943D9E7A799
+:10A020007947283ADD7ABF8C2783C2EFECFEA1E1A5
+:10A030007B592CD0AF1D7F0CB5579171F707348831
+:10A040003F1EAB9092D7E349BEBB3FB0572AE8CB47
+:10A0500017E9C61FAA1D7876FFD0ECC081D6FD890E
+:10A060008C8241D9F5172B1E79B004F848699FEC12
+:10A07000267FB99C3ECEFC564EFAE1CF998C2ECE6F
+:10A0800024FA9FD7DDBBEDF3B9ADC63E1FCE2F67D7
+:10A09000120D7EC80FC7A34FB2DAA5A87CFA00E75D
+:10A0A0001CA8FF37DD3C3F9D6197134079104F5B43
+:10A0B000CBE4CD9B758F84AD7870AEFFACC8F6074E
+:10A0C0008FD1BCADB1B1D57387EB29FAAC6470F810
+:10A0D000A8E992EB19673F7FEF74C8F5DC4074C8BC
+:10A0E000E582B3FD3988F3E3A5AF963505E232E7A3
+:10A0F000C23A2D236D011C9141A5ECDC32D247C33D
+:10A10000B99BB3FBFC08FECEA6D9E64D8CC52C70DE
+:10A1100066DF7513ACEBF90AC3CFAAA59970AD0D34
+:10A12000A693E88D23487E8144EEEB7AED44D60277
+:10A13000283F724404098D6EAB5D2DC1FA1ECDA07F
+:10A14000FBCE559B8E127B70A874BEAAC6AEFF2FA5
+:10A15000B375F4DA59724F09D04F3A383466503833
+:10A160002C8B2D9A0FF2F98E4D0291B74D193AF5BD
+:10A17000D7CA0691DBA891EA47A462786015721AE3
+:10A180001601F0F832FBFB63724CB19E4FBA6BFBC9
+:10A19000FDF3C13E74F24B0ED34F481399BC8F7F31
+:10A1A0003B637A4A3EBF25D41C1C81AB5C9BA1F16A
+:10A1B000FB61099FF2F55C9B41D787EDB46F93BFBC
+:10A1C000BBC4D687A20E7A13DBAB7E04F09FAB1222
+:10A1D000BBC0EFC5721FF2E6BEE1D768DE1CE52BFF
+:10A1E0006EEF38DBDF2CC76D76E3FF05B9373CBD7A
+:10A1F0001DF20F7DE15EFF7D06B7BF95BEF8CB4730
+:10A20000A42F8E86759B9DC5F5C6FF03C8D629333E
+:10A2100000800000000000001F8B0800000000000C
+:10A22000000BDD7D0D7854D5B5E83E73664E669221
+:10A23000996492CCE41F9C49000324780221444095
+:10A2400098240482609D408060030E081A2584A82B
+:10A250005879AFDCE684440C14BDF1E7AAB55EEF93
+:10A2600010D0F25ABC0D965A54DA8E54507BF53603
+:10A27000F88BFDA2466B292085E8AB57DB8F5BDEB0
+:10A280005AFB2773CEC94C08DAF6F2BDF0F19DEC0B
+:10A29000B3F7D93FEB7FADBDF6CE098B3A3FD34341
+:10A2A00088B655264F10423E3CF65935961FE8B504
+:10A2B000B82528AFD8B84A0E390949C692979013E5
+:10A2C000E1C529583E8F3FB3873E6F7A44269142BD
+:10A2D000427FCEC3FFEB5B920CE513DD890182E385
+:10A2E000CD7285C7FA09D9AF108D9412F2C1B6CCE0
+:10A2F000F0162857DB89E69C4CC8F4141F1DCFB319
+:10A30000F98B56F724984FF77F14937C98DF3D77AD
+:10A31000AE08150D1DF72F6E0B215361009FCF4224
+:10A320003208B9C3CEC65C9D4C02D83F81F19ED0A5
+:10A33000F52FBE7BBB9590C8E5503F06BE2B8B7EAC
+:10A3400067EE7FE975578EC675BF7DDD8CD1AB8A10
+:10A35000A2DFC583C35229F42F4B70DC365945B8B0
+:10A36000EEB937A1B13B06DCBE8D709D3A747CFC22
+:10A37000B1C23A16F3DF976CAEB8CB0520D9923450
+:10A38000EBAA508CF1DF26A17BA6C278DA66369E56
+:10A39000799C6BF8386FD7DFB004E1FFB926BB6555
+:10A3A00080477F839C5C8EDFD5DBD4B1D07FBF76C6
+:10A3B000BB6BAD6E9EBF8D039FDF36DEE08A8507E7
+:10A3C000F15C566FA4830FC8C06BD3709CDDB1E7FE
+:10A3D000B75ED09712BAF74A98DFC9AB655583F9D3
+:10A3E0009CB4C077482F8FC277BEA1DFADE2DF7D7E
+:10A3F000B07978BA5C5C639CCF92638946BAB490BA
+:10A40000C69E18EB59FF15E97E05D2BD3D5ADEA365
+:10A410000C8C72C3F71FEC3CF7DE9DB89E9D89142F
+:10A42000DEE67E9253653ADE49E41384D7F604CE25
+:10A43000275DCDCFC1771F5C93A36E2143F9839035
+:10A44000AE6F4C87FABE6E4BC976A8DAD39DD4188E
+:10A450008E31DFF1A98C0E3CB2963801DA93771871
+:10A460003E90DC906F96707A7377FFB08558A2DFCC
+:10A47000BD83749040C81BAD76FADCE1B6D3F1EB36
+:10A4800016D62A3E1867AD9504107EF407FA754F6C
+:10A49000C8DBB91D867ACBC2CADA6AE03F69E87CBC
+:10A4A000BEC7E9724F78D1B0F0AD6F900DF0AC5BE4
+:10A4B0006884AF993E8F872D35B1D62FE839DE7885
+:10A4C000D7D9C25EC4D331BEDEB7F97A7FDBD8EE0E
+:10A4D000C2F6E671F684BB87E5836F361AE9E2427D
+:10A4E000EB3CE6F653B82E0F19BF5B566F5CEF12CC
+:10A4F000D272150152594A541B3EEB484BF173007E
+:10A50000CAE38F2CA6F3798B909A1E9CEFB9DB8B54
+:10A510006B8BA3FD1FE6F0FEBCEEF66B50ECBCA30C
+:10A52000B414BB63CCE72D0E2781EFB7E2C0F379FB
+:10A530002E77DF413C23BD2E9563E2F96DCE47EFC8
+:10A54000340CCF474BEB86C7F3EFDD6EDE4F7B223B
+:10A55000AEF38418F75136EE89307B2FFAFBFDDF1E
+:10A56000887FFB89760BA5E370A21BF58807C9439A
+:10A57000A7475A53B9FE291C5E8F88E71B42AE9A43
+:10A58000DAD75903363D3E4ADC8CCF45B96EA1710E
+:10A590009EEF27BBD9B8C43D3AE8D2C90DAE5F855E
+:10A5A000BE7BE0C989EFA3FEF471FEAF0B7E6A4368
+:10A5B00078807CBDCB85EB7ADDE246F95A762C605B
+:10A5C000D3C3EFCA1406BF93BB8787DF955C1E5DBC
+:10A5D00048CE9AD7FBC13FDD3D19FBFDE09FBEB0E1
+:10A5E000E9FB5FFA652E89A447CBD7D74B81700C66
+:10A5F0003EBBDDAD8C08EEB79BE078FD97A369FF0D
+:10A600001E99B4F4C45A17CA37E87749B0C2E605B0
+:10A6100078DEB0595225E882A4B27E6E10F2CEEAFE
+:10A620001B5D0B70F7B6B7DC118CD14F3987F79FE4
+:10A630009CC194587C36C81F9C1E44BBA5D6902D47
+:10A64000567BB35EEDE77C6E6EB700E9D13B727A64
+:10A650001CB4834CED473A8FE9298C2FD313227F0A
+:10A660004479448A8C76D805C735B5378F3B1FE1CE
+:10A670003E35FEF827FF2A37C682C3B75319FD8639
+:10A6800082403F31EB5DB4FE75C2F4AB164EA2FAC8
+:10A69000F0C4EE1BEE45F3EDC6F9771C4135F972B7
+:10A6A000B29F8EDF103C5A8D6025E71E988478FF9C
+:10A6B000BCE6817B4B616A279550BB0B3E38B945A0
+:10A6C000A2768B799CD7B93E7913E5E9E5D81F616D
+:10A6D000743B077ACB06B0CB81752854C8B7137C7E
+:10A6E0007A3BD5B3E98B563209ED87E01617BC1FCC
+:10A6F000B7F9D38DA8970909D3EF3FB2A93753789B
+:10A700001366E7F6753B776E8776AF25337C10A22C
+:10A710008E0E16EBE484D54DCB23C5CF1B71F073A1
+:10A72000B1724AAC33DE380079FA7D6D95B353BA15
+:10A7300002ED1DF71D088F816A97BB1BD6539B1036
+:10A740005880EB3BFABAC5D2E6A7DD527B6511FE15
+:10A750000643FBAFF67F17ED99450BE58003CA7DF5
+:10A76000F81EC65B52E9D4A41450116F2CFC11E200
+:10A77000E781BA049F0C24513BDBFD4719DAD7CEA1
+:10A780004BF26D8172596F7E9B07EAEB6A2437F6B4
+:10A79000F7E2C229AE7E585FD226E827073B3B5E30
+:10A7A000533586901FE2AFD3099B30C0E20D22EAF9
+:10A7B000D3B6CD017930C1BBDFE204508F494BDB0A
+:10A7C000668779DED516CC72A742BBFB4E74DAAF32
+:10A7D00022242323D03B5B2524E1FE5335F651B0E0
+:10A7E000CE47797FDA279D8199A04F2D21BF04F5AF
+:10A7F00093EEB7CEB75E09F82F10FD676DC3FA254B
+:10A800007357ACDD0FF5756913E65BA1FFB2063136
+:10A810009F2BE65759E1FD4CD1BED481F3F5248935
+:10A8200032CCB79C105B7E74FED62C183F4D94CB77
+:10A83000E7CF816FDFAA68A9B242FF7BD2666D2B9A
+:10A84000721032ADA6C21D80F53C75FF92F94940E9
+:10A850003FFB09D029D4EFBB7FD97C9CBF47B6B062
+:10A86000FEB57A3ABFB2066D02D64BA4615B0DAC61
+:10A870007BBDBDFF0892EB864D9A3D037E49921841
+:10A880009DD86D2D815C80BBED404524974EA78BF4
+:10A89000D1675EA418F5D860B910CAC5BA72162B74
+:10A8A000EFDF42AE8F256F5BD299DCDB9F18BB5E7A
+:10A8B0004A63F218E046F549CA3112D81B43AF9CEF
+:10A8C0004875D276871389664F8BF2DBB5C0C3E536
+:10A8D000C097C4CEE629FA1942D75CEE10EDDA34FF
+:10A8E00094A70B399D16A812F577494B52782C3A4C
+:10A8F000D824625D8C2248B6D0F97A65E9FA5AE824
+:10A900002F239184F6C1D39B4E6819BE0FEC73467A
+:10A91000FB7B95B116A92E08EEC6FEAA33B34BDA1F
+:10A92000FDD17E60DE1DF6C986795BCBD3B07E514A
+:10A93000C9AD453A7816B175001DD0EF60981FCDAE
+:10A9400006BED8DF3B211FEDF7A7538D7C5DD65B9C
+:10A950006923F0FD92742E4F7CEC7B6F15933F03BF
+:10A96000B72685915F895D2D09EAECCEDC34068F30
+:10A97000AABB173E8CED9A7A6D2401DA6DDC5791F3
+:10A980004986D18B4D5FCE20E129BAB235A2A0DC39
+:10A9900069FA72167D5F75F7AB0AF229F6E38379DF
+:10A9A0006D74043255845B7B6CFC83434EE7DDF4AD
+:10A9B000652AD1A6E8DF333845FBF7D0FA0BAD2B7B
+:10A9C000DA9F4CC2E9C3F5A7D0FA41B85B39DC95F0
+:10A9D000D8F3ACE4F042785B74F575486F4E2AFD0D
+:10A9E000681CA5EF1B45DD28EFA3E36EA1FDEFB7C3
+:10A9F000021ED10EEC4DF4A15D5C6605F9E9C1FEC5
+:10AA0000D2DC9A14A50F411702AFFBD35A2AE87A79
+:10AA1000AF91DCDD31ECF8F9827F16327B2CB3216B
+:10AA200024AFD2D1BFE007E87F3FEFBFB49CF2CFA5
+:10AA3000BF327E00BE5981FC8B760BD2A11A295EF3
+:10AA4000E41A3AFF674076607BC02383FF35CE303F
+:10AA5000CE47C06D28FC732F80CFD1B4BEACF79029
+:10AA600082F4D614876F17A427D3EF328F4592D183
+:10AA7000AF7D8EDB1DFB7BA63866205F2CB41014E7
+:10AA800061B86EB457CB660AF9FDC42B95207F33AD
+:10AA90004519E5AD0FF130287F23767BB4FD550FC6
+:10AAA0003C31BF03E57302E0BF88DAA176A2F32749
+:10AAB00036A53139561E2231ED96DA7466B708781C
+:10AAC0007F6F5315F91DACEF502AE3CBF27E4D5A40
+:10AAD0005514E56BB39C7A98E3F141FEFCC7CB2992
+:10AAE000E90272AA96CB29F6FE3098F9D82E2323D4
+:10AAF000522C814E5CFDCA94B1E8CFDC9625FB3E1A
+:10AB000006BE5A2CA9A39E827EEBEC3E1A27137434
+:10AB10005247EC3E27C21D8CA6F312DA070E5AC626
+:10AB20001FB44B3EEB92181D125F4A5D717C3924B5
+:10AB3000E6715B9642C75BBD6D6C4A483F3FAE27EE
+:10AB4000AE4D883C450A86F2B928C3FCD75B645DEC
+:10AB5000BD93E9B33FB8024FA741F9288F43812243
+:10AB600003A72A3AFEAFB93E31DB4B8B93399FA046
+:10AB70007949F9D8429DD3CCCE8430619F68E8A74B
+:10AB800066F6303ACA6C88589A747470242D8F36E1
+:10AB90006A5806956077D5D8AB021FEBE4D8CB1284
+:10ABA000A9A7710412998A7CFA521A31CCA3410EDA
+:10ABB000E64968B76626A82867004F140E871DC4AB
+:10ABC000EA80715F8227E2AD5ABEF5059B07E94036
+:10ABD00052DB29F47772FB944450DF5C3B3B89DA0B
+:10ABE000ADE4DCED63305EE14D62740BFDD8793F7E
+:10ABF000764A275CEEFD66F4F86ED44F427E0A3C3E
+:10AC0000907332ED4FD41F966AF3DC503EECBDBC1E
+:10AC1000A45D32DA3F680F45EDA7DBB6CDB3A2BD28
+:10AC2000D313B1000BB5691BE7DF897638D84F0E17
+:10AC300058CF47694C0F1EF66B7232F63716D601A5
+:10AC4000AF8E24868A5A9C517C808D1342FC6528E5
+:10AC5000F07432FEC0675B3AE33397873D97F16744
+:10AC600046326B6FA6B79B787D00790F9EDB2B98E1
+:10AC70009C30B7FB6FCEBFEBED5A4D46BEDEBE0A31
+:10AC800012A4432B6176D65F39DE409F517855DDA3
+:10AC9000DD90827AF3F3DE2529A4282A476DF63762
+:10ACA000467F0C72244216FF33F2ABF2964CD05E14
+:10ACB000BECB067400ED94D4903B0D9EE949B1FDE6
+:10ACC000E6317C9DE9E85743BB7BB9DF63FB722229
+:10ACD000F5B733B87D969C5547E53AC2D207704E1A
+:10ACE00021039A5B87C794728BC17FB07D39897EBF
+:10ACF0007FF1F643491CFBA1D4603F8871CD76C437
+:10AD00007BAD5974FEE2FB15596F56135DFB95A49C
+:10AD1000FF2EEC6FE5C65C43BC289EFD319DC3074A
+:10AD2000ED052DE6BC14C3FBF7C05FD4F4E39F60D0
+:10AD3000E347C74D02868B8EFBD7B4C08C741A0FC5
+:10AD40009AE93E3E111E60C39F97A9DE61FA1A9EE2
+:10AD50003B9D542FD5A0DC167E12F2BF3B05F9BBFC
+:10AD6000A22ADDABD393FC3BB33C3AC8E31A07B944
+:10AD7000BE493926ECC6449F2445F5CE50BDC5EDED
+:10AD800062937CBC909D0D74ABE9ED8021FC92FE3A
+:10AD900055EDCB8238F431EE1F625F96CD0CC9C5FC
+:10ADA000283F6B2432161ED3E618F5FDB7D39D74E9
+:10ADB0005DDF0686D3FB2D8B1A8CED5AD399BFD25B
+:10ADC0008AEDBC1786A75E1F4932CA3DD65F33CADB
+:10ADD0001BC0B3FFD4EB8A0FE4F0F3DC1EDAE50905
+:10ADE0006C45BAE8484C9E847AA223717418E31229
+:10ADF0003BFFBBAA7027FAE9AFD9D46EECF600F39B
+:10AE0000F32B966F6CB7C27B5B8FE44E20D1793AFF
+:10AE100037498135404AF7737C3579D87A9A3C11A5
+:10AE2000650C8C9FD3C4E691D7F38264D5C9BBBCB3
+:10AE300046D6EEB1749B41FF8479F9F17411EF08A5
+:10AE4000B7559762FB8015F741727A241A1FCE69B5
+:10AE50000140003DE4A8AC7FA71A966E288AAEB7E1
+:10AE6000D3525B847AA2332349453D71CA137A12C7
+:10AE7000F9A8A92F1241704DEBEBB5A2BD67F506FD
+:10AE80007E807010EBF4C9EE1C94B3497D6C7E5D3E
+:10AE900026BA27E4BB3C3EDBCDE4AF4C5E268817E8
+:10AEA0009421305EC69642AAA744FB8C34AE37325A
+:10AEB00048E8696A67914E42F146E83A32B68CA397
+:10AEC000F6BEC06BD4AE1A3F19EDAA821D11EB6A13
+:10AED000B45B1F8B1DAF3FCCE50FAC2342E5C481B3
+:10AEE00091C565443B5B1CBF5AD07D524D6C7B15B0
+:10AEF0003401ADAF58EEB90ED7DDD4A19004290AC4
+:10AF00007FAB37F806CE27A767A784B031D3594760
+:10AF1000DA0FA55C58E7ED3713B74CE2CFBB699366
+:10AF20001C58A3E7E70E85E265A762DCDF137EC647
+:10AF300069AE8FCABDC1DFE1F8CD07EE5310CF3740
+:10AF4000EFFE50196E5F67A470931A99FFD2546F89
+:10AF50000FE37A2B965B291ED7752861944F4D7BA2
+:10AF6000F7452C68676F262AF27F53CFBE2339003E
+:10AF70009FDCA6C054D9A7F39F9BC212CE2703889B
+:10AF8000B1B788CA4D05F5B699BED14E467BE58866
+:10AF900083F1FFE90AA786F1B4D3B65013B63B9DFF
+:10AFA0009DA46AFE28DC5FDA37EF650958DCF5748A
+:10AFB00042049F9D96EE2C3BB4EB9CA0A8484F56B4
+:10AFC0006FC8EE8175A45983FBF1FB548F4B6D83E1
+:10AFD0006F7D096432D5D72384C334135D4CDBCC39
+:10AFE000F865BA2759D88193512EE57B5CC28EA2B1
+:10AFF000F2EA888DADA383B0F9B6A507323D48B714
+:10B00000EE343A6E4E5344423FC03C6E94AE02A3BF
+:10B010003CDE8B99678F82727E1D973715CB774BFD
+:10B02000BFD3D1419187EDCFE6ECDD29A17F08F5B3
+:10B030006DD51EDA9E24A0BCD9CBFCE27550BF565C
+:10B04000275FC43A62C89929383F675FEF8B4CCEBF
+:10B050004428FD89F99AF139DBC3ECBBB96026D0ED
+:10B06000F78A56E883FE8EE427D2FE04DF9BF9744C
+:10B07000B687D1794EFD6EC95244E382D49E14F353
+:10B0800013ED76792AAB3C140EBD140EEBEBAD2C10
+:10B09000DEC0E753AD04C7A05F56EB61FB5D87964A
+:10B0A000BDAFF443F9C19F1DA5F4B8BE4B0A507F54
+:10B0B000A1EBA8B204E376DAFF91314EBB80992868
+:10B0C000E4A19F1EA57A65C17E168F5FBF7F9FF5A5
+:10B0D0000667944EFDA70EAD443A5BDF93401C1209
+:10B0E000E28FADD74CA7206728DD134DA1FB5C2074
+:10B0F00027352A5749C88F7E8A90C36DE97C5FCE79
+:10B10000C9DEAFE1F316FD46E5A783D2BBFFD4E469
+:10B11000437680E77A5552C174023BDC47DB43FF3C
+:10B12000112A878144D15F13FD9BE1D7E5617A2D18
+:10B13000069E5B3C31F489D0B3FEC72B093E05FE69
+:10B14000AC1CEE83FADDA3D07E5B3D563A9F8E0A9F
+:10B1500016D7EEB0313DD2D1660F235FBF943AF7D8
+:10B160006509E4A52B4D89E0F3B0657513D61FCEB4
+:10B1700061F3E8B46C296C617A4CF350FC2513261A
+:10B180009F983C7AF0274C9E34694EEA3F3685EA18
+:10B19000D6D07D098F43C57D09127A5159E28AD2F2
+:10B1A0008319BFBEA75F507C50BFA087F141146ECA
+:10B1B0004C5F09BA053947F1DE26E2888037842BD7
+:10B1C000F8F56D187F107E7D72435073F986F26B2F
+:10B1D0003AF7EBA772BFDE566EFF9BFAF5EB36FD32
+:10B1E00007F5836EC97A853E05BF80FF68E0ABA78F
+:10B1F000B89F763F7FEEE7FCB9AEB487F2C3BA8F53
+:10B200005B281F396B983C71F619E52021F7F0F5A2
+:10B21000EF60F498D43317F725AAFF4D72B793F86F
+:10B22000F3BE496AF94FCC9321FB78FEC639B0F2E0
+:10B23000CB00AE0E0E03DEEE08E7FBD37B0011C899
+:10B2400097D61665387BF842FD92C89B12E27B1DAB
+:10B2500087F5E9BD5557FE1EE38C7B52683ECB2730
+:10B260007B17FFAFDFC3F7A777CF56514F7BDA834A
+:10B27000947E06BC0E15E3A7203E6B24A087B69EE5
+:10B280005F25CFC0FDB21F5D3119E5E67B7C9EA72F
+:10B290007E226F42F86CF9C18F6761FDBAB0948E5F
+:10B2A000F6E3E93DFFF657D48B8DBB37D0BCB4F63F
+:10B2B0001FFD92DAE596F04EF67E4F0AB5334FEE5B
+:10B2C000BA6F16C2BDBDA79DD69FDAB593960FFD86
+:10B2D000E0C7BFF80BDA1DC16415DB9DFAC97DDF3D
+:10B2E000F90BD2795DB28AEB680A59D97EAEA06FAC
+:10B2F000B3DCDAF702E553412F0B50EF229CEA99B9
+:10B30000FC11F4FC11DF6F5ACDF7B13EDAEE6A8C16
+:10B31000156794BC6CBD188BA172AC5EA271B64E61
+:10B32000A01A8C77742692727C261545945C186757
+:10B3300059C3BE59D4EED13EBC11DB2F3EE020DB19
+:10B34000695C0E83BAD17DB0621083C7C16F86DE9F
+:10B35000779F07BA7D1BE403D53B267F6071E72BFF
+:10B360007F46395A67EF7F0145A178DFC9E337D0BF
+:10B370009EEA9DB28DB1E3A40EAF93EB6DA6377339
+:10B38000F6D7E6F9A89C4850C7EAECD351C75AB69D
+:10B39000637A524E63EF5C5CC7D585ABA650BAC0EA
+:10B3A000F81FEA1FCD49FB5F8FF14BE0BF1C2F93C5
+:10B3B0009F196EE2990EE3575B89C7894F42DEB44D
+:10B3C0005139F204ED17EC0F6A57F97EB9EC09B464
+:10B3D000471EB285B2A7623F9D5C6FED66F386EFB4
+:10B3E000DDB88F0AFDB9A74FA6FDF4DAD2E8F71A47
+:10B3F000FB7EDEEE36293A5FA0D4D1A8B7B0BF52AB
+:10B4000027EA19AD9EE2C7A7D0759DC226D974DD83
+:10B4100093561447F9D71CF7417986FBC3E5DE8ABA
+:10B42000295E6FF429E2416678DE89F5D0CF33DEFC
+:10B43000007D923D467F3B9EBD7268D919A67F9FD5
+:10B44000FF90CA9B66A4631C3FF4B141FFDE20E875
+:10B45000F8D90F291DDF7080E9DFE603250AD2ED58
+:10B4600027AD01F23B30409B2B816E817E1F92FA0B
+:10B470006FA4F92ECF3ADC18D73BC3F5CDBA1D1F08
+:10B480001E97011EF907B2A99F7FE659473DF67343
+:10B49000D862A1F03CDC3D7167BBA49F27F30BC0D1
+:10B4A0000EA6A4DA0C762AB383D7DC877EDAFA46B6
+:10B4B000A222FF379BE8A7F9C0514A2FC20EF63FE0
+:10B4C000BE680DB33F1DAA03FDB839CC1E25608FA1
+:10B4D00062FBD439E13685D2574919D2D7A165BF6D
+:10B4E000D88A7ABC790E7163FF0F8D0A3C9B4BD7CB
+:10B4F0002311CC7379C8D6556985EF1FAAF6B90117
+:10B500009200B7DDD4EE25850AD7736BA8BDDC9C0D
+:10B51000F54D95F299591E3CDB46EDAE665F229DD6
+:10B52000CF8203D26DCC1E7112367F89D2E782F0B2
+:10B530008C30C6CFFEC8E127E078C6D6BB12E171D9
+:10B54000E6A7408850BF600EA3D7D4393D548EBCC7
+:10B55000F4EC3CAAC7055DBA9E49A0FA3CCDEA9638
+:10B5600054AAD71627E8F1DA65637A2995EB998210
+:10B570001D0CBF6D5EA697DABC16FE548CF117B792
+:10B580003609F5EE1F39FEA91841F9CEE5C9FA359D
+:10B5900011CA4F4D7B597F9E8440C9ED3AFAF5544C
+:10B5A00031BD28F603707FA03686BC7892CFC3FFEA
+:10B5B000F8EAFBD05EBE1AF08E2A25A790CB51A0E8
+:10B5C0000B845B4E6390D2C1D59E9B54CC4FF5A6A5
+:10B5D00013EA2F0EB4292456DCE7877C5DDEF46085
+:10B5E00029C6A1BD992E6AE778E50A8B03BF2B9186
+:10B5F000D46E1FDDF7A476DE80375BED36F07BB0CE
+:10B60000D402ED4E64B8189EC3BFB12E2A463EF454
+:10B61000097FDD60F70DF5BB99DDB8B04B9B847EEB
+:10B6200088D8D7107008B725D6EBE5670F976FE17C
+:10B63000F12C9E0AF6BD93C6B5DD300EFAF7DD3368
+:10B640007631FFBE9DB6FB9E97D947D5B03EB4DBA1
+:10B65000BC05C18D4C9FBAD458F028E77AE5D0B22A
+:10B660009525E85736D73955E4B7079F9756537A4B
+:10B67000C66021FADDA135140F04F080FC4042CCF5
+:10B680002F6D6E098663D37B2DE5BF66E43F89D2BB
+:10B690003B8DC303BD8719BD33FD27FC7F948FFA13
+:10B6A000BC432107847C6956FAC7211D0B7E689E26
+:10B6B000D53F0EE136527972C606FC8FFC0370400E
+:10B6C000FE11FCE27A8EF1C9F6365F05D66FAF2621
+:10B6D000EE769D3E32FB4B384FF43B855C3FE509EF
+:10B6E0007E8CF2B7D912D98AF915420E373FB76D61
+:10B6F0005CACFC372187ED5626DFECE1A470BB8EF5
+:10B70000BE70CFCF35993E693E4FD2A6D8F1912F6A
+:10B71000BC4E1EC71F59BE4406EA729437DD493439
+:10B72000AF5DC48BCCFD9EE4F426F022FC16DC77E2
+:10B73000C0F6E9198C5E940CC69F7919223E1B361F
+:10B74000F83D3E4BE843CC338AA7BFC4777FABF8C4
+:10B75000951847E85133FEC5BE09AEA7B6287EBB93
+:10B76000AE17987C32D3E3182E373EC4B5C2FF7FA4
+:10B77000E7FB5C43F1CBFA21A1F186BCB84ECBBE0E
+:10B78000C65871B0175A79BED463E3479477F7EF80
+:10B79000BCFDBD3C2F8CAC196FC8B372AABE368CF1
+:10B7A000A35E71D05722D371591CCB358B7C8A7A1A
+:10B7B00038B9BCAB10CF4D7883C6FD92CCFA44C3E8
+:10B7C0007E447628CD50CE6DCC31B41FD5926FA873
+:10B7D000BF6CD30443BD5F9B6C2817744E37B41FF6
+:10B7E000DB5569285FFEC8D586F6E3C38B0CE5ED13
+:10B7F0006D3DF58897897BAE337C7785B5DF520246
+:10B80000EF8B7B561BF3C74CF0ACFCAB1C930E6F5D
+:10B81000CAF0537C5D71C0088F9472233C305D0E7A
+:10B82000E19C42787F897F5687CB6F4D21D63FF5CB
+:10B830008BEFFD43E981D8DDA5FABC8428FD840D9A
+:10B84000798B9556D9340FED2BD15FBC798AFDB633
+:10B85000B8EB8803B7ED837CCFE062E3CB4A995520
+:10B860003F2C5C6C17820BE957470217F37EDF60B1
+:10B87000DCD9D4DF96A4669A27FC261674F6717F6D
+:10B88000ABF13CCC522D85E9A1E0E20BD8D12C0ED6
+:10B890001C4A60FB95E6FA57B85CFC03C084CE678F
+:10B8A000847CFD3EC7431FCF9F1FC2D79B3E3D9C5C
+:10B8B00089F2BB8650BFD9DDD2F629EAADEBAD11D6
+:10B8C0005202F37E90AFE7212E171E6975D37E1EBC
+:10B8D000E5FB918FB5FAE8FBC75B0BE933DCAAD235
+:10B8E000F7DDADE5F4B91BEC397C3ED95A439F7BBB
+:10B8F0005A83B4DD0F5BEBE9736F6B88CD6B08BEC9
+:10B900004819B57382E931E3A5AB347944782272E2
+:10B910005E4C7D19B71FB961D8FCF24D7DD28F5FA7
+:10B92000D4F1CDBB192E0FDDDF9C46A6E1FEE685E6
+:10B93000BEFFA295FCF8C5B123E723414FE45CFAB2
+:10B94000B8608CF85188E7553E9911FAAEE68C0F35
+:10B95000AF289DC586539DFD4C0E3AEB93D066D023
+:10B960007D2FCE9F88725D2825A6DDE0CD64F45939
+:10B970009FC0F6E3979BF8FB5BBCFE5B994CDFBD79
+:10B980001B47CE38332DC29FB7D1FDC1217C77EF45
+:10B9900055B1E0BB35D367E063F3B915733FEFDA18
+:10B9A000BA46A931F8EC42FD88F599BF5B9AC9E423
+:10B9B000D6C64CC2E4E4FF67FCF9EE5A17F51F1037
+:10B9C0006E5EDDFADF5D9B541F2B2EF39D4C1BF347
+:10B9D000B703A0B3D3A8A9AF29682B16121FDBF7B2
+:10B9E0001DE3C6F890C80B884FAF561A47A2309493
+:10B9F00087C215F0E1530AA07FEBE038112B8EA32C
+:10BA00005AA2FA0D736D88EEFC873C941EE07B4DC4
+:10BA1000A1793DFD3938BF8BA527223F3676B87D09
+:10BA2000BA21DF5FA49CB931F3EF2B67049F9373B6
+:10BA30000F8C8DA527EB51CE4C075193F9289333EA
+:10BA400017E8F762E1572FF7D3FDEB11C3EF8067DB
+:10BA50004471A92F1CC993D0B8DA6467CF3B139304
+:10BA6000BBF1F9856374982413F200CE13DA69955B
+:10BA7000849DDF7A5FF84D2DD3E8FE4A76F05F3281
+:10BA8000A17EB5C2FCC53319818732615D897C5FB7
+:10BA90003891EF0B2B99CA562C9340215DD7247017
+:10BAA00097316EB1D5E21B8DEBFA5852C7A3DFE296
+:10BAB000B684557C26934831CBCF0B87D05F4B9F04
+:10BAC00098E8437F37711C21BD343EAE3A308EA6D4
+:10BAD00024F5BF3E06FDDBE7AD345E3409F351A12A
+:10BAE0003CE97BB9618DCE3348E5453A87E376B4CE
+:10BAF000CBE1FBEF4BA1A770DE27DD76CD02F37A19
+:10BB0000A0738A230DDE47F6C89A9282F931A7EF17
+:10BB10005F00EBBDA257A671E72BC89457C6A09C47
+:10BB2000E9B5D1FDDF7556B203F9281E7C3FF95601
+:10BB3000EC3C30922519F2BBCCF51F703DF0499CCE
+:10BB40007CE3DF70392AF2676C227FC61B18367FD0
+:10BB5000C666CA9FB1598304F7856D83F9330D8496
+:10BB6000E6CF403FFAFC994F2A63CFE31D3E0FDB3F
+:10BB7000974971FA4DA6EF3FC91F7E9DB62F1D86CE
+:10BB80007CECE8F74EFA3E5EFECE001FFF9338F9DC
+:10BB90004BA707FBCF265ABAFE3B46CFD171F268BE
+:10BBA000BDCD940714AD67F93F1DA98C4E5EC872D8
+:10BBB0007B5641D7AB483F3DCF79BDD363C3785265
+:10BBC00090A8FBE8F91EAB6DA05FF0613EB6B37EB6
+:10BBD0008476B705242FDADDD76FB27DD4AF935BBF
+:10BBE000B5016399607B9D1C5E88316CE4A7098573
+:10BBF00034FFEF33E24B710F23471BEC72D0AA5B8B
+:10BC0000475F1C3BA2348BC1A72F3B36FC466559CE
+:10BC10000C79CB43BF4FE6E73ED839B4DBDDC3CB6D
+:10BC20004F846F285DDFBF190F1E5A7F21387BDBE1
+:10BC3000197F0F54482CCFFF6F0EEF549EEFC6CEE6
+:10BC40000FD84CF9EA0BB3CDF366F9EAF7A706CBA8
+:10BC5000B2D02EB3FAC6E9CF0BECB7069226C3B327
+:10BC60008FCB1D335C3667317BCFBCEEFD3CEF3EA6
+:10BC700051262DFB74F037AFB785E351B4EFB0B167
+:10BC8000FD2C147C76907B2B0893B3CBB2F2F93960
+:10BC900097542BE2AB81754156B88FD0FD2501E753
+:10BCA00021F0E37037C331487C2B31BFFB42F05C9D
+:10BCB00075345141B9BFD23E70187DD5FE5ECBDBE5
+:10BCC00063E0F9A173CCF1DD04F7E10A9F39443058
+:10BCD0003EA2B27C0A3287DA3D92962B9F9F387241
+:10BCE000BB676B72A810F9E26389C56B853EDA9A6F
+:10BCF000736A1CE6D7BF9F5651943D95C6DF03E992
+:10BD0000483F3F4F60F4F308F404E50DBF184FCFF0
+:10BD1000C12FC90E4DC8F646F3FB4860601CE623F0
+:10BD20005C2C7CE0C786F47321F8ACCD62FCDD9717
+:10BD30001C9B3E1EE37C7821BEA0E7CF4AFF7E7CA1
+:10BD400021E029F62FC4FC266433392C9E026EE6CE
+:10BD50003CA209D916DE8EE5112DC90E52389F1D61
+:10BD6000F5E97107CCBD4F897DAF434F1CFE30AF65
+:10BD70005FC0FBEF257FFB1263CFEFC5FFE1F91535
+:10BD8000E3FC008E7D9362CFEFDD11CE2F4806DEFF
+:10BD90004FFD3BE82FC07331F21DE918A072B12F9F
+:10BDA0002DF63CBF1CF13C43B6BF879E15F44DB445
+:10BDB000558D74DF3E2B31E6BEFD52F0A3D00F321D
+:10BDC000EFDF8B7D7A901F74BD75F68195E988F75A
+:10BDD000397CDD1924928AFB9ABF48A0FB0043E41A
+:10BDE0001AE77380978DC26BE1008D67F48D8B2D00
+:10BDF000176CD90C5E83ED3BD938F1CE1FB8387F74
+:10BE00005EE8FC01290DD1386085DD1991010FB77D
+:10BE1000717C28B9B7A868175664BD7A0CD709F0A9
+:10BE20003F3D084F5D5EDFA9D697DD636CF1E5F617
+:10BE30003AF9E9B29618EBF167847C280F06DBED3E
+:10BE400079C53D4687AF62D26F61E7A7072C06FF31
+:10BE500038935C947FFC3307E3E7F7D382541FA049
+:10BE60007E40BDB3F5B92B4B1099685F605ECF8003
+:10BE70002B91CAD1F69CE9853E1D3C2BB3855D29EB
+:10BE8000C7B117BFDEB980A8BD2419ECD668FF562C
+:10BE9000FA5EE0A7C2F9EB98F8F06704E6213C3FB0
+:10BEA0004F0BD4E03ACDF0D3EE9E994AFD6584DF86
+:10BEB000EC687F83F88F83E75B33028BB0BF89E93F
+:10BEC0003E16BF10F97C83710BABFBB83D0AEF91B6
+:10BED000E2E55EFC05FCD5DBB2032BB17F2581F3E7
+:10BEE0002371D2F3E3C25E2126BB8694B3FCD21544
+:10BEF00059AFFE19E33E5B9319CB6EFD8E83E6D9F5
+:10BF00005D2FB9155C37D81FEF7D1FDA8748E4BD78
+:10BF10006FD37D2D616724C9E793463E4FE1375FBC
+:10BF200028BFFA10DA61309F4A8B93EE731E02B27B
+:10BF3000C906B951A9B067C53CA02AE8AF52CE3BAB
+:10BF4000D80FF3FA9C9C4EBB0ABE4EE4F1C58D4758
+:10BF5000A73A902E2BADB6537AB9658E7BDC956DE2
+:10BF60008C7B7C4E16FE33DD0B2E64FEFF030B2B09
+:10BF700033F57197C1B8873897A6AD62F2D424E73C
+:10BF8000843CB3D8D93D2324407CEE0C1A3F627028
+:10BF900007E71AEFBDBA4A94D13981F24C8E2409D1
+:10BFA000BF87755FC59F6475280BE50CA6F3E07825
+:10BFB000E0F565E1B3FD4AD587CFD952D0CAE61185
+:10BFC00066F987A4250FDB5BECFD328E2FE214743B
+:10BFD0002619D88F1897955DBCDC51F7D9CAB5BE24
+:10BFE000A1F10CE27451BB57E1F33BE9766A165DAF
+:10BFF0009C23C1193949F356F9D31CEFB853D634F1
+:10C00000CCDB4E243D545E3A9D7FD410186EE296F0
+:10C01000B0FC7D29F433E4B7E34A17F1C3FBB33F27
+:10C02000FF8220FED2F16458013E8DFAC9EBDC4854
+:10C03000F3A1BD41AB492F8524E4A3CC7AF37BA3C4
+:10C04000BEB2933E7A6E488A04B3CEA75F388E1391
+:10C050002F7E63AB64A81FB899D9C36F27B2EFDFF7
+:10C060004E64DF1DE37AA6394D212CBE63B7A33D94
+:10C070007FC675028F6AA23EE9447D62B705285EDD
+:10C08000855E59BFFF5682786B3E504BE1F05B896D
+:10C09000ED8F6A2B249AC7B094E7DFD51791D702AA
+:10C0A00038B59C7CA6CF5E0EAD688272DDABA4383D
+:10C0B00002ED4A6607ABF15E97F662A26E8172BB33
+:10C0C00023F4D44F711D47D93D631BF8795AC0C47E
+:10C0D000BABDD0FFCEEB46A9DB714955035B314FAA
+:10C0E00068601B71635EC910FA3D07FC00F4B00B79
+:10C0F000CB30EF0D6B42FF7A07B4CF7E95A8B40D1D
+:10C10000AF471F05F12771BAC0F7B3E1FD064E47EF
+:10C11000050725B6BFEF61F77FD1CEF17E2E3BFB41
+:10C1200075C3C18A6BA7C2BC0A7AA750F21E03ED81
+:10C1300031FF093310587B6289D57E0CB6F7E17E5A
+:10C140003EC30FC951E8BD4984CBBF69263E9C114F
+:10C15000E5075A5FC2CB1BB89E32F00DF603FE7A9C
+:10C16000A08C6DF7D3EF3C8C3F54227E183F4F27B5
+:10C17000D11FECB72A3A0E95CB7378DDE1E5F36970
+:10C18000DEF7346BE405E4F719FC59C29FC8EF767B
+:10C1900080E3326BCB612FAC27751351DB709406B3
+:10C1A0005F3BF6574A8232C2B9CCBDAD1DE7776519
+:10C1B000C3D174A4AF753905949E66DAD502079091
+:10C1C000487BB9AABA0BF09E3189C26549BD3D8C46
+:10C1D000F96D4B06EFF909F99702FF2C0BB1BC661C
+:10C1E0002C37E8E2B522EF6F6902F8D531E4F7BAEF
+:10C1F0001C662789EF37F07329A2FEA61C96FF71F3
+:10C200004DCEDCD21C9A97C4F2A181FFA76159C818
+:10C21000151897E6AB2C26011BAE6B31E75FC1FF0B
+:10C220004B02B7537B7649D06897FE5662F8D69694
+:10C230004BD44E5C563FBCDD3A3747EC07E7B98F2D
+:10C240002745DF0BBA12F27C11EA7794C335A0CFF1
+:10C25000757673C39DE752E977994FAE3F7F59F4E6
+:10C260001CCC06D33998667E0E66C381365B06D237
+:10C270003B3F07B3E1E0875BF5F97F024E43CFC157
+:10C280000CD0BCC7A54AF8053C1FB4F4165823B41B
+:10C29000FF153F37F1229E9B981CA523D7758E086A
+:10C2A000CBAB0BD0FCBE3C77928AF9289D96C93463
+:10C2B0009FA833D9A5EAF377B6B7B554633B914746
+:10C2C00024CEBD2C8DB35F7C7B0EB3B71F92583E3E
+:10C2D00097B6DC4EE1ED95C931FDF97E6F4190E6F0
+:10C2E000D195E6F8447B1A5FC0BCD329F00C839942
+:10C2F000C6F0C5BE37CB07E8AF03FBAB2A5069FEDB
+:10C300004C550ACB43F3A6074B6E2B8AF65B77900E
+:10C31000E5EDD5053F3DC2F26F6B4B119EF1E4BADE
+:10C32000597F01FD75E6C488D3DF29879A91FE6C99
+:10C3300095C1E56BA1DFB3AF2934CF8E6C0E4836C3
+:10C3400068F79357DC2A9EBFEBA808D656D37A2B02
+:10C350003D1F98514F2209505FFAAAD28DF97D8D69
+:10C36000A44BC17E1A4D7AEC16E78B0AF2E92DBB7D
+:10C370006D51BA249897A816A0C06BDA3B242E42C0
+:10C38000E590904F667A26638C72A844C85D900F42
+:10C390002CAFAF81E93DF2A484F1A1B3AE1332F723
+:10C3A000AFA9DC9B2A849549DE4F3DF812B567049E
+:10C3B0003C6781BC403F4EC2F793D8116EBABFA50F
+:10C3C0004985986F3A8324527A1B6247F0F9950E9B
+:10C3D000CE9FD94D424E56943393D48C1F188FD292
+:10C3E000B9D8E79B8AF7FAC073061FFF0B4BA0284A
+:10C3F000E2477C91B005E0BC556AA17AC78EF99FEF
+:10C40000F0DC2E85A85CFC99A6C908D72B49CBE2A5
+:10C41000857E8AF72339543EF626211E8E2BAA1DCF
+:10C42000EBAB3151903E8DF89AE77CD08AF09A9729
+:10C4300065C68B6645F8CEF70DC1173D571088834A
+:10C44000AF80902BC42857FCE41C3BD7BCEDC81D23
+:10C45000E81F5FC83E793023D48FF2339E9D122FA0
+:10C460001FEF2497C723CDC73B6B637EC574D27F74
+:10C47000E35E69289D9C39BC49CED2D193A0D3E715
+:10C48000787EBEF44B9EEF5BEAA2FA2FAA2F191D0D
+:10C4900094F1D274A42F1D1D5C75C01191619D256E
+:10C4A000FCFBE9480F93A3FA326271FA947CC4BB97
+:10C4B000DA29CB43EDE48C341FC5FF144B80E27FB7
+:10C4C0002A51D3B9DDA9E4C2FACBED3DED561FC523
+:10C4D000FFF7D1BFA9203E8AFF0A93DEA972D65981
+:10C4E000914EAAEC663C0728FEABDD43DE5BBE0A3C
+:10C4F000FE2F43FC0BBD3202FB14F0EFCB1D669FF9
+:10C50000311EFEC7E73A795CE3E2F06FC6BB9003E9
+:10C51000FB1CEE2A27C6831B593EF294D7C6B46390
+:10C520003963BD9F9E93D997AAFE8AD6B7B0FAD237
+:10C53000DE808CF732166C847A28EFF307ABB0BC40
+:10C54000619344E5E8D43743ED581EB399D5976C11
+:10C5500069F915DE6FB64163DF3F77722BBDA72205
+:10C56000BC957F5FD15585E50D9DECFB3FB8EC1A7E
+:10C57000FAE565C7C2EDF87EFC0E360F61F7CDE631
+:10C58000F4B64F7AFA57F4BB2EF6DD4D47EC89CC62
+:10C590005F6276DC2CBECED98FB1757A7E77758DD1
+:10C5A0000FE0BE7640B351B961692AA372348E9F01
+:10C5B000562175E5E1731EC80942F10E749ACFF257
+:10C5C00055BB6188B5B9CC0E11799E986F5EABC32F
+:10C5D000D7DA5CA66F45BB8C34C2F2921F65F7CDEB
+:10C5E0008A3CD4C8C344C2F801AE91EADF3879A9C5
+:10C5F000F30A5AA83E9D7799C847EDB7AE86714BAE
+:10C60000CEFFDFB9B1FCF2263EEE099E3F2FDE37AA
+:10C6100086FD16F44FF621F1D0FB7F7EFE1ADA2D4F
+:10C62000FB701F5977FFC83E3F2BFFEFDC67EFE938
+:10C630000427F7264B8B554325305AA2F7A97CA334
+:10C640009744529287CE7F9E954458DE049BFF8D7F
+:10C65000ED4AF7769D1DBF44888F9963A95EA9E3D3
+:10C660007812726309C717F0793BF2C7527B0BB59A
+:10C670001B9713A6D76F26611ADFB8D9C4E7EB9CC6
+:10C680007F7ADF82F6F31E233FAF87E9B07DF58125
+:10C69000C7DF05F8373EE272A3FE5FDF636CD7F8B1
+:10C6A000C86BC798FD65E4F746C1EF6123BF8341BE
+:10C6B000C1F8FDE10974DF469C0B74D807DED7484A
+:10C6C00074BD837ADFC47F0E3C2758887E8D85E554
+:10C6D00027F2B218F7B32EA69735D0CBDC0FA222E3
+:10C6E000F7B3BE05340FBE44E8512E67043F977080
+:10C6F0003D3F448FD798FD9D07299F4CE125B3FE10
+:10C70000167A5B9C3F847EA9FE067DFD5A00E6DB1F
+:10C710006B718611DE51BD1DA67C34D90EF2DA4252
+:10C72000F1F73CCAE9A91C6FED5CAFC7F50F9C1B84
+:10C7300063FA07E06FD07D84A17E41C460EF9BF176
+:10C7400016CFFE1FC49B03ECA924F4F709E3E31CF6
+:10C7500032A2FC1090DBEFE40EA3B79543ECFDC0D2
+:10C760004E078D2F8838BBE0BFDFE4B1F8C277B346
+:10C7700003EF613F7D7CBC3EDE7FDFADF3E8BEF7BB
+:10C780009F4880EE7B631E536E8CBC0BDCF7EED0B3
+:10C79000C54BFB5263C7C13FE17260621E5BDF198C
+:10C7A0006FE034F2D50985C5D94F24F26732DBA793
+:10C7B000F82297C57B27E6B1A72B8FCB119EDF7D93
+:10C7C00022CD189F17ED52F8F3E3567BB043170FB5
+:10C7D000F73D9CD0827ACC5BC0F3E137323A3EFB26
+:10C7E0006CEA4EFDFD7039791513F3304FA420A08B
+:10C7F00064637CE659A62F9AADFD0ADEEB93E20D49
+:10C80000D9F2302EE32381A7B11F5FBFB218E07DBC
+:10C8100096EFF79FE5F7009D75B0A798574E5EED30
+:10C8200044FCEEECADFD546E0C966BFBA95CC8C9E4
+:10C830000BD271CF2E11F5BC7C0F2B13EE57567017
+:10C840003EA171E31871E2A17161E33D371B94D8F9
+:10C85000FBD424CF6588F7AE38C8E2902BED646B2B
+:10C860002ED45F7F3093FA1B8DC9DA38A487AF1BB3
+:10C87000C73D3BAA97AE6B7BC5C0E8474BE9BE30CE
+:10C880008D17AD3FF812957FEB05DFEC37F2CDB495
+:10C89000BC91EDA798E3EC23E0A78ABC61ECA0670C
+:10C8A000507FD9A278B88DE75155CB4D551857FA1E
+:10C8B0006C0DA1E76B6F7B45A67475DB5312BD6FE2
+:10C8C00042D871EB399CE3AD0BCF27F8747205CFDA
+:10C8D00027F8747E1D9E4FD097F17C82BE3D9E4FFF
+:10C8E000D0D7E3F9047D3D9E4FD0974BC80DED188E
+:10C8F000A7DBD049DC611F3BAFA0FF1ECF2BE8CBED
+:10C90000785E41FF3D9E57D0973F230C6E9F3D269A
+:10C91000D3F83F9E5BD07F7FD32B3F298BE0B21DA6
+:10C920002C3FADDD01F0473AD402BD45009F351CD8
+:10C930003E78AE41DFEF27C9735F46FCACE9BD71BD
+:10C94000213EAF38708BA15FD2C5E4710BFC433838
+:10C95000DE488229E8CF4D26034730DED11C9654AD
+:10C960001CF7A6478C727BF01E93B0F1FD3AA28BA8
+:10C97000FFFA87C6FD3BF25C9EE32CB739471FEFF9
+:10C9800089D283538D201CDE94D558F450422E4F0B
+:10C99000A1719E97658C61903F909687664ABAFD1B
+:10C9A00001133C12B28C74E1F019E922A9D04817A6
+:10C9B0002ED5481729E546BA480D4C1816BEE9355C
+:10C9C000463A59273751BE17702E877F08E7C97836
+:10C9D0003325C217D689F162337C1B0FDEB715ED04
+:10C9E000FE8B856F4F1EDF57E1F0FD9CCCAC72FAD9
+:10C9F00068759DBD2C6AC794BEDC423781CDF1536A
+:10CA000001476147883828E87F6A4F47FD7AE6EF9B
+:10CA1000817DF04B94C3C715E6E72125A1DC5C4B73
+:10CA200042543EAD35D90737391F54D03E18B25E57
+:10CA3000B0CCF0DE42F37AD1DE22BAB894D93E907F
+:10CA40000E4A11D7245CEE4121A743E7A931149087
+:10CA50004622377EE40ABC85720B1D457B99216E08
+:10CA60001CD3EE13F3107011E3279016390BE9B9BC
+:10CA7000D06C9F19FD6BE18F8B78BB886B0B7F5A55
+:10CA8000F8316638CB97F9DB91FEA7B8851FDDFB3F
+:10CA90004D7C2FFC67B3DF3A781E00218BE76D7861
+:10CAA0009CFE6EEF6A3BBB8F8FF19D78BFD5B3289C
+:10CAB00065B83CCCBB5A8DE75F60198161CF13210B
+:10CAC000C83270DF89605085ECB8E6483FDEB1B30C
+:10CAD000E31BBF1E78119EDB8B9FECDF8275E7CED8
+:10CAE000CB08D7C1783E61E78315FE9D92B7F55616
+:10CAF000D4A389AA957CA4A30B3B68AA8F0AF9B892
+:10CB0000A827B206EB7FA3DFD7FF473DBF0BF0F9A5
+:10CB100068EC30F58ADA1833AFD6042F710D86A38E
+:10CB200068EE49B44F1C44B76EAA0F7565390A2FD9
+:10CB3000AA5A657A5E4AD407F0DE92AFBB2EC4FBD8
+:10CB400047367D3972F4639B7EFE619657600D1205
+:10CB5000CCBB553C50AFD72F8374080C55A65BDF78
+:10CB600008D6854C83EE27B34B18BEFF56EBEA3050
+:10CB7000E10BFB0D665CD2F3D32EF1F9452E71FC6F
+:10CB800092DA4B1B7E81DA4B1B7EDA253EBFC8252D
+:10CB90008E5FB2E8D29E5F60D1A58D5FED129F5F80
+:10CBA000E412C72F597C69C32FB0F8D2869F7689CB
+:10CBB000CF2F7269E357A376A0B33C42F05E095FC2
+:10CBC0000751FD3E3059E135FAF3052AA1791A845F
+:10CBD000FB25F9DC2FB96F474B3DBA50BB34C54735
+:10CBE000E341E0DF6741FD78C2EA77752EA271D696
+:10CBF000B651E372F09E2A67E7DC93786E6FBCC68D
+:10CC0000FC71F3DF0BAB0D18FFEEDAB5E5E986F248
+:10CC1000D45EE3BD15DF6C2C30D42F0F4D34FDDD19
+:10CC2000BC29C6BF47169C61BA7FE156A23F0F9947
+:10CC30004F222AC657F2EFB154E2BE99157DE62B7A
+:10CC4000E1FF6E857E17807F7AFF251F3CA1C1FE24
+:10CC5000FD0837C5D0BFD3547FB1E74F9F19CDE34F
+:10CC600031A6F3A7042F978C71DEDC9C8749AC3783
+:10CC7000D3F89CC0D7DDDB2CD4E5FD7C07A1F73BC6
+:10CC800056857D167AFF39C7DB444E7A62DDE15660
+:10CC9000E339F47C8D54223E0B3A8805E36BFEDDCC
+:10CCA000440D101A17A274B24B8B4D27BB88BB12D0
+:10CCB000EFE3DA1526F4EF6309BAB8DBE6CBC17D02
+:10CCC000B5899D8C1E049DF8904E92312FC87CDF53
+:10CCD00080195F647204E6BA6B477E9A3E1F95EC3A
+:10CCE0006570B7C3BFE1F055B8DB882F1FD195BF82
+:10CCF00002BE4E7F4D7C299E6024C583F14CE2C369
+:10CD00003CA9C3A3C659101EFE4E95FAFF35D00CA0
+:10CD1000E1ECEF64F7A8093C89FE76B492C81C9D4B
+:10CD2000FFE75723018473B55C5489F9E73B4B69EE
+:10CD3000C878087E76127722C6BD77765A12E9DD6A
+:10CD4000D407002FC584FCD7B6A5298550DFED2771
+:10CD50008978BF56779B85DE57D6FDAC546FBC4FA4
+:10CD6000399260C9A2EB48B094D3A7953D03FC4922
+:10CD7000ACAC3E226379F4E621F77DC8589F5A6334
+:10CD8000FA7B812420617BEB652C8F332560BCC747
+:10CD9000C6566E940700C6DEAC328CB7707AE7F7E1
+:10CDA000A386AB4918FFCED7655CEE98E928F5AEAF
+:10CDB000459498DA467D8BCAB3EE3685C2DFC6E568
+:10CDC00015D9CCE842837F484FA9263A72A9463A42
+:10CDD000B2C979340F57F095988F18BF6D5446A299
+:10CDE00095CECB4AEFC1B699E584697E4E0C06021A
+:10CDF000EE9C1E120E43BD4D63FC41E43EFADE364E
+:10CE00008D9074FF5798E7D7944F575F16FB7CFCC3
+:10CE1000C5CA2717EFF3EEA96C9D9FABEC3EEBAABA
+:10CE20000E46EFAE1D8CDEF12437CBD70A2CCCD6C4
+:10CE3000EDABEEE772CA0C37576FA00AE979AEFC8A
+:10CE40006A00F323EE7993D17FDBA8B75FC6F28E39
+:10CE50007B18FCFD2AC333D08B1A81A9DF7397930B
+:10CE6000E6054F29057C21FE5F35CA93A9BD4638EA
+:10CE70001698E4863F0E5CCDFC1A0FAE7708B89684
+:10CE8000015C0B2E1EAE8AC6E473EA4C76BFE2E16B
+:10CE9000510AFBBBBC1A83636A40A5F277AE7C2EB5
+:10CEA0009202EDEE0B80BC8179D60418BCDD33858F
+:10CEB0001C37C253C81701FF7C0E7FB7EA7E05FFFF
+:10CEC000BE8B53B3129F84F0FDAF00DA115D538522
+:10CED000BC192088B79400A35B01E7AEAB189CF3A4
+:10CEE000031CCE9D1C6E129110CE667A35CBE79452
+:10CEF000AF09E76E01E70C52F655E07C5F12BB3FCD
+:10CF0000D93686C1D5E61C88A09CEDF45BE9BA5EF3
+:10CF1000F02BB4BEB398D53F9CB4320BF56DA77718
+:10CF20006B16D2659BFFC62C94EF8E2C2E6748C0E3
+:10CF3000995D163D77502DEFA0F78F6EF529143FC0
+:10CF40002E5F6CF995323364A7E31459894CE1F0F4
+:10CF5000981A0B0EF652C5202F731B8DF04D32C15F
+:10CF6000D7F135E5C37F7E4DF9803947D8EEEEB174
+:10CF7000E27E862E3BD54FE5B7D0B879011F6BDB3B
+:10CF80008EFBD97BAED774EF6BF2519E38AD2AC2BF
+:10CF900033DEBC859DF338BF0FE67E7E9F4B17BF07
+:10CFA000CFE55E7E9FCB0E7E9FCB76BCCF059E9D50
+:10CFB000789FCBE5684F07E853BE278DDE3BF839F5
+:10CFC00026B0FBF1DE9C3324D6FD247ECDA8FF2EB7
+:10CFD000DB64BC9F2CBDC6A8E75203463D87FB5EC1
+:10CFE000FA7A976ABCAF2DA9D0785F9BC367BCAFB4
+:10CFF0006DCF6521D907F0FD7FB1B1C61E0080005D
+:10D00000000000001F8B080000000000000BDD7D09
+:10D0100009785445B670DDBEB73B9DA4BBD3095912
+:10D0200081849B950E84D040C0A0416F16302A8326
+:10D030009D088A8A1A013140481075CC3C9D97861C
+:10D0400004081830A0A8332E34EBE0B845272A2A6C
+:10D05000321D04069FBEA1595474D4BF757C0AC802
+:10D06000480417FC9ECBAB73AA6EF7BD371D088A28
+:10D07000FFE77BF1934ADDDACF56E79C3A55313B27
+:10D08000CB88DF4AF0E747F8C7DB4D3C76CC9A48BF
+:10D090003221D9BC6CBCF8B0355840C8B2B6EA38B9
+:10D0A0005200F594402A2D8F85429990A566777F8E
+:10D0B0000FFD1EDB366B227110B2B88910FF604283
+:10D0C0005A9BAC982E4CB7B8FD89846C7853744742
+:10D0D000D12616C5A33869FDAEF42584D0EFCB9CCC
+:10D0E00084A464D2EFCEF984641122D101049A970A
+:10D0F000DA261C2185B4C1D4B9848C09CF67599B29
+:10D10000C9ED2F22242ADEE686F14981F45190965A
+:10D1100039E97F3FD2F63FC2CF45E1348AB0725C35
+:10D12000278C236BF204C6D39737BE273CBD5353DD
+:10D130003E58B6277E028B3D8F9CF7A34853715A09
+:10D140005C8D8DA6AD09848CED39DE374DE4E99D0B
+:10D15000B90850429220AD25004F89F7B934BEDAA4
+:10D160004A6C6138ABDF173B197CA30412B1DF16A0
+:10D17000806B54382F11A274003E061645ACAFA642
+:10D180001403848C26A4ADC9BFEF6373F8BBAD84D0
+:10D19000B6B7F5AC5F298B38EF29B28CED6C929F56
+:10D1A00038693DBB9BB6D7C0C5A69CDDF8F4A7285F
+:10D1B00091AED7C1E9863C214880572BCFC70A35AD
+:10D1C00053E424C09787229BD62B56484D011B4F12
+:10D1D00051DB09904AE42357185FF0E3A4E50CA45F
+:10D1E00090D272ABBE5C4E467861BF52B8BDF2A31E
+:10D1F000D0FBBC7FA914F0F851EE69CA2DEE5AE0BD
+:10D2000027E3F77F974D2A1CBB1329DC44BEDE08B9
+:10D2100070FC772D1C451B83638B90B93548F9CD85
+:10D22000AC38DC1423A43451EE00BE6C516CC897AA
+:10D230002D891D81329A3F5964724357F6DC32E4DE
+:10D24000C796FEBB0FCD04B84EDA737823424D0962
+:10D2500054A8F0A5E5765765A042C50709E32B86DB
+:10D26000FFBE7CD8E6E0229AF6BB7C1A715252B11E
+:10D27000A5588848F1129D5B61ADB185F163815F6E
+:10D28000E8F798C4094744CAF7316E0D1EE1FF1F45
+:10D29000591EE141176F19B8E41601882235546F01
+:10D2A0002FCC47923DE1F991738F2F329002298D57
+:10D2B000A6923B15E4654F7AF732BEE7F57AE70BA5
+:10D2C000566FBC3831F5460A97D637A87C04BE7035
+:10D2D00031B960B6327CB61225F546DA55EB40C955
+:10D2E000ED857CE274941F4B52AB5B417E7E95686A
+:10D2F00022A200DF1759417EC0EFDA71933C26E28B
+:10D30000D7E027656A8C4EEEB7CAD528CF7A9B67DF
+:10D310005A8DBEFD805A7DFBF4F909BABCDA2E3A6B
+:10D32000F5B20315FDC2F96592C70A726471E26A2B
+:10D33000A14643DFF1F93507E5D1E1BC397512B6F5
+:10D340008B4A2F8A382FBF4B3904F5E9FA991CB65E
+:10D350002546943FF7F17DE87EBE0F9D699D0FF253
+:10D36000FA7FE4F51F6E72621AC267CE6C1D5E967C
+:10D370002651794DFBDB0C5534E33F23D71C07FEC8
+:10D380000BE3D914860F306DC11C13F0ABDA4F4B91
+:10D39000D274C49BBA9EDEE6D7CAE5BF5ACF2A79BB
+:10D3A00089BB00F91EE57008EEB21E5F05995C6E40
+:10D3B0006C9CAD1B7767FC84A99994EE961C14496C
+:10D3C00014CA11FDFA7AD2AB7E1D4B12D9FA7BA793
+:10D3D0006FC3BAA94408CD0BF309867C7F43FD2CAB
+:10D3E00043F91043F94843FE7C43FD3243FE524368
+:10D3F000FD6A43FE1A43FDE986F23986F20586FC92
+:10D40000BFE9EB17313CDFAE7E3B8D7C01BC1AEBF4
+:10D410004B9282F8950CF8353BF5F82D4D2F3D3F9A
+:10D4200013F7855A1D7E55FAEC2B7E96521917007C
+:10D430007E926A987E523C8768E961496216EE1FC7
+:10D44000622971B3564C4E5978B998C6C6A3FA9A58
+:10D450008E8EBAD267A1FE481E4C6072F30C742106
+:10D4600090047DB9D23F5C9E05FF9E5BBA38331DA8
+:10D47000FBF8BE7BFA79AB7277CB20CFBC4C901710
+:10D480003EAA4F0F0BC3490EE9D37430CA77EB1392
+:10D49000892F8AEE77EBBD26CC7F954A07027DA5C2
+:10D4A00062B64EFF262428403F4639B00AE4144DA8
+:10D4B000EF013945D3BB9B52315DBAC2943613FAA2
+:10D4C0009B6841FDB8DFF0255E09D2B2E27CD8BF8F
+:10D4D000EF1EB64531D1BCFD9448FCA3A8BE5078E0
+:10D4E0004D312C2776FCF4D49D30DC77749C31C010
+:10D4F0009D04958C7515C4671E4EC88A1D6997BA20
+:10D5000068BF728EE48E86B202F7422911EB79C1B0
+:10D510006C90A5EE3DD9343F28C784FA85B9B8BBD5
+:10D5200009F47775DE2B2EA5844B2B6656BA4D5E1B
+:10D530000A823B07D5DC0B701AD4464C0ACDCB5E71
+:10D540005900B9F666A68CF0DEF02265C86C18A802
+:10D550003B0DF6D9AF575816C13C7BC713114DC5CB
+:10D560003F3D55FB413DB33F7E57402ECB129210BD
+:10D570005DE57FB52B346F1359FE95CC239E459AFC
+:10D58000FCE399479C906F1B9561827564263A1461
+:10D590005F04BADA0FF298AE7BC38A5983B4FBA05A
+:10D5A000319527D27E53685AC053A0B5F300FE3C94
+:10D5B00095F9F754967F0DE046FB951B7979224B40
+:10D5C000CFF538C6FE0F643A55BDB43FB71F0B6C9C
+:10D5D000C9A7D54FF783BC32EAA754D0F5073A5F05
+:10D5E0004BED4913ED7BED0A0BF1529E5A9B4ED049
+:10D5F0004EF42EB3F836017F4872FF2B357A976FC1
+:10D6000059F23580179F40A66AE5E4FD1CCE2BB386
+:10D6100004AE671DF38A947ED7D26D13C4ED5AE22F
+:10D620008C067D24846FEF098FA2C1F78559A5ABC5
+:10D63000BC30AF996CDFCC0AC9B3BC8512ED671D55
+:10D64000F443F3EB5A4D38BFB5DB28FFD2A1BEBA85
+:10D65000EB2313E8CDC388DF04EB1B4A7C98BAC8E0
+:10D660007C1300A583EB191B39FFE651FE467B07AF
+:10D67000441F2DF70CAAF91AF8228EC89897BD4EB0
+:10D68000A4A7FA6DF16591F4039265E27626A99557
+:10D69000C6703B87C199648DEE097F33998F70BF47
+:10D6A000DDE53141B96DEB3EFF005AF4DCDB7ABABF
+:10D6B00005A8546BE44E0A1F27CEED5144DACFB6CD
+:10D6C0008C9A58685F5FFBC5EE64E8DAEBC5F6A399
+:10D6D000B29C58EF1A7FC778E866B83B5806B4305A
+:10D6E000ACB26B0790CC50651D9819C4557CCB8E9D
+:10D6F0007E32CCA326318BD6CF0B044B817C6CB50C
+:10D70000FBFCC9389F0B4D4017D9301F4E1F5548A1
+:10D710005F32D2898A6FA0872A9ABFA68EC1875AA4
+:10D7200083584E24A76EFEEB17533AB1F5A4137B32
+:10D7300016D38F866485EC2B623EBD7D35242B820B
+:10D740007DA5C2A5BAD36D067781E709E762B081EE
+:10D7500026F9BA7746D3EF8B326A4640BBA2073D23
+:10D76000CD407FB66D012FD453E1642B092802D63A
+:10D77000538A00AE6BEF2A2BC37DA19DA0BDD49B25
+:10D780009E6B2E31E9FD38A41DD791DBAED7D3298E
+:10D790001DE37EDE838EEF0AD1718CD62FA1EE3F82
+:10D7A000BE36538C0BEC0C6A7F605FBDC891CD7C9C
+:10D7B0005F52E95AFD9E4322FB19A686E19D2A9EEF
+:10D7C0001EDE5323C1DB01FC918DFC320DCA9DA4EA
+:10D7D0001BCB07DDA5E797FAAD5FEC1E40E76F2B8B
+:10D7E0009247027ED4F167717AA6743C13E9F8C1BE
+:10D7F000EEDDB0AF0DBA8BD1F13CD03592C2F478EA
+:10D80000BB4BB919C651E9CCB89E9B787F8B323C93
+:10D81000F3B0DE831DBBA2B19DA701F2B60703FEE4
+:10D82000681286EF200EDFA8DF87F0EC04F9513D87
+:10D83000D1BD0BF6678FCB391ED24972770BA81674
+:10D84000D7D68A3ABDCF885F4A5FBF877514114F1C
+:10D85000B9208036DB61C6FDB317BA09EF9B5E5570
+:10D860007EDC7506B9BD2C121EFADAFF890C4F3B1F
+:10D87000B44FA8F490D3D96D3DE6D5C77AAADF2C72
+:10D88000ACC7FA747AAC4AF7CB5BABD1DE52F1A0ED
+:10D890007E5FDC5A5D9909746E93DC91EC9FD07EBB
+:10D8A000C3E9FC514EE7ABB9FED5CEF5AF954D328D
+:10D8B000CAF7B62617A6CB9BDCDC1F5A8CE9E226FA
+:10D8C00005EB89CB4E94A2FD7E1741BFD6A2D8426C
+:10D8D00021125D657AF5FAFEA0463DDEFB55EAEDC4
+:10D8E000EF78ADBE4CFF8F2BCED295DBDD4374E5D8
+:10D8F000B1AE91BA7CB47CBEAEFE964135AF015D4F
+:10D900005912CB74F548F00B9D7EABC271BC380D3B
+:10D91000F57D0A4F660F707D562D27A48668ED149D
+:10D92000759D6D063D7639C011E1CBE0D80E70448F
+:10D93000F81673785632BB89DB3D31AADD93BF7A86
+:10D94000EAF444D4A7515E2D4CB7E0FEBC3C93E909
+:10D95000DB3DE82755233F29CF2F5DC6F673551FC2
+:10D96000DF95FE5625E8B5EB534D2827D727EE70F7
+:10D970006DC07C8C9BEDA7DE7617C59FD9C5FDD504
+:10D980009462D3E87AED9C6F969A09FABF9727D9EB
+:10D99000DCE007B3BB664DC47A867109B98568EDD2
+:10D9A0003FF271AD4EEF20D26CDD3A43F32FB2B0AF
+:10D9B0007E0422403F0905161DFEAC4493CF84F936
+:10D9C0005AC278CC84F5723C19F41CA39F421DCF37
+:10D9D0003951BFDF2CCD67EDBBD23723DE8DF0751B
+:10D9E00054E8E97739A78B96A4F5C887C6FAC6FE2E
+:10D9F00049498CCEFE5BEE3ABD9F44B5A7D57A600F
+:10DA0000473B23D437DAD1E7C25E77E278FAFD2EBE
+:10DA100082BDEECED6F893547887F0A0FA17B91DE0
+:10DA2000A6FAADD5FE24C2FAC33CFAB7BD28FF1E44
+:10DA30008875A01D9963B3F84016E6D079001DB72C
+:10DA4000FC21D6B788E657C54EEA8EA3F99C8DA275
+:10DA50008CE5360F9EDB74AD99D03F48C77D48A852
+:10DA6000199FADF1C36D8CFF6D2AD307A48F822E51
+:10DA7000607201ED5CEFAA510105F4F17CE2DE4435
+:10DA8000C00A66E52A3D116D5EEC99FF3C9BEDFBFB
+:10DA9000A9D792F91D11F0DF9CCDF6D1B01CF7C4C7
+:10DAA000A0BCE6723C87C36B537B758C568E6BBEF5
+:10DAB000C745A2AB7325BF5B407E0F8671F62BB8BE
+:10DAC0006F17112EBF9F22BF46F93D27B36621D0A5
+:10DAD0009BD978DE2705517E0F939545501E07F69A
+:10DAE0001EE0E5068A9708EB7881E3EDD78A177583
+:10DAF0005FDDD4FE2CC34B818A97952492FDFB2BCE
+:10DB0000C04B27C0BDC7BE4A82780EDB3D50790EA0
+:10DB1000F8F11959791ED2107EAE8ACC379FFEC219
+:10DB2000F87994DBADAB397EDAB97F7C25C74F1B22
+:10DB3000DFAF9773FCB4F2FD7A09E027EAECF966EF
+:10DB400050A31E3FFD2A630CF8D0E327AE588F1F69
+:10DB5000BB5B8F9F58D710033EF4F889CB91991E79
+:10DB600099AAC7530FBE3983BDE2807E22F83706DB
+:10DB7000D6044AE18CABFFD48E2E3374E2692F8534
+:10DB8000545DEFC306BB544DE372983C4C2D8F8C13
+:10DB9000F7EF38DEFF98A5FCB78E8F2F8ECCC7A687
+:10DBA0001C56FF13591172B4747559E4FA565EFF8E
+:10DBB000E020252A47D33FFDB94F3C8DBD605C7FF7
+:10DBC000ACA0C4E5E03AE4AD418AFB8D0BD939E461
+:10DBD000C668B903CEF3BD0B6DEE4D32F6E4B182EB
+:10DBE0007DC4FB21DE38EC37830F33C8B6E75B38E2
+:10DBF000F7CB9C31B0FFCDB43C7341EAD11A9AE621
+:10DC0000E464239CB26ADD3B00CEA2636A7F767E29
+:10DC10003CCDF9C9504A6AFE7EC28F60703B13FA50
+:10DC2000742E47E520EA817422BE4D944EA324222F
+:10DC3000D91360BD0AAECB0C7AAC08EB6DC77C0C77
+:10DC4000E9C0D44602ECFC9ADBA3A37332115E4E0A
+:10DC5000E2447B3581B83155F9D89A48A4A491D8CB
+:10DC60007F4BD448821BFE0560AFDA06AE5B0E36F2
+:10DC70008D42A130065905E121DCB71BD74F5C442A
+:10DC800066FEB6BB9C189FF01A5DDFD0BEAFAFAF8B
+:10DC9000F5BE8976149238421AAD2CBD23C6B11E4A
+:10DCA000D26FA2337CE0B43A3FBBE63780576F199E
+:10DCB00041FDC3FB41ACAF19273BFF3C661FF4B9E4
+:10DCC0009F2BCF513F379CA37E6A813FCED4CFDDBF
+:10DCD000F0EB5838C7F4D4C1B82DF16350EF54536A
+:10DCE000235CFD2E653EF42B590F647CDC2FACB712
+:10DCF000D9DE13506F6B11FC04FC94DE0F05D4AF1A
+:10DD00004801C3934D26AECCE1E17E6CEEF98398D9
+:10DD1000BF8BF97B16BE7FC760D0BF1F889D148C58
+:10DD2000A3ED37ECA37A1EC4D194BBDFADA5F49468
+:10DD3000D4CFE25E4FE9A71FB793A3568CD95B4BB4
+:10DD40007FFD6C30932F5B9AF6385BA840B24BEEA8
+:10DD50004B46D276367E7E4BC48941D01BED632480
+:10DD600019CE38F2457F25CC97349808F0C5437515
+:10DD7000FAF3DC2579F9D89F9A1FC0CF734991D463
+:10DD80001D8AB3A17AFCEA1C1E57E3200ED00BA516
+:10DD90001F94B848710F6AAACEAF2891EE5B71E06C
+:10DDA00017A49C42D3A2363F067F94B9FD56D06398
+:10DDB000D7F888D742E1F4D874CF6CE8AFADD81368
+:10DDC0000B7AF99A83D5970DA3F30E04253780E0DB
+:10DDD000A5C10938CF8022AE88A5DFB7BE6772C261
+:10DDE000FA36F0F66D1E01F9FFA169C4E7A5F0D877
+:10DDF00050B7C32A82DE1B30915CD473A9C135862B
+:10DE0000BB4E64F0D732BEBF6370127EEC0C2C8820
+:10DE100007B8AC8ABD30A0D0FEAB2A99DF79823832
+:10DE20007017F41B68B3207E9278FC9140AA507F53
+:10DE30004E98A6D197E9FF761E0715B88D60DC5382
+:10DE4000DC681BC6013C1764E7460F5532BFB3833D
+:10DE5000F871FC09E2B66813FDDE592939819EE2AA
+:10DE60000CFAB90DFAA324D7F920EBCF3182F5676C
+:10DE700037C44159D57939E9BC28FE44BB8478764A
+:10DE800056EAE3A71C867636C3787B01CF20970637
+:10DE9000923CC0F349CF6F471DC052B71C297EA2E8
+:10DEA000AD89042A34F116B65EFC875FE431BAB559
+:10DEB000A4EDB4C2BC4E7ADE4A0477D71BDFEFFE76
+:10DEC000F81E487FF88FCE06BAAEFFFCF6D0C6A784
+:10DED000018E8D77EF473AE476550A4C81CE67572D
+:10DEE0009505E1385A61FE0152D4B5D35C84E578DA
+:10DEF000AEB5624734960F2826BE680ACF019292CB
+:10DF00007613F06B40742F94A113C5963686B0A398
+:10DF10002A9A5F713D251C2A1F92A629229C1F8CDC
+:10DF200017DF20768AEF358A20B3F8376117F05370
+:10DF30007A85807658FA414F34D0C3C9C9268C7F80
+:10DF4000595875E525B9B4FF474A25F43754569416
+:10DF50005E0DE5030E327A71DCC6F047E1E4AFA056
+:10DF6000FC907D90F9138A48D0EDA7E503DCC49CB2
+:10DF700008FBC7340A60985F1BC70FF70F1415051D
+:10DF8000BC0054BB5B8F47A7018F46BC5A73391E38
+:10DF9000F3493EB3EB98FE58C5EBACA91885F6EBF8
+:10DFA0004332F19A87F7C4D77EAA3F2A54FF0B5019
+:10DFB000FD11D2BF53FD11D24EAA3F426A574A2FDC
+:10DFC0002BA2F30D24D17E81FF268E5E04E7038F02
+:10DFD0008CBBF9CE7FD174343F67A3949F5046E148
+:10DFE0005A0D5CCCF2AB15BA671E281275F915896B
+:10DFF000927A8EE7853DD59E66E2E73CE5F7427969
+:10E000005BAAC4CFF5583EBB80E8F29D134DBAFC25
+:10E01000053B34FD0F04FC4461BE20F7B9D55E4DCD
+:10E02000F9B23C9AA7E57BB93E5735CFE4591F8139
+:10E030007EE7E432BD4AFA8178058AAF2F7308DAA9
+:10E04000E9A24941F94DF224795384F83442A81CDD
+:10E05000D4DAD73954AE6AFC23FBF3B85FDD53CA78
+:10E06000FC6C24FCF3DD181E6745E07B5B00F48844
+:10E07000256F5FEFF693DEE5AE39553AAAA5934BCF
+:10E08000543AC825B930FE97A4646F29D059FB28AB
+:10E0900009E8A188F301E17A1CAA8A947E5E3871AE
+:10E0A000FFEB8A0C765AABB32517E37EAEC8D5F8E2
+:10E0B0001B1627CD1A05FB991AF7434885F313BAA7
+:10E0C0002EC17BA509F4B6DEF514897CA2814757E1
+:10E0D000D58438D8076C5C8E1BEB2F6EDAFA168C61
+:10E0E000BFB4A903535BA207858C55F2A2FFC6EF0C
+:10E0F000AAA985795907D2728D1CB624D2763A3BEB
+:10E100006020D3BB543C3889491BA7BAA66D644C28
+:10E110001405461BDD2F403EAF095447C3386DEE52
+:10E1200091A7F55F9D894F36541C2089148ECFBF6F
+:10E130003DE9F5C934DD07FC46F7C1E738DFA41730
+:10E140003FF3CEAD3A7E399C5066D3F2CBE1D54A4F
+:10E150008E965F58BE777E29B917CA3B53255D3E20
+:10E160001DF84593DF10E217960FF30BEDBF84CA3D
+:10E1700085372D985F9D7B78B557537E67DE613D6F
+:10E18000BF8C173DEB23E801815C26EFCF35BFDC68
+:10E19000C7F7913EF3CB3FCE8E5F9ECEE57ACECFD2
+:10E1A000E7971773937E397EF1F4915F3C3DF9E573
+:10E1B000EF3F855FDA9C7E8C076C9B6CAAF445C0B0
+:10E1C0007703978FAADF7B34F753944F53AE1E0625
+:10E1D000FA2C8F5B53E369DAA6B1FD7B61D504DCD1
+:10E1E0002F37EC63FBA5BA3FF3A35DCA4FCC8F3149
+:10E1F0003AC0F6CDA46201DB4F52049F4C7F6DA361
+:10E200002A413FD8AF4B04D22EC352E757E50A61EB
+:10E21000BD898E877AD3236E16374B0E327DC74A5F
+:10E22000FF037ABABCD8ACDB57538CFA9721AF9E68
+:10E2300063AAE7978F405C0285C7D72ADD18F65B93
+:10E24000150E6B0E96A11EF2D540CB69CFABDAF856
+:10E250007A43FA5491A734923F6C7A1E8B93B8DDBF
+:10E26000A54879A3613FBE11F75D753F37EECB9DA1
+:10E270001507F472C65BD84F2767BC85F7EAE40C34
+:10E28000CFF72A6748119687F6659E0FEDCB3C1FA6
+:10E29000DA97793E2467A0FF92F0BE3C6873E1BD37
+:10E2A0005A393307F27DD897AFCBFB65E4CC5FCE0C
+:10E2B00056CE9CE5BE5C9277CEE4CC84BC5F50CE5B
+:10E2C00054819C893BB39CA9023953A09333D7E670
+:10E2D000FD043963AFEBF2C2F9FD35BDD0BDC8F521
+:10E2E000A5D939CA0CE89F4CEC5BDCB691AEBAAA52
+:10E2F000362F4E067A71333BAFB7F6F6C6BFBCD5A4
+:10E30000A2898BB64B0176BFA2F179FC7E6DDD3E12
+:10E31000F4979D69BED3F308A6C67DB4AB6AB71562
+:10E32000E9D66DC233F19F3A8FB6C98C2FDFDCF48A
+:10E3300002EAB70F80DF2FA9A79EABE2B5AFFA8F35
+:10E3400071DC865C19D7611CFF4C744BE9F421A089
+:10E35000D393036F1B0A769E68BF2F16E0F52BD868
+:10E360000F3B7E0A9D0672193EFBB0EE977EC97583
+:10E37000FF0CFEDC0BF33ADB755F97D7E775BFF355
+:10E380004BAEFB67D80B9FFF9475CFC9256ADC0D98
+:10E39000DE9771C22F944F567F9FF721F82F56FFBB
+:10E3A00030E4195867FBB7D675E0BF20DFFD283A87
+:10E3B000B5F7A708BB3763E7EDEC1E761FC659A972
+:10E3C000B91F45C2F7A5703DE8DF0895EF8D745F72
+:10E3D000EE974E411FF9C87C9A720BF3DB19BFBF51
+:10E3E0009323B07B6C425534C4C5774DDE81F10672
+:10E3F0006D9347E2B995514F51DB753629E84F6A65
+:10E400006BF260BAB2A932007E93E70F7C20403CE9
+:10E4100058D1813ADCDF568CB97400C6F18D2B8A55
+:10E4200081FC4A839EE2E07ACA90C16FEBF48A8E47
+:10E430003FD5ADF69684FD50F784F417DA4ED6D862
+:10E4400049340FE410B29320AFB393E6A15FA11358
+:10E45000F4175AFFBCC1F356471A678589D482FE68
+:10E46000B2A2CE5419497F793727B25F81E6F1DC39
+:10E470002DDA6EF52DCA047D86D468FD6A67D25FF9
+:10E48000FE34F82CFD0A6769274D1E7C6EF4971048
+:10E49000DF72BD253E5FB91E5CB2E74A4E0CE8A3B1
+:10E4A0009C18D0534EDC3AF827C8897773587CB54E
+:10E4B0004A5F1B6437FA93DB2A09FA1FDB028BFAE7
+:10E4C00015D2FC73752622D0FCED6F32BFF09A6234
+:10E4D000E2837BB46B0612CC07DC8C0E2688B6DF99
+:10E4E000801FBCB382DA4F32F8EDAEA802D8AE8AF4
+:10E4F0009D747734A597AA628980DD34412CC1715F
+:10E50000020A8B0FADB291DF44815D354E228BCE76
+:10E51000C26F6D170B04CA91943FE578E0DBDEFC17
+:10E52000D146FF3311DF70E33D27831FFA6CFDCF27
+:10E530006B07FF6CFF33F2DF179BEBAA311EFC0C5D
+:10E54000F478DD601933C67DCAC8C72A3DF5467F19
+:10E5500036D0934669F2FC1EEEBBFC7CD9067AD21B
+:10E56000A8305D74558D898B147FA5A6B18D2FBE03
+:10E57000A5BD8F172B75607FB18DDBF0FB7D10374C
+:10E5800000EB93DC284F1F2BA37238C2FCB637CDAB
+:10E590003F08F2735B5323A61749DD6202ADFF52B9
+:10E5A00093F720C06D6B532BA6CF37B5637967D334
+:10E5B0008398DED3E4C37445D3164CEF6EEAC0F4FF
+:10E5C000B12C364E89E4C77E2E3A45FBD7D0D1B860
+:10E5D0006E3A8E06DF171CF6EACAC7065B75E5E7DA
+:10E5E0001D6AD7E547071ED4D57796F874E5B3734F
+:10E5F0006A3E01BE74146DD17DB71574E8DAF5D5A5
+:10E600002E38D7F532AC4FC1313989877B1770FF6F
+:10E610000AEE0D513E4E69A4E295E61FB5733F47E1
+:10E62000073B274F25A11FA44BBC7245EB77D95957
+:10E630001C64731A6BDFFC3B967F349D9D1FA97190
+:10E640009AA23544D744480E9FE73F6AE7F7947291
+:10E65000585C6446810F3C12240302D4E03CA48839
+:10E660009D93A9E7DECDDCEFF0A8996C15A83ED903
+:10E670002CB1F9372BC4B790D66B2E60F9872A8856
+:10E68000CF04F357A8144FD69C7337EEFE56280CD0
+:10E690009F9793210A9ED788FC9C3D74EE1DFD4FE9
+:10E6A00082E7FA1C5E8B623FC738DAF8C66E01F863
+:10E6B0002BA5B1BB0BE6F7E8EF2D72247BA8EBF797
+:10E6C0005FA701DFACFDDDD769C0EC6B43F133DD43
+:10E6D000D1DAF8990C0E97B58D5918BFB0B6D6A1FE
+:10E6E000BB07A729C77886AF6AF9FB044442BB6819
+:10E6F00080330C579F1A3F2242DC1D5D7F76F8FE67
+:10E70000E9CF8DAF59DBB880C5D70C243CBE66126B
+:10E71000DA932A1ED6423ABCE7BDDE5F3ABEE68CEB
+:10E7200071358638071DFD42DE6BA46F19F112C5E5
+:10E73000E95BB88BC545A419E8468DBB50E9528DFD
+:10E74000CF50E335D4F80D0B8FEBA0C3F2B8E6C879
+:10E75000F465D9415C70EF4D34C5B8D7679E398EEA
+:10E7600060812B8B6F0EF387B37E59FCC057839566
+:10E770005B5C49E17E07B8945B5DA3C37935DD003E
+:10E78000BF8EA55DB88315A0AFE6172BCD709F2F68
+:10E79000A188E03D9DA26201D3FC832CBFD82562F5
+:10E7A000BB7F77317F939ABF5C515E85F671867629
+:10E7B0009787DA99B1DE932EA6E73DE992D8BC7926
+:10E7C0001CF2244EDF4BC78A2C3EBA426072030E05
+:10E7D00054C7F0FD90C2EF72E29C92A3F1BB5EC100
+:10E7E000B1B5B289C5F7A9F1D07F7F53C478685B12
+:10E7F000B1A71CEE9E8D0E04FC70BE5EB491381362
+:10E8000064985F50017E5C987EFF0E888778EE12D8
+:10E8100076667BF941A62F5C517C33BE37E2F84E19
+:10E82000447FACB3C4EEF6C14013CD6CFF57E3A1F7
+:10E830008BF5FA4295415FB8FC0CEF7F24906E2F68
+:10E84000EC935B5C067F2C7F07A437F91D7E078461
+:10E85000C98722DEA7ADD8190DFEEBFC8326BCEEDE
+:10E86000296E5444BC1FDBC6E23C9E0B784E7B1FD6
+:10E87000753F876380CB89BFF338C94E2E27DEE50D
+:10E8800072E210C8099ABEC5E3240FF23849E37D4D
+:10E8900089B6A6CA035A7DC798DA05BF07E3A04622
+:10E8A0004804EFDFF5F2DE87DD4DFBD1C5312E44A4
+:10E8B000FAD9197F7F29EAA31E13EA95F7952869EB
+:10E8C00091ECBBFBA6949D36FE7065D3D4032DA7B7
+:10E8D00099A7C3A2B767D4F45B977A3FAE1DEF5BED
+:10E8E000A42826027155695619EFFFADEC52CFF7F7
+:10E8F000ADBE68585F9D8DFC5313A7D23E2DE081BD
+:10E90000F2154512DECF51FB8D2BA6F3D1FAF92B70
+:10E910003FC278E995E382A9A0CFDC37F693A9B985
+:10E92000102FB24F2440063DE6ED62FE76755D295C
+:10E93000D27C21529C7A6FEBFA90B757E3C58DF0E9
+:10E94000EF55EF808880D3DFB7B2E427F58CDFEB9B
+:10E95000C33CD16EFD76CBFCC970BFB7AFEF5FC4CF
+:10E96000723A4C9B49A2819FCE448F3673379E1BCF
+:10E97000DD3333F2B951763EC3F73D25FBD9FB2297
+:10E980000591E7D1935ED97C5648B47FDA6F7B4915
+:10E99000E4FEAFC81754BA7E07E4557BA509F50A13
+:10E9A0003B159F10176F1F47F520F0E328EC9DA241
+:10E9B0002F4BD8F98C515EF418BF84C257636F1B7C
+:10E9C000E55071BE4D671F9F1C3839CE1F89AE7848
+:10E9D000AAC25195433DE148F09CA91DE088708A88
+:10E9E000CCD7617C2D540FD16ACE705F6F5224FA60
+:10E9F000E90D0F467A5831D313E70778BDFA2D9108
+:10EA0000C1B955A2E7C7DEE06784D7F5BF30BC8C3B
+:10EA1000E517E773FF481FD7D9E77A542F726AF4D6
+:10EA200062B8142DD1FC389EBFC22B041FA2724BBA
+:10EA3000D8F637D47BC6F1F40A48E9FEB84DF0FFAA
+:10EA4000F31FB4718920A703D2AA5F1A0C1E32B239
+:10EA50004498AFD37F960BEE432FA35FA8BB1FD480
+:10EA60001B4F6A2486641FAEEB6F42B01936AC2B85
+:10EA700089B218D27AD26E8176F59D7F3B04E3D4B9
+:10EA80007746FB45704E6E351FD3FA8D666BEF8F60
+:10EA900064C22B1A1D964C3A9FB95BF4E7A4752407
+:10EAA00080FDCDEBD07F37DE1F11440A18789C2003
+:10EAB00014FF5A82F1BD249A954B439C5CCE75E7B6
+:10EAC00069DF33ABE5F0AAB5DAFCF0BE10F1E9E797
+:10EAD000297139B48BCA31EB48BC0FF3A77CBAEE6D
+:10EAE000234EABD744F5E5E4849A7A80C78D44B6CB
+:10EAF000B094E90DEABA8893E173866DB205E03B04
+:10EB0000A3D5B80EC502F3B9A9FDF4EB53F1FEFF8E
+:10EB1000F209C2BD355FC6745ECCC43D0A14170548
+:10EB200032B4EF4134C0FE00FC35BF9F8E7FDF5012
+:10EB3000E99128625FD6DF13AE39E82753E1DA3B6B
+:10EB40009DEAFD642F44B37953F8ED0539A0C28FD7
+:10EB5000483585D0AFBA9E7F8D0E6CF6C3B9AA9D9D
+:10EB6000BD03F54142CD9B00EFF443C14F043A751C
+:10EB70006293F3609D9F6F3DF29698155E1F21C1D1
+:10EB8000FB213EBA76ABE85C0EEBD9FAEA21A0F79E
+:10EB9000DED6A5C6C7527A40B8D1797D14695E9F8A
+:10EBA000FD96DC007AC978B140E747798EEF276B94
+:10EBB0000A3C87617E4507063A60BEE6AC8EDDFD05
+:10EBC000E93CBA6F1730AE36512415003F351EE1CF
+:10EBD000844D423B3B31D62B3A68BEFB46E25E0F8A
+:10EBE000D370CF7703A988E905EEE5946E926F178D
+:10EBF0003D204FDEBF6D46FC0C9A26DB67C667D30F
+:10EC0000F4A228E28DA6FD250B264F073AA1A6C740
+:10EC10004FA1F3BC2E8ACE93E6337F1BEBCFA6FC2D
+:10EC2000F6570BB102BD26C6D6AC1A0FE3C48B381B
+:10EC30009FA3544F94A81C2BBDFACB51563A5EFFAC
+:10EC4000EF6C23613E698DE5E49F1494FBF3995FBB
+:10EC5000F1B327BF1905F7C0C51F6D6EBC67CEE9BC
+:10EC60002F319BC1C388EFAD9CAEDE8B61F64E7D2C
+:10EC7000926509F8DB3FE7F60F515C682FDCC6EDC3
+:10EC800085F762981DF45E9EEA5FF22769F5DBFA6C
+:10EC90006825EE2A301EA89E04F1CE5F3A95B8781A
+:10ECA000A8473CC8B7B771BBF973422A81CE6F5BE6
+:10ECB000569E9240DB2735333818E7377808DB9FBC
+:10ECC000EB4E5182D6F8CFEA24BF05F486BA53162C
+:10ECD000DDF7F7A91EEDD5DC57BFEEF0C1F130BF6F
+:10ECE000EB497031D4BFFEB658E6B8E7FCDAC9E7A5
+:10ECF000D11B5CEAE325225178D40BC473BA7A2F76
+:10ED0000FF204684EFA421AC3CA93CF2FAC60F6177
+:10ED10007A5FF9D2890F009DD507CCA8CBDFF662C8
+:10ED200069CAE9F4E7FA5317109FC6FF572F051178
+:10ED30001EF5A72EC4EFE54B8F5980EEA11F997EDB
+:10ED4000BF2D5A49017F6D6F70DECAF5A0FA53F1ED
+:10ED5000C4DB4FFB9DF177B8FF442CFF3387DB9F6B
+:10ED6000F7982A23C5772DE0EB1E92247940EF1AFD
+:10ED7000EA27CABA08E3AAF5921322EBC5EABC3A1D
+:10ED8000CB82D7C3BCCFAB204AA4F1667238AAF3BA
+:10ED9000ED4C08CEF2207D76E7C13B13A1BCB33B1E
+:10EDA00043FB8EC4235C1E745E1ACC80FE3FBF24DE
+:10EDB000F2BD1D15CF63B8BEFCB7849A4E901FD329
+:10EDC000AEA2194A1F29D3FC26763F85F15B6FF866
+:10EDD0000EC35924BE51A783B305CBD5FE8EECE7F5
+:10EDE000FC48ED708853BF91CBFF1B37CEC5B827C9
+:10EDF000554E1D795044397504F7169AFA04D45FBC
+:10EE0000A7D7509D8ACA95599BCA77C37670632A43
+:10EE1000211726B0EF7741DA62D6F9FBD5F1661CEF
+:10EE2000F2A09E35B34DBFCFD592B62F403F38B23A
+:10EE30009FC903CADF1690C7B3EED3F753BBF1B235
+:10EE40004F617EB506BB3C99EFCF463DEFA121DC7B
+:10EE5000BF3F868C391BBBBC9E92C510DC173C2281
+:10EE6000CC63B4A47F674B4DE30A199D2CD874D2B0
+:10EE7000E2907BEFF728952339B4DF63D41E87F443
+:10EE8000C521CA934368BBE3FB185C5E1B52F30CBD
+:10EE90008C777C1F5BFF89BA13B3E09D183295E92C
+:10EEA0000D5170F980FE1A75ADD5D74CD7BB948A39
+:10EEB000A968B81714C5F411550F13C55B45072D84
+:10EEC0001FFB5F33E3619D898F5F5C09FD253D1E5C
+:10EED000AB00DC96972A2340DE2FAFB2B9E1BECA61
+:10EEE0003A4A86C5B4BD95F603FB89EFCF6377C078
+:10EEF00071644EC7AA3278F7C5B9ADCB3F80AEABCF
+:10EF0000D5C4DEC968BD90B89B4978BC866D55CF25
+:10EF1000C0BC3226D3FD41807BF4CA08A7A67FC2BD
+:10EF2000F5AB7A8E93E3AF0CBEE702B897B04744D7
+:10EF3000F5F1445D16DAF54308A32735FE1EC60633
+:10EF40003D5285DF31BA5F114D9CDA900EC16FA63C
+:10EF5000EB9AD7F90CBEC751B7C89F7C2DECB78F81
+:10EF6000496C1FE5F34BFC6B5A99EC08EFBFD70ACD
+:10EF70004ED423553DF96AA2FE14A0BF702AE78340
+:10EF8000ABB97E7C6D2C83F374E2CE8076D7588942
+:10EF9000C34461766D79C7E8F9B0EFCE35C7837E9B
+:10EFA000036B8984773535EA412A1FD66FB67BC15A
+:10EFB000EFFAB9D09D079D1C35333EEB7E25CAB7CD
+:10EFC0003E33427F7CFFAACFE37A5D0E51E0FE40E4
+:10EFD000FDF6C1781F2C2A86E27124CA3F2BE0750A
+:10EFE00017ECFF74DDB35F8EF6E3BD30F5BD32275D
+:10EFF000F1DAE9380DDB53D6839E9198AD8C5840F9
+:10F00000FBFBDC1CCC407941E59B40F7D6D4A14BFF
+:10F01000A64894AFEAFB53BD8BE6C73F7EEF148949
+:10F02000D2637D56709689E6E73DFE04CB0F097EDC
+:10F0300002F93B1E7F81D51F199C25D2FCEAC777B8
+:10F04000B17238C3A684B5F6F137A680FD7F349E31
+:10F05000E90FC41DBC1EE8A7FEA5C1A6E59AF5DE12
+:10F060003D94C9D1A3D1ACDED14C724335C0DB1580
+:10F07000CCABD69CCB350C0DF96F589C165FA7DA3C
+:10F080008EA446EE7F306F37BB9CD5BB2896B44626
+:10F09000B3FB755ED0C7766E1B8C70B10D4DE0F082
+:10F0A000A2FD1485FB51E1A8F6A78E3B07F67590EB
+:10F0B000FB662AF73572A66828C31B1DA705C7295A
+:10F0C0005046C03B56F5D5034700DE28BE248E2FA0
+:10F0D000C98A8FABAD63F3A3FDC617E23E330AFCCA
+:10F0E000CA3BBFA3F533C3F336D287C2C799DDCC81
+:10F0F000EEF777C767231D5D14CBF4455244E14713
+:10F10000E5D9EAA16CFFB97B683C5B5F080F290277
+:10F11000F6DFCCE13790D53FDBF556FF42EBD5E08B
+:10F120004901FFCACEADF98827753D84ACD2F5738D
+:10F1300074A1A15D31653C98474236B65B1A4DAC6F
+:10F14000F89DAC0FB5CBA4ED2E2AEF1E05FC308F39
+:10F15000EBC3C47B21C635D4716931AF356001BFC3
+:10F16000F4BC0EE6272739747D401FD5138BF8FABF
+:10F170009C7C7D4EB63E9F8E3EC9C1EE8CC9F69EEC
+:10F18000741B827BA8BF8291BC3F1D3F47EA0FF8EA
+:10F19000A2377CB40C65FBD439C3873A4F033C4398
+:10F1A0007036CC4F8527F031B62BD0F3933ACF3B56
+:10F1B0007AE3E7CC9F385E296B37EF77148FA0FF97
+:10F1C000C87A7A9ED799699A5E106ED7DAB1D00361
+:10F1D000723E5690991FBCB3CA0BFB5FC3B652F484
+:10F1E00053CD7BE1C9E7BDB4FD9CA7D73820B8EA71
+:10F1F00088D49E0C7A70DDA6C50E781FEEB0E4753B
+:10F2000080FC3CE21323FA07FFC1F1A0EA5DF57C24
+:10F21000BF39FAE7BB27013CBEDE64C67B860D5BC7
+:10F22000A2FC51E837998DFA18CD7FC8F24BBF0088
+:10F230003BB661AB5E7F9AF3A735C9E80F23DE01C9
+:10F24000263C04F30F80C3B0FA8D663C4FA93F28DB
+:10F25000BAE930A481742F81F919DBC33C4E51BC4B
+:10F2600037748837427C9FB19C4A12D4C71A3AEF50
+:10F27000463DADA1F3924F41AF6830C453D4F6A2DE
+:10F2800087BD3194EB61FC9D74153EC49784FA4DA3
+:10F29000F3630F147E48E7756CE3EB0EA140BB6F80
+:10F2A0002E423C9DE898B1F625B9F7FDF573D00FD5
+:10F2B000A2B4ED187EE5AD023B18DAC6D23AB3DF50
+:10F2C00001FE81BA756637DD8149DD931B36FF117A
+:10F2D000ECCB77A2DC106A3AF7C95D6F9D4FF373F0
+:10F2E0009F31274E64D3B7C139B78A2788D9003DEB
+:10F2F00045C5CB9CBFECB2C8C3D877D07B55FCCCFE
+:10F300007DA6CB02F7FC8C702CEFE8B2603CAC1110
+:10F310004F1D1F4E0015A4F9B16F2C40DF47B60BEF
+:10F32000F8EEBDB17DEDBA5D0EA0438013D8A12AE1
+:10F33000BE42F8EB8137FFA4978AB01EFA43CE8411
+:10F34000BF270047A391CE9F7A09FC28EF46B90159
+:10F350000EB54FDDEA80F57C2ACD67F4FEC8E26485
+:10F36000782FAFD6EC4D7662CABED73E7A3BD2E15B
+:10F37000CDFB6E4F66EF482869EC1D4D6F1AACF35C
+:10F38000A687A7E03A67911AA4C3DA47987FE32BD0
+:10F3900089543E13815FA614B07DE4D3F551101C4F
+:10F3A000443E8573043837D92FE2BDFB1EEF22910E
+:10F3B0000598FF8AFB17F20B42EF1F5A41BF6BE023
+:10F3C000B51A362E0D009E8EA62B29E0B7A570F03B
+:10F3D00072B809F0EEBBB86F7C0AC31391E13C042C
+:10F3E000DB517DBC1CBE43FD8059892ED4B5E3EFB3
+:10F3F000DBB0F155FF069D770C9CA77F9ACCE2F21B
+:10F400008CEB6BE1EBA33F01A2A5B3DEF87FE33207
+:10F41000A4AF2F0F32FEA9F755556279C0EC4F818A
+:10F42000725FD76401E54394EEFC3C441F1BCD9C06
+:10F43000BFF5E5749E92A085EF7601DFD354E965B0
+:10F44000D67D51BAF3FA30FDE8DF8B52F955B5B3EA
+:10F450006EE6F2C0B86EA37CF01418FE8EC2C349EB
+:10F460007DF27FD7997D9BFF08FC4CF9D72B033F9A
+:10F470009BD13FF0D913AFBE750DA5FBCF3A543EDB
+:10F48000D6CB5B231FD73E3B9A44E2E3CF6C6E1290
+:10F49000918FE9F7887C6C63F7A6FF7FC9DB9B7BC4
+:10F4A00091B7FF56A097B75F9182B80B08EC337302
+:10F4B000F1BD57237C55BBD72847130AE4887294C3
+:10F4C000FE1C241A78AA7054E973CEE3F3709C10E2
+:10F4D0001DAB74AAD271884E8DEBD6C3D3587E2152
+:10F4E000CC5D1307615E44ED18D0735F117DEBE9CD
+:10F4F000D48ED3B92CA1F03FFE4426C61B2DE67650
+:10F50000C07167B703E2C71673BBA31BFC9271E11E
+:10F51000EFDDD14C5F3AEEE976C46BF4A60FB78904
+:10F520000ED0F3823E5219C99F442536CE23487A25
+:10F530002B67E762C7B93FF438F7778E176D198DDF
+:10F54000E0076E677FF764E6C2AB1C702E707C5BD1
+:10F55000F63DC07F37BD26B2773DBD8A04711233B8
+:10F560001808C861E2BDBF84AE73C6B6B918DF60C3
+:10F57000F4A3CCB26DC4F385AFC85D981AFD2773B0
+:10F58000C0CF02F4FEB0E1FBB6CB90BEE618E8AB0C
+:10F5900006E82BAD277DED56F9750419A1BD7FB6A0
+:10F5A00080CBBDF162C13DA0CF1CA7763EC61288BC
+:10F5B000057B61DFFD0AEC7E600C6F12D2EDDC9AF8
+:10F5C000C316FE8E33D2BB4A87467BDF981E7BEE86
+:10F5D000FD3177D22A75CFFFA3F0219A1E7BFE9DC5
+:10F5E000BC9721FFC2DB19FF203DEB976FFF16EDA3
+:10F5F0009BE3DBA3703EC7B7FF2DE34EC8BF148566
+:10F60000E7AFC71745615C9477BBDD07F7F98EA7B5
+:10F6100033BF5DF32BDF1462FC0569617A48818595
+:10F62000A5DBFEFB03889F3EB12D4A063F45C3F68E
+:10F6300058B4DB1B5E8AC6B897E3AF7C3346EB67F2
+:10F64000FAB9EBA9E7E7FCC7ED64EAB340CFF1CC28
+:10F65000BE6B7879EC0688979BD7D96581F381F2E8
+:10F66000BF7E5F0872E9F8B34CFFA0F6FCA3F0D2AE
+:10F67000E1F70575F79B29BC3F071D91DAE17F187B
+:10F68000F6E4956087F7840B83C3710A07581785E2
+:10F690004B2DC8D3DEE09138ECD70A8F2FD0BEA80F
+:10F6A000DB761EF251182E82C2BEDB7D5601D7CF0B
+:10F6B000BE6FFFA610F4A9CF3A16A25E70A6758F92
+:10F6C000FA3FB76EC1DF977557C3BA937E8DEB666D
+:10F6D000F47F88EF57463EE849E72FFC16F34FD9F1
+:10F6E000DD38DF3EF2FF82FF6B787F56C073F9335F
+:10F6F000E17DD5FF5ABCBFC6F16E77427CD9F15788
+:10F70000BECF209AF59F69DD1DFF4BD71DD28F44D8
+:10F710008F159EB86F23FE00DC5F5FDC8B9EF2FED0
+:10F7200030D52FC1EC10357E474C9C837A8698B833
+:10F730001CF586C584BD83EC954DFC3D3616F7DD82
+:10F740003AD0ED43BFA8E4A95D47F3E64175EEE585
+:10F75000D883DE3E13932756829FA579219D17ED0E
+:10F76000A739C9E46C96E19976933FAA10D30F218B
+:10F770005D9A7CE91E1857B2E9DFABB519EC8D989C
+:10F780001C8B3EAE98EC70C27975B45B82B7DCA975
+:10F790002AAB7FDFF6E5612CFE2386F8306EF36C32
+:10F7A000E1642FD4DB6B463819E1A3C2AD079CB8E6
+:10F7B0003DAABEC72F252E0F001F4A84DA936C3D49
+:10F7C0006887C2DF9182F31A73DC2CF772769E226F
+:10F7D00087DEF18738086E6F86DE99954D6897AAA7
+:10F7E00070D6F487EB37C2F96CE1ABE2259A54236B
+:10F7F0009EA307DADC3E3AFFC53283FB620A7778C4
+:10F800005F5C85AF0A37231E8240A34961F88753A6
+:10F810007DBC8EB78CB8E09C65BC5812F482BE5C8F
+:10F820001C8BFAF23181F8056ABF1D2B4D2E03BBEC
+:10F83000E258BA4582745C375D9366BE179DB28606
+:10F84000FE861EE44B49BC2E7F2C3D0FDB975BD31D
+:10F8500074EDF642DC36B5DB8FA5155BF13CD4992F
+:10F86000A96B3729D6B11ECAF7421C378E3F01ED6E
+:10F870009B8B53F375FD4CFAE8D8C337D2742BB782
+:10F88000ABBBC799D11F7FECB5696500C74BE411CD
+:10F89000BAFAFB883309888AAEAF02D677996BAC87
+:10F8A0006EDCBA0F77E4811FE237EE52DDF7CB8BC7
+:10F8B0002FD1F5E3B106FD40DE554A95EE7B5DE3C1
+:10F8C000D744EA47C8058DDF11691455DFFD1DBA1D
+:10F8D0007E46EDD9AAABEF0E38CB41651C79C8FD49
+:10F8E0002AA46A3CBBA59FD56BA2E9B00FCB4438D4
+:10F8F000F71CFD714D33B8A12F38465C4007E791E6
+:10F90000183C0FEC2DEEFD1B93AF06D67987E873FC
+:10F91000411A33605621ACEB486A9B08C7D20F09E5
+:10F92000355714523E1BFBA5AF19F2177DD7218224
+:10F930003DD9BC45C4FB75E3C589B1FF09F2B843A5
+:10F94000C018FF3A9B09FDF09F257414DEAAA13B65
+:10F95000356EC7C8C7FD4795DE5448E9AD255569E2
+:10F96000EF02795AF6FEF56284FBAEC4A97F97AE2A
+:10F97000FF284F2B9CD3AB714931E5220B6EBFD8CA
+:10F980008CFE9225267734170AB8EF3A2798D701CC
+:10F99000BF7FCFE546CCEB44067F504CBF1A11EE3B
+:10F9A000D9917B048C6B51C79B51CCE2ED9714AA83
+:10F9B000EF9B3893AE1B06EDED2C5E007C69D06E9C
+:10F9C000A209F594AE719FA2FD1B73B9291DEEE14A
+:10F9D000398A95D773687E4C607F3ADA59A418E368
+:10F9E0006D16F0389994B6CC077640FB3D668C3B9B
+:10F9F0009E314D399943F32B27B2FB819DC565B1EB
+:10FA0000C334F0739C1288AC892BF8BE50C6793889
+:10FA1000A420DE0F739C92B09C044730FB8F8FE3D1
+:10FA20009826BF7DAB661C22297361DECB87BC277D
+:10FA3000831C731C22FCEF8804F1EFE4413C123E6E
+:10FA400080260553AF8B70EFEEE896D1F16087F713
+:10FA50002B75E33DC17E4F8AA17BB2201657C23F72
+:10FA6000788FB6FAED0A5ABE0564232BF7134ACFF6
+:10FA7000CB2D6A39152D2EFECE2196575F55017874
+:10FA800014F5F5876785EA2BD6D470FFCF1456BFDF
+:10FA9000DD52D013AE5DE3A2707F8EA17400FAE553
+:10FAA00082FC8294D3C5E93B4EC59E01AE0E06D7BB
+:10FAB000EFE82E901CF6277E2CC819405FF7C2F5A0
+:10FAC000006A37AF8EAFD90A741C23FA87C1F7E9F1
+:10FAD0000E25651CA5B74E8B92F13BF48B4463BC9D
+:10FAE00057D52D9F3D0857C41C938EBAA866433A3C
+:10FAF00025257624F8A59C5FA31C50E3DAC270A4E8
+:10FB0000F44BC75C690AE7412E38C27055E06DE0DE
+:10FB1000E51A385B69BE8AC3F5E45333AF4238CD8A
+:10FB2000B4225DDCCA79A8259EB4435CDD49E7E6D2
+:10FB30002B811E4E6E3163F06A2714C2BEE9B2B249
+:10FB4000BFE393184C85BFDB326C9F09FD79EF5101
+:10FB5000FA50803EFC2310EE6A7F274BDE4E80FB7E
+:10FB6000122713A50480CF9CA005E1769D44FCF0EC
+:10FB70005E6A67E2CCF2525ADE7948C6F20EDECFF8
+:10FB80009051CAFB85B88FF3FBBECAF922BC8FDA4D
+:10FB90001BBE8CE7F7E00F3E3FA1773A6829B5E23C
+:10FBA0007B430DC50B0B605F58109F87F1570D15F8
+:10FBB00002EEBB0D8D5F22DCD5FEA553229135717F
+:10FBC000524F80F73049F36EFC290B96D7359E448F
+:10FBD000F94DA793097C738C9F6FB69BC90D553463
+:10FBE000ADFB41BCA1CA86E794ADB07FD4911D9610
+:10FBF000051AF9473ABE08C9FBE11477F74EDC1F36
+:10FC00000372B54A704E8147062EEDF05F05E7F7A7
+:10FC100055D1CE2970DE9FE4FEF355707E5F95EEE0
+:10FC20009C02E7FBB94FC74EC5F234E71AF84BA068
+:10FC3000D5EE5C96CF74BE09F90B8797B1BC9DD108
+:10FC400041CCD31953BDB87FDB102E275A637DA753
+:10FC50007B77E4E6C6977570E9512E0A180785810F
+:10FC60001A947EFEB56C007B073727807159E9C373
+:10FC70000535FE8B142784E37513B38902E7A98940
+:10FC80002F44B3775A3F0E6400FC6E7E21DA0F7E5C
+:10FC9000C8798FBC6A81FD67BA28E7015F8D1F5D57
+:10FCA000933D3C09FC2501CCDFDCB81DE775E74836
+:10FCB000FEF7AC9CDD05E0AFAAE571CEB58678DF36
+:10FCC00039B69DE87F9BB351EF679B4B821F009F26
+:10FCD000D63D71FA38DF8F4C6C1E1287C7743170B5
+:10FCE000BD85CD6BCC70389F49E8C23863C91948CF
+:10FCF000AE41F8D6B9D03E498DC17B344BFABF5BDB
+:10FD000018E97D988E26BADF53967BB6692BA6D26A
+:10FD10000882EB4991821637EDA79ECBE531818FA2
+:10FD20002CDA78C12B385CE3B6B2F36E631CEC15A9
+:10FD3000C3ED3CBE9D9D2BCFAB7EA304F0A2E2F3AE
+:10FD4000A258D281F1AA09C4CDF1E206BCA8F00FF5
+:10FD50009F2FD3769991E842853F61F175314C5ED2
+:10FD6000743F178DFA9471FE757CBEEA3ABCC39954
+:10FD70007DD3DBFCBD30FFA4733F7FEF7059F7DE0E
+:10FD8000ADBA0E958F43F6E0C2C87A8A3AEFB3A7B0
+:10FD9000B380A52F74A6CA997A52E3423F2C972BC1
+:10FDA0002A9CD579AAF0EAEC25BE556A7C51B71E8B
+:10FDB00029508697E31F19CEEE374A1D9760889524
+:10FDC000D4B80DEB9DED7A5479DBDBBA54396B5C1A
+:10FDD0009F2A6FD575AA72575DEF382A48501EC208
+:10FDE0005B0F02D80B353AFDB7146E2868CF7DAC97
+:10FDF000B7E8F2E39DBFD3D5BF3875A1AEFC127949
+:10FE000099AEFC32D72A5DFE37EE3F18F4F875BA8A
+:10FE1000F22AE5315D794930500E7AF6DF9B2A31BE
+:10FE20007EFBC2C3DDAF42DEDFE4C4FC8EA6544CD1
+:10FE30007736C9C8DFBB9B5C98EE6972E3F7FF6851
+:10FE40002AC6F48D2605D340930753A35C98F497F4
+:10FE5000AB24D0D38B03EDA8FF678DA83906F270D1
+:10FE6000AFC9D76CA7703AEF3DA68F139F713FFEC5
+:10FE7000E6833B615F77B27B4D2D5D630539823E42
+:10FE8000E7A0FB9DA2A117C7C42081F36407891CCA
+:10FE900067F9C570768E8BF1799436A75AD93BB63F
+:10FEA00053A70A188F3895B0FB0934F5D7D0F2491B
+:10FEB00012F1C2FE5F6593F0FC89F0FBC253D834A7
+:10FEC000E13D756F14ECDF89FDF07ED264F848E700
+:10FED0002B2A22C6B14E297E1DE3FFAEB1B1BF93DE
+:10FEE00075F59E45FFBA93969316EF6876FF417DB0
+:10FEF00027E45DD3D9E80D5FC09D02380F12DCEC1A
+:10FF0000EFA4C44B6EADFEAFA6BB8633FD7F52336C
+:10FF1000BF1FB08FA01EA7F2235D5F2BCC5FE58BC8
+:10FF20002AA7E41FEC80FD7E5539D4AF3B28235C23
+:10FF300054BE50F940B5FF543E182F3ED10CF54F3A
+:10FF40001C62EF929D77ACE6F05FE838FF03F207A2
+:10FF5000233E0080000000001F8B0800000000000E
+:10FF6000000BB53A09705455B6E7F5EB2DA4937420
+:10FF7000428084CD0E110C64EB74D210B6E1911066
+:10FF8000DC101BD42F20420332614D62C02F8EFE45
+:10FF9000EAC63018F8D69F8C5A7EFDA2D53082CCA6
+:10FFA00068151948303343B0418D30E348545090C0
+:10FFB000882D322CDF848E2C223354F9CF39F73D33
+:10FFC000BA5F2761B1BE49A54EEEF2EE3DFBF61ECB
+:10FFD0005CF95182BE002BAD00E00028EEAC2B4D49
+:10FFE000C27F0B82F560A439FCF911FF0AF7358155
+:10FFF000312B321EF343FDBBB46FB7CF0B4613C09A
+:020000021000EC
+:100000002EDF0C8641DF22300E05D8EBABE2F17B10
+:10001000BE553C6EF1F919EEF3D532FCABAF8ED77D
+:100020003FF4BDC4E38F7C0186ADBEAD3CFF96D3EB
+:100030000ED007E0426B693F6F0E409A3A06EBC460
+:10004000344F0242A38033082117422B9852531198
+:10005000CE909C35C0F37E486118F4E2FAB2B4BF8A
+:1000600080B137A3EFB122BD0F80FA93DADB08230A
+:1000700001EE0741FF03C57FBB2C25D2C09B251590
+:1000800001CC4AEB05EB258087C09F3B0FE18CF24A
+:100090003AD35889D627D94F223F24FF17861FB35A
+:1000A0009127F433A12B4444E1A4C6371960896D2C
+:1000B0008D19860020978E8790BF0690E0C70C8030
+:1000C000C5103403ADBF6E3A1E8AE2F352800CC8ED
+:1000D00044FCDF32F17E6D1EE8F9A873E552198AFF
+:1000E00053886F0EE6D37208F17916F95167958D32
+:1000F000EEAB33D339B1F72EB1BD67C64137F7B692
+:10010000F2F3D7BB57935305C03CDABF264DA9DBAA
+:1001100083E72EEFD536473674C30FBBB1F3EA79C8
+:10012000C887DAE1F8BC1BF14F9864F5229E65B2EE
+:100130000D0C28C770400E58F09C45197589742E17
+:100140002A6622E0FCE26699E50146C5988E722B8C
+:1001500057E5D60EC1CF482EE5E3CAA700CA6FD136
+:10016000063D3D4B6C2798EF176157B7F456C0B367
+:10017000DFC9895DE9AD1877FB293AAF42E51BCFAE
+:10018000235EABDAA46DEF45ED5BEA4C483D198F79
+:10019000FF8C8251C417A4C31944FD397750765A95
+:1001A000A067FD38EB03D6F74B3ED8F61EEAFFD921
+:1001B0002B38D11FEDD159F2927FDCCF273763A1C5
+:1001C00067B593EC09F584EC4893E35AD42140BC1D
+:1001D000D79658037EE467D86D37D2FD61295093D6
+:1001E0004872B90CCED5C8EF89BB3E384C7632D1B7
+:1001F0006A0B12DF9088F668B94E6817D3E34F0494
+:100200006A1270FFD836BF4C663BFAA0B7C686E3C9
+:10021000511F2A2869F433EF796492FB765F13F358
+:10022000A1DE57CF30623FB7B29D413ACE65DEB80E
+:100230009DC1235603F9B5152A4E35C9506740872D
+:1002400075DE36594E403ACE07C149F305071D35D4
+:100250008457619B2227225EEE13DE1AC27B2D8A11
+:100260004141C18D6AF7CB49386F3142D0827EC49B
+:10027000926600258AAFA32F046AC80F6A7EEDED4F
+:1002800038C1C70957EA65F25B76B377EB46E427D6
+:10029000FC39CEB9D9D115EF1D4E03EBFFB114CF08
+:1002A0000E9687CD31CC934BFAD3BEE515D29F86FF
+:1002B00078A7059F83183FADF945ED1C8D6F1A1F78
+:1002C0002BEDE751C6A807ABCEB3DF8BBDB7D2008D
+:1002D000DE7AE4BBABD451588DE7B4AF86B9D370A6
+:1002E0005C674298D375FFBBAE9216C2AF4C1ED767
+:1002F000AA105E76C335F5BA72D5777C7F8FEBEAAC
+:10030000FD95CD6EFB7C5B64DE5820093F0F46FBFC
+:10031000496B449E372AF7F19D3374716BC20F5EAF
+:100320005DDC9A889E367ABDD4FAA86E5C667F4200
+:10033000B7FFF6B4D5BAF53B1DEB74EB7767FD5606
+:1003400037BEC7F9B26EFFBDC51B75EBD394DFEBAB
+:10035000D6A7CAA0486873B952C044763613EA19C2
+:10036000CE86568673A093A1173589E07C70327CC7
+:10037000043C0CE7B8BCFF22B9844D9D7DC9EE3B1F
+:1003800076FE2B87F4A2E31763ED198E485CD6E264
+:10039000F4CDC6E35E66945337FA905860603969CD
+:1003A000FEBE47F9C4F8FB7001FA13C473BDA17314
+:1003B000CE5F508FFCBB2DF6CD51FE0435D240F1FF
+:1003C00058B3DB9EFC4B99115301B4C7AD06E781CE
+:1003D0001574CE47BDA13BFBD2E0D41F90D1A88FAE
+:1003E00049B343C621A86F1753144701E2EF7F6654
+:1003F0005CF2C96CD5BFDC8272F8DAC0FE0F164B16
+:1004000081A14857538318E72E4C0E489C07045986
+:100410001E0F43C84474CC05607F3B0F1C0C178033
+:10042000C272C193E3F3D0CF2C6C30BAD6235EF9FD
+:10043000299D43C8CE72471F4991F0FE3C742FA4FA
+:10044000FFF906A8A53C45C3734181F0074F162864
+:1004500045056E7AAE75FDF3787F67A30136E13905
+:10046000A7463FF14B888AAB2FBB4A46D3BE6D12DD
+:1004700028141FFDCD96C0E60CBABFB32FF9756DD9
+:10048000DF1C57E904DA37B900F87CA87F0788CF6A
+:10049000D3EC82A730A90FF3009F1B4CFEA7AB9DA6
+:1004A000F959DEF9141FFA839828E67B79FC60C1BC
+:1004B000E6196B72981E3FE5632FBBBC1EC6DF8C2E
+:1004C0002E8DF07FD512D8C47953D56009F12C7FD9
+:1004D000CD62A0387E04FD2CDC0670D46765F8A5DB
+:1004E000CFCEF02B5F1AC3AF7D0E86DFF8B2182E89
+:1004F000FC010940391E2E50E692FC7AA2A3677FC8
+:1005000021E8084B30A3DED6757D86AAD7790D2762
+:100510009E8E273D68929D431185DC465438C4FB6E
+:10052000ECAE510139239AAFDE6584475ED3A7CF85
+:100530008D2DA2E78C7609F79F6D3ADF97EC301688
+:10054000BFABFC68360B7EA8F86E4B6E5D4FCF6F6D
+:100550006B1C4218A23F00A187244FA93B3A56B317
+:100560001CF30B44BCB9D7D25964B745E8034A150C
+:10057000305E54ABF1A24CBE9218427CA6D1B9A316
+:1005800049AF6F3D40F7F9F7C93094F513E67AA209
+:10059000ECFC75950F1ACC6D367B0278FEB6E6CF73
+:1005A000A6DF8D7C983AE64EB71C656F2F10136856
+:1005B000DFE8CBFFF37C2AEFB7D355336163991D96
+:1005C000F73D64DDF33EB1E061FBD765C9389E9B22
+:1005D00026B5109CE7C8989CE22074034CCF82ACEF
+:1005E000892DA462539CD3CC94174C24A38AF29FE8
+:1005F000A5564CB274FEBAB76E7C7BDA00DDFE3BCA
+:100600001D99BAF5BBB3B275EBDABD539C85BA7DC3
+:1006100064AF9437231D2C77D82C07864AA407177C
+:10062000BE58CAF4CF2C22FAC3C83F332600A78B8A
+:10063000D7BDF83CB98DC6BD89649FB1F9E9B2E672
+:10064000DFB5288E9EF3D30AF02405A59EF3D29E33
+:10065000F2BA1BCD4FD18F3C477E247FE7FDF61ABF
+:10066000C463DBE8CBFD1D48DFDE02CC5BC9FFC500
+:10067000E4AD61356F8DD5A3ABFA2A3984FEEC97D2
+:10068000D9EF6AF96BAC1E013C2DFC8D0A6FD6DEEA
+:10069000A77E22E2CF3FC8EE7B47EBB70A0305BA3D
+:1006A00078916FC67880F2E9FCBB0C9B68E20AE2A5
+:1006B000A1C92133A2FFF0C8C6F7D38B78DE4FF96A
+:1006C0006905C5073CFF0AE51F84EFB23DEFA7A708
+:1006D00046D661E5D7BAFDF094D4A21BAFC9D08F3E
+:1006E0009F9DD812FD7C4FFEA87CC3A3662FFAE91C
+:1006F000F2172425D08D3FD2F029DB1BA790DF34E1
+:10070000EEB2705D54615740B151F68371A49BF80D
+:10071000ACF98799325475E7E72C2E91674DD91BB8
+:1007200007F24F38F708EA0AE1E37F5BC49B2349ED
+:100730000A78A2EE497109BC3B92EBFEE37BDCD761
+:10074000F1277012EB3B9285DFCD6B38653050FCA2
+:10075000EB25F425CF1E32A4200C2F8AF703DA53A1
+:10076000E5E204BF211FD787747E6645D1F7DF9E7F
+:10077000FCB215E5F685C1A08B3F61F27938CE74E5
+:1007800025CF5C83FFDFBD372E68F809F46462CCA7
+:10079000627F5A22EC7E0EE98DB84701743995BF0D
+:1007A00006ED5E85FC04D14FE3D9DB538FBC407965
+:1007B000EC7EE10770D9165B973E145597C206612F
+:1007C000BF56FCA53CA60202936D54FF07D1FEE183
+:1007D000E7B3FF092E5BC4CE6FEB6AD79ADD571ED5
+:1007E00012767F6ED7C54FC8CF9FC3F8176DF71A23
+:1007F000DF347BAF7C4966BBD4E6CFEE92EF087462
+:10080000C3E7E1AABE81E2647BADB68B7BABC75F79
+:100810009A4E71AEBA19252475BD478395B5323805
+:10082000A2EED9B6DBB228608BD011D6E26BF3C54D
+:1008300094893902AEA6F80B75AAFF11790DC65539
+:10084000532AC5D5699273338243CDFD4A887F8789
+:1008500024083A5C7CC4FD56C4EF3E711CCDDB28F5
+:100860003F83B42C23DD335D95EB7D6A9FE881E601
+:10087000078692BFFFAC61FE21059756B83299CE2C
+:1008800007C1CFF9E1A164CFA01588E7D41AA1E789
+:1008900087923BDBA9AF74687CBC5423F1F96BA24F
+:1008A000F3BF4326CFA02AA64BED2F2923E41FE355
+:1008B0006FA2EE55FD22CAD32F893A8DEDC098FE66
+:1008C0002CF70B1643A045C17B2B9C41CE5397823E
+:1008D000A8EF63F3F48A71DF9A293EC4D695139B7F
+:1008E000F61C96F2BAE947C4E8EDF5FA0FB1F56CDB
+:1008F0004F79FEC514CF8BAEA83E606CBE7E352FFF
+:10090000D5F2AACDF1814D88CFBBE3FFFBEC521CA1
+:10091000AFDC1C6FA7FAF9CC6B163FF9E7339B2CC1
+:100920000109D7CFA474B651DD70667BAE134F803A
+:100930007283E3CDB728CEFFC1C47A01E014F6710B
+:10094000554F1F3F46FEAE7A738204945F7BC5BA53
+:1009500056CBC96F24709EB078477AC02245E20C0E
+:10096000D98703538BD3AFC62994F49FD9775F12ED
+:10097000F5A1DA0D7F1CCC7D2DF9A9634FE0734BF7
+:10098000B724B8289F801C60B92DDA347C23E5C7D2
+:100990002F9ABC4D447FE91BF7F4CBA0F33FED0346
+:1009A000444F78D78EBE941F45F2F6EEF3BD73BB6D
+:1009B00032932027C227AD2F58FBFA6A0FC93D5E3C
+:1009C00072F0BC11AA9401A4174DD380CE75C992C0
+:1009D0004276D9B92E9EF3D458BD3BE01275CA3287
+:1009E000AD8FD01BAC69643F5E603E84D7656F5AA3
+:1009F0008F7C3AE54A51E375E7B0E9B9D1FAD956A7
+:100A000041F5DFB90D16EE6FB4C7E9F3060D1E759B
+:100A100025F3FE72EB055D3FA162D565FD38071435
+:100A2000F23BAE1A47E1A30857A8FCEF18E139E6FC
+:100A3000423C97D4FF76E787CC970DFFFE05DDBBE0
+:100A4000CF26FA2A1F0AFEC5D603E556D1BF00D825
+:100A5000C8F76BF3A75EFD3C8FF4F05463F6309259
+:100A6000E37CB9F5E42B48E7D984D6634F22DCBE9A
+:100A7000EF13964B2CBEB17D987649627A97111D83
+:100A8000385FE6F65C2039A320B88E9BBF3E97F90D
+:100A90005726E724911CC367BAAF57343CB5F335EA
+:100AA000FCB4F3B57D52A190578BDAE7EB30B79EDB
+:100AB00025F976ECCC96A8CF77753EA5352F394A27
+:100AC0005F7EAEFEFA2CB5CF71D8B0FA3133EA634F
+:100AD0007BFDF3266FB4DFBBC9BEFAD57C5001871E
+:100AE000BDAF08251CB79038238EC76B6332061C38
+:100AF0008F53D193081FB4CBF12A8425DE34EE9BAB
+:100B0000D37908E320C0E39A894E07C1099287FB95
+:100B1000175ADD3019AA06121D066B88FB7D6BA8DB
+:100B2000CF8879CB03C96BEFC9C0FBD6F481B594EC
+:100B3000CFAC3109BBF0CF8BE77A4EE3931667C099
+:100B40009EA38B2F6BECE030E239338C506B4A1153
+:100B5000FB6E413E1FDA37FF7DEA9F7E6EACEA43B3
+:100B6000F71EB1BD902B1928CF0B2450CDF8C52707
+:100B70007F70FF1DF71E05653CE515F77F6065BFBB
+:100B80001FDB9F58085E1E9743C874019FFB6AF4E1
+:100B90003F37EF85085D5F8DF9BE91EA8487929FAC
+:100BA00076D3F3FE12C8A2B874292E318FE85965A6
+:100BB00015F0F15E899B089EB1DBFCD45FBD143754
+:100BC0003840F1F415C97B6F611F7E8EEB58FFB181
+:100BD000F800C5BBC7656F05F79393CD20E1FE70A4
+:100BE0001F952F1DC07C099BD4FDDF39785C54EA2A
+:100BF000E27E235C72B05F1E1B13778AB20DA23EA9
+:100C0000FB51EC1FDF69D4C59DA27CB59FF32F0774
+:100C1000E7A9137E305E332E75148A7AB7A8B7A180
+:100C2000AABB7C718DBA5E034159F47944BE30F69B
+:100C3000AA7E2932C9B1421D57505C43BD0A275ACA
+:100C4000FD32D23B7697D0B3B1C6E01E82E8656133
+:100C500015E5174D18F7343CD0AF405A36EBC318A2
+:100C60004D4FF1ACD9B86FAD54C5758C95F21A845F
+:100C7000EBA556C6E317D0C95051E3790938194E90
+:100C8000020F43D4538677401DC3BBA09EE1146876
+:100C900015F17F44B086E31A3C65E7F71877961B99
+:100CA00028EF287AB0FBFA61CB75F9808637F2E637
+:100CB000F93019D0FE32BBE1C7C02CF623B1FC8855
+:100CC000B5D3F11092D94EC9416452FFC0C1F65A52
+:100CD0000A0A8FCB6E900FC521AF91FB37B1FC286C
+:100CE000ED5E2FB6A9FC5840BAD62722A713850E71
+:100CF0001E6BF242FB4AA33C34568EDA7C517CC90F
+:100D00007907BAE2BF157E39D388F1ABA8B0644544
+:100D1000268EBFDCD121C6634B760CC1F15785E12D
+:100D200099C674D2EF92429313AB18A973E6241CB0
+:100D30007BC93EF309A21D923FF38AFA78A59AC7B0
+:100D400078573FE6B4A3BD7807D99C44A71593FD17
+:100D500038E4A39C29DE1F0EBE23B8D784FBBE3225
+:100D6000795BC87E975B83890EE4FFCAD565FDC8B1
+:100D7000753E6316FB2D16D17FD5E8C3797F1C8E97
+:100D8000B76FCF5E210DB93E1E78FE413ADFBB7AC8
+:100D9000A89FECD7DB283985644BFACD401EB6B747
+:100DA0009A80FAA6DA7D4F8DF01EA1FDE070B2FFA9
+:100DB0001EA0E639EDDBB3B3494E270AD5F7C3A928
+:100DC0001985C4C7A3233C27687F3841E8DB098A1B
+:100DD000E5EE9EA1AD48395ED8CD7CF81F88003E77
+:100DE0007FB1D07B9AD62BE3AF70DC3F5BF0E9DAC2
+:100DF0005046446F2514DA6CA4BF46818099E3C342
+:100E000038FBD53C95FCDD423C07F951E4F1D69026
+:100E10008B1B35BB7324F9553CF73C9F6B0E0D2E95
+:100E2000C0E75EB8EF9859E8DD40A177AA5F6ADEB7
+:100E3000BDFFC90162E881283BABDC7DF9FBA3C89B
+:100E4000BFCA7336276D8FD8D7CB2BB8DE049BCEA5
+:100E50008F687637A6C9C2F9F6D85DC317D2BEF13E
+:100E60009FB665125D13DA42FC3E2CDCFCF9008172
+:100E70008756875C927E4A3C3EA5C6895356111719
+:100E8000E8FD2ED77B8DE2FD6EB5DAE7AC6E9602FB
+:100E90007EF63FA27E5EA4D2B77C7F630BF54F1631
+:100EA0006D583085F52820EA0A07FE925F5872587F
+:100EB000D4CD4BB7EAEB8D4AAA9B693F04CDA40F72
+:100EC000CBEB63D6379472DD5C19EDFFBBA99B8732
+:100ED00015A9FDB1413088E992672779BBF187B147
+:100EE00075710528B9459CF77A64BADF6DECBEFFD1
+:100EF000909427E9FAB5E5EADDC4271BF3C5CCF5E4
+:100F000044F5AB2B9C761AAB76BB1175A798F2ED26
+:100F1000DA03DC5FD69ED3EC7871ADC475076CE85C
+:100F2000CD3A98BFC5A210BDF95BFA711D82F512CA
+:100F3000E7871BB7586A695CF3EB5E7E399FFAD08E
+:100F40009DFDA90F531387F9A6E8E783E4E23E0C61
+:100F5000F745E617A97E5FCD032058A0ABE76BD419
+:100F6000F85F9D30AC1F56CE917DFBD275F5498D53
+:100F70009A6F17119E94376EED2FD6E3041D7B3EBA
+:100F8000FEB778CA7B1B8D9E78EA6B9F3B3884EB5B
+:100F9000989EF8EEC63004D778DFE8FE7C4AE6B5C6
+:100FA000E456F49251F04BD5DB3FFB14F8C6149194
+:100FB0008B465F99FC56A999FA228F809DFA24D519
+:100FC000FB7F5763A5BA701D7007E21C087D3E7752
+:100FD000DAC0EFCF4742D66FC6E1D87DDAE80CE041
+:100FE000F30DAA5FA4F7C88E283DB3A8FDDF3847EC
+:100FF0002F7044D5D1F15929BA7182B3BFEEB9A48B
+:10100000E221BA75E4F7263A1FFC4A6BCEC848DEE7
+:101010009BAC8CD03DF74CE2E47D6CF7ADBFE4BEF9
+:1010200054EF3B5C7A7CE45D32F903B820F2A562B0
+:10103000FC257B1B05FE1A92C798767D1E551CAABF
+:10104000E3BA31EEA051D707B05CA72FF59C665FDD
+:101050000361A0F01BB1FCD67F4751BD5FE67CAFBA
+:101060007A1026AA19DDF1FB561DBF357BD4F8DEB8
+:10107000C7A3E77BBF197A7EA77BF5FC1EB048CFDC
+:10108000EF41557A7EDFB24ACFD70CBF9E8F99B51C
+:101090006374FB87D695E8C6B7BD74976EFFF0C042
+:1010A00074DD387BEB2CDDFEDCFAF9BAF5FCA62505
+:1010B0003724FF8260B56E5FACFC0BF7FDEA9AF255
+:1010C000F7E3AF903FB03C8A511E41C7FF9F1E7CA3
+:1010D0001AAB0737E867DF249B15DF2584FCA407DC
+:1010E000C5F1AC2753E385DFF968DFB9830A8E0FBA
+:1010F000380A4D699467A9F98347F5435A3D135B54
+:1011000037DE5B2CC5BCB78FD3BDB7BFDEF771EE42
+:10111000D6A06E5C7010F8FB17D761E7BB04DD2723
+:10112000146E778D3C5DF52EC1D117386C77A957B9
+:10113000B5EFEC62EB2D701E64BF3F5B7B2F434627
+:1011400031B26B7F52ABC7B43A37B6FED5EADEAEEA
+:10115000759AC863BAD61BCE3423E7D15ECEAB3FB7
+:1011600090BCDCE77C65B8D7E67653118075B28118
+:10117000EAE4508D60A602F41E3A4CFF7312F2ECC2
+:101180002CEAC7879381FBE7CAEADA597E1BA36F73
+:101190000F8D14ED23FAB9D5EDEDEB46B91E97ECA2
+:1011A0006B0BF1D98FC67C3B98F29174B7F85ECC8B
+:1011B0002223A7302EF59BAD00CD5F4C51FAD3FD15
+:1011C0005ABFA427BD89FDCEA8C1176468B43BF9F6
+:1011D0003BA4D8FE62C8E0E0FCD4FF2B89BFDFF956
+:1011E00096901B1DC963CED59A388F01B59E7F5846
+:1011F000E5BFD6F798ADD2731C8F588471F9E1A67C
+:101200000F582E4BD3DAD57E4915E7E30B06DA5C8F
+:10121000FC5D9B52E8147D32AD0F3240BE99BCEBB1
+:101220007AF42F4D3BA3EB43C15BBD6FE87D79841E
+:101230006E71FEF175A29F797CDD20EE9F47CE3F57
+:10124000CBFDA887AB3ED6D9C7DC554774F630CF67
+:10125000FFB56E3D94DA69A2FE636867FAE4879091
+:101260007F1D8D9691240FD48307DD51FDB7D0BA31
+:10127000EC4974EFF5E9FC96F168F3B5B27C353AC8
+:101280008FF90EF338E40BC57C6726E8D4FA1C1AF4
+:1012900034EF852C23BD4F947A39A9AFDC53FF433B
+:1012A000B3B3F3EE21AC9F970C8E93A24F54358AC3
+:1012B000F2BFB6897D4B08EFB64166A380C3C43840
+:1012C000BDD82AC693EF201836D96AA92FD226890D
+:1012D000EF82664BCA6BF3F0DEC7867B57917E5771
+:1012E0002EE9CC23FBABCC0FCD91F0FCB37DBC4FF2
+:1012F000127F242C2FD253980EFE7EECB4C19F2770
+:10130000A1A9BCDD787416D58DA77BF9CF5286B222
+:10131000CDFDF92CAA1B4F9B853DBED3189CE5A79C
+:10132000FA090F233AFD7F92447FCA16324FC373E6
+:1013300092FA789FA1F3E9BB307ABF47F3A49F5A92
+:10134000BF346C12796258CD17FFCB2DF2D9DFB8BC
+:10135000C5FB3F0DFE9EDEC1E0DF3B04D95F3F3B96
+:101360008CFAE9E7365880F25BBC5F311445BE5F0A
+:10137000E98BB4501EFBBE59D499AE772C41F25381
+:101380005A5F75933B83CF49CD14FDD2D4FF44BF40
+:101390004576186A1D3C2D210ADF83C07DEC0EEADC
+:1013A0004747F5B137B9453F141E117EAF63DD00E5
+:1013B000EEB72FDF7FFC18F9AF32B7770BD13DDFE7
+:1013C000E018497E6F79E21EEE9B35B91D7C2FE255
+:1013D000CBF4A21F5A43725A6E0D719FED7A7DF5C0
+:1013E0009EE8EF58D8FA620EF7911D79A437DABD5E
+:1013F0008847933BAAFFADE11139E7DA76A0F5877C
+:10140000B5F1A9579F19A6F6F7E77ABA89AF07DCB5
+:1014100022BF6F3375DF8FFF5F559E5DE4731B0046
+:10142000F5FF2DBD30F6236C233ED1FBDF99480F2D
+:10143000F737940292EFF2E93627F1593B1FCFF1CB
+:10144000FEF11AF7748CF07C467ABFA44AF4EFB52B
+:10145000F5B024E4EA5F27FAA9CB771F39F624DE3A
+:10146000B2F88DDC428A07DAF3B17C46FE0EE3EF78
+:10147000E864F1FE0BF9FB0D9D1FDBB7FFA97C0DA6
+:101480000F12EF69C31B2F0F76E0F3CBE9BBB63C1D
+:10149000D20FD1FF82067D5F0BF9E5A7FE46D7F795
+:1014A0005AC0EFC72C6A3CB168CF0F34EA9E7F3335
+:1014B000C1F34FC27FA7EA37707FC080F737A8FE1D
+:1014C000A941ADBB63FB2F0DADA26FDA9066E63C80
+:1014D0009AF21F5AD7F29F951F8BBEE9CA0C9167EB
+:1014E000139E2467E9700BE70B57FBE212C67BE4FF
+:1014F0006382D99B309274D2BB82E3997C0BCA99E8
+:10150000DE87FCF52EB58F20E2A35B8D876E3A87D0
+:10151000F0CA49E23859A4DE8BF505F7EF46835748
+:10152000CD1FD4FEDBBA16EE3FFC1F5946A94AB0C8
+:1015300030000000000000001F8B080000000000C9
+:10154000000BFB51CFC0F0030947B3A3F20FA3F187
+:10155000E7B0A1F233B9D0D4B3A0F283D0F4A3E3BF
+:10156000762606064626FC6AF061116606061920F4
+:101570005601621D66F2CD0161235106866209069D
+:10158000062E20FD5F9C81C10BC82E01625F20BF2B
+:101590001D886700B11450FC029096156360782E88
+:1015A0000AD1670D647F1323CF4E4B5ECADC3C8AA1
+:1015B00029C3E6B2A87C013506064F750686891A4E
+:1015C00010BE1E92FC0AA098A01A847D481E98DEC8
+:1015D000807C5559ECE61E06CAEB02E5776AE0B757
+:1015E0007FBB0E2ADFC10C959F8B26DFE882CAD70E
+:1015F0007043E5EBB84368003560D6A4D80300001B
+:1016000000000000000000001F8B08000000000028
+:10161000000BCD7D0B7C54D599F8B98F99B93399CE
+:1016200099DC241398BCE02604881A6012121E8AE2
+:10163000781302461BC304D1E22EDB1D686B23CF57
+:1016400001ADC6C736139290204482765D162D1DDB
+:101650007C15156B4AB14BBB6A27402B55B70E164C
+:101660001FDDDA6E60FDB76A955F50A9F868F99FD3
+:10167000EF3BE74EEEBD998447BBFBDBF8B839F78B
+:101680009EC777BEF3BDCF774E9CA484A8E30939EB
+:10169000033F5710F21AA13FB9434F427A09A98676
+:1016A000E7801C9E02CF187FCF9E81A57D02ED02B0
+:1016B0008A4932839022C27E8A5A36AE13A71232EA
+:1016C00096847E31B99896079635103F2DBF75D513
+:1016D000BBF0DCB8B8B67EBE4648DE92BE2357D219
+:1016E00067201C1722E584DC474442F2A1BFD25890
+:1016F0008D97900EE8EC5242C6C4F2F45839147437
+:101700005A20E49B0A1F88889A4CCB3EFC75681EC1
+:10171000C693102749946145E18C6B787B7B7DE310
+:10172000E98376469D62F8FF7A02F33B5B3B720BDE
+:101730001B2F46FF3943F15230343EF693D76C2AC3
+:1017400013C08FF5BB9EC2FBBAFF95F1F249A55BB2
+:10175000ABA2F36D10D538D4277D59322D0756C969
+:101760002421D0EF55BD82433BFBBA6C24A4BECFED
+:101770008BF8159A7C43F05D47049CCFB83BDEDEC6
+:10178000D51520E4D4526F08E9432524277BF87C43
+:10179000FEB9959084CB545E5C2B4470BCD02F4A2C
+:1017A00069FBD86231F428C0D3B0280BDE1BF56E7C
+:1017B000E3E30CA70FA2C9148F32A70FB941D4DD00
+:1017C00053FF7AFA902F903E726F31B523E7BF5ED8
+:1017D00088F7EA73A78FBF763C635D87F3551BC21A
+:1017E00031EE8E5237A1EB7F6FFDA2CC489A7A235F
+:1017F000AF6B25F27BA081E8F134ED36C17AE23C93
+:10180000631679834FBA3E526A796FB6AC973476D5
+:10181000C6925DA3E0430A58E76BF4EB6C91B4B752
+:101820007368515645E84FE6FD6D5497C708D02DB3
+:10183000D036C587D45B9120943F4890841EE51034
+:1018400088B4EC54F5F8DD0294E2B82E067C4AA97F
+:101850006819CF51E8B1AC07591213CCF03B5B9C2F
+:1018600008870C6CC2E55D18851B831B8638330125
+:10187000CA775AD65FF692849BCAD54DA595C4BC4B
+:101880000E069D0A8241A7779E9B5CB18FB7D80A4E
+:10189000E739B7F3CADAEF8D3625A3B593C9EF0D53
+:1018A0003C51E4FD0A7E31AD7B9783EC17A611D243
+:1018B0005EB831066FBBE07FB3913E416891AEC226
+:1018C0004A15E889EC166480D36D9047301BEBED28
+:1018D000221AD2534CB895403DC91B463C19DF47EC
+:1018E000868BD35D4CEF2FA5FD5EC3BBBD86EB336E
+:1018F00052E5787BC080BB04E73154A6F3F8E0766C
+:10190000FA3F4A1FB10A21FEA830FC7B03E8432AB4
+:101910008F1AE0BD499EB804AB3C6BE0DF0E3EF38E
+:10192000C6A4E9941E93218980B8DAF08C4BAFA34A
+:10193000FD1FB95C88BB040E2FADDFC8E17C59CF19
+:101940002902FA4CD6B9907E1BAFFC2400E47B62DE
+:10195000FFAFE474FCDA38C7310407FD6FAD797E60
+:10196000F4BF313006F2651DD29101D7EA4A09E190
+:1019700048CE11E230CEA1DFFEE19ECB289C2F574E
+:1019800009219786F0FA081D2FA97F14184D4E10D3
+:10199000637C8DA8804FFBF8A9F550424B802F9BAC
+:1019A00055A776371D6FA5143A0C7A8C8C65FAA171
+:1019B000599D5407EB23098C3EE60979D8AEDDBB6F
+:1019C000610CAEBBB434ADBC6AA68A42AD84EF5B99
+:1019D000268D0A67DC313860A2EB96B78AEF39644E
+:1019E00082738AE00BFC3E83FE3293CC8475FED07A
+:1019F000BB28334146EEEFBD56A54D7610F249ABFC
+:101A000076CF21C7F0EF2B2512ED2B1FFEFE6A418A
+:101A1000E1F88839C13E33E69D9AA73780F4BD12BC
+:101A2000C42F25F595BBDD6DB259FED8E691C2EF06
+:101A300005B65302EB63F91AF05B64A100FDC8F42C
+:101A40009F1943FCB8724F13E33B1BBC9D81BF0D34
+:101A5000BC67E3E30FBD1B3682BDDAEE60F4D291C2
+:101A60002B863690E1F462AC8781C7735D8F2D823F
+:101A70001BF9C3A0A36671E9A8EB7E363ABA15E854
+:101A8000E892FF793ABA0FE8A8FAFF241D6DFFBF6C
+:101A9000484743E52BD15E58C8FBEA1FF8EF6F8338
+:101AA0007C7E5D9750EEBD3E87C9FFD7234C2E2626
+:101AB00049A4A71AF4C15109E554526FF721BCD4C7
+:101AC0002486791C81DFE8F847B9BDF46AAB42127D
+:101AD0009371FE458BE8F757AFFAA410F4D7AB74B7
+:101AE0006DC1FE266450D769FB5752656A8043D9A1
+:101AF000CDCA836DA763609F270556FE69DB693DEC
+:101B000086E36DD97825C5E742F895C271DD1C21C1
+:101B1000AD1DF6A2E06478A92316BD4AD7E545813C
+:101B2000D28BB298DAA188BF3041FFB094DA09268F
+:101B3000FBA2051418C8E57A17EA3F7BFFAFF079DE
+:101B4000DAEDB8EBE6D438405FB8169F940728FC6E
+:101B50000B170B0E660FC5886A825BD4051DF44017
+:101B6000788EEB21D07F619938D434F358A8BB2C00
+:101B700076D749AEC7285E9630BF452B6A9A325455
+:101B8000FFA4A17F6DF319892E8C7918E5C5734EDA
+:101B90001ECAA1709106213451033AD58ABEE233A0
+:101BA000F79F61D8373EC0DBEB4BAECD647410417C
+:101BB000BD6AD0D32F8E7DC33100EFEB72502E5D06
+:101BC00017962CF6E4B5F51996795D3FE7DA51EDF5
+:101BD000701231E1C144F7FE0282744AFE8BDA29A9
+:101BE000944E63B58311B45B8E0B5A3B2D67CE6D5B
+:101BF000190FFDDE2966637D616ECBE401B4B71673
+:101C000020FD67F03E339DD13F94805C9D289287F4
+:101C100034B04747F70B3A016F9387CA8E402426AA
+:101C200050BC6931B5521A05DF715DAC4F47AF1337
+:101C300044B66E9DB1456A290074C82A37B2EAA23B
+:101C400068FF19F5291D4F107361DC18BE4FD17163
+:101C5000379D176DE761B608C9BC78512619651E16
+:101C60001DB6F5A7E25F4F27675772F8C87ED6BF4B
+:101C7000219332B369FF69EA1BCF2EDEFFE990485A
+:101C80009200A71C56001E52564BCCFD10BD02CB35
+:101C90004E5E7405C34A31C5A7AB5C846990CEF231
+:101CA000877459033CC470BD37D3B52D34F1E5E6D4
+:101CB0003F4BE8E7AF144BDA406E6CEEBF89681417
+:101CC0001F9E609C6079CA8D0AE0693375B29230BC
+:101CD000BEDC47008E8C42FA3B1D274325718DF6F2
+:101CE000276B7D099196E57A12D2E9279F1A123C5B
+:101CF000D4FF3E102C6993E9FB8EA504E52301AFC8
+:101D0000DC443F1DC1577509E867090901C01D8101
+:101D1000E538CF8DE5CBBB8BE9FB530D32C60FC841
+:101D200017145EC3AFA77E86A78CE830DEE63C12B0
+:101D3000F7A21DAC237E9D2A5B3F6D7B29494CA7F2
+:101D4000DFB366F4C3F8B17F22A1896C48946B328B
+:101D5000972744A6F407E3B7A8A1BBD3D09F42229C
+:101D60003789D5A67556C3E8C7DAF196E924570333
+:101D70007E3B2A281FA4917BB78A22D2413CB468BB
+:101D800061499A71EE1435944F46593BED44F8473A
+:101D9000AA3F544F26891CE85A17002F241CC0F96B
+:101DA0006593D48F0EE51C3EDF31248AF582B37A29
+:101DB000FB81DFF2F5BE1AC0C53FFBAE3F82EB46AA
+:101DC0001E54C18EA5D0969EC9199217A073607E2D
+:101DD0001F8644F43B7C6242D569073E773288CE49
+:101DE000AF46302E97094D28C077B72A1D6097F867
+:101DF000494880EFBE901C33DBF59984962DF11491
+:101E000072B474069216E30FA2F603EBA865D169CB
+:101E100000CC7D7EFDE7E0376DF145D00FFBC4EDD2
+:101E20009F0A83DDE6F13F04CF4FDCE3E2E89F85C4
+:101E300098BFA5D07F40DE65CE922DFE4D966E2DCB
+:101E4000E7D8FCB0059217E799750DE1FE95DE30F5
+:101E500071CC105C14A226A0976D753201FFDFEBE8
+:101E600065F018F0E54877CD0478291CC7010E8A83
+:101E70001684E314F922014BEC2F23183FA5701DA3
+:101E8000B7C175DC06D771335C2D0A9BAFDD5E8C64
+:101E9000D592B22805EE3991FB1FD46E02BBF11426
+:101EA000795FAF07C2095F8D7AD6AFB2365E2589FA
+:101EB000C10A95A8480776BB91AED38716FF6B166B
+:101EC0002F6B4480795038ADDF4921D20B96259293
+:101ED0008A0B2F9F65E04BFBF26F28FFDD74D84122
+:101EE00080BF281F4BF0DDC1BFDEC4E3C3CBC1BF41
+:101EF000A6F8FB1A09FB01BE0F888871A80FC8ABB2
+:101F0000FEE926397942E4F6092CB1998F4928086F
+:101F1000725CF66E4C4A7E4483416FC2195CC710F6
+:101F200093F35E467731A2B4A13EEC66FEA7114F53
+:101F3000FD7AAFD51FFEC6766BF946B2680CC44B6E
+:101F40006FFCB683C469BF3799FD7BBA4EAF892A4F
+:101F5000C2F70D12DD0876499783D91BCB55224372
+:101F6000FC73F5BF7D67C6323A9F53200FAAC17E2E
+:101F7000A7E09BF4C88A40DCA9970F9F5FBB106A5B
+:101F8000BC4C18797E5D8E6423F8DFB11E07DA99A8
+:101F9000C41E07DD27611CD4D40EE1FD6AB7757E2F
+:101FA000679BBF7DBE84DC8BF35DB17B19DAE723D1
+:101FB000CDC7B99BDA9B69F49D57122C711F83AF73
+:101FC0000D7AB7F37795A4B1B80E558368AFFC2EA0
+:101FD00023DE8EEB1B9D09EB7BB6F6B3A17DEE8570
+:101FE000B79FFB578E3FEF2CED572B830B60BD3710
+:101FF000057AC3C09F461C6B0D89E905F457C7B32A
+:10200000EB6260BAA5EA05CFB15E21AD279D43BD65
+:10201000D2D1FB3BC1ED9217F63CEC043BF5832794
+:102020008E35821DB0F2DF25A2507A38B1C7471233
+:1020300068AFC49D60DFACA07417C77262C6B526D6
+:102040007B985234AEC3CAA77D6847ACD8EB8A37B9
+:10205000D0F62B7EF4DF5309C5C3890D833F2F00D3
+:102060007A7E426071D7D8C0D46BE9FB1532F9C7CC
+:10207000701A3A5A26317E7AFFC7194BC04E147631
+:10208000F77F05FBEDFBB2C365D2C74B24078E4B30
+:10209000EBA11F117B5C884F14187C667FC088778A
+:1020A000BFFFB8C0E0DBEF88BB01BEDDBB9C115AAF
+:1020B0006FEDEE9348D7F39E7ECA0F7858BBDF6A68
+:1020C000A7AFDD2D255C53F1790C9EA041851980C9
+:1020D0004FC6CF6BF6AD46BDB1A66FF349E0E7B58D
+:1020E000FB1D16F94FF1124A005EDF90420D50FEC3
+:1020F000E1F7FC1A45D57BC947FD8057DAEF322757
+:10210000A5AB85B3ACEDA0FFD3D9C3FBA39E21FA49
+:10211000CD6BFB36B1F1F65DF30790B76B09D35386
+:10212000063FBF07BFE40DD7339B246B7CEB1479CC
+:102130007906FA81BB73D2FACF865E31F87AE5531D
+:10214000A776C6E8F8EFEFFDE3CE189DC7AABF7CDF
+:10215000B4F34EF0979E77AB20AFD63EF19A9F989E
+:10216000F0FF88C4F6034E3CFEBDC776503E39F101
+:102170006B17DA81279EFBC3388DCEFFC40F3E1D3F
+:102180000376EA2DCFCD1F0BF8B8E599796347B3F5
+:10219000D7816EE32EF3FAC6B17F6DBF009B20841A
+:1021A0003CCB9FB6753AB84F4A4088E083375D71A3
+:1021B00017C5CF5AFAAEA512D66D35EA2B28DF45E2
+:1021C000F1BD664FD749696A3ABCC70AC4203C13BF
+:1021D000052408EB7EEDC2CBABE0E908694027643B
+:1021E00010F584BDDDDAA3747DA78DBC9ED49E70EE
+:1021F00002FED7EED9C4C6EDA3EBE91FBE9E1FC0F9
+:102200002FB387AFE741C91A673A45567D77077CF8
+:10221000DCC7FCCE91D673F533D78DEADF19F2E136
+:102220006C786E16185C5B25FD5712F0E3DE271FF5
+:10223000DB1160EBDC401173E2A953E36093F71DFF
+:10224000C7E057404E0E3EE752C1AE5EF1DC1BC800
+:1022500077279E39E2D4707F9A7805AA274F90D4C9
+:102260004F12F4E61A8115D63EE24BB8FC43EBB5AB
+:1022700026DE54AFF9F1FD317C1F67FCB026DEBFCE
+:102280005848B37E5EB984E9A7782EE265B59674A6
+:10229000AA5EEBBA0AB3603D8F2D00FA1B693D8D33
+:1022A000F9AB30FF99A6757D84F1F148FC7A62970D
+:1022B0004B163287AFF3096E57AC8D0B6FA45B776B
+:1022C0004236B0F8DE08716FE369A70BA76CE573BF
+:1022D000A3BD31FFB3F1F9D9E7757E783BC5F5B5FC
+:1022E0001D7FEF7F915E0F94C802D75BBDF5F92685
+:1022F0007DE776503D560C76673456503C04EFC669
+:102300003E09E5FBFBBB25B4F7ED7262CD087E7D8F
+:10231000C818677FFF549067EF1FF831A74746EF53
+:102320006BF61C73C6B85E889BF502F497663D2E6B
+:10233000E5FDAD7D367D7F6BF79C4CDBDF7BB2FE30
+:102340006580FFBDA483C46817EFF54969E324A540
+:10235000B2C362676DF4CD783393B693FC1E0DE67D
+:10236000DDBE417F2306F6C8AB0E82F6A31C7AC7FA
+:1023700045BFB7FB3CB8DFD2EEBF916826FDDD61FB
+:10238000C3931C0CA31F2D07C2556C2F346EF1672D
+:102390001DAA68819BC8B142D8E7FC65F11F64E8BB
+:1023A00017E2699A292EF48A4C3A73687FAFE842A3
+:1023B000A88DA4896BD9FA0FCF918866A6337DBC0E
+:1023C000688E2FFA0FDC8E718D16124D40BC891469
+:1023D00092BE474DFD3ED8AAB1B86B78BC688EFF5F
+:1023E000B9A251DD45E128BC452D01FF6DA4F18B5B
+:1023F000A2D67D5F63FCF53C1E41763FF1C413B469
+:102400003C1EBE616A45BCCD09F13795D937F3B89A
+:102410003CFC29B79F0F08E1436087E977C56490CA
+:102420007782D626839D51FF454C5E6EA2C77AED1A
+:10243000641EE8D5EFFE595A928E4EF773BA6AFBC6
+:10244000A71FE541FCEE01F76D85CC990D237C8536
+:102450007C9E878ABEE185EFFDAB6FF44EA6F8291E
+:10246000084A04E2350581655B2A60FE47A5905B5A
+:102470001BDEBFF1DCC9E37A0FB5AA28FF1F690D87
+:1024800062F9318ED7DDAD65F87CA23584DFF7B413
+:10249000CEC2725F6B3D3EF7B686F1BDFF8E17056B
+:1024A000A03BF22DD207F19A7DAD4BF0FB8F5A2362
+:1024B000F87C94CFA71EF0E2B5CC1FE331FB3BAE16
+:1024C000D800F118038F76BCD7D1A962FF9AA0017A
+:1024D0009DDF2E33F962C7EF38574208D3724B9411
+:1024E000E52BECE4716363BEFF2A337B731F87E740
+:1024F000C7EEC8F765D86FAA2F2DE7F1F110C8EF26
+:102500009D42786B05E59F178A6606CD72B8C8179D
+:10251000D9279BE8675C378BF7EC9099BC1A4F4E34
+:10252000F66752BCEB5F100DE8CE98EF811AAD1044
+:10253000E4E40141C0F5D6BF10499989EE8CFEBE96
+:10254000238B7C7F23BDDC1EA263260FB2AF92CB10
+:10255000C0AF3D453C2189C2DB9947F681DFD209F6
+:10256000740976F26F33304E6CF8375BF87A67BBDC
+:10257000D9F7536FF9E2207F46F27B36F2FA1F72E9
+:10258000B856CBE15FC9B8AF1C1758BE4302E398F9
+:10259000056C2A944E976EA56B45EEB9F4BD3721B4
+:1025A0003EF8C1336E0DE0EAA93AEE37E391AC9202
+:1025B000DF37EFEB18EFF34F17203EFF1F891C3377
+:1025C000E339BF79D009ED3B056D5B1DCCEB3509D7
+:1025D000F9AF53885F84F13399A05FD07953300EFF
+:1025E00072CF68E70B59F93BDB1D5EB20CE6DDEC00
+:1025F0000CC5D2C8A7DF666816F9E00A5ADB0741A6
+:102600006756B3B246E9B382303911927509FCB40A
+:102610006A12C1E74CA2E133CF11F90CE6319D8477
+:1026200035807343C6B8CBD8FEC1FF18DE14C7FF90
+:1026300041BC19F41ABCB46C1BE41F903B44DC6F22
+:1026400069874F263A5FE810387E1594E7053CAE5F
+:102650004FE5FF0B4501EC86C549D40C9483057CFE
+:10266000C3A065E024C67783E3088FBBC731DF6969
+:10267000C72A11FDF507DE12E290EC726A55C99186
+:1026800049B47D0DE573589FECAB4A33CDFB0C0686
+:102690007F3CA08433D551E2FC065F18E57F19FF2B
+:1026A000BC007268DBF8E7FB413FE40F08211063D0
+:1026B000F9DEE864904735BF7B3C0FBEFFC6139937
+:1026C000635E9F1DABA3E3014EAF2F3C17DE870B6C
+:1026D000E33780BC3B557F8B0B97D9CBF25E5AEE2C
+:1026E000D2B64DD6465E9F9D2DA3EFDF18F3DA7963
+:1026F0008EF332D6EB54FDE228E8713B9EECFD668A
+:102700005FB578D4F11F04BDE2C2F92F35CFBF30D9
+:10271000AA627E8BD1DE98AFBDBD7DBE43FBC0E714
+:102720009617D4E72039B0DE3FF87CDC0F5F2140FC
+:10273000126109E89FF2E71A806706894A8C1FC276
+:102740001AC87F839E778C792C0FF5821C2F4679CF
+:10275000778EE3759270B806ECB2901832DB2BC618
+:10276000B33D45E7098CABBAB81C1133EE0AA6C3DA
+:1027700073AAFF42CAFFA63CA62D84B078544241FA
+:10278000390F814295961D8749E5DDB4BF66079BE9
+:10279000478DCCE221D30F6BBB241657959A7C262C
+:1027A0003CF2FD0623BEDB49EE22AA067E45453FEC
+:1027B0005437F8F4E7CEC8B71D908717D430DFD36D
+:1027C0001188086C3F8EED0F15717E9D2F2D55C021
+:1027D0002E6921E17AB04BC85189B03C3CC6D72E56
+:1027E000631F8CF3B1CB4D783C38C8F89AF77390DF
+:1027F000FBA53FE5F6C9B3DC3EF909D827B45CF484
+:10280000F1E00180733FD8292EB03742F87D1FB721
+:1028100053FCB77812E01FEE6DD5B1FC706B333E00
+:10282000EFB9F5709B1FFA7FEE4707FD14BEEFB4BA
+:1028300010E4D71692FCC54A80372A627C63576B36
+:1028400014FBCDDF923C007B24BD2D077485BEEFC9
+:102850008AD68A6E5A6F6715C1F8C64E85E21DE4A6
+:10286000631F41F908EE12CA2F2E9F32D79522FF1F
+:10287000F654EDBD0AF051788D88DB2F06BFB9BA4A
+:10288000070656D2F283CD7BDD4086D9B9C9F52F34
+:10289000815E9F43E5AD06EB92EC5E40D7B7A06842
+:1028A00091328F96FD7D1BD7817EF6EFBBFF66F0E0
+:1028B0008FFDCF3EF14D2817D8EC59FFBEFDB7B1C3
+:1028C0007A2FDE0EF50A0ED379D0F653D563FD309C
+:1028D0007F8ABF81CDB49EA3CA9AEFF894613F74FA
+:1028E00012A4ABED3FD82FC2FC0303E11AD8AE19F6
+:1028F000F366B41FC8A7F01D86FF5DAB3A76413F73
+:10290000EF3A8A919E1E6839001175F29D6FBE8E56
+:10291000F47C70D57A02F4E05A25635CB160F52D41
+:10292000E41B2679E16A91D3C699DF75B8907E3BA6
+:10293000572D4E4EE2640A7C38EEF63A05E5C5CBDB
+:10294000D67C07637F781789BCEB40FE62FBC4B27C
+:10295000CAF6932FA148077B89AC15599E5FB8CF63
+:102960006D8E1F16AE16C3E9E0F8D421E3BC3AA27F
+:1029700075EFBC48E72BCFBC15ED52D26B1DDF18AD
+:102980008F8EFFA9C3947F22AB0C2E8D84441F1D14
+:1029900077CF5E4F3E944F470D7D95C0FDD3A72B5B
+:1029A000C4C4780ADFBDBD22E6A11CAC67FAABE760
+:1029B00016B6AFD5C3CB3BFAA801563CC44F863FF1
+:1029C000B023CAF6BFC91767D0BEF0723ECAAE7850
+:1029D00055C1FD8998EEADA1EFA71183DFC4A175A4
+:1029E00007FB658B950EC48E6C4B59A3C6BA39EFA5
+:1029F00018360D5365D4A74715F0274FF5C904ECD9
+:102A000097697C7FC88ECF1D9CAF7742DE0CF81D86
+:102A1000ABF6BA350AF7CF0C3A6989EAA0178BEE04
+:102A20000AC798DF63CDA3868C10C07311DF87229D
+:102A3000D25B15480FCFB23C5A631FD15168CDAB62
+:102A40002EB7E58317D9F2A8CF37EE52EDB4C7E31E
+:102A5000B65C84FA42F3A31CCBE7633D329BBAF920
+:102A6000D386C75F52FDF2F802E9F5E37AE673799F
+:102A700078CF1D5233F80BFE159559E638E9D54E3F
+:102A8000E6C71CFAAD0BE979679DC2F73D59BEA7B1
+:102A900083AF7B9353C37A3B7B6F55009F5D81125D
+:102AA00037F473F0D29FB8315F85E7AD1AF278033F
+:102AB0007D7F13EDEF3BB922EAA4CEC257F360BF8E
+:102AC000FEDE3A05F352FD19037D0769D97BA73372
+:102AD0000479233B6B124BC226B86E7732BDB6D455
+:102AE000C9F787B658F33A285F2C7542DE98378AC3
+:102AF000FB99A2C2F37B6D7EBF810FFF81ABC4E265
+:102B000029EC593205FC54262FE33CDF6A27D70B0A
+:102B1000867DB183FBAD5BB8DF6AEFB7B4593F8008
+:102B2000F6D92AB5124254F6F59DD06D959FC53160
+:102B30002B3F8C6FB1F2435134DF52BFA0B9C4F2C6
+:102B4000DD17BAD866B72498BE236C7DBADCDE09DF
+:102B500020472AA93EE6F607CAB791F47DB343DFC2
+:102B6000E004B9768E76883F231C85789BDDCEBE47
+:102B700087AFCF3FC8FA16E88FFA75F760BF725C6F
+:102B800060E787AC76C93038B99C1B05CE7F719E53
+:102B9000877D76B6FD37FBBEDB6D5278FB2BF439B3
+:102BA0003793E54976FA989FDF09F1555A7E8ECF23
+:102BB000EFFB4E099FFFCECB733368FD34FC6DC431
+:102BC0005D7F0A0939506F6CFAFC4BB08CF07B4189
+:102BD000FAEF3F75B27DEEB9E3471FA79F8FB3C5EC
+:102BE000A13FEB34C5F7BA9CFAF3E6F24127DB9735
+:102BF00036E8C2C8AF34ECB45B1DFA2173FDA1A75F
+:102C00005D5EB2FD915CBE9E3EC2F8EF674B966F73
+:102C10009A48F9D959E845FB277749C73AD10F793E
+:102C2000494915FC845C2EBFC96226378DFDF6EC40
+:102C300006AB5CB59FC372F17C7997FDFC0D97AF35
+:102C4000767A1C49BE1EB3C9D7545C7B04BAB2C79E
+:102C5000B55BE057667F72FB389CB968CAC8F4F868
+:102C6000CBD6C19E431387CAAFC0B99AB474C0F61D
+:102C700019FD07DE6D585C05FB795208645CB235BE
+:102C800031F7ED8943F22B3C27EB67100F0DD76529
+:102C9000A1BC690CFEA9E7500E95CB7AFFDCB74DBD
+:102CA000F34CAA14DA09A3F089EEF8CCCC5FDF0369
+:102CB000590F76111F6F2BC7A7DDBEEE12632EE8EA
+:102CC000F76332A00BC5A3CFBB03F136E0053A1B77
+:102CD00069DED35D4CBEFB67454310BF739D919089
+:102CE0000F5CE30D3B268476CC0C5716A3676F0967
+:102CF000EEEF51FF7DB01FD6C1CBF2FE0DFDF89176
+:102D00001167E57AEFE62C56DEDCCAE2CAAE83B381
+:102D1000DFD0683BDFCB0E0271CC4D54AE437CB0AC
+:102D20009BDAF9F0DD5F354020BEDE4EEB474CFE0E
+:102D3000787BA85685FDC68EF24A05EC0A694A15CD
+:102D400096E5E24AB5968E39A5EBFE79B9101F2FAC
+:102D50001531DF761A2DB79552BA76A938BF5F962E
+:102D6000BDED05FB2C1B82A9D543EBE9A88AE8122F
+:102D700085C711546B214723A5B7399DD1F70F4162
+:102D80007ED1F784C86C179DFF2FF9B9AC2E67B4BC
+:102D90006C3DF84372CC0571C01685ED4F003D7453
+:102DA0004C1F82BB96E3D7CDC74DF9477C3D3F967C
+:102DB000076290F2DA2592E674EBD3E06272AE43DA
+:102DC000D5D551E949953FB3E455CF61FCE40C50AA
+:102DD0007A32F1F548F25A728517BB7287F298E899
+:102DE000C2AAC8A784D981C6B99F3F38F52558CF54
+:102DF000CBF04A0AB3914EE9FBF99EEA0B91FBDA5C
+:102E0000D63ABA6E07E6541DC17856D2817124FFB6
+:102E100004F28F663BE4251706E3E893C52DEFA681
+:102E2000F4119FCCE21504E826832A62D89F2C1265
+:102E3000E30F1503BCBBEA27D0FEBAE489D4521FC6
+:102E4000EAA7A688F9033DB59E66B35FF0C70CB646
+:102E50002F739BB7E619171DA7DC1BAF45F30BB209
+:102E600036C7B0735540C797A8644010410E860915
+:102E7000D39B2185C54DEB543847259008399331B4
+:102E80009A7EB49EB77A428E6FF0003E022C0EE618
+:102E9000DB2E6092A0D4A7273C2012BC8BBA5CA882
+:102EA000C7C365304EFF0C0FF1D2FA7FEA77E23EDE
+:102EB000789FAF4006BC3E2F2EFFAE93CE77F0D763
+:102EC0002ECC7BECFBF3C59897DFE7BB6C01C8ED1C
+:102ED0003E811CA6CA9ED49C2EE049882403F6FF9E
+:102EE000FCF37402FB30833F2368FF39822FCD7DD2
+:102EF0007B3A4E3C439C45DBB949B79BB60B7DE61C
+:102F0000F9E80A4A577BBD95F74D2343F11623CEC6
+:102F1000529711D90974D139E63F9B816FBA299C28
+:102F200012FA137A10E0AECC15312E4972BDF18938
+:102F3000F47DCDE1401DE495D6C8159832EB9FC7CE
+:102F4000D6FB379EC86E986F9DDA549745EB571D98
+:102F5000D550CE2E08AE3B04E5196FB172A793F1A0
+:102F60000BC4918849EED69C1E87F3FB21A7938E54
+:102F7000A09ED48551F9C6761EC19A4767A603C89C
+:102F80007F37D141C461A68359940EA698E94017B2
+:102F9000CE870EDA50595F08FFE86FD40943F1BCC1
+:102FA000E17CB04EC92E1FCE2F061C775765074017
+:102FB0008E1A7CA1CEBC0BE5AA6B99330CFB2D06B7
+:102FC0009F18FCF1A9DB817C48F9A411F87DB15769
+:102FD0009B9F8E4FC00F31F3C3B523F04D23193C97
+:102FE00014A08D1A6512CBA4A2E497B3DF291D6744
+:102FF000E2033BDE1AE708E4B8459EB1B209AF6AC6
+:10300000EADCA374EEF87F55D63A03263EDC48FD91
+:10301000103096BBC51001BD52ED5DFE29D0A5DC78
+:10302000F08320F8830E57B819F36967BE9F7123A8
+:10303000A5CB3F8D1135987CA7B6FC69E4E7373303
+:1030400008D8273D3356603CF84F3745C6839ED895
+:1030500044F17F1CF5727CAC88B9990363D93EBCFE
+:103060001664CF4890BD27FC7B9C97755E6F00EB84
+:10307000D175B6C8C71E37A3F71E37D3179B9CBDA3
+:103080000AF0DB60B1A29AF3A0AF90981D5BA5F0A7
+:103090007DA92FDA35881B5629ACDD7DAD7D687F93
+:1030A0006C6ADD8FCF9C8638813C2B4F594C83FD59
+:1030B00070E52FF30407F0F1C56CDF16DEB799EC6D
+:1030C000AF710AF36395BF4811E04F65434CCB36AF
+:1030D000C959451422E9ECE8AD6E99B5DB40F0BB67
+:1030E00072E05F719F3BA734247C1DCA1B7A49881C
+:1030F000F6E34EB0F781525DF89AA9DF40439F4551
+:10310000CF35D225C8AC44EB09CFC1746A1EDC1799
+:103110006B0CD4BE2B4F1D4E47F073DC440F06FCE6
+:10312000C6FEEC2DDCFFAE2B5190FF3A5B9CBB4002
+:1031300035372ACC2EFA38503BEA3902D897A59673
+:103140001BFAB9F084FDD9D864B63F0B65D89F85CA
+:1031500027ECCFC213F667E13BECCF42F9FBAD3A67
+:1031600096619F16CAB04F1B9BCCF665632EB62F97
+:103170000BCFFDADCDF8FC496B14BF3FDBDA82E528
+:103180002B5CCCBF2165B120D8CBDDB73B75C8BF68
+:10319000E9E47470502FC909D1757507589CC0FDBA
+:1031A000F2BD780EDA1D1471DF7563F05EF255FA28
+:1031B000ECAEF675431E8CF2B4179F6EF93EA2E199
+:1031C000BE6CAC1922A7AB94E97532B5134A83EBF8
+:1031D0006AB36979BD32BB03F21127696DA1E5EAD3
+:1031E0005059F355AEF881A93CBE7C97ECA1F56F20
+:1031F000EBBEAC03E401C001FBC86DCADC3AB0E32E
+:103200001225D45001B956EC8C033D7F0DD66B22AC
+:10321000C0CFFCA92F91F620C435C66BCE4AE0433F
+:103220005A3FC1E8FFDCEA774210387778BBD1EA31
+:103230008955E7548F48A3F407DF85D1FA21ED6A59
+:1032400092C2BE196406D8476EB6FFDBED60FCDFA4
+:10325000ED66CFB739DFFFD85D3BDF4DF968BE9B28
+:10326000F161B73B5C0FE75006A788A18708EE9B8A
+:10327000C4DC7028A1A5F857705EE8D6176502FB7C
+:103280000A0F72BE9D38DEC7F4F49D0AEAE92BC727
+:103290003FD5914DCB131F0E8540EF6E26210FD0E9
+:1032A000496C8B88F9294F564DC86EA2D52FA97E3F
+:1032B000261BF4CFA70AB377E3DCDF68EBBC713CD5
+:1032C000C4FFFE7484C9BF2739BDED7224A3B89E24
+:1032D000D55EB457A8C380F6485B50C6BC22318F78
+:1032E0003D9D0EF5EFA09E932AFC1885C7F9E7993E
+:1032F0000AC63F4EBBF8BD1749B4539CEE889A45A9
+:10330000DFF7C644E4F776D51307BB7AB3B712CF1D
+:103310009BC6CA653C77B2B95C64E7657CD7C7C118
+:103320003ED9DAEF66F2C1AB605E69BC7CDFE1DA00
+:10333000003C4515F83DAE2FAA47BCABA28AF9A9BF
+:10334000F437FCDE1CC0732A1023C7EFCD2CFEDC43
+:1033500039E6B397A641BECED7D510BF8B00F3BFD9
+:10336000D1E412619F68F04006C0F30FC63D06032A
+:103370001B3268FD8EE56A08D661AA5A5B0FF90513
+:103380009D6A2DFA391953EA9465288752E734F07B
+:10339000BE8C8E7219F38BE03BF025E92087E09C10
+:1033A000BCB1FF9C915529807DD5D980613E38C73D
+:1033B00060C937EFC8BE1ACF27498DD9086727D112
+:1033C00015A81F6B9051FF15789504EE3F18E7ED97
+:1033D000E1E88529DE90B3CA7A7E23AF59B69C17FF
+:1033E0001F1BB1967379FC20D776CEE34F8AB16F5D
+:1033F00066C5937DBE398187B200DE1C38E0AB0D17
+:103400009FCF7D81CA26986781EA41B883EA861AF0
+:10341000905F6349B40DE8EEBCE1B5C139B5BC239A
+:1034200009EB3E559389A641BC7D7003F4BB99D34B
+:103430007977B1551F3FA848063F4E75E7429C512A
+:103440002431D3F810878C99C69BD09D6D294FEC01
+:10345000CDB7D49FBCBDC4F2FDA2F8C596EF97ECE2
+:10346000AEB494A7F45D6AA93F6D7FADA55C91B839
+:10347000DA527FFAE145967275F2EF2CF567BEB924
+:10348000DCF27DF6C00ACBF7CBDE596F295F3E78C0
+:1034900087A5BE61AFDBF56299FBC2EC7417DC1F38
+:1034A0006189CB5AFD00BB1DAFFCA55DDB0072CD71
+:1034B000EF44FA96418FD3F2FADB991FA5CC0D6940
+:1034C0002057C671395AE4D3AB418ED6F815D407CC
+:1034D000B297D593BD0BD0FE18B79DCAA3E9606D16
+:1034E00092D4F70C90CBADB1B9A5A678935BEDC59E
+:1034F000335B35FE7A02F179A3BDACEA2402FD40CC
+:103500001004E2E7D44B857A6E8DB637CDEB795156
+:10351000C4A3D183D4DF7BC8E4EF8DE4DFD9FDB948
+:1035200073F5DFC689C483E70D8470149EE5D1234B
+:10353000B590264CFDBA1B807E7B9CE1E65DB4DF36
+:103540009E120FEE5F1A7E5D77711FF2C560B18C1F
+:10355000FA85C85AB9391ED7C1D737437912FD4AFF
+:103560008A7794B706DE370B03F176903BB77B5032
+:103570001E8EFB2FD7ABC05F4A8952A0D0F7A18324
+:103580004E1DF6B7EFE3782D512B6A21A4541A6C27
+:103590003A00CF491AB533E8B3AC6CDB0178DEEA08
+:1035A0006679C217877E500BB24499CBEC3F79AA5B
+:1035B00033BE81F623A9148E347E85F194FCDBD9C9
+:1035C000FE45A9FC7BA037B0EACFD029D4642B7884
+:1035D000FF8C1BE840C027D28F3BE045BDE186430E
+:1035E000AF5096857886C0EC53D89FABC9DE8EEB82
+:1035F0006ED8AD60CF46989FDB01F41568B0AE770A
+:1036000086F27DC45387C0E2DEDD59DACBB574DCC7
+:10361000EEDC926C88B1425CA4C9246F7AB8DEFEFD
+:103620008A47E4F96F4CDEFC05FAAC1EB27728FD40
+:103630006F1727007CBD04E496FBAE5E02F4EE56E5
+:10364000E96AA25D1FD3C2A84F99BD7B3387A9AE9B
+:103650006409EEFB7F14A844FBD6DDF27C5AFCB96A
+:103660000724A24F1F19AFFE493B50DF9312A70654
+:1036700076458BE6D477A59107E5DC0FD934CE38B3
+:10368000E7CACEDB76737C18F1D0549C91C7D38CFB
+:1036900038A3D1CFCDB9956347B3C7DDD4BF8C98DC
+:1036A000E0DD44C701BC747ED1548F7890093BA7FC
+:1036B000FBE7F25D904765F849E5DC7EA9E2F81D7D
+:1036C000E724E827CC83B8490E78B55FAA07BE3453
+:1036D000E22CBF03638BD60BC588C4E26A0E436F2E
+:1036E0008967A621CC9A7306BBE28BE5A332BD465F
+:1036F000FFED87F36413BAADE73527F65ACB93B7DE
+:103700005BCB17C5AD656A351F05BB006C348C5BA0
+:10371000ECB67E6F32F603EAD8F932858E7C86E904
+:103720005FCB7D3984EBFF7CDE4F515FA206C46B1B
+:10373000E12D56BD9ACFF57CBE4D7F56FA248C27DD
+:10374000D41C0E1C02FBD188FBFCC6A359EE7530BD
+:10375000E2377679EE796B1BA15FD02F8FB8581CBA
+:1037600003E2C39F14F17849218F978CE3F19222F1
+:10377000162F7148DA2B4B05CC0B3DE9463B233A1B
+:103780008DC569D839AF0FEBE59F091A1B2F621A57
+:10379000EFB6B2D8950C0DF13CA867C44D8CB8803B
+:1037A000D7A7CF073EDB1C7A357A90D249EDAF5DC3
+:1037B00004FA992FBD7CB815E45B918CF9DCEACC56
+:1037C00055DFF5401C12BED3726DB13616F9E01705
+:1037D0000E8C0F7471BA36CE271A7116BF87D94571
+:1037E0001E8F60EC037978BEBE07ECDD4B76535A32
+:1037F000B4E83B16CF33E27653FAACDFFB8890A3F4
+:10380000D2759CB6242E32FB4AF7D698F21D2FE6CD
+:10381000EB367569E2DEA5B4BC87C42BE11EBA0A9B
+:103820004E1FA143D673B1638880E7A2C61C9542A0
+:10383000715A7FEAB3D6EFE5B673B317DBCFD1DAAF
+:10384000F6857C1239B98C8EB7458B0A2047B72C88
+:10385000A5B63C2D4FF6F0FDA2496412D0E17CC91B
+:103860001B4A007E5F93707FCB756CF21B90C7483C
+:103870008EB07C247502CB8B545F92504FA919A453
+:10388000A2C23BB48F74FF9910817D1123AEF50461
+:103890005D57D02B7BA85F5EEA003F5BC5721FF5CA
+:1038A000CBA1BC97FAE5F0DC47FD72780FF94850E0
+:1038B000DE4FFD7278FE84FAE5F0FE59EA9743F98F
+:1038C000366FCD7C4F2EEC1B9521BD782AF629133F
+:1038D00028BC5D8A4305FAB0CBA19A9A9B95C59402
+:1038E000A4FECEF514EE5FD4CE67F9D3F33D4FCDF1
+:1038F0006B93ADF13573FC7128BE362018F1350895
+:10390000791EE3FB0CA9385B84C5D9CEDE8F6EF43B
+:103910008371CD61FDF0F8E607B7FFE763EDF4D3FF
+:10392000EAEA7BBB3D25709E234ACCFBC7C6390F14
+:10393000637EABF7B5619E8C33EF6814D6755F95E7
+:1039400017EFFA713A222AC85BBB3F67F871767BA2
+:10395000DA78DAF59B8FDB1546DCB4C741307F3A65
+:1039600026507B02EC8BD6F8DCB71D23C7535FF7DC
+:10397000F0734536B9903A37C0E33E2EB066E93C65
+:103980009D02C707CF6747D158C2E27AE6B8AAA717
+:10399000348E87D53D5E1DED3A81DA7B68FFA991B3
+:1039A00020C4D136C2398134F37B98F37B5B9E13FC
+:1039B000ED8D8D790ADA497585A120B46FCF9B1101
+:1039C000349F1B30CE351CF2CD50064CFDADF79523
+:1039D0008CAAFF24AAAFB551F4B5E462E77ADA0FF6
+:1039E000CC56E0BC46B7777912FCE8EE6000E3EF16
+:1039F000FD793330AF27553F380BCF75485E660FE2
+:103A00004B4105ED6119E65F3E54DFA8D7EA6174CA
+:103A100042D919E38B6E6F2FD673C961BC4FC215A3
+:103A20006079772E95EDC7794A45A298E485316E85
+:103A30008B87C5A3BBCB232AC459BA8332E6E97767
+:103A40006B9588E7768EE7F622C39E08A11DF36F7B
+:103A50001CCF463FED3C0ED0DEEC447B2EDC92A525
+:103A6000C2D52F5E5F780FF073B7778302FB92CEDB
+:103A7000BCAA51FB3DC0E5F6C8FD568CA99B8EFD46
+:103A8000FE1BF4EBF42D57A15FC708E7915EE170D0
+:103A90005EA8DD6ADFC7A3D006CDF928F6A78FDBC5
+:103AA0009FF676ABCB079CB0EE9B1EB19E5F761067
+:103AB000769E6BCDFE75C8E73D7212EDA89E2F84F1
+:103AC000B4E7C2C66418FA2CE5DF5BECA002CE4F67
+:103AD00005FC3B901AE88B8A84D56E997ED85AAE45
+:103AE0004E5ACB33DFB4DB41FA6B60072DE6722F01
+:103AF00049E53D4B861994011FE158BC06E06E2252
+:103B00007D6D9027E1E071F2C55CFF2DE4FAD19B59
+:103B1000C1E2BD05CD1E8BFF49F8FD7F85BCFFA22C
+:103B2000BA43EB3A40C8860DBB4A43BFB5E8AABDCD
+:103B300035282E6DF655936E3DDFBFD0663FD9ED2B
+:103B4000AC1A7917E6E9E6DBE21AC67E2ECC13EE54
+:103B500039B08F7FBEE31AFD411E16C837E3FE174A
+:103B6000BC6F98B62F92134288E2291FCEE7507897
+:103B70000A6E21FAAE34747C395FF761788B5D810F
+:103B8000789BC7DFE57BD9BD5DF975525C2B86F369
+:103B90000E7D680F2C5A45E78376F819CC8331EAFD
+:103BA0006767F5F5C3BEE78E0681F9A53182768D8C
+:103BB000B1CE3BBCEC5C61D3E5425C84F6D1121C17
+:103BC0001FE12A195A5F8AA7E30C4F2CCFF0DA7A4B
+:103BD000EBF9C7269BFD62D0C342DBFB010FDB176D
+:103BE00037F8E083D96F4E1A47E1582DF4D6674C69
+:103BF00038777D69E20FC719E043F87D0C4B7D01F2
+:103C0000FE38A0FC50057E7F3E6BE0014249B229A0
+:103C100083C4EA28F1FDD433788940CB4B363FDDAD
+:103C2000D95D04C7BA079F0423CFD5B56F7EBDA960
+:103C3000ECB93B81E5001F07B616D97A9BEE83A14C
+:103C4000A8DB0979F360E7EA649B04B9B6A2BA2D50
+:103C5000543CD42E1BDA09A3B40B936D729A765E92
+:103C6000A31D45D746B8EF89CFCBC3BF8B1C1EF32E
+:103C7000F832E04DD5BC78BE7181AC425EC65F0BB8
+:103C8000C798B3CD3B42B639260C6F47C16E33E0BF
+:103C900017D3C31F87EFE6F11DA3C0FFB7C6C7D96F
+:103CA000FA73F2EFE70D1FADBE61CCC8F305B81C87
+:103CB000780F91E6154DFD6CEDFF14E3E2F20D0473
+:103CC000CF2FCA0E5D85FDBC72F5DBE8DFCB5975E1
+:103CD0002AD8019B6819EC804D7DBD18FF2E2FBDA1
+:103CE000B71B88BE3CE121200FA610356B0FED7786
+:103CF0008A2AC3892B225F7E4884783AB98660DE9F
+:103D00004866BF87DD1B547CE9C3E06F656529B851
+:103D10009F919135E36166F4B238B3017F46CDD10E
+:103D20005A88BFCB4D2424005C429CD400935D4450
+:103D3000707FC3A3EFBB0DCE1B1099E927BC3B07D7
+:103D4000F42A8FB78F652443BA9D6A13E6AFBC2867
+:103D5000631C6B2C5C0D4689B2BC3C7B1BC0531EA4
+:103D6000A11D08003F8B974D8988A104EDBFF22467
+:103D70006B47FE839D2BA1BEC99267BC437835E497
+:103D8000CA581E870F2EB5C6A9C9209D336D5FF98D
+:103D90001F8B1E8538C59861F29BF9ED1E0E67E6F4
+:103DA000491286FE030D56BDE1E179D71EDBBD3217
+:103DB000953E87F53E68BBFFF0AD30EA0117092953
+:103DC0004EB42F96A2DD60F8253BA022D8E34584AF
+:103DD000E5E7DBDBCF60ED4990F9292E0F51944ADE
+:103DE000FA7D8547C77C43172D533C0A4EA2E4D188
+:103DF000F7F9228BB7B4094486F2D07809CC337036
+:103E0000295FEA00FBE580321DEF4B33FCEA763593
+:103E1000847910A4ACD662371BF95EEB2B4AC6C27C
+:103E2000F7CC31A9B8930A74B93EB714ED687FCEC8
+:103E3000C0DF839CFD6CB37F81723995A39087713D
+:103E400029E523AF7B636C0E1DF77401D14CF69905
+:103E50004B8E629CCD757A9CE57DA2D57ABE5AF7D1
+:103E60008A75304E9197F1610D513BA05D0DB19E69
+:103E7000A3769DCEB3D8EB43FD175ADE27A85D632A
+:103E8000BEF767E4FE33885666EE7FC208FD4FB288
+:103E9000F5AFA6ED7FA8DF1C4BBF9D328BBFC602DE
+:103EA0009EB4F750567B6B4BBCD523EF0F5479591A
+:103EB0005CB32B18C5FD815A42199FD2CB155F1CEC
+:103EC00097D8F95E82F61B29B4EE0FD4723A162900
+:103ED00065001D5F215BEF339E4BECF71B5BEDA292
+:103EE0003720B845F125FAAA92B84FF0A957033FF9
+:103EF0006C24BB39D94A303E3D3763E066D807BFF2
+:103F000066CB7867E72CCC67467FFEEFB7542DE091
+:103F1000F781B2BCE680887809D78EC5F35B463F4F
+:103F20006127990872312CB23C08FCA1E32773F396
+:103F3000310FD13EAEFDFC7B932ECC2D35CD2B0920
+:103F40007985E6F1E615EC924CF308BB48358EC74F
+:103F5000EDDDD478632E6CBC233C9E658CD7B4C059
+:103F60003ABF26A78AF36BE27C6C8C7704E697064F
+:103F7000BF671D8FE74DA6C6BBD23ABF26978AF30F
+:103F80006BE2F7EFA6C61B7361E319719D2E6734D0
+:103F90000A7438527CC788EB5CEF7AD212D721E4DE
+:103FA000C97935A5846C1398FCD8E9ADD90874F1AA
+:103FB00051C3FA32D42BDCBEC67B56A93E5E2833F1
+:103FC000781B0BBDF136131EE1BC8D3E19CE49287E
+:103FD0004477B173133A9EA308E2F3216AAFEB98DA
+:103FE0005F5286DF1F6B0D617977EB2C7C1AFD9495
+:103FF000CD62F7815D3447486BB7BFEE65FEECB626
+:104000003CF586AF817EABF1B07CDF599711DD6462
+:104010004753C3FA009C9FEBB99E54808E9CB49D7D
+:10402000C11DA81B1387F5F7541C4AB6421C5476D1
+:104030006898EFAAA5FFFB0647BC4CDFB85CAC3D17
+:10404000B98CDD8BDA983A17D480F9478D0BB330F1
+:104050001F61D162DDA752BC2D1684D74AB9BE8339
+:10406000F350D7F1A5B6FB0B01D03C74BD02BA14D6
+:10407000877BE3AE2B7C798940FB0DFBAE453F236C
+:104080004C1B66D37EAEE3FAB6E6988B403C82CCFE
+:1040900077A2FC5ABCD8EA176C732754B073B65594
+:1040A00004481B6DB7A8C1FADDE5627C15B6DD0BCF
+:1040B000D378967B628C7C5B3B7EEC71D397BCFCA7
+:1040C0009E181E1F3D45CAF1DCB991976B6F6FC4F6
+:1040D000413700AF835C7532F9309C0F183C7FE4A8
+:1040E000727047EB9B184733E0CB97E302C8FB8223
+:1040F000E6372D79EF14B168541BFB0444DA538181
+:104100007AD8369F1DC29EBCD1EE89CA27F2EF072E
+:10411000CAF8DF331086CFFBBD61F39EF34A29490D
+:10412000C73F2C1EDC78580AB569437831F0F0BFE0
+:10413000CD47F773BCBF32EFE32AE607165AFE6E8F
+:1041400080717EEBDA545926B2899E17AE70EACCA4
+:104150005F1D2C07BA3C7A794688FDFD0B6E07255A
+:104160007E2D821DF4D7F7AF1759F29A79BF23AD90
+:10417000973D9FD2740E99A4F68D20FFA52D14446F
+:104180007B609D88FB1FF951968F07DF8F5BED5693
+:104190004B3E5E7BFFE302C40D1F80FC44D339BB62
+:1041A00082E63EA113ECBBB6388B4324683D0A7708
+:1041B000617342E8281FCAFBB2CBF5C255D67CC159
+:1041C000CE398BD53D1AE4D5D4F6C285609BB6B303
+:1041D0003897513F15EFE2E7511D244AE0FC85E492
+:1041E00065F1E620BFAFE36CF9BB9F8831B5B81825
+:1041F000F276E34A0D5DB7077322753E885F062AA3
+:10420000A3BB803EE510E6792F6DB9330C714235C2
+:10421000277D1C7C29B70F16FA585CE52D47A208AC
+:10422000E2E6C99CDA85BEEA34F55BBE85FDCD1DAC
+:10423000E11EFA66DECF03627A79B08C7FFFF26A04
+:1042400011EF1772131F9E577597F6CE027C3CB084
+:10425000664728DD39CB196A246286C75DCAEE0736
+:1042600020A46F36CC73D3E70FF63D4DE79DFDB923
+:1042700017E56CB6C4FA35B56FF6E50E6FFFFCA70F
+:10428000EC1CF2F3FCBE75424AAF04BFB1275526C1
+:1042900031B88FBD278B976302FB9E2AFFFB02F884
+:1042A0007B4A3D40A394F8FEE8FBE54688C3F60848
+:1042B0008413EB2B0B206EDFC3EF773F0CDF69FB22
+:1042C000B957BFFFF056D007339CE86FF6707BC735
+:1042D00080EF031FCBFBF9C0C7F87D247CDECDF156
+:1042E000E9057C06CE0B9F77A7C3C755017D33BC7C
+:1042F0007743260805C1FDB9720BE45BFF6B2B0900
+:104300007F8DCEE181D0BEC7E14C116D7F6FBAF6D3
+:104310003FCED1EF8375F2AE3E8EF3F3957A4380B4
+:104320008A4D3309F693068E07D2F563AC6B288B62
+:10433000C93977267B6673FB5272258390BFA056DE
+:10434000DD7FB34AF97E63717249BA38F1E37E6664
+:10435000F7678D10174F70FC5E991D7E12E0EE50CE
+:10436000EF457FCF299030D4DF346B8008A676FFED
+:10437000E567F8A670FF10E076CE66F756FB28DEFC
+:104380002141CE57C5E0DFA41D2590FFEE0B1EC5D1
+:10439000BC565FD500F23B8AC27C4657E00F2ADC50
+:1043A0007E4BF8FE7B01D04DB664D0DD37BB806E0E
+:1043B000A4A1F29550DE95CDDAFF3FFF37BBC05F79
+:1043C000DCE9A46D400EE63BD1BEB1CFEF250EAFC8
+:1043D000ACEA3F87F90DC3A76BE0E1ADB47DCF44F4
+:1043E000767FCB5C31B9E4AB4097577BD13EA3EFEE
+:1043F0009798EF1F3BCDE9ED34F7E77B3E55F0BBD7
+:104400007D3D46A2D7810BA7D78111E8F5988D5E37
+:104410003F26E9E9F59D74F283D2EBBBD0DE8E171F
+:104420007B5922FA76D857963F5BB01BFA93BF347C
+:1044300067FBD3F4297DB62586AB19122CE7998743
+:10444000E47DE4135FEED03D03C6DF2DFA27208420
+:10445000DC34FDCE9CB11DE4D839F42BFAD3F49BA7
+:10446000F43178E75EED8DA4BB376E8F9FE5C7FF13
+:10447000C8CFEA8DC4376FF9597ECA487C73D09F84
+:10448000E29B6C80E36C7CF311AF4FD721DF7F4E52
+:104490007CF36D7CBA4B19DFE0FC2F1DCE3724B6C0
+:1044A000AC0BE4F1C662C61797DCB306F922C54728
+:1044B000B156FC2E0D95517E1B7CF4E93DAD58DFC5
+:1044C000DEDE3FC23D819529FE0F57C03CF44BD440
+:1044D0000E763E6900CFE1EE2283FD2ECC13667985
+:1044E000B99E584C67E64192C07D1297723CEC042D
+:1044F0001F0DFCA0193C9E2527C922DF707EF655B2
+:1045000025AACCF7BE1CE1ED3D99E11A187F1719D9
+:10451000C0FB9A465AA7051CDE33D9FA027F1A3A25
+:104520003F9B1E5AE967E7E556F27EB23F57A2600D
+:104530009FDAF97DEE9A9FBCFBD828FD34F3F61183
+:104540000EFF05F07FC49F867F29FF2F83F726FE8D
+:10455000AF124AD2F27FB33FBDBEBAC9FFB7E5F78B
+:104560006FA6E3CB463FE3F7B3E17BBF9FE9FDFDD9
+:104570001C4F178AEFFB79FB7B2E1CDFF78C80EF3B
+:10458000ADE788EFFBD3B5A7F8FE173FCAFFBD081C
+:10459000BF4FF362BCBC7B26D92794A485E3BBE65E
+:1045A0007E148DF54379EA6381D2FDDCCFBA43E90D
+:1045B000EE45A2ED1E4BD76E815F3592CFD7E1FD60
+:1045C0005F5FF2E2BE02D58F4FFC8DE9E047E9E87C
+:1045D00060AEC8E490E2BFAC0BF4FD5FD1FF817424
+:1045E000FDDFC5E5FAD9EC82D786EC825FF8AB87B0
+:1045F000CBBF5DFC7CB2AC46927E8CDB0F5C05F2DF
+:104600006AE71DD902C4BB0AF584007EC2CFB91E79
+:10461000BB022E0DAA1E6AB7534E08F0773A7646B3
+:104620005501CE4B99FAFBCFD1FAB3C341E1FBADB3
+:104630001FE59DFE3B782EE0F33B5F3BA93F5BFF10
+:10464000BD1FF54FF81D78EA93AD72DB988718EE21
+:104650006579B6B3D2FF5DCB9FFB64AEC7C227CDF1
+:10466000F2FFDD145DB1FECE57FF50F83EF333BDCF
+:10467000F2453AF8EC78391B9C17F965434F39330A
+:10468000D3E8297B7F869F6DAC135C8B618EFBE446
+:1046900064A6F47736F4E7ED14F11C552397278DC3
+:1046A000B3B2B8DDAE7AA0FF07781CFE8155F7D60D
+:1046B000C0BEFAAEBBD40A40417E33D37BDAAA71C6
+:1046C000185F2DCA142CF933C633D5DED97711FC07
+:1046D000BD083A6E318C7BC51C9200BF3113EC06CD
+:1046E0008C57A8F8778DB35DBD4188CF6E127A974D
+:1046F0002C07BD7A95979D8B092E3ECB7D991B2C5F
+:10470000744B825567A9DF86F5D58C5EBC3FE59C6E
+:10471000EBBB7AD3DA59B599A2E14F5C9E593D0AB9
+:104720005E83018C7B19F81D3E0E5BBF9A705400AE
+:104730007CFBAA041552EF7C944EC05E124B9398FA
+:1047400037754D15A31742FD92D1EF5FD968C0159B
+:104750001E75BDCF112EA3DEC8E3F17AB6F316A9FC
+:10476000BF3FE665720C2BD2F2878773D2EE2B180F
+:10477000CFAE5655872B923F54B54CFCBB1DA9BC00
+:10478000EF507091EF7FBEDED0BCE22C3E6AAB9F53
+:10479000BA7F24A8A0FD877FD7C344479B3299DF07
+:1047A000EACC0A7F2B13E56508EF9FA5E518AC0757
+:1047B0005168D987E50DF85D4D953BB01C64F589CE
+:1047C000AA9E13DE69BBCDD84E4EF5D383656F6AC2
+:1047D000DCAD386E2055DE86E54256FF5CC71976A3
+:1047E000FF4A52C2F97F2CEB99B06F7A7DCB5731DB
+:1047F000BE7443CB4DF8EC6E556B204E67DC4372B4
+:10480000FD0D5F55C19FBEE1EBF7E1BEBED1FF429A
+:10481000F03B80FF35B91EEC2567B1187EC43BC460
+:104820007F43707460B95166F7FC2F9C75B2A7C3C3
+:1048300014BF53E0EFA5437E8D66BA07830CC9C34E
+:10484000EF09FAD399E741CFC3E749C8214ABF1F0F
+:104850007B4BE331A4E75A351DDF18F31DA97F63B5
+:10486000BE23C91B036F297A2AE57F5FD716BF7461
+:104870004FACC3FC9F850287D3C7EF8BE4F51AE9E1
+:10488000387BCB912E34A0DB46EEDFD9F58331EEB9
+:10489000F784C8EB801F8813DF55391CBFE78A37C0
+:1048A000A3FFB19118817BB93CE504F7C5023E63D3
+:1048B0005F9DC9B56F7B8D720C934BC2A5BD28E778
+:1048C000DC9A21F7989E5433FA74B1828EB3F5CCFA
+:1048D00095C18B200F3412848B0869F905B8E7392C
+:1048E0005B6265123BF3C2A142D007EAC54288D29F
+:1048F00043C7E72F1C2E22ECE822FEFDF4CF5F40D9
+:10490000FBC228C385BD65B4EC4995752548CB2508
+:10491000A9720CCA3BB9DD7766EBE72F74A03E0B9A
+:104920007F6696AB355CAE9EAF3CFDFFDA45D4E9C1
+:1049300000800000000000001F8B08000000000045
+:10494000000BE57D0B7854D5B5F03E73E6956426F3
+:1049500099BC278190131E12157012480848DB0974
+:10496000AF862B8FC1074609304978846700AD4E6A
+:104970009596810082628DAD0FBC2A0E16BDB6D50C
+:10498000DE68E92D7F8BFC83A0424B3156AB684536
+:10499000A350A56A4D04B98E56CBBFD6DA7B67CE3D
+:1049A000399909A1DAFFEFFF5DF874B3CFD9673FFA
+:1049B000D67BAFB5F69EB367E1CFB7183B6B2A192C
+:1049C0000B3396CBD80E6D8367FC28A879ADBE213A
+:1049D0001A635BF05541BCDD051E3B63158C3D98A9
+:1049E000197479A09CBEA6CBEA8476CE921C77D0AF
+:1049F000C558B1F79370357C5F3C8E310DBF1D9C5F
+:104A0000C5D818E8D77BBD62CF817218F3288CDE39
+:104A1000ADF740FB1C3763ED50326B84B1618CDD28
+:104A2000E59275980F9481D208EB80E7A91A7F6F01
+:104A3000C13A3C571D6C651BD4D34A993F02758F10
+:104A400083CD0BE0F81E0BAD63844715A542F3CD73
+:104A5000F06E601AB477D658FC112833B074E9D7D9
+:104A6000BF81DA8DF058A994F0989213BCC8837076
+:104A700061ACA60DE7C5A281525847EA853959B7FE
+:104A800042ADBAD47A3D83211F5ACB02F36D8C55C7
+:104A90007A0229081757594E6A7018D5CBF07BD780
+:104AA000464B98015CAA993BA294C4E102334F0D96
+:104AB000B893E3E395B5C1C0445BCFF7B29C758D65
+:104AC0001AD0AF439613110E308F8F6AFF7C0F2ED2
+:104AD00067B9B3CBCE06023E07DF19602AAE47A303
+:104AE000F7CE5D33A3FDE0FD8ADDAB18CE777D5AAE
+:104AF000FA38C4A379DC57BEB8D71380F7299F3999
+:104B0000026D09C65B22E0FCF2DA5AFA0EBAD7ACA3
+:104B1000798CCDC3A50C6484D00E27964C39EBA0BC
+:104B2000E5BD3C18DECF659C18AE0CD44F6300D7B2
+:104B3000865A95A925F85D777B7616EA733BEAA736
+:104B4000B2115009D94EE07327FC3D0BFD0659E622
+:104B5000640F3CAE0FF3E7D41EFE5BC07C9373E1A1
+:104B6000BBC6CDA6E76F4CF90B4BC7F7D6131DA5F7
+:104B7000F1FEAFAEAD0F4C14ED4ED3FF23B49E2B20
+:104B800035E647BC5DE94B8B8461895705AE094C1E
+:104B90002C8DF7F7EA97EA3C848B191EBFEA86470B
+:104BA000203071484F78340414BB473B375CFA0A15
+:104BB000877A6BD9E45CAD271CCCEB0788DD8E705F
+:104BC0005E0070BEB524393CA01DE1E3D56BA01D8D
+:104BD0002C65B23AD566013834CE54984321F8A6F4
+:104BE000B341D8CE3F75926EBE66389AE1D5F8349F
+:104BF000F345A1DFC6BBDD3EA070F607099F280084
+:104C0000AD12E4096FAA5FE73B387F0FFCC5755E04
+:104C10005E55F66C0ECC23B841F131BEDE77F4EB75
+:104C20006B60818CA842EB7E2709DEDFD1AFD33CDD
+:104C30003FF3FC53505881FC0BBD51F28303BA760D
+:104C4000CC1A1D1618CED8E31E77CEBB69501FC1F3
+:104C50007C6781AFCEB0711923F1FDE01CE26F33A8
+:104C60005D7CBA56FBC1019B9ECF399DCD0BCDEC2F
+:104C70001E17FB5758B0BBEE013807AE516FBF0A85
+:104C8000FEFDCAC1EC8DF86CB557D54E6423BC60EF
+:104C9000BD842F3F6392BE1896E17D2AC06F2673B4
+:104CA0006A2EE8E75B20A4CEC25AA6FB5334976E67
+:104CB0001DA75A951A94A380BC8C2B87C7D76B9ECF
+:104CC000F76AAF9DC6037AFC444F8F66B8BC523B6F
+:104CD0002803E5C80B71B88C381FB84C42660678BB
+:104CE00078B25954013C7729CEC8C330A7BAD0CD89
+:104CF000818923112E2C6C07D179C25342F251AE17
+:104D0000DBC6E49F950CE5699D9D05715D6FD858E4
+:104D1000ED932E2CA345E53AB9F55E76F50994D3CB
+:104D2000B25E17FA3EF50F84487428E979AED315C0
+:104D300055391D7ED84D3724CFEA3CEF5E4C786262
+:104D400067619D6AC6320DD7ADA6A58F60198C6DBF
+:104D5000C626B04E7B66A00BE5BF9A362082F4973C
+:104D60007ACD8F37733CFEA866960E8F290B7E1185
+:104D7000A6CEB52C03FCD304FEAA05FE524A9D66BE
+:104D8000FC31E4D370298B3CA2081040FDD4607F35
+:104D900004F93699DE90F84C29B57EDEA1A76BD6D2
+:104DA0004AF097786407467521BF06BD56762BBD3D
+:104DB0002F25F8043D123E5D36D427F342B653FA50
+:104DC0007E8205F323EBF0BB2D0E1F3E6BB068799E
+:104DD000D80EE0E4413DCE4A7D3EE41F1686EF2426
+:104DE0003D215CD198D0F5DF016B2828C7FE407AC1
+:104DF000E2779B75E30CEC396E375F99FB357DA745
+:104E0000AA603F901DE1F3F974F2BB2493DB0FA776
+:104E1000BCA3DA2C0393C3AFC199EDB766C7EBEF20
+:104E200014386B2309F480EC4FEAF32C35E8B5E035
+:104E3000DAC23B0F1E18877AD873114832769BED81
+:104E4000A183078B1892086385F8BF870EFA5D640B
+:104E500077883A1026CC7F476A77DDEFF4427D6091
+:104E6000773D8CF5ED301C1B0B764BE6430737C0C6
+:104E7000F79F1E7390FE3A55931A41E6C90E4D6096
+:104E8000C761DE5630733280D4A00863E90CF5A305
+:104E9000F52856801CC03B5BF32908EFCB3335A2C5
+:104EA00007ABC6A26E985CB6D5A720BC7E68674DDE
+:104EB000426E5C385367BF5C9EC9ED0E398EC3C924
+:104EC000C229E5F17E19F3AD433D629DCA48AF00AA
+:104ED0009F93DD26F95BF6333793EBCF6EFE3C37BD
+:104EE0003FCFCD4CC0CF872D2BDFFA1EDAB3BF5595
+:104EF000D923B09439DEEFD2F359A1462AAF092D58
+:104F0000A6B2498CF767166CC27EDA6B5F9A732380
+:104F1000D06FF32E870FD5F2F21BFEF2830A0DE15C
+:104F20000478C7EF1634DE5D01EFED432C64CF6EDD
+:104F30002E62B5484FF6750AD9475B347BCD2E28D3
+:104F4000EFCDA8BE2733373EAF7B3326529DD568C1
+:104F500016A4F3D54E4EE79F1EBBC5DB8076A5CBCE
+:104F600045FC625F57728705EAEC10CC9BA1FC60A0
+:104F70006467A80E5E6ECEB4123D6D16F415167001
+:104F800077C610C99CAE57C2F84E6B98A19DED8CA8
+:104F900059E9B95D81F925A053D99F33064C3A12DE
+:104FA000C7337F6FA7E7B82EFC5ECD6606BBE7CEA2
+:104FB0004C6E37DFD93D8F343E8F6C733FE9FCB9BF
+:104FC000E03FF33C3EF04CB81BE17F6F86FF9E4C08
+:104FD000B2C33B6C28CFE7BA7E7B5419D11779DC7A
+:104FE000A1A03C9EFE85122D06F8A554AB91F52597
+:104FF000A8D73CD346011DB06A9B0FE1D93E38C704
+:105000003D5037FE6302FF2F5A3D6E9C676012D8F9
+:10501000D544DF2CF74AEC67526325977F6070E92F
+:10502000F4EC8BDACECD0351FE866DB45F9AE70CBB
+:1050300047707E3ABB4D39CBE5B266AD8CDB7FF372
+:1050400026AAFE94F49EF61D6C430E90FD2765790A
+:1050500018EAF0DD9BA2FAD6C4D357E1323A98C7DA
+:105060003E506F0FE26EA912ED1BFE675EC868F737
+:1050700099EDC286AAB2E7000D009748CD28A4B3E7
+:105080000B2D44677DB59701D39C5E26B578705F84
+:10509000F5A09013D3271E9F887263069856D8EF09
+:1050A0008C89AA270AADB7862CCC0F133FE2572371
+:1050B0000AACED4869C7A16F21DCAA6C1AE9AD52B0
+:1050C00076FB1539F87EA407E11C107608B4E7FAE0
+:1050D000CDEB8C0C8167EDFEE3AE461DDD1DA93ADC
+:1050E0007E21EE5740EE3525A227C6D6D1BC0EDC78
+:1050F000944AFDBC75971271C0FC27A95FFC7E34F1
+:10510000DAB3DFB3F91C1A2DCB82789DEA6362E330
+:10511000EA774DD2D901C759A092ECCAB263D50E35
+:10512000B45F372AC4A712FEF342467B33B812ECB1
+:1051300032ADA77D0A9DD9919EFB6A9F9AEDABCFB8
+:1051400033C1AE023A67E5AC5C6F5725D353D2AE9C
+:10515000B232BF92457AA8C38A7A773A3C4824078C
+:10516000AECD5008AF93D40F093FA7AA540DE175F7
+:1051700024F4BE0BF7E347BE50F93ED89F6BB0E373
+:10518000F2B3B85F60BB1D0C32F86E7BA133B20E78
+:10519000BADA77D345F91D841FEDDE7188C7DFDAEF
+:1051A000480E279BAF3BA4B2C14098D3420A951248
+:1051B0007FC5A11466D5E987629678FEA5597CFE65
+:1051C000B96B9845837133C3CC9F687F2CDBC1BE1C
+:1051D00078B29551FB6826CC6FC5600BD1A7DC1F58
+:1051E000A7D8C2FE7EB07EDB9E5561DC2717C3FCCC
+:1051F000701E1ACC0FF56549288DEA0343D9540E69
+:105200000A65523938D48FDE0F090DA2F282500997
+:105210003D1F1ABA98EAA5A191545E182AA3F2A2DA
+:10522000D0A5545E0C7A13DB0D0B5553393C741921
+:105230003D1F11BA82CA4B4233A9F48566D3FBB233
+:10524000502395E5A17A7A3E32B494EAA342D7512D
+:10525000BD22B48ACACAD0CD548E0EB55059155A43
+:1052600047EDC6846EA3FAD8D08FA8BC34742795B6
+:10527000E342F7D37B69B7A40A7EBC4D9BEF417F25
+:105280000750B886749C8CEF1665713DF042A67F7E
+:10529000465645BC9DDD027ADCD5B35D6316D76307
+:1052A0009988D704FDCDCDE2F2F923DF3BF70C65F9
+:1052B00071BC6DF1F6EECF60A589F71B71F9C0D70F
+:1052C000373D4BA372BBB5DDAF22FDAE64BE303CB3
+:1052D0009A36EA4505E5CB0ECD5A93C8BEBB37CB0F
+:1052E00046DF3D98195C81EB4C2B397100E5C98C88
+:1052F000B0E7F7E3915E86E5FC763CF457BCC1422B
+:10530000DB7D8D79F6A17F4D9BC8482E4ABF12D810
+:1053100075067D7A87800B636D0707123F0D2EE7B8
+:10532000FAA7630AF297FDA681B47FDF6E8F2A5633
+:10533000B46F5633A6B7FFB76F6A7814DFC7FBB3F5
+:10534000D33C8B37B367D0C42E69D5C6A740396824
+:105350009BFF9914F8644824383E15EA431F0B3F1D
+:1053600083E5856D91F169505EBC3BFA0C6EE38676
+:10537000473BC6BBA07EC941B61FD9BFAC5D9BE011
+:1053800086FAC8A3FEFD4006ACA22338215DC3F90E
+:10539000445AD2613EDBDF04430FEA551FB6AAB080
+:1053A0001D8AE31FEC38B4DF245EDCA3DA2766C372
+:1053B0003FFB5FEF2953F17B6B474AE6B09EF8D97C
+:1053C00081EBC675821E7904D6D5DF1F553C3A3A6B
+:1053D000F98DE067C0C34328E7A45F72C7862CF24B
+:1053E0004BEE48F554E3905D9398E7610DE9D84A98
+:1053F00070B26F1C48FE384977005F833D7B87A001
+:10540000BBEDDDF66E62F8FE46C8BF7F15F8FE5BA9
+:1054100016E78764F07522AD8C39371F1F167C099B
+:105420007C7C50CFC7E6761F0B3899E1BCC3C20E17
+:1054300082AE8271814E395F31F4A37D28E8FB5C36
+:10544000707DF75F8C6EF70B39910CAE4CCB213928
+:1054500009F47A21FAC792C91BBBD8CF98DFFFADF8
+:10546000A79CE37E5B0FC8B941C9E5DCF302DF49C5
+:10547000E597903376937FC799CDF9A6D213B0679D
+:105480005724F0537B730C7EEAA9AAA71AE50D1BDB
+:10549000CAC88E4E1B1609E33EA538AC95ABD80C96
+:1054A0008532C2B1B094FC0F2560675801FFD0551A
+:1054B000144BA7E6B134A0FF5DF29BA7DEABE73744
+:1054C000A9EFE3FC28E9226BC7ADDC2FA9CD04FBD3
+:1054D000E5DBD9C2AFDFDD0FF7836CFA6EE18E5BDF
+:1054E00075727087D74B75D93E19FD2E10EF776C0A
+:1054F000584FF0748E4B6C375467F3B8C2767B9775
+:105500001FE93CFC4DE6417B2673C33B249F32419F
+:105510003E29249FF8F8FD43A98F86A1EECFCE1334
+:105520007E004FEA2CF7FF3B7ACE459B0AE5D43844
+:10553000CF3E15E334A08734E4D37130F751082F00
+:105540003BE15D631C8FDA381641BB17E016C57D61
+:105550007BD8E2263F93DDDEEA477E66F64C5A7F33
+:10556000A5273823BB17BEF0A4696588D46076DB15
+:105570001417D0DFA6124F2AD6E7407D6B158C9BFF
+:10558000D5C1447D8B6BCC3FEEF708FEE8E787364C
+:10559000C078FBB2FC73919E81AE8358FA877AACD7
+:1055A000E4AFF6F6CD1E90FC19E7274F99E4A7FA71
+:1055B00061240F9760BFB2BF64F6CDE06C2EE76E3A
+:1055C000166532FB46D2FD79DB3762BE8BB37BE7D3
+:1055D000FF570EFE68DB4EA6F33716DED36ED5D02E
+:1055E0009FC1FD3416673BF5E716FE463FFA1B8167
+:1055F0000E9C83791DFF24F21727876384E623FD21
+:105600008CD29F982EE88A599508EAF1F42A8FB532
+:1056100081FAEB6097437FDBB2B9BE917C8D72EB70
+:10562000A9612897B2ACB85F477F923B2BDE3FD68B
+:1056300033CAE3F289897DDC7562CEADEB7D19E872
+:10564000720E1FE17E94D6EF73BE9CD69F45D6A303
+:105650009CF033CD03ED5398FCE337F893A77EAE6F
+:1056600000EF821EFC5CA55219CCA26ED8EF4DF360
+:105670002951DC07DA2DCE08EAD2EA4227C3F8A680
+:105680003DDD12C1F888FD1D85D6692F4F8BA0F036
+:105690009B5858958171CCD387F7BB8209F07F75F1
+:1056A000B0DEE0FF32C3B1BBDD9C673D08C7FBCF76
+:1056B00011A77D3EBB3B4EBB0FF972FAFCAE0D76D7
+:1056C0002D1EA795F1C702EFAE2DD5A8B29671FB9E
+:1056D000B49045D6E9ED2A5D1CF477D8CFFDF138BA
+:1056E00068FB05FA386873E11EB477EFEB8E83062A
+:1056F000F712DF65B79521FDDEEFDBF5933B109EDA
+:105700000E11AF1879CCA5A19FBE627F2EAEE7F730
+:10571000A6F9CB52FAF1CCFBE03F651BE30BA77D6A
+:1057200057644489B6B213F2B7F42FCAFD30FA0FAA
+:105730003D09F9D0086F397E9DC2F7B5CCA670F946
+:1057400027F428C897BF921C8830D29B7E87F230FE
+:10575000EA9BD3BE913E8A7B269137723E00C721D9
+:1057600089E2BF305EC238AB2387EBA93A1BF79BB7
+:105770002AAB2A56E2BCEADC2EC5A1F3F79F16FA43
+:10578000CC1C175233BEA8080ABF77A2F59BE33B97
+:10579000A7515FE47278E9FDE4E782D7515B2BC53E
+:1057A0000F8F2E50D93AEC27383A9F25F85E96AFE6
+:1057B00023DD0C61EC18C2B84287CF24F1A2A36BA1
+:1057C0009B28CE6C8EA775BFAF4FA945FD5D8B7032
+:1057D000D48D5B25E0375394CC11D43CF0DEDE70E1
+:1057E000B78761FC6BC827156137FAC5BA7E89F1A6
+:1057F0000BF63D37F92B6AEBCF54AC1BAE83671524
+:10580000E3F1D9FDF77934785E3B64436ED8951C9B
+:105810008E3373381C6FC30763C81F333287FB375F
+:10582000FBE48F61C3785C88ED4FA1F869CA1F550E
+:105830001FDA0D382ED703DC9F7CBD889B98E37858
+:10584000B5A11506F9921653584417BF48B3B6913F
+:105850007F362D66A5E7667ECBCD31F29B847F3205
+:105860007C4AF89B9FFB72F87A8ED62FD6D06F6851
+:105870004F4D6C07DF22DAC9BA391F2159DC7DBED2
+:10588000C0EBE9E0987CF457D5DAC343FAC2E712DB
+:105890003EE7CA739893C3F5B8FB9A97441C4FDD53
+:1058A00080BD49BD9A66ED3D1EEB37C563D346F515
+:1058B00088E7FD53E2B1EB7284DFF03CE3B15304BF
+:1058C000DD9E2B0FE56ABBD1EE91E52C81C7D3C1DC
+:1058D000141606F9785DB54A7128A00FD28F47EFEC
+:1058E00056C8DE8CD63B482F37D6A7907FB6B14C32
+:1058F000A5F78DB7ABA43FA3201F96817CF8BD9080
+:105900001366FF6C35530CF1F3E9A3520CF56B16DB
+:10591000FCE8F76BD1BF5C65D370BC231AF73787FF
+:10592000FD2AD9AFD0872F8AFEE9BBBEE1437D2691
+:10593000E9E1885F257E0BBFACFA70D876E18F3E37
+:10594000B2B92C82792A4C89C7E9B541D87F23C5E1
+:10595000815FF36EA33867CA97F70602B47F0C6ABB
+:1059600065A43779FC3445F0E984C2AA59A8C7DF99
+:10597000DA6A63E8377A6BCD69E2E78EB52B292FB7
+:1059800042FA97A57FD8EC6736FB977BF8954DFEDA
+:10599000E464F90CCF26A10F29AF92D10788ADC3DB
+:1059A000FF881C93F2E375B1CE0985DB6E5F07704B
+:1059B000489BAF121C245DBEF6C52D0FA21C4E01E4
+:1059C000FA58CF109EFFF12CEE43D86225A11FD9C3
+:1059D0002DE53AE64F94C6F1724D7071771DD97F6F
+:1059E00076D32A43DE8759AF24976BBDCBAD3B728C
+:1059F000B8BFC2AC77CCFCF075EB9DDAFABB4BF1CB
+:105A0000FBDAFA05112CB7143A9B50FE9AE583593C
+:105A10004FCC32C9D9B87E505964A47EDE1AB58BFA
+:105A2000EB093BBDFF3485E73B849CBCBC3135FDB5
+:105A3000612C3F4DE1F90E61340AD14E7D332DD2F8
+:105A400042FBF295A3914E42CCD711C6757A53C949
+:105A50008FD0DA9FB753A7A472BBFC4035AD5795E2
+:105A600086F9866AE29B16B19607B28345B980E74C
+:105A700016BF2505E30B13DCD643E87A691D6F6179
+:105A80000E1687573C2F847914F89EDE29B8FF2C18
+:105A900073DA07919D3A2417F1F17DD81F02DD1FBB
+:105AA0003EACEEDA014B3DEC1B9991C84EEFD603AC
+:105AB000A638F2B1EFBC3A00F9F6CF2CE8CBA5F846
+:105AC00071E3ED181F6EDEAD527C69CE0DAF5D4007
+:105AD00076B7294EA9A63B4BD19FD2A2A4FA509EDD
+:105AE0004838EE73DB49CEB41C4BA3FD44CBDB8AB4
+:105AF000A8BB491E4AB81F807605A33057C94D720E
+:105B000053C21FD6E5C775493C54B3E8E171255F20
+:105B1000695D97F5BEAEFE1EB20F90CED4F83A5432
+:105B2000B795D6D7C9527D38BF90F00FB137D2683C
+:105B3000FF27F1DC2CE851E27985C073E79E333F03
+:105B4000B814DAB7FAB328EAA016318243E71B6E1D
+:105B5000A2130907B96EA08B20CE53AE7BFF9E9196
+:105B60004783F87D7A2AC5F1A5DD2DF30ECCEBAF86
+:105B700013FBF7A5B94AB7DD8BFE8BF6ECF14B733F
+:105B80002B12B417F62EC07B05C2BBDAC33E89B018
+:105B9000F83E2F597EC34DB946BEEB437EC34DB987
+:105BA000B93DC7FD0AF8DC88FDF5159FCD56D766CF
+:105BB00025230E6FB96F2696D67AF2BF99FF243E41
+:105BC000943DFB3EC338BE592EDCA8AE640A8CB3AC
+:105BD0006938E74BB68669941F64E29773C91BC0A6
+:105BE0007F04F1944CEEF415FF3FEB89FF9FF5869F
+:105BF000FFD6ECC013084F1CAA5F39ED0BFF13DB77
+:105C0000A33CB10FA4F1886EBB3219E5B3C9FC18EF
+:105C1000391F9927B317935673757938A53E05F543
+:105C2000441FE863AF7E7E5F037D1CEA9DDFA3C453
+:105C3000A7CB05FE97CBBC8C5DBDE765F4017F4724
+:105C400013E1EF46D5D7152CE93BFE8EF7C4DFF103
+:105C5000DEF1177C17F1D762679F90FD5E55EF4527
+:105C60007AA9F4F82FC77C9DBDEB84DC2901FC9553
+:105C7000A0BDA4925CFB21BB88E4F6372D169A6F79
+:105C800027C8EB87953EADF3BF73C94E095BB3A040
+:105C9000DF1BAF6014DFF36AEB14ACE76BA0A7B5B2
+:105CA000BEAF57C9EBB15E25AF777965CDCB25FA8D
+:105CB000BC1EE9D3A979ACBDC92B4FDE79CB2B4FE4
+:105CC000DED72BAFFAE59D875EED03FC87E0FC9203
+:105CD000C989BEE681029FB27E593DC7879D2EC508
+:105CE000D5AAD39D5C6F3FA9083D5E16A4BADB49D7
+:105CF000C2E280D0F3A776F1F7EAF8C476E588BC73
+:105D00002C9EAFD0B62A6035E49384E9F91DFE538A
+:105D10009EC12AE669BB683DD9D3B81F52AE5FE683
+:105D200069A78BF56417F175671FE379ED125EE9DA
+:105D300062BF91516535EC2324DC6E54030AFAD11D
+:105D4000337318A649C03E6198827EAE4CBFB1BD88
+:105D500084772EDBFAB18A295F35C6F7B9B89F1967
+:105D600081EF75CF13EC5F013FA5983F764D9EF014
+:105D70003FD89917F51153EB7AA523DDFE249847F8
+:105D80007197DEF7270BF364BCDDA8F7DA525842AF
+:105D90003FC327821FC05E217FB32AF4DCC48E126A
+:105DA000CA7759EDD6C8FFA0AA3EE7D4929EDF6716
+:105DB000FA81BD75F0C8AE49659ADEDF12C832D4EB
+:105DC000F36B0B0DED0B82030DEFFB355D64785F1C
+:105DD000B4B2DC502F0E8D35B42F01C0EAEB833600
+:105DE000FF9BA1FD90D6CB0DF5A1DBAE35B4BF3046
+:105DF000D260787FF1634B0CEF87B7AD36D42FD9E3
+:105E00007D93A17D8BF0239BE1F2AB3CBE7F6BB118
+:105E10007239B4CE554EFECD1697D1BF79A7807F8B
+:105E200075C6B852F4ABB7BC53568AF03E903E9656
+:105E3000FCECC9E8C22CD792C953F3F33631DE47E4
+:105E4000CFD82D48D72BF603DF5E0275D7EB9B70BA
+:105E50004D5B86F1F8AC8DF17C2119AF91DF77C7EE
+:105E60006BAC3EEEAF4D77B15B13D0C59D799A51C7
+:105E7000CE0AB929E92819DC243D9E0B6EBB057CAE
+:105E8000BF2ADCDE5078BEAB5E1F3C99605E1FE728
+:105E900059447C39F8873C6E0F8D4A254BDE43FC14
+:105EA00078BEFA40CE03F4C131AE0F8C79BA1FD55B
+:105EB000BEB4F05E0DDB2FE4ED2DBE52C44B327F3D
+:105EC000FAC7026E3A7F7A13F7A7A71AE0F696E4AC
+:105ED00077935FAF25FD73F2A7B7D87DA57DF1A7B6
+:105EE000BF05DF22FC77E771FAE8C6AFF0C727DB12
+:105EF0004785183B84E72198CBAAE9F74DC9F6C737
+:105F0000529EC3FEB814E3B4ADB8FF5212EA414743
+:105F10007E05ED9F491FB4821E74909F801DD2A004
+:105F20007EE3040BBB558BAF5BDAF30EE673DA55F9
+:105F3000C2AB1BBF67DF67D7A7A85FCB3ED39BDF92
+:105F4000EBBEC4AC67CF19EF233B6D1AAC7FBD6EBF
+:105F50007F2DE1638EEF49F84CF3F1F8DD46D08FE9
+:105F600018DFDB97CBF5F446D87F231C3DD901EF32
+:105F700000B4E7E1F9C3888EDC4AE21F0957739C3D
+:105F8000AFAF72676C7E0F3B6E6C7E2F769C5CFFB2
+:105F90006AB17F9EA40E6B433FE6A9989DE0A632AE
+:105FA0009E77D97CD0C62284479EBF2CF1688B6D2A
+:105FB0006A47FD6C63E67C652D03D76F3BC8CF89CC
+:105FC000B11CFE3ECC9CEBD0EEC9A832EAAF4CBF70
+:105FD000517F65D76499F499517FE5D71AF55741F8
+:105FE000D0A8BFFA35959BF499517F1587C69BF4CD
+:105FF00099517F0DDA7CB9499F19F5D7D06D46FDCF
+:106000007561C4A8BF2E7E6CB5499F19F5D725BB15
+:10601000D71BDE97456F35BC1F79F087867A45FB25
+:10602000BF1BDA2F3AF40BCAEB197DF46143BB3185
+:106030001D3F35B40380B763FEF77C420963979E2A
+:106040007CCAF07EBEB0D7BED1F56B433FAC95E7BE
+:106050007187E12FE2EB3D16B4A39162655DCFF548
+:1060600003BCAE8828BE28345BBCFBC94A9CC7076A
+:106070006F4E3988FD2CDA66CCFF5E1C31D69BD979
+:10608000C00C940BCD401711A093A59817AE936F39
+:106090004BD94A712EB06F74B6E8D0158CF249C353
+:1060A000FE76CC7B97EB94F4E617F426E727D7BB74
+:1060B00014ECBFA8165FA71FFEF2FD66871DE976E8
+:1060C000E16E85FDBBD2733D4D7BEEDCD42FC1BAB2
+:1060D000CCEB30DBA13FC937FAC727A92E8A179C22
+:1060E0007A59F5717FA3910F571FE27182D54F281E
+:1060F000E4AF33C343DAA7C9E0A286F9BEA139876A
+:1061000045223AFED3043C1C5E23FF9DC27FE07C07
+:106110001E5023986F94A2A59AE9AD32CA7AC2396B
+:10612000ADD4C8A76638BB7D8509E94A83BF388FDF
+:1061300085E2FCA199AECC705FB1FB4E3BCAC3F3C4
+:1061400085FBD1FCC47109D076A3EC09F2EB245C89
+:1061500061DFFE26CACD64FBD9F7F395F33D5FF40A
+:10616000BE5E0E7F0DFBD933BDE9B94EF4B7817D1C
+:1061700069F6B399F5B0B267FF674A3AF9B53B1CC7
+:10618000C877419F93E7C198F46469A9414F76EFBE
+:106190007BDF5168DFBB2BC36FF5C2FA0E65F86D6C
+:1061A0005EB48732FC76AFCE0E6D01B8D0B91FD089
+:1061B000534F26B013C77BA57D1420BFC9C66ADE26
+:1061C000DEDCEE222F3F27B42FB7D24BF6E7DB659C
+:1061D0005EB23FDD95BDDA9F778838D16D18871C98
+:1061E00012CF0FBA5DC46B80EDFC88B78DB68057B7
+:1061F0009F3FECF666D2BCD2C73CD58E79D42D1E1B
+:106200008B47D1B0E4F9DC1B5CD69A9DE2BB1CC382
+:10621000777C9E2AC21BE06A75593FD7D3ED782F51
+:10622000A3F7C9D639DECBED5E1B0BDE8EF6908C64
+:106230000FDBDEA976A2BC6B617E0F97933E8F3E8B
+:10624000FFC3C6783C78BC880FCBE7AAE71FCBC357
+:106250003A9211AC463C9AF3B06ECCF08FC7E7216E
+:106260006BD8817667C899785F5C23F0AA8AF5823B
+:10627000014A7445F350CF3FFE03F6E61538EE8D24
+:106280006A98F2245BDC95A54157DFFD5C73BD9CE9
+:106290006F75F6D15C3D9D9AF913ECD3CBF11C9947
+:1062A0003FA3D04ADB0EABAF14E1BD19FF3D86FC26
+:1062B000B40BF0FB1E79AFE21C2EECE37ACDE39534
+:1062C000FDECCBF22FF3F27CC3155E9E6FB841D587
+:1062D000F5937E8E7EA49FA30F7EAB35DEC4FED1E8
+:1062E00093A8DFFB0AC75BBC3DECCC5BBCBDD89977
+:1062F0009F1E1B9A81F16CE9EF32B793E722657D0F
+:1063000073A671FC4DE5BCFE4381BF3F8A7B3A1EFC
+:1063100015F3709ACE8B3AA732BAA7439E3395FDF8
+:106320003CEA7553FBB5D9E31FC5F96E2A51681FC6
+:10633000BA295331EC47EBBDD58F225E23A2FF472C
+:1063400005FDEE18C8FD39E63CCC25D8BE024BDE73
+:106350002F9E6B45396657D58470FC9997FB8B2E21
+:10636000878EB07FE9776BBC5B11FB27E3BD08C06C
+:10637000E7AFA481FC39BED546E75E17A8AE4D480D
+:106380008FC9EE39A81F16A0FCA7AF7A7E0CE19941
+:1063900096D553AFEEF776EB55DF799E23FBADF73D
+:1063A0003CE2FD1DA99C4EBBDC2EF29B9BDB9D10AD
+:1063B000F8D92AFC1A28D751BF64A96C65223D730D
+:1063C00042C8D57FFC5C33BFCF23DBE5A2EFCCE72F
+:1063D0009A3BEC1D1BF371BEDF507C787E21BFCE53
+:1063E000B32F3F07CF316AE4E3DB54C2D2ABF07D79
+:1063F0009985DE675EE9D964C3BC6F8D61E63EB303
+:10640000C1386E18C755C0E3385BC357ECCB8776ED
+:10641000195A171B388CCE7B4FF622DFD6F2FC7947
+:10642000F3FABE14FCE1DA08FB0B848796380FFD03
+:106430004B417F206FBE403AAFD6D82E7E2E8BE7E1
+:10644000C1225952BEA28FE76BA761BED3202E6F27
+:1064500048DF644DB014E4C6F94B15F0369FE7767B
+:10646000159CDF79EE197589E73BB480AFEB4F19C6
+:10647000812C1C77C6B875DC1FF6C5D9B36A251AFE
+:10648000C79C4FE07B86FE8A941C2E8753348DE494
+:1064900032F32894E7EAD47C4D584F718DF5A86803
+:1064A000273B785C92CDB730BC5F6582E8C75FCB95
+:1064B00094774BB95F96CB592B7B57D2BF2A805329
+:1064C000897A96FF01FB696B1AAC6782EB30C527AE
+:1064D0005306AFACC6730DCFCEE37DFC30C9B90116
+:1064E00079DEBDFB5C3F7BF8B0E15CFFC6070E1BAD
+:1064F000CEF5871F38FC55CEF54FBCEF81C3FFCCDE
+:1065000073FD529E1D5583476F06F85F0544152A9B
+:10651000C7D2CAEA08DF5E82DB9502CEE1CF01CEA8
+:10652000CE389CAFDA7388E077D406F386F16DE35A
+:1065300039A86D3765445A482E4668DC59CED6498D
+:10654000B8EFECB4778DC0713B9F7EB5280CF2E4B8
+:10655000D8F74EBB19D0DF5BD62E373E3FB9E625C4
+:1065600037C2EBD81A95EC353A17ADCB475A28E825
+:10657000EAD982C01CA4AB796BBFACD4DBE32C940A
+:106580004BFA777144A5D42B29FF963E9626888E28
+:10659000D797B7651BEA522F2F77243EA7FE6001DD
+:1065A00097438B1FDF61EFA7E1F8C1E60298C74967
+:1065B00091DF7072979BF661723E0D8F97D971DFF4
+:1065C000F9D61E078B921FB8DDC6C89FE59FAAE4C7
+:1065D000E13D46FC8F799ECFED4DA3FE16DCAD92DA
+:1065E000DFA91EC60A015C837B16F37DB0691D0B13
+:1065F0008E6993515E2DD8A2B0B0C6DBAFC1FB331C
+:1066000042B7501CC6BC4EB37E5994E4FE9C457BF9
+:106610006EA3EFE733FF6D68CF2E6835BF9FF21E84
+:1066200012F9A273C4737E5820F44E251B7D761098
+:10663000C58F32866BE7D63B27D772267D7FAD9319
+:10664000CA0FD77AA89C53A0111E96EEDEF75C3FC6
+:1066500062F3F64AD44BAF1C6C4CBB568BDBDD951A
+:106660003BAEDB7F3F91BC313FB34EC07DB4C8CB66
+:106670005C24CE3D541CED3D2FB30EE131A2E77CEE
+:10668000A59D5D67F2FB4ABBDB0C8F530727A42156
+:106690007DFC52C26534C045FDEA7049F6DD729555
+:1066A000DF9B667E2EF9688EA0EBF93B676E2A842D
+:1066B000F15B9E7E6F4007D129F75F54087855B88B
+:1066C00036B5E3FA2B98C96F18662F331D3D033D8D
+:1066D000A9A877CC742BE989BDCCBF770ABF463710
+:1066E000BDEEB99DE02BE90A4F3A58D0866351AF11
+:1066F000A5EADCF75C2D6835D63FB2750C4079B25F
+:10670000C8E46FF84849BC7F7BBE60202D76BEE6AA
+:106710009F8CF9170B586013F7CFF3FB714E5A5B40
+:106720009FBB19F97C27E7B3E5BF7AE2BF507E2D06
+:10673000F9CFBBD3517EFDC5DA9A87E32D7B646325
+:10674000BA1FE598359C8EDFFF25A2263C473CB852
+:106750005091F9FA2ECC535B41A406FFCD0F4F4761
+:10676000F9F9DF8FD83CE8876D7ECC1175003C5677
+:10677000ECE27084FADBBC7E0BC1AB79B7912F974A
+:10678000FCC7DD791AF903C2FD04FCFAA1085FB168
+:10679000D34679AD2B5E567D384C33EBA2F599BFCD
+:1067A000C779C4006FCD6D6ABD3DA3E77BB084ECB3
+:1067B000C86FCDBB383E9B77717C359BECD02621D2
+:1067C000B7CDF49F5328E2BA82EE013EE45793F925
+:1067D000B62CC2E577CB4FEE1DF136CCEFC39DBF93
+:1067E0004B5786C5E99F615628C0ED545BE33C7B5F
+:1067F0002FF7F57C24F8A45B2F083DA4ED8689E5EE
+:1068000043750F2F97D9A2E997025C96EDB0F9C2B4
+:10681000F078D913AADF8576D46B0EBA7F62E913BC
+:10682000CFBE3216E6B7F4495BCE54BE0C17CA6F22
+:1068300089AF66A4F3F2387E96FCE2593BE669E242
+:10684000F33559713C2D7D729F1DF33ECDF09CD0E8
+:10685000B6CFCEF9CD84AFB6B727A3DE6EF9C9A700
+:1068600076A487BFEC55587E49CFEF9B763C9B8E34
+:106870007206E184FA45E2AD1B8F3DF0179DFEEBF9
+:1068800051D4CE83719E73E1F1133C835041F4FEE9
+:10689000F35FC33C9A5E77F8100E4D3FBF2E1DD7B5
+:1068A000F39E7525A7FB0737E6A1DE6EB285F33CA4
+:1068B00054F2E74DDBBF43F4B8E8C5EFF0FB9C981A
+:1068C000BF00F919D65B80EB5CF0C055B4CE852CC7
+:1068D00048F4D8F420BFDFF08C95D524DA0F3C249F
+:1068E000F8E6BD871DB47978CFCEF87D217F50C5FD
+:1068F0007D58ABC85EF98E58334868AA9F71727C88
+:10690000AD2E94717F2EDF9A45ABE69DB7907C7BD0
+:10691000BFC89F8FFC0F7030FA675F9C942FE422F2
+:10692000DDEB42DF01FD4DC0E7D8BEDDE64F19616A
+:10693000F84EE4DFF2F1AF17E3C3BC53D1CFF75EFB
+:106940009E719F2BCB2385D2AFC6DA999ECE92C97A
+:10695000819D5B88BE3E7999CB9915919935F4BE9E
+:10696000DD16CDC7F7917D572A2427C00E49C4E70D
+:106970003B6D82CF8DEF619E56450FDFBDFCFC9EC7
+:10698000A4978577417B1D5FC7E9C71E7F5E12E72D
+:106990005799BFB1C864CFC9D22C27EE33C909F9C2
+:1069A0003D7B2037E1F988B87C0813FC96D9228F0B
+:1069B000FE3BF2F56B0E3A17B9EC091BDDEFF3C1A4
+:1069C000E3FB5FB916E8FF8336C9CF46F96BE6E70C
+:1069D000A6A7AE6289F8F9839C004BC8CFF03C2192
+:1069E0003FE7F0F306FFB7E4EFA224F2F740614F70
+:1069F000BBE352A8BEFFD3A5C5B43F33C157C2D530
+:106A00002C4F67A3B190DB539EC29F97990E9E12A5
+:106A10008E924E97FC6C398DD34DCF925E253D778B
+:106A2000D3AB79DD46789ADFDF827BA7DC38FE6D59
+:106A3000EB615F8EF1DAA755CACFEBD4BAD2B3605F
+:106A4000DC8D22BFA7D323EA99BCDE956BDF84F2ED
+:106A5000443EEF4AE1F90E9D81AEF44CDD7EE0ED5F
+:106A60003D6A3A9E07E88824CECBA08C0DF483249F
+:106A7000C9DB90E77E3B53B9BFAF3395FBF926A93D
+:106A8000AE0121DCDFB5F2F8D2FC7557A7E3FEBEFC
+:106A900073CFA019B5B81F38A4F29CA3B0DF5A0079
+:106AA000F06DE44B672759F89E7168BFEF593A15AE
+:106AB000FB99BFD5089785AE9D76ECE70C5B43E567
+:106AC000C2BB6C713A81FF9660BE16D2F903A6E78D
+:106AD0007B2E23BA5A62A2AB20D25582F32419FD31
+:106AE000045D95B132BEDF16F13121F726A9C366E8
+:106AF000D4623EE5417EDEE3D41E956DC2F53E2EA6
+:106B0000E265E15CA2D71540DF7ABFE987487743A9
+:106B100093EBF90F7F79ACF26668B2ECBFFE34E21A
+:106B20007E283FFCAFD72EF80DD67FF5EA803FB127
+:106B30009EED27ECFD6C2EE575EE75D0BDA69D7B18
+:106B40009F1F7033D67FEDA0FB453BD7F37D767852
+:106B5000AF9BF47F6711B7175B9EFE744407E92F64
+:106B60007E6FF0D87EFCBCEDA93D7F7B53C17CBE1F
+:106B70003DB02A948F62FFD6FCEB14DAA7773EFD76
+:106B8000A9617FFA55D7B3429CBBEA74B35A3C273C
+:106B9000DD99C9CFA936FF66CC8FF1DCE5F25DFB4C
+:106BA000EC8DF07EC2FFFE7204CAA1CEA7B8DD0153
+:106BB000F6F076E6033CF46BBDDD06F8FB086D44A9
+:106BC000E09937FBB54FC3F3243DE1C2E1D0097032
+:106BD000C075015C9A507E268347DDBF2C3C3E9EEB
+:106BE0008BE32FDB339AEE198EC345F1F3E76ECAC0
+:106BF000F780F5F3E77B3F1D8176D4B9D67B533F11
+:106C00007EEEE77FCA7AB7FDCBAE97D3BB864E99AF
+:106C10008A9E74DF93AE7F7503D57FEEF6D17CFB41
+:106C2000C8EFBBFF87D1F72BFFDFE2FB90C0B7DBDC
+:106C3000837199CEA7BF1CC0CE63DD67FE65F1DC12
+:106C4000FBBABBED1E8BCF390AE6F73A8B5C55AD2C
+:106C500024CF1F1DD85FFA1FF83E43DEC33D3D67BA
+:106C600021D911D3FDDC1FD3C2CA0FE239BBB05FFB
+:106C7000A5F80525EF001CDAAF2C8B509E98353C0B
+:106C8000E41ECC1B9BB5DCC7EF2B33EEBFA6E7D5CC
+:106C9000D4A03D77641DCC0BDA1D715B3C2DB08414
+:106CA000197E95EC3F28C9EEFBE3F8CB280F65462B
+:106CB00095711F72AD693F7175ADF1FD2CF6702EA7
+:106CC000E6FBCD6AB2517ED255E6FD477F0FADF3AC
+:106CD0006AB67223F7E79C1F9C2EEFCFF7633DE166
+:106CE000D03BDC7AC049EC37297748EB093747902D
+:106CF000EF3F1DF042D85B222F6F759FE0C9C4BEE5
+:106D0000D4218696F075F8F9BDA3BA7E092E12EE4D
+:106D1000E70B6F892733DC257C25DCCC781882E7EC
+:106D20003D2BE2F08F97C67BB599B01BA777DB8D23
+:106D30002E82E30B3BF9798917AA1AB79661FD7188
+:106D40007E1FFC9971239913D67BC4C676535CC809
+:106D5000EFD73C95F1FC19A5EA798A4F60FEA27E37
+:106D6000BF8AF98BFA7561FEA2BE8EF98BFAF6988E
+:106D7000BFA87F8FF98BFAF798BFA8AF63FEA2BEBA
+:106D80003DE62FEAEB98BFA86F8FF98BFA3AE62F12
+:106D9000EADB63FEA2FE3DE62FEADF63FEA2BE8EC3
+:106DA000F98BFAF698BFA87F8FF98BFAF798BFA8EE
+:106DB000AF63FEA2BE3DE62DEADF63DEA2FE3DE646
+:106DC00029EAEB989FA86FFFADD833867A35FB9DF3
+:106DD000A1FD04E74B86FA24CF9F0CEDBFED3D6E7D
+:106DE000783F45FBC0F05EE2FFB2D2D386E718FBE6
+:106DF0000857E23E86FF99E6FB9BA11F2B0B509C98
+:106E0000D4CE5652E9447F2F94A9AC8D4A17B0399D
+:106E100096EF0D0D3EDE1FE9757B781312D7913189
+:106E20009F0E40F9FFC2B82BB85F42C41766E03F1F
+:106E30003520E2B42FFAE33E57C64FD3632A8B8E38
+:106E4000043A8C29547A62692C9A0D74184BA13239
+:106E50002B964DCFB3639954E6C4FAD1F3DC5801B5
+:106E60009579B14154E6C74AA8F4C62EA6B2207659
+:106E7000219585B191F45DBF581995FD6397D2F3C3
+:106E8000A2D8182A07C426D0F3E25835955AEC3216
+:106E90002A4B6253A81C18BB82DA0D8ACDA47270EB
+:106EA0006C363D1F12BB86CA0B628D540E8DD553B6
+:106EB000591A5B4AE585B1C5545E14BB8EBEBB381A
+:106EC000B68ACA61B19BE9F9F0D877A91C116BA108
+:106ED000F292D83A2A7DB1DBA85D596C0B95E5B1E9
+:106EE0001FD1F391B13BA91C15BB9F9E57C4EEA3C4
+:106EF000B232F6632A47C776505915FB199563627B
+:106F00003FA1726CEC17F4DDA5B127A91C17FB0D8E
+:106F10003DFF46EC7F51F9CDD87E7AFEADD83E2AB2
+:106F2000FDB1DFD1F3EAD8212AC7C75EA2E7136219
+:106F30002F523931F6277A3E29F61A959363C7A95D
+:106F4000FC76EC6D2A6B621F503925F6172AFF2D4F
+:106F5000769ABEBB2CF6319553637FA3E7D3629F2D
+:106F600051D9BDFF1F97F477052C6771FFECCAEA72
+:106F7000D37D6577A6A5935C9CBE86CBC57BD33EAF
+:106F80003A4072728C437390F0DB668877D18F48F9
+:106F9000C0BE6FDF98F7FAA3BDB3A9FAF81BD7A15B
+:106FA0003E5BE560429F99E4EE172EE1EF64988F17
+:106FB0003847D0F50B55FB73D18EDA54DEB10CFD9A
+:106FC00026B79774D4615950C4ED098F28F38B7894
+:106FD0005CE9EF43B9FEAD5B3584FFBE404EDFD6C2
+:106FE000374BE8EDEEF6033C5C5FB8BA06D079BDEE
+:106FF0003EF6D3D776E7CAC3FA5BFFE0F0A2047986
+:1070000058F1F3837DEEA7F26BEAE75B7DE9E72DAC
+:1070100081F7878A02138A101E56FF087C3F7E7D07
+:10702000818ABFAB52BF55F120BD346E289B8C784E
+:107030002D677EF24BCE49924FB658E0B561A58DD3
+:10704000A17FB24163E41F6ED8C5F390D19F3A0D82
+:10705000E8A549D0CBF22D1F93DFA969E5229EF761
+:1070600014E1FE29F93B364B5B773C876EBD33EC70
+:1070700030E5C72F7DCCE8BF6A16FEA9E56DA6E70F
+:107080002BBF9DD0EF69F64B3514093FB28FE73D1A
+:1070900031B53FADFB0CAC1BF3498237B89DA83727
+:1070A000001E14879170907E4F090FD6F3DC05E522
+:1070B000AF9E3A3884F2E44E695A3EB60BA6F3DF2F
+:1070C000B352ACC1D1F81CE048F92C5DEBD2281FBB
+:1070D000EA6DD0031A265E7982A3F1FEB88ED78BB3
+:1070E00098B8BFD2188F706EA53CF17A9803E6A5C8
+:1070F000D43F924DE736A1BF11BBD1AFF9888DF2D5
+:1071000091C26CB59755F58C570436DA882E1A76ED
+:1071100067F2FCB4B0FF653C5720F1F2F68641936C
+:1071200031AFA961734919B9EB76DBC83E94715947
+:1071300089AF9EF9DB3C5FA099453661EA12E0EB2E
+:1071400044427CB5EE23BC02DE4E24C1DB89DEF076
+:10715000765F91F027FA64BEDAB08CABF1E59A6CF9
+:10716000E2E7BAF5D1212B75F469F6FFB3F963E9CB
+:10717000DE1399FF5C53287F67CC9787F83DBDB538
+:1071800082F066C657CDDF1B092FEC7537DD3B3C1F
+:1071900067109B77393C9F27FC9E735AA690FDFD94
+:1071A0005411DF17BCB016733F197B71AD93F9C151
+:1071B000F87E69AD87EA7F5CEBA5FAAB6B352A5F99
+:1071C0005B5B4AE5093BCF2B92FC058440F97DBB14
+:1071D000055FED2E92F19FEBBDE8E7AEF9FB4B1595
+:1071E00016127DC7A64F2A22BBDD902F527BA531F8
+:1071F0001FA4C326F2CDB6283EBC4FA62170A9A17C
+:107200003D2B1D19AFA3FE11F92B0D9B33E91EBBBE
+:107210006BA6661BDACFDADCCF506F2FD2F87D6A0F
+:1072200035830CCFAFADBBD850AF17BF1FC1B42A49
+:10723000E21B19FF02CDCDF1E2E16D3F59393AFF72
+:107240004618FF93C3367A6FC6C7097B98F6F3E1F9
+:10725000871D3E8CEF9DC4F36F503FF94795F28B2D
+:107260004EDA58D80322FEA4C23660C9AC9CAFCE19
+:107270001CE57C55F37795E13E9EFDD441F1C1C6F6
+:107280006D0A0BE3DD0C5D007918F7FA9F3868DDB5
+:10729000F3B7A92C48E7ABB4368C935FFFC8501FF7
+:1072A000C647E70C8A16E179C3AE5FA6F8F0DC5753
+:1072B0006307FFFE24ECCF33313F4A29A778C45F30
+:1072C000A7B52EB460BE9D7A3817F9F5AF4FF1DF40
+:1072D000355BBCEA8F951E80F392E7DA5EA9827176
+:1072E0004EB4AA34EE078F3976A8C4F7FE7CBCDF13
+:1072F00036BEEE08F929A614063E43F9FEFEC2C8C2
+:1073000008923F6BB87FBC277C60BD886FA4579DF7
+:107310003C8BEB371E7F0321548072A2D1E6A3B8C9
+:10732000EC89AD368A17823EA07C8313ADD9162E28
+:10733000879E22BA6BB06A76FDB80D5B553FFF7D24
+:107340000CCD8EF36577AA41361AEB3C3F22BC592F
+:1073500009F2F88F11BFD7AD1A4DE7A2CD795CB213
+:10736000FC08782AA88B2B2D799AC77FD9A80EAB59
+:107370003ECF5DFA6758B0CA709FD1B281F7FE6008
+:107380001C94A7FCFCEAC5333BDD24273FB43C53E7
+:107390007923941F4C0BBF6B05BCBCA806870CC09F
+:1073A000BC21CBD6ED0AC5558EFF00E3FEEF3F6151
+:1073B000F3111B8ABCB1253F5D4CF1A9E4F602F341
+:1073C000F2F875344FF1E2EDC48CF24566B336E164
+:1073D0005F88F03C039C04C0C7B38CC7C58E57B808
+:1073E0006FC5F3C38DA6F3C6C7C5398BAA01DC6E82
+:1073F00092FAFAC6015C0E345A387FB2BDFC1E4ABE
+:10740000F97B71528E4B792BE575CD009EC722E535
+:107410002C636D245F168AFB92973DE6E0E78B3480
+:10742000E641382EE668621B0770BE5E627FE21E90
+:1074300024EB45AC9DF4DEFBB6C8C2F612FC7EC759
+:10744000862CFADEE68B201F47E4EFD159498E2CBB
+:10745000627C9ECB5B954854E7EF90BF4FC2504F84
+:10746000E8E44E0FBD60D2070B84FE5BC04CF946CA
+:10747000AD463D154873D3BA96B48A3CECEE79A973
+:10748000EC2CC6BB8291E7A6D3BC155F24C13C1689
+:10749000B1AE28DE8BBCFC717E8EC93C2FF33AFA6C
+:1074A0003ACF85BE9913F17EE5EE714DF396F06605
+:1074B00078B04A870709F785610ECF857B14C2D75C
+:1074C0009F85BD25CF079AF1BF8805A6A39C5B7455
+:1074D00017EC334BE2F420E960F193113A0FF80115
+:1074E0006B4D77013F2CDBF6E4AC31F0FDA2075E7B
+:1074F000B423BDD7654587583261FF199E70474D4B
+:107500005102BD6FD2F35F179C98F05BD177009763
+:10751000053B55CAA3D0B513790461E287A630FFB5
+:107520003DC1A697555F0B3C6DC29F392A3FFFF9BD
+:107530004AB8FDB3E76DB66B760DE8DDAE31CB9B97
+:107540001E768D499FE2790ED49F5DB93C3FFD13B5
+:10755000AB3F238BE4B4490EE796D37DAC520E2F9C
+:10756000147A508EB300F51FD4DFDDF68B74F46708
+:10757000FCF9AE5FE451BE06EA9B61717D73432363
+:107580001FEF865FA550BED45FA7B58F407BB0EEDE
+:10759000C1E7D3F5F7BD7E5010FC03CA5BA91F9766
+:1075A000AB3B06E0EF1A4A397BCE7D5BB275BACFB2
+:1075B000B14EB7719D0DB84EDD399546B1CE7736D7
+:1075C000F3F51DDFCAD73BBFC73AC31457B9E1C7AC
+:1075D0000E5F98EC8E28E9F5934FAA0CF759DD76EB
+:1075E00087C90E38C35AB7233C96AF7EF54D2BD0D2
+:1075F000C5E20B003E400775773A48EF2FFE258F16
+:10760000A7BEAF54E75340FF4034FDBBF07C09D820
+:107610000B686FC4E7D16D077C3E406F07F4117EA5
+:107620002B845F6BC59EE7E977B4143FCFC75C211D
+:10763000EFB5D96DBAD7464319C0CFF93B114FFD0D
+:10764000CDF77171FFEC7F0FF978EE6AA2FFAE0BF8
+:10765000F4E7D89A53A336CC43EE7A52213B69F92A
+:10766000F5D5E9D50CCFB771BF5A7E31D76F8ADF18
+:107670004FF9350EC06B2A8C5758ACF1FBAF340F65
+:10768000CF377F80D13D3A72BEE6E7E86F77A23E02
+:107690007459481F9AD73FA598EBCDE5AA85ECEB26
+:1076A00065766E67778AFB2B868A790C2DE6796082
+:1076B000C38BB99FA113ED4A8C777FC341BF63C4CD
+:1076C000D844F2BB5B19A73FAB849BC7FA51377F05
+:1076D00093FDDCD51FE13497B5D3EF224EAF9AA9C5
+:1076E000E1798637F39C744F14FC09603FB3453F42
+:1076F000476CFCFCC29B3806AC6BB6F04FBF89D719
+:10770000A3C2F86F16D8C9AE0D3FED20BBE1965469
+:10771000EE3F64391956E4876B859C9A33CEE14776
+:10772000B93E7BDC2D012CA1BF300378D539BB36A7
+:1077300096C138EB2C5CDFAFCB62DC2FB0A1A3028B
+:10774000E1770998C998BF0FABDF7536BB373A327E
+:107750009E9F58867E86B18C135815C1D7505F66A0
+:10776000E7EFE73DF41F33EEEACFD81F306B0AF5A1
+:107770000CC208E9A23E83F6BF33F07C4116965650
+:10778000A2B7CBAD2C6CE1E56617DDABE435FC2E82
+:10779000EC55552C9A01EB8B1E329EEFB83A6A8954
+:1077A0000EC5789135BA0FE167716A360F8C13A850
+:1077B00051CA11EECBD6F76DBEAB1F7A6AC65DE338
+:1077C000A08EF779E13CBFAB50BED06C607AA4D3F9
+:1077D000B95676402DE7F8433A6CCED2C2D46E1536
+:1077E000A77379AE44E2A50CBAD7C377B6981FF455
+:1077F000B3391DBFB727F6AB7CBF58C6E3B8BDB6DB
+:1078000054F0ED5249778F1BF935827C83FC84F666
+:1078100021C06DB62893D1FD83822F1E2CE6FBCCB0
+:107820002DC5729FD9B7F1963B5894D6FDB483F01D
+:1078300028C79D21CAFB8BB9DD29E721E977215BA8
+:1078400049F93C0B859FC6029284F2835B7FCCFD95
+:1078500042A6BC23309428BF6DC94EF3739D9F4749
+:1078600035C825F29B2AF6AEF9383FE59B293EA4A0
+:10787000F7D9F636F20F98DBD9F0F75331EEB61997
+:10788000EC2A45C4CBA0EED8AAD0EF5ECCEEDF3513
+:107890001CF53948EBC9742E54D8DB0B057E1DE26C
+:1078A0007EAB85685F615C0DED2B84D7366E575AD1
+:1078B000853DDCB0D5686FCCDEA0B33B7961B81FE5
+:1078C000C061CA53B709BBE32D7BD77094FBE6FBBD
+:1078D00002DEB2F07584F318BF573387BFB70AFBD7
+:1078E00052D2D513C53643DC4D9E3BAD4379C5EF2F
+:1078F0006D30E569B9E8FE983A85DFDF29FD906FC4
+:1079000088F214D8A1745FCEB1348A839BFD939D15
+:10791000D5EEB045E7A79C9371C374844F5DBADD83
+:107920008AE51BDDF78A75D0F8C73C03C9FED95438
+:107930003D721BE627FDF9A153339C45144D11E719
+:10794000A73E7D01F3E9AFFC02D643F5D80C3F8E8C
+:10795000F36CD75C2788EEBF157F36C30A7ABEF377
+:10796000EEAEED58776B9600D56FEF1A80772EBB91
+:1079700023765E5F27FBB307304FB9F33E5E7FFF90
+:10798000217B00F39FEAC4B9A5BAB10AC9DF54C18B
+:107990005FD2CF5467798697E3F9EFA29CAB5D9EE7
+:1079A00016482DCEC5FB504FD0EF2F940CF4A716E0
+:1079B00043BBF401C133582E99A984ED78DEFFE56D
+:1079C000C80542AF25FC9D9054A1A70A4A02F4BD08
+:1079D000F4A3433F7FC7FECFD5CFFF016BCEE90AAB
+:1079E00000800000000000001F8B08000000000065
+:1079F000000BD57D0D5C5455DAF8B973E70B6606BC
+:107A0000464003F9700604B140470545A51A011127
+:107A10003FD041CD2CAD4634454341ABCDDDDC7785
+:107A20000651336B0BABB7DCB2763273ADD75A323B
+:107A3000412C3F06B5D26C6B4C6AA9D4C532BFB29B
+:107A400022D35DFAAFBBFECFF39C739939D7416D5A
+:107A500077DFFDFD5EFCF93B3CF79C7BEE739EEF10
+:107A6000E739E75E2E5DA23F371312D94B43482E0C
+:107A700021BFB7B9227B752764FAC2F46877162153
+:107A800051296E838DC2F3CA24AFBE3F21A4C5978E
+:107A9000E1B210329E1067BD99904BFCFE4BAA7963
+:107AA000EEB35F368FF59F99E74FAA79EE94E8BD64
+:107AB00043E97FE2B0C1FD77A439B360DE7BFE8B82
+:107AC000B8611E52345C43061372AF91E0CF8FD57C
+:107AD0005B338C39B4DD648825763AEEF56D29B3D5
+:107AE000E93C6431BD2981906F9A3FD3DBE83C0BC0
+:107AF0003A64E28C25A4AA43C276C196667D311D04
+:107B00005745DBC210FC2A39BE84B469275A82D794
+:107B100007D828BEDDE1FA6A6CEF79FDB4D64DC70F
+:107B2000DDA3A93FF16C1CBD3C4C72BC6CBB7C9DC1
+:107B300009FCBEA38494D4675DDE3FC426617F5DEB
+:107B4000BA7330AC339ECE01B0AC61EB558FF7F217
+:107B5000F9A64792BB5CB47FE6608BD146E99DDB1A
+:107B6000E2AEB5503C66AFB50F94E91C03520A9CD7
+:107B7000301F99354CA057494F4202B03E6D7B0FE4
+:107B800042DB1FB7E746138AD7F498C07D64002113
+:107B90000FFA32EA8CC9848C7D868EE989B7380960
+:107BA000BDB7C4C061EF8DAEA27C0AFF4346F84E5C
+:107BB000DB903A2F9D671FE043E7B963487624E9DD
+:107BC00047A9673769ACD1F4E6E4190F021E770CB8
+:107BD000B9B118AE8F30583266207D09CA8733D9C3
+:107BE00035C596CBC613BA0EB7DEDFFD56BA0EF713
+:107BF000FBB2C34BD7E1EE6772FBC2D06D32A7C3B5
+:107C000083362BCAD13E0DC57360100FE5F9845839
+:107C1000EF0BD0F98E2F4D18B08ACEF7BBE411BF11
+:107C200082E729CFFF5DB27B4EE8F32946FDE0FAFB
+:107C3000B5E2318BE3F12BE01B9DC7954FE58CD36B
+:107C4000FA12FD3FB1C824C093C7C5126766109EE3
+:107C500032395180A74E4F13C6DF3EEB06A1BFD489
+:107C600010C8A93607E55B8D8FD25246215E559626
+:107C70008D5184A27864FB854FA7513DF97EBDEC00
+:107C80009028AE7377BCFCE9703AEA1C5D702CA5B5
+:107C9000DB392705E87ACF6D917D5E3BC887535B62
+:107CA000DA83900A988A8E9FBFFF4DFD08FA6B45D4
+:107CB000F59C71C0C7B93EDD976D21785E2017F540
+:107CC0002495EAC346F17A1579F407B91F407EBDC1
+:107CD0002B9BCE53AFEAAF1E759244C138ED976D22
+:107CE000CA3AE9F3171FB63FB63764DDCFD92C7116
+:107CF000276EA0BF0C24032FC9F0BCB3EFD215929E
+:107D0000C2A666E453ED7ED901225A9B2C1189AE9E
+:107D100073D416832F82AAD6B7DB8EE96D945E7F6B
+:107D2000F5D81EDBAB03FDAF212416EE3BA66FA3F7
+:107D3000D787DB6C48A705DB7FD013CAF751DB1769
+:107D4000A25E17533B164DE527D04CB2B7D0F9BD14
+:107D5000768BE3653AFF3D2B4713328890E88E69B6
+:107D6000D856D68DC6F9E6774C4278418709E17D31
+:107D700091816242F1D8D7D88DD4523C3E92FD1900
+:107D8000CFC13C060BDA89D2C43B96C2BAF7457A1A
+:107D9000B3EEA5CF2BFDC3A812A0EB822D9213E466
+:107DA000AC5426FBA418C03702E72B953FCE5948A8
+:107DB000AF8F2DB47835D1D84F08ED97075B5611AA
+:107DC0000ACB7A6A2FC2C8E77BDCBEE8DA18DE236A
+:107DD0003BCA703EA5FF8FB654945B05D6755FAF66
+:107DE0002D3707D7A36B93B01DD37103B6555BCA6C
+:107DF000B436FA9CF7335F8A033AD1F1667758BB01
+:107E00003C249A84B15F4A6BE0F6781AD8633AEF63
+:107E1000DE54E757A087E397B4698D604FCD46EBFA
+:107E2000CB540EC6E70DB0CD0E5997BCFB3662A3FE
+:107E30007264886BD739E9FCD3681B6ABFEFEAC26A
+:107E4000DF9CEEB4DF35B85EC52F91CC2584503968
+:107E5000BFD3CAF056F4EA533E5EB93F2031FDF07D
+:107E600036187C2FD3DF8FA4BAFF06F8064690A9F8
+:107E70009BD19E0652CA2CFF3EFC297F8DC0FF2855
+:107E80006D1B89017F6657F0677A7D35FCBFB33182
+:107E9000FFFA914C16835C7C74F3CD0127C5ABF9D6
+:107EA000C14183C03F28CFEB66D7E338626DBF087E
+:107EB000F25AB5D3645B45D7574A790370FB0E83FA
+:107EC0006F9D1DAF13290E5AC33A89F65745B56702
+:107ED00080FF29DC15E107B96DDE15A1053FF24EE3
+:107EE000BABB9BBD3B5CEF532451F9766E376841BA
+:107EF0000E7AD89C3170BD2B7CAF66C7147D54CBF5
+:107F0000997B25D33F37D7C3195C6ECBB91ECED032
+:107F10003AA21FA078DFF5814CC08E972F91B2B79F
+:107F2000E4804DB338D243F450D1371DC8E52090DA
+:107F30004F2697951DDDB87EDBF9BC4C0F4AA9830F
+:107F400006FA94DED0CD07FABDA02316C729FAAAF7
+:107F5000E869629A7B04ACBBB496EA377D8E7B6994
+:107F6000420EE84B504EF45690272A27F1B343E4D3
+:107F7000A0B6F9272DC8892E5F423931D0B63044DA
+:107F80008E5C9D718AB5B807C563FC32BB66150966
+:107F9000F617DB19FFAF55DE0771F92A37FBD3352A
+:107FA000743E5D75846329C5EB5C9C0DEDD8A2879A
+:107FB000294049B048E72A843863D16F2507D85F44
+:107FC000883FC0FE0C6EADD6BB43F0BBADA31FB166
+:107FD000513A4DEAE88DED8014F7647B2EF0670A84
+:107FE000A7633F6C892D4F03F8DC67647EE67CF560
+:107FF0004377C2F3CEFB0C0E781E21798CDF1CDF99
+:108000005CA7E3BA0700BF0F74E4453AFE54845BF3
+:1080100006BD3C954CAC4F521467AEA17CA6F39EB6
+:10802000D211AF95F2731685DD007723CE6E034132
+:10803000EFE83A43FCCA056D5D0A49A3FC5DF4A76D
+:10804000A35A6A0AE76604FAF9E973A78F60FEFF8C
+:10805000EC7A1DFAFFCAE68F076B68FF19BBF33A8B
+:10806000426DEFE89EEE05C0D779137DAFEB287C1B
+:10807000CF6FDE8C1A6A0BD2B35EEB4FD7D2FBEB1D
+:10808000291DBD14AFFA47E5121F8B7B4C65D957EC
+:1080900097EB791D69481FC5DF28F67BAB279E2E1D
+:1080A0002268C7AFE68714F99ECFF5603EE8010964
+:1080B000F53765AE1120879992239D84FA1BA60F90
+:1080C0008A9DA6F28E7A539A96ECA82541BBADF60E
+:1080D000477BE4FA2787D1F52E4D75FB80DF05FF3E
+:1080E000F3B7373FA75D959B5F29023E8DB84122CC
+:1080F000B2742D76F2271DDAC9256504ED246D438F
+:10810000EDA4AE8B38FD65FBCFB3F34FF2F134BE77
+:10811000C5B811EC78E87C47520BB6C23AB6DB25FD
+:1081200036DFBF096FB57DDFDEA9AFD766DF5FE55C
+:10813000785FCDBE7FC4EDBBDA9E133A1FD8F3EF54
+:1081400077F4F581BD3F4AA8FD07FFB6DD647B9952
+:10815000DB7BF40791D1BE2BD9FBBAF4991F756173
+:10816000EF0340B77FD5DE2BF2A5D607B51EA8E5F5
+:108170007EEC2334FE023E6D9508D8D760BC455096
+:108180008EF7A5323956F42624FE423F4FF5C197AB
+:108190006EBF5C2F7FACFE538E0DF2CD1CCB002248
+:1081A00005E55DD11745DED57E644EAA5B4ACD0D4F
+:1081B000EA49E566B51FE84A9EB6E9207FD555FE37
+:1081C000C0FC006D43FD4057F18E3EF5E7E9C179F3
+:1081D000FBB5C50B09A97A9CF77F519E12804E61B1
+:1081E000E4A967EABF204F57E023FA1945CEC61E1F
+:1081F00060F241D258BC4FE505F1DEA74FF6D5DA63
+:10820000C1EE317B38F612A9067ADEC5EB098ABCCD
+:1082100016A5B96F0AE533C4F710B75F6B5C382D4C
+:10822000AE9A38E9F5BB681B6A370CC0BF30F17DE8
+:1082300061EACFF3F30352AF8DCF93399FFF8D7176
+:10824000E15DA961EC047132FF1FE48B6112C8CDBE
+:108250008F7E2D01FDEA8AAFBA358CEE0ABCDCAF09
+:1082600055FC6B2CF8572A2FEED47F21DE2C2DAC39
+:108270003F6FA4A1DF7FAD1B5EA61D4AF3F43CC295
+:10828000EB1FF9AB9D5AB02FF4F7613823D6473E68
+:108290009239ECBDF16011C563EC939DFD5EE81F62
+:1082A000991FDD594F81544219FFEB75C30E3E8A69
+:1082B00078D7313EBADBB4AEEC103887C2961038AE
+:1082C0004F05AF65E3C18F58711E1FB3F7747E6908
+:1082D00020C0CA7C5C0F487B71378817B74856A806
+:1082E00087DC9EFFBD1EF8535AD8F66E225DEFEA7A
+:1082F000754565E6BEF43AD8418AEF8BEBC6ADF61C
+:108300006AF9FD3DB03E863F867AC929533E55E65F
+:1083100049BE54FBE5747C3155F467F0A315EF2793
+:10832000FA9C9F773FE82FDE9F8AF7FB0D3FE3F92A
+:10833000B7E613A72F8C9DFC8362272F5258999F75
+:10834000D26E523DCBC3D5E3B7F2F1018D663EA1AB
+:10835000F4DAB5CEBD1AEA652309938FE6757795F1
+:1083600079991C12A76ABD57C2F7E55431BF831F24
+:108370009B78BFFF4AF4FA9FCBE8C5E5A3429497E8
+:1083800068AD6BEF8F148FE838C90A71ED0257C4DE
+:10839000A310BF97162AF23DAFCC9944D71741845A
+:1083A000FA5F50BEEF292BA274594094F1F3578322
+:1083B0005F72693AC73379DF2E75DE9F49E5074B57
+:1083C00071F4FE2FD655AEF666213FB01F61ED1554
+:1083D000E4BD5E05E7ABF483CB37EA27D86D4A9F4F
+:1083E000F43076A383D3E75B894C05BB172860F193
+:1083F0005E2095B5F1692CBE23696C9C318DF339F3
+:1084000032840E49413ED31F3FE41121EB463ADD51
+:1084100016A7ACFBD1B271745D8118922D513989C8
+:10842000495BB97A59889CC4A53D8A72129C6FD564
+:1084300041A0E36D9C4EF1698F1CE4722481DECD76
+:108440004781A072B045F2CA749DF3410EC2ACF3ED
+:10845000CBCBE5C8ABBADFA9BBC2FDA72EBFDFA956
+:10846000BA9FE8E27ECEFD9C4FE3547C2C51F1B1E3
+:1084700048054F57609F60CF143B57DEB47A798F21
+:1084800038A8374AE026C05EEBA5018464BFF4DF5C
+:1084900065E60490579B2E91DAFC012F3D73D0487E
+:1084A000ED5919D83394DF35AB9DBDA97E83BE232A
+:1084B000FCDB32677F909FEAE5F174FC90979E5D4C
+:1084C0006DA4436F5FB65A0731CDF097D6AED6D2C2
+:1084D000796FCBF9C3BB309FB6E68583E3A42BC885
+:1084E0006B9D6A1D6B55B05735FEA9ABD8F765AAD1
+:1084F000FB97A8FA1F55C16B54F04AF1FE19B3243B
+:10850000D49319947F40B8ABE94D595A679ED1E98D
+:10851000CF2433C64982DC8FAD65F0B4973695AD74
+:108520003487C069AF9781BE2B72AC23EC675A1CAD
+:10853000F182FFD07561CF46A7752147996A7FC741
+:10854000FAFF0CBF26E03E8BE097F7C822DC2C2B0D
+:10855000786F3F785F165C54E0B7CBA07ED1E5BE64
+:1085600007D95606FB1E631FE7B0B7A90CE23465B6
+:108570009DCAF8E2BF5F92E1790BD39ACAD6C3BE17
+:108580004A813F1DEAF5D363584BFD8C0C7EAC8AC3
+:10859000D73B8A77C82EF033D323FDE98BB242D67E
+:1085A00049EA33609DCD0FCAC81F6F2DCB47CA89DA
+:1085B000430FF58AE6E8E8C51BE8F83D0FCA8BC112
+:1085C000AF1D5D1CDB03F289DD692CDFDB13DDAB46
+:1085D000C7DD146E36DDA5877A6DF34323B1DD2D3B
+:1085E0003B57B453397EFCA5F7D0CF379BA2913EC1
+:1085F0008FA4ED29ABA17AF1589A0DEF77C7587B7C
+:108600003441BCBA4A47A05E4D88E305949BDF180D
+:1086100006ACA278CCA8B901F78FCAFFBBAC3881F1
+:108620008E2B5FAEC37D05FAD30FF076AF1AA98704
+:10863000FE59CB78EB1D85EDAE7FBC79A01F1DDF09
+:10864000FEB0EC584707EFEC488D2AA7787D15C19E
+:10865000ECF097677B47019E7D7ABB9F4DA37C9D85
+:1086600011658994C079586D5113E9BCBDD39DCF74
+:10867000A5E506C7EFFA878CFB606F9F2DEF01FC25
+:108680007B99DBEF9D1DE53DCA43FCFDEC6FB548D2
+:10869000E75D7ADB7D105FEE8A4C96BCA8C7F5B12A
+:1086A00050B79DC5E36B2A2F8BDF0CE3F79F4893F0
+:1086B00071DEE386C5E42B2AC4CD8F74CF073C95C9
+:1086C000FB94FD375D926D60681CBDAE57C11BB059
+:1086D0008EA09C1D3D087283713485B7BFF4F96A82
+:1086E0002FF8C23D34FE073CE29CC5E007C8925813
+:1086F000B60F1A5F9F115A8F08C6A94BB93D60E3A8
+:108700008E782D98B71ED914E1837CE688F70B4B41
+:1087100068FD5DD1933951162F38E393168B16E817
+:108720007A54EB39F14BD8377C5E877674F6F3DDFB
+:1087300097B4833DA0FC847A90FAB93D7AEB709EA1
+:10874000AEF707BF11F5847C53E63477AD279FBEA3
+:1087500074A66CBDB96B3D99C3E3F6E2E7752E9044
+:10876000F339B9162DECD3153CFFCECB208F731601
+:10877000460C3450C4E73C6F40FEB6592C5E2BECDF
+:10878000234659B4DD68FB0D9787B69A08CC53E4AD
+:108790001E7AB47BF28A5C1BD0A750265A23F52B95
+:1087A0007294C3E662F032A81B2EB7E4D980BFB141
+:1087B000BD993E74F6474F1D23F50BEE9B9D5EFC65
+:1087C000E4D343287E67886FCA10FBBFBE8F56452F
+:1087D0005CD1507FFCDFDA47D3F6B6C49DA0A97800
+:1087E000701F2D2BFA5610BFC532E22D2F8DF001D0
+:1087F0003DE514E627461109F7D18895AE3F3BB811
+:108800008F26FF6A10D2E7B887CA551F4A972823D8
+:108810008E977F25FB0CF4B985B1ACDE2A3F5D460F
+:10882000605F8DD2D56BA5F0A8B86ADC5FF3829D3E
+:1088300001FD9688AB1EF5DF910279F2ECE72390FB
+:108840008F735E98FBE96F73806FA571A1FAD48B6B
+:10885000CB1F9D8F186382F39CACF9750AE053F827
+:108860003B9A5F42DE29BB9FBE0DEDA609F7DB8870
+:10887000B5ED3743405E6A4C03A04E3EE7F9849461
+:10888000D4ACE0FD73963E98C1EEA7796B14D8ADD9
+:10889000085C4FE51603CACB8C876527FAC9643D8F
+:1088A000FAC92F9745205C999487FA3643C3F6DFBF
+:1088B000684C188FF69D919C549A89F34D33D8FBE0
+:1088C000470332E38F97F34D0FFC19D63B169F7F7A
+:1088D00017D098FAAFDB7B73BA68981C919D12EEA3
+:1088E0003711526D033B305D23A1BD53EBE5D8DE5C
+:1088F0006C9F6F468AE34EB86FFE6306C7523BC358
+:108900004156F0A179D37C4D6036EC43924603D6B4
+:1089100037AAE83A22A2D8B987CD14FF2A2DD1EA86
+:10892000A13E6563764DC1A7CA56360AE495F6B7EF
+:108930006A69FF7C0BB3CBF3BBB1BA0FB1187D2FC3
+:10894000873E0F704E63F7D9A240DF86A2BC80FE3F
+:108950006B68FFF784F51746E5D9DAB270FF7E251C
+:10896000D44B009FBEFD429E4BE1847E208F0BB511
+:10897000A916E043EC94A9F0BCD764B44F54A91EE7
+:10898000CB8338F0357910E4B3331EDE53BC06E0F8
+:10899000370658018519AF1F423F750F97B33688C8
+:1089A000FFC16F51F80DDADEDB9BD907B7CCEA398E
+:1089B000F7F69684FD50A57FFEC33AE4C7FCE54C6C
+:1089C0001EE6D7FC09E79D6F09F4007ECC6FD00D41
+:1089D00006B95EC2ED45794D727E2B958F725DB4FE
+:1089E00055A2972ABDA57A802BEB248495E7CD7FED
+:1089F000F8931E9A2C361FB4062E47C179BBA78068
+:108A00005FFB66536CCA8C10BE7FB36C6B14EC6B4F
+:108A10007F15E14FB7423D666184631DEA29E3C7D4
+:108A200037CBD2D741BD6696356081FDF059F7A5A9
+:108A3000C580BF3B6AF5EBA1FF68BD5D03B0D36A9B
+:108A4000CD07D8A9ED8FF037FC9C0AFE503E2D9043
+:108A500098DC546EDAA34FA5CF7B91D3E7DBD70E1A
+:108A60006540DD607E4A2003FC3095AB8C44E0CB52
+:108A7000AB12C60B0B36C9CE887E41B95A0072457F
+:108A8000F57F1E97AB055BB63E007ABA00E469E05D
+:108A9000E57249F3CBBD787DF38BC584DDBF17E468
+:108AA0004EF1FB145EA683FA9A9EC3F43900AFE33D
+:108AB000F4A7FD45ACDF9B85FE84B4E9212EAE9280
+:108AC00059BC40F5291EE289AA269DB72DC43E2E29
+:108AD00080FEAC607F5772B3A737DF2FAB31A05F4A
+:108AE000DAC3F5AFEDE18628908B6F5FDBF3EE30F4
+:108AF000C8B3364B56B0FB97E921A75B15D0290ABE
+:108B0000D789F15115D0252A48A74E7DE3725145EA
+:108B1000181D14BA5469399D947E7EFF5E4E874AB3
+:108B2000C2E9BAA50FD377AEDF5462D08F28EB73BA
+:108B3000C788E7072EF0F57DCCDB4A2A378E2C94C8
+:108B40002FA77E30CFFF69D7B76FBC88F523859FED
+:108B50000ADE96749B62A79DDD62827C6ED3908A4A
+:108B600070F5EA539C7E3A33B32BC76A12EF5C4C24
+:108B7000E9376F93EC40E241EE15F25C83A6CD82BB
+:108B8000F1E9AF642BACABF07FCAC6C0BA15B9D35C
+:108B90006D94B44DB04F48BA21FD15FC0AAF738DEA
+:108BA000E9C6E4CE0FF828781E93FCC82FEF1B927D
+:108BB00095C5BB6D7AA8232A7AAAC6F702C7578E35
+:108BC000928649FD011F870DF49B503F88F8985B02
+:108BD0001FC4E7798F3C68EF177CCE51AF450BE39C
+:108BE0008E12660714B93CC6EB12C7966FC578584B
+:108BF000798E29FDB2E7B817C75DFE1C65BC9CCE17
+:108C0000F453D18B7D314CFE0B97FD09C7297616A5
+:108C10007EA01EA7D053A15B885E0AF451F44BD10D
+:108C20002785AFFFAC5E9125DD316E7D88AF1B756A
+:108C3000A447D02F807C82BF33E8D939B810BF89D0
+:108C400071CDA8A41FF4EE30D7153AA9AF07F32AC7
+:108C50006B0AD07F94391EF7CBC9B2F8BDBD43E291
+:108C6000B3AFA0EE05F6F415D987F69450AD0CF12C
+:108C7000E74ADC56B370947504C8D72609CF1D297E
+:108C8000FE9BFE3CDA29A774BE8A9C8519104FAC66
+:108C90004C4F65FE2CCE791AEEAF3C15288EB205EE
+:108CA000F3971BCFFBE568A80F6EB10BF943E5D92D
+:108CB000BDA8E7F3496005E4BB331E3E543A04F80F
+:108CC000FF8A0ECF2FCCAAB3A3FF3BBD7EE6204880
+:108CD0006D672C4F4778EECB7733F86116D7CD58B8
+:108CE0009EBB01EAF35F45388B41CEDB574B56C83C
+:108CF000BF86BF9CBBE476DA3FDCD2AB1BE07B6473
+:108D0000FD57A5C3208F582CA3DE38D73F3905FA6D
+:108D10009D4DB20396388B5897DC0E72AE8D46BDD2
+:108D200053CE35D6EA98BCCD4C67FE725A3AB31B87
+:108D3000D3B8FC16D6D666C0B982F617A99F82FDB5
+:108D400075BDADDE0F79E08EEB1CEBE873AA68DA37
+:108D50001A4FE5E994C4E2F10A3D31827CEDD70572
+:108D6000EE07FCF7DF6F19500308C8170797B3BC6D
+:108D70001DED0CCDA3F0B90ABD94E797F3E72AF3F4
+:108D800028F7ED83B80AFC08C7F7F4B257A640BC31
+:108D9000707A637A0C09A1FB695817A5F75C6A1F02
+:108DA0003787C907ABD2957AAB0FDB0A5E47DCAFDA
+:108DB000AB4B82FD5C1AD71F0F8DCF4FBE186104DD
+:108DC000B9A471BD785DC7FC0A8DE785EB547F04BB
+:108DD000B833DF93A747BBC3D823A555C7FB4BD3F5
+:108DE000CDAA73732CDE57F44F7DBF12DF77D65DAB
+:108DF0007AFFBC735D673D9431542186417046EF24
+:108E00002F32FDFD4D387F39BBCE603550FA1E073D
+:108E1000FD827DC10699C58B46A66FC7770CF041D0
+:108E20005D61F661E2F05378768BECB0D1F17B575F
+:108E30003F84E73BEE5E2B91EBA490BCEBA9D553AE
+:108E400040DDCE39DC2B12E8F8731BD97914DA6DCA
+:108E500056E55BEF26D8BACEB7FE5D7996527F52C3
+:108E6000D37F733ACFB71CC421D29FE5EDBBA818BE
+:108E7000E50DBC9CFE673D6ECCABBEF354603BB4CD
+:108E8000FEC5C244BA8EEFA5638F0D073DB24463A1
+:108E9000FDE4ACA71A3707BF6B1A74713CA5D3DB8E
+:108EA000E6682BD88FEF3C8BF17AA7DC7039BD7167
+:108EB0004BB39C4870FCF6E174FC4E73346C7784C1
+:108EC000D987637C569FBFB977E190EBE0BAB2DEF9
+:108ED00033BF64FC56F03FB3716614C4ABCDCFC54D
+:108EE0006E1F0A7C36455B4114E6F0733827D63096
+:108EF0007B74CA18BD611CA5DBA9B5937A407E7846
+:108F0000B7AE5DEFA0F33A769445417DE46B6D5BBF
+:108F100094155A3ADE0F78687D32D8C1612504F77E
+:108F20000787F9B5C466C7AD7B949FA167B53EC8F6
+:108F30009BBF817D43F0E31723D9FE3DDF0FBC7B50
+:108F40001BABB375D655787D61385F6F74468CB2B4
+:108F50000F84D70BF3D8F5936BDF1C0FF39D5EAF37
+:108F6000B302BEDFADD7E1FCF3687EAFA1F2786A51
+:108F7000233B2F306F3BCD93ED60472494DF795432
+:108F80007E8D207F0B754E7DF4E57259B891E5D743
+:108F9000F3EA25CCB715F99CE7F41523DDB99C1A43
+:108FA000E9BF4BD4757423F52B801E5DC9EB3F5B85
+:108FB0000FD06784AF07A8E541A19B22174139254F
+:108FC000289F0AFF63EA078C48C41BBC484F6F0107
+:108FD000C98478A1564F32E13C945713E900BDFF94
+:108FE0006B44543FA8432D36B2F681C8A875D0FE15
+:108FF0003522C50778FF55637D07F2AC5F67D871EE
+:109000009E07649B4EA2BF4E8A6B2B423750A871BD
+:109010006AC00FD61AD08EA8ED505A06F33FDB3344
+:1090200008CAFDCD19EC9CB88E54637CA1B4341EE3
+:109030004886F8A5CC1473018E923B36F49804FB55
+:10904000BD65C363EE4FA39167DE86A4495A2AE744
+:109050006583621A52293C2C2391F5F78FC9D551AB
+:10906000B8A626795211856FCD70F6CB08798E326D
+:109070002FBD3E2083E23132C19D03FD557AF34A74
+:10908000F003DF4BED0B347270FC41891C7D5B0AF1
+:10909000C26D3A9202F1F6CD807FF7AEDB1519CEA4
+:1090A0001B33C25C2F276439D425CABDEFB54A688B
+:1090B000CF88CB48F93981CB5FB9D1EC473BB75268
+:1090C00077B6533E52C14E456B81EFE339DB2768DB
+:1090D000FDCD707F5FB2CC7AC288A1E2DA4BB15D80
+:1090E000DB7FAAA8E484321F5DDFF73ABA5ECA5775
+:1090F000C949794D554CA2449E4EED9DB4FDBD9F8E
+:1091000060DE5A2F698B403E4CB7829F92885B731A
+:1091100089B6F34D542EFA434BE5818E5BD4F0EDC6
+:109120005E508BB94A9CE5CEC378F13E2B5B0F7144
+:109130000F4379BD9FCBEB490FA98652D1844020C4
+:109140000A8EC29E1DEFCF00FB5022BB6703BD4EAF
+:10915000AEAD4D5A44E5E7DBCD06C7383AFE94EF95
+:10916000CD28F0AB953CDE271765FFCDB47F9FBDC2
+:10917000EFBA5521F25595C1FCFE59BB3FE541B010
+:10918000337696AF928B7B521EA4E34B5247E7AEE9
+:10919000422A381766E0BE05DBAF18AF0D7F7E634D
+:1091A00072128B53C87AE68F0D5AE2B5C4604BA297
+:1091B000289D46535CF2E05C2A8565DCCFF7E1F33D
+:1091C000615C14C435B699F16CBF87B8C06E29FCD8
+:1091D00055F876193F29CA10D76B8C4407EBED4B35
+:1091E000D65A41FF15BE9EE4FA78D2C8F470A46C3A
+:1091F000463BB5A881D5F51649CCDE2EDA21B1FA69
+:10920000E665FEB66105D8E48AB533D19E2976CCF1
+:1092100046FF817CCDB3BAA2FDB67FC2EFAE2DBCB6
+:10922000267BE653ECD9003200E4EF6AF19262C784
+:10923000287B7E9F11B29F7C557E01C9E8BAE770FA
+:109240001C47CAD36D5AA04B77A303ECF9A2E7D30E
+:10925000D04F92F36BB08EA28C236B63517E57D8A4
+:1092600065E46B695322B1D14B739B243C273BAE21
+:109270002916E1A88E04844B7F7F5D01ACBB731F70
+:10928000F4F77D103EBDE1408E9BD5698C80878BC5
+:10929000287864D583FF3967A678503ABBCC2BB1C8
+:1092A000EEE8229DF990744902984A0DE89D53E733
+:1092B00065FC31D6A0FEF3752DE27AB5683FF3D791
+:1092C0008B46B0FD42ADB76F34F05FB74F263E0A14
+:1092D000DFB25FCEF5D3A1B5DC9E1BE235C416C26A
+:1092E000B7085B24B185F087789D01C8B7A672796D
+:1092F000792882D97D53668C306EAA7936CA4F2080
+:10930000A5781FACD7E2E829CC4BDC2C3E56E46AAA
+:109310000AAF9B8F27EDCBC04FDE3295F687CCA7E7
+:10932000CBFF01FD862E5F8CAB295D8E5F499ECE03
+:1093300064F0F74EFA92BE284F2AFA50FD407F7F24
+:10934000AE85BD7F42A39267F2293C659F8EF86887
+:10935000FF724E17885B21FF39E7B4A0DE28721731
+:1093600000BF47ED5C749E48B76E4E916EB12522EA
+:109370007DBABB447A5C373555E84F705F2FF427D0
+:10938000560C14E0E4EA61C2F85E8B0B04D8EE1DC3
+:10939000238C4F5B395180D3EB6E17C6F759532E90
+:1093A000F4F7F5CD13FA6FD8B84880B3EB7F258C6E
+:1093B000EFDFB454E81FE05F25F40FDAF78400E72D
+:1093C000069E15C60F695D27F40F6D7B55E81F7E5D
+:1093D0006AB300DFD8FE9630FEE68EDD023C821CCA
+:1093E00010C6171A0F09F048EB17C2F851F15F09C0
+:1093F000FDA36DDF08FD63337F14E0E53CCE2975E6
+:10940000FC4DB82F4096A5831CA725B987F7C1BA94
+:10941000CF292DE85FEB1D128985FC67DF242BEA3D
+:10942000FDCFCC030BFB70BBC8E5F80231DF09E7C9
+:10943000D9AF6617ED3C9E18298FC3F7AACED5B3D6
+:109440007A87DAAF2BF15C3475CBDA90E776731A52
+:1094500069421F84634BAC02DCDD152F8CBF6EAA02
+:109460004DE84F70670AFD89150E014EAECE13C64A
+:10947000F75AEC1460BBB744189FB6D225C0E97503
+:109480005385F17DD6B885FEBEBE0AA1FF868DD577
+:10949000029C5DBF5818DFBFC92BF40FF0AF14FA60
+:1094A00007EDAB13E0DCC01A61FC90569FD03FB4CF
+:1094B0006DA3D03FFC54BD00DFD8DE248CBFB9C300
+:1094C0002FC023C87E617CA1F1A0008FB47E268CC2
+:1094D0001F157F4CE81F6D3B2DF4577EE3F0E3BE74
+:1094E000D4DBEC7D57259E1B9BF983304E1747E359
+:1094F0007DA87F9348079CF7EF2ACE57E2C052C75A
+:109500004FC273FFAA61F1F9AB7DD8FB690FC82C7C
+:109510004EACF5BAF07C5E0C1C78A57A12ED955035
+:10952000FE20C59A8EF5C838F4B7E8326D70DE8D2E
+:10953000C6411488D1D8ED90879882716CD2A5412C
+:10954000D71EC736F52188C7C93EEED7402FE7D5CD
+:10955000BF510C79CE5CE25D017850BF1B0DFB580A
+:109560001F4688F528A51D6DA4740C79DEFE88BA07
+:10957000A48157D0DFD1C6B338BE735E5EAF92E828
+:10958000FA1685CCFF18CDBFB4544FEB3C54CF68CE
+:10959000A2FD84C78AF0539E78849FF6D8B05DE31D
+:1095A000C9C4F6598F03FBD77AF2107EC1E344D8C1
+:1095B000E729C1769DC785D7D77BA622BCC1E3C664
+:1095C00076A3A702DB573DD5D8BFC9B318E1D73D75
+:1095D0005E6CEB3D2BF1FA664F1DC25B3C6B106E6F
+:1095E000F4F8B06DF26CC4F62D4F3DF66FF73421F0
+:1095F000BCD3E347D8EFD987F06E4F00E1BD9E564C
+:1096000084DFF5B461BBCF730ADBF73DEDD8FF8192
+:10961000A703E1B37C3FE1EB3EE2BE9D021352841F
+:10962000F2A0C4BFE321EF01E1C8D37D27E43DAA46
+:10963000FC43CD8F33FC39BA021AFE42FCD33363AC
+:109640005D6D485EF0037FDE4391C41B41F5A1468A
+:10965000C3EA02353104DF0F233C3E9FC3E592C4C9
+:10966000B1B87C36C76B0ED7835C90CF4C94CF0FCC
+:109670007E4E9EA5E4DB51296E2993E2312F59E3FA
+:10968000C5BA8399BD873F20C5AD85EBE7AAEF7EBC
+:10969000179F677564C0434A0DFEEEB7423D69BF30
+:1096A0008C75D8AE9E57C5DF93E8B27FE7E924F00A
+:1096B0004725FF90B15EFFA1CE3215EA2D3D32194C
+:1096C0005D7A646A84F6AD145777C0E7647AF586EC
+:1096D0007BA5E0FBFF132035A77A5E466C3A3C87FA
+:1096E0004B9CEFC0AB37B7D0800FE05B89175B674F
+:1096F000B23B25B33B9C97F421EC1E664809B71E8C
+:10970000353E99992C7ECFCCD408ED9F525C7D00DC
+:109710009FE3E94E011F732F1B3F57DFFE02E0F569
+:10972000971D3F9C90D282F456EA1B2B46F0735A49
+:109730000B25651F9CC58946A2C489D83FFD7E566E
+:10974000EF51FCE5E1CE96D9C373D53AB49BD3A5CE
+:109750004807C4DBE7AAEFEF0FFB8577D07C0FF655
+:109760004F153B3A9DC21A0A4F27ECDCC5F4C316CD
+:109770009433B57DA5F711D8EF9B4E4906F9E3A5C3
+:10978000143BAEE743D70F3A9897C4B5E37BAB548D
+:109790006E4A809EF386CAF8FD860F35BE0C494698
+:1097A00079D14B14FF3971545EC2C40B8A5C2CE032
+:1097B000EFE528D7A9BC4D047A7EB76D4826EED3D5
+:1097C000EC1C6A037AD66AD87B75DEF765762E03C1
+:1097D0004AF9706E243AEB457CBF00820BE0DF5003
+:1097E0000BBE5FD02C93C56F84B1A7F772B9FA3066
+:1097F0005E57E2C379C57DC54ACED74ACEEFD2DDEA
+:10980000FB93E1BDC105FB749817919CB62C57984A
+:109810007355558B1FF945EF1039AF6A3AC6CE63C1
+:1098200091B6ACD073588FF07915F992F516F78B85
+:10983000E650FC3AE57C11D095CAF90988FBC71BB4
+:109840006CD1B7D25BDB2869FCB475FFCE8AE7F92F
+:1098500094737DB3880BDB3994DD20D72EEF6A7CBF
+:10986000AF7E1EA9C7EB0BF266A6005C45DA8BE261
+:10987000E97CB7ACAC79279E6237A96EF548A8732E
+:109880004FF4CD7807DAB2F5D209AF0DF5A416F88A
+:10989000D026552FEF499F77FBA611CBA18E3C5EBA
+:1098A000667C2007181FA83C39E598CBD747F5629E
+:1098B00015E04FF502F157F462FA52E294E282EFBA
+:1098C0008174EA49DE3D7F4E843D166D3B9E43A97F
+:1098D000DA698881FAC93CC2FC76B00EC4FCB5A234
+:1098E0000767748CEF675E93F03D9B3312C1EF39CD
+:1098F00074153728F127D53FA677474D4CFE655E96
+:10990000D74B71C70F4C0BFAE7331ADFE0A834F4DA
+:10991000DF1B801EBA02F7A303E0BCDEEB92A39626
+:10992000E272A69B2F859D13E8F403E49229582741
+:109930007C4CC7EA76EA7857594757781AF4C40B33
+:10994000FB5952DEBB3F411C7239BEEEF8C1942E6A
+:10995000B5C022A84B16B86CE1F058C69FBFEFEF18
+:109960002C1FF726133C17A4A6A76465CFE9AABE4F
+:109970006A8864F8287E4AC1F372BC18BF0E66324A
+:109980007BA1E0478835D34A9FAFD5463A405FCBAD
+:10999000B4EE00C887527F53F2E27DF693E80FC819
+:1099A000C5DA2476FED8DF951F3EDB998FA706FD2A
+:1099B000A452C722F9E1EB912EA315EDD744E24062
+:1099C0007FD1971C56E885752C197608B1CEEBC669
+:1099D0007518C05ED33602EA28E82F7DB82E13E052
+:1099E00085EB0A404584AC3645211D86B512B4D3BB
+:1099F000C3600D74BD3B8E111F9CA76ABE30A5D0FD
+:109A000042FB777CABC53CE819D3EB89F01D891D7F
+:109A1000A73F4D847A4FCD854684079F2D3ECDEAE2
+:109A20006787A7C17C6F9FD7DB0C18072C443A28A7
+:109A300075CAB70971C03E68DE67667CCF38B7A5C6
+:109A4000DE8474E375B57CBEEEFCF3AC1EB213800D
+:109A5000A1340F68D7137F48BCACB38A701E09814C
+:109A6000EDF0480A87D4397E6EFE68EACBEB2043DE
+:109A7000C890D0BA1AE98809FB3E957A1F3147622F
+:109A8000789FC874C5F5C5B86CA2CCE8FD0F19E87D
+:109A900075B3D99700F16DF3DC0D0910EF3E63FA51
+:109AA00007D2F1D9BFEB1380AE7523FE827EA48E60
+:109AB000DE1B80FC57EB8B2058FF9A8F75E09BB91B
+:109AC0009F7DF6E297249ED2B32E8FA0FF24DC0F59
+:109AD0002BFD7517CF55003F2FE41B6D60173278B3
+:109AE0003DB4E6A6FF17DF16428F1D34AEF65306CF
+:109AF000BF4DE36A3F8DFDB7D1B81A6078EF14DA35
+:109B0000061A5743EBA37135B42FD0B81AC6415C7F
+:109B10000DEDB334AE86760D8DABA17D9AC6D530F2
+:109B2000EE291A5743FB048DABE17ADDC5F242C43E
+:109B3000A795E0FBF54B4D511AB0AF14FF48A80BA9
+:109B40007DE41C1809F4B8E9BC46E06FFED9480171
+:109B50001E763C26C85FE0FFE19E42FFE09654A1DE
+:109B6000DFEEBD5E807B2D1E28C0501F0ABD3FB1B9
+:109B7000A2408013DC6384F1D74D9D28C0DD5DB722
+:109B80000BE3634BCA85FEC7A3547CF4556A443E7D
+:109B9000B2EF2B5CC837E3F9CAAEE4F409CE17057F
+:109BA0007EF297F2D47075DBB97D35423ED093E3F7
+:109BB000B6B0AF0DAFEF3D32E4958C1CE087866DFB
+:109BC0009B3ADB4DBD295F329ED410385788270E53
+:109BD000287E567EDF9305E74C20977B4AF511C01F
+:109BE0009F5DCE8248809796EA1342E5A8CEEE1E8E
+:109BF00088EF29B8D9FA94FB1F2F9878C57DF427F0
+:109C000040FEFA5CA17FCCBC54D087CBE8482A70D8
+:109C1000BF3648C789F87D27E2AE10F057EB0581C3
+:109C20004DFA0478AE51A4A733F561A0C3B34F69D0
+:109C3000F11C56E77CFC7E65BE91F245535BD6E590
+:109C4000F8EF72B2F134FE8D00BAD06709F8C5386A
+:109C50006C23803EBFE5FAF6DF5CDF9EE17C853C4D
+:109C600016606265F7297CABAB78627406E84D1E1E
+:109C7000C36BDDE427243037B1C451630DA1EB532E
+:109C80001C8F17F8BAD6C2BC14EE3ED92901FD527A
+:109C900016BB24D0B75E4BDA107E96EB7752753B3D
+:109CA0005E4FBECF8F6DCF8A00F68F9437E13A3A80
+:109CB000E9E010E9A8E6938FAF47993778FFE6FD12
+:109CC000206F179C0CFF28AFD909FE22CA6B75B014
+:109CD000D6C65B8703EC7E94D7C9E1EA2C801BF8DB
+:109CE000BAA2BC5E847D7C5D751571FB37D882CFCE
+:109CF00023B62A4DA8BFE94A9E9A38FD1B399DD448
+:109D0000F735E8BC83AC61F44A69157F3AB44D235A
+:109D1000E8F99056D14E7D04BF303FF0495F881B73
+:109D2000BC2E99EF5F211D2775E64BD3519E569BA4
+:109D3000EE3C00F9F6E41699307F3BFE1DB09787A4
+:109D4000461BD09F368F1E951C2A77CA3AB672BA28
+:109D50000FF53A8FDC47C797B90C8021755FCEE4C9
+:109D6000FBE97CAE71B203F6A15A3AFD89CBC4CEB1
+:109D70003B307F3291E3BC7BDCA447E0F9875AA8F3
+:109D80005DB005F154FA1B4A268DCD063E06181F1C
+:109D9000BBA2CF7B9C5FEF70BCF6707E3573F9DEA3
+:109DA000C5FDC90EEE4FDE067F6200BF93C7D7C365
+:109DB000FC4903F7277F047F42DB03DC9FEC077F2E
+:109DC00042DB9CD169456837E12536F4273441C12F
+:109DD000F3040B847529789524C9027F8AE34C0229
+:109DE000FF8ACCB1427F813651809D175305F8A67A
+:109DF000F3D7ABFC94E857861D1FA6F25305023C2F
+:109E0000B8658C70FFF89C49023C2E6B9A008FE974
+:109E10003D538009DF0FCB65BF93DCC8B532E6B98F
+:109E20007CDF4989A70E95C8B86F33F413D911AAFE
+:109E3000B7B9A4739F4C03FB64347CB16995F952A4
+:109E4000857E8CA35A74AE4438BF575346E590B60E
+:109E5000F92D344EC3E223956B1AF7E6BA46611C1E
+:109E600048E3A541C88776B6DFA4EC5B0D55ED3F0E
+:109E7000B98AC4FDA9DCABEC4FDD747D1771597E46
+:109E8000EC35C56554BF30FE7AC674E71E909B6DF5
+:109E90009FD13815E2DCCF7E81F1D7073094EAEB11
+:109EA000D6AF7F81F1EDD64E7D710BFA92CBF5B630
+:109EB000B125B5A98DEA5B4E37C9C1498DFA92C764
+:109EC000D794736CD1348C775A34187F91922AECE2
+:109ED0001FCCEF6F685D6A12DF5B0A897B306E8F83
+:109EE0000CCA0BE4932446ECB786C8672A635AE889
+:109EF0007842AE57CD3750050F538D2F50C1635464
+:109F0000E327AAE0DB55E3CB85FEA6B689578CBBD9
+:109F100015BBAE8CCBD5BA644718BB3BB8458C0794
+:109F200089AB4A38FFD07C6436DACFC6C32B389F62
+:109F30002A043EED569ED342E99D75F9FD055AAFC0
+:109F4000A91F95878216ADA3C616E4A3C22702797E
+:109F500071C87C854659D0E3A656E61FBB5AE74E2A
+:109F60006EA7B7737FF3962A8E93FF7EFED0042AE6
+:109F7000278D6D1ACCB31A5B0A62F1FDC18BB31049
+:109F8000DFA6560DBE4FB6F1D5F1B7D46883F829D8
+:109F9000F8E47CB2D404E7832E507F047296A37356
+:109FA000C65AC3D05D2D5F5DCDABC82F25542CD0D4
+:109FB0006517F547787E98DB55852EBB8F3C8D74F1
+:109FC000DFD6CAF0BDB943F48737B68BFE70F8A967
+:109FD0001801CE39C6E242EA7F71DE1C7EEEEE6ADF
+:109FE00078ABF502764844B8A738FE1AE3826D5C78
+:109FF0004E1A389FB64538A6867BFFA8E1A8BE2238
+:10A00000F4FB0A27AF67F5B993D7B3B83BE79806D7
+:10A01000F35CAAF7686F875AEBE4EA30F30C3BAEC7
+:10A0200051E52D9102FD7E6EDEFAE5F57CDF53658C
+:10A030001FBBBA5FB18F05CA77541C93C29E930DA4
+:10A04000F2819FAF54D19338C2DBDFCBF9A69C4B92
+:10A0500057F1AF8BFB83F378D579F5A5EB619EB60D
+:10A0600032F43BAB4D0BB85D5F8076FD839FB85DEE
+:10A07000FFA93109AE1F18B03509F4E840AEF23D32
+:10A0800058CABD907C5AD1A3F75B3E3685C6FB63A8
+:10A0900038EE3B320F8DED1FC2CFAEF0DCC7E5E7E7
+:10A0A0005D1EF7ECE57ABE9BC73D7E887BFA803D5E
+:10A0B000C8E4F680E5D16FF1B8A789C73D8D3CEEC5
+:10A0C00039C8F3E88F20EEC13888E5D10D99F7E261
+:10A0D000F7C52E242971CF786D383E8FB689766A00
+:10A0E00054BC4990B7915631DE2934260AE3479093
+:10A0F00034A1FFE68EEB55FA2DC63BC34F8979F4A8
+:10A10000D036318F1ED22AE6D1138BC478C7952F53
+:10A11000C63BCA3EC22EAB84E7B1C6E788F1CF2E5C
+:10A12000F885F63718D9F9AC86CC4957B4C37E6E9A
+:10A1300087FFC8F5FB3DCE9F7778FEB093D37F07AE
+:10A14000D01FE3521667E69E77EF89B6817DA8603F
+:10A15000F9426615E6D537725CB67AAA597C7A411F
+:10A16000637650BEEC32B3386B57E6CCF3F0DEFFCB
+:10A1700005ABC906F599033A37C2BB32251B7C6F84
+:10A18000508D5F6EABCACFF1784191CF5D2D5FA24C
+:10A190007FDBD9716D7E5519F71E998475979B5A8F
+:10A1A000083184A92F5CCDBF5EED39EAF1E0C7C369
+:10A1B000F91FF573C674B86542F577476BE04948F7
+:10A1C0008BC6F8E7CAF05DA8C1ADEE42E0EBDE4C0D
+:10A1D000C90AFBE9745C21EC4BBC77F1E3B1707DFB
+:10A1E000E779ADC680FB4E56C11F7D7091D21FE44A
+:10A1F00025939D4FF2B77EF9487FA8F31A657C7FBF
+:10A2000064D7C58171A1747BFC0619ED4A43964160
+:10A2100003F5E686F35AE20F89F71A3B52CDD036A2
+:10A2200064CAFC7A00EDC37337B073AB3BE87CCCF7
+:10A230005ED8100F451EFCE73525E1BEBFF31C7F3D
+:10A240005EEEC53F9B20BF7CF77CB909ECD3CE56B0
+:10A25000F69CDC256D26A0DB818E7566B8BE2B735F
+:10A2600010CEDF9CFD907920C84DAB86EDE7F0F86D
+:10A270004679DEAEAC398F0E8075B7B2BC6CD7F9BB
+:10A28000CD7BA2402FD64B0E16BF307BA68C6F38ED
+:10A29000CFEB4D3E76CE2D97783FCD06FDE9F17B95
+:10A2A0003DC839F1569250FB576815ED4841ABCA8D
+:10A2B0004FB92B511F143E946A6385FE039F4D9C3A
+:10A2C0005C067C33B3F7DB769E5F1A3711F4C2ACC1
+:10A2D0006371B38FDD3F2E58AFC1F7B594EFB0D4A3
+:10A2E000643F70A814EE6F607CCD358BF81CE85B82
+:10A2F0009BB880CED7B0C5E410D67798E0FA76390F
+:10A30000DE9C8E75ED2C03EA61E185BDE6B6903AE0
+:10A3100051679CD8B2DB3C08E87C5623D04DA1C3E2
+:10A32000A83C317FDC91B907C75F38CBE89E4BAAC8
+:10A330000FF567755873E9E060FE95DBC1EAE373DA
+:10A340007D22DE43378AF9E77C557CA4AE9FE76720
+:10A35000CD1927E4573C6ECAE37193BA4E5EAA3515
+:10A3600088F509559D3C575D27FF67E3249D7B1ABF
+:10A37000BE0F17987C4DF1C3501A6BC6E3F95EEF20
+:10A380009320D76FF1F872A8BEEEDE04AA220DB2B8
+:10A390007B38EE5BF03A9D72FF55E325AB97C40D19
+:10A3A0000EC98789F604E4972B618F13F9E265E7FC
+:10A3B0005955F376156F28FB23F945CCFF3C63FA1A
+:10A3C00010E38BC6AF597C013F6D3D60BF9EA01F5F
+:10A3D0006EFE5A8FFB276F8F66FBDE4ABC328938D0
+:10A3E00071DF667CDE79ED6F6CB09F7367F67CDAA7
+:10A3F000BEFD5923E6996F77E69975429E99CFE5A0
+:10A40000725BBBC61B0BF941ABC14742F6DB95FE45
+:10A41000C6F6F247B2410E031A94C3E66FF504BEC6
+:10A42000BFD7B8DD8078379ED5633CBA6DBB89C98C
+:10A4300035AF3F2BFADACAFDE2A79C9F07B85FDC75
+:10A44000CFFDE27BBC5EF30E8F5BF6F07A4D338F6F
+:10A450005B7681DFA4ED9676AE774B4C1C4F569F12
+:10A4600055F0BCAB4FDB112DE56BD57783D7403D65
+:10A47000EA36B7A80FB74E15E3937159627C32A63E
+:10A48000B7588F29494A13EE2F8EBB41E82F320F60
+:10A4900012ED9676B8003B2F8AF1C984BCB1A23C7C
+:10A4A0003943E213CCAFC57CF796D07CD70E7C62E3
+:10A4B000F9CCB6D627D04F6C3B9E1A1DFA9DE0AD65
+:10A4C0009CCEDB8E33BFBCF5F0394B68BFD29EE229
+:10A4D000E3CE707E9CE5FC9894E0BC238BCACA85D1
+:10A4E000E3E7F470FEA32B3956EE57EE3BE5FB2A6B
+:10A4F0002AD4EF7D0DCC08393FF46DE31719684F6E
+:10A50000AE512F6A2DECBC5B831489EFE15FEDFD4A
+:10A51000962559A95C29ABFBB3FDD1EA21D06ED0B9
+:10A52000B912E13DA806C9356D3EECF3FE561FF6A3
+:10A53000EF4AD46649CA39F426F00B32D76FB249D4
+:10A54000D2827C4570F045E2AECDEA0E45B16A1C80
+:10A55000249B5D04D6B545479AC0BF1327B1597BEC
+:10A5600010B655469FF3976CF7C3404F29C0F6913C
+:10A57000A95BC5EF7EC0112DF8FE16B4B05F663042
+:10A58000B2F70F22B3DC8FC3FCF05DDBE881306FE4
+:10A59000411ADB4FF5A39D9EC6E7D598B627E3B9D0
+:10A5A00055759EC4EDB5A2779D74AD14DF4B51DB9C
+:10A5B00059A5BEBBCDEE9A162E1F7D258BE59F4D6E
+:10A5C0005F8D97E1B939C62827FB3EA45386F7C1B2
+:10A5D000B69D18639A1146CEF6F69BF10AAC4781F8
+:10A5E0007302F532FF7B151AB1CEA5F103BF2F9888
+:10A5F000F5A8D74361C13197CFA7B6CF798755F674
+:10A60000B9739FBF4E8273679DF2040C01FE1F64F5
+:10A61000DFD5B89A3CA9F7EFBFC84AE5EF4D557FA3
+:10A6200001E74CE468339EB3D972D0B84EB65F9E52
+:10A630001F36F0BA9F1AFFE6CF6627621DE993D94D
+:10A64000ACFE07861DBF9B563D05DED3EB8461FD46
+:10A65000D00F1FB4C3EF002D60FDA315B86A0AC464
+:10A66000AB5B47B0F19F6F0A3C0DDF05DB7A07EF6C
+:10A67000278FB1F10AEC5D386504C03A568FB9E511
+:10A680003536FEE2F5CE2F803F9159CEC320A7AFDD
+:10A6900082EED0B6E87AE751B8FE05C8186D3FEEF5
+:10A6A000EB6C837E05EED6D7F965687F6367DE2B9A
+:10A6B000D6FD8728F1E0E1727E5DCD77C5AF5CB94C
+:10A6C000DEFF2197D30FB89CBECFEBFDFB78DEFBFE
+:10A6D0002ECF7BF782FFE803F9B083E7C3793C1FF5
+:10A6E0006679D7769EF7BEC5EBFD4D3CEF6DE479FC
+:10A6F0006FCE271359BD1FBE3B2841DEDB2F6CDE1A
+:10A700003B214FF42BA50ED1AF8CCD14FDCA685B55
+:10A71000A22A4F4E53E5C93708FD85C641AA3C79A8
+:10A72000B82A4F16FDCA8DED635479B2B87FFC4547
+:10A73000968DEF27DDAECA97C57DE4201FBBAA47E3
+:10A740002F0ACBC7AD2D8B0E5CCBBECDBFBB7EF130
+:10A7500021E7E3079C8FEF2BFB369F7C8CF9DD858F
+:10A76000F384F3F175F9FF62FD6242DEA4B07C2C44
+:10A77000754C53C9DBCC2EF8F84FEAA3F9CA75A87B
+:10A78000FF943ED6B6C4307DD42A75A8EFE470F1AC
+:10A79000CCFF357DA471C163D9D7A08F6AFFAEBC51
+:10A7A000B7A8C40D9D71028FC7947C690BA5157C59
+:10A7B00077A22141CFBEBBA175F784B843A1D7EFE3
+:10A7C000B259BCD3F8C502D48BC1E0CFC3D0F55584
+:10A7D0003EEED56C2BB6F09E64E440382DED65F16D
+:10A7E0004FF4382B3B5F4502F01DAA2BC44DAF66DA
+:10A7F000770FC64B5A6B35013ECA068D17BEC34B49
+:10A8000064239EBF6B80380ACE59ABE2A82FB3ED0C
+:10A81000CAF7782598F70B3EAFD4F22E9EF3FE4B85
+:10A82000B6730BCE5FE868877DC8C6237ADC67699C
+:10A830008C60DF4351C75B1F6667F0F79719FDE037
+:10A840003D805F803F850FC6A2FFFD52F49F1048F8
+:10A8500050784324EB0F647F35C59B14F4D79FBF1A
+:10A8600076FE69F8BE6C86B9E74C383F20ADF1C67C
+:10A87000B07D4B3FEA973A6EEB32FE55C5697FCE0D
+:10A88000747E0472720EFC72773C5FE5D40EECFAB3
+:10A89000FE0D91AE7BD877619C323C57A153A7FD4A
+:10A8A000CD6671DC877CBE4EBA287205DFA98909A6
+:10A8B000791F5685BF42AF1507F704E028E3CF5D47
+:10A8C0008FB28E30F2E3BA4ADC7D0EE8A0961F32DA
+:10A8D000CEC1DFD70D1FF7E9781C19CAFF61B82E6A
+:10A8E0009FC27F327220BC07A3BCBFCEECA1F2EEA8
+:10A8F0004C8CB5CE6AA77A74678B8CEF1F12BE1F83
+:10A90000AEEDE467BE04F6495B2C91D890784F5DBC
+:10A910008754C7A9EAF365F9677B0AF04DE75355F9
+:10A9200079E4F5AA3C73902A0F15ED51715CA130C2
+:10A93000BE2469AC2ACFBDF239002DD12ADF1BE23B
+:10A94000FBF6920DBEC3A365140AEDE7DF0362F4C4
+:10A950005ED6451EA49CA3FD4BB60DC775EAC75A2B
+:10A960006263FCF30A7F1F4A1FCFF8FBF860C58FB4
+:10A9700039B0EE6EF0CF657FEFC921BE4FBCCE631C
+:10A98000FCBC4807EFD990CF8BD2F1FC0EB62F78E4
+:10A99000E2B15DEBB161FBAC2713C7ADF138107EBE
+:10A9A000DA9387ED531E275E7FC25382709DC78561
+:10A9B000F0A39EA9D8AEF2B8F17A6FADDB0B7F1F82
+:10A9C000B1F74A82E74BD3EBE8F342E89CB692E258
+:10A9D000114247BBD72AC0BD16C70BE393AB6D42EC
+:10A9E0007F6245A6D09FE07608F07553F384F1DDD1
+:10A9F0005D4E018E2D2911C67773BA04D8E2982ACC
+:10AA00008C3765BA85FEDD370D8B6EBB823E3FE12C
+:10AA1000711E013A3CEA711D29C2F7A44A105EE595
+:10AA2000998AEDDC7EDD50AF62B401CC8F6272ACEE
+:10AA300060B121BFC5FDBF58AD43EA16327F6C0936
+:10AA40009D4FC097CE27D4277D389FC5E13A22E29B
+:10AA50003D55B88F3E0BFDE4043E66A49C64817CAA
+:10AA6000EC607E2C7EB7F5119DB53487EAF1479FE7
+:10AA7000B0EFE4C21626096347BFE6718DA99F11A6
+:10AA8000F3C5094F4998DF11C2EE9FDD92E608FD3C
+:10AA9000BB504AFBD1AFD977874CBBB7D9403E26D4
+:10AAA000E4CF888D08D97F99E0FFA92801E71B3002
+:10AAB0003882CACD843533F433B382EB53C6CD7EAE
+:10AAC0004AACFF06E5DF67E4711CAED3C0C7AC4AF1
+:10AAD0005A87D757655E79BFE60C5FD7291EAF9DB1
+:10AAE000E071F7715E7FFB92C76B6D3C5E3BCAEB1A
+:10AAF0006F8779DCFD39AFBFB5F27DAB4F79BCD63E
+:10AB0000C2E3B58F79DCBD2A7333FE9D980B9BD8C9
+:10AB1000DF25EA0A9F7B368AF1DA5C9F18AFCD59B0
+:10AB200023C66B77D789F1DACC9562BC36C32BC6C6
+:10AB30006B772D16E3B53BAA45FB38ADA250806F6D
+:10AB4000738B75B95BA78A71B7C2A75B5CA29D9C2A
+:10AB50005422C6DD5DADF76DFF68DC7702667E15B9
+:10AB6000E20F43BE0B2F9C7BCCB13A0B61FF2697C3
+:10AB7000B86A61BFE6464DE010EC33914F65FC1EAC
+:10AB80006413DC3194EAEB85C1E326D842FC8E578E
+:10AB9000949FE987C5F311B7DF27D2B5AC52AC77E4
+:10ABA000EA4B44BA3A93C4F36793547E87707FA804
+:10ABB00067BF9322D795FD90C65489EF2DFD5C7F2A
+:10ABC000A427EA7364CC1FE17353857EF447C6FE65
+:10ABD000EC7DA5C1FC7D859A88211FC0BEDDEECF2E
+:10ABE000D87B0694EC81DEF4FE9B08A3B7DE380A1E
+:10ABF000BF23B743C7DE1FD89560762CA55D375DB0
+:10AC000064EF09900E2D9E2373C3FB23A930AF7808
+:10AC10008E2C37A015CE99E955FD89E013AF880F2A
+:10AC20003B4FF79FC3879FE3E84FFAE3F988B6F0FD
+:10AC3000EF1D74C6712AFF1CBCCEE456B147397EA5
+:10AC4000EF213B5D578E2A5E32F075694CD3F1FBE4
+:10AC500063864F09BE7F9FA7F1C6C277B6C8390D7C
+:10AC60007EF7650411EDC2E47157CEC747C58B76F8
+:10AC700061B42D4D95F7DDA0CA0B45BB6020AA3805
+:10AC8000A78D9D4F34B09585F623DD26F78F51DED5
+:10AC9000DF417AD51C5B81E7EFB625F3F751B85C4D
+:10ACA0000DE7EB1D9EC4CE2FE6F17A71DE0F8B64AB
+:10ACB0000BBD6E385ECCCF312E71601C7B96F12BB4
+:10ACC0008FFE037EE69110FE013F0F8BFC34A8FA45
+:10ACD000E7807CE586C387C9D57F1E1F7E8E529193
+:10ACE0002F73CC55F6EDC2CBD788805386F783DE21
+:10ACF000B14AB82FFD4EA03A00DF89FC319ED5271E
+:10AD00001E4A9AA865DF6D719A4752BA17F375E625
+:10AD1000F17DB1460F09405CB2C563C496906A3CB0
+:10AD20001FBD227E512CF8CBC61477229C076CECF9
+:10AD3000DE6D199C1368D0754B0AF71E41B36E087F
+:10AD4000FAD7C6E6042D7C577E84D6AA85FB462416
+:10AD500095CB90278E82F74DE20026B81FB6C5E34B
+:10AD60000F14E1B950379E1FA2EB2884F8B5C83AFA
+:10AD700003FFDE63F32754FE6D101777C37DE3BD39
+:10AD8000DDD9F96B83959D6F2D8E63FBB0390EF67F
+:10AD9000FDBE9C24B3C307D3C5B3EFF854D07F974F
+:10ADA0005283FE81EABBF07D9F212404B6237F04F9
+:10ADB000F839357F54E71157B4F273736DE1F76BCF
+:10ADC000FECCE309E57CFB611E4F7CCEEB3F0779AF
+:10ADD0003CB182C7137E1E4F1CE2F1C45E1E4FBC05
+:10ADE000CBE3897D3C9E789FC7131FF07842910B7F
+:10ADF000C34A6233C07BB4C904EBF2F1CB245F09D0
+:10AE0000ECB3BB196C98C5F64F7B25D5B90AE2A007
+:10AE10005FE718057239D53B12D6113FBDBD02C69A
+:10AE20002524E96D4E3BBC9FB40ADF2B51DE0B9B02
+:10AE3000C5E5E6367731DADD595C4F88BC3617F365
+:10AE4000D33AF1FB71096E5DF0BB49F4FF0C157D3F
+:10AE50006F537D57492F317BF1BE6277079141A136
+:10AE6000748FE7748F98C1E90E2F5D85D197359C5B
+:10AE7000EE0A5D9A6F1A6661EBA810E2C243F963AD
+:10AE80002C206F2D497C3EFEBE8C8B3F6722D70F56
+:10AE9000655E657FF6F1822B9F6FFA888FEB848168
+:10AEA0002FD121F3143CA883EF92DFEAFF6532E84B
+:10AEB00049F07D1A07C6E123E5FC3F423E1DE0EF65
+:10AEC0001F28F6720AE1B4523DEF90E7CAEFED1C7D
+:10AED0002A18AB83EF764FF6FF12FFDE83415B1D2E
+:10AEE0001F7ABEB785E3F750D9BDF877E00229EDA8
+:10AEF000F8BE9AC165B0417CDE2BC9B11CE8179F32
+:10AF0000D456C4EBA12A7FB5B6390EE4AB1FFB368D
+:10AF1000E2FF072D97429600800000001F8B08007B
+:10AF200000000000000BED7D097855D5B9E8DAE79F
+:10AF3000EC3364E484C98326B813A658194E263826
+:10AF40000987B003C1460D7002018284709230C43B
+:10AF50008A367632BD8F363B24246110F03EEB8377
+:10AF60004AF080436B3FEF355AEBEB40FB4544E53D
+:10AF7000BE673128B4D8DB62982CB7AF03566BC7D5
+:10AF80007B7DFFFFAFB5CED97B7312A085567B0BBF
+:10AF90009F2ED65E6BAFF5AF7F58EB9FD63E6DA56B
+:10AFA000255903A98C2D0DAFAB645319FB00FFCCC1
+:10AFB00066CCC354632097E11FC7070AFC3FCA341D
+:10AFC000753A3EC7279676F64136FEBF9985D3E09F
+:10AFD00079E5C7FF83A533B6983507FAE0BDFEC211
+:10AFE000C0281F8CCF6A5C67B17F2EFCFD20273EF6
+:10AFF0008F2C1733F5AC79BC9420F4F78A3AA3F977
+:10B00000E27568EFEA669A671854FE04D08D86F7F9
+:10B01000B14D83E72A4BF34D86792B3FEDD5A1CC7B
+:10B02000C974D47B605D0BB33EB5928D843EF33D15
+:10B03000BE09005757A8E8270550EFD2D769B83C9A
+:10B04000ECB70EFAFDB0ECBE2C6D721CAEAECDAC02
+:10B050003402F374657DCEBF360DFBBDDF1AC17EB1
+:10B060002E56D30BEB3A31E7FF65669BFA3F3DADB9
+:10B07000ECE6C02818B002FE3786B189EE484E6073
+:10B08000F2C5EB65CC600CBAB495263356C8D8E946
+:10B090007A25EA01406ABA017F53B1FD42133E8F1F
+:10B0A000747BB42D0820D353E7C33AD77014B0C8CB
+:10B0B000848EA23E58EF9A6E4E37F6A0EB34E2CF64
+:10B0C0000B7F11BF59CDEA6933FE224C3D6DC66F2F
+:10B0D0000D33B543DD8D7300BCE581B4916FDF0C9A
+:10B0E000FF2E60051F3839FD11BF35A26F52FDE2FA
+:10B0F000610CD6C3FC80BCE28BD7B5FC774ED6374B
+:10B100008211C3B0A2F8F337578F4B8EE07BC8375C
+:10B110005EC157D388669A1BF82A199FE460C9DB81
+:10B1200061692F105FB5B8E27C96836CE63262707D
+:10B13000E758C66308EF52731DDF37F4E3E301FEFF
+:10B14000958CF3C7CA505325F227FB0CE72F2F3CF1
+:10B1500014E3C4F90FC6A90ABBE27526E8355AC044
+:10B16000097F96943FD6FB6F30FE633BF3E7235F86
+:10B170002DF9829339A15E0DDDB05E5DA344A380FD
+:10B18000D3A5A15B889E4B6DFC9D5C6D1DFFAD0D35
+:10B190000534CEAA4A180769B1C1D44EF0ED247C1B
+:10B1A0005631DF26942789D7B7B3D97806787C61E2
+:10B1B000F7BABDC82FE71EF0300FAE1BDF05BCD6B7
+:10B1C000730AB2E3691CAE9F6E56A2FB61FCB3BB6F
+:10B1D0003DC4776FAF51A20CE9CF7C4FA0BC76077E
+:10B1E00032689E734991BD9F87F686AE9480017840
+:10B1F000EB1EDE7C4F18E63D9711A9C3711ABA6E9B
+:10B200007618D83FD9F0E6E0B80DCEC07E9862B986
+:10B210000A381D0E25FCFB0628EBBB4DF482FF8E81
+:10B220000614E2FB050E16E94DBD987F92F2149AC2
+:10B230001F11EE31C1BF20C741F09E78D043F0A668
+:10B24000E469344E7D30494F4A473A325DCD077844
+:10B2500032F5B108E75905E413F8EDCC12C540FC0E
+:10B2600030800BDF77DF70FD3E94A727C43ACFDE36
+:10B270003F632CF2F3990CDE7EDA9F1CC5759DD6D8
+:10B2800078DDF0A7461F477AA891DCA5697C1D0AE6
+:10B29000F0418380AB4173E84940DF860797DD8545
+:10B2A000746EF06FBB17CBE369469A02EFFF74B779
+:10B2B0009321BE111FDE7C6C2F5987ED76BCFC3AC2
+:10B2C0009043EB41FC8D00BCBDBDAB3D2D82FBA688
+:10B2D0008F45DCA3E378A8DFF9BFEF53F07DC6F715
+:10B2E0005FAF90138599F663E0DFE59ADBA8807184
+:10B2F000D8A1F1C4B7CB7D9CFFDDC59B46E5F06EC0
+:10B30000A931FED0A8BE0DF7F70651AF47BE05BC68
+:10B310002E4779998AF8183E1DF79B9AD5D67D79E4
+:10B32000D3C88DF72F8675AE09BA9813DAD7F855BA
+:10B330000B5F57B558F91CD66DA9FBF218D1A17B4C
+:10B34000B8E0CF4ECE9F8C85C786A7C4F9E2CB016B
+:10B3500007E107A1730D817F3B5E3F6A78388DFC62
+:10B360000AE7CD992C6D6F318C77A61EF887C3C57F
+:10B370009C2679A8EFF610DFC3CEEE463C017FBADB
+:10B38000ABA6C4F945E2A77E571BF163BDE0BB86BF
+:10B390006DC03FE9263EB2E10BD7ACCA79C6C5F90C
+:10B3A0008CDA13F0D977021C6E297FF52C5CC79CD0
+:10B3B00017CBB52C89CE2548CFBB6A8C4C1CC52039
+:10B3C000BAEE282D1946FC2EE8A1C6E9E145BAA53A
+:10B3D000CBBAC18EE17E9E26EA192DCA9BE505D027
+:10B3E0005FD0C9533E10ED83A6E12DCE37CB475039
+:10B3F0001F4D85FE23043ED881194F4F1C1D3F6F02
+:10B40000D2C479A03A33C7607B3AB3EA3D236CEBF0
+:10B410006785AA3837F839FB80CB3706F7E364B184
+:10B42000BFAF9B374EC17E0F280AED3F9E0AD5C2A3
+:10B4300027AA4D8FC9C97388FDCE90FC4DE7AD5B3F
+:10B44000E83349631C2417BFC984035589E3C3CD7E
+:10B450008760C3FBB4DE3E68AFF37B035186F0F236
+:10B46000F3A10C88D067E2AFEACA14D66782639E64
+:10B470006F84A5FE71FF0D96FEB76AE32CEDB7E76A
+:10B48000DE6C699F1F28B0D4DDCC74AE239C031CF6
+:10B49000EF6E816753BB3C97FB918E8BC53A76B8B4
+:10B4A00023FE30E06BB17F2DD1A3ADF4137ED44BDE
+:10B4B0003D7E4E57B7D0279326ACF6911E51C9E575
+:10B4C00027087F910EED38C898389FB96DE7AD5DBC
+:10B4D000FEECFA64631EE83D2950F918FB18E93DBB
+:10B4E000A9C313EA3776FD0DCE0807F26BB2A0D7D9
+:10B4F0003C672A9D1B5DD55C9FEBCA5DC4F5A5DC4E
+:10B500004F125D17887ECC7090DEBA54AC5FEA5F54
+:10B51000AFB532D60747F38E12AE672D0D5EA83653
+:10B52000EBE5B2DC82FD26C5EBC9A17DBA9E40CF1A
+:10B530006C13FC95A2F3F6A55EA6E23924DB378AEC
+:10B54000F376A938B717821C23DF86B1349DCFDB91
+:10B55000C538DB63FCCAFAF361DD4E013F7B4A511B
+:10B56000110F49A2BA8F45B6E715219E0DEAE44CAA
+:10B570000D3392EF3F0176A1DF02D1AF2C6F75CF73
+:10B5800067817F3DD56901B42D3CC1FAC7BF54889E
+:10B59000FA514AC0A1C5F99DEC0EA88FCCE5FC5E1E
+:10B5A00093E90D50B3A11F1B0FE3558BF66A21CF12
+:10B5B000A35833C9C145768C97F3E5E0760CDF7F5D
+:10B5C000E47C1EB1AF30E78600F15D98EFFB0EF82A
+:10B5D0008B7CB7A4C6CA57CB2243F3596F9ED0AF1A
+:10B5E00067B019C46791F5C4171ED167C7D88361C6
+:10B5F00092F7A09391BC0BFB46EA9D47822F12FF66
+:10B600001FC91D50F5D438BF487D7C41C8A947B13A
+:10B61000BD9825FBE01C39E21AC87C00FAB954D663
+:10B62000A7E2DE2BF4F2F4E0B2DB7CB0AED78A5FA7
+:10B63000F19D4A6583EAF3767E9F08FFC07D7EF325
+:10B6400084B7FD08C76617345D8FCDBFAA4178B6B1
+:10B6500063BD04FB9FAF2983F6ED49B2FEEE2E6C6D
+:10B660007F2299D77FF5CC1F771921A207F14D8A48
+:10B67000C0778AD4CF279BF00678F68ECCA77DC4FE
+:10B680006BC3A75D6F770A7DDB69937FFBBC67A502
+:10B69000BC0B3A0CB6EE8BE005D6FBD8D07CFF8B0A
+:10B6A0003C3A0F9B2D7C7FF1387DA49FAF10EB7649
+:10B6B000A41CC88A2490DF18FED7BB7E6EB6070094
+:10B6C000CFDF5450AFD5E1EDE99C55701C25F8F261
+:10B6D000EFF17C577619C3118F4EE880E7B80B2C39
+:10B6E000408447CA6312F28113F1DE47ED709E0E6B
+:10B6F00028E370905A1FF2A702FD3F40FC5CEE3E2B
+:10B700005861B513DDB87E18CFDDCDCA3CE9683786
+:10B7100036EEDF5C88E7983B40FA57F78532A41392
+:10B72000B4EB1E2A2FE8747EFB1D9673E585D23F8D
+:10B730009C7F1458B3B3DF19F0C07B1DD800F074A0
+:10B7400086BECD50BF7E77320BE0E2EB22BE796E33
+:10B750000DE5A1EF44C784387C275A597FB92B5E89
+:10B76000EF3F98E4D660B111E35E2FD2E5AD0DED69
+:10B77000539E433B3BE8F1A1DED6BFB1DE40649C63
+:10B780001863F4224EBBD40843FBDDBDE17FCEC37A
+:10B79000FDF384CB080C87B27BE3CEBBF1BCD2B502
+:10B7A000CA8A6C807B7FB75A114D60CF7C229FEF95
+:10B7B000AF475EB873FF66F4378C710792609E01E5
+:10B7C000F45F00FDBA5C46168E7FA2AD3D0BE5A38B
+:10B7D000ABBE2B7010FBB5790234FF6E6F0D8EDBA4
+:10B7E00095B5D6BFD634BEF70677333EEFBFDEED54
+:10B7F0001E47EB7927CD0FEBE8DE50300279B373AB
+:10B800008C7B6C23B637AC631AE8856EBFE142FED1
+:10B81000F2AA6C17EE0337FA2F7C7F06DA439A639D
+:10B82000FAC7A1FF7D8148793ED0B1A6E5D43CD8C6
+:10B830000199BB3C63139E3F9D024EB90F49FA0E1E
+:10B840008C69F062BFCE4823F7B3F81DF548E78551
+:10B85000631C61DC7F3A436BBC13C5F375E917E3E6
+:10B86000A513FD2AD3104E58D714ECF77E6B04FABB
+:10B870000D64B96B12E13122F0E86D5F97D302706D
+:10B8800077EEF6FA103F9D4A64573DE0CBC84E0D67
+:10B890003CAE5DFCDE53E23DC91F402792C34F3CE6
+:10B8A0003B7AB7311EF5514E47C08BD7653A179F8B
+:10B8B0009E56B626DFE4BFB868DE319D741E742A3A
+:10B8C0005CAE9F7A76EA6E03EA8140E46E7CAFABB1
+:10B8D0001B78791AAD732CEAF383C9CF8068EF6CBB
+:10B8E000F3D44413C8FFC06A279B348C97D74139DF
+:10B8F00071A373AC92003F03590D39D9781E40BB38
+:10B9000003C619D8EDE5253CCF81E76F0EC29F53E2
+:10B91000F2F9793E796AB81DE9CF2647C88FF772E8
+:10B920005E7813D5D94E3FDA171F01FEDDF321E112
+:10B930005F3A0F23F937137F31DF708B5E3AD8FE01
+:10B940001916FB715BE91F9AF0FCDF5AECD13C261B
+:10B95000BF9FD4939327737D243CE1B100ECDC6C52
+:10B9600071701D3F2F2BB9FFCF077F13F9FFC23630
+:10B97000FF5FB2AD2EF5CF43F9423F117A70A6B604
+:10B98000333C07ED8B579D8128D03D0B5F1889FE16
+:10B990003125DA976D82F726B78097EB6B0BC57967
+:10B9A000F4A3562F2B9FC06276DB72B18E054DEF4C
+:10B9B0003C8676F402A16732243ECC5F3D999FDF3E
+:10B9C000D26E5B849D814597E772BB002C2B7EDE97
+:10B9D000382B8B901F1632AB7EB788D9F4B9D55C63
+:10B9E0001F93F6DA0A9BFE60B70BAA6DED3B60CEA3
+:10B9F0007ED4FB54B04600CEF782053B0A00EEBA77
+:10BA0000E0A14D0309F69BE378DEC07ADF68D5DF5D
+:10BA1000EC80736753F5D7BD03F0FE56B5D78B7234
+:10BA2000B2B5F2D36928275B6B9D248F475B2BA8A7
+:10BA3000DF6BAD612AFF2B3F23E6FFEA93F601C0DF
+:10BA4000B120A0BF8FFB8AD4D3AA2BCBDEEC30D1A0
+:10BA50007751F9AD967A3854F56687DD7F897CE6B3
+:10BA600064CD89FC6E530BA47F45B7F83999F3A9CF
+:10BA70004024417F59021FBD67C6576A8155BF3DAB
+:10BA8000129C3B6C28BD46AE5BE24BE243B60F0610
+:10BA9000EF6FF2A51DF297C19B7385F0DAE194F088
+:10BAA0000FD63F8C9B5909C2DBB6DC48453A46F2BB
+:10BAB0000B00CFD515192FA14FE20D95CBD31B7AD3
+:10BAC0005AD400785E9ACCEDFD945C16453FAE9D4D
+:10BAD000CE2915F5F3705FBB14BD93430AD9A14B72
+:10BAE0007425AAC33F6F1176E996C98CECD2B6D201
+:10BAF000AF1D4E2BC478878B897DA672BEC98E4A36
+:10BB0000A9E571881D6E16E8C3F7A6A40636C2F330
+:10BB10006A944394CFB0EBB4D90F0276D069B31CCA
+:10BB2000D9F79B145BBCA1AA40E8DFD301EFE3E2A5
+:10BB3000781FCC0E198C4FC07A28C2F3CA8EA77B0F
+:10BB40006CF8B1C723C207AAACED9769FFECEF2EE2
+:10BB50007C6924EA1BE54A6002E0E3756C82F79297
+:10BB6000F56728ECB1B940F0A5B0EBAAA55DB70820
+:10BB7000EC7920C111D40B86515C692CFAA5E3EB5A
+:10BB8000E3765C20A07FBAA06870388E89F7BAAAE5
+:10BB900012EB0BC7505F98C6CBEBA09CB8686E56F3
+:10BBA000227DE1587123D717A01DF58463BB2B7844
+:10BBB00009CFCDFA02AB28B8045EDA68BD49130A92
+:10BBC000872592BBD7A7457622BFCB7A4A6E332B07
+:10BBD00037F149539EFE4001C535B8DF41CE07E736
+:10BBE000FC21B33E669FEF997C1FC773C5083A37A7
+:10BBF000647929FAA9BE66867CB6D5A5D7609CC0B3
+:10BC0000EE377AA680C727BA73F4266C67A9F9972E
+:10BC100018B74DEED7B979A34D7E4B9B5D28EDA8A3
+:10BC20007DD868B20F551FB70F93332F1CF241D345
+:10BC3000DA82C8F388AF5917A286A310E3A90AE9EC
+:10BC4000519E4CE622FFC9E5DA6397D9AF7B23DF2B
+:10BC50007FBA1AB8DFBD2C4FA57A72C4B99FE248EB
+:10BC6000C25F1316CB48D6DF217B6C01E803C23FCD
+:10BC7000437AD509E1D70AB36617DA7DA9AEA8974A
+:10BC8000E2BE36FF4C4DA6A36F22EC1F35C10BD58B
+:10BC90001AC539ADFE9D1A2DE7D028D1EE83724129
+:10BCA00098FB7B96A2BF07C7AF8E76E7E0BE165023
+:10BCB000033AE3F61E9EB7CB1AEF9BF29076F5FCA3
+:10BCC0003DD28F24F546E9AF82F3A57B04D265AE61
+:10BCD000A2910FC0E60FB2FB7FC2C21F63F713D958
+:10BCE000FD42BF2DC8267A483D4CFA6BDE2FB0EAE4
+:10BCF00063FF09E281FDB614C35106F2BDC5C5B2AA
+:10BD000076C2F8E9FAB2DB705F7EADEC151FEA1B74
+:10BD1000FF5960F3675EE6FEF663D887CEA0BEF6F5
+:10BD2000E21817EADD55CDF5E437B4CB89BF90EFC3
+:10BD300073C985A99678717F6B8B783FC9C0F3A6CC
+:10BD40006ABC3B9A046BAAD2F938972B4F1979FA3F
+:10BD5000C8C25164978CC69205C02E99827689908C
+:10BD60007BC1DFAC7C143B638E937AC15E4933C3E5
+:10BD700021D67185F3238DCDF35C0A6F3B4A4BBC12
+:10BD80006EF447002C4ECE57BE989F3E07FD3BEB0E
+:10BD900035B35E5187F18902D43F158A53C8E7262F
+:10BDA0003FB98AFC9B9C19D1C309F6D5E5850E4B9A
+:10BDB0009C34E667CF65141792E3A8CCDF46728007
+:10BDC000B22AE17126F0C70B781B259FB380D78379
+:10BDD00071DE6D4EC6F30FB89CC8B8835A1CAEC84E
+:10BDE000C6F8F02625601014358750BF5F2DE4C8D3
+:10BDF0002DFC70F678D16A2957CEF5A4A735EEB49C
+:10BE0000C6D1EC7131BB7E2EFDFA2A4C82707F5E6A
+:10BE1000D2090E78E7D078D847EBFC3BC583E4C362
+:10BE2000CA82BBFC98BFD29914D9558FF1EB1E2F53
+:10BE3000F945BAB00BCA4B1FFC457F7B4FF0D12DA3
+:10BE4000F05E77A193DEEB54783ECBA1319FA3FD4A
+:10BE500043F259B7E0B39B0A35EAE7C57D09448848
+:10BE60006572BB56E6AFBC3686EBABEE10CFFF7902
+:10BE70002AF3D0EB65042DCF63C90DC5F358CA0072
+:10BE80003F5304FE7227AC263B764A88E7B14C7ECE
+:10BE9000CE6AB7DE9EEBB2D473ED76ABADBEA750E3
+:10BEA000EC7BB6FC95783C6D11E961127EBB5C7D44
+:10BEB000B595C755BE06762B964FB5FAA8FCD75652
+:10BEC0003F95BDAD1AE969CFB6E672BFBBC0FB5660
+:10BED000D7053A17CF65B9290F42FA29A5BFFC3B10
+:10BEE00085DC0FC5421C9E85624DF39C996918E75D
+:10BEF0003A1AE2FAE160FBCCE20A6B3C6F49D81ACD
+:10BF0000CF5B56638DE77D7AAA7EA010F5AAC9BFE4
+:10BF10007BF551E479117F5A23F0B0E3211E5F9243
+:10BF2000E31FFD02A7BFAC9F1378F83EF207C68F50
+:10BF30000E8A7DF4C1AA5B681FF5E55F965E785CAA
+:10BF4000C867CA469F2B00E357F52D77E3386B7619
+:10BF5000C138A9973FCEE609A3B3ACF1864FDE8185
+:10BF6000EF1F8DC51BEEB903E30D4745BCE1FC7324
+:10BF7000CD5F467BEBA642FD27880747A17E12CB0B
+:10BF8000F308CF28AA0FE0B922EBF0E770C6E8214A
+:10BF9000FDFAE70B13F8F59D739584F6E93B85DC14
+:10BFA0009E86F3EB97F81EF3C6FC6A17789D9F53A5
+:10BFB0006A119FBFFD47AC09C769FF366B7A3681AE
+:10BFC0005EFFC742458EF73B3A0FFDF23C0CFF2166
+:10BFD000D1784E4FD558C4F73917CF83B18FA716F4
+:10BFE000B9E5788E227C2733069F5A641A6F07E0E2
+:10BFF000A01FE9A4FAD2288EC9EEA678A7E4A394DC
+:10C000003ADF7CCC53000393E13E93F2BC6F7E2178
+:10C01000E6D9FD605CE07136385D7F26F8EBBC90B8
+:10C02000B3B751CE409ECEA29C41791AE50C9E0F2B
+:10C03000A09C4179B23540CF7FDC1AA4F247AD3ADB
+:10C0400095275A2BA8FC416B98FA1D6BADA1F2F510
+:10C05000D6083D3F5AFEF55B289EF69442795583FB
+:10C06000C173D757ADF27567D42A5FEB7659E56B8C
+:10C07000CD4E6BBCBCB1DB1A2FAF37ACF1F2552DF6
+:10C08000D678F9CAE69996FE2B9AE65AEACB23B7F8
+:10C090005BFA2FAB596CA9EB455C5F5C125E617972
+:10C0A0006F7145A3A55FCA22164944FF8A22CE9F1D
+:10C0B000074305C30686D877DC2DB7FF04F59458EF
+:10C0C0005D8D30D4EBDD2D0BE8F9D6A4705D38C161
+:10C0D000F875457CBFEB2C5F1D9EC3D0FF7B8BD3D7
+:10C0E000ACFFAC9F16595464B273DD7E6E97BD3BB6
+:10C0F000FEBD17F1985854FECE4BD7E139D5CF028B
+:10C100000AF0950E6A9F1FB6EC22A3CD791DD4AB21
+:10C1100033C18E34ADBBF833FBDA47C3F399EB5F21
+:10C12000983B12CAFCBC485D11DA5115A7DAF1FD43
+:10C130003995792A8ACDD60C467AE9B9096EB27753
+:10C14000EC707FAA48B1C4B3AE749FEE6CB5C6E57F
+:10C1500073FC3CFE95E3E7F12EA853BCEBE9699133
+:10C160004F217CF09CE25E5D596B73703F192C8E01
+:10C17000F490A097F42B48B8769472788E8A78C39E
+:10C18000107E852F168D1A1CEE73220ED1F5254FC9
+:10C19000C2F8CB3911873827E3100F2D4E18873896
+:10C1A000374FF815A01DFD09E776D7F0725EE390D2
+:10C1B0007108B93ED88F1EA4FD27168710FABEF06D
+:10C1C000A3BF3E4DFF5FB88EA63C7D17F67B7F8AEE
+:10C1D000BE1BEB474DF150DF68533CB4FC154B3CA4
+:10C1E000F499FCC83E7C6F226E693064BBC1069234
+:10C1F000C6617C367C4F223EFE9722A967F7FD453B
+:10C20000F15A535CD5F1C1CDECB2E30297DD2FC8F2
+:10C21000F350EC7A4E0A620486E8C6AE70CE3E5900
+:10C22000183988EBEFC8785EE3F9568EF8FE8187FF
+:10C230009F7679F3250B3B15CF2B3CB78E81C4E05D
+:10C240003EB33DA399FC2AFD026FF6F28D22414FC9
+:10C25000E61B89F47DB230FC3AD28F3DD7AB511E3C
+:10C260009B78CE722FCF5E7DC21DFE09EEEF9D73CF
+:10C270009C1ACF1B64E4BF9894EB8BA27E2BF5B085
+:10C280005FE27E49F92803E3DDB0CE76FDC554CCEC
+:10C29000FF7E6B8F8A1930EC2B69CC8570877361B8
+:10C2A0007F8375CCF1476E1C6A5FC4041E4790F80B
+:10C2B0004271F8A91CC14B43C1E7F6FEAFED796F9F
+:10C2C00014EAE55FE9E1F1B0493DABBD0DA6F173BC
+:10C2D000A6F37DA73393C35FA72B512D1BE1B9F0C4
+:10C2E000FD19186FD11CE4EF786BC36F8E2F43FFDD
+:10C2F00063C8199840F577A9DEAF390A307EFD96FC
+:10C30000FFD7C7B1FFA42FAC194DB68EC0C7AA0D79
+:10C31000054F203EEE0B4494E9304F7FE8DDB471C9
+:10C32000A678DA2A858513E93163A673BADDA637C4
+:10C33000DF81FBE66DBA87615E737F9987F0FE95BA
+:10C34000598A86F6EE42E475680FEF51C98F0DF8F1
+:10C35000588FEDAF065218CE3B477F46C5FAFB53C8
+:10C360001476DD10E7F015E335F4EE2894C3B790AA
+:10C37000FF12C0FF4BB96F0A399AA882DCE723FE8F
+:10C380000FA59AFD95929FFEA9501F37BD08FD7F0E
+:10C3900091A630E9B98B2EC1871B093F0BBF1AA5A7
+:10C3A0001884E7B1E6EB5982FB0DAF09F9B03F2FD6
+:10C3B0009CCECFC95F0BB998D4F3DEABB7629C7942
+:10C3C000838BF2116E2A0C4F47786276D755DE3791
+:10C3D00064BE5A7F5021FB0DD4699AA71F245005D3
+:10C3E0007A2529C9014E4FEEA7F38AFD0FFAE9C35A
+:10C3F000A0DF2AD6DB87FE3EA6EA3B9DD07F73B145
+:10C400008BE8BD6CA52B0DE9128F9F052CF686BD20
+:10C410001C1071B3CE562FE56BF47738B99E0F7FA1
+:10C42000401387461EB767C6948775F8E713228FB7
+:10C43000F493C15B1FC67C9AE30E5E6F08DE7AC37D
+:10C44000468C7B8F6D3EBE04E3160F2881360DCBE4
+:10C450007DBB1A30CFA345095440BDAEEFF37E74C7
+:10C460008935747848C73FB56912E989EFFA990FA1
+:10C47000F5C46563B8DC34F6B3A8233B6EE79ECC05
+:10C48000E2F113B463E74DC76D97E3E39F5BFB08ED
+:10C490007E4F0B8F9B0C0FF0B86972BF1A884297C2
+:10C4A0008F6F7B87ECE0B0DFAD219E47301E578950
+:10C4B00064A606300E1AF4F3B84AB27EEFF125F006
+:10C4C000DEF07295E7B70D707BB809FEE2391261B4
+:10C4D0008136DC9F465458EDE4425B7C459E6F1EDE
+:10C4E000FB7315EC5178DE36DD7ACF6330FFBD2C5F
+:10C4F0009F033D02D7F7BC88E77E13F475A4D3B73A
+:10C50000415FC7F200E8EBF8FC7BA0AF63D907FA04
+:10C510003A9607415FC7F210E8EB58BE0CFA3A961C
+:10C5200087415FC7F7FE0FE8EB58BE0AFA3A3E7F35
+:10C530006E16DF473AB3DCD18D8067EF9F808B01A9
+:10C540002F9D2EF663E42FA3CCA3F17C7CDEAF2BD2
+:10C550006322EDF3FD4AE4138CE781688F633DEDC0
+:10C56000C21F7F85F54DD964873055FBE600F4EF97
+:10C57000F87C76600B54BBDDFCBC1F38CA7CA83746
+:10C580009C5EA24C45BDE9CC7CA55701FDA67FBEB3
+:10C5900042FAC44414BDFCF83E5AF29EB61FE76B43
+:10C5A0004F63821FF7F5E8C07FA71126E2D7B43AA0
+:10C5B000B48F677B643DB90EDBEB5B1461A7A6EF1C
+:10C5C00045FEED92FD8DEB7AB07F87AD7ECC21EB01
+:10C5D0004D7BB07E3C365FFD0A1CEF788E6C6FA8F9
+:10C5E000D5E1CC184892F3CD5C89FDFB15D93FAF5E
+:10C5F00007EDE43359B2FFDA15D87E2666473FB619
+:10C6000092DA47F1FE93BE3BE211B49BAFF678EDB0
+:10C6100011BE3FC33EA69BE33A2D25DCBF10F39F1E
+:10C62000EA8AC57F2AFDF68E94DAEB30EEE6D9C8A9
+:10C63000F3B406B20275785E0FE64735F9F9C98F93
+:10C640003ABB24767FC0EA2FD5159E47EF6311CB06
+:10C65000FD369127EFCE34F9ED84AC5F8EFF50C6E6
+:10C660004BA4FFB0461FDA7F5833CBEA3F947912D0
+:10C6700083F90FE57D04E93F0CAFB6FA071746AE24
+:10C68000CC7F58CBFA5C686F315D2179A9F5F5BE96
+:10C69000341AEDFAB31AF90F9976381ABB7FA0D184
+:10C6A000309A633ADE23E3F5D3772B7EB41FB6DCF2
+:10C6B000AD8CC6F2E4DDCAF5284767EF567C2857F3
+:10C6C000BF98C1EFB7149D0F1CD6705FF53B021CDD
+:10C6D0001DE12FE03E1C5E9DA16D41BADEAD0CC791
+:10C6E000FE2B3F93E1C6F303F44B21371F3C8C7CB8
+:10C6F000E54C512CF5C2B1924FF73C8C72317B84E2
+:10C70000E4C3C57BB05EE696EF7F710FCAC9F288BD
+:10C7100022FADFBB07E5F0F81CD97F782DF65F32EF
+:10C720004E8EB7770F8E3F3B45D61FA4F6EED878D6
+:10C730005FA3F97E882721D5B7EDD1C7C37C55E229
+:10C74000DC323E46E377D6CAF7EFE92983F1568813
+:10C75000738A191F2739273F33BD0F7A3AD4FF5DFB
+:10C76000EC030D337EBF02E5E68E58FBEF69BDB5E5
+:10C77000A2BE7AC6937B30DFECEF7E7D7FE5F9ECDD
+:10C78000F595AC7FDE758571B9B09F8BCB8BF9BE0B
+:10C79000126C7A068F2756DBBCCF89F2887E001197
+:10C7A0007FAA0E237F7B9D943717F687C9EF691FF9
+:10C7B000E7FD195CCFFECC0C6B3CADD3164F0B6381
+:10C7C0003C2D7BF071EA8AF938DD7312DBB34F4FF1
+:10C7D0009BD33A63545C3F4055D00D6529940E2895
+:10C7E000FF3425B26946115EE6E1FE16E9BF5E2020
+:10C7F000F288DB4ABF1C9E83F7928A5D01E1FEEE60
+:10C8000037C777D56DDCFFBF62CE05CA0B5BD3E9B6
+:10C81000D1F6631E4B87C85373A652FC41BDC1BD00
+:10C820008FF679113F8D60BE710ECE33F4BD0DFBD6
+:10C83000FD1943ACF7DDD01617EEDB35E56A9F5BDB
+:10C84000C48F79BE9835BE2CE3C56579E329AEDC8B
+:10C8500098E9A5BCE22ACC0F41D910F1EE3AD1BF3C
+:10C86000B1E58530E2BD7EA793A11E78A5F1E5FA7A
+:10C87000B091F539787F41791AD7E76CF1E69A865D
+:10C88000277517B41F055C8FC00E225E2EEF85C47E
+:10C89000EE1F883874443C5F1ADBFF2BD371FFF422
+:10C8A00074811D86EF8B38B38C4757D9CE81FAD06F
+:10C8B000DC74F2D70654B21FD54BDCB3CE29E1F9B4
+:10C8C00068321E7D7886351EBDD5C5FD7FDD3956A3
+:10C8D0007E2B29E1F6EC2471EE1E2C4DEE4B42FD31
+:10C8E0009A79C9CED882FE9A61DCDE40FF84DD6F82
+:10C8F000A3B6AC20FF22B62BC07F4AEECBBFC7FB4E
+:10C900006A582F81FE2ADE578175A8A90EBAAF2971
+:10C91000FD3BA886CCCB273FCF49E463B5A58EC6A7
+:10C9200091F7D307F3F3FC6C86D40F7A5DD86F854B
+:10C93000FFE51338DF5FECE7117696EC1FD6789EA3
+:10C94000CBF0199A8C5BBAF8FD3DE65A3485FC2190
+:10C95000EFA17CB2C9BD1AC221F7A345C5CFAEC0B5
+:10C96000FD88E9A3D819D3BD08FBBE20F78BD87C7E
+:10C970007EFE7EDDB7BEBBC2183978BC2227148B81
+:10C980002FA8419C7FA48C2FE82EACC7CF595850BC
+:10C99000D072CED636FD37386763FABD31B616DBB6
+:10C9A0003F6AF0035FCD0E52BE14F7B37DD4E07F33
+:10C9B000A5485F8A7C78ADE7F956517835CEB359F2
+:10C9C000D16B52793030A00C1D17BC0BFBDBE3821E
+:10C9D00097F257FCC33F31B47FE24B416B1CFFC35E
+:10C9E000E29FF867C029EE93204F4F923C85B83CF8
+:10C9F000FDBDEF7FB0DE57B85CF44693C75D7DFFA9
+:10CA0000C09385916388CF895A6A3D9EE3308F86B3
+:10CA1000F217F37B20DC418BDF634FD335F07BC013
+:10CA20003ACF125DCB395DFF0EE8F65F749EEB5C8A
+:10CA30009FF83BE4CBEB8B915EBD7C7D7F83F93F20
+:10CA400046F33FC5F9258E1FAE2799F053DBF4B7A7
+:10CA5000C14F29C1F74D0EDF47809ED5046F80C3BB
+:10CA60007B29FBFBCE193C7E02EFADA0F70A391FF4
+:10CA7000DC85FA35B7CBE762BE80B4CB33F2F45530
+:10CA8000D80FF4DC7A3E4F4CCF6D281E35A4DDBCA8
+:10CA9000B67868BB797DF147C86EDE2DF0168FCF72
+:10CAA00044E93E1C9CE41447AE137DB7B42CBEEDA4
+:10CAB0002680FB37807FAC7B703D4ED37AB254B278
+:10CAC0009FEDF7D48E883C08B92ED5593B0CF5085C
+:10CAD00089CF23E99A1BEF4335E84A272603CE3551
+:10CAE000DEA175BB750FE91F37FA7D9D187F5DAC20
+:10CAF000F3F5BB9B7C74EF45DE7393F74E1AFAC6D1
+:10CB0000BCEC86F7B680FD3206C65F586EBD876204
+:10CB1000D72F545BBDE5C7D9DB0F99FA3F566CCBD5
+:10CB20001F743E5541F94386427A1713F9840D620A
+:10CB30008CB6D23B92FD5C8FD3100F73773ED08FB3
+:10CB40007133B7E1A4EF30FDB655DB7E08442A69A6
+:10CB5000F3BBB4BEDFC0FAC8C8ADE4F1FA4611AF0A
+:10CB600067363F8527F9E72EF44F4B3C26DDCFF3A0
+:10CB70003CDCC153E574AFB1764D7F11EF4BFE073E
+:10CB80009543C6E47735AAC438553ACFAB5CEA770B
+:10CB900058F284EC7E0C95A9B6BCF881974620BF6C
+:10CBA000015EBF8CEC91CBFD10C94CA7EF7024B790
+:10CBB0002D1ED687DDCA5D96EFA12C0CDDCBCCF601
+:10CBC00072B28D2F3D367F839D2FEDF4F8818D1E3F
+:10CBD0008FAB5C2FED3CE6247F79E783ABBBD17F45
+:10CBE0006E3CE8207FC65999070240A23F7F198B0F
+:10CBF000E197F4E5CEE68C28FAE1255D96EDE4F9BF
+:10CC000021D4CBE477672C9399BFCFB14CF817EEC2
+:10CC100060BD74BF61251B70A11CAC4257BA13FDE7
+:10CC2000E21A958DCCD8C4087F91EE6C98EFF1E6AE
+:10CC30001101F46BF75DEFCA783B97DB1189F4D7EC
+:10CC4000785C56656F9BFCFCFFF06B5DAE5FCB695B
+:10CC5000D0F7FDFCEE287EDFEF527EAD97453C42DB
+:10CC6000FAB5CEEEE4DFD5E817F72AFA5DDAD89DFB
+:10CC7000A9D84FE3DFCBE85E761BC2FBDAE6577C30
+:10CC800003B44FB20DA387FE0EC4D4920476E1F72D
+:10CC900067309E17973D9085F999275DD6BC5B5903
+:10CCA000CE0FB9C5BDECC88C12935ECC7CB13CCD27
+:10CCB000E212F257F1FBD9D2CFB4B620528ACF6735
+:10CCC0005D60640F7A2A95A882F919A9CA4B8A1661
+:10CCD0009F9FD9F3E5FF1107E3DFB712F8E94FE2B1
+:10CCE00079B3FDD9ACE6D904F4C99EC5CFCFFEBC5B
+:10CCF000C4F493EDA097DC83F443BB299D33CBCFE1
+:10CD0000DD43FB133E5B9220CF58D2F7C9D9FA7DA1
+:10CD10009CEEBC9E941FF902D6DB23E19FD0F7EB7B
+:10CD2000B639B536C47F9F762488F2F945A70FE35C
+:10CD3000DDD73ABE377C46F665C5F77E81F81D45DE
+:10CD40007C2FF4C67FAA433D708BB4CB84DEB862DF
+:10CD5000B8A90E5B71C931DEFF1B25D3F71AEAE0D3
+:10CD60007AE6FA0377F4A01E29F54CA8AFC4BA7C82
+:10CD70009FB1DBC796815EDBD824E388B7EF453DE2
+:10CD8000373EDF92BDA8079F7559C7977AEA2B25D2
+:10CD9000E57B71BC706CFEF2BD08FF800D7EFADE93
+:10CDA00024D4DF28D1F7A2DE5BCF64BB4EF901713A
+:10CDB0007FE27AB25B8FBB65FB27285F607B361F03
+:10CDC000FFD503EB7BF03B691F3678AEF5F857DAF9
+:10CDD0007F307DFFA48BE7071AA09F615E4890F526
+:10CDE0003AB9F0E96E27F07F89AED07EF4EB109768
+:10CDF000D770AA43CCD3D2437C512AF11AA53C8FD9
+:10CE0000C1F8EECE03DF7818D71D87FB1B2B900EE1
+:10CE100031B88DF575E81792701FC5FE30DE8A7B3C
+:10CE2000EEF4239C2B627E8DB61EECD79921EB93FA
+:10CE3000F6627DB0795786B6F5E0BC2B62F8798052
+:10CE4000DE5F912CDFDF65CD4F317A565AE15A6DA6
+:10CE5000C1E7F70EF4F4205C615F74D368F2073227
+:10CE6000FAFEE71D4D6D94BF1D97A3AD592447FEF3
+:10CE700058BDC72A479F26B8AF365CB09FFA67E215
+:10CE8000F995CBEDC3ABBF6ED82771DDDB145AB774
+:10CE9000E4A35A9F89DFE19C6BD464FD9EBAA6C9C6
+:10CEA00057635E6EE7867FCEE8FC93F2C48C884DB4
+:10CEB0007E2E6FBCF6D41CCA9F00FB4A4F946F7D38
+:10CEC000D70C45FA31E7103E83D26E6652EFB86553
+:10CED000E62893DEA1C5F48E0AEA6FD33B3A451EDD
+:10CEE00055A7B86FA2438BDF94E7337E168FD3B676
+:10CEF0008B3CCDC28DE1B5663BFB89D91C9EC766D4
+:10CF0000733994DFAB3DD3A4501E58FBB611E9989A
+:10CF10003F7B2AD3B700CFB5FE6C4700AF2E9F14DE
+:10CF2000DFCBECFFBC27EB33F0FC44762AD9A927F2
+:10CF30003276A6E13D855301A738679E7B8BFC5D69
+:10CF4000717FA281E78AF417AE9ED94EFEBF3735B6
+:10CF50005E0FCC7EFE2D8AB7E5DAEF7186488F71C1
+:10CF6000DF22BED32BBEB729F5A5AA4D8F7E896CD3
+:10CF700060A1BFC8F3D37EAF13FFB8CCFA57879335
+:10CF8000EB5F7EDECFCF06DA3E30E9DDDE41BEF379
+:10CF90005A23EF11DAF429BB7ECCC4774DA57E9ECF
+:10CFA0003CB281FCFAC94DD67EA73A5EAC0CC2FAFF
+:10CFB000BA024ECAB3BA3DD7AA474B3DECB68E472C
+:10CFC000C90E05BDD0D22EF36B6F67BD1D74FF5B1C
+:10CFD0003B7CC8393A6E77B4FBAA484F69C8851ABA
+:10CFE000ACE7F8FF284B2B42FD609B13BFF0CA73E0
+:10CFF000EB4DEB807E2EC748DAA7038A62CE076A24
+:10D000007B04E5229E0FC4EB713FFC7D8FE07E1018
+:10D01000F317B37B5659FC9BC632EA1FF38719619D
+:10D020006A3FA30AFF97B1EA11DCCFE2FEB11FF617
+:10D0300058FC6346E523C84F32BECA8CFB29AF6F4C
+:10D04000A94FC2F3A31EACB7EBFC3CF9E6773C2733
+:10D05000F17B4057DA1FE4F379944316E6FB9DBD5C
+:10D06000BDE458B43D5DE875F83D0ABB9C27857862
+:10D070007E5DB99ED7314AE37E2B0FD0475FE95CD6
+:10D0800089FC1ACF5329A6EFA2350E9257322FC42E
+:10D09000E5F7F0CC548B3D6ECF4F691471E8C1C6F3
+:10D0A000A92FE571F67EC557CDCF6527C373B9ECBF
+:10D0B0008171A9783D55F62B2DE5FBC19FA6E8C7E8
+:10D0C00071FD763FDA59F4A3A1AC0A7FC722C13BB8
+:10D0D000EA4EEB774BCE64F0EF962CDA26BE935EE9
+:10D0E000F197F9CDCECFB4DEAB1F2CFFA1B894EFF2
+:10D0F0006379A55727FFE189645D477C9D83BEE87E
+:10D1000017BC281F42E439C83C08772887E76D30F0
+:10D110009E0FD16EF0EFF15DF57B2CD22E290CA77E
+:10D1200084F05CA8E1E788E4B3BE991AE7BFF30195
+:10D13000E23FC977D03F23847C5DCDFB979CE7DF3E
+:10D14000B790FA45D281933D6DE3E91CBA2E643E57
+:10D15000875263F71EC784129C4347E7EA37F0E71C
+:10D1600086C86788DC182A4AF87E762881FD3C79D3
+:10D170006A783C3D8FDDD7D42784FE91FF00D3260B
+:10D18000CE3B691C24EF44EA85F5DFFBE94A03FA4C
+:10D190007D30475F1032D9AD31FD7280EB3B31BD40
+:10D1A000D2984AFBE235D01B57854C7935D760FCC5
+:10D1B000BB88EF265BF528B4FFCDCF3F6C761CC053
+:10D1C000B791F022E2267FC6FB5B42A678CD5F01D5
+:10D1D000DE5D2193FEFF21C4E75384CF0F2F7C7DBA
+:10D1E000045F25A7F7CC99313E7D31311F5C36FFB6
+:10D1F000FFDF90296E6E1AF7083DAF1C3A2E07FD2F
+:10D20000DEB0F68BBDFF03F3B843BCFFEF047FAC89
+:10D210005FECFD93F45CF0E75590F3F366FA5E8300
+:10D220007DE43D5AEF783EFEE992D83A7E6B7EFE71
+:10D230000F7FD925F93C6B16E2AB99F3D365E8D99A
+:10D24000E366F1FC9608F7D31A52AF99289E0FE0D7
+:10D25000BDD105C8D7A3E85EDE4D38BECEB89D1B54
+:10D26000B34B8CDD7BAD76090C34D972DEEF35DB48
+:10D270001DFAAC7D7B115EE75CDEBFE8BBE9AB70FD
+:10D28000FDF63AE825336659F3328338FFA5C6C563
+:10D29000F83FBD678BFF9BDAE7CCB2E42F703D16F9
+:10D2A0008E70AF0768FCC35AE7C806A857CEE27A6B
+:10D2B0002CE82109EF6F57CE8AF9132A693E918F26
+:10D2C000712CECA47B80317D8579C9AE8AE953C687
+:10D2D000D7C84F14D7A7FE85F8A954D077D5777B48
+:10D2E000EB049CCBF8FAC53A2EDD7F25F5F7F3FE6B
+:10D2F00009DAEBA93D93C3C9520F9F755AE2156C29
+:10D30000BC6374FC7740CA5C4B668D047DE56007A6
+:10D310008F47D5770BFA1ADFDA6BB513B9FC2D17E7
+:10D32000FCDEFADDBE3AE4FFE5EF49789D7CFD3195
+:10D330007F5F1FADFF4DE19748FB5E9F84EFB30415
+:10D340009FC6E1BB06E3B711DD19C74F0D335CA3E0
+:10D3500087C8B3D82CE80FEF75D37B5E0E574D44CA
+:10D3600071F1B8CB2917F279DD3196D0DFB473961D
+:10D370005BBEBF93DE4F15F66C20F1BDDD87E2F199
+:10D380009387A8BF8FCFE780F31FEBA1C8D1B94027
+:10D390001EFCDE1CD935E17255C7EF2C84831716AD
+:10D3A00031D377E5641CBCECFEF1BD680F269727EE
+:10D3B00071BBD16BFD7D0ACFDCFB721FD4485AE9EB
+:10D3C0003BB54B041354316B5C34419CCBE27791F9
+:10D3D000FE9125B1B85426D9B9EEADFCF7A158B5E8
+:10D3E000358E99DCC2C8CFB5C050A21A8CEFD1AD32
+:10D3F000FE96C8066D3BFABB54D515D0B58BE39AA3
+:10D40000F6DFB998ED657A7A3EE5A37C6FD6A87809
+:10D410001ECAE9EE71A92887763BFAF4607674B7E4
+:10D42000D58EEE9776B47E75ECE8A3B3AC76F4DED9
+:10D4300082F01BC4EFAA4EFBDBC1D29245685FBCF1
+:10D440002BF228061E54D3110FC6367E6FE1948846
+:10D45000F3CB78FF40314BC5DF3B1868F3103E0734
+:10D46000D6644453E0BD74635D25FECE81B4A7113C
+:10D47000F3E80793DF27B6DBDDC941A0E7341233B9
+:10D48000B2B7077C3EBACFBCB0437C4742E40B48FE
+:10D490007B5BDE7B6F2CE7F7A7D17367FE7D8B8507
+:10D4A000C21E977679DFBF31C59C07B08805289FDB
+:10D4B000A09A85A95C2ABE9F58E3639B10A8F7A792
+:10D4C000447E47FCBF87F309DBAED2EF570D6C7B80
+:10D4D000807E1F6AB0FB0C6AA9BCCF60509CF61A14
+:10D4E000D8FB49A5A6FDE332F69B61D45FE572DC6B
+:10D4F00086F77C47C5BF1FD12FFCC2DB33B83F6521
+:10D500007C29F737D94BF97D882B3D3FE0FCBCB136
+:10D51000D46AD76BA597777E4EA4F7C4F7294663E4
+:10D520003C88EF4B379572BD404B27BF0A6CD14307
+:10D53000E703044A8788EBB24BE713044B13E41369
+:10D54000FC42E8236B0B22B370FC591718F1AD3D78
+:10D55000EE2FFB1D473F5582FDB659F8DBCA8045CB
+:10D560001DF917DFDBFF61AB7E1275BCE3AD15540F
+:10D570009E508D34CCDF3A22EEEDC30894CF24F3D5
+:10D58000A2E4B835B56527CF9AF6AB85F31EA33C68
+:10D59000B3F6DCFD871580F394C8F7EA4FF36D47C7
+:10D5A000BFB371947F476A69F5AD27CF9AF60F3BF9
+:10D5B000BC98176580A8DF59CABF5FF76299A76F4B
+:10D5C00036C8E1EA6D5C0E576F3BE5427F665D4B06
+:10D5D0003D8B4CA1BC2915E97B6C26FFCEC2C2A0B5
+:10D5E000931926B832F2F486528A7B845713BDE32E
+:10D5F00079816BB05EE6D2D331AF5DFA2965DCA0EC
+:10D60000B4F467A43FF767309A3FEC67518CBFCF03
+:10D61000D5B3DD03187FF1FBC8AF5A57AAF1DFABD2
+:10D62000EBD847F02487DE2178CA54C0F7F08BF19D
+:10D630002DE5A253E0DBB46EC2F760F2BB709E9A98
+:10D6400086F83D82F4827E9BC43EF09A7A21D5977B
+:10D6500080EEB1F78265167C7BFC1516BAB5EBE35C
+:10D66000D2713D92CEF5A2ED7487F3FB48C7F73037
+:10D67000AF8DE898381FE228D26B12B497727FB44E
+:10D68000A4579DC1E9556794713C056F758FA178CA
+:10D6900080D28BF7251BCBEB19DA0B6E3D83BEFFD7
+:10D6A0002FE9B7A81CE8678217E4F1E15293DEF98D
+:10D6B00067F8D91F2D35E9C1D73A0E00F33D43F382
+:10D6C000D9F372FF4A71888BBFDBC3F7DD3705BF23
+:10D6D000D84BB9EF0E9ADF6C54AE6AFA33E0907211
+:10D6E0008372DBA660FEA4E2423E0BA3FC4E417DAA
+:10D6F000EE3F36615CB4C1CF7A712F7C08E508F04B
+:10D70000E6AEC870A3FCD47767135FA0FD4FF81492
+:10D71000FBF44BA54C9E5327E97913E78BBF75FCAF
+:10D7200007E0B940F0D48AFB051FB2F854564558BB
+:10D730009D8DFE597D1F9D2F7D33E5F79A5816F775
+:10D74000935F593CD4A3F3FC3119174D1007D594BE
+:10D750003F230E6A8FAF0E16174D1007B5E8EB8307
+:10D76000C541992D5E6A8F83DED63182E2D0B765DE
+:10D770003A28FF51EAFD32FEF96AC7D7E97B47AF85
+:10D780004E565846F6C571D26DC23FC650AB33AD4A
+:10D79000FF4416FFDEF596315EFA8E28FE719AF28E
+:10D7A000F1E07CF07A60DE8E794ED24BABB2F7DBE3
+:10D7B000F1EA1676C965E155C6D9DD1D3CCEEEF11C
+:10D7C00033FA3D4D49C7F8F7749FA7DF8B642ACF22
+:10D7D000D3ABCFF5515EAB9D0E9E8EB67BE9779CA9
+:10D7E0007CD3D75129E8EFF15F9C3FA84AF812E4B7
+:10D7F0000FFED9F4BC041DDDCE0D5E14B98BE8A973
+:10D800001D4CC5EF8ADF1670FA342D4E4749D78B71
+:10D81000E9E7A3FD45C6B96F2A0CDF857223BFD3A4
+:10D8200024E97B228BE3F7CC4D2C2ABF4F66A62739
+:10D83000E05FA77B77B96C1FE11FF330A75ECC17C1
+:10D840009E5C837EC7D39D5CE927B992F8D50E1004
+:10D850005DDA9B7D0B507F3A5AEEA2BC9504FC40EA
+:10D86000BF5B7B297EB888EEDBF8EF845E29FDEE96
+:10D87000287E5CCF4EC01FD790AE15C14474C57CC6
+:10D8800086BF80AE278AF4C791AE929E3715EA5FB5
+:10D89000995D64965F83DB312CF1F76D9E16792DCF
+:10D8A00030CEBFE27BBD686391FF50EFC5FAE21B4B
+:10D8B0005973A2EF823D5BC6CFDD5AD6FBD268B466
+:10D8C000FBCE3291B71938ACA19FA6655CC2BCCD26
+:10D8D000E3F86121E8BFD0CFF639C4FEEA30E16950
+:10D8E00040E46FBE89F99B60E7BE3C3B9BD6B10527
+:10D8F000F338E1F92991E7598B63E33CA0CF627CCF
+:10D900009EA91186F7D3FB63DF6769A373379E8FE8
+:10D91000F1EB47ACDF67E1F58599B23D356A898364
+:10D92000327F04EDB6B8FD35356A39EF5830628D77
+:10D9300083F27C1D79BE6DD4E7440C731C9455D0E2
+:10D94000F8276B65FF1DD1B2C9E638E8E2A86E8EF4
+:10D95000731AF3A3E638279CAF54977EE8C7FBEE13
+:10D960008FA05E3F796AE43CD25FDE9B870348C7A5
+:10D97000DF9D73FB7DFBD10E07FB00AFE40FAA57C1
+:10D980007FD8CBFF0F02C2B069008000000000000A
+:10D990001F8B080000000000000BE53C0D7454D5FF
+:10D9A00099F7CD7BF393644226017480A02F01DCAC
+:10D9B0005843187E020109BCF9C94F157480A0B103
+:10D9C000207D842CA55D5A83959676EDE6416248CC
+:10D9D0008240E8D2EDCFE9CF88D03DAEEE69E87164
+:10D9E0002991D20E6229964A634B8EB14B75B0597C
+:10D9F000165BDBA295DAEEF194FDBEEFDE3BF3663B
+:10DA0000323128B4C7EE8EC77373DFBDF7BBDFF7C3
+:10DA1000DDEFFFDDC79DC58CB105F03FF3C60C8D72
+:10DA2000B18110FC3911FB7ED380B1955364BF22C4
+:10DA3000669433B6384FF6AB4C6321639D2EB99E86
+:10DA4000590CE6BFC09CD4DF66844C6B2A63C16569
+:10DA5000AA985F4FF05F5A2DE7EF8E0501DE2A8707
+:10DA6000E85B2B628697B10F31D95F4AFDD5C97E3D
+:10DA700094FAF732BEFF81F84ED382F58FCD894EEE
+:10DA800034C6C3B348AF1E9DFEB787FF3945E233A6
+:10DA9000C5C4F1F73BBEC0EF7AA312C1737EFF0D80
+:10DAA000E0BB86E4E330C7F77D88DFFDC4CF2738CD
+:10DAB0007EEF037CDA099F5EC027FF2FBFDF0F2BAD
+:10DAC0008D3DB8DF5F808EAFD1B997733AAE60FEFF
+:10DAD000A34477809F43E6F8C4A08F311C9FC3E125
+:10DAE000BDE8147264359B28F709D9C77383FE8299
+:10DAF0003372BFCD7A50B3E3BF99F46455119FFFE1
+:10DB0000EBF8A74DAB38D5879F81E72ED7FF06C727
+:10DB1000D3D67F8AD67767ECE712E3CAB1AD846FBC
+:10DB20008A5E8BE6F767CC6F14F4151CEB8C5936C4
+:10DB30007E306B3BF1276997AC9D6497065CB2BF62
+:10DB400083F4665709873FE1D8CE18E20FFC3B45C6
+:10DB5000FC9ECAF9F7FF9D1FBF3584BC94717E48B7
+:10DB6000397C6C8EF13B94B3F71BBE707E6A707C7F
+:10DB70004AFEFF0AFB15D27E429FDEEDFAA43E0A62
+:10DB8000BFCF9624F93B2908CF2784741AAFDA70E7
+:10DB9000307C3DFCB9BAE511D544B830878D632C93
+:10DBA0009A60B16DB0E7AD2CA632F061D180C97C2E
+:10DBB000E536BD665F243C5C5E87E87F83ECDFAAC8
+:10DBC00045E25CD8600CE38B14DEDEB5784E49BCD0
+:10DBD000D9D7D2F05E78CCFB88A03B10B4E9C9B5A8
+:10DBE00086EF0F015F6CF150B22FF8B3EA135F9E1E
+:10DBF0008C7C58552AE17E3386705E2C94700FD24F
+:10DC0000BEAB92FB7C8FF773E5FC1FD1FC145E0367
+:10DC1000661A5ED6CF28EE92783D766C80CECBE544
+:10DC20008B3D74DD1C689B958005E7F1A10D5B556C
+:10DC3000D36E1758AF1E04FF760F4BF649AE5276DF
+:10DC4000A097F6BDD6786D0A0AFE083D4DE29960B0
+:10DC5000018BD9F13BCCCFE71AEF6FB30BF7A3DC05
+:10DC60005E7BBEC79DD7DBF82EF560B52FA9DF061A
+:10DC7000F300DF7509E707E606EFD5EF0B72BED3B9
+:10DC80006E4FAE9E8EFE1AA2E3357E2E29FBF31355
+:10DC900033DDFE5C317E8F046DFEFCDDAEFFB760D0
+:10DCA000BA9ED9ECCFE348779BD7E1423E9B7E6694
+:10DCB000C400DE65FC2D4EB513420AD9A7A47E56DA
+:10DCC000F1F52B76B396DE2CF3AF0F39685EDB539C
+:10DCD0006C432FC00DBA2E36476DF3E2413E7E34C1
+:10DCE000A8500BF41D25FE6FE1F89D0AEAB45F9081
+:10DCF00069CC009D6A5831B918F16BFB398707E987
+:10DD0000125B9E9F827741C093FB1C5B96DF18F3EA
+:10DD1000A6C69F15FB9C0A723AD0FF133F1FE474FE
+:10DD2000A8051BFD085FCD5384FEFC9AF8DAE114C8
+:10DD30007DEB0DF26B03493BF43B92F7956E29970F
+:10DD40006F91FECB78FD8DE0FFC4AC85883F638E7C
+:10DD500059F675BF253B38DABA84F417EDE2BCAC4E
+:10DD6000E4799D43BC475BAF869516E29387C51562
+:10DD7000F01F2EBF6F5F3790525E61BC8A7C3E31D0
+:10DD8000D3F815B6A3C1013E5DA47379203D1FB140
+:10DD90008DBF194CCB072E6E8C221CD8D90DE7F6FF
+:10DDA000C26A755C13F0EDCF783E95941FD4DBCF3B
+:10DDB00045B67F4E9DCB9F8369F17C38BF12F488B6
+:10DDC0004D7004A6E9C3D779438A9433714EDA23A0
+:10DDD00048474752DF787F57211FCF79DAB956E895
+:10DDE000535E08F77952F097F9C6E17EACFC645CAB
+:10DDF0009D0BFE95257F8603FA6BF12FD87F207C43
+:10DE0000CE8972B0A65DB9323DE914F01F4E9EDF97
+:10DE100084D078826BB2B9C27FC06FE0235B096E99
+:10DE20006333C0CDA22F53429C7F5342493E4D21C4
+:10DE3000FC0D0ED731273A0DE1C254E69E9582BF04
+:10DE400046E01D74468F5E0F72D061293ADA557331
+:10DE5000CBDACE12E4ABE60C4C83E626E414ACEB52
+:10DE6000F0977AD1CF3D27F643782E3847F425FE38
+:10DE7000229AC73468E7D66F3A0EE0D8DBD3CD4A92
+:10DE8000C4A32ABA278C642D683C781CDB3BC04CA9
+:10DE9000639CB275D157A221D8A77FBE3380A2065A
+:10DEA000D159FF54C0AB41E0A51975AFB2319045CF
+:10DEB000B958203E07FDBA37B00D9E37347F64094C
+:10DEC000AB803951E750C283C498EC7229C2D58621
+:10DED00012659C6797C1C62DDBE24CF511371CF724
+:10DEE000A4C657DCC8EDD3AA10F0D32677DF17F409
+:10DEF0007D5FF07337E0D05F4E00F219EA0DDBE092
+:10DF000040FE991E8E67BFB5E2B69B81E04B652C43
+:10DF100080A36EA44F4DD19798AC05DC3A898B77DE
+:10DF2000E975B0AF38D7D3AD60EBFE0EC05A9C4E4A
+:10DF30004D5D5D10B7C9F1E931260B60DC56663DD9
+:10DF4000C4404EC2E61E6702F0B8B1F9F50D18F7ED
+:10DF5000AD31DD7A1DA078CF065F0DC6B52B4CC163
+:10DF60009725CE57906E0FFC877C71C55FFD810BA6
+:10DF7000F9BC50611300FE9D113E2EF9E266DA2BCA
+:10DF800076BE6819FD2D674B763D639B7F5F287FCA
+:10DF9000DCF95BE08FD96CF665A093A9DEA588CF8C
+:10DFA000A576C5A796D03407033A5D823F07DA37D6
+:10DFB0003D877ABAC6AF051CC887258CF8D728F6E6
+:10DFC00078AB55DFF50CC4AAE12D7B7A4A00CE3D33
+:10DFD000675486FCEA587D0021E1CF83F034211795
+:10DFE0008EBCAFF66B304FFBACCA703FC947E0B791
+:10DFF0006F2E3C3F3700EB61EA3D55C027D8F70E46
+:10E00000C3ADEB302F77E1EBEDC8A75CD6121F0B49
+:10E01000FDBBFC0E16F7A4E802BA2DC117C7658533
+:10E02000F6D235B9AF236D9CF892FB99306368BB8B
+:10E030002DA37F2ACC5B26E5B61DCE13CE6199C1F8
+:10E04000CF439E2B8B707995E7929B21AFEE2A6789
+:10E050004A3EB3C86BE639C432CEE180C6F52471BE
+:10E0600046A5B822B1571B53057D6BAF83F418F258
+:10E07000B4C34A01FC11579806FCBF5BE04B3FE07C
+:10E08000DB8196C2587749EA3CEE2E3BF127A58208
+:10E09000F159D7A5EC11C32416FA7789DEDD5FB2FA
+:10E0A0008A507E3FC47A9DA8D7F762C60CF87C9848
+:10E0B000F95CD86F62016AE1BC5DC8AF037B9FCE9B
+:10E0C000473B129FE82C3C5F46AAC2EC7632B34530
+:10E0D0004E9C9774C3E4B8B49F1ED34F76D90B2DD2
+:10E0E000D9698361BFB026E231B3F891F86CF38748
+:10E0F0006807655FF3B530C4E3EBB3A3CF72BBCB66
+:10E10000D74FAD307E84FD83B38C53D87E13E33D6F
+:10E11000F00F17430F525EF2F674E334DAB54C3B5E
+:10E12000760EED989E9287E519F220EDD820DA312F
+:10E13000185A8EFA0A7C63F55767C7CE4939F8003A
+:10E14000FB00F207E8F925D97F0DE801BEBC84E7A2
+:10E150003E8361F52DCE8A884CDD07F829023F7C8D
+:10E16000AE807D57B6FCF04FCA18DE5F00F3147125
+:10E17000AE9846D6A0DFF87AC0E39982F6C21C4476
+:10E18000BA33F9028ED9497999FFC420CA8D23EF99
+:10E19000BB93CD2C7E3079AE1B9DAF25E9423D82ED
+:10E1A000481EE95098E9B88CF4F8008909EF241763
+:10E1B00016C941C75285E8EB28618D68CFDB7168CD
+:10E1C0003E63DB972ABDF8FCF170118F97A6F2B879
+:10E1D000707B618B3F00F3B63B613EDAF33293AD67
+:10E1E000989E82FB7858A5F937CF31F2D07141DC87
+:10E1F00047F1928C57E53C5F98C79563C33CCE28A6
+:10E20000AF881685719F7126F11DE2A8B1D4F7C6BB
+:10E21000638EEB445D84FF74872D8E1898D4C2D032
+:10E22000BFBB0DEEDF33E9BC219CF4EB3710BCBD66
+:10E23000D2AF1B37227E8BC7FA1AD0CEB900EF7D42
+:10E2400025297F7D68E9E754D896DD122E21FCAAA6
+:10E250009AF7B45D07E71D0C4EF1A27B8F57B7F814
+:10E26000D1EF6D9FC0F996B9EF9630F783736E10BA
+:10E27000F304BFA4DFF740F8ED847D30CD77601C58
+:10E2800050CCE3807BC3A5B44EC60330DF72C1BC63
+:10E29000E04DA0A718374FE37032F7BB57F033E5D6
+:10E2A0006F030568AF196B217F1115FEE48556E3F6
+:10E2B000A52110CA81D67A6AC1FEF747C0C00D6A8F
+:10E2C000567E200B1D77D63CE041386DC54D1EF4BF
+:10E2D0009F1D4698E036AE0EBE3464B3B7DB8BD9D3
+:10E2E00064C4EFAE860FBE3464D3B7FE7C8E2FFAC3
+:10E2F00019CB9D82BB12E504F03D1E74C717034382
+:10E30000DD7E16739750EBD4314F0CEB341E35D6AF
+:10E310003213F3F1AA731AD5BF0A5972FE5638DACE
+:10E32000703123BF1EF5B7305CE7863ECE8F2E7C62
+:10E330009DE6DF59A532CB8627D89F35145065C49A
+:10E340004BBB51C0006EC77C25B60DF068F0AF27FF
+:10E35000FFB375512E3D877D09BF3BA63593DF92F4
+:10E36000F15547241220FF7495F1547C76F47EC455
+:10E37000CBE54FDAD507485E5376757398DBD54FFA
+:10E38000E173693FF61D7F81ECC77685CBE176E0CE
+:10E39000F7B7B3C8C756A107DB0BB3CBCF9785BC84
+:10E3A000BE3D3DDA86F00DF069FE59EF3DDEEC90A2
+:10E3B000F1A6E0E3D5F207F8F12F619B5D067E7CC4
+:10E3C000313C7E381FE0D78EF64295D6E2094543B0
+:10E3D000F9CF11DD47981943381ED64293546F94F4
+:10E3E000A1BF1B0E27CE70DD2A41DFBBB5C7DF8280
+:10E3F000F086DB35E38930E5853AB7A3C22E33D604
+:10E4000023FCEE7BB3DB671C604FB1DE8D8F6CF3BA
+:10E410008F8A73EEAB348F229D37E9DEB5782E5D9F
+:10E420008AE1F74EC1BAA7D9887ACACA668DB2CF37
+:10E43000568233506A6E88929D5F3ECAFC6D625F61
+:10E4400041675911F911D8F74BB96AAA3F1A5D878C
+:10E45000C2C64F11EF3633FA0BD4BBED650EDD5259
+:10E46000A8253DECAECA8929D0CF9965BE887C0528
+:10E4700011319C00BABBEC0D8A8BDC4B148AD3DCC7
+:10E480001EC8E0B2C8F979E16F20D6A07176D6F047
+:10E49000DBEB1D8511477ADE0B2261D8EB171147A4
+:10E4A00013D6E5A53FC3BAC9B7B3C8C545A14FAA9E
+:10E4B0007B539ABFCC9CF746D845F39488A84B0869
+:10E4C000FFB7D2CDF32BF663C0CFE65FFB2A437FC5
+:10E4D000203DB098A5D8FCA2F48334627BEEC6BA86
+:10E4E00013D279261D8EA4B328C2D2F605797544BD
+:10E4F000781D438D54A6C657AA8CD73DFAD3F9058B
+:10E50000F8782264A7D8D008F8ECCF8ACF603A3EDA
+:10E5100045117E2E7D954611C203FF3C16DBCE10C1
+:10E52000C85F16FE7E6B46E87AC45363566769C9B6
+:10E530003BC6AD37201CD9B7C5AD7A24DDBE9644A5
+:10E54000B87D2D8D907DCDBE6F85E0DBD5DA87F768
+:10E55000AAF73BF0CF2C7AD49D7832AF02F070BB93
+:10E56000AD4F92BE96CF1A45DFB87E7FF886FE4942
+:10E5700048E751219F68DB31DE30741E8F7C22C258
+:10E58000E53878538CE63D3542FC919C078CC1BA46
+:10E59000DC4871C8FCF71887742F1CC8A338E4CD79
+:10E5A0007D79E8EF9F1A0A658D438E16F74CCA16DF
+:10E5B00087F48D1087AC8FF078F5F87FB928AEA876
+:10E5C000BEC0FD7CF5851E15E3898D119DF83E7F4B
+:10E5D000A85F35414EAA310E01387D220EC1F914D3
+:10E5E00087BCD9A3225EF32FF4D3BA6AE8631C3246
+:10E5F0007F843804B05051EE0E5777FF0CCF2D9327
+:10E60000DE5315E666BBDC5625FAE93D895CD75D2D
+:10E61000B62DCFA4734E979BF86C8E6F6A1D97F73B
+:10E62000CC7923C9578DEA2DC3FA4017CB0D201F93
+:10E63000DECA1953C10A785E837171174E05BABBE1
+:10E64000CEE6C52CCCAB3D7CFCD3B963F6612BED9B
+:10E650008F47E8C55B3937C4441E6414C0FA4FAB1A
+:10E66000467C31F8A1AEA99FF7717A36911E6D16DE
+:10E67000BC09EDD1289FBE55C48332FE7A6EA51227
+:10E680007353D2652C590AF3E709F8AE393C3FAC15
+:10E6900055BD346F4719A379B75A17A97E313FE1A9
+:10E6A000D275E8CF4BACE7F9A2FADD937918EFDF2A
+:10E6B000A231159EAF6C8FB6917C9E75513DC38083
+:10E6C000FF503F2BCFF412DFF2865C69758E5CB091
+:10E6D00064715BDCE2CAE833757541363B24DBCC00
+:10E6E0003AC4C188C83F2BD88CCBC0974BECC14EE5
+:10E6F000A4CD3D2D74FC51367CBDAC2F6C9C617C4F
+:10E7000007E563AA33F1EFDF017EF5BDE6A2F73A34
+:10E710007D7BF7DE5E81758B1E8DEABA329F01CA62
+:10E720008A96613E8B3CA0BAF4E92694CB23F9B2D9
+:10E730000F060DF03E82092BF9BD8F3619B6FEA9E2
+:10E74000C843AFA0DF3B325ECE7F95AF977D2BD124
+:10E7500084F7358E4CE0FD4B11F5518BCE37A1512E
+:10E760001EBDE597DE6CF6F1744DBABCDE51B5897D
+:10E77000CBEB28EBC0AEBF18C9B22E67A9B9633A7C
+:10E78000F0E3C89083EA389067C5313ED838C37C3F
+:10E7900019F9B57D90F3F5C86BF7FBF09CDC6313BA
+:10E7A0000F64B3F3BF11FE285E1DA3BCAB7BA6C8EC
+:10E7B00077D990867E6BF7A2A74E55C03EA7E74F4C
+:10E7C0009BA50209C00B0FC6CB72BDBB86E77129A2
+:10E7D000FC9E579BD0FEBCF64A43367DAF8C98BF5B
+:10E7E0008FA4CDE7EF45DB7A34E27FD189BA7D781B
+:10E7F000EF275EDDD3AFC1F9F6FDC6C1304FE99B0F
+:10E80000CEE3FE11F10A005E455784D7DE7959E464
+:10E810000DF072D58C1F8ED74F6A187FEF53617839
+:10E820006A2A87E3C9441D7381B0F739AF7E9EEA37
+:10E830008E7D0907154F2E0DED5351F464FDBB7B02
+:10E84000B0142320B678C9391545CA7C504DD3BBC6
+:10E850007983B969FD7B5BC6A6F5576D9894D24361
+:10E86000F87F79644A5ADFEDFF405A3FC866A7F542
+:10E870001B96DC9A06AFC6174EEBD7F96F4F9BFF7E
+:10E88000417D455AFFF6B25569F39706D6A58D57D7
+:10E89000FBF63C84E5A368F94C6D2C23799C897CBC
+:10E8A000CD3B63903C6E1FBCDF877211AF8E521E52
+:10E8B0003D90DF5F8CF5EBE79CD9EB0B0FD6A8D230
+:10E8C0007F17A3BF3718CFD7E4FC606922AD2EBFF6
+:10E8D000AE86FBE735354AD63A41A63F967E58FAD2
+:10E8E000E5CCFD33FD6EA6BFBDF3E67D1E5EEFE712
+:10E8F0007E7FA59083B6B29F7A13485703AF2374E7
+:10E900001703BD5EBA8F41FA757CE5DD93F1BD5A00
+:10E910006E9939D65D92F2D7E1B218FB258CE7FAF1
+:10E92000626CCA741C8FB175D3A92EAD85CBF9F377
+:10E930009BC4F3F5D8829FAEB5F12DD3FF063D33CE
+:10E940007F50C052F14AC31F8D4801E0775BF3410D
+:10E950006D1CB461EF31CD6E874E57FF6ADC087EC7
+:10E96000FA633519FA84EBFA8696BFA31F78B99536
+:10E97000D7DD0FB57A581CE83BDBEAA3F6E7AD7E9E
+:10E980007AFE7CAB4E6D476B19B5F1D6008DFFACAE
+:10E99000B58ADA675A0D6A4FB4D6537BB2354AF35B
+:10E9A0007ED4DA48ED8F5B4D7ABE4BE8E9FB051F5C
+:10E9B000A34CD615A2C71D0AF1B501AFEA2EB86067
+:10E9C000A8763B0F7CFD4236BEBE577F12AFEE9D50
+:10E9D000847206FE2AAB3EF5D6C8B83E79DE84972F
+:10E9E0008C87317F413991753AC0EF31C4CF8DF5B5
+:10E9F000B9A2ABC7EF88A8DF1C29648DDF1670961B
+:10EA0000E5A33DFF4A3444F67CFC4CB2E77EA6A564
+:10EA1000DBF39261F67C2DE91D3B897552AC2FD258
+:10EA20007B8A8C3A4841AD4EEB641D64D11F791D41
+:10EA30006434FA81EE9368B7A4DDBE52BA879DC7ED
+:10EA40006CE327C83FE99F87F90F7323F98F2AA149
+:10EA5000B34C7B93E2C43C41CFEE579617A07D7137
+:10EA600023823C4F3758159E3393F701F66D281ECD
+:10EA70000EF7E5EA5EF2E73B9271CEEB14C70CF7B6
+:10EA80005FE97CC058C8EEDF810FAFA6FB45CE879B
+:10EA90001AF5BB896DE09F8F2418AF93CDE1EFEBA2
+:10EAA000A41F3C7281D7312E694A8CC1D185584B45
+:10EAB000CF3C680F7F8E8D8BC2395B931D810330F5
+:10EAC00035EFE93EDD03F38209736C0E8C57C57395
+:10EAD000685D68C9CC18F61BA2AF937D0A69E97E10
+:10EAE0001223D4A4DFA1225851467F626ABE8AE76E
+:10EAF0005B9AEA03DCF5B34DAD16CE65F9C516A6F3
+:10EB0000978B7AAA37AB7FDFA8D8EA6C1A0B7422EE
+:10EB10001DDA6776F0F77A19F226F924EB6D320FD9
+:10EB20007F8419BEDA2CF143BB78EF92F9BEE50F72
+:10EB3000D34D7F2DF05DF19DA0F72D6C03E3F723FE
+:10EB40001C909F20FFC6B862074A86CBDDC1591FC3
+:10EB50009C5C4BFA6D29D7266FEF51286F177913FC
+:10EB6000D3EF73D8F318993765E6470F0B3BBB0B10
+:10EB7000ED2CB40F3B19E55B1D4A6E609F92CA975E
+:10EB8000C06FCE40BA16D58AF72FAC651EAF177E80
+:10EB90002E2D5F1A116F91973893E75EEC3B9F978C
+:10EBA0003A77AFABC78FF71CBB667EB5B109F936B4
+:10EBB000D343EF399916D7D1EE64D2C37C161B37F5
+:10EBC0003775DE2AD3CE637DB61382197CDFBB1383
+:10EBD000BF040078F901475ADC5350951EB7DD5D3C
+:10EBE0002BEDECB5A1030580DE6F4B3C5954D45599
+:10EBF00079FCE911CFDB756E2F18DA3BDBFBF5767C
+:10EC0000AFE1F1D9CE7F3B9E8F7B647CD492761F9F
+:10EC1000D6C17BBC0ED2EF4E5DEBC2FB1E9D5E8D5E
+:10EC2000C737BAA33EDBFD95DDB58AA09BE3E513AC
+:10EC300078A9C1E514078DB45FB79017D9CF2D37E8
+:10EC40000DD2473D10C53CB9CD3B4EC1FAA81CFFC3
+:10EC500068AD22E485D797BB445C955BD61B77A053
+:10EC60009C4D583F1BD9E68138E93C3CF794F7525C
+:10EC70005CE59DE832B3E1FDCF025E9733504F79FA
+:10EC80007FBE8361DEDF5592DD8FFE632D8F33DB28
+:10EC9000F459519C6F015FA629C3E77D5CC8C1434D
+:10ECA0004E9043D8BF6BDA5D744FAC6B3223FB5D83
+:10ECB0005A37FDD1ADDE2C72A8DF47E7E7F431F912
+:10ECC000FE3DEDBE449BDED0B816F6D59E6701B47E
+:10ECD0001999FAE69CB0BC712DDEB7A8CA0DE0FC0C
+:10ECE0001AF5C716F2B123C0A8DEA115367BA8EE2F
+:10ECF0005CACD1FD08892FC4EB8FA19D1A4DBE33AA
+:10ED0000F181FD48EE463ADF4CFC28949FF50EF366
+:10ED10000BCDC66816783F4FEA55BA7C394791AF9C
+:10ED2000D1E849F3AFC529FFFA6CEDA675784F6DB0
+:10ED300027E3E3A76A4394EF67F6AF959EB7693D73
+:10ED40008D782E6D535D247F99EBBB4A385EDD27AD
+:10ED5000AAC5BE3E05E57F5755510EDA772F1A6AD0
+:10ED60001B5F9FA930CFD5DAE2A6C2482F8FDB6B9D
+:10ED700019C9AF578FFAA6825C78CFA82053C07705
+:10ED8000C7DB7F3CA7BF773EB21E83E4964C3B9720
+:10ED90005BF636F0A54088F518F6703FBF2FB299A4
+:10EDA000E6497EEDBEF1B781F83BF06DCCC2F4FAD6
+:10EDB000D4BBAD3F2975F9E388CF392C07F97C899D
+:10EDC0003DA890FF8E18A477BEA45DE5F756C6C98E
+:10EDD0002E90837D123925559762F8DE03F5CB64BA
+:10EDE00014DFD0CCEBC42B2FA2DB47EB260930136A
+:10EDF000F1428D8AF2CFEDEE25F61ADF1F96E1BDC6
+:10EE000015C572909FBD11E51AE69530F34FE7B234
+:10EE1000DCE799EC6B3EB80EDA4975A29E26E8193C
+:10EE20008D1F12EFBF94DCCAF820B38E2AEBAC1D05
+:10EE3000A2CE3A5A1D956917896F32FECDACABD27E
+:10EE40008D3AD08FB76ED25837F19DC70BA93CDFF2
+:10EE5000CAE375787EFF6E9EA0EBF0D9A45FA4E7AD
+:10EE6000D26E65D2F9E4287EB1FB4C7B1EC2694BA1
+:10EE700034517DFE907FDB2905E3DC844B67367DD2
+:10EE80003D9C9FEE373A84FDDB5627EAF0E73EA52E
+:10EE9000627D609EDF52F1DE5E5522407EA14DC94B
+:10EEA000FEDEA1BB8EFB9B617E22E3FDCC7FE6787C
+:10EEB00063AE5296F41FAAA053FA57E08F62D7BBF5
+:10EEC00043F2BE9761E8BEB9A9F8B3FBE98F321DE2
+:10EED000E323BFADEE5B9A65FF617163BA5F5006D5
+:10EEE000F9FD30C9D76E9177B7F9F979CC4102B203
+:10EEF000F801887F3F5B07F254D99F6E6FF2CAD248
+:10EF0000ED4D663CECF6302BD7060FE2E1D63A52D7
+:10EF1000DEF478B6B89E91BC1E2EB454ACFF8413B8
+:10EF200006C3F3D08A4D86E7E1F2BFF37934D6F118
+:10EF300078A1A3AC298A7993AC3FEF5E741BD957B3
+:10EF4000F0A33D75B6BC49DE7778B7F52829AF5AEE
+:10EF5000867E66D6A5BA17FE3DD5A1DAFC4D27B14F
+:10EF6000AE7408E411F5ED70BE9987F725ADE7554D
+:10EF700076401F5EBFCAA44BD6A1C6D78B7B2BE7BA
+:10EF80005CF1C5788F7290BFA7D0064DBA7F02F4AE
+:10EF9000D07BA279E23D5166DDC9ED6EA1F773F138
+:10EFA000EA9655F6BAB3E45BA390E797AB4DBA3750
+:10EFB000D43142FD4FCE7333C31A87EFC7AB3F4BFB
+:10EFC000FCC6CFCD302F97752D7D86F9BD3A98E7D9
+:10EFD000BA68AAE375CCE72C3A87BC7F6224642C1C
+:10EFE00057891D80F54F2F7A8AF2CDDF27D8587CBC
+:10EFF0007F92CC37359E6FCA3C56DA8D1AF589CE92
+:10F0000052183F7C46A33838EFE9AE5358770F9E2D
+:10F010005947399FA1ACCCC37DE43D2689F7D5E69D
+:10F02000AB9598AFDADEB748B8DF69ADFF05CAC562
+:10F0300093AD516AFB5A0D6ABB5B1BA9ADD28C30F4
+:10F04000FAA5AA7ECA00D9822118B7E1517516D651
+:10F05000DBCE7F5785F9DFC8B7CAFE68DABCBCB221
+:10F06000C6B479902FFF1AE7697ECE4FD71285EE8E
+:10F0700027DC39C81E52F42C76E1FFAE5DCAAFBF63
+:10F080003676A9A89EF29791EC1223BDAB1A14EF25
+:10F090005DA57D12FAF7789D4E7A91D4437CFF4AA4
+:10F0A000FECDA2F59DF8E77CA067CCC7B81D4BDD6F
+:10F0B000F3A0EF1B83E2BBEB9B4F2EDA8FF7803A76
+:10F0C0005E94E3CBF71BB67166D534E3F726C73001
+:10F0D0005986B873C7C9F1CDF45DB6F8AE26DC58D1
+:10F0E000583CC052F71F33F9B5AB9EC7EBF27E4DCB
+:10F0F00090F1FA9A1CFF64BDC8E3801CACE3C9FB25
+:10F1000013B9237C47F4F17A6E0F3E23F8D4E9E279
+:10F11000F71716677C2F1212FB8EF4BDC836313EEE
+:10F12000DAF721ABC47E4D62BFC7E6446FA3738B91
+:10F13000F2EF329AC5F30567626D633068F4B3ACE1
+:10F1400070960B7BFA6C3DBF97ECF21B1A9E0BC0BE
+:10F150006B20788DFCBEA61C5F702139DE48E30D64
+:10F160007C7CC10593EA4AF23BBDE5F565FBB74EF1
+:10F170004DDDD3E9C0FA8417BF57E1F79FBE26F0F3
+:10F18000CF6CE5F72A77F9C47D1F3675BF81700C07
+:10F19000FE7DE6EDF5B70CE177C7B0FF06DA5F7CE0
+:10F1A0009FB300E9ADA4E7FF40CF33FE9D81F5F5A5
+:10F1B00093F78BEF7AEE433D612D1CEFE4BF9B602C
+:10F1C000CDD96FFF4E6841FDEC66317F33C1DBC0A6
+:10F1D000E7679107218F73F7634DF60AE0B512BC1C
+:10F1E000D51CBF5BEA757EDE19728BDFFF139EE2D2
+:10F1F0007BA133D1751EB4E7C97F07C09A4EFB5D72
+:10F20000019F76121C53EEC7C4BD28AE1752FEA54F
+:10F210003C7C4BC8DFEC7A45CAD517687DF335A333
+:10F22000FF1B042FE3FBA4D1E828AF887E93D6F917
+:10F2300093F793FF95FA57898FFC9E2C532FBE2787
+:10F24000E8877DFF83CE0BE22FC413F63D742DF6C5
+:10F2500005B87182E349C23D762DE032FDCAEE99D0
+:10F26000FC2FBAA2684270460000000000000000B7
+:10F270001F8B080000000000000B93E16660F8514E
+:10F280000FC121486C62F17A76068678160686B937
+:10F29000AC0C0C3540ACC8499AFE5540FD4B81780A
+:10F2A0000110CF06E269403C11887B80B81D88655B
+:10F2B00080E68903B11010F3023107103303F13FE8
+:10F2C0000E06869F1C08736E03C51E93683708DB05
+:10F2D000F220D8E781FEDF02C437C80887513C3CE2
+:10F2E00070163F03439D00822F2C882A9FCD8F608C
+:10F2F000F38A5266971C503F008DFE9C5880030095
+:10F3000000000000000000001F8B0800000000004B
+:10F31000000BE57D0B7854D5B5F03A73CE3C333312
+:10F320003909794C20E049483055C0214004A1F505
+:10F330001010432FD78ED42AF5A2774004E49554B9
+:10F34000B1D2AB6D46264050F4060B0A0A3A50A8DB
+:10F35000D08246C4962A7A07454BFFB6365A6F7D4F
+:10F36000D4F6C6DAEBAB18E28362FBEBEFDD6BEDB4
+:10F37000BD33E79CCC24A0C5DAFB874F77F6D9AF25
+:10F38000B5D76BAFBDF6DA3B1EA884C273013EC68B
+:10F390001F96DEE60180E24C3AEAFAAF2EDA3386B7
+:10F3A000FDFE7F3DD11D46A69E4C4F0305602C2BD4
+:10F3B0000713A004E05C1FFB95D59BFCD323BF3D46
+:10F3C000AB08E020A8E0659FD2DAE401FFCCFA396F
+:10F3D000F82144B1DCF5D360796710DB25A8DD970F
+:10F3E00080B74B5718E5FA70CC800BBF9B3EFA9D57
+:10F3F000F5337473136B7FEC8320B577C22153F818
+:10F40000D00569D1E6E34AEC577BBFB346E42B80D5
+:10F410000D0E02DE29007519780FFDEE7582F77169
+:10F420008DC16B6419DFC7E02FCAC07F10BE9A0F71
+:10F43000C339FC665D06FE938587E6CFF09C6C368B
+:10F440001EA9AA0658DB0C8F54B901D634FB28BF7D
+:10F45000BA59A7FCCAE608A5498D356170247742E0
+:10F460002AC1501F8AB2FAB27FF65FA0CA67CBFBEF
+:10F47000CA755BDE53C4FAA9C9E4B5A061CB278382
+:10F48000F5BE7810C76773F7E2F83E4A1998CF4582
+:10F49000183ECEE455C16F246602A34775D063A41D
+:10F4A000D83CCE0CCE9B0E61AC7719E1CD23F07A1F
+:10F4B00075D98A4E84F77D560F58BD338253DFC409
+:10F4C0007AFFA7E2FB7C1E1B014AD9F7D5DF6EEA63
+:10F4D00054587F2BCB3CC60A36AF7BD9F8ADA75B1F
+:10F4E000F0B85BFB03E2CDC7FE211E6B36F37C66F2
+:10F4F000DEF6FC19C0F272DE15997E4EB6DF61EBC6
+:10F50000FBEEB7DA88D523BFCA7E87417C851EFC17
+:10F51000FCF67B26C3F980DA4CBF729C7EFB65EC5F
+:10F5200010636D876D86545AE93D4EB5116D4820C4
+:10F530003F6CD62055C1BF1731B9A81672D1A2CFE2
+:10F5400008205F39E101EB389519BA54177966BB89
+:10F55000189F54472E5EA4205FADB7B4AB049072E1
+:10F56000F3EFCD3A986C1EB734D750BAA3596F4712
+:10F57000B9B9E5237566FBF0DEF2F8DF425FDDEA3C
+:10F5800006E2BFC42E48ED50B0BFA61766B3FCDA42
+:10F590005125B53719989FE942FDE0177CBC5631DB
+:10F5A0002EA9C4FACFA8807AD0290FB7B8635F46D6
+:10F5B000795833CAA5AC403C577179A876A77D43EA
+:10F5C000D9F7B5EB2B473188616DF4599287EAEA98
+:10F5D00061868AF25025E461ECED3ED4873DF35F0D
+:10F5E0005ED25E3500201FE913CCD04B3F413ED0A8
+:10F5F000275AF0F519CAC3A9E3AFB63EF96B6DB44B
+:10F60000F24D2F2BDF51E53154A5375C85A7A5239B
+:10F61000B1E1BDF9ADBA4AF059B46F3E73A62B9B68
+:10F6200053F02A1BFCF6E608F1DDFA6683D29B054F
+:10F630001F7A91A7C6B3BCE043281F43F99CEB1681
+:10F64000DC487CE92E4A01CAC9EDC89FE7E0702B6F
+:10F650004D7322D3913522CF9648175B03D663F9B9
+:10F6600040CA9B508EFC29CBF7264CD6BEB8869755
+:10F6700037287B13B866DCEEE7E55F56BACDC444A5
+:10F680004BFBC4CDA6599EA9CFF2E97ACDDA1FEB88
+:10F690007FB8051E3844F5657FF39457797F7EDE89
+:10F6A000FE26E52533517EEAFBBF49698B30D30244
+:10F6B000D638FAB9A927BFCE348767C6A9BCF17E70
+:10F6C0003311B496DF6F229E64F938655D22C1EA7A
+:10F6D0006F845895C2E85038B329C24C23F0CF4A02
+:10F6E000996EC30A1FC777667EB713BC812A5E3E38
+:10F6F000E2C6E7CC6455A67CB2F2AB04C2EF2F8A17
+:10F700008321EC055C1FDD9CC5981D547ECD2F1810
+:10F71000DFBB4B3D51B23BCA59A68C7D8FC4C1AAF9
+:10F720000FDC11ED35AB3C4B3E64F09E43F0C69AC6
+:10F7300066E68037618557C2D31FFC128EDCFCCA97
+:10F74000C777F255FDA5E37E3591B1BABFC31D451C
+:10F75000B3014D282864BF7CF85D53615D965CCE93
+:10F76000686010FD66C2D0DEFD96CE1C08298BDCD9
+:10F77000FFADE95B85798EB7D94A7186CE2C7F853E
+:10F78000158FE7887A4E3E94F3F3F49ADF15B6F9B5
+:10F7900081D6168985FA9FDF7A7F7C662CD8BBDEFE
+:10F7A000D38A42E3D7CF18F715E0E381B782962CCE
+:10F7B000136A33E3155D2CC74B651DAF38766AF1CC
+:10F7C000E9944B09AFBF17BCDFB5C17B939BC96FF1
+:10F7D00016FA9F6A78034CBF9E941CD69C981C9E78
+:10F7E000AA7E8BF057C65FEF69903E97E175D98589
+:10F7F0003EB2FBA5FEFBACF15782458C9ECB7E79D9
+:10F80000C52BE7BA30C3F87C4466FC26C520B87324
+:10F81000F17BAEF900A46CFDFCBDE6930BAFA75ADB
+:10F820002F9DA8BE5DF19B00A07CADAE8214DA18BE
+:10F83000AB0F9F970FACBFD5BF985C8A70785BCF3A
+:10F84000047334C0066CC2EC8DD5D2FEB8A8F68421
+:10F85000EC8F9B9AA1BD85D9350F859BC85E5AADAB
+:10F8600000B567FB524831BB66CC33DB7DB311FE7C
+:10F87000E86D94AE76B3F2207E3FA44F66530854F1
+:10F88000178E62E883D57EF9FDB986A1ECFBCD55D4
+:10F89000EC3B638DD521DE1FFB1EC3FA79D5FC7BC3
+:10F8A0002EB8F26A183C16BCFB3DA978367D59EF9C
+:10F8B0007211FCB7A13DE6C5FD8041A93FD01647B6
+:10F8C000A60B0CF118DB2A7AB79BE5E2FB8175D514
+:10F8D0003F4AE3D67A8DB0EB1E3FEFFBD089FAA208
+:10F8E000AACD7461FB28771DDCE6B0BB82C3657EC0
+:10F8F000A03299751070E46FE9B1E32A27A11D17B2
+:10F900001676D0792BCE9D84EB6C4F398CB295CF87
+:10F910005971F624B4DB0A7D4D2F4C64E317327D18
+:10F920009A44D1D10CA509EDFF8B0AB3F2CBBA6989
+:10F93000BE992956BEEEBC61155766D9FF302AD252
+:10F940007C657E40839DAF6F1376EC2DC2AE2D4754
+:10F95000191F2BF88F098B9F57EDD16BFED3B95E22
+:10F960000BD41837225F0E688028DADFEB18FEE22E
+:10F97000163AF96BECFAAD50B3CFEB54CD67239840
+:10F9800097B9C6E6EEDF295F1B217E25D62F14EB43
+:10F9900056A026AAC487F73F7FE77C73CDFB2B02D6
+:10F9A0009F6C9CABB38DF359E1A530C8C619F3B772
+:10F9B0001F2780E358D7B113C43B2CDE6EE27E1BB9
+:10F9C0006510F7737E98124DD33EEF7AF2D35D2B1C
+:10F9D000FA84F8261DED1C82394BBF5A9527E36F38
+:10F9E000C3FFA9B3F2B3D145A6CB5F7EA7E090A534
+:10F9F000FE7657A8E835DCD49F0D677FAC66DA83C6
+:10FA0000F0076A128E60A14D9F1E6FEE2E38C4F46F
+:10FA1000C6CDFA0CD2C7B9C6FB21D3A3692657BB02
+:10FA20009A7D94DEDBAC43DA8B7E8B08A5DF63F234
+:10FA300087DFB7B27D24A6F73447E9FB96E67194D9
+:10FA4000DED56C52BAA9B981D23B9A63546F43F3A5
+:10FA50004C4A7BF0F9211BAF4EAC6FCCCE3A7366AB
+:10FA60002AE1423FEE3E885633FCAEC6EF16F8D789
+:10FA7000B9263D4E7232D34F7E8F02E1F70840CA5D
+:10FA8000ACC276CFA9B00372CF2B29E67581EAE22A
+:10FA9000E36B35347840CACB6EA075AB640A5BB7B4
+:10FAA000185DB582ED85885796A7EF056C3D43FF3D
+:10FAB000A07F0AA4FD23A98986ED8B44FBD6A08BE9
+:10FAC000EAADABD168DD73F2C508D0A75561E59802
+:10FAD0008FFCD4BE90C6EB4FE4E3159CCF143DB32E
+:10FAE000EB5B751775BA6E0C5F3FFD358C5F2C7242
+:10FAF0005130F50F486928572B691EEBC2535E64DD
+:10FB0000DD317ED4CB2A583F77B02D35AE6BBBB6F6
+:10FB1000BFABCFB6D039A8727B7DC4AC773B10BFEA
+:10FB2000233426D76C1C757B2085EB0EA3878AF0C7
+:10FB3000E60B0532C2C7E7ADB6406A9B9229D70BE8
+:10FB400038DE47E85113D7B99EEF7EF1DDE84EABC2
+:10FB5000D82E05D16D46A63C24DB99F67621D92E08
+:10FB6000018A86EDD6B37690290FCB7630CAD62E91
+:10FB70002CDBC1B3268DB7D1DECE5F207026E61F09
+:10FB80001E1775C52DFAC15F65BAB8DCD8E9948B2C
+:10FB90007F8A40D0E1F184F231E2630ACF2B8AAF51
+:10FBA000F56317FAB3EC721D1E63A71B5459F28C50
+:10FBB0007417A1EC16931DD480F6C6B6D6ECF4DA11
+:10FBC000A0C5A655E3FC266AB6F9493A6DF0093A94
+:10FBD000B606B2D269832EE8B8006C7496F4DA20C7
+:10FBE000E9B52C3BBD36E4A0D70649AFE5F67692E1
+:10FBF0005E1B72D06B83A4D7627B3B492F273DC22B
+:10FC0000E3D28A9D6E6D943F55F470EA850E97415C
+:10FC1000DF5DBB4D7D12EA871B34DA57438DAEE0C2
+:10FC20007E00CA4F70FD8026C075612DFE2AED331F
+:10FC3000368F5D788EC5ECAB39C95727A11D1E5490
+:10FC400064F9A14968876FF3F0FC75C9E393D00E9E
+:10FC50007FC4159BAB92BD93021ADF812F6F2C05D9
+:10FC60001B1948A76B4D3F43BE397DBB2B9A3032E1
+:10FC7000F07881E305B7EF1F6759BF72CF43E017F4
+:10FC8000EB0C3D2138BF45706A299A772F382F62D7
+:10FC90007032BBC240FE66FC6BB49E1A38612E5FA8
+:10FCA0002F7AD667C7FED7D9FE8CED2E1BDFD46C1A
+:10FCB0000ED8F866D8FA425BBE6AED405BBEB2A5CC
+:10FCC000D296376E38C3D6DF9065B5B67CF9E2734D
+:10FCD0006CF98173EB6DED7BF10B707ED9A9BE7C65
+:10FCE00023E2B9870E899A7AA283A8BF3B59536F42
+:10FCF000E3A71CE55FF9B666FA18FEB5220FAD431F
+:10FD000000D7107E24BEF275487850BF140553E723
+:10FD1000B3F2806E26D02FA0EA26A01DE1D2E39494
+:10FD20007747ECF275211A4A8CFE5FD9A5816F4C9A
+:10FD30009FFD9B9FA4FFFEE6E5E417B9BEAB457CA3
+:10FD40005DBD836D97D0DF9360FA71071BD7CDCC73
+:10FD50001C7F18F942F00FE367D42B459A22F6175F
+:10FD6000272767D529BBFE19BAD10E7F459B431FB4
+:10FD70009D207F7F56F2DB1FFE364034817ABC3FE8
+:10FD8000FC8DD114A1FF4E4EFE872CB3E3A77CB1AE
+:10FD9000C721277F5FFCB5AA20F8A2A91EF112DABD
+:10FDA0000C705305DA5DCFEAD9EC0AC92F77CCBACB
+:10FDB0002D60B5F7618CC776FE2EC7A1BC9A2DFFCA
+:10FDC00079E313A847FB2394E03EA46DAD39E62FF9
+:10FDD000E8BDE1A2CA80753DFFBCCF3F43E76F9FFE
+:10FDE00054FB480FBCE5FA6B7916F81DFBB2DEED4B
+:10FDF000135C5EE27E97554FB29F1AB4B7821088AB
+:10FE0000229E8FFBC323219FED0F7D3C3DD5FBB68A
+:10FE10005DB3F8FE26F1725EAA1AF189FA1DCF8D44
+:10FE20005F1E9122BA5FE482DBB17CB88BCAAF0B54
+:10FE300084B7215C5F57E3D76BC508EF9014C55FAB
+:10FE400068697D46C8324F6117C9F9E7B28F56B568
+:10FE50005C5B6F5BEFE0E27AF4634A7EBCAB654DBE
+:10FE6000BDB03B5AB5CF957D9413CE2D1AD99B9F2B
+:10FE70004FFB4885ECFDFCA3D847BFD096AEB0DB66
+:10FE8000470F733A88FA1D2D0FD79F48B9B48F02D8
+:10FE9000418FD8D73BEC971A661FE1795250D82F83
+:10FEA0003529B257FC35296EBFD4487BC6BE7E5D6E
+:10FEB0008B066871C63EEAA37FF393F4DFDFBC7262
+:10FEC000ADEFFEA0B48FDAB87DC4708DF1276A0D56
+:10FED000F77BA88EF57D9CFB7FBB7D945D7EFBC38D
+:10FEE000DF0668E3F6513FF89B990B7FFFE0F6D100
+:10FEF0006E0DA47EFFFFC43ECAC527FFBBEDA30C59
+:10FF00009DFF36768ED3AE9176C4A9B66FA47DC21E
+:10FF1000EC981A0DF51EB3B3D08E39EE6AF7DDCE2C
+:10FF2000E6739DCAB03514E356F87EE6062DB6C1D9
+:10FF30004DFE8DB48E76C666D4E763859E45B90FB7
+:10FF40008AB83D2D0A334660FDF866B7E51C420DC0
+:10FF5000A6F59E739BCF111E989D679FBFC08BC453
+:10FF6000C37E7781DCF79C1DE3F3FA31E101D2DC3B
+:10FF7000DED2D23E4CFF43AC6FB41E1759F1C1F133
+:10FF8000A3468D14EA03D6FE3FDCC536BCF86C7878
+:10FF900061EB101F0F546ECFC9EF3C0D8CD115F4DF
+:10FFA00087B36C07F2EF002C3298BC415BC330D6AC
+:10FFB000FF80D8AA6F60FC5CE8E5696F02D3BF03DD
+:10FFC0003A674FC7B46578EDE17A562F3FAA5F389C
+:10FFD000D5C07515C8AFB8063BA3F3505772D270A1
+:10FFE000718EC3E4F9D995C7853C9B60B7CB5D861C
+:10FFF00026FD4995B9E585FD281F7B7BB7CF251FD9
+:020000022000DC
+:100000006EAB5C937C5E7D62F2399DCB7582FD4365
+:100010007D51E0E827DFB4AF1321B0E459F98782BE
+:100020008F01BEF1998CA7C36D3E03E34FAA5C3AE2
+:10003000C64DE6835E80FC1798A201C659EA45DDED
+:100040000974C1F6479716E14747BBFF42CB7EA232
+:10005000C0C3E5B568C6948A95ACDF6363787CFE5F
+:10006000009DC7813AE77333CA97D7921FBE8DCEE2
+:100070004D938C9F2AF9FE86CE6FD654EDD5ADEB0D
+:10008000D4688FF47338F9832DE175C29E66F851F8
+:10009000AB5C26DA019F963FD44FC81F79D31DE78A
+:1000A0004927492F53DCBB3851FEF8B4E349BAF66F
+:1000B00096AB1B894F8B66CCF5A1DDBF2A32A3CF4F
+:1000C00073D4DE74BD8DE81AA8023395A5FFF33C06
+:1000D0004A26AEC0195F6BD91F39ED75B5B46EE60F
+:1000E000D6BEE856E4B4CB78BFFEE5AAF147545E2D
+:1000F0009A4EEB804FF4B7C6B82D81FAF318DA0C9C
+:100100000C1F6ADBA834EA4FA882E80E5E85E23F46
+:10011000FC8649FB703AEFAECBC0E72977D9C6D34E
+:100120008A02F6F3E79909C50ABF7FB987E0F0E1D3
+:1001300078A8A775D6A182F730B87FAFD7FED16176
+:1001400037AC2EAFCD1A67A0FDADF6AB17D9E13DA8
+:10015000E17641CD78CD6247E56EA7C16B167BAAEB
+:100160000DF9DDC207ABDCB05F61EB70327231C4F8
+:100170000D96C7A23280564CC7231FD6F2757DA7B5
+:1001800042E7C324D206FEC7CF892EF318D49FCBF3
+:1001900017273CA94113A8BE7162E748C707F3F8C7
+:1001A000A422056CF5EFF778A85F0D62749E7EFCC3
+:1001B00077E747A85F937DAACBC0E1ECF7324FFC0D
+:1001C0007E4F31B21D87071B903F621CF70BD0DDBD
+:1001D0001CD6EEF8BA19749F28177C9B1CF2B549FF
+:1001E000C465416C4C3FF3E2727C9C8DD981F5B5BE
+:1001F0005880EE2DB5717B68B0187FC7B219F47DB9
+:10020000C7FABEE57C8BB08FEE42FB88EC1C9DF2FA
+:100210003D708978B33B057CF27B8D97C7671D15D0
+:1002200072BFC36706E85EC013D3025F60F255F980
+:100230009C1AC523CCB2356D057D8D3F70AEDD3F78
+:1002400072B2F11D9D9E5011D9D18EF88E5CED6574
+:100250005CC7A7C5CB9D621F53E35D90A4F393F4E5
+:10026000B9249F95428F542E03B2E3062F8694C182
+:10027000EA1ACBDA47A591AF3FFC18AC7C3218A242
+:100280002E20BD600667D7D1BD094EBF36179D53DE
+:100290000FBECA93C290B661C20E838DFC3E83BC72
+:1002A00077B1C3175DE1457DD74A961F5426ECF719
+:1002B000440683E57E04D32383D0AE637A6990E35A
+:1002C000FBA7A54381F7EF43874D5A9B5FB7B42F38
+:1002D0005320966DFD3BDDCBF9B4ECCAF779FCD722
+:1002E0000D417855CEBF12E9D9568074B86BEEB384
+:1002F00093F0DE49A215A2781765C8727B1C449D55
+:10030000378FDFEB00338DF6F2CAD917773E8A7448
+:100310009D0836FD95456FD479E93E08D71B9BE6CD
+:10032000CEE0E9872AF149D53248E13DA3296D4D58
+:1003300007DD2C5FBE1CE8DCBCBC35A1A03FABF2E6
+:100340000688E23083D181C7F255B32065D2FA0521
+:10035000CF45EA68A9A39F0AE4135C775AECF773C8
+:1003600086DC60E78BAA56FB7D9C52C117A50EBEAA
+:1003700070F65369B44D4378872E73F17B3B33EDB0
+:10038000F76BAAA0FDCDEFE37C0E05A3C8EF556B7C
+:10039000EDE33AFBD720FE75C4CB434B374F3B9D73
+:1003A000D5DFB2AC7E00E265872F964FF7A2F01240
+:1003B00051967D712F7E95F6468EFA19FD99B0C53E
+:1003C000333BD3D5D525D7CC61B5D6841240E327AE
+:1003D000BE4E7ADD2DE4F589C1F3E85ED7AAA25AB4
+:1003E0008A0B3B8879B4A7CA87955AF5BD1BE3767B
+:1003F0000764F22B518F66E1F3E5822F5F077339B3
+:10040000E26194B72982E37ACA4BDE9BCDC663CB07
+:100410009F99CAD26EA137C0E7AB6B7FB5DF6F0A79
+:10042000EAAF894B6C24874527E657B8D21BBF1922
+:10043000C74FD4B36D04EE3F0B219544FA36B5098E
+:100440007F7B4FBD36512F81F73B7BEAC5DBC0BABE
+:10045000DF64F536887AA6AD5EAC57BD3B453DB04E
+:100460008D6BF61AF71E091F58FB8BF6EA6FBBB7A8
+:1004700098C307D6FE8C5EFDED92F0D9EAE9BDEA9D
+:10048000DD27FA03DBB8601FB7A77CA44794C72811
+:10049000FEFDF1E2A9C41F878AA736E07DC46B7E0A
+:1004A000E6163AE2725AAF55C1570745BD96602D20
+:1004B000D90DC966685DCCF696AD787FB81AEFF1B4
+:1004C000CEA17DBEFC2EE9C7BEEBD9BF5F4DF77E46
+:1004D000E577ADD54F71E4EC3BEDC35A3E52851F35
+:1004E0006EC0143CA76C8DB884FFFBB5A459C5E45D
+:1004F000BD4CB3E5D794F3F251ADAF2513789F48C7
+:100500008BD1FD146F041E196ED1233DE37F66F07D
+:10051000F3738C0CFCEF3BE07FDF06BFCCFB07F3F3
+:10052000F2B1BE639313ECD795A84BD97E7998AFFF
+:10053000B885D6F3CFEDFC5C2DA6669D1FCF67E690
+:10054000C7F3727E67FBD429FF58F3D31DF3D31D85
+:10055000F3D36DF31BEF2B9882FC78A2F373D6BB19
+:10056000D91D8BA0DDBAB2F84764FFAF1C0CD4EFE5
+:1005700004DF8BC91BB19CC97607F56794A2BE1F27
+:1005800005E6085F71FFED9EC62072DCA786787CC9
+:100590002A147BC439702C82FECDB7BCBA889FE385
+:1005A000707A7C3ADF37897CA523CF7EF92BAE9B0E
+:1005B000189EC8F7910E3DDFDFBA5651321AD7B5F3
+:1005C000D690A958D7354FCFBA7631AD6B2B23D9FA
+:1005D000D735DC36D3BE48AC357734F3F7043688EC
+:1005E000FBB12BCB6BA9DE06793F253195F49B5CE3
+:1005F000371FFFDABC860AA61FDF7D8EBF1F71C0C2
+:10060000C7FD3FAB9BA19DBF87E0A3F431D66F9C94
+:100610005538C0EC3D4C1F66F61EA6FB9B2394FE8E
+:10062000A8D9A0742F1B17D3FB9BA394EE691E4778
+:10063000E95DC25EDC24FCBD5F2A77D1FAF9BD66B4
+:1006400058AB55A39FD747E93DCDFA5ACD8DF665F6
+:1006500084D23F2B3316FAC85FD199CC67F47AE87D
+:10066000D92ABA373EB15C237F076869357F4CE6EB
+:10067000BBC4EB9F95FA461FA3D339868BD7F3A54E
+:1006800092E1ECF59661BD718646F04030A1868B13
+:10069000B2D6FB16C25157C4E1063D9E0C65EFEF82
+:1006A0003BD85F6D9180AFC84806B3F797C4FECEC4
+:1006B0008A08F822DD8FE765AFD78AFD8D8808F8B4
+:1006C000CA3BEAF3B28F7B0BD62B2D6CA37B3BE7A7
+:1006D0002E06E26F6FB9B1957C15A2DEB6C14DE072
+:1006E000627C5B3AA0AD09EB7DB12906952CAD2C5F
+:1006F00089818BF1BFB78895337822A29F097379DE
+:10070000F9362C0F59CA45FBF10B5839CB5796DAFD
+:10071000CBE578DE3690FA24CD8C50F0AE859EFB8A
+:10072000D5982F71F1FC1EDFBF4C41B92F11E74E58
+:100730001D22EF6DB1B72F09F07C1ACBD938256196
+:10074000DEBE53D42F2DE4F3F65FEAA338E17BBE7F
+:10075000FDCDB239C333F33DED3BCBBF30C732BF24
+:100760007BBE731395CBF99CD6BC96CA73C96B64D8
+:10077000960B4C8BDE2A691B4EF6A4B40F479D7670
+:10078000717A36A38B3BC6E1EA6EAD6C5951457068
+:1007900025E85C55C0B5E55A3B5C83BF69876BCBE8
+:1007A00037ED700DBEAE6FB80EF8B85ECB051F1BEF
+:1007B000DFB48E9FBAD13EBEB1C23E7E6A857D7CDB
+:1007C00023F9A9C74F5BE972F7B7ECE30FF937FBE1
+:1007D000F877FF9B7DFC21D77FBAF1FF56F6B8E989
+:1007E0008B7FE413F6AE6AB53B9B1236BB93D57391
+:1007F000F985BDAB5AEDD878C266C7B27A5E51CFE3
+:10080000B4D58BF5AA17F40B7BDC36AED96BDC02C2
+:10081000512FEDB2F617EDD55F8984CF65EDCFE8A6
+:10082000D5DF20D19F69ABA7F7AA6788FEC0362E17
+:10083000D8C70511FF759D88FF2AF070795D1EE706
+:10084000FBEC52882BB8DFD707C0A843B83E0FE5B2
+:10085000EF21154C5D7E1ADA27CAD4E5A7E3FAD753
+:100860005A00B67DDB343FDFAF8DF3AB348E9E078D
+:100870004D580EBE44D98596FBAE5B45BD9EF260D9
+:10088000A2ECAB96F22F8BF6ADE2BEE0F96B3A5AD2
+:1008900050CFE88358FD2CFC375DF627CAA128DA33
+:1008A0006132B8375E3663EC4D601DD7CDE13A4D0D
+:1008B0008C5B9E1DAED60A3E6E4A8CBBD52FED8D4D
+:1008C0004419E151E7A9FC7E7BE89BCA1F197E60B1
+:1008D000BBCFF61E5081A7E9DE0A064772B00BF0C7
+:1008E0007EC2EAF2BEFD392DCD76BFA7A6C7E81EAF
+:1008F000F9C0057AAD0AB9DBDDD9E06AC876EE3019
+:100900005FCCA765417D5B15C277C8EEBF650C0E55
+:10091000D67BC89779E2F391CF7AF96F5B7CB67D8D
+:100920007E4149DFF7BEE4FDA89E79B08EB2D1EDDD
+:1009300056BF38E77A8EF72FEF9B1514BA68DF7928
+:100940006C383F2F80441958EDB18281F53EEBF8A9
+:100950006B1CE3F9618689F6272E53282F9E2A48BF
+:10096000E1FDBA40519B5E81EB42A483CE0141DCA4
+:100970007393FDB64466D07EFC98B8FFAA45DA268C
+:10098000B9487E047CBAD055629C811B354833BD82
+:1009900076C81DBFD55F6CA59BA920FE8EBB53E416
+:1009A0000F4A5630FA2BBDE7BFC9CFEF8FDD69CCB8
+:1009B000F8554516FADEED376CF70D077EE081F449
+:1009C000E8DCF533F5385C3D7C1B61FC3A82F40AC7
+:1009D000F1ED368FB9CD9F2DCE42EA0771FE3D670E
+:1009E0001C881FE392DFB2795C75D80D284FF29E08
+:1009F0008D3C17BA4AF8C7E6083FEC5C8885B1F031
+:100A00006D70D1FDB1B7E1D9F0680BFD1FF3F3F3C1
+:100A10000526E0E4FF92E7BD57B6B96DFEB0F91BBD
+:100A2000EDF97930A304F5D6BCF56E48317C5EE56E
+:100A3000F097DD27E63B1F9A56A11DB0D2CDFDF2FF
+:100A40007374D006B0A565C98FB7D4CD66F92705F4
+:100A5000DEDF627C6358E46D6130E5C1B89B57F717
+:100A60008DBE780260FBD4AA81A86F0B20EB7B704F
+:100A700057B4DAE1EB0F7E27BC002B08DE5C706810
+:100A80003B95ACFEAD5FFBEDE789B9E23B64BCC5CD
+:100A900031E423AB1FE6F779A924F94779DC457FD8
+:100AA000EDFFDA4FFB25BE4E0FCA4FA3D6D4A0B838
+:100AB00032E7525E77DC1CC4E6E9DE3F293D086C74
+:100AC000F55AFBAED73D15485F32C358CDD45B0A0B
+:100AD000AC1ECAE5810B13B67A55ACDED0DCF5BA94
+:100AE000845EFDE9EEEF79701FF7F60F5EB900E561
+:100AF00072D1232AF8D8B85DBB4390A67D4CCA8337
+:100B0000FBB485FBD4ACE7B81429C0F0B0E8FE1004
+:100B1000AD970BF77A53D359FB853F7A7524303C58
+:100B200074ADE87E6A10AEBB3F50F8796AA27324B8
+:100B3000AE6B0B35F8D75896FE2201CE87477E92D2
+:100B400047F78E959D072FA77EDB2F717B2DFA220D
+:100B50003FE0A679B17ADC1FB74B495567D127F240
+:100B6000FCEBC82E85C3B7DF9DF2237C3BB77AE24E
+:100B70000C8EC69DEF105F4DBE7F4F18F1D0B85F51
+:100B8000B59DE736EE54D3DE9194BEE2A57BA9660F
+:100B900050A9437C72FDB874DF12F29F2F6DBFF92C
+:100BA0001D358CEDEDFCCDF0124D235E9F57A3D388
+:100BB00031FFE0BD6183A1EAAD8E1D61C42BEB77EF
+:100BC000B6271FCF7FED7E6FECFF83C2DEFD31CBFA
+:100BD000DD83FCD5D8BE868FB7EF9F5F47FDD2E897
+:100BE00090A3B7F097B2DEE72E66C071EEB273C085
+:100BF00009D9978BF61CBB3BC1C63DB2F74F77278F
+:100C000018FC8BFFDF7B775F8F76D0637E1DF5400E
+:100C1000E30FFE330C9675F3D2005FC7BA76DDFBA7
+:100C2000FD3B997C74BDE8A5F5A3EBD1D787E03BEC
+:100C3000295D0FFCA5C460F5973D7A1EF901963D2C
+:100C400034B9B4AFF513F935E5B5C29522BA1AFB3C
+:100C50001534CE98A12D52077D9ED8A7829FC1F949
+:100C6000F60B5EBA1FD5C8BE2DAF457A2D21BD8CBF
+:100C7000F91B189E97EE5EFD8E3A321BBE13835C05
+:100C800078D90098184690DE5FFDCA17C760EAA6BB
+:100C9000F39546E826BDEA6CD7F81CA3EB59B9E9F1
+:100CA000780C3EF4E0E15FE3EE357CDC7646C7701D
+:100CB0006F3ABE8DBF8CEF4DC76F39E8780C16DFE9
+:100CC000732716EE1B90F53C589E9F2D79E86B7D9F
+:100CD000DA5B522FF487E7050A87EBBC80B92680E0
+:100CE000F2BAF787DFBFB388D3793A434CD79E6314
+:100CF0004380F1C91BEEEECB513F763FEAD571BD83
+:100D00005FF8E8F3246F5D0F3DE331C84E87A0C262
+:100D1000EC8D2EE8F9E940FB63293FAB82C6EDA1DB
+:100D2000B4379CA1D7D2D4850D4698BEBF42DF53BD
+:100D30005C0E96A60E5EA464A1DFC100BFC70DA91C
+:100D400062C2CB92EDBFF540D04E57651CD2F395F1
+:100D5000A9F83D173DE5FC759CFFD916BA6EE7F280
+:100D60009B4B4EBBB67A358C6770D2B94BBC9BD2CD
+:100D700098529ECF4677B90E9EECB9EA01A77C8BBC
+:100D800079F727DFFDCFE7E4F0F5C38061E31B8946
+:100D9000B7231F66D7FBCF0B7DB1149A1A060EED51
+:100DA000BD0E6A6CE339A82203EF118C7364FC76E4
+:100DB000E4076A2AC1BEAF6A7F82F4B7534F2CCDD5
+:100DC0006167BF21C7DB7F7024EAB3238FFF84F8FC
+:100DD00071E9EE573CE8AF796AE7839ECEE119FEF0
+:100DE000C775C1FA7EC691FB0E8E24FD8DFD67A1ED
+:100DF000CF31D17FE3017BFF8DBBDFB1F5BF28D1C0
+:100E0000EE21FF6A3FE3BCA59997E07CDFEA70031F
+:100E1000BE97F456BBDA90CD0E7A29E0B6C553AD35
+:100E20000AD5BD80FE49B5D063A0FE6BB9D17C3E2A
+:100E300081EBE5336EFE8EA566BE80E7D7C9028FD3
+:100E400081FBDE96D0C56058F4789B039F7A913E73
+:100E500009F703FA94D818EBFE4BC25F60BA6CF046
+:100E60002F0B35941A41BE8F33F07D0A2D4AFE694F
+:100E7000353CB581EED5EB2EDD9F75DDE6FDB98302
+:100E800031DA77B975171816FE1A35F9E233D1053C
+:100E9000A78161DB0FAC9BC2CF83E5FCD70D86CD6C
+:100EA000C0F4F03AA5FB30BE439498C6E30BA57D91
+:100EB0000762DF1FC67D7F456F7B0F4CD3407D44AB
+:100EC000EAC8E0E39B96FBCD99F85D305C14C71C43
+:100ED000A54D8006718A13F26194C550DC77B55335
+:100EE0001A64EA0DD373F3B85EF24237E56F6BF81C
+:100EF000039D7394E6C5C6E41563BE50E1F348D381
+:100F00003E4F5EDF77E59597F5A50F608A76C4EAD8
+:100F10004FF2C266DACFA03BF3E30119BCC8383BFD
+:100F2000D9EF3AFF447A1F03E73908DF6BC3C78D57
+:100F30004AF8F9019FB749F96299778C8335F53AF8
+:100F4000B1049368C615F750BCA7D7467E9381D0ED
+:100F50004E693974505AE8D3158DE07B99FC5D2EAB
+:100F6000F8037C9CE780EF04EC78A7FD7D9D6ABECA
+:100F70001867744C8A7DCEFA027B1C523C8FEF13AB
+:100F800096E5B964DC73DCBA6F4BC262C281BF887C
+:100F90003F4B26DB7D372FBE20CFB29F55831D3CB4
+:100FA000AECCB15F3E4FBD81CE455647FA8EE75A73
+:100FB00029E2C27395B715FB666F05829FFBC114CA
+:100FC0001F8FEF36C1D0ADFC88B13D75D67849D3BF
+:100FD000F68E8E1BF950453C2728F5A35CB1340FE3
+:100FE000F98AD1E156C18721E8149D7493FF639B70
+:100FF00027BE0AE71BA96A52F8F7B8C2FD65A68AA0
+:10100000F32D11FDBBF21697C5FB9827CC647C62CB
+:10101000899B592FE8A269A0056A119ECD82FE4ED8
+:10102000FEB4C7BF4ABB2E28725E1187F7E49867EB
+:10103000E97D31AD2848F12FC1312DDF708DC4F924
+:1010400037E9A8578332BE25CAE315E5BEDAF9EEC3
+:101050008BD71117EB16FBF75E71E2623DBE153FB1
+:1010600064B19B9DEBF17D7939DE131A973D1E51DA
+:10107000DA699F94FFE5FE73B1AFE3290242372995
+:101080009E53137E8B4917E9E46F3FBA5BE1EF1182
+:101090003AF8E9E8DEFC91A82F519EF15DF33CF1AE
+:1010A0005DD97DF020DA572D61300B0A49FF192AEE
+:1010B000C3FF2A65944F61E9927DEF3CFD08FAF188
+:1010C0000FA880EFB91D0DCA7350B3008996076B46
+:1010D0006D74FEA4F3EA7D8EC9E5EF6A5DCA5F9088
+:1010E000DABDBB5BA17B622A9C7907BE73D578D839
+:1010F0000D2956FE2EF07EDFDDCCED86F93F7BB06C
+:101100008E49026C14F0E0FA655D67063404C0B0E5
+:10111000F04944AE0B09B303DF7F9E2BF0531C2B29
+:10112000B4D593F3FBD39C86C3E4FF89CF23FB158F
+:10113000DF11B4F60FC23F62B07FC8974E3C1C77F8
+:10114000C53D40EB4A2C3F4D7610DB4FE3FE23A517
+:1011500044116EA73F65E97E85D6B3ABD87A86EF9A
+:101160004B5F9572EC471DEF224BFC3BF9D61D14EB
+:101170007C1B84600E3C47D3FC7C96E4EEEA9FF136
+:10118000B8B4ABF728F48E93DA797A3E10DE55F2D4
+:101190004BBD0E4DB7B31526C3DF0EFC792376BCCD
+:1011A000FB0D3BDEF36AECF80D45ED7874E2397F18
+:1011B0005CA5ADFE2275B187984FE0BB86FD437CF0
+:1011C000333D49F358CAE691367AE373C18175AB72
+:1011D000D05FD22F1E1DF81BE1C0DF313870909711
+:1011E00042CC5742A24FF32ED3D224574E39947893
+:1011F0002AD73B26D1B76888FCD411D1893297B75A
+:101200001BE86BE742551B253994F1C9793DEBEAA0
+:10121000ABF0314BAFB9F0D02B7320B7DCB537FB57
+:10122000A2739950DFD70CD1B9D5785EAE53BA19F5
+:10123000EB9FD5E77A4BE3B921AAD37A22CE4D8E24
+:101240000EE7EF5AB5A7DF2F41FBEFD6DAEE0BD052
+:10125000EE6FBC92C75B7E2FC4D7DF1F8BF4FC9070
+:1012600087F4DD4D311798E82F38A0A614F443E930
+:10127000E6CFCE45BBED80DBA0F54FEF7EFA5FA851
+:101280007CB48EE7CC65AEB651382EAB4FFEFEA3D4
+:10129000075E0D5F61B18FBAF67FF70BB83E6D72D6
+:1012A000C1826CFB80F9413E7E57CD1F4A902D973D
+:1012B000F8BA695FBEBAD3EE67F3ECE37EB8A5FB7C
+:1012C0002F247BF4D03CFE0EE74347F87DD4A9EAF7
+:1012D000AC7F1AC1F2E3FF53E37A15CCE9B34BA814
+:1012E0000AD133E9677866785C8FF19B28177F74A1
+:1012F000A5F0EF1C8CFF227FE769FC8B7812C68A71
+:101300009AF8BBF18F84A71EC674CA0185FC478D6D
+:1013100047F8FA36B6C3EE273A7B0AD30BACFFBACE
+:1013200003DCBF55D7C9CF07CE7EC15E6F7CA73D1A
+:101330003FA11FFE5D1914FBC830949C4C7C6EDAF3
+:101340006DAE0D72BB8AEE9345B5ECFBAF57437C97
+:101350007FC4F041F33FDA0DD1156C1E47E70E9CB8
+:1013600084F7938EBECFCF1B8E7EA83664DB5F6D75
+:101370000D727ED9E4E1E7C79BE6055337B2793CAD
+:101380003E6FE169B8AFFAF3B7E2A7E97DD9254C22
+:1013900045B8684D34F3611CCA470BBFE7066D655D
+:1013A000D9DE51967221E544CA47D9BC403C9B5FC7
+:1013B000B45ACCAF7E5E0DC5E3763DA6D01953D7A7
+:1013C0000A06571F784CC08A41084FE3FEF7C84F02
+:1013D000E13B90DDDF7D3018E67CBB2271E30486C3
+:1013E000AF6F32E14EA03C78DA2AB2F59F80F5E487
+:1013F000BFDA19E4FCDCE5E3FB70D0DACAF0BD88A3
+:10140000AEFD93A7AD6270DEC9E40FD7EF4DEE28B5
+:10141000C19D5802F4EE1F887B85E517C0D69B2C32
+:10142000FBB59F07273D1F64F37C3EC8E39306C4CA
+:10143000A30AC21DFDE87818FB3FFA8197E83750F0
+:10144000F88B64BB7783DC0E5F1D329F217E595081
+:10145000444A311A0F47E78E06386B3FC3779638F8
+:1014600033691715C6990E1C83EF58BAF87918DB43
+:10147000A7E1FEA311E44F828C54297F78D90DEFA8
+:101480008949BDAB1C50D221A63FC7F88269F4CB75
+:10149000142E70E1DB3BCC1EF5F1FE3AEC762B6AA4
+:1014A00060D4BFA80378D03EDF1F497D2CF5784B70
+:1014B00001D77F2DEB34D28F9BB54E3FFAA52B4C35
+:1014C000A35E33E8FD568AB718BC80CB7BDED02DF7
+:1014D000053D76D10480073E52B3FA47CE10FCB4E6
+:1014E0003A14FF0BE27BE4E1EEC7D1BC8AFA61005B
+:1014F000D27BAAB07BC6BFCDF591BC5FD028F625C4
+:101500004E7DB4C92FEC1868FB359EDBFFE48F1AC3
+:10151000DD9FEED13FF3A6D27A0AEAF02790BF26EC
+:10152000FC5C6C0F84FE61BB3DC2CBD9BF88271128
+:101530000EA7BE19074C2F29FDEB1D279D9911DE23
+:1015400093C710BED187999C59DA3BF5D4C0905807
+:1015500067859E3A06134BCF3332FC54BB3CFA846A
+:10156000D7C23F524F65F829457CE81C47015F4FC1
+:101570005E1F8AFAE5172AFA518E4EE27FFFE709CD
+:101580009423468782F753D3901FD61F38DF8F7C72
+:10159000BFF7F0641F8AD5D5117EDF4C3B7851022E
+:1015A00004FB58CF95DDE0338235880F17E141D534
+:1015B00059DE32FEBB6D8AB86F69E45F94E55D6CFD
+:1015C000995E1DE1F7C9F61EAECCE7FBD134D1BD63
+:1015D00087EF85FF42CA85E477277F4B7948B2566B
+:1015E0002E8B1DA12AED62FF68F72324851D91949F
+:1015F000EFCE24CAC83E5C26ECC36470D8CD13D9A4
+:10160000AF2DE97A1DCF3D96852A29BE7A5931C77B
+:101610009F131F326DFC80D98B9638F846AD9BFC2A
+:10162000638D1F786CDF257E73E145E2F71CC4AF44
+:10163000F2C9F17B4EC820FE70E2F9D3CEBFFCEABE
+:101640007159EFF1FDA3CC7F02C41FE9247F2CBFA9
+:101650004F22F94DEA8FBA6B5A937946465FC8FB21
+:101660002052EF48FD72F6E2B627F2B2E80FA7DE8D
+:1016700088BAF52BD632FC459F0CD23B1D4E3DF26D
+:101680003EFE52467EB7BB434C2E1F78EA2D17FA1A
+:101690004D1E7A98CD9D95470F4EE17EC18E133B2E
+:1016A000EF9276ABB4579DF5A4BD2AD71D79DED451
+:1016B000118AEF09317C29FB993C313C2475BE4FDE
+:1016C000FE7930DE8E70E5319803180B5893AEE04A
+:1016D000FB59BBBCE692CF3C87FCB5A7355AFF123D
+:1016E0006CFDAB567AC321C79F1F12EF0930AE4382
+:1016F000BBA6BC0EF8604BF97B01E523218EEB33D2
+:101700005E2BC5793E2DD6995F85F8FA2CD39F07BD
+:10171000633F45F8DD1A24BCB59F1C6EE95FEC08F9
+:10172000994F229E7C0D26CD63900E51B4F7076928
+:10173000ED4A94C151B8D8507A9C3D725D67FD0D59
+:101740009A6E4C42391A84770AB03EDA4759E8F368
+:101750004A88FBC197F83A9F4213BE717A5343B847
+:101760008FF3F5CC3B0851E1E7B2C7811C7DF4F95A
+:10177000C178FEF9BB6FBF17C273ADFFD2BA430881
+:10178000E71B37FC3A84F7217E7703DF7F5CEEB0FE
+:10179000733E10F8BC241C3B8AF3FDD7E68FEA6C3D
+:1017A000EFAF2CE7E73357A554DC94F6F0FBA29D8E
+:1017B00079E4DB93F925ED036C79C9A74BBC3C6E4A
+:1017C000CB39FFB3C2FC1CFDAADD5B3D830C1C3F83
+:1017D000AE84D9F86F083BEE8D7D21F27F4878E624
+:1017E000EC1EE5413CFCD701AF38F7EF7073FC9B72
+:1017F000D3F17C2E2E48E184F3A9C7F2A8BF2B3782
+:10180000A86477CC66632D67FC1D3F7015EDC39D02
+:10181000F3B8F277C6D45246BF2BD72864AF62FD27
+:101820001B183FC497AFA6733CE73C67271CF12306
+:10183000C2AE70C699CC3FC0CFDFE78271F3C48AD5
+:101840002C712707A6D1B9DBFC7EF63D5561B1EFBF
+:10185000A983B3316EFE180CFFF7E146FFFB9E37FC
+:101860009A8182C8DE6AF6517AA459A7F428EA4F11
+:101870003C3FDF7FF029E233ADA30EE57EEFE15779
+:10188000F32E35327AFC4B5BDF7BE22E961F0DDCAC
+:10189000CF23FDEDB304DECF15FA7CBEB017467F33
+:1018A000D0B73E9F85F818D91B5EA9C767E1DF2135
+:1018B000B4E041EA75273EDE3D3C340FF9E3FCB06D
+:1018C000F3BCF9D3E12557BB256AF678462947478B
+:1018D000439CAFE76EBF70D540367EF2D1D7877498
+:1018E000723DF11CEA09C9A7004D1E9463273F4AC7
+:1018F0003EE9E1BB03B7109E247F30B98A8873CEDE
+:1019000008EE0F9DFCD75F7C5397BB7308EA052751
+:101910009F7539EE43CBF4EB61EE7F9F6B9853716B
+:10192000BFCA969B55FC3C90EBA337B4B6A7AE4715
+:1019300079DDCEE565C98FF7FC08F5D0C2FB3784A9
+:10194000510FBDA9B595E0788B77AC0CE3B9FA1BC4
+:101950005A228CEDDF4CA959E31FEF0F2BF2EF75E4
+:10196000DAE224A0357101CAF19F77B8753C076BA4
+:10197000DCE9E5E7EEFB38DE589E9FB7EFCB1E278C
+:10198000B1F0DE0D25068FA7B5C74B6C7793FF022C
+:10199000FD6B384CAEF3E29EF3E7F6BECFD31BF7F8
+:1019A00089389B7DD3B2C64BC8B804271FDFE3E05C
+:1019B0005F861FF2FB25185CE46E17E7E4C95D77CC
+:1019C0008C7C85C17764FBCFC3CA70AB3F9E9FC739
+:1019D000BFDB7EC53D3E576EFEED12FC9EB1275229
+:1019E00059E32716BBD361DC572DDEEAA67DE0E282
+:1019F0003D2AE03B78F0A297D6F3457B9EFCCD399B
+:101A00000CBE450FB88BA6F369509C84A4574F1C9D
+:101A10008BA0CFC2079FE4E7CB86886711745AF486
+:101A2000C0410FC6E538F139B9FDA0A7D311074170
+:101A3000F46A7F652ADD27DC75DC83EBEC9B8F295C
+:101A4000F4F7399DED176C7D328CFA02F144710088
+:101A5000826EB9E396D2173C3C86EA91DFAE3F3AFC
+:101A600036A32C8E257EBFEF6106C78297BC143F3C
+:101A7000B5E0BE6B28CEE875AD89F3FD969525B827
+:101A8000FE2E70274A744AF9F705775F4BFC38FF42
+:101A9000996B4BC47DA432EEEF4994E13CAFDCFC82
+:101AA000359AE73C88133F2ED8A2C6D0CF724C831C
+:101AB0008607B2C8CD17F2B9DCBCBECD8B8FE8C0AB
+:101AC000EBC2CF997856157F3FD2795EC5DF8B394F
+:101AD00026F6DF1F89F5187075B3ECC71AB7AFEE9D
+:101AE000403ABD35D82CD5299E404B08BCD1BBEB24
+:101AF000EA33E7950AFD46EFDC483B68327EC7FAD9
+:101B00001D6E7AEFC6D2CEF65ECD32313E833BA05B
+:101B10009CC5D292EC7ED099F9522F88F81BC967E8
+:101B2000B9F4C0761ECFF2FE735CCF605C0E957781
+:101B3000B8D3A5B6781CAFEDDE7526CEC42DE4DC97
+:101B40005ECEE0A478991EFC3EA6A4F0FD63C92FEA
+:101B5000F3D67BEDF1793DFCE37CAFC71E3F33DF6D
+:101B60006197C9B4D7FA9FEF38AFDB7C62F1338B52
+:101B7000DD298A7F5AFCA297F6278BF7B8638897EE
+:101B80003FED7EE2379732BEFF53BB9463BBDE75F9
+:101B9000CAF182BD63219B1CFF291885AC72CCBEA3
+:101BA0006795E360E65CC38053AF77E7E7D0BB1788
+:101BB00038F0C9EC867C8C237EEB078B4E237F8527
+:101BC00003BF52DF3AF5E86B6183F0DC3BDE8FAF99
+:101BD000FB99784C8E47C99F0B7FB884C6E9E163B7
+:101BE000C9A7928F73C48D39F1E92C2F44DFD9D85E
+:101BF000DE7E91443DD4E0DF674A7A80BFF3E60A97
+:101C000044917FFB3BEF7C36BF42BEFB7616DF176D
+:101C1000F2F3CE6850C7BF5401EE2243CD76CE1EFC
+:101C20009DECCA6AFF27F2F9B9463EFA2318DE1E78
+:101C3000CE37F8BD0735261C79ED748F81CE56114D
+:101C4000CE8230C9995BC4A9B09EE93E7A34CFF503
+:101C50009EC1FAD892FFD4F91AA36F74B4EB9AA17B
+:101C60002CFF50FE4BE76BE8AF9DE07AB092E57F2A
+:101C70009CFF5B9E3FCB35DACD587527BC7CFE14AC
+:101C8000567FA998F752E92769196BF39368AE5705
+:101C90006EC7F31CED61372459FE6626F7BEDACC19
+:101CA00039739E17127E96CFF3B094E55755FC7AA0
+:101CB000156E229F0EC4EFCA277CD51B88E723BA76
+:101CC0008FE27796FDE43C8A237D389FC7BD9FF95C
+:101CD000E004FAFB8EA7108EDDF9C5B9E16871F357
+:101CE0007E8EEC3D7332E2F9CCD3D0A796A147ADFE
+:101CF00066D0773F437B82DBFD11BCDF922CF05036
+:101D00003F0FE74BFA9D582AE35ED43CCE176ABEDC
+:101D1000ABE901961E14FCF0B8C00BFEE0BEFBE878
+:101D2000A3A5DBF8BB56DD4390DEAAFAEEEFD1DEC9
+:101D3000ECBE2C8FFE7EC84B018EB797021C6F97AE
+:101D4000E4AF759FC1BED7FA865C834CFF92B2FBAD
+:101D50005A4CB7EBF15F723C401AFBBDF47295F739
+:101D60001B6C0AE17B718AC9ED708531D32C868F9B
+:101D7000A4098667288AB03DFE43556BBBD3347EE9
+:101D8000C8363E94B37593C9F925E339BD186E6919
+:101D90001D7D7E1CCF4BF866A62A939D06C1F37B62
+:101DA000E48F51DED460DC4F5DCACC2AC8F25E7885
+:101DB00057809F6F7661FB9199F881C6FF76D17E3F
+:101DC000B611E7C0F20F1E01F1770AF9BB3BD2EF63
+:101DD00031FE975793FF7BCCFE453CCE44F8BBE4E5
+:101DE000797EDD217E3EE7F46F4D80B5A44FC73B81
+:101DF000F4E884FDFF44FAB5BFF3B9BF48BD3A101B
+:101E0000069EE4F91CE896F3B9FF01DBE0C6DF00AB
+:101E1000800000001F8B080000000000000BB55A76
+:101E20007B7054559AFF6EDF7E25DDE9F48B100838
+:101E3000869B0448421E36498010706CDE4C8C1222
+:101E400060406418695021E6D56CD6416A748B0EE7
+:101E500041459DB2326A29556BCD5E18DC45496615
+:101E60001B4934BA9D4C0710120437082830AE665F
+:101E7000DC1D44973C645670D42AF6FBCE39977E1D
+:101E80002428F3C790A24E9F7BCF3DF73BBFEFF7CF
+:101E9000BDCEB91E3D7883F900D7E9DF9D91B62A02
+:101EA0005902980EF44F0729000D66FCA5005C3915
+:101EB00091990C385EAF07909D004645865267E4C5
+:101EC000B9B66D38CE14E9BF93ACB0790ACED81F3D
+:101ED000001BB5B00E0AA3E6B5F37917CA568012F7
+:101EE0009CFF12A8A60C8069FD392FCFC1BEA1C7E7
+:101EF000002ABD979EA0FBE7746A00459BD1FBBBFF
+:101F0000E2305EDA91602B84DBF195A93A50CC6C1B
+:101F10005EB88EFF1394445072227D4B8E33A62FF1
+:101F200027DAF64032FE0878FB52518E627E0B9221
+:101F30003CE363E679C7B6A487E42EB66FAC20B95C
+:101F4000934B3363E68113FACFFAB19F837FD73384
+:101F500069A995C96194BF082ABD12CAEBF9183C5A
+:101F600061947FC6193E4E7BCE130EC83EC4B1F4B9
+:101F7000E3D8EB6510D5C779B67EFC95E348943C71
+:101F8000A5F624F7C53CFC311EC65F9747C5D113A3
+:101F9000269CCEC81E540334F4E22037B65F800A74
+:101FA00088DB34284C0686AB0C2AF6DF04DF0B7383
+:101FB000B0BDB66DD8716472044F8737164FD79293
+:101FC000583CC754C6E23976752C6EE37CB138A50F
+:101FD000554D8DB97FDBE6A298FEC4AD6531E33384
+:101FE00002F362FA593BCB63C64F6E5E1ED3CFDE5F
+:101FF000B526667CAEBA21E67EDEBEEA5BD27F41C4
+:10200000B021665CBCFE6FEFF855CCBC65F25A1986
+:1020100032233C08E01FF1A088544CFA473D84610C
+:10202000A4FE67BA03C4F8BF59FF5B49FF9628FDB9
+:10203000CB6B937DD691F6ABB59A5EFF89D63A9D70
+:10204000F48A73A070D748CF786DC860DD2961EB42
+:1020500040EEACC5EB5BCDFCFAA3029F6B09E92A0D
+:10206000ADDF113AF657095B540BB3C3C02716B561
+:102070000979F3A8AC3412AF5E942B254079D25085
+:1020800075BA2CE4910EAAC8AF3CA7D3ADAB8C9225
+:10209000EF793B0E1E43AD8EB5FF6C445BC5F7A6D2
+:1020A0005920602E62CFD1DAE89F1770DD36170312
+:1020B00005FF55EC5C3001EF3BFA731407E02DECA3
+:1020C000DF06702191CB7B2191CBB9C6A434F59367
+:1020D000FF90D5C924CF5EBBEF5FECF89E0BD2E337
+:1020E000067C3318DC0103D95D9A1902367C5F93B4
+:1020F00001D65562DF016EA901DB6478C54EF68515
+:102100006228D7911487ABF392FBF1FAFB24C23813
+:10211000B2318F0E6600DCA7F9C3AA5CE60FAFE010
+:102120001AFB48A17A2519B0BDF26016BB7EFE7E6F
+:10213000B442B4A7F3468E8786C325E127BFDC6689
+:1021400066EDE56DF618BF59B5FB852405E7399FA7
+:10215000034B8251F8750BFCBAED32D3E7A0FAE7D6
+:10216000148267E8A1EFA690D07EA9EF492B0E79E3
+:102170006AD73F5402EAC1D8B62C803A815F18155D
+:10218000365E9BC71F9A0B84033196E6BBF723D8B4
+:102190004CF2DDFB1DB651EFEBB31BD8737DE27D36
+:1021A000ABB0B1236EAB502F0E6A8FCD5944768100
+:1021B000D7C312F697F68081EC61992FC340F29C49
+:1021C00006CFD97694E78F76FEFE9F41A581E4FA8B
+:1021D000F0FEBA241A77633E6D1E14D681F1E42313
+:1021E00047C090827E6BF80EC9B34761EF33D3F5D9
+:1021F000CAB5694F5895C8FB3E04DFC059D4F77281
+:10220000F0B079B5F9D1F262FCE21B55359FBA32D4
+:10221000C91FEAC04CFEB0D3C4FCE150F5B5D69757
+:10222000F0FEBAB4FEDB8CF8DC85EAEFA6102EF7E0
+:10223000ED924141FDFF39C9F739F147C3E3FC8312
+:102240007F49A2FB6B4CEAAB2FA11DC07E93E755E3
+:10225000A0E7F6B3E7B4715FD9E75EB653FC2C454F
+:10226000A066DDDC3E35FCE7BF9E3B9678A6F1EB31
+:1022700061C1AF86D7B2C7129F1A926EF08BF75F1B
+:10228000CD1A4BFC9A21715EC6CFDB85FC52B27130
+:10229000DDC82B0579D5F5CD3C17F98983279CC579
+:1022A00024A71E7C3A47141F0EBEBF268FEEC339EB
+:1022B000F72DC94BB6194039EF052EE749611FAB21
+:1022C00043AE62D23BDA9DCD81E3D6FCC76B037F80
+:1022D000247C3AF7BFFA188D29B9353C34FF7420B5
+:1022E00091C7231071CE2370C13897A3475187201F
+:1022F000D143F9C2CDFCD601F20BC8AB6B3A747C6A
+:1023000059E4AF2A81FC82053C0AB5E865DE9B8D65
+:102310007A6CEAD6C133D8B59153D3FC4F29F66510
+:102320009DF03FE035A7621C11FE29E737EA921DB8
+:10233000CC7EBCD6F533984B6472951CA9AEA0F741
+:10234000421FFA7194B512FF281ECC86CD87135018
+:10235000CE19BB303FC07133CFF1FB9A5F9F15D6CA
+:10236000AD3726D3B85F7F25DB08A2D83830FB48CD
+:10237000F9E734EF6C887A6E94F830C711971FDC58
+:10238000627C584C0100710FE670FF1E0C27AA8179
+:102390000C366D716501BA26B43DBAFFEF6E1E476B
+:1023A0008CD2608E19FDF05DBFD9B373E71CA4C356
+:1023B000248E0BF59BF4844531E3F18DBCF1C854B8
+:1023C000E60FE17B948AF0B20B99E3E42941BBE389
+:1023D000C1D8139377868F7E6BEBC775B43A95FFA0
+:1023E000247D0D635E437E2141DF6F748CB2BE3766
+:1023F000C9BF22FF9F77E898BCE60EC9ABE2FBCDD0
+:102400008A17245C4382DD3E4D9622E3173A78BE5C
+:102410005B77F442BA11F535A03B61CBC7F96BDBB2
+:10242000DFB0E1F2618BCD57457CAE39FFC10C0ABC
+:102430005D00BBD32B9308A7CC64B2A7023D04F484
+:102440004523E5F0EFC2C520E5EB77B9589BDB21CA
+:10245000B1F5F9C37C9D831D4DCE68BF71E3B93FD3
+:10246000748E27BDED1F03ABC91F17848A37118FE8
+:10247000491603EAE2F56FF2D87CDB1C194C2FF801
+:102480007E3D5D075075CB71D07E033E87F30E7E97
+:1024900023B371DABC051D73653BF2283FDC7C88F1
+:1024A000F2C2849049213D27EC058E4B2881F945E5
+:1024B0007FD762A0FC75C8011E09EFB7260E7F42C8
+:1024C000BC18EE34297B24C2AF199C387FAB91C76E
+:1024D000CF5C348437AC91EBDAFB12422F03F92B3B
+:1024E000E48757A5FBFA66B8C31A8D7B12C35D75E6
+:1024F000705EB526867556F2FBC8C93D4CAE889C09
+:10250000C0DEABC999CBEA8056E3F0C5C7DC4C2EE0
+:102510003BF12117B89C10CA565EA5E7ED5EB68E5A
+:1025200004BBE2094823E5F217625E8C76F7DC769D
+:10253000B861E764F7FEC448DF8C36D19AC9F90D5B
+:1025400081B33B17CC89EA93C32A8D3CDFEE38B7C1
+:1025500073C704561F0564E48305DB2427AD93C7C6
+:102560003F340DEF98228E830771B298F9FD1BE37B
+:1025700091EF56EA5BF9384FB2DD522E31BB01B212
+:102580009B7AE1671E91C217EF44D57E1D3E54A889
+:10259000A02CB5C7DE61BCADD1855E2A20FF98E8CE
+:1025A000FB03F9F7B73ED6810DD7FFE56B096A0546
+:1025B000E291F3F6EE14AF75E47C4F9DDBFE7C1ADE
+:1025C000E9FB6D4941A4312F1C4E27F9EA439F1BBB
+:1025D000BDD82EEEF89391E2D32F9CBE5EB283D28B
+:1025E0008EC6F984DF2C686EB25B995FF4114F835D
+:1025F000A9DC7F5C3933654F6314DE43C2BE60D80B
+:102600003791EC2624ECB38BF21F6CDB451ED6DE33
+:102610007D5F965210792E0087D200E7DC0E47D2FC
+:1026200008E71BF3A9FA25C4A7BC0FCDEBBC517C6E
+:10263000FB42D8FB17E27D01A7EF53C2A1A6FB33F3
+:10264000A30DD7E5FF9F603AC5A720E669F61FF006
+:102650008BFE38BBF1EB878D34DE7F09981F41BDBF
+:10266000EE48463DEDFFB063EA7A2B931F9271DD91
+:10267000EDE74DCC6FB66770FB6B3C7BB590FCD63D
+:10268000D5CE9A8984D7298741E3F9BC44B2A70300
+:10269000C0FC98668FF9648F287A3EF1BC84FAB941
+:1026A0006CBE56635F39B3BF761D90FD21CF19EF25
+:1026B00091E776CA3FF2EDC87BF67C36B3E7D63EAB
+:1026C0000C78D80FA01F9FCCFAF35650BFB56F817E
+:1026D0009DD9B30EA12D22BB0C1F62F304B1A6221B
+:1026E000D54950199DA72E74D898BC9A7F5C21ECCF
+:1026F0003498A3247B703D16598EB183A878C9FB0A
+:10270000229EAE759A9E7E71025993880B222FEB02
+:10271000127930F88A99BFFF4711CB1ADE2D5BDAA8
+:1027200082EB6D382973FF2F787248E4C947B6A54C
+:10273000B23EC50B05F5341D5B2FFAD319DECDF380
+:1027400029FC942E693E4C6D596570BE81E2E2EA27
+:10275000BEC3066ECE79C4BFB6433FCDD313DFCF21
+:102760009B2001456CFB76F893D711872D5D88FF80
+:1027700028710997C3F887119DF1F166BC1992FA87
+:10278000EF99EDC1FACF39EEA7FA04B41F2206E2A1
+:1027900071BB73ECD30114A8C3E92D72227E9FB8DC
+:1027A0007CAC1D3AF56D0AF9F4F6339FD9C8DFB752
+:1027B00019BD79C4B3B64CAC1746E1E744A781F91B
+:1027C000FB12536C9EAEB52B9DBCAE9A12806789EE
+:1027D0003FF56DB25D457D0FB4C95E23E65117BD6F
+:1027E000BE143D427A0902AB66537C17F5EF431CD9
+:1027F000767888F2178C331B5F34C4D4A5B5625F3A
+:10280000231BFA9F4C439CFC7B2556D756C5E523DA
+:10281000B594BF14527DB1DB48EBA9DE1B370FE541
+:10282000318534EE87EBDC954E91C7644116E53176
+:10283000C823564F0F9F953D7B2806EAA1C784FC0D
+:10284000DDAFE338A1DF64F6A8E533896EEF22B28D
+:10285000FB450E9EB7B48ABA75B8555299FDEC4344
+:102860003F8FFDB24BCA6EE0389C499D41EBE1BC05
+:102870002CD3F3F165A10C667FA55EACE771DD1B7F
+:10288000B19E5769DD5A9EA71AD8FA31FCB23C6F47
+:1028900016A84D361CB7699FC4F67D6AF61962F218
+:1028A0003CBFC0A776D7A9A3544ED605E3EE0B7C58
+:1028B000FC71F8BC413F668DC4E9574EB11F900EC4
+:1028C000E9D1F91EF43847AD0B347CB43CFB7F0DE5
+:1028D0003CBFF840CCAF8DDBE5E47EB4DE0B6CFF93
+:1028E000A856955595E783D6F5C89707045F1E103F
+:1028F0007CF1031F57B74F52C314AF7ECDF56EC6A0
+:102900003FC2E5A1E0FA4569CA485E550B3CAA5AA8
+:102910000C2CFF05D86C24FBAC7A256E9CC0A53A24
+:102920000E977A9F14271FCFC7FF56F96A0C7CBFFA
+:10293000A606F91550FE7EF2C6EBEF0D8DE753614A
+:102940006A8CFE96B86E497FF179F281A3532DF41B
+:10295000FC959E4CB60FA1F1267E9E4522CF5EBC13
+:102960008BE7A3031DF32D05544F9DD07B249CA71B
+:10297000F8E4FFD90A108FA24E192A708AA150F1EB
+:10298000B3015CE7C19E492B148C0F4527F52CBE83
+:10299000149F2C52A9AE293A5964C94A62C6E3A2CF
+:1029A0007A01E761F179E8C4A4D3F9E4677B16946E
+:1029B00010EC8D278A2C94471C04BEAF219D2C71EE
+:1029C000F547C59BF79C325BD793A9FFFD1CE5F942
+:1029D0008B0F183C948F2C360CBF3FDB4DEFD77B11
+:1029E0001AB15F7B72C3F604D2FB6B9287D2F1A35C
+:1029F0007D0DEE9F937E4306BB89C9FBCB43743F9D
+:102A0000D0227926E3787FE7C2BC56EC17ED2EF68C
+:102A100010CCDAFB8A1CCA0B15942F8EB3B03A7E09
+:102A2000F16D0616772F8FB7FC8EF2A56AEFEE4593
+:102A3000E48F2FBF73D048FE60A85582545CC8D184
+:102A4000D4C3BF0FE03A2FBF79CA4849F9FCB65347
+:102A5000C6FE1FC827065419C2AC7E6F36521D54DD
+:102A6000B75BEBF71B494F9522BFAADFFB27D6AF19
+:102A7000A63A01DF57FD8AAC2AF8F370E75B46C23D
+:102A8000BBBE4582B11951F7F74AECBEC6FB0DC07B
+:102A900079B041F8A71AB10F5943FB90781D7672AF
+:102AA0007FA3F1FEC17DCB8E52F87EA839D60F3DB3
+:102AB0002C78BE89EA52567FFB8CA4D74DBBE2C668
+:102AC000099E3FFC233C4F76093F950BB9C4F3ABFD
+:102AD00073793CB97A2AD1928FEBBADA2B7B007EDC
+:102AE00090EF2CFE9E10F9C295B08EC5336DDC6060
+:102AF000C75F58BCF19FB862A4FC7651E82BA68F43
+:102B00008A50F702C2FB6EF0D5127E77872C76B220
+:102B1000FF8A7EEE0FCA432695F6C1EF86E00ED2FD
+:102B2000F350D7BFED70126FFE95F30684BFDB2420
+:102B300070DD2470DD840EDF852EB63ABFFB252CB8
+:102B400007A01CB81F2A0F0A3FF44A2CCE1879EEB2
+:102B5000277DD5874CF00CDEBF4BF8A3BB5AB83F9E
+:102B60008A8F93F5621F60685CDE52B6DF8AF52EAD
+:102B7000E571B52DB1F8D78B7D81FAB8389CE9E2C3
+:102B800079C28FD5FFF17A5A10A7A78A61CE9F72BA
+:102B90008A7BB8FE9EF0F67CDAB7D3F08AD7538FE3
+:102BA00092953C5A3DABB5EF8BBC5FEB2F057EFE9B
+:102BB00014B4375BA3EBF8D75D3CFE54CF9203A46B
+:102BC000E71BF5CEA4C3858A2E52EF609DB3D635A0
+:102BD0009DD73DD370EA63136470BB23F5CE53A930
+:102BE0002F541451BED2C2FDC86029CE974CF93C77
+:102BF00030FFE56F31A954A7F8913FACCE21DE60DC
+:102C00005B199216126FB07EA872218ECB68EB18FA
+:102C10007158D6C1F39E650BBE627CEB9DC4D77B19
+:102C200045AF8C1DAD9ED0EA88FA6F789EAA5DAF45
+:102C300047BBA7F1F52189D5C56D87FE9A9E81FE18
+:102C400073A8F35AFA7A6C5F76F13C4ECB53873116
+:102C50004FCD14790AE5CF1BB9CA6013A6C35B91A7
+:102C6000871B459C036907B3937A4A76896FED12F7
+:102C7000DFC7791B2FCC44FFFB4122CB63063FE427
+:102C8000E743F4FCE398470D6E081E71E2F8ABAD24
+:102C9000128B7F1B31C7FD49D1487BAF13BC6C84BD
+:102CA000EDA22EDBC1DAF29C039F3D46FEA8C5AC27
+:102CB000907F1DEC6832B2FD6535EAF9CC91F95090
+:102CC0009DE06FDD8FEC6BBD1EC74B5C07CB6F8744
+:102CD0007A65BB4962F8FD767C344E22FF693B94ED
+:102CE000C0F43C74CAAA529EFFA5E0DF65B1EFDED6
+:102CF000582A335C74B3789BD7F55626E995F4E0EF
+:102D0000A37D94AEB7A67AD93E9FCAF858B34FA612
+:102D1000C3BE88FC410BDB0BD5FA1ABE7E812FCADD
+:102D200035C5E88EC8D5AEEFB77946B11B493AC470
+:102D3000F4A69362EB5CFFDB72A51A654FB89E7533
+:102D4000E4DF42821FA01F4E21BF1C76294CBEC665
+:102D500010D7B3AE93B7F8FE557CDFC6C0DE3FE2B6
+:102D6000FEBC402DDDBF9A6101C6936F0215D4DF12
+:102D70009229333FB5E583EA6C887A3F48BC1EF759
+:102D80001B8653583D7C4AC7E4F39FBA9232C94A26
+:102D90007E70F7027B3EF937EE1F8E665AAA88DFF7
+:102DA000017AEFD8C83CE52E7E9E00B4DE54CA6698
+:102DB0005EE4F38AF56E87E50C87ED8267DD221FFE
+:102DC000C5BAE93CD9637CDD74B37C37AA7E6378ED
+:102DD0005D9DAB9CFE39F2A0A8571FA07AFDE0399B
+:102DE000EE271A3B377D4A75B0FF8209C84F6CE960
+:102DF000DA944D71187CBEDB29BFBBDAF5F0ED6CBF
+:102E0000FF52DACEE40A907CA994379D4DA17CA8AC
+:102E1000AEF36C0A8BEBEDD35FA03C09F3A2BBE8E9
+:102E20003AE62B8C7F45274B18FF0E9E2871659143
+:102E3000E0E0B1D0BC75BDFA4AC2A7AEB7E4BD0AA6
+:102E4000CA5F4ECE637992961715533D4E7952EF75
+:102E5000A4983C69D8C5F3A4A1EE04B6FF2141268D
+:102E6000E70F4C8AE14F6DDBBB2C9FA8ED90BDD1E5
+:102E70003CD29ED3BBF57C7FD42DF81394BC8C1F21
+:102E800007785BDB7190ADAFC61064FA6E6C31F001
+:102E9000FBADBC0568E6FB2CE00C101EEFD125D481
+:102EA00043B9519D40FBEBC733787D11AF8F67DD90
+:102EB000FC1CEBF879DF44E2CBF1B9BE6CFB287166
+:102EC0002300F378DD2D09BCDB0C2CAF8C1FF7B48D
+:102ED0009BEF4FD85C1073DEA8B5BF7473FE941BD4
+:102EE000F93E55FCFDB96E614F289A0E7971BAC250
+:102EF000607F46D413E3D0DFDE23FCED8ABB0D2CCC
+:102F0000EF382DCE99EED1FC6E298FDFDA7EFFB23D
+:102F100057E0092CFFE16BC867E760CBBCB17E6F5F
+:102F2000A5C8AF562C89BB2EF2A9953F924FCD7202
+:102F30008BBA610A4CE17583D542FBA25FF718ECAE
+:102F400032935B9D545930729D9ABF392ACE877A4D
+:102F5000D00F52DB98FB11DBA73ADE7DFEF70EE6C1
+:102F600047132093EF3BB2FDFABA9BECD737DEB0A4
+:102F7000D39FC5F04ED3D300E5F9F923F5B452E061
+:102F80005D67BE6C64E796B079A74E8E9C539A0C31
+:102F90003E6F1AAEC3D031374CE7978DB926962FC6
+:102FA0000D2C9454F2F72867BA29CADF0F8CE3F985
+:102FB000D7965512DB17EECEFD88C5F1BA709F91FA
+:102FC0007835A56DFD13CC7E037086EA254D9F4BA9
+:102FD000CD3C7EDED0A3B65EBAA9D0FA9C01EE97B6
+:102FE000DDACA5F1142FEF11F1716969ACFEB2A14E
+:102FF0006F11ED8FDCEB9558BE7433BD2F5F3DED47
+:103000005DA2DBADEABFD9EDDBEAA6FDA2BE2BAB2C
+:10301000687FF778EEE7E9145FEB6FC2E726C177C8
+:10302000BF859F8BF92DFC3CCC93AD34F5233E2618
+:10303000876FBB9BFC87EE7BDB54A079FA7FDB209C
+:10304000917E80E9E56676F4B498F769B79DFB6FE9
+:10305000373F1FB2529FECD9A04E203F01F9B776FF
+:10306000CED7F8F6B142D2D360776FA1314A9F979D
+:103070001BD01F507CE93C9CA258A3F9A6137CD31B
+:10308000B35692968BB819CBBFCBC43FD2FF81C346
+:10309000F7505D38D0B6C22D295171B5FDB46D72AF
+:1030A000D4BC0321998DC77A6CCACAA468399F60C1
+:1030B000720E04F97C00FD53561444DF6F123CEE8F
+:1030C000673C7E2A67333B77D778AC07CEE3FA8E2E
+:1030D00065C0E2945877D0883FA8CEE832A9744EF4
+:1030E00041FBED8E283B392EEC63261607C4CF59E1
+:1030F000109069DE9938E35AEAEB21AC77D2796017
+:1031000058E6E7DD1380783D43F07AA63EDC2D15C6
+:10311000B271EC5CAA0CFAD8B89FC0306BBD60D716
+:10312000533B0F3CAC2D3587EF2277921F0CB2EF4B
+:1031300092C2297AC745333B2A85D1F41759BF1E5D
+:103140002E6A3CC5C198F4B07DFCF8715F0B7FEF2F
+:10315000A11C8EF43C006C1FEE0EE897E925B3F538
+:10316000B084BE27BB430FE64494F7C0111DB3E7FC
+:10317000AE7E45257FE67189E7BEC0E7B03FD3CB81
+:10318000ED9642107DB7A2AD371E87329C8FF605B3
+:1031900067EAB1F2653886D9FBEE24C171DD73416F
+:1031A000D153FF923B437CEFC6EBB4F9A24ED399C7
+:1031B000030C8F418A8F63F8798E0DE7296B96E0B7
+:1031C0001C9DCF64F1F56AF39761284DA67C5AAC3B
+:1031D00097B6C2CF39F9398F8D9DCF2DB0135E527E
+:1031E000384577DD72EBB80EA50093DBF6C0F0E052
+:1031F000632591F32E4FE8D839FA2E47F27AD97722
+:103200003D1EB3354CF939B2E37274DEAD1BB30128
+:10321000C6E0FA24C5CEF0021F28947F8C8D7CEF87
+:1032200002D75D91EF6908C64B2991F37DEDFB9ABA
+:103230007DEA7245877A59ED367B482F45E6F46280
+:10324000AA07F7DA7D30867D67D332994DA657A756
+:10325000572645F86E016F29E1AD9DEB4B427F3754
+:103260003BB7275B259E5BD0EDD37741CFA2BD98BE
+:103270009DA37D7FC4CFF3D10A15FAEE081E9FAF40
+:10328000D077014F3ACC9E67C8CFD1FA2C91F53553
+:1032900099F9F7044D66FE5D00EC98CEF6CF1E114D
+:1032A000E7114D565D0ED55B4D90E8A1925E93F708
+:1032B0009124CEC747FECBC2CE47E3E5FE3ED19771
+:1032C0004FF86AF23F2A7BCE61EE1383E71C0D4F65
+:1032D0005D04CFD56A6653BFC2F02BA1E7A799D48E
+:1032E000DB685F648D897FBFA4E1860A65A4B60BA5
+:1032F0007D68F8D949DFB40E2FEA5BE34B6604BF63
+:103300006713396E06FA72228B3DABB0F3FC385C62
+:1033100034DEFD3FD45368B1102A000000000000E5
+:1033200000000000000000001F8B080000000000EB
+:10333000000B7BCFCFC0F0A31E81FDD1F8E8389100
+:103340000F534C94118257B3E0D78B0D5B3122D8C9
+:103350009EDC0C0CB29C0C0C7240DC01C49D40FC49
+:103360001288B5B81818B4813801C84E04624B20D1
+:1033700076E086E8A96567606805E25E209ECA4E31
+:10338000BAFDBF2518181A6411FC0B4036AF02E9CC
+:10339000E68CE2A1897F1BA2F245B451F9F6BAC0CE
+:1033A000F46184E08B6A9366FE36A0DEED46B8E5F4
+:1033B00079CC51F9CC96A8FC6E3354BEAA3B840656
+:1033C000009B2185B9B80300000000000000000048
+:1033D0001F8B080000000000000BC57D0B7C54D53E
+:1033E00099F8B977EEDC794F260FC20021B9794000
+:1033F00002267188E1A5A013040B886CC017B4AE37
+:103400000EE111DE44B49AAEB8B99010420861B42E
+:10341000A8C18D3841405468830D4A57AB03524BC5
+:103420006DB71B1505772D0D688358A0298A4CFFB1
+:103430006BEBFF7CDF393773EF6426E0BAFFFDA743
+:10344000BF7A38F79C7BEE39DFF79DEF7DCEC8243D
+:1034500087A4DD44C837F0474BBF891032205A9209
+:103460007255206308F9A195E09FD62FB6ACAB2129
+:10347000246C2124B290904E27ED28555949212DD6
+:10348000EF982E92744292E07D85907AA1EA686E60
+:103490002921EA5091ECA28F3664CC4E0A38138F62
+:1034A000BB978FFB931A2B96ED351E2C5FAEF16206
+:1034B000D951A390703E21AFD4146079B0C687CFA4
+:1034C000FFB5661C96AFD7F8B17CA3662A96E19A41
+:1034D000722C0FD7CCC1F2484D00DF7BBB66319612
+:1034E000476BAAF0F93B35D558FEB646C5E7BFABEA
+:1034F00069C0B2B32688E57B352D581EAB0961BF84
+:103500000F6BF66079A2A61D9FFF47CD412C3FAE01
+:1035100009637937494678DE79E725EB3CBADEFC6A
+:10352000671E7C6F5A1A215B468B3E0057FE339F05
+:103530007A0385D1756FF99B694E7B1CB8DC450415
+:103540001C678B8B60FB96431F11A58890E6D15DAD
+:103550005E95D6A7F1EF8CD875CC3AAF30DA2F76DE
+:103560009C3F12131BC74CDB69BFE1DB587FAD7D6D
+:103570001A7C6774B47D77CB7BD6F94E7D3B7BFF9D
+:10358000F9D6F7AC80BFCD11898411EF2A21B4B4EC
+:103590002B3D2D03289E6D272CC4924DF1AFB49383
+:1035A0002E3A4EF3F827C36229AC9B7653609DEF09
+:1035B0001381C2417511A40705C6181BFDCE582200
+:1035C000E23CF29F39C6BE73C7252CDFF8AB4C082E
+:1035D0007DAFF94E21E4A0E3374FBCE8F503BDA968
+:1035E0002F9880DE905C15F84F97B79C8EBD65E2F2
+:1035F000875E95C269F3DFDE9F331FE86F14F1C168
+:10360000F7361FFA3951A0BDA807E157CBD7BD79CE
+:10361000EEBC2C4F6162BAA49444C47174B94EE2FA
+:103620000FC581EF3F0210287C4C9E10AEC94EFBA7
+:10363000C5C3C33F1219FB6D76957F007051EF34FF
+:10364000FB76D179DFEC0B936E6774DE50FF84D686
+:103650009D5F8689C905F33EEB35D1F53BC6C9D7D9
+:10366000D9E86C9C3D3D27E07DE784457E587BF39F
+:10367000A82EEF22DADF5AD089EB253EE21B46C79F
+:10368000B517A8647E21C0C184788D9DCF7C80F75A
+:1036900000C0D3575EC08946871FDCF1BEB542D754
+:1036A000FF798D3E04465FA4296C9DE58AB63FA351
+:1036B000B5DB18FD10ABB17D5B0C1D938C04ED6682
+:1036C0000A68C49718DA2520DCADB38BFACEBB2983
+:1036D000FC6BDC074E5FD81A88B32EBA4FACC077AC
+:1036E000924A451FC0AB7922DD2F85D1755E69DF17
+:1036F0003570B86C2E9DED82F1AFC4B78ADA4512F1
+:103700002EE03C93FEFFDA83763AF3687D5438C5A9
+:1037100050BFEEE86043FFD19D3986F6B127461AC7
+:10372000DAC7779518EA377C76BDA1FFC49E498633
+:10373000FA4D91E986FE65E47643FD66EB0F0CFDDC
+:10374000A778E61BDABFE75D66689FA63C60A8DF46
+:103750005AF088A1FF6DBE5A43FB3F8CDB64689F23
+:10376000E5FFB1A17EFBD47F31F4BFB3FC3943FB4D
+:10377000DD735E32B4CF0DFCCC50AFB4074E027E89
+:103780007EB0F835C37BFF58F596A1FE012153E3C7
+:10379000E197088CCF500AF2745FC3FB5316E70120
+:1037A0009A033A1EC0E8B4A02D019FE4ED2FEC7CF3
+:1037B000CFBAD0C027CD8C8E07B1F63DA1F7E2BFBE
+:1037C0003F94EF13D2699DEDD2B7B3795DF357CA39
+:1037D0005FA15D52BF157F75797CD85FE3AB94BE66
+:1037E00009B99EC2571DA2AAF83D3A1EE59726B612
+:1037F00064524D189F22E4017CAEC97D9241C226DD
+:103800003A6EAD2BA3AD116042C796D2A05EB8034D
+:10381000EAA2E2275D71E06AF2C8063CC5C29738A9
+:10382000532831F7C76755849F3A851448F07DC106
+:10383000EE5B4BD72B91C060813EBF2C06BC30F9AC
+:10384000874DEAAF02D9D1FE6B27D27F42FF5342A8
+:10385000681DF657108EB545C40F72431D24877638
+:1038600065233C2DC04FB4F7E803A58BCD57FD264B
+:10387000D75067F3BD62FDEB7C635D1BF79F8CF057
+:10388000A47086FA7DBCD267DD3E394AB726E8C708
+:10389000EA8A28906F900F1ADBB5EF5CB6B98B49B6
+:1038A00012C5A395950FDBDD3BA0BC6CCB0C11378B
+:1038B00021C562609240E1A04E62F0514F3A42B59C
+:1038C000385ED5D8F222806F7C7D8190756C7F7CCC
+:1038D0003C4DD4AF2311DE3682DE961FADDB32289D
+:1038E0005DC5E1CB77094CFE511A95605C0B61B464
+:1038F000E53005EE8279CAA4DC2F225E7D04E677EE
+:1039000068D893732A28FE9A26C83EEC1BA40A277F
+:10391000D54FA55EB84EC5BA95D7E7090A8EBF3117
+:10392000F9B03587AE77B34FE47A4110C76BC8FE64
+:10393000CA0B7CDC26058907CABCF8727AA52072FE
+:103940003C3E4AAE461F8EC5CF48FA3AE32F04E10B
+:10395000A7CD6FCBD0B03507E8713CD3879BC7F5B7
+:103960002F57D673B8D6727D78B3323B8938A3EB24
+:103970009612CC6B03D7A309E99903786FC84E1749
+:1039800061DF6E1018DF3994FDB615F84793E7B084
+:1039900015C60B08D96CBD31F06D487E0FF5FA5A8B
+:1039A000977D4E280E3E03821BD7D900388375259C
+:1039B000132EB7552FE0CDAA784A1A95BE7434D984
+:1039C000F525CECB594A140BEDEF4C63EFDB3E16D9
+:1039D000420ABEEF770EA2F37070FAB02B46F9BA26
+:1039E00076E22D2AE8910FE71032109FDE6FC09328
+:1039F000A3343003E8DFF457138E4B06B17949A4A2
+:103A0000EA0FF361FC42C6A73CF47FDFD031AC790A
+:103A1000317CEBD834DCBFB2877D9F982674DE44BE
+:103A2000E72BE58B034D74AD2673A71FF4B18D5DB5
+:103A30006D3E55077F594F07C0873E9E769614C34B
+:103A40007775E3C3FBC3666FC9ED879E4C5D6E124D
+:103A5000BE0EBE7B4FBFF4E1FAB8ED9D233AB8BC71
+:103A600021B8D2BA016863C958E4135778FF724D80
+:103A7000E89D23C370BDE2D5D0797DCC3EDF90CDEB
+:103A8000F5398AEF593A3DEDB2C0F439A296211CBE
+:103A9000258EC70D13490FC895CDD9B2B20EF0517E
+:103AA0002A8781849052E9F7CDF00F809B52DFC9BD
+:103AB0009EFFD0C047D70F99E90B2B89E727A5C5F3
+:103AC000E0F10AEBAF06F8E9FA7703FCAE89C2CF62
+:103AD0004CCA93C240DBC1A948BF6E6D1E13EF52A2
+:103AE000F4F3E885E30D6C7F9AD354124F2FADE5C4
+:103AF000F0BB53F45F047E67927D2702409F39320A
+:103B0000DA27B1FD478A8C0F45E16C95004F76C2EC
+:103B1000FF668410EEF4AFDC9ACEE147FFCC196F5C
+:103B2000FF5500BAA366B3A3189FD74925747F79C0
+:103B300089EAA0F2C12E1109EA59C06C4763FB64FF
+:103B40003905F6F12D3ED477CDFC7B9E36AF5E4F26
+:103B5000CF12195EA3ED21EF9D8676338EB7C1C5D6
+:103B6000F51BCF7306BAE87D3F39BEDC192832FD5C
+:103B7000274BF470FA790EED39F3D0BB1A0E517859
+:103B8000D7E5FB7D15B0400F413868F243931754D9
+:103B90008E64890300FE010278973CE558C6CAE3AB
+:103BA000847C3C460E9B0B6403DF217AFD2607FED6
+:103BB0009BE1C1FD4662E53F2FCBA75FD5BEAA8D35
+:103BC000D95726125F2EDD2E32FD91A869B87E6D81
+:103BD0005F11AE5F68F8A7F2C140AF32CC87321CEC
+:103BE0001B09E1E00E6A6641DD45AAB07E695C49C9
+:103BF00058A0E358A4AE06E0CB96712251B3E3D8A7
+:103C0000555C0E255AC79689F1E5C4CDA29BD9C74C
+:103C1000CE2ADC1784DC837AA1A006C837A81F0649
+:103C2000B9BCF479018F1B6BAAC927743F590FCF18
+:103C3000457BDD9CA7FAC1DE075901FA23C9286537
+:103C4000A5E453F4F4D98B47B216C7333919FEE50E
+:103C500034AA17E7207D2C00FA205623FDF4D24920
+:103C6000461AC80A9887521E775C8E57DE2F211D90
+:103C7000F5D281B62E4586F162E9C35E4A2D0E115A
+:103C8000AB9D309F811C7B0303F5F78BC5809FE0C4
+:103C9000D4E1140F03BBE6A13C737179525F38FB8A
+:103CA00028A874493ECFAC5B14B0F3890070DD08DE
+:103CB000835D0FE3CD5D5B46EBEB61B0C1B4BA6EE3
+:103CC0006699EA646462D44B4545D2F430B15FBD75
+:103CD00046F8C6D2F7FD44EBB7C4C83B42565F9DD9
+:103CE0001E750FFB9E4AFF07FB2B39469E26F98D5A
+:103CF000FCDD15F39D17019608DFFBFF57BEE7219A
+:103D00008F5B154A0A963CD113A2B499443CC96012
+:103D100027D92753FB8DD63D193D2A4CE94A78A96E
+:103D2000E7762AA1FB534FCF6F727EE9ADA8CBAEE9
+:103D3000A7E35E2A75FA805E0752F6989AD2773D1D
+:103D40009BB8DED75B2FDC8174BD9ED211E8C36ABD
+:103D5000A188FEA68D792F7BF472F194C657FAD014
+:103D60000751244D2EE7C03E14FDB6E2EF4E1FE68C
+:103D700018385F2D7D38EE31E2E3DBE2EBC2B7A409
+:103D80008FEFFABDFA44FE07CE9F285E51FF6E50BA
+:103D9000FAB703FAE2F571C4AB9DDA2FF1F8ED172B
+:103DA000BDF8548DF288DBFF51B961B4FBA5AC5B63
+:103DB0004EB4F5030F29564FE6E3DAAA4DCAA7A978
+:103DC0003080C760EF6C541E5741FFBE047A34E860
+:103DD0007BC132F4FF923CE68F850144D0FB157F16
+:103DE00008FD0C209F74724DCE30EAFDA634BB5105
+:103DF0001ECF5105FDFC6DD532CEC30ADF4B437F8C
+:103E00006D08BE6BF290B0CD1DA557F814B3F71F27
+:103E1000B92A3A3069EF091ABD1ADFDB905142E244
+:103E2000E1AFCFF7EE30CE37215F8A7DCF2929DD94
+:103E30003ABD23F17B12E9D6E92F376A711D8EA7AF
+:103E40007A33392850FDAFD67B170928489F28C7F9
+:103E50001AA0A4F2B4DE5BE241F9BC4788B1CF15E9
+:103E6000464F4A0AF617AD4CBFD2EA89E7C3BE1BDC
+:103E70008D1329A81F27EA5F5B33EE0989321B7374
+:103E8000F55B5B256AFFD4ADF5CF29A7FD1B6B8ED3
+:103E90006E958645FB2D3169F639159F6340AFE17C
+:103EA000F44B683F849B48BE01FB8972684527E755
+:103EB0006DA473AB84769FC2F14884DEFD4087DC3D
+:103EC000CAD7692127B01F0C84761CE9C271E1456D
+:103ED000A8AF37FBFDE5144E8D52C8BA1AF8B98D5C
+:103EE000D7155E4FE6750FAF67F33AD98175B34CBE
+:103EF000EBB07FCD210FD6EDBC9ECDEB29BC9ECC87
+:103F0000EB39BC2EECC0FA7A998DB7496A67E3DBCE
+:103F1000795DE1F5145EF7F07A0EAF9397D9F72D3E
+:103F2000ACEE30B7B3F11DBC9ECDEBA9BC9ECCEB83
+:103F3000B9BC2EBC8CF584FCB280C13FCA1F18BC32
+:103F4000357A240057831FAB2BA69DD18B49205C6B
+:103F50000FAB42FDFFD0D0BBBCE06F5C7FAAD20BA1
+:103F6000F4537F9B464F01E49F24E356E463662DA0
+:103F7000EE98B67A0EECFFFA0C19ED49C2FD305AF4
+:103F8000FB86E4C0D46CF0577C6022F1EC2EAD6C63
+:103F9000E57CF769D07BA97EDEC2E3914FF278E43D
+:103FA000568847D23208F1485A36F37864138F475F
+:103FB00036F27864038F47FE04E291F910E79C83A0
+:103FC000E58B108FA4CFF7403C9296BB211E499FF2
+:103FD000EF8478242D77403C923E0F413C9296DB53
+:103FE000793CB23EADE428E81D97AA45D40712CD2E
+:103FF0007F6895917F0E596C8C4B0C0A18E3120365
+:10400000E718E31203CA8D718964BF312E9134CE53
+:10401000189770F98C71094781312E61538C718921
+:104020006B0FCE36D48BDABF6FE87FCD9E0A43FB91
+:1040300088D052437B7ECB6A437D58F09F0CFD7342
+:104040001BD619DA9F32E5207D65AB8D867E59D56A
+:104050008F1BEA95767FB709FD946957E5AF265F18
+:10406000AAE97A7E192B1F4C99C4EF4739C7E4118E
+:10407000FA6081FE8632BF94F5E3EF1D057BDD9289
+:10408000C7E4944589B13B63C6939DBB4FA8F43BFD
+:1040900065EEA3DE2EDD7E245EDD7B60EF488C4F77
+:1040A000363ECAECF1265EF65D473DF66BFA5B7C68
+:1040B000BBDC269962F40866D7343D2A60FFEF3AEC
+:1040C000BED61E3B6EF47B141563F4F66D48F3AF59
+:1040D000923A9DBE60EE4A9E4F50CE33FBD7C4F756
+:1040E0007B5981EF541D85F77A0FF159687DBD73B7
+:1040F000929FE925A2824276CD6D68A76BFDB579C6
+:10410000D5396733FE42D947D8C0A7EC063FC1FA7C
+:10411000B4FEF53739622261AA97982202FAF56453
+:10412000A97C6A36D5C7E56326DF5AC067027B9F44
+:1041300090C7193FF48A063AAE5BA0F13F1F9B1F60
+:10414000CFBBD0F85B6DDA247C5EE7E97F5E169822
+:1041500017CC87CFCB1C7160698AD870BEE323A9C6
+:10416000581F1749C6726C640896632283B01C1DE1
+:10417000C9C5B234928DE575916BF0BD92C8082C1B
+:104180004745AEC3E7BEC8282CAF8DDC80CF8B235C
+:10419000E3B12C8ADC8CCF0B2365585E13B9159FD5
+:1041A0008F8C4CC37244E4767C5E109985657EE406
+:1041B00007580E8FCCC57258643E9679917958E6AF
+:1041C0004696E17B3991255866471EC0E74AE47E52
+:1041D0002CB3228F609919F911964323B558664480
+:1041E000D6623924B209DF1B1CD988E5A0C88FF13B
+:1041F000B937F21896E9916D5826479EC3764FA4B9
+:104200000DCBA4C84BF8DC1D79014B57E467F8DCF3
+:1042100019D98FA523F21A3EB7477E8EA52DF21627
+:104220003EB7460E6179253C5D490F1EF7A9918F77
+:104230008FF9D8C8C74B8F19F978C96F8D7CDC7797
+:10424000C4C8C78B5F37F2F1C20E231F1FB9D7C88E
+:10425000C70B761AF9F8F056231FCFDB6AE4E3396F
+:104260004D463EAED419F978E61A231FCF78D0C850
+:10427000C7072F37F26FEF0223FF4E274F1BEDF4D6
+:10428000C93B0CEDEE092F1AC67396BE1C63D7848A
+:1042900090BFD80BFFD5F09E35EF700C5F56197F9D
+:1042A0008AF19F0348207EF930B1FBC0AE89C56713
+:1042B0000AE707A9B0EF6899C6F7DD00D877B44CD4
+:1042C000B97502C6A952678E9B07FEB8CBA7040535
+:1042D00074226166753EE841294308F32790FC9BF0
+:1042E000FDB45E3B48AB135580FA5082FE0588FC56
+:1042F000617B36ABFFB2EE91491007AE35F376B570
+:104300007612F8D56A6DAC7EACAE621DF82352927F
+:10431000FC83215169A7393E3FFF5892113E032586
+:10432000FF6F245AFEB9ACEB21F027FECA1AF877CA
+:1043300089C263B935900521B4F3E6C0F3203A721F
+:10434000047F27F42B12FCEF4AC8CF8D7ED35B404D
+:1043500070D2F6A152F987D09E3A730FDA171A1C61
+:104360006A5DFDCFE79D5EF944504E6AFE8AA71C48
+:104370006EB43F1B9F904310373717A4A37CA84D02
+:10438000262C1E0A71218C0BB3FAAEA14AA891E922
+:104390008B46B9B2B5FE7E884758413EE5EAFDA797
+:1043A0005DE83F4D024B2117FC033D99122D575AF2
+:1043B000C2F52057BE4AEE3C2998102E1761FD0F1A
+:1043C0004D0F61FF758E99E3605D142E5FC07A29F1
+:1043D0005CBE944627860BFD2BF78EE1AA05FC6791
+:1043E000AF60F05F3A4C81BFC3383229C7F115D5B1
+:1043F00087F03B2E79F07D0D8EF4EFC19431D1F82A
+:104400003F7D4F360FE83B9E36CEDF25FE7D2E1FCB
+:1044100035FAAE4E20AFB47825516FFB567EEFC310
+:10442000B218F73B66A91CE3B47DF8619A511E9A55
+:10443000D258DE83498A1F7746C7318CDF3AF3AA08
+:10444000E2D99ABF85D4DD7655FD1BB4FED44084F5
+:10445000FEB91A9E5A6F437A1CC6DFCFE57ADE5B3F
+:10446000BF7F556D02BACC2398CF11ABDF356E15E7
+:10447000911E739399BEA8C15BE2FAA1F65DA9C92A
+:10448000A827BE2673BB78EBD5C17F0F877F2EC5CB
+:10449000F3BF96F49D07D93993ADC7C3AA0545C1AB
+:1044A0007720DF64580BAB4B5BE97C8A13CF87F036
+:1044B000B884B68FA416D69FEC318EDBE7BBA61965
+:1044C000BE78F1B384DFF99671BEF966639C4F7BC9
+:1044D0009FE20BF19DC7F528524DFFE8BCF2891110
+:1044E0008E5ABC4FABBFF5FBB1184FAF0D96B078ED
+:1044F000B993C973F2351D7D0CB8BBE2E3418BA7BC
+:10450000D671FBB2DEBB03F3D9C85E239DCA831606
+:10451000E0F3C6820A0FCB4763FD2C431FC4FCC8DF
+:10452000C682D5E8CF955BFD56B06BE502D107306A
+:10453000979227F3F649D86E69657AA705DA15D000
+:104540005B77AE45D1100C35807F98A4493E086357
+:104550004AAD8106E82735101C8700EBA3F3D9C1CB
+:10456000F198E195D695D17F6604CBC3367C8FF860
+:1045700087E9FA85F87A33331E0F43BFCC6055675D
+:1045800019F8FDAA088E9F99B103CDF2C19ED96298
+:1045900099EEBDED7CFCCD7C3FD9827E0FBE1760CD
+:1045A000F98CB1FB577BAF955786A75594C1B8F6E8
+:1045B000607939BED7CADFE3FD9EE6FD86417B29DF
+:1045C0005227CEA777BFF37E2D7C1EF5DCDE1F1EA3
+:1045D00064799F75DCEED7FA3DC9C7B3589F7B0657
+:1045E000FC8EF941E68FD5DA83BC5DCBBB904B8D59
+:1045F000F9A31D66B65F3F97197FD2E826111D9378
+:10460000061DDF83F8A36A37D6AB530CF61FA91A31
+:104610006CAC2FCE31F60F8C34D6E79418FBFBAF81
+:1046200037B45FEEF5BB846C98EFCDFD2EF97CBFFF
+:104630003CDD5A827647D4DFD765D3DB27197CACC3
+:10464000ED551576787F770BDF27DC3F63D3EC974A
+:10465000BCD5D8AEAD7B3BDF271BC0FF6101BCB42E
+:1046600030BFCAA8AA7746503CEEF9C0E4DBA124CB
+:10467000865B223FCE46C027EE3F9657FE24F7E3E7
+:1046800004B91FA719FC38F9E0CFF1737FCE54AC01
+:104690001FE07E9C9FF1BCF2FDDC8FF3539E57BE62
+:1046A0008FE795BFC4FD382FF0BCF21D3CAFFC2650
+:1046B000CEA71BA6F807835F6DE794F876F14D321D
+:1046C0008BFF4CA7EA1641F9DE23A0FF7C1CD555D1
+:1046D000E87AB3AA7AD6CAB49E7E0F835B56A0A7A7
+:1046E0000CFCE99EC9AC3E83CB55901F204F8897A8
+:1046F000EB3B1974C752786FE1749E59DD13867CC9
+:10470000165B866714B8406DFCBBB4CD8BF9FC9C7E
+:104710008E6DD55561682726BF5D1E00E3B379E530
+:104720001CE99904E14DDF89CEC380CEE2CE76113B
+:10473000FA159606D7510B9B380A4322F0AB86B286
+:1047400040E388B428BEE82C0C7441E788722B53F0
+:10475000E3BF138C742147B6A37E5C5B353B09E94C
+:104760004F61FD8727907303E718EDA664BFD1FF63
+:10477000555B3DBB5F7FB4EF75E3FBC51D46BBAB2F
+:1047800036AFFFF70BF71ADF1FB933E6FD16B68E0B
+:1047900044EFE74466A27DF07C6B7CBEF00FA68AF6
+:1047A000898007ADEE8EDC88FD63F53E09F4B95CC7
+:1047B00070BFCB7ED07F25C5E3C7BC2445E1A58F64
+:1047C0003FF7F37A39D6A97E385D1E8D7831E887B8
+:1047D00026CA902116D23082703BE3EB75FE0C5A4C
+:1047E000BF93A01DE290AD37AB13807F2C34F855FA
+:1047F00052E5AA330AECD7C74494253B83FDF3BBAB
+:104800003E79114E3FC68F729B3C25A638F8D6CA1A
+:10481000AD4DE2D47871B1259CAED737CDF6A05C12
+:1048200038123F8F44EB4FD7BF44D6E5930CB88383
+:10483000E7099C63F96C83392DA52EED9F0EAE36EA
+:10484000BF63AFB6EF9C2C6F44A3FBD4E1FDD389CB
+:10485000A67F464222E9847D2155D9F148C21D3EFA
+:10486000CC770701AADF27B57F7BA011F8A6FA2332
+:1048700011F9C8803BAA443D1EB4790C56C265B0FC
+:104880007F6B0F2D1121DF3EBFA54AC4731387082C
+:10489000FF0E9570B4B42D0EF9999F8CE559DAAAE4
+:1048A00002EBE0F9F016062FB04F797F940F1BABA7
+:1048B00067FB018FBB33888FE7AF18FC75BB9DA2E8
+:1048C0000A7AE625CAAF5051F89ACE4BB3EB28F0DE
+:1048D000F25B996BB676180939A1DD3F15E1A5E5C4
+:1048E000EBD9B65D5471DE031E0AE37993514C0F88
+:1048F0003093CE30C616A4802AD0F1D7073C3EC8EC
+:104900004FCC6D29667E99BC20E651AC16037B80A6
+:10491000EE357898D3DA316FA536C179810D9C9F39
+:104920004B24BEFDD1C9F970AAEC9B0EF6E89E2778
+:1049300028FDC7F10BBCC3C7796EEBECA4114A7418
+:10494000FF6AEDC74169D3CD2B3722B33CC1966FC7
+:10495000A7EFDF6C263CBFCAF89E49F219ECAD21E7
+:104960006605FB6975C969E467573F4F09F9122964
+:104970009C6EC073AABB7FBAD6F6CDE5A1317A474B
+:104980005E01D27354EF10899BC2B5358FD30BA74C
+:10499000274D8EC805414FBED0974E5AAB4BF0BC49
+:1049A000C9A509940EE99FC5D3EE07BF816B4218D4
+:1049B000D237800ECE021D0CCA53D70A4827631087
+:1049C000DEED5CEE593DCCBF123B6F4DAF03BBCA71
+:1049D0009B0223C7D83724F81ED077EE0888190227
+:1049E000DDD0CF51BA960AFAB7EFAE365EADC58FBD
+:1049F00033E91FD8371D806FE0E39FC5F8A93C5409
+:104A00004F1DA393EF9F3D80FB2316FEB1EFD57999
+:104A10002679E2F16D620A782CA313D34BAC3D4D9D
+:104A2000FAE4AD3D88FCC332632ADAC9BD7675EB82
+:104A30004C5CB785DB8BE63C6E47F6B11BEFF1F5BE
+:104A4000274FCC19DF2D3F74A425BEDD98E8FDDE8D
+:104A5000BCD06FE977D8C8F3EC34FBA3D7EE881944
+:104A6000472C6C8F7B0EC3596884BB3DCFA877144D
+:104A70009AD9FEB4788D7E63B367707CFF26CF4FE2
+:104A8000AB18A7E149B9FB3FE97E5B72D44C1AA190
+:104A9000CAED5CCDAFB404F2D4281D5740DE1AC570
+:104AA000D30252EE86C6F344C47C98F3E43DF77516
+:104AB000BA7D1FB0F073010DE6D3709E42CBC75A8A
+:104AC0001864756D3E952DC6FA22323B1DFCAC8BE9
+:104AD000B69A09E45F2D21D2E92E6DFE940F945B06
+:104AE000981E5449AAEA81AFADE7FEC30A0F912090
+:104AF0007F6AC5ABCF8C81F33995166E8751F82B41
+:104B0000BA3C9BA5CE900CFED14F3AAEBBEB060251
+:104B1000EF87EA0797629E3BE651C5C27D7E8371AF
+:104B20007E579A7FEC7CB5731789E621ED11E29EE2
+:104B30003FFCA14530C4E7AE742EE41908820D484D
+:104B40007C2EE44AEFEFF88EEF3FFF1DDFDF6B6155
+:104B5000F49BE8FD15D69E5B30CE9F56558EFE5ACF
+:104B60009ED7B19204FCE03A37BD3E4B1DA2E8FA55
+:104B700079AFB25F06ED67BA8A7E79FD8F7781EFF4
+:104B8000F35FED7D4E86FD7BFEC55333412F58F616
+:104B90009A8958214F6DAF8B9FFF0AC920EF9676F7
+:104BA00098985F410A8FB95D971F082758018ECBEF
+:104BB0007EEAC278F2D2972DA119F4FDA5AF7C52FE
+:104BC0004C281C2EACEB797B08E83F2F0A2CDF4ADF
+:104BD000ED2ABE9D3E5F2A91FBCAE3F9D12D4C4FD1
+:104BE00039F773C71CA03361CFA17B71DCF6BBCD55
+:104BF000169D5C3864316BFDD8F9AA1784D03081DA
+:104C0000CD4F9FEFADE5B99D7B4160F33B680ED979
+:104C1000607E7BDAE400EDB76ACF5F90AE6FFEE9AD
+:104C20003E37C061D5419381FFACDA630A5B8AB13C
+:104C30003C65417EEF770A63009E04E5F7CA8E1556
+:104C40009817BBB27DD35F4C6E78DFB8BF285C7C11
+:104C50006180EB71936F06D47FF6BC1BF2893FEF46
+:104C6000DCE506B8D271E7C994AE6EFC52B70F0905
+:104C70001B3F92D2773C427A64A0AF55ED1BD9F727
+:104C80003A6E3B03FC6D55CC3EFE1CFE31A8AFFCDA
+:104C9000B818233F2E91DF8E017D83EC498D9B67F1
+:104CA000D02B3FF8BE5EB6EFD276381F7CEEE53FE4
+:104CB0006D07BD7EF9DFBFD8FE08F803DEB079804E
+:104CC0001FAD7AF10337D1C1DF65657CE1C20BCF3F
+:104CD000EF7E9AEE930B1F5950CFB9F08B33990AA0
+:104CE0005DFF85FD7F4D07BDFEC15F4C1908F07863
+:104CF000F0C0CD03FBB363806E43163D7E43885FF7
+:104D0000E5A0C092975FE7650C9EDEEA782B13E67C
+:104D100079FE8405CF71ADA2CFAA4B006F2B503E18
+:104D2000407D0D85F7CABD1BFE622A8E0777758808
+:104D3000E885323C847801EFB7FFC3C45228CD3EEA
+:104D400005C6233DC8DF63DF5B758CE2F7DAC4F884
+:104D5000BC44BE9601FEABF66E64DF6DA7F874F737
+:104D6000C5E779F8C7F8BEF82CB4C6E273F9B3E822
+:104D700063EC488D9B17A7E173C5813BFBD51B34C2
+:104D8000FE7025382F16D8BC2216FF042BECB397E3
+:104D90001DAA97E1393483B65DD8772993503AF943
+:104DA000CCDC732FF0C99E5F583C60772CFDC57139
+:104DB000DC77170EBC2B2BECFC8853A07AC505D2F0
+:104DC000FBD7097AC64A815556ED74852DEE28BE6B
+:104DD0005686664D55DCF8FC143E0FB1FDB03274BA
+:104DE000E80E210EFE1EB2E630FD333400E1B28241
+:104DF0005A449E42235E857180CF53B700FD25C281
+:104E0000A7B67E0FAC7FAC0EAF3BD93E8EEDBF9206
+:104E1000EE57E0C37DF01B128E4379A1CD22413EB7
+:104E2000E4057E9E2516EF51F8F3F390DF525FAC58
+:104E3000B226883370385C69BF5F697DDF167EF704
+:104E40005A151C37168EE7BE8E2F0F9A38FF584919
+:104E5000AAA60ED6C9338B99CAB36CD0F7CAD5218E
+:104E60004274BEF5EDECBCDDB93DA610C88B587E92
+:104E7000B132817DFCB495F9BF571E3C540C7CEDDA
+:104E8000DCE19F73BA6474BF72EF2959E5F221A483
+:104E9000970F09FC283BF9BC57BD1E7FBC557BFF13
+:104EA0001277BCCF25FFDD30FFCF3BCD44A5437C3F
+:104EB000DE6E9A1A4FDF6AB69A8D79B5AE312792B7
+:104EC000E87B26B71DCF33D6AEF31F57412F79CFDE
+:104ED0008CFE1522F93EB3E0F969BB02F1E55AF701
+:104EE000223CD7A28D57170327C95B8EFE0929AD37
+:104EF000BC94E9D421833D6DF688867953B99B0132
+:104F000072E9E4A8336658E71F62F4C73F48A47EFD
+:104F1000201DEF0FAAE05BABC4B3178DE307D69853
+:104F200088A29787969E93301FF2A68D40BE9AE97D
+:104F30000D9B0AFC64D5761BC6D5DF3A707937C065
+:104F4000EDC2B3161ECF6479B595DC5E3B73E0F21B
+:104F5000F6FFA2ED67E065FAFDCAEDB43FE8ED7B30
+:104F60001D98E4FCE797938A09E5D3956F3E3213C9
+:104F7000F84B25C4C069FFCA9F0E0C41EE42F700F2
+:104F800056EFDE3734047859FEB35FAC0479B2ECE7
+:104F9000270E0224F9D681E3F742FDC29B2ECCEF07
+:104FA000BAF0E6991B611F507D5BD1CBF525FAF372
+:104FB000DB74DC655067EDC2379CD7811DB30C4AAA
+:104FC0004AEFCB0E26E179075D3F7C6F95A5E7217F
+:104FD000BCC885A88345B489C283611F2EDB63FCEE
+:104FE000DE592BB32B56C93D8B58FFE060B65F3BB3
+:104FF000F1BDAF38DD6BEDB1EF6BFDBFE4FC333AD3
+:105000000E7B7FA58554C5A37FC1C6C65DB6E76F7D
+:10501000F9C6F118BDF6FD0E7BFE4381E5E393FD75
+:10502000368C132C97C3C353E87E7D45268B61DFF6
+:105030002E77878727D3EFBDC6F9E5723BADD3E75F
+:1050400083F93CA03FD489B5EB2780DF15AFDA08A0
+:10505000D0FB8A375DE8575EF1CAE5EE7FA1CFCF7E
+:105060001D70A0DF6FC59B0F23BE5758C2F7829FEC
+:10507000AE67BF85ECA0FDCFEDFF7526E823E7CC3A
+:10508000E1CC947EFC432BDA2DFCF217E33AA85DC9
+:10509000505045E7A33EC6F270AA09BB47A09AE765
+:1050A00079908F6DEC9C328F4BADE67EA28B0B948A
+:1050B000249CFF845BD973EE275A7D9B323059378D
+:1050C0000FC89323D751BB44AECA073E6B8ADC4A54
+:1050D000145A9722B9586AFD4C701F4321E427B037
+:1050E000B8A039CD472A69F9700A09E0F948E7F410
+:1050F000DE7DF6EF14C5ABB7290361BC9136C65F00
+:105100002AEDFEB136E433C67B14D4036C5D97F907
+:10511000FD08B1F3BD6C562DC0CFA3F13A962758C8
+:105120002D29C7C1FF4E8E72BED467FD6C9F5DF402
+:10513000A4E03ED3D6B1A9C683FC04E265506EA8B4
+:1051400029204A3EE47BF8B06EE2F0B014AA04CE07
+:10515000F7C21E843F8BB3DC2FB2F83001FFABC91E
+:105160001940FAB278ABD05760E5F7E9989C2AA9C4
+:10517000A4A5D9C9E004E7F6004E32AF4B2D331099
+:10518000AEF47D7C7E933D702FC0C59A31D2C0A70E
+:10519000E4B41243BD0FDC34BAD8F7BF0D3F82F040
+:1051A00002BF8E8271CC7108B7F5357EACFF7F806F
+:1051B0005F3D83DFF544D1ED1F396D92A19E107ED6
+:1051C000DB28FCD2A2FB2A160ED53C0F47DB4F8909
+:1051D000F6EF933504832F8FD7B460A93D4F492054
+:1051E000D7CFD8985CAF2681B566E0531EE68721FD
+:1051F000692AC9D0F99F8857C5731FE8EB87F68CD9
+:105200005BD17FA9E1D7E491BA8DFC4F390EEB79E0
+:10521000F81DB308FCCA54FD1CF92455B78F6794D8
+:10522000DB1484B30FE303B55CBEAEEFC5A7717F9B
+:105230006CAA51B0DCCCF7C916BE4F1E03BCC37DAF
+:105240000E702F05FD5ED35482F2F3095A67F67E85
+:1052500098E8FDE1C9BEF6B099E21F79928225FA7D
+:10526000ABC9094B685836C455891FE825F9C48F66
+:1052700042B856D28EE72592B57B5D5ECF499E8BB4
+:10528000F11F6266728A98581934831D150BDF5A14
+:10529000DF612BD8E189E65376728900DFBB3C974A
+:1052A000C5CCD2EE693F01F73C389B1C6857A6FB82
+:1052B000AAB23291BF5A905E9DBE8050A9C3637A54
+:1052C00002FDEF21FBB40F801E3F843C445A3EDEBA
+:1052D000926B03386F32B77B811F6EE2E7C5953959
+:1052E000140ABAFBC2DEE47CD25D6AE4031A5FF6FC
+:1052F0004C2831D0B3C67753261BE95EE3BB2FD8C9
+:10530000985FA3D25E7E06E6931A69C57D19BB0F2E
+:105310006ACDB22A5C8BF7CB30FFD32981C5D5FB90
+:10532000F2038CBB5FECCADE01E7A9B5FD13BB7EBF
+:10533000A9611A7EA7571F34C7CF07182230B9DEDC
+:1053400040E98D605E82828868A6744678DE02DB62
+:105350004FE3B0D4E8781D613C44ED10D93CB9BFAF
+:10536000563B7BB3CE5AE2073CAE6F677B68A09D8D
+:10537000C749D344905D44A2F6A4933E920E8DB7E4
+:10538000827E29997D47810FF6B8C47688E3AE778F
+:10539000CEB6421C44482E45FAF9CA5591D55F5CF9
+:1053A00007EE5303FAF3387DE474219E8745BFB0BE
+:1053B000C95342C02EDDE7ECB4633E935D34C49F15
+:1053C0002AED810CBB4E4F2D82AF73BCC3B0FB12D4
+:1053D0009CB72CE0EB21192AC9D3F189DEFB8F148D
+:1053E0009514E8F8C5BA61B7E0FD4A7DF944027E3C
+:1053F000B8EB7F861FD6668510AFE658FE93E6C7EA
+:105400003B9D68A9C2D508263274FD0F92914E27A4
+:10541000023C887347AF1E74534EDF79C6F2BFA8B3
+:105420005C53D00F46E5DA53E3809F26946B55F723
+:10543000211D370D51808E0F353FF22CD43F69B6B8
+:1054400028C0BF1645361285CEB732321ECBC52DC9
+:105450003FC6B2A2A58D6E2242D66EAE6C9E0BFDEB
+:10546000B799D0FFD31DBAEE4235AD773759507F8B
+:10547000EF6E7D200BF4BFEE268702F7AB74B78E7C
+:1054800036B63798709F75B79843261E0F36413C45
+:105490008270FE0E5E20DD7C49A9827AFCC5987878
+:1054A0004BC5168B5F7027867F454B7C7DB216FE01
+:1054B000C9CEA3E5037F2D3BF9A32CA00F8DCF3CD4
+:1054C0009C42F91EC0EFA485C48B0BDC649FB2C460
+:1054D0003E004AFFFD768CEF5FDD3D589F8854EF1C
+:1054E000463C05DCB30C7E5FE657FD84EBE5C49AD1
+:1054F000A0DDCDDFF7C46F5FD1F4A7B71FA5B50D51
+:105500008546BFB609FCD502D8E3B3F8FD196C3E59
+:1055100071E89AE9D34D16E42B0BB83F4AA3F32860
+:105520009D05DCFC9C9E810E97441E43BE276C2A81
+:105530007A6A3C85DF1794FE803E844D1307027C17
+:10554000D736DEB0E51E3AFE97BF35E1F3C5111B35
+:10555000F63FFBA8EFA97BC05EF83733E6917C7974
+:10556000740AC691CF9A8D7E8C1B1C6CDF1FE4FBE6
+:105570007F516493413F5FD4305F063FE8A24833D8
+:105580003E5F044124CC8BBFFB976579105F229866
+:10559000CF72D07EC79475284F4BD08F56B9D91291
+:1055A00037AFFFA05D31F2ABAE261C9750FD2C2D1E
+:1055B0009D8FA7E33B959154DC1FC4A312C8EF5EF7
+:1055C000C4F94FEFFC5ACD06FE73D616DF4F73D4E5
+:1055D000CEE4C2A2C80DB8EFFAAEEF467CBE48FBDF
+:1055E0006E17DBA7D1F53C353EDE7AA2EB9880FD45
+:1055F000CF26C7FFFE9FF9F7BB6B16133FE55F157C
+:1056000016DACF09DF7FA07E1CD8F9ADC929826EDA
+:105610005D952DCB885FB7AECAD679B2FEBEC928DC
+:105620001EEEFF659914C5C39F1B974F595708FA83
+:1056300042F97FC23EAAD834B1388076FE4684F360
+:1056400027665F26F0E3332D0FB8E3E50FFFD9AEF1
+:1056500018FC1C952D1C3F54EF2ED5E147C34BEC95
+:10566000FBDDBFAFFCEA51E053DB5C06BE125BF62C
+:10567000C15B767CB8D91C1ADC0A4800E1A6BC7272
+:1056800002E87AB3C307749D187ED790407FF04B31
+:10569000A03F533D4B748C86EF12665FB6303AB82C
+:1056A00012DCA2DFE57450167F3D63F97EEBAEA9F4
+:1056B000262ADDB0A7E52BD1C12344B5F6B38E5E13
+:1056C0003A78C24007631D9B910E3E03FD27BF2F12
+:1056D000FE4FCBAAFB7AD0771A4D18F73A6D57D305
+:1056E000BFCFEAA3803F9F7607675E5F1AAD2FD9D1
+:1056F00035CCADBFA7F14C0385431CF88D75C4ECC8
+:105700006F8D7EF2545238E6FF1DFD7C92E0DCCBBB
+:105710004DF6B21B009F2418DF9FAC95BDE7AA93FE
+:105720009CBD762FC8D1D3CE9CAF42B4B5C11EF874
+:105730009E83B6D7253F8472FEF46901E5F0DADF77
+:105740003F9C0F7CB88FFE5B1379FAD361E8B7FCFE
+:10575000974FCDA84FE1B884EA3F200730671CED92
+:105760008021E8674914CF5D0197F98E8EC675B523
+:10577000F8EDFA9ACE1FC3F8C4AA128FFEFC00619E
+:10578000FAD8FF8179E8FCF3B239E0F181BD2B90C2
+:1057900072A07BB3C4F2D7CDDEB451AA0ECECB1C1F
+:1057A0004C9FB41D39D2904DDFB72DFC770FF8F91F
+:1057B0002CF43B505A33A48B7A7FB996F745F27498
+:1057C000CF7320BF82D60D7E073ADF7EECE6D7048A
+:1057D000EDBE4F15EF2B9EAB5D5800A0A374F39167
+:1057E00096BF22D5B1F664ADB98EB5733FEAAA0A69
+:1057F000E6277D6B5E12C24F5BD7DCD737E07D6951
+:10580000735F1F341FFC69739DF97F0478BE06899E
+:105810003540F7C94C3EC7D2C566CE7F7ED026AA9A
+:10582000663ADE1173CF6107EC8B1F0A68577FFF62
+:1058300083236620F9FF3876DA0CF723DC078945E5
+:10584000743DF3882233253A84EFCF27ED2E566F2F
+:105850001F00F79946C7A326338C773F8B3F7FFF06
+:10586000836353408CD2F1D64379DF6F890CE3CF49
+:10587000EB50EAD9B1273EDEEB743C313A5E2FFCA7
+:10588000242BC2230A1F2BC2EBA3DE73242AEA17A0
+:105890003AF8A2BEA2C1B716E046E1373769CE7426
+:1058A000529C78BFCC750EFF23298ECE2716BE5F83
+:1058B00042D320385FE67F09F6CD3F3BFC7BA15CFD
+:1058C0006EEDC99472F0BC573BECCB95A640563AAE
+:1058D000A5ABF34303F903E0505067FC386FEC3E8F
+:1058E0003D09FBE55A28E9BE8079F07329F7F27586
+:1058F000BEF5A3332ED897F5078E6742B9C2D4B54B
+:10590000F96ED86FBF31A1FE79B123BFDFBCBA9366
+:10591000DCEF72D4A1DDA3C1D6791FD7E7EEEB701F
+:1059200084D652D2B8AFDAD46B5F015DDF57CDF2C7
+:105930004F88D4597C87419FACE3E7D4FA8E03F6B5
+:1059400042EC38DA3A0F670EBE06ECCB6747CB68FD
+:10595000471CFAEDC58F2A69DD3ED48A76C2E6641B
+:105960004EBF65CC6E7D36D9EF2802FF57638A4F54
+:10597000A5EB6CFC256917299C0E8F782834A91497
+:10598000EE7916D177B625F25C7012BC57C8EE9945
+:10599000F170BD744BE7E916A0C733272C1877F8D0
+:1059A000C465C2F9369ACB33418FFF639B1CF7FE67
+:1059B000B28F5C12CEB74DE8C23CBDF92468057EBB
+:1059C000D1D1397B20CCC7ED231E20FF33AD2691EA
+:1059D000DD6FA6F95BC212F3F7AB12ABFB79E9B14D
+:1059E000E9EF17DB387532E6792C687A17CFB1B951
+:1059F0004BE3DFEB6373B2F9BA3A53A6017C5D93D4
+:105A000045CCC376F97A04782FAB73928CEF078577
+:105A10007EDFCF5AE399067085F781CF675DE5FB9E
+:105A20008293E5693DC6EDEC36B3AF7E321DA76DBE
+:105A300073B200F8D0FA0D7632BE7266B2E64762F3
+:105A400079C299791E5B1E9D77A61F37377195061F
+:105A5000F11CD30EE8C7FCAC0887B611AF84218EC9
+:105A6000DD08FE15C0B399D153E36601FDAA147E8B
+:105A700083414EFCF109CBADB08EAC06C103B63B01
+:105A80002DE3CE7BB6CBCAE8BCE929B40BC14D0BE4
+:105A9000E366B6BE8FF3722558EF1A4E1F7FBC0225
+:105AA0007D9C77303F54667527BFDF2E8CF7D80575
+:105AB000014E50F797F2FBEAFC8A3E3F26BA7FD6AA
+:105AC000723A247E88B3558C9343E047101BDAF07A
+:105AD0009ED4F9410BF91E5D5F93C0EE1D55478BB7
+:105AE000FCFE24FF498053F36303310F6F83E8CF3B
+:105AF0000439ACFEB38C71BAC3FE8BDBE03EF8ED2B
+:105B0000E364DC1787FDEC5CE1B36B72DA204EE9ED
+:105B1000AA9ED4329F8E17F260462CA92D25EFE461
+:105B2000439C728DE81168FF60B996B7EDC17CF2B5
+:105B300051A62FA615401C6F90883EA53302BBA727
+:105B400061FD9A491EC0EB7A4F9AA0B75F66713A21
+:105B50003891523ECB49E1E37DF4710F9C85DB1215
+:105B600049BD06FC886A83ACEC62F142BCDF21953A
+:105B7000E325B5530C2F7263DDB9989ACA5B2630C2
+:105B80007FE98FA707989F1362A363D0CFC9FFBC9B
+:105B900088D7345E6B1C69C7CAD6758BB03F8C93AF
+:105BA0004EC7492D15C363207F2DD9BF1DFD7653E8
+:105BB000AC08272275B5009C425306633EF8E3E328
+:105BC00087BF0BF9E3A9477B66831C0D0DB5FF4723
+:105BD0001BF0A9F5B202FB3C754DF73DF03CD9F73F
+:105BE000E40350A6D67DF808F0E9E4AEBFD4E0F3B4
+:105BF000A9B2C1BF98FAF1D9BF417B6AB96CF05321
+:105C00007E9552FEA093C2677B613058A1B0E7FE3B
+:105C1000F4E83AF6ADED9C0AF7D89F9925B2F33235
+:105C200084F1C3AD5B3DDA39E552900B1ADC36885E
+:105C30004A7B18D635D38AF491473A915F0D826832
+:105C4000766E142FA91F6FBC1FF23562E7D3E014E4
+:105C50007ACF51C3BD80786E3107CE1F4EB6035D3B
+:105C6000EF2FE9F4823EBF39C1FD9D475DEC7D8B8E
+:105C7000C8FCACB1ED47783BB0C496122CFD455042
+:105C80003A899A046586D50FF9CFFB45E53F91CE59
+:105C90001F3729801FE86FA6F83BF4CEE7E85F3C8A
+:105CA000147C1FCBE75C05DA78E174FA7E73E9694E
+:105CB0008CD3347B188D5436307E51E9EDB242DC02
+:105CC000A4B2907876707A53353883BF8CCBAB8A88
+:105CD0003B185CD30A09C67DC11704F74BA5433FA7
+:105CE0000ABFB486B5F7231E49A79A4BFB35C3B844
+:105CF000809F3A91B071BBACB87F83268C7BD2FD7C
+:105D0000FE3BF06B55340DC4B83F1C0F86F152F8C2
+:105D10007753F8786D741CF01F9E6930E1B9004824
+:105D2000BF81BAB286D232D2674F59011D5729F5C9
+:105D3000781A353AD0F818DD1A0BA8BC00B82D50E7
+:105D4000D5FB81FE4E5B3DEFC03C1C5B2D0AAC7F5A
+:105D5000C1D6571F06FDC5E1ED6A00FE50398ECD54
+:105D600037A5893E473D47F91DF4AF6CB228EC7B5F
+:105D70001C7EA59CCE381C16F2792F6C65F3B60FED
+:105D80000D05813E2BD750B8425B80D13DB844BF52
+:105D900011715F1D85F5BBD4741C77C09C987D1173
+:105DA000437FDABA2AF8BA2AD6B07511BE9FE8B492
+:105DB000C2306E45295BE702C2DE17E1391D7F2143
+:105DC0005F4F85FA0A960B1B2C86F1B717ECEC8413
+:105DD000F96417CA8A807066F71B66F27565D6B1DA
+:105DE000EF6516BE82F022D5BAF9A25F5557A7FB20
+:105DF000EACCAFE9C682C3FF70D0808E7BFA47EC55
+:105E00009E81BCADC6759DD998FF1C9CF7FEE40928
+:105E100019E3DEFB45DFC92CB4476585F11FDFFBC5
+:105E200033804F2FACF3011FDF57C6E07FE63612F9
+:105E3000027A1876B43C05E03DEC68809755184F1F
+:105E4000A700117AF91E9D1F35991A04E09791DC7D
+:105E50009716031F18C7CEF70CD5CF9BCE2FB521B1
+:105E60007D12E443A58D4B9924E315DE31ED479F68
+:105E70009E0DF78FA61D79FA01F8CE20A25B0FD0F8
+:105E8000833B979D6739425BA15F75F7A3808F269F
+:105E90007E9FFC3098590A9647A04CA5FB7B530A7D
+:105EA000CC5322934BA2FC60D7136346015FC1948D
+:105EB000A7122CC3A4A42FDFD0F51FC1FBAB429CBB
+:105EC0007E16B762B0CF773D71CB08B0E39B414FF0
+:105ED0004C827B383D5F409E8EEA1311EECDE6B0DA
+:105EE000B5300DEEA51609E82F5B0A3E1461DF35CB
+:105EF00077101FD0476AF9DF2D7A3C96B9D8EFEDBD
+:105F00004832D904FBFFF088EEA980A7D02111AF59
+:105F10001898F42BE7D30ED0873E6279306DBFAE70
+:105F200042F9FD50A61CF73E5D72053D31B67FCAB1
+:105F3000B0D9E8CFCBDAFA18DEE7593955F27D8FC0
+:105F4000F64EDB5A56067A8C524EA96B209D77EBA3
+:105F5000A8B5F83B103358BC4C99CA9E2B9359B93D
+:105F6000A9E6E88FC16E0FEE916C7974BE2337B24B
+:105F70007BC436155EB406A85E5A5AF6B2F536FAF8
+:105F8000FCD3522A05E9F34F275CB4417CE7D9D210
+:105F900049A900CF8E06A35E47E0722B6A0F155900
+:105FA000827E179D57D30704E169B2845B2A68DDBE
+:105FB000F4AA13349C3E76CEC6A6B63940A70B0A87
+:105FC0006474DBC7AEB793CB8BF9D53D53E1DEFCF0
+:105FD0006C9530FF7EF02964CA0B39CBC8563B91D3
+:105FE000E9B8B632FB2428F9DF06BE1C2C0CC8F039
+:105FF0008AC6CF9A8655EC067E76DCC5EF0BA95A89
+:106000008CE7CA70FF9B401FEA298B6737153BED71
+:106010004C9F6DBDFD38F8A91754337D3FABF50B90
+:1060200001F141F5BE4174FCAC52BC5A902C58139E
+:10603000B416017EF244A228309F7602764290CABE
+:106040001F3D1CB471FFBBEF2F7359701DC5A03BE2
+:106050008F8EAEC7C9D793E9A3EB8923A70BE1BB0A
+:1060600090EFF3CC1787C603FCD73013292B784A5F
+:10607000B0EAE691A55EDD3C8AF83AEA5CECBC85C4
+:10608000ABB44BC0FB6B62F83BA8F3B06FB73B2ED1
+:106090008C62F6BD919FF6A973BA8A7D9E19C3AF33
+:1060A0008A2CEDD311BFFBD8BDD584D07D6BC5EB59
+:1060B0001B1576CF6748BB5FBA0AFA8D74393D402D
+:1060C000074D233E2C01F86CE6FAC2C24282F6EA82
+:1060D000C28C4ED417E6D7717D41F2D5039375B4C7
+:1060E0002613ED7E18D01F50550213BA8EEB0B9A73
+:1060F000FCE772BBD2DBD98072B58E9DF7EBD5334E
+:10610000542657B3BC4CAE5736D0EF289C98C7E8FE
+:10611000F51226C795AD5C7FE07238957F37AD816B
+:10612000C9AB54D023DC9006A1A25CC618567A54A1
+:106130006F1950C8E4656AD37E946B2F3A199F4C4F
+:10614000DBCAE4E5D0778FA900262F7DDC42F9F485
+:1061500013BCDDEBA1FA594A543FDB20F2781361FE
+:10616000FA21E6FCD3796EE6FDB5E73BF9FCF61FB4
+:1061700049B915F8EBAE600E9E2BD7F62D7A3F6924
+:106180003D93DF879059CDE2E42EDFA2DDFAF3677D
+:10619000152E76CF50858BDD07EFAA0E7B615CBC98
+:1061A0005701F9B88CFEC58D545F42FF13B7AF4A53
+:1061B0009DFC3E194E3F89E489C6875CC4EF2EA43E
+:1061C000F0FD34B41BF9B54AED2558DBA7C1DAC19F
+:1061D0004B61BF076795C2FC9BC77F85F91F5909B3
+:1061E000ECC58F343BF35BF275D7D463CC0EED1462
+:1061F000E39EEF497733FF43BB441C004F5B90DDC8
+:106200001B671B27C7ED6F7333BBEB53BE1F9BC7C9
+:10621000EFC6F39909E5B34454531C79AAC9DB26A8
+:10622000C0F3F574DDAE5FD5E3EF0849A17213F258
+:10623000578276679074A11DA916C8E8376C32079B
+:10624000AD808F2DA51CAF1E6B1B9CCBFCD678A1FF
+:10625000F0003C6FF48B21211BF01CF21431BF0EB7
+:10626000DEDB7986DAEFFA7845AE5BE47052F087D0
+:10627000F6B21A187D358F97711E8DA3D2DB4CD9DB
+:106280007AFE2B70FEC9E8AB71FCDB485F573BBF61
+:1062900045D52F3DF3A92E9ED8BDEDF91C8073F492
+:1062A000FE0B7FBFE7291655FF65EBCE387182DE06
+:1062B00076B0A39C600786BE6F886BBAD9BC6F743A
+:1062C0001BFD77C05FCD685C8406837F69DFC49067
+:1062D0001BDE236B58DC76098FDB7EBEF3763CAF8A
+:1062E0005E44C9CA1C07EF676B8CE7D5CFEE7A7E98
+:1062F00030F36B840CF1B325BB7F3ED2101FF61335
+:10630000256D0CBBB718E5F4DB3ED5628ADE3F2075
+:10631000C3EF0DE446EFD1B293762C9DB07F69E9CF
+:10632000263D587A401CE5829DE4C3328D946399E2
+:106330004EAAB0F492209683493B961960E7E68214
+:106340005CE8C152211E91E8F87E0EF1613D8F9408
+:10635000632901DE52A37109698F15F337207E018D
+:10636000FB3ED1B9B391EE8A656E8477D5B5E598D9
+:106370004FCEE21533DCFEE56E942F61E4DFF33996
+:106380002B3FFA9391ED70FE68F56676EE45E3EFEC
+:1063900068DFD0EFBC94C2E481FAB8807C6C9D6366
+:1063A000E68D08CF26F3397DBC8158AD79F0FB1E10
+:1063B000DAB8F3B99F613E9783E0EE66E7077D7830
+:1063C0003E693EF81B74EDA4B79DDD4BA38D233AC7
+:1063D000260CEF2FDEA77B1FF3A32B62ED802BC9CA
+:1063E000EF98FA82D8F7BFA6134A8FFAE35EBA5144
+:1063F000C9447AE5F29B129482EF35584EA13D16BE
+:106400009CE2D7C3E539CEE734B9B22026DF23B604
+:106410005C20F1FD11330E9580C970EF1ADE29A1C1
+:10642000DBDFDA7DA4DAEF642DF107E441EC352FF0
+:10643000E0D1C3E71D24AD9306D1F233A8EBFCFBFA
+:10644000BF4B0AEC77EBF68BC7CFEE59203C2EB151
+:106450009CEFC729A6A632E0736702C40776C41270
+:1064600052E5BE01FCF9C7D8FDC443E8BCE512B053
+:10647000E3882AA6605D85DF6B395FC3CE0975F3BB
+:10648000FB6876F37B85FFC4EF112E6A797826D0FE
+:10649000C1E7FC1E9A828E8DE5E0F7296A77CC036E
+:1064A000B95FD43EB112DA8BF658D8EFF0703EA146
+:1064B000CD0B8EB9DBE97732E8F7AC29C04F08CABB
+:1064C000DDF34DF610FC7ECFF97613BB47B550C413
+:1064D00073F770EDA089CF2F2905BEF75FF7823ED5
+:1064E000F239E727DDEE64862F4915D434484B2175
+:1064F0003ED06B1E73ACC473908B9CA1DD4FA74143
+:106500007EB8D5B78E7EFFD0FE5733E1F9538E9516
+:1065100058FE69DBF14CE05BE70F1C97E3D1ED0A15
+:10652000292C837F6A59872042FCA4AC7D9E0CF104
+:1065300091457B0FA15F79852780EDCB5BF6637D6D
+:10654000F2DE77317E323449417C9F1F14403F6F29
+:106550005E8B250C3F59B22F27B8346EDC3E89F193
+:10656000DDC71C6FE0F84F39DE781BE1B2CD82E762
+:106570003F0E6DFB158E7BEEC0AB7CBE04F305CFEA
+:10658000DBDA4FFE13C8AFFDFC3CA6B5D3ADF70771
+:10659000FF9DF375AD7E5EFB1D9D8C2BF4D37E8F2E
+:1065A000C7D9E9667CA9D30D71B345ED0C0E7F32D6
+:1065B0008765D02397B50B0AFC3E5ED9DE363C0FCB
+:1065C000B8ACC38AE72596013C006E145E08979626
+:1065D0004338FF0C80CB6858C7FB988F9FD741E1A9
+:1065E000521C5DF7326700F7ABB65E0A07B6EE7D68
+:1065F00057C253C088A7967765F0CB2CEF10107E5A
+:10660000CBF7B2792CEA60F39ABC771EE2FFDC018B
+:10661000A280BFA57BFFF1CF613DE70F58F1FE5E81
+:106620006D5E944E89BB04F60FA353D2C1F8AAA69F
+:1066300077AF08A5E3EF0CF4B6EF65BF330A20B3DC
+:10664000517A2DEA988571C162205EA0534FFB48B4
+:10665000F67B81C14C80EBBE89E14C98F739ED7730
+:106660004CA56026E065A43B509CA4DBE7674FBDCA
+:106670008A72B140ACFAC3A3B08F5F66BFBBF1F0C2
+:10668000C78F897A784C841F4A1E0D70FB9D1BE1D1
+:10669000D67B7F4B90E54B9100EEC7457C3F9E6FCC
+:1066A000A376275DFFD9969F61FBF941C6FCAA3FFF
+:1066B000B5BC950270ABE0E73148E876E447142EAC
+:1066C0000DD63872BEF75C5B889D57BC2010BC2F7E
+:1066D000537D46835B953CDB10E763FC30A335FBC1
+:1066E00008DA19A1F8E71C63F5A4D8FB5113E503F8
+:1066F0009CE6FCEC537E4F97267767B8033F481A19
+:1067000090F8BC77C5A6159900EF0A381B89F711D8
+:10671000BDF13DC823C57343EC5ED430C0A75BBB5D
+:10672000F79474B0F664565F9DF46F1BE03C58B765
+:10673000768FAA7A98B567B3F666DEBEC75DBE34BB
+:1067400009E53C11D8EFF99893E1771934B991181C
+:106750000EC6DF6568830B3706E0780FE278121DFE
+:10676000AFE8BB8FA7F1E9EF3C8EF57F761C4D7E3D
+:10677000C1FE84D447E2F38DFC9F80DF7FF77D125A
+:106780005C68D85797B7E5D6431CED9297DF03D3E3
+:10679000B496803C5FB8F531C3EF7AC4DEE354CBE6
+:1067A000F372E45CBADF74FBFA7012B3730E27095C
+:1067B000BDF794437C6B3821FC9E29AAE2A5F37BAC
+:1067C00025A9FE91CFEF2D2F2041D44F4792762C53
+:1067D0000B492796C5A4074B0C33E782ABD487E55A
+:1067E0009FCBBAC6C0E2975B03CFDA44CC3B7813A9
+:1067F000F6C9F9A181E7E1DED9758E95D7C3FC8F83
+:106800002479F83CC286DF5721FADFBF50401F9C35
+:10681000E1ED4F1F241EE95C6FDE4B0EDE5BFB9B40
+:1068200024C443A2DF41BB3FE6DE1B762E5C83C35C
+:106830000AB84987F6FF65EB6ABCC76FE95E17EADD
+:10684000C9C35BEBF0F7AF9692CE7438273C9CDF60
+:1068500023425AD8FD2DDAFD20235A2C86FB4B56B5
+:10686000C4FCFECE32FE7B59CB627F8F8A9FC3DD94
+:10687000040FE2E463C49EE33D9B14FF7715496176
+:10688000FCDF3F893DC7BBB75DC4FCA8D59077A5A9
+:10689000B32F46ECACB218E94BF94D9E5957177C13
+:1068A000CC1FE1B2FB77097DBF5394CCF4807D828D
+:1068B00010371FEF760FB7B7491D994EC7F9BFD4F0
+:1068C000AD220900800000001F8B080000000000BE
+:1068D000000BDD7D0B7894C5D5F0BCBBEF5EB349F2
+:1068E0007693CD6673DF4080201737185244AC6F23
+:1068F00042C4886817A48ADAE2060402E406A58A7C
+:106900002D2D1B122120D6F83522D0842E7829581F
+:10691000F5DBB4A848835D3022DEFA87D6B654ADE5
+:10692000DF827C8A88B06A4BEDC5FA9F7366267B4E
+:1069300021116CFDBFEF79FEF4B12FF3CEBC3367AC
+:10694000CE9CDB9C7366B6B55EB56F608CB506AD4C
+:106950009ADE094FBB2EA8143396975A655E0265DE
+:10696000E6D0D94778189BA69F72C853CE98B141FC
+:10697000BDC404E5BE1D4BFA0D506E75ABCCA440F2
+:106980007B878E3128B31C5D700494DBEC3F73CCA5
+:106990001FCBD8481BBC877E0AEC2CE8817EF76FA2
+:1069A000BF5D87E5D666C6B2711CC5DFEFA1EF54A7
+:1069B000F630C33F6D46998BB122FC278CA3B28D74
+:1069C0001FEAD318AB6E386E89D8E07DA476061B1B
+:1069D000CFD86576F87822D4BF79F57B58DEB6F249
+:1069E00098C30FE3BDB87DEDAFA7417F8620C005FA
+:1069F0005D947EDAFAFA34182FBADDC87640F9339E
+:106A0000FCBB82B1C255EAB1889906649FC17FF987
+:106A10002B12CB4606E552512E4638E2EAA13C0E37
+:106A2000C7CFC2D21C167661BD80D7A9310670329D
+:106A3000BBCDF9CE18C62EB52BECB361B1F2C5585B
+:106A40000694EC3474545901CE9D7F54BC2D507D76
+:106A500060FBC2229CDFD967FC457698C74A73DA8F
+:106A600078961E8377E099EE11E3062C3A373EC301
+:106A700016E68EB51FFD50B3C90FFDB4AD66DEE35B
+:106A800023183307FBAC63701D0F19BC50647729C2
+:106A90006C4E08EA551BD34230CE388742FD253F65
+:106AA000EF5AED79B9C4101BF7AE4FAF9F83EB1BC4
+:106AB0004DB56A3B9473E192DFA9764F00D7D7902A
+:106AC000CFBC29309EC1D99F6B87EFC63C6DF4DAED
+:106AD0000065D3FE736C7A04C61DF3DC4DCC93CAFB
+:106AE000F185F0AA2B8DDEE3998C99563ABDEA2503
+:106AF000D8CE46F4F891CD183421FE57DEDD81F56D
+:106B0000ADDB2BDC9EB1B171D7AEB67B5580B36BDC
+:106B1000B5D9ABC204D78AF925C357E0D0F982F0C2
+:106B20009D51C7FC585F0FEB80F4536F4FA1E752A4
+:106B30003B87BF5B0DCC42F8BB817E5A905E57709D
+:106B4000FA5D9E630E229D2F7F7178361B3BC8BA7B
+:106B500088E723ABDDDE1280A36BC53C37834F2B68
+:106B600097F559AE82F92F4F35DB911EF569231F3A
+:106B70009882F4FE9281215FB5A65678E6C7F5A704
+:106B80004F9BE4467CE875815C6667ACC57E4B8DA7
+:106B90009A83F412D8CABC8CADEFA8AA512F857283
+:106BA0006A205781FAFB3AA6F1FAACC05605EAB75B
+:106BB000744CE7F505815C1D94B7775CC7CB230265
+:106BC0005BB1BCAB63162F8F03187219EBE9B8A148
+:106BD0002600E3B71ABC73BC30EE1300FF58803FA9
+:106BE000249E3F177891F53FC3F780EFDDE2995C73
+:106BF000FF94F86ECF10F57B457DEF10FD3F2BBE67
+:106C00000B0FF1FD01F15DDF10DF1F14DF1D1AA274
+:106C1000FE2551FFCA10FDFF4A7CD73FC4F7BF16BF
+:106C2000DFBD36C4F7BF13DF1D19A2FE7551FF6625
+:106C300052FF6F89F611F13E3FB5FDF500D05D3E84
+:106C4000C82DFC2B4D6DCF40BAEB6A2E27FA6F9DF5
+:106C500008743E3646EFF90AF361B9D4A1527FA514
+:106C6000288FE1F9AAE8BF7259C9BD4877CB5FD533
+:106C70007B910E5B15EF113FF41F58A6F3A2DC5D6C
+:106C8000FEA29ED3F93235C8E2F8FBD524F8B70945
+:106C9000F8DA04BCCFDB87517DD14AB77786949769
+:106CA000C8F7F6C4B219F84983F1DB9C5CBF942E97
+:106CB000AB328F42FD01FA05E5E65D3663D804E3A9
+:106CC000DF6557A9BECD5965C7FA805D25FD73976D
+:106CD000B3CA3C1FE5AA0D845D058C67E77DB7D973
+:106CE000D59A20CA0F4735D54FFBCF197694A36D9F
+:106CF0002CEAA8C4F9AD02BD02DFEF6FAEA2F745E2
+:106D00008E3F39503EBF9CC1F9BF2FF5A0A518DAC0
+:106D1000A9DFD691BE186957498F0D5BA50B7AA0E4
+:106D2000499F7DB90ECB0FB6717D057FA965307E79
+:106D3000091F9EEDBCBDE2A552D467F7A85E8F8700
+:106D4000BF53E3F44109EA2BD05F398E0C2E1F8527
+:106D5000BEEA2E671AF61B709B830F43BF252A736A
+:106D60006766C4F09EE3D07339AF9FE145BD36BC82
+:106D700023513F15B7C7E92786FA32513F25EBABC0
+:106D80008266908F71DF9BDCF684B2DE914AFA094D
+:106D9000648CF733187A79CFF2ABAC2C26AF93F52D
+:106DA00051ABD00F52EEB67E7A49827E907239593D
+:106DB0003F9C5FBEFEE6EA51448720AD3CE797B3B7
+:106DC000AF221DC03A1AFC0AE90FA6FADDBED4F3C1
+:106DD000E3CB60F0D9EDB6F3E3CD90F51AD9150603
+:106DE000BF4AFD9FA357CE8357D9CE687EB0FB38EC
+:106DF000E8B53FBD7947290396590BB8A1F5CFD225
+:106E0000051F8679E7AFFC6937F69F77D0DA867879
+:106E100036BAE777B7E17C3A1E600CE8496FE6F4D2
+:106E200064CCA9B2E3F7AA4E73670C87F2AEDFDD3C
+:106E3000AC003DE9339BBD0CD6EDD0132F655C83D0
+:106E4000F87BD5407C6ED2F9EC6C388143F4B6AE59
+:106E5000C0BA7D03D1B1DF8C78CADF69263DC0029C
+:106E6000DBD76B40D4ADB01C6C32D67F7DBD06F84D
+:106E7000D9A90C94AFC6722868E4ED4144E3FFF54C
+:106E8000E81451CF341558F3714511F5FF59533DAE
+:106E900005DAABF6312AE89DFAFB7ED66EB81CEB1C
+:106EA00075F27B8D4D82F9E278A2ACC2FAFCB44F48
+:106EB000D407C2EDD5C0443D46393E0B60FB1E9D54
+:106EC0008E9703CFB463FF8F5789EF030FAED7F2CE
+:106ED000099E6BF40EC6BEE3E86BB75D1A83F7EE4E
+:106EE0008C97DA5B607E1F782269B09CAC61FB7185
+:106EF00017EAE775739A7D8837247C1FE8C414BDB0
+:106F000087E86960DD76CF0CE441ED99837F4B1B08
+:106F10000B554DFAC8C114C05FC39E66B301BE379E
+:106F2000197C81BCE2D8770DBB6BC99E69EA2DA3A1
+:106F3000E720DF1D5287FD4BDF998D1730DE07E11B
+:106F40005F373E06550DFAE6769B9EDA33BEFE832A
+:106F5000CF4F7EFFC163BFBE01C73BED89B8A643DB
+:106F6000EB7561C0CB20DFC9F68D7B66D2F3D729E4
+:106F7000DA7A07F0752DC82E92576AB317DB87CCE3
+:106F80001D762F20DA62E8F0A1DE00D40775936247
+:106F9000CF8D8E126A9FFC3E99BF4266963903E5FB
+:106FA00078BD4A7A2A640EA48C87F246D887B4004A
+:106FB000486BCA7E37612C969FB431DC97B4D6F704
+:106FC000B9C7225F798D0CEDDD8D97867290CFDB8E
+:106FD0001A8C731E027842E1E5EE0571F6D6DD19D2
+:106FE000069AD7FAE781EF2E86A721E450F0FB112D
+:106FF000A03780942D0EBF19F739969C0C1628C621
+:1070000076B68DC89FEB0DFE9A2A6C97A323FD627E
+:107010001931BBA60AE07067E9143DC1517D6421B6
+:10702000EA37BB1135283B9231EF6788A79FAADE6C
+:1070300066E4C39FDA6CF60054808CD450FEA9231A
+:107040009C412C9BF4AC19F5785E19E8F3383BF6BB
+:1070500088909F471C468277A32534B312FAB12E3D
+:10706000D7D90330DEFA864DFDD3609C1F353C75C1
+:10707000B805DE6F70A90CE1B039D5B011F48FE11D
+:107080005A8011E07EBCC56747F91ACD52D90EA8C7
+:10709000B7961899274E5ED9C642394E4E663A5574
+:1070A000CD02DF9FCDF0BFE880712F79F535337EBB
+:1070B000EF9EA8D321DB8454BECE69E589FDD8A715
+:1070C00024F693519D58EF9C9158EF9A9D58EFFEEE
+:1070D000466239F7B6C4F22C496F20736CA08FADAD
+:1070E000BC8A59231FAE467D0BF8F903E2DF3A5202
+:1070F000E745FC581A1E3AB110EAF3509EE07E684C
+:107100003C23BD7BA0F03B1EB40B4C19CD1EC7D851
+:1071100073F1915760BE06D7CB56A2DA19B4B7BD4A
+:10712000F9DEA7D8BF8DC5B52B46FC6827113FF8FF
+:10713000E7067852F11F1EC477F37F7D0FF5E261F9
+:10714000BD17F19DD7A0D2F8F7CCF604F5DC9E7000
+:10715000A33D9326DAA79937F6EB419EA7BDB97EEA
+:1071600019EE7B93F1EA62CD0AF225D007DF6FD7E3
+:1071700032D21FEB74AC0EE906F708D81F994720EE
+:107180002FAECD34129E1461EFA0E6C07A97B09F67
+:107190008C39B759908FEF3AC8E9FF2E23EF67A0DB
+:1071A0003F0F0D8A24CF504EA666E812FAD9641715
+:1071B0006D4439CBC1CB3D7D19D7205F6E9A9D318F
+:1071C00001E9C484FB2EE82F3DDFAC8D86F9595EC2
+:1071D000340614E8345D657D0658CB1E2BBBD507FD
+:1071E000706C39640DE8E1BD65C17FD8D14E1B9F3D
+:1071F000C1E9BE678DF7372807A2B52AE1D192D53C
+:10720000619F3096CF2100F02139A05EAC1CD1499E
+:10721000769EA5B283F4BBA5ACA303F1B465868EBC
+:10722000EC8D8CDB7444CF9682D0E112F4132CD019
+:10723000D9B1BF0C50FC46E8E487F91D3E1FF60BA0
+:1072400038D7557052C17E6986304EA6C0ABD3B9CF
+:10725000FB0E05FAC9C4FEC6F3F6882787C053455E
+:107260008687E0768A7E334BA0FD78DE4F5B45ACA7
+:107270001FB98E5B6A5810E193E3CA7E06FA679ADB
+:107280008272D5F032E00DD64929341370772D6122
+:10729000B43FEE59E36BDE4E7C6D233F47AE33BF08
+:1072A0000AE928F7D0D659BAF1F89D95C6312C6075
+:1072B00041A4E35C9599BF9A81F68D8FF098CCAF8D
+:1072C000397D1DD7A39D2AD725997F7354D6AECF7C
+:1072D00038978F739CCEAA91E307E1E7247EC939E2
+:1072E00014FD36127D325F6F4B395D867861F1EDAA
+:1072F000F5E72FEBF5A1C3E8E761D9A02700F585F5
+:1073000049E331F64F139615A6F37C361CE5BE43D0
+:10731000D031E82B60D69E09F6A936E4D3658CE817
+:10732000ABEAE98D37BF0CFD9D1D61B4A35E293822
+:10733000D4D18FFA91EDF18FC275E852FD3F4E81A5
+:10734000FAAE23D90CE5F67A0BDF8FA982CE93F53E
+:10735000CBDD197C3FE6413DE7FED79FD23E0C9541
+:10736000B8C6D881F7EEFE8F2B5F3467FD0FDA5970
+:10737000ECD1F51A94F3FBFA5B6C38FE7DCFB79B2A
+:1073800001BF965779FB0D500EA888BF7AF2671D92
+:1073900028584878525F3731A4D3717A2D8865F622
+:1073A0008685A1FCDDF9E437EA3C287F5CD33D28E3
+:1073B00087BA04BF6F15CFE4F9AB46CD8FF644F220
+:1073C000FBCE01B9E43B510BEB38EE4123DB0095DA
+:1073D000A5BA79EDB8BF8BAE07F90BB5F3F49EC62D
+:1073E000BBE3F6B7EDD6CA4733E0BBEED566E6079A
+:1073F0008339FF1385F981390B9CBFAE44F953C81B
+:10740000C20AEAD9C266307891AE5658993F8EDEEC
+:10741000F33F51A97DBB557B34238BBF37831C3091
+:10742000F07FB29F66F858AD93CB28B45F0C8F59AC
+:107430008FA2DC60CE6A6D603F320CE917F43E8C9F
+:10744000F7B498B70170689800FFD97461D3F873E6
+:10745000DBF70A79AE9A6D619497AAED9523245FC4
+:10746000ECEAA9F876B8EF262156CFC82F8B78A181
+:10747000F2B7EC54CE03F96B9A40767F00F7DF81C8
+:1074800034BE1F619AE671BA905F182139DFCCDAF9
+:10749000CDD08EA81DF82D87F55BC86EEE631EE477
+:1074A00007F4B0BD9342228B215EBB18AB89E70382
+:1074B000F9947E0975A59EF653639EB3103C8666CB
+:1074C00016B4A03D84B001BED5152CA816C7FC8209
+:1074D000A50E0F7D6764CD64CF3EFEE95BB928A79A
+:1074E000AD07C11EBB18D7594772CA6A4DE43FC6E3
+:1074F0005A084F27057D74AFB6D33A0FECDFFCAFC7
+:1075000089758EB4A0BE285C9191B0BEB25DFE2795
+:1075100079CC7F497CBF41EA2FBFA44F41BF4CFECD
+:10752000278554DFBDDA739EFE870DD17F0ED1D142
+:10753000D0FDE7537D77F835C775808AAE689FC365
+:10754000E789D9D7C978CE5F9128972FDE935896CF
+:1075500078B11834E74CC0B9E5DB3AEF76E8EF2BA9
+:107560004712DBD514FF96F6BFB1F661E7F5D81EDA
+:10757000F6E7DBE1ED652712DBFB2A9F77201FC7CB
+:10758000DA73F8AEF824B15DF2FA24C30B70657DAE
+:107590003D0EAEA9665342FD9CDA73E0CABA310EC5
+:1075A000AEABDC89EDFD2D83C3754DA9E973E19286
+:1075B000EDBE36E9C2DA25CFE3FA1AD31078E7ED4B
+:1075C0006F9C7361FDDE52F7F9ED6E5D993C4E8064
+:1075D000F8A551A75D9E09CF79F80AED459B95EC7A
+:1075E000DE647A7954E8A76A343CA0BF8BD2B4EA4F
+:1075F0004C785649BE137E86434F5C948D723D4F46
+:10760000F8D199F02BF4D4BBC9AF70B3680FFAA4CA
+:107610000DE545CF4EF82E8DC3156F3F65D6F37D32
+:10762000859D45899FA5BD94C1EC0ADF8F737B675B
+:10763000A87192FB5F97C1E19EBF722A7B1BF8F095
+:1076400029A3BD52C5FDD93685EC81F9D59A3E15E1
+:10765000E86372BB427EA5F977FEE687E88FB9F44E
+:10766000B8674F04DECF0F3ABC386C633FD3304E5F
+:1076700090AD5F56F63D78DE7F00EC1F515E86F4DC
+:1076800066D33CB8DFA84588A09F5386E6323BCA44
+:10769000CD6FDA34949BB5B3B53FD07CFF0156096A
+:1076A000B45BC0A7CE9EEE9C69C47847ED373C938F
+:1076B000D0EEA90D59347A9A996A8579D4823D869B
+:1076C000CF6C23532DF8B432333E2BD670FB2B6D89
+:1076D00092CF580BE3D7F6FEE4CFF8DD2235BC9FFE
+:1076E000DB93419A776DEF8B7F457B6D81E633A20B
+:1076F000BC18B3D3C86D52410FE34289659407F1BA
+:10770000E5B27062F9924389E5F771E1607D260B7D
+:107710003FD6817D2692DB4BDFB792FDB917141E51
+:10772000EE93038F9B487F4C5D6AA3F57AFFA475A7
+:107730003BFAF5F6BF6EA5F64B7E6AE1ED75A12723
+:10774000B01C782285F6D94B3343151900F72F3E2C
+:10775000D513BE715A06ECFF89D1DB3760FD25A138
+:107760000A8C8B3D751163FD58AF06C7E33C9FFA49
+:1077700027F75B477799823BA0DFF79FF9C913DFB3
+:10778000C57177E56528B03E97A15E8076931F347A
+:107790005B71BF31F9FDC786A3DC58BAD39430BF03
+:1077A0009D998A88AB79D290EE86F23B1E5BFF13DF
+:1077B000FABEF4C411A2BBBD86800EE37881F59CAD
+:1077C000CEF65AB89F74AFA53088EBF47426D73B39
+:1077D00097E976FCA811EDCB57B91D3254FFA5EE01
+:1077E000F9DDD583F81907EA61DC6258E733EF5910
+:1077F0006FD5008E519B13D7697430B1FC4B31AFFC
+:10780000792CEE7D31C2336CAD1BE1D9CE089ED20E
+:10781000136FDE5C8CF6B889DB21C9E31ECAE4F283
+:10782000E1D147A11F2E67F4DC0E078C015F2F15F5
+:10783000FCF00B85DBC1F0B7220FE87F291A10C3DB
+:1078400062EF9726C121FBFFAEC0D3C7E6B41DA8E7
+:10785000CF9D464EF727571FFA21C63165BB775695
+:107860006B5A759C5F79E1E665077360FDEB7BB24F
+:10787000689F29DFD7EF7ACE750BBC3FB553F5A2D1
+:10788000E95B7FD3233F988CED76E9430827D6A3A5
+:107890003FF354E8F9346CB7B0CB3101FD25F2FB6E
+:1078A000459BAFD4AAE3E4E917E527C9FFF5627F5A
+:1078B000FCF4A4FE697980EFA59B152F365B1AFABC
+:1078C000FAF5D7A2ADD3A5F7627CA342653EFD04CD
+:1078D000DABACFC6677DCF930773A1BE69DFC40A4A
+:1078E0009CD7069DEF9A71C82FDB0CE4074B5E1FF7
+:1078F000E6E4EB0CDF8775F0FD861B6C75181781CD
+:107900007EFBB07CA074871EFDF8692740BEF1F7AE
+:10791000477420334FF4DE351EF62C40C7B676E4AC
+:107920008FBDE8B8C0711ED7939E60613E8FC9C2FB
+:10793000FFBCF48F9D46159E274EAC49ABE4FC4737
+:10794000EB8442DD09F3AB7B701CF1EBA2CD89FC2B
+:1079500025DB4978170713EB93E9C2E394FE0A5637
+:107960001A4F5FC9ED3267048CC88FF52B419EC753
+:10797000F14DFDF10E23DA5DC9E3A005C9E4BAEAD1
+:10798000892E612C9CAF85CF174C5E33CCF724FE3B
+:107990008BFBCD15DCD72F51688A6CE945ACDA0337
+:1079A000F85C3A8BD5E053CAC3539342E3B1FD5E12
+:1079B00043E4911F911C4C257970CA1E4E43BF525F
+:1079C000AEF0EB9DF284D350CE9D11713BACC7F26B
+:1079D000925ED007C0D7EF7F6024BDD0127A2E0D03
+:1079E000D7EBD413169D0ED6E5FD9ECC2AF4079D49
+:1079F0000ABD9C86F33A19CAAC42BFDE50722259C6
+:107A0000BE497BE028FEF352C6AE746A9A13E51DA8
+:107A100006197240DF643697350FC2F7F23BA7B103
+:107A2000B90CF334A2DFB47951CE5EEBF4D0FB5A3B
+:107A300085F7877F18DFFBE850E60E5CFF43FB47C6
+:107A4000A6A39DF011F3A4A3DC9EEBF2F99CB09EDB
+:107A5000EEAA7E8AEBBBA7336F2B7CF3B6DE7BBB33
+:107A60001DF0761B03BD85CF72BF91FC2D6D5904AF
+:107A7000D77C958555A0D3F9A857C75399EC98F9A9
+:107A80005D4AB015E0B86D63E23C17769A62EB0B85
+:107A9000FF2D6620109181BAE2DA41FF8B517F02FF
+:107AA000FE9698593805FA5DF250E2774B5998E006
+:107AB000A97FEC33D36078FCB3C0E35C97B618F1D0
+:107AC000A8CC32135CDF7A5C21FDE6147EC6E8FDAB
+:107AD000E9418C872D15FA7A81693FC1D37467AD6E
+:107AE000761BD0CD9995F3B5DB3279CA08EDCB364C
+:107AF0002B44874BAB59B800E05BDAAB84C7A13DA0
+:107B0000F11A5F27D92FDBC6DBDD2CEC9D05801732
+:107B1000B41F263FA60452417E2E30C3560EE58880
+:107B2000981FD6A743B98E75D0BC1A5884E0588BDD
+:107B3000EBC8FD7904FF9F5FE3EB37B96EBB1E8195
+:107B40003AB4BF82E27F1F332FAD23D825CC927188
+:107B50002E9D20DEB5383CD5752596D94371E5615B
+:107B6000885728C7E1BB71F767266D103CDF3FA03F
+:107B70004F82A3678E63E7D8BD6F8975B8FFEB0BA3
+:107B800073500EDC8BF66BAEE86012CA4D26FD1A00
+:107B90006133F46FBD8425F839C0BEA2F283CE995B
+:107BA000D337E733B6C9E0A778C17CBDEF2086B6EE
+:107BB000FEE9F2FF04D777BE4E2B54491E682369B5
+:107BC000BFBB92AFC703139A47370FB2CF95F06F81
+:107BD0005242611DCA8367B87D905A1E35F8E3F89A
+:107BE0006CBF9073E9072207F3905E9E54C82FBFC5
+:107BF00045616D0AE0D90DCB82FA608B72F420EA00
+:107C00008F2D577B582BD497EF9EB9EC79DA2B5BED
+:107C100029AFA76177A5BEC146F3E7F66A4AF376B6
+:107C20001DD467DF5A3A01F904E67DEB2C787F50CA
+:107C3000F06D8E8DD3837B4DA07839FA650FF89661
+:107C40003D8FFC3DCE4AFEAF6C33FA7AE9D98E7691
+:107C5000A89BB528D8EEFE34DE7F964E7FEB4C2CE9
+:107C60004FE0E58C558AB68388F83EEA3FDBC46A6C
+:107C7000107E7C8FF63474A7F5507D90E69B3DB561
+:107C8000B90CFBCB1ECE9F4E63381FFB796560BDE0
+:107C9000FD3A94BB2B84FE5CB1BD2A1BE5E42BA707
+:107CA000CC2ACAC357DCD20E0CDBD00E6425A5BC8F
+:107CB000BDD0532BCAA66623FD3A0B13DB9D31685A
+:107CC000E997A0BC3FACA7B8CD9F6C5ABA03DA5D68
+:107CD00066E4F3485EC7A8D0AB4D9F282C18B7FFC9
+:107CE0006F9A7396ECECA64FD484F7A7569B593045
+:107CF0006EFF5F5F77601AB66B60FD6B91AE1A42E4
+:107D0000292C1847E79759071F57D277D3277A1698
+:107D100018745C63E2FB4F32592073B076AEC4F73F
+:107D2000308F84F29EBF0CCC03DFB3499134F487CB
+:107D3000CE40BD06E533415DC000F2E41503D757E0
+:107D4000A7ED91047D76DA13E1FA0CFD3D366E6FF6
+:107D5000CFC47556A369B35263E3C87AFC3E236E61
+:107D6000BEA7E7185998D6274A7020FE02A318DB51
+:107D7000DAFBA111F35CEA7BF713FE24DDC4E331E7
+:107D8000101F3F6AED0FEB80F7C7DCDFB961EC68CD
+:107D900058B20382CF039B36605CD8A5D725F07D0F
+:107DA0004AF9801C20B1733F46B3C81FFAC086EA67
+:107DB000FCB8B2683FF07D60F374AC2F1FCBBF9F5F
+:107DC00078FF9697D65032480797A36AB4D0971A8F
+:107DD000573627956D501E1757B627D53B93EADDCA
+:107DE00049E57CDEFE546AB850EF05E0EFEF9E8E69
+:107DF000F95CA772C27331FF6BA33E38BD1ACA0D7E
+:107E0000E55CCF36F62A5EF2E109FC357AB9FD670A
+:107E1000F3468C98779652DE7F10E544FD1EC5AE82
+:107E2000003FD8423D612AE3779EB8EF420A7D5772
+:107E30001F3A4ADF0DD97FA98EF87D43E931DE2E46
+:107E4000F42EE9F3756DCB28CE2EE3C87AE6D7F28F
+:107E500094581C59CACBD339DA73242FF72976E406
+:107E6000CF013AC57EE3FC37B2FD1BE37A7F8BE698
+:107E700042CA8A0F5BD02EFD63C3BB13D14E7B4336
+:107E8000E8854D4A70348EBB95F947A3DEFB66C387
+:107E900088FD3A68F79621D28DB1B2D5F73F49F8FF
+:107EA0007B2B355280F9742D59E1E9984FF75656DE
+:107EB000A41BF1F9FBACFDBCBE205280F97377DD49
+:107EC000FF3EAF1F11E9C6F2E359BFE7F5E3220514
+:107ED0007A3B6E758E4CAF86FA87ED83F3F5ED59DC
+:107EE0005C9E48F8869768CBB2D00EABE7FAA41B2D
+:107EF000F63666909B73979C7CFC61C0C3DCEFA454
+:107F0000903C7BF8D4F5D3B99D1DF0A915E887E521
+:107F10007FA4EF486EABB4FFCD411D97115B8FD4AA
+:107F2000C27E0FE9838B9A7BD06EC89E3B96F4C1CC
+:107F3000579DDA111C573EBF9F074F687F24CBCE59
+:107F4000E5B35E4771E9ECEFA6929D75AF85CF076B
+:107F5000F886D6D726D6E3EE2CAEBFEECEE2FBB740
+:107F600045CE2BA9BF9B855DDCB93EB8CB02F87F1F
+:107F70005DE6BBDCC7EDEC5BB6835C0139DEE9D0C6
+:107F800072509EDC22F2D7A4FCC0F71971FB8BCE95
+:107F90003228DB62FBC8CE995A8ED5894F970EE303
+:107FA0002F521E7516F3EFA45ECA6EE5E366DF3B43
+:107FB0007A07CE2345E57EA4057346EE6821FD3E93
+:107FC0008BE6CD342D4781FE8E2F1EA643FF925C9B
+:107FD0009FEA12ED61ACBF59F8E7E53AC9F53C22DA
+:107FE000E63D5F0FF601CCF3772E3FCD1FEC85F118
+:107FF000C28F45F6C2115CE3AC187E991A9988EFDE
+:10800000FF3FC2D34B5F069E1A5682BCD05D80BC38
+:1080100010F8DBA4840DD95C5ED0BE18DFA3DE7936
+:10802000CCE97F0BFB97E3CFFD6E03D98712AE94AB
+:108030003B9EAEB9919DCB67C9F6DB09B15ED2CE4E
+:10804000F44A7FA418E7ADD7CD147F78CB1822B9B6
+:10805000F916EC6B5A50BE88F879C57796BE82FB4C
+:108060003AD9EF752E9ED76791EBAEF87A16166364
+:108070003E090B98711E338DB4EE52EF763A787E3E
+:1080800048E79D79941F72864518F9352731928FFC
+:108090004007541FBDC945FC0FED03166CBFF82205
+:1080A0006A0F741120F9709395F6219D186FC6FA26
+:1080B0009B4A8398CF82FB5FA2B7C53A1A77107AA2
+:1080C000E17EE3513C5F42D28DAB95FB6798AA8D70
+:1080D0009F19A7E72F72713F514A79E4C9DFA37D49
+:1080E000BAD142F629EA588AED7464533FB0FE993A
+:1080F0002EBEBF273ABBED07A9222FCD5B81785D4D
+:1081000097CAE9B2CBC2E34E5D600F935C14F42BC7
+:10811000F3E2FCC2DE8BD4E9D2D05E28760DF80DF6
+:1081200034DCC793DF1BEAE74594A3B8FF9A17D066
+:10813000874DB89F6ABF528BC4ED47F00FE376B707
+:108140000AB9CA3633F203DE8ADFA561FFD6348C62
+:1081500053DE8ADFA3DF75D59509F1B84B5C9CBF70
+:10816000257CC972FF120957C7035AFC38B2FFE4D5
+:10817000FE605F59EECA223C87D3717D5BF4B47E0A
+:10818000C970463673FF75647311D19DEC6F283842
+:10819000FF4B1FFDB6027A70E154BEDF96FB9805D7
+:1081A000623FCC5625EED3D05F3250D69F5B4EDE79
+:1081B000F7619C3DB13DB75B52C6468DC4B71E25E5
+:1081C000017E89AFA1F070F317C49BD47B0F588058
+:1081D0000F32703BAD10FD6EBE3385F498D3181C82
+:1081E0008D74B5C0E5A1765B31DF85F42ADFFF7EB3
+:1081F000FC8AF45F24EE7B9BACD16D88AF262B23E9
+:108200007E3ABD2F95F8879544E662BED899BD2683
+:1082100086F4DBA84446A2DC3AAD68B5D4AE25C5E9
+:10822000837C24FD036F3FC5FD034D884980AF2942
+:10823000F077CA576ADA93B81F3E0DFFD501DD9F6C
+:10824000D6452AB03F290FC08ED6C83EAAE3719CFE
+:10825000461D0BE03EEB32DDBCC59CCF73D90E7AD8
+:108260007F74E4F2383B1DDAF529199C7C906FEAA3
+:10827000051E1B75C7A85D3DE61D213E71BF85FE2D
+:108280002EAC8CF3CF366E7C9FF29E1A7727AE779A
+:108290007D8C1E94CF14FC2E8E3E889F03421E3090
+:1082A000EEB7A8E671E854514EA9E9A73CA826E12B
+:1082B000C7C83A1099867225B53CC4E6C1B3E90433
+:1082C000B73726F76E7F0EF7C78E9AFE02648326B5
+:1082D000E1EF93EB2DE1BCB4F73EF25B483B256E3A
+:1082E000DF397A5682FF600D7D87FB581C2F82AFE5
+:1082F00072900CB87EDB24F41BE84192B70B3A462F
+:10830000911E443D85F249EE83515EA19CF8A7ABD6
+:10831000AA07F9755376D563AE2C3E1ED9F5B8A9D8
+:10832000BA74683F9DC48F6C87FBE1CFF3C3F5221D
+:10833000DD66C5FCE3045139E64D6749BF1BC5E75F
+:10834000962B9E6CA4DB77F47EF2AF2D6201F2F7E0
+:108350002C46BF163CEB05BF2F147EA285C23F847E
+:108360007EDBF83822FA4FE3CB4B583F971B3B4D4F
+:10837000B1FC1AF4E754B3702AF4D780FE267C8649
+:1083800012BF6B6451FAAE69CF67A6843865279F28
+:10839000F7AD62FD1DD5413DCA892D16EE6792F2FB
+:1083A00063F22AEE8F4A9FA015DF8574FEA281FC3E
+:1083B00014FF2DD66D40CFBBAA9E42BD62D5F3F30C
+:1083C00068D1BB4C24378F833EEE11FE9159B80F14
+:1083D0005DCD34CC5F67AABD307E9F2A9F1BF65AC5
+:1083E000EA907EDE75E912E8EB472E9ECF437E23AE
+:1083F00092CB29A477417C8C47FAAA1826F5221B38
+:108400008FFEAAA362DFDC7883CD8FFD45745CDE2E
+:10841000FCC9C5F7017F72F17C4E591ED8E709FAF5
+:1084200091F13FF4DFC4FBCFFF3ED0FE3E9177CB0E
+:1084300068BE9B168BFCEE013AD6915C4A19EB2381
+:10844000F97B99AE8AE452F43D9B07F152F37EFD2D
+:10845000629CC74773AC748EEF36E1CF4DC976503E
+:10846000BFD27F7BBEB858CD86D1242F65FB34DCCC
+:10847000A0649DEB07DE2BE4D85EC6E10D9CB0F254
+:108480007C13950550AEED0D8D0E22BCB5C2FF805C
+:10849000F60DCAD7E8937C1D99CAEDA1BDBDE38254
+:1084A00048EF470DFE2D0BD09FD36320FF1A538357
+:1084B000BB1EC17E9ECDF162FECF695D74DBAFA0B5
+:1084C000DDDE138FE661BC67AFF0BBD71BC323C9EA
+:1084D0006E16F98EF569E191E807FA8558AF7A2BA7
+:1084E00094E17DAAC53F2A3B2B1617C3EFF0FDB1DF
+:1084F00020B7CB8F314E07818D3CEE09F8CD5980E6
+:10850000F0AECFA6B81AAE0BAEC3DBFBC6D1BC36FD
+:108510001944FB67146AAFCC2A9D4B7A61832913F7
+:10852000F17FC667A47CDDA67BB9DD385FE7D9B6ED
+:108530001265E5B32934BF059D8729DED1F4834553
+:10854000740EB269C9AAEBD8E7C40150AFC4FBAF3F
+:108550004FB36821ED87EB8685C200C7E9DED15EA7
+:108560001EC6E3E76A1A455EE87103D310EEE83EE3
+:108570004370B0F37E43F58FF3C5FD29EA37F273FC
+:10858000C7C75B481F24C65FCE573E6D888CBC139F
+:10859000C65F9BE9BF293BCE5E6C7A3687E4DDDBA4
+:1085A000F7FCA590EC8A0E1E2F386ED0E6229F387D
+:1085B000AAC3C6797176D8B26C6E97CE3709FB1113
+:1085C000E4603CDFCBFA8AAA443E93CFE66C6E8728
+:1085D000A48AFC8073EB65FED9F526D49FDCB584B4
+:1085E000FD72795D24E26E934F44F7639E557DA83A
+:1085F0008CE27A45ABC2C49780EF30DAFFC7B7A4EC
+:10860000727902D3C47E164E6264BF2ED4F37C8787
+:108610008526B087B91EA7F6EF6CC9263C54ACE19D
+:108620007660F44985E4A28C3FD632FEFDD36D47D7
+:10863000037A685FBB532903D1CA6ADB2A291F6208
+:10864000495731ADFF64217FE79BB4915B90DE9E7B
+:10865000E6F12B188FECEE7ACCF99A4072C988FAC1
+:10866000B06EA7C2F0DCB09C7F72BC8F0513E32D07
+:1086700093435C7EA3DE6071F69AD443A82F589290
+:108680001D9948178104BDD78D789D1893FF84B13B
+:10869000CFD183604F6F43FAA9A8E2FC17ED5108D0
+:1086A000CF0DAC99C787841E1A8047E8B177F45C78
+:1086B0006F2E34DD47CF9FE321B02CD48311AE075A
+:1086C00041AFA15C1C8A2E7E3E045D487AD82DE81D
+:1086D000A3FE040B5F0EE3D5AF62E186F1FC993A8D
+:1086E0009EF432D7CF66AE9FF169BD003D9DAC9F31
+:1086F00093F571B21ECE36727D2BE920DE4F8FF6D8
+:10870000C8E455413DF7C3E6DB31CF4FAECB22A7DE
+:10871000D6979715B3B79A8E98CD9E8BB1EC63C35D
+:108720006CE85FAAF415A0FF5CE5E78D53004FDB12
+:1087300071FD847D7E79015F47B7C8E731A83E5659
+:1087400066C375EAA7FD74348B517EB6C46F772A71
+:108750007C3701BFE3FC38F0BD99B559E3BEAFDA11
+:108760006B21FD72F699543A57C6547F9103FA7300
+:10877000BD01763A944FEF4D25FD7E5AC87BA7F494
+:108780005BB0B5B41EEFE23A4F44AAABCA43FF2F29
+:1087900053A6E7313A6FCDEDC606C7507E7B515FD9
+:1087A000DC7F03A73313E9D9B38EC8ED58067828C8
+:1087B0005FF8BF04FD36ED9E5AF65D8CF3FB6C5EF0
+:1087C0008E557F19DA0D26FD8A1BCC7A3C77BF2A9D
+:1087D0007A27CCA3A1C04679C8D5456FFEEE2628DE
+:1087E000BFB7DB40E715173F7C7D7A183F5335F75D
+:1087F00060FA7971D090700E6EE9CEC4724328B1E0
+:10880000DC9474EE7DE59BDB5FEA8BAB37BB539D5D
+:10881000B4FE1EE6C53C6AA6FF46BA7F1079299FC2
+:108820007F591D7CA96F04E5A1A5BB797E8D11ED53
+:108830009A79480F837C77309BDB352653F309CC3C
+:108840006737FDC244E7E3DFC8F6BBDDE85FD64526
+:108850000FE27A9A8A4E8D473D5855F40F8A8B9DC8
+:10886000FD1EF3227ECE5A2AC9BE39BBC5E2C1FD28
+:108870005967A18DE8A0F35925A870FB7DC6C40AED
+:108880008C83D21C58D3E6ABDFE3872F98999FA740
+:1088900087DD8B1BE58C46FBA977665AED6BE0BB49
+:1088A000BACD5CDFD6B3FE349403DF748BF5D33FCF
+:1088B0006634C33F8BDBB4D12D00EF529F95CEDDE4
+:1088C000A89FAA74DE7C1D761967FF97BBB93C6828
+:1088D00030478C9538FE3F56D4A06B4CFAB94C0605
+:1088E000BF86E7BB0C7BCAC279F06AD1CAE7689F32
+:1088F00033104FDEC7E5D6A23BF7D37B65560DCDCF
+:10890000F71D982FE2E5B92D269AEF3B0536DA6779
+:10891000BED3CDF7BF8BECC6A099EC8D4F32F15C86
+:10892000EC3BDD063A8F7E2E3EAEA2F3A9EF76BD7C
+:10893000407EB877191F37B05B4FF6CABBF6684563
+:1089400018F1E8694E437BB76EF3623ADFBAA85B71
+:10895000EF4379B6A8FBDBBFBA14FD47B36E2EC751
+:10896000295DE158E1F2D862F5D24E5533263D82B9
+:108970007C78C5A753FBAF407BA91BF8A498E7CF31
+:10898000A39DDED77D15D9A58B665A1D382F4FD7ED
+:10899000C3D3507FBC3B3397CEE32E7A5C6178051E
+:1089A000C322C74A17BE5FA4A8BEC1E8E9E36C3D75
+:1089B000E1B5B2C8E60DE377BFD5139D005FDD805A
+:1089C000FAB3A1DB40766FDFACD77F779333C6571E
+:1089D000CAACCDD74DC6F63F3150FB017BA7EB5A51
+:1089E000492F2C5C81FB2A8EB7643E3315AD1A8962
+:1089F0007025F3DBA235CD2379FCEA8BF11DEBE288
+:108A0000E773EF70F3FB23BE00DF7DFF8BF01DCB20
+:108A1000CF48D84F9D2BDF02D44EFAFFCD5EA63D46
+:108A20006CA378AFA680FCFD0906AC27E2939F3BC0
+:108A300052FFBA7CE7AB809F316E7F07F26F11D394
+:108A4000CA506F7AA2F62A3C536413F61CEB32C963
+:108A50007D00D9F79BB2D8231BE2FC0F0FBAF93E79
+:108A600009E4C016ECE7F41FFE7110D7A9B1F0D4E9
+:108A700078F4FB367DF2278A17DA7A79BCD9E68D4D
+:108A8000523CDDE0F4111D4AF9DEE4E5FA27795E97
+:108A900027DD061EE77546A99F17723C54EE14F1B8
+:108AA00095AD2BADE44FDDEA0C5AB87F21C0503FA5
+:108AB000CD98A4E77132616F5D2BFC91E6F2E71867
+:108AC000C6C7D8149EDFF56AF9736A26947F35E924
+:108AD0004A2F9DCB2B7FB07D18CE7B8A41D40FA728
+:108AE0007B33FE8F5649F5CBDD7A0FF2F78C729E01
+:108AF000DFC8EAD2C86FF26AF9DBCEDBE2E0F73119
+:108B0000B3C70674330B98353E9FEEBA29168F2DE6
+:108B10008E7E3EEA506AB8DDEB499F3D8EFB4548AC
+:108B20001F9727E263B9DB48E36ECAAEEC43BAB9DC
+:108B3000E2AB7C3D4E3E6E0AA21C3C29CEB924E33A
+:108B4000EF376EE1A7534727C4ED9DC65021EAC910
+:108B5000F795C4EF96B4EB296EBEB85D614118EF8E
+:108B6000E4AEA70B519EBFF7F0D385F3E2E049FED8
+:108B70004E3EFFE816F42AFC82C97EDEA1FCBBB2A1
+:108B8000DD99CDCC6F1E1E6B7FA6EE6FE4DF9DD707
+:108B90002BFCC39A56E2C4FD90689FDC9F3997D3A3
+:108BA00087B24721BF87F46F1E3BF420465206D69A
+:108BB000CFD25BAC8BCF4B94CFC962DDAEC7758390
+:108BC000A958DA7979A8F51A8A1F77083D24D7EDD4
+:108BD00058FBF074C4A3B1D1A6327EDEAC14EDF51F
+:108BE0006E66F5223FFD45E4A73AADF0043BCD9813
+:108BF000EBB6A13C93E7FBEFB0A6EDC0E75F44FE08
+:108C0000AAD30A4FE8A720B794FAFB8BCE47FBBA4A
+:108C10003BF41D740E3145F049360B2B0A8636960F
+:108C20003EA550FE567B22BE5DAD5C8F446B8DA48D
+:108C3000BF24DE2F9B773BED5F0759AFCD4847B987
+:108C400093F8BBEA9C62E1EF88501CC13289D9716C
+:108C50007FDF7A6980E090EBD5C49B33A55721FB79
+:108C600019F3585232285E1A104F66CB6003F18315
+:108C700014B1DF6549F1826CB0BBB19D8413CA9415
+:108C80000F73AF23D43192C75BC92EC57EF1FDBCF3
+:108C9000B12AF9DBB19D71C2F9E96F804E457EE1E1
+:108CA0000CF9BECE3A687C62069EF3C17500FD8861
+:108CB0007621F31A12CEF974813D8DFB3419FFD55C
+:108CC000EB42656EDA9FF447D07F62AC307B50DFB9
+:108CD000A6E843A5B87EC9F1606857CCF310F21D31
+:108CE000A867E4399EC695537D18A702FB2360C68A
+:108CF000F59BC9D7AFF1CE4A7AAFCC2A6D41FA6A5B
+:108D00005AC5E8BE81A9BD3D94EFD454C3EDB1A6C8
+:108D10003D478D0CE8779EF0E730E17F7689753D21
+:108D200026ECEF58BC2BB20DF3B73B17E7D3B9DDF8
+:108D3000E4BC922F1AEF3C930A08B9382E8E956E38
+:108D4000E67A46ACBFE46F19D74A1DEB2B464BFCC5
+:108D5000C507DE7BD99AF545F2469EBDE773F3461B
+:108D6000D8F4EBB0DE8C56BEA84730408F0E9CCBBB
+:108D7000B37828EE35508FF72998F72822EFE4ECE6
+:108D8000B5579650DEA8E8AF6F23E67FDF6B610929
+:108D9000E3C5C3A726F56F80FE6D1ED9FEF83557D3
+:108DA000AA14FF15F04FDD88E7FAEE3524F64724C4
+:108DB00028CF119A63E3F9BA7E70CFC6FC983E07BC
+:108DC000FDBE3167624CAFAF7B7D46C7C51EE4AFC9
+:108DD0008F290F57EAE72627CF234996630FE470C0
+:108DE000790E76F13454B9EBE62CA3FB0706E2BF0B
+:108DF000BDB51ADAC332FEDBB4CA47F9B8600FFC5E
+:108E00002887EC8153EFEC6768779EA47D41D327D8
+:108E10002AF713815D81F7C9987B2BC91F8A69A640
+:108E200023E2D67F89D05368C3233F3475DDF8B081
+:108E30001EEA3FCED11EA27E0D83DF27B52F87DB32
+:108E4000F14DA5555B501EB08714BACF6943E94771
+:108E50006477343E73E5C4F87CF2C57BEEE7F9C86D
+:108E60003B0D83CE7F5F0E8F0B373EF324F93B4FD4
+:108E700006F931983A35B81EEDD0BA3A1D5A5EACB3
+:108E80003C587B13D90373601E30AF0773387E9A4A
+:108E9000765E1FC0FCF626F84F81575B7D0B695F3D
+:108EA000B0758ED986719CA6D279CB88FEED560D11
+:108EB000E79F0C672CCE6CA573C81BF6186AD08E82
+:108EC000AA00BBE9E7006F41C6F41A2FC8A53C7D94
+:108ED0004FD9B76C18771F5C2FDF92C7ED8036C56E
+:108EE00017F85A39F939597C1E4FD11E6E9FBD961D
+:108EF000C3ED43F9FEB51C6E374E09F44F459A7B1E
+:108F0000568DA4A09DDCC4B40F71FFCB7C360FF945
+:108F100077198FB33B577BC8BF6B7646EEBE98EC94
+:108F20002895E2CC727F71FA19EE17BB22D77F1415
+:108F3000D7B1421FF9E1D7106F77ABC24FCCE54CE8
+:108F4000E1F5B609E8C7B238233FACF150FE0DF9A0
+:108F500025D22F6FA37578D6C9EC889FA9815A5561
+:108F600089D333526E4C1D3887E324FF6915176B84
+:108F70006C04ACD63B6622D1B6CF326376C2A17FF9
+:108F8000CC56F1A5B41F74663FED73AAE7C0BE11BD
+:108F9000E9726DF4A00EFDF5CE7EB21F1B420A8D64
+:108FA000D350FA33CA8F5B2AF2B006F2A1D408E597
+:108FB00087FD3D2745E8C7364E0FAC9FF6C5EC311F
+:108FC0008E7FD09B943716B3E35BF8BD67A23FA3B7
+:108FD000883334083F0E208AEA8DB9C2AE137E8DE5
+:108FE000589E1B1F97A99E8A78BFC3A699A04908BF
+:108FF0002E4F1AC2DB6EF5A5E7025CC7EA7484A2A5
+:1090000063ED2974BFD426A55F437F64A08CE7C5B8
+:1090100026D351891837FD40741AEA93E83343E5A3
+:10902000C5F23CD82D132FA27CF2F23D1F4E43FA1D
+:1090300060358CF8B171CF85E5C58E16EBF1A5E7EB
+:10904000C57A156D073C2FC97524E6C57A39DE65EA
+:109050007C32391FF6744E58E5796B916D0FE3FE43
+:109060007B8F89F23D66EC79E108FA276798598889
+:10907000E2B54976C061E7F55310DF673E7867DBFC
+:109080005D0CF3A29FF2F27392897A7D28BB9E62F7
+:109090001671FBBFEBE4FA7F4976BD94BB4D629F2E
+:1090A000F4BE12FDC1489CDF3EBD7DB0732DB7E418
+:1090B000CA38D710F91CBD83E773C8735F3591E2D6
+:1090C00084F8D382017AFE62F1AC3AD48113CF8D59
+:1090D00067A9223F4B55B808600E9EBF23E3596A2B
+:1090E000CF688A539962F1AC301B249EA58AF8D0D0
+:1090F0003A83564BFE967D260FDF0FFB480EB5F5E3
+:109100006479514E352D39F9041ECD571DD3DCA895
+:10911000FFDB04FEEB2F3C9ED5923BF1DC78D6764C
+:10912000617FBD5DAA0B1B01AFDB1997A3815E199F
+:10913000D7D2D1FE347A4F01C1ADCC3213DC6F3FB0
+:109140006BDA817EA6F9325EF52CF793CD1771A903
+:10915000B7678D243FD250789EDF9EE8F7FF21E26B
+:10916000398BFC78E46FBFFD3F66929F7D21FAE961
+:1091700087C7CE2F30E1AFF3B4F3F3ED9E9D0ADD48
+:109180002F8A64A223DBD24EF78C2E0571B81545C9
+:109190006800A8E62BF05AD12968D778DAA00CC667
+:1091A000BBBA5E0DB8A1DDF62329E41F5CE7F488A5
+:1091B000FC331E3F0E6C54822378BF74AF58A04D11
+:1091C000A7613F3FCFE57EA59773B95FC293741F38
+:1091D000419B41C481C5782D0CD61D9E3A853FD751
+:1091E000897BEB92F121FB6B33349BD14F172DE040
+:1091F000F7939C356A73C87F9C3192EE216A4B6D60
+:109200006EAFE1F5C4B3672D511FD55FAE72C39247
+:10921000793210DE5DB922EF2E09CF0B3A12CBC99D
+:10922000F19BE47353F3997F54CEF073CF15ED4265
+:10923000B909FD9FDD502CD6C54BF1903683E7D799
+:10924000C51407E5F70CB5E473BCE90AF87398A3F5
+:109250009AEE8B037EE1F618E3F00FBBDCA920BF8A
+:10926000B43938DDFEBB7027C3FB9BDC91445F6DD6
+:109270000ECEAF6DEB9520C71787FB42FD1D1F4A31
+:10928000B9F425C9C5B715EF23E162FA8EE443E0CE
+:109290001E03F1DD5E0B3F0F29E51525E8E03E5288
+:1092A000EC5BFF2EF4D6FC136BE9BEA0AD75C3D208
+:1092B00030EE39F57A1BCDA3F1597EDEB66155A4A7
+:1092C00010E9BAB12A32B27910BCE200AA94AFD048
+:1092D0006E9E93F17B67DA13E378C9F1D9B5999A59
+:1092E00005E33FF7EBDEEE7901D7BBC7427AB271F7
+:1092F00055F411F403DC9CE9B7E7017D9CBAF3F562
+:10930000698A873E23BBFCCCBE51744E705E5BE223
+:10931000B92BB631313EC8DA33F8F9B2CEC4F7789A
+:10932000BE28E1BB73E285DC4ED964F48F463BF284
+:109330008AAFF27C880F16EB18AEEB0716BEFE81E3
+:109340007B5285BCF68E8CD707E3F2865A5F68376E
+:1093500016E3F23C0F54B66FC0F58575AD17EBFB05
+:10936000C1935F1989EB7BAAE72B23717D37193AEB
+:1093700034E48F7FBAFC6588AFE357FAC8CE93799F
+:10938000AF174A775ADEFFAE3EBE56E2E50BEA6300
+:10939000FC8BF77F3CFB0F7DC042FA859F338DF934
+:1093A000E14ED27D5B673ED129288F87EAEFBF85EA
+:1093B000DFC96D6601F477545445E8BB8ABFE918EC
+:1093C000DA75D29E4D86DF2FE05F96A7BD9C83F3B2
+:1093D000107EDB3AD1B739F831B79B1F52C82F6BDB
+:1093E000F604D226D33E69C1257A922F3FA7730F88
+:1093F000AC57B1E37E63F1432D547F7ACF7CAAD77B
+:1094000099C361DC5735403D96D74D49CC6336EE64
+:10941000E6711DB98F05385E4038529C5123D267E2
+:1094200023DAC90062A3CAFDD78D4EE60D30B46BB6
+:1094300013F77D323EBBD5C7EF73D9DAABD0BD4E43
+:109440002EA3BF381FD735294EFBFD3CAD3B2F2E39
+:109450005E3ED7A505B0EC34B242C4D3BA3C8ECF41
+:1094600088419EBF4A3C0F7868FF0D640FFD99F953
+:10947000D207CF2B0B26C4D1178A739B0BC5B94DCE
+:1094800094D3E124391D5FAE8FCB2B0B0F961F10A9
+:10949000975716FF5D7C5E5938419E7588730CCBDB
+:1094A000297EDD0474BE72428C0EEB99F8DB1C7DC4
+:1094B0009BCEB1EC34917FAC5EE49536D51DA37D97
+:1094C00047139E8BE1FCA8F173D1DC1EAA87FD1C1B
+:1094D000E5D78612F34F770F2937FEDFF8C17F29D2
+:1094E000E581E047392F398FFA5E85F34F129CC929
+:1094F000FBD8647FB6DC875EB0FFFF7F592E4592B4
+:10950000F0F0AFCAA573E20225D134EF97101778B7
+:10951000CFD3E142D7A0CC036EDFC7F380A7E96DBC
+:109520001A8F43EA799E42723CD6338DE28D32FE29
+:109530006B7E4A1F5C534CEDBD98BFD5B02F95F2A2
+:1095400006EA3C75647727C72197B09E69B8147FF7
+:1095500066AFD039AC7F3BFE9F2FEE09F6B0E22F0D
+:109560001AFFCFE7FBAE0B8A433E67FB38D31F479A
+:109570002F5563C1801F3B747E56413E5FFF14919F
+:1095800027625603CC11F7FD50DF8DC8E7795FCF16
+:1095900089BCA27B5353E81CBEDBC8CF1DB8753C09
+:1095A000FFE9E31CDF2884DFECE1EBF9E3676E649D
+:1095B000788EECC786109D8B0F34D8BCA8C7A4FF4B
+:1095C00048F6DF9EC3E1BA503E9A92FFE5F2D1F928
+:1095D000E4C7B47CE58BC5D136030EE2F82B991FA6
+:1095E00086FA6E28F97263BE6F16A70B6D3CC51F15
+:1095F0002E502EA59483DC463DBDDBE4C1FD03FA6D
+:1096000051483F6ECC91FB6F7E4FC0BD05A4BF3E5D
+:10961000B0F0FD843CC73380BF21F1FDAFD979BFE5
+:1096200073F9EAF3D1BEABD4E81CC0BA54AE5FA262
+:10963000BB781E50F2799664BD22CF63C8F1BEFF9D
+:1096400025D3C31795AB77CBF1FF4DB90A7A96F6C0
+:109650002F43C65BCFF93E20F231FB3591F742E74D
+:109660001A245C4DFD3C7FEE47827EE5FBEF09FD51
+:109670001BC9D7BA90AE4EFDC16CC67866793997D2
+:109680009F8D3E1BC5031A433C4FA67115A37DBF9A
+:109690003CB73AC6ED7F04D76FDDEB36BA87B471BD
+:1096A000CFF6F6619447E027FBEEF41FF8FB37B2E4
+:1096B000FD8F62BBA6559184B843C5671FAFAD2926
+:1096C000277869DFEE34259E077A259FEFC7E5F3FB
+:1096D000C501FCC2FE04BE3B55C7F3B59B9C9ABDB9
+:1096E00092F207B85F3BC5D34F7EA0C6DDA4241815
+:1096F000258F62FD77F3896E1A775796D17D002109
+:109700004B19DD27F306BF7FE9D49DB9413DF783AF
+:10971000EF477853CB8357A39D5904E3A0497AAA16
+:10972000E7EA32F20F26F19DE4B78173A0B7988380
+:10973000AD4A8C1F3719B89E94FAAD27DFC3FDCE12
+:109740004E9107D83B932DB0C5CA3667627EE4B20E
+:10975000BC2B7B707D7AF25511BFE6F1F26233ECDF
+:109760003E879D4B87C5225E3E53E439B0803996D3
+:10977000DF30ECFCF172099F2CCB7879CA27E2BE6E
+:109780007FBB91E822B59DCB0D06748176F6946877
+:10979000FF543C7F55D2199E82F84A47F453BE6964
+:1097A000E4EE8B310E91A94EC138C4B695130E600C
+:1097B0007C545DDF7F392E8DA7C35E855BCC316E17
+:1097C000DFE97CB2079B4B91FEAB7E6BE07989EBC6
+:1097D0005348DF7716D6535EE2E9D74D09E76D921D
+:1097E0009F01B6C68D7EA361EDBFA13840EA6E65CC
+:1097F000D07CD371053691B7B8C68D7EA8D4F6FE5D
+:10980000C024F4ABDCA3F0BB1C017AC58DFB7F55F3
+:109810008776C7FC3DFCFCF6FC0E479599E4A9C28F
+:10982000E328539C2427D5F5D7E8709FA6B630BA15
+:1098300037ADA480DF9B3AA2D3AEC375FFE5A7FA8C
+:1098400041E3639905B13C37445783297AD05D1CC5
+:109850008BEBC9FCB6A1EE2397FA28D99E3DC78EA3
+:1098600015FA68C09E4FA2E3A1BE93F42DE9F997C3
+:10987000064676D82F15339DEB9274DD26F3F53F1F
+:10988000E57EDD229137736CC3DFC7F373EB322EB5
+:1098900012E4F7711A226BF3085F91AF0670DEBB1A
+:1098A0001DBAC6B1E40F6BA47ED6F3FBCE8ADA876D
+:1098B000AF99548E4F3B530084637B9716215F060C
+:1098C000800E460C42071FE5F37327EAFA145A3755
+:1098D000F53EBAE999A90E17AD9B7A3F5F9F53F900
+:1098E0007C3E322E2BFD96917C7F55C1C4B87358B7
+:1098F0002BADFC1C9638E79BBAF2F5C7F17CD3364A
+:10990000E13F3EF0EC18FA9D86B3EB5505EDD4B37C
+:109910008E5AFA5DA26B0BB8BD94AAF633BB2D9E8E
+:109920003E0F507EECB07D3CCF4F15E798D5F5CE7D
+:10993000ED88CFAF3AFD94077C795B987ECAE059F9
+:10994000FB718AB7815D44E7554F3EA348BB284170
+:109950001FCA7D5BF27EACB6E07FD64EAA2F48F4DC
+:109960007B5CF03E8B25EE3707DACBFD63F27E227F
+:10997000E9FBA1EC1FA60512F25D568B3C68A9DF3E
+:1099800073856C94793003E79659D082E71EF29183
+:109990002927C6F28198C813DAAC58BD682F0D95F7
+:1099A0000F3490AFC39A2FE6FEC8E6AFE053E6133C
+:1099B000C97C210BE68D649E9B3762C1BC914CFC37
+:1099C0003D0B7EFE59E67DB41A3C944712F81EA367
+:1099D00078A032AB86FC75193E23D1DF1916DC82E4
+:1099E000F7B90766DBE89C379E0B42BA8F2A6EEA0E
+:1099F000776A8D26DBEBB0FDC0BD80B58CEA334ABB
+:109A0000B41CB4C32C508FF7150F9C7B5EC0EF4F76
+:109A10004FCE1B91F94B329E9B3BEA2905FDA2E8F4
+:109A2000F6A73C826F89EF8A793F9DDFF490DC7066
+:109A3000B5F2FCA4E8A5CC8E7EF92A297FCC89EB6F
+:109A4000BA49F117237F6EB2F273FFDDCCDBAE872C
+:109A5000F21D05C3B85F8779F6EB486077D0EF2F2A
+:109A6000743AB5A70AB262F424E1629BF9BCCFE074
+:109A7000392F2536DE99C57F2B44FBAAAAD7C4E926
+:109A80003269FCAD03F7AE042DA84F5E2E6044672B
+:109A9000DE247B573E5F96FC26E4B21C7FA8F94982
+:109AA000FA3C9F1D2FE96F287A0B5489757A2B8514
+:109AB000EC0F496F0756EFA47B01FB5687E879C688
+:109AC000A284F4783ED6129D8B92B17FDB9FAEC309
+:109AD0007B39CEA4460BF15E8F377FFCD7AFE1BD5B
+:109AE0001D67B2A26F61F954E1381FD58F886EC32C
+:109AF0007B3E743FEEE1F5B89EB960BF173CF2B50E
+:109B0000808DEEC95ADB8F7AAB3C291F25E93E8256
+:109B100014F17B3ED93623D993D922AEC7AA855DED
+:109B2000CFF8EFA2B5E694511CCFC63CBBFBB13ECB
+:109B3000DFC4EF2D6040FF583FA298E735303E6FFD
+:109B4000962FFCD32C12A0DFE72B76D0F703727C84
+:109B5000B749C4A7F8F8879FE47144999FCB98BD93
+:109B600000ED219B872594E57D1E4CB517E0F9FD9E
+:109B700056E9F713E52753FCC6C238BD7CF8CA3B4B
+:109B8000C6D2EF843CF5DD12949B571913EF59961A
+:109B9000CFE78B389D9C11F70936A5F8D30B61DD13
+:109BA0008FA4CC9D8657C3CEC9AC343AC87EDBA502
+:109BB00047399525E8C3319BC3E7A8F629F8FB1C74
+:109BC000F23EBF2CBF4A7E02E6EFD4A35ECD3AEE52
+:109BD000A3BCBF7A73B4107F47E505B33F0FE13CE8
+:109BE0005B7BF4768A17E61E7E0BF3340E1B3AA6D7
+:109BF000A6A11E2916F742604016CA07F38A683FDD
+:109C000038201F462814CF9C319B9F5F9DCE422A4F
+:109C1000AEF3343B3F4F35ADBCD8DB0AE3CD107912
+:109C20001ED38EF8D250BE4DBB31A2F27B2BA26A5E
+:109C30007C5E857C32B7C113CF0F577BE2CA0CEF35
+:109C40001D4E2C5FEB4D2C7F6DD2A7A3E2CBE3140E
+:109C5000AD02E7F90B45DCFF00F285CF8BE70F3E45
+:109C60002AF67363DCCC5C84F98D4E2580FB85314C
+:109C70004FE7529CE5E9498CCAAE9DE61DE6F8F92E
+:109C8000DFA7E37168E10797BF338475A86F9FFA78
+:109C9000838BF0E5B281BC7592F4217A3B20F8F613
+:109CA00080E0D38A3CB315E5FF0183A78BE83CD560
+:109CB000EC413FD5FE5423DDE3DABA8CFF4E8192AE
+:109CC000666646E8573F8F97A11DD80650AE3053C1
+:109CD0005EC801916FDDFA3D95FC5C588FF7EBEAA9
+:109CE0007F6025FF76755AE937B05E9F66A4F30E54
+:109CF000FB532BFC623CBA5FFEA15473187FEF202C
+:109D0000F93ECDC30817E20DE07A98C341FCA8AF35
+:109D100030921D2ECF9F433F147FD3E79A69BC0337
+:109D20000EFB7EA4BBD6F7C8D283FA491ECCE392C1
+:109D3000F45D9D36897E3F04B8AF24FEBE74BDCB72
+:109D4000EBE1E766F9EF62940EFC4E060C0BEDF0CA
+:109D5000378518F12D8FE71548BC3355C3F6394CBC
+:109D600096F9B931D740B952A5FB7F14596EA1F2CB
+:109D700003A25EDEFF79A890CB29A5F785BF22DD7F
+:109D800096A4015E609DBC29839F5B7AA090F3ED51
+:109D9000B9EB57E146BFBF82F31C1B9BFF0187D77E
+:109DA000ED8B2B0FB22E41A4B7E4753960F17AD058
+:109DB000CF76FEFE385EE53CF4B91C9F03F3C81C69
+:109DC0007C1E87C43C42E29C7572FDEE426EBF7EF3
+:109DD00089F31C94FEFEE579BA12E7F925C2195100
+:109DE000BE0438F585009F2D061FFD0C5805CA4D91
+:109DF0004E7FD3459E322B4DCC4B6293BC666E2F6B
+:109E000026E6215DA574B5A17E7D40C4B95F107CB6
+:109E10007530E5FB25686FBD3077641FC9DBF496AC
+:109E200036642E299FA5FC3F9B73B402CBA007DEAE
+:109E3000443D73FBB0C373B1F33EC70325A8AF40E5
+:109E40006EFEB170E2B9704AFE1D8017F817F9482E
+:109E5000F26F32FC928FD875214ACCEC66617ABAE7
+:109E600019CF8307BB84EE2B679E82D8FC80C9A7DD
+:109E7000999BF93C5A0204F7558E1F52FEDF598F09
+:109E8000FF23846BCEC51FD27D48CC5D3B0AF5080D
+:109E9000C0FBF1FF26BC209F72F0BDB4F393EDFA36
+:109EA000F3E5834B3893E5A1844799B593ECF82605
+:109EB000B0E379BEB842F2BEA94EC7E5F01E85EC0C
+:109EC000FA46D033A8A7E4FDBA578CB4B6E1BD8FEB
+:109ED0007B0DDC9F1A78D2E449BC2729396F5CECF2
+:109EE000275631B95FE0F74134D8F93D4842CF7485
+:109EF0007E7B98BC2789EB43D05309F724D57A128F
+:109F0000EF491A62BF00FB02B2CF58BA4EEC0BB851
+:109F10009EEEBCD4630F30F23FF3DF7BBCC928EC6C
+:109F200041C0852B768F1BEC03E87EBAAF14158BEE
+:109F30007BB282FCF73584FD9FEC8FFEA7CB3FB947
+:109F400008E87DC158AD107FEA65BE91FB9B81DEBC
+:109F5000BAFA19A63F363F84F7955ECD9A5FD30DC6
+:109F6000277AD3B0FD9C311FF27B4C63F456599491
+:109F7000C5F5122A99F3F1F161A77F7AD144C45F44
+:109F8000E80DBCCF7C6BAF89F02DF34B93F93B0E02
+:109F90009EE3060E8F53AF2778660D06CF85D07DE2
+:109FA0003C5D65334EDF43D13F9EE3489D10A3FFE8
+:109FB000718ABF16C71DE083B57CDF750EDC7A1B86
+:109FC000ADF70D37F1B85C538ADC276B33725CE870
+:109FD00087E4E3DFB09ED3C50DB53C8F68666F03A1
+:109FE000C5E158358FAB79E17F08CF0121DF663BB2
+:109FF000CB0C487A7F66DF30A09F73F68CC4F8DB09
+:10A000001CF35514EFBB61B621E1F72A251EE68843
+:10A01000DFC39E93F43B95C978498EDB0DC80331AD
+:10A02000DF3CFCFD1678E6337E7E2647FCAE585BAF
+:10A03000D1C0F9DE515F30BE7777D11788EFF519BF
+:10A04000A2744FC3F3598BBA9601DF8CFAD158BA78
+:10A050007FFD4AD7E287EE83F24FB65E44E5E75DC7
+:10A06000B7AC388CF5DB4652B95AF7E15CE483D2E1
+:10A070008A9BA6E37DF57D16DE8FDBEAEFC4DF3138
+:10A08000718F1F3601F380AB8D516A77CDC50D9767
+:10A09000603E54B595975F29FBFD042A0F13E5092F
+:10A0A000BFB808CB7DCA8773078B0F8E2955C2F8BE
+:10A0B0007B65D519BCFD8C09BB72D15F545DC5CBE6
+:10A0C00063BC95EB8763BDEEA3B983D923CF140995
+:10A0D000BF91B0AF7D82DF9FD68EB6E179409F4DB4
+:10A0E000F1E2B90FDFA4A3FC7E3433CF2BF1696515
+:10A0F0002ADE9F59A5713FEF545B4B0ECAC5EBFC9E
+:10A10000C672F4E7DB6DC56D6817A74FAA9C88EB94
+:10A110003DD5CC889E80AFF6E13ACCF9CA878569F7
+:10A1200048CCB644BE92743B53F2537522DF803C58
+:10A13000788ECB83447E807E0F11BF5E96A8AF06DB
+:10A14000E47D12DF26D3E39076014B9483313A0D00
+:10A1500029F1F4D98DFCCAF9F70F088751D7EFC15F
+:10A16000F7458AF7224AB419C2BE90F0A1DB924D9E
+:10A1700038172EFC53A53DCE21B0DB5D382EAF87BE
+:10A18000EF34FC713909178CFF1EE1672D87A75B3F
+:10A190006916BF57C2F761D2DFD128E7BB2771BE6E
+:10A1A00015567E7F811BFD3D14C329BBE8F3E06E8D
+:10A1B00012FA77B6D9778F09E6F075C77C5AE71B94
+:10A1C00041033A60FEBB52FC7F4778F4BAC0BE88B8
+:10A1D00082BF37A2513E0CACE33FF83AF275917062
+:10A1E00025E3E3FF02863CEC3E0080000000000017
+:10A1F0001F8B080000000000000BE57D097C54D592
+:10A20000D5F87DF3664B324926098484409824644E
+:10A21000830426611164712004A3020E8B028AF864
+:10A22000C21AB20B5D624B9B81B0A9684345A5166B
+:10A23000754040B0408302A2463A2C2A56ADA94B45
+:10A24000EBD2F22548658718AAE2576BFFE79C7BA3
+:10A250006F66DE4B52A45FBFDFAFDFEF0FB597FB3A
+:10A26000EE7ECEB9E79EEDDEA9B43B02EA00C698C9
+:10A2700087F5ED16CF9802FF642EF8EF80E57C732A
+:10A2800016A33FFF4865ACB7096AC44279E3EB5FA8
+:10A290002B587F5583C2D218EBC59A12314D64D525
+:10A2A000944F60EE35AA8AAD7AC57CD69F31FCE723
+:10A2B0003F6E60AC2E12FED18DB1D63C9B7F330E2B
+:10A2C0006286FF0633F6567186FF7EC85FB238D6C7
+:10A2D00028D19057589619EAF99470F7D614C6BE4B
+:10A2E0000A8B1AC0E07BB7704807323662CE0F2661
+:10A2F000B1A88EF3ADB1F37A3F0C8FDA8CE90D196A
+:10A30000E12B4CD1D83ED98FF5BB85433A2038FF9D
+:10A31000AF4C4CB3C37C7FA8C23A545C47EB32339A
+:10A320008CF704ABA7FC68172C7A08633DDAD7E3F7
+:10A3300053BCB98C594DCADD5E07AC09FFDC104C2B
+:10A3400047BB4C8C752770290CE65529E1E85298DB
+:10A350001DF27344BE52C0BB9BD5D50BFB31C279F5
+:10A360008EDDD642F05D53E869B607BFB3FAC73C4D
+:10A37000A1FD74554F01B826C576843FCC9FE637C2
+:10A38000B1A6C07B320EC717F8B83792F031F1DEB4
+:10A3900031F45D9992A534C3BC0A8A5C94C60EFE62
+:10A3A000BD99E5125E6634E404F174B2BB76B30B7A
+:10A3B000D76B6E1E321970FBF69067F234283F6E31
+:10A3C000622558CF089FDB113E433AC247C2C308FB
+:10A3D00087AEE6BF2FC23BC305FD5C509A8662A1E3
+:10A3E000BDA753C05D4B41FCC43853C6C420DCBF7D
+:10A3F00081718732360D8B00CF0FC66B1AB69BCE9C
+:10A40000BC8566586F6C9166D11C349C09E7B3D843
+:10A41000C9E753A83A882EDB762A7E1BD41BE7C9EE
+:10A420007E6C24E4AB8E59981FCADB18A7DBB68D6F
+:10A43000AADF07F4B2F08DE78706E0D3A7824E3398
+:10A440003798984BE203FECBF68733575630DF7FC1
+:10A450007BAC2E9FDBD053577FE081545D795EA0AB
+:10A460009FAE7CD0B17C5D7E48D3F5BAFAD77D38FB
+:10A4700056971FDE7CB3AEFE88D35374F951AD7787
+:10A48000E8EAD785C1FE1988E0F63465015CE60983
+:10A490003CDD70658EAEDDB9A8F1C7705FCD5BBBEA
+:10A4A0007002EEAB31AC4CD70FABB79C40BAAC8668
+:10A4B000BF88CF05CC1B1D007815B2D6D792007E81
+:10A4C000957EC58D705BB881D793ED161DB8676C0E
+:10A4D0000CA67EFDF732660EE6A19F9A3F6DFAED5F
+:10A4E000D190F271CE6213D2DF465764B7CF2210FB
+:10A4F00010ECBA7FA89DE2D71D40FCBDAFBA6DF04D
+:10A5000069F11B2AED83C5BB143F837E33587A342F
+:10A51000E6AB8EA9CC0FF83FC5AA1F1D09E957B5B8
+:10A52000FEDF1E4D0FC2C796A0C773984B8FE788FA
+:10A530002C3D9E23DD7A3C470FD3E339C6A3C77376
+:10A540005C911ECFDDBD7A3CF798A1C773A2A6C768
+:10A550007352891ECFBDABF578EE53A3C7678AAFA0
+:10A56000548F3F03FE25FF4D5BB35857AF9D0EBC84
+:10A570002513304DAFFF91AEDF32B5DC0A1868A766
+:10A58000071FFC457AC864CC1D003857021E02AE76
+:10A590008E7450D2B86E55D2BF40077F42FCF70F81
+:10A5A000C1BF3A2B5AEB845FCB54E23557F19C4044
+:10A5B0007EF6A54BFB0BA633323F4F3603DF60DE42
+:10A5C000E24C6F6490EF3116606C68907FF5C6B511
+:10A5D000E5333A8FCC4383E751577CADC3393A49D1
+:10A5E0009E3F5D9CA3AEDE413E0800F988F95E699E
+:10A5F000A641D69A701E33055D1F0EE77479198B3C
+:10A6000086433DA8330CE6F511CE1BC6F928BCFFE6
+:10A6100051DCA777B0060BF63F8B35513A9BB5520C
+:10A62000AA31A715D339CC4DE93CE6A5F475BB6634
+:10A630004B017894DB9B873298FF97C5BF3FAEE014
+:10A6400064DE8AC3C9760957C9AFDFC37F42BD91B3
+:10A6500029DEE814E0BFE3ECAEEF3D029F0EE339E4
+:10A6600081FC77421CCD9799BDB953723BEB67399A
+:10A670009D1B2F2B9A867CD79768776F85B5F54FF2
+:10A6800062F6443CE712FCA953003FC929FAF3B72C
+:10A690009FA0895D3D1B16C7201E993F16CF876B73
+:10A6A0001DB75F8A271DD72FEB5F6DBD566BC33D6E
+:10A6B00038CFD60A877B33D0E7FB021F4FDF6E0B04
+:10A6C000A851413AFA3062F66BDD016F5511DA207C
+:10A6D000EC7FC6F49B56615E391CE75A0CF3BB5401
+:10A6E0000CF0E6F0BF8EC35FEB130F4BBCD05BCB1F
+:10A6F0008C46F87B39FCE11FB9DE4EE7CFE753A06B
+:10A70000F0F1F745681EECE7B0A929D98DF0303794
+:10A710000DC576CCD19DFAB960E570E90A0E6323C8
+:10A720007ACFC275CDB3D9DC2AF43956E1783D1918
+:10A7300077F7EC2AF8E77C93373EA0EAE63D09F18B
+:10A740005DEE2CEE93087473C122E66DEF2EE0EE01
+:10A75000CAC17DD5D5BCEBB07F94037FA2F8510E62
+:10A76000A43F907FC117E3BF1FF236D3E5F7A7A23E
+:10A77000FC926B726F86A28DE1D035D0FB3B02DE7E
+:10A780004F58201F4BDFD7E0F78470DE3EE1519336
+:10A79000BF0EDA7BC7BE48787ABAD241EB29662E63
+:10A7A0002B6EB2B9CC4374FF97317F7BA519F05162
+:10A7B0009EA22D44B8DD1D674A7E9FE6A1F547792C
+:10A7C000878DFC6EF42FF7E914275FC27C01B7A9CF
+:10A7D000CC43FBEE36A65970DC772F5A3DC83FDFDD
+:10A7E00015FC643AF3D1F799CC4FE99D2C40F5EF75
+:10A7F00062CD94FF7DC480DE3530BFC98F65A6234E
+:10A800007F0D81FB4F08EE76EDEE6E9C5E4EF540BF
+:10A81000B8AFEFFE9DE877B2A017D8AF2B71DDB0CF
+:10A820005F07E7A586EC9B719C5E98D999FECFF6F1
+:10A830004D531B3F2F80313A1261FD370A14DEE879
+:10A8400029A37302E5AC6E00FF26974A7256D19891
+:10A850001633CE7FDBE79C8FBDBE8C45FAA0FCF59E
+:10A86000312A437C4DDA30FE0CB67B8B05BA0D865F
+:10A87000FA8557B4A3D1B0FE49C0DF8123B3A25EED
+:10A88000704E849C4B3727AC1B8772C4CD7DF5DF9F
+:10A890006F61F52AC26F428EFE5C9984E78AAC072D
+:10A8A000E31D4238C4763C5FB6A708F9A21FEB77D8
+:10A8B0002DE74BA5C9F36BE223406748F773CCCC77
+:10A8C000D3D97E73642A928F91DC72AB18BB6DC2B0
+:10A8D00065EB2558EFA914ED25EC67F1C4BFCC4614
+:10A8E0007E0C7AD4DB83F01CFD9DCAEE87F213B593
+:10A8F0000071385C4FD6DA9907049CCF6A9D943F6B
+:10A900005D9B40E9D95A17A5E76BB3A8FC62AD9BE4
+:10A91000F251A9DE23D8EF9C359F9B518E5A1D26FC
+:10A92000F1C7E7B144D0EFEA30AE472D895CF26160
+:10A93000318CBB840E4038AF1BEAC723584A0F3412
+:10A94000BC86297C571D58BE4E71E3F934FFA8B66A
+:10A950000AC967E15BCD9390ED0CF9E0643CC2ADB0
+:10A96000E28AC234D84A3F48F7BC8BE39FAA1D460F
+:10A97000F33A53EBA179791A5B5E8B83F6E76A8B26
+:10A98000289F99EAFD10E9DBC33EB762FB893B5B78
+:10A99000CC49505EE8513CB8BF477B98DF0FF8DBED
+:10A9A00060E1E7C506382F907EC6E44E79E27B88E9
+:10A9B000B614ED048E735BECDCC238A4AB61C566E3
+:10A9C000AC37FD1B90B95282F47DB57D72E1A04297
+:10A9D000F0B9703086E021E15421F075617FFF5BB2
+:10A9E0004740BF07418E54617E6D574C34BFB60F50
+:10A9F000C3FD282418DB2FDE97D68339709DD0D86D
+:10AA000086F9FE3D18E021C2FEF413A8979DDBF500
+:10AA1000C304C4CBB9D8862F3F46BEF767CEF7181C
+:10AA20006BF8EC71E48BBD12DCF743EEA205F43455
+:10AA3000D26BAA23F05CACB4328DE7B5FE983F1719
+:10AA4000CE487F1DBA3B692CEE271CCF9519E46BCD
+:10AA5000598A8BD500DD67EC7E2CF5C730EFED0D04
+:10AA6000F33F7E1CD20B7E93CF02E7D605D670F162
+:10AA700025E4CB5B1CEEAD0CEB9BC3B1FE03163E95
+:10AA80002FDF56D0DB5DD89F9FF800945BB1BCFCF4
+:10AA9000B95FF4C4F9BF8C7209E45F5E1741FCEE44
+:10AAA000658BFB780DB67B82F7F7CC43F79E388039
+:10AAB000E98315F9F742DA273596E03DEFE78BFA9F
+:10AAC000617B38F75922F0C75FBDA004C2006EB9A0
+:10AAD000EB0F2D4F84F1066E6C31F584346F8B5281
+:10AAE0008769FFDE45C7F0BC4D4F75D13C06ED4C84
+:10AAF00051519EECD7D3FFF10D240FE8E5849CF56E
+:10AB00009F8FEDC982F2423FA5E1EC32A087D5BD0F
+:10AB1000FF90CFF5C47AEA675FE3D4F7EE64B80E2E
+:10AB2000904470DEC556B253E0722D90BFB0376DC1
+:10AB300013DA33F69B7C9BE8FC9AC3E5950B5EDF4A
+:10AB40002F90CE2AA0BE0FF21579BEA8EBA1BCE2D1
+:10AB5000CF7DDD4051ACF7933716213C2AF73E32CA
+:10AB6000BE27D4BB3092B90115AC64DFE5F1D88EB5
+:10AB7000F586B5603F7BEBE2EF80760FE48C1D82BB
+:10AB800074E5551B681C56C5C7794C9C7BAC198075
+:10AB9000132F5809D47B003EE3F7D8C69843492CBD
+:10ABA000889FAAC66529686F19ACD9DD2AEE9B1467
+:10ABB0005F62B523788EC2F977632AD44BB48A7E5C
+:10ABC0009D5393BDD770FE59C57926FB7BCCCA7CBB
+:10ABD00061B15C6E56F07CB6F2737B2BF0979AFCF9
+:10ABE000E0B90DE34E4FE5ED495E4E82433A0FE684
+:10ABF00099F498CD4FB2C1771C5FCA5B55427F91E3
+:10AC000072CB8CB8BA579A61BD8F456873717DF36A
+:10AC1000C5B9CFCC6E17CA453F8DF0CC4B25B9AB2B
+:10AC20003519D700E76A09E62B5590C3D242E430C4
+:10AC3000FB773B577744782AB1FD77AD6FE4BB4B88
+:10AC4000BE30B13CA083258FD8484FAD13F6863A6D
+:10AC500061DFAA8B1C6A477EC18E9ACA5F83F37636
+:10AC600014EFA1BDDF2591F9C44FEA18EB146E076C
+:10AC7000810F68C07702706E68C00F465F695539F2
+:10AC8000DD371D891E8CFC9679225D680730312DD9
+:10AC9000E43C35F603787B08E1398645302DE4DC69
+:10ACA000F4B0182BEE5FE688FD97D63F52E04FAE2A
+:10ACB00063A4B0E78D6CFB3002F9E6922FF2897F36
+:10ACC00076B5BE57C4FA7E83EB83D492E9DD84F86F
+:10ACD00018F557A719D739CA3C3919E51C98FF331D
+:10ACE000F87DF45F4DFAF97F13AECB7FD7757C5FAB
+:10ACF000613E13EECFCFAD7EDC9F8D40DFB89F1B52
+:10AD000017E5F8910FEC87FD6047BD668A95E4DC96
+:10AD10004661276DECEE24FBD2CB169EF7CD14EDE9
+:10AD2000C3189D238D337B52FB9EB6EA3773B1FF68
+:10AD3000BA08E29F8D16FF9A54ECFF27716E1FE050
+:10AD40004BC5F36310E81B827FD7590277AAD8DF7F
+:10AD5000E75686E3AD8F09245541FDF58B7A52FD08
+:10AD60000F419442FBDD0893E9EEC90E2CF724C68F
+:10AD7000427EFFB72A9D1BEBF320EF203E4EF6C02C
+:10AD8000F5933D89E1DD308D37D17C54564DDF534D
+:10AD900078BB8F2DBCDE1D027F1F09FCC03E273E05
+:10ADA000A04D8A30231D5F4C9DD342FB8379121541
+:10ADB00098CFE3F3D219F2D13B4A6F4A21BAA97F67
+:10ADC0008CF8D90C8103D91F36B00F45399AFF99F9
+:10ADD000397F6B18E2F3B69230B28F7E58B23CD214
+:10ADE00005ED6FD3D4800DEDC6D30A3DA1FAF8C5A9
+:10ADF000540F8D5BD1909D763284AEE7D8806F4042
+:10AE0000FF6BC2B5D348CFEC401E951F00E1E61F93
+:10AE1000B0AF4ECC4BDF4D768D79528F0CCC45BC0C
+:10AE20001E6CB533D44FBAA2873AC403F4DB479CF7
+:10AE3000EB44AF88FF19E15CCF3103BD40BEAE21CA
+:10AE40009BF49CA72CCCA320BEF6D908FF4553EC5D
+:10AE50001EB23FCE08DF6483F2BB053FAB9B114EB1
+:10AE6000DFEB5E89F49B14D29F28EFDB63A176E5CC
+:10AE700056FF8E6DD04FF9C16C3A6FF65BC5B82F97
+:10AE800045F0F2284FCACAC158DE83E8E0658B2B33
+:10AE90009ACADF50199587073262008E91615A581D
+:10AEA000DA10A43BC0B303FBE5DF8F0BFA3A0EDDEB
+:10AEB00022FE7CD591D42F6D7DC86B75BD37233EA6
+:10AEC000352B2F673F52A9FCB8D393381FF2C7AB7D
+:10AED00093685ED2CE74DC6B25BA3F5EAE90BCF454
+:10AEE000A71A35600DB5E34FD97E5F06B4FBF4A019
+:10AEF00085EC78B37E56F6167E9FB5BC82EC91B396
+:10AF00004A97929FE0E2D24F876E80F5342FFF245C
+:10AF1000590BB14BCF2A8756A176D5344F6A1AE028
+:10AF2000E7D6342D1DD75795D3BC00E5EB8BD6A6BD
+:10AF300027515F7075D3B2F0FBA5174F6DE37277A1
+:10AF40006B069E1395664E27F2BCAD1274F85F69CE
+:10AF5000DA00EC0FE0361BCF95889C26CEFF967E5C
+:10AF600037FE7FB671EB7E05C6290B6FACA454F596
+:10AF70000FC07ECE298128258DE0A8E1BE3AEF0CD6
+:10AF80004421FC351397F3CAB6EBD7857FCCF16823
+:10AF9000376364072F6B503D61B80F98DF8AF32F3A
+:10AFA00063D660FD9420BEA01FC21773FC69F68FA4
+:10AFB000010FA53BB2F351BF288B39F0D008AA0787
+:10AFC000EDE47E513BE6E57A3ACE87AFEFBCD80799
+:10AFD000E7E18B05E965A74DEAF934FEC5177BD09B
+:10AFE000F8F1629F5C5404BDEE08E374E58675E1F8
+:10AFF0003C7FCDE9EA51C92777F07ECAE27C26E49E
+:10B000004B65B54EA22BC997602EB4BFCEED4EA2B4
+:10B0100076928F312F63547F77E2662EBF097D17BA
+:10B02000270CF54B7FC5C7C13CF2F3B3CF26C971DE
+:10B0300049DE369EC7C6752F49E3F62938A77BFC43
+:10B04000337D312B61EE13F30685AC27D22AF882CB
+:10B050003B61722EFA17ACBA7E2F465AEFF638D003
+:10B06000CFA0FF2EFBAB4DE3FA641F039E7BAAAD7E
+:10B07000876CB80F9F66746E18E7B14AB47BF6D937
+:10B0800076BCAAC29ECE5C929E5C5C9E27FC7D64D0
+:10B0900095F8FB5E12F0E33284556A108EFBF3B430
+:10B0A000243C372E0AFFD0FE18C8E7A03CC5F12289
+:10B0B000F3121F46BA5CFED18224F4473D2FE168AB
+:10B0C00080F732802B96D75940BFC9413DF7D8C38E
+:10B0D00027D383EBF9ACD6E39917925FB021CF8EDB
+:10B0E000FB71E1C63CFB9C107CD46D1F74CC0570D9
+:10B0F0003FBFDDEC46F65E67F63F84727ADD76B5DB
+:10B1000001E908CAED08EFF38EC3BFC37A0B36C658
+:10B11000E4A31C2EDB2FDC50E899178287FEDBF5B9
+:10B1200078C96DD0E7071ED0E75F4119B4FBB5B70A
+:10B13000CB0BE8F3838EE9F3AC15B03714E5018E41
+:10B14000B71786B98FB9006F7DFCAA1B3FF5714C0C
+:10B15000993A11E5888DAA3B1DCAFB2CF5DE827257
+:10B16000C5E98DF3DD88F612D557F963C069C927A3
+:10B17000E38FE1B97A8E35FC6122E06541E33AABB9
+:10B18000D985EBD6D3FB7E93A0DF67B9FD6E915FC7
+:10B190005FDE912F2C93FEC1AC50FA32D2018C7B32
+:10B1A000BB0726545EF3DEC3C8174A2600E1039DA1
+:10B1B0000D6F586745F9EFEAE3F8B87CE9F0B8108D
+:10B1C0001EC5C378D9F53505EC53D8776CEDEFC7BC
+:10B1D000E3BC8B1F5048FE287E3EF328D257CB9EFF
+:10B1E0009937537A7B11AD5FDA0917362A8148C83F
+:10B1F0003B87B90E3443BBF97E6EEF98B3C216E4B9
+:10B20000870CFD648679AC0F2987F92F3C70E86BB9
+:10B2100005FA2FD9A86FB708F8349E3FA55BFE61E9
+:10B220000BFD2EF5D1EB1B37A9B8EEF962FEF2FC4F
+:10B2300064BED1E4A7B89E376127F1FFE0DC991D19
+:10B24000AF297DBB07CFD1EBD7F3F6C0768B71DD8D
+:10B25000150EAB0BD75D6167810898CFB148ABC7BE
+:10B2600009DF2F6F88243BDD021BC8ABF994B23095
+:10B27000F47B3037F9CB3E7B4725B9A7228EE3BD5F
+:10B28000E22985F4B40A34AE62FE699E5FC402B45A
+:10B290001EA4174FE83AFDFA3CABE7FA5DB93970E6
+:10B2A00008E152CA9AB97E06F8F484F8BBCB619DD6
+:10B2B0001FC6A2FC6668CFDC1AF9F11C5C1EAB3A13
+:10B2C000F00F5B68B9D433A51E2CEDC74F6578C36A
+:10B2D000711C8B909BD7DFE7C9C0F9AEB4783210F0
+:10B2E0000EBE7561A4EFDFB1899F5FEB63408EED09
+:10B2F00046F233C9E377285C3E6733393F1C617AF5
+:10B300002E80E74DEB2331EECD2EAA4FE7D8FA077A
+:10B31000B3B9FCFFAD4AF250EB3A1E17B13E8FC3F2
+:10B320006FFD83B95CFE97E75E7746FD7594B73D88
+:10B33000196887600FF3797D8C4B0A91AFBF8DD769
+:10B340006EE81BB23E2997B392EFE6CFD82AE234DB
+:10B350005AD785F9D19F7152F1BE660A916FBD7DB2
+:10B36000F9393174AC679BA8477E8F79A6C9F7DF9E
+:10B3700000F39AF7A8C985F6B776787B3C19787EF2
+:10B380009E5C17968F7436742CB7471DCFE37C3FB5
+:10B390006230F3F8219D29FA9DD9D7A44B13C281BD
+:10B3A000FEA09F9385DC1E1E39D84B76C0AD2ECEF5
+:10B3B000F78DEB982FFA9967F5FE765427F3917085
+:10B3C00061E3B8DC71F21E65339F17E01BF2437F27
+:10B3D0001E46F6C393E25C92F005BAA1B807C9B75E
+:10B3E00062DAE9C5BF230CE8659D85D381D4DB42D1
+:10B3F000E845E0BF37E1F70E815FF66098A01713CC
+:10B40000FB6F8463A193D3C335EA5F80EF9F20BEB7
+:10B410008D7A98C43733FB87FC33BF4BC50BBBF623
+:10B42000FB40CE28FDF523510CEA9D31D7C7BBA1C7
+:10B430007DF9D695511E484F9B7D514E18FF8C5F6C
+:10B440002DF27702EF97FB4AFBB5C7A184F849CFED
+:10B450003EFBC0245CE7975B2D4E640955DB6DA471
+:10B460008F55EE5D44F23AE45B787EF5E7E837AD60
+:10B470003AA0B7CF973EF348BC8BE0ED4B32256046
+:10B480001A486290566EB1B4FB91611890BF5B5739
+:10B49000E1FC8CED711E5700DF550D6AB135BA63C2
+:10B4A0007995E02F557B1FF81CED86557B6F3A850B
+:10B4B000FCBECAE0172811FE11A35FE0577DF571AD
+:10B4C00007001F8A33F0C1BCD2895CB85DB96EC772
+:10B4D00063035A507ED8F266949213F40F48BF4922
+:10B4E0005BC3DCA75E7275BD2F2F0AFB70106F9CCB
+:10B4F0007FB90E2818AC048A3F4FCB2D81A811A824
+:10B50000EF6DB290FC5BBEEBE96D8F239D7D64A374
+:10B51000F3BD6CD7AB7FB81EE5E73D966E13F832EE
+:10B520001C4A485C4E958BDBE3247E4A9F7FD5EA1C
+:10B53000CAE5DF97C606F154B6E79015E3838CF0B1
+:10B540002C6838646D767482AF8696F16487DAF180
+:10B550009515F7C799830AEB91D2B17DC9A657A378
+:10B56000503E4338E1F924F1D68E47437DE87FD23F
+:10B570004B83A99E13F594ABE1F181BE8CE056F1AB
+:10B5800042248B8179947C6CF34F40FCEE5E1285F3
+:10B59000EB3965AEE674FFC4CA7894F74A2CBE78DE
+:10B5A00027A5FC7BC993DF277A5CA854C73B738827
+:10B5B000DE134D244BF812719DF337DE46EB5CC071
+:10B5C00034A2C7922754AF1FD22FCCAC684F27FBB1
+:10B5D000E6BA74BE6F4E6D06E4C23A4F89F82CDFAE
+:10B5E000BBAAD0A3EFA1F3FCFB62CD8C2DA6FC1768
+:10B5F000429E0B4B6F8FAFB287EAA1555B56372146
+:10B600009ECEF6F6F4C079021C7C026ECA3FA05FA3
+:10B61000F5F7853D389E980BE317A81D9CAB05F800
+:10B620001DEB37593C68670F6927F4443EFEF7C4A9
+:10B63000F830EF70D4834FC5771EFFB500D7C7E74A
+:10B64000D7141AFFD5251FD8721FD1D75FDFE77C2B
+:10B65000A6D23FB988CA9B2C811E58EE3F344D219B
+:10B660003E616381CEF6F9168BD8E7FA7298A75936
+:10B670000985EF412E9F4A7A5900725920444E089D
+:10B68000D28F35F89DD6FF73C1E79AC99F27FD80F9
+:10B690000B057F30AEDFC82FF2D23B8F53611B3BCF
+:10B6A000F73F05F9848FC62D87F31DE591F28F6C66
+:10B6B000244794EFB278114EE7761EF9C31DA8DF38
+:10B6C00036C87DADE7C3C67D5DF2DC904EF7F5B9B7
+:10B6D000B5799DEF6BF8DEE9BE5EAB10BFFB9FF264
+:10B6E0006138F9C82E71B5FDBBB00B3E3C2B5DCF68
+:10B6F00087BF6039D123B0D059DC87F06480AF8434
+:10B70000AB91AFB6F57575CA5719867484C053C22C
+:10B7100051D22B631A8DD34ED7926E255DB7D3AD20
+:10B7200071DD7A781ACB9311F73075EF8B1692177B
+:10B73000CA1B797C22B4A378BA2AB4CF53EDFAD7C6
+:10B7400092BA85E6FD867C83A1BEC790F71AEA6BA4
+:10B75000867CB5AE7EF9812356AE3F0474F56C3518
+:10B76000B7903ED251CEF073BFD3DECFAD3EA48FA3
+:10B770005EAD56E49396E5CC1709ED5B5F5149EE5B
+:10B78000B9E46A8D42B965651897EB2E39453E8656
+:10B79000E75BBB5B57219F94DF5BC3B81DE692B7A5
+:10B7A000352A26449F6F6954A3D0FEDBEC67459D84
+:10B7B000C7B7D4115C9B5957E55CBEBB14CEED0DE9
+:10B7C00097C2B9BDA1507524D7A01DB69EC711CE92
+:10B7D0005B363D8AE2301AD36E9D01DFE7BF4161DF
+:10B7E00006184767C6F887B91C95EC34F3513CE15D
+:10B7F000DC461E07316FAD1ECF0B1C5B285EEE0BC7
+:10B80000B694D205EBF5F10BA56C2DD159C946C301
+:10B81000F7C65B689F941AF68926ECC3C67D72480A
+:10B82000F29F3C96A78B9314FCBC50CDB97506E0F3
+:10B83000E3D23195D920DFD6A8B25583795C2CFAB2
+:10B840009F5021C1FD5709FB15E52609AFF3B88FBD
+:10B8500032BB965FCEEFFBF3D01F23DDECFF64C05D
+:10B860002F213DBFFFA38C9731FFC21F933F611D66
+:10B87000EB171CFC7A36F2E94B076D0CE9FDD2C1DF
+:10B88000D793D11E79E9251BE9D99796DBB89DFBA3
+:10B8900060A41F8F984BBDB95C5CF7CA57039AE947
+:10B8A0005C5E41F83B9F6EE5F255E3DF8EA33DBD44
+:10B8B000AD1156857CFF6004EDA7AA97C2C8CE7C67
+:10B8C000E995AF8686DAE7FEA7EB91FEF74B916C20
+:10B8D000C67348C7315C2FA87A79F8D3E85FAED831
+:10B8E0007BC83A17CA0B7EF3F701C8572F3DC7E54F
+:10B8F000A98B96E627D1C6F955FA999F5B86A39D39
+:10B900000F3AEB09BB3B237BAA2FA733B870385CF7
+:10B910000238E0BA002E25781E74058FA88CFF54DB
+:10B92000787C3E9BF3B7EB18FAA38370513CFC7B09
+:10B93000A4DFAED0FAF9F7835F0D40FE73B5F5E6EC
+:10B94000FC7FB6DE9BFF63D7CBE9FD5D5442867476
+:10B95000A4FB8E74FDC20F28BF3BD24DF3FD8EFBBE
+:10B96000BD14D7DFFD3F71FDFF3BF85EF31FBBDE6B
+:10B97000ABE1FB0D81EF4827FA332FBDF2F7647678
+:10B980000DEB7EE6FF289D4B397EACEA3E9607F52F
+:10B99000DF640DEFBB53481AE9540E793F43AF3FC4
+:10B9A00015307E4E17D8CB48FE2CE8F520C9CB7554
+:10B9B0002C9FFC17BE5E2AF975280804E0F07A4235
+:10B9C0001EDDB362E640AF25901F9B5441F16246F5
+:10B9D000BDB2207C6211CAA74796C1BCA09F23912B
+:10B9E0002627FAA8C7F55203B60194B660FA5AF2B0
+:10B9F0002D14F73FCEA1D7AF6E31E84937B9F4E542
+:10BA000045ECB96EE8B72BCAB1D0FD8AF1583F4476
+:10BA1000AF7C2EC349EBBC89D5AF703AAE1D4EE664
+:10BA20004C0EA78E70F8E770EB0027A1479B457D71
+:10BA300023DCCC8EFB9BB09D99815ECCD74BFAB4B6
+:10BA4000D48BAF064F26F46DB3185AC2D7DC8BFBEC
+:10BA50006743FA25B848B85F2BBC259E8C7097F0D9
+:10BA6000957033E2E18F194CE8B71CFEBDCC7966C6
+:10BA7000DC77A3845C3FCE1CC3F3BD9A542FED4703
+:10BA80003FA7F3BFBACD28D78F71C4501CA9F1FED0
+:10BA9000C29C61314315586F9299F96CA087A2EF4F
+:10BAA0008DECAEF799FDCB53701C6EDFED6DE6F6B5
+:10BAB0006BD8DDBEF07CAAEFB142BEF8E185CC03C5
+:10BAC000F58B93985BE1F559742C85C73115E3C468
+:10BAD00020C576C5D1BCDFE21ECCBF9CE393F082CB
+:10BAE000661FB46F40BF1E532C6F1F954FED7D2610
+:10BAF000DEDE6386B44F1A8F53685DC9EDF2C5ABC5
+:10BB00007B6720FF9830566F675E9AC9ED2E323DF5
+:10BB10009DE92278A9267702DDA758914DFA911A5E
+:10BB2000EEADD88776FADD3C4EA778D55D1387E079
+:10BB3000FC76C7B9717A6727ED19CAEBCFFCFE070F
+:10BB4000F05DDB1E46DF1D59DA7599180FA0B86647
+:10BB5000EF830F736E3B624D8021B486C917D04EC0
+:10BB600038C9B7E777E89F9C344DA5FA93188FC37F
+:10BB7000642B22280E73A2EF737302F43711940E14
+:10BB80002C6F097326DF03F32F16F6E102B15FD4A1
+:10BB900070A63DE7C079F5CE4885EF1359E7F1C9A6
+:10BBA000CB447CB23A56D9887EA63E05DC7E2FEB8C
+:10BBB000633FD8EFEA4C6EAF9F24529907B852FD0D
+:10BBC000796B6C2D69A8FFACB10432213D943D76B0
+:10BBD0000AAE73422A1BBF01E17EAFCA36D37C5B3B
+:10BBE0008BC9AF1099E5423C6840D2E45FA94F7120
+:10BBF000A15DAC654C4300FD092DBF4871D7B90864
+:10BC0000CB140F24F5AD963181BE68C76FCDE37EAE
+:10BC100089E3CEE648D417E73AECFCFEA4882B9AD9
+:10BC20002FEED1F4A96B7EF03AD4431F51C95F3394
+:10BC3000FF117E3FEC2F0EBB5F41BD6D3DDFA76C5A
+:10BC4000AD3E8E8839DD64079A5B3FC68AFAE63CD2
+:10BC500087C78AEB5C9BA5556722DF16F711FB218E
+:10BC600012A0CBE2FA628A5751A360DFE13E31BBFA
+:10BC7000A2500F36C6215589B823995F13AEDD8BCC
+:10BC8000709A13EDDA8DF472A2268DECA30704DD11
+:10BC90004DC0B84AF467989B13713EFDF03B8C3F52
+:10BCA00021D699E1207A0E630887168B3303E9BB0E
+:10BCB00065659809FD72139673BA867D663743FBF6
+:10BCC000FBCC2C1CFD0C378A7E672D337B3741BEA5
+:10BCD000979D99236391AEF288AECDFDB449B8BE6D
+:10BCE000D33F61C3901EE6AE5D47FE184917CCDC1A
+:10BCF000342E0EC639BD35251FF9663B9FEE37B68B
+:10BD00001EDBB5D3C33485E800D24369440F531E0C
+:10BD1000217A181BE8BB3807F5D172E6C1F33D81E3
+:10BD2000B9514E6863ADE4AF6C73585D68FF92FC27
+:10BD300044F20D795F56D2C13638EFCD16C6B6D76C
+:10BD4000DA297DB6D6C9CCE98CEDAC4DA0FCEE5A13
+:10BD500017A50DB559F4FDB95A37E5F7D60EA3FC72
+:10BD6000FE5A0FE50FD41651FA52AD97BE4BBE04E2
+:10BD700070213E24F98AE447731DD616F45F4ABE4B
+:10BD800064A49BD900DED1F9D49EF89EE477B80E66
+:10BD9000537E901F49FCA62A5E5F420AF2B1E699E3
+:10BDA00088FF42F5FCAE17502F2F71B8494F679CA2
+:10BDB000EFB501BD225C92ADEC00DA65EBEEF1B4BB
+:10BDC000AC4E09C2FFCE12859943E8EAAEEA30666E
+:10BDD0000E3937EEAE89D1E567D5BCF76A0FE87F3B
+:10BDE0004677ED0DC4DBF19F7EF6C41FE1FB533FA8
+:10BDF0003D9B8EF886796C7D0CC75D1ADE3E8F58B0
+:10BE0000CCAFB0909FAB8FB09FF411F613FC137AB8
+:10BE10009FF9A99FFE37EDF3961A9B0BE5E28F1170
+:10BE20005F00DF3F097CCDA9B1111C8B577EBAEBB7
+:10BE300005DCEF4BADC4EFE6AC10FBD1700FFA445C
+:10BE40002223BB0448D514CF7EE227D64004F47FDA
+:10BE500042E1FB5801E16016C61FAE79FD43E403E1
+:10BE60004ACD31F2BF6B786F0FE7E7B39CD7DDABFC
+:10BE7000AE798DEAB1E65E31685F94F79223067B76
+:10BE8000AC2E583FD236E26F4ED66196887E967AB7
+:10BE9000C589A2DF3CF17DDE1A85FC9A18C7330DF7
+:10BEA000E4BFB64C95F0999B69A6F4018CC127F9C3
+:10BEB000AE9ECE2949B7F3D6423BDC1FF579D605B5
+:10BEC00021FC788EF83E37CB44A9FC6ECAE2FDF621
+:10BED0005C933703E58A9E589E8369FE0C846F4FFE
+:10BEE000C778B3124207DF88F173C5F80FE0A68365
+:10BEF000FFDD9F956A9D9F43F701E91C93E3CCC941
+:10BF0000CA5F85F1A573D68E412ECCEA2CEE846EE5
+:10BF100068BFCB92FD88FBD8761E475DDEC539220F
+:10BF2000ED6AA7F19FC369DD64F72DDDFDABDD7818
+:10BF3000BFA0F4131BE1B774A088DBCAF10F9D4AC0
+:10BF40000648BD3D7BDCAFFE1C457E8ABD3CBE1372
+:10BF5000526E675D5AC2EDB26ED85F9DF88B8EEE61
+:10BF6000FE24AA533BF65EF53BD9B1AB946FA250C9
+:10BF70008E90EB297CE58B789A877285FC4455AFCF
+:10BF8000AC8CEF2CCECB68C76EB7770BBB5ED5D22F
+:10BF9000A24EEDDD46FBDDF02C83FFC0CCE89E9980
+:10BFA000B4DF3135271AFD005F88FB275DE939D200
+:10BFB000FE5DB5013A8903BA34BBA2D1BF75A90BA6
+:10BFC000F97A59163FFF2F087BF9A59D2AE93D977D
+:10BFD0007646D2BEAADCF9F06BE877ACDCA2D034AE
+:10BFE0002A5813C10FE0CAECA1E71AC6B1C5759C67
+:10BFF000779B3F3D1ACF95B25F455623BD2D6A50C2
+:10C000003C5B613E6D765774F790F9DC85F406F47D
+:10C0100053666B184AF016F39F9AC5F9A4ACB7A8FB
+:10C02000F161B22F43BD8B2417FD3A82F1FB29AD9C
+:10C03000BFC3799EDB38C88DFEC2450D7B2A49AE51
+:10C04000D819E144BBC25911B7DCDE8FA0EF4559C6
+:10C050005C8E3927FC47E776F37700709EB8CFCE29
+:10C060002ADC0EDD8E6FD1AE4AC02D368BEF3359F0
+:10C070007F51434B545FA87FEAC07B94DE2BD6B53B
+:10C08000C8D13400CFE3537B23C8FF756AEF2FC7B5
+:10C09000BF0CE35D6818D30DF785EC7F759685EAD4
+:10C0A0005FD8A81621BC989FC7CD54207C0785CEA9
+:10C0B000336E932F2574FFF1F8A1737B9F8F32E5C8
+:10C0C00004F15961AFB6279A701FDDE345FA8E403F
+:10C0D000E2817AD6BD937D78865535E631A46BDA58
+:10C0E0007F89547F8D29A49ECDE2A63853CB8162EF
+:10C0F0000FBF6722EE458938FE423587FC8AB307B9
+:10C10000BAA6DF897CF24D0BE16371B66B3AF2A7F8
+:10C11000CB4D2AC3792E4E6101944F96DC1BB90991
+:10C12000CF3139EFD983383F285FA3300FACAFDC74
+:10C13000AF320DD29E807F1FD25342F3108C936C8E
+:10C1400049E172858C1F7DBCC4E4B1C239B8272B8C
+:10C1500056F059ED17F3D17F36258BF4B9E356E647
+:10C1600053D1AEF41C8F2F2D4FE571CD8F8B78F806
+:10C17000F2D840461CF4775EE0B77C4A2003E32EF9
+:10C18000CA9F4BA4B88BF356EEF7C4EFE8672DCFE8
+:10C1900087F60E7A674393ED6342E8A97C8EDB85D0
+:10C1A000F5D458B72BCF81F3755E2439775F2443DC
+:10C1B00039D7F442248F9B7A266CB32D046FAF0AD3
+:10C1C000FA93EF77B03B789CD1A3161E97FAE8D686
+:10C1D00044BF3F045E8F5AB49908075C07CAF78BC7
+:10C1E000ACF51928FFCAF92E8AAAA7799E17F4BEC2
+:10C1F00028BC9EC7738BFBC0581FF32D220EBD7544
+:10C20000878DE280CE2636EDC7F1CFEEC866B8FE48
+:10C210009614FF8203540EF225E0B3F4595B00D765
+:10C22000736607B7479FB17079EDCCE40417E2B7A6
+:10C2300068CA86D964AFD96253D0CE774661D60436
+:10C240002CDFDA9DE2CF4B6B6B287EBB14D806DE69
+:10C250001F82B408EF019DD99A4DF16667F0DD06A3
+:10C2600085BEAFC1EF1AAB9FFD2384C776AE5F9D3D
+:10C270007DF66FD9A1F1DE322DDDA28FAF9374224E
+:10C28000CB3FCBE2FAD067595C9F3B9BC5ED1115C4
+:10C29000110D8FA6D23A39DC014FFC1D1BD61CF9BB
+:10C2A000CBC1184F91AE201F799C05327E897687CD
+:10C2B000ED5CFF3ABBD34271EBA52F447A288E6D1B
+:10C2C000F575268AA750B99C5E6A02F041AAFC74F3
+:10C2D0003BC597757B362CDF46F239233DB775ABEE
+:10C2E0002AC6015D10D7BD8DC71D4F405992CA7334
+:10C2F000A9FC8CC89FD99F4B721FF4EFC1FB55A5B9
+:10C300003FFA3187E3D492B7B8DC65277E5BDEEE77
+:10C31000E719198DE760C5EA11D1785F91BDA332A5
+:10C32000945B8C70BA6C76F7403E3B3C5BF0DDFD75
+:10C330004F907FAA4CDC23287B56E17E68D8877813
+:10C340009FB36CD588C7883E7F6761E9B09EF30DC7
+:10C350000F4785E2232D9BF3C5F6FA5637D52F8379
+:10C36000FAD84FD9AA37A3683EDB2C14AF62C4E3D6
+:10C37000776EFFACFA9DDAB7D34703B7B374583F73
+:10C380006BFAC127D0FF5F7786B97DF4B581EEC126
+:10C390009DB3342CC0F59FDB15467CEB5C0CE70F9E
+:10C3A000A7809FFA32711EB7FC8CE2BBDE9D4AF774
+:10C3B000F716FAF5FDCA71B3B22D3CFE2ACE1D8DDB
+:10C3C000F18215EF703E0878B995DABF63A1F6C621
+:10C3D00075D8B239FF6FDF9FBB22881ECEF5E47897
+:10C3E00039B73B93CEA796184EE730DF64BCEF77A2
+:10C3F0006E57661EDDA343A107E8A154E8BFE762BC
+:10C400001A929D21E52D16A1C705A026D20DB601D1
+:10C41000FE5E5AC3E5AD32FB5A8A2FC178DDA1F921
+:10C4200094066CB11DE36E815E49BFACCDE6E7209A
+:10C43000C3F1E2459C38C9410D56E4DB9A9017CB15
+:10C44000771AE37679F96CD91EAF64C83861A443D2
+:10C450009F42712A652BEE5944F1F7D5EBEEC47D6E
+:10C4600026E75F666645A8A7B5282ACDA3258CDDFB
+:10C470003D05E5CAD07142E4B945D9EDF656E68CE2
+:10C4800027399684FE8A6C17A71B3C41F19EE20A6D
+:10C49000652D8D9322F55DBE2E0927008715E304D7
+:10C4A0005BC688F22ED62DE7695C77BBDC95CDF9AB
+:10C4B000514B8AEB672311CF6FAB74FFF7F23783D1
+:10C4C000A2633B91D382E7BC35182F0BF37F289BE7
+:10C4D000D1FCA7647339BD0CE371619E191BF5F1A2
+:10C4E000E2595BF4F97E3BF5F99CBDFAFC80467D90
+:10C4F000DE7D549FFF018E3B84EBE178DF18F57001
+:10C500004C510F77D9B81E8E79D4C331453D1CBF2D
+:10C51000A31E8E79D4C3318F7A38E625BC511FC74C
+:10C520003CEAE358FE9B6C7E3E968B784BC403D26C
+:10C530003B7B314C771FE9D22BFC7E09D001DF37E2
+:10C5400033ADB46F1EC71AA48F70BB53CFA9761733
+:10C55000C60FAF8AD3766477C77B284DAB12116FB5
+:10C56000E6668A63AD7A89C7B196E78739D0FED18E
+:10C57000BCF2D42A0C0FBD234EDB8DF52F595AB7D0
+:10C58000217C2B6A8ED07DFDE665AE776EE0F823C8
+:10C590003B0C2B892539AA18CFB9D8AEF1688C2766
+:10C5A000676BF5F1E3C67872631CB9910EA4FCF7D2
+:10C5B00094A53511F9FAA73BEC6B71FE9F8689FBB8
+:10C5C0003033EC86780007F193C50F2A9BF1BC7ECF
+:10C5D000279BDFCB6E3B06F27A27E7AC4CE75E1970
+:10C5E0004472797B7EAD62A2F874CD43E7D01231FC
+:10C5F000A764A5B56535F2B945263A372F83BC4601
+:10C60000F2E0FB2AC90FF8AE56E87AF05DAD50FAB9
+:10C61000C277B5F4F7257AEAEAE3BB5AFAFB12FDD2
+:10C62000F4F1F9D3961D42BD7FEADA41BA7AF3BC40
+:10C63000230C7014F316F2EC3C383F3C285F2EDDDF
+:10C64000908CF85DB2A8AD6535E077C9BE303796FD
+:10C6500097E0FF015F2C813EF1DE65C95E717FB915
+:10C66000467F0ECF15E7508999F99CB1413A2C715C
+:10C67000324F0CB45FD4AF6900BE9FB5E88DF7862A
+:10C680003A5351CF18D303F951B2C54371B5E57B85
+:10C69000D2639641BFCD7DB56F91EE4ED61F7968BE
+:10C6A000169E877BB8FEF7E9DAE7A328BE4CD05B7D
+:10C6B000B2C5198E78DF54CFE3EBD07EA6C606E96B
+:10C6C00062537D5C785F4770BD413AF886F004F8AC
+:10C6D000E1769E92C3E417696B10EB1DA3F850CE70
+:10C6E00096EB93EF6EB115BC9FEF89FC49A16FC823
+:10C6F000759ECF3E34C085F73A6A0F24ABC8CF4D44
+:10C700003BB7A11E72C5A625F61B82F1A0E97FC426
+:10C7100077D84A3FE0EBF9CBFA82A8E1287FEEB266
+:10C72000B827407E75FDD356D42B4ACD7E2BC567E6
+:10C73000EED864C578E51BB76FA2EF0BB617533C74
+:10C74000E642564DFAE869F94E828047C95865A31A
+:10C7500013E65DDB8FF38F9270EEDF03F9E8557C13
+:10C76000A7E4F276250FE37CA679F7588BE17BBE30
+:10C77000A867DC276D6F4D2DEC4EF0E0F7403E6072
+:10C78000A0DDA775DC1753AFA4D0BE9876A53FE90E
+:10C7900069B705B2B93E9C63D087DF52B93DAF910E
+:10C7A000EF83126BA0DB54DC27072D24E75698F9A2
+:10C7B0003B4F15F0EFEB21F58E5475F45A352E42B0
+:10C7C00047CF3358ACEE3ECDED185412929F362130
+:10C7D0004D577FFAB4FE06FACF0F96131FB95E7756
+:10C7E000EFAF62A9CFA5909C3956FF9DF1F842C6E4
+:10C7F0006ED6B5AF605382F590BEB7285CEFD91BFB
+:10C80000B319ED802526AE3FCDD0F8F7CA03FC3B27
+:10C810009BC174FBB04F9AFB8FFC5CB490DF40DA95
+:10C82000DB67E0BF3B813F63E1EDF7D8F11E3FDA04
+:10C830002774F7BB85BF10E78D78A810F6A48A2C63
+:10C840006E4FAAF03559F19D0480BF392E96EAD972
+:10C85000E330AEB25E217B23A64B29CE521FA785C3
+:10C86000FD61FC63E531B518F789B1BC04DF2942ED
+:10C87000FCBEC4E3522BD12E14D5F17DB44AB413BF
+:10C88000A17DCBF01EDAA17E2E211FF957F5443889
+:10C890004E50F2E8DEE6CE43568CCF9B362D260F67
+:10C8A000F78F91CE247F877D4D71856D6F1D213A65
+:10C8B0006B2B31131D5F0D1E951E6E6735D2DF0287
+:10C8C000D664C5FB290BF62A6ED44BB11EC2A52730
+:10C8D000D2A5012E71B11DE121E1D40E3743F942F9
+:10C8E000C6E1B5F080E247FED8014E027EC6F97778
+:10C8F000053FB9AE059A361EF9845CDF425C078EAF
+:10C9000003EBC071A4DF820D33EED734B25F557AEA
+:10C91000799CAD913EA65CE17699DBAF98299D3676
+:10C9200041BF3FB11DEE93DBAEC453F9B5D24F25E5
+:10C93000CC13CF856BA51BB91EC98F83FB84DF4B3E
+:10C94000B8DA3B4746FBE4DBFD847D72081BA28B13
+:10C950006F16FCD6D8DE18DF2CE503E3B9531C694B
+:10C96000A278CB36472AC91D92FF6AE25CD1567E77
+:10C9700041F534A8C767E3D19D439AB0132E8E4C7E
+:10C98000A577249297C5C523BE8AC39C14D75FBCE4
+:10C990004CA538EA62A8E70A915B56AD484BC673CE
+:10C9A000E4C47D994FFA409E3F716FB7F86130CE75
+:10C9B000A72B2DDDECAE60BD132B0B9331BEE3D363
+:10C9C00075B619FE4EE0F59538372A7EFA219D732B
+:10C9D000174C6F45CD80F6E52BF745E1F581B29513
+:10C9E000FC7C5FDE57FBB21FF97D376D7322FC9C28
+:10C9F0009B06A09DD8C261DA2E5794AE2CEC8172B2
+:10CA000047F9B7479E74E2BDF0659678944BCFBC6A
+:10CA10000FE7A442E71CC913A7C3A00BF2C345D27A
+:10CA2000FB67A715E6417FD479D3A12F57A3BE9802
+:10CA3000D7901180F47ABB66E98F7AC1CAA7499E64
+:10CA400029BD7F5906BE43A82D4B8FEECC9E22D325
+:10CA50006DE23C47B91E5394EB31BE06E57ACCA398
+:10CA60005C8F29CAF5F8BD6A835E2E8C127E4A69F6
+:10CA700077EE53D79A877E3FDF5896554DE7B083C0
+:10CA8000DE055EA284BB913F2D41190AF37F8E2003
+:10CA9000BB037BFF261D9EE5BBC1F25DE051AD20CF
+:10CAA000AB85EC931BAED859E83DDD312C46972F72
+:10CAB000B027EAEA173A5374E5372664EBCA6F7277
+:10CAC000E5E9F2B7640DD7D59FE81EA3CBDF3AECBA
+:10CAD000265DFDC99EC9BAFCD4A299BAFAB7798B72
+:10CAE00075E5D3672CD295CFD4EED1E5EF2CB957AD
+:10CAF00057FFAEEA65BA72F94E7223EA63367CFFDD
+:10CB0000C54EA97C2FF9872AA3F7D8461698B89D59
+:10CB1000D1C6CFA3256FA73B42E9E0D6FE5C2FDD4F
+:10CB200095E3B9B9FF90E07B98F29DCBBBFA73BC5B
+:10CB300026B180C2F5E1A644A463633D63F9C888C9
+:10CB4000C3975D80CBD7FA1FB9CD8CEF475E77785E
+:10CB5000501AE4A372C26EA7FC88C3CFA7423E7EE0
+:10CB6000E7AD3C3FF0F0652CF7E744F1FC5446A2FA
+:10CB700049EACEDDB7613CCAC81B52D7BAB91DA578
+:10CB8000D3FBEE324578E03D718407A601A0634CEB
+:10CB90000F031D637A14E8789E05E605748CE9316D
+:10CBA000D04FF1FB6F413FC5F42DD04F31FD1DE853
+:10CBB000A59836815E8AE9BBB533287DBF56A3763A
+:10CBC0007FA82DA1F4C3DA6AFAFE716D0DA57FAAC4
+:10CBD000F5D1F77BFB4BFB4340F7DE6857EF8A4A02
+:10CBE0003FA7F46BD655B3E608E41BCDE698CFEC2F
+:10CBF000417F65D7760233FB2C445ECB553C2BFA44
+:10CC0000D3F8BD9C749F427C77A468F7217FF820FD
+:10CC1000656AFA2015CFB1EA5731D4E60353E7EF3E
+:10CC200047DE25E8C397E37908DB8DB2F3FBC9A3A0
+:10CC3000ECFCFEF12873531DD257DDD7CC85F13FB4
+:10CC40008722F9BB1F75F799FD680755AEF07D3E49
+:10CC5000BA1BA37CDDD7CD745F7994D39D80E79513
+:10CC6000CCB7FBFDF14F489C8FF4C3CBF89E7157B6
+:10CC70009A0A505E18EDB0BA908F84C60DA0BFFD21
+:10CC800050E467723E0CC793FEFD2D5FB380694090
+:10CC9000D08F3FCADE94827683D1DFB3BB43E39665
+:10CCA000A4BF5EB9D2ACA25D55C627C971E47C238E
+:10CCB000CDD05F7E30FE6894B3210FFD1D75150E3B
+:10CCC000EAAF077CB7E6533D8F4AED1AF2D02E3714
+:10CCD000BADC4171B0324EA0875837D4A3758EBBF1
+:10CCE000A2519CC468112781FDD879B90FFB19DDC9
+:10CCF0002D90887160A3ABF93B644F28D03E3F185C
+:10CD0000B780F52342F62DCE13FBEDFBDF305F94A9
+:10CD1000A33C1E82EF54A9D7B9445EFA1DED63C946
+:10CD2000BE552078CDF214ED1DA423AFCDF9E70850
+:10CD3000DADF69BDD16E3A59C8F5FF845EDEFFF7D0
+:10CD4000D08B87E3BB17237B9B916E245E249EBB15
+:10CD5000A22389F7903833C2737BDC98E8C7485F19
+:10CD60005DD195A4A751768E77C42BC6A9493A52B6
+:10CD7000AEF077DD4697DBE9BC937464A4838E74D0
+:10CD8000C4E9B2EEFB76EAAF231D05F18FF0F8D7C8
+:10CD9000E9A85945FFD5B5D2CFDDAD6C7C3414156B
+:10CDA000A46A77215D145F71BD86F9B96CCC7824D3
+:10CDB00029593EA18B72EDAFAD96E8103A1B25E8DC
+:10CDC0006C4917F5653DF9EE85ECFF61ACDFBD639D
+:10CDD000FD3785DCF066988C53F138F28606E34621
+:10CDE000971472FA2A4A5149EE28C8E1EF9F330797
+:10CDF00097B35DF017F9F1CD4C3B1A9D82EF947A11
+:10CE0000E97DD2F1DD0CEF930AF9BCC8E0E7BF3948
+:10CE1000E74692CF6FBECA3BD7C373C43DB71496E3
+:10CE2000728DEF907A72483FFCAEEF90F2F76BC7CD
+:10CE300089FD9E24E829CDA5B291B1F89EBB66C6B6
+:10CE4000C3E528BE5F3B00DF79F551FE26E6A7F477
+:10CE50001616203962221C4498BF154458CC1F89ED
+:10CE600098340BEF1C160C2AE88BDF43DED9BB0D80
+:10CE7000E757A96AFFE50C7967EFF03817DD5F3DEA
+:10CE80006C4F233914F7AB25C45EFA069CCF7D6145
+:10CE90007D47E0FCC6F45538BFFBC239FA3A9CDF47
+:10CEA00098BF396B19C376E35DFAB827D9FE1667C8
+:10CEB00001286A5DC3EF96012FF642F8BE19933937
+:10CEC0000EE9E2CD98EBC6E17ADF8CE961E2A9CD0B
+:10CED0004A69EE0B7D3B9393E57E088E379EC63301
+:10CEE000C257C2D3084709DF7F019EB539433AC212
+:10CEF000F32ED423D07E6B7F2F2A2115FD9B9CCF50
+:10CF00005644248BF748DF1EA0A662BCEF089AE7C0
+:10CF1000E89AE1CC8CFE763B87D3A95AE643F89E8B
+:10CF2000C125A0C1DB60DF63E6B1A6D038E83D369D
+:10CF30006D1DE2F5D44695EEEB5F782E8CEC76A76E
+:10CF4000FDDC2E5969D21EC5F272D5B5D68DF2E63A
+:10CF50009B2A7F47F49B23C95322AF815EB7F077AA
+:10CF60000ECAEDE33BC5A7D42F67A57AEEE2F20D1A
+:10CF7000D3FD1E452F1B7F0F42BE4BD995BC3534C8
+:10CF80009CF3BD5E36CEAF257E375A851C00FD0C66
+:10CF9000053E9BF4B370D2B71E8CF7EC463C801E66
+:10CFA00043EF4FB5F58AA4F3E9B0888B1B1DE84F1A
+:10CFB000EFAD1589DF1D785DBCE77E58C4CB3564C5
+:10CFC000682F62FBD75D877BA1FDE106C6FD403778
+:10CFD00039F8FBF9D7AA9F1FCA11FAF90036E09A6F
+:10CFE0007E27A1BB4AF72946B30CF2C317E07C9118
+:10CFF000CFBD31D78CE764C8EF24D0BAFEAFFD4E69
+:10D000000263AD2AAE2BC9A9B0C753AEFD77135446
+:10D01000A157C9DF4F28E2451D7E37E19751453CB6
+:10D020002EDFB1A0D3DF4D4812EF5A33173F37E45C
+:10D03000EF261426E8CF9102E798A34E4AF5769E94
+:10D04000A4ABC48F29B9E2FCB856FC5730C27F7B31
+:10D050009C69371EFF345AEBF733B4CF1774B3B85B
+:10D06000FDAE8E74F09FF6BB285DE1C9F87B2946C2
+:10D070003C197F3F25492D37D33B90024F33E02F9A
+:10D08000E2E906F1FB16E3F0F72DD8BF0F6FC30CF2
+:10D0900078FB82AD1D82EF965E2AE67CBDAB73FF06
+:10D0A0004B9767742EF0BD9B05DF97F61119976BB0
+:10D0B000FCFD24690790F1BABEB11CDFBEE311E4A8
+:10D0C000BFFAA1DA1C89E7CC7113FFBDA4C4EEDA64
+:10D0D00004ECFFEE9C6A05E191C0BC7B16C0FC67C6
+:10D0E000FFC6968CF9D97DF87B912C87FF5E909CCA
+:10D0F000DFEC241ECF352D57E8BB6E1EBF353D97A4
+:10D10000EB01916E27C59917E730113FCB9267E786
+:10D11000227DBE159689F4B79EDB039BF1BDCA6ED6
+:10D12000C1F72A514E47B9B8B7904BEB3EB2DB3945
+:10D130001D32DDF99FEDB7EBE29CFB6F77EAF2B9A8
+:10D140000D09BAFA030FB874E579812C5DF9A06373
+:10D150006E5D7E48D3305DFDEB3EF4E8F2C39B8B01
+:10D1600074F5479CF6EAF249ACF51708DF8772536D
+:10D17000091E7D14612771717CCCFE613CDD5792E4
+:10D18000FA878C7BD7043D1BF59A3E562ED7D725C0
+:10D1900032AEB7DA857ECAF4FA8D26E2D6A55CCF28
+:10D1A0007CFAB87519AFDEAE07093D47EA1321F1E5
+:10D1B000EA1E9CBF8C576FC7BB783FD448AFBF14E3
+:10D1C0007837AEA38F95DFAFABBBD74AF784E4FCCB
+:10D1D0008CF33A20E298B7DA3B7F0F6A472E971319
+:10D1E000BE4EF36ECA857A4F02BB22787618CFDD29
+:10D1F0008CBF3F50F713AB7BB9EBEAE3CD1EC8D72A
+:10D20000330BDFCDCDA1F757E95EA01CF74541DF19
+:10D210009B060A39C530DEEC681E1FC7A2AD74AF8D
+:10D22000A5EBF1385C13AC6C05BD5B25EE79DCB584
+:10D23000B6E1412C9A65ADB7F08707FC16B4A34D53
+:10D24000180B72621EE886CF2C7AC40172D1933516
+:10D2500066B28B05769DB8DDD737786FA70FE86982
+:10D2600048271310FFD0EFD0813C8EBC2597AFAF7D
+:10D2700050FDA6FDBE854DC7FF19F1FF4EE88EE8B3
+:10D2800051AEE37FEBFE85A45F239CA45ECEC4B9C0
+:10D29000D657CC4BC24FEE0B093F79FFC5758FC5F2
+:10D2A000BBD941F7688A302E4FE2EFA681DC6E1FB2
+:10D2B00087B260775E0FF95157F50AD59C68F4176D
+:10D2C000B43157B4F32A76F3FFA57B2904FFAEEE01
+:10D2D000D375C5273AF0872EEED775459FF4E71A28
+:10D2E000EED985F0091E2F25F0E1EF6BA2B884D5A9
+:10D2F00091FA7D5C3080F38753621FC3F9EDC8D388
+:10D30000F30986FE8FBA95AAE0130BDA7F6F04BF8C
+:10D31000CF5F6921B99B31EFA318A7F197F5167A72
+:10D32000E771B487917C3367A3E2DFA4047FE7ABA6
+:10D33000D86778A745FD86E4C32FD62A4EFCBD8862
+:10D34000B96BF4E50B1DFC774AE61BDFAB91FEB829
+:10D35000ABE8F5830788F3DDCDDC249789388A12A2
+:10D3600051C72897B5F9B9BF11F57295DBB128FE01
+:10D370004E9EFB2EF47785BCC302700DCFC2737C2A
+:10D3800085B9D3B8C876B87611F771DE21E23E1CB4
+:10D390003CCEA56D6F18F70F4B3F9CA87FDE7799A9
+:10D3A000CAB13EF676218FC7AF48FF9BD1BFD7E603
+:10D3B00030917FAA6D6F24C539A0DF2B1AE8E1AC4C
+:10D3C000694FFCB094E0FCB46655E73732A6DAB298
+:10D3D0007DA44F2EEFABCD1E8071FA66B7DD0DF93F
+:10D3E000FB1C87E91DAF09C20E669C6FFBEFFE8D2B
+:10D3F000E4EFEAB4F9B8BCDB56C4DF3B01FEC87009
+:10D400003FC9788EC90CA43B488B03C3693ED7EA59
+:10D41000FF9A7A258FFB7FAF8CA0F6DA9AE194EF22
+:10D42000B3E2C17BF09ED16D750B2D180AD0FC8B39
+:10D43000A585E1D0B4B9B77F7938E26D8CD2A9FF68
+:10D44000A276003F5F9A0DF716647A49EC1BC7403D
+:10D4500026F89388E75AA6D07E58AC3019DF45FCF1
+:10D460005CE62FD78B7C21CF2F59C9F3CDE27715FE
+:10D47000B6097B0BAE1B535C37DA05760A7B0CAE24
+:10D480001B535C377E47FE8579E45F9847FE8579BC
+:10D49000E45F9822FFC2EF739837394FE57EBB7186
+:10D4A00021FB03FD76E342E423F4DB85E6D16F172D
+:10D4B0005A1FFD76A1E5E8B70B2D47BF5D681EFD3D
+:10D4C00076A1F5D16F179A67C36E0AE691DF7926C8
+:10D4D000EBF25341FE1F17B2BFD16F17DA3FFAEDDF
+:10D4E00074FD69F7E8DADFC96A74EDD16F175AFF86
+:10D4F000EE1A45E7D7BB5BBC433B77431CD14F7962
+:10D500008AB711E9FEBF22BEFDBE05F545B5711112
+:10D51000D7DBC2DD1CCFF5451CEF267ECF42699DCF
+:10D5200049785E6AE5F9421EE76DA41FF48B8DB35E
+:10D5300070BF18A6E817C314FD6298A25F6C5C3A2E
+:10D54000F78B618A7E31FC8E7E314CD12F8629FA91
+:10D55000C53045BF18A6E817C314FD62D80EFD629A
+:10D5600098A25F0CBFA35F0C53F48BE1F7E3E89F35
+:10D57000B304E785F27C5F9D5E0974A8D32B9DBA46
+:10D580003CCAF3A1F5519E0F2D47793EB41CE5F935
+:10D59000D03CCAF3A1F5519E0FCDFF2DD745FB0C12
+:10D5A000E5FAD07628D787E673EB7DAFA2ED6CE283
+:10D5B000C68B47316D8E549E548065FC7DF78FA6D7
+:10D5C000A3FFB2394C498E01CE69517CD3C7415E6D
+:10D5D0001371940358AB897EAF0F95478C73083055
+:10D5E0008A5BCDFD3A91CAA3329DED71CB88F7BC21
+:10D5F000BD8C7E8F46FAD7657B3773AA98CAFAC16D
+:10D600007CE7F58CE3CB7AC43F43E68137AD31DE6E
+:10D61000276FA9231FE366B789DFCBDDB69CC75B05
+:10D620001BE92A4FC84BDB4C7B0EE37D9AD6628503
+:10D63000EE5D6798D9314B3EC2A93A1FE588C48197
+:10D6400031625DD5D7E3EF8EC9794B3B28F009BA3B
+:10D650009F38B2B5A9201AFAD17C63E8F771265831
+:10D66000B9FC80ED50AFECEF533C9B43E83B4DC819
+:10D67000E39A8F8FFFCC539378BB70DEEE99A7A20D
+:10D68000088E9356281477367227F3E03DE81C3154
+:10D69000EFFE3B032A8E57BC828F27FB2DDE984C72
+:10D6A000F7428B59F338BCD7C2062B0CF9B6841B52
+:10D6B000ACEF28AE2F03B60ADAB1BFEB7DAA5183D7
+:10D6C000630A311E9135327A5774E2E0DFEBD64BB4
+:10D6D000681F4AFDD2B996E953E81DE749BE65CBFC
+:10D6E000F1589FE8BBE7D5EE587F0B73A7B8E82841
+:10D6F000A2FBC7723EFD3C7B4C702CB21CD6640A68
+:10D700005310DFEC485C08FDC0CE9F86F8CE735BFB
+:10D71000E85DE5C966A785DEE9E8225EE7B243C6B3
+:10D72000EB18E405435C4EDDD20F93D1DEBC38D25A
+:10D73000447693C5FB22486ED03628C4D7A41C5427
+:10D740002CE2FD2EAF78B5FB7484FB1E0BF527E3AE
+:10D75000752AD2FCC926BC9FD073D3805895E4802B
+:10D76000BB07A21CE07BFEF661586F257F57F4F2E1
+:10D770008A7DFC7749857F47FECEE93C11FF559CA9
+:10D78000EB8DC67818F97B6AF29E8CFC1D5369E715
+:10D79000297E7BD06B88DFE227C4BBDF6B8AE9FE82
+:10D7A000BB31EEAA4CC87F8B5658286E6B91413E18
+:10D7B0002C13715957FB7DD39A8106F950FE4E8E7A
+:10D7C000A8C3D45E7F40BBB0BCF739CBC2F9C0ACB4
+:10D7D0003D8CFC55B3961598F0BD6AB68FD3CFAC8F
+:10D7E000655CCE99F5A287EE6F4AB9F11D21CF4C49
+:10D7F000B99244F07F4FC82FB761BC2AC0794273F9
+:10D800009888634BA474FA151EBF3AC5C1F941F359
+:10D810002BFCDD8D369F8DCB5547197F37CE409F32
+:10D8200093CD7E135E68748F04FA84FC449487A0C1
+:10D83000BF19281FC521BDA714523C649142F78827
+:10D840008CF43EC152FD2AC6DB4ED8CADC3E164AD5
+:10D85000EF40C7D89F4FA1F71834A1E74A3A36D214
+:10D86000FDEC08619F7270FB53BB9D0265557A44C5
+:10D87000FD83E9184F3C1B6D863D69191E8CDB8BBF
+:10D88000CCE1E5CF0DFC60FA0ABCFBD185DD42FDA1
+:10D890009195E0A1C97727BAB023A0FD00F9E55D15
+:10D8A000DFCBB3CE09E197CBF3C6BEEBEE1EC4F7D8
+:10D8B0001CC37DCAC5F7A5D3EF1F752517CF05B8C3
+:10D8C000E2FE981DDDFC7DA054F6FB81CC332E01D9
+:10D8D0007F5F52AE8F05301EF30E91FFF6D77FFFAC
+:10D8E000E31A07C185F26F0FFC743ABE3B57616FB4
+:10D8F0001E8F645795535D84F1D9413EA5799252AC
+:10D90000904FE505F0F7F80EC87BE006FBC4B703BF
+:10D910005DDCFF62B053CCCDE1FC9B89F7C64FDCE8
+:10D92000F7C26E3CB7E4FC4F58F4F76A65FAE5407D
+:10D93000D3BFF55E89F13EC94F93B453C83F1E353E
+:10D94000F1F7137AAAF54CD88BC8AF2CF90613EF70
+:10D950008E04F1EEB1F2B804C5196AAFD2D628FC34
+:10D96000BD822EEC3A2CABF5175BA1DDEC5A2BFDFA
+:10D970009EE353199C7E9E02FA41F96C96B5E955D7
+:10D980007B4A108E9FD4FCDCC2F958201DDF3BBAC5
+:10D99000A33ACC8D7C79799EF7EF38EF881C37F16C
+:10D9A000A377DD9CBEAEEBEE656EBCCFB8F6D09330
+:10D9B000F87EC3FF037EDA89FC00800000000000CF
+:10D9C0001F8B080000000000000BED7D0B7454D588
+:10D9D000D5F0B973672693CC244C42200F489800A9
+:10D9E000911401270981800837C82358C081100588
+:10D9F0004DC28467B46023D51A2D2D03493020DA37
+:10DA000080C120F53150A5685163B56DA8D80EE2EC
+:10DA1000BB682948F5FBDB86E18D8FD608B5DAFFB8
+:10DA2000E7ABDFDEFB9C93B9F7662680DAF5757508
+:10DA3000FDE3721DCE3DE79EC73EFBBDF7B9F9F68B
+:10DA40009E1CBB7F1863D5EDF96BD33D8CADC9F738
+:10DA5000DBBC7DA0EE72DB7D2EC66E6948B67BA076
+:10DA6000AC4A63B56DD08FB1CEECD9898C7D81BFC6
+:10DA7000098C657915C6A0FF1FF2A1A988B18F6D29
+:10DA80006C2EEFD76C9B65E867A17EACB95573F43B
+:10DA900065CCCFF82FCBCA029602C606D8FD4C4BF8
+:10DAA00065AC3E8379D7E430D60F9EC715F0F6F803
+:10DAB00014E8EFB21F5592E085C0642D9CC7DFFDCE
+:10DAC00062206376C6340BB4F783D20EFDDB877811
+:10DAD000689E2C6857E1B92DEFD83C06FD2AEC6C06
+:10DAE0003EEE47AE479633C5FAD95C8785C1BA1674
+:10DAF0003BE0DF30C46475D894B4918CADD8A8B83D
+:10DB0000E3E0D12297E7FA31505FF4BA8DAD81FAA4
+:10DB1000F4148F3D03EA9DEB14F776A82FB82DDFA0
+:10DB2000EE817D57C03619AC63D19631CCD31BCA78
+:10DB3000209485DDE795E58D1BF765ED86F958485E
+:10DB4000B3FB005E8BDC9A3D6558A47D61B3A205F2
+:10DB50005DDDEBE3BD2AADBB82B14908BFCADB7214
+:10DB6000EC0B5C587FDDB66218EE8BC341BE07FD3F
+:10DB700042D86FFA40F62AC375C3BEB6E7F0F90A79
+:10DB800074E32FC0F175F343FFF93EA8977A136948
+:10DB9000BC6A37EC3B074B37AD13E04070EABC176B
+:10DBA000C6F3D03C741E0B43419B17D7638579A104
+:10DBB0007E833B68C3791634E4DB1994FE0D7C1E2A
+:10DBC0007F53B27D38D4ABAD6E7B16C22F0160910E
+:10DBD0004AEB0B6E87A35904704971E13C6CFE6CF3
+:10DBE0005777F8548BF52E6A4EB62F363CDF68C354
+:10DBF000F39807EB698B72EE77E1B917E17A4AEC9B
+:10DC00000CDFB76A762FAE47C0F7E4ADF1EB592FC2
+:10DC100078BFA5D59603F59B05FEDE85702D42B82D
+:10DC2000847215DCF7ADF15E5CE73C7733EDAF0B4A
+:10DC3000BE9B011EF07CB1DB47F005BC083080C301
+:10DC4000A216E37946D69348E32E6AA9267A5B6248
+:10DC5000F5DBDDFA756CD99BAB005CE6D5C67B15B0
+:10DC6000803F73FBB3115F4E6DBE3E9BF609EB44E4
+:10DC7000B8267A3D53D247129E101E4B7CA92AE447
+:10DC8000F42BE7DBE4B5D27C9B705F453DD1A5F674
+:10DC90006A3AD2259CEF1A4F6CBAB433180FE6B526
+:10DCA0002F5282F54A773A95F429E952D2A9A4DF96
+:10DCB000476CBE50BA12E13355BD58EDCFA2C0E952
+:10DCC000A038871BC4B9025C5F46B8CAF617043D8A
+:10DCD000570C34D23B8E87E3FE449C7BC5C450EE88
+:10DCE000ADC322FDE5BC1529FC3DC47BC4B79F082C
+:10DCF000F860FF15D4DF62E0170BBBF8C5AEC6BEF7
+:10DD0000C82F9E55BCC82F56DCBB2FEB0E80DB8A7C
+:10DD1000A79C5E84C187CB1EBF2503E0C0AC413AFF
+:10DD200037B9AEC59FE7139F58F2F9959C5F84A25F
+:10DD3000F30B579EBFDD5B14A92FBAFFA9CBFC9C48
+:10DD4000DF8490DFFCE9A9170E8F453EC28236DFE3
+:10DD5000F0C87E1634FDDE56EDD2C38FEF777DDE40
+:10DD6000D96A3CAF852EBB4785470B1BAA89FFB2FA
+:10DD700074E6CD5522E76FC68BEA0645A3F7EA465F
+:10DD800005D5AF914F2FDC300BDE8D9C1B4CCCD8D2
+:10DD900028D827E3F095EBFFA3587F87E06F37087B
+:10DDA000FCBEA1A6C49E918AFBAD2E04CEC8E68916
+:10DDB000E7F316199F779D9BBB8BCFAF457A39DB75
+:10DDC000C6CFEDEC061BF19FB3BB12830CF6F7E157
+:10DDD0008A5FBE7D1DF4FBE0816DD94C359E1B2B07
+:10DDE000E4E786E5523837D63BEAB97DECD5F1E178
+:10DDF000A58FF2735BF8F45B7FFE9587F6CBF9DDB8
+:10DE0000BD7141E4C70BDA9EA5739CD7B4D196834C
+:10DE1000F4EACD21FCEBE2FFB5F96E06F0BDA16995
+:10DE20009B0DF9C417120E267A8052633A3A43B911
+:10DE3000A4A420FE853310FF647FE48FCFC23CB7DB
+:10DE4000DD1A9FC4AE88CC9397CFF17E616D720AC4
+:10DE5000CEB7B0B6FA3E3622220FCCFB3C1ECFE93D
+:10DE600065018C87747BBCC49BBD82F0D31255EED8
+:10DE70000EC8E7E7F82300773CE0433F67DB130871
+:10DE8000877EDF4EF022FF183C381CC47911BF7129
+:10DE9000DD76E09F0EE8377859F8135CC760C03034
+:10DEA0007C0FCBC4142A595FA86F8765174339507C
+:10DEB000E5E5E47CBE7F680F613B4B0D17E1FE2575
+:10DEC0007E9BF1D7CE1E6B1A887C2C9579EB3D1189
+:10DED0007C95E3487C95F81C6B7F575DE4FE8EE7EC
+:10DEE0007078DA13607F2997B03F40D6E294C8BEBD
+:10DEF000E4FA581EAC0BE6A9FADEF06DEB619EE386
+:10DF0000ABBDD9B5AE9EF6DB32B96F94FD9AF72959
+:10DF1000E9669183D334D04DAF30ACFB6CF3A05E97
+:10DF200028778E2B20DFE0BDE3B7C65B70FD725F04
+:10DF30003B56416758EBCE550E2A9F5C05843784CB
+:10DF4000B15DABD2A9FEF42A0F956DABF2E87975FD
+:10DF50007E0A97472C9C887A26E8039C1F84389D6C
+:10DF600074D40DA27DC9E7522FE87087135374FC57
+:10DF7000FB44AD909B2C7C2FD237AB1BC41E87A9D2
+:10DF80003A9A8F275A86217EF2F5C9F76EB3751239
+:10DF90003F648976CFE34072CEDB7E3F390DE65B8E
+:10DFA000DC9293AFC07B9575851D75D05ED990E6E8
+:10DFB00045BEB1D8E5598B72717120C78B72D1D92A
+:10DFC000927F6A0BB42F6EB8DC8BFD6F53980FE90C
+:10DFD0000BF82743B82D615D3FCD017C6DA9E06B47
+:10DFE0004B915F02BC96D4ED1BEC86F79778E3F378
+:10DFF00051BE2FDDA284E290DE2CAC4941395CEFAA
+:10E000009B827CACF341C58BFA267B08F8AB23C21C
+:10E010005F37E4F956E6E3F99F07FC83F187A20C2A
+:10E0200056715F6D1AEE83813EF238C375FB48AFBF
+:10E03000FF7F428FE968399AE819C6E18DFA3AF311
+:10E040006B16E4BB2B845C1B60EF3C7A37EA3389A8
+:10E0500016EF76CE2F7FE7C17DBEA1B2389237A2F0
+:10E06000BFE0A7037E50EC40FEB62271601AE9556E
+:10E070005B54E28F127F6AC49A176F2BEB8B78B3D5
+:10E0800018DA51DE6DC587C042D7B65CDD17F16A7C
+:10E09000D1C6C90F04408E650B389EB08667E1F982
+:10E0A0009CD99696B21AF5C2E5F59731685FB4ED42
+:10E0B000EE6C2CCF6C8B9F8BFC7E927BD6A464D8AD
+:10E0C000EF928792F3559DDCF8A9A0C79B975F9DBF
+:10E0D00086F6C0B27FEE7BC43D08E6075823DC3FDE
+:10E0E0006D730603D065D9AAF66C1568ECF338FF9A
+:10E0F0000E84E7B72C7BAE1B83FC5F09EEC8A0FE45
+:10E100009E3477147A97E529C0770FE0F3F21FBCAD
+:10E1100047E3FCC5B27FE63C787FD9F2E792709C7A
+:10E120006F6D3E34CA0DCFD70CF6FF0CC7FF40D938
+:10E13000B6C38D8269CBB61128B79F1376D4F41479
+:10E14000DF75F310EE6FA804F758F3D5B42B045F16
+:10E1500059AF0CF6227DD61F627637966E46FAF2DC
+:10E160001995D5A13E20F51AF9FCD57CAE0F9DE995
+:10E17000D59C8D7871D38ED66C942BEF27F27AC50F
+:10E180008EEBDF443EE57F2C8EEBED56467AF2C2F5
+:10E1900000D7BB590DD06B4664FE03F94E82F34D98
+:10E1A0005B0A0DF210F4129AE77D2B2BC5750CA8B3
+:10E1B000EFCC47FDEB8FD6D0623CD73F825E1BC8C9
+:10E1C000C173E27CEC8FCDEA147C1E0042427DE4F8
+:10E1D0008FCDCF250E7645F4B8C4916D21E473CB75
+:10E1E0009F4F2E50394A117EDDE296FCC935A55F5E
+:10E1F0002AE9636EC4D315BB5F99C2781D04616CB4
+:10E2000078DE2CF4B0AEFAF3CF925DB76C17D72757
+:10E2100096B53DFB6A268C734BBBD027849EB25CBF
+:10E22000D0F32DCF73B82C7FFEA87DA1DE1EC94B85
+:10E2300059DB0F34C173F9B6B99B518FC2731BCB35
+:10E240005842DBE7735783EA9CE07573FE6DED245B
+:10E25000FD707DDE41B2CB973788F1F20EAE1D48DE
+:10E26000FB9DD55BAF0FFD2DDF467095EF033CE8BE
+:10E27000BDCFE2934620FF0B2D4F6842B9AEDDE2E1
+:10E28000B26259BFDC4572FEA15A4B9E15E0AB2924
+:10E29000095ED4E3EA1CBCFF1D0949DBB1DC93C075
+:10E2A000EB9FC567939CFACCE27B7609F4BB433DB8
+:10E2B00010CF06E19177EEB3403DA38FDF5900F315
+:10E2C000A731A01E15E54748C1F68F5F3C5D88EB7E
+:10E2D000183F207C8EC1D26C4ADCBC49A82215882C
+:10E2E0007D0E0B1722BEF77989F3EB876DAC09E53C
+:10E2F0001DB3FAD86C781E42FE85E7FF0F4B10F96C
+:10E30000F11E25F463BDFE555AC0F1D617E76A52D7
+:10E31000609D6539FEFEB88E6B15DB70545D9847C5
+:10E32000CDC5F13FB6F176A9C74E144C384BD86332
+:10E33000F6CC7417EEAF5EC04BD1345607EB5833B2
+:10E34000ECA585882FF7743A581CCC3FB13381F483
+:10E35000DAACCC52926FF5022E8A2715650E7B69D6
+:10E3600098251007EBBD873982D89F394CFAAF2525
+:10E370005EC3F7943DAFFD03F97D3FF5937DBDA0EE
+:10E380007FBF3B146F3DF4A93A7BEAE1DF31B49FD4
+:10E3900083F908BFB97DFCA30A50CF3D5B7AD40F47
+:10E3A000E77D8FBBCDE11DC6C7D3EF63CF9DFF488F
+:10E3B0004AB144D6F771E7A9A77E39124B07C9A124
+:10E3C000897B549223E6F57C9CEEB1D239753A42B2
+:10E3D00016ECEFB2041505FBEF7B0FD737D1E10A3E
+:10E3E000A9A8C73B6C1FE9E50C3B90957CEA72122B
+:10E3F0002DEC0B5016FAD6F3F31BDFCB685FDE581B
+:10E40000C0EDA41B0B38DF95F09570631E8DE9E518
+:10E41000CCAF5D3B2A992542C7DF16CFCF7E3E9019
+:10E42000F48BB37B40CF88A277CAF210EA19A857C1
+:10E430000CD416161445E46CB994BA420EAB62DCE7
+:10E440007201AF729785C3678E093E026FCC786107
+:10E450003E77799EECAE03AFF4CAA1731CFE43462F
+:10E46000E7770BAEA3E31FFB1B81DC58A6AA1DF5C3
+:10E47000E7FC3B9E5F287E08EA159B2DA457A0DE93
+:10E48000877AA2E41F7EE40357D073AE07E631E239
+:10E490001B556A82777D14BE21F9853F01CA11C8D8
+:10E4A000379A891FDCA176BE6251227C624069786E
+:10E4B00038CAE10E30FDB13D6C69A3E7CF170C24DB
+:10E4C0007CE9CF0E64E073B0578A500F541D3F7E35
+:10E4D000F804889496759C3EEA6DC10797207F28C2
+:10E4E000777951AFFB386809D8609D2DC99C6FB40E
+:10E4F000DC9449F2FC6326F8C85C3BF1912B2D9625
+:10E5000000D95BF332C9DEEAEA9FEB09A2FCF9C548
+:10E510003FD5CBB660FB2C07C9DD1694C7506FB949
+:10E520007738B5BF20F9D24D9C2FB5CCD23212B07E
+:10E530007D565F0BCED792EA7F1AE936530D3E1116
+:10E540008FFAE4B712D8E3F83C47CB4079FB80E27E
+:10E550009BB718DF1FCED71D9E97F0F40E7E3C218F
+:10E56000F42775D4256E5FAF934FED4338BF1C1071
+:10E5700038FA20C22B3091E5A13EDF81F87945E4DD
+:10E58000BCC02A67752991734B359D9BC4D7800DFC
+:10E59000CE2F959FDF1A25F6F9A58AF353EA00BF1F
+:10E5A00089FFF3F3B943E5FC9DFD1A1448284FF4A5
+:10E5B000F1EF473CAFBF15CE850462F87684D7C330
+:10E5C00077266AB88F0E0BAB698B42B7EF1608BF80
+:10E5D000134A63A087F9821EE64BBC5D69C2DB70FB
+:10E5E000FFE4534E81B7F0FECF9DBEFFC279FFA27C
+:10E5F0001C1A850FF7FFB73A37DA3CC7849C78C1FD
+:10E60000E13F4A7CC13AD1A0AFEECF3F9D85728AEF
+:10E610009DDFD71FE5EEAE54DF093CBFF8C19D7604
+:10E62000F447746474DA709F1DF33EC842BD687E7F
+:10E63000DD6B445F17BBCE35CE11361C3FB934DFDE
+:10E640001686F7D34AF35F41FC393823CE131745BA
+:10E650000FD93B637416EABF87A68DCE427E77083A
+:10E660000EF000DA11566F22F241D65E497C6CB68C
+:10E6700098F35069217F2EF866E479598FFCF243B4
+:10E68000E09721D053DF07BB0CCBD3609785807F09
+:10E690009E04BB0CCBE36097E1F3A36097617964C0
+:10E6A00095979E1F2A1DD41E467DB959213B68A10E
+:10E6B000D56B8FA60F2FDBA5B290E457F0FFCD8F5F
+:10E6C000390DF59A877A1BEA4B5A40737044EA8BEE
+:10E6D000360C32D4A5FEB8A0E172C373FFCA424320
+:10E6E000FD3F16DE4D1CDEE827FF778237FE360041
+:10E6F0001CCAF01F80FF878AA6DA508E5B1D2CE0B3
+:10E70000047E928C7406EBB7CE51B85E04BF66A04F
+:10E71000BFD9F80FA02BAB8BB737CC5382C88F5023
+:10E7200017427B02E01A72027D95B92F3B89FCE803
+:10E730007AE45C2ADAF3412A6F6421A2CB4A16A656
+:10E74000FA7CD6996D87F21635B416FD76AF39FC92
+:10E75000558540C77F9FF6FB0E0589D15B3D04E9D7
+:10E760009BB952C8CE8C754EC021B97E8A5D47894F
+:10E770007DC16F0EF27D78EFA073C4EDB7C3397C15
+:10E780005C1D1E85F32F73F81F4DB5D07CCB0A910D
+:10E790001FD9FC437AC3F3B78A466721FF60BE3EA8
+:10E7A00006FB28D67C1B71B30087EA52809382F166
+:10E7B000370E9713E51C2E7B37C6D9D18F71629D1A
+:10E7C0008DFC94ADCEEC6CC4DB138D53B311EF56BE
+:10E7D0006F1C928DF83EBB69EAFBC8B727ABD3AB81
+:10E7E000F0FD63CD1CEF19BB95F4ADDBC5D91DF36E
+:10E7F000306F08DACBA7257A03B01F7F202789D690
+:10E80000CB34573EF45B28F6BDB079E9741C4FEE6B
+:10E810007FC18638C3F95F5B6CAC97337B04CF72E2
+:10E82000F09CED91763C7FB5A297BF07FBB9EE4F08
+:10E83000DBDE7C5937DE038589A9A8AFB0D16CF443
+:10E84000176AE4FD5870FD6C55F0CD9773237095F1
+:10E85000F8746BA1EF513C1F784C7136A0259203E0
+:10E86000B774F9B3F62421FC363A7F7DDF9508971B
+:10E8700077B87FA3D55945FCE3C369004758FFDE4D
+:10E8800069D76785757C41BE1F46FA067A3DFCD480
+:10E89000F5C447F695A7511CE6E0F3DCAF7C44D005
+:10E8A000FDC139D757DE0EF2F1E02E95F4BB83EDB2
+:10E8B000E75E41FFCCC136C52B406ED18F7BB07D6A
+:10E8C000D0BD23A1FD539F8DDAF7EE7A8ED669DE97
+:10E8D000F7FB62FED3380FF11537CD775CF097A3C5
+:10E8E000C85F86E03AF2A83C88FC05DAE7EC06FE51
+:10E8F00082E36FE1F32FB6FA88BF30FF5CC3FEBA44
+:10E90000ECE1C754C379D73CE434F115239F59B4E3
+:10E91000A19FA1BEA06190A1EE5F69E42F65A585CE
+:10E9200086F6C3368EA7070FABE4676301ED405E42
+:10E930005F1D7E9672FC5C5D1E47F472781AE733A9
+:10E94000B3E7001DA07ECF3C45684B7ED85ED6075E
+:10E95000CF856DB01D433DDA0DFFA1BC36C3B19C20
+:10E96000598F8575F8BBEC79E8AF5BDF6C6CD7E14C
+:10E97000B3195F3F427C7546F0F553763EDB3E901F
+:10E98000B71FE81BE17BF8D3F317C9B724FE02DFFA
+:10E99000AA42BE067CE533E463DF2DC87931ACE8DA
+:10E9A000F8CA45F2B18DCE7F921C6C75FE93F0F8DB
+:10E9B00050B9C0E3F22184C707670CC92279169CBD
+:10E9C0004BF4305FD847076DBE44F48F1E5ED93BD1
+:10E9D00009DB8F369411DD497A32CF7744E09FEC22
+:10E9E00037DFDA69F3469187FE9546FC613BE71213
+:10E9F000BEDF6EC2B358E39BFBCB79E69BE2BCE67D
+:10EA000079868C14FA665BE545CD8764D8F53EE9D6
+:10EA1000B50911BC54910F7C9618267B9CD349B93B
+:10EA200080DB91D2D189A447CC39472513F4DCD5BA
+:10EA30003EE7DC5BA391DE4A6D82DE6BE8FD32D1FE
+:10EA40006E5EC769A1379C14FCE3B8A06BD9AE6EAB
+:10EA50006BEC7B03E2FD4AD58BFCEAF0F442C2F397
+:10EA600033C1729AFFC81C95FC4CD3460EB801FD09
+:10EA70004C723D72BEB219E712D18FF629C00BFD60
+:10EA80006265366F9F68FA85191EB1C695F8B3772F
+:10EA9000DA90C3B8CF43C847B1D56F84D3217C1F68
+:10EAA000DA676F5329CE6686D3BE6943882F1DD996
+:10EAB00029F827C015F5EF9A878CE7BAA4C569E253
+:10EAC00037BD0DEDB3CBB95E26F9B55CDFA19583FB
+:10EAD000FA30D7C59FB71CE762F1E566F13E8ACDF3
+:10EAE0002F48FEA618C6030BD134DF4053FB50530A
+:10EAF0007B81B17E91787C54E08F943F47E3BD9554
+:10EB0000D1E27747AE89ABD1E7256C1AC9FD369BB8
+:10EB1000468A78F725CAED7B471AF9E085DE977CAF
+:10EB20006F61A1AF6524D269A88CE2D817CBE774D6
+:10EB300072FEA191B8DEB062C7F7A55E5523F4CF8F
+:10EB400056E77DAF22DEFD45D8037B67C4111EFE6C
+:10EB5000F529AE77FDF5E7A7499FDAB7FB8EA4B09C
+:10EB60000E6F9609BC39DD3E2409F1F0585B7D92A9
+:10EB70009EBE65FB19783E7664445EC75AF7979649
+:10EB8000D7CF0A7B602797D737599BA3DA03FF6A51
+:10EB9000393D595D497A88595E9FF67892DC041FA9
+:10EBA000417742AEC8B8CF5F6D9E24F4171E0B723A
+:10EBB000B922F9FA41131C4E201CE222F224161C41
+:10EBC0008F8BF7651DEC511BCE5FE6F0BE928AFE7F
+:10EBD000970D8A17E35E989E520CE77C604EFE8F7D
+:10EBE000D16F25FBCF2F52492EC8793EDAACB4A1A4
+:10EBF000DFEFB595FBB2BF07FDAB773989AFCAFE32
+:10EC00008BA61BED2CB33CFAA8F193B746C3BC65A9
+:10EC1000CDAAD701EF954D2FE9C3F56AB7118F043F
+:10EC20005D9ADF5F6AAD8D7A9E66BE57367D35E9A7
+:10EC3000EB87C47A0FED1D63F324767FAFCCCAE176
+:10EC4000B014F4CDD530EFD2864F48FE2C9DAE7A6D
+:10EC5000512D79ADA97E26E2FF519FCD82F471A49A
+:10EC6000ADF74C8453608EEACD85FEFB9B06111DEB
+:10EC70001C6BBABA2FCED74BC0EB747B9C05FD4FF3
+:10EC8000A77D3616227B3944E7F9514319D9C7A726
+:10EC9000114E78FE5637D149BF22EEC73A0AE370CB
+:10ECA000FBD9C3F4F1C02341B53418852FF513F314
+:10ECB0001D3FFF43C2AB5783FB08EF8EB6F1798E41
+:10ECC000AF7427619CEBB70D85248F8F4D87F1A121
+:10ECD000DCBB7BE97D98AF777A834AF2E374FBF57E
+:10ECE00033B17E688394BB5C1E558BF957EF1E3D94
+:10ECF000A318DA3FFAB98C6B72BA5E20DAAF9E7550
+:10ED0000F8BE62BD3CDB35D7B0FEC3C1E3646F9D86
+:10ED10006E80B7018ED53306D9D11E5EB4CB786E26
+:10ED2000E51B8C74083F577EDF489ECBA206D06758
+:10ED300081651D9D5E4676F4EC406F93BD6DB4E336
+:10ED4000CADBB8BDB7E0E1B2A210D269E0131B9EE6
+:10ED50005375739C619ED92B8D76DA02935D66B6EE
+:10ED6000DBCCF245C263B9ACB755D23ACC7A4B375B
+:10ED70007963ABAD8A961F5155C4F5B16AA0CB74C7
+:10ED8000F42B33EF0CB4BB8E017CD7C378D576F768
+:10ED9000DF73414F3EA2B2F1E44CF30658B1F41BCD
+:10EDA000E8E65BD0A09AFC1346F882BE7E0AF5F92D
+:10EDB000A6DE420E0740AE24A29CD1FC4528272E99
+:10EDC000D61F70D1FA7695D0B7AB0CFAF641ECA20B
+:10EDD0007B7F6FF9F5E4773A3CE37AD2BF0F77F99E
+:10EDE0009D7C06BF9384EFE1E965067D52F7BC1771
+:10EDF000EB813FC6D21F8F0AFE7A44F89DD60A39AE
+:10EE0000D320E4CCE1E9C22E4C65442F56ABC62E8C
+:10EE1000862F5D481F5BD0D0CF745E4639E32CF15E
+:10EE2000B716015EC4A50F353CB7B90B8C7463C22D
+:10EE3000CF7E8CFBC1EF46DB1EE05E5FCEF347F179
+:10EE400039E6B148BC64D01FE573F986A1C1F5BCB1
+:10EE50003DA01660DA1B43158DFA5B795D53783D52
+:10EE6000E012EDAAC85FB341FD688E772EEA519893
+:10EE70009FE34CE1ED8822FD009F935222F88FFE24
+:10EE8000F9781E220F24C17BFDE7E4BC8CF48D7958
+:10EE90003B9741FD5745398437E9E89A2FA0F14364
+:10EEA000989F13AE9F40745CE648E2717690B33D44
+:10EEB000E3DF6A6EDF94F6A6C9FA5BF97A62E2B321
+:10EEC000E877097AD56B442FCC42FE938DCE11366C
+:10EED000C4DFD92E5F16C201F0BDF276B4D35FB4A1
+:10EEE00093BCDC5BCEFDAA07A78D7EF836783EE2A8
+:10EEF000191791F1C1C580E724173A13F5787B649F
+:10EF0000E5710BE6D3FCA19D79311FF1C8AE8A579C
+:10EF1000DE8471F6AD5C786F11D2D17ECEC7CDFEA6
+:10EF2000D89267C6913CBB6E864A79DA874A55C645
+:10EF3000F97C82C1AE88F86955C28F4FF758A91D78
+:10EF4000F3AAF2308F0AFD95986F552ACE45E81541
+:10EF50006DE21C9F10FEDA1D826E5A04DD6C127485
+:10EF6000B3CEECAF7D88D3CDA1763004404EFE6E9B
+:10EF7000FAC289E487DEC2289E9C334D5D3F12F6BB
+:10EF800077799CD786F02B999ECFE13947B1601CE9
+:10EF9000A6AC34DF86F47E796F8FCD477AD62CAA63
+:10EFA0004F9A934376FBDE95658964BF277AB390C9
+:10EFB0002E074F8F0B5992D00E2C243E71E5198BE2
+:10EFC000815EF2430906BA1BFA588AA17DC8964CA5
+:10EFD00043BD8F6FA0A17FEF52233D260C2E30C979
+:10EFE00025AEE749384F56C791DFEA48445E52BB29
+:10EFF000B4EFA4FF4DF6076819F85A93D0074740BD
+:10F000001DF3E2D6CDA97760FEC3A76D562F1FBFB3
+:10F0100082E4BD23E77907D2098648314FAA49CA5D
+:10F020001FE18F671A33AD6B03C378E9915246F83D
+:10F03000143F9829182F6811E77DBF9817F86A893F
+:10F040008DFC6EFC1C7B4FF7513FE633DAA9E94893
+:10F0500067058827FCFD27C4FB3B04BE1C29FDF186
+:10F060009A04C487B98CFCF793D5656B302E78640D
+:10F070003A233A690BBD9480EBC77130CFEF57B19B
+:10F08000C699F3DC1F6FC1F5ECB4D338658F815C92
+:10F09000043C197AEDD10FDE46F06D71EF8B67DD20
+:10F0A000F5E9118F695E044EDE1916B25119D2903E
+:10F0B000FFE49D39A0615C6FE85F777EF034C3792F
+:10F0C000B95C6812F86DE6AF3F7DFC170BD663B9EB
+:10F0D000636BC17B507E63CD839975503EB1E65B17
+:10F0E0005B6FF344FC9F3B662EDDDE02F521DFFC07
+:10F0F000FE93CF235ECDFCFEFF791ED73BF31F7F2F
+:10F1000076C1FA2FAB4F6448DF727DE679D259930E
+:10F1100082F14DE4A3C497AD01AA57078C7A7759C1
+:10F12000A9D3807FD8DF0AF02BABFB29C589D3C5D3
+:10F13000FB8766DCADA830EF7BD59CAF1C5CD5D9D6
+:10F1400032C946FD43D81FF824E55DF6EB0F6C0588
+:10F15000DFB707148C6F8382E4C5B86D06B4233F14
+:10F16000671E0FE93BD9127F055FC1EB0A8CFC7B60
+:10F1700056C2B33C115744FE8BFCBE6ED440E2CB6A
+:10F18000FD5C4CC3F32D7D618382F966EFFA3D5E31
+:10F19000D20B56B1CD93C0EE1DAAF2FC89BCD2773A
+:10F1A0006FC07381AD5AFD059171778ABCA6D217E5
+:10F1B0005C947FFDEE4ED736F2EB1F9869D1EB835E
+:10F1C000137FFAD1CF7E8BF8551D4FF865D65B0EB5
+:10F1D0000AFAE8AADB3C0FDF86FAFE8B0E6E27697F
+:10F1E0009E2CB2BBBD9E2CCCC3E9EAF77D191FF360
+:10F1F000FE19F9F9EC0A27C50D649C482DFDA411F0
+:10F20000E9717E716D11EAE399780EBD23F1E8F79B
+:10F210006EB253DE404049A0FCF25871E79DA372E4
+:10F2200044FCA5F60A5A07AB1D8DE5B9B9F50FDB0D
+:10F230003DB1E5558338D758ED363BF3478B0FEF9B
+:10F240001CC5F5D07A3C079BEE1C5C7FB801E3BC83
+:10F25000B1CE81598305942FE9700CC67C8E34F1B0
+:10F26000B8D5F983B7505E751CE6F22AADEEB355FA
+:10F27000487FD20F5195CEBAE2601ABC6713EFA552
+:10F2800009FD1B6918F5EF2A11FFE9A86414FF496D
+:10F29000AB3BFDDF089F8D62FCAA77F8F8766B68C0
+:10F2A0002FE24B95CB4372A7A34F9217EF27B1F3F1
+:10F2B0003CCF2493717C4C33EBF7A809E9D69D969B
+:10F2C00050F13B541FE68E672127E28FE2A079338D
+:10F2D00057C6517EAAD4AFD2EAEEBE551D61184F73
+:10F2E00041BDFADD0A6E3FA399DB356E8E41AF2238
+:10F2F0003DCBBC0EF95E878DB5A33DA9D3B3480FB6
+:10F3000063FA790619EAC22F66ACDBD2ED063EF14C
+:10F31000EEF9B25EB55C0E785247717F1CC243EACB
+:10F3200063526FEB36AEA0779D7E19407E21F321AC
+:10F33000BAF4A41A9D1D35B0FB7B32EF4C9E83843A
+:10F3400067ACF79D25DAB951941711A271FC6218C8
+:10F350008BD3954DF035F14B605B3C2F5EE8A1A05F
+:10F36000451AF211A45E29F97387E0BBE19C30F9DC
+:10F370000165BE777F78271BDE8F1F9DDC952F8F61
+:10F380007AD091551F533CBD0AF550983FBCE643D7
+:10F39000C37D92A69292F8D1E46F33E63DE8E2A8ED
+:10F3A000B45EBFE09B935517E59F74B0042FF2AF96
+:10F3B0008E80D0C7FEE4247D4CF20B337F98E1357C
+:10F3C000F2FF6B8B8DFC7F96D6DB144732FAB3CA03
+:10F3D0007DA6F8F63BD30C7C53F29F3B542F6DC2B5
+:10F3E0000A821EE334FB05BF7C5BE88176564BCF77
+:10F3F0001D98F73908F97F1B952E7680CA24D649C7
+:10F40000A59BB9294F268579A94C653E2AFBB25A9E
+:10F410002AD319CF8BCA646D54F66707A8CC669DB2
+:10F42000547A98DB82E540E6A57230F351E9636EC9
+:10F430008A7BBF9318CE3A04F09B7E3D233F3C630A
+:10F440003FB9518373EA2897754020A4ABC94C207B
+:10F45000DFE3376A589F26EB3B78BD84F72FFDE545
+:10F460004F7F141846FC46B43FC1DBBBEA3B6F2C10
+:10F47000213AB5507D0EF687FA8323B569A3015F63
+:10F480002B4733E2A3E70BB56FEAEB0F156A33F4B2
+:10F49000F5978BB46BF5F58F0AB459883FB29E5936
+:10F4A000A895E9EB371769E5BC3FF71FBD63D34863
+:10F4B000DFC50529A338BEE1CFA9FA2B090F7729AB
+:10F4C000563CD738416F763C4715E9C8EB88C3D224
+:10F4D000C7F377C2F1AEB0D3D283FD63A2A330F2FB
+:10F4E00027C0C3E18AFF665C8F999F280191079826
+:10F4F0006A8C8300BE93FF2CBC92DBE98C456F972E
+:10F50000F35E08CF99A6F3DB0E8C8C1B6B1F66FC99
+:10F510003D20F4BC8342CF7B47F899BBF61DB6264D
+:10F520009F7244E838B67D6865A7F4FCB2DBBE3F45
+:10F53000AAB4015D87EBE2DC28EF3AE2D9DB68A7E9
+:10F54000050EAB0CF58C4B5D6F69E1940708EEACD2
+:10F55000BF9BE20A725EC1673AF09FA0E75CDE4B98
+:10F56000DA975E078737B73B92C5BAEA27A55C935F
+:10F5700047F137AED70FB31D983515D699B681FB35
+:10F58000479390BE3114F6CC9FDC18176B9E6C61CC
+:10F59000C8A71A05FF34FBDF364E5AE1D6FBA71B7E
+:10F5A00093820AC6233343F1DC0F91CA82F12847C4
+:10F5B0004BBDA594071350DDA558AF6033F3A0BE33
+:10F5C000A045F594C2BCFB5A9E5B817ED84515765A
+:10F5D0008A4BD8B42914BF96F9182902CF1BD6C577
+:10F5E000794308C73E2EF2CF0E6B2C28457BB7DE41
+:10F5F000959282B89852B184FC87F52EEFEB784F44
+:10F6000023E0B6509E21736B8E32D057B6DD662D47
+:10F61000453E9EF5ECC82455B7EEE30D67E331CFC8
+:10F62000FD51B785DA1F5D39D1B1C485F711C15ECF
+:10F6300080729FFB9886FAFB56E89306E3DD5773CA
+:10F64000ACF9B21ECE31A9D46EC05BA7D7588F33A8
+:10F65000F91F6D26BDE0F06891F7318A8DC273BE47
+:10F66000E2C9F364FFCE7779C83F3EB149A17C97E8
+:10F67000F05E6F36EA9BC7EF1D42FEF0862655F816
+:10F68000A3BDE48F0E67B16CBCB753DDAC90BEAACE
+:10F69000367CB21ADF1B90E7C9C07106783B33DCB9
+:10F6A0003AFA7BF4FBDF8D4779D78017CF088F18A4
+:10F6B0008D23ED55793FBCDA7DB692FCBBCDBFF70B
+:10F6C00021FC93350BD1CC115B301DCF7F7DC96CF4
+:10F6D000A24BBC6F857A4C377DF47358A7EE9E41E0
+:10F6E00063EAC0049C3782BF1AF9CD4F3417927E6B
+:10F6F000B4BD6922E5F59BC7B967156B43BDB5710C
+:10F7000095A32D9AFE7B4FB62F1BEF619FDC58B25D
+:10F7100096C1F99FDC7B533ADE5B5FDC1CC7E23DA0
+:10F72000DDFB9FD8389AE65B8CF7A171DEE659764F
+:10F73000942B535B4AEC08B77B56CD7D563FCFC721
+:10F74000257E6731D09FB3F959C213170B0510AE50
+:10F75000BFB94ACB46FDE2442E8B9A97D9A798C7EA
+:10F76000177F7B958FEE999CCC8ADE2FA398C71FBD
+:10F77000EF2BF6487FF1DB4B53C91E7423BD1E6F80
+:10F780002A4C42BCB5611C1DE4A2ADFDFC2AC4FF9D
+:10F7900073150BDF5B0AED8DD3AE3B83E515F65A8F
+:10F7A000D29BD91F54A207D00BE9BED7DFE638DCC5
+:10F7B000F5BABC40D41F35835FC3C7D0FEB035A9AE
+:10F7C000213BF077DB9E53A48723BE6A3AFCA5DF7A
+:10F7D00028A1CF8B7C8FF451747F8E7E8DD75C17E0
+:10F7E0000C318CA32C74443BC7D8F3EBC645FD7693
+:10F7F00012D3E275F383540C915FDBCFE7EBEA277A
+:10F80000DAC10CD5687D422F37B7CBF50FD962A48A
+:10F81000CF6FE2F91445F4F358EBFD46D0F85E4D96
+:10F8200031137916330DF432546D5B3106CE8DBD34
+:10F83000CBF93FD875CC17255E15E1B3B0F6BE0203
+:10F840007E00CFB5A9B3C93E89B50E7BF080963353
+:10F850002262BF7D23DDB82ED9AF46E05D5C908586
+:10F860006C495886E85E461CBC8FF2FBD38AEFB821
+:10F87000AF894217B234F32DFC79F0BB11F2AC4CD6
+:10F880007C02D160B0D4472CFC7D4DC7E7123773A2
+:10F89000FDF7C41685F4DFF51B795EC4A741A89374
+:10F8A00072C1CF09558B2F84B2E3D2DD1F5CF242C7
+:10F8B000D37D433D06B82D62BA78D29927EF7A1BE3
+:10F8C000DB4F3F7D970F977B77EAA224CEB78E2E32
+:10F8D000C0794E5E6E277F0CFE1C123FA0E3D26003
+:10F8E0009C010FD7EF7E72CB02943BBB1D5E4CAFE9
+:10F8F0005BBCC5D81E97AEDB17E3F81530C0293CBA
+:10F900007016D0D191EFFF84EE792720FF447A5C06
+:10F910001947F7BBCC70FE6074D7F742983E0EC70C
+:10F92000C4BD0E4957C736D49F54619CB52BED1EFC
+:10F93000FA2E82C9FE3AE299A5A5EBE2BDF695FC46
+:10F94000BE25D3DB890323FB97E31E092C74785C67
+:10F95000DDC7EB867731C65B58A2ED2A06845D567B
+:10F96000E27B1ACBE31B16D2BEEBDA571E7913FAF1
+:10F970003425F87F867CF3D88641A314BCF762F562
+:10F98000D0FDBF86064B3CF2FDE6366BFC6084770B
+:10F990008385E47C735B6AC260944B2E0BC549512E
+:10F9A000AEA83AFFFE49C12723F2C397A4D77F121E
+:10F9B000043E9ECC13FACF24AEFF28CFEC21BDA38A
+:10F9C000A191C7A9A4BEE116F8E316F1C858FA0F31
+:10F9D000321E5C7762D12237F2B5C624FE1D8D45FA
+:10F9E00093BC01BC9779B58B91DC1880972350CFDD
+:10F9F00072B1E05498477573FDC6DFCC489F4971DA
+:10FA0000B9BC08EAB4966080D6AD713A73C07F087D
+:10FA1000CF843C8DE1F856935E6137E90DAAA9DEEB
+:10FA2000512CF250841EC184FE2DBFDB90786FCF25
+:10FA3000793DD2AFDB2CFC13A03F05E8FE47310B2C
+:10FA400022DE324DF3A4F68DD801E877C4F6F462D5
+:10FA5000B6AD5E177F52B457C96F20FD92D2FF201A
+:10FA6000FD1C238AC15E4BD2F9237E0DA6A54AF167
+:10FA7000B0CF104F72801D903D398C29FC9AC597EC
+:10FA8000D4D3EB2E2EEEF3A397F83D9F064B82774F
+:10FA90007B4EF77E19E3B8DF2C611FEC0DF5DAEB36
+:10FAA0001D749F66B2BA8BEECFB78EB4F03C65760C
+:10FAB000C08DFA40F218CE776F2FF1B9C7202377A7
+:10FAC000F972106F001E011BDEC3137EDBACDB0777
+:10FAD00026A03EFC5EC6A98DA897071A2DC46F24E8
+:10FAE0001C73565B36211AEAE273216B4124CEB6B1
+:10FAF000DE773680F77ECF5FC9EF1125CC3AB1179C
+:10FB0000FDA0EB065BC8CF7E77A246713BA01F87A6
+:10FB1000CAE375AF63BCADC9939282DFCF793A99DE
+:10FB2000B733718E0F24F6DDA6CF17E9BC92EFFB39
+:10FB30000125BABEB2F74ABECF8EDD00C85EE4D75B
+:10FB4000E2F678607F85E6D2D591F6E0FD1F06B833
+:10FB50003D3D6AF7FE8AC060B29344FBF90AB2E702
+:10FB6000D1C708ED1B776FAE40FBFC919CE8F3DE3C
+:10FB70003E8ECBEB47DEF00F407D36BC1BF0A75727
+:10FB8000B4F30D314B318D9B8D71A9F09D7173A331
+:10FB90007D8FE6CD719C9FB4425B5CAF881EDB5AC3
+:10FBA00061D65383C4AFCED51C7B85D2AE817F1482
+:10FBB000013D24B3E8FCF2C2FAAA371DF5CEFA3BA8
+:10FBC00095B5C83FEA415FC5B8609ADB4EFA6A4313
+:10FBD000F2774BF05CCED53037DE5BDD0E6A1FF27C
+:10FBE0002FF4ABE27DD4A9759CCFF8DDDCCF0A768B
+:10FBF0009CEF6AC4C70C2BE1A3D45FAD159CFF5CDE
+:10FC00001EC7F38B3B925DE4374DAEE3F9C4CE00E3
+:10FC1000E8B3B8BF493C1F5883FF900F49FDD63564
+:10FC2000CC6AC80BB69BF286ADA63CE16F8F31DA89
+:10FC3000338945237BD4AB7E0DF62FAE730FF01FB7
+:10FC40002C43600763F912D8ED58BE0C763BC60D05
+:10FC50005E5D9547E5EBABBCF4FCCD55C5544EC895
+:10FC60000E535C91FCC8E4BF612185FC7812BF5E35
+:10FC7000EE3F11F1BD84B76FFFD5CC4703FDA13D29
+:10FC800055F40FE45422FE75D5D9B595D8BF2A9DF9
+:10FC9000D79D636754223E4E9AACAD1B0378D2C702
+:10FCA000E2AB6EC4BE77C579A3D9F77DC7CAFB5E48
+:10FCB000D1ED77869F3A30FA735A894FC4F0E73C0A
+:10FCC000A0F075EC7D61F343E887EA35CBEA433C6D
+:10FCD000CE1E68F4F37F3E86D3C5D4B19C2EB3DF2D
+:10FCE00004FAE801EE923E62B5D7EF061488425757
+:10FCF000B26C4D64E3E99E75A57D6EB47CA66D8201
+:10FD00006FC61CDFC53C715744E8ADDE65A6B73051
+:10FD1000C577CFD57D672FCACBAF4E6F8CECC37044
+:10FD2000A546F23A0CF486FC5CADE1F4A65AF93D26
+:10FD3000CBAAFDDC3FB21DE90BCED98FF406FF9CA8
+:10FD40001AE0F53413BDD59BE9CD65A4B730D21BBD
+:10FD50008C971CE0FA85B3A2ED6BA5B73F7F457A7F
+:10FD6000FBCD5561CA6BE8C8A9CD40F8B48AEFDA7B
+:10FD70005D2A1DDE35D6CEE5C1708DFC020D388EB4
+:10FD80008BF4F90DF8BD94A9FD575B53007ED35356
+:10FD9000F3E97B023963FB0A7A38E0427FCD024DFA
+:10FDA000FB94E8EBBA33744FB18F85D36FDFB1AFFB
+:10FDB000913CC86A3C386B2AD2DD9D2AC949F3BE02
+:10FDC0006E1A2FE25B0A9F174E2E431FD77308BA95
+:10FDD000F4DC59AF38501FAF66DEDC1CFA3E0C7DF8
+:10FDE000B7E6870D7F73E3B8378D4FA1757956BF9E
+:10FDF00093ECE7FEB574B4DFE86A7241777A845F0A
+:10FE00009BADAF819E93C7F6E09FBD10FFB84FE852
+:10FE10000F78F4A837F8C53D4C19178949CF263F0C
+:10FE20006E4CFFE1700E1FF3FB67855CAD17FE5F44
+:10FE3000B3BE27F73FA4C43F0CF7A7B85EE57EE04A
+:10FE40003DCC83EB9471B3AE3C23A91F0658B01E82
+:10FE5000F56D2BA8327DB9BA81E375E51F093DF137
+:10FE6000C512FF681C771BF3EC45F9E6F2F27C053E
+:10FE70006789564CF0FC927AE086124D1BDB035EDC
+:10FE8000BD38459B34B628763B3B0FA38C8AC4B55E
+:10FE90004A6659395FA853041F70ADB543BD351983
+:10FEA000F89907F576BE6F37F00D0FD919463B620A
+:10FEB0000A3A23916F201F21E06AD3312F32498CF7
+:10FEC0001F91D7E157502F0D036C3741535280CB10
+:10FED000EBFAFD9CAFD881AF505CBA98DB09F29E7B
+:10FEE0008F739897EC2F55EBD97EB09AECFB256376
+:10FEF000051F296023116ED916CFFD63E079E183D8
+:10FF0000930F8D81C7450F2FEE8DE274F4B6C63284
+:10FF1000FC6ED74D8F9FDC867ED231FF15C7C4F7AC
+:10FF2000D128CFE05F2867E85CB6ED79B72260455D
+:10FF30007E151D8F0BAFE2782CE3AC3DE07123E121
+:10FF4000B188735E021EBB2E80C7CD884F51F078FA
+:10FF5000E357C4E307715C0D0F01E34653B41FF58B
+:10FF600084B75B276B8FF6D4AE8B1FF0FC21564312
+:10FF7000F6B38C5F9AD7D388F235B707BFD4BAED02
+:10FF8000F168CFD6D76C7F03BFDF585FC7EDEC8E2B
+:10FF900044AF03F38D03BF57E9BB54B1DE47BB3B0E
+:10FFA00000CC72E8553C0F7ADF9D71A109304EA656
+:10FFB0008BCBDB4C97C630EFDBEA0EDBFC89A8AFBE
+:10FFC000F918DA19F6540B0BE8FC3157D80E905C8F
+:10FFD000EE00398EF401F4C9E92D998F23E5F384FD
+:10FFE0003BEFC7480EBBAA13E4A08E4EDED85D4C93
+:10FFF0007EB8C4A2E757E07B6AA5DD83F83DE173D4
+:020000023000CC
+:10000000909BBA794A4013D1D7AF766418C699EC61
+:10001000CE31B44F4DFF86A1FD1AC0173BC5B1F9D3
+:100020003D3FA9D74CF3E41BFA258B38C737F3C6FD
+:1000300018C6B3AAE7378D46FA177AC438F80FE91D
+:100040005F35E90B667DC2AC3F9C1C6BBCBF32C206
+:100050002AF2D0AC3C3FA29539E8FB12C007E9FB7D
+:100060000555913C01A29311F6F0F67BD0AF32CF4B
+:10007000E10DC0B386DDD7A4578F8CF8CF5AEBB80B
+:10008000DFAFBEDDB10DE961ABA04B495FC3128F9D
+:10009000CD6324D7ED0CE5B1995E65BE93F41748A6
+:1000A0007F8252C3FD0CADE37378DE91E03FAD1566
+:1000B000DCFEFD91128A570671BAF4A444BE339750
+:1000C000CE94C0344EDF5A8A2855918F2AF35E7140
+:1000D0001CB4B3D3F97CEC759E37B9FA7BF8BE9BA0
+:1000E00005FA0B7F46564AC44F81F909CBF87B814C
+:1000F00069E2BD0122DFB2175F7F68B2986F049496
+:100100006AAD26FCD37E2AE3301E0EE540C59B80F7
+:10011000FE8F41AA8F022D4922BE9E29E2E94E257B
+:10012000C499C797E42357001BC5BC0496C2BF13EC
+:1001300032F1A72EA6127DD8B7A33CBAFBA8F77759
+:1001400098AADB90F8DDB726C0F3A6DFAB5EF49388
+:10015000DE9D15780FE9DA0AC81020BF96AF1ACFD6
+:100160004D9DE3704F85F7D4C0B6D518DFBDC21ED4
+:10017000DC4BE7B9268EE83D0CEF213E6C4D043A8E
+:10018000457C454FD7A8483E908C6384C7781D288E
+:1001900047C3D88FFB9B0DFECF28F926E42FB58AE5
+:1001A0007A836B3BE9EF6B53EDF8E54CCCEFC9AECE
+:1001B00043BCEC93C0EFD3321E371880FF18A4E382
+:1001C0005BEEE87E4DD0D7080EE1D54BD37BD2BB9A
+:1001D00062C6515C96903DE9E2E3288D375F170CCB
+:1001E000E9D629F7BDD6B55D59C02E657E668CA3CC
+:1001F000D4302D7E4494384A38A8E03A07D4F038F9
+:10020000CB00E1AFFFB2711475FC978BA3C8FDCE94
+:1002100010FF9E0E882DEE0D533C81CECB12599FC0
+:100220000E7E8F113F22DC102802F56B45FDAD5D7F
+:10023000073F7A12FEB97FE74BBBB0947ADC2CD132
+:100240003E73C8677B30776BD6BA15228E658C3FBC
+:10025000CC00AB4EEFE7C7FBFFFAFA2CD37A265A55
+:100260008D7182492E63FF29A9C6F6D2FE71DDCEBB
+:100270000DFDF2B45FA5FB7EEF76DEC7F877A374C1
+:10028000E7A05EB8EEC0BC398CFB78BAE3893E0EBD
+:10029000E07BD1CA524622BE58482FDD1A58BAB95F
+:1002A0001CE8672DC851CE8B3D06FA8BC43D4A35FC
+:1002B000C427E9EF8F454FC75C03C9FF3FA06E6FAE
+:1002C000DBA4DEAC2B0ED094E0FFC5958037035C39
+:1002D0006715D44306D4BD4CEDD7CD2BEA118F72F0
+:1002E000EBF6B54DD27D0F30D7EAB3A0FD9C5BF79E
+:1002F0002A3D8FA9CF77E72394B7962BF042E605E6
+:100300006EC5BC40807B6E8DF8CE6F4BCFF96F52BF
+:100310001E36E8F2FB2899C1A330FDF852EE75F3C2
+:10032000A733EEF795F375E5059AE6ED927F6E2E0D
+:10033000FF9C25FE0E845FD7BD0C718F03F61D3523
+:100340000FF4E49522DE143B8F8DDB9D735E7F0FEF
+:10035000C7BF64BB33C6B813B2C395D1EE47FD4DDA
+:10036000F8AD3AE2C359E837E8B045D7EB3F9E34E1
+:10037000E51F57F660C761DE2CC232D63ABF6CDE8D
+:100380006CF6180E2F196F95F9B3322FF642F9B3A8
+:100390005FD50F3F44F8033AAF64DCCF6F8A4398D0
+:1003A000D79B33AE2BFEE019D743FC41F67F2FC31A
+:1003B0001ED52F5E3F5EE049F7FB47941F0AEB4DC9
+:1003C000D5DB41F23D99976F1E0FECA2C2713A7FC7
+:1003D000A07F752EF9FB74F696CC8725FA68157EFA
+:1003E000882E3A30EB85221E62D60B657C44A9E04C
+:1003F000FE09A08F89E3FA70BD0BF3D2A59D27F308
+:100400004965DE28E685523CEA4BEA555FBB3DB5BF
+:100410007A32E575D5BB27BEFE55ECA9E5E38DF62E
+:1004200094DFC5FD0E7EB4A78677B7A79A4AFC373E
+:10043000E13999EDAA233FF890F263C10EBD99F01E
+:10044000EAABF209937FCA3186E3B794D3D29FB661
+:1004500077B0C5E0779DA2AEDC4BF9E235DCDF92E8
+:10046000A9B5919D6677D93DE86FB14EE274641BE2
+:10047000C6821A8FF3927F45E695A5B8B83D65F61A
+:10048000CB483B312CEDC400FFAE4AC77E1EB7758A
+:10049000A2BF053B9672B926FD2DB654E16F31E53A
+:1004A000633B4DFE15B3BFA5659CB0BB84BFE51192
+:1004B000C5730F92FA735B26FF1641F1F387163B63
+:1004C000D1D4FF65B0F19BC2DFF2A00BD6B7FB3DE4
+:1004D000A3BFC51CFF8A12F722E7D59BE3B653DC06
+:1004E0004DC257D2ADF46765D6F1EF024C51772972
+:1004F000C85F5A5D1CBE2AFAB35223FE2CE5998FC1
+:10050000BAFC52981FD73D4E5EFB06AED30A0C676D
+:100510007D34FF9680AB391E9554C7FDE35F973F4E
+:100520002B34CEE8CF2A78B0F07EFC3EF1C887CBE2
+:100530000E61396ADB777ADF0065F1E3F79761F9DD
+:10054000F737C239A8779AFD58CFE0C78CFB74877C
+:10055000AF198E124FFD35124F5D76A2DB0A0E47A2
+:10056000339CD2348EA7B980A7A02274E15F4732B2
+:10057000A7CFCC49DED7D1BF3660989545C3636B12
+:100580001DBF0F2DE1B855C031A56609F909CD7819
+:100590003AA0E5D2F0F38C097E3FDB52780FC2ED32
+:1005A000F987CA7E8BE52F82DF7122DCDA1FBBFF61
+:1005B0009B027E19F45D5C13FC26C580DF042FB717
+:1005C000AF274FF4FF1DF9F335C021D01FB2BDA9ED
+:1005D000C0618C0319F969DAD7E49F0A77F153F601
+:1005E00076EE25F0D32D26FF545A80D34D5AE028BD
+:1005F000D16726D0673CFAAB6AB81E09623FE8545F
+:10060000D0E6E6FC55CA35643916103E5BDD3CEE9B
+:100610001CC54F19A2EFF69AF8303A70F4780772B9
+:1006200035FBAA3E1179B7B586C7D15E9BE4F3E0EE
+:1006300073195773966839577D35FFE337AED2F992
+:100640001F014F69FF2AE03B7EA7FC6A902768FFE5
+:100650005B6BC236942B5575B72A7E285F1CCBCFB7
+:100660003F2DDDCF30CEDADD5F174E44BD7DC2E0D9
+:100670002E7C28BE4A870F57DC79EE7EF473C5C204
+:1006800087CC18F94A17C6878906F9DADA850FB5D3
+:10069000EB2E4BBD787C68477CE8A3C30741FF691C
+:1006A00035E107917EAD021FAC6EE063000F15F1DE
+:1006B000605824EE29E9212CF20FCCF0090706C579
+:1006C000C84358A114F7B0BE8BCE3F10F1D07A11B9
+:1006D0000FF5D7F17CD98E3BE3A618F30FBCB4EE2F
+:1006E000A9AE5A459FC71F254FB616CF4FC63965CD
+:1006F0005C73F244DF0AC49F0979FC9CC3B1E34CEC
+:1007000021BCDF0AE8E736E1F9F708CFE5FD03A1F0
+:10071000C7BD36495B89E38EB00729CF19F4BDD533
+:1007200058DFBAFB49FEDD5CE1879479795FD96FC8
+:1007300096640FE27D49E9376B4DB46FC7F3AE663F
+:10074000E1C9F4BD5E8C53A0DFE9DE38CA6B5CA85A
+:1007500080E10DEF7F7BA27F33D11FF3513EAE7F4F
+:100760008EC38D7A7E43F29474E41B556B5592EBE5
+:10077000B1EC1B496F55C06F88DEEA38BF4903FCF6
+:10078000227C0B28C46F3281DF70FEA331D4EBAC26
+:100790004877AEEEFCA6B507F85F24DF790AE11CC6
+:1007A00085EF3C83CF757CA70DEB5F16EE7957196B
+:1007B000F90DC60368FF485FFAFD9BF5D9AE7D1BB6
+:1007C000E94BD2DD7F009DFD19E11A85CE8E209E7A
+:1007D0007D053A3B1383CEDE37D1D95FFF4DE9CC9F
+:1007E00032BEE8C274B659E095CCDF967AC550B5F2
+:1007F000ED6C2ECEFFBF9CBFFD1D915F77A1FC6D00
+:10080000FC5D8CFFD49CCFFDFFFDA9FFB1FE54FF22
+:10081000F83E5FDD9FFAEB2B3DA4E79AFDAA0F8E11
+:10082000D66E1EDF831F4EF269ABE4D3C08F91F703
+:1008300056013F43FE9C56D1F9975F727BD3EBF490
+:1008400090BFE10E1C2F53F06B335F06BDB36EFCFF
+:10085000D7E1978CE16FF857F90D8788BCD20BDD93
+:10086000B71F32CE23FCAED1EFDDD70BFBBE1EC6C9
+:10087000C07B7A5BEFB4071B60C1FF1CCBCF674422
+:10088000CD75D72091FDEE267B42B807BB49FE3DD2
+:1008900088E655FE174EE4EAF7C7A2CAADAEFD9949
+:1008A000F464BDDDE4B904BBE9FF8E37EAC9D61AAA
+:1008B0006EE75A41DE515C5F2B0E21BFCE0C286DD6
+:1008C000981AEC4FAD55500EA6D5F8281FFE52E3EE
+:1008D000FA663C8A15E7FFBAE3FAE6BC817F9738EF
+:1008E000FFB1F1D1E3FCD2FF6A8ECB8FB037979284
+:1008F0007CADB4E05FB2600DBB3FD87E0F9EF73C8D
+:1009000007DDD330E703C48ADB8F48B1879D0363DB
+:10091000C7EFA5BFE0115BED1B68873FB2DA42E786
+:100920006BCE1B1896C8F3C75BC7AF7A98F27FA44B
+:100930003E5C21F84C9D6247FCF7570489CFF8B51F
+:100940009DAB319E9CE6626DA867B58FE7F4A2A6C9
+:100950006BC467AC157EC22B199FA8CAE6F7E6E206
+:10096000057EA9836BDFC2F1930FA85E8C6FDF8BCE
+:100970005D816724A2AC443D628C85F2225A945A70
+:10098000F27B342B1EFA3B1EC9C3DCA41F3D9DEC39
+:10099000FDC35CCA0FE57F6F64DFB4EFA6E3FAEE38
+:1009A0005EBD3A1DF5C08C093C1F71D3B453950848
+:1009B000675B1EE87F0A9586BF4B2BCB8F26F038EE
+:1009C00009F005CA4784756FA1F8FB603BF9D9545B
+:1009D000ED81EF201F502F9B4278DDACB8E72DC092
+:1009E000F3CAB5931ED3903B6AEE22D8D7BA3EFE27
+:1009F000A61C3CD7E4C1B4CF86E4BE49A88FAECBD9
+:100A00001A48FA6793524BED812C0BBDA78AF8FC6C
+:100A1000BADCEFBEBE18FD59D9FCFE674BEEA9D774
+:100A2000B15FCB18FEC76CCCEB55DDC67B52F8E14D
+:100A300023E4DF6A7F0BDD2F54455C5C35C59537B9
+:100A4000C87D8AFB2BF1826F55E5AE994BDF4F488D
+:100A5000B5BB11C91A13C3E5586FBCD3C6304EC716
+:100A6000ACCD063DAD7E95310E617519D7D3D475E9
+:100A70003FE1D5F9C8671A15510FFC82D7B19D9295
+:100A8000FEDAE623BE34C6F3FA35BF79723EC511ED
+:100A9000C5FA6C727D7DF8DF5BF97430A3FB6D5590
+:100AA000B670D4EF0B5F685DDDC7DDA48971D9FF37
+:100AB000E6B84DB93C4E641E57F6339F9B6E1EA69A
+:100AC0005CD23CA7CA09FF0EAB0CF98C793EF3FB54
+:100AD000F2BDAA3EB349DEFDABFAC782EBF2095D77
+:100AE0007FDF8575C52DC43D3B8F2E3E563F651477
+:100AF000DD8B6D556A896E02C996A8F9BFB1E947C9
+:100B0000373E0F8E10BFB5728833B52E9EF2382453
+:100B10003DC93C0F6BBA859E33311EF0E157491F2A
+:100B2000D2BACE8BB9FB46C6552BECD4DF7C8FD81E
+:100B30004CA7323F84DECB89B45BC5BCE6FC109782
+:100B4000C6BFB7D25AF900F9F32F354FE438D22790
+:100B5000C18D915DD8F05FCD942FC5DAF9F3867C15
+:100B6000377DE770BDEC97C828BF499E83539C032F
+:100B7000137691CCBB89969783F65CBA84B9870DBE
+:100B8000C67D36CAF73D3E0DF9E53D578CC8C7EF27
+:100B9000773EB873D313680F6DD9B5E67D2CE38724
+:100BA0008DA0EFA726782D5EBC9FE5BAB1BD1D399B
+:100BB000E4DA618B9BE938F5E74AF75315CD0DFD73
+:100BC0001D2ED776E4BFCCA1D077AFD41FA605D118
+:100BD0006E4D5F64C48356C5DB17FF3E6660A3425B
+:100BE0007A177E6F40DF6EF718EBC7262842BF34B6
+:100BF000DA31CD31EE750DD5B8DEAA9AEEB56EB20A
+:100C000079E8FBB99BD6A9A40F6C1271A5F1DADDC6
+:100C1000F357036DDFDEC8FF9E706B893D88F75385
+:100C20005B13DDD7CDC5BA907F32BEDDFC8DCB82A4
+:100C3000FABFFB9439C14378B8B1A46F06E371F0F1
+:100C40000CDFF0D878F165CBFF0132DEFE59008071
+:100C5000000000001F8B080000000000000BC55BB7
+:100C60000F701CE5757F7BBBB777924EA7BDD3C9CC
+:100C70009C8C6C56B6146490E5B56C9953B0A3BDCA
+:100C8000D3BF9371E9C5FC3333B67BC6C6214D266D
+:100C9000114E494C42AA333A59F21F84AC24953381
+:100CA0006D9AB30999CC8401259DB6860073024ADA
+:100CB000288144492990690684096E483313A7C1E5
+:100CC00089D2A1A5EFBD6F5777BB3A59B6E34ECF96
+:100CD000237FF7ED7E7FDFBFEFF7DEFB6E8DDAFF60
+:100CE00072DB7A007855361ED6B104154C3FF0E71A
+:100CF0000319FFD3F06F09007D857A2AC57B052093
+:100D0000FF810470F57115F2767BFCFB6E4718A02D
+:100D10008D6A63905A8DC5E48D1ED800E0B7DA5C09
+:100D2000234FB6AEA0F95E93E1617ED20FA94AECE3
+:100D30004B9F8E42393480135C2DFA284B6855F84E
+:100D400059017030B2F54734BCBBBD5DAAB969B377
+:100D5000BE85E681FEC966805551E7FAEC76A73A72
+:100D600070F13500BE1CE4BD412AF326B450396D44
+:100D70004A589EDBFE196DB3BEF03C3E281AB79E62
+:100D8000C603DEB75C4C3F7CEE853413EFFE8A96DB
+:100D9000DB01F73D74830AB25482CE8BD455253FD4
+:100DA00025E13AC7EFBDFA468800640EC9D088E352
+:100DB00078A345EDF02FF5D47A9809887564F87911
+:100DC000D2243E053BBCBC5FFAF89730FF0088DFB9
+:100DD000FA8177641CEF4B49553F8CEBFD526AEF6B
+:100DE000576EC17AF625D990F83DFE87FCBBC79AAD
+:100DF00003C626581EAAFCA2FFFE53F7BDF922F136
+:100E000028A9BE457403AD882E2BB830FD1B0AF30C
+:100E10003D183B3DB212E9901D293DFE1DD5FAA7B4
+:100E2000885E369D171AD77E2FEF9F9AEC5A57A8E7
+:100E30008F94A77798C887D180014074D8FF1CBFD2
+:100E400087F52897B50BF31329CAF47993BE62BBD3
+:100E5000AF759A7B4CACCBA770E96B00DEAED46F5C
+:100E6000DC8AAFBA236FED20FAEF097834E2A3DD14
+:100E70007FF0A817F2012204CE8B72B70566766C5C
+:100E8000C576D0E0653997236BF9F9EECA94E2C1D3
+:100E9000F2F3E60A9617BB7F1F7C59D987CFD77824
+:100EA000B557494EB211895684CF9180B8F4CD0A16
+:100EB00098412C7BF5B8BF1EC74D3E491301748481
+:100EC000C623E0016879E2785DBA99B6614E3721B0
+:100ED0007F4216BBAEF54DA73A71BCC19765E37E64
+:100EE000AC87027BB700CA91F4182E969E8720E744
+:100EF00043BE2B819E77E9F9A6B3005D45F2D4315C
+:100F0000EB87AEA6423D8E2317D73BFDB58EF6DDAF
+:100F10005ABDE3BD0CA691473AF5465739DA55B6A6
+:100F2000ADD768BD7DFA5AC7F31B9ADA1DFDA14BF8
+:100F3000393D83F58DF88FF82E83A8F37B5C77A07D
+:100F400019EB45FD1528AAE3FBBF352B2367AEC57A
+:100F5000CA75701DE911F2E5E411B23FDBFC06F140
+:100F600065D00BA7A42A20D5CF402B11DBD4234872
+:100F70003FC992D757CC7A960B29F0FC1F580E9F89
+:100F80009CF148C4D727A0F53036FA1B4D9FF2607C
+:100F9000932B6948EC1F4541D7914F0D385E592B73
+:100FA0003F3757623D0A52A60FEBCBB05D54882203
+:100FB000BC40EDFC70E00BA21D2CA3761A64EAB0D5
+:100FC000AE19504E7CADC3713E19E67E993EABDF43
+:100FD00055A25FA62A2CC66FA179D15C76637902EF
+:100FE0000CF0C9448714C04AB222FD5C5E45ABC216
+:100FF000E70F81D14AF5469861BB84EC97A87E053E
+:101000004C6AC2C8E785DD9E514267FCC2EE97D2AA
+:101010009782DE2870C6E607CDDB61FE80F4EFD64E
+:10102000DBDBAAD28185FB29FB9F75E8AD1AD79936
+:10103000CECAFE5ED61365FFF3FCFEEA78EA551AC7
+:101040008F48EF6F9D4FEF16350F64BFB27130328E
+:101050003844F6F1CDD15DC8DFCCE37EA3112E1F5D
+:101060003F2E960F39D0CA89AE72FFA5F2013FB864
+:10107000AFC029FF89C32C8C269F937F045FFEE7B6
+:1010800052F8E2E607DC570DD0BEB81DFD6B295FB4
+:1010900026AD647A98D1D602FDB19E5965D12B6CEC
+:1010A000F14316655EB69E2BE185F942E355870B49
+:1010B000FC598C2FD114BE6F2DF047EE379978F67E
+:1010C000B9EC83B312952B2483F9B5524E79A85EFF
+:1010D00021E52DD093633B1D048DF9B314FAB98C2F
+:1010E000786776117FB2FB71229447781F4F59C2FF
+:1010F00049D6B9980D24FCF5645F9B14C383F5E6CB
+:101100004A4F2A8774BC52813CEDAF56810CD9738B
+:1011100044063C7EF6713CADF09CC9E231EDA17E07
+:10112000F7FA7359A9307F8B65B77F54F94D6DA6D7
+:10113000B940E7D364BFD6087A78D8FE4CE6A97FD9
+:101140003409C6A03EDF9E61BB8C6CD9292A77D2B8
+:101150008B76A65B26887569E4FB7F209C41E3299A
+:1011600058AF88A77BE3354C770884D92ECD5478C7
+:10117000A0142E300957ECB2E6D9F6117D790AD7C2
+:10118000B96BC4F7168D07599F1317B8FBEB1214F0
+:10119000F7B7FBCDC995BBFF25EA01ECAFB9201C21
+:1011A000107F6C6315D179419C497A525DDC4FF018
+:1011B000498DA41977A8A42FD58B8FE375E1177BF0
+:1011C0001C2F0A2E8DE3B5F08B7D4EED85B35E6549
+:1011D000A5B54EA4D76EB03F11A6E74E8B7E7F46D5
+:1011E000E75590E8A9AB44A43D9052496E3F861064
+:1011F0009A70FC8A437B828C17A04B23FA48F9EB48
+:10120000E50FAEBD083A5A74DA997FD7AB935DDA31
+:101210005F096FDBEF5714DEFF76FB4D8CDBD101EE
+:101220006820FE5658EBAB38F5FE0019F5FB2BFE97
+:10123000F2E50E5CFAD0BFC8865C4FEF11CFE23802
+:101240006520CEEF0AD2535C77C59367FE9BDADB4D
+:10125000EFC17A4F2343D1B89E8AA38C672B82AA11
+:10126000CE38DB2567368E86F7050E0E58D42B1A3E
+:101270005722BC6CFB3D3CAE347FDED5163EC757D3
+:10128000F10F2E00CFBB713ACCE173F13E105085C7
+:101290009E1888738BE9B8809ED9EBB6FBD5A8A9B8
+:1012A0007AA3B9447F8B0FCD685708EF5D5107B91A
+:1012B00003B8DE91917DF10AAC1FAB01DD87AF86EB
+:1012C0007B3E2B11DE4844842885620217D21434F9
+:1012D000BFD79A2FF40BFD7013BEDF5B173070651C
+:1012E00070C5AF4C2D8EE3DC59E7374C7C9005F18F
+:1012F0003E13F3087F3203AF101EDD63F1C7FBA47A
+:10130000C099CC1BD4C399B8C0577B4E7D720BF1EA
+:1013100077347CB391C7767BD03E55131E1BF332D6
+:101320009E435CE7C0FDBE58110EC4BF3B8F7B1DC2
+:1013300075AF0B27BE19471C48CCB470E02FE320D3
+:10134000E6C582CE93CB350F04226C4F572BD31EAC
+:10135000ADC4396BF3C3C6DF4FD5083A7BDF1374D6
+:101360004187791F3DF7BD27FC3134E081B62574F4
+:10137000FA0BFAF9DA903EF4F43D711E604F5EB755
+:1013800089FF68DD6E3CEC73E161F77A6D3EC80958
+:101390000B276F800D441FC4E78C13ECFDB8F7F1E9
+:1013A00024FAE75D28144F0FF8B9CC0F685C3E3380
+:1013B00010E5F2B9011DBA10803D3FD0C4E50B0322
+:1013C000063F7F7120C6A54D87F9F44129C4FD5E13
+:1013D00065AD59699E4ED139BAB4CBC3AA70EC3E03
+:1013E0000FD3ED1CCA27295F10BD2005977855D271
+:1013F0009333692F96FF738525AFD7FACE4EF9B098
+:10140000FD682D18F763FF2B627B59CE369DF514CE
+:10141000F404C8CF2977C409E250EDA877FAAF7475
+:10142000B4EFD6563ADE87E3336CA77AA3D73ADA1D
+:10143000D97CFE3AF959B8BE635DA735A26B9FBE51
+:10144000CED14EB90FF9DF42FECFF58E7141DE628B
+:10145000909D0E6F77CA61D0C557F5AEF3FB41364C
+:101460009FCD84530F16E2AF5B5E6DBA86E7E82A24
+:10147000FCCA2CF99548D7B026E86AEF77D4DAAFE2
+:101480003DAF1213FBBBDCFE6590FCCBFA52FEE5D0
+:10149000CF2D3A2FE25F269DFEA59BAE8BF9977F5D
+:1014A0009E70FA97174ACF9DCB45DC2DFC92CC7EDF
+:1014B0008B9CECE773B07A5A367AC9245AB8AC924E
+:1014C0006C00B6DBD9A6E608671E8399289DE70F56
+:1014D0004A485594B7EA66A396ECCCA321E3D56DB0
+:1014E000841BFB3CC649ECF26CFCD628E18EA103C0
+:1014F00027A27858C103090FCF3B163FC3F10B4514
+:10150000078E5F6069E64AE013BBFD3D435E3E0F18
+:101510001EDCA1E6246CFF60A576EB36AA5BF32007
+:10152000414C7A3FD1F6A11CF929A309DD8A336524
+:10153000A2E4AF7C69C7865A3EAC14ACAFA6E606FF
+:10154000EBC9E1322D487E74768747A37DC9EBFF56
+:10155000EA33241F0F48FD871AC87FABF1009D1F97
+:10156000D9D086DA5DD84EDE893086EA3B36BC4E6D
+:10157000367BA2463FD440FD430D4CBFA18DB7FA48
+:10158000699ED1D0923E8A8F8C767B984732E18CCF
+:10159000208FD3743EBF47D68ACE77E0B805AF53CD
+:1015A0008E78F22A9D57843F82F3E37B87432A3962
+:1015B00005F08F895B4E641AF831DBAF2B2C3F604E
+:1015C000E78E84C9F68AF004D267A777A6A6D4B9B5
+:1015D00070D08A77CE9D3B51E77A4ACCC3B8401190
+:1015E00033F247B7E3B4F8C9DED893A373741C523F
+:1015F00049B29F998087E31D0BED5F0938E7B3C7B8
+:10160000E7F1648AA395996545FBD7ACF8EFCB0960
+:1016100089F1EA0F89EF6D62199125857529490FC6
+:10162000F7B3FD5794DB6D93240F16BDD1AF78BE91
+:10163000F8BC7D2D21E2B2AFCFC911365D52B48E18
+:101640008DAA359EC1718A35AEF8B59B3F171BBF79
+:10165000FEA5B59FD7B6DF745E3F7955CED9CFD7FB
+:101660000962FF56BCDB6BF1FF1A79721FC9E3FFF9
+:1016700077BCDBD77979E3DD6F937D229C8776FE9B
+:1016800061FC9EFD698EF5054E9D7D9BF57AD51218
+:101690000BBF40B4C1C68F2BA874E90F017DE4DFF6
+:1016A000F85AC4A5581FB7EA99D5625C28D6CB155D
+:1016B000E4178838CAB2CE95C2DF227B42CC558C63
+:1016C000E544D780F29D8C86FB280F1C831096BEC4
+:1016D000C8AE0C951DCBF5D118AE6B7C9587CFAB02
+:1016E000F1CAF489215AFFAA4049BD68EE14F66F89
+:1016F00084E495FD24303DA46F92AD1C90F6209FAC
+:101700002640F0D9EC0CF17A146D2C7607CA4DCC3A
+:101710009207DC0FF7778FFF611ABFCD31FE374894
+:101720004EB3D6E034CE2E1C27DE29D97A95A1F708
+:101730007E6B3EBF3E16235C90E8D4C47B65AD4112
+:10174000FA301E2A3D5FC29A0F2814B3A1808FAED3
+:10175000D82EC601BFE8FFA07476DBE9F5CC57D6DA
+:10176000275A07BDAF309CF6C13D7E5993D3BF5178
+:10177000EB9CED5373FB70FA450F48A5D77BB7D5AB
+:10178000BE63B99033928FFB4BC8875BDF558A7B72
+:10179000E2B869E207DB0F617702CA7482FC9D4000
+:1017A0003318834CE029DE6FEAA9865333EBC9CEA8
+:1017B000070DF283143F9ACAD6829FE8DEF7627E55
+:1017C0009EA240C6DB3ADFDFC371CDAA5671CE645C
+:1017D0008AC6FB8C252772B13F584FEE887E23EDD9
+:1017E00073EC90CCF1A5B17B7DDB4A9DD3F726CE7F
+:1017F0009FD7399E423F829CD4C78E1EDA8DF5DF7B
+:101800006A1ECDC76DF492791DCDAACFE57552172A
+:1018100096D719EB0AF7355C4C5E678171E7CEE32A
+:10182000F9799DE39D48A76301915F99CBEBDC1C9F
+:10183000B9A0780E58E772D8B2CB957D961FB15FEC
+:10184000623FE299B67F3FB286E4ACCDCB720047EF
+:1018500027A0584FB66CD7BF5A4DE7CCEB3E681463
+:1018600076CDA4F16CBFD8A69F6A8D9FF8F64B0A7F
+:10187000B51FAFF56CE0F120EFF344793DAA55CAEE
+:1018800054AE51F372158D1B06439C0F79899EC788
+:101890009158C5FEC1E8EC4F3AAB284E1200834C7C
+:1018A000D0685C3B50455F280B4478A75ECF91BD64
+:1018B000EDF45738ECFF689F2AEC6B23FA4BA43FFA
+:1018C00053FA57F760FBE1FD658C9B1EA8F308FDFA
+:1018D000CA4839A99EF0B5D3EF199F5C21F0D851C1
+:1018E000AFD188ED1F9914ED77C737E464C6DD4E9C
+:1018F000BFA84F77FA45BB6B5B5F25BC08435E8E84
+:10190000C76B16AEBDA1C9E92755D6F7BF403865EC
+:10191000E790C0C307A3E125BBD1FEADEDD21D7991
+:10192000B25D437772DE684805CEA78EEE50593F10
+:1019300046BD6F1DDFCDB8B19CE938B143AD4D1741
+:10194000E9CBC7BA7C3CCEC40E813F105EA6274BC4
+:10195000BCFF589765A714E073DC96973FF9B8A0D1
+:1019600073B00E723AE1B8BE7D79F22BC7EB704FBF
+:10197000F87E28DAD03745F3BF2203EDD32D87F761
+:1019800090135CB40F5FCCE3A093D797EAA7F1E183
+:1019900006D0C9AE7525B14E7180ED2A507CC017B6
+:1019A000FD0BDE6F18EB6558F727C7320AD6FD0D21
+:1019B000E975848B9FBDF7B6917884CE3BA1DFBEDD
+:1019C000ED7B533751FBF55E28A3F5812E45697DEC
+:1019D0001909449EDFA90F07B3FFD4457C3A684834
+:1019E000CCA29D7D5BEFA2F59C8B94336E1AF3A67F
+:1019F00076B13DBAC5AF65F80C9C613FC2FB051FCF
+:101A000090DC4DDCFB4E0DE1EFABBA56B0BE95E974
+:101A10004EFFDA0F637C6E6F34A7B753BF8D3195DD
+:101A2000321EF04CFB19E6DB449BCFF0E13A26DA9C
+:101A300025A6F3EFDABC399AE769755AA6799FFEB5
+:101A40001DCE5D5F4ABF4BEB95AD47EEF6A3B1AD42
+:101A50007E928B83307D33D127332BE254EE76DFB9
+:101A6000B0E4E060F6962685E3592AE7DB95B38675
+:101A70005985A3876653DFA2D8EB2B9D0AB7BBA776
+:101A8000D6939170BCE13E95F568B8323D42F23C88
+:101A90008C72CF7E5204EBA467B511E370D17CE366
+:101AA000EDB736913D7BB9AD8CF1FD6BCFD6DE91B4
+:101AB000C12113F2AFFEEE31F2ABEA54E6E7B0B764
+:101AC000FF75F283326D65BCDEE796A9E0277B10D7
+:101AD000B9E321F2B3E191ED502CAF1349A1A71363
+:101AE0007542EFA5C7B6B31F302EC94C67B3E6A445
+:101AF0004478CC97B4E34E22CE14B7CCD9C4F6EFD9
+:101B0000721C6A699F88A3C69356BC490E64582EFE
+:101B1000AF2B7B88F4DF54BC0EFF78D359A7BFBC32
+:101B2000D4E52FBBE3515BBBAC78841577B2E532CB
+:101B300068B5998859767ABD2F27E4B0BF566B9E59
+:101B4000AFDF3FB4F0F3F4801F2502E027031AD77C
+:101B500083E66F0E54139F06A2FCFC4F379E908ABB
+:101B6000FB8DAEBFC5AFB33D9989D2B86E3BE2964F
+:101B70008B373ACB1DE789BDCECAF60410EE3D7710
+:101B8000962D326C0ACC74F2D908D38162BC9FA71F
+:101B900075FA284E26D6F91CADD3477132B1BE175F
+:101BA00006742E5F1C68E2F23B5D20F201B67DB840
+:101BB0000AED03D2A1AB4ED4C91E10FFC3913B382E
+:101BC0004EE68B2A1AE9BBBF6E2C2F15D98789CA1E
+:101BD000FE9FDE4976BF26C0F2E8DED7B1AE397C83
+:101BE000E8D8D7CEF67D6C77CEE13C447FB433772E
+:101BF000B11D42BBC0F36E576FE775986897D82E3A
+:101C0000F47FF536B60B5E203977DB817046E877D6
+:101C10005A17F13BFB9ED09C5DC0797238CF336878
+:101C2000D7A93E8C7680E6196E7FEB1334EFEFFE7A
+:101C3000500E34C4C48E57D92EBC7C0EA0FA32DAB2
+:101C4000055B0FD73DF71F27324A293E6FBDED9444
+:101C5000A0870682AEDB5225FCC48BE5339817863D
+:101C60006372CACCED22EFA8321D16CC3B663C064F
+:101C70008505062795A4957704CA3BDAF9C7A2BC67
+:101C800063B933EFA8E6B28C6F7256DEF1D6CD227F
+:101C9000EFA896CF040AEBB0F38D43F4A8B6909F5B
+:101CA000FF87AEF4CB5D6D853CA32E893CF8D571E2
+:101CB000F387F41C22613EFFDD794A3B1F89F04E19
+:101CC0004A17E5375BF0B93F5CC87FB9F399F6BDB9
+:101CD0008C1675E6E411A4CBE0ED7EC60FF6FA068D
+:101CE0001FFFF0EBE948E13E809DEFB4F39976DE0B
+:101CF00013D7FD4EF1BAE14960BB034FF84FD0F95D
+:101D0000E65E6F453CFD4B6A3F6FDD17985FDC0276
+:101D1000D6F888BB489FDFB4E838D7BE4BF89F6B36
+:101D20005411DF86A0CAFE4EE2DB0190096757AA74
+:101D300027492F76C14C37D1773024705EF6012FBA
+:101D4000DB49E8D6997F35AAC9F7216A3E5F661C50
+:101D5000C0C7D9292D48F1A7AF759AD0DD46EB1839
+:101D6000BB792BAD03713BD9BB371ABF12E17C3F66
+:101D7000DD7BAA22FFCF584E7110BDBBF47DA58E2E
+:101D8000E567B7F2BC951E20FF2C5B66BCA013BDB7
+:101D90009F5278BC3E1CC26CE5FB4B5D6A98C61135
+:101DA0007EF260E034F3ABA3D1B796E37A95A5FD5C
+:101DB000C0A5DD820E9B712C15C7792A9EAEA57534
+:101DC00053AC34CA722CFC3BBD1B6CFB759F674344
+:101DD000210E5621A7F56EB2D78F480A9D8F3E4B34
+:101DE0006E6C3FB13B61D6770B7E9834BF7D0FC8D8
+:101DF0009EFFEA6E61175FE9323F44EDDA681E929A
+:101E00004B2D13273D6C49A33C48AC3FAE3CBC90E6
+:101E10000BB7BCDAF2369787B7E450D244BE16E56A
+:101E2000AA8DF6074FEB531E89F2EDE91347A8EF91
+:101E300025E6BB3F9D3037D1BA77C7531D54BE71DD
+:101E4000EF6DC0799D0BBCC7D1B1BC3F4A79FCE1B5
+:101E500032819B1F8D1B0E7B77B7459FBBBB055EF9
+:101E6000BA1665669AF44031AA80F5F82EC6D1B646
+:101E70007D1A1B487FEFE78D85FED90198A47CD0A1
+:101E800042EBF01EDAC771DDC1BA849FEC0FDAB7FE
+:101E90002AAA0FD799D1E275642B859C679689B8D9
+:101EA00005C5D332BEC2FBBDDD32EFA7B30EF224AF
+:101EB0003BBE80C8BBF95071753C7F7C662CCFB8A7
+:101EC0002600931462F814E90FDDFF8B186092BFAF
+:101ED000599702D26F9F56E84F79D4CEBA7EBE6F23
+:101EE000B9D03872D4EE9FE6FEE3DD1A8FAB463CE4
+:101EF0008E38C0627473D36588E8D6B830DDD40BF1
+:101F0000A69BD03B37BD0E13BD909FCF863ECBFB2B
+:101F100083F73B59CF7C1AEE13CB31CBBEC80113EC
+:101F2000D29564A352882029CEDE0F9487B6E92C7F
+:101F30006B82CEB2D6CFFD7C7506A457135DD24C12
+:101F400017371DD04E00D9897F7EFC7884F0690751
+:101F5000D6A3C27E800FCB5F5BFEA0ADA75BE0C7C0
+:101F60000111FF769E17F3ECA9553E6AC59FDDCFA0
+:101F70006FE92913B84E0707DD2B2BB7323F4E8E82
+:101F8000B4323EC0F33343F7627A6A1BCBA97EB901
+:101F9000F388EEFCA13B4FE8CE0F16E4C6F4D33A2B
+:101FA0007FAB9DCE7CB484BCD8E5114BDF8606FCAC
+:101FB00025F5EE08EA3BF16FB8DDCC50DEE860684D
+:101FC00026CA7233F52EE362E525D9207CA9288242
+:101FD000CF3DCB66988FBD311328DF746460DB770B
+:101FE0008AC7FD753CFD23B26715DAA449E30420D6
+:101FF0009FA1F36773B5D95F0A37FD9B6547BA1395
+:10200000A97F257BD5A10BFEC7E2E6AB6C172FD0CD
+:102010006E2DA44F8A4DBB8BD6A7D3429F62FB582F
+:102020009F46EBFA19678DFE58262455C091963EBF
+:102030008DB69F617DB7F5EA3D4B9F3A63422F28ED
+:102040008E40E777B0CE64BBF15F963E29A827A407
+:102050004F3E4B9F825AA13DC5C73B89CEF85CA934
+:102060009BE17EC198A57FA44F01BA3F0C8C0386EB
+:1020700051EF282EE2D6AF8E06716E6A89B4A7871B
+:10208000F0C5B2AD1C971FAEFBCF6AC62F96FC17EA
+:10209000F06E2B9FE7E7463C06E9430B01E8D6824A
+:1020A0001ED8FBDE382B431E59B36956E2F223B328
+:1020B000155C76CC967169CE5673199F0D719998FF
+:1020C000BD92CBCED95A2EBB66510FD621DF67EB1E
+:1020D000B9EC99BD96CBDED9555C2667D771BBBEEE
+:1020E000D9B55C6E9EBD9ECB1B66DBC53C4D625F69
+:1020F00025F481D26097411F8C0C54921E7CFC7594
+:10210000B6EF9ACA7794B2A10D9C27F22933AC0F8F
+:102110002763C2DEF706049FDCFAD09D48AF25BADC
+:10212000BBF5610EDF2AA011FD55B03E2EFC80F8F4
+:10213000A7BDA7E83EB21A3559CE109F7CB887F4E8
+:10214000E31271C21CCE5CAE321EB571E6E832C439
+:1021500099F5059C39DC2EFCB2EC033EF6DF764B9C
+:10216000E27ED9A713E91B7BD82F1671A2F4CD7E8E
+:102170008D707336D4130D505CEFA00C142F401CDF
+:1021800092E2764A4ADC67BD407D8EC5857ED8EDF9
+:102190005BE0B4A7FF2270CC1BF4B57D61BB10BE21
+:1021A000D473D6DB29EC8226EC42B6AE7F84F3D220
+:1021B0002EBB609FB3480F875DF85C8F854B2C3D2D
+:1021C0000FD789F3324C7601E9F3C51EDB2E38CFE9
+:1021D00059C5C621491B8758762129FA216E779C5B
+:1021E000B3C86E3F14E16294A3C19EB6F9F681CFE5
+:1021F000F3A2736EB0A1314EBF25089D8538896763
+:102200007056DF6C943877B25A2BEBC194D209C563
+:10221000F1958BD6B3907DEE987CEEB8DBD9FA368B
+:102220003CD527F6699D4353B87FB348DF7A3571B3
+:102230001EE1F9F3F59E12E74FC772339D2AB1CE26
+:10224000477B84BFF1834D16EE455C690418DF9728
+:10225000C40D8FF608BB4EBFD37802ED4F77329393
+:102260005574D6F34749CE37764DCB1446F8486CB3
+:10227000EC154A89A09E3EF6C7E8E9D1B895EFDB98
+:102280005F2D2E3B5BE562F26FE3225B0FE6EDA371
+:10229000DEDC568A1E4B7B05BE1F1CF1F4D1853F48
+:1022A0005B2EA694958C7F4AD85BD3B82CF6F6C2E9
+:1022B000F0C7149E83C4F7F3E08F374BD9DB85F06A
+:1022C000C7991E912747FCF10EF5EB6816F8636974
+:1022D0002FFCDFE08AF869A6DBA5E28A0F6CFBB170
+:1022E00000AEF0F6EAE27715DA0CDB8FE025E20AC1
+:1022F000B79D40FC50DE4BF431C4B96BFFDE842F38
+:1023000050169D5F6867AA7A055ECFD3E5B19381C9
+:102310004446623D4885E8F998B982E5E872E903E8
+:10232000E2C42B7B8BEA8BE9C505B79BDCC171400E
+:102330003B9FF9FBB2600BC547F6FB45F9B9F2E0EC
+:10234000492AC707441C7A94E27E588E7B81F307A2
+:102350004352B97152A27ECB7322DEDEBF86E29E6B
+:10236000D7F786AD7872FF75FCBB1BF8A2236FBA56
+:10237000F0BAC43D5F1AEA03BE0F5EA7711CDDA26E
+:102380004B981880F31E5EE5671C78B8EF91E377F1
+:10239000505CA64FC4C140D1EB3F4AE72FC29A58C8
+:1023A000D1B920837286E2F32374B79D41C7367199
+:1023B0000FDA5A4F7512FDF722FFA32A76D7F77E60
+:1023C000EEBC37E429CE231F31B75689CBCA77F14B
+:1023D00038B69E1C094CFAB5227B7374C079FFC9CC
+:1023E0005DCA6DAFF07DC3634D0AE72F1E581F29EC
+:1023F000233D39D42082B4E58D9E54AE843E0FF443
+:102400004A8EB876C83AE7CBBAC5BA169A6F784002
+:10241000C46FEDBA4F4F9924A7E5F56329A26B79F4
+:102420006344A2F8ABFDFEF65E61370E4B46BE0379
+:102430008979B8529C17BEBA0C78080F84F6AE237F
+:102440001AFBEBFAE14C80EE6F64E06D2CC3613552
+:102450005D6ADD83D6BA0F7B7329C2538757299CE7
+:10246000E7444C55324EF609CB4E97378EF3FAA01F
+:1024700051E17C95BBDD0EBB9D3AC6F98E438DDFE5
+:10248000D4695F87E807374B914BC9871F3A40767D
+:102490006600F9EA25794E73597ECDB798FEA32DD3
+:1024A0008A46FBE8969B0FD03CC79260105E71CBCA
+:1024B000C531D0CA687CB77C54AC7E8FE34FE54110
+:1024C000CA8C901CCEF8851D157216B0F8336A8838
+:1024D000BCCF684AE4AF6CFE15DE8BFB06E7520A00
+:1024E000FB2576FE6A0940491C67EBE590158F9F36
+:1024F000F77E799ECF9DA39BF251BA2711D4FC465B
+:1025000092C67DC4B9AE837876F2BAFA44FE62CE42
+:102510003EAF15FEE1FC758AF881F2CCBBC2AE5A23
+:102520007E42B0F93DB6ABF6BDAFDE8D425FABACDF
+:102530007BF755919429E872B7C31E48D7FC224314
+:1025400079A6076BC5DD84F04671AFB65C05234FF5
+:10255000F700FA027CBF6949CCCAD76D13F72BECA0
+:10256000FBE16A4475C41322505427DCE9AA83BCFA
+:10257000FDBCF7E0F6FFECC48BCF15F1FDA55EE7DF
+:102580003DF2C5FAFF7E20F7E27368908E19E7D717
+:10259000479B6F5F1E887169CBA52DA761DA62EB3F
+:1025A000C2FDC743A992799A6052E8C362762DE2D0
+:1025B00033DBDF41BE7BAB81F3675FD9E41CEF37D0
+:1025C00096BEFEC6D22F7539D4129E1A0B093B3027
+:1025D0005606DBBE5B426F972455B61B057D70E245
+:1025E0000A5B8EE6D363115CB1BA4BE00A2D5C4600
+:1025F000B8E898917881F281EF69AA5E2CB7EEB8BD
+:10260000BB8D2BD2493BFEA74A840BB4C00CE3ED33
+:10261000395C60E108372E28F7E6B6917E94AF5218
+:102620006D7BC576E5F3DFFFFB8732BCBF8C547C46
+:102630008E8EE66FE771C3AEB83B449CBF63798B67
+:10264000F017AE27AC4F4E2728FFB84511BF6F1BC0
+:1026500033A1F81ECEB8E7FDD83BD6F7F76D1C5274
+:102660004FEF8F4EF3EF6BE01E289EFFE04D3BF9DE
+:10267000F7148BF1DF5E17DDEB2AD69F8BD50F2386
+:1026800069E9471994917E9C83FB380F0F6349C712
+:10269000F9C41989256C12C407B7A96CB0A082547B
+:1026A000D01BE8B5F2E3E9393BA9503FC3EA564BEA
+:1026B000B72C64CA37E4F9778BB6BD39073FE379A5
+:1026C00033CF48D21CEEBA12DD7FFA3DE44A5A827B
+:1026D000E6A1D2BDFE1560F0F3064871F921E8E7E6
+:1026E000B209C6B8BC0626B96C86692E5BE02C9789
+:1026F0006B419769927560CAC05737D35CBF0E3281
+:102700005CB643BA9DEE970FD5EC5D4BE7D12D2E0D
+:102710003AD9742EA1F78C2B6D7AD8742F27E35DEC
+:10272000B3385FB321618F3B6379F61F0201819B50
+:102730006D7FDB1E67211C7CB9F09A8D33FF17CFAC
+:10274000A588169043000000000000000000000073
+:102750000000001800000000000000000000004021
+:102760000000000000000000000000280000000041
+:102770000000000000000010000000000000000049
+:102780000000002000000000000000000000001019
+:102790000000000000000000000000080000000031
+:1027A0000000000000000000000000000000000029
+:1027B0000000000000000000000000000000000019
+:1027C0000000000000000000000000000000000009
+:1027D00000000000000000000000000000000000F9
+:1027E00000000000000000000000000000000000E9
+:1027F00000000000000000000000000000000000D9
+:1028000000000000000000000000000000000000C8
+:1028100000000000000000000000000000000000B8
+:1028200000000000000000000000000000000000A8
+:102830000000000000000000000000000000000098
+:102840000000000000000000000000000000000088
+:102850000000000000000000000000000000000078
+:102860000000000000000000000000000000000068
+:102870000000000000000000000000000000000058
+:102880000000000000000000000000000000000048
+:102890000000000000000000000000000000000038
+:1028A0000000000000000000000000000000000028
+:1028B0000000000000000000000090000010000078
+:1028C0000000000800009008001000000000000256
+:1028D00000009000001000000000001000009DA803
+:1028E00000000000000000080000000000000000E0
+:1028F00000000000000000000000000000000000D8
+:10290000000000000000000000000000000091A096
+:102910000000000000000008000093C00001000457
+:1029200000000001000093C8000000000000000249
+:10293000000093D00000000000000008000093D4C5
+:102940000000000000000002000094980000000059
+:1029500000000008000093D80008000000000008F4
+:1029600000009B3800400000000000400000941868
+:102970000008000000000008000094580008000053
+:1029800000000008000094A800C8000000000098A3
+:10299000000096380098000000000028000096789B
+:1029A00000980000000000280000C0000540003032
+:1029B000000005400000CB200008000000000001DE
+:1029C0000000CB21000800000000000100002008EA
+:1029D00000100000000000100000200000000000B7
+:1029E0000000000800009D600008000000000002D8
+:1029F00000009DA000000000000000010000000099
+:102A000000000000000000000000000000000000C6
+:102A100000000000000000000000000000000000B6
+:102A200000000000000000000000000000000000A6
+:102A30000000000000000000000000000000000096
+:102A40000000000000000000000000000000000086
+:102A50000000000000000000000000000000000076
+:102A60000000000000000000000000000000000066
+:102A70000000000000000000000000000000000056
+:102A80000000000000000000000000000000000046
+:102A90000000000000000000000000000000000036
+:102AA0000000000000000000000000000000000026
+:102AB0000000000000000000000000000000000016
+:102AC0000000000000000000000000000000000006
+:102AD00000000000000000000000000000000000F6
+:102AE00000000000000000000000000000000000E6
+:102AF00000000000000000000000000000000000D6
+:102B000000000000000000000000000000000000C5
+:102B100000000000000000000000000000000000B5
+:102B200000000000000000000000000000000000A5
+:102B30000000000000000000000000000000000095
+:102B40000000000000000000000000000000000085
+:102B50000000000000000000000000000000000075
+:102B60000000000000000000000000000000000065
+:102B70000000000000000000000000000000000055
+:102B80000000000000000000000000000000000045
+:102B900000000000000012C800800000000000805B
+:102BA0000000000100000000000000000000A00084
+:102BB000071000000000071000001EC80000000001
+:102BC000000000080000AEC000080000000000087F
+:102BD0000000AE4000080000000000080000AE80C9
+:102BE000000800000000000800002008001000009D
+:102BF000000000100000200000000000000000089D
+:102C00000000A01007100040000000400000AF408E
+:102C100000080000000000010000AF4100080000B3
+:102C20000000000100001ED00000000000000001B4
+:102C300000001ED8000000000000000200001EDAA4
+:102C40000000000000000002000012B000080000B8
+:102C5000000000080000000000000000000000006C
+:102C60000000000000000000000000000000000064
+:102C70000000000000000000000000000000000054
+:102C80000000000000000000000000000000000044
+:102C90000000000000000000000000000000000034
+:102CA0000000000000000000000000000000000024
+:102CB0000000000000000000000000000000000014
+:102CC0000000000000000000000000000000000004
+:102CD00000000000000000000000000000000000F4
+:102CE00000000000000000000000000000000000E4
+:102CF00000000000000000000000000000000000D4
+:102D000000000000000000000000000000000000C3
+:102D100000000000000000000000000000000000B3
+:102D200000000000000000000000000000000000A3
+:102D30000000000000000000000000000000000093
+:102D40000000000000000000000000000000000083
+:102D50000000B00000180000000000180000B300E0
+:102D600000400000000000400000B30000400002EE
+:102D7000000000010000B30100400002000000005C
+:102D80000000800000400000000000400000000043
+:102D9000000000000000000000008000000800406B
+:102DA000000000040000800400080040000000044F
+:102DB0000000BB0000280000000000280000BC400C
+:102DC00000100000000000100000880000800000DB
+:102DD0000000008000008800000800800000000261
+:102DE00000008C00002000000000002000002008EF
+:102DF0000010000000000010000020000000000093
+:102E00000000000800001108000800000000000891
+:102E1000000011680008000000000008000011A870
+:102E20000008000000000008000012700008000008
+:102E30000000000100001271000800000000000105
+:102E400000008D00001000040000000400001320AA
+:102E50000030001800000010000013280030001897
+:102E60000000000200000000000000000000000060
+:102E7000000000000000000000000000000011E859
+:102E80000000000000000001000000000000000041
+:102E90000000000000000000000000000000000032
+:102EA0000000000000000000000000000000000022
+:102EB0000000000000000000000000000000000012
+:102EC0000000000000000000000000000000000002
+:102ED00000000000000000000000000000000000F2
+:102EE00000000000000000000000000000000000E2
+:102EF00000000000000000000000000000000000D2
+:102F000000000000000000000000000000000000C1
+:102F100000000000000000000000000000000000B1
+:102F20000000000000008308008000000000008016
+:102F30000000000100000000000000000000200868
+:102F40000010000000000010000020000000000041
+:102F50000000000800008D100008000000000008BC
+:102F600000008D7000080000000000080000845080
+:102F7000046000280000046000008EA0000800002B
+:102F80000000000100008EA1000800000000000108
+:102F900000008408000800000000000800008448C9
+:102FA000000000000000000100008DF40008000097
+:102FB0000000000200008DF6000800000000000282
+:102FC00000008E040010000000000004000000005B
+:102FD00000000000000000000000000000000000F1
+:102FE00000000000000000000000000000000000E1
+:102FF00000000000000000000000000000000000D1
+:1030000000000000000000000000000000000000C0
+:1030100000000000000000000000000000000000B0
+:1030200000000000000000000000000000000000A0
+:103030000000000000000000000000000000000090
+:103040000000000000000000000000000000000080
+:103050000000000000000000000000000000000070
+:103060000000000000000000000000000000000060
+:1030700000000000000030000040000000000008D8
+:1030800000003008004000000000002800003390DD
+:1030900001C0001000000008000032000020000005
+:1030A00000000020000037200000000000000008A1
+:1030B0000000102006200038000000080000A000DA
+:1030C000000000000000200000003EA900000000F9
+:1030D0000000000100003EC80000000000000002E7
+:1030E00000001C4000E00008000000080000000094
+:1030F0000000000000000000000040000008000088
+:103100000000000100004001000800000000000174
+:103110000000404000080004000000020000406081
+:103120000008000400000004000040000008000047
+:10313000000000040000400400080000000000043B
+:10314000000040400000000000000008000040486F
+:1031500000000000000000080000800000000000E7
+:1031600000000010000050400001000400000001B9
+:103170000000500000000000000000200000500887
+:1031800000100000000000040000500C00100000BF
+:1031900000000001000052C7000000000000000114
+:1031A000000052C6000000000000000100003000D6
+:1031B0000030001800000004000030040030001847
+:1031C0000000000400003008003000180000000279
+:1031D0000000300A00300018000000020000300C2F
+:1031E00000300018000000010000300D0030001811
+:1031F000000000010000300E003000180000000147
+:1032000000003010003000180000000400003014EE
+:103210000030001800000004000050000100008091
+:1032200000080004000050040100008000080004B1
+:103230000000000A000000000000000000005068CC
+:1032400001000080000000010000506901000080C2
+:10325000000000010000506C01000080000000022E
+:103260000000506E0100008000000002000050705D
+:103270000100008000000004000050740100008084
+:103280000000000400005066010000800000000201
+:103290000000506401000080000000010000506048
+:1032A0000100008000000002000050620100008068
+:1032B00000000002000050500100008000000004E7
+:1032C000000050540100008000000004000050582D
+:1032D00001000080000000040000505C010000803C
+:1032E000000000040000507C01000080000000018C
+:1032F0000000507D01000080000000010000401827
+:1033000000100000000000040000409000100000C9
+:1033100000000004000040980010000000000004BD
+:1033200000004110000000000000000200004112F7
+:103330000000000000000002000041140000000036
+:103340000000000200004116000000000000000222
+:103350000000604000080000000000020000604221
+:1033600000080000000000020000604400080000A7
+:103370000000000400006080000800000000000859
+:10338000000060C00040000800000008000060006D
+:1033900000080000000000020000600200080000B9
+:1033A00000000001000060040008000000000002AE
+:1033B0000000634000080000000000080000638077
+:1033C0000008000000000004000063840008000002
+:1033D00000000001000063C00008000000000002BF
+:1033E000000063C400080000000000020000640048
+:1033F0000008000000000004000070000010000041
+:103400000000000400007004001000000000000430
+:1034100000007008001000000000000400007000B0
+:103420000008000000000002000070020008000018
+:10343000000000010000700400080000000000020D
+:10344000000070400008000000000002000070440E
+:1034500000080000000000020000704600080000A4
+:10346000000000020000764800080000000000088C
+:10347000000070800008000000000002000070845E
+:10348000000800000000000200007688000800002C
+:10349000000000080000804000080000000000015B
+:1034A0000000804100080000000000010000804290
+:1034B0000008000000000001000080430008000038
+:1034C0000000000100008000000800000000000271
+:1034D00000008002000800000000000100008004DD
+:1034E0000008000000000002000080C0000800008A
+:1034F00000000002000080C200080000000000027E
+:10350000000080C40008000000000002000080806D
+:103510000008000000000001000080810008000099
+:10352000000000010000808200080000000000018F
+:10353000000080830008000000000001000080847B
+:103540000008000000000001000080850008000065
+:10355000000000010000808600080000000000015B
+:10356000000060000008000000000002000060028F
+:1035700000080000000000010000600400080000D6
+:10358000000000020000604200C0001800000002BD
+:103590000000604000C00018000000020000604C05
+:1035A00000C00018000000080000604400C00018BF
+:1035B000000000080000605700C000180000000173
+:1035C0000000605400C000180000000200006056B7
+:1035D00000C0001800000001000066400008000064
+:1035E00000000008000066800008000000000008DD
+:1035F000000066C000080000000000080000D9427A
+:1036000000180000000000020000DE400000000082
+:10361000000000000000E0000000000000000004C6
+:103620000000DD4000000000000000040000DD4458
+:1036300000000000000000040000DD480000000061
+:10364000000000040000DD4C000000000000000449
+:103650000000DD5000000000000000040000DD5408
+:1036600000000000000000040000DD580000000021
+:10367000000000040000DD40000000000000002009
+:103680000000DA0000000000000000040000DA0082
+:1036900000000000000000680000BB6000000000A7
+:1036A000000000000000D000000000000000000446
+:1036B0000000B0C000000000000000040000B0C422
+:1036C00000000000000000040000B0C8000000007E
+:1036D000000000040000B0C0000000000000001066
+:1036E0000000D6B000000000000000040000D6B4C6
+:1036F00000000000000000040000D6B80000000038
+:10370000000000040000D6BC00000000000000041F
+:103710000000D6B000000000000000100000D348F8
+:1037200000000000000000080000D3580000000066
+:1037300000000080000000100000000000000000F9
+:103740000000D35800000000000000080000000046
+:08375000060022000000000049
+:00000001FF
diff --git a/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex
new file mode 100644
index 000000000000..78b41615e7d9
--- /dev/null
+++ b/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex
@@ -0,0 +1,15442 @@
+:10000000000052D8000000680000070C00005348B0
+:100010000000318000005A58000000B000008BE062
+:100020000000C14C00008C98000000D800014DE891
+:100030000000F16400014EC800000074000240306E
+:1000400000005250000240A8000000B800029300D7
+:1000500000012110000293C000000FFC0003B4D87F
+:10006000000000040003C4D8020400480000000F90
+: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
+:100610000718040000AC0000081807D800050223E2
+:10062000071C000029B30000071C8000312E0A6D52
+:10063000071D000034A816B9071D80002E6C23E4A6
+:10064000071E0000034B2F80081E07F03F02022503
+:100650000118000000000000011800040000000064
+:1006600001180008000000000118000C0000000044
+:100670000118001000000000011800140000000024
+:1006800002180020000000010218002400000002EF
+:1006900002180028000000030218002C00000000CF
+:1006A00002180030000000040218003400000001AD
+:1006B00002180038000000000218003C0000000191
+:1006C000021800400000000402180044000000006E
+:1006D00002180048000000010218004C000000034E
+:1006E0000218005000000000021800540000000131
+:1006F00002180058000000040218005C000000000E
+:1007000002180060000000010218006400000003ED
+:1007100002180068000000000218006C00000001D0
+:1007200002180070000000040218007400000000AD
+:1007300002180078000000040218007C000000038A
+:100740000618008000000002021800A400007FFFCD
+:10075000021800A8000003FF021802240000000095
+:1007600002180234000000000218024C00000000D1
+:10077000021802E4000000FF061810000000040048
+:10078000021B8BC000000001021B8000000000342F
+:10079000021B804000000018021B80800000000C3B
+:1007A000021B80C0000000200C1B83000008647046
+:1007B0000A1B8300000001570B1B83000000055F2C
+:1007C0000A1B8340000000000C1B8340000002262F
+:1007D0000B1B834000000001021B83800008647033
+:1007E000021B83C000000226021B148000000001CF
+:1007F0000A1B148000000000021B9440000000014E
+:10080000061B944800000002061A1000000002B304
+:10081000041A1ACC00010227061A1AD00000000898
+:10082000061A2008000000C8061A20000000000276
+:10083000041A1BF800900228061A3718000000045A
+:10084000061A371000000002061A500000000002CD
+:10085000061A500800000004061A50180000000490
+:10086000061A502800000004061A50380000000440
+:10087000061A504800000004061A505800000004F0
+:10088000061A506800000004061A507800000002A2
+:10089000041A52C0000202B8061A405000000006B6
+:1008A000041A4068000202BA041A4040000402BC64
+:1008B000041A8000000102C0061A80040000000330
+:1008C000041A8010000102C1061A801400000003FF
+:1008D000041A8020000102C2061A802400000003CE
+:1008E000041A8030000102C3061A8034000000039D
+:1008F000041A8040000102C4061A8044000000036C
+:10090000041A8050000102C5061A8054000000033A
+:10091000041A8060000102C6061A80640000000309
+:10092000041A8070000102C7061A807400000003D8
+:10093000041A8080000102C8061A808400000003A7
+:10094000041A8090000102C9061A80940000000376
+:10095000041A80A0000102CA061A80A40000000345
+:10096000041A80B0000102CB061A80B40000000314
+:10097000041A80C0000102CC061A80C400000003E3
+:10098000041A80D0000102CD061A80D400000003B2
+:10099000041A80E0000102CE061A80E40000000381
+:1009A000041A80F0000102CF061A80F40000000350
+:1009B000041A8100000102D0061A8104000000031D
+:1009C000041A8110000102D1061A811400000003EC
+:1009D000041A8120000102D2061A812400000003BB
+:1009E000041A8130000102D3061A8134000000038A
+:1009F000041A8140000102D4061A81440000000359
+:100A0000041A8150000102D5061A81540000000327
+:100A1000041A8160000102D6061A816400000003F6
+:100A2000041A8170000102D7061A817400000003C5
+:100A3000041A8180000102D8061A81840000000394
+:100A4000041A8190000102D9061A81940000000363
+:100A5000041A81A0000102DA061A81A40000000332
+:100A6000041A81B0000102DB061A81B40000000301
+:100A7000041A81C0000102DC061A81C400000003D0
+:100A8000041A81D0000102DD061A81D4000000039F
+:100A9000041A81E0000102DE061A81E4000000036E
+:100AA000041A81F0000102DF061A81F4000000033D
+:100AB000041A8200000102E0061A8204000000030A
+:100AC000041A8210000102E1061A821400000003D9
+:100AD000041A8220000102E2061A822400000003A8
+:100AE000041A8230000102E3061A82340000000377
+:100AF000041A8240000102E4061A82440000000346
+:100B0000041A8250000102E5061A82540000000314
+:100B1000041A8260000102E6061A826400000003E3
+:100B2000041A8270000102E7061A827400000003B2
+:100B3000041A8280000102E8061A82840000000381
+:100B4000041A8290000102E9061A82940000000350
+:100B5000041A82A0000102EA061A82A4000000031F
+:100B6000041A82B0000102EB061A82B400000003EE
+:100B7000041A82C0000102EC061A82C400000003BD
+:100B8000041A82D0000102ED061A82D4000000038C
+:100B9000041A82E0000102EE061A82E4000000035B
+:100BA000041A82F0000102EF061A82F4000000032A
+:100BB000041A8300000102F0061A830400000003F7
+:100BC000041A8310000102F1061A831400000003C6
+:100BD000041A8320000102F2061A83240000000395
+:100BE000041A8330000102F3061A83340000000364
+:100BF000041A8340000102F4061A83440000000333
+:100C0000041A8350000102F5061A83540000000301
+:100C1000041A8360000102F6061A836400000003D0
+:100C2000041A8370000102F7061A8374000000039F
+:100C3000041A8380000102F8061A8384000000036E
+:100C4000041A8390000102F9061A8394000000033D
+:100C5000041A83A0000102FA061A83A4000000030C
+:100C6000041A83B0000102FB061A83B400000003DB
+:100C7000041A83C0000102FC061A83C400000003AA
+:100C8000041A83D0000102FD061A83D40000000379
+:100C9000041A83E0000102FE061A83E40000000348
+:100CA000041A83F0000102FF061A83F40000000317
+:100CB000041A840000010300061A840400000003E3
+:100CC000041A841000010301061A841400000003B2
+:100CD000041A842000010302061A84240000000381
+:100CE000041A843000010303061A84340000000350
+:100CF000041A844000010304061A8444000000031F
+:100D0000041A845000010305061A845400000003ED
+:100D1000041A846000010306061A846400000003BC
+:100D2000041A847000010307061A8474000000038B
+:100D3000041A848000010308061A8484000000035A
+:100D4000041A849000010309061A84940000000329
+:100D5000041A84A00001030A061A84A400000003F8
+:100D6000041A84B00001030B061A84B400000003C7
+:100D7000041A84C00001030C061A84C40000000396
+:100D8000041A84D00001030D061A84D40000000365
+:100D9000041A84E00001030E061A84E40000000334
+:100DA000041A84F00001030F061A84F40000000303
+:100DB000041A850000010310061A850400000003D0
+:100DC000041A851000010311061A8514000000039F
+:100DD000041A852000010312061A8524000000036E
+:100DE000041A853000010313061A8534000000033D
+:100DF000041A854000010314061A8544000000030C
+:100E0000041A855000010315061A855400000003DA
+:100E1000041A856000010316061A856400000003A9
+:100E2000041A857000010317061A85740000000378
+:100E3000041A858000010318061A85840000000347
+:100E4000041A859000010319061A85940000000316
+:100E5000041A85A00001031A061A85A400000003E5
+:100E6000041A85B00001031B061A85B400000003B4
+:100E7000041A85C00001031C061A85C40000000383
+:100E8000041A85D00001031D061A85D40000000352
+:100E9000041A85E00001031E061A85E40000000321
+:100EA000041A85F00001031F061A85F400000003F0
+:100EB000041A860000010320061A860400000003BD
+:100EC000041A861000010321061A8614000000038C
+:100ED000041A862000010322061A8624000000035B
+:100EE000041A863000010323061A8634000000032A
+:100EF000041A864000010324061A864400000003F9
+:100F0000041A865000010325061A865400000003C7
+:100F1000041A866000010326061A86640000000396
+:100F2000041A867000010327061A86740000000365
+:100F3000041A868000010328061A86840000000334
+:100F4000041A869000010329061A86940000000303
+:100F5000041A86A00001032A061A86A400000003D2
+:100F6000041A86B00001032B061A86B400000003A1
+:100F7000041A86C00001032C061A86C40000000370
+:100F8000041A86D00001032D061A86D4000000033F
+:100F9000041A86E00001032E061A86E4000000030E
+:100FA000041A86F00001032F061A86F400000003DD
+:100FB000041A870000010330061A870400000003AA
+:100FC000041A871000010331061A87140000000379
+:100FD000041A872000010332061A87240000000348
+:100FE000041A873000010333061A87340000000317
+:100FF000041A874000010334061A874400000003E6
+:10100000041A875000010335061A875400000003B4
+:10101000041A876000010336061A87640000000383
+:10102000041A877000010337061A87740000000352
+:10103000041A878000010338061A87840000000321
+:10104000041A879000010339061A879400000003F0
+:10105000041A87A00001033A061A87A400000003BF
+:10106000041A87B00001033B061A87B4000000038E
+:10107000041A87C00001033C061A87C4000000035D
+:10108000041A87D00001033D061A87D4000000032C
+:10109000041A87E00001033E061A87E400000003FB
+:1010A000041A87F00001033F061A87F400000003CA
+:1010B000041A880000010340061A88040000000397
+:1010C000041A881000010341061A88140000000366
+:1010D000041A882000010342061A88240000000335
+:1010E000041A883000010343061A88340000000304
+:1010F000041A884000010344061A884400000003D3
+:10110000041A885000010345061A885400000003A1
+:10111000041A886000010346061A88640000000370
+:10112000041A887000010347061A8874000000033F
+:10113000041A888000010348061A8884000000030E
+:10114000041A889000010349061A889400000003DD
+:10115000041A88A00001034A061A88A400000003AC
+:10116000041A88B00001034B061A88B4000000037B
+:10117000041A88C00001034C061A88C4000000034A
+:10118000041A88D00001034D061A88D40000000319
+:10119000041A88E00001034E061A88E400000003E8
+:1011A000041A88F00001034F061A88F400000003B7
+:1011B000041A890000010350061A89040000000384
+:1011C000041A891000010351061A89140000000353
+:1011D000041A892000010352061A89240000000322
+:1011E000041A893000010353061A893400000003F1
+:1011F000041A894000010354061A894400000003C0
+:10120000041A895000010355061A8954000000038E
+:10121000041A896000010356061A8964000000035D
+:10122000041A897000010357061A8974000000032C
+:10123000041A898000010358061A898400000003FB
+:10124000041A899000010359061A899400000003CA
+:10125000041A89A00001035A061A89A40000000399
+:10126000041A89B00001035B061A89B40000000368
+:10127000041A89C00001035C061A89C40000000337
+:10128000041A89D00001035D061A89D40000000306
+:10129000041A89E00001035E061A89E400000003D5
+:1012A000041A89F00001035F061A89F400000003A4
+:1012B000041A8A0000010360061A8A040000000371
+:1012C000041A8A1000010361061A8A140000000340
+:1012D000041A8A2000010362061A8A24000000030F
+:1012E000041A8A3000010363061A8A3400000003DE
+:1012F000041A8A4000010364061A8A4400000003AD
+:10130000041A8A5000010365061A8A54000000037B
+:10131000041A8A6000010366061A8A64000000034A
+:10132000041A8A7000010367061A8A740000000319
+:10133000041A8A8000010368061A8A8400000003E8
+:10134000041A8A9000010369061A8A9400000003B7
+:10135000041A8AA00001036A061A8AA40000000386
+:10136000041A8AB00001036B061A8AB40000000355
+:10137000041A8AC00001036C061A8AC40000000324
+:10138000041A8AD00001036D061A8AD400000003F3
+:10139000041A8AE00001036E061A8AE400000003C2
+:1013A000041A8AF00001036F061A8AF40000000391
+:1013B000041A8B0000010370061A8B04000000035E
+:1013C000041A8B1000010371061A8B14000000032D
+:1013D000041A8B2000010372061A8B2400000003FC
+:1013E000041A8B3000010373061A8B3400000003CB
+:1013F000041A8B4000010374061A8B44000000039A
+:10140000041A8B5000010375061A8B540000000368
+:10141000041A8B6000010376061A8B640000000337
+:10142000041A8B7000010377061A8B740000000306
+:10143000041A8B8000010378061A8B8400000003D5
+:10144000041A8B9000010379061A8B9400000003A4
+:10145000041A8BA00001037A061A8BA40000000373
+:10146000041A8BB00001037B061A8BB40000000342
+:10147000041A8BC00001037C061A8BC40000000311
+:10148000041A8BD00001037D061A8BD400000003E0
+:10149000041A8BE00001037E061A8BE400000003AF
+:1014A000041A8BF00001037F061A8BF4000000037E
+:1014B000041A8C0000010380061A8C04000000034B
+:1014C000041A8C1000010381061A8C14000000031A
+:1014D000041A8C2000010382061A8C2400000003E9
+:1014E000041A8C3000010383061A8C3400000003B8
+:1014F000041A8C4000010384061A8C440000000387
+:10150000041A8C5000010385061A8C540000000355
+:10151000041A8C6000010386061A8C640000000324
+:10152000041A8C7000010387061A8C7400000003F3
+:10153000041A8C8000010388061A8C8400000003C2
+:10154000041A8C9000010389061A8C940000000391
+:10155000041A8CA00001038A061A8CA40000000360
+:10156000041A8CB00001038B061A8CB4000000032F
+:10157000041A8CC00001038C061A8CC400000003FE
+:10158000041A8CD00001038D061A8CD400000003CD
+:10159000041A8CE00001038E061A8CE4000000039C
+:1015A000041A8CF00001038F061A8CF4000000036B
+:1015B000041A8D0000010390061A8D040000000338
+:1015C000041A8D1000010391061A8D140000000307
+:1015D000041A8D2000010392061A8D2400000003D6
+:1015E000041A8D3000010393061A8D3400000003A5
+:1015F000041A8D4000010394061A8D440000000374
+:10160000041A8D5000010395061A8D540000000342
+:10161000041A8D6000010396061A8D640000000311
+:10162000041A8D7000010397061A8D7400000003E0
+:10163000041A8D8000010398061A8D8400000003AF
+:10164000041A8D9000010399061A8D94000000037E
+:10165000041A8DA00001039A061A8DA4000000034D
+:10166000041A8DB00001039B061A8DB4000000031C
+:10167000041A8DC00001039C061A8DC400000003EB
+:10168000041A8DD00001039D061A8DD400000003BA
+:10169000041A8DE00001039E061A8DE40000000389
+:1016A000041A8DF00001039F061A8DF40000000358
+:1016B000041A8E00000103A0061A8E040000000325
+:1016C000041A8E10000103A1061A8E1400000003F4
+:1016D000041A8E20000103A2061A8E2400000003C3
+:1016E000041A8E30000103A3061A8E340000000392
+:1016F000041A8E40000103A4061A8E440000000361
+:10170000041A8E50000103A5061A8E54000000032F
+:10171000041A8E60000103A6061A8E6400000003FE
+:10172000041A8E70000103A7061A8E7400000003CD
+:10173000041A8E80000103A8061A8E84000000039C
+:10174000041A8E90000103A9061A8E94000000036B
+:10175000041A8EA0000103AA061A8EA4000000033A
+:10176000041A8EB0000103AB061A8EB40000000309
+:10177000041A8EC0000103AC061A8EC400000003D8
+:10178000041A8ED0000103AD061A8ED400000003A7
+:10179000041A8EE0000103AE061A8EE40000000376
+:1017A000041A8EF0000103AF061A8EF40000000345
+:1017B000041A8F00000103B0061A8F040000000312
+:1017C000041A8F10000103B1061A8F1400000003E1
+:1017D000041A8F20000103B2061A8F2400000003B0
+:1017E000041A8F30000103B3061A8F34000000037F
+:1017F000041A8F40000103B4061A8F44000000034E
+:10180000041A8F50000103B5061A8F54000000031C
+:10181000041A8F60000103B6061A8F6400000003EB
+:10182000041A8F70000103B7061A8F7400000003BA
+:10183000041A8F80000103B8061A8F840000000389
+:10184000041A8F90000103B9061A8F940000000358
+:10185000041A8FA0000103BA061A8FA40000000327
+:10186000041A8FB0000103BB061A8FB400000003F6
+:10187000041A8FC0000103BC061A8FC400000003C5
+:10188000041A8FD0000103BD061A8FD40000000394
+:10189000041A8FE0000103BE061A8FE4000000075F
+:1018A000041A62C0002003BF061A1AF000000042AA
+:1018B000061AAF0000000008061AE000000005400C
+:1018C000061AD00000000072061AD248000000106C
+:1018D000061AD6B000000020061AD470000000904E
+:1018E000061AD46800000002061AA000000001C415
+:1018F000061A300000000010061A308000000010A8
+:10190000061A310000000010061A31800000001095
+:10191000061A330000000012061A3390000000700F
+:10192000061AD45800000002061AD348000000022C
+:10193000061AD35800000020061AA710000001C4A0
+:10194000061A304000000010061A30C000000010D7
+:10195000061A314000000010061A31C000000010C5
+:10196000061A334800000012061A355000000070B5
+:10197000061AD46000000002061AD35000000002CC
+:10198000061AD3D800000020021AAE200000000082
+:10199000061A500000000002061A508000000012D3
+:1019A000041A4000000203DF041A63C0000203E1CE
+:1019B000061A700000000004061A32000000000839
+:1019C000021AAE2400000000061A501000000002A7
+:1019D000061A50C800000012041A4008000203E36F
+:1019E000041A63C8000203E5061A70100000000420
+:1019F000061A322000000008021AAE28000000007B
+:101A0000061A502000000002061A511000000012B1
+:101A1000041A4010000203E7041A63D0000203E92D
+:101A2000061A702000000004061A32400000000868
+:101A3000021AAE2C00000000061A5030000000020E
+:101A4000061A515800000012041A4018000203EB55
+:101A5000041A63D8000203ED061A70300000000477
+:101A6000061A326000000008021AAE3000000000C2
+:101A7000061A504000000002061A51A00000001291
+:101A8000041A4020000203EF041A63E0000203F18D
+:101A9000061A704000000004061A32800000000898
+:101AA000021AAE3400000000061A50500000000276
+:101AB000061A51E800000012041A4028000203F33D
+:101AC000041A63E8000203F5061A705000000004CF
+:101AD000061A32A000000008021AAE38000000000A
+:101AE000061A506000000002061A52300000001270
+:101AF000041A4030000203F7041A63F0000203F9ED
+:101B0000061A706000000004061A32C000000008C7
+:101B1000021AAE3C00000000061A507000000002DD
+:101B2000061A527800000012041A4038000203FB23
+:101B3000041A63F8000203FD061A70700000000426
+:101B4000061A32E0000000080200A2A40000020908
+:101B50000200A270000000000200A2740000000059
+:101B60000200A270000000000200A2740000000049
+:101B70000200A270000000000200A2740000000039
+:101B80000200A270000000000200A2740000000029
+:101B9000020100B400000001020100B800000001D1
+:101BA000020100CC00000001020100D00000000191
+:101BB000020100DC00000001020101000000000140
+:101BC00002010104000000010201007C003000005D
+:101BD00002010084000000280201008C00000000C7
+:101BE00002010130000000040201025C000000015B
+:101BF0000201032800000000020160580000FFFFFE
+:101C0000020160700000000702010554000000306E
+:101C1000020100C400000001020100F80000000100
+:101C2000020100F00000000102010080003000000D
+:101C3000020100880000002802010090000000005E
+:101C40000201013400000004020102DC0000000176
+:101C50000201032C000000000201605C0000FFFF95
+:101C600002016074000000070201056400000030FA
+:101C7000020100C800000001020100FC0000000198
+:101C8000020100F400000001020C10000000002816
+:101C9000020C200800000211020C200C00000200BF
+:101CA000020C201000000204020C201C0000FFFFA8
+:101CB000020C20200000FFFF020C20240000FFFF88
+:101CC000020C20280000FFFF020C2038000000005A
+:101CD000020C203C00000037020C204000000021D4
+:101CE000020C204400000020060C20480000001DCB
+:101CF000020C20BC00000001060C20C00000003FC8
+:101D0000020C21BC00000001020C21C000000001F7
+:101D1000020C21C400000001060C21C80000001CB8
+:101D2000020C223807FFFFFF020C223C0000007F5C
+:101D3000020C224007FFFFFF020C22440000003F7C
+:101D4000010C224800000000010C224C00000000A1
+:101D5000010C225000000000010C22540000000081
+:101D6000010C225800000000010C225C0000000061
+:101D7000010C226000000000010C22640000000041
+:101D8000010C226800000000010C226C0000000021
+:101D9000010C227000000000010C22740000000001
+:101DA000010C227800000000010C227C00000000E1
+:101DB000020C22D80000FFFF020C22DC0000FFFF13
+:101DC000020C22E00000FFFF020C22E40000FFFFF3
+:101DD0000C0C2000000003E80A0C200000000001A9
+:101DE0000B0C200000000003020C40080000101142
+:101DF000020C400C00001000020C40100000100407
+:101E0000020C401400001021020C401C0000FFFFD7
+:101E1000020C40200000FFFF020C40240000FFFFE6
+:101E2000020C40280000FFFF020C40380000004672
+:101E3000020C403C0000000C060C40400000000278
+:101E4000020C404800000018020C404C000000F05A
+:101E5000060C40500000001F020C40CC00000001A6
+:101E6000060C40D00000003A020C41B8000000010E
+:101E7000060C41BC00000003020C41C80000000138
+:101E8000020C41CC00000001060C41D00000001AF9
+:101E9000020C423807FFFFFF020C423C0000007FAB
+:101EA000020C424007FFFFFF020C42440000003FCB
+:101EB000010C424800000000010C424C00000000F0
+:101EC000010C425000000000010C425400000000D0
+:101ED000010C425800000000010C425C00000000B0
+:101EE000010C426000000000010C42640000000090
+:101EF000010C426800000000010C426C0000000070
+:101F0000010C427000000000010C4274000000004F
+:101F1000010C427800000000010C427C000000002F
+:101F2000010C428000000000020C42D80000FFFFBC
+:101F3000020C42DC0000FFFF020C42E00000FFFF49
+:101F4000020C42E40000FFFF0C0C4000000003E81C
+:101F50000A0C4000000000010B0C400000000003D0
+:101F6000060D400000000A00020D0044000000328F
+:101F7000020D008C02150020020D009002150020B9
+:101F8000020D009408100000020D009800000036B9
+:101F9000020D00A000000000020D00A400000004DB
+:101FA000020D00A800000004060D00AC00000002B5
+:101FB000020D00B800000002020D00C00000000188
+:101FC000020D00C800000002020D00CC000000025B
+:101FD000020D015C00000001020D0164000000011F
+:101FE000020D016800000002020D02040000000161
+:101FF000020D020C00000020020D02100000004043
+:10200000020D021400000040020D02200000000337
+:10201000020D022400000018060D028000000012CC
+:10202000040D0300001803FF060D03600000000C00
+:10203000020D004C00000001020D005000000002E3
+:10204000020D005400000000020D005800000008BE
+:10205000060D005C00000004020D00C40000000436
+:10206000020D000400000001020D00080000000144
+:10207000020D000C00000001020D00100000000124
+:10208000020D001400000001020D00180000000104
+:10209000020D001C00000001020D002000000001E4
+:1020A000020D002400000001020D002800000001C4
+:1020B000020D002C00000001020D003000000001A4
+:1020C000020D003400000001020D00380000000184
+:1020D000020D003C00000001020D01140000000987
+:1020E000020D011C0000000A020D01240000000086
+:1020F000020D012C00000000020D01340000000060
+:10210000020D013C0000000B020D01440000000024
+:10211000020D011800000029020D01200000002A14
+:10212000020D012800000020020D013000000020F7
+:10213000020D013800000020020D01400000002BBC
+:10214000020D014800000020020D011400000019DA
+:10215000020D011C0000001A020D012400000010F5
+:10216000020D012C00000010020D013400000010CF
+:10217000020D013C0000001B020D01440000001094
+:10218000020D011800000039020D01200000003A84
+:10219000020D012800000030020D01300000003067
+:1021A000020D013800000030020D01400000003B2C
+:1021B000020D014800000030020D0114000000492A
+:1021C000020D011C0000004A020D01240000004025
+:1021D000020D012C00000040020D013400000040FF
+:1021E000020D013C0000004B020D014400000040C4
+:1021F000020D011800000069020D01200000006AB4
+:10220000020D012800000060020D01300000006096
+:10221000020D013800000060020D01400000006B5B
+:10222000020D014800000060020D01140000005979
+:10223000020D011C0000005A020D01240000005094
+:10224000020D012C00000050020D0134000000506E
+:10225000020D013C0000005B020D01440000005033
+:10226000020D011800000079020D01200000007A23
+:10227000020D012800000070020D01300000007006
+:10228000020D013800000070020D01400000007BCB
+:10229000020D014800000070060E2000000008003A
+:1022A000020E004C00000032020E009402150020C5
+:1022B000020E009802150020020E009C0000003063
+:1022C000020E00A008100000020E00A4000000365C
+:1022D000020E00A800000030020E00AC0000003129
+:1022E000020E00B400000003020E00B8000000005F
+:1022F000020E00C400000000020E00CC0000000628
+:10230000020E00D800000001020E0144000000018E
+:10231000020E014C00000001020E015000000002FC
+:10232000020E020400000001020E020C0000004038
+:10233000020E021000000040020E021C0000000409
+:10234000020E022000000020020E02240000000EF7
+:10235000020E02280000001B060E030000000012FF
+:10236000040E0280001B0417060E02EC000000059C
+:10237000020E00540000000C020E00580000000C79
+:10238000020E005C00000000020E00600000001061
+:10239000020E006400000010060E0068000000033A
+:1023A000020E00DC00000003020E00040000000129
+:1023B000020E000800000001020E000C00000001E7
+:1023C000020E001000000001020E001400000001C7
+:1023D000020E001800000001020E001C00000001A7
+:1023E000020E002000000001020E00240000000187
+:1023F000020E002800000001020E002C0000000167
+:10240000020E003000000001020E00340000000146
+:10241000020E003800000001020E003C0000000126
+:10242000020E004000000001020E00440000000106
+:10243000020E01100000000F020E01180000000043
+:10244000020E012000000000020E01280000000022
+:10245000020E01140000002F020E011C00000020DB
+:10246000020E012400000020020E012C00000020BA
+:10247000020E01100000001F020E011800000010E3
+:10248000020E012000000010020E012800000010C2
+:10249000020E01140000003F020E011C000000307B
+:1024A000020E012400000030020E012C000000305A
+:1024B000020E01100000004F020E01180000004043
+:1024C000020E012000000040020E01280000004022
+:1024D000020E01140000006F020E011C00000060DB
+:1024E000020E012400000060020E012C00000060BA
+:1024F000020E01100000005F020E011800000050E3
+:10250000020E012000000050020E012800000050C1
+:10251000020E01140000007F020E011C000000707A
+:10252000020E012400000070020E012C0000007059
+:102530000730040000D60000083007D80005043238
+:10254000073400003222000007348000312C0C894F
+:102550000735000038DD18D5073580002F16270D08
+:1025600007360000261532D30836711031DE0434E8
+:1025700001300000000000000130000400000000F5
+:1025800001300008000000000130000C00000000D5
+:1025900001300010000000000130001400000000B5
+:1025A0000230002000000001023000240000000280
+:1025B00002300028000000030230002C0000000060
+:1025C000023000300000000402300034000000013E
+:1025D00002300038000000000230003C0000000122
+:1025E00002300040000000040230004400000000FF
+:1025F00002300048000000010230004C00000003DF
+:1026000002300050000000000230005400000001C1
+:1026100002300058000000040230005C000000009E
+:10262000023000600000000102300064000000037E
+:1026300002300068000000000230006C0000000161
+:10264000023000700000000402300074000000003E
+:1026500002300078000000040230007C000000031B
+:102660000630008000000002023000A400007FFF5E
+:10267000023000A8000003FF023002240000000026
+:1026800002300234000000000230024C0000000062
+:10269000023002E40000FFFF0630200000000800C6
+:1026A00002338BC000000001023380000000001ADA
+:1026B000023380400000004E023380800000001092
+:1026C000023380C0000000200C33830000086470D7
+:1026D0000A338300000001570B3383000000055FBD
+:1026E0000A338340000000000C33834000000226C0
+:1026F0000B338340000000010233838000086470C4
+:10270000023383C00000022602331480000000015F
+:102710000A3314800000000006328000000001022D
+:1027200006322008000000C8063220000000000227
+:1027300004328520008F04360632875C00000009D1
+:1027400006323EB00000000606323ED00000000215
+:1027500006323E800000000A04323EA8000204C592
+:1027600006323E0000000020063250000000094002
+:102770000632400000000004043294C0000204C786
+:1027800006324110000000020632D0000000007046
+:102790000632DB00000000D40632DEA0000000029A
+:1027A0000632E00000000800063324000000011893
+:1027B00006321000000001880632500000000020A0
+:1027C00006325100000000200632520000000020B6
+:1027D00006325300000000200632540000000020A2
+:1027E000063255000000002006325600000000208E
+:1027F000063257000000002006325800000000207A
+:10280000063259000000002006325A000000002065
+:1028100006325B000000002006325C000000002051
+:1028200006325D000000002006325E00000000203D
+:1028300006325F0000000020063284F00000000233
+:1028400004328500000204C9063285080000000237
+:102850000632DE90000000020633286000000118F6
+:102860000632162000000188063250800000002049
+:102870000632518000000020063252800000002005
+:1028800006325380000000200632548000000020F1
+:1028900006325580000000200632568000000020DD
+:1028A00006325780000000200632588000000020C9
+:1028B000063259800000002006325A8000000020B5
+:1028C00006325B800000002006325C8000000020A1
+:1028D00006325D800000002006325E80000000208D
+:1028E00006325F8000000020063284F800000002FB
+:1028F00004328510000204CB063285180000000265
+:102900000632DE980000000202328450000000000F
+:102910000632401000000002023284540000000021
+:1029200006324020000000020232845800000000FD
+:1029300006324030000000020232845C00000000D9
+:1029400006324040000000020232846000000000B5
+:102950000632405000000002023284640000000091
+:10296000063240600000000202328468000000006D
+:1029700006324070000000020232846C0000000049
+:1029800006324080000000020720040000730000AF
+:1029900008200780001004CD072400002AD500007D
+:1029A0000724800027740AB60824D36063FA04CF92
+:1029B00001200000000000000120000400000000D1
+:1029C00001200008000000000120000C00000000B1
+:1029D0000120001000000000012000140000000091
+:1029E000022000200000000102200024000000025C
+:1029F00002200028000000030220002C000000003C
+:102A00000220003000000004022000340000000119
+:102A100002200038000000000220003C00000001FD
+:102A200002200040000000040220004400000000DA
+:102A300002200048000000010220004C00000003BA
+:102A4000022000500000000002200054000000019D
+:102A500002200058000000040220005C000000007A
+:102A6000022000600000000102200064000000035A
+:102A700002200068000000000220006C000000013D
+:102A8000022000700000000402200074000000001A
+:102A900002200078000000040220007C00000003F7
+:102AA0000620008000000002022000A400007FFF3A
+:102AB000022000A8000003FF022002240000000002
+:102AC00002200234000000000220024C000000003E
+:102AD000022002E40000FFFF0620200000000800A2
+:102AE00002238BC0000000010223800000000010C0
+:102AF000022380400000001202238080000000308A
+:102B0000022380C00000000E0C23830000086470C4
+:102B10000A238300000001570B2383000000055F98
+:102B20000A238340000000000C238340000002269B
+:102B30000B2383400000000102238380000864709F
+:102B4000022383C00000022602231480000000013B
+:102B50000A2314800000000006221000000000423A
+:102B600006222008000000C8062220000000000203
+:102B70000622B000000003300622F40000000053DB
+:102B80000422F54C000104D10622F5500000000398
+:102B90000422F55C000104D20622F5600000000367
+:102BA0000422F56C000104D30622F5700000000336
+:102BB0000422F57C000104D40622F5800000000305
+:102BC0000422F58C000104D50622F59000000003D4
+:102BD0000422F59C000104D60622F5A000000003A3
+:102BE0000422F5AC000104D70622F5B00000000372
+:102BF0000422F5BC000104D80622F5C000000046FE
+:102C00000622E2000000044004221240009004D991
+:102C100006223000000000C006226700000001000C
+:102C2000062290000000040004226B0800200569C1
+:102C3000062211F000000006042212080006058991
+:102C4000062212200000000206224000000005C0FB
+:102C50000622C000000000060422C0180006058FEE
+:102C60000622C0300000000A0422C0580006059564
+:102C70000622C0700000000A0422C0980006059BCE
+:102C80000622C0B00000000A0422C0D8000605A138
+:102C90000622C0F00000000A0422C118000605A7A1
+:102CA0000622C1300000000A0422C158000605AD0A
+:102CB0000622C1700000000A0422C198000605B374
+:102CC0000622C1B00000000A0422C1D8000605B9DE
+:102CD0000622C1F00000000A0422C218000605BF47
+:102CE0000622C2300000000A0422C258000605C5B0
+:102CF0000622C2700000000A0422C298000605CB1A
+:102D00000622C2B00000000A0422C2D8000605D183
+:102D10000622C2F00000000A0422C318000605D7EC
+:102D20000622C3300000000A0422C358000605DD55
+:102D30000622C3700000000A0422C398000605E3BF
+:102D40000622C3B00000000A0422C3D8000605E929
+:102D50000622C3F00000000A0422C418000605EF92
+:102D60000622C4300000000A0422C458000605F5FB
+:102D70000622C4700000000A0422C498000605FB65
+:102D80000622C4B00000000A0422C4D800060601CE
+:102D90000622C4F00000000A0422C5180006060737
+:102DA0000622C5300000000A0422C5580006060DA0
+:102DB0000622C5700000000A0422C598000606130A
+:102DC0000622C5B00000000A0422C5D80006061974
+:102DD0000622C5F00000000A0422C6180006061FDD
+:102DE0000622C6300000000A0422C6580006062546
+:102DF0000622C6700000000A0422C6980006062BB0
+:102E00000622C6B00000000A0422C6D80006063119
+:102E10000622C6F00000000A0422C7180006063782
+:102E20000622C7300000000A0422C7580006063DEB
+:102E30000622C7700000000A0422C7980006064355
+:102E40000622C7B00000000A0422C7D800060649BF
+:102E50000622C7F00000000A0422C8180006064F28
+:102E60000622C8300000000A0422C8580006065591
+:102E70000622C8700000000A0422C8980006065BFB
+:102E80000622C8B00000000A0422C8D80006066165
+:102E90000622C8F00000000A0422C91800060667CE
+:102EA0000622C9300000000A0422C9580006066D37
+:102EB0000622C9700000000A0422C99800060673A1
+:102EC0000622C9B00000000A0422C9D8000606790B
+:102ED0000622C9F00000000A0422CA180006067F74
+:102EE0000622CA300000000A0422CA5800060685DD
+:102EF0000622CA700000000A0422CA980006068B47
+:102F00000622CAB00000000A0422CAD800060691B0
+:102F10000622CAF00000000A0422CB180006069719
+:102F20000622CB300000000A0422CB580006069D82
+:102F30000622CB700000000A0422CB98000606A3EC
+:102F40000622CBB00000000A0422CBD8000606A956
+:102F50000622CBF00000000A0422CC18000606AFBF
+:102F60000622CC300000000A0422CC58000606B528
+:102F70000622CC700000000A0422CC98000606BB92
+:102F80000622CCB00000000A0422CCD8000606C1FC
+:102F90000622CCF00000000A0422CD18000606C765
+:102FA0000622CD300000000A0422CD58000606CDCE
+:102FB0000622CD700000000A0422CD98000606D338
+:102FC0000622CDB00000000A0422CDD8000606D9A2
+:102FD0000622CDF00000000A0422CE18000606DF0B
+:102FE0000622CE300000000A0422CE58000606E574
+:102FF0000622CE700000000A0422CE98000606EBDE
+:103000000622CEB00000000A0422CED8000606F147
+:103010000622CEF00000000A0422CF18000606F7B0
+:103020000622CF300000000A0422CF58000606FD19
+:103030000622CF700000000A0422CF980006070382
+:103040000622CFB00000000A0422CFD800060709EC
+:103050000622CFF00000000A0422D0180006070F55
+:103060000622D0300000000A0422D05800060715BE
+:103070000622D0700000000A0422D0980006071B28
+:103080000622D0B00000000A0422D0D80006072192
+:103090000622D0F00000000A0422D11800060727FB
+:1030A0000622D1300000000A0422D1580006072D64
+:1030B0000622D1700000000A0422D19800060733CE
+:1030C0000622D1B00000000A0422D1D80006073938
+:1030D0000622D1F00000000A0422D2180006073FA1
+:1030E0000622D2300000000A0422D258000607450A
+:1030F0000622D2700000000A0422D2980006074B74
+:103100000622D2B00000000A0422D2D800060751DD
+:103110000622D2F00000000A0422D3180006075746
+:103120000622D3300000000A0422D3580006075DAF
+:103130000622D3700000000A0422D3980006076319
+:103140000622D3B00000000A0422D3D80006076983
+:103150000622D3F00000000A0422D4180006076FEC
+:103160000622D4300000000A0422D4580006077555
+:103170000622D4700000000A0422D4980006077BBF
+:103180000622D4B00000000A0422D4D80006078129
+:103190000622D4F00000000A0422D5180006078792
+:1031A0000622D5300000000A0422D5580006078DFB
+:1031B0000622D5700000000A0422D5980006079365
+:1031C0000622D5B00000000A0422D5D800060799CF
+:1031D0000622D5F00000000A0422D6180006079F38
+:1031E0000622D6300000000A0422D658000607A5A1
+:1031F0000622D6700000000A0422D698000607AB0B
+:103200000622D6B00000000A0422D6D8000607B174
+:103210000622D6F00000000A0422D718000607B7DD
+:103220000622D7300000000A0422D758000607BD46
+:103230000622D7700000000A0422D798000607C3B0
+:103240000622D7B00000000A0422D7D8000607C91A
+:103250000622D7F00000000A0422D818000607CF83
+:103260000622D8300000000A0422D858000607D5EC
+:103270000622D8700000000A0422D898000607DB56
+:103280000622D8B00000000A0422D8D8000607E1C0
+:103290000622D8F00000000A0422D918000607E729
+:1032A0000622D9300000000A0422D958000607ED92
+:1032B0000622D9700000000A0422D998000607F3FC
+:1032C0000622D9B00000000A0422D9D8000607F966
+:1032D0000622D9F00000000A0422DA18000607FFCF
+:1032E0000622DA300000000A0422DA580006080537
+:1032F0000622DA700000000A0422DA980006080BA1
+:103300000622DAB00000000A0422DAD8000608110A
+:103310000622DAF00000000A0422DB180006081773
+:103320000622DB300000000A0422DB580006081DDC
+:103330000622DB700000000A0422DB980006082346
+:103340000622DBB00000000A0422DBD800060829B0
+:103350000622DBF00000000A0422DC180006082F19
+:103360000622DC300000000A0422DC580006083582
+:103370000622DC700000000A0422DC980006083BEC
+:103380000622DCB00000000A0422DCD80006084156
+:103390000622DCF00000000A0422DD1800060847BF
+:1033A0000622DD300000000A0422DD580006084D28
+:1033B0000622DD700000000A0422DD980006085392
+:1033C0000622DDB00000000A0422DDD800060859FC
+:1033D0000622DDF00000000A0422DE180006085F65
+:1033E0000622DE300000000A0422DE5800060865CE
+:1033F0000622DE700000000A0422DE980006086B38
+:103400000622DEB00000000A0422DED800060871A1
+:103410000622DEF00000000A0422DF18000608770A
+:103420000622DF300000000A0422DF580006087D73
+:103430000622DF700000000A0422DF9800060883DD
+:103440000622DFB00000000A0422DFD80006088947
+:103450000622DFF00000000A0422E0180006088FB0
+:103460000622E0300000000A0422E0580006089519
+:103470000622E0700000000A0422E0980006089B83
+:103480000622E0B00000000A0422E0D8000608A1ED
+:103490000622E0F00000000A0422E118000608A756
+:1034A0000622E1300000000A0422E158000608ADBF
+:1034B0000622E1700000000A0422E198000608B329
+:1034C0000622E1B00000000A0422E1D8000608B993
+:1034D0000622E1F000000004062215380000000278
+:1034E000062211E8000000020622F3000000000896
+:1034F00002221148000000000622590000000006C8
+:103500000622330000000002062260400000003066
+:103510000622F320000000080222114C00000000E7
+:103520000622591800000006062233080000000297
+:1035300006226100000000300622F340000000086F
+:10354000022211500000000006225930000000063F
+:103550000622331000000002062261C00000003085
+:103560000622F3600000000802221154000000004F
+:103570000622594800000006062233180000000207
+:1035800006226280000000300622F380000000085E
+:1035900002221158000000000622596000000006B7
+:1035A00006223320000000020622634000000030A3
+:1035B0000622F3A0000000080222115C00000000B7
+:1035C0000622597800000006062233280000000277
+:1035D00006226400000000300622F3C0000000084C
+:1035E000022211600000000006225990000000062F
+:1035F0000622333000000002062264C000000030C2
+:103600000622F3E00000000802221164000000001E
+:10361000062259A8000000060622333800000002E6
+:10362000062265800000003002161000000000280D
+:1036300002170008000000020217002C000000031F
+:103640000217003C000000040217004400000000C4
+:1036500002170048000000020217004C0000009012
+:1036600002170050000000900217005400800090E4
+:103670000217005808100000021700700000000632
+:1036800002170078000009FF0217007C0000076C99
+:10369000021701C4081000000217034400000001D3
+:1036A000021704000000008A0217040400000080D2
+:1036B00002170408000000810217040C00000080BB
+:1036C000021704100000008A021704140000008092
+:1036D00002170418000000810217041C000000807B
+:1036E000021704300000008A021704340000008032
+:1036F00002170438000000810217043C000000801B
+:10370000021704400000008A0217044400000080F1
+:1037100002170448000000810217044C00000080DA
+:10372000021704800000008A021704840000008051
+:1037300002170488000000810217048C000000803A
+:1037400002170038007C1004021700040000000F6C
+:10375000021701EC00000002021701F40000000251
+:10376000021701EC00000002021701F40000000241
+:10377000021701EC00000002021701F40000000231
+:10378000021701EC00000002021701F40000000221
+:10379000021701EC00000002021701F40000000211
+:1037A000021701EC00000002021701F40000000201
+:1037B000021701EC00000002021701F400000002F1
+:1037C000021701EC00000002021701F400000002E1
+:1037D0000616402400000002021640700000001C83
+:1037E000021642080000000102164210000000010B
+:1037F00002164220000000010216422800000001CB
+:10380000021642300000000102164238000000019A
+:1038100002164260000000020C16401C0003D0900B
+:103820000A16401C0000009C0B16401C0000027190
+:103830000216403000000028021640340000002C20
+:1038400002164038000000300216404400000020FC
+:103850000216400000000001021640D800000001DE
+:1038600002164008000000010216400C0000000192
+:103870000216401000000001021642400000000045
+:1038800002164248000000000616427000000002C6
+:1038900002164250000000000216425800000000CC
+:1038A0000616428000000002021660080000121492
+:1038B0000216600C000012000216601000001204D4
+:1038C0000216601C0000FFFF021660200000FFFFD0
+:1038D000021660240000FFFF021660280000FFFFB0
+:1038E00002166038000000200216603C0000001044
+:1038F0000616604000000002021660480000002327
+:103900000216604C000000240216605000000025E2
+:1039100002166054000000260216605800000027BE
+:103920000216605C000000110216606000000000DA
+:10393000021660640000002B021660680000002C74
+:103940000216606C0000002D02166070000000EC92
+:103950000216607400000000021660780000002962
+:103960000216607C0000002A021660800000002F12
+:10397000061660840000000D021660B80000000109
+:10398000061660BC00000008021660DC00000001A2
+:10399000061660E000000004021660F0000000015E
+:1039A000061660F40000000302166100000000012A
+:1039B000061661040000002D021661B80000000127
+:1039C000061661BC00000008021661DC0000000160
+:1039D000061661E000000004021661F0000000011C
+:1039E000061661F4000000030216620000000001E8
+:1039F000061662040000000D0216623807FFFFFF82
+:103A00000216623C0000007F0216624007FFFFFFC3
+:103A1000021662440000003F0116624800000000E8
+:103A20000116624C00000000011662500000000008
+:103A300001166254000000000116625800000000E8
+:103A40000116625C000000000116626000000000C8
+:103A500001166264000000000116626800000000A8
+:103A60000116626C00000000011662700000000088
+:103A70000116627400000000011662780000000068
+:103A80000116627C00000000011662D400000000F4
+:103A9000021662D80000FFFF021662DC0000FFFF82
+:103AA000021662E00000FFFF021662E40000FFFF62
+:103AB0000C166000000003E80A1660000000000118
+:103AC0000B16600000000003021680400000000694
+:103AD0000216804400000005021680480000000A1B
+:103AE0000216804C000000050216805400000002FF
+:103AF000021680CC00000004021680D000000004F2
+:103B0000021680D400000004021680D800000004D1
+:103B1000021680DC00000004021680E000000004B1
+:103B2000021680E400000004021680E80000000491
+:103B30000216880400000006021680300000007C97
+:103B4000021680340000003D021680380000003F5D
+:103B50000216803C0000009C0216E6E800006000AF
+:103B60000216E6EC000060000216E6F000006000BD
+:103B70000216E6F40000600002168234000025E41C
+:103B8000021682380000800002168094000025E3AF
+:103B9000021681F400000C08021681F800000040B3
+:103BA000021681FC000001000216820000000020C5
+:103BB000021682040000001702168208000000802E
+:103BC0000216820C000002000216821000000000A3
+:103BD0000216823C0000001302168220008F008F24
+:103BE0000216821C008F008F021680F00000000772
+:103BF0000216821801FF01FF0216821401FF01FF65
+:103C0000061680F4000000020216811C0000000568
+:103C10000216812000000005021681240000000524
+:103C200002168128000000080216812C0000000600
+:103C300002168130000000070616813400000004DF
+:103C4000021680FC000000000616814400000002FD
+:103C50000216814C00000004021681500000000191
+:103C6000021681540000000202168158000000056F
+:103C70000216815C0000000502168160000000054C
+:103C80000216816400000005021681680000000829
+:103C900002168100000000000216816C0000000680
+:103CA00002168170000000070616817400000006ED
+:103CB0000216818C000000040216819000000001B1
+:103CC0000216810400000000021681940000000228
+:103CD00002168198000000050216819C0000000574
+:103CE000021681A000000005021681A40000000554
+:103CF000021681A800000008021681AC0000000630
+:103D0000021681B000000007061681B40000000210
+:103D10000216810800000000061681BC00000004A5
+:103D2000021681CC00000004021681D000000001C0
+:103D3000021681D400000002021681D8000000059E
+:103D4000021681DC00000005021681E0000000057B
+:103D50000216810C00000004021681E40000000538
+:103D6000021681E800000008021681EC000000063F
+:103D7000021681F000000007021681100000000109
+:103D800002168114000000020216811800000005CE
+:103D90000216809C0000004C021680A00000004C1F
+:103DA000061680C400000002021680A40000000075
+:103DB000021680A800000000021680AC0000004C33
+:103DC000061680B0000000050216E6F800000204A6
+:103DD00002168240003F003F02168244003F003F2F
+:103DE00006168290000000040216824800800080BF
+:103DF0000216824C008000800216825001000100F1
+:103E000002168254010001000616825800000002CA
+:103E100002168260004000400216826400400040AA
+:103E2000021682681E001E000216826C1E001E0012
+:103E3000021682704000400002168274400040006A
+:103E400002168278800080000216827C800080004A
+:103E500002168280200020000216828420002000AA
+:103E60000616828800000002021680900000004BB7
+:103E700002168060000001400216806400000140CC
+:103E8000061680880000000202168068000000000C
+:103E90000216806C0000000002168070000000C056
+:103EA00006168074000000050216880C010101014D
+:103EB000021688100101200402168814200810013F
+:103EC00002168818010101200216881C0101010157
+:103ED00002168820010120040216882420081001FF
+:103EE00002168828010101200216882C20081001E2
+:103EF00002168830010101200216883401010101F7
+:103F000002168838010120040216883C200810019E
+:103F100002168840010101200216884401010101B6
+:103F200002168848010120040216E6BC00000000C9
+:103F30000216E6C0000000020216E6C400000004FB
+:103F40000216E6C8000000060216E7940000000111
+:103F5000021680EC000000FF0214000000000001C7
+:103F60000215C024000000000215C0EC0000000192
+:103F70000215C0F0000000010615C100000000029B
+:103F800002140004000000010214000800000001F7
+:103F90000214000C000000010214003000000001B7
+:103FA000021400340000000102140040000000016F
+:103FB000021400440000FFFF061400040000000388
+:103FC0000214000000000000060280000000200033
+:103FD0000202005800000032020200A00315002077
+:103FE000020200A403150020020200A80100003014
+:103FF000020200AC08100000020200B0000000360F
+:10400000020200B400000030020200B800000031DB
+:10401000020200BC00000002020200C00000000515
+:10402000020200C400000002020200C800000002F8
+:10403000020200D000000007020200DC00000000C5
+:10404000020200E000000005020200E4000000039C
+:10405000020200F000000001020200FC0000000665
+:1040600002020120000000000202013400000002F0
+:10407000020201B0000000010202020C0000000177
+:1040800002020214000000010202021800000002F5
+:1040900002020404000000010202040C00000040BF
+:1040A00002020410000000400202041C0000000490
+:1040B000020204200000002002020424000000028A
+:1040C0000202042800000020060205000000001281
+:1040D00004020480002008BF020200600000000FFC
+:1040E00002020064000000070202006800000000F5
+:1040F0000202006C0000000E020200700000000EC0
+:104100000602007400000003020200F40000000434
+:104110000202000400000001020200080000000189
+:104120000202000C00000001020200100000000169
+:104130000202001400000001020200180000000149
+:104140000202001C00000001020200200000000129
+:104150000202002400000001020200280000000109
+:104160000202002C000000010202003000000001E9
+:1041700002020034000000010202003800000001C9
+:104180000202003C000000010202004000000001A9
+:104190000202004400000001020200480000000189
+:1041A0000202004C00000001020200500000000169
+:1041B00002020108000000C802020118000000020B
+:1041C000020201C400000000020201CC0000000055
+:1041D000020201D400000002020201DC0000000221
+:1041E000020201E4000000FF020201EC000000FFF7
+:1041F00002020100000000000202010C000000C8E1
+:104200000202011C00000002020201C800000000BE
+:10421000020201D000000000020201D800000002EA
+:10422000020201E000000002020201E8000000FFBB
+:10423000020201F0000000FF020201040000002061
+:1042400002020108000000C802020118000000027A
+:10425000020201C400000000020201CC00000000C4
+:10426000020201D400000002020201DC0000000290
+:10427000020201E4000000FF020201EC000000FF66
+:1042800002020100000000100202010C000000C840
+:104290000202011C00000002020201C8000000002E
+:1042A000020201D000000000020201D8000000025A
+:1042B000020201E000000002020201E8000000FF2B
+:1042C000020201F0000000FF0202010400000030C1
+:1042D00002020108000000C80202011800000002EA
+:1042E000020201C400000000020201CC0000000034
+:1042F000020201D400000002020201DC0000000200
+:10430000020201E4000000FF020201EC000000FFD5
+:1043100002020100000000400202010C000000C87F
+:104320000202011C00000002020201C8000000009D
+:10433000020201D000000000020201D800000002C9
+:10434000020201E000000002020201E8000000FF9A
+:10435000020201F0000000FF020201040000006000
+:1043600002020108000000C8020201180000000259
+:10437000020201C400000000020201CC00000000A3
+:10438000020201D400000002020201DC000000026F
+:10439000020201E4000000FF020201EC000000FF45
+:1043A00002020100000000500202010C000000C8DF
+:1043B0000202011C00000002020201C8000000000D
+:1043C000020201D000000000020201D80000000239
+:1043D000020201E000000002020201E8000000FF0A
+:1043E000020201F0000000FF020201040000007060
+:1043F0000728040000B50000082807B8000908DFF6
+:10440000072C000028C30000072C800036720A31F8
+:10441000072D000035B617CE072D80003B00253C48
+:10442000072E0000366D33FD072E80001AA8419933
+:10443000082EBF20281C08E1012800000000000011
+:10444000012800040000000001280008000000000E
+:104450000128000C000000000128001000000000EE
+:1044600001280014000000000228002000000001C4
+:104470000228002400000002022800280000000397
+:104480000228002C00000000022800300000000478
+:10449000022800340000000102280038000000005B
+:1044A0000228003C00000001022800400000000437
+:1044B000022800440000000002280048000000011B
+:1044C0000228004C000000030228005000000000F9
+:1044D00002280054000000010228005800000004D7
+:1044E0000228005C000000000228006000000001BB
+:1044F0000228006400000003022800680000000099
+:104500000228006C00000001022800700000000476
+:104510000228007400000000022800780000000457
+:104520000228007C00000003062800800000000232
+:10453000022800A400007FFF022800A8000003FF5B
+:1045400002280224000000000228023400000000BB
+:104550000228024C00000000022802E40000FFFFD5
+:104560000628200000000800022B8BC0000000017C
+:10457000022B800000000000022B80400000001889
+:10458000022B80800000000C022B80C0000000661F
+:104590000C2B8300000864700A2B83000000015775
+:1045A0000B2B83000000055F0A2B834000000000F6
+:1045B0000C2B8340000002260B2B834000000001DF
+:1045C000022B838000086470022B83C00000022647
+:1045D000022B1480000000010A2B14800000000050
+:1045E000022B944000000001062B944800000002BA
+:1045F000062A9A7000000004042A9A80000408E346
+:10460000062A9A9000000002042A9A98000208E7FD
+:10461000062A900000000048062A2008000000C872
+:10462000062A200000000002062A912800000086C9
+:10463000062AC00000000120062A9348000000035B
+:10464000042A9354000108E9062A9FB000000002E2
+:10465000042A9418000208EA042A9CD0000108ECFD
+:10466000062A9CD400000011042A9D20008F08ED2A
+:10467000062A9F5C00000005042A30000002097C25
+:10468000062A300800000100062A40400000001001
+:10469000042A40000010097E042A84080002098EC2
+:1046A000042ACF4000040990042ACF600002099434
+:1046B000062A9FA000000004062A600000000540B2
+:1046C000062A9D1800000002062AB00000000050D3
+:1046D000062ABB7000000070062ABB6800000002BA
+:1046E000062AB94800000004062AD000000008008D
+:1046F000062AC48000000150062A942000000032DF
+:10470000062A502000000002062A50300000000255
+:10471000062A500000000002062A50100000000285
+:10472000022A520800000001042A9AA000020996F9
+:10473000062A95B000000022042A96380001099844
+:10474000062A963C00000003062A96E0000000229C
+:10475000042A976800010999062A976C0000000353
+:10476000062A981000000022042A98980001099A4D
+:10477000062A989C00000003062A994000000022A7
+:10478000042A99C80001099B062A99CC000000035D
+:10479000062ABB5800000002062AC9C000000150CA
+:1047A000062A94E800000032062A50280000000281
+:1047B000062A503800000002062A500800000002B5
+:1047C000062A501800000002022A520C00000001C4
+:1047D000042A9AA80002099C062A96480000002292
+:1047E000042A96D00001099E062A96D400000003F0
+:1047F000062A977800000022042A98000001099FE9
+:10480000062A980400000003062A98A80000002247
+:10481000042A9930000109A0062A993400000003F7
+:10482000062A99D800000022042A9A60000109A1F2
+:10483000062A9A6400000003062ABB6000000002FA
+:10484000022ACF0000000000042A9AB0001009A23A
+:10485000062A50480000000E022ACF040000000083
+:10486000042A9AF0001009B2062A50800000000EB7
+:10487000022ACF0800000000042A9B30001009C261
+:10488000062A50B80000000E022ACF0C00000000DB
+:10489000042A9B70001009D2062A50F00000000E76
+:1048A000022ACF1000000000042A9BB0001009E289
+:1048B000062A51280000000E022ACF140000000032
+:1048C000042A9BF0001009F2062A51600000000E35
+:1048D000022ACF1800000000042A9C3000100A02AF
+:1048E000062A51980000000E022ACF1C000000008A
+:1048F000042A9C7000100A12062A51D00000000EF3
+:104900000210100800000001021010500000000109
+:10491000021010000003D000021010040000003D3F
+:104920000910180002000A220910110000100C22C0
+:1049300006101140000000080910116000100C3230
+:10494000061011A00000001806102400000000E06E
+:104950000210201C000000000210202000000001B6
+:10496000021020C00000000202102004000000011C
+:104970000210200800000001021030D800000001E1
+:1049800009103C0000050C420910380000050C47D6
+:104990000910392000050C4C09103B0000050C5192
+:1049A00006104C000000010002104028000000101A
+:1049B0000210404400003FFF021040580028000051
+:1049C000021040840084924A021040580000000007
+:1049D00002104138000000010210413800000001BF
+:1049E00002104138000000010210413800000001AF
+:1049F000021041380000000102104138000000019F
+:104A0000021041380000000102104138000000018E
+:104A10000212049001F680400212051400003C10BE
+:104A200002120494FFFFFFFF02120498FFFFFFFF32
+:104A30000212049CFFFFFFFF021204A0FFFFFFFF12
+:104A4000021204A4FFFFFFFF021204A8FFFFFFFFF2
+:104A5000021204ACFFFFFFFF021204B0FFFFFFFFD2
+:104A6000021204B8FFFFFFFF021204BCFFFFFFFFAA
+:104A7000021204C0FFFFFFFF021204C4FFFFFFFF8A
+:104A8000021204C8FFFFFFFF021204CCFFFFFFFF6A
+:104A9000021204D0FFFFFFFF021204D8FFFFFFFF46
+:104AA000021204DCFFFFFFFF021204E0FFFFFFFF22
+:104AB000021204E4FFFFFFFF021204E8FFFFFFFF02
+:104AC000021204ECFFFFFFFF021204F0FFFFFFFFE2
+:104AD000021204F4FFFFFFFF021204F8FFFFFFFFC2
+:104AE000021204FCFFFFFFFF02120500FFFFFFFFA1
+:104AF00002120504FFFFFFFF02120508FFFFFFFF80
+:104B00000212050CFFFFFFFF02120510FFFFFFFF5F
+:104B1000021204D4F800C000021204B4F0005000E5
+:104B200002120390000000080212039C000000081B
+:104B3000021203A000000008021203A400000002F9
+:104B4000021203BC00000004021203C000000005B2
+:104B5000021203C400000004021203D0000000008F
+:104B60000212036C00000001021201BC00000040B0
+:104B7000021201C000001808021201C4000008035C
+:104B8000021201C800000803021201CC000000401C
+:104B9000021201D000000003021201D40000080339
+:104BA000021201D800000803021201DC0000080311
+:104BB000021201E000010003021201E400000803F8
+:104BC000021201E800000803021201EC00000003D9
+:104BD000021201F000000003021201F400000003C1
+:104BE000021201F800000003021201FC00000003A1
+:104BF000021202000000000302120204000000037F
+:104C000002120208000000030212020C000000035E
+:104C1000021202100000000302120214000000033E
+:104C200002120218000000030212021C000000031E
+:104C300002120220000000030212022400000003FE
+:104C400002120228000024030212022C0000002F8E
+:104C500002120230000000090212023400000019A2
+:104C600002120238000001840212023C000001839B
+:104C70000212024000000306021202440000001962
+:104C800002120248000000060212024C0000030655
+:104C90000212025000000306021202540000030632
+:104CA0000212025800000C860212025C0000030689
+:104CB00002120260000003060212026400000006F5
+:104CC00002120268000000060212026C00000006D8
+:104CD00002120270000000060212027400000006B8
+:104CE00002120278000000060212027C0000000698
+:104CF0000212028000000006021202840000000678
+:104D000002120288000000060212028C0000000657
+:104D10000212029000000006021202940000000637
+:104D200002120298000000060212029C0000000617
+:104D3000021202A000000306021202A400000013E7
+:104D4000021202A800000006021202B000001004C5
+:104D5000021202B400001004021203240010644086
+:104D60000212032800106440021205B40000000182
+:104D7000021205F800000040021205FC00000019B4
+:104D800002120600000000010212066C0000000181
+:104D9000021201B000000001021207D80000000357
+:104DA000021207D800000003021207D80000000317
+:104DB000021207D800000003021207D80000000307
+:104DC000021207D800000003021207D800000003F7
+:104DD000021207D8000000030600A0000000000C2B
+:104DE0000200A050000000000200A05400000000DB
+:104DF0000200A0EC555400000200A0F05555555596
+:104E00000200A0F4000055550200A0F8F0000000D8
+:104E10000200A0FC555400000200A1005555555554
+:104E20000200A104000055550200A108F000000096
+:104E30000200A19C000000000200A1A000010000EF
+:104E40000200A1A4000050140200A1A8000000006C
+:104E50000200A6A8000000000200A6AC00000000AE
+:104E60000200A6D0000000000200A45C00000C00BC
+:104E70000200A61C000000030200A070FFF55FFF07
+:104E80000200A0740000FFFF0200A078F00003E021
+:104E90000200A07C000000000200A0800000A00032
+:104EA0000600A084000000050200A0980FE00000AA
+:104EB0000600A09C000000070200A0B8000004004B
+:104EC0000600A0BC000000030200A0C80000100003
+:104ED0000600A0CC000000030200A0D800004000A3
+:104EE0000600A0DC000000030200A0E800010000B2
+:104EF0000600A22C000000040200A688000000FCAE
+:104F00000600A68C000000070200A6F400000000C6
+:104F10000200A10CFF5C00000200A110FFF55FFF82
+:104F20000200A1140000FFFF0200A118F00003E03E
+:104F30000200A11C000000000200A1200000A0004F
+:104F40000600A124000000050200A1380FE00000C7
+:104F50000600A13C000000070200A1580000080064
+:104F60000600A15C000000030200A1680000200010
+:104F70000600A16C000000030200A1780000800080
+:104F80000600A17C000000030200A18800020000CE
+:104F90000600A23C000000040200A6B0000000FCD5
+:104FA0000600A6B4000000070200A6F800000000FA
+:104FB0000200A030000000000200A0340000000049
+:104FC0000200A038000000000200A03C0000000029
+:104FD0000200A040000000000200A0440000000009
+:104FE0000200A048000000000200A04C00000000E9
+:104FF000020090C40000E000020090CC0000F3002A
+:10500000020090D400000003020091A00000000103
+:105010000600917000000003020090EC00006000A8
+:10502000020090F400007300020090FC00000003F6
+:10503000020091A800000001060091880000000312
+:10504000020091000000400002009108000053009F
+:105050000200911000000004020091AC0000000169
+:1050600006009194000000020200919C00000001E3
+:10507000020090D800006000020090E00000730081
+:10508000020090E800000003020091A4000000016B
+:105090000200917C000000010200918000000001EC
+:1050A000020091840000000002009128000003002B
+:1050B0000200916C0003F0080200912C0000030034
+:1050C0000200913000000300020091340000030050
+:1050D00002009138000003000200913C0000030030
+:1050E00002009140000003000200942C0000000127
+:1050F000020094300000000102009434000000011E
+:105100000200942C00000001020094300000000115
+:1051100002009434000000010200942C0000000101
+:1051200002009430000000010200943400000001ED
+:105130000200942C000000010200943000000001E5
+:1051400002009434000000010200942C00000001D1
+:1051500002009430000000010200943400000001BD
+:105160000200942C000000010200943000000001B5
+:1051700002009434000000010200942C00000001A1
+:10518000020094300000000102009434000000018D
+:105190000200942C00000001020094300000000185
+:1051A00002009434000000010213003C000061A8DA
+:1051B00006130108000000030213010400000000B0
+:1051C0000213013400000000061301080000000370
+:1051D000021301040000000002130134000000006B
+:1051E0000613010800000003021301040000000080
+:1051F0000213013400000000061301080000000340
+:10520000021301040000000002130134000000003A
+:10521000061301080000000302130104000000004F
+:10522000021301340000000006130108000000030F
+:10523000021301040000000002130134000000000A
+:10524000061301080000000302130104000000001F
+:1052500002130134000000000613010800000003DF
+:1052600002130104000000000213013400000000DA
+:10527000021100B8000000010216E6E8000020005C
+:105280000216E6EC000020000216E6F0000065556C
+:105290000216E6F400006555021681500000000079
+:1052A00002168174000000010216817800000001DE
+:1052B0000216817C000000010216818000000001BE
+:1052C000021681840000000102168188000000019E
+:1052D000021681B400000001021681B8000000012E
+:1052E000021681BC00000001021681C0000000010E
+:1052F000021681C400000001021681C800000001EE
+:1053000002168110000000000216824000BF00BF9C
+:1053100006168244000000020216824C00BF00BF45
+:105320000216E6C4000000010216E6C800000003F1
+:105330000216E79400000000042ACF40000A0C5631
+:105340000000000000000000000000340000000029
+:10535000000000000000000000000000000000004D
+:10536000000000000000000000000000000000003D
+:1053700000000000003400350000000000000000C4
+:10538000000000000000000000000000000000001D
+:10539000000000000000000000000000000000000D
+:1053A0000035006000000000000000000000000068
+:1053B00000000000000000000000000000000000ED
+:1053C00000000000000000000000000000600091EC
+:1053D0000000000000000000009100950095009979
+:1053E0000099009D009D00A100A100A500A500A9B5
+:1053F00000A900AD00AD00B100B100B50000000093
+:10540000000000000000000000000000000000009C
+:10541000000000000000000000000000000000008C
+:105420000000000000B503100310031A031A032440
+:105430000324032B032B03320332033903390340C4
+:10544000034003470347034E034E03550355035CD4
+:10545000000000000000000000000000000000004C
+:10546000000000000000000000000000000000003C
+:10547000000000000000000000000000000000002C
+:10548000000000000000000000000000000000001C
+:10549000000000000000000000000000000000000C
+:1054A00000000000000000000000000000000000FC
+:1054B00000000000000000000000000000000000EC
+:1054C00000000000000000000000000000000000DC
+:1054D00000000000000000000000000000000000CC
+:1054E00000000000000000000000000000000000BC
+:1054F00000000000000000000000000000000000AC
+:10550000035C035D0000000000000000035D035E1B
+:10551000035E035F035F0360036003610361036273
+:105520000362036303630364036403650000000014
+:10553000000000000000000000000000000000006B
+:10554000000000000000000000000000000000005B
+:1055500000000000000000000365036C036C03788A
+:105560000378038400000000000000000000000039
+:10557000000000000000000000000000000000002B
+:10558000000000000000000000000000000000001B
+:10559000000000000000000000000000000000000B
+:1055A00000000000000000000000000000000000FB
+:1055B00003840385000000000000000000000000DC
+:1055C00000000000000000000000000000000000DB
+:1055D000000000000000000000000000038503B090
+:1055E00000000000000000000000000000000000BB
+:1055F00000000000000000000000000000000000AB
+:10560000000000000000000003B003DF0000000005
+:10561000000000000000000000000000000000008A
+:10562000000000000000000000000000000000007A
+:105630000000000003DF040E000000000000000076
+:10564000040E04150415041C041C04230423042A5A
+:10565000042A0431043104380438043F043F04466A
+:105660000446047900000000000000000479047D75
+:10567000047D048104810485048504890489048DE2
+:10568000048D04910491049504950499049904E807
+:1056900004E804FE04FE0514051405160516051895
+:1056A0000518051A051A051C051C051E051E0520F2
+:1056B000052005220522052405240690000000008F
+:1056C00000000000069006950695069A069A069F29
+:1056D000069F06A406A406A906A906AE06AE06B352
+:1056E00006B306B806B806B90000000000000000C6
+:1056F00000000000000000000000000000000000AA
+:105700000000000000000000000000000000000099
+:1057100006B906DD000000000000000006DD06DF1F
+:1057200006DF06E106E106E306E306E506E506E731
+:1057300006E706E906E906EB06EB06ED06ED0702CD
+:105740000702070507050708000000000000000029
+:105750000000000000000000000000000000000049
+:1057600000000000000000000708074C00000000D7
+:105770000000000000000000000000000000000029
+:105780000000000000000000000000000000000019
+:1057900000000000074C07DE0000000000000000D1
+:1057A00000000000000000000000000000000000F9
+:1057B00000000000000000000000000000000000E9
+:1057C00007DE07EC00000000000000000000000001
+:1057D00000000000000000000000000000000000C9
+:1057E00000000000000000000000000007EC082995
+:1057F0000000000000000000082908320832083BC1
+:10580000083B08440844084D084D08560856085FF0
+:10581000085F086808680871087108D108D108E6AF
+:1058200008E608FB08FB08FE08FE09010901090457
+:10583000090409070907090A090A090D090D0910D0
+:10584000091009130913091C0000000000000000E2
+:105850000000000000000000000000000000000048
+:105860000000000000000000000000000000000038
+:10587000091C0922000000000000000000000000D8
+:105880000000000000000000000000000000000018
+:1058900000000000000000000000000009220927AD
+:1058A00000000000000000000000000000000000F8
+:1058B00000000000000000000000000000000000E8
+:1058C00000000000000000000927092D0000000072
+:1058D00000000000092D092E092E092F092F09307B
+:1058E00009300931093109320932093309330934E0
+:1058F000093409350000000000000000000000002D
+:105900000000000000000000000000000000000097
+:105910000000000000000000000000000000000087
+:10592000093509A6000000000000000009A609A72B
+:1059300009A709A809A809A909A909AA09AA09ABD7
+:1059400009AB09AC09AC09AD09AD09AE09AE09C294
+:1059500009C209D509D509E909E909EA09EA09EB02
+:1059600009EB09EC09EC09ED09ED09EE09EE09EF87
+:1059700009EF09F009F009F109F10A10000000002F
+:10598000000000000A100A130A130A160A160A1960
+:105990000A190A1C0A1C0A1F0A1F0A220A220A25BF
+:1059A0000A250A280A280A29000000000000000031
+:1059B0000A290A2C0A2C0A2F0A2F0A320A320A351F
+:1059C0000A350A380A380A3B0A3B0A3E0A3E0A41AF
+:1059D0000A410A4200000000000000000000000030
+:1059E00000000000000000000000000000000000B7
+:1059F0000000000000000000000000000A420A5AF7
+:105A00000000000000000000000000000000000096
+:105A10000000000000000000000000000000000086
+:105A200000000000000000000A5A0A5B00000000AD
+:105A30000000000000000000000000000000000066
+:105A40000000000000000000000000000000000056
+:105A5000000000000000000000010000000207003C
+:105A600000030E000004150000051C0000062300C2
+:105A700000072A000008310000093800000A3F0032
+:105A8000000B4600000C4D00000D5400000E5B00A2
+:105A9000000F620000106900001170000012770012
+:105AA00000137E000014850000158C000016930082
+:105AB00000179A000018A1000019A800001AAF00F2
+:105AC000001BB600001CBD00001DC400001ECB0062
+:105AD000001FD2000000D90000002000000040009C
+:105AE00000006000000080000000A0000000C00076
+:105AF0000000E00000010000000120000001400063
+:105B000000016000000180000001A0000001C00051
+:105B10000001E0000002000000022000000240003E
+:105B200000026000000280000002A0000002C0002D
+:105B30000002E0000003000000032000000340001A
+:105B400000036000000380000003A0000003C00009
+:105B50000003E000000400000004200000044000F6
+:105B600000046000000480000004A0000004C000E5
+:105B70000004E000000500000005200000054000D2
+:105B800000056000000580000005A0000005C000C1
+:105B90000005E000000600000006200000064000AE
+:105BA00000066000000680000006A0000006C0009D
+:105BB0000006E0000007000000072000000740008A
+:105BC00000076000000780000007A0000007C00079
+:105BD0000007E00000080000000820000008400066
+:105BE00000086000000880000008A0000008C00055
+:105BF0000008E00000090000000920000009400042
+:105C000000096000000980000009A0000009C00030
+:105C10000009E000000A0000000A2000000A40001D
+:105C2000000A6000000A8000000AA000000AC0000C
+:105C3000000AE000000B0000000B2000000B4000F9
+:105C4000000B6000000B8000000BA000000BC000E8
+:105C5000000BE000000C0000000C2000000C4000D5
+:105C6000000C6000000C8000000CA000000CC000C4
+:105C7000000CE000000D0000000D2000000D4000B1
+:105C8000000D6000000D8000000DA000000DC000A0
+:105C9000000DE000000E0000000E2000000E40008D
+:105CA000000E6000000E8000000EA000000EC0007C
+:105CB000000EE000000F0000000F2000000F400069
+:105CC000000F6000000F8000000FA000000FC00058
+:105CD000000FE00000100000001020000010400045
+:105CE00000106000001080000010A0000010C00034
+:105CF0000010E00000110000001120000011400021
+:105D000000116000001180000011A0000011C0000F
+:105D10000011E000001200000012200000124000FC
+:105D200000126000001280000012A0000012C000EB
+:105D30000012E000001300000013200000134000D8
+:105D400000136000001380000013A0000013C000C7
+:105D50000013E000001400000014200000144000B4
+:105D600000146000001480000014A0000014C000A3
+:105D70000014E00000150000001520000015400090
+:105D800000156000001580000015A0000015C0007F
+:105D90000015E0000016000000162000001640006C
+:105DA00000166000001680000016A0000016C0005B
+:105DB0000016E00000170000001720000017400048
+:105DC00000176000001780000017A0000017C00037
+:105DD0000017E00000180000001820000018400024
+:105DE00000186000001880000018A0000018C00013
+:105DF0000018E00000190000001920000019400000
+:105E000000196000001980000019A0000019C000EE
+:105E10000019E000001A0000001A2000001A4000DB
+:105E2000001A6000001A8000001AA000001AC000CA
+:105E3000001AE000001B0000001B2000001B4000B7
+:105E4000001B6000001B8000001BA000001BC000A6
+:105E5000001BE000001C0000001C2000001C400093
+:105E6000001C6000001C8000001CA000001CC00082
+:105E7000001CE000001D0000001D2000001D40006F
+:105E8000001D6000001D8000001DA000001DC0005E
+:105E9000001DE000001E0000001E2000001E40004B
+:105EA000001E6000001E8000001EA000001EC0003A
+:105EB000001EE000001F0000001F2000001F400027
+:105EC000001F6000001F8000001FA000001FC00016
+:105ED000001FE00000200000002020000020400003
+:105EE00000206000002080000020A0000020C000F2
+:105EF0000020E000002100000021200000214000DF
+:105F000000216000002180000021A0000021C000CD
+:105F10000021E000002200000022200000224000BA
+:105F200000226000002280000022A0000022C000A9
+:105F30000022E00000230000002320000023400096
+:105F400000236000002380000023A0000023C00085
+:105F50000023E00000240000002420000024400072
+:105F600000246000002480000024A0000024C00061
+:105F70000024E0000025000000252000002540004E
+:105F800000256000002580000025A0000025C0003D
+:105F90000025E0000026000000262000002640002A
+:105FA00000266000002680000026A0000026C00019
+:105FB0000026E00000270000002720000027400006
+:105FC00000276000002780000027A0000027C000F5
+:105FD0000027E000002800000028200000284000E2
+:105FE00000286000002880000028A0000028C000D1
+:105FF0000028E000002900000029200000294000BE
+:1060000000296000002980000029A0000029C000AC
+:106010000029E000002A0000002A2000002A400099
+:10602000002A6000002A8000002AA000002AC00088
+:10603000002AE000002B0000002B2000002B400075
+:10604000002B6000002B8000002BA000002BC00064
+:10605000002BE000002C0000002C2000002C400051
+:10606000002C6000002C8000002CA000002CC00040
+:10607000002CE000002D0000002D2000002D40002D
+:10608000002D6000002D8000002DA000002DC0001C
+:10609000002DE000002E0000002E2000002E400009
+:1060A000002E6000002E8000002EA000002EC000F8
+:1060B000002EE000002F0000002F2000002F4000E5
+:1060C000002F6000002F8000002FA000002FC000D4
+:1060D000002FE000003000000030200000304000C1
+:1060E00000306000003080000030A0000030C000B0
+:1060F0000030E0000031000000312000003140009D
+:1061000000316000003180000031A0000031C0008B
+:106110000031E00000320000003220000032400078
+:1061200000326000003280000032A0000032C00067
+:106130000032E00000330000003320000033400054
+:1061400000336000003380000033A0000033C00043
+:106150000033E00000340000003420000034400030
+:1061600000346000003480000034A0000034C0001F
+:106170000034E0000035000000352000003540000C
+:1061800000356000003580000035A0000035C000FB
+:106190000035E000003600000036200000364000E8
+:1061A00000366000003680000036A0000036C000D7
+:1061B0000036E000003700000037200000374000C4
+:1061C00000376000003780000037A0000037C000B3
+:1061D0000037E000003800000038200000384000A0
+:1061E00000386000003880000038A0000038C0008F
+:1061F0000038E0000039000000392000003940007C
+:1062000000396000003980000039A0000039C0006A
+:106210000039E000003A0000003A2000003A400057
+:10622000003A6000003A8000003AA000003AC00046
+:10623000003AE000003B0000003B2000003B400033
+:10624000003B6000003B8000003BA000003BC00022
+:10625000003BE000003C0000003C2000003C40000F
+:10626000003C6000003C8000003CA000003CC000FE
+:10627000003CE000003D0000003D2000003D4000EB
+:10628000003D6000003D8000003DA000003DC000DA
+:10629000003DE000003E0000003E2000003E4000C7
+:1062A000003E6000003E8000003EA000003EC000B6
+:1062B000003EE000003F0000003F2000003F4000A3
+:1062C000003F6000003F8000003FA000003FC00092
+:1062D000003FE000003FE00100000000000001FF7F
+:1062E0000000020000007FF800007FF800000A9420
+:1062F00000001500000000010000FF000000000089
+:106300000000FF00000000000000FF00000000008F
+:106310000000FF00000000000000FF00000000007F
+:106320000000FF00000000000000FF00000000006F
+: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
+:106530000000FF000000000000000000140AFF003F
+:106540000000000100000000002010010000000019
+:106550000100900000000100000090020000900483
+:1065600000009006000090080000900A0000900CC7
+:106570000000900E00009010000090120000901497
+:1065800000009016000090180000901A0000901C67
+:106590000000901E00009020000090220000902437
+:1065A00000009026000090280000902A0000902C07
+:1065B0000000902E000090300000903200009034D7
+:1065C00000009036000090380000903A0000903CA7
+:1065D0000000903E00009040000090420000904477
+:1065E00000009046000090480000904A0000904C47
+:1065F0000000904E00009050000090520000905417
+:1066000000009056000090580000905A0000905CE6
+:106610000000905E000090600000906200009064B6
+:1066200000009066000090680000906A0000906C86
+:106630000000906E00009070000090720000907456
+:1066400000009076000090780000907A0000907C26
+:106650000000907E000090800000908200009084F6
+:1066600000009086000090880000908A0000908CC6
+:106670000000908E00009090000090920000909496
+:1066800000009096000090980000909A0000909C66
+:106690000000909E000090A0000090A2000090A436
+:1066A000000090A6000090A8000090AA000090AC06
+:1066B000000090AE000090B0000090B2000090B4D6
+:1066C000000090B6000090B8000090BA000090BCA6
+:1066D000000090BE000090C0000090C2000090C476
+:1066E000000090C6000090C8000090CA000090CC46
+:1066F000000090CE000090D0000090D2000090D416
+:10670000000090D6000090D8000090DA000090DCE5
+:10671000000090DE000090E0000090E2000090E4B5
+:10672000000090E6000090E8000090EA000090EC85
+:10673000000090EE000090F0000090F2000090F455
+:10674000000090F6000090F8000090FA000090FC25
+:10675000000090FE000091000000910200009104F2
+:1067600000009106000091080000910A0000910CC1
+:106770000000910E00009110000091120000911491
+:1067800000009116000091180000911A0000911C61
+:106790000000911E00009120000091220000912431
+:1067A00000009126000091280000912A0000912C01
+:1067B0000000912E000091300000913200009134D1
+:1067C00000009136000091380000913A0000913CA1
+:1067D0000000913E00009140000091420000914471
+:1067E00000009146000091480000914A0000914C41
+:1067F0000000914E00009150000091520000915411
+:1068000000009156000091580000915A0000915CE0
+:106810000000915E000091600000916200009164B0
+:1068200000009166000091680000916A0000916C80
+:106830000000916E00009170000091720000917450
+:1068400000009176000091780000917A0000917C20
+:106850000000917E000091800000918200009184F0
+:1068600000009186000091880000918A0000918CC0
+:106870000000918E00009190000091920000919490
+:1068800000009196000091980000919A0000919C60
+:106890000000919E000091A0000091A2000091A430
+:1068A000000091A6000091A8000091AA000091AC00
+:1068B000000091AE000091B0000091B2000091B4D0
+:1068C000000091B6000091B8000091BA000091BCA0
+:1068D000000091BE000091C0000091C2000091C470
+:1068E000000091C6000091C8000091CA000091CC40
+:1068F000000091CE000091D0000091D2000091D410
+:10690000000091D6000091D8000091DA000091DCDF
+:10691000000091DE000091E0000091E2000091E4AF
+:10692000000091E6000091E8000091EA000091EC7F
+:10693000000091EE000091F0000091F2000091F44F
+:10694000000091F6000091F8000091FA000091FC1F
+:10695000000091FEFFFFFFFFFFFFFFFFFFFFFFFFB4
+:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:1069D000FFFFFFFF0000000300BEBC20000000001E
+:1069E000000000050000000300BEBC200000000005
+:1069F000000000050000000300BEBC2000000000F5
+:106A0000000000050000000300BEBC2000000000E4
+:106A1000000000050000000300BEBC2000000000D4
+:106A2000000000050000000300BEBC2000000000C4
+:106A3000000000050000000300BEBC2000000000B4
+:106A4000000000050000000300BEBC2000000000A4
+:106A50000000000500002000000040C00000618030
+:106A6000000082400000A3000000C3C00000E480DA
+:106A70000001054000012600000146C000016780BA
+:106A8000000188400001A9000001C9C00001EA809E
+:106A900000020B4000022C0000024CC000026D807E
+:106AA00000028E400002AF000002CFC00002F08062
+:106AB00000001140000080000001038000018700F9
+:106AC00000020A8000028E0000031180000395007E
+:106AD0000004188000049C0000051F800005A3002E
+:106AE000000626800006AA0000072D800007B100DE
+:106AF000000834800008B80000093B800009BF008E
+:106B0000000A4280000AC600000B4980000BCD003D
+:106B1000000C5080000CD400000D578000005B007A
+:106B200000007FF800007FF80000022A0000350016
+:106B30000000FF00000000000000FF000000000057
+:106B40000000FF00000000000000FF000000000047
+:106B50000000FF00000000000000FF000000000037
+:106B60000000FF00000000000000FF000000000027
+: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
+:106D60000000FF00000000000000FF00000019000C
+:106D70000000000000000000FFFFFFFF0000000017
+:106D800003938700000000000393870000007FF852
+:106D900000007FF800000BA700003500000000FF96
+:106DA000000000FF000000FF000000FF000000FFE7
+:106DB000000000FF000000FF000000FF0000FF00D7
+:106DC000000000000000FF00000000000000FF00C5
+:106DD000000000000000FF00000000000000FF00B5
+:106DE000000000000000FF00000000000000FF00A5
+:106DF000000000000000FF00000000000000FF0095
+: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
+:106FF000000000000000FF0000000000FFFFFFFF96
+:10700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:10701000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:10702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:10703000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:10707000FFFFFFFFFFFFFFFFFFFFFFFF000000001C
+:10708000000028AD000029180000291900000005A3
+:10709000000000070000FF000FFFFFFF0000FF00DF
+:1070A0000FFFFFFF000000FF0000FF000000FF00D7
+:1070B0000FFFFFFF0000FF000FFFFFFF000000FFBA
+:1070C0000000FF000000FF000FFFFFFF0000FF00B7
+:1070D0000FFFFFFF000000FF0000FF000000FF00A7
+:1070E0000FFFFFFF0000FF000FFFFFFF000000FF8A
+:1070F0000000FF000000FF000FFFFFFF0000FF0087
+:107100000FFFFFFF000000FF0000FF000000FF0076
+:107110000FFFFFFF0000FF000FFFFFFF000000FF59
+:107120000000FF000000FF000FFFFFFF0000FF0056
+:107130000FFFFFFF000000FF0000FF000000FF0046
+:107140000FFFFFFF0000FF000FFFFFFF000000FF29
+:107150000000FF000000FF000FFFFFFF0000FF0026
+:107160000FFFFFFF000000FF0000FF000000FF0016
+:107170000FFFFFFF0000FF000FFFFFFF000000FFF9
+:107180000000FF000000FF000FFFFFFF0000FF00F6
+:107190000FFFFFFF000000FF0000FF000000FF00E6
+:1071A0000FFFFFFF0000FF000FFFFFFF000000FFC9
+:1071B0000000FF000000FF000FFFFFFF0000FF00C6
+:1071C0000FFFFFFF000000FF0000FF000000FF00B6
+:1071D0000FFFFFFF0000FF000FFFFFFF000000FF99
+:1071E0000000FF000000FF000FFFFFFF0000FF0096
+:1071F0000FFFFFFF000000FF0000FF000000FF0086
+:107200000FFFFFFF0000FF000FFFFFFF000000FF68
+:107210000000FF000000FF000FFFFFFF0000FF0065
+:107220000FFFFFFF000000FF0000FF000000FF0055
+:107230000FFFFFFF0000FF000FFFFFFF000000FF38
+:107240000000FF000000FF000FFFFFFF0000FF0035
+:107250000FFFFFFF000000FF0000FF000000FF0025
+:107260000FFFFFFF0000FF000FFFFFFF000000FF08
+:107270000000FF000000FF000FFFFFFF0000FF0005
+:107280000FFFFFFF000000FF0000FF000000FF00F5
+:107290000FFFFFFF0000FF000FFFFFFF000000FFD8
+:1072A0000000FF000000FF000FFFFFFF0000FF00D5
+:1072B0000FFFFFFF000000FF0000FF000000FF00C5
+:1072C0000FFFFFFF0000FF000FFFFFFF000000FFA8
+:1072D0000000FF000000FF000FFFFFFF0000FF00A5
+:1072E0000FFFFFFF000000FF0000FF000000FF0095
+:1072F0000FFFFFFF0000FF000FFFFFFF000000FF78
+:107300000000FF000000FF000FFFFFFF0000FF0074
+:107310000FFFFFFF000000FF0000FF000000FF0064
+:107320000FFFFFFF0000FF000FFFFFFF000000FF47
+:107330000000FF000000FF000FFFFFFF0000FF0044
+:107340000FFFFFFF000000FF0000FF000000FF0034
+:107350000FFFFFFF0000FF000FFFFFFF000000FF17
+:107360000000FF000000FF000FFFFFFF0000FF0014
+:107370000FFFFFFF000000FF0000FF000000FF0004
+:107380000FFFFFFF0000FF000FFFFFFF000000FFE7
+:107390000000FF000000FF000FFFFFFF0000FF00E4
+:1073A0000FFFFFFF000000FF0000FF000000FF00D4
+:1073B0000FFFFFFF0000FF000FFFFFFF000000FFB7
+:1073C0000000FF000000FF000FFFFFFF0000FF00B4
+:1073D0000FFFFFFF000000FF0000FF000000FF00A4
+:1073E0000FFFFFFF0000FF000FFFFFFF000000FF87
+:1073F0000000FF000000FF000FFFFFFF0000FF0084
+:107400000FFFFFFF000000FF0000FF000000FF0073
+:107410000FFFFFFF0000FF000FFFFFFF000000FF56
+:107420000000FF000000FF000FFFFFFF0000FF0053
+:107430000FFFFFFF000000FF0000FF000000FF0043
+:107440000FFFFFFF0000FF000FFFFFFF000000FF26
+:107450000000FF000000FF000FFFFFFF0000FF0023
+:107460000FFFFFFF000000FF0000FF000000FF0013
+:107470000FFFFFFF0000FF000FFFFFFF000000FFF6
+:107480000000FF000000FF000FFFFFFF0000FF00F3
+:107490000FFFFFFF000000FF0000FF000000FF00E3
+:1074A0000FFFFFFF0000FF000FFFFFFF000000FFC6
+:1074B0000000FF000000FF000FFFFFFF0000FF00C3
+:1074C0000FFFFFFF000000FF0000FF000000FF00B3
+:1074D0000FFFFFFF0000FF000FFFFFFF000000FF96
+:1074E0000000FF000000FF000FFFFFFF0000FF0093
+:1074F0000FFFFFFF000000FF0000FF000000FF0083
+:107500000FFFFFFF0000FF000FFFFFFF000000FF65
+:107510000000FF000000FF000FFFFFFF0000FF0062
+:107520000FFFFFFF000000FF0000FF000000FF0052
+:107530000FFFFFFF0000FF000FFFFFFF000000FF35
+:107540000000FF000000FF000FFFFFFF0000FF0032
+:107550000FFFFFFF000000FF0000FF000000FF0022
+:107560000FFFFFFF0000FF000FFFFFFF000000FF05
+:107570000000FF000000FF000FFFFFFF0000FF0002
+:107580000FFFFFFF000000FF0000FF000000FF00F2
+:107590000FFFFFFF0000FF000FFFFFFF000000FFD5
+:1075A0000000FF000000FF000FFFFFFF0000FF00D2
+:1075B0000FFFFFFF000000FF0000FF000000FF00C2
+:1075C0000FFFFFFF0000FF000FFFFFFF000000FFA5
+:1075D0000000FF000000FF000FFFFFFF0000FF00A2
+:1075E0000FFFFFFF000000FF0000FF000000FF0092
+:1075F0000FFFFFFF0000FF000FFFFFFF000000FF75
+:107600000000FF000000FF000FFFFFFF0000FF0071
+:107610000FFFFFFF000000FF0000FF000000FF0061
+:107620000FFFFFFF0000FF000FFFFFFF000000FF44
+:107630000000FF000000FF000FFFFFFF0000FF0041
+:107640000FFFFFFF000000FF0000FF000000FF0031
+:107650000FFFFFFF0000FF000FFFFFFF000000FF14
+:107660000000FF000000FF000FFFFFFF0000FF0011
+:107670000FFFFFFF000000FF0000FF000000FF0001
+:107680000FFFFFFF0000FF000FFFFFFF000000FFE4
+:107690000000FF000000FF000FFFFFFF0000FF00E1
+:1076A0000FFFFFFF000000FF0000FF000000FF00D1
+:1076B0000FFFFFFF0000FF000FFFFFFF000000FFB4
+:1076C0000000FF000000FF000FFFFFFF0000FF00B1
+:1076D0000FFFFFFF000000FF0000FF000000FF00A1
+:1076E0000FFFFFFF0000FF000FFFFFFF000000FF84
+:1076F0000000FF000000FF000FFFFFFF0000FF0081
+:107700000FFFFFFF000000FF0000FF000000FF0070
+:107710000FFFFFFF0000FF000FFFFFFF000000FF53
+:107720000000FF000000FF000FFFFFFF0000FF0050
+:107730000FFFFFFF000000FF0000FF000000FF0040
+:107740000FFFFFFF0000FF000FFFFFFF000000FF23
+:107750000000FF000000FF000FFFFFFF0000FF0020
+:107760000FFFFFFF000000FF0000FF000000FF0010
+:107770000FFFFFFF0000FF000FFFFFFF000000FFF3
+:107780000000FF000000FF000FFFFFFF0000FF00F0
+:107790000FFFFFFF000000FF0000FF000000FF00E0
+:1077A0000FFFFFFF0000FF000FFFFFFF000000FFC3
+:1077B0000000FF000000FF000FFFFFFF0000FF00C0
+:1077C0000FFFFFFF000000FF0000FF000000FF00B0
+:1077D0000FFFFFFF0000FF000FFFFFFF000000FF93
+:1077E0000000FF000000FF000FFFFFFF0000FF0090
+:1077F0000FFFFFFF000000FF0000FF000000FF0080
+:107800000FFFFFFF0000FF000FFFFFFF000000FF62
+:107810000000FF000000FF000FFFFFFF0000FF005F
+:107820000FFFFFFF000000FF0000FF000000FF004F
+:107830000FFFFFFF0000FF000FFFFFFF000000FF32
+:107840000000FF000000FF000FFFFFFF0000FF002F
+:107850000FFFFFFF000000FF0000FF000000FF001F
+:107860000FFFFFFF0000FF000FFFFFFF000000FF02
+:107870000000FF000000FF000FFFFFFF0000FF00FF
+:107880000FFFFFFF000000FF0000FF000000FF00EF
+:107890000FFFFFFF0000FF000FFFFFFF000000FFD2
+:1078A0000000FF000000FF000FFFFFFF0000FF00CF
+:1078B0000FFFFFFF000000FF0000FF000000FF00BF
+:1078C0000FFFFFFF0000FF000FFFFFFF000000FFA2
+:1078D0000000FF000000FF000FFFFFFF0000FF009F
+:1078E0000FFFFFFF000000FF0000FF000000FF008F
+:1078F0000FFFFFFF0000FF000FFFFFFF000000FF72
+:107900000000FF000000FF000FFFFFFF0000FF006E
+:107910000FFFFFFF000000FF0000FF000000FF005E
+:107920000FFFFFFF0000FF000FFFFFFF000000FF41
+:107930000000FF000000FF000FFFFFFF0000FF003E
+:107940000FFFFFFF000000FF0000FF000000FF002E
+:107950000FFFFFFF0000FF000FFFFFFF000000FF11
+:107960000000FF000000FF000FFFFFFF0000FF000E
+:107970000FFFFFFF000000FF0000FF000000FF00FE
+:107980000FFFFFFF0000FF000FFFFFFF000000FFE1
+:107990000000FF000000FF000FFFFFFF0000FF00DE
+:1079A0000FFFFFFF000000FF0000FF000000FF00CE
+:1079B0000FFFFFFF0000FF000FFFFFFF000000FFB1
+:1079C0000000FF000000FF000FFFFFFF0000FF00AE
+:1079D0000FFFFFFF000000FF0000FF000000FF009E
+:1079E0000FFFFFFF0000FF000FFFFFFF000000FF81
+:1079F0000000FF000000FF000FFFFFFF0000FF007E
+:107A00000FFFFFFF000000FF0000FF000000FF006D
+:107A10000FFFFFFF0000FF000FFFFFFF000000FF50
+:107A20000000FF000000FF000FFFFFFF0000FF004D
+:107A30000FFFFFFF000000FF0000FF000000FF003D
+:107A40000FFFFFFF0000FF000FFFFFFF000000FF20
+:107A50000000FF000000FF000FFFFFFF0000FF001D
+:107A60000FFFFFFF000000FF0000FF000000FF000D
+:107A70000FFFFFFF0000FF000FFFFFFF000000FFF0
+:107A80000000FF000000FF000FFFFFFF0000FF00ED
+:107A90000FFFFFFF000000FF0000FF000000FF00DD
+:107AA0000FFFFFFF0000FF000FFFFFFF000000FFC0
+:107AB0000000FF000000FF000FFFFFFF0000FF00BD
+:107AC0000FFFFFFF000000FF0000FF000000FF00AD
+:107AD0000FFFFFFF0000FF000FFFFFFF000000FF90
+:107AE0000000FF000000FF000FFFFFFF0000FF008D
+:107AF0000FFFFFFF000000FF0000FF000000FF007D
+:107B00000FFFFFFF0000FF000FFFFFFF000000FF5F
+:107B10000000FF000000FF000FFFFFFF0000FF005C
+:107B20000FFFFFFF000000FF0000FF000000FF004C
+:107B30000FFFFFFF0000FF000FFFFFFF000000FF2F
+:107B40000000FF000000FF000FFFFFFF0000FF002C
+:107B50000FFFFFFF000000FF0000FF000000FF001C
+:107B60000FFFFFFF0000FF000FFFFFFF000000FFFF
+:107B70000000FF000000FF000FFFFFFF0000FF00FC
+:107B80000FFFFFFF000000FF0000FF000000FF00EC
+:107B90000FFFFFFF0000FF000FFFFFFF000000FFCF
+:107BA0000000FF000000FF000FFFFFFF0000FF00CC
+:107BB0000FFFFFFF000000FF0000FF000000FF00BC
+:107BC0000FFFFFFF0000FF000FFFFFFF000000FF9F
+:107BD0000000FF000000FF000FFFFFFF0000FF009C
+:107BE0000FFFFFFF000000FF0000FF000000FF008C
+:107BF0000FFFFFFF0000FF000FFFFFFF000000FF6F
+:107C00000000FF000000FF000FFFFFFF0000FF006B
+:107C10000FFFFFFF000000FF0000FF000000FF005B
+:107C20000FFFFFFF0000FF000FFFFFFF000000FF3E
+:107C30000000FF000000FF000FFFFFFF0000FF003B
+:107C40000FFFFFFF000000FF0000FF000000FF002B
+:107C50000FFFFFFF0000FF000FFFFFFF000000FF0E
+:107C60000000FF000000FF000FFFFFFF0000FF000B
+:107C70000FFFFFFF000000FF0000FF000000FF00FB
+:107C80000FFFFFFF0000FF000FFFFFFF000000FFDE
+:107C90000000FF000000FF000FFFFFFF0000FF00DB
+:107CA0000FFFFFFF000000FF0000FF000000FF00CB
+:107CB0000FFFFFFF0000FF000FFFFFFF000000FFAE
+:107CC0000000FF000000FF000FFFFFFF0000FF00AB
+:107CD0000FFFFFFF000000FF0000FF000000FF009B
+:107CE0000FFFFFFF0000FF000FFFFFFF000000FF7E
+:107CF0000000FF000000FF000FFFFFFF0000FF007B
+:107D00000FFFFFFF000000FF0000FF000000FF006A
+:107D10000FFFFFFF0000FF000FFFFFFF000000FF4D
+:107D20000000FF000000FF000FFFFFFF0000FF004A
+:107D30000FFFFFFF000000FF0000FF000000FF003A
+:107D40000FFFFFFF0000FF000FFFFFFF000000FF1D
+:107D50000000FF0000001000000020800000310043
+:107D600000004180000052000000628000007300AB
+:107D700000008380000094000000A4800000B50093
+:107D80000000C5800000D6000000E6800000F7007B
+:107D9000000107800001180000012880000139005F
+:107DA0000001498000015A0000016A8000017B0047
+:107DB00000018B8000019C000001AC800001BD002F
+:107DC0000001CD800001DE000001EE800001FF0017
+:107DD00000000F8000007FF800007FF8000005F928
+:107DE0000000350010000000000028AD0000291838
+:107DF0000000291900000005000000060001000134
+:107E000000220006CCCCCCC97058103C0000FF000A
+:107E1000000000000000FF00000000000000FF0064
+:107E2000000000000000FF00000000000000FF0054
+:107E3000000000000000FF00000000000000FF0044
+:107E4000000000000000FF00000000000000FF0034
+: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
+:10804000000000000000FF00000000000000000130
+:10805000CCCC0201CCCCCCCCCCCC0201CCCCCCCC8A
+:10806000CCCC0201CCCCCCCCCCCC0201CCCCCCCC7A
+:10807000CCCC0201CCCCCCCCCCCC0201CCCCCCCC6A
+:10808000CCCC0201CCCCCCCCCCCC0201CCCCCCCC5A
+:1080900000000000FFFFFFFF03030303134202027F
+:1080A0005050502070608050020002000604060408
+:1080B000000E0000011600D6002625A0002625A0EF
+:1080C000002625A0002625A000720000012300F351
+:1080D000002625A0002625A0002625A0002625A0F4
+:1080E0000000FFFF000000000000FFFF0000000094
+:1080F0000000FFFF000000000000FFFF0000000084
+:108100000000FFFF000000000000FFFF0000000073
+:108110000000FFFF000000000000FFFF0000000063
+: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
+:1082E000FFFFFFF3318FFFFF0C30C30CC30C30C313
+:1082F000CF3CF300F3CF3CF30000CF3CCDCDCDCD50
+:10830000FFFFFFF130EFFFFF0C30C30CC30C30C395
+:10831000CF3CF300F3CF3CF30001CF3CCDCDCDCD2E
+:10832000FFFFFFF6305FFFFF0C30C30CC30C30C300
+:10833000CF3CF300F3CF3CF30002CF3CCDCDCDCD0D
+:10834000FFFFF4061CBFFFFF0C30C305C30C30C396
+:10835000CF300014F3CF3CF30004CF3CCDCDCDCDD6
+:10836000FFFFFFF2304FFFFF0C30C30CC30C30C3D4
+:10837000CF3CF300F3CF3CF30008CF3CCDCDCDCDC7
+:10838000FFFFFFFA302FFFFF0C30C30CC30C30C3CC
+:10839000CF3CF300F3CF3CF30010CF3CCDCDCDCD9F
+:1083A000FFFFFFF731EFFFFF0C30C30CC30C30C3EE
+:1083B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6F
+:1083C000FFFFFFF5302FFFFF0C30C30CC30C30C391
+:1083D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2F
+:1083E000FFFFFFF3318FFFFF0C30C30CC30C30C312
+:1083F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4F
+:10840000FFFFFFF1310FFFFF0C30C30CC30C30C373
+:10841000CF3CF300F3CF3CF30001CF3CCDCDCDCD2D
+:10842000FFFFFFF6305FFFFF0C30C30CC30C30C3FF
+:10843000CF3CF300F3CF3CF30002CF3CCDCDCDCD0C
+:10844000FFFFF4061CBFFFFF0C30C305C30C30C395
+:10845000CF300014F3CF3CF30004CF3CCDCDCDCDD5
+:10846000FFFFFFF2304FFFFF0C30C30CC30C30C3D3
+:10847000CF3CF300F3CF3CF30008CF3CCDCDCDCDC6
+:10848000FFFFFFFA302FFFFF0C30C30CC30C30C3CB
+:10849000CF3CF300F3CF3CF30010CF3CCDCDCDCD9E
+:1084A000FFFFFFF730EFFFFF0C30C30CC30C30C3EE
+:1084B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6E
+:1084C000FFFFFFF5304FFFFF0C30C30CC30C30C370
+:1084D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2E
+:1084E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C6
+:1084F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD82
+:10850000FFFFFFFF30CFFFFF0C30C30CC30C30C3A5
+:10851000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD60
+:10852000FFFFFFFF30CFFFFF0C30C30CC30C30C385
+:10853000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3F
+:10854000FFFFFFFF30CFFFFF0C30C30CC30C30C365
+:10855000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD1D
+:10856000FFFFFFFF30CFFFFF0C30C30CC30C30C345
+:10857000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF9
+:10858000FFFFFFFF30CFFFFF0C30C30CC30C30C325
+:10859000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDD1
+:1085A000FFFFFFFF30CFFFFF0C30C30CC30C30C305
+:1085B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDA1
+:1085C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E5
+:1085D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD61
+:1085E000FFFFFFF3320FFFFF0C30C30CC30C30C38F
+:1085F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4D
+:10860000FFFFFFF1310FFFFF0C30C30CC30C30C371
+:10861000CF3CF300F3CF3CF30001CF3CCDCDCDCD2B
+:10862000FFFFFFF6305FFFFF0C30C30CC30C30C3FD
+:10863000CF3CF300F3CF3CF30002CF3CCDCDCDCD0A
+:10864000FFFFF4061CBFFFFF0C30C305C30C30C393
+:10865000CF300014F3CF3CF30004CF3CCDCDCDCDD3
+:10866000FFFFFFF2304FFFFF0C30C30CC30C30C3D1
+:10867000CF3CF300F3CF3CF30008CF3CCDCDCDCDC4
+:10868000FFFFFF8A042FFFFF0C30C30CC30C30C365
+:10869000CF3CC000F3CF3CF30010CF3CCDCDCDCDCF
+:1086A000FFFFFF9705CFFFFF0C30C30CC30C30C397
+:1086B000CF3CC000F3CF3CF30020CF3CCDCDCDCD9F
+:1086C000FFFFFFF5310FFFFF0C30C30CC30C30C3AD
+:1086D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2C
+:1086E000FFFFFFF3320FFFFF0C30C30CC30C30C38E
+:1086F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4C
+:10870000FFFFFFF1302FFFFF0C30C30CC30C30C351
+:10871000CF3CF300F3CF3CF30001CF3CCDCDCDCD2A
+:10872000FFFFFFF6305FFFFF0C30C30CC30C30C3FC
+:10873000CF3CF300F3CF3CF30002CF3CCDCDCDCD09
+:10874000FFFFFF061CBFFFFF0C30C30CC30C30C380
+:10875000CF3CC014F3CF3CF30004CF3CCDCDCDCD06
+:10876000FFFFFFF2304FFFFF0C30C30CC30C30C3D0
+:10877000CF3CF300F3CF3CF30008CF3CCDCDCDCDC3
+:10878000FFFFFFFA302FFFFF0C30C30CC30C30C3C8
+:10879000CF3CF300F3CF3CF30010CF3CCDCDCDCD9B
+:1087A000FFFFFFF731CFFFFF0C30C30CC30C30C30A
+:1087B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6B
+:1087C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E3
+:1087D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5F
+:1087E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C3
+:1087F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7F
+:10880000FFFFFFFF30CFFFFF0C30C30CC30C30C3A2
+:10881000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5D
+:10882000FFFFFFFF30CFFFFF0C30C30CC30C30C382
+:10883000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3C
+:10884000FFFFFFFF30CFFFFF0C30C30CC30C30C362
+:10885000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD1A
+:10886000FFFFFFFF30CFFFFF0C30C30CC30C30C342
+:10887000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF6
+:10888000FFFFFFFF30CFFFFF0C30C30CC30C30C322
+:10889000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCE
+:1088A000FFFFFFFF30CFFFFF0C30C30CC30C30C302
+:1088B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9E
+:1088C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E2
+:1088D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5E
+:1088E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C2
+:1088F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7E
+:10890000FFFFFFFF30CFFFFF0C30C30CC30C30C3A1
+:10891000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5C
+:10892000FFFFFFFF30CFFFFF0C30C30CC30C30C381
+:10893000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3B
+:10894000FFFFFFFF30CFFFFF0C30C30CC30C30C361
+:10895000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD19
+:10896000FFFFFFFF30CFFFFF0C30C30CC30C30C341
+:10897000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF5
+:10898000FFFFFFFF30CFFFFF0C30C30CC30C30C321
+:10899000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCD
+:1089A000FFFFFFFF30CFFFFF0C30C30CC30C30C301
+:1089B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9D
+:1089C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E1
+:1089D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5D
+:1089E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C1
+:1089F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7D
+:108A0000FFFFFFFF30CFFFFF0C30C30CC30C30C3A0
+:108A1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5B
+:108A2000FFFFFFFF30CFFFFF0C30C30CC30C30C380
+:108A3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3A
+:108A4000FFFFFFFF30CFFFFF0C30C30CC30C30C360
+:108A5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD18
+:108A6000FFFFFFFF30CFFFFF0C30C30CC30C30C340
+:108A7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF4
+:108A8000FFFFFFFF30CFFFFF0C30C30CC30C30C320
+:108A9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCC
+:108AA000FFFFFFFF30CFFFFF0C30C30CC30C30C300
+:108AB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9C
+:108AC000FFFFFFFF30CFFFFF0C30C30CC30C30C3E0
+:108AD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5C
+:108AE000000C0000000700C000028130000B81581C
+:108AF0000002021000010230000F024000010330AA
+:108B0000000C0000000800C000028140000B8168DA
+:108B1000000202200001024000070250000202C0D1
+:108B2000001000000008010000028180000B81A8F5
+:108B30000002026000018280000E8298000803801B
+:108B4000001000000001010000028110000901383E
+:108B5000000201C8000101E8000E01F8000002D87F
+:108B6000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC45
+:108B700000002000CCCCCCCCCCCCCCCCCCCCCCCC45
+:108B8000CCCCCCCC00002000CCCCCCCCCCCCCCCC35
+:108B9000CCCCCCCCCCCCCCCC04002000CCCCCCCC21
+:108BA000CCCCCCCCCCCCCCCCCCCCCCCC41002000D4
+:108BB00003030303034202025050502070608050B0
+:108BC0001313131313421212505050207060805030
+:108BD000030102000000000000000000000000008F
+:108BE0001F8B080000000000000BFB51CFC0F003FA
+:108BF0008AF7093230288920F8C4E0427606864D8B
+:108C00001C0C0C5BB849D307C32C0C0C0CDA4CE4DD
+:108C1000E905E1DBBC0C0CCF8098810F555C80131B
+:108C200042FF075A20C80AB4830DBBFEE56A08B6A6
+:108C3000A70A0343011033283130E8AB22C445D4DE
+:108C400019182602F99150B1AB403A4C8D7C378F00
+:108C5000E2C1834F1AA3F2971A426807A8F8293491
+:108C6000F96550F9621D087DDA18BBB9253AC4D9F7
+:108C7000BFCB1A953FCD1ABFFA93F6A8FC7568EAE8
+:108C80001741F900B9FAD21DD80300000000000016
+:108C900000000000000000001F8B08000000000022
+:108CA000000BED7D7F7C14D5B5F8999DD9D9D9CD30
+:108CB000EE6608096C20E024861AFAA25D20609016
+:108CC000A843401ABF8FDA15A9A62DED77B5D4E2D7
+:108CD0000F60EBF3097DCF36931092101017B1D5CA
+:108CE00056AB2B0F2DF56B25B5D4D2FAA38B581E9E
+:108CF000B6EFF3BE4869EBD7621B7FE18F228D5A36
+:108D000084B658BFF79C7B273B33D94D36407FFC58
+:108D1000F1C207863B73EEBDE79E73EEB9E79C7B1D
+:108D2000EE8D0A35F0A133003EC09F0B016E0F019E
+:108D30004045EE695C7F7E4F7F03C05188A47BCBAA
+:108D400001D62860022B5B072399FB25C09F3A853B
+:108D50009557C91F8EF75603DC51F2957B117EB5EE
+:108D6000A540803D7BDB00B267B1EFA1E816280586
+:108D70002881D476FCCE7E12F7B3F68E05276720C5
+:108D80009AEBBF027C0033F173957EA884E0E00388
+:108D900099FD73303917C601C860FFAC863ED68E88
+:108DA0007240CE60BFB2BC50FF554DAE1DEF53D6E2
+:108DB00055C86AA23DFC475E529A0C17865F7DB08B
+:108DC0007AFBD37539F8B320527EE89FD87F1450D0
+:108DD000081F7903201D8E86212357176EE7589BA5
+:108DE000B1FD693FD2F133A589B30BC3D974EA69E8
+:108DF000D3E8D9D5A6433600C05036FBEAD9330CA8
+:108E0000E696FAA1F5E68144F4D20C8BF0E90CFB6E
+:108E10003225D588751280D1D78FF491F0FD22CDFF
+:108E2000CC53DF7E4239A38F3D5E46C720F0F680EB
+:108E30008DEF7ED65E10FBCF43AFCBB07F2627C130
+:108E4000DAA1FD5B0D27DF7F682AC0BE30D2DB448C
+:108E50001CC0A7A7202EF8FD51699876049F1583A2
+:108E6000B73312DD4BEA7CB97ED9DFA01172C94954
+:108E70002056E6961BAF5C229D2A905F86F4F29402
+:108E80005CBB2AF22D0FBDAE11F41A989B684D30D1
+:108E90007AAC6D03EB25473D390666260F9D568952
+:108EA0007A767F4A3983CBD33E40BB983F960BBE40
+:108EB00058FCBE7C92F8ADFF1BE1B749C83B409A15
+:108EC0009E03739384A7B7BD7CF38B4DE2C17248B8
+:108ED000C9583E94EF7288DFCF1E7E8DCF33FBFBE7
+:108EE000C3E0A77676A2C661FDAC11F80DCCE5FA19
+:108EF0006FED3435B345227DE4C2F321D45FAC9EDF
+:108F000024097A687D80F257725C01188BF8999079
+:108F10008800ACAB6DD686D33FA02B7FEAB7E5AE19
+:108F200066A8DC7D9875837885C2F9E9F4F0A01E07
+:108F30005D62BDC4DAD182ECFD99D86E79AC6A1657
+:108F4000E0E8E8C72FBE83E4933FC0797B82C1CDC0
+:108F5000127A56A6F6498F401590BE97053CF5C388
+:108F6000E0036C58E674F6C4F775A21F6968BBDEAF
+:108F70007AC7A08CD347E063EB75191EA77606F17C
+:108F80005112442FEF7B3F7BAF874FFDFDA996FD2C
+:108F90004681FED212C9D348F57F23E465887C164A
+:108FA000E0EB7E31CF14E833E1CC9C1CD9F275B2F2
+:108FB0007274CA72C2BAA7F5A2809C5890A279C3F3
+:108FC000C0ACDE69A397973C729275C22F94C6F02D
+:108FD0007128719217868F4272AB737C2AA69753C1
+:108FE0007B12CEF1B3B00551463AB0F15E65D7873A
+:108FF00038CDD710DA398EFA6C7084AF244B42EF3B
+:1090000073B89BC43C3FBFB98AE30FA27D0FBEACCF
+:109010003DCDD99E0C551E39E7786F94B87E63F02C
+:1090200059A2A7B77F45227C6548583E566F8BE80A
+:10903000DFABBFECE70ED1DE06095AFBC27C3E2D4A
+:1090400072AC87CD92D0131A9F675EFDE447B99A40
+:1090500071F27255AC5E5F28E55F77985514BB34AA
+:109060005278DD29F5D9EB413626F8362ABE9F29FC
+:1090700095B9F85E2CBE579D24BE1387E25B949C85
+:109080004D957CA35A276F3A49FC821EFC4E975C93
+:10909000CF1072562CFEF63C182DFEF250FA163503
+:1090A0008F668F12BF2D2749DF0A9F6D2709FC0AA3
+:1090B000CCDBF305BF2DE0F2A1303B1CFD9C62F13F
+:1090C0007B7464FC00CE637FAD172D53217B0D6054
+:1090D00002C0D3ED2F5A9692C3CF04AED747DBFF21
+:1090E0009E91F927FA7FC3326B73FD1F687FC3D54A
+:1090F000BFC2E40785ADD87E7F51ECB8E16DD7B82B
+:109100005F96DE76F57BB2747FB5E8FEFFE81AF76E
+:10911000BBD21FDDE30EB3719F597CBF7F38497905
+:10912000AC16F3A559D25DEB4021FB7D86E0EBDD6B
+:1091300036BC8D6F01F8A902AFCE22E1278AF63F37
+:1091400055247C9F68BF0FE12B46863F53C0A78AFA
+:1091500084977C7C1E165A3FE74A36FDC0E57FACFB
+:10916000D1781CC45CA340F082A17113AB39F5AD7A
+:109170007EC67BAB23A0AF29A7B809C545560324FB
+:10918000306E7217241B7D187FD9F9E57B11EE1D17
+:1091900045D37B75E013927D0F1E8C6CE9ADCEF547
+:1091A000B74A4EB64A284B6BA2FAFD145F49B54A3E
+:1091B000EC596185758CDB1CAB49B45F598EE3308B
+:1091C000748BB5F3FCB2CB7661F9364DD265266A65
+:1091D0005FBD60EAA6CB0D06F7FEAEE7CE40B869EC
+:1091E000E36A3A485FC6259487B171D594CF61CFC1
+:1091F000C58BB97E07E10FB738CACC0EF864EB27F0
+:109200005CDF3F9D74973FD1F289DC7AC2FE5E91AC
+:10921000707FCF8D07B8DF3187EBED6335A9DF7243
+:10922000BC3E546DF1F8028DB7D48AD2F836BCFF3B
+:10923000452A6F68AFD73BD8B83F75CD510BC717DC
+:109240009680C6178DBF97C532B0F1AA8D00B75E64
+:10925000F04CCF2C28EC7F459B16BBF084B87B9C50
+:10926000ADD7E7C75BD5DF9DF00AB3978EED0A9ABD
+:10927000884F74AF9C0956235F07B293B07FAB341D
+:10928000C9F93300B5C8575307E463B399CCC8ECA8
+:109290007D3AA6C5032866D0AF21DD372168257B3E
+:1092A000DFF88E96ACC7F6DFA3F675F1FDD6C69A49
+:1092B000F1181F79BC6DF54485CDF71FB55913150D
+:1092C00066B4EF6CEBA1E7A36D697ABFA3ED4E7AAC
+:1092D000DAE3434D62D8E393B11FB303E5ED989F02
+:1092E00099460CAF8DE7FBC8BFDD20F44897782A7C
+:1092F0004A562EC5EF7198D60B88D7FE79584E374F
+:10930000C0346459BAE929B9948DE3864A988E6DC0
+:10931000EF7AE157FC7B154C0F30F97ACA6CA679CD
+:10932000706BA32F13A8A6E7C5D8DFADA60F98C909
+:10933000039138C3CB41D740CC5DD621B926D2406A
+:10934000FDC77B0DAC7FC36E2CDF3093194A40ED17
+:10935000CB11A223C4B1BF99074CD2E381261FC50C
+:10936000E9D24DBE20D271A47ED248D761E25573B6
+:109370005E77C3CFEE779799C6FBCDA07C70FA3E9F
+:10938000EC637A62F70BE37D5639E141E3674F1EE8
+:10939000478CF9326894DE26E86CD3FD5884EB9D47
+:1093A0008DCC3FC47860217C369E776D6CB8788216
+:1093B000DAD8958073F0994E60BC556DCC88671FE4
+:1093C000BDF7C23F8F46D1CC5CB92B367DCC95F52D
+:1093D000397CBCF0136495E4FF5805FFDE157B4A29
+:1093E000BF32EC6C4FF27ED73E5FEFFCEEA7FE8EF5
+:1093F00055DADFF76B57D6E7A93F897DCFC397A52D
+:1094000032D7C34FBF1068FE1ACAA7A0EFEE175E8F
+:10941000DB7B26D2FB800C280FE97DCD240F287F33
+:10942000A8479E62F2D0CFDA1BDBB2E137CEF91C3F
+:1094300089BBCBE946864003E71B76F55F821F3F79
+:1094400015F1DABD225EBBA72D46CFA7DB0C7A3E15
+:10945000D55647DFB36D712A3FD9D648E5C7DB4CF7
+:109460002AFFA8AD85CA3BDB12547EB4AD959E3B66
+:10947000DA92F4BCAD6D193DD34D7C9E6F684B51B3
+:10948000B9AB6D35D5B3C7FF31A6359CF2F7CF75B3
+:10949000EEF2C5C659B9F9CEFE7E34E62E5FA47F42
+:1094A000D4559EA7B9CB73E10BAEF62E3C7EB5AB7F
+:1094B0007CFE40970B7ECEEBEEF2ECFE075CF0E715
+:1094C0003EE72ECFDCB7C7551EDBE22E47E2875CB6
+:1094D000ED0562EEF256543E5C7F917C74C56AC61F
+:1094E000E495BFC1EFD3839F737D978B949FAB7A35
+:1094F000AA517E5A7C71CB40F9E1F294467D260D4B
+:1095000095139B6F23C9978DC7DF5AAEFE479E8682
+:1095100097A7A2E5A141895B30541EBC7CF7CAC75E
+:10952000103D23E4E57FE4E01F430E607E19EBA4C9
+:10953000F0BA9AC7EE23BB35B015C8EEF3A30D5DA4
+:10954000E95887276793F9F6C1AEF5CD7D4466EDFE
+:1095500004CAA10BF749034A01FF56AC73018D7F82
+:109560000FD6A67D284F1130A6CBD30096FFE096EC
+:109570000957B1F6F709B8AEFBC1923E02306E82D0
+:109580009A44FF2652EBF673F6CA3CEE613FB77D74
+:109590003FD29AA1987F830BEFA1E3E6FB38F2C498
+:1095A00059ADBF66F340DE326BDB5AF60CD5264D63
+:1095B000D9C0FAE544B7A52183E0CCC68CE563AFFA
+:1095C0008255CC6E639FE5B0096887CDF699CFCA06
+:1095D00033C93EDA8F4FDBEED9269E8F8B7978998F
+:1095E000CFFC25D287C1FD6A3838BBDF11F90549A8
+:1095F0004BE271ABF8FD0C457F79DC653FD9E35355
+:10960000948499C8C3AF23B2D8E7D1E3AD3C3EA25E
+:1096100002EA8742F0AFCBEEFD31FB59CAFC0219DA
+:10962000F188F17D2838719971E9D943F150954459
+:1096300012FBC17DEC2DAC9FCE31971B49473F9269
+:1096400022F08999848FAA737C54256E26F2C8D1A2
+:109650009F043E763BF67E9A141B80FE700EBFB5CB
+:10966000C144EB95E8B78E51894E9D11B7FD354B3E
+:10967000E17276967876FAF3DB87001DDC4F1ED711
+:10968000A861FB6B1A9B35B4AF0D886BE87F7786BA
+:1096900017950E676F6F68E3FBE3BDA80F03B84F24
+:1096A000AE8B7DF2183D3BC38FB4E0BC3B5ACFE894
+:1096B000505DB89D48DCBDDF5B5217F2ECEF6608E9
+:1096C000CFA051E6D9079EE0AAE71FA7F8ECFD6EF0
+:1096D0009046C6BF4BE06FC3752B294DCF4BA78C6F
+:1096E000CBEE0EC4DCF8FEF5E8C7EB97F8FBF47C94
+:1096F000789D2EBA15DA9FB59FEA583595E1719697
+:1097000098731E2C11F2A58ED55218C702ADD0F752
+:1097100010AF1F4E50DC4B0B270CA8C9EDD36A3895
+:109720001F1C74BA51D47B41B1F74B5331F4AB25B4
+:1097300023D58AF2A455B179240DAD673F3F27EABE
+:1097400077BFFF2FCFD13CA9D0689E48069B4779B1
+:10975000FA511473A5827151D94C29B86FF3173996
+:10976000996FBEAC10F3595B9830B41ADADAE3792A
+:10977000201E3C36287C1EBF21E0C14A513CAB581C
+:10978000FCFFBD48FCED7E18FEDD02FF1E7C16C20C
+:10979000BF4BE05306463BC5380DAE67012E359CE6
+:1097A000F918AF89FECB849E02F822F1CDFEFE921D
+:1097B000E04BB1E3F96A91E3792DC78FFB900F6C11
+:1097C0003C5B86E34746E0F19AC2D7192D9130629F
+:1097D00035B4D4E795AB1F0B7ABD6BCB95F5C5516E
+:1097E000C9D5C3A2FE48E3F8718E2F3F12E3786C0F
+:1097F00038BEFC50F0252DC3EC5730FE78A65877C4
+:1098000060918B2FC745BBE980CD971B5C7C3932BB
+:109810004ABEEC2D723CC773E33920E4EC17C3F168
+:10982000C501FFBC18FFAFC5F829AE7EBCF39A0E88
+:109830002B4CEBF26F9599B9FE185CBF6897E06E00
+:1098400054CEEDB0EA09EE157C2FB5F07590C1BD90
+:10985000EA84034874A0FDB616F74ACF03F896725F
+:1098600073B368FF77546FE160FB879DF53628F38B
+:109870006C3C06F07DFBBCBFD8706F3BE18E775E21
+:109880006FC31DA5F6128378BCE71CD78F3B9710DA
+:10989000DC907CA45871F6AABF3C49797D651049DB
+:1098A00063DCB14B49519C193721303EB92A10A7CE
+:1098B000149691E2D4158B793D5DD128CE1A80148F
+:1098C000DC89F1B97285F64D3EAE24753FDA11524E
+:1098D000D2A24D57D097B463FB630DCA0BB3F1D935
+:1098E00054F2D91E6A87E183EDDE5112DD8572756F
+:1098F000DB24D540B9DA35E9268AA76F6AE779858E
+:109900009B2E56298EB8F98508ADBF6B95F82711A7
+:10991000DE325503E3C5AB427F796E292BF7B7974B
+:10992000EAD205340EC2DBF241624D83234F91E14E
+:109930001D88539E1DC5E136B5F0FD1EF65389F511
+:1099400057CD3328CE68A01E63DFBB1B55B25F37EF
+:1099500055D5CCC5FE36376A646F6C5E58D34E71F0
+:10996000BCC610C531CBC28684F1F7E8B92A33C032
+:1099700059B9DC68477B33322B0418772AABE2FDF8
+:1099800045CE028A43F9219DA865CF688F0AD9B1D7
+:10999000D8DEA2ECE7D09E690CE832C6FD2D737FBD
+:1099A000FD384A85E33FF27F01E2E39F2803D2DDE1
+:1099B000E66F343D587FD8FCC668A648B86C717015
+:1099C000911E05B2338A804B17099729122ECBE1DD
+:1099D0000270E9B0797E10E7F9851AFBC3F31B1D0D
+:1099E000F986D5DC7E77DA2D7ECFF7D1E68B2EF7A0
+:1099F00047CA695E9E0BE7F27CD1E1EBDB79A223DB
+:109A00008D17C097C3531E197EADB0FB0A7DF78F2B
+:109A1000BB2986FAACBBE2DFC4F366FEAC14EF2BC5
+:109A200057C7CC303EC5F7CA9B5BCD3CFD7DC3CF4D
+:109A3000F5701D2486E54399C0FF10C31DF37EEA2F
+:109A400014061F290CAF96FB86CDBFD414AB99E644
+:109A5000ED421FCDDB002A039C37557C1EFB219570
+:109A6000A8253D63462B1DF3C7DFB487E6CF7F579C
+:109A7000CA2035127FE24847AF9C78E522008E72FB
+:109A8000F5A9CBC9237E91577C9AE5C4DF2317350E
+:109A90007FFCE922E13245C2658B83537BA4A2F4AB
+:109AA0008A9A2E122E53245C96C3AD9DADF2F5DC3E
+:109AB0003AD6817900FEF3345779ED7921F7F739F9
+:109AC0006157B96BA6BBBE3ACB5DBF6B96BBBE7A86
+:109AD0002EAF1F567DF3709FBFD879F2EA49CE931F
+:109AE0003A6D78F848E308F34AD38358BF4C3120E5
+:109AF0005B4EEB5546AC5B79F7C96B543EFFA7F85C
+:109B0000F9BEFD26450FA21FF98F3E4E45E5F8DA56
+:109B1000E31D095F5BFFBE260B7BAB403E38C4F8FC
+:109B2000B9083F84E268E718F3B5E6DF303AFA9FF8
+:109B3000E1F9F0DE765F54930DAAC32F66F619247F
+:109B40001D71988B2B149E87C3F880F6900A891696
+:109B50008C3BAFA9F2913DA284475837AA1C7A2BBF
+:109B60004FBE5E2E2E05269EB3A04F06C0DCD779D1
+:109B7000BFA13810DE11E82767BA1453E8CE0418E5
+:109B80000386C493C1789E0040938EFAAC3C78BAA9
+:109B9000DB5D42ED4AE626F8A06414ED2AFD944709
+:109BA00073DADB1D01DF20DC4DED322FA9FC83B120
+:109BB000B976FDB114BDC4FC59D9914787E7252872
+:109BC0000FC517CF52DEC38428F9656BCB6F70E5E4
+:109BD000897F45AD71C58754BDEB8B12EEE3565DB1
+:109BE0006FF60F23E71D4C5D517CA46AA9D95F571E
+:109BF000186E307F1FF340F3CC832E359941FBDD87
+:109C00009A1CE6FEBC92A27863B75436BDB7210712
+:109C1000A754314DCBF00AC74D0BFDBDEEB1BE3898
+:109C2000DAA90A6CD8279DC3EAC90BE3CEF8A5F7D9
+:109C3000A954296F3AC77387EAB6A7D68C20EF23B9
+:109C4000DA3D6A3C992F2EFAA0CAFD637F28FFF700
+:109C50005742CDDF522B86D2ED47485FF46FC740A5
+:109C60000FC6DBED3C5AA56ACF734887B5150B626A
+:109C7000C38D9739508707F9C258BC2F64EE5067DF
+:109C80000E8BC74E75661EFE858B8B7F03F3D374D8
+:109C9000062A8BF339681F494CDE4383F218874E3E
+:109CA000D457CCFFE8657C0BD5C7612B2BC7E66981
+:109CB0000985D94BB7346C018C5BFB99FD44FE8957
+:109CC000DCC4EDA73A6E0F99EC0F8E23DA34BC5D3D
+:109CD0002D7BCA0754B73DB4A66D2738F3DFBCE728
+:109CE0002DECE7D650F3F3F9E9519C3FBC99C90B31
+:109CF00033EE60539B46CF5BDB747ADED216A3E76C
+:109D0000FA3683F2F33BDBEAA8FC55AC3A1BCF45AD
+:109D1000A57AAA19FD7A625B9F5BCA5E6D46DA522C
+:109D20009C20330FEDE45E2C53BE1F7303B13C89BE
+:109D30007F7FAF2B3D0FE30DBD411B7EED3CD35527
+:109D4000BE73CD5C8417718648F77DF3D0DFDF3CAE
+:109D5000C9CE4333B54F38D6BD9A003FAF42BE2B74
+:109D6000D5EF5883FD0715BBFC3D6A3F570613F13D
+:109D7000096ABCFCD1C00EC2875400EBEFE381EF4F
+:109D80005379F3141EEF87C58B46A0238FEFAF5195
+:109D90000D1EEF5A5C46FB472A939B1AF66AF3188E
+:109DA000817791ED8092E4EB9D38DF5778DE8CB0BF
+:109DB000AE093C469E0F26C5D1ED736BCA2FF2AF9C
+:109DC000D3A7BBDFCDFED1D1456B4A9AD87CB4A5D1
+:109DD0002F8BACFEB19A9C13C07DA4F9FB6859513E
+:109DE00063596E3714D9FFB8809D079924BFC9A65F
+:109DF000B7A273FB6385879FFE72BE6F1714E7538C
+:109E00008AC5FB73AAE847B4030F4DAF1CCECE2A18
+:109E10005FE843636C506F94CD0FB9CA7A539908C9
+:109E2000DAF072B46182AB1CAEAF7195FDFA875D5A
+:109E3000F54F965FADC25EB4E13FE61957B3779C2C
+:109E400045B6FB6269E25F0233314E05752946D79C
+:109E50003B3EF300D13F34385F17749A4D942F2E58
+:109E6000FC8A0B7959B7BF9FD76956B1B2617F9F02
+:109E7000C9BF9BF6F7E9BC6CD9DF3FC2E1D15F6691
+:109E8000E58EEEA99D167E870E8ADF42550A1639A9
+:109E9000F44B787C7317E2377E492666B1F7BDEF45
+:109EA000CB5C6E211D73C2DDA5713FE02753BE164A
+:109EB000C3B8E5BAA90FC480F49E94775FF0D900C7
+:109EC000CF1BAB0C256E4739667A6D00F3050F3D4D
+:109ED000201B7C5D525EC275D167F17C7D15E2FB73
+:109EE0004CB48FEA78DC3A24BE131FAB73F0837C4A
+:109EF000F5943FA2F1F5FDF79864C9C6F3ED52F36E
+:109F00003EEA1732520B9BF755160CE0F92410F677
+:109F1000DF445E15CA13198AF74D62F4C47DF6C991
+:109F20008B07DAFD8CD6C612DD8753A46669DC0781
+:109F3000A4076C7B72ACF4017B7E17F9857AF9CBB0
+:109F400029C0757CEDD4075A912E81EC97C06074BE
+:109F5000FBD749293018BDDF0E70BC024BD2407AC6
+:109F6000BB364D74F6D26BDD20DD332EBAFF4CD4F8
+:109F70008F2579BD413885C19D3D14AE37989EAB84
+:109F8000A21D3785D3D1DBCFD100DF1FF1E261B74E
+:109F9000EB85DF1410FBDB5A86F6397E32F5A61806
+:109FA000C6B7BBA730FED717E6FFA600CFBB324E21
+:109FB0007C99F46FEFA4DB685F735DED16B22B8FB5
+:109FC000327B02F3367BABF3D7EF6EE3793217C205
+:109FD000DD2D358C3FDD07648AD77AE1BE1370DB57
+:109FE000CD5A95DB2F64F2F74A60E6C8F22747B6F0
+:109FF000F279394AB953698AE2BC1BDF89FCF58BD7
+:10A000003273E63A851D40EB6CE5D23438F31E8F8F
+:10A01000097E3D2DF474B08ACB47AFDF929CFC8B58
+:10A02000B1F7731DF50AF1AD903CFC58CC877795DC
+:10A03000782B19014A4ACFE7572BB17FFEF97CC72D
+:10A0400079B04E25A3E9887FDD6D92D3BEFD869958
+:10A050008C6A0E7F3614BBE4E7F3D10F52E279FD30
+:10A06000F5FF659A65DA4CB4B360462D9E5B50AC43
+:10A0700000C2AD57B22DE45FD4FA286EBEAEEA86B8
+:10A08000BDD538EE7A5F1CC1D6543DD582F6C5BA2F
+:10A09000DA4774A4DB2BFAA22A6C27105367D48EFC
+:10A0A000A5FCEF048E3B5CCFDA75F0DBEE3723E4E2
+:10A0B000FC5EDDAC417C993E3853FB1BE883772185
+:10A0C0001EE3C616A3739E7570289D79BE4077D592
+:10A0D000103ACF71D23980749E81EDC6F3C6311823
+:10A0E0009D2F74D119189DCFCED1B9B78AD3B9BBE2
+:10A0F0006E4B4F8D93CE754FEDAD36B07F4EE7076B
+:10A10000357E7E37847476E0E9A57358B2D79FBA5E
+:10A110004EB43FBD72CFE87E29E263BFF769FBC84A
+:10A12000EE0C8F4F7C82F8C0FC6594833BA482EBDD
+:10A13000D227116EA475697D80EF57DEA57139674E
+:10A14000ED5F89FD42B968DF5E6FC57A7899B66BBD
+:10A150001EAE870CEE6AC2434F913F3C0867C1B008
+:10A16000EB28ABB79CDA0F7BDA376154EB316BE746
+:10A17000266A47F3F46FC029ADF3ACDD761A97E297
+:10A1800069F734DB13AC9F8D9AF0375D74F82BDBE5
+:10A1900031B1A4471E94B44BEFD9F250B9D40D5746
+:10A1A000785D4BF3756DA85D4372FB6CF7DEDDE8FF
+:10A1B0009FBDA29BFF07F935DA7960DB8195A1E4A9
+:10A1C000A3482F6607521EA9F58D92CC1A5657F94F
+:10A1D000201DE5FBF0EEF568BC6D0FD5F27520385B
+:10A1E000CA75E98026F204C7301D55CA9EFE446B2D
+:10A1F000BE78C33302CE6B37FF56CC2705121467E7
+:10A20000EB8C5DBEB39FF1CE6C49433E3DBF3494B1
+:10A210007C16E9A3EA29939657112729D46E79C2AF
+:10A22000DAB5B781F4EE803C465418C74D6B8CCB41
+:10A230004519DD0E6914528B639CAD62B13517F57B
+:10A2400058159317841FD7BA4F4AE6DB2717F41E19
+:10A250008B48E4F15FC67D6A5692F2E216368CE0D6
+:10A26000DFF0FC3C663FFC0EC775484D5F32C541D0
+:10A27000779B4F5F9312975E84FAF47CCEA7D251FE
+:10A28000F2E9CFC2AE8685E534F80B4F5C48E77F34
+:10A2900082115F02E3F1417F5A2F73C8D1381F2426
+:10A2A000FB46817F130CECFE00FDBFB08FFCDEDEB1
+:10A2B000F055DFC6FB792C5D8D4F3172FDF6B2F59E
+:10A2C000BECCB1FE78E35683FEB4802FDC2F879B93
+:10A2D000629D4BFBFEB9FB85DC79084CB0EA307F10
+:10A2E0006895CCE3E877947C85F211565B013D508C
+:10A2F0004EEB18D97FEB445E5BB7C86B5B2BF2DA91
+:10A30000FCD6AAED08BF192081F1C9F6F353B4EFCA
+:10A310001F5534BD834E0CA5CEC575225A6ECFCFC6
+:10A32000C7E7A37D3558B6EEEE6C66E38DC6ECF25A
+:10A33000ED347F3BDBB9BEF94CF057F351DF18E247
+:10A340003CD6E6C645A5304C5C325CEFCEA30BD5BF
+:10A35000865C65ADAACC5556CB270CBB7FB10FE30D
+:10A360004515389E7E88239E05F286A70665829352
+:10A37000E5690359CC3B98A3C6B71878CEDA9DCFD0
+:10A38000D913E4F6E08F30303413DD2C21178D7CA7
+:10A390007FB564764D1FEE07C1182E17982FE894ED
+:10A3A000874272F1F7A68FAFE4700CF32F6EE98845
+:10A3B00002E6BBDC32FB97F1AC817AB53F86791AB5
+:10A3C0006B9826E960DF37CEFEA5912FAEDCAF2576
+:10A3D0009705917EE104D95F9186243DFFDEE31A63
+:10A3E000899F7705F93A3755F053417E36E4F8B93D
+:10A3F000AE91F1B32137CFD72969AD187E7E0CFB22
+:10A400009F897AE8F7E4B7AD6FF4B5A01E32A08F4C
+:10A41000F27037D6FB7CD8FEDF8B2E365EE1D94C4E
+:10A420003F129FB2095C1736C6151FEA917F383973
+:10A43000FC4B3FBD2F420E7F984F0E97D9F250B282
+:10A44000AF355FFEDDD4A0E4E2D706E417A74B0BDF
+:10A45000A78BEFEF4297C1F5424BAE40B959165367
+:10A46000C9EF56CA7ABA68DF88AD7BB86F749D6C45
+:10A470001AB8EF04FFE1E7F735E1BAED585FDE0FF8
+:10A4800006793BF2860594FFC186867E192B7F688C
+:10A49000D87DD18C7FC0798F89373FE350D0BDEF15
+:10A4A000F44ED5A252E457A1F6DE6CDBABE3395B88
+:10A4B0003B4FC3FBFD3A1952F9CE2FFAD120263A71
+:10A4C000F4A944879BD95A3B0DE9F1A1F9783EB331
+:10A4D000BBAA631CD931E27CC375DB9ED115079EF4
+:10A4E000D7296CF99B3E743C367DAFC365B2CC5125
+:10A4F0003FB3D755DF5B6FB03D519FD96DC1107B26
+:10A500009A4A6A2FEE3BDBE738D46D73B3B46C160E
+:10A51000C09BF1F194F02EF63CC73B5BD774A1BF12
+:10A520008DF6D7794C4E5EFBAE1CEF605F97DD7DFC
+:10A53000D67C3CE77A08B8BCD8FC7963EB9A71F911
+:10A54000E4A2107F2E0EFD75E46B7AC8235F7D9721
+:10A550009566E1F4CB57A2907C09FA1CEEE3F480F7
+:10A560003BC7E6E553A1F10CF2C9AE27E4CC5BBFD3
+:10A57000503D26578B433351AEB2D139C5C895C033
+:10A58000D7E6DFA9E23B925C69AB6503CF75552B3B
+:10A5900009D29B3DE51D96B8F791F23EE5F4347E75
+:10A5A000BFCC607E3B64D19ED0CA4DB2A343E2FED5
+:10A5B0009E40AD5B6F2A31F7F989586B226BB78BE0
+:10A5C000F14B6DB54AFD0EEE2387211B8C6299EF8E
+:10A5D00097A2FA43BF22007751DC93D5CB1BF7B487
+:10A5E0009F8AC85BC39C5EBAB70D3E3D429E8BBB43
+:10A5F0009FD8E2E1F36CBCF010568C430EBA17AE54
+:10A60000A7C021879F739BB877D4A6BFB9ED4ACA6C
+:10A610002F0F822F4EFE41EC260BFDBE2E319F7B6D
+:10A62000F0399BCEF3EAE4AF197CBFC592AEA638F1
+:10A63000837DFECCEECF3E7766C38DC4FF55389F39
+:10A64000F2CCEF3D21EE8F1DFB4AEAF7E887587FF9
+:10A650000203EFC97CACED38ED575F907D43C6F83F
+:10A66000FE33A1710477C140BF3CCF312F2F10E7DB
+:10A670003900FAE47CE7BDFC56E0299487270F7384
+:10A680007FECC9C3EF901DFEE41F7C1994BB278F9C
+:10A690000F9FFFF098F08B6CB8C7FEC0EDB3C79466
+:10A6A000BE927CF65DAEFF0CF7070FBBE515943E3E
+:10A6B00019E5E5D897F7C9181F78AC4D935E66FA8F
+:10A6C000E77C31CE0B0EF7CBE8378D34AEEF79F85F
+:10A6D0006B8F737B13B747B737BD13C2F8FFF6C74D
+:10A6E000F9788F8A73B285F07DAA8DE7796C7F3C0B
+:10A6F0003F3D9ACFE7FE71B3DF28CF6BD77ACE5BB1
+:10A70000CDD364F739AFD38CDFEE266E77ED56E20A
+:10A71000E193C1C77E5FD2149770BD2B85CCDE0F4D
+:10A72000551339F73BE322A507BFDE7E35E6B75E5A
+:10A730001936A51896EF9226B3B23E41067F0CF368
+:10A7400037DEC9BEC0F05FDB5A42F91B9D0DE5ED57
+:10A75000786E73ECF2DA5DB88FDC8B1115CA5BB8DA
+:10A760006B2DE62174E27F5939B03E7D119D930037
+:10A77000AE0F98456B28E3C4FE469E790EB9FC0ED9
+:10A78000E98340AE5E217AA99E7C90002C1A5E4F30
+:10A790002DE57ACD627F3EA07352EEFCDC312DAA0E
+:10A7A0008B7EA59EF6CF2EE1F23862FEF829F65395
+:10A7B000065B3483D15FADF3E9198487F818CC0FB9
+:10A7C0002C59C80C203C1F10D377F98C91E9BE1688
+:10A7D000A085C7B7FBC039BF9A4BB87D3FE1DADB34
+:10A7E00025F4238EC699144CC3F2F178BE79714BCF
+:10A7F0009BFB3E915B1A1E21BDD809991E5C4FAC94
+:10A80000061FAD67BD75FB7567FD2B4B24911F6659
+:10A81000F31F0C6516DDEB484138A5CE6706A3276C
+:10A82000CF7FC543D791F81F59EAA6FB68F9B21C40
+:10A83000F93F7364FE9F6A3F36DF86CE8F76C1B7DD
+:10A840001B35A0FD9DE1F5FA50BE6DA175AEA42E9D
+:10A850007F5EEE0D2576DCD672E95D0D521077E451
+:10A860007FC9E367B5DE0785FB95CBDDE31B8C3342
+:10A870001A9689FB7FE35919CF7733998E6701CFF9
+:10A88000F198807610337FC85F933DFEDA6D428E7B
+:10A89000343840F5D92CB0745A37785E9A9D877257
+:10A8A000911C8E637CA2470FD3BD48A81F799E0ED2
+:10A8B000CFE72FE528313B600026B37AA14A192C57
+:10A8C0008CEB35097C25267798C77FF08D83E88F40
+:10A8D000841BDCF968CAC192177DE7A09DE6390F99
+:10A8E0007270F972F25F3C7C1E6D7EFFC325229F61
+:10A8F000AD04C2641789FA85F2F46CBBDEA6AF71B1
+:10A90000224279395D0725A247C5E4C47DE87FC1AD
+:10A910002F65E0F99760E23DC6AB7E3693BE0FDD52
+:10A92000374854235FDE3858A27754179317994855
+:10A93000B633F8EA8301F29FAA416FD6B0BF7E8991
+:10A94000F8288DD3282F6BD54FFDF70586C9CBB2DC
+:10A95000F71707CB4A9AF689D7D54ED79CFB979520
+:10A96000A1E4CF4B1CFB9741B19F3874DFFD769279
+:10A97000F3D1EE6F945F76379DEB2F1F0F62FFFDD3
+:10A98000D30BD04E595701AEBCBC7595BCFCEAFA4E
+:10A99000290B701F679DC8BBD337BC73513BE9DBE4
+:10A9A00004C5F95633C1437AC25EBFB84FD2187F8F
+:10A9B000E9307AC34B870DCA3ECA8BFF6678FFC564
+:10A9C00067219FE23E8ABB7DF346BEAF6AC3BDA24C
+:10A9D00037FFA184E6ABDE89FBD0139320F234DD90
+:10A9E000FB1F1370F560E39CC418E467F43863310F
+:10A9F00074A0F8542FE9ABC4F5786DF92363F8F926
+:10AA0000FEF9FA21B2CF65DA872E84AFD71E2F3434
+:10AA10005E7B5FDD5BFFF608BF4FD5BBFFE58DFBBF
+:10AA2000DC87F465703DB8EFF411F6F467F2C6AD5B
+:10AA30005E2DE1F1E84E6341E2F3382EC59CFD2A1C
+:10AA4000A347A63C4A7EA2FFB2FA2BF08A3E1BDE49
+:10AA5000CE5B5384DFE62F4FD1BAA668A656C7C691
+:10AA6000A11D90716681966E277D65DFFF80645D14
+:10AA70007C361F2F8E2B00DCFEC5F3091F38C60D58
+:10AA80003147BC0BF58AF0D34E03BFA787670EE5AD
+:10AA9000EFDC1E9E771E5BC6CF334D54F2F37BFC7A
+:10AAA00012DDC7F7B94E2F9F0BD52FB4BF79FB2D01
+:10AAB000EA02B453A6E8ABF64E62787759A549DCB2
+:10AAC0007739E64FD13D39BDFFEA832D80E31F7E04
+:10AAD0009DEBF4AC738A9EA0FBF4AA52FA749CE638
+:10AAE00085EA7D2DC5FD1CEFFBCF87F97AB329558B
+:10AAF000B609F319CCA753BBFCE857C6B8DF6CFB0B
+:10AB0000D94B43C9CF871DFA68CC7C2E3F5392574F
+:10AB1000D0FC3F5631FC3D0BEB3D789740FEFB5D92
+:10AB20006F8B707CA618AB78BB93868FBBDAF4383A
+:10AB3000DE238BDF8B00E487F8990027187DEF3543
+:10AB4000B87C2806FC14E56CB2E503C3C0EF03ED46
+:10AB5000A877BFE68365F9F0688BF0F935D964A66C
+:10AB6000A7A887F6693A62D0FC1CBF84D3695D351B
+:10AB7000C4C3ECD519D81EEB7FCF1495E492F9BE6F
+:10AB8000742F526035D0BA1DA8838C81FB0ABBBEDE
+:10AB900094457EA9F5100FB27ABBA774D17D2BDD49
+:10ABA0000698786F92FF6636B1F07BAD2F6362BE78
+:10ABB0008975157D5FABF37BFCD6D63603D9B131F1
+:10ABC0005ED60C7EDE65DD5485F0B0EF1F27BB93AB
+:10ABD000AD0FFEFA812C5E5967C0326AC73F9BF306
+:10ABE000B5EACE263A8FB66ECC0374DFBFB51CF83B
+:10ABF0007EA6BDEFAC30B962EF3B97E979E327EF72
+:10AC00008592DF72CA83A2EF2379289407D71DE6C5
+:10AC1000F4BC4DE8B763FE2CDD6FD8BBD647F7B662
+:10AC200078E13F2BE87F77E7A28FD3F5D4629DB11F
+:10AC3000BF1F2A315CF765541D57693C0BE49B41EB
+:10AC40006778DFC3EC24BAE7052F063D931AB8A452
+:10AC5000D2716EE59E781FD945AA6D17D5737BC654
+:10AC60003EDFC8E890FD26FBAE639E3FF303C7B707
+:10AC7000E6B78FBC7E5921FBA8A7C4FC19D2AB4B09
+:10AC8000E4ED7F7DE9227E6F6581BCFD3BC5F8EF79
+:10AC900094ACEA2ED48F93F83D335EB843C25E6421
+:10ACA000F620C9CD3A8BDFC7B58EB93E8FB272CFD1
+:10ACB0008DFC3EBF1ECBC7CF7FD602C54962375D34
+:10ACC000A5E59BAFB61DBD5EDCAF5568DE95A899C6
+:10ACD00064BE75E99F227C5F6D6CA3417E1B51723F
+:10ACE0001C2E279CEEF4C4785E1D5FB7CF007D2E2E
+:10ACF000E6316E5E58534DF77CB275036DE27BAA68
+:10AD000033D9F9289712F4DD8F95948CB59495CFAB
+:10AD1000888F337A1DE7BAF5AA07B278EEFDF627D9
+:10AD200003106864E5F99EDF67E3E40F2AC83AF789
+:10AD3000EF532934BE629FB7327ABDE488370324CB
+:10AD40005B703E85D87A8AF326D894C9D2EFD3B007
+:10AD50008280E3E8D15819F9D21902BC6F36541F2A
+:10AD60000F63DC36D43FB7859EF5895E949FE8EC8F
+:10AD7000AD7ABE73312D916A97DC87EBDCF99A418D
+:10AD800071EE2858A552BE5A30A9E6BDDFF85089A9
+:10AD9000C2ED68D625CEAB1E6B783D7BAA72F1BAA8
+:10ADA0005867F49C7F4C72C14325EC59B5E00DD92E
+:10ADB00071DF66C4EB5F78F9E8299F2A1F7B3D7C31
+:10ADC0000C36713E02E323BF07C4EAA17317860F56
+:10ADD0009CE72EC6476A5CFC508E2B748EF6CEB96B
+:10ADE000F9EFE31C1FE179DD3D25894B2294570BD8
+:10ADF00012E5F70ABD7091BC81EE3162D2C1EF8FCE
+:10AE000067FDDD9F473F8E8F70FF756BC8BC3C525E
+:10AE100051785C8F4985F0E0F50F093FBF783DCB55
+:10AE2000C737C57C2D4871CF2F0DBFEEDBEBF3315B
+:10AE300036B67D686F2B29D23B4ABF019D389F6390
+:10AE4000BE0CAEABDDB145A417EEB1988C4824978B
+:10AE50005086FEADD01350DF1FC4F88B5FCCAB7BA8
+:10AE600056FBE8BED8508542F7D7066E4EB2B510F5
+:10AE7000CF350E6431965F75E702C293AD53372329
+:10AE80009DA3B1BE76D447FEF20CED0BDFADE821F9
+:10AE90005CFF8FA191C8ECB3EF86B777519EBF9945
+:10AEA000C8E29597E81639EFEFCF58EEFED800DAF2
+:10AEB00051EF7436E9646F9F71733F38E72BEB777E
+:10AEC0003DF265625D66AE64E4D647AF3D51C88E23
+:10AED00060EBA8F0CBE675A15F46262C2B3F147ED5
+:10AEE000A40BFDB07B75F3AB11F283F2FB0F4C2E7C
+:10AEF000BE7E3272F1AC98A7B65C0CC647441CF516
+:10AF0000AA46103FC615BF66785FB3D70F38FE0B51
+:10AF10004FDCBBE79B8C1EB23817C734F99E27D88D
+:10AF2000F7A5A696C0F23507CF5631CEFACB093237
+:10AF30009E0146398BA29CBD053E8AFFBC05FBA342
+:10AF4000331CF83C21E60973805EEA77C4173F9F03
+:10AF5000E6655BDF7DE14E77F96A58340EE387578B
+:10AF6000DFEE878C84BF57CAED177F27C2F3C5BFBA
+:10AF700000A92EA4F35A71EFE9F21F9CADA27D74D3
+:10AF8000CD0CBD1AF72F6D3C7E22D6B337991C1B12
+:10AF90000EFBF5DA7046C57CA79777CCB87C0E60BF
+:10AFA0003B99AE09B85E8D81BCEBF4E77ADC788E14
+:10AFB000340E2FDEF679A1427828DBA4BC71AE9F57
+:10AFC0000B7BDAE6E3A9DEBFFE7684EB03FBF7D367
+:10AFD000D97962A7DAEE7BC2AEF6B6BB5CC30BA42E
+:10AFE00001562AE916A926B76F15F4A7CC8968DFA0
+:10AFF000ED9C9BC5DC73075C4F91702DBE61E046F4
+:10B000001ACFAAD03D518C07F5337F3FDF3D3A95EB
+:10B01000A164245A31F43E1D10BF0FE8D06FEC7BC1
+:10B02000EA0716601C2F00CC6FA7A7427240F11DE3
+:10B0300009EDD17416FD80A0A1B8E4A304F74398EC
+:10B040005DBB52D88F2575EEEFDE78CF19512E07F4
+:10B050004DD04FF67D540B6771BD854677FED21DEE
+:10B06000259F253B72C53E3F1D015801C6AD4D0DC4
+:10B07000340F29CE75E3BA33699FF7C60A83EEF918
+:10B0800055206E525D8FDCAD3C2E41C6E1FFAF54C2
+:10B0900006549C6F2BD9FAE17C7F434C365EC9F392
+:10B0A000FB99ECA79F69F5701DD2C1C7CFC5EAAC6B
+:10B0B000EC18E73B69A985EFAB19A58B87F1CB6F3E
+:10B0C00088A9D4CF55EBA694F2B88F5B6F1E11EB15
+:10B0D000D47F3EF41F2AAEBF6F3DF8E2254887EBD0
+:10B0E0001E934163FD1E792802595ABF322AAE5F72
+:10B0F000D7EE90F3DA5598A9447925DB797CF2DA1A
+:10B1000047029985ACFEB58FBE7C0E30FC8E740C68
+:10B11000EC9988F3E0411E3704ABFF9CCBD8FB6B66
+:10B1200015F8DFF9ECA62BA2DC0F38FCC312BA7FAE
+:10B1300054DAB6EBB3D46EDF15FE80637FED92A8D0
+:10B14000DF86E371CE6F4B992979F6DFECB8FAE12F
+:10B150006F4B1CBF9D7EBA8FF5DA6DF7A94986C784
+:10B16000CA6D6F933E99B7FD3B51A4C3CA9DEE7D56
+:10B17000B6EBB6BFDF857924D7C930B010E5593EAC
+:10B1800041E5A3A6362093DEE7E7A557104B18DC70
+:10B19000F75E5BF06BF6FDCD980C41A67ADFDCF72D
+:10B1A000AAFA189693E1147AB02B77BAF5DECA6D35
+:10B1B0002F535E83EE8381AA39B8BFEF966B2F3C85
+:10B1C0009B3F2ADA212BFBD6BD2D33BDB172C75B65
+:10B1D000CFA3FE58E9D19F6FE27F2A87C6A1DBA2E9
+:10B1E0009E7B66B61597FF70DD778EDE63B17E0FAE
+:10B1F0003FF2BB7B304FFEFABFBC7BCFBFA3BDF09D
+:10B20000645047FDBFF2C15F44C1218F5F8F727BE5
+:10B21000EBC824B02A19DC91FF17C8E0FD57479E00
+:10B22000786D329E733BF2DD3F8E3318FC8D4F5CA0
+:10B2300044F7EBDFF8FD79E387B3C7515E330127AD
+:10B240005E197E5E6CA7C48D97C7C5D3C38FC3DF5D
+:10B250003DA6A25DFB9E0403B8CEADE87B5F457FB3
+:10B26000648F0903489FDD3B5EDEF36FACFC16E3A1
+:10B270004F200F7FD8F827FA68FD666A923D57EC99
+:10B28000787901E2BB1206683D1DC2CF038C9F0D89
+:10B29000397E7ABF1F85132AC663573EC4F8770EDE
+:10B2A000F291F1EF9CA1FC7B0BFF337B28FF7E101A
+:10B2B00075E7091D85EBEFADC48DDA1D63F3E6314B
+:10B2C000E4F61186BFCFC4D60723D17799C4F1EA3B
+:10B2D0008C9AFF19C579F548C9207F17227FBF7363
+:10B2E00074323A39AFFB073E8B74187822A0E3EF33
+:10B2F0008FB8F6895FD13C3BF2FD675583F66D2030
+:10B300002ACD626518FCD90FACBC82C7B661F9D6EC
+:10B310003F2F789ED55F8EBF204327BE51790F9B6C
+:10B3200077C487CCA52D06AE9B990A1AF78A0C9F85
+:10B330000F2B32BB16E3BD125EBA4BA5F6BD9E398C
+:10B340007EE27D4F2B76BCB800E5AE103FEDF1EB11
+:10B3500038FE73D9F7ADEEF9EA855FC1E627AD5344
+:10B360005EFE6676FD373E8FDC1750F07CC51171AE
+:10B37000DEDBCBF71CFDC5F9F751EE33FDD93BBF42
+:10B38000ED7D2641A7C2F2C1E7F948E31B2DFDDEA2
+:10B39000881ADCEFF6D0F1F089FCFA7F7C295FB7E0
+:10B3A0005740BA054D67AFBDA240D29A589DC3F72A
+:10B3B00030DA170CDFC30FCA14F7E9EADB4D7ADC89
+:10B3C000AB2F561488BFD6D9FDEDDC750EEAB5C398
+:10B3D0004FFD90E473C5432FAAE877ECD9F63DB54D
+:10B3E000BF3E371F707DC838E87DF8E15DE7707DAE
+:10B3F000903FAE3553B4BFF27177FB2B1F7ADBD58C
+:10B40000FE75561FD90B23F5F3A6625E81E37D73AB
+:10B410009F9FEE137CB34FCE1BE79E50EA77D9C1B6
+:10B420005DCF2EF8359E676DD81FA27B1477749878
+:10B43000E36F41FB6DBF5FEC1F9ABF43BB74C7B3A3
+:10B440002103EDB41DFB2FA77C1EBBBD1F78E8793F
+:10B45000EE016B5E84B5776E7FA201F345BC7AA3E3
+:10B46000F120F3F71C7270E3B32DE351EFA37F6C6F
+:10B47000A0E3ADC4E91C951C5D4079E2B2EED38334
+:10B4800079D76FDE9E3F9CA0FD1C3F134CE7BDECBF
+:10B49000179EF8BFE4BF77C5F3C7FBEF2AB5F7BD2A
+:10B4A000F9EF77B2DF6F90B8DC58CFF07D8E42F3C2
+:10B4B0006B5B5B2C5ECB4879575B631CF77396978D
+:10B4C000F2F8C7D4572C1F9E0D99DD6F4CC7F14F72
+:10B4D000843EC0F3FA3BDA74821FE4FF4266519760
+:10B4E000E37DF3104738EC17FDB5D1F67B73A17EF1
+:10B4F000EBFB882EC5F4AB9D44BFEB4BF979E953C8
+:10B50000E9377C127406DC1D2A62BCDE3C296FFF21
+:10B51000EA349EF7E5ED6F4929B733EDFD039A7ADA
+:10B52000C3C4D5FCA29DCF941A2E7902254BF74FA8
+:10B53000E7F22A32527703EECB0D9E174E688EF358
+:10B54000C2EC3B9D175E63F23C56568FE6418F88F6
+:10B550004FE03EE5550E7C9F15FA2350958AA1FDDC
+:10B56000D58DFB0D79F4D8F342CEBB23CD943FB2F9
+:10B570004B9F5EDA3FCCBAA1ACBE6B86F35CB1A246
+:10B580006725D7FEB0F932DD8355A8BE77DFD0C678
+:10B59000BF7BD797A006F35CCB13D09107CF3E219A
+:10B5A000C708578D70B124B43BE0D4181FA75DEED7
+:10B5B0007E9FDF73FBFCAD07BB515F16A2D30EC1AC
+:10B5C000CF6731116426B96F1AE663F6447CA4276D
+:10B5D0007B82F9EFA3FF45CE2EA0FA2A9E5FA478C6
+:10B5E000EB3EF21B8D132F9878BFD1ADF52AED0BF2
+:10B5F000459AF653F9A8E923EBBF107DECFB08064A
+:10B60000CB05E24F8D3AE7EF6EF311CA6FBDE16CE7
+:10B61000D5182E9F22B47A5A1CCFB36BABE7C43136
+:10B620003F2254C77F9FC2C6F3793C6D6301F998EE
+:10B63000A573F958FF453B2E992539D938CD17C444
+:10B64000E7FF075094EC5E00800000001F8B0800AD
+:10B6500000000000000BED7D0B5C14D7B9F899DDFC
+:10B66000D9D92730C002CBF21A10140D268B226ACA
+:10B6700035664134F8885915A326185763521201CC
+:10B6800037D636B4B5611010C447486349DADA7664
+:10B69000A5D892366D31A58D491F77D5E8B58FDBDA
+:10B6A000A2318937571B34DE5C494D2F7DA4F5DE6E
+:10B6B0006BEBFF7CDF996167965D3069DA5FEFFFC6
+:10B6C00077C92F999C39E77CE73BDFF9DEE7CCD9D6
+:10B6D000A3DE6909830E426EC0DF1DA39FE6862F9D
+:10B6E0004EAF981E2EB7E5C473FE224276E63C4E5E
+:10B6F00006E9D37CBD91F8687F334FBC7DF499E8AF
+:10B700002547139CB4EC9D986BCEA54F0749379401
+:10B71000D07E6513B91DB9A3E11FCDFA84EB12EDFC
+:10B7200097E625E9F06C2B13D20D1A7C3A3F1320D3
+:10B730003E3A4E6B99B016F034873E49A4384DBD61
+:10B74000682064067D5FDDE9F5D276F42FDD47EBF6
+:10B75000094FD25768DB71644D5FD1E8F1F78B1C5C
+:10B76000212984EC56EAF7CD7EFB990728FEA257E3
+:10B770002A365230FB8E0E91BCA9B41C1AF27230DC
+:10B780002F27996625A3E140BB5CDA2EDEE5271B57
+:10B7900000CFCC41E2A7E3C7170E1298BF4D22920B
+:10B7A000414238887FC2AC6122D3760973075DF2CB
+:10B7B000540D9C3F1BA3E27923C18078DA1A4A3CDE
+:10B7C000F9C984581AE679F2E9BAC4F10344A470BD
+:10B7D000E22446FFC87E6F2530FAA874E92C9B98B6
+:10B7E000E08F065F5DDFC653A9BC49532EEB5C03B7
+:10B7F000F43739FD32CC3F7E16A38B5A1F2F0D1222
+:10B800002F1D379EB0799212E23D441F712532817F
+:10B8100071E8905EED7C362AF4DE28B2F9C09F37DD
+:10B8200015DB11425FC579170E196F85324F2E1542
+:10B83000B2FA1BB90417F49245291B479763CD67E9
+:10B84000BCE7AE46422E69E66BC9A4F357E1D27F4E
+:10B850003B4D241DE8FB41E926B806911FD4F701B2
+:10B8600065FE26E720D26714FD8A18FDEC458C7E24
+:10B87000F608FAED52FAEFFA07A3DF089D38C31A6B
+:10B88000E0C3483AAAEDE78DE02DE393F623E423E5
+:10B89000505E5609F2DB6965E5FDE25D9572119334
+:10B8A000AB71E485103721A59D37DAA0BD5B14117B
+:10B8B000AE7913D5070E4DD9AFEA0736AE23D7536D
+:10B8C00049283F935C03394449DA3E5776C17A757B
+:10B8D000A0A484E1BF2A4EC0F66D9260E06EA3CFB3
+:10B8E000530BD20885DB6CE9B4C07CDB4D9D08A707
+:10B8F00039CB207647D16FC794F91A1BECD37BA6BE
+:10B90000C7A6A35120FE6872FFA6D2BFF9E8E74F91
+:10B9100019297FF092205929BE20F46FA9EB9B478B
+:10B92000FB93BE81DC5C18271EC7712878390A0C8E
+:10B93000A429777C3CBFA5F015DF601D134F1EF0D6
+:10B940008CA267543C5B004F676C3CED59E5C8A77F
+:10B950007C8303C7F99128A17E729802968D747E2C
+:10B960008EA604A9893E77F181F66A780E98884CF4
+:10B970009B9888F75439C59B9F3A8D100AA7F5E22A
+:10B980004CCB04E0FD864EE2D3E8F94D36FF05913D
+:10B99000C2E3453FF1533C7947C00B68F42A7CA0D1
+:10B9A000AE1B294C2264361DCFCF4F077D6AF70BA3
+:10B9B000F854E1A87C623779895804700CDE207D48
+:10B9C0005A00D8EC70BB8F2432BA35CF0DF908D8A5
+:10B9D000B9629E809D6B33794F6DA0E50E3A9F6EE4
+:10B9E000FA6C51F846EDE74E4C647CA88C6F2355F9
+:10B9F0000921806D7CCEE51FC31EDB806EB47DC344
+:10BA0000F9DCEFBCACD295FEFB3F629CF3ED5B90A2
+:10BA100077D3419EDF2345AB0D86D870FED4287DB9
+:10BA2000E7658DBE6A20CC7E1022A52D9F1ABBDF54
+:10BA3000EE46323DBF205CDEC3072C409F36C7D6A2
+:10BA400053B9749EB2C7E02990004C898E4E914F35
+:10BA5000429A70DD4DC403CC4B9A33CB4F954BB01B
+:10BA6000BE2B5C8F43B5D1C1535B4B4C1349D008FF
+:10BA700074919C3AB9DC64637C13B9CED6113A1E3A
+:10BA800018938E56454E22E9989FF8BF938E2265F3
+:10BA900027E4D7B8150921E8779CFA49747C92A964
+:10BAA000973FB59FCAEF91F3AFF85F3EFF483E194D
+:10BAB000DD5E56ED267F9436CDF093600787659F57
+:10BAC0002515BB5218543E2DA126304D59D57DE980
+:10BAD0002708D8E716F16D0BAA2ECF8DE4B1E0F35D
+:10BAE000E46D959EC6F0785AFA18C0EE9C32050FA8
+:10BAF00071613AC589F7BB8E920F4EA7B6CCE7C5E8
+:10BB00000D1AFB71592CDF9E48E9B213FCDA28723A
+:10BB1000B03EB15C4EA4780986E8FA7C3FE835F483
+:10BB20001B457E011DE78E613D9D6E57E8342FED6C
+:10BB3000ED4FC334A996E40955C8E53E4F05D0AD95
+:10BB4000628D0FD8820819D76FF1233F54884017B0
+:10BB50004E9E64B861BF79FAC5A2978323BE687808
+:10BB60007F455CF1259897A388D24DE37F50411023
+:10BB7000DFB66BD6C5E11C87AFD8BA1DBF90669003
+:10BB800069D336972108F18C8904DA81EEE4AC910F
+:10BB9000809F961A4AC77AB32B2F08F62E35642554
+:10BBA0005E8C13C4A095B6EF5A7B8F07F5D3B539D9
+:10BBB0002444F906751965323ED31B027F9A17A5F6
+:10BBC00032A304E33C6681F8A6CDB52281307F9B89
+:10BBD00044D35F7589FE17615DF96BF3109EC1E276
+:10BBE000453FF166E7F3F4CA78027E80F53C1734EE
+:10BBF000535C9E5C39AF7D90CEC742E23ACDF4D91A
+:10BC0000CCCB21B063F279AB04F4DE5A20DF69A01B
+:10BC1000CFB25F590B79FABE9DB379800EED0574F2
+:10BC2000C9299C3F7DDE1E24B4BC73E5B2E10480CB
+:10BC3000D36394A07EFF8DC06DE04F59AE3F81F17C
+:10BC4000A145890F091F9809EB67FD807A6237DFEC
+:10BC500089FCBF2B7F9A45EB8FA7DBFCE7812E6A1F
+:10BC6000D9EAA2FA6D3AF2D3A541CA4F0699233711
+:10BC7000287F5A1CDB5C2724982F7DAFF2476EB8D3
+:10BC80005D586EF56527A535F89994C316815FD97F
+:10BC900006FA06FD562273504E67F5BF7DF2EE455B
+:10BCA000E087B659D5FAE58BBCDAB2FC3FA7B0BF46
+:10BCB000E2F7162525ED82F6CE0C1260F4F19155CF
+:10BCC0001A7F464AE2510E7B12BD7F4C9C319A2F5F
+:10BCD000DBF3195F1EBFD05699077C4AF9D22C01BD
+:10BCE0001FEED2C5C9EA53E5C3B67CC667B1E86E9C
+:10BCF000BA564C421A3FD0E4EC447EB4387DE84753
+:10BD000047B6BF2B99E90B95FF2D2E82F26091FC6F
+:10BD10009F7F10E5C3E101F133E7070847F9C42429
+:10BD2000B27878BC79C4C24FE5FFB6FC3C19F8F58F
+:10BD30003D913A1263B4375D2BC1F9D4257A7392E1
+:10BD400034F1873387D23DCA7CBE98C4E6D3EAABD0
+:10BD5000F63D48E17A6B2419E5C6453C1D609728FD
+:10BD6000FB83DF49FDCD5B9252B4740A307954E015
+:10BD7000CB5CE0A809E4DC49FBD1B72DE487322C89
+:10BD8000BDC919D4C9F7BE647F4992867F7991C530
+:10BD9000870B8C0E03F900F47982C665A14984EC07
+:10BDA0006D14F1B9A7D185CFF646099F1D8D5E129E
+:10BDB00032D3F0875C3BF700F8D90E1BE2371E5FE9
+:10BDC000B4367AB07F4BE32C068753F9BC7017F07A
+:10BDD000B5CDA0CAC9AD584E30AAF525BB30BEE3DB
+:10BDE00058FDD6A4DB514EE87C50EFB58F33AE3111
+:10BDF000588AEBF7FEE12BFA5BA1DF13B77FA23283
+:10BE00000FF8EF7523D1E63146F14B888D77B3F00B
+:10BE1000DB330DA84F9FB87DE7A95CF05B5FA3F013
+:10BE2000C7E2C74E063F263C15DFA3BB105F335D5C
+:10BE30006F2B85671699BE8F250F91F3A54F82F260
+:10BE4000E124A8A79F38BA961C07F9A4C35A4590C5
+:10BE5000539F17F25D420BA5B107ECAD2FF455B01F
+:10BE6000B734D03944CB822237D4ECCBC7291CC19C
+:10BE70006B211DB4DFD1DBEF21D0AFED650BC589A0
+:10BE8000DA87E43CE4776B411569A6ED76565A896A
+:10BE900091BE4F98B78600BC9DBFB022FCDC539387
+:10BEA000515E77894C8EC6D5432E030969EDB8C51E
+:10BEB000162EE781BEDC447C5351AEBF90A4D18FD7
+:10BEC000D44E7E19CA02A990090776F8210FF343D0
+:10BED000587D4FA2EF206BEFC3FE61BF304044900E
+:10BEE000D7B3C66007C49BC65A74FA161A0F580611
+:10BEF00051AEBDCBD24B09713014C82E4F886403AC
+:10BF00005DD28DD417A32F3C020951BBD149FF014B
+:10BF1000FCF8F343E7C9AD84A4AD1174F3E0CFDBC3
+:10BF20002F1A6E05FC587BD50EF1E7EBEAA03D4FCA
+:10BF300034EDC13E19AB13C68A6722FDF81F2529CF
+:10BF40007EBC9D6481DD6B693C42DE3285E1F0118F
+:10BF50007925F5A9FAF39B930D7AFF4762FCFD1250
+:10BF60008DD3811F5B5F3592EE28FCFD87A45C9D1D
+:10BF7000BF9BEE3784E747FF7DF982B9BC4BC79F73
+:10BF800063AF7F468DBE7F56C0A6A3634E4392AE7D
+:10BF90009C2BBB75ED27B4E7E9EA0B3AA7E8EA2743
+:10BFA0003D334D579E1CFC88AEFD2DBDE5BAF2D445
+:10BFB000BEC5BAF6B71D59A12B1787EED5B59F7E22
+:10BFC0006AA3AE7EC6C023BAFA99E7B6EACAB30737
+:10BFD0003FA56BEFF28BC78E807C527E34527AED98
+:10BFE0004A979F01FB39D84CFDB879CC3F067B4B73
+:10BFF0003289E21F53C3940A7CC5FE5AC00E809E4C
+:10C00000DFF3E9D067D04E1A3C20BF7CFE42EF46FA
+:10C01000E8D7221A884BA347A48504DE97EF49C4CA
+:10C02000F7DE9226940F819A0D6B3CD86DFD7A1045
+:10C03000E376D207F8BDCEF0E34539AA7E1232F599
+:10C04000FC6F26F725F8C6F0FB4C92BEFDFBE5FF22
+:10C05000AC64CAFFE0706451FE378EDF5FE5FB47DA
+:10C060000CDE09C92C5F5E71D6A98B7B90AE237163
+:10C070008F85B4803895550F679C60CD95F8C66C58
+:10C08000B871CBCDC73791F2459F94E6749D5C4C57
+:10C090005FABFEFD687B385DE79F453E9BE31F413C
+:10C0A0007D47F5E2EDC93ABDE8F32643DCC77B5195
+:10C0B0002FAAEF737BA7A05E6E17999FD22651B966
+:10C0C0001C835E917AF9F34912D39F31F4B340F5A2
+:10C0D0002C18DC9D2BEF6F07BA79B711B44BD4063F
+:10C0E000A19E8D844FFDAA7B006FC1C5FC29351E22
+:10C0F00052E32D0BD51F105F592482F432537AD9A5
+:10C10000D13F7A0CFD4B3A0F09FC23B393FA9F60A1
+:10C11000EFA9FFC9FCCD0FD7BFCC56E63D4217C5EE
+:10C120005EF6D8BCB5C929B1E1FF20C67ED4CB49A3
+:10C130006ADCFDBF93FFE6264B887F241FAA7C663E
+:10C1400006A6A3E3BD27B175A7D38AE7D4FD0B09E3
+:10C15000FEE3477E3931EB8C3C1FD6CDEFF09AA938
+:10C160005DDD376B05F61326F004F44CDCE086A5A4
+:10C1700060274909D31332FD07F8CD56A4D71B9683
+:10C18000083B2A803D8E1F6D7755FDA0C6E7E3E989
+:10C19000976755FD3293CCD4EA975871B8AA5F548B
+:10C1A0003ADC71BD5144BFE33AAD57FD090AC7946B
+:10C1B000C5FB20CF2C7888F76014F9FB27C52EEF3C
+:10C1C0003D66C5F8DBB146C038CBED0995019FBA95
+:10C1D00003C403F4993518227E0AFF0527E34FB7FD
+:10C1E00027C881FFEABE1CE400CF2E13CB0BB9B7E2
+:10C1F00005396DDEE8DF93593EFB4F171EF3C0BAD9
+:10C2000097E738504E3FF620417B3DE0DAD859069B
+:10C21000E3CE221E334E97276E289F3307519F7817
+:10C2200006BD024BC1C97174E82B8D64DA261ABFB2
+:10C23000BFD368C1E7D546119FF3730E1CBD83C2FF
+:10C24000DD9A6BC37C416B9E0DC769CB16900FFFC7
+:10C2500098F5480EF805BF697461FBF6C703859031
+:10C260004F683BC6F68332BCD3711F14A9E6027C2B
+:10C27000426C7F870FB860DF37E3F84FB05D9BC932
+:10C28000FFAF1B283EF25AC17348627480F9B6585A
+:10C29000D9FCCDF680279196CD13C8FAE5D1E451AB
+:10C2A000A107E524A3900A7940C6A7C22CA909F2E8
+:10C2B00021542BF451F488A935C8C1BE077958948C
+:10C2C000202F9469091EA5311FC9AC113DCD04DA98
+:10C2D000136FD0115E0F9395F80E3BA05D887B9491
+:10C2E0008EDBEF64FB13EE736C7D7E7FFECEA35975
+:10C2F00024B61CEF69AC3C53A1C9BB3A48F4FDDF3E
+:10C300007373CAFF027A087D045CD79963DAC19B14
+:10C3100085EB75323D75FCC2A434F08B1BF8E8FE4A
+:10C32000A45154D7494A8378796B819496E8D0C256
+:10C3300061FAC278EC455C2F7B5110CF17347FEF48
+:10C34000F5FA4F53FAFE8E7684BCD4CB173E8A7131
+:10C35000E2BB49D213105FC93F351258CF77BF3FB8
+:10C36000F32449183DEEAF1B4F25F19ABCD1BBDF3A
+:10C370003E5D6AA2F0DF7DFE74298FCA26A8D353E2
+:10C3800075375E29853C95D0F07BF7658AAF5C4EAA
+:10C390000A0350A68E32C69B72DD92D01874EB4A07
+:10C3A0007DE851C80B069B1D2247FDB2A7ED7F110A
+:10C3B00080EF1A007FFADC6219DEC9D125FEEFAEEC
+:10C3C000B71757D078722B27CB0E0EE8269B217E0D
+:10C3D00020E7CD1EE09BAD05CC2E6E7D580CCAA08B
+:10C3E000AF42012FA6852CAFB82F537D6BFD79107E
+:10C3F000F6FA490BE79B1F0779BAA904F97ACED55B
+:10C40000400EEC1F2712210FF8D06430229CE10B64
+:10C41000F66037EAD9C04CD0374D171E9B04EBF5B8
+:10C42000FB64762E40CDAFA51A024F56E7427ECD73
+:10C4300083F9B5DD7C1FEE93C59AAFDDC5F60FF825
+:10C44000F944898F7FDB119A1BE60755BE22FBED6D
+:10C450006F249E7CCA5F2F355A3C30EE671B457CAB
+:10C460001E6974E1F38946099FDF6F2CC4767B1B3C
+:10C470003D58DEDD380BCBAD26B2DEA7E1B34F3839
+:10C48000D93C5627947DC2499FFD14EE65DAAE97DC
+:10C49000F687E79CB341631CA5C79C2B542F4A50D9
+:10C4A000DFEEB94CE17D91C283E7E87A4B31BC2FD6
+:10C4B0000DF685044ABFD222F6BEB7B157E977041C
+:10C4C000E1D27AA47FE955566FAF6570EC57D4F688
+:10C4D00085C5CA38C5D09E8E5BACF48B848BEF29A2
+:10C4E000DCE268F844B6A7DEBC91942AFB1410D7AE
+:10C4F00099FA38F067648E840EC17EC6F9A7CBC066
+:10C500002EEC29267906DAC894D2CF41B9B78188B2
+:10C51000C644420AD3A7759401FF98BCF85EDECBEF
+:10C52000070FE5A21D42B8AA1DCAA80D79817FE2B6
+:10C530003D24CF584CD741BA84F686D035B6CFA12A
+:10C540004353F1B9A4B1B337E87FE0BC01AE0BEDC2
+:10C550009F5EABAF1FAF3DB52711F5D1F9EE833E1E
+:10C56000BFD8A83FE7D15547B538D51B5D8A1F76A0
+:10C5700000EA61BDEA4A133642F9D187D2416E7FA3
+:10C580004F5C1CECBB8FF48BF0DB0E349E4AAD2865
+:10C590006078037D32B78907B5FE6CA64CF9552348
+:10C5A000077B037C6537E611FCE92B34F14FABC9FF
+:10C5B0009F4E8597FCF6A9D717817E00BB0C7AFAAF
+:10C5C0002357981D1FB1DF57997E54FD064159AF7F
+:10C5D000CF95FC2E04722F833D02FBE4F19372DAB7
+:10C5E0003F658681033B448AF5EF9D02C3CBED0A8C
+:10C5F00072504E76FA5E06F9E1939E21C0477FE8BD
+:10C60000374BC06F7B8FAD2D04FF790B8997ACF44E
+:10C61000BDFB871705C0A3D5302810AACF86F66FBB
+:10C620005BCC537FA75550F4243838741D5B5315E9
+:10C63000BD20FFB1A302FC0D837F08B67AD5F65D5D
+:10C6400036FFA350A67F5E0BB5DFFBADAA9E0D742F
+:10C6500078298FED37B1F2D0FE2D1D329669FB623D
+:10C66000566E4987FD296FBA81D22BBEA9AEE3541D
+:10C670001694D5F6751D72265D4BC59E12873F1721
+:10C68000F4DE4859A4E5384D9967656261CFBDC7AE
+:10C69000FE4B807DD3D6D4E1931940CF1F737DA08C
+:10C6A0005FEB8E3F7B14CAF53544823C9CFBC8414E
+:10C6B0005C87678D6543CE1490E353223AE4F0A77C
+:10C6C000AE0BF54727BB08E68D852017CC033FADA1
+:10C6D000A8D3807EDA76EA5B1703BDDB53619DE762
+:10C6E000A4323F637290C2D1C8C1649E86EFD3C0AA
+:10C6F0005C998607B57115F118005F2439FEE7DCF7
+:10C70000E210C5A777966C9B42C7DBBC81F7344922
+:10C71000607F824DE08F91231CDA89DC53E93BBEB8
+:10C7200041CB57FB92BB21AE30ED607CB039B72FC7
+:10C73000751A7DB65A997EDD9CA89413F5E516C549
+:10C740006F7425CA8949F47DFD9127B3658AC7D0E6
+:10C75000A199182FD6ABF8C87B1783BD1C3A3A3B7A
+:10C76000610E9D6FDDCF59FEB2AEBF7831CCBF6E8A
+:10C770008F8140BC56DF4FF9492B1F540EBD93E803
+:10C780003CBC9D5378CA1F8B52739758E9FA3E9B65
+:10C79000E715815E1BBAA6ECB6D020E859419C0C87
+:10C7A000F2B2A1CBB31BF869F38C4BC88F96CF794B
+:10C7B0007E569944E3AF7B2B17835A4B3530B9A48F
+:10C7C0000C877ACE98B80DE9FF9F6564D89C88E401
+:10C7D000C4FDCC1CF83F8ADF24D15B0EEDC5A53427
+:10C7E000F4013E157CC7C00F91CB2D980F2D1797E4
+:10C7F000627DF61A62E8A0F81C9492929A68576BD0
+:10C80000BED7007E4A9ECF86794E635CC50E909B54
+:10C8100043675939BC4EBFC275B21506FB2C14CE06
+:10C8200044072F42CC916AF45A60DDA82C0F1C2AD1
+:10C8300001792168BFE5CF16615EA72B9ED43C4FDE
+:10C84000E9D463D8D8F113DAAE27C949C0AF6CE593
+:10C85000B8F52BF07DF994AD146E8FB27EC6448F7F
+:10C8600008EBD593A82FEFE7363E0C72B4E5732F93
+:10C870002C86F9A59ABD9DC914BFFACFBDD0E19A07
+:10C880008D74CEB350BAD4A7BCD061A174EF69F255
+:10C89000BA454D79D29FA9B6C679BC8072CA277EA7
+:10C8A000F61190635AFF530BE5DF6793547F80D5F1
+:10C8B000E7E7A9651ABF521D6F6C1A29CB16AAFFAC
+:10C8C000F335ED2BA8DC7EEDCB46A2C20FD1B26DC5
+:10C8D000769FC566C479101BF8335379F4676C8969
+:10C8E0006C5D6D93F3D04FEAB1327A0D6719B07E6B
+:10C8F000A1F13911F200E6C9BCC18CF173C0672AFD
+:10C90000817D579EB0BCEE01EF6409D2A36C1F90ED
+:10C91000EB5C8E71A0B550B3EF47205ED5EF13F2FC
+:10C9200011E502F360BA81DA61E7F9E55C36855713
+:10C930009BA2C4854E920E79D7400AD3338FF9E477
+:10C940003B4D12F0D8203B9F4A7CD3E099B62E3F56
+:10C950006DAC7385A3F7FF43E897ED711814BA49DE
+:10C96000BB43D4476D763C2F821EA1667EC701F083
+:10C97000279D3CF24D01C83F2D6F4B64F9F6DCDE7C
+:10C98000C54FCF02FFF0748101E49F173D229CA7A1
+:10C990002B8B2B4900BF8D1FE1D357507E8D4767EE
+:10C9A000DF0DF19E00F24BDF1EB0B273A0C3E9A40D
+:10C9B0000FF2BFBCCB4BB4FB81AAFCEE6CB4E073AE
+:10C9C0006FC98A6FC03EC1D7DB09EE07082E1F96DC
+:10C9D000A516C2815C1C2FBD17C7FD2AEF4B580757
+:10C9E000FAF62CF3EB815D309F117A8A837CC67B4B
+:10C9F000165F02CC7B5FA2DE9EDE96CAE2613985BD
+:10CA0000E9CF3625DF295CBB05F337AD26551F5925
+:10CA100096807F2AF07E3C2F6BF66FF382BEB210B9
+:10CA2000591635F9704BA63EAF255CBB15E1C829F8
+:10CA30006C9CC873050E4E854FD7610C7F597D469F
+:10CA40009E4368203ED44764809D6FD8B66B7E5A63
+:10CA50009206CE36CE9B268EC11F5BAE194950730F
+:10CA60001E650B3F2CC07CB65C13F03D710DC637C4
+:10CA7000C1FE0B65B80E58C717BF8B76C9463A433F
+:10CA80007060CA0CF908CDF94FE2E28747F83F2FF2
+:10CA90002C1FB87FCE45910F495F8EDC370F808DFC
+:10CAA000A57EC50EFB6F0498E7BBF3C930F89384ED
+:10CAB0000C2E04F9AD9B6FC37CF416D269B1401EF5
+:10CAC00085EF14B579E1BAFE8BF1708E8E2EA90434
+:10CAD000FECD961F96E9F251EA3930B55C7F6403CA
+:10CAE000E609B7F45C15A694201A03261A8FD559C7
+:10CAF0003A4F99F3C2EDAD26BF9C01FCFFC347BD81
+:10CB000019F4D5D7004F383FD5306126C47F7F1048
+:10CB10006BD2814E765EB11F6B2C683F5AAC345E8F
+:10CB2000033EBD3009ED29ADE6C13EABE32F56E231
+:10CB3000E221F02F6640D73EF4D35B6DBE2B609FA1
+:10CB400080B179EAEFB426A97CB3AD03E4A74B0822
+:10CB5000EB45F09FBA6CAC6CEFDAD6D1C2EC30F397
+:10CB60006F9CDC6EF06F5A157F6968FF75F48FBAA1
+:10CB7000844EE6FF7DDF2C019E5D369F07E2417902
+:10CB8000C76409EC49459A03E7617AC1DC0DFA30C4
+:10CB9000D9E9BF047E0B7132FFE8DD94F3D9200F91
+:10CBA00051E00C733703C7A587639DCBC67F9733CE
+:10CBB000FA769484DBD1FE21DCFFBFCF82791EB5EB
+:10CBC000FD01935EAED5675E2AA327E813906BF54F
+:10CBD000BDE0DF84F26B2601945FB34BBF2FA4CA84
+:10CBE000B3706DB22E4FF9B514B63FA5EA01E15A04
+:10CBF00011D6CB0A9FEE84FDF231C7498A31CE743B
+:10CC0000D413B1C72955F40851F2BB3C9E2753E514
+:10CC100024B6BED0E76B23F59FFA54F5DF17143E18
+:10CC20003E6DF5CF4BA5E33C12EC5B68C3DEFE5BCB
+:10CC3000617DFEA4F06561EF93C780FD2E8BDE4F12
+:10CC4000A5CC807353DE6FA4A4BC7FB9D990CAE68B
+:10CC5000335A8FB1FCC3B68725B4CF5FE53D364F5D
+:10CC6000143D5673CDAED35F19296C9C1A5E463DB8
+:10CC700056732D1EEB3F387C2B094E1F0BBE03EB6A
+:10CC800047E0F731F8C74B7FDA350BE01F3619CC98
+:10CC90009A786EDBE105699097DC66A57AD9A19355
+:10CCA0005B2FC82D9F4B46E22090F37D23F5F37751
+:10CCB000837FF3AC56CE6781FF15EECFD375DEA729
+:10CCC000C83D9197446F6F8F683FE25F5561FB48A5
+:10CCD0007C543D0265F0B7F83F9B55FC500F3D6911
+:10CCE0008880A7FA637235C2DB3C83F919969407F2
+:10CCF0007F26E703FF05CB200E1A7E9848DD6434BB
+:10CD0000DD2D0A1FD65C9BA05BD730BD27EADEFF76
+:10CD100047A38B0435F2F651FFB6856897619D00F5
+:10CD20000E917762BF031924A891BBFFC3E383E28E
+:10CD30003127061EF3FECE78E4EAE4328C47BEEEDD
+:10CD4000FD07C5C368B9E6BEAC299B4492A12D1767
+:10CD5000872C1997357ECBF453A2AE3C63C0A56BEC
+:10CD60003FF39CA4AB9F3D58A8AB9F73C5A32BDF9B
+:10CD70003E3C4BD7FE8E6B5E5DB98C2CD2B59F6F5F
+:10CD800059AE2B2F10D7EADA4F54F2E477BA36E8CF
+:10CD9000DA2D921ED6B5131A92BF03FECB1DD7EF24
+:10CDA000B0407CB1D361A8847D879DBCDF921445DF
+:10CDB0003FDEA6C01DB177AE54ECBF400CB4803E40
+:10CDC0005C4043E166EAAFA555FB5AC0EE578A2C9A
+:10CDD0008FA8E6CFC9F59515F0FEEE4544EC480C5A
+:10CDE00097EFFC14215036677AF1FC9AB5C880E7BA
+:10CDF000037617AD1873FF619FE2BFEF89B0F7EAC2
+:10CE000033C1C8CE4946BE2F48637EC29377EC2318
+:10CE1000B04F607104F17B9EA39377BAA0FCF41D20
+:10CE2000DF76419CD13EF9132EE09FB6ACAFE9CE40
+:10CE3000DFD9F2097EDF110977BF0237FFDA631607
+:10CE4000B09FBB33193D23DBA9E7D0775B58DEFCED
+:10CE50006F35CFF234263F1FF63C2F2870775B8268
+:10CE600098FFEF28FCDBE05F3D82FFE384E1FB38C5
+:10CE70009E376ECF1224AD9D559FF07D28CCA72DF7
+:10CE800077A70BEC6E7BEE2774FEBF399FEDAB45A9
+:10CE9000F6E35C6CDD768B7FDBF93CF657CF67679A
+:10CEA000D4FD754B8C7915A8F3720591CFFE56F31E
+:10CEB000FAEC883CFD7DE6F5A2325E7C1AF34F77F2
+:10CEC0004B4C8E128CBE5FE6E5C696BF8459FAF3D2
+:10CED00048711E7D1C9097EF1BF39CD139853EB1A4
+:10CEE000E4758D494E013C5E6B64E769CF021DE934
+:10CEF000F39C7F42397C97F01A9CCBE2A0FF8EB85E
+:10CF0000B1D661ADDFA8C3733CFD30258D9DA75C14
+:10CF1000BD46DF6F95CFAE3F17A59C27A0747A0260
+:10CF2000F2CB2ADD46ADF38744A758FC76B374EA0A
+:10CF3000287C7F741A8FBFE3D398FD1A8F4E2A1F67
+:10CF4000C582F3FF2B1F95037D6E828F54FEF95B24
+:10CF5000D3E71F8D7FAAFF8F3E63D2E7B19BA48FDB
+:10CF6000AA877A055213ED1C48934B40399DC4059E
+:10CF7000CE2C8238FB2E239E773873A0A78EE469CF
+:10CF8000DB317B7AA6F2AB7578EEAEC68EE7BDDEFE
+:10CF90003078FEA504F2528F1831EF1609FF8C424B
+:10CFA000BF4DAE44E5BC8E9402F47EA366E598F3D3
+:10CFB00023959A79E1BE9A2D5C3652B84442FACA5A
+:10CFC00094BE90173853393D2E9A5D53D72FD6789B
+:10CFD00037BB7E6FD434BFAFF51B6F7E2B5D7937C7
+:10CFE000A51FE1C43ACB4BB17301BD8F33FFBDD751
+:10CFF00040D793C2BF0FF2DCB3210E2098FF5BBD78
+:10D0000026ED20E0FB2F2E76FEA25F90EAF01E9028
+:10D01000954B77C3B988B3AB1239486DA8787C4576
+:10D0200059D7D2EAE8FEE7734A7DB83F472645590B
+:10D03000E72F2AFECFAA6A0EFD08C27BB3B4F77CA5
+:10D04000FC73447D64FFEFBBE2B1FE6C8CF3975F31
+:10D0500057FAAFAE1ABB3FA94D510E618853B5DFE9
+:10D060009F8FF095220F8B5DFE3E176DFF1AE7FF35
+:10D07000D2C7818F263B90EF094F7261FF7F040E6C
+:10D08000EFC5731B97EB18DD23E16AE0BD3416BCD6
+:10D0900058F455E7A58E57427C18DF914A223E315D
+:10D0A0001BC737C279B6BBE793008ECF4B884FF2D0
+:10D0B0009B34AECB0DF3C7798358871FCE2870FA07
+:10D0C000FF7BFE1280D37FC620EEC88D8D772CBDEE
+:10D0D000F0A6C23F4EA37F079C2F20EBB9A8F27D9C
+:10D0E000CE65C576BB5CCC3F24BC3F0BC699B8DF90
+:10D0F0006F9228DC7B94F36784F8B3966BC6DFA548
+:10D10000CC3BB29FD3C8F6C9C9EB4C0FF5763F9222
+:10D11000154D8E5E51FCE65DAE42DD39DF2ADFA3A0
+:10D1200026D003554B979B2407D44B8CEF143C7AA5
+:10D13000057F56B1234CA798FA47A14FFF397F339B
+:10D140009CFB59DFC0E139E3A2ED8CFFD66F3F6A4B
+:10D15000A8A3CF838A1C2E57E450ED6F4F6772D37C
+:10D16000DB6DCB06FC7BB5E730281EF73F43307FF5
+:10D170006748FFE21E99276490234ABEEFC65DB060
+:10D18000EF30A8EC8FE5D0FA26C0B782E1BB7EFB7A
+:10D19000728CF72756B278BF5F20781EE8CDDBE3AC
+:10D1A000823B0086C57BF4315ABEF4E704D2E10924
+:10D1B000F3C75342682AF0474AB3EFE3BE28EBEDCA
+:10D1C00056F0FD8383EDE7C5A28BAACFD5762B78E9
+:10D1D000C914ADFDCA4ABD5E53F14F3687DE2551F5
+:10D1E000F2EA23FC181CDBEEBDAAE8E95722E2A60E
+:10D1F000AA73D1E397D274C6C7BDC1F2CD78BE5928
+:10D20000364B789658C1C729AF467ADE5842442833
+:10D21000DF6D96BE0CF8DD53658CD0C34184B37EC0
+:10D22000A95D37AFA7BA7F3A15BE43CACB67FAF7F5
+:10D23000BD42079E0B7F880404D85FAA26F23C9467
+:10D240004B229980BFCF2AF453F13B4BBC71334042
+:10D250005F3444B79FBE742627677DF357A1DD6D09
+:10D2600031E2B9848B55C9CB200F2EFB4C1E38E61A
+:10D2700074B16565DC839A7555ED9EEADF9CF3CF4A
+:10D280001FD37EADF2E9D7AB57E8C47D40B99C040B
+:10D290000E513E9BF4A5CB7B67D2F299A001EF190A
+:10D2A000C23F2C67A8E7E0099F4AD75DA91A320C54
+:10D2B000627BF90B6C5EEBAA830B606BECBE673A8A
+:10D2C000F7CDA4E587D2993FB0C33EEF7690D75F04
+:10D2D000358C632F23F869E27E9BAE5C7A8E08D092
+:10D2E000DFBF2DBA7DF88F0CBB72AEC8930DEBB0CB
+:10D2F0006E7BF476F64C07DB27FC8BB1265AFCBD1F
+:10D300003B83C9C9FA1A2EAA3EDF9D11C7EA6BA357
+:10D31000C3BFDBADE22166C3BAAC8F81EF1237B376
+:10D32000676FB5AE5E07FAE08A41AFA7E7BA195F4B
+:10D33000B8DD6CFF7BA8FBA5D654E0879D9C08E771
+:10D34000C92E257A2603FF6D68B988F17EA2D2DE48
+:10D3500098E6DB974EDBDF7BEEF913D0BEBF9A7801
+:10D360003829B61DE84A57ED80FA1DB46A0F3BAD67
+:10D37000608FE07F619F15B6FA139260DDE547F09C
+:10D380007C4CB74D64DF3D796668FDEB1E45CF0CE4
+:10D39000F5BCBFF5BEAF46EF1745FA7F4382B4B781
+:10D3A000848E3B44F9AD89CE875C7FEA56ADBD5192
+:10D3B000E521D6B837EB070EF5BC3F3F70BC799E30
+:10D3C0004ACFBD293FF0BDCAA7F6954830CFCE5B06
+:10D3D000A3E95B552FBFA1E8C5487E19D1378A3E26
+:10D3E000B9121C1BAF8F3EA3C7675D408F8F2A1FEA
+:10D3F0005782CD36B8478B8E3E15D659F54B49C569
+:10D400008C9BBA1F24169E57143C7FD560E451EFC5
+:10D41000F57098A7FE55C353F1D1FCFCC8F90F195C
+:10D42000283F007F7C9947FD5350B3E158AA14E68A
+:10D43000C7F714F87F2D1FAAFA55B52791FDFF51A4
+:10D44000F94EB567E3F19D33461E7277BA05FB6F5F
+:10D45000E04501F69176A74BAC4CC4852EF05F6792
+:10D46000B1F3EFD4EE65C33D1243DD36FCFE4BEE67
+:10D4700030070BE83A5EE99E3359BB8ED3DC8A5EF7
+:10D48000AD4DDC095BD7570C9E4569B07E2BD87D2E
+:10D490001E67CF252D4CA3FD9F1A30C08D5864DD2B
+:10D4A000B60D4698DF6DEE446697B79F46BFEFFD19
+:10D4B000F2F5FA80DE9E3F9DAE9E3F657EF8DDD49C
+:10D4C0002F80F384B1E890E3B660FBFB6A0EA33EC5
+:10D4D0007D603B87FA54724BF8FE013E887A99B41E
+:10D4E00030FF9958283DA85EBA0893007A7C8E6375
+:10D4F000E7BC799FA0BD6FE3C13DAB17C0F9CB4836
+:10D50000F9F88EA2C73FEF3628FADCBFC88DF1A12B
+:10D510008F0378973EC9F05DBFFD513CA7FC7ABAF6
+:10D52000E25F2BF2F9BAB24EEAFC9295F99DB70D83
+:10D530006F037B41E5C680E74C5E33225E435FFBB1
+:10D540006600DA89531C18EFA31F4BCBBDCBE282D8
+:10D550004D9ABC9DEAD7E479983C54F15E9D5FF802
+:10D56000903B57E7A747FA1BFF670FD8B3C3FDF7F8
+:10D57000B5075DEE0FC71E04D219BF47DA85113912
+:10D58000DEC9E4F8E2B9DF2D8072A41C7F5D91FF53
+:10D59000BF567EAF74DF8B7C2D2F2662812E3ECA54
+:10D5A0000A421C3CC2FFE1388983736E4F75FF6CE1
+:10D5B0002AE4BB2EEE5DBD2EDAF87B33989FB531A1
+:10D5C0005E32E07D90AF313E8BD41391FD46E42274
+:10D5D000469EB16AC56C8C0FCFAE98930DDFBF45E8
+:10D5E000C607A3DA73DE9455101F3729F1F13E7395
+:10D5F0004D77147C93143F352F7FF804D0FBBD5A30
+:10D600000EBF1F863FAD9F7EEF39CF8F06A5D1F8A5
+:10D610008E94D5F8643B1B2F729CCBEE88F844A601
+:10D62000F109A5F36095311ECEB3AAF1C9A0FCE1C2
+:10D63000C6276F92E17F9909EBDC131D2F3E43E172
+:10D640006BC1BF6F36C56368B1D12383BC18683F17
+:10D650004D5C12D9EF9AC2876F6E7F9FFAE89C3EAD
+:10D66000AF1C4BDE46F0FA2BE5AD5718CE02B97F62
+:10D67000F3E0F50B8FC17C0EDAF0BEB1483807330A
+:10D680008C4A7C60433950ED6FBFD059FF12EDF7E3
+:10D69000E65D6ECF0EA2910B42E582BE3FFF172AD8
+:10D6A000171ED46F28C7BDDDF69A6871CA0F143EE5
+:10D6B0008BCCDB88DDDF08405CEC251E9336EFF475
+:10D6C000BAB2EEAF2A7A292F83D9CF7BAA960B90D4
+:10D6D0002F7A70245F4430B810A7641E84F8F215C6
+:10D6E000E57B0179631CCA5D241EB729741D2F7F59
+:10D6F000B0A65A1FD7DF53A5D71F6F07F346EC48D4
+:10D70000C118FB522AFFC61AEF66ED476FF0FDED18
+:10D710000B8C37BFBA8CDC9BDA17584502B7639E77
+:10D7200083AE0F3CAB4860EA4B149FB79F59897991
+:10D73000F45709A9443FFEFAC7A66AFD927B95F506
+:10D740007EAFEA637701BBBC2E04A646B33F917956
+:10D750009A5783D1CF67F814BDFABAFA5DC53DC6B2
+:10D76000A8EBBB5959DFD7ABC7969BC8BC4DD55268
+:10D77000FDBC3F95212A709A6D7E1657B371BFC0CC
+:10D78000C605BBA5F54B3FF521C9EB20E4EF619C35
+:10D79000ED84403EA55790A768CF5FC565323AE457
+:10D7A000158EBD1FF58A4257B55DA49FF513B7A42A
+:10D7B0003B3754B5548FD76746FC4111F320436083
+:10D7C0002F9D617B79B7D9F330F001714858FFBCC8
+:10D7D000B2DEF7D6FCD604F3A7FAB315F2A1F2191C
+:10D7E0008308FAB3F45CD0A4A5CB6B3719DFBFA6CE
+:10D7F000F80BE3E9D1BCC261D46FEF051DF89DC4FD
+:10D800009B9FF993291ADCAA6B19BAF3C4EB7DD15B
+:10D81000F32AB60CB6DF158BCEB60C49E7A7AEBF20
+:10D82000968DE78363F9FF9FCD6071D07D35075BEF
+:10D83000B5FEFF530A9C07547DC633BF3F56FEF525
+:10D84000A71937977F55EDB3DA2E72FDD567A4BDC2
+:10D850001C54E439B2DDBF65DC1CDF8DF83131F8D2
+:10D860002ED6B86AFCA1E67DF38A68FF28FB32A3B6
+:10D87000C651DA458EF3AF197AFE1E1547C4C8DBD0
+:10D880005933991CFB63E4EDAC9971587F8630BB2A
+:10D890002807ED68C7AEF43CB00FDCBD87167DFCF1
+:10D8A0002498B78F2AF99AEA9AD327204E55E38A0B
+:10D8B000B03FEE6F867DB2A11D1CFA1B91E344FAC6
+:10D8C000E51F853D269047257F5068F4629E9A7C2F
+:10D8D0009A9DF37736AC46FF52CD4FF70ABE1D71C5
+:10D8E000F4FDC4EDBFDD06F6558DE32F993C0FB373
+:10D8F0003C33F377CF773BF07BD7DA1179F760BE13
+:10D900007144FE95FCE378EB31A26F62ACC778FA04
+:10D9100026565E447D8EECB308E28C97E17C2A1794
+:10D92000EF817B99979B09E67D962FE130CE5C6E67
+:10D93000F6E27ED6E9330603947317E7EE067F63BB
+:10D94000C552A3D74A51F83700359BAAF257AA0B04
+:10D9500000CE5374C210C7F6BF21BE07CF5717C4FD
+:10D9600049E0FF9F9E27353969F9F4624EDC41FB9F
+:10D97000BDBCF401E3545A7E8586CF70EF8CBD8127
+:10D9800028DF7FDCB26C7E3E21DF00B89AEF3F5E7D
+:10D99000216AFD3DFB2A281F4D49E937382849BF38
+:10D9A00075E09E7D160ABFB5C9E782EFF2EECFBCE7
+:10D9B000751F7C0F999AEA1DB883FA519D999E654F
+:10D9C000F09D5EFF175478C5FBE03BBC1F18FCB907
+:10D9D0001CAD7F2173D1321EF62326A8F0ABB17E99
+:10D9E000D5C2750FF6D3FA0B07EA97C119F6D26ABA
+:10D9F000A5BFFCB165F3794AEFB96AFB8678283B8D
+:10DA0000ED24BCCF348B1053F83B3F3CF7DE3F7224
+:10DA10008E7CFBB20ADAF7D5B2C07CF89ED3F3A5B0
+:10DA20001DFB8AAC84CCAC2C13BD743EA5595F5849
+:10DA300066877521941F69FD47B20E2C83F9388DD6
+:10DA40000605FE9710BFD26A790AD47372705F65BB
+:10DA5000227C97307812D8724B43A72555F77D4228
+:10DA6000C00BAE8970A42C9481E828FBDA99A1A997
+:10DA7000ECBB3BA55CC8F2142365172BF7EF88FEBF
+:10DA80007DC57F6531FDD56F8B5EDF91A9DFDF4EF0
+:10DA90003847BCCF4591FF8F29797F559E4E403E38
+:10DAA000C48957CC059A601FD6C2F08CB58FDBAE07
+:10DAB000E897FCA604BC976869C08EF7E84CF03084
+:10DAC0007D43A5885F09FADF68403C538C1CDE6B00
+:10DAD000926A23FEC3F49992CCEE39594AE517EEC7
+:10DAE0001F5930C1D783E77CD3D28B9BE19C5DD398
+:10DAF0002F79F0C3D4FEA3F1141F053C538C2B8A5D
+:10DB00001F2DD2D0AF88E14DD75DE9E7FDE61D209E
+:10DB1000170353F2C0AFBE3D536FEF4A07CA4DB073
+:10DB20003FF9AB2C250F26B1FE29F3995E197E54DF
+:10DB3000B9B7C2E229D6E5F5153ACF6F5BFA34B42E
+:10DB4000AB1D3011388FB8ED7099EE7EF5C8672D9A
+:10DB50009C7BD7D8ED5A3E84E7CD6BE1DCFB74802B
+:10DB6000F77301CE39021C880FE0FB0EF09B529A2E
+:10DB7000A3AFB79A57AEBD9648E4E9DAF78C5E6179
+:10DB8000F84EAC1F6F5E6178FAEFF946C353BEEBF7
+:10DB900053E9CE2B7417A2E3F933952F29BDB5BFF6
+:10DBA000AB52554D94F313EC1EDFF3CB8ABAB5F7A5
+:10DBB0001610B2839DEBE0E93A823F3960C3FB80E7
+:10DBC0004B79AA1F9D002F4994B9D17CA1AE6B7FE0
+:10DBD0005200EF231ABE8B13BBA3F8D967143E2E55
+:10DBE0005DCAF836ADDA6FDCA0E17795FFC3F007C8
+:10DBF0003EA3CAC73A94DBBD0C3FF037800F3DA16E
+:10DC0000A9DA73202AFE659904E74FD791D1FF2E38
+:10DC100047B09B0BD36D34FD33C659CF6CAC2F1D71
+:10DC2000382600BFD5C690D3B359F1386EDAB95053
+:10DC30003C9C0F58A0F07F7FDF74EB1C908BA506F7
+:10DC4000C2496CDEE06796CE55F5E73BBF28A7F6E4
+:10DC5000206DA44CF5AB04EB30A26F43164BB8FD1E
+:10DC6000C9AC7796B5803E36B3EFBCA9FF68219A60
+:10DC7000EF11B92C96BF9DE58FBE6FFD4616F34799
+:10DC8000547A7FBE613E798BCEEFAE4C66BF670D96
+:10DC9000CA785F922AD7917A29278BAD634616E31B
+:10DCA000B3BFBD5EE2C6D14BCB15BDC4EA89D35725
+:10DCB0000BF5A906E5FB0491ADFBC69F4C2F803CFC
+:10DCC000DC56975182EF1D56729EAC6FD171AA2C13
+:10DCD000526B9C14E68F2A62911C406F3A027CFFC3
+:10DCE000BA62A915CBF0077EC7EF3A39C67F444A1E
+:10DCF000A81AC3AF55F1D9EA1270BC8DBB0A12FC49
+:10DD00005A3C79DF7398DFB32B785A22EC15AF2F8A
+:10DD1000A7A686EA0C464DBD83D9AF1697774E1657
+:10DD20002D9F56F242A43659E717AD52E42ED22F5A
+:10DD3000FAAD8B287A6205C68F69347E847B02D265
+:10DD4000FA7C781E0C2E322AC0EF76D97DC6970E4B
+:10DD500093B91027A9707C59453AFD5EBD1A364D1E
+:10DD6000A8705AE67B2F6BF4D929E53E7ACA0F33A7
+:10DD7000405E9767117D3FA32F13BE2F2769660F63
+:10DD8000E89B1382EF00AEAF4812617D17181F3D6C
+:10DD9000807C612489CD784EEA20F6AFAC1E2E41FE
+:10DDA0003FF5BA310476E797D9E998CF49B133BE48
+:10DDB0003D610D603F9E4849A84714BDF7CBECC9B3
+:10DDC000780F86AA3FC3DFB5A87058FD096E792683
+:10DDD000DC0B7B2265527133A7F777C0FF09FB4B41
+:10DDE000DFDF77673EF8377D218A33D52A2F2E7BF8
+:10DDF0008CB6DF9C25317ECDF5F5C3B82712890896
+:10DE0000F8CF1AF43F07E5452E3BDEDBA6AE47AA66
+:10DE100081FD1E4CAAF27B2B2027F0B4653339EB31
+:10DE2000529E83D96C3D53E3A3FF7ECCB0D26EBF2C
+:10DE30008DD1B9A34C7F7F92FADCA9C8719DA5B39F
+:10DE4000123EA9D77CEF89DF87F384FA551C7C4FFB
+:10DE500042F03DB56748AFF96DD5F8FB61EF0DAC09
+:10DE6000C27B5C477ED703EEABA2EB1E222B9F004A
+:10DE7000BA0BAF1AF16EBD56133B772724FA45F85B
+:10DE80001E29D91E3DDEFD96824FB291DDCFAD7EBB
+:10DE9000C76052BEEBFF8AE28FC5BBAAD83D45944E
+:10DEA0008612A55F0219C6EF74D5758C3C976B522C
+:10DEB000BEE77FFFFE43710CFFA144E73FA8E346A6
+:10DEC000FA1117E0FE6D4DBE7B9DEBEC02A2697F5F
+:10DED0003F196C0578F76FCBD0E52562F91FC715A0
+:10DEE0007D0BFE821C152F41F7FE028D0365EDF8B8
+:10DEF00057D8F8E171ED44D68CDB96E57D390BFD02
+:10DF0000D4B922DE234C7D76380F4BED0EB3D77398
+:10DF1000D9FD84D42E5582FE56E322907B3101E454
+:10DF2000BAECE759291A3BA9F48BD447772AFAE8C7
+:10DF30004EC5DE249C53FD469BC47161BB33DA6E33
+:10DF4000718A1F1DA91F23ED82DEAFA67C2B6BFDFE
+:10DF50008051F292F541FDCB0931F863E2DFC5BF94
+:10DF60002C9DEBC7F892547204F6416656E8ED3DDD
+:10DF70009FEDC079F1D9769DBD5F51AD6F6751DAE4
+:10DF8000599476E3D1536B8F3823E83D06AF9E63F7
+:10DF9000FC90FBCE19BC4FA9229BF943B7E4781340
+:10DFA000B269FB837F9EDF0BBF3B31DCC4936E27DE
+:10DFB000F4F3F60E3A615E1611E2D4B2B515850798
+:10DFC00069BDE9E7260FC4CBE448F4F8DED1C07997
+:10DFD000375196CA54F460AD93CDABD61912F229DD
+:10DFE0001EEE5A864F66DF518ED7E8BDCC1AD66E2C
+:10DFF00062B649677FA628E5C26C252E21C126F8A6
+:10E00000FD93CC1A2F0FF6CEDDC711E59E4DBC1F38
+:10E01000D5ED61F01D9E20F7405178DEED86E54597
+:10E02000602FDA53ED1EB0175B72FC9E6C90D7F335
+:10E03000A110906DE6F9011EFCBE5D39DE62A0877D
+:10E040003A3FC928BA617FDC7E9EE1D719C1FF84BF
+:10E05000EC56D6A59BE1E7F015033EA9F112DE4789
+:10E0600044FFF2C0AEA62629762395F8E1DE2062B1
+:10E07000A1EDC00FB2D176DAEF3789AF04F609828D
+:10E080002953A7819D5B60F31CB3807D9D963B0D5A
+:10E09000EE177AE940F47CFA32C5AE50FC1769F10C
+:10E0A0008F251F23F7AB2BED4C31E26895EFED95F3
+:10E0B000D1FD556A09985FBFD6792FCCA7B6452008
+:10E0C000708F844AF75D39BE6AC0C7DD77900379E7
+:10E0D00075F795215FB9659E805FD162CB0EC2BD99
+:10E0E000B12D491F4903FAC7C2BBB6C1E8DDA495EB
+:10E0F000E71601D7E360C4F93535CEF87836F3B3C7
+:10E100004339BE5A58E7FA234FE239C1877B2E0ABA
+:10E1100063DDEF73B374E36A58FC52BB86DD9B5139
+:10E12000B696473EDCDC22E0BDACB5CF1D0EE17EED
+:10E13000F17682FBA0B57D874FC2BDAC19B5DE1963
+:10E14000DADF21C8A865F7C7A5521E192842BD29E4
+:10E1500080DD76F72DAF45BE168948908FFCE877B5
+:10E16000655A983FAAD2F7A410CA7E99B63B692097
+:10E170009E665A7FD52417C24F345DCDB579E01E17
+:10E18000867F3EFCBAF469A033E4C55CB01EFE276E
+:10E19000811E1D4DEC3C79C702EAF7D0760BEC648A
+:10E1A0002B9417343B08C8C7CDD26166045FCCDC22
+:10E1B000CEE4E4B8A25FE81FDEABF4CD6C16D7A4C2
+:10E1C0001AFCD5E8BFD279B4CD46BC701EB66C6FD0
+:10E1D00010F02262128EEBAE0D71DAEF50D4679818
+:10E1E000AFBC5FCB4E793F78F6E13EE36645CF9416
+:10E1F000ADEDE1DED2F0C1F7B2D97EA9FBB9831C47
+:10E20000C487B4BE698113DB637ED0FD1C8B9B3653
+:10E21000D3FA07757A6503CEA7DDC6FC47AA577EF9
+:10E2200008FC7EC2F0E871D82F39318DE07DB377DC
+:10E230009D0F9D44F5ACE07B4260EBC9533A34D16D
+:10E24000F2A96CE6DF9D14FC9B60DD4FBAD977DE46
+:10E25000ED861D78EFA92AF791727A4AE173F79A51
+:10E260001ECE50847940F42755FCD476B7E494FF51
+:10E270003C1BE9308074A85BC3B37C8382CF02C1AE
+:10E28000970F71DA1B0ABC63ABBF6D7C86E25757F0
+:10E29000C4213FEF7FE134F2655D27C77E27A8F3F5
+:10E2A000B4B04A135F757DEF34DA9525FD6CFFA598
+:10E2B000AEFF30FF8003ECCD31E4CF3ACA7FD612F7
+:10E2C000583709E97CD514CA067B19C99FF64AA6B6
+:10E2D0001721E75AC0EE83C3FDDFE05A0BFAFDAA0F
+:10E2E000FEB5652BBF5BE9F0E7827E7D5729ABF079
+:10E2F000C3F1AAD503FC9DFBCEB46370BF5B9D87C1
+:10E30000F3C079E4E1117BC2F4B544D915F4B50A40
+:10E310003F927EAE1C66CFA2D891FF8A6647543BDF
+:10E320009BFBE572FCDD3775FD7885EE23F63D87B6
+:10E33000ED4B597278051FAF0BF2D81295E78E128C
+:10E34000B8DFCF57043FA1D69262F7407EE79F1314
+:10E350005F933668E87552A0F24ECB27F36C880FB6
+:10E36000950B6B8E66FD6A8BD8EF4AEDFFEE72A4BB
+:10E370006B2DAC1DA56BAD7FD326A4B38B888740D6
+:10E38000BFF899FEAA5D730FBB075CB57FCF7348DA
+:10E39000FF5AD981F75A2FE95B8EFC499C564F01F1
+:10E3A000877A0DD7599533DB085DD9FD4334AE6FBD
+:10E3B000827C891AD7C757FBE43869B49C262B7135
+:10E3C000FD0C25AE37CDB27CA871FDE6869F61FCC1
+:10E3D000F388EB27F854E584C68D3A799AA1ACB35B
+:10E3E0003B87D9D3B9394C2E3797F421FF6FBE1C28
+:10E3F00040F97154323DE238AFD77F6A1E8C903DB0
+:10E400008C0FED7D0B611F62C1573811F4402CBC9D
+:10E410003FCA057E01E755C861768EE28EEBBF8C60
+:10E42000D7DE47BA3487F1F7D55E230901BDF980FD
+:10E430003096FF1B0B5E56A862F6BFD3F5FB756FD7
+:10E44000029E0BBAFADCCA4F4259EE49C0732459F6
+:10E45000A12AE48BABCED91EE0036733A3D3D5BE8C
+:10E46000F9C83FEFA44906B82FACA9EFA979F0FB92
+:10E47000D01B15BCDEF9AEB101E8B0E3EBDF9907C4
+:10E48000F74B6E0E72C9F0BDD9D5DEAFFC05EC5E60
+:10E490004DCF163CF7D5FCCD7F42BFDB103CC8DE2C
+:10E4A000F72688D06EE8AB4FCE03FA36F73563FD1A
+:10E4B0003B5F3D88E5635FFF8EF19992301FBFF3AC
+:10E4C000DD833FFE6F28FBE2F1BB9C5AFFFEC7A134
+:10E4D0004CAAE2D97757FE9705EDEF75751D3E8A78
+:10E4E00072A8F2C5923E4EB93F4CC0731E2AFF5E21
+:10E4F0002A2F2A05B9831B768DF368B923AE265AD5
+:10E500001E71A732DF5AE04518770D1704396817D6
+:10E51000E45ED4E7625F36E8737B5148807B5756F0
+:10E52000571F9EC77E76B009EB575AD879B1A954C8
+:10E530005EE01E290AADE706F56B56B63FBC0EE05D
+:10E540001D3012D1981EC6B75E90303EAA5FC179C9
+:10E55000A884118E6C3B9102FB5F0D4439D7C5DA5C
+:10E56000B5D3F0D29284768858E9B3745BF43CE872
+:10E57000BE1C87229F4C5EDDFDCB33417F10A7D9A7
+:10E5800053901B8697752ED001D7F9BB6B0616C228
+:10E590003C16176E980EF37042BE0FEC8BEC40F8F1
+:10E5A00075909FA4F21454E42655F4E17D2316AF30
+:10E5B0002F057E834D32FB703F4F5AEF3335819EDE
+:10E5C000E187B357A1213CA4CB7B7599FCE93300CB
+:10E5D0005EBB629F7A18FEB43FC293E67B9DD09FDC
+:10E5E000C24778966A2F8FBFF16661EBF09F3FBA02
+:10E5F000F3903E5F1E1C05BFC401F6455E83EB260B
+:10E600000938DF77A029D25BBE559BC78ECCF78037
+:10E610003E83FDDE504ED90F7266849F6A1E28929B
+:10E62000CE7F817AD01F92179FA437F9A67E0F5014
+:10E63000D5DBF57B14BBFB838BA877EAFD3CB3BB32
+:10E64000FECB68777FDDE8256F51C7B2EBC58BC87D
+:10E65000DF0F1C6176B7FE48B100FCACDE8B5C5F5F
+:10E660007E15EDAF6C24C8D7F542DF4917C0EF2007
+:10E6700089D4B327F5F3062782FEFBCD8BD635D0A0
+:10E68000FF84C180FC76A2FB9683CD9C163F1607C3
+:10E6900070354194C77AC52F285BBBE94988C7EA22
+:10E6A0006A08C685F5FD8A7CD1780CE85B7FE43486
+:10E6B000F28FEAF7E67E7905F25B22E537FC9D846E
+:10E6C0008A01C48FFE790AE833B182DD8FBBB8B00E
+:10E6D000B814F8EDD8EA1FEF04BB5D5F414480DF5A
+:10E6E00095E57D11EF017E91C37B29BB4C9DE5F043
+:10E6F0009D64D7024904F9A8F7578DD8273C5FEDF0
+:10E70000AFEA47F971AEF380FFD0D1E447BFBA2337
+:10E71000DD8E7E41D78B4D683FEB259B077EBF6426
+:10E72000C9116E2BF6971D84E1CFA19FBF24380736
+:10E73000CF6DA9F458523198CDF405C3FB37A681AB
+:10E74000FB61DEBFF99E19EEFE1EE1BFC48AC00167
+:10E75000B8AF768938CD03F76B26F1037EF077A842
+:10E7600009F634C1FEB0C967F640DCBD97C37DA889
+:10E77000FF076B233BDE0080000000001F8B0800BA
+:10E7800000000000000BDD7D0B7854D5D5E83E730A
+:10E79000CE3C924C26274F1208F14C123040124EBC
+:10E7A00020BC114F88416CA90ECA2354C4E11D201E
+:10E7B000242362C55F6F33381023BFD71BAB156AA4
+:10E7C000A91DF0516A45A38D354AE01F10107BD575
+:10E7D000466B11FDD18E4A798964E451E957AA77D5
+:10E7E000ADB5CF49E64C263C5A7B3FBF1F3FD9EC25
+:10E7F000B3DF6BAFF75E7B4FEA64A6058B192B780E
+:10E8000040D0824EC6EC8AC05826A6163DB5313699
+:10E8100082C19F669ECAFE524F09635F3468ECB3A3
+:10E82000018CFE28598C2DA37F30B67C41C8A640B0
+:10E830007FB5CFF2FE32EC5AD9ED907E837FAE8663
+:10E840007C25BBD503E599A270EB544A2D941AE5BB
+:10E85000465AACCFC3FDF8BC87AA3218FB5E0D53F5
+:10E86000136088BE45F01DF2CCC78203DC90AFF187
+:10E87000E42A589EB15815219F99CE7E88E591D5FE
+:10E8800036B659E8D9AF8AEB1A81F53CE502D4CB0C
+:10E89000EC93AC067028B1C29280EDCA0475B382C5
+:10E8A000F91B9F64E590CFCC51B11FC6823A1C3C46
+:10E8B000E516A877342B595D87DF837F906E047847
+:10E8C0008C5764A3BC0CDB292EC6D69575B7AB2A32
+:10E8D000F0507F557D12D400CC734AB3BF94E573DA
+:10E8E00038789CDD7008AE4EAC0E46C16324C20180
+:10E8F000DA0707B1EA966284BFA716FBC9B2A8E996
+:10E90000EB5221EFF497DE948CE304085E57E03C71
+:10E9100020AD82F5F9B0DF02CF4A824766B21A0F06
+:10E920001EA12B383C76CD7C4EDC00F5EA8A85A012
+:10E930001DE6F7C8B6A965B8CEBA694E9541BECEF8
+:10E940002BCDC37199DFC19E823CF32E78A80AF2C9
+:10E9500075351E759D42EB5E80E5B91909EA3A28C6
+:10E960007FF41541C37C9DDF194C80FCF7DB383EFA
+:10E97000D4B5BD20CD873409F1CE89EDFCA5534B2C
+:10E98000BAE7C3D86A9A4FDDC41379BBA1BD5F64EF
+:10E99000AA3801F2B6F04015D65F37213C10E17578
+:10E9A000F295846A6CBFC762F1E3387B360FD914E5
+:10E9B000107AF673D2EA69C5F59F84F5FBA1FCF5E0
+:10E9C00057DE0FDE0DF935800A6236ECD16AA502FA
+:10E9D000CBD7553119F7C5D8AFBD367F11E2D5DE9B
+:10E9E000FC44C20F9CA707E07C1CFF99C358FD158F
+:10E9F0009E250ACED3126A94B0DD9674C6C640FE38
+:10EA0000D5FB077A9D3DE10CED695F1C1223FC7577
+:10EA10000493828128BC7238184B1E46A9DF09690D
+:10EA2000D22A0E9FD87EEE519C547FB923BC177614
+:10EA30008ED5AF6A7664011E2D4854E87B82D5A737
+:10EA4000F583F9D8DA2A42FDA03C2B0DFEC27DDB0E
+:10EA50009C14C47DCBCA62DE17E3F45BA7D39BB1E1
+:10EA60002FCD698CF032CBC5EBFF4CA79B07F47A16
+:10EA70009BF5348A2ECC78EFF4BA914F6425326F2F
+:10EA80004B9CF18CF6303F2A37E6C51CD04F06B6BA
+:10EA9000532C84DF317417CC2C1986745795A8EE4B
+:10EAA00072203D0D730F0BB0EE710031DD53937B7F
+:10EAB000E201AE03E907D78574D65BBDE69D9C3FB6
+:10EAC000C5E2E5B33A9D2C425C87793F27003DC6FD
+:10EAD000DD67DE4F93C56D7914E6FB9FFBC5E066ED
+:10EAE00077CF7A46FA6003D0A09DB1FC8DB3523C3B
+:10EAF00025BDD7DB89F5AE84711B1C54DFA92AAB79
+:10EB000025E87FA2C35D26321C4F9988E3F9613C5A
+:10EB1000DCE7E409EC4B11E053DAD65C74AF1BF18F
+:10EB2000BCA51AD7355192A532E40B1E0B0B1571FB
+:10EB3000FEFD0DFCDFA73A91851CDDF91C6F9A29BB
+:10EB4000DFAFA6AFA97E7F5FBEA9FC8A55834DE5E6
+:10EB50006EFF3053BEA069ACA9FE80E689A6FC9585
+:10EB60001BBE67AA3F2878A3293F64CB0F4DF54B06
+:10EB70005AE699CA53BE2ED8F533C4735C7F1C3E47
+:10EB800067A4C71537EDCF444934F537B4CDBC7E03
+:10EB900089852D48EF29138E0E8B47CF465ACAA47C
+:10EBA0003361A31DF20187627914E6E17A5F0CAE4E
+:10EBB0008BB3EF063E1BF994D1E67D30F8C4C5F067
+:10EBC0002BDF7B617C31F0AAB7F294AFC5B87499A2
+:10EBD000E8E67429310FE3EBAF562FB47E6BECFA05
+:10EBE000994278FFAFAE3FDF3BA82D0CFD9CAD16E0
+:10EBF00048BEBC8745637AF6F751CC3A67AC4C21E6
+:10EC00007D86796E8A5BBF7B1EF7D23C6EB1335F27
+:10EC10003C384C7273B93BCFCDE9FD62F4F9893EC3
+:10EC20008F3F1BF4B9C64DF4C8DE138303A0AB7944
+:10EC30004DC2CE3E8017695EA72AAA909742AC2C9F
+:10EC40004ACE3FA2D3F7A3D81ED20D0D32F5F3580A
+:10EC50004336A51B1B14FAFE784311A5C10695BEC9
+:10EC60006F6E184DE993A08F61FA74C3644AB7348C
+:10EC700078A8DE330DD5943EDBE0A5EFC6FEDCA21E
+:10EC8000EF0FF3A4933C8B5DCF9C9566FA30F6852D
+:10EC900089C5D47E0ED0997801BED6A3BD383BE598
+:10ECA0004278B4EAA0FBF9DD517830DD9D9C7178A3
+:10ECB00008FC63141BF58D78F1F65F3528CFEFB6AD
+:10ECC0005E9C2E0C7C61E73F1B10AFDE2D49503659
+:10ECD00016F893FB97CD7E67EFF0E9C6A3187CF595
+:10ECE00000BEC2D75294ED39581EEE1B3DCE9FF4A4
+:10ECF0007D36F2D3A6717C8DEDF7419D0EA7237E64
+:10ED000042F98C187AFD422FFFC2CDF5F4FDBDF01B
+:10ED10008B46B745979F7CDFA7033EA2FCBC3769B3
+:10ED2000CE55DE38E3FEDDAD98E873C634F33EEE33
+:10ED3000B772FEB6FF4F6270759CFDBF587B633D96
+:10ED4000B1EDFEA0AFE773C4C911FF73E86DFFAC6E
+:10ED500064D2E7F75BBDFD33A3F667FFACA4EA78A6
+:10ED6000FB7EC66DE57456243394EF2C8D69A8079D
+:10ED7000C192FC36D4E558A17C18E9048C21A48BFF
+:10ED8000DEF15262870D7A12119E09A48F9F9D9623
+:10ED90004CFBCFBCB2C6A2FA67924C7AE9733F0033
+:10EDA0005D01C793603CD043996AE9DEBF7CFC3BC0
+:10EDB000B19B5F8BBDD3DBC5F0C0E02333908F5C8C
+:10EDC000405EF76C77797CE4E37F131F31E8989D10
+:10EDD0009F3FC093DCB37C3AF291BE8C3DECDE4F9A
+:10EDE0007CE49F869341B7EF73BA8DE527BDB66B80
+:10EDF000CBB888FCD3F9B9E46B0A035EDC2926376B
+:10EE0000AF8326F749BE5F62DEEF97D85390DA579B
+:10EE10009DEE7B6838755B2451BDC164DFD925DF69
+:10EE2000AFC2640FDA65ACB73EE9C7CF637E157039
+:10EE30004C3BA45F25E40519D80243F2397F121D2B
+:10EE4000E7FA1E8A9A9F5566FDA2F3652147BF43E4
+:10EE500051FB367C9F6CCA8FE8C836D51F75403190
+:10EE6000958F091799CAC71D554DF9AB22A34DF5CA
+:10EE7000AF3EA799F215EC3A53FD4AC75453BE4A28
+:10EE80009E65AA7F6DF65C53F975CA1253F9D84294
+:10EE90004F493EEA0F36679390C2D812B7569A0F81
+:10EEA00070484CACF3CD453B69B54B6613B076303A
+:10EEB00088706BB439E475C0A73E15B43C0678FA87
+:10EEC000B005ACEE02A82F8619A6072D6A19A6F97F
+:10EED000DA162FD269E9A04405F1217120631D28BB
+:10EEE000A7243581013FB12585DF2D44BADE06FB1D
+:10EEF00007A8559A0A8A3EDA013F480BA2FD9B9368
+:10EF0000E8ADC479ADB334BB56E33E5B98E729ACBA
+:10EF1000CFD4FB47437AF87A8B05F7B7B5C3F9C06E
+:10EF200058C80F85EE19A59FFDE4FBB8DF1DA28A26
+:10EF30006E9F87A7BC3809BFAFBC8E896259EF7836
+:10EF4000F6F98FB83D15FB7D7D3ED7AF322BB99DCD
+:10EF5000195B7E875EFEB92D7EF9C27C2E2F2AEFCB
+:10EF60009BB21ED767EDB032F45BACCCD4FAB00BD9
+:10EF7000E9ABE70A587078545EF230D989DF07D2DE
+:10EF8000F7CAFB66B3B093F7837EAC95095A1FF4BA
+:10EF90003B7C3E31FE3C96EBF3B49E4BEAA55F17FB
+:10EFA0007DFF3CFFC2EBB49E4B60C1F478ED9DF455
+:10EFB0003D3310BF7DA301A7B4F8E5F7EA70B29E18
+:10EFC000CB61FEF4E8769CEF748F934BE5D673A982
+:10EFD000CC1F771D19F49D656BD988373B81CE9185
+:10EFE0005F54A466D91890F81C16D9A301FCA7A2F7
+:10EFF000490078CA1C6A19F22926592361832E40D8
+:10F000007ECC65D2A7682F580019BF81A9DDBACA86
+:10F01000FA69388A8EA66AE63CC3FA51F2E630F6FF
+:10F020000DF34E1C5C9482F87E8A2929721CFC32F6
+:10F03000D2D90ED12345ADE7602F7AD2EF75381DB6
+:10F04000CC890FC7DFE6733D6AE46C16575FFB7D22
+:10F05000BE8BEB81456A9F0BC90D84AF373DBADF8C
+:10F06000D87DC8A0F24B8533E005C9F5C80F9C4197
+:10F07000F2537EEBF036F0A79F092F0E1728FC7B8A
+:10F08000D7BCF3A83C2FD7F3663EC9156520CAC587
+:10F09000569D7E5B252D699813F918AB8907FF8C67
+:10F0A000025D4F8D59772BD3B2E7A25F43B2AA4FCF
+:10F0B00031E487CCF7421CF8C7AEDBA1CF1BDA578F
+:10F0C00087B03D73A99CCF318F230BF47CFC172CA8
+:10F0D000A1C2FF8E15FB9FED73A9EB40053AA9CBAA
+:10F0E000ABB92C6C453EDC037ECE0C2BFA6D63E194
+:10F0F000E861CA1CA1E0E2F0B438E4ACADB0BE39BE
+:10F100007E1743FFCCADB399AB04E6E1FD41DADBFA
+:10F110001AD49977FDE0D235980E19DF2852AB6BDF
+:10F1200048DF13FCFDC46F865CBABED7E8F2162137
+:10F130005D1C129445B47E01D68F72A6EFF18173E7
+:10F14000A3E0B7B87FC5DE02F47B5999968E7EE2C4
+:10F15000ED76F257B10D8CF4CFFA1D8336A19CE900
+:10F160002CF0EEC67AA3AED1FDB65A64E08DC997F5
+:10F170000F27F86345FAB8189CCEE7733A3FE88A40
+:10F180008F2FE5057C9F2E954E320A381C22008772
+:10F19000CDE5DF3E9D00FC4C7C63B78E7F466AC0A8
+:10F1A0006DD464B35F77B7BE8EDD059C7F7416782F
+:10F1B00008CE9DFDBF3C9C8072DF06EB8F83EFD7AE
+:10F1C0005DE6FA7BA3936F8B1F1F4C8C3FCF39DF1B
+:10F1D0009179BE6ECCB334FE3C6FBFCC79C2FE2CAD
+:10F1E00072147CFBF3EC2CD05E2F403994167F9E7A
+:10F1F0003FB9CC7902935B14827A3380FF61BD6F93
+:10F200007BBECC3FB70AE5CF4D5EEEF72F014E8BAC
+:10F210007C08A6F2E437C351AF55D76E40BEB3C2E7
+:10F22000A5FA65E223AF237E031F641ACC67DA6474
+:10F2300081FC489D23BE5C2421BE67B1502AF2ABFD
+:10F240001D76F263C7AEFF67BA9C003AF925C28902
+:10F250004D890C447E7270607C3EF1CBD8FA4D1122
+:10F26000924BEB2AE2EBA5BFD2E975B9A37972966E
+:10F2700025FA5C0516282297F569FD50CE96CB6BD2
+:10F28000909FD8401E215C6DFD06F7C1FD80BC47F4
+:10F2900080B422FBCD03828BE07DA20B7EF9DDE3FF
+:10F2A0001C6FD827175A7BE7E7CBC41747FAE2ACA5
+:10F2B000E7578AF7D582287B71D99637E4C268BFB1
+:10F2C000380B5B18098E08F9AFBBFC057DD865F9D2
+:10F2D0000B0622AE64A27CF0907C40B9817673E389
+:10F2E000AB63CA707341EF6022F2D3E4449217819A
+:10F2F000BE638B9428781EECD21BC45EF4499BE954
+:10F30000FB470D0E3025BBF3B71C7DAF0AF5F8396E
+:10F310002CBC16EBCF599984478F5DEBECEAEF9C40
+:10F3200060D26BBBFB97E87B85C31912C188A970BB
+:10F33000FE3EEE7EFC4AD13EC1F5FDB8BFF629A6E1
+:10F34000B1F0F3DF373E95FC0708BFAB7BEE7B6F78
+:10F35000FB7C5AD14E607FADFD65C39FA3D2395C63
+:10F36000A2712E2CC9871DDDF0BED47D7910FF015E
+:10F37000767D52A1760EFBD758AD0FE733DBA0EFB9
+:10F3800018FD868D4E233F64A3AB63EDCE283ABCB7
+:10F39000D512C9E4723BBC169D4B7FDE9E40FCA398
+:10F3A00073FBEBFDBD748E66E81D49E23749973E5D
+:10F3B0003FC3AF604D8CAF471BE717BBACC585A4FF
+:10F3C00097E0F9EE68C80BCA02B4272599A90198FD
+:10F3D0006FC5B5804DD0DF4431B73D0CEB38CB4E17
+:10F3E000A45D85E0D3FDAA2BDF199180F39C2859F9
+:10F3F0008F47F3A758FF4F5EA1D9FF738ACD4E09FF
+:10F40000215C8AB87FA4F4956B52D00FFAF09489EE
+:10F410007D30DDD9D0244BD66E3F50ECFC2B7AB139
+:10F42000478714727CEF48D48614C2FA2A7A59BFEF
+:10F43000AAD73B94A8A98599DDFD61FD7871106F6D
+:10F440005CA9F37B1DAE37F9E792BE6571005F459D
+:10F45000FE097AAB28A37FB0D04AF4AE3145CE2264
+:10F460007F21DF7FE0EB12E4AFD2F342D307016CE0
+:10F47000B7F176179D7F33AFC2503E0060E83CA0E5
+:10F4800051F091BFC181F11E90AE13D40D22A4A200
+:10F490002592CEE922C8E3199857C2FCEB42388086
+:10F4A000F1016B1C3FFE25FABFB580C41226405EF9
+:10F4B00062E45FF41F4CA6F3389A19CCC36ECC4BB0
+:10F4C000CF27EBF9CEE993260F80F4CEC4C75D8831
+:10F4D000A76101F828F4F355E28F434437BE44D5C1
+:10F4E000DA17FD4A1F535E5891A80AD9E8777215BA
+:10F4F000A19EBA8A25AA7618477396F8715C9BC2BA
+:10F50000C80F9FC85A681D4EE7177E048ACC640155
+:10F51000F33989DEF98564A7303A1F3FFC71F26642
+:10F520005C7F827C2A74377C4A671AD54B8F918F17
+:10F5300099CE9502C56D78A418B9E81510FE7DAA7C
+:10F5400063BF9BE5A5831D94111F859027FB1BE0DE
+:10F550004F1D08B7F26EB87548DC9E33E0E69FE8B1
+:10F56000FB15C2D57FAF5D0E64F4EE6703008D42DC
+:10F570007DBC435EB415EB83C1C42CD85F365F9F5E
+:10F58000BFC6CEF741F26EC5F61F5AB365B4770C0D
+:10F590003C6B1EA8FB217AF1733C58C8F1B02EEDEC
+:10F5A000701DCA3906835AF2C05E4A3E3A12F90605
+:10F5B000C8CB26949709568DE06DC8CDE5ADB7311F
+:10F5C000A4ABBAB6B90CE9F543C13B6037D9238C7B
+:10F5D000ECB19993FD7B2C0AFAB0A6AD75427AB8CE
+:10F5E000309F9F67EC99B487D890E82CC176655717
+:10F5F0007BAA3261DC400953EF857A8104EFD6970C
+:10F60000705DEF882AFAB9EA5755B2CF86EBC80485
+:10F61000DF37CD48277F694665A411E30422F7331D
+:10F6200019E37A7AD0C77958DF48C69EA0B1A09F67
+:10F63000057208F12707F04D90BBCB9FC4F2029EE4
+:10F64000BF1AF2F57C4B59417BC50D23B85F8CA1E5
+:10F650005FACBE5D207F5BC1B4E1A4D71462794684
+:10F660007479EAB267215F587D958AE4A458BCBFDB
+:10F67000B803CBDF66B40EA6F3EF5131F43BAE9B7B
+:10F680006EA8BCAC2BEFABC4F9EEB98D91FD5AAFAF
+:10F69000CB5B13BDE162A14C1B89F8D7D50FC37EAC
+:10F6A0002AF5FC3849A67E727D4CE70B9E8D3FA55E
+:10F6B000F3018B8A7EC946A199E0C3FC3ED2F730A4
+:10F6C0005E06E9256FF6CE5D561C2C83D39DBA8F5E
+:10F6D000D35D39F38808AF91F2FD011C7FE66C37EA
+:10F6E000F199314719C185280FF257A50AB44FB9CE
+:10F6F000030A68DFC73BD42611F04814CB0A126016
+:10F70000BCEAD9029D4B4CAF760405F8E774A00F14
+:10F710008A8392BCEE1980EF33BD023FEF85FCEC8B
+:10F72000283F3C68C3745E36C3CE7C2FC4C1E7DC7F
+:10F73000019C0F1BEDEBD7D84C7E9DEC014E2AFFB0
+:10F74000BA70D261E2138CC7B3E4247A8E217F674A
+:10F750005233F1A9C316D0BF51FF651AE9DB37E96F
+:10F76000F46EF08BE9DAED64074FF798F5E80F7166
+:10F770004F900E6609A4E7CEACBEB09E7DAE50D0D1
+:10F78000CFF172E5C349DDDF15A6903D7D23EA394F
+:10F79000A5F07132E82151FAFDEC3BCFA752FD3EB6
+:10F7A0004F2FFFE60A40851ACE5FEA019EC82F2B35
+:10F7B0006649442F756B6C14F755DFB6DA9A85F8F5
+:10F7C0007C0F5339BE7ED2D80FE6D9AF561B212A03
+:10F7D000DDF0E9571B1490AEB390E710FC2336F42C
+:10F7E000C7CDB0A9B5B8AE19694CF6A7025ECEBABE
+:10F7F0006E23F6BFC6C16411E46DDFF677828857C9
+:10F80000C0CA55C449C01C8A67CB9593E85CA1C99E
+:10F81000328CE2B59A5CC96A747CD4BAD5DD78873B
+:10F82000715A8A9D0D93F5FD8D6727150CE0FCEA52
+:10F83000518191BCF0CF72109C330B789C52668A38
+:10F840006A0BA422BFE17CEA5181C7D73D6AF5E685
+:10F850000CC7383C502BF9FEF076B1749F99AEF787
+:10F8600093A4080120C669ED65E516849B3359C54C
+:10F87000B844A3DFCA44CD8A7CAB72B0302240F0DA
+:10F88000DC242D40FD34C1CCF7AD56BE2FEC23CE89
+:10F89000F763E520C801E2FBE8AF0F9493FC1A3F41
+:10F8A0006004C903EA6795E490ED2AEB21CF323C6E
+:10F8B0002C19FD5BC30064A8AF77647BA662DC9E55
+:10F8C000FF4D89FC69E5D5EACD0BA3F6F5E7037595
+:10F8D000BD7D62640EC541DDA3F6C338A83515DDD4
+:10F8E000798C77AC61CD36C4F79A18F9B8D4B99B46
+:10F8F000F4C8A54F5ABBF197617CA85A80FCA3F6C7
+:10F90000D91EFE20E253DDFC2CC6BE64F26BB89E0D
+:10F9100011C08F910F6985C922F995D96C2E47D9ED
+:10F92000D302FAC544D7AA26947B9D4272B358DE0F
+:10F93000CD2747E8FB759FE479ED6E5C37E84B4FC8
+:10F94000C9ACA71C603ED25F2680DC443D5A689F4C
+:10F9500029E2B81B1743DF788E2F852B317FE762B2
+:10F960007E3ECAFCB7D1F9D738BF5D46FAFF2A31CF
+:10F970006F8D3EAECF0ACCFA987C0FF5C7605F5012
+:10F980006F11901F4279DFC9D014E8605CFB11EA67
+:10F990006F633AA78B583D66B7C519B45890EFFA14
+:10F9A00049EE24B06036C24F2BE47CB6FC00E7B3CE
+:10F9B0002FFB4183165195F5DD34C54D7A20958F87
+:10F9C0008D308A9BD9CEBC75BABEE31F908951A2F7
+:10F9D0003ECEC7757DC1D0E3AA62F6F15AE7231285
+:10F9E000F2AD6BB37BEC9788FD4F6602E98BD729AC
+:10F9F00017E65B9AC19798992FB9D979DA3F76FFC4
+:10FA0000DE3BD04F1088D1830297A907A5BBBD1B51
+:10FA1000911E62F5A1DEE2289FD2F9FBA5C65182B4
+:10FA2000063107E5D758C3CE8AC19FBABDC7E73CA8
+:10FA3000C0BAF1AE0B9FFD9B6EC675803C97D1EEB0
+:10FA400013FE6B3DD1F51AA8278E47681E0CFC1CCF
+:10FA5000F2210BF3619C02F3CAA7114F0DB90B9C65
+:10FA600088F0A47121C7BB5112CFE782228B78198D
+:10FA7000181DABAF7BDDE887D6CA4B282ED690C7C2
+:10FA8000C32D1AE1C908A6A6633D034F46867939FE
+:10FA9000E0C76EC48F7193015FF231BE76543FD4DC
+:10FAA000BB2A9842F8511123D72A9DD324A4F34AA4
+:10FAB00047ECFE6B16ECF71A1D3FAAE47F0E3FAE33
+:10FAC00040FC30E416E8C9F7C5D817F7C5D8179732
+:10FAD000801F615CDFA5E2C7B101971767DB69BDD5
+:10FAE000E7637F39D9B33E31AF277E08ED772E7AB1
+:10FAF00000E93D90CC70DF5F48902B9D30CFFA1A23
+:10FB00001E6F3EFCADC200E6B396BB492F7C21556B
+:10FB10007D8DCA7DBCBCBC431393215FB012CA214A
+:10FB2000FF82DB5389F9FA55500EF547BCE70D60AB
+:10FB3000BEF01E5E5E76AFEFB56494F37EDEFED55A
+:10FB4000638DA20BCA838D7AFB8AE64ACCD737F144
+:10FB5000F6230F0403981FF4001FDFD03BAFD6F944
+:10FB6000E70BC2A9D7EEC2FE807F6E06FE39EE8497
+:10FB700056F61CE417C8160BE2EDC288DF8AF8704F
+:10FB8000D8523B12F187CDF366239ED9D16E15BBB7
+:10FB9000F997059D3AD06E826425BDEF0DC12761AE
+:10FBA000BDC94812286747AB0EE4EF1887BC19E4BB
+:10FBB000CD005D1E1971BB787F606AD47E0D18C8B8
+:10FBC000E5BC512F2B8DE3057B8CE38511571C5A27
+:10FBD000CF04F4B7E0DAC80FD123CED847F23BD830
+:10FBE000BF6418E2EDB5185F0CE5D78EE5F1C56589
+:10FBF000DF9C9E14CF2E2AD6C73DAADF8730BED702
+:10FC000004DD16A49F171079FA62FFFDFF88FAD26F
+:10FC10000B38D65802A99F8DC67DE4F9B103731E37
+:10FC20006E02BC586CF14988472C4F5071FED77753
+:10FC3000F8AEA1F5D43276434E9C75E8F27E51C001
+:10FC4000B699C78770FE335DDFB763F2EC3D7791FD
+:10FC5000FDEC52AD30CEC4F10388EEA7550B06DDA6
+:10FC6000570E443D184F30C89FEDA538F7252C6836
+:10FC7000C34196C4D0FD32E7998F512E2DDB62A689
+:10FC8000EBE52C64E3FEE6C8E31F40FF351B9265FD
+:10FC9000943FCB5BCCF56A36BC754028EDC9076A4A
+:10FCA0000C3E1034F3015038381F583F98CEBF56E1
+:10FCB000648BCAA174F47FF848DE27302EEFEF93EF
+:10FCC000D430D15FBB9DDB51BA7E7EA7C8F5F3046B
+:10FCD000E6509C45C8872D7A9C2ACF1BE3B398F841
+:10FCE0009653CDB711BF31E260008024EF4FF9AFDA
+:10FCF00095A3FD6C5D7C3E86DECBDAFB84F09E81B5
+:10FD0000E16701FD80EC2BB60038DD38E243B46FCB
+:10FD1000C252F87F0CAECB46EB5A9F9447FC7D1540
+:10FD20001084BD0CED62A924847D0EE6F4E4403A13
+:10FD300042FE3ED96C6F2530AEC70FEFE07E9C11BE
+:10FD4000DD72BF01F7D7CE540797FBCD0CE9AB5757
+:10FD50007BC5B932AEBD42120AFA9F3199F3F58BD9
+:10FD6000D92BBDD9235DFB99007A1BA4D3BC09CF45
+:10FD7000E3BAAF3E9F921C2F8E6A5A85E841BB6C56
+:10FD80009A55CB4C8B1727897A7666547DAF93FAB8
+:10FD900093BCE9CF63DC12F41B42FEDFF1A62D6EAB
+:10FDA0003CB2A4F72F5935395EFFD7A2532ACADFD8
+:10FDB0002E79B3A8DF6F415F7971601C7DC5B62BCA
+:10FDC000E69C92F90746C7133CA3FB0347166A6DEE
+:10FDD000D8FE60421EF13BA50CECA97E94A7FE0E56
+:10FDE000DE762DC5479C61DA45E323D644F9CF0F73
+:10FDF000A6C63F17795DE773368C7983716F57B468
+:10FE00007D8857476DFCDCE568A29EBAF8B9D51F1E
+:10FE1000BBEAF3F498C1272DBCFC689AF9BCC6A8CC
+:10FE2000F7B9EE873AD4E0F0AC89F2BF2AEBED3EA9
+:10FE300094D39905FAFD8D958CECE7CE5752374552
+:10FE4000EFEBD98115B62B33B19E66CB4138BEC2DC
+:10FE5000E55F9D14B6E1FE3E7285F7139C779DC267
+:10FE6000B417B11F256CBBA904ED061E17D269E5B6
+:10FE7000766067024F8D799D1D38D576259E23DDEE
+:10FE80001626BED8959F1A26BE7776A087C6ED9C0B
+:10FE90006E94EBF9FFCDF30A93559C6F8543B71F22
+:10FEA0008AE435E47705BD0FFD36B1E7078C8DE7B1
+:10FEB000FAB11EE7A9E5FE83CEF17AF3F35B1C1DD0
+:10FEC0007B7E0EDFE7E8FE606FDB977BEE56087FF8
+:10FED0000EE3B87383098CE2BDFF45BF7E67FF0E5A
+:10FEE0005ACFBA8A48DE63E5142F407EB5E5EDAF00
+:10FEF000135F5F6ED07DAB99EED3AEBCB473B5D853
+:10FF0000F3966F81CEAEB8320E9DFD0EE535E0570B
+:10FF1000953885F8DAA95681FC210AEB684438AF98
+:10FF200010F8BEAC78637EA50DF30B994C7CBE3502
+:10FF3000969F7903A8272C6B6224EFCA58410AC206
+:10FF4000BB7E9F883E04BA67A344F149BC67A344C3
+:10FF5000D9C578CF263A8FF76CA2EBE33D9BE872C8
+:10FF6000BC67135D8EF76CA2F378CF26BA3EDEB382
+:10FF700089CEE33D9BE8FA78CF263A8FF76CA2EB67
+:10FF80001F61BE47C70B08D7091B10AEADABED32E2
+:10FF9000C295F9B5778BB3489C11FEE17D9CE87E54
+:10FFA00096B926D996031CF6668B4C188DF76B967E
+:10FFB0009AFA5D26D6929F00D40E92233EF88FE0E7
+:10FFC0002916939D7CB64D80BD037D68438CFED081
+:10FFD000FE5023EADB4B82E6EFCB5894DFDDDDF306
+:10FFE0001CE8D62BF573A0BEAC2FE27395E85471D4
+:10FFF0009F4FBD27AA76A6BB00709FB7727F64197A
+:020000021000EC
+:10000000BB72FD78DA472B0B2A783CC2CB4F6D14BC
+:10001000837E77F7F9D0A97DBF3DEC857A8B734459
+:1000200019E9CE9E6DDEEF04C5BCDF4945E6FD4E05
+:1000300056CDFB9D32DABCDFB1704ED5CCFBCFC4C0
+:100040002904E765FDC0BC83F1D3279BF1C180EF94
+:1000500068F88FE3AB42F05D04F07D4CC073B507E8
+:10006000F6F6537AC2B9AEED211BEAAF970BE7075C
+:1000700010CE49DD703ECBC6573A09B86C9A63641E
+:10008000B7BE54BECF474102C7E4DC4AFD3E2F3F16
+:10009000DFD1E10AFA0BD90B51E7504DA248FACC57
+:1000A00063C857B58C64E203EA8624DAAF610EDEDA
+:1000B000DF42E625FEB43046AF59EC7CC4867A4D6B
+:1000C000EC3A7136E877A969E77A4DEC7A7BF8A3C8
+:1000D0008AE4503FCEB75B1E537199ED069FF6A29E
+:1000E0001F238375D8508FE98D0F7E2F5B7B1EF900
+:1000F00011703186F0E0A600FD89AB4FD6771573FD
+:10010000FFBCDDC7FDFCCC9F4AF318C5F83CA851E5
+:1001100094BF7F941424BF432EE3FE25C31E8B851A
+:1001200027CB15D6BC0BFD8AAF311D8EAA2858BA35
+:10013000FDF760056AA85F8F3CC3F5A7D18E968056
+:10014000A4F4B4CF0F17E8E7DC921EF77991734857
+:100150009C3FFA396ED2E3EEAE6A1FB507F35DE756
+:10016000923BDEE887FB357EC75BE998BE2B284FC4
+:10017000DD0DE3DF2870BC88B52B03DBC729B8FF92
+:10018000570B1EF2574C62BE5C6E8F0449CE4C700A
+:100190007849AFB538342B9D47E9FE4BC6C2935022
+:1001A0004F5FAADA681E6BE44F27A13F6619D3FDA3
+:1001B000316DE6FDEB610FC5D841B5B0FFD86FAC2E
+:1001C000DD13078F62E201CCF2FE87453A3C198FBE
+:1001D000575118BFF75DA3FB916A1C1B5DFC1C0EF9
+:1001E000E45C2EEB61374908F831745EF135E25B6F
+:1001F000561AD80374DEAFD8E2C5EB313983CED5B9
+:10020000E73BA7115F9EDFD4C3AF4378BDB0F922AF
+:10021000EBD2F58411F80DC6FDF3950AF7A3244E31
+:10022000D9A7617179475EB43E5B6FE3F772992F8E
+:10023000DD745F21BF88EBB9E5BADE54E3D0E15449
+:10024000E46F44FDB84B6FEA612FFE73F7638C785F
+:100250001780D78022FD7C677546F7F98EB18E2F07
+:1002600046743C1D027889C9D738903F2EEEEF1DA9
+:100270005204EDFA1F081F46BA614E85F4F5936DDE
+:10028000C7F68BF9DDEB023C7B741CAEA34D94F9F1
+:100290007D797FE338E8B7B38CE35DEFF6AFDF98A5
+:1002A000D7E878F332E2EBABC4E2947094DEEED49C
+:1002B000E17774B06702B62BFF63AE0BE76BCD6FCF
+:1002C000D9DB17F5E23BB85E0CFB4A7E10D1CA04BD
+:1002D000D44BABC4F3B763FE543693D1FECC48F293
+:1002E0008B2ED4F3E632F21331D5A722AA88FD8BE8
+:1002F000C94ECEBA03EC27E8F7A395F353F15E7F1E
+:1003000056F282D40227C637C15407405EB078F84F
+:10031000BDEC173FFE8F722C9F4D7EE95BECFC9C81
+:10032000D9FDA3BF2F233A604A9A7D0C8EE7A577AB
+:100330000522A922CDAF62D699E1A85FF53DEF1C59
+:1003400086FA590E9EF302488B74FAB8BA3232DC40
+:10035000E7EC865346417CFB254587C7C1C49333F0
+:10036000F03CC4B87FB13EE96D3A0F3FA99F9FE4CE
+:100370006B935310CF0F0E34CEB54299E8B2AA4B0F
+:10038000D05266E23CDF11199E9B9C91B594542893
+:100390003FC9F8FD0A7F8795CE8956DE5FD927CD04
+:1003A000D97BBCFE7F1471FBA636262EAA560AD92D
+:1003B000F03CABF65F8C8B6A058B3BDE7998B1FE27
+:1003C000BA54894943211598E742F5B67D2DC68573
+:1003D000E3A622CB05EF6D6CD0D767DCCBA8C37B3F
+:1003E00019F069E52B157DD805ECD0BA73E34CF70D
+:1003F0001FD05EC3F5D59D9B40DF2BEF3B6143FCD7
+:10040000C67EF00904E35E466F704E29E2F6461D93
+:10041000DE67488FFEAEF0EF5DFD6750F9333ADCE2
+:100420009ED96799BC39CE3CF7E870199C2991BFD9
+:10043000604888699BE28C6BD433DE35E86D5EAD35
+:1004400013C37370DE18171C6FBC97F57AC67C5BFC
+:10045000D3C28B3CFC9C7520BE5BD095972379372B
+:1004600046F1D3B3BA7FA0F57BE13C7A27E33A6E3D
+:10047000C7F6B6CF53FB7B93903F8C944277ECC981
+:1004800020B38BA11FADCFEC9005E5A44157BDED86
+:1004900077379C45D3FD979E70B65179D7BD33A66B
+:1004A000B9842C94438CF481F57F2CB5D960FC631E
+:1004B000161641BE5325E64E7A15F3603F205D1EA9
+:1004C00023D901E90691EE311D7BB2C08676D9A20F
+:1004D0000A1611816F1D7B37AF11E32E95B9A04924
+:1004E0008E0375678DF9FCB186697B93A1DDFC03F2
+:1004F0009E9410E4173C609663C7DE7DD086F6803C
+:1005000030CFE9C3B82298E7A45721BFB0CD46F752
+:10051000B2163D12DB9F590FCED2E56DAC3E7CB2D8
+:1005200048B73B46B29128675E6D68E3EFE6E8F7AF
+:100530001041FFD3E2E189A1073F9938F1AF4504AB
+:10054000AF1611F9D238297EFD5B8B39DDAD78EA23
+:10055000B4CDA5F44E67C7819F14C2F8271A644A28
+:100560005D83346110F49F37C86B1B04ED45259201
+:10057000F705F939F93928E01BE5EBF17E1ACADBFA
+:100580006AAE27D8C5DB6A481FEDC7E400E92F3EF5
+:100590001FF9D32DA09FA462FCC6EDA28BFC0DFC1D
+:1005A000DDA0317F59908AEBCDF8CDCC1710AE7815
+:1005B000C781E1FB2B155A19F2F775539D74DEBF05
+:1005C000C9E2A77E3050EB3E8067F09931BBD07D09
+:1005D0005ED8F2D044B4FBE4F69D21B4579A2C5F68
+:1005E000EEC5B884A6094C0D10B483344E7DFBD4FF
+:1005F00017B07DDE34A78AF74AD7B9B53239AA7F5A
+:1006000085453E463DF364AD85FCA6A7DA9EA0F382
+:100610002AB0EF22A87C9FAACD27BF9911F7436784
+:100620007F71FC862740BEB1A87BDCCB5B3759507D
+:100630001F1F821B15155765CCABF6DE50D6CD2893
+:10064000777F2D911CCDF8AFEB287EC02D2902C2FB
+:10065000F36641E6FAA8AE27CF62C69FE63DA89FA3
+:10066000CE433D19F0F0332148F19A16D6FE12B66A
+:10067000AFCEE6FA20535A46A0FF3A5CABBF4BB46C
+:10068000CC9A8AFA8D714ED01B3EF4E6E7819E1615
+:100690007D08E39E1418F99BEA2D913C9CDF716B59
+:1006A0007CF93A7D10C7BFBA81BE20C9F334263F1A
+:1006B00085F32AF4BA912EEB2CCA0AF27BBDE7A18E
+:1006C000F8904E414E33BDEF2237FF0EF5EE7A8B98
+:1006D000CCED9B035A199EC7744E2DA6F75E4E5A59
+:1006E000C379C44780EF615C56DDA017A649F8DEE8
+:1006F0004E5FD0BB20FFF3413B783E3FBCC802F9C0
+:100700005DBF7E7F9A0470AD1B1C3E8CF937077D60
+:10071000CAF3C3C28B707F8E0C8AF03C1A60806073
+:1007200067067D35CD0FEB3AAEFB3F991A9E83F3FA
+:10073000AC7BF54A4BB47F313C88F3CDE309BCDE9A
+:100740007137BBF546D43F8AC2741FC6A8B77B90E9
+:1007500011B7C9F17FC9B68410C6091BED5876FCE4
+:10076000FEEFD1DB2DD1DFC902FAFB2DD6DB9DAD2B
+:10077000A4D13E1F051E85707965109DF7CC1B9492
+:10078000A6BF7314CE4B2BEE39DE5294F32807AC80
+:10079000E67B6FF70FE27C9B15F3FEEBFACAA9B874
+:1007A0001F5969DCCE800D49BD8FDE2FD8A4EB55D3
+:1007B0007C7F3244B92C2093DC198E76F3EEF3B9AA
+:1007C00065643757C6C78B4775BC5812E0E344725F
+:1007D000147933DD37671AC6A3EC6E4BA07518F594
+:1007E0008F0CE2FA4578502AC78BAE7DE823D038CB
+:1007F000011D2EB900EF926EFC31DA5F6CDD5BFEFD
+:100800004DEBEEB14FE57C7EC67A187B88EF2BCCA2
+:100810002F15F4FCE3ABF576A38D7928440F4BB686
+:10082000DDB581F33F258DEC76F6133E5F87316EA3
+:10083000319D4F2ED7F560D1FFB60DED8DE54D1DE5
+:10084000F4EEDAF216FECE5637DD692BA3E92CA3BF
+:1008500080AF3343D43202448FB03EA2474D8F372E
+:1008600030E34F17BC63E9B8477F4A9AB93F85FA2E
+:10087000EB6D1F3EF8B6F721101F9E5DFC25067E2E
+:100880005DF4E8D6DB15039E95F7A4C737BBF62FBA
+:10089000868EDDFFE478FABD93E577E9F1AA8A193F
+:1008A0008F97B7BA2DF38ABBEBDFDFF290273A9E22
+:1008B000D6DE3AD78FF2AFBEBD82E26A97BFBCF5F3
+:1008C000777E68BFF4F99FBA3098FA98D49C857AFD
+:1008D00071ED536B5D1A9EB3487E17F2CD63417183
+:1008E00072BC7BABEA60415F1FD7C7EAF09FD0FFC5
+:1008F000F167FEDEF81F30FFBF0AA05F21BF6DFD6C
+:100900005B23DA6F7B354704E5F651293C09E5E8BE
+:1009100092B94EDF6A15E306CDFAD4D25FFD344BAF
+:10092000A1E06E7F3F0BE953A17ED8AEEE49AB8AC2
+:10093000F67BDD7BA20AC3B07A1669C4F9C5B6AFEF
+:100940006FF9CC867095411FCC1DD7B31C3809E1D7
+:100950007D7DEB7F7E29BA303DF6212BC5FEA2FCC2
+:100960001100F79A5EF432F760DD4FA9DF0B30E03B
+:10097000C38299A4DF047EBDBEF41398D78927FFF4
+:10098000AF4B288E9697F712BC4EB5CCFFE5AB4A1D
+:10099000EF72F524EA07F69E7A80D2267025BB9D79
+:1009A000A7B5D6900BFD02B59BACAA1F3ED76E7DB6
+:1009B000E2693C57611FD8553C7AACDD7ADA86EFA4
+:1009C0009ED50A5A44203D8BB98491DDFBB46CEB73
+:1009D0005FB8BF2A476453609F96FEF62CAFAFB155
+:1009E0004802D45FF6C227E4DFAAF53A7D8E38FBD1
+:1009F00054D9B2D31676C6D9A7964F26A11E14F89D
+:100A0000F557B40FC77608AC8FBB67FB9A4D7FB123
+:100A100021DD9C800D494FE5F042FBB4BE459C6B47
+:100A20004B89B76FA1EB51FF8372F2835C6CFF843B
+:100A3000C18CD3C5CB5B9F437BA0E643BB3A05C7C4
+:100A40007DEE761743FE2AF938BEFF626D9606E307
+:100A5000D658FD5932A5FC7BCDE377101E2E7EE7DC
+:100A60008E2CD2EB989663194DEBCDC1752EDC38E8
+:100A70009DD6B98879090F6B7EC1FD196725363976
+:100A8000DE3DE32D8339DFB2B3DB4A913ECE424FE8
+:100A9000E8873962633C9EF75DFEFE989DDD981203
+:100AA000FDBEDCDD83391FF1B3E0C7F8EE643DD84D
+:100AB000C5C817C477CE4EC27E56BA259F5DA6F52F
+:100AC000FB757809DFF0780E4532E24EF361BFDE48
+:100AD000A9EA8376B09D9DB2DD528EE7BB4C41FF03
+:100AE0006F543B82DB91CDF64401ECFC2359F1EFCE
+:100AF00011BEDF45F7EC5D16854FF55B8E103E317C
+:100B0000B0BB52B279FE31A443B08B52006E67DEA7
+:100B1000FBCCD617FD1D19163600E7DBF117CA33DB
+:100B20003553C1FA46FFF56D76D37B24F54FFE258C
+:100B3000869EED31EF9CF8089EF52C45417DF388AB
+:100B40002D32691B8E03E362BCE6A247ECA677C296
+:100B5000BAF1C5D6FDDDDD4D9F867DB558A7FFD81E
+:100B6000F5C7F2832762F801DB987949EF3ED55A41
+:100B7000834F237C6A815EFD44AF9CFE40478F0C0F
+:100B8000007AF8FCD9D7F6FF10FD742DD68C2934E5
+:100B90009A99CFD6BC08F48BFE348077828A7CF693
+:100BA0002B1BEABDD9956007C3BC3F77AA7829AD56
+:100BB00027DDC2F7B874EB6474AEF5FF8BBF2EEE81
+:100BC00085BFBE35D87CEFEA2C2B4EC13B0CC79FAE
+:100BD000597605F91562E06BD8BBB17C73F160857D
+:100BE000E01CCB37E1CF7E1605C7A5BFF982F0F632
+:100BF000AF39FC1CACEEC9BF91FC02B046EC80B72B
+:100C000075C12F29BF16E517E5774EC3F3EA9EEBB2
+:100C100036C333B6FC219D1F75DD73BB97F931EEEA
+:100C20002EB25DA4F7173A612E8DA89F3FEBA673F5
+:100C3000C2B5BABEDF29475CA89FAF4D35F2EC566E
+:100C40007C07A6D35F2AFBB17D821E7FE089B85264
+:100C5000A3F4A44FDA4517EA75E1209B1CFF3DC0C1
+:100C600000CD23CC7A2B5FCDEF6B89E79F0BEB7622
+:100C7000BD1DC60BAFFEEA393C373F2439E8DC72B4
+:100C8000C1EA992EBAFFD75EF07F102F16BE017011
+:100C9000447AF26BB61C80F37C0E02303FFC741E6B
+:100CA0002C2697EFDD06F5160180F19C24D69FB225
+:100CB00094795242EE9E7E1390833694FF8B411EB0
+:100CC00091DF7BA3B97C69FBE784674B63F0CC8B36
+:100CD0007896D313CFFA0ED1E9B68C95E9E7BA64CA
+:100CE000CF77EE13E93CFF948391BE81E7BCB063FC
+:100CF000EC54BB48FB73EA592148F186FE4CFE6E6A
+:100D00002BE03BEA59061EC6DAF7B1E989973E1A8D
+:100D100089F7C46A7FF7DFA53F87F4C4EF3E18B8B0
+:100D20000DF32FBF9FF7DFAC67FDCA1D7F233BA6E6
+:100D300073879DFCA19D3B5ECF43B9DCF9AA5D455D
+:100D4000FCEDBCD7CEE31A7624D3FB659DFDB9DF5D
+:100D50002EB0FDABD230C9AD357C1F87D868BF4FF0
+:100D6000B5FF9DE4C8A976BB82EBA8DF9144FEB134
+:100D7000FA571382E81FE8DCFED5C8E877AEFED547
+:100D8000F5D4E9F7693A935935C6CD74A6F238CB54
+:100D9000FA6D639E588DF648EB4E1BFAFF2BFFEB66
+:100DA0001FA5C8973A5FDC6943BE0576E9E30CF0FE
+:100DB000C3F39B9FFED49A83F7C518D9DB277EB374
+:100DC0007F3ABE8BD5132E1C0E9D00075C17C0A565
+:100DD00006F5B2DEE0B1F83B0B8F2FC99EA86D1F60
+:100DE0004574D40D1741E3DF93830E01D7FF8A0BBF
+:100DF000FD469DF920FF555CF757A5A83F5D6CDDCA
+:100E00008DFF53D66D6197B5EEA786F0F7C8BF7B0F
+:100E1000EBE6F83F64089757B174D013CF5FFE112B
+:100E2000E59F4B5669BE9748FF7BBEB3EBBFE47DA1
+:100E30002F45BFEDE5EEFBA1EFECBA2FB6EF6FE863
+:100E4000FB9E2CE3FDBACEEDFFC8A3F55EE2BAC56A
+:100E5000E2EF2A9D5F78DD5DFA91E871E0D35A0FE9
+:100E6000B0508702E9DA5EF414B5D86C8F88BABE48
+:100E7000B1960DD336A15D057A06DA016B3378BEE3
+:100E800009F40791EE0F52B00A6BCA55F97BB6927E
+:100E90008FC990B7BE3F9FE259D6667D8FE597E335
+:100EA0007905F7630456ABDE9DD03E906A51022A65
+:100EB0003E53B5C2BB09CAE5BEA28CF6CD5AE54683
+:100EC00047F43B1692D366B2539C31F64662A1CDED
+:100ED000649724B05D32FAE1135489E2FFEC2CAA46
+:100EE0003DD47715F373EB4416F4CBCECB87D32DDB
+:100EF000C5BADFECF2E1E4A07B95B20E27A669B893
+:100F00006EBB22911E2631B01FF93AB8DD0970542C
+:100F1000A2E0C8743B54D2412E29C3088E604028F9
+:100F20001347235C7D04C7408E28135CBBFBA3756D
+:100F3000C7EEC35A6522CBD7F57141FDF6E13CBC43
+:100F400098FF1E432C9C8DB4C05BB11AF5DF95ABA6
+:100F5000F939D78BBFFF1EE55BADA00FC37CC6A7D9
+:100F6000781715A3DFD1A30948A72BA7F27705CBE4
+:100F7000F11E58069AFA3C0E37C391CB24F25782E1
+:100F80009D41FE4A99A1FD274E642DE40FF448319E
+:100F900071BD32C53D056EE3714FAC8829FC9D16CD
+:100FA00073FC8F7F222BC2B8862AB1B619E7758AE7
+:100FB000253763DCA5CD1ACA23FF707F9085E86FC3
+:100FC000A9F8EB462C77835ECFF03E9914FA18E32C
+:100FD0001BEE145318C55545E05314DCAE3EE760D4
+:100FE00052149C2B58AA297FA2FFE156B413F2FD9C
+:100FF000761983C72A1D39A6F62772CED17801BB90
+:101000004346FBA84A769BDA8BAE7D1FA35DF37641
+:101010009A85EC826BB30799DA5FFFE9898D737566
+:101020009CC575DCF011BFA70AF6D6E36F42BB770B
+:101030001E610CFDC6D72965A6766DBA7F2552655F
+:10104000A5F766BE5F34C6346E5B7817C1A53693CC
+:1010500009781E5C6B0192807A3F502B4CF56E181C
+:101060007D9DA9DFA9DA5453BE76D55F9994CED879
+:10107000B855E719BE1B58166A31B51FBEAFCD541F
+:10108000DFF52698429096BDA704301D7590DF23AA
+:101090001D0EFB81E71B6DE1792AC6EB94E005D0BC
+:1010A000723C16F0546218F2C8A3BED730BD58FC8B
+:1010B00032D3DF634DD4CF5FD759822D73DD18FF54
+:1010C000D3FCE04E81E221B7158F40377473650A77
+:1010D000541F7BAEE5354C5B3BC6378D2DA76B436C
+:1010E0001D247F9D163A17A812DB4B05B27F92860E
+:1010F000DBA3CE5D7A7BA7F3EEB28AB7900ED664FF
+:101100006BCD3B91EF4FFC688E98DFB31E93A548E3
+:10111000349EDF5DE6F933C69D197152899522FF31
+:101120001D8A6B799C4CA3454DD09917E907F22491
+:101130002BC5F1CF2DE1726064C7E6166739DA9DE1
+:101140000E05F73531DD7CCF7BFE687E6FEF8B625D
+:10115000DD3F2FC999B79460FB64DE1E7D7C38DECD
+:10116000140BE9533BAF3A42767AE20D96FE2041EA
+:10117000996BB46A41BB7BE4BE3FD17B04AD53F2B3
+:10118000D7EF82FAADFBFEC40428EFF340D95E2B03
+:10119000D2D9688B8CC7F5ADA3279E2EC4F229EF58
+:1011A000524CA3310FD739812951710F734B141A47
+:1011B000DF2585E91D22D73989CA5DB3554B1EF657
+:1011C000B7CF4ABF5BB3E22AAEEFAD1894B815F1C2
+:1011D000D47540E37150454E6500D143389BF88289
+:1011E00014CEBE2599C753291778CFFFF89611A9B9
+:1011F00028B7D22BD454F47BA66F15BBEE99E17CB3
+:101200001FC4BFF020DDBF76FF3550BE0563D57823
+:10121000790878105B67D3CB9105413E5DD0CBFD5B
+:101220006B675CE3A477174DF587E677D5D71CD9B4
+:10123000DDFDF7D9BA76FF9A6284F7280BC69124B0
+:10124000FE5F2BBD2BB0629093F4871540BF4CE836
+:101250007D1DAE73491781A78BCA0F094ACC3BB9D4
+:10126000A112CCE7E57AF34A005FAF389F42F7FE60
+:10127000CF342590BCBBE2FC0DF42E67AB4DCBBB4D
+:101280008BFC3509145F36F5B6CF37AC423ABEFE5B
+:101290007811C62418EF54D6CB7F25FA37E2EABA84
+:1012A000E087F80A78FEA0A53B8FFCC0D50D4F0D56
+:1012B000DFE35A17055FFC6D97A93A3C676E5D3F07
+:1012C00003E1A32C989C8D74789A39298EEFB4FC95
+:1012D000F40C9CEFE92D560A9A6DD5F9A3BF487F0F
+:1012E0007F20239C8DF7F04BDEB150FCD141C0072D
+:1012F0000DF0A120F44E5A09B6CB90D2309EE1F405
+:10130000F8F7E99D84D3F7300A265E1AB611BC5A65
+:1013100033165456A07C3BA0A4A1BFC1806F8BDEC6
+:10132000CFBA326D6209C947FD7E8836F6B2DE9BC0
+:10133000DC79D557740EB0C60D7A7D2A86189F6B5E
+:10134000C4F72457B8AD248756A4FE755206E27B35
+:10135000852382EF3ED4AF3A43F0856EDCD1F7BEF1
+:10136000A4732253A2E2B5FA0CE5FB2F491AEDBF94
+:1013700074CE46E5B5AB4E139F36DA9FD0CF53F10E
+:101380001D46BC1F54FBB548F74481FF3509C330E7
+:10139000DD655B117D8ED3F265175F1F6AC1F79F14
+:1013A000DE4D44BFE454419E8EF3FB6DE99919185C
+:1013B0001F3035419E8EF105FFABF4239EEF2F4F7A
+:1013C000C77882755BAF9E89F1065373E49F5A40DC
+:1013D0005E6D7B6ED64C2A77CB7FC2FC132577F2ED
+:1013E000F264BEEF752537CDC4F8822A91D3C1A926
+:1013F000A6A4A0FD0274B078D53616FD6E6D8F726E
+:10140000FD77A35835E7735FDCDF8FDEE964851D68
+:10141000141FB6BA44D0E3D08CF35426E3796A465D
+:1014200001D3D0BF9CF17202FFFDA1431D7908BF1B
+:10143000231B6FFF11FA4F970B8CDECBAF65CA48A9
+:10144000A4AB7996F0C798FE66B8B789E34707C59D
+:10145000B72E5EB583E6F789AAC729CB9162CF3F45
+:10146000F52E04F41FF75D08735CF1A7166520F6EE
+:101470002BE970992776CCB1F179FDBC04CF87D2E6
+:1014800076525CB324776479B9DE5444F6527622FE
+:10149000BD0BDDD8F7C3D278BF77D0D200F21D489C
+:1014A000EEC586364AEB87325A4F1F296C53A19FEF
+:1014B000BA035CCE8CECF8D4161DBFF88A2EA75266
+:1014C000F4DFB58A8DBF7D459743C6F9F6F2BEA11C
+:1014D0005CD4078D7DEDDE9750AEBE2F0CE79B915F
+:1014E000FEDAB3F8BE09C6B5DE83E7172F2784D02E
+:1014F0004FDD3B9E18FBC068BCD644CE37222F255B
+:10150000909E14BB8E3F76C957BE9E233A9EF4B67A
+:101510008E23B88ECC7FDF3A8E207FCFECB91E832E
+:10152000BE8DEF067DF76CCFE77FF978C7EFB15D31
+:101530000CEF0CFE53C7BC45FC7E34E73706BC8D70
+:10154000791A706BED25FE565AF58A693D52C744EB
+:10155000347298AD349FF3B796EB18EE87B4AA9D1A
+:10156000EAF5B61E31F90C9DDB2C55980FF5DCD849
+:1015700075D5B2166AD7735D11E2C7CB15CE8F7BD6
+:10158000C6ED47883FD7813D86FAB7B1EE2E3E0DB6
+:10159000EB47FABE0A180EF14DBC3B28A03DE135E1
+:1015A000E9C315784322FA9CCA719B295F25DF6540
+:1015B000AA7F6DF66A53F975CAFDA6F2EF173D646E
+:1015C000CAFF40FD598C3EBF29469FFFB5A97C7CD0
+:1015D000B883F4EDB71B26533CFA84A311D2BB4366
+:1015E0000D32E577356453BABB4121FADFDB504455
+:1015F000E9BE0695BEFFBE6134A56F3668947634A9
+:1016000078288DE51BE51DE172F4E78FCE48A1F344
+:10161000A707867AA795E2D1C27B9162C4BFB107C2
+:101620005A5E43515010FCF263AC775AB651FCE15C
+:101630009A9D63FE703BE4D3DF1459827221BD484A
+:10164000645A14FEB8A684199E77BB187F0F2BB678
+:10165000FEAC521E4756CDC2FCFD805574E2CDAAA9
+:101660001DF21E2D83C44604EDF46AE6233DD4B278
+:101670008ABF4B53CD54568EF6AB97F91EA0F82374
+:10168000F37B021E6DEADADF42F90CBC670AED7FDC
+:10169000E86CA17BE42FEE4BBBA60CBECFF208F4A6
+:1016A0007B1E0776DC778783EC5DE3BEE98796CB0C
+:1016B000D127669572FAEA14D40E9CAF3F95BF57B6
+:1016C00014DBAE545FE7F58108E91F11D03F30BE4F
+:1016D000CCA0CBA9F2217DFD8A25650CD2C76ABAC0
+:1016E000CF50DBA1A80180F798439C2E46005DE017
+:1016F000BE8D3DCAE96024D001C941DD1E34E80039
+:10170000ECA7D7B0FDA9834C453BA271C27F8A6884
+:101710006F8D39130C607AF5F9C8CE6FA07C5C0729
+:10172000FF7DA48BD98F865EDADE504D78B4A3C1DD
+:101730004B69A8A146C74F1FE57737ACA2FCDE0670
+:101740003FA5FB1A9A74FC6CA6F2371B3650FEEDCF
+:1017500086A08EA75BE87B1F5D9EF94B653D2EA999
+:1017600042B72B78EAD1565BE95E3F7C427E528DD0
+:101770007345FCA81182C8BF1BD3FC56CC3726E2A8
+:101780001EE0ACFD54FF66270BA11CA8CDDEC6F5FC
+:10179000B0183CA9C8B889F0649A1EB77A20ADF198
+:1017A0000E1BE0C3899687ADE6F7452F0F2F963ABB
+:1017B000D7D03DBE58BEB804DF9F107BF243C6545D
+:1017C000B5BC9CDFE7C2B8BC4BE5F7B2A543BF1F71
+:1017D000C6EFBBD4E53A29AEF6DF2767645DCEB02D
+:1017E000B958BFCBDE4E3C3807DFC3EB0197187BFF
+:1017F000FBCF57F2F686BD0D7A26F9A13A8322D99E
+:101800005F35EE6617D9DBA3232EDCCF25DB4546FB
+:10181000FAA2C4CF771763470AC6F184F68F23393B
+:10182000B3722FF2A5A5FAF96EEC396D1D9EEF0A81
+:10183000F1E01DA638FA65FAF96EECBAEBC61FA105
+:10184000F3DDBA8BDC23FD53A9391E23F6BE6E6F80
+:10185000F882F103D1EFB79E3CDF4076DAC7A57777
+:10186000AEF78FFFF7EDDFC232CFE7A53C6E9AEE01
+:10187000C919FBD9A8FFFE66E34407DD5BE81C211C
+:10188000D37B379D027F6FA7F36F4C5DADE07B3A52
+:10189000F26E940B57AB36E2ABA3C3FC7D80F178BC
+:1018A0000F31CEFB00571D0A0692B1DD413FF99F73
+:1018B000C6BCE70DE03DDB516F6A229257D96E8FAF
+:1018C000887860C827435E75D3957E4F0E63300AD3
+:1018D0002E9DFE9405A3B351BFEBB25B9D93E85DD3
+:1018E000A2D32146D1A3861F6CF8414DC47B0823A7
+:1018F0000E7903286F1B753B73D409BF9802DFAFC5
+:101900003AE3233B680CD8A9F8FB31786F5A8B82F5
+:10191000AFE1C732F89CC1D78C7B7AB2CDBB05FD55
+:10192000CDECD5047AEF2576DE7943B95F68717F17
+:101930004FDE50E47BFABDBC2AF1FCCE6FD02EE81E
+:10194000E0F101579CEF7C1AED9E952F25D1BDB497
+:101950008BDA07F2E9B8FAA991D65BF8B9C9B04AAF
+:101960006538DA9BA8B7A21D6AD8A5B1F50BCB26BE
+:10197000960DCDC4798DEFD010BF65CB05F1BB7E40
+:10198000D59717B40B8DF1EBB78F90E7459D1FD41A
+:101990000F35CE57FEB977A7AF8A549BE4D8775D51
+:1019A000EF033A2C47FC429B15E5D40F7107601DED
+:1019B00037B310E92BB7E8BF5B712BA8E0D1F76212
+:1019C000E7338DF8C31ED5BB08F765218BCCC17CEE
+:1019D000BD10A9DD0620FC62C238D9ADF494D797BA
+:1019E0002B9F13F57BAFB170BF6B28D7670CFEDF61
+:1019F000EBFEC4F0FFCE3299EE3D77BE34CE82E7E7
+:101A0000369D6F89F45EEA3A0BE72BFE6136F529C5
+:101A100015DF1F997D8DE10FC0F8B258BEB2C5A287
+:101A2000FEE17628F7BF9DCEE2D195915E8FFA2830
+:101A3000E061CAECB094EFA4F7D3D721BCBADEEFD3
+:101A400040BE7205C0FF137E3EC79608E4F76C6B7C
+:101A5000E5F99285A934BF4BDD0FE839A914D6B159
+:101A6000B0551A86743A342D928FF45532E6833489
+:101A7000C189BFC3CAEF4501F89A585AF73CDFD273
+:101A8000E1F997A1DAE338BFA1691DEB1E463DF1EC
+:101A9000250B43FFDF9131772D6251F2F56B75E233
+:101AA00013C82F9E17F4F7E5B6F3DF21801659D13E
+:101AB0007EAA3D6AE5AFB15E0BEA5748579E57E8EC
+:101AC000FEFD5499C3925D93A9FFFE63242FDEEFC0
+:101AD0000119E75043513E703F22BD07F6BCEE6747
+:101AE000DC39F4C3996B90918722F9388F2309FC74
+:101AF000FEF3D7AAF7555A07FA6B711DBFE076FEC1
+:101B000091541FDDFFF800F82C9EFBFE778383D2F3
+:101B10008FC0CEC1F4CF60E760FA09D839987E064D
+:101B2000760EA60BCF41A7B08F15AAF6C6D00BAC88
+:101B3000A3773EC1D7D1D9CBEF2AEDD2E15FDA7AD4
+:101B4000E8DE24C4833691E29A4B5E9248CF3CD9BA
+:101B50003ECAF43BA24077FB711EA56D7FFC09DEF7
+:101B60008F2E6D956441C1FBD4A7B3286E30667E7D
+:101B700008073C27886CB7F1DF3FD2E7FB7C6AC7D8
+:101B80003A6CFFFC4BF938433C7FE178B8DD1EF737
+:101B9000F7818D38B99FE972FB067BA43CFADC30F3
+:101BA00036AE8CFCB963109F0BFF80E3F8F7896CAD
+:101BB00000E1A5D94F91AC723964A425DB6D145FA7
+:101BC000FCFCF6FD377E1FFABB7EEC75A67775FF31
+:101BD000819B9B8978FDB7C71ECEA0FA320E358B4C
+:101BE0006DAA92A1DECD8E9D7B70E9B7C89F54A5EA
+:101BF00042FED66C612FA67315F7A43405E71BA42B
+:101C000071E61755EC45D49AA24EB5F1771C453CC8
+:101C10006BECE28F958E247A0CFAFF01C9CDB6AA3F
+:101C200000800000000000001F8B08000000000082
+:101C3000000BED7D7B7C54D5B5F09A39F34A329395
+:101C40004CC2041220709200060830249390902019
+:101C50002721D088944E225A54D4915A44E53122F7
+:101C6000AD694B9B13122084A04191624518285AFC
+:101C7000EDF5ABA9052FF6AA77824AD55A1B149F1A
+:101C8000A576A4D66AAB9282D87A6BCB5D6BED73E6
+:101C900032732693F010BE8F3FBEF0D39D7DF63E8B
+:101CA000FBB1DE8F7D7600004EE27F33DD83001CCA
+:101CB000C03F54FF4AD630808268FD1239DFD07EA3
+:101CC00069C178433B4008A004608EB7D8D06F52FA
+:101CD000464F5ED00930E1A9CFEEA8F4E0031384AB
+:101CE00047633961EFA76FDF82E5DCA957FA241952
+:101CF000E043E8B862BC09E083B2F55BEEA6972D3D
+:101D00008A2D7B30C08DF43BB67F04E1D72BB05DCC
+:101D100072AD3C701BBE77739604921760F136EB80
+:101D20009148CC3A96813F2D8CFD6EDE6D7C0E1075
+:101D3000B1857D00B7049CC13637C09247B0DD61E4
+:101D400068E77197EEB3B9A97D1958A2EDB9000DF6
+:101D500087731F7D3666BC4919DD77DD8DE34D7ACB
+:101D60007C9EBB19D7F768F9E74365DC67A1D7E527
+:101D7000793F053B4C812927252C25A719B0DF8900
+:101D8000E7A59084EB9A297D911A29C4E73599003B
+:101D9000D9F89E49FE6D05B6AB2F48F0008EF3F7DB
+:101DA00046F9D167AD343E5CE7C77E27E9673ACD97
+:101DB000BA9AE1AB976F35E2AF1701FCAED1C1E53E
+:101DC000EF1BDD5CFEA1318BCB771B652EFFD85856
+:101DD000C0E5DC5720D089E3FDE91F930106D13827
+:101DE0002A4066B49C64F39A87E23A7A7E23857629
+:101DF000E17E8F574E49035AE717387FA98607249B
+:101E0000813ADC0394E37F37EC7C2EDBC7CF551798
+:101E10004EB5EC1F122838EE0D5E9358E792AEE7F0
+:101E2000B23DD17658F9AEA13FAC321D30D45B72D1
+:101E30008DF5F6AA03B1EFEB70882F6FDC76AB2D32
+:101E4000E0C272B3490939FBB6EBEB99B93F4931AE
+:101E5000E1789627ED213BEE6F995B0105FB5B0076
+:101E600094CEC2BEEF0134F17B574A10EC4C30EEF9
+:101E7000721A17E136677F12486731EE5B481BB470
+:101E80001EF53FEDA107F0BDB7D214F0C7CCF35D4E
+:101E90006DDD1FA7777CFF33ECF7F113404FB00ED9
+:101EA000F3693D13F7FCD96CC67252B2A09389EE68
+:101EB000883903CBA38BFFB9E5750F93A9DF743184
+:101EC000B6E7F5BCEE4094AFEE9CB9D581787BDBEC
+:101ED0006C06180A02F165D81FC7A0FA06EFCCF904
+:101EE0002DF8FBA5FB93C2E6B3D8CF06E4452A271D
+:101EF000550B7EBF96E846CCA300F2C3F235A0CFC7
+:101F0000AB907CA0FD53FD99CEDA3737D31AA0678A
+:101F10000BC9878F00C26DBC7E253596FF973FF5B4
+:101F20002DE6CF25D9C8F748EAB04DF0AF03FF9DA5
+:101F3000CC237E0DCD72E27A6F0A23FFC3F9E7FF4F
+:101F400087BDCE289F5F9490CF5FB914EBCB9F9055
+:101F5000BC766C3EF6E468C14F1ADFEB7CDE4B4F7B
+:101F60005B25E64BBDFEC993526D2801BC376974F1
+:101F700091AFF4D4D37C2B9EB2401BAE6FC5B48B13
+:101F800086C48EDF875E5B259063C67FF469FB6243
+:101F9000E217197A06D721FF4C7AEA444655A12860
+:101FA0009B681CE8D0E44DCF08FF0494D726FFEFD0
+:101FB000BF87F301E2F101844F75D6FC1C9ABFDEA6
+:101FC000094ADB6406CB3C07CA89CB0488E0B2B27D
+:101FD000AB7300E1B90DD12521DDCD53EA5EBB1A0B
+:101FE000F178B939F05592F36F79F379FC2B5C2BCA
+:101FF000AD606672CD31E178F3E7D98B693F739BB1
+:10200000055DBF96DEF3113D7F6D5A8AA919DF7B0E
+:10201000CD042D9011DDC76B567F4E90E9A7C6FD0C
+:102020003EE2C7A48C934EA6F42F2F8892DFD7F1FF
+:102030002845E5DF4CC9A9D23CC7DC66A67B4B76B8
+:10204000BB8DD67513840E2838EF326FD846F2EF69
+:1020500016705BA8C4A2A7973E88FE2AFFD9751206
+:10206000DF5FD62D854CD8BFB3B1132C88DFC71ADC
+:10207000F77139F28B912DC3101E2B27DBBC6DA499
+:10208000B734FA32AB263899405FF5A54F4BB41DF3
+:10209000D75DE57086A5547A6CFD28761D3FC85142
+:1020A000FEE945B8AAEB2AD3DF4715CDB43032BAE2
+:1020B000CF49360027C9F9075258CE7FF874A9993D
+:1020C000F0F4E18BD69089EADB2F7AE3361FD781D3
+:1020D000E4CD87195EB38DDA33F2422AB6DF6806A3
+:1020E00095E432EC1272EB9969B7BF43726CE50369
+:1020F0002E93DD24E858461340FAC9C677EEC57121
+:102100006E4266B57BA37A63C9F49F6C7904E9607B
+:1021100089B9E38E4A7C7602C213DD08CFBF9A3AB2
+:10212000C790DEFEF3FDF6B099DEFBF1D85D128EAE
+:10213000FF5C6A207B32E9A92C65482E3E5FFC4A91
+:1021400026B4E1FB337EF2AF97496FDEF46826F3E5
+:10215000974EF733890F713D47910F693DC79ECC6C
+:1021600067BE8BE25FC06129CA034038AEDFBDC9DC
+:102170004FF8BC2159667AB440501946F8DE773DD5
+:102180000490AE8A24934274DEB31EE165EA4B4F9D
+:10219000DEC9667E6F8919F52BD161402E26781C29
+:1021A00035C9451A5F00ADE7C8D36377B5E1FBB524
+:1021B0005AFF28DD1D5EF65F4477DBEC5E3B2EE1C7
+:1021C000A324A3DED7CBCAC9E9DCFF46C7A7602991
+:1021D0008E3E5FD6F0B9B15E080AC98DA266B9F825
+:1021E000562C6FD3E03E63AC7F3AC1F1E6CE4D8F03
+:1021F000BF24D3BCDBBEFD36CDFBBC93E785970483
+:10220000FC8E9A847EE9D5AF8EBFF1F8003B797ED3
+:10221000FDF99FEF7F636200C7FFF3DEF16300E922
+:102220006EA1D4FDFE7D88AF4F5CDDEF7C0FCBC788
+:102230009E7F6530C12F7EBD4B1A8E8325460E7D55
+:102240006432F17E97D03EF0F97F14FB2F9F5CC281
+:102250006CAA10DC16B64DD845F260A654984676A6
+:10226000D3D10F8DEB8B5FA73EBEBE3E7D7CBDDF25
+:1022700042823FEE63F22437971FDBBA3F21FC7E98
+:10228000FCF87813B262F47946F7C4F4C2289EFCD5
+:102290004A9395FA5D41A21E5131DF21F03A7FB198
+:1022A00029D49CCBFDB8FD6A7C4E78AFF234737DA7
+:1022B0009E13F519F65F92F55FBC2E12740ED46B67
+:1022C0009783FE53B7E617D8EFCD15A92C17E6DF95
+:1022D000D861253BB7579EA96F9B4F8E3F73798678
+:1022E000D093DD83817998F427E0E62C589FA6D51A
+:1022F0004D65BF6BFE05C9E7DB52BD129A8CB05825
+:102300008630F1F5310811BCD79A826CEF39480F4D
+:1023100060D966F26659B094CC3D8380E70909BB69
+:102320000A0216AAFFCA1469067C6F8DA73A8BE8C9
+:10233000FF4D70FAC92EBA3C7DED0492A3D5EE395B
+:10234000F3E979BD9AEA6EC3FDB658E50D8564FFE1
+:102350005C2E79C9EED5E1A2EB8FF916AF95E03B83
+:1023600038287B55A4DFE297148789E1EF5069DCB8
+:10237000372CC14C5AD75BCECD134C66B2D342AE8C
+:1023800009B8D9B75FF969C96FF0FDDF81328DEC0B
+:102390008179BF72B01CBF1E64E6F76F80C272FC09
+:1023A0009B10E0FA8D10B17E8AEFFDA1FC7F1ED854
+:1023B0000FD17DFD61EA677BC9AE9F2F7566E6622E
+:1023C000BB5A0D05A4677EE9F8C18E08AE4369B615
+:1023D0004012DA57BF243A25FBFDB02BF400F6BBC0
+:1023E0003D797B6A17D62326617FA9D5C147A9BF4E
+:1023F0006A067F3396D9C9815F101FFE30458CD3A2
+:102400006071B8493E928145E3BCFF8E8BE99DF433
+:10241000EEF558AF406C11BC8E660A7A53FF062C5D
+:10242000778F5ABDDD0A8D7B42F63E40AFCE30F34A
+:10243000FB7052E67554C4E917DF7833BF0FFF9481
+:10244000F9FD693D16837EF14D32071FC3FD4DFF37
+:10245000876540BD737991905FBE41E660227BF055
+:102460002F1A7F2184245A4FF33E53A88D8950D8C8
+:1024700007153A3D42642DD15B254090E81EF6A138
+:102480001ED3E7C9E3FD7FA2FA880EB19DEDC1CE50
+:1024900067484EDA83824FB03E83F6E3088297ECBA
+:1024A0003554C860C17A12BE28E4AE1BC88E6DAB2D
+:1024B000824EAA4F838844F89E4E9046FC5781CCAA
+:1024C000743B0314AEEB74FC1550B9BC04425C5E63
+:1024D0000A61A1EF416EF939CEFFD50F40EC675C80
+:1024E00098E91D1D1937DB8197DC6826BBC3F7F51A
+:1024F000C4FE426A910E174488E7F4E1320B025998
+:10250000627E010F3B3DF745E1E188834712C1C37D
+:102510001B8507CE21E0D107BE023ED314840FCA2B
+:10252000A78BA147A27914CDBEA9062F9735E0E766
+:102530007200B83CDBE4E90B97B248C012284C00AB
+:102540009F1989E966884657BF2E022E75F933BB5D
+:102550004866B8E97208F9338BECD178F9A43FF7F3
+:10256000A5541F97911E7C45E9575A509FF98AAB95
+:102570006FCBC7FA8CC76451AFA8FE451ED667164D
+:10258000E589FAA4EA622BC2ABC9947F650DCA99AA
+:10259000FC80690BF1E5CA26B4AB715F81A43B8274
+:1025A00044C7A60C709BB07FA0A9C45B84F500D281
+:1025B0002520DCEC526E13C1D9FE3DF036E32A52E1
+:1025C000D302138B70FD850BBAD70A7C560F998FF7
+:1025D000FD3FEAB6B2DDB2CE160C129E90DDDD4DA7
+:1025E000E5D1FD7DF4D8F716D3F3C786829BF40BB3
+:1025F00078E462BFABEF7ACC0EE0FA52941B14FF82
+:10260000C0F92A69BE00AA2799D6F5732944F05F5C
+:10261000D93493FD81DF16F8A717C58E8FFB90265E
+:10262000D3BC42CF8127B798E03679AC7F368D7323
+:10263000D485F2358DDA051EFA2B571629B5346E7E
+:10264000FC7373CA17D72EC37996238D909CBEA6B0
+:1026500028F0351A77B93932A2189FAD4E79C7C61E
+:1026600074A1207D927C207EA5FD2E467A24BADEC0
+:102670002FF81539C0DD6BBF227E3DFE9E6B17F92A
+:10268000848893F07FA5F383CFA0594DE35FCDE31A
+:102690004B3D8B882E3F497FD5F627E6CBE182EE76
+:1026A00034B9B5FCE9CF997F9E324350D2FC6388A0
+:1026B000E1BBE54F2759C83F5CFE1708A5E0FB15B5
+:1026C0004F3EDC4CFE4E39FAFFE4272FDDF373E674
+:1026D000B727495F22E896FFF753CFDC477C7A693A
+:1026E00012C7A1A6BD7A389FECA0E98723CD883612
+:1026F00038FAD41BC304FDEB7EC9DF4D67A3C7675F
+:102700004AABEE207CAF40FCDB71BE15A6A0A85BF7
+:102710001D6E95E59EF093176BFBF818BAB72C6009
+:10272000B9A21E28A7FD6449C0F23124FC0919FF93
+:1027300011FFDF7238B496D609D21736923727D0F8
+:102740002FA67DDDF250BCDFD173A09CFC6EF28B16
+:10275000719F4B3B8DEDCB63F543023FF98E222DEC
+:102760001E960339B4AF5FA23FF4C7D134EF823471
+:10277000B20FA7525C2181BCD4FDE3DDC9D55B8AD1
+:10278000D85EEE94881F2A2C89FB5F57A8C5793440
+:10279000FB7FC5FD12FB712BEE1F348EFD648D5F38
+:1027A00021EC65FE7D94F40AD199FC021A19643F6C
+:1027B0008A35C3B6414C7337B59AD88FB14BB77AC7
+:1027C00049EF4F7A70C8CDDF65BA49754316D5A772
+:1027D000CC7FC8C3F655908435FA556C673E9ADEB7
+:1027E0009347F33F9A2E838AF33527F5E4919C555E
+:1027F0009F727849EFC6AFFB454DEEE587276F8D99
+:1028000078049E89CF739F2FDF4A783E867C4EF8EE
+:102810005BE11A33049C64375C9C15C1B259B3D395
+:10282000731F1A97568F70F1D17A63ECEAAE835713
+:10283000A490BDBCD7E24F7163BF6387F20C7E509A
+:102840007C591246E4140FD0FEC69CFC4002B8EB43
+:10285000A56FAB85E1A5D3ED2F1B15F8A395F0511E
+:1028600029F6A1DADD761FD15F6806F9932BBE0940
+:10287000EE36ECBDE2851F373BA8BE1E989A8FD17D
+:10288000FFA8FF07E610D9E33F4C99786725D6F7F4
+:102890007C68117E8AAABC521863C7DAB3CC201BAD
+:1028A000E8B55B5A4AF298E81EE935494E06398682
+:1028B0001E530A320C759777A8E1FDB4B23C437BF6
+:1028C000BA32CED05E0A0D9100AEA7244B7287704B
+:1028D000C5836A8B0CED76A4EB30ADF3536147955D
+:1028E000E13FA16F836C0F5544007E847430F52363
+:1028F000A39D5516E9607F33E990C51007B09F226C
+:102900000EF53F3A7F0D87E1C45F48FF5E9263C7D3
+:102910000E89B893ACC173458ED0CF2B5E90D80E84
+:102920005CF1A199F5C431F0F6E287E4A3CE77F12A
+:1029300070CFF41BE13C64BE11AED901235C872D3E
+:1029400036C235276884EBC806235C7355231CF315
+:102950005BA71AFA8FEEA836D42FDA3ADBD07F6C59
+:10296000A8DE501FFFD05586FE133A171ADA27ED5E
+:10297000BBD9D01E4F5793C32B0CEDF6D4D799AECD
+:102980000E205D99501F143FFFDD38BAB030DC4B8C
+:10299000863BBDA118FCABF88FF05FA1E525A680B2
+:1029A000DA4CFC78AEF03FB518F13F3E8A7F5DAE61
+:1029B000F6C7A73A7E0769FA1AF93342783F569666
+:1029C000C2F4F2F2F3C70E2940F84F8522DCEFDCA7
+:1029D000E9228E22C9C156A2936E707590FDB9CEC0
+:1029E0001264FF4545B3F00152CA71FEE6D7CAD062
+:1029F000DF8C59679D92049698FD4E0E771AEAC5B2
+:102A0000CFEF33F42FE90E1BEA930F8144FAAAE8C3
+:102A10004DEF335496BCA770F8ABF483E033549673
+:102A20007F1ABC9DF46FBC9F7B99DA24A5E1A2A616
+:102A3000FEA3F319346BD03F1BA192DF1BB935D530
+:102A40006B1A8AF0487EA799FC6F403BDA8ACA0865
+:102A5000BA7F43C884050EF1FEDF932E5E43FD4D21
+:102A6000E89F13DE112E0564EF3540B297E0427601
+:102A70000BF961305BD8F36B4D2ADBA349688F9269
+:102A80003DD25CE5677B79160487D3F32B4059432D
+:102A90007C2799D17EC5E7C72F0AAC2C2E118B2538
+:102AA000FAB9FDB8CCFEF774F2A719980A90DE3B8C
+:102AB0004ABFD3FA207CA5427110D265B8FECD6D15
+:102AC0004F5EA952DCC903EE08AE3B204006EDC5BF
+:102AD000811F14A31C3E6272AF2DC6775F9EFAD78A
+:102AE00011648F34150BBBCF2E21A49006862C5079
+:102AF000809EFF2047595D9C198DB3F4473F7A3C77
+:102B0000538F6FEE690C7369717B25A2BBF8B863B4
+:102B1000C4ECAE994CFA6F8589FDCEBFD2E2CA797A
+:102B20009E5496F30EE8B6A7F392D9FFBF46C39B17
+:102B3000D9D1BDE67BF8DEB541616F2D3479D95F1F
+:102B4000BF25EB238EA3D82513F8C81F4A2BDC25FD
+:102B5000E22F7ABC6498742676D6A9F67B4BD6878A
+:102B60008678153C3228617C3D3ABECAF08DD9E7A3
+:102B7000F6AD1EA1D7C8CF3FB23EA71A5213CDF370
+:102B800009C7AFAE091E34F0C5750D6F19F8E07AAC
+:102B9000F55D437BC4D363A57865E4F1EC59145F1C
+:102BA000FF78AFBD94F080F87FBA38265E17593FA2
+:102BB000BE06269ECE7EFFCAEB38DCD8CD78D5F790
+:102BC000FB4EE39B5C8F3446B88CDFAF1E1FD14BAE
+:102BD0001487AD64CFDC2EA1BC207F97E485274607
+:102BE0005E001490FD7FBB34CE4BF46EDB1FFC09FE
+:102BF000B5F734D9DDBB7C1C1FE1B84903D205D938
+:102C00000DE014EF2FB439D80EBDDE27FCE9C35513
+:102C10009F5D4BF66B2EA47A5106127FFC9EE22636
+:102C20000B4C69ACFFD7661FE0FA7BEB41E48D16D5
+:102C300087EF277F75796AAAB08B15EC8FF5A319FA
+:102C400066AEFFFAA2C0FBCC8F8561CE6F2C1F222F
+:102C5000E279E0898C203EBC4DF67F58CC7EBC3BAF
+:102C600040ED8B33D0DF46FAFDC0AC4E34E1FBA320
+:102C7000F7645C6541BC7F90AC7E42164D8E2FF5AB
+:102C80002AF2333FB009FE9DB0E7EFCCAFEF9924B5
+:102C9000F6CFD5274C1CAF0167C456877ED8E69186
+:102CA0008113347F8715ED49A7785E3F211A973D40
+:102CB0006AC592F83F49945F148B3CE4BF8A85FD56
+:102CC000AB97430866F87C8256CE94DAC750FCED89
+:102CD000D8363B90DCC2F915F2B7D4A7441C7F70FC
+:102CE000867F0908BCB8D7E17A3DF9F271E23F8FDF
+:102CF000847E2DEEC3EDCBE571F5782E39B0A9D8E1
+:102D00007EE471FB4EC25FEF7A0F8978D8C7EBC7BC
+:102D100073BC5BA713B7862FB80140B40FDB49ED36
+:102D20004B5F38F20EC5E7FEA338E0F1E1F80BCDBA
+:102D30007229C9C9A5A95D1CA71BE393F93D5C2FA6
+:102D4000EF17E5560BFAE2B0D411E1B8DEA9E2F7CD
+:102D5000FDEDFFE36F766F29E478B53C91E48A3EA0
+:102D60002FAE638C2F26CEAEAF233ACEC0FCA3C7C6
+:102D7000A1F5FA9FEF5F3746CB235CE74FA097A7FB
+:102D8000E9746C4D1CF79FEF13F88DC74FD145C107
+:102D900010C7F3DCE06EC6FA6C0D4E1F5F89FBE1D5
+:102DA00078883299F0BBB4DEE92538EBE30FCE80AA
+:102DB000C0CF079867C6587F0DEDFFE6A0C813E89F
+:102DC000ED487F22CEB93E85E975E9D36FBDF33D6D
+:102DD0009CE5A69F4C2826FDA1BF1F0F6784EF1816
+:102DE0005ACF4249E4CF10BE75347E7C7EE06CE160
+:102DF0007A34A79BF5C2D19DDF09D1FA8E6683DBB9
+:102E000084FCB8F4C95FBD699A4874E20C4B58C29F
+:102E10001E63FC2B5E4FB9217035C9113BCA11B23C
+:102E20006FECFA7BC32D86F766672937FA585F2B5C
+:102E30001B481ED955E1AFE507AAB8BED22AFCB59A
+:102E40003DDD6699F87B8F0542A4C7571ECC50C95B
+:102E50007E5C8976077B3A05415E2F24A31F949EF2
+:102E6000C06E307965AA57A6056E277849DF98713C
+:102E7000DF23B9517F54D797259ABE570AAF6BA667
+:102E8000F17D5A3C10ED4C8E77964340B323B43815
+:102E9000DCFA031C87D0E5B60DE63B28FEB32E73A3
+:102EA000A183FC431987E5F89AA73E0D06B023D706
+:102EB00034A2A4BD285AB7F6E3C7EBE703788D83A5
+:102EC00069BB40C21ADABF7A20D24276CADC177BCD
+:102ED0009EC5B26DC28391D5D4F6C54989EC4887A9
+:102EE0006607703198D629DEB30D5F7BAB09F567B5
+:102EF000B2D7024762F4A00339FF4881362FD903C5
+:102F000059BDEDBF25BCF5B78FF3556E40F81C19C0
+:102F10003D40BBCDBB3811BFC7C32B49C36F52E186
+:102F2000AC0FC9E04D82987DB3DD135397A2F02218
+:102F3000D54DF8B746DB959309F297675A12DE8FA5
+:102F40005863EBE183EF19EC8110AFDF6AF183176F
+:102F5000F767F360BBE11C86AAC5C191804B357A47
+:102F6000603638F5BEC82EFFBFB52F1AD73FF8829E
+:102F70005E9F7A81AF2F7C81E317EA2E6CF829756A
+:102F80001736FCD40B7C7DE10B1CBF507F61AF4F2B
+:102F9000A9BFB0F1AB5EE0EB0B5FE0F885CB2E6C28
+:102FA000F829975DD8F0532FF0F5852F6CFCAA6CAB
+:102FB000073A2B81CFCDA6B7984374CE46AA0973A2
+:102FC000DE384F058E47A7AE07CE57ECF20A3F4AD0
+:102FD0008FD38FA52164F45BACEE6CF2AB77B5DCDC
+:102FE000557D038E73220B174FF9FC9CD7151A677A
+:102FF000E74CE0FC85B3E5FDC314FFCA85B0379C00
+:103000004B713509C23176E935C11408C7F813751B
+:10301000CA2043BDA47BA8A1FF8D5BF30DEDDFECBF
+:10302000186F68FF466BB1A17EBD5A61E86F87DCFF
+:10303000B602CABBB658BC9407B3D0DECAFBC20DF9
+:1030400076DBF83D05FF911F938B9E50EFB8B88F4C
+:1030500074D56618D719D77EAA7C407C3EA1A654A9
+:10306000CB27F47EBF20DE07B72761DC53CF27E8EC
+:10307000F81C6349627C6D5245BE69DD4CE147CE68
+:1030800068719B286FA9E36F3CE83F6E33F99B0F93
+:10309000350A7F5287437A48AD667F74B7A08FB1F7
+:1030A00035E6109DC39D293993699C1092B41BDBB2
+:1030B0004335F59CD7D4E9607CCDA239145F6DCA45
+:1030C000199C4DF184DC1A81F7E5FB8CF8A6B42D30
+:1030D0006D29FD90C4EB4C6FCA28A2BC5D1FF83F60
+:1030E00022E0A99F334F8F83EFD89011FEF1F8397A
+:1030F00053F8AFFC92F0B7D5CA5D69140F5541A6DD
+:10310000F8CB733963CC0C87562FE3A116BB113C67
+:10311000735B81F33AF174D7DE08E19A183ECDF57E
+:10312000861582EF4CA9B09AF909DF1D027C1A942A
+:10313000F3EC3B5B459E16CB641A1FF6C943099F0F
+:1031400021B59ED7BD6BBD2D99CEED7DD664063AD7
+:1031500017BF2B571E4AF9AF5D4F98E6C79E034233
+:10316000ECDBCD59BC0FBBB98C4B8B2815AD048B58
+:10317000680F4B541FB1CA1C874F55A2F6F4DAE40E
+:10318000B8E78A89FA6F28CD63BF344DC930E0CBE8
+:103190005A66E46B04E32B85280747D2EF32D195BA
+:1031A000A093D06B526835C7517A4C8B896EB4733B
+:1031B00015E96BEA81F24E4D39DF9ECF72AAC9C67E
+:1031C000708755822EF4FC9FB555D0613CFDB8BC8C
+:1031D00046FAB14AC34D228F25F8445FC74E459B3E
+:1031E000375B0295E59B6D28F181356E3C3B0949C3
+:1031F000922B1EC17F4EA8077ACF5966E77C3548CF
+:103200008719FFD629008362CE23C4AFF794EBFC65
+:1032100092747EF01CC9999D35E2BCEABA35E27C15
+:10322000E389E7859E98D1EA36B3BC0199E50BD2D4
+:10323000C1DCEC52717E88E0D9AEC91B3BD4A551EC
+:10324000BB4EE7B3A4E155B1748E72E44517C9B320
+:10325000172C1CCF5C6795AB6FA0F672BB7B35C398
+:10326000B3B088D6ED6B41B943F1C26E01275D5E04
+:10327000C4C3AD0862EAB9443A89E1D89F3EE893F5
+:10328000FFD7E1588A70CC3F7338DABC42DFA6978B
+:10329000097DFB5CCEB7F955F721717E265D0106ED
+:1032A000DA7155C07596F45198E4CB2605E50BB656
+:1032B000D76AEDEE32214F7438E78925F6CA934D6F
+:1032C0000B2083F8DE4D7076125CDF67FDDC512247
+:1032D000E00C10E13C67AA22F8649D15BC148FED48
+:1032E00028777A292E98A768F06DD5E065025322D9
+:1032F000F8CA71F04D8DAB9F297CC74CD1E03B18CB
+:103300004ACF06BE9B525205BF8D12F0B13A237CC4
+:103310007EB935D7E25D8D74D8958BF0C6F6D6D7D9
+:1033200004BC7FA8F55F3301B8DE9AB9368BE1950E
+:10333000BB288BE478ABB543A57C552BD11F9FF3FD
+:1033400014E7BF5C1A5DCF44FE5E88EFAF45F944D9
+:10335000F9C6D4B28083C66B2DB480C4FBDFE64DC2
+:10336000B47F87CF669083C3161BE19A1207C7A468
+:103370002FC9FF7553BE1CFFDF49BF62BF75A39104
+:10338000E538DF1872109C6C657F71101DB595EDE6
+:10339000E2BA0CA1D63CDCFF1D4E6167B595D50F96
+:1033A000780E6A972617428D0E2EB737BA51330121
+:1033B000DCD598C5F58E4699CBF6C6022EDB1ABD34
+:1033C0005CB6369671B9A651E1FE527951157F0F60
+:1033D00036876915DC8E4FC061EE3B5F7EAB518F47
+:1033E000E5AAC906B88F6C30EAAB41B5467D95AE0B
+:1033F000E419DA5DDE7186F694822243BD704AA03C
+:10340000794A099D8B9A6A78CFE6A936F4D3CFD151
+:10341000B59589EFA174B8E97AC9A9F1F73A6B2497
+:103420008BE2D8CE32C19FEB35F8B56AF04B5680AF
+:10343000CFC5D80E49DE1010DFAF65FABE03713874
+:1034400004E1D295738542F6419B2CEC742B887372
+:10345000BDB62CBFFA0D7C9E847A8BF2B6B6F929E4
+:103460002C0FEEF038BD748EB6AD6C859BD7E3158E
+:10347000E765DCF82F519C3FFEFC8C6394F1DC8DFA
+:10348000F514E7171F9C12FF3DAF46A7951909E5F4
+:10349000471FF9DA9B5FD96FC8AFB46BF9157B3F53
+:1034A0007248D74F7ADDA9E55760B82F61FFA81D94
+:1034B00025F2071B292E1F937F705526FE7EF3B938
+:1034C0002912AFF3E01499DF7359BA81E474AACFDB
+:1034D00018B7772967363FFEF83C8349FE02CBA533
+:1034E0001B92030789EE9447847D92345CE86D1B40
+:1034F000282ACB2510F90EEE6FA252E4737AE50B61
+:10350000898618BA73F6F16745DE833EA320FAB1C7
+:1035100044DF3F27FEEB99962D8D03E77F5AFAC9CA
+:10352000FF7C3E45FF3E0C7A3CA500BA6B8EF0FB5B
+:10353000BC1FF885095E2DA64DB57964E7F92C5EB0
+:10354000C4005479E57D948F5CA3A4B25E5FE395DB
+:103550003B890F8F2B4E2FE16363610D59F090343F
+:10356000FA59D63F2D74BC26060F7ADE0914A5BB86
+:10357000468733E9DB82DAEE9A18BA583F610BE7E7
+:10358000EDDABEFA20E7F3DAE6FE94F3796BB3677F
+:1035900015505E38C93BEB43CEA3424C5E8AF447DC
+:1035A00081317F77F2A4A8331C28FEA0E5F9C0631F
+:1035B000CCE359647F743D70EEF104C385FE018B4A
+:1035C000C2DF13F4A56FC1D77ABFFEF940D5BF2B78
+:1035D0005D4DE77F5B3D428EB682F7CD00D55F92B1
+:1035E000BCAA4CCF8BDEA4F3A46B875B182F6BB304
+:1035F000EA5B85FD2EFCA556CF6A961BF1FA9ACEA2
+:1036000063C6CA6B3A8F192BCF5BE5FA01F5717669
+:10361000C01CA7EF8DEFE7048D7A477F2F29EBD2EF
+:10362000576B62CE43ADB7F81D242FD678EE320526
+:1036300062E8F9474A606E5949B46ECD9ACBEFD92A
+:10364000737C09D7355B51EACB3279FF03DA019BF2
+:1036500035B9B845D32FA7DAE756ADFF8FB4FEDBF7
+:10366000489F5F14C5CF98516393583E5F22E43161
+:10367000C13C76DEC2B2C0E2D87D10D3F4C205E907
+:10368000744CE1B824B2379A2F294A223CDD3D67B9
+:10369000E0F5E87973BD9F9E278DCF9FDB3C6603E5
+:1036A000FC7795897322CFBA1655FF08417377AD21
+:1036B000A0A7E64B845E1EF388D8475F3A34AEF786
+:1036C000EEDA81ED9FF8FE1439ECA513AE67C4D590
+:1036D00087C6F5CF8B6B1F17D75E14579F1AD7BFBE
+:1036E0003AAE3E3BAE7F7D5CFDAAB8FE0BE3DA6FDF
+:1036F0008E6B5F1157FFAE119FBEABD212C1311E50
+:103700007F7ABFD3C5DF6F7D553F23FA1E03054C7B
+:103710002F3ABD9D2E1EA276AE97E9CC56366E1F6F
+:103720009D8FBB0BED2BB287EEAEAD760BFB22B0BF
+:103730007AAF461FA41F2C5F15F374E59426B13FA2
+:10374000ECF418E4C8A9F06D820C63BB12637FE649
+:103750009D7B7C9F9A3E439A7E1C78DD3A1F174ED4
+:10376000F1BF43708790F02F75BB76A72AF867A743
+:10377000BAB07A33C9DB56B3882F6BF79D64D0405B
+:103780001C070F684A3862227CB712FEEDE4070876
+:1037900079B25193271BC83FC0E749A3825B29AE8A
+:1037A0009B7C888FDFC07A5FD1DF16127ECA4B7791
+:1037B000D2F7611B26943DFC63ACBBFE2141B818D7
+:1037C000EDF3896D0AD92C1D4A46129D174A3139ED
+:1037D0003AC93F5C53DCE11F85FD36EEFFB0F319BB
+:1037E000C4B39C65F326615DB6F49888DEA0D0CBA7
+:1037F000DF9DE13A55F2FDAC953D8D89CE956E9CED
+:10380000ED369173985E2B9B557A6F4AC0548EF0BB
+:103810001BD90A663A479CA186F9AC4D75B9CCF222
+:1038200065D713C850BCDF9E6C82D767EB6DFBA9D0
+:10383000DA3F3E40D2E2736755EAE3A409D2A01F03
+:103840008EC3C816ADAE6EDB46F78F3825511FFF0D
+:10385000C48E05AB0BA3F5EC27760CA77A7BF10899
+:1038600013C9D3744F6AC27B60A6970BF9B96BFD7D
+:10387000A2918101E84B267F6D0896855A4934351F
+:1038800005CB515A296BCFB3447D0AC10DE12937CD
+:1038900068ED1E519EEB79E2C757CADDBA9D38D458
+:1038A000CFCE3F143A071BECC5E9E599FDDB8B68E9
+:1038B0001E739C7687551E4AE70477ACB701DDEF8F
+:1038C000B02307C477C66B6C7C2E142CEEA157B8BE
+:1038D000A2EB0EAD19CCE7CF432630C46F2DE5C265
+:1038E0006E3D5E6ED2EC9E2FC2F49DDE0E2D8FB328
+:1038F00003226E8AD747F1FCF0022506CF0F957F91
+:10390000BA8DE8B32B6751F5167C6F538B99E3257D
+:103910009B5AF298CE691CB28F4EAC7AC54CC1A5A9
+:1039200042E834939D3F8EBEACCEA72B8E025C76D0
+:103930006AF2F967C49F38F16850F8F908E861E065
+:10394000BC511AB89EE0924FA24D22FE91CD0E9C22
+:1039500067D993E95589F4F62DE5BDF6F8624BA9D0
+:10396000E65FC80CDF5BCA13D8E374029FE38D8A5D
+:103970007F29B53BF71D0C0FC3EADE378CF449787D
+:10398000AB8FD133AB35FA747BFD0AE1707669E019
+:10399000DBF4FEB2AD7F3B40E6A8ACBACDF4FEFD51
+:1039A0001ADE178583B3689809DE7035F51FDFB01E
+:1039B000733FC5D10A82B7560FC1F58D51EAAA3DB2
+:1039C00044434AA091C619D51DA97261DDB9F560BD
+:1039D000389BD73391C7CBD3D783F450C774E41641
+:1039E000F17B0DBF847F3A97BC689B800FB667F36D
+:1039F000FE2CEEECD8F5EF9C8974E1EC4B170DDA58
+:103A0000BE3647E10856A35FB339111C753AD5E1BC
+:103A100071ED233D6B2897B920D4FD1CC941FF5699
+:103A2000F74C2ADDA581FBE87D5F87BF99F37C7B9E
+:103A3000BAE9BAA15EF838956E4A1B613F653BE171
+:103A40007DC7AA23D51C97D907C2DF89D3877A6996
+:103A500055E2F30BE23E9C49FB8C7632D2ABB2C509
+:103A6000134BAF66CE5785347D126A45FAA5F956D9
+:103A700009FA0DA92BDC89E8EC414DAFECD6E856EC
+:103A80007F3EAA9F73954F97EBDF9343966484E73D
+:103A9000D303F17D1A78991F900FF653BF0CE20300
+:103AA000AC8F5C25333DE87CB06CDFDF0E0C637FB0
+:103AB000522EA2FBD9F4795FD2E645FA7C91DE5F03
+:103AC000B6B5E700F98A235709FA7C95EE06CB8C48
+:103AD000D219FA8FBFA17E3AFDC4EFE3D71A5DB8C1
+:103AE0004BFDAF121E176D0DF278C83FAF31FF6C62
+:103AF000ED0E2731CB29D5B49F1D1DE0A6FDD8BF03
+:103B00005FD44572E1448389E17A5D61788D19CB98
+:103B10006B468195AE13AACB42B2C9A33CAD31EF3F
+:103B200037BAC3883FA49F3FD23C259E804D04AD49
+:103B3000833696A7FDD04554EFA93AFC57C5C9DD99
+:103B40004F0694BBA739EE774B954F699CD35EC760
+:103B500069F6D3E34D7DE3A6E39289AFDB5AEBF53B
+:103B600038552DDDB7B38BE2A608D735AD03DBABF7
+:103B7000218D7EB76BF47B971637EDD0ECA23B4ED0
+:103B8000376EBAFE5815FBBFAB80E340AB53269AA5
+:103B900012D14DAE6AE4CF910DC9717152A3FF9A53
+:103BA000AE18E3A6F49DE799C44DE3E3A58553025F
+:103BB000E3A796F48D9B42E45D839DB9A655C805A5
+:103BC0001D7E636A6EE2F8E72E8F3914FB7D845EFA
+:103BD000B66B70D3EDC936821BC3B3408B3F7B35C8
+:103BE000789669F0ABE5FA18B2E23C1C471579F714
+:103BF000B177CD5F4870CC02CE1234E53C9895E8A1
+:103C00007C3D64C5D8D148FFEBD66B79B42CE0EF8E
+:103C1000439FCB79BD369FF29A59668ECFEEF2EC78
+:103C20002FF831D79399EFACA07614E07C63DE9B3C
+:103C3000AFD27CBBCAEC6E711F07A4521E48CF4B9B
+:103C4000E8F99CB64C91CF711568F99CB8F9ED7004
+:103C50007D7507CD5F20FC977EE9D9A7E523B43CAD
+:103C60005046A1315FE188CB57C4E72BD7AD5FB891
+:103C70007F9788B3B09C1E73C3D864BFABEF3CEE94
+:103C800039463F6EDD58DD9F7AD091089EA93546B2
+:103C9000BA6CD3F0DE9C29F211A71A1F2A930DFEED
+:103CA000555BC1E9C513F47EE48FBA13F48FF7476F
+:103CB000CFC6CF75F3F8C63872023F77C354115799
+:103CC0006179B26EBDD87F6F5C4DF3AFF47346FA85
+:103CD0003856CD9FE37A6E545EE9F9B0516E1BFB06
+:103CE0006BA3B47BA19AEF4D09ADCEA5FCDADC1E27
+:103CF000CA478EDA2D71DE7D94D33F94E2AA5DF738
+:103D0000CCE2FC78767260C7D498EFE076BBBE9DBB
+:103D1000C579032DEECFF7E3A0FE533715772B645B
+:103D2000F78E05BE4F27392E2F107F0F4E9FFBD8E1
+:103D30002A841ECBBA1A12DE6FF2BBA9426F46E587
+:103D4000AE3F59F8F1B3194E0F74D4270BB9ABE855
+:103D5000F501FDE073256F1FE87885BFEB39E103BE
+:103D60004DDEFE0C2E4479FBBBB2C05B09E5ADA570
+:103D700087E5ED235394B709CFD7D3851E8487EB0E
+:103D800012DFC3E3AAB850F1F098C043A18E873B7D
+:103D90002091FF7801E021B922111ED0BF2278A91D
+:103DA0003E25A52293E2A68A93FAF5E2E3EB89F990
+:103DB000A2E23CE36393868F3BB5FCED460D1F1BEF
+:103DC000081F76CA570A7CACEB838F23021F653A23
+:103DD0003E9E3E2B7C64D46418DADD95467CA4FAC2
+:103DE000F20C7567A1111FC9A38A0CE35D5F218BDB
+:103DF000FB90864F35F4EB8B0FA35F10A0F706F016
+:103E0000B38607BAABE81BABA1F33BBB483667F9F7
+:103E10003BAAA8D4F7B92DCEAFD3CBEB35FC65CDFB
+:103E2000488CDFAF69EDFF2E57E656C4F2E7571214
+:103E3000F3E7E59A1C0D9429F30CF47369E2FE573D
+:103E40006BE37F7D8A72556C7FFCD92CC5D8E5FD6C
+:103E5000EDFB8664E57A7A2F6B86CCF1D4DD4DA933
+:103E60009C3FDB9D24F2656A93D3703FDD48FA0DD9
+:103E7000EB59DFF8A24BA57376741F105A583B6FAD
+:103E80001D9CB70E9B76668C594D70FC56453EAF17
+:103E90002B7F89FF6DCAF328EA51933887B480EFEE
+:103EA0003532850799E83E2C70679C561E09E599C6
+:103EB000B8BF6D2488EF8521C87A50F2433A7D9FC0
+:103EC0006C01BFC89B537FF11D216F3E05C25C771B
+:103ED0004184EB699ABFB7AE2297C74D07D92480BA
+:103EE000E435911CD5F9D4E10932FD7B1ADCA6D565
+:103EF000E4D3599057C91F740EE7EF76A11A54CA3C
+:103F00006B99C0C1F6A669F381CF395FA77F67F8C7
+:103F1000C220F19DE169EEEF74FBB5D0FD7B9EE818
+:103F2000FD7B2D9A3DA0DFBFA75607F93B7275B503
+:103F3000DDDDECE9FB1DF9E6A9819D44877F4F1A81
+:103F40001112C9E6E0947AD7391DFFFF9CE7F19F73
+:103F500038CFE33F47FCD0DFF81BE8D772CAEFF950
+:103F60005FA07ECDAE52B63BF5321E6FB3D1FFA738
+:103F7000F54A8E5787BE37286ACF390F9BD82F6AEC
+:103F80003689F367EABB26B6BBA050D08153868240
+:103F9000DC49D1719CDEE048117F127198A6DFDF09
+:103FA0007E11D9DF3F4C991B49C3F15E3E28EC3F9F
+:103FB000CB8CC836BAC779489ACDBB0BF9EE0E6DDB
+:103FC000BDF6F22977DE86BFD64F376BE71CBC976C
+:103FD00014F1B9A53911B21F5DA516997206CEB8B4
+:103FE000FC66BBA583CF19B7EFBEAB6A1CD039E521
+:103FF000E7DD2DD6BEFB746AF9CDB1526239F89770
+:104000006949422EF98CF7061FABD0CE41A5422A52
+:10401000D991967F2B6989CE05E8A53E7F892752E5
+:1040200043DF5947E8B236C47349595D52B287CF6E
+:104030004774137CABBD6107D9BF0F2F0CDE14FB97
+:10404000DD797B19B8C88ECF9D2ECEC3DEA3482E56
+:10405000BA47E3BE8885EF17BF6FC963EB53B0BEA5
+:10406000EFB0D94DF068F7BFEB4CC6FAC3382EC994
+:10407000BB97778B7B26D505101A8DF06B27EF1237
+:10408000EB7B15E073C0EC90956A57F221FCDFB929
+:104090003853C01B8275743FE7A6948BF9DECA9C27
+:1040A00079222E3C4B3ADC45EFDF576667FCE56B27
+:1040B000E7754C6A1DDF5B99B9C0785EE7BE95DD98
+:1040C0002AE1D75D6E77D33958909CAE89F8BEEB64
+:1040D0002766905835F6F0E4B324A75897579CA369
+:1040E0007B580EAB74AF7126BED7E4E6DB110DE74B
+:1040F00082F66E15FE69DA64A717291DD71B776E45
+:10410000485F5707AE8BEE37768DE2B844C63CE386
+:10411000FAD2E2FC06675CDD5BD97B5FCF18C2F7A1
+:1041200071FFB78B5FE556AF9CC8FF6C6F84EE9A4A
+:1041300098F309CE7EE281975F2CE8DA96FDAC8396
+:10414000EC94E3FED73D848397FE75E03D3A2BF770
+:10415000D2BF5FDCB31CE1F39BCFDFDCFD28EDAF0A
+:1041600061C32B44AFBA3FC66730713DCFD5D91874
+:104170006EFE5AED3CA7AFEB59AB8FDB39CFB47174
+:104180007F12B78FAD845012B68FB528D9DF24BA0D
+:10419000EB96BC4D320D22CE23EAF8DF78ADDF047A
+:1041A00013088F7E89EEBD9829BDA4B8F0FD7B96DB
+:1041B000804CF8B72DE9E4F3EABE95E2BCBA4FA90A
+:1041C0004BE2F3A6F3CC7C4EA4A9EE8A4B46637D6A
+:1041D000CF25E21EAADA95CA953CBF22E825ADBBE1
+:1041E000D4BC92E8325BDCCBA49F372D811EFECE7F
+:1041F00063ACB7B3CB46F266010298D6D7AEE14BBB
+:104200008B1B94F8BA55B2275D5E231E33E2F0167D
+:104210008FD79B743C8E85B18447193A92491FDE33
+:104220000FD049F707DCB3F2B12BE95CDB71358DB8
+:10423000E1D51F3FBF83F6AA7211DDB7E2E0B21BE2
+:10424000ED552AF7A0BD4AA52B5875F54A5CF7E352
+:104250006FBCFCFCD771BAB94ADDA57C544BCB7F4F
+:10426000012C1A518D70BD96B857D4B72BA300FE00
+:10427000E0930CF58D1E4BF4DE7FFCD595ADFD1D56
+:1042800000F5C4764A40B66759B47C9BA8CF253F59
+:1042900024A67DEF1C63FF8AFD31E357E27A97DAAB
+:1042A000B87D63E5A2EDEAA868FBC7D3B03E1CE089
+:1042B000A0663F5EF380D9BF2B817C7BA952D87169
+:1042C000967F834A72ED5319D8BF97CC0ACB77C833
+:1042D000B3C889EECF03407918EB97CB46F95AAAB9
+:1042E000F185C55F055A9E0CBED0E30FF8F3F8EFD9
+:1042F000E6F2BD4B6BF22D7CCF10EA03EF40793B29
+:104300008BC7F297D8FBB97EAAD3C168184DF37F4B
+:104310000A95BFAD623E88B99F01D73DA3E399617D
+:10432000CB711EDFE1648EA74AAECD29344F4B63BB
+:104330002BCBF31F29813D9531718A96F445C52415
+:104340005FF4F332D1FB8DAE309FC9FDF65D75078A
+:1043500080F4C2A7485AF601E8B0A571DFEBB48E2D
+:10436000B58D9D5C3ADD0A0B1BBB25C8719FD94AF0
+:10437000E0C5CA12BA570FDB63F8C4EAC6F70C7E71
+:1043800087F1DE4DD91D7112DCEF29FBA393E66F97
+:104390003F24F8FA9E43F57C8EA1DDFB4A12F1CD55
+:1043A00071BAE0F14BF0894F39C8326CEF1BA9D7D5
+:1043B00010FD3CDE9CC676C5CB2BEFBE8AF8E7BA73
+:1043C000EF5FCEF0EEE51BF5DE11D585317CA3DE87
+:1043D000CB74DDCB375ABD7FBEF944F0452FDF8863
+:1043E000BAAF100CF597E718FBF7F20D8D8F7CF143
+:1043F00070959DDB3F7DF25E03DFFCE1A97B8D7C48
+:10440000F32DE49B0472BF789A46DFE7986FFE3184
+:104410004DE3C7F3C437E9D3B473B55F9E6F864DE0
+:104420002B391F7CF3B8E96CF866585FBE993CEDF8
+:104430002CF8A6DD1DE67375EDF3CC09FF0E487769
+:10444000A5C0FB8C0581EA0EB26B14714FDF4C697D
+:104450004EB6CF437C26D15DD1A83F853E7FF99AE9
+:10446000DEEF33583FFB353C6E2684929DB454D02A
+:10447000CDAB8D22EE3B5372CE5C4A7A97BE23A021
+:104480002BE3E698B8DF65A8F765B20BA1D3948952
+:10449000F3DC83EABD43A62D07EB46F3F861B6CF04
+:1044A000F2B53C80532A14DF3329E2EF5BE8DFC525
+:1044B000CC9B63BC4776C829EC261C2085FC18776A
+:1044C00099F87B2757EAF4D3AB7FD10EC1F5750F6E
+:1044D000B7319DDCA35C36609CA8CFF96A5F306180
+:1044E0007EF2C0349320464559342D93E4CBF664D4
+:1044F0003A2FF1B8047C4E6741F0E75712DFB95408
+:10450000216FDA57FD89D292B067E6D78D7A5A8D3E
+:1045100018F5B41A31EA69ADDEAFBC81F78D7A5A6D
+:10452000ABF7EA69ADDEABA7B57A54DE440C7A7A14
+:10453000F55391ED6A4CFBCB54AF3CB59EEE9A76A9
+:104540007EF4F490F3ACA7779C3B79F3F0F99137C4
+:10455000AF9F95BCC9E92B6FFEFB6CE48D6B5B973D
+:104560004AE99945FDF0C137353D73A042F9158DF3
+:104570000F65A717AF89A7AFAEBA456BE9EFC77C48
+:10458000EA15FE5F7FEFBB1A7EF17A4B8C1FAE7F80
+:1045900097E06A789C9FDFB8ED20C7634FB95EBA99
+:1045A0000834B3AF5E45BBC8C1F4EB35734EFC6C49
+:1045B000D7D13E4FF05BD9B4C5CC4F7FD7E28FF156
+:1045C000F66F579DCDCCF3950939DD9F3DD4DFBC07
+:1045D000DD95B2E1FB0C7DFE78FA45FAFC37C9297E
+:1045E000A4470BDDFF7DBC1BF8EF51FDE7B12DBFEC
+:1045F00056E40B4A2F7A283470A6745AACE133C1C2
+:10460000BE732E2E399FFB3E67FC597C36FBEE9A1B
+:10461000067A5C3B7EDF95E777DFE7CC7FA8BFF8C3
+:104620002CE4D24B95BDFBE6EF5232B47DDFF3AF05
+:104630002BDEA5B8C63DFFBEEAE714D7B8EBF38280
+:104640009D14D7D0EF8F4B83E88FAC7F1F8970719B
+:10465000F9C5772519F362BE2F02F6EFA3DF9F900D
+:10466000BDE1EB6DFF7F727F1CD9274712C4197B18
+:10467000DB6DC6B89E5E4EA53FAA85F4D56EDAC442
+:10468000F1887BD0AF6A42BC75CD13F18876B45304
+:1046900058EECC2B1AD03EDAD3A870DCA9BDD1CF0E
+:1046A000E59D8DB55CEE79755905C95DDFAB4B585D
+:1046B000EFF9BCFEAB7F8C407257BDE7A4E7777A79
+:1046C00074FB44D82F6964BF60BDE3E9B61DB1FE39
+:1046D000CD90E939AC0FF4785547568CDD23C7F8F7
+:1046E00051582772E9F5A3A83E2AD6AEC9613F6AA0
+:1046F0002FD93558BFFFE91C835DA3CFB3D10C8BF5
+:10470000C9AED9B8DB5C9BC8AEA9A84CEC47619D8B
+:10471000F3200E9783BFFF97B4BFF315E59781EDA4
+:104720009AB4E9E7D78FFAE5C5E726FED0CBC79A5A
+:104730003DF323457956932B5F527E6C3153FCF841
+:104740004CE5C758921F8506F9F1F6D9C88F8A4AF9
+:10475000B7212EFAB2AC0E9A4876FA6E3334C99A63
+:10476000FEF5907E05FEFB77DFAA92D8CFB9C70B86
+:10477000FC77FC66490B5E207AD8BBC4CCDFBBDF7C
+:10478000A7887322F7CF13E7AA7EBCB2A89E3E2764
+:10479000DA9472ED86248A6B575A80FACD922A39C0
+:1047A000CE7D5FADB073729C9D97D0FE5FAEB200C0
+:1047B000D1D5A9E2DC146EE778B57E9E4ADAC67ED2
+:1047C00087EBEB16379D5B8D8F5F3BCBFECCDFCD50
+:1047D00083F4127FDF7DAAF8F599C6ADEDD37BFF98
+:1047E000CEC0D9C6AD991F2FBF38E75AFE0E218E15
+:1047F0003E9FB958E64A7F7A2C9E9FBBEA66A54544
+:10480000063817E524FB29E6BE58A725CC7454A129
+:10481000D9514EB29F8AA374D155573AE0FDB329BE
+:104820000D4FBC1E9B174AB174F278290D4FF2F35D
+:10483000CD747E81F665F1B25C7DB81AE57382F1C4
+:104840009E6C0C1E22B8FCB2B1E110C5A9A759BAE2
+:1048500025FABBADFB1A55AE3FDED8CAE59EC60EA3
+:10486000EEB7B9712B97773586F8F99D8D0F717D6D
+:10487000436327D71FCE13F34CB584789C693D382A
+:104880007E0C3F547C80F3C4E0B93CA21ADAA7BC8A
+:10489000D96A682FE9EE30D433FD5B0DFD07D5866C
+:1048A0000CED072A025F9D9E49E71A1E32F473162B
+:1048B000761AEAA7EB2F9CEB7EAB53522DFF447E7A
+:1048C0001D11407A423A4B6F9055CE9B2F167C3982
+:1048D000A4C11BA6FA76978DF95BA74B3EBB6C1261
+:1048E000EB37C5DC47DBE5B2B1BC68CE14F194E62A
+:1048F000EF88FAF66C715E724C8DC88F340F17E733
+:1049000030F53CFC7697C89B9DF0897B3446144675
+:10491000F8928C11DADF7D73568AFC991BDC9C9F20
+:104920006F6E04ED3BC508E73B32C0EC15F7A82BD2
+:1049300032FFDD240B849A70BEE642B77A23C99910
+:1049400060AAD7ECE53F211B32531E91C4132761A7
+:104950003A35BDA3E5E593FE087CEEA0173E9F889F
+:10496000EF121A7AF87EA6210D3D9C8FDBFE7D7139
+:104970008F4D3C5CBBBEFF19DFABB4E33B9F6513BF
+:1049800053EFE83DB7D363F82E6DFBE254BE6F6181
+:1049900047431E9FA3D8B1587C772C83D8EFF625C8
+:1049A000363E87B1A3C16C263979628925A4C33B01
+:1049B000A49F5BA1FF158041BEE8DF73DEA59DEFDC
+:1049C000E9D0BEBFBA433B6FD5AE9D976DD3CE5BEA
+:1049D000B56AE765D7D2F91E3BE919859FEF68589C
+:1049E00021CEF70C07ED7CCF270C670BC299E2387C
+:1049F0003BACB0CF3409E80F1732FCE2BF971D542F
+:104A00009B1C77CECA78EE2A2DEE5E2197D778EEE2
+:104A10002AA5605CDC392BE3B92B7B96F1DC95D5BC
+:104A20005D6D3C271A4BA70854D3AA2D4D4407BDF2
+:104A30007FCF911E0EE6BF17C7FB53280F85FBCA19
+:104A4000AA15743948FBFE259DCE85E493FC0F33EF
+:104A5000BC5D44AFF9746E44E57A92F6FD9B7EBE70
+:104A6000A43F3A3ADBFBFEA5D589EFFBD7CF1FBCAD
+:104A7000A1D94F0BA62BAF4F2F89CEA74E57DE8C57
+:104A8000ADEB657FF2E0FF9789CBFF0532DED6778D
+:104A900000800000000000001F8B080000000000E4
+:104AA000000BB555CF6B134114FE36BB69923669C6
+:104AB0001649B5211536C668031122A6A59588D3D7
+:104AC0001A24875AA2F4E0C1430E39F9E3EE6D537C
+:104AD000158A92D218C173840A160AEDA17F40AAE2
+:104AE000C1736AAB281609B5F42CA87829C437B36A
+:104AF000D9264D36B5170792973733EFCDFBBEF762
+:104B000023CF41CB0F4462EC9AAC0123895AC549AB
+:104B10003214072B4581E92A4937ED2F1A526532A5
+:104B200029808BD98434F574AAA62864A7B6D9A5A0
+:104B30000FECECE2DE18B71BE05211F2DCAE13F022
+:104B4000016B49A9F42C08CC6DD0791CF83D269551
+:104B500010E4C1EDD7EBA3C21490F917EBF79F0453
+:104B600066F84F7AAF7FDC379021FF0B3A503ECF8B
+:104B7000EFDCF172DD9D284C6A144764AB0A85FCBA
+:104B80008D54A19E00C7F78381F6674F5F97157A12
+:104B900077691E3845FB73F65AF22EDD5B1B77A84A
+:104BA0008F62DCCF94FD019D4F0764C85C4FDB77BB
+:104BB0006A142A2448F533C44F4231745A75FADC1A
+:104BC000448B4E714F737DB8A97BF743132AC5F50B
+:104BD000703BB852196EDA852814BE7F89797C7BC8
+:104BE0007DB41141A42E3771D4F9BADA29FFE8DA7D
+:104BF0004AC5CE71C2C6F98A6FD94A417AA7FF6306
+:104C0000B197E393AB69B946F64812EA71C2B99518
+:104C1000F6E2087FDF387F0E605B770A59D55521B1
+:104C2000D7F44121F7744DC85D7D58C81D3D2664F9
+:104C30004D1F1312C8897C3A2488F7DEE8A9CD6499
+:104C4000B8FB7B1129778BE71DAF14BCE6791E8A70
+:104C50000BBB8E7B25F2D3C217D1258AA1E279390D
+:104C6000C1ED5FA46C70907D31A1F9D3D14EFBE210
+:104C70008D492F2CF64D99D76F6F3EB1773F77F75F
+:104C800020B36A61FFB851C74041C41148D8C0EB96
+:104C9000D7EF844BA5FBF97597A8EB50CC597271EF
+:104CA0007C7937BE9B38A87E16EE1704FEA54545D5
+:104CB000A59A3AF0EB89513C2D7515606F0779DEA6
+:104CC000F257CA836992C58BEF3F9F25BBDC868C68
+:104CD000303AE37ACA241197892BA0AC4AAA45DE60
+:104CE000BBE1BAD7B0C790CF980B6DFCB7DF37F3F5
+:104CF000CE112AA38D16A595EDCD2C30DA67CB9277
+:104D0000E0C13504D1DF3D60658EF718F101978968
+:104D1000E7F24826E76EC6D32D4F661C7D8DFAF369
+:104D200067355786E7E11F75E8B61BF92A646DA958
+:104D300092451CCB8D3957601F9CBC1F11B58EC38B
+:104D4000136BAF53239E7985FCF3BC31F26FC1F72F
+:104D500057CEB751CF5F646A81E2944DE33DE421C1
+:104D60006E183DE59940291714751E2BD3F92FD6DF
+:104D70001313EEDBE643C7FBACA58ECE74CE9D7558
+:104D8000E636E64D18613E6F7E0ECD78CB16F96D96
+:104D9000F689C1A339773A79D40C9C590327A2D656
+:104DA000FDDCCCD76C63A823231FAE9B4F47D54DAA
+:104DB00037FEDBEB603E9BF696E9FF01EF5C9276F7
+:104DC00081F371B8FFBAF1D6CED3DE7FE6A9FDBC80
+:104DD0006ACE9563E23CEE3D53FF0BC81D4E69F071
+:104DE00007000000000000001F8B0800000000000A
+:104DF000000BFB51CFC0F0030977F3A0F2BFA3F182
+:104E000057F1A3F2CBB851F99E68FC2634FDE7D1E7
+:104E1000E4591820B4033BAA38B15888838141165D
+:104E200088353850C5F3A1E656012DE805E265AC9A
+:104E300084CD7A27C5C0F05F9681E12890AE06E266
+:104E40004B4036931C0303AF34038307104703F131
+:104E50003B190686A940FA25106F9086E8E3048A7C
+:104E60009D9421CFFD6D42E4E91BC5D4C1B7955097
+:104E7000F993B51918AEE93030A8E941F8E791E4A3
+:104E80009D806253B421EC70550686BDBA0C0C8728
+:104E900095B09B1B0194DF07948FD0C36FBF831124
+:104EA0002A7F8B352AFF8B212AFF9A272ABFC11B15
+:104EB000955FE103A10157D509D0D8030000000098
+:104EC00000000000000000001F8B08000000000030
+:104ED000000BCD7D0B7815D5B5F09AC79933E799BE
+:104EE0004972028710601283440D3884F0147512E1
+:104EF00082C6368503A2E6B7B61EA955449023D2D2
+:104F00009AF6573379125E6D406FE5F779A0DA5261
+:104F1000AB357AB1F5B66A9340BD784B21526B6DD3
+:104F20004BDBA05EB55EB5D18ADA5E947FAFB56724
+:104F30009299C34988B5FD6CBCBD9B3DB367EFB585
+:104F4000D75E6BEDF5DAFB285002FA2480E3F877A0
+:104F50002EC0E92200CC1C2AA373A04CAE04D8209A
+:104F6000048D70312B3F94EABBC2EC1D58F1A55360
+:104F700087BEBB04046AFFB3E2F6783F7BDF31F9FA
+:104F80005B712867ED2708D4DE69E79457820450E7
+:104F90000050DAB95C4DB07E368C6B56B17D87BE61
+:104FA000AD1ED878474B159070BCE2ECDFB73702E6
+:104FB000744F01381736AB2531567F4E323642B624
+:104FC000718A691CA7EE8F8BD05D06F4779CFD6F0C
+:104FD000C3CD4948B071DB267FAB1EE156BAAF01A5
+:104FE0003D02F0957149D0D9F3E920D2BC9439162D
+:104FF00098ACAEEA56DC9A7AE2381D889772ECB526
+:1050000033BE3432F47C898317868F0CBC00CC030A
+:10501000D0A0A2DBC27A00E8FBCC7E4D7B7C2D3E8B
+:10502000BAF14F9C3F1F7F1AE88407503BE389C8C1
+:10503000103C1B7C03DD12C3B7550CC6FDAC490EFA
+:105040001BA7CAD54FE67883F3943B3DEB3F15E1B0
+:105050002CA07908B2ABBF4C7866D9ED66B19963E4
+:10506000E9CC2B673E1FE764FD7F06515C80ED3B7A
+:10507000E356C4458FB2E5C17BD06EAF99DE76C3EF
+:10508000E12784F89989F8B1E2488F0E1D4B61BD84
+:10509000A996CDA7C082012997C8C6843100F9F826
+:1050A0002FF689ACE95548AF634CD696BD1F1BB3AC
+:1050B0009A24F67CDCFCB420B332027769AF84001A
+:1050C000A1293D4E1F599CEEBB6674F433BA3D0ACC
+:1050D00091CE8DAC6C9159BF88B7C391F4FD0CA4EF
+:1050E000A6B353F7F6B37AC492A1B992C6253EBCD3
+:1050F000513ADDD8C8487AA34DFF1D8D2A95ED8D14
+:105100001A74FB015A1BE354DE1EBAE5BBD87F8339
+:10511000E5D7FCAC94BB6E7818EB2D00091C2F1260
+:10512000E3FD83AC6AF76B580713F11E29E5E5B37D
+:10513000881706E7B71826112F3FB6F1A44337F1B9
+:105140006B8BB13407B2E0D32943655E3E0BE84177
+:10515000F6E550DD1FCFF3D47D5AA1A73D4011E104
+:105160008DEA4C54AC10B83C8AC87D60209C0C5F22
+:1051700059E5822D572469FA40379B5F78B662EC77
+:10518000649F6E11BCFC354EE0F4512EA854C660ED
+:1051900060CF71C48B21A637B2B182D34BBABA6348
+:1051A00038A6624C66EB18F4A5B5BC2CFC0595F24C
+:1051B0001BFD0EDC259F3E7E24A92795C832EEBB41
+:1051C000F6FA9D7BECA08AFCAF4E1713E97284D7E8
+:1051D0004AB0C9C3665D1671DE9F1EDC23AFD711CE
+:1051E0009B9FDB41A5F632AE57E5D07A75186CBDB2
+:1051F000907F2AF97A75C8963A9AF57A00C0839713
+:10520000D0205EBA385ECA3F65BCB4F4D627B2CCB3
+:10521000A3DD5E4F190CA38CF0A0E808E7E6264E4C
+:10522000B716A3DB6CF277383C483987E3C9F21331
+:10523000F17EB1C0C75960F38983A70D86589B0ED4
+:10524000239E3A6B516E6D2E1545944B9F169E1CF6
+:10525000B8360EC295E670957DBA7049A1EEFA6C2B
+:10526000FCD89EC18F9B106E4E77B59CEEC44F95B7
+:10527000EE1CB802C80F7C9D137C9DE57F89756E7E
+:105280001F5CE7245FE7F8A7B3CECE7E0EAA518F4E
+:10529000EBB642637CC8E0B856B2942B707F0D0920
+:1052A00070BFC1E800E11FC7F4CC70F3F3BA0E7011
+:1052B0009B10E0FA8674594ED205EF0A99E92C1535
+:1052C000F87CF3A9C911E60169DF40BF0327E3DFDA
+:1052D00086C34DEBF7BAE0BC5988C408CED9301B61
+:1052E000E17C27BC34A71B86EFEFF546B549F601F4
+:1052F000BCDF68ADDFEB3BF1FDB512A4B2E99777F7
+:10530000DA7201D42E85E67F13E3C1E98887536BF7
+:1053100020CAD623DC3C06E70161F6722EEB675704
+:10532000A04976E177B8F90CE2D5F98EA93BFEBC2D
+:1053300013BF1FEEBBBF09C97B0586DFB698588334
+:1053400070A9A590C635F0EF5AD25D08C3C3DB162D
+:10535000FBC7C03BECBAD9EDDE0937B733D30B5AE4
+:105360007CC63E9DD1496B816834C3101C0EBD388C
+:10537000EBE2E071B4EBF2C741FADA7C1E909E09D1
+:10538000BA34FD93D3D53EA4AB33FEF974F5CABF4E
+:105390002E5DBD2E14FCEBD295D220E92F333BA31A
+:1053A0005836B99CD4965BB4FE3836934B52E7F42A
+:1053B0006E94971067F6191F064456573493EBBD49
+:1053C0006000EAAF6AA9574EFA8ABC72325E6F7605
+:1053D0003BFD6ED4715C85C645F308C795C3D01DEF
+:1053E00088625DA17E909C8F9FC2F00477D696F074
+:1053F000EF0CFC6EB8F9C8F81D1B0FD58FE3C5F88C
+:10540000DDE7731259ECDEA1F97BC7892F4BE42449
+:1054100022A36F0F61597FC585F7E1BF93E115079F
+:105420002F8CFECBD04F5230847F73D7F5E4BF086A
+:105430008068905D57D46EE1DBF5F8FFE6E2BECF01
+:10544000F97A7D518586FA16B0FD069F5BC2570139
+:10545000EB7F1374E25B673C299C00A21BBBDDC998
+:10546000D6FF46E4A72CFC7D99C8F58DF76F49FD62
+:1054700019ED416BA3A0DFCFF07AA0F1037889F199
+:10548000E5F2EED314F47B5C2E8EA176CBE7172BDE
+:105490000B5CFD2C076E1702F4CB4B22EE719BB810
+:1054A0001EDA25F5E2BC5F9C23A571FF7B71CE5F00
+:1054B000483F7FD194D288E4173B2ECC1949EE1C8B
+:1054C00068E4F6ACD3EE8029D1FE7E40EE0F67D3C0
+:1054D000E387C64FD3F88BE748DE7D5AEE9771FD20
+:1054E000DFBF197CA83F1F685485972633E317E771
+:1054F000C9E868F99C6205FD0E279BD705B61FCC4D
+:10550000C1AF33CFD6B048F36C0D5793DFAA557BAC
+:1055100087ECC7A3EC39CA83E1E075FC56ADDAD25B
+:10552000ACF850225CDF527CC9ECF6A63D5FA79E2A
+:10553000E9CFFAA4F0B565C0D71EE67A56BB9CCC7D
+:105540006E4F65C0A3C4448F9C885DD625E03E376E
+:10555000168C67A614131A0FA1FF64822D7BC61E3A
+:10556000FE4DD3D50CDE0357844D218EF5DF091394
+:10557000199C5AA1043E56FFB7656B7B7E8FFEBD1A
+:10558000FA10481A836BD96D4D8C5C61FCCDF7091C
+:1055900058DE8A76210A5EEBCB4DE8B76AC54EE746
+:1055A00001DC257EBE0AFD6A327039C0A49C2E8FB4
+:1055B000417F0C9033663879C0FE84E3FEA1EF860C
+:1055C000C353C4964F344F924F4B47964FEB78FFDF
+:1055D00016FB0FE5CBF8A1F1E8FB712B14CF3A8E47
+:1055E000CD78DF6BD3A11F96FC53C729848A00EACC
+:1055F00023913A514B637BE8CA45BF536C950CDD50
+:105600008C6E0A2B3B059F7E72BC333957CBFDC491
+:10561000A6E0E6AB5FDB7268E2D79F1304F4F31AEF
+:105620004C859F8EF586E9D9F8E1DF901EFDAEFA34
+:10563000B26A01DBB5327A2A4539B64C243BF7D63B
+:10564000BAA5B9EEEFDF131DFBD8597FD0E5595845
+:10565000E7EB2FD7896660DADFBFFEF2C75CFF8217
+:10566000758A872F3EEEBA88686B149C7CFD3FE9F3
+:1056700038CEBA9DC81F4DF6BA9506509E6CABCD7C
+:105680002EBF865FB70A01F7B7581D98E92CDFF9DE
+:1056900025C123679D528514186C9DA5E724D24F20
+:1056A000A4B1B3EA77C0F0E34A3125C35EB3FBB3DC
+:1056B000CC3DA56CFD3F07CE5F9F8C72A62E2EC100
+:1056C00046669F41A5EF65B73F84ADF0509DE1FE72
+:1056D000CDAFEDD97B37FA97E6FAC95F9AF9BE0EDE
+:1056E000EB2E7AA891B8FFB4F7B15F9F2AB0710E84
+:1056F0001A7EDDCF1EED17FA5E213F6F9544FB2F1A
+:10570000C2A7CEC2EF81949183A664D6B0F67D95F0
+:1057100002ED9B7E78F68BFF97BE0F517CA36FFE48
+:105720004BDF388B7DFFB9B37DC8391C13F83D932F
+:1057300095807ACCB1FE6F9CC5DAEF3F3B7F44FD8C
+:10574000AA0EE7EBA293C54F78EB9722BDB1F5E81F
+:10575000FDFDAB7577B2F10E424EC28FE51C0EDF38
+:1057600041840FE9BEFFB7AFA01E78C014C8FF7414
+:1057700070CE2F63687F579902E9878BE60B697FAC
+:1057800096792E9A7FFDA489ACBF8411D202ECFDDC
+:10579000FEAAB7379FC5E05DFC1FD2162CDF7A5CEE
+:1057A0002A48960F0FAFF37CB1E97D3EA80743D29C
+:1057B00042BC83C6E310BE981177D3EBA0DE22274C
+:1057C000CC6CFEB59512F7370A9A41FA9C1C56002C
+:1057D000E7315CFB2B87A1DF1C18E896100E47DF32
+:1057E0003E76A1BE64EA897028722289E3489A0253
+:1057F0003B71DFCEBD5877CFFF66079EB849F028D2
+:105800001A8747910D339B7FE9AB363C4E3F009D95
+:105810005417E203D01F1E82AF2D90A8473F8595F5
+:10582000CBFD85AD11AFFFEF519B8EBF6D97AD3EA8
+:10583000C81A470168A6FEABC7CC51B1FF96395CC8
+:10584000EFD0C1207F782BB31361043D6EB3AD77E9
+:105850006CC478861FE31A9A1DD788737D24FC28B0
+:10586000F9C58E968B64C70CD74FC4F0EA43A132BA
+:10587000AFDDE2E82B013D2FC3EFE3F5F3F8C6C837
+:10588000A2A34721BD9E0CFE41BDCE6EB75E4EA9C0
+:105890005A563CA547D4DFFE79F8E3DF877C5D5A92
+:1058A00036B8FE517873E82AB37F255F49A5294EA3
+:1058B0009788BBE9FFD7365D29F96A0AFD9FA00EDC
+:1058C000F73EC8BF0FB3F718BF082774D42B25E0E5
+:1058D000712015F9C0859F3FDBF45F2F8B363FA603
+:1058E00028EE29E829F2D3A9458C7F8413BF73CA17
+:1058F0003FD8E3AEFFF08617883F0A54E20F4167B6
+:10590000FC93651C4B325F9758FB5592F93F58FA50
+:105910003E9292D9F8E44F128FE7AA75095D2DA146
+:105920003822D91F9970F8653EFE950EFC568AE222
+:1059300092A385FFBD51C2EF8CC3E017E59904BF68
+:1059400084E570F00B363C79A037C928D7742E5FF8
+:105950000196E86EBD64B9DD6F9E2D9F00AE8FBBD2
+:10596000F5C02FD8FD8C763E9A3CBAF92C1F9A4F81
+:10597000913D9F0923CD67BCCCD763B9CCF73BB52C
+:1059800026A1C7D9BAE40E4357F364BEDED70DAEE5
+:10599000CBF51F8BAE4E1BE53C9C71D83C66CA9C78
+:1059A000AE668D348F4A1B9E4E09E6BE8C7AF12975
+:1059B0008E7F67A9675D6EB0C7EFF43BEBB2D6B3DD
+:1059C0002ED7D8F818ED7C168C723E370CADCB6212
+:1059D0007B5D1223CDC7D5FE227BFE17DBEDC9EE22
+:1059E000B8419ED28C768625252E95670E8DC7DA16
+:1059F0007D5E2E186AF7E796779BAC30B5BB9CDAD4
+:105A0000D5F2FD8FB54BBAFB032BD28CFE8036B49A
+:105A100015981D53D23AB7DAEEFF2AFAAE6EB0FFF0
+:105A2000ABDDFDFB5BA1D9EEFF5A7CDEB4E023A722
+:105A3000DD2A2FBCA73BED52D84EA81984E37A7714
+:105A4000BB797221CDEB8438C328FD3FBE58B20329
+:105A5000E3FA7910E9C4BC8E7639752FC6FD2D4B5B
+:105A600086FB317FC06F08E8538BCE497D17DBE59D
+:105A70005A7E8DF23FAA530F63DD1221D15249F9AC
+:105A800003941FD020AB9ADFC07C0B03B6B3BA16C9
+:105A900093D39897D326242DDC177F2E2537CB243C
+:105AA0005FB5CB9AB0FF7C9DEBE9D04FFB9603D757
+:105AB000D6D01729DF2197C185FEA7B60CB86E0F87
+:105AC0004DECC1FDF6D60285F464666095A17CB903
+:105AD000510A1AD85F4FC15709DE6D4D3C9F61DBFB
+:105AE000E7BE4AF0DE2600C5696FF3F17C86AD3E65
+:105AF000556BD6B0BFE8B82F53FE438EE6AFB4E186
+:105B000040F83E5B42F0E5835675A540E2AB07EDF9
+:105B1000DBB6390AE9CBDB621555D4DF1C95F4D42A
+:105B2000DB12154DA477CC09924F3E3F6C90DD1AE5
+:105B30009DAD8085F598D1847A66645610735E2099
+:105B4000BF083099002253208D751F747696B232AB
+:105B5000DAC1EC927CEC6F295C8976EF1C8677B415
+:105B6000232CF310DA2561B0FFA4FD26CEDB375ECF
+:105B700002C9185ADF68E7E0F723DA5DD1F428DBC1
+:105B8000758FAE5DA483D9FD3346D1AE7394EDD24B
+:105B9000A36CD7CDDB9DD4DF61707B4F65FFA1DDAA
+:105BA00016C8B067516FF7C4F332DE67C6DF32CB79
+:105BB000CCF8C76BB237AE76B2EF9DB8C7C9E68BEB
+:105BC0004E894138A593B777F4CDE1DE2B8517C711
+:105BD0004DF67DDBB84BE324D7C65DC6CB09F6F3A3
+:105BE00009F576FD52BB7E59BD9945BE17F8F83EC2
+:105BF0005486FE9011D6211FB8FEF80A83FDB880A6
+:105C0000C94A23FB4F32F5DE4C79A7CA5635F2EB71
+:105C1000B604CFEFF02333221F1601F9357D90EA49
+:105C20002C4539016674E19821FEF1994F9BC8CF4C
+:105C300007C64920CCA1F531C87F9E41279974E160
+:105C4000CFF0E77C523A99EAF3C6C9FE5174A274C8
+:105C500048A3E21FA57394EDD2A36CD73DBA76FE9C
+:105C60000E6174ED3A47D92E3DCA76DDBC5DFB5C12
+:105C700085EFE7F058B359CAE09EA77AEAEDF382C0
+:105C8000DEF767853DF5F53315DAFF9DBA7F96EAB5
+:105C9000A9AF6772DEF37E7698EAEBDB7E5ACDB66B
+:105CA000B251F3C97FFF9D7C52A69EC42F3D47CCC5
+:105CB000B0DB32F84AD503F87DBEAC03E64BE5C74E
+:105CC000F83EC5CAAC7EB9BB6DFE4FCB1A95DB64FE
+:105CD0003D80F6E3BFFA3C1B7D1C5E67BE2783D781
+:105CE00091BFAF4AB6BE355C9E470DCFC3942148E5
+:105CF0007998A53566B5C9E492FC0C8F7B65F67B77
+:105D000099927CD8E7B2F7652DC9E379767F1714AD
+:105D1000C8A497C84CAEA1DEA340A2B698E28622E2
+:105D2000F9FBE4F049F68D2297DC2A19016E3B6FEE
+:105D3000955EE90055AFF1718306907C8D403F1967
+:105D4000D339A8F59C827A9A2E007D6F08DC7F3EBD
+:105D50005F4379160BFCA3FBBD8CFA15CCAD703CF0
+:105D6000F431FA95FBC9DFF90FEFF724F006309F05
+:105D7000F70C0A21C4DCF9BCBE788A1EC2B1E3C7A5
+:105D8000A559C03FA1BF24C5D365D1207F281446A3
+:105D9000C92E6B8BAD55DDEBFA575F89378EA6B5F3
+:105DA0005F2F445959B4CAEC1F81CE3FC42018FA62
+:105DB000478AAE34FB47D84F07E397189FCFC207F7
+:105DC000ED4A328DFABB3531CCED7939457EC6F5D9
+:105DD000425EC5C64A17FD1629DD0857D8302DB4D6
+:105DE000F7D6E78B06EAA9326CEE13A6B1EFA43A18
+:105DF0002399458F18FA5E7EDD3D9F3CC5BB4FB6AB
+:105E00009C84DE9DF8E470EF7D8A91CCE60F9DAC1A
+:105E100070BBD617CCFEFEEB62758932F344BCE151
+:105E20007680DFADCF850EE14C4E3E94DF50F4F42A
+:105E30000B8887B682F3E223CD17346F9EE555A217
+:105E400079A65230221C33B2C131DAFC0F8014B370
+:105E5000D186E225A81F096330AFC3F933A015ED41
+:105E60000B667F60DC23586EC07DAC1E5FA026648D
+:105E7000A62F6DA9DC09E8AFF631FD89EC13693E68
+:105E8000D79FCAB83E64B2FF701ED1F923EBD5523A
+:105E9000467DB1E2D59B5B1A1F078CC73BF03B7E6A
+:105EA000BCCC79CD13AB2F520AB2E16374F6F0ADDE
+:105EB0008C5E9872075B1B552ABFD9A851B9A531D2
+:105EC0004EE5A64646ECE81F6D2CA3FABFE1A7738A
+:105ED00091CF531DC50C7F1DF1FB5EB812D02E056E
+:105EE000DB4FF08505A82F6FC43AE901CC0CC4FA4A
+:105EF00004FEFE7A65D102B4F337069CF6D50B504A
+:105F0000AF1EAA5FD45285EF6D3F43877239B5BF8C
+:105F10007502D8E7184CF522D7BE77B7E2A379E02F
+:105F2000DEC2BF3FB705FB0BC84E3D45F00CD63176
+:105F3000E08A7595D77BDBAFA7FE4904B0F1FEABD5
+:105F40007DED02F42FDC3A99FBF961D9D293E0910F
+:105F5000FBF53FC2A02FD2E5B23CCA5F5118DD94D9
+:105F6000B047B7E6DA708FB21F90937CBF7B2EFBF1
+:105F70007E39C43727D9D76C384ECE0FA6ED874867
+:105F80008285E3FE8AF3C53F7BDC5B7D1F0F2FEA32
+:105F9000FCA489DD476BBBBA71A9E729C91F22DDC3
+:105FA000E7D4F4D1B6A2C4BBB9DE30CAF1B72A9A9D
+:105FB0001D8F4A92DDE4E0DBD13FFE94B19EBE9896
+:105FC00049F9478130E7C3D1C2FD071F3FC7E3F45A
+:105FD000030F568C1B49CF8AD589A88C0DCA8DBC5E
+:105FE0009AA0A7AECDCF43236DB01EAD2CF4D4C381
+:105FF000E5259EBA4F3BDDF3FDDFBB5EBFB4F54543
+:10600000A7FDBE8CFA9399F31C65BF4EBDA77F8197
+:1060100058C6D6E1F9F912C5439F9FFFD26D3318D8
+:106020003D3E6FE2EEC9ECDAFA161FC633FA980A63
+:106030005289FB7052B2FDEA3001F1F92BFC171BBB
+:10604000EF97F6FEF7AC7DEE876DBC13F09CD4B3F2
+:106050000BDF2FC2F57BD607B65CEA24B97070B0AF
+:10606000CEE5C2C100AF9FE9DFDE8272A04FE075CE
+:10607000D1BF7D01F73B6E6E3F9FE92F8BF19F6C87
+:10608000FC65F305339D657F0BFB15271F32EC671D
+:1060900078326B4C5F01E6BDE9407AAB1F12A49FDA
+:1060A00035805525A2DEC3E88FE2DDB236211B7DA7
+:1060B0001C6CE4F9027EB890F4FE65F3A7FBD0A84F
+:1060C000F727DE96D14FBA3821F8C0D69B35177C1A
+:1060D000A2299848DF89F9FE9DA83F2764461259F6
+:1060E000F691C5A6DFB35F196C2C84BF4FB0F914CD
+:1060F000B409EEB893E1E7764FBC7464BBC181DBB1
+:10610000A95F38FFEDBDF9E86FAC158CC9D8ADAA11
+:106110004DF862C4DD6FC8891347B0DFE7EBBFC439
+:10612000FD1A8C2ED0AFFACC91AB7D149F5D96EF0B
+:10613000E1BF6575DEFCB6A535214FFDE2F923E729
+:10614000D741D29F21D72CFBFCA548F278E361818F
+:10615000E443CEC48134E667C2F312703DD0F1C38C
+:10616000CE233F6C74FC808EF9A2F0C79076BF4BB3
+:106170008EB666E021B37CC2CFF55B39AF96E2DC28
+:10618000EF1F1174F4A70A790D5370BEB26236E3A3
+:10619000B8ADC5621AE3DF37966C5371BD37947E94
+:1061A0003C7DD017E3717FDDD22A90FD87FB2E6DF9
+:1061B000F2BCB6CCE7D7FA79DCA1CD5AAA9522D3A6
+:1061C000ECD5AA70FE8122C87ABE94D1FFB57EF2CA
+:1061D000BB5BC0E3EC09D2AF4BD5E5947F2B178EA8
+:1061E0001CB7CDC49B6CC70333DB3D68D363E99C0C
+:1061F0009DD4EFFBA78DDCAF83970F0C11FA102E07
+:10620000A657607B15D87C18FE3795F1FCDBD6F2DB
+:106210004709CF9259457AAD4F4B99D86E53F972D1
+:10622000A2CB36D6269F0D9D5BD345E733377DC87D
+:10623000E3140FFAF7B6A05EB1A9E71AC07CCA60F2
+:106240003C0D283F364DBD4A453C6CDAC1788BF495
+:10625000992E72CE856CBF78488334B3A840D6BBE4
+:10626000BA512EC8B56098EC556FBC1A70DD365522
+:1062700072D6CC4FA79A3004B4297EC8C4F8446BB8
+:106280003D50BE4BB0CCAC2D46F8C789240E7448A7
+:106290007660BDB54EA6F9B46B1C2F68871D77F2EA
+:1062A000BD302FA694DB61A5E8EF67E32837F3F94B
+:1062B000EBDB4BC96FB42957A9473967DAF611D31D
+:1062C000532CF4F3B7366859D77DB3987CC0EF925E
+:1062D000EFB296A0FCA64CFCBCEF83CFE0BC5BA762
+:1062E0008BB0338BDEF1233FB74BD2C6D2C52559D5
+:1062F000C679C2AF7BF611FD0385E01DAEFD503BB4
+:1063000099FCFB68805CC0E65150CBFDA690717E85
+:10631000350649B273C782D584FCE89C5B1D5F9348
+:10632000F84D9295526419E5D50D778ED5C9E75C85
+:106330003E07EC3FFD92DFB1F95EB3CF0788B7733C
+:106340008FDDFB34E64D39F606DB979E7E92BDBFAE
+:1063500092A96558BFE6F05405F3809E2F9430470C
+:1063600006F9278A74F826889487F6261C8ACE7048
+:10637000D1F9FFD8FB0E4A5694232DB97C5E72B832
+:10638000BD4F8AE27ACB56BF93C747F60FCF6787D8
+:10639000307BAE52165213C9BF0E9E37E4E4497EDD
+:1063A000B9D39B4774F5766FFD2A583A06F9E6AAE9
+:1063B000DB7C9066FD5EE3CEFF62E3FFD2CFF58328
+:1063C000AB21D58EFBCF7A5BFF5BFDA3A90AD2F58B
+:1063D0003533B4623C7FE1CCE32FF6BABFCEF8543C
+:1063E00077F1FFCA589AF29233E7F7E6EE05DD49F6
+:1063F000567F499753DCDEF6CE73BDAF6F11E67D55
+:10640000595B7C8EDEE0C9775CB9ABCAC4BC31860F
+:106410003D3DDFFB3DC1FFA50EEF7C4F868FCCF9E4
+:106420003BFAE070F3517665D72382AA376FAA450D
+:10643000E57147B34586C039279E8BB6AA5374AE23
+:10644000D96AF66B2D318A53521CB081110EC6F9F0
+:1064500066A83ACF730F4C4C039D3F48CDC673E1FD
+:106460009FB4DF392AE7C37F74BF670FD3EF6AB5E4
+:106470005F41FE5C2377D60A2543E702023ECB1C30
+:10648000CFF0ED7F7C49F778F0B4EB1865BB7D78F1
+:10649000F47914ED6AC511FA7BCBDEB7FEF3C16F58
+:1064A0002BB87FBFF9C0914528E7AEFD89042A6B60
+:1064B000F7D68311E8A67D27ADA03C5EB95BA2F5B7
+:1064C00007B97BD6859E3CFB169AFFB50F47687FC0
+:1064D00058F9A83F5DC7BE5FF9C397A601E3DBB7D4
+:1064E0009A079E1E8FF87B40E0F90C56FFB40BD93B
+:1064F000F395325C9E2D1F21A972BE7AE33F42F5CF
+:10650000B8BF0BBB7ABE48FD765DE2F3BBE4EF2576
+:10651000AACF6947FAA3F53D213D59E0F065CBCFFD
+:106520007BE37B3CFEB4F2715F1AF31557EEDAA100
+:106530002459BB35BBDE26FA5EF0F04351C4C39A42
+:10654000C7BD7ADAB50F7FD83EAF92CE390DD4A150
+:10655000FC938E51FDA8A90E70CD9FFB67AE238ED4
+:1065600065EDFEFDD5F37EC7DEBF1E9720C044CA91
+:10657000EB7DFFADFC04EBC9708A8932D6BFEF45D5
+:10658000371FAED9F5129D37D24418283A0BCF41A8
+:1065900064BCCF680F30A0A03C5CD3B5E16D94978C
+:1065A0006B76BFF95BA4BB3520BFE8E6E7D7F11FE8
+:1065B000E34E8C6B75A85E3FCE51D83F0BED16D8DD
+:1065C000959FD55E74E25A0E7F5FFBD0D17B508FD2
+:1065D00078E3D1FFB907EF6558F5D15FEEC1FC56FE
+:1065E000782AA0A1DC5AF3C0AFA2E0C2FFB76DF9D0
+:1065F000F0D6F7BEFB9D3B181EDEFA8D9FB0F6D697
+:1066000093AF4EC4FB39DE7AE4AF6350FF58F7E432
+:10661000C2B14867EB1E5B3076A4F39F48B769BFF1
+:106620007B7DD3FC5E83C705DC04D9866B9719EBB1
+:1066300002FB0714D47BDF136060632E7BDEF5A1C1
+:1066400082FACBD3260C209EF6EC7EE9E9AFB3FAB2
+:106650009B6C9DFC59D689CD7FBC48FB1B631F56A4
+:106660005EB7FBC2C5675762E933B0FB353040FB0C
+:10667000C609EBFB1C5BDFCAA1F5CD7C7F148E291C
+:1066800088FF350FB2F59C86EBCAD673DA89EBF931
+:1066900026FE63EE89EBD9AB7AFDAF4761D5BD77B6
+:1066A000E0CBDDF959ED5B673D573F76D1887AB98C
+:1066B000231F4E86673AD7CBE0FA866A1E520B90AC
+:1066C0002EBEFF9D3B627C9DEB1862DE7AE8E844BB
+:1066D0003CB4F19A6FE08B88878127FD1AEA512B31
+:1066E0009FFC35F1DD5B8F3D4BE779D85F5460FB54
+:1066F000DD5B30F8770858FD3A815756EB03E7FD2C
+:1067000096F5BB9A756119B47EE7FDB612D74F1D99
+:10671000A0F5482FA9D551FEA60B68DED7A5397F75
+:106720005C97EE59867EED4CBC87034E5EE1D0BA95
+:1067300062BCF9BADD47CE43FA1B6E3D9DF96B385A
+:10674000FFD9ECFD7D5EFE1D965FEDF57D6BC7FB11
+:106750000AEA57DD3F513491D9ED6FF9069442DCD6
+:106760006F1E91343C679CB9EE43F86FCE7ADE38E9
+:10677000B3CCA40F25903D8EEDE0E964FC7EF2F9E8
+:106780007D3CFCBD6BEF9799787CE358F6FDA02427
+:10679000C0EDB9EBA0B31655CCCCFDCC07296B7C72
+:1067A000F110BCED5D12C9F9377649148FCB9417FF
+:1067B000D70D639F19CE388FF74C43B9F646EF7F5C
+:1067C000D874C9E9FEBA078F2896BD3FA45DF85D6D
+:1067D000339CDFDBEE6FCD13D9FB5BF3E0DB59FBC2
+:1067E0007B5D362F41F85FEFF3517ED2EB5D525661
+:1067F0003BB734E0F3E85DED91592FE460DC201AFB
+:10680000A4FCAB9666F3D7E82FB50EF96C3F80F188
+:106810001AE65DB5448274BEBD257A15DD93E4F4B5
+:10682000D79A8127399E20FB498E252A792C2CED79
+:10683000896FF91841B8E106D92A42BDFF40F1AB92
+:1068400032F68B7E15DD65D71F94A10DFD2A074D0D
+:10685000C168822CFE8D8CFE13F325D0DD7EC2EE46
+:1068600071E2BBEC7BFF73521A51DB00A96E3A1F39
+:1068700050045DF767E9EFAE469DECE7E2C4E5E45E
+:10688000FFF1A75226EA6B45EBB412511F7EDC09DB
+:10689000296F1CBB9051FEBB38CE3E1FE983B0EB85
+:1068A00081071E18C3B714D4CB9FC692C9BF7357B4
+:1068B000E84558BFCB9E37E3013ABF38C14AC828E4
+:1068C000E784D812F2832D4C25E4E5AEF55C18136D
+:1068D0000A713F4D0F73FFD30F037CFF6C6ABA98A8
+:1068E000F2D9EFBC5924BABE33707E11F2D9DEDC86
+:1068F000D961CC57EC593D6BFF1406E7F8B004683A
+:1069000072EE098FEC4FBAC7F62FECB4EF1DBACF79
+:10691000CE33FF8E8DB75D8D65543ED068D0FB07BA
+:106920001BE750BDABB196CA471B13F43CFAF560A8
+:1069300012E97377633D3D1F0F6F0BB8FE3F6C4C40
+:1069400052FDDB815C827FD24D2026D9F385888F72
+:10695000F0D0BC1D78D2B6DDFDC30D4FB5A21F62CD
+:10696000108F19F83E17FA0415FD573141C775BF4E
+:1069700031C0E549267E27FA07048CCF35DCC4F305
+:1069800022EE11BCE71EBE65CBFF476D3E7D3B9AF4
+:106990007C30C0E07CA7765919E943A09523DDDC63
+:1069A00023240E1AC58467CFF9939579C947032E1E
+:1069B000BA99D8C1EDFADB035C3EE9EB40447A9B1F
+:1069C00090021DE9CD99776F955E8472B15710687A
+:1069D000BD91DECA5CF4E6F4776780EBC110CFBEF0
+:1069E0008F0FD12FE7FFF8BCB2AD358897B522F9EC
+:1069F0002D5BF095EBBBBFDAF364768B68213DAF7E
+:106A000010C99F3BE9F0116122834FD7BE1F403F61
+:106A1000747C22D8FEA6AE00D2D79D2BB87FF1EEB3
+:106A2000C3FC3CD3D175254BA6B0F68B187E30281D
+:106A3000957741698E3B7EEA9C63B85B4DE46823A1
+:106A4000F8B732F3DF6E9F74CB07396C9CF1874344
+:106A50003AFAD7B74E7AAA4761F5C27E81FC4985DA
+:106A6000E1D4145CCFAA3F7C6F5CBF6B1DEE589DD8
+:106A70009A847A63FBA41F08C80785C77E2AE03E74
+:106A800032494BBE1228C0FC70FB7CB09C9A8D76BC
+:106A9000C1A57989D770DD1245E9FF83F474B47616
+:106AA000DD7F62FF4E3CB2A141CF9DE2920F99E79C
+:106AB0002AEE4A8DECCF74E67F17CE7F8476CEFC2B
+:106AC0009DF53B5A1B5B857231139F99FDE65DB0C6
+:106AD0006CC4F1EFB2EF0F63F357822EFA2C4AF534
+:106AE000CBF89DF3FD70F1D7CCF90EFA894619AFBA
+:106AF000EDF2413ED2C523FF3BF1DF0F02924E4241
+:106B000042FF544F20190F16E0BD7129AA33E948FE
+:106B100079ED67E472FEBD63CC77C611DFC9E96227
+:106B2000CAFF18E5786D904854E13E678846B67D07
+:106B3000A03CC8E5E77C48917F540CDD3472BCBFB3
+:106B4000C81BEFDF0C3409B0BA553BFE01B286FE1C
+:106B5000B07D5081FEC7BC2087BF4AE6F6E58C7D3C
+:106B6000FA0E89FBADA4251117FE6CBF9D8F77CD62
+:106B7000E0BE09341DCF7F4DEF115CFCFA7E287911
+:106B800036E24989EB744ED6174B925F72A1141608
+:106B9000C99FDBC9E57F0324D4D3785C0670DE3A55
+:106BA000C445DCEFEF5AC7CF8DEB5A88E0BE2BA669
+:106BB00053BDC1D6531EB1F5FA876CB9FF7D5BEEAC
+:106BC0007FCF96FBA55DA9056106D7776DF97FBFDD
+:106BD0002DFF77A2FC67E569F7F5C3F72A491E1B6D
+:106BE000985FF08D6DF16644C13D8D26BD7FA27129
+:106BF00005957B7EFF7C7588C177DF73DC1F7CDFAA
+:106C0000E1319FC1F859DA140D81B5BFCBCA131F0A
+:106C100067F51DEBC49D28577EDC98A2EF76A8DDB2
+:106C200012EA314799B56C2119BC66B68458FBC885
+:106C3000BB035A2D2B77B41E0AE0BCF33E2702DEBD
+:106C4000D3E7F051F40F5FED8EA21C9B290691ADA6
+:106C5000F20ABAD553D04E5F27523FDFFCD565EA22
+:106C600002C07B1B5E84D5ECFB095784293FA2E858
+:106C7000FA97CDD5ACDD9697C394AF5DB1AFBFFBAE
+:106C800021F67ED68A08D5CBBBFACD2DAC5EFA06AE
+:106C9000AF4FB0BCFC71FAAE7EF321F67D712A4A8B
+:106CA000EF67EEEE6BC2F9FA2ABDE7AF72FED031A4
+:106CB0006E0B836F22187B826C3D1E1352BD01F454
+:106CC0005B2CE1E73C0AD2C92ADC3AC66EEFEAA1A6
+:106CD000D07F0754235EE3BF7D217E0D2BB7E147B4
+:106CE0008C2E66EFE5F8B8BBF5C50BCE67EDF6ACBC
+:106CF0005B4BE715FCEBD6717D88E10DE5FF84AFBA
+:106D0000EC15AE76C989A25639ABFF6E5BD04FFC4D
+:106D1000D1B66E59620A07776F18F5BE52EEB72CDE
+:106D20006EABF1E439397192BF09C96D41D23F7937
+:106D3000BC44D652F47C06E37DF4B3C28D22D797CF
+:106D4000127D01B73F46FF0ABF9F2D138E9D4199CB
+:106D50009F77B46A5EDBCFE6B765A62207108E295F
+:106D6000F6FD2C763CD269CFC6DFE9966FB2C6E15C
+:106D70009AC00C2505E15ED537EE21D6CF072967ED
+:106D80003F3383B89FFD68AB48FBDFE64A7E2E7039
+:106D90008FF14E37DE73E1F0559B21121F6FEB83AD
+:106DA000349EB3D85659927B1AD2510C77719AAF50
+:106DB0008A782EED93C1CECFE945FFB81FFDE38C55
+:106DC0009E4A0F878E88E407F4E683175B5E7A108D
+:106DD0001BBCE7F02630E5C79DBFCC2C9F213AA312
+:106DE0007DB6A617EF51388AF728A007C532A355FC
+:106DF00063C874E2CA917493847EF8D28C73077767
+:106E0000D8FC7E8F7DAE108E5D0F28BFEEB0F38B69
+:106E1000EE5825067586979F598768FF9CD0D05DF0
+:106E2000458199C33C8FC2C9B7F6DFA435E33E5B09
+:106E30009CF2E60D5566E45D977EC2BCEBC341AFA4
+:106E40007FAAF7C74103EFC34B3F2719A8D77EE3BB
+:106E5000EB33480E5A2BB9FE925E917707C697F234
+:106E60000530F0B9D3AF63C7BE13CC23BE49CF659D
+:106E7000EF7398FC88745DB002D70B72B4E6189E6D
+:106E80008FBE117E80FDAFE0EB5F550474BF4E51A5
+:106E90000C28CECFCA8DA7227FAF1331360EC76D17
+:106EA000790F6ADF33F83CF73322DD9F53DC6A9DAC
+:106EB00086F3EC9D575888F4B139CCCFC1B4083C67
+:106EC0009FCB2AE0FCB023D24DF9A15B6A4568C68E
+:106ED0007563B833B09FE5C19D94D782F0CE24BAD4
+:106EE00023FD0B6315C88FD61541BEFF1CB34E435F
+:106EF000FF7234D4DFB587F5135EAF183B512E56C1
+:106F000079EFA99B1CE2FA5E20C4F73FC62F8110DF
+:106F1000C6F93703E531B2B9107F33BEB280F60748
+:106F20008DEC2B27CE1FEDBD402C9ECACB1217FF38
+:106F3000EEB4E56DDACE5FB8C7DE471CBDE30E7B6D
+:106F40001FD96CEF1FC5E6E26605E976054C473CA4
+:106F500095AEEA129667E1FF533ABC7235935F260D
+:106F600065F24BCA7B6E75FC8A12CFFB8871BAE75B
+:106F70003D856470DDD93E8E785E1F289750FF9B5B
+:106F80000109D32D5786D303F282E634C4DF68F5B6
+:106F900092682891423D34530F3FCB5E972F0412E5
+:106FA00073B1BFE8BC7ACAE75915489C45FDCB6967
+:106FB00001E5E97CFC2E96155E4A061B05BC351FD3
+:106FC000075E900D3ADF75A3E4DC67EB3DDF051942
+:106FD000F7D766DE4F7BCEFFDE44F7D3B6094CE130
+:106FE000C37A8E7D3FAD9FDF4FDB16E1F6579B8F57
+:106FF000E7AD5D67E3E1F210BFEF75954DA7E7845C
+:10700000B2DF7FE4F8BF52281BB0DDD8ECF78EA1C9
+:107010006685FD9D333EFBFB5448E1DF4F1A799CAA
+:10702000B5380EEB6766D05C1D2A18C2D38C90B9B8
+:10703000C65DBF2164E715C909D22F4D99EF877A44
+:10704000D05CE76EE794791754D2F9BEA3F6F93E07
+:10705000F6DD7681F02A69A3C1BB6307B409FA564D
+:107060009283BF62FA5F96F5783F18B5C49CA1B8C9
+:1070700094A327ED0A71BB97D1DB06A20F266110FE
+:10708000EE30E85BF15E88F1780FB78EF6E7E17BD2
+:10709000BE8DF2F6ECBE5AD4A356FF58A2FBED4EBD
+:1070A000C0D72A4677AEBC14E779E107E3C91E9E34
+:1070B00020256F0FB9F6E9C215030AD23BC25FC3A0
+:1070C000E1E7F9D442FA346E1700C573DAAE897B72
+:1070D000F20B33ED923CBCF780E48A42FA5D265C09
+:1070E0008E5DE1D433CF271CB0E908FFF431784F2F
+:1070F0003870A5563625E4AF9990A47236E854321C
+:10710000FBA50BD793F19F8E703687269E85F3F8EB
+:1071100027E2EDA950C1BF1EDE1C3A2E4E9E3B4811
+:10712000C7D9EEBFBE3D142579DB7038B2D34FFB13
+:10713000C9D788AE2546D7A8F73A79330D60E7D589
+:1071400087A10BFD94C5C9463A277A94D131F62B15
+:1071500069FC5CAB0C5A02E337528CF3874F2ED399
+:10716000440DE3B3961FF51EAB040C94B5E8977479
+:10717000C35B194EBEEAA6BF1B0F6F2579FB854086
+:10718000F275C4EF8DA5961F353B971C7EC32D87E6
+:107190000508EBC87FE71CE3FB65555297911E1667
+:1071A000304E47BC2F8424D5CF078BCA0B204DE52A
+:1071B00067F18A23D2E3EC730CDD9788EE730C83BE
+:1071C000E7E12A9DBC0E1EAF2AB0E9106C7BF56783
+:1071D000F54B9B16B2F1D9E29B1897FA563DCFEBCF
+:1071E000F1CF96E93C6B41FF1575182F82655C0F56
+:1071F00073F221F2EABC7ADA09F75D1DFED361FC75
+:107200002EF3DC9CA3AF65EE5B4E99A9AFE58587B5
+:10721000892F0CB3EF64C6171AF09FDC8EB5EDEB27
+:10722000448EFBDEF8CCF240E340EB5E57DEF941E2
+:10723000BCEF28EB3EC0E3BED1DE3FD52DABA4FBB7
+:10724000E50C4C9DEC6BEC3EE7E5C943F670627EC5
+:10725000EECFD02F9DA8C9AD407B7251FCBDD6BDED
+:10726000F9004BCC9E735E76CDB34F63D066D113DD
+:1072700006C7337D7F73EFBF6FE0B903F44FD8E3E8
+:1072800045EC38D97AD1F213BFDA7EB8778BB8BD26
+:10729000EED8F9D9E6DB4AF8EA0F233D0C37DF2FA9
+:1072A00085F97E3AA6DEA0FBF25BECFBF25B2638AA
+:1072B000795C8686FAE45561EE8F5D1F2EA5386BEA
+:1072C0004BCF5CF22B17ECF7915F7DCCB2A460B989
+:1072D000F645CCBF473FEC37997EA753BE7D19D505
+:1072E0007BAB66A9682FDC10A9A0B8EDC646C39396
+:1072F00037E2942DECFBA4CBCFD792A8D630EEDBAF
+:107300005A57A1A2DD217DAE92EAF269159DD58C76
+:107310009FBFB079DA7905189F28E7F7935DCEEA29
+:107320004DA500D561BECF1E305E0E239EAAC3BA06
+:10733000433FB48EBE6549D3877221AE5563CE8C70
+:10734000F31C6CFA62CF49BF7E43495E13C67EECE4
+:107350007BB2D62BA9B2B5E5784E9E091CF417ABCB
+:10736000DC5F8874D03A6308EEB5367EE7D9E33245
+:1073700081243EE25A3F25CED76FBD082BB2ADCF58
+:107380004D61AEDFB46AA636221D69F2DF3CF78795
+:1073900056C678BE7E8CD1918B9F4FA477CE4F95E9
+:1073A000E1442BCECFAA86B214CD3F4CF287BE93D8
+:1073B00086EEB18C87CD0E6CF78B5C3B4FBA88E7BD
+:1073C00043B3E7ED3924FF5224DF1D7D70BDCCF5BA
+:1073D000B9D1EA837917AC237DF01DC65A649F7D2D
+:1073E0006E1DC9ED753E5543FBB477BE4C71ADE8DB
+:1073F0002970B9DB6E91225C1F9422DCFF8DBF9354
+:10740000909EC2F51E3CE7110D4137EE0303137841
+:107410009EE97AD8517B0AC1375973EF675513B883
+:107420009F614B757085DBDF303797C7CDF6E65629
+:10743000FD29CCCAF270BA1A59F30C0DFA31AF0615
+:10744000AAF97932A1889F27F381A1727EADD1F08C
+:10745000DE500192741E6DD8F503EFFDA20FC8E94E
+:10746000E620E22DC6EF59896C1728794FEA32BB26
+:10747000F14C4F73EED21F8709DF0903F9BB675642
+:1074800090ECBDF77A14B23FDFBB067ED785755FFF
+:107490000E586CA99E12C5DF3DCCE63BC0987527FF
+:1074A000E68169FCFDF4CD02F9B39EFA5B703CD233
+:1074B000BB1105117FCF6211D32778B22084304EE3
+:1074C0001B5D00DDE7E2F73D61C29F2FFEF3735EB7
+:1074D0009E41FB4F489C83E7B7C43B71FE8FC6219A
+:1074E0000FBF9FF1D76A094A86F4A1AD5AF210C2C4
+:1074F0003B1BAC153DECFB2D0AE7AF2D794A1AE397
+:1075000095150522E921E00BA527B3F78BF6BD5CA5
+:1075100083F99D8BE64CC796383EADF7242D79183C
+:10752000E9AF465B5293CBDA573EA793FC3D2F7EE3
+:10753000FD5EACCF3ACCEB3E3FD7E3518F719F134A
+:1075400058F4C1449AD7AB61AECFB6C6CD3E5318FE
+:1075500091AF32EEE5F59E3370E8806DEB3AE6A729
+:10756000D3BF75A28BA44F1CF23FC11CC33E8FE258
+:10757000D083297C1C7AD88D3C89F217F3CE6243E4
+:107580007967EB6DFD6DB4796799FC9477814CEB6D
+:10759000F00ED3B7300FFD443EB99EEEFFCCE4278A
+:1075A00007CE8D95793194C30EDF68B36F22B9ECA5
+:1075B000BF42A1FB4C1D3E72F86756CE201F7D13C3
+:1075C000E5C5B2B0BE90A76A98E0E6930B4FC257EC
+:1075D0008B60606F8CD517C960E530117460EE6BFD
+:1075E000A5135D7C9289CF45F30578D1230779DD1A
+:1075F000856F6DF01EE02C76F270EB7248D6DB6280
+:107600002E3E6DB7CF99758806E07ED49CBBDC8892
+:10761000CCC47B277357213F6C121229E487C8EC36
+:1076200037425731BCBF37866991E83FD4973F4C0A
+:10763000FCFE4288ECB22DB356527CEABD6B9293AD
+:10764000707FD9C0F0FE22EDE7E9B122E5DCF68FCC
+:10765000E5F9137A9C97C9387F0EF6FBB45D37EDD8
+:1076600076FDD48EADAF476EEE8B723ED817E5FB3C
+:10767000D406A553457A1828563577DEF2B9F6FDBB
+:10768000C2D746ECFC97632D3AC629AE8D08F67931
+:10769000BB2ED25736343E4E657E5D1A304F2E5883
+:1076A00066E9A857A81F2D10709F85D379DC1D9F10
+:1076B00037B9F4B58B6CB9ADE2BD406CDE6AB3A5E9
+:1076C000BBEF9D554521EB7D41FF15E5FE5FB519EB
+:1076D000E8BDDAFBFF283F21BFD410BE8CF5E64E93
+:1076E000FADD9840377F1E2B35852B5DFDC6EABA43
+:1076F0003CFBA32AF6CB640F358066A17127F7D730
+:10770000A0DFAD6369B013F39633E908FF5E74D16F
+:1077100083FAD185A417C121AE97D694A844BF6D32
+:107720000DCA0EF4EBBD1BABA63CF5161B6F99F30F
+:10773000C1F83AD3F4C84F66F9799CDD9AC2E3ECFC
+:1077400058C7383B961867C712E3ECF81EE3EC58AD
+:10775000FF41A349758CB7631DE3ED58C7383BD68D
+:1077600031BE8EE5E38D2BA8C4F809BE7FA2B1819E
+:10777000EAE7DA7213CAF8EF7C757C4D31313FEAE3
+:1077800027F6FAEC3197AEF825FA01216AE07E1D62
+:10779000D8DFFCC27FD975BAFF3A5E928F7E4988E6
+:1077A0008980F184F6F836A6630ECD2F20DF0A3AE1
+:1077B000C5D5AD1598D7B83372E03C99E90FA5F15E
+:1077C000EBABF3587D57E4B976CC233D556FAADF78
+:1077D000E1AAEB918A958F6843F549E53BE4207B6C
+:1077E000FFD096E7DB510E04625CEFFB51E437E714
+:1077F000353192E82E618A0DCAB162258D748C678D
+:10780000395F9C8CF3E07ACB67A1258E797C9374E9
+:10781000A502F98FB5EFE6743FBAF63F89E8F43C6C
+:10782000F3BB91DA8995A36A47E770876B87EF8589
+:1078300011FA698316AD8FC1BEC9C7F757AB80FB7C
+:107840007F3B7C9CEF3B02BC9C98E3E42F54DF120F
+:1078500065E52D51BEBE1D017E0FC1C054917E8FC6
+:10786000071A84CF633F5F2D040DF31F2BA696E408
+:10787000A3FE7FC8A687C993227CDFFEBF2AEDDB6B
+:10788000E74F7AA8358FD5277FDB30701FDE04469F
+:1078900010EF71B5368B944FF4FDCA53F296B0E6F3
+:1078A00067CC7C2C0FF5DE0A5BEEA46DFBA4A9ED82
+:1078B000AA49681FBCF72C977B47EC7176F8FA52FF
+:1078C000B49E33C3749E02A093F492A6B84CC10C2C
+:1078D000711C2F159F7629DD93D9A6D0BD4CCA8780
+:1078E000B355F2A77EE0B7EF25EE237D450924B519
+:1078F0005CF6BCD312C9FFD0A205296EB3295C4146
+:10790000BFCB6095CB140FDB54CEE33AA1C8C5744E
+:107910004EEB9B3D016ADF1656291F385DBE7B5F2B
+:10792000750C4B51C37D3F6D2EA5FB2A2D4DD428E0
+:10793000AF98FD8BDEAF8A919F6713D8EBB28AC7F1
+:10794000217C63F753BDE5228DFA073B7F9F542FBF
+:10795000117F2722D1E3BD7F76E0E767A21F642570
+:107960003F9F324D5BDAF3247BDF6AAA8912C60F90
+:107970006DDA3BBD21AC5F06142F0D4D7DB919E3C7
+:10798000A9AD576A06CFC7E2E721C0BEEFB8B57C04
+:1079900059CFEFB1FFFA104C36B07D8D8AFC0AAD9D
+:1079A000F034DE4F5564EB33A1DC0A01F5B1B63A91
+:1079B000BA8693C1E73D47D09AF71915E9465A941C
+:1079C00047E3B481A9627BAB4EA67DB128AC76A318
+:1079D000DFA0C8F63B38F2203FE53A4FC0FE57B86B
+:1079E0004AF69C37187BA5B75E9071DFEE9936FD9D
+:1079F00064E22D739EF9B14773119EFC557432E217
+:107A000004F86F8D552CC1798DD37A851D9564D27C
+:107A100068BA86A986A926773EC62785775A796BE4
+:107A20001FD2C3345D069DE1E54C1868C6FE37D908
+:107A3000F4DF51ECDD9F0FD9760DE3D3ABA3980FA4
+:107A4000D52082E5EA1FE31D960B9E533AF23CF5E2
+:107A5000C99D859EF653B69778DE9F963EDDF3FE70
+:107A60008C5D159EFAD4AE799EF6673E5EEDA94F09
+:107A7000EFFE8CA7FD8C7D4B3DF5997D977ADACF93
+:107A80007E61B9E7FDDCFE959EF767BDB6D6533F34
+:107A90007BE0EB9EF68E5E9FB96F5E11FDFBF47985
+:107AA000FCDD1FF7B9E24C7BE1847B743E6AD13187
+:107AB000FE07517E6FAE8CFB3BABAFFD1AB7BBD45C
+:107AC000730C1DE5CD25365DAECC33AF43F95A15A9
+:107AD00055699F90C3BC9D1C3E8FF49189DB999C96
+:107AE0009A41F6D8E0FB10CAEB46EB9C5297BF2AAE
+:107AF000A07502E68155456BE9FE40E77B593301ED
+:107B0000F3E32EC12486023C766A51BB80CEBE7759
+:107B1000CD8BD97F7495C400B30F51AF1FB4FFE470
+:107B20001C8AFB32FB8FEC4323C8ED413826D17B06
+:107B3000E39B02607C9AD977641F3E1A66F6E17473
+:107B4000B4C7FA37A11C1AF8854C7144F647F65FA2
+:107B500025B3FF36E6BAFDE0FDC558A6412B247FCC
+:107B6000B8D22D8E2D267BF036A4E72FAC7B760580
+:107B7000F63BB592DFB3D731A62E8E7A72477117D6
+:107B8000F1C940B1CCF7213951E6F6EFFDD45EEFF3
+:107B900090FA7DB243D93A905C76D66193D09FC675
+:107BA000FB0CADAF05C9DF3DF18FFE43C86F6A899D
+:107BB0003A1EF3008D3D8A89E3DD6AE3B9449B5E9A
+:107BC0008D3FF3581A5FD28BE5A93AD347585956DF
+:107BD000B6B517CB47A22534DEE9C623D52863D432
+:107BE00073B8DF5A9EA6A49B05F4373338B2D81D6C
+:107BF00083FE89E8767E8EBF547E05E90FB5FEE3ED
+:107C00006C0A55792AC58D0348170295444F0139EE
+:107C100044FB4B000FA3627D8E90C65017EAAF98CD
+:107C2000175A95B79DE8C0D16B51DF4D72FBF8A78D
+:107C300088D7589D77FD43EA0F084FADF6EFBC7526
+:107C4000E4EAFBABD9B81D052579E8B3457FCA1234
+:107C500097FCD963EFBBF7E6881EF9331B731466F4
+:107C60000EE9458C1FB68BA720BC098AAF07F64BDF
+:107C700064CF076EEAA4DF570D68960EA4FF5B3A47
+:107C8000F65B53524FFEBFBFC42A480F0E343C95DB
+:107C9000156F817E09CC19C3E3337AEA1DA40FC0A6
+:107CA00098A08EFB6C432C68EEC8621F7C29C2FD35
+:107CB000671B263AFECC049D7B6D437F5B18B7366D
+:107CC000557C84F573C32F0A76BAEF87B8A180FB81
+:107CD00027871B3FC0ECCCA40BBE0DAC5F94E36DBB
+:107CE000C796D4D2FDAAB8CD54E2B9D0F21DE4A70C
+:107CF000B7EDA52FD978BD36C2F1385181053B507B
+:107D00009EE431FD88A1B4CAF6AB38FE97780E8F99
+:107D1000EB1B1648DC2FE773F62DF138DE4BA383FF
+:107D2000AECCB2AF00211598EF6BECFF7AF07CE09F
+:107D3000291DAE7D0E703FF0D6A76CF7D64F4B7B5A
+:107D4000EB4C8B7E1EF5806500DCAFB1CBFB3E0CAF
+:107D5000A60FE32885CE7DFA097E5E506510207D52
+:107D60009777A57BEE66F34B38F75E66DC9F3F7531
+:107D7000779AF497C54C7FC1F799F7BA171E5EBD85
+:107D80001AF585C28C7DB4C22791BF01FD4486CB14
+:107D90004F3449D33D7695E3EFC994EBC1C35B8182
+:107DA000BD217B3DE9C7FB51B572F42BB417DDF261
+:107DB000C7239543FE957639F5EA11F25F32FD2B24
+:107DC000C6FD1FE897BEE1175FF9F311979FF2ED2B
+:107DD00068721AFA336E9FC4BF77EE4F75CEF5BD49
+:107DE000532BFF4CD0391C49171C379659E7737534
+:107DF000254DF76738FE15C78F70699E790BF2DD48
+:107E000026E3506A0FEBB7FA377EC07E164AFBF7BF
+:107E100035A2BC9B2053BE88367BD5BD41F467E2BA
+:107E20007B56AF2ED6C7127F3CE3237FC27A9BEFEF
+:107E30009DF3A98E3FE6B3B61D707E8EA3475941D0
+:107E4000FB5C4610F5E43376B135F4EC87DC1FE8D3
+:107E5000F8FDA67679DF9F8E47BDC9EFB983F29B07
+:107E60008CB93CBF694C7DBA17D7F94C7B9D316EFC
+:107E700055356B287E3AF6B2742FEAA1D3EC3CA5B7
+:107E8000F2677E463FE50B5211E5279D3E9EDF4B94
+:107E900064EC953DE742C68040793E639E938C3406
+:107EA000EB67DA13DEF7E5E0AA17237CDE7A665C7F
+:107EB0008AA95B6F5F21E0EFA2A60494679B2F6302
+:107EC0003602ABAFC8B1F38B4E8553916E174A6142
+:107ED00003EFD15BFB2B89F214FD47A6FC1AE3A349
+:107EE000F02CCFABD44EE1F156EDE792C1242068DF
+:107EF00021983E3D3C14C7FAD67103EFD41FF48F8E
+:107F00003DC0D61DF7A10799DD5FEA433B5EA37A2A
+:107F100017B3FBB1FE28B3FBB1DCCDEC7E7CFE4396
+:107F200066F763FD7166F763F96366F7E3F3279815
+:107F3000DD8FF5BDB955E48FEFC3FB8DA6E0EFDA19
+:107F4000EEA6BCC6F5AA4F43FAC99467555537A8A3
+:107F5000CB187E378617521CA57A21CFAB6FCF592D
+:107F600048F6F4A09F2EC3CF39E4B7EB171CBF1D12
+:107F70001E718EDBF6ECA0FF3369D0FD0527EFC73D
+:107F800074FA21FFE909FDD87ED437BFF6DBEFB4E0
+:107F9000B057AB676EEB0896E0B99E147F6FE7159C
+:107FA00066FE9ED6EADD4D94E7A78C7B2E85EBBA64
+:107FB000BB324CFA06FEDE12CAED4C3BD1B10F3398
+:107FC000F571A7CCDC0F33F36022B65E72B2BC8CC5
+:107FD0002DBE14C5ADAD26265F70BF684C9FF3B2B1
+:107FE000EF44BF6DA1969771BE99E75DF9F7F17CFB
+:107FF000BC0E486AEEF93BE71FC8E62BE1FE43B72B
+:10800000DF36589AA6FB19826193F44581E991A461
+:10801000576A498A03B60FF3BBD9AFDA72A269DC9B
+:10802000C5B4DFB73FE3237DABC6CE7F6B19A75244
+:10803000BD65DCAC389D3389CC52FBB3F4B336520A
+:1080400032E2FE2AB1FD5F1F61FF97FCFCDC574B5B
+:10805000EF5C15CF47758497F7A1DDDE118F91FF97
+:10806000BF67DC2CCF3DE4527C0EDD572185B99EE5
+:108070002DC555D2B3659C7FF9507BA7DD9E1CBEF4
+:108080008F3036273F6620DC49EDFC72C2447F8B7F
+:108090003FC6F38CFD1A8F17064B4550B39CC7782B
+:1080A0002287DFE3D5519ED4D0AFD31197E95C4747
+:1080B000875E315CBC95F4A2FFCD113CF4DB62FB22
+:1080C0001D5A5628A417261A72B59A7C3A97308002
+:1080D0007CDE116E5631FEAA8CAB1CB15F45E3FD10
+:1080E000FE7FA3B2F95D0080000000001F8B080036
+:1080F00000000000000BCD7D0D6014D5B5F09D9DF6
+:10810000D99F24BBC924BB9BECE68F09241A34E019
+:1081100026240134E224048A167111D0D052D98069
+:10812000282A48405B57ABCD8604842035F853A9F4
+:1081300058BAB160ED57ADD1D296D7222F28F2FCB4
+:10814000414DD52A58D400D66A6B6D0469A9FA3E10
+:10815000BE73CE9D497626B34950FBBE872DC39D85
+:10816000B93FE79E7BFEEFB9774F9D823F1730D630
+:10817000BA27456595F05CEA88A71431168E966794
+:10818000D74F60EC1B59E1CF32FC8C393C8BE49823
+:108190009B313B636A173C4F69EDF4A75716188370
+:1081A0007AA2FCF329EF7A077FD79F62FA661681DD
+:1081B000F6AC587AAFD7C5984D61C2291B94995B2C
+:1081C0007EEF6C467F4E89F8774F20EC49DE8FC7F3
+:1081D000F58B29EF4E18DC6E7959AF4354185BBF0D
+:1081E000AD23CCA0FCA900852A843BA6E6C1BCAE89
+:1081F000DFB99245CA18DB28F5B8648063E3E7C2AB
+:10820000C270D9E0FE17E37CAAB057298670C21F5E
+:10821000DBA973E06F85298E6AC6F2F0CD687CF227
+:10822000EF30CA9E53D07F7937944B3578E0FF13F7
+:108230009E3596AB7A8CE589078C65C642F6F03898
+:10824000C65E6B864ECF646CCEA10F0EB174C6E6CF
+:10825000C642CF3CE9632C577585E33263F358E897
+:1082600099B7A09CD790C6BA4330B88D2DC57581FB
+:1082700069BE510CF035308295E52D4D65CC35D079
+:10828000FF7C3993D6A9A1B771261BCFD8F76F69A8
+:10829000650CFA89D509F1ED00FFECFA6DB3C7C0A2
+:1082A000F3FE4A5BC143D828627F17E7E782CE4ED0
+:1082B000C17C336D2B478D86FAE1A969422BD4FB33
+:1082C000FEB967AD2F8672CFF49210E21DF0F56E05
+:1082D000FF7C00FFF3C2BCBD3EFECB95C7E68E819E
+:1082E000E796CA2766E3734E627DE86FD6A4CE1682
+:1082F00007F477C932A502FB0BD71BDBE7D518CBF8
+:1083000000399F0FFCCB9B3518DEE1E0318FAFF7D2
+:10831000777FB342F8679F033D003EC3F809DA87D1
+:10832000A53E290478CEAD11D438D04D9E2AA89D03
+:1083300016FCD0AEF18319FF622C83219FD5CD139B
+:10834000E3ED5025D76527FCE7CE14E20A8C9FBBEE
+:10835000B4AFFB14942F73D9E3227CCFCAEC12F094
+:10836000FBFDCB18EB2822F0D26B13D6F77ED71A81
+:108370007B217C9F1714990DE880D58CA1F1088E84
+:10838000D1848F231C1F2EC247DEB2D0333F82F12F
+:108390002F9FE49445A87F7903FFAEC3B751023AFB
+:1083A00083EF1B81CE624467D29144FCCC39B47C0C
+:1083B00039D2E31CD3FB62A88BF3FDDBE403671423
+:1083C000025CCB858E1969004A8ABD89315C68C020
+:1083D00020D2B5CE8F3A9E96EF68217E4CE033FBDB
+:1083E00029E467FC7736A186F8EC29D72F65941B22
+:1083F000BB337BB73020E1AD328BD5E733F69FA995
+:108400007D670B50DE2E5FB66EDDF9F03DA5EFE720
+:10841000AC9C31A7F39B336624945353AFA6B24F61
+:108420001B07A610E3EBDD3F2ED1C75F650EDF060D
+:10843000956D12A12CD9E44DA1A2817659D84E1880
+:10844000A25D986D922CDAB9F57680A7B5B07EA9B9
+:10845000DABC52B5EF360D9EC4F125C49BACB8050D
+:10846000580F69BA2423BD7C5938B2879B77846D35
+:10847000B28F19DC0EC06ED1E1B759C31FC7EF89A7
+:10848000E3DB8780FFABC6C770FD39B4EFA70D1FD4
+:10849000545F9D9D7CBE08971DF595A2B86D09FDA2
+:1084A000DCB9E75F2F9C03C42BCD67A114E843B26E
+:1084B000AB7208E8BC4CBEC7859D4B99F57204F8B9
+:1084C000613D945578BFBEABC3A5C0FBB2E2BBD63D
+:1084D00021D19775A7329407E3989CF908F43B4E95
+:1084E000965837AEDAF97B6D69506617B35009F4C8
+:1084F0009BB12795E44966D1B93F1160DCCC4C971C
+:108500008AEDD332AB7FC2883E982225E023ADF6B8
+:10851000B5BA34846B360B212B4A429CD522938DFD
+:10852000051E8272E6B46DAC1ECA157FF32822F2D6
+:10853000B4C4F55D3BB6473DDDC6F6A17E096AF2DF
+:10854000679D43DE44FAE35A89A1FE481B778F807A
+:10855000F0DC0F5D89C097656559B3EBA15CB6DFB0
+:108560001652149C4F875088F30988A4B7747CEA8C
+:1085700072A4E2E36ECEF463597C3BC0DF668F7772
+:10858000A3BC8A4DBE5CDE0EF0E45E9920AFF1AF75
+:108590003EC001C2FBE2A5DBDB8B90BEA57713FBDF
+:1085A000CBF838DE8DF28CD53684B1BD6FA66490E1
+:1085B000FFA99A3C4B35E981E62C3BC9335D1F305E
+:1085C00055526498B7A0CD9B7D2F4CFAC0C9422E5E
+:1085D00007D92B0BC80E1158AF702A0DE68F151155
+:1085E000EE023E8F41EDAB797B1608B9D0CE71A675
+:1085F0003635617DF898D502C815AE4D55513F0B03
+:108600000EE60A56C0BC6D2CD20574D2223009CBBE
+:1086100003E375331CCFE94A6B43BBEB2957AB0D22
+:10862000F1D7FA2CE80F98C7ED76D6807641AB1CCF
+:10863000726541FBA866BFAD2A1F9D83E50CA0EDC6
+:108640001EB41BA4B08C74B9CA5F9CC3E07DBAB7DA
+:10865000F79B2867BF96F9AB19AE0290A37550E758
+:108660005C90FB9B1E5B17AB81F14EE63125C1CEC2
+:10867000734A4D0CED29E7C942C3FBEE6698D199C8
+:108680000365D56DABC771AECD5408AFB54C6EC3A5
+:1086900076B5800C25615D9C27834C9960D57FBEA3
+:1086A000E17D37D8498A7324FDA731A534B1FF3164
+:1086B00049FA3FC3D4BF6CD9FF40BF5E43BF6B24B0
+:1086C000467674CCE7A67537DB05AB33EB5664A270
+:1086D0003DEA644D5D1676674BA68DE0BE3DD0D475
+:1086E000A342FB3A068C0F7472C1E7474446F60C6E
+:1086F000AC14D00BCB97FAFAE97834D6E3F46B8B51
+:10870000090CE5D20592DDC0275398B16CB68B4AAF
+:1087100060AD715C9BA7B207E967953F55715AC080
+:10872000AF3F7B9AD994E212986F6A7829033EBED4
+:108730003F739F6B4D00CAE99C4E1ECEFCE30CF4C8
+:10874000177A044E7F6B7C36C24BB82EA7534CE889
+:1087500037EC60252817C348DF6E0E0F8EDFE3CF9E
+:108760007FB0DD627C10BB06FB61B62A4C294E98B7
+:10877000578F6607F78F3735AF13F9A07F3C27ABCC
+:10878000A2F144C07FE278D95F6CBCDFE3FCCA068B
+:10879000C69B3DDD38BFD90E99E6375BE35F7DBCF4
+:1087A000DFE3FC8ABEC07838BFC4F1BE669CDF6CD4
+:1087B000A74CF39B2D72FAEA1F2FFB8B8DD7D35C4E
+:1087C0004A76F0ED0E904F4027A9E53B5C6360DCF4
+:1087D000DB5D76595006DAD5D6DEE09A8BBAD73D06
+:1087E00075BA1FC6A99B069573B197A9D36B8B1950
+:1087F000DB2470BAF8EBA63FAF43BA383E73552975
+:10880000E913CDBEBE04AB823EBE44E2F0CECA77D1
+:10881000C75B12F0783FC81115E07800F85D057E5F
+:10882000DC0A7C89E57873809E0F82BD8ECF6D0057
+:108830002F7E7FA83944E5879B27D153EFA7741279
+:10884000B7DBC7D658DBED676471BF6F53509E7FAF
+:1088500025EAB5DAD410EA4536E93CA626DAD5ACE5
+:10886000E9A914F8BEF132568EBAF18CCD1C6E5FB8
+:108870007D36D9EDA9E57B7B9AA17CBB6457502F4F
+:10888000DFAEB019567E7311EA992AB457797B7618
+:108890001EF7C37CE1DEBDA8F7E6A09D0E78F5CFFC
+:1088A000EDDD8BFEDFA56097935E6687F7BE05DF83
+:1088B0005F03FFAF1DCBA29BC9509E35C74FE3C3DB
+:1088C0009FF4DA6CB4DFF99FBB671E23BF229CC202
+:1088D000F5828FCD7E660FC21B722871EA8FDD1B79
+:1088E000463E50ED4A3B8982B01DF5B41FF5347CFD
+:1088F000AF3DEC6436846F9A83E4DADCB946BF613D
+:10890000534AB78CF6CFA6721F6B81FE2F9D69FC70
+:10891000EE74727E0B9BFC8659A6324848EE778B2C
+:108920000B32D0DEBF1D5F4D1E8CB7E8A196DBF782
+:1089300026D0695E96C747718033D81928CF4EB0CC
+:10894000B23BEBF1637E16192BE6F6FF6C8EDDBEB3
+:108950001750FF32CABD2AA46F2E3706F307876768
+:10896000B256EFFEE69E29EF960CC0972BC505D4B4
+:1089700003794BE17DC27C255F5C407F87898F94C2
+:10898000A37F639EC7FDC2234166319EFECC65D2A4
+:108990007B88175C4A94E7E6F94E1E34DF9A978B82
+:1089A00099153F299BD09E9BF5AC186A5106F0A102
+:1089B000CFFF7F9AAF8E6A7A86A93ED60DF4F23247
+:1089C000D07B3BF76318DAA93ABD4205B29F2EB9B6
+:1089D00004BE235DA86A01E2F3E5D17DDBAEC27679
+:1089E000203B5AD1DFD5EDA0EE8336B483BE68BFFD
+:1089F000975CEB207B8BB17AF9BDD281FE92AD0FF3
+:108A0000F6FB5E82FEECB713F14FB526FA10C69660
+:108A10005080EC819BC13E467F3F5AFF8194CEBF80
+:108A20001F49B053F1CF9184FE5AF7FC4C5000AE71
+:108A3000CEE6AE29EFDA13E4C552D9B606EDB99603
+:108A4000B84071886EA807F6C0E8A58AAD0DF07F22
+:108A500025F683F46992EBA3DBA09F443BA566AEA9
+:108A6000FC08D0435B595D47089EEB37F378995E6D
+:108A7000BF3F6EE68B917F6E674D4C00381D29DF3E
+:108A8000FB712FCC476D9558CA1428DBB9BDC3DEE6
+:108A9000F2905C10DD4D3FC5EF8118C82D9C775DCD
+:108AA000D363588ED958B8159EF7A5F1F651C9254C
+:108AB0003B431827699B81D3CF0C46EECD02FCAD1A
+:108AC000C94E2539E878DBF320CA294766C552B478
+:108AD0007B1644BF1BC678A4EC650BC316F4B540E7
+:108AE000B31FE2593CEE72C8DE5D900970D706EB09
+:108AF000E2D8EFA0FAD1EF517F53446B3B6CA7D67D
+:108B0000CF169BB55C785CFB7EF9F2273E7808E6D1
+:108B10009356EC0E21B9AD3F87ED106C83EBEFF26D
+:108B200047BA12E1482996258A83B2AEC968CFAD0B
+:108B3000FFEC81AEC700E5599FB949CE66899EB862
+:108B4000506468BF33AB6A70FBDDFF7A3D80EBB3E6
+:108B50003B85917E65EC850BD19FDCD85F6631014A
+:108B6000E39C995A39F6F085AAA1BCF8C25A2C2385
+:108B7000ED02514EBEFBDBEB63D85EE06516FB0EEB
+:108B8000AF6FE7F573B4EF532EFAF02777A23EA844
+:108B900076901FBA51B38374F8CEF38A443FE779D5
+:108BA00087C6E3414D2EB8468EC7835678DC1D54E8
+:108BB000DFC4F729AC4B403A4EF9CC7523B6FF61C0
+:108BC000330B5F09B06F5176FCEC4E85DA1FB6C2ED
+:108BD000E35941F508B6772D3FF2933B010E8F0E16
+:108BE000C74476631238FE32D47AEEC8E6726E9EBF
+:108BF0008FEB8D2CCDDE74387A02B3E12957FEE07D
+:108C00000619E4CDDAA2AE06ABF8F309AF8DDA654A
+:108C10002689B7677839DE76E5843F4538DAE42778
+:108C20005C387EAAC0C2587FC3A45E2624F47BB6FB
+:108C30008FAF03C06DF342BBD4C94C453AF3304FFC
+:108C40009C019D792A39FC1B02AF3105DA794AE192
+:108C5000E9C6F7BDC4FFE87270A106820ECA0E8D88
+:108C60003E32EE6EBF10E9214BD4E92DAF1DE9C5B0
+:108C700061D3EBE75D84E5CE2C5E2EF7E5B5C7F258
+:108C800041CF38A00DCA855C07D93BE6F9E568F00D
+:108C9000B6FB55BFD76F814F672FADD3C6718E50CE
+:108CA0000CD6758AADA761317EBBC84DF61ABC6F74
+:108CB0008827CC7FBA4687D3BDDCDEDAF82F57434E
+:108CC000DC623D92D1E978EF69D3E978AF359D9EBA
+:108CD00083F84FA0D34F98359D565BB5073A9D68F2
+:108CE000850F735964EAE6460050FA74FAC377A216
+:108CF000B6FA7ACDE6C7E039E533B7E4853AE2194A
+:108D00008CEC449B8BCBF701B91F9986FD4B7213FA
+:108D1000BD17DD61DAAF79318BF73FA8DF89D59BCD
+:108D2000516E8DA0DF30CEDBDCEF282F8777CA4570
+:108D3000EE48DC02EF27BD12F74B7D7CFC64FC5251
+:108D4000EAE37E73527ED1E93F271C413886E397E0
+:108D50000B06F865E9C8F86507F14B5A19E797B4AF
+:108D600024FCC2624EE28FB545BC7CF3DD3EE28757
+:108D70007EFE899518F9275662E09F69F794507D29
+:108D800073FB749CB7055E625E7D1EE1669C877A0C
+:108D9000B6DC2692BDD1CB504E75B2BE3D4EE4C37B
+:108DA0001A21B41DDECE8AF5D4BB14FCDEC3668363
+:108DB000FDB14EA3FBAD080FFA43D55A3C4BEA6117
+:108DC000977A06F3B1A7B2BB349280FF020D8F975A
+:108DD000F9C277E2F89DAC772CDAA5C9D6E91E0D69
+:108DE000DE1B03EA3D56743E9CDED9897AC78F4F5D
+:108DF0000E77D667AE269403663E9F72FD6F3F786E
+:108E000068887E7EA5C1F1A8F63C0DBE7FD46BA517
+:108E1000A783EA2F4C7C5F298CB6E4FB5F59B5072A
+:108E2000BEFFB5153EBE049F3F65C5E70F7879FFCD
+:108E3000C3E159F2713C4BBE2F87E723DA3ABD7983
+:108E4000FA787E33099EFFE8F58F08CF4792C8D79E
+:108E5000A35E82C316C37D01E477F4DFD74D8CF5A2
+:108E6000E17EA8051C7F4DECC7A5F07EC0B4FF4491
+:108E7000003A9FF2E9BA50C4822FA1DDB144F8F55F
+:108E800076F77865CD8F5056A25DBDE5EB6EDA4F73
+:108E9000003DF80FEF572BE76D3E0B793CC5C6E55B
+:108EA000D065771F5E8F719A2FD17FBA55FFCF693A
+:108EB000F4359CFE2F4AD0FFD88F59DE75321E4FF5
+:108EC00069F747F27D84AFDE0B513E6DBD254B4007
+:108ED000BF2E5FED16D0FEF76BFA65A397FB337AD2
+:108EE000BBAD52B72061FD2659880986FECE18AA6F
+:108EF0003F331C00DF5884EF329F7A163EEFF1F6C5
+:108F0000DB7BA7650F5507D40A6C0F72BA12C757DF
+:108F1000CF34CA697D1EB67017EB45FD02EE77DCD3
+:108F200082AEFC9ABE847ECEA77E34795FE5D3E91B
+:108F30008AF777BAFA06E09BAEC137039F66F8CC92
+:108F400078190ECE9B104EDEDFA5897026EB4FF709
+:108F5000AFF575227D9A10D75938A0AFAFC0FE5C2F
+:108F60006B6C31E61BE05F5D5F83644AC5FEB7381A
+:108F7000781C75CBB2BB6A31DFA0F356B91C519295
+:108F8000BB94EB39655921C555AFD1FA35C3DFDF45
+:108F9000DED1357642198DBB1CC7BDA08675A3DC1A
+:108FA000C8403B81E20FB284F1852C674700E3B2F1
+:108FB000EB858E8645A8472F7493BE6581B996F1DF
+:108FC00029FDA9C79FF479B340E530F55BA8BE9CA5
+:108FD000D6D18476D288EB3B3B2CEDAAEF6B76158D
+:108FE000CC6FFD90780DF828BEA5E377F0387CFDB6
+:108FF0006AC34D02E23BB50C8604964C0D77D066F1
+:10900000ABAD38CE7AD17E2A057AA1FE5EB38CFB59
+:109010000DF4B75687EB01A4C72F0B975E2FF97895
+:10902000BC1EEE9F51BCC3CDE5167D80F2B167BD7D
+:1090300096FB07FAF3F666599540FF1C93950C8C46
+:1090400017DEAEE941C642814B3DFFFE7A03F3884D
+:10905000F378A7A97E9471BA670117D97718864F5C
+:10906000A49B577DDC1F6DCF0E3FCBE56328847436
+:109070000DE5E711FFCC05650F95F75359EE2FBFAE
+:1090800044F503BC3E93E511E119DAFD81DA49FDAF
+:10909000FDBC41FDBAFBC73D48DF7DFDE53FD2F792
+:1090A0007C5E7FA4E324AC2B9F7F8F48F3FF445268
+:1090B00033707FF4B2E8628A13CD8F5E43CF75CDF3
+:1090C000722DC6E35E6AEE6B6B83E765F317CB68C0
+:1090D000F7CF5F7237EDDFEBFD5F827E05F2BB22DB
+:1090E000CD20BBA8C816DEE61EE0B70138DAB43CD6
+:1090F000B3DE7AA42397CAFADACBA1FDA48FDBDA18
+:109100000C794E1D943F93A2489F26C6D57539F819
+:10911000A143FD94E63F723A36CD97B1BD30FE27AC
+:10912000EEE2788CE8BA4EB6E2177DDEC9FAD7E7F0
+:109130009D4CCEE8F8D3DFAF2FAE9079FE4FDC80A8
+:109140009794927ACAF7B944D0E0F4B8347EE3F544
+:1091500066C1384F94117D2848BFB3343FCEAC1759
+:10916000F4713F74448AFCD80EDEDC5A6181DF1151
+:10917000E2ED40F3D270BD1DE571570AEDDF339982
+:10918000E2FC7ABD8624F33FDFCFF50873AA349F53
+:109190000DB765C4D1EED8D0F82B19832B69E33E07
+:1091A000A98AE153E83BB108E5CB6D1ECAC76868E0
+:1091B0003C51D592D0FFC2A7FFC385F1DE8671ABCB
+:1091C000FD187759C8A44F12F31DCCE33644AF27DE
+:1091D000BA8DB5080D56FED61BD99CAF17628A8C86
+:1091E00048FD1D49DC476E542A1C189F688C19F7EE
+:1091F0007340433A903E16AF33BF4FD8CF11B17F83
+:1092000046F38EE1661EEABD3536A2B72D8037F4EF
+:10921000030B415DE2F38DEC2C8D1F7B089FFF6EED
+:1092200078DEC896F9BE9B8BC5D2B206E82627D257
+:10923000C1503F792A05DADFF479F4FC882ED25345
+:10924000F7B8F532E82DC07FB84CB3738AF9771BB5
+:1092500096D1FF49EBD96B033E5E73EF531705C6FA
+:10926000427F6591804DA6F2F3921FED2F5E66B1AD
+:10927000A79EDF4BF6AC7C961002FE6FDBFDFCB3C5
+:1092800005E4CF6BF6D8EEE7C91ED3CB8C753398C7
+:109290004F676A7F597505A03CBABF1CC3F256CD13
+:1092A0008E5F73EFEEE7DBC83E09C7FC097AB29622
+:1092B000F1F8F257AD1F3B035776603E51ACD846EC
+:1092C000FE5EAA891F1FF13BA85E514EE42EE2C745
+:1092D0005BFB248C373882AFF9500E8C2A3EA68E69
+:1092E00006FA1F55C3D36458291FB7B37815D90D93
+:1092F0009DDABAC0FF56A3DE1B589F1ED3FAF0F5C5
+:109300000857F6D0FA78CA7A68BD6C58A6B81FDF3D
+:109310008FBFB892DB1BB293EF2B6CF7737ED8E153
+:10932000E7FEED0E3FF74F338AEFA2F84ECA0C1B53
+:10933000D5CFD09E6639BEC32F69F29CE3637730E8
+:10934000D2E54FB05BE17DB8B412E59B2F0BF75926
+:109350006B8BA51B919E7FACF9A7B04E77D23A15C7
+:10936000F952237CDD7EE3F75BAC5BE9C8D6EDF513
+:10937000E608C9AB64EB76D97C316C15777B5EC3AC
+:10938000C3470D7FFA014E67B9ABCF81FB30EB8B42
+:109390003719F2AA5D3B6677632EB49E57BD3A2D0E
+:1093A000BD06E5B679DCD73FFF2F1FE277E6BF9C0D
+:1093B00096F2F1634D3EBED6DC40ED608115299BEF
+:1093C000E400E3792FFD7962C229274DEF75CC4384
+:1093D000BB82589FB1B9E1C3B45FBD282032DC1F06
+:1093E0005FC88C79652CAAE705F33CD8D725704D6A
+:1093F0000185AFC78410608A354AB375B962C80F5A
+:109400009B3777F63EDC875FACEDC3837C317C5FB6
+:1094100062CA1BBBBCA1315CAF7D3F4E7FC7094F09
+:1094200073156E37CE75BB49BFCE0BCF0FD727EC68
+:10943000C7BDF1DFA2651EFAF9D93A5EC2E1FA9220
+:10944000C1785914161CB2323C7ECCF8A89538BEAF
+:109450001A357C99F163C6C3E2B9B369FDCDF37FD8
+:10946000DD1526FCBC0EF8C17C61333E188B5C8C8C
+:1094700074FBC67C91A17D3C5D9C69C73C81C5B3F2
+:109480000586F9454B58289DE707ABB3A625C06B69
+:10949000C6A3195F8B9F64A16EE877F1BD1E5ABF0A
+:1094A0005734FC88DD7FA77985615EED7C5E477867
+:1094B000FEAA4CF3BA542D7FC607DF236D206D152D
+:1094C0002B3DC2E7B308E6D32E0FD62727584D13FE
+:1094D000D2C91253DE82193E33FC33510E4E1EBCEC
+:1094E0008F5F91ADEDE38F67216D1F3F838E3584D4
+:1094F000FC43E62D0CF039A7AF85D1D9FDE361BF60
+:10950000028BF49765C0EFCCE7BC1BE7C1BF5705E2
+:109510004405F30467CF1FB306E71F66E18CEE2214
+:10952000B4F7FBEC28472E6560C642BB0B6092A8DF
+:109530006FC3F52954D6FB3DD6F1B19DF47884353F
+:109540006DA7FD772563EEB8E4F26555C041E39958
+:10955000ED9499E52519282FCCF8D0F1340FF1922C
+:109560004678197F3A7879017515FAB318478375EB
+:10957000ECBB86B107CB07F68F59BECAEDC96C4666
+:10958000FBFFD764676A764713C51D16687AE190BA
+:109590009D353CEEE6FBC81509F2F11BC1DA6BB252
+:1095A00013EC547D1FD9CD7A097F57B8DCDDE27802
+:1095B000A2BB0FFBE983E4979EAF19A17C4D3163F9
+:1095C000994271B1B4F4F12C03EC62C6E70D7ECC84
+:1095D0008DD97E7C5F18472360E6733F59374F195A
+:1095E00058B7F5576EEF40799CB2E49731EA5CE1E9
+:1095F000F91C69DABAD56AEBD66F4797C2FB04FC4F
+:109600001EEBD0ECB0522D8E8F7FA07CAC588D0F0E
+:10961000E5BFEAEB98520AFE87218FB083F0ADAF29
+:109620002738117DC89791804439C336E622FF3828
+:109630007233CFC758C894AD981FB4306A3F96D8DC
+:109640004F2428111C91F5295ADC2444FD2C0AF2E0
+:109650007E5829F7F3FAE93E06ED13F21F6D2E301E
+:1096600025B17D260BA1FF04FD65A3BE67EB12C6E5
+:10967000193D78DC64FD99DB89DAFEADE80C8542A2
+:1096800009727ABB663F1F0B5476D94627C7DF2283
+:1096900097579512F2628F045D0D567131BD3F5D93
+:1096A0007FF7DB89ECEA1712ED44B7A3F18567CFAA
+:1096B0004FB01359E30BB8EFFF45EDC497B21B5FF2
+:1096C0006883F9FDF3ADAF51FEF8B12610988047DD
+:1096D0006F742A3BEA45F92093FE2A6C008F0A93A7
+:1096E000BF25652CD27B4A344F9512F265DFC856F0
+:1096F000087E6FB14AFB65D0B40B5D71AF141210D8
+:109700006F7769713320DCB1B33D89EDF8BCF5F1B9
+:109710009C2E99E070E8E3B1500BE5D7CF64A447E5
+:10972000F43C109DAFF57E8E661BE37523E0E7A346
+:10973000D9FEC1FC2C8A4DEFDC8672E20591FCB0AB
+:109740006F056EA6F7E678C0DFB2B97D582046FEF9
+:1097500086FDF434BCFAAD9BA0DD8A1DCE10AAE1D3
+:10976000E5DFF9E0FB550AE289AFFFFC258BEFADA1
+:10977000C279954832ED6F14F0388CA34520FF353F
+:10978000A5C811DE01CFC3BEDADC9C04B80EFBEA2B
+:10979000A93C7A0687EB18F4D9AE60BB4D0DE42FD7
+:1097A0007AF8BEF73145C960245718D913A2933F00
+:1097B000DD393C2EECCEE1F13C2987E3DB7552A08C
+:1097C0004542BA6EC27D0B294679D0AE9312BD7761
+:1097D0000882A5BDA6F7E73A09C219F195666EEFB2
+:1097E000A0F7381F6C2F7A99C1BEF1E7703BD9DF23
+:1097F0000F471A87C36BEE279DBFD7F8CF0CC78AD8
+:10980000ECA941C4CB619F9A9BC3E3285C0EBB9F2C
+:109810003F208C1F893CE6F9FA17072517C5F56E1E
+:1098200013E225209FDA4B8FAD21B955E46AC2734C
+:109830005209F693C0CFDDF0731503F669DFB43932
+:109840009518BD66CAFDA1C1F6D63B9527E6CDC1E8
+:1098500082767EE20A5DF6C6A00CF6DCDB5AB151D8
+:1098600019BD1643FD97D470FB6C31DA6721925B0A
+:1098700006BBCB6C9FB941DFCF01BA58129064A4EC
+:109880000BB39DD65E398FEC9A76B06B305F7BB0B0
+:109890009DC6E5CD1D511B53A1DE4B3522F9192F75
+:1098A00095F63E7701EA8B497685F44569DF1D73AD
+:1098B000E8FB041AC7ADF977509F9F7708A5C54B01
+:1098C000E0DDCB3547DD8B13D6FBA54947C7A25F4B
+:1098D000B035497E851EA7D97B0BCFFF7AE71E21C5
+:1098E000EE44BCDD2ADAB0DF85E51ECA5B9D26BAF0
+:1098F000699CC51BC5B89370A8A64FCB1EB01B9919
+:109900005893FD2AE2E14E3BC3F3830537F61AEC88
+:10991000DC8551A33D176902FB47397D3BD06CFFC5
+:1099200099ED98E5399AFD52C12AD07E79A9792717
+:109930003B5A3260C7CC4AB2FFADDB31E7DAEABE50
+:10994000ADD133ED1FCC92ACF7F72FD6FC5316E216
+:10995000FEE034F1435AAF63214941FCB96F7E9E6A
+:10996000CE75B8FF5B0C5B8D77478E43DF8F237915
+:10997000BBB5228DF2AEF7DC72564E2FAD97725FFB
+:109980000DAEFFF3769283C9F45B4A5464C530315F
+:109990004F54A0A7BE9EA3A2292C513F8C4A92A748
+:1099A000F0A31C3E0FFFADCC867E76668CA9567E5A
+:1099B000A95E0FFCD1E918A386FADD9900DFF5C591
+:1099C000368AFBEB7E698A9D9FF7B5EF5A1943FFF4
+:1099D0007414C0877028001FCAE1A2681A9547470F
+:1099E000BDF41C13CDA46771348FBE9744C7D0F368
+:1099F0008C6811BD3F337A36954BA313E839365A3C
+:109A00004ECFB3A2E7D1F36CD05B58AF2C5A4BCFFB
+:109A100071D1AFD3FBF1D139F43C273A9B9EA1E839
+:109A200037E97B7974313D2BA28DF47E42F43A2ADA
+:109A300057466FA0725574253DABA3DFA5E7C468F8
+:109A40002B3D27455BA8DEE4E8062A9F1BBD9B9EB5
+:109A5000E74537D1B326BA85BEEBFC9CA6D9D32FF8
+:109A600006B6C9946FCFBACB503E26E3C3439A3CA7
+:109A7000AECB51F722FDE9F5F66BE70ECCF50EE41F
+:109A80000C9D77F3AAB65E1F858EFC008FD3EAEBA0
+:109A9000B63E30741C8195F986D9B7E2F37B3A471C
+:109AA000E1F42B7590BDB1B589513E98A7B24740FE
+:109AB00079D319906658D1913BC0F3C08A7222477E
+:109AC000517FB883EFEEC5FDA84B623DBEA9482F7C
+:109AD000215FEA54E86F549B8DDC6B85C902969533
+:109AE0007A2677B381780ED85706BD260574FBAD6C
+:109AF00067E60484E7ACE20AB25FB5FDE4FDB78C2B
+:109B000066E8776C75740B12CACB558C25DAE15B6D
+:109B1000D72E7A28F19C8614E0FC396A1D7B0AE373
+:109B200064451D4A1D9E271CB3597D0A533C4BE2D8
+:109B300091BA54289FF970EC297C8EED8AD7A5C183
+:109B4000F3EC9DDD4FA1F819D7DD5BE786F239CF45
+:109B5000B2A731FC54DEA34CF54079C201F569DCB3
+:109B600026A9EA8D4C4D57109E786B3AC0B3F56D1F
+:109B700030B4A03CE9C30E11DC9281F507BBEDF1D6
+:109B800084754929EE5145F867FE8D7239CAD9AD01
+:109B9000526F4A66D9E0F5E9C479E33C41AF6CD72E
+:109BA000F6D1E584F50805043D1EE80B24C4033B0B
+:109BB000DB5EA1786067AA5C8BA1AEBE694C7E506B
+:109BC000413AE67E42EA9AD1A49F74BA03FC1AECA9
+:109BD0004929C0E96E6BBFBD698DDF10E2B7EA7F2E
+:109BE0000F7EFF3347935F49F0FB22CE23383C1FA3
+:109BF000D706385F021F9F1FA84A5EEF2A0DFF6637
+:109C00003C6F95E4B3085F6E668B950FAC5BA34623
+:109C1000DFC3E1F59BFFCBE876526068BCB24A2F08
+:109C20008F336BF969C9E4CDFE24E7449A0283E4DB
+:109C30001C8F97CA20E7C6249773358161E4579239
+:109C40007C87DB027ABE43F8BB8111C4F5EFB0C953
+:109C5000B598EF121BCFC84F00FBB20DF37746C586
+:109C6000940ADAC642A18C78AC389BFCF422B03757
+:109C7000A40A86A98EDDF8BCB832D3B6A80CF31AB4
+:109C8000347E931B0389FCA6EBFB017ED4E922AB57
+:109C900093CE5900BD623EE12E0D4F03FDF078C416
+:109CA000DA9B733BDB13E46067288FCA7AFD64F4A8
+:109CB000FBA6F61DE405EDF75F5C639D6FF2EB809C
+:109CC000A8D9397D2AD2796C0A93E9BC73DB119249
+:109CD0004F99209F84221E1EC2F1F3A3A90F619CFD
+:109CE000F657816C4D9ECBA99779FEFFD1733BF857
+:109CF000EAC44F35F21E3C57310AF4908272B20624
+:109D000060AF443DE7A07557185F47A586C5BB0502
+:109D1000C25B37FACD311B3F9FB1DFD1A592DE7117
+:109D200064CA987FB2CB1FD91BF027E70B394D29A6
+:109D3000C745FDC3E66B67BA83989723A762F915F9
+:109D400028DF3109F3847A9956BEC33DF98BC71FCA
+:109D5000FE10B8663FEE535507D457919E81AEFF73
+:109D60008070A967CA12C58747B8FFA4F3E7003F10
+:109D7000C9E53A3F3596913C7C2790B04F9ECCBECA
+:109D8000F9A1263FFB0243DB373ADD9FB67DA3C135
+:109D9000FBF630FC3FF3B957376F6303F13F4FEEEB
+:109DA000EB3D9282F6F654767402C6BD7A38DD3306
+:109DB0001EE75331FE07749052E932C56D85195A7A
+:109DC000DC65C878AD1E4FD6E37D7A5C2F5DA32B92
+:109DD000BC3000F578FA24595A44FDF5B24BA13F46
+:109DE0004F90E349E76B945BB83FEF5A93258D2E74
+:109DF0001BE8172425C9A9CE0626B767F2FDD70CA4
+:109E0000902F1DAB19F979B19744EAFFB86AFBC0EE
+:109E100009F58E570202512EA84C91B3B573084430
+:109E2000E432D1AB93B12EF4B7D9F7422E07C6B9BD
+:109E30003F15980A70EFFF54A4A784116E687471DF
+:109E4000A83C848D6B336A42B81F281E8532C059E6
+:109E50009F519381E5FDFB27849845FCEEF248A3D2
+:109E600021BE64C6537FBD6FADA17C852DC3EC7F41
+:109E70004E0A3A74BBB32288F6CE957D6D0E6560AE
+:109E8000FF53DFD70B163F7121DEB3135CC6EDCF56
+:109E90005C166F49B49B12F6176BB09F2D03FB8BBA
+:109EA0003D6724EE2FAEC8BD158FEEFFB07F7F312A
+:109EB000720ED657BD5DE5489F7A3EEC7E07DF0700
+:109EC00060135EF02916F4B1A0FC193FD1A3E64F50
+:109ED0000CFAAEC5CDCC7EF0ACA0318E7F3C3427E1
+:109EE000A31B3F2689E3EBF13CDD0FC6789D6CC9CF
+:109EF0007746FCEBE32F10B81FCBEC02C93B5D6F3C
+:109F0000823C8904FDD48CE2D1AA53A07CADE3A1AC
+:109F1000C50AF94549E44BFFBE01EB2EB1DA675D96
+:109F2000A0E59D98DFDF1CE4FA79819DC72985951E
+:109F30004B2238EE82A04B7026D8495705B9FED285
+:109F4000F75F1CB927AB10CF0E4744B19AB7791F02
+:109F5000E5AA20EB3FEF16B2D07BC9F074C0DE411A
+:109F6000FB72079688745EF7786422DDFB904C2EB6
+:109F7000BC89F453C25838978F37B08ED678D3F354
+:109F800064CCFB55FDDF1B53E8FC8D395FE6510DBA
+:109F90006FFB34BCFCBBF365F669F87B518BCFE8F3
+:109FA000F1AC8B93C8FB736D750F131D0D139739AF
+:109FB00043CFF7D1F0C39E1E4BF7726CE8B1C75385
+:109FC0000484C746FB970D7F1043687FE9EDDC26CC
+:109FD00079A1E7EFE8E5B493028B27EC23A4495D70
+:109FE00014274D3B29D17B33FFDD6EE23F7D5D922F
+:109FF000ADB3BE2EE6F79DDABA1C68FC8F009E77E3
+:10A00000D990C22CF3893E0B1AE3EFE63C8064FB47
+:10A01000DC07B576C7239373502E3738622523E1CA
+:10A020007B1D3FAF7FFE1B17F2D98693CE1956EBEF
+:10A03000F14A90FB2DA04FD725EE837AE6BFDA8652
+:10A04000BDA649C67D505D9FEAFBA06995E67D34BB
+:10A05000EB7DD00DCC5A3E26DB071DB4FFA9E9DB12
+:10A0600013C124FB9F65439F67DFADD1F370791F58
+:10A07000973BF87959F3FB17FAD7617DC10F80AF91
+:10A080006E6874D2EE5377A393F87071630AC56556
+:10A090001797F378EFE27B056DBFCE18877D11E44B
+:10A0A000C5323C5FAFE99DA32C5C8DF6E8AC4AC19C
+:10A0B000B04F1EAE493194E72FB9FB45BC37E1A53F
+:10A0C000497685E2CFD0570CED821A9EA7C894BE80
+:10A0D0003B30CEADC79FF5F57FA9E628DD8316039B
+:10A0E0003BBF2484F16791F8EBA5D726F07BE98488
+:10A0F00081FD7005EC840DE78EA17C8F8365DFA068
+:10A1000038EF068C8BC34C377CFE9B194447A094D8
+:10A1100063C8AFE3B3E2281F178FABC846BA7C7A97
+:10A12000FCA71E8C8BBE73EB713FAE536F7313E5B0
+:10A130001D98D7DD1C6736C7974F379E3C31B73F18
+:10A140004F80E8E145533C59975766F991104FBE4F
+:10A15000207704F1645D6EE97242975F07CBDADF26
+:10A160007A10FE7930E22498DED4E6DDCF971A5DCE
+:10A170001ED4F9F07327D9234F8FFF2DE55BE9F546
+:10A180009A8399C487DF288BDB697F16F3144A070B
+:10A19000D6657EE49AFE3276FBCDA52B0DF4D12F49
+:10A1A000A786956343CB293197C72792E56BEA7C55
+:10A1B0003058FF94909D9AF67B7BDC55F4C5F550A2
+:10A1C00043E3AF146C07CFCDD47EBC2312B7D04F7E
+:10A1D0006678D24E8A2C3E21F1BDC2DFF7EB010733
+:10A1E0007D8FD529AB57FBB83DDD4AFC1973D2FEF4
+:10A1F000B94F6DCE85FA3EBF1A437A78C8A7B6E448
+:10A2000026C8D3563BDF8F146D2CF2B8055E9ECC6A
+:10A21000D5F4320B07B0BF35B5C6F35CFA737B2EAD
+:10A22000DFDFDBE3AF0EA07DDD7AB83C80FCB3D787
+:10A23000534DF676B275BB53E727945F2503FEC4F2
+:10A24000466DBD814555DCC75D630F0712E38DEB9D
+:10A2500072791E47FAE4277AD06E6E956D9427D8EE
+:10A260002AF3FCEB36B734639BD6CE676827E9E761
+:10A27000A8E8BE0CC96DCCAF7E52B37792CDF3C9BE
+:10A280005C9B76BF68F73D35C2805EB11FA975D172
+:10A29000FD0F4C95797E53C8904F6DD7F44B9D2997
+:10A2A0005F4394BF98DF16F44776E55AF86D7B7CE0
+:10A2B000EA93B8DE5129E644FA88BAACF9FE696D32
+:10A2C0005DBFA7CDD77CAFAA68BAF74134DDFB10DC
+:10A2D000AB6BFA692FD2DB6AA7DCEAA37B1EE8DE50
+:10A2E00087285EB904CF7FA6F07C16F0FF26F2F334
+:10A2F00006A15E94AF2CE0A2785447BEAAE643596B
+:10A30000F4D81E5C0DFDB5AA752A1E5DE970DB3A16
+:10A31000719F2F33183988F398EA9148EF745C9451
+:10A320004A7A08BEA77039C264A19AFC41BA3405C2
+:10A330007D703C5F660F38289ED51A61BDCE31FC1A
+:10A34000FC3FF653CBBAF7D714A1BDEDAA443CEDC0
+:10A350000F4DC88858C809FD69DEFF7FEBDB6F141D
+:10A3600062BB0231F221E2BDA761F146DCD75FB1E9
+:10A37000530CE13EC2B7BE73F00C7EDEC8B8CF7C92
+:10A380005FDA945ED46751B783EAEDF15477209E8B
+:10A390005A054F07FABBAD8757FE18F1D8DAC2E36A
+:10A3A000DC663CEFF57C87EED7380ECB89F5CDF730
+:10A3B0006BB08E957C9D9C2EDAB784F9B2BC2ABE18
+:10A3C0008E141F3CE4A17BA08EEF7FDA8DF07D8997
+:10A3D00079A7E5F9879A77BE4CF68B463F4C0AAFD2
+:10A3E000C379DD247A3ADA7D784F1AAC37C2BDCB17
+:10A3F0004EFEFE7D69E9B4AE51800FD755F4D4AB63
+:10A40000E892FD7DA748EB1C959A685E2C26B1ED7D
+:10A41000F87ED789EF9F8774A066D1AE9658D04456
+:10A4200078F93BE065B5055E807E8A10DEA777DDB2
+:10A4300040FD74385C325A36AD9E6A3AAF3CD2FB6E
+:10A4400045CAF2389F24DC2F52965765515FF3B30B
+:10A45000D0DFC6716B65F6499C0DE03D59FECA79A7
+:10A460005AFFFDFD0C9FBF725EE2F8FAB85F625DB5
+:10A47000A79FCEBAB6BAFEEF74B4B354313D94522E
+:10A4800008655C27C43FAE13AE9716B72115A4200C
+:10A490001DC8DD79480737A487903E87931B12E3D8
+:10A4A000EB6E97809EC1AE73CA91037476518BF7A1
+:10A4B000E8F2C4CC67AD2EA3BC6AD5EFE53B3432DD
+:10A4C0007905F47215E2C12CB7464A272BF304F341
+:10A4D0003D342BF3FCC9E9C41E0CDF80EB8878CA3D
+:10A4E000ABA078C5B7B1FEFEFDE20EC7681C8FC7F2
+:10A4F000CDFA824C7E30212F4B87A70D37BB799C3C
+:10A500009AE21F5203639807E72D0D0972D988E874
+:10A51000A82D11BEAF808EEE1C8A8EDCAC87CE6B70
+:10A520002CD7F373760C9D9FF365F50FAC6727E28C
+:10A53000B7D5F31DA2CFB57697CCEF513BBD757D56
+:10A5400064F0BA3E32F4BA461EC3EF6A5E35DD638C
+:10A55000C4263592DDB4CBAFBE8179A44C0A19E490
+:10A56000E220FED1E4F64D672A94AFBABB4593735F
+:10A570002D4E19EDF1677C373C86F5EF624A18E302
+:10A58000A1536CAB084F7F87F93D1822B95A8AFB5B
+:10A590003E51961AD2F4E8538887194A8B9005EFFA
+:10A5A0007D0B141B5D43AA6C62B6B291E3E1C5C199
+:10A5B00072F0C561E4608F46CF37223DEBE7ED9343
+:10A5C000C9C143A72F070F7DC572F0CF79A7A1D7C7
+:10A5D000BF0279F3098E6796376E8D9FAF08B11071
+:10A5E000C6CB479ACF06F6A682FC559BEE22FA69A7
+:10A5F0007D5CA07C29B0C32354F6B848D8ECF5386C
+:10A6000078FEEF0EFE5DACE37836E3E9F3BC2C9EFA
+:10A6100077D3B5322C19F2A462C40F77AAC7E462CB
+:10A6200011F3FB6B889EBD9A3DA3E7F5A76BF2BFC4
+:10A630005FCFCFB4D178DE022EDFBD60EFA05DC466
+:10A64000A45E867EFC4D793C7F1FF881E81B46099D
+:10A65000233F644C924C795A9C5FFC12B777327D51
+:10A660004C205D837962F0FE04D813783F41A66ADE
+:10A670006C7753EA1502EAADDE46779340E7F4C300
+:10A680007B7E04E52CCCF702BEF1CE30D6F7B38446
+:10A69000B2857F1EAB63A598B75896AFF9E90E1641
+:10A6A00020FDA8F9E9FA7D81E2F0795F95F9238828
+:10A6B0002F9E9BAFE79918F571570AB38CAFFD57E2
+:10A6C0003E975BF5BDB5756857AFF230B2AB56A19A
+:10A6D000EEC472A683EEB509EDA97459DD5791A9B0
+:10A6E000DA0CF7F37A67A41AEEBDF587B30CE59C94
+:10A6F000865C43FD6064B4E17BDED2B30CDF0B9A71
+:10A700002A0CE551D1730DF58B00C189E531EB2E93
+:10A7100032D42FE9B8D4503E73F3370CF5C7C617BF
+:10A7200019BE9FFDF0B586EFE3BA5619CAE7ECBC37
+:10A73000C550BF9559DFDFB9219FCB29E0779263E0
+:10A740002DEEBA06FA1D0DD96188F32FD1EAEDC9B5
+:10A75000AC2EC57848EB91F252F287D3CF1DD21FB1
+:10A7600036CBC564F2D8FCBE4D1BEFA3A7DEAB5EB3
+:10A7700086748E421EE4D247EE37D7E29CD697F11C
+:10A78000BC04FD7731CCF7F2F7EF534A2ACD67418D
+:10A790009683599D0F5892AF58EE2FB4092117EEAA
+:10A7A0001525C39B4E8FC3E1ED0EADDE97C5DB21B2
+:10A7B000C11807427DF2B8055C7BF3FBEF3B7828BC
+:10A7C0009FEBABCA54F230F83D0EA7AB4F74384044
+:10A7D0009F3C9EEF1F9C1FFE51C3AB57DDA760FD42
+:10A7E000AB787D5BA814D725D9BED2DE7CF3BE52F0
+:10A7F000D55294730B3CA942E27DCDBFD4EAE9F176
+:10A80000ECD6F44F695FA9D5112A1DC9BED22FF12C
+:10A81000CE8D2AC4BFC2C7D3D7D5AE06644BFFCEF8
+:10A820006CC7B0E7F01E8C985BA2BC61B37F17D5F4
+:10A83000E4B6EECF497B6BC9DF6F758FA6BC8F5630
+:10A840007515E9CB8E247E2EE8CB3FE657613CE0C0
+:10A8500046833F37100F50693C684B76536B82FF3D
+:10A860008FEBA0DEC7EFD5FE0AFCE00FF34FC34E1F
+:10A870005018F7838F338EA7E3AA8DEC84E360270B
+:10A88000A0FC5D2331DAF78E550A8A955FDCB15A58
+:10A89000B30F5773BC99F7BBCD76C6C5A19584B7E6
+:10A8A00035404FAE4A8CC771FB778D9DDFBF297B4A
+:10A8B000C301D4B77D7E077B10A0DDEBE7F1391D26
+:10A8C0002F5F541E65160CB293330B86B093A78985
+:10A8D000655D786FEBB1933C2EA2E051441FDE43DF
+:10A8E000CED76FD57373622B504F15494D98BF2E3D
+:10A8F000322503F1B2E25991C5059463C6FC7C3B55
+:10A900006BFA01C6E3988FBF8F31570BDA49199361
+:10A910008C7A2C5335EA31EF8C2C935E33EAB19C60
+:10A9200006A31E0B468C7A2C6F698549AF19F5D8A2
+:10A93000A8689D49AF19F5D89875979AF49A518FE0
+:10A940009DB9D9A8C7C6C68D7AECEC875799F49AF9
+:10A95000518F9DB373B5E17B7977BBE1FB8467EFE2
+:10A960003294AB7AEE37D49F78E041C3F7C9BDFF8C
+:10A97000C7F01D10FD0A9E67C07B687111CF7BFF79
+:10A9800009E377A63A301FFF3A3C9F09EB787EDF58
+:10A990006F0DFDB10E7E6E2106FFE17AFD9945E84F
+:10A9A0001E009063FBF2A0DDF57121D4CD503F3D38
+:10A9B000FE1EEEDB5C1310C98F5B81C156A4874776
+:10A9C0003C71A487AB371BCF3F5C13379663403F86
+:10A9D0000AC615807E90BEAE33FD6E04D883446FE8
+:10A9E000D7295213DA9566FAFAB34E5F31F5153C62
+:10A9F000CFA1CF579F9F5D3F7FAAD19FAAD11F13A1
+:10AA00007711DCD7E589F4FB3BFA7C55F88F7FFFA3
+:10AA1000D081F338B153605EDCDF67B17D7916F326
+:10AA2000B97EE72607F2A7795EE6790CB2530B8C64
+:10AA3000FB8AD3447788F8EE3591F4114D01F9EC97
+:10AA4000517E5E6FD573229D8B413E447F418C3594
+:10AA5000105E56005EF0DE70DD6E3DA6B53BF68002
+:10AA600048E79B87E34745C3873360E4C71425D590
+:10AA7000444F46FCA6951AF9F3BAB72F74A0FCDA36
+:10AA800007F8162631E60919F9F53A7119EDF3E9D7
+:10AA90007856E03F1C57025317E77D3DCCBB5B194E
+:10AAA0008CDFA5BB36ADCDB3A09BE1F0FB48817137
+:10AAB0009F4EDF9FAB05EC382CF24A75FCEDF2ABF4
+:10AAC0004FA07C4CE60FEF2E30EEAB8FC01FDE9D0B
+:10AAD000286FBF027FF8B98221F55CDF2CF4A79CB8
+:10AAE0002C3DD46E11F79398DC8DF15A7B138FFBBC
+:10AAF0000DC4EFBEF238CF3B08A724733D9922E97D
+:10AB0000719ED08108DA27196785302F6AA4718E6B
+:10AB1000BF140C8A73FCA560E838C71B780E50CDB3
+:10AB2000C8ADB7213349A152BADF1941E079481FB6
+:10AB3000E3BA0CCAD72DCED2F28F9521F38F2FD640
+:10AB4000F677AB03EA498403FAFB149FFDF7B1558E
+:10AB5000FAA99FF461FA89D5717B2D66F374B472FA
+:10AB60007B8DF699BE8238467A21FAA56E8EFF5605
+:10AB7000078FDB9E6E9C2D583808EFC1C221F0FE76
+:10AB8000CFB772F8B9D5105807E5C9E95B3F87A977
+:10AB900097D7671AFDE5B5151CAE126DFC6F66738D
+:10ABA0007F607221E73F3DEF12F316532AA03C93DA
+:10ABB0009F53D2CFB5EAFD4C2EF450FD4F02759352
+:10ABC0000BFD9837CBEFDF599B69BC87E76F05B565
+:10ABD00093715E13B4FE2717329ECF3C9AC365CEA5
+:10ABE0003BFD8756FF1F0575F4C473B4E8973844DE
+:10ABF000D1129F530A799C40BFF766BA7E7EEE5E03
+:10AC00007EBECE7CEF02F0C9EBF8FB5047EFB0936D
+:10AC1000BF07FA88CECF2DC9E3E710CDF729444A04
+:10AC2000E57D285E4FB032CB7B7906E5391CBA99B9
+:10AC3000F2EF5E9ACC6421387CDEC36585C6FB11D9
+:10AC4000BEC039BA2B0A4790F7B0503B47D79BCAD2
+:10AC5000F5585FD0157FD0C2DF8D6AEB7487E6D7D9
+:10AC6000E2FE34EE93E3FDDE56FBE5D1424E3F2398
+:10AC70003D577D97231241BE359FAB4E769EBAD786
+:10AC8000D1BB2607E11DCB4268BFE72C90F7E4401B
+:10AC9000BDD47A85CE3FAE2D62E993F07BB92D8489
+:10ACA000E73A32E7CA6BEDC8A7C52C4B80726F6CD0
+:10ACB0000E8D7F4703934580ABB390EFA32FBCF578
+:10ACC000631ACF5F035353E8DCF974F4CF620D8C41
+:10ACD000EE2D34CFF32E8D5F5C6BF83D3919C5D660
+:10ACE00079F87769F408726B13F2456D31DBC1CFE7
+:10ACF000CFF2730A782D3DE56F8652695FF01258E6
+:10AD000037BE7FDE43EB776360EA7DB89E3ABF399A
+:10AD1000B43C05F379F2CEC2D33B4F9EBAC01ADEE3
+:10AD2000DF69EBDDE80FFF14E14D2DEDE0BF5FFAC9
+:10AD3000F9A95362B5F6D38E0AB68F4450FFA580A9
+:10AD4000FE13F0A9C8748E96B9043A0FEB529A8894
+:10AD5000AE522685BCF8BB68EC4A1BC37B5CA66A76
+:10AD6000EDD50626E0EF49502E20C969D3EF4BA858
+:10AD7000A1B616683F0DF7CD4298F71D5A8AFDD54A
+:10AD8000BB53658C6FA61437D5E27A3DB390F7714B
+:10AD90005792F312FA39FB81FBA796BDBCB726E1A7
+:10ADA0005E81B557BD6CBC7FEAAA97BFCCFD530747
+:10ADB000B75EF5F2FFC4BD02BA7C03356447BBFE43
+:10ADC00080C8EFD1FBFB9397DB711DD6D6B22EC4A2
+:10ADD0007BEC53C0B36B00CFF6BAF0335BD02E5987
+:10ADE000951EE2BF2712FB16C2F9761A93B1BD9EDB
+:10ADF0006F28B052D2D7731B04B21F98D4773D96F8
+:10AE0000E7EF4A93D17FF8FB936F14C4803EDFBA1B
+:10AE1000EDB807F353DF91FA3C08D7FBB7BEEA4120
+:10AE2000FCBD75AB48792874EE3B214FEC738DBEA9
+:10AE3000168C0A1F47FA5AD8FCDFD589F6198BFA07
+:10AE400049DF5F13078813EDDE87D30CBF2BBABC35
+:10AE5000CB6B28EB7A7EB9D3FADC7CE5282E97AE53
+:10AE600079A4D391A7E0F811FB2898E7FBDA39A081
+:10AE7000F77778C88ED7E159F448B903EDE17776D2
+:10AE8000395937C5057BECCCCDF507E65D44F8D0E4
+:10AE900083E0DCB73BCF817CB644607D4E626EB60A
+:10AEA0000FF1FD27CDFF33CF63C95BB203D77749DD
+:10AEB0002DEBC373678B6E14D6DE04F51745DCE407
+:10AEC000F79BE769D63757E37D3682D53D704DFB5A
+:10AED0007E07FD5C09FDA0FDB9A4C3F8FDD8B3371A
+:10AEE000ECDB02E3EED8E9207BF1EA61E2FD6347A7
+:10AEF000697AA99A4D3C3586F45FC63825B9DDA13B
+:10AF0000EBA3F79B1925A9FC057FDF179E1F36CB06
+:10AF1000F43C5EA8D07A5CB773CF3EFA6D61A9A706
+:10AF20001AE5DDCCE716A77D830DE4155577DEF035
+:10AF3000F41662053D5FB59BE27B13B5FB5FAED6B1
+:10AF4000CE7F541D30E7ABEE79E67768B7C1FC4F92
+:10AF5000E7DE9E0523BCB7E7D8B353D3E87C808EE9
+:10AF600097898017F1CBE32559BBE5497EB745E7C3
+:10AF7000A7E39ADEBD72DBECB5B9307EEB937F2E92
+:10AF8000C4F8718C71FAAE7A80FFFE4F953B9BE856
+:10AF9000CD85F41944BC9AEE7988B1D759027D5F0A
+:10AFA000BD2B8DE82400F6907312BEE1F45A85F7AC
+:10AFB00076227DBFC6DBBB34FF36B2EB365EFF7751
+:10AFC0000ED91920BE0CD8E8D91DB04DB2B867CB48
+:10AFD0007CBF5887B1FC91BDB710E5CAD5263FF4B8
+:10AFE00023C13A3FED8A51A3497E5DA9A8D3310F11
+:10AFF00060090BAFE5F15B7E6FCFFB52C7BEEF225E
+:10B00000BF6F13580CF0B4FC378FFE1AE5D8B58F1C
+:10B01000DD9B8E72EC03A9231BC75BB67D4D3ADE28
+:10B020002FF3BE144BC7F61FC4B93C1BA42F47090E
+:10B03000DABE949A2E804CBE9E480DFE7F65DFDA04
+:10B040005B609C7F009E91EFAFDFF12F2AEF535D95
+:10B050007D2C80FDF64E4738AE697437B584D0BF7D
+:10B0600034F2E7B53FBD375BA13C8F589E86BF3CAD
+:10B070006C77FD363BE5F9A21F8FC3AC607D343F92
+:10B0800073FB155D471D28AF651BEBCB3F6FF0775A
+:10B09000B0901CC86F2B766CF8584CC7E7076FE26E
+:10B0A000EF41AD30D9A74B35F96DA6FF9F9BE81E48
+:10B0B000F043F18518C0C57F8E89CBF1D69FDD376F
+:10B0C000FE30C0F7E1B617D2F1F72674FAD7EF7960
+:10B0D0003ED6B578A163887B843ED2F8A45F3F68F2
+:10B0E000FA49D90980E54071177F2EB377A79F07EA
+:10B0F000F35DD6690F21CD2F7B5454DD68571D7445
+:10B10000923DB2ECD1E344B7CB04B54F203DC7D25A
+:10B11000518EEBEB75DDA37F9A8E72FABAA0C866EA
+:10B12000022B5EFBCB13BC3ED0790AD4BFEEF1C339
+:10B13000D3BF8B6590272E8BF59ADAB5C7D1EBB6C6
+:10B1400058AFAEC3D3313EDFFAB37FD27A7CB05B67
+:10B1500060394583DB2FEDFC13C5C13E8485F16664
+:10B16000727CA1BE59D125363A32ACD6AF7BD66FB0
+:10B170002BE93BE5850FB78E1B4631AE1F7FF3E809
+:10B180002F7E0B702C7DD3199A89E3FEE28674061C
+:10B1900074F067A989D3FD8FD664A3FE5E6A8F65BC
+:10B1A000CBF4E4EF976EFD36D1E3D5BFFF76B6B6AC
+:10B1B000DF10B4913C8805719E4B1E9847F3BC8A02
+:10B1C00045881E97FE88DFB37802FC6C2B3FA152A6
+:10B1D000E172CBC9568EBFC5877213EF6C01381C64
+:10B1E0008CDFD7F50ACF7F77B24B3312ED5C87C285
+:10B1F000EDB9188BBF8D76E70A50CB28D7C4DF9FF7
+:10B20000988EFDDC58243539293E6A7D7FCDFF03B9
+:10B2100074C90FBA00800000000000001F8B0800F6
+:10B2200000000000000BE57D0B7854C5F5F8DCBD8F
+:10B23000FB0A792D79404220DCBC1309718104128C
+:10B2400040DD10C020AF0D444589B0040C0112123E
+:10B250009116ACFE9A1B0208946A50AA54D02E088C
+:10B260008ACF0604C18AB01145A8FD300AB5F8A2FC
+:10B270008B206F6441A8EBBF54FEE79CB9377BEF8E
+:10B28000261168FD7D5FFFDF3FFDEA70EECC9D3B40
+:10B2900073DE7366E66C0D83BF64C68A3E1ED6D528
+:10B2A0009BCD98855D34DF97CBD825C6A467EC8C01
+:10B2B000D530A3ECB532FABB9AC4D88975964EC284
+:10B2C000CD507661954DD0FE2AFEDD1628A74A02A4
+:10B2D0006379D4FC13D69FB1D9F82F09FAD97862D3
+:10B2E000F86AE897C5892C328EC3CFC430662B0F1D
+:10B2F000AB8DCC87EF1D3C6AEE06F5728C81A5D92B
+:10B30000A0BEE51B82993D56C2F66AFF35DB2DCC07
+:10B31000A38E07FE5FB3FE1B33C37E0CCCD77D50DC
+:10B32000DB7AC66A737E1583F38894964179C2EC02
+:10B330001BFE367E07BEBB01BE53B112DA676AFA46
+:10B34000DB72EA739683EDCD81E749F8DF057C5E19
+:10B350006259A42B8CB1E9304D56D076FEF3BFACC8
+:10B360007FF43D4D7F395278CCF150F8C70036E07C
+:10B37000AA18789FAD89652CBEEDFBDFD7C98FBEBB
+:10B3800067C2B765C6A04995C9FD02E2A9EA338B39
+:10B390005D063C56BD76D96C009809CC97D699B11C
+:10B3A00033AFEEFEF45E98CF992653CC28FAAA2349
+:10B3B00042E812C07BE5E66F86AF86F626C07B08C2
+:10B3C000D073F696EFCD06681F57C47C1618FF9908
+:10B3D000182763BD116FA6AFBD1ABC15C1736F18D6
+:10B3E0008D23C11087A5278141393B86D93DF0FEC9
+:10B3F000EC83A25D427C31DF625B58DBF76B9A8E97
+:10B4000006D1455FCF98CFECC4EF6EF9CD05314240
+:10B410008B77E3D75E0DDE553C07E3F59E20BC5EDF
+:10B4200066D991F01976FAE5593D5DD96DF1ABE237
+:10B43000F5DB3A864CDEFAFC624F89F02C6D870F03
+:10B440007585BA1D4AC9D8A74C83C799AF9C23FEFE
+:10B45000FD47BCC844E09BD9EB7F588C7C0568F560
+:10B4600059807F67BB2F10BCC861F531829B4B852B
+:10B470009CF6E6ADC767707D77446A5E80FEA605E0
+:10B480004C0E877E7DEF88EE7530B4F3922F220A42
+:10B49000E6B728844D764279DEA6C09D55984D9E2C
+:10B4A00002E33C2FE7D8647C2F844D6802FA9C7736
+:10B4B000FA223A8705E67D64871821417BAF9B1508
+:10B4C0003785B5E543C61AE8FB5ED6517D3D8D73E1
+:10B4D0009878E5752F7CEFA26C6416F89EB7FEFB9A
+:10B4E000D7BD501E335A6D88A769F5774730037C66
+:10B4F0007F47CAD809D0EEFE7D803F9A9EC31C0FBD
+:10B50000F89DCAA7CE4E32F9A9C1303F313C77CF62
+:10B51000DBF07E052056047E9DB65C8F9F99CC198A
+:10B52000E94942B93505F884FEEB367BE0BDE9AE6A
+:10B53000B0DA65F0DDCA35FAFA993BCE107FCD0C52
+:10B54000E22F17F2577C5BFEDAA0F2571FD607F9FD
+:10B550006B981866407E3EBF57745BE09D8B0B4D29
+:10B560006C31C0175F15DC0CFAB9B8031A21BC9D09
+:10B57000C34C8E25BE55F95CC5DB59E4BF8CB6F8CB
+:10B580006CADDFFA55FF87A149D59B5FE4AC86F22D
+:10B59000EC9B9FA5BF8DF0B6BF257EC1DAB62FDA32
+:10B5A000F9C3241AD74E0BC3719DDFF941E2C308DA
+:10B5B000FFC96247BE3DBFC0E260A8EF7686BBD33D
+:10B5C000B0BE07F003D0BDE19DEF7350DF33B690FE
+:10B5D000E8D82299A9BCB8E39F87059CC70E8B8445
+:10B5E000F3A8D9094880F76BFE14E266F8FE3BDF4A
+:10B5F000F77785FD7CF3996D662EE2CF7036613367
+:10B60000F26F67E6C0F9D4BC5DF07C3D7CBF7A4B3D
+:10B61000B3792AD417EDFA570EEAA3F39B9BCDA872
+:10B62000AFBE35799F63C01F5F48131B4D80E76F26
+:10B63000C3A1B36E8CCD4D5AED94C3DAC30BC7C30F
+:10B6400079C003CE0BF052E9CEEE181F17FF6BF155
+:10B650007161127EBF6AC700262669F12238F8F3AD
+:10B6600070B755A0F9F3E73BBFCF6161D79EAF2D0F
+:10B67000C94CF2FEFFCB7C7392FE5BE9CBF9FD4D2A
+:10B6800089DBA560BE6FCBD7DB7E49F0EBE1761A94
+:10B69000EF75CAFB98FFDAF9FFEFD0BBEABF76BEC1
+:10B6A000D7A2F73E85DEE1360BEAAD77FE95C86E90
+:10B6B00060DEBFF97F74DEADFE8FC16ECD85F17D9A
+:10B6C000CEDC77160AE495B4EB8F6C4F12A83D538D
+:10B6D000D61D6314BFA2817D3D740A7C57067F028C
+:10B6E000FDFD86B0AF8D07016E013F01FD0B86CEDB
+:10B6F00009E0A1A5B48F7B19DA6D632DB3016CFA53
+:10B70000742AC113CA7F30E642FB3BC1CFC3F6FBAC
+:10B71000EBBDD3EAA17E7F6783D400F058C7F8B4AD
+:10B720002D00DBBA89365CC73438FA5925CDF8C606
+:10B73000E6EBD723F706AD2BEE9EA0AFBF8BAD8B0C
+:10B7400035427F77559A981BA6746750FBA7926C79
+:10B7500034CFBB59ED225BD88DE3E978125F9F357A
+:10B76000B0BE7B25C48B43B46F606DF1C6106F888B
+:10B7700097B87E6C991DBFE2351E04D8A2F857F029
+:10B7800047F278678CF505C49385CD61BF84FE2EA2
+:10B790004BC65A6C6F61B06EE4E316AE0A6DF106EB
+:10B7A0007F92B13FB9E24482B18E0719E2199FF747
+:10B7B0008CD3BD4FF30EC6F38DE37541DA5388D7B2
+:10B7C000D270BB1BF9C2F17CAC11BED700781684D5
+:10B7D000003E553C05E3FD6DE40D8D5FAE96D9CC82
+:10B7E0003709FDCE0816615F06FD4758BB33239F1E
+:10B7F00087CF128F858DE17A4D1CC29A96C17A8DC2
+:10B80000E51BCFB6CE2B99EA3D0FC37B0D0FC0FBD6
+:10B8100088D7EE4C7212FF97D98EF7C2659E8B5D6A
+:10B820000D0DF89F1FE583FF994425F1ED47EBB916
+:10B83000BF7979F01B8BFB80283198B3DC1FFD5C4E
+:10B84000E54FF696E17B2233D871FDCB1C0EC9D6AD
+:10B850001FFB65B4AE89CC37E8D6BF9D1D9D7478BB
+:10B860008B2E8ED2C1B1CE6EBAF65D2724EBEAE301
+:10B870005D37E9EA132AFBEAE01EB50375ED7BCEDE
+:10B880001FA28393E43B74ED53968CD3C1698DF76B
+:10B89000EADA67AC2AD7D567B967EAEA7B6D9CA379
+:10B8A000837B37FD4AD7FEE6ED0B74F57D3CCB7408
+:10B8B000F5FDF63EA183F35A9ED1B51F70689DAE8B
+:10B8C000BEC0FBB2AE7ED0C9CD3AF816DF9F74ED94
+:10B8D0006FF3BFAB830BD987BAF645D6033A789896
+:10B8E000ED0B5DFBDBE38E06C53B6CF283B9A8C6AE
+:10B8F000809F40CE46486774ED618556867C6352D2
+:10B90000F86164E677BAFAD1F67FEAFA33B35A20DF
+:10B9100002B25523959D58139561AC85CA877ABBB1
+:10B920004626A33C3C272F46A6DA5FF07D22DA911B
+:10B930008F063F2823DF5D8E6336B10F8C87F98C2D
+:10B94000C8D786D02BDD5D9AB851845F649E7EC0D7
+:10B95000877E814A9B3F9479A2810FFD215446F94D
+:10B96000A3E979B4BF339531FE047A1EEB8FA7B2F9
+:10B970008B3F85CAAEFE242AE3FCBDA88CF7675135
+:10B98000D9CDDF8FDE4BF0F7A1B2BB7F103DEFE1E9
+:10B990002FA032D15F44CF7BFA0BA994FC23A94C92
+:10B9A000F28FA032D93F9EDAA5F84BA84CF54FA4F0
+:10B9B000E769FE7BA84CF74FA532C33F85CA4CFF11
+:10B9C0002C2AB3FC33A8BCC9FF20BDD7CBFF009500
+:10B9D000D9FE87E9796FFF4354E6F81BA8BCD95F0D
+:10B9E0004FA5DDFF1B6AD7C7BF94CABEFE27E97902
+:10B9F0003FFF0A2A73FDABE9799EFFF754F6F73F44
+:10BA00004FE500FF5A2AF3FDAF5059E07F89CA8104
+:10BA1000FE37E8BD41FE4D540EF6BF4DCF6FF1BF6E
+:10BA200045E5ADFEDDF4FC367F33950EFF87F4BCB3
+:10BA3000D0BF8FCA21FE03F4BCC8FF319543FD5F20
+:10BA4000D0F361FECFA81CEE3F4AE5EDFE2354166D
+:10BA5000FBCF5039C27F8ACA3BFCDFD17B23FD1765
+:10BA6000A81CE5FF273D1FEDFF81CAD678C26053B1
+:10BA7000905E6CD57F86AB50B2B0A876E36DADEF2B
+:10BA80002BFA7845E8730CE31E636A055AA73F1D3D
+:10BA9000FAED7BA4270B2C12C28BB0693CFF8EAD54
+:10BAA0000B63F7E13F24C69A0B2CB47EDFFF3FFC0B
+:10BAB000BDC58547BF7C10EDE3031686F63158FF00
+:10BAC000AADFFD287F772CFA618BFB7AAB30FEF280
+:10BAD000DB246F1996DB92B93FF27A32B7B75B93EA
+:10BAE0000D543EDEDB4665D903699114A78AB9BEC1
+:10BAF000795D56ECBEDAFEF7A90A1CE64B247B7191
+:10BB00009DFD5C6FBB45D65FFF01E33A8E06230BBC
+:10BB1000B9156023B7F7F297E1EE0D30257948EDBE
+:10BB20008B18E79117586C0D3188E75FFF11DBCF59
+:10BB300067CC6981F29964D77ED40BDF8724BAC1C0
+:10BB400038C25FED8071E13F6BFF9FFF2FF77FFCF5
+:10BB5000A7FAFFBBC247B7A7384F27A35F6074E4BB
+:10BB6000201D862C881763E0FD29CB051BF2D1D45C
+:10BB7000857D86237FF4650E8A93DE17CD263BDB19
+:10BB8000F1CBA2520C8A7F2199EF86F19C63CC8382
+:10BB9000FE44B9C4882FCB77086E99E2D08E88D145
+:10BBA00060BF2B15BE2D5F526F9E07EDAAE379BCD7
+:10BBB0008CB979BCCC0AFF43399AD5B8760F851B6E
+:10BBC000C52B141FBB8C7E2FB0CEAC8D6DE3B1F3B3
+:10BBD00030CEBCDD6C43BB51DD1414CF0D8A9B0508
+:10BBE000C7CB4253C263505E999DD9799C3BACE26E
+:10BBF0006FF83D16218931D7C68B1A9F9598D415B9
+:10BC0000F1384CCC8EC475CCC5BD69910C4B49EA5A
+:10BC10008AED5C408B162805A36B003E077CCA4862
+:10BC2000575F7DA87B1D8CEB08D813A91F0AB76B43
+:10BC30008019E3919FF760CB04A21AF96135EB45B7
+:10BC4000F2EBBD0BFEB918E3D833928CB40E988298
+:10BC500031771CDF5B9DDDB240FD12DE7DAF091444
+:10BC60007795D99C388CEB6AF643C8AF752E8A1D40
+:10BC7000938F745AD2B9AF0569253B3E4DEDA2A111
+:10BC8000CFC206C26B795C34A7CF7613F9B5409F5B
+:10BC90007AA4CF0CB7E99816CF97D91533EEC7948D
+:10BCA0002FB940F49A19A097AE5D756333D115E8AA
+:10BCB000A47B5E537B428DA31FFB297A15A628F136
+:10BCC0004D855E183FBF1B2B1F8926FD50B6C093C4
+:10BCD00056ABE1D3E07D89D46903239D200FC5DDF8
+:10BCE000383D98D1DE05E9F9DDF23CA257309D8A56
+:10BCF0007F9C4AF4609F87B30D309EFB52D8E4715D
+:10BD0000F07CB2127FBDAF614431C6CBEF49E1FA9E
+:10BD1000F223587F3A60FDF9719D953940351FA88F
+:10BD2000B311FCD7BA3882FF562751F9595D2695D1
+:10BD3000C7CCACB249235FC000661CDF6445AE26A9
+:10BD4000A7A8FB5273E330EE5EFCE3813C03AA50EC
+:10BD5000B9A964D82DB8BE002468F033A134947C0E
+:10BD60006915F69A6CC3E3507F2C15EC1B90AECE90
+:10BD700041BAF62CB35F0046FB65E4FC047CB10ECF
+:10BD8000F9EF9E51D1BAF6772D49D0C1F352241A5A
+:10BD90005F49718AEEF9BD65BD74F0143FACE7E10F
+:10BDA00053A952B14186FE2FFDC544FC7CA97640C3
+:10BDB000D7791C26BE0BC6FF31B34C7104799DC5E3
+:10BDC0008EFAEF6408E7EF937F15DD0DB4EE952949
+:10BDD000EE72D96A93709DF2CBA97222D6FF32140B
+:10BDE0005CF23E882F9161FC80BD6C21FD39759518
+:10BDF000C06494111FA3F5F2DC972C34CF69AB44D7
+:10BE0000E6EA477C9288EDE7C64AD4DF7D295213E3
+:10BE1000F2B36F83C5BE0E6AA77A95F785BEB40FDD
+:10BE2000523DE76F878D280FE92D3918DF2F4BF230
+:10BE3000C4A21E3CBBDE44FB5ED5E2DA8A3020D1D0
+:10BE4000ACDFBE11512091F8117E4F7F1CBB16E76D
+:10BE50001F98AF9BE222DE9ECE6753009FA72BDC8C
+:10BE600039B44E7E84C7E3DBE285919E920D11D2F8
+:10BE7000069CEF54D7005BB6D61EF27DBFA9267B89
+:10BE8000177B36727F6E3CEA8163CB4DC518770114
+:10BE9000BD3F06F174AC31DAB08C16559B89BFCA30
+:10BEA0008D9259FBDDF2E5A283DA837E2F417BBDC3
+:10BEB0004274B101083752FFF212C185FB4EA92C22
+:10BEC000BF2BF2ED830F0CE88AF398D4C13EE3B7A1
+:10BED00020332ECD3ED6CC7744A71BBF97EB3596AB
+:10BEE000F6D68E9FC781525D4BBACF413A6D0AB1EB
+:10BEF0002F9350AFA644E23AF5D441B01BF08D1910
+:10BF00000DCD3912B05ED583DB880E95639AD23D94
+:10BF1000F0BCC5EAFA00F17832BEE9A9411827DA87
+:10BF2000F17CA28C76703EDF5F9BF9F28C9E5A7F8B
+:10BF3000BEAD3FC1E20CF95878BA08801797C486A5
+:10BF4000237E27B226257EE1A6F149A874011FB6FB
+:10BF50002ABEFF36D5609F742017D11F6E43BAA842
+:10BF6000FD1D35F138D7E72982CE0EC7A672F99E9E
+:10BF70006AE072C7760AC4A740B04F5335F6B2865E
+:10BF80002D277B19972032DCB73B9512A5E8056E6B
+:10BF9000FF66A1FDC37D619B40F251B5D1E27603FE
+:10BFA0007FA5A472F99C697EEDA9BED83CA9D68C68
+:10BFB000DF99B14560CF40D3D32677450BEE4BD9FF
+:10BFC000D62E8CA2F74C7637F2A9A2DFADA0105086
+:10BFD0002F4CC77F427DF54AC1ED217E71921D9A9B
+:10BFE0008671135CFFA39ED7E89136FA3D48AFDF18
+:10BFF000CFF4F68835EAED8B3334DC8AE39CB992D2
+:10C00000FBB581F188EC2AE0AAC2E5DE3386C62BB7
+:10C01000505C24F8FBD3717C385E189FC77EE3E345
+:10C02000A9B07339AD6A14DCEE76C6A7E23572307A
+:10C0300093D03ECF5A2FB8911F87C53C40F89D0939
+:10C04000F88D46BCCACE88BB01AE004672537C85D3
+:10C05000E3BF660DC73FD0F913ADDDFD26C66746C9
+:10C06000BC7E03F653C6FDC0DAEF89EE7B80BE28A6
+:10C07000BF3336B9CDB811798635468421DFAFFAA2
+:10C08000780F2E0BBE59F946175CBF964579D20C36
+:10C09000A0B7A2E5A8278A6F09F05FB0BD6E6397CD
+:10C0A00083F0233327D9A13678B22E6FC17DEF36C6
+:10C0B000F453E262F7E3BF003FF7AF171D2139BA2F
+:10C0C00076CA790499F8BF52F6919F5009F36CB083
+:10C0D000E1537938E2E57E3B23BD7BA3E30D1E27C8
+:10C0E00013CB883F31AE877EC8BF3BDE60FFA32401
+:10C0F000F5A7FD8F603D12EC7F7C69721816A0DFFA
+:10C10000F731DF17BF64F4F440F9BD14936C871660
+:10C11000013D1ADBB72BEA79558F5628764BEDF7A0
+:10C120007EB457001F5FF54604D25DA5FF74B413BB
+:10C13000D9013BF1CBA9D03F7CEF97DB42A8FF733D
+:10C14000A3C14E419F65CF7E10C134FA6F414F5756
+:10C15000752AEA13D5AE896B136DC05FAABEBCD633
+:10C16000BAABC3798505CD2B5C3FAF729C57BF40FE
+:10C170007F5395797DBD84CFE7E8723EBF696DE658
+:10C18000C5EDFE2F9FB7D865F20B3CB12887273746
+:10C1900089AC81E8CBFD86CB56E0A73E18BF594E4F
+:10C1A00076FD542C9330AED3A1FD5E6121BF60C6F5
+:10C1B00056BEDF7A5A28EC4A1BFFEF79221E42B99D
+:10C1C000DE2C32B44381F1B4DAED95A9B11ABB7D0E
+:10C1D0009D78C3382BDAB3D9803AE4FBD93BBA3225
+:10C1E0003CE7B2BC903589B40FEF253D062C44F1F5
+:10C1F00069F0C375F1060BB35BAD48A70EE2AFFF64
+:10C2000048BB30690EE1C3978EF857BF5FD3C9634F
+:10C21000EA8A7ECD2681FC9AEAB98511850CBFC3D6
+:10C22000E3669B53B99DDAAAE839C1514B7131F0ED
+:10C23000696C8FE3B8D6F0F8307B9735217E11A674
+:10C24000F8B181CF43906CACAC2F8FCB5BD1AE8576
+:10C2500019C8AE05E3E16BE53BD5A281FCDF2A33CB
+:10C26000F783CF0BFCFCC7BB8A7D7C3795FBC31FD4
+:10C27000A4F238C479F403A1DFF3B758DCF502BAAD
+:10C28000AD465A271B075BDCE8CF18AD611E3107AE
+:10C29000D16BFCB6559E015F93588B09E93926FF97
+:10C2A000818D389FC3DD984DEC4CD54EDC479848C6
+:10C2B0009A81B1FDA62FDFC778A40C6D45582B4C91
+:10C2C000CC3FD103DBAF4118E67F38A4E97D8CB3C6
+:10C2D0001C4E3232DC1790DFB190FD370DF1F6A025
+:10C2E000386527C61AFA603C66F722E4A33D71D18F
+:10C2F0009936683FD9D8C92E72FD33F4028EB752F1
+:10C30000E0FB370BBD79489F9BD942DB712B6D2D2C
+:10C310006CB91AFD53FC6364C7553E8031550D81DD
+:10C320007F0C649CB1F2099F3A18F04AF0F7A973A8
+:10C33000C7ADEC8E9B26526FA47355B2CF88FB29F4
+:10C340003E81F9D6011EEECCF7191D482F076B1A56
+:10C350000BFCEBD9C704FC0E8A007EF76E4FF2305F
+:10C36000C403CB945824D48F354A04772F6651A246
+:10C37000B26F8071AC438304A283C12A9970DECE70
+:10C3800062A12FEE8B562DB8BE71866CF8F5B8956C
+:10C3900083013618F87AF621BE9E9D281F19467E25
+:10C3A000D26026201FD6443599681D0DF282E3EF36
+:10C3B00003DD68F137D1E8E5E3AB84F115A05CA4B7
+:10C3C000121FDF5B2B903F59636E3FAE119BA6EEB1
+:10C3D000CBD9246C3F0BFE857C3D6BC7B634FCDEAD
+:10C3E0007281F3C12C95CF5ED5CBE58034467CDAE3
+:10C3F000115FE72AFDE7A619F839AED6EF3591DDD2
+:10C400009DB5E38343B8AEECA8FF6A0BF3105EDE84
+:10C41000B150FC4030F852892E8848A0C344F4271C
+:10C42000C145EC9BC6FD44953F2BD0FF48C192C748
+:10C43000450CA03CD11E56363E6F46A4059F3F02D8
+:10C44000C787CE01CD5C1FFC5C135711757A87E25C
+:10C450009E82D9370DC723DC1A62477D3CD1DC446C
+:10C46000EBF2E076A646EE679996703F8BF6D50024
+:10C47000B62CE77EE6C4EEBEDE8CF49C6DB890C4AC
+:10C480005AFDE20AFE69785EA5F38B2D1847C0B805
+:10C49000D72AEE0F1A15FFB57CB9DE5F98B850E3C6
+:10C4A0002F52B7BE6A1CAFE991508ABB58D09FD0BB
+:10C4B000F8017F3794C8A887E564239DBF34B16035
+:10C4C0007FC2C9783C933F372A7EE2D034936EDF37
+:10C4D0004D1EC232110F65A8875250D53897603C67
+:10C4E000EF220B6FC4B8D930F1118AFF95D5F373E1
+:10C4F00069C1F1BF8BB5EF3F8BEDB11E9FCFEBF460
+:10C500006322EE6FC2B2D429DC0AF2DDE9F06517CE
+:10C51000CA07282A13CA7BC8FE6F10160C914CC894
+:10C52000C7EF7B9EC5FE65B3D5867AEBE9D008EAF6
+:10C5300067FE7C81E2C30B6D5CDEBEFA327C1DEAD5
+:10C540002935DEBBB8B0DF2A3CB7F4EBB45DE3AC11
+:10C550003D503D303AB70486F11307CCA7F40AC822
+:10C560000DC1EF8F7344029FBFEF9B64053CADDCB0
+:10C57000F0FE3823F0E3F9DFF99E43F8850DFB392F
+:10C58000FC5B5F6208C26907C619418ECED7ABFD5E
+:10C590001D18E7C07DF7DF73B801EA6580CB50BF97
+:10C5A000E1BC070AB4EEDF8076293610EF2933BCF0
+:10C5B000CBCB21CC83F6F35AEDFE98E6DC80F65A1D
+:10C5C0000C3F168EFEC5960C07C19B539C8FA5A1F0
+:10C5D0001F74D0DD2516E35806D68274013BE66849
+:10C5E0006F5F7A432A97DF4DE9BC3F155FD0CFD309
+:10C5F00069B137DECF6D6DFB71FF3BE3E99401FD5F
+:10C60000E4E9FA79E9DFE9A72AA81FD56F030758FB
+:10C61000423D7526D3F11ECE73D6AF1D43B6A0FEA4
+:10C62000D92F129F7E57BB2D1DEDFE77AF5AA2D199
+:10C63000FECD7AFDADC40A8C23287ED199E6CFCCFD
+:10C6400012BC3FDB2F3207E8E91ABF40E5EC2DCDE5
+:10C65000E6E1D978AEB6D95CA4195795324EE074AC
+:10C66000E3388D1FB32F4D8D3FAFA0F1CE7AFD94EF
+:10C6700011E939CBD0741CCF1FB3813CEE153CBF00
+:10C68000CDCA7B87F1BC413B71808FD2B8DF11D717
+:10C69000CBB11FE7B709F539F28B819F0F096EDF28
+:10C6A000359DF757D689EBF9BC83F68A03B4EECBF8
+:10C6B000318850F63F546B2E87E70752861C4A6B31
+:10C6C000370EE9E371C81D3C0E5916D532178C1987
+:10C6D0008B4ABFF804CADBC8A755F900D103FD5245
+:10C6E0006C51E190F14307F33817C29737189EC495
+:10C6F00073847B3BB5FCE200DA87A5E16C1DC8D9E9
+:10C700007D03C21337C338A6CA9102D84E566809B2
+:10C710004F9F02ED4E241746A5F3F327E41F9E48D2
+:10C72000769EC3F17993420DE08C309799C7B35C44
+:10C730007F16299EE5CA0975B9DBC1D719059F5136
+:10C74000E9DC3FDB6B8071F6C571F0F3BDF097B8A3
+:10C7500019E34D0B7A0AC877EAF76F4F29EC9C9ED4
+:10C7600017F8FEED29CE1FD362B5ED2319B6BFDE53
+:10C7700071FC53B1A79DD339BD9C8381BF347A7FAF
+:10C78000DCD0501D5C3A2A9A39B4F1CDD2041D3C5C
+:10C79000A12C45D7FEDE69BD74F5A32D2DB9B537A3
+:10C7A000E0EF8B119991B4FECFE3EB90AF765CFE96
+:10C7B0007422FAB1EB45BB00F39AF1CE864F0751D4
+:10C7C000EF12C5B94EEF15C91E817B6BD6EE9F9C4B
+:10C7D000632D74EED8D87921D9BF5971FC7CF70C40
+:10C7E000B77EFF438DCBB7B76F82F6AC0ACFC5B427
+:10C7F000B76F1288C7FFE4FE49BF74653DDC97F54B
+:10C80000E5EBE1B37B60A6AC687B33D1AB619F689D
+:10C8100047566DE8213001C679FB168B3B04C67D77
+:10C82000EEAD236649B37F52E30703108DEF1D3150
+:10C83000E379AA03695C6FCFDE71C1CC902F763C9F
+:10C840004072DDD2EC8A8945FB05FEEAD65CE4AF96
+:10C85000A65CB47F7B0D3627EE87CD5A3282E2CCC0
+:10C8600091FE895456358EA07EABFDE3099EED0FF7
+:10C8700025F823B165CBC7D8CFD39136B4E7D546D9
+:10C88000F955A44BB514DA0FF7AB666FF9F8D2AFD0
+:10C89000D08EDAF8BD8ED1E227B9583FBAA7CDD0F5
+:10C8A000D019C71B42FDB40CF92217ED5231AE0B63
+:10C8B000E079D5E60217CA7D6143B80DE55EC4F3A1
+:10C8C00064EDF0E9E474AE5F4C5E3EDE61FE12EAB8
+:10C8D000AF757D9F9E4CF3576153EC7A23EA0F7539
+:10C8E0001E2630F858DEE1EF4565CD9612239E8B6B
+:10C8F000FF73E6F3318827681F8665EAD041A46795
+:10C90000BEAB1D10C9DAD15B6A6951F4F044D4C3DF
+:10C91000D05F69A6E3572897631EF11AADA847C3F5
+:10C92000AC36DCFF1893DF47AAD0CC477CF71E5CFF
+:10C930004980AFE233A11F30114AADDE9EDC817D1C
+:10C9400091D30D8A5F54CFCF75AAFA7DE5130CD72A
+:10C950006193F859AD56B9AA56DAABEFB708DC1FA8
+:10C9600090B7F2B87E75A6EB491C6F4B219BB0992E
+:10C97000F4694B6249F8CF37FE08630BD139C22600
+:10C9800019705F41AD5FD53A0F2EDFD79AC722A548
+:10C99000FD47229B8F7CF1D16DB7B538A0DFE687CC
+:10C9A000FBF5133576EAA5747EAE99D97C57485FBE
+:10C9B000EC0C95500F8CC6BD87DC80DF8FE72131F2
+:10C9C000AE51B3D3B20ECF83D544C03A1FBE3FAAF7
+:10C9D00097EB25C447F3AE824B788FC6810B33901B
+:10C9E00073C78E0197F09CBDC30ADAC68E7E90E3B2
+:10C9F00065D2FF1D8CF75AFA2C75E8AC18F427BEE7
+:10CA00008321A1BD05BB9F7B90C34EC4976B099743
+:10CA10003F9722875314FE2D57E4708A91CBE1E4AF
+:10CA20009591368C77963F22F4C6F3724C0AB7A3E1
+:10CA30000A30215FF643FEE47C59E5EFACC87392FF
+:10CA4000D20FE7FF60F99CED8FA676AA9CBE9CE909
+:10CA50003AC4ED5C4BEE7C18D71D20D7A8F75C0BD1
+:10CA6000E273514E027C62B6213F019FC45568F8C3
+:10CA7000A0A1F90723F28969B0407C6281B248C362
+:10CA800047CE56FFC436BC0BFA550B930CCB58A0BF
+:10CA9000FEAB74D54FB93E7EFFB3D2BE3C0CFC0852
+:10CAA0008AFF44308CAF5D8C91284E3A67290C1276
+:10CAB0005030C7E449C338CC9C0742280E5671B0A9
+:10CAC0007671B8D4965EF7F873687F79BC3F95CAE3
+:10CAD0000329AE33888F29FEBB143CE65CD7FE5C8D
+:10CAE0009E83C7DD4C6E8B7D6D12C6DD5C22EDC76B
+:10CAF000F560B627C94EA9FB713CEE86F13C8CEF80
+:10CB000005EFAF611C0ED7D39618836E9FB04D3CD6
+:10CB1000AE50BF9F56D5FC497F03D49F4E72505CE8
+:10CB2000CEDBD365CC8079CC1CE77EDDA4DD6753FA
+:10CB3000F0D864F4A4A11D6DAAE5F8695A2E16D3A5
+:10CB40007E1363A1259AF3BAD7E2E399FE14C28F4C
+:10CB50006A5F54BDBDAD8E0E7DB6EAEF6BD99D6A9E
+:10CB600085DFAB91DFED6DED8CCAAFC1FCACEA6740
+:10CB700053EC41D24377C02BE83FA8FABAB868D04B
+:10CB800060B4F3835E4AD9F227987F74A62B3703EB
+:10CB9000F8E7B6577AE4AE06F80EA3DB680BBB1EC7
+:10CBA0007DF88389F4E123258CF421945A7D68EA89
+:10CBB000C00F2FC8B8317D9EA1B4073F96FB87A058
+:10CBC000AFB5FD55670E1985E32FC9E076F2E71A78
+:10CBD00077477ABC244395CFEBD3E3B72AEDAFA5D3
+:10CBE000C7A765703D1EACB7411B93DE3EFF4E16D6
+:10CBF000C5C90E33D0F368CF76844A1B9234E7DC84
+:10CC00003B45BAB57A3DAED7D469C8EFD7A1D7EFC7
+:10CC100047FCFDBB7A7D78C926F2ABE0CF39F656EA
+:10CC2000587FFC06D677087F04EBBBA4B6F2102C25
+:10CC300007C17C0FEB912D1FC3F8F63ED593E20E92
+:10CC40002007C4F7D5C0F72807AABCCCDED227122C
+:10CC5000F70DD85F4486FA3F580E8A8B5E31629C8E
+:10CC60000AF538E26B37C83CEA99603BE1CF70AD1A
+:10CC7000C4F9ABF2A0CAC1B5F9E82D13AE4B4D55BE
+:10CC800017B89E8752ABE73BF2677E7F83FCFF6855
+:10CC9000C6F5F901AF66F07B103F23FFBC9A717DAA
+:10CCA0007EC16B19FF915FF036F10FEA4F5CBF8DCB
+:10CCB000FCD01E398FF30F9D4B047EC8C5B8F3DE40
+:10CCC000FE3DEC18A7197995FBF5A0D3C9AF0FF677
+:10CCD000AB272AFA6FB212273890E96CC9E0F24A02
+:10CCE0007E7B614A681FB457D7EBEF4D8CA965185E
+:10CCF000679A0CA5564F58906EEDF8EB7FCDB83182
+:10CD0000FBBDFB3AE97B3CE33FF6F37CD7A30F5234
+:10CD10001DD6F188CFEF3C468678BAD67AC0B48A61
+:10CD2000E3598517798CAADD8C46BB09FC71E13F7C
+:10CD3000E18FD1454D97AC40D7C84C6329C603EF6E
+:10CD4000C2B31614CF30AD74A4A2BE61EABE00C552
+:10CD50003B3E1255D87C70288C63E4932CB06F0056
+:10CD6000F5C30647B6C6470416681F91291E5C4ED8
+:10CD7000E3E6E75598CB6BE4FB640A9C0B70B806BE
+:10CD8000CE0F82D7F0F611462FB369FB51F4CF18BE
+:10CD90001BDF1708ECE7F9867746FF6F8B60C3FD52
+:10CDA000857B079F37633C677491774F02B44BCA0A
+:10CDB0000C2F0D03137FEF1681C6DB6763CC4A3956
+:10CDC000958E6C39F0BC61553EDF37B134350F7745
+:10CDD000B4C3877D32F5760AFF8C5D283E467F9688
+:10CDE00026819973793FC949D7F73ED28FDE4FA686
+:10CDF000F73D9698EB7FFFEEC1CCE16E878F6ECB4F
+:10CE000054F421C685D5FE8126E39B04477B719BA4
+:10CE1000DB95F62D064335033C8DDD98B912E35EB4
+:10CE2000C318E78B928D19A532E73FE6089AEF4FBA
+:10CE30008D372F53BF3EC33F49FFBEE7A7F035A84C
+:10CE40000DBE14FA57EAF924D2E87CEF3B18476488
+:10CE50008C60433F75B63364398B44BA2B7C2DF715
+:10CE60002D750C86F985305D1CAF95AFE57EA5C8A4
+:10CE7000D7B399DA3E6F25D2DF69686DCFF97C8729
+:10CE8000D0FA7EA691E127E8FD591B7357629C1CDE
+:10CE9000E841F5041B7F82CF9B82E0C14172C1381B
+:10CEA0004C72897A19F093D6CEFEED1205BFE704D5
+:10CEB0007EBEA96508F7E75A9279F96226F7DF1E68
+:10CEC00057F0F8B452B674D2E0A17B80CEF0E7C13F
+:10CED000F58066DE84A77B629479CBE34B47C1BCC7
+:10CEE0005AA2586F01F864EDC6B12B176AF8E4F93D
+:10CEF0008DE34B110FADFDC92507118FF728787A07
+:10CF000071E3B883C84778E404E5AD3A9FEFBF5AB0
+:10CF1000B67CDCAEBCCD69CB3F32E657A82646C214
+:10CF2000F704872997F793DC0E7EE6B77DDF11F4CF
+:10CF30003E33C5DCC8FB0A7D4605D1AF38887E4349
+:10CF400083E0323D1CF083A167F09FCAB7AF58D48D
+:10CF500005E3671B05BA6305FAD92CC0F31D99F7E1
+:10CF60009586C5239F4AA60468EBC99C7CD09A0588
+:10CF7000F288FA8BF4AF8BF4F578947382A7943A25
+:10CF80006E46BEA95D1407EDF76496AFC47BAFF79C
+:10CF90002E5C6142A4FF3973DA4A23F47B4FEE1F03
+:10CFA000F7607F46A1E2E028E127F8B431681E6B04
+:10CFB000826039A8FDCA6BE8F38541EF3F1254BF88
+:10CFC0003C085E15042FD1BF3F651ADFBF9C02F4F9
+:10CFD00043C45D4B5EBC99ADEB8656FB25A03DFB83
+:10CFE00050CFEF231B387C6AE383A54BC23470E635
+:10CFF0002F4AB5FC6B52ECC5C418A7A33DFE3DD427
+:10D0000011FF6406DB3559772EF130633AFBBB5BC9
+:10D01000D4C3CDA22A5F0B0ECECDD6EC07CAF5A5A0
+:10D02000184FE978BF422EC5FD8A918FABEDEB4AD0
+:10D030001D9AF9A9ED87FFEBAA88DFBB9A5957BA69
+:10D040009EF6FF94FDBB285EDE76E56A04D2653865
+:10D050009E1FC5FA4E9EB439D99AF9B1A6749C5F49
+:10D06000F3C3FCBEA1DC00F400392F6776DAFF6E53
+:10D070008E8C9CFF02B4DFFDB0381FEDD7E1F9D1F3
+:10D0800074DE686C16F7B77747F6EC723FC0CDA137
+:10D0900093CD18576D7E741895EF8A8EC53E407EED
+:10D0A000F7ACC74AC3B2B03E92F012F7D2D2D27AEE
+:10D0B0009083842C89DE7745D9BA6C473F7499896F
+:10D0C000E1FE1363F6E7884F7E6B213F754A7D2FA3
+:10D0D000DAEF29FF5DC9F0786857BEC844F17FF8E0
+:10D0E000A3FB18AE65C3CC583F6DA152CAB753B964
+:10D0F000EBC7373ECCA17D1D91CEEDECF4471D076B
+:10D1000049665FCBBDE9BEC25125BFCA962C5746C2
+:10D11000168CE3EBB3A9942F85D9A48871E8B7DD09
+:10D12000E4C8CC8A0DB4DBF5A348FB556F9F2DEF07
+:10D1300082FB7B7DB338BFECF4977729D7D8F58A8B
+:10D140007346C2F32EB33417F5C6AE4E3D0499E4D0
+:10D15000B6291AE3ACD314BF19F864FE1BEDF061D5
+:10D16000CF2C91F072CC321FCFC2B2E6DFC40EC614
+:10D1700071A9EFE51D743560BE185377A9AFD63F8E
+:10D180002E481B722B8E37C05FEB499F937F0CF0AC
+:10D1900088ACB52B65B01F6C37F8F5388E18C770A2
+:10D1A000E427F53C1E8B6B4AD7C615027EE8024584
+:10D1B000FE79BBAFF070307CFFAB5743E8DCD7574C
+:10D1C000F217E15AFF58958FE911FF73B885D6C55C
+:10D1D000919290087C63AC3BFE10BC57F1AC89F493
+:10D1E00066C5B3B18FF8B01EE8895B86C1DF7D3EAE
+:10D1F0008B9F07E8583E36970EEDAE958F4DA538BC
+:10D20000DF8EE4636AD6A60EE4A3AE0BF2D1F0671C
+:10D210004D74BEBAAC53ED5D18472C33DCCC1A60AC
+:10D220007C439EFD4517DC6799FEAC85E8EA0D0F4F
+:10D230003FCEE7D53309E7D56A7FB2B8BEF2D6173D
+:10D2400090BD100DE09D81FE16179B683D22763142
+:10D2500093DE1323ECBCBE134B5A0076795178BE93
+:10D2600084F4752BF200F512F25951E4843BF05C22
+:10D27000CBE1F929B40F762A97EF83CD78E8F90846
+:10D28000F43FBF9ACBCF77CFC47C3BB8CEFD37F706
+:10D29000BD6A947C3BFF5BFB5E4F6429F7865AF7BF
+:10D2A000BDF839D0DDF3FBE572BC30C982784AECB9
+:10D2B0004378B9DDCAA410C08B18C5D251FFA8FBB2
+:10D2C0005EE2AFB87E120D02ADD38FD5C994BFA078
+:10D2D00028C2CA9FFF8ADFDB139F2A61B40F16534F
+:10D2E0004BFB60E188578CDF0ACC89F27334C49E13
+:10D2F000F84036F25F08D173FA73333EFD7D2ED2CB
+:10D300006D748C2E9EA0F09FFAFE89FA5B687C27D4
+:10D310000466437B5FF4878CA1489F66D1F5D43DBA
+:10D32000A4374369FF9CD9BCBF1D00F0F47A58674D
+:10D3300033E49BF8C4E4EC403FD3173C9C8EF42EBE
+:10D34000FA438807CFDF4C5B18B20ACF6154EDE097
+:10D35000F7BCA72CFD8ECEE3B224632DC639BF5E89
+:10D3600018C2CFA96F1940FC33C5C0CFB9B0443340
+:10D37000C597AAC214B87B3EC19AFB4B66A4877AB4
+:10D38000FF660FEA15F8FE71151FE837A2DE55CFCC
+:10D39000D1B35A09E5BFCC20B47BCEEB6F59DC3F4B
+:10D3A0009D9268A7F3A2D58F59EC0B92389DC5FECC
+:10D3B000F85D46EBA26A836FF82AECD7C0A4AD36BD
+:10D3C0005C3FB454E07A9B6DC9A03C04354666349A
+:10D3D00047C17389EB33753C3552C9EDC44F46766E
+:10D3E000C81885786CF9B405F96341B8847191EA7D
+:10D3F000CE7617F51B6EB5713BA17C17C79E827C5C
+:10D40000E03747211F7C2A182C3CFF80C300F5E73A
+:10D4100019AF6FFDCEC2A5D9346FABCD30241EF944
+:10D42000EEC2F055F0DEED4C4A8EC77B624BA3EFA7
+:10D430009A80F5AF89A49740981ECB477FEF35B10E
+:10D440001FAE53A72CDD4DF39BB5A90FDE20605313
+:10D450005E3F40F66996C25F5EE5DC5A39C09B10BC
+:10D460008F8A5E7089AC96E2610A1E5BF1ABD4577D
+:10D470002F35113DAA175988CED5F57FA37EABC3B2
+:10D480005BBA203DAAB79A287F87F5263E8FF2FA2D
+:10D490001E830FC1B8CB4D9136011E55C9A3CD08CF
+:10D4A00057350A04ABDFAB5EFAD72E866CDE1F96CB
+:10D4B0001603DF670DF41B9B88F6ECCCABD18953C8
+:10D4C00034743FB3705B04EE3B1F0DF1A4E1395F90
+:10D4D000DF0321763C57A8C6D3CE2C4CE3F7816CF2
+:10D4E0002DE1B85F3D6D6E4A14DAB9C3368F19EB82
+:10D4F0000F3725E19139E6B0D90623EC30DE4CF048
+:10D5000019E51C09FD61FE4081F34DD5ABBBCDC9CA
+:10D51000F0BDDE3771FC9C7BEDE89E81880FE02337
+:10D520001BEA9FC49674B4C3D58696F404A4CFCBEB
+:10D5300002F90BB03E7560FE91D9C8577D411F2A94
+:10D540007C357BCBB679289FD56F9E1A8E783D3778
+:10D550009A99313E56ADCC1FD68FEF19A17DF5E6D5
+:10D56000B5C3197FFF3DE43BD5DE03BCD004F05EBC
+:10D570003387736EE2FA79AFD94B79EFF6DEC518CF
+:10D58000ED9F19D9506C0794E7F7004451B99F56A5
+:10D590001B378EE7DD93B5E7E766637D76A0BE2394
+:10D5A000BE197B9341A1B385ECD258C40BC0DEA554
+:10D5B0005B23902FCEBDB67BCF40948BCD828D69FF
+:10D5C000E54195C3441FAF07FC3D81F8DB7C613822
+:10D5D000E6A19879365C421AAA7852E54DC54B0D02
+:10D5E000E37850F1526354F0A4D43B153C54311FFE
+:10D5F000F5C7CEF6963660FF6FFE40FB6DE7A630AE
+:10D60000819F13E679D1D4F9B9A2F4FBFBF5377108
+:10D61000BE9FA4CCB3CAC6ED62550C93EAFB109F23
+:10D6200039CC6A7E4968726ED311DDF8572972D001
+:10D630004A6F9C078CD36BE0F70483F5D75C85AF0A
+:10D640008ED44FF4A05E9929433FB9280FB649B84C
+:10D65000CFC95E1715FD0D3653F3DDA2578E101F8F
+:10D6600082EE92A260CD62DA08E340FFEB6C0F8A93
+:10D67000171675F5D2BC378CB23103E89323823785
+:10D680007C3BDA838744D253EA381DF287440F4744
+:10D6900013974FE4178C0FB6EA85A0F1D62BE3B5AC
+:10D6A00018EC5E3C17CC1608747F4D5C702EFC1095
+:10D6B000B77714490CF47FCB7BB81FE9B814210964
+:10D6C00054633762BBD9972292D17E1F51E20E4735
+:10D6D000166D8B28D7D0E1A98EBEB3788084F42F45
+:10D6E0000A3BF430CAD1634ABBBD66FBD0F9A80F30
+:10D6F0002E4748785E6A6F949C8D7ED45E035BC231
+:10D70000A2381F1ABB04F007F242F8837AE9495B9A
+:10D71000402ED57103DD3C483768EFE07264A77D89
+:10D720008CD9317C5FF4DAF2D4CF4BFAA95E90D673
+:10D73000E506DAA9F7F21E55E64D32D225600F90C4
+:10D740003FD1DE59943C46C179506FEFDE3911F17B
+:10D7500057136635E0122EB83E180EACA76A8DE856
+:10D76000E7B385717BB4F7D28E86C874FFCC172FD0
+:10D77000B275408FFA073EE0E77977F07B5BAA9DB0
+:10D7800086BFE5ADFC07EF55E65E188EFAF5C502DB
+:10D790000BDD6BEADC2B99BE739A35990BD1FE9F9A
+:10D7A0006C191E2105D627B75CF28891E42F24E975
+:10D7B000D6075567DF2379AE662D741F7BCAD20367
+:10D7C000A30720BD5F32D1F981698D4964E74EAD71
+:10D7D0009FDA0FE73B65511AC13336DCCFE1A53C38
+:10D7E000FFE19445792FA0FF7534C4311CF9D9B7F6
+:10D7F00042B0E1FA6AD086BC47EE85FA41E13D3B92
+:10D80000E3B8BF5A7F7434D2FDABF922E927C7FAD7
+:10D8100027EFC27AC776116F8CC17AC6F608E63553
+:10D8200065C6481BFA05EAF9C20613D7B76715BDE6
+:10D83000704CD113C714FE2B6A6848477FC9B716CE
+:10D84000EC11EE7B9B7D1574BE5BB0D9D701BF9CFC
+:10D8500014648299CD965C5F80F759D6507E9CF314
+:10D8600069161BFAC9F759981DFDDAFB76F5E88BA6
+:10D870004B0587B2AE1A1DCDBFABE24BFDFE19E5DD
+:10D88000BB4C5C5E41FB0ED15232EAB7BDCAB9F166
+:10D89000A3CA784F2D7CE92EF40B4E6D4C8B621A87
+:10D8A000BC9F52F234CD003DB8B99DF59EFF2635A0
+:10D8B000EEE0A6EF542AF1C07DA6C6EE98F733F845
+:10D8C0007ED789B52156CCCF1B7CCFEB8489DB8FEB
+:10D8D00036F7BDB6EBE1E03CB7C1E3695DCF04DFED
+:10D8E000FFEF15D6AE1FAFCA59F0FB6DEE93A75EE2
+:10D8F000DFF92ACC4B86F7BD77DFC4E8BDA1A1FFD5
+:10D900007A03F57545A3C586F7EF8F8548B41E9257
+:10D91000F398B401ED8C558AC4F5FCB17DFDE8FCAB
+:10D920005FC5978CE4AA628BE8C654C5EFADC87892
+:10D930007C30C0F76F31D9F1FD532B57DCC5C54C96
+:10D940009F67219F71F99C0EEB248F2DB02E0A5EEC
+:10D950002FCD5CB589EE11FE5CEB25358E148CEF76
+:10D96000825EFA7C0BC1F7E77601DBE4F76D8BEFA3
+:10D97000B3752E5A177D5B57496541D3DAA2040966
+:10D98000EF531C796C10CA4D7824C543CED6D5D23E
+:10D9900026DEB7DBFB5DC1FBA16F8745DA505F7CFC
+:10D9A0005B375FB95CA0F089C297B76C6916131832
+:10D9B000B5DF3108DAEF0C8BA4BB2EA98EFC48B47E
+:10D9C000F32A5D83EF37ABF33BFD10A7AB3ADED311
+:10D9D0001BA746A0DFD9BC3A7A4701F4278746DA6D
+:10D9E000D0DF9EAE9C7F39BE8AEB9B93D6C817468C
+:10D9F000E1F99935E3BBE0BAEE7E93CF6C877EED1B
+:10DA0000EF9444E07AFF1BA33702EF1B7F03ED3D49
+:10DA100068278C6E11F5DCC06246FB78033D462614
+:10DA200025D19639F145C159A31BE97AC67369F727
+:10DA300055E4A3B3068A770166765F85F6F6F09E15
+:10DA40001427BCFF2DBEDE64FFEAC4EB83EE2D3E3F
+:10DA5000D18BEBA5136BDE1843EBF3F5261B8EF38E
+:10DA6000DBF57FED82E77066327EBEFEE44681E63E
+:10DA70003113F8312409F5038F83CE04BD6F15DA15
+:10DA8000F261D1C67AE2C399C08716F4D31C3C1F59
+:10DA9000F34CCCC72CB136F93F3A2B7C370BF80E40
+:10DAA000EFEFFEDC793F96F50A3EB7CAF950A5BB09
+:10DAB0008A1795FE013E64BAFC82514D7D0A1358C7
+:10DAC000401FA8F73B98D1BB1CEF69CC13C31B3197
+:10DAD0005FD57E63ED1F286F8B6C641BC89EB34CB3
+:10DAE000CC97374FBCC98EF1C006736D6B5E17AC17
+:10DAF0000FCEEB2286F1F74B303F31CC372C3B89F0
+:10DB0000BE37CE661F86E836C578292E2016191C2A
+:10DB1000742FAFC142EBE6603DF48A42DF3BD07721
+:10DB200040BFA7173FAFADDEFB534B30343D90DF16
+:10DB30004B42A32E4BD064FB2B9FDF89FBB4258384
+:10DB4000A27E9102DF6FEE75E44EBCB751D22F6A10
+:10DB50006B32C0BB5FF93BAFBF392ACF847E80F008
+:10DB6000F59D43D16FECE578B397E63B6ABFF0FCD7
+:10DB70002D7CFE79A2EB9D5E7CDFB402E97D5E88A0
+:10DB8000E0F9DE527D140755DFFB586087DF16028F
+:10DB9000B0D7C41231AFC1DE5E5C9F7654C6643B21
+:10DBA000F6F0EFEB9F2385BEC375A6B2FF63B04AC4
+:10DBB00066F4FF9C76B39DE757644E2BF8556315CA
+:10DBC000FE2DB75E194AF6B796D92D98C06489FE26
+:10DBD0003E5656E0DEDE9A1BB9B7C7649E87AF415A
+:10DBE000C9C3D7D13D4A61C7073FA07F197C7FAA2F
+:10DBF000DF5F5ADE443E19037C85F622B785C36396
+:10DC0000153EA9DE369AF23DCFF9D8E4463F61864B
+:10DC1000E28FA5BA3A3109DA5D06F945BD70768C16
+:10DC2000271DF5C7893AD6989A86F12A970FE9B247
+:10DC300037E903CA8B76624D4304FA3DE7603D3114
+:10DC40000ABAA852FC7B7645F4DC867E7052D6BABE
+:10DC5000651A7EFBA117B7FF67933C89B8BE919305
+:10DC60002C3C5FE395DD94E7B93879441EC691F604
+:10DC7000D76D6747D302EF75741F65A06108CBD6D7
+:10DC8000EC4B8E31B67F4EE3A49A4F733DB7DF164F
+:10DC90006323E5D10252D6D613ECA4B8521CF22865
+:10DCA000C687A507095E3C83D9E81E6B609F8EEE90
+:10DCB00083AAF477D8AF0EC5766380FEA86F0C56A2
+:10DCC0009F116167313F9F920584437DA2D27F9867
+:10DCD000F8C863488739CA3DAE39422D874D563A58
+:10DCE000E71AAC1F31AE59467A53DE5380FE18E86E
+:10DCF00049CAABA0E84509FE477991F2D79AA9D95C
+:10DD0000B5F322ED29F80FF4634EB63E8FB84A27DB
+:10DD1000D5BFEA884EAA9E047AF5BF117AA979CABE
+:10DD2000E63CCBE39D739E9D1AD797F0061287FEC3
+:10DD300050DC1F29AE325D99035B134D7C6C1AE2F7
+:10DD40009450DF8EDE9EC024783463BB40E75B478F
+:10DD50006D8F2638C21FCFF32A29F67EF48B5D879C
+:10DD6000607CF2D40B5FCCC5BCF7A37EC3287E6C6D
+:10DD7000080DA37C13E210258F8318F63EDE63BDE9
+:10DD800028196BD15E39599BFC0106A2FF5E7E4EBD
+:10DD900016567932A713BFF737671FB7F3730AF91F
+:10DDA000BEE0457C03DA5F2C15294FD3D3A139E4BB
+:10DDB000BF35DC69A2FB114C767C82EBAA090A3FD5
+:10DDC00058E26061A9A1578804F2AAA1CFA3218FCC
+:10DDD000BDEF82FEBDB0EE12BA811F9B19A5AB3715
+:10DDE000CA21DF60FE58539C6873C3F8C3EDDD742D
+:10DDF000FD39C52A13C653988BFBD12A7F31F1AC6C
+:10DE000091EECD0FE6F92BEE9CA0BF27691A7C613D
+:10DE100028D99BC17AFFDB798DBC4DF3557ECA6250
+:10DE2000594A5E7AB2FF170FF2FB211273AE52E528
+:10DE300005F53F78374F237EEEDA6B626E89F0F797
+:10DE40001AD65F942D368C07B4FAE1A9F05E0C1A4D
+:10DE5000492BF139E605D5CE13F3826AF182794177
+:10DE6000B530E605D5B6C7BCA0DA7ACC0BAAADC7EB
+:10DE7000BCA05A18F3826ADB635E502D8C7941B5E1
+:10DE8000ED312FA816C6BCA0DAF69817545B8F792F
+:10DE900041B5F59817540B635E506D7BCC0BAAAD62
+:10DEA000C7BCA0DA7ACC0BAA85312FA8B63DE6050F
+:10DEB000D5D6635E506D3DE605D5C2981754DB1E7E
+:10DEC000F3826A61CC0BAA6D8F7941B530E605D536
+:10DED000B6C7BCA0DA7ACC03AAADC7BC9F5A18F368
+:10DEE0007E6ADBB7B0856968C7DE4A72EDCD8EC544
+:10DEF0007DA793C4CF87EE037E4639DC3BDE46F92F
+:10DF00000B6F709DD892ADAC5B14FEBDCCC226E108
+:10DF100039F48EDE57F9F3257C278FECC112E25FCE
+:10DF200016DE88FEDCA34607DD87929BF8FD44667B
+:10DF3000E47EC03C51F17F94BC10F34489FC00CCDA
+:10DF40001D6CD48CA7B3C3CA8C1A3C4417DB747005
+:10DF5000AC334ED7BEEB0449571FEFCAD4D5275474
+:10DF6000DA75708FDA7C5DFB9EF31D3A38492ED648
+:10DF7000B54F59E2D4C1698D1374ED3356B974F5B8
+:10DF800059EE4A5D7DAF8DB53AB877D37C5DFB9B8A
+:10DF9000B7CBBAFA3E9E25BAFA7E7B1B75705ECB74
+:10DFA0002A5DFB0187DCBAFA02EF465DFDA0934DC6
+:10DFB0003AF816DF765DFBDBFC1E1D5CC8F6E9DA7D
+:10DFC00017593FD6C1C36C9FE9DADF1E7744573F2C
+:10DFD000423AA5ABAF3AC3FD7BD600EB038C538628
+:10DFE000F1FC1AB33DAC09FD8B91991774ED4D31DD
+:10DFF000B05E00FEA9067D887EDFF79D12291F33E3
+:10E00000AB8DB0E3BD6F7948ED1FB4F7BC47DB7F44
+:10E01000D07DFFE9D0084F08AD2FAC646F6FE9CD1C
+:10E02000EF9BB5E61351EFB3331F8B8BA190900F8D
+:10E03000FD23017F6109E00807CF0B0D7E10F94F2A
+:10E0400036F08BD0DF6C5D17199292D02E8706FCCC
+:10E05000E2EE5735795EAEE5178FC46FE7519E5EED
+:10E06000476F2867366D1A8EEBAC194C5E8CFB89B6
+:10E070006A9EC5FD21FAF8965A8EB0027E35DFDB26
+:10E0800017D2D8BDEF4FC8FB08EB596ADFDAAF12E1
+:10E09000FF1260B27334FD3F06EB3F23C875631D6A
+:10E0A000C81FF8434FD4D9085E591747F05375126B
+:10E0B00095ABEA32A97CA6CE4EF56BEAF2097EAEAC
+:10E0C000CE41B0BBAE98CA75754E7ABEBE6E02C167
+:10E0D0002FD4B9A8DC585749E5CB75B554FF6ADD94
+:10E0E0007C825FAF93A96CAA5B42CF37D73512BC55
+:10E0F000A56E15C16FD6B9A9DC5EB791CA3FD535FB
+:10E1000051FD0EF0DF10DE59E721D853B797E077C5
+:10E11000EB5A087EAFEE10C17BEABC54EEAD3B4932
+:10E12000E59FEB7C54FF973A3FC167957D8879BDA9
+:10E1300005DD7D3C1536B263DCDFC3BC1598872155
+:10E14000DFF4ED4FE5C70DA6C369A57FD310709727
+:10E15000308EDC2D7D5D83665DD1D09BC72DEB0DB0
+:10E160003C7F4B7D37666B20BFDDC1F8392DEEB7A4
+:10E170004FC77F49F034A66E0FAE372A6A799EF2F8
+:10E180003CE4C74CE2C7BFDCD03A4D59176C4E7126
+:10E190003E81FCC8C2DC9F26E506EED11F4871FD1A
+:10E1A0000E9F5FACBD7F0FB69E6EB3A7E347465B85
+:10E1B0003CB198FFCBB74FB4AF933AFE5E8D72FF80
+:10E1C000A1C3FA9DA7BAA3BD2AFE51A4B8FE7E53EF
+:10E1D000F804DCE77F51C1C78BBD0DBAF2EE54E7FE
+:10E1E0000BBD717F3FADF6850785C0FDFDB1B8C49D
+:10E1F00007F92E6112E5C119CF1CEFA30B7E27385A
+:10E200008208DFCD642A4F24BBFE88F3B9071620AD
+:10E2100008BB065A12DB9B4FF078DE52C6F39632EB
+:10E220000EB59C93EADC8EFD1D4B73E8C6F3A292FB
+:10E230005F680CF33D87E3FAC73B178E0B29017C1F
+:10E24000B7C653582DE5C928633C9EF228E6C58819
+:10E2500009E4C550D70F65FBF8EF1CD11FDACF7961
+:10E2600049B4BE0DCE9BB1B87037CF8301EB31BC42
+:10E27000FF5BF6C02F48FFE2EF41E1BDDD799D0E67
+:10E28000539E19EF0CE0D504CAABC1F3DEB8008190
+:10E2900009945783EA859BE0FFF1382E6BA691C65F
+:10E2A000D789F29D3C1DBA9FF2D2604CC1D219F3BE
+:10E2B0001E27D13CF73B2F70BF3BC647F75337A70C
+:10E2C000B8BEEACDE3E44FF5C33811F2137EC7E6DA
+:10E2D000A6F36BC04F660150343D06F8A91D7F437D
+:10E2E000E59BD9CA3D1CF539F0E309C4F7B76F0DBA
+:10E2F000C844BEA9D9592021BE1B0CFC3E9DFC6719
+:10E30000655F50F93D0431327B2DDD3B40671CE9F0
+:10E310005B104EF70E9A45367F533BFAD59AC3E908
+:10E32000BC3F8EE7936C08DA9F147238DD05A5DDDB
+:10E33000E877F7511EB2D97B79BC9AE57AB39DEDA7
+:10E340009CCBAA99FF9BA75235F3A8D97E849FE75F
+:10E3500062DE6CED392E49E957E53FD11CEE5A1BC0
+:10E36000A61D5FAB1C5872F2480E8EE3BDEE31164F
+:10E3700029F26E817E1FEC5BCC2FE3FA838DCE03F6
+:10E38000AAE702A7312795D3C17222DF3BE51574B6
+:10E390007F7E266BA2E7B3F3A726225CC37C43E310
+:10E3A000707DB4A4FE7D0C078D6F5C312C1EE635AC
+:10E3B000CE3DE57D2C4BD60BC76589E4280EBFEF1B
+:10E3C000156A177583EFDDFB6AE1228C5B8F1139CB
+:10E3D0001DD8879C0E65C0CF6254DBF981DCF4CC7C
+:10E3E0008925B9A1F1AB7253B68039F0FC817A3F2F
+:10E3F000A4558EF267FD3D01F770C09F447EADD9F4
+:10E400006989A2F529E699417DA5C8CF2223F72F76
+:10E41000654C6D4AFA93FB1B268792CF8B717F6404
+:10E4200096CCD763A74D5CDE4E7F15EE46FE9ED799
+:10E43000E9F544920F932A1F3F4EA2F33D0CFC8F47
+:10E440005BDBFA1FAD7966BA33F23758A22BAE6F99
+:10E450004AC09E9F36B8FB47F0BCFC0EC4D79E381E
+:10E46000BE7E9E857968B0BEB353C278E9E9582B69
+:10E47000DD170ACE73C6989DE66752E607239B8098
+:10E48000FEB44589AB3504CDF7FB90449AAF54C830
+:10E490009A183A16469B3C15E5FE416E27E675FA3A
+:10E4A000B50BBFEF0D61366110CD87E2B1B2813996
+:10E4B0001B787C96E637DF68B5E1B99CC55344AF5D
+:10E4C000407602C689F1BC18AB9DE75555F36F073E
+:10E4D0008FD7A11F9F3591E1FC1C22F3850CE2E34D
+:10E4E000C5F1C9400FA20FC05334E3837EDD94FF12
+:10E4F0002754B2A11FB6F75F0FF2F8723DF71F6104
+:10E50000FC1B893EF130FE846B8FDF842C0AE39F75
+:10E5100093C3F55403EE208A68673B93FE2D09717F
+:10E520003E807C98EA5AD67D0EC6350A2C768CDF62
+:10E53000B12B0DDD514F853189F26A8D71F0BC5AD6
+:10E54000D0DD42E48712CC5B67233FE0AC360F1B83
+:10E550000B8AAF015928BE3A0EE36BFC2ED17B1813
+:10E560009F1DAF9C6FCE625FAAF8A3F89A88E3A3C1
+:10E5700078B58BC66941CA421982711EA2839BE697
+:10E5800011CA3C4A3CBB85FC83150A1F0E3AC4F9EC
+:10E59000705018D7773B8F30379EFB6AFEE1AEA2F2
+:10E5A00070842F18494F019E281FE0DB7FE571A979
+:10E5B0009DE78E27E03E4CFD0F7B12D04FDC697249
+:10E5C000893530EE9D0516DB027B20AEB1E3501895
+:10E5D0008FEB2871BE5B9479EE602D0D35509F1F37
+:10E5E0002F328C03E61DF484A23C0F54E2B2C1FA30
+:10E5F00070F025B3EE772D4C363D9CCF34701286EB
+:10E60000C8827EFFF306D7B9AFE574F0BB9F2763DE
+:10E61000AE6B3F147FCB87CE27E438DFCC21BB36EF
+:10E620004E54F02E20BE400F34239D9FA936D3EFC9
+:10E630001A34579BE3BD9AF135CEF847029D73FE1D
+:10E64000D73FC86EEDCA53F3E33485E073B31C4E75
+:10E6500071B767AE1828EEB6BAF26B5A9F34E6333C
+:10E66000FA1DB1C62BE5E4075C2E66B889C4EA6FD3
+:10E67000FD3F95083F7E8B95BE173CFE6DE0CF7B3E
+:10E6800080505BC19FC7D20DFEBC2703FDF4382A22
+:10E69000D7803F8FE533E0CF63FD2AF0E7117E0A94
+:10E6A000FC792C57823F8FCF9F007F1EE177C09F60
+:10E6B00047F86DF0E7117E0BFC792C1BAF7C5248BC
+:10E6C000E39ACBE8DEFE82D088A5E8677493C3C9DD
+:10E6D000DFF8C8D1B793576367F3BF34E8E8DCFFCE
+:10E6E0006027DDEF9D24C95141BF47D32DE8F76A6C
+:10E6F000F4BF6F9350A9FF7D9B7857DFA0DFC3194C
+:10E7000018F47B3943827E4F47FFFB36B75E1AA76A
+:10E71000AB1F7C56FFFB36038F95EBE0C7957C99CA
+:10E720002A1DD3A5D742902F56578E8B64EDF8172C
+:10E730006A89EB2B8F667FF5C987C409EDC59123E4
+:10E740006FE6F6FEDDAF2CFBD6033E77B14827C659
+:10E75000DD77390CA4979E59154671588B77E029BF
+:10E76000E49F5D0E2621FF3C736548271C4F2190D6
+:10E77000119F275472BDD0ED6689F839A1D227E2E6
+:10E780007DD1DBAEF8ECC88F4F46F0DFD9827EDD5D
+:10E790000BA0BF7747F7CFC238CE3361C0CF286F09
+:10E7A0001E5F682AC091570D0CF523D84ACAF32F73
+:10E7B000FF3E4C398F7A95EEC345A24E07BDB4ABF0
+:10E7C000927F3FDD7B2554EB0F3DFEE3B5F0C28821
+:10E7D000AF3AACBF6366328E378077508D50A6B3A8
+:10E7E0004AF618E2A38ACB4F63A581E4E932C81345
+:10E7F000E207664D74617838215EFB3DAB9E0E5595
+:10E80000C94B719ECFAC34D26ED930F1D57D37C3B0
+:10E810002BAB0F8AB4CD2ED97CA1EDF977EAB8578E
+:10E820003BF8FCA2ECCC80762E0AF0E9A6FD6C7BCE
+:10E83000BDF6F7AC7EAFC8E7EFF0FBF0DED30A3FE2
+:10E84000AC54E47398B866443A8E239FEB6BA0A750
+:10E8500080F7B12E4F63F43BA2BF2B4DEED45E9EEA
+:10E86000EF95CA389E53E6B54691FB67B05FBCC7CB
+:10E870002E9615623FAB9D8CF4F86AC7D7F518B792
+:10E88000BB5CCAFBEDF9885740FC76AFF509D87F31
+:10E890008FB91E2ADDCA38BB55B650BDDA9F6477E2
+:10E8A000737EAFFA9AED85F9E2215B91ECC559CA06
+:10E8B0008FBADA68646887519F217CD96AC43312A1
+:10E8C000ACDB8C630CEF33378619699F62F5ECD3B0
+:10E8D00004AFB0713842AECDC6F3176F29F38990FB
+:10E8E0006582DD41F3499726476A7FCFF55A7AF072
+:10E8F0002D93CB7011C631E06F22FD7E4747EFA903
+:10E9000076F65AFAEA4FF88F78B20B0FDD8CEB6788
+:10E91000D94976415DB76D1DC5D76D2B42277D88DE
+:10E92000EBFE52858F9E0E1DF33ED61F18C17F074A
+:10E93000A779C4ED3DB47A72BB32EE6D0ADE0B8E60
+:10E9400039BE9A0BEF8F745A189EFB18293B7AFC3C
+:10E9500002E15122E5351FC01A1BF05CC5C13C55D0
+:10E960002E9CA1287FEF8E9ACA0EE1778AB99DDF8F
+:10E970005A3C9E9E4BCC39B237BCFF498B91FC1A56
+:10E9800078FE9372B94F19CF070A1EDF57E8B05BC4
+:10E99000A14333DA132877A13D217B6157EC05B7FA
+:10E9A00027DBD09E64201DB83D69417B9281FB6FBF
+:10E9B00013A8DD5FD09E40993BA288F6232F232326
+:10E9C000913D99CD16035C08E317DBA1D71DA9A2E1
+:10E9D0008E3EC5DD4375F4191E13AD83878625E889
+:10E9E000E021C6141DECB87253903DE81B640FF48F
+:10E9F000F624FFCB21BAF6FD0FDEA1AB2F718CD729
+:10EA0000D58FCD9FA8AB1F6D9FAAAB9759635104BB
+:10EA1000CC37EF4B467E685EA73522ADAB957D3493
+:10EA2000D5DF027A923F56F05791E456C5471E6BE8
+:10EA3000DDCF33D07E9ECC243CDF495B96C9BA7AC9
+:10EA4000F2A30E9A9C09780EB1BE04F80FCF231ED4
+:10EA5000AC18C5683F1EF818E42ACF79E24BCA3BD0
+:10EA60002A96F5237FE99251B7AF5610B43F36206E
+:10EA70005BBF7F96778DFD33EFCDCAFE431BBFACE6
+:10EA8000FDDF450AF6CB40AE441CF7D3A1937623B5
+:10EA9000DF7CF819B757CD9F3DD51D9F7F824DA1D3
+:10EAA0009F7DBD9FEE8E7CBFAF553E5CA15ABF6B74
+:10EAB0006B26FF1D9A370F266FC7F546AE4920FD1E
+:10EAC0009F9BF5249D47BC7CD040BFD3995E5C13CF
+:10EAD0008A78D97A685D98FE1E95464F909FAED190
+:10EAE0001322FAF751FA7A6342004EE6C4C1F6FFE8
+:10EAF0001710600A2E008000000000001F8B080025
+:10EB000000000000000BED7D0B7C14D5BDF0D99DFD
+:10EB10007D259BC08604DD400293F030228F0D7965
+:10EB20006D42122621D0A03C36801004E384A0D090
+:10EB3000566DEA137B6933493089014B546AC1FA37
+:10EB400058B1DAC7E7FD9A5A0950B15D9E55A1B296
+:10EB500048B051515779685BDA0F155AEFFDF17DD6
+:10EB60007EFFFFFF9C4976864D88BD7DD97B939FB4
+:10EB70004ECECC9933E7FCDFAF73608CB1CF24F875
+:10EB80001F9BC0422E463FBC3DD5D42E62A1ACE8AF
+:10EB900076B9A97DB5A9FF0253FB3A53FF1586E765
+:10EBA000AF642D1CAA26C0DFF833FDE2EBB606C623
+:10EBB0004257F4F5CBB30524DFC48BFBE5775BFB51
+:10EBC000C685FF768F5B653D9FC25857B714746644
+:10EBD000C075EC2AA6E5C238DDD620B3D0D5CAE090
+:10EBE000F92B3DBCED64C10D53E1F9B66E9BAF5DF1
+:10EBF00066EC45FCAE93B1F1811B860612192BB170
+:10EC000085637EB7F49CF1BBAFF42C18CA62F4D3D1
+:10EC1000AFBF10E3BED0E0A275ED6CF0505B7F2E6D
+:10EC2000FDDF7347E7E3BCB3241FDC86F997273386
+:10EC300058F72F2FAC74E3B8305FC6463036A33395
+:10EC4000ADBA712C63320B2658A1FFB62C89B5C31F
+:10EC50003A738FF1EFE7DA95644F0CB8326635C23C
+:10EC6000FFA2F1E007E174C11AC4F1F68C5BF2D0A7
+:10EC70005418FF60B7C4703E0E75B53B3009DA3DDD
+:10EC80007C5EFAB8D33FB5F6E119FE2B3E136F80D8
+:10EC90004BD1C96186E7B9572E1C8AEF3BE4F9C90D
+:10ECA00008DF4BCD93B178131D0D33B54718FA8F9C
+:10ECB00097016F93FAC7C37681876D8807B86E8F07
+:10ECC000F3550762E06DDB78E7EA60D43A1B7C40DD
+:10ECD0002C7978B5D235F74AC91702F89CEFB6FA05
+:10ECE0001078059E7AA93E06DCFDC78D7492DF1D63
+:10ECF0006F800793960FC8076B8E37B6EE8BEAFFCF
+:10ED00000D5F62CA6937FC51C00A68FD9778FFCF72
+:10ED10000D5AEB3E3BD031634A27AC93552E64AC81
+:10ED2000B0FFFE8C35D1FA7438B2CA64C65207837C
+:10ED3000A70E7AEF227CF5F37EDF381A63C3019EBB
+:10ED4000005E9C57EBE4C0C33E1C275225E1F71F31
+:10ED500070DF2A45607DDF75DFBA17E9F3D07B0EDF
+:10ED600019F97AF77B5D6978FF60F6F634A4FB83C6
+:10ED7000F04E18DACC065883B643BBDE8DF4F54A64
+:10ED8000F76DC43F32AB3F3889CB015F3B74DB9EEC
+:10ED9000C5E9B0BF79BD24E4CF01C1AFFB04BFEE2C
+:10EDA00069F0523BD420D3F5170D59747F57838FE8
+:10EDB000DA3F6FF0537B478342EDAE864ABA1E6955
+:10EDC00008D0FDC30DD5D4FE75834AD76D59B7570A
+:10EDD000A03C3A9F0600807535B9E7D962E173B669
+:10EDE0002C19E8E64B5EB781AE667A920DED19AE4E
+:10EDF0009186FE656C8CE1F9F44F27189E979C9DD7
+:10EE00006A684FFBB0C8D0BF30526E6817F45C6DB3
+:10EE1000E8BFA062A1E179A07899717E5202C997FA
+:10EE20009D6719C9E579B97586E73BF10F94C31F52
+:10EE3000B2A09681705938A03CD5E5F45E819FDD83
+:10EE4000023FBF14F8E942F8139F571AE09D7FBCB8
+:10EE5000F39A29C0AFBF6A584DCF1D5943CF49F02F
+:10EE6000DDED67E365947BFB1BEAA9DFC1B71F24D7
+:10EE7000BAD929E671D0CECE4929D8B6C84D968BDD
+:10EE8000E793D763E4F3F1953790BCDCD9DDE44632
+:10EE90003ADB115930287DA7F7FBD5B90533902E01
+:10EEA000FCDDA0A3322EADF7747D75A9F1F57EA827
+:10EEB0004F63E909F3B857475489C13AB6F7D43FCD
+:10EEC0009488EDD0972519DAF93DEA0CC4D7AE2C19
+:10EED0008B47B250BF190ACEFBE46DD7E0FD1DC7CA
+:10EEE0006D569CF72190FFB88E9DA06F9DA87FCF97
+:10EEF0006D754F06F8BFD8F3E03593A19F76C6E64F
+:10EF00001BC72E9EC7A86C89E4C2B6894EAB650AA2
+:10EF10005C8FDB5808E5974D25787645B6D215F518
+:10EF20001FBF5F4FF8BA32DB43EF6D3FF95C32B67B
+:10EF3000ADAC9EE4C08BC7AD95C118EBBD12BF034D
+:10EF4000B223EF4283DB03FD0F1C5FE146B9B2A39E
+:10EF5000878F9FB75673239C0E46B626E0FD9D59BA
+:10EF60003FA371774FE276C5CEE356A2E79D13AF7C
+:10EF7000D8E0CBA575FA1076703F01DBDB7A6CD454
+:10EF80009699CAC2292877A460BB05D7B382BD066B
+:10EF9000CFCFFBA420F27D1ED31CC0A26CDBFF6B85
+:10EFA000599CCDC1CF6C9731760B7F994D3B6BD47B
+:10EFB000B3453D463DE2885C383A1FC6EB3AC3E5AF
+:10EFC000DB8C4F8D7AF7E01B999B028897337C3E50
+:10EFD0003B8E2F58548572E77989DA8D93563DFA26
+:10EFE000757CBECDED73C2F7BE9CFB644B327F7D5A
+:10EFF000C85C9847B19853DE19E33C0E5E59C73E92
+:10F00000C6759EB4D13AB61DE7F6D5F92CBEAE9DB5
+:10F01000BE3AF66DE42F617FCD78FBFBD74C4A41B9
+:10F02000BAB0925DF182EF67C939289F3C9281EEB8
+:10F03000004E4437E7BB198D031245BA15C629F0B7
+:10F040003B3DED1EE4C70EA29F836FDB7C4DF8585D
+:10F050003AB4F736E89F375262B8A22F074DF2F262
+:10F06000876E43FB16D9282F9DAC6A40BB61DA59E5
+:10F070008751BE7EEA308C57C0A29E133EA39E6786
+:10F08000FC0576895D5D8676090B2F1A94BE66AC09
+:10F090009EE4C50EC67CED404085574A0AC1EFB8D4
+:10F0A0008BE057F0DDAA698CF4B43A0DF981883110
+:10F0B0004A2F5FD24EF1682C255F7C0AE980D94E39
+:10F0C00047A07F1B10C967A8BB851E378FDB9FBE7B
+:10F0D0007FC03D84E47D718585F8E7BBEE5749BF6D
+:10F0E000779DE2FA1D7F224077D7E21FA8EF4F39C4
+:10F0F000881E5E986D2139A2DB0B0B996247BE9981
+:10F10000E73F67BB1FE836E0AA99740B5C5F78A302
+:10F110006B24F2EF0B6817907CE8207E7668895AA2
+:10F12000328CB3ABC7497CB813F8CA85DFDDE52460
+:10F13000FA043E5D8F76C2AE30E7A3AEB3566EE7FB
+:10F14000ED72139FECFE8383E6DDB5D6CDFD8B33E8
+:10F150000E05EDF09D6B13E9FDF17262C88676FC39
+:10F160001A3E7E8FC0EBEB02AF07859E7A19F594AD
+:10F1700013F5904CD7FDC28ED88B768413F5995F2A
+:10F18000E833AEC79E3FFBDC5B48FFE777C591BD28
+:10F19000399E6575E2BC762538689E66382F558D98
+:10F1A000F4BFA4DA682FCC9968A4FFABC78E34B43F
+:10F1B0002BD3C618DE9F957295E17945428EE17991
+:10F1C000B96D9AA1AD5C30DA0BF3FDD718E9498926
+:10F1D000B21732F1FF467FF1DA687F11E5C8D90531
+:10F1E00064AFEDEC117AF964E65075E2C5FCB3F357
+:10F1F00024D79FDB8F7F9CA8C6B01F3E14FD7E27BF
+:10F20000F07146E0E3B7A39493D94097E74F7EECC3
+:10F2100000A5D12F1DEBEFEBEF7D183C31245AAF49
+:10F22000A74B32D1B7DEFE43D75BE3F1F960F902B9
+:10F23000F4585B04F07CB794D8D10EAFB4DAEA9FEF
+:10F24000C0B6A6D9D8D3B9048E2C1B3D9FE0437B12
+:10F25000A539B1FE07F87C5BA3D3B33505F9E85BAC
+:10F260003FC1F61A6005275CFF1C372AC880D51CF1
+:10F2700053B9DFF28C3D30D2877AD31258760BF433
+:10F28000D7B6387C4FCB17CF2761AA4567F61DA8A4
+:10F290008724C1F7FF695113A6C27DE5590BF163BD
+:10F2A0001C38A2380F270B8490FED96A6519F20723
+:10F2B000B302FFC0F51B39EA30ECCF14267B601C8B
+:10F2C0001215F03D4BF8C07F58605E7656AFE138BE
+:10F2D000CED52061809F1FC85653A9BF6D018DFFF9
+:10F2E000FC5CC6DA492106A89D7B17F3B427C1FC54
+:10F2F000986AFD18DACBC0CFC7EF5BDD37931E7A73
+:10F30000EBB7D6A014C35EEA85F3CDF633119DCEDC
+:10F3100032FBEEEF1078ED1274B12323B02C965F20
+:10F320003815E182F6C5BBF324A4AF5CD71005ED18
+:10F330000A58A05405F27DC7FB57BB6B63BC37333B
+:10F34000B776EAD428BAC80D774AB509080A4DC27B
+:10F35000756D83BF715D3FEFB68610BFE7131C2448
+:10F36000B7FB5B4761C4A8870B7A8C7E3763CB3DC4
+:10F37000A7AF427877583EBB2A9ABE94F5D1F4F5F0
+:10F38000FCC5F44570BEFB6816C1B5D9C2E94B0394
+:10F39000FAC2E75A793DD197666581E65CA2377A71
+:10F3A0007F8DCDE57182845C353593E8A62B71CED7
+:10F3B0005B2199BE376601F97135C28FAB2139FFE8
+:10F3C000F23190F331ECE8DDC7168F8C00FCB68D7E
+:10F3D0005B3212F9BC0B15C0089C7EFE52B42F7B29
+:10F3E000DB802EB20367320C55C1F3DCA50AF69F11
+:10F3F000ADB7F378FF32DEFFA6A99BB668F8FC7ABA
+:10F40000F19C2DE4FDF5B656B0B40CFBDBADD47E1B
+:10F410005BF47FC8A7AC42BC3D90ADACC66B361A5E
+:10F420002B703D3D45F90AD2E9AAA98CD67BD714A9
+:10F43000E5E6E8F6CF262BB746B7B7F5FAA71DC223
+:10F440003FBD85ECD2977B16905E9259E01AD43B73
+:10F450002F87791C6ADBD881FD9F5F097B7EBFF017
+:10F460007FF6A23C223F88FB3FBF147AE545A157B7
+:10F470005E107A65A7D02BDB857FAAFB47AFA27F02
+:10F480000AD743C23F7D05FD25E8973BEE04D91519
+:10F49000E73F65C4BC4DEE5F48B1E46A659AD17E32
+:10F4A0009B9562B4B72A128CFAA6DC66D437CA855B
+:10F4B0004C43BBF4DC0443BBF88CD13F2D3A596478
+:10F4C00068FB8F971BDAF9DD579BF4CF42C3F355E6
+:10F4D0005365C2E35C9FD14FBD26ABCED0AF0F6F5B
+:10F4E00001613F3C968076DCB6B175026FDC5ED080
+:10F4F000F1D6F54F83B7BDE49F9D3FCB445CE171EE
+:10F500002996FFF9AF8FB74BF05B02B7F32EC56FAB
+:10F5100007847ED827F4C31EA1FF43C28EFB8588D3
+:10F5200007ED42BC511C88C7837620DEA2E211CFD2
+:10F5300023DE9CFDE3AD79EC439CDF4EEA78BB35DE
+:10F5400026DEBEE435DA77333D46FB6E86CB88B7E0
+:10F5500032668C074DFFD488B792B3C678D0B40F0B
+:10F560008D782B8C18E341053D46FB2E2F6C8C07C4
+:10F5700099F10676404ACE20F0067E924274EB1353
+:10F580007A3FB890F451CB5CAE1F810FC9FE7EE686
+:10F590004EB003B2FBE0F1BCC97F7ABE1FFD3D3E19
+:10F5A00087DB355D6FD5105CF3507FC7E8972DFA88
+:10F5B00065E778E8EAB4312D7E2A4D73DF08988F2D
+:10F5C0006D2CB77B6C891B18D98B406ED6FC3E3BEB
+:10F5D000494A08301C1FECA5EC9CBCBE716D9E7A9C
+:10F5E00086F253723EB81CD7C524AB8FF4AEC93E29
+:10F5F00062AB3DCA6D78FFB621BE7680C54D3949F4
+:10F60000340F2FEBB4A39DF18D1CA508C795667030
+:10F61000786C4B071F1EE0B12D8EB73580D7D3D045
+:10F6200096862E27F87501BCA46C1C3F85DD05F37A
+:10F630005A98E3E07058CA843E7DDAA80FD1608002
+:10F64000F633F1BC7D6DCE334BB5B43EFD5BF3B309
+:10F65000AE2D1A8C333E61441D9B0CE36ED686A101
+:10F660009D3911E687F2D1EADE951E4B4FF467878C
+:10F6700069939545481F7709FD3A1E20629BDAFF82
+:10F68000FBCFC407BE8AF8CD457844C5BDE6E67019
+:10F69000FB6C218E9347F6A5126D5FB2F0426AB7FC
+:10F6A0006473FA7A6AC302A2B70480979484F3E77A
+:10F6B000F05B7607A7AFCFBB0E7DFE03D04920DA03
+:10F6C0009E8EA293BB62D1099BE3F392BFDE9F3D66
+:10F6D000A7F1F9360BFB51B7939D69BADD1C147085
+:10F6E00060A1A26174653301AEC33C8CE234351E67
+:10F6F0006B3008208B4B9A6A21B95361619E0C1CB8
+:10F700005D611C8F73E468F9638E0FFA8FC79BE409
+:10F71000BB31EE547C6684A15D7A2ED3E4274E3053
+:10F72000F99139263F739A493FCD30F4AF4CBBC6AF
+:10F73000E4C72E34F9B946796363364DE0CB4A719C
+:10F740000BCD22DBF2F13E23FC443D27BFB317CEA5
+:10F750008F2AD5C4AFC2AF31F3EB37726482B3C521
+:10F76000C3FD1A9D1FF4F775F839BC1AE17563BE25
+:10F77000AE9F7CA4775CA12F338CABBA7C3C4FA3AB
+:10F78000F7DFDAE07AAB621C63DF6F606F5500F27F
+:10F79000820D1EBA3EDEE0A5EBA30D325D1F69C8E7
+:10F7A000A27E9B1B7CD47EB8C14FD74D0D0ADD7F56
+:10F7B000B0A192DA1D0D016A6F68A8A66B7B834A1F
+:10F7C000F7C7DA540DE32063DB984F83A58CEB80F9
+:10F7D000EF45C16D4C1BCC230AEE199AC7D01EBD54
+:10F7E000C66BE89F5E2F1B9E8F5C9D65789EAAFA74
+:10F7F0000CEDCBABFD86FEC3038AA19D5C5969E885
+:10F800009FA4040CED445FB5A1BF3B4B353CDF53D7
+:10F810005A343432001F773484C20887F686305D4C
+:10F820003734BC44D796869E30C2E90CCA5FC0A369
+:10F83000C7D649F2C333D1C3304FE17201BE008F46
+:10F8400049368F25296AFC2405C6CB8A9E1F8C6702
+:10F85000F0CF82442FEEACB0E1BED3DB63786FA66D
+:10F8600094508EF98923C512C5BD8E142727A2FD99
+:10F87000B2DEEE999B0BF3387C4CF26DC5F5E20BD2
+:10F8800031E4E529616FBA27BB482ECCDF64D92A61
+:10F89000115DF3F76FEA1E13337E74F89BAC1AD731
+:10F8A000E5DEB35346BA985F5C9B1C17E5AFCD0FFE
+:10F8B000FD47452A8D979D1F07F4327F73ADA36ED8
+:10F8C00062DFBAF47E376D32DA977D741F74E13AE5
+:10F8D000C66BDF74A17C6B4FDB4AEDF6AC81F32481
+:10F8E000BF13EBF950D8CFA7851D7652D861EF0B27
+:10F8F0003B2C22ECB07784FD7C5CD8CF6F0A3BAC0C
+:10F9000047D861AF0B3BAC5BD861AF093BAC3DEB7B
+:10F91000B959240F9FB53029869FAA5FBFFA43A328
+:10F920001DF6E5A0D10E5BB5D96887DDD861B4C3FB
+:10F93000EADA8C79B95AED2AC3F31BD618E36CD7EF
+:10F94000D71BE5E1B2D5330CEDA5AA31CEB6A4DACA
+:10F950006887E9F8B93660948B0B2B8D76587FEB6E
+:10F960007D21349BF23F88C413517AAF378F8B7A55
+:10F9700005E825F702E8158A83079A317FB203BBB1
+:10F9800080FE2DB1868F4E41F9F9BAC430EEB4E74E
+:10F990007CFE9CF9F2C5DFC9D78C74B3FCB831BECC
+:10F9A00071DD1D46B856DD6CF44B1C9546B82A69CE
+:10F9B00046BF64A159CF048C700529CD902ECDFA95
+:10F9C000C6EABE5946F9FD79F58E83815EE16D8305
+:10F9D000DE71E09D4CC373D23B6DB93C5E970FF373
+:10F9E0004063A131AEE010E693F6BC61A3FA109833
+:10F9F000E06B6341FF94E2DF00BF17EDAA560FF4FE
+:10FA0000FACB42A7A7094C56269DD9FB35E8EF1043
+:10FA1000F910F6A9ED248EAFC22FE22B9F413B4A8D
+:10FA2000CFE585F9F3A8F91A9E7F0F7136E07C9433
+:10FA3000D7C6E6FF3DE7939882F6109BC2A6509D7D
+:10FA40004164D8A0E2ABE6FBB9216E07E5A6713BA5
+:10FA5000C89FBE40127927E6C1B695B9289E398A5B
+:10FA6000059FC63867FC21F73C6836E390A9E85744
+:10FA700019F97FD19C81F3F25FF21AF97FB63CC687
+:10FA8000E40F19F97FAECFC8FF4E66B25F224C4635
+:10FA90007B927060353C2738BD26E8A8F1BD96659D
+:10FAA00094874DE771379D7EA6097C31D6B9B7168C
+:10FAB000F3CDE057A2BFE1645AF214AC2B0AD72B66
+:10FAC0007ADE8DF026ADF5915D7A86E3C70FBF88AB
+:10FAD0003F3F8BC217E2EFB8117F4ED3F3D3829E24
+:10FAE0002E9E17A7A37FDCBC4C749530EC12F9B79F
+:10FAF000D874551656A44498DF7E8F85F2A9FBC3AF
+:10FB0000F5E132687FE2E5F542AD690B6C345FA642
+:10FB10000C9909789825D6EB1779ADAE064676C7CD
+:10FB2000F30D2EBA32562FA13C6AF1DE968CFAB153
+:10FB30006B943A12EBD2BA8627ADC3FCFC367B52EB
+:10FB40005AAC7A96DDF602D2A75DBB536D32BC5F2C
+:10FB500066F3D8F0BDB2B41512FA7B5FEA616417A0
+:10FB600094A5F1BA8CE71B4247F8F754AABF8175F8
+:10FB7000CC40FBB4C2533B233105E3B3608BC9686F
+:10FB8000E72691FFBA6FB893F0E6F4ACAAC0FCF197
+:10FB9000ABA912B3F8013F3EE60BA11E484BF0059E
+:10FBA0007138AFFD7D84F36AF8FD2CB34F2F009FB1
+:10FBB000BF1F8D8F0216D5A6BC82B13D224FD43F08
+:10FBC00009FCC84CA53A8B961E9E1F6291D8799667
+:10FBD0007785DDA0C7F78F0BBBE14D11773B22EC9A
+:10FBE000861661378484DD7054D80DFB84DD704047
+:10FBF000D80D2F09BBE11561371C127643AFBFC08A
+:10FC0000EAC99EAE65AE08C6D95F05FF1CE58877D8
+:10FC1000A5255809EB98A17604CAA1ED5C6727F9E0
+:10FC2000393A4D6BC4F8B8B35A9B89EBF02E3FBB01
+:10FC30001AFBA7A6396405FA3796B6A746789E61DF
+:10FC4000C85CE08F95825E96AAB30E207FE870674D
+:10FC5000D2A379946FEAE0F076C12FC23B55857646
+:10FC6000941CA935C17529B6A3E48603E910E058B0
+:10FC70009927F82187E570786B7108EFB85A016F02
+:10FC80006F4A4CFED82CE0ADC36377E957AC1A74C9
+:10FC90003D9AC6EB258E167FC5FA2AACAF5B91283C
+:10FCA0006FDA9DC6C75B20E8DF3C9E9E47DD583E6D
+:10FCB000709CEEB0E8D7DB6E63B27368D438E5FFB2
+:10FCC0006697E1FD25A17BD2911F360ED1F3C33E8D
+:10FCD000B2AB674AC5BFCE80798645DDA32E271714
+:10FCE00033011BD3F78E8A75F6379FA3E5D7D86506
+:10FCF000187751E81E86DF73DAEABDD1F5A4DD621C
+:10FD00007EAD55B733E4C7F028C03BFAEF01A78CAE
+:10FD1000F6F6E834DFBD88776F9A6ABF13EECF033B
+:10FD200039287B705A1DBB53B01FBCF30843FA98A7
+:10FD3000D089FC7634DD45F2A6BFF95CA43F828C05
+:10FD4000EC90FEF407D031D941CE391F1C477F76A5
+:10FD500021ABF785E0BD70AE6F38F22FABB6935E86
+:10FD6000CE82DFE87C9A7E5D68D2DB6EBF7D40F993
+:10FD70003BFA42431BF2CD51C137AD3696887539F7
+:10FD8000E139B7BB103EF3D333F7207E58992B32BD
+:10FD90000EE0D05A7CE7F508AFD639AB3C16A4ABE1
+:10FDA0009231F43C5CE63A8D9538BF29BB3B5D8EC1
+:10FDB0008277EB7DAC544578A7DFE5BD09D69599F0
+:10FDC000F6A7067532F4B3737FA7A7FCF76919513C
+:10FDD000FD27E595FD200FF9B97238F1C378879AB0
+:10FDE00019AB1E58A7F3C6D278E2F3F76B799D02E0
+:10FDF000DCBF770DCC47C5BA155F1FFFDE28E829A9
+:10FE00006EDC39E273F53EA78C7E069396B7AC8123
+:10FE10007635DA4968376DE27CABF3717ABD515EB5
+:10FE2000AA26BEAD36F1B5CEC7BB75B9D9C7C7894D
+:10FE300088D7B85ACE4FFDF1F1D24FC1BEA142A032
+:10FE4000A0C1AF7B63E59878AEBFA2ECDA2924931A
+:10FE500064473E568132B26BE3C57320C9DD389FDB
+:10FE6000F03D3973115F5A23D8FF38B735F63E7A23
+:10FE7000CBC475B2217E587FFC5A291BF329ACDE16
+:10FE8000DE6717671ABE4775028BA3DB48AF9AF28D
+:10FE90001BB41F308C891FFDF37B47F637C3F7DA9D
+:10FEA0004724B34684E71D9CFE5CF010C703353D34
+:10FEB000C48FCFBF352E1B53F72C9A5E61FC88C6CA
+:10FEC0009FBFB36678369999A25D73CF98A9D8AED3
+:10FED0000AD84F46CB55566123FC5FBBD6B215E31B
+:10FEE0007EE3A58FCEEE85FEF157397CCD30FEB591
+:10FEF0000FACB0235C1669EAFE3AB8BF08E822E806
+:10FF0000A37518F8E4A8CD63C7718E56585807B486
+:10FF1000E31719BF53B3D6C847663BE458A23ACAA1
+:10FF20000AEF7F6071B2AD70DDBD65D5E338DEA943
+:10FF3000079C544FC870AC7CD4034CC42595C7EFC4
+:10FF400081E72B363B19C603960A3B3F313F83C6F8
+:10FF5000B5BA97D3FBB5ED89E40F9FDE72F964C49F
+:10FF60007FDBB0FA5B03C037A792D41AC4EB8AD602
+:10FF7000ABAC1A3C6F8BEF9889FD3FB032CFD66C9B
+:10FF800068CB0FDA713E3D6017609C559F676D5BD3
+:10FF9000147EE1BFEA7C1E779F67656A670C7BA6CB
+:10FFA00023DFA2C7573567D4FC1FCA97E9FEBCCC34
+:10FFB000612D0FE17700FB1E9F800BAE7B268F87A4
+:10FFC000B6A5F96A8643FBA485799A52F0AABC8348
+:10FFD000FCA9DDEF644F13FA19F5778C1CF1647BF3
+:10FFE00094DF3F497CF744127FFEBE373E88EB7CAE
+:10FFF0005FE66DCD9B10247AB6A9598B13F97A2C44
+:020000022000DC
+:1000000097E1AE073EBF6389B22393F0C1E4E76096
+:100010005E2B367D97F0BB0DE083FCD9E3915B76D8
+:10002000C33C4E83F2D6F0B9F7919908CFDBA70213
+:10003000A1A65E0CA77BF287F13CF4E6E644D2F77A
+:100040001EA63A2EEB83476DC7F6BB2D9349CF6BA7
+:100050005C7E70FEB3B028F90EF89D57F81DFB0AC0
+:100060005C6F1CEB40BC58F7AD73E13C97D6DA29C6
+:100070002E94C00295284F6B3759A80D3F1B505F37
+:10008000AC10FCD5260F3B5087F0403B9CFCBC4796
+:10009000F7635D40AD905FD52B8D747AA3D766A0D2
+:1000A000E3AA3546BA86751ADA9BF379FEA5C77FAF
+:1000B0002A05F5731B2C1BE1F2418B25B895E46BE7
+:1000C0006054745D9D9C6FD5EB56647B14FC5700A7
+:1000D000FDAD40BDE1621DE5A9B8EE71B390DE1D36
+:1000E000C7E2699E66F8FEB3C3E144BA5C331CE61E
+:1000F0007302E818EB7EDEDFD24CF60BFE4806BE3C
+:10010000F6B4207DDF04B37CC443F4E9C0FC914E17
+:100110002F3A7C6A37671CC07EDEFF932883D3C4E6
+:100120006ABD45AB30AFD34B4726F8E09A6DFA77FE
+:10013000C6F4D1193D8F4167E5D097E345237EA9E9
+:10014000ADE8CDE78D1AA86E99F05D049FEB9ABCDF
+:100150004C2B16EF03DD6F2C7D85E8E0130F0B4A67
+:10016000DC9F7D1DE57EA2989BC69410CAD721A274
+:100170005E14F512FAC9C962BD496B2C6F56E430A2
+:10018000366C8DF46605DC4CAA0887504F38BD42AA
+:10019000EFEE2AF8C9F8CBFAF4D890F839BE10ADD2
+:1001A000C6934AFB12EC9E54B47F1EB058AA315E2F
+:1001B0003F8419EDAA64133C58AEED64B43D1E2F84
+:1001C000E4FDAA99632CE4E7541AFD529BC92EFA68
+:1001D00011D2F5F0BEF5CBF827C0B105FC3694532B
+:1001E000C3421D1D489F3560B70669FD3ECAE7380A
+:1001F000407F3C62E98B5BFDA3E21617C5BF44DC80
+:10020000A2BFF8971E0758C86FB18D0ED58BF9BEE7
+:1002100085DE9BE6A01DDA58FA152FF94BDED36474
+:10022000973A845D1A376EA587E7CD38FFE87100ED
+:10023000335D99E34966FE33DBA5BFCD17F6D304E2
+:1002400036E1F3C405F4F87D6B16F77B5AB35634E8
+:1002500061DDDA79E1F778342BE171F1220BE151BC
+:10026000B7D716FBCF2E42FE7B55F81797F27BDAF5
+:100270004D7E48BCFF494589A13FED055C3EBA8BE8
+:10028000F9F3C52E667345E50D1C055CFF2E063D92
+:10029000E88225CE633CBF319F19F35249621CFDB1
+:1002A0000A3FE1A9F9863AC1A4027E9FF2A04E91CD
+:1002B0000775893AC1B2EC737B3FC3FB0AAFFF7588
+:1002C0002AB58FDD8976DFA2449F95E8577DFA3BFA
+:1002D000E81F2F7293BC4DC992A9DEB53ACDE52334
+:1002E000DAD794D7D12F5BC488B701D40AC9DB25EC
+:1002F0005817E119C0DF710D1C2F4BD0FD9D624EC8
+:1003000057BD71A50097DF56F8457ABAB6DA482F7F
+:100310004BD481E927BB40F8D162DFD6F8C885DD30
+:100320009F115D70FEDD388AE7A1CFCF813E98B77F
+:10033000EDC71ED7FDDB043BF8450968BFEE257A03
+:100340000F67317B34BE03C592A1AE215CC8E23D8C
+:1003500043713641C257D8CED21F80FE87CB3E6054
+:1003600077C0A712BE33CC82F57BFD7DD74CD7F783
+:100370008DBB89E2FCDF9E0D2082F9DE878965AAAC
+:1003800023F8E9329CC7B7B14D75753F5A8675752C
+:10039000DF8ED3DBCF7F4F89AA2BF87AC1AEEFA1D6
+:1003A0005C575DA05F613CB7CCA88E8AB14E92C706
+:1003B00012C6FD501E4F8C8227F90946F89AED7639
+:1003C00009F13719E9D1C8E7E6EFAE32E1A5BF750B
+:1003D0009BDF839FEA09467AFF5AC10075B1E6F7B1
+:1003E00013B04E22F1F3D71780E0A43CB4C4AC3E66
+:1003F000F48F5939A3EF593C9C8E50A2A0DEB3D79D
+:100400000FF111DCA01D877A20E8D6E3A734E93884
+:10041000A40309F38621D2DF309588650CF6D7EB6B
+:100420000C54F6997BF0720EE42F8D2357F23CF2B8
+:100430001B0A8BE0F7C63FB239908FFEF931D0AB83
+:1004400032EAEDAF682E689F5BCB280FE0F6A8D4A8
+:10045000864F459A61BE5E95B76B0046A8879D5E44
+:10046000639DEBEED247CA1CF0BCA582C7550F377F
+:1004700084DE588779DAE222928FEBB063D47CC3B2
+:100480007BE21C187751B5AFBBD04E7E77ADE4C090
+:100490006BB8A956C345BF91AA755A648C33A80C92
+:1004A000FD7AC7DAE69948BF6FD835DF30B8BE8726
+:1004B000715818BFAD49BB05FD1C459E539901728B
+:1004C000616B9B8DF613BD57FEFB34398AEF7E5B63
+:1004D000C0FD845777C77D1BE1D06A7145E2F06AA1
+:1004E00057B7DE9782DF73F81A618A6F343E948EB5
+:1004F000DF69BDB1D5B7079F373A7187296BDDE258
+:10050000AAC6715BD36FF2DE1435AE6BA4A31EEFE7
+:100510008747B450FE59ADF439E292705D1F257AD9
+:10052000E1FDB6B539C9488B2DA98E5175D8EFA616
+:100530003FFFBA00F12E5BF391F51CDE0E3BAE7B64
+:10054000B457D5300F7E214FDD87F4BA74CD7B339D
+:10055000A93EAE22E95EBC8EBEF0B53684FF1B22FA
+:10056000FE12495D4179D99695752E9CEFFCD4CC4D
+:10057000A6E8F84B4BF18DAEF1F05EA6D75ABB6AF8
+:10058000C8C5F4D182F19629382F58CF24ECF7A7AB
+:100590000615FA45D21DD5B1F663BD2BE0E76A5EBC
+:1005A00095897190962D2E4CC3B0168BBA19E39C89
+:1005B0005A4642CC7AF5097EFE5E8DEA99E99009A9
+:1005C0003FC46FBFDDFEFAF7B4B1684772FCB96C87
+:1005D000CC658FD27793F2CA4E1644F9CD177D378A
+:1005E000B585E47F8B85F3EF04FF1FBF87754FCF81
+:1005F000E605CE20FC5ADBD4CD082FA6B9D890D280
+:10060000FEF924721F1BC540FEB6343AAB63D59B7E
+:1006100045564AF3904F8083DE1B322A4ADE37D597
+:1006200065623C24D2780571776FFF2DAE77100F8D
+:10063000912D5949A8FF22E92B3233916E055D9A1D
+:10064000C7FFF7026E3FFE242760F5A35E9EC8F346
+:100650009BB30B02366AB30E2FDAB55F00BA1DE901
+:100660001FFE0FA55BD273EF6EFF1DD115F30C2E8D
+:10067000EF1810F2B6B1F43F29BEBBBE90E74DF4BF
+:1006800078A06EE7C68DFB7E08FDF140A19ED72ABB
+:10069000BEF7768C1FE979D3393C1EE881DF58F12B
+:1006A000C080291E18DF4F5C7F865FE83D61CFA6C2
+:1006B000C91D817294BB87241FFA0F98AEC079566A
+:1006C000052CC110E51FE25D34EF1211D714FED6E0
+:1006D0005231EF371B5C0CF3461B1DCA7E9C7FBB5F
+:1006E000C8FB5EB7FA817BD1EFC6B835CE7F1EE37B
+:1006F000761C2B8EF351BC05892095F5FA670BF01B
+:100700001EFAADD29CBC68BD083320BB653E33DA0F
+:10071000730B98C9CF5AC9ED30DDCF5A66B213CCEE
+:1007200076FE22D3F3BE7C0078174037E7FC391BF6
+:10073000B1B4ABC6BFEFDE480CB9734CE4E98E36FA
+:10074000286FA21EBA77D1CF5C48A7EB6D9D2ED43F
+:1007500027EBE7DC9E88F4B77EB9447C79A4A192AC
+:10076000FA1D6E08D0F55BFEA4DE785648CF33C084
+:100770003C5EC953EE423AD7EDB14573CADE5C1711
+:1007800085E70515B30DED4071D59BEBA2E3903ADB
+:10079000DD49AC3E561CED593FB7DB6D4097545FC9
+:1007A000283DEB1BA8EE06E8E85C349CD6FB8DE701
+:1007B00010BCEA9F3174203B465FAF0E271D0EFA36
+:1007C000F3FEE679A79FCBADBF749EC1CF394FF33F
+:1007D000FCF479F7D73F2071BD70A7BF6C39EE17D5
+:1007E00079254FED4479BAA832693FC61A8EDA38B6
+:1007F0001F1D5512695FFBFE89566ABBB378BED5D3
+:100800008C5777652DC9B54BE137BED8C2E3CCE034
+:100810003F29F0E72CB1BFBE7D2223FE6C2CFDF1F9
+:100820004B987FFE4D999D0939336F6E94BFB4D1BB
+:10083000D119BA338A4F81DFEE45BE75EB798780D7
+:10084000317F08FE8E217F6896336E53DEE1B00E55
+:10085000F77C80FB983EB8F7EFD7C4A60F407C1E0C
+:10086000E2DD0CA75B4DF031E72702BBAA8CCF0776
+:10087000E9D76C6DCBDD8F79350DECCB7100A7D747
+:10088000F011BC17AFFC94D220AE42CE37E3236701
+:1008900036A09EEC069580FA66E382DB3763FB3C6C
+:1008A000D80188DFFEF980FB6FCFE6291FFB63D4F8
+:1008B0000DE8D76EB417A6605E30B6BDD0BD72C667
+:1008C000DC98F6C282BACC3C9C5795D15EE8DE52E9
+:1008D000F9580EDE477B017EBA0BEB0CF602ABCC6F
+:1008E000B9047CB8FC8D1B971BB33E6F7E9E3AB457
+:1008F000306A3DEEAC7A165DC7F8C77CC55308EF89
+:1009000057F59E43C2BF07F6D83E7B8CBA45FD7BA8
+:1009100053FC7C3FBF7E8EC860CF13D1EBA7D7DBE3
+:10092000956AB4FBF4B897DE6F4A218F73B4652AD9
+:10093000ABF1394B987A89711BF5384756F665A2A9
+:100940005E5866BDFED17F5A647A1EC3FF639897D6
+:100950008C4F3BBBCF035D4EFAD55C8443C9D9A015
+:1009600086F910E71C0BD94FCE344676CE60FDAD2C
+:10097000C1F66B6BE2F2A775058F979765DBA81D33
+:10098000AF4A5B51FE4CBF30D4827223A04A4FE283
+:100990007CE3958F3E7C0AF535D801188709B07A3B
+:1009A000DA5F9D600F507CA27D0E8C9C8D71982625
+:1009B0007B26C5D3337E9AE8C5AF05DB305EEEF407
+:1009C000F17D50D57EED5E3C2F637EC9380B83E709
+:1009D000F3025CEF2FC6F80D8EBBE8EC6E8CFF5C6B
+:1009E000EBE7F20BFD38F4B396D4DD3DE961F92F66
+:1009F00089DB04DB9273299E2453FCC0141F7216FA
+:100A0000CFA2F8905E271128E6E7F7B0B4043A7F4A
+:100A1000C21CDF31C773CCF11E737CA7BE90EB7193
+:100A2000DDBEFA5AA1D1BEBA0BF71E0C47790B2ACC
+:100A30000AF8BADDCED23B2646C75FAC0CE32F776F
+:100A4000159AE28C83945B61902B2770217B5FB6B3
+:100A5000A3BFBB5CA9A5F89E99EE1F10F2ABB930FD
+:100A6000C150D7116E5823DE8FD310CFCBC73A8237
+:100A700071197DE30C963FB6E42BF717723F6323A1
+:100A80005E994FA57D04B30B3C06BA65F5C3D989C1
+:100A9000E8BCAEE9BBFA7CF4F13FEF3C3608780FD6
+:100AA000964F369616B91CF0FD4F00C7BC3E1A0C87
+:100AB000ECA8F8B41E3FD7DFABC1BC410EDA9316E9
+:100AC000CA1FE8F7A3E2D836A4DBF8345509C4906E
+:100AD00097E1C2DEB829E531F5EF308B4A72A14EBD
+:100AE000E46BF4F16CCCDB487C80B4ADCF4B8A1165
+:100AF00037673E97134866C50689613C2881291DE2
+:100B0000187F76B4D9A9CDB4EA0363A3EA871CC5DC
+:100B1000B30E609C4DE70B73DEC621A5CDC261EB21
+:100B20003A8CF92B737ECA6C57EBF1751B7C04E78A
+:100B3000F507C4075F6F501ADC7A9FA4F57C41D794
+:100B4000ABD3D59C9CAF7AB1FEA4254EDD5C0BF3F4
+:100B5000D21E7351FCC28D73439884E017E5E463A1
+:100B6000FEA750FE5E28E4E7D1B458783DCABED453
+:100B70003FA544EF5BB850C8EDE1A70A651E27B159
+:100B8000B110EE93621353882FF4FA93C3A9DCBE1D
+:100B90009C5F7263E87668FF2F51277955C9D37A35
+:100BA000BE7F48593EA3D20F6E0FF27AB4C357F6F8
+:100BB0009EA7B207FD4EBD5EF7AA4EA39F794D9644
+:100BC000DDD0BEC8CF34B5938ACC7564AA8BEAC891
+:100BD00052451D9998BF994F7ED8C0F31A3F16F51C
+:100BE000FECF8AFDB2FF5BD4ED758AFDB2CF89FDE1
+:100BF000B23ADCD7DB558A4F9F9A0D365D765F5C43
+:100C00007063E937BCC8C7938B2C7A7E660FEAA95C
+:100C1000BEFD15039F0BB6B0D29837BB3660CC9B98
+:100C20002DA936E6CDFE94A34C29C27CCBE4D54D4C
+:100C3000783E41D52689CE27D8F8F0271F3E85F685
+:100C400062313F7FC7FC9D2362FF85BE7F43BF5F4C
+:100C500056C4E9C3BD27D58E75F8559BAA66613C7D
+:100C60009D79A60ECA7E9B8D317858B7BBC963C7E4
+:100C70007320AA424B1D38CE8D9B619C84C18F731B
+:100C8000DFB8CB286EDD1BF7D7AEBC1EDF3FA2C797
+:100C9000FD59D6F565F0FC8888FB2FFBF984C7D099
+:100CA0003F7AAA50A94278FC5BA1B200AFCBC47CCA
+:100CB000A0BD28BA0D3F2F2519CF9D585634407C32
+:100CC0005D9A6189E93FAE2CE27216F4516D118E86
+:100CD000EBEA8D7BD5E178CCD541FBEBEE2EE2F251
+:100CE000A9F94DB61AC769FE395BFD5C0CBBFBD692
+:100CF000228B3EDE57693CAFAEDF02B7F0F18DE3E9
+:100D000049CEAA5108E753585F1663BCBB8B1CFA47
+:100D10007877D2FB69BDF3BB3B7A7E7DFB663C896D
+:100D2000C8B4EE1AD5DA03F4C31E96A82EDDDDE5AD
+:100D3000995B88ED5963A88EE548C5C0E76BFEBD99
+:100D4000F6D11CA9F8D9BFE43E9AE78A3206B58FDE
+:100D5000C6BD80A9B1F0FE7341977B8A73864606B3
+:100D6000C09363CDC130DA19BD6D9BCA30EFE7582F
+:100D7000F32ADD5F1F17A889B5CF392CE8B4A56227
+:100D800065005344ADE9B30CE736FC3E57DD57141C
+:100D9000E52F3BBCDC5FFA64ECB9BDA89A16545849
+:100DA0006C9614B2B77D16306D73D756495E993183
+:100DB0007FFD03332E87E78BD2C0BF8B5A77D1EAF2
+:100DC0009FEE057665C515479A53A0DFCE7C358C1E
+:100DD000E3977AE57DD85E14C8A67AF7F5498CECDE
+:100DE000BC53E31CE48F98E77D42CC1BE47293ED87
+:100DF00073C8E516939C6C4D1FDF84F31F5FCE22F2
+:100E0000286133BD67CB301F38294F3D817C96E97F
+:100E1000658A7332DD5758543EC73CAE6B1AD7B75C
+:100E2000E32369F7637CF9B0EEEF977E6E7FFF6C8A
+:100E3000D100FEFE29911F68FD8E33665EE4D4CAA0
+:100E400085B1F3030FD7AD40BE3FF51DA3BF7F6A49
+:100E50004B750DEEEF3B25F203A766D60D981FD01C
+:100E6000D70972C8310DE5506F7E40D8ED22CE3DD6
+:100E70003F4F89C3E7E0CFC74FCBA37DE86EBC32BD
+:100E8000CD733DED4366B1F7C7B2473D0AFA39FA73
+:100E90007EF6297E3505C7D1F7C98E47D1368CF647
+:100EA00075DF1A8B9E478BF9FDE579D3DEBCA695DD
+:100EB000F64F0F326E3FD87EB2BF93D7E3D8789DFE
+:100EC000615C6AB917F355E727BA48BFB7E1FFA2DB
+:100ED000F46A7A919A376D78F438A6F354E5C17DB7
+:100EE000375EF89BA8AF506F75335689F2E6DB4941
+:100EF000F514F79821E066BECE9A26F0CA3C290880
+:100F0000CFF4A2C04CC2E3F39D329DFB2AEEB3ACFA
+:100F1000C1F99FCF38026FD3BEFA7249E675798C5A
+:100F2000F8E28A2C0FE969DDFEAA9DC6E5A6934585
+:100F3000C63A609DCDCADE841CE8F7EEA3B66C7C91
+:100F4000ED0789CC8EF30E64819C8375947BD5D19B
+:100F500003C9473C89C88AFB1E58C862F5D2359937
+:100F60005F350BDEBF881F1F3D371CEDF11F3CC6F0
+:100F7000F355573CB6D2B5226AFC87A709B999C682
+:100F8000E75FA358827206CEE72CE5A5AA64AB4FB3
+:100F90006198473E7F6C09C609C17E1B47ED4FA88B
+:100FA0001D96AD3998E77ED7FBF131EC7FC5376FE1
+:100FB000BC8CE85FC0E386B539CF909D9FA7DE81EA
+:100FC000F80F177F92386622D9F19B91FE6FB0B06F
+:100FD000402C3B6683C0DBD54AFD754867572B4ED6
+:100FE00086FBD5C2654E82FB0F4A2C32DA95F3910F
+:100FF000E6319EF3A88DE2CD008F9BF1F9219F9BF6
+:10100000CE892E577E6AC3F69F2659D8E503E8E3BA
+:10101000CF0DD7E24F86233FBE8BF41763FEB56238
+:10102000FE3A3F01DCCB695E0AAF1FE98FAEFE5886
+:10103000A87C17E1D496A9AEA6F3103D0B06751E49
+:10104000E2FC1F06A976CFF9FDFA112C46FDD76107
+:10105000C127E6FB3F9CC6FD821BA7F17ACB2B1E66
+:101060003B776836F2F55ABB07F1FA5461E0C7D313
+:10107000A2FDAEBFB21C99292D27FC85E7C0DCF983
+:1010800041A089D89E37D646F8D3CAC5F91E773114
+:101090004F7312BD456DD75A0BF1993BA1A31A8D21
+:1010A000665B61FDB16BF1BD3289F6F347ED7319F3
+:1010B000B08E2C22F2592DB8EF0C6CF9F03A493F62
+:1010C0006F8B5940B6852B6CC2BEFFE031652CF0AA
+:1010D000BDA8CF3CFEA2F571AC6B3966E5EDF08B97
+:1010E000D6514D400791517C1EED0F587C8D325EDC
+:1010F0009FDC8C7906758DC55709ED9AD03D5E0C45
+:1011000071AD58E764E82ABC77EF15642F7EE2657D
+:1011100074AEEC9254CE37756116B466F4F9B7EF3D
+:10112000A4B3A09E3FC5FD737EA1671EC4FD6B30B6
+:10113000EF2F6DF8BA7637BC1700BF17E36AC37C90
+:101140003CBF191FB6F9820CFD5D5E1FD9D26861E4
+:101150000FE238D28666F4CF9D22FF11AFD492FF02
+:10116000380CE853C68879C466D8BFA63295E837EC
+:10117000B91238231BAF46FF38F712FBD8965C3FF5
+:101180003C09F9E5DC34A35FDC5F7C5DBFE2393705
+:10119000889F2E916FDD01763BAEF7E760B7E37570
+:1011A00017D8ED781FCFA5C62BEE63C3EB1EB0DBBF
+:1011B000F18AFBD8F08AFBD8F08AFBD8F03DDCC777
+:1011C0008657DCC746FB0E4BB4D050844F593CC306
+:1011D000FC508B9DD39996EEA03AF75009A37C7EE4
+:1011E00038DDB1B509E375168E272D893F0F27AA83
+:1011F0005FA176C64499D7C5B351B87F709D65A2EB
+:101200008CF6539B43A63AFC534D36DA9F7062AE80
+:10121000E56DCCBB308BD527817DF3CBCF6E25F828
+:10122000D72ACC8AF2A109CF0B4579FC2113E71705
+:1012300084253C57AE3991097ABC2EA880CC7E1FFC
+:10124000BF45F47A4045BF78BA536FEF55F179ED59
+:101250001A8BE8FFAB20D26FABDE5F3BF404FAAF32
+:10126000EB4CED6EABFEFE686A1FEBFDDEC81A05A7
+:10127000E93D537F9E7A03B62371FAFB7FBC01FBE5
+:10128000135CA8EEEDD413389F13E97A7FB986DAA0
+:10129000BD7573D7ABD8FFC470DE7FCB9E834F6222
+:1012A0009DC95F7BBC6655A338BEB688B1A7932E97
+:1012B000A6AF77A74BC678A86231C443F5F8BBD573
+:1012C000BDFC72DA7FD6E424B91849F7D5A0DEEE6A
+:1012D0002F2E1A15AFA7B8E88FA6EBF5CCA6F827E6
+:1012E00070168E5B8DF1401F7D558DDE9FC62CF5EF
+:1012F00021AC530F9C4994D18E74A445C5EF840C46
+:1013000018285ED85CCFE38361D54EE777E875FD9A
+:101310008E6251D72FE2857A5D83A3F86143DEC0E8
+:101320001C2F64D2CD948F0EAC34C603E7AB9F2F35
+:101330005EB89C85EC9723FD2B16AA8B58EE91DFA7
+:10134000B90CED6836819FCB28BF14ECADEB9769E3
+:101350001819CF9BAA16EDF65BDE7B1BFB079BE201
+:1013600064DC84BFECE6B2772E23D32D81617C6BE5
+:1013700059093F9731EF43DF4B32CA53AFD5C7CD41
+:10138000B4C03751FE06562651DEE4FA3B2CF4DD9C
+:101390005ACDCD104E60570A7AEF7A1CE94B725B3A
+:1013A0000CEDDC513ABD5DFB38D2FFF464BD1DFF8E
+:1013B00004F25B99437F3F8FDA4B558B789EF5841F
+:1013C00002AAE458B94EDF2FD7E0F36BC7F48E477B
+:1013D000F43DDDADB7AFB9019FB7F58E5747DFFBE1
+:1013E0000D9E6844ED194F203F9755097DA5BDF727
+:1013F000388EDFB25C1F7F7C10EB509759F5F759A0
+:1014000010C7AF63BD6D05F5E25B82FFBB8B3B6B25
+:10141000305E755DEFF34E5AEF72D17EBD587D029E
+:10142000F9E95F7E7D7FE7EF99DBD7B3F0CCCB7333
+:10143000FBF8C22CAF7E55CAE5887FF54F91CCD919
+:10144000F2FA27E95C378C07F07C56EAA200D2B7A3
+:101450004BF20167B08037302B565DFCCA123ECE8E
+:10146000E962635EACC594170B88FC547FE31C2AC9
+:10147000E5719DB6F2D87EECA4BCF28F8A319EC095
+:10148000CE4A389E470550823DDB98A3FE19EF03F4
+:10149000EB56903DC7980FEF835FACA19D390FC00D
+:1014A0008979D8C6D247284E7FA2D06E380744CF5C
+:1014B000736E7428241FDFC3BA0E908FCBCA959920
+:1014C00058CF78E308896DA57AB204CA37D8463A6E
+:1014D0009E24B92EF29EFA391CF32EB12FC2BC2FD6
+:1014E000E58F62BD9F14B7DB513E6B4C9B59914B0E
+:1014F000F23A8CF5C756F706CA033B4BED9447D03A
+:10150000F3CF75E2DC6F3DEF3BFDC250AEDFB3F4CD
+:10151000B8EEC0F9DFBA35BB03641F7448CC9A71CA
+:10152000713EB836A0A5DF85F66F4522ED17A85E9F
+:10153000F1328D7F6414A3F87BFCA27ADA1F640376
+:10154000FB50C17A17912FD6F7798FBEF035DA3775
+:10155000AAEAF5E7D29C2128279DADE067D1801C3F
+:101560002E7ABEB8CA24EF6B8BF939730CECF87184
+:1015700049F89D81F73DDF3F9D9FEF77B283D7F319
+:10158000179418F3C7EBED3CCED79669A4ABEF4F99
+:10159000E7FEEA83D3453CB1F4C7D508974F98D509
+:1015A000877931F6283F0F0E632CB4DFCA7C0E73A7
+:1015B000D662B2EB1E1D0D4B045BDBB6E62D8A2B0B
+:1015C0005A36F3F73E9CCCEAD16FB1D9781B2E1A6C
+:1015D000E6FFA7F8D53925583FB6E61DEADFACF19E
+:1015E000FAEFFEE237D525BABEE7F19B65DE033D93
+:1015F000B8AFECBF1CC731ED7B0DC8BCBE645DB19C
+:10160000ACDB17741E2110AE1DEDC5F4A2C00A9C00
+:10161000379BD829E33C7479132AFD6A0DCA1BA6AF
+:10162000C4CE4BEB7CDF62CA4B07BCFCFD43BFB8AA
+:10163000AB06FF3D88FEF2109BCA7AF306B795E031
+:10164000BC52F4BC81723BB6FBF4282CC86FD0A30B
+:1016500037ACFE6FA0477BED76ED580DCAD52FDA7B
+:10166000FC81AEFE9DE8AA92C7CFBE68F32F9AA672
+:10167000ECC3F9FFADBF73D5B4C06BF89DFB2C4A2A
+:1016800075024FEEF92CC63C5F4FC90079BE4BC5C1
+:101690001FFE27DE3070BCC15AFACF196FB0E39E2F
+:1016A000AA3CE2A3CB4A918F8A391FFDABCB3D58B0
+:1016B0006F6E29F14367307ECC5FDFDF4F2F52CB57
+:1016C0004B490FAAD63D403FF795B9B83D13E2F01C
+:1016D000ED8B67C0FCFD8678C613ABFF06F10C5896
+:1016E000EF02C26F85F8FE171F7F37137C156E4F10
+:1016F000FC0BD2671BADAF93AFEF1FF0FDCD442FB6
+:10170000CF727AE9830FB793A2E073C3EA7F0C7CB0
+:101710009E25F8ECE0F3FB02E0730FC1D3C7E77B33
+:1017200029FFFAAD629E0F81F75EA675E6723A78E0
+:101730005BD8D7E077CFB85CEEF3BBB7E42BBF2E16
+:10174000E579E4C3A586FA4F258CED01FCE2EED2E3
+:10175000D87EF19B38DF2F9A5FEC2EE170EBCBBB8C
+:1017600004F979B7ACFAEA2BE13BEF00BC31DED6E5
+:10177000BE4622FBE27C1AA3F300747BE34412AF63
+:10178000DFBB787F584508E7ED2CE4E78CE8E703FA
+:10179000D8A4E54343F2C5707D7588ECC07D482B25
+:1017A000144B0B9E133843FB88F69F391427FD3BDF
+:1017B0005BA3BD3EFB1DE847839FFB25ACBF5CEDF3
+:1017C000A1FD27FA3E337DFFC78A50EA01DC77DBB3
+:1017D0000EF4900ADF995F61DC0F62B6376CA6B633
+:1017E000F9DF314D9E6E3C8F0AE04FF6CFF9365E41
+:1017F0001FD76E637BB0FE43DD2005C164624F6B73
+:10180000163A877325C0C90AED191D19544FEE48C1
+:10181000E3E79DE9FFCE29D041079DE7744C62784C
+:101820009F897D65FAF9DE7173F9B97A11583F9E87
+:10183000DFA39F335125E8448767DCFDC90497F394
+:1018400000178671663FB747E7ADE1F9E096E537E7
+:1018500086918D6A8A3F5A17AB2E65B1D7784EBAFA
+:10186000399E613E67DCC60243F1FC8AF9C5651A00
+:10187000DAAB4E51AF19CF143AD722A23DC5CFB53E
+:10188000A8B01BCE11317F37DE44A74E53DCC14CCC
+:10189000A766BCCC32E1E5691B3FC7B1A55BF26925
+:1018A00070BB65D3CA36DCA7AF6DB2F2BA79A6D0E9
+:1018B000B94F2D60F1D27E74982CC6EB970878EA68
+:1018C00078C183BCEE49413921F6A55BEBEFC5FD3C
+:1018D000A54BC5BEF4EB5827ED33B89E45ECE80C9C
+:1018E000DC80217209E3DDB2833B071E86F3A8ABDF
+:1018F000E6E76458710D9827D864257E6DF1EEA156
+:101900007FEF2B34C29E743A8BFB13B1ECD9DEB857
+:101910000240E274541CFF7FE257FFB5F8555E09A0
+:101920003F8FAA252EE429CCE0E74DE03E87BC128C
+:10193000599C37218FEA003E397CDF071ACA617D46
+:10194000BF03FCACBDCC788EC2E6E903F87FC525A9
+:101950008C7F2723928E7595EF8873FBCCF8FD253D
+:101960003A0E5C0F3D399DF2EF60FFE6A2DCE3F634
+:10197000EFEC82C053D3A91E9DEF7BD6E34827FD31
+:10198000EA0FF17E09FEBB39B9B43F2788FB77E641
+:101990002758F65BE4BEEF33731DFB7FD3BCD5ED58
+:1019A000C51C1EE1385EDF1ACE60D5CFC5C0C74367
+:1019B000E55C1F86B363E34B7F0E76C6EB882FF49E
+:1019C000878670A238E330C6078E0F441F3A1E93F5
+:1019D000672AEF10DEF57AF002F524B69BD5C0DB5E
+:1019E000747EDB06496E44FD1A925FC5FDF5F3BEB9
+:1019F0002579108E7FEB3CDCBAE28C41E5E1962143
+:101A00009DE5F52FBFFED2EBFF0742E7FBCB008041
+:101A1000000000001F8B080000000000000BED7D9F
+:101A20000B7855D595F03EF79CFBC8931B08F42224
+:101A3000014F0268D4602FEF04089E9B9B272470FF
+:101A400041C0280F4F08626CD1466514289D9C90B8
+:101A5000104244C119ABAD75F4120CFE7FC7AFA69E
+:101A6000FDAD15E9E38268A9851A6DA8B1551A90F4
+:101A70005AFA8F9DC10A63EBE8386BADBDCFBDE765
+:101A8000DCDCCBCBD8A1DF4CF8F4649FFD5A7BEDB6
+:101A9000B5D65EAF7D72D4C9189B01FF1993EBB424
+:101AA00002C63AB07C19C31F8D4179E9504B390702
+:101AB0009AF6F2F65768FF1636C63156CF447FD1F4
+:101AC000FE37126F7F34302C6CA4337693A887B224
+:101AD0008E65B33F634A6E4081FE0D9259DEA9299F
+:101AE000D6F932776A30DF09A77DFC6562BC42ED2A
+:101AF000131A3F149DFF93B006E5FE38F897335E46
+:101B00002ED5FE42EDEB9859FF171DD77B5C32CBEB
+:101B1000E375EC7FC46596C7D6E1FC0FE4F2F1678C
+:101B2000978C0F1B97203C9FF7F817DAFEED592A88
+:101B300063C3011F0DDF0D7E017E5DD6B853D6A1B4
+:101B4000DF5167E86D960D64F6A0A476419F42D6FA
+:101B50002D3399C076C95360084D621D30D7AA1243
+:101B6000F8DF54C063BA83CF63F8C31AD0D9D2D98F
+:101B7000269DD68671DE6474F79B7D773C8EEB8E56
+:101B8000C26DDCB1C206B731BE4E9B15833BB81F98
+:101B9000DAC3784BEFB8CD87702ECD33D73783E6D5
+:101BA00069CB32FBF59F75DE57F79512BE9746E776
+:101BB000A9A2F64B53CDF1168471DE183E97D07E64
+:101BC000C4E01A6DC3A7BF6409E133E40D6F1E01C1
+:101BD000F809F998DF007CDED4D02CEB05163E32F4
+:101BE000822AF1912F5A0EDBF9A880F868B0E11A29
+:101BF0003D23B455837D62F9DD6A68C2E7B1EE88A2
+:101C0000F30BB8EE6D12ADDBA4A3655E0BBD7B607C
+:101C1000DDAA59BEB2AE217D30E6ED29A379DF03FE
+:101C20007CB3183F3163649D967EE1E3B5A4E7B9C8
+:101C300070BF566A921686FE9FE2CF75B1E7DBB39E
+:101C400024E217C0E7FF237C16023E33F03D233E1B
+:101C5000786672E8071AD4335577EC07B85C9A8730
+:101C600075000EAAA687F6507BB6C387F8070068F2
+:101C70009CB6D798827C06BCE577CC84B293D576A7
+:101C8000170C9CF7E11207B56F61ACB21BE09AB27A
+:101C900029B43A6469E72DE370658AE7918CFEE523
+:101CA000C361FE77A06A138CDFB20D98179EC71A26
+:101CB000A4B0044D8EE578E715427D4FAEC3BF0951
+:101CC000A6EF59EF1EBD16CA7DB9E97E84AE2F6B13
+:101CD000478617E639E697059DDE761CF9FA4846F1
+:101CE000949F0C3C5F7A245EFE9556D489FCF4A642
+:101CF000CACBDF2AFDF271A300E98D79D908C003B0
+:101D0000F6005E75A4CDF2B8010E57398813ECEBDE
+:101D100065BA0BEADD580F4B5CB079D7D7AFA7D1C6
+:101D20006B5F1E378DB15AFC5DC5FE8AD1EFA1797C
+:101D3000954F257A32E7B4D8B8AED696975A108F19
+:101D40003E9995206FF9787B1FEB6FFED481E343BA
+:101D5000399F2109EEFB14F65C1265FCF914969884
+:101D6000CE4295B908573EF377C07C0B74E789687B
+:101D70003D7F6C53A60938111E79636521FC9ADA00
+:101D8000606F37371FCA9E58794E6B7D0903BCCEF2
+:101D9000D1A0DB44C60EB5D647EA619E43856EAF3F
+:101DA000049876E528B6F67359772BE29DA9070FBC
+:101DB000C880971562BE16EF82B7719C95F95002E4
+:101DC000F88F7C359031351BF94DF63B441B8789E4
+:101DD0000F46ED9C8E6C92D37EDCEF9617CC7D9BEC
+:101DE000DE897C20A749B672C065D64FE8443E3CE8
+:101DF0001295ABE3566279F158936F323A91AFAED8
+:101E00004B33CBAE95C847EF284E4127C33B914E8D
+:101E1000DACDF18CED245FDE6066BD83EA4351F9D3
+:101E200057BE13CB4BBC021EE31F481EB668FC3CDA
+:101E3000B96A5FA4DFB888F6C09F570690DF425C9E
+:101E4000DEC5D7CFE80DB76422BD007EC6AB03F96F
+:101E50006D4340263E0A69EFCBC837A58D8033D845
+:101E6000BF60ADD43B15695C61A391EFDB9A60ED77
+:101E7000E3A1FC62914BCD40B91E2AD712C88D1F39
+:101E80000438FFCE08A467BF8BB89BCC2623DDB5F2
+:101E900035AD13FD530CDCDFFA71AE704A6EF27192
+:101EA0005E0D3A48CEF448DE45FC7C96199ECF8103
+:101EB00007C7A617B158BBA783FC5C6E9EAC550440
+:101EC00060DE79207E19EC61F3EC47432530CF8941
+:101ED00022A7DF8DEB30B4D791CF160A1ADAEED2F3
+:101EE000D87A941B456EEF2694DD72C14BEBA0AC03
+:101EF0008C027EC57225A76F1DFE7D9A87E32A316D
+:101F0000FA073816ACB3F383C22CF40DF53705325B
+:101F1000B2DFBD060A57B3AB71FDF739432B508EC4
+:101F2000B5E785EEB0CAB3A7825C8E85C57AF7CFD8
+:101F3000FE762DE2E703E6F0A3FCD89D1A2279F69F
+:101F4000BB4CC63A27E23E32D53B02F99AAF43CAB0
+:101F50005FC2B0FD6397C31246021CEB7ED3533AB7
+:101F600019DE7F83F73B792D6B64F85EE1657818A5
+:101F7000C6446C7794DADD1BC8A379D9E37E8F075A
+:101F8000691F9AE37EA7B36E273E1D693F1CAD27EC
+:101F900090D3E693AD71BE17C503F2129C84B86E60
+:101FA00089E98E4F71FD42FE039D6EC4FD01A94F6C
+:101FB000E7C88C93A76CF43629A0121CF17407FDB6
+:101FC0005AA8DF22B31F73EA167D7D43E09170F3B8
+:101FD000383A8FB652BB74388FB26DE7D17D810429
+:101FE000E7D19555DAFDFC3D2F43FF0793F4FFC77A
+:101FF00044FDA1FDC3F4DEA313BEAAA66B8F6079D6
+:10200000CA18539E4043109CD70D33CBA93737E4F1
+:1020100058E5CFD427505EDCA84BA23EFF09E4EF81
+:102020002325A6BCF9D90AAC8FCA23B6F809945F58
+:102030005179C4E6DE8CF551F9C3EA1F47F91595CD
+:102040003F2CF804CA8FC002598C77EC711CBF6D0D
+:102050009939FE15E100EA250EB33F0BE3F8C9F408
+:10206000C8DE59DD2BF09CBB295ADFFDB866B133C1
+:102070007E354B7F02CF45B66D387BC7E483BC818C
+:10208000FC6ECA01937E4CFDF0D517C3BA01ED1664
+:10209000566A11EBBE44F5CC7EAEF7C4F4CBDF73C9
+:1020A000FD7BF0F5C7D768FE024E6F9FC3F86F5BEC
+:1020B000C737F52978DF4FF427DE5F6AF61CC07753
+:1020C0009AE09BC2E1BB88FE1FD3BAFDFC9CFA2BB1
+:1020D000C09B5A62B1032E417C8EB9C4E19B5482ED
+:1020E000FB5DCDF7FB698D99727C2AC13D800ECED8
+:1020F0009BFE8B69DC52BE6ECBB89A75BE64F63A15
+:10210000B42BB3B78BF24F25C125C63D4BFF1A7BCD
+:10211000BB68FF5089853E0781CF6FB2EEEFE720A5
+:102120004756D3F8E3F8F8D7C7F0789BF5FDFFFAE8
+:10213000CDCE49E7DB899E1A393D9D87BEFD75C42A
+:10214000EF56A95BCF243F9161E2FD1B380EBCEF37
+:1021500077C1FB88D88F5D45A16FE17B2CFA2659AA
+:10216000EC1363E14E842F669FC04005D6F3FE86D4
+:102170009DD6F3FE7B2537ED34804EE4206FFFD4EF
+:10218000FE97EB70FDF165D04BFE2FED7F36E82515
+:1021900013482FF936CE7FAE7101FE6EC2C3F39C99
+:1021A0006E12D43F4BE33ECDEBDB5D5C8F7D63D99C
+:1021B00007A4C76977AA0ED4E3CC73FD27255C9FDB
+:1021C000057DA432917FE127C29F06E3FE84E6ED00
+:1021D000E6F8EF0DC919A86F46F51616213B28A69B
+:1021E00057AD223A8AE955B75279B6D8E7D74BBEF0
+:1021F0005427E07D85E341ACE7DCED7B080E1F6FE3
+:102200009FA0BE97C6CBE170B2F48327D06E257A2B
+:10221000E53FE31C505E89BFA900BF73717136E8CA
+:102220002DFB5B255586725DBBB9CF77135FC4F478
+:1022300036CE87370ABAFF53C906DAC71B4F9BFC55
+:10224000BF97DA4F89DAA91B08FE37857FE26BC199
+:102250000D267C27093E95C3F7398C7F9AF0C33849
+:102260007E6A99E144BD0CEDCA2E36707F3F167E22
+:102270001CE8F71FD4CFC3E1AAD525D2DF43AB8E2C
+:102280003991DE57F4B284FE2739E832FBCB41D2D4
+:10229000CB857DEBE77EA1F8F629C1283DA5507BD3
+:1022A0002F9FEFAB45A1B420BC9FA5BF161CC1F763
+:1022B000C983FA68A8540A77E4A27D935E560AE5BA
+:1022C000050ED64F761F639BD1EFEBFEA1C23AFC01
+:1022D000D45A552C7E1DE0D25FA11DB9586CFA026C
+:1022E00016F5AF38D05F63F1DF901DE80EDE9BFF7F
+:1022F000904A7E97975AD04FE693C9AE08DCBF2A22
+:10230000520FE5D442B7D78DF3C83964E7BAEE036C
+:10231000FB1365D4226E5F3AE01FEAD1A9EB18D90E
+:102320006FF30C29ACC23C6ECDEE7FD1379E6A2193
+:10233000FB6E15F36A59F02CB4D7BBE2ECD7E6C9B3
+:10234000BA1FF174BCBDDE81F80854713BEC78FB18
+:10235000D874E4BF783BFA78723BDA40BBB92766A1
+:10236000473BD70EA21D1D0CDAEDE8D145A132DCAA
+:102370004FA66824DFF6CF9EB190EC6543666E6889
+:10238000DFFF909289FE3E639BE24777C331A7B699
+:1023900082FC07604FCB63689B18FAB7E60BF8FB2B
+:1023A0008B4E9522FCDADD63FC48EFFDCD6EC273E7
+:1023B000FF2D59E134182FD3F8B03505EA5F0E8FA1
+:1023C00042275BD4BE8EB7C3C17C32906EFAD96807
+:1023D000D681FBA078D97A7C3666FA0D7FCCDE9E5A
+:1023E0009FEF3570BCFA701AC37D8FFC8C49EFE605
+:1023F000330A39201D2F60AA130BD733CD89F85F1C
+:10240000CC742ADF00FC268DC5F9F20DA203E03B57
+:10241000F4DF6D98ACDF46F8788CD3077B40D98920
+:10242000F18AFE6D0F66209FED4EB5FB1BCCE75A7F
+:10243000E16FF0A09D3F6150EDFCF5048F9013E734
+:1024400021579AF87E727E3D8DF6EF703A271B90E9
+:10245000CF7B841FF8812CEE3F7928C8E54AFC1316
+:10246000183E1BFB5FE83901E7E5F6A0DD8EDF8152
+:10247000E5F3382F1F2639F32C5F675B9099F2E75D
+:102480009B41AE07A899E44F01513C8DEF2FFE7C94
+:1024900024E94FE0F8DAD312ED578ACA480EB95949
+:1024A00028C289C910EB611B47D8FBED3E5BBF9B7F
+:1024B000037CFE1385FA3FE3FCC5A78042A19DBBC8
+:1024C0005A0A4BD06E7EBAF492A4C6DA1D413F542C
+:1024D00002397A54C85168167180BEB23D13F600B5
+:1024E000FDDB8A7F08CAEB379AB4A3A8C31D69AA8B
+:1024F000A4679FD248F2A3AF5D0E37C33CBF6862AA
+:102500003DA5E3078E5BBB2C70F484451ECD2F7B6D
+:10251000D2034291B5E4771E94D05FAFB955E4DFA2
+:102520009E0CEF0385C8AFAFC9AC0BE05DB2A8EA63
+:10253000E8098B7C881F17E66306B0EC1B41EEC7E9
+:102540007C31E08E5C07F0ACDA268571BC55DB8E01
+:1025500039D15FB9625D1DD3619F5C85C714DCCF43
+:10256000F28097D639BF50668605AE6F4ED37A8219
+:10257000DCBFF33AEDAF3FAA47FD12CB01A796E9C6
+:102580002D88F921CDB8C0D3C15DA48FF664319AEE
+:102590003FE463848FA096EBEAC7388BCF4B7ED3A2
+:1025A000434195E6AD6BDD49F0A4CE7A9FE001DDB5
+:1025B00039E2183A10DF261FBC26F0DE26F09E0C0A
+:1025C000CF7F0A727F9E599E5FA664209E5F5754FC
+:1025D0008A7324E3EF85A5F6FD71FB2A6DE516ED00
+:1025E0006E07D2D3F15639EC96E87918F7ED34EC52
+:1025F0001BFAE9CD717A3258ADF57C36F76756A9EA
+:102600004C7099FBB3C2E0FBB3C208105E569456FF
+:10261000B946F2B85A37D036AB2FAC6388179776E5
+:102620004C4139966CBF80DFDCA516FDF122FCE73A
+:10263000434A2D7AEDE7EDDF87F946D37C717AF6D0
+:102640005F2BBE60D2532FCAD582985C2D2BE5E755
+:1026500041FCD394AB167D92FC9A163856365C0436
+:102660001C269F209F3643D3E00EC9897C12427EF0
+:102670009D80FAD91F367F211BF98675A7C0308E41
+:1026800052CE37AE59592EA48BBAF6F7153CAF008F
+:102690009F15844F2187279632F31C9A4374D1C02B
+:1026A000E9E2BF3BAE03F02C23389771382FB5B861
+:1026B000D3ED35A146842FA4815C4A477FBC57ECFB
+:1026C0003F1BCDFDDE1716DF3CD67A37433D70C188
+:1026D0001F3354D4036F2AEAD272D584F14D55B218
+:1026E000C537EB4B488FD1182B19C9CE19DF8C8F0A
+:1026F0009F0E8C771A142F35F5EEF878677C5C9373
+:1027000025897F0E8C77BE588D7AE61CBFEC55D597
+:10271000583CD335EBDDB7D8B503E39D9FC07A04B1
+:102720003EB39965BD7DA3D5EE08C0D731D2E3EFA6
+:10273000E4CD993C2D864738073C6E98A7B50CE050
+:10274000477D39B793E2C6163CBA080F1788478A07
+:102750006F235E5AA5F026DC07A5D140795EC7BC81
+:10276000EAA3DED87E46C7CBBF47F341FD57EBD384
+:10277000990310B239FB2E5607E5D443294C063D88
+:10278000F6907A17EDF7A1F732548CF7BA7D967D63
+:1027900010B8544CF8E48176D25F611F3D7989F618
+:1027A00051ED2CC573F67CF76F5751E808CA150F29
+:1027B0009CD7CAA4D8FBBED11C9FEF5CC5C29DD2DA
+:1027C000C07D047C6B6477E6B39D846FD6C8D03F30
+:1027D000D02A31F551FF40BA70A46D341C682FAE79
+:1027E0004C273BAAA5B191F0FD1AE0DBF072FEC2C6
+:1027F00038D559F8CBA40B268D387FBA88DF778C73
+:10280000E3AFCBBEA4F735097FEEBAA07D9D3B5365
+:102810001B5236DCBACF5A56D9542BDF1A222FC599
+:10282000A07D341631D69535508FBA4CE4A5C078CA
+:1028300023B1FFA83226FC80DA282C5F7F396B4C4D
+:1028400094F7E2ACE076CC3250C1C9AF62A4B2AE2C
+:10285000296865ED787B04EE9771958A65A61E0C54
+:10286000235DD589F51FD9B2B30FDBCF074C621EAC
+:1028700004BE7558F0E32FCBA5718BD61C3BAC5230
+:10288000B5F7288EE702E18F76EA327C89E382BED3
+:102890008AF175A6E86C21C8FBE56BA5B771DC5A17
+:1028A000238DA15D1BCBAB782A2EAF8297E7E788FB
+:1028B0007AE3FB74FEC4E298FBE2CEB7373A6D715F
+:1028C0004CE3D84A7B1C93E7DB98E7D99197FE65E8
+:1028D000A5A158E398EFD3F8479799F315EEB2C73F
+:1028E000313FA1F14D3F35631F765AE3946049D1E2
+:1028F000F96AFA91FF5C36BD9EFB4DF585B83F72D3
+:10290000506A44FD080E184D227F8DB713ED69D033
+:10291000FFAFC7FABFF575821E727B9925FEF1B72E
+:1029200006FF31D3BF6F1C5AA9155CFAF002BEBF77
+:1029300045F8AEE4F8FE1B80F7BB6509E20097108E
+:102940007C2F117CD138C47F3B3C6F9459ECCFCFA6
+:102950007BBE1933B51338DFE7B08E536596FC8321
+:10296000F368FFEFD45EC44BE3EB6F2FF7723F9633
+:102970008813BF198DE365D6C7C5F528EE158B23DF
+:102980005E3E3630CE0AFFE5BBB0BD19479C5D9E6A
+:102990005B4F79D149E2981AD62BD6FE2AF5EF88FB
+:1029A0009BCF25EA17955F536FD8F07335B5EF8944
+:1029B0006B5F2BD6B7B27CD22EC3820FB038A97D05
+:1029C000542EB1E9F5F6B8E3D47A6BDC714DF9F425
+:1029D0005D66FCBF1CF1336E403EC4FF487C04CAF8
+:1029E00085BD29E2E5261D8E9EA195944FBDF4E09C
+:1029F00085FD5B526EA1FFBFC27CABCA2D79171754
+:102A0000DA3FCA8FE2DC37F32700BF77E03A6EAFD8
+:102A10005009FFF1F912A69D18EA676427CE646198
+:102A200019E31221BFCED00F1AE56B43AB277F5DB0
+:102A3000F47E44E52EFBFD88E65DA85FC4CEEFE79B
+:102A4000EAED790EE536B8B7BFFC9CB9EE96724B4D
+:102A50003EC3608FBFA6C28E976859E067E91DDF4D
+:102A60001C6DBF7F11DA45718CE8FD8B9B68DE58C9
+:102A70007EC7ADBBECF91D6BA91CDBAFA6B8FDFA98
+:102A80009A0DAE8FCB9B082E97C87B73AD9292DCCC
+:102A9000AFB891E48219D785B24D2E50F97380EB0F
+:102AA000804947824FA3700EC8CFABDB857EA6C19D
+:102AB0009EDF22175E42BA187CBCF3FB1D26DE9314
+:102AC000DDEFB85135CB5FA96F28F8ECF362FE5FFC
+:102AD00079C2FCA38B5D07BF2FE28ABF2FC2D6D776
+:102AE000DBE5CF79C3773AB1FC39BFFE9F24973F2E
+:102AF000FF89F2A725DDE1423CEB3EA68513D8C74E
+:102B0000B757F0B854943FC57D94EBB727B6A7BF2D
+:102B10005CC1FDD7A6BF3BE03AB5CA1A071D26EA3D
+:102B2000BD15D1BC016F058EBB8EC33706E521C62E
+:102B30007B98C234E0A945D78FCE41F85A7ECDC7E5
+:102B4000633EB0933362E3CD14E399F3EC5B9051B1
+:102B50006BCD6BC811F38CA9904CFFF4980AC4E7B5
+:102B600046BE0E79C81ABAE715B5AB8D87487EB553
+:102B7000394D3BFBB15D24CFA272E89B44178BDD3E
+:102B800026FD877759FDC6653FDDC5CF5528621CF8
+:102B90002FD6EF1BF564E79DA3DF6413CFAD62BFB3
+:102BA0008CE87E4D41B8CFD5DF624747A4EC981D35
+:102BB000FDCC646D16E219ECE9E2F31907F014A4F8
+:102BC0007D596BB7472CF51515B6BCA4536B30AEC9
+:102BD000992C2F6961C5D9F39216C6E86161854DBC
+:102BE000AF0F664C453FC94847C27B14BAD8D75887
+:102BF0007ED77768BFDA4CBE13E507B278FDF29F47
+:102C00003E532FE0BFB9C212BF30E32DACE06004E9
+:102C1000FD3C96FC22CD61F5FB048F3971BC15ADEE
+:102C2000D2F9F14BBB187F5B741F6FAFE0FE681DDC
+:102C3000FD8E378A498EDCDA4CE3D6AEE2F7C2E28B
+:102C4000F9E65EE1A7BA3746C7F7D2385A34DF66ED
+:102C50003DE20D5306DC9362E39BF77B02CED08FFF
+:102C600030AED366482ACA577D5D1DC51559256308
+:102C7000E3619F0223F3B6A1E830E7BBBC92EF17F4
+:102C8000FC5A8AED7C20218D9198275E4771E76977
+:102C90001ACF5B995EDD2C0F5729AFA503E72F5A9A
+:102CA000B4B305977DC3B2EFCA89F2597A309F0554
+:102CB0006132D8EBE346007F0BF8F05EC85A98E724
+:102CC000CD683E4B75D93DD67C96D067CB6731FD3C
+:102CD0007F4B4B00AF16FACBAAE478CDAAE4788DEF
+:102CE000C58119C56FAF60B573AEC2BC14BCB70562
+:102CF000AF7B0C7ECFED4C0E0B63FCBF79762AF9CF
+:102D0000F1FAB318C5556143326BA6611E09FF493C
+:102D1000195FCA30CFC50DEBC275605C3672250CE9
+:102D20002F2F1B124940CFBFC8D4993F1DFDFEC6AF
+:102D300066067413D41FA4F8DCE5ABDE6FC07957C8
+:102D4000E86E1549E0C6066F19E571ADF13BEF81FC
+:102D5000F7F37D32D3D09F5DED3CCEE3341EC2D37A
+:102D6000FC525E36F1E266CA712B5E94B8F2BAB7D5
+:102D70009AB71CB0B477455232302EF85285C80746
+:102D800012F78A989C4E7470C6E708631CAA4761C4
+:102D9000FB158C63E832C515BB5AEF3C8C7CBBC27B
+:102DA000A7F81DB0CEE03A89F2BF6EF4723C7DD830
+:102DB000646C39003A6CCAC83C8AC39CF17AC81B5F
+:102DC000DFB6AC8BFCF6402F3D0AB43FB69EE7174A
+:102DD00099F94F0B04BD98784CA9FB80F07206E37B
+:102DE000E18897C22CCA839A07F850BD14E76F4553
+:102DF0003CA5B2C6C830186789CFC122163F34AC93
+:102E0000DF9647066353DE99426F6CF5849FD4F5D5
+:102E1000419E8F26576BE89F3F53C8F715CA7EA483
+:102E20007756CAE9D4C47F6A1C9DBAE3F2C3E2E9CB
+:102E3000341EFFA711EF96FB5C5D0AF34790DE7A24
+:102E400065D22FA279570F3928EF8AB130DD63EAB6
+:102E50006243FD1D28372312C5096E107833F1CE69
+:102E600058E3E695E8E76ECCF4A3FF9F391A376381
+:102E70007ED48DE134CABFBB8975531ED472B49021
+:102E800061DE9B99D785E595CC4F4F8915D0FD9292
+:102E900025BA447CA1B348CD5580BFC865CE2C6B04
+:102EA0005E55D2BC2658F9BB9678C4D04A212F3D36
+:102EB000BA8FE779EAE2DE8F46F9415965A51E3DF2
+:102EC000C1B931BB481F5969C9BB50BC8D8CE2D315
+:102ED00045A151955363FD9F9AACE554C2F85F2C10
+:102EE000D446E37337EA79701E040F8E7F12CF83C6
+:102EF000E6C99A8AEDE3E5D5B1E4F9771AF2751FD0
+:102F0000CA2BCA232C203E1CACFCBBC99503F2EF94
+:102F1000A6565AF2EF8E3AF9BD32CA459EC906DE70
+:102F20004F5B7703D59BF7D3E2EFA5B1C7781916AE
+:102F30006474801C6F311A69DD26DEE3F1C3C4BD01
+:102F4000B4A5BE97FBA46B07216FCD0BCADDC8B338
+:102F5000D187C1EF2FD7DCD987F13A83299447D89D
+:102F600096CBEF2FCFC385E23AC6717D9055F1F332
+:102F70006A4B56A3CF0FF55B9C3C1F86E5EBECFA42
+:102F8000099671AB64332EB402F1097A1FE94BA69E
+:102F9000BE6AB6AB17E7C26A712E3C3339740BE1D7
+:102FA0003F96DFBD1AE988A547C20E336EC77F285A
+:102FB0000E64EA0F474635523E8D3BC97DEF3B2BF1
+:102FC000A3E7F99D34FE43E679AEDD85E35F37CCB8
+:102FD000BB08F9CC159459279E63F36F27B9FB1CE6
+:102FE000E68D824E335D6F0E8E80FD6EAA14F1A6C3
+:102FF000862C4417EBD1783E69A4B8D187E7DD96DB
+:103000009189EF7DBF2AD63965CC2919C7DD028A9F
+:10301000CEA689883F83F2D88CC5204BA00CE6FE53
+:10302000018CCB78500F28C27391B7F736401BD86C
+:10303000876EA12F04AE00FA41FD6BBC3D1FC97C19
+:103040009AEDE2F3AD409467E0BAE3F3DCCC7CABFD
+:103050003EC5C8F027807F7ED95A0FE56BE5ACF4FA
+:10306000E039D9A60569BCF8BCB72D396C34C21556
+:103070009FD766E64D99F952E6B8FFA7D29ED7E6EC
+:10308000F6F1730B9E9427F39D4A957F9742B3E721
+:10309000B799F935D89EF26B7218CFAFF13532EC93
+:1030A000E78632B60F89FCB3F8BC2A9043DFC57DB2
+:1030B000BF50BDA92DA6376DAE1B44BDE93CE4EF62
+:1030C000CF10DE04F2F7E7C41F31F97B08E91BE4F7
+:1030D000EF617C9AF2E5CF959B48BE6C91387D6E8E
+:1030E00081FDF85E8279FA049F6CC94A4C57A704A7
+:1030F0001D374F0EFD1AE7D5B2F9BD8F4B058F80F6
+:103100008F3F5AE537E0E35F13E1017E5A519E5845
+:10311000F24FFF9DD69324FF34BEFFC5DE1F5640FD
+:103120009EF0EF4B685215D989AAB0F751A8602BD1
+:10313000F31E6E9C1C17F5E792E3BD0E90AF000FD7
+:10314000EA0A56B93FAC8AEFEB3533F56155442FA7
+:10315000FC1EF0D600BF07CC221AE9034732F45A0E
+:10316000E45F963FE91CE746B3C8B3D51B4224FF92
+:10317000179EA3FD266A7FCD4C55F8C187D27AB63B
+:103180004ADA3752E558F95CEB4BABD2F2ABD0EFF1
+:10319000A187E83B0A5BF21DAA014BBB6FBA7E2DEB
+:1031A000BEDF92BF89F6AF03084E02793ACF71EACB
+:1031B000FE3C89F2849F9786C0D303965C02BA9E38
+:1031C00029F0033A08D5B3B7349FD5FFB1BA2AEA3C
+:1031D0006F11F6EFB79FB4E6092CFED9D3AB0CCB39
+:1031E000F9867E94EF25A08BB22ACE3FB2FB4EDB50
+:1031F000F919DFAEA28ADF0F595225E206E23C5CE4
+:10320000ECE6F6153B04F059CEDB6B6696CCC5F5C3
+:10321000039A0CC9724E9AE722D558DEBB7DFC5E3C
+:103220000AEBB58F63AEF35641A7E6BC40AF3770EB
+:103230007AD56AF169D62F9619F783F4D8F105F09B
+:103240002CE774C64E2481E7C984F0F4D9E1B9357E
+:103250004AB7DAADB83E38AF1B70DCF612A0BB043B
+:10326000F89D30B5640DD62BCC68CFCB3DAB3CBDC3
+:10327000BB2AB13CFDBB2ABB3E7B4F1597A7F75637
+:10328000911C493CEF2681B741FBAEC079EA6DF74E
+:10329000E1AF09F8A6A3FFD9B46B81D5DC6EE36E6C
+:1032A000E2CF8249E7E02FCECF378F69243BFB473F
+:1032B000423FF99193299877033CE64F940FF462CB
+:1032C00095A98F8447215E5E48A28F44DB25C9BB48
+:1032D000BF92ED48BB18BDA463D69134D24B4E7754
+:1032E000A6E1F9FFC28992847AC98F72768C4AA4CA
+:1032F00097EC49A297EC15FAEB8BBF73919E517C2A
+:1033000092EB25C52777C8A85FECABE272BBE84417
+:103310008FAC03DCC5A897C0387B845E82ED492F53
+:1033200039BD4346B88A4EF650BF6228A35E529418
+:10333000442F012864C4C3F3C51DBFC4FD8B5F6F58
+:10334000F514FD152BDD16F6F790FFC7ECD791BFEE
+:10335000294DA7FDB6D3CFEC22D596375FD8CFE95C
+:103360003DBE5D323A2B93ABDBFB615D5B59C60E14
+:10337000CAD7541A9FC0B2612894C7851FDE40BACD
+:10338000B9773EC09085ED1A9FEAC7F3C5707BF10F
+:10339000BB071FA6AEE076D05AE675CE8CC9235A7D
+:1033A0003A80669488F15C1E6F0BD8798FA4651201
+:1033B0001ED7794D7FCF8ECA3CE87FEF95E3E85E5C
+:1033C00050C98330109467F6CA546FFA870E8F6421
+:1033D00094BF0FFC3BAF06C69F2EC687F34EBB1BA8
+:1033E000DA2F2E747BD1EE2E97D3A9FD7DF9BCFD8B
+:1033F0004CE35403968BFA5D2ADE3F63F246F90EE6
+:10340000F4EBA25E02EDEFFB61A8CC03F5A9470047
+:10341000121CEF2D17F93734F887FC3BB5B79BF03A
+:103420009976C265F37BA482848B58F417575C9914
+:10343000C9CB8624924FE633DE4F913247F829AE4E
+:10344000655FFC14F4AD336C633BAED13DBEE4C5A7
+:103450005D6C607FD30FF12F53B42173601FC739A8
+:1034600075B26BF65402AE619FF63CF4D0DC6B1182
+:10347000EF3B14F2FB1EDD9046FBB4F7416527FAE3
+:103480009B8E029F72FFEEFA5B905EF76630334EC2
+:103490001441BFDDDEE87DE7E1B76896F2D8572634
+:1034A000FE0ECFC3BDC3CDF60FF3FE66D9D8760BA3
+:1034B000E675EC1DC9CB35AF3CD365101DF72B6409
+:1034C00077AF7B273D91FCCC9FCBF9CE2CCF2BBC8B
+:1034D00093D3F139FA81BC9F382741BF941A6E7F8C
+:1034E000ED5D06204D443CE9D3E6009FECE9BBAB23
+:1034F0007D024C3565D6861E92A3C3FAD72692FB71
+:103500006573F8F914290E933D06363EB787997214
+:1035100000F35BE7317512DAFDDB67BFF0F36B6137
+:103520009E5F148D9F2427E06B7D4E5EDCBA5E9318
+:1035300057A25C7AEFF8A24472606B953ED7BE1E2C
+:103540001E3F6DD9A110FEBF3CF7F49398F71E29DA
+:10355000DE41FEBD3D7F74B04D406F7B2670FD1F88
+:103560006FF0C9D98302DF43D313D01DC077732214
+:10357000F8AE9ACB689CEA295A1DD6C7C3ABA21FE6
+:103580001CE00535CB8F7224E50FFFD083FECE3DC6
+:10359000FD0E72BA9C39D129230976F4E595A2DA99
+:1035A0007A5DF5311949AAD8FBE0660C0DEB1B6575
+:1035B0001BFF4DEF4BB59597370EB39597368C8A19
+:1035C000F123C37B42636D65B7EF6A5B39C026DBCD
+:1035D000CA8BAA67DAC62BF3066DE50ADF5C5BFBD4
+:1035E0002AF57A5B796EFE525BFB1A7FBDAD3E54C5
+:1035F0003051C12B7E40975B115F69BD1AF1F9967E
+:10360000BEBBBC481791E210D9DB47327A72D09F1B
+:103610007D38C977E77E394716E73BA8462827E17A
+:103620003CDF94156B1FC8EBB7F9EB5F98C3F5D47B
+:10363000EFCF89F7D727BB27C7CFE7F3BD1F177F8A
+:103640000ECFBFEA2E924B1D8BE430DEB76AC97FE6
+:103650003DBD1FD7B388FB193A72609DE994AF4115
+:10366000FCF5E2E21B4663DC2D355F1F86F2DF3C92
+:10367000BF83F961F60ED4A77AC36C2CDE3F837248
+:10368000BDB887162CE0EFAF10EF57E313CEED7205
+:103690000BBEE2CFE38067E24B6036B0D97FF6D253
+:1036A000F7FD1615707F50E9E97029DEB79EABED86
+:1036B0003BC0AF5573F9F38BE2FF9F9DE4DCDE372F
+:1036C00067AA9D7F901FF69C587856F9FFDB26EE7F
+:1036D0007F7FAEC9C322B0BEB79ABCF4FC75938F8E
+:1036E000DEBFD6A4D2B3AD299F9E91263FD5FFB2AF
+:1036F000A9909E079A347ABEDC5449CF834D216A43
+:10370000F74A532D3D0F35E9F4FE777318D1C7A55D
+:10371000028F966FFA15422F3A24C2EB224CE59D98
+:10372000715293ADF21DF0FA5E22BC5EEC391229A3
+:10373000EE1E15E2E756423EF2CC35EF8D713D7933
+:103740009E4E323F0A9F0BFD77D931FF9D1B559A44
+:10375000A104A73477F8E0C1B957F871F666B1DA79
+:10376000EF717BAA55A2F3C63B91CBF347432524C7
+:10377000CF874F4C2CCF7307C8F33A3AB7D841F4F0
+:10378000AB62DA110AE3069C7F6A42BF883124F7F4
+:10379000AC78A078A68907CB7EE5CDBD88FD8A5F91
+:1037A000FFEC22ED2AC427DE53710E1D788E5CD10A
+:1037B000FFB186BEA9E70B38BCDB8F2F1C82FA8ACB
+:1037C0001B9D52A4AF80E25688FBCD843EF2685721
+:1037D000C3AC81E3FCB6B89BCEF5FBA27ACE3F9199
+:1037E0009E13DF0E7E0E101EF0DCB2E021811C283D
+:1037F00049B4FE32F987FD9BA0FFDE7E467E33157D
+:10380000756A80FF05857FC761EF4907E1F98C473D
+:1038100022F9E85E7FB7077DDFCF7F8DB7336A245B
+:10382000BADF90B67F8F8A7A6AA05F1F86DF232B6C
+:103830008C5439F1FBA125B326FA532C7450A2D82D
+:10384000CF49D454A3E70E39C586C6952F8BB597BB
+:1038500071FFF362E55CBA97BD1CD7B5F0542353F2
+:103860000B84FF35319ED64816BF9BC2FCEDD37347
+:1038700049EF3C7019C675C6B3307D1F02CC8390EA
+:10388000C59F20A787E8DE9E69A77F2469B7E17CF2
+:1038900003C66FD0282EC71C0E8ACB6D98ACDF896B
+:1038A0007432206EE37DF92F129C69ED0E1641FDF6
+:1038B000C2C87411FEE2F7EB8B8555F7E03CBECF32
+:1038C0006CD7EF90ACDF11B842BD8EECA933604FDE
+:1038D000E13D951685DF9F32DECA087711902C1FD7
+:1038E000F5B67BE5ABFDB8FF8FA4FD3DD947EBC036
+:1038F000DE42FB6B9B90C30FA01C86E73627B7B751
+:10390000DA9ADDDECE6CB4B7320D071C5C1FA68CD4
+:10391000093358E723426EB9D9F221A10967815FC3
+:10392000D827CEE8BEE778C9DE10E57497EEF81325
+:10393000DA7547E430FADDB64E7CAC7625E26FA24C
+:1039400087C7459588BA001534AFC1B22DF7FB651E
+:10395000A6BC8B7EDA76506630FE7BBFB89F9BE1BB
+:1039600077D8F49D2185767DED3B8304B70B251137
+:10397000DAADD9AE30E6E9A828B700EE769F83F835
+:10398000AB55E5F2A1355DF37813ECEF16C4B73B08
+:10399000F9FC726EAB17FDDE3BD21DC4BFEDAAB2BF
+:1039A0003517CAEDE90AFFEEABEAA84C94C7F2CE90
+:1039B0005C9EC7024D52284F2AB090F49D64F37468
+:1039C000887D37CBA905BA467CA6FA43B89E96F403
+:1039D0006C09F7C5ACFFF15C497C6F81FB95B70AB8
+:1039E000FD2935BF3B827E9DB691AB2723BA3CA013
+:1039F0000FBD0BEF3D05DDA43FA55FE6D213C1FB74
+:103A00007B31DE56A7BF12F1B935C3C10CC0DFD67A
+:103A1000DC2471AFB95C8F6C51278588BE011FE330
+:103A2000A581EDF68B7DDEECDCE1C3FB6C5BC72F83
+:103A3000A17CB1ADA3B97CFE4A755F577301F2CD8D
+:103A400057D89F906FB215DA3795F93D78CEB57992
+:103A5000152FFA05A664DFE30958E45C3C9F38475C
+:103A60002EACADA37C82543F22BD4C3E44DF1B698B
+:103A7000F383DCCDC57CA646AFF53B02A0777F84FF
+:103A8000F2E35C74AA32DD83F885F1898E92ED5FF2
+:103A90003C3CE92899269DA57D965E9BE83B16F95E
+:103AA000D50E1BDD38CF4137E782DF762EE6C4CE58
+:103AB00045DF21DF6A8C77DCCF78FD65D5EF75A116
+:103AC0005D1F5FFEACFCD9A2EC20B9DD32CE45F41F
+:103AD00014DF7F6B2E87E7E8CF7F4FF3A1FB01F761
+:103AE0002DCBC3FD4D0F140E4D492497CBA6E8FEF8
+:103AF0006A8B9E9355DA4DE76D4A3523BA4C57438E
+:103B0000DE71304E7AAF0C340AF8767CFCE763EA5B
+:103B1000C5E351D9D1C842305E66AF4CF4893F1F2E
+:103B2000831C1C22E4E096CBFF95615EC9F6B18A46
+:103B30009FE7B3BCE73FDB799239CBEE4FBA507FBA
+:103B4000D1FC6A91DF90C252783E51758942793C2E
+:103B50000E7ECE6AF0DF08212224B1FF2378C89FB1
+:103B6000CE49C6FD64D9CB18C9CD685E0B7E9706D9
+:103B7000C7D119E92378B116DB5DB686EB5B39ACAA
+:103B80005FC278E0E598DD2323BD73F97986E538D7
+:103B900028AF07A6C1BC14C970D0B9F8F0E547A595
+:103BA00000BC7DA068F544C447FC3A1A06ACE3ECBF
+:103BB0007830E11C6C3A35CFEF160F3F8F3538B8AF
+:103BC0005350598EF37F96C91BF9796CB8BD785E56
+:103BD000B7288DCF60197A87C85F1AE7FFFC308558
+:103BE000FB47A57B98572A22FF673EEED33A96EA19
+:103BF00047FFE41045F7607DDA3885FE5E03E8DDB7
+:103C0000D331DE12B3CBD5749E47B78EF20D7F82CF
+:103C1000E71AB4DBFFF1D9E5D1B3E738D73A7AC771
+:103C2000A5937FDD539F86F6F873BEBC4368DF9C87
+:103C3000F1F03C30B3DDFEB8EFA2B40939F76AB554
+:103C4000F0A3A77C2863FFEB7CAA82F976259E89E6
+:103C500024DF5BA4C4F18237847CBB427D95D3D939
+:103C60001AF37B666B48FEFF2643D06F83BE94FC3D
+:103C7000CA42DF639AA67AA7C5F43CF3BCF4295E76
+:103C8000E3761C47E4610D58E7FEDB187EA785F953
+:103C90002CFED93C9C7F4834FF8EF8394EBF4B86B2
+:103CA000CF0E611FB7F84A287FE30CCAAC04F113AA
+:103CB000F3097AEA4F514E4DEDB1CB97B47CBB7C02
+:103CC000697734523E987135F362BE08ABF6FBACAF
+:103CD0007A32E8AB87AAC93EB5EB9D6B6A18FFFE46
+:103CE0007696AAA09F26E809308C4B28393AC3FD66
+:103CF00070F9FC67DD8FAE6AAEA7B4E5AF0CA15DCD
+:103D0000B37DF697082F532A797EAAD90ECECBA37E
+:103D1000D516FBC6E5E3FAFA797F67C9EBB8A0EFE1
+:103D20002C75CCBA857F67C9B792BEB3F41CD02579
+:103D3000F2CBFE0C3D0DF5AF0BFDCED22D35E23BA7
+:103D40003E293C1F45E9E3F107A54FA7BC1297EFB9
+:103D500014C56FAE137928F1FE22B7BB91E26D91C5
+:103D6000E2C6A5567FB189BF2E41D7BF2DD6295FA8
+:103D700028D9DF8930DB21C6705D6EE10FDD52BCD2
+:103D800081F0BFB0328BFC518AF047B94EE9941FE5
+:103D90001C9EA267D658F0EFCE31E8BC4BFB7BC629
+:103DA000EFC17FC4EFC1A76D622578EFBDE4E349A1
+:103DB00014A72A89A4109FCD3EEDA7EF5897C94FAD
+:103DC000B7E741FDFE5E85F2F2F6CF4ECDC673ED4C
+:103DD000835EAEDFA6EDBFEAD017A15CDC5B8F3E51
+:103DE00001903B00CBD081EB987DDAF199ECCCA926
+:103DF00068675AE225E6B83F683A48F4F16C530F19
+:103E00003DF73445E8D9D1D447CF42450BE27A0A91
+:103E10007B2876C9669C807A0B1C856F417F0B3DA1
+:103E200078A7E8D36B88FF7A6CEDD2F2FB6CEDC01B
+:103E3000CE9D89F8557C1C9FAE6AFE7738E6F7B1B7
+:103E4000CD92FA3F4A5E2D473C0C82BC5A597356BC
+:103E500079C5E3A9257DE27B63A6DC12FCF8976AAD
+:103E6000957F37C9E44B115735CFE976FC15CED392
+:103E700096CC2F71F966E66F887B8CE6F7EAD7D788
+:103E80009CDC8DDFBD6B7BD3ACFF78B766A967C6C2
+:103E9000BFADC6FB28FBD0B8053DF4B7353F5E8DFE
+:103EA000FE8625B5598A06F00531009B15BB476390
+:103EB000E63BC6E3ED780DB7878EE479C90FDF06E0
+:103EC0007BD29900CF2FD708BB4DB5FF3D90D424AE
+:103ED000F7872262DC43026FED2E9EA790EC9EC80E
+:103EE000D745FB64F7447E5523E2F5E7B817F21D8A
+:103EF000D1EEFB38EF70CAAFFC27E423F3EF75FC7B
+:103F000040C013FD3B1D3E96709C2E217747CFE3AA
+:103F1000F9C92E9F46DF4583F19EA2F1C4DF5530DB
+:103F2000EB679C8CD6FF33D547FF7E824E7E22F313
+:103F30009E5ED7E1D776372BB1BC9CB6E8F71679F1
+:103F40009ED3FB02FEF8A7794F25F65DA9C3BB35CA
+:103F5000CB77A51E3FDCFBAEF8EED55EA25F713FCE
+:103F6000675B0C0F3FA6F771DF19D853F3F26EF1C0
+:103F70007DC5FD047763DCF7BBD8D1DDD6EF266CB9
+:103F80003BFCD66AD1FE20B517DFFB4A4017826E94
+:103F9000FB77E3BDD1F318EF75824F7CAF6B630DF8
+:103FA000E7A364F40CEDFBA87DF43BC6F51E3C577B
+:103FB00062DF317E83F0731EF83A46E3E8E6BC4CDC
+:103FC000E443717E31F3C94CBA90E7713ADD5C236A
+:103FD00099F796FE407858356878F880E089BB9F5D
+:103FE00074AE753C3339F411F5F345F394FF83CA8D
+:103FF0009F111EF35E593C7F0C9D2799F9D129F33F
+:10400000709E9CE8F73C53E725961317342F8C9B42
+:104010004DE3C6BE133A7CDE20AC87A9E7975FF27A
+:104020005FBC10FE351071000000000000000000B1
+:104030001F8B080000000000000B0B146060F8519B
+:104040008FC0DC687C5AE3BF4C0C0CFACC0C0C978C
+:10405000D81818DC38191844F8C833E7329ABE87E4
+:1040600040B366F130302C636560D809C4865CD8F3
+:10407000F5D90922D8C7817E5F05C497E91C06A33C
+:1040800078F0E03A11068629A208BE8118AA7CBD04
+:104090000882AD2745995D2E40FD00C5F694E2806B
+:1040A00003000000000000001F8B0800000000005B
+:1040B000000BD57D0D7854D5B5E83A3367CE9CF921
+:1040C0004B4E92012721E0991031D840074C145AE9
+:1040D0005A27116D14D4887FD17A7B07DB228ACAD4
+:1040E000D47A956BB199FC4F4280008A142D8C3F95
+:1040F00054B0FA9A2A5AACB577A2146DF55DD15A2C
+:10410000ABBDB42F566BAB551B5B29F415E5EDB574
+:10411000F63E99734E66328348DB173FBFCD3EFBB8
+:104120006FEDF5B7D75E7BED3D0A5441D569008749
+:10413000F18FA5F7F900A03E93CEFAC605CB1EACD1
+:1041400063FFF6B923DB5832EBE97995B1DA4CFD20
+:104150007A90002600343E7DF91F81D5FB2F70EA4E
+:104160006EF6E9C9C0882FC2F209C909D8CE0D0D73
+:1041700065E70459F94147A48FE5D3871C7E60FDAC
+:10418000CC04278DA383E66F9EC1BECB171483A9F1
+:104190007F7BFAF94D32A4CB009EBA05E46656AF98
+:1041A0002B70EAE5C37E80E75BD37F7DE304806804
+:1041B0007ABAACB37E76B73E43F91FB7EEFDEB1B80
+:1041C0002E801894D0388DF3DE9717B3764FB9A0B0
+:1041D0006590B56B8C4AAEC5A6F162623E4F7944DC
+:1041E000B9D620672D0FB072F6BD31787ED6F218A1
+:1041F0009B11D52B11FD1C1C76623D1D467C34CFD6
+:10420000438BB2CEF338D1CEC8D70DF3F93EF9EBDC
+:10421000030B900E69286E76637AA86A1FE27B48CA
+:1042200095740833FC0E9F4DF84D237E5917075E99
+:10423000E3F87EEA4347A48DE1BB51D5FC11960714
+:1042400099D1839537FA214A70C92C65702C10706A
+:104250005F2AD24598125D74A2CB90CAE8E2CF0FD4
+:10426000EF699B1482D798E710CEB38076065DD9AC
+:10427000577F7380B583EC7C30163F6CBC938F1CEA
+:104280004E03AFCDF386FEFA860AF47798FD7F865B
+:10429000F6D3BFBE5193C99F7670AF25CF381AD4DD
+:1042A0005318BCF84F1D53F98361A33CCCCB719CD0
+:1042B00064ABFE4135E3BF8156F8A09AF1DF9A5610
+:1042C00095F2FDAD1AE5FB5A43944FCAAC09A363BE
+:1042D000B21F5209D6BE24CAEA9BC62B9EC3DA99E6
+:1042E000E00B44344BDE5713B2D4F7E8BAA53CA92F
+:1042F0005FEF4831BAF7D63A524E09E16032722286
+:10430000C2A152CAC07D39C4E653CD9BC06A97FE94
+:10431000CB2A84E70527B4B37C911E755CC1F253A8
+:10432000424E4845D8F8452300ACBFE42D00EB5978
+:104330007FFDB34E715CC1F27D73DD9A530348B1CA
+:10434000FE936ED6CF4769BD03FB99A144B01F18F9
+:10435000907F8B7852D97F87AB00A6EACA6B8E22FA
+:104360008070827D37CFCF9D08A15C17CFB17E9F33
+:10437000AA2FB91658FDA960FA1ECED0D318D7C8F7
+:10438000DBC7B38F73FC0A5BFFB67EA7E8C30D5A89
+:104390006DA6DFE361A44DF3FF2BF71B6D94904EE8
+:1043A00011D053B38E1DDCFE157F2979E3E40C9EFA
+:1043B000FB5D5C0FDAE56D181CA43F409E005106C2
+:1043C00097AE3B527DAC9FBEB083F847EF8214EAB4
+:1043D000ADD593F7C631DF1756F476960FD7EC6953
+:1043E000916602AC9AAC11DFF53DE186F6088723B1
+:1043F000C8F8748AC1A71F0D3754211F4A1059CF1E
+:10440000CAC3FA9B6D585F7BD9ABBBE68C9D1FACD2
+:10441000E0F3A73C9BFF08FEA37E6CBF3FAB57A217
+:10442000CDC8B70948B9193CBDD5ED4D0936CE9672
+:10443000840C283F7DB70CBE82784E9EC0E1B5CF7C
+:104440007B8AAE2C46BE06F3F86CBC29D5172FC369
+:1044500079D9E130F4C59DAD1A4419BD36B7D6906F
+:104460005C6E69D506514F6CFED09915BF0B24AE1A
+:104470009FEF70353B12B8CE4E77A4B649D85F6C2B
+:10448000F3550CDED5F51367E33A70FD748EEF0F2C
+:10449000FA05BEA5D4A540F5159DEADBE47F8B1C8B
+:1044A0006D47795E1D2A8304C3EB14D7DEA6A99855
+:1044B0005F51352B8178AFBBFB35EC6FCAF4693A9D
+:1044C000E2636ACD9BFB502E377F9422B99D5AC37D
+:1044D000E49ACD73CA8A8983D58C4F2AF5D4D7A89C
+:1044E0007E8DA2A7A40C5F4E86483BD2EBF8161F28
+:1044F000A4B5FCFC39393E3E7F1E3B3DF08F91ABAD
+:104500004936B9BA23875C2D941CC42FA37255C3B6
+:10451000E48AE175C74956B9DA3C39F55631CACF54
+:104520000CCEA7763E0FD7BCD98074ED67F2531A34
+:1045300002A8700FFC5942399CC5EA4B542E7D9954
+:10454000E5FFF40BAF0E284FB59CAEF9E4CAE0E7E7
+:104550004C6A1D774B9DA3B19981FAB3AB36BEED82
+:10456000C6F16A151DE5AC4FDEF467C4B35EAFE873
+:1045700009C9244FB55C9EA6D431F9C92257F9C6A2
+:104580004FB6A6E0752647EB5A43245F6B5B7592E6
+:10459000AF5542CED660D5B92C2FE40CE6CCA67C24
+:1045A0002EFB13A08DE44ED5F702DAC1EB58DF5095
+:1045B00081DFD3D1E83C80D23A230F69075BDBD798
+:1045C0008E9643142A09DF009F41F0FE9888B2F6C8
+:1045D0005A1DCF3FDEF6C7440713C2751E5EFF09A2
+:1045E000A9A62131CFDC7E0FF56FD467F97463B5CE
+:1045F000A93FECDF028FA301EB1BFDBDDA56D19082
+:1046000060E3AF1579A5BD84E78F71FF4CDF841897
+:10461000D3439FAD9FD592E827F16C34EACF8C73DA
+:10462000BBF456346129FF4314F164947FB7EDD98C
+:104630004482D57F1F9ABF25313A4C9F1FAB605BE8
+:1046400018F036ED0534A5D6D9F09D99DF0B34BFAF
+:10465000400DCFDFDDF66114F16D943F2A05DA10CD
+:10466000DFC837FE89CCAEC27FB23157FDE4474B7D
+:104670009FC37FCF29052867E3E803CCD264B3AF9B
+:104680004E01EE3B7C35F29BA3FC0719BE63F03D67
+:1046900028B174FABCD865B81466812F6186CF182A
+:1046A0003F1FBC061CB9F9938F6FE7A3C633E73CE5
+:1046B0003F8FC99B77AF2BC2C480CD4393701D2819
+:1046C00045A0985E2BF9E8E721DC8A81CCF478607C
+:1046D0006CBFA5F32B206592FB4F9A9EDFC23CC7AF
+:1046E000DB4B66BAB2FCCB663C3E88F5EAC7F29D6E
+:1046F000313F8F989F67CCFCEE69C1F9E5C29B7D85
+:104700007E6B3D032DCD59F6119F7788FDEEE7E7CF
+:104710009C87FDB3F100F597471F213B5EC3F1D89D
+:1047200056B3F8A39FB720DFE71A4F9BC7C6AB3934
+:1047300076F8CCC7C701A6BF888FEB181FD7E6E66F
+:1047400063BB3C1BF3F68A797B73CC9BAD9421DC75
+:104750008FFDFF3AEFBFC87C5E37B03E127C5E5CD7
+:104760003EFE49F3FACB736512AEEF088F93F373F5
+:10477000281B7FBD2EE9967DAE9DAF73CDEB9FC507
+:10478000A763E7353E9E8FB51E2A54BFB6BFEC2502
+:104790003CF6D5B27D02EE0B9E3983FC157DCF9D94
+:1047A0007E1CFA1FBCC94F41B40C601AF6CFEC89CD
+:1047B0003EB42FB0FF4D7505D917FDAD30D8790245
+:1047C000C023450C0F7E9A27B5DFCCECCF14537075
+:1047D000752FEC5617637EE9432AFA95FA84BD5883
+:1047E000F7C2BDEBCE64F8F4CF289DE564ACD0E70A
+:1047F00031BEEFFCE934B4E36BD977C45B80F7C713
+:10480000BEBF80F50333F8F75C70F994540CEDFBF0
+:104810004084C165E207A3FC6107B74B77A09D7593
+:1048200022C2A993BDE5F30EC690BEDECD8A7E7787
+:1048300096FDD2FF16FA74FB8C3D092FC285F61A3D
+:104840009BF7937775575CCDDAF9EE04D2E7BE9A01
+:1048500054C2C150E7AB03DA0DEE7099E85E4970BF
+:1048600009BA2E924E67EBA4CF96DF3C5AFF8B64B9
+:10487000B74CAAE5E58FB6FF4743876C2A4F5CD952
+:1048800010ADCC943FDF7E6D03AEBBD3D5D8AFE681
+:10489000B1F1A733BDD7C1F03A5D1E70C4899EC186
+:1048A000ACFCB27D9BDA92627D6CBF6B63D557B373
+:1048B000AC238C8A4467237FD2BD56BEDE21F0B77D
+:1048C00059E0B39FA117EBFB6A07DA119F27DD0BB5
+:1048D000116738B7BECB49C73BADFA6EBA6C9DD7EE
+:1048E000B19ACFFBA0F1FDB6E89FADEB2F3AF87C73
+:1048F0001C284727311A384B8E7E3E69C413B723D4
+:104900007E93ADFF7FD47CA7FBD938C14F7E1C9F1F
+:104910006D9C5CFDDAF555A2112419F7FD151041C7
+:10492000784AE6C769FFE2F4EF0D25989E95B561D8
+:104930004A5DC1915082D97F4A482FC7D45D192959
+:10494000C7EFAB3F740A79EA6943BDBA6634DFDB6F
+:10495000867A742DE6497E5651F9FAD1FC6ACA6FFF
+:1049600098CCE5EB78E76D43A887AB503931B85662
+:104970000FBDDAF2650657D96E7F044D8D327F0484
+:10498000500F1BE56B86DE0AA968C7EDF68387F139
+:1049900043A9160573FBB5437F0BE19EC52FCAFDE6
+:1049A000C1664BF9FAA1E9E521D43FA2DC1B8A518B
+:1049B000F986A1B9E53AEA93DD7E0DBFFB2AE3341F
+:1049C000EEE94F5F43FC925CE820BD6EE031B970C8
+:1049D00036F9952F9762D39D8C1E0D4FF7AB68FF6C
+:1049E0002777D792BEA7358BFC49F2FF457E245D21
+:1049F0004AEB985F7BF353825ECE0C3DFAF1BC82AA
+:104A0000FCC0FC9C2229CE29128DE934F9678A3832
+:104A10009D184767FCCFD4FE998CBF9AF27B2DF985
+:104A200080968AE23E5E0E32FDC0DAFBA28928D271
+:104A30005DA9E479A73F9246FD71C75510F1EB4897
+:104A4000F72860FDB57379DE156CA6F6BDF53CAFB1
+:104A5000846209CC2767F1BCBB329EC6FCAAE93C44
+:104A60007F874167D861E503F813D1BD7734EF69DB
+:104A7000C7F2A4C137E06BC7F2559FE37AB6426E26
+:104A80007812F17FC7D063AF2E61FD17233FB0FED0
+:104A90008B97462C74D9AC5BE9B259E7749955CC25
+:104AA0003081749075A2C7ACE3AF776878DEF129E6
+:104AB000EE176B7CFA471EB4F7EEA8994DE55364E8
+:104AC000A7F00F707FF836E10FA862D285FB9F6DCB
+:104AD000C21FF0E46DD38AB1DD939B7F48F4FE3CA6
+:104AE0002A11D66E550D3FBF7990ADD3E8C7FF6E42
+:104AF000AB4AFEBA5DACBF18D3DB8FB6AA943ED4E6
+:104B0000AA418CF5FB3DA6C7313FC0CAD36E3A0F10
+:104B10008034FBFED84E47538AF5BBA9959966AC05
+:104B20009F8DAD2AA5B7B66A7F91597FEB5B439401
+:104B3000BFD2B1688593FC1A030B66B2793DF2626D
+:104B400035F9F7E63EE868C6F6A00D5C706E5DE6E6
+:104B5000BB819F2B1D8DB720BFFE60A7DC847A062A
+:104B6000E4F8B333B2D76BC77AA73E283753BD609A
+:104B7000FCE7E704B3D6EBC17A0FEFE270831A7952
+:104B8000B6367B7FFD08EFC9DF77F0FE42919F2F9D
+:104B9000CCDEDF3AAC37B84BE6FDF999CACE5E6F92
+:104BA000238E1BF9BE80AF12CA16661FF70EEC4F9C
+:104BB0002DE5F6CA9C28905F6CD235FA5D92896F1C
+:104BC0006EBF765072303AAB65A938D63B657E4AE7
+:104BD000AA62E97157A72407D3779396B272068F1A
+:104BE00007FB61E9EC39BCFC762C0F98CAB13D4B50
+:104BF0003F3D8F95B3F4B865D67263BC495F815170
+:104C0000BF103A5B27C5C0B05F283FCDC1F38F3BD3
+:104C10007FDB80FA699AC2EBFF19F3AC9F492DD66E
+:104C2000F6D3BC3CFF5BA37E116FEF90795E6566A7
+:104C30002CEDD336AB29B4BB6E3DBF3B74853F33FF
+:104C4000DFE0A264CD15A6F9DDBA6873E88ADACC94
+:104C50007C8217DC5983F95CEB8A477740D4B40E29
+:104C60004D1BA8257BF75F5DBF5C645A37705DA95B
+:104C7000C07581E1A782310A9633BC25B8BDCAF15F
+:104C8000B6FE2C2BDE4ACFB6E26DFDD956BC952E72
+:104C9000181F6F3F13E3E7C21F1B3F6A1EFFB68B4F
+:104CA000ACE34FB8D83AFE6D175BC79F70C9518F00
+:104CB0009F36F3CD8673ACE3979D6B1D7FC3B9D64A
+:104CC000F1CBCE3BBAF10DFAF40E7DCBBAAED735AF
+:104CD00083997EC9A1DE90655D8FF075DD285F3513
+:104CE000F45808D7770FAEEFE89FA9E1EBFBACD7FC
+:104CF000DF0FA1DF7EEDE7F6846298B2BA7B6B33FB
+:104D0000EBC6939FBBD1713FEBF7EBD31D74FE3322
+:104D1000F4B94755D4FFAB6A6693BE4F8AF3DCBE45
+:104D2000D6F4FE6B5C997905921E889AFCF7A3F67F
+:104D300012FCAE01F93059E310F652797B94D9A2F6
+:104D4000EA74D992EFADE5E5377796B727D0972289
+:104D50000F96E33AE4AB810F6A4D7832FA37C637E3
+:104D6000E0C93D3EDF1767C69F6A1B7FAA657C23AB
+:104D7000EF99C1CB13727523C27387D827DF20FF49
+:104D80008EF4CBB1836F467BB4DA0C1FCF67E0E3C0
+:104D90007903BE6FCA331B13D5FF48F84EB5E1EF58
+:104DA000541BFE4EB5E06F853CE788F067AFD76FC8
+:104DB000E3CF6510BD499E807204646FC6654D9C4B
+:104DC00007F1FEEA64215F383EFAF2AF55522784BC
+:104DD00079F922B6AE5D2E8B7D98A8DF64CB1BF6E9
+:104DE0002B2E4787C98F97DD7E5580EB6DB6AD8B37
+:104DF0006C23BD1E2179CAEC3BB81F43969BA3CD03
+:104E000059F4C146999F0F4B5AA405E194FD0AF944
+:104E10001373D51F9025615F272CE73BC530927631
+:104E2000221C21A0F8243874817EFE8CB170287277
+:104E3000730CC7716A0AA05EEB2CB95837C731ED05
+:104E400030E00945091E45E3F02872249ACD0F7C15
+:104E5000B7CCFD16463F0C42D17E84CE050CF8BA85
+:104E60003CCD2D8BD19E2F51084F9D01EBB9DE6FAC
+:104E7000C4BC9E1769A7884BB28F07188D81F14B70
+:104E800013E7901DDA31A75145BED421A2A29FACF1
+:104E9000D39F3D9EC848FBD1EE3C11F95E25FB3304
+:104EA000C9EC52CC7733BB14D34EFF434DB8EEEC74
+:104EB000473ECEE2A719D5731107A44DFB6D5F8D58
+:104EC00017D2E6FDA8D8AF7AF452CB7777A8C2D232
+:104ED000CE3551267BBED3EF48E13E3F1FFCDD02BD
+:104EE0007EA35E8F1C57B502F6CBEE9015DE63876E
+:104EF0003FDEDEE71AD4B2C1F549E1CDE02B7BFFFE
+:104F00004A991227FB596E0E99F9DFE9E27CAA94BF
+:104F1000A971B29BD55CE55EDEDECFCAD12EF63735
+:104F2000EB78FEC2449EE2C4549403137E26897635
+:104F30009D2E711E0D713A3792F4780BF2915AC979
+:104F4000E4471ADBCE48BDA27DCF875F7F85E4634F
+:104F5000824AF221E923E497B78FF3801C9DE8622F
+:104F6000E926397A1CA6AE8F9CB16C7232C1C5E5B8
+:104F7000586D6ED6557E249E15FE9345BF0306FCE4
+:104F80008938F99B0B85BFAA40F84FCEC03FD35557
+:104F90004FF07F1AD35CF0CF10F094416408F7ED26
+:104FA000C8A0D82FC0F9BAD91FBE46F45B26E003CB
+:104FB000F81AD1CD28EF157828743EF30A9CCF9AC1
+:104FC000CC7C9AC47CCE1A6F3E5F10F359E3E2EBBF
+:104FD00095DAD4AC87185F95E6A0CB12D1FFE651E5
+:104FE000BA7CED88F8EAA202E7B124338FC582AF1C
+:104FF000AE186F1E3101CF8013E6BE11443349ACA9
+:1050000037B0C84297AD065FB9F9BA0170BD852EB9
+:10501000B7897E0A9DCFF202E7B335339F6F08BA96
+:10502000AC1C6F3EA6FA6DA27EBB902BB25BB6BAEB
+:105030009E6847FBE301B9B9DB559F198FD5EB316A
+:10504000D79BD4D567D45B85DFA585A3F5FAC5F8D2
+:10505000C22EBA87F6635D686330FBE6DCAEE71B01
+:10506000D11E67EDD653FFCD7CDD64ED3698FB3F56
+:10507000B96B63BBA8773BD66B3BFD23A3FF4DE623
+:10508000FEB7BAD2061C77121C4DA3FD7DDB5C6F08
+:10509000896BB09D9F13566A6FFA4C764DA834CF3A
+:1050A000B90CD7BBAE602C398CFE4A080CA0DDD100
+:1050B0002DC7B70E233F30236F1BFB7E933B2A493E
+:1050C0006CFDD4A2F1FBB05E69C2AD39916E8DF179
+:1050D000EF613EE180668C8BBCDDF7CDAD985F2142
+:1050E000AB9A3B82F6964E47436B8232C5C97549EF
+:1050F000B104AE8B07E4D82E17D93DAC4B36CE4D5C
+:10510000653AC5FB94CC0789DB1D1CAE75BE2F2507
+:10511000110E37830BE383BB6C70B1F1685FDE3B2C
+:1051200081C7DB800C3532F6E7F446B0BFA1093702
+:1051300012BCC936B786ED9327DC48F0B2B2668A56
+:10514000CF73C509DE1E97AA613CDEEDBEEB36616A
+:10515000FCD68A4431D5273870FE53AB087E0FC485
+:10516000D38BC3A8BE06A2786ED3B550A1B8E464B1
+:10517000703DED6FFB16AAE4DFEFAB599FC076FBE5
+:10518000177A29BECEE31F008C032A5BA000C6C39A
+:105190007A82036467969EEDE5F94AA0714A3FCB97
+:1051A000E3655D30AC55B1B42CC9E38EFB6A1625BE
+:1051B00016A31D3387C7A34222FA22C6B79580F8EB
+:1051C00073560E61FFAE494E704632F42D1B186DBA
+:1051D0005F1CCB222FA3F55205D64B1756AF3429AF
+:1051E00017566FA0C07AA902EBA5793D379C5F9C4A
+:1051F000ED9C7594EFE72B647F18F16D45CCF21FA1
+:10520000B54FC2DC6E37DB2B2E5032F60AF299F323
+:10521000F271E158B1AF2DB8DB64DF04954090F630
+:105220001BA7C2A9249779DA1F684D0477BBF2CF78
+:1052300017252C6DF293E7ABBFAA95FB697395FB1D
+:10524000665E1C227D36E332915ECED359EC7B2D17
+:10525000A62D227F99C85FDE12CD325E83C2F57023
+:105260000D348F4B078F80FF4D3CAB674D6A645602
+:105270003F4B9C8E91FA6B1D36BBD1AAEF5439D1AE
+:1052800048E71C353C2ED78DC288721301D22F2ED1
+:10529000486B55B8178568D1E28919F9718526924E
+:1052A000FCFC77B913A439449F08E2D1CE2776BE1F
+:1052B000F0DBF8E268F9E4D263C427BEA4B320F9B6
+:1052C000F10D14582F5560BD7461F5FC49A9B07AF1
+:1052D0000305D64B15582FCDEBAD3A4711FED60539
+:1052E0001DE887F19DAB5AF2ABCEF55ACBCFF35BFD
+:1052F000F2FD6759DBFBCFB6B6EF3FDBDADEBF80EE
+:10530000B77FB8FBA2D3D1CF53A89CFCEE63CA49A8
+:105310008D3A7EFDD28579E44A4DD07ED223EB9042
+:105320000EE2FAC5D62989D2682A8B7DF75321FF70
+:10533000CFB9B81F272927685FFBAF3ECFEF2ADC24
+:105340006F64CC371FBC86FEFDBD53D85B76FB6B0C
+:10535000D4AF73E8F0E153508F00064B83A6B3A996
+:10536000A11F17BC110C15F1540FD0F9B4BDFF5E8D
+:1053700023BE0612A14526389E7373BFCA4FC2DDF5
+:10538000213AAF3D616308F7E9BD93A5AC7E968FE6
+:10539000147E2E5815F3919DD1A3ABA40F7B27F358
+:1053A0007B4CBDAE01F21FF786ADED55613F7CA48D
+:1053B000F0F17A6F8903DAFF5D276C6CC171DDE96A
+:1053C000FF049DC1FD1F93E3A0E3F86EBE0F70477D
+:1053D0001380EB82AA27E8FCDD0E4FD2884B868132
+:1053E000D022D3BC2F32E6C5E653C8BC5E57141A90
+:1053F0004F8B72FCE5C257FA08F1B5D4ADF07B6271
+:10540000210FE16BFF3CBE7E20219D8C8EE452D4A7
+:10541000292F99F9CDBE1E037805BF1DA6BC2E5FAE
+:105420003A2E3FAD12E7A7BDE88761EBB47EE76592
+:10543000E3F2738F58CFDDF045EAD7ADC7A3A8EFED
+:105440007CB569403BDE53ADCD767270A23051F031
+:105450001FC1DD197504291E25B299B1BC6F426FB9
+:10546000242DE51E47AD55AC727384EB5A9DDBBA13
+:10547000AEED877E72C6AE76C0D26CF7018C754DEC
+:105480000F5E3AEEFC57D9E6EFA88D0B3FE54A1EBA
+:1054900057C5742BDECB84502FD9EB3E89CD3752C4
+:1054A000F83C5F75733DA687C687636D2BF7A3AD88
+:1054B00016F4CB556F353AA031BED7BDAD03F76BAF
+:1054C00025F3B97C8CCA833C60E1DB830AF777F46F
+:1054D0007AF4368A730973BFC9987E057FDBE52DA0
+:1054E00099E39E8D21CF7F5374AE9FD401F247186C
+:1054F00072A7EBFF49FAAF7772BB8AFA21A9AF27EF
+:10550000FFF1FE6A05303ECBAE278CB44FE0E134AC
+:10551000E857F11E53DF4B4EBA176BAFE7C1CD9A78
+:10552000C9DFE7ABB1EAE57C7A66B39BE3E5E3EA82
+:10553000991F0ABA66D133B42E2FEDE97C0AE9D35C
+:105540002BE20C4B9B12B0D834DFB542CFFDBB5BD6
+:10555000AC17951C8E5E97D660A65309FBDE60D60D
+:10556000A739E8938BEE976190E0840C1CF6F9ED77
+:10557000107828C5F16BF3E3612C1D381F74BBB3A1
+:10558000F3C127359F2E81AF7C7CBC55CC67ABC067
+:10559000AB31AF7C7262F4FF30E2AB1EEBDBD603C3
+:1055A0003961A1BFD3C05B93AD9E6AAD67E047761A
+:1055B000733BC6583FF2F5FF6B85C363EF3F971C03
+:1055C000FE66540E13E4AF35C671C3E3E457D8CF7B
+:1055D000F474DF2C80623F48E837706A3CEE291093
+:1055E0006C06F3798F5D7F197A31973EB2EF67F2DF
+:1055F000D55782CAB8F69361EF948A7B5FAA881365
+:105600005E2F653FFFF9BBA01B53F405C5FB61F896
+:1056100008E2039A21B58DE244A3436D2C3F31A2E9
+:10562000E87DE81791CF18BA8BE527FCC80D7D11EE
+:1056300074C5CC1F1A62FCB62AAA366379851A1E75
+:10564000BD1F39700AFABBB83D06CE95AFE0FDE04C
+:105650008997C8807875C35C8ADFDEBF02EF8E8DC4
+:105660008567A20C30A994A5C26F40E78AB8D5BC63
+:10567000D08A4F5868CAB3FDE304D5B6BF2B70DE9D
+:10568000767872B5CB0B4F667FFA068EEF86F1D730
+:10569000B5239DDFA8BD5BE0BC686D36D50B1F74DC
+:1056A000828EF7DE0F4A941E7FD047E994831E4A0C
+:1056B000271F2C039D11ADF26009A5930E4EA2EF9A
+:1056C0001507CB292D3F3895D2D0C130A525073FEE
+:1056D00045A976703AA5EB841C161F3C99F250330D
+:1056E0009BC62F3A388BF281839FA5D47F702E2FD3
+:1056F00017E7ACEB6E8901FAB1155C87987C749D55
+:10570000B184D625FBBC6E55F9BAD22DE2D6BB6D5D
+:105710007AFB6151FEA048D709B900390E667F7A3D
+:105720004AE57A615D558CECF26E633D2C5F6259FF
+:105730000FEDF5BB73DCAF7CCC804BC003358BF237
+:10574000D0879FCBBA8331BA4F001023BD0472CCEF
+:10575000A277BB0DF8051E73F727F078C6A3C4C760
+:105760001E85C72D7BBE7067CBBDA877CEBC71E907
+:105770006E267723EED8CD2AF2FB17AE26A6BBE322
+:10578000BA9B43741FF18C8D74EF09CD72BC4FD15D
+:1057900073E6CAF8BDC4758C2E33A85D9B6A3A1FA8
+:1057A000ED5D7273CB77587F7AA7037413BF4E59A0
+:1057B000E905DDACBF0E959563FBCA1B4A2DDF2BB7
+:1057C000AEA9B0B4831AEE470F7DA5CA524F9B7F96
+:1057D00092A55ED1BCD9D676E2FCDC5FF7194B3BD3
+:1057E000B7DFC02B3F5F64F4B7AC1F3D52763A7E03
+:1057F0005D758CCB3797AAC22EF21746B75CFD1B9E
+:10580000F3CDAB978279E741F6EED7D573E7E3396D
+:10581000865B8BD1FD9523AF7F6CE751683DBBBEA6
+:105820002A427D5586FA44A2D48FFAAA0CF58887BD
+:1058300052A3DE6AC36E29504E56A3BEF19BF44DAF
+:105840003D93FB2CFC50EC195FDFCC14E535225D59
+:105850002DF8CACE37938C72D437B5F9F5CD24DB49
+:10586000B876B8EA3C421FFD93F54DEFEC8DB12FB1
+:10587000B39CE7D43B5BEE6169CFAC1B29CFF485C9
+:10588000DBC3CA7B4E5919BFC7A447E0D0CF395FED
+:105890000A7E289E63D51F46FF81884D8F18F2F03F
+:1058A00031E55AF270B9CD459FDF1FA55C1BFD7F26
+:1058B000D2722DF5AE3A22B91E5BFFD8CEA3D07AB4
+:1058C0008946489F86FB9269DE5407FAE31C031160
+:1058D0007EDF3346F13CBD3F75D17902AB41FBE23F
+:1058E0007A357A0EF24FBDDA7C1EA6D787F5E370C3
+:1058F0009D66F9F36DF90B3C132CF98B6CF94B6C2D
+:10590000F52FB5957FD15C9ED4F5E3D08F917CC601
+:1059100045E78649DDD194F53D0581A767D5E62F9A
+:1059200063FB1353271D877461F9AF527F1EDE1F7F
+:10593000CB5F49E365F257D9CA97D9CAAFB5E597A6
+:10594000DBEA7FCD9CEFFD68EAEDB8DE277EE682DC
+:105950006D59FC4BAF083DD273C2CDB1762E97374F
+:10596000935C4E5B19BF02882F00E176FA6DFB3F16
+:10597000C667667E7956E89B9F4CBE91F64D3D6C9E
+:10598000FF44F18DE8DFCB829FDF78C4FB5CFA55E2
+:10599000742F22597E3DF9397A2ADB297E61BFAE08
+:1059A000D0B96D329CBD7D6F2BF773F454663F5FA9
+:1059B000F88D276C89D7826AEE17443138ECC077AE
+:1059C00086B87EEF0A77937E55D25771FF46798C61
+:1059D000FC1BDB3C7CFD52FC71F22BB82BE359F72E
+:1059E000F53DA3F8B0FA3B7F22F06AEC234DF82096
+:1059F00039ECF2FC6937FA37929EEC72B6538CEFB1
+:105A00000A1536FED8F9F3F1EFC6CB2E28AFB67DD6
+:105A10006DD2C5E3E71393B91F4066E398FD0AF61C
+:105A2000F146E769DB67DF25F83CE9E1F1F7467FFE
+:105A30007678EE17F3B9DFA359E6256B7C9C7CFDE5
+:105A4000FF182F71A11F40B3FB21AC7AAE55D4775C
+:105A500005ADF572E127318A1F1EA765F06F3E7E06
+:105A600037C67916E1A2F385ECFB70FDD01C8AEBFA
+:105A7000D80F81813EDC37CBDA2BE817BE896D93D6
+:105A8000D09FDD2127C8BF90D041E3EFECF07389B0
+:105A90009B9C274550DFA922DE0230DE22688A5710
+:105AA000147ECEDB7DDFBC0FCB5724DC1ABE7BF22D
+:105AB00077CF543E9F432B28CEA297EDD471DC03C1
+:105AC0009E29297C4FC759DC4FF6BCD3392B9E2D1C
+:105AD000FED4EDE5727CDAA1B5A467BB997EC3F371
+:105AE000A56E39A696D6A2EB3A41F2DAAB8F1FD754
+:105AF000688F8F7469F6B8442BBE225E4EDFA458BF
+:105B00007F939E488B252ED0EBA1F2BF7BACF0F5A6
+:105B1000E8FCBE900E718A334D563A1C88B7630577
+:105B20009F31AE12E6F78F8210A338163524D3B812
+:105B30000E1FC76FAE714197DF31BF2B73ACF039C9
+:105B4000BAFEC6383FC9E0257ED2E7AB8DDB31FF18
+:105B50005327ADA7F6717EEF8D7DC66BD29BB21633
+:105B6000033A8717FD9D3581C77FCB95FC7EBA022E
+:105B7000CD4D6136FF8E4AFEFEA2ECCF132F516948
+:105B8000F757E43AAFE3E72554C444B4E10F7C5C33
+:105B9000AF882308C030059116A34A9F8A7104BAC2
+:105BA000C4EFF747241E6F3E8FE2CB839E4FBADFD0
+:105BB000CBA95F29BA0E0EFB8EA05F7998FC5C9F83
+:105BC00078BF79E0F5C09DD42F86AC1E2ECBF48B28
+:105BD000FA979C4A870E1FC6F334714605861D2E20
+:105BE0003BF87D2BA828A278C4AEE0F5AA99AE9D1B
+:105BF000DE2ACBFAAA68DD5FC3779494CA6BA2C38E
+:105C0000E3F06552C89152F995E870017E4C994DC8
+:105C10003F9B3FB45B89A5DAD05E9CE2E771AC7232
+:105C20009CCE477AA4D2D97D7526FEAD54D2089772
+:105C30003F124D609C634F992382F15932F4EFA5D6
+:105C400077D39C0B23E3C9AB5C29BF6D9ECFB7BD57
+:105C50008120C129FC871D79F8BD4BE8EB5CE52E5E
+:105C60002512CBA68707BD621DF3662F3FE06B7C34
+:105C7000D09B65DD490BFCF6943055FA69CE3EC8E1
+:105C80000772E59E57100F5D13CE1C5F3F6956FDEE
+:105C9000F4BA2FFA43EFF870FCD85B9F857EFE6064
+:105CA00061FB038803DEA775BEE414E7BBD122695C
+:105CB000229EDA1A7F11E864E5AE396E0DFDC9DE69
+:105CC000DA08DCCBF2A1D3D566790EBD1B47E7AC71
+:105CD000AE7227505C9E731E8F1BAAE17ED628FBF6
+:105CE0008FE2CBE68D1F4FE6B4E57F65A773EB2E01
+:105CF0007A3FC280DF885FB7CFEB07BEC6E1ECF822
+:105D0000286C1FB481F10BB8F15D3195D2B5AD1A95
+:105D1000A5AB5B4394AE6A65CC4EEB7F0DE56FC3DC
+:105D2000A673312E249E0CE37E2474EF2B78257409
+:105D300003E296EE19DD7306DA597D98E7F7421310
+:105D400012E627F3F2437D1BCEC0FD609FC7A89FDC
+:105D5000E4F547F37774A15DD827E26BCB56DD7B82
+:105D600006DAAD1B261BFEAFA87A91C9FEAAF1B9CF
+:105D7000B89F266CB4EFEAC27DAC4736F28F9E61C5
+:105D8000CD4314E1F1A83C7F8EEF07040FA9003644
+:105D9000DE45BE5D94DF7082D8975FB8280F1EB9CC
+:105DA0001FA3D7AB733BE842FEEE8AC2F8A68A7DFA
+:105DB000DA20DECD2DB41FDCFFD07AF752F6F532B3
+:105DC000233779D6B50B0B7BFF85A183EC0BD4C3AE
+:105DD000F8FEA2FC0B2E17C77ADC0DAE23C38B3A5C
+:105DE0002F16C5EE8B9A06D348EA9F78630D3ED6F0
+:105DF0004FF1FCBDB4AC28A134B71B0A1CBFD2279D
+:105E0000EE9BB179E3BA63E0DBB03F6E407A4EC8F7
+:105E1000F4E70A46E9DCCD23DE1B2E14EEABBC9A78
+:105E2000A51F786076F978E76DC1850E0C421AD50A
+:105E30001BA5F3BD96BC36AF540475F07C515D854F
+:105E400025EFAFADB2E45DDA4996F61F975E5FF2DB
+:105E50006A16FEBEC036AF26FB3C0BECD7B3C2A918
+:105E6000BFC1EC84B06CD8A5EBE9DEF27EC431EAA8
+:105E7000C98159748F17AA8D7B0A40712C1E3D4A27
+:105E80007CEA65FA9AECE34AABBD2A07ADF66AA84C
+:105E9000259136FAC5F86DCF0A85C61D5DAFFC9019
+:105EA000F6E0DD73A19769DF3E1555DE379E09F3F5
+:105EB0007611F3FD7C7B2A8B7333BA9B1FCE7FAEAA
+:105EC0006A1F2774E1F8716CF6FAE097F5374D72A6
+:105ED00098BB9D0C6F9ADEDDD886B49F90C17F740D
+:105EE000FB62F27FB881D9D30CCF1DA18B21C6E60E
+:105EF000D98D5518FD9298323EEF0ECDD6284E5FC3
+:105F0000E77475A85C4E6EF2E916BBCCE9E77262E5
+:105F1000D4CB47FF9B9C10CFB6AEBDEAE3FBE503B5
+:105F2000DF8CFF09F799891741C7F3DFC1D683F4E6
+:105F30000E665DFA2C27FA4FF6F92652BDBADD51EE
+:105F4000E7E9A67EEA80BF07CEFE9C66BFAAE127EE
+:105F500086432AC50DEF4CF3B8E19DE93F3F751824
+:105F6000F3CF38E8DDD19D7BC7B7B306859D65D4F7
+:105F70001B7C86EF5B0765F0958E67EF88FB71B33E
+:105F8000D2B6B844199C48FF03B7E84EB47B065B11
+:105F90005509D7FFD9629E75E9A813D7B17CF3DA0A
+:105FA00063A3AF314FBC9F88F3ECF4F3FB829D1ADF
+:105FB0009B2FF1357F4F3B17BCA3FB7F2D3B3E94BE
+:105FC000007FB74371C5B46CF3CE778FF168E1EB16
+:105FD000B2C1D7EDE7FB73C37F900F1E25E8B0E891
+:105FE000096F9D26E182128081A6696142E38BB828
+:105FF0001F2255C1583DB06FAEB404E3C617FBA3D2
+:106000005208F39F95A63038B50A27DBE3307BA909
+:10601000F6C5F4AF713E2D3EBA97D151FB01C517BD
+:10602000947C556EC375AA173B27BBA8BABB81C128
+:10603000D781FF642ABCBCBFFC4CB43B64E07A80CF
+:1060400049982E4F44BB11F031979CFA80FD498747
+:10605000DD9976B9F064B73FDDB0687CFD24CEF9F8
+:1060600013EC3FD42F25B6F6C551AB7D1BB0DDA791
+:10607000380DF5777D01F7328E721C0DD6AB187A8C
+:10608000E0AA766829AC0F5A09DE07F2CE9701E341
+:106090001BB5E048C2A1E7C77B275BC2B85CA52C53
+:1060A000E73017FAB9FF2774451DC5E1EC8F302E94
+:1060B0009885F957B2EEE3ECF72D56D5DE4D7AB25E
+:1060C00083F113C69B246A1DB47FECAD7E4833CBAD
+:1060D000D3D7C53819FA832E1BFB64BCBF5AED8891
+:1060E0007A667E7CFADBF71BF9E8EF5B688DFB399B
+:1060F00052BAB4FA41C4B18C4FFFA31DC7A0DB58FC
+:10610000F9681374FB0AE993EED091DD935955BBFE
+:106110009EE8E6ADCE1EEFDEE997AC7A56A42ADB08
+:106120005F464CFB4BE771A7B4DC05E3D0654C7CC4
+:1061300015EFC7E9E77EB4D592378243ADCEE1577C
+:106140009E1630E018E6717C73F784F0DCB8BFFE71
+:10615000CD109E6FACF930FBF9E382008F0FD7A30F
+:10616000AF92FDBFA69EFB03F10FF5CE4DFC9F50F5
+:1061700095786B13BE6BB67A9FCF62FF18EB42AE79
+:106180007929154BE9BDC403AF49F4BEBA54B1E255
+:1061900044846B68EE127A87A4BBEE493A7FE98F9C
+:1061A0008C4F1723BEB45BDC571F1D3FC779E1DF5F
+:1061B000045DAA12CBC89E5C53FE228DB3BA6EFC5E
+:1061C000719236FADB53D50131F213DBCE73F70946
+:1061D000B9DDE717E712AEE6F3A686318E2A4EFE4A
+:1061E000B10935D121D4FB170662AFF859F99AB934
+:1061F0004BCA691FA15BD7C15B73CC2714E0FD1AA2
+:1062000076D281AAF8FFB9A50E7FAF62DAAC848995
+:106210001EFD39E2DA6B03C6B99787F639DD780FD0
+:1062200080C1D75F5E18FE0D3A9F06CFA9F8CE7ADF
+:10623000778EF85E23B5AFEFF9F06EC7C31AD7308B
+:10624000C53FAD91B2CF674180E37BCD2D697E9E86
+:1062500036F74D3A4FF3A75FA5B889FFA8DF4BE7A4
+:10626000697A809FFF04FCC3144F5A3487BF0F988C
+:106270004B8E527E5E5FD6ACF5401EB69E0FF98DFA
+:10628000F39EF1FB33E00475989FF38C954B5A7F96
+:10629000EEEBDFB687DE5181349D2774FFC2496F74
+:1062A000C11A7818235749FE3B316B241EB7BC2016
+:1062B000D0DA8DFE9135C6F9DA2CBE4F92EBD2744E
+:1062C000BEE60DE8167BC71F31DE492C6C9E45B833
+:1062D00016D573B580EB2AFAE111BECE5917933F5C
+:1062E00037175D6FF2C5EA03F5667F3EDF67FDABEA
+:1062F000F1E1DFFCBA252EDDCE8F6EF8B723DAC7C9
+:10630000E5F22B1F10F269BCA36BB45F1C50B2E323
+:10631000F7D797E4C3EFE2C0846CF83DCB4BFB8822
+:1063200075E39FEF6CB2E9EF4D469C8D78D797F5FA
+:10633000577E7E167BC258570F048CF77C9ABD3867
+:106340004E55A2D68B78DA965C44F96DB78E4F4FD6
+:1063500063FC2D42AF6F15EF9018E55B055FA66CEF
+:10636000FAF66521D75B857C6D53A35E8C5F82A7AF
+:10637000CEF24E67F80B33BE4057E2F15D2325E3C2
+:106380008DAFAFB4DAFD477ABF652060F5D7167AD6
+:106390006FF368F1921271352F07D224F7CE743162
+:1063A000C9537829903C85632369DC37550D3852F1
+:1063B0003AC5AF347BA733928696CA3AC5B2897B79
+:1063C000B0278AF51D9C2B1DB87F09897BE48C853D
+:1063D0002FA338983BADBF07B24D8D342A78AEDC81
+:1063E00049118E104E9A7EAF8240B2FE1E4868DF81
+:1063F0005BF47B2A2130D50B1F3DDEFF2BF0F1EE45
+:10640000CB1E353FCA231EB33E3E5E82E66C7AFF4A
+:1064100017C21E3BFE969D12C9E5357E78DDE4A7C6
+:106420004949232588DF2D2BDB25C467A2132227AA
+:1064300064D1636F047C865ED88DEF2EB82A397DD7
+:10644000BBFEEDE2E12798CADAB2A211B2ED3F98A5
+:106450005E782340EB13D70B5B572EE2E92127F13F
+:1064600049751252F83B2AF307626D2EA4FB52FEC7
+:106470002E75A8333E84F9F03510D159FF55E8D474
+:1064800067E356B7402A4A7C042F8726E2EFDDF007
+:10649000BFC9C38B87BECDEAEF99E3D6F07755E04D
+:1064A000062BBF545C63FD7D95EA4E2BBF4CB4F1C7
+:1064B0008BBD7D581F390BE19D9A7400EEEB82175E
+:1064C000DAFA83E11DF7E17C76FB2369066F75BF7D
+:1064D000B5DCDEBF0C317711A3CB23371FEAAD61EA
+:1064E000F5EF4E3696215EB6A9C0EF5B342B74BF34
+:1064F00035D73BC463F8D6B0FB0B7CB7D858F77AD6
+:10650000F649FCDD8B29DA6B61F46BBECC7FC72EBC
+:10651000F38EC567E81D8BE320C6ED478852DA2964
+:10652000EC53EDF4CA30FA3F93BFF669782F4B2B4A
+:10653000B3FACFE4D2267A1F6CD4EE2E6576372BD1
+:106540004F9658EDCBD38B389FCE2EE2F6A1E6E3E3
+:10655000FD801A2F37BFABB4B148B296FBE3E51705
+:1065600098CAE71789F767C5BBE30D450B7A502F2B
+:10657000699358FD2CFC79A618D7288760642FBE34
+:106580000772FBA58BEACDFB8B8D45FC5C473B5E20
+:106590008C5B991DAE64988F7B9B18776391F10E8D
+:1065A0005C9CBF03A7F1D4F87E5B6089F406FB7C9A
+:1065B000C0058D18A7D231C141EF43DE34D1880721
+:1065C0001B5F4F187418C5B7C6E3902A96F27B97E5
+:1065D000B9DA6D6EE2FE41FBF7989847E7D2C681C3
+:1065E0006A36FFE86E203E710721EBF90F93EF58F2
+:1065F0005136BBAAB389F671074AB2FF4EA1917614
+:10660000D8D67D59F813C7D41374D25F0A118B778B
+:1066100086B87FEE4089234AF7026B81DE3B3B5010
+:10662000CEFD75F6F6BDB6713CB0288AEB349EB34C
+:10663000623CA3520D293CC8F10607B4B08EF101AB
+:106640007BC94FA303C3272BEF8E00D9779D216E03
+:10665000C7C8A1810607AE1FD0A499EDB10AF17B8E
+:106660008B1E7FACA3C812479220FD7BC095223DB4
+:10667000D21176C0DD59FC886B8AB89DBB595FF496
+:106680007C380BFD3614E916FBB9E220B7BF73D591
+:10669000CFD4E3708DF263284EE73EA0737EBC300A
+:1066A00010BDBD689C382EC3EF78C51CA17041BFDA
+:1066B000E47FD83CAE7AC64531E9A71DDABAE7DBFC
+:1066C0000C4F4E714ECD56E53D4FB0F2AFE0BD27B9
+:1066D00096BF6ADF0C650A2B7FB9C2898B30FB6BD2
+:1066E0002EC271DF054713CAD3BBF062D1C926BAE7
+:1066F0003D5224ECD0A48BF4A6E18FFBEA80CBA220
+:1067000057AFDC64CD2F814513D14FB1E45617D973
+:106710002657D9D6FB6D62FE5742BC1BD7CF2E1130
+:106720003F7EED0F66282837579DAC859DA6FB560A
+:106730004F087ABCCDF84737C9D9D5FE9482FBB84B
+:10674000D7779E7CF16701FB497557E0FA59923D76
+:10675000FEEFCB492B9CF9E66187DB38BFCB058781
+:10676000BC5D8AA6B2C8D9B34556BF5087CADF47B9
+:106770008A76C8E0F93CC6DF01C94F625F80DEF36C
+:106780004E34C6299E2ED1EED63A82145F477174DC
+:106790002B18C1F03DA23F08FE33E2E900E2A7E278
+:1067A0003EED5A7558417FF47239DE843FA5669CF0
+:1067B000C3B85DB1E82406BF6B57437A1258EA2587
+:1067C0000BACF78C545550BD26C738FDBD27F4E4FB
+:1067D000D30FDCA3E0FAF3EEFDAF9D8B72B8EC7142
+:1067E00027E095BCF71E08409AF60F2905E5FBEA5D
+:1067F0009DCEAC7E36F2D4323C2EFB5E80F4E2D5E8
+:106800000FB9530B59FBAB1F7D7D2630797AAF7DD5
+:1068100064CF24C4DFFD123F1F4C0CCFC4F5E96ADE
+:1068200019FE3DDB3B64BE62CE5FEF3CE66B41FA96
+:1068300049DB87BE44FD0E5EE232BFC7EE28E6EBC1
+:106840000FABC7E3257748A913B2E80F633FF4CE37
+:106850000E89C3B7CB95C250E0ABB7DFA5C4181CF7
+:10686000CBB7BF4FFC72FAF71E2C423C2CDFE5B4CD
+:10687000EC2F977DEFC3EECF303A2F73C2C842940E
+:1068800063E721CAEF8FAA234E926B1E9F721DA948
+:106890000056EFE1DF9FF93FACFCED901330B4F50B
+:1068A000EDBDBF531EC77CCC1FC75F1459BECBCAFA
+:1068B000D7CBB7BFAE205C9A03462A3F8BE79C56E6
+:1068C0003BC95E1F6044413DB57CB0F77D27E3B70F
+:1068D000E53BDFFD15F2DD729B7CBC8DFF281F6B55
+:1068E0009F9F5C6CB3CFB797151487B2ECC1FD5B6B
+:1068F000D01FF1CE437FDC82F767AFF9E82F5BBE94
+:1069000081F1603FF66828DFCBEFFF451198F4FE78
+:1069100039C55CCEDEDB71DF7736B3F9BFF7AA9BF2
+:10692000B0F5DE13BF9F82FE9FF7BEFFB789E80F69
+:10693000BAE189338E43FEBAE111FE7B36B9E040FD
+:106940007E4D997F6F519C13E9BBC81803F891489D
+:106950006DF480811105D7B3BF4A30D257C2BE0F44
+:106960007EA8A07DB6270A23889FA776BEBEE766CD
+:10697000967F97D1C79D853E6CFE931CA49F99D8A6
+:10698000B0F4BA9D179CF7B93A4C5D11EC7E398C86
+:1069900090DE1C43D797185DEB3274B597EF8743B1
+:1069A0000A9E1B2C7F80D17126D293D171E6583A72
+:1069B000BE8BFF983B968ED714DBDF6FB866EB6615
+:1069C0002CDC5996D5DE35F659D73E72D1B8F69300
+:1069D000A117F2E179A9F093CC298EAE2C46397C2F
+:1069E000E8BBDFD91CE4745EC810F3DE83FBA7E0CC
+:1069F000A31C7F708D7C09F130F2845BC3F5FDEA46
+:106A0000277E49F2F6DE232F283AC5B54091740A55
+:106A1000CBC3E8DF8BC0F2D7493C73EDBD7F3FF3BA
+:106A200057ACFDB5F853AA1AD18FF27B98FC113DF3
+:106A300052E737E9A877531368DED7A5B85C5C97AF
+:106A40001ABA10E3F9EC787F44E817335DF17DA9B9
+:106A5000EB76BE7626F25F2E7A1AF3D770FEA7B2D7
+:106A6000F27BAD729B534E057DDFBBEB8082F6411E
+:106A7000FA714573307BF83DD78842EBE3F79DDA36
+:106A8000B6C858BA67F02FE28E8E701F3E586CF36E
+:106A90007F08FCE493F3FCF33A32BC6D29D62DFC5D
+:106AA00063E0EF9D43D9F5FFB3C5DCDEBE0EE24DDA
+:106AB0001553C7AE5F323427268533F0BE8371632A
+:106AC0000CDE77EE77D23B7DDD834F911EB7EB8BEB
+:106AD000EB72D8D1FB8CF1760DCD44BDF6CE938F01
+:106AE000115F5EF7C06B0AEE57F66C7F5819AECD9A
+:106AF000C801AE0FE6DF297BE77F0DCD44FDB53C35
+:106B000047FCDF5BA2FFE53FB2F6BFFC81F72DFD3E
+:106B10002F4B0C2AF43BAF79C6795B8E5E82F37DF6
+:106B20007BAF0B703FFCF6A0B3299B9DF3DF627D2A
+:106B300034F0D41D38E595623CF72AE5EF3276B69D
+:106B4000457F89BF379C78C125F6B7D157D09EE9DC
+:106B50002851E81E4267E062F2D71BFD0DD8F0A96C
+:106B600005B506DC0768F39BEBCCFB2A03FE92A875
+:106B7000C302FFFF03C228CF4D00800000000000C9
+:106B80001F8B080000000000000BD57C0B7C54D547
+:106B9000B5F73A73CE3C42269393D7E4693C4978E3
+:106BA0004AC02109101ED58120A6986A50AA5CEB24
+:106BB000D50121444832292A5AEB779990885EF012
+:106BC000B3B1D28296B60317AA95C40E1034B6811B
+:106BD0000E606950B4019F7851A3D68A15C8180574
+:106BE0006DAFD6BBD6DAE730332783D0EFFEBEEFEA
+:106BF000F7FBC2CFDF769FB3CF3E7BAFF55FCFBD54
+:106C0000CEDC91529DAD3901DA560268A30040F105
+:106C1000E4D4A600C8AED9D59089AD6A519324803A
+:106C2000AFE9EFF2680B100498086075D6820F9FE9
+:106C3000B7AA16D01CC07F5F03CFD3DE8FCFDF256E
+:106C4000A7B4AFA179ACCDBFA43EB428B0B58287BC
+:106C50008D562AE8FE259E354500EB93FFED71BA6F
+:106C60007F77C0AEDAB16D4D59F11BEAFF4A825A07
+:106C700019C7B5D2F3D806AC0E75AB8AD7D3607EF0
+:106C8000C8195D4FBE2AF17AC6E33AA8C53F1F4C2A
+:106C9000C2F78A25412B34008E80A4CC60805AE351
+:106CA000B97F577D25EAC4685F76F681AF14E00AA4
+:106CB000D969A1FDDF9F6309DA8BA8BD36154A8724
+:106CC000D2C168EF5B590BE151E7BEDF9EE558B0DA
+:106CD0000978DD010BCE1B901CC1ADB4102F68AA42
+:106CE0001B786DA0E17F484347CCBA718097F6A12D
+:106CF000E8F7ADB82DBA698700B749C4076C93218E
+:106D00000C500270A55A0C90059002FDFA2411A8AF
+:106D10001D07302FC5E7A57D660FF749342E0BBC44
+:106D2000DC5640AD44F72DC937E5FABE617F304FE0
+:106D300039D13F5AE72FBEE25756417F450165588A
+:106D400019AD63A3FA97B1380FDDCFA051015EC72B
+:106D500084AAEBC7B6111C68F131747E78D6CC0CCE
+:106D6000C28D31AED551785442BA78E52435A91098
+:106D7000FB0A5286F87D2C85E9F4A3E93833DEFF5F
+:106D8000F1B194CD32F2E36149E0294078225C41CF
+:106D9000F3E3840F17E2670D3D37B3F9378C170B18
+:106DA000D4B656E8947413FDC41FE28DF174B7E2B3
+:106DB00050ED1EA2AD5753681E1B04D748B45E1F8A
+:106DC000D3D301EDDC0E8310B74EE8E37605D1791D
+:106DD00022F1C1C3FD54E86F1F8ECFD5A8B50D2A8F
+:106DE000EEE7C7D5E912EDCF09AA4EDF825C9FF32B
+:106DF0001BE83B0BE9EB88D2D74EF44C1E4A4F07F9
+:106E0000A84C87340F78D64CE079218CFB78780633
+:106E1000046506910A2AE2255BDF6786CE67C20F0A
+:106E2000ED2F6BBED89FF97D39D0CEE3F220C46D33
+:106E300001F4719BEE502585D7734CE7EF7BF0751D
+:106E400072743D466B2704E3FCA70B70FE22A6B6C6
+:106E50004B72D3FE8DBF5AC6E11F2AF679AB709CE8
+:106E6000E2737AEDB895FF5D31934008D68B15201B
+:106E7000BE3AFB17D4800B877B6C101E4DB307788E
+:106E80007D49A345DFD02F766454D8583F3E673DF7
+:106E9000F6D1317ACE0A31E3681DF24DA944F78765
+:106EA000E8C294A174BFFB584BE67331F36E5153A3
+:106EB00032699F3019267F2D479F87CA7480DCA1D5
+:106EC000CF7FBE3290F99C354A8736C7BF312EBD81
+:106ED00008E0A4CBB04F38CE8CE21871C97A2EB03E
+:106EE000CAAEB666320E19A7772381ECD87E9E54BF
+:106EF00018E4FD43F3E46B510F5B1C5E49C2EB0DDC
+:106F0000AA2B48F469748666B39E30E98D19F3D4D0
+:106F1000701E8E1B68060FD175FDCE6B8E135D073C
+:106F2000DCA0D9D3042EBC93484F187A043419F945
+:106F3000BB5A9AE090B06DECFAE4A5DFE1F8A41E2C
+:106F40001964BC3F807BEEA37D2BDE346262323C51
+:106F50001827DFAD0E213FC63ECDF2FACFEE133932
+:106F6000CFF3331F64D2BF0FFE3B3D3F0829ED3402
+:106F70007E8382AFA6F97BADC1AD4887E50765C6C4
+:106F8000DBF24E2908C467454BA5FE5D2FC820F0F3
+:106F9000077CFFAE5F96301E6518FBA3E9F8BC7F47
+:106FA000A3D5831A13D2BCF1F62AA37A1868313814
+:106FB0008080F7480ED26B914EAFF5C90F6DA2F5E8
+:106FC0006C6811F629AB363D6EFCE74957DBEA7079
+:106FD0007E2D17D7359570D3337235F697E5CBAA4A
+:106FE0008C2A227B7E5EBC7D6CB7BE47F2A7E13F58
+:106FF000C2B7A1BFEA487F911E92EF65FB771AE9FD
+:107000002593BC80B07F4DA8AFC238DF920DE279E6
+:1070100063BEFA9E8757E7637B5B30FEFA3250A26D
+:107020007DB6B3AED1A407EE86611EBB3414FF4A11
+:107030001AE29F40E204A7E083D343FA65F015D932
+:107040006317A4607925BA931E91FB47AD9F8EF319
+:10705000F97BAD10D4885FE2FEE0463918288ACA71
+:10706000C760EF4EA6C7925CA407E2D39E134FFF02
+:10707000242D9EFEC9A3D3BF911F291E133DE51ADF
+:10708000A63FD21B68FED4CAE2F8E7757A8FC67FA6
+:1070900082DE5E5E675DB7048F4944E7070FE46BED
+:1070A00043E9DAD4FDB08DE4FF7C7435D3715C9A8A
+:1070B000AE47743A9E869EBD3A2A6B1D6E5625BC1D
+:1070C0000F456D9F41382D40B9259C98E5DAA09F6A
+:1070D0003553F5DA70DC45340EF797E7080961F4AB
+:1070E00080F232E165A1D0BBADAA97ED91A16F937B
+:1070F000CFEAEDF7E16B6C33E7563C4038BA5D4AB6
+:107100006967BFCA24B76BC7AD60FD55B00AF531DA
+:10711000DBD5783F2DB4D2E15984EB796A25781616
+:107120008D00D8B152E5D6ECBF19F2BE11FD37BBC8
+:10713000B0CF3CAF82F85DA392FEF1A8B4CE876CCD
+:10714000C0723A500AC1CDF8FE50F83337F9A30F98
+:107150009545AEAE457FC4BF186A43D86E4DB7B0F3
+:107160007E7D365DF877D5E9366ED7D45AC08BEF81
+:1071700039D52307255CDF29D57BF072D23B3D56FC
+:107180008DFD2B35F2D2F7F87EB9BA06E9996B6915
+:107190009F40EFC5F1D5419C77A0E77DD7AD317613
+:1071A000F954F72363C80F7AD402F5A104FE5063A3
+:1071B0009A78FFA9D1EFB971DBD0E888D800F174D3
+:1071C0007F7F732DF95B77256B7CDFD635239CCFD2
+:1071D000F899CBFEF17375C3186FBB4E4090E46E07
+:1071E000B67CD355E3B03FE555C56367A1F25EBDFC
+:1071F00060120F61BEAFFBB27C03D1CF8FF45CC5D0
+:1072000017DB5F267E3DFB670548EE2A9A9F7EDFEF
+:1072100087FB3C908368A80498E40D958771D4ACF3
+:107220009EB41924DFFE63C0F23AB14F89C32DC862
+:107230000DFBF349AFBC21DCC3C96F98EE43402678
+:10724000FF7F4A7FFCF569E7C1FB5A03EF2E7013FD
+:10725000DE1F5BD90DEF935DD4ED671E6E30113DDF
+:107260000D7C3F933CF39134F6274026DC7A94C49E
+:10727000E3FF9C2E310ED67D294B84CB81087856B6
+:1072800021BD0616E5F1BE073E23870CDB2FE5EA9C
+:1072900050027FEB89341B3FFFA84DE0FED13A67D7
+:1072A000B005F7B3AF6EE9C5FDF8BE333FF05DAC96
+:1072B0007E931F8CAAC552C9FC4A25BADF3EB74D42
+:1072C000623984F65CA29B79BC212786DC18F29295
+:1072D0005B37CC174CF09ED1FAFE66D68D966C8447
+:1072E000DB3D12101F4FADC2757D83FF188055F92D
+:1072F000B41E7FF7A736B2D78E1EC91B4C30BE37DF
+:10730000CD25F0BB2AD0320DE9B562213E4B72612A
+:107310006B2F4A347F00D6E5A37308BF49D3785D4D
+:10732000A71C700BC92528EDB964B74F75577D9B15
+:10733000F4FA632887E4373C6AF5F0BA038D28B382
+:107340004416723CB15F70356C5A1313471E499B4B
+:10735000F1761AAEE3ED3495E7CDF079245AB7E72C
+:10736000ABCF5D34FFC01776E65F1EC9708CDF7649
+:10737000264DD0E78174EF1B8C97FA4C56A61E9FC2
+:10738000CBB3A81CE0D26EA4770C2EA37C0BF073B9
+:10739000E9BE00AF27BD0F03278EBFBC1AF9CB7E15
+:1073A0005D394358026552543F57380AC2F9227E6C
+:1073B0000865237DD3EB7FCCFA3A09F530B9E2D0EA
+:1073C000171F17B146C6E749F6492FB4AAC2CF6ABC
+:1073D0004B137AAEED6125D88AEFDDA8F4278DC076
+:1073E000B6C8ABCD5434D2F7A53C6FCE1DC0F26DFC
+:1073F000710425D243C9253F4F3BEB774D03D8FE9F
+:1074000095CCF437F3695CBA4117DF574497F1BD67
+:10741000917DE4BE79922083F83A5B76F2BEA79C18
+:1074200014FAC7AC6FE4F02F1F257D33A0C74F09B6
+:10743000F4CDAD645F0D7D0372E97EC2CFB417F465
+:107440003053D733187D301D261FF2B53A13E89715
+:107450004AA84D45129F57BF98F988CEFED97E01A4
+:1074600012A3BC17E528E679B33EBA283D5E1F9DFE
+:1074700086E9D9576851BC94DDEDD96F8FC187A1DA
+:1074800087A27809B29C98DF2381E36C5F2D21FDF0
+:1074900071484E25BD3303F98EF33FAFCB49DA6710
+:1074A000C16F13FFD7F55C9944B8DED15BE520B11D
+:1074B000599E236B7F46FF59D93B2F003A5C48DF2A
+:1074C00019EFB58243738E267A58980EB28AFD98CA
+:1074D000F70FB64BD5A4179169A9F3C69D5B1F2C76
+:1074E000CFB1F17B76F416A7128E9C80F12DF2AF0E
+:1074F000A247623FC18C6B338E5BF105168E1B6B0E
+:10750000D99F90A5909E77888F4B8B0253D84EDDE4
+:10751000817138F9AD83BD68B7B0DD81769EFC948A
+:1075200056E76CDEB7B15F637D77A4CCCC86D2A181
+:10753000FB375AFF1732043362FA4AC44638F67FE3
+:10754000618BBB6ED0F35C7430E83995E829FD9F00
+:10755000D3F35BE91AE3C14CD7FFE9FE0B96574220
+:10756000A2BCC0FF2FFB9F06BEDFF58B78EBB51CDE
+:1075700077549F142CAF9697201D26913FEE89EAF1
+:107580000707FE237C8DEF6E677D5389FA86FCCC5E
+:10759000FC8610EB97C939225E32EB8D4B7BE03ACB
+:1075A000D28F53C2E8975E80FEF88CFE2797F3389F
+:1075B000C174CA43FD71FEB20EBC345E838C1A7C6A
+:1075C000CFF83EC543760FFA3212E605CC76C3F00B
+:1075D0004B0D7FD43CCEF0470D7BD2A4D3E170BAE3
+:1075E0002F44EF07550D90BCA15C851EF330EC35A0
+:1075F000F2178EA4D5EEE4FBA343018E038A41A5C6
+:10760000BC0ECA2BFB61150E67581E3F543E934DAE
+:10761000721842BA509E20E0B404474843D781EE26
+:107620007680FC3E7C80DF5F9F2EF2A50538869930
+:10763000D604ECFF178C071FD9DD82326C719F7F57
+:10764000D2ED4A9F3EDE6871DD07D329FFAB40C013
+:107650005EF6CFAF9796985F46F4F1FE91E67154CF
+:107660007B79FDF92A78C88FCF57429207DF9FDEDA
+:10767000A049679348869DC6F9F26B34B697F9C363
+:10768000B14FE3C9DF49C097F7D2ADBCDE4647FF33
+:10769000011BD2C15FD35CEDB244FD74BBD5E7CD15
+:1076A000A7FC51B7F0D781F27D9C3FF648B41F6527
+:1076B000A6A08F5F15F1951354D69B153A1F2B1C6E
+:1076C000359CDF219B689F3274DF92E6E5C179F338
+:1076D000400B4C89EA5523FEC16980DE63D6AB03BB
+:1076E000BB5FBF2880F2F8D6FFFA3405F0FE3B4AB4
+:1076F0002485E871FCDE9753BC488FB7EE15F1CBBB
+:10770000CD26FFC89621F8539751FB15D1F59695D4
+:107710005F4D8AD52F707716CBC56D419982E1B345
+:10772000F2B3EC8964CE3D1BFDC650465CDF90830E
+:10773000463B3427F2AB2FCB10F1D96D1D9B6C1457
+:1077400047D765F85233F0FDC775FFEF78570AE762
+:10775000038CF52CEC9860237ABFD36387302BC859
+:107760003EABE0B3F76A691225EFC59F799D07F636
+:10777000E4DB2C38DF62092222AF05077E86FD0F8D
+:10778000726458E319BA8FC56FA936CAB72F9E0124
+:107790009100CAD5C23BA4D577E1F8853E27797020
+:1077A00043F6B920101FE72FD1FD955B1FB09AE279
+:1077B000A4E603942F5B84F3503CBBB83DFEFE600F
+:1077C000EFED077E4676A0DBC67660C979E2A7F2C8
+:1077D0000C3DEF3209267F5D42FE4AE98F4AB573C0
+:1077E000EB25C35F39BE12083CF0D7950E6E4FAC47
+:1077F00054B9FD4AD7D7CBBAF71E605C2B7D93C82E
+:10780000CEEEE87D3FF9462D6A372EDBF4E9FE9F88
+:1078100061BF9CF65944FA326C253C5EAEDB8D2587
+:10782000BA1F52FE85D96EECFDC3EF28CEC6FD6FA0
+:10783000E588EBC2FC919B40F92C960E861D31D356
+:1078400063B0B724997072BD41173D1FFB3FA5CBB4
+:10785000B99E6B9411D709F487214F5FE979874569
+:107860005BE6AECEC3F7B7EEFEB0B05FE8A5D7C01B
+:107870001DC52B2A7AC6DB1280C81AC4A7AFE7073A
+:1078800007884E07086F95D4BF88EFE754217E51D3
+:107890006E97F47CF4268C67F9CAB1E4501BCEA134
+:1078A000F8D28C4333FECC783B65ED2F24FD60C6C7
+:1078B000D92909E627DA577D8638BF58A479675356
+:1078C000BC8B666DB5CAFB11FAEFB8D27EE0872497
+:1078D000B75B248E0F1B9FE97C9AF4D1D2DFFCC4E6
+:1078E00045FAE823A5DD4DEF6BD87A9FCB4B7A495B
+:1078F00009B8E8F98F82422F99DFB747A7A3712E05
+:1079000070D62E3D10597D0FD2E30CCA33C96F5388
+:10791000D7DF56DF437186D711A1B8F3B8D23F9BAA
+:10792000D671DB0267738B87E2DBF87D2F7DFC2746
+:107930006E8DF3C7817C9D7E1CAF366DB17AC238E7
+:107940006FD32BB2875EE38708EFCFFCBC3FF4BE5A
+:107950008DF4B76A8148C1B4A1F7918D36921B7F2F
+:10796000D7DA4F6417B5825F7EA273CC3943BDAEC0
+:1079700087CD387E2A23FE3C01E9C3F9D400AE8BC3
+:10798000F2471014FAB8F5D7EBC7BF8BEB3BB1E564
+:107990000597541A7BAEB08AE93618BAF5970ECB24
+:1079A000B9F17B4AC77BD46F09F2735AB7240E83AF
+:1079B0007A44DB600DBB286E6BD864F504F072432B
+:1079C000A70C0EB25F47EDEC3734747ECAF86C90AA
+:1079D000BC1169026FC325C5F811CB3A3F984DFA27
+:1079E0007659AE0C3528524B779E16E3BD1049C22E
+:1079F000F1CBB6BF3BFB87D447BC3B12F0AB2AB4FC
+:107A0000D726E4C6C4AFD0BBB3C91F6EFDF5E7CC23
+:107A10008F8FF648905D34F4F9FA4D1FD8C89E9CBC
+:107A200040C664A4097A91DDF087E405B6D444FC2D
+:107A30000B5FFDDB0ABECFF9BFF3F1F1213A6BCB4F
+:107A400062BC3FF55B5C47FD9B764F0DBDF7A9DB44
+:107A50005D8038F8506916B8FFF97D6EB2C3F5D66F
+:107A6000805BE5565CAFFFC59D8CC72587EF748BA7
+:107A7000F8C69B2BF245815CDAE7E28DDFE57DD627
+:107A8000818FF158FF73B996F234A715A8DE9E4096
+:107A90006E26654AFAF9DAF7C7DF23CE0380E2F3F0
+:107AA0000FF5BC69E088CC7E9B1DAE4D9D1B937F7E
+:107AB0004ACA14F63800C1B7E95CD58FE695CF41C4
+:107AC0000E9F9E4DF3DC51A434D33911EE3FA0D369
+:107AD0004BFA9AF302A029317E56D5E12BB2292F19
+:107AE000668741DBBF56B05FAD91DF13F31CD3ED6A
+:107AF000C3CDF661D2A5D8BA13E74D17EBFBC0BFD3
+:107B000023108327FF131F329E00ED776A8EE83F14
+:107B100046F2B8D0D99C8A74FBEC95F76D74AE151B
+:107B2000C0FD8CA0F5F67DC07DF0646934DE98DF81
+:107B3000DF6D8F9E07925C6FF9C024D7F1F7D17E7D
+:107B4000333DFD90AA51DCF6A12D329BEC7900DF8C
+:107B50004BF50575EBEC71E78D51BC98CE1775F9B7
+:107B600034F29C4B4CFE98D19AF5C284CC78BB067B
+:107B70001BB3129E2F9AE390066BF057449F86A387
+:107B8000768E5F1A3A85FCA1431D1981F2F071C708
+:107B9000FED76EC47D7C1CB266D6F0DBE2F56DFDCF
+:107BA0000E945F1C2F23BD9358DF7ECEFE94618F11
+:107BB0003E76E2C57109E416AF27945B27B03EFB21
+:107BC0007FA567979C43CF7E2F73889F908AAF8154
+:107BD000BF3EB9EC62F22FCCF435F4AB596F9ECEB8
+:107BE000D012EA4DD0EDBC41C7A5DB4E326ECFE4DA
+:107BF0008AF3A6A62D7F633B86648DD811B74DC14D
+:107C00004FB87F1FD931EEEF9D278D4FB4EF787AB3
+:107C10009AEF5F4CBC65B989DC4C74962D2E8FC8E9
+:107C2000CFA97C9EDF4A7693F4B4A602F111664296
+:107C300088FC0EA9E78F7FA3F799E38AC04C18DD73
+:107C4000CCE7BAB036B63E27A4E8F51481C4F539BE
+:107C5000ADB6E8792EDD3FD779EE715DCE3D4E951C
+:107C6000CB11AC999A9CA8AEC45365491847ACCFC8
+:107C7000147ED608DA33B67FCAD4C4B9BA5CAB274F
+:107C80001A45BC443954D67F692E3E0FB6EAF51921
+:107C900038730E9F1F245B3E4592C0CE7573E72854
+:107CA000941F2EB7DC5E82FDE7D72D9AA3207E3C81
+:107CB000D32C3B8BB17F68DD6271FF524BB915A1AC
+:107CC000FF78A06ECE2CCA1B58DEFD29ED4F59A5BA
+:107CD00000D58F94B47DC0FD3BACE2FCAAE9D95D30
+:107CE000F5F4FE26091981F46F73859AB98E210780
+:107CF000D455943CD676FAE8FEEA5C8CE7911FFBFB
+:107D0000527DDB33C9AE38C22EAD98E24AEFFAEFAE
+:107D1000E17DE588956242DCA7C8838FDD392D8738
+:107D2000F4EEFF85F7EFCD9C78EEF79FD871D57C08
+:107D30001A3F560655C6F9CA14AD8AFA768CAF2991
+:107D40006E33F850A608BA973A6D1CCFB5A5797373
+:107D5000084F7FCA34F875616DAB55F8A572B2C093
+:107D6000819C6A69DE8EED6B3AFF5FD7E9417F94B3
+:107D70001718D89DBD99EB56205248FC95E5CD9D2E
+:107D8000448F488B029B29FFBAFBF14EC2E7EB36CA
+:107D900007E78F6E487DD07A092EB9CC51783B81A8
+:107DA000FF4DA9E34E6A7F9FE57B2F53D4878569FA
+:107DB000DE1B6F96C5BCCEE614B29FE045B91279C2
+:107DC0001AF6DFC18772456BDE8772358154417CBC
+:107DD0009D93791D726A07AFE306BB58C7FC6071BB
+:107DE0006B3FAE63823D7811C557F8FE41C2C18D2D
+:107DF000E86E119E0305D04B7C7BFD964B3789FDC9
+:107E000015B0BCB2FCF3F9FB89A7683E3FCE4FE743
+:107E1000A87EA99FFB3B15871A50857E5F1093773C
+:107E20007B16DA5F2E15F9FD568A3BA6E971B191F2
+:107E30007F33EA0D26F7FAAA9CA4B0E51E99F4CA8E
+:107E400069F4D7488F99F36E534CFA775AF7C7AC59
+:107E500097CF771E9892A5FBBD799047FB08D17903
+:107E60002039BCBA9DF4D0796002F98F390FCCCAA1
+:107E7000BA80F3C03B33455CA1519D1CEE631027D3
+:107E800026BE0D1E5A0865155C8FD00C69E7B6AB8F
+:107E90005D26FD6FE07CDC2BEAADA4CFC6BD02B74A
+:107EA000D07EAFD0CF4F068F03D7034EE877707DDB
+:107EB000A0B5D71A0C4A31F528472D5C8F32089EA1
+:107EC00020D7AF04EC6A80F5E578AE3F693BAA9F06
+:107ED000F7EAF50CE58264FF743D84B9FE61AAAB54
+:107EE000525E50C1E73320550EAD7F982ADF2493B0
+:107EF0005E8143829F67EB20E45299F6753A0C400D
+:107F000021DAA45762F88DFF4DCE0CC85CFE742CAC
+:107F1000FEFA54132ECCFCFF4E966E8F75FE9FB367
+:107F20008EE42391579B00E3B98EC46AAE2379C3D4
+:107F3000C2059BD13A92F220C9DBA41691373E5F6D
+:107F40001D8FB94EC75C8793EB8BA7537EFD2571C0
+:107F5000F72F6A2E8BEB5F7CF7D4B8F1456850633E
+:107F6000FB250FCC891B3FA2FDDAB8FEA80D37C652
+:107F70008D1F135C18777FEC134B13D6BD1838197F
+:107F8000175A1E777F7DF253EF13BEDA726595FCA8
+:107F9000F94BBBEF31D5C54C675C4C35F2F03AFF7D
+:107FA0008DBA3A2A03233A4F44FE3F56447ED3BD4E
+:107FB00055923614079E7080EDF83F8B83874C38BE
+:107FC00030E4FF7CF99B75BADF2327154AE4E77894
+:107FD000D1AF4A9A4675C4E2DC1EDE12F52A9F270D
+:107FE000FD83FD224D7279E0327AAB2A911F7457DE
+:107FF00095C67ED05DC30AF752FEA0FFFB2E8F947C
+:1080000037B42ED45C079AEEF04E012EA115759070
+:108010006DA8E8B95E77A683FD8C872C965B6A63B2
+:10802000D6DF9125F44F4796B05B3FB385B6931EDC
+:10803000501CA0B6E48AE7A9F801A8B207F9E2CA81
+:1080400000511F0647D7CC9A4EF6B37FB49646F53B
+:10805000B3D8BF082F2B41B62737B62A1CE7AD4A45
+:108060007E8AED499922ECC90459D80DB423BFCDBD
+:108070009A4876ED5EABF0B30256E24FBE0302AE15
+:1080800032B6AF7C4E9C0699D2F252AA4F3D6BB7E6
+:10809000B4AF114CFB974EB3109D0617C97C1EFC64
+:1080A000122D09D73B583F86EB9C07CFD6FF69A915
+:1080B000145F0F2E7AE4E49D1551B93C6A4B1CE71E
+:1080C0009D2FEF56BFE991143A47393A1AE2EA3345
+:1080D0008E6509BFF158962CEA13821FB8894C03AC
+:1080E0008BFF6B242DDA2FF5AD76E290FB377CBF4A
+:1080F00096F862EB9A1BA0BCA691C73F1B07F6CC73
+:10810000E0FA6D235EBAE17591D7BBE1BFE2F3D629
+:1081100027B3AC7CFF24BD8FFC9A5EDF44E2DB35E5
+:1081200024109C57F64D24FFA056058DECFE7CDFF5
+:10813000823B0F617FEE8312FBFB749FC65F5B8007
+:10814000F606EFBF0C9E5777E1FAFE9E25D6330F59
+:108150006AADB4CED76E6E4C213CBD9E26C6472478
+:10816000D036C7CC778D3EDFEB372FDB45713ABD7C
+:108170008FDE4FEBA1F7CF55A198FAAF81EFE4ABBB
+:108180004543DF7B1D78AD7ABD9795EC6409043BD0
+:108190009F26BD7AD0E25903DC8633D82ED9D92E5A
+:1081A0000DB4449E5A81EB7C67E9DF764948D7B726
+:1081B00017447EF5345EFF970D3268888B4FD37D70
+:1081C000567756944E47177D9A42F4447F65EB4F9D
+:1081D00049EEB6D93D54D7F1E6D26D2363FDFA548A
+:1081E000F78C616EF2AB2A2FEC3CADEAC9298CBF4B
+:1081F000E55B05FE96FF7A5436E16C79CA59DC8955
+:10820000FED6123E279D2441C2F878CF4AF1DDC246
+:108210000EC4998638DBF385A82BDF7928BD9CD660
+:10822000A780EFE2D8FDEC7CE9C6B15CCFFB46E667
+:1082300005AD93643680FAF7065695002FEA723240
+:10824000BF27A35CF727C7D2FC37FEEED727FF93E3
+:10825000E8B27BDBD61FB28C5C181D86D6D1AADBB8
+:10826000583F197118D5BD529CB6DFC276F20AF993
+:108270005E8EC3A84E83E3AE61853C1E158E6A15E3
+:10828000FA4D7C27817E70AB87EB3D595EEF5685BA
+:10829000DF62C449B2C593A3888F0C5E98C6F317FA
+:1082A00003E5C75C145819FA0AFD08976CD1F51557
+:1082B000781D189F8ED5F559B57BC2556DE2BC2649
+:1082C000CEFFC47E554702BFB316FFB1DFB9D1D789
+:1082D0009AC47669A35C4A7E87D711263B6EF63B2B
+:1082E000A7C1839C0718E27F3EF7D70BF23FFFD56B
+:1082F0001DEF7F5EA8DDA9776BE2BC77B4D073A1D8
+:10830000F0308E73F0AF9CE46B64B6B04B7D1463B9
+:10831000519D9F746AB403E5B3C15DBEF6019449F3
+:10832000C770411FEAB7E2FF97689FEEFF9AFCC053
+:108330003E85F937F8DC25DFF81D4905CA2119FB10
+:10834000F081A95CEF3CD02BE4A3335DFBD3348AEE
+:1083500033D0CFDC8C4B4C52FA6D6909F6F334E91B
+:108360005F9207B7B0478E6E712EEAD0BC40FA25F7
+:1083700049552750606E8CAF730BFBD578E0CD422A
+:108380001BF2E7A4E5908BCE571A76ED70E176E10B
+:10839000BE0CDFFD84EF65478F4C52B9CE6D532183
+:1083A000C5DFA1F09199EC9F552369279C7B3FFE87
+:1083B0000DE5F41102346DC8E0760CE555F0923FFE
+:1083C0002CF679AABB353D517EC0FFFBB7F6D17EB6
+:1083D000B7BD98C47ECBB6AC3E9683C05C80AD483A
+:1083E000EF27BF18CBF32127781D97D46A12D9FB4A
+:1083F0005FEAFBD9A6C797A7BE90799C31EFB8EE8C
+:1084000019B28AB82A0DB7EFE33AAE1EBB46FC4D4F
+:10841000DA02823E3D495C17E6DF73A5883BD3C490
+:108420007974E7B0C8DBF49EC86EBB4675AA496A8A
+:108430003BA4E3FC9D366167C720F07738A3D78D56
+:10844000F725F5ACE78F2010175C8F97A4B4C3B75E
+:108450009CB1F44FE1F586DD02579DC3C21627D9C2
+:10846000098C9536F3BAA2EB047EAFB1CE31EC178E
+:1084700077DA227FA17C3BAE4B255C8C01B14EE8C4
+:1084800019A591BF92A48A73F52455F304A4A1EB16
+:10849000F28F87203A07F0D02A382BE75C47382C38
+:1084A000DA77A02C7416EB7E4C60F1DA5905317D39
+:1084B000526495D1E75F75D7AF6D2BA07D093BA8BE
+:1084C00028213E1F77CD0795CEBF93142FC749496A
+:1084D000F3406B417E253BBC7CDF8D73B44CE17E69
+:1084E00098D6AFD27DCACBA4AAC97370DDA95FA606
+:1084F000F2734D7D56AE3B6FF8C775A9A5B8BF1393
+:10850000967D2B3AB0FD784168249DD356A6FADEBD
+:1085100021BC3E736CE1DA7138FEAF9D564F0DE918
+:10852000A5FEC08FE9DC7EE993568DECE2FD6F0C71
+:1085300086BF26FE3E2BB15E1CB08AFBD8D75AF010
+:108540007E53CF87363AD7BAB2FB5D1BE5BFEFC982
+:10855000F61D27FB56D9DD5245749B02EDAD94E71D
+:10856000447DC8F512A11CA12F065F19B9B9258653
+:10857000CEAE6CFDDC2BE2BB98E4A64797CF3DE482
+:108580001F61BB4BF7D376EDFD97122DE6FC34004F
+:10859000FB381FB80A9EE3BA4EE3FA4050A9261CE6
+:1085A0008D7DCD718B3706678E6C5DDEF5F7FD3CFA
+:1085B000DBF70F96DBBDEFD95CB87FFF9F43856487
+:1085C000AF42E8CF7D531DA9DF242F67EB8E8E03CA
+:1085D000EB916DAF75B3FFBDED1E358DE41ED70F6A
+:1085E000A9D8DF85FE05C9D1AE2221772DAF9E190E
+:1085F0004FF9E233BB975D4CF48AB8AD06BE670E07
+:108600002339DA0EACC70C392C2539C4A597AA2218
+:10861000DF534AF826B9B3F5CD61B9DB6501923B6A
+:10862000C437E31DF1AD921F52AA22DEF9F9512C95
+:10863000C79D7D472EE17A7624EF8809D4B730BEF6
+:108640003AC37382123E5F610DEFA3E72BF0FD2D5D
+:108650005A542E2BA4F8BA9E3AB7A89335F4E3EDFA
+:108660006EA1EF43A3B5540F8E4F96E538FCC7D8E3
+:1086700049D1D7EDE80FD6FF74ED3A9487126FB960
+:108680006512F93B2FCA6C07F6E87EF2F23F4CBD4B
+:10869000A6435C67FB19D671B14FF79B9F5B99C3EB
+:1086A0007DB20B1AF26522B6DE72AAF76EAEA25444
+:1086B0005C6575FB7E6AA7D686AAE8B870FAFCBE30
+:1086C000FDE21B37EF58C25BD7BE6F8FE53AE9A3D7
+:1086D00076A0EF38BBFE1E79FB49DCFF8A3D486F70
+:1086E00048E89730DED06233FECE859301A9FFEAD9
+:1086F00069A897AF59FFF8550A1AF4260202EEBF8F
+:1087000066FDD6B5E8BAC0ABD9DE6BB291DF5FE5E6
+:10871000F8AEC946BA0D1CFEBB9BECC9AE57DE7362
+:10872000911DEEB279C712AEBA8A318E4880C7E980
+:10873000D9A26EA7E21CF526CBB3C5F9D6C800AC0A
+:1087400025BC3475C96A90ECB4B7EF6AB21B7F419F
+:1087500052525EBB6E46C045F152FDAEFD5CA76F46
+:10876000C4D38B41FF936F9A4DF43F9D23E2E3BA4C
+:1087700075D6B8F87614846D748EECF7399BC3C83F
+:10878000927A93DF715BF726FE6E64E996F8E71A3A
+:10879000C84F4108359C273E5E9EADFB29255042BF
+:1087A0007E0AE286F324915765CF66E0FAAA5EAAB4
+:1087B000AFDA6611744A76405B6A7AD45F1993EB3C
+:1087C0005D4272BE44C767A75EAF14E994F87B8A26
+:1087D000314F887879EA716D137F2715F0729D5EAD
+:1087E0003D2D00D73D5509F0FEA7E6944000F75F08
+:1087F00089EA99E4A5AE470A323DF5EF5E14FC27FD
+:10880000F2451B65FECE6FA3041945346F84E9B3AE
+:1088100054CF1F2E7B22FEFCA261C3E103E42A3564
+:10882000864CE7413A7DCCE73B3BE87F129CEFACBE
+:10883000CFD6F308855018F75D5EEF857D97F7B1C9
+:10884000FEBDEA117D7E63DC2E5D6F36E9FB6E08AE
+:10885000CA62DFC80AAA8FBE5587891F3C4CA7464B
+:10886000C409E1001E14FC36EA199742AD8DEAC82E
+:108870001ABB5A0ED0F95B9DEED79AF18404657A43
+:108880002DD1EB86EA37C6DF5FAAD365A9892E4DC5
+:108890003EC9B43EE1775FE8FA50735D4F3858DA6D
+:1088A00061E57AEED37013D75F35766DE2F5D4E9E2
+:1088B000FC1BBADE00EF6709EE87E4E942D76BE6FE
+:1088C000DF9F0C9C5F0297C4F1AF3AE382F8570236
+:1088D000EA32DADF60AF886B077B8B392F61E0C546
+:1088E000FCFC6CDD8FBE7283F0374F765725933FCB
+:1088F000307048F14888FBF2173F73D1F73765BBFA
+:1089000065A073D2819EF2B501D4973B7B875FA7A8
+:10891000A11D287B5161BB51FE625930A988FA65BF
+:10892000C9255C67A265501C80F3B01D1E3834FC5D
+:10893000E552F6D367555088DA72A82C99FC859DCC
+:1089400020F21BD28B1519FD3176E5C36C91DF58EF
+:108950009DF3FE43A4A7AEDC6EE57CF095D6C84B34
+:108960001487EDEC553C2DD86F7871E1AA24E2F71D
+:10897000AF250FB9DD07FA9667D2794D638F55B5EC
+:10898000F37AEFDC47F7031D9267048EF7EFBE62C0
+:108990006C27E58936957B88BCC6FBCAD2B447A84C
+:1089A000DE157293396EBFF2222BDBD71379C9FF24
+:1089B0005183FB5AEADD349BF4F089DFEEE4BA8A96
+:1089C000814E097224CA23EF7F8AEA7D4E3C7DD80E
+:1089D00046E7C1555D87B96EE35CF6E0641071C788
+:1089E000717BBB8DE29BC64D46BF9FBF47A9D5FD9E
+:1089F000A8A62DEF727F29C50184C78D7250C3FFD1
+:108A0000DDBFFB193E1F6EEA10751F67EF6F91F80F
+:108A1000BE81F785BADE5A061AE37D998177BD3E9D
+:108A2000CAC0FB69A8E13AAD651D0F33BE17EBF86C
+:108A300036D74D0134DB4A3385BC52BECDFCFDDF59
+:108A40006D3ABE6F3B0FBEC7E6E8F81E036308DF52
+:108A50006766887ABA33878725D3FC670E72F6F586
+:108A60009B70CE76F790EE170C862D5EDBA5D1714C
+:108A7000A7BA3FE5EF10FD87066D547732BBE713C9
+:108A8000E6474DCFDE5944EFEF80AF81E8F79D9E7A
+:108A90006495FCE09A7EA1CFE6F4D8F97CE23B1025
+:108AA0006A233E0FEC79BC2D9D70F32B811B43CFC5
+:108AB0002DD1E97A55E9F76753FCBE54B78783BDDA
+:108AC000B7CF66BD33018AC8DF9BA37FE73D27A4EC
+:108AD000EBA18DF174A7736AE25B538F9DEB4DAEF2
+:108AE000827E1BD9B3AB74FB69B69303B9C9CCE7DB
+:108AF00000DAAB1138BEA1C35447A9F4F37A06BB20
+:108B00006D7CDED564B2BF97E508BFF27CF1BD99FC
+:108B10005F0B72747BA2F3AB2622EA18E6BC227BC1
+:108B2000E8FCA137BCAA94FC05836E667EF56A2535
+:108B3000A9DFF47B092FE97EBED1BF46FFFE2DA43D
+:108B4000B63B63E3F6833916FD9C33F8D372DCE75A
+:108B50001D12F4110E31BEB9A64C4A18DFDC938306
+:108B6000FAE38F05B73E382136BEF16E1A49FEDEB4
+:108B7000FDA857CA2BB87EA78FCF0B95F61A3A07D8
+:108B8000F377583D14D7F8BB65F607FC1DF6A00532
+:108B9000E7BD927084EBAAED91AE201C61DCB09A27
+:108BA000E69F4B29651C37B71BFD117C6EEEAC4F61
+:108BB000187F07878B7D0F2A5A76A238C2881F9AA2
+:108BC000BE10FEAA71BD09F5008D6FD2BF4BEBDA66
+:108BD000F7B7C2A2143AB7FDBC7001B64FE7083B25
+:108BE0006CF8AB11F4578B757F85EA2EEA04EBA085
+:108BF000EEB97B6CA4BF0ED00F5B50FDA4EA5B4DB9
+:108C0000F1B0EA83E61F91A321B5B11C35914C1157
+:108C10000E7749227FF3AC956A43A0E5C830AE0BCE
+:108C20003CF59A388732CBFBA9857DAC2FCE2C70D2
+:108C30003613DE96956E5A9D4EF2BDE775D63763B4
+:108C40007F6B532D6A745F2DF4DD1DC7696D71FE56
+:108C5000F2A9EE561BE7A163BF1B2E1EEA1F359E2D
+:108C6000278F75D0A45770FDECEF0E1C9455CA0BDE
+:108C7000211D7F91174B2FDD1FEADA97C4F66BE0B9
+:108C8000B033487EFF5F753C9ED0F3F22D9532D312
+:108C9000C33245B463F73C534CFC257EF850DF6F7C
+:108CA000DBF3CC255ECEA307451DF113F175D88DFE
+:108CB000A1F83A6B83AE7E9DAEB8AE91F4BDB2B171
+:108CC000AE5D4ABFCB93408E24691FF3CB22C5C74C
+:108CD000B9FE67E5DAD83A52DCCF2DA4F7FED3907F
+:108CE0001725E2263BFC4E8EC6EB6BE911FCB5EC7A
+:108CF000162DBEFF7A91AFB1F2FB87DC9F1968A0F9
+:108D0000FB678A92B9BE01BE08D4507F45B1F8FD19
+:108D1000801547968E8ACDD38124E271BF35C2F586
+:108D20007EFEC3165E9FFFF0A07BB893F4E2A659C7
+:108D300054477B95AE2F0E1427D713CE03F4DEECE9
+:108D4000E83C4B72C47903D07E73A2DF571AFB5DF7
+:108D500005D7321D56E9B87A4B8F73308EFA222729
+:108D6000411C752EFFF7ECBA75FFE9CC0CEDE5EF71
+:108D7000210ECA0E2A018AD777BE911424FBDFB2D6
+:108D80007BC93B140FFBDFB403F9212BF62C19C56B
+:108D900075F83EDFA5A44FCEECB9ED52AE6394C496
+:108DA000F7A5015A5F0EF953AFBAC94F6ADCFD2A25
+:108DB000D73936EE9AF808F94FE82F5D45D7D18FAD
+:108DC00061FC95BD58C1F8DB79A822A384160E9EDC
+:108DD000649AB7F1A0C2758F8D072B5EA821BFE6FC
+:108DE000C599EC3F19FE5239C5E3E43F1D1C1EE74F
+:108DF0003FA5E60AFA0DEC4DE2FC8704C5023F30C0
+:108E00003C0E3F0D5D7F603FA301F55D2C8E8CE72E
+:108E10004A72159E6754AE8E9F90E4657C6C176D08
+:108E200043F74EDEDF326B88F9DDD26115F73B4543
+:108E30006BD44907203D40F478812E211FE6D8826B
+:108E400005146F3E5F14FFFB4446DB912BF209CF04
+:108E50001F15DF193F3FC3372AD1F7C6019829E212
+:108E60007049A77797B53AD1F7BC4FEAF3B93220EA
+:108E7000EE5CD2687F922BF4EA1C9BC85399EF2FCB
+:108E8000CC35EC0FACA5F398976BACAAF1FB2DB9E0
+:108E9000A877AF06E3CFF3EABC4C3AE7127135404E
+:108EA000FF2CD287DFA53C3FF95F95C2AE1B79FE50
+:108EB000B91BE13E91E7BFC94A7AC1A82F99EB35AA
+:108EC000FB5FB557D03CD7A27DA779AEAB8EBFFF75
+:108ED000DDF3F85D37E6EA767C248C1471853399EE
+:108EE000ECC1E95EAB2AF33E82C3137D5F68E89F65
+:108EF000032BC5F9512FEA456A5BC6BCCE79ABE7B7
+:108F0000F71E7D2A8DF56A121423892FFFF21D7733
+:108F1000A2795ACECAEBBC38FC19FC3A497140E937
+:108F2000507EDDA9D3BDD171C2C6E79BD0FC804580
+:108F30003EF777492D633E6F23793AA97FF782EB9D
+:108F40002BB4C7E8FD93B99FF0FD15332112C0FB88
+:108F50007BC7D8D9FE35CE92F8FCA0312CEC61E36A
+:108F60003C610F4776CD65BE5C8F7CF17A584DBC75
+:108F70004675B906BF2FFF726096114FD2394E0B5E
+:108F8000E19CF57426B78D5DEFB6F17925DA5DF2D7
+:108F90000BAFA98CE7DB28F0DD9785F76FA8963C2F
+:108FA000684186F0FD869BE632DFAFD3BF8F391F65
+:108FB000DFB7E7FA36E492DCF70D5E3F0E49F4FCCA
+:108FC000980F0BC9BE369D03D75B0C5C0F8F3C4DD1
+:108FD000E7659EB3E7E9FF783AF63C7DB8DBF71F1B
+:108FE000B9A4572D5FBA2E019AAFFF17CB25E21314
+:108FF000F0F3E792AB2775B97A325715F9DD4C716A
+:109000003E3456EF3F6F0D16F0F714A517760ED8C5
+:10901000F2EC1FC7939E3BB5F7E0785B0C5F4F2CDB
+:1090200047FD40F666F77EFEFE308A3B8B8E3B8521
+:109030005B49BA56B7A3F1383C413824FDBC7DFFEB
+:10904000D5143F9EECBA2E53D262ECECAE975D2362
+:1090500062E63DA9FF2E06C66D23BF9B12BBCEFB69
+:10906000C4797948CC87F23FF2BA71B1F75B753CAD
+:10907000F7339EEF1FDDCCE7F4069E151078367EA1
+:109080000FE3EC779536E0EF1E037BEC5C5F31601D
+:109090008D14A6C5C8CBC73A9D314E930B32999417
+:1090A0005CEF3A19D655F1390106EF6BA7D0E77797
+:1090B0002159D4873673DDE2F466F0106E25D8C8E6
+:1090C000FD49D5E2BC7C2AF4C9B4AECB20C2AD17B1
+:1090D0005485DA995461866DA52324933AE9ECDA34
+:1090E000974CF80ABB95B4BF3844E96922FE45F7AE
+:1090F000AFC05F0CBCE2607482127EA7EFCE137526
+:109100000E9E64218F9193E2774FBE05FDBCFE69F0
+:109110004A1FAF3745D3D2E9BC64FB73CB65AA7F46
+:10912000D9035A84E4CC93D1CCF9B7C80C086D4E5E
+:109130008BEEB792F6AB46FB53E78385F62B418760
+:10914000D87F33A4D3F9D81408F37B2EA705E37E88
+:109150006780A650DF9157A4D359C46F557AFC6637
+:109160007104B8EE27354FE03A5909CAB9159CDAAF
+:109170000E3D4CE73325629F93F13A9FE3348B75A4
+:109180009FB5D77942DF4D8510F319EA417D817F84
+:109190005C61964AF492C26E0BFD9ED885D275C072
+:1091A0000DBC7ED7AD91533FAC889E7B797AB2B926
+:1091B0001EFA41C91291695D8E02510F1D86107F02
+:1091C00097198EFFBDB392BC6B8BF268BF3EF11D49
+:1091D000AEB9AEF389E066AEBB991F40F2D03C0554
+:1091E00000C7DDD13A006B7190EF5BE99C5DE53A19
+:1091F000D3728A177F9FE52BCACBE27AD3113C99B1
+:10920000129C589B12C53BAE8C7F7F271952DA49BE
+:109210001FB5EAF5B401D5A5D73315F23E34D4F322
+:10922000FC23128AA8EBBEAB4AD49FDE356C0FD765
+:10923000F9F64BA04AF974FEBF87EB80E987E1ACF1
+:10924000F9DF70FE9FA9FFEE43B1EF8DC925BA92F9
+:10925000C7E75A8FA570FDAB32D3AB511DAFB95ED6
+:10926000BCA46DE203FD1C971AEB35D5892B1EBEFD
+:109270007F97AE5F5B1DE27780A45576559A4EDFEF
+:10928000BF2FE7DFB16A25D7A082BE7B5FCECF5369
+:109290001D33158146527DDF257A997F970AE13586
+:1092A000F83CCD9B3A92F37D89F831DDE087656823
+:1092B0009D14F2E166E2AF51776BD4DB122068DFD8
+:1092C000C95EF13B782AE2847FF70F9762275C7AC8
+:1092D000CDBFE721EA7FDB74FAE3BA9EE0BA4F879D
+:1092E000F84EDBF89ED74C3703BFFF0D047C0BCE46
+:1092F00060530000000000000000000000000000BB
+:109300001F8B080000000000000B9B29C3C0F0A3C6
+:109310001E8145A451F9E8F82C9A3C0B0303C34F76
+:10932000209EC7835F1F2E1CCD82607B8A3330183E
+:109330008932301803F14C209E05C43F80D8408C00
+:1093400081C110888B80EC6220F6016207A0DA2FC1
+:109350001C0C0C138419186603F1326154739F328C
+:109360004268252E06065320FEC784DDFEC96A0C1E
+:109370000CDB7510FC385D068635FAE4F965140FD0
+:109380003DBCCD1195BFC70A95FFDC8681C1DE09C2
+:10939000C1DF6B459AF9D540BD354EB8E58FB9A10F
+:1093A000F2F779A0F22DD1E41787416800E6955CC9
+:1093B000CAB8030000000000000000000000000028
+:1093C0001F8B080000000000000BED7D0D981C5560
+:1093D00095E8ADAEEAEAEAEEEA9E9A494FD293CC1E
+:1093E00040CDA443069884CAFF04265033C130AC54
+:1093F000A84D94ECA0A89D1F312ACB6B780A01C11F
+:10940000A9F9EF9924A4F3F342F89134D12CA0AE3A
+:109410000EC87323B2CF4E88BCE0DBA711D12F6AF0
+:10942000F01B621E4FD45D67D92F4BBB06F3EE399C
+:10943000F7D64C574DFF4D02ABDF7EAFF3E1F5544D
+:10944000DD9F73CE3DF7DC73CE3D7547264D247608
+:109450000D21E7E047CB3F780921CB264BABC3C8B2
+:1094600092A5B4FC0A31FAE8A3CBB56C8740CB05D2
+:10947000EA9847D009B9229226C443486CF431E2F5
+:10948000A1F552F532196924C4AFAFAD22EA64BF29
+:10949000EEB2AF9B90ECFCE2EFC523C3513D44FB21
+:1094A0007B6A799749FB493DDDDA65B64CBEAF83EF
+:1094B00041297E4D8462534BC840C35EE28910321D
+:1094C00044C79E4FFF53EE4B90386D27678789BE88
+:1094D00000EA55637DE5D9E39EF5F4F99097748D24
+:1094E000D2523964658314EF85CF6B8B454A8F5F09
+:1094F000323DBFA5B03FEAC95840477417F67B8696
+:10950000D20543BD5BF42C017A281D6D15D2D356CC
+:109510008C9EE72D0BE8B9E290BE289F1EA59ED138
+:10952000A3D4F7E23C9D89527A1A2F849E7B909EA9
+:10953000214ECF908B9EF7717AD6D9F4D40D223D6F
+:10954000830D941EFAC8779F45E2B4BE02F484A04E
+:109550009E939E41A0A7A5003DCA9F879E4F72790A
+:109560004B023DCBCAD393047A6A2BA0474D138D8F
+:109570003EF713C11C6D998A979FF371C1B3E9A897
+:1095800045FB1D7E5BC479A62B32BA76C164BD3122
+:109590008ED7F71A07A363205FF3F64609ED6FB87D
+:1095A00041C0FAEE7E1F2232D6AFAD377BA0FFCB93
+:1095B0009E74F63FDCC0F0B5EBFF139FC77F2222FD
+:1095C000B6AB51E3C3000FCFFB1649C038DE74546D
+:1095D00083768DACDDC0BCE55D636AA1F68C9EE14F
+:1095E000FB2D9467257B0FF2EB730D69A253D8FF17
+:1095F000648200FFE528C3C76E4FF122E44A20FBD6
+:109600002ED364F811329BCE937557D6A2E3C5D200
+:10961000B72B71CA8FE1BA5E05E84EE9BBBA406F5D
+:109620009D89C9446C04BC0AF3C1968B6BC836A5EE
+:1096300089CE67DF2BA23142A6D6B340B86A276134
+:1096400049F5906C33C1DF3902F42470FE07E6ED72
+:1096500045BA65A06B01D095243A7DFE1C971FDFAB
+:10966000B31601B952742B6A2D983A4E0AF8DF02EC
+:10967000BDA6A36BF3E8FFB93DBF745E5DF38B7CC1
+:10968000798898590BF8E277CE9B5DBEC4F97E4588
+:10969000BD85FC2D37FE54FAD9F87F4F74EC87282E
+:1096A000E9683C3489CFB077AC17E49AAE49E3203F
+:1096B000ADB2908ED39EC76FF77813744A69871C3A
+:1096C0007F8BF369D83F7E24BF3F373EDFE5F5BE91
+:1096D0004B342C6DBA161E62E394EBFFC7C0E25AFE
+:1096E000A8EF5A5792E5E0FBBDBCFE15CF3BEB154A
+:1096F000E3CFE727F86345411EEDF5083F732621C8
+:109700005C64F0A72E27E452F83FB4C9EFD78FDD91
+:10971000054BEB1791C419E8E73692B8383097AE8D
+:10972000176FE20928AF95CC7F83E7B495F6FAE589
+:109730005CEE44D4036C3CDA3DA1FD87787F92D087
+:10974000490895675F2BC98C50D4DE239ECC0A94C0
+:109750009FBB0831666979FBFA29B6AFAFD432AB4B
+:10976000613FBF4AA284D0F1AA88E68712EA6769FE
+:10977000BDF032D5A023111FF94855BC80DCF89705
+:1097800012CB5F45C76F951DEBC26F2608E8855069
+:109790009464FD614234211441FC5790150C7F5DA7
+:1097A00080FE6A24BD47A2E388318F71803EAD6A96
+:1097B000232B37E4C9A12E30F9ED89793C40D7201D
+:1097C000D5FF3EBA24C30D74BDC37A88527BA380F3
+:1097D000DC4EE8F79C48B23368BF39816497505833
+:1097E000252B13B45DDA47569EC6718971A0809C03
+:1097F000AD13D8BC0AB1F173E7D02E2099EBD02E6F
+:1098000048E33A96636913F601C50C1B3E98F6B31C
+:109810003B985E93880972521D4B67ABE0BD7E4951
+:1098200023E03B2B9624AFB5B0F2541EBE8A6A45A6
+:10983000D17E6ABC44E8CDDBC70E53F93995276F5A
+:10984000A9FB991D30D038C8F5CCA7507FDAEF3F7F
+:10985000C6F9248F5164802E5DCE340953E53A2534
+:1098600014D6131B39BDF0BB76B9535EA5995C5E67
+:10987000E9103E89A07C0D3D4532802FE5E491F54D
+:1098800014BEFCA84246A87CB590E31E909F856458
+:109890001C4B836822948B8981E55212C7F2F7ED45
+:1098A00054EE69799B49E5BD09E5FF2601F68986F5
+:1098B000C4FC307DEE8F5957C2FE42E57F1D3CA7A8
+:1098C0007222803CD598A4E07E592DB0F5BA53D2CF
+:1098D000FC506FA749503FEE11FA2CD82752DC4EAE
+:1098E0004AF989631D3FC0E94EF1B23A96206330D0
+:1098F000BF745E40AF1F6EBC15D7B14F62F0209DA4
+:109900001794BB556C1F73E3A1C0BC2C38FF79586A
+:10991000F7E79F87416159C179188279582730FD4F
+:1099200029FF9A8D5F823EDCA737F63C8EFC974F6D
+:109930004FAFBE4DFF7297DE5CC1F5DC5564FC2273
+:1099400089EA91DB7D59591210EF2F02DEFFF6B341
+:10995000E31F037AC858623EEC5314EFC704E46770
+:10996000921CA7E34BAF8819F0533CC11B944409E8
+:109970003F8568549F295C9F35C1FFD66BAF07A711
+:10998000EADF4B463F7902ED0DA22446403FAD4A47
+:109990002A20177DF56B1590A3A17A0A83DC446514
+:1099A00045B882962AE904F9B3ED8F17A21B14D0AB
+:1099B000CF723431C397B7FE574713E457B0CEB5D3
+:1099C0004454A474C899EB14A067405BABE4FB5704
+:1099D000B29A88CA54DE86A05F18C79B5404D493F9
+:1099E00064462FE5CBEAFA24F67338DA81F80C687E
+:1099F0001BB0BD4EE26837BD50BFA1B311F68B5707
+:109A00003612D063C5F8E1B6A37D6A92C879FB81AE
+:109A10004F4B12316F3E7D52320B7888D1C2FAF52E
+:109A20000497738F1EC77D85A41F34152ADF5E3E01
+:109A3000D7DE28F999B0306F3E2279FB0B9D8F411C
+:109A4000BFD15568FDD19DC2D9AF21106579E5FD23
+:109A50004EEEAB7C7ED32B526338BFA134CC6F1F4C
+:109A6000D5EFB87F9E0C650E52127A5625F7C37B50
+:109A7000AF2591DE0876D30CFBD9DDE26506C8D9A7
+:109A800003C037CAD86DDD0A9623DD1A96A9EE28E1
+:109A9000960F06BFF0C4186DB7C5F2693E5ACAE901
+:109AA000BBBF01FD51EF3A3E02FD4668FFD0AFA4B7
+:109AB00068073580D9FEE28DB1F2660FE3A3EA09AB
+:109AC00020BE8B3CCCDED68989F292D64AFBE35588
+:109AD000AD4E7B36640426E59EFE176CAE71C07EEB
+:109AE0007DB6A3BE7B5DFC80EA26C0C72BC589D1AD
+:109AF0000265617D7D5610114F515C340E768634BF
+:109B00004BC6FD7F4070EAE7473C6C5FCB7814ECB6
+:109B1000374AC65F3847F9E1D53C68DF84AB9B46DE
+:109B2000B3C09F5AD998478BB0774CAB29301E8968
+:109B300048BF1BCB5BCF4F0966A3E72F804F53E88D
+:109B4000EFE970C875CAC3F6B5B37CBD883EB30BE8
+:109B5000F449948A2141F9D01F073E78826D46333B
+:109B6000E5C340B5AC83DFD3DFE329B8BFB8F92044
+:109B700056DD12053DE8E6FBF35C8E9EE27CBFE617
+:109B8000EC07505F6CD73C9D19D41FC73B419FF732
+:109B90002FF57840CEFF62F8E7A2E3735C7ECE0A31
+:109BA000137420DFFA23CC3EDEA651F981F51C6147
+:109BB000F2A3936C27BE37285DC254BADCFC7BB796
+:109BC000E9B3F95E55ED89675A00BFF138E2D7264F
+:109BD00015C4EF3F8AEF365EEA045E598697F19727
+:109BE00081D7534262BF87C20F70797D401A5340BC
+:109BF0002F34423DD03B41B68EA6EA25C1DDCF933E
+:109C0000A02776403FB4FE0E69DCD18F5D2F047C27
+:109C100060EB22CED685F4675D17365E231C6F9D00
+:109C200064985C371796EB771B2F7B3FED0D5E4DED
+:109C300040DF54AB71B4B367A9F12CF0ABAF56D68B
+:109C4000C1FEA10E11EED7D854CFF3876AD745D104
+:109C50007E09AD43FB7BC01B477BFC58EDB7CCF5C1
+:109C600094AEBEB355C46750BB3F78F5311DF4E2E6
+:109C70003111FDB2BEB37367250BCC7310E26014D3
+:109C8000FF00E087F6B33C616C03BE7D2A557CB4CF
+:109C90009F375B4806F4A95735A3605FF72D508CBA
+:109CA0005EAC1527C0DFDEE0C75A132D53DB07D5A6
+:109CB000C13BC48593E3D09F700E6C5CBA8783BFB1
+:109CC0008EF4098EF705F128077B27610DFBA7B0FD
+:109CD000AE40D782796EEE24DF292DCD12EC9B2485
+:109CE00060C0FCC7E29DBD7F043EBD24A21E74F38C
+:109CF000E75931E113F3E25EDE4802E7CDEEEFFA19
+:109D00005A09F5A8544F323E01468DA31DD957EF8D
+:109D1000C1389AA4AEAD2A695FD757665F131EDFBC
+:109D2000B0E5A1FDD76CDC80C1F477888C11889FE9
+:109D3000541116BFA826BA40B0BD21C43128D2861E
+:109D4000719388FF9DEEF716EC5730779273C169D7
+:109D5000F42BD17EE7BE0BFD96C1D74F1EC57EA961
+:109D60007A889C9B31D9AF379AC487E4ECB973E207
+:109D700072C29AE02F81F22D790C5C9F6476D838FC
+:109D8000488B81C89D0EBFE946B1C9111F95B5C169
+:109D90003B84302DEB6F33C7F2F4837B7E6F82817F
+:109DA0009641BD4DE658057A03CCEE42F1A7413904
+:109DB00091E981FDFB2215E385444A62FC7748A8BE
+:109DC000590CF6B35D4FAA97B380976A9816E88B43
+:109DD000A1191E4334A0DF6DC7C11F20E20D46A2AA
+:109DE000441C49AA977E934FCFA745673CABAF8CE5
+:109DF000BC0F74973E87F0CA46A2903F73BFC8EC71
+:109E0000176FA0F0FBEBE58E7BC56553F9B69DF3AC
+:109E100077A89ABAD65730F1013990EA5F3C017CB5
+:109E200018A85D132D452FD1A89D93E7172D93CD2D
+:109E300021B1341E5BC5DA02F3A752E15959629C85
+:109E400009F94E120DFCC557983EA2F88685994C2B
+:109E50003FB39F01361BF1B6FAB4113A6F811683F6
+:109E60007C99C2D1D54A5C6AA5F42E3D4044785F06
+:109E700027121174ACD866A0BE6A66FE9D49FF0128
+:109E80001DE136D9B16F81FE9CD8B71A41FE9DF015
+:109E90001330CFC1BC79EE3E447E356F127FFAC8D5
+:109EA0002C1417F6CB1D7F57981F3515F163379586
+:109EB0001770C87752BF11CA1DD46F84723BF51B4F
+:109EC000A1DCDA4D859DCA537F7733C2FF0D9AAE70
+:109ED0008473B264AAB111E2A25F3EB1893EDA0D89
+:109EE00038CC866EFD1D10271F01F84A44C71200AA
+:109EF000E6E7292F89FFDE0E719711BF5DFF9FDB1B
+:109F0000B1FE042CF4425C7F24C4DA8F89C10EA810
+:109F1000BFBB81F0F8B9A9DC94E7FF9F11BD287F92
+:109F20006003B1F6BFED81FEFC920DD777401C7542
+:109F300002A67C047CFC0A8367F73774C0B906AAC2
+:109F4000003A5E53FF456CBC792C6E463EB4B60CAD
+:109F50001F7B71FC7570D806347FA8060E8F894C64
+:109F6000E5A6893EDA5DCDF1AEB01F2225D87EC7C9
+:109F7000E347C5D74D997D8DE3517E3D9868BF81FC
+:109F80001EB660DC9F14DEA7DFE971777BA7C717D9
+:109F9000A52D6142F7E1CED12C4CF52E31119668FA
+:109FA0003F55D71EC76D458E6699DD50E1F86F8825
+:109FB0001A8F7F26305E68F35BD298FDD1EE9A4F00
+:109FC0006FC4C47348BFCAD661A5782F8771F2FAEF
+:109FD000215F5B5C57687FB1CBC80D9E49BB8BFE90
+:109FE00057736DC0016B6D3593761CF063E96C0798
+:109FF000ACB6343960AF7699A3FDF9CED7E52E3AE9
+:10A00000749B7F1CAE75C195CB9FA4F3FDCE627689
+:10A01000E404CCF7E572F0D9F94E98F5EB231FAEC6
+:10A0200062760EB3673E4E781D371E469E1E16A101
+:10A030001E83758F406C3B37DB3CB5FF3EE50B184C
+:10A040008F33FB24E2BF7A6ABCCEEA4862BCCDEA19
+:10A05000F5697D118CBF61BC6D0B35E87DB4BCDD4D
+:10A060009BB855A2FC7ACB7F518684A1DFE40A8895
+:10A0700053F7B9E20A6E798A3D7A73C1F331BBECCA
+:10A08000EF6671401B96EA0B9FFB6F9164A4E3257A
+:10A090006F620BAC2349234731CE43ED6C11ED6C5D
+:10A0A00013EDC7C3D56BA260C7A44C19FD1C297D55
+:10A0B0003BAE9707DA3CB85E7A241DF1EA5FD97BA4
+:10A0C0006C2EF8A3BA87737A0CED801DABE43A5876
+:10A0D00037616A8FC27949382614DCC7B64BFCFC5D
+:10A0E0009A7CB4247DEEF9F838CF234A3708786E8D
+:10A0F00067853CC8FF94EA413DBABD4D7E1CFC9F7C
+:10A10000ED4B3D37C3FB336DB2472CA1DF06B9FDE4
+:10A11000B415E2A8B0EFA91BB09F33862753497E40
+:10A12000CEE1556B30FEDD2798CA5C3C5FF690832C
+:10A13000C8B71F60FC6FC7A20ECC1FB02416F7DA99
+:10A14000BA20D09529741E2E85F1FD8EC6F6230FF8
+:10A15000015D542F1F44BF6DFCC4C6089C5F6A8B11
+:10A160004774A0DBF4BC01E3ACF4E0FB7463F20AD7
+:10A1700003E2B66D1E87FD915EC9F8B12342908E51
+:10A18000336DA7206909F653F321387F8D2C9DB0DC
+:10A1900087EAF2ECA1706B724522EF1CC1B69F8A70
+:10A1A000ED4FA26C8C59F4BD7AD287FEAB107E9233
+:10A1B0008810A79E2DA2DF7CED82A3088B6382E12D
+:10A1C000D3216E6F9904FD3D93C5F1EB0979983E5B
+:10A1D0000FFE41C4736112E2F636B7AF34FA0FF6E0
+:10A1E0001D9FEE3C079E625F9D7CE324AC2BF164D7
+:10A1F000F0350F94AD89BF21E027BFFD4D8C1F3D89
+:10A20000D07A67A047986A879D59FA4C7A6E013DCB
+:10A210006197C1B1309EF312F1969276B87AF253FB
+:10A220003F3C9A87DFAF24971DCFED3BBB9F62F683
+:10A23000DD5BDD9B7F7894CAF8062F8B17F965F3F9
+:10A24000B7A0374EF1FD330DF93779F2B3C1CBD654
+:10A25000D11FF8FA8619067F1CFC6798DFFEF67599
+:10A2600038EFC5F0A6FAE00F4C1FD87E38B3E77779
+:10A27000B495F63B26F35CCEA21E2896E7F20129A0
+:10A28000217B97E5E927579E8BBD9E075799244A66
+:10A29000E7695B35C9C0F912B9C6241B417E056266
+:10A2A000F41AACFEF872BED5417E14794F16D6C5AD
+:10A2B000195D32E05C3235EBFDD4A12C8EAFE49217
+:10A2C0009F72F3B9C5359F0D5EE77C8A245E0586D3
+:10A2D000492CAED46D02BDA3CA06AC4FEA1FE8F903
+:10A2E000FE8F3D9F64058B8B896A86141A7788EBF5
+:10A2F000F1A4D7BCD40BFB8D377902F4B0B54A4634
+:10A30000FFD85DFFE35EE6BF0D3612C962792DA866
+:10A310000749A769C2B95F4AD0920F6B887E1CCEED
+:10A32000BF4097837FEF8BBE6EC2BA7B5424C9199E
+:10A330006DD45FF63622FF77ACBA8BD9A1EF2582B8
+:10A34000580DF52DDCDFEA4C4DB0EA26F3CD88D66A
+:10A3500013BD314F5FDFE4657A6DF2BD15BDC9F104
+:10A360009ED9EB83216EFF697DD11B4305DA571718
+:10A370003EB77E1FA7F3262FB747AC3ECC83494597
+:10A380006E3804269B74CD607A3D2D4D2D89725B0D
+:10A3900040BE6F02F9F352F9663B15936FDB5E28FE
+:10A3A00036FF6E3BC1AD7F2A3DC78DEDB9B9E438AC
+:10A3B0006EFF7D90E7BB516977F0C9C7D7F942BE00
+:10A3C0005E26EDA934870DE48B0FFC7D3817075905
+:10A3D000C8B3C776733EFA02ECBD1B0FEA676F0184
+:10A3E000B9F385991F8E8B11EC3AC970CCF7047FB5
+:10A3F000F879E8418E4F2C7D358B0B87EC7CB94A80
+:10A40000F547E93C39AA3F1E28A53F4894C5016C91
+:10A41000FAA7E2C9F814E5F33ED430EDF8C42330CE
+:10A420007E09BEED3F1FBE8DF03CBBEE811F1FE1DC
+:10A4300079094EBD7DE93A8C9F15C393CAF5A8B73B
+:10A4400080DE7E17E7E1BBDEDA0B9F07BB5E51FEC5
+:10A45000F37AFE2DA27E9AEEBB8D928576D4B0BEA5
+:10A46000CB427B0E6885FD3EBD08F3CD488CA07EB7
+:10A4700084869037E5D74DE45F801818D793EB9D1D
+:10A48000784A11E77943B4CBCADAFD82FEF66F91C0
+:10A4900071DC89B896CAF2CC6C3B149615F82D3E47
+:10A4A000F2F9638DAC1DEAFD62F44884E90938FED7
+:10A4B000017BA358BEDB24FDCE71A21F8A97D65321
+:10A4C000AEFA4495F4D70B9C234E6D2791D7F3F445
+:10A4D000DB5BB08EF3F213CC27D77761BE1FF11888
+:10A4E00010EFEC8BAE23094AE720617A2505E54A97
+:10A4F000C83F59ACE13985CEFC3F8FC2E4F125AFAE
+:10A50000EE88DF8A2AF3A7ED7AE5E6FF6EBA3F15FB
+:10A51000B28F2E97D97EF1D61792BF87BC066B44B7
+:10A52000D0C10E3EDD9D43FB6A43F65219F2D716A9
+:10A53000CA33B1DE863D8DF2EA7C7B89B0BC018AEC
+:10A54000889CBF3EED7529A77D4780EE536916179D
+:10A550003995FE57CC0B38B54F443BFA54EA832566
+:10A56000D7D369BE8FDBF54EEF134DF453524266DD
+:10A570001E6D7F5A32C305F308A8994EF2F4DC270A
+:10A58000D2A2436EDFBA3F2183FE39DDAD08BFA200
+:10A5900073752BD049F1DF906E9421FE558E2E48B5
+:10A5A00067CFDF376C3AFB55E6D7F5ABCC4FE9D731
+:10A5B000DE447ACFD0E7A5FCA614A7B35F2BAC5F2F
+:10A5C00094103BBF55BC56E1BC0917BD7EDDB94EAA
+:10A5D000DF69FC8655765E3B2CA595F3C127645A4E
+:10A5E00002D8D11AC9A6203F9FB2F165883360888E
+:10A5F000918ABA76F229E19314AF1FAC574D210A24
+:10A60000F057858B28AC513FC81B05FFC373F85525
+:10A61000BA8E86BB8218471E6CDD7418CC84E83D68
+:10A620009FC5D0D33650F6183F7D5F5F7B0B5F67C9
+:10A63000B4F3CF0C76AC8678A544E23CBEE1D125DC
+:10A64000DB5F2BB0BEF3FC65E19C6FB25D313E0574
+:10A650005CFE908FAC2DAD9F36337D66D17FA05FC1
+:10A66000A2AEF6336F71C6C1359207D3F73B65C210
+:10A67000E33537BEABE3CC2247141DCFB13C5A06BD
+:10A68000EA13AB1AF2A742098980DD3EAB39D10E3D
+:10A69000FC2FC7F761C2F2EA08394EF2D7D5DF7254
+:10A6A0003D547FE79705B0A7CF18540A1601AC2C8C
+:10A6B0002A645FD8F95A1370EBCBA80F0729D61874
+:10A6C0003768F5A0DFBBCD38A5E5AFA7EFF1712660
+:10A6D000E79FE8D2723CADC5F9970D8FE95F78FE30
+:10A6E000F32F4F73FEC39B9D76F074E7E5475C0F35
+:10A6F000959BFF0B1DC79EB7A9EB83E9C3FA3B9F50
+:10A70000C57CC5AD2DA5EDA3A9F37604F7B790419F
+:10A71000CC4C81763F9505977DCE4A8524899177EB
+:10A720000E255EBE7C1FE415151B574CB8FC0DDED4
+:10A730004FEE135412F15C442FF33DDCE81E89EE1A
+:10A7400087C12D57ED919640DE9689F95FC3DD26CE
+:10A750003E9F987F9F87E32B108FED5FEB782EBA9B
+:10A760004742BBC243CE2D21C861DD963B02F53A7C
+:10A77000F7480A3EE5F905B4EA4C6847D06E5D0437
+:10A78000C19E5A3CBFC77EA023A827912E06D38620
+:10A79000006FF59A669CEBE53BE97AD8EAE7B0CE24
+:10A7A000E16A0E6B1C6EE430D9857050A630C4E9A6
+:10A7B000BD690DE100871B395CC3E16A0E37715832
+:10A7C000D885F05699F537226558FF010EEB1CAE7F
+:10A7D000E1B0C6E1260E93036C7C1F8303DE0CEB15
+:10A7E0003FC8E1460ECFE0703587E7725838807079
+:10A7F00051BD1C3391BF93F3DFC9F84608F72FE32F
+:10A800002EB86BB27E9EFF39D0AD0BF9E78ADE22FF
+:10A8100071A7C53EA667C6DBE398BF44FD52EB5463
+:10A82000FE792475A00AC52D4DDE6EE23C3D5278BE
+:10A830005DD8EBCEBD2E2AC56FCD79E2F7A1FF2002
+:10A84000FC3EECB3D73DF3C7C7DB0DC4D3DD9FBBE4
+:10A85000DD08D52F24CFFF0F48190BBEDBA0B60FA4
+:10A86000FA355EC599E77AB7CFCBBE5BF1B13CD77D
+:10A870003E8EDF783B3B8F189817C81C10A6C61772
+:10A880003FE763FEFFF76D3C9551F48F8239BA6262
+:10A89000F3FC9DE1584799FC75E9DFF3F314DD7192
+:10A8A0008F7F8577749C805A984F774FE89B5BAC7D
+:10A8B00053B4AEE2A7CFC16FD122D1FAFC7C6AFEBD
+:10A8C0009E081E11F5CB595ACFCE2311B17F3C976C
+:10A8D00020F52CEE25F2FA384E23FB8EC15C0CFBE2
+:10A8E0000C7DDECCC711A6F6EB6E97F5D5B0F9E27C
+:10A8F000F8D8792B22791EFB99C0478A23BFDCCF79
+:10A90000213F59532FFCF985C25EBDC87869763E58
+:10A9100054AEFD135C5EA6C86791797DC467DB29E0
+:10A92000A3269C23D97264CBD7F9CAD105CB096C75
+:10A93000484B8BCB894592B86E247025174D5F5ECE
+:10A940000AC84936BF7EAD52CDCFF90D94178A8F14
+:10A950008472AB317C6A1747B03F01D6389EB7701E
+:10A9600018F840E9BD5CA9E67C60F18C009C3BE6F0
+:10A97000B5A7C421BE02758698DE67F5AE51D83AF8
+:10A980005FD551CFF027BC7F17BEB43F25BF3F91A5
+:10A99000D4BBE49CE1FDD70A9B5F5A9FC55DDCE315
+:10A9A0004B02E22B92B8E5A1ED3EC3EBBBF5975D00
+:10A9B000DECFF11BF690CD2CCF234EF2BFAB0C2A8D
+:10A9C0001EFEDD235B676EFDE405B95A72FE72550B
+:10A9D000A95EAF550AEF3B54CF37437CB6D8BE7360
+:10A9E0004299D80F9AF9BC4D6BDE7F077A68D9E49B
+:10A9F0007C568AEFE57CDCE9E27B7A2ABE15C9D970
+:10AA00009B5C4F548ADF35E789DFCB2EFCDE29B90A
+:10AA10003ECBF7A34AF1FFEBF394877F9CCADF8A12
+:10AA2000D69147991E7F3F739EF8FDD28D5F917539
+:10AA30002B2B8C5F1661F221A904E33395E2D75DDD
+:10AA40001E3FEE8FAFE9376368AFA13FBE5D59D3BC
+:10AA50006F4993F89984E9F5E98EBFA3E2F1DFDF4E
+:10AA60006F4A93E37F5179BF637C89CA0F085BA566
+:10AA7000E33E56E9B8D64D0EBABF96BAC931EEF9E3
+:10AA8000F2FDEB158FFF5107DDCFA73EEAA45B3542
+:10AA9000304FA4D271FFE13CD7FB6F38BE41457304
+:10AAA000EC03C5ECF7B3DCAEFD84A239E4B858FD85
+:10AAB00037B9BDF2BE0AEB9FE6FDCFB5F12953FFD2
+:10AAC0001E8EFF3D15D6FF1DC7676585F87C9FAFBD
+:10AAD000C362FB6780F33D083A32CFAFB9D03CA6E2
+:10AAE0004DBE84E08773CD67BBF1FBC1372545833D
+:10AAF000F377D249D01EF79F0C1DC0DC4C3BCE4CE7
+:10AB00001296C0F430C6B7BC11239AEF5FD87E9777
+:10AB100024C5CD42E76BD57EA6FF04CDE862EB5D90
+:10AB200026F03D47B1FA417FE1F84B1519CF421E9F
+:10AB30002F89F2F3A2B31FD40BC6FFA57802BFAFD3
+:10AB4000D6647200E2CED5EB1CE7F9311B9FA889D1
+:10AB5000F8C81AC347960CB350FE72839FCDABDD85
+:10AB60008FED1F0AD171C2EE7160F80DF8E35D78C8
+:10AB7000DE5F2D239FFA43CEF3F09B793F7FC5E93B
+:10AB8000EBF796CE1BEB98D9AA40FF7DAD2C6EAEAD
+:10AB90001303CF05FBD5D2F71A6CEB66E78123FCD4
+:10ABA000BBD2147C573A1FF2A4A23C3FEA19FC3EE8
+:10ABB000EF4C8BA7E4FD3821C3193F0F363BCFDDA7
+:10ABC000EC78BB5F777EEFE38B3ABFF7F1CE943C36
+:10ABD000F87D91CAF2B1CAE16FE773D9F586A4A4F2
+:10ABE000A215E453C611EFF7459DF8BE7BFC63ED5B
+:10ABF00083DE51AD105EEF14DF8AC51B26E8AD92EF
+:10AC00009319A6371CE7D4DD5CBE7C554A12F4329A
+:10AC1000D5BB45DE07587B358E790A4A34AE633C96
+:10AC20009AEF030AAC873C3E3D68AFCB80C7CE436A
+:10AC3000C6FB5E04DDC4734605D69130B5DDC4BCE9
+:10AC4000DA72FFF66ACC4FB46A155C27823E8EDF5B
+:10AC50007BB9C799EF3777F96939C36FEE86D2FBB5
+:10AC600027315168BDECF4333DAADC10D79526742A
+:10AC700055D1EE71E3F10DBEFE541B7FCBC473EED4
+:10AC80004AF17FAC42FCED7128FE5F013D4BF1FFC4
+:10AC90002A94C5F07F8AEBA31AA2F7E09EAD333D5C
+:10ACA0004BC88D7A7E7C3D1060FDD6703D4548BB1B
+:10ACB00023BFC4CBE9AA949E43B65E2B438F3D2E9F
+:10ACC000A5E7289F8FEF959A8F17383D8100DBB756
+:10ACD000947D719D2E4D7249917939C5F19819E095
+:10ACE0007125AB7D5A72F5A30AE93835392FAFF2D9
+:10ACF00079F965293A4E72B94A8B64E569D84FE70C
+:10AD0000DA790A6B1DF33287F327EDB3E7A5C33178
+:10AD10002FD5D39C97DF5648CF9CC979798BCF4BE1
+:10AD2000AE949CE5D57F9BD7FF13AF8F76E29CC096
+:10AD30001FFBE1BC6CBE3FEE09D44EEE6FB49E1813
+:10AD4000583659EFC1E163763D1FD6EB9CA8A704A6
+:10AD5000F2FA23D66BFD70AE3DC0BF0BF9FE70E872
+:10AD60003DBC5D18DBDDC0E8A1EDAAF2FBFFC6F03B
+:10AD70002B76FF33A05ECFEA3FD9F522F9F5E60442
+:10AD8000FE64D78BC27361DF447F75F9789CF2FF54
+:10AD9000733FCBCF71E5776995E531782309BCE73F
+:10ADA000A18684D290073B28B17B172C6A541F845C
+:10ADB0003C595F224B2AB0BB3C0A6BE7A3F6167CDA
+:10ADC0005F36432387FD3AB82006D907F9AD11094C
+:10ADD000FD813BFD89A5815A8627C8CBC0ABCC1E1F
+:10ADE000EB5197F2380AC36B67F06329E84FA378F9
+:10ADF00041FF0F06C387A1FEAE065907F93ADC7082
+:10AE000017DA893B7B2402EF775E2FA39DB8FBD531
+:10AE100010EEC3039281F9D59629EB6037DE1DF859
+:10AE2000D3894D141EEBA9D284AB911EC4DFF290DE
+:10AE3000781FF6CFECCE2D147FC80BC6AD0BFAED04
+:10AE4000647E0CFDD541FBBB57EB984FA313767F77
+:10AE5000D350AB8CF9483BEB9BDA61BCDDAD0ADA31
+:10AE60001DBB6F68EAC13CEDD600813C801A5517C6
+:10AE700020EF31BC422616C011BD07ECCED0F20047
+:10AE8000E446929A7A365E683EC17BFEBC241D8FF2
+:10AE9000D1329C9231BF77F70D6B593E69AB4FC3EE
+:10AEA000EFBC2CF3E5D872C25295E127FE23017C5A
+:10AEB000BC734402FCB7E7399C9E685FF21C319C6E
+:10AEC000A9B05EB6B27AA19484F74E95AD97AEB0B4
+:10AED0005EA6C27A5956AFECF93DCF9F54E83F8841
+:10AEE000C3F95DE7B760C797FA5E6EBAF9B93B037D
+:10AEF000CEEFE9CAB5B7F372CBD10B879913788A35
+:10AF0000E5EB97FD1E73E65D51F83E6DA8F65E5EBB
+:10AF1000DEC7CA3AFEBC6E4B14EF8BACE3EFEBEE30
+:10AF2000C3FB23DDFDFC0FAE8F9B49BCE43CD4701A
+:10AF3000FC5FA7B8433CBB592A930F10F1B8EC4D06
+:10AF4000A7DE5324AB03D7ED0D2C2FC707CA00D6BD
+:10AF50004D3D5BC75E928CC7309E658617CD9C5C6D
+:10AF60003FDEB61771FDFCA04E24422BCE0FFB8EA8
+:10AF7000D225276EB9F0B9CEF52F544E7EFA2EC9E0
+:10AF800089372556B47EBCE90AEB652AAC97ADAC8F
+:10AF90009E9C122AD22B72BAC27A990AEB6559BDCD
+:10AFA000819532DFD7870720BEE5BD5271C00357B8
+:10AFB000069CEFAF521DF0E032677B79B9B3FDE03C
+:10AFC00072677B79056B6F04F7BCC78A55BE4EFE6E
+:10AFD000CF79AE9366A574FD506B9975A5687E68B0
+:10AFE0005F23E904EE1DA2FB5586EF5B05E33F6B93
+:10AFF000826CFD5F1FD01CF7D3FDA5D3D91C64F86C
+:10B00000DAF496C3D7D6BFFF57E47657913CFB6A74
+:10B01000D03990774DB275D0EFE13BBE550776E55C
+:10B0200023AFADC07B3DFADE67E7CD1898F7239DCF
+:10B03000F8FECDA0C71E49CA04F2711EAD368E5D62
+:10B0400012C1EFC908D8CBD48DC2FB3E1ED92CA1AA
+:10B05000FDD1775BE97B4DBED1CDF284FE8EFBFD49
+:10B060005FE5F7713DC5EFE37AA25BC7F260773326
+:10B07000965FEA36B07CBCBB15CBFDDD26EE1B5FD0
+:10B08000ECEEC4725F771CCBBDDD5D58EEE84E6020
+:10B09000B9BD7B33FF5E2D89E570F7162C87BA2D7D
+:10B0A0002C07BA5358F675A7B19CFD3707862F5960
+:10B0B0008AF99290A156147FE37967DC61E1B301CC
+:10B0C00007DCF23567BCE1B22FCF76CAC5A34D8E3F
+:10B0D000FA97ECB9CCF13EB66DB1E37D53FF950E16
+:10B0E00058BFAFC3015FF4D9BF72B4AF4BAC75BCEE
+:10B0F0009FD5F56167FE57DB06C7FBF0D24F3B607B
+:10B10000B5E54E47FD40EC5E070CF73EE7D7BF3193
+:10B11000D8C4E2819111473D49DDE5A8F7A999E638
+:10B12000FE20C443D361B42F1F3929E03E38E32207
+:10B13000E3359027F25311E5895CCBF2DE673425C5
+:10B14000AF80FBCB88945CF1C150F97BA4ED788F84
+:10B15000186E4DC03EFBD66B820EF6AE10DE323F4F
+:10B16000DF9FB3CBCD67926414E2923CCF4C9B4DF2
+:10B170004C13FC46AA4F08DAD9C9ECFD18B7F4E025
+:10B180007753692181F74E539BD9F8EF1AE4CBBB73
+:10B19000F7DF20DAE5673482EBA0BD4369ECA7ED69
+:10B1A000B72F90F17BBE29F8BABE8B7923C8FCD7A4
+:10B1B000ADF7B378A576C4DFA82C85FB321233C077
+:10B1C00055B5DBA9D997F0DE5335662C87AB01D492
+:10B1D000E60CD9A842BD2CDEBF40EB7F1396FD44A0
+:10B1E000FD4D594BA6CFEB3627E6C2773DDB79FF05
+:10B1F000DB0FFF8C5C42F91A5A7A9CDC8AFECE5E29
+:10B20000E45FA8758CACC95BBFDBDF2EFCBDD12F22
+:10B21000832CAF667B8F85F7CC29D96FE37DA8F6A9
+:10B220003C045B8E9304F4DF368EF7036FBF9F7D83
+:10B230008FB75DF85134CAE9EA71D285F8001DB7BD
+:10B24000523DA7DE9214D6B4B0E773F3FA85F71B2C
+:10B25000E17DC212205FBD127EC9F07C13E5179D0F
+:10B260000775734628C9AF58967D1FD15C845F94DB
+:10B270003FB7A29F3BE8881BDA7CDADE739C2C6F19
+:10B2800001FB9FD59FE02BE5C3AD797C9CE0C7B265
+:10B290009F627E6BC8FA1159A2B276406F88D2B70E
+:10B2A000B100DF29FFB07F9B1FF63821CA2F869798
+:10B2B000657FDF88F775DAF91F767DF8752EE7F977
+:10B2C00087941FDEB1EA8DF03D687B4B02BF131EF1
+:10B2D000503D789FD080FA4CD6C3E519EA4992D9FF
+:10B2E000FB639E67DE2B145A7F4EFB1F32A6F3BF13
+:10B2F0000BEB57D9BD990391327610BF2F58E4F765
+:10B3000005CB52BCB391AD53A3874CC64DA78EBF9E
+:10B310000BE916A3CE7DB57F93733F8B691FC6F8EB
+:10B32000745FA403E16279F976E9CB31BB51E6F8A9
+:10B33000787341768F71CE8F789AB919585E93AB36
+:10B34000C6F2EADC1C7CBF2A5787705B6E2EC257A0
+:10B35000E51AB1BC3277393E5F99BB14E1D6DC12F5
+:10B360002C57E416E1F3E5B9AB105E965B89F0D299
+:10B37000DC6A2C97E4DAB15C9C7B2FBE5F94BB1E29
+:10B380006123F7412C2FCDDD886573EE23F87E7E97
+:10B39000EE66842FC96D44785E6E3DC2B1DC6710E5
+:10B3A0009E9BFB14964DB9FF8A6563EE0E7CAFE75A
+:10B3B0003E8FF0C5B97B10BE28D7877043AE07E13A
+:10B3C000FADC5684E7E486B19C9DDB8D655D6E27D3
+:10B3D000BE9F957B08CB99B92FE1F3EADCE3586A6D
+:10B3E000B9AFF27BA09FC2329CFB2696A1DCD3F8BA
+:10B3F0005ECD7D07E160EEDB5806722F60A9E40E9A
+:10B4000063596E9EDCDF2F8911E7BE7C0D99E190B8
+:10B410008B5539E7BE7CD57893035EF96BE7BEBCEC
+:10B42000626CB1035E76C2B92F2F39DEE178BFE8D6
+:10B4300098735FBE34EBDC97E7673EEC80E7EDDBAB
+:10B44000E0A83F37FD6907DC98BAD351FF62CBB95A
+:10B450002F376C71EECB7392230EB86EF32E47FD2F
+:10B4600059E461877F58DD75C051BFCAFC8AA37E4D
+:10B47000A8F519D7B94986E979E339C773A5F94819
+:10B48000C1F395D89EEB3D6F803ED13DFC7B7A7E2B
+:10B490004F2BBF0FCD3D9F355C0FCCC831BF28C2AD
+:10B4A000D75D2DACBBBC7C266A3F3436417E08B7E5
+:10B4B0001F6634E94F1FA5F05B4DB2D14361DB7EBF
+:10B4C000B0EB97FD7B14FC3B7D1F7CA7AFA3FD80F9
+:10B4D000F7B7DF7D4AC07B1E6AE6107EFEDFD90922
+:10B4E000FB5A0A6C69767F0EDEE7936AE0EFC9FAD1
+:10B4F000EBF07D23835FD876EF1A88A3A6BC76FB9A
+:10B50000AF5E07718B949FC12F6F5B3F08EF6BAAF3
+:10B510001275B09FEE2D726EF973957DBFAEAAE6DF
+:10B520004B6AEDE4FDD1BF8824FE37C0B729898B73
+:10B53000E12A6EB8BF1EEE67BE56327F00CF3F20B5
+:10B54000993F54715F70FA05EB20A7B516FFAEC4A2
+:10B550002B2ADA4F87703FAA79EF36FCFE3315A20B
+:10B56000F8A8C5F139A68A13FB0DB1F79B268C9379
+:10B57000A29D37D840F0BEF85475DC82FBFBACEFDF
+:10B5800029E4A00174A7591212CF3B4C5DAADB72CB
+:10B59000E1D89FE09EBF0DF47D30A1EA6087A9E469
+:10B5A00038E65584C938961AD104C73DDA36FD0D00
+:10B5B0008C7ECA9771A04B26E6A1317EDECEEFA528
+:10B5C000FE17CE9737D565C5F9F21EF13EA2D1F12F
+:10B5D000F7533B11F6C5FD5081D2F17494FA9D02E8
+:10B5E000E09988B760BFEC7E08FB7E38E9E4B7F1EC
+:10B5F000DE063B8E23896D9DB83DB730BBAF93FE11
+:10B6000003BBAF36EEB423DDDF9948AEB8CE74E3AA
+:10B61000385521771C47C573E2335D1EBC57B158BE
+:10B620003F763CE7E9AED2FEDCD7F97AFA1ABF17CB
+:10B63000E42BFC1CF7497E8EFBB7E0CFD1F2CBE0C8
+:10B64000CFD1F200F873B4CC803F47CBC7C09FCBBB
+:10B65000FB6EE4B122F7BC5C526DE72B6C41BB3D45
+:10B66000C8EFD9206414ED7409EC742A574F1FED0C
+:10B670009D19A37CA7BE06D2B7F9FA0EFC8E9F0EC9
+:10B6800061C077FEB7BFF1FACCFF1281AF6FD9F777
+:10B69000C3B43EE6494A2DEEEF48CA8C2399A81759
+:10B6A00082D41F481BC5F933ED7E1513AF6C9B7E0A
+:10B6B000BFEC3E9FC975D389F924414EB78F7C07F3
+:10B6C000C739C3FD1922D6FF2FCC8FBA4222A5BE9F
+:10B6D0000F9C32CE34E5EFE365E40FEECA44BB3392
+:10B6E000C9E663E173C7EA0ADD0B61CB61CF6B3E4C
+:10B6F0008CAB0E7D8FFD1D8AA30DF21C885F8C1E06
+:10B700007EB111BF5FE4F2D877D4997F509F244275
+:10B710007EBF0F75B338445F84F5ABAB2C6FC14D62
+:10B720008FFD5D53AA4C3EC3837CDCAF07CDFB424B
+:10B73000A80FB378EFE3C2E7948F00BE8FDEA114A9
+:10B74000E4F3D78389FE50ED543CF3DBE33D14C5AD
+:10B75000DB6F0B2D2BDEBEE519E517A474FB3DA5B1
+:10B76000DA5FF615E59132F83F5A187F6B3FB4ABBC
+:10B770008FB2BF4BD653F7FA81AD14DE7B07F38748
+:10B780008FDEBC0EFFAEC3402D9BB702FD3E510ABB
+:10B79000AF85CF757595C1EB1BA5F9DAD55586AF89
+:10B7A0007F5FAA7DCB335D27CAF0F5BBA5F9DAB57B
+:10B7B000AF0CFEFFB3707BEB62D03BF53A8BC7F565
+:10B7C0003452BE523C866CBEBAD643817E5F2E2771
+:10B7D0006F65F0FA79E979292BAFA74AF3B5ACBCCC
+:10B7E000FEE602E5F5CD227CDD0F785F80BCBE7DF4
+:10B7F00081F2EA0D5F98BC86C225F5405979AD2DDE
+:10B80000D5BE02796D2884BF8F044DB0A7CFB4B0E8
+:10B8100073AFCDED1EF6F79134A6EF8327AFC37D4E
+:10B82000B49FEE53335A61BF3EB5F7F6A593FBB311
+:10B830007BFF71F7E7DE3F6FFF973544A5F022BE2F
+:10B84000EFD9F80462EE7E4ADF2F31DD7125FE77F5
+:10B8500096ECF6B337BDD3E339F777E9281B9FD0D1
+:10B86000F157E33921BB3FB7AAD51D979CEEB8A588
+:10B87000EB476FB9307B607DD8793FD49C2DDFDCFE
+:10B880007F3AEFDEB039FC3B2F2FF910DECF446E4C
+:10B8900063F940E296A7F79F5E92774F141915F26D
+:10B8A000F37FC4DB46F79FCEA33B07711F8C1F5B62
+:10B8B000989718D3AEC4FDBDDC3EFE28DFEF1FE62F
+:10B8C000F6EC3E7E3EB1979F4FA4B93DFB003F9FF3
+:10B8D000D8C6EDD9117E3E91E2E71303FC7CE279F4
+:10B8E0007EBEF05CF73E7C7FA83B83E5B7BA9FC481
+:10B8F000F2D9EE517CFF4CF7218447BBB3CC2EBE6E
+:10B90000E756CC839DA4C3E474DC8BF7BCF4D797D3
+:10B91000B6CB1B92CE78C89CCD01D73981F39C62FF
+:10B920005697332FB2DA74C643AA5A2F73DD47EF06
+:10B930003CA708365FE9BA8FDE190F9123CE78C88D
+:10B9400015879CF19005A3CE738ACB9F749E535CA0
+:10B950009A71C643E6EF739E53CC4BDFEBA83F379B
+:10B96000D5EB8C9F58CE78C8AA71E7F9C455BF7E35
+:10B97000D819FF1973C643569C70C643961D7FC6DF
+:10B98000012F39E68C837C2098C8823E5C9475C771
+:10B990004332A84F7FA2B2F33DDBCFA6F55F0CA3E5
+:10B9A000BFA966AFA2EBBE6F33BBD7BD8F687E0D5C
+:10B9B000F5F067D16FF04EDCCF1CCFDE1F99D43F7E
+:10B9C0003BAF3DF553F06BBC21764FE5EDC27559A9
+:10B9D00092EFF778DF12F2CF23A588534F94ED5FF3
+:10B9E00062F7107AC12FD18ACBDDD47EDD7EC9B556
+:10B9F00059C893F2025E06EA1B1C27CF2F1946BFD7
+:10BA00006496444AF9A753C699A61E7AD3A58726F9
+:10BA1000FC9228BB2F4597482FE0B1F7A8A7E0BDBF
+:10BA2000BFB61EDA192DBD0EED3C979D5D95E56301
+:10BA3000EF3C5ABA9E1DBFD2F97DEC5EADF0B9F76E
+:10BA40008B619657F9C12AC2FDE6FF2F3FEFA4FC98
+:10BA50005C59F59F467E78FC72E3107CCF24BB6076
+:10BA600091C3E1AA4FAF81EF9BB610760E445E61A1
+:10BA7000F7AE961B27D6F6D1CAEEF5D398BCC65AB8
+:10BA80005761FE24DE33562A2EE1BA57CDAB5AF069
+:10BA900047F726FEFEA3BBFECF6B58FC28D6F5B1B8
+:10BAA00092F6CD41BEFF7F89EFFF31B3F4BDBB8F6E
+:10BAB00071FC5F787516DAB57B6F637A5BEAFA879B
+:10BAC000C3609F8D72F9F791CFF85B80AEDB2402E3
+:10BAD000E7C373419669FD8B55928173D02DC440A5
+:10BAE000B9A63F3C5FB6FB176F73DA5B7FB0F91402
+:10BAF0002FCD57FB9E4CF7731FF94E3BF25727C9CA
+:10BB000087ABE15AF52FC4FD149E534B10AFD41EE2
+:10BB100003ED2E99E2A11558A76E7CECF5697F4FD5
+:10BB20002A6DBADA82F673043BEE1434204FE78CA8
+:10BB3000AA96BCFF6D4ABFD35C8F5F9BB21E6FE8B5
+:10BB4000FD4964F2FE2BB285FE964FDEEF596C3D47
+:10BB5000DAF00BAF0EE1772D29D5BE1FD0BE4F8B8B
+:10BB6000948C9B6EE57C1FE6F92D5B5B3A7A5F87D0
+:10BB70007353BA5EF2DB05173C8B71C77EED19BCBF
+:10BB8000C7689BC1BED756171D55C01EE8D78EE0AB
+:10BB90007D71C1FA7427DC3718A472043AD03F6F64
+:10BBA0000F7FBF0BDFABF599149C7FA8F09ED235B9
+:10BBB000D2FCCA61F89C3B50FDE6E10EA85F3F7ADB
+:10BBC0000CDEFB3582ED2575F47807C8D966827FD7
+:10BBD0006FCBE2F72A356435CC5BB858653049D075
+:10BBE000F73ABED756537876177B6FA819F4D74823
+:10BBF0003331597B8A1F85A347359CDF996A3A8E7A
+:10BC0000FD4758FB99C6B326E0311C637FCF47ED53
+:10BC1000228F031F16A90C6FF8CE8C8DC3E988B153
+:10BC200071BC6A26DD017AA6DEC693C210378DB0DC
+:10BC30007164957D0F49C7C7FBA67C2ADB0727F4F3
+:10BC40004E5718C73B13218F97FA7B01F67A7F9CDA
+:10BC5000DBF9FBB99D2F2973BE783AEF3E867EFE55
+:10BC6000F7421B55E777987FAC62EBF1C51A9667F0
+:10BC700056EE1E49F259763EFDFF00D7C62C0E0047
+:10BC8000800000001F8B080000000000000BC53D75
+:10BC90000B7854D59967EEDC796526E126992493D3
+:10BCA000D7E426241021E0000141B19D445454D42E
+:10BCB00088B6069F43409E01026A89169B9B172403
+:10BCC00021C0A02E445E99605154D0C18252ABEE87
+:10BCD0008029C5D6B6A9F54195DA08181501532A69
+:10BCE000CAEEEABAFFFF9F7B93B9934982B5BB9B2B
+:10BCF000EFD3C3B9E7FDBFCF7FFE738631C6BECD9C
+:10BD000081FFCD8B61212BA33FCAFB1258283F2C0A
+:10BD10005F9AA6CF7B72F4F98211FA7CEE587D7F90
+:10BD2000CE4B75E55F5DCF58870332A2D7CA0A2094
+:10BD300039F2A0B52496B1BA8C1A2B83EFE7EFD174
+:10BD4000CA991DF3B9528CC09C8CB5960A81260302
+:10BD500063C115350D79858CADCC10189321754DC7
+:10BD60001FE2837ADFE2DF0FFBA6DBAB180B0D6768
+:10BD7000ACA9CA4F6963550B0B59185B953170BB61
+:10BD800000B6837ADBAAAC946EA992A8FDA62A1706
+:10BD9000E55BAA644A3754E553EAAFF2505A573587
+:10BDA00091EAADADF252DA5C3595D2BD552554FE1F
+:10BDB0007C5529E583553E4A9FAD9A47DF77555517
+:10BDC00050FEE9AA4ACAAF1E23DD5E02F0D959A58A
+:10BDD00050FE89AA064AAB2558F77828BFD2E3C29D
+:10BDE000F2DA2B596930CA3AAA2503D55B23012C14
+:10BDF0009318B3318F6006B831C8EF00B80D553CC9
+:10BE00003516C827DFC1088E432B3C356680B33416
+:10BE100085E7D7E138D0AE92312FC376B92CB02365
+:10BE20009BB19C06F69601F2AE7CA9CD98DD3BDE77
+:10BE3000F5EA7850EE12A89C05B0FCB8D97B839443
+:10BE400084FD312A1F16EA1400DDECE2B742350EFC
+:10BE50001867D41B811A23E4474E56044C630BFD2C
+:10BE600082AF00F12A14E338E75608D48F5CC80487
+:10BE700001E61774713A585D04F0095BB7EDFC36C2
+:10BE8000161AC758C38AE943D800784D29157AE9AC
+:10BE900011FE8BF786D13FFCD710120E1A619C73EE
+:10BEA000406F2CBBFF7E2EDEAFEF675430A29FD2D7
+:10BEB00081E73172A7BEFD458188F640D7C81FFDD6
+:10BEC000B51F76FE065A6F7F747CCA5C56258DEFCF
+:10BED000CD8BE77FC042898CBDED90080F09D73527
+:10BEE000BB10CEF03705D72B6630822BA03B540613
+:10BEF0007913FCAB09AA8A0592978DC65456538FC5
+:10BF000097C561EA55F325947FDDE45B83781625B8
+:10BF10001FC3F920D9205FAFBE08FE9986F9AC0691
+:10BF2000EF64C8FF08FE792963374A23A62A90FFE9
+:10BF3000CAE4132A61BC3DD942603BC07B79CE582C
+:10BF40009203B58E81F9B34EE5CF9EF549255E0388
+:10BF5000F4935E2E8D453AEAAFDDA3E5CFBF3E0CEC
+:10BF6000EA294EC19327F72DDFA5D2F1A325C214EC
+:10BF700007C22193D3B1B69EC8FAB0EE5DB86E93F6
+:10BF800093AF3BE996124A73775D632D1905EB8BEE
+:10BF90001F980EB644AC2303060A46C1FB499C1702
+:10BFA0008C93FBC67C1BF53B63E07E1B55B9773E4B
+:10BFB00020B00EC4B35841F236E9161FCB85753553
+:10BFC000A40A0107ACABE19B7B1BB2111E070492D4
+:10BFD0000B49B754305F41DF71C5DCEE6A01E9F20D
+:10BFE000C07C26C3F8165705530A30AFC96B9F01B2
+:10BFF000E7932C495750CA025EEC3F79854FC171D7
+:10C00000CD2E3FC1A521B5A7BE0DBF6F080924DF06
+:10C0100057CAC06F064A9903F9BE82513E23F561A3
+:10C020001A977D0DF39900FDE0BF01C1960CBF1773
+:10C03000E541C345CC8372C496CF8ACCD928A60EDD
+:10C040001B50AED91E609E269C6FEA130ACA23E5D8
+:10C050007246F80605C7107E30BEF526C0677ACB5B
+:10C0600068E20B5B6EC880EBBEDDECEB427C6AEBFA
+:10C0700037BB3A091E0DDF184BA3E1E537AA9CCC6C
+:10C0800044BC45C1476C3C97D75F9982D7A01CDD63
+:10C090009324B0ED86BEF52C6ABDCDCEE97F94E544
+:10C0A0005EFED4CADFC64586F173FA7933CD3BF71D
+:10C0B000963B87E07AFAA383552A7DAD1BC2F540F3
+:10C0C000EEE43BBD08EF73F05F5394792C182253D4
+:10C0D000BD9EF53B059D5CBAF0F989249F724F35F2
+:10C0E000927EFF2A7B607A6D50E7F955A6DE3E10FE
+:10C0F000725B08CFAB5C804F19ED0481C5011C5BFE
+:10C1000055FA804F84DF20E8A726C07FEB8AB3B6BC
+:10C1100002C867BC6D4432017A98A7A01EB15DC405
+:10C12000E941923BBD0CEC9098FC6EA2C78C8A4E04
+:10C1300003A680F7BCF8F1480F1374F47046D59F3E
+:10C14000F057E79AA08A3299F8BE201EBE7B77C1CD
+:10C15000249CC80F7C7C13F32A669217952C08E365
+:10C16000DADF32D2779861E8A142945382A7C903FB
+:10C1700074D05E938C7C684FE2F265DE35C524BFD7
+:10C1800000049E4D30E6E24FBB929740DEE3E27240
+:10C1900019EA5B719E628159A737061D47F48670C4
+:10C1A000FD7603F3F83DFDC3FF3BF76BF532948F4B
+:10C1B000DFBD5F10A4C968DE7138323655C175DB4A
+:10C1C000D5755BD8AF689C73380EC2DE98F13B849E
+:10C1D000AF78B1C88C51E8B5DF718C770CA83F2AD5
+:10C1E0008FCEFF637B58FDD9F1B1CE2E9804BB846E
+:10C1F0005DF22D128ED12120BFA21D40F607F20064
+:10C20000CCA3BE82E363F44B8753C3E9FFABAA79A7
+:10C210007F6C07A5B947D5FBD51F5A8AB1FDAA5F28
+:10C220000B010BB46FCF34A777C2F7E08143D93845
+:10C230002F4D3ED7B6EBF57C46053384F7FB98CA05
+:10C2400017B54EDEAFECF058A3F1FB5AB55E836331
+:10C2500060BB61A33AEEB3766F753CD175C880FCC4
+:10C2600039FA25EBED38DF2D4BAD51E1FCACDDD7D4
+:10C27000189FD4779EE1ED118F03B45F3F50FB828E
+:10C28000E7ADEFB381DB3F163FBEFFF6239EB66EF0
+:10C290001E64FE6DD1C7575AB15D86CBCC90CEAB34
+:10C2A00053BBB6AF86FC86A5668F05E8B37DC68F07
+:10C2B0005D88B7FA248EB728FDEE1A685EA35F2A60
+:10C2C0002D1D645E7B076B3F085C5F1E18AEA547A3
+:10C2D00006816BFB40ED473C5DDA32C8FCDF883EEF
+:10C2E0007F250BE54E866C263D539D0D704539AE7E
+:10C2F000C135821FA2F4FBEEC07019945EFFF63DBB
+:10C30000E9F5E381C6BF007AFD7C60B80E4AAF5FF5
+:10C31000F547AF38EFEF41AF42C2807019945E63CA
+:10C3200012BE1FBD260CD4FE02E8356DA0F95F00D9
+:10C33000BDE6441BDFC2EC5E05EDA202AEC7E71509
+:10C34000095CAF4B5CDEDB8F5E4D7AB40EF454E2D9
+:10C3500044D4D7C7362C2EECD5CF91FA27B2BF489C
+:10C36000FDB9F8EF57919D3B46D57BDA7C6272238D
+:10C37000FBB97D40FBEEBB8E2BBA58C816D7DB3E0F
+:10C380006DF6BF7A3CBD7E17DBF9F80CC6BF6222A2
+:10C39000EAD5691E84F79089669D5DF9DDC71DB8F1
+:10C3A000BEEB8EEF670FCC49007B6064AF3D905EC3
+:10C3B000F98BD61389BDFDA48B254C72A0BD778B5C
+:10C3C00017E9829533CF0E2CAEDCD37A625CAF3D99
+:10C3D00000F037DC14B66F3496075B4F84ADFBFC7E
+:10C3E0006CA6EECF14B27773A54B49BF0FA6C7B5A5
+:10C3F0007DE326F44F0D477F94A4FAA35CAA3F4A3D
+:10C4000056FD50DC3FD58CFE29F2834DE47682EA5E
+:10C410009FAA57FD532FABFEB19754FFD8FEAA0039
+:10C42000A52F54EDA4746F5590CA9FAFDA4FF960F1
+:10C430005588F2DB1E9823233E7BD7E155D7A1F91F
+:10C44000F506B6FB332BF47E90F4797A3F482AFA4E
+:10C4500023C3F229E1FE4886FE9B1C5DF9908923E7
+:10C4600074E5B19EB1BABC3DFF525D7D9B5CACCB27
+:10C470009B9DD7EAF217EF9F1EE1E7B94D573E7239
+:10C480006759841F6781AE7C78CB325D3ECFFFA0B9
+:10C49000AEFED0861A5D79B6D2A42BBFBCFB615D1F
+:10C4A000FEB24F36E9EA4FEADCAE2BBFE4C8D3BA9E
+:10C4B000F2F11DCFEBF2E30EBFA4AB7FA3DDF76B70
+:10C4C000948763420723ECF400C9D310C80ADCFF49
+:10C4D000B857485778A3E0F1BF86F07D2BD8ED45DB
+:10C4E000642F833C6B1A83ED95121BE4D37F0D34CC
+:10C4F00027E396DD676043216DD7CB1F63F977E3B0
+:10C500006BF400607D37FC215FFE97B6AFDD6953A9
+:10C510007E80E3FBB83C56A4008BD64FAD6AFFE6A5
+:10C52000EE9C3184E8532A96A2C985E366DF27E1B1
+:10C530007A4674E8E934D71BCBBC385EB9E637E3FA
+:10C5400072CFC8ABB0F4A3571F36A09FACF4D57818
+:10C550009CC73675DC06955F57229F0EC7F55E16A1
+:10C56000B2A870DB04F29919277B06925391F0FA76
+:10C57000AE72CD90A8976B208F431FA1FC2E17039E
+:10C5800003EDAF347996FBD6DD03E24783AF8647F0
+:10C59000A3245D81F2C196ABB032475F3819654E76
+:10C5A0000FFFDBEB9623D67D8EBD5CE4C5F309E679
+:10C5B000894A273DEB2DBD8BD6A1E133B2DE0E5566
+:10C5C0000E3FAEE2B54D95C342B347403BAC5595E7
+:10C5D000C7C2A3DE1A84731EECA7713F686EAE0853
+:10C5E0005901EFA60C467AD2E804388CEEED77D8E4
+:10C5F000A37ABF4B6EB35E2EE6D425E8E021AF48A8
+:10C60000FB4EFAB42FDF5D46F68D468783F11F920D
+:10C61000FCB743FF99712E8CBFDB672753FF0FAA2E
+:10C62000FC0D1CCD5385BD89F4533651252026DFE2
+:10C63000FA3EC075FE611343FFCE0FBF6E3DB415C9
+:10C64000D6619C6891D0DE014D78E815289FEDB544
+:10C6500096607EFED151663794BF930644E0C2F2E5
+:10C6600092389403A7993015FD77A7D99B71E3C23F
+:10C67000F4EEB244331FB7C174ACD38AC32B748EAB
+:10C68000758F9FE7B575CD6DD1E7E7B0E9C9228C0D
+:10C6900033E751134852189789C73A353800FECB13
+:10C6A0001225EA772EAB58897644BD89917F71D1E6
+:10C6B0008BA3CC683FCF1F27651BC7F4CEE3C144D3
+:10C6C000EE673C09F42687F98B173802662FB43BD6
+:10C6D000BE77DC8F2F63D84F60651AFA3BE3C11E2B
+:10C6E00091FBC27756837E9E83AD2372DE8CD590FC
+:10C6F000BCEF6F1EE24E833710852F1B12B95F5DB2
+:10C70000C363ADF567AD9D304F6FADC86C3F80BC66
+:10C71000C8CF9994A3B1811D28BF8B2B9EEC44BF39
+:10C72000748D45AA8574A3FD67CF61FD4A4018CA80
+:10C73000CB3D8932F7ABDADC013C7F60ACE292E9B9
+:10C74000B1DFBFDF17B0DFA47F7DBFBFEA67BE8B5D
+:10C75000AC9D66E4FF2562C55483807E453EBEC520
+:10C76000E4F3A6A33F717F51289DE9EA355C60BDE3
+:10C77000C3869C0BAA375518A0BF33AA7CFBCDAE4D
+:10C78000C7CD28CF4E3FFDE10DB82F5AF82B23B36C
+:10C7900042BD33BB625988ECBE8019EDBE057B8D6E
+:10C7A000DE00E543136E8E0DE7EB5AEA7FE173B1CD
+:10C7B000B4AF5AF0BC25300DDA2F78E1F86806F2F4
+:10C7C000E04C4DF7A17484DFD306B2A399D239FAB5
+:10C7D00066F8BE4064779744B1833F48E476C7A9C2
+:10C7E0005FDA4B91DE0C3B0FDC45FD066F3559C21D
+:10C7F000F4D8DB8926AD1EF9BD95A70C813C039FBB
+:10C80000DF4DA3C2E757CDEB3DC5FDB90BF69B024B
+:10C81000369CDFCE36B30FEA2DD9F977A2EF2B9EE7
+:10C82000DB1D877058B2DFA8936B0B9FFB66E5A5F5
+:10C8300080E78546D63D8DF4F8D7943FE7B5761B63
+:10C84000490E79E30C20B71693C8827ABFF8F8AA8C
+:10C85000F7A1FCA4CBC86C200A4E767C64FE15E6DA
+:10C860007D8E0A5049D0BF9E0F97EC3C6EC6794929
+:10C8700002EBCE0046FFC117617CC9FAD667ACDB7C
+:10C880008C727649B0F1EF46A0B7257B4FBF877415
+:10C89000B724829F4FE23F52FBEA4BB333525FBE55
+:10C8A0003101FDE66C276C8226F5AF2F35FE5EB8B0
+:10C8B000FBDC3605C63FF5FC67DB144079F97FFFEA
+:10C8C00063DB4F61FEEC559B847269C9D36FC7B1BE
+:10C8D00030F8673BF939D399A79E7C6213C0E1CC4D
+:10C8E0005F2C04B533AF7CEC96D10FBFE73F92F1DC
+:10C8F000DCE9BE57AE4C413ABB6FDF152903ED2B87
+:10C90000906E039670FC0608BFF27E182705B22FC2
+:10C91000AB69045E4EEDF9CA8CE7095F1A5837CA55
+:10C92000DFC5C16FCC78FE70C8CBBA114EAFED3DFC
+:10C930007EE841C89F063C59A2E009D69F2E905E32
+:10C9400001F68174F1DE9B6FBCBC10539347463CEB
+:10C95000B16E92F77DF0FB16E0B7B017BF91E5E737
+:10C96000D8D76684FF925D80CFD18857C0E7E8BEF4
+:10C97000F83C8DFF98D4179F5EA7DEBF7D8E95B7DC
+:10C980006EC2C2BD8984FFFEF0B968DF8F06B4B302
+:10C9900034F930189CE719F8BC1C4E6F893309E94B
+:10C9A000C2AEB8389E03D3A0ECCCEE736E0674F220
+:10C9B00089A9FB2E8443F72B1609CFC916BCF22E8A
+:10C9C000F1DD997D7F3223FEE12FCE3001F2ACE71D
+:10C9D000EF4D06F9C5DC06678B58F755EF1562CAAF
+:10C9E000BA150FE18FF287800F091F819BA6CA2815
+:10C9F0007F0349B4EEC501CE1F8B03076E318CEE69
+:10CA00000BF726A7A0E9AD1EBC1A26223E3FBC0AA2
+:10CA1000E9AF3F7C6AEB9770FD9740F9CFF5FC1BBF
+:10CA2000597F31F02BEE8FFAE03770E00F989E6956
+:10CA3000B38806B085CE9878BC4724DE7BE1CFF57D
+:10CA4000F377B58FEB9C91FB02DE5E83D360FC3EF7
+:10CA5000D8FABE2BFC963965EA37128EA7BE8EAE89
+:10CA60000F02AAFC58CC2AA6A60DEDABCF4456A2C5
+:10CA7000A467F7CE7765D04872FED44EB0C70D7D5F
+:10CA8000E5C5E27ECEE19F75723B66F1FE03A351E0
+:10CA9000AE9D3AF84B952E39DD2FDEF5A15951F5B3
+:10CAA00043205C3EF7733EBC5F9DF79297A3F7B7B8
+:10CAB00064D7DFA3F67752F4DE8AF33FD961620AC6
+:10CAC000747132689C1ACDEEDAEE34E9ECE795B178
+:10CAD000138E0C8176C6B81819D75D5BE37D57417C
+:10CAE0003BE64D139DFF33D1F38905CA6B63636445
+:10CAF000F4E7D5C6CD6172981EAF8B8093E82AA16A
+:10CB0000F355D15952C8F77401DD39B00908227CB8
+:10CB1000DEA07733502F7D30E66313AEF36F1176CE
+:10CB2000E4DF44B63205FAFB9B62F054CBD1F60742
+:10CB3000FAFE7D2B8C4C0EEB7FB1A5FB03F2C7FDFB
+:10CB4000BB8DA15D667CD5664079B2649B89F65D3C
+:10CB50004B601B8570FB78AB2DA0407EE32FAAEEC7
+:10CB600042BDF4F9360B9EBDB2D7F62DEF7A00E543
+:10CB7000D26603437FFAE7BFACFA12F5F2FC2D460A
+:10CB8000DC2AB2B9F6EE27B0FDDCE7D2592DB4FFAE
+:10CB9000CC109C809BD9AEA4D004DC8774ED4EF5FC
+:10CBA00028D4CF8B8BB1DF33CFD9A9DF33FFFE2E53
+:10CBB0008D73E6DF6349AF69F3077B5B0ED7E360F4
+:10CBC0006FCB3D7C40F41A96877116629ED7377CF6
+:10CBD000ABCA3C947F0B3105BA5FB87F8817F791D9
+:10CBE00061F5A89F2596EE9F7868FFADA409B477FC
+:10CBF0000AA5213F2EDCA91FFFBF5579B7C4DC3D34
+:10CC000087D7F7A771BEEDA076F624955ED5F2C85A
+:10CC1000F65A7D5B528EAE9ED67EB1855544E38337
+:10CC200064B5DF853BBF19AEEF4F51BF478EC3BF21
+:10CC3000DF6F600AEA67B6C746F169E5E6D0B0047F
+:10CC4000E0DB17CC6C1EF26F795C68583C8CF72BDC
+:10CC5000556E96C7401EBEA7A9F3C0FA9867D6CEF8
+:10CC60003388D7452FDAE85C65D10BEF7E89F83C35
+:10CC70008530068C9D4AEAF8F2A74007A7B61A99B4
+:10CC800002F6DA224BC8BD19F5D41E0BDB8EFCFD73
+:10CC9000EAEBA4B74E3F6F11C2E3E222D34541A0B5
+:10CCA000066BDF7528C52CBF02E6A3ACF70A6DB88A
+:10CCB0006F386C0C54C3D895A2B7E6395CDF6113AA
+:10CCC000ED33CECE66F9B8AF3CCBD23C0AE15F7E05
+:10CCD0005784F2E5BF35199AA28C6B3A0F4A7F1C34
+:10CCE000F0C1F9EB983C0EE3C08652BADC5C311C13
+:10CCF000E5AE5182C51590FF81EC7693D3C3E64231
+:10CD0000BA3C81F9107ECC716D0F7FFD1150BAECE9
+:10CD1000313905DBFD2089DBD5F393BDD726917E24
+:10CD20007448A43F543A55F6F1797E6588F154630E
+:10CD30005CCEF907EF46F82EFBD02087C79DF4C6DE
+:10CD4000837A28EEAB5294DF950B69BD248F72A5D0
+:10CD50001886703D2B0974BE7076B63C243E4C2E6E
+:10CD6000AFAE92487E3456B9285D5595CF64F26BCC
+:10CD70007B286F54D76F29509811FA419EC63F8B7C
+:10CD8000A3C48B761ECE09E3828C0E1FD111C6354B
+:10CD9000A11CB33A18ED638D0E85CD453FBF83C30B
+:10CDA000C7E82821F898D5BCD8328DE009EDE9FB19
+:10CDB00094645F4512E0D39A31422797CCCEB1BA42
+:10CDC0007C1F7869F8DFFD7F053746706AACB25288
+:10CDD000BAAA6A22C1ABBECA4BF9FF07B86DE470AC
+:10CDE000BB94C75AF4C0AD5897EF176E8F01DF3868
+:10CDF000C3F906E0887CC3623C3BA2AC3F32DD5005
+:10CE0000C528F8E6E1AA164AB5EF09FDE8ED2F932B
+:10CE1000B81D50C97CD5261C47E2FE16E65458C6FC
+:10CE2000845EFF2673294CC63CF22AE2E5480CC119
+:10CE30006ED95F6DE437364A6257B85C5B76BD9C4D
+:10CE400082F2CB58F9383B9E18E6479B566293090D
+:10CE5000AE1E3AAFAC55F5667D0FFEF47CB0BA4A13
+:10CE6000A6748DCA0FEB547E588F78C6B8130F3F47
+:10CE7000DF6C9ECA482FFE1BE4F93E3EC4C2CF9D24
+:10CE8000E23DC19009F04D3252A63444F1C0472C26
+:10CE9000813C68672F605EA48FF8230F90FF1823F2
+:10CEA00074D19F16AFC28DBD9C133F23969667E247
+:10CEB0007A871979EA37A13D1E09D75ACF412BEE5F
+:10CEC000AFFB9B4FD107F30D38DE5733084DCC79BC
+:10CED00047F008C6AB3A9AEDA457933D1559E8DFE1
+:10CEE00063472D449F0E8FCF30370C7FC9FDD87517
+:10CEF00095C9D79C40FAFB086D25C0EBC32D436D47
+:10CF000008E7D5A6A00BE5DDEA78AE3FE45280C283
+:10CF100025BDEDFEA0CAC1B8423DBF6BF2559A3C9B
+:10CF20005647BF9A5C4D98A2A7734DAEEE4FE2F6FE
+:10CF3000DAFCE4922F51AE269EDF427C1849F7B905
+:10CF4000D2A5A53E27EA01E669427B0D6D46B4E312
+:10CF50003E340438BD73FFD4D9CEECED68E7C0AEE3
+:10CF600080E48A82FC4078EA7EED5B68B75B950FCF
+:10CF700035D6E9568A73043A6214B72E1380F1FC51
+:10CF800090A9F1ED9C3F2652AAD1676672B62E5E3B
+:10CF9000D0987B48407CD5831D4171C5B0BF73E0FC
+:10CFA000F9F8814956B4F74493E730CAA9EE5821FD
+:10CFB000887AB3DE31DD8AE74A86F842C2FB97B150
+:10CFC0006559039D7B82DD427E5BC9E161C7701CB0
+:10CFD000C6C86F6B94C632DC27EE7674C4E0BEC55B
+:10CFE000912CE8ECC4F9C9BE9CE4B0FC281C5DC5DA
+:10CFF0001776BB5BED2772BCD1C9AADF324361DE75
+:10D00000B0738B4A8DBE65854D09E3EF9ABCAB5872
+:10D0100067415FBEEE576EEDF87E72AB362B40F87F
+:10D020003245CA0B27C87107A58A0028352A59AB93
+:10D030006F1F4374558C70608EED3D76C80F73A2E0
+:10D04000D0D791112914B7D9A36760D75C407A660D
+:10D05000E3446E8FA87A86EBA7B3CD76D24F67678D
+:10D0600057503CD5D9E61419E9EEC0DACB46233C3B
+:10D07000E69C6F6432CC6FEEF94994CE6B7984D222
+:10D08000B296362072C6AAD7CC5D3B03DA1D7FCCA0
+:10D09000E841BEEE0A8C3B5309F9AE660B9E11B116
+:10D0A000AE2DF766A15FBC0BC641FBAA6B4B1ED130
+:10D0B0005717C08DF20DFAFA182F6C04BC9431A6E4
+:10D0C000C619CA5EAC3FE775635B343BA96C9DC56E
+:10D0D0001BED7CA7A7BC25BADD568BFF4CC5FF55C1
+:10D0E0000C4778157DF04016AE57E3FFE509208F19
+:10D0F000105E1F5858347FFC94E42B17223EA62460
+:10D100007BEFE5784988EA5FEBA57F3EEE7101ECA5
+:10D110005BC28B2FEE269D9F95FB318FABF62FB315
+:10D12000F6531EA7B697A2972F6AFEECD043905BEA
+:10D130005550518244AFEDA745C6F7D38BF7DFA416
+:10D14000C6F9F3F9809D4A74CC001F285F66ABFED8
+:10D150001E80FB8D78AFE4F8EB4603D2472F3DF9F4
+:10D16000E2D06E31ACBEBE663794FFE330DF9FCDB8
+:10D170003FBF9EE49D61F5A88D93E0FBBDAF9B484A
+:10D18000CE57375DB6EE0EC0EF176F18293FEFBCD4
+:10D190008DEA7DFA9067E31D50AFFBF726B2C3BF5F
+:10D1A000387C25C54D7C6AD2FB092E4BE17CBC5FE7
+:10D1B000E5E739E75793FDA195CF69986596894EC4
+:10D1C000D7D2F739786883C1BECAADBF2B12F13C04
+:10D1D00087D1BD85FDC9B75C57437A6D2CD9FB73E8
+:10D1E000D7583CD1E2A8F727CB3AF933B7B399FA2D
+:10D1F0006560173993D5FEC2E4C8DCF389C4074CD7
+:10D200005218C619CF51E549CFFCB69874F2E453D1
+:10D210005B743FC8E164BE8F9A73FE32E2AFBEEB2F
+:10D22000FB017D9FA38DDBC9F9B1773D1B27455BD2
+:10D230004FEF3A2653FD4FE3A38FFFB93A7E57D500
+:10D240003CE605B95466817A0E1CFFDE95130B711E
+:10D250001DF10986B075CD6D59C8BC61EB9ABB65EF
+:10D26000A6B92CACDF5E3C2CFD5D516E2F1E3EDF5F
+:10D27000507E5D0DCAA3E492F7916FCA565F3E1AC5
+:10D28000E9716E4B23C1F9B8C9E346F9FA71CBBD18
+:10D2900071BEA8F394757A6B6E8B8A1FB0770BC33F
+:10D2A000F0A3E125B27DD75FE77EF910CA9FC7B82A
+:10D2B00071D31FBCFAE02D3B3ADC6C291ADCF299E1
+:10D2C0008FE026BF7004E97A8DDD8374DD3FFC4674
+:10D2D00032DF40F0EBC77E057B474849C27119D168
+:10D2E000E9DC164E0783C1AD775C950E8AA2AFE7E5
+:10D2F0001295DFBAAA2A99020C7BCC3C181DFC942B
+:10D3000029D601D6D14307FFA6A3834B52D6101DC1
+:10D310007C82F6CAF0BEF83F6656E22EC5739F26A1
+:10D32000239D2B1D8B51926FE3F931288F8FC5F907
+:10D330006FC0731A2D3F7F475EDCCCB0713F6E002B
+:10D34000384481DF252911FCADD14FAEC20A26FC3D
+:10D35000EFD1CF71F59C38B2DE94E4A2CB52507F6E
+:10D36000F8A3FB6BB55493D7C6218E9E7D26EACFDA
+:10D37000638E9C2F0350DA94ECBB1AFBA98BFFC978
+:10D38000DD280F8E1D3390BEADFEEBF2E1A8D72253
+:10D39000ED04D87F36E0B9E77263AC9FEC50B1A2E0
+:10D3A00095CE411591ED28C47D4AC5A61379E8377D
+:10D3B000ACA494A976E872E3080FEA6123AB781273
+:10D3C000CF49814824AC2FB20A3A3705415882F937
+:10D3D0008D767EEE5A295A254B585CC252955FEAEB
+:10D3E000AB4A1E39817E68ABC2A4F0B843C6EDAF2C
+:10D3F000FFC47986E97BB3C92779701F6A6025C8A5
+:10D400001726D1D7900DFD9B5CCE314A181E96A4ED
+:10D41000F0F3765B7B7B4336B4B7DDF37B89EE1D9F
+:10D42000C138E867B3668867C3FDD5266790EE0903
+:10D43000B1DCB0EF6057390A20AFF303C07C07B00E
+:10D440000B7F65F0B8BE447AACE6F098882082F491
+:10D450002FB387B6A15C9E28D61931EE68C63D79F8
+:10D4600094DF38EBDB619D51E861C6CBAB3AD09ECF
+:10D4700099F172EA2C3C3F98E118F611A6B05DB024
+:10D48000C640FBD70C2CD804E914EBE314D7F89A68
+:10D49000EA1F6BC77C985E6C57E90DEC9CA97B205A
+:10D4A0009D61F59B9616F4FAD322C7DDA0E2A5DDB7
+:10D4B000144C1A817400E3E03AEE7C39F02350FDFD
+:10D4C000EC8E60E0FA51809FBB58B709E1E8631227
+:10D4D0009D7B687EDD32E651F38CF6A7EF979BB615
+:10D4E000239D44F6774788F777673BF407E95D8724
+:10D4F000BB7F8D6AD91794AEB2B3B0FEF67B0ED95E
+:10D5000059DFFE22E1EC11AD46250CAE8022211C34
+:10D51000EE7DE03BA4F45A36BA7F3EEB85379F4759
+:10D52000243EBEC022E0D3408AF77994C35529DE59
+:10D530005F605A6EED768B4037EF3B7D2F221F2EBA
+:10D5400036FAB292011EA7337DC393102E1DD1CFA0
+:10D550005F23F93BB7F4F456E49BBBAA4586785E9B
+:10D56000B9EFE3ADC897A74DC047B01F78ED818FE5
+:10D5700063916E16010386CB930F2AF3C87E3ABBE4
+:10D5800077F880F1A71FA8FE923FAA7CA2ADF36EA8
+:10D59000644018EFEEBD76DACFDC5D69ECD9672127
+:10D5A000BDDF5DC9E34398D831FA169DDD59A79ECA
+:10D5B000B3F5ED07F71191FD7455F95A89EF45DF81
+:10D5C00004B4BB8F57CD6B45F91239CF3C97EF1898
+:10D5D000C2756ECB4C5DDCEDECE6F9ADE17CA8D517
+:10D5E000AFED47BEBE344C5DA7958FC7E48B8B1C57
+:10D5F00013F05E35FFB385AC1F1AC2E861B0F15875
+:10D60000EE146F8F5CA07BF702EC59FBF617594FB5
+:10D61000EBDF5579053B3E0ED7E7FDCF94F183CF85
+:10D62000DFE452E599DA4EFB6EF3F919DA85B6AF0D
+:10D6300087909DF0D230EECFF80FD52E600E582F88
+:10D6400032987FA3F7FF63BD3030C5E7D9B658A243
+:10D65000C615A5B9443ECFE0A1226B94F9F5E92F98
+:10D6600024B20BA9F7D230BE7E749391BF6B580CD5
+:10D67000ED6BCA2A6B699FDD08F203F541E47C8EED
+:10D68000356DA678689BD92FA35FB4715872760D5B
+:10D69000B403A9467E1F5B8C5F16C3BFABFE205B45
+:10D6A0008D5FC6FD6D635E1A7DD7FA6B347039AB42
+:10D6B000F14523ECFB9E27BF98C7351DE0D2F856F5
+:10D6C000606A2CB4DBBE92858C6EC60EBAD346E27D
+:10D6D0003ED75F6FA6F3BDC67C217536E4E332AD5D
+:10D6E000E41F6B8B0FCDC07B078A4124FDEA8F9727
+:10D6F000AF8945FF6E4D4A07CABF834BCDB4DED517
+:10D7000093F8BD35CBA527FC5760FFF7310FEAD55D
+:10D71000EDE77FD182F7FE9423B09F45BF21760AC3
+:10D72000F268FBD4B336DCCFA5605C1DD0D91653AC
+:10D7300090E6B5A9DA42FD6E6A339746C3DFC95455
+:10D7400091EA070C9D141F9CC8823684EBC353A733
+:10D750006FCC8576D9B94CC2FDFCEA82B3DABD72D2
+:10D76000233F8FD2FC88CCA69E6759D5732ADDFD56
+:10D77000B8CDFEBDE43FB44F0BF274AA40FEE7C83B
+:10D7800079DCEBE27E37FBE48EA9A827EC85023337
+:10D79000A07F3397D1BD66692A58E19066E7B37ED2
+:10D7A000DAF3754B5E685FC8DBA34F48BAC0F60B6F
+:10D7B0005D3CCE700DFAA1A03C60F218AE817904F8
+:10D7C000AE970C8ADC5BAFCEC5F56B2BF41F22390C
+:10D7D0001AA075B9F38321A43777B940785A33F189
+:10D7E000189D0B3C5CA8F9513D348F2DD5EF1C40A2
+:10D7F000FB6BCBFD8CECA42D2843A1DD96EB59806F
+:10D800009F27B134946F9BE69BAFA3F3FC0280BFCC
+:10D8100081D2A8F3F6A55A892EDD2B1E0EE13DFE1E
+:10D82000180FA37713208D5ABF2195C369932990B0
+:10D830008AFE91FEE8E256151FEE4AD5AE627E17CB
+:10D84000E275AD0A1F76CB58EE5F10BD72781C579B
+:10D85000AF3EE17E0C581FDDAB4DAC33933E12A6BC
+:10D860008566E0BA12F2CDECEA6CE42F0E376594CF
+:10D87000C0E3CE58A005F9B3EDA2648A275D250464
+:10D880005CE86F568ACD749E7C70A230631E94AFA4
+:10D89000AB33931F02F2C42F7E6F4E1BF29B7D723F
+:10D8A00071E93CC8AF97CC12C2B7B640B2211DD7C0
+:10D8B0007A05C900F9B525DA3D091683781B63346A
+:10D8C000DAF2A1BC3555401F2D6B351888DFEBBD52
+:10D8D000C5FEA1F0BD5E721AC2FD002FB9F8BEAA46
+:10D8E00022ABE42517F28DF761FF5099E3529C407B
+:10D8F00024467FB12C340F636EDAEA9FA0FB546B91
+:10D90000C65819DAF199F7F9E97E57EC456619F12D
+:10D91000BAFD7CE2485A5F9D59467E5E6F085C8383
+:10D920007CBF65E92105FDEAB68F1CCC08F682A311
+:10D93000F3EF55183FE62834479C633101E5B836CC
+:10D94000AEE3AD10D153A7C1F7E758F2FF1434E5A9
+:10D950003BF11E46CC0484E7DA4BDFCB9F13852EC8
+:10D96000C8653B16ED6521346134CA29AEC79828D5
+:10D97000A586E3777D66DA5FD0CFB4AD08E68FE3A6
+:10D980005576DD41F3F2BEF353B4AB1C473FFD26A1
+:10D99000FA3CDF243D127BD41E124663BA681AD9C2
+:10D9A00067E1F540EEAFCDF29E70017C775773B919
+:10D9B000DF7C0FA37729F02F3F0CBECD0520A5E912
+:10D9C0006102803CD62B90C88FBE4A90832184E7A9
+:10D9D000682BD1538A7AEF2172BDF6A38D4B31EEBD
+:10D9E000C8EED1CFF32B15BFF82726D379055AA25D
+:10D9F000CC9C3ADB86F26FCF583915F7DB0FC7475F
+:10DA0000D7F3EFA572F9B0DB10DD3EFF22D5C6FBE0
+:10DA10000759199A40A86214D707792199CE6DF851
+:10DA2000FB0A02970BEC5A467A2F6E4CA7CD1336A1
+:10DA30005E501D87FEA09F216A3B267587AA61FD67
+:10DA40006D40B578AF2D2E93C3D1A1F4C211EB4B2D
+:10DA5000EABA800FAA8717221025AACF4ACC742EC3
+:10DA600002D250F956E88543AC5A7FD344D1608541
+:10DA700079E500300C503F7EAA59778E22D5BDA3A0
+:10DA800060F94F8D4C4E98D83BFED6312C5003E3B5
+:10DA90000FF1EAE11D7BDF0BCBD12E8FA4039C415C
+:10DAA0004FBF182A3E5BDF2EF98E3E7C40F0A479F2
+:10DAB00002689ADF62DBCD0094E69DA2161F4BF24E
+:10DAC00077BCB143417F28C0AA641FCC7FC4536F89
+:10DAD000797741BED9C7F92C36FF85E54897521AA8
+:10DAE000C7D311F42D039C3733E91F18B7A3540A89
+:10DAF00032E2635B2887F47823134B104F8D15EFC8
+:10DB00000828D757EF651E8301E9FFBF2DE1F39B7E
+:10DB100091CACF69982893FC13DDFCFEE8EA02C1A4
+:10DB20008EF2F5E0D21748EF6D3D2030E4FFE2DFE2
+:10DB30001C7DCC8E74FD170BE59B5FAF20B9F113F4
+:10DB400068A744F19F0FA69723EBE72EDA6EC0F388
+:10DB500089AC79417A8F25D12F7AAE467CCCEBF017
+:10DB6000D23DF7427ECEE6981652288F5A0D6C525F
+:10DB7000D9AFA6CDBC9CDD9240FBA85196CE866B5A
+:10DB8000617E9B9F1219EA4BA325983A17FA35BE7E
+:10DB9000E8404DD0677FB4795A2815E5784C058563
+:10DBA00041F7B5E352391FBAA7C9BF1D06FDC64FDD
+:10DBB000E6B0B4F9530EA0BC449B19EF35D915AEAD
+:10DBC000E7D68A012FC679AFBDCF67C6F199BA7F74
+:10DBD000695C54F604C2F91355EFB18A79F48E8961
+:10DBE0005BE5177B252B8AB6CFDAE88AE1F12D0FAA
+:10DBF0000907903FDC5E46FA43AA0C8686AB7A1989
+:10DC0000272EAD78BE11F58BA35CA075AC153BAA91
+:10DC1000F15D89B5F731A95AEEDBDF3FDB7E79AAEA
+:10DC200085E0B1D1C574EBA0F73040BEB9E7455FE0
+:10DC3000C7BFE1B8E37BD711A3AD23BF93F2DA3CB2
+:10DC40005ABDC10B9AC706B53F7F2A7FC7C85EC0C1
+:10DC5000DFEF8894F735F60FE85D9900D8EA46BA09
+:10DC60008F16BC16F3F27302E3F7B5F4FCDD27AFB1
+:10DC7000D255E47799858D938D74C7F10C74A7DA2A
+:10DC80004FC07756140182FC2DF931FC34CF487A0D
+:10DC9000FC5F978BE1F386FE631B9841BDA72A17B3
+:10DCA000A7F6958B4C958B56A68450FEFD5FCB4511
+:10DCB000908324179B61A589B053896D6F5A8A7A26
+:10DCC0005C9387E31127976227D6EB8B0B685F4441
+:10DCD000F909A9BF6FC6F8C855827ADEA5C205DD6D
+:10DCE000500897AF5D728F9EC2EF1BF01F39F89EF0
+:10DCF0004AC2750530DEC6D29C31B8BFB0F95F2488
+:10DD0000FBC05DC0E357DC95FCFCDC9E3BE789F083
+:10DD10007B714B52B99DBE44A3BF4ABF0BC7598B01
+:10DD2000FDA27CCE3593BEDCCC825C1FAAF6E95600
+:10DD3000971A47ACD255249F44CAA771BF7716A340
+:10DD40007C4F355824DCCFA17E3E98ACD7D7482FE6
+:10DD50009ABE6EE9A889477F58B6EAEFCFB6EAE3E4
+:10DD60001C26A4717926A6723FC02AA182F69B4A7E
+:10DD7000B140FB388DFE7AF478041C23E18784BA25
+:10DD80007202C5C7503EAEA89B21FF6E03925D8F05
+:10DD90007A2C5583BB44706EBB53188BF2724F7B49
+:10DDA000990DFDEB06B7F51ADC1FAE3330BAFFB89C
+:10DDB000AEE84D8A2B69AA849E61518E7C61A6795A
+:10DDC000745F3C031FD37ED5AE583AD0AF150C6DAF
+:10DDD000A7B885A6C0A1198CDBB10CE3529AF26BEF
+:10DDE000D216A07CCF2F2944FCB6D59B296E46CAFB
+:10DDF0006751FD0827711F43F3FD6E7ACCAEED2FFE
+:10DE0000CBA3EF2B6F4CE3FBDBA008A20AE69391B8
+:10DE10002F7890FF33EACC51E751ACE2292D8DDF0A
+:10DE20000F6BAB3F44EFCC00BE026C207CC1F46BA7
+:10DE300092C3F031A91F7CB8347C881A3EE2671285
+:10DE40001F7676085CDE925E5BCBA4DB503F2A1522
+:10DE500066B2631B4D7C5FBEBD40E50BC9DA86C46C
+:10DE6000F65DE93A6E9140F7703227F2F7F5ECE58E
+:10DE7000CF535CD366D6FD3ACA3BA580DFA38F6C37
+:10DE80007F679AA0C2513678683FCDF10878A5F92E
+:10DE90006CC94B6E0BE7D38DAA1DBDD1C5F9744B70
+:10DEA000FD06E2D30B9DA726B76B553B7ABED7671D
+:10DEB0004675A0184AAE4A45FDF973FE1E15333A61
+:10DEC000C82EFF049B84F9652B337C4BD2C2FC72B5
+:10DED00092B742C07A57E2BB42D0FEE320BF07FAB6
+:10DEE00071F01745F41E978F1133CF671D066272CC
+:10DEF00090A13B20EF128354EE9A077389A7DB9120
+:10DF000094B75A412FC2844E57F1FB175DF8BEE417
+:10DF1000707C2792BF2FF999FA9EE4A89655C59B6D
+:10DF2000713C59F4A1CC3889EF4BE2FDE789EF5100
+:10DF30005CF42990B54DF1180FC3EF6F4B0F3249C8
+:10DF40009884F935C518F77CEFAB16F59E64470D3C
+:10DF5000DE7B795C60F48EC46A11F4FD502C6A306B
+:10DF60005484D1F1EECB3BE2F09CEF74F0E601FD7E
+:10DF7000C7787F10E7B143A5F7F5F6C574BF6C8E7F
+:10DF800023E4C6F607F63CF9C42618EFB37D567AAB
+:10DF9000D764A37DB11BCB3F7BEC5D37EA8BD3FB12
+:10DFA000DE35473B9F5C2406AFC27B64E5CA105652
+:10DFB00003F32F0ACE3453FCC9AE03743F6D91E4D2
+:10DFC0003363FFE52D7B283F65D79FDC587E348D7A
+:10DFD000F3C7E9549F1BFD12B92D969000FA67779D
+:10DFE0008E7F41D47376951ED7DB5FA5FE37DA5F4F
+:10DFF0003D847839FD9885FC6E071EFB0DF57B6A24
+:10E00000DF8B34DFCF76BF7B17DAD3E58C79509E78
+:10E010009FB6A97E3D6B475CF8FEF615151E5AFEAD
+:10E0200074ACBA0FCE18A49E7A1EC31C007FBA3FF0
+:10E03000D01187F70B3F33F9CC088F85080F488B39
+:10E04000000E28F717060D34CF852D6D74DF6AE1B9
+:10E050005EEE1F5C08F022B8B41CA0F9BF8F7019E7
+:10E060008FEBF8B39BDE75D86BA1FDB3B6EE850ED2
+:10E070009F1BE1A3AD17E0C0D7BDFBC2F03447C37F
+:10E0800053CB9F685EE57BF9BCCA77F179CCD90B9D
+:10E090007872209E6612FE4FED6332DE83E9DAF37A
+:10E0A000EE49B4674EEFB3CA685768F3CA00711BF4
+:10E0B0003716F988EB63B6D740FA98891D749EB37A
+:10E0C0004892247C9FA0A73C600E7079DA519C0E88
+:10E0D000E5CF3C0AF62142420A8E40FFEAE934EDE0
+:10E0E000FE4F871BFD62BB2FF7137D7E1AABC25B11
+:10E0F000EC7063FCCC8674DFE9B4B07882D31FBEC9
+:10E100003802D7BDDC58F19B4C1CE7491E1FFA555D
+:10E110004EC5DF1EA2790FD59D3746A600B7383C05
+:10E12000FFCE17988FEE25EF7D2D26FC1C5A48E771
+:10E130007EB78DF60FE83EE2697CE791E613A438DE
+:10E14000AD61DE32379EF37DCA1C3E3C97FDECE7A5
+:10E15000AF51BC4D57AAE67FEAA07AA7F6BE9680DB
+:10E1600069991A0FCF0237931C03383658C7469364
+:10E170008FEAFDA200BF3776C6000213F5C4560D24
+:10E18000CE15E6E9BA731D2E4733B664B793BF25A3
+:10E1900010FDBE59A4FCCD7D74129D2B9F63D1CF81
+:10E1A00095991A27B7DC1843F1371BED3FA3FBB74E
+:10E1B000958A45C2FB2BC754B97842BD97FF554C91
+:10E1C0009C2200DDEC4FF7E5A48FEF7B0FB76CF5D9
+:10E1D0002237C2B70CCF3D28CEA0ED7A8C27EC4A6F
+:10E1E00062AADDC942043F9356BE9197C7F3FCA4CF
+:10E1F000CDC135F81E26C297D77F829767F3F21FED
+:10E20000A9E573D24AC6A473FF0EBDAFC19829BE5B
+:10E21000CBCA55783478F4C245645D9A5D0D95E7B4
+:10E22000E1E5DC24EAEF32EA4F84FE467DFFFE00A2
+:10E23000EF8A35E15FD08FF55FD54F90F492E0C360
+:10E24000B7AEE09B87EBBFC78B99D414FFFDFBFFF4
+:10E2500067DB2F377A854F910E870844F71A5F776F
+:10E260003D367C0CEEFFCD0D4B43A836BB628BCD0B
+:10E27000A9F0FD9CCCCF4FEE79743D8B164FA2BD1B
+:10E280009BD19357CFF1CC43F5E7B3ABD3B9DE596C
+:10E290009DDEEB7FC373393CAEA28D33FC35275333
+:10E2A000280CB7D3598580F187F9ED567ACFF7223C
+:10E2B000068202E63F928504D4DFA35827E52F4665
+:10E2C000100CC5F7A8647A38731CEB768B43F1FC0D
+:10E2D00039B412EDB4F79DBEC67418EFCBC73A3E01
+:10E2E0003040F94FD27C2F75A25F289DDB570EF589
+:10E2F0007D5C0953A043C13ECD154DEEF7C05312CE
+:10E300004F859FB7DD287A1F49A7F564485DF65E03
+:10E31000386BF26081FAFE92D6FEE4534FE2563734
+:10E32000ECBD70EF80F781E754CE7FF4E7E3062879
+:10E3300057E5ECEEEAC06DE1FAFEC974AE679F4E98
+:10E34000177476218C4A76DCD33771FB69F7E5DEEA
+:10E350009AC751DEB618693FFD69CB9FE9FDC773C7
+:10E36000258CECBAFEC6FD3402EF9FEE78328D9F0D
+:10E370007704F4F1CB4FFC724478BC258059764E7B
+:10E38000E0EF7010DE0F79148B91EE39923FC6CC1E
+:10E390002A789C0ACE17D218DC8F0E453C75501A8D
+:10E3A000C7BA29959844FEE904E6A1D4C94A284D84
+:10E3B0006615066EDFF9294D63414A33D03E457F2D
+:10E3C0000FEBA654C61B9F61F11B3978623A14DF2C
+:10E3D0005D2DE1DF23E28344C4E3B828F23C222E22
+:10E3E00048DC5949F21CE382F29C7DDF53D0E4F70C
+:10E3F00086F4E2F7906EF6A77BDFC7F4F0B3BFE5D3
+:10E40000F72BD618C8BE3E6E9B66960175CF247852
+:10E41000E91D104560253B40BFCFD6FCFFF8A7C5DE
+:10E420000923309B4DA7C2E37798D5918FE7C5B3F9
+:10E43000D4AAB3D4739059AA1F248631F59E9E871F
+:10E44000EEDBCF52CF1F6645F85F98DFA2F3A3281B
+:10E45000F80F58C72CBF81CE0D66C54C7BB593F520
+:10E460004F2761FDD1BDBFB2083FD4A0FEAC88FCF0
+:10E47000ECC8F65603B326E3774E4FCFFC4026BBDD
+:10E480004EF36701C1C9D4AEC1F221F985FC577AB8
+:10E49000C3E19490C1F9C4E6BF3A2EDA3BD95A3AA7
+:10E4A0001BEC335342DFF6B0238C47BED7E4B046B3
+:10E4B000E7D9B8B1453ECA3707068A4B5DADEAFBDE
+:10E4C000A687FC0CE76D0B3D40EF54DF9FA990AF92
+:10E4D000D65A10A0FB0131F9019712657E4DF8BEA6
+:10E4E00033F05753ACFEDC64A9BAAEA519DC7F7BD0
+:10E4F000E8A2E4623CCF5E250B746F7895BC8CCEAD
+:10E500005907FB3D815AF57704B4FCCAC46D0CED84
+:10E5100036DBD7AD0CED499B18FD5ECA0C75FCF5DA
+:10E520006AFD8D89DBC84FD290C7CFF723EB1FC898
+:10E53000DBE042FBBB311BF6BB983EA450FFF579F4
+:10E540001B4AB1BD35D4A8BBCFEBCBE0F6AD752FE0
+:10E55000A74763AE399083F420FA29BE40ABD7D8E1
+:10E56000CF79D2F56AFB265380EEC934A9F6D0D212
+:10E570002DB16BC92F97B1FD08BD6F95CBE8BCD10C
+:10E58000167A8ACE11ACF9666683BC55F6337C5F89
+:10E59000C3561024FCA0B329A4A3DB98DE77368CE5
+:10E5A0007DFBAFFBD6EFC2F53566FB69FCC1D65BE0
+:10E5B000ACC2B351D5AF8D36FD39DAC20CAE57AF10
+:10E5C000CDE0F2DEFA32237932005CC8DEBB3E23B6
+:10E5D000EF06B4EFACFB0785A3AE7E362B1D128D84
+:10E5E0005F22E5BFA340887847C940F33AB7D7A078
+:10E5F000BEBBC8DFB1E8B5038266ECF7D75BCA0ED5
+:10E600005E03F359E07378317EF2C92DDBE99EFE9B
+:10E61000C2174D149F30AC732697832DFC3D46EDF9
+:10E620007DA38B5A2CBAF7A416B1B0F71A61BC853A
+:10E63000473F3DCAE89EB1FEBBF66EC06AFC10259E
+:10E640004E2DF2DD81473222DF5D56DF1D2888EE38
+:10E65000A7897C7760575020BDB10CE358691FB083
+:10E66000AD18F73D95470DE437E8CB87F2D65C53FC
+:10E6700058DEE0217A546263BC3BA2F0D37B999CC4
+:10E680005E76E3A11AD9FD3F5B1BC237BB581DC3A1
+:10E69000F3A6DAFB4409CFB56B033174BFA456125D
+:10E6A00002183792195B6C45FF238B1724BC8776C1
+:10E6B000957132DD7B32DF2F8EA3775AB72FE8C0FA
+:10E6C0007B75B52E91211F67C6F33802962AD0FBC1
+:10E6D0003475D29BF1B3701FE7E0F7F4B2241690C3
+:10E6E0000D68D779199E2FC366A52204A657A6C127
+:10E6F0001BC2F7AED8248BB483BF3373C39809E42D
+:10E7000007A6BF036D57855EC171BCD612C4FF94C6
+:10E71000FB9D640F065C467CDB947D9CC1CF05CDE0
+:10E72000B1C5A1BFE2FC66D8C9B71B508404C4C3FD
+:10E73000EB6D2BA75F0DDF4D0191E21DF2BFA9BD6F
+:10E74000ED6A68DFDD66A6FB161A9CE43A51F77E97
+:10E75000837B853E6F8E78AF426461E5903FA2CEA9
+:10E7600083B152160A8FE3757AF9A1BBE4A0F729A9
+:10E770003E02FEA4F30F35FF9E9ADF69F213DE77A7
+:10E78000FED540FED5836D73B2485EDA17B7DA71F5
+:10E790005F78849F63F6279F7766C8DA3B0936F572
+:10E7A0009D0A1BFABD22E9A9AE8A7930CED01A683B
+:10E7B0008F1989F83D6CF2605873BD2A1F45079781
+:10E7C000E31ADD44A6F511F4576FF2E4FBA17EFDD8
+:10E7D000374675DF78FA86D0640C7B90695F6DCA26
+:10E7E000601E640F93B3234D82798C7CD1ECC1DF22
+:10E7F00055B8EAB9822128E747BE3683E41BC289AF
+:10E80000DE87AF347BD04EB6543A3DE238ACE720D9
+:10E81000BA3CEB30933D2456DAFD647FB54D70C9A8
+:10E8200061726F6595E4114DF47B3794AEEC47DE71
+:10E8300067C50B25E87735ABF672B2BAAEE44C3B50
+:10E84000A5496ABE5554A6233DB702DD60DCCD81E3
+:10E85000159CBE97A55A496F2E7B7D68CA40FEC1A4
+:10E8600027AA5C9E5C00ECB61565E4B72D7AE044FF
+:10E8700023D2DDB258AB8474688C1BB67132D2FDE2
+:10E880006F4D74CFB33676823C2BAC3F63DC4417BC
+:10E89000C2C328286948CF233383378893904E9486
+:10E8A0004D789F7FDCD68D3788205F76C62A6978C1
+:10E8B0005E76D9D6CDBC3C49D96480F22BB6B6F28F
+:10E8C000F24C254D80FC755B1FE7E579CA26CCDF4D
+:10E8D000BCF5495E3E8AEBA3DBB73E7303EAA35A5D
+:10E8E00093A714FDD3CFC2FC0BF2F09D549EDEA97A
+:10E8F000C2452B7F1EBF9BF05D559E4696BFA0B6BE
+:10E90000DBDF4FF94B6AF9CBFDF4FFAADA2ED44FC7
+:10E91000FB836ABBF67EDA1F52DB1DEEA7FCB76AEB
+:10E92000F91BFDF4FF07B55D473FEDDF54DBBDD5B7
+:10E930004FFB77D47647FA297F4F2D3F1AD1FF0737
+:10E940006AFD4EF5BB3BB6E13DB4D7DC20AF509E2F
+:10E95000E4C73690BF6B5B6521D17FED78AEFF35A4
+:10E960007A77ABF702DECEE471A56F6772FB66794A
+:10E9700026B70B8A1EC85D3719E9F0F7FC9E22E81E
+:10E980008F23780F57794020FFDEB2D7F9BB32CB07
+:10E990001E1075BF1FA4B5D7E61F50E759A7A64B99
+:10E9A0003273689C6CC5E59916A61F4D923E6F05A3
+:10E9B0007EC2F8FF3A27D733F90F1437E0B9492D53
+:10E9C000E8195C5FBDC31C42FF57BD2452799DB35B
+:10E9D000D88FE7FD8A24921EAA772684F0BDE6BA76
+:10E9E000BA42DD7B9F759248EFC788F153ACB31CE8
+:10E9F0002837A649283FEB98945044E76AB04F4324
+:10EA00007D52592CA1DCC98E7726A05C9E95C5E16C
+:10EA1000DE1EDB65C37B14E24302BD15304C128958
+:10EA2000DF73EB84800CF368979691FF7547B37A98
+:10EA3000A6C8F879A226E777FEEC2AD263B5A0C76C
+:10EA400064D2636CC898E4DEFB9BE2D19166D45B30
+:10EA5000529A9199402E1FCA4CA071773CCAF55624
+:10EA60001EE82D7C67ADB590F177DE5C56F2EB9633
+:10EA700089CC9518E6C73C946954DF47E2EF50E72C
+:10EA8000E17B8861F01DEAD7EBADEC41F4565625E9
+:10EA9000C8CBB0FA1697A4CB3F97A9BEABE4611ED2
+:10EAA000B46FAE7A6E0BE993B3A84F18EA973FC4E0
+:10EAB0008C44FD027AC4C2FACA414D1E6B768B2685
+:10EAC000A76B55BD511BA1370697BBFF787D38D189
+:10EAD000A7A07B87A63FF9BB1CE304005E269F81AD
+:10EAE000F40A137D74BF7F30B8994C2512DAE383A2
+:10EAF000C1CF94F4453CCA69934FF49C88724F6A25
+:10EB000030F86AF5CCD6F4ADA8D7BE38BA3C1FFDB4
+:10EB10005E2B4D1D337721DD1A86D0FD0E59F53B56
+:10EB20006CABDACF8EE7E1EFFABCBFA56E1CDE1F3F
+:10EB3000F74AE42F492D96B19D0DF6E98964C7F196
+:10EB4000FD26937CFE0568CFBF6896F15CE0F0B3CC
+:10EB5000EAFB0D990E82E7BD7BEEA3762643858BFB
+:10EB60009FF73382F7AAB404B2CBE59D56D56E3C2D
+:10EB7000BDCE0B65B542A701F5CF5BAD817556D40F
+:10EB800027EA7E8029811B71FF130C98D5A01ABC3F
+:10EB9000E8CED81EC1A0F99FBDA22BDC0E35DD3812
+:10EBA00065329E874A2345E82FD56D5B67CAC472DC
+:10EBB000416BEFC5CB4328BEB4BC087878A65D2B6B
+:10EBC0004F593705E6B3C7CCB4FE15ACBF071F835A
+:10EBD000A4BCB40EFBDF5DACB6573E5F87BFDF055C
+:10EBE000F3B9CE087BB0E1DBD2D639527BE79BD3B9
+:10EBF0002AAFABCE052A943BE3701BB7A8ED443295
+:10EC0000EAED55A5FCFEB0F6FB59DA3DE21EBCED7F
+:10EC1000BD494157ECE787FE33AE008A96183B0F9B
+:10EC2000D9016E8BF657584D02BEDFC5DFEDD2DA43
+:10EC30002DDA3B93EC9C252F17515C70947687F16D
+:10EC4000FECC3FD1CE6ABE80F14E87DE5CBC4BC6A7
+:10EC50007B33150D0E23D567DCFF157D7D5AFBD365
+:10EC6000BBDEFC318E7746EE4CBE166AAF0A015C05
+:10EC7000A2B4D3EA6BF7AB27B9BC13DCF0FD3FDCE1
+:10EC80009C0F9958E1413F53D0EAA77B6C3693BF64
+:10EC900004F509803E80710A5A3AC99D4BF523BF9D
+:10ECA00047F257D0CA12A7A1BCBC4FA473F7A05516
+:10ECB000B18F867C33EC53AA614A3563DE198BF140
+:10ECC00002CDFB1C24D76BEF6B77E1EF2B291E33B2
+:10ECD00043BBB7F9F28E5409E65177BFB9F4E74860
+:10ECE000BFA165AE7BC2ECB09C2C1EC79D19EF2F57
+:10ECF000457EB4013FA23E6E34F9ACF86E8A922A8A
+:10ED0000505CB50DCADFA0F24CB5DC33F56ADA977A
+:10ED10000912CEAB3E77F6D462D46BAE04D207B6FE
+:10ED2000BC29A573A13C20992524AF8AACB2BB11A4
+:10ED30004ECF889E0AE4BF671C0E09E3B14056928D
+:10ED40003E10F39C149F6551EF3B658EE17ABE67E0
+:10ED50005FEE56FD026E1EDFD31CDB715311B48BC8
+:10ED600079509014E8BFF1FE0D25189FB8F5FE7795
+:10ED7000FE84F1AD4DC922BD33B0BB3AE4C57ADDA6
+:10ED800006D6B11DECC83595D33B703FBA86C93263
+:10ED9000DAEBBB0DD3FDA89FBB9344B65DE6BFEF96
+:10EDA000101EAFEA28D0C74B6594EBF36BB37C0F12
+:10EDB000BAC7633C5061118E936490657C3AB8B0D9
+:10EDC00083517C7E726EAE8471DD71851171B0935A
+:10EDD000F5FD244CD1973BA745C46DDDA22FC7DFBD
+:10EDE0004F08CFE3EF4484E74F223D523C093F7F79
+:10EDF00088E145009F2718EAE9C6AF87503C2BC23F
+:10EE000011EDF69861A207CF4532CD1D33300E8E3D
+:10EE10008D88217BE9A03B86C990B72C66244F2DB5
+:10EE200009C103B85FB5085289421A2A78E0AF5089
+:10EE30006E87FD2ACADF48F8656672FFA043FD3D74
+:10EE4000B0A018223BC2F6C010A9DA835BC7083F06
+:10EE50006C79589EC77B6F77ABE7282E2D4E8DF0CF
+:10EE60000A2B43BC4D62017C8732F3FE134A08E64D
+:10EE7000B146CEAD403B6395D049E328650E1FEE09
+:10EE8000BB9330CEDB88F1DE0AA591F8D8E3E6F635
+:10EE90009FCC66FB118FAE9902C58FD41F8AA9C380
+:10EEA000C3977AF5BD062D8E4DA3CB97DCDCFEDC37
+:10EEB000D32E085EF483DF91BB1DF1ADE55B7C4E84
+:10EEC000FA1DCECC31159D4897EC7A6E87821EA034
+:10EED0007BD95A9C981657F85196999FE767093D38
+:10EEE000F80B6971446171E0747467C4A30BBF844B
+:10EEF000E73D99634A2494338F68F72F18EF179FE3
+:10EF00002FA473836982F722D59F8E765DA23A5E25
+:10EF1000A253F4D2FBEE302701EA3FCA78FDC4DCED
+:10EF2000BDCBF1DED51E241CE49F7B389C23E93643
+:10EF3000B5DD5F320AE165007D98D1978E0DEE1642
+:10EF40003A0FAC7F902558C6F4A5EBF1466EFF74DE
+:10EF5000CF9729CE72303AFFC41DCFFDD8499B24EC
+:10EF6000B46FD3721FADA67B300F3209F55D5A7BAB
+:10EF7000C74DE8F78AE487803D6E2C8F93FB6E7E49
+:10EF800078A391F3074B11096F91F1A591F1A43981
+:10EF900059F1AA9F02F4402CDE0790AEC038C1EEB2
+:10EFA0000718BD1350FC62F36DBF83FEBECC334B1C
+:10EFB00028AFB3DEF23D6987797DF94B5F16CAE968
+:10EFC0006D62A72D3ECCEF290AFCFE59A4BCCEC928
+:10EFD000E27427A3DE70FDF36926D2F710FC7DBE34
+:10EFE000E4919284FDAEFFA335E9FFD06E61563FF8
+:10EFF000DA2DEE762D9F417658D65B3C7F893B63B8
+:10F000009D928B702B277FD1C1CC39E42F12DFE387
+:10F01000FEA251466F00F3EC7D1BC5DDEDDC77C72A
+:10F020003C8C57AB4FBE5646FD3C4EDDFF8CC9D2E3
+:10F03000F85BBF7ED1ECF521DF447E1F99A5C59515
+:10F04000947C3213F037EA7133C5DDE50B65F47B50
+:10F050009CDD8D46C26799515EBC3A6C9FD6945C2C
+:10F06000549495C47F97D8071B06F9BC81F980D9C1
+:10F07000DCCE634548AF59C066285FB2146E406667
+:10F0800055C6305F189DCAE745AADF94EC2DCAE249
+:10F09000710874EE635259FA9984123613F5327C72
+:10F0A00043BD6BDA15C3CF7B9CFAFB9146238F17C8
+:10F0B000B9415DBF09CF75C6E27B6F42C832BA6FF6
+:10F0C000FD9BD57AA2D511320E413FD91B47E8DE10
+:10F0D00065C43930EE6F292EA79C911F14E142F9C7
+:10F0E0007B25FE6E77258F07A85DC10C781650AB87
+:10F0F000DE5351EEE2BF4FCCBC5E19DF57A12DA607
+:10F100008CFF0B11FFBAAC2C01EBA7B20E8A636423
+:10F11000ED4CE6F112FA73A76DFDBC03A5F901C42D
+:10F120004A23ED5346BE66A3714D958CDE09A73781
+:10F130009B70FFBB82054443AF1FEEED4C99DA692B
+:10F14000E7B1BBBFF9200DE572BEB0DDF706D90D02
+:10F15000B1D276D48F317A3ED4EEAFD5A874B2ADA9
+:10F160004A227C6BE56EE518C5DB67B1EE6ADC67A9
+:10F17000655526E8F0DCE3973D9FCE7CE3C2FB0DAE
+:10F1800070BECE15E99D2EF9BC9BCAB755C983F454
+:10F190009FD34FFFA9444FFDF79F41E5ADA12FE25B
+:10F1A0006F00506CEB3E115F22F7DAAD917076AFD5
+:10F1B000D0CBEF8BF747C69373B8D84C5EE74D00C2
+:10F1C00037DB4382A78DE1EFDEE8EB4DCD3E17CF75
+:10F1D000CFCBB5FA21E7CD581FF6BD6D32FE8E8E2E
+:10F1E000BE7E49D147F1FCDC5DABCFE7F7C3F3FA54
+:10F1F0007A91F8899C2FCC2BE94761F3BAC26AD186
+:10F200009597CEEC33AFA45BC3E675B54B5FDF5784
+:10F210001D7D5ED7E55B069C9756EFC68917562F76
+:10F22000721D374FB5F403775EFFD6D20BEBF7F6BE
+:10F230007903D7BBBB32721C85DF53377BDF46397E
+:10F2400057C6E495F84E3873C4448D0B2E52F9E33B
+:10F25000EFE8A748C27800EF516CF779268F4B3959
+:10F26000FCEC023F9EC32CDB6796F1BC2353F55B9D
+:10F2700083E05988FCBBC72AC5633CA0C52DABFB06
+:10F28000AB8E6C8CE7DBB3F39DDB48EE31BD3DC349
+:10F2900098A708F5358830BA97F1276C97141E4760
+:10F2A000E125FBAF5EF0FC99F6553FE6FB2A2D7E8B
+:10F2B0003FDCCE62137AED2C2D7E7BBD3ACE3759E2
+:10F2C000DC1F08763EFD3E6A72AE48F1CD8F583B9A
+:10F2D000D6E3FDA3479CCE78DCCFFC469DB76637CE
+:10F2E0006AF71A5266E68E3146819796FE0F29DC40
+:10F2F000A2280080000000001F8B08000000000012
+:10F30000000BDD7D0B7814559AE8A9AEEA57D2DDE3
+:10F31000A90E9D178F509D7720840A8418909126FE
+:10F3200009195486E9A022E80C360908485E181F1E
+:10F330006165C7CA431E51C7384604046CA228BE83
+:10F34000669A59D488C16DA3C3E82E8E61D7191D62
+:10F35000C7CBB6C05506105ADD41BDABC33DFF7FDC
+:10F36000AA92EE4AB7C2E8CEDDEF663EA73875EA4C
+:10F37000BCFEF3BFFFFF9CBE2B81AC0C1411FCE361
+:10F380004A0971E6E4F476B9091957E215A7D0F7EE
+:10F39000BFCD3410328D900DF44168BD9227F877BF
+:10F3A00073F4DF2221EBCBE8F7D0308B9007C44118
+:10F3B000A740EB1F7009A2C2413B09DBED7DCD6088
+:10F3C000F0B80879E82739BDBC7BB8BCC5E7DA05D9
+:10F3D000E57106E20BD8A0137135A1EFF75A446727
+:10F3E00057092D0A83EE1A3B2DEFF9C3759C8390C4
+:10F3F000CCF1F45D0A2175AD95E4D854429E378571
+:10F400005F3D0FF3D9CCF977D37E5EE829A9166862
+:10F41000FBE52708B1D24FEBD65EF5C0F151844C25
+:10F420003F2ECE86F775DB9D324FDF370E3657C342
+:10F4300038A499C8B9322169FC6CDE4EFB49BBFB8C
+:10F44000B0DC41A7FCE080D417A2E5F02E4EEE958B
+:10F45000A07E4DC91A808FCD23D9E87A97C254F186
+:10F46000BDB3DA08EDAE32C99DB49FD346B208E011
+:10F47000781EFE660D3F97FE442A2774FE4B036BF1
+:10F4800097E2B8220559062D5B449C87451293DB11
+:10F4900068392D8158AC5308296B170FDE01E3AF93
+:10F4A000B28BBD14C68E72F1E0C3B0AEE64C91973C
+:10F4B00061703FC255EB7FB9C76B2274DC897B4C0E
+:10F4C000B433B68FE7E97F9302D1E5C97DD1E592E8
+:10F4D000607479EAEBD1E57D1283F70CCB981DC7F8
+:10F4E00029BC070E9809CC77F5A904BF99C27BBF48
+:10F4F000911058BFF2AC19F1A172B5CD03F871EAC1
+:10F5000064C22E332DBFF25E027E7FD3D356F6BD8A
+:10F5100021F04B282BBF4C24F0FDEA5181B2643A14
+:10F52000EF97BEE66FF016B16519A1FF5F16EEEA20
+:10F5300082FAA9813291BE7F7E022183502FF88BFF
+:10F54000619DCFFF95C77EC34F9AFDBDB4DF532F9A
+:10F550003EF14B80D7A927C7247374CE971A7AA798
+:10F5600076417D9B5DEAA5EF679C7A26DB17B12F7C
+:10F57000ABF798A3D6D92C71B8CE56C1D3FE28ECE0
+:10F58000CF2123E253CB727F5D90B66FE1326505E8
+:10F59000FA31513C2D82B29CE6A4F83AC3C1F0B6D0
+:10F5A000C54ACB31F65D7BD66EE1896FEA70F9E82A
+:10F5B000A627703E0527DE45BCDE6F540C0900C748
+:10F5C0004D9CBC9BCE7FBFD5514C92E099E907BCC6
+:10F5D000B95332E0FCE8BA1E6E04BC7893977B49BD
+:10F5E000FCF10AD2FFB4BD6AEA37D4D371DDC58419
+:10F5F0009CFD73C20D1E3A8FFC2DD1FB5EE88F2E51
+:10F600006F00F8507CAB2511EFDD309FACF5E94879
+:10F610002704E75370E2FDEBDC74BEA3CDA419E030
+:10F62000A21FB75B627CE4A9A7683F05D80D7F9E47
+:10F6300067FD49A9745F54BA7A89637444FF6E19EF
+:10F6400043E96D35C7F88BF67EB56E1E5AFFD3D5EC
+:10F65000FE5D26F9BE10EEBF5984FD3F79E7DC0759
+:10F660008E1B47CEE7C33B3D9EAA88F7376E597382
+:10F670003083B6ABDF9B32858F806FFD93AFA65E84
+:10F680004FDF9FDE23C8C002EB173FFEF319F0DD0A
+:10F69000937C00E60BF51EBADED381DF38E0BB1B9E
+:10F6A000B73BA7F0D270FB155BE678AA0A86E17932
+:10F6B000B174FA4239E373AB0346BF05E822F0FBAD
+:10F6C000EA3180A75B3839978E5326F878A03B7BC8
+:10F6D000A9C7A84C2764D657FF7C7034AD6F3A3069
+:10F6E000ADAC8BD67719BC57FD08E86E272FEFA677
+:10F6F000CD9E7BFBE6545FC4FEFC56C5FFAE85F590
+:10F70000D88F4271239732F58182DA4A28CF282296
+:10F710009C99F263C709E2F1DB603CF2AE2199905B
+:10F7200013FD77150B06E447D7039D9C220E19E8BD
+:10F730006EBFBDF9DF71BC678D38DEAC601207FCAF
+:10F7400077FF639CDC45001ED1F477E244BB63364F
+:10F75000A3EB1BBC28070CC445FB5BF9E824E403BE
+:10F76000DA7BFDFEADF247F7A3C78B132ADE026AF0
+:10F7700046E297FEBB51F31413D0637D2B9517110E
+:10F7800074537FBCDB446C23C72164087F09E02FDE
+:10F79000C54B22E17AADC837E81F67A1787B12FE1E
+:10F7A00095CDCA848E7F13874B23AB2704F280CF7D
+:10F7B000718258D19931CC5F49B91FF9FC69FACFF0
+:10F7C0002E19F842E008D03BC8D2DD205FC4E09992
+:10F7D0006D50AF8CF7003F1A0D484A9FE45789C817
+:10F7E0007F4F4BA1C7B1FD33936485BE3E0BF462DE
+:10F7F000C3768EE408FED41678D511A2E5537B4774
+:10F8000055F00EC0DB7F75C03A4F064655981CF187
+:10F81000F9869E6FD29921DE7C00FFA47897E4F6EA
+:10F8200024B869997452A10BF26C547349738C7D9E
+:10F83000D3DAB94CCD2512F08F9FDA64E0E3C99694
+:10F84000BA47405EC39F87BEFFF4F551BDB0FFBF0E
+:10F8500050E5EA528E8DA3F533DACDE8FDF557F287
+:10F860009242749C4F899404F2E2E96CEF38377D40
+:10F870009F5E31E8E1293CD2AF2072076D7A8C9708
+:10F880006F13E97E2C23545EC2B3D46702BE423AA2
+:10F890005370BE84C8D500CF15F328FC4B5819E42B
+:10F8A000DB2AAF49EEA272B84E60F0AEDBC3F93B83
+:10F8B000E85C96DD130D8F1B7BCCC37801FFB73D51
+:10F8C000A29E8EB34AF0AF07B935968A9C51E514D3
+:10F8D0001F1E8BFE7E3509E2BCEA9F396F8E05E75D
+:10F8E000BFA8707E3ADB7309AC8F5B60C1F9B43C92
+:10F8F000CBA17C759902A84F84D7507E4CE74BDE94
+:10F9000066FB709DAA2F35AD5DEA59469F675BEB9C
+:10F910003CCB6815921AF0919E24C49FD5558183E3
+:10F92000C85788F8EBEBD3A13FE211A1BCD9CEF4C4
+:10F930003DF2D8ABC057FE42C400E0E18C951CB646
+:10F940009FF136DF4B319C5C37B47F5E8463BD44EE
+:10F950004480E37B462FAE5B5945C4DD94AFD45B56
+:10F96000BC9AFE25FE90AEE746D28CEB5EE8CEC296
+:10F97000FD5C49BAB1DC404226C2C3FE962501BEF9
+:10F980007E4664DC5FAA27116BF248BC02F87B223A
+:10F99000E0B6727B74993C1651CE0238D37204FCE7
+:10F9A0001BF79D377B62C0FDC12179E42FAC991410
+:10F9B00089C76D38DF23EABE3C78CD8D19C047EE8C
+:10F9C000038578B4DA4139F05FFAAF19580E5A68F6
+:10F9D000FF095387CA585FD6CECA2DEE17BD5B28E4
+:10F9E000726C36FA3244BA3975BCF7A081C27561BF
+:10F9F0008EEF76D8EF3A832753407EE2C9F3D2796F
+:10FA00009056B6BF0F4D692E6C8EA17F68F3DFCC88
+:10FA1000058206E0232F32FDC25E1A3646F2FFFB56
+:10FA2000DD8C4F260D8470FFC3CF7104F4DEADDC96
+:10FA3000FD19B08F5B3324AE83AEA9745FDB6CE439
+:10FA4000379417E5D27D6DD8F7C1C131B45C3A77F0
+:10FA500010B689AEDBBBE63740CFD31298DE9CD818
+:10FA6000BCCB40FB4BBBA1604A07C5CFCD6E09E7BD
+:10FA70009330B5FB15E827BC46127B693FE9ED8A58
+:10FA8000FBE62218BFB90DF1B786E0FB946BD7B542
+:10FA9000C177778F26C93C7C47DA38F8EE410741B9
+:10FAA0007D31C5C0DF5003E529AC9CBC8EF3F42248
+:10FAB00052DF8FE3A499C95C2E99BDF71721297AEB
+:10FAC000F662BD1FD79B56D95C02FDA565B3A7CBD7
+:10FAD000E433E4D0F10E1D36FADBE97C0FA9FB7E9E
+:10FAE000CBAE8AB448FE79E8B4453050FDEC50BA4C
+:10FAF000A697066DA097DE52529906449595333726
+:10FB000009F6C795195D7FD6E8499A0A7470982757
+:10FB1000B00FFF69F324811E79A989CD5FBF7FFFF4
+:10FB2000ACEE4BD3171CF147C8A5A645E750DF6FD5
+:10FB3000FA42887A7FFA4E0B01513524BF560E5493
+:10FB4000C3770D64703DE053432091F823F0FBD25E
+:10FB500084D8E36A78DDF4054F9498E39AA2DF7FB6
+:10FB6000318A28A3627D971AFD9EAE23AADCF7F99D
+:10FB7000D03AE03D290F39BCD4DE9B07F29096CFF6
+:10FB8000FA0D8A7132A8E34C8E9D11430ED0B3A9B1
+:10FB9000DC6B867D39238550AE9D25642ED45F6A4B
+:10FBA00030DC5003FB2B841D0BECC3E368F5D03E27
+:10FBB000721FCF2C329120EE4F18E701F053F2095B
+:10FBC000D9D6FF8949027DA0FF15849F862F9170A9
+:10FBD0005422F8466AC760D040E9E3FFB8BFEA2E76
+:10FBE0002AA4A837A0D1F75FBB3D33693D6F88A237
+:10FBF000F7C4D221FA4776F3A08157F9C5F9EEAAE6
+:10FC0000999165F67D44FB9A2ACA1F4A8B587B213D
+:10FC10008B3BDC9E03AFBB999E238433017E4365FF
+:10FC20008BAE6CA3E54911655157EFD2D5A7EBCA4E
+:10FC300063D9F7A7EDC14CB04393B28C3502E57B95
+:10FC4000A733824B385ABEA7C35C5345CB0DA54C96
+:10FC5000EE36F673328A0D157E8D32D31F6D72C863
+:10FC600054570470183C08FCA1BE8F13394A0FB6D4
+:10FC7000C0DE2096A19D14D12EC061BBFAC007D86A
+:10FC80002E6EFF0506A4F3AE82A3ECBBC04728DFAF
+:10FC90003774AEF102837AC3C8F88F407C9E3194EA
+:10FCA000BE1BFB6A88CF36CC27CF64785E453E7991
+:10FCB0008013813E87F014FAB50DD385F6FD9F269B
+:10FCC000F5FF1ED487C45B3E6913E8F7FFABE1A3E1
+:10FCD00069A0DFFD4995079B397F218CBB8DF80A10
+:10FCE000419EFDB421F71503FDEE8831B40378E899
+:10FCF0008FB3C6D508947F1FB187C671545ED76491
+:10FD000015B0724A6807C0F3C9AC42561E171A678D
+:10FD1000A0E56B7AAF46781FC90DED80F2CF7A6708
+:10FD2000B1FA49A1713C6D9FAD7810FEBBC5D87486
+:10FD30003D278BF1136D7EFF36D5E3C982F5D433B1
+:10FD400039B2E4A6F71603FF5D622022A1FC76F724
+:10FD5000E963CFEEA6F0D8DD9A487A193A7A05AA77
+:10FD6000D7A631D4A7FCBE1BF973D84DF9353A811B
+:10FD70000643E03F4A9C6691BADCC3FBA28D9F36E6
+:10FD8000A1792FF49FB6A408E581C5ED790AC6D7FD
+:10FD90009E6F15B2E7535922E3DFBCC183DFDF61F9
+:10FDA000F7C3F7F759D9BA28FDE03EDBD47DB95E39
+:10FDB0005DD7F5594C1F9CE69EF354560AE823AADA
+:10FDC0005EBD31903281CEAB872301B04FDE33125E
+:10FDD000C58AFA4802EA353D3077A8BF3FC3AFD0A5
+:10FDE00071AEE78817F88BC64F7A9C9E8CE408FBAF
+:10FDF000A4A784966DC3F6684F8D2723C105CF5401
+:10FE000003E8EA1A7FEA71B3769A7C4AEB60E3A4CE
+:10FE1000DD57D80BEB491408FA4B962FCAEB6D430C
+:10FE200039BF00E74D3C9E0C8EF6777C559601E07D
+:10FE3000A8EDD767533DB7017CAEE3997DADED9B4F
+:10FE400006DFA7B2989FA08EA77A02C5BBE21C1F4F
+:10FE5000C293EA0DC528A055BDE12940DA08381340
+:10FE600021340DDEFF7F08AFED8807DF115E0DAD99
+:10FE7000948F182E808FA870DCCC058D698C8FA094
+:10FE8000FD0BEF411EAD73FB025911F4B0E48E0679
+:10FE9000D417B57925DEFEC2DC6B09D0E149A4BBDD
+:10FEA00025FF9088F6AA5E9FD3EC244DEFFC451CFD
+:10FEB000BFE3CBEAFA64CDBFAACE23B128F4ECBDF0
+:10FEC000145EC9C42E021F3D620A4D9269FB2306CF
+:10FED000DFA32FC0BC47F322E52123FABB2D9B47AC
+:10FEE000BCB16A7842C28E09AE613CD944F1C40209
+:10FEF000ED6B4C6807F738FD5B6F043CB966ACAC42
+:10FF0000482887919E95D644ACBFD4709480BF3862
+:10FF10003C5D14415FA47885F53D8BF3FC0AB3FB8F
+:10FF2000152BFA4113FCBD8077251400D0DFE209C0
+:10FF3000580F7637FA2B165BD87823F18AD9C7F990
+:10FF400084D5BB55BC5D9585789BDA4198BF41F05F
+:10FF500014D744E80B85D90C6E89A5A1E7DE013BD7
+:10FF6000E51EAB9C4B9829077E0CD29D86FD517CEB
+:10FF70003995C5FC0B8897CB7E6EDFC5F89E5C0675
+:10FF800070DE60EF266BD10F65C4F96FB706519F25
+:10FF900036582427F87B97F064731EF4D761140158
+:10FFA0004FF4F0B667C7F34B866E8DF44B2E312BB2
+:10FFB000E64CA8BFD38AFABDE69F5C92C4E84AF338
+:10FFC0004F027DC6920B9A7FF20615AF46D4777D1D
+:10FFD000995B4BFBFB0F15CFE4812F7297DAD8BAF0
+:10FFE000C1CF510BFFA2E3D6AEB37E00FECC5AC503
+:10FFF00018343B808FCCF18422EC2DB285ADC3F751
+:020000023000CC
+:10000000A6D10F706A15C8E6C7617F14B6FE96E5E3
+:10001000FE5591EBDA6662EB52FEC11EB5AE6D0E77
+:1000200016AFF8EEEBFAF3B4E8759D98A6AE8B58D0
+:1000300052693B55CEDDD06AFF802BA64F58177D05
+:100040009275745D05C3EB9A93CDF8E912958F8D87
+:1000500090BB71F7F17FC87ABB1FF2C45AAF7E9D87
+:100060004F677BAAB353906E8262E9305EFBB6D2D3
+:100070007595C2BEA6F8DB705F197E12E290818F83
+:10008000B52CA7EB82675B1AFAA59698A53EF0CF30
+:10009000928793D47512E4032D5BC7215D52BC6532
+:1000A00074FB108BEBB45899BFA0658D282B22AC44
+:1000B000FFD768CF86297F45BDA4359AAF7F3B1C0B
+:1000C000AC99B5459170B0642E2D8AB1EF8A19F1C3
+:1000D00039DEBEFF071FBE95CB8EEF2F23EBA2FDAF
+:1000E0000DE0371C2AF323CB7AFF05B51FCCD1DFF7
+:1000F0002BF1F8C14F23F1E88851C5A3B556943FC1
+:100100001A1E1DB1B3F5EAF188502D1AE8585BB7F5
+:100110001E8E4B008E31E209149F72018E4754FBF4
+:100120008CE2532EC051A3831B5A193FD0C3ED89D3
+:10013000F87CEDBBAD4387C7DF751D5A7DBC756884
+:10014000FAED166ECD56C0CF2D1944EC403D383433
+:1001500009EC2497C95F08F3DA66A2F44BFBAD55AE
+:10016000C707CD01F0FBB343CCBF79541D573FAF58
+:10017000E75539A4F77F3539C23B410F694A60F230
+:10018000F0CC013BD20DC9092D01FDFBEC7E330102
+:10019000FEDAC885F2E0BB339C67297ED7962881BA
+:1001A0005CD4FC86C79E677E438550FB17FC753E7A
+:1001B000E6F76C52FE753DECC3F96CA119ECCFA6C5
+:1001C000BE683F195D9F03D67BC64006E1FB46DE55
+:1001D000BF0A4CD6CD26A60F6C369000ECDFB05D82
+:1001E0007E340FED840C91805FA7D1F041DECD11FC
+:1001F000767CA35ADF98C9FC4C1057467F390CE532
+:100200001E0997C67B4E7D0D71B1C67D7A7A89A68F
+:10021000A7FAE132779E83FE22EADDC3F484F63842
+:10022000E06115F1E772E01F63E5C4B9837E884F92
+:1002300037A9FED394815035E80BF6D200013EDA9F
+:100240007482D92133FA77BD0A7E33E7DCC171A00D
+:100250009234A97104BDFD33BDFF7E1EFC439AFD9F
+:1002600012E18F2A5C10E5576CC776E0DF82F1421D
+:10027000F00AFCD302D37337AB7A2ED587916F2E59
+:10028000EFCE477D18F455D03B34FF18E821A08FFE
+:100290002ECCA91072E83ABFCCA9380FFC1BC6437C
+:1002A000BB1F9C2ED3BF817FA9F0D1BE033FD9379E
+:1002B000FBF3993E3543E7C7BFF98D14C4F3FD71D5
+:1002C000F4D45139437EFC34F0E3DFCC496980E754
+:1002D0001FF23EF4D7AF200AFA8157817F1CF960E4
+:1002E00010FDCB373513B90BE3E1BEF5506E58491D
+:1002F000C42EF02F57F9B01EFCCB574E67F12629BC
+:10030000027F219E1359267B68398A4F0FA2BFBAFC
+:1003100091F6B04D063F42F4F74DC45F29005EF4FC
+:100320009D3747F5D3C3E074838A2F5BADCC4F3D37
+:1003300063DD2E9E44F81992A678DC77013DBC61FE
+:10034000443FE9FF56F75783C7D3D915D61C0A8F08
+:1003500004F0FBC077779951CE1E379095802FF728
+:1003600039C90D0BC09F7527F1E418012FC4CC4883
+:100370007F97F6ECDA6F5D0978362B87F111EDFD8A
+:10038000996C2396D1EF8CFA6922C6D1295B2A0693
+:100390003C2CCBD2F462520CFEEE0F54FED4B8D0FB
+:1003A000E683FE4206C6CFE6E530BB7B5E8E09FBE8
+:1003B000D3CA43FE2215CFE838D85FC2541215C7FE
+:1003C000BB2A87C901CD5F4BD4F8CAE655094C8FCB
+:1003D0001EC27703F2B3C422AFC987FCA402F95945
+:1003E000F8CF3609E032F754FD2A58C7A78B120818
+:1003F000E41D2C53E3448D394EEC578B0BC5D0BF15
+:10040000AE0FBA86E58D869F9A9CD96F67EBBED8F2
+:10041000F8BEFE39B7AB10F9B7368F193ABD241EB6
+:100420005DDC364C1751F12D0AD744E0B3FB0DCCFF
+:10043000EEDA4F110BFD560135FE48ED649003FBDB
+:10044000F7E5A39EBD54F5A7523989F65598CA0B16
+:10045000B6DFBEADCBE1BB402EC6653F30FA9F7C18
+:100460001CE4ED01664768FBB17FFF183FD0EF8CBD
+:10047000535F6502FCF79F786A0CC4BBF7ABF1C50C
+:100480007A53300FED7D13D353EB1DC13C80DF4B0E
+:100490002ADED427D0327D9F95E2EB063EA4E50705
+:1004A000403B27AE477280BFE1986A471EA576257C
+:1004B000CC8B52CB20C43DE97E674039BC298DE905
+:1004C0007B745E8017C70E4CC2F56D36323C565EAB
+:1004D000E4D03F71D418FEB0957E7F34632A69134F
+:1004E00041DE7DF1F841E87F274FCC22E45F7C7E3E
+:1004F000AE8F7E7F96DAB9E037AB3378AB33805F6F
+:100500003CCFEC75FD3E80FC8B8CC79D21E14CF40B
+:10051000EBADCC0A00FE9CE92FC4BC22E21289425A
+:10052000CB4D2F32FB461F273E6E8CC67F7DBFB062
+:100530002EF0AF35C1BF41BE47B68FD1DFB795CFE3
+:100540001843796B293CAA245F302785B163D8CF43
+:10055000A69733901F1FBBF773DC4FD2CDE29FC726
+:100560008D9E25303F6755D0541B818FEFA8FCA38B
+:10057000CECCE435E5BFA6487EA3D59755909871BB
+:10058000FA3FA87CC13EC8E4DEC87A86E7B7924746
+:1005900079E017EFE448D8DF7835DFE056F2D92B61
+:1005A00066D04F022598CF307E5D10F9009D2FE276
+:1005B000E7F1AD49C81FC93D0C5F6F7CD88CFCE3E7
+:1005C000462A3F98BDCDF2ABC83D2C8FE2C3BBDCC1
+:1005D00088CF65EDC132A4072791412F79A1F3039C
+:1005E00085A7F54BF77025903FB6B4D38D76CA4DED
+:1005F000FBDCB8BF3354BE5E67F660BE187984C5B5
+:10060000D396FD62158ED390489C3CEA7F7E13C83A
+:10061000E5957B3802743523C0F87FBD107C05F466
+:10062000487DFE03F147C789411E91083D13E40F41
+:10063000D1D905D1FBAE5C94FCD5CB1B3E37B6FCC3
+:10064000A5F69E90CBF695C989BD1CE31BAAFC6D4F
+:1006500000F90BBA9A2AF734B9B942959B1FF24CAC
+:100660006EDF68BE1F9F19B96E1CE72688EB621CFF
+:10067000336C02FD241E5E64E432BCD2F062746E00
+:10068000345ED49F081E34A39D293F0FF1EAFA750A
+:100690002468A776DA8D4233CA87D1221131AFAEF2
+:1006A000D287F34A6BA1FA39DDE71B21063BE5E26D
+:1006B000F582117A804EFE6BF3D6F044AFFFCD5831
+:1006C000E7E7219E74328FE07BED29924009CCB799
+:1006D000C6C2F4EF1A8B2DC883BD59653C1D696FE6
+:1006E000FC58F094E5A25C1DEBFC7022B20802FD00
+:1006F0004E737B664D9836AC57269686D7DF4BFBFC
+:1007000033926203F0496D7C8B7BF692220ABF26FE
+:100710006110ED15924EC4DD74BC2B8B249C4722D6
+:10072000DD875D14AE464141F8192DA2B3CD09FB1A
+:100730003F887199700A413F9DB65F3BEC44817CD4
+:10074000C52B8B187D5F5924E293B6C738AEB180B4
+:10075000B6A7FD57ECB7225D9E7BD1EE07F94CE5BD
+:10076000CE7827AD4FFD13B55368F9CC7E3BEA290F
+:10077000675479E1D2FCB5643DEEF722156F14524F
+:100780003106EC11C25D3186CE9D687A7283335E8C
+:100790001C53AD770F2E64F86B467DE19C33741BC0
+:1007A00094E97C30B7C69BCBD6DFB4AFB2E40EE0A1
+:1007B000DF5E9BCCA0EE2B01FDC7CCDFB2D0428127
+:1007C0005DCDAF0BAF05BC1F6713CDB449D5F8F7AE
+:1007D000FFB09896FFBCCF48CC803FBBAF4A0A42DF
+:1007E00033C193EE9D34723EABFCC6A3A1083A5EC2
+:1007F000BD27BADC10882E3711E1682882FFB7BE0A
+:10080000BFEAADD722F06D6DAEDD05784024229FA2
+:10081000A7F474FCCE3E720C6421FF9324E08FCBCE
+:1008200028F9C7D22B3EBF73E55BAFD1EFACA68AE8
+:10083000B65C940B9209E8AB96EA0DB1ECD0C9B95D
+:100840004C4F339B9B4FECA2F031BF6496DB68ABFF
+:1008500079B9BE2EC0C74643F820ECAB79FCE962FB
+:10086000F067578CFF0AF302CEFD2391014EE7ACEF
+:10087000B3119FCE6DB54A60A7F664DA981FF6658E
+:10088000CECF31BB65FEB454C8FBC0B5503E165E3A
+:10089000BF15F8F474B3D82EE2722D06DC6F6ABD72
+:1008A000D1678F49590F7ED51E6A40B6C960E70DE2
+:1008B0003A80180655FED0C43F63B2D07FBA3B3DA4
+:1008C000856DF4BBD5DE0402F978C2D78217F06CCF
+:1008D00003741561F73CAEF2BF46F1EDF5307ED3FF
+:1008E00057B7CC4D310CFBF9CD46E6E737F6CD0EC8
+:1008F0008EA14D57B456A27D47F92DE38B07185FA3
+:100900005CB17636BEE716CCC5F57E48D70B70795C
+:1009100075AB19D7FBE1381BDADB1FEEE0B0BC4248
+:1009200034613E1FD54F46CD76C17BA3682623E1B7
+:10093000D1B465C3FAADB4FE77193CE128FE7FB4AB
+:10094000FDB7188FF888B0F1957D3CEA3D1F89E12D
+:10095000B220C0536A7644DA932B76F05EE0972B90
+:1009600076DCFABBE900B705D795023C66396F49DA
+:10097000956CC3F59ABE2724973F0E7439EBEBCAEA
+:10098000C159A077EDA07443E72D18880FEC8FD7DD
+:1009900076FC10F5ED1535094E589FB47D7735C8B6
+:1009A000B78F6A461B705DCF72440478385B53E1A1
+:1009B000FD0A4EF0C6C2AB65B92C9E307BBC4D061D
+:1009C0007FC38ADFF3882F94CE16421CA161871162
+:1009D000F5F9D716BCF787C5AE613AE3166C993FB7
+:1009E00003BE7FC288DF0FE953DB3F7E1FFC02F0AE
+:1009F00047253BC821849F9EEECCE3D7E5C1BCF4DC
+:100A0000F4B7A2BD398FC5F72F8E0EC9764687275A
+:100A1000299D9C37FC4D74F829E3EB174687646CDD
+:100A20007294FC1EC9F714FC4E8B8F5A64E2D96D88
+:100A3000C37C180F47F9F5983C01E13E268FD96D2C
+:100A4000C29737EF7993C26947AE4FC8A3EFC71378
+:100A50004F09C867292C56802BD6A6EA8D643BCB5C
+:100A6000F306FB02F67F730A79BC2BC23F93A6F60E
+:100A700047F9821DFA39F3C7AF0EC27E35669E2E46
+:100A800006BDBAE98BFFC4BC0A5B3FCBC7B1C961E5
+:100A9000CC3732BABC888F1ADF6F92991CD2AFABB9
+:100AA0003D8FD9AD4DAE30F6F3423EA34F2D1EB96A
+:100AB000AD3501E342DB5C7E2BF3B3507D8FF63F17
+:100AC000AF94473E6329ED2020C748398FF19C59E8
+:100AD0005FBD4520FEF5BB999532E895B6D25785A6
+:100AE00051B0CE72A35AFFAB8D59B4FEAD9973D0FD
+:100AF0003EBA399D9740AF9A579AADA0FCF4B0FC2E
+:100B0000DB595F25211DCE5F351FF54A6DBE5E6244
+:100B1000916C144F1650628DCC539E3FD32AD9222C
+:100B2000F0EBD36E6E2ED3ABA5A4AB2731BF50A094
+:100B300088C9F34838DC9C6EC2F1BFCC997D09C0EE
+:100B400077D6656C1F4E3E6BF6B7D3714F5A63DB99
+:100B500091D5790C6FB284CB912FDDF2AC19E3F310
+:100B6000A7B8D8DFDFB491C7BCA2551B39E2A7E311
+:100B70009D7CF2854CE0EB7FDEFD42666DC47CE23D
+:100B8000B5AFCB63FAC0487B3BB82CD2DE9E676220
+:100B9000710132C51CE5DF9DE750F3EC2F30DEF12B
+:100BA000A3B87EFE37C6C27CDF1CF2F3BF3E3632EE
+:100BB000DE3114B792999F5F1FAFCA29FF1775BE28
+:100BC0002CAFB95550E72B9B59DC62398B8BB71C86
+:100BD00018857837CF14FE39C6B35EE64535AEE1E9
+:100BE000B160FB74561F675DC4E3C97195A1BF096D
+:100BF000E7C3F57141BBE33BAC8FB038867E7DB572
+:100C0000FD7CCCB8DC97F92C0F20B1288C76D5D19F
+:100C1000D71F85C8FB10BE5BFBDD86C87CF8217D35
+:100C200056C5EFAB00BFE9FAAC1B59391E5EC7E3EE
+:100C300057A9798C8E35FC3EBA313B09F0ED2E4B2D
+:100C400063E820859F874F22D6D1B4ACC6FF95F7C5
+:100C5000593E2A1F61E7001DEC78DF8E764E87B182
+:100C6000F91138BFA3B40964377DEF4A68F4B7D1EE
+:100C7000B264B463DED4ED09F377815D17A20A2E66
+:100C800047CB9F271CD9057A02B12411231D47A900
+:100C900050DB9B2C6207D52F1E4A74207F695D466E
+:100CA000507EA79120C75180ECCF63F9AA29AB9F52
+:100CB000E7308F98523CE87D72766C7DF4572A5D60
+:100CC000BC0B0934F42957C6FE6E7F9EE617137CD1
+:100CD000A1083B6F03274BC877E85FDB74D0EF07B1
+:100CE00017235FA67AFC5B541E8CE17F8DFED963CF
+:100CF00077FA1E8975DE6148EE56C6B6D35F55E7B2
+:100D000057D0CDF98D0EA45FC3AE28FA55E378F61F
+:100D100054994A1888DFB2385D0ED1F2DEB780DF11
+:100D20007E74399BA3C31322A05FA4775F4E7CA37C
+:100D3000809E66A4817C6B591EED4F4BAFDD988180
+:100D40007EBDDADBE683FCDE62B46DE492E019ED91
+:100D50008FDBA2F3C77D1B5F488F4B37D3D3C1BF57
+:100D6000B16538FE87F8D3B154F4F31CAE8244C6A3
+:100D7000B5533BA4833ED083665BE45E7924FD904B
+:100D800072391DFD9CF9EABEA9F4DCA4A226D7CFD6
+:100D9000A15D3A921FAAF06C188BF0B476DF8E76C4
+:100DA000536209F36327AEAAF501FF49A4FC07ECDF
+:100DB0003893A999C3FD9FC1ECB6168E955B668BDF
+:100DC000A242BF37399A6763FD152CCFBAC5EAF343
+:100DD00045C6D32E35DC3C3B32BF5624B43DF0E152
+:100DE000456CBC7996752CBFD74775A48C61385675
+:100DF000A870CC294F60F9E6B75AD0BFB5DDDA8DBF
+:100E0000F33548CCCEAEEDB222BF1BC31760DC6415
+:100E1000C0C8F043B15B905EE58177313F6CCC2573
+:100E2000E912EF8EC09F5B58BD861744975760321A
+:100E30004907C17F472722435E4A0B271DACC07577
+:100E40008961458675AB7CB93881C9116A6EA63354
+:100E5000B8B2B8986EBF28DE30BFFA241BF31B115E
+:100E60009F847A976EBD23F1E6C502E0B70343780D
+:100E7000D357108BDFDEE7940EF646E20B91D68354
+:100E80005FF56E030977C5C21F39DACED7E7C9E926
+:100E9000EDFDC6D64AAF6A7F2816DC4F13DA1F8DE8
+:100EA0006B677B99FD51D006FEA7A6755452D136CB
+:100EB00095FD9C05FA6B5AE440FBBBA96F2FC6CF8A
+:100EC0001BE71219A651ABFA87B5751E35B2381E4D
+:100ED00095590188DFF738433BE17C5DCF2A2D8FA0
+:100EE00087E5B5287D9C9AC7A3E57D858F80FFB3F4
+:100EF0008793D00F3A744E8FEE3FCBDFB9B83C30BA
+:100F00007B91D70D96F8F4DCDE7F4B98763179B47F
+:100F10001FF5409E6CDC3C5A25780DD45B602FD4C5
+:100F20007A4003AA2F6B658F5582FC9DE17A81DAA6
+:100F30009D963E4E1DAFFA9A393978BE46EDAFFF09
+:100F4000013847779F95448D17393F41D73F989691
+:100F50003649FB7EFB02E8EFC1296A59F9FA17907E
+:100F6000377C9F31BA3F4419B53D14B4F1D29E7E0F
+:100F7000ACE79E99C37A3BD5E3FF317FDAB0FEBE82
+:100F8000E1BD79DD93E95889E267789E49D3C39B37
+:100F90005C2CAF568FE71B553ED6600955836ABD62
+:100FA00061D11A2FF43B94F7D6BFD40376B096F7ED
+:100FB000D6B4CE8BE79AA8DE7F4F3EE4D1FEF1F4A3
+:100FC00087AF10B0334FA23FA0E90B81F99DA9FD77
+:100FD000C0517CB1F4DF8FF843F618FDE0DAE97117
+:100FE0002A04F0B1E700370DF08B90E6CC6B28ECCB
+:100FF0008FE77B7A601D67E2C4C79FCD67767B531E
+:1010000041C5D63C80F5631C017DBCABE053B42BDD
+:101010001A5F9C332DF21CDEAABE07D979AE3DC6FD
+:1010200098EB7E369FC7F535BEF81CC64F4EFA3991
+:10103000A4B995827F13D89B2B571AC0B222A5FE64
+:10104000A598274B169908CCFF01D50E69DA739540
+:1010500002E7029BE87F9404C836EF8DA86F6F5BB0
+:1010600064B1411CBBA9A0760DF23B31C103A69C23
+:101070007E9E43F96F6B13308FA6ABCF3817ECA46D
+:10108000324A17FF6403BE7AD8BD0BF8E7A8297C63
+:1010900087087986B1F5EF670A991CEFE4BCCA8F1F
+:1010A0004B312E4222F399C7F731FBEBB57C5354F9
+:1010B0005CF0B57C6617CE54062B01D75E164289CC
+:1010C000600F3711CF27E0F7225E9B847121124019
+:1010D0007FA0EB4E09ED268B2B74F764A89F29A007
+:1010E000DDA4F911CEBC9886FA584981EF30E0456D
+:1010F000191F7AE0C700B7BB0535BEC4F84AE655EC
+:10110000B629605F195D4C9FB1527D06CE7B5CB6FF
+:10111000E9F8BF56026F7579518F2054C8C1B9F1F3
+:101120004A0BC7E22B3ABD99887215B4AF56FDD26F
+:10113000B974B73EB4206A769E1F05FE0C9702F084
+:101140007E9D2E6014AD9F433C9DB02F5FAAFBB7E0
+:10115000D9C4F4F5CD060BEAEB9A3E9CE81A443B61
+:10116000B121C0E1380D05BFC6F302ABD5BCF4A177
+:10117000FC702184F9F2A7F313D5F86727C34F3227
+:1011800088FE30F20CDB07AA79621EBD06772DAF10
+:101190005CEBCFA4C64B1B547F2E0518D67F9EAFA9
+:1011A000C557DBA3E3ACEAB84490CA22FD8E9B6B23
+:1011B0000819C479490E986F57AA9714D0EF8F5227
+:1011C0003C063C3BBA31D10FE7B63673831E887BB1
+:1011D00028252C9EA1C7A794024E3D1F14AEC6BC65
+:1011E000AB17E39C0FEA8B3E1F44F9C39ADFD07123
+:1011F0004A4BDF9301BFEF73AAED2F27984FAE3F05
+:101200001F34BA40C271FEDBCE07C99CA7973E735C
+:101210000A9CECFC8F763E486670D7F231F4E78288
+:10122000CE64040596C71FDAB91BE59E19EDBB977E
+:101230003E3ED809FEE2B3252619CE43A45EF77AD6
+:1012400027E6C5704233C415F5727D97BBB218E02E
+:10125000FFE035CFCB98F7AB93EBF1EC798C794687
+:10126000F87B3CEA7E7C5FF6BCB5FB7307E0CD29DA
+:101270002EFC73C847550EF031F3516F28E0E2E4BD
+:101280006D791645EA999D5ADE9633212A8FB1333E
+:101290004EDE563CFD5D889BAF7539EA619D43F992
+:1012A0005A73353D2C3A1F554CF846BB571B7F6E81
+:1012B000C81D155FBFE582D7A9DA2371D617CFFE07
+:1012C000BAD87C013D1C3AE3C8C37505F1F2053C70
+:1012D00022C4D73B21BE4E9F024714F483ED1DCAA2
+:1012E0001708A2DFF7B97CF45F99E3E60BB03C3254
+:1012F000E140BE04DF6D307A3D6097287B8D2A3F48
+:10130000F73F09FE8FCE0319E82F2305A162E07392
+:1013100082B33A1DF4A34E153FEB2F3C5F6073413F
+:101320008C7C815DFE293FCF6276F06022D5AF765E
+:1013300011266F947EE69FA4F346FF5CF8DE71A849
+:1013400077720B2CB88E632F9B7BCDA84FCB18FFE9
+:10135000AF4DE74590133D35651F821C3A46155049
+:10136000A0E3BA9BD6A11D1A6F7FEA3646C763B5C4
+:10137000F717BA4FCFA9FB7414EC7414980AFA7DCE
+:10138000576EE45EC1BC5B5D3CF805E021C8EFA38D
+:10139000E3FBE7ACB331AE7ADB2F6A309EAA9DA3A4
+:1013A000D5CECF12356E226D1490DF4B7B38BFE463
+:1013B000666462401B5D34E07D1E544C6D03D1A613
+:1013C00050AAB984BEE60C1CE89B52272DA7D17504
+:1013D0006D129474FADDAE7713D18FBAC125A9E7E7
+:1013E00021981DA5DCC3A11E47FB453B58E9A47805
+:1013F00043FB79A780F9F7CF16303D83A2881FE71A
+:10140000A33E3BD57C086DBC366208C2D3C0B1E7B1
+:101410000651981B4B4FD3FAEB34365B206E121EED
+:1014200067C0B8E439936711C6F592F308D87D9D7B
+:10143000F6E68D73593DF2D073D6B017EB7F2030AE
+:10144000859F48C930DF37D5FDD0EFEBF2EEE8B22B
+:101450003E6EAFBF17A08EF8F233B2479E937F5314
+:10146000956BE7BADCEABEC818F7EE344AFFE60629
+:1014700039B7494079DA3696C1CD308E3DB39C55A7
+:101480008B509E3AA99E89F365F3CFFA818B03FABC
+:10149000EB7432FCFAAEF3D6CFF7F3823CA63F8270
+:1014A000F24FC7EBDCC4F919BCD8BC2FD4EF9C5267
+:1014B000F8FDFA9D8F71F2E341C0339BFF61F0DFCD
+:1014C000D5B59945E067A73895FE37F1C8CFB6ADD9
+:1014D0004CC6F2D18DB9E8CF19A2DB13EBD7C07D92
+:1014E00007179A7F955FC8F0E2773A7F5A6D397790
+:1014F00018FAD1C31D104AD0E40F6D5A79555135F1
+:10150000F0C7460391D2401FD8A8CBF3D0D1739532
+:10151000E49B5608FAA269F020E353A13C01F56868
+:10152000AB0C707BD0706CEF6F015FF65A316FB00F
+:10153000715DF871F03BA64ABE998514CEA7D7BE5F
+:1015400057CD49D81DDA5B670FE4E3FD19B59DBAA5
+:101550007B09EE89CE2F211B9359FE464FF47B3831
+:101560003F1FD56E44DE09D33F379B7C856027CC77
+:10157000BA8CE5EB7DBCCA40002F3EB632FC51EE82
+:10158000B5AB7246CE8BD44F1717EAF4987BAD8873
+:101590001F75EA7925FD7E34007ED07DAB57F1E3DF
+:1015A000E3E72EC903FC38BDF7923CC08FCDC66E71
+:1015B0000FDE2390E3FB29C0F1F81CEF4103E34B5E
+:1015C000791783B7F5FA79FD9DF4ABBB0BE3C54DF5
+:1015D000A49F44C64D068CCCDFA558A3CFFB0C5C62
+:1015E000A47F34BE9FAB3027DACF55901353BFB2E0
+:1015F00058BF51BFBAF875103CEFA5C55306ECE1D2
+:101600009F3F1E01AF162BCB2B69291445A504D68D
+:10161000579B8DE7C7FE68917BB9EF759D51FEBC66
+:1016200097BFCA5EDF0DF3F030FFE3CB8274F05258
+:101630003AEECB84F91FF5EBFE7D3ECB83D1EC6710
+:10164000CD9ED38FBF57DDEF8142CF4B601FCFFAC6
+:10165000EA3CFA034EC03D39745C8BFF9FD02E23C9
+:10166000FD9C88E7CF2416CF6C7C71F9A3E03F5D29
+:10167000E557E390FB38B4BB573DF609D69FE9AB7D
+:10168000C37A5B3F17847866D35803CA6D2D8F41A8
+:10169000F3E334F5CF2680A79A1F87CEE30598475A
+:1016A000A22B6C42BE0576226DD728B0386DA38B75
+:1016B000C80AB0DABE68FF8796E7B4CD6B427ADF1E
+:1016C000D6CFF9C1AE4E35F9DC63119E63C50F1359
+:1016D00087F9C65B859ECF805F6979684F677B0E0F
+:1016E00003BDBA4C2413F3DDD5FDF00DC577D879D1
+:1016F00089BFBCCDCE4B84E2F0EBF70BB5F3120BF8
+:10170000517FFE0BF126C5CE23F7B33CF2A1BC35C9
+:10171000962F5E3F8FDAC84E56867B5F1AE0DE1743
+:1017200099C9CFA04E7E4696214F2C18C137EB8524
+:1017300041CC47D7EE7981BCB1C8EF1BE1BC45363F
+:10174000CB1F8BEA47E5A769FCCD18C789113FFD80
+:1017500049A4FD7148B3B34AB4F3316113F8695A2F
+:10176000DA5C6188071CB2ABE776D5BCD8166BF89B
+:1017700018F8315A9E4CC3732043FAFDB366D50F57
+:10178000CEF0BE9EFD9334AD3C8AF67A139CCFE733
+:1017900086E9695E5CBBEC8D1C88AB1C1AB2CB5E23
+:1017A000CF8173341A9FAD9719BFA8EFE3D879AAF8
+:1017B00040F4799A3113BE5FBEAB7D17AFFDF409DB
+:1017C000F1F8EDB7C199F1DB43F1CE21A97C528349
+:1017D000A39E1F5D2CFC86E492063F4AD7C86F7516
+:1017E000F0D3FBC334BF16E914D1EF45759200E482
+:1017F000656A7EAD0B9587F3BFE77DB95079D83028
+:10180000219E1DFEDDF6279E9CB8D87D19210F6113
+:101810007F8AE3CBC39CF27F51E7ADCF2750E7AD82
+:10182000CB2738640CCF67F75150F8B847E613C49C
+:10183000C5BF6FC927F81BD6A9CB27F8E675EAF311
+:10184000091E39F09003426E70EE0CFC0E03BB8D46
+:101850001847AFE66D1E96E7C5B3BC50E2C1FB3139
+:101860009B2C56F42FE8F3E028A75ADF0CFA6539D1
+:10187000D5FBE15CCE8E0E94CB0D193CFA1C21EF0A
+:101880004F9462E4590A3549416964BE17E4B1E3F3
+:10189000F9FE8BCCF7DA336128EFD2FD37E65D062F
+:1018A000265C40BE57712EA3BB576D9F8D8ABCBF6F
+:1018B000B2A2881AEA45F1F3ED5F56E93551CDD36E
+:1018C000B5080A89F447C56B777002B3775E358532
+:1018D000DF0D805E45BB81F865BA895AD3A5C3E7A1
+:1018E000D68FE77B5F87F9537D04F7F7CC8BEFA0AA
+:1018F000DFFE910C2242FEFB234605F75949218861
+:10190000D75A5E8236CE5AD58F7DA1FCE7C8DF5903
+:101910002EFCD7FF74BE33227F89D1E3DFC06F90E6
+:10192000FE86F88991C575B47B2BBE55CE7DDF7CD4
+:10193000469777116F5D5FE613C487F113BD1913E6
+:10194000918E3CE867BC58F997584AF52180C73E0C
+:10195000B304A46651EFA720F764687E5176DFDFF9
+:101960007DE350EFFCD8CAE6ABDDBBA1AD67CAC4CE
+:10197000EFD78E2DCEF1964EA4F33E3EDB83E77774
+:1019800037D899DE167E92E5AFEBEF91A074C3EEE7
+:10199000D550EFE1D59F87AFD6CFEFEF24BF974F5C
+:1019A000FC1F4E471729BF2F7E1DD1F6EC213BCBE4
+:1019B0000F1CB667FFDBD67551F25ACB172EAB184A
+:1019C00054FDFD1C017FBF364ED3203B6FB351DD6C
+:1019D0004FEDFDEF54FFDEA1899E4D4087A5A5C1C7
+:1019E0009D70EEA49138F01EF1C6C0ED7BDE74B19F
+:1019F00073B4582E607147E2B5E139EB1DB9BE07EB
+:101A000018FD86D6037D8E779132881B74152C20A5
+:101A10007536CC277808E860FCBAD0CE374B319FBA
+:101A2000AA19E855CB272E3BFFD9FAB9A5385FF4A0
+:101A3000FFBACCD1F76FF44D64F6A0F67C4EA50347
+:101A4000BAED19309FD32BD9B9D2269747043FB2AC
+:101A500016BF4E940631FEDFB88F194565602B42E4
+:101A6000FD1D6391BE1AF7CD2E81B82609584BF0A3
+:101A7000FEDD3FB17BAF4FAF1D8DFEC69202DF2F63
+:101A8000615DF652FFE560478FA7E340FCF3F4DEAB
+:101A9000CB4B7C31F8661A9FAC407C388D27810790
+:101AA000C461BE45EDE7C5E82F5E1F463FD6CE892F
+:101AB000128B27BB985C6FEAAF21CB6DC3659B2B64
+:101AC000FA1CD540E19C9D308F9D13595C5FCBE79C
+:101AD0007453350CFC867A7C72ABF99C356ABE3245
+:101AE000512CC379CA59DF9ECFA9CD4F2B6BF99CDE
+:101AF000895F30FB3D4B3461FE877D23E3AB641D82
+:101B0000C1B8C1CCF060651285534E4F7026C02914
+:101B100009C08EF7B186EE9E4CDFBB460933C11F6C
+:101B2000B2B375CA00E8BFC2A6C11FC09648DD6245
+:101B300005B81877E47ADF033C21427301F0A58AE7
+:101B4000DF1BD979A34D89A857F664D6E379A3336F
+:101B5000EF9963DE27A03D15D29E0E7187AC8DFFF5
+:101B60008EF17DFB3E2EE6B9B44B8B6CEA79A4F680
+:101B7000748863D8370E2AE5B4FFAC7B39A29AD1BA
+:101B8000195C3AF8870503C8D7BA3E764F5D5DB752
+:101B9000B3C282F286F96BC84C17CA1161D395069D
+:101BA000E013421BD562E93AA714B1F8746E8F684E
+:101BB0000039F5CF5FF331E348E755BC6EB0844C94
+:101BC00000AE0673F860BA7B385F473BAFA2F97B83
+:101BD00086E4CFBEA5E8EFB9F8FCECF0F598FFF786
+:101BE000752AC657E639983D4205917A4F4B74FBEA
+:101BF00011F7B4A87A8B6617EBE9409FEF9C533E30
+:101C00001AE982F2D1C036318AEFC5CC7B6E1598C5
+:101C1000DE4DD7616A8179CC4E97C13F77A179E6D5
+:101C20007A7B7A48CF51F5126DDE7F6B5EB6565FD8
+:101C30000FF9D831FC1F9A5ED3A99D67FE9ADDA3E8
+:101C4000355EB5278E76FD5731BBAF50CBFFF0E345
+:101C5000533052FE89F813BA4C013CD8E73434169D
+:101C6000617CA911FBD9C4EEDB1FBF31BBBDBC1425
+:101C70009E22E128BC8FEE5F3D1EE3B7942E726377
+:101C8000D0C5918946D6FFA644C463E17E82D98C33
+:101C9000823315F1587890E1EBBB13197E69F9672F
+:101CA0005A1CF0D0449F17CE1B0EDDAFD19AC0EE68
+:101CB000D750F3B8EDADEF3D0BF756EC54E3C0034E
+:101CC0002F4F5C80F1B94D0207F6E139E7D2F1E020
+:101CD000BFBBBE88E1B95D1824A22D925E07F01C3F
+:101CE00060D601767E4950F34D854DAE5D809F16DE
+:101CF000B70FCF3BFEA033C8633E9378FC81B91287
+:101D0000D81D6113E49F9D6C13C2ED4ED49FA2FCBD
+:101D1000647ABF171102985FD354F4F7B543EE2DE0
+:101D20008AEB9FFA4EE728C8B7F8A7BE2B5EC7F329
+:101D30004F5DFC3AF4E727987D425E66794A31D6DA
+:101D400015E5BFFCDED7A5F92DF5796723E898F9ED
+:101D50003F347B488B3F108F1295173E601483A051
+:101D6000F7409EED7332E8D54F5823F3C29E57F1EA
+:101D70007EE8FE3EE2B7C2B9FB8FE1DC30CA3B79B8
+:101D800023C4416FE7EDDD60DF7540BE3EE897009C
+:101D90005F2EE2DCC2FB76CC7B6815D8B906A2B018
+:101DA00073112DCB9B9F80F62D6D6922C05FA968B2
+:101DB000FE159E7B30106F077D7EAEFEFE84361FC3
+:101DC0002D8F3F9EFC1C91C7FF2DE71032E29C43F4
+:101DD000785BC5FB826504CF21908D9E5D30AF9E00
+:101DE000368140BC37792E2B8F172CF87B2856C8AC
+:101DF000871E85E746316F394CE109F9D756C88708
+:101E00001E05E744D87D85DC82B9887FC9143EA0D1
+:101E1000177418D9FD84CA3536C4A7CAB92C7E995F
+:101E2000EC3521FF394B64CC9F57E01E3317E05946
+:101E30003BE267D89E8AF1D7E41CA6475ABD2683A9
+:101E4000C58DF9CE88AF614ECB77667CAF67A9842C
+:101E500079E843F7152E27B83F9B72AB33E0770044
+:101E6000465F65E2205EA3C9990A153F7A76A9ED1F
+:101E70001B587BB8CF10E6475A58FBA1FB0C7FCA12
+:101E8000EA5B8510DE07447518F53E3D56DFB23833
+:101E900015E98757CFAB92EBD47C7B8EDD1FD5B293
+:101EA0007834AB77303E486E4A50E5B9DAFED664F6
+:101EB000BF1A2F6079F3AB0CEA3D00DD24329EABF4
+:101EC000D159F2B79CBBF8C570FE3CD273C7E5226E
+:101ED000E6076AF73156D84CEC3C96259AAE9E2917
+:101EE0004A66785F2E5B60DC656E4FFAA498FCD181
+:101EF000BF3492AF8CD6F8CA4D269D5D96C6E0EAF7
+:101F000008EF64E7B6CC176597C58F2B3E99111D76
+:101F100057DC93111957D4F6B762A509F94A8F53C4
+:101F20007A0DF28FB651D0C2FD76FA756F1BBAA743
+:101F3000DA6F05BD546F0F1E8A9367B46812F3E71A
+:101F4000C971FC108B26C5932F71E2B425E6FFA65C
+:101F50007833E3BF0371CEE90DC14BD39B2CFAB8A4
+:101F60008772517E9F01CBCF900F7A3A0462BD8C6D
+:101F70009675E7CA281F44BEA8B49BC50E17F0D1BA
+:101F80009F215F6CA596AB39822F5273F412E0C784
+:101F9000037716E0EFCBBC76A78CCFB3562EC04F9D
+:101FA00086677809684C4B8A0F2C847B9BCFDAC3F9
+:101FB0009970CFF3BAC96F5C8BE594F01128DF51AB
+:101FC0004C16613937BC13EE7DBEBFB8FD5AB8D789
+:101FD000F92CD0D868426E7DF6B66B9522FC3D8414
+:101FE000F583A0DF97EAF2F175F7D0C2B951584FE7
+:101FF0009ACD8471DF34F5BC2EA952FD4390E905DA
+:1020000074975182797A3622ED1B84FAB14CEED264
+:10201000FA36B8E7B423D7CDE2D084F1013256CDF9
+:10202000E3202105FC511D6E27B61FD2EFF699D58E
+:102030003C3036FEE1E7D8FD3CDA396442C47160D9
+:1020400037DA241255D6EE752682380EEE61ED5041
+:10205000F1402BF7A7F91E9A1461571E9E737B114E
+:10206000ACF3E3E7EFC8017DEA87EAEF32E9F1EA92
+:10207000C6C90CBFDB13FFBA04F8F8BBBC4306FFAC
+:10208000414B9A6F17F4B7DCD536CD49F1A74A9C7E
+:102090008DBFFF324359CC015F715ECDE6E7ACF2F4
+:1020A00072CB8B867F1726C527A09F9EF87A78D0A3
+:1020B000B7538E7B45804FBD259C29D07EFEE4F230
+:1020C0003D03FD9E5BFAC16D989737FAF011B81F7A
+:1020D000F2B0B1BBD201F8E456EF03A63B06E763CA
+:1020E0000E8E19DFABFEBE0D3B2793CBA971D860D6
+:1020F00015C8852B08C35B2843FD95EA7D67D5226B
+:10210000BB3FB3BAD48DBF57369F8405C087EA77EB
+:10211000BD0E02F471B5AF34D6FD13DA93A41BA53E
+:1021200048FAB95C8A28D3FFAE2C882EFF488E2E41
+:10213000FFB8FCEBFCA8B2E07963520AC837267FEF
+:1021400094E94CFE8824D00EF2F1A966710AC6D536
+:102150005D9C02E5892F8CC6BC2492CEF2192638EC
+:10216000B2FC0C0ED9DB615D612AE77B5DF0BB47F9
+:10217000EC1EABD4774DBBE09E042249DB810E9F61
+:10218000371660DE66AAADF69FDA509FB1935CE425
+:1021900053D276C46BBB4582DF6F78C5CEF2113A5D
+:1021A000EE3760BC8973580C1EFA1DDF2B30F96FB7
+:1021B0005F5909F57C19DD102AAB079CEC77943A3E
+:1021C000A611637B09EC9BFC2EEA45760BE6ED57E6
+:1021D000390A7E02F5BCC384F73ABC622FF3A9E347
+:1021E00011E8FF31FB4A6C0F3CDA48E977C0CAFCC2
+:1021F000EB3CB58FDBD9F8F87B69FCCD441DDF42A1
+:102200004C50AE2598873FE014D97C6F35603C0474
+:10221000EA2FC3F959B05EBB8770F8DCEB6C01EFB5
+:1022200063E7881A1F6BC3F2432A1FEC308AAF00A2
+:102230009E2A7F2604F6A3CAF105D2016F70C878E2
+:102240006F8E87E4B85209F359D0EFF9543108F989
+:10225000ECFCCD0EB49B41F3817AF02110A46BC14C
+:1022600043CA54D70C8EE7390A783C9E235ED88F38
+:102270006B8BB3901F3D6A38BC05F32B6C5EB34C7F
+:10228000C7315D47707FE5C4D8E75DF38A199D8E3D
+:10229000DCBFB274C8E3E01CE5123C3BECE5129CE9
+:1022A000DF1970CAE9DE88728C7DF103DE0CEF8BDA
+:1022B00025682886FD9025D02FBEBD3F5A6F83F537
+:1022C00048382F7EB42C811D9AE3A0FD50BE2F8F7D
+:1022D0008ABD8E6BD57504D4FBF1F4F595C586EFF8
+:1022E0007B9D3AFCFB8EEB4C8D5EE7F738CF10F709
+:1022F0003DCC93CFA4F3B30DCF8FFE13EFEBBAC257
+:102300006640FCBA42BB37A920FADC85FE9C0595E5
+:10231000C05B81CFFC50CD1FAD48FC47F4E35F4E5E
+:10232000F57C906B07137F9603F99BD5496D9D8CC7
+:10233000389A4F2F077E6CE190EF5C4982EBE1FD0C
+:10234000D9D9BE479CD9C8F75717C3B931DE979F73
+:102350004CCB1F1BBB73D6B8912FD6C37B1B092355
+:10236000DD5D01BF8F067437CFDF09653A4633DE86
+:102370009F45E910E856A3C391F3A77449BF1FD343
+:10238000ECC0734D3B48100FA6A5936E8EF95B9A77
+:10239000516E1169DCF03A29D1565B9A711DBF6DFF
+:1023A00053503EFCD0F98000E587655F1BCC6BD1B4
+:1023B000E44FF0DE7B92BE341FEC4E3ADFF6FF971F
+:1023C000F31D79DEFC9BCF51FCBDECD1C78B599C32
+:1023D00043B3475D09549FA0F39438874CA8FE3857
+:1023E000649F1A2D9897307C3E375C87E780B9242C
+:1023F0002FC833ED7CAE9EEFCEBA8CF1DD8FD7388F
+:10240000E476BCAF700FDAA54D57DBB4F3BBA87F01
+:1024100035AD34A8E77739942B8DC482F7070DFDCD
+:102420007E1CFDE352877F9F633F9CE32DFDA673D7
+:10243000BC129E1356D6B138FD907DD72032FB5585
+:10244000FB9D875BB3B4FBF8999EB2865C907D1BC5
+:10245000E37C2FEA8D24C9A0DAAF4C5FE8992E897E
+:102460000AC1F82AD3C3179BB07E73821F7F37A59A
+:102470008EEF4624F963B153BD17C16FC5DF5732E4
+:10248000C979C027B438EBC21CDFFB80BFCB8B3CC3
+:10249000991C5D4A9D89C54F291D6C1FA4ADE6920C
+:1024A000E6C7E0F7B32E27CD6F1BB2910E8E221D2B
+:1024B0004CFC84FDAED6301D1C2B86FC06C2FC01F4
+:1024C00057A871A2973E7EBC13F6FD2C47D8F9AEF3
+:1024D00002FDF92EEFA9629C5F48FD5D9D68BE1369
+:1024E000318FE346360F17CFE33C3E8B358F1174A7
+:1024F00048FC383EDDDF663C47AEC323FD7CB8FEBA
+:10250000DBF1BCFFF6EB89C84F07393E6805788ED2
+:10251000058CC88675FA0C93A7A13CF7C1FD669A95
+:102520005D3D62DEBC0DF775E1E2A13C9DF91965E8
+:10253000102762E33E94D8F820F83D9AAE37227F08
+:10254000AFE99F847ADA41C52C421224A962F93599
+:1025500032FD1FCC6B11F1CC71D27EAE126BF0BE8E
+:10256000B4ABE7E9F37294BB9A69FB6BD43C9F85EB
+:10257000571B8F46EA9B678DF718010E4A9DAD9950
+:102580009F01FD09C3EDDD23E132E2BEA64EC69FE9
+:1025900008D573A0FF8EF200F2A7787C2A6FF25064
+:1025A000BE4FFEDF98EF533C19F1E29BF37D64359B
+:1025B000DFE7356318EFE1FC4DCA8AED6BE83AF3CB
+:1025C0001F2EC2DF139D93BAEAB1FB69F9896D131F
+:1025D000B0FC9BD4EB6F390CF53BF3B05C65F86451
+:1025E00009D04341D9E22BE077585FB3B27ED213D2
+:1025F0007C3D35F4BBF4E2AC2970B14B95298CDFFE
+:102600005D39B9612AF863AA1258F950C93B53B031
+:102610009CA596A7BC3401CAAF719F2C89C517270A
+:102620001670C1422A6FAB92D9F7F3A63C391AEC67
+:10263000F8AA0A569E28CFDE940DF5864F97C4D28D
+:1026400097AE9FCCF8EAACAFCE768E72415898FD2B
+:102650003EE80B9E0FF07736BC54DEC2397C6F39F2
+:102660008BC3793D2502FCAE538587952B6D6D1983
+:10267000C007E7FB4CA51077156DEE4EF8BDC2A460
+:10268000F2D9D360DF2BA9BA0D714E4A5F37009E95
+:102690002FBAE4934C07EAA51A7D8946787EC37D5C
+:1026A0008BCBD8BE45D303ED6F15F67769B4FC1C10
+:1026B00041AF3A3CBCC23296E11D958BE6F291F4F3
+:1026C000AAE7DF647D808BA4D71D80973CD2ED5AAA
+:1026D00018DF641894E0FD784E9E207E03FD9E3541
+:1026E000BEEFC638107DC15F1A836FD03F41D3F370
+:1026F000D92C443115F397595E4FFF3BD81E8E837A
+:10270000F01938FE26189FAC67F3D901F790F060F6
+:10271000EFF91E053ED198CE7EF711E2FA40A7E907
+:102720001ABFEA8B5E6F47B97C93931F395F83852D
+:10273000C1F16A551FFB7DAB37A5844E7621693602
+:10274000C27A1F4A742810CF6DAA65F74906D27C59
+:102750000FC33EF106E540889697138F89F137CF76
+:102760007698A7B62F8DEABE345ADEC77C36F8833A
+:102770007B4E46C0A34FCF47A3D73FBC2F8319F052
+:10278000CC807B54B2619DF2463EC67A88D0BC298B
+:10279000D24FFFD0B7FAE909F3B7C866F55E94F0F7
+:1027A00092487F5C87BDF991483B999A65789FD1A3
+:1027B000A1B61C120BEF343DE910A7FAB5A8DE0B49
+:1027C000FAC0E7097F45FD84528CD798097EADF9A0
+:1027D000A8C770268B08F1EBF4DA74C4D72D542FF8
+:1027E000013FBB5211C8467FF94E9EC0FD03C37026
+:1027F000A033710FE3E7F1C9CC0E4C1B8287827CBA
+:10280000D464E062EA57C7271BD47B50D9F9D2467B
+:102810008B99E57FAABF4BA1E5B1345A8AD637E33D
+:10282000FA2C8C7E74FB3422AF459F27674943FD09
+:10283000429C4264908723F360F4768282EBF8D165
+:10284000507C8130FD67AD1DF59F1FA9F1056EC15C
+:1028500017B83FC914BFCC2E8823481CD82BC9A554
+:1028600087053269F87724E1F797C09FF57C96EFEA
+:1028700093C911F1F837A73D817921470C2C0EAA95
+:1028800087CF5743F00961BE6AA3C6AFF4EB8F331D
+:10289000FFFE34EF5F61BC8FB9C132A8D4E253545C
+:1028A000ECBBA1BFFF0B8F9234BF00800000000083
+:1028B0001F8B080000000000000BE57D097C5445DB
+:1028C000B677DDBEBD25E9249D859010960E3B129E
+:1028D000B03B21618726408651C000A2A008371076
+:1028E000D6AC82CEA0E3980E0144079D38A2328A6E
+:1028F000DA202028308D02A246A70544FC74346EED
+:10290000E3FA98C40551B61844719E6FFCCEFFD40B
+:10291000BDA46F13467CCBEF37EFFBF0375339B7CD
+:10292000EADEAA3AE7D4D9EA5475923B6B5492474F
+:1029300008F1C38F3FFE982FC495F4A7E82644639F
+:1029400037CDEECD13E26A5134D6AA08913C4EB38E
+:10295000692E21C6AAF47F038468D9A6041DF47CDD
+:102960008C3FC6225285A83C640B06095EFC8A2A6D
+:10297000002F7E480D0A825B84776D23DA071CEEF8
+:102980000095F7C7F5FFFD302A3F7DC8E675A0DF4B
+:1029900080FFADDED46F09FA25B8D75A8BF0380521
+:1029A000FFFB91FED727182B3CBD5BE1BE5B924D30
+:1029B00070BF500753FB4BF77635D5FBC29798EAAB
+:1029C000730FE598E0BC8621A6F603DF2F30C183A4
+:1029D0001B2F33B51F7A74B2091EDE7C8DA9FDC88A
+:1029E000B3B34DF5A509850797D27C0FA6AB421965
+:1029F00024C428516A6A5FAA96D98585FEA8B37D4A
+:102A0000D248EF55D17F3F7625589D61059ECFEC8A
+:102A100055444A9610F3D7CA7AE3BD05F577AFCC93
+:102A2000A47261D0FCBC54585B617A6FE9C70BDFBC
+:102A30003810D15FAFD4624B1295A3BCF1A947FA0D
+:102A400062C262E08F2AD3D51B069DDE51BD0E49BE
+:102A50000AA6F3E2ED4AF00EA2634FD1E37ED08DD9
+:102A6000E82C821ED055D6B7AC538301EAE7BBEA07
+:102A7000056F1CB0117C28776D23D17F7E8DC3AD8F
+:102A800052BD23DD4CCF188F999E71BDCDF48CF7CC
+:102A90009AE99938C84CCF24BF999E29E3CCF46CAD
+:102AA0005764A667FB69667A6668667A662E30D3D5
+:102AB000B35395999E5D969AE999155864AA8FE645
+:102AC000DF6EAB169BEAEF8F7BE188467848EDA07E
+:102AD000BA1D6E217AD4DD6CFA9E50C7DB5710BE4A
+:102AE0004A3355A1BA5BF92040FF311F882A5E5F47
+:102AF000F3880F1E203A9C11AB0F667ACEE7878AC7
+:102B0000BD77DBB13E7F2E3F2C8BE203E2BB447CE2
+:102B1000E747FC1B797E69D0F90AAB7F95B79D101A
+:102B20000F7AB5DFA19CD6EBEBCE56921BA2A8B8CC
+:102B30005751BC102ED13C13FC542112BC77A07409
+:102B40007E9C057EC13F4706FD9F5F74B712DE1471
+:102B50001D6F62AFED78A3312E9AB752FF5E16E675
+:102B6000BD8E985145FB892145D0F83A8A860CC81C
+:102B7000A70C51A5A04C17DE552AC6EDE99484791F
+:102B8000E0CF1F3399309630BDFF41898DF97759D9
+:102B90005CFF6DE0CBF76B255F9E4693C1425C23E3
+:102BA00042367CE783D8073BA1BF0242B832189572
+:102BB00075D761FC33307EAF10D789461B3E3E4B44
+:102BC000083BCA62E1E1728EF0DBF1FE5C115E89C6
+:102BD000C97C94AA6D073E2A54AD4B1AF0D1B1A11D
+:102BE00073513F2A5F4BC1A02F8857505CD07B6F39
+:102BF000E34F6AF789B76837BE33DAE9B9E15EC2F5
+:102C0000CF3E8B581022BA88F1293C6E612DEA37ED
+:102C1000B95F5BDF5946424D88E7144D03BE031987
+:102C20004EEF2620393DF4A442F3BB24D9937347D9
+:102C3000526BFB035E0BB727D60B28D4FEF15DB1B8
+:102C40008CAFBEEDD727635E3FB7DF06AFFF558C75
+:102C5000DB68FF53F3B5DBBD8B6EA47E9B1551B5CE
+:102C60008106F18E4E974C07F10F8D37534DF0D6FC
+:102C7000826E71330FB6233C2C69AF7D00BD34EDFD
+:102C8000EA5FAE04ACEC4BF12CA6F19D2A6ECCC7EA
+:102C90007809FFFF86FA3227E19FA676A293D62B0A
+:102CA000114C5124F14F7FF42B6A73FC723C077472
+:102CB000FCD7B7D78EE03BFB2C0D9DBDA0A3B52163
+:102CC0009FE9E896F33A619778B9101E0AE23ACD87
+:102CD00000FE4B1C0EAF4AF82C50E4773F4B9C355E
+:102CE000B392C63DD7529416564DE3FE06782B7329
+:102CF0001577C9C0B86DFAB89DED74BC7BB2B1AEA2
+:102D00002E34EE5A7C9FF014F8AD12DC9485E7E186
+:102D1000AD809F166EF71D3E5A7316A9979B6B9454
+:102D2000E006AA7F43C7F343366A8775E914C935BD
+:102D300034BE2B86AF588F76BFD39C3CEE4DC27B02
+:102D4000C99A2CD043B0BCCFBC4D09D6123C5B789D
+:102D500099EF4B4451E75DB00F7C5ABC8FC6F1B779
+:102D6000B87FE465597819E7BD43DFD9B3ACBDF747
+:102D70000E40C32E8EFF7B93E440FF932748BD3364
+:102D800057C7DB95A288D7E955A28A4B5AF0272A64
+:102D9000A8DD34FA0BEB93E07E18DF74C0BED67565
+:102DA0003D4334703953B89F6FA46FBD55D3FEC6F1
+:102DB0009BA8CD644B7367BB8A754AEB368BF1DFFA
+:102DC0001DE3FF76EC9B8715E0FD169263A0F79A52
+:102DD0007617C5C79314894F5AB7D9BE3C5EB7035F
+:102DE0007C9688F533A69DE43FABBBC73F5B3F2491
+:102DF000181332D284F8851485E2FED3092295E6B1
+:102E0000D9D0550D3AB2A0A76FB1EEA27936903D58
+:102E1000E1C0BCFDC51D4E51FD38D2B77748F91A47
+:102E20001F2078A25F1577301F342E5F48CF5F1BBD
+:102E300044F5D4FEE51A113F80E0977D366F2DF101
+:102E4000E1D8B3DA81442A2792DC0F53EBCBD2EFDF
+:102E50001E03FB605C47D223117AE2B2EE6698163D
+:102E60004247D0E9721DDFE3B3CD7A6722F48ED1F9
+:102E7000BE0DBD43F255057E27FB74FD7389B80472
+:102E8000FA677FF55EF129E917430F8DA61986B21F
+:102E90002FAC8762EC05D7806E447F3BD6C76C2B86
+:102EA000B507BEDD5A874911EB656FBEC274F2905B
+:102EB000E2B1D0FCDF38A406811FAB3F3C14F85BC5
+:102EC000FCBCC27CFA079F3617DF3B696B9C07BED0
+:102ED0006918969B28A8FF4FAA6920BD68FD563B3C
+:102EE000859FD6C2916A37C347ABD3B9FCAADAC370
+:102EF000E5F1EADE5C7FB2DACBF0B3BEA20AF0C342
+:102F0000EC555F5BB56CF45FC5F6D1921AAB00BDB2
+:102F100096C42F96B0CDE98610BEADD3414B1CC1EF
+:102F2000B705152FF4E2C25DC1957134AED27ABFF8
+:102F3000DD05F9D72979B40BEDEF5598EBE71DAA1C
+:102F40003A88E99E7CE793AB2688D6F9969F55840C
+:102F5000464BAE5B9EFFB798CF17D583785C5F5624
+:102F6000FB795CFEFAA68329F4BD63D5E3187EC71E
+:102F700057548B767EF135DB1113B6355961678C6A
+:102F8000F52B7ED079845F048384AFB536A957D6FC
+:102F9000925E811C18D56FF2433708C87DED4ECC88
+:102FA000736AF29CB1B057270E2A66FBF5EA1F043C
+:102FB000DBAF06FFFFD43AF288869399D4DF89808D
+:102FC000C44FCBAEB7196EB1127E68C62FEC2A2D56
+:102FD00015641FB49C7D4B3EA7766CA7EE96ED164C
+:102FE000DB64BBC5BB7F97CCCF15A55944E8BB6359
+:102FF000444741788873663EF419E1E7D8F65FA745
+:103000006B11FC752C39F4ED879093FF66F16E60BF
+:103010003ED53E7D167274B99BE5CC495BE8C8038A
+:1030200090B39D48AF727D55DC64E2B30ABBD09883
+:10303000EF84D617F0B15831ABC825FBF3F492CF2B
+:10304000C18F3D77DCDFF5379ED6FEB684E67EF88D
+:1030500000E8B0E3A3844B68BC7D541152317F215A
+:10306000C711D818CBFD943D797BB29FE0AD8A683B
+:1030700051594E04595EFCCE26A6A1DFDE8AD5BE8C
+:103080003499FCAA3B9FCEC4BC7BA9A24AA5753942
+:10309000E7AE67329FA1F71E2359A4D2F89FB379F8
+:1030A0004FEEC5771FA2F153BF8FDD599E037958AC
+:1030B000F2878597000F7F81D0223A3CF1F44EB61B
+:1030C000178827BDA349AEF55BF3E2B20C6A7FE92E
+:1030D000BA264B072A7D1B955A94A5DB76BE55432D
+:1030E000FDE5BA2D55B05FDFF279785C39A1F51BAB
+:1030F00014E8811F1EED807599BDE6EB820EE2C2D9
+:1031000076C6139DDF6F29F6B05CE0F777D74F796D
+:10311000FB5A013B862C188CB7D8EE65BD46D3B65A
+:10312000013FBBBAADC7FB7B2C01D65781D9D2CEAC
+:10313000395114F823E65F4EED030497FB1A9A6E9B
+:10314000A2FAF2A4AE2240F33F1A5C321DF5031539
+:10315000E1067E2A76DD5BD881E013C38457A1FEA9
+:1031600017EC3E5DC8FAB013D9EAF8DEAEDAB46BFC
+:10317000A00FB30BF254AA2F5243DC9FA894FD5525
+:10318000D6EF740226D427ABC46749F5A3F6677A55
+:103190005AE96369BC2BCB4ADF6B47FA14E35D9BAA
+:1031A00015C8A872B5EADF645FD169AC1BE1BEA7A0
+:1031B00018DFF99CC605FBEC62F5A5DD52B590C79A
+:1031C000932EDC81C1ADDFED64092FC43C6875B876
+:1031D00003F49D4DEE86E9DC8EE0DF73BF9A9A938F
+:1031E00007FB8AB09E2AF57B2DFA754FE90C7A5DB4
+:1031F0006CFFF7C7FD83EDB44A4B82D731A0D5CE23
+:10320000999652FB7C23D12BD85E4BCC6907FB5897
+:10321000DAC9C2EAF540EE57B7F7BB73D84E233D83
+:103220006C61FD9B9A1361379FB3DB9C17A77F43AB
+:10323000EDFD1DF0BD8B6DEFD1E312E7E4F0991CBD
+:10324000931CAE8DB70B1F3DAF5DE3E03886386051
+:10325000293B48FECA707CC2D2FABD25F139EDA1E6
+:103260001F6A8568135F2FD0FAD708B761D21B1A7F
+:10327000C98111679B558DE544C3FEC40190B7C257
+:103280001FEF41DCC022B408FD18FD1DA2D760CCA1
+:103290006F9488135A849EF58B243BD6AD70255FBE
+:1032A000E4BCC38F9AF5CFBE4723E73DACE5FD38BC
+:1032B0009860848FF6282F34AFE7F579FD19F3A2D3
+:1032C00072677ED1E5A0DFF06FDC56CC6FB8755227
+:1032D000675F571EF7243C1FF18DC53CEE1F624D02
+:1032E000F0C58EFF46851C3BF0F1D7F620D65F3D3A
+:1032F0006C059A47FDC2EC20D6FB1EBB0838E1F7EF
+:103300004CB6B31D5C1F1F88875CAD57DC21C49F82
+:103310009EB3354C977E91706FF2817F5F7F10FC7A
+:103320007F4D8B5D413CAB83431C817D25D444B1F3
+:103330002935E2FBEDDC1CE750A13772091EAC3FDA
+:103340009F6EE7E7B536C17A32303D96C7B526A9FC
+:10335000EAD57E54BFA626D34B2317EF8BE0AAAE47
+:10336000A8BF4565793ED4B261D37DF07B26A5B375
+:103370009E599314CEAC44FB85977803C40F7BFE13
+:10338000A1B2FE58E3F36724BB200749CE139DD7B3
+:103390004CF267C4A6A24CB360BE1D48CEF3F32C1A
+:1033A0006A47E58736D9EE039D6E84E90CC8DB07D2
+:1033B0004A7A08963F390577F03AA10A27F1F35483
+:1033C0004902317DEEBDE226B4D3D4A09A05BCDC1F
+:1033D00075674F82AF99ADBA11A79BBA20A649E98C
+:1033E0004FA5A6861D09F4C29563FD91FEFADA1C6D
+:1033F000FF1DA07379A84FB7CF22F878FADC1EBF63
+:10340000827CF884FC68F8DD77A4697FE0FEF7FA37
+:10341000B8DD5E326E7E849E707AFAB3BD5D62F86E
+:1034200099E139C0EF0BCD4EB6632FC40F42789DA2
+:1034300097D0F7EFB38810F8B98BAED76B110000B7
+:103440009D4331CC07E3263BFD1CAF725936C08E3D
+:103450007E84E805FD16D8ED607A91A064FADDF768
+:103460004227D64BB37439563B2D96DFABDD690B43
+:103470005A406725B87533DE7B3E86F567995DB0A7
+:10348000BF52F66C5FE6833D767FD60AF4FB82433B
+:10349000EAED044F22D7FF9F1481FAE7747D5D1691
+:1034A0001BEE994474EADA4E7B0A7823BEABE2E75E
+:1034B00076F9FC70B0603DD6A520FB266E04C1C233
+:1034C000BF1EF22A4076D026AFA41FC6A5D576DA55
+:1034D00080F16A340ED059DCACF27C0ED35AC6FCB3
+:1034E0000E5775E2712993C765CCA5FA4F17C771BE
+:1034F000DCF570D1C133B0030EA7ABBCEE4942DDA1
+:103500003990EA49E736DC4170E5C24F5E1F484F0B
+:103510002B6A3FE8BCD7D38AF719CBCAC70BE28323
+:10352000198B6E9928122EBC5E679439E053B6AEA3
+:103530006F618773276192EB4D39FE06F0C17FE41E
+:10354000686FA3ACCC267B9BF8E8A4BDE161C455B1
+:103550008E7AB4BF022FA79EF962339E0B6B734F16
+:10356000E60F676321E23265161957BA2B57FB380D
+:1035700087F56C02D3AF32E460FAC5653748B97895
+:10358000CBC5E983AFEA37ED51A89FD2D8FA0A2E0E
+:10359000D5607FE8AB634A3841E9C6F8D5B0AE8E56
+:1035A000BBC309A08F6691F65EE996E879D250D345
+:1035B00010771342FAA921FB501AD72212BD0FB877
+:1035C000F1DCDEDA3EAB958EF41DA6A3707D3CF3F4
+:1035D0003768BFB54FCE1D84F7D2A4BD770DCD3A65
+:1035E0001F7FD1B0319FF3C7A3AF93A27002D6C99A
+:1035F0003145AE93E342CAAFC096183D5E20C77115
+:10360000F299F63C8E347D1D9D54F4765B1DB21DFF
+:10361000F11EEC99D23F49BEBBCFE665BD19207DB6
+:103620000279599A22E15247BA1BF656073560894A
+:10363000055F560B5E2F34365E97C77664F2FB86C5
+:103640005C13454240AE95EEC8D820ED3ADD6FC61A
+:1036500004A8FDA227647F8021FFBF7A3C53EF5F5F
+:10366000AEA768BA46E3A15BAE8C73D5C6E7B7FFD9
+:1036700067F1CDDEE91FAD8308BACF26D775205E8E
+:10368000EA11B25BD227F5C3FE84DDF4DD93F1F6D7
+:10369000597E17F629CCCF8DEF5D9AAB70BF5DA236
+:1036A000E8DE416D7E11F6927854B09C881E477E0C
+:1036B000AEF4571F7FFC1C9D554977622483BF3CA5
+:1036C0008C3F61037D3EB01B74BC2193E47A29706A
+:1036D000D5B5158F7B7C5A26F4C849C084EF3D4987
+:1036E0000467C3DE92FAC3800D7A44F3E9B20FE6B1
+:1036F0006536D2FB7372A57F501B93D05F24A2EC7A
+:103700001C841CA821BCA29EF4E0ACA26CF8C3E30C
+:10371000EEF9CCD63A9F23D57E3FA9A073F0BCB575
+:103720003E27D6E7FC753EE7EC087AD46EC93DE447
+:1037300021BC1FDF62456452D45A83770D49C5739B
+:103740003514105CEF04BE8FBBF6BD8E76F3D62524
+:10375000E5A811F269FEDAB1FE92083AF4DD62A63C
+:103760004BBF9019BE74AF192E27DD8EF9FDDCF723
+:103770007C61339C7BC80C3F3DA859FD11FAC9659B
+:10378000093A15942DEA8F90EF4135083FA3CB2DD0
+:10379000455326107C74DD1C2FC83CFFDD65F9A065
+:1037A000DF89DDB7ED29A7F78E265BBCF0AF8E89E8
+:1037B000D05F27103DE6D5DF6DB77A305F339FEFDE
+:1037C000B1E87CFBB88C032E0C9AEBCF970F357ABF
+:1037D000DC49F48EE4AB68FA53BF57F96960654B76
+:1037E000A7DC03FB67C17862781ADFE0D0DD76E101
+:1037F000BA987E028C576B8208A7D3F89A6E8BE733
+:10380000F8CB90A5A3C5A7F4BD72AB3BFF3734CF6F
+:10381000D94EC51D70B7C6D59B766654409F6E7253
+:103820005BBCE4E308F7A0AA839903E04F8890DB30
+:103830008BB8FEAD2BE1F72FA84A60FC2C14418E0B
+:10384000CBCF5EEE68958FF4BF92D551E3591351FB
+:103850004FF358B0CEDC7ED1C61F1D91B0E1970E5C
+:10386000A95FAF62BE73F571AB8189AC9787E8F150
+:103870008ACFD094F4CD13DD8A76E4D27C87AC195C
+:1038800025EBAD4E5DCFFAD9CF2B77D93D2CCFAC00
+:103890006FAEE4FD1D5A87D00F87E2E7FD0AF2EE16
+:1038A000B453B81D3EB4D7183E9222FD42DEB7A0F5
+:1038B000F6A7D729ACD7CB53245CFEA812440CB88A
+:1038C0001C415BC08FC9386D998E0FF0893F623EF5
+:1038D000A057242CEA8CF87898FDDF8A2AE1851D10
+:1038E00020888E7E036FBC1F15B61F859E0D28A1F4
+:1038F000077CB0F7CCDFA9DCFBA323123E175F26C1
+:10390000D2D5F0F7838C47D52EFC90E3EAADB16CAD
+:10391000B7930288857EB7E9F6B558156C077DB573
+:1039200006FA8ACA15BA1D1EB85BEAAB3549FE9E77
+:103930006ED4DF9DE1051EAE5174FF16767D12EC4C
+:10394000EB7DDC6FB3E2766F48427B11884965FB03
+:103950005AFA09FF5059DF3593FDBE01F6BA2F140C
+:10396000C678D6DC9BC5F6FA7386DEBB3346DAF33F
+:10397000E7DBDD6C5F897BA4FDF8A1E0BEC555DD0A
+:10398000B593B934BF396A116F46952CF367E0BB24
+:103990002593ED16D0432CB8B87D914D56D97F3381
+:1039A000CD17F1FACF94A28396483B58D70FF9056B
+:1039B000FECD7A3B2FDA9558DE643C9458841BFE8A
+:1039C000FCA6B3AAB012BCA9CE115C46AF9474F5A4
+:1039D000F75C9C8DF7647CEAB04FCAFBB801C21F4C
+:1039E000A4D239407ED739C0622AC5181967F92C8C
+:1039F00046F2E10C5154C8FB031E29EFA3E7913AAC
+:103A000040EABD127B83793C1FEF67BA90CE732FDB
+:103A1000037F8F9176C767D72BACCF693E3DDD041E
+:103A2000E7FF2186E38B9FE9FAC8C02FF14F1EE222
+:103A30006886DC4AD2F965CDEDC1AD3184EFBB6D4E
+:103A4000C437A01BF1CDA6014C77B60BD74C4F6302
+:103A5000BA5FA3D355DC19CF741B6AB1483CDF9918
+:103A6000C178A6F6E2EF786FAC47DAF317E9871171
+:103A7000DDB307E49DEF8F19F416D660DE3FDBBFA0
+:103A8000297F7AFB9E00F1FFA23FDD9B20A8DD97F6
+:103A9000D6BA342FBD5FB66945829FCAA3D640828D
+:103AA0009BFAFF32A88E0BB681EF453ABEB17FA0DC
+:103AB000A461DF55CAF1AF1EFFF79537D338BF5564
+:103AC0004433E463C5AEEF57DE4CF33BE87736434F
+:103AD0009E1EB5361642EE2E2C7655D578B17ECD8B
+:103AE00071FC458FDD9BE6617C07322DE9BCFE331E
+:103AF000F15EC5469B177E5DC53BAAD783752F9A9D
+:103B000057627CD1EF57863EB503FF6E8B68EE3867
+:103B1000B48D7AD1C872BE72D7EFBE5613507EF9FB
+:103B200021FC8BCAA8FD8305FAFE4AF43EC2350388
+:103B3000E2538F2040AEEF5F137E388F2140E3EADF
+:103B4000C1EC22E3CEB55BEFEFDF04BB61E3AB0971
+:103B50004A76EBFE81B1EFD2129AF3C8B39E0BAF57
+:103B6000CB937ADCB8956E528E79F6D2C0DA0B041C
+:103B700018B82CB3851360EF97ADB7B11C29DBFEE5
+:103B8000E8E607C06F1F38BC3D3C804FDB210FCA01
+:103B9000147FB3C2F25D2428F9ADF42ADDFE79E189
+:103BA00083B0AF3354319EE8B5E8A933B2BD5F347A
+:103BB000C750FBD29D4D85F00FCA345795B30D7A8F
+:103BC0008D0EBD686F74B541AF505321C7A9B67E45
+:103BD000C7F4F8F20545B4CF3AFFFD05EB3FB70B4C
+:103BE000E91F34A724497C41DF5586D4627BE2F982
+:103BF000EDE9FB139F1DC0F56EF82B3F45C721C0B3
+:103C000005F37BBC4882DEFED0111C0FFAEE589201
+:103C10002088FFBFB05649BE7F68451AECBC05B688
+:103C2000409A9B4BF97CC1C337323FCE57AAD2DCB6
+:103C3000D9CCEF1996413CDF0CCC73EEBAA93CCF3E
+:103C40007942637E5CF0905A14A4F28C558CDBD9D7
+:103C5000C6BAF94C5F370E717D7FAC9333F425E81B
+:103C6000F12F74BF3EF096F4A71D627262E47ED21B
+:103C70006E5D2E0644F030F44065838DE314EA9BBC
+:103C8000670AF19D1BB2AC55C8F7A0F907747C29EF
+:103C90003F4AFFC583BC874AFC45FA74F49B63DB4B
+:103CA0003766E3FB2DF6EBA8DF6FE0277A4DEF31A7
+:103CB000DEBED8E088552EA5324DDAEFD1F348C9E3
+:103CC00033D6BF784B44F053E5962F989F44BA2AD9
+:103CD00012D3258CFD0BF76C575522E1ED9B773EF7
+:103CE000B523FE1D48B5881E186FC3E70C0B6F3B4C
+:103CF0000FDA1BDFAFDCEB10E1C875BBF1F3A87581
+:103D00006DAE17A28AF15929123DD0DF5FD89B0B07
+:103D10009F433FD4EF26EA671ED95F61937DD55C50
+:103D2000F820E4C95EBB9BE30F647F8623F8E6DCE2
+:103D3000FEA8BE2F385F9707D17888960F87A3E437
+:103D400083F1BE58D7F67E54AB5C08307DCB6C2235
+:103D5000003BA3EC0307EB8FB2ED723D0A92A73D47
+:103D6000687D1CDBB6FFAFD7C09F0DD952C773AFBC
+:103D700066F9BBE0C9CF795E7308FF315EC8DFEF3B
+:103D8000ECF07FD3478B66078DFFD86A9F1D7C7F41
+:103D9000DE3AA6E76DAEE3D50ACBB7FFAADC257CF9
+:103DA000DB616FFDD47A9D7F01B91B9367CE1B3A0F
+:103DB00023B21387A2D25DDC85F70FA2F06BE0354A
+:103DC0005A8EAE1FE09171E928394AFFFE2A22F08F
+:103DD000284423F3F1B72417B10F57B1F17BD66B09
+:103DE00084D66607F17145F06B865740AF31FCE22F
+:103DF0009588579E3F6F333EA3EB5F05EF139F15EA
+:103E00003D6363BBA0AC5EE639D27BEC7754225EA7
+:103E1000CFADEB0E66A646C2C1283814D5DE1F050D
+:103E20001745B5D7A2E02A53FBB2BDFBD9CFA2718B
+:103E30009BDA39965ECE7EC8F9764590E751B9EBAC
+:103E40006B7B00FCD1B1D90EB9685B2602F1F47E20
+:103E5000F3F32ADBBDA73CCD09B05356C4483BEE73
+:103E6000945B87930C58CC2AA6719C0AF47723AFF5
+:103E7000A03946C65B4E1535272445F8ED4DF56A49
+:103E80008287DA3706C5B8B6F3626A99CE8DE24208
+:103E9000F5D29E1BABFEB043E68B5A8583FA6BAC22
+:103EA000F96E07E2499F91FF04FBA5A4E6EA04EC42
+:103EB000BF9CAAEF76C534F881AFA89CF325027E9B
+:103EC0003BF226E648528AA32270DF309A9F1A3FBF
+:103ED000E0E073F0AF8851B0FF59B23ACABE114565
+:103EE0008961F8D36BA2F31B8276D837F349CF42AE
+:103EF0001E2D5867AE5F547F8CD7CBA2A8F5A2E9E0
+:103F000071E3E8F55269AC179FF0E9F9969CD77711
+:103F1000EA90CAFCD5B2DC2656A6CABC5AE4A3B4C1
+:103F2000D4CB7C9D96BD1216013D0F485FB706DECF
+:103F30008E633DF5BAB0DD727CF7BFE5FF06FCB3DA
+:103F4000E7A3FE0F52797CCF073D9F03FCF47B9DD6
+:103F50003F12E7B71FFDC2F733795C2F3804C675EF
+:103F6000EA85973BC3DE38F5AC83F3114E2D73B071
+:103F7000BD1E78219EE316A73A497BB8F6F9EFFA01
+:103F800037B23E5ECE747C20CF2EEDAAFA7F67FD5D
+:103F9000D852EFF0601E952FC4F1BAAA7C3686F78E
+:103FA000D54E3DFF5D7E643CEEBF3A1F631FFE545D
+:103FB000BC98F624F857B7FF2B9F1BFC680DFCE557
+:103FC0005D2FDAE720AFE4CFFFD11FF2F5D4932FB6
+:103FD000B2FC3D696B7C18B1CD4D79E1076C831162
+:103FE000D7A38F75106244BEB83690DD165E241ECE
+:103FF0004E111E302FC2CB02D8E517C2473DF0D17B
+:10400000EE5F111F5FCF94726EA0C0BE4F2B5E1487
+:10401000BF7C1ECFF12A9ABF7CFEC277FD21877E2E
+:104020006ABE1FFE7F36DFB3FFB2F395FC1EC8F3F6
+:10403000F038A3F9FE7CBE7EFA570CEF88F7F278D1
+:104040002F72BDA7E7FFABAEF7FF197AE7FFCBCE24
+:10405000F7A7E8FD8A4EEF7837F6414F3DFF1F9DE9
+:10406000C5CF98F7D4FFA5F336ECF902D57BC84746
+:10407000ED5F15A177BC596C95B4698F2CD3F3050E
+:1040800085EE4F8DC65F1EB4CF591EC27A207B02CB
+:104090007E4CAD2BE7C09B04BF4C7682CAFBB2328C
+:1040A0009EF472BA2F28E3BB5502F1AC82F7E630DA
+:1040B000FC9AEF1707905752A8CA78CCFE1AEFC6A1
+:1040C000069AC7FE248BA796E0311DE77CB693EADB
+:1040D000DD1D5437FCB3DA8EB94E4FC4F8C6B8CCE8
+:1040E0007ED6E5517ED22F3DE6FA71E2C954ECD777
+:1040F0008DCBB6099CCF2944FB08BF52CB77F33C4C
+:104100007F29EA96BB5D3F1F4FA17CE977125E785D
+:10411000DF26D051D5F3E2CC7813C05B2AF092CBE6
+:10412000F67B40780FBC49B055B7AF84BEFF58E866
+:104130008CDF0C3FDA210AC24182CF78AC55686F20
+:1041400015E40FCB79B21F1D8D37A1FBD5569D0409
+:10415000633A8E0E03CF78DE25DDF43ECF3B1ACFD7
+:104160003F1FAFFB3A2E015ED3E3BD41F045C7A729
+:10417000521167AD253C2B4A2B3E0D3C45E37D0596
+:104180008D55F297C47747ABCF8A75365CB7E7C7D2
+:10419000589324DCB1412DE2F517947CFD8DD70AAC
+:1041A0007B7E942B89F349857ECE42D5F7C39161FE
+:1041B000C7E320FF1479B95758B5703EFCE6F16E9D
+:1041C0005100BFB5408410BF55EA5FFE1EFE11CE00
+:1041D0009714F1BEE6C1F701F772BAC2F007C53A0B
+:1041E000EBF1737632E2FE51E72B260EDA390AF450
+:1041F0009ABD949E218EE5F61CC47A2CBEC7E101BF
+:10420000FD3A5A1BB89E7C2D77CD60EC5687188EF0
+:104210002D214B3F03ED5E1EC5ED9708B7928474C8
+:10422000BB9002D8E596F96AE4BC7E0BD8BE3CDEB2
+:10423000532BE32602FCD41D65577C5FB64F1F430A
+:10424000DF43BE9BD0D85E8EEDCE9120D15529E2C2
+:10425000FDF72EDD645E44F30A07FB3BC5B775EA44
+:1042600009B934BEC01CB7CE1D28F7878D3238502F
+:10427000CA11D5E24DC777662FEFC3FE971A5B547C
+:10428000BE1B78DC11C77C5EBCF2BA0979F4FDE292
+:104290001D295E0CF3AB893BF365FBE937BE4BCFC1
+:1042A000B52D31FC7CFF40AD391F79068A67E66E7B
+:1042B0007A307BEA7E7B3A75A185269D40DC71626F
+:1042C00060E7EBD8E79C78A5CAED27EAF99F627909
+:1042D0001CEF9B4F087C6D4DA7EF4D20A706F54DB9
+:1042E00031EECED7D3F88BF578F30FBABC52638595
+:1042F000F6A40BE3EAD4B32B3D9F20643E74F4BADA
+:104300001D3450B6EF32DAEB49057E9418F786017A
+:10431000ADEDF11D7C77C44019E772E8A501135E8D
+:10432000392E5EB2CAD1D42D01A52DDC8BCA5F0D0A
+:104330002E881B48F5E3BB8AC2B5F8EE4DAAD8C05B
+:10434000E36D2EE6387B7C6F0FE8A0893ACE3712FA
+:104350006B7AF07E4ED328C1FCD3747796416FCE32
+:104360004F32FCB9A651DE83C8DF6A1EE5F46EF059
+:1043700022BF2514461CE5F05AB95FD3A536DC1DD3
+:1043800072B6D927F7413E5F9AEB019FCCBD774AC1
+:1043900002E4E79C356AD8017E5F6DCE5B126E2F1A
+:1043A000E78DCFA91B6587FF5AE2F2DB312FFF2093
+:1043B000AD17E6619C8BBC0463C2B99FBAE2D7E03B
+:1043C000F7A909B49EB1FEAC9E04F8D5D1794F95FA
+:1043D0007A7E9301DF91A679F1BDD9899E1DE08F88
+:1043E0004F9676E3B86AD540297F8535DC1DF8798C
+:1043F00098D602D6E7A7F992FFC627BB7BBA987F6B
+:104400006304E6D56473F7043F37AD88B1004FE32A
+:1044100097493EBEDD2AD757D0EFB10490C7A9F324
+:10442000EF8C1A6BD17AEAA7A35358E39385786A85
+:10443000B0E6C03826046A0EC3BF9EA3EBAB39AB0F
+:10444000E5F9B12EA3255D85B5614C0A3D3FBA293A
+:104450002B0779F106DF3C35B8E01703F35AE93F43
+:10446000BEC05FD88EBE33DEE269811C2EB95279A0
+:10447000B19BE483F1E867AC5ACFEBBC85E48423BD
+:1044800009E7061B248C7C55C88DBAFBFDCE08BFFE
+:10449000DD2E7671BDBD44E6A376B1876B38FFEAA9
+:1044A0007AE15E46F066B223AC3621B6543BB97C65
+:1044B000BC9AE45D0F21B655A733BCA3DAC365A847
+:1044C000BA373F7FB2DACBF0AEEA410CEFA9F63350
+:1044D000BCB77A1C97CF5617F1F368F933C7358FFD
+:1044E000E589BB27D17AF0F97C33D343E382FC71B1
+:1044F0000AF76D38AF24A4BC4BEA2DE58FD0E55107
+:10450000D73E82CFDF54811E840FDBAA51163EEFC7
+:10451000696DCC00DF8D558F6F7F1AF18E052ECE21
+:10452000CB6A118DBC4E5A84C51B1820E58F83F8C9
+:10453000AECBADE3B222F3D4AF5DA0086B047F5DD8
+:10454000571523AC11FA69D6D224133C63E9DB2F4B
+:10455000B5A7EFF7EAAAD5802E876F3DF2D07BF49E
+:10456000FC915BBFEA21CFF5FEB03E32EED2229A3B
+:10457000256C75F27EFC233767A4A57495DF03BD17
+:1045800066E30F0FE8D3FCE56358872B54EF3282C4
+:104590003F047D089F1FEBF4295ED16DE5AFB1AEFE
+:1045A000FD4EAF42DF397C73DFC241D4FE117D3F47
+:1045B0004AAC22BC46EA9974A9BF3E81FE4A92FAEF
+:1045C000AC0072342CF5D627BF4D0BDC86FAEB130A
+:1045D000BC3801A1AD6A1F984FF06A9FDDAB22AED7
+:1045E000572F56226E4338967645C066D6638D1D8A
+:1045F00093100F663D3612FB9E41279FD3A28EB0CB
+:104600001F33BBF73E9101B954A7B8B15F83739DC7
+:10461000CE64C83785F74791077425E9CBC707AA49
+:104620004CCF23F95679DE0BC97204C7082FC76730
+:104630004A56537BC8C73A9F7D5E84FC9DAD3F9F21
+:10464000D3DBC2A5F1FC197C0FFB87AB7CD3C01F69
+:104650001D509F8D32671AC6D7C155685522F67F07
+:104660009F1A68D5FB97FD1680A8F4FE1DBDBBDA26
+:10467000E766F3F92CD65B463FB37BE7ACEC0A7DEB
+:10468000BD7A14B0236A6DDEF4546A577FEE3B6E38
+:10469000195F77CAFCECB20BE80D234E77147FCA82
+:1046A00073923CDF453B9ED88173128B3E72B0FE05
+:1046B0005A74A9D44B223B983F85039AE6B8F898E0
+:1046C000274E1CBC8DC67302E79810EFDFF5A91DBD
+:1046D000F9A1B46CAA123300AB4DC8338D8ECF1E36
+:1046E000D8F151429B71F15DEAC5C5C5951F12A075
+:1046F000178CF98C7DFE4C1AECAC4AE52CEF335547
+:104700003EBF22ADADFCB0E8B8F8B9F8B958FDB578
+:104710008A38F32D47DB8C9F47C7019B0746EF473D
+:10472000B80A2027CE1C5283D84F6F09F648146D63
+:10473000F46FC4CF2BD7D24B2958979E44EC879D5A
+:10474000BA805D9E3748DAE527F478FBA96D2AFB2D
+:104750004BA7B6C507619F566CBBE720F6292B36E1
+:104760002A6C9E978B06C617E1513823F518F2DDA7
+:1047700052605C7B1221AF8CF1953E115F05BE5AF1
+:104780001852FC9B681C2D4E4F62BB8871240D9201
+:10479000EBA2D411CA67BCEAE3760C9272D068B778
+:1047A000B0FE1E8E4B53BB936CEFFC294E709EA047
+:1047B000687E1DE33BB62ED78B7DC585A19D159CDC
+:1047C000DFB12DCE8D38C4577A9EB3F19D4E7A7FDE
+:1047D0009D0649FBED98BE7F776C873C9F8E71628A
+:1047E0003D7DA598F305BB0D92FCDF6D90B4875E0F
+:1047F000D1D7B1D17E61A829A13BB5FF62EFDB5CC7
+:10480000F6D3FB59E86AE80FBDFBC5AE38DE8FFF73
+:1048100062D7838588339F088D4A05FF1BDF1F3AC7
+:10482000C826E9B04E1D077C89A0CCB329075E736A
+:1048300023C799B23E9015B9CE64BED1B15D4F2564
+:1048400058B25BE958EEAC72E27C68E5AEEB8BC027
+:10485000C7AFD8243EEDBB260570ECB992D42DF439
+:1048600004AFB30C6EBFCA12D1CE61F3B3F0B3ED97
+:104870002DF6A3BD11875EBCDBC6E70B675EEAB908
+:10488000FA5AACC3576D4C87C57D3C57733E528373
+:10489000CAF9CB8BB34418F6C7929BE2D7633FCCDF
+:1048A00018EFCC5CB9DECB5629C24FF32A0BAA42D3
+:1048B000A3B203D13D801CA5F4C63CE44F36650588
+:1048C0006FEF99CAE77DC31B525BF34C691DF7C4B8
+:1048D000B9C89241C93CEFFBA617B2BE3B6C1701A9
+:1048E000C885C093320FA7ACABCC8F7E007C8FFE07
+:1048F00092C33D5308AFC775BA964D0EF7445E4656
+:10490000D993199C9771DC2EF74BF11CFBC56539C7
+:10491000F43EB54BD5F379F17E52041F95CDF67A6E
+:10492000D04E4DF67A7C2E8CD77D92EDD6DDF102FD
+:1049300076ABE5E9783DBF2A86F3C88DF796EA7C29
+:1049400097AAD3535C23F331EFB3C97CD5FB36650B
+:10495000F0FD1846FBFB6CDA74D84F9807ECF58530
+:10496000F6BA9ED87731C6BB30A18EC7795CE7F323
+:1049700085B175322F5C3F778CF6809BF43CF6E670
+:10498000AD0ECE5FF92AA3E15B8CF7ABAD7D900352
+:10499000037CCFDBCBF5643F123D173DEE08A3FE51
+:1049A000CBAD326EFDA52DF82DE4F0970FA5F0F9F3
+:1049B000A82FDB05F3393F40715B609F7DA9E8B00C
+:1049C000CDCD7665173BC1D43E35565890BF336E7A
+:1049D000F2DA99C86F68D9E8007B8AAF36DF9FC6E4
+:1049E0007E8DF024729ECD2155806E5F3DFEEF7D61
+:1049F00022ED17A35CB4D19C77D79425ED4AA37E12
+:104A0000ADBE2ED70E927EC7BA41524F95C785EEE6
+:104A1000EBCAF393F826FAB07F470A3E9EF327B617
+:104A2000F75020371E10C15F7D3480BD6C0FF2E659
+:104A3000CB9EDCFA3AF66BBFB28806D81FCAAD5BD4
+:104A40007E85FB3952EF4A643D24C4469EDF976E53
+:104A500079AE95162CCF7F617B092F9AB2A527E0FE
+:104A600083A473145A5F8B2C0AF7BF684F3FCEB7ED
+:104A7000237A58789F6CA7AA8F876C4AE06FB3CCD3
+:104A8000571E9F1CDC0C7BAFF9A16E02E7DDC7AAA5
+:104A9000EBFA837EA737C659C04FE5B70D4D1C0A08
+:104AA000BCBDA10AD81FA7ADDEF6917184687C4514
+:104AB000E7819FD0E55319AD3B9CFF2CDDF310DF60
+:104AC0002F520ABE045E1E57781FBB74E5D0FB99B7
+:104AD0004F5FB7891ED4EFF1D03D0991F4792FFAD9
+:104AE0003B762FB72FA5F6F2FD5713789C9B6D9C54
+:104AF000D7124DD78B7EFF71F5A2DE3F37FF10D95D
+:104B000005FDCFC7C369D1F0AB8FE8FBDF6C8B61CC
+:104B10007F903C003EC776CC169A87791FDB1EC378
+:104B2000F2EB589294135F903C0DF4C2382EFF3D87
+:104B3000F3E95B53F8BCDFFCA0F9BB46BF1FEB7287
+:104B4000BC3CC59B08BFB3FC0D290F895E57F0FB29
+:104B50006FD8F8FDE8793C87F7DA45ACD3ED71CC36
+:104B600017C73A487A1CDBD18BF55353925B30DF81
+:104B70006CB5C97A5BA833ECE063DB7BF96A23BED2
+:104B80007B2C29D4D91DF1BCC9165C3950CAD36617
+:104B9000F8C5228C583CF28B04C73F8CF74A9DAB7A
+:104BA0001B60A720BF373F87CBB023F9FC3CDDF16A
+:104BB000C9D29F1C3058DA0F9CB39AA6E793B3DD95
+:104BC00013B2438E6BBA7D58B62D3ACF57D6A7187D
+:104BD000EFD3BA4B35F28A2D186FC89ECEF106E19D
+:104BE0007992C65BBAFCFA85C81F2FADBAFB5AD8BA
+:104BF0004FA55631CE4EE36A52541E47538C98351A
+:104C0000197664643F11F65BE7C1E7E2B4C29DC662
+:104C1000762BEBB7AE83A5BE035C47DF2B5BAEAC58
+:104C2000C6F70DF9C281C2B4563C21AF15F93D4D0E
+:104C3000A3F4FA0BCCBBC926EBA3E76D8C277FB09E
+:104C400094534D599EDF0F035DFEA2F2F9AED33FA0
+:104C5000E42626B761A7B5EA7B7B6B9E2D8D1F6787
+:104C60006E595F0F96F2AE94C68771F65C67CE2BD5
+:104C7000EFBDD10C5FB2CD0C67EF32C3FDEBCDB011
+:104C8000F78019EE8B7EF3A49F8D73CBF0B351C2E6
+:104C9000CFF638A49F0D187E364AF8D9780E3F1B00
+:104CA00030FC6CC0F0B3011BF886BF0D18FE36EA6D
+:104CB0006FD0F124FCE134E46B5658649E2FD1C3CD
+:104CC000CFE798A6DB4DE7524E3D2FCFA5103F48CA
+:104CD00079BFD0C5EBE401B4180CBD24D753EAB3B7
+:104CE0008EE032C4773DDACCC158AF6BBF9E07BEB1
+:104CF000ABE8DAC879AF4D2B5EEE790FB56B54E2B5
+:104D000005EC8A8AB55FCF841D95E6D14A06D37833
+:104D10002A631B560EE4B87D98E547638DE78D91B5
+:104D2000928E1C7F2956715306D52F486E337F28EB
+:104D30003AEF5CAC36E799FF54DE79341F1876E021
+:104D400023B6E60C37FBE9C31E469C77B112EF860B
+:104D50009FFE698C5886FB8302AFC83CB5964336EC
+:104D60009937B05AD92022EC93653ABE0D78CED946
+:104D70005CB6C7CFC1AB158BB85488EE5A7313FC21
+:104D8000EBD30B2C6C779F5E5050D80EF61FF96555
+:104D90005813B89F2B72BCB89FCBC43F5B92A3CE75
+:104DA0004D7430B5C7FD5CE673139798EAA7ACCE97
+:104DB00035D597140D35D57717727C4B16CAF195FA
+:104DC000907EF0A7005EC6798B4B403BB2533A2BE6
+:104DD00081952C97D72B7C6EDCB3745521F0729C97
+:104DE000D8197104836FE6E8FA45580376F0DD9927
+:104DF0005459FFA5D270E4367AEF84AF6E33AE4ECD
+:104E000039615977DF300FF2EBD77776D33ABC416F
+:104E100009A541F4FC7E80B61D7CF399B57112EFB3
+:104E200027EE6C975C03BBF350DEEB83D0DF369547
+:104E3000F3260C7EE96C9371BAF5838866644FACF7
+:104E4000AF93F9BCEBEB5262BB47ECBF18F36C01BC
+:104E50001D04CA6569A91C17120D9807D9EDCB600E
+:104E6000B79D3E24ED76633EDD97873B2EA1FA1B6E
+:104E700076C6307E3ED3FD86E37D5EECEFC1F98DD4
+:104E8000EABD9D55D803966D9BE147B852B597B0E2
+:104E90004E16ACEFF11EEEF75AF4AE2A709EE6F312
+:104EA00035A31306D377BEDA6EF38E27F8B6BA476A
+:104EB000EDF09317598376CEC3DCBADE8EBCE45F87
+:104EC0006C59CFCFE76D29E6BCCBF9A28AFDC8A308
+:104ED000FAB92C63DE0B0A94756EE2AF5E43241FB1
+:104EE0002E8895FB79C4CF2F615EA7B7283ED88F57
+:104EF0005716EDB417D3F3C33ABF7AA64D1B0BFE7A
+:104F00006B09C9FB395A5E53E5BD6357AA322FE6D8
+:104F100002F7F94C399BC5FC7DE5D9BEEC674D0D18
+:104F2000F7917E6CB6941F2DF52AEFC7B5BCB63F3E
+:104F3000750ABE576FE3DDBB05F60679FEDF22AAD0
+:104F4000708EC033AD41F25596A882FDB7E42F6F45
+:104F50001FC4BA5B92E5F4603D140D534DFC593902
+:104F600026CEC4BFD344B2E91CCD55482A8980AFB0
+:104F70001CDFCDD4FEEA2BFB46C9839CD67A96076C
+:104F800043A2CE011698E0722A6F817C129799DEB7
+:104F90002B17935BDBC11FDE28EDD6F25D491BB0FA
+:104FA0002FBEC022FDA1699A7C5EB1573E1722F642
+:104FB000DCB9749CC7477CC0746E5BDFE743BF1CE1
+:104FC0000FECD6C0719DE60C929784D1F2DE8D76FF
+:104FD000C4D3C85C6E469CB43C4030FAF58BE65AAC
+:104FE0009C1FB14AFCBABCEEAECB325AF9A2629712
+:104FF00039DFAAE2D0DBDCCEC8678CAE273B7D650B
+:10500000078C7BBCE2E37393DB9AEC88075DA975A0
+:10501000E47B29A2EF4B2B0B35F138A7EE4D7363E0
+:10502000DFB622EA9EB485433C523FE9F17FDC3390
+:1050300024ED8406BB8CDBBAF65978FDC97B79CEAA
+:10504000F1E5028BBC2F200A2FE37DEF727F1D322A
+:10505000641E1AF0628DC04B341F014FD6083CCD40
+:1050600013124FF3489A0409EE003E8BC4CFCFC40D
+:10507000D77CFC41F5F3F72A41E4BF45E3679ED6B0
+:10508000C8F89BA7B9AA82EEF3E75371CBFB0721BF
+:105090009F7664C87B0DA3F1375F34AC84DF3B9F00
+:1050A000F4463889F9C2EE643F4DF1426F7B063514
+:1050B000DA6D529E719CB7E5B5B779DDB578695563
+:1050C000832F04D5537B97DFD3BCAC8D3CDFC967FE
+:1050D00065FCE4AAB3562EAF1C6F5E7753CFA6F1E2
+:1050E000F39F8B970AE0197C8EB85E421BF7EC2188
+:1050F000CE9770FE7C8DFD10430EB7DA75E6BCE5E9
+:105100000BD97FD171C21B87E871C23C9167CA5B22
+:10511000BE80DD119DB76CE8F11697D49363D5EC92
+:10512000373C34EFE25754F6D33DD3C659F8FCF878
+:105130002BF27E3C6DC59926F0A7166F6139B83801
+:10514000BE2BDF6BA1E971BB73F6764D4A1AE27F85
+:10515000C5316ECEC72FAE518BA0BF8AA99D27A2A5
+:10516000DDCAE5DD3A432F7C727BAF8703B45E3E38
+:10517000B929350D71FF4F57D85249729E6BF7C947
+:105180008AB19D919FF1E9DD8E69C136F0F3D010AF
+:10519000195729BFF57DD65B272CAF254CA3F7CB3C
+:1051A00056EC4E40DA7FE98AB7F3DD6452F80668C0
+:1051B000EB86E421BEB77EB31BF872AFE7FB04B603
+:1051C00093B8043E8A57AC60BA2F52E47EF50D4A7C
+:1051D000F8C8486A773CE6EE8469443F8DFE87FD57
+:1051E000C3331BE3F5F368359C37743C96EC016AD6
+:1051F0007F3446E2F3E8CE782FDF89E10D7466FF55
+:10520000AD9DDCDF29B5D45F85F14C4CD5B60FE1FF
+:105210007DDEE0E67495DBF1B975ADA647625BF122
+:105220000FA3DCACEB69D8DB28616F235F06F63691
+:1052300060D8DB28616FE379E55AB3FDF6B2BE5F53
+:1052400068C483BBD436FB60EF060A44EF2AD6B3AA
+:10525000E30BFE08BDF58AB4179628DE558D6C2F3A
+:10526000C5D7C1EFACB54A3B3BF0B13C1745FF7A1F
+:10527000433EFD5ABDC48BFDFCFBE36E7D04ED9700
+:10528000627F6800EE3D25DB2B825F479E758AC8F2
+:1052900073B7A3C8088B84473B334CEDC7BAB34CF4
+:1052A000F5BF48EF63AAFFA5C767822FEF3DD8D4AB
+:1052B0007E82779409BE62D02F4DED27F92799E0C1
+:1052C00029E3A69BDA4F2D2A36D55F3D6DA1A97E35
+:1052D000BA76BD09BE76C14DA6F6D755D598EA85F2
+:1052E000A87A0CF8F107E43D6CF5F09F1CB8FFC5F7
+:1052F000C925D5FF0979CCA348D4F3BD2B7FB9F1DB
+:1053000011C0FB90D74C2B6ED8684B555B71FC1FBE
+:10531000747BE9EA61FE6F87B03FDDC0F7682276F3
+:105320000BBE8B1BEAD1FD5FF9BCA3D5885B35644E
+:10533000F07D0951ED2FD46E58DCBED31E62B92525
+:10534000431FB8CE4AF26BD8C07DB9DD08DEFDDC64
+:10535000C7121EBAEFA9AE043F3FB4C74C862FDD7B
+:10536000771AF5970F6B92F553049B262F3FB7E200
+:105370003AE4A70C1BD975B557C645DA3CDF6E94E5
+:10538000C013CE85034F28C3C4F728F711DFA33C11
+:10539000407C5F4272ED20F13DCA43E467E2F9FFD1
+:1053A000213F13E56BE467A27C9DFC4B940DE45F09
+:1053B000A27CAB7A1A97EF546BFCDE5FAB1770F9E7
+:1053C0007E75153FFFB07A29971F5707F879CFA14F
+:1053D000328EE022BD03FD5E813C18E40B44DD4BC0
+:1053E0002AAADC7CFF41ADAEB744BD9E57B38FFC0B
+:1053F00057E0B3D19A74C4D9BABF78617FDF2A8EDF
+:1054000044D86D5758FD3943998E1DDD2CF7F5E7CB
+:105410004F7AB5814389EEEF664DE991AB42DF5596
+:10542000BD944875EF5ADABE7F326EA8E497DEC3AA
+:10543000FCC3F0DE70E761DE4FF76490B53A94612B
+:1054400005F4577264FC72B8B5A116F5B5DF0B0F01
+:10545000FCE617E3FFCAFBE0B5642EE3FCB172562D
+:10546000FA2B23F4FDFBDAEFE5FEFD088C9DEA87BD
+:10547000BB657DED5CD2743ED487F8FB2370DA59AE
+:105480009E6F33E5ED8C39DB309AEB5D760FF24D94
+:105490004738C3F27B4EE1467CF9C5F83DB2FFB117
+:1054A000B2FF8DDF87F9FBF03E91973DDCD93A9E44
+:1054B000653CBE06793F5DB66C5FABB71FA151FF7F
+:1054C00049185F951C5F31B597E367393702DF4CA8
+:1054D00082B72DEB63D3E5F9E43167F57AAF9C6FC2
+:1054E0007BAB8471A604F599299AF0537F9999C2F0
+:1054F0008BF8DB88D4860C6EAFE733C45BE5F7121C
+:10550000BDF23EAEEE7FD7E47E002100E337F2929B
+:105510008C75DB29399C013BAFD3623B7F2F53DD78
+:10552000E983BCEEE3D37E0D7EB03A2D3CBF5ABF7B
+:105530003C2FFFE6F39E4EB88F74926EAFFF13FAC6
+:10554000DF82F7873B5F90F4C7256F99ADB0328F4C
+:10555000FE37B84DFA4B7C11BF60FE447FA607E8CA
+:10556000A9D35F31F0A3D3FF1CBD9645D6EBFC71E8
+:105570003EFD4392DE3A3F8D70CABC09B407FD87F9
+:105580005B253FD4C6C87C8F17E30B1FC03D5984F1
+:105590009B22C4E7871BFC5225CF0FFF6FA5FF009E
+:1055A000ABBC47CE51E6E47BEA7E8A1F66358B4270
+:1055B000DCD379CAA7C5615D179FF51C043C478CF5
+:1055C0002A84796ED49FBD40BDF64DB30DB0F1BCB9
+:1055D0004B8E6C67D45B9D6FC541EE19DF31DA8D60
+:1055E00038AF5D8E13FA62C9D8D03AE8AF7135563C
+:1055F0008E5B9365C2F021D267329FD39FE04B8BC5
+:10560000CCFFF41E583C00F78BCAF35BC225ED6A51
+:105610000FFD07B95AF843D172F427D46D56F81D1F
+:1056200067904F4BDF294C35DBE7E3A2F6D72FCB52
+:10563000FE82EDF1CB7EE29EEBBF0DD5CFDF64891C
+:10564000ACFFE43DA35F48F97C71F78CF616F5CC0E
+:1056500007638A653E17CDDF9283B88D5F54012EB4
+:10566000145556F0C1385167957EA5FF78C500F6F0
+:10567000DA193F978B303F9F400A05CAE40A621F40
+:10568000C0FBE326CEC0FDC1A3734777C7F388FBF9
+:10569000F37EC0F82A54ED6FEE88FBF3F68D91EBA4
+:1056A0006DF154196FDAE7ECD6A61DFA0AE9DBEEC4
+:1056B0003D8017C1E54BA48FBBD3BC5F267D0CF8A2
+:1056C000B2DE35BCAF5CE831E71D19EF5FEE1E2D91
+:1056D000AC2917D67797F77FA623F0FC6A52AF3133
+:1056E000A0D7AB4903C7201EFF6A527B8B2C1D76C7
+:1056F0002EFB3DDDBDADF119EBA3B5BF42EECFB83A
+:105700002F784C3B795F70345E2F1321137EC7EBEB
+:10571000F8FD1978ED352CEF7CBCC6E1B0631EF0C6
+:10572000F9F61E236F0AF1E4EECB1B18BEC126D793
+:1057300041F9D3130A9017BDF85D99DFF125860270
+:10574000BDBB74288F7FC4D2C1C29ACBFB5101E08C
+:10575000BBCC29F17822F0627FDC6BFE528A3608DE
+:10576000FD7FB14EE5F3F6279E8CE178DCD1E05366
+:1057700009C0A7C1C765AA67B517EBF05555DEB3D9
+:10578000F4C3FECEB887F4427C4DFC3C6A585E1BE5
+:10579000FCEC227EEE773E3F8B8DF21E83326761FA
+:1057A0009B7436FC4E678E3F0E7CE816E1EBC1FF22
+:1057B0001542FA4715CED7E43D9504E3DC6BB45DA2
+:1057C000951F4BEDA9DEEE94F9C206BD331DF21E06
+:1057D000CBCC38E1461C4468B997705CBE9B7F1AFD
+:1057E000C64F7EEDB6C8BCB511E1BEBCEF3CEE9035
+:1057F000CAF9EE2FC7CA7BDF1B891E0AD9A7BFE8EB
+:105800005BE5EA4A749C99AFCD198679A93FA8E86F
+:10581000F7B51E8A48E1F879AE8BFDEC9FE9AF97AA
+:105820000ED3FDF5FEA2FF3FFD3D8576F2DEE1C51C
+:10583000AFE40631EEC535A4D552F97731F89EB8FC
+:105840005AF8E759AD726784E8C9BF97313AD5C6AF
+:1058500079E6FFDB7E4F215368BCFEFEB3BFAB3061
+:105860004E3E3AEF77153213561DD0525B7F5723C9
+:10587000FA771532F5FBAC8547EA0FE3F714460AD1
+:105880003FE7E58F4D37EB95D1EE5107DC5C9AE3AE
+:105890003D993F91CFF5F8305DAFFC14DDCB854EDF
+:1058A0007779AE137CA0FF3E4A10FC69FC3E8A412A
+:1058B00077E377526ADBC9DF49F957FB5D9468FAF1
+:1058C00044FF4E4A347DA27F37658416CB781A5D3B
+:1058D000E662BE36E8348DFE637B00E77295FF7E9C
+:1058E0007A3546ADD33362751EEE293D552CE5FA67
+:1058F00085F4FF835EFF11C88B6F114FC27917A724
+:105900008C87F86BAD226684C0FD849C2FFBEB5A1C
+:10591000790F54AD55C603024457DC8BF75DEC3F5D
+:10592000E47D8E641FD93A202E53C5EF07EC4E77E5
+:10593000AD17F44E603E59BA549E073E6CA9E3DFA2
+:10594000BB98955DA560FFF268967616FDA78BA2C1
+:105950009DF3382E5F3510F27DE69F1D9D513FB3BC
+:105960008BBC3F526437E645DA233333F53CCCE158
+:10597000FA7EBC57E661A9C3655C2DDEEBE6730DCC
+:10598000C5D942CF6F159D67F6031F7FCC767C8B00
+:1059900047DAD58D36798F65E01599CFB3AEEA2D0C
+:1059A000B6FB37915DAB4AFB66ED9D1C674810D88E
+:1059B000C77D24A63909E3EFB55698EC853E41A78B
+:1059C000292FB9EF16B709EE174A37B5BF74AFC71D
+:1059D00054EF0BF736D5E71EF29AE0BC8641A6F6E7
+:1059E00003DFF79BE0C18DE34CED871E2D32C3C36F
+:1059F000BB4A3C8127693E3397B883F21E7D192745
+:105A0000E96297F654ED4DD29F30F2D7357D1D44B3
+:105A1000E7AF77B2CAFC757B95D46B9A4BFAB7EEB9
+:105A200064E156F95C4C03C3B81B82F3C603E63C41
+:105A3000F38E4EE95F59C648FFC3AEE799C7F696A5
+:105A4000E75E8CBC72F22BFCC07777D1389D7FEF7C
+:105A500040BF4F349A9F7FA1D33D7ADC5DECF23C8E
+:105A60005DED4D76DE3FD75CF62625E1FCF1540D69
+:105A700094FCBFC9D9F6BD4F53753E7B2CB768C2A5
+:105A8000702A1F26B5C5F6D779FD791B21EF6A7FED
+:105A90006BE7BCF19FEA6FE6A5723E332C965993F3
+:105AA000B2D91FE4738046BF73F57E7F39526973A4
+:105AB0007E33139BF9DE359168F7807F35D74A86B0
+:105AC000DDB122496D03EFADE732649EFE75AB4355
+:105AD00077F6A271CEB0D7D9E48503411BF8617C7B
+:105AE00001D991B43E5EDE33FC2117D1E3E1A55626
+:105AF0008E83950D7F6666A03BECCC66E60724A2FC
+:105B0000603F11F6A79AD33AEEA611328FFC4E5C95
+:105B10002CCDE7257EE071B5E8F19116113A777E3C
+:105B200022D006BF69AE837C0EC1BD58F253A78850
+:105B30007356F03FFFA7CE4B08EC90523FB63A2188
+:105B4000CF39FE04FE8C732A9EEB6D451B5C382F0B
+:105B500022C6291178F866848C5BFC79B8A437DA00
+:105B6000411E5DA81DD97D89D85F68119E44F74FFD
+:105B7000C4D5FF27E69F69957186CE4E795EA493C2
+:105B800055637961EFADDF73771EBFEB72438F937F
+:105B900075B4CA75DFD12BD7F5F972E1007FDFAE9E
+:105BA000C97BD3A2F1CBFF22E22AC6F995D83152A4
+:105BB0008E1872E1DC39941ED20FB5E9F221D8DDDE
+:105BC000C27907B7C59BD771B32E1FEE31F445805C
+:105BD000FCF87C939C10D8D7AB5DA1B29C2039799E
+:105BE00050A37116E35E1677EBEFC3CDBD57EAB154
+:105BF00011FEA2FBB06F327B8D4DACE77D05793F86
+:105C0000EC7C3D4E5E1C88BA9F45B7C7CFAC56DCD6
+:105C1000F8DD8839ABCCF5F35D473E86FF3837FABF
+:105C20009E1A63BFEE27E2008DC3757BCD2BBC7A35
+:105C3000FEFD328CEF4C50DE7B7DEEBC921EFF6988
+:105C4000093E25E15B8488FC1D09C32E30600FF6F8
+:105C5000C922EE6121FCC6F6867E5F6E6D33BFD130
+:105C6000C0EFB93C0F7D9F8ECA652BD89F91F90D6F
+:105C7000240F785FEE38D5C30E3C1E38CDED8FEF84
+:105C80008AE1BC9213BE86FED8BF35F6E9BA6B72C4
+:105C90001FAB6557BCCC6F705924BC45DE63BFE8B1
+:105CA000EFC1FEF0631B034F99CE39688DE67DBED0
+:105CB000E852ABD9CDFEA66F80163382F8EA98D5AC
+:105CC000EBF4127CBB6B1FDFD3359EFC47C835E479
+:105CD000A5AC4895E367F915382DF15725F17705FF
+:105CE000197A909FEF0A929E88630AF26AA92C0E95
+:105CF0000FE6FE7FEE3ED894B33EB9FF7B7628BF19
+:105D0000AFAD1ACC70EF60F3A8F7A9DFAB349707FB
+:105D100071A4A9B5BF1E1B0BFAFFD1B582CB4EE60D
+:105D2000F30346D97B84A44BA3ADEDFA3F8E90EBF1
+:105D300063CF08A1DF5723F97D718DC2FB6A8BC148
+:105D4000E380EF94F7731AF0E93A1D1E2BE1252B3F
+:105D5000240CD5043B78B6FE3B699BF5F80BE68F27
+:105D600012F3475C609B1E9FC1FC5162FE780E7966
+:105D70000518F20A30E41560C82B94905778FE7924
+:105D8000D268DED7C6BEDD9888F5847DBB3111EBC5
+:105D900003FB769130F6ED22DB63DF2EB21EFB763D
+:105DA00091F5D8B78B84B16F17D91EFB7691B018D7
+:105DB000F4CB561872CD3FC9044F217F604CC47A92
+:105DC000C6BE5DE4F7B16F67FA9E76BDE9FD6BC5AF
+:105DD00052D3FBD8B78B6C3F6BA962DAD72309C8C3
+:105DE0007A7DCEDA14E6A3645FD1BC1179FCBB5690
+:105DF00037DABAB27CE038C6E2F258AFA477DD38C1
+:105E0000497F8B3C1FA134F3EF0B9CBEC52EE1B143
+:105E1000E6FC6DA3C4BED7189BDCF742897D2F94A6
+:105E2000D8F742897DAF313DE4BE174AEC7BE139BA
+:105E3000F6BD5062DF0B25F6BD5062DF0B25F6BDC7
+:105E40005062DF0BEF61DF0B25F6BDF01CFB5E2817
+:105E5000B1EF85E787691C2511720CF67A77939F5D
+:105E6000497C68F233DD2618F67A647BD8EB91F52D
+:105E7000B0D723EB61AF47C2B0D723DBC35E8F84BB
+:105E80001F1BEE613D06BB3DF23DD8ED9170BFBAE0
+:105E9000C04B88AD4D5877F200CAC678E5619C3793
+:105EA0007CEC852B6659491F36C6289D9348A6DB96
+:105EB00094A9B3C640DFEAF98FFD45B305F24783E5
+:105EC000333980CF19725E69BFEF33B8FE65E35C8A
+:105ED0001CFE11DD7DBB04FFEE8CB1DF6EBCEF2537
+:105EE000B58DD268DF0AB7DD2EBA7FA31DE7564510
+:105EF0008C03279A9137E3BBC595033F64B345E113
+:105F00003C93CDCB645E74345F7DACDB479B2D3B13
+:105F1000F7E11C4C73B1E2C5B98FEE751A9F33EBF4
+:105F2000374358545FEB7C7A3D92C079B50746C839
+:105F3000389F317E233E4AF282CF0F0E6B6E189D42
+:105F400048EDB5C028FE1D9CF176693790A5310457
+:105F5000FE64DF80E2DF10C1E7AFEBDFD302721C2B
+:105F60008F3D3251BE172BDF7BEC9104EE7FE27246
+:105F700085F3CC866D137E9C537E4F97AF7DB7859E
+:105F800055F457BC5CF6677CB7785D673BCE731BF6
+:105F9000F82A168D63709FB418A0E04E59D1D3AA89
+:105FA000B15DDA7E86DB023BE862CF410D1F9034A3
+:105FB000167988A25EF0BDA11306BC699A2FA32BA7
+:105FC0001FBF832AD837D402D75BD0EF4442400AA0
+:105FD000E2C904633E9A26AAB208BF574D2B667CDD
+:105FE000F79E2114E0BBCF8CF596547AAFAFF6A2A2
+:105FF00005F65ABFBA462E8D79788725A980C7DB6A
+:10600000DC6331FEF16315961FD1793CB00F185E49
+:106010006E637D6ED80F8BE3CFE5F9BC873C9FD3D1
+:10602000876C9CE7737AF919AE2FDE1DC3793DDAD0
+:106030005A85E59A613718793B65D7BF9B0FFC7C81
+:106040009515DC9CD48DF5BC7D24F269BAEE4CC06C
+:10605000119CE3CB775F85A37BA797EF96BF57ABE8
+:10606000EFEF18BF7B2AB2FD9C0F66D88142ADB717
+:1060700047EEE318BF9F46F293DB9DDE6B77F3EFAD
+:10608000D7E9BF776AC47D8AFF927B10782D7E485E
+:10609000FEFED9EC5577174E23789EDF19C6EF62C6
+:1060A00045E7632D8CB2037FEAF74E3D23F5F84FA9
+:1060B000ABFDC7FC72E63569FF15FF65FF5469AF9C
+:1060C000D838EF7F468D8CD7899D82EF3F9A513328
+:1060D000DA827BA467ECF67B154FAB1DF8866EB7B2
+:1060E0004C3E9BC9F87D5BB753A622FF94F03BBEA4
+:1060F0003146CF57CBE0F2EAB3321F75B24BAEF761
+:10610000C66704DBD32D0187CC23AC177A7EAB990D
+:10611000EF7C82F883E873895FD98FB4E509B07B9F
+:10612000E87BD36007A5808F8B57205F96DE66BB28
+:10613000339A8F275BC357E2FB93BD36E6AF7FC62A
+:10614000C7B897E39C5C12552FE19CBFD8287FC746
+:10615000619A26F9BBAFCEDF33E3F4F8934BC697D1
+:10616000CEC59F3048C4CCC4D659C8179E89E48593
+:106170000E3C2D3FF2F5E2B365FD3523B7CE5A0E46
+:1061800067E6027109F5663BDF5FADB99CFC3B3405
+:10619000178A13203E00F978DD0D3EFBEC08F95814
+:1061A00030AA608D3F2FE2BCE3ED320F6AF1ED3D86
+:1061B000DAB775DED628E7107EB13E662636DE8871
+:1061C000F3E64B470AFF9841F27726E5BC4418797D
+:1061D00098D7E8F0C63F37FC6D958BF1C1F00D7F85
+:1061E000DE330BF7C7953B1B0BC16E95D955E3907A
+:1061F00077DD2A87347F6616E4D0A830E4D085E2C4
+:106200000E1B474A3A44C71FE6644BF92CF4FBC205
+:106210003FB9FDE91D90E7C6F83FB9C0EF63AC1B7D
+:10622000A9EB89EAFF9E731ED1E73BDEE8A3DD35CB
+:10623000B21D7E97C7DF843CFA0E6A9D9E3F2BEF0E
+:10624000F530E81B53F71DC73B4AF4FBF0499EB0FD
+:106250003F39DBEFF4D6408EF4162B715E68A62A28
+:106260009A79DFF83CBA4B3C3E32FDEF0B918FFB45
+:10627000C86F63E5791D1D7F33EC0D2F39B35AF1DB
+:10628000F7D1D23FD8A4FC0AF7C0BEDC3555319C0B
+:10629000DF5630AAE851C8BBB86C2FDF83B1C62FD8
+:1062A000F9C9DEB568339E97AF7EF161DC9750592E
+:1062B0009FC5BF2B53BCD7B712E71C0B46694F6075
+:1062C0009EC52E37DF1B52B13C89F5D3CCF67ADC64
+:1062D0005534F33E9C81F7037A7CEA9E51F2FBA78A
+:1062E000743F03827092A9DD85E27432FF06F939AA
+:1062F000883F6AAE3D1C2770DF2CEFA9B08B776416
+:10630000FC31BDEDB841A61E6FCCF0CAF89081BF3C
+:106310003B7ACF66396733E2B9E7F0673E8F69941D
+:106320006EBFD4EFB36F50D85F2D59A3F2B9F2B15D
+:10633000EA78BEC765F1DD8A87D7D7BDDD38DF7B58
+:10634000F1ED648D7970BECC53D87E00EE5B57DCE6
+:10635000B04B66801611F19D92B58379BD9504A965
+:106360006CE35E53A3BCF6EEFD9D9EF1808C7EDE59
+:10637000BF2C71FBEDC911EB7D4E9D62BA5FC180F0
+:10638000855FC6DB66085290348E19DD3D0AF6152E
+:10639000DD7E8987EB6EC8B2E3F74866D0972D396A
+:1063A00017EEFFFF95F2FF02371C2052008000001D
+:1063B000000000001F8B080000000000000BE57DBE
+:1063C000097854E5B9F077E6CC99992433E1640172
+:1063D0009200F1241088803861A72E1C1202130845
+:1063E000305940F086308120A1456F0497D04699FE
+:1063F0009085104143890D52D461F3564B352ED709
+:1064000042C57600EB525131486B1793617169DDDB
+:106410005228B5BD0FF7FABFEFFB9D93CC39990415
+:10642000B4F6FEFD9F3F3E78F29D6F7FBF777FDF22
+:10643000EF243F9DBDCC2632D6B54D90F7A4315602
+:106440002EABB6F14EC6BEC49FE98C2D6F16D4C0DC
+:10645000D89E727E3A5BE68572B4EA626C1263651E
+:10646000B2624B4EC3A76C8B87F7CBEF3822B14497
+:10647000C6568C604CC882F6F16E9B13C75F0DE365
+:106480000B8CDD2C0773B1FEE6B10AAB8983F67580
+:10649000593606F3F9B6F0797C8D71B66BA05C665F
+:1064A000956DC3A05C12CD18B687F505B07F795005
+:1064B000B5C53B715CB6ACD0C9D71B1FB6BE326D3B
+:1064C000BDE5CD71B69586F7DB2405CA4B1853DBC5
+:1064D000C2F6A73FA7AB02ED67795D416A2BACB767
+:1064E000DCEF9271DE72AB6A73E3BA705CE8B7A45A
+:1064F000A5554A0BEB7F8D6AA17ED355859EF9E9A0
+:10650000C10C01F77B7B941BD7BB446E96109EF9A0
+:106510003A9C1FE4705829073370FC950E0E077DD6
+:10652000BCF2163E4FEFF5717897B794D914A8BF17
+:10653000C5EA4D6D85FEB7C03AFDF05CB2E3488612
+:1065400080CFCA28B700E7C1645FAAD7D5D3FF833D
+:10655000076F4AA5FDC3FA11DE2EB7322B09D6B359
+:10656000A21916A3D093E62D9DC02ADBC2E0769334
+:106570006A656C203E2DF464CDADAA6310C083F132
+:106580009FAB6C2766E03E6AAF666C23ECC3E77C8A
+:106590007E06EE53FE2E63E23458EF96B7A97E4591
+:1065A000129305A8B7B1E704ACB795431F28337F12
+:1065B000AE1ACAE4637D99CED8301C19DA3B017F4C
+:1065C000FCC98C554E5168DE252CB4840D8771B6FC
+:1065D00014C01CB0CEC17C9DA50358E53311E0D595
+:1065E000A2ADF766EDBC4B2CEC2516DF537FAF76E2
+:1065F000DE2588CF61FD713C1C778D5E9F1DCCB878
+:106600007D6C4F7B7DDE9278DE0FE901F1708D8627
+:1066100007D87E2DB5E7E55CD1B9B11EF6B376ABF0
+:1066200018B00BF8DC5B3F08CB4F0B6E84FBC76BDD
+:106630007FFAE62278FEE907BB4B717FFA3A56FEF5
+:106640002D8B290970BE7FBB8E9EE5C1694C99D008
+:106650007B9FC7A6F8BEA74E0AC39FED3F19E983EB
+:10666000F93F7EF2F50C84F31F00074480F3BFFD71
+:1066700064AFC4D27BD6BFBCF16DA9CC190E2F81FB
+:10668000E0D594D94EE7B72293F75B51F7E7323C58
+:106690000FE6B4291969BDCFBFACEE69DEBECA4DA5
+:1066A000ED7DCE5FF3F34F61B2987CF9F3D6CFD78F
+:1066B0007CEE8F48DE609280E7D36CA07FF3FE1FF4
+:1066C000D6D61DD0E8EF660D8F6FAED846FD963753
+:1066D00096ED1561DD4B74FA2D37BED7CFE7FC166A
+:1066E00089CEE7FC968C86242CB7F1F3F98ED83648
+:1066F000EE6E68F7F19AFDB725A7E3AA03A9DE6B52
+:10670000F8F9B009FC7CF0B90ACE8725443C9FA774
+:10671000C2CF67D5A3FC7C563CF9C67B3F5308FF2C
+:10672000F8FEB6DA03C87F97B73D7DEA5BF07E4995
+:10673000E336290DDAFD424DA37DE9FD575466C9C4
+:106740002C16F6D7B85B423EF00B558988E73A5CC9
+:106750009995F399472438DB38AA67427C4FFB258B
+:106760004C1D8C7C84F987B2FD89BDD7FF278D8EA7
+:10677000F2D3DDB6C1C8BFEA63D81E19D751763F40
+:106780001BD7BBBDFE3C1BC5E96239CC83F47976CF
+:10679000863B15E9A2C46231D09BFE3CADD1D790B7
+:1067A00098B625B8DE21094CAE0510FF305ACDB69B
+:1067B000C0BC3FFC9643AE75637F9F82F57607931E
+:1067C000FD00F23D16653CE1276C795332C232344C
+:1067D00009F9DE8835A13FE3FA109DA2C6F3A70BA5
+:1067E000F66D9FC1F104CA6C107F1FC4E7306B1BAC
+:1067F000F1A9E82A8E7F36F60E956DC0B7106FF5B9
+:106800007E43D80901DF27C35A70FEA6CCE5747E0B
+:10681000D2084E2F7DEDEFCB2BDCDFD9345F80E447
+:10682000441493F7C4D1FED662B97B7F994CB5402E
+:10683000FFD2EF5DB3BB09863C5BA31EB541FDD91A
+:10684000F54EEAFF4DEDD7BCCF25E565867D76D3C5
+:106850004D33F0B5347C4E48C5759E77C044507FAB
+:10686000F6F6280BC2FF6C1AD717180BB90AE15CB1
+:106870001EDB00BFDA19FBD106073D9FD800C834E4
+:106880008AB1031B92A8FCE406859E6D1B32E97D4C
+:10689000FA0C8E7F25D16A2CCAE5AE1A97BC07E1A7
+:1068A00011E474D351359CE0007A02E7C79A5ED0B8
+:1068B00021875CF1617C1AE4C7569477AC6A38DBB7
+:1068C0000F5374349F7559C6225EF2F5E9EDEF90CF
+:1068D0009AD97A6CF79010D80FE3C6DCF176EE60A7
+:1068E00094D32D695902F45B5A7581F8E152E7207F
+:1068F00085A11C77FA1AA660FD8E347923748B6902
+:10690000C9EAA882FE2BEB46B9B1FD1D82D240F345
+:10691000D6086E9C177E54C764E003F81B94573961
+:106920005F1EA1F14B0BF2CB15F7AF6F4886F269F2
+:106930000BEB120134F996825958CEDF19E7AE45B8
+:10694000795BCBF7C376011F75F4F05175AAF7FA9E
+:106950001970CEEC12E01B8C3F1AD6C644DC4F9B5C
+:106960008AEB67A077EC67B85EAF0DFBBFA0F1CBF9
+:106970008E96D32E453B9F02A41B5FD7E94D78AE80
+:106980004E8BBB4941F9AEBCA520DC5F13D91E0577
+:10699000F187D7AF75F17A786EAC87FAB5BBC500D1
+:1069A000C223572C191442FD6B87487C71E5EEA277
+:1069B00041A86FAC8432CAAF9D3815E053434B0EEB
+:1069C0006FB72DF7077EE0A7A902F3223F3A670DC4
+:1069D00015203C3EDA3D38BE06F5BD5B6B4732A85C
+:1069E0002FDFBD29159F1FED8E5A8C7C7CA65C3055
+:1069F000330EF59F5D7159A2D243671533389D7DE3
+:106A0000FBD69CC128EFD6FCCFB1476490AB2B01DD
+:106A1000476518F7625B4CC00F4DD66C38982A0258
+:106A20006A39137D2B106EDFB11C5E340DE5B0109A
+:106A3000782C99DA2B83E54874ACEB5380C70AE0D5
+:106A4000E9ADF7BE4BE37C6A393E7F09F45F73EB37
+:106A5000B3B138CE771E3C395986F759137DFF8E76
+:106A6000E3FF49D8FD980C20613B768F43F95139FB
+:106A70008371BE1AEF5DB484C3D7BD47E97BBE8A7C
+:106A80008302C1532F2F0D0CB031D44B83CC26E39E
+:106A90005366A4077F24B22A94EFBA5EA2BFAFD593
+:106AA000E0F2D180E6543CFFD58FB5A6A2FCF8A356
+:106AB0008B977DFB5E59F95D5887AFC52233C03B8C
+:106AC0009F9591DEBBC2CFF5695601CC24B967FE14
+:106AD000AD336268FDAB774C30C83D908F34CF1F2B
+:106AE000ADCC83EBB8AAB62B0BF5A7DF5B832BF1FC
+:106AF0005C7F0FFAA93F0DCF89E3DFEF9BC559F803
+:106B0000DE7F87C032042C3FEB1AE1243DCC427C6F
+:106B1000FD0529B01FDABB26B60591EFDDFA5CDC76
+:106B2000780463AE387630E2CFDA43D2AC215C9F92
+:106B30009271F635D6A02DD2B97D5BD3A3BACBCF57
+:106B40003D6D43BC5F7300F401A4CFE78400EA37D6
+:106B50006BDA9E7E3905C6BBED60D9049C476F7F1A
+:106B6000DB731C0E512C642B0AD3ABCB32E31B8698
+:106B7000008F7C72C6BBCB1E842D95E1397D0BF84E
+:106B8000D7F45FFB6A46E053A67D326B17E9E3A0BA
+:106B90005FD950FEDF5AC7C7BB35B3BD219DF6553F
+:106BA00090C0C2CEFFA91912F5D3FBC3BEA95FAD39
+:106BB000E3DE4743B05EB5D6CAA26E84B295FDE16E
+:106BC00031841F8B95F7E33EACECDCCBF0BC5B1C57
+:106BD000C09AE0B9AB72ED7F50FB1ABB2CC2B3F682
+:106BE000D6EAA742309F22322F83FEFEEC4A1ACF0C
+:106BF0006FE3F2A735E6C9876E817255B1D30DE810
+:106C00000DE55882CFE1BB2CC4E79359D7310B3C3B
+:106C10000733A02200D04769BEE3C47718E7C777DF
+:106C2000AF5302C88F61E502E2F9E72F7E3801D742
+:106C30007DE355A10B885752CD87BE9940FFEFCC1D
+:106C400090B97E32363401DB0D3CAAF135EB099266
+:106C50008F5292128FFA4A10C7C2F5FDDD4278704A
+:106C60005808EEC5797538456573FDEFEF6EDF7B2B
+:106C7000B80E5590EE0C42FB0542AC1BF77B225E32
+:106C8000CC180FF4FCB9F487341CD70F682B0EE92D
+:106C9000D163B3B5A5DB52A6EE40B8CC0080B2EB11
+:106CA000C196191BCFAC50BE8F59BAECB08EECAE6A
+:106CB000DFEDAE81B2FCFD014C0451551B95CAB20B
+:106CC000617CE1286C14F67374ECD115B8CEFBBA74
+:106CD0001C0CE1C41C463DD766490E7E0FF1B9324B
+:106CE000D6CD92500EB565213F62B739DD4DD07ECD
+:106CF000E9A550C6BFA35CFAFB71D2D347A5FBBE82
+:106D00009801FB4A11D5D33EA8BF4F0E0E7F00C796
+:106D1000AF8A71D77039C2C2D77F78FDDF6313A005
+:106D2000DFE75D23AD4F41BBCF55871B3458D6F10C
+:106D3000DD312F5D07E5EB3579625ED7E7498A15CE
+:106D4000ED8ECFBB1C41D4433E775A02028034FB08
+:106D5000F0B1770590DFD90E67508CC57ED227E160
+:106D6000F2869D1816F7C1181231EC4B80E7204DC2
+:106D70002EDD38C0683FA664733B28259BF31FAB0C
+:106D8000E226389FF75B5913E2218332CE6B75C838
+:106D90004DB0BE9F3B1F5B0A94CFCEFF2D7D00CA36
+:106DA0008DF387870F6063FBE68B27519F003D6162
+:106DB000D178352D7B528F7C5DA8C125AAF9260993
+:106DC000E1510BF06802782C745A8276D8172B3672
+:106DD000C28155759522DE304BAC1BE906CF17CF2B
+:106DE0005F112C5DECBADEE73DFD921CFC1E949712
+:106DF000C279225C4BCF7F70CD038CCEED1A5C073D
+:106E00009C63FDB5ACE7FCFED5CE8B59DD8D780ECD
+:106E1000778BAE663C875A2BD7F7FC805BFBE3A8E9
+:106E2000DB63782E77D78EA0731A540B7C02ED9417
+:106E30001A2BDB93887CA59DDAEFD7F4419659494C
+:106E40007CA6B4D62E23FCBE888EA5FE0CCE554A59
+:106E500089C467385FA92A67C457968DAD14F0DCE2
+:106E6000937006D84F8725E4C27D86A2408B84E7C5
+:106E7000FAEC74A2F321C81186F373C6FE0FAF7744
+:106E8000ED417E233A863C7C0E44116BEC8A1D0D4D
+:106E9000EB6A11581BED4BD2F8C76A27E9732D71C5
+:106EA00001E26F2D0B87BA71AF9F33ADBE229AF806
+:106EB000CB75160B95BB960C227BAC250E582B8EF2
+:106EC000B76434E90DCFFF8FC8EDB50CC6EBB3D86E
+:106ED000C81D585F9049E3BDA0F3ABAD2E1AAFA516
+:106EE000404D8EA6FA4116EC5F9EE65B87F8912234
+:106EF000F276A07850BB9D3BD5643CCF9D85366A29
+:106F0000F703C1BB64258E738D93F4C6D092E82736
+:106F10001FE3C71944FF524715DFB74E0795533893
+:106F20003FBDCA7FFA21E41FFE6C381127CA8BCF00
+:106F300096225EAB62AC1B50B8D7397FD18DE7ACDF
+:106F40000B80CB12A33BC85E573218021BCE4F6694
+:106F5000D98827C7009ED0DE2FC13927F273DE986B
+:106F600088E73C7F77F839C378FEBBE1BDB036D601
+:106F70002D4CA573CEC4F1AB58B41BEDEBEEF3FB77
+:106F800079200B9FA2C59D6407583C9FEE7B307B08
+:106F9000608F1C79F83DD81FC0A5D41E9AD48CFAF6
+:106FA000B98555B445E0038F6673FB40665D12CA30
+:106FB000D7653AFE579BF03F3434EE83180DFFA19E
+:106FC000DFE1C1DEDD780E9F0A2727E3CBE3FF2D4B
+:106FD0002E8E34FEE39A7C792BD1FB235CDF08EB09
+:106FE000D1A1EB50DF586F27FD975D3A3614E7AD1E
+:106FF0004EF3FE18C78B1AD16543FF54477297842E
+:10700000FBEB58F2A761A8672DAB7A85E8F34AD766
+:10701000B731669C847233CE932585A0FF604FD62E
+:107020002FF15CDAE7D9157B043FC891795386A12B
+:107030003E74326FCA30E497278701C9933C75BB11
+:10704000908F4A07AF71E13A4F7A265059618A56BC
+:107050002EEA97BF7E0CFC35088AC01FC15EC3E7CD
+:107060008760AF0581DFBE0FF61A3ECF82BD86EF87
+:107070004F83BD86CFCE0D6E7A7FD233FC20E2C522
+:10708000C566EE4759617547D4CBD61C105950E7F9
+:107090006FF0EFDBFB620CE58A5D0986F22D2D8037
+:1070A000418E9E72F996E186B2AE7F2EAF1B637859
+:1070B000EFAB9E60286F8C2995F09CE28AD3387CD8
+:1070C0008BD308BEA7F2FA806FDE28826FFBC25115
+:1070D000C3107EED085FD48BAD8A0BE1271D5CEAFF
+:1070E000423DA6BD78389501BE5B27E2789A1DD552
+:1070F0005EDC3F9CFF88701E85F07568F095099EE8
+:107100006735389F46388F42F866D2B31DE10CF5DB
+:10711000B5C50067C0C78B7E941E805FD62E29A29E
+:10712000FEBB4F34ECBF62578C09AE4638976F19DF
+:1071300062282FAF1B6E28EB70F6551BE15CE499BB
+:10714000606AC7D816907B45F80BE0F91B9366136D
+:107150003F3D29B0CA0478C6C99C0F5ABD02F9DF69
+:10716000F0A719E47721FE02F463752AF5585F074A
+:10717000EDBF0F6DD106463B8431B75406EF177A49
+:10718000A26494EB8B5825D1DB62D64CCF9B591B64
+:107190003D4BD8097A96324E8F9F978526E3F3F7B9
+:1071A00089BEF41CA0E7350EDFA38968BF0DF38DFF
+:1071B0004A40BEE48C27FBB4AF73424D9B697CCA46
+:1071C0003959DB17FC14E3DAA15F7BCCB83BEF54F1
+:1071D0007AE6D1C787F9DC38DFA7129FE78D4953DC
+:1071E0008621FE31EF40835DD5D77CDB347959E6CB
+:1071F000E17042DF2D96CF2D14021BA17C649BDD34
+:10720000867E86739B254D6FBF97ECDDD3A7B87F35
+:10721000E65CFDEC54C4BF9A6DA35211DFCF494A1E
+:107220007D15C0FFDC34E0E36EF2E7B8514E9CF10F
+:10723000B8A83F488CD82C38B715DAFECE286EDBBC
+:107240007A68BF3059647E68EFF3A7C5E2FAF57D2E
+:107250009BD7BD7C8BDD80170BA61ACB0B99AD0796
+:107260004FD2F0BC6D3DF5A82F8925037CFDD8DFFA
+:10727000557F58FDD64B6178F66F39AE44D46FD840
+:107280001436E54BB1A77F5FF0FD6243C55B2F4924
+:107290003DF0D5F16A528EB71CCF095EDB903F02FC
+:1072A0005C2C28974F1EE470DC1673E3D6EB000EBF
+:1072B00085EF888CC3B9D4FF7BC4E743DCBF6F9EE6
+:1072C00027A4D175A7C63FCBEADE263B6E597501D0
+:1072D000F19F4267D730F43F1DB907F80BF295795B
+:1072E0009CBF1CCB1BF5F01D306E67BEE8B6033E9D
+:1072F0001DC9BFB015CB27AB4519E7ED3C7841E37D
+:10730000E35D6F4C81F57DE69188CF741EFCE7F05C
+:10731000F3C2431A9F09707EBECAEA650D30EF2A98
+:10732000800BDAF3FF6CBE7E397EDE2E7973072286
+:10733000BC6A0437FAE16AF2ECA447B4037DD83999
+:107340003ED5DF81F2682AD8C132E29B7712DA9605
+:10735000270F0E1F88F0627EB53D73720FBEAFA877
+:107360005E958F7E76B6453A83FA373A45504E178A
+:1073700032EB9950189EFA9E937ACA84D7D633A1DD
+:1073800030BC36E3699B094F2FB24BA9B6745E7FC0
+:1073900062500FDFC39F70FE729B186C60693D786E
+:1073A000FBD7BCB74B515900BEF202E2EB5DE3D311
+:1073B0005E0C09617CE50AF918E033C9BFD6981B59
+:1073C000B97EB190CBBF230B6F3AFA3B80DFC7F396
+:1073D000385E7F9CF753E21F1F839685F87A2A3F19
+:1073E0002116F1EF745D11D1994E3FE679DA357CC3
+:1073F000D3DB155A15C91D013F8B3C467CC9786EFD
+:10740000E90094A77DAD5F1F576FA78F5B88718DD3
+:10741000B17D8FFB610EB74733F695F43B3E188282
+:107420003DF885FC8445F78C03E5233FB98961DC91
+:10743000F5643187CFC903A3881EDB8B75FDCA476E
+:10744000F5A73C6200F5D893C513DE9888F4E39560
+:10745000484EF735EF396D5F67343DA053D303F4E1
+:107460007AF1C1858B96E0B81A5F38E5E1F8FB7ECA
+:10747000CB42D23B603DE47FB2CDFC9F32F43F81F2
+:107480007DED42FED59E2F325C47615E11D9D585D8
+:10749000923230929E60DEB779BC233FB1935F0E8B
+:1074A000C623BA2A9E57C41A705FC5DCFFDB8EED77
+:1074B00061BEE20779F918B69F688013F19176E012
+:1074C00023283AA4833790DEB4B2D9784E2B1A63BE
+:1074D0004CF46EE417C50B399F6BCFCF191889DFB9
+:1074E0005DEEFCF4FE577AFE15D81FCAB8E62F49A8
+:1074F0004F89378C07169D69BE7453FD6853FD781C
+:1075000043F972F8D8A9C991761D2FA294A5DE0877
+:10751000EB6F7FD25E119EAF317726B75FE6CED498
+:10752000E2F75F51AECE9A09FC2A86F592AB7DF563
+:10753000D7F9D3A81CEFBC99385FB048C27D5D294C
+:107540003F0A93C30BA97F48B061FF6D9A9CAD6859
+:10755000E378D41A73FFCB88879F6AF6D091799C21
+:10756000DF7FA6F1FBCFFE532BFF440820DF3C76E4
+:10757000E8EE58D4DF3F3C382A16EDB1336DB5B193
+:107580005C4FF7C77E0BF0F313A0CB2698EEA3B6A3
+:107590007F8E9E5EFCB4660FFD88EBE9ABADCD91AE
+:1075A000FDD4DFB09E6ED6CF73C592A3BF83757C2A
+:1075B00018E07034EBEB1F2A4AAC4CF0E170F84C49
+:1075C0005262D1AF7726C0F97D5FF8A8C3E11CC233
+:1075D000218CDFF705C7B35A7FBD0CF621D92D45A5
+:1075E0000EF72F13D19FB0457063BC8A59199B0ABF
+:1075F000E778A2386B6F53989E11972B12BE9CAE02
+:107600003B569A8CFC070C5DF4F7BE527D2C15FDA1
+:10761000AC650762883F9AE72DCF37F2994FEA0BA6
+:10762000B27F0FFD8ADE11030E84477E1CE75F4F99
+:107630008B0111CA9DD539B1E1FBF8D02477565999
+:107640002B239E63C52EE33916E5D7D038271F14A8
+:10765000DA8401F03C324D525CBDFB1559F9FE57FE
+:107660001D10C9CFBBAAEECF6F607C7115F07B54A3
+:10767000135E69AC9D8F787DDA2B5910CF3BDB12FE
+:10768000E6237CFCC5A23B03DA1F6F1C4E787EA666
+:10769000316710CEF7CB9922C9BB0F0FDA2DC2B5D7
+:1076A000F0F44A2C487E81209DE727754524AF3EA3
+:1076B00044B8903D2B135D9C98C9E30EA7611CACA8
+:1076C000B7009DA03EDC19103D8108F47162263F91
+:1076D0008FB3971E20FC7939702C16F58AD36D7CF8
+:1076E000FCB3D5722CC6A95EAF9BE0A2F5E5C3B88A
+:1076F000A8F71EE272F4C33A8E8FB84EB20F1BB9D0
+:10770000FC3859B7E2FE69008F4FB788A4777EDA5C
+:1077100058347F1A9EF71689CA39050B29CE713263
+:10772000C0E5D1A9C0D9523CBF0FEBE0F4A15C7316
+:10773000680AC9DD4FEA25C287F203C67359B82526
+:10774000C66CAFC66681DE558EBF29F83F7516DA66
+:1077500049CB93407E02E59ECE2F92D04F59E84F01
+:10776000308C63670512E21DEA97D86EF9C3459322
+:1077700082487F7E81E4DFB2E7009F603DD2BEEBAE
+:1077800049DE9535DB0DF316561BEDA3E5267BC8C8
+:107790006C2F5D4E5E9CD6F054B73B4E4B95A59139
+:1077A000F212E45C4D2E307916C2FD0C18D64D59FC
+:1077B00000CFE74415CB17EBA2887F962D3B7F8344
+:1077C000A697DE8878C0DC7E3655B7D3C3E86C79DF
+:1077D0009D6892DB46F882FEFC01EAC78D099A1C7F
+:1077E000F51791DF6E548E1A9F8BEBB852FBFB8A14
+:1077F000F5DB524DBF2D25FDF624EAB7B09F766C20
+:1078000012D61FF45DF2EF9C9A7713D95FA7BAFDE9
+:10781000675ECD7FC6F59453F9459A7FC7AD97074C
+:10782000B07EF89CCE2FDED7CEE1ACC6274F6B7C66
+:10783000B253B3B71A347951A7C98B53F99ABD958E
+:10784000C8485E58AD2ABB123E734B4B8C493E2450
+:1078500098ECA821A6F331CA8BED5EDF6C3C077B68
+:10786000D268C37B491E6FD4CFF71D263FF24585F2
+:10787000E7156D429CC0B8C9429EA7C51C6DE44780
+:107880005EE856A87E08C60BA13D9A54984FA2E325
+:10789000A7FE5E4EE4EFF5723CECBA06DBA5B551EF
+:1078A000B9762163980F33421F07C051037AC21083
+:1078B000F467C33C4960A0617B1DDF87166FA37628
+:1078C000D9154C16A0DDEADC34C28724A6127F1934
+:1078D000B486A998F7C202CF52BBBDF7C23E00EFF3
+:1078E00043B5D3C92E2F72C4F2B837C8C7FEF1AC66
+:1078F00086C7773D09A4B70CB572D4EC136FB57683
+:1079000097C3DB303DE82EA20B66217FC4B6987189
+:1079100012E269A1D34B7E03C0EBA577A27EFFA242
+:107920008DFB0916723F707BDE9487D1DE1DF794C4
+:10793000937CCAED2B757F6517E1736775911FE521
+:10794000DEAF3D5CCE8D79EA130BE6BD751E646E2D
+:107950002C1FAB7EF6FCAF486F17C81F74B23A8776
+:10796000F365C6BC98C779D293B391CA53C130CEE0
+:10797000427A50375A711D00D726AA5FB17512EAB4
+:107980003BC745C2DF242DDF48C6734DEE2927AA29
+:107990005A991DA472523ECF13FC99A61FB469E7F1
+:1079A000F9B8E6A7784CA39B168D6EBEAFD1CD6615
+:1079B000B3DF7917A79B9156F7D618288FF4BB48E9
+:1079C000CEBC957F96D60DF42F635C372D4F6C9A05
+:1079D00008701B630F119F2E02B1B711F63323BF3E
+:1079E00086F2188B7C8CE21685C535B4BE10C6981D
+:1079F000AE43BDA94610B57AE48F631282D4BED0DF
+:107A0000C164EC5FE479FA08E6E32EF40168A03C77
+:107A1000B3B84620F894C178D0FE48F5761AEF54F2
+:107A2000055F47BB8BF73F59C6643F943398E7E83F
+:107A30001D7C9D5E8C8B9EAA7EF608C1BB98C3FB05
+:107A4000BA8F2C067ACC0A461BE87AF4BE7843FD3E
+:107A5000A81D2986F2406FBAA17D82C748EFD123C5
+:107A6000C61BEA4F7A8A2C2867753B4FF78B757ACD
+:107A7000B8DC9DF194D382F058A4F90B1061D920A1
+:107A8000B4BA18F97D1B353D91350F6798C7B1F72A
+:107A9000BB16CA13D85C5CEBC0FC878B6D563A2FC3
+:107AA0001897F8C8A9C3561AD7915627A01FF33EB6
+:107AB00080B318A6FF35EAF24D8B5FE07AAC61EB3C
+:107AC000895718668E75B76FD1F069BBB60EE0DBCB
+:107AD0003324B2C7399E24E4338B04FD071673396F
+:107AE0006DA6CB36ADFFE35AFFC7347CECF4ECDD7A
+:107AF000188D7059CC481FC915D76C8CC275E433EA
+:107B0000A2C7B6E0D1E870FDF1677D8D533C2197A7
+:107B1000C6F1733E3A7A81501B85E7BA2BF4A7373A
+:107B2000E1F9C2A70D1B6361BD4F08AC0D294AE7FF
+:107B30009FBAFE7DDD678D543F7A3C986850FFC246
+:107B4000674DBCFD64A6A0BFEB679ADC69D4E8274B
+:107B500063DF58F22F5EDC6123BBE7B1F9ABF6B40B
+:107B6000C07A47CDBDE789E7105FE6DFF3BBE79456
+:107B70001E3DBF687E7207E6F18FDCE062C81FF42D
+:107B80007933F67D924DEB96AD0CF1F4C7FB9F5F18
+:107B90008EE33DFE58B44585F17FBCC74AFCE5EA5B
+:107BA000FB1EDEB383E48D492FF618EDFCC737B713
+:107BB0003E7110DF573DFBE8B9B07C9D93F3360D65
+:107BC00043BF69FB868A9699197DF3CF221BF3A1E7
+:107BD000FFC7F3C227CFBC0EF3FFC677F5F8703BA3
+:107BE00060D42CEEFF69DF50D53213ECD4D122CF14
+:107BF000576056FF4684C7E89F0E52507F0352B02D
+:107C0000FA00969E39511615F6F79B807537F1816B
+:107C1000399B33F03CB37F9C7FF4233CE7531ABE7F
+:107C2000F7A18FE87EAAEEB2A410DCFD2F3AB87D52
+:107C3000A32AC3C83E762BC30AC3F4B9F67BF43833
+:107C40009EFB3DE4E3852531145FD6E32EA2E7CF0A
+:107C5000F5C8E7974DAD9C24D3FA8DF1FC1484DF71
+:107C6000048CF7F2B8BDDF6F65941F045B433AB92B
+:107C70005B1C4D7927EFAEBE8BE2F6FE1ABB9C91E2
+:107C8000487183A7B05C057CC73E91E2B901CA3751
+:107C90009EC5F3372E2CAE7DD8A6F40DFFBACB9C33
+:107CA0008FA49D8FF9FDCDDAB9D4E2B96418CEE581
+:107CB000A86F6284738975107EE9E722C636D2B94F
+:107CC00030873313F33F067394C2FDBC8172A8E37F
+:107CD000944872EC3725EB6AEE86F2F94B0318D222
+:107CE000851E57294DE279087424C0B724ADFF6082
+:107CF0004DEF463E867A77A91677E958CA28EEA254
+:107D00008F77B16A80CCC7BB8DF4E6D24AA07F944E
+:107D100025313F27FDA27E38CF932875762DA5BC4F
+:107D200055C1E2C6F8F960935EEF6795B4DEC1EF26
+:107D300088E4CFB7C46CA1FE83013C6216B6B211D1
+:107D400010A83D0A76305A31AF24055F28617A9633
+:107D500096B73BB8EAA75C3FCA819EC986F9842FD3
+:107D600069FDB5EF8BC807AAEC0AF23DCCD142BE43
+:107D70004DF04B433C6AA5FEF2B7998CF73998CA8F
+:107D800094C4C9DC0F86F399D70FE371BD10F433A7
+:107D9000DCAF50CDE7DF3597DF07618799126EB70B
+:107DA000B0F0F50C3794353F99B12C25D90C72EA17
+:107DB00037978A0654F6EBC733F6B728DEFEFDBECA
+:107DC000156176577A4F7B3D5F4C87734A95FDB4BA
+:107DD00010DB77BFED5EF5C02CC06727F366FF0AA6
+:107DE000E0E17B4724796789394EF0084571F874E2
+:107DF000EBB38BB9BE0BDA790DE55D83BCC3F3C37E
+:107E00007CED9180EFCC6FCC17D0E7D5E34B1D1AFA
+:107E10003F0EA58522FA058F69F4DBB9E173CA2B01
+:107E20002845FD167039B4F163C33D900105338ECA
+:107E3000E1BACDF908BA5E8A7296F0D7CFE56C87C1
+:107E40007F02F19D8BCCD54CFABF99DF5819E57FA5
+:107E5000DC2D46BB9BC86F772FE58F54F9EDB21D23
+:107E60009EF3DC467FCC82A9467950A02698E48513
+:107E7000D1DFB5D06B8C138D68594FFCEB22EA4DE6
+:107E8000C4EFF87AAC5A7E9984F74C44B4D7FDF429
+:107E90003CAEF1E737353D330AF92BBC8FC1047393
+:107EA000C047170B517900A2FC704C6D5728EF3179
+:107EB00081A9541EC87C54D6F3219359809E7A9E82
+:107EC000CB3016A2F255A80F8948520A3D87A31D50
+:107ED000321CF53C7777BC87F22773D2285E50C0FE
+:107EE000D4F7B05DFE844F49EEE5DFC4C80FCFFC88
+:107EF000F52B5428772CD4CA98098FF926B98C23EE
+:107F0000A7BF96D7E7E9E5BA152AD6CFE0EDA5D900
+:107F10004D7BFD4EE25F5AFD265EDF5D6E583103FC
+:107F2000CB9285CA715AFBC299AA6D36E62DCD66F1
+:107F30008407C11CD5317B604FB92C478D0E2FAF04
+:107F4000CB559DE1E567B3D5D8F07267B62A879720
+:107F500087E6AAF1BCCCFD4EEF48EA30B477E1E702
+:107F600047C2648E87F8F39AE44BC176EA0181E058
+:107F70006507BE8DF092981A44A60464E3C07C2283
+:107F8000E033B63BA19E8DB751DE9F25C699DA9F9F
+:107F90003FD24C5F21891D443FDD02AB2F13F76DAB
+:107FA000E67B82FF95BF633E0FD04336EAF9A16AB4
+:107FB000AE0784AAB93F40A713FDBD79BECBE13D12
+:107FC00053C3FCBCE93DE3F6B57E331E9FD0F4BD40
+:107FD000764DDF7B47F34B77EF37648DFBC0D143A2
+:107FE000DF7DF34F2BFB208C7FF6DEEFD9A51297B8
+:107FF0001F32CA8B8E28B638D2FDCABED6E7CC99BE
+:1080000055309BECDBA132C51998CEF739BFE9C0DA
+:108010005F810F8E19A0DBAF6E07C2218325CDC90A
+:108020008479B77918E9AFB5338F1622FFB95802B2
+:10803000120CD675F68E7348714C788ADB13CDC35B
+:1080400018ADD7952647A1BE54AFF14D3B8BCB1B46
+:1080500081EB1F6A25796B5E777D6C40C0B8624A00
+:10806000308AFB371259200AC649F1B83D94B7E26D
+:1080700017650F964BD8FC4C282F6F11150F8C737A
+:10808000ACA58895C3B8E55381CF51663ACFA78890
+:10809000D7F0788C9D51BE45EB4027C5ABEB368FB2
+:1080A0003AB212F966B2C832A0FDD8FAF11EF47BDA
+:1080B000D63AE3E329E6A4ADA7D6E97E15EF63F847
+:1080C000650BBF4F22AB0ECC47DF7D87D583FC7C91
+:1080D000D8D31363C530F89FAD3B1F8579EE8FCAA7
+:1080E00016AA7FB43ADB718B13EF130655CA33908F
+:1080F000CFA84E987727B4190CE3DD5F71A67924D9
+:10810000EB1B1F623D36039EC6B86D263FA8D16F9C
+:108110002999F483E6D95AFC7B329B8CE77CED13DA
+:108120009724D473973915F2A367370A949F123AAC
+:10813000E24EC5733ABB7514F9CDEB1A45CD6FED20
+:1081400026BF7568184BC57B3665CD02E9C562DD73
+:108150009F6BB0DF55994A328E73D5C4AEE4707F01
+:10816000D9A3F7DC15857CB4AEC4A2F9B9198DA3E7
+:1081700028AA230DF6FF7E9DC0F3272459C0FBCC0F
+:10818000AE07C5285C57A7C4FD144DC04FF19E6EC5
+:10819000D38CC27EE950FA1BAC33CC6EA94F4C8F06
+:1081A000C6797BF05725FFFAB9E609141FD9D39891
+:1081B0004DF920E671EEDBC0DAD03EA9DFE0A06722
+:1081C000AFFA546FAA1BFABFBF6D46030829F6FE2B
+:1081D00091D549784F6865B39D4545C0E373DBA6EB
+:1081E000D07C2BF13E33CEDB5C60433931BB6586FE
+:1081F0000DE176DF06F5E9F079EE2CF0BD8C7C2FF1
+:10820000A6F969C213270BFA119EBFB8414D45FD6F
+:10821000E25C068B982F796236D7335EBFC14BF78D
+:108220004ADE1F16B9DD3BB3B9DF792E120BCA0F38
+:108230002B7B7315C0B90CE8A9065E9D6D9C108B55
+:10824000782BB135C4A47E5352E4477BEE02EAEDAD
+:10825000C0CF1BEE59B4A31CDAD5DF3BF22D64CF9F
+:10826000D7DAB8DECC7E2D125D805E5886F4F997A1
+:1082700062875C1BC67F517F540DF9825E86FA9D32
+:10828000D428066DC0CFA5C31FFC37DA3B88B76A78
+:10829000181ED3CF64CD2ED0F235922693364E3FA2
+:1082A000F5731605820CE32E2B1C789E663DBD17D8
+:1082B0009EF45A47D8F8A8E7CE646A54D83A802585
+:1082C00004C95FEEE3F376B7D3EAADC060BE0CD36A
+:1082D000DFCDF5FA3E46ED30D2ABC3C3CF0BE0DBCA
+:1082E0006FBCEEEA80B1DF480FA3731B2DAA473F96
+:1082F0004039DB2A527EF598561EFFBF3894919F75
+:10830000A8AFF174FE8B3FD6411A1C01AE0D8985D2
+:10831000749E7DF5B3054EA869E37AECC3AB938CEC
+:10832000EBD2DB8DECDED73A16CDF5C136B4CFEC0F
+:1083300001E07BE3F0794245F99DB9FB0EB9BF7DC1
+:108340009BF9D94A5669437D4D51427BEE43BED1DC
+:10835000E222F983E83062325D5D24B983FDD430D6
+:10836000BEE77A706FD36858C7B95DDC1FDAB46DA9
+:10837000EF134FA0DCD915E3E671267E4EE3982E6D
+:10838000FF78FECF2DACE74719A48D0FED3FD2E467
+:1083900029C350D5A09E78D50707967FF604FCFA2E
+:1083A0003EAB9C8A7C4CDA5DE4B819CAE36C81244C
+:1083B000E4A7B7ECB2F7AC0BFED95B8C65699FBD47
+:1083C000175E3A747C82F19A0E3DB16339CAA943B3
+:1083D0000E37A688237EF90D74124A2F007AEABC64
+:1083E000E73FE89E7EB47C7E29E5B957DBE97E97BE
+:1083F00019BEFB6673BB9F69F736747A8A6A1EC51D
+:10840000D0BF7846B39BCE6C013B15CA0DD536055F
+:10841000BF6FD0E92E5093228C67ABB69DC67365B3
+:10842000E176627ACF3EF4F13BFDDC0FD900E30B3D
+:1084300011FC7D971BEF4F5EB5C203F87FC1EBFDCA
+:10844000B607D67F76CB0ADA6FD5C1EACE5FE1F9FF
+:108450000EF2DD86F567B60C9F2CA023D2AAD0BD04
+:10846000BFBABA67489E344F857760CF37B759A3F4
+:1084700050FFF0D759287EDBDC96183D02E594D3F7
+:108480001231CE1AF070BED9234FBCB1E1FA50D3ED
+:108490004CAE0F094F95DC9F0EF0AA3BC5F3147547
+:1084A000FD43D6F0648C5D26FE2CD7F13CB71E7DD3
+:1084B00088EBD51751AF467D6952B91C2E9FEA63F0
+:1084C000F9F730CA67BAFD781F33C7C9487E5C85A3
+:1084D0009716D06FE16481D969F8BD0C37C3FCDC15
+:1084E00078D07F14C0F8C12D5CDF89763ADD2AE2AE
+:1084F000BBCAE9CA01FF213CA3335586F3584DFAA4
+:1085000085CDA43F88A6F24E8F519F50983B16E12F
+:10851000ECDADA7F1E87EECF05BD89EE9BF919C034
+:108520001FF1D4E1A7F389054302ED0AA6AA4AE2A6
+:10853000A01EBD1FEFB571FF8A4CF122416D20BF17
+:10854000FDAE09DCBF91CC78DC2B45E5F6FCB8A983
+:108550007E2A83FD407128F673168D7C79BBD7F790
+:108560000CE24D9A1020FB2F7E2C1388ECBFA65EE8
+:10857000CEAAAE2CAEF4C3A3DCFF576B897647FAC4
+:108580009EC2A1B99C1EA38FC1DEA09D789383E2F9
+:1085900079B9E28146C4A79D132DE4D7DEC94EC840
+:1085A000C84F8E7B787ED125AFF7750FC565BD6945
+:1085B00008FF242B5854A0ECDA343FEEB03BD3A391
+:1085C00051D4BF9BFC3CC1C30FB0CB807FBBAB126F
+:1085D000E333E1FD23551B09AECA40EE27D3EF9FDD
+:1085E00027C8FC9E7F93F7BC1FEFF9FE702EBF07D4
+:1085F000145D609D930EE5ABAA4302D2DD26977B06
+:1086000031E273A3F20C9D475A9662417FD9102B39
+:108610007BD53E9EB127E3783D0A4AACFFC1D241EB
+:10862000BBC3F3491ED0F6FD0321B2BEB27C2E9728
+:10863000271D87009003D03E669AFDFD7839D9CF7B
+:10864000DD65801BF47FC0CFEDE73F7B1E2FF75B1E
+:10865000C92ED2ECF7F672B2CF315E0AF573F2D6BC
+:1086600095FBA1FC485AE47913F2397C1F794DDD62
+:108670001103F0F86B0D8F63F57DCEAA6001DE5219
+:108680003B90A5E23AEB5CB6C591BE27B3329FEFB3
+:10869000B723B18DE0C5409EC75E47F7E94DFA6A42
+:1086A00080F4E00B15E3FD536877958CE2FFC04F33
+:1086B000264DA6ABFEF4E39AC4E5A8596FD5F52B79
+:1086C0007DDEFB522B9351FF6C75A9C43F5A416F5D
+:1086D000453C2BADE67A6BA9B5EB3DBC3F94729C53
+:1086E000E7BF084F8D6DC2EF1B00BC14C4BBD94E51
+:1086F0009521BF1963F7D23DA35ACC5F977BF457FE
+:10870000260E3DE283F7D21091F4C418B98DF457C8
+:108710003693E7E5AAF01FF21B5D9F758EB51AF23E
+:1087200077EDA6FC5EC994CF9B99A7E5C369FCC60B
+:10873000356962BF7AD3CFC1DEC5751D067E83CF92
+:1087400020D8BDF83C0A76393E5F02BB1CFDDD2F08
+:108750006FC8A4E7AB1BDCF4FE571BA6D2737A6A82
+:1087600048427D9BFCCEE47C644181FC773A3E0527
+:1087700046648FC5FBC7BC7EE69C94FFF05F0FF597
+:10878000895A7BFF17849FDD65A6ACC4F6A549BC5A
+:108790007C302F7525FA775E2B56B3F300CF065A3F
+:1087A000BC65F85D07F65D3BC527CCFB3996A7CBCA
+:1087B000EBC8F63AC34F1618FD35DEBC7EFC353FDC
+:1087C00010F83A96CF5DB70FD731A0C0EA457C4D7F
+:1087D0004D37C609F6E769F107ED99FAABCA878804
+:1087E0001E04A08789FDD14390213DEC74B11B91FB
+:1087F0001E5A5747A6871BF2B95C6D75727B8FCDE9
+:10880000017A1802E512B3FD16A2FC8F0B557B8F7F
+:10881000647C23F4A026A13CAD5B0DF214C6A93BF9
+:10882000B2FA5D92A3480FD07A30D203D247183DF6
+:10883000E077585AE3347A900302C681801E82782A
+:108840005FB04EBBCF11460F02CAE16E7AA8F86640
+:10885000E9A129CF287FBF2A3DFCE28610E53174CB
+:10886000A40592110E3B25EE3FFAAA74326C8E8D50
+:10887000FB8BAE7127217FA995383F9D3DF434F9DC
+:10888000E1F21D6E11E58A47E178983B71027DFFA8
+:10889000E7CD3C1BFF5EC102750FE1FFA28FC8DF71
+:1088A0003AD0C2E9EBD86B7BCB112F87D5B717CC69
+:1088B00046BC582F92DEDB6B7FF334FC11F8FA4193
+:1088C000034A0E8FE7FD671EAF57D69FE4FC368E36
+:1088D000C919B09E24BF5CE8C1F8CCF516FABEC732
+:1088E0008082F6389493FA78CC5A998CF8852AA825
+:1088F000637C6F7A819F36699081DE7EDE1FBD5D6D
+:108900008EBE676BF4053F9477EBD3EE2D7E55FF5B
+:10891000699FFEBC6B22FB07B76872AE55E27918FF
+:10892000D05AC67BFA4F797DBFCD23FFAB490F3BB1
+:108930002C07D15FC6D6C6927F37C9CAF5AE24854B
+:10894000E78F0C617E82B31E07D3F53645E5793E8D
+:10895000B905BEB338EE6EA61CC1EF1938DD6C3117
+:10896000C5B9407FC578F576AF7A8EE6FD9AFA589C
+:108970004281FA497FF874FD22B50BC7EFAB7E4602
+:10898000C15F8E7D89718B6A9ECF6CADBE9DEE738B
+:108990008960AF5830DEE969A3EF02C9B24D51C812
+:1089A000EE52E763DE62AC069F59E227A47FB7264A
+:1089B00081FEEFEEF183EE4CE6714E113DDCA077C7
+:1089C000B61E77FB6F81796CC037FC788F3D1FF442
+:1089D0007428C7A09E8E634DE5FAB87EFF2566AC6D
+:1089E000A6A7ABC638DCE5F4F4017334B9399E4D63
+:1089F00044F8A45A94EDD3E0FD8487724FE2F14C21
+:108A00007A7865028AB329BBEB8BF0FB57ABF7BFD3
+:108A1000BF1BFD92D37E6B6748A7AD87B89EA22E81
+:108A200060742FF90AF83CD1C90DF94F97FB472024
+:108A30007F898C77AF6B78D781789768C0BBCC394A
+:108A40000323E29D1FF9F13F8077E3E718F12EDF62
+:108A5000847713E6FC6378771DAEFB138CFFC03878
+:108A6000EF2D546F98D30F1EA62E5467CCE9070F35
+:108A7000C3FCEE644F8D645551E1DF15D49F0D2882
+:108A8000E7FA89FBDB379F21B9595B95E340FDADE0
+:108A9000AEE4CC1B1847F84B955D09F713819E6730
+:108AA000D083615CE60703F6683ECF633EB6DE1E08
+:108AB0009C0EFD4A65EECF2F95DD0CF3A845679718
+:108AC000E4037EB52CC9C750BFB627597AFC12F013
+:108AD000EF5AE9843707E0DC097214CE984DBF677E
+:108AE0007B22FA9B5E3B3495FC4E3A7D74C4F17157
+:108AF0006FE802F914D67FFADF406E85E1FB0C6067
+:108B0000E0E1E51C47B2A17DAE9C66A89F9D74B5CF
+:108B1000A1DE3569DF4CC40BB14C8BEB6BF7CF7426
+:108B2000FD618C5D253C6BD5F4DB3C25CBD01FF57E
+:108B30005CE47F5694EB503F37739A613E5DBE5FB5
+:108B40000FFF21DD8A26B96D96F356939CEFACBEDC
+:108B5000108FFCBE618EF1BEDA666B289BF808E3CD
+:108B6000796A575DFA05E17FA7C2F1BB4EE2F8EEE4
+:108B70009FAA7D67C5443FE36CDC6F56BBC4417E52
+:108B8000FBDA43DF7AD717E64F622CF01ADE671C58
+:108B9000171BAFA03F7E8895DBCFB2CAEDC0B1AE48
+:108BA000EFD3F86C35979F82CCBF37B90BF8027EB4
+:108BB0003F8B1D0E913DCFBE6BA3FB4EE3E6C7116D
+:108BC000DEECACB0501ED60F856094301CE9562503
+:108BD00039C392985C47F9876FF3EF1432E6DE9C55
+:108BE0008CA6B44A79826CAAA3EB352D2F15ED948F
+:108BF000280F736F9C867C90EF337E223F3FA79BAC
+:108C000097E5EB7959B75FE3925833E6990EC1F1D6
+:108C1000A06D6215936BC94F10A4FAA11E76A2969F
+:108C2000E6E7FD0797336F2394C54A55F3DFFAB49F
+:108C3000787517C591D3057734F2EDE1A297E2C8B4
+:108C4000B14CA638730AABA4678C10E44CE36BF20A
+:108C50008F6B010018AF67B136F2E766FFD8C9D055
+:108C6000EFD6EAB2EDA1FC9890427EB94DA7F8BDCF
+:108C7000B6DAA577BD3109DA37BEC1F3F3370DF3A4
+:108C8000BF8B748D3889F742456725D50F7E5574A3
+:108C9000CF56F07D33C37BC4CB9C9600860AAEB51D
+:108CA00075FD12F3EE58BC8DA13E5207FDCBA0BE60
+:108CB00073A905793143CDB4DBFF88F53778FDAF73
+:108CC000A39EFBDF03E81E3233F90D5B7D5C5F6E14
+:108CD0004DB4119DD7966427E1780D89D174DF6C6E
+:108CE000F18D956F20FFA87D5B746F14781FF4A73A
+:108CF00013EE613CDFE64D433DD4E6B4517E87D9A7
+:108D0000EF6763DEB726C1BEEAE26E49EA4F1FEAAB
+:108D100033CE506209DA62AF3CCE507FEF4D14572C
+:108D2000D0D7A9EFB3A1E4BCB45CC1DFFEC1384326
+:108D3000B51039CE10E2DFD3C8C0FA71081FEECFEC
+:108D4000FEBA71861DF3BE5E9C41DFF73CEDF77CF9
+:108D5000406C2D5F82FCED746E969EF585C1711F8F
+:108D6000AEAF147F53F87BF49F2FD0CA6F1C68FFFF
+:108D700004FDE4C77F74F4003EA75F7AB4642DE07D
+:108D800045C154EECF7FEB7B710FF2E18C7EF97918
+:108D90006EA3BF1C7F103F691D02BFE71E5E5F60B0
+:108DA0005A57B6D5E85F9FE934B69F9568ACF70C83
+:108DB0003596F5BC15F37E37C6DC4F79679BD63107
+:108DC000FA1E110B3F0FF1F265BBD21B4FC2FDE53E
+:108DD000CC9D4674DFF90EA77BEF8B7F71915D9977
+:108DE0006491D10EBDB0B87ED3EB4A783CC0A322CB
+:108DF0001E7DF193B16FA25F9BC9BE20E6F12DCF1E
+:108E0000E1DF61EAE59FD7FCE3195547DA6686C5DD
+:108E10004F9B06F96E9A0BFA4B4649A105F5878CD4
+:108E2000AA97A87ED19249FDE291AFEA98611CFC15
+:108E30009E1DDAB7BEAA97E97D5FFA8E45F1F37CF5
+:108E4000B86ABB42FE5FD3F76E7D98CF867C3E9DAD
+:108E5000CB9B5A89CB273815265EC7485909DF971F
+:108E600045E17CFDE2547E4F820117427EA58F676B
+:108E7000968FBA1C70AA5C7FF4559BF2EF4CE36F9F
+:108E8000F7FAEE990B7425381B789E5D8ED6EE307E
+:108E9000D74BD91C26A35C867D46CCBBAC9BABD9FB
+:108EA000997DE47B31DD0E2C7EF55DE4875FD90E84
+:108EB000EC63DCE9A9A1A591EE23EDCED3F4F1A8F2
+:108EC000D030E4C31D5264BDFDF6E2593BE6F6A383
+:108ED000D7629E6A78DE44AF7D7FCD3CD5DF7AB81D
+:108EE000FF4B8F3FEAF9AACC1A188FDFCFCC74FE64
+:108EF000FA668A2BF691A7BAC9E50EA1BFAAB62CCD
+:108F00008ABEF7F875FDD56734BFFB037319F78781
+:108F10009BFCF5E6751FD1FCD797BCDE20E24B5FCA
+:108F20007E7ABDFDBBC991FD64C9F3F5FBF3DAFDA3
+:108F30001F0FD7FB54C9CD22D9057A7EA2F93DD89F
+:108F400041EDB80EBD5C569F417EB65689E32DE5D6
+:108F5000740CE9C96775A2FE477A5433D5C75670B9
+:108F60007D50D7B3642D4E60A627A08FD3441F2514
+:108F70003CEED0A3276AF4B108E803E87228E37452
+:108F80006CD1F230873A784AF7D7D5A37ADB4D1EF9
+:108F900047A4BCD3CBDA4DF5931C643739C7BF8ADD
+:108FA0007A556715BFBFD6E1EA7261DE8AFF6D911F
+:108FB000BE67DB577FDD7E12E71BEDA76525DCCEA4
+:108FC0005956A2DB4F21C9E742BF30D84FE487F59D
+:108FD000D9F307F6B6A3305F14CF09EC4C47FE3740
+:108FE000C11F4C7EA263985700EB3C32E23CF93F34
+:108FF000065771FFC7E02AEEFF4841FF471AFA37CC
+:10900000B8BD56EBE6FE0CDD7EABD3F2BC747FC878
+:10901000551A1E8CB157727F88664FD51EEF22FB02
+:10902000C9A97DCF06E3758847B66A21802E4226FE
+:109030005ECA453DD83E983E6FCA58B5D10F62CE44
+:1090400043769AFC1DE6BC816BF3353B4AF37F3CCB
+:109050002228F74D83799EDD91FB3AA2ED7FEE5AEF
+:109060001983FE8F9F06EAE76AFE8F87F0BEC5A1CF
+:1090700077B9FFA3EE10F74BFB5081B92E12FEF526
+:109080008AFB90FF6365BE9FFC1FBA3F6999533B03
+:109090007727DF2FC297BEE7E9E165F4432804CFC5
+:1090A0004F7E8971C2BA6B782EB89D6511FCF4FBB6
+:1090B000AD3AFC772619E1ADFB9FC6D803AFE1FAC4
+:1090C0003B92AD6C23CA51F1138AD7889A1FFA9B41
+:1090D000F22BDD9C6FF42B8D7F68C276FC0EEFC403
+:1090E000878B4EE273F2EE750937C373EAFEED45E6
+:1090F000F864AF7238FE751EE75B98311DCEB796E7
+:10910000E729C44F7BE0CAFD4A3A3EF6F8E378BC53
+:10911000BBB482913FAE54ADA43B8C98E78DF8A3CD
+:10912000C3A7D5849FB5C3783965666510EDDE0C9D
+:1091300080A72AF7C6D7D6E36D6B89EFADB6297E37
+:1091400082DFA51AF4D3D9357BDF8C8F197EE3FD3E
+:10915000E1CBE1638D096ECFEC98701FC2EBB95D76
+:1091600045AFE3F3F9C0BA1884D7C17DDBE7F60158
+:10917000B764431E3FC26D526F7C3C5EE06BCE878E
+:10918000F7D3DD012BF1DB0A8CD961DEDBDA286352
+:109190005C45E7933F8AFA5A7C72F379BAD7585BF9
+:1091A0007D81FC4A7555FCBB101D2EB571E4C42BA6
+:1091B000E793D7CEE3F7D8753E99A2F99952E41018
+:1091C000D1E332A047CCFF5C56CDE30A78CC310026
+:1091D0000F31890563C87FE0207ADA89F9C3D7F6B1
+:1091E000E04F27B4B30F60BDE49399BF825C7C1E4F
+:1091F000E1D5599D407ED93DDAF74555AB9BECC78B
+:10920000D9C5DE8358AFC7A5B67BD543C487BFBEDB
+:10921000BFF0487E98BFB0238E75FBD76A601F39B8
+:1092200055590CE34BA2DC2529E85FABDE2DA09C51
+:10923000583A87D349CAD04A9217BDFD6D5D396847
+:109240002F74E04DF12CC283B771DD1D557B090FE2
+:10925000AE5DCDFD241D55171222E3C1DF5C5FCF4B
+:10926000CF389EF2837579B9B31B0F02AF4DF90A5F
+:10927000F272FE3CA3BC4CD1E83EA5FAF443E89759
+:1092800016353C109DDC2F8DFC13F160701FFE47DE
+:109290001D0FEA1056801775B239AEC8EFE55EA80B
+:1092A000DE4B7FBEA5AFF55D3E2F548BAF633C9187
+:1092B000C7D7DF453CB556F17862C7FAD964275E57
+:1092C000A81664F437EFA9BE5DC0F39B5D1210428F
+:1092D000CEF0797AE5833AE60DEC891FEAF1C2E334
+:1092E00005DE687C3F1D702A291EFD7F9A1F7D6860
+:1092F00064FF1FE077FC3CD43F0FCB244F743F3A10
+:109300009374FC561370BC71B6AE6132E1B72F098D
+:10931000DB771EFA2FCA0BE8F113F23CB37FD8CFEC
+:10932000556AF473ED5C6ADB43DFD763A15C8A8F17
+:10933000601C01F9F6363BE533960B0AE5FFFDB5F7
+:10934000C03796F6C1BC9467EA2B76C8E40F734D1C
+:109350004E42FC286D10496EF7659FF4A6B3D3C446
+:109360005F5200AF347E437044391D158774271057
+:109370007F1181BFC4A01C44BA1B1BCE5F024B8867
+:10938000BF328B3B36F58AF84C0EC2B91F3E933B79
+:10939000CFC86766CDFB07E212C17CC6ED3A6DDF30
+:1093A000A87FD2BE357AEADE77099733A287EFBB72
+:1093B0005B2FD5F88C998ECCFBFA7F90AED6F54119
+:1093C000577722BCBF025DDD7319BABA17EBC3E849
+:1093D000AA96CEFF5F8FAE5AAF84AEC6CE63C6FCF0
+:1093E00063ED3BCA63BE63E1F98BFF97F38F13E72D
+:1093F00072FBDC9C7F8CF92258CE87B3A1F3D1CAD3
+:10940000F3273205EFA7D977BFB465B4C2C70BF70E
+:109410007B3293BF9399FC9B66FD2E823FD4E0FF85
+:109420003CFEC4EF8E8F865F7FFCE47F915EFBC6BF
+:109430002C81E28FF3477D7118F5FD82CD6BB53C31
+:10944000F7FEFD9FFF6C7F27FE84FB57CDFBDA14F0
+:1094500073BF068FAFE6EF64EE1AFA7E7867257366
+:1094600013DC2FE3FFEC94471AF285BD2F963FB82B
+:1094700010FD9FC7F977F8CC7E4F3D0FB8B5643922
+:10948000E9F96754875B8CE0F75C9EA0DC46FEDC64
+:10949000DE7ECFBF221DFCA37ECF657315C243B312
+:1094A000FFB318D8D5FC7EE2BE1D719502F2BB9CBD
+:1094B0001237E5DBB14BEBE8EF39882521D2034BBE
+:1094C000ABB81E38A0C0E7C2715286B27107D13E58
+:1094D000A912DC16A5375F063D33767E785EC93764
+:1094E000EC2FF867F9FB5E99FBD5EEA5BF82F09EE5
+:1094F000D4CFFD7425F430E6AD3D52E3A2EF563DE6
+:10950000A2E9D11D929A84DF397F2BEE030BF2EF93
+:10951000408B85E1BD31B35EDCF7FEB8FCEACBCF12
+:1095200024A17D34B6C73EAAEDF623B91DE17EA481
+:10953000FA0D9E43E722C049D78BB7CD37DA47A54E
+:1095400025DC9E2D2D51C98F549AE861387E8A936F
+:10955000B5A15C1493BA24D4539655F8C8BE37C746
+:10956000E1CD78628ECB9BE3F0E638FDFFAF71F979
+:10957000F5F38DDF651CA7E5A1206FC7EFE998E340
+:10958000F09BADDC4ED9A9C23BDCCC578CCB5F75D0
+:10959000E9011EE757B9BF3499713D2D259FFB4B5B
+:1095A000CD7AC723526033DADD8FD458F4EF5618E2
+:1095B000E2FA635D3C3F7ADCFC05FB293F47D70BB1
+:1095C0002B402F14482FA4EF1C9556540A1CAFAA09
+:1095D0008EE03DD36532C7ABF9F339DD5887BA4920
+:1095E0000F16AB6F67FCDE959FDE97A6F2FB60D18E
+:1095F0008867D054CCE4715FF984E8C6FB095BB19D
+:10960000E934BC0FCAB81F679A85FEBE438B5099D8
+:109610008CFCF80141A627E84A748FF0C93875D050
+:1096200012F2DF58C86F7F2CB72109D7D758B32D56
+:1096300009F336DB34BFF8B6DC0FE8FB0EE2582640
+:10964000A39E02CF887FCFF39E0582F67781DA92C0
+:10965000E8FB02AC99F44931D3C6F8DFCF71075764
+:10966000201E9D73929EF08010E0F76E5C0EBADFB4
+:10967000D67CB52DB91CD6D3E4B291165177F5AC92
+:109680001369F0BE69A01C8B7180BAB474D94F7194
+:10969000EA865791BE9BD2D219E6CF37964CA67B6D
+:1096A000748D9780B140CFDAD123DF9A04EF370B66
+:1096B00021FA0E8F7F9A85E2F02D57CF4A0EBFE731
+:1096C00028CA3653DC93EB95A262A17B73A216CF16
+:1096D000167BC5B38DF1E9AB1670BD4861CD8BE942
+:1096E0005EA5D326E37E4BAF1E4F79AF179D36CADA
+:1096F000072A9518FF8EC6D58CCE2502BF337C571E
+:109700004532AD6F3306A629FFF98155A887E31DC1
+:10971000409E9F5FC3CBDDF5DF5B85F8431FDB8198
+:10972000F2D937EF5A85F9F80AE37FF7A33693E7C2
+:109730004F96BA0A89FF964AA188DFCDBDDC7A141C
+:109740001650B5F1D8FFE6789BAFB62DC67B44978F
+:109750001BAFE75C02C4BFBFEAB87A3BF3B8E67E52
+:10976000FF5BEDFBDAA76581FEBD43467910A41AC5
+:109770006AF7C3503FB66AFCB0367B7220A8603EE1
+:10978000AF9FD3459C2562BE6CDFF411363E4FCEB1
+:10979000257E4BE3E3B75CAAF2826913F9FBC2A40E
+:1097A0001EBAE9CEBFD0C683AA97514E6CD2F90536
+:1097B000560DEA19F7372513280F16EC0B25C11D96
+:1097C00081FEB43C0D6A9F46F7647F8B79E26C346E
+:1097D000233EA2B7B76AF39AF336B66BF37ED5BCD5
+:1097E0008D73B88789246BC80EACFB6D33E52F31C0
+:1097F000FCB813FA67B364BA5F769F10A07B91FE42
+:10980000951CBEFA3944B1EE1FB27BF47C9848F93E
+:109810003268BF25E9ADC3CF219DCE7204EAED9B2E
+:10982000478DA3BF136965CD8F3F01CF1D0736FE5E
+:1098300011F33EA2478CBB7FEA44BCC76E71E3F2D2
+:109840009CFFB6E36FA80A378C5DD98CC3ACD822D5
+:10985000A8E8D7B7CBCE3D681F318740768375FB2C
+:1098600060E20B49E5C6736F15D45FE377F4FC5BE8
+:1098700005E2A3516EA35D611B6A6CBF4EA33BB3AF
+:109880007DF2801039EEFDCC022E67AC686F84E962
+:109890000DDB2485BE0BBB6DB388914CB66DBD9DB1
+:1098A000F8D9CB6F15AEC2EF76DF592F11DC5B6FA5
+:1098B000B0D1DF8B6A75C98B16635993677A9CF9AF
+:1098C000816B4606C2FFAED0D39A9C6DBEC146F2F4
+:1098D0008059BB92D02F6BBE6FDDCBBE32E1DDE590
+:1098E000F02C7741BC86DF01922BDD76FD280BBF83
+:1098F000573CCAF22F71AF786E373D7CB3F78AE7D9
+:10990000A2613EB027DFCFDA2BBF2795FC7BF5B3F2
+:109910006DF4FDB5AF6AEF6E5BBF8AE485FF76E656
+:10992000CE70F7CE0BF3BE3882F0476C14C90F2708
+:109930009AECD9FDF3A56EFEE308E3937A5ED07648
+:10994000ED9EEE766F03E5CFD479F83DDDA8E655C0
+:1099500064276F033D0CF3AA74BBF8CCD4F4C9029E
+:10996000E5FDA87EFC4EC6996C2D2F48367E4789B2
+:1099700069F97DFA7CDBA6A6D37C756887F7830737
+:10998000568F766FD7345E37BF467B3BECEF6982EC
+:10999000BD7D6E01C0FF7EA71B9D7050FF12D5B329
+:1099A00089F15774AFB2137F85761945EAC7384EEF
+:1099B0005EC6243FDA7967D80086F038E772CF4276
+:1099C000B5BB43723BC2FFFE416DB3A47D8F02E67F
+:1099D0001D4BF96D4B0B11EF4748C43FC4C42C7AA3
+:1099E0005FEEF25A2DB02EC19B6E884FE6B116EB9A
+:1099F0005AB2AB023329FE5DCE648CB794B99A2972
+:109A0000CE928B0B8489672B33C8CEF31CE6DF59CB
+:109A10009C1EF7FD449443FF0700378FAE00800083
+:109A2000000000001F8B080000000000000BAD3B91
+:109A30006B705BD599DFD5BDBA926C49BEB2652318
+:109A40001313AEED189CC43137217165089BEB47A9
+:109A5000880D29556CC749769C548140C3B4D36A9C
+:109A60005BBA4D76682DC772E2386014D3D661CBED
+:109A7000B622C0B6BB74C0A52FC8D08E1CB29467E6
+:109A8000715BDAC2B643454ABDA5D31FEE23E0EEB3
+:109A90006427FB7DDFB93796642571D28881C3B90D
+:109AA000E79CEF9CF3BD1FC78DC78E54451B00205C
+:109AB0006EFEB4BE092000E2B7DC3515695B0D30DF
+:109AC000F89A6CECE32FDA643408A084641831004F
+:109AD000A4A7D686325EEC7BA77F0D7E809B6600B6
+:109AE000DADD62ED19FC77DDAC1BDAEBE7FA2D0865
+:109AF00039BBDFE6AECC99BF5EABCE1997C134D28D
+:109B000012C086D0D29C79BE35AB353A6FA7BE3233
+:109B1000E7FBADF5CD39EBA15D3999C1FE5AFCE704
+:109B20004C0DC1137D1EAF06F036603F6BBD025970
+:109B30007D1CAF8BF882D3C5D8F9107CE88C0CB0B3
+:109B4000118CAD10A45187F138E2A5E2983B53EC9B
+:109B5000C0AE69EAC10AC4070DE9007D115CBC060C
+:109B6000FBDE6907E0BC8711865C09D0A8651C9FF5
+:109B7000263C6B13127F0798184164871493E741C2
+:109B800008B404CE5B047149C3BE2F0449EA5F05E3
+:109B9000499E8FBFE483CD004BDC62BDBF0B8C07B9
+:109BA00070BCB8212E49D82FED004346785E634A39
+:109BB000A2736AB85E5E09500969EE5775C0D42079
+:109BC000C337F7D1FACA3DA00D5512D8388FA7FA7E
+:109BD000204EE779040C70C9848F08402D800A312B
+:109BE0006EAF06BD1491088F82B18AFA759021A4D8
+:109BF00022555312F5AF80098DFA006988ACC02652
+:109C0000A304A6DD3C05CEACC37FE957A0A59DA665
+:109C10006DBAE0E4AFDC667647107FBDDBD69444D6
+:109C2000BDE75EA7EC797EA2FDFAB9FE6804915FFC
+:109C30004EDF37003450FB028F3F1589EC88E0F788
+:109C40004684EF5E75F1F86F54053E131218719C4F
+:109C50009F78F696D04E1C8F3FEB36EA80F08BF85B
+:109C600024BE08BB675E6A16EB891E41A407E1BBF0
+:109C7000B40124C2C1554407FCAE221D0E321D930F
+:109C80000C77710C8C016B5FEA57221D882E29D04E
+:109C90008A08AF72ECE2E8C03F8473C533EE4746F2
+:109CA00024C22ED2A5F6B2D0653FE1F162E9924F0F
+:109CB0000FB8B70CA0F97CFBC6998E5F91D21EA994
+:109CC00096C882F4C1FB48481FC26708043D54008F
+:109CD00083F05408FFD4F7AC067D1FF7C57CA2675C
+:109CE000BC798EFF4B90FF455FC85700E920FA8290
+:109CF0004E419217EC872213BCBE741744EEAF247A
+:109D00007A988C3C2744B975C18C446D8D6430BD04
+:109D10006AE58883FAC5525A20192949FAC00F1AF0
+:109D2000D3E74A88711B74CE4C9EC17D125E472AD0
+:109D30005E4DEDD32DB4CFE046D43028B70DBEB183
+:109D400016E6CBBB41AB43BE5BAC9AEE6AE29765CD
+:109D50008A11D7B3F1B58FE1836E1E29A671870FE3
+:109D60004656CFED9B701AA124D2EB75DFF4F12893
+:109D70007E2FAA94C165CCE1F9A453DC8F60CA8B15
+:109D8000481E847C84C27896C07CFD165204DF7A1B
+:109D90007723FE101F3B6800F1240D7F9FBF3FDC3F
+:109DA00026F4DD8391E8EB24C7A49F187F2668A4DE
+:109DB0009F3403586F3AF4F8EF64FC7E6AD8A51319
+:109DC0009F4272DC74E33E3BAD7D760EBBDE91FCC0
+:109DD00059F74CB8206DEBE71A5A1F29617E3624DB
+:109DE00070372D7CDDA5F23FEC292766BB20DFB65E
+:109DF0003CB5B624D370EE792AC94759F63A4127C3
+:109E00003588FCE4A5F11778FC42709C7B2673E44E
+:109E1000CC86E30C45188E73CF09216F64B7909EF2
+:109E200077A1DD1A417C7FD4D454C19733FF45F626
+:109E3000FCF698DF207BCE28C2797724A5D408F2DF
+:109E4000E39D1053894F25581227FAED884BC60819
+:109E50004EA939B8CBCFFE02B46B841F297DA37CF9
+:109E600066F945E0D1C2D38EF47B4EDD4778F5C16B
+:109E70006FEDF19AB9F1BFF4D5BEBE4627A5EDADA1
+:109E800027FA165BF445B51D7F05CFE93C5D02233B
+:109E90001A727FF1175E5B87E71BFA996CC8D5349D
+:109EA0004F0513E11581B0E3C524A7B5C42F13E90D
+:109EB0008F13BFED29D1E8BEF63CB0E6C5216AD2CA
+:109EC0003D8B510F105C47F17DCC9FC57E55979916
+:109ED000F951E364DFC38D7C57C1A8E65FB99A4EA0
+:109EE000937C95B7BA8D815CF8D2195A8F30A1C294
+:109EF000BA87347FFF15D477F350CB196B3FD39DCE
+:109F0000B55F5EDF19CAEA83188F67CF3754486799
+:109F1000E1F5ACBC5872669FDBEB5573E5256F9D90
+:109F20004D8F06A7E08F4008520378DEE1E1D2961C
+:109F300062EC8F064077E1D0FE1B2A2440B96ED533
+:109F4000C43C7F15A45C12EDA38FD4B3DFE865FE9B
+:109F5000F1FFDE4C7F9CF831ECD274C453E08FC625
+:109F60009489FD3B436EC3C4F1419A4FF6B50AFD97
+:109F70002C9DB7FF05F9A57758E7BD82708372F86D
+:109F8000B14DC2CF927DABF7BF82F00F5C29834CFD
+:109F90007BCB1B0DE2CF3B1480B252ECDFE764BFFA
+:109FA0000FFD3BBE8F5A95EBF7DD79C439E717C239
+:109FB0007C3FF0AE4DB97E606C13F0BE749EB2551E
+:109FC0007F3F7CE80BB2FE5CA14C39B40276D5C66B
+:109FD000BFF49497F1FA8372C42BAD8388F929EC0E
+:109FE000BB108FC4AFA8A8FD6B104F84439213DF42
+:109FF0009AEF7C9AE6BB4E21FFD27CD9DBFE29DCAE
+:10A00000CAB908F1C4FADFC9E730F11F3A77BE3F99
+:10A01000ECCA3BA733CF7F962D3A8C107E50FEA121
+:10A02000099A083FE89FB37F00DE60413BFF5C3F39
+:10A030006A0EE4A51FF6BBB94DF76BDC1EEF0F717E
+:10A040007BA25F877674AC5EE8AFE7F6C57E83BF20
+:10A05000BFDC1FE6D6C6C7B9F48DAFDCC1FEC2E1D6
+:10A060007B1D291226A5417BE95AC4C3956FC8AC54
+:10A070003EFCA07B14D4077EC48182F3AEEE505226
+:10A0800026DDC58A7FAEB0F86CB96B66D245FC5D43
+:10A0900009C63E5A08B1813B56CFC53F37CD38E699
+:10A0A000E40428DE299AB33340F14E594EBFCDBDAA
+:10A0B0002867FE7AAD3667DCA6EFD79A85DC6C0898
+:10A0C0002DCF997FB8BD35FD313CAFBFD9A5119FCC
+:10A0D00077EAD7E78CDF5A7F630E3C5B0E4AFB942E
+:10A0E0001CFEF3E7D155DD7DFE38C8A6F38F6C3A30
+:10A0F0005B72702EFAE6F3AD8DD7D2B37815716529
+:10A1000082E24A9DEEDD20ED0C129E6DBFC4848874
+:10A110008FF480D85709637CD978F9E34B3FC59712
+:10A12000D585E2CB7735E2DF0BC6971DB9F1653EE9
+:10A130005E2F145FFE691E3E4B1784CF1D8B63AFED
+:10A14000ADA178EF5599FD40B923C6F6AF6C4A36FC
+:10A150003620DC72CB1FF391CCE3BC1D6B54F62F81
+:10A160000F43264476FF0109B18AFC5FD660549202
+:10A17000BE793260566CA338BFD3611CC525CFB7FA
+:10A180007C39447EC7C1814742689420D8E5607D10
+:10A19000976C99DE4E72A5E8E8C749DC9AA902FEE1
+:10A1A000893DFFB3434E8E431ED8AEA6249CFF804C
+:10A1B0004FEBDD4A7D6B1F4408DBDBF135D7A4C8CC
+:10A1C000FF2BEFD205BF403C44F47F707B53251B2F
+:10A1D0002905FB2B68BAC1767CC46798248789DF80
+:10A1E00079218E9FEE9734BF44FEEB7687F638DEFA
+:10A1F00073BC63D55BBBB07FD0AB1A24F0894053EE
+:10A2000025F197BC03DD1EEC8F758CBDC8725CE731
+:10A21000E07E62FB35AF93FB3C5EAE75D6509CB7DB
+:10A22000BE86300DF233A7FB29AF91084C8768FD3D
+:10A23000E00D62FDB9E8236B59F61C387FC1E79544
+:10A240009738D22AC2919F9BFE3F822767DB71D647
+:10A25000E3B97EC54840A52001CCAE2BFF23BE84C8
+:10A2600054B969121DC751E6094F3BB67795503C6A
+:10A27000B5C399292F642F8650BFA6AFCDF237837F
+:10A28000B97E423E7CFE35117EF1E7105DBDC20A0B
+:10A290005DF097B8EDE6549AF006C98E1AB2CB5E1F
+:10A2A000B4CB709EF8CF9B8B071B3EC3C3FFC87B0C
+:10A2B0003CA6270B0F78AD34F93BBD5D12F3CD966C
+:10A2C000B37C001C77D8E7523A1CBCCED60FC8C767
+:10A2D0005B27883F2CBC87D064901CDAE7885AF053
+:10A2E00076CEC103AD22EB1C6B550B9EC171F1758F
+:10A2F000AA902BF885CC7EC73C3A59FE1BAFAF9E87
+:10A300001B57ACF35F7B44CDD1BF9FA1FD71DF5FD5
+:10A31000F6759F375E5E9ACA5D77B80BF8DCCB6442
+:10A32000F3F834C5B5D73A528F23A8E5D73A589EEB
+:10A330004FA15F4576ED5CF06CFAB388553077A19C
+:10A34000D38EFE59B08BF9FC5CEBD4D49459DD4824
+:10A35000FB426C02F96B6928F75CF6BCC367EFF54A
+:10A360001928A2F3A0434EF6C8954A9BA4A75D08FE
+:10A3700047C2B6FE917BB4F3DDDB0559F0119FEFC8
+:10A380004A425FC503C0F74DBC9562F98167667E9E
+:10A390004BF29D585AA18FB0BC40684913F923E293
+:10A3A0005ECE3C3A8D78049CB195C24F1DB3FAF154
+:10A3B00015022E64CB29AEF7587995AF77D5F2BD4B
+:10A3C00054D2334464C55C4C7CE155BE15D7901F14
+:10A3D0008ABC872180AD2BB8334EEDBAC5FA681818
+:10A3E000CF35B6D4C1766CCC177D6488F4D0526F6B
+:10A3F00041F9F81EE945843F4C7CCBF113980E924D
+:10A400003BC91612883A905EE3CCF9002F750544DB
+:10A410003E4B4B866F473C1EB7F802EFC3EBF3E1B0
+:10A420009F980FFF31E2D784059CE0EC44382F5B06
+:10A43000720164502AACB80FF773EBC930F90BAF57
+:10A440007469425E949506DD7F2C5078BF57ACFD51
+:10A450004C474CA27957F489F5E016EB1E9066B68E
+:10A460009E14F46479A2FD69BCD8C8D50FF9703D7B
+:10A47000F5B9FA4AADCA9DFF96C57FF9F1D0FD52F4
+:10A48000E173FEAF75DF758B81ED11F1C5BE027C06
+:10A49000912FEF2AE53F11EE7B4407C697D03B5E34
+:10A4A00065AA95E21E6F0318ECA328937CDF7DC597
+:10A4B000B7719C3C74ABC873A88AD0DB555B110C98
+:10A4C000DAE3C80FDAE3D497EF01CD15988F878BC5
+:10A4D0008DF7C8DEC4B3D69F26FE2817F78867DD40
+:10A4E00023E9D46FA37D930765203F20B9D7B5B585
+:10A4F00090DD862EE7593DE9B6F52ED20D8C6A70B7
+:10A50000E0FA236FC89C173812DECF717122A2EADD
+:10A510005235E5291E86BD38FE17D3C17EEB9E67F6
+:10A52000EEFDCDCBB8EC647B4D93E46039823B719A
+:10A53000FE498C8BC96F26F9CBC9C72062DD4D73EC
+:10A54000FB25DB6B78BF04EE279D47CF29118C5B81
+:10A550001BE7C33B6B8FF3F223231551BD1BEF7732
+:10A56000D86B703E52B6F3233DC105E5757448A61D
+:10A57000F7905EE903C683AF730CF6523E2124E2E6
+:10A580008CE36B5C82BFF64A567C06ED60EB29FCDF
+:10A590006DECD31F2A23FBF2A60BEA70BCF589579A
+:10A5A00015EA8F553A9A287EBE4ECD1CBA8EC69BB0
+:10A5B0009CAC3F5A9092E91CFE48BB1C213E8F6A1E
+:10A5C000B5B268D312B56DEEE21C7DBD5ECB8D3F9A
+:10A5D00046678FCB25C49F1A1812E279B4C5304B59
+:10A5E00048F7189941FA3EBA5E374674F28773E32A
+:10A5F00094D14E55E8D36A6177C626F587C8BF3A2D
+:10A60000B0C7C3FEE7FD550E71EF2590227EE8D45A
+:10A6100073E39AB1899A834B48CE924ECE977F735B
+:10A6200042CCDF35B0324571A966F9ABBB2A5BD9A4
+:10A630000F852131EFD6FAE579F79FD2882F927BEB
+:10A640009D40F83F5075FB30E543DF4938AF277137
+:10A65000F96EB7CE726AD36DE7D09D5C271A52614E
+:10A660001B9D7F74BBCAFC3F5AFECE913B484F975F
+:10A6700017319EC7B7AB95D12C7978AFDBC570C6C3
+:10A68000B70BFFA2DC01D18902E3EF750BBDF2E14C
+:10A69000BB81EF43F90E1D3FE94A2CED227C5401AA
+:10A6A000FC2B5D27F4EE97F8FE1D0EA8C3238E0544
+:10A6B000FBD87FCBE7B30FBAEB72CEEF0A3B72F059
+:10A6C000E87445629CE7BE1574D257ED1DD8A7F813
+:10A6D000BE4F05E23757E81EBE6729F63DD87777AB
+:10A6E00024E30AF6DD4BA2D793DFFAFCDE2DC32D5F
+:10A6F00041B25F0E8DF8CDD57757A49BE6AF768239
+:10A7000007C78740974274CEB804A4AF7588769087
+:10A71000BF3E16726894B7D998D8BC9BF6DF182C48
+:10A7200002A2F38E4E07EF77CA543969554E8E0652
+:10A73000E5BF2ABC6C77DF76C61EDA82F3DF467A85
+:10A74000C561EE5E8F76D7F03D3D7A6EFCEC8624D7
+:10A75000DBE1B5E6541FEDB336AC5245038E374FFF
+:10A760001F217F7D7C8DCB70E1B9C69B25C6F7FB91
+:10A770006B9C293C2AFC509D9269DF1FBE8FBC5107
+:10A780005D487ECF2F37F9F347C35D6EE287FD301A
+:10A79000D543F889CF8A3C54FEBC253D82FEFB118F
+:10A7A0002F84E7389EB78EE2A219942B841E988DD1
+:10A7B0007C837244DBBA15D61F9FAD74C4A92E7476
+:10A7C000A053653939E08B0E57531FF99DE3A16003
+:10A7D00094F979AC32C87268EF33D6DC5B4FFCF287
+:10A7E000DA1A0FFBED7D3FFBD5DDE4B7B7CA7FFC7E
+:10A7F000F653143F55A94CCF03CE48FA65E2EB4E11
+:10A80000E12F9EB8EA9F59EE86FA6E07C21BC46319
+:10A810006F52DD6A687533C3B7F30D6357897CD215
+:10A8200050F0D3F15DD84F87457EC12C3F2A01EB14
+:10A830006791576AB1F4D87257ECA53A5A77B722A4
+:10A84000EAC2725582F4816B91C8BF998A3327EEB0
+:10A85000BD6926370EBE322F0ECECF33817B6A49BB
+:10A8600037DAD39F775B79372BAF445760395EED8A
+:10A87000E278713C2CE2A0A43356A935CC97E31FB3
+:10A880005B7EF054BF1B3900E0A7FD1AF7FDE69F81
+:10A8900006CA10D41BFD21FEFE91B58F48D9EB46A8
+:10A8A000576F76EBAC373221829BAF2FF2F9E08EF7
+:10A8B000EE22E6038CD380E83B3A038C5F5FF3AA79
+:10A8C00034F1E9A9BF02C7A1FFD03EE5859AF9EBB3
+:10A8D000D3744E17E5BFC4394FD0395D94FF12E7EA
+:10A8E0007BB15FE7F6E5FE7A6E57F680C8F3DBFAD8
+:10A8F000E06AD40788B7F62AD127F9273B5C1ABC4F
+:10A900003D42FCE50A291AC9B7BB2A9996B2F4C19F
+:10A91000B82FF616D9E503E55EE6BFFC73057A1C91
+:10A92000D6BD62DB08EE28C225BC3FBFF77FBE5410
+:10A930004BFBBC21335F95F6F5EE66BD837AC1C350
+:10A94000FE86D087C9722FE71DC6F7D64921ECEFE6
+:10A9500018108EEE05E51EF749E1BAE3A8AFA97F0E
+:10A9600000E59CEE73A0F99D8FD33EEFFFAD882AE2
+:10A970007C48EF5FB0DCBF860148D965947B5BCE35
+:10A98000BEDFFDA4157F47B63C23EECF7A70DC37DF
+:10A9900095A4FB1FF8B90C85F076A9740573617E48
+:10A9A000484A99993C132C50373445DD7070E23B8E
+:10A9B000DC8F6F04A8C3FE579DA69BF8E0AB038E07
+:10A9C000F3D60DBF3A70FEBA61EA8B0E706973E779
+:10A9D000580419CEB352084F75C0211AC2B6A92720
+:10A9E0007A5B0FFBCBA2AEA83753CE81FA5A11F98E
+:10A9F000CF4F45CC8FF4909F1914F9AE9032912629
+:10AA0000BB1EA27AB94EEF17E25CF7D4280C5B3973
+:10AA1000FFFE83CE4C2BDF0FA750BD32BF3E2979FE
+:10AA2000BF27EAFBB5A20E69D7271BD5CCD143843B
+:10AA3000A76D6EC6C3E0B337BC49F52FBB8E1FB2FE
+:10AA4000EAC0DA6ED006C43D3EC6E77C4ED443E190
+:10AA500006BCC74ADA2453B36905D7373F41E31729
+:10AA60003AFF42EB861B2DFD86CC9D2279FE8D851B
+:10AA70004F7BDE80258FD7A9226F0D7E95F57CEB6D
+:10AA8000135E90C95FF6A947494E7642663DC9D329
+:10AA90006040F86D89C34EF6DBF6F5E8BCBE5C3568
+:10AAA000F9FD42F9BF788C01049398D4FC9447AA2D
+:10AAB000EB36F7F5F039923D5D748E6199F5DDDB8B
+:10AAC00075EBE3C41F9D5209CBA3A2998BB3F5E5A7
+:10AAD000A33D3539F9F84EF8A242EF5CD62D9EE938
+:10AAE000E2FD7D0EA0782BE1315ED409DF3F5018E6
+:10AAF0006E27A4DAF9BEBB346918EF39E83DC9F412
+:10AB00005957E75A49FAE951CBBE267C85E3BA7F0B
+:10AB1000EB11F1E7FA4DD187E9DCB7C04C1BE937FF
+:10AB2000146D23CEEF5A445EE751D29722AEB9D7C7
+:10AB3000D13497D77AC9197D94D699DF14FE842B26
+:10AB400024FC7A279869C2D7AB9BCCC7888F371271
+:10AB50009FAF6645058FAF9C7F8E27AC73F4F69848
+:10AB6000FF49F08E59FAB95133B9EEDA080E633065
+:10AB7000985557D717565797B4EF897AFA8D828F21
+:10AB8000E1B9B8E0C356D0489E90FF8ED1F9ECF7FA
+:10AB9000258DC7765773DDE512EBDBEF6F328F1330
+:10ABA000BC3F442227E81E6FEFDD020C6F81EF35BA
+:10ABB000D62DCE8422642F3DC26F7EB2C5D81AC96D
+:10ABC000CAFF9CB2F8F79445D7E5C84E53942F506E
+:10ABD0000CB6E3D740D84DFA211F7EA21F26A8EE5F
+:10ABE00073AEFD9D074FBA294F3C186E75D37BB4E9
+:10ABF00084B7B584FAA3556688F61FEAEF78F6DDC8
+:10AC00003AE223C1F7F166918FD88FFA39EE9A8331
+:10AC1000F3871E99CFD5168634E5D3FD5EE117F98B
+:10AC2000315ED4918FFCC130DB73FC3E41A9833F80
+:10AC3000933C51BC1D32C0A478321C05920BBF3628
+:10AC4000B79E4C5E5B380374AE73C191AB70BD9719
+:10AC5000D6C718DFE59B353E872BE4988BE361E18F
+:10AC6000F8DA4FF8AA3B4FDE8DF0D5706E7C9DC5AB
+:10AC7000BB2577F978F26D96F9DECF07A6F95E70FD
+:10AC8000BA8DF3227E547854CF2FDB2CF48CEC3524
+:10AC900021EAA37A5994EF970864C06898C32FFA01
+:10ACA0008A8C5F59CBF03A7FD880E80AC2478CF192
+:10ACB000997FFFC663DF6827BCBDB453E8D5758AAA
+:10ACC000A53F627817E4CF7FB2F41B5876A9D3234F
+:10ACD000ECCE46F88957E4B5059F36A23BEE2E9D93
+:10ACE000AF5FEDF6492BAF9CFFFDE79B3D220FA028
+:10ACF0004FB07E1FEC10F07D3EE1871E1D5EC5FE4D
+:10AD0000C3CD957545D9FAF172D709F3EB8217AA2D
+:10AD100003CEF18DC974FF8B7632BE493F377F1C5D
+:10AD2000B2E46DA8DF5D50EE0E2D8E840C92AB6602
+:10AD3000330E48B7FD814C88F86768F23DF693956D
+:10AD4000576583FC4D458900CDBBB93CC3F4DF108A
+:10AD50003681EA4A87FACD6F65C3FDECA668F766CF
+:10AD60007A27A44D9804C70BE938D9A35BCACC58FD
+:10AD7000A4001D3EBA59E4FF5EDD14D9B699F40E65
+:10AD8000E9CE55E86B45CC7FA4FE42F5D57C79EA47
+:10AD90007093BDB87479EA72D3FD46AB22FC4E6B5A
+:10ADA000F42732795873FEA5254FA3CDD3AC276C79
+:10ADB000B9FADCE63CBD13B4F44ED064B9F8FC66D5
+:10ADC000DDCA0347583E9C244FD97A2668EB199375
+:10ADD000E55109DAF264C91FC9137EBFCE39D346E3
+:10ADE0007ECA1088778CF9F235BE299A203A5C57D2
+:10ADF000FEE7EE6A7DEEFDA7AE0B791AADB2F8BDA7
+:10AE0000F969E6FF53C8FFF45878D05B93C3EF7637
+:10AE1000BB7656863492E2A65989DB7F982DE6767A
+:10AE2000DDAC875B73B68CDB96D900B7ADB38BB85E
+:10AE30006D9BADE4B67D16F9FE7AE4FFD96A6E6FBC
+:10AE40009E5DCEED86D9A5DC76CC5ECFF33A675712
+:10AE5000727BCBEC8DDCDE3ADB2CF6A19A5069419B
+:10AE6000FEA772D665E07F234EF5D1A1C9BBDF24D2
+:10AE7000FC383595F328894013D77B9C4A86F9FF27
+:10AE80006858D8870D5E419F7CFE7F7553F4DB8543
+:10AE9000F87FD009CF90CB95EF27A0BFF32CF1B965
+:10AEA000E47DE16F9CFF740A3F07FD8F63CCFF9741
+:10AEB00068FFCFFA9515B97EE56879AE5F39D46C35
+:10AEC000FB95AE14D5C176493ABF137B7F53F4C7C7
+:10AED0009B59FF4676D278B4C7AD913F9508DC1CEC
+:10AEE000F2627FC77E1928DF87FEC514CF43FD407D
+:10AEF0007663A1F29AB6DEF7DAF31BE1A4237611AA
+:10AF0000FEC9DBF4BFCD85E4BEDE734976D4D92615
+:10AF1000E45E13729FA88A0C53BE259127F7B61DD5
+:10AF2000453CE4C8FDFBB6DC5B725C1A14EF3E4A9C
+:10AF300049EE919EA7CFCA7DAE1D55ACF9CE0E51FC
+:10AF4000DF6A0B0ABDAA74087DA168B97614F905F9
+:10AF50007A0BF8137145F04D67DD77CFDA33B2AB7A
+:10AF6000A5C18054825B6B7FCDC489FD26955A961E
+:10AF7000EF7C394A68AB98CF2795362824FF0B968B
+:10AF8000A3806D474CB623F9F36C791A9AEC64BC34
+:10AF9000D8766512EF6D66D9930D9AC003DA93AB3C
+:10AFA0007A0BC8D3BAC5663452E09C2B7A85FFFE73
+:10AFB000CA4D11E12FA29F487E4AC259D80F58D1DD
+:10AFC0002BE856DA9154086FEB758895A11EECE8D2
+:10AFD00048B7510D03E579452FC2BBC9CC0C920C83
+:10AFE0000E7AC782747E94CF463AD7A5CA67D9260F
+:10AFF000AB2EB7A78CFD16BBBD10DFDBFE8ECDFFE1
+:10B00000F9F39EAC36B716C2CB915EE1AF1F1D7E41
+:10B010003A873F924AED2D865E50AF9AC665D1AB16
+:10B020000BF32B26D1CEB15E3DB75FB183E8B050B4
+:10B03000BFE2CEDEB37EC52EA2D3BA06E1571CE92D
+:10B0400085CBEB2FB4D8F1CAA5F90B9FEF3DBFBF5D
+:10B0500030D8ABF3B8827E35E90DBFA5372ED65F69
+:10B0600028E01F1CECE5387A46A6FA1FA2DA10F990
+:10B07000105117453D733FE10DE378F6178E7A05C1
+:10B08000BF988A6D9F220FD078D214FEC2E592033A
+:10B09000F4FB1EEA2D5FB83C2C745EDD636B8733D6
+:10B0A000E4E7802F49EFA607E9BD12C58FBFF689F7
+:10B0B000770400F594F7FF9CBCCC203B375EFC8501
+:10B0C000AFD1FC3D7105E8DDE083FD22FF374AF991
+:10B0D000BF6BB1EF8C7D9DC6F70FB8B4A308EF83AB
+:10B0E000227FDC813CF58167718ADE051DB3E4CDEA
+:10B0F00005DB4B0AF1D5DCF9C4FB5C7ABA7286FF3A
+:10B10000AEA34AE33CB98D1F350271843FB2C2C180
+:10B11000F591910F7FF3C8ED74EE0FBB0DAA3F714F
+:10B12000A115FB65CB429C47476F10C25979111995
+:10B130009469CAC70FD31BF5ACFA6B7023C6D159FB
+:10B140007146493892D3D721CAFB1E0E3A18EEA198
+:10B150007611171DF24EB8B502FAE5BEFEDC774A4D
+:10B16000F9ADBCE60D7E273856AF70DDE7FED54B56
+:10B170003A494E0E2EE14A3114D53922A902727C89
+:10B18000DA92631D740FE1D1D3D95552C8AED8ED10
+:10B1900060DE39642D6A92BE2EAA4E46888F8BEAF5
+:10B1A00082523C0B0FBFB4E08F48F1F43A7E8F26F9
+:10B1B000EC04C5BBF44E65A8FC2EAE47BA31DE9F49
+:10B1C000C6EF6EB44BBFC5B6AC428D163A2F6C11AC
+:10B1D000F99011672A42741959AA709D1279AA60D0
+:10B1E000DEEBF796BD2AAA1BE3F3419DC275A7FCCF
+:10B1F00079BFB2E7A949AE631CACFB779DE4EEE0F2
+:10B2000055C0F9EDFFFEE5AE270648BFF4231D9DAE
+:10B21000C4AF1DDC162DFB06E37DB451D1E81EEB57
+:10B22000E5B5035C27DA0806F927F97C50BC62898A
+:10B2300087F39D1D0EF6EFF2F9A20819758AFC340A
+:10B2400025C376C2092FB2DE1C3544DCA463B42AC0
+:10B25000FA825FEC7A53D0E2C7FC7B8D5A72B5DF7D
+:10B26000CAAB97587F8733D6F167AEF78E2E4EB3B1
+:10B270001DB9AF251DA2BAA13FE836285439D01C0C
+:10B28000E1FCF6E84A07FBADF3E0AE147A39FF3C87
+:10B29000CEE3EF09FDA888FC85BF4191C8EE7CC9CB
+:10B2A0003AC70653C8931616FE9BD613030D0F5FBD
+:10B2B000FE869CD2711F69D9EFE34E1C4F6E136F4F
+:10B2C0008B8B54912753CD9B07C8AEFDB8520629EE
+:10B2D0004C82F70983F36D1121DFF6BBEC8A1E3532
+:10B2E00027BE2F81AC3EBF53C9ED83DC77DEF76606
+:10B2F0007B7E7DF7EB27B2E0B56EC9ADB35D68FD2F
+:10B3000007FDBB5F3F817C32669C5FAE6CFA24FB1D
+:10B31000C342FF59FC65F31B8580F428F85CEB1FE2
+:10B320000C440BFA25FBB6083D79217DA4B9A23166
+:10B330005A7FF8A65C387759F2769705C7B558ABAF
+:10B34000E479D63BA7C31ED8FA74817B8D6C517902
+:10B35000FE1C3FDB7EC08B9796875BD123E2876024
+:10B360008D87EC30E2F345D21F7F0DAA7A367F0E2F
+:10B37000F972FD50DB0FF8E9162B0F575E21D1FA59
+:10B38000806EDBF1DC3C41BE1D2F72A6382F5DB410
+:10B3900054B5F50CEB830F7AEF79224EF2933EC849
+:10B3A000FE9E8AFC4BF5BC32328805E804A1DCBF66
+:10B3B00013D9B205183F65FAC4542BDEA32CA27032
+:10B3C0003D4449829126781B8BF8EF3FE877BA8994
+:10B3D000EC1C70509B6CFB24A471FE03B58AC1EF7A
+:10B3E00008C1D9FC2ED9DD2A3FD7516DB9B810BD9F
+:10B3F000ED73D17BB1DC77F017270F8F6DB1DE6570
+:10B400007BC023E461A36388F31D8E14BF85477955
+:10B41000579AAC9202D5FB4908703C48EF8224ABA6
+:10B420008E543B272770ABF56E73B7783FC37F5FB1
+:10B43000584B7F0F9AE1BF1BBC9A5EB7CA82AE24FD
+:10B4400027A7A0CA4175E2F871493AEB1F2DA2A7C0
+:10B450008E8683D62D8108B7F9E7BE0662FCBD1E35
+:10B4600092DC2E83096E1B608ADB4698E196D41528
+:10B470009DC73821EA1DABC090E9FB6A8870DB04E8
+:10B48000316EC390E4F6CB6D9FFCD64EA4C38FE61D
+:10B49000E145E0B5805CA711E8D9FBDB78FEC21678
+:10B4A0007D41723B14107993B6709AFD7AAF1EE11C
+:10B4B000B8CF19147C6DC3719E234FFCF7FA4FF976
+:10B4C0007F5FF2FF519E9355203F00000000000077
+:10B4D0000000000000000000000000180000000054
+:10B4E000000000000000004000000000000000001C
+:10B4F0000000002800000000000000000000001014
+:10B50000000000000000000000000020000000001B
+:10B51000000000000000001000000000000000001B
+:10B520000000000800000000000000000000000013
+:10B5300000000000000000000000003900000000D2
+:10B5400000000000000000380000000000000000C3
+:10B5500000000000000000000000000000000008E3
+:10B5600000000000000000000000000000000000DB
+:10B57000000000000000000C0000000000000000BF
+:10B580000000000E000000000000000000000004A9
+:10B590000000000000000000000000180000000093
+:10B5A000000000000000001C00000000000000007F
+:10B5B0000000001C0000000000000000000000135C
+:10B5C00000000000000000000000003A0000000041
+:10B5D000000000000000000100000000000000006A
+:10B5E0000000000200000000000000000000000158
+:10B5F000000000000000000000000010000000003B
+:10B6000000000000000000500000000000000000EA
+:10B610000000000000000000000000000000000327
+:10B620000000000000000000000000AB000000006F
+:10B630000000000000000008000000000000000002
+:10B640000000C00000100000000000080000C0085A
+:10B6500000100000000000020000C0000010000008
+:10B660000000001000009FB0000000000000000873
+:10B670000000C08000100000000000040000C0882E
+:10B6800000100000000000020000C0800010000058
+:10B6900000000010000091200000000000000008E1
+:10B6A00000009340000100040000000100009348E6
+:10B6B00000000000000000020000935000000000A5
+:10B6C0000000000800009354000000000000000289
+:10B6D00000009418000000000000000800009358CB
+:10B6E000000800000000000800009AB000400000C0
+:10B6F00000000040000093980008000000000008CF
+:10B70000000093D80008000000000008000094200A
+:10B7100000C8000000000098000095B000980000EC
+:10B7200000000028000095F00098000000000028AC
+:10B730000000C480054000300000054000009D204E
+:10B74000000800000000000100009D21000800002A
+:10B7500000000001000020080010000000000010A0
+:10B7600000002000000000000000000800009CD83D
+:10B77000000800000000000200009D18000000000A
+:10B7800000000001000000010000000000000000B7
+:10B79000000000090000000000000000000000029E
+:10B7A00000000000000000000000CF2000000000AA
+:10B7B000000000200000CF46000000000000000153
+:10B7C0000000600000200000000000200000730066
+:10B7D000000800000000000800009FA0000000001A
+:10B7E0000000000100009FA8000000000000000110
+:10B7F00000009F60000000000000001000009F6338
+:10B80000000000000000000100009F610000000037
+:10B810000000000100009F66000000000000000121
+:10B8200000009F67000000000000000000009F680B
+:10B83000000000000000000400009F6C00000000F9
+:10B8400000000004000000520000000000000000A2
+:10B8500000000003000000000000000000000003E2
+:10B8600000000000000000000000000500000000D3
+:10B8700000000000000000020000000000000000C6
+:10B8800000060000000000000000002000009F7083
+:10B89000000000000000000100009F900000000078
+:10B8A000000000080000005300000000000000003D
+:10B8B00000009F98000000000000000200009F9C14
+:10B8C000000000000000000100009F9D000000003B
+:10B8D000000000010000000900000000000000005E
+:10B8E0000000000100000000000000000000004413
+:10B8F0000000000000000000000000010000000047
+:10B9000000000000000000500000000000000000E7
+:10B91000000000890000000000000000000012C8C4
+:10B920000080000000000080000000010000000016
+:10B93000000000000000A000071000000000071039
+:10B9400000001AC800000000000000080000AEC09F
+:10B9500000080000000000080000AE4000080000E1
+:10B96000000000080000AE80000800000000000891
+:10B97000000020080010000000000010000020005F
+:10B9800000000000000000080000A01007100040A8
+:10B990000000004000001BF800080000000000014B
+:10B9A00000001BF9000800000000000100001AD090
+:10B9B000000000000000000100001AD80000000094
+:10B9C0000000000200001ADA00000000000000027F
+:10B9D0000000000000000000000000000000AF00B8
+:10B9E000000000000000002000001B78002800007C
+:10B9F000000000040000E000002000000000002023
+:10BA00000000F300000800000000000800001AF029
+:10BA1000000000000000010800001B3700000000CB
+:10BA20000000000100001B0F0000000000000001EA
+:10BA300000001B70000000000000000400001B74E8
+:10BA400000000000000000040000005000000000A2
+:10BA500000000000000000030000000000000000E3
+:10BA600000000005000000000000000000000006CB
+:10BA700000000000000000000000000700000000BF
+:10BA80000000000000001BC80000000000000001D2
+:10BA900000001BE80000000000000008000000514A
+:10BAA000000000000000000000001BD000000000AB
+:10BAB0000000000400001BD400000000000000048F
+:10BAC00000001BD8000000000000000400001BDC88
+:10BAD00000000000000000080000B0000018000096
+:10BAE000000000180000C0000040000000000040FE
+:10BAF0000000C00000400002000000010000C00182
+:10BB000000400002000000000000E20000200000F1
+:10BB1000000000200000E2040002000800200002F3
+:10BB20000000000000000000000000000000E20033
+:10BB300000080020000000040000F40000280000BD
+:10BB4000000000280000F540001000000000001078
+:10BB50000000F5C000200000000000200000F5C03B
+:10BB600000020020000000020000F300002000009E
+:10BB7000000000200000200800100000000000105D
+:10BB80000000200000000000000000080000110874
+:10BB90000008000000000008000011680008000014
+:10BBA00000000008000011A80008000000000008C4
+:10BBB00000001240000800000000000100001241D7
+:10BBC0000008000000000001000040000020000408
+:10BBD00000000010000059000030001800000010A4
+:10BBE0000000590800300018000000020000570053
+:10BBF00000080000000000010000570100080000DC
+:10BC000000000001000011E8000000000000000139
+:10BC1000000011F00000000000000001000011F819
+:10BC200000000000000000100000124400080000A6
+:10BC30000000000400004000002000000000002080
+:10BC40000000530000100000000000100000153834
+:10BC500000000000000000010000000300000000E0
+:10BC600000000000000000000000000000000000D4
+:10BC700000000001000000000000000000000004BF
+:10BC80000000000000000000000015080000000097
+:10BC9000000000010000152800000000000000085E
+:10BCA00000000050000000000000000000008308B9
+:10BCB0000080000000000080000000010000000083
+:10BCC000000000000000200800100000000000102C
+:10BCD00000002000000000000000000800008410A8
+:10BCE0000008000000000008000084700008000048
+:10BCF0000000000800060000046000280000046046
+:10BD000000008520000800000000000100008521DF
+:10BD1000000800000000000100000000000000001A
+:10BD20000000000000008408000000000000000186
+:10BD3000000084F40008000000000002000084F607
+:10BD40000008000000000002000085040010000050
+:10BD500000000004000087600000000000000020D8
+:10BD600000006000002000000000002000007300C0
+:10BD700000080000000000080000000300000000B0
+:10BD800000000000000000050000000000000000AE
+:10BD90000000000600000000000000000000000796
+:10BDA0000000000000000000000088080000000003
+:10BDB00000000001000088280000000000000008CA
+:10BDC000000000500000000000000000000088108B
+:10BDD00000000000000000040000881400000000C3
+:10BDE00000000004000088180000000000000004AB
+:10BDF0000000881C00000000000000080000300067
+:10BE00000040000000000008000030080040000072
+:10BE1000000000280000339001C00010000000085E
+:10BE20000000320000200000000000200000372049
+:10BE3000000000000000000800001020062000386C
+:10BE4000000000080000A00000000000000020002A
+:10BE500000003EA9000000000000000100003EC8F4
+:10BE600000000000000000020000000000000000D0
+:10BE7000000000000000600000200000000000083A
+:10BE80000000400000080000000000010000400128
+:10BE9000000800000000000100004040000800040D
+:10BEA00000000002000040600008000400000004E0
+:10BEB00000004000000800000000000400004004F2
+:10BEC00000080000000000040000404000000000E6
+:10BED00000000008000040480000000000000008CA
+:10BEE0000000800000000000000000100000504032
+:10BEF00000010004000000010000500000000000EC
+:10BF000000000020000050080010000000000004A5
+:10BF10000000500C0010000000000001000052C79B
+:10BF20000000000000000001000052C600000000F8
+:10BF30000000000100003000003000180000000484
+:10BF40000000300400300018000000040000300839
+:10BF500000300018000000020000300A0030001815
+:10BF6000000000020000300C00300018000000014A
+:10BF70000000300D00300018000000010000300EFD
+:10BF800000300018000000010000301000300018E0
+:10BF9000000000040000301400300018000000040D
+:10BFA0000000500001000080000800040000500460
+:10BFB00001000080000800040000000A00000000EA
+:10BFC0000000000000005068010000800000000137
+:10BFD0000000506901000080000000010000506C6A
+:10BFE00001000080000000020000506E010000808F
+:10BFF00000000002000050700100008000000004FA
+:10C000000000507401000080000000040000506631
+:10C010000100008000000002000050640100008068
+:10C0200000000001000050600100008000000002DC
+:10C03000000050620100008000000002000050502B
+:10C040000100008000000004000050540100008046
+:10C0500000000004000050580100008000000004AF
+:10C060000000505C01000080000000040000507CD3
+:10C0700001000080000000010000507D01000080F0
+:10C080000000000100004018001000000000000443
+:10C0900000004090001000000000000400004098E4
+:10C0A000001000000000000400004110000000002B
+:10C0B0000000000200004112000000000000000229
+:10C0C00000004114000000000000000200004116C2
+:10C0D00000000000000000020000604000080000B6
+:10C0E00000000002000060420008000000000002A2
+:10C0F00000006044000800000000000400006080B0
+:10C100000008000000000008000060C000400008B7
+:10C1100000000008000060000008000000000002AD
+:10C120000000600200080000000000010000600440
+:10C13000000800000000000200006340000800004A
+:10C1400000000008000063800008000000000004F8
+:10C15000000063840008000000000001000063C0CC
+:10C160000008000000000002000063C40008000096
+:10C17000000000020000640000080000000000044D
+:10C1800000007000001000000000000400007004B7
+:10C190000010000000000004000070080010000003
+:10C1A00000000004000090000008000000000002F1
+:10C1B0000000900200080000000000010000900450
+:10C1C000000800000000000200009040000800008D
+:10C1D000000000020000904400080000000000027F
+:10C1E0000000904600080000000000020000964891
+:10C1F0000008000000000008000090800008000017
+:10C20000000000020000908400080000000000020E
+:10C210000000968800080000000000080000804030
+:10C22000000800000000000100008041000800003C
+:10C230000000000100008042000800000000000132
+:10C2400000008043000800000000000100008000A2
+:10C25000000800000000000200008002000800004A
+:10C26000000000010000800400080000000000023F
+:10C27000000080C00008000000000002000080C232
+:10C280000008000000000002000080C40008000058
+:10C290000000000200008080000800000000000193
+:10C2A0000000808100080000000000010000808282
+:10C2B000000800000000000100008083000800006A
+:10C2C0000000000100008084000800000000000160
+:10C2D000000080850008000000000001000080864A
+:10C2E00000080000000000010000600000080000DD
+:10C2F00000000002000060020008000000000001D1
+:10C30000000060040008000000000002000060421D
+:10C3100000C00018000000020000604000C00018CB
+:10C32000000000020000604C00C00018000000087F
+:10C330000000604400C000180000000800006057C2
+:10C3400000C00018000000010000605400C0001888
+:10C35000000000020000605600C00018000000014C
+:10C360000000664000080000000000080000668031
+:10C370000008000000000008000066C0000800007F
+:10C38000000000080000DA4200180000000000026F
+:10C390000000DE4000000000000000000000E0009F
+:10C3A00000000000000000040000D0C000000000F9
+:10C3B000000000040000D0C40000000000000004E1
+:10C3C0000000D0C800000000000000040000D0CC35
+:10C3D00000000000000000040000D0D000000000B9
+:10C3E000000000040000D0D40000000000000004A1
+:10C3F0000000D0D800000000000000040000D0C001
+:10C4000000000000000000200000DB000000000031
+:10C41000000000040000DB000000000000000068D5
+:10C420000000B94800000000000000000000D0003B
+:10C4300000000000000000040000B0C00000000088
+:10C44000000000040000B0C4000000000000000470
+:10C450000000B0C800000000000000040000B0C0F0
+:10C4600000000000000000100000D6B00000000036
+:10C47000000000040000D6B400000000000000042A
+:10C480000000D6B800000000000000040000D6BC88
+:10C4900000000000000000040000D6B00000000012
+:10C4A000000000100000D348000000000000000859
+:10C4B0000000D358000000000000008000000010C1
+:10C4C00000000000000000000000D3580000000041
+:10C4D000000000080000000006002200000000002C
+:00000001FF
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 4e8ea8c8ec1e..831c4634162c 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -301,6 +301,7 @@ header-y += quota.h
header-y += radeonfb.h
header-y += random.h
header-y += raw.h
+header-y += rds.h
header-y += reboot.h
header-y += reiserfs_fs.h
header-y += reiserfs_xattr.h
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index f6481daf6e52..a8e4e832cdbb 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -449,7 +449,7 @@ void vcc_insert_socket(struct sock *sk);
static inline int atm_guess_pdu2truesize(int size)
{
- return (SKB_DATA_ALIGN(size) + sizeof(struct skb_shared_info));
+ return SKB_DATA_ALIGN(size) + sizeof(struct skb_shared_info);
}
diff --git a/include/linux/can/platform/mcp251x.h b/include/linux/can/platform/mcp251x.h
index dba28268e651..8e20540043f5 100644
--- a/include/linux/can/platform/mcp251x.h
+++ b/include/linux/can/platform/mcp251x.h
@@ -12,7 +12,6 @@
/**
* struct mcp251x_platform_data - MCP251X SPI CAN controller platform data
* @oscillator_frequency: - oscillator frequency in Hz
- * @model: - actual type of chip
* @board_specific_setup: - called before probing the chip (power,reset)
* @transceiver_enable: - called to power on/off the transceiver
* @power_enable: - called to power on/off the mcp *and* the
@@ -25,9 +24,6 @@
struct mcp251x_platform_data {
unsigned long oscillator_frequency;
- int model;
-#define CAN_MCP251X_MCP2510 0x2510
-#define CAN_MCP251X_MCP2515 0x2515
int (*board_specific_setup)(struct spi_device *spi);
int (*transceiver_enable)(int enable);
int (*power_enable) (int enable);
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 7434a8353e23..7187bd8a75f6 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -165,8 +165,10 @@ enum {
DCCPO_TIMESTAMP_ECHO = 42,
DCCPO_ELAPSED_TIME = 43,
DCCPO_MAX = 45,
- DCCPO_MIN_CCID_SPECIFIC = 128,
- DCCPO_MAX_CCID_SPECIFIC = 255,
+ DCCPO_MIN_RX_CCID_SPECIFIC = 128, /* from sender to receiver */
+ DCCPO_MAX_RX_CCID_SPECIFIC = 191,
+ DCCPO_MIN_TX_CCID_SPECIFIC = 192, /* from receiver to sender */
+ DCCPO_MAX_TX_CCID_SPECIFIC = 255,
};
/* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */
#define DCCP_SINGLE_OPT_MAXLEN 253
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 2308fbb4523a..f16a01081e15 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -71,7 +71,7 @@ static inline int is_zero_ether_addr(const u8 *addr)
*/
static inline int is_multicast_ether_addr(const u8 *addr)
{
- return (0x01 & addr[0]);
+ return 0x01 & addr[0];
}
/**
@@ -82,7 +82,7 @@ static inline int is_multicast_ether_addr(const u8 *addr)
*/
static inline int is_local_ether_addr(const u8 *addr)
{
- return (0x02 & addr[0]);
+ return 0x02 & addr[0];
}
/**
@@ -237,13 +237,29 @@ static inline bool is_etherdev_addr(const struct net_device *dev,
* entry points.
*/
-static inline int compare_ether_header(const void *a, const void *b)
+static inline unsigned long compare_ether_header(const void *a, const void *b)
{
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
+ unsigned long fold;
+
+ /*
+ * We want to compare 14 bytes:
+ * [a0 ... a13] ^ [b0 ... b13]
+ * Use two long XOR, ORed together, with an overlap of two bytes.
+ * [a0 a1 a2 a3 a4 a5 a6 a7 ] ^ [b0 b1 b2 b3 b4 b5 b6 b7 ] |
+ * [a6 a7 a8 a9 a10 a11 a12 a13] ^ [b6 b7 b8 b9 b10 b11 b12 b13]
+ * This means the [a6 a7] ^ [b6 b7] part is done two times.
+ */
+ fold = *(unsigned long *)a ^ *(unsigned long *)b;
+ fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
+ return fold;
+#else
u32 *a32 = (u32 *)((u8 *)a + 2);
u32 *b32 = (u32 *)((u8 *)b + 2);
return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) |
(a32[1] ^ b32[1]) | (a32[2] ^ b32[2]);
+#endif
}
#endif /* _LINUX_ETHERDEVICE_H */
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 991269e5b152..6628a507fd3b 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -14,6 +14,7 @@
#define _LINUX_ETHTOOL_H
#include <linux/types.h>
+#include <linux/if_ether.h>
/* This should work for both 32 and 64 bit userland. */
struct ethtool_cmd {
@@ -308,15 +309,28 @@ struct ethtool_perm_addr {
* flag differs from the read-only value.
*/
enum ethtool_flags {
+ ETH_FLAG_TXVLAN = (1 << 7), /* TX VLAN offload enabled */
+ ETH_FLAG_RXVLAN = (1 << 8), /* RX VLAN offload enabled */
ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */
ETH_FLAG_NTUPLE = (1 << 27), /* N-tuple filters enabled */
ETH_FLAG_RXHASH = (1 << 28),
};
/* The following structures are for supporting RX network flow
- * classification configuration. Note, all multibyte fields, e.g.,
- * ip4src, ip4dst, psrc, pdst, spi, etc. are expected to be in network
- * byte order.
+ * classification and RX n-tuple configuration. Note, all multibyte
+ * fields, e.g., ip4src, ip4dst, psrc, pdst, spi, etc. are expected to
+ * be in network byte order.
+ */
+
+/**
+ * struct ethtool_tcpip4_spec - flow specification for TCP/IPv4 etc.
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @psrc: Source port
+ * @pdst: Destination port
+ * @tos: Type-of-service
+ *
+ * This can be used to specify a TCP/IPv4, UDP/IPv4 or SCTP/IPv4 flow.
*/
struct ethtool_tcpip4_spec {
__be32 ip4src;
@@ -326,6 +340,15 @@ struct ethtool_tcpip4_spec {
__u8 tos;
};
+/**
+ * struct ethtool_ah_espip4_spec - flow specification for IPsec/IPv4
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @spi: Security parameters index
+ * @tos: Type-of-service
+ *
+ * This can be used to specify an IPsec transport or tunnel over IPv4.
+ */
struct ethtool_ah_espip4_spec {
__be32 ip4src;
__be32 ip4dst;
@@ -333,21 +356,17 @@ struct ethtool_ah_espip4_spec {
__u8 tos;
};
-struct ethtool_rawip4_spec {
- __be32 ip4src;
- __be32 ip4dst;
- __u8 hdata[64];
-};
-
-struct ethtool_ether_spec {
- __be16 ether_type;
- __u8 frame_size;
- __u8 eframe[16];
-};
-
#define ETH_RX_NFC_IP4 1
-#define ETH_RX_NFC_IP6 2
+/**
+ * struct ethtool_usrip4_spec - general flow specification for IPv4
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
+ * @tos: Type-of-service
+ * @ip_ver: Value must be %ETH_RX_NFC_IP4; mask must be 0
+ * @proto: Transport protocol number; mask must be 0
+ */
struct ethtool_usrip4_spec {
__be32 ip4src;
__be32 ip4dst;
@@ -357,6 +376,15 @@ struct ethtool_usrip4_spec {
__u8 proto;
};
+/**
+ * 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
+ * @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 {
@@ -365,36 +393,91 @@ struct ethtool_rx_flow_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_rawip4_spec raw_ip4_spec;
- struct ethtool_ether_spec ether_spec;
struct ethtool_usrip4_spec usr_ip4_spec;
- __u8 hdata[64];
- } h_u, m_u; /* entry, mask */
+ struct ethhdr ether_spec;
+ __u8 hdata[72];
+ } h_u, m_u;
__u64 ring_cookie;
__u32 location;
};
+/**
+ * struct ethtool_rxnfc - command to get or set RX flow classification rules
+ * @cmd: Specific command number - %ETHTOOL_GRXFH, %ETHTOOL_SRXFH,
+ * %ETHTOOL_GRXRINGS, %ETHTOOL_GRXCLSRLCNT, %ETHTOOL_GRXCLSRULE,
+ * %ETHTOOL_GRXCLSRLALL, %ETHTOOL_SRXCLSRLDEL or %ETHTOOL_SRXCLSRLINS
+ * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW
+ * @data: Command-dependent value
+ * @fs: Flow filter specification
+ * @rule_cnt: Number of rules to be affected
+ * @rule_locs: Array of valid rule indices
+ *
+ * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating
+ * the fields included in the flow hash, e.g. %RXH_IP_SRC. The following
+ * structure fields must not be used.
+ *
+ * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues
+ * on return.
+ *
+ * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined
+ * rules on return.
+ *
+ * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the index of an
+ * existing filter rule on entry and @fs contains the rule on return.
+ *
+ * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the
+ * user buffer for @rule_locs on entry. On return, @data is the size
+ * of the filter table and @rule_locs contains the indices of the
+ * defined rules.
+ *
+ * For %ETHTOOL_SRXCLSRLINS, @fs specifies the filter rule to add or
+ * update. @fs.@location specifies the index to use and must not be
+ * ignored.
+ *
+ * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the index of an
+ * existing filter rule on entry.
+ *
+ * Implementation of indexed classification rules generally requires a
+ * TCAM.
+ */
struct ethtool_rxnfc {
__u32 cmd;
__u32 flow_type;
- /* The rx flow hash value or the rule DB size */
__u64 data;
- /* The following fields are not valid and must not be used for
- * the ETHTOOL_{G,X}RXFH commands. */
struct ethtool_rx_flow_spec fs;
__u32 rule_cnt;
__u32 rule_locs[0];
};
+/**
+ * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection
+ * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR
+ * @size: On entry, the array size of the user buffer. On return from
+ * %ETHTOOL_GRXFHINDIR, the array size of the hardware indirection table.
+ * @ring_index: RX ring/queue index for each hash value
+ */
struct ethtool_rxfh_indir {
__u32 cmd;
- /* On entry, this is the array size of the user buffer. On
- * return from ETHTOOL_GRXFHINDIR, this is the array size of
- * the hardware indirection table. */
__u32 size;
- __u32 ring_index[0]; /* ring/queue index for each hash value */
+ __u32 ring_index[0];
};
+/**
+ * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter
+ * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
+ * @h_u: Flow field values to match (dependent on @flow_type)
+ * @m_u: Masks for flow field value bits to be ignored
+ * @vlan_tag: VLAN tag to match
+ * @vlan_tag_mask: Mask for VLAN tag bits to be ignored
+ * @data: Driver-dependent data to match
+ * @data_mask: Mask for driver-dependent data bits to be ignored
+ * @action: RX ring/queue index to deliver to (non-negative) or other action
+ * (negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP)
+ *
+ * For flow types %TCP_V4_FLOW, %UDP_V4_FLOW and %SCTP_V4_FLOW, where
+ * a field value and mask are both zero this is treated as if all mask
+ * bits are set i.e. the field is ignored.
+ */
struct ethtool_rx_ntuple_flow_spec {
__u32 flow_type;
union {
@@ -403,22 +486,26 @@ struct ethtool_rx_ntuple_flow_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_rawip4_spec raw_ip4_spec;
- struct ethtool_ether_spec ether_spec;
struct ethtool_usrip4_spec usr_ip4_spec;
- __u8 hdata[64];
- } h_u, m_u; /* entry, mask */
+ struct ethhdr ether_spec;
+ __u8 hdata[72];
+ } h_u, m_u;
__u16 vlan_tag;
__u16 vlan_tag_mask;
- __u64 data; /* user-defined flow spec data */
- __u64 data_mask; /* user-defined flow spec mask */
+ __u64 data;
+ __u64 data_mask;
- /* signed to distinguish between queue and actions (DROP) */
__s32 action;
-#define ETHTOOL_RXNTUPLE_ACTION_DROP -1
+#define ETHTOOL_RXNTUPLE_ACTION_DROP (-1) /* drop packet */
+#define ETHTOOL_RXNTUPLE_ACTION_CLEAR (-2) /* clear filter */
};
+/**
+ * struct ethtool_rx_ntuple - command to set or clear RX flow filter
+ * @cmd: Command number - %ETHTOOL_SRXNTUPLE
+ * @fs: Flow filter specification
+ */
struct ethtool_rx_ntuple {
__u32 cmd;
struct ethtool_rx_ntuple_flow_spec fs;
@@ -759,22 +846,23 @@ struct ethtool_ops {
#define WAKE_MAGIC (1 << 5)
#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
-/* L3-L4 network traffic flow types */
-#define TCP_V4_FLOW 0x01
-#define UDP_V4_FLOW 0x02
-#define SCTP_V4_FLOW 0x03
-#define AH_ESP_V4_FLOW 0x04
-#define TCP_V6_FLOW 0x05
-#define UDP_V6_FLOW 0x06
-#define SCTP_V6_FLOW 0x07
-#define AH_ESP_V6_FLOW 0x08
-#define AH_V4_FLOW 0x09
-#define ESP_V4_FLOW 0x0a
-#define AH_V6_FLOW 0x0b
-#define ESP_V6_FLOW 0x0c
-#define IP_USER_FLOW 0x0d
-#define IPV4_FLOW 0x10
-#define IPV6_FLOW 0x11
+/* L2-L4 network traffic flow types */
+#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */
+#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */
+#define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */
+#define AH_ESP_V4_FLOW 0x04 /* hash only */
+#define TCP_V6_FLOW 0x05 /* hash only */
+#define UDP_V6_FLOW 0x06 /* hash only */
+#define SCTP_V6_FLOW 0x07 /* hash only */
+#define AH_ESP_V6_FLOW 0x08 /* hash only */
+#define AH_V4_FLOW 0x09 /* hash or spec (ah_ip4_spec) */
+#define ESP_V4_FLOW 0x0a /* hash or spec (esp_ip4_spec) */
+#define AH_V6_FLOW 0x0b /* hash only */
+#define ESP_V6_FLOW 0x0c /* hash only */
+#define IP_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */
+#define IPV4_FLOW 0x10 /* hash only */
+#define IPV6_FLOW 0x11 /* hash only */
+#define ETHER_FLOW 0x12 /* spec only (ether_spec) */
/* L3-L4 network traffic flow hash options */
#define RXH_L2DA (1 << 1)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 97b2eae6a22c..ed5a03cbe184 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -986,6 +986,7 @@ struct ieee80211_ht_info {
#define WLAN_AUTH_OPEN 0
#define WLAN_AUTH_SHARED_KEY 1
#define WLAN_AUTH_FT 2
+#define WLAN_AUTH_SAE 3
#define WLAN_AUTH_LEAP 128
#define WLAN_AUTH_CHALLENGE_LEN 128
@@ -1072,6 +1073,10 @@ enum ieee80211_statuscode {
WLAN_STATUS_NO_DIRECT_LINK = 48,
WLAN_STATUS_STA_NOT_PRESENT = 49,
WLAN_STATUS_STA_NOT_QSTA = 50,
+ /* 802.11s */
+ WLAN_STATUS_ANTI_CLOG_REQUIRED = 76,
+ WLAN_STATUS_FCG_NOT_SUPP = 78,
+ WLAN_STATUS_STA_NO_TBTT = 78,
};
@@ -1112,6 +1117,22 @@ enum ieee80211_reasoncode {
WLAN_REASON_QSTA_REQUIRE_SETUP = 38,
WLAN_REASON_QSTA_TIMEOUT = 39,
WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45,
+ /* 802.11s */
+ WLAN_REASON_MESH_PEER_CANCELED = 52,
+ WLAN_REASON_MESH_MAX_PEERS = 53,
+ WLAN_REASON_MESH_CONFIG = 54,
+ WLAN_REASON_MESH_CLOSE = 55,
+ WLAN_REASON_MESH_MAX_RETRIES = 56,
+ WLAN_REASON_MESH_CONFIRM_TIMEOUT = 57,
+ WLAN_REASON_MESH_INVALID_GTK = 58,
+ WLAN_REASON_MESH_INCONSISTENT_PARAM = 59,
+ WLAN_REASON_MESH_INVALID_SECURITY = 60,
+ WLAN_REASON_MESH_PATH_ERROR = 61,
+ WLAN_REASON_MESH_PATH_NOFORWARD = 62,
+ WLAN_REASON_MESH_PATH_DEST_UNREACHABLE = 63,
+ WLAN_REASON_MAC_EXISTS_IN_MBSS = 64,
+ WLAN_REASON_MESH_CHAN_REGULATORY = 65,
+ WLAN_REASON_MESH_CHAN = 66,
};
@@ -1139,20 +1160,33 @@ enum ieee80211_eid {
WLAN_EID_TS_DELAY = 43,
WLAN_EID_TCLAS_PROCESSING = 44,
WLAN_EID_QOS_CAPA = 46,
- /* 802.11s
- *
- * All mesh EID numbers are pending IEEE 802.11 ANA approval.
- * The numbers have been incremented from those suggested in
- * 802.11s/D2.0 so that MESH_CONFIG does not conflict with
- * EXT_SUPP_RATES.
+ /* 802.11s */
+ WLAN_EID_MESH_CONFIG = 113,
+ WLAN_EID_MESH_ID = 114,
+ WLAN_EID_LINK_METRIC_REPORT = 115,
+ WLAN_EID_CONGESTION_NOTIFICATION = 116,
+ /* Note that the Peer Link IE has been replaced with the similar
+ * Peer Management IE. We will keep the former definition until mesh
+ * code is changed to comply with latest 802.11s drafts.
*/
- WLAN_EID_MESH_CONFIG = 51,
- WLAN_EID_MESH_ID = 52,
- WLAN_EID_PEER_LINK = 55,
- WLAN_EID_PREQ = 68,
- WLAN_EID_PREP = 69,
- WLAN_EID_PERR = 70,
- WLAN_EID_RANN = 49, /* compatible with FreeBSD */
+ WLAN_EID_PEER_LINK = 55, /* no longer in 802.11s drafts */
+ WLAN_EID_PEER_MGMT = 117,
+ WLAN_EID_CHAN_SWITCH_PARAM = 118,
+ WLAN_EID_MESH_AWAKE_WINDOW = 119,
+ WLAN_EID_BEACON_TIMING = 120,
+ WLAN_EID_MCCAOP_SETUP_REQ = 121,
+ WLAN_EID_MCCAOP_SETUP_RESP = 122,
+ WLAN_EID_MCCAOP_ADVERT = 123,
+ WLAN_EID_MCCAOP_TEARDOWN = 124,
+ WLAN_EID_GANN = 125,
+ WLAN_EID_RANN = 126,
+ WLAN_EID_PREQ = 130,
+ WLAN_EID_PREP = 131,
+ WLAN_EID_PERR = 132,
+ WLAN_EID_PXU = 137,
+ WLAN_EID_PXUC = 138,
+ WLAN_EID_AUTH_MESH_PEER_EXCH = 139,
+ WLAN_EID_MIC = 140,
WLAN_EID_PWR_CONSTRAINT = 32,
WLAN_EID_PWR_CAPABILITY = 33,
@@ -1211,9 +1245,14 @@ enum ieee80211_category {
WLAN_CATEGORY_HT = 7,
WLAN_CATEGORY_SA_QUERY = 8,
WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
+ WLAN_CATEGORY_MESH_ACTION = 13,
+ WLAN_CATEGORY_MULTIHOP_ACTION = 14,
+ WLAN_CATEGORY_SELF_PROTECTED = 15,
WLAN_CATEGORY_WMM = 17,
- WLAN_CATEGORY_MESH_PLINK = 30, /* Pending ANA approval */
- WLAN_CATEGORY_MESH_PATH_SEL = 32, /* Pending ANA approval */
+ /* TODO: remove MESH_PLINK and MESH_PATH_SEL after */
+ /* mesh is updated to current 802.11s draft */
+ WLAN_CATEGORY_MESH_PLINK = 30,
+ WLAN_CATEGORY_MESH_PATH_SEL = 32,
WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
};
@@ -1351,6 +1390,8 @@ enum ieee80211_sa_query_action {
/* AKM suite selectors */
#define WLAN_AKM_SUITE_8021X 0x000FAC01
#define WLAN_AKM_SUITE_PSK 0x000FAC02
+#define WLAN_AKM_SUITE_SAE 0x000FAC08
+#define WLAN_AKM_SUITE_FT_OVER_SAE 0x000FAC09
#define WLAN_MAX_KEY_LEN 32
diff --git a/include/linux/if.h b/include/linux/if.h
index 53558ec59e1b..123959927745 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -75,6 +75,8 @@
#define IFF_DISABLE_NETPOLL 0x2000 /* disable netpoll at run-time */
#define IFF_MACVLAN_PORT 0x4000 /* device used as macvlan port */
#define IFF_BRIDGE_PORT 0x8000 /* device used as bridge port */
+#define IFF_OVS_DATAPATH 0x10000 /* device used as Open vSwitch
+ * datapath port */
#define IF_GET_IFACE 0x0001 /* for querying only */
#define IF_GET_PROTO 0x0002
diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h
index 2c7994372bde..a17edda8a781 100644
--- a/include/linux/if_bonding.h
+++ b/include/linux/if_bonding.h
@@ -84,6 +84,9 @@
#define BOND_DEFAULT_MAX_BONDS 1 /* Default maximum number of devices to support */
#define BOND_DEFAULT_TX_QUEUES 16 /* Default number of tx queues per device */
+
+#define BOND_DEFAULT_RESEND_IGMP 1 /* Default number of IGMP membership reports */
+
/* hashing types */
#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */
#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index bed7a4682b90..f9c3df03db0f 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -137,8 +137,6 @@ extern struct ctl_table ether_table[];
extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len);
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-
#endif
#endif /* _LINUX_IF_ETHER_H */
diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h
index 35280b302290..8a2fd66a8b5f 100644
--- a/include/linux/if_macvlan.h
+++ b/include/linux/if_macvlan.h
@@ -40,6 +40,12 @@ struct macvlan_rx_stats {
unsigned long rx_errors;
};
+/*
+ * Maximum times a macvtap device can be opened. This can be used to
+ * configure the number of receive queue, e.g. for multiqueue virtio.
+ */
+#define MAX_MACVTAP_QUEUES (NR_CPUS < 16 ? NR_CPUS : 16)
+
struct macvlan_dev {
struct net_device *dev;
struct list_head list;
@@ -50,7 +56,8 @@ struct macvlan_dev {
enum macvlan_mode mode;
int (*receive)(struct sk_buff *skb);
int (*forward)(struct net_device *dev, struct sk_buff *skb);
- struct macvtap_queue *tap;
+ struct macvtap_queue *taps[MAX_MACVTAP_QUEUES];
+ int numvtaps;
};
static inline void macvlan_count_rx(const struct macvlan_dev *vlan,
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
index 27741e05446f..397921b09ef9 100644
--- a/include/linux/if_pppox.h
+++ b/include/linux/if_pppox.h
@@ -40,25 +40,35 @@
* PPPoE addressing definition
*/
typedef __be16 sid_t;
-struct pppoe_addr{
- sid_t sid; /* Session identifier */
- unsigned char remote[ETH_ALEN]; /* Remote address */
- char dev[IFNAMSIZ]; /* Local device to use */
+struct pppoe_addr {
+ sid_t sid; /* Session identifier */
+ unsigned char remote[ETH_ALEN]; /* Remote address */
+ char dev[IFNAMSIZ]; /* Local device to use */
};
/************************************************************************
- * Protocols supported by AF_PPPOX
- */
+ * PPTP addressing definition
+ */
+struct pptp_addr {
+ __be16 call_id;
+ struct in_addr sin_addr;
+};
+
+/************************************************************************
+ * Protocols supported by AF_PPPOX
+ */
#define PX_PROTO_OE 0 /* Currently just PPPoE */
#define PX_PROTO_OL2TP 1 /* Now L2TP also */
-#define PX_MAX_PROTO 2
-
-struct sockaddr_pppox {
- sa_family_t sa_family; /* address family, AF_PPPOX */
- unsigned int sa_protocol; /* protocol identifier */
- union{
- struct pppoe_addr pppoe;
- }sa_addr;
+#define PX_PROTO_PPTP 2
+#define PX_MAX_PROTO 3
+
+struct sockaddr_pppox {
+ sa_family_t sa_family; /* address family, AF_PPPOX */
+ unsigned int sa_protocol; /* protocol identifier */
+ union {
+ struct pppoe_addr pppoe;
+ struct pptp_addr pptp;
+ } sa_addr;
} __attribute__((packed));
/* The use of the above union isn't viable because the size of this
@@ -150,15 +160,23 @@ struct pppoe_opt {
relayed to (PPPoE relaying) */
};
+struct pptp_opt {
+ struct pptp_addr src_addr;
+ struct pptp_addr dst_addr;
+ u32 ack_sent, ack_recv;
+ u32 seq_sent, seq_recv;
+ int ppp_flags;
+};
#include <net/sock.h>
struct pppox_sock {
/* struct sock must be the first member of pppox_sock */
- struct sock sk;
- struct ppp_channel chan;
+ struct sock sk;
+ struct ppp_channel chan;
struct pppox_sock *next; /* for hash table */
union {
struct pppoe_opt pppoe;
+ struct pptp_opt pptp;
} proto;
__be16 num;
};
@@ -186,7 +204,7 @@ struct pppox_proto {
struct module *owner;
};
-extern int register_pppox_proto(int proto_num, struct pppox_proto *pp);
+extern int register_pppox_proto(int proto_num, const struct pppox_proto *pp);
extern void unregister_pppox_proto(int proto_num);
extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */
extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 3d870fda8c4f..c2f3a72712ce 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -16,6 +16,7 @@
#ifdef __KERNEL__
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
#define VLAN_HLEN 4 /* The additional bytes (on top of the Ethernet header)
* that VLAN requires.
@@ -68,6 +69,7 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
#define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator */
#define VLAN_TAG_PRESENT VLAN_CFI_MASK
#define VLAN_VID_MASK 0x0fff /* VLAN Identifier */
+#define VLAN_N_VID 4096
/* found in socket.c */
extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
@@ -76,9 +78,8 @@ extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
* depends on completely exhausting the VLAN identifier space. Thus
* it gives constant time look-up, but in many cases it wastes memory.
*/
-#define VLAN_GROUP_ARRAY_LEN 4096
#define VLAN_GROUP_ARRAY_SPLIT_PARTS 8
-#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_GROUP_ARRAY_LEN/VLAN_GROUP_ARRAY_SPLIT_PARTS)
+#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS)
struct vlan_group {
struct net_device *real_dev; /* The ethernet(like) device
@@ -114,12 +115,24 @@ static inline void vlan_group_set_device(struct vlan_group *vg,
#define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+/* Must be invoked with rcu_read_lock or with RTNL. */
+static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
+ u16 vlan_id)
+{
+ struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp);
+
+ if (grp)
+ return vlan_group_get_device(grp, vlan_id);
+
+ return NULL;
+}
+
extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
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 int vlan_hwaccel_do_receive(struct sk_buff *skb);
+extern bool vlan_hwaccel_do_receive(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);
@@ -128,6 +141,12 @@ vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
unsigned int vlan_tci);
#else
+static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
+ u16 vlan_id)
+{
+ return NULL;
+}
+
static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
{
BUG();
@@ -147,9 +166,11 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
return NET_XMIT_SUCCESS;
}
-static inline int vlan_hwaccel_do_receive(struct sk_buff *skb)
+static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb)
{
- return 0;
+ if ((*skb)->vlan_tci & VLAN_VID_MASK)
+ (*skb)->pkt_type = PACKET_OTHERHOST;
+ return false;
}
static inline gro_result_t
diff --git a/include/linux/in.h b/include/linux/in.h
index 41d88a4689af..beeb6dee2b49 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -250,6 +250,25 @@ struct sockaddr_in {
#ifdef __KERNEL__
+#include <linux/errno.h>
+
+static inline int proto_ports_offset(int proto)
+{
+ switch (proto) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ case IPPROTO_DCCP:
+ case IPPROTO_ESP: /* SPI */
+ case IPPROTO_SCTP:
+ case IPPROTO_UDPLITE:
+ return 0;
+ case IPPROTO_AH: /* SPI */
+ return 4;
+ default:
+ return -EINVAL;
+ }
+}
+
static inline bool ipv4_is_loopback(__be32 addr)
{
return (addr & htonl(0xff000000)) == htonl(0x7f000000);
diff --git a/include/linux/in6.h b/include/linux/in6.h
index c4bf46f764bf..097a34b55560 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -268,6 +268,10 @@ struct in6_flowlabel_req {
/* RFC5082: Generalized Ttl Security Mechanism */
#define IPV6_MINHOPCOUNT 73
+#define IPV6_ORIGDSTADDR 74
+#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
+#define IPV6_TRANSPARENT 75
+
/*
* Multicast Routing:
* see include/linux/mroute6.h.
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 2be1a1a2beb9..ccd5b07d678d 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -9,6 +9,7 @@
#include <linux/rcupdate.h>
#include <linux/timer.h>
#include <linux/sysctl.h>
+#include <linux/rtnetlink.h>
enum
{
@@ -158,7 +159,12 @@ struct in_ifaddr {
extern int register_inetaddr_notifier(struct notifier_block *nb);
extern int unregister_inetaddr_notifier(struct notifier_block *nb);
-extern struct net_device *ip_dev_find(struct net *net, __be32 addr);
+extern struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref);
+static inline struct net_device *ip_dev_find(struct net *net, __be32 addr)
+{
+ return __ip_dev_find(net, addr, true);
+}
+
extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
extern int devinet_ioctl(struct net *net, unsigned int cmd, void __user *);
extern void devinet_init(void);
@@ -198,14 +204,10 @@ static __inline__ int bad_mask(__be32 mask, __be32 addr)
static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev)
{
- struct in_device *in_dev = dev->ip_ptr;
- if (in_dev)
- in_dev = rcu_dereference(in_dev);
- return in_dev;
+ return rcu_dereference(dev->ip_ptr);
}
-static __inline__ struct in_device *
-in_dev_get(const struct net_device *dev)
+static inline struct in_device *in_dev_get(const struct net_device *dev)
{
struct in_device *in_dev;
@@ -217,10 +219,9 @@ in_dev_get(const struct net_device *dev)
return in_dev;
}
-static __inline__ struct in_device *
-__in_dev_get_rtnl(const struct net_device *dev)
+static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev)
{
- return (struct in_device*)dev->ip_ptr;
+ return rcu_dereference_check(dev->ip_ptr, lockdep_rtnl_is_held());
}
extern void in_dev_finish_destroy(struct in_device *idev);
diff --git a/include/linux/ip_vs.h b/include/linux/ip_vs.h
index 9708de265bb1..5f43a3b2e3ad 100644
--- a/include/linux/ip_vs.h
+++ b/include/linux/ip_vs.h
@@ -70,6 +70,7 @@
/*
* IPVS Connection Flags
+ * Only flags 0..15 are sent to backup server
*/
#define IP_VS_CONN_F_FWD_MASK 0x0007 /* mask for the fwd methods */
#define IP_VS_CONN_F_MASQ 0x0000 /* masquerading/NAT */
@@ -88,9 +89,20 @@
#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */
#define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */
+/* Flags that are not sent to backup server start from bit 16 */
+#define IP_VS_CONN_F_NFCT (1 << 16) /* use netfilter conntrack */
+
+/* Connection flags from destination that can be changed by user space */
+#define IP_VS_CONN_F_DEST_MASK (IP_VS_CONN_F_FWD_MASK | \
+ IP_VS_CONN_F_ONE_PACKET | \
+ IP_VS_CONN_F_NFCT | \
+ 0)
+
#define IP_VS_SCHEDNAME_MAXLEN 16
+#define IP_VS_PENAME_MAXLEN 16
#define IP_VS_IFNAME_MAXLEN 16
+#define IP_VS_PEDATA_MAXLEN 255
/*
* The struct ip_vs_service_user and struct ip_vs_dest_user are
@@ -324,6 +336,9 @@ enum {
IPVS_SVC_ATTR_NETMASK, /* persistent netmask */
IPVS_SVC_ATTR_STATS, /* nested attribute for service stats */
+
+ IPVS_SVC_ATTR_PE_NAME, /* name of ct retriever */
+
__IPVS_SVC_ATTR_MAX,
};
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index e62683ba88e6..8e429d0e0405 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -341,7 +341,9 @@ struct ipv6_pinfo {
odstopts:1,
rxflow:1,
rxtclass:1,
- rxpmtu:1;
+ rxpmtu:1,
+ rxorigdstaddr:1;
+ /* 2 bits hole */
} bits;
__u16 all;
} rxopt;
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index 0f82293a82ed..78a1b9671752 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -56,6 +56,7 @@ enum {
MLX4_CMD_QUERY_HCA = 0xb,
MLX4_CMD_QUERY_PORT = 0x43,
MLX4_CMD_SENSE_PORT = 0x4d,
+ MLX4_CMD_HW_HEALTH_CHECK = 0x50,
MLX4_CMD_SET_PORT = 0xc,
MLX4_CMD_ACCESS_DDR = 0x2e,
MLX4_CMD_MAP_ICM = 0xffa,
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 7a7f9c1e679a..7338654c02b4 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -186,6 +186,10 @@ struct mlx4_caps {
int eth_mtu_cap[MLX4_MAX_PORTS + 1];
int gid_table_len[MLX4_MAX_PORTS + 1];
int pkey_table_len[MLX4_MAX_PORTS + 1];
+ int trans_type[MLX4_MAX_PORTS + 1];
+ int vendor_oui[MLX4_MAX_PORTS + 1];
+ int wavelength[MLX4_MAX_PORTS + 1];
+ u64 trans_code[MLX4_MAX_PORTS + 1];
int local_ca_ack_delay;
int num_uars;
int bf_reg_size;
@@ -229,6 +233,8 @@ struct mlx4_caps {
u32 bmme_flags;
u32 reserved_lkey;
u16 stat_rate_support;
+ int udp_rss;
+ int loopback_support;
u8 port_width_cap[MLX4_MAX_PORTS + 1];
int max_gso_sz;
int reserved_qps_cnt[MLX4_NUM_QP_REGION];
@@ -480,5 +486,6 @@ void mlx4_fmr_unmap(struct mlx4_dev *dev, struct mlx4_fmr *fmr,
u32 *lkey, u32 *rkey);
int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr);
int mlx4_SYNC_TPT(struct mlx4_dev *dev);
+int mlx4_test_interrupts(struct mlx4_dev *dev);
#endif /* MLX4_DEVICE_H */
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index 33b2ea09a4ad..a36ab3bc7b03 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -18,6 +18,7 @@
#define SDIO_CLASS_PHS 0x06 /* PHS standard interface */
#define SDIO_CLASS_WLAN 0x07 /* WLAN interface */
#define SDIO_CLASS_ATA 0x08 /* Embedded SDIO-ATA std interface */
+#define SDIO_CLASS_BT_AMP 0x09 /* Type-A Bluetooth AMP interface */
/*
* Vendors and devices. Sort key: vendor first, device next.
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index fa04b246c9ae..0fa7a3a874c8 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -213,6 +213,7 @@ struct mfc_cache {
unsigned char ttls[MAXVIFS]; /* TTL thresholds */
} res;
} mfc_un;
+ struct rcu_head rcu;
};
#define MFC_STATIC 1
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 46c36ffe20ee..fcd3dda86322 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -228,9 +228,9 @@ struct netdev_hw_addr {
#define NETDEV_HW_ADDR_T_SLAVE 3
#define NETDEV_HW_ADDR_T_UNICAST 4
#define NETDEV_HW_ADDR_T_MULTICAST 5
- int refcount;
bool synced;
bool global_use;
+ int refcount;
struct rcu_head rcu_head;
};
@@ -281,6 +281,12 @@ struct hh_cache {
unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)];
};
+static inline void hh_cache_put(struct hh_cache *hh)
+{
+ if (atomic_dec_and_test(&hh->hh_refcnt))
+ kfree(hh);
+}
+
/* Reserve HH_DATA_MOD byte aligned hard_header_len, but at least that much.
* Alternative is:
* dev->hard_header_len ? (dev->hard_header_len +
@@ -884,6 +890,9 @@ struct net_device {
int iflink;
struct net_device_stats stats;
+ atomic_long_t rx_dropped; /* dropped packets by core network
+ * Do not use this in drivers.
+ */
#ifdef CONFIG_WIRELESS_EXT
/* List of functions to handle Wireless Extensions (instead of ioctl).
@@ -901,7 +910,7 @@ struct net_device {
unsigned int flags; /* interface flags (a la BSD) */
unsigned short gflags;
- unsigned short priv_flags; /* Like 'flags' but invisible to userspace. */
+ 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 */
@@ -918,10 +927,6 @@ struct net_device {
unsigned short needed_headroom;
unsigned short needed_tailroom;
- struct net_device *master; /* Pointer to master device of a group,
- * which this device is member of.
- */
-
/* Interface address info. */
unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
unsigned char addr_assign_type; /* hw address assignment type */
@@ -937,12 +942,15 @@ struct net_device {
/* Protocol specific pointers */
-
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+ struct vlan_group *vlgrp; /* VLAN group */
+#endif
#ifdef CONFIG_NET_DSA
void *dsa_ptr; /* dsa specific data */
#endif
void *atalk_ptr; /* AppleTalk link */
- void *ip_ptr; /* IPv4 specific data */
+ struct in_device __rcu *ip_ptr; /* IPv4 specific data */
void *dn_ptr; /* DECnet specific data */
void *ip6_ptr; /* IPv6 specific data */
void *ec_ptr; /* Econet specific data */
@@ -951,9 +959,20 @@ struct net_device {
assign before registering */
/*
- * Cache line mostly used on receive path (including eth_type_trans())
+ * Cache lines mostly used on receive path (including eth_type_trans())
*/
- unsigned long last_rx; /* Time of last Rx */
+ unsigned long last_rx; /* Time of last Rx
+ * This should not be set in
+ * drivers, unless really needed,
+ * because network stack (bonding)
+ * use it if/when necessary, to
+ * avoid dirtying this cache line.
+ */
+
+ struct net_device *master; /* Pointer to master device of a group,
+ * which this device is member of.
+ */
+
/* Interface address info used in eth_type_trans() */
unsigned char *dev_addr; /* hw address, (before bcast
because most packets are
@@ -969,14 +988,21 @@ struct net_device {
struct netdev_rx_queue *_rx;
- /* Number of RX queues allocated at alloc_netdev_mq() time */
+ /* Number of RX queues allocated at register_netdev() time */
unsigned int num_rx_queues;
+
+ /* Number of RX queues currently active in device */
+ unsigned int real_num_rx_queues;
#endif
- struct netdev_queue rx_queue;
rx_handler_func_t *rx_handler;
void *rx_handler_data;
+ struct netdev_queue __rcu *ingress_queue;
+
+/*
+ * Cache lines mostly used on transmit path
+ */
struct netdev_queue *_tx ____cacheline_aligned_in_smp;
/* Number of TX queues allocated at alloc_netdev_mq() time */
@@ -990,9 +1016,7 @@ struct net_device {
unsigned long tx_queue_len; /* Max frames per queue allowed */
spinlock_t tx_global_lock;
-/*
- * One part is mostly used on xmit path (device)
- */
+
/* These may be needed for future network-power-down code. */
/*
@@ -1005,7 +1029,7 @@ struct net_device {
struct timer_list watchdog_timer;
/* Number of references to this device */
- atomic_t refcnt ____cacheline_aligned_in_smp;
+ int __percpu *pcpu_refcnt;
/* delayed register/unregister */
struct list_head todo_list;
@@ -1041,8 +1065,12 @@ struct net_device {
#endif
/* mid-layer private */
- void *ml_priv;
-
+ union {
+ void *ml_priv;
+ struct pcpu_lstats __percpu *lstats; /* loopback stats */
+ struct pcpu_tstats __percpu *tstats; /* tunnel stats */
+ struct pcpu_dstats __percpu *dstats; /* dummy stats */
+ };
/* GARP */
struct garp_port *garp_port;
@@ -1305,6 +1333,7 @@ static inline void unregister_netdevice(struct net_device *dev)
unregister_netdevice_queue(dev, NULL);
}
+extern int netdev_refcnt_read(const struct net_device *dev);
extern void free_netdev(struct net_device *dev);
extern void synchronize_net(void);
extern int register_netdevice_notifier(struct notifier_block *nb);
@@ -1667,11 +1696,34 @@ static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
*/
static inline int netif_is_multiqueue(const struct net_device *dev)
{
- return (dev->num_tx_queues > 1);
+ return dev->num_tx_queues > 1;
}
-extern void netif_set_real_num_tx_queues(struct net_device *dev,
- unsigned int txq);
+extern int netif_set_real_num_tx_queues(struct net_device *dev,
+ unsigned int txq);
+
+#ifdef CONFIG_RPS
+extern int netif_set_real_num_rx_queues(struct net_device *dev,
+ unsigned int rxq);
+#else
+static inline int netif_set_real_num_rx_queues(struct net_device *dev,
+ unsigned int rxq)
+{
+ return 0;
+}
+#endif
+
+static inline int netif_copy_real_num_queues(struct net_device *to_dev,
+ const struct net_device *from_dev)
+{
+ netif_set_real_num_tx_queues(to_dev, from_dev->real_num_tx_queues);
+#ifdef CONFIG_RPS
+ return netif_set_real_num_rx_queues(to_dev,
+ from_dev->real_num_rx_queues);
+#else
+ return 0;
+#endif
+}
/* Use this variant when it is known for sure that it
* is executing from hardware interrupt context or with hardware interrupts
@@ -1695,8 +1747,7 @@ extern gro_result_t dev_gro_receive(struct napi_struct *napi,
extern gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb);
extern gro_result_t napi_gro_receive(struct napi_struct *napi,
struct sk_buff *skb);
-extern void napi_reuse_skb(struct napi_struct *napi,
- struct sk_buff *skb);
+extern void napi_gro_flush(struct napi_struct *napi);
extern struct sk_buff * napi_get_frags(struct napi_struct *napi);
extern gro_result_t napi_frags_finish(struct napi_struct *napi,
struct sk_buff *skb,
@@ -1715,7 +1766,6 @@ extern int netdev_rx_handler_register(struct net_device *dev,
void *rx_handler_data);
extern void netdev_rx_handler_unregister(struct net_device *dev);
-extern void netif_nit_deliver(struct sk_buff *skb);
extern int dev_valid_name(const char *name);
extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
extern int dev_ethtool(struct net *net, struct ifreq *);
@@ -1749,7 +1799,7 @@ extern void netdev_run_todo(void);
*/
static inline void dev_put(struct net_device *dev)
{
- atomic_dec(&dev->refcnt);
+ irqsafe_cpu_dec(*dev->pcpu_refcnt);
}
/**
@@ -1760,7 +1810,7 @@ static inline void dev_put(struct net_device *dev)
*/
static inline void dev_hold(struct net_device *dev)
{
- atomic_inc(&dev->refcnt);
+ irqsafe_cpu_inc(*dev->pcpu_refcnt);
}
/* Carrier loss detection, dial on demand. The functions netif_carrier_on
@@ -2171,6 +2221,8 @@ extern void dev_seq_stop(struct seq_file *seq, void *v);
extern int netdev_class_create_file(struct class_attribute *class_attr);
extern void netdev_class_remove_file(struct class_attribute *class_attr);
+extern struct kobj_ns_type_operations net_ns_type_operations;
+
extern char *netdev_drivername(const struct net_device *dev, char *buffer, int len);
extern void linkwatch_run_queue(void);
@@ -2191,14 +2243,22 @@ static inline int net_gso_ok(int features, int gso_type)
static inline int skb_gso_ok(struct sk_buff *skb, int features)
{
return net_gso_ok(features, skb_shinfo(skb)->gso_type) &&
- (!skb_has_frags(skb) || (features & NETIF_F_FRAGLIST));
+ (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST));
}
static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
{
- return skb_is_gso(skb) &&
- (!skb_gso_ok(skb, dev->features) ||
- unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
+ if (skb_is_gso(skb)) {
+ int features = dev->features;
+
+ if (skb->protocol == htons(ETH_P_8021Q) || skb->vlan_tci)
+ features &= dev->vlan_features;
+
+ return (!skb_gso_ok(skb, features) ||
+ unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
+ }
+
+ return 0;
}
static inline void netif_set_gso_max_size(struct net_device *dev,
diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
index 1afd18c855ec..50cdc2559a5a 100644
--- a/include/linux/netfilter/nf_conntrack_common.h
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -98,8 +98,14 @@ enum ip_conntrack_events {
enum ip_conntrack_expect_events {
IPEXP_NEW, /* new expectation */
+ IPEXP_DESTROY, /* destroyed expectation */
};
+/* expectation flags */
+#define NF_CT_EXPECT_PERMANENT 0x1
+#define NF_CT_EXPECT_INACTIVE 0x2
+#define NF_CT_EXPECT_USERSPACE 0x4
+
#ifdef __KERNEL__
struct ip_conntrack_stat {
unsigned int searched;
diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h
index ff8cfbcf3b81..0ce91d56a5f2 100644
--- a/include/linux/netfilter/nf_conntrack_sip.h
+++ b/include/linux/netfilter/nf_conntrack_sip.h
@@ -89,6 +89,7 @@ enum sip_header_types {
SIP_HDR_VIA_TCP,
SIP_HDR_EXPIRES,
SIP_HDR_CONTENT_LENGTH,
+ SIP_HDR_CALL_ID,
};
enum sdp_header_types {
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index 70cd0603911c..19711e3ffd42 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -162,6 +162,7 @@ enum ctattr_expect {
CTA_EXPECT_ID,
CTA_EXPECT_HELP_NAME,
CTA_EXPECT_ZONE,
+ CTA_EXPECT_FLAGS,
__CTA_EXPECT_MAX
};
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 24e5d01d27d0..742bec051440 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -66,6 +66,11 @@ struct xt_standard_target {
int verdict;
};
+struct xt_error_target {
+ struct xt_entry_target target;
+ char errorname[XT_FUNCTION_MAXNAMELEN];
+};
+
/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision
* kernel supports, if >= revision. */
struct xt_get_revision {
diff --git a/include/linux/netfilter/xt_TPROXY.h b/include/linux/netfilter/xt_TPROXY.h
index 152e8f97132b..3f3d69361289 100644
--- a/include/linux/netfilter/xt_TPROXY.h
+++ b/include/linux/netfilter/xt_TPROXY.h
@@ -1,5 +1,5 @@
-#ifndef _XT_TPROXY_H_target
-#define _XT_TPROXY_H_target
+#ifndef _XT_TPROXY_H
+#define _XT_TPROXY_H
/* TPROXY target is capable of marking the packet to perform
* redirection. We can get rid of that whenever we get support for
@@ -11,4 +11,11 @@ struct xt_tproxy_target_info {
__be16 lport;
};
-#endif /* _XT_TPROXY_H_target */
+struct xt_tproxy_target_info_v1 {
+ u_int32_t mark_mask;
+ u_int32_t mark_value;
+ union nf_inet_addr laddr;
+ __be16 lport;
+};
+
+#endif /* _XT_TPROXY_H */
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index e9948c0560f6..adbf4bff87ed 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -21,8 +21,21 @@
#include <linux/netfilter/x_tables.h>
+#ifndef __KERNEL__
#define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
#define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define arpt_entry_target xt_entry_target
+#define arpt_standard_target xt_standard_target
+#define arpt_error_target xt_error_target
+#define ARPT_CONTINUE XT_CONTINUE
+#define ARPT_RETURN XT_RETURN
+#define arpt_counters_info xt_counters_info
+#define arpt_counters xt_counters
+#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET
+#define ARPT_ERROR_TARGET XT_ERROR_TARGET
+#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \
+ XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args)
+#endif
#define ARPT_DEV_ADDR_LEN_MAX 16
@@ -63,9 +76,6 @@ struct arpt_arp {
u_int16_t invflags;
};
-#define arpt_entry_target xt_entry_target
-#define arpt_standard_target xt_standard_target
-
/* Values for "flag" field in struct arpt_ip (general arp structure).
* No flags defined yet.
*/
@@ -125,16 +135,10 @@ struct arpt_entry
#define ARPT_SO_GET_REVISION_TARGET (ARPT_BASE_CTL + 3)
#define ARPT_SO_GET_MAX (ARPT_SO_GET_REVISION_TARGET)
-/* CONTINUE verdict for targets */
-#define ARPT_CONTINUE XT_CONTINUE
-
-/* For standard target */
-#define ARPT_RETURN XT_RETURN
-
/* The argument to ARPT_SO_GET_INFO */
struct arpt_getinfo {
/* Which table: caller fills this in. */
- char name[ARPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
/* Kernel fills these in. */
/* Which hook entry points are valid: bitmask */
@@ -156,7 +160,7 @@ struct arpt_getinfo {
/* The argument to ARPT_SO_SET_REPLACE. */
struct arpt_replace {
/* Which table. */
- char name[ARPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
/* Which hook entry points are valid: bitmask. You can't
change this. */
@@ -184,14 +188,10 @@ struct arpt_replace {
struct arpt_entry entries[0];
};
-/* The argument to ARPT_SO_ADD_COUNTERS. */
-#define arpt_counters_info xt_counters_info
-#define arpt_counters xt_counters
-
/* The argument to ARPT_SO_GET_ENTRIES. */
struct arpt_get_entries {
/* Which table: user fills this in. */
- char name[ARPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
/* User fills this in: total entry size. */
unsigned int size;
@@ -200,23 +200,12 @@ struct arpt_get_entries {
struct arpt_entry entrytable[0];
};
-/* Standard return verdict, or do jump. */
-#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET
-/* Error verdict. */
-#define ARPT_ERROR_TARGET XT_ERROR_TARGET
-
/* Helper functions */
-static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e)
+static __inline__ struct xt_entry_target *arpt_get_target(struct arpt_entry *e)
{
return (void *)e + e->target_offset;
}
-#ifndef __KERNEL__
-/* fn returns 0 to continue iteration */
-#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \
- XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args)
-#endif
-
/*
* Main firewall chains definitions and global var's definitions.
*/
@@ -225,17 +214,12 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e
/* Standard entry. */
struct arpt_standard {
struct arpt_entry entry;
- struct arpt_standard_target target;
-};
-
-struct arpt_error_target {
- struct arpt_entry_target target;
- char errorname[ARPT_FUNCTION_MAXNAMELEN];
+ struct xt_standard_target target;
};
struct arpt_error {
struct arpt_entry entry;
- struct arpt_error_target target;
+ struct xt_error_target target;
};
#define ARPT_ENTRY_INIT(__size) \
@@ -247,16 +231,16 @@ struct arpt_error {
#define ARPT_STANDARD_INIT(__verdict) \
{ \
.entry = ARPT_ENTRY_INIT(sizeof(struct arpt_standard)), \
- .target = XT_TARGET_INIT(ARPT_STANDARD_TARGET, \
- sizeof(struct arpt_standard_target)), \
+ .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \
+ sizeof(struct xt_standard_target)), \
.target.verdict = -(__verdict) - 1, \
}
#define ARPT_ERROR_INIT \
{ \
.entry = ARPT_ENTRY_INIT(sizeof(struct arpt_error)), \
- .target = XT_TARGET_INIT(ARPT_ERROR_TARGET, \
- sizeof(struct arpt_error_target)), \
+ .target = XT_TARGET_INIT(XT_ERROR_TARGET, \
+ sizeof(struct xt_error_target)), \
.target.errorname = "ERROR", \
}
@@ -271,8 +255,6 @@ extern unsigned int arpt_do_table(struct sk_buff *skb,
const struct net_device *out,
struct xt_table *table);
-#define ARPT_ALIGN(s) XT_ALIGN(s)
-
#ifdef CONFIG_COMPAT
#include <net/compat.h>
@@ -285,14 +267,12 @@ struct compat_arpt_entry {
unsigned char elems[0];
};
-static inline struct arpt_entry_target *
+static inline struct xt_entry_target *
compat_arpt_get_target(struct compat_arpt_entry *e)
{
return (void *)e + e->target_offset;
}
-#define COMPAT_ARPT_ALIGN(s) COMPAT_XT_ALIGN(s)
-
#endif /* CONFIG_COMPAT */
#endif /*__KERNEL__*/
#endif /* _ARPTABLES_H */
diff --git a/include/linux/netfilter_bridge/Kbuild b/include/linux/netfilter_bridge/Kbuild
index d4d78672873e..e48f1a3f5a4a 100644
--- a/include/linux/netfilter_bridge/Kbuild
+++ b/include/linux/netfilter_bridge/Kbuild
@@ -3,11 +3,13 @@ header-y += ebt_among.h
header-y += ebt_arp.h
header-y += ebt_arpreply.h
header-y += ebt_ip.h
+header-y += ebt_ip6.h
header-y += ebt_limit.h
header-y += ebt_log.h
header-y += ebt_mark_m.h
header-y += ebt_mark_t.h
header-y += ebt_nat.h
+header-y += ebt_nflog.h
header-y += ebt_pkttype.h
header-y += ebt_redirect.h
header-y += ebt_stp.h
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index 704a7b6e8169..64a5d95c58e8 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -27,12 +27,49 @@
#include <linux/netfilter/x_tables.h>
+#ifndef __KERNEL__
#define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
#define IPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
#define ipt_match xt_match
#define ipt_target xt_target
#define ipt_table xt_table
#define ipt_get_revision xt_get_revision
+#define ipt_entry_match xt_entry_match
+#define ipt_entry_target xt_entry_target
+#define ipt_standard_target xt_standard_target
+#define ipt_error_target xt_error_target
+#define ipt_counters xt_counters
+#define IPT_CONTINUE XT_CONTINUE
+#define IPT_RETURN XT_RETURN
+
+/* This group is older than old (iptables < v1.4.0-rc1~89) */
+#include <linux/netfilter/xt_tcpudp.h>
+#define ipt_udp xt_udp
+#define ipt_tcp xt_tcp
+#define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT
+#define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT
+#define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS
+#define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION
+#define IPT_TCP_INV_MASK XT_TCP_INV_MASK
+#define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT
+#define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT
+#define IPT_UDP_INV_MASK XT_UDP_INV_MASK
+
+/* The argument to IPT_SO_ADD_COUNTERS. */
+#define ipt_counters_info xt_counters_info
+/* Standard return verdict, or do jump. */
+#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
+/* Error verdict. */
+#define IPT_ERROR_TARGET XT_ERROR_TARGET
+
+/* fn returns 0 to continue iteration */
+#define IPT_MATCH_ITERATE(e, fn, args...) \
+ XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args)
+
+/* fn returns 0 to continue iteration */
+#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
+ XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
+#endif
/* Yes, Virginia, you have to zero the padding. */
struct ipt_ip {
@@ -52,12 +89,6 @@ struct ipt_ip {
u_int8_t invflags;
};
-#define ipt_entry_match xt_entry_match
-#define ipt_entry_target xt_entry_target
-#define ipt_standard_target xt_standard_target
-
-#define ipt_counters xt_counters
-
/* Values for "flag" field in struct ipt_ip (general ip structure). */
#define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */
#define IPT_F_GOTO 0x02 /* Set if jump is a goto */
@@ -116,23 +147,6 @@ struct ipt_entry {
#define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3)
#define IPT_SO_GET_MAX IPT_SO_GET_REVISION_TARGET
-#define IPT_CONTINUE XT_CONTINUE
-#define IPT_RETURN XT_RETURN
-
-#include <linux/netfilter/xt_tcpudp.h>
-#define ipt_udp xt_udp
-#define ipt_tcp xt_tcp
-
-#define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT
-#define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT
-#define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS
-#define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION
-#define IPT_TCP_INV_MASK XT_TCP_INV_MASK
-
-#define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT
-#define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT
-#define IPT_UDP_INV_MASK XT_UDP_INV_MASK
-
/* ICMP matching stuff */
struct ipt_icmp {
u_int8_t type; /* type to match */
@@ -146,7 +160,7 @@ struct ipt_icmp {
/* The argument to IPT_SO_GET_INFO */
struct ipt_getinfo {
/* Which table: caller fills this in. */
- char name[IPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
/* Kernel fills these in. */
/* Which hook entry points are valid: bitmask */
@@ -168,7 +182,7 @@ struct ipt_getinfo {
/* The argument to IPT_SO_SET_REPLACE. */
struct ipt_replace {
/* Which table. */
- char name[IPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
/* Which hook entry points are valid: bitmask. You can't
change this. */
@@ -196,13 +210,10 @@ struct ipt_replace {
struct ipt_entry entries[0];
};
-/* The argument to IPT_SO_ADD_COUNTERS. */
-#define ipt_counters_info xt_counters_info
-
/* The argument to IPT_SO_GET_ENTRIES. */
struct ipt_get_entries {
/* Which table: user fills this in. */
- char name[IPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
/* User fills this in: total entry size. */
unsigned int size;
@@ -211,28 +222,13 @@ struct ipt_get_entries {
struct ipt_entry entrytable[0];
};
-/* Standard return verdict, or do jump. */
-#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
-/* Error verdict. */
-#define IPT_ERROR_TARGET XT_ERROR_TARGET
-
/* Helper functions */
-static __inline__ struct ipt_entry_target *
+static __inline__ struct xt_entry_target *
ipt_get_target(struct ipt_entry *e)
{
return (void *)e + e->target_offset;
}
-#ifndef __KERNEL__
-/* fn returns 0 to continue iteration */
-#define IPT_MATCH_ITERATE(e, fn, args...) \
- XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args)
-
-/* fn returns 0 to continue iteration */
-#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
- XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
-#endif
-
/*
* Main firewall chains definitions and global var's definitions.
*/
@@ -249,17 +245,12 @@ extern void ipt_unregister_table(struct net *net, struct xt_table *table);
/* Standard entry. */
struct ipt_standard {
struct ipt_entry entry;
- struct ipt_standard_target target;
-};
-
-struct ipt_error_target {
- struct ipt_entry_target target;
- char errorname[IPT_FUNCTION_MAXNAMELEN];
+ struct xt_standard_target target;
};
struct ipt_error {
struct ipt_entry entry;
- struct ipt_error_target target;
+ struct xt_error_target target;
};
#define IPT_ENTRY_INIT(__size) \
@@ -271,7 +262,7 @@ struct ipt_error {
#define IPT_STANDARD_INIT(__verdict) \
{ \
.entry = IPT_ENTRY_INIT(sizeof(struct ipt_standard)), \
- .target = XT_TARGET_INIT(IPT_STANDARD_TARGET, \
+ .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \
sizeof(struct xt_standard_target)), \
.target.verdict = -(__verdict) - 1, \
}
@@ -279,8 +270,8 @@ struct ipt_error {
#define IPT_ERROR_INIT \
{ \
.entry = IPT_ENTRY_INIT(sizeof(struct ipt_error)), \
- .target = XT_TARGET_INIT(IPT_ERROR_TARGET, \
- sizeof(struct ipt_error_target)), \
+ .target = XT_TARGET_INIT(XT_ERROR_TARGET, \
+ sizeof(struct xt_error_target)), \
.target.errorname = "ERROR", \
}
@@ -291,8 +282,6 @@ extern unsigned int ipt_do_table(struct sk_buff *skb,
const struct net_device *out,
struct xt_table *table);
-#define IPT_ALIGN(s) XT_ALIGN(s)
-
#ifdef CONFIG_COMPAT
#include <net/compat.h>
@@ -307,14 +296,12 @@ struct compat_ipt_entry {
};
/* Helper functions */
-static inline struct ipt_entry_target *
+static inline struct xt_entry_target *
compat_ipt_get_target(struct compat_ipt_entry *e)
{
return (void *)e + e->target_offset;
}
-#define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s)
-
#endif /* CONFIG_COMPAT */
#endif /*__KERNEL__*/
#endif /* _IPTABLES_H */
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 18442ff19c07..c9784f7a9c1f 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -27,13 +27,42 @@
#include <linux/netfilter/x_tables.h>
+#ifndef __KERNEL__
#define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
#define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
-
#define ip6t_match xt_match
#define ip6t_target xt_target
#define ip6t_table xt_table
#define ip6t_get_revision xt_get_revision
+#define ip6t_entry_match xt_entry_match
+#define ip6t_entry_target xt_entry_target
+#define ip6t_standard_target xt_standard_target
+#define ip6t_error_target xt_error_target
+#define ip6t_counters xt_counters
+#define IP6T_CONTINUE XT_CONTINUE
+#define IP6T_RETURN XT_RETURN
+
+/* Pre-iptables-1.4.0 */
+#include <linux/netfilter/xt_tcpudp.h>
+#define ip6t_tcp xt_tcp
+#define ip6t_udp xt_udp
+#define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT
+#define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT
+#define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS
+#define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION
+#define IP6T_TCP_INV_MASK XT_TCP_INV_MASK
+#define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT
+#define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT
+#define IP6T_UDP_INV_MASK XT_UDP_INV_MASK
+
+#define ip6t_counters_info xt_counters_info
+#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET
+#define IP6T_ERROR_TARGET XT_ERROR_TARGET
+#define IP6T_MATCH_ITERATE(e, fn, args...) \
+ XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args)
+#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \
+ XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args)
+#endif
/* Yes, Virginia, you have to zero the padding. */
struct ip6t_ip6 {
@@ -62,12 +91,6 @@ struct ip6t_ip6 {
u_int8_t invflags;
};
-#define ip6t_entry_match xt_entry_match
-#define ip6t_entry_target xt_entry_target
-#define ip6t_standard_target xt_standard_target
-
-#define ip6t_counters xt_counters
-
/* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */
#define IP6T_F_PROTO 0x01 /* Set if rule cares about upper
protocols */
@@ -112,17 +135,12 @@ struct ip6t_entry {
/* Standard entry */
struct ip6t_standard {
struct ip6t_entry entry;
- struct ip6t_standard_target target;
-};
-
-struct ip6t_error_target {
- struct ip6t_entry_target target;
- char errorname[IP6T_FUNCTION_MAXNAMELEN];
+ struct xt_standard_target target;
};
struct ip6t_error {
struct ip6t_entry entry;
- struct ip6t_error_target target;
+ struct xt_error_target target;
};
#define IP6T_ENTRY_INIT(__size) \
@@ -134,16 +152,16 @@ struct ip6t_error {
#define IP6T_STANDARD_INIT(__verdict) \
{ \
.entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)), \
- .target = XT_TARGET_INIT(IP6T_STANDARD_TARGET, \
- sizeof(struct ip6t_standard_target)), \
+ .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \
+ sizeof(struct xt_standard_target)), \
.target.verdict = -(__verdict) - 1, \
}
#define IP6T_ERROR_INIT \
{ \
.entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_error)), \
- .target = XT_TARGET_INIT(IP6T_ERROR_TARGET, \
- sizeof(struct ip6t_error_target)), \
+ .target = XT_TARGET_INIT(XT_ERROR_TARGET, \
+ sizeof(struct xt_error_target)), \
.target.errorname = "ERROR", \
}
@@ -166,30 +184,6 @@ struct ip6t_error {
#define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 5)
#define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET
-/* CONTINUE verdict for targets */
-#define IP6T_CONTINUE XT_CONTINUE
-
-/* For standard target */
-#define IP6T_RETURN XT_RETURN
-
-/* TCP/UDP matching stuff */
-#include <linux/netfilter/xt_tcpudp.h>
-
-#define ip6t_tcp xt_tcp
-#define ip6t_udp xt_udp
-
-/* Values for "inv" field in struct ipt_tcp. */
-#define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT
-#define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT
-#define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS
-#define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION
-#define IP6T_TCP_INV_MASK XT_TCP_INV_MASK
-
-/* Values for "invflags" field in struct ipt_udp. */
-#define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT
-#define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT
-#define IP6T_UDP_INV_MASK XT_UDP_INV_MASK
-
/* ICMP matching stuff */
struct ip6t_icmp {
u_int8_t type; /* type to match */
@@ -203,7 +197,7 @@ struct ip6t_icmp {
/* The argument to IP6T_SO_GET_INFO */
struct ip6t_getinfo {
/* Which table: caller fills this in. */
- char name[IP6T_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
/* Kernel fills these in. */
/* Which hook entry points are valid: bitmask */
@@ -225,7 +219,7 @@ struct ip6t_getinfo {
/* The argument to IP6T_SO_SET_REPLACE. */
struct ip6t_replace {
/* Which table. */
- char name[IP6T_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
/* Which hook entry points are valid: bitmask. You can't
change this. */
@@ -253,13 +247,10 @@ struct ip6t_replace {
struct ip6t_entry entries[0];
};
-/* The argument to IP6T_SO_ADD_COUNTERS. */
-#define ip6t_counters_info xt_counters_info
-
/* The argument to IP6T_SO_GET_ENTRIES. */
struct ip6t_get_entries {
/* Which table: user fills this in. */
- char name[IP6T_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
/* User fills this in: total entry size. */
unsigned int size;
@@ -268,28 +259,13 @@ struct ip6t_get_entries {
struct ip6t_entry entrytable[0];
};
-/* Standard return verdict, or do jump. */
-#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET
-/* Error verdict. */
-#define IP6T_ERROR_TARGET XT_ERROR_TARGET
-
/* Helper functions */
-static __inline__ struct ip6t_entry_target *
+static __inline__ struct xt_entry_target *
ip6t_get_target(struct ip6t_entry *e)
{
return (void *)e + e->target_offset;
}
-#ifndef __KERNEL__
-/* fn returns 0 to continue iteration */
-#define IP6T_MATCH_ITERATE(e, fn, args...) \
- XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args)
-
-/* fn returns 0 to continue iteration */
-#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \
- XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args)
-#endif
-
/*
* Main firewall chains definitions and global var's definitions.
*/
@@ -316,8 +292,6 @@ extern int ip6t_ext_hdr(u8 nexthdr);
extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
int target, unsigned short *fragoff);
-#define IP6T_ALIGN(s) XT_ALIGN(s)
-
#ifdef CONFIG_COMPAT
#include <net/compat.h>
@@ -331,14 +305,12 @@ struct compat_ip6t_entry {
unsigned char elems[0];
};
-static inline struct ip6t_entry_target *
+static inline struct xt_entry_target *
compat_ip6t_get_target(struct compat_ip6t_entry *e)
{
return (void *)e + e->target_offset;
}
-#define COMPAT_IP6T_ALIGN(s) COMPAT_XT_ALIGN(s)
-
#endif /* CONFIG_COMPAT */
#endif /*__KERNEL__*/
#endif /* _IP6_TABLES_H */
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index 50d8009be86c..79358bb712c6 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -14,7 +14,6 @@
struct netpoll {
struct net_device *dev;
- struct net_device *real_dev;
char dev_name[IFNAMSIZ];
const char *name;
void (*rx_hook)(struct netpoll *, int, char *, int);
@@ -53,7 +52,13 @@ void netpoll_set_trap(int trap);
void __netpoll_cleanup(struct netpoll *np);
void netpoll_cleanup(struct netpoll *np);
int __netpoll_rx(struct sk_buff *skb);
-void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
+void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
+ struct net_device *dev);
+static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
+{
+ netpoll_send_skb_on_dev(np, skb, np->dev);
+}
+
#ifdef CONFIG_NETPOLL
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 2c8701687336..0edb2566c14c 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -40,6 +40,43 @@
*/
/**
+ * DOC: Frame transmission/registration support
+ *
+ * Frame transmission and registration support exists to allow userspace
+ * management entities such as wpa_supplicant react to management frames
+ * that are not being handled by the kernel. This includes, for example,
+ * certain classes of action frames that cannot be handled in the kernel
+ * for various reasons.
+ *
+ * Frame registration is done on a per-interface basis and registrations
+ * cannot be removed other than by closing the socket. It is possible to
+ * specify a registration filter to register, for example, only for a
+ * certain type of action frame. In particular with action frames, those
+ * that userspace registers for will not be returned as unhandled by the
+ * driver, so that the registered application has to take responsibility
+ * for doing that.
+ *
+ * The type of frame that can be registered for is also dependent on the
+ * driver and interface type. The frame types are advertised in wiphy
+ * attributes so applications know what to expect.
+ *
+ * NOTE: When an interface changes type while registrations are active,
+ * these registrations are ignored until the interface type is
+ * changed again. This means that changing the interface type can
+ * lead to a situation that couldn't otherwise be produced, but
+ * any such registrations will be dormant in the sense that they
+ * will not be serviced, i.e. they will not receive any frames.
+ *
+ * Frame transmission allows userspace to send for example the required
+ * responses to action frames. It is subject to some sanity checking,
+ * but many frames can be transmitted. When a frame was transmitted, its
+ * status is indicated to the sending socket.
+ *
+ * For more technical details, see the corresponding command descriptions
+ * below.
+ */
+
+/**
* enum nl80211_commands - supported nl80211 commands
*
* @NL80211_CMD_UNSPEC: unspecified command to catch errors
@@ -258,7 +295,9 @@
* auth and assoc steps. For this, you need to specify the SSID in a
* %NL80211_ATTR_SSID attribute, and can optionally specify the association
* IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC,
- * %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_CONTROL_PORT.
+ * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
+ * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and
+ * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT.
* It is also sent as an event, with the BSSID and response IEs when the
* connection is established or failed to be established. This can be
* determined by the STATUS_CODE attribute.
@@ -276,8 +315,8 @@
* channel for the specified amount of time. This can be used to do
* off-channel operations like transmit a Public Action frame and wait for
* a response while being associated to an AP on another channel.
- * %NL80211_ATTR_WIPHY or %NL80211_ATTR_IFINDEX is used to specify which
- * radio is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the
+ * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus
+ * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the
* frequency for the operation and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be
* optionally used to specify additional channel parameters.
* %NL80211_ATTR_DURATION is used to specify the duration in milliseconds
@@ -301,16 +340,20 @@
* rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface
* and @NL80211_ATTR_TX_RATES the set of allowed rates.
*
- * @NL80211_CMD_REGISTER_ACTION: Register for receiving certain action frames
- * (via @NL80211_CMD_ACTION) for processing in userspace. This command
- * requires an interface index and a match attribute containing the first
- * few bytes of the frame that should match, e.g. a single byte for only
- * a category match or four bytes for vendor frames including the OUI.
- * The registration cannot be dropped, but is removed automatically
- * when the netlink socket is closed. Multiple registrations can be made.
- * @NL80211_CMD_ACTION: Action frame TX request and RX notification. This
- * command is used both as a request to transmit an Action frame and as an
- * event indicating reception of an Action frame that was not processed in
+ * @NL80211_CMD_REGISTER_FRAME: Register for receiving certain mgmt frames
+ * (via @NL80211_CMD_FRAME) for processing in userspace. This command
+ * requires an interface index, a frame type attribute (optional for
+ * backward compatibility reasons, if not given assumes action frames)
+ * and a match attribute containing the first few bytes of the frame
+ * that should match, e.g. a single byte for only a category match or
+ * four bytes for vendor frames including the OUI. The registration
+ * cannot be dropped, but is removed automatically when the netlink
+ * socket is closed. Multiple registrations can be made.
+ * @NL80211_CMD_REGISTER_ACTION: Alias for @NL80211_CMD_REGISTER_FRAME for
+ * backward compatibility
+ * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This
+ * command is used both as a request to transmit a management frame and
+ * as an event indicating reception of a frame that was not processed in
* kernel code, but is for us (i.e., which may need to be processed in a
* user space application). %NL80211_ATTR_FRAME is used to specify the
* frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and
@@ -320,11 +363,14 @@
* operational channel). When called, this operation returns a cookie
* (%NL80211_ATTR_COOKIE) that will be included with the TX status event
* pertaining to the TX request.
- * @NL80211_CMD_ACTION_TX_STATUS: Report TX status of an Action frame
- * transmitted with %NL80211_CMD_ACTION. %NL80211_ATTR_COOKIE identifies
+ * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility.
+ * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame
+ * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies
* the TX command and %NL80211_ATTR_FRAME includes the contents of the
* frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged
* the frame.
+ * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for
+ * backward compatibility.
* @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command
* is used to configure connection quality monitoring notification trigger
* levels.
@@ -341,6 +387,8 @@
* of any other interfaces, and other interfaces will again take
* precedence when they are used.
*
+ * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -429,9 +477,12 @@ enum nl80211_commands {
NL80211_CMD_SET_TX_BITRATE_MASK,
- NL80211_CMD_REGISTER_ACTION,
- NL80211_CMD_ACTION,
- NL80211_CMD_ACTION_TX_STATUS,
+ NL80211_CMD_REGISTER_FRAME,
+ NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME,
+ NL80211_CMD_FRAME,
+ NL80211_CMD_ACTION = NL80211_CMD_FRAME,
+ NL80211_CMD_FRAME_TX_STATUS,
+ NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS,
NL80211_CMD_SET_POWER_SAVE,
NL80211_CMD_GET_POWER_SAVE,
@@ -440,6 +491,7 @@ enum nl80211_commands {
NL80211_CMD_NOTIFY_CQM,
NL80211_CMD_SET_CHANNEL,
+ NL80211_CMD_SET_WDS_PEER,
/* add new commands above here */
@@ -639,6 +691,15 @@ enum nl80211_commands {
* request, the driver will assume that the port is unauthorized until
* authorized by user space. Otherwise, port is marked authorized by
* default in station mode.
+ * @NL80211_ATTR_CONTROL_PORT_ETHERTYPE: A 16-bit value indicating the
+ * ethertype that will be used for key negotiation. It can be
+ * specified with the associate and connect commands. If it is not
+ * specified, the value defaults to 0x888E (PAE, 802.1X). This
+ * attribute is also used as a flag in the wiphy information to
+ * indicate that protocols other than PAE are supported.
+ * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with
+ * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom
+ * ethertype frames used for key negotiation must not be encrypted.
*
* @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
* We recommend using nested, driver-specific attributes within this.
@@ -708,7 +769,16 @@ enum nl80211_commands {
* is used with %NL80211_CMD_SET_TX_BITRATE_MASK.
*
* @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain
- * at least one byte, currently used with @NL80211_CMD_REGISTER_ACTION.
+ * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME.
+ * @NL80211_ATTR_FRAME_TYPE: A u16 indicating the frame type/subtype for the
+ * @NL80211_CMD_REGISTER_FRAME command.
+ * @NL80211_ATTR_TX_FRAME_TYPES: wiphy capability attribute, which is a
+ * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing
+ * information about which frame types can be transmitted with
+ * %NL80211_CMD_FRAME.
+ * @NL80211_ATTR_RX_FRAME_TYPES: wiphy capability attribute, which is a
+ * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing
+ * information about which frame types can be registered for RX.
*
* @NL80211_ATTR_ACK: Flag attribute indicating that the frame was
* acknowledged by the recipient.
@@ -731,6 +801,9 @@ enum nl80211_commands {
* This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING
* for non-automatic settings.
*
+ * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly
+ * means support for per-station GTKs.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -891,6 +964,15 @@ enum nl80211_attrs {
NL80211_ATTR_WIPHY_TX_POWER_SETTING,
NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
+ NL80211_ATTR_TX_FRAME_TYPES,
+ NL80211_ATTR_RX_FRAME_TYPES,
+ NL80211_ATTR_FRAME_TYPE,
+
+ NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
+ NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT,
+
+ NL80211_ATTR_SUPPORT_IBSS_RSN,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -946,8 +1028,10 @@ enum nl80211_attrs {
* @NL80211_IFTYPE_WDS: wireless distribution interface
* @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames
* @NL80211_IFTYPE_MESH_POINT: mesh point
+ * @NL80211_IFTYPE_P2P_CLIENT: P2P client
+ * @NL80211_IFTYPE_P2P_GO: P2P group owner
* @NL80211_IFTYPE_MAX: highest interface type number currently defined
- * @__NL80211_IFTYPE_AFTER_LAST: internal use
+ * @NUM_NL80211_IFTYPES: number of defined interface types
*
* These values are used with the %NL80211_ATTR_IFTYPE
* to set the type of an interface.
@@ -962,10 +1046,12 @@ enum nl80211_iftype {
NL80211_IFTYPE_WDS,
NL80211_IFTYPE_MONITOR,
NL80211_IFTYPE_MESH_POINT,
+ NL80211_IFTYPE_P2P_CLIENT,
+ NL80211_IFTYPE_P2P_GO,
/* keep last */
- __NL80211_IFTYPE_AFTER_LAST,
- NL80211_IFTYPE_MAX = __NL80211_IFTYPE_AFTER_LAST - 1
+ NUM_NL80211_IFTYPES,
+ NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
};
/**
@@ -974,11 +1060,14 @@ enum nl80211_iftype {
* Station flags. When a station is added to an AP interface, it is
* assumed to be already associated (and hence authenticated.)
*
+ * @__NL80211_STA_FLAG_INVALID: attribute number 0 is reserved
* @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X)
* @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
* with short barker preamble
* @NL80211_STA_FLAG_WME: station is WME/QoS capable
* @NL80211_STA_FLAG_MFP: station uses management frame protection
+ * @NL80211_STA_FLAG_MAX: highest station flag number currently defined
+ * @__NL80211_STA_FLAG_AFTER_LAST: internal use
*/
enum nl80211_sta_flags {
__NL80211_STA_FLAG_INVALID,
@@ -1048,6 +1137,8 @@ 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)
+ * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station)
+ * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station)
*/
enum nl80211_sta_info {
__NL80211_STA_INFO_INVALID,
@@ -1061,6 +1152,8 @@ enum nl80211_sta_info {
NL80211_STA_INFO_TX_BITRATE,
NL80211_STA_INFO_RX_PACKETS,
NL80211_STA_INFO_TX_PACKETS,
+ NL80211_STA_INFO_TX_RETRIES,
+ NL80211_STA_INFO_TX_FAILED,
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
@@ -1091,14 +1184,17 @@ enum nl80211_mpath_flags {
* information about a mesh path.
*
* @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved
- * @NL80211_ATTR_MPATH_FRAME_QLEN: number of queued frames for this destination
- * @NL80211_ATTR_MPATH_SN: destination sequence number
- * @NL80211_ATTR_MPATH_METRIC: metric (cost) of this mesh path
- * @NL80211_ATTR_MPATH_EXPTIME: expiration time for the path, in msec from now
- * @NL80211_ATTR_MPATH_FLAGS: mesh path flags, enumerated in
+ * @NL80211_MPATH_INFO_FRAME_QLEN: number of queued frames for this destination
+ * @NL80211_MPATH_INFO_SN: destination sequence number
+ * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path
+ * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now
+ * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in
* &enum nl80211_mpath_flags;
- * @NL80211_ATTR_MPATH_DISCOVERY_TIMEOUT: total path discovery timeout, in msec
- * @NL80211_ATTR_MPATH_DISCOVERY_RETRIES: mesh path discovery retries
+ * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec
+ * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries
+ * @NL80211_MPATH_INFO_MAX: highest mesh path information attribute number
+ * currently defind
+ * @__NL80211_MPATH_INFO_AFTER_LAST: internal use
*/
enum nl80211_mpath_info {
__NL80211_MPATH_INFO_INVALID,
@@ -1127,6 +1223,8 @@ enum nl80211_mpath_info {
* @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
* @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
* @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
+ * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
+ * @__NL80211_BAND_ATTR_AFTER_LAST: internal use
*/
enum nl80211_band_attr {
__NL80211_BAND_ATTR_INVALID,
@@ -1147,6 +1245,7 @@ enum nl80211_band_attr {
/**
* enum nl80211_frequency_attr - frequency attributes
+ * @__NL80211_FREQUENCY_ATTR_INVALID: attribute number 0 is reserved
* @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
* @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current
* regulatory domain.
@@ -1158,6 +1257,9 @@ enum nl80211_band_attr {
* on this channel in current regulatory domain.
* @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
* (100 * dBm).
+ * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
+ * currently defined
+ * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
*/
enum nl80211_frequency_attr {
__NL80211_FREQUENCY_ATTR_INVALID,
@@ -1177,9 +1279,13 @@ enum nl80211_frequency_attr {
/**
* enum nl80211_bitrate_attr - bitrate attributes
+ * @__NL80211_BITRATE_ATTR_INVALID: attribute number 0 is reserved
* @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps
* @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported
* in 2.4 GHz band.
+ * @NL80211_BITRATE_ATTR_MAX: highest bitrate attribute number
+ * currently defined
+ * @__NL80211_BITRATE_ATTR_AFTER_LAST: internal use
*/
enum nl80211_bitrate_attr {
__NL80211_BITRATE_ATTR_INVALID,
@@ -1235,6 +1341,7 @@ enum nl80211_reg_type {
/**
* enum nl80211_reg_rule_attr - regulatory rule attributes
+ * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved
* @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional
* considerations for a given frequency range. These are the
* &enum nl80211_reg_rule_flags.
@@ -1251,6 +1358,9 @@ enum nl80211_reg_type {
* If you don't have one then don't send this.
* @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for
* a given frequency range. The value is in mBm (100 * dBm).
+ * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
+ * currently defined
+ * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
*/
enum nl80211_reg_rule_attr {
__NL80211_REG_RULE_ATTR_INVALID,
@@ -1302,11 +1412,31 @@ enum nl80211_reg_rule_flags {
* @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved
* @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel
* @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm)
+ * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio
+ * spent on this channel
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary
+ * channel was sensed busy (either due to activity or energy detect)
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension
+ * channel was sensed busy
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent
+ * receiving data
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent
+ * transmitting data
+ * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number
+ * currently defined
+ * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use
*/
enum nl80211_survey_info {
__NL80211_SURVEY_INFO_INVALID,
NL80211_SURVEY_INFO_FREQUENCY,
NL80211_SURVEY_INFO_NOISE,
+ NL80211_SURVEY_INFO_IN_USE,
+ NL80211_SURVEY_INFO_CHANNEL_TIME,
+ NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
+ NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
+ NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
+ NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
/* keep last */
__NL80211_SURVEY_INFO_AFTER_LAST,
@@ -1466,6 +1596,7 @@ enum nl80211_channel_type {
* enum nl80211_bss - netlink attributes for a BSS
*
* @__NL80211_BSS_INVALID: invalid
+ * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets)
* @NL80211_BSS_FREQUENCY: frequency in MHz (u32)
* @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64)
* @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16)
@@ -1509,6 +1640,12 @@ enum nl80211_bss {
/**
* enum nl80211_bss_status - BSS "status"
+ * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS.
+ * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS.
+ * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS.
+ *
+ * The BSS status is a BSS attribute in scan dumps, which
+ * indicates the status the interface has wrt. this BSS.
*/
enum nl80211_bss_status {
NL80211_BSS_STATUS_AUTHENTICATED,
@@ -1546,11 +1683,14 @@ enum nl80211_auth_type {
* @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key
* @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key
* @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS)
+ * @NUM_NL80211_KEYTYPES: number of defined key types
*/
enum nl80211_key_type {
NL80211_KEYTYPE_GROUP,
NL80211_KEYTYPE_PAIRWISE,
NL80211_KEYTYPE_PEERKEY,
+
+ NUM_NL80211_KEYTYPES
};
/**
@@ -1581,6 +1721,9 @@ enum nl80211_wpa_versions {
* CCMP keys, each six bytes in little endian
* @NL80211_KEY_DEFAULT: flag indicating default key
* @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key
+ * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not
+ * specified the default depends on whether a MAC address was
+ * given with the command using the key or not (u32)
* @__NL80211_KEY_AFTER_LAST: internal
* @NL80211_KEY_MAX: highest key attribute
*/
@@ -1592,6 +1735,7 @@ enum nl80211_key_attributes {
NL80211_KEY_SEQ,
NL80211_KEY_DEFAULT,
NL80211_KEY_DEFAULT_MGMT,
+ NL80211_KEY_TYPE,
/* keep last */
__NL80211_KEY_AFTER_LAST,
@@ -1619,8 +1763,8 @@ enum nl80211_tx_rate_attributes {
/**
* enum nl80211_band - Frequency band
- * @NL80211_BAND_2GHZ - 2.4 GHz ISM band
- * @NL80211_BAND_5GHZ - around 5 GHz band (4.9 - 5.7 GHz)
+ * @NL80211_BAND_2GHZ: 2.4 GHz ISM band
+ * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz)
*/
enum nl80211_band {
NL80211_BAND_2GHZ,
@@ -1658,9 +1802,9 @@ enum nl80211_attr_cqm {
/**
* enum nl80211_cqm_rssi_threshold_event - RSSI threshold event
- * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW - The RSSI level is lower than the
+ * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: The RSSI level is lower than the
* configured threshold
- * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH - The RSSI is higher than the
+ * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the
* configured threshold
*/
enum nl80211_cqm_rssi_threshold_event {
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index e4471b27c396..90c038c0ad96 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2194,6 +2194,9 @@
#define PCI_VENDOR_ID_ARIMA 0x161f
#define PCI_VENDOR_ID_BROCADE 0x1657
+#define PCI_DEVICE_ID_BROCADE_CT 0x0014
+#define PCI_DEVICE_ID_BROCADE_FC_8G1P 0x0017
+#define PCI_DEVICE_ID_BROCADE_CT_FC 0x0021
#define PCI_VENDOR_ID_SIBYTE 0x166d
#define PCI_DEVICE_ID_BCM1250_PCI 0x0001
diff --git a/include/linux/phonet.h b/include/linux/phonet.h
index 76edadf046d3..26c8df786918 100644
--- a/include/linux/phonet.h
+++ b/include/linux/phonet.h
@@ -36,6 +36,9 @@
/* Socket options for SOL_PNPIPE level */
#define PNPIPE_ENCAP 1
#define PNPIPE_IFINDEX 2
+#define PNPIPE_PIPE_HANDLE 3
+#define PNPIPE_ENABLE 4
+/* unused slot */
#define PNADDR_ANY 0
#define PNADDR_BROADCAST 0xFC
@@ -47,6 +50,8 @@
/* ioctls */
#define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0)
+#define SIOCPNADDRESOURCE (SIOCPROTOPRIVATE + 14)
+#define SIOCPNDELRESOURCE (SIOCPROTOPRIVATE + 15)
/* Phonet protocol header */
struct phonethdr {
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 6b0a782c6224..a6e047a04f79 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -116,7 +116,7 @@ struct mii_bus {
/* list of all PHYs on bus */
struct phy_device *phy_map[PHY_MAX_ADDR];
- /* Phy addresses to be ignored when probing */
+ /* PHY addresses to be ignored when probing */
u32 phy_mask;
/*
@@ -283,7 +283,7 @@ struct phy_device {
phy_interface_t interface;
- /* Bus address of the PHY (0-32) */
+ /* Bus address of the PHY (0-31) */
int addr;
/*
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index 7f6ba8658abe..defbde203d07 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -332,6 +332,7 @@ enum {
FLOW_KEY_SKUID,
FLOW_KEY_SKGID,
FLOW_KEY_VLAN_TAG,
+ FLOW_KEY_RXHASH,
__FLOW_KEY_MAX,
};
diff --git a/include/linux/rds.h b/include/linux/rds.h
index 24bce3ded9ea..91950950aa59 100644
--- a/include/linux/rds.h
+++ b/include/linux/rds.h
@@ -36,15 +36,6 @@
#include <linux/types.h>
-/* These sparse annotated types shouldn't be in any user
- * visible header file. We should clean this up rather
- * than kludging around them. */
-#ifndef __KERNEL__
-#define __be16 u_int16_t
-#define __be32 u_int32_t
-#define __be64 u_int64_t
-#endif
-
#define RDS_IB_ABI_VERSION 0x301
/*
@@ -82,6 +73,10 @@
#define RDS_CMSG_RDMA_MAP 3
#define RDS_CMSG_RDMA_STATUS 4
#define RDS_CMSG_CONG_UPDATE 5
+#define RDS_CMSG_ATOMIC_FADD 6
+#define RDS_CMSG_ATOMIC_CSWP 7
+#define RDS_CMSG_MASKED_ATOMIC_FADD 8
+#define RDS_CMSG_MASKED_ATOMIC_CSWP 9
#define RDS_INFO_FIRST 10000
#define RDS_INFO_COUNTERS 10000
@@ -98,9 +93,9 @@
#define RDS_INFO_LAST 10010
struct rds_info_counter {
- u_int8_t name[32];
- u_int64_t value;
-} __packed;
+ uint8_t name[32];
+ uint64_t value;
+} __attribute__((packed));
#define RDS_INFO_CONNECTION_FLAG_SENDING 0x01
#define RDS_INFO_CONNECTION_FLAG_CONNECTING 0x02
@@ -109,56 +104,48 @@ struct rds_info_counter {
#define TRANSNAMSIZ 16
struct rds_info_connection {
- u_int64_t next_tx_seq;
- u_int64_t next_rx_seq;
- __be32 laddr;
- __be32 faddr;
- u_int8_t transport[TRANSNAMSIZ]; /* null term ascii */
- u_int8_t flags;
-} __packed;
-
-struct rds_info_flow {
+ uint64_t next_tx_seq;
+ uint64_t next_rx_seq;
__be32 laddr;
__be32 faddr;
- u_int32_t bytes;
- __be16 lport;
- __be16 fport;
-} __packed;
+ uint8_t transport[TRANSNAMSIZ]; /* null term ascii */
+ uint8_t flags;
+} __attribute__((packed));
#define RDS_INFO_MESSAGE_FLAG_ACK 0x01
#define RDS_INFO_MESSAGE_FLAG_FAST_ACK 0x02
struct rds_info_message {
- u_int64_t seq;
- u_int32_t len;
+ uint64_t seq;
+ uint32_t len;
__be32 laddr;
__be32 faddr;
__be16 lport;
__be16 fport;
- u_int8_t flags;
-} __packed;
+ uint8_t flags;
+} __attribute__((packed));
struct rds_info_socket {
- u_int32_t sndbuf;
+ uint32_t sndbuf;
__be32 bound_addr;
__be32 connected_addr;
__be16 bound_port;
__be16 connected_port;
- u_int32_t rcvbuf;
- u_int64_t inum;
-} __packed;
+ uint32_t rcvbuf;
+ uint64_t inum;
+} __attribute__((packed));
struct rds_info_tcp_socket {
__be32 local_addr;
__be16 local_port;
__be32 peer_addr;
__be16 peer_port;
- u_int64_t hdr_rem;
- u_int64_t data_rem;
- u_int32_t last_sent_nxt;
- u_int32_t last_expected_una;
- u_int32_t last_seen_una;
-} __packed;
+ uint64_t hdr_rem;
+ uint64_t data_rem;
+ uint32_t last_sent_nxt;
+ uint32_t last_expected_una;
+ uint32_t last_seen_una;
+} __attribute__((packed));
#define RDS_IB_GID_LEN 16
struct rds_info_rdma_connection {
@@ -212,42 +199,69 @@ struct rds_info_rdma_connection {
* (so that the application does not have to worry about
* alignment).
*/
-typedef u_int64_t rds_rdma_cookie_t;
+typedef uint64_t rds_rdma_cookie_t;
struct rds_iovec {
- u_int64_t addr;
- u_int64_t bytes;
+ uint64_t addr;
+ uint64_t bytes;
};
struct rds_get_mr_args {
struct rds_iovec vec;
- u_int64_t cookie_addr;
+ uint64_t cookie_addr;
uint64_t flags;
};
struct rds_get_mr_for_dest_args {
struct sockaddr_storage dest_addr;
struct rds_iovec vec;
- u_int64_t cookie_addr;
+ uint64_t cookie_addr;
uint64_t flags;
};
struct rds_free_mr_args {
rds_rdma_cookie_t cookie;
- u_int64_t flags;
+ uint64_t flags;
};
struct rds_rdma_args {
rds_rdma_cookie_t cookie;
struct rds_iovec remote_vec;
- u_int64_t local_vec_addr;
- u_int64_t nr_local;
- u_int64_t flags;
- u_int64_t user_token;
+ uint64_t local_vec_addr;
+ uint64_t nr_local;
+ uint64_t flags;
+ uint64_t user_token;
+};
+
+struct rds_atomic_args {
+ rds_rdma_cookie_t cookie;
+ uint64_t local_addr;
+ uint64_t remote_addr;
+ union {
+ struct {
+ uint64_t compare;
+ uint64_t swap;
+ } cswp;
+ struct {
+ uint64_t add;
+ } fadd;
+ struct {
+ uint64_t compare;
+ uint64_t swap;
+ uint64_t compare_mask;
+ uint64_t swap_mask;
+ } m_cswp;
+ struct {
+ uint64_t add;
+ uint64_t nocarry_mask;
+ } m_fadd;
+ };
+ uint64_t flags;
+ uint64_t user_token;
};
struct rds_rdma_notify {
- u_int64_t user_token;
+ uint64_t user_token;
int32_t status;
};
@@ -266,5 +280,6 @@ struct rds_rdma_notify {
#define RDS_RDMA_USE_ONCE 0x0008 /* free MR after use */
#define RDS_RDMA_DONTWAIT 0x0010 /* Don't wait in SET_BARRIER */
#define RDS_RDMA_NOTIFY_ME 0x0020 /* Notify when operation completes */
+#define RDS_RDMA_SILENT 0x0040 /* Do not interrupt remote */
#endif /* IB_RDS_H */
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 58d44491880f..d42f274418b8 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -6,6 +6,7 @@
#include <linux/if_link.h>
#include <linux/if_addr.h>
#include <linux/neighbour.h>
+#include <linux/netdevice.h>
/* rtnetlink families. Values up to 127 are reserved for real address
* families, values above 128 may be used arbitrarily.
@@ -749,6 +750,35 @@ extern int rtnl_is_locked(void);
extern int lockdep_rtnl_is_held(void);
#endif /* #ifdef CONFIG_PROVE_LOCKING */
+/**
+ * rcu_dereference_rtnl - rcu_dereference with debug checking
+ * @p: The pointer to read, prior to dereferencing
+ *
+ * Do an rcu_dereference(p), but check caller either holds rcu_read_lock()
+ * or RTNL. Note : Please prefer rtnl_dereference() or rcu_dereference()
+ */
+#define rcu_dereference_rtnl(p) \
+ rcu_dereference_check(p, rcu_read_lock_held() || \
+ lockdep_rtnl_is_held())
+
+/**
+ * rtnl_dereference - fetch RCU pointer when updates are prevented by RTNL
+ * @p: The pointer to read, prior to dereferencing
+ *
+ * Return the value of the specified RCU-protected pointer, but omit
+ * both the smp_read_barrier_depends() and the ACCESS_ONCE(), because
+ * caller holds RTNL.
+ */
+#define rtnl_dereference(p) \
+ rcu_dereference_protected(p, lockdep_rtnl_is_held())
+
+static inline struct netdev_queue *dev_ingress_queue(struct net_device *dev)
+{
+ return rtnl_dereference(dev->ingress_queue);
+}
+
+extern struct netdev_queue *dev_ingress_queue_create(struct net_device *dev);
+
extern void rtnetlink_init(void);
extern void __rtnl_unlock(void);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 77eb60d2b496..e6ba898de61c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -129,8 +129,13 @@ typedef struct skb_frag_struct skb_frag_t;
struct skb_frag_struct {
struct page *page;
+#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
__u32 page_offset;
__u32 size;
+#else
+ __u16 page_offset;
+ __u16 size;
+#endif
};
#define HAVE_HW_TIME_STAMP
@@ -163,26 +168,19 @@ struct skb_shared_hwtstamps {
ktime_t syststamp;
};
-/**
- * struct skb_shared_tx - instructions for time stamping of outgoing packets
- * @hardware: generate hardware time stamp
- * @software: generate software time stamp
- * @in_progress: device driver is going to provide
- * hardware time stamp
- * @prevent_sk_orphan: make sk reference available on driver level
- * @flags: all shared_tx flags
- *
- * These flags are attached to packets as part of the
- * &skb_shared_info. Use skb_tx() to get a pointer.
- */
-union skb_shared_tx {
- struct {
- __u8 hardware:1,
- software:1,
- in_progress:1,
- prevent_sk_orphan:1;
- };
- __u8 flags;
+/* Definitions for tx_flags in struct skb_shared_info */
+enum {
+ /* generate hardware time stamp */
+ SKBTX_HW_TSTAMP = 1 << 0,
+
+ /* generate software time stamp */
+ SKBTX_SW_TSTAMP = 1 << 1,
+
+ /* device driver is going to provide hardware time stamp */
+ SKBTX_IN_PROGRESS = 1 << 2,
+
+ /* ensure the originating sk reference is available on driver level */
+ SKBTX_DRV_NEEDS_SK_REF = 1 << 3,
};
/* This data is invariant across clones and lives at
@@ -195,7 +193,7 @@ struct skb_shared_info {
unsigned short gso_segs;
unsigned short gso_type;
__be32 ip6_frag_id;
- union skb_shared_tx tx_flags;
+ __u8 tx_flags;
struct sk_buff *frag_list;
struct skb_shared_hwtstamps hwtstamps;
@@ -462,19 +460,7 @@ static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
skb->_skb_refdst = (unsigned long)dst;
}
-/**
- * skb_dst_set_noref - sets skb dst, without a reference
- * @skb: buffer
- * @dst: dst entry
- *
- * Sets skb dst, assuming a reference was not taken on dst
- * skb_dst_drop() should not dst_release() this dst
- */
-static inline void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst)
-{
- WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held());
- skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF;
-}
+extern void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst);
/**
* skb_dst_is_noref - Test if skb dst isnt refcounted
@@ -498,13 +484,13 @@ extern struct sk_buff *__alloc_skb(unsigned int size,
static inline struct sk_buff *alloc_skb(unsigned int size,
gfp_t priority)
{
- return __alloc_skb(size, priority, 0, -1);
+ return __alloc_skb(size, priority, 0, NUMA_NO_NODE);
}
static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
gfp_t priority)
{
- return __alloc_skb(size, priority, 1, -1);
+ return __alloc_skb(size, priority, 1, NUMA_NO_NODE);
}
extern bool skb_recycle_check(struct sk_buff *skb, int skb_size);
@@ -558,6 +544,15 @@ extern unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
unsigned int to, struct ts_config *config,
struct ts_state *state);
+extern __u32 __skb_get_rxhash(struct sk_buff *skb);
+static inline __u32 skb_get_rxhash(struct sk_buff *skb)
+{
+ if (!skb->rxhash)
+ skb->rxhash = __skb_get_rxhash(skb);
+
+ return skb->rxhash;
+}
+
#ifdef NET_SKBUFF_DATA_USES_OFFSET
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
{
@@ -578,11 +573,6 @@ static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb)
return &skb_shinfo(skb)->hwtstamps;
}
-static inline union skb_shared_tx *skb_tx(struct sk_buff *skb)
-{
- return &skb_shinfo(skb)->tx_flags;
-}
-
/**
* skb_queue_empty - check if a queue is empty
* @list: queue head
@@ -604,7 +594,7 @@ static inline int skb_queue_empty(const struct sk_buff_head *list)
static inline bool skb_queue_is_last(const struct sk_buff_head *list,
const struct sk_buff *skb)
{
- return (skb->next == (struct sk_buff *) list);
+ return skb->next == (struct sk_buff *)list;
}
/**
@@ -617,7 +607,7 @@ static inline bool skb_queue_is_last(const struct sk_buff_head *list,
static inline bool skb_queue_is_first(const struct sk_buff_head *list,
const struct sk_buff *skb)
{
- return (skb->prev == (struct sk_buff *) list);
+ return skb->prev == (struct sk_buff *)list;
}
/**
@@ -1123,7 +1113,7 @@ extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page,
int off, int size);
#define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags)
-#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_has_frags(skb))
+#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_has_frag_list(skb))
#define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb))
#ifdef NET_SKBUFF_DATA_USES_OFFSET
@@ -1561,13 +1551,25 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
return skb;
}
-extern struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask);
+/**
+ * __netdev_alloc_page - allocate a page for ps-rx on a specific device
+ * @dev: network device to receive on
+ * @gfp_mask: alloc_pages_node mask
+ *
+ * Allocate a new page. dev currently unused.
+ *
+ * %NULL is returned if there is no free memory.
+ */
+static inline struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask)
+{
+ return alloc_pages_node(NUMA_NO_NODE, gfp_mask, 0);
+}
/**
* netdev_alloc_page - allocate a page for ps-rx on a specific device
* @dev: network device to receive on
*
- * Allocate a new page node local to the specified device.
+ * Allocate a new page. dev currently unused.
*
* %NULL is returned if there is no free memory.
*/
@@ -1787,7 +1789,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
skb = skb->prev)
-static inline bool skb_has_frags(const struct sk_buff *skb)
+static inline bool skb_has_frag_list(const struct sk_buff *skb)
{
return skb_shinfo(skb)->frag_list != NULL;
}
@@ -1987,8 +1989,8 @@ extern void skb_tstamp_tx(struct sk_buff *orig_skb,
static inline void sw_tx_timestamp(struct sk_buff *skb)
{
- union skb_shared_tx *shtx = skb_tx(skb);
- if (shtx->software && !shtx->in_progress)
+ if (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP &&
+ !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
skb_tstamp_tx(skb, NULL);
}
@@ -2159,7 +2161,7 @@ static inline u16 skb_get_rx_queue(const struct sk_buff *skb)
static inline bool skb_rx_queue_recorded(const struct sk_buff *skb)
{
- return (skb->queue_mapping != 0);
+ return skb->queue_mapping != 0;
}
extern u16 skb_tx_hash(const struct net_device *dev,
@@ -2209,6 +2211,21 @@ static inline void skb_forward_csum(struct sk_buff *skb)
skb->ip_summed = CHECKSUM_NONE;
}
+/**
+ * skb_checksum_none_assert - make sure skb ip_summed is CHECKSUM_NONE
+ * @skb: skb to check
+ *
+ * fresh skbs have their ip_summed set to CHECKSUM_NONE.
+ * Instead of forcing ip_summed to CHECKSUM_NONE, we can
+ * use this helper, to document places where we make this assertion.
+ */
+static inline void skb_checksum_none_assert(struct sk_buff *skb)
+{
+#ifdef DEBUG
+ BUG_ON(skb->ip_summed != CHECKSUM_NONE);
+#endif
+}
+
bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off);
#endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */
diff --git a/include/linux/socket.h b/include/linux/socket.h
index a8f56e1ec760..5146b50202ce 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -326,7 +326,6 @@ extern long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *a
extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
int offset, int len);
-extern int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, int __user *ulen);
extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr);
extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index a6d5225b9275..11daf9c140e7 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -97,6 +97,7 @@
#define SSB_TMSLOW_RESET 0x00000001 /* Reset */
#define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */
#define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */
+#define SSB_TMSLOW_PHYCLK 0x00000010 /* MAC PHY Clock Control Enable */
#define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */
#define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */
#define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 632ff7c03280..d66c61774d95 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -32,10 +32,14 @@
struct plat_stmmacenet_data {
int bus_id;
int pbl;
+ int clk_csr;
int has_gmac;
int enh_desc;
+ int tx_coe;
+ int bugged_jumbo;
+ int pmt;
void (*fix_mac_speed)(void *priv, unsigned int speed);
- void (*bus_setup)(unsigned long ioaddr);
+ void (*bus_setup)(void __iomem *ioaddr);
#ifdef CONFIG_STM_DRIVERS
struct stm_pad_config *pad_config;
#endif
diff --git a/include/linux/tc_act/Kbuild b/include/linux/tc_act/Kbuild
index 76990937f4c9..67b501c302b2 100644
--- a/include/linux/tc_act/Kbuild
+++ b/include/linux/tc_act/Kbuild
@@ -4,3 +4,4 @@ header-y += tc_mirred.h
header-y += tc_pedit.h
header-y += tc_nat.h
header-y += tc_skbedit.h
+header-y += tc_csum.h
diff --git a/include/linux/tc_act/tc_csum.h b/include/linux/tc_act/tc_csum.h
new file mode 100644
index 000000000000..a047c49a3153
--- /dev/null
+++ b/include/linux/tc_act/tc_csum.h
@@ -0,0 +1,32 @@
+#ifndef __LINUX_TC_CSUM_H
+#define __LINUX_TC_CSUM_H
+
+#include <linux/types.h>
+#include <linux/pkt_cls.h>
+
+#define TCA_ACT_CSUM 16
+
+enum {
+ TCA_CSUM_UNSPEC,
+ TCA_CSUM_PARMS,
+ TCA_CSUM_TM,
+ __TCA_CSUM_MAX
+};
+#define TCA_CSUM_MAX (__TCA_CSUM_MAX - 1)
+
+enum {
+ TCA_CSUM_UPDATE_FLAG_IPV4HDR = 1,
+ TCA_CSUM_UPDATE_FLAG_ICMP = 2,
+ TCA_CSUM_UPDATE_FLAG_IGMP = 4,
+ TCA_CSUM_UPDATE_FLAG_TCP = 8,
+ TCA_CSUM_UPDATE_FLAG_UDP = 16,
+ TCA_CSUM_UPDATE_FLAG_UDPLITE = 32
+};
+
+struct tc_csum {
+ tc_gen;
+
+ __u32 update_flags;
+};
+
+#endif /* __LINUX_TC_CSUM_H */
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h
index 0864206ec1a3..7138962664f8 100644
--- a/include/linux/tc_ematch/tc_em_meta.h
+++ b/include/linux/tc_ematch/tc_em_meta.h
@@ -79,6 +79,7 @@ enum {
TCF_META_ID_SK_SENDMSG_OFF,
TCF_META_ID_SK_WRITE_PENDING,
TCF_META_ID_VLAN_TAG,
+ TCF_META_ID_RXHASH,
__TCF_META_ID_MAX
};
#define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1)
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index a778ee024590..e64f4c67d0ef 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -105,6 +105,7 @@ enum {
#define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */
#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/
#define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */
+#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
/* for TCP_INFO socket option */
#define TCPI_OPT_TIMESTAMPS 1
diff --git a/include/linux/tipc.h b/include/linux/tipc.h
index 181c8d0e6f73..d10614b29d59 100644
--- a/include/linux/tipc.h
+++ b/include/linux/tipc.h
@@ -127,17 +127,23 @@ static inline unsigned int tipc_node(__u32 addr)
* TIPC topology subscription service definitions
*/
-#define TIPC_SUB_SERVICE 0x00 /* Filter for service availability */
-#define TIPC_SUB_PORTS 0x01 /* Filter for port availability */
-#define TIPC_SUB_CANCEL 0x04 /* Cancel a subscription */
+#define TIPC_SUB_PORTS 0x01 /* filter for port availability */
+#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */
+#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */
+#if 0
+/* The following filter options are not currently implemented */
+#define TIPC_SUB_NO_BIND_EVTS 0x04 /* filter out "publish" events */
+#define TIPC_SUB_NO_UNBIND_EVTS 0x08 /* filter out "withdraw" events */
+#define TIPC_SUB_SINGLE_EVT 0x10 /* expire after first event */
+#endif
#define TIPC_WAIT_FOREVER ~0 /* timeout for permanent subscription */
struct tipc_subscr {
- struct tipc_name_seq seq; /* NBO. Name sequence of interest */
- __u32 timeout; /* NBO. Subscription duration (in ms) */
- __u32 filter; /* NBO. Bitmask of filter options */
- char usr_handle[8]; /* Opaque. Available for subscriber use */
+ struct tipc_name_seq seq; /* name sequence of interest */
+ __u32 timeout; /* subscription duration (in ms) */
+ __u32 filter; /* bitmask of filter options */
+ char usr_handle[8]; /* available for subscriber use */
};
#define TIPC_PUBLISHED 1 /* publication event */
@@ -145,11 +151,11 @@ struct tipc_subscr {
#define TIPC_SUBSCR_TIMEOUT 3 /* subscription timeout event */
struct tipc_event {
- __u32 event; /* NBO. Event type, as defined above */
- __u32 found_lower; /* NBO. Matching name seq instances */
- __u32 found_upper; /* " " " " " */
- struct tipc_portid port; /* NBO. Associated port */
- struct tipc_subscr s; /* Original, associated subscription */
+ __u32 event; /* event type */
+ __u32 found_lower; /* matching name seq instances */
+ __u32 found_upper; /* " " " " */
+ struct tipc_portid port; /* associated port */
+ struct tipc_subscr s; /* associated subscription */
};
/*
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index e6827eedf18b..4395b28bb86c 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1157,6 +1157,6 @@ struct __compat_iw_event {
#define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
#define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
#define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
-#define IW_EV_POINT_PK_LEN (IW_EV_LCP_LEN + 4)
+#define IW_EV_POINT_PK_LEN (IW_EV_LCP_PK_LEN + 4)
#endif /* _LINUX_WIRELESS_H */
diff --git a/include/linux/spi/wl12xx.h b/include/linux/wl12xx.h
index a223ecbc71ef..4f902e1908aa 100644
--- a/include/linux/spi/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -21,14 +21,31 @@
*
*/
-#ifndef _LINUX_SPI_WL12XX_H
-#define _LINUX_SPI_WL12XX_H
+#ifndef _LINUX_WL12XX_H
+#define _LINUX_WL12XX_H
struct wl12xx_platform_data {
void (*set_power)(bool enable);
/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
int irq;
bool use_eeprom;
+ int board_ref_clock;
};
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+
+int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
+
+#else
+
+static inline
+int wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
+{
+ return -ENOSYS;
+}
+
+#endif
+
+const struct wl12xx_platform_data *wl12xx_get_platform_data(void);
+
#endif
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index d1aa2cfb30f0..7f63d5ab7b44 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -212,15 +212,12 @@ struct p9_dirent {
int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb);
int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name);
-int p9_client_version(struct p9_client *);
struct p9_client *p9_client_create(const char *dev_name, char *options);
void p9_client_destroy(struct p9_client *clnt);
void p9_client_disconnect(struct p9_client *clnt);
void p9_client_begin_disconnect(struct p9_client *clnt);
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
char *uname, u32 n_uname, char *aname);
-struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname,
- u32 n_uname, char *aname);
struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
int clone);
int p9_client_open(struct p9_fid *fid, int mode);
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 4d40c4d0230b..a9441249306c 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -175,20 +175,32 @@ extern int ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
extern int register_inet6addr_notifier(struct notifier_block *nb);
extern int unregister_inet6addr_notifier(struct notifier_block *nb);
-static inline struct inet6_dev *
-__in6_dev_get(struct net_device *dev)
+/**
+ * __in6_dev_get - get inet6_dev pointer from netdevice
+ * @dev: network device
+ *
+ * Caller must hold rcu_read_lock or RTNL, because this function
+ * does not take a reference on the inet6_dev.
+ */
+static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev)
{
- return rcu_dereference_check(dev->ip6_ptr,
- rcu_read_lock_held() ||
- lockdep_rtnl_is_held());
+ return rcu_dereference_rtnl(dev->ip6_ptr);
}
-static inline struct inet6_dev *
-in6_dev_get(struct net_device *dev)
+/**
+ * in6_dev_get - get inet6_dev pointer from netdevice
+ * @dev: network device
+ *
+ * This version can be used in any context, and takes a reference
+ * on the inet6_dev. Callers must use in6_dev_put() later to
+ * release this reference.
+ */
+static inline struct inet6_dev *in6_dev_get(const struct net_device *dev)
{
- struct inet6_dev *idev = NULL;
+ struct inet6_dev *idev;
+
rcu_read_lock();
- idev = __in6_dev_get(dev);
+ idev = rcu_dereference(dev->ip6_ptr);
if (idev)
atomic_inc(&idev->refcnt);
rcu_read_unlock();
@@ -197,16 +209,21 @@ in6_dev_get(struct net_device *dev)
extern void in6_dev_finish_destroy(struct inet6_dev *idev);
-static inline void
-in6_dev_put(struct inet6_dev *idev)
+static inline void in6_dev_put(struct inet6_dev *idev)
{
if (atomic_dec_and_test(&idev->refcnt))
in6_dev_finish_destroy(idev);
}
-#define __in6_dev_put(idev) atomic_dec(&(idev)->refcnt)
-#define in6_dev_hold(idev) atomic_inc(&(idev)->refcnt)
+static inline void __in6_dev_put(struct inet6_dev *idev)
+{
+ atomic_dec(&idev->refcnt);
+}
+static inline void in6_dev_hold(struct inet6_dev *idev)
+{
+ atomic_inc(&idev->refcnt);
+}
extern void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);
@@ -216,9 +233,15 @@ static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
inet6_ifa_finish_destroy(ifp);
}
-#define __in6_ifa_put(ifp) atomic_dec(&(ifp)->refcnt)
-#define in6_ifa_hold(ifp) atomic_inc(&(ifp)->refcnt)
+static inline void __in6_ifa_put(struct inet6_ifaddr *ifp)
+{
+ atomic_dec(&ifp->refcnt);
+}
+static inline void in6_ifa_hold(struct inet6_ifaddr *ifp)
+{
+ atomic_inc(&ifp->refcnt);
+}
/*
@@ -241,23 +264,21 @@ static inline int ipv6_addr_is_multicast(const struct in6_addr *addr)
static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
{
- return (((addr->s6_addr32[0] ^ htonl(0xff020000)) |
+ return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
addr->s6_addr32[1] | addr->s6_addr32[2] |
- (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0);
+ (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0;
}
static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
{
- return (((addr->s6_addr32[0] ^ htonl(0xff020000)) |
+ return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
addr->s6_addr32[1] | addr->s6_addr32[2] |
- (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0);
+ (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0;
}
-extern int __ipv6_isatap_ifid(u8 *eui, __be32 addr);
-
static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
{
- return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+ return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
}
#ifdef CONFIG_PROC_FS
diff --git a/include/net/arp.h b/include/net/arp.h
index 716f43c5c98e..f4cf6ce66586 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -26,6 +26,4 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
const unsigned char *target_hw);
extern void arp_xmit(struct sk_buff *skb);
-extern const struct neigh_ops arp_broken_ops;
-
#endif /* _ARP_H */
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 30fce0128dd7..d81ea7997701 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -126,6 +126,8 @@ int bt_sock_unregister(int proto);
void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags);
+int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t len, int flags);
uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index bcbdd6d4e6dd..e30e00834340 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -54,7 +54,7 @@
/* HCI controller types */
#define HCI_BREDR 0x00
-#define HCI_80211 0x01
+#define HCI_AMP 0x01
/* HCI device quirks */
enum {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4568b938ca35..ebec8c9a929d 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -233,7 +233,7 @@ static inline void inquiry_cache_init(struct hci_dev *hdev)
static inline int inquiry_cache_empty(struct hci_dev *hdev)
{
struct inquiry_cache *c = &hdev->inq_cache;
- return (c->list == NULL);
+ return c->list == NULL;
}
static inline long inquiry_cache_age(struct hci_dev *hdev)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6c241444f902..c819c8bf9b68 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -414,7 +414,7 @@ static inline int l2cap_tx_window_full(struct sock *sk)
if (sub < 0)
sub += 64;
- return (sub == pi->remote_tx_win);
+ return sub == pi->remote_tx_win;
}
#define __get_txseq(ctrl) ((ctrl) & L2CAP_CTRL_TXSEQ) >> 1
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index a140847d622c..71047bc0af84 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -213,11 +213,6 @@ struct rfcomm_dlc {
#define RFCOMM_DEFER_SETUP 8
/* Scheduling flags and events */
-#define RFCOMM_SCHED_STATE 0
-#define RFCOMM_SCHED_RX 1
-#define RFCOMM_SCHED_TX 2
-#define RFCOMM_SCHED_TIMEO 3
-#define RFCOMM_SCHED_AUTH 4
#define RFCOMM_SCHED_WAKEUP 31
/* MSC exchange flags */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 2fd06c60ffbb..2a7936d7851d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -25,6 +25,43 @@
#include <linux/wireless.h>
+/**
+ * DOC: Introduction
+ *
+ * cfg80211 is the configuration API for 802.11 devices in Linux. It bridges
+ * userspace and drivers, and offers some utility functionality associated
+ * with 802.11. cfg80211 must, directly or indirectly via mac80211, be used
+ * by all modern wireless drivers in Linux, so that they offer a consistent
+ * API through nl80211. For backward compatibility, cfg80211 also offers
+ * wireless extensions to userspace, but hides them from drivers completely.
+ *
+ * Additionally, cfg80211 contains code to help enforce regulatory spectrum
+ * use restrictions.
+ */
+
+
+/**
+ * DOC: Device registration
+ *
+ * In order for a driver to use cfg80211, it must register the hardware device
+ * with cfg80211. This happens through a number of hardware capability structs
+ * described below.
+ *
+ * The fundamental structure for each device is the 'wiphy', of which each
+ * instance describes a physical wireless device connected to the system. Each
+ * such wiphy can have zero, one, or many virtual interfaces associated with
+ * it, which need to be identified as such by pointing the network interface's
+ * @ieee80211_ptr pointer to a &struct wireless_dev which further describes
+ * the wireless part of the interface, normally this struct is embedded in the
+ * network interface's private data area. Drivers can optionally allow creating
+ * or destroying virtual interfaces on the fly, but without at least one or the
+ * ability to create some the wireless device isn't useful.
+ *
+ * Each wiphy structure contains device capability information, and also has
+ * a pointer to the various operations the driver offers. The definitions and
+ * structures here describe these capabilities in detail.
+ */
+
/*
* wireless hardware capability structures
*/
@@ -205,6 +242,21 @@ struct ieee80211_supported_band {
*/
/**
+ * DOC: Actions and configuration
+ *
+ * Each wireless device and each virtual interface offer a set of configuration
+ * operations and other actions that are invoked by userspace. Each of these
+ * actions is described in the operations structure, and the parameters these
+ * operations use are described separately.
+ *
+ * Additionally, some operations are asynchronous and expect to get status
+ * information via some functions that drivers need to call.
+ *
+ * Scanning and BSS list handling with its associated functionality is described
+ * in a separate chapter.
+ */
+
+/**
* struct vif_params - describes virtual interface parameters
* @mesh_id: mesh ID to use
* @mesh_id_len: length of the mesh ID
@@ -241,12 +293,24 @@ struct key_params {
* enum survey_info_flags - survey information flags
*
* @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
+ * @SURVEY_INFO_IN_USE: channel is currently being used
+ * @SURVEY_INFO_CHANNEL_TIME: channel active time (in ms) was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_BUSY: channel busy time was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: extension channel busy time was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_RX: channel receive time was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_TX: channel transmit time was filled in
*
* Used by the driver to indicate which info in &struct survey_info
* it has filled in during the get_survey().
*/
enum survey_info_flags {
SURVEY_INFO_NOISE_DBM = 1<<0,
+ SURVEY_INFO_IN_USE = 1<<1,
+ SURVEY_INFO_CHANNEL_TIME = 1<<2,
+ SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3,
+ SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4,
+ SURVEY_INFO_CHANNEL_TIME_RX = 1<<5,
+ SURVEY_INFO_CHANNEL_TIME_TX = 1<<6,
};
/**
@@ -256,6 +320,11 @@ enum survey_info_flags {
* @filled: bitflag of flags from &enum survey_info_flags
* @noise: channel noise in dBm. This and all following fields are
* optional
+ * @channel_time: amount of time in ms the radio spent on the channel
+ * @channel_time_busy: amount of time the primary channel was sensed busy
+ * @channel_time_ext_busy: amount of time the extension channel was sensed busy
+ * @channel_time_rx: amount of time the radio spent receiving data
+ * @channel_time_tx: amount of time the radio spent transmitting data
*
* Used by dump_survey() to report back per-channel survey information.
*
@@ -264,6 +333,11 @@ enum survey_info_flags {
*/
struct survey_info {
struct ieee80211_channel *channel;
+ u64 channel_time;
+ u64 channel_time_busy;
+ u64 channel_time_ext_busy;
+ u64 channel_time_rx;
+ u64 channel_time_tx;
u32 filled;
s8 noise;
};
@@ -347,6 +421,9 @@ struct station_parameters {
* (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs)
* @STATION_INFO_RX_PACKETS: @rx_packets filled
* @STATION_INFO_TX_PACKETS: @tx_packets filled
+ * @STATION_INFO_TX_RETRIES: @tx_retries filled
+ * @STATION_INFO_TX_FAILED: @tx_failed filled
+ * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -359,6 +436,9 @@ enum station_info_flags {
STATION_INFO_TX_BITRATE = 1<<7,
STATION_INFO_RX_PACKETS = 1<<8,
STATION_INFO_TX_PACKETS = 1<<9,
+ STATION_INFO_TX_RETRIES = 1<<10,
+ STATION_INFO_TX_FAILED = 1<<11,
+ STATION_INFO_RX_DROP_MISC = 1<<12,
};
/**
@@ -408,6 +488,9 @@ struct rate_info {
* @txrate: current unicast bitrate to this station
* @rx_packets: packets received from this station
* @tx_packets: packets transmitted to this station
+ * @tx_retries: cumulative retry counts
+ * @tx_failed: number of failed transmissions (retries exceeded, no ACK)
+ * @rx_dropped_misc: Dropped for un-specified reason.
* @generation: generation number for nl80211 dumps.
* This number should increase every time the list of stations
* changes, i.e. when a station is added or removed, so that
@@ -425,6 +508,9 @@ struct station_info {
struct rate_info txrate;
u32 rx_packets;
u32 tx_packets;
+ u32 tx_retries;
+ u32 tx_failed;
+ u32 rx_dropped_misc;
int generation;
};
@@ -570,8 +656,28 @@ struct ieee80211_txq_params {
/* from net/wireless.h */
struct wiphy;
-/* from net/ieee80211.h */
-struct ieee80211_channel;
+/**
+ * DOC: Scanning and BSS list handling
+ *
+ * The scanning process itself is fairly simple, but cfg80211 offers quite
+ * a bit of helper functionality. To start a scan, the scan operation will
+ * be invoked with a scan definition. This scan definition contains the
+ * channels to scan, and the SSIDs to send probe requests for (including the
+ * wildcard, if desired). A passive scan is indicated by having no SSIDs to
+ * probe. Additionally, a scan request may contain extra information elements
+ * that should be added to the probe request. The IEs are guaranteed to be
+ * well-formed, and will not exceed the maximum length the driver advertised
+ * in the wiphy structure.
+ *
+ * When scanning finds a BSS, cfg80211 needs to be notified of that, because
+ * it is responsible for maintaining the BSS list; the driver should not
+ * maintain a list itself. For this notification, various functions exist.
+ *
+ * Since drivers do not maintain a BSS list, there are also a number of
+ * functions to search for a BSS and obtain information about it from the
+ * BSS structure cfg80211 maintains. The BSS list is also made available
+ * to userspace.
+ */
/**
* struct cfg80211_ssid - SSID description
@@ -691,6 +797,10 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
* sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
* required to assume that the port is unauthorized until authorized by
* user space. Otherwise, port is marked authorized by default.
+ * @control_port_ethertype: the control port protocol that should be
+ * allowed through even on unauthorized ports
+ * @control_port_no_encrypt: TRUE to prevent encryption of control port
+ * protocol frames.
*/
struct cfg80211_crypto_settings {
u32 wpa_versions;
@@ -700,6 +810,8 @@ struct cfg80211_crypto_settings {
int n_akm_suites;
u32 akm_suites[NL80211_MAX_NR_AKM_SUITES];
bool control_port;
+ __be16 control_port_ethertype;
+ bool control_port_no_encrypt;
};
/**
@@ -1020,7 +1132,7 @@ struct cfg80211_pmksa {
* @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation.
* This allows the operation to be terminated prior to timeout based on
* the duration value.
- * @action: Transmit an action frame
+ * @mgmt_tx: Transmit a management frame
*
* @testmode_cmd: run a test mode command
*
@@ -1035,6 +1147,9 @@ struct cfg80211_pmksa {
* allows the driver to adjust the dynamic ps timeout value.
* @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold.
*
+ * @mgmt_frame_register: Notify driver that a management frame type was
+ * registered. Note that this callback may not sleep, and cannot run
+ * concurrently with itself.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy);
@@ -1050,13 +1165,14 @@ struct cfg80211_ops {
struct vif_params *params);
int (*add_key)(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, const u8 *mac_addr,
+ u8 key_index, bool pairwise, const u8 *mac_addr,
struct key_params *params);
int (*get_key)(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, const u8 *mac_addr, void *cookie,
+ u8 key_index, bool pairwise, const u8 *mac_addr,
+ void *cookie,
void (*callback)(void *cookie, struct key_params*));
int (*del_key)(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, const u8 *mac_addr);
+ u8 key_index, bool pairwise, const u8 *mac_addr);
int (*set_default_key)(struct wiphy *wiphy,
struct net_device *netdev,
u8 key_index);
@@ -1140,7 +1256,7 @@ struct cfg80211_ops {
int (*get_tx_power)(struct wiphy *wiphy, int *dbm);
int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
- u8 *addr);
+ const u8 *addr);
void (*rfkill_poll)(struct wiphy *wiphy);
@@ -1172,7 +1288,7 @@ struct cfg80211_ops {
struct net_device *dev,
u64 cookie);
- int (*action)(struct wiphy *wiphy, struct net_device *dev,
+ int (*mgmt_tx)(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type,
bool channel_type_valid,
@@ -1184,6 +1300,10 @@ struct cfg80211_ops {
int (*set_cqm_rssi_config)(struct wiphy *wiphy,
struct net_device *dev,
s32 rssi_thold, u32 rssi_hyst);
+
+ void (*mgmt_frame_register)(struct wiphy *wiphy,
+ struct net_device *dev,
+ u16 frame_type, bool reg);
};
/*
@@ -1221,21 +1341,31 @@ struct cfg80211_ops {
* @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station
* on a VLAN interface)
* @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station
+ * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the
+ * control port protocol ethertype. The device also honours the
+ * control_port_no_encrypt flag.
+ * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
*/
enum wiphy_flags {
- WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
- WIPHY_FLAG_STRICT_REGULATORY = BIT(1),
- WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2),
- WIPHY_FLAG_NETNS_OK = BIT(3),
- WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4),
- WIPHY_FLAG_4ADDR_AP = BIT(5),
- WIPHY_FLAG_4ADDR_STATION = BIT(6),
+ WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
+ WIPHY_FLAG_STRICT_REGULATORY = BIT(1),
+ WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2),
+ WIPHY_FLAG_NETNS_OK = BIT(3),
+ WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4),
+ WIPHY_FLAG_4ADDR_AP = BIT(5),
+ WIPHY_FLAG_4ADDR_STATION = BIT(6),
+ WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7),
+ WIPHY_FLAG_IBSS_RSN = BIT(7),
};
struct mac_address {
u8 addr[ETH_ALEN];
};
+struct ieee80211_txrx_stypes {
+ u16 tx, rx;
+};
+
/**
* struct wiphy - wireless hardware description
* @reg_notifier: the driver's regulatory notification callback
@@ -1286,6 +1416,10 @@ struct mac_address {
* @privid: a pointer that drivers can use to identify if an arbitrary
* wiphy is theirs, e.g. in global notifiers
* @bands: information about bands/channels supported by this device
+ *
+ * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or
+ * transmitted through nl80211, points to an array indexed by interface
+ * type
*/
struct wiphy {
/* assign these fields before you register the wiphy */
@@ -1294,9 +1428,12 @@ struct wiphy {
u8 perm_addr[ETH_ALEN];
u8 addr_mask[ETH_ALEN];
- u16 n_addresses;
struct mac_address *addresses;
+ const struct ieee80211_txrx_stypes *mgmt_stypes;
+
+ u16 n_addresses;
+
/* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
u16 interface_modes;
@@ -1492,8 +1629,8 @@ struct cfg80211_cached_keys;
* set by driver (if supported) on add_interface BEFORE registering the
* netdev and may otherwise be used by driver read-only, will be update
* by cfg80211 on change_interface
- * @action_registrations: list of registrations for action frames
- * @action_registrations_lock: lock for the list
+ * @mgmt_registrations: list of registrations for management frames
+ * @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
*/
@@ -1505,8 +1642,8 @@ struct wireless_dev {
struct list_head list;
struct net_device *netdev;
- struct list_head action_registrations;
- spinlock_t action_registrations_lock;
+ struct list_head mgmt_registrations;
+ spinlock_t mgmt_registrations_lock;
struct mutex mtx;
@@ -1563,8 +1700,10 @@ static inline void *wdev_priv(struct wireless_dev *wdev)
return wiphy_priv(wdev->wiphy);
}
-/*
- * Utility functions
+/**
+ * DOC: Utility functions
+ *
+ * cfg80211 offers a number of utility functions that can be useful.
*/
/**
@@ -1715,7 +1854,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);
* ieee80211_hdrlen - get header length in bytes from frame control
* @fc: frame control field in little-endian format
*/
-unsigned int ieee80211_hdrlen(__le16 fc);
+unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);
+
+/**
+ * DOC: Data path helpers
+ *
+ * In addition to generic utilities, cfg80211 also offers
+ * functions that help implement the data path for devices
+ * that do not do the 802.11/802.3 conversion on the device.
+ */
/**
* ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3
@@ -1777,8 +1924,10 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb);
*/
const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len);
-/*
- * Regulatory helper functions for wiphys
+/**
+ * DOC: Regulatory enforcement infrastructure
+ *
+ * TODO
*/
/**
@@ -2181,6 +2330,20 @@ 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);
/**
+ * DOC: RFkill integration
+ *
+ * RFkill integration in cfg80211 is almost invisible to drivers,
+ * as cfg80211 automatically registers an rfkill instance for each
+ * wireless device it knows about. Soft kill is also translated
+ * into disconnecting and turning all interfaces off, drivers are
+ * expected to turn off the device when all interfaces are down.
+ *
+ * However, devices may have a hard RFkill line, in which case they
+ * also need to interact with the rfkill subsystem, via cfg80211.
+ * They can do this with a few helper functions documented here.
+ */
+
+/**
* wiphy_rfkill_set_hw_state - notify cfg80211 about hw block state
* @wiphy: the wiphy
* @blocked: block status
@@ -2201,6 +2364,17 @@ void wiphy_rfkill_stop_polling(struct wiphy *wiphy);
#ifdef CONFIG_NL80211_TESTMODE
/**
+ * DOC: Test mode
+ *
+ * Test mode is a set of utility functions to allow drivers to
+ * interact with driver-specific tools to aid, for instance,
+ * factory programming.
+ *
+ * This chapter describes how drivers interact with it, for more
+ * information see the nl80211 book's chapter on it.
+ */
+
+/**
* cfg80211_testmode_alloc_reply_skb - allocate testmode reply
* @wiphy: the wiphy
* @approxlen: an upper bound of the length of the data that will
@@ -2373,38 +2547,39 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
struct station_info *sinfo, gfp_t gfp);
/**
- * cfg80211_rx_action - notification of received, unprocessed Action frame
+ * cfg80211_rx_mgmt - notification of received, unprocessed management frame
* @dev: network device
* @freq: Frequency on which the frame was received in MHz
- * @buf: Action frame (header + body)
+ * @buf: Management frame (header + body)
* @len: length of the frame data
* @gfp: context flags
- * Returns %true if a user space application is responsible for rejecting the
- * unrecognized Action frame; %false if no such application is registered
- * (i.e., the driver is responsible for rejecting the unrecognized Action
- * frame)
+ *
+ * Returns %true if a user space application has registered for this frame.
+ * For action frames, that makes it responsible for rejecting unrecognized
+ * action frames; %false otherwise, in which case for action frames the
+ * driver is responsible for rejecting the frame.
*
* This function is called whenever an Action frame is received for a station
* mode interface, but is not processed in kernel.
*/
-bool cfg80211_rx_action(struct net_device *dev, int freq, const u8 *buf,
- size_t len, gfp_t gfp);
+bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
+ size_t len, gfp_t gfp);
/**
- * cfg80211_action_tx_status - notification of TX status for Action frame
+ * cfg80211_mgmt_tx_status - notification of TX status for management frame
* @dev: network device
- * @cookie: Cookie returned by cfg80211_ops::action()
- * @buf: Action frame (header + body)
+ * @cookie: Cookie returned by cfg80211_ops::mgmt_tx()
+ * @buf: Management frame (header + body)
* @len: length of the frame data
* @ack: Whether frame was acknowledged
* @gfp: context flags
*
- * This function is called whenever an Action frame was requested to be
- * transmitted with cfg80211_ops::action() to report the TX status of the
+ * This function is called whenever a management frame was requested to be
+ * transmitted with cfg80211_ops::mgmt_tx() to report the TX status of the
* transmission attempt.
*/
-void cfg80211_action_tx_status(struct net_device *dev, u64 cookie,
- const u8 *buf, size_t len, bool ack, gfp_t gfp);
+void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie,
+ const u8 *buf, size_t len, bool ack, gfp_t gfp);
/**
@@ -2420,56 +2595,41 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
enum nl80211_cqm_rssi_threshold_event rssi_event,
gfp_t gfp);
-#ifdef __KERNEL__
-
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
#define wiphy_printk(level, wiphy, format, args...) \
- printk(level "%s: " format, wiphy_name(wiphy), ##args)
+ dev_printk(level, &(wiphy)->dev, format, ##args)
#define wiphy_emerg(wiphy, format, args...) \
- wiphy_printk(KERN_EMERG, wiphy, format, ##args)
+ dev_emerg(&(wiphy)->dev, format, ##args)
#define wiphy_alert(wiphy, format, args...) \
- wiphy_printk(KERN_ALERT, wiphy, format, ##args)
+ dev_alert(&(wiphy)->dev, format, ##args)
#define wiphy_crit(wiphy, format, args...) \
- wiphy_printk(KERN_CRIT, wiphy, format, ##args)
+ dev_crit(&(wiphy)->dev, format, ##args)
#define wiphy_err(wiphy, format, args...) \
- wiphy_printk(KERN_ERR, wiphy, format, ##args)
+ dev_err(&(wiphy)->dev, format, ##args)
#define wiphy_warn(wiphy, format, args...) \
- wiphy_printk(KERN_WARNING, wiphy, format, ##args)
+ dev_warn(&(wiphy)->dev, format, ##args)
#define wiphy_notice(wiphy, format, args...) \
- wiphy_printk(KERN_NOTICE, wiphy, format, ##args)
+ dev_notice(&(wiphy)->dev, format, ##args)
#define wiphy_info(wiphy, format, args...) \
- wiphy_printk(KERN_INFO, wiphy, format, ##args)
+ dev_info(&(wiphy)->dev, format, ##args)
-int wiphy_debug(const struct wiphy *wiphy, const char *format, ...)
- __attribute__ ((format (printf, 2, 3)));
-
-#if defined(DEBUG)
-#define wiphy_dbg(wiphy, format, args...) \
+#define wiphy_debug(wiphy, format, args...) \
wiphy_printk(KERN_DEBUG, wiphy, format, ##args)
-#elif defined(CONFIG_DYNAMIC_DEBUG)
+
#define wiphy_dbg(wiphy, format, args...) \
- dynamic_pr_debug("%s: " format, wiphy_name(wiphy), ##args)
-#else
-#define wiphy_dbg(wiphy, format, args...) \
-({ \
- if (0) \
- wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \
- 0; \
-})
-#endif
+ dev_dbg(&(wiphy)->dev, format, ##args)
#if defined(VERBOSE_DEBUG)
#define wiphy_vdbg wiphy_dbg
#else
-
#define wiphy_vdbg(wiphy, format, args...) \
({ \
if (0) \
wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \
- 0; \
+ 0; \
})
#endif
@@ -2481,6 +2641,4 @@ int wiphy_debug(const struct wiphy *wiphy, const char *format, ...)
#define wiphy_WARN(wiphy, format, args...) \
WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args);
-#endif
-
#endif /* __NET_CFG80211_H */
diff --git a/include/net/dst.h b/include/net/dst.h
index 02386505033d..a217c838ec0d 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -43,10 +43,11 @@ struct dst_entry {
short error;
short obsolete;
int flags;
-#define DST_HOST 1
-#define DST_NOXFRM 2
-#define DST_NOPOLICY 4
-#define DST_NOHASH 8
+#define DST_HOST 0x0001
+#define DST_NOXFRM 0x0002
+#define DST_NOPOLICY 0x0004
+#define DST_NOHASH 0x0008
+#define DST_NOCACHE 0x0010
unsigned long expires;
unsigned short header_len; /* more space at head required */
@@ -228,23 +229,37 @@ static inline void skb_dst_force(struct sk_buff *skb)
/**
+ * __skb_tunnel_rx - prepare skb for rx reinsert
+ * @skb: buffer
+ * @dev: tunnel device
+ *
+ * After decapsulation, packet is going to re-enter (netif_rx()) our stack,
+ * so make some cleanups. (no accounting done)
+ */
+static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
+{
+ skb->dev = dev;
+ skb->rxhash = 0;
+ skb_set_queue_mapping(skb, 0);
+ skb_dst_drop(skb);
+ nf_reset(skb);
+}
+
+/**
* skb_tunnel_rx - prepare skb for rx reinsert
* @skb: buffer
* @dev: tunnel device
*
* After decapsulation, packet is going to re-enter (netif_rx()) our stack,
* so make some cleanups, and perform accounting.
+ * Note: this accounting is not SMP safe.
*/
static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
{
- skb->dev = dev;
/* TODO : stats should be SMP safe */
dev->stats.rx_packets++;
dev->stats.rx_bytes += skb->len;
- skb->rxhash = 0;
- skb_set_queue_mapping(skb, 0);
- skb_dst_drop(skb);
- nf_reset(skb);
+ __skb_tunnel_rx(skb, dev);
}
/* Children define the path of the packet through the
diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h
index d1ff9b7e99b8..1fa5306e3e23 100644
--- a/include/net/dst_ops.h
+++ b/include/net/dst_ops.h
@@ -1,6 +1,7 @@
#ifndef _NET_DST_OPS_H
#define _NET_DST_OPS_H
#include <linux/types.h>
+#include <linux/percpu_counter.h>
struct dst_entry;
struct kmem_cachep;
@@ -22,7 +23,41 @@ struct dst_ops {
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
int (*local_out)(struct sk_buff *skb);
- atomic_t entries;
struct kmem_cache *kmem_cachep;
+
+ struct percpu_counter pcpuc_entries ____cacheline_aligned_in_smp;
};
+
+static inline int dst_entries_get_fast(struct dst_ops *dst)
+{
+ return percpu_counter_read_positive(&dst->pcpuc_entries);
+}
+
+static inline int dst_entries_get_slow(struct dst_ops *dst)
+{
+ int res;
+
+ local_bh_disable();
+ res = percpu_counter_sum_positive(&dst->pcpuc_entries);
+ local_bh_enable();
+ return res;
+}
+
+static inline void dst_entries_add(struct dst_ops *dst, int val)
+{
+ local_bh_disable();
+ percpu_counter_add(&dst->pcpuc_entries, val);
+ local_bh_enable();
+}
+
+static inline int dst_entries_init(struct dst_ops *dst)
+{
+ return percpu_counter_init(&dst->pcpuc_entries, 0);
+}
+
+static inline void dst_entries_destroy(struct dst_ops *dst)
+{
+ percpu_counter_destroy(&dst->pcpuc_entries);
+}
+
#endif
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index e8923bc20f9f..106f3097d384 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -31,6 +31,8 @@ struct fib_lookup_arg {
void *lookup_ptr;
void *result;
struct fib_rule *rule;
+ int flags;
+#define FIB_LOOKUP_NOREF 1
};
struct fib_rules_ops {
@@ -106,7 +108,6 @@ static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
extern struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *, struct net *);
extern void fib_rules_unregister(struct fib_rules_ops *);
-extern void fib_rules_cleanup_ops(struct fib_rules_ops *);
extern int fib_rules_lookup(struct fib_rules_ops *,
struct flowi *, int flags,
diff --git a/include/net/flow.h b/include/net/flow.h
index bb08692a20b0..0ac3fb5e0973 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -49,6 +49,7 @@ struct flowi {
__u8 proto;
__u8 flags;
#define FLOWI_FLAG_ANYSRC 0x01
+#define FLOWI_FLAG_MATCH_ANY_IIF 0x02
union {
struct {
__be16 sport;
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index f7dcd2c70412..8a64b811a39a 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -20,6 +20,9 @@ struct genl_multicast_group {
u32 id;
};
+struct genl_ops;
+struct genl_info;
+
/**
* struct genl_family - generic netlink family
* @id: protocol family idenfitier
@@ -29,6 +32,10 @@ struct genl_multicast_group {
* @maxattr: maximum number of attributes supported
* @netnsok: set to true if the family can handle network
* namespaces and should be presented in all of them
+ * @pre_doit: called before an operation's doit callback, it may
+ * do additional, common, filtering and return an error
+ * @post_doit: called after an operation's doit callback, it may
+ * undo operations done by pre_doit, for example release locks
* @attrbuf: buffer to store parsed attributes
* @ops_list: list of all assigned operations
* @family_list: family list
@@ -41,6 +48,12 @@ struct genl_family {
unsigned int version;
unsigned int maxattr;
bool netnsok;
+ int (*pre_doit)(struct genl_ops *ops,
+ struct sk_buff *skb,
+ struct genl_info *info);
+ void (*post_doit)(struct genl_ops *ops,
+ struct sk_buff *skb,
+ struct genl_info *info);
struct nlattr ** attrbuf; /* private */
struct list_head ops_list; /* private */
struct list_head family_list; /* private */
@@ -55,6 +68,8 @@ struct genl_family {
* @genlhdr: generic netlink message header
* @userhdr: user specific header
* @attrs: netlink attributes
+ * @_net: network namespace
+ * @user_ptr: user pointers
*/
struct genl_info {
u32 snd_seq;
@@ -66,6 +81,7 @@ struct genl_info {
#ifdef CONFIG_NET_NS
struct net * _net;
#endif
+ void * user_ptr[2];
};
static inline struct net *genl_info_net(struct genl_info *info)
@@ -81,6 +97,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
/**
* struct genl_ops - generic netlink operations
* @cmd: command identifier
+ * @internal_flags: flags used by the family
* @flags: flags
* @policy: attribute validation policy
* @doit: standard command callback
@@ -90,6 +107,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
*/
struct genl_ops {
u8 cmd;
+ u8 internal_flags;
unsigned int flags;
const struct nla_policy *policy;
int (*doit)(struct sk_buff *skb,
diff --git a/include/net/gre.h b/include/net/gre.h
new file mode 100644
index 000000000000..82665474bcb7
--- /dev/null
+++ b/include/net/gre.h
@@ -0,0 +1,18 @@
+#ifndef __LINUX_GRE_H
+#define __LINUX_GRE_H
+
+#include <linux/skbuff.h>
+
+#define GREPROTO_CISCO 0
+#define GREPROTO_PPTP 1
+#define GREPROTO_MAX 2
+
+struct gre_protocol {
+ int (*handler)(struct sk_buff *skb);
+ void (*err_handler)(struct sk_buff *skb, u32 info);
+};
+
+int gre_add_protocol(const struct gre_protocol *proto, u8 version);
+int gre_del_protocol(const struct gre_protocol *proto, u8 version);
+
+#endif
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index b6d3b55da19b..e4f494b42e06 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -125,6 +125,7 @@ struct inet_connection_sock {
int probe_size;
} icsk_mtup;
u32 icsk_ca_priv[16];
+ u32 icsk_user_timeout;
#define ICSK_CA_PRIV_SIZE (16 * sizeof(u32))
};
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index 9b5d08f4f6e8..88bdd010d65d 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -27,7 +27,7 @@ static inline int INET_ECN_is_not_ect(__u8 dsfield)
static inline int INET_ECN_is_capable(__u8 dsfield)
{
- return (dsfield & INET_ECN_ECT_0);
+ return dsfield & INET_ECN_ECT_0;
}
static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner)
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 74358d1b3f43..e9c2ed8af864 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -245,7 +245,7 @@ static inline int inet_sk_listen_hashfn(const struct sock *sk)
}
/* Caller must disable local BH processing. */
-extern void __inet_inherit_port(struct sock *sk, struct sock *child);
+extern int __inet_inherit_port(struct sock *sk, struct sock *child);
extern void inet_put_port(struct sock *sk);
diff --git a/include/net/ip.h b/include/net/ip.h
index 890f9725d681..dbee3fe260e1 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -53,7 +53,7 @@ struct ipcm_cookie {
__be32 addr;
int oif;
struct ip_options *opt;
- union skb_shared_tx shtx;
+ __u8 tx_flags;
};
#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
@@ -238,9 +238,9 @@ int ip_decrease_ttl(struct iphdr *iph)
static inline
int ip_dont_fragment(struct sock *sk, struct dst_entry *dst)
{
- return (inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO ||
+ return inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO ||
(inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT &&
- !(dst_metric_locked(dst, RTAX_MTU))));
+ !(dst_metric_locked(dst, RTAX_MTU)));
}
extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more);
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index c93f94edc610..ba3666d31766 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -86,6 +86,7 @@ struct fib_info {
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int fib_power;
#endif
+ struct rcu_head rcu;
struct fib_nh fib_nh[0];
#define fib_dev fib_nh[0].nh_dev
};
@@ -148,7 +149,7 @@ struct fib_table {
};
extern int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
- struct fib_result *res);
+ struct fib_result *res, int fib_flags);
extern int fib_table_insert(struct fib_table *, struct fib_config *);
extern int fib_table_delete(struct fib_table *, struct fib_config *);
extern int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
@@ -185,11 +186,11 @@ static inline int fib_lookup(struct net *net, const struct flowi *flp,
struct fib_table *table;
table = fib_get_table(net, RT_TABLE_LOCAL);
- if (!fib_table_lookup(table, flp, res))
+ if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF))
return 0;
table = fib_get_table(net, RT_TABLE_MAIN);
- if (!fib_table_lookup(table, flp, res))
+ if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF))
return 0;
return -ENETUNREACH;
}
@@ -254,16 +255,6 @@ static inline void fib_info_put(struct fib_info *fi)
free_fib_info(fi);
}
-static inline void fib_res_put(struct fib_result *res)
-{
- if (res->fi)
- fib_info_put(res->fi);
-#ifdef CONFIG_IP_MULTIPLE_TABLES
- if (res->r)
- fib_rule_put(res->r);
-#endif
-}
-
#ifdef CONFIG_PROC_FS
extern int __net_init fib_proc_init(struct net *net);
extern void __net_exit fib_proc_exit(struct net *net);
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index f976885f686f..b7bbd6c28cfa 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -25,7 +25,9 @@
#include <linux/ip.h>
#include <linux/ipv6.h> /* for struct ipv6hdr */
#include <net/ipv6.h> /* for ipv6_addr_copy */
-
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#include <net/netfilter/nf_conntrack.h>
+#endif
/* Connections' size value needed by ip_vs_ctl.c */
extern int ip_vs_conn_tab_size;
@@ -134,24 +136,24 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
if (net_ratelimit()) \
printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__); \
} while (0)
-#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) \
+#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg) \
do { \
if (level <= ip_vs_get_debug_level()) \
- pp->debug_packet(pp, skb, ofs, msg); \
+ pp->debug_packet(af, pp, skb, ofs, msg); \
} while (0)
-#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg) \
+#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) \
do { \
if (level <= ip_vs_get_debug_level() && \
net_ratelimit()) \
- pp->debug_packet(pp, skb, ofs, msg); \
+ pp->debug_packet(af, pp, skb, ofs, msg); \
} while (0)
#else /* NO DEBUGGING at ALL */
#define IP_VS_DBG_BUF(level, msg...) do {} while (0)
#define IP_VS_ERR_BUF(msg...) do {} while (0)
#define IP_VS_DBG(level, msg...) do {} while (0)
#define IP_VS_DBG_RL(msg...) do {} while (0)
-#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) do {} while (0)
-#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg) do {} while (0)
+#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg) do {} while (0)
+#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) do {} while (0)
#endif
#define IP_VS_BUG() BUG()
@@ -343,7 +345,7 @@ struct ip_vs_protocol {
int (*app_conn_bind)(struct ip_vs_conn *cp);
- void (*debug_packet)(struct ip_vs_protocol *pp,
+ void (*debug_packet)(int af, struct ip_vs_protocol *pp,
const struct sk_buff *skb,
int offset,
const char *msg);
@@ -355,6 +357,19 @@ struct ip_vs_protocol {
extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto);
+struct ip_vs_conn_param {
+ const union nf_inet_addr *caddr;
+ const union nf_inet_addr *vaddr;
+ __be16 cport;
+ __be16 vport;
+ __u16 protocol;
+ u16 af;
+
+ const struct ip_vs_pe *pe;
+ char *pe_data;
+ __u8 pe_data_len;
+};
+
/*
* IP_VS structure allocated for each dynamically scheduled connection
*/
@@ -366,6 +381,7 @@ struct ip_vs_conn {
union nf_inet_addr caddr; /* client address */
union nf_inet_addr vaddr; /* virtual address */
union nf_inet_addr daddr; /* destination address */
+ volatile __u32 flags; /* status flags */
__be16 cport;
__be16 vport;
__be16 dport;
@@ -378,7 +394,6 @@ struct ip_vs_conn {
/* Flags and state transition */
spinlock_t lock; /* lock for state transition */
- volatile __u16 flags; /* status flags */
volatile __u16 state; /* state info */
volatile __u16 old_state; /* old state, to be used for
* state transition triggerd
@@ -394,6 +409,7 @@ struct ip_vs_conn {
/* packet transmitter for different forwarding methods. If it
mangles the packet, it must return NF_DROP or better NF_STOLEN,
otherwise this must be changed to a sk_buff **.
+ NF_ACCEPT can be returned when destination is local.
*/
int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp,
struct ip_vs_protocol *pp);
@@ -405,6 +421,9 @@ struct ip_vs_conn {
void *app_data; /* Application private data */
struct ip_vs_seq in_seq; /* incoming seq. struct */
struct ip_vs_seq out_seq; /* outgoing seq. struct */
+
+ char *pe_data;
+ __u8 pe_data_len;
};
@@ -426,6 +445,7 @@ struct ip_vs_service_user_kern {
/* virtual service options */
char *sched_name;
+ char *pe_name;
unsigned flags; /* virtual service flags */
unsigned timeout; /* persistent timeout in sec */
u32 netmask; /* persistent netmask */
@@ -475,6 +495,9 @@ struct ip_vs_service {
struct ip_vs_scheduler *scheduler; /* bound scheduler object */
rwlock_t sched_lock; /* lock sched_data */
void *sched_data; /* scheduler application data */
+
+ /* alternate persistence engine */
+ struct ip_vs_pe *pe;
};
@@ -507,6 +530,10 @@ struct ip_vs_dest {
spinlock_t dst_lock; /* lock of dst_cache */
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
/* for virtual service */
struct ip_vs_service *svc; /* service it belongs to */
@@ -538,6 +565,21 @@ struct ip_vs_scheduler {
const struct sk_buff *skb);
};
+/* The persistence engine object */
+struct ip_vs_pe {
+ struct list_head n_list; /* d-linked list head */
+ char *name; /* scheduler name */
+ atomic_t refcnt; /* reference counter */
+ struct module *module; /* THIS_MODULE/NULL */
+
+ /* get the connection template, if any */
+ int (*fill_param)(struct ip_vs_conn_param *p, struct sk_buff *skb);
+ bool (*ct_match)(const struct ip_vs_conn_param *p,
+ struct ip_vs_conn *ct);
+ u32 (*hashkey_raw)(const struct ip_vs_conn_param *p, u32 initval,
+ bool inverse);
+ int (*show_pe_data)(const struct ip_vs_conn *cp, char *buf);
+};
/*
* The application module object (a.k.a. app incarnation)
@@ -556,11 +598,19 @@ struct ip_vs_app {
__be16 port; /* port number in net order */
atomic_t usecnt; /* usage counter */
- /* output hook: return false if can't linearize. diff set for TCP. */
+ /*
+ * output hook: Process packet in inout direction, diff set for TCP.
+ * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok,
+ * 2=Mangled but checksum was not updated
+ */
int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *,
struct sk_buff *, int *diff);
- /* input hook: return false if can't linearize. diff set for TCP. */
+ /*
+ * input hook: Process packet in outin direction, diff set for TCP.
+ * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok,
+ * 2=Mangled but checksum was not updated
+ */
int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *,
struct sk_buff *, int *diff);
@@ -624,13 +674,25 @@ enum {
IP_VS_DIR_LAST,
};
-extern struct ip_vs_conn *ip_vs_conn_in_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port);
+static inline void ip_vs_conn_fill_param(int af, int protocol,
+ const union nf_inet_addr *caddr,
+ __be16 cport,
+ const union nf_inet_addr *vaddr,
+ __be16 vport,
+ struct ip_vs_conn_param *p)
+{
+ p->af = af;
+ p->protocol = protocol;
+ p->caddr = caddr;
+ p->cport = cport;
+ p->vaddr = vaddr;
+ p->vport = vport;
+ p->pe = NULL;
+ p->pe_data = NULL;
+}
-extern struct ip_vs_conn *ip_vs_ct_in_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port);
+struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p);
+struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p);
struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb,
struct ip_vs_protocol *pp,
@@ -638,9 +700,7 @@ struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb,
unsigned int proto_off,
int inverse);
-extern struct ip_vs_conn *ip_vs_conn_out_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port);
+struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p);
struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb,
struct ip_vs_protocol *pp,
@@ -656,11 +716,10 @@ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
extern void ip_vs_conn_put(struct ip_vs_conn *cp);
extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport);
-extern struct ip_vs_conn *
-ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,
- const union nf_inet_addr *vaddr, __be16 vport,
- const union nf_inet_addr *daddr, __be16 dport, unsigned flags,
- struct ip_vs_dest *dest);
+struct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p,
+ const union nf_inet_addr *daddr,
+ __be16 dport, unsigned flags,
+ struct ip_vs_dest *dest);
extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp);
extern const char * ip_vs_state_name(__u16 proto, int state);
@@ -751,6 +810,12 @@ extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb);
extern int ip_vs_app_init(void);
extern void ip_vs_app_cleanup(void);
+void ip_vs_bind_pe(struct ip_vs_service *svc, struct ip_vs_pe *pe);
+void ip_vs_unbind_pe(struct ip_vs_service *svc);
+int register_ip_vs_pe(struct ip_vs_pe *pe);
+int unregister_ip_vs_pe(struct ip_vs_pe *pe);
+extern struct ip_vs_pe *ip_vs_pe_get(const char *name);
+extern void ip_vs_pe_put(struct ip_vs_pe *pe);
/*
* IPVS protocol functions (from ip_vs_proto.c)
@@ -763,7 +828,8 @@ extern int
ip_vs_set_state_timeout(int *table, int num, const char *const *names,
const char *name, int to);
extern void
-ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
+ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
+ const struct sk_buff *skb,
int offset, const char *msg);
extern struct ip_vs_protocol ip_vs_protocol_tcp;
@@ -785,7 +851,8 @@ extern int ip_vs_unbind_scheduler(struct ip_vs_service *svc);
extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name);
extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler);
extern struct ip_vs_conn *
-ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb);
+ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
+ struct ip_vs_protocol *pp, int *ignored);
extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
struct ip_vs_protocol *pp);
@@ -798,6 +865,8 @@ extern int sysctl_ip_vs_expire_nodest_conn;
extern int sysctl_ip_vs_expire_quiescent_template;
extern int sysctl_ip_vs_sync_threshold[2];
extern int sysctl_ip_vs_nat_icmp_send;
+extern int sysctl_ip_vs_conntrack;
+extern int sysctl_ip_vs_snat_reroute;
extern struct ip_vs_stats ip_vs_stats;
extern const struct ctl_path net_vs_ctl_path[];
@@ -955,8 +1024,65 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
return csum_partial(diff, sizeof(diff), oldsum);
}
+/*
+ * Forget current conntrack (unconfirmed) and attach notrack entry
+ */
+static inline void ip_vs_notrack(struct sk_buff *skb)
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo);
+
+ if (!ct || !nf_ct_is_untracked(ct)) {
+ nf_reset(skb);
+ skb->nfct = &nf_ct_untracked_get()->ct_general;
+ skb->nfctinfo = IP_CT_NEW;
+ nf_conntrack_get(skb->nfct);
+ }
+#endif
+}
+
+#ifdef CONFIG_IP_VS_NFCT
+/*
+ * Netfilter connection tracking
+ * (from ip_vs_nfct.c)
+ */
+static inline int ip_vs_conntrack_enabled(void)
+{
+ return sysctl_ip_vs_conntrack;
+}
+
extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,
int outin);
+extern int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp);
+extern void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
+ struct ip_vs_conn *cp, u_int8_t proto,
+ const __be16 port, int from_rs);
+extern void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp);
+
+#else
+
+static inline int ip_vs_conntrack_enabled(void)
+{
+ return 0;
+}
+
+static inline void ip_vs_update_conntrack(struct sk_buff *skb,
+ struct ip_vs_conn *cp, int outin)
+{
+}
+
+static inline int ip_vs_confirm_conntrack(struct sk_buff *skb,
+ struct ip_vs_conn *cp)
+{
+ return NF_ACCEPT;
+}
+
+static inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp)
+{
+}
+/* CONFIG_IP_VS_NFCT */
+#endif
#endif /* __KERNEL__ */
diff --git a/include/net/ipip.h b/include/net/ipip.h
index 65caea8b414f..58abbf966b0c 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -45,7 +45,7 @@ struct ip_tunnel_prl_entry {
struct rcu_head rcu_head;
};
-#define IPTUNNEL_XMIT() do { \
+#define __IPTUNNEL_XMIT(stats1, stats2) do { \
int err; \
int pkt_len = skb->len - skb_transport_offset(skb); \
\
@@ -54,12 +54,14 @@ struct ip_tunnel_prl_entry {
\
err = ip_local_out(skb); \
if (likely(net_xmit_eval(err) == 0)) { \
- txq->tx_bytes += pkt_len; \
- txq->tx_packets++; \
+ (stats1)->tx_bytes += pkt_len; \
+ (stats1)->tx_packets++; \
} else { \
- stats->tx_errors++; \
- stats->tx_aborted_errors++; \
+ (stats2)->tx_errors++; \
+ (stats2)->tx_aborted_errors++; \
} \
} while (0)
+#define IPTUNNEL_XMIT() __IPTUNNEL_XMIT(txq, stats)
+
#endif
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 1f8412410998..4a3cd2cd2f5e 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -262,7 +262,7 @@ static inline int ipv6_addr_scope(const struct in6_addr *addr)
static inline int __ipv6_addr_src_scope(int type)
{
- return (type == IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16));
+ return (type == IPV6_ADDR_ANY) ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16);
}
static inline int ipv6_addr_src_scope(const struct in6_addr *addr)
@@ -279,10 +279,10 @@ static inline int
ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m,
const struct in6_addr *a2)
{
- return (!!(((a1->s6_addr32[0] ^ a2->s6_addr32[0]) & m->s6_addr32[0]) |
- ((a1->s6_addr32[1] ^ a2->s6_addr32[1]) & m->s6_addr32[1]) |
- ((a1->s6_addr32[2] ^ a2->s6_addr32[2]) & m->s6_addr32[2]) |
- ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3])));
+ return !!(((a1->s6_addr32[0] ^ a2->s6_addr32[0]) & m->s6_addr32[0]) |
+ ((a1->s6_addr32[1] ^ a2->s6_addr32[1]) & m->s6_addr32[1]) |
+ ((a1->s6_addr32[2] ^ a2->s6_addr32[2]) & m->s6_addr32[2]) |
+ ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3]));
}
static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
@@ -317,10 +317,10 @@ static inline void ipv6_addr_set(struct in6_addr *addr,
static inline int ipv6_addr_equal(const struct in6_addr *a1,
const struct in6_addr *a2)
{
- return (((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
- (a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
- (a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
- (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0);
+ return ((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
+ (a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
+ (a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
+ (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0;
}
static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2,
@@ -373,20 +373,20 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a);
static inline int ipv6_addr_any(const struct in6_addr *a)
{
- return ((a->s6_addr32[0] | a->s6_addr32[1] |
- a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
+ return (a->s6_addr32[0] | a->s6_addr32[1] |
+ a->s6_addr32[2] | a->s6_addr32[3]) == 0;
}
static inline int ipv6_addr_loopback(const struct in6_addr *a)
{
- return ((a->s6_addr32[0] | a->s6_addr32[1] |
- a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0);
+ return (a->s6_addr32[0] | a->s6_addr32[1] |
+ a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0;
}
static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
{
- return ((a->s6_addr32[0] | a->s6_addr32[1] |
- (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0);
+ return (a->s6_addr32[0] | a->s6_addr32[1] |
+ (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0;
}
/*
@@ -395,8 +395,7 @@ static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
*/
static inline int ipv6_addr_orchid(const struct in6_addr *a)
{
- return ((a->s6_addr32[0] & htonl(0xfffffff0))
- == htonl(0x20010010));
+ return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010);
}
static inline void ipv6_addr_set_v4mapped(const __be32 addr,
@@ -441,7 +440,7 @@ static inline int __ipv6_addr_diff(const void *token1, const void *token2, int a
* if returned value is greater than prefix length.
* --ANK (980803)
*/
- return (addrlen << 5);
+ return addrlen << 5;
}
static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2)
diff --git a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h
index 73cacb3ac16c..0af8b8dfbc22 100644
--- a/include/net/irda/irlan_common.h
+++ b/include/net/irda/irlan_common.h
@@ -171,7 +171,6 @@ struct irlan_cb {
int magic;
struct list_head dev_list;
struct net_device *dev; /* Ethernet device structure*/
- struct net_device_stats stats;
__u32 saddr; /* Source device address */
__u32 daddr; /* Destination device address */
diff --git a/include/net/irda/irlan_event.h b/include/net/irda/irlan_event.h
index 6d9539f05806..018b5a77e610 100644
--- a/include/net/irda/irlan_event.h
+++ b/include/net/irda/irlan_event.h
@@ -67,7 +67,7 @@ typedef enum {
IRLAN_WATCHDOG_TIMEOUT,
} IRLAN_EVENT;
-extern char *irlan_state[];
+extern const char * const irlan_state[];
void irlan_do_client_event(struct irlan_cb *self, IRLAN_EVENT event,
struct sk_buff *skb);
diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h
index 9d0c78ea92f5..17fcd964f9d9 100644
--- a/include/net/irda/irlap.h
+++ b/include/net/irda/irlap.h
@@ -282,7 +282,7 @@ static inline int irlap_is_primary(struct irlap_cb *self)
default:
ret = -1;
}
- return(ret);
+ return ret;
}
/* Clear a pending IrLAP disconnect. - Jean II */
diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h
index 3ffc1d0f93d6..fff11b7fe8a4 100644
--- a/include/net/irda/irlmp.h
+++ b/include/net/irda/irlmp.h
@@ -274,7 +274,7 @@ static inline int irlmp_lap_tx_queue_full(struct lsap_cb *self)
if (self->lap->irlap == NULL)
return 0;
- return(IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap) >= LAP_HIGH_THRESHOLD);
+ return IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap) >= LAP_HIGH_THRESHOLD;
}
/* After doing a irlmp_dup(), this get one of the two socket back into
diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h
index 11aee7a2972a..af4b87721d13 100644
--- a/include/net/irda/irttp.h
+++ b/include/net/irda/irttp.h
@@ -204,7 +204,7 @@ static inline int irttp_is_primary(struct tsap_cb *self)
(self->lsap->lap == NULL) ||
(self->lsap->lap->irlap == NULL))
return -2;
- return(irlap_is_primary(self->lsap->lap->irlap));
+ return irlap_is_primary(self->lsap->lap->irlap);
}
#endif /* IRTTP_H */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index b0787a1dea90..9fdf982d1286 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -149,6 +149,7 @@ struct ieee80211_low_level_stats {
* @BSS_CHANGED_ARP_FILTER: Hardware ARP filter address list or state changed.
* @BSS_CHANGED_QOS: QoS for this association was enabled/disabled. Note
* that it is only ever disabled for station mode.
+ * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface.
*/
enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0,
@@ -165,6 +166,7 @@ enum ieee80211_bss_change {
BSS_CHANGED_IBSS = 1<<11,
BSS_CHANGED_ARP_FILTER = 1<<12,
BSS_CHANGED_QOS = 1<<13,
+ BSS_CHANGED_IDLE = 1<<14,
/* when adding here, make sure to change ieee80211_reconfig */
};
@@ -223,6 +225,9 @@ enum ieee80211_bss_change {
* hardware must not perform any ARP filtering. Note, that the filter will
* be enabled also in promiscuous mode.
* @qos: This is a QoS-enabled BSS.
+ * @idle: This interface is idle. There's also a global idle flag in the
+ * hardware config which may be more appropriate depending on what
+ * your driver/device needs to do.
*/
struct ieee80211_bss_conf {
const u8 *bssid;
@@ -247,6 +252,7 @@ struct ieee80211_bss_conf {
u8 arp_addr_cnt;
bool arp_filter_enabled;
bool qos;
+ bool idle;
};
/**
@@ -315,6 +321,9 @@ struct ieee80211_bss_conf {
* @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame
* @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this
* frame and selects the maximum number of streams that it can use.
+ *
+ * Note: If you have to add new flags to the enumeration, then don't
+ * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
*/
enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
@@ -344,6 +353,19 @@ enum mac80211_tx_control_flags {
#define IEEE80211_TX_CTL_STBC_SHIFT 23
+/*
+ * This definition is used as a mask to clear all temporary flags, which are
+ * set by the tx handlers for each transmission attempt by the mac80211 stack.
+ */
+#define IEEE80211_TX_TEMPORARY_FLAGS (IEEE80211_TX_CTL_NO_ACK | \
+ IEEE80211_TX_CTL_CLEAR_PS_FILT | IEEE80211_TX_CTL_FIRST_FRAGMENT | \
+ IEEE80211_TX_CTL_SEND_AFTER_DTIM | IEEE80211_TX_CTL_AMPDU | \
+ IEEE80211_TX_STAT_TX_FILTERED | IEEE80211_TX_STAT_ACK | \
+ IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_STAT_AMPDU_NO_BACK | \
+ IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_PSPOLL_RESPONSE | \
+ IEEE80211_TX_CTL_MORE_FRAMES | IEEE80211_TX_CTL_LDPC | \
+ IEEE80211_TX_CTL_STBC)
+
/**
* enum mac80211_rate_control_flags - per-rate flags set by the
* Rate Control algorithm.
@@ -559,9 +581,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
* @RX_FLAG_40MHZ: HT40 (40 MHz) was used
* @RX_FLAG_SHORT_GI: Short guard interval was used
- * @RX_FLAG_INTERNAL_CMTR: set internally after frame was reported
- * on cooked monitor to avoid double-reporting it for multiple
- * virtual interfaces
*/
enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = 1<<0,
@@ -575,7 +594,6 @@ enum mac80211_rx_flags {
RX_FLAG_HT = 1<<9,
RX_FLAG_40MHZ = 1<<10,
RX_FLAG_SHORT_GI = 1<<11,
- RX_FLAG_INTERNAL_CMTR = 1<<12,
};
/**
@@ -596,6 +614,7 @@ enum mac80211_rx_flags {
* @rate_idx: index of data rate into band's supported rates or MCS index if
* HT rates are use (RX_FLAG_HT)
* @flag: %RX_FLAG_*
+ * @rx_flags: internal RX flags for mac80211
*/
struct ieee80211_rx_status {
u64 mactime;
@@ -605,6 +624,7 @@ struct ieee80211_rx_status {
int antenna;
int rate_idx;
int flag;
+ unsigned int rx_flags;
};
/**
@@ -763,6 +783,8 @@ struct ieee80211_channel_switch {
* @bss_conf: BSS configuration for this interface, either our own
* or the BSS we're associated to
* @addr: address of this interface
+ * @p2p: indicates whether this AP or STA interface is a p2p
+ * interface, i.e. a GO or p2p-sta respectively
* @drv_priv: data area for driver use, will always be aligned to
* sizeof(void *).
*/
@@ -770,6 +792,7 @@ struct ieee80211_vif {
enum nl80211_iftype type;
struct ieee80211_bss_conf bss_conf;
u8 addr[ETH_ALEN];
+ bool p2p;
/* must be last */
u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
};
@@ -783,20 +806,6 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
}
/**
- * enum ieee80211_key_alg - key algorithm
- * @ALG_WEP: WEP40 or WEP104
- * @ALG_TKIP: TKIP
- * @ALG_CCMP: CCMP (AES)
- * @ALG_AES_CMAC: AES-128-CMAC
- */
-enum ieee80211_key_alg {
- ALG_WEP,
- ALG_TKIP,
- ALG_CCMP,
- ALG_AES_CMAC,
-};
-
-/**
* enum ieee80211_key_flags - key flags
*
* These flags are used for communication about keys between the driver
@@ -833,7 +842,7 @@ enum ieee80211_key_flags {
* @hw_key_idx: To be set by the driver, this is the key index the driver
* wants to be given when a frame is transmitted and needs to be
* encrypted in hardware.
- * @alg: The key algorithm.
+ * @cipher: The key's cipher suite selector.
* @flags: key flags, see &enum ieee80211_key_flags.
* @keyidx: the key index (0-3)
* @keylen: key material length
@@ -846,7 +855,7 @@ enum ieee80211_key_flags {
* @iv_len: The IV length for this key type
*/
struct ieee80211_key_conf {
- enum ieee80211_key_alg alg;
+ u32 cipher;
u8 icv_len;
u8 iv_len;
u8 hw_key_idx;
@@ -1032,6 +1041,13 @@ enum ieee80211_tkip_key_type {
* @IEEE80211_HW_NEED_DTIM_PERIOD:
* This device needs to know the DTIM period for the BSS before
* associating.
+ *
+ * @IEEE80211_HW_SUPPORTS_PER_STA_GTK: The device's crypto engine supports
+ * per-station GTKs as used by IBSS RSN or during fast transition. If
+ * the device doesn't support per-station GTKs, but can be asked not
+ * to decrypt group addressed frames, then IBSS RSN support is still
+ * possible but software crypto will be used. Advertise the wiphy flag
+ * only in that case.
*/
enum ieee80211_hw_flags {
IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -1055,6 +1071,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18,
IEEE80211_HW_CONNECTION_MONITOR = 1<<19,
IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20,
+ IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21,
};
/**
@@ -1100,8 +1117,15 @@ enum ieee80211_hw_flags {
* @sta_data_size: size (in bytes) of the drv_priv data area
* within &struct ieee80211_sta.
*
- * @max_rates: maximum number of alternate rate retry stages
+ * @max_rates: maximum number of alternate rate retry stages the hw
+ * can handle.
+ * @max_report_rates: maximum number of alternate rate retry stages
+ * the hw can report back.
* @max_rate_tries: maximum number of tries for each stage
+ *
+ * @napi_weight: weight used for NAPI polling. You must specify an
+ * appropriate value here if a napi_poll operation is provided
+ * by your driver.
*/
struct ieee80211_hw {
struct ieee80211_conf conf;
@@ -1113,10 +1137,12 @@ struct ieee80211_hw {
int channel_change_time;
int vif_data_size;
int sta_data_size;
+ int napi_weight;
u16 queues;
u16 max_listen_interval;
s8 max_signal;
u8 max_rates;
+ u8 max_report_rates;
u8 max_rate_tries;
};
@@ -1245,8 +1271,8 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
* %IEEE80211_CONF_PS flag enabled means that the powersave mode defined in
* IEEE 802.11-2007 section 11.2 is enabled. This is not to be confused
* with hardware wakeup and sleep states. Driver is responsible for waking
- * up the hardware before issueing commands to the hardware and putting it
- * back to sleep at approriate times.
+ * up the hardware before issuing commands to the hardware and putting it
+ * back to sleep at appropriate times.
*
* When PS is enabled, hardware needs to wakeup for beacons and receive the
* buffered multicast/broadcast frames after the beacon. Also it must be
@@ -1267,7 +1293,7 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
* there's data traffic and still saving significantly power in idle
* periods.
*
- * Dynamic powersave is supported by simply mac80211 enabling and disabling
+ * Dynamic powersave is simply supported by mac80211 enabling and disabling
* PS based on traffic. Driver needs to only set %IEEE80211_HW_SUPPORTS_PS
* flag and mac80211 will handle everything automatically. Additionally,
* hardware having support for the dynamic PS feature may set the
@@ -1452,12 +1478,14 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
* honour this flag if possible.
*
* @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS
- * is not set then only those addressed to this station.
+ * is not set then only those addressed to this station.
*
* @FIF_OTHER_BSS: pass frames destined to other BSSes
*
- * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only
- * those addressed to this station.
+ * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only
+ * those addressed to this station.
+ *
+ * @FIF_PROBE_REQ: pass probe request frames
*/
enum ieee80211_filter_flags {
FIF_PROMISC_IN_BSS = 1<<0,
@@ -1468,6 +1496,7 @@ enum ieee80211_filter_flags {
FIF_CONTROL = 1<<5,
FIF_OTHER_BSS = 1<<6,
FIF_PSPOLL = 1<<7,
+ FIF_PROBE_REQ = 1<<8,
};
/**
@@ -1540,6 +1569,12 @@ enum ieee80211_ampdu_mlme_action {
* negative error code (which will be seen in userspace.)
* Must be implemented and can sleep.
*
+ * @change_interface: Called when a netdevice changes type. This callback
+ * is optional, but only if it is supported can interface types be
+ * switched while the interface is UP. The callback may sleep.
+ * Note that while an interface is being switched, it will not be
+ * found by the interface iteration callbacks.
+ *
* @remove_interface: Notifies a driver that an interface is going down.
* The @stop callback is called after this if it is the last interface
* and no monitor interfaces are present.
@@ -1687,6 +1722,8 @@ enum ieee80211_ampdu_mlme_action {
* switch operation for CSAs received from the AP may implement this
* callback. They must then call ieee80211_chswitch_done() to indicate
* completion of the channel switch.
+ *
+ * @napi_poll: Poll Rx queue for incoming data frames.
*/
struct ieee80211_ops {
int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -1694,6 +1731,9 @@ struct ieee80211_ops {
void (*stop)(struct ieee80211_hw *hw);
int (*add_interface)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
+ int (*change_interface)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum nl80211_iftype new_type, bool p2p);
void (*remove_interface)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int (*config)(struct ieee80211_hw *hw, u32 changed);
@@ -1752,6 +1792,7 @@ struct ieee80211_ops {
void (*flush)(struct ieee80211_hw *hw, bool drop);
void (*channel_switch)(struct ieee80211_hw *hw,
struct ieee80211_channel_switch *ch_switch);
+ int (*napi_poll)(struct ieee80211_hw *hw, int budget);
};
/**
@@ -1897,6 +1938,22 @@ void ieee80211_free_hw(struct ieee80211_hw *hw);
*/
void ieee80211_restart_hw(struct ieee80211_hw *hw);
+/** ieee80211_napi_schedule - schedule NAPI poll
+ *
+ * Use this function to schedule NAPI polling on a device.
+ *
+ * @hw: the hardware to start polling
+ */
+void ieee80211_napi_schedule(struct ieee80211_hw *hw);
+
+/** ieee80211_napi_complete - complete NAPI polling
+ *
+ * Use this function to finish NAPI polling on a device.
+ *
+ * @hw: the hardware to stop polling
+ */
+void ieee80211_napi_complete(struct ieee80211_hw *hw);
+
/**
* ieee80211_rx - receive frame
*
@@ -2252,7 +2309,8 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw);
*
* When hardware scan offload is used (i.e. the hw_scan() callback is
* assigned) this function needs to be called by the driver to notify
- * mac80211 that the scan finished.
+ * mac80211 that the scan finished. This function can be called from
+ * any context, including hardirq context.
*
* @hw: the hardware that finished the scan
* @aborted: set to true if scan was aborted
@@ -2267,6 +2325,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted);
* This function allows the iterator function to sleep, when the iterator
* function is atomic @ieee80211_iterate_active_interfaces_atomic can
* be used.
+ * Does not iterate over a new interface during add_interface()
*
* @hw: the hardware struct of which the interfaces should be iterated over
* @iterator: the iterator function to call
@@ -2284,6 +2343,7 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
* hardware that are currently active and calls the callback for them.
* This function requires the iterator callback function to be atomic,
* if that is not desired, use @ieee80211_iterate_active_interfaces instead.
+ * Does not iterate over a new interface during add_interface()
*
* @hw: the hardware struct of which the interfaces should be iterated over
* @iterator: the iterator function to call, cannot sleep
@@ -2385,25 +2445,28 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
const u8 *addr);
/**
- * ieee80211_find_sta_by_hw - find a station on hardware
+ * ieee80211_find_sta_by_ifaddr - find a station on hardware
*
* @hw: pointer as obtained from ieee80211_alloc_hw()
- * @addr: station's address
+ * @addr: remote station's address
+ * @localaddr: local address (vif->sdata->vif.addr). Use NULL for 'any'.
*
* This function must be called under RCU lock and the
* resulting pointer is only valid under RCU lock as well.
*
- * NOTE: This function should not be used! When mac80211 is converted
- * internally to properly keep track of stations on multiple
- * virtual interfaces, it will not always know which station to
- * return here since a single address might be used by multiple
- * logical stations (e.g. consider a station connecting to another
- * BSSID on the same AP hardware without disconnecting first).
+ * NOTE: You may pass NULL for localaddr, but then you will just get
+ * the first STA that matches the remote address 'addr'.
+ * We can have multiple STA associated with multiple
+ * logical stations (e.g. consider a station connecting to another
+ * BSSID on the same AP hardware without disconnecting first).
+ * In this case, the result of this method with localaddr NULL
+ * is not reliable.
*
- * DO NOT USE THIS FUNCTION.
+ * DO NOT USE THIS FUNCTION with localaddr NULL if at all possible.
*/
-struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
- const u8 *addr);
+struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw,
+ const u8 *addr,
+ const u8 *localaddr);
/**
* ieee80211_sta_block_awake - block station from waking up
@@ -2442,7 +2505,7 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
*
- * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTERING and
+ * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER and
* %IEEE80211_CONF_PS is set, the driver needs to inform whenever the
* hardware is not receiving beacons with this function.
*/
@@ -2453,7 +2516,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif);
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
*
- * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTERING, and
+ * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER, and
* %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver
* needs to inform if the connection to the AP has been lost.
*
@@ -2518,6 +2581,34 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
*/
void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success);
+/**
+ * ieee80211_request_smps - request SM PS transition
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @smps_mode: new SM PS mode
+ *
+ * This allows the driver to request an SM PS transition in managed
+ * mode. This is useful when the driver has more information than
+ * the stack about possible interference, for example by bluetooth.
+ */
+void ieee80211_request_smps(struct ieee80211_vif *vif,
+ enum ieee80211_smps_mode smps_mode);
+
+/**
+ * ieee80211_key_removed - disable hw acceleration for key
+ * @key_conf: The key hw acceleration should be disabled for
+ *
+ * This allows drivers to indicate that the given key has been
+ * removed from hardware acceleration, due to a new key that
+ * was added. Don't use this if the key can continue to be used
+ * for TX, if the key restriction is on RX only it is permitted
+ * to keep the key for TX only and not call this function.
+ *
+ * Due to locking constraints, it may only be called during
+ * @set_key. This function must be allowed to sleep, and the
+ * key it tries to disable may still be used until it returns.
+ */
+void ieee80211_key_removed(struct ieee80211_key_conf *key_conf);
+
/* Rate control API */
/**
@@ -2681,4 +2772,26 @@ conf_is_ht(struct ieee80211_conf *conf)
return conf->channel_type != NL80211_CHAN_NO_HT;
}
+static inline enum nl80211_iftype
+ieee80211_iftype_p2p(enum nl80211_iftype type, bool p2p)
+{
+ if (p2p) {
+ switch (type) {
+ case NL80211_IFTYPE_STATION:
+ return NL80211_IFTYPE_P2P_CLIENT;
+ case NL80211_IFTYPE_AP:
+ return NL80211_IFTYPE_P2P_GO;
+ default:
+ break;
+ }
+ }
+ return type;
+}
+
+static inline enum nl80211_iftype
+ieee80211_vif_type_p2p(struct ieee80211_vif *vif)
+{
+ return ieee80211_iftype_p2p(vif->type, vif->p2p);
+}
+
#endif /* MAC80211_H */
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 242879b6c4df..55590ab16b3e 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -91,26 +91,28 @@ struct neigh_statistics {
#define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field)
struct neighbour {
- struct neighbour *next;
+ struct neighbour __rcu *next;
struct neigh_table *tbl;
struct neigh_parms *parms;
- struct net_device *dev;
- unsigned long used;
unsigned long confirmed;
unsigned long updated;
__u8 flags;
__u8 nud_state;
__u8 type;
__u8 dead;
+ atomic_t refcnt;
+ struct sk_buff_head arp_queue;
+ struct timer_list timer;
+ unsigned long used;
atomic_t probes;
rwlock_t lock;
+ seqlock_t ha_lock;
unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
struct hh_cache *hh;
- atomic_t refcnt;
int (*output)(struct sk_buff *skb);
- struct sk_buff_head arp_queue;
- struct timer_list timer;
const struct neigh_ops *ops;
+ struct rcu_head rcu;
+ struct net_device *dev;
u8 primary_key[0];
};
@@ -138,13 +140,22 @@ struct pneigh_entry {
* neighbour table manipulation
*/
+struct neigh_hash_table {
+ struct neighbour __rcu **hash_buckets;
+ unsigned int hash_mask;
+ __u32 hash_rnd;
+ struct rcu_head rcu;
+};
+
struct neigh_table {
struct neigh_table *next;
int family;
int entry_size;
int key_len;
- __u32 (*hash)(const void *pkey, const struct net_device *);
+ __u32 (*hash)(const void *pkey,
+ const struct net_device *dev,
+ __u32 hash_rnd);
int (*constructor)(struct neighbour *);
int (*pconstructor)(struct pneigh_entry *);
void (*pdestructor)(struct pneigh_entry *);
@@ -163,11 +174,9 @@ struct neigh_table {
atomic_t entries;
rwlock_t lock;
unsigned long last_rand;
- struct kmem_cache *kmem_cachep;
+ struct kmem_cache *kmem_cachep;
struct neigh_statistics __percpu *stats;
- struct neighbour **hash_buckets;
- unsigned int hash_mask;
- __u32 hash_rnd;
+ struct neigh_hash_table __rcu *nht;
struct pneigh_entry **phash_buckets;
};
@@ -237,6 +246,7 @@ extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_en
struct neigh_seq_state {
struct seq_net_private p;
struct neigh_table *tbl;
+ struct neigh_hash_table *nht;
void *(*neigh_sub_iter)(struct neigh_seq_state *state,
struct neighbour *n, loff_t *pos);
unsigned int bucket;
@@ -293,7 +303,10 @@ static inline void neigh_confirm(struct neighbour *neigh)
static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
{
- neigh->used = jiffies;
+ unsigned long now = ACCESS_ONCE(jiffies);
+
+ if (neigh->used != now)
+ neigh->used = now;
if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
return __neigh_event_send(neigh, skb);
return 0;
@@ -364,4 +377,14 @@ struct neighbour_cb {
#define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb)
+static inline void neigh_ha_snapshot(char *dst, const struct neighbour *n,
+ const struct net_device *dev)
+{
+ unsigned int seq;
+
+ do {
+ seq = read_seqbegin(&n->ha_lock);
+ memcpy(dst, n->ha, dev->addr_len);
+ } while (read_seqretry(&n->ha_lock, seq));
+}
#endif
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index bd10a7908993..65af9a07cf76 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -41,6 +41,8 @@ struct net {
* destroy on demand
*/
#endif
+ spinlock_t rules_mod_lock;
+
struct list_head list; /* list of network namespaces */
struct list_head cleanup_list; /* namespaces on death row */
struct list_head exit_list; /* Use only net_mutex */
@@ -52,7 +54,8 @@ struct net {
struct ctl_table_set sysctls;
#endif
- struct net_device *loopback_dev; /* The loopback */
+ struct sock *rtnl; /* rtnetlink socket */
+ struct sock *genl_sock;
struct list_head dev_base_head;
struct hlist_head *dev_name_head;
@@ -60,11 +63,9 @@ struct net {
/* core fib_rules */
struct list_head rules_ops;
- spinlock_t rules_mod_lock;
- struct sock *rtnl; /* rtnetlink socket */
- struct sock *genl_sock;
+ struct net_device *loopback_dev; /* The loopback */
struct netns_core core;
struct netns_mib mib;
struct netns_packet packet;
@@ -84,13 +85,15 @@ struct net {
struct sock *nfnl;
struct sock *nfnl_stash;
#endif
-#ifdef CONFIG_XFRM
- struct netns_xfrm xfrm;
-#endif
#ifdef CONFIG_WEXT_CORE
struct sk_buff_head wext_nlevents;
#endif
struct net_generic *gen;
+
+ /* Note : following structs are cache line aligned */
+#ifdef CONFIG_XFRM
+ struct netns_xfrm xfrm;
+#endif
};
diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
new file mode 100644
index 000000000000..94dd54d76b48
--- /dev/null
+++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
@@ -0,0 +1,6 @@
+#ifndef _NF_DEFRAG_IPV6_H
+#define _NF_DEFRAG_IPV6_H
+
+extern void nf_defrag_ipv6_enable(void);
+
+#endif /* _NF_DEFRAG_IPV6_H */
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h
index 11e815084fcf..0f8a8c587532 100644
--- a/include/net/netfilter/nf_conntrack_expect.h
+++ b/include/net/netfilter/nf_conntrack_expect.h
@@ -67,9 +67,6 @@ struct nf_conntrack_expect_policy {
#define NF_CT_EXPECT_CLASS_DEFAULT 0
-#define NF_CT_EXPECT_PERMANENT 0x1
-#define NF_CT_EXPECT_INACTIVE 0x2
-
int nf_conntrack_expect_init(struct net *net);
void nf_conntrack_expect_fini(struct net *net);
@@ -85,9 +82,16 @@ struct nf_conntrack_expect *
nf_ct_find_expectation(struct net *net, u16 zone,
const struct nf_conntrack_tuple *tuple);
-void nf_ct_unlink_expect(struct nf_conntrack_expect *exp);
+void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,
+ u32 pid, int report);
+static inline void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
+{
+ nf_ct_unlink_expect_report(exp, 0, 0);
+}
+
void nf_ct_remove_expectations(struct nf_conn *ct);
void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
+void nf_ct_remove_userspace_expectations(void);
/* Allocate space for an expectation: this is mandatory before calling
nf_ct_expect_related. You will have to call put afterwards. */
diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h
index df17bac46bf5..93cc90d28e66 100644
--- a/include/net/netfilter/nf_nat_protocol.h
+++ b/include/net/netfilter/nf_nat_protocol.h
@@ -45,9 +45,6 @@ struct nf_nat_protocol {
extern int nf_nat_protocol_register(const struct nf_nat_protocol *proto);
extern void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto);
-extern const struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol);
-extern void nf_nat_proto_put(const struct nf_nat_protocol *proto);
-
/* Built-in protocols. */
extern const struct nf_nat_protocol nf_nat_protocol_tcp;
extern const struct nf_nat_protocol nf_nat_protocol_udp;
diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h
index 208b46f4d6d2..cd85b3bc8327 100644
--- a/include/net/netfilter/nf_tproxy_core.h
+++ b/include/net/netfilter/nf_tproxy_core.h
@@ -5,15 +5,201 @@
#include <linux/in.h>
#include <linux/skbuff.h>
#include <net/sock.h>
-#include <net/inet_sock.h>
+#include <net/inet_hashtables.h>
+#include <net/inet6_hashtables.h>
#include <net/tcp.h>
+#define NFT_LOOKUP_ANY 0
+#define NFT_LOOKUP_LISTENER 1
+#define NFT_LOOKUP_ESTABLISHED 2
+
/* look up and get a reference to a matching socket */
-extern struct sock *
+
+
+/* This function is used by the 'TPROXY' target and the 'socket'
+ * match. The following lookups are supported:
+ *
+ * Explicit TProxy target rule
+ * ===========================
+ *
+ * This is used when the user wants to intercept a connection matching
+ * an explicit iptables rule. In this case the sockets are assumed
+ * matching in preference order:
+ *
+ * - match: if there's a fully established connection matching the
+ * _packet_ tuple, it is returned, assuming the redirection
+ * already took place and we process a packet belonging to an
+ * established connection
+ *
+ * - match: if there's a listening socket matching the redirection
+ * (e.g. on-port & on-ip of the connection), it is returned,
+ * regardless if it was bound to 0.0.0.0 or an explicit
+ * address. The reasoning is that if there's an explicit rule, it
+ * does not really matter if the listener is bound to an interface
+ * or to 0. The user already stated that he wants redirection
+ * (since he added the rule).
+ *
+ * "socket" match based redirection (no specific rule)
+ * ===================================================
+ *
+ * There are connections with dynamic endpoints (e.g. FTP data
+ * connection) that the user is unable to add explicit rules
+ * for. These are taken care of by a generic "socket" rule. It is
+ * assumed that the proxy application is trusted to open such
+ * connections without explicit iptables rule (except of course the
+ * generic 'socket' rule). In this case the following sockets are
+ * matched in preference order:
+ *
+ * - match: if there's a fully established connection matching the
+ * _packet_ tuple
+ *
+ * - match: if there's a non-zero bound listener (possibly with a
+ * non-local address) We don't accept zero-bound listeners, since
+ * then local services could intercept traffic going through the
+ * box.
+ *
+ * Please note that there's an overlap between what a TPROXY target
+ * and a socket match will match. Normally if you have both rules the
+ * "socket" match will be the first one, effectively all packets
+ * belonging to established connections going through that one.
+ */
+static inline struct sock *
nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
const __be32 saddr, const __be32 daddr,
const __be16 sport, const __be16 dport,
- const struct net_device *in, bool listening);
+ const struct net_device *in, int lookup_type)
+{
+ struct sock *sk;
+
+ /* look up socket */
+ switch (protocol) {
+ case IPPROTO_TCP:
+ switch (lookup_type) {
+ case NFT_LOOKUP_ANY:
+ sk = __inet_lookup(net, &tcp_hashinfo,
+ saddr, sport, daddr, dport,
+ in->ifindex);
+ break;
+ case NFT_LOOKUP_LISTENER:
+ sk = inet_lookup_listener(net, &tcp_hashinfo,
+ daddr, dport,
+ in->ifindex);
+
+ /* NOTE: we return listeners even if bound to
+ * 0.0.0.0, those are filtered out in
+ * xt_socket, since xt_TPROXY needs 0 bound
+ * listeners too */
+
+ break;
+ case NFT_LOOKUP_ESTABLISHED:
+ sk = inet_lookup_established(net, &tcp_hashinfo,
+ saddr, sport, daddr, dport,
+ in->ifindex);
+ break;
+ default:
+ WARN_ON(1);
+ sk = NULL;
+ break;
+ }
+ break;
+ case IPPROTO_UDP:
+ sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
+ in->ifindex);
+ if (sk && lookup_type != NFT_LOOKUP_ANY) {
+ int connected = (sk->sk_state == TCP_ESTABLISHED);
+ int wildcard = (inet_sk(sk)->inet_rcv_saddr == 0);
+
+ /* NOTE: we return listeners even if bound to
+ * 0.0.0.0, those are filtered out in
+ * xt_socket, since xt_TPROXY needs 0 bound
+ * listeners too */
+ if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) ||
+ (lookup_type == NFT_LOOKUP_LISTENER && connected)) {
+ sock_put(sk);
+ sk = NULL;
+ }
+ }
+ break;
+ default:
+ WARN_ON(1);
+ sk = NULL;
+ }
+
+ pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n",
+ protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk);
+
+ return sk;
+}
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+static inline struct sock *
+nf_tproxy_get_sock_v6(struct net *net, const u8 protocol,
+ const struct in6_addr *saddr, const struct in6_addr *daddr,
+ const __be16 sport, const __be16 dport,
+ const struct net_device *in, int lookup_type)
+{
+ struct sock *sk;
+
+ /* look up socket */
+ switch (protocol) {
+ case IPPROTO_TCP:
+ switch (lookup_type) {
+ case NFT_LOOKUP_ANY:
+ sk = inet6_lookup(net, &tcp_hashinfo,
+ saddr, sport, daddr, dport,
+ in->ifindex);
+ break;
+ case NFT_LOOKUP_LISTENER:
+ sk = inet6_lookup_listener(net, &tcp_hashinfo,
+ daddr, ntohs(dport),
+ in->ifindex);
+
+ /* NOTE: we return listeners even if bound to
+ * 0.0.0.0, those are filtered out in
+ * xt_socket, since xt_TPROXY needs 0 bound
+ * listeners too */
+
+ break;
+ case NFT_LOOKUP_ESTABLISHED:
+ sk = __inet6_lookup_established(net, &tcp_hashinfo,
+ saddr, sport, daddr, ntohs(dport),
+ in->ifindex);
+ break;
+ default:
+ WARN_ON(1);
+ sk = NULL;
+ break;
+ }
+ break;
+ case IPPROTO_UDP:
+ sk = udp6_lib_lookup(net, saddr, sport, daddr, dport,
+ in->ifindex);
+ if (sk && lookup_type != NFT_LOOKUP_ANY) {
+ int connected = (sk->sk_state == TCP_ESTABLISHED);
+ int wildcard = ipv6_addr_any(&inet6_sk(sk)->rcv_saddr);
+
+ /* NOTE: we return listeners even if bound to
+ * 0.0.0.0, those are filtered out in
+ * xt_socket, since xt_TPROXY needs 0 bound
+ * listeners too */
+ if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) ||
+ (lookup_type == NFT_LOOKUP_LISTENER && connected)) {
+ sock_put(sk);
+ sk = NULL;
+ }
+ }
+ break;
+ default:
+ WARN_ON(1);
+ sk = NULL;
+ }
+
+ pr_debug("tproxy socket lookup: proto %u %pI6:%u -> %pI6:%u, lookup type: %d, sock %p\n",
+ protocol, saddr, ntohs(sport), daddr, ntohs(dport), lookup_type, sk);
+
+ return sk;
+}
+#endif
static inline void
nf_tproxy_put_sock(struct sock *sk)
diff --git a/include/net/netfilter/xt_log.h b/include/net/netfilter/xt_log.h
new file mode 100644
index 000000000000..0dfb34a5b53c
--- /dev/null
+++ b/include/net/netfilter/xt_log.h
@@ -0,0 +1,54 @@
+#define S_SIZE (1024 - (sizeof(unsigned int) + 1))
+
+struct sbuff {
+ unsigned int count;
+ char buf[S_SIZE + 1];
+};
+static struct sbuff emergency, *emergency_ptr = &emergency;
+
+static int sb_add(struct sbuff *m, const char *f, ...)
+{
+ va_list args;
+ int len;
+
+ if (likely(m->count < S_SIZE)) {
+ va_start(args, f);
+ len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args);
+ va_end(args);
+ if (likely(m->count + len < S_SIZE)) {
+ m->count += len;
+ return 0;
+ }
+ }
+ m->count = S_SIZE;
+ printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n");
+ return -1;
+}
+
+static struct sbuff *sb_open(void)
+{
+ struct sbuff *m = kmalloc(sizeof(*m), GFP_ATOMIC);
+
+ if (unlikely(!m)) {
+ local_bh_disable();
+ do {
+ m = xchg(&emergency_ptr, NULL);
+ } while (!m);
+ }
+ m->count = 0;
+ return m;
+}
+
+static void sb_close(struct sbuff *m)
+{
+ m->buf[m->count] = 0;
+ printk("%s\n", m->buf);
+
+ if (likely(m != &emergency))
+ kfree(m);
+ else {
+ xchg(&emergency_ptr, m);
+ local_bh_enable();
+ }
+}
+
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 74f119a2829a..748f91f87cd5 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -43,10 +43,6 @@ struct netns_xfrm {
unsigned int policy_count[XFRM_POLICY_MAX * 2];
struct work_struct policy_hash_work;
- struct dst_ops xfrm4_dst_ops;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- struct dst_ops xfrm6_dst_ops;
-#endif
struct sock *nlsk;
struct sock *nlsk_stash;
@@ -58,6 +54,11 @@ struct netns_xfrm {
#ifdef CONFIG_SYSCTL
struct ctl_table_header *sysctl_hdr;
#endif
+
+ struct dst_ops xfrm4_dst_ops;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ struct dst_ops xfrm6_dst_ops;
+#endif
};
#endif
diff --git a/include/net/phonet/pep.h b/include/net/phonet/pep.h
index 35672b1cf44a..b60b28c99e87 100644
--- a/include/net/phonet/pep.h
+++ b/include/net/phonet/pep.h
@@ -45,6 +45,10 @@ struct pep_sock {
u8 tx_fc; /* TX flow control */
u8 init_enable; /* auto-enable at creation */
u8 aligned;
+#ifdef CONFIG_PHONET_PIPECTRLR
+ u8 pipe_state;
+ struct sockaddr_pn remote_pep;
+#endif
};
static inline struct pep_sock *pep_sk(struct sock *sk)
@@ -77,6 +81,11 @@ static inline struct pnpipehdr *pnp_hdr(struct sk_buff *skb)
#define MAX_PNPIPE_HEADER (MAX_PHONET_HEADER + 4)
enum {
+ PNS_PIPE_CREATE_REQ = 0x00,
+ PNS_PIPE_CREATE_RESP,
+ PNS_PIPE_REMOVE_REQ,
+ PNS_PIPE_REMOVE_RESP,
+
PNS_PIPE_DATA = 0x20,
PNS_PIPE_ALIGNED_DATA,
@@ -160,4 +169,21 @@ enum {
PEP_IND_READY,
};
+#ifdef CONFIG_PHONET_PIPECTRLR
+#define PNS_PEP_CONNECT_UTID 0x02
+#define PNS_PIPE_CREATED_IND_UTID 0x04
+#define PNS_PIPE_ENABLE_UTID 0x0A
+#define PNS_PIPE_ENABLED_IND_UTID 0x0C
+#define PNS_PIPE_DISABLE_UTID 0x0F
+#define PNS_PIPE_DISABLED_IND_UTID 0x11
+#define PNS_PEP_DISCONNECT_UTID 0x06
+
+/* Used for tracking state of a pipe */
+enum {
+ PIPE_IDLE,
+ PIPE_DISABLED,
+ PIPE_ENABLED,
+};
+#endif /* CONFIG_PHONET_PIPECTRLR */
+
#endif
diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
index 7b114079a51b..d5df797f9540 100644
--- a/include/net/phonet/phonet.h
+++ b/include/net/phonet/phonet.h
@@ -54,6 +54,11 @@ void pn_sock_hash(struct sock *sk);
void pn_sock_unhash(struct sock *sk);
int pn_sock_get_port(struct sock *sk, unsigned short sport);
+struct sock *pn_find_sock_by_res(struct net *net, u8 res);
+int pn_sock_bind_res(struct sock *sock, u8 res);
+int pn_sock_unbind_res(struct sock *sk, u8 res);
+void pn_sock_unbind_all_res(struct sock *sk);
+
int pn_skb_send(struct sock *sk, struct sk_buff *skb,
const struct sockaddr_pn *target);
diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h
index 2d16783d5e20..13649eb57413 100644
--- a/include/net/phonet/pn_dev.h
+++ b/include/net/phonet/pn_dev.h
@@ -57,5 +57,6 @@ struct net_device *phonet_route_output(struct net *net, u8 daddr);
#define PN_NO_ADDR 0xff
extern const struct file_operations pn_sock_seq_fops;
+extern const struct file_operations pn_res_seq_fops;
#endif
diff --git a/include/net/raw.h b/include/net/raw.h
index 43c57502659b..42ce6fe7a2d5 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -45,7 +45,10 @@ struct raw_iter_state {
struct raw_hashinfo *h;
};
-#define raw_seq_private(seq) ((struct raw_iter_state *)(seq)->private)
+static inline struct raw_iter_state *raw_seq_private(struct seq_file *seq)
+{
+ return seq->private;
+}
void *raw_seq_start(struct seq_file *seq, loff_t *pos);
void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos);
void raw_seq_stop(struct seq_file *seq, void *v);
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index af60fd050844..e013c68bfb00 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -79,7 +79,6 @@ struct rtnl_link_ops {
extern int __rtnl_link_register(struct rtnl_link_ops *ops);
extern void __rtnl_link_unregister(struct rtnl_link_ops *ops);
-extern void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops);
extern int rtnl_link_register(struct rtnl_link_ops *ops);
extern void rtnl_link_unregister(struct rtnl_link_ops *ops);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 3c8728aaab4e..ea1f8a83160d 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -328,8 +328,7 @@ extern void qdisc_destroy(struct Qdisc *qdisc);
extern void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n);
extern struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
struct Qdisc_ops *ops);
-extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
- struct netdev_queue *dev_queue,
+extern struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
struct Qdisc_ops *ops, u32 parentid);
extern void qdisc_calculate_pkt_len(struct sk_buff *skb,
struct qdisc_size_table *stab);
@@ -601,7 +600,7 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen)
slot = 0;
slot >>= rtab->rate.cell_log;
if (slot > 255)
- return (rtab->data[255]*(slot >> 8) + rtab->data[slot & 0xFF]);
+ return rtab->data[255]*(slot >> 8) + rtab->data[slot & 0xFF];
return rtab->data[slot];
}
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 65946bc43d00..505845ddb0be 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -275,24 +275,35 @@ struct sctp_mib {
/* Print debugging messages. */
#if SCTP_DEBUG
extern int sctp_debug_flag;
-#define SCTP_DEBUG_PRINTK(whatever...) \
- ((void) (sctp_debug_flag && printk(KERN_DEBUG whatever)))
-#define SCTP_DEBUG_PRINTK_IPADDR(lead, trail, leadparm, saddr, otherparms...) \
- if (sctp_debug_flag) { \
- if (saddr->sa.sa_family == AF_INET6) { \
- printk(KERN_DEBUG \
- lead "%pI6" trail, \
- leadparm, \
- &saddr->v6.sin6_addr, \
- otherparms); \
- } else { \
- printk(KERN_DEBUG \
- lead "%pI4" trail, \
- leadparm, \
- &saddr->v4.sin_addr.s_addr, \
- otherparms); \
- } \
- }
+#define SCTP_DEBUG_PRINTK(fmt, args...) \
+do { \
+ if (sctp_debug_flag) \
+ printk(KERN_DEBUG pr_fmt(fmt), ##args); \
+} while (0)
+#define SCTP_DEBUG_PRINTK_CONT(fmt, args...) \
+do { \
+ if (sctp_debug_flag) \
+ pr_cont(fmt, ##args); \
+} while (0)
+#define SCTP_DEBUG_PRINTK_IPADDR(fmt_lead, fmt_trail, \
+ args_lead, saddr, args_trail...) \
+do { \
+ if (sctp_debug_flag) { \
+ if (saddr->sa.sa_family == AF_INET6) { \
+ printk(KERN_DEBUG \
+ pr_fmt(fmt_lead "%pI6" fmt_trail), \
+ args_lead, \
+ &saddr->v6.sin6_addr, \
+ args_trail); \
+ } else { \
+ printk(KERN_DEBUG \
+ pr_fmt(fmt_lead "%pI4" fmt_trail), \
+ args_lead, \
+ &saddr->v4.sin_addr.s_addr, \
+ args_trail); \
+ } \
+ } \
+} while (0)
#define SCTP_ENABLE_DEBUG { sctp_debug_flag = 1; }
#define SCTP_DISABLE_DEBUG { sctp_debug_flag = 0; }
@@ -306,6 +317,7 @@ extern int sctp_debug_flag;
#else /* SCTP_DEBUG */
#define SCTP_DEBUG_PRINTK(whatever...)
+#define SCTP_DEBUG_PRINTK_CONT(fmt, args...)
#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
#define SCTP_ENABLE_DEBUG
#define SCTP_DISABLE_DEBUG
@@ -393,7 +405,7 @@ static inline void sctp_v6_del_protocol(void) { return; }
/* Map an association to an assoc_id. */
static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc)
{
- return (asoc?asoc->assoc_id:0);
+ return asoc ? asoc->assoc_id : 0;
}
/* Look up the association by its id. */
@@ -461,7 +473,7 @@ static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
/* Tests if the list has one and only one entry. */
static inline int sctp_list_single_entry(struct list_head *head)
{
- return ((head->next != head) && (head->next == head->prev));
+ return (head->next != head) && (head->next == head->prev);
}
/* Generate a random jitter in the range of -50% ~ +50% of input RTO. */
@@ -619,13 +631,13 @@ static inline int sctp_sanity_check(void)
/* This is the hash function for the SCTP port hash table. */
static inline int sctp_phashfn(__u16 lport)
{
- return (lport & (sctp_port_hashsize - 1));
+ return lport & (sctp_port_hashsize - 1);
}
/* This is the hash function for the endpoint hash table. */
static inline int sctp_ep_hashfn(__u16 lport)
{
- return (lport & (sctp_ep_hashsize - 1));
+ return lport & (sctp_ep_hashsize - 1);
}
/* This is the hash function for the association hash table. */
@@ -633,7 +645,7 @@ static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport)
{
int h = (lport << 16) + rport;
h ^= h>>8;
- return (h & (sctp_assoc_hashsize - 1));
+ return h & (sctp_assoc_hashsize - 1);
}
/* This is the hash function for the association hash table. This is
@@ -644,7 +656,7 @@ static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag)
{
int h = (lport << 16) + rport;
h ^= vtag;
- return (h & (sctp_assoc_hashsize-1));
+ return h & (sctp_assoc_hashsize - 1);
}
#define sctp_for_each_hentry(epb, node, head) \
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 4088c89a9055..9352d12f02de 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -345,12 +345,12 @@ enum {
static inline int TSN_lt(__u32 s, __u32 t)
{
- return (((s) - (t)) & TSN_SIGN_BIT);
+ return ((s) - (t)) & TSN_SIGN_BIT;
}
static inline int TSN_lte(__u32 s, __u32 t)
{
- return (((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT));
+ return ((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT);
}
/* Compare two SSNs */
@@ -369,12 +369,12 @@ enum {
static inline int SSN_lt(__u16 s, __u16 t)
{
- return (((s) - (t)) & SSN_SIGN_BIT);
+ return ((s) - (t)) & SSN_SIGN_BIT;
}
static inline int SSN_lte(__u16 s, __u16 t)
{
- return (((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT));
+ return ((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT);
}
/*
@@ -388,7 +388,7 @@ enum {
static inline int ADDIP_SERIAL_gte(__u16 s, __u16 t)
{
- return (((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT));
+ return ((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT);
}
/* Check VTAG of the packet matches the sender's own tag. */
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index f9e7473613bd..69fef4fb79c0 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -847,7 +847,7 @@ void sctp_packet_free(struct sctp_packet *);
static inline int sctp_packet_empty(struct sctp_packet *packet)
{
- return (packet->size == packet->overhead);
+ return packet->size == packet->overhead;
}
/* This represents a remote transport address.
diff --git a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h
index 4aabc5a96cf6..e7728bc14ccf 100644
--- a/include/net/sctp/tsnmap.h
+++ b/include/net/sctp/tsnmap.h
@@ -157,7 +157,7 @@ __u16 sctp_tsnmap_pending(struct sctp_tsnmap *map);
/* Is there a gap in the TSN map? */
static inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map)
{
- return (map->cumulative_tsn_ack_point != map->max_tsn_seen);
+ return map->cumulative_tsn_ack_point != map->max_tsn_seen;
}
/* Mark a duplicate TSN. Note: limit the storage of duplicate TSN
diff --git a/include/net/sock.h b/include/net/sock.h
index adab9dc58183..73a4f9702a65 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1558,7 +1558,11 @@ static inline void sk_wake_async(struct sock *sk, int how, int band)
}
#define SOCK_MIN_SNDBUF 2048
-#define SOCK_MIN_RCVBUF 256
+/*
+ * Since sk_rmem_alloc sums skb->truesize, even a small frame might need
+ * sizeof(sk_buff) + MTU + padding, unless net driver perform copybreak
+ */
+#define SOCK_MIN_RCVBUF (2048 + sizeof(struct sk_buff))
static inline void sk_stream_moderate_sndbuf(struct sock *sk)
{
@@ -1670,17 +1674,13 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
/**
* sock_tx_timestamp - checks whether the outgoing packet is to be time stamped
- * @msg: outgoing packet
* @sk: socket sending this packet
- * @shtx: filled with instructions for time stamping
+ * @tx_flags: filled with instructions for time stamping
*
* Currently only depends on SOCK_TIMESTAMPING* flags. Returns error code if
* parameters are invalid.
*/
-extern int sock_tx_timestamp(struct msghdr *msg,
- struct sock *sk,
- union skb_shared_tx *shtx);
-
+extern int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags);
/**
* sk_eat_skb - Release a skb if it is no longer needed
diff --git a/include/net/tc_act/tc_csum.h b/include/net/tc_act/tc_csum.h
new file mode 100644
index 000000000000..9e8710be7a04
--- /dev/null
+++ b/include/net/tc_act/tc_csum.h
@@ -0,0 +1,15 @@
+#ifndef __NET_TC_CSUM_H
+#define __NET_TC_CSUM_H
+
+#include <linux/types.h>
+#include <net/act_api.h>
+
+struct tcf_csum {
+ struct tcf_common common;
+
+ u32 update_flags;
+};
+#define to_tcf_csum(pc) \
+ container_of(pc,struct tcf_csum,common)
+
+#endif /* __NET_TC_CSUM_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 3e4b33e36602..4fee0424af7e 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -346,8 +346,6 @@ static inline void tcp_dec_quickack_mode(struct sock *sk,
}
}
-extern void tcp_enter_quickack_mode(struct sock *sk);
-
#define TCP_ECN_OK 1
#define TCP_ECN_QUEUE_CWR 2
#define TCP_ECN_DEMAND_CWR 4
@@ -803,6 +801,15 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk)
/* Use define here intentionally to get WARN_ON location shown at the caller */
#define tcp_verify_left_out(tp) WARN_ON(tcp_left_out(tp) > tp->packets_out)
+/*
+ * Convert RFC 3390 larger initial window into an equivalent number of packets.
+ * This is based on the numbers specified in RFC 5681, 3.1.
+ */
+static inline u32 rfc3390_bytes_to_packets(const u32 smss)
+{
+ return smss <= 1095 ? 4 : (smss > 2190 ? 2 : 3);
+}
+
extern void tcp_enter_cwr(struct sock *sk, const int set_ssthresh);
extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst);
diff --git a/include/net/tipc/tipc.h b/include/net/tipc/tipc.h
index 15af6dca0b49..1e0645e1eed2 100644
--- a/include/net/tipc/tipc.h
+++ b/include/net/tipc/tipc.h
@@ -50,8 +50,6 @@
* TIPC operating mode routines
*/
-u32 tipc_get_addr(void);
-
#define TIPC_NOT_RUNNING 0
#define TIPC_NODE_MODE 1
#define TIPC_NET_MODE 2
@@ -62,8 +60,6 @@ int tipc_attach(unsigned int *userref, tipc_mode_event, void *usr_handle);
void tipc_detach(unsigned int userref);
-int tipc_get_mode(void);
-
/*
* TIPC port manipulation routines
*/
@@ -153,12 +149,6 @@ int tipc_disconnect(u32 portref);
int tipc_shutdown(u32 ref);
-int tipc_isconnected(u32 portref, int *isconnected);
-
-int tipc_peer(u32 portref, struct tipc_portid *peer);
-
-int tipc_ref_valid(u32 portref);
-
/*
* TIPC messaging routines
*/
@@ -170,38 +160,12 @@ int tipc_send(u32 portref,
unsigned int num_sect,
struct iovec const *msg_sect);
-int tipc_send_buf(u32 portref,
- struct sk_buff *buf,
- unsigned int dsz);
-
int tipc_send2name(u32 portref,
struct tipc_name const *name,
u32 domain,
unsigned int num_sect,
struct iovec const *msg_sect);
-int tipc_send_buf2name(u32 portref,
- struct tipc_name const *name,
- u32 domain,
- struct sk_buff *buf,
- unsigned int dsz);
-
-int tipc_forward2name(u32 portref,
- struct tipc_name const *name,
- u32 domain,
- unsigned int section_count,
- struct iovec const *msg_sect,
- struct tipc_portid const *origin,
- unsigned int importance);
-
-int tipc_forward_buf2name(u32 portref,
- struct tipc_name const *name,
- u32 domain,
- struct sk_buff *buf,
- unsigned int dsz,
- struct tipc_portid const *orig,
- unsigned int importance);
-
int tipc_send2port(u32 portref,
struct tipc_portid const *dest,
unsigned int num_sect,
@@ -212,46 +176,11 @@ int tipc_send_buf2port(u32 portref,
struct sk_buff *buf,
unsigned int dsz);
-int tipc_forward2port(u32 portref,
- struct tipc_portid const *dest,
- unsigned int num_sect,
- struct iovec const *msg_sect,
- struct tipc_portid const *origin,
- unsigned int importance);
-
-int tipc_forward_buf2port(u32 portref,
- struct tipc_portid const *dest,
- struct sk_buff *buf,
- unsigned int dsz,
- struct tipc_portid const *orig,
- unsigned int importance);
-
int tipc_multicast(u32 portref,
struct tipc_name_seq const *seq,
u32 domain, /* currently unused */
unsigned int section_count,
struct iovec const *msg);
-
-#if 0
-int tipc_multicast_buf(u32 portref,
- struct tipc_name_seq const *seq,
- u32 domain,
- void *buf,
- unsigned int size);
-#endif
-
-/*
- * TIPC subscription routines
- */
-
-int tipc_ispublished(struct tipc_name const *name);
-
-/*
- * Get number of available nodes within specified domain (excluding own node)
- */
-
-unsigned int tipc_available_nodes(const u32 domain);
-
#endif
#endif
diff --git a/include/net/tipc/tipc_msg.h b/include/net/tipc/tipc_msg.h
index 2e159a812f83..ffe50b4e7b93 100644
--- a/include/net/tipc/tipc_msg.h
+++ b/include/net/tipc/tipc_msg.h
@@ -107,7 +107,7 @@ static inline u32 msg_hdr_sz(struct tipc_msg *m)
static inline int msg_short(struct tipc_msg *m)
{
- return (msg_hdr_sz(m) == 24);
+ return msg_hdr_sz(m) == 24;
}
static inline u32 msg_size(struct tipc_msg *m)
@@ -117,7 +117,7 @@ static inline u32 msg_size(struct tipc_msg *m)
static inline u32 msg_data_sz(struct tipc_msg *m)
{
- return (msg_size(m) - msg_hdr_sz(m));
+ return msg_size(m) - msg_hdr_sz(m);
}
static inline unchar *msg_data(struct tipc_msg *m)
@@ -132,17 +132,17 @@ static inline u32 msg_type(struct tipc_msg *m)
static inline u32 msg_named(struct tipc_msg *m)
{
- return (msg_type(m) == TIPC_NAMED_MSG);
+ return msg_type(m) == TIPC_NAMED_MSG;
}
static inline u32 msg_mcast(struct tipc_msg *m)
{
- return (msg_type(m) == TIPC_MCAST_MSG);
+ return msg_type(m) == TIPC_MCAST_MSG;
}
static inline u32 msg_connected(struct tipc_msg *m)
{
- return (msg_type(m) == TIPC_CONN_MSG);
+ return msg_type(m) == TIPC_CONN_MSG;
}
static inline u32 msg_errcode(struct tipc_msg *m)
diff --git a/include/net/tipc/tipc_port.h b/include/net/tipc/tipc_port.h
index c54917cbfa48..1893aaf49426 100644
--- a/include/net/tipc/tipc_port.h
+++ b/include/net/tipc/tipc_port.h
@@ -88,8 +88,6 @@ void tipc_acknowledge(u32 port_ref,u32 ack);
struct tipc_port *tipc_get_port(const u32 ref);
-void *tipc_get_handle(const u32 ref);
-
/*
* The following routines require that the port be locked on entry
*/
diff --git a/include/net/udp.h b/include/net/udp.h
index a184d3496b13..200b82848c9a 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -183,6 +183,9 @@ extern int udp_lib_setsockopt(struct sock *sk, int level, int optname,
extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
__be32 daddr, __be16 dport,
int dif);
+extern struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport,
+ const struct in6_addr *daddr, __be16 dport,
+ int dif);
/*
* SNMP statistics for UDP and UDP-Lite
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 4f53532d4c2f..f28d7c9b9f8d 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1419,7 +1419,6 @@ 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 void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr);
extern __be32 xfrm6_tunnel_spi_lookup(struct net *net, 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);
@@ -1466,8 +1465,6 @@ struct xfrm_state *xfrm_find_acq(struct net *net, struct xfrm_mark *mark,
xfrm_address_t *saddr, int create,
unsigned short family);
extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
-extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
- struct flowi *fl, int family, int strict);
#ifdef CONFIG_XFRM_MIGRATE
extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
diff --git a/net/802/fc.c b/net/802/fc.c
index 34cf1ee014b8..1e49f2d4ea96 100644
--- a/net/802/fc.c
+++ b/net/802/fc.c
@@ -70,7 +70,7 @@ static int fc_header(struct sk_buff *skb, struct net_device *dev,
if(daddr)
{
memcpy(fch->daddr,daddr,dev->addr_len);
- return(hdr_len);
+ return hdr_len;
}
return -hdr_len;
}
diff --git a/net/802/fddi.c b/net/802/fddi.c
index 3ef0ab0a543a..94b3ad08f39a 100644
--- a/net/802/fddi.c
+++ b/net/802/fddi.c
@@ -82,10 +82,10 @@ static int fddi_header(struct sk_buff *skb, struct net_device *dev,
if (daddr != NULL)
{
memcpy(fddi->daddr, daddr, dev->addr_len);
- return(hl);
+ return hl;
}
- return(-hl);
+ return -hl;
}
@@ -108,7 +108,7 @@ static int fddi_rebuild_header(struct sk_buff *skb)
{
printk("%s: Don't know how to resolve type %04X addresses.\n",
skb->dev->name, ntohs(fddi->hdr.llc_snap.ethertype));
- return(0);
+ return 0;
}
}
@@ -162,7 +162,7 @@ __be16 fddi_type_trans(struct sk_buff *skb, struct net_device *dev)
/* Assume 802.2 SNAP frames, for now */
- return(type);
+ return type;
}
EXPORT_SYMBOL(fddi_type_trans);
@@ -170,9 +170,9 @@ EXPORT_SYMBOL(fddi_type_trans);
int fddi_change_mtu(struct net_device *dev, int new_mtu)
{
if ((new_mtu < FDDI_K_SNAP_HLEN) || (new_mtu > FDDI_K_SNAP_DLEN))
- return(-EINVAL);
+ return -EINVAL;
dev->mtu = new_mtu;
- return(0);
+ return 0;
}
EXPORT_SYMBOL(fddi_change_mtu);
diff --git a/net/802/hippi.c b/net/802/hippi.c
index cd3e8e929529..91aca8780fd0 100644
--- a/net/802/hippi.c
+++ b/net/802/hippi.c
@@ -152,7 +152,7 @@ int hippi_change_mtu(struct net_device *dev, int new_mtu)
if ((new_mtu < 68) || (new_mtu > 65280))
return -EINVAL;
dev->mtu = new_mtu;
- return(0);
+ return 0;
}
EXPORT_SYMBOL(hippi_change_mtu);
diff --git a/net/802/tr.c b/net/802/tr.c
index 1c6e596074df..5e20cf8a074b 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -145,7 +145,7 @@ static int tr_header(struct sk_buff *skb, struct net_device *dev,
{
memcpy(trh->daddr,daddr,dev->addr_len);
tr_source_route(skb, trh, dev);
- return(hdr_len);
+ return hdr_len;
}
return -hdr_len;
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index a2ad15250575..05b867e43757 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -44,9 +44,6 @@
int vlan_net_id __read_mostly;
-/* Our listing of VLAN group(s) */
-static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
-
const char vlan_fullname[] = "802.1Q VLAN Support";
const char vlan_version[] = DRV_VERSION;
static const char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
@@ -59,40 +56,6 @@ static struct packet_type vlan_packet_type __read_mostly = {
/* End of global variables definitions. */
-static inline unsigned int vlan_grp_hashfn(unsigned int idx)
-{
- return ((idx >> VLAN_GRP_HASH_SHIFT) ^ idx) & VLAN_GRP_HASH_MASK;
-}
-
-/* Must be invoked with RCU read lock (no preempt) */
-static struct vlan_group *__vlan_find_group(struct net_device *real_dev)
-{
- struct vlan_group *grp;
- struct hlist_node *n;
- int hash = vlan_grp_hashfn(real_dev->ifindex);
-
- hlist_for_each_entry_rcu(grp, n, &vlan_group_hash[hash], hlist) {
- if (grp->real_dev == real_dev)
- return grp;
- }
-
- return NULL;
-}
-
-/* Find the protocol handler. Assumes VID < VLAN_VID_MASK.
- *
- * Must be invoked with RCU read lock (no preempt)
- */
-struct net_device *__find_vlan_dev(struct net_device *real_dev, u16 vlan_id)
-{
- struct vlan_group *grp = __vlan_find_group(real_dev);
-
- if (grp)
- return vlan_group_get_device(grp, vlan_id);
-
- return NULL;
-}
-
static void vlan_group_free(struct vlan_group *grp)
{
int i;
@@ -111,8 +74,6 @@ static struct vlan_group *vlan_group_alloc(struct net_device *real_dev)
return NULL;
grp->real_dev = real_dev;
- hlist_add_head_rcu(&grp->hlist,
- &vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]);
return grp;
}
@@ -151,7 +112,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
ASSERT_RTNL();
- grp = __vlan_find_group(real_dev);
+ grp = real_dev->vlgrp;
BUG_ON(!grp);
/* Take it out of our own structures, but be sure to interlock with
@@ -173,11 +134,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
if (grp->nr_vlans == 0) {
vlan_gvrp_uninit_applicant(real_dev);
- if (real_dev->features & NETIF_F_HW_VLAN_RX)
+ rcu_assign_pointer(real_dev->vlgrp, NULL);
+ if (ops->ndo_vlan_rx_register)
ops->ndo_vlan_rx_register(real_dev, NULL);
- hlist_del_rcu(&grp->hlist);
-
/* Free the group, after all cpu's are done. */
call_rcu(&grp->rcu, vlan_rcu_free);
}
@@ -196,18 +156,13 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
return -EOPNOTSUPP;
}
- if ((real_dev->features & NETIF_F_HW_VLAN_RX) && !ops->ndo_vlan_rx_register) {
- pr_info("8021q: device %s has buggy VLAN hw accel\n", name);
- return -EOPNOTSUPP;
- }
-
if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
(!ops->ndo_vlan_rx_add_vid || !ops->ndo_vlan_rx_kill_vid)) {
pr_info("8021q: Device %s has buggy VLAN hw accel\n", name);
return -EOPNOTSUPP;
}
- if (__find_vlan_dev(real_dev, vlan_id) != NULL)
+ if (vlan_find_dev(real_dev, vlan_id) != NULL)
return -EEXIST;
return 0;
@@ -222,7 +177,7 @@ int register_vlan_dev(struct net_device *dev)
struct vlan_group *grp, *ngrp = NULL;
int err;
- grp = __vlan_find_group(real_dev);
+ grp = real_dev->vlgrp;
if (!grp) {
ngrp = grp = vlan_group_alloc(real_dev);
if (!grp)
@@ -252,8 +207,11 @@ int register_vlan_dev(struct net_device *dev)
vlan_group_set_device(grp, vlan_id, dev);
grp->nr_vlans++;
- if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX)
- ops->ndo_vlan_rx_register(real_dev, ngrp);
+ if (ngrp) {
+ if (ops->ndo_vlan_rx_register)
+ ops->ndo_vlan_rx_register(real_dev, ngrp);
+ rcu_assign_pointer(real_dev->vlgrp, ngrp);
+ }
if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
ops->ndo_vlan_rx_add_vid(real_dev, vlan_id);
@@ -264,7 +222,6 @@ out_uninit_applicant:
vlan_gvrp_uninit_applicant(real_dev);
out_free_group:
if (ngrp) {
- hlist_del_rcu(&ngrp->hlist);
/* Free the group, after all cpu's are done. */
call_rcu(&ngrp->rcu, vlan_rcu_free);
}
@@ -321,7 +278,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
if (new_dev == NULL)
return -ENOBUFS;
- new_dev->real_num_tx_queues = real_dev->real_num_tx_queues;
+ netif_copy_real_num_queues(new_dev, real_dev);
dev_net_set(new_dev, net);
/* need 4 bytes for extra VLAN header info,
* hope the underlying device can handle it.
@@ -428,7 +385,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
dev->netdev_ops->ndo_vlan_rx_add_vid(dev, 0);
}
- grp = __vlan_find_group(dev);
+ grp = dev->vlgrp;
if (!grp)
goto out;
@@ -439,7 +396,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
switch (event) {
case NETDEV_CHANGE:
/* Propagate real device state to vlan devices */
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
vlandev = vlan_group_get_device(grp, i);
if (!vlandev)
continue;
@@ -450,7 +407,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
case NETDEV_CHANGEADDR:
/* Adjust unicast filters on underlying device */
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
vlandev = vlan_group_get_device(grp, i);
if (!vlandev)
continue;
@@ -464,7 +421,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
break;
case NETDEV_CHANGEMTU:
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
vlandev = vlan_group_get_device(grp, i);
if (!vlandev)
continue;
@@ -478,7 +435,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
case NETDEV_FEAT_CHANGE:
/* Propagate device features to underlying device */
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
vlandev = vlan_group_get_device(grp, i);
if (!vlandev)
continue;
@@ -490,7 +447,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
case NETDEV_DOWN:
/* Put all VLANs for this dev in the down state too. */
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
vlandev = vlan_group_get_device(grp, i);
if (!vlandev)
continue;
@@ -508,7 +465,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
case NETDEV_UP:
/* Put all VLANs for this dev in the up state too. */
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
vlandev = vlan_group_get_device(grp, i);
if (!vlandev)
continue;
@@ -525,10 +482,14 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
break;
case NETDEV_UNREGISTER:
+ /* twiddle thumbs on netns device moves */
+ if (dev->reg_state != NETREG_UNREGISTERING)
+ break;
+
/* Delete all VLANs for this dev. */
grp->killall = 1;
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ for (i = 0; i < VLAN_N_VID; i++) {
vlandev = vlan_group_get_device(grp, i);
if (!vlandev)
continue;
@@ -536,7 +497,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
/* unregistration of last vlan destroys group, abort
* afterwards */
if (grp->nr_vlans == 1)
- i = VLAN_GROUP_ARRAY_LEN;
+ i = VLAN_N_VID;
unregister_vlan_dev(vlandev, &list);
}
@@ -742,8 +703,6 @@ err0:
static void __exit vlan_cleanup_module(void)
{
- unsigned int i;
-
vlan_ioctl_set(NULL);
vlan_netlink_fini();
@@ -751,10 +710,6 @@ static void __exit vlan_cleanup_module(void)
dev_remove_pack(&vlan_packet_type);
- /* This table must be empty if there are no module references left. */
- for (i = 0; i < VLAN_GRP_HASH_SIZE; i++)
- BUG_ON(!hlist_empty(&vlan_group_hash[i]));
-
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 8d9503ad01da..db01b3181fdc 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -72,23 +72,6 @@ static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev)
return netdev_priv(dev);
}
-#define VLAN_GRP_HASH_SHIFT 5
-#define VLAN_GRP_HASH_SIZE (1 << VLAN_GRP_HASH_SHIFT)
-#define VLAN_GRP_HASH_MASK (VLAN_GRP_HASH_SIZE - 1)
-
-/* Find a VLAN device by the MAC address of its Ethernet device, and
- * it's VLAN ID. The default configuration is to have VLAN's scope
- * to be box-wide, so the MAC will be ignored. The mac will only be
- * looked at if we are configured to have a separate set of VLANs per
- * each MAC addressable interface. Note that this latter option does
- * NOT follow the spec for VLANs, but may be useful for doing very
- * large quantities of VLAN MUX/DEMUX onto FrameRelay or ATM PVCs.
- *
- * Must be invoked with rcu_read_lock (ie preempt disabled)
- * or with RTNL.
- */
-struct net_device *__find_vlan_dev(struct net_device *real_dev, u16 vlan_id);
-
/* 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);
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 0eb96f7e44be..69b2f79800a5 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -4,53 +4,29 @@
#include <linux/netpoll.h>
#include "vlan.h"
-/* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */
-int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
- u16 vlan_tci, int polling)
+bool vlan_hwaccel_do_receive(struct sk_buff **skbp)
{
+ struct sk_buff *skb = *skbp;
+ u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK;
struct net_device *vlan_dev;
- u16 vlan_id;
-
- if (netpoll_rx(skb))
- return NET_RX_DROP;
-
- if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
- skb->deliver_no_wcard = 1;
+ struct vlan_rx_stats *rx_stats;
- skb->skb_iif = skb->dev->ifindex;
- __vlan_hwaccel_put_tag(skb, vlan_tci);
- vlan_id = vlan_tci & VLAN_VID_MASK;
- vlan_dev = vlan_group_get_device(grp, vlan_id);
-
- if (vlan_dev)
- skb->dev = vlan_dev;
- else if (vlan_id) {
- if (!(skb->dev->flags & IFF_PROMISC))
- goto drop;
- skb->pkt_type = PACKET_OTHERHOST;
+ vlan_dev = vlan_find_dev(skb->dev, vlan_id);
+ if (!vlan_dev) {
+ if (vlan_id)
+ skb->pkt_type = PACKET_OTHERHOST;
+ return false;
}
- return (polling ? netif_receive_skb(skb) : netif_rx(skb));
+ skb = *skbp = skb_share_check(skb, GFP_ATOMIC);
+ if (unlikely(!skb))
+ return false;
-drop:
- dev_kfree_skb_any(skb);
- return NET_RX_DROP;
-}
-EXPORT_SYMBOL(__vlan_hwaccel_rx);
-
-int vlan_hwaccel_do_receive(struct sk_buff *skb)
-{
- struct net_device *dev = skb->dev;
- struct vlan_rx_stats *rx_stats;
-
- skb->dev = vlan_dev_info(dev)->real_dev;
- netif_nit_deliver(skb);
-
- skb->dev = dev;
- skb->priority = vlan_get_ingress_priority(dev, skb->vlan_tci);
+ skb->dev = vlan_dev;
+ skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci);
skb->vlan_tci = 0;
- rx_stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats);
+ rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_rx_stats);
u64_stats_update_begin(&rx_stats->syncp);
rx_stats->rx_packets++;
@@ -67,12 +43,13 @@ int vlan_hwaccel_do_receive(struct sk_buff *skb)
* 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,
- dev->dev_addr))
+ vlan_dev->dev_addr))
skb->pkt_type = PACKET_HOST;
break;
}
u64_stats_update_end(&rx_stats->syncp);
- return 0;
+
+ return true;
}
struct net_device *vlan_dev_real_dev(const struct net_device *dev)
@@ -87,71 +64,27 @@ u16 vlan_dev_vlan_id(const struct net_device *dev)
}
EXPORT_SYMBOL(vlan_dev_vlan_id);
-static gro_result_t
-vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
- unsigned int vlan_tci, struct sk_buff *skb)
+/* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */
+int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
+ u16 vlan_tci, int polling)
{
- struct sk_buff *p;
- struct net_device *vlan_dev;
- u16 vlan_id;
-
- if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
- skb->deliver_no_wcard = 1;
-
- skb->skb_iif = skb->dev->ifindex;
__vlan_hwaccel_put_tag(skb, vlan_tci);
- vlan_id = vlan_tci & VLAN_VID_MASK;
- vlan_dev = vlan_group_get_device(grp, vlan_id);
-
- if (vlan_dev)
- skb->dev = vlan_dev;
- else if (vlan_id) {
- if (!(skb->dev->flags & IFF_PROMISC))
- goto drop;
- skb->pkt_type = PACKET_OTHERHOST;
- }
-
- for (p = napi->gro_list; p; p = p->next) {
- NAPI_GRO_CB(p)->same_flow =
- p->dev == skb->dev && !compare_ether_header(
- skb_mac_header(p), skb_gro_mac_header(skb));
- NAPI_GRO_CB(p)->flush = 0;
- }
-
- return dev_gro_receive(napi, skb);
-
-drop:
- return GRO_DROP;
+ return polling ? netif_receive_skb(skb) : netif_rx(skb);
}
+EXPORT_SYMBOL(__vlan_hwaccel_rx);
gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
unsigned int vlan_tci, struct sk_buff *skb)
{
- if (netpoll_rx_on(skb))
- return vlan_hwaccel_receive_skb(skb, grp, vlan_tci)
- ? GRO_DROP : GRO_NORMAL;
-
- skb_gro_reset_offset(skb);
-
- return napi_skb_finish(vlan_gro_common(napi, grp, vlan_tci, skb), skb);
+ __vlan_hwaccel_put_tag(skb, vlan_tci);
+ return napi_gro_receive(napi, skb);
}
EXPORT_SYMBOL(vlan_gro_receive);
gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
unsigned int vlan_tci)
{
- struct sk_buff *skb = napi_frags_skb(napi);
-
- if (!skb)
- return GRO_DROP;
-
- if (netpoll_rx_on(skb)) {
- skb->protocol = eth_type_trans(skb, skb->dev);
- return vlan_hwaccel_receive_skb(skb, grp, vlan_tci)
- ? GRO_DROP : GRO_NORMAL;
- }
-
- return napi_frags_finish(napi, skb,
- vlan_gro_common(napi, grp, vlan_tci, skb));
+ __vlan_hwaccel_put_tag(napi->skb, vlan_tci);
+ return napi_gro_frags(napi);
}
EXPORT_SYMBOL(vlan_gro_frags);
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 3bccdd12a264..14e3d1fa07a0 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -158,7 +158,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
vlan_id = vlan_tci & VLAN_VID_MASK;
rcu_read_lock();
- vlan_dev = __find_vlan_dev(dev, vlan_id);
+ 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
@@ -177,8 +177,8 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
} else {
skb->dev = vlan_dev;
- rx_stats = per_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats,
- smp_processor_id());
+ rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats);
+
u64_stats_update_begin(&rx_stats->syncp);
rx_stats->rx_packets++;
rx_stats->rx_bytes += skb->len;
@@ -226,12 +226,14 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
}
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;
}
@@ -843,7 +845,7 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st
accum.rx_packets += rxpackets;
accum.rx_bytes += rxbytes;
accum.rx_multicast += rxmulticast;
- /* rx_errors is an ulong, not protected by syncp */
+ /* rx_errors is ulong, not protected by syncp */
accum.rx_errors += p->rx_errors;
}
stats->rx_packets = accum.rx_packets;
diff --git a/net/9p/client.c b/net/9p/client.c
index 9eb72505308f..83bf0541d66f 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -61,13 +61,13 @@ static const match_table_t tokens = {
inline int p9_is_proto_dotl(struct p9_client *clnt)
{
- return (clnt->proto_version == p9_proto_2000L);
+ return clnt->proto_version == p9_proto_2000L;
}
EXPORT_SYMBOL(p9_is_proto_dotl);
inline int p9_is_proto_dotu(struct p9_client *clnt)
{
- return (clnt->proto_version == p9_proto_2000u);
+ return clnt->proto_version == p9_proto_2000u;
}
EXPORT_SYMBOL(p9_is_proto_dotu);
@@ -671,7 +671,7 @@ static void p9_fid_destroy(struct p9_fid *fid)
kfree(fid);
}
-int p9_client_version(struct p9_client *c)
+static int p9_client_version(struct p9_client *c)
{
int err = 0;
struct p9_req_t *req;
@@ -730,7 +730,6 @@ error:
return err;
}
-EXPORT_SYMBOL(p9_client_version);
struct p9_client *p9_client_create(const char *dev_name, char *options)
{
@@ -887,54 +886,6 @@ error:
}
EXPORT_SYMBOL(p9_client_attach);
-struct p9_fid *
-p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname)
-{
- int err;
- struct p9_req_t *req;
- struct p9_qid qid;
- struct p9_fid *afid;
-
- P9_DPRINTK(P9_DEBUG_9P, ">>> TAUTH uname %s aname %s\n", uname, aname);
- err = 0;
-
- afid = p9_fid_create(clnt);
- if (IS_ERR(afid)) {
- err = PTR_ERR(afid);
- afid = NULL;
- goto error;
- }
-
- req = p9_client_rpc(clnt, P9_TAUTH, "dss?d",
- afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
- if (err) {
- p9pdu_dump(1, req->rc);
- p9_free_req(clnt, req);
- goto error;
- }
-
- P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n",
- qid.type,
- (unsigned long long)qid.path,
- qid.version);
-
- memmove(&afid->qid, &qid, sizeof(struct p9_qid));
- p9_free_req(clnt, req);
- return afid;
-
-error:
- if (afid)
- p9_fid_destroy(afid);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL(p9_client_auth);
-
struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
int clone)
{
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index c85109d809ca..078eb162d9bf 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -222,7 +222,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
}
}
-static unsigned int
+static int
p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt)
{
int ret, n;
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 95fdd1185067..ff956d1115bc 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -310,9 +310,9 @@ static int clip_constructor(struct neighbour *neigh)
return 0;
}
-static u32 clip_hash(const void *pkey, const struct net_device *dev)
+static u32 clip_hash(const void *pkey, const struct net_device *dev, __u32 rnd)
{
- return jhash_2words(*(u32 *) pkey, dev->ifindex, clip_tbl.hash_rnd);
+ return jhash_2words(*(u32 *) pkey, dev->ifindex, rnd);
}
static struct neigh_table clip_tbl = {
diff --git a/net/atm/common.c b/net/atm/common.c
index 940404a73b3d..1b9c52a02cd3 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -792,7 +792,7 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
default:
if (level == SOL_SOCKET)
return -EINVAL;
- break;
+ break;
}
if (!vcc->dev || !vcc->dev->ops->getsockopt)
return -EINVAL;
diff --git a/net/atm/lec.c b/net/atm/lec.c
index d98bde1a0ac8..181d70c73d70 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -220,7 +220,6 @@ static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
static int lec_open(struct net_device *dev)
{
netif_start_queue(dev);
- memset(&dev->stats, 0, sizeof(struct net_device_stats));
return 0;
}
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index cfdfd7e2a172..26eaebf4aaa9 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1103,7 +1103,7 @@ done:
out:
release_sock(sk);
- return 0;
+ return err;
}
/*
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 7805945a5fd6..a1690845dc6e 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -412,7 +412,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
{
ax25_uid_assoc *user;
ax25_route *ax25_rt;
- int err;
+ int err = 0;
if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL)
return -EHOSTUNREACH;
@@ -453,7 +453,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
put:
ax25_put_route(ax25_rt);
- return 0;
+ return err;
}
struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src,
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 421c45bd1b95..c4cf3f595004 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -265,6 +265,115 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
}
EXPORT_SYMBOL(bt_sock_recvmsg);
+static long bt_sock_data_wait(struct sock *sk, long timeo)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(sk_sleep(sk), &wait);
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ if (!skb_queue_empty(&sk->sk_receive_queue))
+ break;
+
+ if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
+ break;
+
+ if (signal_pending(current) || !timeo)
+ break;
+
+ set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ release_sock(sk);
+ timeo = schedule_timeout(timeo);
+ lock_sock(sk);
+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ }
+
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(sk_sleep(sk), &wait);
+ return timeo;
+}
+
+int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t size, int flags)
+{
+ struct sock *sk = sock->sk;
+ int err = 0;
+ size_t target, copied = 0;
+ long timeo;
+
+ if (flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+ msg->msg_namelen = 0;
+
+ BT_DBG("sk %p size %zu", sk, size);
+
+ lock_sock(sk);
+
+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
+ timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+
+ do {
+ struct sk_buff *skb;
+ int chunk;
+
+ skb = skb_dequeue(&sk->sk_receive_queue);
+ if (!skb) {
+ if (copied >= target)
+ break;
+
+ if ((err = sock_error(sk)) != 0)
+ break;
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+ break;
+
+ err = -EAGAIN;
+ if (!timeo)
+ break;
+
+ timeo = bt_sock_data_wait(sk, timeo);
+
+ if (signal_pending(current)) {
+ err = sock_intr_errno(timeo);
+ goto out;
+ }
+ continue;
+ }
+
+ chunk = min_t(unsigned int, skb->len, size);
+ if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ if (!copied)
+ copied = -EFAULT;
+ break;
+ }
+ copied += chunk;
+ size -= chunk;
+
+ sock_recv_ts_and_drops(msg, sk, skb);
+
+ if (!(flags & MSG_PEEK)) {
+ skb_pull(skb, chunk);
+ if (skb->len) {
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ break;
+ }
+ kfree_skb(skb);
+
+ } else {
+ /* put message back and return */
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ break;
+ }
+ } while (size);
+
+out:
+ release_sock(sk);
+ return copied ? : err;
+}
+EXPORT_SYMBOL(bt_sock_stream_recvmsg);
+
static inline unsigned int bt_accept_poll(struct sock *parent)
{
struct list_head *p, *n;
@@ -297,13 +406,12 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w
mask |= POLLERR;
if (sk->sk_shutdown & RCV_SHUTDOWN)
- mask |= POLLRDHUP;
+ mask |= POLLRDHUP | POLLIN | POLLRDNORM;
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- (sk->sk_shutdown & RCV_SHUTDOWN))
+ if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= POLLIN | POLLRDNORM;
if (sk->sk_state == BT_CLOSED)
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
index d4c6af082d48..ec0a1347f933 100644
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -321,14 +321,10 @@ static int cmtp_session(void *arg)
int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
{
struct cmtp_session *session, *s;
- bdaddr_t src, dst;
int i, err;
BT_DBG("");
- baswap(&src, &bt_sk(sock->sk)->src);
- baswap(&dst, &bt_sk(sock->sk)->dst);
-
session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL);
if (!session)
return -ENOMEM;
@@ -347,7 +343,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
BT_DBG("mtu %d", session->mtu);
- sprintf(session->name, "%s", batostr(&dst));
+ sprintf(session->name, "%s", batostr(&bt_sk(sock->sk)->dst));
session->sock = sock;
session->state = BT_CONFIG;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c52f091ee6de..bc2a052e518b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -562,7 +562,6 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_dev_lock_bh(hdev);
inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev);
- hci_blacklist_clear(hdev);
hci_dev_unlock_bh(hdev);
hci_notify(hdev, HCI_DEV_DOWN);
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 8fb967beee80..5fce3d6d07b4 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -37,9 +37,7 @@ static ssize_t show_link_type(struct device *dev, struct device_attribute *attr,
static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
- bdaddr_t bdaddr;
- baswap(&bdaddr, &conn->dst);
- return sprintf(buf, "%s\n", batostr(&bdaddr));
+ return sprintf(buf, "%s\n", batostr(&conn->dst));
}
static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf)
@@ -196,8 +194,8 @@ static inline char *host_typetostr(int type)
switch (type) {
case HCI_BREDR:
return "BR/EDR";
- case HCI_80211:
- return "802.11";
+ case HCI_AMP:
+ return "AMP";
default:
return "UNKNOWN";
}
@@ -238,9 +236,7 @@ static ssize_t show_class(struct device *dev, struct device_attribute *attr, cha
static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
- bdaddr_t bdaddr;
- baswap(&bdaddr, &hdev->bdaddr);
- return sprintf(buf, "%s\n", batostr(&bdaddr));
+ return sprintf(buf, "%s\n", batostr(&hdev->bdaddr));
}
static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf)
@@ -408,10 +404,8 @@ static int inquiry_cache_show(struct seq_file *f, void *p)
for (e = cache->list; e; e = e->next) {
struct inquiry_data *data = &e->data;
- bdaddr_t bdaddr;
- baswap(&bdaddr, &data->bdaddr);
seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
- batostr(&bdaddr),
+ batostr(&data->bdaddr),
data->pscan_rep_mode, data->pscan_period_mode,
data->pscan_mode, data->dev_class[2],
data->dev_class[1], data->dev_class[0],
@@ -445,13 +439,10 @@ static int blacklist_show(struct seq_file *f, void *p)
list_for_each(l, &hdev->blacklist) {
struct bdaddr_list *b;
- bdaddr_t bdaddr;
b = list_entry(l, struct bdaddr_list, list);
- baswap(&bdaddr, &b->bdaddr);
-
- seq_printf(f, "%s\n", batostr(&bdaddr));
+ seq_printf(f, "%s\n", batostr(&b->bdaddr));
}
hci_dev_unlock_bh(hdev);
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index bfe641b7dfaf..c0ee8b3928ed 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -758,7 +758,6 @@ static int hidp_setup_hid(struct hidp_session *session,
struct hidp_connadd_req *req)
{
struct hid_device *hid;
- bdaddr_t src, dst;
int err;
session->rd_data = kzalloc(req->rd_size, GFP_KERNEL);
@@ -781,9 +780,6 @@ static int hidp_setup_hid(struct hidp_session *session,
hid->driver_data = session;
- baswap(&src, &bt_sk(session->ctrl_sock->sk)->src);
- baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst);
-
hid->bus = BUS_BLUETOOTH;
hid->vendor = req->vendor;
hid->product = req->product;
@@ -791,8 +787,8 @@ static int hidp_setup_hid(struct hidp_session *session,
hid->country = req->country;
strncpy(hid->name, req->name, 128);
- strncpy(hid->phys, batostr(&src), 64);
- strncpy(hid->uniq, batostr(&dst), 64);
+ strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64);
+ strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64);
hid->dev.parent = hidp_get_device(session);
hid->ll_driver = &hidp_hid_driver;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 0b54b7dd8401..daa7a988d9a6 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1008,10 +1008,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
goto done;
}
- if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
- !capable(CAP_NET_BIND_SERVICE)) {
- err = -EACCES;
- goto done;
+ if (la.l2_psm) {
+ __u16 psm = __le16_to_cpu(la.l2_psm);
+
+ /* PSM must be odd and lsb of upper byte must be 0 */
+ if ((psm & 0x0101) != 0x0001) {
+ err = -EINVAL;
+ goto done;
+ }
+
+ /* Restrict usage of well-known PSMs */
+ if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) {
+ err = -EACCES;
+ goto done;
+ }
}
write_lock_bh(&l2cap_sk_list.lock);
@@ -1190,6 +1200,13 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
goto done;
}
+ /* PSM must be odd and lsb of upper byte must be 0 */
+ if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
+ sk->sk_type != SOCK_RAW) {
+ err = -EINVAL;
+ goto done;
+ }
+
/* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
l2cap_pi(sk)->psm = la.l2_psm;
@@ -1635,7 +1652,7 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in
*frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
if (!*frag)
- return -EFAULT;
+ return err;
if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
return -EFAULT;
@@ -1661,7 +1678,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr
skb = bt_skb_send_alloc(sk, count + hlen,
msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
- return ERR_PTR(-ENOMEM);
+ return ERR_PTR(err);
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
@@ -1690,7 +1707,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *ms
skb = bt_skb_send_alloc(sk, count + hlen,
msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
- return ERR_PTR(-ENOMEM);
+ return ERR_PTR(err);
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
@@ -1727,7 +1744,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *m
skb = bt_skb_send_alloc(sk, count + hlen,
msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
- return ERR_PTR(-ENOMEM);
+ return ERR_PTR(err);
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
@@ -1934,6 +1951,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
release_sock(sk);
+ if (sock->type == SOCK_STREAM)
+ return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
+
return bt_sock_recvmsg(iocb, sock, msg, len, flags);
}
@@ -2891,7 +2911,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
struct l2cap_chan_list *list = &conn->chan_list;
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
- struct sock *parent, *uninitialized_var(sk);
+ struct sock *parent, *sk = NULL;
int result, status = L2CAP_CS_NO_INFO;
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3000,7 +3020,7 @@ sendresp:
L2CAP_INFO_REQ, sizeof(info), &info);
}
- if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
+ if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
result == L2CAP_CR_SUCCESS) {
u8 buf[128];
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
@@ -3151,6 +3171,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
u8 buf[64];
+ 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++;
@@ -4643,6 +4664,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
if (flags & ACL_START) {
struct l2cap_hdr *hdr;
+ struct sock *sk;
+ u16 cid;
int len;
if (conn->rx_len) {
@@ -4653,7 +4676,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
l2cap_conn_unreliable(conn, ECOMM);
}
- if (skb->len < 2) {
+ /* Start fragment always begin with Basic L2CAP header */
+ if (skb->len < L2CAP_HDR_SIZE) {
BT_ERR("Frame is too short (len %d)", skb->len);
l2cap_conn_unreliable(conn, ECOMM);
goto drop;
@@ -4661,6 +4685,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
hdr = (struct l2cap_hdr *) skb->data;
len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
+ cid = __le16_to_cpu(hdr->cid);
if (len == skb->len) {
/* Complete frame received */
@@ -4677,6 +4702,19 @@ 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);
+
+ 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 (sk)
+ bh_unlock_sock(sk);
+
/* Allocate skb for the complete frame (with header) */
conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!conn->rx_skb)
diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c
index ad2af5814e40..b826d1bf10df 100644
--- a/net/bluetooth/lib.c
+++ b/net/bluetooth/lib.c
@@ -51,8 +51,8 @@ char *batostr(bdaddr_t *ba)
i ^= 1;
sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
- ba->b[0], ba->b[1], ba->b[2],
- ba->b[3], ba->b[4], ba->b[5]);
+ ba->b[5], ba->b[4], ba->b[3],
+ ba->b[2], ba->b[1], ba->b[0]);
return str[i];
}
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 7dca91bb8c57..39a5d87e33b4 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -113,11 +113,10 @@ static void rfcomm_session_del(struct rfcomm_session *s);
#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
#define __get_rpn_parity(line) (((line) >> 3) & 0x7)
-static inline void rfcomm_schedule(uint event)
+static inline void rfcomm_schedule(void)
{
if (!rfcomm_thread)
return;
- //set_bit(event, &rfcomm_event);
set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
wake_up_process(rfcomm_thread);
}
@@ -179,13 +178,13 @@ static unsigned char rfcomm_crc_table[256] = {
/* FCS on 2 bytes */
static inline u8 __fcs(u8 *data)
{
- return (0xff - __crc(data));
+ return 0xff - __crc(data);
}
/* FCS on 3 bytes */
static inline u8 __fcs2(u8 *data)
{
- return (0xff - rfcomm_crc_table[__crc(data) ^ data[2]]);
+ return 0xff - rfcomm_crc_table[__crc(data) ^ data[2]];
}
/* Check FCS */
@@ -203,13 +202,13 @@ static inline int __check_fcs(u8 *data, int type, u8 fcs)
static void rfcomm_l2state_change(struct sock *sk)
{
BT_DBG("%p state %d", sk, sk->sk_state);
- rfcomm_schedule(RFCOMM_SCHED_STATE);
+ rfcomm_schedule();
}
static void rfcomm_l2data_ready(struct sock *sk, int bytes)
{
BT_DBG("%p bytes %d", sk, bytes);
- rfcomm_schedule(RFCOMM_SCHED_RX);
+ rfcomm_schedule();
}
static int rfcomm_l2sock_create(struct socket **sock)
@@ -255,7 +254,7 @@ static void rfcomm_session_timeout(unsigned long arg)
BT_DBG("session %p state %ld", s, s->state);
set_bit(RFCOMM_TIMED_OUT, &s->flags);
- rfcomm_schedule(RFCOMM_SCHED_TIMEO);
+ rfcomm_schedule();
}
static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout)
@@ -283,7 +282,7 @@ static void rfcomm_dlc_timeout(unsigned long arg)
set_bit(RFCOMM_TIMED_OUT, &d->flags);
rfcomm_dlc_put(d);
- rfcomm_schedule(RFCOMM_SCHED_TIMEO);
+ rfcomm_schedule();
}
static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
@@ -465,7 +464,7 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
case BT_CONFIG:
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
set_bit(RFCOMM_AUTH_REJECT, &d->flags);
- rfcomm_schedule(RFCOMM_SCHED_AUTH);
+ rfcomm_schedule();
break;
}
/* Fall through */
@@ -485,7 +484,7 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
case BT_CONNECT2:
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
set_bit(RFCOMM_AUTH_REJECT, &d->flags);
- rfcomm_schedule(RFCOMM_SCHED_AUTH);
+ rfcomm_schedule();
break;
}
/* Fall through */
@@ -533,7 +532,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
skb_queue_tail(&d->tx_queue, skb);
if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
- rfcomm_schedule(RFCOMM_SCHED_TX);
+ rfcomm_schedule();
return len;
}
@@ -545,7 +544,7 @@ void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
d->v24_sig |= RFCOMM_V24_FC;
set_bit(RFCOMM_MSC_PENDING, &d->flags);
}
- rfcomm_schedule(RFCOMM_SCHED_TX);
+ rfcomm_schedule();
}
void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
@@ -556,7 +555,7 @@ void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
d->v24_sig &= ~RFCOMM_V24_FC;
set_bit(RFCOMM_MSC_PENDING, &d->flags);
}
- rfcomm_schedule(RFCOMM_SCHED_TX);
+ rfcomm_schedule();
}
/*
@@ -577,7 +576,7 @@ int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
d->v24_sig = v24_sig;
if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
- rfcomm_schedule(RFCOMM_SCHED_TX);
+ rfcomm_schedule();
return 0;
}
@@ -816,7 +815,7 @@ static int rfcomm_queue_disc(struct rfcomm_dlc *d)
cmd->fcs = __fcs2((u8 *) cmd);
skb_queue_tail(&d->tx_queue, skb);
- rfcomm_schedule(RFCOMM_SCHED_TX);
+ rfcomm_schedule();
return 0;
}
@@ -1415,8 +1414,8 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
return 0;
if (len == 1) {
- /* This is a request, return default settings */
- bit_rate = RFCOMM_RPN_BR_115200;
+ /* This is a request, return default (according to ETSI TS 07.10) settings */
+ bit_rate = RFCOMM_RPN_BR_9600;
data_bits = RFCOMM_RPN_DATA_8;
stop_bits = RFCOMM_RPN_STOP_1;
parity = RFCOMM_RPN_PARITY_NONE;
@@ -1431,9 +1430,9 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_BITRATE)) {
bit_rate = rpn->bit_rate;
- if (bit_rate != RFCOMM_RPN_BR_115200) {
+ if (bit_rate > RFCOMM_RPN_BR_230400) {
BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
- bit_rate = RFCOMM_RPN_BR_115200;
+ bit_rate = RFCOMM_RPN_BR_9600;
rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
}
}
@@ -1698,7 +1697,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
break;
default:
- BT_ERR("Unknown packet type 0x%02x\n", type);
+ BT_ERR("Unknown packet type 0x%02x", type);
break;
}
kfree_skb(skb);
@@ -1884,7 +1883,7 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s)
* L2CAP MTU minus UIH header and FCS. */
s->mtu = min(l2cap_pi(nsock->sk)->omtu, l2cap_pi(nsock->sk)->imtu) - 5;
- rfcomm_schedule(RFCOMM_SCHED_RX);
+ rfcomm_schedule();
} else
sock_release(nsock);
}
@@ -2093,7 +2092,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
rfcomm_session_put(s);
- rfcomm_schedule(RFCOMM_SCHED_AUTH);
+ rfcomm_schedule();
}
static struct hci_cb rfcomm_cb = {
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 194b3a04cfd3..aec505f934df 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -621,121 +621,29 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
return sent;
}
-static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(sk_sleep(sk), &wait);
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
-
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- sk->sk_err ||
- (sk->sk_shutdown & RCV_SHUTDOWN) ||
- signal_pending(current) ||
- !timeo)
- break;
-
- set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- release_sock(sk);
- timeo = schedule_timeout(timeo);
- lock_sock(sk);
- clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- }
-
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(sk_sleep(sk), &wait);
- return timeo;
-}
-
static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)
{
struct sock *sk = sock->sk;
struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
- int err = 0;
- size_t target, copied = 0;
- long timeo;
+ int len;
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
rfcomm_dlc_accept(d);
return 0;
}
- if (flags & MSG_OOB)
- return -EOPNOTSUPP;
-
- msg->msg_namelen = 0;
-
- BT_DBG("sk %p size %zu", sk, size);
+ len = bt_sock_stream_recvmsg(iocb, sock, msg, size, flags);
lock_sock(sk);
+ if (!(flags & MSG_PEEK) && len > 0)
+ atomic_sub(len, &sk->sk_rmem_alloc);
- target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
- timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-
- do {
- struct sk_buff *skb;
- int chunk;
-
- skb = skb_dequeue(&sk->sk_receive_queue);
- if (!skb) {
- if (copied >= target)
- break;
-
- if ((err = sock_error(sk)) != 0)
- break;
- if (sk->sk_shutdown & RCV_SHUTDOWN)
- break;
-
- err = -EAGAIN;
- if (!timeo)
- break;
-
- timeo = rfcomm_sock_data_wait(sk, timeo);
-
- if (signal_pending(current)) {
- err = sock_intr_errno(timeo);
- goto out;
- }
- continue;
- }
-
- chunk = min_t(unsigned int, skb->len, size);
- if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- if (!copied)
- copied = -EFAULT;
- break;
- }
- copied += chunk;
- size -= chunk;
-
- sock_recv_ts_and_drops(msg, sk, skb);
-
- if (!(flags & MSG_PEEK)) {
- atomic_sub(chunk, &sk->sk_rmem_alloc);
-
- skb_pull(skb, chunk);
- if (skb->len) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- break;
- }
- kfree_skb(skb);
-
- } else {
- /* put message back and return */
- skb_queue_head(&sk->sk_receive_queue, skb);
- break;
- }
- } while (size);
-
-out:
if (atomic_read(&sk->sk_rmem_alloc) <= (sk->sk_rcvbuf >> 2))
rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
-
release_sock(sk);
- return copied ? : err;
+
+ return len;
}
static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 84c2a4d013c6..a9b81f5dacd1 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -183,9 +183,7 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
{
struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
- bdaddr_t bdaddr;
- baswap(&bdaddr, &dev->dst);
- return sprintf(buf, "%s\n", batostr(&bdaddr));
+ return sprintf(buf, "%s\n", batostr(&dev->dst));
}
static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index cf09fe591fc2..17cb0b633576 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -212,6 +212,11 @@ static int br_set_tx_csum(struct net_device *dev, u32 data)
return 0;
}
+static int br_set_flags(struct net_device *netdev, u32 data)
+{
+ return ethtool_op_set_flags(netdev, data, ETH_FLAG_TXVLAN);
+}
+
#ifdef CONFIG_NET_POLL_CONTROLLER
static void br_poll_controller(struct net_device *br_dev)
{
@@ -304,6 +309,7 @@ static const struct ethtool_ops br_ethtool_ops = {
.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 = {
@@ -343,5 +349,5 @@ void br_dev_setup(struct net_device *dev)
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_NETNS_LOCAL | NETIF_F_GSO | NETIF_F_HW_VLAN_TX;
}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index c03d2c3ff03e..89ad25a76202 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -61,30 +61,27 @@ static int port_cost(struct net_device *dev)
}
-/*
- * Check for port carrier transistions.
- * Called from work queue to allow for calling functions that
- * might sleep (such as speed check), and to debounce.
- */
+/* Check for port carrier transistions. */
void br_port_carrier_check(struct net_bridge_port *p)
{
struct net_device *dev = p->dev;
struct net_bridge *br = p->br;
- if (netif_carrier_ok(dev))
+ if (netif_running(dev) && netif_carrier_ok(dev))
p->path_cost = port_cost(dev);
- if (netif_running(br->dev)) {
- spin_lock_bh(&br->lock);
- if (netif_carrier_ok(dev)) {
- if (p->state == BR_STATE_DISABLED)
- br_stp_enable_port(p);
- } else {
- if (p->state != BR_STATE_DISABLED)
- br_stp_disable_port(p);
- }
- spin_unlock_bh(&br->lock);
+ if (!netif_running(br->dev))
+ return;
+
+ spin_lock_bh(&br->lock);
+ if (netif_running(dev) && netif_carrier_ok(dev)) {
+ if (p->state == BR_STATE_DISABLED)
+ br_stp_enable_port(p);
+ } else {
+ if (p->state != BR_STATE_DISABLED)
+ br_stp_disable_port(p);
}
+ spin_unlock_bh(&br->lock);
}
static void release_nbp(struct kobject *kobj)
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 826cd5221536..25207a1f182b 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -141,7 +141,7 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb)
const unsigned char *dest = eth_hdr(skb)->h_dest;
int (*rhook)(struct sk_buff *skb);
- if (skb->pkt_type == PACKET_LOOPBACK)
+ if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
return skb;
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
@@ -159,7 +159,7 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb)
goto drop;
/* If STP is turned off, then forward */
- if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0)
+ if (p->br->stp_enabled == BR_NO_STP)
goto forward;
if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 137f23259a93..865fd7634b67 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -64,22 +64,24 @@ static int brnf_filter_pppoe_tagged __read_mostly = 0;
static inline __be16 vlan_proto(const struct sk_buff *skb)
{
- return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+ if (vlan_tx_tag_present(skb))
+ return skb->protocol;
+ else if (skb->protocol == htons(ETH_P_8021Q))
+ return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+ else
+ return 0;
}
#define IS_VLAN_IP(skb) \
- (skb->protocol == htons(ETH_P_8021Q) && \
- vlan_proto(skb) == htons(ETH_P_IP) && \
+ (vlan_proto(skb) == htons(ETH_P_IP) && \
brnf_filter_vlan_tagged)
#define IS_VLAN_IPV6(skb) \
- (skb->protocol == htons(ETH_P_8021Q) && \
- vlan_proto(skb) == htons(ETH_P_IPV6) &&\
+ (vlan_proto(skb) == htons(ETH_P_IPV6) && \
brnf_filter_vlan_tagged)
#define IS_VLAN_ARP(skb) \
- (skb->protocol == htons(ETH_P_8021Q) && \
- vlan_proto(skb) == htons(ETH_P_ARP) && \
+ (vlan_proto(skb) == htons(ETH_P_ARP) && \
brnf_filter_vlan_tagged)
static inline __be16 pppoe_proto(const struct sk_buff *skb)
@@ -106,7 +108,6 @@ static struct dst_ops fake_dst_ops = {
.family = AF_INET,
.protocol = cpu_to_be16(ETH_P_IP),
.update_pmtu = fake_update_pmtu,
- .entries = ATOMIC_INIT(0),
};
/*
@@ -209,6 +210,72 @@ static inline void nf_bridge_update_protocol(struct sk_buff *skb)
skb->protocol = htons(ETH_P_PPP_SES);
}
+/* When handing a packet over to the IP layer
+ * check whether we have a skb that is in the
+ * expected format
+ */
+
+static int br_parse_ip_options(struct sk_buff *skb)
+{
+ struct ip_options *opt;
+ struct iphdr *iph;
+ struct net_device *dev = skb->dev;
+ u32 len;
+
+ iph = ip_hdr(skb);
+ opt = &(IPCB(skb)->opt);
+
+ /* Basic sanity checks */
+ if (iph->ihl < 5 || iph->version != 4)
+ goto inhdr_error;
+
+ if (!pskb_may_pull(skb, iph->ihl*4))
+ goto inhdr_error;
+
+ iph = ip_hdr(skb);
+ if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
+ goto inhdr_error;
+
+ len = ntohs(iph->tot_len);
+ if (skb->len < len) {
+ IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INTRUNCATEDPKTS);
+ goto drop;
+ } else if (len < (iph->ihl*4))
+ goto inhdr_error;
+
+ if (pskb_trim_rcsum(skb, len)) {
+ IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
+ goto drop;
+ }
+
+ /* Zero out the CB buffer if no options present */
+ if (iph->ihl == 5) {
+ memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
+ return 0;
+ }
+
+ opt->optlen = iph->ihl*4 - sizeof(struct iphdr);
+ if (ip_options_compile(dev_net(dev), opt, skb))
+ goto inhdr_error;
+
+ /* Check correct handling of SRR option */
+ if (unlikely(opt->srr)) {
+ struct in_device *in_dev = __in_dev_get_rcu(dev);
+ if (in_dev && !IN_DEV_SOURCE_ROUTE(in_dev))
+ goto drop;
+
+ if (ip_options_rcv_srr(skb))
+ goto drop;
+ }
+
+ return 0;
+
+inhdr_error:
+ IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INHDRERRORS);
+drop:
+ return -1;
+}
+
/* Fill in the header for fragmented IP packets handled by
* the IPv4 connection tracking code.
*/
@@ -549,7 +616,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
{
struct net_bridge_port *p;
struct net_bridge *br;
- struct iphdr *iph;
__u32 len = nf_bridge_encap_header_len(skb);
if (unlikely(!pskb_may_pull(skb, len)))
@@ -578,28 +644,9 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
nf_bridge_pull_encap_header_rcsum(skb);
- if (!pskb_may_pull(skb, sizeof(struct iphdr)))
- goto inhdr_error;
-
- iph = ip_hdr(skb);
- if (iph->ihl < 5 || iph->version != 4)
- goto inhdr_error;
-
- if (!pskb_may_pull(skb, 4 * iph->ihl))
- goto inhdr_error;
-
- iph = ip_hdr(skb);
- if (ip_fast_csum((__u8 *) iph, iph->ihl) != 0)
- goto inhdr_error;
-
- len = ntohs(iph->tot_len);
- if (skb->len < len || len < 4 * iph->ihl)
- goto inhdr_error;
-
- pskb_trim_rcsum(skb, len);
-
- /* BUG: Should really parse the IP options here. */
- memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
+ if (br_parse_ip_options(skb))
+ /* Drop invalid packet */
+ goto out;
nf_bridge_put(skb->nf_bridge);
if (!nf_bridge_alloc(skb))
@@ -614,8 +661,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
return NF_STOLEN;
-inhdr_error:
-// IP_INC_STATS_BH(IpInHdrErrors);
out:
return NF_DROP;
}
@@ -759,14 +804,19 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
#if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE)
static int br_nf_dev_queue_xmit(struct sk_buff *skb)
{
+ int ret;
+
if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) &&
skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu &&
!skb_is_gso(skb)) {
- /* BUG: Should really parse the IP options here. */
- memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
- return ip_fragment(skb, br_dev_queue_push_xmit);
+ if (br_parse_ip_options(skb))
+ /* Drop invalid packet */
+ return NF_DROP;
+ ret = ip_fragment(skb, br_dev_queue_push_xmit);
} else
- return br_dev_queue_push_xmit(skb);
+ ret = br_dev_queue_push_xmit(skb);
+
+ return ret;
}
#else
static int br_nf_dev_queue_xmit(struct sk_buff *skb)
@@ -954,15 +1004,22 @@ int __init br_netfilter_init(void)
{
int ret;
- ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
+ ret = dst_entries_init(&fake_dst_ops);
if (ret < 0)
return ret;
+
+ ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
+ if (ret < 0) {
+ dst_entries_destroy(&fake_dst_ops);
+ return ret;
+ }
#ifdef CONFIG_SYSCTL
brnf_sysctl_header = register_sysctl_paths(brnf_path, brnf_table);
if (brnf_sysctl_header == NULL) {
printk(KERN_WARNING
"br_netfilter: can't register to sysctl.\n");
nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
+ dst_entries_destroy(&fake_dst_ops);
return -ENOMEM;
}
#endif
@@ -976,4 +1033,5 @@ void br_netfilter_fini(void)
#ifdef CONFIG_SYSCTL
unregister_sysctl_table(brnf_sysctl_header);
#endif
+ dst_entries_destroy(&fake_dst_ops);
}
diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c
index 87b53b3a921d..eae67bf0446c 100644
--- a/net/bridge/netfilter/ebt_vlan.c
+++ b/net/bridge/netfilter/ebt_vlan.c
@@ -39,8 +39,6 @@ static bool
ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct ebt_vlan_info *info = par->matchinfo;
- const struct vlan_hdr *fp;
- struct vlan_hdr _frame;
unsigned short TCI; /* Whole TCI, given from parsed frame */
unsigned short id; /* VLAN ID, given from frame TCI */
@@ -48,9 +46,20 @@ ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par)
/* VLAN encapsulated Type/Length field, given from orig frame */
__be16 encap;
- fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
- if (fp == NULL)
- return false;
+ if (vlan_tx_tag_present(skb)) {
+ TCI = vlan_tx_tag_get(skb);
+ encap = skb->protocol;
+ } else {
+ const struct vlan_hdr *fp;
+ struct vlan_hdr _frame;
+
+ fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
+ if (fp == NULL)
+ return false;
+
+ TCI = ntohs(fp->h_vlan_TCI);
+ encap = fp->h_vlan_encapsulated_proto;
+ }
/* Tag Control Information (TCI) consists of the following elements:
* - User_priority. The user_priority field is three bits in length,
@@ -59,10 +68,8 @@ ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par)
* (CFI) is a single bit flag value. Currently ignored.
* - VLAN Identifier (VID). The VID is encoded as
* an unsigned binary number. */
- TCI = ntohs(fp->h_vlan_TCI);
id = TCI & VLAN_VID_MASK;
prio = (TCI >> 13) & 0x7;
- encap = fp->h_vlan_encapsulated_proto;
/* Checking VLAN Identifier (VID) */
if (GET_BITMASK(EBT_VLAN_ID))
@@ -111,10 +118,10 @@ static int ebt_vlan_mt_check(const struct xt_mtchk_param *par)
* 0 - The null VLAN ID.
* 1 - The default Port VID (PVID)
* 0x0FFF - Reserved for implementation use.
- * if_vlan.h: VLAN_GROUP_ARRAY_LEN 4096. */
+ * if_vlan.h: VLAN_N_VID 4096. */
if (GET_BITMASK(EBT_VLAN_ID)) {
if (!!info->id) { /* if id!=0 => check vid range */
- if (info->id > VLAN_GROUP_ARRAY_LEN) {
+ if (info->id > VLAN_N_VID) {
pr_debug("id %d is out of range (1-4096)\n",
info->id);
return -EINVAL;
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index bcc102e3be4d..a1dcf83f0d58 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -124,16 +124,23 @@ ebt_dev_check(const char *entry, const struct net_device *device)
#define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg))
/* process standard matches */
static inline int
-ebt_basic_match(const struct ebt_entry *e, const struct ethhdr *h,
+ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out)
{
+ const struct ethhdr *h = eth_hdr(skb);
+ __be16 ethproto;
int verdict, i;
+ if (vlan_tx_tag_present(skb))
+ ethproto = htons(ETH_P_8021Q);
+ else
+ ethproto = h->h_proto;
+
if (e->bitmask & EBT_802_3) {
- if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO))
+ if (FWINV2(ntohs(ethproto) >= 1536, EBT_IPROTO))
return 1;
} else if (!(e->bitmask & EBT_NOPROTO) &&
- FWINV2(e->ethproto != h->h_proto, EBT_IPROTO))
+ FWINV2(e->ethproto != ethproto, EBT_IPROTO))
return 1;
if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN))
@@ -213,7 +220,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
base = private->entries;
i = 0;
while (i < nentries) {
- if (ebt_basic_match(point, eth_hdr(skb), in, out))
+ if (ebt_basic_match(point, skb, in, out))
goto letscontinue;
if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &acpar) != 0)
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index 0b586e9d1378..b99369a055d1 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -9,6 +9,8 @@
* and Sakari Ailus <sakari.ailus@nokia.com>
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -171,7 +173,7 @@ static int receive(struct sk_buff *skb, struct net_device *dev,
net = dev_net(dev);
pkt = cfpkt_fromnative(CAIF_DIR_IN, skb);
caifd = caif_get(dev);
- if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd)
+ if (!caifd || !caifd->layer.up || !caifd->layer.up->receive)
return NET_RX_DROP;
if (caifd->layer.up->receive(caifd->layer.up, pkt))
@@ -214,7 +216,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
switch (what) {
case NETDEV_REGISTER:
- pr_info("CAIF: %s():register %s\n", __func__, dev->name);
+ netdev_info(dev, "register\n");
caifd = caif_device_alloc(dev);
if (caifd == NULL)
break;
@@ -225,14 +227,13 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
break;
case NETDEV_UP:
- pr_info("CAIF: %s(): up %s\n", __func__, dev->name);
+ netdev_info(dev, "up\n");
caifd = caif_get(dev);
if (caifd == NULL)
break;
caifdev = netdev_priv(dev);
if (atomic_read(&caifd->state) == NETDEV_UP) {
- pr_info("CAIF: %s():%s already up\n",
- __func__, dev->name);
+ netdev_info(dev, "already up\n");
break;
}
atomic_set(&caifd->state, what);
@@ -273,7 +274,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
caifd = caif_get(dev);
if (caifd == NULL)
break;
- pr_info("CAIF: %s():going down %s\n", __func__, dev->name);
+ netdev_info(dev, "going down\n");
if (atomic_read(&caifd->state) == NETDEV_GOING_DOWN ||
atomic_read(&caifd->state) == NETDEV_DOWN)
@@ -295,11 +296,10 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
caifd = caif_get(dev);
if (caifd == NULL)
break;
- pr_info("CAIF: %s(): down %s\n", __func__, dev->name);
+ netdev_info(dev, "down\n");
if (atomic_read(&caifd->in_use))
- pr_warning("CAIF: %s(): "
- "Unregistering an active CAIF device: %s\n",
- __func__, dev->name);
+ 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);
@@ -307,7 +307,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
case NETDEV_UNREGISTER:
caifd = caif_get(dev);
- pr_info("CAIF: %s(): unregister %s\n", __func__, dev->name);
+ netdev_info(dev, "unregister\n");
atomic_set(&caifd->state, what);
caif_device_destroy(dev);
break;
@@ -391,7 +391,7 @@ static int __init caif_device_init(void)
int result;
cfg = cfcnfg_create();
if (!cfg) {
- pr_warning("CAIF: %s(): can't create cfcnfg.\n", __func__);
+ pr_warn("can't create cfcnfg\n");
goto err_cfcnfg_create_failed;
}
result = register_pernet_device(&caif_net_ops);
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 4bf28f25f368..2eca2dd0000f 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -15,7 +17,6 @@
#include <linux/poll.h>
#include <linux/tcp.h>
#include <linux/uaccess.h>
-#include <linux/mutex.h>
#include <linux/debugfs.h>
#include <linux/caif/caif_socket.h>
#include <asm/atomic.h>
@@ -28,9 +29,6 @@
MODULE_LICENSE("GPL");
MODULE_ALIAS_NETPROTO(AF_CAIF);
-#define CAIF_DEF_SNDBUF (4096*10)
-#define CAIF_DEF_RCVBUF (4096*100)
-
/*
* CAIF state is re-using the TCP socket states.
* caif_states stored in sk_state reflect the state as reported by
@@ -157,9 +155,7 @@ 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)) {
- trace_printk("CAIF: %s():"
- " sending flow OFF (queue len = %d %d)\n",
- __func__,
+ 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);
@@ -172,9 +168,7 @@ 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);
- trace_printk("CAIF: %s():"
- " sending flow OFF due to rmem_schedule\n",
- __func__);
+ 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);
}
@@ -275,8 +269,7 @@ static void caif_ctrl_cb(struct cflayer *layr,
break;
default:
- pr_debug("CAIF: %s(): Unexpected flow command %d\n",
- __func__, flow);
+ pr_debug("Unexpected flow command %d\n", flow);
}
}
@@ -536,8 +529,7 @@ static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk,
/* Slight paranoia, probably not needed. */
if (unlikely(loopcnt++ > 1000)) {
- pr_warning("CAIF: %s(): transmit retries failed,"
- " error = %d\n", __func__, ret);
+ pr_warn("transmit retries failed, error = %d\n", ret);
break;
}
@@ -912,8 +904,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
cf_sk->tailroom = tailroom;
cf_sk->maxframe = mtu - (headroom + tailroom);
if (cf_sk->maxframe < 1) {
- pr_warning("CAIF: %s(): CAIF Interface MTU too small (%u)\n",
- __func__, mtu);
+ pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu);
goto out;
}
@@ -1132,10 +1123,6 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
/* Store the protocol */
sk->sk_protocol = (unsigned char) protocol;
- /* Sendbuf dictates the amount of outbound packets not yet sent */
- sk->sk_sndbuf = CAIF_DEF_SNDBUF;
- sk->sk_rcvbuf = CAIF_DEF_RCVBUF;
-
/*
* Lock in order to try to stop someone from opening the socket
* too early.
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c
index 1c29189b344d..41adafd18914 100644
--- a/net/caif/cfcnfg.c
+++ b/net/caif/cfcnfg.c
@@ -3,6 +3,9 @@
* Author: Sjur Brendeland/sjur.brandeland@stericsson.com
* License terms: GNU General Public License (GPL) version 2
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/slab.h>
@@ -78,7 +81,7 @@ struct cfcnfg *cfcnfg_create(void)
/* Initiate this layer */
this = kzalloc(sizeof(struct cfcnfg), GFP_ATOMIC);
if (!this) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return NULL;
}
this->mux = cfmuxl_create();
@@ -106,7 +109,7 @@ struct cfcnfg *cfcnfg_create(void)
layer_set_up(this->ctrl, this);
return this;
out_of_mem:
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
kfree(this->mux);
kfree(this->ctrl);
kfree(this);
@@ -194,7 +197,7 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
caif_assert(adap_layer != NULL);
channel_id = adap_layer->id;
if (adap_layer->dn == NULL || channel_id == 0) {
- pr_err("CAIF: %s():adap_layer->id is 0\n", __func__);
+ pr_err("adap_layer->dn == NULL or adap_layer->id is 0\n");
ret = -ENOTCONN;
goto end;
}
@@ -204,9 +207,8 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
layer_set_up(servl, NULL);
ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer);
if (servl == NULL) {
- pr_err("CAIF: %s(): PROTOCOL ERROR "
- "- Error removing service_layer Channel_Id(%d)",
- __func__, channel_id);
+ pr_err("PROTOCOL ERROR - Error removing service_layer Channel_Id(%d)",
+ channel_id);
ret = -EINVAL;
goto end;
}
@@ -216,18 +218,14 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
phyinfo = cfcnfg_get_phyinfo(cnfg, phyid);
if (phyinfo == NULL) {
- pr_warning("CAIF: %s(): "
- "No interface to send disconnect to\n",
- __func__);
+ 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("CAIF: %s(): "
- "Inconsistency in phy registration\n",
- __func__);
+ pr_err("Inconsistency in phy registration\n");
ret = -EINVAL;
goto end;
}
@@ -276,21 +274,20 @@ int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
{
struct cflayer *frml;
if (adap_layer == NULL) {
- pr_err("CAIF: %s(): adap_layer is zero", __func__);
+ pr_err("adap_layer is zero\n");
return -EINVAL;
}
if (adap_layer->receive == NULL) {
- pr_err("CAIF: %s(): adap_layer->receive is NULL", __func__);
+ pr_err("adap_layer->receive is NULL\n");
return -EINVAL;
}
if (adap_layer->ctrlcmd == NULL) {
- pr_err("CAIF: %s(): adap_layer->ctrlcmd == NULL", __func__);
+ pr_err("adap_layer->ctrlcmd == NULL\n");
return -EINVAL;
}
frml = cnfg->phy_layers[param->phyid].frm_layer;
if (frml == NULL) {
- pr_err("CAIF: %s(): Specified PHY type does not exist!",
- __func__);
+ pr_err("Specified PHY type does not exist!\n");
return -ENODEV;
}
caif_assert(param->phyid == cnfg->phy_layers[param->phyid].id);
@@ -330,9 +327,7 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv,
struct net_device *netdev;
if (adapt_layer == NULL) {
- pr_debug("CAIF: %s(): link setup response "
- "but no client exist, send linkdown back\n",
- __func__);
+ pr_debug("link setup response but no client exist, send linkdown back\n");
cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL);
return;
}
@@ -374,13 +369,11 @@ 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("CAIF: %s(): Protocol error. "
- "Link setup response - unknown channel type\n",
- __func__);
+ pr_err("Protocol error. Link setup response - unknown channel type\n");
return;
}
if (!servicel) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return;
}
layer_set_dn(servicel, cnfg->mux);
@@ -418,7 +411,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
}
}
if (*phyid == 0) {
- pr_err("CAIF: %s(): No Available PHY ID\n", __func__);
+ pr_err("No Available PHY ID\n");
return;
}
@@ -427,7 +420,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
phy_driver =
cfserl_create(CFPHYTYPE_FRAG, *phyid, stx);
if (!phy_driver) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return;
}
@@ -436,7 +429,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
phy_driver = NULL;
break;
default:
- pr_err("CAIF: %s(): %d", __func__, phy_type);
+ pr_err("%d\n", phy_type);
return;
break;
}
@@ -455,7 +448,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
phy_layer->type = phy_type;
frml = cffrml_create(*phyid, fcs);
if (!frml) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return;
}
cnfg->phy_layers[*phyid].frm_layer = frml;
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
index 563145fdc4c3..08f267a109aa 100644
--- a/net/caif/cfctrl.c
+++ b/net/caif/cfctrl.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
@@ -36,7 +38,7 @@ struct cflayer *cfctrl_create(void)
struct cfctrl *this =
kmalloc(sizeof(struct cfctrl), GFP_ATOMIC);
if (!this) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return NULL;
}
caif_assert(offsetof(struct cfctrl, serv.layer) == 0);
@@ -132,9 +134,7 @@ struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
if (cfctrl_req_eq(req, p)) {
if (p != first)
- pr_warning("CAIF: %s(): Requests are not "
- "received in order\n",
- __func__);
+ pr_warn("Requests are not received in order\n");
atomic_set(&ctrl->rsp_seq_no,
p->sequence_no);
@@ -177,7 +177,7 @@ void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid)
int ret;
struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
if (!pkt) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return;
}
caif_assert(offsetof(struct cfctrl, serv.layer) == 0);
@@ -189,8 +189,7 @@ void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid)
ret =
cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
if (ret < 0) {
- pr_err("CAIF: %s(): Could not transmit enum message\n",
- __func__);
+ pr_err("Could not transmit enum message\n");
cfpkt_destroy(pkt);
}
}
@@ -208,7 +207,7 @@ int cfctrl_linkup_request(struct cflayer *layer,
char utility_name[16];
struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
if (!pkt) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return -ENOMEM;
}
cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_SETUP);
@@ -253,13 +252,13 @@ int cfctrl_linkup_request(struct cflayer *layer,
param->u.utility.paramlen);
break;
default:
- pr_warning("CAIF: %s():Request setup of bad link type = %d\n",
- __func__, param->linktype);
+ pr_warn("Request setup of bad link type = %d\n",
+ param->linktype);
return -EINVAL;
}
req = kzalloc(sizeof(*req), GFP_KERNEL);
if (!req) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return -ENOMEM;
}
req->client_layer = user_layer;
@@ -276,8 +275,7 @@ int cfctrl_linkup_request(struct cflayer *layer,
ret =
cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
if (ret < 0) {
- pr_err("CAIF: %s(): Could not transmit linksetup request\n",
- __func__);
+ pr_err("Could not transmit linksetup request\n");
cfpkt_destroy(pkt);
return -ENODEV;
}
@@ -291,7 +289,7 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid,
struct cfctrl *cfctrl = container_obj(layer);
struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
if (!pkt) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return -ENOMEM;
}
cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY);
@@ -300,8 +298,7 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid,
ret =
cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
if (ret < 0) {
- pr_err("CAIF: %s(): Could not transmit link-down request\n",
- __func__);
+ pr_err("Could not transmit link-down request\n");
cfpkt_destroy(pkt);
}
return ret;
@@ -313,7 +310,7 @@ void cfctrl_sleep_req(struct cflayer *layer)
struct cfctrl *cfctrl = container_obj(layer);
struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
if (!pkt) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return;
}
cfpkt_addbdy(pkt, CFCTRL_CMD_SLEEP);
@@ -330,7 +327,7 @@ void cfctrl_wake_req(struct cflayer *layer)
struct cfctrl *cfctrl = container_obj(layer);
struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
if (!pkt) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return;
}
cfpkt_addbdy(pkt, CFCTRL_CMD_WAKE);
@@ -347,7 +344,7 @@ void cfctrl_getstartreason_req(struct cflayer *layer)
struct cfctrl *cfctrl = container_obj(layer);
struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
if (!pkt) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return;
}
cfpkt_addbdy(pkt, CFCTRL_CMD_START_REASON);
@@ -364,12 +361,11 @@ void 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);
- pr_warning("CAIF: %s(): enter\n", __func__);
+ pr_warn("enter\n");
list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
if (p->client_layer == adap_layer) {
- pr_warning("CAIF: %s(): cancel req :%d\n", __func__,
- p->sequence_no);
+ pr_warn("cancel req :%d\n", p->sequence_no);
list_del(&p->list);
kfree(p);
}
@@ -520,9 +516,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
cfpkt_extr_head(pkt, &param, len);
break;
default:
- pr_warning("CAIF: %s(): Request setup "
- "- invalid link type (%d)",
- __func__, serv);
+ pr_warn("Request setup - invalid link type (%d)\n",
+ serv);
goto error;
}
@@ -532,9 +527,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) ||
cfpkt_erroneous(pkt)) {
- pr_err("CAIF: %s(): Invalid O/E bit or parse "
- "error on CAIF control channel",
- __func__);
+ pr_err("Invalid O/E bit or parse error on CAIF control channel\n");
cfctrl->res.reject_rsp(cfctrl->serv.layer.up,
0,
req ? req->client_layer
@@ -556,8 +549,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid);
break;
case CFCTRL_CMD_LINK_ERR:
- pr_err("CAIF: %s(): Frame Error Indication received\n",
- __func__);
+ pr_err("Frame Error Indication received\n");
cfctrl->res.linkerror_ind();
break;
case CFCTRL_CMD_ENUM:
@@ -576,7 +568,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
cfctrl->res.radioset_rsp();
break;
default:
- pr_err("CAIF: %s(): Unrecognized Control Frame\n", __func__);
+ pr_err("Unrecognized Control Frame\n");
goto error;
break;
}
@@ -595,8 +587,7 @@ static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
case CAIF_CTRLCMD_FLOW_OFF_IND:
spin_lock(&this->info_list_lock);
if (!list_empty(&this->list)) {
- pr_debug("CAIF: %s(): Received flow off in "
- "control layer", __func__);
+ pr_debug("Received flow off in control layer\n");
}
spin_unlock(&this->info_list_lock);
break;
@@ -620,7 +611,7 @@ static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt)
if (!ctrl->loop_linkused[linkid])
goto found;
spin_unlock(&ctrl->loop_linkid_lock);
- pr_err("CAIF: %s(): Out of link-ids\n", __func__);
+ pr_err("Out of link-ids\n");
return -EINVAL;
found:
if (!ctrl->loop_linkused[linkid])
diff --git a/net/caif/cfdbgl.c b/net/caif/cfdbgl.c
index 676648cac8dd..496fda9ac66f 100644
--- a/net/caif/cfdbgl.c
+++ b/net/caif/cfdbgl.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/stddef.h>
#include <linux/slab.h>
#include <net/caif/caif_layer.h>
@@ -17,7 +19,7 @@ struct cflayer *cfdbgl_create(u8 channel_id, struct dev_info *dev_info)
{
struct cfsrvl *dbg = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
if (!dbg) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return NULL;
}
caif_assert(offsetof(struct cfsrvl, layer) == 0);
diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c
index ed9d53aff280..d3ed264ad6c4 100644
--- a/net/caif/cfdgml.c
+++ b/net/caif/cfdgml.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
@@ -26,7 +28,7 @@ struct cflayer *cfdgml_create(u8 channel_id, struct dev_info *dev_info)
{
struct cfsrvl *dgm = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
if (!dgm) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return NULL;
}
caif_assert(offsetof(struct cfsrvl, layer) == 0);
@@ -49,14 +51,14 @@ static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt)
caif_assert(layr->ctrlcmd != NULL);
if (cfpkt_extr_head(pkt, &cmd, 1) < 0) {
- pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+ pr_err("Packet is erroneous!\n");
cfpkt_destroy(pkt);
return -EPROTO;
}
if ((cmd & DGM_CMD_BIT) == 0) {
if (cfpkt_extr_head(pkt, &dgmhdr, 3) < 0) {
- pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+ pr_err("Packet is erroneous!\n");
cfpkt_destroy(pkt);
return -EPROTO;
}
@@ -75,8 +77,7 @@ static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt)
return 0;
default:
cfpkt_destroy(pkt);
- pr_info("CAIF: %s(): Unknown datagram control %d (0x%x)\n",
- __func__, cmd, cmd);
+ pr_info("Unknown datagram control %d (0x%x)\n", cmd, cmd);
return -EPROTO;
}
}
diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
index e86a4ca3b217..a445043931ae 100644
--- a/net/caif/cffrml.c
+++ b/net/caif/cffrml.c
@@ -6,6 +6,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
@@ -32,7 +34,7 @@ struct cflayer *cffrml_create(u16 phyid, bool use_fcs)
{
struct cffrml *this = kmalloc(sizeof(struct cffrml), GFP_ATOMIC);
if (!this) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return NULL;
}
caif_assert(offsetof(struct cffrml, layer) == 0);
@@ -83,7 +85,7 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
if (cfpkt_setlen(pkt, len) < 0) {
++cffrml_rcv_error;
- pr_err("CAIF: %s():Framing length error (%d)\n", __func__, len);
+ pr_err("Framing length error (%d)\n", len);
cfpkt_destroy(pkt);
return -EPROTO;
}
@@ -99,14 +101,14 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
cfpkt_add_trail(pkt, &tmp, 2);
++cffrml_rcv_error;
++cffrml_rcv_checsum_error;
- pr_info("CAIF: %s(): Frame checksum error "
- "(0x%x != 0x%x)\n", __func__, hdrchks, pktchks);
+ pr_info("Frame checksum error (0x%x != 0x%x)\n",
+ hdrchks, pktchks);
return -EILSEQ;
}
}
if (cfpkt_erroneous(pkt)) {
++cffrml_rcv_error;
- pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+ pr_err("Packet is erroneous!\n");
cfpkt_destroy(pkt);
return -EPROTO;
}
@@ -132,7 +134,7 @@ static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
cfpkt_add_head(pkt, &tmp, 2);
cfpkt_info(pkt)->hdr_len += 2;
if (cfpkt_erroneous(pkt)) {
- pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+ pr_err("Packet is erroneous!\n");
return -EPROTO;
}
ret = layr->dn->transmit(layr->dn, pkt);
diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c
index 80c8d332b258..46f34b2e0478 100644
--- a/net/caif/cfmuxl.c
+++ b/net/caif/cfmuxl.c
@@ -3,6 +3,9 @@
* Author: Sjur Brendeland/sjur.brandeland@stericsson.com
* License terms: GNU General Public License (GPL) version 2
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
@@ -190,7 +193,7 @@ static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt)
u8 id;
struct cflayer *up;
if (cfpkt_extr_head(pkt, &id, 1) < 0) {
- pr_err("CAIF: %s(): erroneous Caif Packet\n", __func__);
+ pr_err("erroneous Caif Packet\n");
cfpkt_destroy(pkt);
return -EPROTO;
}
@@ -199,8 +202,8 @@ static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt)
up = get_up(muxl, id);
spin_unlock(&muxl->receive_lock);
if (up == NULL) {
- pr_info("CAIF: %s():Received data on unknown link ID = %d "
- "(0x%x) up == NULL", __func__, id, id);
+ pr_info("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
@@ -223,9 +226,8 @@ static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt)
struct caif_payload_info *info = cfpkt_info(pkt);
dn = get_dn(muxl, cfpkt_info(pkt)->dev_info);
if (dn == NULL) {
- pr_warning("CAIF: %s(): Send data on unknown phy "
- "ID = %d (0x%x)\n",
- __func__, info->dev_info->id, info->dev_info->id);
+ pr_warn("Send data on unknown phy ID = %d (0x%x)\n",
+ info->dev_info->id, info->dev_info->id);
return -ENOTCONN;
}
info->hdr_len += 1;
diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c
index c49a6695793a..d7e865e2ff65 100644
--- a/net/caif/cfpkt_skbuff.c
+++ b/net/caif/cfpkt_skbuff.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/hardirq.h>
@@ -12,11 +14,12 @@
#define PKT_PREFIX 48
#define PKT_POSTFIX 2
#define PKT_LEN_WHEN_EXTENDING 128
-#define PKT_ERROR(pkt, errmsg) do { \
- cfpkt_priv(pkt)->erronous = true; \
- skb_reset_tail_pointer(&pkt->skb); \
- pr_warning("CAIF: " errmsg);\
- } while (0)
+#define PKT_ERROR(pkt, errmsg) \
+do { \
+ cfpkt_priv(pkt)->erronous = true; \
+ skb_reset_tail_pointer(&pkt->skb); \
+ pr_warn(errmsg); \
+} while (0)
struct cfpktq {
struct sk_buff_head head;
@@ -130,13 +133,13 @@ int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len)
return -EPROTO;
if (unlikely(len > skb->len)) {
- PKT_ERROR(pkt, "cfpkt_extr_head read beyond end of packet\n");
+ PKT_ERROR(pkt, "read beyond end of packet\n");
return -EPROTO;
}
if (unlikely(len > skb_headlen(skb))) {
if (unlikely(skb_linearize(skb) != 0)) {
- PKT_ERROR(pkt, "cfpkt_extr_head linearize failed\n");
+ PKT_ERROR(pkt, "linearize failed\n");
return -EPROTO;
}
}
@@ -156,11 +159,11 @@ int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, u16 len)
return -EPROTO;
if (unlikely(skb_linearize(skb) != 0)) {
- PKT_ERROR(pkt, "cfpkt_extr_trail linearize failed\n");
+ PKT_ERROR(pkt, "linearize failed\n");
return -EPROTO;
}
if (unlikely(skb->data + len > skb_tail_pointer(skb))) {
- PKT_ERROR(pkt, "cfpkt_extr_trail read beyond end of packet\n");
+ PKT_ERROR(pkt, "read beyond end of packet\n");
return -EPROTO;
}
from = skb_tail_pointer(skb) - len;
@@ -202,7 +205,7 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len)
/* Make sure data is writable */
if (unlikely(skb_cow_data(skb, addlen, &lastskb) < 0)) {
- PKT_ERROR(pkt, "cfpkt_add_body: cow failed\n");
+ PKT_ERROR(pkt, "cow failed\n");
return -EPROTO;
}
/*
@@ -211,8 +214,7 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len)
* lengths of the top SKB.
*/
if (lastskb != skb) {
- pr_warning("CAIF: %s(): Packet is non-linear\n",
- __func__);
+ pr_warn("Packet is non-linear\n");
skb->len += len;
skb->data_len += len;
}
@@ -242,14 +244,14 @@ int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len)
if (unlikely(is_erronous(pkt)))
return -EPROTO;
if (unlikely(skb_headroom(skb) < len)) {
- PKT_ERROR(pkt, "cfpkt_add_head: no headroom\n");
+ PKT_ERROR(pkt, "no headroom\n");
return -EPROTO;
}
/* Make sure data is writable */
ret = skb_cow_data(skb, 0, &lastskb);
if (unlikely(ret < 0)) {
- PKT_ERROR(pkt, "cfpkt_add_head: cow failed\n");
+ PKT_ERROR(pkt, "cow failed\n");
return ret;
}
@@ -283,7 +285,7 @@ inline u16 cfpkt_iterate(struct cfpkt *pkt,
if (unlikely(is_erronous(pkt)))
return -EPROTO;
if (unlikely(skb_linearize(&pkt->skb) != 0)) {
- PKT_ERROR(pkt, "cfpkt_iterate: linearize failed\n");
+ PKT_ERROR(pkt, "linearize failed\n");
return -EPROTO;
}
return iter_func(data, pkt->skb.data, cfpkt_getlen(pkt));
@@ -309,7 +311,7 @@ int cfpkt_setlen(struct cfpkt *pkt, u16 len)
/* Need to expand SKB */
if (unlikely(!cfpkt_pad_trail(pkt, len - skb->len)))
- PKT_ERROR(pkt, "cfpkt_setlen: skb_pad_trail failed\n");
+ PKT_ERROR(pkt, "skb_pad_trail failed\n");
return cfpkt_getlen(pkt);
}
@@ -380,8 +382,7 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
return NULL;
if (skb->data + pos > skb_tail_pointer(skb)) {
- PKT_ERROR(pkt,
- "cfpkt_split: trying to split beyond end of packet");
+ PKT_ERROR(pkt, "trying to split beyond end of packet\n");
return NULL;
}
@@ -455,17 +456,17 @@ int cfpkt_raw_append(struct cfpkt *pkt, void **buf, unsigned int buflen)
return -EPROTO;
/* Make sure SKB is writable */
if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) {
- PKT_ERROR(pkt, "cfpkt_raw_append: skb_cow_data failed\n");
+ PKT_ERROR(pkt, "skb_cow_data failed\n");
return -EPROTO;
}
if (unlikely(skb_linearize(skb) != 0)) {
- PKT_ERROR(pkt, "cfpkt_raw_append: linearize failed\n");
+ PKT_ERROR(pkt, "linearize failed\n");
return -EPROTO;
}
if (unlikely(skb_tailroom(skb) < buflen)) {
- PKT_ERROR(pkt, "cfpkt_raw_append: buffer too short - failed\n");
+ PKT_ERROR(pkt, "buffer too short - failed\n");
return -EPROTO;
}
@@ -483,14 +484,13 @@ int cfpkt_raw_extract(struct cfpkt *pkt, void **buf, unsigned int buflen)
return -EPROTO;
if (unlikely(buflen > skb->len)) {
- PKT_ERROR(pkt, "cfpkt_raw_extract: buflen too large "
- "- failed\n");
+ 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, "cfpkt_raw_extract: linearize failed\n");
+ PKT_ERROR(pkt, "linearize failed\n");
return -EPROTO;
}
}
diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c
index 9a699242d104..bde8481e8d25 100644
--- a/net/caif/cfrfml.c
+++ b/net/caif/cfrfml.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
@@ -48,7 +50,7 @@ struct cflayer *cfrfml_create(u8 channel_id, struct dev_info *dev_info,
kzalloc(sizeof(struct cfrfml), GFP_ATOMIC);
if (!this) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return NULL;
}
@@ -178,9 +180,7 @@ out:
cfpkt_destroy(rfml->incomplete_frm);
rfml->incomplete_frm = NULL;
- pr_info("CAIF: %s(): "
- "Connection error %d triggered on RFM link\n",
- __func__, err);
+ pr_info("Connection error %d triggered on RFM link\n", err);
/* Trigger connection error upon failure.*/
layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND,
@@ -280,9 +280,7 @@ static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt)
out:
if (err != 0) {
- pr_info("CAIF: %s(): "
- "Connection error %d triggered on RFM link\n",
- __func__, err);
+ pr_info("Connection error %d triggered on RFM link\n", err);
/* Trigger connection error upon failure.*/
layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND,
diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c
index a11fbd68a13d..9297f7dea9d8 100644
--- a/net/caif/cfserl.c
+++ b/net/caif/cfserl.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
@@ -34,7 +36,7 @@ struct cflayer *cfserl_create(int type, int instance, bool use_stx)
{
struct cfserl *this = kmalloc(sizeof(struct cfserl), GFP_ATOMIC);
if (!this) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return NULL;
}
caif_assert(offsetof(struct cfserl, layer) == 0);
diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c
index f40939a91211..ab5e542526bf 100644
--- a/net/caif/cfsrvl.c
+++ b/net/caif/cfsrvl.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
@@ -79,8 +81,7 @@ static void cfservl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
layr->up->ctrlcmd(layr->up, ctrl, phyid);
break;
default:
- pr_warning("CAIF: %s(): "
- "Unexpected ctrl in cfsrvl (%d)\n", __func__, ctrl);
+ pr_warn("Unexpected ctrl in cfsrvl (%d)\n", ctrl);
/* We have both modem and phy flow on, send flow on */
layr->up->ctrlcmd(layr->up, ctrl, phyid);
service->phy_flow_on = true;
@@ -107,14 +108,12 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl)
u8 flow_on = SRVL_FLOW_ON;
pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE);
if (!pkt) {
- pr_warning("CAIF: %s(): Out of memory\n",
- __func__);
+ pr_warn("Out of memory\n");
return -ENOMEM;
}
if (cfpkt_add_head(pkt, &flow_on, 1) < 0) {
- pr_err("CAIF: %s(): Packet is erroneous!\n",
- __func__);
+ pr_err("Packet is erroneous!\n");
cfpkt_destroy(pkt);
return -EPROTO;
}
@@ -131,14 +130,12 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl)
u8 flow_off = SRVL_FLOW_OFF;
pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE);
if (!pkt) {
- pr_warning("CAIF: %s(): Out of memory\n",
- __func__);
+ pr_warn("Out of memory\n");
return -ENOMEM;
}
if (cfpkt_add_head(pkt, &flow_off, 1) < 0) {
- pr_err("CAIF: %s(): Packet is erroneous!\n",
- __func__);
+ pr_err("Packet is erroneous!\n");
cfpkt_destroy(pkt);
return -EPROTO;
}
diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c
index 02795aff57a4..efad410e4c82 100644
--- a/net/caif/cfutill.c
+++ b/net/caif/cfutill.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/slab.h>
@@ -26,7 +28,7 @@ struct cflayer *cfutill_create(u8 channel_id, struct dev_info *dev_info)
{
struct cfsrvl *util = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
if (!util) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return NULL;
}
caif_assert(offsetof(struct cfsrvl, layer) == 0);
@@ -47,7 +49,7 @@ static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt)
caif_assert(layr->up->receive != NULL);
caif_assert(layr->up->ctrlcmd != NULL);
if (cfpkt_extr_head(pkt, &cmd, 1) < 0) {
- pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+ pr_err("Packet is erroneous!\n");
cfpkt_destroy(pkt);
return -EPROTO;
}
@@ -64,16 +66,14 @@ static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt)
cfpkt_destroy(pkt);
return 0;
case UTIL_REMOTE_SHUTDOWN: /* Remote Shutdown Request */
- pr_err("CAIF: %s(): REMOTE SHUTDOWN REQUEST RECEIVED\n",
- __func__);
+ pr_err("REMOTE SHUTDOWN REQUEST RECEIVED\n");
layr->ctrlcmd(layr, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, 0);
service->open = false;
cfpkt_destroy(pkt);
return 0;
default:
cfpkt_destroy(pkt);
- pr_warning("CAIF: %s(): Unknown service control %d (0x%x)\n",
- __func__, cmd, cmd);
+ pr_warn("Unknown service control %d (0x%x)\n", cmd, cmd);
return -EPROTO;
}
}
diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c
index 77cc09faac9a..3b425b189a99 100644
--- a/net/caif/cfveil.c
+++ b/net/caif/cfveil.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/stddef.h>
#include <linux/slab.h>
#include <net/caif/caif_layer.h>
@@ -25,7 +27,7 @@ struct cflayer *cfvei_create(u8 channel_id, struct dev_info *dev_info)
{
struct cfsrvl *vei = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
if (!vei) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return NULL;
}
caif_assert(offsetof(struct cfsrvl, layer) == 0);
@@ -47,7 +49,7 @@ static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt)
if (cfpkt_extr_head(pkt, &cmd, 1) < 0) {
- pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+ pr_err("Packet is erroneous!\n");
cfpkt_destroy(pkt);
return -EPROTO;
}
@@ -67,8 +69,7 @@ static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt)
cfpkt_destroy(pkt);
return 0;
default: /* SET RS232 PIN */
- pr_warning("CAIF: %s():Unknown VEI control packet %d (0x%x)!\n",
- __func__, cmd, cmd);
+ pr_warn("Unknown VEI control packet %d (0x%x)!\n", cmd, cmd);
cfpkt_destroy(pkt);
return -EPROTO;
}
@@ -86,7 +87,7 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt)
caif_assert(layr->dn->transmit != NULL);
if (cfpkt_add_head(pkt, &tmp, 1) < 0) {
- pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+ pr_err("Packet is erroneous!\n");
return -EPROTO;
}
diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c
index ada6ee2d48f5..bf6fef2a0eff 100644
--- a/net/caif/cfvidl.c
+++ b/net/caif/cfvidl.c
@@ -4,6 +4,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/slab.h>
@@ -21,7 +23,7 @@ struct cflayer *cfvidl_create(u8 channel_id, struct dev_info *dev_info)
{
struct cfsrvl *vid = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
if (!vid) {
- pr_warning("CAIF: %s(): Out of memory\n", __func__);
+ pr_warn("Out of memory\n");
return NULL;
}
caif_assert(offsetof(struct cfsrvl, layer) == 0);
@@ -38,7 +40,7 @@ static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt)
{
u32 videoheader;
if (cfpkt_extr_head(pkt, &videoheader, 4) < 0) {
- pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+ pr_err("Packet is erroneous!\n");
cfpkt_destroy(pkt);
return -EPROTO;
}
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
index 4293e190ec53..84a422c98941 100644
--- a/net/caif/chnl_net.c
+++ b/net/caif/chnl_net.c
@@ -5,6 +5,8 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
+
#include <linux/version.h>
#include <linux/fs.h>
#include <linux/init.h>
@@ -28,9 +30,6 @@
#define CONNECT_TIMEOUT (5 * HZ)
#define CAIF_NET_DEFAULT_QUEUE_LEN 500
-#undef pr_debug
-#define pr_debug pr_warning
-
/*This list is protected by the rtnl lock. */
static LIST_HEAD(chnl_net_list);
@@ -142,8 +141,7 @@ static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow,
int phyid)
{
struct chnl_net *priv = container_of(layr, struct chnl_net, chnl);
- pr_debug("CAIF: %s(): NET flowctrl func called flow: %s\n",
- __func__,
+ pr_debug("NET flowctrl func called flow: %s\n",
flow == CAIF_CTRLCMD_FLOW_ON_IND ? "ON" :
flow == CAIF_CTRLCMD_INIT_RSP ? "INIT" :
flow == CAIF_CTRLCMD_FLOW_OFF_IND ? "OFF" :
@@ -196,12 +194,12 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
priv = netdev_priv(dev);
if (skb->len > priv->netdev->mtu) {
- pr_warning("CAIF: %s(): Size of skb exceeded MTU\n", __func__);
+ pr_warn("Size of skb exceeded MTU\n");
return -ENOSPC;
}
if (!priv->flowenabled) {
- pr_debug("CAIF: %s(): dropping packets flow off\n", __func__);
+ pr_debug("dropping packets flow off\n");
return NETDEV_TX_BUSY;
}
@@ -237,7 +235,7 @@ static int chnl_net_open(struct net_device *dev)
ASSERT_RTNL();
priv = netdev_priv(dev);
if (!priv) {
- pr_debug("CAIF: %s(): chnl_net_open: no priv\n", __func__);
+ pr_debug("chnl_net_open: no priv\n");
return -ENODEV;
}
@@ -246,18 +244,17 @@ static int chnl_net_open(struct net_device *dev)
result = caif_connect_client(&priv->conn_req, &priv->chnl,
&llifindex, &headroom, &tailroom);
if (result != 0) {
- pr_debug("CAIF: %s(): err: "
- "Unable to register and open device,"
- " Err:%d\n",
- __func__,
- result);
+ pr_debug("err: "
+ "Unable to register and open device,"
+ " Err:%d\n",
+ result);
goto error;
}
lldev = dev_get_by_index(dev_net(dev), llifindex);
if (lldev == NULL) {
- pr_debug("CAIF: %s(): no interface?\n", __func__);
+ pr_debug("no interface?\n");
result = -ENODEV;
goto error;
}
@@ -279,9 +276,7 @@ static int chnl_net_open(struct net_device *dev)
dev_put(lldev);
if (mtu < 100) {
- pr_warning("CAIF: %s(): "
- "CAIF Interface MTU too small (%d)\n",
- __func__, mtu);
+ pr_warn("CAIF Interface MTU too small (%d)\n", mtu);
result = -ENODEV;
goto error;
}
@@ -296,33 +291,32 @@ static int chnl_net_open(struct net_device *dev)
rtnl_lock();
if (result == -ERESTARTSYS) {
- pr_debug("CAIF: %s(): wait_event_interruptible"
- " woken by a signal\n", __func__);
+ pr_debug("wait_event_interruptible woken by a signal\n");
result = -ERESTARTSYS;
goto error;
}
if (result == 0) {
- pr_debug("CAIF: %s(): connect timeout\n", __func__);
+ pr_debug("connect timeout\n");
caif_disconnect_client(&priv->chnl);
priv->state = CAIF_DISCONNECTED;
- pr_debug("CAIF: %s(): state disconnected\n", __func__);
+ pr_debug("state disconnected\n");
result = -ETIMEDOUT;
goto error;
}
if (priv->state != CAIF_CONNECTED) {
- pr_debug("CAIF: %s(): connect failed\n", __func__);
+ pr_debug("connect failed\n");
result = -ECONNREFUSED;
goto error;
}
- pr_debug("CAIF: %s(): CAIF Netdevice connected\n", __func__);
+ pr_debug("CAIF Netdevice connected\n");
return 0;
error:
caif_disconnect_client(&priv->chnl);
priv->state = CAIF_DISCONNECTED;
- pr_debug("CAIF: %s(): state disconnected\n", __func__);
+ pr_debug("state disconnected\n");
return result;
}
@@ -413,7 +407,7 @@ static void caif_netlink_parms(struct nlattr *data[],
struct caif_connect_request *conn_req)
{
if (!data) {
- pr_warning("CAIF: %s: no params data found\n", __func__);
+ pr_warn("no params data found\n");
return;
}
if (data[IFLA_CAIF_IPV4_CONNID])
@@ -442,8 +436,7 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev,
ret = register_netdevice(dev);
if (ret)
- pr_warning("CAIF: %s(): device rtml registration failed\n",
- __func__);
+ pr_warn("device rtml registration failed\n");
return ret;
}
diff --git a/net/can/raw.c b/net/can/raw.c
index a10e3338f084..e88f610fdb7b 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -90,23 +90,39 @@ struct raw_sock {
can_err_mask_t err_mask;
};
+/*
+ * Return pointer to store the extra msg flags for raw_recvmsg().
+ * We use the space of one unsigned int beyond the 'struct sockaddr_can'
+ * in skb->cb.
+ */
+static inline unsigned int *raw_flags(struct sk_buff *skb)
+{
+ BUILD_BUG_ON(sizeof(skb->cb) <= (sizeof(struct sockaddr_can) +
+ sizeof(unsigned int)));
+
+ /* return pointer after struct sockaddr_can */
+ return (unsigned int *)(&((struct sockaddr_can *)skb->cb)[1]);
+}
+
static inline struct raw_sock *raw_sk(const struct sock *sk)
{
return (struct raw_sock *)sk;
}
-static void raw_rcv(struct sk_buff *skb, void *data)
+static void raw_rcv(struct sk_buff *oskb, void *data)
{
struct sock *sk = (struct sock *)data;
struct raw_sock *ro = raw_sk(sk);
struct sockaddr_can *addr;
+ struct sk_buff *skb;
+ unsigned int *pflags;
/* check the received tx sock reference */
- if (!ro->recv_own_msgs && skb->sk == sk)
+ if (!ro->recv_own_msgs && oskb->sk == sk)
return;
/* clone the given skb to be able to enqueue it into the rcv queue */
- skb = skb_clone(skb, GFP_ATOMIC);
+ skb = skb_clone(oskb, GFP_ATOMIC);
if (!skb)
return;
@@ -123,6 +139,14 @@ static void raw_rcv(struct sk_buff *skb, void *data)
addr->can_family = AF_CAN;
addr->can_ifindex = skb->dev->ifindex;
+ /* add CAN specific message flags for raw_recvmsg() */
+ pflags = raw_flags(skb);
+ *pflags = 0;
+ if (oskb->sk)
+ *pflags |= MSG_DONTROUTE;
+ if (oskb->sk == sk)
+ *pflags |= MSG_CONFIRM;
+
if (sock_queue_rcv_skb(sk, skb) < 0)
kfree_skb(skb);
}
@@ -647,12 +671,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
if (err < 0)
goto free_skb;
- err = sock_tx_timestamp(msg, sk, skb_tx(skb));
+ err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
if (err < 0)
goto free_skb;
/* to be able to check the received tx sock reference in raw_rcv() */
- skb_tx(skb)->prevent_sk_orphan = 1;
+ skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF;
skb->dev = dev;
skb->sk = sk;
@@ -707,6 +731,9 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
}
+ /* assign the flags that have been recorded in raw_rcv() */
+ msg->msg_flags |= *(raw_flags(skb));
+
skb_free_datagram(sk, skb);
return size;
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 282806ba7a57..cd1e039c8755 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -747,13 +747,12 @@ unsigned int datagram_poll(struct file *file, struct socket *sock,
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
mask |= POLLERR;
if (sk->sk_shutdown & RCV_SHUTDOWN)
- mask |= POLLRDHUP;
+ mask |= POLLRDHUP | POLLIN | POLLRDNORM;
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
/* readable? */
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- (sk->sk_shutdown & RCV_SHUTDOWN))
+ if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= POLLIN | POLLRDNORM;
/* Connection-based need to check for termination and startup */
diff --git a/net/core/dev.c b/net/core/dev.c
index 7ec85e27beed..78b5a89b0f40 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -131,6 +131,7 @@
#include <trace/events/net.h>
#include <trace/events/skb.h>
#include <linux/pci.h>
+#include <linux/inetdevice.h>
#include "net-sysfs.h"
@@ -373,6 +374,14 @@ static inline void netdev_set_addr_lockdep_class(struct net_device *dev)
* --ANK (980803)
*/
+static inline struct list_head *ptype_head(const struct packet_type *pt)
+{
+ if (pt->type == htons(ETH_P_ALL))
+ return &ptype_all;
+ else
+ return &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK];
+}
+
/**
* dev_add_pack - add packet handler
* @pt: packet type declaration
@@ -388,16 +397,11 @@ static inline void netdev_set_addr_lockdep_class(struct net_device *dev)
void dev_add_pack(struct packet_type *pt)
{
- int hash;
+ struct list_head *head = ptype_head(pt);
- spin_lock_bh(&ptype_lock);
- if (pt->type == htons(ETH_P_ALL))
- list_add_rcu(&pt->list, &ptype_all);
- else {
- hash = ntohs(pt->type) & PTYPE_HASH_MASK;
- list_add_rcu(&pt->list, &ptype_base[hash]);
- }
- spin_unlock_bh(&ptype_lock);
+ spin_lock(&ptype_lock);
+ list_add_rcu(&pt->list, head);
+ spin_unlock(&ptype_lock);
}
EXPORT_SYMBOL(dev_add_pack);
@@ -416,15 +420,10 @@ EXPORT_SYMBOL(dev_add_pack);
*/
void __dev_remove_pack(struct packet_type *pt)
{
- struct list_head *head;
+ struct list_head *head = ptype_head(pt);
struct packet_type *pt1;
- spin_lock_bh(&ptype_lock);
-
- if (pt->type == htons(ETH_P_ALL))
- head = &ptype_all;
- else
- head = &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK];
+ spin_lock(&ptype_lock);
list_for_each_entry(pt1, head, list) {
if (pt == pt1) {
@@ -435,7 +434,7 @@ void __dev_remove_pack(struct packet_type *pt)
printk(KERN_WARNING "dev_remove_pack: %p not found.\n", pt);
out:
- spin_unlock_bh(&ptype_lock);
+ spin_unlock(&ptype_lock);
}
EXPORT_SYMBOL(__dev_remove_pack);
@@ -1486,8 +1485,9 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
skb_orphan(skb);
nf_reset(skb);
- if (!(dev->flags & IFF_UP) ||
- (skb->len > (dev->mtu + dev->hard_header_len))) {
+ if (unlikely(!(dev->flags & IFF_UP) ||
+ (skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN)))) {
+ atomic_long_inc(&dev->rx_dropped);
kfree_skb(skb);
return NET_RX_DROP;
}
@@ -1555,21 +1555,56 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
* Routine to help set real_num_tx_queues. To avoid skbs mapped to queues
* greater then real_num_tx_queues stale skbs on the qdisc must be flushed.
*/
-void netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
+int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
{
- unsigned int real_num = dev->real_num_tx_queues;
+ if (txq < 1 || txq > dev->num_tx_queues)
+ return -EINVAL;
- if (unlikely(txq > dev->num_tx_queues))
- ;
- else if (txq > real_num)
- dev->real_num_tx_queues = txq;
- else if (txq < real_num) {
- dev->real_num_tx_queues = txq;
- qdisc_reset_all_tx_gt(dev, txq);
+ if (dev->reg_state == NETREG_REGISTERED) {
+ ASSERT_RTNL();
+
+ if (txq < dev->real_num_tx_queues)
+ qdisc_reset_all_tx_gt(dev, txq);
}
+
+ dev->real_num_tx_queues = txq;
+ return 0;
}
EXPORT_SYMBOL(netif_set_real_num_tx_queues);
+#ifdef CONFIG_RPS
+/**
+ * netif_set_real_num_rx_queues - set actual number of RX queues used
+ * @dev: Network device
+ * @rxq: Actual number of RX queues
+ *
+ * This must be called either with the rtnl_lock held or before
+ * registration of the net device. Returns 0 on success, or a
+ * negative error code. If called before registration, it always
+ * succeeds.
+ */
+int netif_set_real_num_rx_queues(struct net_device *dev, unsigned int rxq)
+{
+ int rc;
+
+ if (rxq < 1 || rxq > dev->num_rx_queues)
+ return -EINVAL;
+
+ if (dev->reg_state == NETREG_REGISTERED) {
+ ASSERT_RTNL();
+
+ rc = net_rx_queue_update_kobjects(dev, dev->real_num_rx_queues,
+ rxq);
+ if (rc)
+ return rc;
+ }
+
+ dev->real_num_rx_queues = rxq;
+ return 0;
+}
+EXPORT_SYMBOL(netif_set_real_num_rx_queues);
+#endif
+
static inline void __netif_reschedule(struct Qdisc *q)
{
struct softnet_data *sd;
@@ -1661,7 +1696,12 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol)
static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
{
- if (can_checksum_protocol(dev->features, skb->protocol))
+ int features = dev->features;
+
+ if (vlan_tx_tag_present(skb))
+ features &= dev->vlan_features;
+
+ if (can_checksum_protocol(features, skb->protocol))
return true;
if (skb->protocol == htons(ETH_P_8021Q)) {
@@ -1760,6 +1800,16 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
__be16 type = skb->protocol;
int err;
+ if (type == htons(ETH_P_8021Q)) {
+ struct vlan_ethhdr *veh;
+
+ if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
+ return ERR_PTR(-EINVAL);
+
+ veh = (struct vlan_ethhdr *)skb->data;
+ type = veh->h_vlan_encapsulated_proto;
+ }
+
skb_reset_mac_header(skb);
skb->mac_len = skb->network_header - skb->mac_header;
__skb_pull(skb, skb->mac_len);
@@ -1904,14 +1954,14 @@ static int dev_gso_segment(struct sk_buff *skb)
/*
* Try to orphan skb early, right before transmission by the device.
- * We cannot orphan skb if tx timestamp is requested, since
- * drivers need to call skb_tstamp_tx() to send the timestamp.
+ * We cannot orphan skb if tx timestamp is requested or the sk-reference
+ * is needed on driver level for other reasons, e.g. see net/can/raw.c
*/
static inline void skb_orphan_try(struct sk_buff *skb)
{
struct sock *sk = skb->sk;
- if (sk && !skb_tx(skb)->flags) {
+ if (sk && !skb_shinfo(skb)->tx_flags) {
/* skb_tx_hash() wont be able to get sk.
* We copy sk_hash into skb->rxhash
*/
@@ -1931,9 +1981,14 @@ static inline void skb_orphan_try(struct sk_buff *skb)
static inline int skb_needs_linearize(struct sk_buff *skb,
struct net_device *dev)
{
+ int features = dev->features;
+
+ if (skb->protocol == htons(ETH_P_8021Q) || vlan_tx_tag_present(skb))
+ features &= dev->vlan_features;
+
return skb_is_nonlinear(skb) &&
- ((skb_has_frags(skb) && !(dev->features & NETIF_F_FRAGLIST)) ||
- (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) ||
+ ((skb_has_frag_list(skb) && !(features & NETIF_F_FRAGLIST)) ||
+ (skb_shinfo(skb)->nr_frags && (!(features & NETIF_F_SG) ||
illegal_highdma(dev, skb))));
}
@@ -1956,6 +2011,15 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
skb_orphan_try(skb);
+ if (vlan_tx_tag_present(skb) &&
+ !(dev->features & NETIF_F_HW_VLAN_TX)) {
+ skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb));
+ if (unlikely(!skb))
+ goto out;
+
+ skb->vlan_tci = 0;
+ }
+
if (netif_needs_gso(dev, skb)) {
if (unlikely(dev_gso_segment(skb)))
goto out_kfree_skb;
@@ -2019,6 +2083,7 @@ out_kfree_gso_skb:
skb->destructor = DEV_GSO_CB(skb)->destructor;
out_kfree_skb:
kfree_skb(skb);
+out:
return rc;
}
@@ -2147,6 +2212,9 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
return rc;
}
+static DEFINE_PER_CPU(int, xmit_recursion);
+#define RECURSION_LIMIT 3
+
/**
* dev_queue_xmit - transmit a buffer
* @skb: buffer to transmit
@@ -2213,10 +2281,15 @@ int dev_queue_xmit(struct sk_buff *skb)
if (txq->xmit_lock_owner != cpu) {
+ if (__this_cpu_read(xmit_recursion) > RECURSION_LIMIT)
+ goto recursion_alert;
+
HARD_TX_LOCK(dev, txq, cpu);
if (!netif_tx_queue_stopped(txq)) {
+ __this_cpu_inc(xmit_recursion);
rc = dev_hard_start_xmit(skb, dev, txq);
+ __this_cpu_dec(xmit_recursion);
if (dev_xmit_complete(rc)) {
HARD_TX_UNLOCK(dev, txq);
goto out;
@@ -2228,7 +2301,9 @@ int dev_queue_xmit(struct sk_buff *skb)
"queue packet!\n", dev->name);
} else {
/* Recursion is detected! It is possible,
- * unfortunately */
+ * unfortunately
+ */
+recursion_alert:
if (net_ratelimit())
printk(KERN_CRIT "Dead loop on virtual device "
"%s, fix it urgently!\n", dev->name);
@@ -2264,69 +2339,44 @@ static inline void ____napi_schedule(struct softnet_data *sd,
__raise_softirq_irqoff(NET_RX_SOFTIRQ);
}
-#ifdef CONFIG_RPS
-
-/* One global table that all flow-based protocols share. */
-struct rps_sock_flow_table *rps_sock_flow_table __read_mostly;
-EXPORT_SYMBOL(rps_sock_flow_table);
-
/*
- * get_rps_cpu is called from netif_receive_skb and returns the target
- * CPU from the RPS map of the receiving queue for a given skb.
- * rcu_read_lock must be held on entry.
+ * __skb_get_rxhash: calculate a flow hash based on src/dst addresses
+ * and src/dst port numbers. Returns a non-zero hash number on success
+ * and 0 on failure.
*/
-static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
- struct rps_dev_flow **rflowp)
+__u32 __skb_get_rxhash(struct sk_buff *skb)
{
+ int nhoff, hash = 0, poff;
struct ipv6hdr *ip6;
struct iphdr *ip;
- struct netdev_rx_queue *rxqueue;
- struct rps_map *map;
- struct rps_dev_flow_table *flow_table;
- struct rps_sock_flow_table *sock_flow_table;
- int cpu = -1;
u8 ip_proto;
- u16 tcpu;
u32 addr1, addr2, ihl;
union {
u32 v32;
u16 v16[2];
} ports;
- if (skb_rx_queue_recorded(skb)) {
- u16 index = skb_get_rx_queue(skb);
- if (unlikely(index >= dev->num_rx_queues)) {
- WARN_ONCE(dev->num_rx_queues > 1, "%s received packet "
- "on queue %u, but number of RX queues is %u\n",
- dev->name, index, dev->num_rx_queues);
- goto done;
- }
- rxqueue = dev->_rx + index;
- } else
- rxqueue = dev->_rx;
-
- if (!rxqueue->rps_map && !rxqueue->rps_flow_table)
- goto done;
-
- if (skb->rxhash)
- goto got_hash; /* Skip hash computation on packet header */
+ nhoff = skb_network_offset(skb);
switch (skb->protocol) {
case __constant_htons(ETH_P_IP):
- if (!pskb_may_pull(skb, sizeof(*ip)))
+ if (!pskb_may_pull(skb, sizeof(*ip) + nhoff))
goto done;
- ip = (struct iphdr *) skb->data;
- ip_proto = ip->protocol;
+ ip = (struct iphdr *) (skb->data + nhoff);
+ if (ip->frag_off & htons(IP_MF | IP_OFFSET))
+ ip_proto = 0;
+ else
+ ip_proto = ip->protocol;
addr1 = (__force u32) ip->saddr;
addr2 = (__force u32) ip->daddr;
ihl = ip->ihl;
break;
case __constant_htons(ETH_P_IPV6):
- if (!pskb_may_pull(skb, sizeof(*ip6)))
+ if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff))
goto done;
- ip6 = (struct ipv6hdr *) skb->data;
+ ip6 = (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];
@@ -2335,33 +2385,81 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
default:
goto done;
}
- switch (ip_proto) {
- case IPPROTO_TCP:
- case IPPROTO_UDP:
- case IPPROTO_DCCP:
- case IPPROTO_ESP:
- case IPPROTO_AH:
- case IPPROTO_SCTP:
- case IPPROTO_UDPLITE:
- if (pskb_may_pull(skb, (ihl * 4) + 4)) {
- ports.v32 = * (__force u32 *) (skb->data + (ihl * 4));
+
+ ports.v32 = 0;
+ poff = proto_ports_offset(ip_proto);
+ if (poff >= 0) {
+ nhoff += ihl * 4 + poff;
+ if (pskb_may_pull(skb, nhoff + 4)) {
+ ports.v32 = * (__force u32 *) (skb->data + nhoff);
if (ports.v16[1] < ports.v16[0])
swap(ports.v16[0], ports.v16[1]);
- break;
}
- default:
- ports.v32 = 0;
- break;
}
/* get a consistent hash (same value on both flow directions) */
if (addr2 < addr1)
swap(addr1, addr2);
- skb->rxhash = jhash_3words(addr1, addr2, ports.v32, hashrnd);
- if (!skb->rxhash)
- skb->rxhash = 1;
-got_hash:
+ hash = jhash_3words(addr1, addr2, ports.v32, hashrnd);
+ if (!hash)
+ hash = 1;
+
+done:
+ return hash;
+}
+EXPORT_SYMBOL(__skb_get_rxhash);
+
+#ifdef CONFIG_RPS
+
+/* One global table that all flow-based protocols share. */
+struct rps_sock_flow_table *rps_sock_flow_table __read_mostly;
+EXPORT_SYMBOL(rps_sock_flow_table);
+
+/*
+ * get_rps_cpu is called from netif_receive_skb and returns the target
+ * CPU from the RPS map of the receiving queue for a given skb.
+ * rcu_read_lock must be held on entry.
+ */
+static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
+ struct rps_dev_flow **rflowp)
+{
+ struct netdev_rx_queue *rxqueue;
+ struct rps_map *map = NULL;
+ struct rps_dev_flow_table *flow_table;
+ struct rps_sock_flow_table *sock_flow_table;
+ int cpu = -1;
+ u16 tcpu;
+
+ if (skb_rx_queue_recorded(skb)) {
+ u16 index = skb_get_rx_queue(skb);
+ if (unlikely(index >= dev->real_num_rx_queues)) {
+ WARN_ONCE(dev->real_num_rx_queues > 1,
+ "%s received packet on queue %u, but number "
+ "of RX queues is %u\n",
+ dev->name, index, dev->real_num_rx_queues);
+ goto done;
+ }
+ rxqueue = dev->_rx + index;
+ } else
+ rxqueue = dev->_rx;
+
+ if (rxqueue->rps_map) {
+ map = rcu_dereference(rxqueue->rps_map);
+ if (map && map->len == 1) {
+ tcpu = map->cpus[0];
+ if (cpu_online(tcpu))
+ cpu = tcpu;
+ goto done;
+ }
+ } else if (!rxqueue->rps_flow_table) {
+ goto done;
+ }
+
+ skb_reset_network_header(skb);
+ if (!skb_get_rxhash(skb))
+ goto done;
+
flow_table = rcu_dereference(rxqueue->rps_flow_table);
sock_flow_table = rcu_dereference(rps_sock_flow_table);
if (flow_table && sock_flow_table) {
@@ -2401,7 +2499,6 @@ got_hash:
}
}
- map = rcu_dereference(rxqueue->rps_map);
if (map) {
tcpu = map->cpus[((u64) skb->rxhash * map->len) >> 32];
@@ -2487,6 +2584,7 @@ enqueue:
local_irq_restore(flags);
+ atomic_long_inc(&skb->dev->rx_dropped);
kfree_skb(skb);
return NET_RX_DROP;
}
@@ -2643,11 +2741,10 @@ EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook);
* the ingress scheduler, you just cant add policies on ingress.
*
*/
-static int ing_filter(struct sk_buff *skb)
+static int ing_filter(struct sk_buff *skb, struct netdev_queue *rxq)
{
struct net_device *dev = skb->dev;
u32 ttl = G_TC_RTTL(skb->tc_verd);
- struct netdev_queue *rxq;
int result = TC_ACT_OK;
struct Qdisc *q;
@@ -2661,8 +2758,6 @@ static int ing_filter(struct sk_buff *skb)
skb->tc_verd = SET_TC_RTTL(skb->tc_verd, ttl);
skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_INGRESS);
- rxq = &dev->rx_queue;
-
q = rxq->qdisc;
if (q != &noop_qdisc) {
spin_lock(qdisc_lock(q));
@@ -2678,7 +2773,9 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb,
struct packet_type **pt_prev,
int *ret, struct net_device *orig_dev)
{
- if (skb->dev->rx_queue.qdisc == &noop_qdisc)
+ struct netdev_queue *rxq = rcu_dereference(skb->dev->ingress_queue);
+
+ if (!rxq || rxq->qdisc == &noop_qdisc)
goto out;
if (*pt_prev) {
@@ -2686,7 +2783,7 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb,
*pt_prev = NULL;
}
- switch (ing_filter(skb)) {
+ switch (ing_filter(skb, rxq)) {
case TC_ACT_SHOT:
case TC_ACT_STOLEN:
kfree_skb(skb);
@@ -2699,33 +2796,6 @@ out:
}
#endif
-/*
- * netif_nit_deliver - deliver received packets to network taps
- * @skb: buffer
- *
- * This function is used to deliver incoming packets to network
- * taps. It should be used when the normal netif_receive_skb path
- * is bypassed, for example because of VLAN acceleration.
- */
-void netif_nit_deliver(struct sk_buff *skb)
-{
- struct packet_type *ptype;
-
- if (list_empty(&ptype_all))
- return;
-
- skb_reset_network_header(skb);
- skb_reset_transport_header(skb);
- skb->mac_len = skb->network_header - skb->mac_header;
-
- rcu_read_lock();
- list_for_each_entry_rcu(ptype, &ptype_all, list) {
- if (!ptype->dev || ptype->dev == skb->dev)
- deliver_skb(skb, ptype, skb->dev);
- }
- rcu_read_unlock();
-}
-
/**
* netdev_rx_handler_register - register receive handler
* @dev: device to register a handler for
@@ -2836,8 +2906,6 @@ static int __netif_receive_skb(struct sk_buff *skb)
net_timestamp_check(skb);
trace_netif_receive_skb(skb);
- if (vlan_tx_tag_present(skb) && vlan_hwaccel_do_receive(skb))
- return NET_RX_SUCCESS;
/* if we've gotten here through NAPI, check netpoll */
if (netpoll_receive_skb(skb))
@@ -2851,8 +2919,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
* be delivered to pkt handlers that are exact matches. Also
* the deliver_no_wcard flag will be set. If packet handlers
* are sensitive to duplicate packets these skbs will need to
- * be dropped at the handler. The vlan accel path may have
- * already set the deliver_no_wcard flag.
+ * be dropped at the handler.
*/
null_or_orig = NULL;
orig_dev = skb->dev;
@@ -2911,6 +2978,18 @@ ncls:
goto out;
}
+ if (vlan_tx_tag_present(skb)) {
+ if (pt_prev) {
+ ret = deliver_skb(skb, pt_prev, orig_dev);
+ pt_prev = NULL;
+ }
+ if (vlan_hwaccel_do_receive(&skb)) {
+ ret = __netif_receive_skb(skb);
+ goto out;
+ } else if (unlikely(!skb))
+ goto out;
+ }
+
/*
* Make sure frames received on VLAN interfaces stacked on
* bonding interfaces still make their way to any base bonding
@@ -2938,6 +3017,7 @@ ncls:
if (pt_prev) {
ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
} else {
+ atomic_long_inc(&skb->dev->rx_dropped);
kfree_skb(skb);
/* Jamal, now you will not able to escape explaining
* me how you were going to use this. :-)
@@ -3058,7 +3138,7 @@ out:
return netif_receive_skb(skb);
}
-static void napi_gro_flush(struct napi_struct *napi)
+inline void napi_gro_flush(struct napi_struct *napi)
{
struct sk_buff *skb, *next;
@@ -3071,6 +3151,7 @@ static void napi_gro_flush(struct napi_struct *napi)
napi->gro_count = 0;
napi->gro_list = NULL;
}
+EXPORT_SYMBOL(napi_gro_flush);
enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
@@ -3085,7 +3166,7 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
if (!(skb->dev->features & NETIF_F_GRO) || netpoll_rx_on(skb))
goto normal;
- if (skb_is_gso(skb) || skb_has_frags(skb))
+ if (skb_is_gso(skb) || skb_has_frag_list(skb))
goto normal;
rcu_read_lock();
@@ -3164,16 +3245,19 @@ normal:
}
EXPORT_SYMBOL(dev_gro_receive);
-static gro_result_t
+static inline gro_result_t
__napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
struct sk_buff *p;
for (p = napi->gro_list; p; p = p->next) {
- NAPI_GRO_CB(p)->same_flow =
- (p->dev == skb->dev) &&
- !compare_ether_header(skb_mac_header(p),
+ unsigned long diffs;
+
+ diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
+ diffs |= p->vlan_tci ^ skb->vlan_tci;
+ diffs |= compare_ether_header(skb_mac_header(p),
skb_gro_mac_header(skb));
+ NAPI_GRO_CB(p)->same_flow = !diffs;
NAPI_GRO_CB(p)->flush = 0;
}
@@ -3226,14 +3310,14 @@ gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
}
EXPORT_SYMBOL(napi_gro_receive);
-void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
+static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
{
__skb_pull(skb, skb_headlen(skb));
skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb));
+ skb->vlan_tci = 0;
napi->skb = skb;
}
-EXPORT_SYMBOL(napi_reuse_skb);
struct sk_buff *napi_get_frags(struct napi_struct *napi)
{
@@ -4867,21 +4951,6 @@ static void rollback_registered(struct net_device *dev)
rollback_registered_many(&single);
}
-static void __netdev_init_queue_locks_one(struct net_device *dev,
- struct netdev_queue *dev_queue,
- void *_unused)
-{
- spin_lock_init(&dev_queue->_xmit_lock);
- netdev_set_xmit_lockdep_class(&dev_queue->_xmit_lock, dev->type);
- dev_queue->xmit_lock_owner = -1;
-}
-
-static void netdev_init_queue_locks(struct net_device *dev)
-{
- netdev_for_each_tx_queue(dev, __netdev_init_queue_locks_one, NULL);
- __netdev_init_queue_locks_one(dev, &dev->rx_queue, NULL);
-}
-
unsigned long netdev_fix_features(unsigned long features, const char *name)
{
/* Fix illegal SG+CSUM combinations. */
@@ -4949,6 +5018,66 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev,
}
EXPORT_SYMBOL(netif_stacked_transfer_operstate);
+static int netif_alloc_rx_queues(struct net_device *dev)
+{
+#ifdef CONFIG_RPS
+ unsigned int i, count = dev->num_rx_queues;
+ struct netdev_rx_queue *rx;
+
+ BUG_ON(count < 1);
+
+ rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
+ if (!rx) {
+ pr_err("netdev: Unable to allocate %u rx queues.\n", count);
+ return -ENOMEM;
+ }
+ dev->_rx = rx;
+
+ /*
+ * Set a pointer to first element in the array which holds the
+ * reference count.
+ */
+ for (i = 0; i < count; i++)
+ rx[i].first = rx;
+#endif
+ return 0;
+}
+
+static int netif_alloc_netdev_queues(struct net_device *dev)
+{
+ unsigned int count = dev->num_tx_queues;
+ struct netdev_queue *tx;
+
+ BUG_ON(count < 1);
+
+ tx = kcalloc(count, sizeof(struct netdev_queue), GFP_KERNEL);
+ if (!tx) {
+ pr_err("netdev: Unable to allocate %u tx queues.\n",
+ count);
+ return -ENOMEM;
+ }
+ dev->_tx = tx;
+ return 0;
+}
+
+static void netdev_init_one_queue(struct net_device *dev,
+ struct netdev_queue *queue,
+ void *_unused)
+{
+ queue->dev = dev;
+
+ /* Initialize queue lock */
+ spin_lock_init(&queue->_xmit_lock);
+ netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type);
+ queue->xmit_lock_owner = -1;
+}
+
+static void netdev_init_queues(struct net_device *dev)
+{
+ netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL);
+ spin_lock_init(&dev->tx_global_lock);
+}
+
/**
* register_netdevice - register a network device
* @dev: device to register
@@ -4982,28 +5111,19 @@ int register_netdevice(struct net_device *dev)
spin_lock_init(&dev->addr_list_lock);
netdev_set_addr_lockdep_class(dev);
- netdev_init_queue_locks(dev);
dev->iflink = -1;
-#ifdef CONFIG_RPS
- if (!dev->num_rx_queues) {
- /*
- * Allocate a single RX queue if driver never called
- * alloc_netdev_mq
- */
+ ret = netif_alloc_rx_queues(dev);
+ if (ret)
+ goto out;
- dev->_rx = kzalloc(sizeof(struct netdev_rx_queue), GFP_KERNEL);
- if (!dev->_rx) {
- ret = -ENOMEM;
- goto out;
- }
+ ret = netif_alloc_netdev_queues(dev);
+ if (ret)
+ goto out;
+
+ netdev_init_queues(dev);
- dev->_rx->first = dev->_rx;
- atomic_set(&dev->_rx->count, 1);
- dev->num_rx_queues = 1;
- }
-#endif
/* Init, if this function is available */
if (dev->netdev_ops->ndo_init) {
ret = dev->netdev_ops->ndo_init(dev);
@@ -5043,6 +5163,12 @@ int register_netdevice(struct net_device *dev)
if (dev->features & NETIF_F_SG)
dev->features |= NETIF_F_GSO;
+ /* 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.
+ */
+ dev->vlan_features |= (NETIF_F_GRO | NETIF_F_HIGHDMA);
+
ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev);
ret = notifier_to_errno(ret);
if (ret)
@@ -5113,9 +5239,6 @@ int init_dummy_netdev(struct net_device *dev)
*/
dev->reg_state = NETREG_DUMMY;
- /* initialize the ref count */
- atomic_set(&dev->refcnt, 1);
-
/* NAPI wants this */
INIT_LIST_HEAD(&dev->napi_list);
@@ -5123,6 +5246,11 @@ int init_dummy_netdev(struct net_device *dev)
set_bit(__LINK_STATE_PRESENT, &dev->state);
set_bit(__LINK_STATE_START, &dev->state);
+ /* Note : We dont allocate pcpu_refcnt for dummy devices,
+ * because users of this 'device' dont need to change
+ * its refcount.
+ */
+
return 0;
}
EXPORT_SYMBOL_GPL(init_dummy_netdev);
@@ -5164,6 +5292,16 @@ out:
}
EXPORT_SYMBOL(register_netdev);
+int netdev_refcnt_read(const struct net_device *dev)
+{
+ int i, refcnt = 0;
+
+ for_each_possible_cpu(i)
+ refcnt += *per_cpu_ptr(dev->pcpu_refcnt, i);
+ return refcnt;
+}
+EXPORT_SYMBOL(netdev_refcnt_read);
+
/*
* netdev_wait_allrefs - wait until all references are gone.
*
@@ -5178,11 +5316,14 @@ EXPORT_SYMBOL(register_netdev);
static void netdev_wait_allrefs(struct net_device *dev)
{
unsigned long rebroadcast_time, warning_time;
+ int refcnt;
linkwatch_forget_dev(dev);
rebroadcast_time = warning_time = jiffies;
- while (atomic_read(&dev->refcnt) != 0) {
+ refcnt = netdev_refcnt_read(dev);
+
+ while (refcnt != 0) {
if (time_after(jiffies, rebroadcast_time + 1 * HZ)) {
rtnl_lock();
@@ -5209,11 +5350,13 @@ static void netdev_wait_allrefs(struct net_device *dev)
msleep(250);
+ refcnt = netdev_refcnt_read(dev);
+
if (time_after(jiffies, warning_time + 10 * HZ)) {
printk(KERN_EMERG "unregister_netdevice: "
"waiting for %s to become free. Usage "
"count = %d\n",
- dev->name, atomic_read(&dev->refcnt));
+ dev->name, refcnt);
warning_time = jiffies;
}
}
@@ -5271,8 +5414,8 @@ void netdev_run_todo(void)
netdev_wait_allrefs(dev);
/* paranoia */
- BUG_ON(atomic_read(&dev->refcnt));
- WARN_ON(dev->ip_ptr);
+ BUG_ON(netdev_refcnt_read(dev));
+ WARN_ON(rcu_dereference_raw(dev->ip_ptr));
WARN_ON(dev->ip6_ptr);
WARN_ON(dev->dn_ptr);
@@ -5350,30 +5493,34 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
if (ops->ndo_get_stats64) {
memset(storage, 0, sizeof(*storage));
- return ops->ndo_get_stats64(dev, storage);
- }
- if (ops->ndo_get_stats) {
+ ops->ndo_get_stats64(dev, storage);
+ } else if (ops->ndo_get_stats) {
netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev));
- return storage;
+ } else {
+ netdev_stats_to_stats64(storage, &dev->stats);
+ dev_txq_stats_fold(dev, storage);
}
- netdev_stats_to_stats64(storage, &dev->stats);
- dev_txq_stats_fold(dev, storage);
+ storage->rx_dropped += atomic_long_read(&dev->rx_dropped);
return storage;
}
EXPORT_SYMBOL(dev_get_stats);
-static void netdev_init_one_queue(struct net_device *dev,
- struct netdev_queue *queue,
- void *_unused)
+struct netdev_queue *dev_ingress_queue_create(struct net_device *dev)
{
- queue->dev = dev;
-}
+ struct netdev_queue *queue = dev_ingress_queue(dev);
-static void netdev_init_queues(struct net_device *dev)
-{
- netdev_init_one_queue(dev, &dev->rx_queue, NULL);
- netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL);
- spin_lock_init(&dev->tx_global_lock);
+#ifdef CONFIG_NET_CLS_ACT
+ if (queue)
+ return queue;
+ queue = kzalloc(sizeof(*queue), GFP_KERNEL);
+ if (!queue)
+ return NULL;
+ netdev_init_one_queue(dev, queue, NULL);
+ queue->qdisc = &noop_qdisc;
+ queue->qdisc_sleeping = &noop_qdisc;
+ rcu_assign_pointer(dev->ingress_queue, queue);
+#endif
+ return queue;
}
/**
@@ -5390,17 +5537,18 @@ static void netdev_init_queues(struct net_device *dev)
struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
void (*setup)(struct net_device *), unsigned int queue_count)
{
- struct netdev_queue *tx;
struct net_device *dev;
size_t alloc_size;
struct net_device *p;
-#ifdef CONFIG_RPS
- struct netdev_rx_queue *rx;
- int i;
-#endif
BUG_ON(strlen(name) >= sizeof(dev->name));
+ if (queue_count < 1) {
+ pr_err("alloc_netdev: Unable to allocate device "
+ "with zero queues.\n");
+ return NULL;
+ }
+
alloc_size = sizeof(struct net_device);
if (sizeof_priv) {
/* ensure 32-byte alignment of private area */
@@ -5416,55 +5564,31 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
return NULL;
}
- tx = kcalloc(queue_count, sizeof(struct netdev_queue), GFP_KERNEL);
- if (!tx) {
- printk(KERN_ERR "alloc_netdev: Unable to allocate "
- "tx qdiscs.\n");
- goto free_p;
- }
-
-#ifdef CONFIG_RPS
- rx = kcalloc(queue_count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
- if (!rx) {
- printk(KERN_ERR "alloc_netdev: Unable to allocate "
- "rx queues.\n");
- goto free_tx;
- }
-
- atomic_set(&rx->count, queue_count);
-
- /*
- * Set a pointer to first element in the array which holds the
- * reference count.
- */
- for (i = 0; i < queue_count; i++)
- rx[i].first = rx;
-#endif
-
dev = PTR_ALIGN(p, NETDEV_ALIGN);
dev->padded = (char *)dev - (char *)p;
+ dev->pcpu_refcnt = alloc_percpu(int);
+ if (!dev->pcpu_refcnt)
+ goto free_p;
+
if (dev_addr_init(dev))
- goto free_rx;
+ goto free_pcpu;
dev_mc_init(dev);
dev_uc_init(dev);
dev_net_set(dev, &init_net);
- dev->_tx = tx;
dev->num_tx_queues = queue_count;
dev->real_num_tx_queues = queue_count;
#ifdef CONFIG_RPS
- dev->_rx = rx;
dev->num_rx_queues = queue_count;
+ dev->real_num_rx_queues = queue_count;
#endif
dev->gso_max_size = GSO_MAX_SIZE;
- netdev_init_queues(dev);
-
INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list);
dev->ethtool_ntuple_list.count = 0;
INIT_LIST_HEAD(&dev->napi_list);
@@ -5475,12 +5599,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
strcpy(dev->name, name);
return dev;
-free_rx:
-#ifdef CONFIG_RPS
- kfree(rx);
-free_tx:
-#endif
- kfree(tx);
+free_pcpu:
+ free_percpu(dev->pcpu_refcnt);
free_p:
kfree(p);
return NULL;
@@ -5503,6 +5623,8 @@ void free_netdev(struct net_device *dev)
kfree(dev->_tx);
+ kfree(rcu_dereference_raw(dev->ingress_queue));
+
/* Flush device addresses */
dev_addr_flush(dev);
@@ -5512,6 +5634,9 @@ void free_netdev(struct net_device *dev)
list_for_each_entry_safe(p, n, &dev->napi_list, dev_list)
netif_napi_del(p);
+ free_percpu(dev->pcpu_refcnt);
+ dev->pcpu_refcnt = NULL;
+
/* Compatibility with error handling in drivers */
if (dev->reg_state == NETREG_UNINITIALIZED) {
kfree((char *)dev - dev->padded);
@@ -5666,6 +5791,10 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
/* Notify protocols, that we are about to destroy
this device. They should clean all the things.
+
+ Note that dev->reg_state stays at NETREG_REGISTERED.
+ This is wanted because this way 8021q and macvlan know
+ the device is just moving and can keep their slaves up.
*/
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
diff --git a/net/core/dst.c b/net/core/dst.c
index 6c41b1fac3db..8abe628b79f1 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -168,7 +168,7 @@ void *dst_alloc(struct dst_ops *ops)
{
struct dst_entry *dst;
- if (ops->gc && atomic_read(&ops->entries) > ops->gc_thresh) {
+ if (ops->gc && dst_entries_get_fast(ops) > ops->gc_thresh) {
if (ops->gc(ops))
return NULL;
}
@@ -183,7 +183,7 @@ void *dst_alloc(struct dst_ops *ops)
#if RT_CACHE_DEBUG >= 2
atomic_inc(&dst_total);
#endif
- atomic_inc(&ops->entries);
+ dst_entries_add(ops, 1);
return dst;
}
EXPORT_SYMBOL(dst_alloc);
@@ -228,15 +228,15 @@ again:
child = dst->child;
dst->hh = NULL;
- if (hh && atomic_dec_and_test(&hh->hh_refcnt))
- kfree(hh);
+ if (hh)
+ hh_cache_put(hh);
if (neigh) {
dst->neighbour = NULL;
neigh_release(neigh);
}
- atomic_dec(&dst->ops->entries);
+ dst_entries_add(dst->ops, -1);
if (dst->ops->destroy)
dst->ops->destroy(dst);
@@ -271,13 +271,40 @@ void dst_release(struct dst_entry *dst)
if (dst) {
int newrefcnt;
- smp_mb__before_atomic_dec();
newrefcnt = atomic_dec_return(&dst->__refcnt);
WARN_ON(newrefcnt < 0);
+ if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt) {
+ dst = dst_destroy(dst);
+ if (dst)
+ __dst_free(dst);
+ }
}
}
EXPORT_SYMBOL(dst_release);
+/**
+ * skb_dst_set_noref - sets skb dst, without a reference
+ * @skb: buffer
+ * @dst: dst entry
+ *
+ * Sets skb dst, assuming a reference was not taken on dst
+ * skb_dst_drop() should not dst_release() this dst
+ */
+void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst)
+{
+ WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held());
+ /* If dst not in cache, we must take a reference, because
+ * dst_release() will destroy dst as soon as its refcount becomes zero
+ */
+ if (unlikely(dst->flags & DST_NOCACHE)) {
+ dst_hold(dst);
+ skb_dst_set(skb, dst);
+ } else {
+ skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF;
+ }
+}
+EXPORT_SYMBOL(skb_dst_set_noref);
+
/* Dirty hack. We did it in 2.2 (in __dst_free),
* we have _very_ good reasons not to repeat
* this mistake in 2.3, but we have no choice
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 8451ab481095..956a9f4971cb 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -19,6 +19,7 @@
#include <linux/netdevice.h>
#include <linux/bitops.h>
#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
#include <linux/slab.h>
/*
@@ -131,7 +132,8 @@ EXPORT_SYMBOL(ethtool_op_set_ufo);
* NETIF_F_xxx values in include/linux/netdevice.h
*/
static const u32 flags_dup_features =
- (ETH_FLAG_LRO | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH);
+ (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
+ ETH_FLAG_RXHASH);
u32 ethtool_op_get_flags(struct net_device *dev)
{
@@ -205,18 +207,24 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo info;
const struct ethtool_ops *ops = dev->ethtool_ops;
- if (!ops->get_drvinfo)
- return -EOPNOTSUPP;
-
memset(&info, 0, sizeof(info));
info.cmd = ETHTOOL_GDRVINFO;
- ops->get_drvinfo(dev, &info);
+ if (ops && ops->get_drvinfo) {
+ ops->get_drvinfo(dev, &info);
+ } else if (dev->dev.parent && dev->dev.parent->driver) {
+ strlcpy(info.bus_info, dev_name(dev->dev.parent),
+ sizeof(info.bus_info));
+ strlcpy(info.driver, dev->dev.parent->driver->name,
+ sizeof(info.driver));
+ } else {
+ return -EOPNOTSUPP;
+ }
/*
* this method of obtaining string set info is deprecated;
* Use ETHTOOL_GSSET_INFO instead.
*/
- if (ops->get_sset_count) {
+ if (ops && ops->get_sset_count) {
int rc;
rc = ops->get_sset_count(dev, ETH_SS_TEST);
@@ -229,9 +237,9 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
if (rc >= 0)
info.n_priv_flags = rc;
}
- if (ops->get_regs_len)
+ if (ops && ops->get_regs_len)
info.regdump_len = ops->get_regs_len(dev);
- if (ops->get_eeprom_len)
+ if (ops && ops->get_eeprom_len)
info.eedump_len = ops->get_eeprom_len(dev);
if (copy_to_user(useraddr, &info, sizeof(info)))
@@ -479,6 +487,38 @@ static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
list->count++;
}
+/*
+ * ethtool does not (or did not) set masks for flow parameters that are
+ * not specified, so if both value and mask are 0 then this must be
+ * treated as equivalent to a mask with all bits set. Implement that
+ * here rather than in drivers.
+ */
+static void rx_ntuple_fix_masks(struct ethtool_rx_ntuple_flow_spec *fs)
+{
+ struct ethtool_tcpip4_spec *entry = &fs->h_u.tcp_ip4_spec;
+ struct ethtool_tcpip4_spec *mask = &fs->m_u.tcp_ip4_spec;
+
+ if (fs->flow_type != TCP_V4_FLOW &&
+ fs->flow_type != UDP_V4_FLOW &&
+ fs->flow_type != SCTP_V4_FLOW)
+ return;
+
+ if (!(entry->ip4src | mask->ip4src))
+ mask->ip4src = htonl(0xffffffff);
+ if (!(entry->ip4dst | mask->ip4dst))
+ mask->ip4dst = htonl(0xffffffff);
+ if (!(entry->psrc | mask->psrc))
+ mask->psrc = htons(0xffff);
+ if (!(entry->pdst | mask->pdst))
+ mask->pdst = htons(0xffff);
+ if (!(entry->tos | mask->tos))
+ mask->tos = 0xff;
+ if (!(fs->vlan_tag | fs->vlan_tag_mask))
+ fs->vlan_tag_mask = 0xffff;
+ if (!(fs->data | fs->data_mask))
+ fs->data_mask = 0xffffffffffffffffULL;
+}
+
static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev,
void __user *useraddr)
{
@@ -493,6 +533,8 @@ static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev,
if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
return -EFAULT;
+ rx_ntuple_fix_masks(&cmd.fs);
+
/*
* Cache filter in dev struct for GET operation only if
* the underlying driver doesn't have its own GET operation, and
@@ -667,19 +709,19 @@ static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr)
break;
case IP_USER_FLOW:
sprintf(p, "\tSrc IP addr: 0x%x\n",
- fsc->fs.h_u.raw_ip4_spec.ip4src);
+ fsc->fs.h_u.usr_ip4_spec.ip4src);
p += ETH_GSTRING_LEN;
num_strings++;
sprintf(p, "\tSrc IP mask: 0x%x\n",
- fsc->fs.m_u.raw_ip4_spec.ip4src);
+ fsc->fs.m_u.usr_ip4_spec.ip4src);
p += ETH_GSTRING_LEN;
num_strings++;
sprintf(p, "\tDest IP addr: 0x%x\n",
- fsc->fs.h_u.raw_ip4_spec.ip4dst);
+ fsc->fs.h_u.usr_ip4_spec.ip4dst);
p += ETH_GSTRING_LEN;
num_strings++;
sprintf(p, "\tDest IP mask: 0x%x\n",
- fsc->fs.m_u.raw_ip4_spec.ip4dst);
+ fsc->fs.m_u.usr_ip4_spec.ip4dst);
p += ETH_GSTRING_LEN;
num_strings++;
break;
@@ -775,7 +817,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
if (regs.len > reglen)
regs.len = reglen;
- regbuf = kzalloc(reglen, GFP_USER);
+ regbuf = vmalloc(reglen);
if (!regbuf)
return -ENOMEM;
@@ -790,7 +832,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
ret = 0;
out:
- kfree(regbuf);
+ vfree(regbuf);
return ret;
}
@@ -1175,8 +1217,11 @@ static int ethtool_set_gro(struct net_device *dev, char __user *useraddr)
return -EFAULT;
if (edata.data) {
- if (!dev->ethtool_ops->get_rx_csum ||
- !dev->ethtool_ops->get_rx_csum(dev))
+ u32 rxcsum = dev->ethtool_ops->get_rx_csum ?
+ dev->ethtool_ops->get_rx_csum(dev) :
+ ethtool_op_get_rx_csum(dev);
+
+ if (!rxcsum)
return -EINVAL;
dev->features |= NETIF_F_GRO;
} else
@@ -1402,14 +1447,22 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
if (!dev || !netif_device_present(dev))
return -ENODEV;
- if (!dev->ethtool_ops)
- return -EOPNOTSUPP;
-
if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
return -EFAULT;
+ if (!dev->ethtool_ops) {
+ /* ETHTOOL_GDRVINFO does not require any driver support.
+ * It is also unprivileged and does not change anything,
+ * so we can take a shortcut to it. */
+ if (ethcmd == ETHTOOL_GDRVINFO)
+ return ethtool_get_drvinfo(dev, useraddr);
+ else
+ return -EOPNOTSUPP;
+ }
+
/* Allow some commands to be done by anyone */
switch (ethcmd) {
+ case ETHTOOL_GSET:
case ETHTOOL_GDRVINFO:
case ETHTOOL_GMSGLVL:
case ETHTOOL_GCOALESCE:
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 42e84e08a1be..1bc3f253ba6c 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -144,7 +144,7 @@ fib_rules_register(const struct fib_rules_ops *tmpl, struct net *net)
}
EXPORT_SYMBOL_GPL(fib_rules_register);
-void fib_rules_cleanup_ops(struct fib_rules_ops *ops)
+static void fib_rules_cleanup_ops(struct fib_rules_ops *ops)
{
struct fib_rule *rule, *tmp;
@@ -153,7 +153,6 @@ void fib_rules_cleanup_ops(struct fib_rules_ops *ops)
fib_rule_put(rule);
}
}
-EXPORT_SYMBOL_GPL(fib_rules_cleanup_ops);
static void fib_rules_put_rcu(struct rcu_head *head)
{
@@ -182,7 +181,8 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
{
int ret = 0;
- if (rule->iifindex && (rule->iifindex != fl->iif))
+ if (rule->iifindex && (rule->iifindex != fl->iif) &&
+ !(fl->flags & FLOWI_FLAG_MATCH_ANY_IIF))
goto out;
if (rule->oifindex && (rule->oifindex != fl->oif))
@@ -225,9 +225,12 @@ jumped:
err = ops->action(rule, fl, flags, arg);
if (err != -EAGAIN) {
- fib_rule_get(rule);
- arg->rule = rule;
- goto out;
+ if ((arg->flags & FIB_LOOKUP_NOREF) ||
+ likely(atomic_inc_not_zero(&rule->refcnt))) {
+ arg->rule = rule;
+ goto out;
+ }
+ break;
}
}
@@ -491,7 +494,6 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
}
}
- synchronize_rcu();
notify_rule_change(RTM_DELRULE, rule, ops, nlh,
NETLINK_CB(skb).pid);
fib_rule_put(rule);
diff --git a/net/core/filter.c b/net/core/filter.c
index 52b051f82a01..7adf50352918 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -638,10 +638,9 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
return err;
}
- rcu_read_lock_bh();
- old_fp = rcu_dereference_bh(sk->sk_filter);
+ old_fp = rcu_dereference_protected(sk->sk_filter,
+ sock_owned_by_user(sk));
rcu_assign_pointer(sk->sk_filter, fp);
- rcu_read_unlock_bh();
if (old_fp)
sk_filter_delayed_uncharge(sk, old_fp);
@@ -654,14 +653,13 @@ int sk_detach_filter(struct sock *sk)
int ret = -ENOENT;
struct sk_filter *filter;
- rcu_read_lock_bh();
- filter = rcu_dereference_bh(sk->sk_filter);
+ filter = rcu_dereference_protected(sk->sk_filter,
+ sock_owned_by_user(sk));
if (filter) {
rcu_assign_pointer(sk->sk_filter, NULL);
sk_filter_delayed_uncharge(sk, filter);
ret = 0;
}
- rcu_read_unlock_bh();
return ret;
}
EXPORT_SYMBOL_GPL(sk_detach_filter);
diff --git a/net/core/flow.c b/net/core/flow.c
index f67dcbfe54ef..127c8a7ffd61 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -53,8 +53,7 @@ struct flow_flush_info {
struct flow_cache {
u32 hash_shift;
- unsigned long order;
- struct flow_cache_percpu *percpu;
+ struct flow_cache_percpu __percpu *percpu;
struct notifier_block hotcpu_notifier;
int low_watermark;
int high_watermark;
@@ -64,7 +63,7 @@ struct flow_cache {
atomic_t flow_cache_genid = ATOMIC_INIT(0);
EXPORT_SYMBOL(flow_cache_genid);
static struct flow_cache flow_cache_global;
-static struct kmem_cache *flow_cachep;
+static struct kmem_cache *flow_cachep __read_mostly;
static DEFINE_SPINLOCK(flow_cache_gc_lock);
static LIST_HEAD(flow_cache_gc_list);
@@ -177,15 +176,11 @@ static u32 flow_hash_code(struct flow_cache *fc,
{
u32 *k = (u32 *) key;
- return (jhash2(k, (sizeof(*key) / sizeof(u32)), fcp->hash_rnd)
- & (flow_cache_hash_size(fc) - 1));
+ return jhash2(k, (sizeof(*key) / sizeof(u32)), fcp->hash_rnd)
+ & (flow_cache_hash_size(fc) - 1);
}
-#if (BITS_PER_LONG == 64)
-typedef u64 flow_compare_t;
-#else
-typedef u32 flow_compare_t;
-#endif
+typedef unsigned long flow_compare_t;
/* I hear what you're saying, use memcmp. But memcmp cannot make
* important assumptions that we can here, such as alignment and
@@ -357,62 +352,73 @@ void flow_cache_flush(void)
put_online_cpus();
}
-static void __init flow_cache_cpu_prepare(struct flow_cache *fc,
- struct flow_cache_percpu *fcp)
+static int __cpuinit flow_cache_cpu_prepare(struct flow_cache *fc, int cpu)
{
- fcp->hash_table = (struct hlist_head *)
- __get_free_pages(GFP_KERNEL|__GFP_ZERO, fc->order);
- if (!fcp->hash_table)
- panic("NET: failed to allocate flow cache order %lu\n", fc->order);
+ struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu);
+ size_t sz = sizeof(struct hlist_head) * flow_cache_hash_size(fc);
- fcp->hash_rnd_recalc = 1;
- fcp->hash_count = 0;
- tasklet_init(&fcp->flush_tasklet, flow_cache_flush_tasklet, 0);
+ if (!fcp->hash_table) {
+ fcp->hash_table = kzalloc_node(sz, GFP_KERNEL, cpu_to_node(cpu));
+ if (!fcp->hash_table) {
+ pr_err("NET: failed to allocate flow cache sz %zu\n", sz);
+ return -ENOMEM;
+ }
+ fcp->hash_rnd_recalc = 1;
+ fcp->hash_count = 0;
+ tasklet_init(&fcp->flush_tasklet, flow_cache_flush_tasklet, 0);
+ }
+ return 0;
}
-static int flow_cache_cpu(struct notifier_block *nfb,
+static int __cpuinit flow_cache_cpu(struct notifier_block *nfb,
unsigned long action,
void *hcpu)
{
struct flow_cache *fc = container_of(nfb, struct flow_cache, hotcpu_notifier);
- int cpu = (unsigned long) hcpu;
+ int res, cpu = (unsigned long) hcpu;
struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu);
- if (action == CPU_DEAD || action == CPU_DEAD_FROZEN)
+ switch (action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ res = flow_cache_cpu_prepare(fc, cpu);
+ if (res)
+ return notifier_from_errno(res);
+ break;
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
__flow_cache_shrink(fc, fcp, 0);
+ break;
+ }
return NOTIFY_OK;
}
-static int flow_cache_init(struct flow_cache *fc)
+static int __init flow_cache_init(struct flow_cache *fc)
{
- unsigned long order;
int i;
fc->hash_shift = 10;
fc->low_watermark = 2 * flow_cache_hash_size(fc);
fc->high_watermark = 4 * flow_cache_hash_size(fc);
- for (order = 0;
- (PAGE_SIZE << order) <
- (sizeof(struct hlist_head)*flow_cache_hash_size(fc));
- order++)
- /* NOTHING */;
- fc->order = order;
fc->percpu = alloc_percpu(struct flow_cache_percpu);
+ if (!fc->percpu)
+ return -ENOMEM;
- setup_timer(&fc->rnd_timer, flow_cache_new_hashrnd,
- (unsigned long) fc);
- fc->rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD;
- add_timer(&fc->rnd_timer);
-
- for_each_possible_cpu(i)
- flow_cache_cpu_prepare(fc, per_cpu_ptr(fc->percpu, i));
-
+ for_each_online_cpu(i) {
+ if (flow_cache_cpu_prepare(fc, i))
+ return -ENOMEM;
+ }
fc->hotcpu_notifier = (struct notifier_block){
.notifier_call = flow_cache_cpu,
};
register_hotcpu_notifier(&fc->hotcpu_notifier);
+ setup_timer(&fc->rnd_timer, flow_cache_new_hashrnd,
+ (unsigned long) fc);
+ fc->rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD;
+ add_timer(&fc->rnd_timer);
+
return 0;
}
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 6743146e4d6b..7c2373321b74 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -274,9 +274,9 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
while ((e = gen_find_node(bstats, rate_est))) {
rb_erase(&e->node, &est_root);
- write_lock_bh(&est_lock);
+ write_lock(&est_lock);
e->bstats = NULL;
- write_unlock_bh(&est_lock);
+ write_unlock(&est_lock);
list_del_rcu(&e->list);
call_rcu(&e->e_rcu, __gen_kill_estimator);
diff --git a/net/core/iovec.c b/net/core/iovec.c
index e6b133b77ccb..72aceb1fe4fa 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -42,7 +42,9 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address,
if (m->msg_namelen) {
if (mode == VERIFY_READ) {
- err = move_addr_to_kernel(m->msg_name, m->msg_namelen,
+ void __user *namep;
+ namep = (void __user __force *) m->msg_name;
+ err = move_addr_to_kernel(namep, m->msg_namelen,
address);
if (err < 0)
return err;
@@ -53,7 +55,7 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address,
}
size = m->msg_iovlen * sizeof(struct iovec);
- if (copy_from_user(iov, m->msg_iov, size))
+ if (copy_from_user(iov, (void __user __force *) m->msg_iov, size))
return -EFAULT;
m->msg_iov = iov;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index a4e0a7482c2b..8cc8f9a79db9 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -122,7 +122,7 @@ static void neigh_cleanup_and_release(struct neighbour *neigh)
unsigned long neigh_rand_reach_time(unsigned long base)
{
- return (base ? (net_random() % base) + (base >> 1) : 0);
+ return base ? (net_random() % base) + (base >> 1) : 0;
}
EXPORT_SYMBOL(neigh_rand_reach_time);
@@ -131,15 +131,20 @@ static int neigh_forced_gc(struct neigh_table *tbl)
{
int shrunk = 0;
int i;
+ struct neigh_hash_table *nht;
NEIGH_CACHE_STAT_INC(tbl, forced_gc_runs);
write_lock_bh(&tbl->lock);
- for (i = 0; i <= tbl->hash_mask; i++) {
- struct neighbour *n, **np;
+ nht = rcu_dereference_protected(tbl->nht,
+ lockdep_is_held(&tbl->lock));
+ for (i = 0; i <= nht->hash_mask; i++) {
+ struct neighbour *n;
+ struct neighbour __rcu **np;
- np = &tbl->hash_buckets[i];
- while ((n = *np) != NULL) {
+ np = &nht->hash_buckets[i];
+ while ((n = rcu_dereference_protected(*np,
+ lockdep_is_held(&tbl->lock))) != NULL) {
/* Neighbour record may be discarded if:
* - nobody refers to it.
* - it is not permanent
@@ -147,7 +152,9 @@ static int neigh_forced_gc(struct neigh_table *tbl)
write_lock(&n->lock);
if (atomic_read(&n->refcnt) == 1 &&
!(n->nud_state & NUD_PERMANENT)) {
- *np = n->next;
+ rcu_assign_pointer(*np,
+ rcu_dereference_protected(n->next,
+ lockdep_is_held(&tbl->lock)));
n->dead = 1;
shrunk = 1;
write_unlock(&n->lock);
@@ -199,16 +206,24 @@ static void pneigh_queue_purge(struct sk_buff_head *list)
static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev)
{
int i;
+ struct neigh_hash_table *nht;
- for (i = 0; i <= tbl->hash_mask; i++) {
- struct neighbour *n, **np = &tbl->hash_buckets[i];
+ nht = rcu_dereference_protected(tbl->nht,
+ lockdep_is_held(&tbl->lock));
- while ((n = *np) != NULL) {
+ for (i = 0; i <= nht->hash_mask; i++) {
+ struct neighbour *n;
+ struct neighbour __rcu **np = &nht->hash_buckets[i];
+
+ while ((n = rcu_dereference_protected(*np,
+ lockdep_is_held(&tbl->lock))) != NULL) {
if (dev && n->dev != dev) {
np = &n->next;
continue;
}
- *np = n->next;
+ rcu_assign_pointer(*np,
+ rcu_dereference_protected(n->next,
+ lockdep_is_held(&tbl->lock)));
write_lock(&n->lock);
neigh_del_timer(n);
n->dead = 1;
@@ -279,6 +294,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl)
skb_queue_head_init(&n->arp_queue);
rwlock_init(&n->lock);
+ seqlock_init(&n->ha_lock);
n->updated = n->used = now;
n->nud_state = NUD_NONE;
n->output = neigh_blackhole;
@@ -297,64 +313,86 @@ out_entries:
goto out;
}
-static struct neighbour **neigh_hash_alloc(unsigned int entries)
+static struct neigh_hash_table *neigh_hash_alloc(unsigned int entries)
{
- unsigned long size = entries * sizeof(struct neighbour *);
- struct neighbour **ret;
+ size_t size = entries * sizeof(struct neighbour *);
+ struct neigh_hash_table *ret;
+ struct neighbour **buckets;
- if (size <= PAGE_SIZE) {
- ret = kzalloc(size, GFP_ATOMIC);
- } else {
- ret = (struct neighbour **)
- __get_free_pages(GFP_ATOMIC|__GFP_ZERO, get_order(size));
+ ret = kmalloc(sizeof(*ret), GFP_ATOMIC);
+ if (!ret)
+ return NULL;
+ if (size <= PAGE_SIZE)
+ buckets = kzalloc(size, GFP_ATOMIC);
+ else
+ buckets = (struct neighbour **)
+ __get_free_pages(GFP_ATOMIC | __GFP_ZERO,
+ get_order(size));
+ if (!buckets) {
+ kfree(ret);
+ return NULL;
}
+ rcu_assign_pointer(ret->hash_buckets, buckets);
+ ret->hash_mask = entries - 1;
+ get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd));
return ret;
}
-static void neigh_hash_free(struct neighbour **hash, unsigned int entries)
+static void neigh_hash_free_rcu(struct rcu_head *head)
{
- unsigned long size = entries * sizeof(struct neighbour *);
+ struct neigh_hash_table *nht = container_of(head,
+ struct neigh_hash_table,
+ rcu);
+ size_t size = (nht->hash_mask + 1) * sizeof(struct neighbour *);
+ struct neighbour **buckets = nht->hash_buckets;
if (size <= PAGE_SIZE)
- kfree(hash);
+ kfree(buckets);
else
- free_pages((unsigned long)hash, get_order(size));
+ free_pages((unsigned long)buckets, get_order(size));
+ kfree(nht);
}
-static void neigh_hash_grow(struct neigh_table *tbl, unsigned long new_entries)
+static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl,
+ unsigned long new_entries)
{
- struct neighbour **new_hash, **old_hash;
- unsigned int i, new_hash_mask, old_entries;
+ unsigned int i, hash;
+ struct neigh_hash_table *new_nht, *old_nht;
NEIGH_CACHE_STAT_INC(tbl, hash_grows);
BUG_ON(!is_power_of_2(new_entries));
- new_hash = neigh_hash_alloc(new_entries);
- if (!new_hash)
- return;
-
- old_entries = tbl->hash_mask + 1;
- new_hash_mask = new_entries - 1;
- old_hash = tbl->hash_buckets;
+ old_nht = rcu_dereference_protected(tbl->nht,
+ lockdep_is_held(&tbl->lock));
+ new_nht = neigh_hash_alloc(new_entries);
+ if (!new_nht)
+ return old_nht;
- get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd));
- for (i = 0; i < old_entries; i++) {
+ for (i = 0; i <= old_nht->hash_mask; i++) {
struct neighbour *n, *next;
- for (n = old_hash[i]; n; n = next) {
- unsigned int hash_val = tbl->hash(n->primary_key, n->dev);
-
- hash_val &= new_hash_mask;
- next = n->next;
-
- n->next = new_hash[hash_val];
- new_hash[hash_val] = n;
+ for (n = rcu_dereference_protected(old_nht->hash_buckets[i],
+ lockdep_is_held(&tbl->lock));
+ n != NULL;
+ n = next) {
+ hash = tbl->hash(n->primary_key, n->dev,
+ new_nht->hash_rnd);
+
+ hash &= new_nht->hash_mask;
+ next = rcu_dereference_protected(n->next,
+ lockdep_is_held(&tbl->lock));
+
+ rcu_assign_pointer(n->next,
+ rcu_dereference_protected(
+ new_nht->hash_buckets[hash],
+ lockdep_is_held(&tbl->lock)));
+ rcu_assign_pointer(new_nht->hash_buckets[hash], n);
}
}
- tbl->hash_buckets = new_hash;
- tbl->hash_mask = new_hash_mask;
- neigh_hash_free(old_hash, old_entries);
+ rcu_assign_pointer(tbl->nht, new_nht);
+ call_rcu(&old_nht->rcu, neigh_hash_free_rcu);
+ return new_nht;
}
struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
@@ -363,19 +401,26 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
struct neighbour *n;
int key_len = tbl->key_len;
u32 hash_val;
+ struct neigh_hash_table *nht;
NEIGH_CACHE_STAT_INC(tbl, lookups);
- read_lock_bh(&tbl->lock);
- hash_val = tbl->hash(pkey, dev);
- for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
+ rcu_read_lock_bh();
+ nht = rcu_dereference_bh(tbl->nht);
+ hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask;
+
+ for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
+ n != NULL;
+ n = rcu_dereference_bh(n->next)) {
if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) {
- neigh_hold(n);
+ if (!atomic_inc_not_zero(&n->refcnt))
+ n = NULL;
NEIGH_CACHE_STAT_INC(tbl, hits);
break;
}
}
- read_unlock_bh(&tbl->lock);
+
+ rcu_read_unlock_bh();
return n;
}
EXPORT_SYMBOL(neigh_lookup);
@@ -386,20 +431,27 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
struct neighbour *n;
int key_len = tbl->key_len;
u32 hash_val;
+ struct neigh_hash_table *nht;
NEIGH_CACHE_STAT_INC(tbl, lookups);
- read_lock_bh(&tbl->lock);
- hash_val = tbl->hash(pkey, NULL);
- for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
+ rcu_read_lock_bh();
+ nht = rcu_dereference_bh(tbl->nht);
+ hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) & nht->hash_mask;
+
+ for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
+ n != NULL;
+ n = rcu_dereference_bh(n->next)) {
if (!memcmp(n->primary_key, pkey, key_len) &&
net_eq(dev_net(n->dev), net)) {
- neigh_hold(n);
+ if (!atomic_inc_not_zero(&n->refcnt))
+ n = NULL;
NEIGH_CACHE_STAT_INC(tbl, hits);
break;
}
}
- read_unlock_bh(&tbl->lock);
+
+ rcu_read_unlock_bh();
return n;
}
EXPORT_SYMBOL(neigh_lookup_nodev);
@@ -411,6 +463,7 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey,
int key_len = tbl->key_len;
int error;
struct neighbour *n1, *rc, *n = neigh_alloc(tbl);
+ struct neigh_hash_table *nht;
if (!n) {
rc = ERR_PTR(-ENOBUFS);
@@ -437,18 +490,24 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey,
n->confirmed = jiffies - (n->parms->base_reachable_time << 1);
write_lock_bh(&tbl->lock);
+ nht = rcu_dereference_protected(tbl->nht,
+ lockdep_is_held(&tbl->lock));
- if (atomic_read(&tbl->entries) > (tbl->hash_mask + 1))
- neigh_hash_grow(tbl, (tbl->hash_mask + 1) << 1);
+ if (atomic_read(&tbl->entries) > (nht->hash_mask + 1))
+ nht = neigh_hash_grow(tbl, (nht->hash_mask + 1) << 1);
- hash_val = tbl->hash(pkey, dev) & tbl->hash_mask;
+ hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask;
if (n->parms->dead) {
rc = ERR_PTR(-EINVAL);
goto out_tbl_unlock;
}
- for (n1 = tbl->hash_buckets[hash_val]; n1; n1 = n1->next) {
+ for (n1 = rcu_dereference_protected(nht->hash_buckets[hash_val],
+ lockdep_is_held(&tbl->lock));
+ n1 != NULL;
+ n1 = rcu_dereference_protected(n1->next,
+ lockdep_is_held(&tbl->lock))) {
if (dev == n1->dev && !memcmp(n1->primary_key, pkey, key_len)) {
neigh_hold(n1);
rc = n1;
@@ -456,10 +515,12 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey,
}
}
- n->next = tbl->hash_buckets[hash_val];
- tbl->hash_buckets[hash_val] = n;
n->dead = 0;
neigh_hold(n);
+ rcu_assign_pointer(n->next,
+ rcu_dereference_protected(nht->hash_buckets[hash_val],
+ lockdep_is_held(&tbl->lock)));
+ rcu_assign_pointer(nht->hash_buckets[hash_val], n);
write_unlock_bh(&tbl->lock);
NEIGH_PRINTK2("neigh %p is created.\n", n);
rc = n;
@@ -616,6 +677,12 @@ static inline void neigh_parms_put(struct neigh_parms *parms)
neigh_parms_destroy(parms);
}
+static void neigh_destroy_rcu(struct rcu_head *head)
+{
+ struct neighbour *neigh = container_of(head, struct neighbour, rcu);
+
+ kmem_cache_free(neigh->tbl->kmem_cachep, neigh);
+}
/*
* neighbour must already be out of the table;
*
@@ -643,8 +710,7 @@ void neigh_destroy(struct neighbour *neigh)
write_seqlock_bh(&hh->hh_lock);
hh->hh_output = neigh_blackhole;
write_sequnlock_bh(&hh->hh_lock);
- if (atomic_dec_and_test(&hh->hh_refcnt))
- kfree(hh);
+ hh_cache_put(hh);
}
skb_queue_purge(&neigh->arp_queue);
@@ -655,7 +721,7 @@ void neigh_destroy(struct neighbour *neigh)
NEIGH_PRINTK2("neigh %p is destroyed.\n", neigh);
atomic_dec(&neigh->tbl->entries);
- kmem_cache_free(neigh->tbl->kmem_cachep, neigh);
+ call_rcu(&neigh->rcu, neigh_destroy_rcu);
}
EXPORT_SYMBOL(neigh_destroy);
@@ -696,12 +762,16 @@ static void neigh_connect(struct neighbour *neigh)
static void neigh_periodic_work(struct work_struct *work)
{
struct neigh_table *tbl = container_of(work, struct neigh_table, gc_work.work);
- struct neighbour *n, **np;
+ struct neighbour *n;
+ struct neighbour __rcu **np;
unsigned int i;
+ struct neigh_hash_table *nht;
NEIGH_CACHE_STAT_INC(tbl, periodic_gc_runs);
write_lock_bh(&tbl->lock);
+ nht = rcu_dereference_protected(tbl->nht,
+ lockdep_is_held(&tbl->lock));
/*
* periodically recompute ReachableTime from random function
@@ -715,10 +785,11 @@ static void neigh_periodic_work(struct work_struct *work)
neigh_rand_reach_time(p->base_reachable_time);
}
- for (i = 0 ; i <= tbl->hash_mask; i++) {
- np = &tbl->hash_buckets[i];
+ for (i = 0 ; i <= nht->hash_mask; i++) {
+ np = &nht->hash_buckets[i];
- while ((n = *np) != NULL) {
+ while ((n = rcu_dereference_protected(*np,
+ lockdep_is_held(&tbl->lock))) != NULL) {
unsigned int state;
write_lock(&n->lock);
@@ -766,9 +837,9 @@ next_elt:
static __inline__ int neigh_max_probes(struct neighbour *n)
{
struct neigh_parms *p = n->parms;
- return (n->nud_state & NUD_PROBE ?
+ return (n->nud_state & NUD_PROBE) ?
p->ucast_probes :
- p->ucast_probes + p->app_probes + p->mcast_probes);
+ p->ucast_probes + p->app_probes + p->mcast_probes;
}
static void neigh_invalidate(struct neighbour *neigh)
@@ -945,7 +1016,7 @@ out_unlock_bh:
}
EXPORT_SYMBOL(__neigh_event_send);
-static void neigh_update_hhs(struct neighbour *neigh)
+static void neigh_update_hhs(const struct neighbour *neigh)
{
struct hh_cache *hh;
void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *)
@@ -1081,7 +1152,9 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
}
if (lladdr != neigh->ha) {
+ write_seqlock(&neigh->ha_lock);
memcpy(&neigh->ha, lladdr, dev->addr_len);
+ write_sequnlock(&neigh->ha_lock);
neigh_update_hhs(neigh);
if (!(new & NUD_CONNECTED))
neigh->confirmed = jiffies -
@@ -1139,44 +1212,73 @@ struct neighbour *neigh_event_ns(struct neigh_table *tbl,
}
EXPORT_SYMBOL(neigh_event_ns);
+static inline bool neigh_hh_lookup(struct neighbour *n, struct dst_entry *dst,
+ __be16 protocol)
+{
+ struct hh_cache *hh;
+
+ smp_rmb(); /* paired with smp_wmb() in neigh_hh_init() */
+ for (hh = n->hh; hh; hh = hh->hh_next) {
+ if (hh->hh_type == protocol) {
+ atomic_inc(&hh->hh_refcnt);
+ if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL))
+ hh_cache_put(hh);
+ return true;
+ }
+ }
+ return false;
+}
+
+/* called with read_lock_bh(&n->lock); */
static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst,
__be16 protocol)
{
struct hh_cache *hh;
struct net_device *dev = dst->dev;
- for (hh = n->hh; hh; hh = hh->hh_next)
- if (hh->hh_type == protocol)
- break;
+ if (likely(neigh_hh_lookup(n, dst, protocol)))
+ return;
- if (!hh && (hh = kzalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) {
- seqlock_init(&hh->hh_lock);
- hh->hh_type = protocol;
- atomic_set(&hh->hh_refcnt, 0);
- hh->hh_next = NULL;
+ /* slow path */
+ hh = kzalloc(sizeof(*hh), GFP_ATOMIC);
+ if (!hh)
+ return;
- if (dev->header_ops->cache(n, hh)) {
- kfree(hh);
- hh = NULL;
- } else {
- atomic_inc(&hh->hh_refcnt);
- hh->hh_next = n->hh;
- n->hh = hh;
- if (n->nud_state & NUD_CONNECTED)
- hh->hh_output = n->ops->hh_output;
- else
- hh->hh_output = n->ops->output;
- }
+ seqlock_init(&hh->hh_lock);
+ hh->hh_type = protocol;
+ atomic_set(&hh->hh_refcnt, 2);
+
+ if (dev->header_ops->cache(n, hh)) {
+ kfree(hh);
+ return;
}
- if (hh) {
- atomic_inc(&hh->hh_refcnt);
- dst->hh = hh;
+
+ write_lock_bh(&n->lock);
+
+ /* must check if another thread already did the insert */
+ if (neigh_hh_lookup(n, dst, protocol)) {
+ kfree(hh);
+ goto end;
}
+
+ if (n->nud_state & NUD_CONNECTED)
+ hh->hh_output = n->ops->hh_output;
+ else
+ hh->hh_output = n->ops->output;
+
+ hh->hh_next = n->hh;
+ smp_wmb(); /* paired with smp_rmb() in neigh_hh_lookup() */
+ n->hh = hh;
+
+ if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL))
+ hh_cache_put(hh);
+end:
+ write_unlock_bh(&n->lock);
}
/* This function can be used in contexts, where only old dev_queue_xmit
- worked, f.e. if you want to override normal output path (eql, shaper),
- but resolution is not made yet.
+ * worked, f.e. if you want to override normal output path (eql, shaper),
+ * but resolution is not made yet.
*/
int neigh_compat_output(struct sk_buff *skb)
@@ -1210,19 +1312,19 @@ int neigh_resolve_output(struct sk_buff *skb)
if (!neigh_event_send(neigh, skb)) {
int err;
struct net_device *dev = neigh->dev;
- if (dev->header_ops->cache && !dst->hh) {
- write_lock_bh(&neigh->lock);
- if (!dst->hh)
- neigh_hh_init(neigh, dst, dst->ops->protocol);
- err = dev_hard_header(skb, dev, ntohs(skb->protocol),
- neigh->ha, NULL, skb->len);
- write_unlock_bh(&neigh->lock);
- } else {
- read_lock_bh(&neigh->lock);
+ unsigned int seq;
+
+ if (dev->header_ops->cache &&
+ !dst->hh &&
+ !(dst->flags & DST_NOCACHE))
+ neigh_hh_init(neigh, dst, dst->ops->protocol);
+
+ do {
+ seq = read_seqbegin(&neigh->ha_lock);
err = dev_hard_header(skb, dev, ntohs(skb->protocol),
neigh->ha, NULL, skb->len);
- read_unlock_bh(&neigh->lock);
- }
+ } while (read_seqretry(&neigh->ha_lock, seq));
+
if (err >= 0)
rc = neigh->ops->queue_xmit(skb);
else
@@ -1248,13 +1350,16 @@ int neigh_connected_output(struct sk_buff *skb)
struct dst_entry *dst = skb_dst(skb);
struct neighbour *neigh = dst->neighbour;
struct net_device *dev = neigh->dev;
+ unsigned int seq;
__skb_pull(skb, skb_network_offset(skb));
- read_lock_bh(&neigh->lock);
- err = dev_hard_header(skb, dev, ntohs(skb->protocol),
- neigh->ha, NULL, skb->len);
- read_unlock_bh(&neigh->lock);
+ do {
+ seq = read_seqbegin(&neigh->ha_lock);
+ err = dev_hard_header(skb, dev, ntohs(skb->protocol),
+ neigh->ha, NULL, skb->len);
+ } while (read_seqretry(&neigh->ha_lock, seq));
+
if (err >= 0)
err = neigh->ops->queue_xmit(skb);
else {
@@ -1436,17 +1541,14 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
panic("cannot create neighbour proc dir entry");
#endif
- tbl->hash_mask = 1;
- tbl->hash_buckets = neigh_hash_alloc(tbl->hash_mask + 1);
+ tbl->nht = neigh_hash_alloc(8);
phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *);
tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL);
- if (!tbl->hash_buckets || !tbl->phash_buckets)
+ if (!tbl->nht || !tbl->phash_buckets)
panic("cannot allocate neighbour cache hashes");
- get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd));
-
rwlock_init(&tbl->lock);
INIT_DELAYED_WORK_DEFERRABLE(&tbl->gc_work, neigh_periodic_work);
schedule_delayed_work(&tbl->gc_work, tbl->parms.reachable_time);
@@ -1486,8 +1588,7 @@ int neigh_table_clear(struct neigh_table *tbl)
struct neigh_table **tp;
/* It is not clean... Fix it to unload IPv6 module safely */
- cancel_delayed_work(&tbl->gc_work);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&tbl->gc_work);
del_timer_sync(&tbl->proxy_timer);
pneigh_queue_purge(&tbl->proxy_queue);
neigh_ifdown(tbl, NULL);
@@ -1502,8 +1603,8 @@ int neigh_table_clear(struct neigh_table *tbl)
}
write_unlock(&neigh_tbl_lock);
- neigh_hash_free(tbl->hash_buckets, tbl->hash_mask + 1);
- tbl->hash_buckets = NULL;
+ call_rcu(&tbl->nht->rcu, neigh_hash_free_rcu);
+ tbl->nht = NULL;
kfree(tbl->phash_buckets);
tbl->phash_buckets = NULL;
@@ -1529,6 +1630,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
struct net_device *dev = NULL;
int err = -EINVAL;
+ ASSERT_RTNL();
if (nlmsg_len(nlh) < sizeof(*ndm))
goto out;
@@ -1538,7 +1640,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
ndm = nlmsg_data(nlh);
if (ndm->ndm_ifindex) {
- dev = dev_get_by_index(net, ndm->ndm_ifindex);
+ dev = __dev_get_by_index(net, ndm->ndm_ifindex);
if (dev == NULL) {
err = -ENODEV;
goto out;
@@ -1554,34 +1656,31 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
read_unlock(&neigh_tbl_lock);
if (nla_len(dst_attr) < tbl->key_len)
- goto out_dev_put;
+ goto out;
if (ndm->ndm_flags & NTF_PROXY) {
err = pneigh_delete(tbl, net, nla_data(dst_attr), dev);
- goto out_dev_put;
+ goto out;
}
if (dev == NULL)
- goto out_dev_put;
+ goto out;
neigh = neigh_lookup(tbl, nla_data(dst_attr), dev);
if (neigh == NULL) {
err = -ENOENT;
- goto out_dev_put;
+ goto out;
}
err = neigh_update(neigh, NULL, NUD_FAILED,
NEIGH_UPDATE_F_OVERRIDE |
NEIGH_UPDATE_F_ADMIN);
neigh_release(neigh);
- goto out_dev_put;
+ goto out;
}
read_unlock(&neigh_tbl_lock);
err = -EAFNOSUPPORT;
-out_dev_put:
- if (dev)
- dev_put(dev);
out:
return err;
}
@@ -1595,6 +1694,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
struct net_device *dev = NULL;
int err;
+ ASSERT_RTNL();
err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
if (err < 0)
goto out;
@@ -1605,14 +1705,14 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
ndm = nlmsg_data(nlh);
if (ndm->ndm_ifindex) {
- dev = dev_get_by_index(net, ndm->ndm_ifindex);
+ dev = __dev_get_by_index(net, ndm->ndm_ifindex);
if (dev == NULL) {
err = -ENODEV;
goto out;
}
if (tb[NDA_LLADDR] && nla_len(tb[NDA_LLADDR]) < dev->addr_len)
- goto out_dev_put;
+ goto out;
}
read_lock(&neigh_tbl_lock);
@@ -1626,7 +1726,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
read_unlock(&neigh_tbl_lock);
if (nla_len(tb[NDA_DST]) < tbl->key_len)
- goto out_dev_put;
+ goto out;
dst = nla_data(tb[NDA_DST]);
lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL;
@@ -1639,29 +1739,29 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
pn->flags = ndm->ndm_flags;
err = 0;
}
- goto out_dev_put;
+ goto out;
}
if (dev == NULL)
- goto out_dev_put;
+ goto out;
neigh = neigh_lookup(tbl, dst, dev);
if (neigh == NULL) {
if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
err = -ENOENT;
- goto out_dev_put;
+ goto out;
}
neigh = __neigh_lookup_errno(tbl, dst, dev);
if (IS_ERR(neigh)) {
err = PTR_ERR(neigh);
- goto out_dev_put;
+ goto out;
}
} else {
if (nlh->nlmsg_flags & NLM_F_EXCL) {
err = -EEXIST;
neigh_release(neigh);
- goto out_dev_put;
+ goto out;
}
if (!(nlh->nlmsg_flags & NLM_F_REPLACE))
@@ -1674,15 +1774,11 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
} else
err = neigh_update(neigh, lladdr, ndm->ndm_state, flags);
neigh_release(neigh);
- goto out_dev_put;
+ goto out;
}
read_unlock(&neigh_tbl_lock);
err = -EAFNOSUPPORT;
-
-out_dev_put:
- if (dev)
- dev_put(dev);
out:
return err;
}
@@ -1748,18 +1844,22 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
unsigned long now = jiffies;
unsigned int flush_delta = now - tbl->last_flush;
unsigned int rand_delta = now - tbl->last_rand;
-
+ struct neigh_hash_table *nht;
struct ndt_config ndc = {
.ndtc_key_len = tbl->key_len,
.ndtc_entry_size = tbl->entry_size,
.ndtc_entries = atomic_read(&tbl->entries),
.ndtc_last_flush = jiffies_to_msecs(flush_delta),
.ndtc_last_rand = jiffies_to_msecs(rand_delta),
- .ndtc_hash_rnd = tbl->hash_rnd,
- .ndtc_hash_mask = tbl->hash_mask,
.ndtc_proxy_qlen = tbl->proxy_queue.qlen,
};
+ rcu_read_lock_bh();
+ nht = rcu_dereference_bh(tbl->nht);
+ ndc.ndtc_hash_rnd = nht->hash_rnd;
+ ndc.ndtc_hash_mask = nht->hash_mask;
+ rcu_read_unlock_bh();
+
NLA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc);
}
@@ -2056,10 +2156,14 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
read_lock_bh(&neigh->lock);
ndm->ndm_state = neigh->nud_state;
- if ((neigh->nud_state & NUD_VALID) &&
- nla_put(skb, NDA_LLADDR, neigh->dev->addr_len, neigh->ha) < 0) {
- read_unlock_bh(&neigh->lock);
- goto nla_put_failure;
+ if (neigh->nud_state & NUD_VALID) {
+ char haddr[MAX_ADDR_LEN];
+
+ neigh_ha_snapshot(haddr, neigh, neigh->dev);
+ if (nla_put(skb, NDA_LLADDR, neigh->dev->addr_len, haddr) < 0) {
+ read_unlock_bh(&neigh->lock);
+ goto nla_put_failure;
+ }
}
ci.ndm_used = jiffies_to_clock_t(now - neigh->used);
@@ -2087,18 +2191,23 @@ static void neigh_update_notify(struct neighbour *neigh)
static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
struct netlink_callback *cb)
{
- struct net * net = sock_net(skb->sk);
+ struct net *net = sock_net(skb->sk);
struct neighbour *n;
int rc, h, s_h = cb->args[1];
int idx, s_idx = idx = cb->args[2];
+ struct neigh_hash_table *nht;
- read_lock_bh(&tbl->lock);
- for (h = 0; h <= tbl->hash_mask; h++) {
+ rcu_read_lock_bh();
+ nht = rcu_dereference_bh(tbl->nht);
+
+ for (h = 0; h <= nht->hash_mask; h++) {
if (h < s_h)
continue;
if (h > s_h)
s_idx = 0;
- for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) {
+ for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0;
+ n != NULL;
+ n = rcu_dereference_bh(n->next)) {
if (!net_eq(dev_net(n->dev), net))
continue;
if (idx < s_idx)
@@ -2107,17 +2216,16 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
cb->nlh->nlmsg_seq,
RTM_NEWNEIGH,
NLM_F_MULTI) <= 0) {
- read_unlock_bh(&tbl->lock);
rc = -1;
goto out;
}
- next:
+next:
idx++;
}
}
- read_unlock_bh(&tbl->lock);
rc = skb->len;
out:
+ rcu_read_unlock_bh();
cb->args[1] = h;
cb->args[2] = idx;
return rc;
@@ -2150,15 +2258,22 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie)
{
int chain;
+ struct neigh_hash_table *nht;
- read_lock_bh(&tbl->lock);
- for (chain = 0; chain <= tbl->hash_mask; chain++) {
+ rcu_read_lock_bh();
+ nht = rcu_dereference_bh(tbl->nht);
+
+ read_lock(&tbl->lock); /* avoid resizes */
+ for (chain = 0; chain <= nht->hash_mask; chain++) {
struct neighbour *n;
- for (n = tbl->hash_buckets[chain]; n; n = n->next)
+ for (n = rcu_dereference_bh(nht->hash_buckets[chain]);
+ n != NULL;
+ n = rcu_dereference_bh(n->next))
cb(n, cookie);
}
- read_unlock_bh(&tbl->lock);
+ read_unlock(&tbl->lock);
+ rcu_read_unlock_bh();
}
EXPORT_SYMBOL(neigh_for_each);
@@ -2167,18 +2282,25 @@ void __neigh_for_each_release(struct neigh_table *tbl,
int (*cb)(struct neighbour *))
{
int chain;
+ struct neigh_hash_table *nht;
- for (chain = 0; chain <= tbl->hash_mask; chain++) {
- struct neighbour *n, **np;
+ nht = rcu_dereference_protected(tbl->nht,
+ lockdep_is_held(&tbl->lock));
+ for (chain = 0; chain <= nht->hash_mask; chain++) {
+ struct neighbour *n;
+ struct neighbour __rcu **np;
- np = &tbl->hash_buckets[chain];
- while ((n = *np) != NULL) {
+ np = &nht->hash_buckets[chain];
+ while ((n = rcu_dereference_protected(*np,
+ lockdep_is_held(&tbl->lock))) != NULL) {
int release;
write_lock(&n->lock);
release = cb(n);
if (release) {
- *np = n->next;
+ rcu_assign_pointer(*np,
+ rcu_dereference_protected(n->next,
+ lockdep_is_held(&tbl->lock)));
n->dead = 1;
} else
np = &n->next;
@@ -2196,13 +2318,13 @@ static struct neighbour *neigh_get_first(struct seq_file *seq)
{
struct neigh_seq_state *state = seq->private;
struct net *net = seq_file_net(seq);
- struct neigh_table *tbl = state->tbl;
+ struct neigh_hash_table *nht = state->nht;
struct neighbour *n = NULL;
int bucket = state->bucket;
state->flags &= ~NEIGH_SEQ_IS_PNEIGH;
- for (bucket = 0; bucket <= tbl->hash_mask; bucket++) {
- n = tbl->hash_buckets[bucket];
+ for (bucket = 0; bucket <= nht->hash_mask; bucket++) {
+ n = rcu_dereference_bh(nht->hash_buckets[bucket]);
while (n) {
if (!net_eq(dev_net(n->dev), net))
@@ -2219,8 +2341,8 @@ static struct neighbour *neigh_get_first(struct seq_file *seq)
break;
if (n->nud_state & ~NUD_NOARP)
break;
- next:
- n = n->next;
+next:
+ n = rcu_dereference_bh(n->next);
}
if (n)
@@ -2237,14 +2359,14 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
{
struct neigh_seq_state *state = seq->private;
struct net *net = seq_file_net(seq);
- struct neigh_table *tbl = state->tbl;
+ struct neigh_hash_table *nht = state->nht;
if (state->neigh_sub_iter) {
void *v = state->neigh_sub_iter(state, n, pos);
if (v)
return n;
}
- n = n->next;
+ n = rcu_dereference_bh(n->next);
while (1) {
while (n) {
@@ -2261,17 +2383,17 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
if (n->nud_state & ~NUD_NOARP)
break;
- next:
- n = n->next;
+next:
+ n = rcu_dereference_bh(n->next);
}
if (n)
break;
- if (++state->bucket > tbl->hash_mask)
+ if (++state->bucket > nht->hash_mask)
break;
- n = tbl->hash_buckets[state->bucket];
+ n = rcu_dereference_bh(nht->hash_buckets[state->bucket]);
}
if (n && pos)
@@ -2369,7 +2491,7 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
}
void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags)
- __acquires(tbl->lock)
+ __acquires(rcu_bh)
{
struct neigh_seq_state *state = seq->private;
@@ -2377,7 +2499,8 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
state->bucket = 0;
state->flags = (neigh_seq_flags & ~NEIGH_SEQ_IS_PNEIGH);
- read_lock_bh(&tbl->lock);
+ rcu_read_lock_bh();
+ state->nht = rcu_dereference_bh(tbl->nht);
return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN;
}
@@ -2411,12 +2534,9 @@ out:
EXPORT_SYMBOL(neigh_seq_next);
void neigh_seq_stop(struct seq_file *seq, void *v)
- __releases(tbl->lock)
+ __releases(rcu_bh)
{
- struct neigh_seq_state *state = seq->private;
- struct neigh_table *tbl = state->tbl;
-
- read_unlock_bh(&tbl->lock);
+ rcu_read_unlock_bh();
}
EXPORT_SYMBOL(neigh_seq_stop);
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index af4dfbadf2a0..b143173e3eb2 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -515,7 +515,7 @@ static ssize_t rx_queue_attr_store(struct kobject *kobj, struct attribute *attr,
return attribute->store(queue, attribute, buf, count);
}
-static struct sysfs_ops rx_queue_sysfs_ops = {
+static const struct sysfs_ops rx_queue_sysfs_ops = {
.show = rx_queue_attr_show,
.store = rx_queue_attr_store,
};
@@ -726,6 +726,7 @@ static struct kobj_type rx_queue_ktype = {
static int rx_queue_add_kobject(struct net_device *net, int index)
{
struct netdev_rx_queue *queue = net->_rx + index;
+ struct netdev_rx_queue *first = queue->first;
struct kobject *kobj = &queue->kobj;
int error = 0;
@@ -738,38 +739,43 @@ static int rx_queue_add_kobject(struct net_device *net, int index)
}
kobject_uevent(kobj, KOBJ_ADD);
+ atomic_inc(&first->count);
return error;
}
-static int rx_queue_register_kobjects(struct net_device *net)
+int
+net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num)
{
int i;
int error = 0;
- net->queues_kset = kset_create_and_add("queues",
- NULL, &net->dev.kobj);
- if (!net->queues_kset)
- return -ENOMEM;
- for (i = 0; i < net->num_rx_queues; i++) {
+ for (i = old_num; i < new_num; i++) {
error = rx_queue_add_kobject(net, i);
- if (error)
+ if (error) {
+ new_num = old_num;
break;
+ }
}
- if (error)
- while (--i >= 0)
- kobject_put(&net->_rx[i].kobj);
+ while (--i >= new_num)
+ kobject_put(&net->_rx[i].kobj);
return error;
}
-static void rx_queue_remove_kobjects(struct net_device *net)
+static int rx_queue_register_kobjects(struct net_device *net)
{
- int i;
+ net->queues_kset = kset_create_and_add("queues",
+ NULL, &net->dev.kobj);
+ if (!net->queues_kset)
+ return -ENOMEM;
+ return net_rx_queue_update_kobjects(net, 0, net->real_num_rx_queues);
+}
- for (i = 0; i < net->num_rx_queues; i++)
- kobject_put(&net->_rx[i].kobj);
+static void rx_queue_remove_kobjects(struct net_device *net)
+{
+ net_rx_queue_update_kobjects(net, net->real_num_rx_queues, 0);
kset_unregister(net->queues_kset);
}
#endif /* CONFIG_RPS */
@@ -789,12 +795,13 @@ static const void *net_netlink_ns(struct sock *sk)
return sock_net(sk);
}
-static struct kobj_ns_type_operations net_ns_type_operations = {
+struct kobj_ns_type_operations net_ns_type_operations = {
.type = KOBJ_NS_TYPE_NET,
.current_ns = net_current_ns,
.netlink_ns = net_netlink_ns,
.initial_ns = net_initial_ns,
};
+EXPORT_SYMBOL_GPL(net_ns_type_operations);
static void net_kobj_ns_exit(struct net *net)
{
diff --git a/net/core/net-sysfs.h b/net/core/net-sysfs.h
index 805555e8b187..778e1571548d 100644
--- a/net/core/net-sysfs.h
+++ b/net/core/net-sysfs.h
@@ -4,4 +4,8 @@
int netdev_kobject_init(void);
int netdev_register_kobject(struct net_device *);
void netdev_unregister_kobject(struct net_device *);
+#ifdef CONFIG_RPS
+int net_rx_queue_update_kobjects(struct net_device *, int old_num, int new_num);
+#endif
+
#endif
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 537e01afd81b..4e98ffac3af0 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -288,11 +288,11 @@ static int netpoll_owner_active(struct net_device *dev)
return 0;
}
-void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
+void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
+ struct net_device *dev)
{
int status = NETDEV_TX_BUSY;
unsigned long tries;
- struct net_device *dev = np->dev;
const struct net_device_ops *ops = dev->netdev_ops;
/* It is up to the caller to keep npinfo alive. */
struct netpoll_info *npinfo = np->dev->npinfo;
@@ -346,7 +346,7 @@ void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
schedule_delayed_work(&npinfo->tx_work,0);
}
}
-EXPORT_SYMBOL(netpoll_send_skb);
+EXPORT_SYMBOL(netpoll_send_skb_on_dev);
void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
{
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 10a1ea72010d..2c0df0f95b3d 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -729,16 +729,14 @@ static int hex32_arg(const char __user *user_buffer, unsigned long maxlen,
*num = 0;
for (; i < maxlen; i++) {
+ int value;
char c;
*num <<= 4;
if (get_user(c, &user_buffer[i]))
return -EFAULT;
- if ((c >= '0') && (c <= '9'))
- *num |= c - '0';
- else if ((c >= 'a') && (c <= 'f'))
- *num |= c - 'a' + 10;
- else if ((c >= 'A') && (c <= 'F'))
- *num |= c - 'A' + 10;
+ value = hex_to_bin(c);
+ if (value >= 0)
+ *num |= value;
else
break;
}
@@ -3907,8 +3905,6 @@ static void __exit pg_cleanup(void)
{
struct pktgen_thread *t;
struct list_head *q, *n;
- wait_queue_head_t queue;
- init_waitqueue_head(&queue);
/* Stop all interfaces & threads */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f78d821bd935..8121268ddbdd 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -299,14 +299,6 @@ static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops)
unregister_netdevice_many(&list_kill);
}
-void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops)
-{
- rtnl_lock();
- __rtnl_kill_links(net, ops);
- rtnl_unlock();
-}
-EXPORT_SYMBOL_GPL(rtnl_kill_links);
-
/**
* __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
* @ops: struct rtnl_link_ops * to unregister
@@ -612,36 +604,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b)
{
- struct rtnl_link_stats64 a;
-
- a.rx_packets = b->rx_packets;
- a.tx_packets = b->tx_packets;
- a.rx_bytes = b->rx_bytes;
- a.tx_bytes = b->tx_bytes;
- a.rx_errors = b->rx_errors;
- a.tx_errors = b->tx_errors;
- a.rx_dropped = b->rx_dropped;
- a.tx_dropped = b->tx_dropped;
-
- a.multicast = b->multicast;
- a.collisions = b->collisions;
-
- a.rx_length_errors = b->rx_length_errors;
- a.rx_over_errors = b->rx_over_errors;
- a.rx_crc_errors = b->rx_crc_errors;
- a.rx_frame_errors = b->rx_frame_errors;
- a.rx_fifo_errors = b->rx_fifo_errors;
- a.rx_missed_errors = b->rx_missed_errors;
-
- a.tx_aborted_errors = b->tx_aborted_errors;
- a.tx_carrier_errors = b->tx_carrier_errors;
- a.tx_fifo_errors = b->tx_fifo_errors;
- a.tx_heartbeat_errors = b->tx_heartbeat_errors;
- a.tx_window_errors = b->tx_window_errors;
-
- a.rx_compressed = b->rx_compressed;
- a.tx_compressed = b->tx_compressed;
- memcpy(v, &a, sizeof(a));
+ memcpy(v, b, sizeof(*b));
}
/* All VF info */
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 56ba3c4e4761..104f8444754a 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -202,8 +202,6 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
skb->data = data;
skb_reset_tail_pointer(skb);
skb->end = skb->tail + size;
- kmemcheck_annotate_bitfield(skb, flags1);
- kmemcheck_annotate_bitfield(skb, flags2);
#ifdef NET_SKBUFF_DATA_USES_OFFSET
skb->mac_header = ~0U;
#endif
@@ -249,10 +247,9 @@ EXPORT_SYMBOL(__alloc_skb);
struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
unsigned int length, gfp_t gfp_mask)
{
- int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
struct sk_buff *skb;
- skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node);
+ skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE);
if (likely(skb)) {
skb_reserve(skb, NET_SKB_PAD);
skb->dev = dev;
@@ -261,16 +258,6 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
}
EXPORT_SYMBOL(__netdev_alloc_skb);
-struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask)
-{
- int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
- struct page *page;
-
- page = alloc_pages_node(node, gfp_mask, 0);
- return page;
-}
-EXPORT_SYMBOL(__netdev_alloc_page);
-
void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
int size)
{
@@ -340,7 +327,7 @@ static void skb_release_data(struct sk_buff *skb)
put_page(skb_shinfo(skb)->frags[i].page);
}
- if (skb_has_frags(skb))
+ if (skb_has_frag_list(skb))
skb_drop_fraglist(skb);
kfree(skb->head);
@@ -686,16 +673,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
{
- int headerlen = skb->data - skb->head;
- /*
- * Allocate the copy buffer
- */
- struct sk_buff *n;
-#ifdef NET_SKBUFF_DATA_USES_OFFSET
- n = alloc_skb(skb->end + skb->data_len, gfp_mask);
-#else
- n = alloc_skb(skb->end - skb->head + skb->data_len, gfp_mask);
-#endif
+ int headerlen = skb_headroom(skb);
+ unsigned int size = (skb_end_pointer(skb) - skb->head) + skb->data_len;
+ struct sk_buff *n = alloc_skb(size, gfp_mask);
+
if (!n)
return NULL;
@@ -727,20 +708,14 @@ EXPORT_SYMBOL(skb_copy);
struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
{
- /*
- * Allocate the copy buffer
- */
- struct sk_buff *n;
-#ifdef NET_SKBUFF_DATA_USES_OFFSET
- n = alloc_skb(skb->end, gfp_mask);
-#else
- n = alloc_skb(skb->end - skb->head, gfp_mask);
-#endif
+ unsigned int size = skb_end_pointer(skb) - skb->head;
+ struct sk_buff *n = alloc_skb(size, gfp_mask);
+
if (!n)
goto out;
/* Set the data pointer */
- skb_reserve(n, skb->data - skb->head);
+ skb_reserve(n, skb_headroom(skb));
/* Set the tail pointer and length */
skb_put(n, skb_headlen(skb));
/* Copy the bytes */
@@ -760,7 +735,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
skb_shinfo(n)->nr_frags = i;
}
- if (skb_has_frags(skb)) {
+ if (skb_has_frag_list(skb)) {
skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list;
skb_clone_fraglist(n);
}
@@ -792,12 +767,9 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
{
int i;
u8 *data;
-#ifdef NET_SKBUFF_DATA_USES_OFFSET
- int size = nhead + skb->end + ntail;
-#else
- int size = nhead + (skb->end - skb->head) + ntail;
-#endif
+ int size = nhead + (skb_end_pointer(skb) - skb->head) + ntail;
long off;
+ bool fastpath;
BUG_ON(nhead < 0);
@@ -811,23 +783,36 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
goto nodata;
/* Copy only real data... and, alas, header. This should be
- * optimized for the cases when header is void. */
-#ifdef NET_SKBUFF_DATA_USES_OFFSET
- memcpy(data + nhead, skb->head, skb->tail);
-#else
- memcpy(data + nhead, skb->head, skb->tail - skb->head);
-#endif
- memcpy(data + size, skb_end_pointer(skb),
+ * optimized for the cases when header is void.
+ */
+ memcpy(data + nhead, skb->head, skb_tail_pointer(skb) - skb->head);
+
+ memcpy((struct skb_shared_info *)(data + size),
+ skb_shinfo(skb),
offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags]));
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
- get_page(skb_shinfo(skb)->frags[i].page);
+ /* Check if we can avoid taking references on fragments if we own
+ * the last reference on skb->head. (see skb_release_data())
+ */
+ if (!skb->cloned)
+ fastpath = true;
+ else {
+ int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1;
- if (skb_has_frags(skb))
- skb_clone_fraglist(skb);
+ fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta;
+ }
- skb_release_data(skb);
+ if (fastpath) {
+ kfree(skb->head);
+ } else {
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+ get_page(skb_shinfo(skb)->frags[i].page);
+ if (skb_has_frag_list(skb))
+ skb_clone_fraglist(skb);
+
+ skb_release_data(skb);
+ }
off = (data + nhead) - skb->head;
skb->head = data;
@@ -1100,7 +1085,7 @@ drop_pages:
for (; i < nfrags; i++)
put_page(skb_shinfo(skb)->frags[i].page);
- if (skb_has_frags(skb))
+ if (skb_has_frag_list(skb))
skb_drop_fraglist(skb);
goto done;
}
@@ -1195,7 +1180,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta)
/* Optimization: no fragments, no reasons to preestimate
* size of pulled pages. Superb.
*/
- if (!skb_has_frags(skb))
+ if (!skb_has_frag_list(skb))
goto pull_pages;
/* Estimate size of pulled pages. */
@@ -2324,7 +2309,7 @@ next_skb:
st->frag_data = NULL;
}
- if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) {
+ if (st->root_skb == st->cur_skb && skb_has_frag_list(st->root_skb)) {
st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
st->frag_idx = 0;
goto next_skb;
@@ -2894,7 +2879,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
return -ENOMEM;
/* Easy case. Most of packets will go this way. */
- if (!skb_has_frags(skb)) {
+ if (!skb_has_frag_list(skb)) {
/* A little of trouble, not enough of space for trailer.
* This should not happen, when stack is tuned to generate
* good frames. OK, on miss we reallocate and reserve even more
@@ -2929,7 +2914,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
if (skb1->next == NULL && tailbits) {
if (skb_shinfo(skb1)->nr_frags ||
- skb_has_frags(skb1) ||
+ skb_has_frag_list(skb1) ||
skb_tailroom(skb1) < tailbits)
ntail = tailbits + 128;
}
@@ -2938,7 +2923,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
skb_cloned(skb1) ||
ntail ||
skb_shinfo(skb1)->nr_frags ||
- skb_has_frags(skb1)) {
+ skb_has_frag_list(skb1)) {
struct sk_buff *skb2;
/* Fuck, we are miserable poor guys... */
@@ -3021,7 +3006,7 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
} else {
/*
* no hardware time stamps available,
- * so keep the skb_shared_tx and only
+ * so keep the shared tx_flags and only
* store software time stamp
*/
skb->tstamp = ktime_get_real();
diff --git a/net/core/sock.c b/net/core/sock.c
index 7d99e13148e6..11db43632df8 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1560,6 +1560,8 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size,
EXPORT_SYMBOL(sock_alloc_send_skb);
static void __lock_sock(struct sock *sk)
+ __releases(&sk->sk_lock.slock)
+ __acquires(&sk->sk_lock.slock)
{
DEFINE_WAIT(wait);
@@ -1576,6 +1578,8 @@ static void __lock_sock(struct sock *sk)
}
static void __release_sock(struct sock *sk)
+ __releases(&sk->sk_lock.slock)
+ __acquires(&sk->sk_lock.slock)
{
struct sk_buff *skb = sk->sk_backlog.head;
diff --git a/net/core/utils.c b/net/core/utils.c
index f41854470539..5fea0ab21902 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -75,7 +75,7 @@ __be32 in_aton(const char *str)
str++;
}
}
- return(htonl(l));
+ return htonl(l);
}
EXPORT_SYMBOL(in_aton);
@@ -92,18 +92,19 @@ EXPORT_SYMBOL(in_aton);
static inline int xdigit2bin(char c, int delim)
{
+ int val;
+
if (c == delim || c == '\0')
return IN6PTON_DELIM;
if (c == ':')
return IN6PTON_COLON_MASK;
if (c == '.')
return IN6PTON_DOT;
- if (c >= '0' && c <= '9')
- return (IN6PTON_XDIGIT | IN6PTON_DIGIT| (c - '0'));
- if (c >= 'a' && c <= 'f')
- return (IN6PTON_XDIGIT | (c - 'a' + 10));
- if (c >= 'A' && c <= 'F')
- return (IN6PTON_XDIGIT | (c - 'A' + 10));
+
+ val = hex_to_bin(c);
+ if (val >= 0)
+ return val | IN6PTON_XDIGIT | (val < 10 ? IN6PTON_DIGIT : 0);
+
if (delim == -1)
return IN6PTON_DELIM;
return IN6PTON_UNKNOWN;
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index 6df6f8ac9636..117fb093dcaf 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -62,22 +62,18 @@ struct ccid_operations {
void (*ccid_hc_tx_exit)(struct sock *sk);
void (*ccid_hc_rx_packet_recv)(struct sock *sk,
struct sk_buff *skb);
- int (*ccid_hc_rx_parse_options)(struct sock *sk,
- unsigned char option,
- unsigned char len, u16 idx,
- unsigned char* value);
+ int (*ccid_hc_rx_parse_options)(struct sock *sk, u8 pkt,
+ u8 opt, u8 *val, u8 len);
int (*ccid_hc_rx_insert_options)(struct sock *sk,
struct sk_buff *skb);
void (*ccid_hc_tx_packet_recv)(struct sock *sk,
struct sk_buff *skb);
- int (*ccid_hc_tx_parse_options)(struct sock *sk,
- unsigned char option,
- unsigned char len, u16 idx,
- unsigned char* value);
+ int (*ccid_hc_tx_parse_options)(struct sock *sk, u8 pkt,
+ u8 opt, u8 *val, u8 len);
int (*ccid_hc_tx_send_packet)(struct sock *sk,
struct sk_buff *skb);
void (*ccid_hc_tx_packet_sent)(struct sock *sk,
- int more, unsigned int len);
+ unsigned int len);
void (*ccid_hc_rx_get_info)(struct sock *sk,
struct tcp_info *info);
void (*ccid_hc_tx_get_info)(struct sock *sk,
@@ -148,10 +144,10 @@ static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk,
}
static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk,
- int more, unsigned int len)
+ unsigned int len)
{
if (ccid->ccid_ops->ccid_hc_tx_packet_sent != NULL)
- ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, more, len);
+ ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, len);
}
static inline void ccid_hc_rx_packet_recv(struct ccid *ccid, struct sock *sk,
@@ -168,27 +164,31 @@ static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk,
ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb);
}
+/**
+ * ccid_hc_tx_parse_options - Parse CCID-specific options sent by the receiver
+ * @pkt: type of packet that @opt appears on (RFC 4340, 5.1)
+ * @opt: the CCID-specific option type (RFC 4340, 5.8 and 10.3)
+ * @val: value of @opt
+ * @len: length of @val in bytes
+ */
static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk,
- unsigned char option,
- unsigned char len, u16 idx,
- unsigned char* value)
+ u8 pkt, u8 opt, u8 *val, u8 len)
{
- int rc = 0;
- if (ccid->ccid_ops->ccid_hc_tx_parse_options != NULL)
- rc = ccid->ccid_ops->ccid_hc_tx_parse_options(sk, option, len, idx,
- value);
- return rc;
+ if (ccid->ccid_ops->ccid_hc_tx_parse_options == NULL)
+ return 0;
+ return ccid->ccid_ops->ccid_hc_tx_parse_options(sk, pkt, opt, val, len);
}
+/**
+ * ccid_hc_rx_parse_options - Parse CCID-specific options sent by the sender
+ * Arguments are analogous to ccid_hc_tx_parse_options()
+ */
static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk,
- unsigned char option,
- unsigned char len, u16 idx,
- unsigned char* value)
+ u8 pkt, u8 opt, u8 *val, u8 len)
{
- int rc = 0;
- if (ccid->ccid_ops->ccid_hc_rx_parse_options != NULL)
- rc = ccid->ccid_ops->ccid_hc_rx_parse_options(sk, option, len, idx, value);
- return rc;
+ if (ccid->ccid_ops->ccid_hc_rx_parse_options == NULL)
+ return 0;
+ return ccid->ccid_ops->ccid_hc_rx_parse_options(sk, pkt, opt, val, len);
}
static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk,
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 8408398cd44e..0581143cb800 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -47,37 +47,6 @@ config IP_DCCP_CCID3_DEBUG
If in doubt, say N.
-config IP_DCCP_CCID3_RTO
- int "Use higher bound for nofeedback timer"
- default 100
- depends on IP_DCCP_CCID3 && EXPERIMENTAL
- ---help---
- Use higher lower bound for nofeedback timer expiration.
-
- The TFRC nofeedback timer normally expires after the maximum of 4
- RTTs and twice the current send interval (RFC 3448, 4.3). On LANs
- with a small RTT this can mean a high processing load and reduced
- performance, since then the nofeedback timer is triggered very
- frequently.
-
- This option enables to set a higher lower bound for the nofeedback
- value. Values in units of milliseconds can be set here.
-
- A value of 0 disables this feature by enforcing the value specified
- in RFC 3448. The following values have been suggested as bounds for
- experimental use:
- * 16-20ms to match the typical multimedia inter-frame interval
- * 100ms as a reasonable compromise [default]
- * 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4)
-
- The default of 100ms is a compromise between a large value for
- efficient DCCP implementations, and a small value to avoid disrupting
- the network in times of congestion.
-
- The purpose of the nofeedback timer is to slow DCCP down when there
- is serious network congestion: experimenting with larger values should
- therefore not be performed on WANs.
-
config IP_DCCP_TFRC_LIB
def_bool y if IP_DCCP_CCID3
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 9b3ae9922be1..d850e291f87c 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -25,59 +25,14 @@
*/
#include <linux/slab.h>
#include "../feat.h"
-#include "../ccid.h"
-#include "../dccp.h"
#include "ccid2.h"
#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
static int ccid2_debug;
#define ccid2_pr_debug(format, a...) DCCP_PR_DEBUG(ccid2_debug, format, ##a)
-
-static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hc)
-{
- int len = 0;
- int pipe = 0;
- struct ccid2_seq *seqp = hc->tx_seqh;
-
- /* there is data in the chain */
- if (seqp != hc->tx_seqt) {
- seqp = seqp->ccid2s_prev;
- len++;
- if (!seqp->ccid2s_acked)
- pipe++;
-
- while (seqp != hc->tx_seqt) {
- struct ccid2_seq *prev = seqp->ccid2s_prev;
-
- len++;
- if (!prev->ccid2s_acked)
- pipe++;
-
- /* packets are sent sequentially */
- BUG_ON(dccp_delta_seqno(seqp->ccid2s_seq,
- prev->ccid2s_seq ) >= 0);
- BUG_ON(time_before(seqp->ccid2s_sent,
- prev->ccid2s_sent));
-
- seqp = prev;
- }
- }
-
- BUG_ON(pipe != hc->tx_pipe);
- ccid2_pr_debug("len of chain=%d\n", len);
-
- do {
- seqp = seqp->ccid2s_prev;
- len++;
- } while (seqp != hc->tx_seqh);
-
- ccid2_pr_debug("total len=%d\n", len);
- BUG_ON(len != hc->tx_seqbufc * CCID2_SEQBUF_LEN);
-}
#else
#define ccid2_pr_debug(format, a...)
-#define ccid2_hc_tx_check_sanity(hc)
#endif
static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hc)
@@ -156,19 +111,10 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
dp->dccps_l_ack_ratio = val;
}
-static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hc, long val)
-{
- ccid2_pr_debug("change SRTT to %ld\n", val);
- hc->tx_srtt = val;
-}
-
-static void ccid2_start_rto_timer(struct sock *sk);
-
static void ccid2_hc_tx_rto_expire(unsigned long data)
{
struct sock *sk = (struct sock *)data;
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
- long s;
bh_lock_sock(sk);
if (sock_owned_by_user(sk)) {
@@ -178,23 +124,19 @@ static void ccid2_hc_tx_rto_expire(unsigned long data)
ccid2_pr_debug("RTO_EXPIRE\n");
- ccid2_hc_tx_check_sanity(hc);
-
/* back-off timer */
hc->tx_rto <<= 1;
+ if (hc->tx_rto > DCCP_RTO_MAX)
+ hc->tx_rto = DCCP_RTO_MAX;
- s = hc->tx_rto / HZ;
- if (s > 60)
- hc->tx_rto = 60 * HZ;
-
- ccid2_start_rto_timer(sk);
+ sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
/* adjust pipe, cwnd etc */
hc->tx_ssthresh = hc->tx_cwnd / 2;
if (hc->tx_ssthresh < 2)
hc->tx_ssthresh = 2;
- hc->tx_cwnd = 1;
- hc->tx_pipe = 0;
+ hc->tx_cwnd = 1;
+ hc->tx_pipe = 0;
/* clear state about stuff we sent */
hc->tx_seqt = hc->tx_seqh;
@@ -204,23 +146,12 @@ static void ccid2_hc_tx_rto_expire(unsigned long data)
hc->tx_rpseq = 0;
hc->tx_rpdupack = -1;
ccid2_change_l_ack_ratio(sk, 1);
- ccid2_hc_tx_check_sanity(hc);
out:
bh_unlock_sock(sk);
sock_put(sk);
}
-static void ccid2_start_rto_timer(struct sock *sk)
-{
- struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
-
- ccid2_pr_debug("setting RTO timeout=%ld\n", hc->tx_rto);
-
- BUG_ON(timer_pending(&hc->tx_rtotimer));
- sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
-}
-
-static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
+static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len)
{
struct dccp_sock *dp = dccp_sk(sk);
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
@@ -230,7 +161,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
hc->tx_seqh->ccid2s_seq = dp->dccps_gss;
hc->tx_seqh->ccid2s_acked = 0;
- hc->tx_seqh->ccid2s_sent = jiffies;
+ hc->tx_seqh->ccid2s_sent = ccid2_time_stamp;
next = hc->tx_seqh->ccid2s_next;
/* check if we need to alloc more space */
@@ -296,23 +227,20 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
}
#endif
- /* setup RTO timer */
- if (!timer_pending(&hc->tx_rtotimer))
- ccid2_start_rto_timer(sk);
+ sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
do {
struct ccid2_seq *seqp = hc->tx_seqt;
while (seqp != hc->tx_seqh) {
- ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n",
+ ccid2_pr_debug("out seq=%llu acked=%d time=%u\n",
(unsigned long long)seqp->ccid2s_seq,
seqp->ccid2s_acked, seqp->ccid2s_sent);
seqp = seqp->ccid2s_next;
}
} while (0);
ccid2_pr_debug("=========\n");
- ccid2_hc_tx_check_sanity(hc);
#endif
}
@@ -378,17 +306,87 @@ out_invalid_option:
return -1;
}
-static void ccid2_hc_tx_kill_rto_timer(struct sock *sk)
+/**
+ * ccid2_rtt_estimator - Sample RTT and compute RTO using RFC2988 algorithm
+ * This code is almost identical with TCP's tcp_rtt_estimator(), since
+ * - it has a higher sampling frequency (recommended by RFC 1323),
+ * - the RTO does not collapse into RTT due to RTTVAR going towards zero,
+ * - it is simple (cf. more complex proposals such as Eifel timer or research
+ * which suggests that the gain should be set according to window size),
+ * - in tests it was found to work well with CCID2 [gerrit].
+ */
+static void ccid2_rtt_estimator(struct sock *sk, const long mrtt)
{
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
+ long m = mrtt ? : 1;
- sk_stop_timer(sk, &hc->tx_rtotimer);
- ccid2_pr_debug("deleted RTO timer\n");
+ if (hc->tx_srtt == 0) {
+ /* First measurement m */
+ hc->tx_srtt = m << 3;
+ hc->tx_mdev = m << 1;
+
+ hc->tx_mdev_max = max(hc->tx_mdev, tcp_rto_min(sk));
+ hc->tx_rttvar = hc->tx_mdev_max;
+
+ hc->tx_rtt_seq = dccp_sk(sk)->dccps_gss;
+ } else {
+ /* Update scaled SRTT as SRTT += 1/8 * (m - SRTT) */
+ m -= (hc->tx_srtt >> 3);
+ hc->tx_srtt += m;
+
+ /* Similarly, update scaled mdev with regard to |m| */
+ if (m < 0) {
+ m = -m;
+ m -= (hc->tx_mdev >> 2);
+ /*
+ * This neutralises RTO increase when RTT < SRTT - mdev
+ * (see P. Sarolahti, A. Kuznetsov,"Congestion Control
+ * in Linux TCP", USENIX 2002, pp. 49-62).
+ */
+ if (m > 0)
+ m >>= 3;
+ } else {
+ m -= (hc->tx_mdev >> 2);
+ }
+ hc->tx_mdev += m;
+
+ if (hc->tx_mdev > hc->tx_mdev_max) {
+ hc->tx_mdev_max = hc->tx_mdev;
+ if (hc->tx_mdev_max > hc->tx_rttvar)
+ hc->tx_rttvar = hc->tx_mdev_max;
+ }
+
+ /*
+ * Decay RTTVAR at most once per flight, exploiting that
+ * 1) pipe <= cwnd <= Sequence_Window = W (RFC 4340, 7.5.2)
+ * 2) AWL = GSS-W+1 <= GAR <= GSS (RFC 4340, 7.5.1)
+ * GAR is a useful bound for FlightSize = pipe.
+ * AWL is probably too low here, as it over-estimates pipe.
+ */
+ if (after48(dccp_sk(sk)->dccps_gar, hc->tx_rtt_seq)) {
+ if (hc->tx_mdev_max < hc->tx_rttvar)
+ hc->tx_rttvar -= (hc->tx_rttvar -
+ hc->tx_mdev_max) >> 2;
+ hc->tx_rtt_seq = dccp_sk(sk)->dccps_gss;
+ hc->tx_mdev_max = tcp_rto_min(sk);
+ }
+ }
+
+ /*
+ * Set RTO from SRTT and RTTVAR
+ * As in TCP, 4 * RTTVAR >= TCP_RTO_MIN, giving a minimum RTO of 200 ms.
+ * This agrees with RFC 4341, 5:
+ * "Because DCCP does not retransmit data, DCCP does not require
+ * TCP's recommended minimum timeout of one second".
+ */
+ hc->tx_rto = (hc->tx_srtt >> 3) + hc->tx_rttvar;
+
+ if (hc->tx_rto > DCCP_RTO_MAX)
+ hc->tx_rto = DCCP_RTO_MAX;
}
-static inline void ccid2_new_ack(struct sock *sk,
- struct ccid2_seq *seqp,
- unsigned int *maxincr)
+static void ccid2_new_ack(struct sock *sk, struct ccid2_seq *seqp,
+ unsigned int *maxincr)
{
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
@@ -402,93 +400,27 @@ static inline void ccid2_new_ack(struct sock *sk,
hc->tx_cwnd += 1;
hc->tx_packets_acked = 0;
}
-
- /* update RTO */
- if (hc->tx_srtt == -1 ||
- time_after(jiffies, hc->tx_lastrtt + hc->tx_srtt)) {
- unsigned long r = (long)jiffies - (long)seqp->ccid2s_sent;
- int s;
-
- /* first measurement */
- if (hc->tx_srtt == -1) {
- ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n",
- r, jiffies,
- (unsigned long long)seqp->ccid2s_seq);
- ccid2_change_srtt(hc, r);
- hc->tx_rttvar = r >> 1;
- } else {
- /* RTTVAR */
- long tmp = hc->tx_srtt - r;
- long srtt;
-
- if (tmp < 0)
- tmp *= -1;
-
- tmp >>= 2;
- hc->tx_rttvar *= 3;
- hc->tx_rttvar >>= 2;
- hc->tx_rttvar += tmp;
-
- /* SRTT */
- srtt = hc->tx_srtt;
- srtt *= 7;
- srtt >>= 3;
- tmp = r >> 3;
- srtt += tmp;
- ccid2_change_srtt(hc, srtt);
- }
- s = hc->tx_rttvar << 2;
- /* clock granularity is 1 when based on jiffies */
- if (!s)
- s = 1;
- hc->tx_rto = hc->tx_srtt + s;
-
- /* must be at least a second */
- s = hc->tx_rto / HZ;
- /* DCCP doesn't require this [but I like it cuz my code sux] */
-#if 1
- if (s < 1)
- hc->tx_rto = HZ;
-#endif
- /* max 60 seconds */
- if (s > 60)
- hc->tx_rto = HZ * 60;
-
- hc->tx_lastrtt = jiffies;
-
- ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n",
- hc->tx_srtt, hc->tx_rttvar,
- hc->tx_rto, HZ, r);
- }
-
- /* we got a new ack, so re-start RTO timer */
- ccid2_hc_tx_kill_rto_timer(sk);
- ccid2_start_rto_timer(sk);
-}
-
-static void ccid2_hc_tx_dec_pipe(struct sock *sk)
-{
- struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
-
- if (hc->tx_pipe == 0)
- DCCP_BUG("pipe == 0");
- else
- hc->tx_pipe--;
-
- if (hc->tx_pipe == 0)
- ccid2_hc_tx_kill_rto_timer(sk);
+ /*
+ * FIXME: RTT is sampled several times per acknowledgment (for each
+ * entry in the Ack Vector), instead of once per Ack (as in TCP SACK).
+ * This causes the RTT to be over-estimated, since the older entries
+ * in the Ack Vector have earlier sending times.
+ * The cleanest solution is to not use the ccid2s_sent field at all
+ * and instead use DCCP timestamps: requires changes in other places.
+ */
+ ccid2_rtt_estimator(sk, ccid2_time_stamp - seqp->ccid2s_sent);
}
static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp)
{
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
- if (time_before(seqp->ccid2s_sent, hc->tx_last_cong)) {
+ if ((s32)(seqp->ccid2s_sent - hc->tx_last_cong) < 0) {
ccid2_pr_debug("Multiple losses in an RTT---treating as one\n");
return;
}
- hc->tx_last_cong = jiffies;
+ hc->tx_last_cong = ccid2_time_stamp;
hc->tx_cwnd = hc->tx_cwnd / 2 ? : 1U;
hc->tx_ssthresh = max(hc->tx_cwnd, 2U);
@@ -510,7 +442,6 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
int done = 0;
unsigned int maxincr = 0;
- ccid2_hc_tx_check_sanity(hc);
/* check reverse path congestion */
seqno = DCCP_SKB_CB(skb)->dccpd_seq;
@@ -620,7 +551,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
seqp->ccid2s_acked = 1;
ccid2_pr_debug("Got ack for %llu\n",
(unsigned long long)seqp->ccid2s_seq);
- ccid2_hc_tx_dec_pipe(sk);
+ hc->tx_pipe--;
}
if (seqp == hc->tx_seqt) {
done = 1;
@@ -677,7 +608,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
* one ack vector.
*/
ccid2_congestion_event(sk, seqp);
- ccid2_hc_tx_dec_pipe(sk);
+ hc->tx_pipe--;
}
if (seqp == hc->tx_seqt)
break;
@@ -695,7 +626,11 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
hc->tx_seqt = hc->tx_seqt->ccid2s_next;
}
- ccid2_hc_tx_check_sanity(hc);
+ /* restart RTO timer if not all outstanding data has been acked */
+ if (hc->tx_pipe == 0)
+ sk_stop_timer(sk, &hc->tx_rtotimer);
+ else
+ sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
}
static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
@@ -707,12 +642,8 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
/* RFC 4341, 5: initialise ssthresh to arbitrarily high (max) value */
hc->tx_ssthresh = ~0U;
- /*
- * RFC 4341, 5: "The cwnd parameter is initialized to at most four
- * packets for new connections, following the rules from [RFC3390]".
- * We need to convert the bytes of RFC3390 into the packets of RFC 4341.
- */
- hc->tx_cwnd = clamp(4380U / dp->dccps_mss_cache, 2U, 4U);
+ /* Use larger initial windows (RFC 4341, section 5). */
+ hc->tx_cwnd = rfc3390_bytes_to_packets(dp->dccps_mss_cache);
/* Make sure that Ack Ratio is enabled and within bounds. */
max_ratio = DIV_ROUND_UP(hc->tx_cwnd, 2);
@@ -723,15 +654,11 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
if (ccid2_hc_tx_alloc_seq(hc))
return -ENOMEM;
- hc->tx_rto = 3 * HZ;
- ccid2_change_srtt(hc, -1);
- hc->tx_rttvar = -1;
+ hc->tx_rto = DCCP_TIMEOUT_INIT;
hc->tx_rpdupack = -1;
- hc->tx_last_cong = jiffies;
+ hc->tx_last_cong = ccid2_time_stamp;
setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire,
(unsigned long)sk);
-
- ccid2_hc_tx_check_sanity(hc);
return 0;
}
@@ -740,7 +667,7 @@ static void ccid2_hc_tx_exit(struct sock *sk)
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
int i;
- ccid2_hc_tx_kill_rto_timer(sk);
+ sk_stop_timer(sk, &hc->tx_rtotimer);
for (i = 0; i < hc->tx_seqbufc; i++)
kfree(hc->tx_seqbuf[i]);
diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h
index 1ec6a30103bb..9731c2dc1487 100644
--- a/net/dccp/ccids/ccid2.h
+++ b/net/dccp/ccids/ccid2.h
@@ -18,18 +18,23 @@
#ifndef _DCCP_CCID2_H_
#define _DCCP_CCID2_H_
-#include <linux/dccp.h>
#include <linux/timer.h>
#include <linux/types.h>
#include "../ccid.h"
+#include "../dccp.h"
+
+/*
+ * CCID-2 timestamping faces the same issues as TCP timestamping.
+ * Hence we reuse/share as much of the code as possible.
+ */
+#define ccid2_time_stamp tcp_time_stamp
+
/* NUMDUPACK parameter from RFC 4341, p. 6 */
#define NUMDUPACK 3
-struct sock;
-
struct ccid2_seq {
u64 ccid2s_seq;
- unsigned long ccid2s_sent;
+ u32 ccid2s_sent;
int ccid2s_acked;
struct ccid2_seq *ccid2s_prev;
struct ccid2_seq *ccid2s_next;
@@ -42,7 +47,12 @@ struct ccid2_seq {
* struct ccid2_hc_tx_sock - CCID2 TX half connection
* @tx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5
* @tx_packets_acked: Ack counter for deriving cwnd growth (RFC 3465)
- * @tx_lastrtt: time RTT was last measured
+ * @tx_srtt: smoothed RTT estimate, scaled by 2^3
+ * @tx_mdev: smoothed RTT variation, scaled by 2^2
+ * @tx_mdev_max: maximum of @mdev during one flight
+ * @tx_rttvar: moving average/maximum of @mdev_max
+ * @tx_rto: RTO value deriving from SRTT and RTTVAR (RFC 2988)
+ * @tx_rtt_seq: to decay RTTVAR at most once per flight
* @tx_rpseq: last consecutive seqno
* @tx_rpdupack: dupacks since rpseq
*/
@@ -55,14 +65,19 @@ struct ccid2_hc_tx_sock {
int tx_seqbufc;
struct ccid2_seq *tx_seqh;
struct ccid2_seq *tx_seqt;
- long tx_rto;
- long tx_srtt;
- long tx_rttvar;
- unsigned long tx_lastrtt;
+
+ /* RTT measurement: variables/principles are the same as in TCP */
+ u32 tx_srtt,
+ tx_mdev,
+ tx_mdev_max,
+ tx_rttvar,
+ tx_rto;
+ u64 tx_rtt_seq:48;
struct timer_list tx_rtotimer;
+
u64 tx_rpseq;
int tx_rpdupack;
- unsigned long tx_last_cong;
+ u32 tx_last_cong;
u64 tx_high_ack;
};
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 95f752986497..3060a60ed5ab 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -54,7 +54,6 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
[TFRC_SSTATE_NO_SENT] = "NO_SENT",
[TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
[TFRC_SSTATE_FBACK] = "FBACK",
- [TFRC_SSTATE_TERM] = "TERM",
};
return ccid3_state_names[state];
@@ -91,19 +90,16 @@ static inline u64 rfc3390_initial_rate(struct sock *sk)
return scaled_div(w_init << 6, hc->tx_rtt);
}
-/*
- * Recalculate t_ipi and delta (should be called whenever X changes)
+/**
+ * ccid3_update_send_interval - Calculate new t_ipi = s / X_inst
+ * This respects the granularity of X_inst (64 * bytes/second).
*/
static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hc)
{
- /* Calculate new t_ipi = s / X_inst (X_inst is in 64 * bytes/second) */
hc->tx_t_ipi = scaled_div32(((u64)hc->tx_s) << 6, hc->tx_x);
- /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
- hc->tx_delta = min_t(u32, hc->tx_t_ipi / 2, TFRC_OPSYS_HALF_TIME_GRAN);
-
- ccid3_pr_debug("t_ipi=%u, delta=%u, s=%u, X=%u\n", hc->tx_t_ipi,
- hc->tx_delta, hc->tx_s, (unsigned)(hc->tx_x >> 6));
+ ccid3_pr_debug("t_ipi=%u, s=%u, X=%u\n", hc->tx_t_ipi,
+ hc->tx_s, (unsigned)(hc->tx_x >> 6));
}
static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hc, ktime_t now)
@@ -211,16 +207,19 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
ccid3_pr_debug("%s(%p, state=%s) - entry\n", dccp_role(sk), sk,
ccid3_tx_state_name(hc->tx_state));
+ /* Ignore and do not restart after leaving the established state */
+ if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN))
+ goto out;
+
+ /* Reset feedback state to "no feedback received" */
if (hc->tx_state == TFRC_SSTATE_FBACK)
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
- else if (hc->tx_state != TFRC_SSTATE_NO_FBACK)
- goto out;
/*
* Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4
+ * RTO is 0 if and only if no feedback has been received yet.
*/
- if (hc->tx_t_rto == 0 || /* no feedback received yet */
- hc->tx_p == 0) {
+ if (hc->tx_t_rto == 0 || hc->tx_p == 0) {
/* halve send rate directly */
hc->tx_x = max(hc->tx_x / 2,
@@ -256,7 +255,7 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
* Set new timeout for the nofeedback timer.
* See comments in packet_recv() regarding the value of t_RTO.
*/
- if (unlikely(hc->tx_t_rto == 0)) /* no feedback yet */
+ if (unlikely(hc->tx_t_rto == 0)) /* no feedback received yet */
t_nfb = TFRC_INITIAL_TIMEOUT;
else
t_nfb = max(hc->tx_t_rto, 2 * hc->tx_t_ipi);
@@ -290,8 +289,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
if (unlikely(skb->len == 0))
return -EBADMSG;
- switch (hc->tx_state) {
- case TFRC_SSTATE_NO_SENT:
+ if (hc->tx_state == TFRC_SSTATE_NO_SENT) {
sk_reset_timer(sk, &hc->tx_no_feedback_timer, (jiffies +
usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)));
hc->tx_last_win_count = 0;
@@ -326,27 +324,22 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
ccid3_update_send_interval(hc);
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
- break;
- case TFRC_SSTATE_NO_FBACK:
- case TFRC_SSTATE_FBACK:
+
+ } else {
delay = ktime_us_delta(hc->tx_t_nom, now);
ccid3_pr_debug("delay=%ld\n", (long)delay);
/*
- * Scheduling of packet transmissions [RFC 3448, 4.6]
+ * Scheduling of packet transmissions (RFC 5348, 8.3)
*
* if (t_now > t_nom - delta)
* // send the packet now
* else
* // send the packet in (t_nom - t_now) milliseconds.
*/
- if (delay - (s64)hc->tx_delta >= 1000)
- return (u32)delay / 1000L;
+ if (delay >= TFRC_T_DELTA)
+ return (u32)delay / USEC_PER_MSEC;
ccid3_hc_tx_update_win_count(hc, now);
- break;
- case TFRC_SSTATE_TERM:
- DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
- return -EINVAL;
}
/* prepare to send now (add options etc.) */
@@ -358,8 +351,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
return 0;
}
-static void ccid3_hc_tx_packet_sent(struct sock *sk, int more,
- unsigned int len)
+static void ccid3_hc_tx_packet_sent(struct sock *sk, unsigned int len)
{
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
@@ -372,48 +364,34 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more,
static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
- struct ccid3_options_received *opt_recv;
+ struct tfrc_tx_hist_entry *acked;
ktime_t now;
unsigned long t_nfb;
- u32 pinv, r_sample;
+ u32 r_sample;
/* we are only interested in ACKs */
if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
return;
- /* ... and only in the established state */
- if (hc->tx_state != TFRC_SSTATE_FBACK &&
- hc->tx_state != TFRC_SSTATE_NO_FBACK)
- return;
-
- opt_recv = &hc->tx_options_received;
- now = ktime_get_real();
-
- /* Estimate RTT from history if ACK number is valid */
- r_sample = tfrc_tx_hist_rtt(hc->tx_hist,
- DCCP_SKB_CB(skb)->dccpd_ack_seq, now);
- if (r_sample == 0) {
- DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk,
- dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type),
- (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq);
- return;
- }
-
- /* Update receive rate in units of 64 * bytes/second */
- hc->tx_x_recv = opt_recv->ccid3or_receive_rate;
- hc->tx_x_recv <<= 6;
-
- /* Update loss event rate (which is scaled by 1e6) */
- pinv = opt_recv->ccid3or_loss_event_rate;
- if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */
- hc->tx_p = 0;
- else /* can not exceed 100% */
- hc->tx_p = scaled_div(1, pinv);
/*
- * Validate new RTT sample and update moving average
+ * Locate the acknowledged packet in the TX history.
+ *
+ * Returning "entry not found" here can for instance happen when
+ * - the host has not sent out anything (e.g. a passive server),
+ * - the Ack is outdated (packet with higher Ack number was received),
+ * - it is a bogus Ack (for a packet not sent on this connection).
*/
- r_sample = dccp_sample_rtt(sk, r_sample);
+ acked = tfrc_tx_hist_find_entry(hc->tx_hist, dccp_hdr_ack_seq(skb));
+ if (acked == NULL)
+ return;
+ /* For the sake of RTT sampling, ignore/remove all older entries */
+ tfrc_tx_hist_purge(&acked->next);
+
+ /* Update the moving average for the RTT estimate (RFC 3448, 4.3) */
+ now = ktime_get_real();
+ r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, acked->stamp));
hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9);
+
/*
* Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
*/
@@ -461,13 +439,12 @@ done_computing_x:
sk->sk_write_space(sk);
/*
- * Update timeout interval for the nofeedback timer.
- * We use a configuration option to increase the lower bound.
- * This can help avoid triggering the nofeedback timer too
- * often ('spinning') on LANs with small RTTs.
+ * Update timeout interval for the nofeedback timer. In order to control
+ * rate halving on networks with very low RTTs (<= 1 ms), use per-route
+ * tunable RTAX_RTO_MIN value as the lower bound.
*/
- hc->tx_t_rto = max_t(u32, 4 * hc->tx_rtt, (CONFIG_IP_DCCP_CCID3_RTO *
- (USEC_PER_SEC / 1000)));
+ hc->tx_t_rto = max_t(u32, 4 * hc->tx_rtt,
+ USEC_PER_SEC/HZ * tcp_rto_min(sk));
/*
* Schedule no feedback timer to expire in
* max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
@@ -482,66 +459,41 @@ done_computing_x:
jiffies + usecs_to_jiffies(t_nfb));
}
-static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
- unsigned char len, u16 idx,
- unsigned char *value)
+static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type,
+ u8 option, u8 *optval, u8 optlen)
{
- int rc = 0;
- const struct dccp_sock *dp = dccp_sk(sk);
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
- struct ccid3_options_received *opt_recv;
__be32 opt_val;
- opt_recv = &hc->tx_options_received;
-
- if (opt_recv->ccid3or_seqno != dp->dccps_gsr) {
- opt_recv->ccid3or_seqno = dp->dccps_gsr;
- opt_recv->ccid3or_loss_event_rate = ~0;
- opt_recv->ccid3or_loss_intervals_idx = 0;
- opt_recv->ccid3or_loss_intervals_len = 0;
- opt_recv->ccid3or_receive_rate = 0;
- }
-
switch (option) {
+ case TFRC_OPT_RECEIVE_RATE:
case TFRC_OPT_LOSS_EVENT_RATE:
- if (unlikely(len != 4)) {
- DCCP_WARN("%s(%p), invalid len %d "
- "for TFRC_OPT_LOSS_EVENT_RATE\n",
- dccp_role(sk), sk, len);
- rc = -EINVAL;
- } else {
- opt_val = get_unaligned((__be32 *)value);
- opt_recv->ccid3or_loss_event_rate = ntohl(opt_val);
- ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n",
- dccp_role(sk), sk,
- opt_recv->ccid3or_loss_event_rate);
+ /* Must be ignored on Data packets, cf. RFC 4342 8.3 and 8.5 */
+ if (packet_type == DCCP_PKT_DATA)
+ break;
+ if (unlikely(optlen != 4)) {
+ DCCP_WARN("%s(%p), invalid len %d for %u\n",
+ dccp_role(sk), sk, optlen, option);
+ return -EINVAL;
}
- break;
- case TFRC_OPT_LOSS_INTERVALS:
- opt_recv->ccid3or_loss_intervals_idx = idx;
- opt_recv->ccid3or_loss_intervals_len = len;
- ccid3_pr_debug("%s(%p), LOSS_INTERVALS=(%u, %u)\n",
- dccp_role(sk), sk,
- opt_recv->ccid3or_loss_intervals_idx,
- opt_recv->ccid3or_loss_intervals_len);
- break;
- case TFRC_OPT_RECEIVE_RATE:
- if (unlikely(len != 4)) {
- DCCP_WARN("%s(%p), invalid len %d "
- "for TFRC_OPT_RECEIVE_RATE\n",
- dccp_role(sk), sk, len);
- rc = -EINVAL;
- } else {
- opt_val = get_unaligned((__be32 *)value);
- opt_recv->ccid3or_receive_rate = ntohl(opt_val);
+ opt_val = ntohl(get_unaligned((__be32 *)optval));
+
+ if (option == TFRC_OPT_RECEIVE_RATE) {
+ /* Receive Rate is kept in units of 64 bytes/second */
+ hc->tx_x_recv = opt_val;
+ hc->tx_x_recv <<= 6;
+
ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n",
- dccp_role(sk), sk,
- opt_recv->ccid3or_receive_rate);
+ dccp_role(sk), sk, opt_val);
+ } else {
+ /* Update the fixpoint Loss Event Rate fraction */
+ hc->tx_p = tfrc_invert_loss_event_rate(opt_val);
+
+ ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n",
+ dccp_role(sk), sk, opt_val);
}
- break;
}
-
- return rc;
+ return 0;
}
static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
@@ -559,42 +511,36 @@ static void ccid3_hc_tx_exit(struct sock *sk)
{
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
- ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
sk_stop_timer(sk, &hc->tx_no_feedback_timer);
-
tfrc_tx_hist_purge(&hc->tx_hist);
}
static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
{
- struct ccid3_hc_tx_sock *hc;
-
- /* Listen socks doesn't have a private CCID block */
- if (sk->sk_state == DCCP_LISTEN)
- return;
-
- hc = ccid3_hc_tx_sk(sk);
- info->tcpi_rto = hc->tx_t_rto;
- info->tcpi_rtt = hc->tx_rtt;
+ info->tcpi_rto = ccid3_hc_tx_sk(sk)->tx_t_rto;
+ info->tcpi_rtt = ccid3_hc_tx_sk(sk)->tx_rtt;
}
static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
u32 __user *optval, int __user *optlen)
{
- const struct ccid3_hc_tx_sock *hc;
+ const struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
+ struct tfrc_tx_info tfrc;
const void *val;
- /* Listen socks doesn't have a private CCID block */
- if (sk->sk_state == DCCP_LISTEN)
- return -EINVAL;
-
- hc = ccid3_hc_tx_sk(sk);
switch (optname) {
case DCCP_SOCKOPT_CCID_TX_INFO:
- if (len < sizeof(hc->tx_tfrc))
+ if (len < sizeof(tfrc))
return -EINVAL;
- len = sizeof(hc->tx_tfrc);
- val = &hc->tx_tfrc;
+ tfrc.tfrctx_x = hc->tx_x;
+ tfrc.tfrctx_x_recv = hc->tx_x_recv;
+ tfrc.tfrctx_x_calc = hc->tx_x_calc;
+ tfrc.tfrctx_rtt = hc->tx_rtt;
+ tfrc.tfrctx_p = hc->tx_p;
+ tfrc.tfrctx_rto = hc->tx_t_rto;
+ tfrc.tfrctx_ipi = hc->tx_t_ipi;
+ len = sizeof(tfrc);
+ val = &tfrc;
break;
default:
return -ENOPROTOOPT;
@@ -624,7 +570,6 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
static const char *const ccid3_rx_state_names[] = {
[TFRC_RSTATE_NO_DATA] = "NO_DATA",
[TFRC_RSTATE_DATA] = "DATA",
- [TFRC_RSTATE_TERM] = "TERM",
};
return ccid3_rx_state_names[state];
@@ -650,14 +595,9 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk,
{
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
- ktime_t now;
+ ktime_t now = ktime_get_real();
s64 delta = 0;
- if (unlikely(hc->rx_state == TFRC_RSTATE_TERM))
- return;
-
- now = ktime_get_real();
-
switch (fbtype) {
case CCID3_FBACK_INITIAL:
hc->rx_x_recv = 0;
@@ -701,14 +641,12 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk,
static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
{
- const struct ccid3_hc_rx_sock *hc;
+ const struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
__be32 x_recv, pinv;
if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
return 0;
- hc = ccid3_hc_rx_sk(sk);
-
if (dccp_packet_without_ack(skb))
return 0;
@@ -749,10 +687,11 @@ static u32 ccid3_first_li(struct sock *sk)
x_recv = scaled_div32(hc->rx_bytes_recv, delta);
if (x_recv == 0) { /* would also trigger divide-by-zero */
DCCP_WARN("X_recv==0\n");
- if ((x_recv = hc->rx_x_recv) == 0) {
+ if (hc->rx_x_recv == 0) {
DCCP_BUG("stored value of X_recv is zero");
return ~0U;
}
+ x_recv = hc->rx_x_recv;
}
fval = scaled_div(hc->rx_s, hc->rx_rtt);
@@ -862,46 +801,31 @@ static void ccid3_hc_rx_exit(struct sock *sk)
{
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
- ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
-
tfrc_rx_hist_purge(&hc->rx_hist);
tfrc_lh_cleanup(&hc->rx_li_hist);
}
static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
{
- const struct ccid3_hc_rx_sock *hc;
-
- /* Listen socks doesn't have a private CCID block */
- if (sk->sk_state == DCCP_LISTEN)
- return;
-
- hc = ccid3_hc_rx_sk(sk);
- info->tcpi_ca_state = hc->rx_state;
+ info->tcpi_ca_state = ccid3_hc_rx_sk(sk)->rx_state;
info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
- info->tcpi_rcv_rtt = hc->rx_rtt;
+ info->tcpi_rcv_rtt = ccid3_hc_rx_sk(sk)->rx_rtt;
}
static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
u32 __user *optval, int __user *optlen)
{
- const struct ccid3_hc_rx_sock *hc;
+ const struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
struct tfrc_rx_info rx_info;
const void *val;
- /* Listen socks doesn't have a private CCID block */
- if (sk->sk_state == DCCP_LISTEN)
- return -EINVAL;
-
- hc = ccid3_hc_rx_sk(sk);
switch (optname) {
case DCCP_SOCKOPT_CCID_RX_INFO:
if (len < sizeof(rx_info))
return -EINVAL;
rx_info.tfrcrx_x_recv = hc->rx_x_recv;
rx_info.tfrcrx_rtt = hc->rx_rtt;
- rx_info.tfrcrx_p = hc->rx_pinv == 0 ? ~0U :
- scaled_div(1, hc->rx_pinv);
+ rx_info.tfrcrx_p = tfrc_invert_loss_event_rate(hc->rx_pinv);
len = sizeof(rx_info);
val = &rx_info;
break;
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index 032635776653..1a9933c29672 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -42,35 +42,36 @@
#include "lib/tfrc.h"
#include "../ccid.h"
-/* Two seconds as per RFC 3448 4.2 */
+/* Two seconds as per RFC 5348, 4.2 */
#define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC)
-/* In usecs - half the scheduling granularity as per RFC3448 4.6 */
-#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ))
-
/* Parameter t_mbi from [RFC 3448, 4.3]: backoff interval in seconds */
#define TFRC_T_MBI 64
+/*
+ * The t_delta parameter (RFC 5348, 8.3): delays of less than %USEC_PER_MSEC are
+ * rounded down to 0, since sk_reset_timer() here uses millisecond granularity.
+ * Hence we can use a constant t_delta = %USEC_PER_MSEC when HZ >= 500. A coarse
+ * resolution of HZ < 500 means that the error is below one timer tick (t_gran)
+ * when using the constant t_delta = t_gran / 2 = %USEC_PER_SEC / (2 * HZ).
+ */
+#if (HZ >= 500)
+# define TFRC_T_DELTA USEC_PER_MSEC
+#else
+# define TFRC_T_DELTA (USEC_PER_SEC / (2 * HZ))
+#endif
+
enum ccid3_options {
TFRC_OPT_LOSS_EVENT_RATE = 192,
TFRC_OPT_LOSS_INTERVALS = 193,
TFRC_OPT_RECEIVE_RATE = 194,
};
-struct ccid3_options_received {
- u64 ccid3or_seqno:48,
- ccid3or_loss_intervals_idx:16;
- u16 ccid3or_loss_intervals_len;
- u32 ccid3or_loss_event_rate;
- u32 ccid3or_receive_rate;
-};
-
/* TFRC sender states */
enum ccid3_hc_tx_states {
TFRC_SSTATE_NO_SENT = 1,
TFRC_SSTATE_NO_FBACK,
TFRC_SSTATE_FBACK,
- TFRC_SSTATE_TERM,
};
/**
@@ -90,19 +91,16 @@ enum ccid3_hc_tx_states {
* @tx_no_feedback_timer: Handle to no feedback timer
* @tx_t_ld: Time last doubled during slow start
* @tx_t_nom: Nominal send time of next packet
- * @tx_delta: Send timer delta (RFC 3448, 4.6) in usecs
* @tx_hist: Packet history
- * @tx_options_received: Parsed set of retrieved options
*/
struct ccid3_hc_tx_sock {
- struct tfrc_tx_info tx_tfrc;
-#define tx_x tx_tfrc.tfrctx_x
-#define tx_x_recv tx_tfrc.tfrctx_x_recv
-#define tx_x_calc tx_tfrc.tfrctx_x_calc
-#define tx_rtt tx_tfrc.tfrctx_rtt
-#define tx_p tx_tfrc.tfrctx_p
-#define tx_t_rto tx_tfrc.tfrctx_rto
-#define tx_t_ipi tx_tfrc.tfrctx_ipi
+ u64 tx_x;
+ u64 tx_x_recv;
+ u32 tx_x_calc;
+ u32 tx_rtt;
+ u32 tx_p;
+ u32 tx_t_rto;
+ u32 tx_t_ipi;
u16 tx_s;
enum ccid3_hc_tx_states tx_state:8;
u8 tx_last_win_count;
@@ -110,9 +108,7 @@ struct ccid3_hc_tx_sock {
struct timer_list tx_no_feedback_timer;
ktime_t tx_t_ld;
ktime_t tx_t_nom;
- u32 tx_delta;
struct tfrc_tx_hist_entry *tx_hist;
- struct ccid3_options_received tx_options_received;
};
static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
@@ -126,21 +122,16 @@ static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
enum ccid3_hc_rx_states {
TFRC_RSTATE_NO_DATA = 1,
TFRC_RSTATE_DATA,
- TFRC_RSTATE_TERM = 127,
};
/**
* struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket
- * @rx_x_recv: Receiver estimate of send rate (RFC 3448 4.3)
- * @rx_rtt: Receiver estimate of rtt (non-standard)
- * @rx_p: Current loss event rate (RFC 3448 5.4)
* @rx_last_counter: Tracks window counter (RFC 4342, 8.1)
* @rx_state: Receiver state, one of %ccid3_hc_rx_states
* @rx_bytes_recv: Total sum of DCCP payload bytes
* @rx_x_recv: Receiver estimate of send rate (RFC 3448, sec. 4.3)
* @rx_rtt: Receiver estimate of RTT
* @rx_tstamp_last_feedback: Time at which last feedback was sent
- * @rx_tstamp_last_ack: Time at which last feedback was sent
* @rx_hist: Packet history (loss detection + RTT sampling)
* @rx_li_hist: Loss Interval database
* @rx_s: Received packet size in bytes
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c
index 8fc3cbf79071..497723c4d4bb 100644
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -116,7 +116,7 @@ u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb)
cur->li_length = len;
tfrc_lh_calc_i_mean(lh);
- return (lh->i_mean < old_i_mean);
+ return lh->i_mean < old_i_mean;
}
/* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index 3a4f414e94a0..de8fe294bf0b 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -38,18 +38,6 @@
#include "packet_history.h"
#include "../../dccp.h"
-/**
- * tfrc_tx_hist_entry - Simple singly-linked TX history list
- * @next: next oldest entry (LIFO order)
- * @seqno: sequence number of this entry
- * @stamp: send time of packet with sequence number @seqno
- */
-struct tfrc_tx_hist_entry {
- struct tfrc_tx_hist_entry *next;
- u64 seqno;
- ktime_t stamp;
-};
-
/*
* Transmitter History Routines
*/
@@ -71,15 +59,6 @@ void tfrc_tx_packet_history_exit(void)
}
}
-static struct tfrc_tx_hist_entry *
- tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno)
-{
- while (head != NULL && head->seqno != seqno)
- head = head->next;
-
- return head;
-}
-
int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno)
{
struct tfrc_tx_hist_entry *entry = kmem_cache_alloc(tfrc_tx_hist_slab, gfp_any());
@@ -107,24 +86,6 @@ void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp)
*headp = NULL;
}
-u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno,
- const ktime_t now)
-{
- u32 rtt = 0;
- struct tfrc_tx_hist_entry *packet = tfrc_tx_hist_find_entry(head, seqno);
-
- if (packet != NULL) {
- rtt = ktime_us_delta(now, packet->stamp);
- /*
- * Garbage-collect older (irrelevant) entries:
- */
- tfrc_tx_hist_purge(&packet->next);
- }
-
- return rtt;
-}
-
-
/*
* Receiver History Routines
*/
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index 7df6c5299999..7ee4a9d9d335 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -40,12 +40,28 @@
#include <linux/slab.h>
#include "tfrc.h"
-struct tfrc_tx_hist_entry;
+/**
+ * tfrc_tx_hist_entry - Simple singly-linked TX history list
+ * @next: next oldest entry (LIFO order)
+ * @seqno: sequence number of this entry
+ * @stamp: send time of packet with sequence number @seqno
+ */
+struct tfrc_tx_hist_entry {
+ struct tfrc_tx_hist_entry *next;
+ u64 seqno;
+ ktime_t stamp;
+};
+
+static inline struct tfrc_tx_hist_entry *
+ tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno)
+{
+ while (head != NULL && head->seqno != seqno)
+ head = head->next;
+ return head;
+}
extern int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno);
extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp);
-extern u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head,
- const u64 seqno, const ktime_t now);
/* Subtraction a-b modulo-16, respects circular wrap-around */
#define SUB16(a, b) (((a) + 16 - (b)) & 0xF)
diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h
index 01bb48e96c2e..f8ee3f549770 100644
--- a/net/dccp/ccids/lib/tfrc.h
+++ b/net/dccp/ccids/lib/tfrc.h
@@ -57,6 +57,7 @@ static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight)
extern u32 tfrc_calc_x(u16 s, u32 R, u32 p);
extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
+extern u32 tfrc_invert_loss_event_rate(u32 loss_event_rate);
extern int tfrc_tx_packet_history_init(void);
extern void tfrc_tx_packet_history_exit(void);
diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c
index 22ca1cf0eb55..a052a4377e26 100644
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -687,3 +687,17 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalue)
index = tfrc_binsearch(fvalue, 0);
return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE;
}
+
+/**
+ * tfrc_invert_loss_event_rate - Compute p so that 10^6 corresponds to 100%
+ * When @loss_event_rate is large, there is a chance that p is truncated to 0.
+ * To avoid re-entering slow-start in that case, we set p = TFRC_SMALLEST_P > 0.
+ */
+u32 tfrc_invert_loss_event_rate(u32 loss_event_rate)
+{
+ if (loss_event_rate == UINT_MAX) /* see RFC 4342, 8.5 */
+ return 0;
+ if (unlikely(loss_event_rate == 0)) /* map 1/0 into 100% */
+ return 1000000;
+ return max_t(u32, scaled_div(1, loss_event_rate), TFRC_SMALLEST_P);
+}
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 3ccef1b70fee..3eb264b60823 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -153,18 +153,27 @@ static inline u64 max48(const u64 seq1, const u64 seq2)
}
/**
- * dccp_loss_free - Evaluates condition for data loss from RFC 4340, 7.7.1
- * @s1: start sequence number
- * @s2: end sequence number
+ * dccp_loss_count - Approximate the number of lost data packets in a burst loss
+ * @s1: last known sequence number before the loss ('hole')
+ * @s2: first sequence number seen after the 'hole'
* @ndp: NDP count on packet with sequence number @s2
- * Returns true if the sequence range s1...s2 has no data loss.
*/
-static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp)
+static inline u64 dccp_loss_count(const u64 s1, const u64 s2, const u64 ndp)
{
s64 delta = dccp_delta_seqno(s1, s2);
WARN_ON(delta < 0);
- return (u64)delta <= ndp + 1;
+ delta -= ndp + 1;
+
+ return delta > 0 ? delta : 0;
+}
+
+/**
+ * dccp_loss_free - Evaluate condition for data loss from RFC 4340, 7.7.1
+ */
+static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp)
+{
+ return dccp_loss_count(s1, s2, ndp) == 0;
}
enum {
@@ -246,7 +255,6 @@ static inline void dccp_clear_xmit_timers(struct sock *sk)
extern unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu);
extern const char *dccp_packet_name(const int type);
-extern const char *dccp_state_name(const int state);
extern void dccp_set_state(struct sock *sk, const int state);
extern void dccp_done(struct sock *sk);
@@ -415,6 +423,23 @@ static inline void dccp_update_gsr(struct sock *sk, u64 seq)
dp->dccps_gsr = seq;
/* Sequence validity window depends on remote Sequence Window (7.5.1) */
dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4);
+ /*
+ * Adjust SWL so that it is not below ISR. In contrast to RFC 4340,
+ * 7.5.1 we perform this check beyond the initial handshake: W/W' are
+ * always > 32, so for the first W/W' packets in the lifetime of a
+ * connection we always have to adjust SWL.
+ * A second reason why we are doing this is that the window depends on
+ * the feature-remote value of Sequence Window: nothing stops the peer
+ * from updating this value while we are busy adjusting SWL for the
+ * first W packets (we would have to count from scratch again then).
+ * Therefore it is safer to always make sure that the Sequence Window
+ * is not artificially extended by a peer who grows SWL downwards by
+ * continually updating the feature-remote Sequence-Window.
+ * If sequence numbers wrap it is bad luck. But that will take a while
+ * (48 bit), and this measure prevents Sequence-number attacks.
+ */
+ if (before48(dp->dccps_swl, dp->dccps_isr))
+ dp->dccps_swl = dp->dccps_isr;
dp->dccps_swh = ADD48(dp->dccps_gsr, (3 * dp->dccps_r_seq_win) / 4);
}
@@ -425,14 +450,16 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq)
dp->dccps_gss = seq;
/* Ack validity window depends on local Sequence Window value (7.5.1) */
dp->dccps_awl = SUB48(ADD48(dp->dccps_gss, 1), dp->dccps_l_seq_win);
+ /* Adjust AWL so that it is not below ISS - see comment above for SWL */
+ if (before48(dp->dccps_awl, dp->dccps_iss))
+ dp->dccps_awl = dp->dccps_iss;
dp->dccps_awh = dp->dccps_gss;
}
static inline int dccp_ack_pending(const struct sock *sk)
{
const struct dccp_sock *dp = dccp_sk(sk);
- return dp->dccps_timestamp_echo != 0 ||
- (dp->dccps_hc_rx_ackvec != NULL &&
+ return (dp->dccps_hc_rx_ackvec != NULL &&
dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
inet_csk_ack_scheduled(sk);
}
@@ -449,7 +476,6 @@ extern int dccp_insert_options_rsk(struct dccp_request_sock*, struct sk_buff*);
extern int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed);
extern u32 dccp_timestamp(void);
extern void dccp_timestamping_init(void);
-extern int dccp_insert_option_timestamp(struct sk_buff *skb);
extern int dccp_insert_option(struct sk_buff *skb, unsigned char option,
const void *value, unsigned char len);
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index df7dd26cf07e..568def952722 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -730,16 +730,6 @@ int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
0, list, len);
}
-/* Analogous to dccp_feat_register_sp(), but for non-negotiable values */
-int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val)
-{
- /* any changes must be registered before establishing the connection */
- if (sk->sk_state != DCCP_CLOSED)
- return -EISCONN;
- if (dccp_feat_type(feat) != FEAT_NN)
- return -EINVAL;
- return __feat_register_nn(&dccp_sk(sk)->dccps_featneg, feat, 0, val);
-}
/*
* Tracking features whose value depend on the choice of CCID
diff --git a/net/dccp/feat.h b/net/dccp/feat.h
index f96721619def..e56a4e5e634e 100644
--- a/net/dccp/feat.h
+++ b/net/dccp/feat.h
@@ -111,7 +111,6 @@ extern int dccp_feat_init(struct sock *sk);
extern void dccp_feat_initialise_sysctls(void);
extern int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
u8 const *list, u8 len);
-extern int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val);
extern int dccp_feat_parse_options(struct sock *, struct dccp_request_sock *,
u8 mand, u8 opt, u8 feat, u8 *val, u8 len);
extern int dccp_feat_clone_list(struct list_head const *, struct list_head *);
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 10c957a88f4f..265985370fa1 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -259,7 +259,7 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
sysctl_dccp_sync_ratelimit)))
return 0;
- DCCP_WARN("DCCP: Step 6 failed for %s packet, "
+ DCCP_WARN("Step 6 failed for %s packet, "
"(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and "
"(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), "
"sending SYNC...\n", dccp_packet_name(dh->dccph_type),
@@ -441,20 +441,14 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
kfree_skb(sk->sk_send_head);
sk->sk_send_head = NULL;
- dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
- dccp_update_gsr(sk, dp->dccps_isr);
/*
- * SWL and AWL are initially adjusted so that they are not less than
- * the initial Sequence Numbers received and sent, respectively:
- * SWL := max(GSR + 1 - floor(W/4), ISR),
- * AWL := max(GSS - W' + 1, ISS).
- * These adjustments MUST be applied only at the beginning of the
- * connection.
- *
- * AWL was adjusted in dccp_v4_connect -acme
+ * Set ISR, GSR from packet. ISS was set in dccp_v{4,6}_connect
+ * and GSS in dccp_transmit_skb(). Setting AWL/AWH and SWL/SWH
+ * is done as part of activating the feature values below, since
+ * these settings depend on the local/remote Sequence Window
+ * features, which were undefined or not confirmed until now.
*/
- dccp_set_seqno(&dp->dccps_swl,
- max48(dp->dccps_swl, dp->dccps_isr));
+ dp->dccps_gsr = dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
dccp_sync_mss(sk, icsk->icsk_pmtu_cookie);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index d4a166f0f391..3f69ea114829 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -392,7 +392,7 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb,
newsk = dccp_create_openreq_child(sk, req, skb);
if (newsk == NULL)
- goto exit;
+ goto exit_nonewsk;
sk_setup_caps(newsk, dst);
@@ -409,16 +409,20 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb,
dccp_sync_mss(newsk, dst_mtu(dst));
+ if (__inet_inherit_port(sk, newsk) < 0) {
+ sock_put(newsk);
+ goto exit;
+ }
__inet_hash_nolisten(newsk, NULL);
- __inet_inherit_port(sk, newsk);
return newsk;
exit_overflow:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
+exit_nonewsk:
+ dst_release(dst);
exit:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
- dst_release(dst);
return NULL;
}
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 6e3f32575df7..dca711df9b60 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -564,7 +564,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
newsk = dccp_create_openreq_child(sk, req, skb);
if (newsk == NULL)
- goto out;
+ goto out_nonewsk;
/*
* No need to charge this sock to the relevant IPv6 refcnt debug socks
@@ -632,18 +632,22 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
+ if (__inet_inherit_port(sk, newsk) < 0) {
+ sock_put(newsk);
+ goto out;
+ }
__inet6_hash(newsk, NULL);
- __inet_inherit_port(sk, newsk);
return newsk;
out_overflow:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
+out_nonewsk:
+ dst_release(dst);
out:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
if (opt != NULL && opt != np->opt)
sock_kfree_s(sk, opt, opt->tot_len);
- dst_release(dst);
return NULL;
}
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index 128b089d3aef..d7041a0963af 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -121,30 +121,18 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
*
* Choose S.ISS (initial seqno) or set from Init Cookies
* Initialize S.GAR := S.ISS
- * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
- */
- newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss;
- dccp_update_gss(newsk, dreq->dreq_iss);
-
- newdp->dccps_isr = dreq->dreq_isr;
- dccp_update_gsr(newsk, dreq->dreq_isr);
-
- /*
- * SWL and AWL are initially adjusted so that they are not less than
- * the initial Sequence Numbers received and sent, respectively:
- * SWL := max(GSR + 1 - floor(W/4), ISR),
- * AWL := max(GSS - W' + 1, ISS).
- * These adjustments MUST be applied only at the beginning of the
- * connection.
+ * Set S.ISR, S.GSR from packet (or Init Cookies)
+ *
+ * Setting AWL/AWH and SWL/SWH happens as part of the feature
+ * activation below, as these windows all depend on the local
+ * and remote Sequence Window feature values (7.5.2).
*/
- dccp_set_seqno(&newdp->dccps_swl,
- max48(newdp->dccps_swl, newdp->dccps_isr));
- dccp_set_seqno(&newdp->dccps_awl,
- max48(newdp->dccps_awl, newdp->dccps_iss));
+ newdp->dccps_gss = newdp->dccps_iss = dreq->dreq_iss;
+ newdp->dccps_gar = newdp->dccps_iss;
+ newdp->dccps_gsr = newdp->dccps_isr = dreq->dreq_isr;
/*
- * Activate features after initialising the sequence numbers,
- * since CCID initialisation may depend on GSS, ISR, ISS etc.
+ * Activate features: initialise CCIDs, sequence windows etc.
*/
if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) {
/* It is still raw copy of parent, so invalidate
diff --git a/net/dccp/options.c b/net/dccp/options.c
index bfda087bd90d..cd3061813009 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -96,18 +96,11 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
}
/*
- * CCID-Specific Options (from RFC 4340, sec. 10.3):
- *
- * Option numbers 128 through 191 are for options sent from the
- * HC-Sender to the HC-Receiver; option numbers 192 through 255
- * are for options sent from the HC-Receiver to the HC-Sender.
- *
* CCID-specific options are ignored during connection setup, as
* negotiation may still be in progress (see RFC 4340, 10.3).
* The same applies to Ack Vectors, as these depend on the CCID.
- *
*/
- if (dreq != NULL && (opt >= 128 ||
+ if (dreq != NULL && (opt >= DCCPO_MIN_RX_CCID_SPECIFIC ||
opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1))
goto ignore_option;
@@ -170,6 +163,8 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
dccp_role(sk), ntohl(opt_val),
(unsigned long long)
DCCP_SKB_CB(skb)->dccpd_ack_seq);
+ /* schedule an Ack in case this sender is quiescent */
+ inet_csk_schedule_ack(sk);
break;
case DCCPO_TIMESTAMP_ECHO:
if (len != 4 && len != 6 && len != 8)
@@ -226,23 +221,15 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
dccp_role(sk), elapsed_time);
break;
- case 128 ... 191: {
- const u16 idx = value - options;
-
+ case DCCPO_MIN_RX_CCID_SPECIFIC ... DCCPO_MAX_RX_CCID_SPECIFIC:
if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk,
- opt, len, idx,
- value) != 0)
+ pkt_type, opt, value, len))
goto out_invalid_option;
- }
break;
- case 192 ... 255: {
- const u16 idx = value - options;
-
+ case DCCPO_MIN_TX_CCID_SPECIFIC ... DCCPO_MAX_TX_CCID_SPECIFIC:
if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk,
- opt, len, idx,
- value) != 0)
+ pkt_type, opt, value, len))
goto out_invalid_option;
- }
break;
default:
DCCP_CRIT("DCCP(%p): option %d(len=%d) not "
@@ -384,7 +371,7 @@ int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed_time)
EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time);
-int dccp_insert_option_timestamp(struct sk_buff *skb)
+static int dccp_insert_option_timestamp(struct sk_buff *skb)
{
__be32 now = htonl(dccp_timestamp());
/* yes this will overflow but that is the point as we want a
@@ -393,8 +380,6 @@ int dccp_insert_option_timestamp(struct sk_buff *skb)
return dccp_insert_option(skb, DCCPO_TIMESTAMP, &now, sizeof(now));
}
-EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp);
-
static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp,
struct dccp_request_sock *dreq,
struct sk_buff *skb)
diff --git a/net/dccp/output.c b/net/dccp/output.c
index aadbdb58758b..a988fe9ffcba 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -304,7 +304,7 @@ void dccp_write_xmit(struct sock *sk, int block)
dcb->dccpd_type = DCCP_PKT_DATA;
err = dccp_transmit_skb(sk, skb);
- ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
+ ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len);
if (err)
DCCP_BUG("err=%d after ccid_hc_tx_packet_sent",
err);
@@ -474,8 +474,9 @@ int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code)
/*
* Do all connect socket setups that can be done AF independent.
*/
-static inline void dccp_connect_init(struct sock *sk)
+int dccp_connect(struct sock *sk)
{
+ struct sk_buff *skb;
struct dccp_sock *dp = dccp_sk(sk);
struct dst_entry *dst = __sk_dst_get(sk);
struct inet_connection_sock *icsk = inet_csk(sk);
@@ -485,22 +486,12 @@ static inline void dccp_connect_init(struct sock *sk)
dccp_sync_mss(sk, dst_mtu(dst));
- /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */
- dp->dccps_gar = dp->dccps_iss;
-
- icsk->icsk_retransmits = 0;
-}
-
-int dccp_connect(struct sock *sk)
-{
- struct sk_buff *skb;
- struct inet_connection_sock *icsk = inet_csk(sk);
-
/* do not connect if feature negotiation setup fails */
if (dccp_feat_finalise_settings(dccp_sk(sk)))
return -EPROTO;
- dccp_connect_init(sk);
+ /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */
+ dp->dccps_gar = dp->dccps_iss;
skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation);
if (unlikely(skb == NULL))
@@ -516,6 +507,7 @@ int dccp_connect(struct sock *sk)
DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);
/* Timer for repeating the REQUEST until an answer. */
+ icsk->icsk_retransmits = 0;
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
icsk->icsk_rto, DCCP_RTO_MAX);
return 0;
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 096250d1323b..7e5fc04eb6d1 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -50,6 +50,30 @@ EXPORT_SYMBOL_GPL(dccp_hashinfo);
/* the maximum queue length for tx in packets. 0 is no limit */
int sysctl_dccp_tx_qlen __read_mostly = 5;
+#ifdef CONFIG_IP_DCCP_DEBUG
+static const char *dccp_state_name(const int state)
+{
+ static const char *const dccp_state_names[] = {
+ [DCCP_OPEN] = "OPEN",
+ [DCCP_REQUESTING] = "REQUESTING",
+ [DCCP_PARTOPEN] = "PARTOPEN",
+ [DCCP_LISTEN] = "LISTEN",
+ [DCCP_RESPOND] = "RESPOND",
+ [DCCP_CLOSING] = "CLOSING",
+ [DCCP_ACTIVE_CLOSEREQ] = "CLOSEREQ",
+ [DCCP_PASSIVE_CLOSE] = "PASSIVE_CLOSE",
+ [DCCP_PASSIVE_CLOSEREQ] = "PASSIVE_CLOSEREQ",
+ [DCCP_TIME_WAIT] = "TIME_WAIT",
+ [DCCP_CLOSED] = "CLOSED",
+ };
+
+ if (state >= DCCP_MAX_STATES)
+ return "INVALID STATE!";
+ else
+ return dccp_state_names[state];
+}
+#endif
+
void dccp_set_state(struct sock *sk, const int state)
{
const int oldstate = sk->sk_state;
@@ -146,30 +170,6 @@ const char *dccp_packet_name(const int type)
EXPORT_SYMBOL_GPL(dccp_packet_name);
-const char *dccp_state_name(const int state)
-{
- static const char *const dccp_state_names[] = {
- [DCCP_OPEN] = "OPEN",
- [DCCP_REQUESTING] = "REQUESTING",
- [DCCP_PARTOPEN] = "PARTOPEN",
- [DCCP_LISTEN] = "LISTEN",
- [DCCP_RESPOND] = "RESPOND",
- [DCCP_CLOSING] = "CLOSING",
- [DCCP_ACTIVE_CLOSEREQ] = "CLOSEREQ",
- [DCCP_PASSIVE_CLOSE] = "PASSIVE_CLOSE",
- [DCCP_PASSIVE_CLOSEREQ] = "PASSIVE_CLOSEREQ",
- [DCCP_TIME_WAIT] = "TIME_WAIT",
- [DCCP_CLOSED] = "CLOSED",
- };
-
- if (state >= DCCP_MAX_STATES)
- return "INVALID STATE!";
- else
- return dccp_state_names[state];
-}
-
-EXPORT_SYMBOL_GPL(dccp_state_name);
-
int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
{
struct dccp_sock *dp = dccp_sk(sk);
@@ -944,7 +944,7 @@ void dccp_close(struct sock *sk, long timeout)
if (data_was_unread) {
/* Unread data was tossed, send an appropriate Reset Code */
- DCCP_WARN("DCCP: ABORT -- %u bytes unread\n", data_was_unread);
+ DCCP_WARN("ABORT with %u bytes unread\n", data_was_unread);
dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
dccp_set_state(sk, DCCP_CLOSED);
} else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 0363bb95cc7d..a085dbcf5c7f 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -48,7 +48,6 @@
#include <net/dn_neigh.h>
#include <net/dn_route.h>
-static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev);
static int dn_neigh_construct(struct neighbour *);
static void dn_long_error_report(struct neighbour *, struct sk_buff *);
static void dn_short_error_report(struct neighbour *, struct sk_buff *);
@@ -93,6 +92,13 @@ static const struct neigh_ops dn_phase3_ops = {
.queue_xmit = dev_queue_xmit
};
+static u32 dn_neigh_hash(const void *pkey,
+ const struct net_device *dev,
+ __u32 hash_rnd)
+{
+ return jhash_2words(*(__u16 *)pkey, 0, hash_rnd);
+}
+
struct neigh_table dn_neigh_table = {
.family = PF_DECnet,
.entry_size = sizeof(struct dn_neigh),
@@ -122,11 +128,6 @@ struct neigh_table dn_neigh_table = {
.gc_thresh3 = 1024,
};
-static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev)
-{
- return jhash_2words(*(__u16 *)pkey, 0, dn_neigh_table.hash_rnd);
-}
-
static int dn_neigh_construct(struct neighbour *neigh)
{
struct net_device *dev = neigh->dev;
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
index baeb1eaf011b..2ef115277bea 100644
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -693,22 +693,22 @@ void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg)
aux = scp->accessdata.acc_userl;
*skb_put(skb, 1) = aux;
if (aux > 0)
- memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux);
+ memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux);
aux = scp->accessdata.acc_passl;
*skb_put(skb, 1) = aux;
if (aux > 0)
- memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux);
+ memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux);
aux = scp->accessdata.acc_accl;
*skb_put(skb, 1) = aux;
if (aux > 0)
- memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux);
+ memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux);
aux = (__u8)le16_to_cpu(scp->conndata_out.opt_optl);
*skb_put(skb, 1) = aux;
if (aux > 0)
- memcpy(skb_put(skb,aux), scp->conndata_out.opt_data, aux);
+ memcpy(skb_put(skb, aux), scp->conndata_out.opt_data, aux);
scp->persist = dn_nsp_persist(sk);
scp->persist_fxn = dn_nsp_retrans_conninit;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 6585ea6d1182..df0f3e54ff8a 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -132,7 +132,6 @@ static struct dst_ops dn_dst_ops = {
.negative_advice = dn_dst_negative_advice,
.link_failure = dn_dst_link_failure,
.update_pmtu = dn_dst_update_pmtu,
- .entries = ATOMIC_INIT(0),
};
static __inline__ unsigned dn_hash(__le16 src, __le16 dst)
@@ -1758,6 +1757,7 @@ void __init dn_route_init(void)
dn_dst_ops.kmem_cachep =
kmem_cache_create("dn_dst_cache", sizeof(struct dn_route), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
+ dst_entries_init(&dn_dst_ops);
setup_timer(&dn_route_timer, dn_dst_check_expire, 0);
dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ;
add_timer(&dn_route_timer);
@@ -1816,5 +1816,6 @@ void __exit dn_route_cleanup(void)
dn_run_flush(0);
proc_net_remove(&init_net, "decnet_cache");
+ dst_entries_destroy(&dn_dst_ops);
}
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index dc54bd0d083b..f8c1ae4b41f0 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -392,7 +392,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
dev_queue_xmit(skb);
dev_put(dev);
mutex_unlock(&econet_mutex);
- return(len);
+ return len;
out_free:
kfree_skb(skb);
@@ -637,7 +637,7 @@ static int econet_create(struct net *net, struct socket *sock, int protocol,
eo->num = protocol;
econet_insert_socket(&econet_sklist, sk);
- return(0);
+ return 0;
out:
return err;
}
@@ -1009,7 +1009,6 @@ static int __init aun_udp_initialise(void)
struct sockaddr_in sin;
skb_queue_head_init(&aun_queue);
- spin_lock_init(&aun_queue_lock);
setup_timer(&ab_cleanup_timer, ab_cleanup, 0);
ab_cleanup_timer.expires = jiffies + (HZ*2);
add_timer(&ab_cleanup_timer);
@@ -1167,7 +1166,6 @@ static int __init econet_proto_init(void)
goto out;
sock_register(&econet_family_ops);
#ifdef CONFIG_ECONET_AUNUDP
- spin_lock_init(&aun_queue_lock);
aun_udp_initialise();
#endif
#ifdef CONFIG_ECONET_NATIVE
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 215c83986a9d..f00ef2f1d814 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -367,7 +367,7 @@ struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count)
EXPORT_SYMBOL(alloc_etherdev_mq);
static size_t _format_mac_addr(char *buf, int buflen,
- const unsigned char *addr, int len)
+ const unsigned char *addr, int len)
{
int i;
char *cp = buf;
@@ -376,7 +376,7 @@ static size_t _format_mac_addr(char *buf, int buflen,
cp += scnprintf(cp, buflen - (cp - buf), "%02x", addr[i]);
if (i == len - 1)
break;
- cp += strlcpy(cp, ":", buflen - (cp - buf));
+ cp += scnprintf(cp, buflen - (cp - buf), ":");
}
return cp - buf;
}
@@ -386,7 +386,7 @@ ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len)
size_t l;
l = _format_mac_addr(buf, PAGE_SIZE, addr, len);
- l += strlcpy(buf + l, "\n", PAGE_SIZE - l);
- return ((ssize_t) l);
+ l += scnprintf(buf + l, PAGE_SIZE - l, "\n");
+ return (ssize_t)l;
}
EXPORT_SYMBOL(sysfs_format_mac);
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 7cd7760144f7..e848e6c062cd 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -215,9 +215,15 @@ config NET_IPIP
be inserted in and removed from the running kernel whenever you
want). Most people won't need this and can say N.
+config NET_IPGRE_DEMUX
+ tristate "IP: GRE demultiplexer"
+ help
+ This is helper module to demultiplex GRE packets on GRE version field criteria.
+ Required by ip_gre and pptp modules.
+
config NET_IPGRE
tristate "IP: GRE tunnels over IP"
- depends on IPV6 || IPV6=n
+ depends on (IPV6 || IPV6=n) && NET_IPGRE_DEMUX
help
Tunneling means encapsulating data of one protocol type within
another protocol and sending it over a channel that understands the
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 80ff87ce43aa..4978d22f9a75 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
obj-$(CONFIG_IP_MROUTE) += ipmr.o
obj-$(CONFIG_NET_IPIP) += ipip.o
+obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o
obj-$(CONFIG_NET_IPGRE) += ip_gre.o
obj-$(CONFIG_SYN_COOKIES) += syncookies.o
obj-$(CONFIG_INET_AH) += ah4.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 6a1100c25a9f..f581f77d1097 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -227,18 +227,16 @@ EXPORT_SYMBOL(inet_ehash_secret);
/*
* inet_ehash_secret must be set exactly once
- * Instead of using a dedicated spinlock, we (ab)use inetsw_lock
*/
void build_ehash_secret(void)
{
u32 rnd;
+
do {
get_random_bytes(&rnd, sizeof(rnd));
} while (rnd == 0);
- spin_lock_bh(&inetsw_lock);
- if (!inet_ehash_secret)
- inet_ehash_secret = rnd;
- spin_unlock_bh(&inetsw_lock);
+
+ cmpxchg(&inet_ehash_secret, 0, rnd);
}
EXPORT_SYMBOL(build_ehash_secret);
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 96c1955b3e2f..d8e540c5b071 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -55,7 +55,7 @@
* Stuart Cheshire : Metricom and grat arp fixes
* *** FOR 2.1 clean this up ***
* Lawrence V. Stefani: (08/12/96) Added FDDI support.
- * Alan Cox : Took the AP1000 nasty FDDI hack and
+ * Alan Cox : Took the AP1000 nasty FDDI hack and
* folded into the mainstream FDDI code.
* Ack spit, Linus how did you allow that
* one in...
@@ -120,14 +120,14 @@ EXPORT_SYMBOL(clip_tbl_hook);
#endif
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/netfilter_arp.h>
/*
* Interface to generic neighbour cache.
*/
-static u32 arp_hash(const void *pkey, const struct net_device *dev);
+static u32 arp_hash(const void *pkey, const struct net_device *dev, __u32 rnd);
static int arp_constructor(struct neighbour *neigh);
static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb);
static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb);
@@ -161,7 +161,7 @@ static const struct neigh_ops arp_direct_ops = {
.queue_xmit = dev_queue_xmit,
};
-const struct neigh_ops arp_broken_ops = {
+static const struct neigh_ops arp_broken_ops = {
.family = AF_INET,
.solicit = arp_solicit,
.error_report = arp_error_report,
@@ -170,35 +170,34 @@ const struct neigh_ops arp_broken_ops = {
.hh_output = dev_queue_xmit,
.queue_xmit = dev_queue_xmit,
};
-EXPORT_SYMBOL(arp_broken_ops);
struct neigh_table arp_tbl = {
- .family = AF_INET,
- .entry_size = sizeof(struct neighbour) + 4,
- .key_len = 4,
- .hash = arp_hash,
- .constructor = arp_constructor,
- .proxy_redo = parp_redo,
- .id = "arp_cache",
- .parms = {
- .tbl = &arp_tbl,
- .base_reachable_time = 30 * HZ,
- .retrans_time = 1 * HZ,
- .gc_staletime = 60 * HZ,
- .reachable_time = 30 * HZ,
- .delay_probe_time = 5 * HZ,
- .queue_len = 3,
- .ucast_probes = 3,
- .mcast_probes = 3,
- .anycast_delay = 1 * HZ,
- .proxy_delay = (8 * HZ) / 10,
- .proxy_qlen = 64,
- .locktime = 1 * HZ,
+ .family = AF_INET,
+ .entry_size = sizeof(struct neighbour) + 4,
+ .key_len = 4,
+ .hash = arp_hash,
+ .constructor = arp_constructor,
+ .proxy_redo = parp_redo,
+ .id = "arp_cache",
+ .parms = {
+ .tbl = &arp_tbl,
+ .base_reachable_time = 30 * HZ,
+ .retrans_time = 1 * HZ,
+ .gc_staletime = 60 * HZ,
+ .reachable_time = 30 * HZ,
+ .delay_probe_time = 5 * HZ,
+ .queue_len = 3,
+ .ucast_probes = 3,
+ .mcast_probes = 3,
+ .anycast_delay = 1 * HZ,
+ .proxy_delay = (8 * HZ) / 10,
+ .proxy_qlen = 64,
+ .locktime = 1 * HZ,
},
- .gc_interval = 30 * HZ,
- .gc_thresh1 = 128,
- .gc_thresh2 = 512,
- .gc_thresh3 = 1024,
+ .gc_interval = 30 * HZ,
+ .gc_thresh1 = 128,
+ .gc_thresh2 = 512,
+ .gc_thresh3 = 1024,
};
EXPORT_SYMBOL(arp_tbl);
@@ -226,14 +225,16 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir)
}
-static u32 arp_hash(const void *pkey, const struct net_device *dev)
+static u32 arp_hash(const void *pkey,
+ const struct net_device *dev,
+ __u32 hash_rnd)
{
- return jhash_2words(*(u32 *)pkey, dev->ifindex, arp_tbl.hash_rnd);
+ return jhash_2words(*(u32 *)pkey, dev->ifindex, hash_rnd);
}
static int arp_constructor(struct neighbour *neigh)
{
- __be32 addr = *(__be32*)neigh->primary_key;
+ __be32 addr = *(__be32 *)neigh->primary_key;
struct net_device *dev = neigh->dev;
struct in_device *in_dev;
struct neigh_parms *parms;
@@ -296,16 +297,19 @@ static int arp_constructor(struct neighbour *neigh)
neigh->ops = &arp_broken_ops;
neigh->output = neigh->ops->output;
return 0;
+#else
+ break;
#endif
- ;}
+ }
#endif
if (neigh->type == RTN_MULTICAST) {
neigh->nud_state = NUD_NOARP;
arp_mc_map(addr, neigh->ha, dev, 1);
- } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
+ } else if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) {
neigh->nud_state = NUD_NOARP;
memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
- } else if (neigh->type == RTN_BROADCAST || dev->flags&IFF_POINTOPOINT) {
+ } else if (neigh->type == RTN_BROADCAST ||
+ (dev->flags & IFF_POINTOPOINT)) {
neigh->nud_state = NUD_NOARP;
memcpy(neigh->ha, dev->broadcast, dev->addr_len);
}
@@ -315,7 +319,7 @@ static int arp_constructor(struct neighbour *neigh)
else
neigh->ops = &arp_generic_ops;
- if (neigh->nud_state&NUD_VALID)
+ if (neigh->nud_state & NUD_VALID)
neigh->output = neigh->ops->connected_output;
else
neigh->output = neigh->ops->output;
@@ -334,7 +338,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
__be32 saddr = 0;
u8 *dst_ha = NULL;
struct net_device *dev = neigh->dev;
- __be32 target = *(__be32*)neigh->primary_key;
+ __be32 target = *(__be32 *)neigh->primary_key;
int probes = atomic_read(&neigh->probes);
struct in_device *in_dev;
@@ -347,7 +351,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
default:
case 0: /* By default announce any local IP */
- if (skb && inet_addr_type(dev_net(dev), ip_hdr(skb)->saddr) == RTN_LOCAL)
+ if (skb && inet_addr_type(dev_net(dev),
+ ip_hdr(skb)->saddr) == RTN_LOCAL)
saddr = ip_hdr(skb)->saddr;
break;
case 1: /* Restrict announcements of saddr in same subnet */
@@ -369,16 +374,21 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
if (!saddr)
saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);
- if ((probes -= neigh->parms->ucast_probes) < 0) {
- if (!(neigh->nud_state&NUD_VALID))
- printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n");
+ probes -= neigh->parms->ucast_probes;
+ if (probes < 0) {
+ if (!(neigh->nud_state & NUD_VALID))
+ printk(KERN_DEBUG
+ "trying to ucast probe in NUD_INVALID\n");
dst_ha = neigh->ha;
read_lock_bh(&neigh->lock);
- } else if ((probes -= neigh->parms->app_probes) < 0) {
+ } else {
+ probes -= neigh->parms->app_probes;
+ if (probes < 0) {
#ifdef CONFIG_ARPD
- neigh_app_ns(neigh);
+ neigh_app_ns(neigh);
#endif
- return;
+ return;
+ }
}
arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
@@ -451,7 +461,8 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
* is allowed to use this function, it is scheduled to be removed. --ANK
*/
-static int arp_set_predefined(int addr_hint, unsigned char * haddr, __be32 paddr, struct net_device * dev)
+static int arp_set_predefined(int addr_hint, unsigned char *haddr,
+ __be32 paddr, struct net_device *dev)
{
switch (addr_hint) {
case RTN_LOCAL:
@@ -483,17 +494,16 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb)
paddr = skb_rtable(skb)->rt_gateway;
- if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, paddr, dev))
+ if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr,
+ paddr, dev))
return 0;
n = __neigh_lookup(&arp_tbl, &paddr, dev, 1);
if (n) {
n->used = jiffies;
- if (n->nud_state&NUD_VALID || neigh_event_send(n, skb) == 0) {
- read_lock_bh(&n->lock);
- memcpy(haddr, n->ha, dev->addr_len);
- read_unlock_bh(&n->lock);
+ if (n->nud_state & NUD_VALID || neigh_event_send(n, skb) == 0) {
+ neigh_ha_snapshot(haddr, n, dev);
neigh_release(n);
return 0;
}
@@ -515,13 +525,14 @@ int arp_bind_neighbour(struct dst_entry *dst)
return -EINVAL;
if (n == NULL) {
__be32 nexthop = ((struct rtable *)dst)->rt_gateway;
- if (dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT))
+ if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
nexthop = 0;
n = __neigh_lookup_errno(
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
- dev->type == ARPHRD_ATM ? clip_tbl_hook :
+ dev->type == ARPHRD_ATM ?
+ clip_tbl_hook :
#endif
- &arp_tbl, &nexthop, dev);
+ &arp_tbl, &nexthop, dev);
if (IS_ERR(n))
return PTR_ERR(n);
dst->neighbour = n;
@@ -543,8 +554,8 @@ static inline int arp_fwd_proxy(struct in_device *in_dev,
if (!IN_DEV_PROXY_ARP(in_dev))
return 0;
-
- if ((imi = IN_DEV_MEDIUM_ID(in_dev)) == 0)
+ imi = IN_DEV_MEDIUM_ID(in_dev);
+ if (imi == 0)
return 1;
if (imi == -1)
return 0;
@@ -555,7 +566,7 @@ static inline int arp_fwd_proxy(struct in_device *in_dev,
if (out_dev)
omi = IN_DEV_MEDIUM_ID(out_dev);
- return (omi != imi && omi != -1);
+ return omi != imi && omi != -1;
}
/*
@@ -685,7 +696,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
arp->ar_pln = 4;
arp->ar_op = htons(type);
- arp_ptr=(unsigned char *)(arp+1);
+ arp_ptr = (unsigned char *)(arp + 1);
memcpy(arp_ptr, src_hw, dev->addr_len);
arp_ptr += dev->addr_len;
@@ -735,9 +746,8 @@ void arp_send(int type, int ptype, __be32 dest_ip,
skb = arp_create(type, ptype, dest_ip, dev, src_ip,
dest_hw, src_hw, target_hw);
- if (skb == NULL) {
+ if (skb == NULL)
return;
- }
arp_xmit(skb);
}
@@ -815,7 +825,7 @@ static int arp_process(struct sk_buff *skb)
/*
* Extract fields
*/
- arp_ptr= (unsigned char *)(arp+1);
+ arp_ptr = (unsigned char *)(arp + 1);
sha = arp_ptr;
arp_ptr += dev->addr_len;
memcpy(&sip, arp_ptr, 4);
@@ -869,16 +879,17 @@ static int arp_process(struct sk_buff *skb)
addr_type = rt->rt_type;
if (addr_type == RTN_LOCAL) {
- int dont_send = 0;
+ int dont_send;
- if (!dont_send)
- dont_send |= arp_ignore(in_dev,sip,tip);
+ dont_send = arp_ignore(in_dev, sip, tip);
if (!dont_send && IN_DEV_ARPFILTER(in_dev))
- dont_send |= arp_filter(sip,tip,dev);
+ dont_send |= arp_filter(sip, tip, dev);
if (!dont_send) {
n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
if (n) {
- arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
+ arp_send(ARPOP_REPLY, ETH_P_ARP, sip,
+ dev, tip, sha, dev->dev_addr,
+ sha);
neigh_release(n);
}
}
@@ -887,8 +898,7 @@ static int arp_process(struct sk_buff *skb)
if (addr_type == RTN_UNICAST &&
(arp_fwd_proxy(in_dev, dev, rt) ||
arp_fwd_pvlan(in_dev, dev, rt, sip, tip) ||
- pneigh_lookup(&arp_tbl, net, &tip, dev, 0)))
- {
+ pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) {
n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
if (n)
neigh_release(n);
@@ -896,9 +906,12 @@ static int arp_process(struct sk_buff *skb)
if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED ||
skb->pkt_type == PACKET_HOST ||
in_dev->arp_parms->proxy_delay == 0) {
- arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
+ arp_send(ARPOP_REPLY, ETH_P_ARP, sip,
+ dev, tip, sha, dev->dev_addr,
+ sha);
} else {
- pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb);
+ pneigh_enqueue(&arp_tbl,
+ in_dev->arp_parms, skb);
return 0;
}
goto out;
@@ -939,7 +952,8 @@ static int arp_process(struct sk_buff *skb)
if (arp->ar_op != htons(ARPOP_REPLY) ||
skb->pkt_type != PACKET_HOST)
state = NUD_STALE;
- neigh_update(n, sha, state, override ? NEIGH_UPDATE_F_OVERRIDE : 0);
+ neigh_update(n, sha, state,
+ override ? NEIGH_UPDATE_F_OVERRIDE : 0);
neigh_release(n);
}
@@ -975,7 +989,8 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
arp->ar_pln != 4)
goto freeskb;
- if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (skb == NULL)
goto out_of_mem;
memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
@@ -1019,7 +1034,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
return -EINVAL;
if (!dev && (r->arp_flags & ATF_COM)) {
dev = dev_getbyhwaddr(net, r->arp_ha.sa_family,
- r->arp_ha.sa_data);
+ r->arp_ha.sa_data);
if (!dev)
return -ENODEV;
}
@@ -1033,7 +1048,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
}
static int arp_req_set(struct net *net, struct arpreq *r,
- struct net_device * dev)
+ struct net_device *dev)
{
__be32 ip;
struct neighbour *neigh;
@@ -1046,10 +1061,11 @@ static int arp_req_set(struct net *net, struct arpreq *r,
if (r->arp_flags & ATF_PERM)
r->arp_flags |= ATF_COM;
if (dev == NULL) {
- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip,
- .tos = RTO_ONLINK } } };
- struct rtable * rt;
- if ((err = ip_route_output_key(net, &rt, &fl)) != 0)
+ struct flowi fl = { .nl_u.ip4_u = { .daddr = ip,
+ .tos = RTO_ONLINK } };
+ struct rtable *rt;
+ err = ip_route_output_key(net, &rt, &fl);
+ if (err != 0)
return err;
dev = rt->dst.dev;
ip_rt_put(rt);
@@ -1083,9 +1099,9 @@ static int arp_req_set(struct net *net, struct arpreq *r,
unsigned state = NUD_STALE;
if (r->arp_flags & ATF_PERM)
state = NUD_PERMANENT;
- err = neigh_update(neigh, (r->arp_flags&ATF_COM) ?
+ err = neigh_update(neigh, (r->arp_flags & ATF_COM) ?
r->arp_ha.sa_data : NULL, state,
- NEIGH_UPDATE_F_OVERRIDE|
+ NEIGH_UPDATE_F_OVERRIDE |
NEIGH_UPDATE_F_ADMIN);
neigh_release(neigh);
}
@@ -1094,12 +1110,12 @@ static int arp_req_set(struct net *net, struct arpreq *r,
static unsigned arp_state_to_flags(struct neighbour *neigh)
{
- unsigned flags = 0;
if (neigh->nud_state&NUD_PERMANENT)
- flags = ATF_PERM|ATF_COM;
+ return ATF_PERM | ATF_COM;
else if (neigh->nud_state&NUD_VALID)
- flags = ATF_COM;
- return flags;
+ return ATF_COM;
+ else
+ return 0;
}
/*
@@ -1142,7 +1158,7 @@ static int arp_req_delete_public(struct net *net, struct arpreq *r,
}
static int arp_req_delete(struct net *net, struct arpreq *r,
- struct net_device * dev)
+ struct net_device *dev)
{
int err;
__be32 ip;
@@ -1153,10 +1169,11 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
if (dev == NULL) {
- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip,
- .tos = RTO_ONLINK } } };
- struct rtable * rt;
- if ((err = ip_route_output_key(net, &rt, &fl)) != 0)
+ struct flowi fl = { .nl_u.ip4_u = { .daddr = ip,
+ .tos = RTO_ONLINK } };
+ struct rtable *rt;
+ err = ip_route_output_key(net, &rt, &fl);
+ if (err != 0)
return err;
dev = rt->dst.dev;
ip_rt_put(rt);
@@ -1166,7 +1183,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
err = -ENXIO;
neigh = neigh_lookup(&arp_tbl, &ip, dev);
if (neigh) {
- if (neigh->nud_state&~NUD_NOARP)
+ if (neigh->nud_state & ~NUD_NOARP)
err = neigh_update(neigh, NULL, NUD_FAILED,
NEIGH_UPDATE_F_OVERRIDE|
NEIGH_UPDATE_F_ADMIN);
@@ -1186,24 +1203,24 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
struct net_device *dev = NULL;
switch (cmd) {
- case SIOCDARP:
- case SIOCSARP:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- case SIOCGARP:
- err = copy_from_user(&r, arg, sizeof(struct arpreq));
- if (err)
- return -EFAULT;
- break;
- default:
- return -EINVAL;
+ case SIOCDARP:
+ case SIOCSARP:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ case SIOCGARP:
+ err = copy_from_user(&r, arg, sizeof(struct arpreq));
+ if (err)
+ return -EFAULT;
+ break;
+ default:
+ return -EINVAL;
}
if (r.arp_pa.sa_family != AF_INET)
return -EPFNOSUPPORT;
if (!(r.arp_flags & ATF_PUBL) &&
- (r.arp_flags & (ATF_NETMASK|ATF_DONTPUB)))
+ (r.arp_flags & (ATF_NETMASK | ATF_DONTPUB)))
return -EINVAL;
if (!(r.arp_flags & ATF_NETMASK))
((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr =
@@ -1211,7 +1228,8 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
rtnl_lock();
if (r.arp_dev[0]) {
err = -ENODEV;
- if ((dev = __dev_get_by_name(net, r.arp_dev)) == NULL)
+ dev = __dev_get_by_name(net, r.arp_dev);
+ if (dev == NULL)
goto out;
/* Mmmm... It is wrong... ARPHRD_NETROM==0 */
@@ -1243,7 +1261,8 @@ out:
return err;
}
-static int arp_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
+static int arp_netdev_event(struct notifier_block *this, unsigned long event,
+ void *ptr)
{
struct net_device *dev = ptr;
@@ -1311,12 +1330,13 @@ static char *ax2asc2(ax25_address *a, char *buf)
for (n = 0, s = buf; n < 6; n++) {
c = (a->ax25_call[n] >> 1) & 0x7F;
- if (c != ' ') *s++ = c;
+ if (c != ' ')
+ *s++ = c;
}
*s++ = '-';
-
- if ((n = ((a->ax25_call[6] >> 1) & 0x0F)) > 9) {
+ n = (a->ax25_call[6] >> 1) & 0x0F;
+ if (n > 9) {
*s++ = '1';
n -= 10;
}
@@ -1325,10 +1345,9 @@ static char *ax2asc2(ax25_address *a, char *buf)
*s++ = '\0';
if (*buf == '\0' || *buf == '-')
- return "*";
+ return "*";
return buf;
-
}
#endif /* CONFIG_AX25 */
@@ -1408,10 +1427,10 @@ static void *arp_seq_start(struct seq_file *seq, loff_t *pos)
/* ------------------------------------------------------------------------ */
static const struct seq_operations arp_seq_ops = {
- .start = arp_seq_start,
- .next = neigh_seq_next,
- .stop = neigh_seq_stop,
- .show = arp_seq_show,
+ .start = arp_seq_start,
+ .next = neigh_seq_next,
+ .stop = neigh_seq_stop,
+ .show = arp_seq_show,
};
static int arp_seq_open(struct inode *inode, struct file *file)
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
index 721a8a37b45c..174be6caa5c8 100644
--- a/net/ipv4/datagram.c
+++ b/net/ipv4/datagram.c
@@ -73,6 +73,6 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
inet->inet_id = jiffies;
sk_dst_set(sk, &rt->dst);
- return(0);
+ return 0;
}
EXPORT_SYMBOL(ip4_datagram_connect);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index da14c49284f4..dc94b0316b78 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -209,7 +209,7 @@ static void inetdev_destroy(struct in_device *in_dev)
inet_free_ifa(ifa);
}
- dev->ip_ptr = NULL;
+ rcu_assign_pointer(dev->ip_ptr, NULL);
devinet_sysctl_unregister(in_dev);
neigh_parms_release(&arp_tbl, in_dev->arp_parms);
@@ -403,6 +403,9 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
return inet_insert_ifa(ifa);
}
+/* Caller must hold RCU or RTNL :
+ * We dont take a reference on found in_device
+ */
struct in_device *inetdev_by_index(struct net *net, int ifindex)
{
struct net_device *dev;
@@ -411,7 +414,7 @@ struct in_device *inetdev_by_index(struct net *net, int ifindex)
rcu_read_lock();
dev = dev_get_by_index_rcu(net, ifindex);
if (dev)
- in_dev = in_dev_get(dev);
+ in_dev = rcu_dereference_rtnl(dev->ip_ptr);
rcu_read_unlock();
return in_dev;
}
@@ -453,8 +456,6 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
goto errout;
}
- __in_dev_put(in_dev);
-
for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
ifap = &ifa->ifa_next) {
if (tb[IFA_LOCAL] &&
@@ -1059,7 +1060,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
switch (event) {
case NETDEV_REGISTER:
printk(KERN_DEBUG "inetdev_event: bug\n");
- dev->ip_ptr = NULL;
+ rcu_assign_pointer(dev->ip_ptr, NULL);
break;
case NETDEV_UP:
if (!inetdev_valid_mtu(dev->mtu))
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 7d02a9f999fa..36e27c2107de 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -147,35 +147,43 @@ static void fib_flush(struct net *net)
rt_cache_flush(net, -1);
}
-/*
- * Find the first device with a given source address.
+/**
+ * __ip_dev_find - find the first device with a given source address.
+ * @net: the net namespace
+ * @addr: the source address
+ * @devref: if true, take a reference on the found device
+ *
+ * If a caller uses devref=false, it should be protected by RCU, or RTNL
*/
-
-struct net_device * ip_dev_find(struct net *net, __be32 addr)
+struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)
{
- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
- struct fib_result res;
+ struct flowi fl = {
+ .nl_u = {
+ .ip4_u = {
+ .daddr = addr
+ }
+ },
+ .flags = FLOWI_FLAG_MATCH_ANY_IIF
+ };
+ struct fib_result res = { 0 };
struct net_device *dev = NULL;
- struct fib_table *local_table;
-#ifdef CONFIG_IP_MULTIPLE_TABLES
- res.r = NULL;
-#endif
-
- local_table = fib_get_table(net, RT_TABLE_LOCAL);
- if (!local_table || fib_table_lookup(local_table, &fl, &res))
+ rcu_read_lock();
+ if (fib_lookup(net, &fl, &res)) {
+ rcu_read_unlock();
return NULL;
+ }
if (res.type != RTN_LOCAL)
goto out;
dev = FIB_RES_DEV(res);
- if (dev)
+ if (dev && devref)
dev_hold(dev);
out:
- fib_res_put(&res);
+ rcu_read_unlock();
return dev;
}
-EXPORT_SYMBOL(ip_dev_find);
+EXPORT_SYMBOL(__ip_dev_find);
/*
* Find address type as if only "dev" was present in the system. If
@@ -202,11 +210,12 @@ static inline unsigned __inet_dev_addr_type(struct net *net,
local_table = fib_get_table(net, RT_TABLE_LOCAL);
if (local_table) {
ret = RTN_UNICAST;
- if (!fib_table_lookup(local_table, &fl, &res)) {
+ rcu_read_lock();
+ if (!fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) {
if (!dev || dev == res.fi->fib_dev)
ret = res.type;
- fib_res_put(&res);
}
+ rcu_read_unlock();
}
return ret;
}
@@ -220,30 +229,34 @@ EXPORT_SYMBOL(inet_addr_type);
unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
__be32 addr)
{
- return __inet_dev_addr_type(net, dev, addr);
+ return __inet_dev_addr_type(net, dev, addr);
}
EXPORT_SYMBOL(inet_dev_addr_type);
/* Given (packet source, input interface) and optional (dst, oif, tos):
- - (main) check, that source is valid i.e. not broadcast or our local
- address.
- - figure out what "logical" interface this packet arrived
- and calculate "specific destination" address.
- - check, that packet arrived from expected physical interface.
+ * - (main) check, that source is valid i.e. not broadcast or our local
+ * address.
+ * - figure out what "logical" interface this packet arrived
+ * and calculate "specific destination" address.
+ * - 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)
{
struct in_device *in_dev;
- struct flowi fl = { .nl_u = { .ip4_u =
- { .daddr = src,
- .saddr = dst,
- .tos = tos } },
- .mark = mark,
- .iif = oif };
-
+ struct flowi fl = {
+ .nl_u = {
+ .ip4_u = {
+ .daddr = src,
+ .saddr = dst,
+ .tos = tos
+ }
+ },
+ .mark = mark,
+ .iif = oif
+ };
struct fib_result res;
int no_addr, rpf, accept_local;
bool dev_match;
@@ -251,7 +264,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
struct net *net;
no_addr = rpf = accept_local = 0;
- rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
if (in_dev) {
no_addr = in_dev->ifa_list == NULL;
@@ -260,7 +272,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
if (mark && !IN_DEV_SRC_VMARK(in_dev))
fl.mark = 0;
}
- rcu_read_unlock();
if (in_dev == NULL)
goto e_inval;
@@ -270,7 +281,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
goto last_resort;
if (res.type != RTN_UNICAST) {
if (res.type != RTN_LOCAL || !accept_local)
- goto e_inval_res;
+ goto e_inval;
}
*spec_dst = FIB_RES_PREFSRC(res);
fib_combine_itag(itag, &res);
@@ -291,10 +302,8 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
#endif
if (dev_match) {
ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
- fib_res_put(&res);
return ret;
}
- fib_res_put(&res);
if (no_addr)
goto last_resort;
if (rpf == 1)
@@ -307,7 +316,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
*spec_dst = FIB_RES_PREFSRC(res);
ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
}
- fib_res_put(&res);
}
return ret;
@@ -318,8 +326,6 @@ last_resort:
*itag = 0;
return 0;
-e_inval_res:
- fib_res_put(&res);
e_inval:
return -EINVAL;
e_rpf:
@@ -472,9 +478,9 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt,
}
/*
- * Handle IP routing ioctl calls. These are used to manipulate the routing tables
+ * Handle IP routing ioctl calls.
+ * These are used to manipulate the routing tables
*/
-
int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
{
struct fib_config cfg;
@@ -518,7 +524,7 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
return -EINVAL;
}
-const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = {
+const struct nla_policy rtm_ipv4_policy[RTA_MAX + 1] = {
[RTA_DST] = { .type = NLA_U32 },
[RTA_SRC] = { .type = NLA_U32 },
[RTA_IIF] = { .type = NLA_U32 },
@@ -532,7 +538,7 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = {
};
static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct fib_config *cfg)
+ struct nlmsghdr *nlh, struct fib_config *cfg)
{
struct nlattr *attr;
int err, remaining;
@@ -687,12 +693,11 @@ out:
}
/* Prepare and feed intra-kernel routing request.
- Really, it should be netlink message, but :-( netlink
- can be not configured, so that we feed it directly
- to fib engine. It is legal, because all events occur
- only when netlink is already locked.
+ * Really, it should be netlink message, but :-( netlink
+ * can be not configured, so that we feed it directly
+ * to fib engine. It is legal, because all events occur
+ * only when netlink is already locked.
*/
-
static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa)
{
struct net *net = dev_net(ifa->ifa_dev->dev);
@@ -738,9 +743,9 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
struct in_ifaddr *prim = ifa;
__be32 mask = ifa->ifa_mask;
__be32 addr = ifa->ifa_local;
- __be32 prefix = ifa->ifa_address&mask;
+ __be32 prefix = ifa->ifa_address & mask;
- if (ifa->ifa_flags&IFA_F_SECONDARY) {
+ if (ifa->ifa_flags & IFA_F_SECONDARY) {
prim = inet_ifa_byprefix(in_dev, prefix, mask);
if (prim == NULL) {
printk(KERN_WARNING "fib_add_ifaddr: bug: prim == NULL\n");
@@ -750,22 +755,24 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
fib_magic(RTM_NEWROUTE, RTN_LOCAL, addr, 32, prim);
- if (!(dev->flags&IFF_UP))
+ if (!(dev->flags & IFF_UP))
return;
/* Add broadcast address, if it is explicitly assigned. */
if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF))
fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
- if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) &&
+ if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags & IFA_F_SECONDARY) &&
(prefix != addr || ifa->ifa_prefixlen < 32)) {
- fib_magic(RTM_NEWROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL :
- RTN_UNICAST, prefix, ifa->ifa_prefixlen, prim);
+ fib_magic(RTM_NEWROUTE,
+ dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST,
+ prefix, ifa->ifa_prefixlen, prim);
/* Add network specific broadcasts, when it takes a sense */
if (ifa->ifa_prefixlen < 31) {
fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix, 32, prim);
- fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix|~mask, 32, prim);
+ fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix | ~mask,
+ 32, prim);
}
}
}
@@ -776,17 +783,18 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
struct net_device *dev = in_dev->dev;
struct in_ifaddr *ifa1;
struct in_ifaddr *prim = ifa;
- __be32 brd = ifa->ifa_address|~ifa->ifa_mask;
- __be32 any = ifa->ifa_address&ifa->ifa_mask;
+ __be32 brd = ifa->ifa_address | ~ifa->ifa_mask;
+ __be32 any = ifa->ifa_address & ifa->ifa_mask;
#define LOCAL_OK 1
#define BRD_OK 2
#define BRD0_OK 4
#define BRD1_OK 8
unsigned ok = 0;
- if (!(ifa->ifa_flags&IFA_F_SECONDARY))
- fib_magic(RTM_DELROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL :
- RTN_UNICAST, any, ifa->ifa_prefixlen, prim);
+ if (!(ifa->ifa_flags & IFA_F_SECONDARY))
+ fib_magic(RTM_DELROUTE,
+ dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST,
+ any, ifa->ifa_prefixlen, prim);
else {
prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask);
if (prim == NULL) {
@@ -796,9 +804,9 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
}
/* Deletion is more complicated than add.
- We should take care of not to delete too much :-)
-
- Scan address list to be sure that addresses are really gone.
+ * We should take care of not to delete too much :-)
+ *
+ * Scan address list to be sure that addresses are really gone.
*/
for (ifa1 = in_dev->ifa_list; ifa1; ifa1 = ifa1->ifa_next) {
@@ -812,23 +820,23 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
ok |= BRD0_OK;
}
- if (!(ok&BRD_OK))
+ if (!(ok & BRD_OK))
fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
- if (!(ok&BRD1_OK))
+ if (!(ok & BRD1_OK))
fib_magic(RTM_DELROUTE, RTN_BROADCAST, brd, 32, prim);
- if (!(ok&BRD0_OK))
+ if (!(ok & BRD0_OK))
fib_magic(RTM_DELROUTE, RTN_BROADCAST, any, 32, prim);
- if (!(ok&LOCAL_OK)) {
+ if (!(ok & LOCAL_OK)) {
fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim);
/* Check, that this local address finally disappeared. */
if (inet_addr_type(dev_net(dev), ifa->ifa_local) != RTN_LOCAL) {
/* And the last, but not the least thing.
- We must flush stray FIB entries.
-
- First of all, we scan fib_info list searching
- for stray nexthop entries, then ignite fib_flush.
- */
+ * We must flush stray FIB entries.
+ *
+ * First of all, we scan fib_info list searching
+ * for stray nexthop entries, then ignite fib_flush.
+ */
if (fib_sync_down_addr(dev_net(dev), ifa->ifa_local))
fib_flush(dev_net(dev));
}
@@ -839,14 +847,20 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
#undef BRD1_OK
}
-static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
+static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb)
{
struct fib_result res;
- struct flowi fl = { .mark = frn->fl_mark,
- .nl_u = { .ip4_u = { .daddr = frn->fl_addr,
- .tos = frn->fl_tos,
- .scope = frn->fl_scope } } };
+ struct flowi fl = {
+ .mark = frn->fl_mark,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = frn->fl_addr,
+ .tos = frn->fl_tos,
+ .scope = frn->fl_scope
+ }
+ }
+ };
#ifdef CONFIG_IP_MULTIPLE_TABLES
res.r = NULL;
@@ -857,15 +871,16 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
local_bh_disable();
frn->tb_id = tb->tb_id;
- frn->err = fib_table_lookup(tb, &fl, &res);
+ rcu_read_lock();
+ frn->err = fib_table_lookup(tb, &fl, &res, FIB_LOOKUP_NOREF);
if (!frn->err) {
frn->prefixlen = res.prefixlen;
frn->nh_sel = res.nh_sel;
frn->type = res.type;
frn->scope = res.scope;
- fib_res_put(&res);
}
+ rcu_read_unlock();
local_bh_enable();
}
}
@@ -894,8 +909,8 @@ static void nl_fib_input(struct sk_buff *skb)
nl_fib_lookup(frn, tb);
- pid = NETLINK_CB(skb).pid; /* pid of sending process */
- NETLINK_CB(skb).pid = 0; /* from kernel */
+ pid = NETLINK_CB(skb).pid; /* pid of sending process */
+ NETLINK_CB(skb).pid = 0; /* from kernel */
NETLINK_CB(skb).dst_group = 0; /* unicast */
netlink_unicast(net->ipv4.fibnl, skb, pid, MSG_DONTWAIT);
}
@@ -942,7 +957,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
fib_del_ifaddr(ifa);
if (ifa->ifa_dev->ifa_list == NULL) {
/* Last address was deleted from this interface.
- Disable IP.
+ * Disable IP.
*/
fib_disable_ip(dev, 1, 0);
} else {
@@ -1001,16 +1016,15 @@ static struct notifier_block fib_netdev_notifier = {
static int __net_init ip_fib_net_init(struct net *net)
{
int err;
- unsigned int i;
+ size_t size = sizeof(struct hlist_head) * FIB_TABLE_HASHSZ;
- net->ipv4.fib_table_hash = kzalloc(
- sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL);
+ /* Avoid false sharing : Use at least a full cache line */
+ size = max_t(size_t, size, L1_CACHE_BYTES);
+
+ net->ipv4.fib_table_hash = kzalloc(size, GFP_KERNEL);
if (net->ipv4.fib_table_hash == NULL)
return -ENOMEM;
- for (i = 0; i < FIB_TABLE_HASHSZ; i++)
- INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]);
-
err = fib4_rules_init(net);
if (err < 0)
goto fail;
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 4ed7e0dea1bc..43e1c594ce8f 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -54,36 +54,37 @@ struct fib_node {
struct fib_alias fn_embedded_alias;
};
-struct fn_zone {
- struct fn_zone *fz_next; /* Next not empty zone */
- struct hlist_head *fz_hash; /* Hash table pointer */
- int fz_nent; /* Number of entries */
+#define EMBEDDED_HASH_SIZE (L1_CACHE_BYTES / sizeof(struct hlist_head))
- int fz_divisor; /* Hash divisor */
+struct fn_zone {
+ struct fn_zone __rcu *fz_next; /* Next not empty zone */
+ struct hlist_head __rcu *fz_hash; /* Hash table pointer */
+ seqlock_t fz_lock;
u32 fz_hashmask; /* (fz_divisor - 1) */
-#define FZ_HASHMASK(fz) ((fz)->fz_hashmask)
- int fz_order; /* Zone order */
- __be32 fz_mask;
+ u8 fz_order; /* Zone order (0..32) */
+ u8 fz_revorder; /* 32 - fz_order */
+ __be32 fz_mask; /* inet_make_mask(order) */
#define FZ_MASK(fz) ((fz)->fz_mask)
-};
-/* NOTE. On fast computers evaluation of fz_hashmask and fz_mask
- * can be cheaper than memory lookup, so that FZ_* macros are used.
- */
+ struct hlist_head fz_embedded_hash[EMBEDDED_HASH_SIZE];
+
+ int fz_nent; /* Number of entries */
+ int fz_divisor; /* Hash size (mask+1) */
+};
struct fn_hash {
- struct fn_zone *fn_zones[33];
- struct fn_zone *fn_zone_list;
+ struct fn_zone *fn_zones[33];
+ struct fn_zone __rcu *fn_zone_list;
};
static inline u32 fn_hash(__be32 key, struct fn_zone *fz)
{
- u32 h = ntohl(key)>>(32 - fz->fz_order);
+ u32 h = ntohl(key) >> fz->fz_revorder;
h ^= (h>>20);
h ^= (h>>10);
h ^= (h>>5);
- h &= FZ_HASHMASK(fz);
+ h &= fz->fz_hashmask;
return h;
}
@@ -92,7 +93,6 @@ static inline __be32 fz_key(__be32 dst, struct fn_zone *fz)
return dst & FZ_MASK(fz);
}
-static DEFINE_RWLOCK(fib_hash_lock);
static unsigned int fib_hash_genid;
#define FZ_MAX_DIVISOR ((PAGE_SIZE<<MAX_ORDER) / sizeof(struct hlist_head))
@@ -101,12 +101,11 @@ static struct hlist_head *fz_hash_alloc(int divisor)
{
unsigned long size = divisor * sizeof(struct hlist_head);
- if (size <= PAGE_SIZE) {
+ if (size <= PAGE_SIZE)
return kzalloc(size, GFP_KERNEL);
- } else {
- return (struct hlist_head *)
- __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(size));
- }
+
+ return (struct hlist_head *)
+ __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(size));
}
/* The fib hash lock must be held when this is called. */
@@ -121,12 +120,12 @@ static inline void fn_rebuild_zone(struct fn_zone *fz,
struct fib_node *f;
hlist_for_each_entry_safe(f, node, n, &old_ht[i], fn_hash) {
- struct hlist_head *new_head;
+ struct hlist_head __rcu *new_head;
- hlist_del(&f->fn_hash);
+ hlist_del_rcu(&f->fn_hash);
new_head = &fz->fz_hash[fn_hash(f->fn_key, fz)];
- hlist_add_head(&f->fn_hash, new_head);
+ hlist_add_head_rcu(&f->fn_hash, new_head);
}
}
}
@@ -147,14 +146,14 @@ static void fn_rehash_zone(struct fn_zone *fz)
int old_divisor, new_divisor;
u32 new_hashmask;
- old_divisor = fz->fz_divisor;
+ new_divisor = old_divisor = fz->fz_divisor;
switch (old_divisor) {
- case 16:
- new_divisor = 256;
+ case EMBEDDED_HASH_SIZE:
+ new_divisor *= EMBEDDED_HASH_SIZE;
break;
- case 256:
- new_divisor = 1024;
+ case EMBEDDED_HASH_SIZE*EMBEDDED_HASH_SIZE:
+ new_divisor *= (EMBEDDED_HASH_SIZE/2);
break;
default:
if ((old_divisor << 1) > FZ_MAX_DIVISOR) {
@@ -175,31 +174,55 @@ static void fn_rehash_zone(struct fn_zone *fz)
ht = fz_hash_alloc(new_divisor);
if (ht) {
- write_lock_bh(&fib_hash_lock);
+ struct fn_zone nfz;
+
+ memcpy(&nfz, fz, sizeof(nfz));
+
+ write_seqlock_bh(&fz->fz_lock);
old_ht = fz->fz_hash;
- fz->fz_hash = ht;
+ nfz.fz_hash = ht;
+ nfz.fz_hashmask = new_hashmask;
+ nfz.fz_divisor = new_divisor;
+ fn_rebuild_zone(&nfz, old_ht, old_divisor);
+ fib_hash_genid++;
+ rcu_assign_pointer(fz->fz_hash, ht);
fz->fz_hashmask = new_hashmask;
fz->fz_divisor = new_divisor;
- fn_rebuild_zone(fz, old_ht, old_divisor);
- fib_hash_genid++;
- write_unlock_bh(&fib_hash_lock);
+ write_sequnlock_bh(&fz->fz_lock);
- fz_hash_free(old_ht, old_divisor);
+ if (old_ht != fz->fz_embedded_hash) {
+ synchronize_rcu();
+ fz_hash_free(old_ht, old_divisor);
+ }
}
}
-static inline void fn_free_node(struct fib_node * f)
+static void fn_free_node_rcu(struct rcu_head *head)
{
+ struct fib_node *f = container_of(head, struct fib_node, fn_embedded_alias.rcu);
+
kmem_cache_free(fn_hash_kmem, f);
}
+static inline void fn_free_node(struct fib_node *f)
+{
+ call_rcu(&f->fn_embedded_alias.rcu, fn_free_node_rcu);
+}
+
+static void fn_free_alias_rcu(struct rcu_head *head)
+{
+ struct fib_alias *fa = container_of(head, struct fib_alias, rcu);
+
+ kmem_cache_free(fn_alias_kmem, fa);
+}
+
static inline void fn_free_alias(struct fib_alias *fa, struct fib_node *f)
{
fib_release_info(fa->fa_info);
if (fa == &f->fn_embedded_alias)
fa->fa_info = NULL;
else
- kmem_cache_free(fn_alias_kmem, fa);
+ call_rcu(&fa->rcu, fn_free_alias_rcu);
}
static struct fn_zone *
@@ -210,68 +233,71 @@ fn_new_zone(struct fn_hash *table, int z)
if (!fz)
return NULL;
- if (z) {
- fz->fz_divisor = 16;
- } else {
- fz->fz_divisor = 1;
- }
- fz->fz_hashmask = (fz->fz_divisor - 1);
- fz->fz_hash = fz_hash_alloc(fz->fz_divisor);
- if (!fz->fz_hash) {
- kfree(fz);
- return NULL;
- }
+ seqlock_init(&fz->fz_lock);
+ fz->fz_divisor = z ? EMBEDDED_HASH_SIZE : 1;
+ fz->fz_hashmask = fz->fz_divisor - 1;
+ fz->fz_hash = fz->fz_embedded_hash;
fz->fz_order = z;
+ fz->fz_revorder = 32 - z;
fz->fz_mask = inet_make_mask(z);
/* Find the first not empty zone with more specific mask */
- for (i=z+1; i<=32; i++)
+ for (i = z + 1; i <= 32; i++)
if (table->fn_zones[i])
break;
- write_lock_bh(&fib_hash_lock);
- if (i>32) {
+ if (i > 32) {
/* No more specific masks, we are the first. */
- fz->fz_next = table->fn_zone_list;
- table->fn_zone_list = fz;
+ rcu_assign_pointer(fz->fz_next,
+ rtnl_dereference(table->fn_zone_list));
+ rcu_assign_pointer(table->fn_zone_list, fz);
} else {
- fz->fz_next = table->fn_zones[i]->fz_next;
- table->fn_zones[i]->fz_next = fz;
+ rcu_assign_pointer(fz->fz_next,
+ rtnl_dereference(table->fn_zones[i]->fz_next));
+ rcu_assign_pointer(table->fn_zones[i]->fz_next, fz);
}
table->fn_zones[z] = fz;
fib_hash_genid++;
- write_unlock_bh(&fib_hash_lock);
return fz;
}
int fib_table_lookup(struct fib_table *tb,
- const struct flowi *flp, struct fib_result *res)
+ const struct flowi *flp, struct fib_result *res,
+ int fib_flags)
{
int err;
struct fn_zone *fz;
struct fn_hash *t = (struct fn_hash *)tb->tb_data;
- read_lock(&fib_hash_lock);
- for (fz = t->fn_zone_list; fz; fz = fz->fz_next) {
- struct hlist_head *head;
+ rcu_read_lock();
+ for (fz = rcu_dereference(t->fn_zone_list);
+ fz != NULL;
+ fz = rcu_dereference(fz->fz_next)) {
+ struct hlist_head __rcu *head;
struct hlist_node *node;
struct fib_node *f;
- __be32 k = fz_key(flp->fl4_dst, fz);
+ __be32 k;
+ unsigned int seq;
- head = &fz->fz_hash[fn_hash(k, fz)];
- hlist_for_each_entry(f, node, head, fn_hash) {
- if (f->fn_key != k)
- continue;
+ do {
+ seq = read_seqbegin(&fz->fz_lock);
+ k = fz_key(flp->fl4_dst, fz);
+
+ head = &fz->fz_hash[fn_hash(k, fz)];
+ hlist_for_each_entry_rcu(f, node, head, fn_hash) {
+ if (f->fn_key != k)
+ continue;
- err = fib_semantic_match(&f->fn_alias,
+ err = fib_semantic_match(&f->fn_alias,
flp, res,
- fz->fz_order);
- if (err <= 0)
- goto out;
- }
+ fz->fz_order, fib_flags);
+ if (err <= 0)
+ goto out;
+ }
+ } while (read_seqretry(&fz->fz_lock, seq));
}
err = 1;
out:
- read_unlock(&fib_hash_lock);
+ rcu_read_unlock();
return err;
}
@@ -293,11 +319,11 @@ void fib_table_select_default(struct fib_table *tb,
last_resort = NULL;
order = -1;
- read_lock(&fib_hash_lock);
- hlist_for_each_entry(f, node, &fz->fz_hash[0], fn_hash) {
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(f, node, &fz->fz_hash[0], fn_hash) {
struct fib_alias *fa;
- list_for_each_entry(fa, &f->fn_alias, fa_list) {
+ list_for_each_entry_rcu(fa, &f->fn_alias, fa_list) {
struct fib_info *next_fi = fa->fa_info;
if (fa->fa_scope != res->scope ||
@@ -309,7 +335,8 @@ void fib_table_select_default(struct fib_table *tb,
if (!next_fi->fib_nh[0].nh_gw ||
next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
continue;
- fa->fa_state |= FA_S_ACCESSED;
+
+ fib_alias_accessed(fa);
if (fi == NULL) {
if (next_fi != res->fi)
@@ -341,7 +368,7 @@ void fib_table_select_default(struct fib_table *tb,
fib_result_assign(res, last_resort);
tb->tb_default = last_idx;
out:
- read_unlock(&fib_hash_lock);
+ rcu_read_unlock();
}
/* Insert node F to FZ. */
@@ -349,7 +376,7 @@ static inline void fib_insert_node(struct fn_zone *fz, struct fib_node *f)
{
struct hlist_head *head = &fz->fz_hash[fn_hash(f->fn_key, fz)];
- hlist_add_head(&f->fn_hash, head);
+ hlist_add_head_rcu(&f->fn_hash, head);
}
/* Return the node in FZ matching KEY. */
@@ -359,7 +386,7 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key)
struct hlist_node *node;
struct fib_node *f;
- hlist_for_each_entry(f, node, head, fn_hash) {
+ hlist_for_each_entry_rcu(f, node, head, fn_hash) {
if (f->fn_key == key)
return f;
}
@@ -367,6 +394,17 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key)
return NULL;
}
+
+static struct fib_alias *fib_fast_alloc(struct fib_node *f)
+{
+ struct fib_alias *fa = &f->fn_embedded_alias;
+
+ if (fa->fa_info != NULL)
+ fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
+ return fa;
+}
+
+/* Caller must hold RTNL. */
int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
{
struct fn_hash *table = (struct fn_hash *) tb->tb_data;
@@ -451,7 +489,6 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
}
if (cfg->fc_nlflags & NLM_F_REPLACE) {
- struct fib_info *fi_drop;
u8 state;
fa = fa_first;
@@ -460,21 +497,25 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
err = 0;
goto out;
}
- write_lock_bh(&fib_hash_lock);
- fi_drop = fa->fa_info;
- fa->fa_info = fi;
- fa->fa_type = cfg->fc_type;
- fa->fa_scope = cfg->fc_scope;
+ err = -ENOBUFS;
+ new_fa = fib_fast_alloc(f);
+ if (new_fa == NULL)
+ goto out;
+
+ new_fa->fa_tos = fa->fa_tos;
+ new_fa->fa_info = fi;
+ new_fa->fa_type = cfg->fc_type;
+ new_fa->fa_scope = cfg->fc_scope;
state = fa->fa_state;
- fa->fa_state &= ~FA_S_ACCESSED;
+ new_fa->fa_state = state & ~FA_S_ACCESSED;
fib_hash_genid++;
- write_unlock_bh(&fib_hash_lock);
+ list_replace_rcu(&fa->fa_list, &new_fa->fa_list);
- fib_release_info(fi_drop);
+ fn_free_alias(fa, f);
if (state & FA_S_ACCESSED)
rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
- rtmsg_fib(RTM_NEWROUTE, key, fa, cfg->fc_dst_len, tb->tb_id,
- &cfg->fc_nlinfo, NLM_F_REPLACE);
+ rtmsg_fib(RTM_NEWROUTE, key, new_fa, cfg->fc_dst_len,
+ tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
return 0;
}
@@ -506,12 +547,10 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
f = new_f;
}
- new_fa = &f->fn_embedded_alias;
- if (new_fa->fa_info != NULL) {
- new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
- if (new_fa == NULL)
- goto out;
- }
+ new_fa = fib_fast_alloc(f);
+ if (new_fa == NULL)
+ goto out;
+
new_fa->fa_info = fi;
new_fa->fa_tos = tos;
new_fa->fa_type = cfg->fc_type;
@@ -522,13 +561,11 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
* Insert new entry to the list.
*/
- write_lock_bh(&fib_hash_lock);
if (new_f)
fib_insert_node(fz, new_f);
- list_add_tail(&new_fa->fa_list,
+ list_add_tail_rcu(&new_fa->fa_list,
(fa ? &fa->fa_list : &f->fn_alias));
fib_hash_genid++;
- write_unlock_bh(&fib_hash_lock);
if (new_f)
fz->fz_nent++;
@@ -603,14 +640,12 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
tb->tb_id, &cfg->fc_nlinfo, 0);
kill_fn = 0;
- write_lock_bh(&fib_hash_lock);
- list_del(&fa->fa_list);
+ list_del_rcu(&fa->fa_list);
if (list_empty(&f->fn_alias)) {
- hlist_del(&f->fn_hash);
+ hlist_del_rcu(&f->fn_hash);
kill_fn = 1;
}
fib_hash_genid++;
- write_unlock_bh(&fib_hash_lock);
if (fa->fa_state & FA_S_ACCESSED)
rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
@@ -641,14 +676,12 @@ static int fn_flush_list(struct fn_zone *fz, int idx)
struct fib_info *fi = fa->fa_info;
if (fi && (fi->fib_flags&RTNH_F_DEAD)) {
- write_lock_bh(&fib_hash_lock);
- list_del(&fa->fa_list);
+ list_del_rcu(&fa->fa_list);
if (list_empty(&f->fn_alias)) {
- hlist_del(&f->fn_hash);
+ hlist_del_rcu(&f->fn_hash);
kill_f = 1;
}
fib_hash_genid++;
- write_unlock_bh(&fib_hash_lock);
fn_free_alias(fa, f);
found++;
@@ -662,13 +695,16 @@ static int fn_flush_list(struct fn_zone *fz, int idx)
return found;
}
+/* caller must hold RTNL. */
int fib_table_flush(struct fib_table *tb)
{
struct fn_hash *table = (struct fn_hash *) tb->tb_data;
struct fn_zone *fz;
int found = 0;
- for (fz = table->fn_zone_list; fz; fz = fz->fz_next) {
+ for (fz = rtnl_dereference(table->fn_zone_list);
+ fz != NULL;
+ fz = rtnl_dereference(fz->fz_next)) {
int i;
for (i = fz->fz_divisor - 1; i >= 0; i--)
@@ -690,10 +726,10 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb,
s_i = cb->args[4];
i = 0;
- hlist_for_each_entry(f, node, head, fn_hash) {
+ hlist_for_each_entry_rcu(f, node, head, fn_hash) {
struct fib_alias *fa;
- list_for_each_entry(fa, &f->fn_alias, fa_list) {
+ list_for_each_entry_rcu(fa, &f->fn_alias, fa_list) {
if (i < s_i)
goto next;
@@ -711,7 +747,7 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb,
cb->args[4] = i;
return -1;
}
- next:
+next:
i++;
}
}
@@ -746,23 +782,26 @@ fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb,
int fib_table_dump(struct fib_table *tb, struct sk_buff *skb,
struct netlink_callback *cb)
{
- int m, s_m;
+ int m = 0, s_m;
struct fn_zone *fz;
struct fn_hash *table = (struct fn_hash *)tb->tb_data;
s_m = cb->args[2];
- read_lock(&fib_hash_lock);
- for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) {
- if (m < s_m) continue;
+ rcu_read_lock();
+ for (fz = rcu_dereference(table->fn_zone_list);
+ fz != NULL;
+ fz = rcu_dereference(fz->fz_next), m++) {
+ if (m < s_m)
+ continue;
if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) {
cb->args[2] = m;
- read_unlock(&fib_hash_lock);
+ rcu_read_unlock();
return -1;
}
memset(&cb->args[3], 0,
sizeof(cb->args) - 3*sizeof(cb->args[0]));
}
- read_unlock(&fib_hash_lock);
+ rcu_read_unlock();
cb->args[2] = m;
return skb->len;
}
@@ -825,8 +864,9 @@ static struct fib_alias *fib_get_first(struct seq_file *seq)
iter->genid = fib_hash_genid;
iter->valid = 1;
- for (iter->zone = table->fn_zone_list; iter->zone;
- iter->zone = iter->zone->fz_next) {
+ for (iter->zone = rcu_dereference(table->fn_zone_list);
+ iter->zone != NULL;
+ iter->zone = rcu_dereference(iter->zone->fz_next)) {
int maxslot;
if (!iter->zone->fz_nent)
@@ -911,7 +951,7 @@ static struct fib_alias *fib_get_next(struct seq_file *seq)
}
}
- iter->zone = iter->zone->fz_next;
+ iter->zone = rcu_dereference(iter->zone->fz_next);
if (!iter->zone)
goto out;
@@ -950,11 +990,11 @@ static struct fib_alias *fib_get_idx(struct seq_file *seq, loff_t pos)
}
static void *fib_seq_start(struct seq_file *seq, loff_t *pos)
- __acquires(fib_hash_lock)
+ __acquires(RCU)
{
void *v = NULL;
- read_lock(&fib_hash_lock);
+ rcu_read_lock();
if (fib_get_table(seq_file_net(seq), RT_TABLE_MAIN))
v = *pos ? fib_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
return v;
@@ -967,15 +1007,16 @@ static void *fib_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void fib_seq_stop(struct seq_file *seq, void *v)
- __releases(fib_hash_lock)
+ __releases(RCU)
{
- read_unlock(&fib_hash_lock);
+ rcu_read_unlock();
}
static unsigned fib_flag_trans(int type, __be32 mask, struct fib_info *fi)
{
static const unsigned type2flags[RTN_MAX + 1] = {
- [7] = RTF_REJECT, [8] = RTF_REJECT,
+ [7] = RTF_REJECT,
+ [8] = RTF_REJECT,
};
unsigned flags = type2flags[type];
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index 637b133973bd..a29edf2219c8 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -12,17 +12,22 @@ struct fib_alias {
u8 fa_type;
u8 fa_scope;
u8 fa_state;
-#ifdef CONFIG_IP_FIB_TRIE
struct rcu_head rcu;
-#endif
};
#define FA_S_ACCESSED 0x01
+/* Dont write on fa_state unless needed, to keep it shared on all cpus */
+static inline void fib_alias_accessed(struct fib_alias *fa)
+{
+ if (!(fa->fa_state & FA_S_ACCESSED))
+ fa->fa_state |= FA_S_ACCESSED;
+}
+
/* Exported by fib_semantics.c */
extern int fib_semantic_match(struct list_head *head,
const struct flowi *flp,
- struct fib_result *res, int prefixlen);
+ struct fib_result *res, int prefixlen, int fib_flags);
extern void fib_release_info(struct fib_info *);
extern struct fib_info *fib_create_info(struct fib_config *cfg);
extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi);
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 76daeb5ff564..7981a24f5c7b 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -6,7 +6,7 @@
* IPv4 Forwarding Information Base: policy rules.
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
- * Thomas Graf <tgraf@suug.ch>
+ * Thomas Graf <tgraf@suug.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -14,7 +14,7 @@
* 2 of the License, or (at your option) any later version.
*
* Fixes:
- * Rani Assaf : local_rule cannot be deleted
+ * Rani Assaf : local_rule cannot be deleted
* Marc Boucher : routing by fwmark
*/
@@ -32,8 +32,7 @@
#include <net/ip_fib.h>
#include <net/fib_rules.h>
-struct fib4_rule
-{
+struct fib4_rule {
struct fib_rule common;
u8 dst_len;
u8 src_len;
@@ -58,6 +57,7 @@ int fib_lookup(struct net *net, struct flowi *flp, struct fib_result *res)
{
struct fib_lookup_arg arg = {
.result = res,
+ .flags = FIB_LOOKUP_NOREF,
};
int err;
@@ -91,10 +91,11 @@ static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp,
goto errout;
}
- if ((tbl = fib_get_table(rule->fr_net, rule->table)) == NULL)
+ tbl = fib_get_table(rule->fr_net, rule->table);
+ if (!tbl)
goto errout;
- err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result);
+ err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result, arg->flags);
if (err > 0)
err = -EAGAIN;
errout:
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 20f09c5b31e8..3e0da3ef6116 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -60,21 +60,30 @@ static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE];
static DEFINE_SPINLOCK(fib_multipath_lock);
-#define for_nexthops(fi) { int nhsel; const struct fib_nh * nh; \
-for (nhsel=0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
-
-#define change_nexthops(fi) { int nhsel; struct fib_nh *nexthop_nh; \
-for (nhsel=0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nexthop_nh++, nhsel++)
+#define for_nexthops(fi) { \
+ int nhsel; const struct fib_nh *nh; \
+ for (nhsel = 0, nh = (fi)->fib_nh; \
+ nhsel < (fi)->fib_nhs; \
+ nh++, nhsel++)
+
+#define change_nexthops(fi) { \
+ int nhsel; struct fib_nh *nexthop_nh; \
+ for (nhsel = 0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \
+ nhsel < (fi)->fib_nhs; \
+ nexthop_nh++, nhsel++)
#else /* CONFIG_IP_ROUTE_MULTIPATH */
/* Hope, that gcc will optimize it to get rid of dummy loop */
-#define for_nexthops(fi) { int nhsel = 0; const struct fib_nh * nh = (fi)->fib_nh; \
-for (nhsel=0; nhsel < 1; nhsel++)
+#define for_nexthops(fi) { \
+ int nhsel; const struct fib_nh *nh = (fi)->fib_nh; \
+ for (nhsel = 0; nhsel < 1; nhsel++)
-#define change_nexthops(fi) { int nhsel = 0; struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \
-for (nhsel=0; nhsel < 1; nhsel++)
+#define change_nexthops(fi) { \
+ int nhsel; \
+ struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \
+ for (nhsel = 0; nhsel < 1; nhsel++)
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
@@ -86,63 +95,70 @@ static const struct
int error;
u8 scope;
} fib_props[RTN_MAX + 1] = {
- {
+ [RTN_UNSPEC] = {
.error = 0,
.scope = RT_SCOPE_NOWHERE,
- }, /* RTN_UNSPEC */
- {
+ },
+ [RTN_UNICAST] = {
.error = 0,
.scope = RT_SCOPE_UNIVERSE,
- }, /* RTN_UNICAST */
- {
+ },
+ [RTN_LOCAL] = {
.error = 0,
.scope = RT_SCOPE_HOST,
- }, /* RTN_LOCAL */
- {
+ },
+ [RTN_BROADCAST] = {
.error = 0,
.scope = RT_SCOPE_LINK,
- }, /* RTN_BROADCAST */
- {
+ },
+ [RTN_ANYCAST] = {
.error = 0,
.scope = RT_SCOPE_LINK,
- }, /* RTN_ANYCAST */
- {
+ },
+ [RTN_MULTICAST] = {
.error = 0,
.scope = RT_SCOPE_UNIVERSE,
- }, /* RTN_MULTICAST */
- {
+ },
+ [RTN_BLACKHOLE] = {
.error = -EINVAL,
.scope = RT_SCOPE_UNIVERSE,
- }, /* RTN_BLACKHOLE */
- {
+ },
+ [RTN_UNREACHABLE] = {
.error = -EHOSTUNREACH,
.scope = RT_SCOPE_UNIVERSE,
- }, /* RTN_UNREACHABLE */
- {
+ },
+ [RTN_PROHIBIT] = {
.error = -EACCES,
.scope = RT_SCOPE_UNIVERSE,
- }, /* RTN_PROHIBIT */
- {
+ },
+ [RTN_THROW] = {
.error = -EAGAIN,
.scope = RT_SCOPE_UNIVERSE,
- }, /* RTN_THROW */
- {
+ },
+ [RTN_NAT] = {
.error = -EINVAL,
.scope = RT_SCOPE_NOWHERE,
- }, /* RTN_NAT */
- {
+ },
+ [RTN_XRESOLVE] = {
.error = -EINVAL,
.scope = RT_SCOPE_NOWHERE,
- }, /* RTN_XRESOLVE */
+ },
};
/* Release a nexthop info record */
+static void free_fib_info_rcu(struct rcu_head *head)
+{
+ struct fib_info *fi = container_of(head, struct fib_info, rcu);
+
+ kfree(fi);
+}
+
void free_fib_info(struct fib_info *fi)
{
if (fi->fib_dead == 0) {
- printk(KERN_WARNING "Freeing alive fib_info %p\n", fi);
+ pr_warning("Freeing alive fib_info %p\n", fi);
return;
}
change_nexthops(fi) {
@@ -152,7 +168,7 @@ void free_fib_info(struct fib_info *fi)
} endfor_nexthops(fi);
fib_info_cnt--;
release_net(fi->fib_net);
- kfree(fi);
+ call_rcu(&fi->rcu, free_fib_info_rcu);
}
void fib_release_info(struct fib_info *fi)
@@ -173,7 +189,7 @@ void fib_release_info(struct fib_info *fi)
spin_unlock_bh(&fib_info_lock);
}
-static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi)
+static inline int nh_comp(const struct fib_info *fi, const struct fib_info *ofi)
{
const struct fib_nh *onh = ofi->fib_nh;
@@ -187,7 +203,7 @@ static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *
#ifdef CONFIG_NET_CLS_ROUTE
nh->nh_tclassid != onh->nh_tclassid ||
#endif
- ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD))
+ ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD))
return -1;
onh++;
} endfor_nexthops(fi);
@@ -238,7 +254,7 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi)
nfi->fib_priority == fi->fib_priority &&
memcmp(nfi->fib_metrics, fi->fib_metrics,
sizeof(fi->fib_metrics)) == 0 &&
- ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 &&
+ ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 &&
(nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0))
return fi;
}
@@ -247,9 +263,8 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi)
}
/* Check, that the gateway is already configured.
- Used only by redirect accept routine.
+ * Used only by redirect accept routine.
*/
-
int ip_fib_check_default(__be32 gw, struct net_device *dev)
{
struct hlist_head *head;
@@ -264,7 +279,7 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev)
hlist_for_each_entry(nh, node, head, nh_hash) {
if (nh->nh_dev == dev &&
nh->nh_gw == gw &&
- !(nh->nh_flags&RTNH_F_DEAD)) {
+ !(nh->nh_flags & RTNH_F_DEAD)) {
spin_unlock(&fib_info_lock);
return 0;
}
@@ -362,10 +377,10 @@ int fib_detect_death(struct fib_info *fi, int order,
}
if (state == NUD_REACHABLE)
return 0;
- if ((state&NUD_VALID) && order != dflt)
+ if ((state & NUD_VALID) && order != dflt)
return 0;
- if ((state&NUD_VALID) ||
- (*last_idx<0 && order > dflt)) {
+ if ((state & NUD_VALID) ||
+ (*last_idx < 0 && order > dflt)) {
*last_resort = fi;
*last_idx = order;
}
@@ -476,75 +491,76 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
/*
- Picture
- -------
-
- Semantics of nexthop is very messy by historical reasons.
- We have to take into account, that:
- a) gateway can be actually local interface address,
- so that gatewayed route is direct.
- b) gateway must be on-link address, possibly
- described not by an ifaddr, but also by a direct route.
- c) If both gateway and interface are specified, they should not
- contradict.
- d) If we use tunnel routes, gateway could be not on-link.
-
- Attempt to reconcile all of these (alas, self-contradictory) conditions
- results in pretty ugly and hairy code with obscure logic.
-
- I chose to generalized it instead, so that the size
- of code does not increase practically, but it becomes
- much more general.
- Every prefix is assigned a "scope" value: "host" is local address,
- "link" is direct route,
- [ ... "site" ... "interior" ... ]
- and "universe" is true gateway route with global meaning.
-
- Every prefix refers to a set of "nexthop"s (gw, oif),
- where gw must have narrower scope. This recursion stops
- when gw has LOCAL scope or if "nexthop" is declared ONLINK,
- which means that gw is forced to be on link.
-
- Code is still hairy, but now it is apparently logically
- consistent and very flexible. F.e. as by-product it allows
- to co-exists in peace independent exterior and interior
- routing processes.
-
- Normally it looks as following.
-
- {universe prefix} -> (gw, oif) [scope link]
- |
- |-> {link prefix} -> (gw, oif) [scope local]
- |
- |-> {local prefix} (terminal node)
+ * Picture
+ * -------
+ *
+ * Semantics of nexthop is very messy by historical reasons.
+ * We have to take into account, that:
+ * a) gateway can be actually local interface address,
+ * so that gatewayed route is direct.
+ * b) gateway must be on-link address, possibly
+ * described not by an ifaddr, but also by a direct route.
+ * c) If both gateway and interface are specified, they should not
+ * contradict.
+ * d) If we use tunnel routes, gateway could be not on-link.
+ *
+ * Attempt to reconcile all of these (alas, self-contradictory) conditions
+ * results in pretty ugly and hairy code with obscure logic.
+ *
+ * I chose to generalized it instead, so that the size
+ * of code does not increase practically, but it becomes
+ * much more general.
+ * Every prefix is assigned a "scope" value: "host" is local address,
+ * "link" is direct route,
+ * [ ... "site" ... "interior" ... ]
+ * and "universe" is true gateway route with global meaning.
+ *
+ * Every prefix refers to a set of "nexthop"s (gw, oif),
+ * where gw must have narrower scope. This recursion stops
+ * when gw has LOCAL scope or if "nexthop" is declared ONLINK,
+ * which means that gw is forced to be on link.
+ *
+ * Code is still hairy, but now it is apparently logically
+ * consistent and very flexible. F.e. as by-product it allows
+ * to co-exists in peace independent exterior and interior
+ * routing processes.
+ *
+ * Normally it looks as following.
+ *
+ * {universe prefix} -> (gw, oif) [scope link]
+ * |
+ * |-> {link prefix} -> (gw, oif) [scope local]
+ * |
+ * |-> {local prefix} (terminal node)
*/
-
static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
struct fib_nh *nh)
{
int err;
struct net *net;
+ struct net_device *dev;
net = cfg->fc_nlinfo.nl_net;
if (nh->nh_gw) {
struct fib_result res;
- if (nh->nh_flags&RTNH_F_ONLINK) {
- struct net_device *dev;
+ if (nh->nh_flags & RTNH_F_ONLINK) {
if (cfg->fc_scope >= RT_SCOPE_LINK)
return -EINVAL;
if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST)
return -EINVAL;
- if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL)
+ dev = __dev_get_by_index(net, nh->nh_oif);
+ if (!dev)
return -ENODEV;
- if (!(dev->flags&IFF_UP))
+ if (!(dev->flags & IFF_UP))
return -ENETDOWN;
nh->nh_dev = dev;
dev_hold(dev);
nh->nh_scope = RT_SCOPE_LINK;
return 0;
}
+ rcu_read_lock();
{
struct flowi fl = {
.nl_u = {
@@ -559,50 +575,53 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
/* It is not necessary, but requires a bit of thinking */
if (fl.fl4_scope < RT_SCOPE_LINK)
fl.fl4_scope = RT_SCOPE_LINK;
- if ((err = fib_lookup(net, &fl, &res)) != 0)
+ err = fib_lookup(net, &fl, &res);
+ if (err) {
+ rcu_read_unlock();
return err;
+ }
}
err = -EINVAL;
if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
goto out;
nh->nh_scope = res.scope;
nh->nh_oif = FIB_RES_OIF(res);
- if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL)
+ nh->nh_dev = dev = FIB_RES_DEV(res);
+ if (!dev)
goto out;
- dev_hold(nh->nh_dev);
- err = -ENETDOWN;
- if (!(nh->nh_dev->flags & IFF_UP))
- goto out;
- err = 0;
-out:
- fib_res_put(&res);
- return err;
+ dev_hold(dev);
+ err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN;
} else {
struct in_device *in_dev;
- if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
+ if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK))
return -EINVAL;
+ rcu_read_lock();
+ err = -ENODEV;
in_dev = inetdev_by_index(net, nh->nh_oif);
if (in_dev == NULL)
- return -ENODEV;
- if (!(in_dev->dev->flags&IFF_UP)) {
- in_dev_put(in_dev);
- return -ENETDOWN;
- }
+ goto out;
+ err = -ENETDOWN;
+ if (!(in_dev->dev->flags & IFF_UP))
+ goto out;
nh->nh_dev = in_dev->dev;
dev_hold(nh->nh_dev);
nh->nh_scope = RT_SCOPE_HOST;
- in_dev_put(in_dev);
+ err = 0;
}
- return 0;
+out:
+ rcu_read_unlock();
+ return err;
}
static inline unsigned int fib_laddr_hashfn(__be32 val)
{
unsigned int mask = (fib_hash_size - 1);
- return ((__force u32)val ^ ((__force u32)val >> 7) ^ ((__force u32)val >> 14)) & mask;
+ return ((__force u32)val ^
+ ((__force u32)val >> 7) ^
+ ((__force u32)val >> 14)) & mask;
}
static struct hlist_head *fib_hash_alloc(int bytes)
@@ -611,7 +630,8 @@ static struct hlist_head *fib_hash_alloc(int bytes)
return kzalloc(bytes, GFP_KERNEL);
else
return (struct hlist_head *)
- __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(bytes));
+ __get_free_pages(GFP_KERNEL | __GFP_ZERO,
+ get_order(bytes));
}
static void fib_hash_free(struct hlist_head *hash, int bytes)
@@ -806,7 +826,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
goto failure;
} else {
change_nexthops(fi) {
- if ((err = fib_check_nh(cfg, fi, nexthop_nh)) != 0)
+ err = fib_check_nh(cfg, fi, nexthop_nh);
+ if (err != 0)
goto failure;
} endfor_nexthops(fi)
}
@@ -819,7 +840,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
}
link_it:
- if ((ofi = fib_find_info(fi)) != NULL) {
+ ofi = fib_find_info(fi);
+ if (ofi) {
fi->fib_dead = 1;
free_fib_info(fi);
ofi->fib_treeref++;
@@ -864,7 +886,7 @@ failure:
/* Note! fib_semantic_match intentionally uses RCU list functions. */
int fib_semantic_match(struct list_head *head, const struct flowi *flp,
- struct fib_result *res, int prefixlen)
+ struct fib_result *res, int prefixlen, int fib_flags)
{
struct fib_alias *fa;
int nh_sel = 0;
@@ -879,7 +901,7 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp,
if (fa->fa_scope < flp->fl4_scope)
continue;
- fa->fa_state |= FA_S_ACCESSED;
+ fib_alias_accessed(fa);
err = fib_props[fa->fa_type].error;
if (err == 0) {
@@ -895,7 +917,7 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp,
case RTN_ANYCAST:
case RTN_MULTICAST:
for_nexthops(fi) {
- if (nh->nh_flags&RTNH_F_DEAD)
+ if (nh->nh_flags & RTNH_F_DEAD)
continue;
if (!flp->oif || flp->oif == nh->nh_oif)
break;
@@ -906,16 +928,15 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp,
goto out_fill_res;
}
#else
- if (nhsel < 1) {
+ if (nhsel < 1)
goto out_fill_res;
- }
#endif
endfor_nexthops(fi);
continue;
default:
- printk(KERN_WARNING "fib_semantic_match bad type %#x\n",
- fa->fa_type);
+ pr_warning("fib_semantic_match bad type %#x\n",
+ fa->fa_type);
return -EINVAL;
}
}
@@ -929,7 +950,8 @@ out_fill_res:
res->type = fa->fa_type;
res->scope = fa->fa_scope;
res->fi = fa->fa_info;
- atomic_inc(&res->fi->fib_clntref);
+ if (!(fib_flags & FIB_LOOKUP_NOREF))
+ atomic_inc(&res->fi->fib_clntref);
return 0;
}
@@ -1028,10 +1050,10 @@ nla_put_failure:
}
/*
- Update FIB if:
- - local address disappeared -> we must delete all the entries
- referring to it.
- - device went down -> we must shutdown all nexthops going via it.
+ * Update FIB if:
+ * - local address disappeared -> we must delete all the entries
+ * referring to it.
+ * - device went down -> we must shutdown all nexthops going via it.
*/
int fib_sync_down_addr(struct net *net, __be32 local)
{
@@ -1078,7 +1100,7 @@ int fib_sync_down_dev(struct net_device *dev, int force)
prev_fi = fi;
dead = 0;
change_nexthops(fi) {
- if (nexthop_nh->nh_flags&RTNH_F_DEAD)
+ if (nexthop_nh->nh_flags & RTNH_F_DEAD)
dead++;
else if (nexthop_nh->nh_dev == dev &&
nexthop_nh->nh_scope != scope) {
@@ -1110,10 +1132,9 @@ int fib_sync_down_dev(struct net_device *dev, int force)
#ifdef CONFIG_IP_ROUTE_MULTIPATH
/*
- Dead device goes up. We wake up dead nexthops.
- It takes sense only on multipath routes.
+ * Dead device goes up. We wake up dead nexthops.
+ * It takes sense only on multipath routes.
*/
-
int fib_sync_up(struct net_device *dev)
{
struct fib_info *prev_fi;
@@ -1123,7 +1144,7 @@ int fib_sync_up(struct net_device *dev)
struct fib_nh *nh;
int ret;
- if (!(dev->flags&IFF_UP))
+ if (!(dev->flags & IFF_UP))
return 0;
prev_fi = NULL;
@@ -1142,12 +1163,12 @@ int fib_sync_up(struct net_device *dev)
prev_fi = fi;
alive = 0;
change_nexthops(fi) {
- if (!(nexthop_nh->nh_flags&RTNH_F_DEAD)) {
+ if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
alive++;
continue;
}
if (nexthop_nh->nh_dev == NULL ||
- !(nexthop_nh->nh_dev->flags&IFF_UP))
+ !(nexthop_nh->nh_dev->flags & IFF_UP))
continue;
if (nexthop_nh->nh_dev != dev ||
!__in_dev_get_rtnl(dev))
@@ -1169,10 +1190,9 @@ int fib_sync_up(struct net_device *dev)
}
/*
- The algorithm is suboptimal, but it provides really
- fair weighted route distribution.
+ * The algorithm is suboptimal, but it provides really
+ * fair weighted route distribution.
*/
-
void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
{
struct fib_info *fi = res->fi;
@@ -1182,7 +1202,7 @@ void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
if (fi->fib_power <= 0) {
int power = 0;
change_nexthops(fi) {
- if (!(nexthop_nh->nh_flags&RTNH_F_DEAD)) {
+ if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
power += nexthop_nh->nh_weight;
nexthop_nh->nh_power = nexthop_nh->nh_weight;
}
@@ -1198,15 +1218,16 @@ void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
/* w should be random number [0..fi->fib_power-1],
- it is pretty bad approximation.
+ * it is pretty bad approximation.
*/
w = jiffies % fi->fib_power;
change_nexthops(fi) {
- if (!(nexthop_nh->nh_flags&RTNH_F_DEAD) &&
+ if (!(nexthop_nh->nh_flags & RTNH_F_DEAD) &&
nexthop_nh->nh_power) {
- if ((w -= nexthop_nh->nh_power) <= 0) {
+ w -= nexthop_nh->nh_power;
+ if (w <= 0) {
nexthop_nh->nh_power--;
fi->fib_power--;
res->nh_sel = nhsel;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 4a8e370862bc..cd5e13aee7d5 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -186,9 +186,7 @@ static inline struct tnode *node_parent_rcu(struct node *node)
{
struct tnode *ret = node_parent(node);
- return rcu_dereference_check(ret,
- rcu_read_lock_held() ||
- lockdep_rtnl_is_held());
+ return rcu_dereference_rtnl(ret);
}
/* Same as rcu_assign_pointer
@@ -211,9 +209,7 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i)
{
struct node *ret = tnode_get_child(tn, i);
- return rcu_dereference_check(ret,
- rcu_read_lock_held() ||
- lockdep_rtnl_is_held());
+ return rcu_dereference_rtnl(ret);
}
static inline int tnode_child_length(const struct tnode *tn)
@@ -459,8 +455,8 @@ static struct tnode *tnode_new(t_key key, int pos, int bits)
tn->empty_children = 1<<bits;
}
- pr_debug("AT %p s=%u %lu\n", tn, (unsigned int) sizeof(struct tnode),
- (unsigned long) (sizeof(struct node) << bits));
+ pr_debug("AT %p s=%zu %zu\n", tn, sizeof(struct tnode),
+ sizeof(struct node) << bits);
return tn;
}
@@ -609,11 +605,10 @@ static struct node *resize(struct trie *t, struct tnode *tn)
/* Keep root node larger */
- if (!node_parent((struct node*) tn)) {
+ if (!node_parent((struct node *)tn)) {
inflate_threshold_use = inflate_threshold_root;
halve_threshold_use = halve_threshold_root;
- }
- else {
+ } else {
inflate_threshold_use = inflate_threshold;
halve_threshold_use = halve_threshold;
}
@@ -639,7 +634,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
check_tnode(tn);
/* Return if at least one inflate is run */
- if( max_work != MAX_WORK)
+ if (max_work != MAX_WORK)
return (struct node *) tn;
/*
@@ -966,9 +961,7 @@ fib_find_node(struct trie *t, u32 key)
struct node *n;
pos = 0;
- n = rcu_dereference_check(t->trie,
- rcu_read_lock_held() ||
- lockdep_rtnl_is_held());
+ n = rcu_dereference_rtnl(t->trie);
while (n != NULL && NODE_TYPE(n) == T_TNODE) {
tn = (struct tnode *) n;
@@ -1349,7 +1342,7 @@ err:
/* should be called with rcu_read_lock */
static int check_leaf(struct trie *t, struct leaf *l,
t_key key, const struct flowi *flp,
- struct fib_result *res)
+ struct fib_result *res, int fib_flags)
{
struct leaf_info *li;
struct hlist_head *hhead = &l->list;
@@ -1363,7 +1356,7 @@ static int check_leaf(struct trie *t, struct leaf *l,
if (l->key != (key & ntohl(mask)))
continue;
- err = fib_semantic_match(&li->falh, flp, res, plen);
+ err = fib_semantic_match(&li->falh, flp, res, plen, fib_flags);
#ifdef CONFIG_IP_FIB_TRIE_STATS
if (err <= 0)
@@ -1379,7 +1372,7 @@ static int check_leaf(struct trie *t, struct leaf *l,
}
int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
- struct fib_result *res)
+ struct fib_result *res, int fib_flags)
{
struct trie *t = (struct trie *) tb->tb_data;
int ret;
@@ -1391,8 +1384,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
t_key cindex = 0;
int current_prefix_length = KEYLENGTH;
struct tnode *cn;
- t_key node_prefix, key_prefix, pref_mismatch;
- int mp;
+ t_key pref_mismatch;
rcu_read_lock();
@@ -1406,7 +1398,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
/* Just a leaf? */
if (IS_LEAF(n)) {
- ret = check_leaf(t, (struct leaf *)n, key, flp, res);
+ ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags);
goto found;
}
@@ -1431,7 +1423,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
}
if (IS_LEAF(n)) {
- ret = check_leaf(t, (struct leaf *)n, key, flp, res);
+ ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags);
if (ret > 0)
goto backtrace;
goto found;
@@ -1507,10 +1499,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
* matching prefix.
*/
- node_prefix = mask_pfx(cn->key, cn->pos);
- key_prefix = mask_pfx(key, cn->pos);
- pref_mismatch = key_prefix^node_prefix;
- mp = 0;
+ pref_mismatch = mask_pfx(cn->key ^ key, cn->pos);
/*
* In short: If skipped bits in this node do not match
@@ -1518,13 +1507,9 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
* state.directly.
*/
if (pref_mismatch) {
- while (!(pref_mismatch & (1<<(KEYLENGTH-1)))) {
- mp++;
- pref_mismatch = pref_mismatch << 1;
- }
- key_prefix = tkey_extract_bits(cn->key, mp, cn->pos-mp);
+ int mp = KEYLENGTH - fls(pref_mismatch);
- if (key_prefix != 0)
+ if (tkey_extract_bits(cn->key, mp, cn->pos - mp) != 0)
goto backtrace;
if (current_prefix_length >= cn->pos)
@@ -1748,16 +1733,14 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c)
/* Node empty, walk back up to parent */
c = (struct node *) p;
- } while ( (p = node_parent_rcu(c)) != NULL);
+ } while ((p = node_parent_rcu(c)) != NULL);
return NULL; /* Root of trie */
}
static struct leaf *trie_firstleaf(struct trie *t)
{
- struct tnode *n = (struct tnode *) rcu_dereference_check(t->trie,
- rcu_read_lock_held() ||
- lockdep_rtnl_is_held());
+ struct tnode *n = (struct tnode *)rcu_dereference_rtnl(t->trie);
if (!n)
return NULL;
@@ -1855,7 +1838,8 @@ void fib_table_select_default(struct fib_table *tb,
if (!next_fi->fib_nh[0].nh_gw ||
next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
continue;
- fa->fa_state |= FA_S_ACCESSED;
+
+ fib_alias_accessed(fa);
if (fi == NULL) {
if (next_fi != res->fi)
@@ -2043,14 +2027,14 @@ struct fib_trie_iter {
struct seq_net_private p;
struct fib_table *tb;
struct tnode *tnode;
- unsigned index;
- unsigned depth;
+ unsigned int index;
+ unsigned int depth;
};
static struct node *fib_trie_get_next(struct fib_trie_iter *iter)
{
struct tnode *tn = iter->tnode;
- unsigned cindex = iter->index;
+ unsigned int cindex = iter->index;
struct tnode *p;
/* A single entry routing table */
@@ -2159,7 +2143,7 @@ static void trie_collect_stats(struct trie *t, struct trie_stat *s)
*/
static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat)
{
- unsigned i, max, pointers, bytes, avdepth;
+ unsigned int i, max, pointers, bytes, avdepth;
if (stat->leaves)
avdepth = stat->totdepth*100 / stat->leaves;
@@ -2356,7 +2340,8 @@ static void fib_trie_seq_stop(struct seq_file *seq, void *v)
static void seq_indent(struct seq_file *seq, int n)
{
- while (n-- > 0) seq_puts(seq, " ");
+ while (n-- > 0)
+ seq_puts(seq, " ");
}
static inline const char *rtn_scope(char *buf, size_t len, enum rt_scope_t s)
@@ -2388,7 +2373,7 @@ static const char *const rtn_type_names[__RTN_MAX] = {
[RTN_XRESOLVE] = "XRESOLVE",
};
-static inline const char *rtn_type(char *buf, size_t len, unsigned t)
+static inline const char *rtn_type(char *buf, size_t len, unsigned int t)
{
if (t < __RTN_MAX && rtn_type_names[t])
return rtn_type_names[t];
@@ -2544,13 +2529,12 @@ static void fib_route_seq_stop(struct seq_file *seq, void *v)
rcu_read_unlock();
}
-static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
+static unsigned int fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
{
- static unsigned type2flags[RTN_MAX + 1] = {
- [7] = RTF_REJECT, [8] = RTF_REJECT,
- };
- unsigned flags = type2flags[type];
+ unsigned int flags = 0;
+ if (type == RTN_UNREACHABLE || type == RTN_PROHIBIT)
+ flags = RTF_REJECT;
if (fi && fi->fib_nh->nh_gw)
flags |= RTF_GATEWAY;
if (mask == htonl(0xFFFFFFFF))
@@ -2562,7 +2546,7 @@ static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
/*
* This outputs /proc/net/route.
* The format of the file is not supposed to be changed
- * and needs to be same as fib_hash output to avoid breaking
+ * and needs to be same as fib_hash output to avoid breaking
* legacy utilities
*/
static int fib_route_seq_show(struct seq_file *seq, void *v)
@@ -2587,7 +2571,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
list_for_each_entry_rcu(fa, &li->falh, fa_list) {
const struct fib_info *fi = fa->fa_info;
- unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
+ unsigned int flags = fib_flag_trans(fa->fa_type, mask, fi);
int len;
if (fa->fa_type == RTN_BROADCAST
diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c
new file mode 100644
index 000000000000..caea6885fdbd
--- /dev/null
+++ b/net/ipv4/gre.c
@@ -0,0 +1,151 @@
+/*
+ * GRE over IPv4 demultiplexer driver
+ *
+ * Authors: Dmitry Kozlov (xeb@mail.ru)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/kmod.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/netdevice.h>
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <net/protocol.h>
+#include <net/gre.h>
+
+
+static const struct gre_protocol *gre_proto[GREPROTO_MAX] __read_mostly;
+static DEFINE_SPINLOCK(gre_proto_lock);
+
+int gre_add_protocol(const struct gre_protocol *proto, u8 version)
+{
+ if (version >= GREPROTO_MAX)
+ goto err_out;
+
+ spin_lock(&gre_proto_lock);
+ if (gre_proto[version])
+ goto err_out_unlock;
+
+ rcu_assign_pointer(gre_proto[version], proto);
+ spin_unlock(&gre_proto_lock);
+ return 0;
+
+err_out_unlock:
+ spin_unlock(&gre_proto_lock);
+err_out:
+ return -1;
+}
+EXPORT_SYMBOL_GPL(gre_add_protocol);
+
+int gre_del_protocol(const struct gre_protocol *proto, u8 version)
+{
+ if (version >= GREPROTO_MAX)
+ goto err_out;
+
+ spin_lock(&gre_proto_lock);
+ if (gre_proto[version] != proto)
+ goto err_out_unlock;
+ rcu_assign_pointer(gre_proto[version], NULL);
+ spin_unlock(&gre_proto_lock);
+ synchronize_rcu();
+ return 0;
+
+err_out_unlock:
+ spin_unlock(&gre_proto_lock);
+err_out:
+ return -1;
+}
+EXPORT_SYMBOL_GPL(gre_del_protocol);
+
+static int gre_rcv(struct sk_buff *skb)
+{
+ const struct gre_protocol *proto;
+ u8 ver;
+ int ret;
+
+ if (!pskb_may_pull(skb, 12))
+ goto drop;
+
+ ver = skb->data[1]&0x7f;
+ if (ver >= GREPROTO_MAX)
+ goto drop;
+
+ rcu_read_lock();
+ proto = rcu_dereference(gre_proto[ver]);
+ if (!proto || !proto->handler)
+ goto drop_unlock;
+ ret = proto->handler(skb);
+ rcu_read_unlock();
+ return ret;
+
+drop_unlock:
+ rcu_read_unlock();
+drop:
+ kfree_skb(skb);
+ return NET_RX_DROP;
+}
+
+static void gre_err(struct sk_buff *skb, u32 info)
+{
+ const struct gre_protocol *proto;
+ u8 ver;
+
+ if (!pskb_may_pull(skb, 12))
+ goto drop;
+
+ ver = skb->data[1]&0x7f;
+ if (ver >= GREPROTO_MAX)
+ goto drop;
+
+ rcu_read_lock();
+ proto = rcu_dereference(gre_proto[ver]);
+ if (!proto || !proto->err_handler)
+ goto drop_unlock;
+ proto->err_handler(skb, info);
+ rcu_read_unlock();
+ return;
+
+drop_unlock:
+ rcu_read_unlock();
+drop:
+ kfree_skb(skb);
+}
+
+static const struct net_protocol net_gre_protocol = {
+ .handler = gre_rcv,
+ .err_handler = gre_err,
+ .netns_ok = 1,
+};
+
+static int __init gre_init(void)
+{
+ pr_info("GRE over IPv4 demultiplexor driver");
+
+ if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) {
+ pr_err("gre: can't add protocol\n");
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+static void __exit gre_exit(void)
+{
+ inet_del_protocol(&net_gre_protocol, IPPROTO_GRE);
+}
+
+module_init(gre_init);
+module_exit(gre_exit);
+
+MODULE_DESCRIPTION("GRE over IPv4 demultiplexer driver");
+MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)");
+MODULE_LICENSE("GPL");
+
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index a0d847c7cba5..96bc7f9475a3 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -379,7 +379,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
inet->tos = ip_hdr(skb)->tos;
daddr = ipc.addr = rt->rt_src;
ipc.opt = NULL;
- ipc.shtx.flags = 0;
+ ipc.tx_flags = 0;
if (icmp_param->replyopts.optlen) {
ipc.opt = &icmp_param->replyopts;
if (ipc.opt->srr)
@@ -538,7 +538,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
inet_sk(sk)->tos = tos;
ipc.addr = iph->saddr;
ipc.opt = &icmp_param.replyopts;
- ipc.shtx.flags = 0;
+ ipc.tx_flags = 0;
{
struct flowi fl = {
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 2a4bb76f2132..c8877c6c7216 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1269,14 +1269,14 @@ void ip_mc_rejoin_group(struct ip_mc_list *im)
if (im->multiaddr == IGMP_ALL_HOSTS)
return;
- if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) {
- igmp_mod_timer(im, IGMP_Initial_Report_Delay);
- return;
- }
- /* else, v3 */
- im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
- IGMP_Unsolicited_Report_Count;
- igmp_ifc_event(in_dev);
+ /* a failover is happening and switches
+ * must be notified immediately */
+ if (IGMP_V1_SEEN(in_dev))
+ igmp_send_report(in_dev, im, IGMP_HOST_MEMBERSHIP_REPORT);
+ else if (IGMP_V2_SEEN(in_dev))
+ igmp_send_report(in_dev, im, IGMPV2_HOST_MEMBERSHIP_REPORT);
+ else
+ igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT);
#endif
}
EXPORT_SYMBOL(ip_mc_rejoin_group);
@@ -1418,6 +1418,7 @@ void ip_mc_destroy_dev(struct in_device *in_dev)
write_unlock_bh(&in_dev->mc_list_lock);
}
+/* RTNL is locked */
static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
{
struct flowi fl = { .nl_u = { .ip4_u =
@@ -1428,15 +1429,12 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
if (imr->imr_ifindex) {
idev = inetdev_by_index(net, imr->imr_ifindex);
- if (idev)
- __in_dev_put(idev);
return idev;
}
if (imr->imr_address.s_addr) {
- dev = ip_dev_find(net, imr->imr_address.s_addr);
+ dev = __ip_dev_find(net, imr->imr_address.s_addr, false);
if (!dev)
return NULL;
- dev_put(dev);
}
if (!dev && !ip_route_output_key(net, &rt, &fl)) {
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index e5fa2ddce320..ba8042665849 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -425,7 +425,7 @@ static int inet_diag_bc_run(const void *bc, int len,
bc += op->no;
}
}
- return (len == 0);
+ return len == 0;
}
static int valid_cc(const void *bc, int len, int cc)
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index fb7ad5a21ff3..1b344f30b463 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -101,19 +101,43 @@ void inet_put_port(struct sock *sk)
}
EXPORT_SYMBOL(inet_put_port);
-void __inet_inherit_port(struct sock *sk, struct sock *child)
+int __inet_inherit_port(struct sock *sk, struct sock *child)
{
struct inet_hashinfo *table = sk->sk_prot->h.hashinfo;
- const int bhash = inet_bhashfn(sock_net(sk), inet_sk(child)->inet_num,
+ unsigned short port = inet_sk(child)->inet_num;
+ const int bhash = inet_bhashfn(sock_net(sk), port,
table->bhash_size);
struct inet_bind_hashbucket *head = &table->bhash[bhash];
struct inet_bind_bucket *tb;
spin_lock(&head->lock);
tb = inet_csk(sk)->icsk_bind_hash;
+ if (tb->port != port) {
+ /* NOTE: using tproxy and redirecting skbs to a proxy
+ * on a different listener port breaks the assumption
+ * that the listener socket's icsk_bind_hash is the same
+ * as that of the child socket. We have to look up or
+ * create a new bind bucket for the child here. */
+ struct hlist_node *node;
+ inet_bind_bucket_for_each(tb, node, &head->chain) {
+ if (net_eq(ib_net(tb), sock_net(sk)) &&
+ tb->port == port)
+ break;
+ }
+ if (!node) {
+ tb = inet_bind_bucket_create(table->bind_bucket_cachep,
+ sock_net(sk), head, port);
+ if (!tb) {
+ spin_unlock(&head->lock);
+ return -ENOMEM;
+ }
+ }
+ }
sk_add_bind_node(child, &tb->owners);
inet_csk(child)->icsk_bind_hash = tb;
spin_unlock(&head->lock);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(__inet_inherit_port);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index b7c41654dde5..168440834ade 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -116,11 +116,11 @@ static int ip4_frag_match(struct inet_frag_queue *q, void *a)
struct ip4_create_arg *arg = a;
qp = container_of(q, struct ipq, q);
- return (qp->id == arg->iph->id &&
+ return qp->id == arg->iph->id &&
qp->saddr == arg->iph->saddr &&
qp->daddr == arg->iph->daddr &&
qp->protocol == arg->iph->protocol &&
- qp->user == arg->user);
+ qp->user == arg->user;
}
/* Memory Tracking Functions. */
@@ -542,7 +542,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
/* If the first fragment is fragmented itself, we split
* it to two chunks: the first with data and paged part
* and the second, holding only fragments. */
- if (skb_has_frags(head)) {
+ if (skb_has_frag_list(head)) {
struct sk_buff *clone;
int i, plen = 0;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 35c93e8b6a46..d0ffcbe369b7 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -44,6 +44,7 @@
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
+#include <net/gre.h>
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#include <net/ipv6.h>
@@ -63,13 +64,13 @@
We cannot track such dead loops during route installation,
it is infeasible task. The most general solutions would be
to keep skb->encapsulation counter (sort of local ttl),
- and silently drop packet when it expires. It is the best
+ and silently drop packet when it expires. It is a good
solution, but it supposes maintaing new variable in ALL
skb, even if no tunneling is used.
- Current solution: HARD_TX_LOCK lock breaks dead loops.
-
-
+ Current solution: xmit_recursion breaks dead loops. This is a percpu
+ counter, since when we enter the first ndo_xmit(), cpu migration is
+ forbidden. We force an exit if this counter reaches RECURSION_LIMIT
2. Networking dead loops would not kill routers, but would really
kill network. IP hop limit plays role of "t->recursion" in this case,
@@ -128,7 +129,7 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev);
static int ipgre_net_id __read_mostly;
struct ipgre_net {
- struct ip_tunnel *tunnels[4][HASH_SIZE];
+ struct ip_tunnel __rcu *tunnels[4][HASH_SIZE];
struct net_device *fb_tunnel_dev;
};
@@ -158,13 +159,40 @@ struct ipgre_net {
#define tunnels_l tunnels[1]
#define tunnels_wc tunnels[0]
/*
- * Locking : hash tables are protected by RCU and a spinlock
+ * Locking : hash tables are protected by RCU and RTNL
*/
-static DEFINE_SPINLOCK(ipgre_lock);
#define for_each_ip_tunnel_rcu(start) \
for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
+/* often modified stats are per cpu, other are shared (netdev->stats) */
+struct pcpu_tstats {
+ unsigned long rx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_packets;
+ unsigned long tx_bytes;
+};
+
+static struct net_device_stats *ipgre_get_stats(struct net_device *dev)
+{
+ struct pcpu_tstats sum = { 0 };
+ int i;
+
+ for_each_possible_cpu(i) {
+ const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
+
+ sum.rx_packets += tstats->rx_packets;
+ sum.rx_bytes += tstats->rx_bytes;
+ sum.tx_packets += tstats->tx_packets;
+ sum.tx_bytes += tstats->tx_bytes;
+ }
+ dev->stats.rx_packets = sum.rx_packets;
+ dev->stats.rx_bytes = sum.rx_bytes;
+ dev->stats.tx_packets = sum.tx_packets;
+ dev->stats.tx_bytes = sum.tx_bytes;
+ return &dev->stats;
+}
+
/* Given src, dst and key, find appropriate for input tunnel. */
static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
@@ -173,8 +201,8 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
{
struct net *net = dev_net(dev);
int link = dev->ifindex;
- unsigned h0 = HASH(remote);
- unsigned h1 = HASH(key);
+ unsigned int h0 = HASH(remote);
+ unsigned int h1 = HASH(key);
struct ip_tunnel *t, *cand = NULL;
struct ipgre_net *ign = net_generic(net, ipgre_net_id);
int dev_type = (gre_proto == htons(ETH_P_TEB)) ?
@@ -289,13 +317,13 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
return NULL;
}
-static struct ip_tunnel **__ipgre_bucket(struct ipgre_net *ign,
+static struct ip_tunnel __rcu **__ipgre_bucket(struct ipgre_net *ign,
struct ip_tunnel_parm *parms)
{
__be32 remote = parms->iph.daddr;
__be32 local = parms->iph.saddr;
__be32 key = parms->i_key;
- unsigned h = HASH(key);
+ unsigned int h = HASH(key);
int prio = 0;
if (local)
@@ -308,7 +336,7 @@ static struct ip_tunnel **__ipgre_bucket(struct ipgre_net *ign,
return &ign->tunnels[prio][h];
}
-static inline struct ip_tunnel **ipgre_bucket(struct ipgre_net *ign,
+static inline struct ip_tunnel __rcu **ipgre_bucket(struct ipgre_net *ign,
struct ip_tunnel *t)
{
return __ipgre_bucket(ign, &t->parms);
@@ -316,23 +344,22 @@ static inline struct ip_tunnel **ipgre_bucket(struct ipgre_net *ign,
static void ipgre_tunnel_link(struct ipgre_net *ign, struct ip_tunnel *t)
{
- struct ip_tunnel **tp = ipgre_bucket(ign, t);
+ struct ip_tunnel __rcu **tp = ipgre_bucket(ign, t);
- spin_lock_bh(&ipgre_lock);
- t->next = *tp;
+ rcu_assign_pointer(t->next, rtnl_dereference(*tp));
rcu_assign_pointer(*tp, t);
- spin_unlock_bh(&ipgre_lock);
}
static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t)
{
- struct ip_tunnel **tp;
-
- for (tp = ipgre_bucket(ign, t); *tp; tp = &(*tp)->next) {
- if (t == *tp) {
- spin_lock_bh(&ipgre_lock);
- *tp = t->next;
- spin_unlock_bh(&ipgre_lock);
+ struct ip_tunnel __rcu **tp;
+ struct ip_tunnel *iter;
+
+ for (tp = ipgre_bucket(ign, t);
+ (iter = rtnl_dereference(*tp)) != NULL;
+ tp = &iter->next) {
+ if (t == iter) {
+ rcu_assign_pointer(*tp, t->next);
break;
}
}
@@ -346,10 +373,13 @@ static struct ip_tunnel *ipgre_tunnel_find(struct net *net,
__be32 local = parms->iph.saddr;
__be32 key = parms->i_key;
int link = parms->link;
- struct ip_tunnel *t, **tp;
+ struct ip_tunnel *t;
+ struct ip_tunnel __rcu **tp;
struct ipgre_net *ign = net_generic(net, ipgre_net_id);
- for (tp = __ipgre_bucket(ign, parms); (t = *tp) != NULL; tp = &t->next)
+ for (tp = __ipgre_bucket(ign, parms);
+ (t = rtnl_dereference(*tp)) != NULL;
+ tp = &t->next)
if (local == t->parms.iph.saddr &&
remote == t->parms.iph.daddr &&
key == t->parms.i_key &&
@@ -360,7 +390,7 @@ static struct ip_tunnel *ipgre_tunnel_find(struct net *net,
return t;
}
-static struct ip_tunnel * ipgre_tunnel_locate(struct net *net,
+static struct ip_tunnel *ipgre_tunnel_locate(struct net *net,
struct ip_tunnel_parm *parms, int create)
{
struct ip_tunnel *t, *nt;
@@ -582,7 +612,7 @@ static int ipgre_rcv(struct sk_buff *skb)
if ((tunnel = ipgre_tunnel_lookup(skb->dev,
iph->saddr, iph->daddr, key,
gre_proto))) {
- struct net_device_stats *stats = &tunnel->dev->stats;
+ struct pcpu_tstats *tstats;
secpath_reset(skb);
@@ -606,22 +636,22 @@ static int ipgre_rcv(struct sk_buff *skb)
/* Looped back packet, drop it! */
if (skb_rtable(skb)->fl.iif == 0)
goto drop;
- stats->multicast++;
+ tunnel->dev->stats.multicast++;
skb->pkt_type = PACKET_BROADCAST;
}
#endif
if (((flags&GRE_CSUM) && csum) ||
(!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
- stats->rx_crc_errors++;
- stats->rx_errors++;
+ tunnel->dev->stats.rx_crc_errors++;
+ tunnel->dev->stats.rx_errors++;
goto drop;
}
if (tunnel->parms.i_flags&GRE_SEQ) {
if (!(flags&GRE_SEQ) ||
(tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) {
- stats->rx_fifo_errors++;
- stats->rx_errors++;
+ tunnel->dev->stats.rx_fifo_errors++;
+ tunnel->dev->stats.rx_errors++;
goto drop;
}
tunnel->i_seqno = seqno + 1;
@@ -630,8 +660,8 @@ static int ipgre_rcv(struct sk_buff *skb)
/* Warning: All skb pointers will be invalidated! */
if (tunnel->dev->type == ARPHRD_ETHER) {
if (!pskb_may_pull(skb, ETH_HLEN)) {
- stats->rx_length_errors++;
- stats->rx_errors++;
+ tunnel->dev->stats.rx_length_errors++;
+ tunnel->dev->stats.rx_errors++;
goto drop;
}
@@ -640,14 +670,19 @@ static int ipgre_rcv(struct sk_buff *skb)
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
}
- skb_tunnel_rx(skb, tunnel->dev);
+ tstats = this_cpu_ptr(tunnel->dev->tstats);
+ tstats->rx_packets++;
+ tstats->rx_bytes += skb->len;
+
+ __skb_tunnel_rx(skb, tunnel->dev);
skb_reset_network_header(skb);
ipgre_ecn_decapsulate(iph, skb);
netif_rx(skb);
+
rcu_read_unlock();
- return(0);
+ return 0;
}
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
@@ -655,20 +690,19 @@ drop:
rcu_read_unlock();
drop_nolock:
kfree_skb(skb);
- return(0);
+ return 0;
}
static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
- struct net_device_stats *stats = &dev->stats;
- struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+ struct pcpu_tstats *tstats;
struct iphdr *old_iph = ip_hdr(skb);
struct iphdr *tiph;
u8 tos;
__be16 df;
struct rtable *rt; /* Route to the other host */
- struct net_device *tdev; /* Device to other host */
+ struct net_device *tdev; /* Device to other host */
struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
int gre_hlen;
@@ -690,7 +724,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
/* NBMA tunnel */
if (skb_dst(skb) == NULL) {
- stats->tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
goto tx_error;
}
@@ -736,14 +770,20 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
}
{
- struct flowi fl = { .oif = tunnel->parms.link,
- .nl_u = { .ip4_u =
- { .daddr = dst,
- .saddr = tiph->saddr,
- .tos = RT_TOS(tos) } },
- .proto = IPPROTO_GRE };
+ struct flowi fl = {
+ .oif = tunnel->parms.link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = dst,
+ .saddr = tiph->saddr,
+ .tos = RT_TOS(tos)
+ }
+ },
+ .proto = IPPROTO_GRE
+ }
+;
if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
- stats->tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
goto tx_error;
}
}
@@ -751,7 +791,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
if (tdev == dev) {
ip_rt_put(rt);
- stats->collisions++;
+ dev->stats.collisions++;
goto tx_error;
}
@@ -814,7 +854,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
dev->needed_headroom = max_headroom;
if (!new_skb) {
ip_rt_put(rt);
- txq->tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -881,15 +921,15 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
}
nf_reset(skb);
-
- IPTUNNEL_XMIT();
+ tstats = this_cpu_ptr(dev->tstats);
+ __IPTUNNEL_XMIT(tstats, &dev->stats);
return NETDEV_TX_OK;
tx_error_icmp:
dst_link_failure(skb);
tx_error:
- stats->tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -909,13 +949,19 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
/* Guess output device to choose reasonable mtu and needed_headroom */
if (iph->daddr) {
- struct flowi fl = { .oif = tunnel->parms.link,
- .nl_u = { .ip4_u =
- { .daddr = iph->daddr,
- .saddr = iph->saddr,
- .tos = RT_TOS(iph->tos) } },
- .proto = IPPROTO_GRE };
+ struct flowi fl = {
+ .oif = tunnel->parms.link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = iph->daddr,
+ .saddr = iph->saddr,
+ .tos = RT_TOS(iph->tos)
+ }
+ },
+ .proto = IPPROTO_GRE
+ };
struct rtable *rt;
+
if (!ip_route_output_key(dev_net(dev), &rt, &fl)) {
tdev = rt->dst.dev;
ip_rt_put(rt);
@@ -1012,7 +1058,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
break;
}
} else {
- unsigned nflags = 0;
+ unsigned int nflags = 0;
t = netdev_priv(dev);
@@ -1125,7 +1171,7 @@ static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type,
- const void *daddr, const void *saddr, unsigned len)
+ const void *daddr, const void *saddr, unsigned int len)
{
struct ip_tunnel *t = netdev_priv(dev);
struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen);
@@ -1167,13 +1213,19 @@ static int ipgre_open(struct net_device *dev)
struct ip_tunnel *t = netdev_priv(dev);
if (ipv4_is_multicast(t->parms.iph.daddr)) {
- struct flowi fl = { .oif = t->parms.link,
- .nl_u = { .ip4_u =
- { .daddr = t->parms.iph.daddr,
- .saddr = t->parms.iph.saddr,
- .tos = RT_TOS(t->parms.iph.tos) } },
- .proto = IPPROTO_GRE };
+ struct flowi fl = {
+ .oif = t->parms.link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = t->parms.iph.daddr,
+ .saddr = t->parms.iph.saddr,
+ .tos = RT_TOS(t->parms.iph.tos)
+ }
+ },
+ .proto = IPPROTO_GRE
+ };
struct rtable *rt;
+
if (ip_route_output_key(dev_net(dev), &rt, &fl))
return -EADDRNOTAVAIL;
dev = rt->dst.dev;
@@ -1193,10 +1245,8 @@ static int ipgre_close(struct net_device *dev)
if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
struct in_device *in_dev;
in_dev = inetdev_by_index(dev_net(dev), t->mlink);
- if (in_dev) {
+ if (in_dev)
ip_mc_dec_group(in_dev, t->parms.iph.daddr);
- in_dev_put(in_dev);
- }
}
return 0;
}
@@ -1213,12 +1263,19 @@ static const struct net_device_ops ipgre_netdev_ops = {
.ndo_start_xmit = ipgre_tunnel_xmit,
.ndo_do_ioctl = ipgre_tunnel_ioctl,
.ndo_change_mtu = ipgre_tunnel_change_mtu,
+ .ndo_get_stats = ipgre_get_stats,
};
+static void ipgre_dev_free(struct net_device *dev)
+{
+ free_percpu(dev->tstats);
+ free_netdev(dev);
+}
+
static void ipgre_tunnel_setup(struct net_device *dev)
{
dev->netdev_ops = &ipgre_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = ipgre_dev_free;
dev->type = ARPHRD_IPGRE;
dev->needed_headroom = LL_MAX_HEADER + sizeof(struct iphdr) + 4;
@@ -1256,6 +1313,10 @@ static int ipgre_tunnel_init(struct net_device *dev)
} else
dev->header_ops = &ipgre_header_ops;
+ dev->tstats = alloc_percpu(struct pcpu_tstats);
+ if (!dev->tstats)
+ return -ENOMEM;
+
return 0;
}
@@ -1274,14 +1335,13 @@ static void ipgre_fb_tunnel_init(struct net_device *dev)
tunnel->hlen = sizeof(struct iphdr) + 4;
dev_hold(dev);
- ign->tunnels_wc[0] = tunnel;
+ rcu_assign_pointer(ign->tunnels_wc[0], tunnel);
}
-static const struct net_protocol ipgre_protocol = {
- .handler = ipgre_rcv,
- .err_handler = ipgre_err,
- .netns_ok = 1,
+static const struct gre_protocol ipgre_protocol = {
+ .handler = ipgre_rcv,
+ .err_handler = ipgre_err,
};
static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head)
@@ -1291,11 +1351,13 @@ static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head)
for (prio = 0; prio < 4; prio++) {
int h;
for (h = 0; h < HASH_SIZE; h++) {
- struct ip_tunnel *t = ign->tunnels[prio][h];
+ struct ip_tunnel *t;
+
+ t = rtnl_dereference(ign->tunnels[prio][h]);
while (t != NULL) {
unregister_netdevice_queue(t->dev, head);
- t = t->next;
+ t = rtnl_dereference(t->next);
}
}
}
@@ -1441,6 +1503,10 @@ static int ipgre_tap_init(struct net_device *dev)
ipgre_tunnel_bind_dev(dev);
+ dev->tstats = alloc_percpu(struct pcpu_tstats);
+ if (!dev->tstats)
+ return -ENOMEM;
+
return 0;
}
@@ -1451,6 +1517,7 @@ static const struct net_device_ops ipgre_tap_netdev_ops = {
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = ipgre_tunnel_change_mtu,
+ .ndo_get_stats = ipgre_get_stats,
};
static void ipgre_tap_setup(struct net_device *dev)
@@ -1459,7 +1526,7 @@ static void ipgre_tap_setup(struct net_device *dev)
ether_setup(dev);
dev->netdev_ops = &ipgre_tap_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = ipgre_dev_free;
dev->iflink = 0;
dev->features |= NETIF_F_NETNS_LOCAL;
@@ -1487,6 +1554,10 @@ static int ipgre_newlink(struct net *src_net, struct net_device *dev, struct nla
if (!tb[IFLA_MTU])
dev->mtu = mtu;
+ /* Can use a lockless transmit, unless we generate output sequences */
+ if (!(nt->parms.o_flags & GRE_SEQ))
+ dev->features |= NETIF_F_LLTX;
+
err = register_netdevice(dev);
if (err)
goto out;
@@ -1522,7 +1593,7 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
t = nt;
if (dev->type != ARPHRD_ETHER) {
- unsigned nflags = 0;
+ unsigned int nflags = 0;
if (ipv4_is_multicast(p.iph.daddr))
nflags = IFF_BROADCAST;
@@ -1663,7 +1734,7 @@ static int __init ipgre_init(void)
if (err < 0)
return err;
- err = inet_add_protocol(&ipgre_protocol, IPPROTO_GRE);
+ err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
if (err < 0) {
printk(KERN_INFO "ipgre init: can't add protocol\n");
goto add_proto_failed;
@@ -1683,7 +1754,7 @@ out:
tap_ops_failed:
rtnl_link_unregister(&ipgre_link_ops);
rtnl_link_failed:
- inet_del_protocol(&ipgre_protocol, IPPROTO_GRE);
+ gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
add_proto_failed:
unregister_pernet_device(&ipgre_net_ops);
goto out;
@@ -1693,7 +1764,7 @@ static void __exit ipgre_fini(void)
{
rtnl_link_unregister(&ipgre_tap_ops);
rtnl_link_unregister(&ipgre_link_ops);
- if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
+ if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0)
printk(KERN_INFO "ipgre close: can't remove protocol\n");
unregister_pernet_device(&ipgre_net_ops);
}
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index ba9836c488ed..1906fa35860c 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -466,7 +466,7 @@ error:
}
return -EINVAL;
}
-
+EXPORT_SYMBOL(ip_options_compile);
/*
* Undo all the changes done by ip_options_compile().
@@ -646,3 +646,4 @@ int ip_options_rcv_srr(struct sk_buff *skb)
}
return 0;
}
+EXPORT_SYMBOL(ip_options_rcv_srr);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 7649d7750075..439d2a34ee44 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -487,7 +487,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
* LATER: this step can be merged to real generation of fragments,
* we can switch to copy when see the first bad fragment.
*/
- if (skb_has_frags(skb)) {
+ if (skb_has_frag_list(skb)) {
struct sk_buff *frag, *frag2;
int first_len = skb_pagelen(skb);
@@ -844,10 +844,9 @@ int ip_append_data(struct sock *sk,
inet->cork.length = 0;
sk->sk_sndmsg_page = NULL;
sk->sk_sndmsg_off = 0;
- if ((exthdrlen = rt->dst.header_len) != 0) {
- length += exthdrlen;
- transhdrlen += exthdrlen;
- }
+ exthdrlen = rt->dst.header_len;
+ length += exthdrlen;
+ transhdrlen += exthdrlen;
} else {
rt = (struct rtable *)inet->cork.dst;
if (inet->cork.flags & IPCORK_OPT)
@@ -934,16 +933,19 @@ alloc_new_skb:
!(rt->dst.dev->features&NETIF_F_SG))
alloclen = mtu;
else
- alloclen = datalen + fragheaderlen;
+ alloclen = fraglen;
/* The last fragment gets additional space at tail.
* Note, with MSG_MORE we overallocate on fragments,
* because we have no idea what fragment will be
* the last.
*/
- if (datalen == length + fraggap)
+ if (datalen == length + fraggap) {
alloclen += rt->dst.trailer_len;
-
+ /* make sure mtu is not reached */
+ if (datalen > mtu - fragheaderlen - rt->dst.trailer_len)
+ datalen -= ALIGN(rt->dst.trailer_len, 8);
+ }
if (transhdrlen) {
skb = sock_alloc_send_skb(sk,
alloclen + hh_len + 15,
@@ -960,7 +962,7 @@ alloc_new_skb:
else
/* only the initial fragment is
time stamped */
- ipc->shtx.flags = 0;
+ ipc->tx_flags = 0;
}
if (skb == NULL)
goto error;
@@ -971,7 +973,7 @@ alloc_new_skb:
skb->ip_summed = csummode;
skb->csum = 0;
skb_reserve(skb, hh_len);
- *skb_tx(skb) = ipc->shtx;
+ skb_shinfo(skb)->tx_flags = ipc->tx_flags;
/*
* Find where to start putting bytes.
@@ -1391,7 +1393,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
daddr = ipc.addr = rt->rt_src;
ipc.opt = NULL;
- ipc.shtx.flags = 0;
+ ipc.tx_flags = 0;
if (replyopts.opt.optlen) {
ipc.opt = &replyopts.opt;
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index ec036731a70b..e9b816e6cd73 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -122,31 +122,59 @@
static int ipip_net_id __read_mostly;
struct ipip_net {
- struct ip_tunnel *tunnels_r_l[HASH_SIZE];
- struct ip_tunnel *tunnels_r[HASH_SIZE];
- struct ip_tunnel *tunnels_l[HASH_SIZE];
- struct ip_tunnel *tunnels_wc[1];
- struct ip_tunnel **tunnels[4];
+ struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE];
+ struct ip_tunnel __rcu *tunnels_r[HASH_SIZE];
+ struct ip_tunnel __rcu *tunnels_l[HASH_SIZE];
+ struct ip_tunnel __rcu *tunnels_wc[1];
+ struct ip_tunnel __rcu **tunnels[4];
struct net_device *fb_tunnel_dev;
};
-static void ipip_tunnel_init(struct net_device *dev);
+static int ipip_tunnel_init(struct net_device *dev);
static void ipip_tunnel_setup(struct net_device *dev);
+static void ipip_dev_free(struct net_device *dev);
/*
- * Locking : hash tables are protected by RCU and a spinlock
+ * Locking : hash tables are protected by RCU and RTNL
*/
-static DEFINE_SPINLOCK(ipip_lock);
#define for_each_ip_tunnel_rcu(start) \
for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
+/* often modified stats are per cpu, other are shared (netdev->stats) */
+struct pcpu_tstats {
+ unsigned long rx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_packets;
+ unsigned long tx_bytes;
+};
+
+static struct net_device_stats *ipip_get_stats(struct net_device *dev)
+{
+ struct pcpu_tstats sum = { 0 };
+ int i;
+
+ for_each_possible_cpu(i) {
+ const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
+
+ sum.rx_packets += tstats->rx_packets;
+ sum.rx_bytes += tstats->rx_bytes;
+ sum.tx_packets += tstats->tx_packets;
+ sum.tx_bytes += tstats->tx_bytes;
+ }
+ dev->stats.rx_packets = sum.rx_packets;
+ dev->stats.rx_bytes = sum.rx_bytes;
+ dev->stats.tx_packets = sum.tx_packets;
+ dev->stats.tx_bytes = sum.tx_bytes;
+ return &dev->stats;
+}
+
static struct ip_tunnel * ipip_tunnel_lookup(struct net *net,
__be32 remote, __be32 local)
{
- unsigned h0 = HASH(remote);
- unsigned h1 = HASH(local);
+ unsigned int h0 = HASH(remote);
+ unsigned int h1 = HASH(local);
struct ip_tunnel *t;
struct ipip_net *ipn = net_generic(net, ipip_net_id);
@@ -169,12 +197,12 @@ static struct ip_tunnel * ipip_tunnel_lookup(struct net *net,
return NULL;
}
-static struct ip_tunnel **__ipip_bucket(struct ipip_net *ipn,
+static struct ip_tunnel __rcu **__ipip_bucket(struct ipip_net *ipn,
struct ip_tunnel_parm *parms)
{
__be32 remote = parms->iph.daddr;
__be32 local = parms->iph.saddr;
- unsigned h = 0;
+ unsigned int h = 0;
int prio = 0;
if (remote) {
@@ -188,7 +216,7 @@ static struct ip_tunnel **__ipip_bucket(struct ipip_net *ipn,
return &ipn->tunnels[prio][h];
}
-static inline struct ip_tunnel **ipip_bucket(struct ipip_net *ipn,
+static inline struct ip_tunnel __rcu **ipip_bucket(struct ipip_net *ipn,
struct ip_tunnel *t)
{
return __ipip_bucket(ipn, &t->parms);
@@ -196,13 +224,14 @@ static inline struct ip_tunnel **ipip_bucket(struct ipip_net *ipn,
static void ipip_tunnel_unlink(struct ipip_net *ipn, struct ip_tunnel *t)
{
- struct ip_tunnel **tp;
-
- for (tp = ipip_bucket(ipn, t); *tp; tp = &(*tp)->next) {
- if (t == *tp) {
- spin_lock_bh(&ipip_lock);
- *tp = t->next;
- spin_unlock_bh(&ipip_lock);
+ struct ip_tunnel __rcu **tp;
+ struct ip_tunnel *iter;
+
+ for (tp = ipip_bucket(ipn, t);
+ (iter = rtnl_dereference(*tp)) != NULL;
+ tp = &iter->next) {
+ if (t == iter) {
+ rcu_assign_pointer(*tp, t->next);
break;
}
}
@@ -210,12 +239,10 @@ static void ipip_tunnel_unlink(struct ipip_net *ipn, struct ip_tunnel *t)
static void ipip_tunnel_link(struct ipip_net *ipn, struct ip_tunnel *t)
{
- struct ip_tunnel **tp = ipip_bucket(ipn, t);
+ struct ip_tunnel __rcu **tp = ipip_bucket(ipn, t);
- spin_lock_bh(&ipip_lock);
- t->next = *tp;
+ rcu_assign_pointer(t->next, rtnl_dereference(*tp));
rcu_assign_pointer(*tp, t);
- spin_unlock_bh(&ipip_lock);
}
static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
@@ -223,12 +250,15 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
{
__be32 remote = parms->iph.daddr;
__be32 local = parms->iph.saddr;
- struct ip_tunnel *t, **tp, *nt;
+ struct ip_tunnel *t, *nt;
+ struct ip_tunnel __rcu **tp;
struct net_device *dev;
char name[IFNAMSIZ];
struct ipip_net *ipn = net_generic(net, ipip_net_id);
- for (tp = __ipip_bucket(ipn, parms); (t = *tp) != NULL; tp = &t->next) {
+ for (tp = __ipip_bucket(ipn, parms);
+ (t = rtnl_dereference(*tp)) != NULL;
+ tp = &t->next) {
if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr)
return t;
}
@@ -238,7 +268,7 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
if (parms->name[0])
strlcpy(name, parms->name, IFNAMSIZ);
else
- sprintf(name, "tunl%%d");
+ strcpy(name, "tunl%d");
dev = alloc_netdev(sizeof(*t), name, ipip_tunnel_setup);
if (dev == NULL)
@@ -254,7 +284,8 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
nt = netdev_priv(dev);
nt->parms = *parms;
- ipip_tunnel_init(dev);
+ if (ipip_tunnel_init(dev) < 0)
+ goto failed_free;
if (register_netdevice(dev) < 0)
goto failed_free;
@@ -264,20 +295,19 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
return nt;
failed_free:
- free_netdev(dev);
+ ipip_dev_free(dev);
return NULL;
}
+/* called with RTNL */
static void ipip_tunnel_uninit(struct net_device *dev)
{
struct net *net = dev_net(dev);
struct ipip_net *ipn = net_generic(net, ipip_net_id);
- if (dev == ipn->fb_tunnel_dev) {
- spin_lock_bh(&ipip_lock);
- ipn->tunnels_wc[0] = NULL;
- spin_unlock_bh(&ipip_lock);
- } else
+ if (dev == ipn->fb_tunnel_dev)
+ rcu_assign_pointer(ipn->tunnels_wc[0], NULL);
+ else
ipip_tunnel_unlink(ipn, netdev_priv(dev));
dev_put(dev);
}
@@ -359,8 +389,10 @@ static int ipip_rcv(struct sk_buff *skb)
const struct iphdr *iph = ip_hdr(skb);
rcu_read_lock();
- if ((tunnel = ipip_tunnel_lookup(dev_net(skb->dev),
- iph->saddr, iph->daddr)) != NULL) {
+ tunnel = ipip_tunnel_lookup(dev_net(skb->dev), iph->saddr, iph->daddr);
+ if (tunnel != NULL) {
+ struct pcpu_tstats *tstats;
+
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
rcu_read_unlock();
kfree_skb(skb);
@@ -374,10 +406,16 @@ static int ipip_rcv(struct sk_buff *skb)
skb->protocol = htons(ETH_P_IP);
skb->pkt_type = PACKET_HOST;
- skb_tunnel_rx(skb, tunnel->dev);
+ tstats = this_cpu_ptr(tunnel->dev->tstats);
+ tstats->rx_packets++;
+ tstats->rx_bytes += skb->len;
+
+ __skb_tunnel_rx(skb, tunnel->dev);
ipip_ecn_decapsulate(iph, skb);
+
netif_rx(skb);
+
rcu_read_unlock();
return 0;
}
@@ -394,13 +432,12 @@ static int ipip_rcv(struct sk_buff *skb)
static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
- struct net_device_stats *stats = &dev->stats;
- struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+ struct pcpu_tstats *tstats;
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 net_device *tdev; /* Device to other host */
struct iphdr *old_iph = ip_hdr(skb);
struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
@@ -410,13 +447,13 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->protocol != htons(ETH_P_IP))
goto tx_error;
- if (tos&1)
+ if (tos & 1)
tos = old_iph->tos;
if (!dst) {
/* NBMA tunnel */
if ((rt = skb_rtable(skb)) == NULL) {
- stats->tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
goto tx_error;
}
if ((dst = rt->rt_gateway) == 0)
@@ -424,14 +461,20 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
}
{
- struct flowi fl = { .oif = tunnel->parms.link,
- .nl_u = { .ip4_u =
- { .daddr = dst,
- .saddr = tiph->saddr,
- .tos = RT_TOS(tos) } },
- .proto = IPPROTO_IPIP };
+ struct flowi fl = {
+ .oif = tunnel->parms.link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = dst,
+ .saddr = tiph->saddr,
+ .tos = RT_TOS(tos)
+ }
+ },
+ .proto = IPPROTO_IPIP
+ };
+
if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
- stats->tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
goto tx_error_icmp;
}
}
@@ -439,7 +482,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if (tdev == dev) {
ip_rt_put(rt);
- stats->collisions++;
+ dev->stats.collisions++;
goto tx_error;
}
@@ -449,7 +492,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr);
if (mtu < 68) {
- stats->collisions++;
+ dev->stats.collisions++;
ip_rt_put(rt);
goto tx_error;
}
@@ -485,7 +528,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
if (!new_skb) {
ip_rt_put(rt);
- txq->tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -522,14 +565,14 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
iph->ttl = old_iph->ttl;
nf_reset(skb);
-
- IPTUNNEL_XMIT();
+ tstats = this_cpu_ptr(dev->tstats);
+ __IPTUNNEL_XMIT(tstats, &dev->stats);
return NETDEV_TX_OK;
tx_error_icmp:
dst_link_failure(skb);
tx_error:
- stats->tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -544,13 +587,19 @@ static void ipip_tunnel_bind_dev(struct net_device *dev)
iph = &tunnel->parms.iph;
if (iph->daddr) {
- struct flowi fl = { .oif = tunnel->parms.link,
- .nl_u = { .ip4_u =
- { .daddr = iph->daddr,
- .saddr = iph->saddr,
- .tos = RT_TOS(iph->tos) } },
- .proto = IPPROTO_IPIP };
+ struct flowi fl = {
+ .oif = tunnel->parms.link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = iph->daddr,
+ .saddr = iph->saddr,
+ .tos = RT_TOS(iph->tos)
+ }
+ },
+ .proto = IPPROTO_IPIP
+ };
struct rtable *rt;
+
if (!ip_route_output_key(dev_net(dev), &rt, &fl)) {
tdev = rt->dst.dev;
ip_rt_put(rt);
@@ -696,13 +745,19 @@ static const struct net_device_ops ipip_netdev_ops = {
.ndo_start_xmit = ipip_tunnel_xmit,
.ndo_do_ioctl = ipip_tunnel_ioctl,
.ndo_change_mtu = ipip_tunnel_change_mtu,
-
+ .ndo_get_stats = ipip_get_stats,
};
+static void ipip_dev_free(struct net_device *dev)
+{
+ free_percpu(dev->tstats);
+ free_netdev(dev);
+}
+
static void ipip_tunnel_setup(struct net_device *dev)
{
dev->netdev_ops = &ipip_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = ipip_dev_free;
dev->type = ARPHRD_TUNNEL;
dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
@@ -711,10 +766,11 @@ static void ipip_tunnel_setup(struct net_device *dev)
dev->iflink = 0;
dev->addr_len = 4;
dev->features |= NETIF_F_NETNS_LOCAL;
+ dev->features |= NETIF_F_LLTX;
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
}
-static void ipip_tunnel_init(struct net_device *dev)
+static int ipip_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
@@ -725,9 +781,15 @@ static void ipip_tunnel_init(struct net_device *dev)
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
ipip_tunnel_bind_dev(dev);
+
+ dev->tstats = alloc_percpu(struct pcpu_tstats);
+ if (!dev->tstats)
+ return -ENOMEM;
+
+ return 0;
}
-static void __net_init ipip_fb_tunnel_init(struct net_device *dev)
+static int __net_init ipip_fb_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
struct iphdr *iph = &tunnel->parms.iph;
@@ -740,11 +802,16 @@ static void __net_init ipip_fb_tunnel_init(struct net_device *dev)
iph->protocol = IPPROTO_IPIP;
iph->ihl = 5;
+ dev->tstats = alloc_percpu(struct pcpu_tstats);
+ if (!dev->tstats)
+ return -ENOMEM;
+
dev_hold(dev);
- ipn->tunnels_wc[0] = tunnel;
+ rcu_assign_pointer(ipn->tunnels_wc[0], tunnel);
+ return 0;
}
-static struct xfrm_tunnel ipip_handler = {
+static struct xfrm_tunnel ipip_handler __read_mostly = {
.handler = ipip_rcv,
.err_handler = ipip_err,
.priority = 1,
@@ -760,11 +827,12 @@ static void ipip_destroy_tunnels(struct ipip_net *ipn, struct list_head *head)
for (prio = 1; prio < 4; prio++) {
int h;
for (h = 0; h < HASH_SIZE; h++) {
- struct ip_tunnel *t = ipn->tunnels[prio][h];
+ struct ip_tunnel *t;
+ t = rtnl_dereference(ipn->tunnels[prio][h]);
while (t != NULL) {
unregister_netdevice_queue(t->dev, head);
- t = t->next;
+ t = rtnl_dereference(t->next);
}
}
}
@@ -789,7 +857,9 @@ static int __net_init ipip_init_net(struct net *net)
}
dev_net_set(ipn->fb_tunnel_dev, net);
- ipip_fb_tunnel_init(ipn->fb_tunnel_dev);
+ err = ipip_fb_tunnel_init(ipn->fb_tunnel_dev);
+ if (err)
+ goto err_reg_dev;
if ((err = register_netdev(ipn->fb_tunnel_dev)))
goto err_reg_dev;
@@ -797,7 +867,7 @@ static int __net_init ipip_init_net(struct net *net)
return 0;
err_reg_dev:
- free_netdev(ipn->fb_tunnel_dev);
+ ipip_dev_free(ipn->fb_tunnel_dev);
err_alloc_dev:
/* nothing */
return err;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 179fcab866fc..86dd5691af46 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -75,7 +75,7 @@ struct mr_table {
struct net *net;
#endif
u32 id;
- struct sock *mroute_sk;
+ struct sock __rcu *mroute_sk;
struct timer_list ipmr_expire_timer;
struct list_head mfc_unres_queue;
struct list_head mfc_cache_array[MFC_LINES];
@@ -98,7 +98,7 @@ struct ipmr_result {
};
/* Big lock, protecting vif table, mrt cache and mroute socket state.
- Note that the changes are semaphored via rtnl_lock.
+ * Note that the changes are semaphored via rtnl_lock.
*/
static DEFINE_RWLOCK(mrt_lock);
@@ -113,11 +113,11 @@ static DEFINE_RWLOCK(mrt_lock);
static DEFINE_SPINLOCK(mfc_unres_lock);
/* We return to original Alan's scheme. Hash table of resolved
- entries is changed only in process context and protected
- with weak lock mrt_lock. Queue of unresolved entries is protected
- with strong spinlock mfc_unres_lock.
-
- In this case data path is free of exclusive locks at all.
+ * entries is changed only in process context and protected
+ * with weak lock mrt_lock. Queue of unresolved entries is protected
+ * with strong spinlock mfc_unres_lock.
+ *
+ * In this case data path is free of exclusive locks at all.
*/
static struct kmem_cache *mrt_cachep __read_mostly;
@@ -396,9 +396,9 @@ struct net_device *ipmr_new_tunnel(struct net *net, struct vifctl *v)
set_fs(KERNEL_DS);
err = ops->ndo_do_ioctl(dev, &ifr, SIOCADDTUNNEL);
set_fs(oldfs);
- } else
+ } else {
err = -EOPNOTSUPP;
-
+ }
dev = NULL;
if (err == 0 &&
@@ -495,7 +495,8 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt)
dev->iflink = 0;
rcu_read_lock();
- if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
+ in_dev = __in_dev_get_rcu(dev);
+ if (!in_dev) {
rcu_read_unlock();
goto failure;
}
@@ -552,9 +553,10 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify,
mrt->mroute_reg_vif_num = -1;
#endif
- if (vifi+1 == mrt->maxvif) {
+ if (vifi + 1 == mrt->maxvif) {
int tmp;
- for (tmp=vifi-1; tmp>=0; tmp--) {
+
+ for (tmp = vifi - 1; tmp >= 0; tmp--) {
if (VIF_EXISTS(mrt, tmp))
break;
}
@@ -565,25 +567,33 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify,
dev_set_allmulti(dev, -1);
- if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
+ in_dev = __in_dev_get_rtnl(dev);
+ if (in_dev) {
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--;
ip_rt_multicast_event(in_dev);
}
- if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER) && !notify)
+ if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER) && !notify)
unregister_netdevice_queue(dev, head);
dev_put(dev);
return 0;
}
-static inline void ipmr_cache_free(struct mfc_cache *c)
+static void ipmr_cache_free_rcu(struct rcu_head *head)
{
+ struct mfc_cache *c = container_of(head, struct mfc_cache, rcu);
+
kmem_cache_free(mrt_cachep, c);
}
+static inline void ipmr_cache_free(struct mfc_cache *c)
+{
+ call_rcu(&c->rcu, ipmr_cache_free_rcu);
+}
+
/* Destroy an unresolved cache entry, killing queued skbs
- and reporting error to netlink readers.
+ * and reporting error to netlink readers.
*/
static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
@@ -605,8 +615,9 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
memset(&e->msg, 0, sizeof(e->msg));
rtnl_unicast(skb, net, NETLINK_CB(skb).pid);
- } else
+ } else {
kfree_skb(skb);
+ }
}
ipmr_cache_free(c);
@@ -724,13 +735,13 @@ static int vif_add(struct net *net, struct mr_table *mrt,
case 0:
if (vifc->vifc_flags == VIFF_USE_IFINDEX) {
dev = dev_get_by_index(net, vifc->vifc_lcl_ifindex);
- if (dev && dev->ip_ptr == NULL) {
+ if (dev && __in_dev_get_rtnl(dev) == NULL) {
dev_put(dev);
return -EADDRNOTAVAIL;
}
- } else
+ } else {
dev = ip_dev_find(net, vifc->vifc_lcl_addr.s_addr);
-
+ }
if (!dev)
return -EADDRNOTAVAIL;
err = dev_set_allmulti(dev, 1);
@@ -743,16 +754,16 @@ static int vif_add(struct net *net, struct mr_table *mrt,
return -EINVAL;
}
- if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) {
+ in_dev = __in_dev_get_rtnl(dev);
+ if (!in_dev) {
dev_put(dev);
return -EADDRNOTAVAIL;
}
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
ip_rt_multicast_event(in_dev);
- /*
- * Fill in the VIF structures
- */
+ /* Fill in the VIF structures */
+
v->rate_limit = vifc->vifc_rate_limit;
v->local = vifc->vifc_lcl_addr.s_addr;
v->remote = vifc->vifc_rmt_addr.s_addr;
@@ -765,14 +776,14 @@ static int vif_add(struct net *net, struct mr_table *mrt,
v->pkt_in = 0;
v->pkt_out = 0;
v->link = dev->ifindex;
- if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER))
+ if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER))
v->link = dev->iflink;
/* And finish update writing critical data */
write_lock_bh(&mrt_lock);
v->dev = dev;
#ifdef CONFIG_IP_PIMSM
- if (v->flags&VIFF_REGISTER)
+ if (v->flags & VIFF_REGISTER)
mrt->mroute_reg_vif_num = vifi;
#endif
if (vifi+1 > mrt->maxvif)
@@ -781,6 +792,7 @@ static int vif_add(struct net *net, struct mr_table *mrt,
return 0;
}
+/* called with rcu_read_lock() */
static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt,
__be32 origin,
__be32 mcastgrp)
@@ -788,7 +800,7 @@ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt,
int line = MFC_HASH(mcastgrp, origin);
struct mfc_cache *c;
- list_for_each_entry(c, &mrt->mfc_cache_array[line], list) {
+ list_for_each_entry_rcu(c, &mrt->mfc_cache_array[line], list) {
if (c->mfc_origin == origin && c->mfc_mcastgrp == mcastgrp)
return c;
}
@@ -801,19 +813,20 @@ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt,
static struct mfc_cache *ipmr_cache_alloc(void)
{
struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
- if (c == NULL)
- return NULL;
- c->mfc_un.res.minvif = MAXVIFS;
+
+ if (c)
+ c->mfc_un.res.minvif = MAXVIFS;
return c;
}
static struct mfc_cache *ipmr_cache_alloc_unres(void)
{
struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
- if (c == NULL)
- return NULL;
- skb_queue_head_init(&c->mfc_un.unres.unresolved);
- c->mfc_un.unres.expires = jiffies + 10*HZ;
+
+ if (c) {
+ skb_queue_head_init(&c->mfc_un.unres.unresolved);
+ c->mfc_un.unres.expires = jiffies + 10*HZ;
+ }
return c;
}
@@ -827,17 +840,15 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
struct sk_buff *skb;
struct nlmsgerr *e;
- /*
- * Play the pending entries through our router
- */
+ /* Play the pending entries through our router */
while ((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) {
if (ip_hdr(skb)->version == 0) {
struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr));
if (__ipmr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) {
- nlh->nlmsg_len = (skb_tail_pointer(skb) -
- (u8 *)nlh);
+ nlh->nlmsg_len = skb_tail_pointer(skb) -
+ (u8 *)nlh;
} else {
nlh->nlmsg_type = NLMSG_ERROR;
nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
@@ -848,8 +859,9 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
}
rtnl_unicast(skb, net, NETLINK_CB(skb).pid);
- } else
+ } else {
ip_mr_forward(net, mrt, skb, c, 0);
+ }
}
}
@@ -867,6 +879,7 @@ static int ipmr_cache_report(struct mr_table *mrt,
const int ihl = ip_hdrlen(pkt);
struct igmphdr *igmp;
struct igmpmsg *msg;
+ struct sock *mroute_sk;
int ret;
#ifdef CONFIG_IP_PIMSM
@@ -882,9 +895,9 @@ static int ipmr_cache_report(struct mr_table *mrt,
#ifdef CONFIG_IP_PIMSM
if (assert == IGMPMSG_WHOLEPKT) {
/* Ugly, but we have no choice with this interface.
- Duplicate old header, fix ihl, length etc.
- And all this only to mangle msg->im_msgtype and
- to set msg->im_mbz to "mbz" :-)
+ * Duplicate old header, fix ihl, length etc.
+ * And all this only to mangle msg->im_msgtype and
+ * to set msg->im_mbz to "mbz" :-)
*/
skb_push(skb, sizeof(struct iphdr));
skb_reset_network_header(skb);
@@ -901,39 +914,38 @@ static int ipmr_cache_report(struct mr_table *mrt,
#endif
{
- /*
- * Copy the IP header
- */
+ /* Copy the IP header */
skb->network_header = skb->tail;
skb_put(skb, ihl);
skb_copy_to_linear_data(skb, pkt->data, ihl);
- ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */
+ ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */
msg = (struct igmpmsg *)skb_network_header(skb);
msg->im_vif = vifi;
skb_dst_set(skb, dst_clone(skb_dst(pkt)));
- /*
- * Add our header
- */
+ /* Add our header */
- igmp=(struct igmphdr *)skb_put(skb, sizeof(struct igmphdr));
+ igmp = (struct igmphdr *)skb_put(skb, sizeof(struct igmphdr));
igmp->type =
msg->im_msgtype = assert;
- igmp->code = 0;
- ip_hdr(skb)->tot_len = htons(skb->len); /* Fix the length */
+ igmp->code = 0;
+ ip_hdr(skb)->tot_len = htons(skb->len); /* Fix the length */
skb->transport_header = skb->network_header;
}
- if (mrt->mroute_sk == NULL) {
+ rcu_read_lock();
+ mroute_sk = rcu_dereference(mrt->mroute_sk);
+ if (mroute_sk == NULL) {
+ rcu_read_unlock();
kfree_skb(skb);
return -EINVAL;
}
- /*
- * Deliver to mrouted
- */
- ret = sock_queue_rcv_skb(mrt->mroute_sk, skb);
+ /* Deliver to mrouted */
+
+ ret = sock_queue_rcv_skb(mroute_sk, skb);
+ rcu_read_unlock();
if (ret < 0) {
if (net_ratelimit())
printk(KERN_WARNING "mroute: pending queue full, dropping entries.\n");
@@ -965,9 +977,7 @@ ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb)
}
if (!found) {
- /*
- * Create a new entry if allowable
- */
+ /* Create a new entry if allowable */
if (atomic_read(&mrt->cache_resolve_queue_len) >= 10 ||
(c = ipmr_cache_alloc_unres()) == NULL) {
@@ -977,16 +987,14 @@ ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb)
return -ENOBUFS;
}
- /*
- * Fill in the new cache entry
- */
+ /* Fill in the new cache entry */
+
c->mfc_parent = -1;
c->mfc_origin = iph->saddr;
c->mfc_mcastgrp = iph->daddr;
- /*
- * Reflect first query at mrouted.
- */
+ /* Reflect first query at mrouted. */
+
err = ipmr_cache_report(mrt, skb, vifi, IGMPMSG_NOCACHE);
if (err < 0) {
/* If the report failed throw the cache entry
@@ -1006,10 +1014,9 @@ ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb)
mod_timer(&mrt->ipmr_expire_timer, c->mfc_un.unres.expires);
}
- /*
- * See if we can append the packet
- */
- if (c->mfc_un.unres.unresolved.qlen>3) {
+ /* See if we can append the packet */
+
+ if (c->mfc_un.unres.unresolved.qlen > 3) {
kfree_skb(skb);
err = -ENOBUFS;
} else {
@@ -1035,9 +1042,7 @@ static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc)
list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[line], list) {
if (c->mfc_origin == mfc->mfcc_origin.s_addr &&
c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) {
- write_lock_bh(&mrt_lock);
- list_del(&c->list);
- write_unlock_bh(&mrt_lock);
+ list_del_rcu(&c->list);
ipmr_cache_free(c);
return 0;
@@ -1090,9 +1095,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
if (!mrtsock)
c->mfc_flags |= MFC_STATIC;
- write_lock_bh(&mrt_lock);
- list_add(&c->list, &mrt->mfc_cache_array[line]);
- write_unlock_bh(&mrt_lock);
+ list_add_rcu(&c->list, &mrt->mfc_cache_array[line]);
/*
* Check to see if we resolved a queued list. If so we
@@ -1130,26 +1133,21 @@ static void mroute_clean_tables(struct mr_table *mrt)
LIST_HEAD(list);
struct mfc_cache *c, *next;
- /*
- * Shut down all active vif entries
- */
+ /* Shut down all active vif entries */
+
for (i = 0; i < mrt->maxvif; i++) {
- if (!(mrt->vif_table[i].flags&VIFF_STATIC))
+ if (!(mrt->vif_table[i].flags & VIFF_STATIC))
vif_delete(mrt, i, 0, &list);
}
unregister_netdevice_many(&list);
- /*
- * Wipe the cache
- */
+ /* Wipe the cache */
+
for (i = 0; i < MFC_LINES; i++) {
list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) {
- if (c->mfc_flags&MFC_STATIC)
+ if (c->mfc_flags & MFC_STATIC)
continue;
- write_lock_bh(&mrt_lock);
- list_del(&c->list);
- write_unlock_bh(&mrt_lock);
-
+ list_del_rcu(&c->list);
ipmr_cache_free(c);
}
}
@@ -1164,6 +1162,9 @@ static void mroute_clean_tables(struct mr_table *mrt)
}
}
+/* called from ip_ra_control(), before an RCU grace period,
+ * we dont need to call synchronize_rcu() here
+ */
static void mrtsock_destruct(struct sock *sk)
{
struct net *net = sock_net(sk);
@@ -1171,13 +1172,9 @@ static void mrtsock_destruct(struct sock *sk)
rtnl_lock();
ipmr_for_each_table(mrt, net) {
- if (sk == mrt->mroute_sk) {
+ if (sk == rtnl_dereference(mrt->mroute_sk)) {
IPV4_DEVCONF_ALL(net, MC_FORWARDING)--;
-
- write_lock_bh(&mrt_lock);
- mrt->mroute_sk = NULL;
- write_unlock_bh(&mrt_lock);
-
+ rcu_assign_pointer(mrt->mroute_sk, NULL);
mroute_clean_tables(mrt);
}
}
@@ -1204,7 +1201,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
return -ENOENT;
if (optname != MRT_INIT) {
- if (sk != mrt->mroute_sk && !capable(CAP_NET_ADMIN))
+ if (sk != rcu_dereference_raw(mrt->mroute_sk) &&
+ !capable(CAP_NET_ADMIN))
return -EACCES;
}
@@ -1217,23 +1215,20 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
return -ENOPROTOOPT;
rtnl_lock();
- if (mrt->mroute_sk) {
+ if (rtnl_dereference(mrt->mroute_sk)) {
rtnl_unlock();
return -EADDRINUSE;
}
ret = ip_ra_control(sk, 1, mrtsock_destruct);
if (ret == 0) {
- write_lock_bh(&mrt_lock);
- mrt->mroute_sk = sk;
- write_unlock_bh(&mrt_lock);
-
+ rcu_assign_pointer(mrt->mroute_sk, sk);
IPV4_DEVCONF_ALL(net, MC_FORWARDING)++;
}
rtnl_unlock();
return ret;
case MRT_DONE:
- if (sk != mrt->mroute_sk)
+ if (sk != rcu_dereference_raw(mrt->mroute_sk))
return -EACCES;
return ip_ra_control(sk, 0, NULL);
case MRT_ADD_VIF:
@@ -1246,7 +1241,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
return -ENFILE;
rtnl_lock();
if (optname == MRT_ADD_VIF) {
- ret = vif_add(net, mrt, &vif, sk == mrt->mroute_sk);
+ ret = vif_add(net, mrt, &vif,
+ sk == rtnl_dereference(mrt->mroute_sk));
} else {
ret = vif_delete(mrt, vif.vifc_vifi, 0, NULL);
}
@@ -1267,7 +1263,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
if (optname == MRT_DEL_MFC)
ret = ipmr_mfc_delete(mrt, &mfc);
else
- ret = ipmr_mfc_add(net, mrt, &mfc, sk == mrt->mroute_sk);
+ ret = ipmr_mfc_add(net, mrt, &mfc,
+ sk == rtnl_dereference(mrt->mroute_sk));
rtnl_unlock();
return ret;
/*
@@ -1276,7 +1273,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
case MRT_ASSERT:
{
int v;
- if (get_user(v,(int __user *)optval))
+ if (get_user(v, (int __user *)optval))
return -EFAULT;
mrt->mroute_do_assert = (v) ? 1 : 0;
return 0;
@@ -1286,7 +1283,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
{
int v;
- if (get_user(v,(int __user *)optval))
+ if (get_user(v, (int __user *)optval))
return -EFAULT;
v = (v) ? 1 : 0;
@@ -1309,14 +1306,16 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
return -EINVAL;
if (get_user(v, (u32 __user *)optval))
return -EFAULT;
- if (sk == mrt->mroute_sk)
- return -EBUSY;
rtnl_lock();
ret = 0;
- if (!ipmr_new_table(net, v))
- ret = -ENOMEM;
- raw_sk(sk)->ipmr_table = v;
+ if (sk == rtnl_dereference(mrt->mroute_sk)) {
+ ret = -EBUSY;
+ } else {
+ if (!ipmr_new_table(net, v))
+ ret = -ENOMEM;
+ raw_sk(sk)->ipmr_table = v;
+ }
rtnl_unlock();
return ret;
}
@@ -1347,9 +1346,9 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, int
if (optname != MRT_VERSION &&
#ifdef CONFIG_IP_PIMSM
- optname!=MRT_PIM &&
+ optname != MRT_PIM &&
#endif
- optname!=MRT_ASSERT)
+ optname != MRT_ASSERT)
return -ENOPROTOOPT;
if (get_user(olr, optlen))
@@ -1416,19 +1415,19 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
if (copy_from_user(&sr, arg, sizeof(sr)))
return -EFAULT;
- read_lock(&mrt_lock);
+ rcu_read_lock();
c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
if (c) {
sr.pktcnt = c->mfc_un.res.pkt;
sr.bytecnt = c->mfc_un.res.bytes;
sr.wrong_if = c->mfc_un.res.wrong_if;
- read_unlock(&mrt_lock);
+ rcu_read_unlock();
if (copy_to_user(arg, &sr, sizeof(sr)))
return -EFAULT;
return 0;
}
- read_unlock(&mrt_lock);
+ rcu_read_unlock();
return -EADDRNOTAVAIL;
default:
return -ENOIOCTLCMD;
@@ -1465,7 +1464,7 @@ static struct notifier_block ip_mr_notifier = {
};
/*
- * Encapsulate a packet by attaching a valid IPIP header to it.
+ * Encapsulate a packet by attaching a valid IPIP header to it.
* This avoids tunnel drivers and other mess and gives us the speed so
* important for multicast video.
*/
@@ -1480,7 +1479,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr)
skb_reset_network_header(skb);
iph = ip_hdr(skb);
- iph->version = 4;
+ iph->version = 4;
iph->tos = old_iph->tos;
iph->ttl = old_iph->ttl;
iph->frag_off = 0;
@@ -1498,7 +1497,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr)
static inline int ipmr_forward_finish(struct sk_buff *skb)
{
- struct ip_options * opt = &(IPCB(skb)->opt);
+ struct ip_options *opt = &(IPCB(skb)->opt);
IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS);
@@ -1535,22 +1534,34 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
}
#endif
- if (vif->flags&VIFF_TUNNEL) {
- struct flowi fl = { .oif = vif->link,
- .nl_u = { .ip4_u =
- { .daddr = vif->remote,
- .saddr = vif->local,
- .tos = RT_TOS(iph->tos) } },
- .proto = IPPROTO_IPIP };
+ if (vif->flags & VIFF_TUNNEL) {
+ struct flowi fl = {
+ .oif = vif->link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = vif->remote,
+ .saddr = vif->local,
+ .tos = RT_TOS(iph->tos)
+ }
+ },
+ .proto = IPPROTO_IPIP
+ };
+
if (ip_route_output_key(net, &rt, &fl))
goto out_free;
encap = sizeof(struct iphdr);
} else {
- struct flowi fl = { .oif = vif->link,
- .nl_u = { .ip4_u =
- { .daddr = iph->daddr,
- .tos = RT_TOS(iph->tos) } },
- .proto = IPPROTO_IPIP };
+ struct flowi fl = {
+ .oif = vif->link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = iph->daddr,
+ .tos = RT_TOS(iph->tos)
+ }
+ },
+ .proto = IPPROTO_IPIP
+ };
+
if (ip_route_output_key(net, &rt, &fl))
goto out_free;
}
@@ -1559,8 +1570,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
if (skb->len+encap > dst_mtu(&rt->dst) && (ntohs(iph->frag_off) & IP_DF)) {
/* Do not fragment multicasts. Alas, IPv4 does not
- allow to send ICMP, so that packets will disappear
- to blackhole.
+ * allow to send ICMP, so that packets will disappear
+ * to blackhole.
*/
IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
@@ -1583,7 +1594,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
ip_decrease_ttl(ip_hdr(skb));
/* FIXME: forward and output firewalls used to be called here.
- * What do we do with netfilter? -- RR */
+ * What do we do with netfilter? -- RR
+ */
if (vif->flags & VIFF_TUNNEL) {
ip_encap(skb, vif->local, vif->remote);
/* FIXME: extra output firewall step used to be here. --RR */
@@ -1644,15 +1656,15 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
if (skb_rtable(skb)->fl.iif == 0) {
/* It is our own packet, looped back.
- Very complicated situation...
-
- The best workaround until routing daemons will be
- fixed is not to redistribute packet, if it was
- send through wrong interface. It means, that
- multicast applications WILL NOT work for
- (S,G), which have default multicast route pointing
- to wrong oif. In any case, it is not a good
- idea to use multicasting applications on router.
+ * Very complicated situation...
+ *
+ * The best workaround until routing daemons will be
+ * fixed is not to redistribute packet, if it was
+ * send through wrong interface. It means, that
+ * multicast applications WILL NOT work for
+ * (S,G), which have default multicast route pointing
+ * to wrong oif. In any case, it is not a good
+ * idea to use multicasting applications on router.
*/
goto dont_forward;
}
@@ -1662,9 +1674,9 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
if (true_vifi >= 0 && mrt->mroute_do_assert &&
/* pimsm uses asserts, when switching from RPT to SPT,
- so that we cannot check that packet arrived on an oif.
- It is bad, but otherwise we would need to move pretty
- large chunk of pimd to kernel. Ough... --ANK
+ * so that we cannot check that packet arrived on an oif.
+ * It is bad, but otherwise we would need to move pretty
+ * large chunk of pimd to kernel. Ough... --ANK
*/
(mrt->mroute_do_pim ||
cache->mfc_un.res.ttls[true_vifi] < 255) &&
@@ -1682,10 +1694,12 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
/*
* Forward the frame
*/
- for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) {
+ for (ct = cache->mfc_un.res.maxvif - 1;
+ ct >= cache->mfc_un.res.minvif; ct--) {
if (ip_hdr(skb)->ttl > cache->mfc_un.res.ttls[ct]) {
if (psend != -1) {
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
+
if (skb2)
ipmr_queue_xmit(net, mrt, skb2, cache,
psend);
@@ -1696,6 +1710,7 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
if (psend != -1) {
if (local) {
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
+
if (skb2)
ipmr_queue_xmit(net, mrt, skb2, cache, psend);
} else {
@@ -1713,6 +1728,7 @@ dont_forward:
/*
* Multicast packets for forwarding arrive here
+ * Called with rcu_read_lock();
*/
int ip_mr_input(struct sk_buff *skb)
@@ -1724,9 +1740,9 @@ int ip_mr_input(struct sk_buff *skb)
int err;
/* Packet is looped back after forward, it should not be
- forwarded second time, but still can be delivered locally.
+ * forwarded second time, but still can be delivered locally.
*/
- if (IPCB(skb)->flags&IPSKB_FORWARDED)
+ if (IPCB(skb)->flags & IPSKB_FORWARDED)
goto dont_forward;
err = ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt);
@@ -1736,28 +1752,28 @@ int ip_mr_input(struct sk_buff *skb)
}
if (!local) {
- if (IPCB(skb)->opt.router_alert) {
- if (ip_call_ra_chain(skb))
- return 0;
- } else if (ip_hdr(skb)->protocol == IPPROTO_IGMP){
- /* IGMPv1 (and broken IGMPv2 implementations sort of
- Cisco IOS <= 11.2(8)) do not put router alert
- option to IGMP packets destined to routable
- groups. It is very bad, because it means
- that we can forward NO IGMP messages.
- */
- read_lock(&mrt_lock);
- if (mrt->mroute_sk) {
- nf_reset(skb);
- raw_rcv(mrt->mroute_sk, skb);
- read_unlock(&mrt_lock);
- return 0;
- }
- read_unlock(&mrt_lock);
+ if (IPCB(skb)->opt.router_alert) {
+ if (ip_call_ra_chain(skb))
+ return 0;
+ } else if (ip_hdr(skb)->protocol == IPPROTO_IGMP) {
+ /* IGMPv1 (and broken IGMPv2 implementations sort of
+ * Cisco IOS <= 11.2(8)) do not put router alert
+ * option to IGMP packets destined to routable
+ * groups. It is very bad, because it means
+ * that we can forward NO IGMP messages.
+ */
+ struct sock *mroute_sk;
+
+ mroute_sk = rcu_dereference(mrt->mroute_sk);
+ if (mroute_sk) {
+ nf_reset(skb);
+ raw_rcv(mroute_sk, skb);
+ return 0;
+ }
}
}
- read_lock(&mrt_lock);
+ /* already under rcu_read_lock() */
cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr);
/*
@@ -1769,13 +1785,12 @@ int ip_mr_input(struct sk_buff *skb)
if (local) {
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
ip_local_deliver(skb);
- if (skb2 == NULL) {
- read_unlock(&mrt_lock);
+ if (skb2 == NULL)
return -ENOBUFS;
- }
skb = skb2;
}
+ read_lock(&mrt_lock);
vif = ipmr_find_vif(mrt, skb->dev);
if (vif >= 0) {
int err2 = ipmr_cache_unresolved(mrt, vif, skb);
@@ -1788,8 +1803,8 @@ int ip_mr_input(struct sk_buff *skb)
return -ENODEV;
}
+ read_lock(&mrt_lock);
ip_mr_forward(net, mrt, skb, cache, local);
-
read_unlock(&mrt_lock);
if (local)
@@ -1805,6 +1820,7 @@ dont_forward:
}
#ifdef CONFIG_IP_PIMSM
+/* called with rcu_read_lock() */
static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb,
unsigned int pimlen)
{
@@ -1813,10 +1829,10 @@ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb,
encap = (struct iphdr *)(skb_transport_header(skb) + pimlen);
/*
- Check that:
- a. packet is really destinted to a multicast group
- b. packet is not a NULL-REGISTER
- c. packet is not truncated
+ * Check that:
+ * a. packet is really sent to a multicast group
+ * b. packet is not a NULL-REGISTER
+ * c. packet is not truncated
*/
if (!ipv4_is_multicast(encap->daddr) ||
encap->tot_len == 0 ||
@@ -1826,26 +1842,23 @@ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb,
read_lock(&mrt_lock);
if (mrt->mroute_reg_vif_num >= 0)
reg_dev = mrt->vif_table[mrt->mroute_reg_vif_num].dev;
- if (reg_dev)
- dev_hold(reg_dev);
read_unlock(&mrt_lock);
if (reg_dev == NULL)
return 1;
skb->mac_header = skb->network_header;
- skb_pull(skb, (u8*)encap - skb->data);
+ skb_pull(skb, (u8 *)encap - skb->data);
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_IP);
- skb->ip_summed = 0;
+ skb->ip_summed = CHECKSUM_NONE;
skb->pkt_type = PACKET_HOST;
skb_tunnel_rx(skb, reg_dev);
netif_rx(skb);
- dev_put(reg_dev);
- return 0;
+ return NET_RX_SUCCESS;
}
#endif
@@ -1854,7 +1867,7 @@ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb,
* Handle IGMP messages of PIMv1
*/
-int pim_rcv_v1(struct sk_buff * skb)
+int pim_rcv_v1(struct sk_buff *skb)
{
struct igmphdr *pim;
struct net *net = dev_net(skb->dev);
@@ -1881,7 +1894,7 @@ drop:
#endif
#ifdef CONFIG_IP_PIMSM_V2
-static int pim_rcv(struct sk_buff * skb)
+static int pim_rcv(struct sk_buff *skb)
{
struct pimreghdr *pim;
struct net *net = dev_net(skb->dev);
@@ -1891,8 +1904,8 @@ static int pim_rcv(struct sk_buff * skb)
goto drop;
pim = (struct pimreghdr *)skb_transport_header(skb);
- if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) ||
- (pim->flags&PIM_NULL_REGISTER) ||
+ if (pim->type != ((PIM_VERSION << 4) | (PIM_REGISTER)) ||
+ (pim->flags & PIM_NULL_REGISTER) ||
(ip_compute_csum((void *)pim, sizeof(*pim)) != 0 &&
csum_fold(skb_checksum(skb, 0, skb->len, 0))))
goto drop;
@@ -1958,28 +1971,33 @@ int ipmr_get_route(struct net *net,
if (mrt == NULL)
return -ENOENT;
- read_lock(&mrt_lock);
+ rcu_read_lock();
cache = ipmr_cache_find(mrt, rt->rt_src, rt->rt_dst);
if (cache == NULL) {
struct sk_buff *skb2;
struct iphdr *iph;
struct net_device *dev;
- int vif;
+ int vif = -1;
if (nowait) {
- read_unlock(&mrt_lock);
+ rcu_read_unlock();
return -EAGAIN;
}
dev = skb->dev;
- if (dev == NULL || (vif = ipmr_find_vif(mrt, dev)) < 0) {
+ read_lock(&mrt_lock);
+ if (dev)
+ vif = ipmr_find_vif(mrt, dev);
+ if (vif < 0) {
read_unlock(&mrt_lock);
+ rcu_read_unlock();
return -ENODEV;
}
skb2 = skb_clone(skb, GFP_ATOMIC);
if (!skb2) {
read_unlock(&mrt_lock);
+ rcu_read_unlock();
return -ENOMEM;
}
@@ -1992,13 +2010,16 @@ int ipmr_get_route(struct net *net,
iph->version = 0;
err = ipmr_cache_unresolved(mrt, vif, skb2);
read_unlock(&mrt_lock);
+ rcu_read_unlock();
return err;
}
- if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY))
+ read_lock(&mrt_lock);
+ if (!nowait && (rtm->rtm_flags & RTM_F_NOTIFY))
cache->mfc_flags |= MFC_NOTIFY;
err = __ipmr_fill_mroute(mrt, skb, cache, rtm);
read_unlock(&mrt_lock);
+ rcu_read_unlock();
return err;
}
@@ -2050,14 +2071,14 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
s_h = cb->args[1];
s_e = cb->args[2];
- read_lock(&mrt_lock);
+ rcu_read_lock();
ipmr_for_each_table(mrt, net) {
if (t < s_t)
goto next_table;
if (t > s_t)
s_h = 0;
for (h = s_h; h < MFC_LINES; h++) {
- list_for_each_entry(mfc, &mrt->mfc_cache_array[h], list) {
+ list_for_each_entry_rcu(mfc, &mrt->mfc_cache_array[h], list) {
if (e < s_e)
goto next_entry;
if (ipmr_fill_mroute(mrt, skb,
@@ -2075,7 +2096,7 @@ next_table:
t++;
}
done:
- read_unlock(&mrt_lock);
+ rcu_read_unlock();
cb->args[2] = e;
cb->args[1] = h;
@@ -2086,7 +2107,8 @@ done:
#ifdef CONFIG_PROC_FS
/*
- * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif
+ * The /proc interfaces to multicast routing :
+ * /proc/net/ip_mr_cache & /proc/net/ip_mr_vif
*/
struct ipmr_vif_iter {
struct seq_net_private p;
@@ -2208,14 +2230,14 @@ static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net,
struct mr_table *mrt = it->mrt;
struct mfc_cache *mfc;
- read_lock(&mrt_lock);
+ rcu_read_lock();
for (it->ct = 0; it->ct < MFC_LINES; it->ct++) {
it->cache = &mrt->mfc_cache_array[it->ct];
- list_for_each_entry(mfc, it->cache, list)
+ list_for_each_entry_rcu(mfc, it->cache, list)
if (pos-- == 0)
return mfc;
}
- read_unlock(&mrt_lock);
+ rcu_read_unlock();
spin_lock_bh(&mfc_unres_lock);
it->cache = &mrt->mfc_unres_queue;
@@ -2274,7 +2296,7 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
/* exhausted cache_array, show unresolved */
- read_unlock(&mrt_lock);
+ rcu_read_unlock();
it->cache = &mrt->mfc_unres_queue;
it->ct = 0;
@@ -2282,7 +2304,7 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
if (!list_empty(it->cache))
return list_first_entry(it->cache, struct mfc_cache, list);
- end_of_list:
+end_of_list:
spin_unlock_bh(&mfc_unres_lock);
it->cache = NULL;
@@ -2297,7 +2319,7 @@ static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
if (it->cache == &mrt->mfc_unres_queue)
spin_unlock_bh(&mfc_unres_lock);
else if (it->cache == &mrt->mfc_cache_array[it->ct])
- read_unlock(&mrt_lock);
+ rcu_read_unlock();
}
static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
@@ -2323,7 +2345,7 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
mfc->mfc_un.res.bytes,
mfc->mfc_un.res.wrong_if);
for (n = mfc->mfc_un.res.minvif;
- n < mfc->mfc_un.res.maxvif; n++ ) {
+ n < mfc->mfc_un.res.maxvif; n++) {
if (VIF_EXISTS(mrt, n) &&
mfc->mfc_un.res.ttls[n] < 255)
seq_printf(seq,
@@ -2421,7 +2443,7 @@ int __init ip_mr_init(void)
mrt_cachep = kmem_cache_create("ip_mrt_cache",
sizeof(struct mfc_cache),
- 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
+ 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC,
NULL);
if (!mrt_cachep)
return -ENOMEM;
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 1833bdbf9805..8e3350643b63 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -324,10 +324,10 @@ config IP_NF_TARGET_ECN
config IP_NF_TARGET_TTL
tristate '"TTL" target support'
- depends on NETFILTER_ADVANCED
+ depends on NETFILTER_ADVANCED && IP_NF_MANGLE
select NETFILTER_XT_TARGET_HL
---help---
- This is a backwards-compat option for the user's convenience
+ This is a backwards-compatible option for the user's convenience
(e.g. when running oldconfig). It selects
CONFIG_NETFILTER_XT_TARGET_HL.
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index e8f4f9a57f12..3cad2591ace0 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -72,7 +72,7 @@ static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
for (i = 0; i < len; i++)
ret |= (hdr_addr[i] ^ ap->addr[i]) & ap->mask[i];
- return (ret != 0);
+ return ret != 0;
}
/*
@@ -228,7 +228,7 @@ arpt_error(struct sk_buff *skb, const struct xt_action_param *par)
return NF_DROP;
}
-static inline const struct arpt_entry_target *
+static inline const struct xt_entry_target *
arpt_get_target_c(const struct arpt_entry *e)
{
return arpt_get_target((struct arpt_entry *)e);
@@ -282,7 +282,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
arp = arp_hdr(skb);
do {
- const struct arpt_entry_target *t;
+ const struct xt_entry_target *t;
if (!arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
e = arpt_next_entry(e);
@@ -297,10 +297,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
if (!t->u.kernel.target->target) {
int v;
- v = ((struct arpt_standard_target *)t)->verdict;
+ v = ((struct xt_standard_target *)t)->verdict;
if (v < 0) {
/* Pop from stack? */
- if (v != ARPT_RETURN) {
+ if (v != XT_RETURN) {
verdict = (unsigned)(-v) - 1;
break;
}
@@ -332,7 +332,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
/* Target might have changed stuff. */
arp = arp_hdr(skb);
- if (verdict == ARPT_CONTINUE)
+ if (verdict == XT_CONTINUE)
e = arpt_next_entry(e);
else
/* Verdict */
@@ -377,7 +377,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
e->counters.pcnt = pos;
for (;;) {
- const struct arpt_standard_target *t
+ const struct xt_standard_target *t
= (void *)arpt_get_target_c(e);
int visited = e->comefrom & (1 << hook);
@@ -392,13 +392,13 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
/* Unconditional return/END. */
if ((e->target_offset == sizeof(struct arpt_entry) &&
(strcmp(t->target.u.user.name,
- ARPT_STANDARD_TARGET) == 0) &&
+ XT_STANDARD_TARGET) == 0) &&
t->verdict < 0 && unconditional(&e->arp)) ||
visited) {
unsigned int oldpos, size;
if ((strcmp(t->target.u.user.name,
- ARPT_STANDARD_TARGET) == 0) &&
+ XT_STANDARD_TARGET) == 0) &&
t->verdict < -NF_MAX_VERDICT - 1) {
duprintf("mark_source_chains: bad "
"negative verdict (%i)\n",
@@ -433,7 +433,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
int newpos = t->verdict;
if (strcmp(t->target.u.user.name,
- ARPT_STANDARD_TARGET) == 0 &&
+ XT_STANDARD_TARGET) == 0 &&
newpos >= 0) {
if (newpos > newinfo->size -
sizeof(struct arpt_entry)) {
@@ -464,14 +464,14 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
static inline int check_entry(const struct arpt_entry *e, const char *name)
{
- const struct arpt_entry_target *t;
+ const struct xt_entry_target *t;
if (!arp_checkentry(&e->arp)) {
duprintf("arp_tables: arp check failed %p %s.\n", e, name);
return -EINVAL;
}
- if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset)
+ if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset)
return -EINVAL;
t = arpt_get_target_c(e);
@@ -483,7 +483,7 @@ static inline int check_entry(const struct arpt_entry *e, const char *name)
static inline int check_target(struct arpt_entry *e, const char *name)
{
- struct arpt_entry_target *t = arpt_get_target(e);
+ struct xt_entry_target *t = arpt_get_target(e);
int ret;
struct xt_tgchk_param par = {
.table = name,
@@ -506,7 +506,7 @@ static inline int check_target(struct arpt_entry *e, const char *name)
static inline int
find_check_entry(struct arpt_entry *e, const char *name, unsigned int size)
{
- struct arpt_entry_target *t;
+ struct xt_entry_target *t;
struct xt_target *target;
int ret;
@@ -536,7 +536,7 @@ out:
static bool check_underflow(const struct arpt_entry *e)
{
- const struct arpt_entry_target *t;
+ const struct xt_entry_target *t;
unsigned int verdict;
if (!unconditional(&e->arp))
@@ -544,7 +544,7 @@ static bool check_underflow(const struct arpt_entry *e)
t = arpt_get_target_c(e);
if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
return false;
- verdict = ((struct arpt_standard_target *)t)->verdict;
+ verdict = ((struct xt_standard_target *)t)->verdict;
verdict = -verdict - 1;
return verdict == NF_DROP || verdict == NF_ACCEPT;
}
@@ -566,7 +566,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
}
if (e->next_offset
- < sizeof(struct arpt_entry) + sizeof(struct arpt_entry_target)) {
+ < sizeof(struct arpt_entry) + sizeof(struct xt_entry_target)) {
duprintf("checking: element %p size %u\n",
e, e->next_offset);
return -EINVAL;
@@ -598,7 +598,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
static inline void cleanup_entry(struct arpt_entry *e)
{
struct xt_tgdtor_param par;
- struct arpt_entry_target *t;
+ struct xt_entry_target *t;
t = arpt_get_target(e);
par.target = t->u.kernel.target;
@@ -794,7 +794,7 @@ static int copy_entries_to_user(unsigned int total_size,
/* FIXME: use iterator macros --RR */
/* ... then go back and fix counters and names */
for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
- const struct arpt_entry_target *t;
+ const struct xt_entry_target *t;
e = (struct arpt_entry *)(loc_cpu_entry + off);
if (copy_to_user(userptr + off
@@ -807,7 +807,7 @@ static int copy_entries_to_user(unsigned int total_size,
t = arpt_get_target_c(e);
if (copy_to_user(userptr + off + e->target_offset
- + offsetof(struct arpt_entry_target,
+ + offsetof(struct xt_entry_target,
u.user.name),
t->u.kernel.target->name,
strlen(t->u.kernel.target->name)+1) != 0) {
@@ -844,7 +844,7 @@ static int compat_calc_entry(const struct arpt_entry *e,
const struct xt_table_info *info,
const void *base, struct xt_table_info *newinfo)
{
- const struct arpt_entry_target *t;
+ const struct xt_entry_target *t;
unsigned int entry_offset;
int off, i, ret;
@@ -895,7 +895,7 @@ static int compat_table_info(const struct xt_table_info *info,
static int get_info(struct net *net, void __user *user,
const int *len, int compat)
{
- char name[ARPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
struct xt_table *t;
int ret;
@@ -908,7 +908,7 @@ static int get_info(struct net *net, void __user *user,
if (copy_from_user(name, user, sizeof(name)) != 0)
return -EFAULT;
- name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
+ name[XT_TABLE_MAXNAMELEN-1] = '\0';
#ifdef CONFIG_COMPAT
if (compat)
xt_compat_lock(NFPROTO_ARP);
@@ -1204,7 +1204,7 @@ static int do_add_counters(struct net *net, const void __user *user,
#ifdef CONFIG_COMPAT
static inline void compat_release_entry(struct compat_arpt_entry *e)
{
- struct arpt_entry_target *t;
+ struct xt_entry_target *t;
t = compat_arpt_get_target(e);
module_put(t->u.kernel.target->me);
@@ -1220,7 +1220,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
const unsigned int *underflows,
const char *name)
{
- struct arpt_entry_target *t;
+ struct xt_entry_target *t;
struct xt_target *target;
unsigned int entry_offset;
int ret, off, h;
@@ -1288,7 +1288,7 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
unsigned int *size, const char *name,
struct xt_table_info *newinfo, unsigned char *base)
{
- struct arpt_entry_target *t;
+ struct xt_entry_target *t;
struct xt_target *target;
struct arpt_entry *de;
unsigned int origsize;
@@ -1474,7 +1474,7 @@ out_unlock:
}
struct compat_arpt_replace {
- char name[ARPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
u32 valid_hooks;
u32 num_entries;
u32 size;
@@ -1567,7 +1567,7 @@ static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr,
struct xt_counters *counters,
unsigned int i)
{
- struct arpt_entry_target *t;
+ struct xt_entry_target *t;
struct compat_arpt_entry __user *ce;
u_int16_t target_offset, next_offset;
compat_uint_t origsize;
@@ -1628,7 +1628,7 @@ static int compat_copy_entries_to_user(unsigned int total_size,
}
struct compat_arpt_get_entries {
- char name[ARPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
compat_uint_t size;
struct compat_arpt_entry entrytable[0];
};
@@ -1828,7 +1828,7 @@ void arpt_unregister_table(struct xt_table *table)
/* The built-in targets: standard (NULL) and error. */
static struct xt_target arpt_builtin_tg[] __read_mostly = {
{
- .name = ARPT_STANDARD_TARGET,
+ .name = XT_STANDARD_TARGET,
.targetsize = sizeof(int),
.family = NFPROTO_ARP,
#ifdef CONFIG_COMPAT
@@ -1838,9 +1838,9 @@ static struct xt_target arpt_builtin_tg[] __read_mostly = {
#endif
},
{
- .name = ARPT_ERROR_TARGET,
+ .name = XT_ERROR_TARGET,
.target = arpt_error,
- .targetsize = ARPT_FUNCTION_MAXNAMELEN,
+ .targetsize = XT_FUNCTION_MAXNAMELEN,
.family = NFPROTO_ARP,
},
};
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index e1be7dd1171b..b8ddcc480ed9 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -63,7 +63,7 @@ static int checkentry(const struct xt_tgchk_param *par)
return false;
if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT &&
- mangle->target != ARPT_CONTINUE)
+ mangle->target != XT_CONTINUE)
return false;
return true;
}
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index d163f2e3b2e9..d31b007a6d80 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -186,7 +186,7 @@ static inline bool unconditional(const struct ipt_ip *ip)
}
/* for const-correctness */
-static inline const struct ipt_entry_target *
+static inline const struct xt_entry_target *
ipt_get_target_c(const struct ipt_entry *e)
{
return ipt_get_target((struct ipt_entry *)e);
@@ -230,9 +230,9 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e,
const char *hookname, const char **chainname,
const char **comment, unsigned int *rulenum)
{
- const struct ipt_standard_target *t = (void *)ipt_get_target_c(s);
+ const struct xt_standard_target *t = (void *)ipt_get_target_c(s);
- if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) {
+ if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) {
/* Head of user chain: ERROR target with chainname */
*chainname = t->target.data;
(*rulenum) = 0;
@@ -241,7 +241,7 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e,
if (s->target_offset == sizeof(struct ipt_entry) &&
strcmp(t->target.u.kernel.target->name,
- IPT_STANDARD_TARGET) == 0 &&
+ XT_STANDARD_TARGET) == 0 &&
t->verdict < 0 &&
unconditional(&s->ip)) {
/* Tail of chains: STANDARD target (return/policy) */
@@ -346,7 +346,7 @@ ipt_do_table(struct sk_buff *skb,
get_entry(table_base, private->underflow[hook]));
do {
- const struct ipt_entry_target *t;
+ const struct xt_entry_target *t;
const struct xt_entry_match *ematch;
IP_NF_ASSERT(e);
@@ -380,10 +380,10 @@ ipt_do_table(struct sk_buff *skb,
if (!t->u.kernel.target->target) {
int v;
- v = ((struct ipt_standard_target *)t)->verdict;
+ v = ((struct xt_standard_target *)t)->verdict;
if (v < 0) {
/* Pop from stack? */
- if (v != IPT_RETURN) {
+ if (v != XT_RETURN) {
verdict = (unsigned)(-v) - 1;
break;
}
@@ -421,7 +421,7 @@ ipt_do_table(struct sk_buff *skb,
verdict = t->u.kernel.target->target(skb, &acpar);
/* Target might have changed stuff. */
ip = ip_hdr(skb);
- if (verdict == IPT_CONTINUE)
+ if (verdict == XT_CONTINUE)
e = ipt_next_entry(e);
else
/* Verdict */
@@ -461,7 +461,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
e->counters.pcnt = pos;
for (;;) {
- const struct ipt_standard_target *t
+ const struct xt_standard_target *t
= (void *)ipt_get_target_c(e);
int visited = e->comefrom & (1 << hook);
@@ -475,13 +475,13 @@ mark_source_chains(const struct xt_table_info *newinfo,
/* Unconditional return/END. */
if ((e->target_offset == sizeof(struct ipt_entry) &&
(strcmp(t->target.u.user.name,
- IPT_STANDARD_TARGET) == 0) &&
+ XT_STANDARD_TARGET) == 0) &&
t->verdict < 0 && unconditional(&e->ip)) ||
visited) {
unsigned int oldpos, size;
if ((strcmp(t->target.u.user.name,
- IPT_STANDARD_TARGET) == 0) &&
+ XT_STANDARD_TARGET) == 0) &&
t->verdict < -NF_MAX_VERDICT - 1) {
duprintf("mark_source_chains: bad "
"negative verdict (%i)\n",
@@ -524,7 +524,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
int newpos = t->verdict;
if (strcmp(t->target.u.user.name,
- IPT_STANDARD_TARGET) == 0 &&
+ XT_STANDARD_TARGET) == 0 &&
newpos >= 0) {
if (newpos > newinfo->size -
sizeof(struct ipt_entry)) {
@@ -552,7 +552,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
return 1;
}
-static void cleanup_match(struct ipt_entry_match *m, struct net *net)
+static void cleanup_match(struct xt_entry_match *m, struct net *net)
{
struct xt_mtdtor_param par;
@@ -568,14 +568,14 @@ static void cleanup_match(struct ipt_entry_match *m, struct net *net)
static int
check_entry(const struct ipt_entry *e, const char *name)
{
- const struct ipt_entry_target *t;
+ const struct xt_entry_target *t;
if (!ip_checkentry(&e->ip)) {
duprintf("ip check failed %p %s.\n", e, par->match->name);
return -EINVAL;
}
- if (e->target_offset + sizeof(struct ipt_entry_target) >
+ if (e->target_offset + sizeof(struct xt_entry_target) >
e->next_offset)
return -EINVAL;
@@ -587,7 +587,7 @@ check_entry(const struct ipt_entry *e, const char *name)
}
static int
-check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par)
+check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
{
const struct ipt_ip *ip = par->entryinfo;
int ret;
@@ -605,7 +605,7 @@ check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par)
}
static int
-find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par)
+find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
{
struct xt_match *match;
int ret;
@@ -630,7 +630,7 @@ err:
static int check_target(struct ipt_entry *e, struct net *net, const char *name)
{
- struct ipt_entry_target *t = ipt_get_target(e);
+ struct xt_entry_target *t = ipt_get_target(e);
struct xt_tgchk_param par = {
.net = net,
.table = name,
@@ -656,7 +656,7 @@ static int
find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
unsigned int size)
{
- struct ipt_entry_target *t;
+ struct xt_entry_target *t;
struct xt_target *target;
int ret;
unsigned int j;
@@ -707,7 +707,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
static bool check_underflow(const struct ipt_entry *e)
{
- const struct ipt_entry_target *t;
+ const struct xt_entry_target *t;
unsigned int verdict;
if (!unconditional(&e->ip))
@@ -715,7 +715,7 @@ static bool check_underflow(const struct ipt_entry *e)
t = ipt_get_target_c(e);
if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
return false;
- verdict = ((struct ipt_standard_target *)t)->verdict;
+ verdict = ((struct xt_standard_target *)t)->verdict;
verdict = -verdict - 1;
return verdict == NF_DROP || verdict == NF_ACCEPT;
}
@@ -738,7 +738,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
}
if (e->next_offset
- < sizeof(struct ipt_entry) + sizeof(struct ipt_entry_target)) {
+ < sizeof(struct ipt_entry) + sizeof(struct xt_entry_target)) {
duprintf("checking: element %p size %u\n",
e, e->next_offset);
return -EINVAL;
@@ -771,7 +771,7 @@ static void
cleanup_entry(struct ipt_entry *e, struct net *net)
{
struct xt_tgdtor_param par;
- struct ipt_entry_target *t;
+ struct xt_entry_target *t;
struct xt_entry_match *ematch;
/* Cleanup all matches */
@@ -972,8 +972,8 @@ copy_entries_to_user(unsigned int total_size,
/* ... then go back and fix counters and names */
for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
unsigned int i;
- const struct ipt_entry_match *m;
- const struct ipt_entry_target *t;
+ const struct xt_entry_match *m;
+ const struct xt_entry_target *t;
e = (struct ipt_entry *)(loc_cpu_entry + off);
if (copy_to_user(userptr + off
@@ -990,7 +990,7 @@ copy_entries_to_user(unsigned int total_size,
m = (void *)e + i;
if (copy_to_user(userptr + off + i
- + offsetof(struct ipt_entry_match,
+ + offsetof(struct xt_entry_match,
u.user.name),
m->u.kernel.match->name,
strlen(m->u.kernel.match->name)+1)
@@ -1002,7 +1002,7 @@ copy_entries_to_user(unsigned int total_size,
t = ipt_get_target_c(e);
if (copy_to_user(userptr + off + e->target_offset
- + offsetof(struct ipt_entry_target,
+ + offsetof(struct xt_entry_target,
u.user.name),
t->u.kernel.target->name,
strlen(t->u.kernel.target->name)+1) != 0) {
@@ -1040,7 +1040,7 @@ static int compat_calc_entry(const struct ipt_entry *e,
const void *base, struct xt_table_info *newinfo)
{
const struct xt_entry_match *ematch;
- const struct ipt_entry_target *t;
+ const struct xt_entry_target *t;
unsigned int entry_offset;
int off, i, ret;
@@ -1092,7 +1092,7 @@ static int compat_table_info(const struct xt_table_info *info,
static int get_info(struct net *net, void __user *user,
const int *len, int compat)
{
- char name[IPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
struct xt_table *t;
int ret;
@@ -1105,7 +1105,7 @@ static int get_info(struct net *net, void __user *user,
if (copy_from_user(name, user, sizeof(name)) != 0)
return -EFAULT;
- name[IPT_TABLE_MAXNAMELEN-1] = '\0';
+ name[XT_TABLE_MAXNAMELEN-1] = '\0';
#ifdef CONFIG_COMPAT
if (compat)
xt_compat_lock(AF_INET);
@@ -1400,14 +1400,14 @@ do_add_counters(struct net *net, const void __user *user,
#ifdef CONFIG_COMPAT
struct compat_ipt_replace {
- char name[IPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
u32 valid_hooks;
u32 num_entries;
u32 size;
u32 hook_entry[NF_INET_NUMHOOKS];
u32 underflow[NF_INET_NUMHOOKS];
u32 num_counters;
- compat_uptr_t counters; /* struct ipt_counters * */
+ compat_uptr_t counters; /* struct xt_counters * */
struct compat_ipt_entry entries[0];
};
@@ -1416,7 +1416,7 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
unsigned int *size, struct xt_counters *counters,
unsigned int i)
{
- struct ipt_entry_target *t;
+ struct xt_entry_target *t;
struct compat_ipt_entry __user *ce;
u_int16_t target_offset, next_offset;
compat_uint_t origsize;
@@ -1451,7 +1451,7 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
}
static int
-compat_find_calc_match(struct ipt_entry_match *m,
+compat_find_calc_match(struct xt_entry_match *m,
const char *name,
const struct ipt_ip *ip,
unsigned int hookmask,
@@ -1473,7 +1473,7 @@ compat_find_calc_match(struct ipt_entry_match *m,
static void compat_release_entry(struct compat_ipt_entry *e)
{
- struct ipt_entry_target *t;
+ struct xt_entry_target *t;
struct xt_entry_match *ematch;
/* Cleanup all matches */
@@ -1494,7 +1494,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
const char *name)
{
struct xt_entry_match *ematch;
- struct ipt_entry_target *t;
+ struct xt_entry_target *t;
struct xt_target *target;
unsigned int entry_offset;
unsigned int j;
@@ -1576,7 +1576,7 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
unsigned int *size, const char *name,
struct xt_table_info *newinfo, unsigned char *base)
{
- struct ipt_entry_target *t;
+ struct xt_entry_target *t;
struct xt_target *target;
struct ipt_entry *de;
unsigned int origsize;
@@ -1884,7 +1884,7 @@ compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user,
}
struct compat_ipt_get_entries {
- char name[IPT_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
compat_uint_t size;
struct compat_ipt_entry entrytable[0];
};
@@ -2039,7 +2039,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
case IPT_SO_GET_REVISION_MATCH:
case IPT_SO_GET_REVISION_TARGET: {
- struct ipt_get_revision rev;
+ struct xt_get_revision rev;
int target;
if (*len != sizeof(rev)) {
@@ -2176,7 +2176,7 @@ static int icmp_checkentry(const struct xt_mtchk_param *par)
static struct xt_target ipt_builtin_tg[] __read_mostly = {
{
- .name = IPT_STANDARD_TARGET,
+ .name = XT_STANDARD_TARGET,
.targetsize = sizeof(int),
.family = NFPROTO_IPV4,
#ifdef CONFIG_COMPAT
@@ -2186,9 +2186,9 @@ static struct xt_target ipt_builtin_tg[] __read_mostly = {
#endif
},
{
- .name = IPT_ERROR_TARGET,
+ .name = XT_ERROR_TARGET,
.target = ipt_error,
- .targetsize = IPT_FUNCTION_MAXNAMELEN,
+ .targetsize = XT_FUNCTION_MAXNAMELEN,
.family = NFPROTO_IPV4,
},
};
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 3a43cf36db87..1e26a4897655 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -29,6 +29,7 @@
#include <net/netfilter/nf_conntrack.h>
#include <net/net_namespace.h>
#include <net/checksum.h>
+#include <net/ip.h>
#define CLUSTERIP_VERSION "0.8"
@@ -231,24 +232,22 @@ clusterip_hashfn(const struct sk_buff *skb,
{
const struct iphdr *iph = ip_hdr(skb);
unsigned long hashval;
- u_int16_t sport, dport;
- const u_int16_t *ports;
-
- switch (iph->protocol) {
- case IPPROTO_TCP:
- case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
- case IPPROTO_SCTP:
- case IPPROTO_DCCP:
- case IPPROTO_ICMP:
- ports = (const void *)iph+iph->ihl*4;
- sport = ports[0];
- dport = ports[1];
- break;
- default:
+ u_int16_t sport = 0, dport = 0;
+ int poff;
+
+ poff = proto_ports_offset(iph->protocol);
+ if (poff >= 0) {
+ const u_int16_t *ports;
+ u16 _ports[2];
+
+ ports = skb_header_pointer(skb, iph->ihl * 4 + poff, 4, _ports);
+ if (ports) {
+ sport = ports[0];
+ dport = ports[1];
+ }
+ } else {
if (net_ratelimit())
pr_info("unknown protocol %u\n", iph->protocol);
- sport = dport = 0;
}
switch (config->hash_mode) {
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index 915fc17d7ce2..72ffc8fda2e9 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -24,16 +24,15 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ipt_LOG.h>
#include <net/netfilter/nf_log.h>
+#include <net/netfilter/xt_log.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
MODULE_DESCRIPTION("Xtables: IPv4 packet logging to syslog");
-/* Use lock to serialize, so printks don't overlap */
-static DEFINE_SPINLOCK(log_lock);
-
/* One level of recursion won't kill us */
-static void dump_packet(const struct nf_loginfo *info,
+static void dump_packet(struct sbuff *m,
+ const struct nf_loginfo *info,
const struct sk_buff *skb,
unsigned int iphoff)
{
@@ -48,32 +47,32 @@ static void dump_packet(const struct nf_loginfo *info,
ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
if (ih == NULL) {
- printk("TRUNCATED");
+ sb_add(m, "TRUNCATED");
return;
}
/* Important fields:
* TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
- printk("SRC=%pI4 DST=%pI4 ",
+ sb_add(m, "SRC=%pI4 DST=%pI4 ",
&ih->saddr, &ih->daddr);
/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
- printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
+ sb_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK,
ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id));
/* Max length: 6 "CE DF MF " */
if (ntohs(ih->frag_off) & IP_CE)
- printk("CE ");
+ sb_add(m, "CE ");
if (ntohs(ih->frag_off) & IP_DF)
- printk("DF ");
+ sb_add(m, "DF ");
if (ntohs(ih->frag_off) & IP_MF)
- printk("MF ");
+ sb_add(m, "MF ");
/* Max length: 11 "FRAG:65535 " */
if (ntohs(ih->frag_off) & IP_OFFSET)
- printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
+ sb_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
if ((logflags & IPT_LOG_IPOPT) &&
ih->ihl * 4 > sizeof(struct iphdr)) {
@@ -85,15 +84,15 @@ static void dump_packet(const struct nf_loginfo *info,
op = skb_header_pointer(skb, iphoff+sizeof(_iph),
optsize, _opt);
if (op == NULL) {
- printk("TRUNCATED");
+ sb_add(m, "TRUNCATED");
return;
}
/* Max length: 127 "OPT (" 15*4*2chars ") " */
- printk("OPT (");
+ sb_add(m, "OPT (");
for (i = 0; i < optsize; i++)
- printk("%02X", op[i]);
- printk(") ");
+ sb_add(m, "%02X", op[i]);
+ sb_add(m, ") ");
}
switch (ih->protocol) {
@@ -102,7 +101,7 @@ static void dump_packet(const struct nf_loginfo *info,
const struct tcphdr *th;
/* Max length: 10 "PROTO=TCP " */
- printk("PROTO=TCP ");
+ sb_add(m, "PROTO=TCP ");
if (ntohs(ih->frag_off) & IP_OFFSET)
break;
@@ -111,41 +110,41 @@ static void dump_packet(const struct nf_loginfo *info,
th = skb_header_pointer(skb, iphoff + ih->ihl * 4,
sizeof(_tcph), &_tcph);
if (th == NULL) {
- printk("INCOMPLETE [%u bytes] ",
+ sb_add(m, "INCOMPLETE [%u bytes] ",
skb->len - iphoff - ih->ihl*4);
break;
}
/* Max length: 20 "SPT=65535 DPT=65535 " */
- printk("SPT=%u DPT=%u ",
+ sb_add(m, "SPT=%u DPT=%u ",
ntohs(th->source), ntohs(th->dest));
/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
if (logflags & IPT_LOG_TCPSEQ)
- printk("SEQ=%u ACK=%u ",
+ sb_add(m, "SEQ=%u ACK=%u ",
ntohl(th->seq), ntohl(th->ack_seq));
/* Max length: 13 "WINDOW=65535 " */
- printk("WINDOW=%u ", ntohs(th->window));
+ sb_add(m, "WINDOW=%u ", ntohs(th->window));
/* Max length: 9 "RES=0x3F " */
- printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22));
+ sb_add(m, "RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22));
/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
if (th->cwr)
- printk("CWR ");
+ sb_add(m, "CWR ");
if (th->ece)
- printk("ECE ");
+ sb_add(m, "ECE ");
if (th->urg)
- printk("URG ");
+ sb_add(m, "URG ");
if (th->ack)
- printk("ACK ");
+ sb_add(m, "ACK ");
if (th->psh)
- printk("PSH ");
+ sb_add(m, "PSH ");
if (th->rst)
- printk("RST ");
+ sb_add(m, "RST ");
if (th->syn)
- printk("SYN ");
+ sb_add(m, "SYN ");
if (th->fin)
- printk("FIN ");
+ sb_add(m, "FIN ");
/* Max length: 11 "URGP=65535 " */
- printk("URGP=%u ", ntohs(th->urg_ptr));
+ sb_add(m, "URGP=%u ", ntohs(th->urg_ptr));
if ((logflags & IPT_LOG_TCPOPT) &&
th->doff * 4 > sizeof(struct tcphdr)) {
@@ -158,15 +157,15 @@ static void dump_packet(const struct nf_loginfo *info,
iphoff+ih->ihl*4+sizeof(_tcph),
optsize, _opt);
if (op == NULL) {
- printk("TRUNCATED");
+ sb_add(m, "TRUNCATED");
return;
}
/* Max length: 127 "OPT (" 15*4*2chars ") " */
- printk("OPT (");
+ sb_add(m, "OPT (");
for (i = 0; i < optsize; i++)
- printk("%02X", op[i]);
- printk(") ");
+ sb_add(m, "%02X", op[i]);
+ sb_add(m, ") ");
}
break;
}
@@ -177,9 +176,9 @@ static void dump_packet(const struct nf_loginfo *info,
if (ih->protocol == IPPROTO_UDP)
/* Max length: 10 "PROTO=UDP " */
- printk("PROTO=UDP " );
+ sb_add(m, "PROTO=UDP " );
else /* Max length: 14 "PROTO=UDPLITE " */
- printk("PROTO=UDPLITE ");
+ sb_add(m, "PROTO=UDPLITE ");
if (ntohs(ih->frag_off) & IP_OFFSET)
break;
@@ -188,13 +187,13 @@ static void dump_packet(const struct nf_loginfo *info,
uh = skb_header_pointer(skb, iphoff+ih->ihl*4,
sizeof(_udph), &_udph);
if (uh == NULL) {
- printk("INCOMPLETE [%u bytes] ",
+ sb_add(m, "INCOMPLETE [%u bytes] ",
skb->len - iphoff - ih->ihl*4);
break;
}
/* Max length: 20 "SPT=65535 DPT=65535 " */
- printk("SPT=%u DPT=%u LEN=%u ",
+ sb_add(m, "SPT=%u DPT=%u LEN=%u ",
ntohs(uh->source), ntohs(uh->dest),
ntohs(uh->len));
break;
@@ -221,7 +220,7 @@ static void dump_packet(const struct nf_loginfo *info,
[ICMP_ADDRESSREPLY] = 12 };
/* Max length: 11 "PROTO=ICMP " */
- printk("PROTO=ICMP ");
+ sb_add(m, "PROTO=ICMP ");
if (ntohs(ih->frag_off) & IP_OFFSET)
break;
@@ -230,19 +229,19 @@ static void dump_packet(const struct nf_loginfo *info,
ich = skb_header_pointer(skb, iphoff + ih->ihl * 4,
sizeof(_icmph), &_icmph);
if (ich == NULL) {
- printk("INCOMPLETE [%u bytes] ",
+ sb_add(m, "INCOMPLETE [%u bytes] ",
skb->len - iphoff - ih->ihl*4);
break;
}
/* Max length: 18 "TYPE=255 CODE=255 " */
- printk("TYPE=%u CODE=%u ", ich->type, ich->code);
+ sb_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code);
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if (ich->type <= NR_ICMP_TYPES &&
required_len[ich->type] &&
skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
- printk("INCOMPLETE [%u bytes] ",
+ sb_add(m, "INCOMPLETE [%u bytes] ",
skb->len - iphoff - ih->ihl*4);
break;
}
@@ -251,35 +250,35 @@ static void dump_packet(const struct nf_loginfo *info,
case ICMP_ECHOREPLY:
case ICMP_ECHO:
/* Max length: 19 "ID=65535 SEQ=65535 " */
- printk("ID=%u SEQ=%u ",
+ sb_add(m, "ID=%u SEQ=%u ",
ntohs(ich->un.echo.id),
ntohs(ich->un.echo.sequence));
break;
case ICMP_PARAMETERPROB:
/* Max length: 14 "PARAMETER=255 " */
- printk("PARAMETER=%u ",
+ sb_add(m, "PARAMETER=%u ",
ntohl(ich->un.gateway) >> 24);
break;
case ICMP_REDIRECT:
/* Max length: 24 "GATEWAY=255.255.255.255 " */
- printk("GATEWAY=%pI4 ", &ich->un.gateway);
+ sb_add(m, "GATEWAY=%pI4 ", &ich->un.gateway);
/* Fall through */
case ICMP_DEST_UNREACH:
case ICMP_SOURCE_QUENCH:
case ICMP_TIME_EXCEEDED:
/* Max length: 3+maxlen */
if (!iphoff) { /* Only recurse once. */
- printk("[");
- dump_packet(info, skb,
+ sb_add(m, "[");
+ dump_packet(m, info, skb,
iphoff + ih->ihl*4+sizeof(_icmph));
- printk("] ");
+ sb_add(m, "] ");
}
/* Max length: 10 "MTU=65535 " */
if (ich->type == ICMP_DEST_UNREACH &&
ich->code == ICMP_FRAG_NEEDED)
- printk("MTU=%u ", ntohs(ich->un.frag.mtu));
+ sb_add(m, "MTU=%u ", ntohs(ich->un.frag.mtu));
}
break;
}
@@ -292,19 +291,19 @@ static void dump_packet(const struct nf_loginfo *info,
break;
/* Max length: 9 "PROTO=AH " */
- printk("PROTO=AH ");
+ sb_add(m, "PROTO=AH ");
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
ah = skb_header_pointer(skb, iphoff+ih->ihl*4,
sizeof(_ahdr), &_ahdr);
if (ah == NULL) {
- printk("INCOMPLETE [%u bytes] ",
+ sb_add(m, "INCOMPLETE [%u bytes] ",
skb->len - iphoff - ih->ihl*4);
break;
}
/* Length: 15 "SPI=0xF1234567 " */
- printk("SPI=0x%x ", ntohl(ah->spi));
+ sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
break;
}
case IPPROTO_ESP: {
@@ -312,7 +311,7 @@ static void dump_packet(const struct nf_loginfo *info,
const struct ip_esp_hdr *eh;
/* Max length: 10 "PROTO=ESP " */
- printk("PROTO=ESP ");
+ sb_add(m, "PROTO=ESP ");
if (ntohs(ih->frag_off) & IP_OFFSET)
break;
@@ -321,25 +320,25 @@ static void dump_packet(const struct nf_loginfo *info,
eh = skb_header_pointer(skb, iphoff+ih->ihl*4,
sizeof(_esph), &_esph);
if (eh == NULL) {
- printk("INCOMPLETE [%u bytes] ",
+ sb_add(m, "INCOMPLETE [%u bytes] ",
skb->len - iphoff - ih->ihl*4);
break;
}
/* Length: 15 "SPI=0xF1234567 " */
- printk("SPI=0x%x ", ntohl(eh->spi));
+ sb_add(m, "SPI=0x%x ", ntohl(eh->spi));
break;
}
/* Max length: 10 "PROTO 255 " */
default:
- printk("PROTO=%u ", ih->protocol);
+ sb_add(m, "PROTO=%u ", ih->protocol);
}
/* Max length: 15 "UID=4294967295 " */
if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) {
read_lock_bh(&skb->sk->sk_callback_lock);
if (skb->sk->sk_socket && skb->sk->sk_socket->file)
- printk("UID=%u GID=%u ",
+ sb_add(m, "UID=%u GID=%u ",
skb->sk->sk_socket->file->f_cred->fsuid,
skb->sk->sk_socket->file->f_cred->fsgid);
read_unlock_bh(&skb->sk->sk_callback_lock);
@@ -347,7 +346,7 @@ static void dump_packet(const struct nf_loginfo *info,
/* Max length: 16 "MARK=0xFFFFFFFF " */
if (!iphoff && skb->mark)
- printk("MARK=0x%x ", skb->mark);
+ sb_add(m, "MARK=0x%x ", skb->mark);
/* Proto Max log string length */
/* IP: 40+46+6+11+127 = 230 */
@@ -364,7 +363,8 @@ static void dump_packet(const struct nf_loginfo *info,
/* maxlen = 230+ 91 + 230 + 252 = 803 */
}
-static void dump_mac_header(const struct nf_loginfo *info,
+static void dump_mac_header(struct sbuff *m,
+ const struct nf_loginfo *info,
const struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
@@ -378,7 +378,7 @@ static void dump_mac_header(const struct nf_loginfo *info,
switch (dev->type) {
case ARPHRD_ETHER:
- printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
+ sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
ntohs(eth_hdr(skb)->h_proto));
return;
@@ -387,17 +387,17 @@ static void dump_mac_header(const struct nf_loginfo *info,
}
fallback:
- printk("MAC=");
+ sb_add(m, "MAC=");
if (dev->hard_header_len &&
skb->mac_header != skb->network_header) {
const unsigned char *p = skb_mac_header(skb);
unsigned int i;
- printk("%02x", *p++);
+ sb_add(m, "%02x", *p++);
for (i = 1; i < dev->hard_header_len; i++, p++)
- printk(":%02x", *p);
+ sb_add(m, ":%02x", *p);
}
- printk(" ");
+ sb_add(m, " ");
}
static struct nf_loginfo default_loginfo = {
@@ -419,11 +419,12 @@ ipt_log_packet(u_int8_t pf,
const struct nf_loginfo *loginfo,
const char *prefix)
{
+ struct sbuff *m = sb_open();
+
if (!loginfo)
loginfo = &default_loginfo;
- spin_lock_bh(&log_lock);
- printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
+ sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
prefix,
in ? in->name : "",
out ? out->name : "");
@@ -434,20 +435,20 @@ ipt_log_packet(u_int8_t pf,
physindev = skb->nf_bridge->physindev;
if (physindev && in != physindev)
- printk("PHYSIN=%s ", physindev->name);
+ sb_add(m, "PHYSIN=%s ", physindev->name);
physoutdev = skb->nf_bridge->physoutdev;
if (physoutdev && out != physoutdev)
- printk("PHYSOUT=%s ", physoutdev->name);
+ sb_add(m, "PHYSOUT=%s ", physoutdev->name);
}
#endif
/* MAC logging for input path only. */
if (in && !out)
- dump_mac_header(loginfo, skb);
+ dump_mac_header(m, loginfo, skb);
+
+ dump_packet(m, loginfo, skb, 0);
- dump_packet(loginfo, skb, 0);
- printk("\n");
- spin_unlock_bh(&log_lock);
+ sb_close(m);
}
static unsigned int
diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c
index c31b87668250..0f23b3f06df0 100644
--- a/net/ipv4/netfilter/nf_nat_amanda.c
+++ b/net/ipv4/netfilter/nf_nat_amanda.c
@@ -44,9 +44,16 @@ static unsigned int help(struct sk_buff *skb,
/* Try to get same port: if not, try to change it. */
for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ port = 0;
break;
+ }
}
if (port == 0)
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 957c9241fb0c..295c97431e43 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -47,7 +47,7 @@ __nf_nat_proto_find(u_int8_t protonum)
return rcu_dereference(nf_nat_protos[protonum]);
}
-const struct nf_nat_protocol *
+static const struct nf_nat_protocol *
nf_nat_proto_find_get(u_int8_t protonum)
{
const struct nf_nat_protocol *p;
@@ -60,14 +60,12 @@ nf_nat_proto_find_get(u_int8_t protonum)
return p;
}
-EXPORT_SYMBOL_GPL(nf_nat_proto_find_get);
-void
+static void
nf_nat_proto_put(const struct nf_nat_protocol *p)
{
module_put(p->me);
}
-EXPORT_SYMBOL_GPL(nf_nat_proto_put);
/* We keep an extra hash for each conntrack, for fast searching. */
static inline unsigned int
@@ -262,11 +260,17 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
proto = __nf_nat_proto_find(orig_tuple->dst.protonum);
/* Only bother mapping if it's not already in range and unique */
- if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM) &&
- (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) ||
- proto->in_range(tuple, maniptype, &range->min, &range->max)) &&
- !nf_nat_used_tuple(tuple, ct))
- goto out;
+ if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
+ if (range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
+ if (proto->in_range(tuple, maniptype, &range->min,
+ &range->max) &&
+ (range->min.all == range->max.all ||
+ !nf_nat_used_tuple(tuple, ct)))
+ goto out;
+ } else if (!nf_nat_used_tuple(tuple, ct)) {
+ goto out;
+ }
+ }
/* Last change: get protocol to try to obtain unique tuple. */
proto->unique_tuple(tuple, range, maniptype, ct);
@@ -458,6 +462,18 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
return 0;
}
+ if (manip == IP_NAT_MANIP_SRC)
+ statusbit = IPS_SRC_NAT;
+ else
+ statusbit = IPS_DST_NAT;
+
+ /* Invert if this is reply dir. */
+ if (dir == IP_CT_DIR_REPLY)
+ statusbit ^= IPS_NAT_MASK;
+
+ if (!(ct->status & statusbit))
+ return 1;
+
pr_debug("icmp_reply_translation: translating error %p manip %u "
"dir %s\n", skb, manip,
dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
@@ -492,20 +508,9 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
/* Change outer to look the reply to an incoming packet
* (proto 0 means don't invert per-proto part). */
- if (manip == IP_NAT_MANIP_SRC)
- statusbit = IPS_SRC_NAT;
- else
- statusbit = IPS_DST_NAT;
-
- /* Invert if this is reply dir. */
- if (dir == IP_CT_DIR_REPLY)
- statusbit ^= IPS_NAT_MASK;
-
- if (ct->status & statusbit) {
- nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
- if (!manip_pkt(0, skb, 0, &target, manip))
- return 0;
- }
+ nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
+ if (!manip_pkt(0, skb, 0, &target, manip))
+ return 0;
return 1;
}
diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c
index 86e0e84ff0a0..dc73abb3fe27 100644
--- a/net/ipv4/netfilter/nf_nat_ftp.c
+++ b/net/ipv4/netfilter/nf_nat_ftp.c
@@ -79,9 +79,16 @@ static unsigned int nf_nat_ftp(struct sk_buff *skb,
/* Try to get same port: if not, try to change it. */
for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ port = 0;
break;
+ }
}
if (port == 0)
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
index 5045196d853c..790f3160e012 100644
--- a/net/ipv4/netfilter/nf_nat_h323.c
+++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -222,13 +222,24 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
/* Try to get a pair of ports. */
for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port);
nated_port != 0; nated_port += 2) {
+ int ret;
+
rtp_exp->tuple.dst.u.udp.port = htons(nated_port);
- if (nf_ct_expect_related(rtp_exp) == 0) {
+ ret = nf_ct_expect_related(rtp_exp);
+ if (ret == 0) {
rtcp_exp->tuple.dst.u.udp.port =
htons(nated_port + 1);
- if (nf_ct_expect_related(rtcp_exp) == 0)
+ ret = nf_ct_expect_related(rtcp_exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ nf_ct_unexpect_related(rtp_exp);
+ nated_port = 0;
break;
- nf_ct_unexpect_related(rtp_exp);
+ }
+ } else if (ret != -EBUSY) {
+ nated_port = 0;
+ break;
}
}
@@ -284,9 +295,16 @@ static int nat_t120(struct sk_buff *skb, struct nf_conn *ct,
/* Try to get same port: if not, try to change it. */
for (; nated_port != 0; nated_port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(nated_port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ nated_port = 0;
break;
+ }
}
if (nated_port == 0) { /* No port available */
@@ -334,9 +352,16 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct,
/* Try to get same port: if not, try to change it. */
for (; nated_port != 0; nated_port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(nated_port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
break;
+ else if (ret != -EBUSY) {
+ nated_port = 0;
+ break;
+ }
}
if (nated_port == 0) { /* No port available */
@@ -418,9 +443,16 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct,
/* Try to get same port: if not, try to change it. */
for (; nated_port != 0; nated_port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(nated_port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ nated_port = 0;
break;
+ }
}
if (nated_port == 0) { /* No port available */
@@ -500,9 +532,16 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,
/* Try to get same port: if not, try to change it. */
for (nated_port = ntohs(port); nated_port != 0; nated_port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(nated_port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
break;
+ else if (ret != -EBUSY) {
+ nated_port = 0;
+ break;
+ }
}
if (nated_port == 0) { /* No port available */
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 4a0c6b548eee..31427fb57aa8 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -153,6 +153,35 @@ 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,
+ int datalen, __sum16 *check, int oldlen)
+{
+ struct rtable *rt = skb_rtable(skb);
+
+ if (skb->ip_summed != CHECKSUM_PARTIAL) {
+ if (!(rt->rt_flags & RTCF_LOCAL) &&
+ skb->dev->features & NETIF_F_V4_CSUM) {
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ skb->csum_start = skb_headroom(skb) +
+ skb_network_offset(skb) +
+ iph->ihl * 4;
+ skb->csum_offset = (void *)check - data;
+ *check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
+ datalen, iph->protocol, 0);
+ } else {
+ *check = 0;
+ *check = csum_tcpudp_magic(iph->saddr, iph->daddr,
+ datalen, iph->protocol,
+ csum_partial(data, datalen,
+ 0));
+ if (iph->protocol == IPPROTO_UDP && !*check)
+ *check = CSUM_MANGLED_0;
+ }
+ } else
+ inet_proto_csum_replace2(check, skb,
+ htons(oldlen), htons(datalen), 1);
+}
+
/* Generic function for mangling variable-length address changes inside
* NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX
* command in FTP).
@@ -169,7 +198,6 @@ int __nf_nat_mangle_tcp_packet(struct sk_buff *skb,
const char *rep_buffer,
unsigned int rep_len, bool adjust)
{
- struct rtable *rt = skb_rtable(skb);
struct iphdr *iph;
struct tcphdr *tcph;
int oldlen, datalen;
@@ -192,26 +220,7 @@ int __nf_nat_mangle_tcp_packet(struct sk_buff *skb,
match_offset, match_len, rep_buffer, rep_len);
datalen = skb->len - iph->ihl*4;
- if (skb->ip_summed != CHECKSUM_PARTIAL) {
- if (!(rt->rt_flags & RTCF_LOCAL) &&
- skb->dev->features & NETIF_F_V4_CSUM) {
- skb->ip_summed = CHECKSUM_PARTIAL;
- skb->csum_start = skb_headroom(skb) +
- skb_network_offset(skb) +
- iph->ihl * 4;
- skb->csum_offset = offsetof(struct tcphdr, check);
- tcph->check = ~tcp_v4_check(datalen,
- iph->saddr, iph->daddr, 0);
- } else {
- tcph->check = 0;
- tcph->check = tcp_v4_check(datalen,
- iph->saddr, iph->daddr,
- csum_partial(tcph,
- datalen, 0));
- }
- } else
- inet_proto_csum_replace2(&tcph->check, skb,
- htons(oldlen), htons(datalen), 1);
+ nf_nat_csum(skb, iph, tcph, datalen, &tcph->check, oldlen);
if (adjust && rep_len != match_len)
nf_nat_set_seq_adjust(ct, ctinfo, tcph->seq,
@@ -240,7 +249,6 @@ nf_nat_mangle_udp_packet(struct sk_buff *skb,
const char *rep_buffer,
unsigned int rep_len)
{
- struct rtable *rt = skb_rtable(skb);
struct iphdr *iph;
struct udphdr *udph;
int datalen, oldlen;
@@ -274,29 +282,7 @@ nf_nat_mangle_udp_packet(struct sk_buff *skb,
if (!udph->check && skb->ip_summed != CHECKSUM_PARTIAL)
return 1;
- if (skb->ip_summed != CHECKSUM_PARTIAL) {
- if (!(rt->rt_flags & RTCF_LOCAL) &&
- skb->dev->features & NETIF_F_V4_CSUM) {
- skb->ip_summed = CHECKSUM_PARTIAL;
- skb->csum_start = skb_headroom(skb) +
- skb_network_offset(skb) +
- iph->ihl * 4;
- skb->csum_offset = offsetof(struct udphdr, check);
- udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
- datalen, IPPROTO_UDP,
- 0);
- } else {
- udph->check = 0;
- udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
- datalen, IPPROTO_UDP,
- csum_partial(udph,
- datalen, 0));
- if (!udph->check)
- udph->check = CSUM_MANGLED_0;
- }
- } else
- inet_proto_csum_replace2(&udph->check, skb,
- htons(oldlen), htons(datalen), 1);
+ nf_nat_csum(skb, iph, udph, datalen, &udph->check, oldlen);
return 1;
}
diff --git a/net/ipv4/netfilter/nf_nat_irc.c b/net/ipv4/netfilter/nf_nat_irc.c
index ea83a886b03e..535e1a802356 100644
--- a/net/ipv4/netfilter/nf_nat_irc.c
+++ b/net/ipv4/netfilter/nf_nat_irc.c
@@ -45,9 +45,16 @@ static unsigned int help(struct sk_buff *skb,
/* Try to get same port: if not, try to change it. */
for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ port = 0;
break;
+ }
}
if (port == 0)
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index ebbd319f62f5..21c30426480b 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -106,16 +106,15 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
{
/* Force range to this IP; let proto decide mapping for
per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED).
- Use reply in case it's already been mangled (eg local packet).
*/
- __be32 ip
- = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
- ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip
- : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip);
- struct nf_nat_range range
- = { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } };
-
- pr_debug("Allocating NULL binding for %p (%pI4)\n", ct, &ip);
+ struct nf_nat_range range;
+
+ range.flags = 0;
+ pr_debug("Allocating NULL binding for %p (%pI4)\n", ct,
+ HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC ?
+ &ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip :
+ &ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip);
+
return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
}
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index 11b538deaaec..e40cf7816fdb 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -307,9 +307,16 @@ static unsigned int ip_nat_sip_expect(struct sk_buff *skb, unsigned int dataoff,
exp->expectfn = ip_nat_sip_expected;
for (; port != 0; port++) {
+ int ret;
+
exp->tuple.dst.u.udp.port = htons(port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ port = 0;
break;
+ }
}
if (port == 0)
@@ -480,13 +487,25 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff,
/* Try to get same pair of ports: if not, try to change them. */
for (port = ntohs(rtp_exp->tuple.dst.u.udp.port);
port != 0; port += 2) {
+ int ret;
+
rtp_exp->tuple.dst.u.udp.port = htons(port);
- if (nf_ct_expect_related(rtp_exp) != 0)
+ ret = nf_ct_expect_related(rtp_exp);
+ if (ret == -EBUSY)
continue;
+ else if (ret < 0) {
+ port = 0;
+ break;
+ }
rtcp_exp->tuple.dst.u.udp.port = htons(port + 1);
- if (nf_ct_expect_related(rtcp_exp) == 0)
+ ret = nf_ct_expect_related(rtcp_exp);
+ if (ret == 0)
break;
- nf_ct_unexpect_related(rtp_exp);
+ else if (ret != -EBUSY) {
+ nf_ct_unexpect_related(rtp_exp);
+ port = 0;
+ break;
+ }
}
if (port == 0)
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index f2d297351405..65699c24411c 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -28,8 +28,7 @@
#include <linux/spinlock.h>
#include <net/protocol.h>
-const struct net_protocol *inet_protos[MAX_INET_PROTOS] ____cacheline_aligned_in_smp;
-static DEFINE_SPINLOCK(inet_proto_lock);
+const struct net_protocol *inet_protos[MAX_INET_PROTOS] __read_mostly;
/*
* Add a protocol handler to the hash tables
@@ -37,20 +36,9 @@ static DEFINE_SPINLOCK(inet_proto_lock);
int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
{
- int hash, ret;
+ int hash = protocol & (MAX_INET_PROTOS - 1);
- hash = protocol & (MAX_INET_PROTOS - 1);
-
- spin_lock_bh(&inet_proto_lock);
- if (inet_protos[hash]) {
- ret = -1;
- } else {
- inet_protos[hash] = prot;
- ret = 0;
- }
- spin_unlock_bh(&inet_proto_lock);
-
- return ret;
+ return !cmpxchg(&inet_protos[hash], NULL, prot) ? 0 : -1;
}
EXPORT_SYMBOL(inet_add_protocol);
@@ -60,18 +48,9 @@ EXPORT_SYMBOL(inet_add_protocol);
int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
{
- int hash, ret;
-
- hash = protocol & (MAX_INET_PROTOS - 1);
+ int ret, hash = protocol & (MAX_INET_PROTOS - 1);
- spin_lock_bh(&inet_proto_lock);
- if (inet_protos[hash] == prot) {
- inet_protos[hash] = NULL;
- ret = 0;
- } else {
- ret = -1;
- }
- spin_unlock_bh(&inet_proto_lock);
+ ret = (cmpxchg(&inet_protos[hash], prot, NULL) == prot) ? 0 : -1;
synchronize_net();
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 009a7b2aa1ef..1f85ef289895 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -505,7 +505,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
ipc.addr = inet->inet_saddr;
ipc.opt = NULL;
- ipc.shtx.flags = 0;
+ ipc.tx_flags = 0;
ipc.oif = sk->sk_bound_dev_if;
if (msg->msg_controllen) {
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ac6559cb54f9..d6cb2bfcd8e1 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -159,7 +159,6 @@ static struct dst_ops ipv4_dst_ops = {
.link_failure = ipv4_link_failure,
.update_pmtu = ip_rt_update_pmtu,
.local_out = __ip_local_out,
- .entries = ATOMIC_INIT(0),
};
#define ECN_OR_COST(class) TC_PRIO_##class
@@ -466,7 +465,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v)
seq_printf(seq,"%08x %08x %08x %08x %08x %08x %08x %08x "
" %08x %08x %08x %08x %08x %08x %08x %08x %08x \n",
- atomic_read(&ipv4_dst_ops.entries),
+ dst_entries_get_slow(&ipv4_dst_ops),
st->in_hit,
st->in_slow_tot,
st->in_slow_mc,
@@ -945,6 +944,7 @@ static int rt_garbage_collect(struct dst_ops *ops)
struct rtable *rth, **rthp;
unsigned long now = jiffies;
int goal;
+ int entries = dst_entries_get_fast(&ipv4_dst_ops);
/*
* Garbage collection is pretty expensive,
@@ -954,28 +954,28 @@ static int rt_garbage_collect(struct dst_ops *ops)
RT_CACHE_STAT_INC(gc_total);
if (now - last_gc < ip_rt_gc_min_interval &&
- atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) {
+ entries < ip_rt_max_size) {
RT_CACHE_STAT_INC(gc_ignored);
goto out;
}
+ entries = dst_entries_get_slow(&ipv4_dst_ops);
/* Calculate number of entries, which we want to expire now. */
- goal = atomic_read(&ipv4_dst_ops.entries) -
- (ip_rt_gc_elasticity << rt_hash_log);
+ goal = entries - (ip_rt_gc_elasticity << rt_hash_log);
if (goal <= 0) {
if (equilibrium < ipv4_dst_ops.gc_thresh)
equilibrium = ipv4_dst_ops.gc_thresh;
- goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium;
+ goal = entries - equilibrium;
if (goal > 0) {
equilibrium += min_t(unsigned int, goal >> 1, rt_hash_mask + 1);
- goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium;
+ goal = entries - equilibrium;
}
} else {
/* We are in dangerous area. Try to reduce cache really
* aggressively.
*/
goal = max_t(unsigned int, goal >> 1, rt_hash_mask + 1);
- equilibrium = atomic_read(&ipv4_dst_ops.entries) - goal;
+ equilibrium = entries - goal;
}
if (now - last_gc >= ip_rt_gc_min_interval)
@@ -1032,14 +1032,16 @@ static int rt_garbage_collect(struct dst_ops *ops)
expire >>= 1;
#if RT_CACHE_DEBUG >= 2
printk(KERN_DEBUG "expire>> %u %d %d %d\n", expire,
- atomic_read(&ipv4_dst_ops.entries), goal, i);
+ dst_entries_get_fast(&ipv4_dst_ops), goal, i);
#endif
- if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size)
+ if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size)
goto out;
} while (!in_softirq() && time_before_eq(jiffies, now));
- if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size)
+ if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size)
+ goto out;
+ if (dst_entries_get_slow(&ipv4_dst_ops) < ip_rt_max_size)
goto out;
if (net_ratelimit())
printk(KERN_WARNING "dst cache overflow\n");
@@ -1049,11 +1051,12 @@ static int rt_garbage_collect(struct dst_ops *ops)
work_done:
expire += ip_rt_gc_min_interval;
if (expire > ip_rt_gc_timeout ||
- atomic_read(&ipv4_dst_ops.entries) < ipv4_dst_ops.gc_thresh)
+ 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,
- atomic_read(&ipv4_dst_ops.entries), goal, rover);
+ dst_entries_get_fast(&ipv4_dst_ops), goal, rover);
#endif
out: return 0;
}
@@ -1102,23 +1105,23 @@ restart:
* Note that we do rt_free on this new route entry, so that
* once its refcount hits zero, we are still able to reap it
* (Thanks Alexey)
- * Note also the rt_free uses call_rcu. We don't actually
- * need rcu protection here, this is just our path to get
- * on the route gc list.
+ * Note: To avoid expensive rcu stuff for this uncached dst,
+ * we set DST_NOCACHE so that dst_release() can free dst without
+ * waiting a grace period.
*/
+ rt->dst.flags |= DST_NOCACHE;
if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) {
int err = arp_bind_neighbour(&rt->dst);
if (err) {
if (net_ratelimit())
printk(KERN_WARNING
"Neighbour table failure & not caching routes.\n");
- rt_drop(rt);
+ ip_rt_put(rt);
return err;
}
}
- rt_free(rt);
goto skip_hashing;
}
@@ -1268,18 +1271,11 @@ skip_hashing:
void rt_bind_peer(struct rtable *rt, int create)
{
- static DEFINE_SPINLOCK(rt_peer_lock);
struct inet_peer *peer;
peer = inet_getpeer(rt->rt_dst, create);
- spin_lock_bh(&rt_peer_lock);
- if (rt->peer == NULL) {
- rt->peer = peer;
- peer = NULL;
- }
- spin_unlock_bh(&rt_peer_lock);
- if (peer)
+ if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL)
inet_putpeer(peer);
}
@@ -1779,12 +1775,15 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt)
if (rt->fl.iif == 0)
src = rt->rt_src;
- else if (fib_lookup(dev_net(rt->dst.dev), &rt->fl, &res) == 0) {
- src = FIB_RES_PREFSRC(res);
- fib_res_put(&res);
- } else
- src = inet_select_addr(rt->dst.dev, rt->rt_gateway,
+ else {
+ rcu_read_lock();
+ if (fib_lookup(dev_net(rt->dst.dev), &rt->fl, &res) == 0)
+ src = FIB_RES_PREFSRC(res);
+ else
+ src = inet_select_addr(rt->dst.dev, rt->rt_gateway,
RT_SCOPE_UNIVERSE);
+ rcu_read_unlock();
+ }
memcpy(addr, &src, 4);
}
@@ -2087,6 +2086,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
* Such approach solves two big problems:
* 1. Not simplex devices are handled properly.
* 2. IP spoofing attempts are filtered with 100% of guarantee.
+ * called with rcu_read_lock()
*/
static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
@@ -2108,7 +2108,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
unsigned hash;
__be32 spec_dst;
int err = -EINVAL;
- int free_res = 0;
struct net * net = dev_net(dev);
/* IP on this device is disabled. */
@@ -2124,7 +2123,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
ipv4_is_loopback(saddr))
goto martian_source;
- if (daddr == htonl(0xFFFFFFFF) || (saddr == 0 && daddr == 0))
+ if (ipv4_is_lbcast(daddr) || (saddr == 0 && daddr == 0))
goto brd_input;
/* Accept zero addresses only to limited broadcast;
@@ -2133,19 +2132,18 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
if (ipv4_is_zeronet(saddr))
goto martian_source;
- if (ipv4_is_lbcast(daddr) || ipv4_is_zeronet(daddr) ||
- ipv4_is_loopback(daddr))
+ if (ipv4_is_zeronet(daddr) || ipv4_is_loopback(daddr))
goto martian_destination;
/*
* Now we are ready to route packet.
*/
- if ((err = fib_lookup(net, &fl, &res)) != 0) {
+ err = fib_lookup(net, &fl, &res);
+ if (err != 0) {
if (!IN_DEV_FORWARD(in_dev))
goto e_hostunreach;
goto no_route;
}
- free_res = 1;
RT_CACHE_STAT_INC(in_slow_tot);
@@ -2154,8 +2152,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
if (res.type == RTN_LOCAL) {
err = fib_validate_source(saddr, daddr, tos,
- net->loopback_dev->ifindex,
- dev, &spec_dst, &itag, skb->mark);
+ net->loopback_dev->ifindex,
+ dev, &spec_dst, &itag, skb->mark);
if (err < 0)
goto martian_source_keep_err;
if (err)
@@ -2170,9 +2168,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
goto martian_destination;
err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos);
-done:
- if (free_res)
- fib_res_put(&res);
out: return err;
brd_input:
@@ -2232,7 +2227,7 @@ local_input:
rth->rt_type = res.type;
hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
err = rt_intern_hash(hash, rth, NULL, skb, fl.iif);
- goto done;
+ goto out;
no_route:
RT_CACHE_STAT_INC(in_no_route);
@@ -2255,21 +2250,21 @@ martian_destination:
e_hostunreach:
err = -EHOSTUNREACH;
- goto done;
+ goto out;
e_inval:
err = -EINVAL;
- goto done;
+ goto out;
e_nobufs:
err = -ENOBUFS;
- goto done;
+ goto out;
martian_source:
err = -EINVAL;
martian_source_keep_err:
ip_handle_martian_source(dev, in_dev, skb, daddr, saddr);
- goto done;
+ goto out;
}
int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
@@ -2355,6 +2350,7 @@ skip_cache:
}
EXPORT_SYMBOL(ip_route_input_common);
+/* called with rcu_read_lock() */
static int __mkroute_output(struct rtable **result,
struct fib_result *res,
const struct flowi *fl,
@@ -2365,53 +2361,47 @@ static int __mkroute_output(struct rtable **result,
struct rtable *rth;
struct in_device *in_dev;
u32 tos = RT_FL_TOS(oldflp);
- int err = 0;
- if (ipv4_is_loopback(fl->fl4_src) && !(dev_out->flags&IFF_LOOPBACK))
+ if (ipv4_is_loopback(fl->fl4_src) && !(dev_out->flags & IFF_LOOPBACK))
return -EINVAL;
- if (fl->fl4_dst == htonl(0xFFFFFFFF))
+ if (ipv4_is_lbcast(fl->fl4_dst))
res->type = RTN_BROADCAST;
else if (ipv4_is_multicast(fl->fl4_dst))
res->type = RTN_MULTICAST;
- else if (ipv4_is_lbcast(fl->fl4_dst) || ipv4_is_zeronet(fl->fl4_dst))
+ else if (ipv4_is_zeronet(fl->fl4_dst))
return -EINVAL;
if (dev_out->flags & IFF_LOOPBACK)
flags |= RTCF_LOCAL;
- /* get work reference to inet device */
- in_dev = in_dev_get(dev_out);
+ in_dev = __in_dev_get_rcu(dev_out);
if (!in_dev)
return -EINVAL;
if (res->type == RTN_BROADCAST) {
flags |= RTCF_BROADCAST | RTCF_LOCAL;
- if (res->fi) {
- fib_info_put(res->fi);
- res->fi = NULL;
- }
+ res->fi = NULL;
} else if (res->type == RTN_MULTICAST) {
- flags |= RTCF_MULTICAST|RTCF_LOCAL;
+ flags |= RTCF_MULTICAST | RTCF_LOCAL;
if (!ip_check_mc(in_dev, oldflp->fl4_dst, oldflp->fl4_src,
oldflp->proto))
flags &= ~RTCF_LOCAL;
/* If multicast route do not exist use
- default one, but do not gateway in this case.
- Yes, it is hack.
+ * default one, but do not gateway in this case.
+ * Yes, it is hack.
*/
- if (res->fi && res->prefixlen < 4) {
- fib_info_put(res->fi);
+ if (res->fi && res->prefixlen < 4)
res->fi = NULL;
- }
}
rth = dst_alloc(&ipv4_dst_ops);
- if (!rth) {
- err = -ENOBUFS;
- goto cleanup;
- }
+ if (!rth)
+ return -ENOBUFS;
+
+ in_dev_hold(in_dev);
+ rth->idev = in_dev;
atomic_set(&rth->dst.__refcnt, 1);
rth->dst.flags= DST_HOST;
@@ -2432,7 +2422,6 @@ static int __mkroute_output(struct rtable **result,
cache entry */
rth->dst.dev = dev_out;
dev_hold(dev_out);
- rth->idev = in_dev_get(dev_out);
rth->rt_gateway = fl->fl4_dst;
rth->rt_spec_dst= fl->fl4_src;
@@ -2467,15 +2456,11 @@ static int __mkroute_output(struct rtable **result,
rt_set_nexthop(rth, res, 0);
rth->rt_flags = flags;
-
*result = rth;
- cleanup:
- /* release work reference to inet device */
- in_dev_put(in_dev);
-
- return err;
+ return 0;
}
+/* called with rcu_read_lock() */
static int ip_mkroute_output(struct rtable **rp,
struct fib_result *res,
const struct flowi *fl,
@@ -2497,6 +2482,7 @@ static int ip_mkroute_output(struct rtable **rp,
/*
* Major route resolver routine.
+ * called with rcu_read_lock();
*/
static int ip_route_output_slow(struct net *net, struct rtable **rp,
@@ -2515,9 +2501,8 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
.iif = net->loopback_dev->ifindex,
.oif = oldflp->oif };
struct fib_result res;
- unsigned flags = 0;
+ unsigned int flags = 0;
struct net_device *dev_out = NULL;
- int free_res = 0;
int err;
@@ -2543,9 +2528,9 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
if (oldflp->oif == 0 &&
(ipv4_is_multicast(oldflp->fl4_dst) ||
- oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
+ ipv4_is_lbcast(oldflp->fl4_dst))) {
/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
- dev_out = ip_dev_find(net, oldflp->fl4_src);
+ dev_out = __ip_dev_find(net, oldflp->fl4_src, false);
if (dev_out == NULL)
goto out;
@@ -2570,29 +2555,24 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) {
/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
- dev_out = ip_dev_find(net, oldflp->fl4_src);
- if (dev_out == NULL)
+ if (!__ip_dev_find(net, oldflp->fl4_src, false))
goto out;
- dev_put(dev_out);
- dev_out = NULL;
}
}
if (oldflp->oif) {
- dev_out = dev_get_by_index(net, oldflp->oif);
+ dev_out = dev_get_by_index_rcu(net, oldflp->oif);
err = -ENODEV;
if (dev_out == NULL)
goto out;
/* RACE: Check return value of inet_select_addr instead. */
- if (__in_dev_get_rtnl(dev_out) == NULL) {
- dev_put(dev_out);
+ if (rcu_dereference(dev_out->ip_ptr) == NULL)
goto out; /* Wrong error code */
- }
if (ipv4_is_local_multicast(oldflp->fl4_dst) ||
- oldflp->fl4_dst == htonl(0xFFFFFFFF)) {
+ ipv4_is_lbcast(oldflp->fl4_dst)) {
if (!fl.fl4_src)
fl.fl4_src = inet_select_addr(dev_out, 0,
RT_SCOPE_LINK);
@@ -2612,10 +2592,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
fl.fl4_dst = fl.fl4_src;
if (!fl.fl4_dst)
fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK);
- if (dev_out)
- dev_put(dev_out);
dev_out = net->loopback_dev;
- dev_hold(dev_out);
fl.oif = net->loopback_dev->ifindex;
res.type = RTN_LOCAL;
flags |= RTCF_LOCAL;
@@ -2649,23 +2626,15 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
res.type = RTN_UNICAST;
goto make_route;
}
- if (dev_out)
- dev_put(dev_out);
err = -ENETUNREACH;
goto out;
}
- free_res = 1;
if (res.type == RTN_LOCAL) {
if (!fl.fl4_src)
fl.fl4_src = fl.fl4_dst;
- if (dev_out)
- dev_put(dev_out);
dev_out = net->loopback_dev;
- dev_hold(dev_out);
fl.oif = dev_out->ifindex;
- if (res.fi)
- fib_info_put(res.fi);
res.fi = NULL;
flags |= RTCF_LOCAL;
goto make_route;
@@ -2682,28 +2651,21 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
if (!fl.fl4_src)
fl.fl4_src = FIB_RES_PREFSRC(res);
- if (dev_out)
- dev_put(dev_out);
dev_out = FIB_RES_DEV(res);
- dev_hold(dev_out);
fl.oif = dev_out->ifindex;
make_route:
err = ip_mkroute_output(rp, &res, &fl, oldflp, dev_out, flags);
-
- if (free_res)
- fib_res_put(&res);
- if (dev_out)
- dev_put(dev_out);
out: return err;
}
int __ip_route_output_key(struct net *net, struct rtable **rp,
const struct flowi *flp)
{
- unsigned hash;
+ unsigned int hash;
+ int res;
struct rtable *rth;
if (!rt_caching(net))
@@ -2734,7 +2696,10 @@ int __ip_route_output_key(struct net *net, struct rtable **rp,
rcu_read_unlock_bh();
slow_output:
- return ip_route_output_slow(net, rp, flp);
+ rcu_read_lock();
+ res = ip_route_output_slow(net, rp, flp);
+ rcu_read_unlock();
+ return res;
}
EXPORT_SYMBOL_GPL(__ip_route_output_key);
@@ -2753,7 +2718,6 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
.destroy = ipv4_dst_destroy,
.check = ipv4_blackhole_dst_check,
.update_pmtu = ipv4_rt_blackhole_update_pmtu,
- .entries = ATOMIC_INIT(0),
};
@@ -2798,7 +2762,7 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi
dst_release(&(*rp)->dst);
*rp = rt;
- return (rt ? 0 : -ENOMEM);
+ return rt ? 0 : -ENOMEM;
}
int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp,
@@ -3323,6 +3287,12 @@ int __init ip_rt_init(void)
ipv4_dst_blackhole_ops.kmem_cachep = ipv4_dst_ops.kmem_cachep;
+ if (dst_entries_init(&ipv4_dst_ops) < 0)
+ panic("IP: failed to allocate ipv4_dst_ops counter\n");
+
+ if (dst_entries_init(&ipv4_dst_blackhole_ops) < 0)
+ panic("IP: failed to allocate ipv4_dst_blackhole_ops counter\n");
+
rt_hash_table = (struct rt_hash_bucket *)
alloc_large_system_hash("IP route cache",
sizeof(struct rt_hash_bucket),
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index f115ea68a4ef..1664a0590bb8 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2392,7 +2392,12 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
err = tp->af_specific->md5_parse(sk, optval, optlen);
break;
#endif
-
+ case TCP_USER_TIMEOUT:
+ /* Cap the max timeout in ms TCP will retry/retrans
+ * before giving up and aborting (ETIMEDOUT) a connection.
+ */
+ icsk->icsk_user_timeout = msecs_to_jiffies(val);
+ break;
default:
err = -ENOPROTOOPT;
break;
@@ -2611,6 +2616,10 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
case TCP_THIN_DUPACK:
val = tp->thin_dupack;
break;
+
+ case TCP_USER_TIMEOUT:
+ val = jiffies_to_msecs(icsk->icsk_user_timeout);
+ break;
default:
return -ENOPROTOOPT;
}
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index b55f60f6fcbe..ee0df4817498 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -182,7 +182,7 @@ static void tcp_incr_quickack(struct sock *sk)
icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
}
-void tcp_enter_quickack_mode(struct sock *sk)
+static void tcp_enter_quickack_mode(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
tcp_incr_quickack(sk);
@@ -805,25 +805,12 @@ void tcp_update_metrics(struct sock *sk)
}
}
-/* Numbers are taken from RFC3390.
- *
- * John Heffner states:
- *
- * The RFC specifies a window of no more than 4380 bytes
- * unless 2*MSS > 4380. Reading the pseudocode in the RFC
- * is a bit misleading because they use a clamp at 4380 bytes
- * rather than use a multiplier in the relevant range.
- */
__u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst)
{
__u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0);
- if (!cwnd) {
- if (tp->mss_cache > 1460)
- cwnd = 2;
- else
- cwnd = (tp->mss_cache > 1095) ? 3 : 4;
- }
+ if (!cwnd)
+ cwnd = rfc3390_bytes_to_packets(tp->mss_cache);
return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
}
@@ -2314,7 +2301,7 @@ static inline int tcp_dupack_heuristics(struct tcp_sock *tp)
static inline int tcp_skb_timedout(struct sock *sk, struct sk_buff *skb)
{
- return (tcp_time_stamp - TCP_SKB_CB(skb)->when > inet_csk(sk)->icsk_rto);
+ return tcp_time_stamp - TCP_SKB_CB(skb)->when > inet_csk(sk)->icsk_rto;
}
static inline int tcp_head_timedout(struct sock *sk)
@@ -2508,7 +2495,7 @@ static void tcp_timeout_skbs(struct sock *sk)
/* Mark head of queue up as lost. With RFC3517 SACK, the packets is
* is against sacked "cnt", otherwise it's against facked "cnt"
*/
-static void tcp_mark_head_lost(struct sock *sk, int packets)
+static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
{
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb;
@@ -2516,13 +2503,13 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
int err;
unsigned int mss;
- if (packets == 0)
- return;
-
WARN_ON(packets > tp->packets_out);
if (tp->lost_skb_hint) {
skb = tp->lost_skb_hint;
cnt = tp->lost_cnt_hint;
+ /* Head already handled? */
+ if (mark_head && skb != tcp_write_queue_head(sk))
+ return;
} else {
skb = tcp_write_queue_head(sk);
cnt = 0;
@@ -2557,6 +2544,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
}
tcp_skb_mark_lost(tp, skb);
+
+ if (mark_head)
+ break;
}
tcp_verify_left_out(tp);
}
@@ -2568,17 +2558,18 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
struct tcp_sock *tp = tcp_sk(sk);
if (tcp_is_reno(tp)) {
- tcp_mark_head_lost(sk, 1);
+ tcp_mark_head_lost(sk, 1, 1);
} else if (tcp_is_fack(tp)) {
int lost = tp->fackets_out - tp->reordering;
if (lost <= 0)
lost = 1;
- tcp_mark_head_lost(sk, lost);
+ tcp_mark_head_lost(sk, lost, 0);
} else {
int sacked_upto = tp->sacked_out - tp->reordering;
- if (sacked_upto < fast_rexmit)
- sacked_upto = fast_rexmit;
- tcp_mark_head_lost(sk, sacked_upto);
+ if (sacked_upto >= 0)
+ tcp_mark_head_lost(sk, sacked_upto, 0);
+ else if (fast_rexmit)
+ tcp_mark_head_lost(sk, 1, 1);
}
tcp_timeout_skbs(sk);
@@ -2887,7 +2878,7 @@ static void tcp_mtup_probe_success(struct sock *sk)
icsk->icsk_mtup.probe_size;
tp->snd_cwnd_cnt = 0;
tp->snd_cwnd_stamp = tcp_time_stamp;
- tp->rcv_ssthresh = tcp_current_ssthresh(sk);
+ tp->snd_ssthresh = tcp_current_ssthresh(sk);
icsk->icsk_mtup.search_low = icsk->icsk_mtup.probe_size;
icsk->icsk_mtup.probe_size = 0;
@@ -2984,7 +2975,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
before(tp->snd_una, tp->high_seq) &&
icsk->icsk_ca_state != TCP_CA_Open &&
tp->fackets_out > tp->reordering) {
- tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering);
+ tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0);
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS);
}
@@ -3412,8 +3403,8 @@ static void tcp_ack_probe(struct sock *sk)
static inline int tcp_ack_is_dubious(const struct sock *sk, const int flag)
{
- return (!(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) ||
- inet_csk(sk)->icsk_ca_state != TCP_CA_Open);
+ return !(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) ||
+ inet_csk(sk)->icsk_ca_state != TCP_CA_Open;
}
static inline int tcp_may_raise_cwnd(const struct sock *sk, const int flag)
@@ -3430,9 +3421,9 @@ static inline int tcp_may_update_window(const struct tcp_sock *tp,
const u32 ack, const u32 ack_seq,
const u32 nwin)
{
- return (after(ack, tp->snd_una) ||
+ return after(ack, tp->snd_una) ||
after(ack_seq, tp->snd_wl1) ||
- (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd));
+ (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd);
}
/* Update our send window.
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 020766292bb0..8f8527d41682 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1422,7 +1422,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
newsk = tcp_create_openreq_child(sk, req, skb);
if (!newsk)
- goto exit;
+ goto exit_nonewsk;
newsk->sk_gso_type = SKB_GSO_TCPV4;
sk_setup_caps(newsk, dst);
@@ -1469,16 +1469,20 @@ 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;
+ }
__inet_hash_nolisten(newsk, NULL);
- __inet_inherit_port(sk, newsk);
return newsk;
exit_overflow:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
+exit_nonewsk:
+ dst_release(dst);
exit:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
- dst_release(dst);
return NULL;
}
EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
@@ -2571,7 +2575,6 @@ struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb)
return tcp_gro_receive(head, skb);
}
-EXPORT_SYMBOL(tcp4_gro_receive);
int tcp4_gro_complete(struct sk_buff *skb)
{
@@ -2584,7 +2587,6 @@ int tcp4_gro_complete(struct sk_buff *skb)
return tcp_gro_complete(skb);
}
-EXPORT_SYMBOL(tcp4_gro_complete);
struct proto tcp_prot = {
.name = "TCP",
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index f25b56cb85cb..43cf901d7659 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -55,7 +55,7 @@ static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win)
return 1;
if (after(end_seq, s_win) && before(seq, e_win))
return 1;
- return (seq == e_win && seq == end_seq);
+ return seq == e_win && seq == end_seq;
}
/*
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index de3bd8458588..05b1ecf36763 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -224,16 +224,10 @@ void tcp_select_initial_window(int __space, __u32 mss,
}
}
- /* Set initial window to value enough for senders,
- * following RFC2414. Senders, not following this RFC,
- * will be satisfied with 2.
- */
+ /* Set initial window to value enough for senders, following RFC5681. */
if (mss > (1 << *rcv_wscale)) {
- int init_cwnd = 4;
- if (mss > 1460 * 3)
- init_cwnd = 2;
- else if (mss > 1460)
- init_cwnd = 3;
+ int init_cwnd = rfc3390_bytes_to_packets(mss);
+
/* when initializing use the value from init_rcv_wnd
* rather than the default from above
*/
@@ -1376,9 +1370,9 @@ static inline int tcp_nagle_check(const struct tcp_sock *tp,
const struct sk_buff *skb,
unsigned mss_now, int nonagle)
{
- return (skb->len < mss_now &&
+ return skb->len < mss_now &&
((nonagle & TCP_NAGLE_CORK) ||
- (!nonagle && tp->packets_out && tcp_minshall_check(tp))));
+ (!nonagle && tp->packets_out && tcp_minshall_check(tp)));
}
/* Return non-zero if the Nagle test allows this packet to be
@@ -1449,10 +1443,10 @@ int tcp_may_send_now(struct sock *sk)
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb = tcp_send_head(sk);
- return (skb &&
+ return skb &&
tcp_snd_test(sk, skb, tcp_current_mss(sk),
(tcp_skb_is_last(sk, skb) ?
- tp->nonagle : TCP_NAGLE_PUSH)));
+ tp->nonagle : TCP_NAGLE_PUSH));
}
/* Trim TSO SKB to LEN bytes, put the remaining data into a new packet
@@ -2429,6 +2423,12 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
__u8 rcv_wscale;
/* Set this up on the first call only */
req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW);
+
+ /* limit the window selection if the user enforce a smaller rx buffer */
+ if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&
+ (req->window_clamp > tcp_full_space(sk) || req->window_clamp == 0))
+ req->window_clamp = tcp_full_space(sk);
+
/* tcp_full_space because it is guaranteed to be the first packet */
tcp_select_initial_window(tcp_full_space(sk),
mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0),
@@ -2555,6 +2555,11 @@ static void tcp_connect_init(struct sock *sk)
tcp_initialize_rcv_mss(sk);
+ /* limit the window selection if the user enforce a smaller rx buffer */
+ if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&
+ (tp->window_clamp > tcp_full_space(sk) || tp->window_clamp == 0))
+ tp->window_clamp = tcp_full_space(sk);
+
tcp_select_initial_window(tcp_full_space(sk),
tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
&tp->rcv_wnd,
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 74c54b30600f..74a6aa003657 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -140,10 +140,10 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
*/
static bool retransmits_timed_out(struct sock *sk,
unsigned int boundary,
+ unsigned int timeout,
bool syn_set)
{
- unsigned int timeout, linear_backoff_thresh;
- unsigned int start_ts;
+ unsigned int linear_backoff_thresh, start_ts;
unsigned int rto_base = syn_set ? TCP_TIMEOUT_INIT : TCP_RTO_MIN;
if (!inet_csk(sk)->icsk_retransmits)
@@ -154,14 +154,15 @@ static bool retransmits_timed_out(struct sock *sk,
else
start_ts = tcp_sk(sk)->retrans_stamp;
- linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base);
-
- if (boundary <= linear_backoff_thresh)
- timeout = ((2 << boundary) - 1) * rto_base;
- else
- timeout = ((2 << linear_backoff_thresh) - 1) * rto_base +
- (boundary - linear_backoff_thresh) * TCP_RTO_MAX;
+ if (likely(timeout == 0)) {
+ linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base);
+ if (boundary <= linear_backoff_thresh)
+ timeout = ((2 << boundary) - 1) * rto_base;
+ else
+ timeout = ((2 << linear_backoff_thresh) - 1) * rto_base +
+ (boundary - linear_backoff_thresh) * TCP_RTO_MAX;
+ }
return (tcp_time_stamp - start_ts) >= timeout;
}
@@ -178,7 +179,7 @@ static int tcp_write_timeout(struct sock *sk)
retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
syn_set = 1;
} else {
- if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0)) {
+ if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) {
/* Black hole detection */
tcp_mtu_probing(icsk, sk);
@@ -191,14 +192,15 @@ static int tcp_write_timeout(struct sock *sk)
retry_until = tcp_orphan_retries(sk, alive);
do_reset = alive ||
- !retransmits_timed_out(sk, retry_until, 0);
+ !retransmits_timed_out(sk, retry_until, 0, 0);
if (tcp_out_of_resources(sk, do_reset))
return 1;
}
}
- if (retransmits_timed_out(sk, retry_until, syn_set)) {
+ if (retransmits_timed_out(sk, retry_until,
+ syn_set ? 0 : icsk->icsk_user_timeout, syn_set)) {
/* Has it gone just too far? */
tcp_write_err(sk);
return 1;
@@ -365,18 +367,19 @@ void tcp_retransmit_timer(struct sock *sk)
if (icsk->icsk_retransmits == 0) {
int mib_idx;
- if (icsk->icsk_ca_state == TCP_CA_Disorder) {
- if (tcp_is_sack(tp))
- mib_idx = LINUX_MIB_TCPSACKFAILURES;
- else
- mib_idx = LINUX_MIB_TCPRENOFAILURES;
- } else if (icsk->icsk_ca_state == TCP_CA_Recovery) {
+ if (icsk->icsk_ca_state == TCP_CA_Recovery) {
if (tcp_is_sack(tp))
mib_idx = LINUX_MIB_TCPSACKRECOVERYFAIL;
else
mib_idx = LINUX_MIB_TCPRENORECOVERYFAIL;
} else if (icsk->icsk_ca_state == TCP_CA_Loss) {
mib_idx = LINUX_MIB_TCPLOSSFAILURES;
+ } else if ((icsk->icsk_ca_state == TCP_CA_Disorder) ||
+ tp->sacked_out) {
+ if (tcp_is_sack(tp))
+ mib_idx = LINUX_MIB_TCPSACKFAILURES;
+ else
+ mib_idx = LINUX_MIB_TCPRENOFAILURES;
} else {
mib_idx = LINUX_MIB_TCPTIMEOUTS;
}
@@ -440,7 +443,7 @@ out_reset_timer:
icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
}
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
- if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0))
+ if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0, 0))
__sk_dst_reset(sk);
out:;
@@ -560,7 +563,14 @@ static void tcp_keepalive_timer (unsigned long data)
elapsed = keepalive_time_elapsed(tp);
if (elapsed >= keepalive_time_when(tp)) {
- if (icsk->icsk_probes_out >= keepalive_probes(tp)) {
+ /* If the TCP_USER_TIMEOUT option is enabled, use that
+ * to determine when to timeout instead.
+ */
+ if ((icsk->icsk_user_timeout != 0 &&
+ elapsed >= icsk->icsk_user_timeout &&
+ icsk->icsk_probes_out > 0) ||
+ (icsk->icsk_user_timeout == 0 &&
+ icsk->icsk_probes_out >= keepalive_probes(tp))) {
tcp_send_active_reset(sk, GFP_ATOMIC);
tcp_write_err(sk);
goto out;
diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c
index 20151d6a6241..a534dda5456e 100644
--- a/net/ipv4/tcp_westwood.c
+++ b/net/ipv4/tcp_westwood.c
@@ -80,7 +80,7 @@ static void tcp_westwood_init(struct sock *sk)
*/
static inline u32 westwood_do_filter(u32 a, u32 b)
{
- return (((7 * a) + b) >> 3);
+ return ((7 * a) + b) >> 3;
}
static void westwood_filter(struct westwood *w, u32 delta)
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c
index 59186ca7808a..9a17bd2a0a37 100644
--- a/net/ipv4/tunnel4.c
+++ b/net/ipv4/tunnel4.c
@@ -14,8 +14,8 @@
#include <net/protocol.h>
#include <net/xfrm.h>
-static struct xfrm_tunnel *tunnel4_handlers;
-static struct xfrm_tunnel *tunnel64_handlers;
+static struct xfrm_tunnel *tunnel4_handlers __read_mostly;
+static struct xfrm_tunnel *tunnel64_handlers __read_mostly;
static DEFINE_MUTEX(tunnel4_mutex);
static inline struct xfrm_tunnel **fam_handlers(unsigned short family)
@@ -39,7 +39,7 @@ int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family)
}
handler->next = *pprev;
- *pprev = handler;
+ rcu_assign_pointer(*pprev, handler);
ret = 0;
@@ -73,6 +73,11 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family)
}
EXPORT_SYMBOL(xfrm4_tunnel_deregister);
+#define for_each_tunnel_rcu(head, handler) \
+ for (handler = rcu_dereference(head); \
+ handler != NULL; \
+ handler = rcu_dereference(handler->next)) \
+
static int tunnel4_rcv(struct sk_buff *skb)
{
struct xfrm_tunnel *handler;
@@ -80,7 +85,7 @@ static int tunnel4_rcv(struct sk_buff *skb)
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
goto drop;
- for (handler = tunnel4_handlers; handler; handler = handler->next)
+ for_each_tunnel_rcu(tunnel4_handlers, handler)
if (!handler->handler(skb))
return 0;
@@ -99,7 +104,7 @@ static int tunnel64_rcv(struct sk_buff *skb)
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
goto drop;
- for (handler = tunnel64_handlers; handler; handler = handler->next)
+ for_each_tunnel_rcu(tunnel64_handlers, handler)
if (!handler->handler(skb))
return 0;
@@ -115,7 +120,7 @@ static void tunnel4_err(struct sk_buff *skb, u32 info)
{
struct xfrm_tunnel *handler;
- for (handler = tunnel4_handlers; handler; handler = handler->next)
+ for_each_tunnel_rcu(tunnel4_handlers, handler)
if (!handler->err_handler(skb, info))
break;
}
@@ -125,7 +130,7 @@ static void tunnel64_err(struct sk_buff *skb, u32 info)
{
struct xfrm_tunnel *handler;
- for (handler = tunnel64_handlers; handler; handler = handler->next)
+ for_each_tunnel_rcu(tunnel64_handlers, handler)
if (!handler->err_handler(skb, info))
break;
}
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index fb23c2e63b52..b3f7e8cf18ac 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -797,7 +797,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
return -EOPNOTSUPP;
ipc.opt = NULL;
- ipc.shtx.flags = 0;
+ ipc.tx_flags = 0;
if (up->pending) {
/*
@@ -845,7 +845,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
ipc.addr = inet->inet_saddr;
ipc.oif = sk->sk_bound_dev_if;
- err = sock_tx_timestamp(msg, sk, &ipc.shtx);
+ err = sock_tx_timestamp(sk, &ipc.tx_flags);
if (err)
return err;
if (msg->msg_controllen) {
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index a580349f0b8a..4464f3bff6a7 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -174,7 +174,7 @@ static inline int xfrm4_garbage_collect(struct dst_ops *ops)
struct net *net = container_of(ops, struct net, xfrm.xfrm4_dst_ops);
xfrm4_policy_afinfo.garbage_collect(net);
- return (atomic_read(&ops->entries) > ops->gc_thresh * 2);
+ return (dst_entries_get_slow(ops) > ops->gc_thresh * 2);
}
static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -232,7 +232,6 @@ static struct dst_ops xfrm4_dst_ops = {
.ifdown = xfrm4_dst_ifdown,
.local_out = __ip_local_out,
.gc_thresh = 1024,
- .entries = ATOMIC_INIT(0),
};
static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
@@ -288,6 +287,7 @@ void __init xfrm4_init(int rt_max_size)
* and start cleaning when were 1/2 full
*/
xfrm4_dst_ops.gc_thresh = rt_max_size/2;
+ dst_entries_init(&xfrm4_dst_ops);
xfrm4_state_init();
xfrm4_policy_init();
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 41f5982d2087..82806455e859 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -58,14 +58,14 @@ static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
return -ENOENT;
}
-static struct xfrm_tunnel xfrm_tunnel_handler = {
+static struct xfrm_tunnel xfrm_tunnel_handler __read_mostly = {
.handler = xfrm_tunnel_rcv,
.err_handler = xfrm_tunnel_err,
.priority = 2,
};
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static struct xfrm_tunnel xfrm64_tunnel_handler = {
+static struct xfrm_tunnel xfrm64_tunnel_handler __read_mostly = {
.handler = xfrm_tunnel_rcv,
.err_handler = xfrm_tunnel_err,
.priority = 2,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 324fac3b6c16..ec7a91d9e865 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -243,7 +243,7 @@ static inline bool addrconf_qdisc_ok(const struct net_device *dev)
/* Check if a route is valid prefix route */
static inline int addrconf_is_prefix_route(const struct rt6_info *rt)
{
- return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0);
+ return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0;
}
static void addrconf_del_timer(struct inet6_ifaddr *ifp)
@@ -1544,7 +1544,7 @@ static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev)
return 0;
}
-int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
+static int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
{
if (addr == 0)
return -1;
@@ -1560,7 +1560,6 @@ int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
memcpy(eui + 4, &addr, 4);
return 0;
}
-EXPORT_SYMBOL(__ipv6_isatap_ifid);
static int addrconf_ifid_sit(u8 *eui, struct net_device *dev)
{
@@ -2964,7 +2963,8 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
start sending router solicitations.
*/
- if (ifp->idev->cnf.forwarding == 0 &&
+ if ((ifp->idev->cnf.forwarding == 0 ||
+ ifp->idev->cnf.forwarding == 2) &&
ifp->idev->cnf.rtr_solicits > 0 &&
(dev->flags&IFF_LOOPBACK) == 0 &&
(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 8175f802651b..c8993e5a337c 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -518,10 +518,9 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
static inline int ip6addrlbl_msgsize(void)
{
- return (NLMSG_ALIGN(sizeof(struct ifaddrlblmsg))
+ return NLMSG_ALIGN(sizeof(struct ifaddrlblmsg))
+ nla_total_size(16) /* IFAL_ADDRESS */
- + nla_total_size(4) /* IFAL_LABEL */
- );
+ + nla_total_size(4); /* IFAL_LABEL */
}
static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 56b9bf2516f4..54e8e42f7a88 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -343,7 +343,8 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
*/
v4addr = LOOPBACK4_IPV6;
if (!(addr_type & IPV6_ADDR_MULTICAST)) {
- if (!ipv6_chk_addr(net, &addr->sin6_addr,
+ if (!inet->transparent &&
+ !ipv6_chk_addr(net, &addr->sin6_addr,
dev, 0)) {
err = -EADDRNOTAVAIL;
goto out_unlock;
@@ -467,7 +468,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin->sin6_scope_id = sk->sk_bound_dev_if;
*uaddr_len = sizeof(*sin);
- return(0);
+ return 0;
}
EXPORT_SYMBOL(inet6_getname);
@@ -488,7 +489,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case SIOCADDRT:
case SIOCDELRT:
- return(ipv6_route_ioctl(net, cmd, (void __user *)arg));
+ return ipv6_route_ioctl(net, cmd, (void __user *)arg);
case SIOCSIFADDR:
return addrconf_add_ifaddr(net, (void __user *) arg);
@@ -502,7 +503,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
return sk->sk_prot->ioctl(sk, cmd, arg);
}
/*NOTREACHED*/
- return(0);
+ return 0;
}
EXPORT_SYMBOL(inet6_ioctl);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index ef371aa01ac5..320bdb877eed 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -577,6 +577,25 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
u8 *ptr = nh + opt->dst1;
put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
}
+ if (np->rxopt.bits.rxorigdstaddr) {
+ struct sockaddr_in6 sin6;
+ u16 *ports = (u16 *) skb_transport_header(skb);
+
+ if (skb_transport_offset(skb) + 4 <= skb->len) {
+ /* All current transport protocols have the port numbers in the
+ * first four bytes of the transport header and this function is
+ * written with this assumption in mind.
+ */
+
+ sin6.sin6_family = AF_INET6;
+ ipv6_addr_copy(&sin6.sin6_addr, &ipv6_hdr(skb)->daddr);
+ sin6.sin6_port = ports[1];
+ sin6.sin6_flowinfo = 0;
+ sin6.sin6_scope_id = 0;
+
+ put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6);
+ }
+ }
return 0;
}
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index e1caa5d526c2..14ed0a955b56 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -13,12 +13,12 @@ int ipv6_ext_hdr(u8 nexthdr)
/*
* find out if nexthdr is an extension header or a protocol
*/
- return ( (nexthdr == NEXTHDR_HOP) ||
+ return (nexthdr == NEXTHDR_HOP) ||
(nexthdr == NEXTHDR_ROUTING) ||
(nexthdr == NEXTHDR_FRAGMENT) ||
(nexthdr == NEXTHDR_AUTH) ||
(nexthdr == NEXTHDR_NONE) ||
- (nexthdr == NEXTHDR_DEST) );
+ (nexthdr == NEXTHDR_DEST);
}
/*
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index b1108ede18e1..d829874d8946 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -34,11 +34,10 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
{
struct fib_lookup_arg arg = {
.lookup_ptr = lookup,
+ .flags = FIB_LOOKUP_NOREF,
};
fib_rules_lookup(net->ipv6.fib6_rules_ops, fl, flags, &arg);
- if (arg.rule)
- fib_rule_put(arg.rule);
if (arg.result)
return arg.result;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index b6a585909d35..de382114609b 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1500,15 +1500,18 @@ static void fib6_gc_timer_cb(unsigned long arg)
static int __net_init fib6_net_init(struct net *net)
{
+ size_t size = sizeof(struct hlist_head) * FIB6_TABLE_HASHSZ;
+
setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net);
net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL);
if (!net->ipv6.rt6_stats)
goto out_timer;
- net->ipv6.fib_table_hash = kcalloc(FIB6_TABLE_HASHSZ,
- sizeof(*net->ipv6.fib_table_hash),
- GFP_KERNEL);
+ /* Avoid false sharing : Use at least a full cache line */
+ size = max_t(size_t, size, L1_CACHE_BYTES);
+
+ net->ipv6.fib_table_hash = kzalloc(size, GFP_KERNEL);
if (!net->ipv6.fib_table_hash)
goto out_rt6_stats;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 980912ed7a38..99157b4cd56e 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -637,7 +637,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
}
mtu -= hlen + sizeof(struct frag_hdr);
- if (skb_has_frags(skb)) {
+ if (skb_has_frag_list(skb)) {
int first_len = skb_pagelen(skb);
struct sk_buff *frag2;
@@ -878,8 +878,8 @@ static inline int ip6_rt_check(struct rt6key *rt_key,
struct in6_addr *fl_addr,
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)));
+ return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) &&
+ (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache));
}
static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 0fd027f3f47e..c2c0f89397b1 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -75,7 +75,7 @@ MODULE_LICENSE("GPL");
(addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \
(HASH_SIZE - 1))
-static void ip6_tnl_dev_init(struct net_device *dev);
+static int ip6_tnl_dev_init(struct net_device *dev);
static void ip6_tnl_dev_setup(struct net_device *dev);
static int ip6_tnl_net_id __read_mostly;
@@ -83,15 +83,42 @@ struct ip6_tnl_net {
/* the IPv6 tunnel fallback device */
struct net_device *fb_tnl_dev;
/* lists for storing tunnels in use */
- struct ip6_tnl *tnls_r_l[HASH_SIZE];
- struct ip6_tnl *tnls_wc[1];
- struct ip6_tnl **tnls[2];
+ struct ip6_tnl __rcu *tnls_r_l[HASH_SIZE];
+ struct ip6_tnl __rcu *tnls_wc[1];
+ struct ip6_tnl __rcu **tnls[2];
};
+/* often modified stats are per cpu, other are shared (netdev->stats) */
+struct pcpu_tstats {
+ unsigned long rx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_packets;
+ unsigned long tx_bytes;
+};
+
+static struct net_device_stats *ip6_get_stats(struct net_device *dev)
+{
+ struct pcpu_tstats sum = { 0 };
+ int i;
+
+ for_each_possible_cpu(i) {
+ const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
+
+ sum.rx_packets += tstats->rx_packets;
+ sum.rx_bytes += tstats->rx_bytes;
+ sum.tx_packets += tstats->tx_packets;
+ sum.tx_bytes += tstats->tx_bytes;
+ }
+ dev->stats.rx_packets = sum.rx_packets;
+ dev->stats.rx_bytes = sum.rx_bytes;
+ dev->stats.tx_packets = sum.tx_packets;
+ dev->stats.tx_bytes = sum.tx_bytes;
+ return &dev->stats;
+}
+
/*
- * Locking : hash tables are protected by RCU and a spinlock
+ * Locking : hash tables are protected by RCU and RTNL
*/
-static DEFINE_SPINLOCK(ip6_tnl_lock);
static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t)
{
@@ -138,8 +165,8 @@ static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst)
static struct ip6_tnl *
ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
{
- unsigned h0 = HASH(remote);
- unsigned h1 = HASH(local);
+ unsigned int h0 = HASH(remote);
+ unsigned int h1 = HASH(local);
struct ip6_tnl *t;
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
@@ -167,7 +194,7 @@ ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
* Return: head of IPv6 tunnel list
**/
-static struct ip6_tnl **
+static struct ip6_tnl __rcu **
ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p)
{
struct in6_addr *remote = &p->raddr;
@@ -190,12 +217,10 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p)
static void
ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
{
- struct ip6_tnl **tp = ip6_tnl_bucket(ip6n, &t->parms);
+ struct ip6_tnl __rcu **tp = ip6_tnl_bucket(ip6n, &t->parms);
- spin_lock_bh(&ip6_tnl_lock);
- t->next = *tp;
+ rcu_assign_pointer(t->next , rtnl_dereference(*tp));
rcu_assign_pointer(*tp, t);
- spin_unlock_bh(&ip6_tnl_lock);
}
/**
@@ -206,18 +231,25 @@ ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
static void
ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
{
- struct ip6_tnl **tp;
-
- for (tp = ip6_tnl_bucket(ip6n, &t->parms); *tp; tp = &(*tp)->next) {
- if (t == *tp) {
- spin_lock_bh(&ip6_tnl_lock);
- *tp = t->next;
- spin_unlock_bh(&ip6_tnl_lock);
+ struct ip6_tnl __rcu **tp;
+ struct ip6_tnl *iter;
+
+ for (tp = ip6_tnl_bucket(ip6n, &t->parms);
+ (iter = rtnl_dereference(*tp)) != NULL;
+ tp = &iter->next) {
+ if (t == iter) {
+ rcu_assign_pointer(*tp, t->next);
break;
}
}
}
+static void ip6_dev_free(struct net_device *dev)
+{
+ free_percpu(dev->tstats);
+ free_netdev(dev);
+}
+
/**
* ip6_tnl_create() - create a new tunnel
* @p: tunnel parameters
@@ -256,7 +288,9 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
t = netdev_priv(dev);
t->parms = *p;
- ip6_tnl_dev_init(dev);
+ err = ip6_tnl_dev_init(dev);
+ if (err < 0)
+ goto failed_free;
if ((err = register_netdevice(dev)) < 0)
goto failed_free;
@@ -266,7 +300,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
return t;
failed_free:
- free_netdev(dev);
+ ip6_dev_free(dev);
failed:
return NULL;
}
@@ -290,10 +324,13 @@ static struct ip6_tnl *ip6_tnl_locate(struct net *net,
{
struct in6_addr *remote = &p->raddr;
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);
- for (t = *ip6_tnl_bucket(ip6n, p); t; t = t->next) {
+ for (tp = ip6_tnl_bucket(ip6n, p);
+ (t = rtnl_dereference(*tp)) != NULL;
+ tp = &t->next) {
if (ipv6_addr_equal(local, &t->parms.laddr) &&
ipv6_addr_equal(remote, &t->parms.raddr))
return t;
@@ -318,13 +355,10 @@ ip6_tnl_dev_uninit(struct net_device *dev)
struct net *net = dev_net(dev);
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
- if (dev == ip6n->fb_tnl_dev) {
- spin_lock_bh(&ip6_tnl_lock);
- ip6n->tnls_wc[0] = NULL;
- spin_unlock_bh(&ip6_tnl_lock);
- } else {
+ if (dev == ip6n->fb_tnl_dev)
+ rcu_assign_pointer(ip6n->tnls_wc[0], NULL);
+ else
ip6_tnl_unlink(ip6n, t);
- }
ip6_tnl_dst_reset(t);
dev_put(dev);
}
@@ -702,6 +736,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr,
&ipv6h->daddr)) != NULL) {
+ struct pcpu_tstats *tstats;
+
if (t->parms.proto != ipproto && t->parms.proto != 0) {
rcu_read_unlock();
goto discard;
@@ -724,10 +760,16 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
skb->pkt_type = PACKET_HOST;
memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
- skb_tunnel_rx(skb, t->dev);
+ tstats = this_cpu_ptr(t->dev->tstats);
+ tstats->rx_packets++;
+ tstats->rx_bytes += skb->len;
+
+ __skb_tunnel_rx(skb, t->dev);
dscp_ecn_decapsulate(t, ipv6h, skb);
+
netif_rx(skb);
+
rcu_read_unlock();
return 0;
}
@@ -934,8 +976,10 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
err = ip6_local_out(skb);
if (net_xmit_eval(err) == 0) {
- stats->tx_bytes += pkt_len;
- stats->tx_packets++;
+ struct pcpu_tstats *tstats = this_cpu_ptr(t->dev->tstats);
+
+ tstats->tx_bytes += pkt_len;
+ tstats->tx_packets++;
} else {
stats->tx_errors++;
stats->tx_aborted_errors++;
@@ -1300,12 +1344,14 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)
static const struct net_device_ops ip6_tnl_netdev_ops = {
- .ndo_uninit = ip6_tnl_dev_uninit,
+ .ndo_uninit = ip6_tnl_dev_uninit,
.ndo_start_xmit = ip6_tnl_xmit,
- .ndo_do_ioctl = ip6_tnl_ioctl,
+ .ndo_do_ioctl = ip6_tnl_ioctl,
.ndo_change_mtu = ip6_tnl_change_mtu,
+ .ndo_get_stats = ip6_get_stats,
};
+
/**
* ip6_tnl_dev_setup - setup virtual tunnel device
* @dev: virtual device associated with tunnel
@@ -1317,7 +1363,7 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
static void ip6_tnl_dev_setup(struct net_device *dev)
{
dev->netdev_ops = &ip6_tnl_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = ip6_dev_free;
dev->type = ARPHRD_TUNNEL6;
dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
@@ -1333,12 +1379,17 @@ static void ip6_tnl_dev_setup(struct net_device *dev)
* @dev: virtual device associated with tunnel
**/
-static inline void
+static inline int
ip6_tnl_dev_init_gen(struct net_device *dev)
{
struct ip6_tnl *t = netdev_priv(dev);
+
t->dev = dev;
strcpy(t->parms.name, dev->name);
+ dev->tstats = alloc_percpu(struct pcpu_tstats);
+ if (!dev->tstats)
+ return -ENOMEM;
+ return 0;
}
/**
@@ -1346,11 +1397,15 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
* @dev: virtual device associated with tunnel
**/
-static void ip6_tnl_dev_init(struct net_device *dev)
+static int ip6_tnl_dev_init(struct net_device *dev)
{
struct ip6_tnl *t = netdev_priv(dev);
- ip6_tnl_dev_init_gen(dev);
+ int err = ip6_tnl_dev_init_gen(dev);
+
+ if (err)
+ return err;
ip6_tnl_link_config(t);
+ return 0;
}
/**
@@ -1360,25 +1415,29 @@ static void ip6_tnl_dev_init(struct net_device *dev)
* Return: 0
**/
-static void __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
+static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
{
struct ip6_tnl *t = netdev_priv(dev);
struct net *net = dev_net(dev);
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+ int err = ip6_tnl_dev_init_gen(dev);
+
+ if (err)
+ return err;
- ip6_tnl_dev_init_gen(dev);
t->parms.proto = IPPROTO_IPV6;
dev_hold(dev);
- ip6n->tnls_wc[0] = t;
+ rcu_assign_pointer(ip6n->tnls_wc[0], t);
+ return 0;
}
-static struct xfrm6_tunnel ip4ip6_handler = {
+static struct xfrm6_tunnel ip4ip6_handler __read_mostly = {
.handler = ip4ip6_rcv,
.err_handler = ip4ip6_err,
.priority = 1,
};
-static struct xfrm6_tunnel ip6ip6_handler = {
+static struct xfrm6_tunnel ip6ip6_handler __read_mostly = {
.handler = ip6ip6_rcv,
.err_handler = ip6ip6_err,
.priority = 1,
@@ -1391,14 +1450,14 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
LIST_HEAD(list);
for (h = 0; h < HASH_SIZE; h++) {
- t = ip6n->tnls_r_l[h];
+ t = rtnl_dereference(ip6n->tnls_r_l[h]);
while (t != NULL) {
unregister_netdevice_queue(t->dev, &list);
- t = t->next;
+ t = rtnl_dereference(t->next);
}
}
- t = ip6n->tnls_wc[0];
+ t = rtnl_dereference(ip6n->tnls_wc[0]);
unregister_netdevice_queue(t->dev, &list);
unregister_netdevice_many(&list);
}
@@ -1419,7 +1478,9 @@ static int __net_init ip6_tnl_init_net(struct net *net)
goto err_alloc_dev;
dev_net_set(ip6n->fb_tnl_dev, net);
- ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev);
+ err = ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev);
+ if (err < 0)
+ goto err_register;
err = register_netdev(ip6n->fb_tnl_dev);
if (err < 0)
@@ -1427,7 +1488,7 @@ static int __net_init ip6_tnl_init_net(struct net *net)
return 0;
err_register:
- free_netdev(ip6n->fb_tnl_dev);
+ ip6_dev_free(ip6n->fb_tnl_dev);
err_alloc_dev:
return err;
}
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 66078dad7fe8..6f32ffce7022 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -667,6 +667,7 @@ static int pim6_rcv(struct sk_buff *skb)
skb_tunnel_rx(skb, reg_dev);
netif_rx(skb);
+
dev_put(reg_dev);
return 0;
drop:
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index a7f66bc8f0b0..0553867a317f 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -342,6 +342,21 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
retv = 0;
break;
+ case IPV6_TRANSPARENT:
+ if (optlen < sizeof(int))
+ goto e_inval;
+ /* we don't have a separate transparent bit for IPV6 we use the one in the IPv4 socket */
+ inet_sk(sk)->transparent = valbool;
+ retv = 0;
+ break;
+
+ case IPV6_RECVORIGDSTADDR:
+ if (optlen < sizeof(int))
+ goto e_inval;
+ np->rxopt.bits.rxorigdstaddr = valbool;
+ retv = 0;
+ break;
+
case IPV6_HOPOPTS:
case IPV6_RTHDRDSTOPTS:
case IPV6_RTHDR:
@@ -1104,6 +1119,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
break;
}
+ case IPV6_TRANSPARENT:
+ val = inet_sk(sk)->transparent;
+ break;
+
+ case IPV6_RECVORIGDSTADDR:
+ val = np->rxopt.bits.rxorigdstaddr;
+ break;
+
case IPV6_UNICAST_HOPS:
case IPV6_MULTICAST_HOPS:
{
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 58841c4ae947..998d6d27e7cf 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -91,7 +91,9 @@
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
-static u32 ndisc_hash(const void *pkey, const struct net_device *dev);
+static u32 ndisc_hash(const void *pkey,
+ const struct net_device *dev,
+ __u32 rnd);
static int ndisc_constructor(struct neighbour *neigh);
static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
@@ -228,12 +230,12 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
do {
cur = ((void *)cur) + (cur->nd_opt_len << 3);
} while(cur < end && cur->nd_opt_type != type);
- return (cur <= end && cur->nd_opt_type == type ? cur : NULL);
+ return cur <= end && cur->nd_opt_type == type ? cur : NULL;
}
static inline int ndisc_is_useropt(struct nd_opt_hdr *opt)
{
- return (opt->nd_opt_type == ND_OPT_RDNSS);
+ return opt->nd_opt_type == ND_OPT_RDNSS;
}
static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur,
@@ -244,7 +246,7 @@ static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur,
do {
cur = ((void *)cur) + (cur->nd_opt_len << 3);
} while(cur < end && !ndisc_is_useropt(cur));
- return (cur <= end && ndisc_is_useropt(cur) ? cur : NULL);
+ return cur <= end && ndisc_is_useropt(cur) ? cur : NULL;
}
static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
@@ -319,7 +321,7 @@ static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
int prepad = ndisc_addr_option_pad(dev->type);
if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad))
return NULL;
- return (lladdr + prepad);
+ return lladdr + prepad;
}
int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
@@ -350,7 +352,9 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d
EXPORT_SYMBOL(ndisc_mc_map);
-static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
+static u32 ndisc_hash(const void *pkey,
+ const struct net_device *dev,
+ __u32 hash_rnd)
{
const u32 *p32 = pkey;
u32 addr_hash, i;
@@ -359,7 +363,7 @@ static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++)
addr_hash ^= *p32++;
- return jhash_2words(addr_hash, dev->ifindex, nd_tbl.hash_rnd);
+ return jhash_2words(addr_hash, dev->ifindex, hash_rnd);
}
static int ndisc_constructor(struct neighbour *neigh)
@@ -1105,6 +1109,18 @@ errout:
rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err);
}
+static inline int accept_ra(struct inet6_dev *in6_dev)
+{
+ /*
+ * If forwarding is enabled, RA are not accepted unless the special
+ * hybrid mode (accept_ra=2) is enabled.
+ */
+ if (in6_dev->cnf.forwarding && in6_dev->cnf.accept_ra < 2)
+ return 0;
+
+ return in6_dev->cnf.accept_ra;
+}
+
static void ndisc_router_discovery(struct sk_buff *skb)
{
struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb);
@@ -1158,8 +1174,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
return;
}
- /* skip route and link configuration on routers */
- if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra)
+ if (!accept_ra(in6_dev))
goto skip_linkparms;
#ifdef CONFIG_IPV6_NDISC_NODETYPE
@@ -1309,8 +1324,7 @@ skip_linkparms:
NEIGH_UPDATE_F_ISROUTER);
}
- /* skip route and link configuration on routers */
- if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra)
+ if (!accept_ra(in6_dev))
goto out;
#ifdef CONFIG_IPV6_ROUTE_INFO
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 29d643bcafa4..44d2eeac089b 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -132,10 +132,10 @@ config IP6_NF_MATCH_RT
# The targets
config IP6_NF_TARGET_HL
tristate '"HL" hoplimit target support'
- depends on NETFILTER_ADVANCED
+ depends on NETFILTER_ADVANCED && IP6_NF_MANGLE
select NETFILTER_XT_TARGET_HL
---help---
- This is a backwards-compat option for the user's convenience
+ This is a backwards-compatible option for the user's convenience
(e.g. when running oldconfig). It selects
CONFIG_NETFILTER_XT_TARGET_HL.
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index aafbba30c899..3f8e4a3d83ce 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -11,10 +11,11 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o
# objects for l3 independent conntrack
-nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
+nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o
+nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
# l3 independent conntrack
-obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o
+obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o
# matches
obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 8e754be92c24..51df035897e7 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -82,13 +82,13 @@ EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table);
int
ip6t_ext_hdr(u8 nexthdr)
{
- return ( (nexthdr == IPPROTO_HOPOPTS) ||
- (nexthdr == IPPROTO_ROUTING) ||
- (nexthdr == IPPROTO_FRAGMENT) ||
- (nexthdr == IPPROTO_ESP) ||
- (nexthdr == IPPROTO_AH) ||
- (nexthdr == IPPROTO_NONE) ||
- (nexthdr == IPPROTO_DSTOPTS) );
+ return (nexthdr == IPPROTO_HOPOPTS) ||
+ (nexthdr == IPPROTO_ROUTING) ||
+ (nexthdr == IPPROTO_FRAGMENT) ||
+ (nexthdr == IPPROTO_ESP) ||
+ (nexthdr == IPPROTO_AH) ||
+ (nexthdr == IPPROTO_NONE) ||
+ (nexthdr == IPPROTO_DSTOPTS);
}
/* Returns whether matches rule or not. */
@@ -215,7 +215,7 @@ static inline bool unconditional(const struct ip6t_ip6 *ipv6)
return memcmp(ipv6, &uncond, sizeof(uncond)) == 0;
}
-static inline const struct ip6t_entry_target *
+static inline const struct xt_entry_target *
ip6t_get_target_c(const struct ip6t_entry *e)
{
return ip6t_get_target((struct ip6t_entry *)e);
@@ -260,9 +260,9 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e,
const char *hookname, const char **chainname,
const char **comment, unsigned int *rulenum)
{
- const struct ip6t_standard_target *t = (void *)ip6t_get_target_c(s);
+ const struct xt_standard_target *t = (void *)ip6t_get_target_c(s);
- if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) {
+ if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) {
/* Head of user chain: ERROR target with chainname */
*chainname = t->target.data;
(*rulenum) = 0;
@@ -271,7 +271,7 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e,
if (s->target_offset == sizeof(struct ip6t_entry) &&
strcmp(t->target.u.kernel.target->name,
- IP6T_STANDARD_TARGET) == 0 &&
+ XT_STANDARD_TARGET) == 0 &&
t->verdict < 0 &&
unconditional(&s->ipv6)) {
/* Tail of chains: STANDARD target (return/policy) */
@@ -369,7 +369,7 @@ ip6t_do_table(struct sk_buff *skb,
e = get_entry(table_base, private->hook_entry[hook]);
do {
- const struct ip6t_entry_target *t;
+ const struct xt_entry_target *t;
const struct xt_entry_match *ematch;
IP_NF_ASSERT(e);
@@ -403,10 +403,10 @@ ip6t_do_table(struct sk_buff *skb,
if (!t->u.kernel.target->target) {
int v;
- v = ((struct ip6t_standard_target *)t)->verdict;
+ v = ((struct xt_standard_target *)t)->verdict;
if (v < 0) {
/* Pop from stack? */
- if (v != IP6T_RETURN) {
+ if (v != XT_RETURN) {
verdict = (unsigned)(-v) - 1;
break;
}
@@ -434,7 +434,7 @@ ip6t_do_table(struct sk_buff *skb,
acpar.targinfo = t->data;
verdict = t->u.kernel.target->target(skb, &acpar);
- if (verdict == IP6T_CONTINUE)
+ if (verdict == XT_CONTINUE)
e = ip6t_next_entry(e);
else
/* Verdict */
@@ -474,7 +474,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
e->counters.pcnt = pos;
for (;;) {
- const struct ip6t_standard_target *t
+ const struct xt_standard_target *t
= (void *)ip6t_get_target_c(e);
int visited = e->comefrom & (1 << hook);
@@ -488,13 +488,13 @@ mark_source_chains(const struct xt_table_info *newinfo,
/* Unconditional return/END. */
if ((e->target_offset == sizeof(struct ip6t_entry) &&
(strcmp(t->target.u.user.name,
- IP6T_STANDARD_TARGET) == 0) &&
+ XT_STANDARD_TARGET) == 0) &&
t->verdict < 0 &&
unconditional(&e->ipv6)) || visited) {
unsigned int oldpos, size;
if ((strcmp(t->target.u.user.name,
- IP6T_STANDARD_TARGET) == 0) &&
+ XT_STANDARD_TARGET) == 0) &&
t->verdict < -NF_MAX_VERDICT - 1) {
duprintf("mark_source_chains: bad "
"negative verdict (%i)\n",
@@ -537,7 +537,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
int newpos = t->verdict;
if (strcmp(t->target.u.user.name,
- IP6T_STANDARD_TARGET) == 0 &&
+ XT_STANDARD_TARGET) == 0 &&
newpos >= 0) {
if (newpos > newinfo->size -
sizeof(struct ip6t_entry)) {
@@ -565,7 +565,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
return 1;
}
-static void cleanup_match(struct ip6t_entry_match *m, struct net *net)
+static void cleanup_match(struct xt_entry_match *m, struct net *net)
{
struct xt_mtdtor_param par;
@@ -581,14 +581,14 @@ static void cleanup_match(struct ip6t_entry_match *m, struct net *net)
static int
check_entry(const struct ip6t_entry *e, const char *name)
{
- const struct ip6t_entry_target *t;
+ const struct xt_entry_target *t;
if (!ip6_checkentry(&e->ipv6)) {
duprintf("ip_tables: ip check failed %p %s.\n", e, name);
return -EINVAL;
}
- if (e->target_offset + sizeof(struct ip6t_entry_target) >
+ if (e->target_offset + sizeof(struct xt_entry_target) >
e->next_offset)
return -EINVAL;
@@ -599,7 +599,7 @@ check_entry(const struct ip6t_entry *e, const char *name)
return 0;
}
-static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par)
+static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
{
const struct ip6t_ip6 *ipv6 = par->entryinfo;
int ret;
@@ -618,7 +618,7 @@ static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par)
}
static int
-find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par)
+find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
{
struct xt_match *match;
int ret;
@@ -643,7 +643,7 @@ err:
static int check_target(struct ip6t_entry *e, struct net *net, const char *name)
{
- struct ip6t_entry_target *t = ip6t_get_target(e);
+ struct xt_entry_target *t = ip6t_get_target(e);
struct xt_tgchk_param par = {
.net = net,
.table = name,
@@ -670,7 +670,7 @@ static int
find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
unsigned int size)
{
- struct ip6t_entry_target *t;
+ struct xt_entry_target *t;
struct xt_target *target;
int ret;
unsigned int j;
@@ -721,7 +721,7 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
static bool check_underflow(const struct ip6t_entry *e)
{
- const struct ip6t_entry_target *t;
+ const struct xt_entry_target *t;
unsigned int verdict;
if (!unconditional(&e->ipv6))
@@ -729,7 +729,7 @@ static bool check_underflow(const struct ip6t_entry *e)
t = ip6t_get_target_c(e);
if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
return false;
- verdict = ((struct ip6t_standard_target *)t)->verdict;
+ verdict = ((struct xt_standard_target *)t)->verdict;
verdict = -verdict - 1;
return verdict == NF_DROP || verdict == NF_ACCEPT;
}
@@ -752,7 +752,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
}
if (e->next_offset
- < sizeof(struct ip6t_entry) + sizeof(struct ip6t_entry_target)) {
+ < sizeof(struct ip6t_entry) + sizeof(struct xt_entry_target)) {
duprintf("checking: element %p size %u\n",
e, e->next_offset);
return -EINVAL;
@@ -784,7 +784,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
static void cleanup_entry(struct ip6t_entry *e, struct net *net)
{
struct xt_tgdtor_param par;
- struct ip6t_entry_target *t;
+ struct xt_entry_target *t;
struct xt_entry_match *ematch;
/* Cleanup all matches */
@@ -985,8 +985,8 @@ copy_entries_to_user(unsigned int total_size,
/* ... then go back and fix counters and names */
for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
unsigned int i;
- const struct ip6t_entry_match *m;
- const struct ip6t_entry_target *t;
+ const struct xt_entry_match *m;
+ const struct xt_entry_target *t;
e = (struct ip6t_entry *)(loc_cpu_entry + off);
if (copy_to_user(userptr + off
@@ -1003,7 +1003,7 @@ copy_entries_to_user(unsigned int total_size,
m = (void *)e + i;
if (copy_to_user(userptr + off + i
- + offsetof(struct ip6t_entry_match,
+ + offsetof(struct xt_entry_match,
u.user.name),
m->u.kernel.match->name,
strlen(m->u.kernel.match->name)+1)
@@ -1015,7 +1015,7 @@ copy_entries_to_user(unsigned int total_size,
t = ip6t_get_target_c(e);
if (copy_to_user(userptr + off + e->target_offset
- + offsetof(struct ip6t_entry_target,
+ + offsetof(struct xt_entry_target,
u.user.name),
t->u.kernel.target->name,
strlen(t->u.kernel.target->name)+1) != 0) {
@@ -1053,7 +1053,7 @@ static int compat_calc_entry(const struct ip6t_entry *e,
const void *base, struct xt_table_info *newinfo)
{
const struct xt_entry_match *ematch;
- const struct ip6t_entry_target *t;
+ const struct xt_entry_target *t;
unsigned int entry_offset;
int off, i, ret;
@@ -1105,7 +1105,7 @@ static int compat_table_info(const struct xt_table_info *info,
static int get_info(struct net *net, void __user *user,
const int *len, int compat)
{
- char name[IP6T_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
struct xt_table *t;
int ret;
@@ -1118,7 +1118,7 @@ static int get_info(struct net *net, void __user *user,
if (copy_from_user(name, user, sizeof(name)) != 0)
return -EFAULT;
- name[IP6T_TABLE_MAXNAMELEN-1] = '\0';
+ name[XT_TABLE_MAXNAMELEN-1] = '\0';
#ifdef CONFIG_COMPAT
if (compat)
xt_compat_lock(AF_INET6);
@@ -1415,14 +1415,14 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
#ifdef CONFIG_COMPAT
struct compat_ip6t_replace {
- char name[IP6T_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
u32 valid_hooks;
u32 num_entries;
u32 size;
u32 hook_entry[NF_INET_NUMHOOKS];
u32 underflow[NF_INET_NUMHOOKS];
u32 num_counters;
- compat_uptr_t counters; /* struct ip6t_counters * */
+ compat_uptr_t counters; /* struct xt_counters * */
struct compat_ip6t_entry entries[0];
};
@@ -1431,7 +1431,7 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
unsigned int *size, struct xt_counters *counters,
unsigned int i)
{
- struct ip6t_entry_target *t;
+ struct xt_entry_target *t;
struct compat_ip6t_entry __user *ce;
u_int16_t target_offset, next_offset;
compat_uint_t origsize;
@@ -1466,7 +1466,7 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
}
static int
-compat_find_calc_match(struct ip6t_entry_match *m,
+compat_find_calc_match(struct xt_entry_match *m,
const char *name,
const struct ip6t_ip6 *ipv6,
unsigned int hookmask,
@@ -1488,7 +1488,7 @@ compat_find_calc_match(struct ip6t_entry_match *m,
static void compat_release_entry(struct compat_ip6t_entry *e)
{
- struct ip6t_entry_target *t;
+ struct xt_entry_target *t;
struct xt_entry_match *ematch;
/* Cleanup all matches */
@@ -1509,7 +1509,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
const char *name)
{
struct xt_entry_match *ematch;
- struct ip6t_entry_target *t;
+ struct xt_entry_target *t;
struct xt_target *target;
unsigned int entry_offset;
unsigned int j;
@@ -1591,7 +1591,7 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
unsigned int *size, const char *name,
struct xt_table_info *newinfo, unsigned char *base)
{
- struct ip6t_entry_target *t;
+ struct xt_entry_target *t;
struct xt_target *target;
struct ip6t_entry *de;
unsigned int origsize;
@@ -1899,7 +1899,7 @@ compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user,
}
struct compat_ip6t_get_entries {
- char name[IP6T_TABLE_MAXNAMELEN];
+ char name[XT_TABLE_MAXNAMELEN];
compat_uint_t size;
struct compat_ip6t_entry entrytable[0];
};
@@ -2054,7 +2054,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
case IP6T_SO_GET_REVISION_MATCH:
case IP6T_SO_GET_REVISION_TARGET: {
- struct ip6t_get_revision rev;
+ struct xt_get_revision rev;
int target;
if (*len != sizeof(rev)) {
@@ -2191,7 +2191,7 @@ static int icmp6_checkentry(const struct xt_mtchk_param *par)
/* The built-in targets: standard (NULL) and error. */
static struct xt_target ip6t_builtin_tg[] __read_mostly = {
{
- .name = IP6T_STANDARD_TARGET,
+ .name = XT_STANDARD_TARGET,
.targetsize = sizeof(int),
.family = NFPROTO_IPV6,
#ifdef CONFIG_COMPAT
@@ -2201,9 +2201,9 @@ static struct xt_target ip6t_builtin_tg[] __read_mostly = {
#endif
},
{
- .name = IP6T_ERROR_TARGET,
+ .name = XT_ERROR_TARGET,
.target = ip6t_error,
- .targetsize = IP6T_FUNCTION_MAXNAMELEN,
+ .targetsize = XT_FUNCTION_MAXNAMELEN,
.family = NFPROTO_IPV6,
},
};
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 0a07ae7b933f..09c88891a753 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -23,6 +23,7 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <net/netfilter/nf_log.h>
+#include <net/netfilter/xt_log.h>
MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
MODULE_DESCRIPTION("Xtables: IPv6 packet logging to syslog");
@@ -32,11 +33,9 @@ struct in_device;
#include <net/route.h>
#include <linux/netfilter_ipv6/ip6t_LOG.h>
-/* Use lock to serialize, so printks don't overlap */
-static DEFINE_SPINLOCK(log_lock);
-
/* One level of recursion won't kill us */
-static void dump_packet(const struct nf_loginfo *info,
+static void dump_packet(struct sbuff *m,
+ const struct nf_loginfo *info,
const struct sk_buff *skb, unsigned int ip6hoff,
int recurse)
{
@@ -55,15 +54,15 @@ static void dump_packet(const struct nf_loginfo *info,
ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
if (ih == NULL) {
- printk("TRUNCATED");
+ sb_add(m, "TRUNCATED");
return;
}
/* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
- printk("SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);
+ sb_add(m, "SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);
/* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
- printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
+ sb_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
(ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
ih->hop_limit,
@@ -78,35 +77,35 @@ static void dump_packet(const struct nf_loginfo *info,
hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
if (hp == NULL) {
- printk("TRUNCATED");
+ sb_add(m, "TRUNCATED");
return;
}
/* Max length: 48 "OPT (...) " */
if (logflags & IP6T_LOG_IPOPT)
- printk("OPT ( ");
+ sb_add(m, "OPT ( ");
switch (currenthdr) {
case IPPROTO_FRAGMENT: {
struct frag_hdr _fhdr;
const struct frag_hdr *fh;
- printk("FRAG:");
+ sb_add(m, "FRAG:");
fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
&_fhdr);
if (fh == NULL) {
- printk("TRUNCATED ");
+ sb_add(m, "TRUNCATED ");
return;
}
/* Max length: 6 "65535 " */
- printk("%u ", ntohs(fh->frag_off) & 0xFFF8);
+ sb_add(m, "%u ", ntohs(fh->frag_off) & 0xFFF8);
/* Max length: 11 "INCOMPLETE " */
if (fh->frag_off & htons(0x0001))
- printk("INCOMPLETE ");
+ sb_add(m, "INCOMPLETE ");
- printk("ID:%08x ", ntohl(fh->identification));
+ sb_add(m, "ID:%08x ", ntohl(fh->identification));
if (ntohs(fh->frag_off) & 0xFFF8)
fragment = 1;
@@ -120,7 +119,7 @@ static void dump_packet(const struct nf_loginfo *info,
case IPPROTO_HOPOPTS:
if (fragment) {
if (logflags & IP6T_LOG_IPOPT)
- printk(")");
+ sb_add(m, ")");
return;
}
hdrlen = ipv6_optlen(hp);
@@ -132,10 +131,10 @@ static void dump_packet(const struct nf_loginfo *info,
const struct ip_auth_hdr *ah;
/* Max length: 3 "AH " */
- printk("AH ");
+ sb_add(m, "AH ");
if (fragment) {
- printk(")");
+ sb_add(m, ")");
return;
}
@@ -146,13 +145,13 @@ static void dump_packet(const struct nf_loginfo *info,
* Max length: 26 "INCOMPLETE [65535
* bytes] )"
*/
- printk("INCOMPLETE [%u bytes] )",
+ sb_add(m, "INCOMPLETE [%u bytes] )",
skb->len - ptr);
return;
}
/* Length: 15 "SPI=0xF1234567 */
- printk("SPI=0x%x ", ntohl(ah->spi));
+ sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
}
@@ -164,10 +163,10 @@ static void dump_packet(const struct nf_loginfo *info,
const struct ip_esp_hdr *eh;
/* Max length: 4 "ESP " */
- printk("ESP ");
+ sb_add(m, "ESP ");
if (fragment) {
- printk(")");
+ sb_add(m, ")");
return;
}
@@ -177,23 +176,23 @@ static void dump_packet(const struct nf_loginfo *info,
eh = skb_header_pointer(skb, ptr, sizeof(_esph),
&_esph);
if (eh == NULL) {
- printk("INCOMPLETE [%u bytes] )",
+ sb_add(m, "INCOMPLETE [%u bytes] )",
skb->len - ptr);
return;
}
/* Length: 16 "SPI=0xF1234567 )" */
- printk("SPI=0x%x )", ntohl(eh->spi) );
+ sb_add(m, "SPI=0x%x )", ntohl(eh->spi) );
}
return;
default:
/* Max length: 20 "Unknown Ext Hdr 255" */
- printk("Unknown Ext Hdr %u", currenthdr);
+ sb_add(m, "Unknown Ext Hdr %u", currenthdr);
return;
}
if (logflags & IP6T_LOG_IPOPT)
- printk(") ");
+ sb_add(m, ") ");
currenthdr = hp->nexthdr;
ptr += hdrlen;
@@ -205,7 +204,7 @@ static void dump_packet(const struct nf_loginfo *info,
const struct tcphdr *th;
/* Max length: 10 "PROTO=TCP " */
- printk("PROTO=TCP ");
+ sb_add(m, "PROTO=TCP ");
if (fragment)
break;
@@ -213,40 +212,40 @@ static void dump_packet(const struct nf_loginfo *info,
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
th = skb_header_pointer(skb, ptr, sizeof(_tcph), &_tcph);
if (th == NULL) {
- printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
+ sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
return;
}
/* Max length: 20 "SPT=65535 DPT=65535 " */
- printk("SPT=%u DPT=%u ",
+ sb_add(m, "SPT=%u DPT=%u ",
ntohs(th->source), ntohs(th->dest));
/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
if (logflags & IP6T_LOG_TCPSEQ)
- printk("SEQ=%u ACK=%u ",
+ sb_add(m, "SEQ=%u ACK=%u ",
ntohl(th->seq), ntohl(th->ack_seq));
/* Max length: 13 "WINDOW=65535 " */
- printk("WINDOW=%u ", ntohs(th->window));
+ sb_add(m, "WINDOW=%u ", ntohs(th->window));
/* Max length: 9 "RES=0x3C " */
- printk("RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22));
+ sb_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22));
/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
if (th->cwr)
- printk("CWR ");
+ sb_add(m, "CWR ");
if (th->ece)
- printk("ECE ");
+ sb_add(m, "ECE ");
if (th->urg)
- printk("URG ");
+ sb_add(m, "URG ");
if (th->ack)
- printk("ACK ");
+ sb_add(m, "ACK ");
if (th->psh)
- printk("PSH ");
+ sb_add(m, "PSH ");
if (th->rst)
- printk("RST ");
+ sb_add(m, "RST ");
if (th->syn)
- printk("SYN ");
+ sb_add(m, "SYN ");
if (th->fin)
- printk("FIN ");
+ sb_add(m, "FIN ");
/* Max length: 11 "URGP=65535 " */
- printk("URGP=%u ", ntohs(th->urg_ptr));
+ sb_add(m, "URGP=%u ", ntohs(th->urg_ptr));
if ((logflags & IP6T_LOG_TCPOPT) &&
th->doff * 4 > sizeof(struct tcphdr)) {
@@ -260,15 +259,15 @@ static void dump_packet(const struct nf_loginfo *info,
ptr + sizeof(struct tcphdr),
optsize, _opt);
if (op == NULL) {
- printk("OPT (TRUNCATED)");
+ sb_add(m, "OPT (TRUNCATED)");
return;
}
/* Max length: 127 "OPT (" 15*4*2chars ") " */
- printk("OPT (");
+ sb_add(m, "OPT (");
for (i =0; i < optsize; i++)
- printk("%02X", op[i]);
- printk(") ");
+ sb_add(m, "%02X", op[i]);
+ sb_add(m, ") ");
}
break;
}
@@ -279,9 +278,9 @@ static void dump_packet(const struct nf_loginfo *info,
if (currenthdr == IPPROTO_UDP)
/* Max length: 10 "PROTO=UDP " */
- printk("PROTO=UDP " );
+ sb_add(m, "PROTO=UDP " );
else /* Max length: 14 "PROTO=UDPLITE " */
- printk("PROTO=UDPLITE ");
+ sb_add(m, "PROTO=UDPLITE ");
if (fragment)
break;
@@ -289,12 +288,12 @@ static void dump_packet(const struct nf_loginfo *info,
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
uh = skb_header_pointer(skb, ptr, sizeof(_udph), &_udph);
if (uh == NULL) {
- printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
+ sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
return;
}
/* Max length: 20 "SPT=65535 DPT=65535 " */
- printk("SPT=%u DPT=%u LEN=%u ",
+ sb_add(m, "SPT=%u DPT=%u LEN=%u ",
ntohs(uh->source), ntohs(uh->dest),
ntohs(uh->len));
break;
@@ -304,7 +303,7 @@ static void dump_packet(const struct nf_loginfo *info,
const struct icmp6hdr *ic;
/* Max length: 13 "PROTO=ICMPv6 " */
- printk("PROTO=ICMPv6 ");
+ sb_add(m, "PROTO=ICMPv6 ");
if (fragment)
break;
@@ -312,18 +311,18 @@ static void dump_packet(const struct nf_loginfo *info,
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h);
if (ic == NULL) {
- printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
+ sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
return;
}
/* Max length: 18 "TYPE=255 CODE=255 " */
- printk("TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code);
+ sb_add(m, "TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code);
switch (ic->icmp6_type) {
case ICMPV6_ECHO_REQUEST:
case ICMPV6_ECHO_REPLY:
/* Max length: 19 "ID=65535 SEQ=65535 " */
- printk("ID=%u SEQ=%u ",
+ sb_add(m, "ID=%u SEQ=%u ",
ntohs(ic->icmp6_identifier),
ntohs(ic->icmp6_sequence));
break;
@@ -334,35 +333,35 @@ static void dump_packet(const struct nf_loginfo *info,
case ICMPV6_PARAMPROB:
/* Max length: 17 "POINTER=ffffffff " */
- printk("POINTER=%08x ", ntohl(ic->icmp6_pointer));
+ sb_add(m, "POINTER=%08x ", ntohl(ic->icmp6_pointer));
/* Fall through */
case ICMPV6_DEST_UNREACH:
case ICMPV6_PKT_TOOBIG:
case ICMPV6_TIME_EXCEED:
/* Max length: 3+maxlen */
if (recurse) {
- printk("[");
- dump_packet(info, skb, ptr + sizeof(_icmp6h),
- 0);
- printk("] ");
+ sb_add(m, "[");
+ dump_packet(m, info, skb,
+ ptr + sizeof(_icmp6h), 0);
+ sb_add(m, "] ");
}
/* Max length: 10 "MTU=65535 " */
if (ic->icmp6_type == ICMPV6_PKT_TOOBIG)
- printk("MTU=%u ", ntohl(ic->icmp6_mtu));
+ sb_add(m, "MTU=%u ", ntohl(ic->icmp6_mtu));
}
break;
}
/* Max length: 10 "PROTO=255 " */
default:
- printk("PROTO=%u ", currenthdr);
+ sb_add(m, "PROTO=%u ", currenthdr);
}
/* Max length: 15 "UID=4294967295 " */
if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) {
read_lock_bh(&skb->sk->sk_callback_lock);
if (skb->sk->sk_socket && skb->sk->sk_socket->file)
- printk("UID=%u GID=%u ",
+ sb_add(m, "UID=%u GID=%u ",
skb->sk->sk_socket->file->f_cred->fsuid,
skb->sk->sk_socket->file->f_cred->fsgid);
read_unlock_bh(&skb->sk->sk_callback_lock);
@@ -370,10 +369,11 @@ static void dump_packet(const struct nf_loginfo *info,
/* Max length: 16 "MARK=0xFFFFFFFF " */
if (!recurse && skb->mark)
- printk("MARK=0x%x ", skb->mark);
+ sb_add(m, "MARK=0x%x ", skb->mark);
}
-static void dump_mac_header(const struct nf_loginfo *info,
+static void dump_mac_header(struct sbuff *m,
+ const struct nf_loginfo *info,
const struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
@@ -387,7 +387,7 @@ static void dump_mac_header(const struct nf_loginfo *info,
switch (dev->type) {
case ARPHRD_ETHER:
- printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
+ sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
ntohs(eth_hdr(skb)->h_proto));
return;
@@ -396,7 +396,7 @@ static void dump_mac_header(const struct nf_loginfo *info,
}
fallback:
- printk("MAC=");
+ sb_add(m, "MAC=");
if (dev->hard_header_len &&
skb->mac_header != skb->network_header) {
const unsigned char *p = skb_mac_header(skb);
@@ -408,19 +408,19 @@ fallback:
p = NULL;
if (p != NULL) {
- printk("%02x", *p++);
+ sb_add(m, "%02x", *p++);
for (i = 1; i < len; i++)
- printk(":%02x", p[i]);
+ sb_add(m, ":%02x", p[i]);
}
- printk(" ");
+ sb_add(m, " ");
if (dev->type == ARPHRD_SIT) {
const struct iphdr *iph =
(struct iphdr *)skb_mac_header(skb);
- printk("TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr);
+ sb_add(m, "TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr);
}
} else
- printk(" ");
+ sb_add(m, " ");
}
static struct nf_loginfo default_loginfo = {
@@ -442,22 +442,23 @@ ip6t_log_packet(u_int8_t pf,
const struct nf_loginfo *loginfo,
const char *prefix)
{
+ struct sbuff *m = sb_open();
+
if (!loginfo)
loginfo = &default_loginfo;
- spin_lock_bh(&log_lock);
- printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
- prefix,
- in ? in->name : "",
- out ? out->name : "");
+ sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
+ prefix,
+ in ? in->name : "",
+ out ? out->name : "");
/* MAC logging for input path only. */
if (in && !out)
- dump_mac_header(loginfo, skb);
+ dump_mac_header(m, loginfo, skb);
+
+ dump_packet(m, loginfo, skb, skb_network_offset(skb), 1);
- dump_packet(loginfo, skb, skb_network_offset(skb), 1);
- printk("\n");
- spin_unlock_bh(&log_lock);
+ sb_close(m);
}
static unsigned int
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index ff43461704be..c8af58b22562 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/icmp.h>
-#include <linux/sysctl.h>
#include <net/ipv6.h>
#include <net/inet_frag.h>
@@ -29,6 +28,7 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
#include <net/netfilter/nf_log.h>
static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
@@ -189,53 +189,6 @@ out:
return nf_conntrack_confirm(skb);
}
-static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
- struct sk_buff *skb)
-{
- u16 zone = NF_CT_DEFAULT_ZONE;
-
- if (skb->nfct)
- zone = nf_ct_zone((struct nf_conn *)skb->nfct);
-
-#ifdef CONFIG_BRIDGE_NETFILTER
- if (skb->nf_bridge &&
- skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
- return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
-#endif
- if (hooknum == NF_INET_PRE_ROUTING)
- return IP6_DEFRAG_CONNTRACK_IN + zone;
- else
- return IP6_DEFRAG_CONNTRACK_OUT + zone;
-
-}
-
-static unsigned int ipv6_defrag(unsigned int hooknum,
- struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
-{
- struct sk_buff *reasm;
-
- /* Previously seen (loopback)? */
- if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
- return NF_ACCEPT;
-
- reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
- /* queued */
- if (reasm == NULL)
- return NF_STOLEN;
-
- /* error occured or not fragmented */
- if (reasm == skb)
- return NF_ACCEPT;
-
- nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
- (struct net_device *)out, okfn);
-
- return NF_STOLEN;
-}
-
static unsigned int __ipv6_conntrack_in(struct net *net,
unsigned int hooknum,
struct sk_buff *skb,
@@ -288,13 +241,6 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
{
- .hook = ipv6_defrag,
- .owner = THIS_MODULE,
- .pf = NFPROTO_IPV6,
- .hooknum = NF_INET_PRE_ROUTING,
- .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
- },
- {
.hook = ipv6_conntrack_in,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
@@ -309,13 +255,6 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
.priority = NF_IP6_PRI_CONNTRACK,
},
{
- .hook = ipv6_defrag,
- .owner = THIS_MODULE,
- .pf = NFPROTO_IPV6,
- .hooknum = NF_INET_LOCAL_OUT,
- .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
- },
- {
.hook = ipv6_confirm,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6,
@@ -387,10 +326,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
.nlattr_to_tuple = ipv6_nlattr_to_tuple,
.nla_policy = ipv6_nla_policy,
#endif
-#ifdef CONFIG_SYSCTL
- .ctl_table_path = nf_net_netfilter_sysctl_path,
- .ctl_table = nf_ct_ipv6_sysctl_table,
-#endif
.me = THIS_MODULE,
};
@@ -403,16 +338,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
int ret = 0;
need_conntrack();
+ nf_defrag_ipv6_enable();
- ret = nf_ct_frag6_init();
- if (ret < 0) {
- pr_err("nf_conntrack_ipv6: can't initialize frag6.\n");
- return ret;
- }
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6);
if (ret < 0) {
pr_err("nf_conntrack_ipv6: can't register tcp.\n");
- goto cleanup_frag6;
+ return ret;
}
ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6);
@@ -450,8 +381,6 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
cleanup_tcp:
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
- cleanup_frag6:
- nf_ct_frag6_cleanup();
return ret;
}
@@ -463,7 +392,6 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void)
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
- nf_ct_frag6_cleanup();
}
module_init(nf_conntrack_l3proto_ipv6_init);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 578f3c1a16db..489d71b844ac 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -73,7 +73,7 @@ static struct inet_frags nf_frags;
static struct netns_frags nf_init_frags;
#ifdef CONFIG_SYSCTL
-struct ctl_table nf_ct_ipv6_sysctl_table[] = {
+struct ctl_table nf_ct_frag6_sysctl_table[] = {
{
.procname = "nf_conntrack_frag6_timeout",
.data = &nf_init_frags.timeout,
@@ -97,6 +97,8 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
},
{ }
};
+
+static struct ctl_table_header *nf_ct_frag6_sysctl_header;
#endif
static unsigned int nf_hashfn(struct inet_frag_queue *q)
@@ -363,7 +365,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
/* If the first fragment is fragmented itself, we split
* it to two chunks: the first with data and paged part
* and the second, holding only fragments. */
- if (skb_has_frags(head)) {
+ if (skb_has_frag_list(head)) {
struct sk_buff *clone;
int i, plen = 0;
@@ -623,11 +625,21 @@ int nf_ct_frag6_init(void)
inet_frags_init_net(&nf_init_frags);
inet_frags_init(&nf_frags);
+ nf_ct_frag6_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path,
+ nf_ct_frag6_sysctl_table);
+ if (!nf_ct_frag6_sysctl_header) {
+ inet_frags_fini(&nf_frags);
+ return -ENOMEM;
+ }
+
return 0;
}
void nf_ct_frag6_cleanup(void)
{
+ unregister_sysctl_table(nf_ct_frag6_sysctl_header);
+ nf_ct_frag6_sysctl_header = NULL;
+
inet_frags_fini(&nf_frags);
nf_init_frags.low_thresh = 0;
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
new file mode 100644
index 000000000000..99abfb53bab9
--- /dev/null
+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
@@ -0,0 +1,131 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/ipv6.h>
+#include <linux/in6.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/icmp.h>
+#include <linux/sysctl.h>
+#include <net/ipv6.h>
+#include <net/inet_frag.h>
+
+#include <linux/netfilter_ipv6.h>
+#include <linux/netfilter_bridge.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_l4proto.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_zones.h>
+#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
+
+static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
+ struct sk_buff *skb)
+{
+ u16 zone = NF_CT_DEFAULT_ZONE;
+
+ if (skb->nfct)
+ zone = nf_ct_zone((struct nf_conn *)skb->nfct);
+
+#ifdef CONFIG_BRIDGE_NETFILTER
+ if (skb->nf_bridge &&
+ skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
+ return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
+#endif
+ if (hooknum == NF_INET_PRE_ROUTING)
+ return IP6_DEFRAG_CONNTRACK_IN + zone;
+ else
+ return IP6_DEFRAG_CONNTRACK_OUT + zone;
+
+}
+
+static unsigned int ipv6_defrag(unsigned int hooknum,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct sk_buff *reasm;
+
+ /* Previously seen (loopback)? */
+ if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
+ return NF_ACCEPT;
+
+ reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
+ /* queued */
+ if (reasm == NULL)
+ return NF_STOLEN;
+
+ /* error occured or not fragmented */
+ if (reasm == skb)
+ return NF_ACCEPT;
+
+ nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
+ (struct net_device *)out, okfn);
+
+ return NF_STOLEN;
+}
+
+static struct nf_hook_ops ipv6_defrag_ops[] = {
+ {
+ .hook = ipv6_defrag,
+ .owner = THIS_MODULE,
+ .pf = NFPROTO_IPV6,
+ .hooknum = NF_INET_PRE_ROUTING,
+ .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
+ },
+ {
+ .hook = ipv6_defrag,
+ .owner = THIS_MODULE,
+ .pf = NFPROTO_IPV6,
+ .hooknum = NF_INET_LOCAL_OUT,
+ .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
+ },
+};
+
+static int __init nf_defrag_init(void)
+{
+ int ret = 0;
+
+ ret = nf_ct_frag6_init();
+ if (ret < 0) {
+ pr_err("nf_defrag_ipv6: can't initialize frag6.\n");
+ return ret;
+ }
+ ret = nf_register_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops));
+ if (ret < 0) {
+ pr_err("nf_defrag_ipv6: can't register hooks\n");
+ goto cleanup_frag6;
+ }
+ return ret;
+
+cleanup_frag6:
+ nf_ct_frag6_cleanup();
+ return ret;
+
+}
+
+static void __exit nf_defrag_fini(void)
+{
+ nf_unregister_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops));
+ nf_ct_frag6_cleanup();
+}
+
+void nf_defrag_ipv6_enable(void)
+{
+}
+EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable);
+
+module_init(nf_defrag_init);
+module_exit(nf_defrag_fini);
+
+MODULE_LICENSE("GPL");
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index 1fa3468f0f32..9bb936ae2452 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -25,28 +25,14 @@
#include <linux/spinlock.h>
#include <net/protocol.h>
-const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
-static DEFINE_SPINLOCK(inet6_proto_lock);
-
+const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS] __read_mostly;
int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol)
{
- int ret, hash = protocol & (MAX_INET_PROTOS - 1);
-
- spin_lock_bh(&inet6_proto_lock);
-
- if (inet6_protos[hash]) {
- ret = -1;
- } else {
- inet6_protos[hash] = prot;
- ret = 0;
- }
-
- spin_unlock_bh(&inet6_proto_lock);
+ int hash = protocol & (MAX_INET_PROTOS - 1);
- return ret;
+ return !cmpxchg(&inet6_protos[hash], NULL, prot) ? 0 : -1;
}
-
EXPORT_SYMBOL(inet6_add_protocol);
/*
@@ -57,20 +43,10 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol
{
int ret, hash = protocol & (MAX_INET_PROTOS - 1);
- spin_lock_bh(&inet6_proto_lock);
-
- if (inet6_protos[hash] != prot) {
- ret = -1;
- } else {
- inet6_protos[hash] = NULL;
- ret = 0;
- }
-
- spin_unlock_bh(&inet6_proto_lock);
+ ret = (cmpxchg(&inet6_protos[hash], prot, NULL) == prot) ? 0 : -1;
synchronize_net();
return ret;
}
-
EXPORT_SYMBOL(inet6_del_protocol);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index e677937a07fc..45e6efb7f171 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -764,7 +764,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
return -EINVAL;
if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
- return(-EAFNOSUPPORT);
+ return -EAFNOSUPPORT;
/* port is the proto value [0..255] carried in nexthdr */
proto = ntohs(sin6->sin6_port);
@@ -772,10 +772,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
if (!proto)
proto = inet->inet_num;
else if (proto != inet->inet_num)
- return(-EINVAL);
+ return -EINVAL;
if (proto > 255)
- return(-EINVAL);
+ return -EINVAL;
daddr = &sin6->sin6_addr;
if (np->sndflow) {
@@ -985,7 +985,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
/* You may get strange result with a positive odd offset;
RFC2292bis agrees with me. */
if (val > 0 && (val&1))
- return(-EINVAL);
+ return -EINVAL;
if (val < 0) {
rp->checksum = 0;
} else {
@@ -997,7 +997,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
break;
default:
- return(-ENOPROTOOPT);
+ return -ENOPROTOOPT;
}
}
@@ -1190,7 +1190,7 @@ static int rawv6_init_sk(struct sock *sk)
default:
break;
}
- return(0);
+ return 0;
}
struct proto rawv6_prot = {
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 64cfef1b0a4c..c7ba3149633f 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -458,7 +458,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
/* If the first fragment is fragmented itself, we split
* it to two chunks: the first with data and paged part
* and the second, holding only fragments. */
- if (skb_has_frags(head)) {
+ if (skb_has_frag_list(head)) {
struct sk_buff *clone;
int i, plen = 0;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index a275c6e1e25c..25661f968f3f 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -109,7 +109,6 @@ static struct dst_ops ip6_dst_ops_template = {
.link_failure = ip6_link_failure,
.update_pmtu = ip6_rt_update_pmtu,
.local_out = __ip6_local_out,
- .entries = ATOMIC_INIT(0),
};
static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -122,7 +121,6 @@ static struct dst_ops ip6_dst_blackhole_ops = {
.destroy = ip6_dst_destroy,
.check = ip6_dst_check,
.update_pmtu = ip6_rt_blackhole_update_pmtu,
- .entries = ATOMIC_INIT(0),
};
static struct rt6_info ip6_null_entry_template = {
@@ -217,14 +215,14 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
static __inline__ int rt6_check_expired(const struct rt6_info *rt)
{
- return (rt->rt6i_flags & RTF_EXPIRES &&
- time_after(jiffies, rt->rt6i_expires));
+ return (rt->rt6i_flags & RTF_EXPIRES) &&
+ time_after(jiffies, rt->rt6i_expires);
}
static inline int rt6_need_strict(struct in6_addr *daddr)
{
- return (ipv6_addr_type(daddr) &
- (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK));
+ return ipv6_addr_type(daddr) &
+ (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
}
/*
@@ -440,7 +438,7 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
__func__, match);
net = dev_net(rt0->rt6i_dev);
- return (match ? match : net->ipv6.ip6_null_entry);
+ return match ? match : net->ipv6.ip6_null_entry;
}
#ifdef CONFIG_IPV6_ROUTE_INFO
@@ -859,7 +857,7 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl
dst_release(*dstp);
*dstp = new;
- return (new ? 0 : -ENOMEM);
+ return new ? 0 : -ENOMEM;
}
EXPORT_SYMBOL_GPL(ip6_dst_blackhole);
@@ -1058,19 +1056,22 @@ static int ip6_dst_gc(struct dst_ops *ops)
int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity;
int rt_gc_timeout = net->ipv6.sysctl.ip6_rt_gc_timeout;
unsigned long rt_last_gc = net->ipv6.ip6_rt_last_gc;
+ int entries;
+ entries = dst_entries_get_fast(ops);
if (time_after(rt_last_gc + rt_min_interval, now) &&
- atomic_read(&ops->entries) <= rt_max_size)
+ entries <= rt_max_size)
goto out;
net->ipv6.ip6_rt_gc_expire++;
fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net);
net->ipv6.ip6_rt_last_gc = now;
- if (atomic_read(&ops->entries) < ops->gc_thresh)
+ entries = dst_entries_get_slow(ops);
+ if (entries < ops->gc_thresh)
net->ipv6.ip6_rt_gc_expire = rt_gc_timeout>>1;
out:
net->ipv6.ip6_rt_gc_expire -= net->ipv6.ip6_rt_gc_expire>>rt_elasticity;
- return (atomic_read(&ops->entries) > rt_max_size);
+ return entries > rt_max_size;
}
/* Clean host part of a prefix. Not necessary in radix tree,
@@ -1169,6 +1170,8 @@ int ip6_route_add(struct fib6_config *cfg)
if (addr_type & IPV6_ADDR_MULTICAST)
rt->dst.input = ip6_mc_input;
+ else if (cfg->fc_flags & RTF_LOCAL)
+ rt->dst.input = ip6_input;
else
rt->dst.input = ip6_forward;
@@ -1190,7 +1193,8 @@ int ip6_route_add(struct fib6_config *cfg)
they would result in kernel looping; promote them to reject routes
*/
if ((cfg->fc_flags & RTF_REJECT) ||
- (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) {
+ (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK)
+ && !(cfg->fc_flags&RTF_LOCAL))) {
/* hold loopback dev/idev if we haven't done so. */
if (dev != net->loopback_dev) {
if (dev) {
@@ -2102,6 +2106,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
if (rtm->rtm_type == RTN_UNREACHABLE)
cfg->fc_flags |= RTF_REJECT;
+ if (rtm->rtm_type == RTN_LOCAL)
+ cfg->fc_flags |= RTF_LOCAL;
+
cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
cfg->fc_nlinfo.nlh = nlh;
cfg->fc_nlinfo.nl_net = sock_net(skb->sk);
@@ -2222,6 +2229,8 @@ static int rt6_fill_node(struct net *net,
NLA_PUT_U32(skb, RTA_TABLE, table);
if (rt->rt6i_flags&RTF_REJECT)
rtm->rtm_type = RTN_UNREACHABLE;
+ else if (rt->rt6i_flags&RTF_LOCAL)
+ rtm->rtm_type = RTN_LOCAL;
else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK))
rtm->rtm_type = RTN_LOCAL;
else
@@ -2516,7 +2525,7 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v)
net->ipv6.rt6_stats->fib_rt_alloc,
net->ipv6.rt6_stats->fib_rt_entries,
net->ipv6.rt6_stats->fib_rt_cache,
- atomic_read(&net->ipv6.ip6_dst_ops.entries),
+ dst_entries_get_slow(&net->ipv6.ip6_dst_ops),
net->ipv6.rt6_stats->fib_discarded_routes);
return 0;
@@ -2658,11 +2667,14 @@ static int __net_init ip6_route_net_init(struct net *net)
memcpy(&net->ipv6.ip6_dst_ops, &ip6_dst_ops_template,
sizeof(net->ipv6.ip6_dst_ops));
+ if (dst_entries_init(&net->ipv6.ip6_dst_ops) < 0)
+ goto out_ip6_dst_ops;
+
net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template,
sizeof(*net->ipv6.ip6_null_entry),
GFP_KERNEL);
if (!net->ipv6.ip6_null_entry)
- goto out_ip6_dst_ops;
+ goto out_ip6_dst_entries;
net->ipv6.ip6_null_entry->dst.path =
(struct dst_entry *)net->ipv6.ip6_null_entry;
net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops;
@@ -2712,6 +2724,8 @@ out_ip6_prohibit_entry:
out_ip6_null_entry:
kfree(net->ipv6.ip6_null_entry);
#endif
+out_ip6_dst_entries:
+ dst_entries_destroy(&net->ipv6.ip6_dst_ops);
out_ip6_dst_ops:
goto out;
}
@@ -2750,10 +2764,14 @@ int __init ip6_route_init(void)
if (!ip6_dst_ops_template.kmem_cachep)
goto out;
- ret = register_pernet_subsys(&ip6_route_net_ops);
+ ret = dst_entries_init(&ip6_dst_blackhole_ops);
if (ret)
goto out_kmem_cache;
+ ret = register_pernet_subsys(&ip6_route_net_ops);
+ if (ret)
+ goto out_dst_entries;
+
ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
/* Registering of the loopback is done before this portion of code,
@@ -2800,6 +2818,8 @@ out_fib6_init:
fib6_gc_cleanup();
out_register_subsys:
unregister_pernet_subsys(&ip6_route_net_ops);
+out_dst_entries:
+ dst_entries_destroy(&ip6_dst_blackhole_ops);
out_kmem_cache:
kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep);
goto out;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 4699cd3c3118..367a6cc584cc 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -63,36 +63,63 @@
#define HASH_SIZE 16
#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
-static void ipip6_tunnel_init(struct net_device *dev);
+static int ipip6_tunnel_init(struct net_device *dev);
static void ipip6_tunnel_setup(struct net_device *dev);
+static void ipip6_dev_free(struct net_device *dev);
static int sit_net_id __read_mostly;
struct sit_net {
- struct ip_tunnel *tunnels_r_l[HASH_SIZE];
- struct ip_tunnel *tunnels_r[HASH_SIZE];
- struct ip_tunnel *tunnels_l[HASH_SIZE];
- struct ip_tunnel *tunnels_wc[1];
- struct ip_tunnel **tunnels[4];
+ struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE];
+ struct ip_tunnel __rcu *tunnels_r[HASH_SIZE];
+ struct ip_tunnel __rcu *tunnels_l[HASH_SIZE];
+ struct ip_tunnel __rcu *tunnels_wc[1];
+ struct ip_tunnel __rcu **tunnels[4];
struct net_device *fb_tunnel_dev;
};
/*
- * Locking : hash tables are protected by RCU and a spinlock
+ * Locking : hash tables are protected by RCU and RTNL
*/
-static DEFINE_SPINLOCK(ipip6_lock);
#define for_each_ip_tunnel_rcu(start) \
for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
+/* often modified stats are per cpu, other are shared (netdev->stats) */
+struct pcpu_tstats {
+ unsigned long rx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_packets;
+ unsigned long tx_bytes;
+};
+
+static struct net_device_stats *ipip6_get_stats(struct net_device *dev)
+{
+ struct pcpu_tstats sum = { 0 };
+ int i;
+
+ for_each_possible_cpu(i) {
+ const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
+
+ sum.rx_packets += tstats->rx_packets;
+ sum.rx_bytes += tstats->rx_bytes;
+ sum.tx_packets += tstats->tx_packets;
+ sum.tx_bytes += tstats->tx_bytes;
+ }
+ dev->stats.rx_packets = sum.rx_packets;
+ dev->stats.rx_bytes = sum.rx_bytes;
+ dev->stats.tx_packets = sum.tx_packets;
+ dev->stats.tx_bytes = sum.tx_bytes;
+ return &dev->stats;
+}
/*
* Must be invoked with rcu_read_lock
*/
static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
struct net_device *dev, __be32 remote, __be32 local)
{
- unsigned h0 = HASH(remote);
- unsigned h1 = HASH(local);
+ unsigned int h0 = HASH(remote);
+ unsigned int h1 = HASH(local);
struct ip_tunnel *t;
struct sit_net *sitn = net_generic(net, sit_net_id);
@@ -121,12 +148,12 @@ static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
return NULL;
}
-static struct ip_tunnel **__ipip6_bucket(struct sit_net *sitn,
+static struct ip_tunnel __rcu **__ipip6_bucket(struct sit_net *sitn,
struct ip_tunnel_parm *parms)
{
__be32 remote = parms->iph.daddr;
__be32 local = parms->iph.saddr;
- unsigned h = 0;
+ unsigned int h = 0;
int prio = 0;
if (remote) {
@@ -140,7 +167,7 @@ static struct ip_tunnel **__ipip6_bucket(struct sit_net *sitn,
return &sitn->tunnels[prio][h];
}
-static inline struct ip_tunnel **ipip6_bucket(struct sit_net *sitn,
+static inline struct ip_tunnel __rcu **ipip6_bucket(struct sit_net *sitn,
struct ip_tunnel *t)
{
return __ipip6_bucket(sitn, &t->parms);
@@ -148,13 +175,14 @@ static inline struct ip_tunnel **ipip6_bucket(struct sit_net *sitn,
static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t)
{
- struct ip_tunnel **tp;
-
- for (tp = ipip6_bucket(sitn, t); *tp; tp = &(*tp)->next) {
- if (t == *tp) {
- spin_lock_bh(&ipip6_lock);
- *tp = t->next;
- spin_unlock_bh(&ipip6_lock);
+ struct ip_tunnel __rcu **tp;
+ struct ip_tunnel *iter;
+
+ for (tp = ipip6_bucket(sitn, t);
+ (iter = rtnl_dereference(*tp)) != NULL;
+ tp = &iter->next) {
+ if (t == iter) {
+ rcu_assign_pointer(*tp, t->next);
break;
}
}
@@ -162,12 +190,10 @@ static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t)
static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t)
{
- struct ip_tunnel **tp = ipip6_bucket(sitn, t);
+ struct ip_tunnel __rcu **tp = ipip6_bucket(sitn, t);
- spin_lock_bh(&ipip6_lock);
- t->next = *tp;
+ rcu_assign_pointer(t->next, rtnl_dereference(*tp));
rcu_assign_pointer(*tp, t);
- spin_unlock_bh(&ipip6_lock);
}
static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
@@ -187,17 +213,20 @@ static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
#endif
}
-static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
+static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
struct ip_tunnel_parm *parms, int create)
{
__be32 remote = parms->iph.daddr;
__be32 local = parms->iph.saddr;
- struct ip_tunnel *t, **tp, *nt;
+ struct ip_tunnel *t, *nt;
+ struct ip_tunnel __rcu **tp;
struct net_device *dev;
char name[IFNAMSIZ];
struct sit_net *sitn = net_generic(net, sit_net_id);
- for (tp = __ipip6_bucket(sitn, parms); (t = *tp) != NULL; tp = &t->next) {
+ for (tp = __ipip6_bucket(sitn, parms);
+ (t = rtnl_dereference(*tp)) != NULL;
+ tp = &t->next) {
if (local == t->parms.iph.saddr &&
remote == t->parms.iph.daddr &&
parms->link == t->parms.link) {
@@ -213,7 +242,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
if (parms->name[0])
strlcpy(name, parms->name, IFNAMSIZ);
else
- sprintf(name, "sit%%d");
+ strcpy(name, "sit%d");
dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup);
if (dev == NULL)
@@ -229,7 +258,8 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
nt = netdev_priv(dev);
nt->parms = *parms;
- ipip6_tunnel_init(dev);
+ if (ipip6_tunnel_init(dev) < 0)
+ goto failed_free;
ipip6_tunnel_clone_6rd(dev, sitn);
if (parms->i_flags & SIT_ISATAP)
@@ -244,7 +274,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
return nt;
failed_free:
- free_netdev(dev);
+ ipip6_dev_free(dev);
failed:
return NULL;
}
@@ -340,7 +370,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
ASSERT_RTNL();
- for (p = t->prl; p; p = p->next) {
+ for (p = rtnl_dereference(t->prl); p; p = rtnl_dereference(p->next)) {
if (p->addr == a->addr) {
if (chg) {
p->flags = a->flags;
@@ -451,15 +481,12 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
struct sit_net *sitn = net_generic(net, sit_net_id);
if (dev == sitn->fb_tunnel_dev) {
- spin_lock_bh(&ipip6_lock);
- sitn->tunnels_wc[0] = NULL;
- spin_unlock_bh(&ipip6_lock);
- dev_put(dev);
+ rcu_assign_pointer(sitn->tunnels_wc[0], NULL);
} else {
ipip6_tunnel_unlink(sitn, netdev_priv(dev));
ipip6_tunnel_del_prl(netdev_priv(dev), NULL);
- dev_put(dev);
}
+ dev_put(dev);
}
@@ -548,6 +575,8 @@ static int ipip6_rcv(struct sk_buff *skb)
tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
iph->saddr, iph->daddr);
if (tunnel != NULL) {
+ struct pcpu_tstats *tstats;
+
secpath_reset(skb);
skb->mac_header = skb->network_header;
skb_reset_network_header(skb);
@@ -563,10 +592,16 @@ static int ipip6_rcv(struct sk_buff *skb)
return 0;
}
- skb_tunnel_rx(skb, tunnel->dev);
+ tstats = this_cpu_ptr(tunnel->dev->tstats);
+ tstats->rx_packets++;
+ tstats->rx_bytes += skb->len;
+
+ __skb_tunnel_rx(skb, tunnel->dev);
ipip6_ecn_decapsulate(iph, skb);
+
netif_rx(skb);
+
rcu_read_unlock();
return 0;
}
@@ -590,7 +625,7 @@ __be32 try_6rd(struct in6_addr *v6dst, struct ip_tunnel *tunnel)
#ifdef CONFIG_IPV6_SIT_6RD
if (ipv6_prefix_equal(v6dst, &tunnel->ip6rd.prefix,
tunnel->ip6rd.prefixlen)) {
- unsigned pbw0, pbi0;
+ unsigned int pbw0, pbi0;
int pbi1;
u32 d;
@@ -625,14 +660,13 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
- struct net_device_stats *stats = &dev->stats;
- struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+ struct pcpu_tstats *tstats;
struct iphdr *tiph = &tunnel->parms.iph;
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 */
- struct net_device *tdev; /* Device to other host */
+ struct net_device *tdev; /* Device to other host */
struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
__be32 dst = tiph->daddr;
@@ -703,20 +737,20 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
.oif = tunnel->parms.link,
.proto = IPPROTO_IPV6 };
if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
- stats->tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
goto tx_error_icmp;
}
}
if (rt->rt_type != RTN_UNICAST) {
ip_rt_put(rt);
- stats->tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
goto tx_error_icmp;
}
tdev = rt->dst.dev;
if (tdev == dev) {
ip_rt_put(rt);
- stats->collisions++;
+ dev->stats.collisions++;
goto tx_error;
}
@@ -724,7 +758,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr);
if (mtu < 68) {
- stats->collisions++;
+ dev->stats.collisions++;
ip_rt_put(rt);
goto tx_error;
}
@@ -763,7 +797,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
if (!new_skb) {
ip_rt_put(rt);
- txq->tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -799,14 +833,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
iph->ttl = iph6->hop_limit;
nf_reset(skb);
-
- IPTUNNEL_XMIT();
+ tstats = this_cpu_ptr(dev->tstats);
+ __IPTUNNEL_XMIT(tstats, &dev->stats);
return NETDEV_TX_OK;
tx_error_icmp:
dst_link_failure(skb);
tx_error:
- stats->tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -1083,12 +1117,19 @@ static const struct net_device_ops ipip6_netdev_ops = {
.ndo_start_xmit = ipip6_tunnel_xmit,
.ndo_do_ioctl = ipip6_tunnel_ioctl,
.ndo_change_mtu = ipip6_tunnel_change_mtu,
+ .ndo_get_stats = ipip6_get_stats,
};
+static void ipip6_dev_free(struct net_device *dev)
+{
+ free_percpu(dev->tstats);
+ free_netdev(dev);
+}
+
static void ipip6_tunnel_setup(struct net_device *dev)
{
dev->netdev_ops = &ipip6_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = ipip6_dev_free;
dev->type = ARPHRD_SIT;
dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
@@ -1098,9 +1139,10 @@ static void ipip6_tunnel_setup(struct net_device *dev)
dev->iflink = 0;
dev->addr_len = 4;
dev->features |= NETIF_F_NETNS_LOCAL;
+ dev->features |= NETIF_F_LLTX;
}
-static void ipip6_tunnel_init(struct net_device *dev)
+static int ipip6_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
@@ -1111,9 +1153,14 @@ static void ipip6_tunnel_init(struct net_device *dev)
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
ipip6_tunnel_bind_dev(dev);
+ dev->tstats = alloc_percpu(struct pcpu_tstats);
+ if (!dev->tstats)
+ return -ENOMEM;
+
+ return 0;
}
-static void __net_init ipip6_fb_tunnel_init(struct net_device *dev)
+static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
struct iphdr *iph = &tunnel->parms.iph;
@@ -1128,11 +1175,15 @@ static void __net_init ipip6_fb_tunnel_init(struct net_device *dev)
iph->ihl = 5;
iph->ttl = 64;
+ dev->tstats = alloc_percpu(struct pcpu_tstats);
+ if (!dev->tstats)
+ return -ENOMEM;
dev_hold(dev);
sitn->tunnels_wc[0] = tunnel;
+ return 0;
}
-static struct xfrm_tunnel sit_handler = {
+static struct xfrm_tunnel sit_handler __read_mostly = {
.handler = ipip6_rcv,
.err_handler = ipip6_err,
.priority = 1,
@@ -1173,7 +1224,10 @@ static int __net_init sit_init_net(struct net *net)
}
dev_net_set(sitn->fb_tunnel_dev, net);
- ipip6_fb_tunnel_init(sitn->fb_tunnel_dev);
+ err = ipip6_fb_tunnel_init(sitn->fb_tunnel_dev);
+ if (err)
+ goto err_dev_free;
+
ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn);
if ((err = register_netdev(sitn->fb_tunnel_dev)))
@@ -1183,7 +1237,8 @@ static int __net_init sit_init_net(struct net *net)
err_reg_dev:
dev_put(sitn->fb_tunnel_dev);
- free_netdev(sitn->fb_tunnel_dev);
+err_dev_free:
+ ipip6_dev_free(sitn->fb_tunnel_dev);
err_alloc_dev:
return err;
}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index fe6d40418c0b..7e41e2cbb85e 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -139,7 +139,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
return -EINVAL;
if (usin->sin6_family != AF_INET6)
- return(-EAFNOSUPPORT);
+ return -EAFNOSUPPORT;
memset(&fl, 0, sizeof(fl));
@@ -1409,7 +1409,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
newsk = tcp_create_openreq_child(sk, req, skb);
if (newsk == NULL)
- goto out;
+ goto out_nonewsk;
/*
* No need to charge this sock to the relevant IPv6 refcnt debug socks
@@ -1497,18 +1497,22 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
}
#endif
+ if (__inet_inherit_port(sk, newsk) < 0) {
+ sock_put(newsk);
+ goto out;
+ }
__inet6_hash(newsk, NULL);
- __inet_inherit_port(sk, newsk);
return newsk;
out_overflow:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
-out:
- NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
+out_nonewsk:
if (opt && opt != np->opt)
sock_kfree_s(sk, opt, opt->tot_len);
dst_release(dst);
+out:
+ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
return NULL;
}
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index fc3c86a47452..d9864725d0c6 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -30,8 +30,8 @@
#include <net/protocol.h>
#include <net/xfrm.h>
-static struct xfrm6_tunnel *tunnel6_handlers;
-static struct xfrm6_tunnel *tunnel46_handlers;
+static struct xfrm6_tunnel *tunnel6_handlers __read_mostly;
+static struct xfrm6_tunnel *tunnel46_handlers __read_mostly;
static DEFINE_MUTEX(tunnel6_mutex);
int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family)
@@ -51,7 +51,7 @@ int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family)
}
handler->next = *pprev;
- *pprev = handler;
+ rcu_assign_pointer(*pprev, handler);
ret = 0;
@@ -88,6 +88,11 @@ int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
EXPORT_SYMBOL(xfrm6_tunnel_deregister);
+#define for_each_tunnel_rcu(head, handler) \
+ for (handler = rcu_dereference(head); \
+ handler != NULL; \
+ handler = rcu_dereference(handler->next)) \
+
static int tunnel6_rcv(struct sk_buff *skb)
{
struct xfrm6_tunnel *handler;
@@ -95,7 +100,7 @@ static int tunnel6_rcv(struct sk_buff *skb)
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
goto drop;
- for (handler = tunnel6_handlers; handler; handler = handler->next)
+ for_each_tunnel_rcu(tunnel6_handlers, handler)
if (!handler->handler(skb))
return 0;
@@ -113,7 +118,7 @@ static int tunnel46_rcv(struct sk_buff *skb)
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
goto drop;
- for (handler = tunnel46_handlers; handler; handler = handler->next)
+ for_each_tunnel_rcu(tunnel46_handlers, handler)
if (!handler->handler(skb))
return 0;
@@ -129,7 +134,7 @@ static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
{
struct xfrm6_tunnel *handler;
- for (handler = tunnel6_handlers; handler; handler = handler->next)
+ for_each_tunnel_rcu(tunnel6_handlers, handler)
if (!handler->err_handler(skb, opt, type, code, offset, info))
break;
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 5acb3560ff15..c84dad432114 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -122,8 +122,8 @@ static void udp_v6_rehash(struct sock *sk)
static inline int compute_score(struct sock *sk, struct net *net,
unsigned short hnum,
- struct in6_addr *saddr, __be16 sport,
- struct in6_addr *daddr, __be16 dport,
+ const struct in6_addr *saddr, __be16 sport,
+ const struct in6_addr *daddr, __be16 dport,
int dif)
{
int score = -1;
@@ -239,8 +239,8 @@ exact_match:
}
static struct sock *__udp6_lib_lookup(struct net *net,
- struct in6_addr *saddr, __be16 sport,
- struct in6_addr *daddr, __be16 dport,
+ const struct in6_addr *saddr, __be16 sport,
+ const struct in6_addr *daddr, __be16 dport,
int dif, struct udp_table *udptable)
{
struct sock *sk, *result;
@@ -320,6 +320,14 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
udptable);
}
+struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport,
+ const struct in6_addr *daddr, __be16 dport, int dif)
+{
+ return __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, &udp_table);
+}
+EXPORT_SYMBOL_GPL(udp6_lib_lookup);
+
+
/*
* This should be easy, if there is something there we
* return it, otherwise we block.
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 6baeabbbca82..7e74023ea6e4 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -199,7 +199,7 @@ static inline int xfrm6_garbage_collect(struct dst_ops *ops)
struct net *net = container_of(ops, struct net, xfrm.xfrm6_dst_ops);
xfrm6_policy_afinfo.garbage_collect(net);
- return (atomic_read(&ops->entries) > ops->gc_thresh * 2);
+ return dst_entries_get_fast(ops) > ops->gc_thresh * 2;
}
static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -255,7 +255,6 @@ static struct dst_ops xfrm6_dst_ops = {
.ifdown = xfrm6_dst_ifdown,
.local_out = __ip6_local_out,
.gc_thresh = 1024,
- .entries = ATOMIC_INIT(0),
};
static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
@@ -312,11 +311,13 @@ int __init xfrm6_init(void)
*/
gc_thresh = FIB6_TABLE_HASHSZ * 8;
xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh;
+ dst_entries_init(&xfrm6_dst_ops);
ret = xfrm6_policy_init();
- if (ret)
+ if (ret) {
+ dst_entries_destroy(&xfrm6_dst_ops);
goto out;
-
+ }
ret = xfrm6_state_init();
if (ret)
goto out_policy;
@@ -341,4 +342,5 @@ void xfrm6_fini(void)
//xfrm6_input_fini();
xfrm6_policy_fini();
xfrm6_state_fini();
+ dst_entries_destroy(&xfrm6_dst_ops);
}
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 2ce3a8278f26..2969cad408de 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -199,7 +199,7 @@ static void x6spi_destroy_rcu(struct rcu_head *head)
container_of(head, struct xfrm6_tunnel_spi, rcu_head));
}
-void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
+static void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
{
struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
struct xfrm6_tunnel_spi *x6spi;
@@ -223,8 +223,6 @@ void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
spin_unlock_bh(&xfrm6_tunnel_spi_lock);
}
-EXPORT_SYMBOL(xfrm6_tunnel_free_spi);
-
static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
{
skb_push(skb, -skb_network_offset(skb));
@@ -317,13 +315,13 @@ static const struct xfrm_type xfrm6_tunnel_type = {
.output = xfrm6_tunnel_output,
};
-static struct xfrm6_tunnel xfrm6_tunnel_handler = {
+static struct xfrm6_tunnel xfrm6_tunnel_handler __read_mostly = {
.handler = xfrm6_tunnel_rcv,
.err_handler = xfrm6_tunnel_err,
.priority = 2,
};
-static struct xfrm6_tunnel xfrm46_tunnel_handler = {
+static struct xfrm6_tunnel xfrm46_tunnel_handler __read_mostly = {
.handler = xfrm6_tunnel_rcv,
.err_handler = xfrm6_tunnel_err,
.priority = 2,
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index fd55b5135de5..7f097989cde2 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -573,9 +573,9 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name)
/* Requested object/attribute doesn't exist */
if((self->errno == IAS_CLASS_UNKNOWN) ||
(self->errno == IAS_ATTRIB_UNKNOWN))
- return (-EADDRNOTAVAIL);
+ return -EADDRNOTAVAIL;
else
- return (-EHOSTUNREACH);
+ return -EHOSTUNREACH;
}
/* Get the remote TSAP selector */
@@ -663,7 +663,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
__func__, name);
self->daddr = DEV_ADDR_ANY;
kfree(discoveries);
- return(-ENOTUNIQ);
+ return -ENOTUNIQ;
}
/* First time we found that one, save it ! */
daddr = self->daddr;
@@ -677,7 +677,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
IRDA_DEBUG(0, "%s(), unexpected IAS query failure\n", __func__);
self->daddr = DEV_ADDR_ANY;
kfree(discoveries);
- return(-EHOSTUNREACH);
+ return -EHOSTUNREACH;
break;
}
}
@@ -689,7 +689,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
IRDA_DEBUG(1, "%s(), cannot discover service ''%s'' in any device !!!\n",
__func__, name);
self->daddr = DEV_ADDR_ANY;
- return(-EADDRNOTAVAIL);
+ return -EADDRNOTAVAIL;
}
/* Revert back to discovered device & service */
@@ -715,14 +715,11 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
struct sockaddr_irda saddr;
struct sock *sk = sock->sk;
struct irda_sock *self = irda_sk(sk);
- int err;
- lock_kernel();
memset(&saddr, 0, sizeof(saddr));
if (peer) {
- err = -ENOTCONN;
if (sk->sk_state != TCP_ESTABLISHED)
- goto out;
+ return -ENOTCONN;
saddr.sir_family = AF_IRDA;
saddr.sir_lsap_sel = self->dtsap_sel;
@@ -739,10 +736,8 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
/* uaddr_len come to us uninitialised */
*uaddr_len = sizeof (struct sockaddr_irda);
memcpy(uaddr, &saddr, *uaddr_len);
- err = 0;
-out:
- unlock_kernel();
- return err;
+
+ return 0;
}
/*
@@ -758,7 +753,8 @@ static int irda_listen(struct socket *sock, int backlog)
IRDA_DEBUG(2, "%s()\n", __func__);
- lock_kernel();
+ lock_sock(sk);
+
if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) &&
(sk->sk_type != SOCK_DGRAM))
goto out;
@@ -770,7 +766,7 @@ static int irda_listen(struct socket *sock, int backlog)
err = 0;
}
out:
- unlock_kernel();
+ release_sock(sk);
return err;
}
@@ -793,7 +789,7 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (addr_len != sizeof(struct sockaddr_irda))
return -EINVAL;
- lock_kernel();
+ lock_sock(sk);
#ifdef CONFIG_IRDA_ULTRA
/* Special care for Ultra sockets */
if ((sk->sk_type == SOCK_DGRAM) &&
@@ -836,7 +832,7 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
err = 0;
out:
- unlock_kernel();
+ release_sock(sk);
return err;
}
@@ -856,12 +852,13 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
IRDA_DEBUG(2, "%s()\n", __func__);
- lock_kernel();
err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0);
if (err)
- goto out;
+ return err;
err = -EINVAL;
+
+ lock_sock(sk);
if (sock->state != SS_UNCONNECTED)
goto out;
@@ -947,7 +944,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
irda_connect_response(new);
err = 0;
out:
- unlock_kernel();
+ release_sock(sk);
return err;
}
@@ -981,7 +978,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
- lock_kernel();
+ lock_sock(sk);
/* Don't allow connect for Ultra sockets */
err = -ESOCKTNOSUPPORT;
if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA))
@@ -1072,6 +1069,8 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
if (sk->sk_state != TCP_ESTABLISHED) {
sock->state = SS_UNCONNECTED;
+ if (sk->sk_prot->disconnect(sk, flags))
+ sock->state = SS_DISCONNECTING;
err = sock_error(sk);
if (!err)
err = -ECONNRESET;
@@ -1084,7 +1083,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
self->saddr = irttp_get_saddr(self->tsap);
err = 0;
out:
- unlock_kernel();
+ release_sock(sk);
return err;
}
@@ -1231,7 +1230,6 @@ static int irda_release(struct socket *sock)
if (sk == NULL)
return 0;
- lock_kernel();
lock_sock(sk);
sk->sk_state = TCP_CLOSE;
sk->sk_shutdown |= SEND_SHUTDOWN;
@@ -1250,7 +1248,6 @@ static int irda_release(struct socket *sock)
/* Destroy networking socket if we are the last reference on it,
* i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */
sock_put(sk);
- unlock_kernel();
/* Notes on socket locking and deallocation... - Jean II
* In theory we should put pairs of sock_hold() / sock_put() to
@@ -1298,7 +1295,6 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
- lock_kernel();
/* Note : socket.c set MSG_EOR on SEQPACKET sockets */
if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT |
MSG_NOSIGNAL)) {
@@ -1306,6 +1302,8 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
goto out;
}
+ lock_sock(sk);
+
if (sk->sk_shutdown & SEND_SHUTDOWN)
goto out_err;
@@ -1361,14 +1359,14 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
goto out_err;
}
- unlock_kernel();
+ release_sock(sk);
/* Tell client how much data we actually sent */
return len;
out_err:
err = sk_stream_error(sk, msg->msg_flags, err);
out:
- unlock_kernel();
+ release_sock(sk);
return err;
}
@@ -1390,14 +1388,10 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(4, "%s()\n", __func__);
- lock_kernel();
- if ((err = sock_error(sk)) < 0)
- goto out;
-
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err);
if (!skb)
- goto out;
+ return err;
skb_reset_transport_header(skb);
copied = skb->len;
@@ -1425,12 +1419,8 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
irttp_flow_request(self->tsap, FLOW_START);
}
}
- unlock_kernel();
- return copied;
-out:
- unlock_kernel();
- return err;
+ return copied;
}
/*
@@ -1448,17 +1438,15 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(3, "%s()\n", __func__);
- lock_kernel();
if ((err = sock_error(sk)) < 0)
- goto out;
+ return err;
- err = -EINVAL;
if (sock->flags & __SO_ACCEPTCON)
- goto out;
+ return -EINVAL;
err =-EOPNOTSUPP;
if (flags & MSG_OOB)
- goto out;
+ return -EOPNOTSUPP;
err = 0;
target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
@@ -1500,7 +1488,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
finish_wait(sk_sleep(sk), &wait);
if (err)
- goto out;
+ return err;
if (sk->sk_shutdown & RCV_SHUTDOWN)
break;
@@ -1553,9 +1541,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
}
}
-out:
- unlock_kernel();
- return err ? : copied;
+ return copied;
}
/*
@@ -1573,13 +1559,12 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
struct sk_buff *skb;
int err;
- lock_kernel();
-
IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
- err = -EINVAL;
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
- goto out;
+ return -EINVAL;
+
+ lock_sock(sk);
if (sk->sk_shutdown & SEND_SHUTDOWN) {
send_sig(SIGPIPE, current, 0);
@@ -1630,10 +1615,12 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
goto out;
}
- unlock_kernel();
+
+ release_sock(sk);
return len;
+
out:
- unlock_kernel();
+ release_sock(sk);
return err;
}
@@ -1656,10 +1643,11 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
- lock_kernel();
err = -EINVAL;
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
- goto out;
+ return -EINVAL;
+
+ lock_sock(sk);
err = -EPIPE;
if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -1732,7 +1720,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
if (err)
IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
out:
- unlock_kernel();
+ release_sock(sk);
return err ? : len;
}
#endif /* CONFIG_IRDA_ULTRA */
@@ -1747,7 +1735,7 @@ static int irda_shutdown(struct socket *sock, int how)
IRDA_DEBUG(1, "%s(%p)\n", __func__, self);
- lock_kernel();
+ lock_sock(sk);
sk->sk_state = TCP_CLOSE;
sk->sk_shutdown |= SEND_SHUTDOWN;
@@ -1769,7 +1757,7 @@ static int irda_shutdown(struct socket *sock, int how)
self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */
self->saddr = 0x0; /* so IrLMP assign us any link */
- unlock_kernel();
+ release_sock(sk);
return 0;
}
@@ -1786,7 +1774,6 @@ static unsigned int irda_poll(struct file * file, struct socket *sock,
IRDA_DEBUG(4, "%s()\n", __func__);
- lock_kernel();
poll_wait(file, sk_sleep(sk), wait);
mask = 0;
@@ -1834,20 +1821,8 @@ static unsigned int irda_poll(struct file * file, struct socket *sock,
default:
break;
}
- unlock_kernel();
- return mask;
-}
-static unsigned int irda_datagram_poll(struct file *file, struct socket *sock,
- poll_table *wait)
-{
- int err;
-
- lock_kernel();
- err = datagram_poll(file, sock, wait);
- unlock_kernel();
-
- return err;
+ return mask;
}
/*
@@ -1860,7 +1835,6 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd);
- lock_kernel();
err = -EINVAL;
switch (cmd) {
case TIOCOUTQ: {
@@ -1903,7 +1877,6 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__);
err = -ENOIOCTLCMD;
}
- unlock_kernel();
return err;
}
@@ -1927,7 +1900,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
* Set some options for the socket
*
*/
-static int __irda_setsockopt(struct socket *sock, int level, int optname,
+static int irda_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
@@ -1935,13 +1908,15 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
struct irda_ias_set *ias_opt;
struct ias_object *ias_obj;
struct ias_attrib * ias_attr; /* Attribute in IAS object */
- int opt, free_ias = 0;
+ int opt, free_ias = 0, err = 0;
IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
if (level != SOL_IRLMP)
return -ENOPROTOOPT;
+ lock_sock(sk);
+
switch (optname) {
case IRLMP_IAS_SET:
/* The user want to add an attribute to an existing IAS object
@@ -1951,17 +1926,22 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
* create the right attribute...
*/
- if (optlen != sizeof(struct irda_ias_set))
- return -EINVAL;
+ if (optlen != sizeof(struct irda_ias_set)) {
+ err = -EINVAL;
+ goto out;
+ }
ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
- if (ias_opt == NULL)
- return -ENOMEM;
+ if (ias_opt == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
/* Copy query to the driver. */
if (copy_from_user(ias_opt, optval, optlen)) {
kfree(ias_opt);
- return -EFAULT;
+ err = -EFAULT;
+ goto out;
}
/* Find the object we target.
@@ -1971,7 +1951,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
if(ias_opt->irda_class_name[0] == '\0') {
if(self->ias_obj == NULL) {
kfree(ias_opt);
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
ias_obj = self->ias_obj;
} else
@@ -1983,7 +1964,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
if((!capable(CAP_NET_ADMIN)) &&
((ias_obj == NULL) || (ias_obj != self->ias_obj))) {
kfree(ias_opt);
- return -EPERM;
+ err = -EPERM;
+ goto out;
}
/* If the object doesn't exist, create it */
@@ -1993,7 +1975,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
jiffies);
if (ias_obj == NULL) {
kfree(ias_opt);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto out;
}
free_ias = 1;
}
@@ -2005,7 +1988,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
kfree(ias_obj->name);
kfree(ias_obj);
}
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
/* Look at the type */
@@ -2028,7 +2012,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
kfree(ias_obj);
}
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
/* Add an octet sequence attribute */
irias_add_octseq_attrib(
@@ -2060,7 +2045,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
kfree(ias_obj->name);
kfree(ias_obj);
}
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
irias_insert_object(ias_obj);
kfree(ias_opt);
@@ -2071,17 +2057,22 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
* object is not owned by the kernel and delete it.
*/
- if (optlen != sizeof(struct irda_ias_set))
- return -EINVAL;
+ if (optlen != sizeof(struct irda_ias_set)) {
+ err = -EINVAL;
+ goto out;
+ }
ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
- if (ias_opt == NULL)
- return -ENOMEM;
+ if (ias_opt == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
/* Copy query to the driver. */
if (copy_from_user(ias_opt, optval, optlen)) {
kfree(ias_opt);
- return -EFAULT;
+ err = -EFAULT;
+ goto out;
}
/* Find the object we target.
@@ -2094,7 +2085,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
ias_obj = irias_find_object(ias_opt->irda_class_name);
if(ias_obj == (struct ias_object *) NULL) {
kfree(ias_opt);
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
/* Only ROOT can mess with the global IAS database.
@@ -2103,7 +2095,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
if((!capable(CAP_NET_ADMIN)) &&
((ias_obj == NULL) || (ias_obj != self->ias_obj))) {
kfree(ias_opt);
- return -EPERM;
+ err = -EPERM;
+ goto out;
}
/* Find the attribute (in the object) we target */
@@ -2111,14 +2104,16 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
ias_opt->irda_attrib_name);
if(ias_attr == (struct ias_attrib *) NULL) {
kfree(ias_opt);
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
/* Check is the user space own the object */
if(ias_attr->value->owner != IAS_USER_ATTR) {
IRDA_DEBUG(1, "%s(), attempting to delete a kernel attribute\n", __func__);
kfree(ias_opt);
- return -EPERM;
+ err = -EPERM;
+ goto out;
}
/* Remove the attribute (and maybe the object) */
@@ -2126,11 +2121,15 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
kfree(ias_opt);
break;
case IRLMP_MAX_SDU_SIZE:
- if (optlen < sizeof(int))
- return -EINVAL;
+ if (optlen < sizeof(int)) {
+ err = -EINVAL;
+ goto out;
+ }
- if (get_user(opt, (int __user *)optval))
- return -EFAULT;
+ if (get_user(opt, (int __user *)optval)) {
+ err = -EFAULT;
+ goto out;
+ }
/* Only possible for a seqpacket service (TTP with SAR) */
if (sk->sk_type != SOCK_SEQPACKET) {
@@ -2140,16 +2139,21 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
} else {
IRDA_WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n",
__func__);
- return -ENOPROTOOPT;
+ err = -ENOPROTOOPT;
+ goto out;
}
break;
case IRLMP_HINTS_SET:
- if (optlen < sizeof(int))
- return -EINVAL;
+ if (optlen < sizeof(int)) {
+ err = -EINVAL;
+ goto out;
+ }
/* The input is really a (__u8 hints[2]), easier as an int */
- if (get_user(opt, (int __user *)optval))
- return -EFAULT;
+ if (get_user(opt, (int __user *)optval)) {
+ err = -EFAULT;
+ goto out;
+ }
/* Unregister any old registration */
if (self->skey)
@@ -2163,12 +2167,16 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
* making a discovery (nodes which don't match any hint
* bit in the mask are not reported).
*/
- if (optlen < sizeof(int))
- return -EINVAL;
+ if (optlen < sizeof(int)) {
+ err = -EINVAL;
+ goto out;
+ }
/* The input is really a (__u8 hints[2]), easier as an int */
- if (get_user(opt, (int __user *)optval))
- return -EFAULT;
+ if (get_user(opt, (int __user *)optval)) {
+ err = -EFAULT;
+ goto out;
+ }
/* Set the new hint mask */
self->mask.word = (__u16) opt;
@@ -2180,19 +2188,12 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname,
break;
default:
- return -ENOPROTOOPT;
+ err = -ENOPROTOOPT;
+ break;
}
- return 0;
-}
-static int irda_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, unsigned int optlen)
-{
- int err;
-
- lock_kernel();
- err = __irda_setsockopt(sock, level, optname, optval, optlen);
- unlock_kernel();
+out:
+ release_sock(sk);
return err;
}
@@ -2249,7 +2250,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt,
/*
* Function irda_getsockopt (sock, level, optname, optval, optlen)
*/
-static int __irda_getsockopt(struct socket *sock, int level, int optname,
+static int irda_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
@@ -2262,7 +2263,7 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname,
int daddr = DEV_ADDR_ANY; /* Dest address for IAS queries */
int val = 0;
int len = 0;
- int err;
+ int err = 0;
int offset, total;
IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
@@ -2276,15 +2277,18 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname,
if(len < 0)
return -EINVAL;
+ lock_sock(sk);
+
switch (optname) {
case IRLMP_ENUMDEVICES:
/* Ask lmp for the current discovery log */
discoveries = irlmp_get_discoveries(&list.len, self->mask.word,
self->nslots);
/* Check if the we got some results */
- if (discoveries == NULL)
- return -EAGAIN; /* Didn't find any devices */
- err = 0;
+ if (discoveries == NULL) {
+ err = -EAGAIN;
+ goto out; /* Didn't find any devices */
+ }
/* Write total list length back to client */
if (copy_to_user(optval, &list,
@@ -2297,8 +2301,7 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname,
sizeof(struct irda_device_info);
/* Copy the list itself - watch for overflow */
- if(list.len > 2048)
- {
+ if (list.len > 2048) {
err = -EINVAL;
goto bed;
}
@@ -2314,17 +2317,20 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname,
bed:
/* Free up our buffer */
kfree(discoveries);
- if (err)
- return err;
break;
case IRLMP_MAX_SDU_SIZE:
val = self->max_data_size;
len = sizeof(int);
- if (put_user(len, optlen))
- return -EFAULT;
+ if (put_user(len, optlen)) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ if (copy_to_user(optval, &val, len)) {
+ err = -EFAULT;
+ goto out;
+ }
- if (copy_to_user(optval, &val, len))
- return -EFAULT;
break;
case IRLMP_IAS_GET:
/* The user want an object from our local IAS database.
@@ -2332,17 +2338,22 @@ bed:
* that we found */
/* Check that the user has allocated the right space for us */
- if (len != sizeof(struct irda_ias_set))
- return -EINVAL;
+ if (len != sizeof(struct irda_ias_set)) {
+ err = -EINVAL;
+ goto out;
+ }
ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
- if (ias_opt == NULL)
- return -ENOMEM;
+ if (ias_opt == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
/* Copy query to the driver. */
if (copy_from_user(ias_opt, optval, len)) {
kfree(ias_opt);
- return -EFAULT;
+ err = -EFAULT;
+ goto out;
}
/* Find the object we target.
@@ -2355,7 +2366,8 @@ bed:
ias_obj = irias_find_object(ias_opt->irda_class_name);
if(ias_obj == (struct ias_object *) NULL) {
kfree(ias_opt);
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
/* Find the attribute (in the object) we target */
@@ -2363,21 +2375,23 @@ bed:
ias_opt->irda_attrib_name);
if(ias_attr == (struct ias_attrib *) NULL) {
kfree(ias_opt);
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
/* Translate from internal to user structure */
err = irda_extract_ias_value(ias_opt, ias_attr->value);
if(err) {
kfree(ias_opt);
- return err;
+ goto out;
}
/* Copy reply to the user */
if (copy_to_user(optval, ias_opt,
sizeof(struct irda_ias_set))) {
kfree(ias_opt);
- return -EFAULT;
+ err = -EFAULT;
+ goto out;
}
/* Note : don't need to put optlen, we checked it */
kfree(ias_opt);
@@ -2388,17 +2402,22 @@ bed:
* then wait for the answer to come back. */
/* Check that the user has allocated the right space for us */
- if (len != sizeof(struct irda_ias_set))
- return -EINVAL;
+ if (len != sizeof(struct irda_ias_set)) {
+ err = -EINVAL;
+ goto out;
+ }
ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
- if (ias_opt == NULL)
- return -ENOMEM;
+ if (ias_opt == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
/* Copy query to the driver. */
if (copy_from_user(ias_opt, optval, len)) {
kfree(ias_opt);
- return -EFAULT;
+ err = -EFAULT;
+ goto out;
}
/* At this point, there are two cases...
@@ -2419,7 +2438,8 @@ bed:
daddr = ias_opt->daddr;
if((!daddr) || (daddr == DEV_ADDR_ANY)) {
kfree(ias_opt);
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
}
@@ -2428,7 +2448,8 @@ bed:
IRDA_WARNING("%s: busy with a previous query\n",
__func__);
kfree(ias_opt);
- return -EBUSY;
+ err = -EBUSY;
+ goto out;
}
self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
@@ -2436,7 +2457,8 @@ bed:
if (self->iriap == NULL) {
kfree(ias_opt);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto out;
}
/* Treat unexpected wakeup as disconnect */
@@ -2455,7 +2477,8 @@ bed:
* we can free it regardless! */
kfree(ias_opt);
/* Treat signals as disconnect */
- return -EHOSTUNREACH;
+ err = -EHOSTUNREACH;
+ goto out;
}
/* Check what happened */
@@ -2465,9 +2488,11 @@ bed:
/* Requested object/attribute doesn't exist */
if((self->errno == IAS_CLASS_UNKNOWN) ||
(self->errno == IAS_ATTRIB_UNKNOWN))
- return (-EADDRNOTAVAIL);
+ err = -EADDRNOTAVAIL;
else
- return (-EHOSTUNREACH);
+ err = -EHOSTUNREACH;
+
+ goto out;
}
/* Translate from internal to user structure */
@@ -2476,14 +2501,15 @@ bed:
irias_delete_value(self->ias_result);
if (err) {
kfree(ias_opt);
- return err;
+ goto out;
}
/* Copy reply to the user */
if (copy_to_user(optval, ias_opt,
sizeof(struct irda_ias_set))) {
kfree(ias_opt);
- return -EFAULT;
+ err = -EFAULT;
+ goto out;
}
/* Note : don't need to put optlen, we checked it */
kfree(ias_opt);
@@ -2504,11 +2530,15 @@ bed:
*/
/* Check that the user is passing us an int */
- if (len != sizeof(int))
- return -EINVAL;
+ if (len != sizeof(int)) {
+ err = -EINVAL;
+ goto out;
+ }
/* Get timeout in ms (max time we block the caller) */
- if (get_user(val, (int __user *)optval))
- return -EFAULT;
+ if (get_user(val, (int __user *)optval)) {
+ err = -EFAULT;
+ goto out;
+ }
/* Tell IrLMP we want to be notified */
irlmp_update_client(self->ckey, self->mask.word,
@@ -2520,8 +2550,6 @@ bed:
/* Wait until a node is discovered */
if (!self->cachedaddr) {
- int ret = 0;
-
IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __func__);
/* Set watchdog timer to expire in <val> ms. */
@@ -2534,7 +2562,7 @@ bed:
/* Wait for IR-LMP to call us back */
__wait_event_interruptible(self->query_wait,
(self->cachedaddr != 0 || self->errno == -ETIME),
- ret);
+ err);
/* If watchdog is still activated, kill it! */
if(timer_pending(&(self->watchdog)))
@@ -2542,8 +2570,8 @@ bed:
IRDA_DEBUG(1, "%s(), ...waking up !\n", __func__);
- if (ret != 0)
- return ret;
+ if (err != 0)
+ goto out;
}
else
IRDA_DEBUG(1, "%s(), found immediately !\n",
@@ -2566,25 +2594,19 @@ bed:
* If the user want more details, he should query
* the whole discovery log and pick one device...
*/
- if (put_user(daddr, (int __user *)optval))
- return -EFAULT;
+ if (put_user(daddr, (int __user *)optval)) {
+ err = -EFAULT;
+ goto out;
+ }
break;
default:
- return -ENOPROTOOPT;
+ err = -ENOPROTOOPT;
}
- return 0;
-}
-
-static int irda_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- int err;
+out:
- lock_kernel();
- err = __irda_getsockopt(sock, level, optname, optval, optlen);
- unlock_kernel();
+ release_sock(sk);
return err;
}
@@ -2628,7 +2650,7 @@ static const struct proto_ops irda_seqpacket_ops = {
.socketpair = sock_no_socketpair,
.accept = irda_accept,
.getname = irda_getname,
- .poll = irda_datagram_poll,
+ .poll = datagram_poll,
.ioctl = irda_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = irda_compat_ioctl,
@@ -2652,7 +2674,7 @@ static const struct proto_ops irda_dgram_ops = {
.socketpair = sock_no_socketpair,
.accept = irda_accept,
.getname = irda_getname,
- .poll = irda_datagram_poll,
+ .poll = datagram_poll,
.ioctl = irda_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = irda_compat_ioctl,
@@ -2677,7 +2699,7 @@ static const struct proto_ops irda_ultra_ops = {
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.getname = irda_getname,
- .poll = irda_datagram_poll,
+ .poll = datagram_poll,
.ioctl = irda_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = irda_compat_ioctl,
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index c1c8ae939126..36c3f037f172 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -315,7 +315,7 @@ struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn,
/* Get the actual number of device in the buffer and return */
*pn = i;
- return(buffer);
+ return buffer;
}
#ifdef CONFIG_PROC_FS
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index faa82ca2dfdc..a39cca8331df 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -449,8 +449,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
}
#ifdef SERIAL_DO_RESTART
- return ((self->flags & ASYNC_HUP_NOTIFY) ?
- -EAGAIN : -ERESTARTSYS);
+ return (self->flags & ASYNC_HUP_NOTIFY) ?
+ -EAGAIN : -ERESTARTSYS;
#else
return -EAGAIN;
#endif
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index fce364c6c71a..5b743bdd89ba 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -502,7 +502,8 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self,
IRDA_DEBUG(4, "%s(), strlen=%d\n", __func__, value_len);
/* Make sure the string is null-terminated */
- fp[n+value_len] = 0x00;
+ if (n + value_len < skb->len)
+ fp[n + value_len] = 0x00;
IRDA_DEBUG(4, "Got string %s\n", fp+n);
/* Will truncate to IAS_MAX_STRING bytes */
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
index 5bb8353105cc..8ee1ff6c742f 100644
--- a/net/irda/irlan/irlan_eth.c
+++ b/net/irda/irlan/irlan_eth.c
@@ -45,13 +45,11 @@ static int irlan_eth_close(struct net_device *dev);
static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb,
struct net_device *dev);
static void irlan_eth_set_multicast_list( struct net_device *dev);
-static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev);
static const struct net_device_ops irlan_eth_netdev_ops = {
.ndo_open = irlan_eth_open,
.ndo_stop = irlan_eth_close,
.ndo_start_xmit = irlan_eth_xmit,
- .ndo_get_stats = irlan_eth_get_stats,
.ndo_set_multicast_list = irlan_eth_set_multicast_list,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
@@ -208,10 +206,10 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb,
* tried :-) DB
*/
/* irttp_data_request already free the packet */
- self->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
} else {
- self->stats.tx_packets++;
- self->stats.tx_bytes += len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += len;
}
return NETDEV_TX_OK;
@@ -226,15 +224,16 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb,
int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb)
{
struct irlan_cb *self = instance;
+ struct net_device *dev = self->dev;
if (skb == NULL) {
- ++self->stats.rx_dropped;
+ dev->stats.rx_dropped++;
return 0;
}
if (skb->len < ETH_HLEN) {
IRDA_DEBUG(0, "%s() : IrLAN frame too short (%d)\n",
__func__, skb->len);
- ++self->stats.rx_dropped;
+ dev->stats.rx_dropped++;
dev_kfree_skb(skb);
return 0;
}
@@ -244,10 +243,10 @@ int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb)
* might have been previously set by the low level IrDA network
* device driver
*/
- skb->protocol = eth_type_trans(skb, self->dev); /* Remove eth header */
+ skb->protocol = eth_type_trans(skb, dev); /* Remove eth header */
- self->stats.rx_packets++;
- self->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
netif_rx(skb); /* Eat it! */
@@ -348,16 +347,3 @@ static void irlan_eth_set_multicast_list(struct net_device *dev)
else
irlan_set_broadcast_filter(self, FALSE);
}
-
-/*
- * Function irlan_get_stats (dev)
- *
- * Get the current statistics for this device
- *
- */
-static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev)
-{
- struct irlan_cb *self = netdev_priv(dev);
-
- return &self->stats;
-}
diff --git a/net/irda/irlan/irlan_event.c b/net/irda/irlan/irlan_event.c
index cbcb4eb54037..43f16040a6fe 100644
--- a/net/irda/irlan/irlan_event.c
+++ b/net/irda/irlan/irlan_event.c
@@ -24,7 +24,7 @@
#include <net/irda/irlan_event.h>
-char *irlan_state[] = {
+const char * const irlan_state[] = {
"IRLAN_IDLE",
"IRLAN_QUERY",
"IRLAN_CONN",
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index 0e7d8bde145d..6115a44c0a24 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -939,7 +939,7 @@ struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots)
}
/* Return current cached discovery log */
- return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask, TRUE));
+ return irlmp_copy_discoveries(irlmp->cachelog, pn, mask, TRUE);
}
EXPORT_SYMBOL(irlmp_get_discoveries);
diff --git a/net/irda/irlmp_frame.c b/net/irda/irlmp_frame.c
index 3750884094da..062e63b1c5c4 100644
--- a/net/irda/irlmp_frame.c
+++ b/net/irda/irlmp_frame.c
@@ -448,7 +448,7 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
(self->cache.slsap_sel == slsap_sel) &&
(self->cache.dlsap_sel == dlsap_sel))
{
- return (self->cache.lsap);
+ return self->cache.lsap;
}
#endif
diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h
index 4300df35d37d..0d82ff5aeff1 100644
--- a/net/irda/irnet/irnet.h
+++ b/net/irda/irnet/irnet.h
@@ -458,6 +458,8 @@ typedef struct irnet_socket
int disco_index; /* Last read in the discovery log */
int disco_number; /* Size of the discovery log */
+ struct mutex lock;
+
} irnet_socket;
/*
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
index e98e40d76f4f..7f17a8020e8a 100644
--- a/net/irda/irnet/irnet_irda.c
+++ b/net/irda/irnet/irnet_irda.c
@@ -238,7 +238,7 @@ irnet_ias_to_tsap(irnet_socket * self,
DEXIT(IRDA_SR_TRACE, "\n");
/* Return the TSAP */
- return(dtsap_sel);
+ return dtsap_sel;
}
/*------------------------------------------------------------------*/
@@ -301,7 +301,7 @@ irnet_connect_tsap(irnet_socket * self)
{
clear_bit(0, &self->ttp_connect);
DERROR(IRDA_SR_ERROR, "connect aborted!\n");
- return(err);
+ return err;
}
/* Connect to remote device */
@@ -312,7 +312,7 @@ irnet_connect_tsap(irnet_socket * self)
{
clear_bit(0, &self->ttp_connect);
DERROR(IRDA_SR_ERROR, "connect aborted!\n");
- return(err);
+ return err;
}
/* The above call is non-blocking.
@@ -321,7 +321,7 @@ irnet_connect_tsap(irnet_socket * self)
* See you there ;-) */
DEXIT(IRDA_SR_TRACE, "\n");
- return(err);
+ return err;
}
/*------------------------------------------------------------------*/
@@ -362,10 +362,10 @@ irnet_discover_next_daddr(irnet_socket * self)
/* The above request is non-blocking.
* After a while, IrDA will call us back in irnet_discovervalue_confirm()
* We will then call irnet_ias_to_tsap() and come back here again... */
- return(0);
+ return 0;
}
else
- return(1);
+ return 1;
}
/*------------------------------------------------------------------*/
@@ -436,7 +436,7 @@ irnet_discover_daddr_and_lsap_sel(irnet_socket * self)
/* Follow me in irnet_discovervalue_confirm() */
DEXIT(IRDA_SR_TRACE, "\n");
- return(0);
+ return 0;
}
/*------------------------------------------------------------------*/
@@ -485,7 +485,7 @@ irnet_dname_to_daddr(irnet_socket * self)
/* No luck ! */
DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname);
kfree(discoveries);
- return(-EADDRNOTAVAIL);
+ return -EADDRNOTAVAIL;
}
@@ -527,7 +527,7 @@ irda_irnet_create(irnet_socket * self)
INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect);
DEXIT(IRDA_SOCK_TRACE, "\n");
- return(0);
+ return 0;
}
/*------------------------------------------------------------------*/
@@ -601,7 +601,7 @@ irda_irnet_connect(irnet_socket * self)
* We will finish the connection procedure in irnet_connect_tsap().
*/
DEXIT(IRDA_SOCK_TRACE, "\n");
- return(0);
+ return 0;
}
/*------------------------------------------------------------------*/
@@ -733,7 +733,7 @@ irnet_daddr_to_dname(irnet_socket * self)
/* No luck ! */
DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr);
kfree(discoveries);
- return(-EADDRNOTAVAIL);
+ return -EADDRNOTAVAIL;
}
/*------------------------------------------------------------------*/
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index dfe7b38dd4af..0993bd454ea5 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -166,7 +166,7 @@ irnet_ctrl_write(irnet_socket * ap,
}
/* Success : we have parsed all commands successfully */
- return(count);
+ return count;
}
#ifdef INITIAL_DISCOVERY
@@ -300,7 +300,7 @@ irnet_ctrl_read(irnet_socket * ap,
}
DEXIT(CTRL_TRACE, "\n");
- return(strlen(event));
+ return strlen(event);
}
#endif /* INITIAL_DISCOVERY */
@@ -409,7 +409,7 @@ irnet_ctrl_read(irnet_socket * ap,
}
DEXIT(CTRL_TRACE, "\n");
- return(strlen(event));
+ return strlen(event);
}
/*------------------------------------------------------------------*/
@@ -480,7 +480,6 @@ dev_irnet_open(struct inode * inode,
ap = kzalloc(sizeof(*ap), GFP_KERNEL);
DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n");
- lock_kernel();
/* initialize the irnet structure */
ap->file = file;
@@ -502,18 +501,20 @@ dev_irnet_open(struct inode * inode,
{
DERROR(FS_ERROR, "Can't setup IrDA link...\n");
kfree(ap);
- unlock_kernel();
+
return err;
}
/* For the control channel */
ap->event_index = irnet_events.index; /* Cancel all past events */
+ mutex_init(&ap->lock);
+
/* Put our stuff where we will be able to find it later */
file->private_data = ap;
DEXIT(FS_TRACE, " - ap=0x%p\n", ap);
- unlock_kernel();
+
return 0;
}
@@ -623,7 +624,7 @@ dev_irnet_poll(struct file * file,
mask |= irnet_ctrl_poll(ap, file, wait);
DEXIT(FS_TRACE, " - mask=0x%X\n", mask);
- return(mask);
+ return mask;
}
/*------------------------------------------------------------------*/
@@ -664,7 +665,9 @@ dev_irnet_ioctl(
{
DEBUG(FS_INFO, "Entering PPP discipline.\n");
/* PPP channel setup (ap->chan in configued in dev_irnet_open())*/
- lock_kernel();
+ if (mutex_lock_interruptible(&ap->lock))
+ return -EINTR;
+
err = ppp_register_channel(&ap->chan);
if(err == 0)
{
@@ -677,14 +680,17 @@ dev_irnet_ioctl(
}
else
DERROR(FS_ERROR, "Can't setup PPP channel...\n");
- unlock_kernel();
+
+ mutex_unlock(&ap->lock);
}
else
{
/* In theory, should be N_TTY */
DEBUG(FS_INFO, "Exiting PPP discipline.\n");
/* Disconnect from the generic PPP layer */
- lock_kernel();
+ if (mutex_lock_interruptible(&ap->lock))
+ return -EINTR;
+
if(ap->ppp_open)
{
ap->ppp_open = 0;
@@ -693,24 +699,31 @@ dev_irnet_ioctl(
else
DERROR(FS_ERROR, "Channel not registered !\n");
err = 0;
- unlock_kernel();
+
+ mutex_unlock(&ap->lock);
}
break;
/* Query PPP channel and unit number */
case PPPIOCGCHAN:
- lock_kernel();
+ if (mutex_lock_interruptible(&ap->lock))
+ return -EINTR;
+
if(ap->ppp_open && !put_user(ppp_channel_index(&ap->chan),
(int __user *)argp))
err = 0;
- unlock_kernel();
+
+ mutex_unlock(&ap->lock);
break;
case PPPIOCGUNIT:
- lock_kernel();
+ if (mutex_lock_interruptible(&ap->lock))
+ return -EINTR;
+
if(ap->ppp_open && !put_user(ppp_unit_number(&ap->chan),
(int __user *)argp))
err = 0;
- unlock_kernel();
+
+ mutex_unlock(&ap->lock);
break;
/* All these ioctls can be passed both directly and from ppp_generic,
@@ -730,9 +743,12 @@ dev_irnet_ioctl(
if(!capable(CAP_NET_ADMIN))
err = -EPERM;
else {
- lock_kernel();
+ if (mutex_lock_interruptible(&ap->lock))
+ return -EINTR;
+
err = ppp_irnet_ioctl(&ap->chan, cmd, arg);
- unlock_kernel();
+
+ mutex_unlock(&ap->lock);
}
break;
@@ -740,7 +756,9 @@ dev_irnet_ioctl(
/* Get termios */
case TCGETS:
DEBUG(FS_INFO, "Get termios.\n");
- lock_kernel();
+ if (mutex_lock_interruptible(&ap->lock))
+ return -EINTR;
+
#ifndef TCGETS2
if(!kernel_termios_to_user_termios((struct termios __user *)argp, &ap->termios))
err = 0;
@@ -748,12 +766,15 @@ dev_irnet_ioctl(
if(kernel_termios_to_user_termios_1((struct termios __user *)argp, &ap->termios))
err = 0;
#endif
- unlock_kernel();
+
+ mutex_unlock(&ap->lock);
break;
/* Set termios */
case TCSETSF:
DEBUG(FS_INFO, "Set termios.\n");
- lock_kernel();
+ if (mutex_lock_interruptible(&ap->lock))
+ return -EINTR;
+
#ifndef TCGETS2
if(!user_termios_to_kernel_termios(&ap->termios, (struct termios __user *)argp))
err = 0;
@@ -761,7 +782,8 @@ dev_irnet_ioctl(
if(!user_termios_to_kernel_termios_1(&ap->termios, (struct termios __user *)argp))
err = 0;
#endif
- unlock_kernel();
+
+ mutex_unlock(&ap->lock);
break;
/* Set DTR/RTS */
@@ -784,9 +806,10 @@ dev_irnet_ioctl(
* We should also worry that we don't accept junk here and that
* we get rid of our own buffers */
#ifdef FLUSH_TO_PPP
- lock_kernel();
+ if (mutex_lock_interruptible(&ap->lock))
+ return -EINTR;
ppp_output_wakeup(&ap->chan);
- unlock_kernel();
+ mutex_unlock(&ap->lock);
#endif /* FLUSH_TO_PPP */
err = 0;
break;
diff --git a/net/irda/irnet/irnet_ppp.h b/net/irda/irnet/irnet_ppp.h
index b5df2418f90c..940225866da0 100644
--- a/net/irda/irnet/irnet_ppp.h
+++ b/net/irda/irnet/irnet_ppp.h
@@ -103,7 +103,8 @@ static const struct file_operations irnet_device_fops =
.poll = dev_irnet_poll,
.unlocked_ioctl = dev_irnet_ioctl,
.open = dev_irnet_open,
- .release = dev_irnet_close
+ .release = dev_irnet_close,
+ .llseek = noop_llseek,
/* Also : llseek, readdir, mmap, flush, fsync, fasync, lock, readv, writev */
};
diff --git a/net/irda/parameters.c b/net/irda/parameters.c
index fc1a20565e2d..71cd38c1a67f 100644
--- a/net/irda/parameters.c
+++ b/net/irda/parameters.c
@@ -298,6 +298,8 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi,
p.pi = pi; /* In case handler needs to know */
p.pl = buf[1]; /* Extract length of value */
+ if (p.pl > 32)
+ p.pl = 32;
IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __func__,
p.pi, p.pl);
@@ -318,7 +320,7 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi,
(__u8) str[0], (__u8) str[1]);
/* Null terminate string */
- str[p.pl+1] = '\0';
+ str[p.pl] = '\0';
p.pv.c = str; /* Handler will need to take a copy */
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 43040e97c474..d87c22df6f1e 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -565,12 +565,12 @@ pfkey_proto2satype(uint16_t proto)
static uint8_t pfkey_proto_to_xfrm(uint8_t proto)
{
- return (proto == IPSEC_PROTO_ANY ? 0 : proto);
+ return proto == IPSEC_PROTO_ANY ? 0 : proto;
}
static uint8_t pfkey_proto_from_xfrm(uint8_t proto)
{
- return (proto ? proto : IPSEC_PROTO_ANY);
+ return proto ? proto : IPSEC_PROTO_ANY;
}
static inline int pfkey_sockaddr_len(sa_family_t family)
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index 1ae697681bc7..8d9ce0accc98 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -144,7 +144,6 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb,
nf_reset(skb);
if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) {
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes += data_len;
} else
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 226a0ae3bcfd..1c770c0644d1 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -65,9 +65,7 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif
continue;
if ((l2tp->conn_id == tunnel_id) &&
-#ifdef CONFIG_NET_NS
- (sk->sk_net == net) &&
-#endif
+ net_eq(sock_net(sk), net) &&
!(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
!(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
goto found;
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index ff954b3e94b6..39a21d0c61c4 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -1768,7 +1768,7 @@ static const struct proto_ops pppol2tp_ops = {
.ioctl = pppox_ioctl,
};
-static struct pppox_proto pppol2tp_proto = {
+static const struct pppox_proto pppol2tp_proto = {
.create = pppol2tp_create,
.ioctl = pppol2tp_ioctl
};
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index a87cb3ba2df6..d2b03e0851ef 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -138,10 +138,8 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
struct crypto_cipher *tfm;
tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(tfm))
- return NULL;
-
- crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN);
+ if (!IS_ERR(tfm))
+ crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN);
return tfm;
}
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index 3d097b3d7b62..b4d66cca76d6 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -119,10 +119,8 @@ struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[])
struct crypto_cipher *tfm;
tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(tfm))
- return NULL;
-
- crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN);
+ if (!IS_ERR(tfm))
+ crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN);
return tfm;
}
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 965b272499fd..720b7a84af59 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -56,7 +56,7 @@ static void ieee80211_free_tid_rx(struct rcu_head *h)
}
void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
- u16 initiator, u16 reason)
+ u16 initiator, u16 reason, bool tx)
{
struct ieee80211_local *local = sta->local;
struct tid_ampdu_rx *tid_rx;
@@ -81,20 +81,21 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
"aggregation for tid %d\n", tid);
/* check if this is a self generated aggregation halt */
- if (initiator == WLAN_BACK_RECIPIENT)
+ if (initiator == WLAN_BACK_RECIPIENT && tx)
ieee80211_send_delba(sta->sdata, sta->sta.addr,
tid, 0, reason);
del_timer_sync(&tid_rx->session_timer);
+ del_timer_sync(&tid_rx->reorder_timer);
call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx);
}
void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
- u16 initiator, u16 reason)
+ u16 initiator, u16 reason, bool tx)
{
mutex_lock(&sta->ampdu_mlme.mtx);
- ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason);
+ ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, tx);
mutex_unlock(&sta->ampdu_mlme.mtx);
}
@@ -120,6 +121,20 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
}
+static void sta_rx_agg_reorder_timer_expired(unsigned long data)
+{
+ u8 *ptid = (u8 *)data;
+ u8 *timer_to_id = ptid - *ptid;
+ struct sta_info *sta = container_of(timer_to_id, struct sta_info,
+ timer_to_tid[0]);
+
+ rcu_read_lock();
+ spin_lock(&sta->lock);
+ ieee80211_release_reorder_timeout(sta, *ptid);
+ spin_unlock(&sta->lock);
+ rcu_read_unlock();
+}
+
static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
u8 dialog_token, u16 status, u16 policy,
u16 buf_size, u16 timeout)
@@ -251,11 +266,18 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
goto end;
}
+ spin_lock_init(&tid_agg_rx->reorder_lock);
+
/* rx timer */
tid_agg_rx->session_timer.function = sta_rx_agg_session_timer_expired;
tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];
init_timer(&tid_agg_rx->session_timer);
+ /* rx reorder timer */
+ tid_agg_rx->reorder_timer.function = sta_rx_agg_reorder_timer_expired;
+ tid_agg_rx->reorder_timer.data = (unsigned long)&sta->timer_to_tid[tid];
+ init_timer(&tid_agg_rx->reorder_timer);
+
/* prepare reordering buffer */
tid_agg_rx->reorder_buf =
kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC);
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 8f23401832b7..d4679b265ba8 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -145,7 +145,8 @@ static void kfree_tid_tx(struct rcu_head *rcu_head)
}
int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
- enum ieee80211_back_parties initiator)
+ 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];
@@ -185,6 +186,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
tid_tx->stop_initiator = initiator;
+ tid_tx->tx_stop = tx;
ret = drv_ampdu_action(local, sta->sdata,
IEEE80211_AMPDU_TX_STOP,
@@ -577,13 +579,14 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
- enum ieee80211_back_parties initiator)
+ enum ieee80211_back_parties initiator,
+ bool tx)
{
int ret;
mutex_lock(&sta->ampdu_mlme.mtx);
- ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
+ ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator, tx);
mutex_unlock(&sta->ampdu_mlme.mtx);
@@ -672,7 +675,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
goto unlock_sta;
}
- if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR)
+ if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop)
ieee80211_send_delba(sta->sdata, ra, tid,
WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
@@ -772,7 +775,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
sta->ampdu_mlme.addba_req_num[tid] = 0;
} else {
- ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
+ ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR,
+ true);
}
out:
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 29ac8e1a509e..18bd0e550600 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -19,33 +19,6 @@
#include "rate.h"
#include "mesh.h"
-static bool nl80211_type_check(enum nl80211_iftype type)
-{
- switch (type) {
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_MONITOR:
-#ifdef CONFIG_MAC80211_MESH
- case NL80211_IFTYPE_MESH_POINT:
-#endif
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_AP_VLAN:
- case NL80211_IFTYPE_WDS:
- return true;
- default:
- return false;
- }
-}
-
-static bool nl80211_params_check(enum nl80211_iftype type,
- struct vif_params *params)
-{
- if (!nl80211_type_check(type))
- return false;
-
- return true;
-}
-
static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
enum nl80211_iftype type, u32 *flags,
struct vif_params *params)
@@ -55,9 +28,6 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
struct ieee80211_sub_if_data *sdata;
int err;
- if (!nl80211_params_check(type, params))
- return -EINVAL;
-
err = ieee80211_if_add(local, name, &dev, type, params);
if (err || type != NL80211_IFTYPE_MONITOR || !flags)
return err;
@@ -82,12 +52,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
int ret;
- if (ieee80211_sdata_running(sdata))
- return -EBUSY;
-
- if (!nl80211_params_check(type, params))
- return -EINVAL;
-
ret = ieee80211_if_change_type(sdata, type);
if (ret)
return ret;
@@ -104,54 +68,71 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
params && params->use_4addr >= 0)
sdata->u.mgd.use_4addr = params->use_4addr;
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags)
- sdata->u.mntr_flags = *flags;
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
+ struct ieee80211_local *local = sdata->local;
+
+ if (ieee80211_sdata_running(sdata)) {
+ /*
+ * Prohibit MONITOR_FLAG_COOK_FRAMES to be
+ * changed while the interface is up.
+ * Else we would need to add a lot of cruft
+ * to update everything:
+ * cooked_mntrs, monitor and all fif_* counters
+ * reconfigure hardware
+ */
+ if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
+ (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
+ return -EBUSY;
+
+ ieee80211_adjust_monitor_flags(sdata, -1);
+ sdata->u.mntr_flags = *flags;
+ ieee80211_adjust_monitor_flags(sdata, 1);
+
+ ieee80211_configure_filter(local);
+ } else {
+ /*
+ * Because the interface is down, ieee80211_do_stop
+ * and ieee80211_do_open take care of "everything"
+ * mentioned in the comment above.
+ */
+ sdata->u.mntr_flags = *flags;
+ }
+ }
return 0;
}
static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
- u8 key_idx, const u8 *mac_addr,
+ u8 key_idx, bool pairwise, const u8 *mac_addr,
struct key_params *params)
{
- struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct sta_info *sta = NULL;
- enum ieee80211_key_alg alg;
struct ieee80211_key *key;
int err;
- if (!netif_running(dev))
+ if (!ieee80211_sdata_running(sdata))
return -ENETDOWN;
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
+ /* reject WEP and TKIP keys if WEP failed to initialize */
switch (params->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- alg = ALG_WEP;
- break;
case WLAN_CIPHER_SUITE_TKIP:
- alg = ALG_TKIP;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- alg = ALG_CCMP;
- break;
- case WLAN_CIPHER_SUITE_AES_CMAC:
- alg = ALG_AES_CMAC;
+ case WLAN_CIPHER_SUITE_WEP104:
+ if (IS_ERR(sdata->local->wep_tx_tfm))
+ return -EINVAL;
break;
default:
- return -EINVAL;
+ break;
}
- /* reject WEP and TKIP keys if WEP failed to initialize */
- if ((alg == ALG_WEP || alg == ALG_TKIP) &&
- IS_ERR(sdata->local->wep_tx_tfm))
- return -EINVAL;
+ key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len,
+ params->key, params->seq_len, params->seq);
+ if (IS_ERR(key))
+ return PTR_ERR(key);
- key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
- params->seq_len, params->seq);
- if (!key)
- return -ENOMEM;
+ if (pairwise)
+ key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
mutex_lock(&sdata->local->sta_mtx);
@@ -164,9 +145,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
}
}
- ieee80211_key_link(key, sdata, sta);
+ err = ieee80211_key_link(key, sdata, sta);
+ if (err)
+ ieee80211_key_free(sdata->local, key);
- err = 0;
out_unlock:
mutex_unlock(&sdata->local->sta_mtx);
@@ -174,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
}
static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
- u8 key_idx, const u8 *mac_addr)
+ u8 key_idx, bool pairwise, const u8 *mac_addr)
{
struct ieee80211_sub_if_data *sdata;
struct sta_info *sta;
@@ -191,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
if (!sta)
goto out_unlock;
- if (sta->key) {
- ieee80211_key_free(sdata->local, sta->key);
- WARN_ON(sta->key);
- ret = 0;
+ 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;
@@ -216,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
}
static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
- u8 key_idx, const u8 *mac_addr, void *cookie,
+ u8 key_idx, bool pairwise, const u8 *mac_addr,
+ void *cookie,
void (*callback)(void *cookie,
struct key_params *params))
{
@@ -224,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
struct sta_info *sta = NULL;
u8 seq[6] = {0};
struct key_params params;
- struct ieee80211_key *key;
+ struct ieee80211_key *key = NULL;
u32 iv32;
u16 iv16;
int err = -ENOENT;
@@ -238,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
if (!sta)
goto out;
- key = sta->key;
+ if (pairwise)
+ key = sta->ptk;
+ else if (key_idx < NUM_DEFAULT_KEYS)
+ key = sta->gtk[key_idx];
} else
key = sdata->keys[key_idx];
@@ -247,10 +240,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
memset(&params, 0, sizeof(params));
- switch (key->conf.alg) {
- case ALG_TKIP:
- params.cipher = WLAN_CIPHER_SUITE_TKIP;
+ params.cipher = key->conf.cipher;
+ switch (key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
iv32 = key->u.tkip.tx.iv32;
iv16 = key->u.tkip.tx.iv16;
@@ -268,8 +261,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
params.seq = seq;
params.seq_len = 6;
break;
- case ALG_CCMP:
- params.cipher = WLAN_CIPHER_SUITE_CCMP;
+ case WLAN_CIPHER_SUITE_CCMP:
seq[0] = key->u.ccmp.tx_pn[5];
seq[1] = key->u.ccmp.tx_pn[4];
seq[2] = key->u.ccmp.tx_pn[3];
@@ -279,14 +271,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
params.seq = seq;
params.seq_len = 6;
break;
- case ALG_WEP:
- if (key->conf.keylen == 5)
- params.cipher = WLAN_CIPHER_SUITE_WEP40;
- else
- params.cipher = WLAN_CIPHER_SUITE_WEP104;
- break;
- case ALG_AES_CMAC:
- params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
seq[0] = key->u.aes_cmac.tx_pn[5];
seq[1] = key->u.aes_cmac.tx_pn[4];
seq[2] = key->u.aes_cmac.tx_pn[3];
@@ -342,13 +327,19 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
STATION_INFO_TX_BYTES |
STATION_INFO_RX_PACKETS |
STATION_INFO_TX_PACKETS |
- STATION_INFO_TX_BITRATE;
+ STATION_INFO_TX_RETRIES |
+ STATION_INFO_TX_FAILED |
+ STATION_INFO_TX_BITRATE |
+ STATION_INFO_RX_DROP_MISC;
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
sinfo->rx_bytes = sta->rx_bytes;
sinfo->tx_bytes = sta->tx_bytes;
sinfo->rx_packets = sta->rx_packets;
sinfo->tx_packets = sta->tx_packets;
+ sinfo->tx_retries = sta->tx_retry_count;
+ sinfo->tx_failed = sta->tx_retry_failed;
+ sinfo->rx_dropped_misc = sta->rx_dropped;
if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
(sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
@@ -634,6 +625,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
struct sta_info *sta,
struct station_parameters *params)
{
+ unsigned long flags;
u32 rates;
int i, j;
struct ieee80211_supported_band *sband;
@@ -642,7 +634,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
sband = local->hw.wiphy->bands[local->oper_channel->band];
- spin_lock_bh(&sta->lock);
+ spin_lock_irqsave(&sta->flaglock, flags);
mask = params->sta_flags_mask;
set = params->sta_flags_set;
@@ -669,7 +661,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
if (set & BIT(NL80211_STA_FLAG_MFP))
sta->flags |= WLAN_STA_MFP;
}
- spin_unlock_bh(&sta->lock);
+ spin_unlock_irqrestore(&sta->flaglock, flags);
/*
* cfg80211 validates this (1-2007) and allows setting the AID
@@ -1143,9 +1135,9 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
p.uapsd = false;
if (drv_conf_tx(local, params->queue, &p)) {
- printk(KERN_DEBUG "%s: failed to set TX queue "
- "parameters for queue %d\n",
- wiphy_name(local->hw.wiphy), params->queue);
+ wiphy_debug(local->hw.wiphy,
+ "failed to set TX queue parameters for queue %d\n",
+ params->queue);
return -EINVAL;
}
@@ -1207,15 +1199,26 @@ static int ieee80211_scan(struct wiphy *wiphy,
struct net_device *dev,
struct cfg80211_scan_request *req)
{
- struct ieee80211_sub_if_data *sdata;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->vif.type != NL80211_IFTYPE_STATION &&
- sdata->vif.type != NL80211_IFTYPE_ADHOC &&
- sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
- (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon))
+ switch (ieee80211_vif_type_p2p(&sdata->vif)) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ break;
+ case NL80211_IFTYPE_P2P_GO:
+ if (sdata->local->ops->hw_scan)
+ break;
+ /* FIXME: implement NoA while scanning in software */
+ return -EOPNOTSUPP;
+ case NL80211_IFTYPE_AP:
+ if (sdata->u.ap.beacon)
+ return -EOPNOTSUPP;
+ break;
+ default:
return -EOPNOTSUPP;
+ }
return ieee80211_request_scan(sdata, req);
}
@@ -1362,7 +1365,7 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
}
static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
- u8 *addr)
+ const u8 *addr)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1411,7 +1414,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
if (!sdata->u.mgd.associated ||
sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
mutex_lock(&sdata->local->iflist_mtx);
- ieee80211_recalc_smps(sdata->local, sdata);
+ ieee80211_recalc_smps(sdata->local);
mutex_unlock(&sdata->local->iflist_mtx);
return 0;
}
@@ -1541,11 +1544,11 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
return ieee80211_wk_cancel_remain_on_channel(sdata, cookie);
}
-static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type,
- bool channel_type_valid,
- const u8 *buf, size_t len, u64 *cookie)
+static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type,
+ bool channel_type_valid,
+ const u8 *buf, size_t len, u64 *cookie)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
@@ -1566,7 +1569,11 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
switch (sdata->vif.type) {
case NL80211_IFTYPE_ADHOC:
- if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_P2P_GO:
+ if (!ieee80211_is_action(mgmt->frame_control) ||
+ mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
break;
rcu_read_lock();
sta = sta_info_get(sdata, mgmt->da);
@@ -1575,8 +1582,7 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
return -ENOLINK;
break;
case NL80211_IFTYPE_STATION:
- if (!(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
- flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+ case NL80211_IFTYPE_P2P_CLIENT:
break;
default:
return -EOPNOTSUPP;
@@ -1598,6 +1604,23 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
+static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
+ struct net_device *dev,
+ u16 frame_type, bool reg)
+{
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+
+ if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
+ return;
+
+ if (reg)
+ local->probe_req_reg++;
+ else
+ local->probe_req_reg--;
+
+ ieee80211_queue_work(&local->hw, &local->reconfig_filter);
+}
+
struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -1647,6 +1670,7 @@ struct cfg80211_ops mac80211_config_ops = {
.set_bitrate_mask = ieee80211_set_bitrate_mask,
.remain_on_channel = ieee80211_remain_on_channel,
.cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
- .action = ieee80211_action,
+ .mgmt_tx = ieee80211_mgmt_tx,
.set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
+ .mgmt_frame_register = ieee80211_mgmt_frame_register,
};
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 32be11e4c4d9..5b24740fc0b0 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -11,7 +11,7 @@ __ieee80211_get_channel_mode(struct ieee80211_local *local,
{
struct ieee80211_sub_if_data *sdata;
- WARN_ON(!mutex_is_locked(&local->iflist_mtx));
+ lockdep_assert_held(&local->iflist_mtx);
list_for_each_entry(sdata, &local->interfaces, list) {
if (sdata == ignore)
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index b8b0ae79a743..18260aa99c56 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -86,13 +86,15 @@ static ssize_t tsf_write(struct file *file,
if (strncmp(buf, "reset", 5) == 0) {
if (local->ops->reset_tsf) {
drv_reset_tsf(local);
- printk(KERN_INFO "%s: debugfs reset TSF\n", wiphy_name(local->hw.wiphy));
+ wiphy_info(local->hw.wiphy, "debugfs reset TSF\n");
}
} else {
tsf = simple_strtoul(buf, NULL, 0);
if (local->ops->set_tsf) {
drv_set_tsf(local, tsf);
- printk(KERN_INFO "%s: debugfs set TSF to %#018llx\n", wiphy_name(local->hw.wiphy), tsf);
+ wiphy_info(local->hw.wiphy,
+ "debugfs set TSF to %#018llx\n", tsf);
+
}
}
@@ -375,7 +377,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
if (!phyd)
return;
- local->debugfs.stations = debugfs_create_dir("stations", phyd);
local->debugfs.keys = debugfs_create_dir("keys", phyd);
DEBUGFS_ADD(frequency);
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 7cd8dd9fc240..4aa47d074a79 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -66,26 +66,13 @@ static ssize_t key_algorithm_read(struct file *file,
char __user *userbuf,
size_t count, loff_t *ppos)
{
- char *alg;
+ char buf[15];
struct ieee80211_key *key = file->private_data;
+ u32 c = key->conf.cipher;
- switch (key->conf.alg) {
- case ALG_WEP:
- alg = "WEP\n";
- break;
- case ALG_TKIP:
- alg = "TKIP\n";
- break;
- case ALG_CCMP:
- alg = "CCMP\n";
- break;
- case ALG_AES_CMAC:
- alg = "AES-128-CMAC\n";
- break;
- default:
- return 0;
- }
- return simple_read_from_buffer(userbuf, count, ppos, alg, strlen(alg));
+ sprintf(buf, "%.2x-%.2x-%.2x:%d\n",
+ c >> 24, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff);
+ return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
}
KEY_OPS(algorithm);
@@ -97,21 +84,22 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
int len;
struct ieee80211_key *key = file->private_data;
- switch (key->conf.alg) {
- case ALG_WEP:
+ switch (key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
len = scnprintf(buf, sizeof(buf), "\n");
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
len = scnprintf(buf, sizeof(buf), "%08x %04x\n",
key->u.tkip.tx.iv32,
key->u.tkip.tx.iv16);
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
tpn = key->u.ccmp.tx_pn;
len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
break;
- case ALG_AES_CMAC:
+ case WLAN_CIPHER_SUITE_AES_CMAC:
tpn = key->u.aes_cmac.tx_pn;
len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
tpn[0], tpn[1], tpn[2], tpn[3], tpn[4],
@@ -132,11 +120,12 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
int i, len;
const u8 *rpn;
- switch (key->conf.alg) {
- case ALG_WEP:
+ switch (key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
len = scnprintf(buf, sizeof(buf), "\n");
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
p += scnprintf(p, sizeof(buf)+buf-p,
"%08x %04x\n",
@@ -144,7 +133,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
key->u.tkip.rx[i].iv16);
len = p - buf;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) {
rpn = key->u.ccmp.rx_pn[i];
p += scnprintf(p, sizeof(buf)+buf-p,
@@ -154,7 +143,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
}
len = p - buf;
break;
- case ALG_AES_CMAC:
+ case WLAN_CIPHER_SUITE_AES_CMAC:
rpn = key->u.aes_cmac.rx_pn;
p += scnprintf(p, sizeof(buf)+buf-p,
"%02x%02x%02x%02x%02x%02x\n",
@@ -176,11 +165,11 @@ static ssize_t key_replays_read(struct file *file, char __user *userbuf,
char buf[20];
int len;
- switch (key->conf.alg) {
- case ALG_CCMP:
+ switch (key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
break;
- case ALG_AES_CMAC:
+ case WLAN_CIPHER_SUITE_AES_CMAC:
len = scnprintf(buf, sizeof(buf), "%u\n",
key->u.aes_cmac.replays);
break;
@@ -198,8 +187,8 @@ static ssize_t key_icverrors_read(struct file *file, char __user *userbuf,
char buf[20];
int len;
- switch (key->conf.alg) {
- case ALG_AES_CMAC:
+ switch (key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_AES_CMAC:
len = scnprintf(buf, sizeof(buf), "%u\n",
key->u.aes_cmac.icverrors);
break;
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 8ad33eef7dda..cbdf36d7841c 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -410,6 +410,9 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
sprintf(buf, "netdev:%s", sdata->name);
sdata->debugfs.dir = debugfs_create_dir(buf,
sdata->local->hw.wiphy->debugfsdir);
+ if (sdata->debugfs.dir)
+ sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
+ sdata->debugfs.dir);
add_files(sdata);
}
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 6a8fdc372c43..4601fea1784d 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -198,7 +198,8 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu
else
ret = ieee80211_stop_tx_ba_session(&sta->sta, tid);
} else {
- __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3);
+ __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
+ 3, true);
ret = 0;
}
@@ -302,7 +303,7 @@ STA_OPS(ht_capa);
void ieee80211_sta_debugfs_add(struct sta_info *sta)
{
- struct dentry *stations_dir = sta->local->debugfs.stations;
+ struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations;
u8 mac[3*ETH_ALEN];
sta->debugfs.add_has_run = true;
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 14123dce544b..16983825f8e8 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -54,6 +54,20 @@ static inline int drv_add_interface(struct ieee80211_local *local,
return ret;
}
+static inline int drv_change_interface(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ enum nl80211_iftype type, bool p2p)
+{
+ int ret;
+
+ might_sleep();
+
+ trace_drv_change_interface(local, sdata, type, p2p);
+ ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p);
+ trace_drv_return_int(local, ret);
+ return ret;
+}
+
static inline void drv_remove_interface(struct ieee80211_local *local,
struct ieee80211_vif *vif)
{
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 5d5d2a974668..6831fb1641c8 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -25,12 +25,14 @@ static inline void trace_ ## name(proto) {}
#define STA_PR_FMT " sta:%pM"
#define STA_PR_ARG __entry->sta_addr
-#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \
+#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \
+ __field(bool, p2p) \
__string(vif_name, sdata->dev ? sdata->dev->name : "<nodev>")
-#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \
+#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \
+ __entry->p2p = sdata->vif.p2p; \
__assign_str(vif_name, sdata->dev ? sdata->dev->name : "<nodev>")
-#define VIF_PR_FMT " vif:%s(%d)"
-#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type
+#define VIF_PR_FMT " vif:%s(%d%s)"
+#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
/*
* Tracing for driver callbacks.
@@ -136,6 +138,34 @@ TRACE_EVENT(drv_add_interface,
)
);
+TRACE_EVENT(drv_change_interface,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ enum nl80211_iftype type, bool p2p),
+
+ TP_ARGS(local, sdata, type, p2p),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ VIF_ENTRY
+ __field(u32, new_type)
+ __field(bool, new_p2p)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ __entry->new_type = type;
+ __entry->new_p2p = p2p;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT VIF_PR_FMT " new type:%d%s",
+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->new_type,
+ __entry->new_p2p ? "/p2p" : ""
+ )
+);
+
TRACE_EVENT(drv_remove_interface,
TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata),
@@ -336,7 +366,7 @@ TRACE_EVENT(drv_set_key,
LOCAL_ENTRY
VIF_ENTRY
STA_ENTRY
- __field(enum ieee80211_key_alg, alg)
+ __field(u32, cipher)
__field(u8, hw_key_idx)
__field(u8, flags)
__field(s8, keyidx)
@@ -346,7 +376,7 @@ TRACE_EVENT(drv_set_key,
LOCAL_ASSIGN;
VIF_ASSIGN;
STA_ASSIGN;
- __entry->alg = key->alg;
+ __entry->cipher = key->cipher;
__entry->flags = key->flags;
__entry->keyidx = key->keyidx;
__entry->hw_key_idx = key->hw_key_idx;
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 9d101fb33861..75d679d75e63 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -101,16 +101,16 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
ht_cap->mcs.rx_mask[32/8] |= 1;
}
-void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta)
+void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx)
{
int i;
cancel_work_sync(&sta->ampdu_mlme.work);
for (i = 0; i < STA_TID_NUM; i++) {
- __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR);
+ __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx);
__ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
- WLAN_REASON_QSTA_LEAVE_QBSS);
+ WLAN_REASON_QSTA_LEAVE_QBSS, tx);
}
}
@@ -135,7 +135,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired))
___ieee80211_stop_rx_ba_session(
sta, tid, WLAN_BACK_RECIPIENT,
- WLAN_REASON_QSTA_TIMEOUT);
+ WLAN_REASON_QSTA_TIMEOUT, true);
tid_tx = sta->ampdu_mlme.tid_tx[tid];
if (!tid_tx)
@@ -146,7 +146,8 @@ void ieee80211_ba_session_work(struct work_struct *work)
else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
&tid_tx->state))
___ieee80211_stop_tx_ba_session(sta, tid,
- WLAN_BACK_INITIATOR);
+ WLAN_BACK_INITIATOR,
+ true);
}
mutex_unlock(&sta->ampdu_mlme.mtx);
}
@@ -214,9 +215,11 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
#endif /* CONFIG_MAC80211_HT_DEBUG */
if (initiator == WLAN_BACK_INITIATOR)
- __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0);
+ __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0,
+ true);
else
- __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT);
+ __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
+ true);
}
int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
@@ -265,3 +268,33 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
return 0;
}
+
+void ieee80211_request_smps_work(struct work_struct *work)
+{
+ struct ieee80211_sub_if_data *sdata =
+ container_of(work, struct ieee80211_sub_if_data,
+ u.mgd.request_smps_work);
+
+ mutex_lock(&sdata->u.mgd.mtx);
+ __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode);
+ mutex_unlock(&sdata->u.mgd.mtx);
+}
+
+void ieee80211_request_smps(struct ieee80211_vif *vif,
+ enum ieee80211_smps_mode smps_mode)
+{
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+
+ if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
+ return;
+
+ if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
+ smps_mode = IEEE80211_SMPS_AUTOMATIC;
+
+ sdata->u.mgd.driver_smps_mode = smps_mode;
+
+ ieee80211_queue_work(&sdata->local->hw,
+ &sdata->u.mgd.request_smps_work);
+}
+/* this might change ... don't want non-open drivers using it */
+EXPORT_SYMBOL_GPL(ieee80211_request_smps);
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index c691780725a7..ff60c022f51d 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -173,6 +173,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
memcpy(skb_put(skb, ifibss->ie_len),
ifibss->ie, ifibss->ie_len);
+ if (local->hw.queues >= 4) {
+ pos = skb_put(skb, 9);
+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
+ *pos++ = 7; /* len */
+ *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
+ *pos++ = 0x50;
+ *pos++ = 0xf2;
+ *pos++ = 2; /* WME */
+ *pos++ = 0; /* WME info */
+ *pos++ = 1; /* WME ver */
+ *pos++ = 0; /* U-APSD no in use */
+ }
+
rcu_assign_pointer(ifibss->presp, skb);
sdata->vif.bss_conf.beacon_int = beacon_int;
@@ -266,37 +279,45 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
return;
- if (sdata->vif.type == NL80211_IFTYPE_ADHOC && elems->supp_rates &&
+ if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) {
- supp_rates = ieee80211_sta_get_rates(local, elems, band);
rcu_read_lock();
-
sta = sta_info_get(sdata, mgmt->sa);
- if (sta) {
- u32 prev_rates;
- prev_rates = sta->sta.supp_rates[band];
- /* make sure mandatory rates are always added */
- sta->sta.supp_rates[band] = supp_rates |
- ieee80211_mandatory_rates(local, band);
+ if (elems->supp_rates) {
+ supp_rates = ieee80211_sta_get_rates(local, elems,
+ band);
+ if (sta) {
+ u32 prev_rates;
+
+ prev_rates = sta->sta.supp_rates[band];
+ /* make sure mandatory rates are always added */
+ sta->sta.supp_rates[band] = supp_rates |
+ ieee80211_mandatory_rates(local, band);
- if (sta->sta.supp_rates[band] != prev_rates) {
+ if (sta->sta.supp_rates[band] != prev_rates) {
#ifdef CONFIG_MAC80211_IBSS_DEBUG
- printk(KERN_DEBUG "%s: updated supp_rates set "
- "for %pM based on beacon/probe_response "
- "(0x%x -> 0x%x)\n",
- sdata->name, sta->sta.addr,
- prev_rates, sta->sta.supp_rates[band]);
+ printk(KERN_DEBUG
+ "%s: updated supp_rates set "
+ "for %pM based on beacon"
+ "/probe_resp (0x%x -> 0x%x)\n",
+ sdata->name, sta->sta.addr,
+ prev_rates,
+ sta->sta.supp_rates[band]);
#endif
- rate_control_rate_init(sta);
- }
- rcu_read_unlock();
- } else {
- rcu_read_unlock();
- ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
- supp_rates, GFP_KERNEL);
+ rate_control_rate_init(sta);
+ }
+ } else
+ sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
+ mgmt->sa, supp_rates,
+ GFP_ATOMIC);
}
+
+ if (sta && elems->wmm_info)
+ set_sta_flags(sta, WLAN_STA_WME);
+
+ rcu_read_unlock();
}
bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
@@ -427,8 +448,8 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
return NULL;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n",
- wiphy_name(local->hw.wiphy), addr, sdata->name);
+ wiphy_debug(local->hw.wiphy, "Adding new IBSS station %pM (dev=%s)\n",
+ addr, sdata->name);
#endif
sta = sta_info_alloc(sdata, addr, gfp);
@@ -920,12 +941,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
sdata->u.ibss.ssid_len = params->ssid_len;
+ mutex_unlock(&sdata->u.ibss.mtx);
+
+ mutex_lock(&sdata->local->mtx);
ieee80211_recalc_idle(sdata->local);
+ mutex_unlock(&sdata->local->mtx);
ieee80211_queue_work(&sdata->local->hw, &sdata->work);
- mutex_unlock(&sdata->u.ibss.mtx);
-
return 0;
}
@@ -980,7 +1003,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
mutex_unlock(&sdata->u.ibss.mtx);
+ mutex_lock(&local->mtx);
ieee80211_recalc_idle(sdata->local);
+ mutex_unlock(&local->mtx);
return 0;
}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 65e0ed6c2975..b80c38689927 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -50,12 +50,6 @@ struct ieee80211_local;
* increased memory use (about 2 kB of RAM per entry). */
#define IEEE80211_FRAGMENT_MAX 4
-/*
- * Time after which we ignore scan results and no longer report/use
- * them in any way.
- */
-#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ)
-
#define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024))
#define IEEE80211_DEFAULT_UAPSD_QUEUES \
@@ -165,12 +159,37 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
#define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u)
#define RX_QUEUED ((__force ieee80211_rx_result) 3u)
-#define IEEE80211_RX_IN_SCAN BIT(0)
-/* frame is destined to interface currently processed (incl. multicast frames) */
-#define IEEE80211_RX_RA_MATCH BIT(1)
-#define IEEE80211_RX_AMSDU BIT(2)
-#define IEEE80211_RX_FRAGMENTED BIT(3)
-/* only add flags here that do not change with subframes of an aMPDU */
+/**
+ * enum ieee80211_packet_rx_flags - packet RX flags
+ * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed
+ * (incl. multicast frames)
+ * @IEEE80211_RX_IN_SCAN: received while scanning
+ * @IEEE80211_RX_FRAGMENTED: fragmented frame
+ * @IEEE80211_RX_AMSDU: a-MSDU packet
+ * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed
+ *
+ * These are per-frame flags that are attached to a frame in the
+ * @rx_flags field of &struct ieee80211_rx_status.
+ */
+enum ieee80211_packet_rx_flags {
+ IEEE80211_RX_IN_SCAN = BIT(0),
+ IEEE80211_RX_RA_MATCH = BIT(1),
+ IEEE80211_RX_FRAGMENTED = BIT(2),
+ IEEE80211_RX_AMSDU = BIT(3),
+ IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4),
+};
+
+/**
+ * enum ieee80211_rx_flags - RX data flags
+ *
+ * @IEEE80211_RX_CMNTR: received on cooked monitor already
+ *
+ * These flags are used across handling multiple interfaces
+ * for a single frame.
+ */
+enum ieee80211_rx_flags {
+ IEEE80211_RX_CMNTR = BIT(0),
+};
struct ieee80211_rx_data {
struct sk_buff *skb;
@@ -343,10 +362,14 @@ struct ieee80211_if_managed {
unsigned long timers_running; /* used for quiesce/restart */
bool powersave; /* powersave requested for this iface */
enum ieee80211_smps_mode req_smps, /* requested smps mode */
- ap_smps; /* smps mode AP thinks we're in */
+ ap_smps, /* smps mode AP thinks we're in */
+ driver_smps_mode; /* smps mode request */
+
+ struct work_struct request_smps_work;
unsigned int flags;
+ bool beacon_crc_valid;
u32 beacon_crc;
enum {
@@ -371,6 +394,13 @@ struct ieee80211_if_managed {
int ave_beacon_signal;
/*
+ * Number of Beacon frames used in ave_beacon_signal. This can be used
+ * to avoid generating less reliable cqm events that would be based
+ * only on couple of received frames.
+ */
+ unsigned int count_beacon_signal;
+
+ /*
* Last Beacon frame signal strength average (ave_beacon_signal / 16)
* that triggered a cqm event. 0 indicates that no event has been
* generated for the current association.
@@ -474,6 +504,19 @@ enum ieee80211_sub_if_data_flags {
IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3),
};
+/**
+ * enum ieee80211_sdata_state_bits - virtual interface state bits
+ * @SDATA_STATE_RUNNING: virtual interface is up & running; this
+ * mirrors netif_running() but is separate for interface type
+ * change handling while the interface is up
+ * @SDATA_STATE_OFFCHANNEL: This interface is currently in offchannel
+ * mode, so queues are stopped
+ */
+enum ieee80211_sdata_state_bits {
+ SDATA_STATE_RUNNING,
+ SDATA_STATE_OFFCHANNEL,
+};
+
struct ieee80211_sub_if_data {
struct list_head list;
@@ -487,6 +530,8 @@ struct ieee80211_sub_if_data {
unsigned int flags;
+ unsigned long state;
+
int drop_unencrypted;
char name[IFNAMSIZ];
@@ -497,17 +542,20 @@ struct ieee80211_sub_if_data {
*/
bool ht_opmode_valid;
+ /* to detect idle changes */
+ bool old_idle;
+
/* Fragment table for host-based reassembly */
struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
unsigned int fragment_next;
-#define NUM_DEFAULT_KEYS 4
-#define NUM_DEFAULT_MGMT_KEYS 2
struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
struct ieee80211_key *default_key;
struct ieee80211_key *default_mgmt_key;
u16 sequence_number;
+ __be16 control_port_protocol;
+ bool control_port_no_encrypt;
struct work_struct work;
struct sk_buff_head skb_queue;
@@ -539,6 +587,7 @@ struct ieee80211_sub_if_data {
#ifdef CONFIG_MAC80211_DEBUGFS
struct {
struct dentry *dir;
+ struct dentry *subdir_stations;
struct dentry *default_key;
struct dentry *default_mgmt_key;
} debugfs;
@@ -595,11 +644,17 @@ enum queue_stop_reason {
* determine if we are on the operating channel or not
* @SCAN_OFF_CHANNEL: We're off our operating channel for scanning,
* gets only set in conjunction with SCAN_SW_SCANNING
+ * @SCAN_COMPLETED: Set for our scan work function when the driver reported
+ * that the scan completed.
+ * @SCAN_ABORTED: Set for our scan work function when the driver reported
+ * a scan complete for an aborted scan.
*/
enum {
SCAN_SW_SCANNING,
SCAN_HW_SCANNING,
SCAN_OFF_CHANNEL,
+ SCAN_COMPLETED,
+ SCAN_ABORTED,
};
/**
@@ -634,7 +689,6 @@ struct ieee80211_local {
/*
* work stuff, potentially off-channel (in the future)
*/
- struct mutex work_mtx;
struct list_head work_list;
struct timer_list work_timer;
struct work_struct work_work;
@@ -653,9 +707,13 @@ struct ieee80211_local {
int open_count;
int monitors, cooked_mntrs;
/* number of interfaces with corresponding FIF_ flags */
- int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll;
+ int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
+ fif_probe_req;
+ int probe_req_reg;
unsigned int filter_flags; /* FIF_* */
+ bool wiphy_ciphers_allocated;
+
/* protects the aggregated multicast list and filter calls */
spinlock_t filter_lock;
@@ -746,9 +804,10 @@ struct ieee80211_local {
*/
struct mutex key_mtx;
+ /* mutex for scan and work locking */
+ struct mutex mtx;
/* Scanning and BSS list */
- struct mutex scan_mtx;
unsigned long scanning;
struct cfg80211_ssid scan_ssid;
struct cfg80211_scan_request *int_scan_req;
@@ -866,10 +925,14 @@ struct ieee80211_local {
#ifdef CONFIG_MAC80211_DEBUGFS
struct local_debugfsdentries {
struct dentry *rcdir;
- struct dentry *stations;
struct dentry *keys;
} debugfs;
#endif
+
+ /* dummy netdev for use w/ NAPI */
+ struct net_device napi_dev;
+
+ struct napi_struct napi;
};
static inline struct ieee80211_sub_if_data *
@@ -1003,6 +1066,8 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata);
void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb);
+void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata);
+void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
/* IBSS code */
void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
@@ -1068,10 +1133,12 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
void ieee80211_remove_interfaces(struct ieee80211_local *local);
u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
void ieee80211_recalc_idle(struct ieee80211_local *local);
+void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
+ const int offset);
static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
{
- return netif_running(sdata->dev);
+ return test_bit(SDATA_STATE_RUNNING, &sdata->state);
}
/* tx handling */
@@ -1105,12 +1172,13 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
enum ieee80211_smps_mode smps, const u8 *da,
const u8 *bssid);
+void ieee80211_request_smps_work(struct work_struct *work);
void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
- u16 initiator, u16 reason);
+ u16 initiator, u16 reason, bool stop);
void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
- u16 initiator, u16 reason);
-void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta);
+ u16 initiator, u16 reason, bool stop);
+void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx);
void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta,
struct ieee80211_mgmt *mgmt, size_t len);
@@ -1124,13 +1192,16 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
size_t len);
int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
- enum ieee80211_back_parties initiator);
+ enum ieee80211_back_parties initiator,
+ bool tx);
int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
- enum ieee80211_back_parties initiator);
+ enum ieee80211_back_parties initiator,
+ bool tx);
void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid);
void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid);
void ieee80211_ba_session_work(struct work_struct *work);
void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid);
+void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid);
/* Spectrum management */
void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
@@ -1146,6 +1217,12 @@ int __ieee80211_suspend(struct ieee80211_hw *hw);
static inline int __ieee80211_resume(struct ieee80211_hw *hw)
{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
+ "%s: resume with hardware scan still in progress\n",
+ wiphy_name(hw->wiphy));
+
return ieee80211_reconfig(hw_to_local(hw));
}
#else
@@ -1208,7 +1285,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
const u8 *key, u8 key_len, u8 key_idx);
int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
const u8 *ie, size_t ie_len,
- enum ieee80211_band band);
+ enum ieee80211_band band, u32 rate_mask,
+ u8 channel);
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
const u8 *ssid, size_t ssid_len,
const u8 *ie, size_t ie_len);
@@ -1221,8 +1299,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
enum ieee80211_band band);
int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
enum ieee80211_smps_mode smps_mode);
-void ieee80211_recalc_smps(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *forsdata);
+void ieee80211_recalc_smps(struct ieee80211_local *local);
size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
const u8 *ids, int n_ids, size_t offset);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index ebbe264e2b0b..f9163b12c7f1 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -24,6 +24,7 @@
#include "led.h"
#include "driver-ops.h"
#include "wme.h"
+#include "rate.h"
/**
* DOC: Interface list locking
@@ -94,21 +95,14 @@ static inline int identical_mac_addr_allowed(int type1, int type2)
type2 == NL80211_IFTYPE_AP_VLAN));
}
-static int ieee80211_open(struct net_device *dev)
+static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
+ enum nl80211_iftype iftype)
{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_sub_if_data *nsdata;
struct ieee80211_local *local = sdata->local;
- struct sta_info *sta;
- u32 changed = 0;
- int res;
- u32 hw_reconf_flags = 0;
- u8 null_addr[ETH_ALEN] = {0};
+ struct ieee80211_sub_if_data *nsdata;
+ struct net_device *dev = sdata->dev;
- /* fail early if user set an invalid address */
- if (compare_ether_addr(dev->dev_addr, null_addr) &&
- !is_valid_ether_addr(dev->dev_addr))
- return -EADDRNOTAVAIL;
+ ASSERT_RTNL();
/* we hold the RTNL here so can safely walk the list */
list_for_each_entry(nsdata, &local->interfaces, list) {
@@ -125,7 +119,7 @@ static int ieee80211_open(struct net_device *dev)
* belonging to the same hardware. Then, however, we're
* faced with having to adopt two different TSF timers...
*/
- if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
+ if (iftype == NL80211_IFTYPE_ADHOC &&
nsdata->vif.type == NL80211_IFTYPE_ADHOC)
return -EBUSY;
@@ -139,19 +133,56 @@ static int ieee80211_open(struct net_device *dev)
/*
* check whether it may have the same address
*/
- if (!identical_mac_addr_allowed(sdata->vif.type,
+ if (!identical_mac_addr_allowed(iftype,
nsdata->vif.type))
return -ENOTUNIQ;
/*
* can only add VLANs to enabled APs
*/
- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
+ if (iftype == NL80211_IFTYPE_AP_VLAN &&
nsdata->vif.type == NL80211_IFTYPE_AP)
sdata->bss = &nsdata->u.ap;
}
}
+ return 0;
+}
+
+void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
+ const int offset)
+{
+ struct ieee80211_local *local = sdata->local;
+ u32 flags = sdata->u.mntr_flags;
+
+#define ADJUST(_f, _s) do { \
+ if (flags & MONITOR_FLAG_##_f) \
+ local->fif_##_s += offset; \
+ } while (0)
+
+ ADJUST(FCSFAIL, fcsfail);
+ ADJUST(PLCPFAIL, plcpfail);
+ ADJUST(CONTROL, control);
+ ADJUST(CONTROL, pspoll);
+ ADJUST(OTHER_BSS, other_bss);
+
+#undef ADJUST
+}
+
+/*
+ * NOTE: Be very careful when changing this function, it must NOT return
+ * an error on interface type changes that have been pre-checked, so most
+ * checks should be in ieee80211_check_concurrent_iface.
+ */
+static int ieee80211_do_open(struct net_device *dev, bool coming_up)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+ u32 changed = 0;
+ int res;
+ u32 hw_reconf_flags = 0;
+
switch (sdata->vif.type) {
case NL80211_IFTYPE_WDS:
if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
@@ -177,7 +208,9 @@ static int ieee80211_open(struct net_device *dev)
/* no special treatment */
break;
case NL80211_IFTYPE_UNSPECIFIED:
- case __NL80211_IFTYPE_AFTER_LAST:
+ case NUM_NL80211_IFTYPES:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ case NL80211_IFTYPE_P2P_GO:
/* cannot happen */
WARN_ON(1);
break;
@@ -187,39 +220,30 @@ static int ieee80211_open(struct net_device *dev)
res = drv_start(local);
if (res)
goto err_del_bss;
+ if (local->ops->napi_poll)
+ napi_enable(&local->napi);
/* we're brought up, everything changes */
hw_reconf_flags = ~0;
ieee80211_led_radio(local, true);
}
/*
- * Check all interfaces and copy the hopefully now-present
- * MAC address to those that have the special null one.
+ * Copy the hopefully now-present MAC address to
+ * this interface, if it has the special null one.
*/
- list_for_each_entry(nsdata, &local->interfaces, list) {
- struct net_device *ndev = nsdata->dev;
-
- /*
- * No need to check running since we do not allow
- * it to start up with this invalid address.
- */
- if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) {
- memcpy(ndev->dev_addr,
- local->hw.wiphy->perm_addr,
- ETH_ALEN);
- memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN);
+ if (is_zero_ether_addr(dev->dev_addr)) {
+ memcpy(dev->dev_addr,
+ local->hw.wiphy->perm_addr,
+ ETH_ALEN);
+ memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);
+
+ if (!is_valid_ether_addr(dev->dev_addr)) {
+ if (!local->open_count)
+ drv_stop(local);
+ return -EADDRNOTAVAIL;
}
}
- /*
- * Validate the MAC address for this device.
- */
- if (!is_valid_ether_addr(dev->dev_addr)) {
- if (!local->open_count)
- drv_stop(local);
- return -EADDRNOTAVAIL;
- }
-
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP_VLAN:
/* no need to tell driver */
@@ -237,25 +261,17 @@ static int ieee80211_open(struct net_device *dev)
hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
}
- if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
- local->fif_fcsfail++;
- if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
- local->fif_plcpfail++;
- if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
- local->fif_control++;
- local->fif_pspoll++;
- }
- if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
- local->fif_other_bss++;
-
+ ieee80211_adjust_monitor_flags(sdata, 1);
ieee80211_configure_filter(local);
netif_carrier_on(dev);
break;
default:
- res = drv_add_interface(local, &sdata->vif);
- if (res)
- goto err_stop;
+ if (coming_up) {
+ res = drv_add_interface(local, &sdata->vif);
+ if (res)
+ goto err_stop;
+ }
if (ieee80211_vif_is_mesh(&sdata->vif)) {
local->fif_other_bss++;
@@ -264,8 +280,11 @@ static int ieee80211_open(struct net_device *dev)
ieee80211_start_mesh(sdata);
} else if (sdata->vif.type == NL80211_IFTYPE_AP) {
local->fif_pspoll++;
+ local->fif_probe_req++;
ieee80211_configure_filter(local);
+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ local->fif_probe_req++;
}
changed |= ieee80211_reset_erp_info(sdata);
@@ -277,6 +296,8 @@ static int ieee80211_open(struct net_device *dev)
netif_carrier_on(dev);
}
+ set_bit(SDATA_STATE_RUNNING, &sdata->state);
+
if (sdata->vif.type == NL80211_IFTYPE_WDS) {
/* Create STA entry for the WDS peer */
sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
@@ -294,6 +315,8 @@ static int ieee80211_open(struct net_device *dev)
/* STA has been freed */
goto err_del_interface;
}
+
+ rate_control_rate_init(sta);
}
/*
@@ -307,9 +330,13 @@ static int ieee80211_open(struct net_device *dev)
if (sdata->flags & IEEE80211_SDATA_PROMISC)
atomic_inc(&local->iff_promiscs);
+ mutex_lock(&local->mtx);
hw_reconf_flags |= __ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
+
+ if (coming_up)
+ local->open_count++;
- local->open_count++;
if (hw_reconf_flags) {
ieee80211_hw_config(local, hw_reconf_flags);
/*
@@ -334,22 +361,42 @@ static int ieee80211_open(struct net_device *dev)
sdata->bss = NULL;
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
list_del(&sdata->u.vlan.list);
+ clear_bit(SDATA_STATE_RUNNING, &sdata->state);
return res;
}
-static int ieee80211_stop(struct net_device *dev)
+static int ieee80211_open(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ int err;
+
+ /* fail early if user set an invalid address */
+ if (!is_zero_ether_addr(dev->dev_addr) &&
+ !is_valid_ether_addr(dev->dev_addr))
+ return -EADDRNOTAVAIL;
+
+ err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type);
+ if (err)
+ return err;
+
+ return ieee80211_do_open(dev, true);
+}
+
+static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
+ bool going_down)
+{
struct ieee80211_local *local = sdata->local;
unsigned long flags;
struct sk_buff *skb, *tmp;
u32 hw_reconf_flags = 0;
int i;
+ clear_bit(SDATA_STATE_RUNNING, &sdata->state);
+
/*
* Stop TX on this interface first.
*/
- netif_tx_stop_all_queues(dev);
+ netif_tx_stop_all_queues(sdata->dev);
/*
* Purge work for this interface.
@@ -366,12 +413,9 @@ static int ieee80211_stop(struct net_device *dev)
* (because if we remove a STA after ops->remove_interface()
* the driver will have removed the vif info already!)
*
- * We could relax this and only unlink the stations from the
- * hash table and list but keep them on a per-sdata list that
- * will be inserted back again when the interface is brought
- * up again, but I don't currently see a use case for that,
- * except with WDS which gets a STA entry created when it is
- * brought up.
+ * This is relevant only in AP, WDS and mesh modes, since in
+ * all other modes we've already removed all stations when
+ * disconnecting etc.
*/
sta_info_flush(local, sdata);
@@ -387,14 +431,19 @@ static int ieee80211_stop(struct net_device *dev)
if (sdata->flags & IEEE80211_SDATA_PROMISC)
atomic_dec(&local->iff_promiscs);
- if (sdata->vif.type == NL80211_IFTYPE_AP)
+ if (sdata->vif.type == NL80211_IFTYPE_AP) {
local->fif_pspoll--;
+ local->fif_probe_req--;
+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ local->fif_probe_req--;
+ }
- netif_addr_lock_bh(dev);
+ netif_addr_lock_bh(sdata->dev);
spin_lock_bh(&local->filter_lock);
- __hw_addr_unsync(&local->mc_list, &dev->mc, dev->addr_len);
+ __hw_addr_unsync(&local->mc_list, &sdata->dev->mc,
+ sdata->dev->addr_len);
spin_unlock_bh(&local->filter_lock);
- netif_addr_unlock_bh(dev);
+ netif_addr_unlock_bh(sdata->dev);
ieee80211_configure_filter(local);
@@ -406,11 +455,21 @@ static int ieee80211_stop(struct net_device *dev)
struct ieee80211_sub_if_data *vlan, *tmpsdata;
struct beacon_data *old_beacon = sdata->u.ap.beacon;
+ /* sdata_running will return false, so this will disable */
+ ieee80211_bss_info_change_notify(sdata,
+ BSS_CHANGED_BEACON_ENABLED);
+
/* remove beacon */
rcu_assign_pointer(sdata->u.ap.beacon, NULL);
synchronize_rcu();
kfree(old_beacon);
+ /* free all potentially still buffered bcast frames */
+ while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
+ local->total_ps_buffered--;
+ dev_kfree_skb(skb);
+ }
+
/* down all dependent devices, that is VLANs */
list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
u.vlan.list)
@@ -418,7 +477,8 @@ static int ieee80211_stop(struct net_device *dev)
WARN_ON(!list_empty(&sdata->u.ap.vlans));
}
- local->open_count--;
+ if (going_down)
+ local->open_count--;
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP_VLAN:
@@ -437,40 +497,9 @@ static int ieee80211_stop(struct net_device *dev)
hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
}
- if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
- local->fif_fcsfail--;
- if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
- local->fif_plcpfail--;
- if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
- local->fif_pspoll--;
- local->fif_control--;
- }
- if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
- local->fif_other_bss--;
-
+ ieee80211_adjust_monitor_flags(sdata, -1);
ieee80211_configure_filter(local);
break;
- case NL80211_IFTYPE_STATION:
- del_timer_sync(&sdata->u.mgd.chswitch_timer);
- del_timer_sync(&sdata->u.mgd.timer);
- del_timer_sync(&sdata->u.mgd.conn_mon_timer);
- del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
- /*
- * If any of the timers fired while we waited for it, it will
- * have queued its work. Now the work will be running again
- * but will not rearm the timer again because it checks
- * whether the interface is running, which, at this point,
- * it no longer is.
- */
- cancel_work_sync(&sdata->u.mgd.chswitch_work);
- cancel_work_sync(&sdata->u.mgd.monitor_work);
- cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work);
-
- /* fall through */
- case NL80211_IFTYPE_ADHOC:
- if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
- del_timer_sync(&sdata->u.ibss.timer);
- /* fall through */
case NL80211_IFTYPE_MESH_POINT:
if (ieee80211_vif_is_mesh(&sdata->vif)) {
/* other_bss and allmulti are always set on mesh
@@ -498,27 +527,34 @@ static int ieee80211_stop(struct net_device *dev)
ieee80211_scan_cancel(local);
/*
- * Disable beaconing for AP and mesh, IBSS can't
- * still be joined to a network at this point.
+ * Disable beaconing here for mesh only, AP and IBSS
+ * are already taken care of.
*/
- if (sdata->vif.type == NL80211_IFTYPE_AP ||
- sdata->vif.type == NL80211_IFTYPE_MESH_POINT) {
+ if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
ieee80211_bss_info_change_notify(sdata,
BSS_CHANGED_BEACON_ENABLED);
- }
- /* free all remaining keys, there shouldn't be any */
+ /*
+ * Free all remaining keys, there shouldn't be any,
+ * except maybe group keys in AP more or WDS?
+ */
ieee80211_free_keys(sdata);
- drv_remove_interface(local, &sdata->vif);
+
+ if (going_down)
+ drv_remove_interface(local, &sdata->vif);
}
sdata->bss = NULL;
+ mutex_lock(&local->mtx);
hw_reconf_flags |= __ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
ieee80211_recalc_ps(local, -1);
if (local->open_count == 0) {
+ if (local->ops->napi_poll)
+ napi_disable(&local->napi);
ieee80211_clear_tx_pending(local);
ieee80211_stop_device(local);
@@ -541,6 +577,13 @@ static int ieee80211_stop(struct net_device *dev)
}
}
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+}
+
+static int ieee80211_stop(struct net_device *dev)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ ieee80211_do_stop(sdata, true);
return 0;
}
@@ -585,8 +628,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
- struct beacon_data *beacon;
- struct sk_buff *skb;
int flushed;
int i;
@@ -599,37 +640,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
__skb_queue_purge(&sdata->fragments[i].skb_list);
sdata->fragment_next = 0;
- switch (sdata->vif.type) {
- case NL80211_IFTYPE_AP:
- beacon = sdata->u.ap.beacon;
- rcu_assign_pointer(sdata->u.ap.beacon, NULL);
- synchronize_rcu();
- kfree(beacon);
-
- while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
- local->total_ps_buffered--;
- dev_kfree_skb(skb);
- }
-
- break;
- case NL80211_IFTYPE_MESH_POINT:
- if (ieee80211_vif_is_mesh(&sdata->vif))
- mesh_rmc_free(sdata);
- break;
- case NL80211_IFTYPE_ADHOC:
- if (WARN_ON(sdata->u.ibss.presp))
- kfree_skb(sdata->u.ibss.presp);
- break;
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_WDS:
- case NL80211_IFTYPE_AP_VLAN:
- case NL80211_IFTYPE_MONITOR:
- break;
- case NL80211_IFTYPE_UNSPECIFIED:
- case __NL80211_IFTYPE_AFTER_LAST:
- BUG();
- break;
- }
+ if (ieee80211_vif_is_mesh(&sdata->vif))
+ mesh_rmc_free(sdata);
flushed = sta_info_flush(local, sdata);
WARN_ON(flushed);
@@ -791,7 +803,8 @@ static void ieee80211_iface_work(struct work_struct *work)
__ieee80211_stop_rx_ba_session(
sta, tid, WLAN_BACK_RECIPIENT,
- WLAN_REASON_QSTA_REQUIRE_SETUP);
+ WLAN_REASON_QSTA_REQUIRE_SETUP,
+ true);
}
mutex_unlock(&local->sta_mtx);
} else switch (sdata->vif.type) {
@@ -844,9 +857,13 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
/* and set some type-dependent values */
sdata->vif.type = type;
+ sdata->vif.p2p = false;
sdata->dev->netdev_ops = &ieee80211_dataif_ops;
sdata->wdev.iftype = type;
+ sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE);
+ sdata->control_port_no_encrypt = false;
+
/* only monitor differs */
sdata->dev->type = ARPHRD_ETHER;
@@ -854,10 +871,20 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
INIT_WORK(&sdata->work, ieee80211_iface_work);
switch (type) {
+ case NL80211_IFTYPE_P2P_GO:
+ type = NL80211_IFTYPE_AP;
+ sdata->vif.type = type;
+ sdata->vif.p2p = true;
+ /* fall through */
case NL80211_IFTYPE_AP:
skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
INIT_LIST_HEAD(&sdata->u.ap.vlans);
break;
+ case NL80211_IFTYPE_P2P_CLIENT:
+ type = NL80211_IFTYPE_STATION;
+ sdata->vif.type = type;
+ sdata->vif.p2p = true;
+ /* fall through */
case NL80211_IFTYPE_STATION:
ieee80211_sta_setup_sdata(sdata);
break;
@@ -878,7 +905,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
case NL80211_IFTYPE_AP_VLAN:
break;
case NL80211_IFTYPE_UNSPECIFIED:
- case __NL80211_IFTYPE_AFTER_LAST:
+ case NUM_NL80211_IFTYPES:
BUG();
break;
}
@@ -886,12 +913,85 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
ieee80211_debugfs_add_netdev(sdata);
}
+static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
+ enum nl80211_iftype type)
+{
+ struct ieee80211_local *local = sdata->local;
+ int ret, err;
+ enum nl80211_iftype internal_type = type;
+ bool p2p = false;
+
+ ASSERT_RTNL();
+
+ if (!local->ops->change_interface)
+ return -EBUSY;
+
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_ADHOC:
+ /*
+ * Could maybe also all others here?
+ * Just not sure how that interacts
+ * with the RX/config path e.g. for
+ * mesh.
+ */
+ break;
+ default:
+ return -EBUSY;
+ }
+
+ switch (type) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_ADHOC:
+ /*
+ * Could probably support everything
+ * but WDS here (WDS do_open can fail
+ * under memory pressure, which this
+ * code isn't prepared to handle).
+ */
+ break;
+ case NL80211_IFTYPE_P2P_CLIENT:
+ p2p = true;
+ internal_type = NL80211_IFTYPE_STATION;
+ break;
+ case NL80211_IFTYPE_P2P_GO:
+ p2p = true;
+ internal_type = NL80211_IFTYPE_AP;
+ break;
+ default:
+ return -EBUSY;
+ }
+
+ ret = ieee80211_check_concurrent_iface(sdata, internal_type);
+ if (ret)
+ return ret;
+
+ ieee80211_do_stop(sdata, false);
+
+ ieee80211_teardown_sdata(sdata->dev);
+
+ ret = drv_change_interface(local, sdata, internal_type, p2p);
+ if (ret)
+ type = sdata->vif.type;
+
+ ieee80211_setup_sdata(sdata, type);
+
+ err = ieee80211_do_open(sdata->dev, false);
+ WARN(err, "type change: do_open returned %d", err);
+
+ return ret;
+}
+
int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
enum nl80211_iftype type)
{
+ int ret;
+
ASSERT_RTNL();
- if (type == sdata->vif.type)
+ if (type == ieee80211_vif_type_p2p(&sdata->vif))
return 0;
/* Setting ad-hoc mode on non-IBSS channel is not supported. */
@@ -899,18 +999,15 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
type == NL80211_IFTYPE_ADHOC)
return -EOPNOTSUPP;
- /*
- * We could, here, on changes between IBSS/STA/MESH modes,
- * invoke an MLME function instead that disassociates etc.
- * and goes into the requested mode.
- */
-
- if (ieee80211_sdata_running(sdata))
- return -EBUSY;
-
- /* Purge and reset type-dependent state. */
- ieee80211_teardown_sdata(sdata->dev);
- ieee80211_setup_sdata(sdata, type);
+ if (ieee80211_sdata_running(sdata)) {
+ ret = ieee80211_runtime_change_iftype(sdata, type);
+ if (ret)
+ return ret;
+ } else {
+ /* Purge and reset type-dependent state. */
+ ieee80211_teardown_sdata(sdata->dev);
+ ieee80211_setup_sdata(sdata, type);
+ }
/* reset some values that shouldn't be kept across type changes */
sdata->vif.bss_conf.basic_rates =
@@ -1167,8 +1264,7 @@ static u32 ieee80211_idle_off(struct ieee80211_local *local,
return 0;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: device no longer idle - %s\n",
- wiphy_name(local->hw.wiphy), reason);
+ wiphy_debug(local->hw.wiphy, "device no longer idle - %s\n", reason);
#endif
local->hw.conf.flags &= ~IEEE80211_CONF_IDLE;
@@ -1181,8 +1277,7 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local)
return 0;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: device now idle\n",
- wiphy_name(local->hw.wiphy));
+ wiphy_debug(local->hw.wiphy, "device now idle\n");
#endif
drv_flush(local, false);
@@ -1195,28 +1290,61 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
{
struct ieee80211_sub_if_data *sdata;
int count = 0;
+ bool working = false, scanning = false;
+ struct ieee80211_work *wk;
- if (!list_empty(&local->work_list))
- return ieee80211_idle_off(local, "working");
-
- if (local->scanning)
- return ieee80211_idle_off(local, "scanning");
+#ifdef CONFIG_PROVE_LOCKING
+ WARN_ON(debug_locks && !lockdep_rtnl_is_held() &&
+ !lockdep_is_held(&local->iflist_mtx));
+#endif
+ lockdep_assert_held(&local->mtx);
list_for_each_entry(sdata, &local->interfaces, list) {
- if (!ieee80211_sdata_running(sdata))
+ if (!ieee80211_sdata_running(sdata)) {
+ sdata->vif.bss_conf.idle = true;
continue;
+ }
+
+ sdata->old_idle = sdata->vif.bss_conf.idle;
+
/* do not count disabled managed interfaces */
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
- !sdata->u.mgd.associated)
+ !sdata->u.mgd.associated) {
+ sdata->vif.bss_conf.idle = true;
continue;
+ }
/* do not count unused IBSS interfaces */
if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
- !sdata->u.ibss.ssid_len)
+ !sdata->u.ibss.ssid_len) {
+ sdata->vif.bss_conf.idle = true;
continue;
+ }
/* count everything else */
count++;
}
+ list_for_each_entry(wk, &local->work_list, list) {
+ working = true;
+ wk->sdata->vif.bss_conf.idle = false;
+ }
+
+ if (local->scan_sdata) {
+ scanning = true;
+ local->scan_sdata->vif.bss_conf.idle = false;
+ }
+
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (sdata->old_idle == sdata->vif.bss_conf.idle)
+ continue;
+ if (!ieee80211_sdata_running(sdata))
+ continue;
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
+ }
+
+ if (working)
+ return ieee80211_idle_off(local, "working");
+ if (scanning)
+ return ieee80211_idle_off(local, "scanning");
if (!count)
return ieee80211_idle_on(local);
else
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 1b9d87ed143a..ccd676b2f599 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -49,7 +49,7 @@ static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
static void assert_key_lock(struct ieee80211_local *local)
{
- WARN_ON(!mutex_is_locked(&local->key_mtx));
+ lockdep_assert_held(&local->key_mtx);
}
static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
@@ -60,7 +60,7 @@ static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
return NULL;
}
-static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
+static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
{
struct ieee80211_sub_if_data *sdata;
struct ieee80211_sta *sta;
@@ -69,12 +69,20 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
might_sleep();
if (!key->local->ops->set_key)
- return;
+ goto out_unsupported;
assert_key_lock(key->local);
sta = get_sta_for_key(key);
+ /*
+ * If this is a per-STA GTK, check if it
+ * is supported; if not, return.
+ */
+ if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) &&
+ !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
+ goto out_unsupported;
+
sdata = key->sdata;
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
sdata = container_of(sdata->bss,
@@ -83,14 +91,28 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
- if (!ret)
+ if (!ret) {
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
+ return 0;
+ }
- if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP)
- printk(KERN_ERR "mac80211-%s: failed to set key "
- "(%d, %pM) to hardware (%d)\n",
- wiphy_name(key->local->hw.wiphy),
- key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
+ if (ret != -ENOSPC && ret != -EOPNOTSUPP)
+ wiphy_err(key->local->hw.wiphy,
+ "failed to set key (%d, %pM) to hardware (%d)\n",
+ key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
+
+ out_unsupported:
+ switch (key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ /* all of these we can do in software */
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
@@ -121,14 +143,33 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
sta, &key->conf);
if (ret)
- printk(KERN_ERR "mac80211-%s: failed to remove key "
- "(%d, %pM) from hardware (%d)\n",
- wiphy_name(key->local->hw.wiphy),
- key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
+ wiphy_err(key->local->hw.wiphy,
+ "failed to remove key (%d, %pM) from hardware (%d)\n",
+ key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
}
+void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
+{
+ struct ieee80211_key *key;
+
+ key = container_of(key_conf, struct ieee80211_key, conf);
+
+ might_sleep();
+ assert_key_lock(key->local);
+
+ key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
+
+ /*
+ * Flush TX path to avoid attempts to use this key
+ * after this function returns. Until then, drivers
+ * must be prepared to handle the key.
+ */
+ synchronize_rcu();
+}
+EXPORT_SYMBOL_GPL(ieee80211_key_removed);
+
static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
int idx)
{
@@ -184,6 +225,7 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta,
+ bool pairwise,
struct ieee80211_key *old,
struct ieee80211_key *new)
{
@@ -192,8 +234,14 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
if (new)
list_add(&new->list, &sdata->key_list);
- if (sta) {
- rcu_assign_pointer(sta->key, new);
+ if (sta && pairwise) {
+ rcu_assign_pointer(sta->ptk, new);
+ } else if (sta) {
+ if (old)
+ idx = old->conf.keyidx;
+ else
+ idx = new->conf.keyidx;
+ rcu_assign_pointer(sta->gtk[idx], new);
} else {
WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
@@ -227,20 +275,18 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
}
}
-struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
- int idx,
- size_t key_len,
+struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
const u8 *key_data,
size_t seq_len, const u8 *seq)
{
struct ieee80211_key *key;
- int i, j;
+ int i, j, err;
BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
if (!key)
- return NULL;
+ return ERR_PTR(-ENOMEM);
/*
* Default to software encryption; we'll later upload the
@@ -249,15 +295,16 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
key->conf.flags = 0;
key->flags = 0;
- key->conf.alg = alg;
+ key->conf.cipher = cipher;
key->conf.keyidx = idx;
key->conf.keylen = key_len;
- switch (alg) {
- case ALG_WEP:
+ switch (cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
key->conf.iv_len = WEP_IV_LEN;
key->conf.icv_len = WEP_ICV_LEN;
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
key->conf.iv_len = TKIP_IV_LEN;
key->conf.icv_len = TKIP_ICV_LEN;
if (seq) {
@@ -269,7 +316,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
}
}
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
key->conf.iv_len = CCMP_HDR_LEN;
key->conf.icv_len = CCMP_MIC_LEN;
if (seq) {
@@ -278,42 +325,38 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
key->u.ccmp.rx_pn[i][j] =
seq[CCMP_PN_LEN - j - 1];
}
- break;
- case ALG_AES_CMAC:
- key->conf.iv_len = 0;
- key->conf.icv_len = sizeof(struct ieee80211_mmie);
- if (seq)
- for (j = 0; j < 6; j++)
- key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
- break;
- }
- memcpy(key->conf.key, key_data, key_len);
- INIT_LIST_HEAD(&key->list);
-
- if (alg == ALG_CCMP) {
/*
* Initialize AES key state here as an optimization so that
* it does not need to be initialized for every packet.
*/
key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data);
- if (!key->u.ccmp.tfm) {
+ if (IS_ERR(key->u.ccmp.tfm)) {
+ err = PTR_ERR(key->u.ccmp.tfm);
kfree(key);
- return NULL;
+ key = ERR_PTR(err);
}
- }
-
- if (alg == ALG_AES_CMAC) {
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ key->conf.iv_len = 0;
+ key->conf.icv_len = sizeof(struct ieee80211_mmie);
+ if (seq)
+ for (j = 0; j < 6; j++)
+ key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
/*
* Initialize AES key state here as an optimization so that
* it does not need to be initialized for every packet.
*/
key->u.aes_cmac.tfm =
ieee80211_aes_cmac_key_setup(key_data);
- if (!key->u.aes_cmac.tfm) {
+ if (IS_ERR(key->u.aes_cmac.tfm)) {
+ err = PTR_ERR(key->u.aes_cmac.tfm);
kfree(key);
- return NULL;
+ key = ERR_PTR(err);
}
+ break;
}
+ memcpy(key->conf.key, key_data, key_len);
+ INIT_LIST_HEAD(&key->list);
return key;
}
@@ -326,9 +369,9 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
if (key->local)
ieee80211_key_disable_hw_accel(key);
- if (key->conf.alg == ALG_CCMP)
+ if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
ieee80211_aes_key_free(key->u.ccmp.tfm);
- if (key->conf.alg == ALG_AES_CMAC)
+ if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
if (key->local)
ieee80211_debugfs_key_remove(key);
@@ -336,12 +379,13 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
kfree(key);
}
-void ieee80211_key_link(struct ieee80211_key *key,
- struct ieee80211_sub_if_data *sdata,
- struct sta_info *sta)
+int ieee80211_key_link(struct ieee80211_key *key,
+ struct ieee80211_sub_if_data *sdata,
+ struct sta_info *sta)
{
struct ieee80211_key *old_key;
- int idx;
+ int idx, ret;
+ bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
BUG_ON(!sdata);
BUG_ON(!key);
@@ -358,13 +402,6 @@ void ieee80211_key_link(struct ieee80211_key *key,
*/
if (test_sta_flags(sta, WLAN_STA_WME))
key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
-
- /*
- * This key is for a specific sta interface,
- * inform the driver that it should try to store
- * this key as pairwise key.
- */
- key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
} else {
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
struct sta_info *ap;
@@ -386,19 +423,23 @@ void ieee80211_key_link(struct ieee80211_key *key,
mutex_lock(&sdata->local->key_mtx);
- if (sta)
- old_key = sta->key;
+ if (sta && pairwise)
+ old_key = sta->ptk;
+ else if (sta)
+ old_key = sta->gtk[idx];
else
old_key = sdata->keys[idx];
- __ieee80211_key_replace(sdata, sta, old_key, key);
+ __ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
__ieee80211_key_destroy(old_key);
ieee80211_debugfs_key_add(key);
- ieee80211_key_enable_hw_accel(key);
+ ret = ieee80211_key_enable_hw_accel(key);
mutex_unlock(&sdata->local->key_mtx);
+
+ return ret;
}
static void __ieee80211_key_free(struct ieee80211_key *key)
@@ -408,7 +449,8 @@ static void __ieee80211_key_free(struct ieee80211_key *key)
*/
if (key->sdata)
__ieee80211_key_replace(key->sdata, key->sta,
- key, NULL);
+ key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
+ key, NULL);
__ieee80211_key_destroy(key);
}
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index b665bbb7a471..0db1c0f5f697 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -16,6 +16,9 @@
#include <linux/rcupdate.h>
#include <net/mac80211.h>
+#define NUM_DEFAULT_KEYS 4
+#define NUM_DEFAULT_MGMT_KEYS 2
+
#define WEP_IV_LEN 4
#define WEP_ICV_LEN 4
#define ALG_TKIP_KEY_LEN 32
@@ -123,18 +126,16 @@ struct ieee80211_key {
struct ieee80211_key_conf conf;
};
-struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
- int idx,
- size_t key_len,
+struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
const u8 *key_data,
size_t seq_len, const u8 *seq);
/*
* Insert a key into data structures (sdata, sta if necessary)
* to make it used, free old key.
*/
-void ieee80211_key_link(struct ieee80211_key *key,
- struct ieee80211_sub_if_data *sdata,
- struct sta_info *sta);
+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_local *local,
struct ieee80211_key *key);
void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index ded5c3843e06..22bc42b18991 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
if (local->monitors || local->scanning)
new_flags |= FIF_BCN_PRBRESP_PROMISC;
+ if (local->fif_probe_req || local->probe_req_reg)
+ new_flags |= FIF_PROBE_REQ;
+
if (local->fif_fcsfail)
new_flags |= FIF_FCSFAIL;
@@ -99,16 +102,19 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
int ret = 0;
int power;
enum nl80211_channel_type channel_type;
+ u32 offchannel_flag;
might_sleep();
scan_chan = local->scan_channel;
+ offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
if (scan_chan) {
chan = scan_chan;
channel_type = NL80211_CHAN_NO_HT;
local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
- } else if (local->tmp_channel) {
+ } else if (local->tmp_channel &&
+ local->oper_channel != local->tmp_channel) {
chan = scan_chan = local->tmp_channel;
channel_type = local->tmp_channel_type;
local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
@@ -117,8 +123,9 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
channel_type = local->_oper_channel_type;
local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
}
+ offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
- if (chan != local->hw.conf.channel ||
+ if (offchannel_flag || chan != local->hw.conf.channel ||
channel_type != local->hw.conf.channel_type) {
local->hw.conf.channel = chan;
local->hw.conf.channel_type = channel_type;
@@ -197,6 +204,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
else if (sdata->vif.type == NL80211_IFTYPE_AP)
sdata->vif.bss_conf.bssid = sdata->vif.addr;
+ else if (sdata->vif.type == NL80211_IFTYPE_WDS)
+ sdata->vif.bss_conf.bssid = NULL;
else if (ieee80211_vif_is_mesh(&sdata->vif)) {
sdata->vif.bss_conf.bssid = zero;
} else {
@@ -207,6 +216,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_WDS:
case NL80211_IFTYPE_MESH_POINT:
break;
default:
@@ -291,7 +301,16 @@ static void ieee80211_restart_work(struct work_struct *work)
struct ieee80211_local *local =
container_of(work, struct ieee80211_local, restart_work);
+ /* wait for scan work complete */
+ flush_workqueue(local->workqueue);
+
+ mutex_lock(&local->mtx);
+ WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
+ "%s called with hardware scan in progress\n", __func__);
+ mutex_unlock(&local->mtx);
+
rtnl_lock();
+ ieee80211_scan_cancel(local);
ieee80211_reconfig(local);
rtnl_unlock();
}
@@ -302,7 +321,7 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
trace_api_restart_hw(local);
- /* use this reason, __ieee80211_resume will unblock it */
+ /* use this reason, ieee80211_reconfig will unblock it */
ieee80211_stop_queues_by_reason(hw,
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
@@ -316,7 +335,7 @@ static void ieee80211_recalc_smps_work(struct work_struct *work)
container_of(work, struct ieee80211_local, recalc_smps);
mutex_lock(&local->iflist_mtx);
- ieee80211_recalc_smps(local, NULL);
+ ieee80211_recalc_smps(local);
mutex_unlock(&local->iflist_mtx);
}
@@ -336,9 +355,6 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
struct ieee80211_if_managed *ifmgd;
int c = 0;
- if (!netif_running(ndev))
- return NOTIFY_DONE;
-
/* Make sure it's our interface that got changed */
if (!wdev)
return NOTIFY_DONE;
@@ -349,11 +365,14 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
bss_conf = &sdata->vif.bss_conf;
+ if (!ieee80211_sdata_running(sdata))
+ return NOTIFY_DONE;
+
/* ARP filtering is only supported in managed mode */
if (sdata->vif.type != NL80211_IFTYPE_STATION)
return NOTIFY_DONE;
- idev = sdata->dev->ip_ptr;
+ idev = __in_dev_get_rtnl(sdata->dev);
if (!idev)
return NOTIFY_DONE;
@@ -390,6 +409,80 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
}
#endif
+static int ieee80211_napi_poll(struct napi_struct *napi, int budget)
+{
+ struct ieee80211_local *local =
+ container_of(napi, struct ieee80211_local, napi);
+
+ return local->ops->napi_poll(&local->hw, budget);
+}
+
+void ieee80211_napi_schedule(struct ieee80211_hw *hw)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ napi_schedule(&local->napi);
+}
+EXPORT_SYMBOL(ieee80211_napi_schedule);
+
+void ieee80211_napi_complete(struct ieee80211_hw *hw)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ napi_complete(&local->napi);
+}
+EXPORT_SYMBOL(ieee80211_napi_complete);
+
+/* There isn't a lot of sense in it, but you can transmit anything you like */
+static const struct ieee80211_txrx_stypes
+ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
+ [NL80211_IFTYPE_ADHOC] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4),
+ },
+ [NL80211_IFTYPE_STATION] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
+ },
+ [NL80211_IFTYPE_AP] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+ BIT(IEEE80211_STYPE_ACTION >> 4),
+ },
+ [NL80211_IFTYPE_AP_VLAN] = {
+ /* copy AP */
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+ BIT(IEEE80211_STYPE_ACTION >> 4),
+ },
+ [NL80211_IFTYPE_P2P_CLIENT] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
+ },
+ [NL80211_IFTYPE_P2P_GO] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+ BIT(IEEE80211_STYPE_ACTION >> 4),
+ },
+};
+
struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
const struct ieee80211_ops *ops)
{
@@ -419,6 +512,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
if (!wiphy)
return NULL;
+ wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes;
+
wiphy->flags |= WIPHY_FLAG_NETNS_OK |
WIPHY_FLAG_4ADDR_AP |
WIPHY_FLAG_4ADDR_STATION;
@@ -444,6 +539,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
/* set up some defaults */
local->hw.queues = 1;
local->hw.max_rates = 1;
+ local->hw.max_report_rates = 0;
local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
local->user_power_level = -1;
@@ -455,7 +551,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
__hw_addr_init(&local->mc_list);
mutex_init(&local->iflist_mtx);
- mutex_init(&local->scan_mtx);
+ mutex_init(&local->mtx);
mutex_init(&local->key_mtx);
spin_lock_init(&local->filter_lock);
@@ -494,6 +590,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
skb_queue_head_init(&local->skb_queue);
skb_queue_head_init(&local->skb_queue_unreliable);
+ /* init dummy netdev for use w/ NAPI */
+ init_dummy_netdev(&local->napi_dev);
+
return local_to_hw(local);
}
EXPORT_SYMBOL(ieee80211_alloc_hw);
@@ -506,6 +605,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
int channels, max_bitrates;
bool supp_ht;
static const u32 cipher_suites[] = {
+ /* keep WEP first, it may be removed below */
WLAN_CIPHER_SUITE_WEP40,
WLAN_CIPHER_SUITE_WEP104,
WLAN_CIPHER_SUITE_TKIP,
@@ -515,6 +615,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
WLAN_CIPHER_SUITE_AES_CMAC
};
+ if (hw->max_report_rates == 0)
+ hw->max_report_rates = hw->max_rates;
+
/*
* generic code guarantees at least one band,
* set this very early because much code assumes
@@ -554,6 +657,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
/* mac80211 always supports monitor */
local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
+#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
+
+ /* mac80211 supports control port protocol changing */
+ local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL;
+
if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
@@ -589,10 +700,41 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (local->hw.wiphy->max_scan_ie_len)
local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;
- local->hw.wiphy->cipher_suites = cipher_suites;
- local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
- if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE))
- local->hw.wiphy->n_cipher_suites--;
+ /* Set up cipher suites unless driver already did */
+ if (!local->hw.wiphy->cipher_suites) {
+ local->hw.wiphy->cipher_suites = cipher_suites;
+ local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+ if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE))
+ local->hw.wiphy->n_cipher_suites--;
+ }
+ if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) {
+ if (local->hw.wiphy->cipher_suites == cipher_suites) {
+ local->hw.wiphy->cipher_suites += 2;
+ local->hw.wiphy->n_cipher_suites -= 2;
+ } else {
+ u32 *suites;
+ int r, w = 0;
+
+ /* Filter out WEP */
+
+ suites = kmemdup(
+ local->hw.wiphy->cipher_suites,
+ sizeof(u32) * local->hw.wiphy->n_cipher_suites,
+ GFP_KERNEL);
+ if (!suites)
+ return -ENOMEM;
+ for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
+ u32 suite = local->hw.wiphy->cipher_suites[r];
+ if (suite == WLAN_CIPHER_SUITE_WEP40 ||
+ suite == WLAN_CIPHER_SUITE_WEP104)
+ continue;
+ suites[w++] = suite;
+ }
+ local->hw.wiphy->cipher_suites = suites;
+ local->hw.wiphy->n_cipher_suites = w;
+ local->wiphy_ciphers_allocated = true;
+ }
+ }
result = wiphy_register(local->hw.wiphy);
if (result < 0)
@@ -641,16 +783,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
result = ieee80211_wep_init(local);
if (result < 0)
- printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n",
- wiphy_name(local->hw.wiphy), result);
+ wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
+ result);
rtnl_lock();
result = ieee80211_init_rate_ctrl_alg(local,
hw->rate_control_algorithm);
if (result < 0) {
- printk(KERN_DEBUG "%s: Failed to initialize rate control "
- "algorithm\n", wiphy_name(local->hw.wiphy));
+ wiphy_debug(local->hw.wiphy,
+ "Failed to initialize rate control algorithm\n");
goto fail_rate;
}
@@ -659,8 +801,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
result = ieee80211_if_add(local, "wlan%d", NULL,
NL80211_IFTYPE_STATION, NULL);
if (result)
- printk(KERN_WARNING "%s: Failed to add default virtual iface\n",
- wiphy_name(local->hw.wiphy));
+ wiphy_warn(local->hw.wiphy,
+ "Failed to add default virtual iface\n");
}
rtnl_unlock();
@@ -683,6 +825,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
goto fail_ifa;
#endif
+ netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll,
+ local->hw.napi_weight);
+
return 0;
#ifdef CONFIG_INET
@@ -703,6 +848,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
fail_workqueue:
wiphy_unregister(local->hw.wiphy);
fail_wiphy_register:
+ if (local->wiphy_ciphers_allocated)
+ kfree(local->hw.wiphy->cipher_suites);
kfree(local->int_scan_req);
return result;
}
@@ -738,6 +885,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
*/
del_timer_sync(&local->work_timer);
+ cancel_work_sync(&local->restart_work);
cancel_work_sync(&local->reconfig_filter);
ieee80211_clear_tx_pending(local);
@@ -746,8 +894,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
if (skb_queue_len(&local->skb_queue) ||
skb_queue_len(&local->skb_queue_unreliable))
- printk(KERN_WARNING "%s: skb_queue not empty\n",
- wiphy_name(local->hw.wiphy));
+ wiphy_warn(local->hw.wiphy, "skb_queue not empty\n");
skb_queue_purge(&local->skb_queue);
skb_queue_purge(&local->skb_queue_unreliable);
@@ -764,7 +911,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
struct ieee80211_local *local = hw_to_local(hw);
mutex_destroy(&local->iflist_mtx);
- mutex_destroy(&local->scan_mtx);
+ mutex_destroy(&local->mtx);
+
+ if (local->wiphy_ciphers_allocated)
+ kfree(local->hw.wiphy->cipher_suites);
wiphy_free(local->hw.wiphy);
}
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index ea13a80a476c..1c91f0f3c307 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
enum plink_event event;
enum plink_frame_type ftype;
size_t baselen;
- bool deactivated;
+ bool deactivated, matches_local = true;
u8 ie_len;
u8 *baseaddr;
__le16 plid, llid, reason;
@@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
/* Now we will figure out the appropriate event... */
event = PLINK_UNDEFINED;
if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) {
+ matches_local = false;
switch (ftype) {
case PLINK_OPEN:
event = OPN_RJCT;
@@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
/* avoid warning */
break;
}
- spin_lock_bh(&sta->lock);
+ }
+
+ if (!sta && !matches_local) {
+ rcu_read_unlock();
+ reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
+ llid = 0;
+ mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid,
+ plid, reason);
+ return;
} else if (!sta) {
/* ftype == PLINK_OPEN */
u32 rates;
@@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}
event = OPN_ACPT;
spin_lock_bh(&sta->lock);
- } else {
+ } else if (matches_local) {
spin_lock_bh(&sta->lock);
switch (ftype) {
case PLINK_OPEN:
@@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
rcu_read_unlock();
return;
}
+ } else {
+ spin_lock_bh(&sta->lock);
}
mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b6c163ac22da..a3a9421555af 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -54,6 +54,12 @@
*/
#define IEEE80211_SIGNAL_AVE_WEIGHT 3
+/*
+ * How many Beacon frames need to have been used in average signal strength
+ * before starting to indicate signal change events.
+ */
+#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
+
#define TMR_RUNNING_TIMER 0
#define TMR_RUNNING_CHANSW 1
@@ -86,7 +92,7 @@ enum rx_mgmt_action {
/* utils */
static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
{
- WARN_ON(!mutex_is_locked(&ifmgd->mtx));
+ lockdep_assert_held(&ifmgd->mtx);
}
/*
@@ -109,7 +115,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd,
mod_timer(&ifmgd->timer, timeout);
}
-static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata)
+void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
{
if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
return;
@@ -118,6 +124,19 @@ static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata)
round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME));
}
+void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+ if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
+ return;
+
+ mod_timer(&sdata->u.mgd.conn_mon_timer,
+ round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
+
+ ifmgd->probe_send_count = 0;
+}
+
static int ecw2cw(int ecw)
{
return (1 << ecw) - 1;
@@ -778,16 +797,17 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
params.uapsd = uapsd;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
- "cWmin=%d cWmax=%d txop=%d uapsd=%d\n",
- wiphy_name(local->hw.wiphy), queue, aci, acm,
- params.aifs, params.cw_min, params.cw_max, params.txop,
- params.uapsd);
+ wiphy_debug(local->hw.wiphy,
+ "WMM queue=%d aci=%d acm=%d aifs=%d "
+ "cWmin=%d cWmax=%d txop=%d uapsd=%d\n",
+ queue, aci, acm,
+ params.aifs, params.cw_min, params.cw_max,
+ params.txop, params.uapsd);
#endif
if (drv_conf_tx(local, queue, &params))
- printk(KERN_DEBUG "%s: failed to set TX queue "
- "parameters for queue %d\n",
- wiphy_name(local->hw.wiphy), queue);
+ wiphy_debug(local->hw.wiphy,
+ "failed to set TX queue parameters for queue %d\n",
+ queue);
}
/* enable WMM or activate new settings */
@@ -860,14 +880,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
IEEE80211_STA_BEACON_POLL);
- /*
- * Always handle WMM once after association regardless
- * of the first value the AP uses. Setting -1 here has
- * that effect because the AP values is an unsigned
- * 4-bit value.
- */
- sdata->u.mgd.wmm_last_param_set = -1;
-
ieee80211_led_assoc(local, 1);
if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
@@ -901,7 +913,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
mutex_lock(&local->iflist_mtx);
ieee80211_recalc_ps(local, -1);
- ieee80211_recalc_smps(local, sdata);
+ ieee80211_recalc_smps(local);
mutex_unlock(&local->iflist_mtx);
netif_tx_start_all_queues(sdata->dev);
@@ -909,7 +921,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
}
static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
- bool remove_sta)
+ bool remove_sta, bool tx)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local;
@@ -948,7 +960,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
sta = sta_info_get(sdata, bssid);
if (sta) {
set_sta_flags(sta, WLAN_STA_BLOCK_BA);
- ieee80211_sta_tear_down_BA_sessions(sta);
+ ieee80211_sta_tear_down_BA_sessions(sta, tx);
}
mutex_unlock(&local->sta_mtx);
@@ -990,6 +1002,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
if (remove_sta)
sta_info_destroy_addr(sdata, bssid);
+
+ del_timer_sync(&sdata->u.mgd.conn_mon_timer);
+ del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
+ del_timer_sync(&sdata->u.mgd.timer);
+ del_timer_sync(&sdata->u.mgd.chswitch_timer);
}
void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -1006,21 +1023,26 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
if (is_multicast_ether_addr(hdr->addr1))
return;
- if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
- return;
-
- mod_timer(&sdata->u.mgd.conn_mon_timer,
- round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
+ ieee80211_sta_reset_conn_monitor(sdata);
}
static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
const u8 *ssid;
+ u8 *dst = ifmgd->associated->bssid;
+ u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3);
+
+ /*
+ * Try sending broadcast probe requests for the last three
+ * probe requests after the first ones failed since some
+ * buggy APs only support broadcast probe requests.
+ */
+ if (ifmgd->probe_send_count >= unicast_limit)
+ dst = NULL;
ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
- ieee80211_send_probe_req(sdata, ifmgd->associated->bssid,
- ssid + 2, ssid[1], NULL, 0);
+ ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
ifmgd->probe_send_count++;
ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
@@ -1102,9 +1124,12 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
- ieee80211_set_disassoc(sdata, true);
- ieee80211_recalc_idle(local);
+ ieee80211_set_disassoc(sdata, true, true);
mutex_unlock(&ifmgd->mtx);
+
+ mutex_lock(&local->mtx);
+ ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
/*
* must be outside lock due to cfg80211,
* but that's not a problem.
@@ -1172,8 +1197,10 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
sdata->name, bssid, reason_code);
- ieee80211_set_disassoc(sdata, true);
+ ieee80211_set_disassoc(sdata, true, false);
+ mutex_lock(&sdata->local->mtx);
ieee80211_recalc_idle(sdata->local);
+ mutex_unlock(&sdata->local->mtx);
return RX_MGMT_CFG80211_DEAUTH;
}
@@ -1202,8 +1229,10 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
sdata->name, mgmt->sa, reason_code);
- ieee80211_set_disassoc(sdata, true);
+ ieee80211_set_disassoc(sdata, true, false);
+ mutex_lock(&sdata->local->mtx);
ieee80211_recalc_idle(sdata->local);
+ mutex_unlock(&sdata->local->mtx);
return RX_MGMT_CFG80211_DISASSOC;
}
@@ -1262,7 +1291,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
rates = 0;
basic_rates = 0;
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+ sband = local->hw.wiphy->bands[wk->chan->band];
for (i = 0; i < elems.supp_rates_len; i++) {
int rate = (elems.supp_rates[i] & 0x7f) * 5;
@@ -1298,11 +1327,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
}
}
- sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
+ sta->sta.supp_rates[wk->chan->band] = rates;
sdata->vif.bss_conf.basic_rates = basic_rates;
/* cf. IEEE 802.11 9.2.12 */
- if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
+ if (wk->chan->band == IEEE80211_BAND_2GHZ &&
have_higher_than_11mbit)
sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
else
@@ -1330,6 +1359,14 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
return false;
}
+ /*
+ * Always handle WMM once after association regardless
+ * of the first value the AP uses. Setting -1 here has
+ * that effect because the AP values is an unsigned
+ * 4-bit value.
+ */
+ ifmgd->wmm_last_param_set = -1;
+
if (elems.wmm_param)
ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
elems.wmm_param_len);
@@ -1362,7 +1399,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
* Also start the timer that will detect beacon loss.
*/
ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
- mod_beacon_timer(sdata);
+ ieee80211_sta_reset_beacon_monitor(sdata);
return true;
}
@@ -1465,7 +1502,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
* we have or will be receiving any beacons or data, so let's
* schedule the timers again, just in case.
*/
- mod_beacon_timer(sdata);
+ ieee80211_sta_reset_beacon_monitor(sdata);
mod_timer(&ifmgd->conn_mon_timer,
round_jiffies_up(jiffies +
@@ -1540,15 +1577,18 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
ifmgd->last_beacon_signal = rx_status->signal;
if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
- ifmgd->ave_beacon_signal = rx_status->signal;
+ ifmgd->ave_beacon_signal = rx_status->signal * 16;
ifmgd->last_cqm_event_signal = 0;
+ ifmgd->count_beacon_signal = 1;
} else {
ifmgd->ave_beacon_signal =
(IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
(16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
ifmgd->ave_beacon_signal) / 16;
+ ifmgd->count_beacon_signal++;
}
if (bss_conf->cqm_rssi_thold &&
+ ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
int sig = ifmgd->ave_beacon_signal / 16;
int last_event = ifmgd->last_cqm_event_signal;
@@ -1588,7 +1628,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
* Push the beacon loss detection into the future since
* we are processing a beacon from the AP just now.
*/
- mod_beacon_timer(sdata);
+ ieee80211_sta_reset_beacon_monitor(sdata);
ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
@@ -1599,7 +1639,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
ifmgd->aid);
- if (ncrc != ifmgd->beacon_crc) {
+ if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) {
ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
true);
@@ -1630,9 +1670,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
}
}
- if (ncrc == ifmgd->beacon_crc)
+ if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
return;
ifmgd->beacon_crc = ncrc;
+ ifmgd->beacon_crc_valid = true;
if (elems.erp_info && elems.erp_info_len >= 1) {
erp_valid = true;
@@ -1751,7 +1792,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct ieee80211_work *wk;
- mutex_lock(&local->work_mtx);
+ mutex_lock(&local->mtx);
list_for_each_entry(wk, &local->work_list, list) {
if (wk->sdata != sdata)
continue;
@@ -1783,7 +1824,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
free_work(wk);
break;
}
- mutex_unlock(&local->work_mtx);
+ mutex_unlock(&local->mtx);
cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
}
@@ -1823,10 +1864,12 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "No probe response from AP %pM"
- " after %dms, try %d\n", bssid,
- (1000 * IEEE80211_PROBE_WAIT)/HZ,
- ifmgd->probe_send_count);
+ wiphy_debug(local->hw.wiphy,
+ "%s: No probe response from AP %pM"
+ " after %dms, try %d\n",
+ sdata->name,
+ bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ,
+ ifmgd->probe_send_count);
#endif
ieee80211_mgd_probe_ap_send(sdata);
} else {
@@ -1836,12 +1879,16 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
*/
ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
IEEE80211_STA_BEACON_POLL);
- printk(KERN_DEBUG "No probe response from AP %pM"
- " after %dms, disconnecting.\n",
- bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
- ieee80211_set_disassoc(sdata, true);
- ieee80211_recalc_idle(local);
+ wiphy_debug(local->hw.wiphy,
+ "%s: No probe response from AP %pM"
+ " after %dms, disconnecting.\n",
+ sdata->name,
+ bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
+ ieee80211_set_disassoc(sdata, true, true);
mutex_unlock(&ifmgd->mtx);
+ mutex_lock(&local->mtx);
+ ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
/*
* must be outside lock due to cfg80211,
* but that's not a problem.
@@ -1917,6 +1964,8 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
* time -- the code here is properly synchronised.
*/
+ cancel_work_sync(&ifmgd->request_smps_work);
+
cancel_work_sync(&ifmgd->beacon_connection_loss_work);
if (del_timer_sync(&ifmgd->timer))
set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
@@ -1952,6 +2001,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
INIT_WORK(&ifmgd->beacon_connection_loss_work,
ieee80211_beacon_connection_loss_work);
+ INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_work);
setup_timer(&ifmgd->timer, ieee80211_sta_timer,
(unsigned long) sdata);
setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
@@ -2158,7 +2208,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
}
/* Trying to reassociate - clear previous association state */
- ieee80211_set_disassoc(sdata, true);
+ ieee80211_set_disassoc(sdata, true, false);
}
mutex_unlock(&ifmgd->mtx);
@@ -2169,6 +2219,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
+ ifmgd->beacon_crc_valid = false;
+
for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
@@ -2249,6 +2301,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
else
ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT;
+ sdata->control_port_protocol = req->crypto.control_port_ethertype;
+ sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
+
ieee80211_add_work(wk);
return 0;
}
@@ -2267,7 +2322,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
memcpy(bssid, req->bss->bssid, ETH_ALEN);
if (ifmgd->associated == req->bss) {
- ieee80211_set_disassoc(sdata, false);
+ ieee80211_set_disassoc(sdata, false, true);
mutex_unlock(&ifmgd->mtx);
assoc_bss = true;
} else {
@@ -2275,7 +2330,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
mutex_unlock(&ifmgd->mtx);
- mutex_lock(&local->work_mtx);
+ mutex_lock(&local->mtx);
list_for_each_entry(wk, &local->work_list, list) {
if (wk->sdata != sdata)
continue;
@@ -2294,7 +2349,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
free_work(wk);
break;
}
- mutex_unlock(&local->work_mtx);
+ mutex_unlock(&local->mtx);
/*
* If somebody requests authentication and we haven't
@@ -2319,7 +2374,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
if (assoc_bss)
sta_info_destroy_addr(sdata, bssid);
+ mutex_lock(&sdata->local->mtx);
ieee80211_recalc_idle(sdata->local);
+ mutex_unlock(&sdata->local->mtx);
return 0;
}
@@ -2348,7 +2405,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
sdata->name, req->bss->bssid, req->reason_code);
memcpy(bssid, req->bss->bssid, ETH_ALEN);
- ieee80211_set_disassoc(sdata, false);
+ ieee80211_set_disassoc(sdata, false, true);
mutex_unlock(&ifmgd->mtx);
@@ -2357,7 +2414,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
cookie, !req->local_state_change);
sta_info_destroy_addr(sdata, bssid);
+ mutex_lock(&sdata->local->mtx);
ieee80211_recalc_idle(sdata->local);
+ mutex_unlock(&sdata->local->mtx);
return 0;
}
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index c36b1911987a..4b564091e51d 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -22,12 +22,16 @@
static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
local->offchannel_ps_enabled = false;
/* FIXME: what to do when local->pspolling is true? */
del_timer_sync(&local->dynamic_ps_timer);
+ del_timer_sync(&ifmgd->bcn_mon_timer);
+ del_timer_sync(&ifmgd->conn_mon_timer);
+
cancel_work_sync(&local->dynamic_ps_enable_work);
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
@@ -85,6 +89,9 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
mod_timer(&local->dynamic_ps_timer, jiffies +
msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
}
+
+ ieee80211_sta_reset_beacon_monitor(sdata);
+ ieee80211_sta_reset_conn_monitor(sdata);
}
void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local)
@@ -112,8 +119,10 @@ void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local)
* used from user space controlled off-channel operations.
*/
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
- sdata->vif.type != NL80211_IFTYPE_MONITOR)
+ sdata->vif.type != NL80211_IFTYPE_MONITOR) {
+ set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
netif_tx_stop_all_queues(sdata->dev);
+ }
}
mutex_unlock(&local->iflist_mtx);
}
@@ -131,6 +140,7 @@ void ieee80211_offchannel_stop_station(struct ieee80211_local *local)
continue;
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+ set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
netif_tx_stop_all_queues(sdata->dev);
if (sdata->u.mgd.associated)
ieee80211_offchannel_ps_enable(sdata);
@@ -155,8 +165,20 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
ieee80211_offchannel_ps_disable(sdata);
}
- if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
+ if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
+ clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
+ /*
+ * This may wake up queues even though the driver
+ * currently has them stopped. This is not very
+ * likely, since the driver won't have gotten any
+ * (or hardly any) new packets while we weren't
+ * on the right channel, and even if it happens
+ * it will at most lead to queueing up one more
+ * packet per queue in mac80211 rather than on
+ * the interface qdisc.
+ */
netif_tx_wake_all_queues(sdata->dev);
+ }
/* re-enable beaconing */
if (enable_beaconing &&
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index d287fde0431d..e37355193ed1 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -45,7 +45,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
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);
+ ieee80211_sta_tear_down_BA_sessions(sta, true);
}
if (sta->uploaded) {
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 334cbd3d2aae..809cf230d251 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -208,7 +208,7 @@ static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc)
fc = hdr->frame_control;
- return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc));
+ return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc);
}
static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx)
@@ -369,8 +369,8 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
ref = rate_control_alloc(name, local);
if (!ref) {
- printk(KERN_WARNING "%s: Failed to select rate control "
- "algorithm\n", wiphy_name(local->hw.wiphy));
+ wiphy_warn(local->hw.wiphy,
+ "Failed to select rate control algorithm\n");
return -ENOENT;
}
@@ -381,9 +381,8 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
sta_info_flush(local, NULL);
}
- printk(KERN_DEBUG "%s: Selected rate control "
- "algorithm '%s'\n", wiphy_name(local->hw.wiphy),
- ref->ops->name);
+ wiphy_debug(local->hw.wiphy, "Selected rate control algorithm '%s'\n",
+ ref->ops->name);
return 0;
}
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index c5b465904e3b..2a18d6602d4a 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
!(info->flags & IEEE80211_TX_STAT_AMPDU))
return;
- if (!info->status.ampdu_len) {
- info->status.ampdu_ack_len = 1;
+ if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) {
+ info->status.ampdu_ack_len =
+ (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
info->status.ampdu_len = 1;
}
@@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
group = minstrel_ht_get_group_idx(&ar[i]);
rate = &mi->groups[group].rates[ar[i].idx % 8];
- if (last && (info->flags & IEEE80211_TX_STAT_ACK))
+ if (last)
rate->success += info->status.ampdu_ack_len;
rate->attempts += ar[i].count * info->status.ampdu_len;
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
index 7905f79cc2e4..4851e9e2daed 100644
--- a/net/mac80211/rc80211_pid_debugfs.c
+++ b/net/mac80211/rc80211_pid_debugfs.c
@@ -162,7 +162,7 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf,
file_info->next_entry = (file_info->next_entry + 1) %
RC_PID_EVENT_RING_SIZE;
- /* Print information about the event. Note that userpace needs to
+ /* Print information about the event. Note that userspace needs to
* provide large enough buffers. */
length = length < RC_PID_PRINT_BUF_SIZE ?
length : RC_PID_PRINT_BUF_SIZE;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 28624282c5f3..902b03ee8f60 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -315,6 +315,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
int tid;
/* does the frame have a qos control field? */
@@ -323,9 +324,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
/* frame has qos control */
tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
- rx->flags |= IEEE80211_RX_AMSDU;
- else
- rx->flags &= ~IEEE80211_RX_AMSDU;
+ status->rx_flags |= IEEE80211_RX_AMSDU;
} else {
/*
* IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"):
@@ -387,26 +386,25 @@ static ieee80211_rx_result debug_noinline
ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
{
struct ieee80211_local *local = rx->local;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
struct sk_buff *skb = rx->skb;
- if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning)))
+ if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN)))
+ return RX_CONTINUE;
+
+ if (test_bit(SCAN_HW_SCANNING, &local->scanning))
return ieee80211_scan_rx(rx->sdata, skb);
- if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning) &&
- (rx->flags & IEEE80211_RX_IN_SCAN))) {
+ if (test_bit(SCAN_SW_SCANNING, &local->scanning)) {
/* drop all the other packets during a software scan anyway */
if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED)
dev_kfree_skb(skb);
return RX_QUEUED;
}
- if (unlikely(rx->flags & IEEE80211_RX_IN_SCAN)) {
- /* scanning finished during invoking of handlers */
- I802_DEBUG_INC(local->rx_handlers_drop_passive_scan);
- return RX_DROP_UNUSABLE;
- }
-
- return RX_CONTINUE;
+ /* scanning finished during invoking of handlers */
+ I802_DEBUG_INC(local->rx_handlers_drop_passive_scan);
+ return RX_DROP_UNUSABLE;
}
@@ -538,20 +536,12 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
int index,
struct sk_buff_head *frames)
{
- struct ieee80211_supported_band *sband;
- struct ieee80211_rate *rate = NULL;
struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
- struct ieee80211_rx_status *status;
if (!skb)
goto no_frame;
- status = IEEE80211_SKB_RXCB(skb);
-
- /* release the reordered frames to stack */
- sband = hw->wiphy->bands[status->band];
- if (!(status->flag & RX_FLAG_HT))
- rate = &sband->bitrates[status->rate_idx];
+ /* release the frame from the reorder ring buffer */
tid_agg_rx->stored_mpdu_num--;
tid_agg_rx->reorder_buf[index] = NULL;
__skb_queue_tail(frames, skb);
@@ -580,9 +570,102 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
* frames that have not yet been received are assumed to be lost and the skb
* can be released for processing. This may also release other skb's from the
* reorder buffer if there are no additional gaps between the frames.
+ *
+ * Callers must hold tid_agg_rx->reorder_lock.
*/
#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
+static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
+ struct tid_ampdu_rx *tid_agg_rx,
+ struct sk_buff_head *frames)
+{
+ int index, j;
+
+ /* release the buffer until next missing frame */
+ index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
+ tid_agg_rx->buf_size;
+ if (!tid_agg_rx->reorder_buf[index] &&
+ tid_agg_rx->stored_mpdu_num > 1) {
+ /*
+ * No buffers ready to be released, but check whether any
+ * frames in the reorder buffer have timed out.
+ */
+ int skipped = 1;
+ for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
+ j = (j + 1) % tid_agg_rx->buf_size) {
+ if (!tid_agg_rx->reorder_buf[j]) {
+ skipped++;
+ continue;
+ }
+ if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
+ HT_RX_REORDER_BUF_TIMEOUT))
+ goto set_release_timer;
+
+#ifdef CONFIG_MAC80211_HT_DEBUG
+ if (net_ratelimit())
+ wiphy_debug(hw->wiphy,
+ "release an RX reorder frame due to timeout on earlier frames\n");
+#endif
+ ieee80211_release_reorder_frame(hw, tid_agg_rx,
+ j, frames);
+
+ /*
+ * Increment the head seq# also for the skipped slots.
+ */
+ tid_agg_rx->head_seq_num =
+ (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK;
+ skipped = 0;
+ }
+ } else while (tid_agg_rx->reorder_buf[index]) {
+ ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames);
+ index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
+ tid_agg_rx->buf_size;
+ }
+
+ /*
+ * Disable the reorder release timer for now.
+ *
+ * The current implementation lacks a proper locking scheme
+ * which would protect vital statistic and debug counters
+ * from being updated by two different but concurrent BHs.
+ *
+ * More information about the topic is available from:
+ * - thread: http://marc.info/?t=128635927000001
+ *
+ * What was wrong:
+ * => http://marc.info/?l=linux-wireless&m=128636170811964
+ * "Basically the thing is that until your patch, the data
+ * in the struct didn't actually need locking because it
+ * was accessed by the RX path only which is not concurrent."
+ *
+ * List of what needs to be fixed:
+ * => http://marc.info/?l=linux-wireless&m=128656352920957
+ *
+
+ if (tid_agg_rx->stored_mpdu_num) {
+ j = index = seq_sub(tid_agg_rx->head_seq_num,
+ tid_agg_rx->ssn) % tid_agg_rx->buf_size;
+
+ for (; j != (index - 1) % tid_agg_rx->buf_size;
+ j = (j + 1) % tid_agg_rx->buf_size) {
+ if (tid_agg_rx->reorder_buf[j])
+ break;
+ }
+
+ set_release_timer:
+
+ mod_timer(&tid_agg_rx->reorder_timer,
+ tid_agg_rx->reorder_time[j] +
+ HT_RX_REORDER_BUF_TIMEOUT);
+ } else {
+ del_timer(&tid_agg_rx->reorder_timer);
+ }
+ */
+
+set_release_timer:
+ return;
+}
+
/*
* As this function belongs to the RX path it must be under
* rcu_read_lock protection. It returns false if the frame
@@ -598,14 +681,16 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4;
u16 head_seq_num, buf_size;
int index;
+ bool ret = true;
buf_size = tid_agg_rx->buf_size;
head_seq_num = tid_agg_rx->head_seq_num;
+ spin_lock(&tid_agg_rx->reorder_lock);
/* frame with out of date sequence number */
if (seq_less(mpdu_seq_num, head_seq_num)) {
dev_kfree_skb(skb);
- return true;
+ goto out;
}
/*
@@ -626,7 +711,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
/* check if we already stored this frame */
if (tid_agg_rx->reorder_buf[index]) {
dev_kfree_skb(skb);
- return true;
+ goto out;
}
/*
@@ -636,58 +721,19 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
if (mpdu_seq_num == tid_agg_rx->head_seq_num &&
tid_agg_rx->stored_mpdu_num == 0) {
tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
- return false;
+ ret = false;
+ goto out;
}
/* put the frame in the reordering buffer */
tid_agg_rx->reorder_buf[index] = skb;
tid_agg_rx->reorder_time[index] = jiffies;
tid_agg_rx->stored_mpdu_num++;
- /* release the buffer until next missing frame */
- index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
- tid_agg_rx->buf_size;
- if (!tid_agg_rx->reorder_buf[index] &&
- tid_agg_rx->stored_mpdu_num > 1) {
- /*
- * No buffers ready to be released, but check whether any
- * frames in the reorder buffer have timed out.
- */
- int j;
- int skipped = 1;
- for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
- j = (j + 1) % tid_agg_rx->buf_size) {
- if (!tid_agg_rx->reorder_buf[j]) {
- skipped++;
- continue;
- }
- if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
- HT_RX_REORDER_BUF_TIMEOUT))
- break;
+ ieee80211_sta_reorder_release(hw, tid_agg_rx, frames);
-#ifdef CONFIG_MAC80211_HT_DEBUG
- if (net_ratelimit())
- printk(KERN_DEBUG "%s: release an RX reorder "
- "frame due to timeout on earlier "
- "frames\n",
- wiphy_name(hw->wiphy));
-#endif
- ieee80211_release_reorder_frame(hw, tid_agg_rx,
- j, frames);
-
- /*
- * Increment the head seq# also for the skipped slots.
- */
- tid_agg_rx->head_seq_num =
- (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK;
- skipped = 0;
- }
- } else while (tid_agg_rx->reorder_buf[index]) {
- ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames);
- index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
- tid_agg_rx->buf_size;
- }
-
- return true;
+ out:
+ spin_unlock(&tid_agg_rx->reorder_lock);
+ return ret;
}
/*
@@ -761,13 +807,14 @@ static ieee80211_rx_result debug_noinline
ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
/* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) {
if (unlikely(ieee80211_has_retry(hdr->frame_control) &&
rx->sta->last_seq_ctrl[rx->queue] ==
hdr->seq_ctrl)) {
- if (rx->flags & IEEE80211_RX_RA_MATCH) {
+ if (status->rx_flags & IEEE80211_RX_RA_MATCH) {
rx->local->dot11FrameDuplicateCount++;
rx->sta->num_duplicates++;
}
@@ -796,11 +843,12 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
if (unlikely((ieee80211_is_data(hdr->frame_control) ||
ieee80211_is_pspoll(hdr->frame_control)) &&
rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+ rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
(!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
if ((!ieee80211_has_fromds(hdr->frame_control) &&
!ieee80211_has_tods(hdr->frame_control) &&
ieee80211_is_data(hdr->frame_control)) ||
- !(rx->flags & IEEE80211_RX_RA_MATCH)) {
+ !(status->rx_flags & IEEE80211_RX_RA_MATCH)) {
/* Drop IBSS frames and frames for other hosts
* silently. */
return RX_DROP_MONITOR;
@@ -822,7 +870,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
int keyidx;
int hdrlen;
ieee80211_rx_result result = RX_DROP_UNUSABLE;
- struct ieee80211_key *stakey = NULL;
+ struct ieee80211_key *sta_ptk = NULL;
int mmie_keyidx = -1;
__le16 fc;
@@ -857,22 +905,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
* No point in finding a key and decrypting if the frame is neither
* addressed to us nor a multicast frame.
*/
- if (!(rx->flags & IEEE80211_RX_RA_MATCH))
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
return RX_CONTINUE;
/* start without a key */
rx->key = NULL;
if (rx->sta)
- stakey = rcu_dereference(rx->sta->key);
+ sta_ptk = rcu_dereference(rx->sta->ptk);
fc = hdr->frame_control;
if (!ieee80211_has_protected(fc))
mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
- if (!is_multicast_ether_addr(hdr->addr1) && stakey) {
- rx->key = stakey;
+ if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) {
+ rx->key = sta_ptk;
+ if ((status->flag & RX_FLAG_DECRYPTED) &&
+ (status->flag & RX_FLAG_IV_STRIPPED))
+ return RX_CONTINUE;
/* Skip decryption if the frame is not protected. */
if (!ieee80211_has_protected(fc))
return RX_CONTINUE;
@@ -885,7 +936,10 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
if (mmie_keyidx < NUM_DEFAULT_KEYS ||
mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
return RX_DROP_MONITOR; /* unexpected BIP keyidx */
- rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
+ if (rx->sta)
+ rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]);
+ if (!rx->key)
+ rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
} else if (!ieee80211_has_protected(fc)) {
/*
* The frame was not protected, so skip decryption. However, we
@@ -928,16 +982,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
keyidx = keyid >> 6;
- rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
+ /* check per-station GTK first, if multicast packet */
+ if (is_multicast_ether_addr(hdr->addr1) && rx->sta)
+ rx->key = rcu_dereference(rx->sta->gtk[keyidx]);
- /*
- * RSNA-protected unicast frames should always be sent with
- * pairwise or station-to-station keys, but for WEP we allow
- * using a key index as well.
- */
- if (rx->key && rx->key->conf.alg != ALG_WEP &&
- !is_multicast_ether_addr(hdr->addr1))
- rx->key = NULL;
+ /* if not found, try default key */
+ if (!rx->key) {
+ rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
+
+ /*
+ * RSNA-protected unicast frames should always be
+ * sent with pairwise or station-to-station keys,
+ * but for WEP we allow using a key index as well.
+ */
+ if (rx->key &&
+ rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 &&
+ rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 &&
+ !is_multicast_ether_addr(hdr->addr1))
+ rx->key = NULL;
+ }
}
if (rx->key) {
@@ -951,8 +1014,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
return RX_DROP_UNUSABLE;
/* the hdr variable is invalid now! */
- switch (rx->key->conf.alg) {
- case ALG_WEP:
+ switch (rx->key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
/* Check for weak IVs if possible */
if (rx->sta && ieee80211_is_data(fc) &&
(!(status->flag & RX_FLAG_IV_STRIPPED) ||
@@ -962,15 +1026,21 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
result = ieee80211_crypto_wep_decrypt(rx);
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
result = ieee80211_crypto_tkip_decrypt(rx);
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
result = ieee80211_crypto_ccmp_decrypt(rx);
break;
- case ALG_AES_CMAC:
+ case WLAN_CIPHER_SUITE_AES_CMAC:
result = ieee80211_crypto_aes_cmac_decrypt(rx);
break;
+ default:
+ /*
+ * We can reach here only with HW-only algorithms
+ * but why didn't it decrypt the frame?!
+ */
+ return RX_DROP_UNUSABLE;
}
/* either the frame has been decrypted or will be dropped */
@@ -1079,7 +1149,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
sta->last_rx = jiffies;
}
- if (!(rx->flags & IEEE80211_RX_RA_MATCH))
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
return RX_CONTINUE;
if (rx->sdata->vif.type == NL80211_IFTYPE_STATION)
@@ -1236,6 +1306,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
unsigned int frag, seq;
struct ieee80211_fragment_entry *entry;
struct sk_buff *skb;
+ struct ieee80211_rx_status *status;
hdr = (struct ieee80211_hdr *)rx->skb->data;
fc = hdr->frame_control;
@@ -1265,7 +1336,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
/* This is the first fragment of a new frame. */
entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
rx->queue, &(rx->skb));
- if (rx->key && rx->key->conf.alg == ALG_CCMP &&
+ if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP &&
ieee80211_has_protected(fc)) {
int queue = ieee80211_is_mgmt(fc) ?
NUM_RX_DATA_QUEUES : rx->queue;
@@ -1294,7 +1365,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
int i;
u8 pn[CCMP_PN_LEN], *rpn;
int queue;
- if (!rx->key || rx->key->conf.alg != ALG_CCMP)
+ if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP)
return RX_DROP_UNUSABLE;
memcpy(pn, entry->last_pn, CCMP_PN_LEN);
for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
@@ -1335,7 +1406,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
}
/* Complete frame has been reassembled - process it now */
- rx->flags |= IEEE80211_RX_FRAGMENTED;
+ status = IEEE80211_SKB_RXCB(rx->skb);
+ status->rx_flags |= IEEE80211_RX_FRAGMENTED;
out:
if (rx->sta)
@@ -1352,9 +1424,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
{
struct ieee80211_sub_if_data *sdata = rx->sdata;
__le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
if (likely(!rx->sta || !ieee80211_is_pspoll(fc) ||
- !(rx->flags & IEEE80211_RX_RA_MATCH)))
+ !(status->rx_flags & IEEE80211_RX_RA_MATCH)))
return RX_CONTINUE;
if ((sdata->vif.type != NL80211_IFTYPE_AP) &&
@@ -1492,7 +1565,7 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc)
* Allow EAPOL frames to us/the PAE group address regardless
* of whether the frame was encrypted or not.
*/
- if (ehdr->h_proto == htons(ETH_P_PAE) &&
+ if (ehdr->h_proto == rx->sdata->control_port_protocol &&
(compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 ||
compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0))
return true;
@@ -1515,6 +1588,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
struct sk_buff *skb, *xmit_skb;
struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
struct sta_info *dsta;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
skb = rx->skb;
xmit_skb = NULL;
@@ -1522,7 +1596,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
if ((sdata->vif.type == NL80211_IFTYPE_AP ||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
!(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
- (rx->flags & IEEE80211_RX_RA_MATCH) &&
+ (status->rx_flags & IEEE80211_RX_RA_MATCH) &&
(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) {
if (is_multicast_ether_addr(ehdr->h_dest)) {
/*
@@ -1599,6 +1673,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
__le16 fc = hdr->frame_control;
struct sk_buff_head frame_list;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
if (unlikely(!ieee80211_is_data(fc)))
return RX_CONTINUE;
@@ -1606,7 +1681,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
if (unlikely(!ieee80211_is_data_present(fc)))
return RX_DROP_MONITOR;
- if (!(rx->flags & IEEE80211_RX_AMSDU))
+ if (!(status->rx_flags & IEEE80211_RX_AMSDU))
return RX_CONTINUE;
if (ieee80211_has_a4(hdr->frame_control) &&
@@ -1657,6 +1732,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
struct sk_buff *skb = rx->skb, *fwd_skb;
struct ieee80211_local *local = rx->local;
struct ieee80211_sub_if_data *sdata = rx->sdata;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -1702,7 +1778,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
mesh_hdr->ttl--;
- if (rx->flags & IEEE80211_RX_RA_MATCH) {
+ if (status->rx_flags & IEEE80211_RX_RA_MATCH) {
if (!mesh_hdr->ttl)
IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh,
dropped_frames_ttl);
@@ -1909,13 +1985,38 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,
}
static ieee80211_rx_result debug_noinline
+ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+
+ /*
+ * From here on, look only at management frames.
+ * Data and control frames are already handled,
+ * and unknown (reserved) frames are useless.
+ */
+ if (rx->skb->len < 24)
+ return RX_DROP_MONITOR;
+
+ if (!ieee80211_is_mgmt(mgmt->frame_control))
+ return RX_DROP_MONITOR;
+
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
+ return RX_DROP_MONITOR;
+
+ if (ieee80211_drop_unencrypted_mgmt(rx))
+ return RX_DROP_UNUSABLE;
+
+ return RX_CONTINUE;
+}
+
+static ieee80211_rx_result debug_noinline
ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
{
struct ieee80211_local *local = rx->local;
struct ieee80211_sub_if_data *sdata = rx->sdata;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
- struct sk_buff *nskb;
- struct ieee80211_rx_status *status;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
int len = rx->skb->len;
if (!ieee80211_is_action(mgmt->frame_control))
@@ -1928,10 +2029,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)
return RX_DROP_UNUSABLE;
- if (!(rx->flags & IEEE80211_RX_RA_MATCH))
- return RX_DROP_UNUSABLE;
-
- if (ieee80211_drop_unencrypted_mgmt(rx))
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
return RX_DROP_UNUSABLE;
switch (mgmt->u.action.category) {
@@ -2024,17 +2122,36 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
goto queue;
}
+ return RX_CONTINUE;
+
invalid:
- /*
- * For AP mode, hostapd is responsible for handling any action
- * frames that we didn't handle, including returning unknown
- * ones. For all other modes we will return them to the sender,
- * setting the 0x80 bit in the action category, as required by
- * 802.11-2007 7.3.1.11.
- */
- if (sdata->vif.type == NL80211_IFTYPE_AP ||
- sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- return RX_DROP_MONITOR;
+ status->rx_flags |= IEEE80211_RX_MALFORMED_ACTION_FRM;
+ /* will return in the next handlers */
+ return RX_CONTINUE;
+
+ handled:
+ if (rx->sta)
+ rx->sta->rx_packets++;
+ dev_kfree_skb(rx->skb);
+ return RX_QUEUED;
+
+ queue:
+ rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME;
+ skb_queue_tail(&sdata->skb_queue, rx->skb);
+ ieee80211_queue_work(&local->hw, &sdata->work);
+ if (rx->sta)
+ rx->sta->rx_packets++;
+ return RX_QUEUED;
+}
+
+static ieee80211_rx_result debug_noinline
+ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
+{
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+
+ /* skip known-bad action frames and return them in the next handler */
+ if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM)
+ return RX_CONTINUE;
/*
* Getting here means the kernel doesn't know how to handle
@@ -2042,12 +2159,46 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
* so userspace can register for those to know whether ones
* it transmitted were processed or returned.
*/
- status = IEEE80211_SKB_RXCB(rx->skb);
- if (cfg80211_rx_action(rx->sdata->dev, status->freq,
- rx->skb->data, rx->skb->len,
- GFP_ATOMIC))
- goto handled;
+ if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq,
+ rx->skb->data, rx->skb->len,
+ GFP_ATOMIC)) {
+ if (rx->sta)
+ rx->sta->rx_packets++;
+ dev_kfree_skb(rx->skb);
+ return RX_QUEUED;
+ }
+
+
+ return RX_CONTINUE;
+}
+
+static ieee80211_rx_result debug_noinline
+ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx)
+{
+ struct ieee80211_local *local = rx->local;
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
+ struct sk_buff *nskb;
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+
+ if (!ieee80211_is_action(mgmt->frame_control))
+ return RX_CONTINUE;
+
+ /*
+ * For AP mode, hostapd is responsible for handling any action
+ * frames that we didn't handle, including returning unknown
+ * ones. For all other modes we will return them to the sender,
+ * setting the 0x80 bit in the action category, as required by
+ * 802.11-2007 7.3.1.11.
+ * Newer versions of hostapd shall also use the management frame
+ * registration mechanisms, but older ones still use cooked
+ * monitor interfaces so push all frames there.
+ */
+ if (!(status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) &&
+ (sdata->vif.type == NL80211_IFTYPE_AP ||
+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
+ return RX_DROP_MONITOR;
/* do not return rejected action frames */
if (mgmt->u.action.category & 0x80)
@@ -2066,20 +2217,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
ieee80211_tx_skb(rx->sdata, nskb);
}
-
- handled:
- if (rx->sta)
- rx->sta->rx_packets++;
dev_kfree_skb(rx->skb);
return RX_QUEUED;
-
- queue:
- rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME;
- skb_queue_tail(&sdata->skb_queue, rx->skb);
- ieee80211_queue_work(&local->hw, &sdata->work);
- if (rx->sta)
- rx->sta->rx_packets++;
- return RX_QUEUED;
}
static ieee80211_rx_result debug_noinline
@@ -2090,15 +2229,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
struct ieee80211_mgmt *mgmt = (void *)rx->skb->data;
__le16 stype;
- if (!(rx->flags & IEEE80211_RX_RA_MATCH))
- return RX_DROP_MONITOR;
-
- if (rx->skb->len < 24)
- return RX_DROP_MONITOR;
-
- if (ieee80211_drop_unencrypted_mgmt(rx))
- return RX_DROP_UNUSABLE;
-
rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb);
if (rxs != RX_CONTINUE)
return rxs;
@@ -2199,6 +2329,14 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
struct net_device *prev_dev = NULL;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ /*
+ * If cooked monitor has been processed already, then
+ * don't do it again. If not, set the flag.
+ */
+ if (rx->flags & IEEE80211_RX_CMNTR)
+ goto out_free_skb;
+ rx->flags |= IEEE80211_RX_CMNTR;
+
if (skb_headroom(skb) < sizeof(*rthdr) &&
pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC))
goto out_free_skb;
@@ -2253,29 +2391,53 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
if (prev_dev) {
skb->dev = prev_dev;
netif_receive_skb(skb);
- skb = NULL;
- } else
- goto out_free_skb;
-
- return;
+ return;
+ }
out_free_skb:
dev_kfree_skb(skb);
}
+static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
+ ieee80211_rx_result res)
+{
+ switch (res) {
+ case RX_DROP_MONITOR:
+ I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
+ if (rx->sta)
+ rx->sta->rx_dropped++;
+ /* fall through */
+ case RX_CONTINUE: {
+ struct ieee80211_rate *rate = NULL;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_rx_status *status;
+
+ status = IEEE80211_SKB_RXCB((rx->skb));
+
+ sband = rx->local->hw.wiphy->bands[status->band];
+ if (!(status->flag & RX_FLAG_HT))
+ rate = &sband->bitrates[status->rate_idx];
+
+ ieee80211_rx_cooked_monitor(rx, rate);
+ break;
+ }
+ case RX_DROP_UNUSABLE:
+ I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
+ if (rx->sta)
+ rx->sta->rx_dropped++;
+ dev_kfree_skb(rx->skb);
+ break;
+ case RX_QUEUED:
+ I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
+ break;
+ }
+}
-static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_rx_data *rx,
- struct sk_buff *skb,
- struct ieee80211_rate *rate)
+static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
+ struct sk_buff_head *frames)
{
- struct sk_buff_head reorder_release;
ieee80211_rx_result res = RX_DROP_MONITOR;
-
- __skb_queue_head_init(&reorder_release);
-
- rx->skb = skb;
- rx->sdata = sdata;
+ struct sk_buff *skb;
#define CALL_RXH(rxh) \
do { \
@@ -2284,23 +2446,14 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
goto rxh_next; \
} while (0);
- /*
- * NB: the rxh_next label works even if we jump
- * to it from here because then the list will
- * be empty, which is a trivial check
- */
- CALL_RXH(ieee80211_rx_h_passive_scan)
- CALL_RXH(ieee80211_rx_h_check)
-
- ieee80211_rx_reorder_ampdu(rx, &reorder_release);
-
- while ((skb = __skb_dequeue(&reorder_release))) {
+ while ((skb = __skb_dequeue(frames))) {
/*
* all the other fields are valid across frames
* that belong to an aMPDU since they are on the
* same TID from the same station
*/
rx->skb = skb;
+ rx->flags = 0;
CALL_RXH(ieee80211_rx_h_decrypt)
CALL_RXH(ieee80211_rx_h_check_more_data)
@@ -2312,50 +2465,92 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
CALL_RXH(ieee80211_rx_h_remove_qos_control)
CALL_RXH(ieee80211_rx_h_amsdu)
#ifdef CONFIG_MAC80211_MESH
- if (ieee80211_vif_is_mesh(&sdata->vif))
+ if (ieee80211_vif_is_mesh(&rx->sdata->vif))
CALL_RXH(ieee80211_rx_h_mesh_fwding);
#endif
CALL_RXH(ieee80211_rx_h_data)
/* special treatment -- needs the queue */
- res = ieee80211_rx_h_ctrl(rx, &reorder_release);
+ res = ieee80211_rx_h_ctrl(rx, frames);
if (res != RX_CONTINUE)
goto rxh_next;
+ CALL_RXH(ieee80211_rx_h_mgmt_check)
CALL_RXH(ieee80211_rx_h_action)
+ CALL_RXH(ieee80211_rx_h_userspace_mgmt)
+ CALL_RXH(ieee80211_rx_h_action_return)
CALL_RXH(ieee80211_rx_h_mgmt)
+ rxh_next:
+ ieee80211_rx_handlers_result(rx, res);
+
#undef CALL_RXH
+ }
+}
+
+static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
+{
+ struct sk_buff_head reorder_release;
+ ieee80211_rx_result res = RX_DROP_MONITOR;
+
+ __skb_queue_head_init(&reorder_release);
+
+#define CALL_RXH(rxh) \
+ do { \
+ res = rxh(rx); \
+ if (res != RX_CONTINUE) \
+ goto rxh_next; \
+ } while (0);
+
+ CALL_RXH(ieee80211_rx_h_passive_scan)
+ CALL_RXH(ieee80211_rx_h_check)
+
+ ieee80211_rx_reorder_ampdu(rx, &reorder_release);
+
+ ieee80211_rx_handlers(rx, &reorder_release);
+ return;
rxh_next:
- switch (res) {
- case RX_DROP_MONITOR:
- I802_DEBUG_INC(sdata->local->rx_handlers_drop);
- if (rx->sta)
- rx->sta->rx_dropped++;
- /* fall through */
- case RX_CONTINUE:
- ieee80211_rx_cooked_monitor(rx, rate);
- break;
- case RX_DROP_UNUSABLE:
- I802_DEBUG_INC(sdata->local->rx_handlers_drop);
- if (rx->sta)
- rx->sta->rx_dropped++;
- dev_kfree_skb(rx->skb);
- break;
- case RX_QUEUED:
- I802_DEBUG_INC(sdata->local->rx_handlers_queued);
- break;
- }
- }
+ ieee80211_rx_handlers_result(rx, res);
+
+#undef CALL_RXH
+}
+
+/*
+ * This function makes calls into the RX path. Therefore the
+ * caller must hold the sta_info->lock and everything has to
+ * be under rcu_read_lock protection as well.
+ */
+void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
+{
+ struct sk_buff_head frames;
+ struct ieee80211_rx_data rx = {
+ .sta = sta,
+ .sdata = sta->sdata,
+ .local = sta->local,
+ .queue = tid,
+ };
+ struct tid_ampdu_rx *tid_agg_rx;
+
+ tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
+ if (!tid_agg_rx)
+ return;
+
+ __skb_queue_head_init(&frames);
+
+ spin_lock(&tid_agg_rx->reorder_lock);
+ ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames);
+ spin_unlock(&tid_agg_rx->reorder_lock);
+
+ ieee80211_rx_handlers(&rx, &frames);
}
/* main receive path */
-static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_rx_data *rx,
+static int prepare_for_handlers(struct ieee80211_rx_data *rx,
struct ieee80211_hdr *hdr)
{
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
struct sk_buff *skb = rx->skb;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
@@ -2369,7 +2564,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) {
if (!(sdata->dev->flags & IFF_PROMISC))
return 0;
- rx->flags &= ~IEEE80211_RX_RA_MATCH;
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
}
break;
case NL80211_IFTYPE_ADHOC:
@@ -2379,15 +2574,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
return 1;
}
else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) {
- if (!(rx->flags & IEEE80211_RX_IN_SCAN))
+ if (!(status->rx_flags & IEEE80211_RX_IN_SCAN))
return 0;
- rx->flags &= ~IEEE80211_RX_RA_MATCH;
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
} else if (!multicast &&
compare_ether_addr(sdata->vif.addr,
hdr->addr1) != 0) {
if (!(sdata->dev->flags & IFF_PROMISC))
return 0;
- rx->flags &= ~IEEE80211_RX_RA_MATCH;
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
} else if (!rx->sta) {
int rate_idx;
if (status->flag & RX_FLAG_HT)
@@ -2405,7 +2600,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
if (!(sdata->dev->flags & IFF_PROMISC))
return 0;
- rx->flags &= ~IEEE80211_RX_RA_MATCH;
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
}
break;
case NL80211_IFTYPE_AP_VLAN:
@@ -2416,9 +2611,9 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
return 0;
} else if (!ieee80211_bssid_match(bssid,
sdata->vif.addr)) {
- if (!(rx->flags & IEEE80211_RX_IN_SCAN))
+ if (!(status->rx_flags & IEEE80211_RX_IN_SCAN))
return 0;
- rx->flags &= ~IEEE80211_RX_RA_MATCH;
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
}
break;
case NL80211_IFTYPE_WDS:
@@ -2427,9 +2622,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
return 0;
break;
- case NL80211_IFTYPE_MONITOR:
- case NL80211_IFTYPE_UNSPECIFIED:
- case __NL80211_IFTYPE_AFTER_LAST:
+ default:
/* should never get here */
WARN_ON(1);
break;
@@ -2439,12 +2632,56 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
}
/*
+ * This function returns whether or not the SKB
+ * was destined for RX processing or not, which,
+ * if consume is true, is equivalent to whether
+ * or not the skb was consumed.
+ */
+static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
+ struct sk_buff *skb, bool consume)
+{
+ struct ieee80211_local *local = rx->local;
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ struct ieee80211_hdr *hdr = (void *)skb->data;
+ int prepares;
+
+ rx->skb = skb;
+ status->rx_flags |= IEEE80211_RX_RA_MATCH;
+ prepares = prepare_for_handlers(rx, hdr);
+
+ 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) {
+ if (net_ratelimit())
+ wiphy_debug(local->hw.wiphy,
+ "failed to copy multicast frame for %s\n",
+ sdata->name);
+ return true;
+ }
+
+ rx->skb = skb;
+ }
+
+ ieee80211_invoke_rx_handlers(rx);
+ return true;
+}
+
+/*
* This is the actual Rx frames handler. as it blongs to Rx path it must
* be called with rcu_read_lock protection.
*/
static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
- struct sk_buff *skb,
- struct ieee80211_rate *rate)
+ struct sk_buff *skb)
{
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_local *local = hw_to_local(hw);
@@ -2452,11 +2689,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr;
__le16 fc;
struct ieee80211_rx_data rx;
- int prepares;
- struct ieee80211_sub_if_data *prev = NULL;
- struct sk_buff *skb_new;
- struct sta_info *sta, *tmp;
- bool found_sta = false;
+ struct ieee80211_sub_if_data *prev;
+ struct sta_info *sta, *tmp, *prev_sta;
int err = 0;
fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
@@ -2469,7 +2703,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
- rx.flags |= IEEE80211_RX_IN_SCAN;
+ status->rx_flags |= IEEE80211_RX_IN_SCAN;
if (ieee80211_is_mgmt(fc))
err = skb_linearize(skb);
@@ -2486,91 +2720,67 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
ieee80211_verify_alignment(&rx);
if (ieee80211_is_data(fc)) {
+ prev_sta = NULL;
+
for_each_sta_info(local, hdr->addr2, sta, tmp) {
- rx.sta = sta;
- found_sta = true;
- rx.sdata = sta->sdata;
-
- rx.flags |= IEEE80211_RX_RA_MATCH;
- prepares = prepare_for_handlers(rx.sdata, &rx, hdr);
- if (prepares) {
- if (status->flag & RX_FLAG_MMIC_ERROR) {
- if (rx.flags & IEEE80211_RX_RA_MATCH)
- ieee80211_rx_michael_mic_report(hdr, &rx);
- } else
- prev = rx.sdata;
- }
- }
- }
- if (!found_sta) {
- list_for_each_entry_rcu(sdata, &local->interfaces, list) {
- if (!ieee80211_sdata_running(sdata))
+ if (!prev_sta) {
+ prev_sta = sta;
continue;
+ }
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
- sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- continue;
+ rx.sta = prev_sta;
+ rx.sdata = prev_sta->sdata;
+ ieee80211_prepare_and_rx_handle(&rx, skb, false);
- /*
- * frame is destined for this interface, but if it's
- * not also for the previous one we handle that after
- * the loop to avoid copying the SKB once too much
- */
+ prev_sta = sta;
+ }
- if (!prev) {
- prev = sdata;
- continue;
- }
+ if (prev_sta) {
+ rx.sta = prev_sta;
+ rx.sdata = prev_sta->sdata;
- rx.sta = sta_info_get_bss(prev, hdr->addr2);
+ if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
+ return;
+ }
+ }
- rx.flags |= IEEE80211_RX_RA_MATCH;
- prepares = prepare_for_handlers(prev, &rx, hdr);
+ prev = NULL;
- if (!prepares)
- goto next;
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ if (!ieee80211_sdata_running(sdata))
+ continue;
- if (status->flag & RX_FLAG_MMIC_ERROR) {
- rx.sdata = prev;
- if (rx.flags & IEEE80211_RX_RA_MATCH)
- ieee80211_rx_michael_mic_report(hdr,
- &rx);
- goto next;
- }
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ continue;
- /*
- * frame was destined for the previous interface
- * so invoke RX handlers for it
- */
+ /*
+ * frame is destined for this interface, but if it's
+ * not also for the previous one we handle that after
+ * the loop to avoid copying the SKB once too much
+ */
- skb_new = skb_copy(skb, GFP_ATOMIC);
- if (!skb_new) {
- if (net_ratelimit())
- printk(KERN_DEBUG "%s: failed to copy "
- "multicast frame for %s\n",
- wiphy_name(local->hw.wiphy),
- prev->name);
- goto next;
- }
- ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
-next:
+ if (!prev) {
prev = sdata;
+ continue;
}
- if (prev) {
- rx.sta = sta_info_get_bss(prev, hdr->addr2);
+ rx.sta = sta_info_get_bss(prev, hdr->addr2);
+ rx.sdata = prev;
+ ieee80211_prepare_and_rx_handle(&rx, skb, false);
- rx.flags |= IEEE80211_RX_RA_MATCH;
- prepares = prepare_for_handlers(prev, &rx, hdr);
+ prev = sdata;
+ }
- if (!prepares)
- prev = NULL;
- }
+ if (prev) {
+ rx.sta = sta_info_get_bss(prev, hdr->addr2);
+ rx.sdata = prev;
+
+ if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
+ return;
}
- if (prev)
- ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);
- else
- dev_kfree_skb(skb);
+
+ dev_kfree_skb(skb);
}
/*
@@ -2611,30 +2821,41 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (WARN_ON(!local->started))
goto drop;
- if (status->flag & RX_FLAG_HT) {
+ if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) {
/*
- * rate_idx is MCS index, which can be [0-76] as documented on:
- *
- * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n
- *
- * Anything else would be some sort of driver or hardware error.
- * The driver should catch hardware errors.
+ * Validate the rate, unless a PLCP error means that
+ * we probably can't have a valid rate here anyway.
*/
- if (WARN((status->rate_idx < 0 ||
- status->rate_idx > 76),
- "Rate marked as an HT rate but passed "
- "status->rate_idx is not "
- "an MCS index [0-76]: %d (0x%02x)\n",
- status->rate_idx,
- status->rate_idx))
- goto drop;
- } else {
- if (WARN_ON(status->rate_idx < 0 ||
- status->rate_idx >= sband->n_bitrates))
- goto drop;
- rate = &sband->bitrates[status->rate_idx];
+
+ if (status->flag & RX_FLAG_HT) {
+ /*
+ * rate_idx is MCS index, which can be [0-76]
+ * as documented on:
+ *
+ * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n
+ *
+ * Anything else would be some sort of driver or
+ * hardware error. The driver should catch hardware
+ * errors.
+ */
+ if (WARN((status->rate_idx < 0 ||
+ status->rate_idx > 76),
+ "Rate marked as an HT rate but passed "
+ "status->rate_idx is not "
+ "an MCS index [0-76]: %d (0x%02x)\n",
+ status->rate_idx,
+ status->rate_idx))
+ goto drop;
+ } else {
+ if (WARN_ON(status->rate_idx < 0 ||
+ status->rate_idx >= sband->n_bitrates))
+ goto drop;
+ rate = &sband->bitrates[status->rate_idx];
+ }
}
+ status->rx_flags = 0;
+
/*
* key references and virtual interfaces are protected using RCU
* and this requires that we are in a read-side RCU section during
@@ -2654,7 +2875,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
return;
}
- __ieee80211_rx_handle_packet(hw, skb, rate);
+ __ieee80211_rx_handle_packet(hw, skb);
rcu_read_unlock();
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 872d7b6ef6b3..fb274db77e3c 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -242,20 +242,19 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
local->hw_scan_req->n_channels = n_chans;
ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
- req->ie, req->ie_len, band);
+ req->ie, req->ie_len, band, (u32) -1,
+ 0);
local->hw_scan_req->ie_len = ielen;
return true;
}
-void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
+static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
+ bool was_hw_scan)
{
struct ieee80211_local *local = hw_to_local(hw);
- bool was_hw_scan;
-
- trace_api_scan_completed(local, aborted);
- mutex_lock(&local->scan_mtx);
+ lockdep_assert_held(&local->mtx);
/*
* It's ok to abort a not-yet-running scan (that
@@ -266,17 +265,13 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
if (WARN_ON(!local->scanning && !aborted))
aborted = true;
- if (WARN_ON(!local->scan_req)) {
- mutex_unlock(&local->scan_mtx);
- return;
- }
+ if (WARN_ON(!local->scan_req))
+ return false;
- was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
- ieee80211_queue_delayed_work(&local->hw,
- &local->scan_work, 0);
- mutex_unlock(&local->scan_mtx);
- return;
+ int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req);
+ if (rc == 0)
+ return false;
}
kfree(local->hw_scan_req);
@@ -290,26 +285,42 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
local->scanning = 0;
local->scan_channel = NULL;
- /* we only have to protect scan_req and hw/sw scan */
- mutex_unlock(&local->scan_mtx);
-
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
- if (was_hw_scan)
- goto done;
-
- ieee80211_configure_filter(local);
+ return true;
+}
- drv_sw_scan_complete(local);
+static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw,
+ bool was_hw_scan)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
- ieee80211_offchannel_return(local, true);
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
+ if (!was_hw_scan) {
+ ieee80211_configure_filter(local);
+ drv_sw_scan_complete(local);
+ ieee80211_offchannel_return(local, true);
+ }
- done:
+ mutex_lock(&local->mtx);
ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
+
ieee80211_mlme_notify_scan_completed(local);
ieee80211_ibss_notify_scan_completed(local);
ieee80211_mesh_notify_scan_completed(local);
ieee80211_queue_work(&local->hw, &local->work_work);
}
+
+void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ trace_api_scan_completed(local, aborted);
+
+ set_bit(SCAN_COMPLETED, &local->scanning);
+ if (aborted)
+ set_bit(SCAN_ABORTED, &local->scanning);
+ ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
+}
EXPORT_SYMBOL(ieee80211_scan_completed);
static int ieee80211_start_sw_scan(struct ieee80211_local *local)
@@ -353,6 +364,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
int rc;
+ lockdep_assert_held(&local->mtx);
+
if (local->scan_req)
return -EBUSY;
@@ -434,8 +447,8 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan)
return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME;
}
-static int ieee80211_scan_state_decision(struct ieee80211_local *local,
- unsigned long *next_delay)
+static void ieee80211_scan_state_decision(struct ieee80211_local *local,
+ unsigned long *next_delay)
{
bool associated = false;
bool tx_empty = true;
@@ -445,12 +458,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata;
struct ieee80211_channel *next_chan;
- /* if no more bands/channels left, complete scan and advance to the idle state */
- if (local->scan_channel_idx >= local->scan_req->n_channels) {
- ieee80211_scan_completed(&local->hw, false);
- return 1;
- }
-
/*
* check if at least one STA interface is associated,
* check if at least one STA interface has pending tx frames
@@ -522,7 +529,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
}
*next_delay = 0;
- return 0;
}
static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
@@ -638,21 +644,18 @@ void ieee80211_scan_work(struct work_struct *work)
container_of(work, struct ieee80211_local, scan_work.work);
struct ieee80211_sub_if_data *sdata = local->scan_sdata;
unsigned long next_delay = 0;
+ bool aborted, hw_scan, finish;
- mutex_lock(&local->scan_mtx);
- if (!sdata || !local->scan_req) {
- mutex_unlock(&local->scan_mtx);
- return;
- }
+ mutex_lock(&local->mtx);
- if (local->hw_scan_req) {
- int rc = drv_hw_scan(local, sdata, local->hw_scan_req);
- mutex_unlock(&local->scan_mtx);
- if (rc)
- ieee80211_scan_completed(&local->hw, true);
- return;
+ if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
+ aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
+ goto out_complete;
}
+ if (!sdata || !local->scan_req)
+ goto out;
+
if (local->scan_req && !local->scanning) {
struct cfg80211_scan_request *req = local->scan_req;
int rc;
@@ -661,21 +664,21 @@ void ieee80211_scan_work(struct work_struct *work)
local->scan_sdata = NULL;
rc = __ieee80211_start_scan(sdata, req);
- mutex_unlock(&local->scan_mtx);
-
- if (rc)
- ieee80211_scan_completed(&local->hw, true);
- return;
+ if (rc) {
+ /* need to complete scan in cfg80211 */
+ local->scan_req = req;
+ aborted = true;
+ goto out_complete;
+ } else
+ goto out;
}
- mutex_unlock(&local->scan_mtx);
-
/*
* Avoid re-scheduling when the sdata is going away.
*/
if (!ieee80211_sdata_running(sdata)) {
- ieee80211_scan_completed(&local->hw, true);
- return;
+ aborted = true;
+ goto out_complete;
}
/*
@@ -685,8 +688,12 @@ void ieee80211_scan_work(struct work_struct *work)
do {
switch (local->next_scan_state) {
case SCAN_DECISION:
- if (ieee80211_scan_state_decision(local, &next_delay))
- return;
+ /* if no more bands/channels left, complete scan */
+ if (local->scan_channel_idx >= local->scan_req->n_channels) {
+ aborted = false;
+ goto out_complete;
+ }
+ ieee80211_scan_state_decision(local, &next_delay);
break;
case SCAN_SET_CHANNEL:
ieee80211_scan_state_set_channel(local, &next_delay);
@@ -704,6 +711,19 @@ void ieee80211_scan_work(struct work_struct *work)
} while (next_delay == 0);
ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
+ mutex_unlock(&local->mtx);
+ return;
+
+out_complete:
+ hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
+ finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan);
+ mutex_unlock(&local->mtx);
+ if (finish)
+ __ieee80211_scan_completed_finish(&local->hw, hw_scan);
+ return;
+
+out:
+ mutex_unlock(&local->mtx);
}
int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
@@ -711,9 +731,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
{
int res;
- mutex_lock(&sdata->local->scan_mtx);
+ mutex_lock(&sdata->local->mtx);
res = __ieee80211_start_scan(sdata, req);
- mutex_unlock(&sdata->local->scan_mtx);
+ mutex_unlock(&sdata->local->mtx);
return res;
}
@@ -726,7 +746,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
int ret = -EBUSY;
enum ieee80211_band band;
- mutex_lock(&local->scan_mtx);
+ mutex_lock(&local->mtx);
/* busy scanning */
if (local->scan_req)
@@ -761,25 +781,44 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
unlock:
- mutex_unlock(&local->scan_mtx);
+ mutex_unlock(&local->mtx);
return ret;
}
+/*
+ * Only call this function when a scan can't be queued -- under RTNL.
+ */
void ieee80211_scan_cancel(struct ieee80211_local *local)
{
bool abortscan;
-
- cancel_delayed_work_sync(&local->scan_work);
+ bool finish = false;
/*
- * Only call this function when a scan can't be
- * queued -- mostly at suspend under RTNL.
+ * We are only canceling software scan, or deferred scan that was not
+ * yet really started (see __ieee80211_start_scan ).
+ *
+ * Regarding hardware scan:
+ * - we can not call __ieee80211_scan_completed() as when
+ * SCAN_HW_SCANNING bit is set this function change
+ * local->hw_scan_req to operate on 5G band, what race with
+ * driver which can use local->hw_scan_req
+ *
+ * - we can not cancel scan_work since driver can schedule it
+ * by ieee80211_scan_completed(..., true) to finish scan
+ *
+ * Hence low lever driver is responsible for canceling HW scan.
*/
- mutex_lock(&local->scan_mtx);
- abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
- (!local->scanning && local->scan_req);
- mutex_unlock(&local->scan_mtx);
+ mutex_lock(&local->mtx);
+ abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
if (abortscan)
- ieee80211_scan_completed(&local->hw, true);
+ finish = __ieee80211_scan_completed(&local->hw, true, false);
+ mutex_unlock(&local->mtx);
+
+ if (abortscan) {
+ /* The scan is canceled, but stop work from being pending */
+ cancel_delayed_work_sync(&local->scan_work);
+ }
+ if (finish)
+ __ieee80211_scan_completed_finish(&local->hw, false);
}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 6d86f0c1ad04..6d8f897d8763 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -125,7 +125,7 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
lockdep_is_held(&local->sta_mtx));
while (sta) {
if ((sta->sdata == sdata ||
- sta->sdata->bss == sdata->bss) &&
+ (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
break;
sta = rcu_dereference_check(sta->hnext,
@@ -174,8 +174,7 @@ static void __sta_info_free(struct ieee80211_local *local,
}
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: Destroyed STA %pM\n",
- wiphy_name(local->hw.wiphy), sta->sta.addr);
+ wiphy_debug(local->hw.wiphy, "Destroyed STA %pM\n", sta->sta.addr);
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
kfree(sta);
@@ -262,8 +261,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX);
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: Allocated STA %pM\n",
- wiphy_name(local->hw.wiphy), sta->sta.addr);
+ wiphy_debug(local->hw.wiphy, "Allocated STA %pM\n", sta->sta.addr);
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
#ifdef CONFIG_MAC80211_MESH
@@ -282,7 +280,7 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async)
unsigned long flags;
int err = 0;
- WARN_ON(!mutex_is_locked(&local->sta_mtx));
+ lockdep_assert_held(&local->sta_mtx);
/* notify driver */
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
@@ -300,8 +298,9 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async)
sta->uploaded = true;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
if (async)
- printk(KERN_DEBUG "%s: Finished adding IBSS STA %pM\n",
- wiphy_name(local->hw.wiphy), sta->sta.addr);
+ wiphy_debug(local->hw.wiphy,
+ "Finished adding IBSS STA %pM\n",
+ sta->sta.addr);
#endif
}
@@ -411,8 +410,8 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
spin_unlock_irqrestore(&local->sta_lock, flags);
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: Added IBSS STA %pM\n",
- wiphy_name(local->hw.wiphy), sta->sta.addr);
+ wiphy_debug(local->hw.wiphy, "Added IBSS STA %pM\n",
+ sta->sta.addr);
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
ieee80211_queue_work(&local->hw, &local->sta_finish_work);
@@ -459,8 +458,7 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
}
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: Inserted STA %pM\n",
- wiphy_name(local->hw.wiphy), sta->sta.addr);
+ wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr);
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
/* move reference to rcu-protected */
@@ -618,7 +616,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
struct ieee80211_sub_if_data *sdata;
struct sk_buff *skb;
unsigned long flags;
- int ret;
+ int ret, i;
might_sleep();
@@ -635,7 +633,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
* will be sufficient.
*/
set_sta_flags(sta, WLAN_STA_BLOCK_BA);
- ieee80211_sta_tear_down_BA_sessions(sta);
+ ieee80211_sta_tear_down_BA_sessions(sta, true);
spin_lock_irqsave(&local->sta_lock, flags);
ret = sta_info_hash_del(local, sta);
@@ -646,10 +644,10 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
if (ret)
return ret;
- if (sta->key) {
- ieee80211_key_free(local, sta->key);
- WARN_ON(sta->key);
- }
+ for (i = 0; i < NUM_DEFAULT_KEYS; i++)
+ ieee80211_key_free(local, sta->gtk[i]);
+ if (sta->ptk)
+ ieee80211_key_free(local, sta->ptk);
sta->dead = true;
@@ -690,8 +688,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
#endif
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: Removed STA %pM\n",
- wiphy_name(local->hw.wiphy), sta->sta.addr);
+ wiphy_debug(local->hw.wiphy, "Removed STA %pM\n", sta->sta.addr);
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
cancel_work_sync(&sta->drv_unblock_wk);
@@ -841,13 +838,20 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
mutex_unlock(&local->sta_mtx);
}
-struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
- const u8 *addr)
+struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw,
+ const u8 *addr,
+ const u8 *localaddr)
{
struct sta_info *sta, *nxt;
- /* Just return a random station ... first in list ... */
+ /*
+ * Just return a random station if localaddr is NULL
+ * ... first in list.
+ */
for_each_sta_info(hw_to_local(hw), addr, sta, nxt) {
+ if (localaddr &&
+ compare_ether_addr(sta->sdata->vif.addr, localaddr) != 0)
+ continue;
if (!sta->uploaded)
return NULL;
return &sta->sta;
@@ -855,7 +859,7 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
return NULL;
}
-EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw);
+EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_ifaddr);
struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
const u8 *addr)
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 54262e72376d..9265acadef32 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -79,6 +79,7 @@ enum ieee80211_sta_info_flags {
* @dialog_token: dialog token for aggregation session
* @state: session state (see above)
* @stop_initiator: initiator of a session stop
+ * @tx_stop: TX DelBA frame when stopping
*
* This structure is protected by RCU and the per-station
* spinlock. Assignments to the array holding it must hold
@@ -95,6 +96,7 @@ struct tid_ampdu_tx {
unsigned long state;
u8 dialog_token;
u8 stop_initiator;
+ bool tx_stop;
};
/**
@@ -103,6 +105,7 @@ struct tid_ampdu_tx {
* @reorder_buf: buffer to reorder incoming aggregated MPDUs
* @reorder_time: jiffies when skb was added
* @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
+ * @reorder_timer: releases expired frames from the reorder buffer.
* @head_seq_num: head sequence number in reordering buffer.
* @stored_mpdu_num: number of MPDUs in reordering buffer
* @ssn: Starting Sequence Number expected to be aggregated.
@@ -110,20 +113,25 @@ struct tid_ampdu_tx {
* @timeout: reset timer value (in TUs).
* @dialog_token: dialog token for aggregation session
* @rcu_head: RCU head used for freeing this struct
+ * @reorder_lock: serializes access to reorder buffer, see below.
*
* This structure is protected by RCU and the per-station
* spinlock. Assignments to the array holding it must hold
- * the spinlock, only the RX path can access it under RCU
- * lock-free. The RX path, since it is single-threaded,
- * can even modify the structure without locking since the
- * only other modifications to it are done when the struct
- * can not yet or no longer be found by the RX path.
+ * the spinlock.
+ *
+ * The @reorder_lock is used to protect the variables and
+ * arrays such as @reorder_buf, @reorder_time, @head_seq_num,
+ * @stored_mpdu_num and @reorder_time from being corrupted by
+ * concurrent access of the RX path and the expired frame
+ * release timer.
*/
struct tid_ampdu_rx {
struct rcu_head rcu_head;
+ spinlock_t reorder_lock;
struct sk_buff **reorder_buf;
unsigned long *reorder_time;
struct timer_list session_timer;
+ struct timer_list reorder_timer;
u16 head_seq_num;
u16 stored_mpdu_num;
u16 ssn;
@@ -191,7 +199,8 @@ enum plink_state {
* @hnext: hash table linked list pointer
* @local: pointer to the global information
* @sdata: virtual interface this station belongs to
- * @key: peer key negotiated with this station, if any
+ * @ptk: peer key negotiated with this station, if any
+ * @gtk: group keys negotiated with this station, if any
* @rate_ctrl: rate control algorithm reference
* @rate_ctrl_priv: rate control private per-STA pointer
* @last_tx_rate: rate used for last transmit, to report to userspace as
@@ -246,7 +255,8 @@ struct sta_info {
struct sta_info *hnext;
struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata;
- struct ieee80211_key *key;
+ struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
+ struct ieee80211_key *ptk;
struct rate_control_ref *rate_ctrl;
void *rate_ctrl_priv;
spinlock_t lock;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 34da67995d94..3153c19893b8 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -58,6 +58,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
info->control.vif = &sta->sdata->vif;
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING |
IEEE80211_TX_INTFL_RETRANSMISSION;
+ info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
sta->tx_filtered_count++;
@@ -114,11 +115,10 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
if (net_ratelimit())
- printk(KERN_DEBUG "%s: dropped TX filtered frame, "
- "queue_len=%d PS=%d @%lu\n",
- wiphy_name(local->hw.wiphy),
- skb_queue_len(&sta->tx_filtered),
- !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies);
+ wiphy_debug(local->hw.wiphy,
+ "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n",
+ skb_queue_len(&sta->tx_filtered),
+ !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies);
#endif
dev_kfree_skb(skb);
}
@@ -176,7 +176,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
/* the HW cannot have attempted that rate */
- if (i >= hw->max_rates) {
+ if (i >= hw->max_report_rates) {
info->status.rates[i].idx = -1;
info->status.rates[i].count = 0;
} else if (info->status.rates[i].idx >= 0) {
@@ -296,7 +296,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
}
if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX)
- cfg80211_action_tx_status(
+ cfg80211_mgmt_tx_status(
skb->dev, (unsigned long) skb, skb->data, skb->len,
!!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c54db966926b..96c594309506 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -273,6 +273,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
*/
return TX_DROP;
+ if (tx->sdata->vif.type == NL80211_IFTYPE_WDS)
+ return TX_CONTINUE;
+
if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
return TX_CONTINUE;
@@ -351,8 +354,8 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
local->total_ps_buffered = total;
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
- printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n",
- wiphy_name(local->hw.wiphy), purged);
+ wiphy_debug(local->hw.wiphy, "PS buffers full - purged %d frames\n",
+ purged);
#endif
}
@@ -509,6 +512,18 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx)
}
static ieee80211_tx_result debug_noinline
+ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
+
+ if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol &&
+ tx->sdata->control_port_no_encrypt))
+ info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+
+ return TX_CONTINUE;
+}
+
+static ieee80211_tx_result debug_noinline
ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
{
struct ieee80211_key *key = NULL;
@@ -517,7 +532,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
tx->key = NULL;
- else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
+ else if (tx->sta && (key = rcu_dereference(tx->sta->ptk)))
tx->key = key;
else if (ieee80211_is_mgmt(hdr->frame_control) &&
is_multicast_ether_addr(hdr->addr1) &&
@@ -527,7 +542,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
else if ((key = rcu_dereference(tx->sdata->default_key)))
tx->key = key;
else if (tx->sdata->drop_unencrypted &&
- (tx->skb->protocol != cpu_to_be16(ETH_P_PAE)) &&
+ (tx->skb->protocol != tx->sdata->control_port_protocol) &&
!(info->flags & IEEE80211_TX_CTL_INJECTED) &&
(!ieee80211_is_robust_mgmt_frame(hdr) ||
(ieee80211_is_action(hdr->frame_control) &&
@@ -543,15 +558,16 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
tx->key->tx_rx_count++;
/* TODO: add threshold stuff again */
- switch (tx->key->conf.alg) {
- case ALG_WEP:
+ switch (tx->key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
if (ieee80211_is_auth(hdr->frame_control))
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
if (!ieee80211_is_data_present(hdr->frame_control))
tx->key = NULL;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
if (!ieee80211_is_data_present(hdr->frame_control) &&
!ieee80211_use_mfp(hdr->frame_control, tx->sta,
tx->skb))
@@ -561,7 +577,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
IEEE80211_KEY_FLAG_SW_MGMT) &&
ieee80211_is_mgmt(hdr->frame_control);
break;
- case ALG_AES_CMAC:
+ case WLAN_CIPHER_SUITE_AES_CMAC:
if (!ieee80211_is_mgmt(hdr->frame_control))
tx->key = NULL;
break;
@@ -946,22 +962,31 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
static ieee80211_tx_result debug_noinline
ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx)
{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
+
if (!tx->key)
return TX_CONTINUE;
- switch (tx->key->conf.alg) {
- case ALG_WEP:
+ switch (tx->key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
return ieee80211_crypto_wep_encrypt(tx);
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
return ieee80211_crypto_tkip_encrypt(tx);
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
return ieee80211_crypto_ccmp_encrypt(tx);
- case ALG_AES_CMAC:
+ case WLAN_CIPHER_SUITE_AES_CMAC:
return ieee80211_crypto_aes_cmac_encrypt(tx);
+ default:
+ /* handle hw-only algorithm */
+ if (info->control.hw_key) {
+ ieee80211_tx_set_protected(tx);
+ return TX_CONTINUE;
+ }
+ break;
+
}
- /* not reached */
- WARN_ON(1);
return TX_DROP;
}
@@ -1339,6 +1364,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
CALL_TXH(ieee80211_tx_h_dynamic_ps);
CALL_TXH(ieee80211_tx_h_check_assoc);
CALL_TXH(ieee80211_tx_h_ps_buf);
+ CALL_TXH(ieee80211_tx_h_check_control_port_protocol);
CALL_TXH(ieee80211_tx_h_select_key);
if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
CALL_TXH(ieee80211_tx_h_rate_ctrl);
@@ -1511,8 +1537,8 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
I802_DEBUG_INC(local->tx_expand_skb_head);
if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) {
- printk(KERN_DEBUG "%s: failed to reallocate TX buffer\n",
- wiphy_name(local->hw.wiphy));
+ wiphy_debug(local->hw.wiphy,
+ "failed to reallocate TX buffer\n");
return -ENOMEM;
}
@@ -1586,6 +1612,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
return;
}
+ hdr = (struct ieee80211_hdr *) skb->data;
info->control.vif = &sdata->vif;
if (ieee80211_vif_is_mesh(&sdata->vif) &&
@@ -1699,7 +1726,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
u16 ethertype, hdrlen, meshhdrlen = 0;
__le16 fc;
struct ieee80211_hdr hdr;
- struct ieee80211s_hdr mesh_hdr;
+ struct ieee80211s_hdr mesh_hdr __maybe_unused;
const u8 *encaps_data;
int encaps_len, skip_header_bytes;
int nh_pos, h_pos;
@@ -1816,7 +1843,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
#endif
case NL80211_IFTYPE_STATION:
memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN);
- if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) {
+ if (sdata->u.mgd.use_4addr &&
+ cpu_to_be16(ethertype) != sdata->control_port_protocol) {
fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
/* RA TA DA SA */
memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
@@ -1869,7 +1897,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
if (!ieee80211_vif_is_mesh(&sdata->vif) &&
unlikely(!is_multicast_ether_addr(hdr.addr1) &&
!(sta_flags & WLAN_STA_AUTHORIZED) &&
- !(ethertype == ETH_P_PAE &&
+ !(cpu_to_be16(ethertype) == sdata->control_port_protocol &&
compare_ether_addr(sdata->vif.addr,
skb->data + ETH_ALEN) == 0))) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -2068,8 +2096,7 @@ void ieee80211_tx_pending(unsigned long data)
if (skb_queue_empty(&local->pending[i]))
list_for_each_entry_rcu(sdata, &local->interfaces, list)
- netif_tx_wake_queue(
- netdev_get_tx_queue(sdata->dev, i));
+ netif_wake_subqueue(sdata->dev, i);
}
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 748387d45bc0..0b6fc92bc0d7 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -283,8 +283,11 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
if (skb_queue_empty(&local->pending[queue])) {
rcu_read_lock();
- list_for_each_entry_rcu(sdata, &local->interfaces, list)
- netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
+ continue;
+ netif_wake_subqueue(sdata->dev, queue);
+ }
rcu_read_unlock();
} else
tasklet_schedule(&local->tx_pending_tasklet);
@@ -323,7 +326,7 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces, list)
- netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue));
+ netif_stop_subqueue(sdata->dev, queue);
rcu_read_unlock();
}
@@ -471,16 +474,10 @@ void ieee80211_iterate_active_interfaces(
list_for_each_entry(sdata, &local->interfaces, list) {
switch (sdata->vif.type) {
- case __NL80211_IFTYPE_AFTER_LAST:
- case NL80211_IFTYPE_UNSPECIFIED:
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_AP_VLAN:
continue;
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_WDS:
- case NL80211_IFTYPE_MESH_POINT:
+ default:
break;
}
if (ieee80211_sdata_running(sdata))
@@ -505,16 +502,10 @@ void ieee80211_iterate_active_interfaces_atomic(
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
switch (sdata->vif.type) {
- case __NL80211_IFTYPE_AFTER_LAST:
- case NL80211_IFTYPE_UNSPECIFIED:
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_AP_VLAN:
continue;
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_WDS:
- case NL80211_IFTYPE_MESH_POINT:
+ default:
break;
}
if (ieee80211_sdata_running(sdata))
@@ -904,26 +895,34 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
const u8 *ie, size_t ie_len,
- enum ieee80211_band band)
+ enum ieee80211_band band, u32 rate_mask,
+ u8 channel)
{
struct ieee80211_supported_band *sband;
u8 *pos;
size_t offset = 0, noffset;
int supp_rates_len, i;
+ u8 rates[32];
+ int num_rates;
+ int ext_rates_len;
sband = local->hw.wiphy->bands[band];
pos = buffer;
- supp_rates_len = min_t(int, sband->n_bitrates, 8);
+ num_rates = 0;
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if ((BIT(i) & rate_mask) == 0)
+ continue; /* skip rate */
+ rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5);
+ }
+
+ supp_rates_len = min_t(int, num_rates, 8);
*pos++ = WLAN_EID_SUPP_RATES;
*pos++ = supp_rates_len;
-
- for (i = 0; i < supp_rates_len; i++) {
- int rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
- }
+ memcpy(pos, rates, supp_rates_len);
+ pos += supp_rates_len;
/* insert "request information" if in custom IEs */
if (ie && ie_len) {
@@ -941,14 +940,18 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
offset = noffset;
}
- if (sband->n_bitrates > i) {
+ ext_rates_len = num_rates - supp_rates_len;
+ if (ext_rates_len > 0) {
*pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos++ = sband->n_bitrates - i;
+ *pos++ = ext_rates_len;
+ memcpy(pos, rates + supp_rates_len, ext_rates_len);
+ pos += ext_rates_len;
+ }
- for (; i < sband->n_bitrates; i++) {
- int rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
- }
+ if (channel && sband->band == IEEE80211_BAND_2GHZ) {
+ *pos++ = WLAN_EID_DS_PARAMS;
+ *pos++ = 1;
+ *pos++ = channel;
}
/* insert custom IEs that go before HT */
@@ -1017,6 +1020,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
struct ieee80211_mgmt *mgmt;
size_t buf_len;
u8 *buf;
+ u8 chan;
/* FIXME: come up with a proper value */
buf = kmalloc(200 + ie_len, GFP_KERNEL);
@@ -1026,8 +1030,14 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
return;
}
+ chan = ieee80211_frequency_to_channel(
+ local->hw.conf.channel->center_freq);
+
buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
- local->hw.conf.channel->band);
+ local->hw.conf.channel->band,
+ sdata->rc_rateidx_mask
+ [local->hw.conf.channel->band],
+ chan);
skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
ssid, ssid_len,
@@ -1189,7 +1199,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
/* ignore virtual */
break;
case NL80211_IFTYPE_UNSPECIFIED:
- case __NL80211_IFTYPE_AFTER_LAST:
+ case NUM_NL80211_IFTYPES:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ case NL80211_IFTYPE_P2P_GO:
WARN_ON(1);
break;
}
@@ -1209,7 +1221,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
mutex_lock(&local->sta_mtx);
list_for_each_entry(sta, &local->sta_list, list) {
- ieee80211_sta_tear_down_BA_sessions(sta);
+ ieee80211_sta_tear_down_BA_sessions(sta, true);
clear_sta_flags(sta, WLAN_STA_BLOCK_BA);
}
@@ -1285,17 +1297,13 @@ static int check_mgd_smps(struct ieee80211_if_managed *ifmgd,
}
/* must hold iflist_mtx */
-void ieee80211_recalc_smps(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *forsdata)
+void ieee80211_recalc_smps(struct ieee80211_local *local)
{
struct ieee80211_sub_if_data *sdata;
enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF;
int count = 0;
- if (forsdata)
- WARN_ON(!mutex_is_locked(&forsdata->u.mgd.mtx));
-
- WARN_ON(!mutex_is_locked(&local->iflist_mtx));
+ lockdep_assert_held(&local->iflist_mtx);
/*
* This function could be improved to handle multiple
@@ -1308,22 +1316,12 @@ void ieee80211_recalc_smps(struct ieee80211_local *local,
*/
list_for_each_entry(sdata, &local->interfaces, list) {
- if (!netif_running(sdata->dev))
+ if (!ieee80211_sdata_running(sdata))
continue;
if (sdata->vif.type != NL80211_IFTYPE_STATION)
goto set;
- if (sdata != forsdata) {
- /*
- * This nested is ok -- we are holding the iflist_mtx
- * so can't get here twice or so. But it's required
- * since normally we acquire it first and then the
- * iflist_mtx.
- */
- mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING);
- count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
- mutex_unlock(&sdata->u.mgd.mtx);
- } else
- count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
+
+ count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
if (count > 1) {
smps_mode = IEEE80211_SMPS_OFF;
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 9ebc8d8a1f5b..2ff6d1e3ed21 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -222,7 +222,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
struct ieee80211_key *key)
{
u32 klen;
- u8 *rc4key;
+ u8 rc4key[3 + WLAN_KEY_LEN_WEP104];
u8 keyidx;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
unsigned int hdrlen;
@@ -240,15 +240,11 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
keyidx = skb->data[hdrlen + 3] >> 6;
- if (!key || keyidx != key->conf.keyidx || key->conf.alg != ALG_WEP)
+ if (!key || keyidx != key->conf.keyidx)
return -1;
klen = 3 + key->conf.keylen;
- rc4key = kmalloc(klen, GFP_ATOMIC);
- if (!rc4key)
- return -1;
-
/* Prepend 24-bit IV to RC4 key */
memcpy(rc4key, skb->data + hdrlen, 3);
@@ -260,8 +256,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
len))
ret = -1;
- kfree(rc4key);
-
/* Trim ICV */
skb_trim(skb, skb->len - WEP_ICV_LEN);
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 81d4ad64184a..ae344d1ba056 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -43,7 +43,7 @@ enum work_action {
/* utils */
static inline void ASSERT_WORK_MTX(struct ieee80211_local *local)
{
- WARN_ON(!mutex_is_locked(&local->work_mtx));
+ lockdep_assert_held(&local->mtx);
}
/*
@@ -757,7 +757,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
mgmt = (struct ieee80211_mgmt *) skb->data;
fc = le16_to_cpu(mgmt->frame_control);
- mutex_lock(&local->work_mtx);
+ mutex_lock(&local->mtx);
list_for_each_entry(wk, &local->work_list, list) {
const u8 *bssid = NULL;
@@ -833,7 +833,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
WARN(1, "unexpected: %d", rma);
}
- mutex_unlock(&local->work_mtx);
+ mutex_unlock(&local->mtx);
if (rma != WORK_ACT_DONE)
goto out;
@@ -845,9 +845,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
case WORK_DONE_REQUEUE:
synchronize_rcu();
wk->started = false; /* restart */
- mutex_lock(&local->work_mtx);
+ mutex_lock(&local->mtx);
list_add_tail(&wk->list, &local->work_list);
- mutex_unlock(&local->work_mtx);
+ mutex_unlock(&local->mtx);
}
out:
@@ -888,9 +888,9 @@ static void ieee80211_work_work(struct work_struct *work)
while ((skb = skb_dequeue(&local->work_skb_queue)))
ieee80211_work_rx_queued_mgmt(local, skb);
- ieee80211_recalc_idle(local);
+ mutex_lock(&local->mtx);
- mutex_lock(&local->work_mtx);
+ ieee80211_recalc_idle(local);
list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
bool started = wk->started;
@@ -995,20 +995,16 @@ static void ieee80211_work_work(struct work_struct *work)
run_again(local, jiffies + HZ/2);
}
- mutex_lock(&local->scan_mtx);
-
if (list_empty(&local->work_list) && local->scan_req &&
!local->scanning)
ieee80211_queue_delayed_work(&local->hw,
&local->scan_work,
round_jiffies_relative(0));
- mutex_unlock(&local->scan_mtx);
-
- mutex_unlock(&local->work_mtx);
-
ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
+
list_for_each_entry_safe(wk, tmp, &free_work, list) {
wk->done(wk, NULL);
list_del(&wk->list);
@@ -1035,16 +1031,15 @@ void ieee80211_add_work(struct ieee80211_work *wk)
wk->started = false;
local = wk->sdata->local;
- mutex_lock(&local->work_mtx);
+ mutex_lock(&local->mtx);
list_add_tail(&wk->list, &local->work_list);
- mutex_unlock(&local->work_mtx);
+ mutex_unlock(&local->mtx);
ieee80211_queue_work(&local->hw, &local->work_work);
}
void ieee80211_work_init(struct ieee80211_local *local)
{
- mutex_init(&local->work_mtx);
INIT_LIST_HEAD(&local->work_list);
setup_timer(&local->work_timer, ieee80211_work_timer,
(unsigned long)local);
@@ -1057,7 +1052,7 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
struct ieee80211_local *local = sdata->local;
struct ieee80211_work *wk;
- mutex_lock(&local->work_mtx);
+ mutex_lock(&local->mtx);
list_for_each_entry(wk, &local->work_list, list) {
if (wk->sdata != sdata)
continue;
@@ -1065,19 +1060,19 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
wk->started = true;
wk->timeout = jiffies;
}
- mutex_unlock(&local->work_mtx);
+ mutex_unlock(&local->mtx);
/* run cleanups etc. */
ieee80211_work_work(&local->work_work);
- mutex_lock(&local->work_mtx);
+ mutex_lock(&local->mtx);
list_for_each_entry(wk, &local->work_list, list) {
if (wk->sdata != sdata)
continue;
WARN_ON(1);
break;
}
- mutex_unlock(&local->work_mtx);
+ mutex_unlock(&local->mtx);
}
ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
@@ -1163,7 +1158,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata,
struct ieee80211_work *wk, *tmp;
bool found = false;
- mutex_lock(&local->work_mtx);
+ mutex_lock(&local->mtx);
list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
if ((unsigned long) wk == cookie) {
wk->timeout = jiffies;
@@ -1171,7 +1166,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata,
break;
}
}
- mutex_unlock(&local->work_mtx);
+ mutex_unlock(&local->mtx);
if (!found)
return -ENOENT;
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 8d59d27d887e..bee230d8fd11 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -36,8 +36,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
int tail;
hdr = (struct ieee80211_hdr *)skb->data;
- if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 ||
- !ieee80211_is_data_present(hdr->frame_control))
+ if (!tx->key || tx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
+ skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control))
return TX_CONTINUE;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -94,7 +94,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
if (status->flag & RX_FLAG_MMIC_STRIPPED)
return RX_CONTINUE;
- if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
+ if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
!ieee80211_has_protected(hdr->frame_control) ||
!ieee80211_is_data_present(hdr->frame_control))
return RX_CONTINUE;
@@ -117,7 +117,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
key = &rx->key->conf.key[key_offset];
michael_mic(key, hdr, data, data_len, mic);
if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) {
- if (!(rx->flags & IEEE80211_RX_RA_MATCH))
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
return RX_DROP_UNUSABLE;
mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
@@ -221,19 +221,13 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
if (!rx->sta || skb->len - hdrlen < 12)
return RX_DROP_UNUSABLE;
- if (status->flag & RX_FLAG_DECRYPTED) {
- if (status->flag & RX_FLAG_IV_STRIPPED) {
- /*
- * Hardware took care of all processing, including
- * replay protection, and stripped the ICV/IV so
- * we cannot do any checks here.
- */
- return RX_CONTINUE;
- }
-
- /* let TKIP code verify IV, but skip decryption */
+ /*
+ * Let TKIP code verify IV, but skip decryption.
+ * In the case where hardware checks the IV as well,
+ * we don't even get here, see ieee80211_rx_h_decrypt()
+ */
+ if (status->flag & RX_FLAG_DECRYPTED)
hwaccel = 1;
- }
res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
key, skb->data + hdrlen,
@@ -447,10 +441,6 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
if (!rx->sta || data_len < 0)
return RX_DROP_UNUSABLE;
- if ((status->flag & RX_FLAG_DECRYPTED) &&
- (status->flag & RX_FLAG_IV_STRIPPED))
- return RX_CONTINUE;
-
ccmp_hdr2pn(pn, skb->data + hdrlen);
queue = ieee80211_is_mgmt(hdr->frame_control) ?
@@ -564,10 +554,6 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
if (!ieee80211_is_mgmt(hdr->frame_control))
return RX_CONTINUE;
- if ((status->flag & RX_FLAG_DECRYPTED) &&
- (status->flag & RX_FLAG_IV_STRIPPED))
- return RX_CONTINUE;
-
if (skb->len < 24 + sizeof(*mmie))
return RX_DROP_UNUSABLE;
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index fdaec7daff1d..85dabb86be6f 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -105,10 +105,8 @@ EXPORT_SYMBOL(nf_register_hooks);
void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
{
- unsigned int i;
-
- for (i = 0; i < n; i++)
- nf_unregister_hook(&reg[i]);
+ while (n-- > 0)
+ nf_unregister_hook(&reg[n]);
}
EXPORT_SYMBOL(nf_unregister_hooks);
diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig
index 46a77d5c3887..a22dac227055 100644
--- a/net/netfilter/ipvs/Kconfig
+++ b/net/netfilter/ipvs/Kconfig
@@ -3,7 +3,7 @@
#
menuconfig IP_VS
tristate "IP virtual server support"
- depends on NET && INET && NETFILTER && NF_CONNTRACK
+ depends on NET && INET && NETFILTER
---help---
IP Virtual Server support will let you build a high-performance
virtual server based on cluster of two or more real servers. This
@@ -235,7 +235,8 @@ comment 'IPVS application helper'
config IP_VS_FTP
tristate "FTP protocol helper"
- depends on IP_VS_PROTO_TCP && NF_NAT
+ depends on IP_VS_PROTO_TCP && NF_CONNTRACK && NF_NAT
+ select IP_VS_NFCT
---help---
FTP is a protocol that transfers IP address and/or port number in
the payload. In the virtual server via Network Address Translation,
@@ -247,4 +248,19 @@ config IP_VS_FTP
If you want to compile it in kernel, say Y. To compile it as a
module, choose M here. If unsure, say N.
+config IP_VS_NFCT
+ bool "Netfilter connection tracking"
+ depends on NF_CONNTRACK
+ ---help---
+ The Netfilter connection tracking support allows the IPVS
+ connection state to be exported to the Netfilter framework
+ for filtering purposes.
+
+config IP_VS_PE_SIP
+ tristate "SIP persistence engine"
+ depends on IP_VS_PROTO_UDP
+ depends on NF_CONNTRACK_SIP
+ ---help---
+ Allow persistence based on the SIP Call-ID
+
endif # IP_VS
diff --git a/net/netfilter/ipvs/Makefile b/net/netfilter/ipvs/Makefile
index e3baefd7066e..34ee602ddb66 100644
--- a/net/netfilter/ipvs/Makefile
+++ b/net/netfilter/ipvs/Makefile
@@ -9,10 +9,13 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_UDP) += ip_vs_proto_udp.o
ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH_ESP) += ip_vs_proto_ah_esp.o
ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_SCTP) += ip_vs_proto_sctp.o
+ip_vs-extra_objs-y :=
+ip_vs-extra_objs-$(CONFIG_IP_VS_NFCT) += ip_vs_nfct.o
+
ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \
ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \
- ip_vs_est.o ip_vs_proto.o \
- $(ip_vs_proto-objs-y)
+ ip_vs_est.o ip_vs_proto.o ip_vs_pe.o \
+ $(ip_vs_proto-objs-y) $(ip_vs-extra_objs-y)
# IPVS core
@@ -32,3 +35,6 @@ obj-$(CONFIG_IP_VS_NQ) += ip_vs_nq.o
# IPVS application helpers
obj-$(CONFIG_IP_VS_FTP) += ip_vs_ftp.o
+
+# IPVS connection template retrievers
+obj-$(CONFIG_IP_VS_PE_SIP) += ip_vs_pe_sip.o
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index e76f87f4aca8..a475edee0912 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -103,8 +103,8 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port)
goto out;
list_add(&inc->a_list, &app->incs_list);
- IP_VS_DBG(9, "%s application %s:%u registered\n",
- pp->name, inc->name, inc->port);
+ IP_VS_DBG(9, "%s App %s:%u registered\n",
+ pp->name, inc->name, ntohs(inc->port));
return 0;
@@ -130,7 +130,7 @@ ip_vs_app_inc_release(struct ip_vs_app *inc)
pp->unregister_app(inc);
IP_VS_DBG(9, "%s App %s:%u unregistered\n",
- pp->name, inc->name, inc->port);
+ pp->name, inc->name, ntohs(inc->port));
list_del(&inc->a_list);
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index b71c69a2db13..e9adecdc8ca4 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -148,6 +148,42 @@ static unsigned int ip_vs_conn_hashkey(int af, unsigned proto,
& ip_vs_conn_tab_mask;
}
+static unsigned int ip_vs_conn_hashkey_param(const struct ip_vs_conn_param *p,
+ bool inverse)
+{
+ const union nf_inet_addr *addr;
+ __be16 port;
+
+ if (p->pe_data && p->pe->hashkey_raw)
+ return p->pe->hashkey_raw(p, ip_vs_conn_rnd, inverse) &
+ ip_vs_conn_tab_mask;
+
+ if (likely(!inverse)) {
+ addr = p->caddr;
+ port = p->cport;
+ } else {
+ addr = p->vaddr;
+ port = p->vport;
+ }
+
+ return ip_vs_conn_hashkey(p->af, p->protocol, addr, port);
+}
+
+static unsigned int ip_vs_conn_hashkey_conn(const struct ip_vs_conn *cp)
+{
+ struct ip_vs_conn_param p;
+
+ ip_vs_conn_fill_param(cp->af, cp->protocol, &cp->caddr, cp->cport,
+ NULL, 0, &p);
+
+ if (cp->dest && cp->dest->svc->pe) {
+ p.pe = cp->dest->svc->pe;
+ p.pe_data = cp->pe_data;
+ p.pe_data_len = cp->pe_data_len;
+ }
+
+ return ip_vs_conn_hashkey_param(&p, false);
+}
/*
* Hashes ip_vs_conn in ip_vs_conn_tab by proto,addr,port.
@@ -162,7 +198,7 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp)
return 0;
/* Hash by protocol, client address and port */
- hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport);
+ hash = ip_vs_conn_hashkey_conn(cp);
ct_write_lock(hash);
spin_lock(&cp->lock);
@@ -195,7 +231,7 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp)
int ret;
/* unhash it and decrease its reference counter */
- hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport);
+ hash = ip_vs_conn_hashkey_conn(cp);
ct_write_lock(hash);
spin_lock(&cp->lock);
@@ -218,27 +254,26 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp)
/*
* Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab.
* Called for pkts coming from OUTside-to-INside.
- * s_addr, s_port: pkt source address (foreign host)
- * d_addr, d_port: pkt dest address (load balancer)
+ * p->caddr, p->cport: pkt source address (foreign host)
+ * p->vaddr, p->vport: pkt dest address (load balancer)
*/
-static inline struct ip_vs_conn *__ip_vs_conn_in_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port)
+static inline struct ip_vs_conn *
+__ip_vs_conn_in_get(const struct ip_vs_conn_param *p)
{
unsigned hash;
struct ip_vs_conn *cp;
- hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port);
+ hash = ip_vs_conn_hashkey_param(p, false);
ct_read_lock(hash);
list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
- if (cp->af == af &&
- ip_vs_addr_equal(af, s_addr, &cp->caddr) &&
- ip_vs_addr_equal(af, d_addr, &cp->vaddr) &&
- s_port == cp->cport && d_port == cp->vport &&
- ((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) &&
- protocol == cp->protocol) {
+ if (cp->af == p->af &&
+ ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) &&
+ ip_vs_addr_equal(p->af, p->vaddr, &cp->vaddr) &&
+ p->cport == cp->cport && p->vport == cp->vport &&
+ ((!p->cport) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) &&
+ p->protocol == cp->protocol) {
/* HIT */
atomic_inc(&cp->refcnt);
ct_read_unlock(hash);
@@ -251,99 +286,111 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get
return NULL;
}
-struct ip_vs_conn *ip_vs_conn_in_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port)
+struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p)
{
struct ip_vs_conn *cp;
- cp = __ip_vs_conn_in_get(af, protocol, s_addr, s_port, d_addr, d_port);
- if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt))
- cp = __ip_vs_conn_in_get(af, protocol, s_addr, 0, d_addr,
- d_port);
+ cp = __ip_vs_conn_in_get(p);
+ if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) {
+ struct ip_vs_conn_param cport_zero_p = *p;
+ cport_zero_p.cport = 0;
+ cp = __ip_vs_conn_in_get(&cport_zero_p);
+ }
IP_VS_DBG_BUF(9, "lookup/in %s %s:%d->%s:%d %s\n",
- ip_vs_proto_name(protocol),
- IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port),
- IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port),
+ ip_vs_proto_name(p->protocol),
+ IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport),
+ IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport),
cp ? "hit" : "not hit");
return cp;
}
+static int
+ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb,
+ const struct ip_vs_iphdr *iph,
+ unsigned int proto_off, int inverse,
+ struct ip_vs_conn_param *p)
+{
+ __be16 _ports[2], *pptr;
+
+ pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
+ if (pptr == NULL)
+ return 1;
+
+ if (likely(!inverse))
+ ip_vs_conn_fill_param(af, iph->protocol, &iph->saddr, pptr[0],
+ &iph->daddr, pptr[1], p);
+ else
+ ip_vs_conn_fill_param(af, iph->protocol, &iph->daddr, pptr[1],
+ &iph->saddr, pptr[0], p);
+ return 0;
+}
+
struct ip_vs_conn *
ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb,
struct ip_vs_protocol *pp,
const struct ip_vs_iphdr *iph,
unsigned int proto_off, int inverse)
{
- __be16 _ports[2], *pptr;
+ struct ip_vs_conn_param p;
- pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
- if (pptr == NULL)
+ if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p))
return NULL;
- if (likely(!inverse))
- return ip_vs_conn_in_get(af, iph->protocol,
- &iph->saddr, pptr[0],
- &iph->daddr, pptr[1]);
- else
- return ip_vs_conn_in_get(af, iph->protocol,
- &iph->daddr, pptr[1],
- &iph->saddr, pptr[0]);
+ return ip_vs_conn_in_get(&p);
}
EXPORT_SYMBOL_GPL(ip_vs_conn_in_get_proto);
/* Get reference to connection template */
-struct ip_vs_conn *ip_vs_ct_in_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port)
+struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p)
{
unsigned hash;
struct ip_vs_conn *cp;
- hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port);
+ hash = ip_vs_conn_hashkey_param(p, false);
ct_read_lock(hash);
list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
- if (cp->af == af &&
- ip_vs_addr_equal(af, s_addr, &cp->caddr) &&
+ if (p->pe_data && p->pe->ct_match) {
+ if (p->pe->ct_match(p, cp))
+ goto out;
+ continue;
+ }
+
+ if (cp->af == p->af &&
+ ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) &&
/* protocol should only be IPPROTO_IP if
- * d_addr is a fwmark */
- ip_vs_addr_equal(protocol == IPPROTO_IP ? AF_UNSPEC : af,
- d_addr, &cp->vaddr) &&
- s_port == cp->cport && d_port == cp->vport &&
+ * p->vaddr is a fwmark */
+ ip_vs_addr_equal(p->protocol == IPPROTO_IP ? AF_UNSPEC :
+ p->af, p->vaddr, &cp->vaddr) &&
+ p->cport == cp->cport && p->vport == cp->vport &&
cp->flags & IP_VS_CONN_F_TEMPLATE &&
- protocol == cp->protocol) {
- /* HIT */
- atomic_inc(&cp->refcnt);
+ p->protocol == cp->protocol)
goto out;
- }
}
cp = NULL;
out:
+ if (cp)
+ atomic_inc(&cp->refcnt);
ct_read_unlock(hash);
IP_VS_DBG_BUF(9, "template lookup/in %s %s:%d->%s:%d %s\n",
- ip_vs_proto_name(protocol),
- IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port),
- IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port),
+ ip_vs_proto_name(p->protocol),
+ IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport),
+ IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport),
cp ? "hit" : "not hit");
return cp;
}
-/*
- * Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab.
- * Called for pkts coming from inside-to-OUTside.
- * s_addr, s_port: pkt source address (inside host)
- * d_addr, d_port: pkt dest address (foreign host)
- */
-struct ip_vs_conn *ip_vs_conn_out_get
-(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
- const union nf_inet_addr *d_addr, __be16 d_port)
+/* Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab.
+ * Called for pkts coming from inside-to-OUTside.
+ * p->caddr, p->cport: pkt source address (inside host)
+ * p->vaddr, p->vport: pkt dest address (foreign host) */
+struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p)
{
unsigned hash;
struct ip_vs_conn *cp, *ret=NULL;
@@ -351,16 +398,16 @@ struct ip_vs_conn *ip_vs_conn_out_get
/*
* Check for "full" addressed entries
*/
- hash = ip_vs_conn_hashkey(af, protocol, d_addr, d_port);
+ hash = ip_vs_conn_hashkey_param(p, true);
ct_read_lock(hash);
list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
- if (cp->af == af &&
- ip_vs_addr_equal(af, d_addr, &cp->caddr) &&
- ip_vs_addr_equal(af, s_addr, &cp->daddr) &&
- d_port == cp->cport && s_port == cp->dport &&
- protocol == cp->protocol) {
+ if (cp->af == p->af &&
+ ip_vs_addr_equal(p->af, p->vaddr, &cp->caddr) &&
+ ip_vs_addr_equal(p->af, p->caddr, &cp->daddr) &&
+ p->vport == cp->cport && p->cport == cp->dport &&
+ p->protocol == cp->protocol) {
/* HIT */
atomic_inc(&cp->refcnt);
ret = cp;
@@ -371,9 +418,9 @@ struct ip_vs_conn *ip_vs_conn_out_get
ct_read_unlock(hash);
IP_VS_DBG_BUF(9, "lookup/out %s %s:%d->%s:%d %s\n",
- ip_vs_proto_name(protocol),
- IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port),
- IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port),
+ ip_vs_proto_name(p->protocol),
+ IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport),
+ IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport),
ret ? "hit" : "not hit");
return ret;
@@ -385,20 +432,12 @@ ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb,
const struct ip_vs_iphdr *iph,
unsigned int proto_off, int inverse)
{
- __be16 _ports[2], *pptr;
+ struct ip_vs_conn_param p;
- pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
- if (pptr == NULL)
+ if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p))
return NULL;
- if (likely(!inverse))
- return ip_vs_conn_out_get(af, iph->protocol,
- &iph->saddr, pptr[0],
- &iph->daddr, pptr[1]);
- else
- return ip_vs_conn_out_get(af, iph->protocol,
- &iph->daddr, pptr[1],
- &iph->saddr, pptr[0]);
+ return ip_vs_conn_out_get(&p);
}
EXPORT_SYMBOL_GPL(ip_vs_conn_out_get_proto);
@@ -505,6 +544,8 @@ static inline int ip_vs_dest_totalconns(struct ip_vs_dest *dest)
static inline void
ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
{
+ unsigned int conn_flags;
+
/* if dest is NULL, then return directly */
if (!dest)
return;
@@ -512,16 +553,20 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
/* Increase the refcnt counter of the dest */
atomic_inc(&dest->refcnt);
+ conn_flags = atomic_read(&dest->conn_flags);
+ if (cp->protocol != IPPROTO_UDP)
+ conn_flags &= ~IP_VS_CONN_F_ONE_PACKET;
/* Bind with the destination and its corresponding transmitter */
- if ((cp->flags & IP_VS_CONN_F_SYNC) &&
- (!(cp->flags & IP_VS_CONN_F_TEMPLATE)))
+ if (cp->flags & IP_VS_CONN_F_SYNC) {
/* if the connection is not template and is created
* by sync, preserve the activity flag.
*/
- cp->flags |= atomic_read(&dest->conn_flags) &
- (~IP_VS_CONN_F_INACTIVE);
- else
- cp->flags |= atomic_read(&dest->conn_flags);
+ if (!(cp->flags & IP_VS_CONN_F_TEMPLATE))
+ conn_flags &= ~IP_VS_CONN_F_INACTIVE;
+ /* connections inherit forwarding method from dest */
+ cp->flags &= ~IP_VS_CONN_F_FWD_MASK;
+ }
+ cp->flags |= conn_flags;
cp->dest = dest;
IP_VS_DBG_BUF(7, "Bind-dest %s c:%s:%d v:%s:%d "
@@ -717,6 +762,10 @@ static void ip_vs_conn_expire(unsigned long data)
if (cp->control)
ip_vs_control_del(cp);
+ if (cp->flags & IP_VS_CONN_F_NFCT)
+ ip_vs_conn_drop_conntrack(cp);
+
+ kfree(cp->pe_data);
if (unlikely(cp->app != NULL))
ip_vs_unbind_app(cp);
ip_vs_unbind_dest(cp);
@@ -751,13 +800,12 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp)
* Create a new connection entry and hash it into the ip_vs_conn_tab
*/
struct ip_vs_conn *
-ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,
- const union nf_inet_addr *vaddr, __be16 vport,
+ip_vs_conn_new(const struct ip_vs_conn_param *p,
const union nf_inet_addr *daddr, __be16 dport, unsigned flags,
struct ip_vs_dest *dest)
{
struct ip_vs_conn *cp;
- struct ip_vs_protocol *pp = ip_vs_proto_get(proto);
+ struct ip_vs_protocol *pp = ip_vs_proto_get(p->protocol);
cp = kmem_cache_zalloc(ip_vs_conn_cachep, GFP_ATOMIC);
if (cp == NULL) {
@@ -767,17 +815,21 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,
INIT_LIST_HEAD(&cp->c_list);
setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp);
- cp->af = af;
- cp->protocol = proto;
- ip_vs_addr_copy(af, &cp->caddr, caddr);
- cp->cport = cport;
- ip_vs_addr_copy(af, &cp->vaddr, vaddr);
- cp->vport = vport;
+ cp->af = p->af;
+ cp->protocol = p->protocol;
+ ip_vs_addr_copy(p->af, &cp->caddr, p->caddr);
+ cp->cport = p->cport;
+ ip_vs_addr_copy(p->af, &cp->vaddr, p->vaddr);
+ cp->vport = p->vport;
/* proto should only be IPPROTO_IP if d_addr is a fwmark */
- ip_vs_addr_copy(proto == IPPROTO_IP ? AF_UNSPEC : af,
+ ip_vs_addr_copy(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af,
&cp->daddr, daddr);
cp->dport = dport;
cp->flags = flags;
+ if (flags & IP_VS_CONN_F_TEMPLATE && p->pe_data) {
+ cp->pe_data = p->pe_data;
+ cp->pe_data_len = p->pe_data_len;
+ }
spin_lock_init(&cp->lock);
/*
@@ -803,7 +855,7 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,
/* Bind its packet transmitter */
#ifdef CONFIG_IP_VS_IPV6
- if (af == AF_INET6)
+ if (p->af == AF_INET6)
ip_vs_bind_xmit_v6(cp);
else
#endif
@@ -812,13 +864,22 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,
if (unlikely(pp && atomic_read(&pp->appcnt)))
ip_vs_bind_app(cp, pp);
+ /*
+ * Allow conntrack to be preserved. By default, conntrack
+ * is created and destroyed for every packet.
+ * Sometimes keeping conntrack can be useful for
+ * IP_VS_CONN_F_ONE_PACKET too.
+ */
+
+ if (ip_vs_conntrack_enabled())
+ cp->flags |= IP_VS_CONN_F_NFCT;
+
/* Hash it in the ip_vs_conn_tab finally */
ip_vs_conn_hash(cp);
return cp;
}
-
/*
* /proc/net/ip_vs_conn entries
*/
@@ -834,7 +895,7 @@ static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos)
list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
if (pos-- == 0) {
seq->private = &ip_vs_conn_tab[idx];
- return cp;
+ return cp;
}
}
ct_read_unlock_bh(idx);
@@ -891,30 +952,45 @@ static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)
if (v == SEQ_START_TOKEN)
seq_puts(seq,
- "Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires\n");
+ "Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires PEName PEData\n");
else {
const struct ip_vs_conn *cp = v;
+ char pe_data[IP_VS_PENAME_MAXLEN + IP_VS_PEDATA_MAXLEN + 3];
+ size_t len = 0;
+
+ if (cp->dest && cp->pe_data &&
+ cp->dest->svc->pe->show_pe_data) {
+ pe_data[0] = ' ';
+ len = strlen(cp->dest->svc->pe->name);
+ memcpy(pe_data + 1, cp->dest->svc->pe->name, len);
+ pe_data[len + 1] = ' ';
+ len += 2;
+ len += cp->dest->svc->pe->show_pe_data(cp,
+ pe_data + len);
+ }
+ pe_data[len] = '\0';
#ifdef CONFIG_IP_VS_IPV6
if (cp->af == AF_INET6)
- seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X %pI6 %04X %-11s %7lu\n",
+ seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X "
+ "%pI6 %04X %-11s %7lu%s\n",
ip_vs_proto_name(cp->protocol),
&cp->caddr.in6, ntohs(cp->cport),
&cp->vaddr.in6, ntohs(cp->vport),
&cp->daddr.in6, ntohs(cp->dport),
ip_vs_state_name(cp->protocol, cp->state),
- (cp->timer.expires-jiffies)/HZ);
+ (cp->timer.expires-jiffies)/HZ, pe_data);
else
#endif
seq_printf(seq,
"%-3s %08X %04X %08X %04X"
- " %08X %04X %-11s %7lu\n",
+ " %08X %04X %-11s %7lu%s\n",
ip_vs_proto_name(cp->protocol),
ntohl(cp->caddr.ip), ntohs(cp->cport),
ntohl(cp->vaddr.ip), ntohs(cp->vport),
ntohl(cp->daddr.ip), ntohs(cp->dport),
ip_vs_state_name(cp->protocol, cp->state),
- (cp->timer.expires-jiffies)/HZ);
+ (cp->timer.expires-jiffies)/HZ, pe_data);
}
return 0;
}
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 4c2f89df5cce..b4e51e9c5a04 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -40,6 +40,7 @@
#include <net/udp.h>
#include <net/icmp.h> /* for icmp_send */
#include <net/route.h>
+#include <net/ip6_checksum.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
@@ -47,6 +48,7 @@
#ifdef CONFIG_IP_VS_IPV6
#include <net/ipv6.h>
#include <linux/netfilter_ipv6.h>
+#include <net/ip6_route.h>
#endif
#include <net/ip_vs.h>
@@ -175,6 +177,18 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction,
return pp->state_transition(cp, direction, skb, pp);
}
+static inline void
+ip_vs_conn_fill_param_persist(const struct ip_vs_service *svc,
+ struct sk_buff *skb, int protocol,
+ const union nf_inet_addr *caddr, __be16 cport,
+ const union nf_inet_addr *vaddr, __be16 vport,
+ struct ip_vs_conn_param *p)
+{
+ ip_vs_conn_fill_param(svc->af, protocol, caddr, cport, vaddr, vport, p);
+ p->pe = svc->pe;
+ if (p->pe && p->pe->fill_param)
+ p->pe->fill_param(p, skb);
+}
/*
* IPVS persistent scheduling function
@@ -185,15 +199,16 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction,
*/
static struct ip_vs_conn *
ip_vs_sched_persist(struct ip_vs_service *svc,
- const struct sk_buff *skb,
+ struct sk_buff *skb,
__be16 ports[2])
{
struct ip_vs_conn *cp = NULL;
struct ip_vs_iphdr iph;
struct ip_vs_dest *dest;
struct ip_vs_conn *ct;
- __be16 dport; /* destination port to forward */
- __be16 flags;
+ __be16 dport = 0; /* destination port to forward */
+ unsigned int flags;
+ struct ip_vs_conn_param param;
union nf_inet_addr snet; /* source network of the client,
after masking */
@@ -226,120 +241,75 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
* service, and a template like <caddr, 0, vaddr, vport, daddr, dport>
* is created for other persistent services.
*/
- if (ports[1] == svc->port) {
- /* Check if a template already exists */
- if (svc->port != FTPPORT)
- ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
- &iph.daddr, ports[1]);
- else
- ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
- &iph.daddr, 0);
-
- if (!ct || !ip_vs_check_template(ct)) {
- /*
- * No template found or the dest of the connection
- * template is not available.
- */
- dest = svc->scheduler->schedule(svc, skb);
- if (dest == NULL) {
- IP_VS_DBG(1, "p-schedule: no dest found.\n");
- return NULL;
- }
-
- /*
- * Create a template like <protocol,caddr,0,
- * vaddr,vport,daddr,dport> for non-ftp service,
- * and <protocol,caddr,0,vaddr,0,daddr,0>
- * for ftp service.
+ {
+ int protocol = iph.protocol;
+ const union nf_inet_addr *vaddr = &iph.daddr;
+ const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
+ __be16 vport = 0;
+
+ if (ports[1] == svc->port) {
+ /* non-FTP template:
+ * <protocol, caddr, 0, vaddr, vport, daddr, dport>
+ * FTP template:
+ * <protocol, caddr, 0, vaddr, 0, daddr, 0>
*/
if (svc->port != FTPPORT)
- ct = ip_vs_conn_new(svc->af, iph.protocol,
- &snet, 0,
- &iph.daddr,
- ports[1],
- &dest->addr, dest->port,
- IP_VS_CONN_F_TEMPLATE,
- dest);
- else
- ct = ip_vs_conn_new(svc->af, iph.protocol,
- &snet, 0,
- &iph.daddr, 0,
- &dest->addr, 0,
- IP_VS_CONN_F_TEMPLATE,
- dest);
- if (ct == NULL)
- return NULL;
-
- ct->timeout = svc->timeout;
+ vport = ports[1];
} else {
- /* set destination with the found template */
- dest = ct->dest;
- }
- dport = dest->port;
- } else {
- /*
- * Note: persistent fwmark-based services and persistent
- * port zero service are handled here.
- * fwmark template: <IPPROTO_IP,caddr,0,fwmark,0,daddr,0>
- * port zero template: <protocol,caddr,0,vaddr,0,daddr,0>
- */
- if (svc->fwmark) {
- union nf_inet_addr fwmark = {
- .ip = htonl(svc->fwmark)
- };
-
- ct = ip_vs_ct_in_get(svc->af, IPPROTO_IP, &snet, 0,
- &fwmark, 0);
- } else
- ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
- &iph.daddr, 0);
-
- if (!ct || !ip_vs_check_template(ct)) {
- /*
- * If it is not persistent port zero, return NULL,
- * otherwise create a connection template.
+ /* Note: persistent fwmark-based services and
+ * persistent port zero service are handled here.
+ * fwmark template:
+ * <IPPROTO_IP,caddr,0,fwmark,0,daddr,0>
+ * port zero template:
+ * <protocol,caddr,0,vaddr,0,daddr,0>
*/
- if (svc->port)
- return NULL;
-
- dest = svc->scheduler->schedule(svc, skb);
- if (dest == NULL) {
- IP_VS_DBG(1, "p-schedule: no dest found.\n");
- return NULL;
+ if (svc->fwmark) {
+ protocol = IPPROTO_IP;
+ vaddr = &fwmark;
}
+ }
+ ip_vs_conn_fill_param_persist(svc, skb, protocol, &snet, 0,
+ vaddr, vport, &param);
+ }
- /*
- * Create a template according to the service
- */
- if (svc->fwmark) {
- union nf_inet_addr fwmark = {
- .ip = htonl(svc->fwmark)
- };
-
- ct = ip_vs_conn_new(svc->af, IPPROTO_IP,
- &snet, 0,
- &fwmark, 0,
- &dest->addr, 0,
- IP_VS_CONN_F_TEMPLATE,
- dest);
- } else
- ct = ip_vs_conn_new(svc->af, iph.protocol,
- &snet, 0,
- &iph.daddr, 0,
- &dest->addr, 0,
- IP_VS_CONN_F_TEMPLATE,
- dest);
- if (ct == NULL)
- return NULL;
-
- ct->timeout = svc->timeout;
- } else {
- /* set destination with the found template */
- dest = ct->dest;
+ /* Check if a template already exists */
+ ct = ip_vs_ct_in_get(&param);
+ if (!ct || !ip_vs_check_template(ct)) {
+ /* No template found or the dest of the connection
+ * template is not available.
+ */
+ dest = svc->scheduler->schedule(svc, skb);
+ if (!dest) {
+ IP_VS_DBG(1, "p-schedule: no dest found.\n");
+ kfree(param.pe_data);
+ return NULL;
}
- dport = ports[1];
+
+ if (ports[1] == svc->port && svc->port != FTPPORT)
+ dport = dest->port;
+
+ /* Create a template
+ * This adds param.pe_data to the template,
+ * and thus param.pe_data will be destroyed
+ * when the template expires */
+ ct = ip_vs_conn_new(&param, &dest->addr, dport,
+ IP_VS_CONN_F_TEMPLATE, dest);
+ if (ct == NULL) {
+ kfree(param.pe_data);
+ return NULL;
+ }
+
+ ct->timeout = svc->timeout;
+ } else {
+ /* set destination with the found template */
+ dest = ct->dest;
+ kfree(param.pe_data);
}
+ dport = ports[1];
+ if (dport == svc->port && dest->port)
+ dport = dest->port;
+
flags = (svc->flags & IP_VS_SVC_F_ONEPACKET
&& iph.protocol == IPPROTO_UDP)?
IP_VS_CONN_F_ONE_PACKET : 0;
@@ -347,12 +317,9 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
/*
* Create a new connection according to the template
*/
- cp = ip_vs_conn_new(svc->af, iph.protocol,
- &iph.saddr, ports[0],
- &iph.daddr, ports[1],
- &dest->addr, dport,
- flags,
- dest);
+ ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, ports[0],
+ &iph.daddr, ports[1], &param);
+ cp = ip_vs_conn_new(&param, &dest->addr, dport, flags, dest);
if (cp == NULL) {
ip_vs_conn_put(ct);
return NULL;
@@ -376,23 +343,53 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
* Protocols supported: TCP, UDP
*/
struct ip_vs_conn *
-ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
+ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
+ struct ip_vs_protocol *pp, int *ignored)
{
struct ip_vs_conn *cp = NULL;
struct ip_vs_iphdr iph;
struct ip_vs_dest *dest;
- __be16 _ports[2], *pptr, flags;
+ __be16 _ports[2], *pptr;
+ unsigned int flags;
+ *ignored = 1;
ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports);
if (pptr == NULL)
return NULL;
/*
+ * FTPDATA needs this check when using local real server.
+ * Never schedule Active FTPDATA connections from real server.
+ * For LVS-NAT they must be already created. For other methods
+ * with persistence the connection is created on SYN+ACK.
+ */
+ if (pptr[0] == FTPDATA) {
+ IP_VS_DBG_PKT(12, svc->af, pp, skb, 0,
+ "Not scheduling FTPDATA");
+ return NULL;
+ }
+
+ /*
+ * Do not schedule replies from local real server. It is risky
+ * for fwmark services but mostly for persistent services.
+ */
+ if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK) &&
+ (svc->flags & IP_VS_SVC_F_PERSISTENT || svc->fwmark) &&
+ (cp = pp->conn_in_get(svc->af, skb, pp, &iph, iph.len, 1))) {
+ IP_VS_DBG_PKT(12, svc->af, pp, skb, 0,
+ "Not scheduling reply for existing connection");
+ __ip_vs_conn_put(cp);
+ return NULL;
+ }
+
+ /*
* Persistent service
*/
- if (svc->flags & IP_VS_SVC_F_PERSISTENT)
+ if (svc->flags & IP_VS_SVC_F_PERSISTENT) {
+ *ignored = 0;
return ip_vs_sched_persist(svc, skb, pptr);
+ }
/*
* Non-persistent service
@@ -405,6 +402,8 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
return NULL;
}
+ *ignored = 0;
+
dest = svc->scheduler->schedule(svc, skb);
if (dest == NULL) {
IP_VS_DBG(1, "Schedule: no dest found.\n");
@@ -418,14 +417,16 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
/*
* Create a connection entry.
*/
- cp = ip_vs_conn_new(svc->af, iph.protocol,
- &iph.saddr, pptr[0],
- &iph.daddr, pptr[1],
- &dest->addr, dest->port ? dest->port : pptr[1],
- flags,
- dest);
- if (cp == NULL)
- return NULL;
+ {
+ struct ip_vs_conn_param p;
+ ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr,
+ pptr[0], &iph.daddr, pptr[1], &p);
+ cp = ip_vs_conn_new(&p, &dest->addr,
+ dest->port ? dest->port : pptr[1],
+ flags, dest);
+ if (!cp)
+ return NULL;
+ }
IP_VS_DBG_BUF(6, "Schedule fwd:%c c:%s:%u v:%s:%u "
"d:%s:%u conn->flags:%X conn->refcnt:%d\n",
@@ -472,23 +473,26 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
if (sysctl_ip_vs_cache_bypass && svc->fwmark && unicast) {
int ret, cs;
struct ip_vs_conn *cp;
- __u16 flags = (svc->flags & IP_VS_SVC_F_ONEPACKET &&
- iph.protocol == IPPROTO_UDP)?
- IP_VS_CONN_F_ONE_PACKET : 0;
+ unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET &&
+ iph.protocol == IPPROTO_UDP)?
+ IP_VS_CONN_F_ONE_PACKET : 0;
union nf_inet_addr daddr = { .all = { 0, 0, 0, 0 } };
ip_vs_service_put(svc);
/* create a new connection entry */
IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__);
- cp = ip_vs_conn_new(svc->af, iph.protocol,
- &iph.saddr, pptr[0],
- &iph.daddr, pptr[1],
- &daddr, 0,
- IP_VS_CONN_F_BYPASS | flags,
- NULL);
- if (cp == NULL)
- return NF_DROP;
+ {
+ struct ip_vs_conn_param p;
+ ip_vs_conn_fill_param(svc->af, iph.protocol,
+ &iph.saddr, pptr[0],
+ &iph.daddr, pptr[1], &p);
+ cp = ip_vs_conn_new(&p, &daddr, 0,
+ IP_VS_CONN_F_BYPASS | flags,
+ NULL);
+ if (!cp)
+ return NF_DROP;
+ }
/* statistics */
ip_vs_in_stats(cp, skb);
@@ -526,9 +530,14 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
* ICMP_PORT_UNREACH is sent here no matter it is TCP/UDP. --WZ
*/
#ifdef CONFIG_IP_VS_IPV6
- if (svc->af == AF_INET6)
+ if (svc->af == AF_INET6) {
+ if (!skb->dev) {
+ struct net *net = dev_net(skb_dst(skb)->dev);
+
+ skb->dev = net->loopback_dev;
+ }
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
- else
+ } else
#endif
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
@@ -540,6 +549,15 @@ __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
}
+static inline enum ip_defrag_users ip_vs_defrag_user(unsigned int hooknum)
+{
+ if (NF_INET_LOCAL_IN == hooknum)
+ return IP_DEFRAG_VS_IN;
+ if (NF_INET_FORWARD == hooknum)
+ return IP_DEFRAG_VS_FWD;
+ return IP_DEFRAG_VS_OUT;
+}
+
static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
{
int err = ip_defrag(skb, user);
@@ -600,10 +618,10 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
skb->ip_summed = CHECKSUM_UNNECESSARY;
if (inout)
- IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph,
+ IP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph,
"Forwarding altered outgoing ICMP");
else
- IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph,
+ IP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph,
"Forwarding altered incoming ICMP");
}
@@ -637,17 +655,21 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
}
/* And finally the ICMP checksum */
- icmph->icmp6_cksum = 0;
- /* TODO IPv6: is this correct for ICMPv6? */
- ip_vs_checksum_complete(skb, icmp_offset);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ icmph->icmp6_cksum = ~csum_ipv6_magic(&iph->saddr, &iph->daddr,
+ skb->len - icmp_offset,
+ IPPROTO_ICMPV6, 0);
+ skb->csum_start = skb_network_header(skb) - skb->head + icmp_offset;
+ skb->csum_offset = offsetof(struct icmp6hdr, icmp6_cksum);
+ skb->ip_summed = CHECKSUM_PARTIAL;
if (inout)
- IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph,
- "Forwarding altered outgoing ICMPv6");
+ IP_VS_DBG_PKT(11, AF_INET6, pp, skb,
+ (void *)ciph - (void *)iph,
+ "Forwarding altered outgoing ICMPv6");
else
- IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph,
- "Forwarding altered incoming ICMPv6");
+ IP_VS_DBG_PKT(11, AF_INET6, pp, skb,
+ (void *)ciph - (void *)iph,
+ "Forwarding altered incoming ICMPv6");
}
#endif
@@ -688,10 +710,25 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
#endif
ip_vs_nat_icmp(skb, pp, cp, 1);
+#ifdef CONFIG_IP_VS_IPV6
+ if (af == AF_INET6) {
+ if (sysctl_ip_vs_snat_reroute && ip6_route_me_harder(skb) != 0)
+ goto out;
+ } else
+#endif
+ if ((sysctl_ip_vs_snat_reroute ||
+ skb_rtable(skb)->rt_flags & RTCF_LOCAL) &&
+ ip_route_me_harder(skb, RTN_LOCAL) != 0)
+ goto out;
+
/* do the statistics and put it back */
ip_vs_out_stats(cp, skb);
skb->ipvs_property = 1;
+ if (!(cp->flags & IP_VS_CONN_F_NFCT))
+ ip_vs_notrack(skb);
+ else
+ ip_vs_update_conntrack(skb, cp, 0);
verdict = NF_ACCEPT;
out:
@@ -705,7 +742,8 @@ out:
* Find any that might be relevant, check against existing connections.
* Currently handles error types - unreachable, quench, ttl exceeded.
*/
-static int ip_vs_out_icmp(struct sk_buff *skb, int *related)
+static int ip_vs_out_icmp(struct sk_buff *skb, int *related,
+ unsigned int hooknum)
{
struct iphdr *iph;
struct icmphdr _icmph, *ic;
@@ -720,7 +758,7 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related)
/* reassemble IP fragments */
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
- if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
+ if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum)))
return NF_STOLEN;
}
@@ -763,7 +801,8 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related)
pp->dont_defrag))
return NF_ACCEPT;
- IP_VS_DBG_PKT(11, pp, skb, offset, "Checking outgoing ICMP for");
+ IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset,
+ "Checking outgoing ICMP for");
offset += cih->ihl * 4;
@@ -779,7 +818,8 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related)
}
#ifdef CONFIG_IP_VS_IPV6
-static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related)
+static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related,
+ unsigned int hooknum)
{
struct ipv6hdr *iph;
struct icmp6hdr _icmph, *ic;
@@ -795,7 +835,7 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related)
/* reassemble IP fragments */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) {
- if (ip_vs_gather_frags_v6(skb, IP_DEFRAG_VS_OUT))
+ if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum)))
return NF_STOLEN;
}
@@ -838,7 +878,8 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related)
if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag))
return NF_ACCEPT;
- IP_VS_DBG_PKT(11, pp, skb, offset, "Checking outgoing ICMPv6 for");
+ IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset,
+ "Checking outgoing ICMPv6 for");
offset += sizeof(struct ipv6hdr);
@@ -886,7 +927,7 @@ static unsigned int
handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
struct ip_vs_conn *cp, int ihl)
{
- IP_VS_DBG_PKT(11, pp, skb, 0, "Outgoing packet");
+ IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet");
if (!skb_make_writable(skb, ihl))
goto drop;
@@ -905,6 +946,15 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
ip_send_check(ip_hdr(skb));
}
+ /*
+ * nf_iterate does not expect change in the skb->dst->dev.
+ * It looks like it is not fatal to enable this code for hooks
+ * where our handlers are at the end of the chain list and
+ * when all next handlers use skb->dst->dev and not outdev.
+ * It will definitely route properly the inout NAT traffic
+ * when multiple paths are used.
+ */
+
/* For policy routing, packets originating from this
* machine itself may be routed differently to packets
* passing through. We want this packet to be routed as
@@ -913,21 +963,25 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
*/
#ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6) {
- if (ip6_route_me_harder(skb) != 0)
+ if (sysctl_ip_vs_snat_reroute && ip6_route_me_harder(skb) != 0)
goto drop;
} else
#endif
- if (ip_route_me_harder(skb, RTN_LOCAL) != 0)
+ if ((sysctl_ip_vs_snat_reroute ||
+ skb_rtable(skb)->rt_flags & RTCF_LOCAL) &&
+ ip_route_me_harder(skb, RTN_LOCAL) != 0)
goto drop;
- IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
+ IP_VS_DBG_PKT(10, af, pp, skb, 0, "After SNAT");
ip_vs_out_stats(cp, skb);
ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp);
- ip_vs_update_conntrack(skb, cp, 0);
- ip_vs_conn_put(cp);
-
skb->ipvs_property = 1;
+ if (!(cp->flags & IP_VS_CONN_F_NFCT))
+ ip_vs_notrack(skb);
+ else
+ ip_vs_update_conntrack(skb, cp, 0);
+ ip_vs_conn_put(cp);
LeaveFunction(11);
return NF_ACCEPT;
@@ -935,35 +989,46 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
drop:
ip_vs_conn_put(cp);
kfree_skb(skb);
+ LeaveFunction(11);
return NF_STOLEN;
}
/*
- * It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT.
* Check if outgoing packet belongs to the established ip_vs_conn.
*/
static unsigned int
-ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
- const struct net_device *in, const struct net_device *out,
- int (*okfn)(struct sk_buff *))
+ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
{
struct ip_vs_iphdr iph;
struct ip_vs_protocol *pp;
struct ip_vs_conn *cp;
- int af;
EnterFunction(11);
- af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
-
+ /* Already marked as IPVS request or reply? */
if (skb->ipvs_property)
return NF_ACCEPT;
+ /* Bad... Do not break raw sockets */
+ if (unlikely(skb->sk != NULL && hooknum == NF_INET_LOCAL_OUT &&
+ af == AF_INET)) {
+ struct sock *sk = skb->sk;
+ struct inet_sock *inet = inet_sk(skb->sk);
+
+ if (inet && sk->sk_family == PF_INET && inet->nodefrag)
+ return NF_ACCEPT;
+ }
+
+ if (unlikely(!skb_dst(skb)))
+ return NF_ACCEPT;
+
ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
#ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6) {
if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
- int related, verdict = ip_vs_out_icmp_v6(skb, &related);
+ int related;
+ int verdict = ip_vs_out_icmp_v6(skb, &related,
+ hooknum);
if (related)
return verdict;
@@ -972,7 +1037,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
} else
#endif
if (unlikely(iph.protocol == IPPROTO_ICMP)) {
- int related, verdict = ip_vs_out_icmp(skb, &related);
+ int related;
+ int verdict = ip_vs_out_icmp(skb, &related, hooknum);
if (related)
return verdict;
@@ -986,19 +1052,19 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
/* reassemble IP fragments */
#ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6) {
- if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
- int related, verdict = ip_vs_out_icmp_v6(skb, &related);
-
- if (related)
- return verdict;
-
- ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
+ if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) {
+ if (ip_vs_gather_frags_v6(skb,
+ ip_vs_defrag_user(hooknum)))
+ return NF_STOLEN;
}
+
+ ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
} else
#endif
if (unlikely(ip_hdr(skb)->frag_off & htons(IP_MF|IP_OFFSET) &&
!pp->dont_defrag)) {
- if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
+ if (ip_vs_gather_frags(skb,
+ ip_vs_defrag_user(hooknum)))
return NF_STOLEN;
ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
@@ -1009,55 +1075,123 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
*/
cp = pp->conn_out_get(af, skb, pp, &iph, iph.len, 0);
- if (unlikely(!cp)) {
- if (sysctl_ip_vs_nat_icmp_send &&
- (pp->protocol == IPPROTO_TCP ||
- pp->protocol == IPPROTO_UDP ||
- pp->protocol == IPPROTO_SCTP)) {
- __be16 _ports[2], *pptr;
-
- pptr = skb_header_pointer(skb, iph.len,
- sizeof(_ports), _ports);
- if (pptr == NULL)
- return NF_ACCEPT; /* Not for me */
- if (ip_vs_lookup_real_service(af, iph.protocol,
- &iph.saddr,
- pptr[0])) {
- /*
- * Notify the real server: there is no
- * existing entry if it is not RST
- * packet or not TCP packet.
- */
- if ((iph.protocol != IPPROTO_TCP &&
- iph.protocol != IPPROTO_SCTP)
- || ((iph.protocol == IPPROTO_TCP
- && !is_tcp_reset(skb, iph.len))
- || (iph.protocol == IPPROTO_SCTP
- && !is_sctp_abort(skb,
- iph.len)))) {
+ if (likely(cp))
+ return handle_response(af, skb, pp, cp, iph.len);
+ if (sysctl_ip_vs_nat_icmp_send &&
+ (pp->protocol == IPPROTO_TCP ||
+ pp->protocol == IPPROTO_UDP ||
+ pp->protocol == IPPROTO_SCTP)) {
+ __be16 _ports[2], *pptr;
+
+ pptr = skb_header_pointer(skb, iph.len,
+ sizeof(_ports), _ports);
+ if (pptr == NULL)
+ return NF_ACCEPT; /* Not for me */
+ if (ip_vs_lookup_real_service(af, iph.protocol,
+ &iph.saddr,
+ pptr[0])) {
+ /*
+ * Notify the real server: there is no
+ * existing entry if it is not RST
+ * packet or not TCP packet.
+ */
+ if ((iph.protocol != IPPROTO_TCP &&
+ iph.protocol != IPPROTO_SCTP)
+ || ((iph.protocol == IPPROTO_TCP
+ && !is_tcp_reset(skb, iph.len))
+ || (iph.protocol == IPPROTO_SCTP
+ && !is_sctp_abort(skb,
+ iph.len)))) {
#ifdef CONFIG_IP_VS_IPV6
- if (af == AF_INET6)
- icmpv6_send(skb,
- ICMPV6_DEST_UNREACH,
- ICMPV6_PORT_UNREACH,
- 0);
- else
+ if (af == AF_INET6) {
+ struct net *net =
+ dev_net(skb_dst(skb)->dev);
+
+ if (!skb->dev)
+ skb->dev = net->loopback_dev;
+ icmpv6_send(skb,
+ ICMPV6_DEST_UNREACH,
+ ICMPV6_PORT_UNREACH,
+ 0);
+ } else
#endif
- icmp_send(skb,
- ICMP_DEST_UNREACH,
- ICMP_PORT_UNREACH, 0);
- return NF_DROP;
- }
+ icmp_send(skb,
+ ICMP_DEST_UNREACH,
+ ICMP_PORT_UNREACH, 0);
+ return NF_DROP;
}
}
- IP_VS_DBG_PKT(12, pp, skb, 0,
- "packet continues traversal as normal");
- return NF_ACCEPT;
}
+ IP_VS_DBG_PKT(12, af, pp, skb, 0,
+ "ip_vs_out: packet continues traversal as normal");
+ return NF_ACCEPT;
+}
+
+/*
+ * It is hooked at the NF_INET_FORWARD and NF_INET_LOCAL_IN chain,
+ * used only for VS/NAT.
+ * Check if packet is reply for established ip_vs_conn.
+ */
+static unsigned int
+ip_vs_reply4(unsigned int hooknum, struct sk_buff *skb,
+ const struct net_device *in, const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ return ip_vs_out(hooknum, skb, AF_INET);
+}
+
+/*
+ * It is hooked at the NF_INET_LOCAL_OUT chain, used only for VS/NAT.
+ * Check if packet is reply for established ip_vs_conn.
+ */
+static unsigned int
+ip_vs_local_reply4(unsigned int hooknum, struct sk_buff *skb,
+ const struct net_device *in, const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ unsigned int verdict;
+
+ /* Disable BH in LOCAL_OUT until all places are fixed */
+ local_bh_disable();
+ verdict = ip_vs_out(hooknum, skb, AF_INET);
+ local_bh_enable();
+ return verdict;
+}
+
+#ifdef CONFIG_IP_VS_IPV6
+
+/*
+ * It is hooked at the NF_INET_FORWARD and NF_INET_LOCAL_IN chain,
+ * used only for VS/NAT.
+ * Check if packet is reply for established ip_vs_conn.
+ */
+static unsigned int
+ip_vs_reply6(unsigned int hooknum, struct sk_buff *skb,
+ const struct net_device *in, const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ return ip_vs_out(hooknum, skb, AF_INET6);
+}
- return handle_response(af, skb, pp, cp, iph.len);
+/*
+ * It is hooked at the NF_INET_LOCAL_OUT chain, used only for VS/NAT.
+ * Check if packet is reply for established ip_vs_conn.
+ */
+static unsigned int
+ip_vs_local_reply6(unsigned int hooknum, struct sk_buff *skb,
+ const struct net_device *in, const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ unsigned int verdict;
+
+ /* Disable BH in LOCAL_OUT until all places are fixed */
+ local_bh_disable();
+ verdict = ip_vs_out(hooknum, skb, AF_INET6);
+ local_bh_enable();
+ return verdict;
}
+#endif
/*
* Handle ICMP messages in the outside-to-inside direction (incoming).
@@ -1081,8 +1215,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
/* reassemble IP fragments */
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
- if (ip_vs_gather_frags(skb, hooknum == NF_INET_LOCAL_IN ?
- IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD))
+ if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum)))
return NF_STOLEN;
}
@@ -1125,7 +1258,8 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
pp->dont_defrag))
return NF_ACCEPT;
- IP_VS_DBG_PKT(11, pp, skb, offset, "Checking incoming ICMP for");
+ IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset,
+ "Checking incoming ICMP for");
offset += cih->ihl * 4;
@@ -1159,7 +1293,14 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol)
offset += 2 * sizeof(__u16);
verdict = ip_vs_icmp_xmit(skb, cp, pp, offset);
- /* do not touch skb anymore */
+ /* 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;
+ }
out:
__ip_vs_conn_put(cp);
@@ -1180,14 +1321,13 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
struct ip_vs_protocol *pp;
unsigned int offset, verdict;
union nf_inet_addr snet;
+ struct rt6_info *rt;
*related = 1;
/* reassemble IP fragments */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) {
- if (ip_vs_gather_frags_v6(skb, hooknum == NF_INET_LOCAL_IN ?
- IP_DEFRAG_VS_IN :
- IP_DEFRAG_VS_FWD))
+ if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum)))
return NF_STOLEN;
}
@@ -1230,7 +1370,8 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag))
return NF_ACCEPT;
- IP_VS_DBG_PKT(11, pp, skb, offset, "Checking incoming ICMPv6 for");
+ IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset,
+ "Checking incoming ICMPv6 for");
offset += sizeof(struct ipv6hdr);
@@ -1258,7 +1399,15 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
IPPROTO_SCTP == cih->nexthdr)
offset += 2 * sizeof(__u16);
verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset);
- /* do not touch skb anymore */
+ /* 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;
+ }
__ip_vs_conn_put(cp);
@@ -1272,35 +1421,49 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
* and send it on its way...
*/
static unsigned int
-ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
- const struct net_device *in, const struct net_device *out,
- int (*okfn)(struct sk_buff *))
+ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
{
struct ip_vs_iphdr iph;
struct ip_vs_protocol *pp;
struct ip_vs_conn *cp;
- int ret, restart, af, pkts;
+ int ret, restart, pkts;
- af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
-
- ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
+ /* Already marked as IPVS request or reply? */
+ if (skb->ipvs_property)
+ return NF_ACCEPT;
/*
- * Big tappo: only PACKET_HOST, including loopback for local client
- * Don't handle local packets on IPv6 for now
+ * Big tappo:
+ * - remote client: only PACKET_HOST
+ * - route: used for struct net when skb->dev is unset
*/
- if (unlikely(skb->pkt_type != PACKET_HOST)) {
- IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s ignored\n",
- skb->pkt_type,
- iph.protocol,
- IP_VS_DBG_ADDR(af, &iph.daddr));
+ if (unlikely((skb->pkt_type != PACKET_HOST &&
+ hooknum != NF_INET_LOCAL_OUT) ||
+ !skb_dst(skb))) {
+ ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
+ IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s"
+ " ignored in hook %u\n",
+ skb->pkt_type, iph.protocol,
+ IP_VS_DBG_ADDR(af, &iph.daddr), hooknum);
return NF_ACCEPT;
}
+ ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
+
+ /* Bad... Do not break raw sockets */
+ if (unlikely(skb->sk != NULL && hooknum == NF_INET_LOCAL_OUT &&
+ af == AF_INET)) {
+ struct sock *sk = skb->sk;
+ struct inet_sock *inet = inet_sk(skb->sk);
+
+ if (inet && sk->sk_family == PF_INET && inet->nodefrag)
+ return NF_ACCEPT;
+ }
#ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6) {
if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
- int related, verdict = ip_vs_in_icmp_v6(skb, &related, hooknum);
+ int related;
+ int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum);
if (related)
return verdict;
@@ -1309,7 +1472,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
} else
#endif
if (unlikely(iph.protocol == IPPROTO_ICMP)) {
- int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
+ int related;
+ int verdict = ip_vs_in_icmp(skb, &related, hooknum);
if (related)
return verdict;
@@ -1329,23 +1493,18 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
if (unlikely(!cp)) {
int v;
- /* For local client packets, it could be a response */
- cp = pp->conn_out_get(af, skb, pp, &iph, iph.len, 0);
- if (cp)
- return handle_response(af, skb, pp, cp, iph.len);
-
if (!pp->conn_schedule(af, skb, pp, &v, &cp))
return v;
}
if (unlikely(!cp)) {
/* sorry, all this trouble for a no-hit :) */
- IP_VS_DBG_PKT(12, pp, skb, 0,
- "packet continues traversal as normal");
+ IP_VS_DBG_PKT(12, af, pp, skb, 0,
+ "ip_vs_in: packet continues traversal as normal");
return NF_ACCEPT;
}
- IP_VS_DBG_PKT(11, pp, skb, 0, "Incoming packet");
+ IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet");
/* Check the server status */
if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
@@ -1381,8 +1540,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
if (af == AF_INET && (ip_vs_sync_state & IP_VS_STATE_MASTER) &&
cp->protocol == IPPROTO_SCTP) {
if ((cp->state == IP_VS_SCTP_S_ESTABLISHED &&
- (atomic_read(&cp->in_pkts) %
- sysctl_ip_vs_sync_threshold[1]
+ (pkts % sysctl_ip_vs_sync_threshold[1]
== sysctl_ip_vs_sync_threshold[0])) ||
(cp->old_state != cp->state &&
((cp->state == IP_VS_SCTP_S_CLOSED) ||
@@ -1393,7 +1551,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
}
}
- if (af == AF_INET &&
+ /* Keep this block last: TCP and others with pp->num_states <= 1 */
+ else if (af == AF_INET &&
(ip_vs_sync_state & IP_VS_STATE_MASTER) &&
(((cp->protocol != IPPROTO_TCP ||
cp->state == IP_VS_TCP_S_ESTABLISHED) &&
@@ -1412,6 +1571,72 @@ out:
return ret;
}
+/*
+ * AF_INET handler in NF_INET_LOCAL_IN chain
+ * Schedule and forward packets from remote clients
+ */
+static unsigned int
+ip_vs_remote_request4(unsigned int hooknum, struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ return ip_vs_in(hooknum, skb, AF_INET);
+}
+
+/*
+ * AF_INET handler in NF_INET_LOCAL_OUT chain
+ * Schedule and forward packets from local clients
+ */
+static unsigned int
+ip_vs_local_request4(unsigned int hooknum, struct sk_buff *skb,
+ const struct net_device *in, const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ unsigned int verdict;
+
+ /* Disable BH in LOCAL_OUT until all places are fixed */
+ local_bh_disable();
+ verdict = ip_vs_in(hooknum, skb, AF_INET);
+ local_bh_enable();
+ return verdict;
+}
+
+#ifdef CONFIG_IP_VS_IPV6
+
+/*
+ * AF_INET6 handler in NF_INET_LOCAL_IN chain
+ * Schedule and forward packets from remote clients
+ */
+static unsigned int
+ip_vs_remote_request6(unsigned int hooknum, struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ return ip_vs_in(hooknum, skb, AF_INET6);
+}
+
+/*
+ * AF_INET6 handler in NF_INET_LOCAL_OUT chain
+ * Schedule and forward packets from local clients
+ */
+static unsigned int
+ip_vs_local_request6(unsigned int hooknum, struct sk_buff *skb,
+ const struct net_device *in, const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ unsigned int verdict;
+
+ /* Disable BH in LOCAL_OUT until all places are fixed */
+ local_bh_disable();
+ verdict = ip_vs_in(hooknum, skb, AF_INET6);
+ local_bh_enable();
+ return verdict;
+}
+
+#endif
+
/*
* It is hooked at the NF_INET_FORWARD chain, in order to catch ICMP
@@ -1452,23 +1677,39 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb,
static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
+ /* After packet filtering, change source only for VS/NAT */
+ {
+ .hook = ip_vs_reply4,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_INET_LOCAL_IN,
+ .priority = 99,
+ },
/* After packet filtering, forward packet through VS/DR, VS/TUN,
* or VS/NAT(change destination), so that filtering rules can be
* applied to IPVS. */
{
- .hook = ip_vs_in,
+ .hook = ip_vs_remote_request4,
.owner = THIS_MODULE,
.pf = PF_INET,
- .hooknum = NF_INET_LOCAL_IN,
- .priority = 100,
+ .hooknum = NF_INET_LOCAL_IN,
+ .priority = 101,
},
- /* After packet filtering, change source only for VS/NAT */
+ /* Before ip_vs_in, change source only for VS/NAT */
{
- .hook = ip_vs_out,
+ .hook = ip_vs_local_reply4,
.owner = THIS_MODULE,
.pf = PF_INET,
- .hooknum = NF_INET_FORWARD,
- .priority = 100,
+ .hooknum = NF_INET_LOCAL_OUT,
+ .priority = -99,
+ },
+ /* After mangle, schedule and forward local requests */
+ {
+ .hook = ip_vs_local_request4,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_INET_LOCAL_OUT,
+ .priority = -98,
},
/* After packet filtering (but before ip_vs_out_icmp), catch icmp
* destined for 0.0.0.0/0, which is for incoming IPVS connections */
@@ -1476,27 +1717,51 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
.hook = ip_vs_forward_icmp,
.owner = THIS_MODULE,
.pf = PF_INET,
- .hooknum = NF_INET_FORWARD,
- .priority = 99,
+ .hooknum = NF_INET_FORWARD,
+ .priority = 99,
+ },
+ /* After packet filtering, change source only for VS/NAT */
+ {
+ .hook = ip_vs_reply4,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_INET_FORWARD,
+ .priority = 100,
},
#ifdef CONFIG_IP_VS_IPV6
+ /* After packet filtering, change source only for VS/NAT */
+ {
+ .hook = ip_vs_reply6,
+ .owner = THIS_MODULE,
+ .pf = PF_INET6,
+ .hooknum = NF_INET_LOCAL_IN,
+ .priority = 99,
+ },
/* After packet filtering, forward packet through VS/DR, VS/TUN,
* or VS/NAT(change destination), so that filtering rules can be
* applied to IPVS. */
{
- .hook = ip_vs_in,
+ .hook = ip_vs_remote_request6,
.owner = THIS_MODULE,
.pf = PF_INET6,
- .hooknum = NF_INET_LOCAL_IN,
- .priority = 100,
+ .hooknum = NF_INET_LOCAL_IN,
+ .priority = 101,
},
- /* After packet filtering, change source only for VS/NAT */
+ /* Before ip_vs_in, change source only for VS/NAT */
+ {
+ .hook = ip_vs_local_reply6,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_INET_LOCAL_OUT,
+ .priority = -99,
+ },
+ /* After mangle, schedule and forward local requests */
{
- .hook = ip_vs_out,
+ .hook = ip_vs_local_request6,
.owner = THIS_MODULE,
.pf = PF_INET6,
- .hooknum = NF_INET_FORWARD,
- .priority = 100,
+ .hooknum = NF_INET_LOCAL_OUT,
+ .priority = -98,
},
/* After packet filtering (but before ip_vs_out_icmp), catch icmp
* destined for 0.0.0.0/0, which is for incoming IPVS connections */
@@ -1504,8 +1769,16 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
.hook = ip_vs_forward_icmp_v6,
.owner = THIS_MODULE,
.pf = PF_INET6,
- .hooknum = NF_INET_FORWARD,
- .priority = 99,
+ .hooknum = NF_INET_FORWARD,
+ .priority = 99,
+ },
+ /* After packet filtering, change source only for VS/NAT */
+ {
+ .hook = ip_vs_reply6,
+ .owner = THIS_MODULE,
+ .pf = PF_INET6,
+ .hooknum = NF_INET_FORWARD,
+ .priority = 100,
},
#endif
};
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 0f0c079c422a..5f5daa30b0af 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -61,7 +61,7 @@ static DEFINE_RWLOCK(__ip_vs_svc_lock);
static DEFINE_RWLOCK(__ip_vs_rs_lock);
/* lock for state and timeout tables */
-static DEFINE_RWLOCK(__ip_vs_securetcp_lock);
+static DEFINE_SPINLOCK(ip_vs_securetcp_lock);
/* lock for drop entry handling */
static DEFINE_SPINLOCK(__ip_vs_dropentry_lock);
@@ -88,6 +88,10 @@ int sysctl_ip_vs_expire_nodest_conn = 0;
int sysctl_ip_vs_expire_quiescent_template = 0;
int sysctl_ip_vs_sync_threshold[2] = { 3, 50 };
int sysctl_ip_vs_nat_icmp_send = 0;
+#ifdef CONFIG_IP_VS_NFCT
+int sysctl_ip_vs_conntrack;
+#endif
+int sysctl_ip_vs_snat_reroute = 1;
#ifdef CONFIG_IP_VS_DEBUG
@@ -204,7 +208,7 @@ static void update_defense_level(void)
spin_unlock(&__ip_vs_droppacket_lock);
/* secure_tcp */
- write_lock(&__ip_vs_securetcp_lock);
+ spin_lock(&ip_vs_securetcp_lock);
switch (sysctl_ip_vs_secure_tcp) {
case 0:
if (old_secure_tcp >= 2)
@@ -238,7 +242,7 @@ static void update_defense_level(void)
old_secure_tcp = sysctl_ip_vs_secure_tcp;
if (to_change >= 0)
ip_vs_protocol_timeout_change(sysctl_ip_vs_secure_tcp>1);
- write_unlock(&__ip_vs_securetcp_lock);
+ spin_unlock(&ip_vs_securetcp_lock);
local_bh_enable();
}
@@ -401,7 +405,7 @@ static int ip_vs_svc_unhash(struct ip_vs_service *svc)
* Get service by {proto,addr,port} in the service table.
*/
static inline struct ip_vs_service *
-__ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr,
+__ip_vs_service_find(int af, __u16 protocol, const union nf_inet_addr *vaddr,
__be16 vport)
{
unsigned hash;
@@ -416,7 +420,6 @@ __ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr,
&& (svc->port == vport)
&& (svc->protocol == protocol)) {
/* HIT */
- atomic_inc(&svc->usecnt);
return svc;
}
}
@@ -429,7 +432,7 @@ __ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr,
* Get service by {fwmark} in the service table.
*/
static inline struct ip_vs_service *
-__ip_vs_svc_fwm_get(int af, __u32 fwmark)
+__ip_vs_svc_fwm_find(int af, __u32 fwmark)
{
unsigned hash;
struct ip_vs_service *svc;
@@ -440,7 +443,6 @@ __ip_vs_svc_fwm_get(int af, __u32 fwmark)
list_for_each_entry(svc, &ip_vs_svc_fwm_table[hash], f_list) {
if (svc->fwmark == fwmark && svc->af == af) {
/* HIT */
- atomic_inc(&svc->usecnt);
return svc;
}
}
@@ -459,14 +461,14 @@ ip_vs_service_get(int af, __u32 fwmark, __u16 protocol,
/*
* Check the table hashed by fwmark first
*/
- if (fwmark && (svc = __ip_vs_svc_fwm_get(af, fwmark)))
+ if (fwmark && (svc = __ip_vs_svc_fwm_find(af, fwmark)))
goto out;
/*
* Check the table hashed by <protocol,addr,port>
* for "full" addressed entries
*/
- svc = __ip_vs_service_get(af, protocol, vaddr, vport);
+ svc = __ip_vs_service_find(af, protocol, vaddr, vport);
if (svc == NULL
&& protocol == IPPROTO_TCP
@@ -476,7 +478,7 @@ ip_vs_service_get(int af, __u32 fwmark, __u16 protocol,
* Check if ftp service entry exists, the packet
* might belong to FTP data connections.
*/
- svc = __ip_vs_service_get(af, protocol, vaddr, FTPPORT);
+ svc = __ip_vs_service_find(af, protocol, vaddr, FTPPORT);
}
if (svc == NULL
@@ -484,10 +486,12 @@ ip_vs_service_get(int af, __u32 fwmark, __u16 protocol,
/*
* Check if the catch-all port (port zero) exists
*/
- svc = __ip_vs_service_get(af, protocol, vaddr, 0);
+ svc = __ip_vs_service_find(af, protocol, vaddr, 0);
}
out:
+ if (svc)
+ atomic_inc(&svc->usecnt);
read_unlock(&__ip_vs_svc_lock);
IP_VS_DBG_BUF(9, "lookup service: fwm %u %s %s:%u %s\n",
@@ -506,14 +510,19 @@ __ip_vs_bind_svc(struct ip_vs_dest *dest, struct ip_vs_service *svc)
dest->svc = svc;
}
-static inline void
+static void
__ip_vs_unbind_svc(struct ip_vs_dest *dest)
{
struct ip_vs_service *svc = dest->svc;
dest->svc = NULL;
- if (atomic_dec_and_test(&svc->refcnt))
+ if (atomic_dec_and_test(&svc->refcnt)) {
+ IP_VS_DBG_BUF(3, "Removing service %u/%s:%u usecnt=%d\n",
+ svc->fwmark,
+ IP_VS_DBG_ADDR(svc->af, &svc->addr),
+ ntohs(svc->port), atomic_read(&svc->usecnt));
kfree(svc);
+ }
}
@@ -758,31 +767,18 @@ ip_vs_zero_stats(struct ip_vs_stats *stats)
* Update a destination in the given service
*/
static void
-__ip_vs_update_dest(struct ip_vs_service *svc,
- struct ip_vs_dest *dest, struct ip_vs_dest_user_kern *udest)
+__ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
+ struct ip_vs_dest_user_kern *udest, int add)
{
int conn_flags;
/* set the weight and the flags */
atomic_set(&dest->weight, udest->weight);
- conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE;
-
- /* check if local node and update the flags */
-#ifdef CONFIG_IP_VS_IPV6
- if (svc->af == AF_INET6) {
- if (__ip_vs_addr_is_local_v6(&udest->addr.in6)) {
- conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
- | IP_VS_CONN_F_LOCALNODE;
- }
- } else
-#endif
- if (inet_addr_type(&init_net, udest->addr.ip) == RTN_LOCAL) {
- conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
- | IP_VS_CONN_F_LOCALNODE;
- }
+ conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK;
+ conn_flags |= IP_VS_CONN_F_INACTIVE;
/* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */
- if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != 0) {
+ if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != IP_VS_CONN_F_MASQ) {
conn_flags |= IP_VS_CONN_F_NOOUTPUT;
} else {
/*
@@ -813,6 +809,29 @@ __ip_vs_update_dest(struct ip_vs_service *svc,
dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
dest->u_threshold = udest->u_threshold;
dest->l_threshold = udest->l_threshold;
+
+ spin_lock(&dest->dst_lock);
+ ip_vs_dst_reset(dest);
+ spin_unlock(&dest->dst_lock);
+
+ if (add)
+ ip_vs_new_estimator(&dest->stats);
+
+ write_lock_bh(&__ip_vs_svc_lock);
+
+ /* Wait until all other svc users go away */
+ IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0);
+
+ if (add) {
+ list_add(&dest->n_list, &svc->destinations);
+ svc->num_dests++;
+ }
+
+ /* call the update_service, because server weight may be changed */
+ if (svc->scheduler->update_service)
+ svc->scheduler->update_service(svc);
+
+ write_unlock_bh(&__ip_vs_svc_lock);
}
@@ -843,7 +862,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest,
return -EINVAL;
}
- dest = kzalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC);
+ dest = kzalloc(sizeof(struct ip_vs_dest), GFP_KERNEL);
if (dest == NULL) {
pr_err("%s(): no memory.\n", __func__);
return -ENOMEM;
@@ -860,13 +879,12 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest,
atomic_set(&dest->activeconns, 0);
atomic_set(&dest->inactconns, 0);
atomic_set(&dest->persistconns, 0);
- atomic_set(&dest->refcnt, 0);
+ atomic_set(&dest->refcnt, 1);
INIT_LIST_HEAD(&dest->d_list);
spin_lock_init(&dest->dst_lock);
spin_lock_init(&dest->stats.lock);
- __ip_vs_update_dest(svc, dest, udest);
- ip_vs_new_estimator(&dest->stats);
+ __ip_vs_update_dest(svc, dest, udest, 1);
*dest_p = dest;
@@ -926,65 +944,22 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
IP_VS_DBG_ADDR(svc->af, &dest->vaddr),
ntohs(dest->vport));
- __ip_vs_update_dest(svc, dest, udest);
-
/*
* Get the destination from the trash
*/
list_del(&dest->n_list);
- ip_vs_new_estimator(&dest->stats);
-
- write_lock_bh(&__ip_vs_svc_lock);
-
+ __ip_vs_update_dest(svc, dest, udest, 1);
+ ret = 0;
+ } else {
/*
- * Wait until all other svc users go away.
+ * Allocate and initialize the dest structure
*/
- IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1);
-
- list_add(&dest->n_list, &svc->destinations);
- svc->num_dests++;
-
- /* call the update_service function of its scheduler */
- if (svc->scheduler->update_service)
- svc->scheduler->update_service(svc);
-
- write_unlock_bh(&__ip_vs_svc_lock);
- return 0;
- }
-
- /*
- * Allocate and initialize the dest structure
- */
- ret = ip_vs_new_dest(svc, udest, &dest);
- if (ret) {
- return ret;
+ ret = ip_vs_new_dest(svc, udest, &dest);
}
-
- /*
- * Add the dest entry into the list
- */
- atomic_inc(&dest->refcnt);
-
- write_lock_bh(&__ip_vs_svc_lock);
-
- /*
- * Wait until all other svc users go away.
- */
- IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1);
-
- list_add(&dest->n_list, &svc->destinations);
- svc->num_dests++;
-
- /* call the update_service function of its scheduler */
- if (svc->scheduler->update_service)
- svc->scheduler->update_service(svc);
-
- write_unlock_bh(&__ip_vs_svc_lock);
-
LeaveFunction(2);
- return 0;
+ return ret;
}
@@ -1023,19 +998,7 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
return -ENOENT;
}
- __ip_vs_update_dest(svc, dest, udest);
-
- write_lock_bh(&__ip_vs_svc_lock);
-
- /* Wait until all other svc users go away */
- IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1);
-
- /* call the update_service, because server weight may be changed */
- if (svc->scheduler->update_service)
- svc->scheduler->update_service(svc);
-
- write_unlock_bh(&__ip_vs_svc_lock);
-
+ __ip_vs_update_dest(svc, dest, udest, 0);
LeaveFunction(2);
return 0;
@@ -1062,6 +1025,10 @@ static void __ip_vs_del_dest(struct ip_vs_dest *dest)
* the destination into the trash.
*/
if (atomic_dec_and_test(&dest->refcnt)) {
+ IP_VS_DBG_BUF(3, "Removing destination %u/%s:%u\n",
+ dest->vfwmark,
+ IP_VS_DBG_ADDR(dest->af, &dest->addr),
+ ntohs(dest->port));
ip_vs_dst_reset(dest);
/* simply decrease svc->refcnt here, let the caller check
and release the service if nobody refers to it.
@@ -1128,7 +1095,7 @@ ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
/*
* Wait until all other svc users go away.
*/
- IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1);
+ IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0);
/*
* Unlink dest from the service
@@ -1157,6 +1124,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
{
int ret = 0;
struct ip_vs_scheduler *sched = NULL;
+ struct ip_vs_pe *pe = NULL;
struct ip_vs_service *svc = NULL;
/* increase the module use count */
@@ -1167,7 +1135,17 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
if (sched == NULL) {
pr_info("Scheduler module ip_vs_%s not found\n", u->sched_name);
ret = -ENOENT;
- goto out_mod_dec;
+ goto out_err;
+ }
+
+ if (u->pe_name && *u->pe_name) {
+ pe = ip_vs_pe_get(u->pe_name);
+ if (pe == NULL) {
+ pr_info("persistence engine module ip_vs_pe_%s "
+ "not found\n", u->pe_name);
+ ret = -ENOENT;
+ goto out_err;
+ }
}
#ifdef CONFIG_IP_VS_IPV6
@@ -1177,7 +1155,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
}
#endif
- svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC);
+ svc = kzalloc(sizeof(struct ip_vs_service), GFP_KERNEL);
if (svc == NULL) {
IP_VS_DBG(1, "%s(): no memory\n", __func__);
ret = -ENOMEM;
@@ -1185,7 +1163,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
}
/* I'm the first user of the service */
- atomic_set(&svc->usecnt, 1);
+ atomic_set(&svc->usecnt, 0);
atomic_set(&svc->refcnt, 0);
svc->af = u->af;
@@ -1207,6 +1185,10 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
goto out_err;
sched = NULL;
+ /* Bind the ct retriever */
+ ip_vs_bind_pe(svc, pe);
+ pe = NULL;
+
/* Update the virtual service counters */
if (svc->port == FTPPORT)
atomic_inc(&ip_vs_ftpsvc_counter);
@@ -1227,10 +1209,9 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
*svc_p = svc;
return 0;
- out_err:
+ out_err:
if (svc != NULL) {
- if (svc->scheduler)
- ip_vs_unbind_scheduler(svc);
+ ip_vs_unbind_scheduler(svc);
if (svc->inc) {
local_bh_disable();
ip_vs_app_inc_put(svc->inc);
@@ -1239,8 +1220,8 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
kfree(svc);
}
ip_vs_scheduler_put(sched);
+ ip_vs_pe_put(pe);
- out_mod_dec:
/* decrease the module use count */
ip_vs_use_count_dec();
@@ -1255,6 +1236,7 @@ static int
ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)
{
struct ip_vs_scheduler *sched, *old_sched;
+ struct ip_vs_pe *pe = NULL, *old_pe = NULL;
int ret = 0;
/*
@@ -1267,6 +1249,17 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)
}
old_sched = sched;
+ if (u->pe_name && *u->pe_name) {
+ pe = ip_vs_pe_get(u->pe_name);
+ if (pe == NULL) {
+ pr_info("persistence engine module ip_vs_pe_%s "
+ "not found\n", u->pe_name);
+ ret = -ENOENT;
+ goto out;
+ }
+ old_pe = pe;
+ }
+
#ifdef CONFIG_IP_VS_IPV6
if (u->af == AF_INET6 && (u->netmask < 1 || u->netmask > 128)) {
ret = -EINVAL;
@@ -1279,7 +1272,7 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)
/*
* Wait until all other svc users go away.
*/
- IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1);
+ IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0);
/*
* Set the flags and timeout value
@@ -1318,15 +1311,17 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)
}
}
+ old_pe = svc->pe;
+ if (pe != old_pe) {
+ ip_vs_unbind_pe(svc);
+ ip_vs_bind_pe(svc, pe);
+ }
+
out_unlock:
write_unlock_bh(&__ip_vs_svc_lock);
-#ifdef CONFIG_IP_VS_IPV6
out:
-#endif
-
- if (old_sched)
- ip_vs_scheduler_put(old_sched);
-
+ ip_vs_scheduler_put(old_sched);
+ ip_vs_pe_put(old_pe);
return ret;
}
@@ -1340,6 +1335,9 @@ static void __ip_vs_del_service(struct ip_vs_service *svc)
{
struct ip_vs_dest *dest, *nxt;
struct ip_vs_scheduler *old_sched;
+ struct ip_vs_pe *old_pe;
+
+ pr_info("%s: enter\n", __func__);
/* Count only IPv4 services for old get/setsockopt interface */
if (svc->af == AF_INET)
@@ -1350,8 +1348,12 @@ static void __ip_vs_del_service(struct ip_vs_service *svc)
/* Unbind scheduler */
old_sched = svc->scheduler;
ip_vs_unbind_scheduler(svc);
- if (old_sched)
- ip_vs_scheduler_put(old_sched);
+ ip_vs_scheduler_put(old_sched);
+
+ /* Unbind persistence engine */
+ old_pe = svc->pe;
+ ip_vs_unbind_pe(svc);
+ ip_vs_pe_put(old_pe);
/* Unbind app inc */
if (svc->inc) {
@@ -1378,21 +1380,23 @@ static void __ip_vs_del_service(struct ip_vs_service *svc)
/*
* Free the service if nobody refers to it
*/
- if (atomic_read(&svc->refcnt) == 0)
+ if (atomic_read(&svc->refcnt) == 0) {
+ IP_VS_DBG_BUF(3, "Removing service %u/%s:%u usecnt=%d\n",
+ svc->fwmark,
+ IP_VS_DBG_ADDR(svc->af, &svc->addr),
+ ntohs(svc->port), atomic_read(&svc->usecnt));
kfree(svc);
+ }
/* decrease the module use count */
ip_vs_use_count_dec();
}
/*
- * Delete a service from the service list
+ * Unlink a service from list and try to delete it if its refcnt reached 0
*/
-static int ip_vs_del_service(struct ip_vs_service *svc)
+static void ip_vs_unlink_service(struct ip_vs_service *svc)
{
- if (svc == NULL)
- return -EEXIST;
-
/*
* Unhash it from the service table
*/
@@ -1403,11 +1407,21 @@ static int ip_vs_del_service(struct ip_vs_service *svc)
/*
* Wait until all the svc users go away.
*/
- IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1);
+ IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0);
__ip_vs_del_service(svc);
write_unlock_bh(&__ip_vs_svc_lock);
+}
+
+/*
+ * Delete a service from the service list
+ */
+static int ip_vs_del_service(struct ip_vs_service *svc)
+{
+ if (svc == NULL)
+ return -EEXIST;
+ ip_vs_unlink_service(svc);
return 0;
}
@@ -1426,14 +1440,7 @@ static int ip_vs_flush(void)
*/
for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
list_for_each_entry_safe(svc, nxt, &ip_vs_svc_table[idx], s_list) {
- write_lock_bh(&__ip_vs_svc_lock);
- ip_vs_svc_unhash(svc);
- /*
- * Wait until all the svc users go away.
- */
- IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0);
- __ip_vs_del_service(svc);
- write_unlock_bh(&__ip_vs_svc_lock);
+ ip_vs_unlink_service(svc);
}
}
@@ -1443,14 +1450,7 @@ static int ip_vs_flush(void)
for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
list_for_each_entry_safe(svc, nxt,
&ip_vs_svc_fwm_table[idx], f_list) {
- write_lock_bh(&__ip_vs_svc_lock);
- ip_vs_svc_unhash(svc);
- /*
- * Wait until all the svc users go away.
- */
- IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0);
- __ip_vs_del_service(svc);
- write_unlock_bh(&__ip_vs_svc_lock);
+ ip_vs_unlink_service(svc);
}
}
@@ -1579,6 +1579,15 @@ static struct ctl_table vs_vars[] = {
.mode = 0644,
.proc_handler = proc_do_defense_mode,
},
+#ifdef CONFIG_IP_VS_NFCT
+ {
+ .procname = "conntrack",
+ .data = &sysctl_ip_vs_conntrack,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
{
.procname = "secure_tcp",
.data = &sysctl_ip_vs_secure_tcp,
@@ -1586,6 +1595,13 @@ static struct ctl_table vs_vars[] = {
.mode = 0644,
.proc_handler = proc_do_defense_mode,
},
+ {
+ .procname = "snat_reroute",
+ .data = &sysctl_ip_vs_snat_reroute,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
#if 0
{
.procname = "timeout_established",
@@ -2041,6 +2057,8 @@ static const unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = {
static void ip_vs_copy_usvc_compat(struct ip_vs_service_user_kern *usvc,
struct ip_vs_service_user *usvc_compat)
{
+ memset(usvc, 0, sizeof(*usvc));
+
usvc->af = AF_INET;
usvc->protocol = usvc_compat->protocol;
usvc->addr.ip = usvc_compat->addr;
@@ -2058,6 +2076,8 @@ static void ip_vs_copy_usvc_compat(struct ip_vs_service_user_kern *usvc,
static void ip_vs_copy_udest_compat(struct ip_vs_dest_user_kern *udest,
struct ip_vs_dest_user *udest_compat)
{
+ memset(udest, 0, sizeof(*udest));
+
udest->addr.ip = udest_compat->addr;
udest->port = udest_compat->port;
udest->conn_flags = udest_compat->conn_flags;
@@ -2147,10 +2167,10 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
/* Lookup the exact service by <protocol, addr, port> or fwmark */
if (usvc.fwmark == 0)
- svc = __ip_vs_service_get(usvc.af, usvc.protocol,
- &usvc.addr, usvc.port);
+ svc = __ip_vs_service_find(usvc.af, usvc.protocol,
+ &usvc.addr, usvc.port);
else
- svc = __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark);
+ svc = __ip_vs_svc_fwm_find(usvc.af, usvc.fwmark);
if (cmd != IP_VS_SO_SET_ADD
&& (svc == NULL || svc->protocol != usvc.protocol)) {
@@ -2189,9 +2209,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
ret = -EINVAL;
}
- if (svc)
- ip_vs_service_put(svc);
-
out_unlock:
mutex_unlock(&__ip_vs_mutex);
out_dec:
@@ -2284,10 +2301,10 @@ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get,
int ret = 0;
if (get->fwmark)
- svc = __ip_vs_svc_fwm_get(AF_INET, get->fwmark);
+ svc = __ip_vs_svc_fwm_find(AF_INET, get->fwmark);
else
- svc = __ip_vs_service_get(AF_INET, get->protocol, &addr,
- get->port);
+ svc = __ip_vs_service_find(AF_INET, get->protocol, &addr,
+ get->port);
if (svc) {
int count = 0;
@@ -2315,7 +2332,6 @@ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get,
}
count++;
}
- ip_vs_service_put(svc);
} else
ret = -ESRCH;
return ret;
@@ -2436,15 +2452,14 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
entry = (struct ip_vs_service_entry *)arg;
addr.ip = entry->addr;
if (entry->fwmark)
- svc = __ip_vs_svc_fwm_get(AF_INET, entry->fwmark);
+ svc = __ip_vs_svc_fwm_find(AF_INET, entry->fwmark);
else
- svc = __ip_vs_service_get(AF_INET, entry->protocol,
- &addr, entry->port);
+ svc = __ip_vs_service_find(AF_INET, entry->protocol,
+ &addr, entry->port);
if (svc) {
ip_vs_copy_service(entry, svc);
if (copy_to_user(user, entry, sizeof(*entry)) != 0)
ret = -EFAULT;
- ip_vs_service_put(svc);
} else
ret = -ESRCH;
}
@@ -2559,6 +2574,8 @@ static const struct nla_policy ip_vs_svc_policy[IPVS_SVC_ATTR_MAX + 1] = {
[IPVS_SVC_ATTR_FWMARK] = { .type = NLA_U32 },
[IPVS_SVC_ATTR_SCHED_NAME] = { .type = NLA_NUL_STRING,
.len = IP_VS_SCHEDNAME_MAXLEN },
+ [IPVS_SVC_ATTR_PE_NAME] = { .type = NLA_NUL_STRING,
+ .len = IP_VS_PENAME_MAXLEN },
[IPVS_SVC_ATTR_FLAGS] = { .type = NLA_BINARY,
.len = sizeof(struct ip_vs_flags) },
[IPVS_SVC_ATTR_TIMEOUT] = { .type = NLA_U32 },
@@ -2635,6 +2652,8 @@ static int ip_vs_genl_fill_service(struct sk_buff *skb,
}
NLA_PUT_STRING(skb, IPVS_SVC_ATTR_SCHED_NAME, svc->scheduler->name);
+ if (svc->pe)
+ NLA_PUT_STRING(skb, IPVS_SVC_ATTR_PE_NAME, svc->pe->name);
NLA_PUT(skb, IPVS_SVC_ATTR_FLAGS, sizeof(flags), &flags);
NLA_PUT_U32(skb, IPVS_SVC_ATTR_TIMEOUT, svc->timeout / HZ);
NLA_PUT_U32(skb, IPVS_SVC_ATTR_NETMASK, svc->netmask);
@@ -2711,10 +2730,12 @@ nla_put_failure:
}
static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc,
- struct nlattr *nla, int full_entry)
+ struct nlattr *nla, int full_entry,
+ struct ip_vs_service **ret_svc)
{
struct nlattr *attrs[IPVS_SVC_ATTR_MAX + 1];
struct nlattr *nla_af, *nla_port, *nla_fwmark, *nla_protocol, *nla_addr;
+ struct ip_vs_service *svc;
/* Parse mandatory identifying service fields first */
if (nla == NULL ||
@@ -2750,14 +2771,21 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc,
usvc->fwmark = 0;
}
+ if (usvc->fwmark)
+ svc = __ip_vs_svc_fwm_find(usvc->af, usvc->fwmark);
+ else
+ svc = __ip_vs_service_find(usvc->af, usvc->protocol,
+ &usvc->addr, usvc->port);
+ *ret_svc = svc;
+
/* If a full entry was requested, check for the additional fields */
if (full_entry) {
- struct nlattr *nla_sched, *nla_flags, *nla_timeout,
+ struct nlattr *nla_sched, *nla_flags, *nla_pe, *nla_timeout,
*nla_netmask;
struct ip_vs_flags flags;
- struct ip_vs_service *svc;
nla_sched = attrs[IPVS_SVC_ATTR_SCHED_NAME];
+ nla_pe = attrs[IPVS_SVC_ATTR_PE_NAME];
nla_flags = attrs[IPVS_SVC_ATTR_FLAGS];
nla_timeout = attrs[IPVS_SVC_ATTR_TIMEOUT];
nla_netmask = attrs[IPVS_SVC_ATTR_NETMASK];
@@ -2768,21 +2796,14 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc,
nla_memcpy(&flags, nla_flags, sizeof(flags));
/* prefill flags from service if it already exists */
- if (usvc->fwmark)
- svc = __ip_vs_svc_fwm_get(usvc->af, usvc->fwmark);
- else
- svc = __ip_vs_service_get(usvc->af, usvc->protocol,
- &usvc->addr, usvc->port);
- if (svc) {
+ if (svc)
usvc->flags = svc->flags;
- ip_vs_service_put(svc);
- } else
- usvc->flags = 0;
/* set new flags from userland */
usvc->flags = (usvc->flags & ~flags.mask) |
(flags.flags & flags.mask);
usvc->sched_name = nla_data(nla_sched);
+ usvc->pe_name = nla_pe ? nla_data(nla_pe) : NULL;
usvc->timeout = nla_get_u32(nla_timeout);
usvc->netmask = nla_get_u32(nla_netmask);
}
@@ -2793,17 +2814,11 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc,
static struct ip_vs_service *ip_vs_genl_find_service(struct nlattr *nla)
{
struct ip_vs_service_user_kern usvc;
+ struct ip_vs_service *svc;
int ret;
- ret = ip_vs_genl_parse_service(&usvc, nla, 0);
- if (ret)
- return ERR_PTR(ret);
-
- if (usvc.fwmark)
- return __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark);
- else
- return __ip_vs_service_get(usvc.af, usvc.protocol,
- &usvc.addr, usvc.port);
+ ret = ip_vs_genl_parse_service(&usvc, nla, 0, &svc);
+ return ret ? ERR_PTR(ret) : svc;
}
static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest)
@@ -2894,7 +2909,6 @@ static int ip_vs_genl_dump_dests(struct sk_buff *skb,
nla_put_failure:
cb->args[0] = idx;
- ip_vs_service_put(svc);
out_err:
mutex_unlock(&__ip_vs_mutex);
@@ -3107,17 +3121,10 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
ret = ip_vs_genl_parse_service(&usvc,
info->attrs[IPVS_CMD_ATTR_SERVICE],
- need_full_svc);
+ need_full_svc, &svc);
if (ret)
goto out;
- /* Lookup the exact service by <protocol, addr, port> or fwmark */
- if (usvc.fwmark == 0)
- svc = __ip_vs_service_get(usvc.af, usvc.protocol,
- &usvc.addr, usvc.port);
- else
- svc = __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark);
-
/* Unless we're adding a new service, the service must already exist */
if ((cmd != IPVS_CMD_NEW_SERVICE) && (svc == NULL)) {
ret = -ESRCH;
@@ -3151,6 +3158,7 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
break;
case IPVS_CMD_DEL_SERVICE:
ret = ip_vs_del_service(svc);
+ /* do not use svc, it can be freed */
break;
case IPVS_CMD_NEW_DEST:
ret = ip_vs_add_dest(svc, &udest);
@@ -3169,8 +3177,6 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
}
out:
- if (svc)
- ip_vs_service_put(svc);
mutex_unlock(&__ip_vs_mutex);
return ret;
@@ -3216,7 +3222,6 @@ static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
goto out_err;
} else if (svc) {
ret = ip_vs_genl_fill_service(msg, svc);
- ip_vs_service_put(svc);
if (ret)
goto nla_put_failure;
} else {
@@ -3385,6 +3390,16 @@ int __init ip_vs_control_init(void)
EnterFunction(2);
+ /* Initialize ip_vs_svc_table, ip_vs_svc_fwm_table, ip_vs_rtable */
+ for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+ INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
+ INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
+ }
+ for(idx = 0; idx < IP_VS_RTAB_SIZE; idx++) {
+ INIT_LIST_HEAD(&ip_vs_rtable[idx]);
+ }
+ smp_wmb();
+
ret = nf_register_sockopt(&ip_vs_sockopts);
if (ret) {
pr_err("cannot register sockopt.\n");
@@ -3403,15 +3418,6 @@ int __init ip_vs_control_init(void)
sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars);
- /* Initialize ip_vs_svc_table, ip_vs_svc_fwm_table, ip_vs_rtable */
- for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
- INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
- INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
- }
- for(idx = 0; idx < IP_VS_RTAB_SIZE; idx++) {
- INIT_LIST_HEAD(&ip_vs_rtable[idx]);
- }
-
ip_vs_new_estimator(&ip_vs_stats);
/* Hook the defense timer */
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index 7e9af5b76d9e..75455000ad1c 100644
--- a/net/netfilter/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -20,17 +20,6 @@
*
* Author: Wouter Gadeyne
*
- *
- * Code for ip_vs_expect_related and ip_vs_expect_callback is taken from
- * http://www.ssi.bg/~ja/nfct/:
- *
- * ip_vs_nfct.c: Netfilter connection tracking support for IPVS
- *
- * Portions Copyright (C) 2001-2002
- * Antefacto Ltd, 181 Parnell St, Dublin 1, Ireland.
- *
- * Portions Copyright (C) 2003-2008
- * Julian Anastasov
*/
#define KMSG_COMPONENT "IPVS"
@@ -58,16 +47,6 @@
#define SERVER_STRING "227 Entering Passive Mode ("
#define CLIENT_STRING "PORT "
-#define FMT_TUPLE "%pI4:%u->%pI4:%u/%u"
-#define ARG_TUPLE(T) &(T)->src.u3.ip, ntohs((T)->src.u.all), \
- &(T)->dst.u3.ip, ntohs((T)->dst.u.all), \
- (T)->dst.protonum
-
-#define FMT_CONN "%pI4:%u->%pI4:%u->%pI4:%u/%u:%u"
-#define ARG_CONN(C) &((C)->caddr.ip), ntohs((C)->cport), \
- &((C)->vaddr.ip), ntohs((C)->vport), \
- &((C)->daddr.ip), ntohs((C)->dport), \
- (C)->protocol, (C)->state
/*
* List of ports (up to IP_VS_APP_MAX_PORTS) to be handled by helper
@@ -85,6 +64,8 @@ static int ip_vs_ftp_pasv;
static int
ip_vs_ftp_init_conn(struct ip_vs_app *app, struct ip_vs_conn *cp)
{
+ /* We use connection tracking for the command connection */
+ cp->flags |= IP_VS_CONN_F_NFCT;
return 0;
}
@@ -149,120 +130,6 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
}
/*
- * Called from init_conntrack() as expectfn handler.
- */
-static void
-ip_vs_expect_callback(struct nf_conn *ct,
- struct nf_conntrack_expect *exp)
-{
- struct nf_conntrack_tuple *orig, new_reply;
- struct ip_vs_conn *cp;
-
- if (exp->tuple.src.l3num != PF_INET)
- return;
-
- /*
- * We assume that no NF locks are held before this callback.
- * ip_vs_conn_out_get and ip_vs_conn_in_get should match their
- * expectations even if they use wildcard values, now we provide the
- * actual values from the newly created original conntrack direction.
- * The conntrack is confirmed when packet reaches IPVS hooks.
- */
-
- /* RS->CLIENT */
- orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
- cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum,
- &orig->src.u3, orig->src.u.tcp.port,
- &orig->dst.u3, orig->dst.u.tcp.port);
- if (cp) {
- /* Change reply CLIENT->RS to CLIENT->VS */
- new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
- IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", "
- FMT_TUPLE ", found inout cp=" FMT_CONN "\n",
- __func__, ct, ct->status,
- ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
- ARG_CONN(cp));
- new_reply.dst.u3 = cp->vaddr;
- new_reply.dst.u.tcp.port = cp->vport;
- IP_VS_DBG(7, "%s(): ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE
- ", inout cp=" FMT_CONN "\n",
- __func__, ct,
- ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
- ARG_CONN(cp));
- goto alter;
- }
-
- /* CLIENT->VS */
- cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum,
- &orig->src.u3, orig->src.u.tcp.port,
- &orig->dst.u3, orig->dst.u.tcp.port);
- if (cp) {
- /* Change reply VS->CLIENT to RS->CLIENT */
- new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
- IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", "
- FMT_TUPLE ", found outin cp=" FMT_CONN "\n",
- __func__, ct, ct->status,
- ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
- ARG_CONN(cp));
- new_reply.src.u3 = cp->daddr;
- new_reply.src.u.tcp.port = cp->dport;
- IP_VS_DBG(7, "%s(): ct=%p, new tuples=" FMT_TUPLE ", "
- FMT_TUPLE ", outin cp=" FMT_CONN "\n",
- __func__, ct,
- ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
- ARG_CONN(cp));
- goto alter;
- }
-
- IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuple=" FMT_TUPLE
- " - unknown expect\n",
- __func__, ct, ct->status, ARG_TUPLE(orig));
- return;
-
-alter:
- /* Never alter conntrack for non-NAT conns */
- if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ)
- nf_conntrack_alter_reply(ct, &new_reply);
- ip_vs_conn_put(cp);
- return;
-}
-
-/*
- * Create NF conntrack expectation with wildcard (optional) source port.
- * Then the default callback function will alter the reply and will confirm
- * the conntrack entry when the first packet comes.
- */
-static void
-ip_vs_expect_related(struct sk_buff *skb, struct nf_conn *ct,
- struct ip_vs_conn *cp, u_int8_t proto,
- const __be16 *port, int from_rs)
-{
- struct nf_conntrack_expect *exp;
-
- BUG_ON(!ct || ct == &nf_conntrack_untracked);
-
- exp = nf_ct_expect_alloc(ct);
- if (!exp)
- return;
-
- if (from_rs)
- nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
- nf_ct_l3num(ct), &cp->daddr, &cp->caddr,
- proto, port, &cp->cport);
- else
- nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
- nf_ct_l3num(ct), &cp->caddr, &cp->vaddr,
- proto, port, &cp->vport);
-
- exp->expectfn = ip_vs_expect_callback;
-
- IP_VS_DBG(7, "%s(): ct=%p, expect tuple=" FMT_TUPLE "\n",
- __func__, ct, ARG_TUPLE(&exp->tuple));
- nf_ct_expect_related(exp);
- nf_ct_expect_put(exp);
-}
-
-/*
* Look at outgoing ftp packets to catch the response to a PASV command
* from the server (inside-to-outside).
* When we see one, we build a connection entry with the client address,
@@ -328,14 +195,19 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
/*
* Now update or create an connection entry for it
*/
- n_cp = ip_vs_conn_out_get(AF_INET, iph->protocol, &from, port,
- &cp->caddr, 0);
+ {
+ struct ip_vs_conn_param p;
+ ip_vs_conn_fill_param(AF_INET, iph->protocol,
+ &from, port, &cp->caddr, 0, &p);
+ n_cp = ip_vs_conn_out_get(&p);
+ }
if (!n_cp) {
- n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP,
- &cp->caddr, 0,
- &cp->vaddr, port,
- &from, port,
- IP_VS_CONN_F_NO_CPORT,
+ struct ip_vs_conn_param p;
+ ip_vs_conn_fill_param(AF_INET, IPPROTO_TCP, &cp->caddr,
+ 0, &cp->vaddr, port, &p);
+ n_cp = ip_vs_conn_new(&p, &from, port,
+ IP_VS_CONN_F_NO_CPORT |
+ IP_VS_CONN_F_NFCT,
cp->dest);
if (!n_cp)
return 0;
@@ -370,9 +242,14 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
ret = nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
start-data, end-start,
buf, buf_len);
- if (ret)
- ip_vs_expect_related(skb, ct, n_cp,
- IPPROTO_TCP, NULL, 0);
+ if (ret) {
+ ip_vs_nfct_expect_related(skb, ct, n_cp,
+ IPPROTO_TCP, 0, 0);
+ if (skb->ip_summed == CHECKSUM_COMPLETE)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ /* csum is updated */
+ ret = 1;
+ }
}
/*
@@ -479,21 +356,22 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
ip_vs_proto_name(iph->protocol),
&to.ip, ntohs(port), &cp->vaddr.ip, 0);
- n_cp = ip_vs_conn_in_get(AF_INET, iph->protocol,
- &to, port,
- &cp->vaddr, htons(ntohs(cp->vport)-1));
- if (!n_cp) {
- n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP,
- &to, port,
+ {
+ struct ip_vs_conn_param p;
+ ip_vs_conn_fill_param(AF_INET, iph->protocol, &to, port,
&cp->vaddr, htons(ntohs(cp->vport)-1),
- &cp->daddr, htons(ntohs(cp->dport)-1),
- 0,
- cp->dest);
- if (!n_cp)
- return 0;
+ &p);
+ n_cp = ip_vs_conn_in_get(&p);
+ if (!n_cp) {
+ n_cp = ip_vs_conn_new(&p, &cp->daddr,
+ htons(ntohs(cp->dport)-1),
+ IP_VS_CONN_F_NFCT, cp->dest);
+ if (!n_cp)
+ return 0;
- /* add its controller */
- ip_vs_control_add(n_cp, cp);
+ /* add its controller */
+ ip_vs_control_add(n_cp, cp);
+ }
}
/*
diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c
new file mode 100644
index 000000000000..4680647cd450
--- /dev/null
+++ b/net/netfilter/ipvs/ip_vs_nfct.c
@@ -0,0 +1,292 @@
+/*
+ * ip_vs_nfct.c: Netfilter connection tracking support for IPVS
+ *
+ * Portions Copyright (C) 2001-2002
+ * Antefacto Ltd, 181 Parnell St, Dublin 1, Ireland.
+ *
+ * Portions Copyright (C) 2003-2010
+ * Julian Anastasov
+ *
+ *
+ * This code 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
+ *
+ *
+ * Authors:
+ * Ben North <ben@redfrontdoor.org>
+ * Julian Anastasov <ja@ssi.bg> Reorganize and sync with latest kernels
+ * Hannes Eder <heder@google.com> Extend NFCT support for FTP, ipvs match
+ *
+ *
+ * Current status:
+ *
+ * - provide conntrack confirmation for new and related connections, by
+ * this way we can see their proper conntrack state in all hooks
+ * - support for all forwarding methods, not only NAT
+ * - FTP support (NAT), ability to support other NAT apps with expectations
+ * - to correctly create expectations for related NAT connections the proper
+ * NF conntrack support must be already installed, eg. ip_vs_ftp requires
+ * nf_conntrack_ftp ... iptables_nat for the same ports (but no iptables
+ * NAT rules are needed)
+ * - alter reply for NAT when forwarding packet in original direction:
+ * conntrack from client in NEW or RELATED (Passive FTP DATA) state or
+ * when RELATED conntrack is created from real server (Active FTP DATA)
+ * - if iptables_nat is not loaded the Passive FTP will not work (the
+ * PASV response can not be NAT-ed) but Active FTP should work
+ *
+ */
+
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/compiler.h>
+#include <linux/vmalloc.h>
+#include <linux/skbuff.h>
+#include <net/ip.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <net/ip_vs.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_expect.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_zones.h>
+
+
+#define FMT_TUPLE "%pI4:%u->%pI4:%u/%u"
+#define ARG_TUPLE(T) &(T)->src.u3.ip, ntohs((T)->src.u.all), \
+ &(T)->dst.u3.ip, ntohs((T)->dst.u.all), \
+ (T)->dst.protonum
+
+#define FMT_CONN "%pI4:%u->%pI4:%u->%pI4:%u/%u:%u"
+#define ARG_CONN(C) &((C)->caddr.ip), ntohs((C)->cport), \
+ &((C)->vaddr.ip), ntohs((C)->vport), \
+ &((C)->daddr.ip), ntohs((C)->dport), \
+ (C)->protocol, (C)->state
+
+void
+ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin)
+{
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo);
+ struct nf_conntrack_tuple new_tuple;
+
+ if (ct == NULL || nf_ct_is_confirmed(ct) || nf_ct_is_untracked(ct) ||
+ nf_ct_is_dying(ct))
+ return;
+
+ /* Never alter conntrack for non-NAT conns */
+ if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
+ return;
+
+ /* Alter reply only in original direction */
+ if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
+ return;
+
+ /*
+ * The connection is not yet in the hashtable, so we update it.
+ * CIP->VIP will remain the same, so leave the tuple in
+ * IP_CT_DIR_ORIGINAL untouched. When the reply comes back from the
+ * real-server we will see RIP->DIP.
+ */
+ new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+ /*
+ * This will also take care of UDP and other protocols.
+ */
+ if (outin) {
+ new_tuple.src.u3 = cp->daddr;
+ if (new_tuple.dst.protonum != IPPROTO_ICMP &&
+ new_tuple.dst.protonum != IPPROTO_ICMPV6)
+ new_tuple.src.u.tcp.port = cp->dport;
+ } else {
+ new_tuple.dst.u3 = cp->vaddr;
+ if (new_tuple.dst.protonum != IPPROTO_ICMP &&
+ new_tuple.dst.protonum != IPPROTO_ICMPV6)
+ new_tuple.dst.u.tcp.port = cp->vport;
+ }
+ IP_VS_DBG(7, "%s: Updating conntrack ct=%p, status=0x%lX, "
+ "ctinfo=%d, old reply=" FMT_TUPLE
+ ", new reply=" FMT_TUPLE ", cp=" FMT_CONN "\n",
+ __func__, ct, ct->status, ctinfo,
+ ARG_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple),
+ ARG_TUPLE(&new_tuple), ARG_CONN(cp));
+ nf_conntrack_alter_reply(ct, &new_tuple);
+}
+
+int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp)
+{
+ return nf_conntrack_confirm(skb);
+}
+
+/*
+ * Called from init_conntrack() as expectfn handler.
+ */
+static void ip_vs_nfct_expect_callback(struct nf_conn *ct,
+ struct nf_conntrack_expect *exp)
+{
+ struct nf_conntrack_tuple *orig, new_reply;
+ struct ip_vs_conn *cp;
+ struct ip_vs_conn_param p;
+
+ if (exp->tuple.src.l3num != PF_INET)
+ return;
+
+ /*
+ * We assume that no NF locks are held before this callback.
+ * ip_vs_conn_out_get and ip_vs_conn_in_get should match their
+ * expectations even if they use wildcard values, now we provide the
+ * actual values from the newly created original conntrack direction.
+ * The conntrack is confirmed when packet reaches IPVS hooks.
+ */
+
+ /* RS->CLIENT */
+ orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+ ip_vs_conn_fill_param(exp->tuple.src.l3num, orig->dst.protonum,
+ &orig->src.u3, orig->src.u.tcp.port,
+ &orig->dst.u3, orig->dst.u.tcp.port, &p);
+ cp = ip_vs_conn_out_get(&p);
+ if (cp) {
+ /* Change reply CLIENT->RS to CLIENT->VS */
+ new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+ IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", "
+ FMT_TUPLE ", found inout cp=" FMT_CONN "\n",
+ __func__, ct, ct->status,
+ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
+ ARG_CONN(cp));
+ new_reply.dst.u3 = cp->vaddr;
+ new_reply.dst.u.tcp.port = cp->vport;
+ IP_VS_DBG(7, "%s: ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE
+ ", inout cp=" FMT_CONN "\n",
+ __func__, ct,
+ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
+ ARG_CONN(cp));
+ goto alter;
+ }
+
+ /* CLIENT->VS */
+ cp = ip_vs_conn_in_get(&p);
+ if (cp) {
+ /* Change reply VS->CLIENT to RS->CLIENT */
+ new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+ IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", "
+ FMT_TUPLE ", found outin cp=" FMT_CONN "\n",
+ __func__, ct, ct->status,
+ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
+ ARG_CONN(cp));
+ new_reply.src.u3 = cp->daddr;
+ new_reply.src.u.tcp.port = cp->dport;
+ IP_VS_DBG(7, "%s: ct=%p, new tuples=" FMT_TUPLE ", "
+ FMT_TUPLE ", outin cp=" FMT_CONN "\n",
+ __func__, ct,
+ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
+ ARG_CONN(cp));
+ goto alter;
+ }
+
+ IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuple=" FMT_TUPLE
+ " - unknown expect\n",
+ __func__, ct, ct->status, ARG_TUPLE(orig));
+ return;
+
+alter:
+ /* Never alter conntrack for non-NAT conns */
+ if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ)
+ nf_conntrack_alter_reply(ct, &new_reply);
+ ip_vs_conn_put(cp);
+ return;
+}
+
+/*
+ * Create NF conntrack expectation with wildcard (optional) source port.
+ * Then the default callback function will alter the reply and will confirm
+ * the conntrack entry when the first packet comes.
+ * Use port 0 to expect connection from any port.
+ */
+void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
+ struct ip_vs_conn *cp, u_int8_t proto,
+ const __be16 port, int from_rs)
+{
+ struct nf_conntrack_expect *exp;
+
+ if (ct == NULL || nf_ct_is_untracked(ct))
+ return;
+
+ exp = nf_ct_expect_alloc(ct);
+ if (!exp)
+ return;
+
+ nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
+ from_rs ? &cp->daddr : &cp->caddr,
+ from_rs ? &cp->caddr : &cp->vaddr,
+ proto, port ? &port : NULL,
+ from_rs ? &cp->cport : &cp->vport);
+
+ exp->expectfn = ip_vs_nfct_expect_callback;
+
+ IP_VS_DBG(7, "%s: ct=%p, expect tuple=" FMT_TUPLE "\n",
+ __func__, ct, ARG_TUPLE(&exp->tuple));
+ nf_ct_expect_related(exp);
+ nf_ct_expect_put(exp);
+}
+EXPORT_SYMBOL(ip_vs_nfct_expect_related);
+
+/*
+ * Our connection was terminated, try to drop the conntrack immediately
+ */
+void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp)
+{
+ struct nf_conntrack_tuple_hash *h;
+ struct nf_conn *ct;
+ struct nf_conntrack_tuple tuple;
+
+ if (!cp->cport)
+ return;
+
+ tuple = (struct nf_conntrack_tuple) {
+ .dst = { .protonum = cp->protocol, .dir = IP_CT_DIR_ORIGINAL } };
+ tuple.src.u3 = cp->caddr;
+ tuple.src.u.all = cp->cport;
+ tuple.src.l3num = cp->af;
+ tuple.dst.u3 = cp->vaddr;
+ tuple.dst.u.all = cp->vport;
+
+ IP_VS_DBG(7, "%s: dropping conntrack with tuple=" FMT_TUPLE
+ " for conn " FMT_CONN "\n",
+ __func__, ARG_TUPLE(&tuple), ARG_CONN(cp));
+
+ h = nf_conntrack_find_get(&init_net, NF_CT_DEFAULT_ZONE, &tuple);
+ if (h) {
+ ct = nf_ct_tuplehash_to_ctrack(h);
+ /* Show what happens instead of calling nf_ct_kill() */
+ if (del_timer(&ct->timeout)) {
+ IP_VS_DBG(7, "%s: ct=%p, deleted conntrack timer for tuple="
+ FMT_TUPLE "\n",
+ __func__, ct, ARG_TUPLE(&tuple));
+ if (ct->timeout.function)
+ ct->timeout.function(ct->timeout.data);
+ } else {
+ IP_VS_DBG(7, "%s: ct=%p, no conntrack timer for tuple="
+ FMT_TUPLE "\n",
+ __func__, ct, ARG_TUPLE(&tuple));
+ }
+ nf_ct_put(ct);
+ } else {
+ IP_VS_DBG(7, "%s: no conntrack for tuple=" FMT_TUPLE "\n",
+ __func__, ARG_TUPLE(&tuple));
+ }
+}
+
diff --git a/net/netfilter/ipvs/ip_vs_pe.c b/net/netfilter/ipvs/ip_vs_pe.c
new file mode 100644
index 000000000000..3414af70ee12
--- /dev/null
+++ b/net/netfilter/ipvs/ip_vs_pe.c
@@ -0,0 +1,147 @@
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <asm/string.h>
+#include <linux/kmod.h>
+#include <linux/sysctl.h>
+
+#include <net/ip_vs.h>
+
+/* IPVS pe list */
+static LIST_HEAD(ip_vs_pe);
+
+/* lock for service table */
+static DEFINE_SPINLOCK(ip_vs_pe_lock);
+
+/* Bind a service with a pe */
+void ip_vs_bind_pe(struct ip_vs_service *svc, struct ip_vs_pe *pe)
+{
+ svc->pe = pe;
+}
+
+/* Unbind a service from its pe */
+void ip_vs_unbind_pe(struct ip_vs_service *svc)
+{
+ svc->pe = NULL;
+}
+
+/* Get pe in the pe list by name */
+static struct ip_vs_pe *
+ip_vs_pe_getbyname(const char *pe_name)
+{
+ struct ip_vs_pe *pe;
+
+ IP_VS_DBG(2, "%s(): pe_name \"%s\"\n", __func__,
+ pe_name);
+
+ spin_lock_bh(&ip_vs_pe_lock);
+
+ list_for_each_entry(pe, &ip_vs_pe, n_list) {
+ /* Test and get the modules atomically */
+ if (pe->module &&
+ !try_module_get(pe->module)) {
+ /* This pe is just deleted */
+ continue;
+ }
+ if (strcmp(pe_name, pe->name)==0) {
+ /* HIT */
+ spin_unlock_bh(&ip_vs_pe_lock);
+ return pe;
+ }
+ if (pe->module)
+ module_put(pe->module);
+ }
+
+ spin_unlock_bh(&ip_vs_pe_lock);
+ return NULL;
+}
+
+/* Lookup pe and try to load it if it doesn't exist */
+struct ip_vs_pe *ip_vs_pe_get(const char *name)
+{
+ struct ip_vs_pe *pe;
+
+ /* Search for the pe by name */
+ pe = ip_vs_pe_getbyname(name);
+
+ /* If pe not found, load the module and search again */
+ if (!pe) {
+ request_module("ip_vs_pe_%s", name);
+ pe = ip_vs_pe_getbyname(name);
+ }
+
+ return pe;
+}
+
+void ip_vs_pe_put(struct ip_vs_pe *pe)
+{
+ if (pe && pe->module)
+ module_put(pe->module);
+}
+
+/* Register a pe in the pe list */
+int register_ip_vs_pe(struct ip_vs_pe *pe)
+{
+ struct ip_vs_pe *tmp;
+
+ /* increase the module use count */
+ ip_vs_use_count_inc();
+
+ spin_lock_bh(&ip_vs_pe_lock);
+
+ if (!list_empty(&pe->n_list)) {
+ spin_unlock_bh(&ip_vs_pe_lock);
+ ip_vs_use_count_dec();
+ pr_err("%s(): [%s] pe already linked\n",
+ __func__, pe->name);
+ return -EINVAL;
+ }
+
+ /* Make sure that the pe with this name doesn't exist
+ * in the pe list.
+ */
+ list_for_each_entry(tmp, &ip_vs_pe, n_list) {
+ if (strcmp(tmp->name, pe->name) == 0) {
+ spin_unlock_bh(&ip_vs_pe_lock);
+ ip_vs_use_count_dec();
+ pr_err("%s(): [%s] pe already existed "
+ "in the system\n", __func__, pe->name);
+ return -EINVAL;
+ }
+ }
+ /* Add it into the d-linked pe list */
+ list_add(&pe->n_list, &ip_vs_pe);
+ spin_unlock_bh(&ip_vs_pe_lock);
+
+ pr_info("[%s] pe registered.\n", pe->name);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(register_ip_vs_pe);
+
+/* Unregister a pe from the pe list */
+int unregister_ip_vs_pe(struct ip_vs_pe *pe)
+{
+ spin_lock_bh(&ip_vs_pe_lock);
+ if (list_empty(&pe->n_list)) {
+ spin_unlock_bh(&ip_vs_pe_lock);
+ pr_err("%s(): [%s] pe is not in the list. failed\n",
+ __func__, pe->name);
+ return -EINVAL;
+ }
+
+ /* Remove it from the d-linked pe list */
+ list_del(&pe->n_list);
+ spin_unlock_bh(&ip_vs_pe_lock);
+
+ /* decrease the module use count */
+ ip_vs_use_count_dec();
+
+ pr_info("[%s] pe unregistered.\n", pe->name);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(unregister_ip_vs_pe);
diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c
new file mode 100644
index 000000000000..b8b4e9620f3e
--- /dev/null
+++ b/net/netfilter/ipvs/ip_vs_pe_sip.c
@@ -0,0 +1,169 @@
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <net/ip_vs.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <linux/netfilter/nf_conntrack_sip.h>
+
+#ifdef CONFIG_IP_VS_DEBUG
+static const char *ip_vs_dbg_callid(char *buf, size_t buf_len,
+ const char *callid, size_t callid_len,
+ int *idx)
+{
+ size_t len = min(min(callid_len, (size_t)64), buf_len - *idx - 1);
+ memcpy(buf + *idx, callid, len);
+ buf[*idx+len] = '\0';
+ *idx += len + 1;
+ return buf + *idx - len;
+}
+
+#define IP_VS_DEBUG_CALLID(callid, len) \
+ ip_vs_dbg_callid(ip_vs_dbg_buf, sizeof(ip_vs_dbg_buf), \
+ callid, len, &ip_vs_dbg_idx)
+#endif
+
+static int get_callid(const char *dptr, unsigned int dataoff,
+ unsigned int datalen,
+ unsigned int *matchoff, unsigned int *matchlen)
+{
+ /* Find callid */
+ while (1) {
+ int ret = ct_sip_get_header(NULL, dptr, dataoff, datalen,
+ SIP_HDR_CALL_ID, matchoff,
+ matchlen);
+ if (ret > 0)
+ break;
+ if (!ret)
+ return 0;
+ dataoff += *matchoff;
+ }
+
+ /* Empty callid is useless */
+ if (!*matchlen)
+ return -EINVAL;
+
+ /* Too large is useless */
+ if (*matchlen > IP_VS_PEDATA_MAXLEN)
+ return -EINVAL;
+
+ /* SIP headers are always followed by a line terminator */
+ if (*matchoff + *matchlen == datalen)
+ return -EINVAL;
+
+ /* RFC 2543 allows lines to be terminated with CR, LF or CRLF,
+ * RFC 3261 allows only CRLF, we support both. */
+ if (*(dptr + *matchoff + *matchlen) != '\r' &&
+ *(dptr + *matchoff + *matchlen) != '\n')
+ return -EINVAL;
+
+ IP_VS_DBG_BUF(9, "SIP callid %s (%d bytes)\n",
+ IP_VS_DEBUG_CALLID(dptr + *matchoff, *matchlen),
+ *matchlen);
+ return 0;
+}
+
+static int
+ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb)
+{
+ struct ip_vs_iphdr iph;
+ unsigned int dataoff, datalen, matchoff, matchlen;
+ const char *dptr;
+
+ ip_vs_fill_iphdr(p->af, skb_network_header(skb), &iph);
+
+ /* Only useful with UDP */
+ if (iph.protocol != IPPROTO_UDP)
+ return -EINVAL;
+
+ /* No Data ? */
+ dataoff = iph.len + sizeof(struct udphdr);
+ if (dataoff >= skb->len)
+ return -EINVAL;
+
+ dptr = skb->data + dataoff;
+ datalen = skb->len - dataoff;
+
+ if (get_callid(dptr, dataoff, datalen, &matchoff, &matchlen))
+ return -EINVAL;
+
+ p->pe_data = kmalloc(matchlen, GFP_ATOMIC);
+ if (!p->pe_data)
+ return -ENOMEM;
+
+ /* N.B: pe_data is only set on success,
+ * this allows fallback to the default persistence logic on failure
+ */
+ memcpy(p->pe_data, dptr + matchoff, matchlen);
+ p->pe_data_len = matchlen;
+
+ return 0;
+}
+
+static bool ip_vs_sip_ct_match(const struct ip_vs_conn_param *p,
+ struct ip_vs_conn *ct)
+
+{
+ bool ret = 0;
+
+ if (ct->af == p->af &&
+ ip_vs_addr_equal(p->af, p->caddr, &ct->caddr) &&
+ /* protocol should only be IPPROTO_IP if
+ * d_addr is a fwmark */
+ ip_vs_addr_equal(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af,
+ p->vaddr, &ct->vaddr) &&
+ ct->vport == p->vport &&
+ ct->flags & IP_VS_CONN_F_TEMPLATE &&
+ ct->protocol == p->protocol &&
+ ct->pe_data && ct->pe_data_len == p->pe_data_len &&
+ !memcmp(ct->pe_data, p->pe_data, p->pe_data_len))
+ ret = 1;
+
+ IP_VS_DBG_BUF(9, "SIP template match %s %s->%s:%d %s\n",
+ ip_vs_proto_name(p->protocol),
+ IP_VS_DEBUG_CALLID(p->pe_data, p->pe_data_len),
+ IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport),
+ ret ? "hit" : "not hit");
+
+ return ret;
+}
+
+static u32 ip_vs_sip_hashkey_raw(const struct ip_vs_conn_param *p,
+ u32 initval, bool inverse)
+{
+ return jhash(p->pe_data, p->pe_data_len, initval);
+}
+
+static int ip_vs_sip_show_pe_data(const struct ip_vs_conn *cp, char *buf)
+{
+ memcpy(buf, cp->pe_data, cp->pe_data_len);
+ return cp->pe_data_len;
+}
+
+static struct ip_vs_pe ip_vs_sip_pe =
+{
+ .name = "sip",
+ .refcnt = ATOMIC_INIT(0),
+ .module = THIS_MODULE,
+ .n_list = LIST_HEAD_INIT(ip_vs_sip_pe.n_list),
+ .fill_param = ip_vs_sip_fill_param,
+ .ct_match = ip_vs_sip_ct_match,
+ .hashkey_raw = ip_vs_sip_hashkey_raw,
+ .show_pe_data = ip_vs_sip_show_pe_data,
+};
+
+static int __init ip_vs_sip_init(void)
+{
+ return register_ip_vs_pe(&ip_vs_sip_pe);
+}
+
+static void __exit ip_vs_sip_cleanup(void)
+{
+ unregister_ip_vs_pe(&ip_vs_sip_pe);
+}
+
+module_init(ip_vs_sip_init);
+module_exit(ip_vs_sip_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index 027f654799fe..c53998390877 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -172,8 +172,8 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
else if (ih->frag_off & htons(IP_OFFSET))
sprintf(buf, "%pI4->%pI4 frag", &ih->saddr, &ih->daddr);
else {
- __be16 _ports[2], *pptr
-;
+ __be16 _ports[2], *pptr;
+
pptr = skb_header_pointer(skb, offset + ih->ihl*4,
sizeof(_ports), _ports);
if (pptr == NULL)
@@ -223,13 +223,13 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
void
-ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
+ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
const struct sk_buff *skb,
int offset,
const char *msg)
{
#ifdef CONFIG_IP_VS_IPV6
- if (skb->protocol == htons(ETH_P_IPV6))
+ if (af == AF_INET6)
ip_vs_tcpudp_debug_packet_v6(pp, skb, offset, msg);
else
#endif
diff --git a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
index 1892dfc12fdd..3a0461117d3f 100644
--- a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
@@ -40,6 +40,19 @@ struct isakmp_hdr {
#define PORT_ISAKMP 500
+static void
+ah_esp_conn_fill_param_proto(int af, const struct ip_vs_iphdr *iph,
+ int inverse, struct ip_vs_conn_param *p)
+{
+ if (likely(!inverse))
+ ip_vs_conn_fill_param(af, IPPROTO_UDP,
+ &iph->saddr, htons(PORT_ISAKMP),
+ &iph->daddr, htons(PORT_ISAKMP), p);
+ else
+ ip_vs_conn_fill_param(af, IPPROTO_UDP,
+ &iph->daddr, htons(PORT_ISAKMP),
+ &iph->saddr, htons(PORT_ISAKMP), p);
+}
static struct ip_vs_conn *
ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
@@ -47,21 +60,10 @@ ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
int inverse)
{
struct ip_vs_conn *cp;
+ struct ip_vs_conn_param p;
- if (likely(!inverse)) {
- cp = ip_vs_conn_in_get(af, IPPROTO_UDP,
- &iph->saddr,
- htons(PORT_ISAKMP),
- &iph->daddr,
- htons(PORT_ISAKMP));
- } else {
- cp = ip_vs_conn_in_get(af, IPPROTO_UDP,
- &iph->daddr,
- htons(PORT_ISAKMP),
- &iph->saddr,
- htons(PORT_ISAKMP));
- }
-
+ ah_esp_conn_fill_param_proto(af, iph, inverse, &p);
+ cp = ip_vs_conn_in_get(&p);
if (!cp) {
/*
* We are not sure if the packet is from our
@@ -87,21 +89,10 @@ ah_esp_conn_out_get(int af, const struct sk_buff *skb,
int inverse)
{
struct ip_vs_conn *cp;
+ struct ip_vs_conn_param p;
- if (likely(!inverse)) {
- cp = ip_vs_conn_out_get(af, IPPROTO_UDP,
- &iph->saddr,
- htons(PORT_ISAKMP),
- &iph->daddr,
- htons(PORT_ISAKMP));
- } else {
- cp = ip_vs_conn_out_get(af, IPPROTO_UDP,
- &iph->daddr,
- htons(PORT_ISAKMP),
- &iph->saddr,
- htons(PORT_ISAKMP));
- }
-
+ ah_esp_conn_fill_param_proto(af, iph, inverse, &p);
+ cp = ip_vs_conn_out_get(&p);
if (!cp) {
IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet "
"%s%s %s->%s\n",
@@ -126,54 +117,6 @@ ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
return 0;
}
-
-static void
-ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb,
- int offset, const char *msg)
-{
- char buf[256];
- struct iphdr _iph, *ih;
-
- ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
- if (ih == NULL)
- sprintf(buf, "TRUNCATED");
- else
- sprintf(buf, "%pI4->%pI4", &ih->saddr, &ih->daddr);
-
- pr_debug("%s: %s %s\n", msg, pp->name, buf);
-}
-
-#ifdef CONFIG_IP_VS_IPV6
-static void
-ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb,
- int offset, const char *msg)
-{
- char buf[256];
- struct ipv6hdr _iph, *ih;
-
- ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
- if (ih == NULL)
- sprintf(buf, "TRUNCATED");
- else
- sprintf(buf, "%pI6->%pI6", &ih->saddr, &ih->daddr);
-
- pr_debug("%s: %s %s\n", msg, pp->name, buf);
-}
-#endif
-
-static void
-ah_esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
- int offset, const char *msg)
-{
-#ifdef CONFIG_IP_VS_IPV6
- if (skb->protocol == htons(ETH_P_IPV6))
- ah_esp_debug_packet_v6(pp, skb, offset, msg);
- else
-#endif
- ah_esp_debug_packet_v4(pp, skb, offset, msg);
-}
-
-
static void ah_esp_init(struct ip_vs_protocol *pp)
{
/* nothing to do now */
@@ -204,7 +147,7 @@ struct ip_vs_protocol ip_vs_protocol_ah = {
.register_app = NULL,
.unregister_app = NULL,
.app_conn_bind = NULL,
- .debug_packet = ah_esp_debug_packet,
+ .debug_packet = ip_vs_tcpudp_debug_packet,
.timeout_change = NULL, /* ISAKMP */
.set_state_timeout = NULL,
};
@@ -228,7 +171,7 @@ struct ip_vs_protocol ip_vs_protocol_esp = {
.register_app = NULL,
.unregister_app = NULL,
.app_conn_bind = NULL,
- .debug_packet = ah_esp_debug_packet,
+ .debug_packet = ip_vs_tcpudp_debug_packet,
.timeout_change = NULL, /* ISAKMP */
};
#endif
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
index 4c0855cb006e..1ea96bcd342b 100644
--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
@@ -31,6 +31,8 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
if ((sch->type == SCTP_CID_INIT) &&
(svc = ip_vs_service_get(af, skb->mark, iph.protocol,
&iph.daddr, sh->dest))) {
+ int ignored;
+
if (ip_vs_todrop()) {
/*
* It seems that we are very loaded.
@@ -44,8 +46,8 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
* Let the virtual server select a real server for the
* incoming connection, and create a connection entry.
*/
- *cpp = ip_vs_schedule(svc, skb);
- if (!*cpp) {
+ *cpp = ip_vs_schedule(svc, skb, pp, &ignored);
+ if (!*cpp && !ignored) {
*verdict = ip_vs_leave(svc, skb, pp);
return 0;
}
@@ -61,6 +63,7 @@ sctp_snat_handler(struct sk_buff *skb,
{
sctp_sctphdr_t *sctph;
unsigned int sctphoff;
+ struct sk_buff *iter;
__be32 crc32;
#ifdef CONFIG_IP_VS_IPV6
@@ -89,8 +92,8 @@ sctp_snat_handler(struct sk_buff *skb,
/* Calculate the checksum */
crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff);
- for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next)
- crc32 = sctp_update_cksum((u8 *) skb->data, skb_headlen(skb),
+ skb_walk_frags(skb, iter)
+ crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter),
crc32);
crc32 = sctp_end_cksum(crc32);
sctph->checksum = crc32;
@@ -102,9 +105,9 @@ static int
sctp_dnat_handler(struct sk_buff *skb,
struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
{
-
sctp_sctphdr_t *sctph;
unsigned int sctphoff;
+ struct sk_buff *iter;
__be32 crc32;
#ifdef CONFIG_IP_VS_IPV6
@@ -133,8 +136,8 @@ sctp_dnat_handler(struct sk_buff *skb,
/* Calculate the checksum */
crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff);
- for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next)
- crc32 = sctp_update_cksum((u8 *) skb->data, skb_headlen(skb),
+ skb_walk_frags(skb, iter)
+ crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter),
crc32);
crc32 = sctp_end_cksum(crc32);
sctph->checksum = crc32;
@@ -145,9 +148,9 @@ sctp_dnat_handler(struct sk_buff *skb,
static int
sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
{
- struct sk_buff *list = skb_shinfo(skb)->frag_list;
unsigned int sctphoff;
struct sctphdr *sh, _sctph;
+ struct sk_buff *iter;
__le32 cmp;
__le32 val;
__u32 tmp;
@@ -166,15 +169,15 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
cmp = sh->checksum;
tmp = sctp_start_cksum((__u8 *) sh, skb_headlen(skb));
- for (; list; list = list->next)
- tmp = sctp_update_cksum((__u8 *) list->data,
- skb_headlen(list), tmp);
+ skb_walk_frags(skb, iter)
+ tmp = sctp_update_cksum((__u8 *) iter->data,
+ skb_headlen(iter), tmp);
val = sctp_end_cksum(tmp);
if (val != cmp) {
/* CRC failure, dump it. */
- IP_VS_DBG_RL_PKT(0, pp, skb, 0,
+ IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
"Failed checksum for");
return 0;
}
diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index 282d24de8592..f6c5200e2146 100644
--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -43,9 +43,12 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
return 0;
}
+ /* No !th->ack check to allow scheduling on SYN+ACK for Active FTP */
if (th->syn &&
(svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr,
th->dest))) {
+ int ignored;
+
if (ip_vs_todrop()) {
/*
* It seems that we are very loaded.
@@ -60,8 +63,8 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
* Let the virtual server select a real server for the
* incoming connection, and create a connection entry.
*/
- *cpp = ip_vs_schedule(svc, skb);
- if (!*cpp) {
+ *cpp = ip_vs_schedule(svc, skb, pp, &ignored);
+ if (!*cpp && !ignored) {
*verdict = ip_vs_leave(svc, skb, pp);
return 0;
}
@@ -101,15 +104,15 @@ tcp_partial_csum_update(int af, struct tcphdr *tcph,
#ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6)
tcph->check =
- csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
+ ~csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
ip_vs_check_diff2(oldlen, newlen,
- ~csum_unfold(tcph->check))));
+ csum_unfold(tcph->check))));
else
#endif
tcph->check =
- csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
+ ~csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
ip_vs_check_diff2(oldlen, newlen,
- ~csum_unfold(tcph->check))));
+ csum_unfold(tcph->check))));
}
@@ -120,6 +123,7 @@ tcp_snat_handler(struct sk_buff *skb,
struct tcphdr *tcph;
unsigned int tcphoff;
int oldlen;
+ int payload_csum = 0;
#ifdef CONFIG_IP_VS_IPV6
if (cp->af == AF_INET6)
@@ -134,13 +138,20 @@ tcp_snat_handler(struct sk_buff *skb,
return 0;
if (unlikely(cp->app != NULL)) {
+ int ret;
+
/* Some checks before mangling */
if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
return 0;
/* Call application helper if needed */
- if (!ip_vs_app_pkt_out(cp, skb))
+ if (!(ret = ip_vs_app_pkt_out(cp, skb)))
return 0;
+ /* ret=2: csum update is needed after payload mangling */
+ if (ret == 1)
+ oldlen = skb->len - tcphoff;
+ else
+ payload_csum = 1;
}
tcph = (void *)skb_network_header(skb) + tcphoff;
@@ -151,12 +162,13 @@ tcp_snat_handler(struct sk_buff *skb,
tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
htons(oldlen),
htons(skb->len - tcphoff));
- } else if (!cp->app) {
+ } else if (!payload_csum) {
/* Only port and addr are changed, do fast csum update */
tcp_fast_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
cp->dport, cp->vport);
if (skb->ip_summed == CHECKSUM_COMPLETE)
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = (cp->app && pp->csum_check) ?
+ CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
} else {
/* full checksum calculation */
tcph->check = 0;
@@ -174,6 +186,7 @@ tcp_snat_handler(struct sk_buff *skb,
skb->len - tcphoff,
cp->protocol,
skb->csum);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
pp->name, tcph->check,
@@ -190,6 +203,7 @@ tcp_dnat_handler(struct sk_buff *skb,
struct tcphdr *tcph;
unsigned int tcphoff;
int oldlen;
+ int payload_csum = 0;
#ifdef CONFIG_IP_VS_IPV6
if (cp->af == AF_INET6)
@@ -204,6 +218,8 @@ tcp_dnat_handler(struct sk_buff *skb,
return 0;
if (unlikely(cp->app != NULL)) {
+ int ret;
+
/* Some checks before mangling */
if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
return 0;
@@ -212,8 +228,13 @@ tcp_dnat_handler(struct sk_buff *skb,
* Attempt ip_vs_app call.
* It will fix ip_vs_conn and iph ack_seq stuff
*/
- if (!ip_vs_app_pkt_in(cp, skb))
+ if (!(ret = ip_vs_app_pkt_in(cp, skb)))
return 0;
+ /* ret=2: csum update is needed after payload mangling */
+ if (ret == 1)
+ oldlen = skb->len - tcphoff;
+ else
+ payload_csum = 1;
}
tcph = (void *)skb_network_header(skb) + tcphoff;
@@ -223,15 +244,16 @@ tcp_dnat_handler(struct sk_buff *skb,
* Adjust TCP checksums
*/
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
+ tcp_partial_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr,
htons(oldlen),
htons(skb->len - tcphoff));
- } else if (!cp->app) {
+ } else if (!payload_csum) {
/* Only port and addr are changed, do fast csum update */
tcp_fast_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr,
cp->vport, cp->dport);
if (skb->ip_summed == CHECKSUM_COMPLETE)
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = (cp->app && pp->csum_check) ?
+ CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
} else {
/* full checksum calculation */
tcph->check = 0;
@@ -278,7 +300,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
skb->len - tcphoff,
ipv6_hdr(skb)->nexthdr,
skb->csum)) {
- IP_VS_DBG_RL_PKT(0, pp, skb, 0,
+ IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
"Failed checksum for");
return 0;
}
@@ -289,7 +311,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
skb->len - tcphoff,
ip_hdr(skb)->protocol,
skb->csum)) {
- IP_VS_DBG_RL_PKT(0, pp, skb, 0,
+ IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
"Failed checksum for");
return 0;
}
diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
index 8553231b5d41..9d106a06bb0a 100644
--- a/net/netfilter/ipvs/ip_vs_proto_udp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
@@ -46,6 +46,8 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
svc = ip_vs_service_get(af, skb->mark, iph.protocol,
&iph.daddr, uh->dest);
if (svc) {
+ int ignored;
+
if (ip_vs_todrop()) {
/*
* It seems that we are very loaded.
@@ -60,8 +62,8 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
* Let the virtual server select a real server for the
* incoming connection, and create a connection entry.
*/
- *cpp = ip_vs_schedule(svc, skb);
- if (!*cpp) {
+ *cpp = ip_vs_schedule(svc, skb, pp, &ignored);
+ if (!*cpp && !ignored) {
*verdict = ip_vs_leave(svc, skb, pp);
return 0;
}
@@ -102,15 +104,15 @@ udp_partial_csum_update(int af, struct udphdr *uhdr,
#ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6)
uhdr->check =
- csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
+ ~csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
ip_vs_check_diff2(oldlen, newlen,
- ~csum_unfold(uhdr->check))));
+ csum_unfold(uhdr->check))));
else
#endif
uhdr->check =
- csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
+ ~csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
ip_vs_check_diff2(oldlen, newlen,
- ~csum_unfold(uhdr->check))));
+ csum_unfold(uhdr->check))));
}
@@ -121,6 +123,7 @@ udp_snat_handler(struct sk_buff *skb,
struct udphdr *udph;
unsigned int udphoff;
int oldlen;
+ int payload_csum = 0;
#ifdef CONFIG_IP_VS_IPV6
if (cp->af == AF_INET6)
@@ -135,6 +138,8 @@ udp_snat_handler(struct sk_buff *skb,
return 0;
if (unlikely(cp->app != NULL)) {
+ int ret;
+
/* Some checks before mangling */
if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
return 0;
@@ -142,8 +147,13 @@ udp_snat_handler(struct sk_buff *skb,
/*
* Call application helper if needed
*/
- if (!ip_vs_app_pkt_out(cp, skb))
+ if (!(ret = ip_vs_app_pkt_out(cp, skb)))
return 0;
+ /* ret=2: csum update is needed after payload mangling */
+ if (ret == 1)
+ oldlen = skb->len - udphoff;
+ else
+ payload_csum = 1;
}
udph = (void *)skb_network_header(skb) + udphoff;
@@ -156,12 +166,13 @@ udp_snat_handler(struct sk_buff *skb,
udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
htons(oldlen),
htons(skb->len - udphoff));
- } else if (!cp->app && (udph->check != 0)) {
+ } else if (!payload_csum && (udph->check != 0)) {
/* Only port and addr are changed, do fast csum update */
udp_fast_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
cp->dport, cp->vport);
if (skb->ip_summed == CHECKSUM_COMPLETE)
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = (cp->app && pp->csum_check) ?
+ CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
} else {
/* full checksum calculation */
udph->check = 0;
@@ -181,6 +192,7 @@ udp_snat_handler(struct sk_buff *skb,
skb->csum);
if (udph->check == 0)
udph->check = CSUM_MANGLED_0;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
pp->name, udph->check,
(char*)&(udph->check) - (char*)udph);
@@ -196,6 +208,7 @@ udp_dnat_handler(struct sk_buff *skb,
struct udphdr *udph;
unsigned int udphoff;
int oldlen;
+ int payload_csum = 0;
#ifdef CONFIG_IP_VS_IPV6
if (cp->af == AF_INET6)
@@ -210,6 +223,8 @@ udp_dnat_handler(struct sk_buff *skb,
return 0;
if (unlikely(cp->app != NULL)) {
+ int ret;
+
/* Some checks before mangling */
if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
return 0;
@@ -218,8 +233,13 @@ udp_dnat_handler(struct sk_buff *skb,
* Attempt ip_vs_app call.
* It will fix ip_vs_conn
*/
- if (!ip_vs_app_pkt_in(cp, skb))
+ if (!(ret = ip_vs_app_pkt_in(cp, skb)))
return 0;
+ /* ret=2: csum update is needed after payload mangling */
+ if (ret == 1)
+ oldlen = skb->len - udphoff;
+ else
+ payload_csum = 1;
}
udph = (void *)skb_network_header(skb) + udphoff;
@@ -229,15 +249,16 @@ udp_dnat_handler(struct sk_buff *skb,
* Adjust UDP checksums
*/
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
+ udp_partial_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr,
htons(oldlen),
htons(skb->len - udphoff));
- } else if (!cp->app && (udph->check != 0)) {
+ } else if (!payload_csum && (udph->check != 0)) {
/* Only port and addr are changed, do fast csum update */
udp_fast_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr,
cp->vport, cp->dport);
if (skb->ip_summed == CHECKSUM_COMPLETE)
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = (cp->app && pp->csum_check) ?
+ CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
} else {
/* full checksum calculation */
udph->check = 0;
@@ -293,7 +314,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
skb->len - udphoff,
ipv6_hdr(skb)->nexthdr,
skb->csum)) {
- IP_VS_DBG_RL_PKT(0, pp, skb, 0,
+ IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
"Failed checksum for");
return 0;
}
@@ -304,7 +325,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
skb->len - udphoff,
ip_hdr(skb)->protocol,
skb->csum)) {
- IP_VS_DBG_RL_PKT(0, pp, skb, 0,
+ IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
"Failed checksum for");
return 0;
}
diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c
index bbc1ac795952..076ebe00435d 100644
--- a/net/netfilter/ipvs/ip_vs_sched.c
+++ b/net/netfilter/ipvs/ip_vs_sched.c
@@ -35,7 +35,7 @@
static LIST_HEAD(ip_vs_schedulers);
/* lock for service table */
-static DEFINE_RWLOCK(__ip_vs_sched_lock);
+static DEFINE_SPINLOCK(ip_vs_sched_lock);
/*
@@ -46,15 +46,6 @@ int ip_vs_bind_scheduler(struct ip_vs_service *svc,
{
int ret;
- if (svc == NULL) {
- pr_err("%s(): svc arg NULL\n", __func__);
- return -EINVAL;
- }
- if (scheduler == NULL) {
- pr_err("%s(): scheduler arg NULL\n", __func__);
- return -EINVAL;
- }
-
svc->scheduler = scheduler;
if (scheduler->init_service) {
@@ -74,18 +65,10 @@ int ip_vs_bind_scheduler(struct ip_vs_service *svc,
*/
int ip_vs_unbind_scheduler(struct ip_vs_service *svc)
{
- struct ip_vs_scheduler *sched;
+ struct ip_vs_scheduler *sched = svc->scheduler;
- if (svc == NULL) {
- pr_err("%s(): svc arg NULL\n", __func__);
- return -EINVAL;
- }
-
- sched = svc->scheduler;
- if (sched == NULL) {
- pr_err("%s(): svc isn't bound\n", __func__);
- return -EINVAL;
- }
+ if (!sched)
+ return 0;
if (sched->done_service) {
if (sched->done_service(svc) != 0) {
@@ -108,7 +91,7 @@ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name)
IP_VS_DBG(2, "%s(): sched_name \"%s\"\n", __func__, sched_name);
- read_lock_bh(&__ip_vs_sched_lock);
+ spin_lock_bh(&ip_vs_sched_lock);
list_for_each_entry(sched, &ip_vs_schedulers, n_list) {
/*
@@ -122,14 +105,14 @@ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name)
}
if (strcmp(sched_name, sched->name)==0) {
/* HIT */
- read_unlock_bh(&__ip_vs_sched_lock);
+ spin_unlock_bh(&ip_vs_sched_lock);
return sched;
}
if (sched->module)
module_put(sched->module);
}
- read_unlock_bh(&__ip_vs_sched_lock);
+ spin_unlock_bh(&ip_vs_sched_lock);
return NULL;
}
@@ -159,7 +142,7 @@ struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name)
void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler)
{
- if (scheduler->module)
+ if (scheduler && scheduler->module)
module_put(scheduler->module);
}
@@ -184,10 +167,10 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
/* increase the module use count */
ip_vs_use_count_inc();
- write_lock_bh(&__ip_vs_sched_lock);
+ spin_lock_bh(&ip_vs_sched_lock);
if (!list_empty(&scheduler->n_list)) {
- write_unlock_bh(&__ip_vs_sched_lock);
+ spin_unlock_bh(&ip_vs_sched_lock);
ip_vs_use_count_dec();
pr_err("%s(): [%s] scheduler already linked\n",
__func__, scheduler->name);
@@ -200,7 +183,7 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
*/
list_for_each_entry(sched, &ip_vs_schedulers, n_list) {
if (strcmp(scheduler->name, sched->name) == 0) {
- write_unlock_bh(&__ip_vs_sched_lock);
+ spin_unlock_bh(&ip_vs_sched_lock);
ip_vs_use_count_dec();
pr_err("%s(): [%s] scheduler already existed "
"in the system\n", __func__, scheduler->name);
@@ -211,7 +194,7 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
* Add it into the d-linked scheduler list
*/
list_add(&scheduler->n_list, &ip_vs_schedulers);
- write_unlock_bh(&__ip_vs_sched_lock);
+ spin_unlock_bh(&ip_vs_sched_lock);
pr_info("[%s] scheduler registered.\n", scheduler->name);
@@ -229,9 +212,9 @@ int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
return -EINVAL;
}
- write_lock_bh(&__ip_vs_sched_lock);
+ spin_lock_bh(&ip_vs_sched_lock);
if (list_empty(&scheduler->n_list)) {
- write_unlock_bh(&__ip_vs_sched_lock);
+ spin_unlock_bh(&ip_vs_sched_lock);
pr_err("%s(): [%s] scheduler is not in the list. failed\n",
__func__, scheduler->name);
return -EINVAL;
@@ -241,7 +224,7 @@ int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
* Remove it from the d-linked scheduler list
*/
list_del(&scheduler->n_list);
- write_unlock_bh(&__ip_vs_sched_lock);
+ spin_unlock_bh(&ip_vs_sched_lock);
/* decrease the module use count */
ip_vs_use_count_dec();
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 7ba06939829f..ab85aedea17e 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -288,6 +288,16 @@ void ip_vs_sync_conn(struct ip_vs_conn *cp)
ip_vs_sync_conn(cp->control);
}
+static inline int
+ip_vs_conn_fill_param_sync(int af, int protocol,
+ const union nf_inet_addr *caddr, __be16 cport,
+ const union nf_inet_addr *vaddr, __be16 vport,
+ struct ip_vs_conn_param *p)
+{
+ /* XXX: Need to take into account persistence engine */
+ ip_vs_conn_fill_param(af, protocol, caddr, cport, vaddr, vport, p);
+ return 0;
+}
/*
* Process received multicast message and create the corresponding
@@ -301,6 +311,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
struct ip_vs_conn *cp;
struct ip_vs_protocol *pp;
struct ip_vs_dest *dest;
+ struct ip_vs_conn_param param;
char *p;
int i;
@@ -370,18 +381,20 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
}
}
- if (!(flags & IP_VS_CONN_F_TEMPLATE))
- cp = ip_vs_conn_in_get(AF_INET, s->protocol,
- (union nf_inet_addr *)&s->caddr,
- s->cport,
- (union nf_inet_addr *)&s->vaddr,
- s->vport);
- else
- cp = ip_vs_ct_in_get(AF_INET, s->protocol,
- (union nf_inet_addr *)&s->caddr,
- s->cport,
- (union nf_inet_addr *)&s->vaddr,
- s->vport);
+ {
+ if (ip_vs_conn_fill_param_sync(AF_INET, s->protocol,
+ (union nf_inet_addr *)&s->caddr,
+ s->cport,
+ (union nf_inet_addr *)&s->vaddr,
+ s->vport, &param)) {
+ pr_err("ip_vs_conn_fill_param_sync failed");
+ return;
+ }
+ if (!(flags & IP_VS_CONN_F_TEMPLATE))
+ cp = ip_vs_conn_in_get(&param);
+ else
+ cp = ip_vs_ct_in_get(&param);
+ }
if (!cp) {
/*
* Find the appropriate destination for the connection.
@@ -406,14 +419,9 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
else
flags &= ~IP_VS_CONN_F_INACTIVE;
}
- cp = ip_vs_conn_new(AF_INET, s->protocol,
- (union nf_inet_addr *)&s->caddr,
- s->cport,
- (union nf_inet_addr *)&s->vaddr,
- s->vport,
+ cp = ip_vs_conn_new(&param,
(union nf_inet_addr *)&s->daddr,
- s->dport,
- flags, dest);
+ s->dport, flags, dest);
if (dest)
atomic_dec(&dest->refcnt);
if (!cp) {
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 49df6bea6a2d..de04ea39cde8 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -11,6 +11,16 @@
*
* Changes:
*
+ * Description of forwarding methods:
+ * - all transmitters are called from LOCAL_IN (remote clients) and
+ * LOCAL_OUT (local clients) but for ICMP can be called from FORWARD
+ * - not all connections have destination server, for example,
+ * connections in backup server when fwmark is used
+ * - bypass connections use daddr from packet
+ * LOCAL_OUT rules:
+ * - skb->dev is NULL, skb->protocol is not set (both are set in POST_ROUTING)
+ * - skb->pkt_type is not set yet
+ * - the only place where we can see skb->sk != NULL
*/
#define KMSG_COMPONENT "IPVS"
@@ -26,9 +36,9 @@
#include <net/route.h> /* for ip_route_output */
#include <net/ipv6.h>
#include <net/ip6_route.h>
+#include <net/addrconf.h>
#include <linux/icmpv6.h>
#include <linux/netfilter.h>
-#include <net/netfilter/nf_conntrack.h>
#include <linux/netfilter_ipv4.h>
#include <net/ip_vs.h>
@@ -38,26 +48,27 @@
* Destination cache to speed up outgoing route lookup
*/
static inline void
-__ip_vs_dst_set(struct ip_vs_dest *dest, u32 rtos, struct dst_entry *dst)
+__ip_vs_dst_set(struct ip_vs_dest *dest, u32 rtos, struct dst_entry *dst,
+ u32 dst_cookie)
{
struct dst_entry *old_dst;
old_dst = dest->dst_cache;
dest->dst_cache = dst;
dest->dst_rtos = rtos;
+ dest->dst_cookie = dst_cookie;
dst_release(old_dst);
}
static inline struct dst_entry *
-__ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos, u32 cookie)
+__ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)
{
struct dst_entry *dst = dest->dst_cache;
if (!dst)
return NULL;
- if ((dst->obsolete
- || (dest->af == AF_INET && rtos != dest->dst_rtos)) &&
- dst->ops->check(dst, cookie) == NULL) {
+ if ((dst->obsolete || rtos != dest->dst_rtos) &&
+ dst->ops->check(dst, dest->dst_cookie) == NULL) {
dest->dst_cache = NULL;
dst_release(dst);
return NULL;
@@ -66,16 +77,24 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos, u32 cookie)
return dst;
}
+/*
+ * 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 rtable *
-__ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
+__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
+ __be32 daddr, u32 rtos, int rt_mode)
{
+ struct net *net = dev_net(skb_dst(skb)->dev);
struct rtable *rt; /* Route to the other host */
- struct ip_vs_dest *dest = cp->dest;
+ struct rtable *ort; /* Original route */
+ int local;
if (dest) {
spin_lock(&dest->dst_lock);
if (!(rt = (struct rtable *)
- __ip_vs_dst_check(dest, rtos, 0))) {
+ __ip_vs_dst_check(dest, rtos))) {
struct flowi fl = {
.oif = 0,
.nl_u = {
@@ -85,13 +104,13 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
.tos = rtos, } },
};
- if (ip_route_output_key(&init_net, &rt, &fl)) {
+ if (ip_route_output_key(net, &rt, &fl)) {
spin_unlock(&dest->dst_lock);
IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
&dest->addr.ip);
return NULL;
}
- __ip_vs_dst_set(dest, rtos, dst_clone(&rt->dst));
+ __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,
atomic_read(&rt->dst.__refcnt), rtos);
@@ -102,78 +121,199 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
.oif = 0,
.nl_u = {
.ip4_u = {
- .daddr = cp->daddr.ip,
+ .daddr = daddr,
.saddr = 0,
.tos = rtos, } },
};
- if (ip_route_output_key(&init_net, &rt, &fl)) {
+ if (ip_route_output_key(net, &rt, &fl)) {
IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
- &cp->daddr.ip);
+ &daddr);
return NULL;
}
}
+ local = rt->rt_flags & RTCF_LOCAL;
+ if (!((local ? 1 : 2) & 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);
+ ip_rt_put(rt);
+ return NULL;
+ }
+ if (local && !(rt_mode & 4) && !((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_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_rt_put(rt);
+ return NULL;
+ }
+
return rt;
}
+/* Reroute packet to local IPv4 stack after DNAT */
+static int
+__ip_vs_reroute_locally(struct sk_buff *skb)
+{
+ struct rtable *rt = skb_rtable(skb);
+ struct net_device *dev = rt->dst.dev;
+ struct net *net = dev_net(dev);
+ struct iphdr *iph = ip_hdr(skb);
+
+ if (rt->fl.iif) {
+ unsigned long orefdst = skb->_skb_refdst;
+
+ if (ip_route_input(skb, iph->daddr, iph->saddr,
+ iph->tos, skb->dev))
+ return 0;
+ refdst_drop(orefdst);
+ } else {
+ struct flowi fl = {
+ .oif = 0,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = iph->daddr,
+ .saddr = iph->saddr,
+ .tos = RT_TOS(iph->tos),
+ }
+ },
+ .mark = skb->mark,
+ };
+ struct rtable *rt;
+
+ if (ip_route_output_key(net, &rt, &fl))
+ return 0;
+ if (!(rt->rt_flags & RTCF_LOCAL)) {
+ ip_rt_put(rt);
+ return 0;
+ }
+ /* Drop old route. */
+ skb_dst_drop(skb);
+ skb_dst_set(skb, &rt->dst);
+ }
+ return 1;
+}
+
#ifdef CONFIG_IP_VS_IPV6
+
+static inline int __ip_vs_is_local_route6(struct rt6_info *rt)
+{
+ return rt->rt6i_dev && rt->rt6i_dev->flags & IFF_LOOPBACK;
+}
+
+static struct dst_entry *
+__ip_vs_route_output_v6(struct net *net, struct in6_addr *daddr,
+ struct in6_addr *ret_saddr, int do_xfrm)
+{
+ struct dst_entry *dst;
+ struct flowi fl = {
+ .oif = 0,
+ .nl_u = {
+ .ip6_u = {
+ .daddr = *daddr,
+ },
+ },
+ };
+
+ dst = ip6_route_output(net, NULL, &fl);
+ if (dst->error)
+ goto out_err;
+ if (!ret_saddr)
+ return dst;
+ if (ipv6_addr_any(&fl.fl6_src) &&
+ ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
+ &fl.fl6_dst, 0, &fl.fl6_src) < 0)
+ goto out_err;
+ if (do_xfrm && xfrm_lookup(net, &dst, &fl, NULL, 0) < 0)
+ goto out_err;
+ ipv6_addr_copy(ret_saddr, &fl.fl6_src);
+ return dst;
+
+out_err:
+ dst_release(dst);
+ IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n", daddr);
+ return NULL;
+}
+
+/*
+ * 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 ip_vs_conn *cp)
+__ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
+ struct in6_addr *daddr, struct in6_addr *ret_saddr,
+ int do_xfrm, int rt_mode)
{
+ struct net *net = dev_net(skb_dst(skb)->dev);
struct rt6_info *rt; /* Route to the other host */
- struct ip_vs_dest *dest = cp->dest;
+ struct rt6_info *ort; /* Original route */
+ struct dst_entry *dst;
+ int local;
if (dest) {
spin_lock(&dest->dst_lock);
- rt = (struct rt6_info *)__ip_vs_dst_check(dest, 0, 0);
+ rt = (struct rt6_info *)__ip_vs_dst_check(dest, 0);
if (!rt) {
- struct flowi fl = {
- .oif = 0,
- .nl_u = {
- .ip6_u = {
- .daddr = dest->addr.in6,
- .saddr = {
- .s6_addr32 =
- { 0, 0, 0, 0 },
- },
- },
- },
- };
+ u32 cookie;
- rt = (struct rt6_info *)ip6_route_output(&init_net,
- NULL, &fl);
- if (!rt) {
+ dst = __ip_vs_route_output_v6(net, &dest->addr.in6,
+ &dest->dst_saddr,
+ do_xfrm);
+ if (!dst) {
spin_unlock(&dest->dst_lock);
- IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n",
- &dest->addr.in6);
return NULL;
}
- __ip_vs_dst_set(dest, 0, dst_clone(&rt->dst));
- IP_VS_DBG(10, "new dst %pI6, refcnt=%d\n",
- &dest->addr.in6,
+ rt = (struct rt6_info *) dst;
+ 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,
atomic_read(&rt->dst.__refcnt));
}
+ if (ret_saddr)
+ ipv6_addr_copy(ret_saddr, &dest->dst_saddr);
spin_unlock(&dest->dst_lock);
} else {
- struct flowi fl = {
- .oif = 0,
- .nl_u = {
- .ip6_u = {
- .daddr = cp->daddr.in6,
- .saddr = {
- .s6_addr32 = { 0, 0, 0, 0 },
- },
- },
- },
- };
-
- rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
- if (!rt) {
- IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n",
- &cp->daddr.in6);
+ dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm);
+ if (!dst)
return NULL;
- }
+ rt = (struct rt6_info *) dst;
+ }
+
+ local = __ip_vs_is_local_route6(rt);
+ if (!((local ? 1 : 2) & 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) &&
+ !((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 "
+ "requires NAT method, dest: %pI6\n",
+ &ipv6_hdr(skb)->daddr, daddr);
+ dst_release(&rt->dst);
+ return NULL;
+ }
+ if (unlikely(!local && (!skb->dev || skb->dev->flags & IFF_LOOPBACK) &&
+ ipv6_addr_type(&ipv6_hdr(skb)->saddr) &
+ IPV6_ADDR_LOOPBACK)) {
+ IP_VS_DBG_RL("Stopping traffic from loopback address %pI6 "
+ "to non-local address, dest: %pI6\n",
+ &ipv6_hdr(skb)->saddr, daddr);
+ dst_release(&rt->dst);
+ return NULL;
}
return rt;
@@ -194,12 +334,44 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)
dst_release(old_dst);
}
-#define IP_VS_XMIT(pf, skb, rt) \
+#define IP_VS_XMIT_TUNNEL(skb, cp) \
+({ \
+ int __ret = NF_ACCEPT; \
+ \
+ (skb)->ipvs_property = 1; \
+ if (unlikely((cp)->flags & IP_VS_CONN_F_NFCT)) \
+ __ret = ip_vs_confirm_conntrack(skb, cp); \
+ if (__ret == NF_ACCEPT) { \
+ nf_reset(skb); \
+ skb_forward_csum(skb); \
+ } \
+ __ret; \
+})
+
+#define IP_VS_XMIT_NAT(pf, skb, cp, local) \
+do { \
+ (skb)->ipvs_property = 1; \
+ if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \
+ ip_vs_notrack(skb); \
+ else \
+ ip_vs_update_conntrack(skb, cp, 1); \
+ if (local) \
+ return NF_ACCEPT; \
+ skb_forward_csum(skb); \
+ NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \
+ skb_dst(skb)->dev, dst_output); \
+} while (0)
+
+#define IP_VS_XMIT(pf, skb, cp, local) \
do { \
(skb)->ipvs_property = 1; \
+ if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \
+ ip_vs_notrack(skb); \
+ if (local) \
+ return NF_ACCEPT; \
skb_forward_csum(skb); \
NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \
- (rt)->dst.dev, dst_output); \
+ skb_dst(skb)->dev, dst_output); \
} while (0)
@@ -211,7 +383,7 @@ ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
struct ip_vs_protocol *pp)
{
/* we do not touch skb and do not need pskb ptr */
- return NF_ACCEPT;
+ IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1);
}
@@ -226,24 +398,13 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
{
struct rtable *rt; /* Route to the other host */
struct iphdr *iph = ip_hdr(skb);
- u8 tos = iph->tos;
int mtu;
- struct flowi fl = {
- .oif = 0,
- .nl_u = {
- .ip4_u = {
- .daddr = iph->daddr,
- .saddr = 0,
- .tos = RT_TOS(tos), } },
- };
EnterFunction(10);
- if (ip_route_output_key(&init_net, &rt, &fl)) {
- IP_VS_DBG_RL("%s(): ip_route_output error, dest: %pI4\n",
- __func__, &iph->daddr);
+ if (!(rt = __ip_vs_get_out_rt(skb, NULL, iph->daddr,
+ RT_TOS(iph->tos), 2)))
goto tx_error_icmp;
- }
/* MTU checking */
mtu = dst_mtu(&rt->dst);
@@ -271,7 +432,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
+ IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 0);
LeaveFunction(10);
return NF_STOLEN;
@@ -292,28 +453,22 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
struct rt6_info *rt; /* Route to the other host */
struct ipv6hdr *iph = ipv6_hdr(skb);
int mtu;
- struct flowi fl = {
- .oif = 0,
- .nl_u = {
- .ip6_u = {
- .daddr = iph->daddr,
- .saddr = { .s6_addr32 = {0, 0, 0, 0} }, } },
- };
EnterFunction(10);
- rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
- if (!rt) {
- IP_VS_DBG_RL("%s(): ip6_route_output error, dest: %pI6\n",
- __func__, &iph->daddr);
+ if (!(rt = __ip_vs_get_out_rt_v6(skb, NULL, &iph->daddr, NULL, 0, 2)))
goto tx_error_icmp;
- }
/* MTU checking */
mtu = dst_mtu(&rt->dst);
if (skb->len > mtu) {
- dst_release(&rt->dst);
+ if (!skb->dev) {
+ struct net *net = dev_net(skb_dst(skb)->dev);
+
+ skb->dev = net->loopback_dev;
+ }
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+ dst_release(&rt->dst);
IP_VS_DBG_RL("%s(): frag needed\n", __func__);
goto tx_error;
}
@@ -335,7 +490,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
+ IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 0);
LeaveFunction(10);
return NF_STOLEN;
@@ -349,36 +504,6 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
}
#endif
-void
-ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin)
-{
- struct nf_conn *ct = (struct nf_conn *)skb->nfct;
- struct nf_conntrack_tuple new_tuple;
-
- if (ct == NULL || nf_ct_is_untracked(ct) || nf_ct_is_confirmed(ct))
- return;
-
- /*
- * The connection is not yet in the hashtable, so we update it.
- * CIP->VIP will remain the same, so leave the tuple in
- * IP_CT_DIR_ORIGINAL untouched. When the reply comes back from the
- * real-server we will see RIP->DIP.
- */
- new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
- if (outin)
- new_tuple.src.u3 = cp->daddr;
- else
- new_tuple.dst.u3 = cp->vaddr;
- /*
- * This will also take care of UDP and other protocols.
- */
- if (outin)
- new_tuple.src.u.tcp.port = cp->dport;
- else
- new_tuple.dst.u.tcp.port = cp->vport;
- nf_conntrack_alter_reply(ct, &new_tuple);
-}
-
/*
* NAT transmitter (only for outside-to-inside nat forwarding)
* Not used for related ICMP
@@ -390,6 +515,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
struct rtable *rt; /* Route to the other host */
int mtu;
struct iphdr *iph = ip_hdr(skb);
+ int local;
EnterFunction(10);
@@ -403,16 +529,42 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
IP_VS_DBG(10, "filled cport=%d\n", ntohs(*p));
}
- if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(iph->tos))))
+ if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
+ RT_TOS(iph->tos), 1|2|4)))
goto tx_error_icmp;
+ local = rt->rt_flags & RTCF_LOCAL;
+ /*
+ * Avoid duplicate tuple in reply direction for NAT traffic
+ * to local address when connection is sync-ed
+ */
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ if (cp->flags & IP_VS_CONN_F_SYNC && local) {
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo);
+
+ if (ct && !nf_ct_is_untracked(ct)) {
+ IP_VS_DBG_RL_PKT(10, AF_INET, pp, skb, 0,
+ "ip_vs_nat_xmit(): "
+ "stopping DNAT to local address");
+ goto tx_error_put;
+ }
+ }
+#endif
+
+ /* From world but DNAT to loopback address? */
+ if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) {
+ IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): "
+ "stopping DNAT to loopback address");
+ goto tx_error_put;
+ }
/* MTU checking */
mtu = dst_mtu(&rt->dst);
if ((skb->len > mtu) && (iph->frag_off & htons(IP_DF))) {
- ip_rt_put(rt);
icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
- IP_VS_DBG_RL_PKT(0, pp, skb, 0, "ip_vs_nat_xmit(): frag needed for");
- goto tx_error;
+ IP_VS_DBG_RL_PKT(0, AF_INET, pp, skb, 0,
+ "ip_vs_nat_xmit(): frag needed for");
+ goto tx_error_put;
}
/* copy-on-write the packet before mangling it */
@@ -422,19 +574,28 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
if (skb_cow(skb, rt->dst.dev->hard_header_len))
goto tx_error_put;
- /* drop old route */
- skb_dst_drop(skb);
- skb_dst_set(skb, &rt->dst);
-
/* mangle the packet */
if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp))
- goto tx_error;
+ goto tx_error_put;
ip_hdr(skb)->daddr = cp->daddr.ip;
ip_send_check(ip_hdr(skb));
- IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT");
+ if (!local) {
+ /* drop old route */
+ skb_dst_drop(skb);
+ skb_dst_set(skb, &rt->dst);
+ } else {
+ ip_rt_put(rt);
+ /*
+ * Some IPv4 replies get local address from routes,
+ * not from iph, so while we DNAT after routing
+ * we need this second input/output route.
+ */
+ if (!__ip_vs_reroute_locally(skb))
+ goto tx_error;
+ }
- ip_vs_update_conntrack(skb, cp, 1);
+ IP_VS_DBG_PKT(10, AF_INET, pp, skb, 0, "After DNAT");
/* FIXME: when application helper enlarges the packet and the length
is larger than the MTU of outgoing device, there will be still
@@ -443,7 +604,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
+ IP_VS_XMIT_NAT(NFPROTO_IPV4, skb, cp, local);
LeaveFunction(10);
return NF_STOLEN;
@@ -451,8 +612,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
tx_error_icmp:
dst_link_failure(skb);
tx_error:
- LeaveFunction(10);
kfree_skb(skb);
+ LeaveFunction(10);
return NF_STOLEN;
tx_error_put:
ip_rt_put(rt);
@@ -466,6 +627,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
{
struct rt6_info *rt; /* Route to the other host */
int mtu;
+ int local;
EnterFunction(10);
@@ -480,18 +642,49 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
IP_VS_DBG(10, "filled cport=%d\n", ntohs(*p));
}
- rt = __ip_vs_get_out_rt_v6(cp);
- if (!rt)
+ if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL,
+ 0, 1|2|4)))
goto tx_error_icmp;
+ local = __ip_vs_is_local_route6(rt);
+ /*
+ * Avoid duplicate tuple in reply direction for NAT traffic
+ * to local address when connection is sync-ed
+ */
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ if (cp->flags & IP_VS_CONN_F_SYNC && local) {
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo);
+
+ if (ct && !nf_ct_is_untracked(ct)) {
+ IP_VS_DBG_RL_PKT(10, AF_INET6, pp, skb, 0,
+ "ip_vs_nat_xmit_v6(): "
+ "stopping DNAT to local address");
+ goto tx_error_put;
+ }
+ }
+#endif
+
+ /* From world but DNAT to loopback address? */
+ if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) &&
+ ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) {
+ IP_VS_DBG_RL_PKT(1, AF_INET6, pp, skb, 0,
+ "ip_vs_nat_xmit_v6(): "
+ "stopping DNAT to loopback address");
+ goto tx_error_put;
+ }
/* MTU checking */
mtu = dst_mtu(&rt->dst);
if (skb->len > mtu) {
- dst_release(&rt->dst);
+ if (!skb->dev) {
+ struct net *net = dev_net(skb_dst(skb)->dev);
+
+ skb->dev = net->loopback_dev;
+ }
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
- IP_VS_DBG_RL_PKT(0, pp, skb, 0,
+ IP_VS_DBG_RL_PKT(0, AF_INET6, pp, skb, 0,
"ip_vs_nat_xmit_v6(): frag needed for");
- goto tx_error;
+ goto tx_error_put;
}
/* copy-on-write the packet before mangling it */
@@ -501,18 +694,21 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
if (skb_cow(skb, rt->dst.dev->hard_header_len))
goto tx_error_put;
- /* drop old route */
- skb_dst_drop(skb);
- skb_dst_set(skb, &rt->dst);
-
/* mangle the packet */
if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp))
goto tx_error;
- ipv6_hdr(skb)->daddr = cp->daddr.in6;
+ ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &cp->daddr.in6);
- IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT");
+ if (!local || !skb->dev) {
+ /* drop the old route when skb is not shared */
+ skb_dst_drop(skb);
+ skb_dst_set(skb, &rt->dst);
+ } else {
+ /* destined to loopback, do we need to change route? */
+ dst_release(&rt->dst);
+ }
- ip_vs_update_conntrack(skb, cp, 1);
+ IP_VS_DBG_PKT(10, AF_INET6, pp, skb, 0, "After DNAT");
/* FIXME: when application helper enlarges the packet and the length
is larger than the MTU of outgoing device, there will be still
@@ -521,7 +717,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
+ IP_VS_XMIT_NAT(NFPROTO_IPV6, skb, cp, local);
LeaveFunction(10);
return NF_STOLEN;
@@ -567,30 +763,27 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
struct iphdr *old_iph = ip_hdr(skb);
u8 tos = old_iph->tos;
__be16 df = old_iph->frag_off;
- sk_buff_data_t old_transport_header = skb->transport_header;
struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
int mtu;
+ int ret;
EnterFunction(10);
- if (skb->protocol != htons(ETH_P_IP)) {
- IP_VS_DBG_RL("%s(): protocol error, "
- "ETH_P_IP: %d, skb protocol: %d\n",
- __func__, htons(ETH_P_IP), skb->protocol);
- goto tx_error;
- }
-
- if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(tos))))
+ if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
+ RT_TOS(tos), 1|2)))
goto tx_error_icmp;
+ if (rt->rt_flags & RTCF_LOCAL) {
+ ip_rt_put(rt);
+ IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1);
+ }
tdev = rt->dst.dev;
mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr);
if (mtu < 68) {
- ip_rt_put(rt);
IP_VS_DBG_RL("%s(): mtu less than 68\n", __func__);
- goto tx_error;
+ goto tx_error_put;
}
if (skb_dst(skb))
skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
@@ -600,9 +793,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
if ((old_iph->frag_off & htons(IP_DF))
&& mtu < ntohs(old_iph->tot_len)) {
icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
- ip_rt_put(rt);
IP_VS_DBG_RL("%s(): frag needed\n", __func__);
- goto tx_error;
+ goto tx_error_put;
}
/*
@@ -625,7 +817,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
old_iph = ip_hdr(skb);
}
- skb->transport_header = old_transport_header;
+ skb->transport_header = skb->network_header;
/* fix old IP header checksum */
ip_send_check(old_iph);
@@ -655,7 +847,11 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- ip_local_out(skb);
+ ret = IP_VS_XMIT_TUNNEL(skb, cp);
+ if (ret == NF_ACCEPT)
+ ip_local_out(skb);
+ else if (ret == NF_DROP)
+ kfree_skb(skb);
LeaveFunction(10);
@@ -667,6 +863,9 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
kfree_skb(skb);
LeaveFunction(10);
return NF_STOLEN;
+tx_error_put:
+ ip_rt_put(rt);
+ goto tx_error;
}
#ifdef CONFIG_IP_VS_IPV6
@@ -675,43 +874,44 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
struct ip_vs_protocol *pp)
{
struct rt6_info *rt; /* Route to the other host */
+ struct in6_addr saddr; /* Source for tunnel */
struct net_device *tdev; /* Device to other host */
struct ipv6hdr *old_iph = ipv6_hdr(skb);
- sk_buff_data_t old_transport_header = skb->transport_header;
struct ipv6hdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
int mtu;
+ int ret;
EnterFunction(10);
- if (skb->protocol != htons(ETH_P_IPV6)) {
- IP_VS_DBG_RL("%s(): protocol error, "
- "ETH_P_IPV6: %d, skb protocol: %d\n",
- __func__, htons(ETH_P_IPV6), skb->protocol);
- goto tx_error;
- }
-
- rt = __ip_vs_get_out_rt_v6(cp);
- if (!rt)
+ if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6,
+ &saddr, 1, 1|2)))
goto tx_error_icmp;
+ if (__ip_vs_is_local_route6(rt)) {
+ dst_release(&rt->dst);
+ IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 1);
+ }
tdev = rt->dst.dev;
mtu = dst_mtu(&rt->dst) - sizeof(struct ipv6hdr);
- /* TODO IPv6: do we need this check in IPv6? */
- if (mtu < 1280) {
- dst_release(&rt->dst);
- IP_VS_DBG_RL("%s(): mtu less than 1280\n", __func__);
- goto tx_error;
+ if (mtu < IPV6_MIN_MTU) {
+ IP_VS_DBG_RL("%s(): mtu less than %d\n", __func__,
+ IPV6_MIN_MTU);
+ goto tx_error_put;
}
if (skb_dst(skb))
skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)) {
+ if (!skb->dev) {
+ struct net *net = dev_net(skb_dst(skb)->dev);
+
+ skb->dev = net->loopback_dev;
+ }
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
- dst_release(&rt->dst);
IP_VS_DBG_RL("%s(): frag needed\n", __func__);
- goto tx_error;
+ goto tx_error_put;
}
/*
@@ -734,7 +934,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
old_iph = ipv6_hdr(skb);
}
- skb->transport_header = old_transport_header;
+ skb->transport_header = skb->network_header;
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
@@ -754,14 +954,18 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
be16_add_cpu(&iph->payload_len, sizeof(*old_iph));
iph->priority = old_iph->priority;
memset(&iph->flow_lbl, 0, sizeof(iph->flow_lbl));
- iph->daddr = rt->rt6i_dst.addr;
- iph->saddr = cp->vaddr.in6; /* rt->rt6i_src.addr; */
+ ipv6_addr_copy(&iph->daddr, &cp->daddr.in6);
+ ipv6_addr_copy(&iph->saddr, &saddr);
iph->hop_limit = old_iph->hop_limit;
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- ip6_local_out(skb);
+ ret = IP_VS_XMIT_TUNNEL(skb, cp);
+ if (ret == NF_ACCEPT)
+ ip6_local_out(skb);
+ else if (ret == NF_DROP)
+ kfree_skb(skb);
LeaveFunction(10);
@@ -773,6 +977,9 @@ tx_error:
kfree_skb(skb);
LeaveFunction(10);
return NF_STOLEN;
+tx_error_put:
+ dst_release(&rt->dst);
+ goto tx_error;
}
#endif
@@ -791,8 +998,13 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
EnterFunction(10);
- if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(iph->tos))))
+ if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
+ RT_TOS(iph->tos), 1|2)))
goto tx_error_icmp;
+ if (rt->rt_flags & RTCF_LOCAL) {
+ ip_rt_put(rt);
+ IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1);
+ }
/* MTU checking */
mtu = dst_mtu(&rt->dst);
@@ -820,7 +1032,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
+ IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 0);
LeaveFunction(10);
return NF_STOLEN;
@@ -843,13 +1055,22 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
EnterFunction(10);
- rt = __ip_vs_get_out_rt_v6(cp);
- if (!rt)
+ if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL,
+ 0, 1|2)))
goto tx_error_icmp;
+ if (__ip_vs_is_local_route6(rt)) {
+ dst_release(&rt->dst);
+ IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 1);
+ }
/* MTU checking */
mtu = dst_mtu(&rt->dst);
if (skb->len > mtu) {
+ if (!skb->dev) {
+ struct net *net = dev_net(skb_dst(skb)->dev);
+
+ skb->dev = net->loopback_dev;
+ }
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
dst_release(&rt->dst);
IP_VS_DBG_RL("%s(): frag needed\n", __func__);
@@ -873,7 +1094,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
+ IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 0);
LeaveFunction(10);
return NF_STOLEN;
@@ -899,6 +1120,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
struct rtable *rt; /* Route to the other host */
int mtu;
int rc;
+ int local;
EnterFunction(10);
@@ -919,16 +1141,43 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
* mangle and send the packet here (only for VS/NAT)
*/
- if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(ip_hdr(skb)->tos))))
+ if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
+ RT_TOS(ip_hdr(skb)->tos), 1|2|4)))
goto tx_error_icmp;
+ local = rt->rt_flags & RTCF_LOCAL;
+
+ /*
+ * Avoid duplicate tuple in reply direction for NAT traffic
+ * to local address when connection is sync-ed
+ */
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ if (cp->flags & IP_VS_CONN_F_SYNC && local) {
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo);
+
+ if (ct && !nf_ct_is_untracked(ct)) {
+ IP_VS_DBG(10, "%s(): "
+ "stopping DNAT to local address %pI4\n",
+ __func__, &cp->daddr.ip);
+ goto tx_error_put;
+ }
+ }
+#endif
+
+ /* From world but DNAT to loopback address? */
+ if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) {
+ IP_VS_DBG(1, "%s(): "
+ "stopping DNAT to loopback %pI4\n",
+ __func__, &cp->daddr.ip);
+ goto tx_error_put;
+ }
/* MTU checking */
mtu = dst_mtu(&rt->dst);
if ((skb->len > mtu) && (ip_hdr(skb)->frag_off & htons(IP_DF))) {
- ip_rt_put(rt);
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
IP_VS_DBG_RL("%s(): frag needed\n", __func__);
- goto tx_error;
+ goto tx_error_put;
}
/* copy-on-write the packet before mangling it */
@@ -938,16 +1187,27 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
if (skb_cow(skb, rt->dst.dev->hard_header_len))
goto tx_error_put;
- /* drop the old route when skb is not shared */
- skb_dst_drop(skb);
- skb_dst_set(skb, &rt->dst);
-
ip_vs_nat_icmp(skb, pp, cp, 0);
+ if (!local) {
+ /* drop the old route when skb is not shared */
+ skb_dst_drop(skb);
+ skb_dst_set(skb, &rt->dst);
+ } else {
+ ip_rt_put(rt);
+ /*
+ * Some IPv4 replies get local address from routes,
+ * not from iph, so while we DNAT after routing
+ * we need this second input/output route.
+ */
+ if (!__ip_vs_reroute_locally(skb))
+ goto tx_error;
+ }
+
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
+ IP_VS_XMIT_NAT(NFPROTO_IPV4, skb, cp, local);
rc = NF_STOLEN;
goto out;
@@ -973,6 +1233,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
struct rt6_info *rt; /* Route to the other host */
int mtu;
int rc;
+ int local;
EnterFunction(10);
@@ -993,17 +1254,49 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
* mangle and send the packet here (only for VS/NAT)
*/
- rt = __ip_vs_get_out_rt_v6(cp);
- if (!rt)
+ if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL,
+ 0, 1|2|4)))
goto tx_error_icmp;
+ local = __ip_vs_is_local_route6(rt);
+ /*
+ * Avoid duplicate tuple in reply direction for NAT traffic
+ * to local address when connection is sync-ed
+ */
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ if (cp->flags & IP_VS_CONN_F_SYNC && local) {
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo);
+
+ if (ct && !nf_ct_is_untracked(ct)) {
+ IP_VS_DBG(10, "%s(): "
+ "stopping DNAT to local address %pI6\n",
+ __func__, &cp->daddr.in6);
+ goto tx_error_put;
+ }
+ }
+#endif
+
+ /* From world but DNAT to loopback address? */
+ if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) &&
+ ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) {
+ IP_VS_DBG(1, "%s(): "
+ "stopping DNAT to loopback %pI6\n",
+ __func__, &cp->daddr.in6);
+ goto tx_error_put;
+ }
+
/* MTU checking */
mtu = dst_mtu(&rt->dst);
if (skb->len > mtu) {
- dst_release(&rt->dst);
+ if (!skb->dev) {
+ struct net *net = dev_net(skb_dst(skb)->dev);
+
+ skb->dev = net->loopback_dev;
+ }
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
IP_VS_DBG_RL("%s(): frag needed\n", __func__);
- goto tx_error;
+ goto tx_error_put;
}
/* copy-on-write the packet before mangling it */
@@ -1013,16 +1306,21 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
if (skb_cow(skb, rt->dst.dev->hard_header_len))
goto tx_error_put;
- /* drop the old route when skb is not shared */
- skb_dst_drop(skb);
- skb_dst_set(skb, &rt->dst);
-
ip_vs_nat_icmp_v6(skb, pp, cp, 0);
+ if (!local || !skb->dev) {
+ /* drop the old route when skb is not shared */
+ skb_dst_drop(skb);
+ skb_dst_set(skb, &rt->dst);
+ } else {
+ /* destined to loopback, do we need to change route? */
+ dst_release(&rt->dst);
+ }
+
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
+ IP_VS_XMIT_NAT(NFPROTO_IPV6, skb, cp, local);
rc = NF_STOLEN;
goto out;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index df3eedb142ff..1eacf8d9966a 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -65,32 +65,42 @@ EXPORT_SYMBOL_GPL(nf_conntrack_max);
DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked);
EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked);
-static int nf_conntrack_hash_rnd_initted;
-static unsigned int nf_conntrack_hash_rnd;
+static unsigned int nf_conntrack_hash_rnd __read_mostly;
-static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
- u16 zone, unsigned int size, unsigned int rnd)
+static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple, u16 zone)
{
unsigned int n;
- u_int32_t h;
/* The direction must be ignored, so we hash everything up to the
* destination ports (which is a multiple of 4) and treat the last
* three bytes manually.
*/
n = (sizeof(tuple->src) + sizeof(tuple->dst.u3)) / sizeof(u32);
- h = jhash2((u32 *)tuple, n,
- zone ^ rnd ^ (((__force __u16)tuple->dst.u.all << 16) |
- tuple->dst.protonum));
+ return jhash2((u32 *)tuple, n, zone ^ nf_conntrack_hash_rnd ^
+ (((__force __u16)tuple->dst.u.all << 16) |
+ tuple->dst.protonum));
+}
+
+static u32 __hash_bucket(u32 hash, unsigned int size)
+{
+ return ((u64)hash * size) >> 32;
+}
+
+static u32 hash_bucket(u32 hash, const struct net *net)
+{
+ return __hash_bucket(hash, net->ct.htable_size);
+}
- return ((u64)h * size) >> 32;
+static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
+ u16 zone, unsigned int size)
+{
+ return __hash_bucket(hash_conntrack_raw(tuple, zone), size);
}
static inline u_int32_t hash_conntrack(const struct net *net, u16 zone,
const struct nf_conntrack_tuple *tuple)
{
- return __hash_conntrack(tuple, zone, net->ct.htable_size,
- nf_conntrack_hash_rnd);
+ return __hash_conntrack(tuple, zone, net->ct.htable_size);
}
bool
@@ -292,20 +302,20 @@ static void death_by_timeout(unsigned long ul_conntrack)
* OR
* - Caller must lock nf_conntrack_lock before calling this function
*/
-struct nf_conntrack_tuple_hash *
-__nf_conntrack_find(struct net *net, u16 zone,
- const struct nf_conntrack_tuple *tuple)
+static struct nf_conntrack_tuple_hash *
+____nf_conntrack_find(struct net *net, u16 zone,
+ const struct nf_conntrack_tuple *tuple, u32 hash)
{
struct nf_conntrack_tuple_hash *h;
struct hlist_nulls_node *n;
- unsigned int hash = hash_conntrack(net, zone, tuple);
+ unsigned int bucket = hash_bucket(hash, net);
/* Disable BHs the entire time since we normally need to disable them
* at least once for the stats anyway.
*/
local_bh_disable();
begin:
- hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnnode) {
+ hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[bucket], hnnode) {
if (nf_ct_tuple_equal(tuple, &h->tuple) &&
nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)) == zone) {
NF_CT_STAT_INC(net, found);
@@ -319,7 +329,7 @@ begin:
* not the expected one, we must restart lookup.
* We probably met an item that was moved to another chain.
*/
- if (get_nulls_value(n) != hash) {
+ if (get_nulls_value(n) != bucket) {
NF_CT_STAT_INC(net, search_restart);
goto begin;
}
@@ -327,19 +337,27 @@ begin:
return NULL;
}
+
+struct nf_conntrack_tuple_hash *
+__nf_conntrack_find(struct net *net, u16 zone,
+ const struct nf_conntrack_tuple *tuple)
+{
+ return ____nf_conntrack_find(net, zone, tuple,
+ hash_conntrack_raw(tuple, zone));
+}
EXPORT_SYMBOL_GPL(__nf_conntrack_find);
/* Find a connection corresponding to a tuple. */
-struct nf_conntrack_tuple_hash *
-nf_conntrack_find_get(struct net *net, u16 zone,
- const struct nf_conntrack_tuple *tuple)
+static struct nf_conntrack_tuple_hash *
+__nf_conntrack_find_get(struct net *net, u16 zone,
+ const struct nf_conntrack_tuple *tuple, u32 hash)
{
struct nf_conntrack_tuple_hash *h;
struct nf_conn *ct;
rcu_read_lock();
begin:
- h = __nf_conntrack_find(net, zone, tuple);
+ h = ____nf_conntrack_find(net, zone, tuple, hash);
if (h) {
ct = nf_ct_tuplehash_to_ctrack(h);
if (unlikely(nf_ct_is_dying(ct) ||
@@ -357,6 +375,14 @@ begin:
return h;
}
+
+struct nf_conntrack_tuple_hash *
+nf_conntrack_find_get(struct net *net, u16 zone,
+ const struct nf_conntrack_tuple *tuple)
+{
+ return __nf_conntrack_find_get(net, zone, tuple,
+ hash_conntrack_raw(tuple, zone));
+}
EXPORT_SYMBOL_GPL(nf_conntrack_find_get);
static void __nf_conntrack_hash_insert(struct nf_conn *ct,
@@ -409,8 +435,11 @@ __nf_conntrack_confirm(struct sk_buff *skb)
return NF_ACCEPT;
zone = nf_ct_zone(ct);
- hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
- repl_hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+ /* reuse the hash saved before */
+ hash = *(unsigned long *)&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev;
+ hash = hash_bucket(hash, net);
+ repl_hash = hash_conntrack(net, zone,
+ &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
/* We're not in hash table, and we refuse to set up related
connections for unconfirmed conns. But packet copies and
@@ -567,17 +596,29 @@ static noinline int early_drop(struct net *net, unsigned int hash)
return dropped;
}
-struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone,
- const struct nf_conntrack_tuple *orig,
- const struct nf_conntrack_tuple *repl,
- gfp_t gfp)
+static struct nf_conn *
+__nf_conntrack_alloc(struct net *net, u16 zone,
+ const struct nf_conntrack_tuple *orig,
+ const struct nf_conntrack_tuple *repl,
+ gfp_t gfp, u32 hash)
{
struct nf_conn *ct;
- if (unlikely(!nf_conntrack_hash_rnd_initted)) {
- get_random_bytes(&nf_conntrack_hash_rnd,
- sizeof(nf_conntrack_hash_rnd));
- nf_conntrack_hash_rnd_initted = 1;
+ if (unlikely(!nf_conntrack_hash_rnd)) {
+ unsigned int rand;
+
+ /*
+ * Why not initialize nf_conntrack_rnd in a "init()" function ?
+ * Because there isn't enough entropy when system initializing,
+ * and we initialize it as late as possible.
+ */
+ do {
+ get_random_bytes(&rand, sizeof(rand));
+ } while (!rand);
+ cmpxchg(&nf_conntrack_hash_rnd, 0, rand);
+
+ /* recompute the hash as nf_conntrack_hash_rnd is initialized */
+ hash = hash_conntrack_raw(orig, zone);
}
/* We don't want any race condition at early drop stage */
@@ -585,8 +626,7 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone,
if (nf_conntrack_max &&
unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) {
- unsigned int hash = hash_conntrack(net, zone, orig);
- if (!early_drop(net, hash)) {
+ if (!early_drop(net, hash_bucket(hash, net))) {
atomic_dec(&net->ct.count);
if (net_ratelimit())
printk(KERN_WARNING
@@ -616,7 +656,8 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone,
ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL;
ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
- ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev = NULL;
+ /* save hash for reusing when confirming */
+ *(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash;
/* Don't set timer yet: wait for confirmation */
setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
write_pnet(&ct->ct_net, net);
@@ -643,6 +684,14 @@ out_free:
return ERR_PTR(-ENOMEM);
#endif
}
+
+struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone,
+ const struct nf_conntrack_tuple *orig,
+ const struct nf_conntrack_tuple *repl,
+ gfp_t gfp)
+{
+ return __nf_conntrack_alloc(net, zone, orig, repl, gfp, 0);
+}
EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
void nf_conntrack_free(struct nf_conn *ct)
@@ -664,7 +713,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
struct nf_conntrack_l3proto *l3proto,
struct nf_conntrack_l4proto *l4proto,
struct sk_buff *skb,
- unsigned int dataoff)
+ unsigned int dataoff, u32 hash)
{
struct nf_conn *ct;
struct nf_conn_help *help;
@@ -678,7 +727,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
return NULL;
}
- ct = nf_conntrack_alloc(net, zone, tuple, &repl_tuple, GFP_ATOMIC);
+ ct = __nf_conntrack_alloc(net, zone, tuple, &repl_tuple, GFP_ATOMIC,
+ hash);
if (IS_ERR(ct)) {
pr_debug("Can't allocate conntrack.\n");
return (struct nf_conntrack_tuple_hash *)ct;
@@ -755,6 +805,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
struct nf_conntrack_tuple_hash *h;
struct nf_conn *ct;
u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE;
+ u32 hash;
if (!nf_ct_get_tuple(skb, skb_network_offset(skb),
dataoff, l3num, protonum, &tuple, l3proto,
@@ -764,10 +815,11 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
}
/* look for tuple match */
- h = nf_conntrack_find_get(net, zone, &tuple);
+ hash = hash_conntrack_raw(&tuple, zone);
+ h = __nf_conntrack_find_get(net, zone, &tuple, hash);
if (!h) {
h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto,
- skb, dataoff);
+ skb, dataoff, hash);
if (!h)
return NULL;
if (IS_ERR(h))
@@ -1307,8 +1359,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
ct = nf_ct_tuplehash_to_ctrack(h);
hlist_nulls_del_rcu(&h->hnnode);
bucket = __hash_conntrack(&h->tuple, nf_ct_zone(ct),
- hashsize,
- nf_conntrack_hash_rnd);
+ hashsize);
hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]);
}
}
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index acb29ccaa41f..46e8966912b1 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -38,25 +38,30 @@ static int nf_ct_expect_hash_rnd_initted __read_mostly;
static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
+static HLIST_HEAD(nf_ct_userspace_expect_list);
+
/* nf_conntrack_expect helper functions */
-void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
+void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,
+ u32 pid, int report)
{
struct nf_conn_help *master_help = nfct_help(exp->master);
struct net *net = nf_ct_exp_net(exp);
- NF_CT_ASSERT(master_help);
NF_CT_ASSERT(!timer_pending(&exp->timeout));
hlist_del_rcu(&exp->hnode);
net->ct.expect_count--;
hlist_del(&exp->lnode);
- master_help->expecting[exp->class]--;
+ if (!(exp->flags & NF_CT_EXPECT_USERSPACE))
+ master_help->expecting[exp->class]--;
+
+ nf_ct_expect_event_report(IPEXP_DESTROY, exp, pid, report);
nf_ct_expect_put(exp);
NF_CT_STAT_INC(net, expect_delete);
}
-EXPORT_SYMBOL_GPL(nf_ct_unlink_expect);
+EXPORT_SYMBOL_GPL(nf_ct_unlink_expect_report);
static void nf_ct_expectation_timed_out(unsigned long ul_expect)
{
@@ -320,16 +325,21 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
atomic_inc(&exp->use);
- hlist_add_head(&exp->lnode, &master_help->expectations);
- master_help->expecting[exp->class]++;
+ if (master_help) {
+ hlist_add_head(&exp->lnode, &master_help->expectations);
+ master_help->expecting[exp->class]++;
+ } else if (exp->flags & NF_CT_EXPECT_USERSPACE)
+ hlist_add_head(&exp->lnode, &nf_ct_userspace_expect_list);
hlist_add_head_rcu(&exp->hnode, &net->ct.expect_hash[h]);
net->ct.expect_count++;
setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
(unsigned long)exp);
- p = &master_help->helper->expect_policy[exp->class];
- exp->timeout.expires = jiffies + p->timeout * HZ;
+ if (master_help) {
+ p = &master_help->helper->expect_policy[exp->class];
+ exp->timeout.expires = jiffies + p->timeout * HZ;
+ }
add_timer(&exp->timeout);
atomic_inc(&exp->use);
@@ -380,7 +390,9 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
unsigned int h;
int ret = 1;
- if (!master_help->helper) {
+ /* Don't allow expectations created from kernel-space with no helper */
+ if (!(expect->flags & NF_CT_EXPECT_USERSPACE) &&
+ (!master_help || (master_help && !master_help->helper))) {
ret = -ESHUTDOWN;
goto out;
}
@@ -398,13 +410,16 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
}
}
/* Will be over limit? */
- p = &master_help->helper->expect_policy[expect->class];
- if (p->max_expected &&
- master_help->expecting[expect->class] >= p->max_expected) {
- evict_oldest_expect(master, expect);
- if (master_help->expecting[expect->class] >= p->max_expected) {
- ret = -EMFILE;
- goto out;
+ if (master_help) {
+ p = &master_help->helper->expect_policy[expect->class];
+ if (p->max_expected &&
+ master_help->expecting[expect->class] >= p->max_expected) {
+ evict_oldest_expect(master, expect);
+ if (master_help->expecting[expect->class]
+ >= p->max_expected) {
+ ret = -EMFILE;
+ goto out;
+ }
}
}
@@ -439,6 +454,21 @@ out:
}
EXPORT_SYMBOL_GPL(nf_ct_expect_related_report);
+void nf_ct_remove_userspace_expectations(void)
+{
+ struct nf_conntrack_expect *exp;
+ struct hlist_node *n, *next;
+
+ hlist_for_each_entry_safe(exp, n, next,
+ &nf_ct_userspace_expect_list, lnode) {
+ if (del_timer(&exp->timeout)) {
+ nf_ct_unlink_expect(exp);
+ nf_ct_expect_put(exp);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(nf_ct_remove_userspace_expectations);
+
#ifdef CONFIG_PROC_FS
struct ct_expect_iter_state {
struct seq_net_private p;
@@ -529,8 +559,12 @@ static int exp_seq_show(struct seq_file *s, void *v)
seq_printf(s, "PERMANENT");
delim = ",";
}
- if (expect->flags & NF_CT_EXPECT_INACTIVE)
+ if (expect->flags & NF_CT_EXPECT_INACTIVE) {
seq_printf(s, "%sINACTIVE", delim);
+ delim = ",";
+ }
+ if (expect->flags & NF_CT_EXPECT_USERSPACE)
+ seq_printf(s, "%sUSERSPACE", delim);
helper = rcu_dereference(nfct_help(expect->master)->helper);
if (helper) {
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 146476c6441a..b729ace1dcc1 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1588,8 +1588,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
const struct nf_conntrack_expect *exp)
{
struct nf_conn *master = exp->master;
- struct nf_conntrack_helper *helper;
long timeout = (exp->timeout.expires - jiffies) / HZ;
+ struct nf_conn_help *help;
if (timeout < 0)
timeout = 0;
@@ -1605,9 +1605,15 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
NLA_PUT_BE32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout));
NLA_PUT_BE32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp));
- helper = rcu_dereference(nfct_help(master)->helper);
- if (helper)
- NLA_PUT_STRING(skb, CTA_EXPECT_HELP_NAME, helper->name);
+ NLA_PUT_BE32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags));
+ help = nfct_help(master);
+ if (help) {
+ struct nf_conntrack_helper *helper;
+
+ helper = rcu_dereference(help->helper);
+ if (helper)
+ NLA_PUT_STRING(skb, CTA_EXPECT_HELP_NAME, helper->name);
+ }
return 0;
@@ -1654,17 +1660,20 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
struct nlmsghdr *nlh;
struct nfgenmsg *nfmsg;
struct sk_buff *skb;
- unsigned int type;
+ unsigned int type, group;
int flags = 0;
- if (events & (1 << IPEXP_NEW)) {
+ if (events & (1 << IPEXP_DESTROY)) {
+ type = IPCTNL_MSG_EXP_DELETE;
+ group = NFNLGRP_CONNTRACK_EXP_DESTROY;
+ } else if (events & (1 << IPEXP_NEW)) {
type = IPCTNL_MSG_EXP_NEW;
flags = NLM_F_CREATE|NLM_F_EXCL;
+ group = NFNLGRP_CONNTRACK_EXP_NEW;
} else
return 0;
- if (!item->report &&
- !nfnetlink_has_listeners(net, NFNLGRP_CONNTRACK_EXP_NEW))
+ if (!item->report && !nfnetlink_has_listeners(net, group))
return 0;
skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
@@ -1687,8 +1696,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
rcu_read_unlock();
nlmsg_end(skb, nlh);
- nfnetlink_send(skb, net, item->pid, NFNLGRP_CONNTRACK_EXP_NEW,
- item->report, GFP_ATOMIC);
+ nfnetlink_send(skb, net, item->pid, group, item->report, GFP_ATOMIC);
return 0;
nla_put_failure:
@@ -1761,6 +1769,8 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
[CTA_EXPECT_TIMEOUT] = { .type = NLA_U32 },
[CTA_EXPECT_ID] = { .type = NLA_U32 },
[CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING },
+ [CTA_EXPECT_ZONE] = { .type = NLA_U16 },
+ [CTA_EXPECT_FLAGS] = { .type = NLA_U32 },
};
static int
@@ -1869,7 +1879,13 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
}
/* after list removal, usage count == 1 */
- nf_ct_unexpect_related(exp);
+ spin_lock_bh(&nf_conntrack_lock);
+ if (del_timer(&exp->timeout)) {
+ nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).pid,
+ nlmsg_report(nlh));
+ nf_ct_expect_put(exp);
+ }
+ spin_unlock_bh(&nf_conntrack_lock);
/* have to put what we 'get' above.
* after this line usage count == 0 */
nf_ct_expect_put(exp);
@@ -1886,7 +1902,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
m_help = nfct_help(exp->master);
if (!strcmp(m_help->helper->name, name) &&
del_timer(&exp->timeout)) {
- nf_ct_unlink_expect(exp);
+ nf_ct_unlink_expect_report(exp,
+ NETLINK_CB(skb).pid,
+ nlmsg_report(nlh));
nf_ct_expect_put(exp);
}
}
@@ -1900,7 +1918,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
&net->ct.expect_hash[i],
hnode) {
if (del_timer(&exp->timeout)) {
- nf_ct_unlink_expect(exp);
+ nf_ct_unlink_expect_report(exp,
+ NETLINK_CB(skb).pid,
+ nlmsg_report(nlh));
nf_ct_expect_put(exp);
}
}
@@ -1946,23 +1966,35 @@ ctnetlink_create_expect(struct net *net, u16 zone,
if (!h)
return -ENOENT;
ct = nf_ct_tuplehash_to_ctrack(h);
- help = nfct_help(ct);
-
- if (!help || !help->helper) {
- /* such conntrack hasn't got any helper, abort */
- err = -EOPNOTSUPP;
- goto out;
- }
-
exp = nf_ct_expect_alloc(ct);
if (!exp) {
err = -ENOMEM;
goto out;
}
+ help = nfct_help(ct);
+ if (!help) {
+ if (!cda[CTA_EXPECT_TIMEOUT]) {
+ err = -EINVAL;
+ goto out;
+ }
+ exp->timeout.expires =
+ jiffies + ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ;
+
+ exp->flags = NF_CT_EXPECT_USERSPACE;
+ if (cda[CTA_EXPECT_FLAGS]) {
+ exp->flags |=
+ ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS]));
+ }
+ } else {
+ if (cda[CTA_EXPECT_FLAGS]) {
+ exp->flags = ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS]));
+ exp->flags &= ~NF_CT_EXPECT_USERSPACE;
+ } else
+ exp->flags = 0;
+ }
exp->class = 0;
exp->expectfn = NULL;
- exp->flags = 0;
exp->master = ct;
exp->helper = NULL;
memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
@@ -2130,6 +2162,7 @@ static void __exit ctnetlink_exit(void)
{
pr_info("ctnetlink: unregistering from nfnetlink.\n");
+ nf_ct_remove_userspace_expectations();
#ifdef CONFIG_NF_CONNTRACK_EVENTS
nf_ct_expect_unregister_notifier(&ctnl_notifier_exp);
nf_conntrack_unregister_notifier(&ctnl_notifier);
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index f64de9544866..bcf47eb518ef 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -130,6 +130,44 @@ static int digits_len(const struct nf_conn *ct, const char *dptr,
return len;
}
+static int iswordc(const char c)
+{
+ if (isalnum(c) || c == '!' || c == '"' || c == '%' ||
+ (c >= '(' && c <= '/') || c == ':' || c == '<' || c == '>' ||
+ c == '?' || (c >= '[' && c <= ']') || c == '_' || c == '`' ||
+ c == '{' || c == '}' || c == '~')
+ return 1;
+ return 0;
+}
+
+static int word_len(const char *dptr, const char *limit)
+{
+ int len = 0;
+ while (dptr < limit && iswordc(*dptr)) {
+ dptr++;
+ len++;
+ }
+ return len;
+}
+
+static int callid_len(const struct nf_conn *ct, const char *dptr,
+ const char *limit, int *shift)
+{
+ int len, domain_len;
+
+ len = word_len(dptr, limit);
+ dptr += len;
+ if (!len || dptr == limit || *dptr != '@')
+ return len;
+ dptr++;
+ len++;
+
+ domain_len = word_len(dptr, limit);
+ if (!domain_len)
+ return 0;
+ return len + domain_len;
+}
+
/* get media type + port length */
static int media_len(const struct nf_conn *ct, const char *dptr,
const char *limit, int *shift)
@@ -152,6 +190,9 @@ static int parse_addr(const struct nf_conn *ct, const char *cp,
const char *end;
int ret = 0;
+ if (!ct)
+ return 0;
+
memset(addr, 0, sizeof(*addr));
switch (nf_ct_l3num(ct)) {
case AF_INET:
@@ -296,6 +337,7 @@ static const struct sip_header ct_sip_hdrs[] = {
[SIP_HDR_VIA_TCP] = SIP_HDR("Via", "v", "TCP ", epaddr_len),
[SIP_HDR_EXPIRES] = SIP_HDR("Expires", NULL, NULL, digits_len),
[SIP_HDR_CONTENT_LENGTH] = SIP_HDR("Content-Length", "l", NULL, digits_len),
+ [SIP_HDR_CALL_ID] = SIP_HDR("Call-Id", "i", NULL, callid_len),
};
static const char *sip_follow_continuation(const char *dptr, const char *limit)
diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c
index daab8c4a903c..4d87befb04c0 100644
--- a/net/netfilter/nf_tproxy_core.c
+++ b/net/netfilter/nf_tproxy_core.c
@@ -18,41 +18,6 @@
#include <net/udp.h>
#include <net/netfilter/nf_tproxy_core.h>
-struct sock *
-nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
- const __be32 saddr, const __be32 daddr,
- const __be16 sport, const __be16 dport,
- const struct net_device *in, bool listening_only)
-{
- struct sock *sk;
-
- /* look up socket */
- switch (protocol) {
- case IPPROTO_TCP:
- if (listening_only)
- sk = __inet_lookup_listener(net, &tcp_hashinfo,
- daddr, ntohs(dport),
- in->ifindex);
- else
- sk = __inet_lookup(net, &tcp_hashinfo,
- saddr, sport, daddr, dport,
- in->ifindex);
- break;
- case IPPROTO_UDP:
- sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
- in->ifindex);
- break;
- default:
- WARN_ON(1);
- sk = NULL;
- }
-
- pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, listener only: %d, sock %p\n",
- protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), listening_only, sk);
-
- return sk;
-}
-EXPORT_SYMBOL_GPL(nf_tproxy_get_sock_v4);
static void
nf_tproxy_destructor(struct sk_buff *skb)
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index e34622fa0003..80463507420e 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -116,10 +116,8 @@ EXPORT_SYMBOL(xt_register_targets);
void
xt_unregister_targets(struct xt_target *target, unsigned int n)
{
- unsigned int i;
-
- for (i = 0; i < n; i++)
- xt_unregister_target(&target[i]);
+ while (n-- > 0)
+ xt_unregister_target(&target[n]);
}
EXPORT_SYMBOL(xt_unregister_targets);
@@ -174,10 +172,8 @@ EXPORT_SYMBOL(xt_register_matches);
void
xt_unregister_matches(struct xt_match *match, unsigned int n)
{
- unsigned int i;
-
- for (i = 0; i < n; i++)
- xt_unregister_match(&match[i]);
+ while (n-- > 0)
+ xt_unregister_match(&match[n]);
}
EXPORT_SYMBOL(xt_unregister_matches);
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
index c61294d85fda..19c482caf30b 100644
--- a/net/netfilter/xt_TPROXY.c
+++ b/net/netfilter/xt_TPROXY.c
@@ -1,7 +1,7 @@
/*
* Transparent proxy support for Linux/iptables
*
- * Copyright (c) 2006-2007 BalaBit IT Ltd.
+ * Copyright (c) 2006-2010 BalaBit IT Ltd.
* Author: Balazs Scheidler, Krisztian Kovacs
*
* This program is free software; you can redistribute it and/or modify
@@ -16,19 +16,96 @@
#include <net/checksum.h>
#include <net/udp.h>
#include <net/inet_sock.h>
-
+#include <linux/inetdevice.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter/xt_TPROXY.h>
#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#include <net/if_inet6.h>
+#include <net/addrconf.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
+#endif
+
#include <net/netfilter/nf_tproxy_core.h>
+#include <linux/netfilter/xt_TPROXY.h>
+
+static inline __be32
+tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr)
+{
+ struct in_device *indev;
+ __be32 laddr;
+
+ if (user_laddr)
+ return user_laddr;
+
+ laddr = 0;
+ rcu_read_lock();
+ indev = __in_dev_get_rcu(skb->dev);
+ for_primary_ifa(indev) {
+ laddr = ifa->ifa_local;
+ break;
+ } endfor_ifa(indev);
+ rcu_read_unlock();
+
+ return laddr ? laddr : daddr;
+}
+
+/**
+ * tproxy_handle_time_wait4() - handle IPv4 TCP TIME_WAIT reopen redirections
+ * @skb: The skb being processed.
+ * @laddr: IPv4 address to redirect to or zero.
+ * @lport: TCP port to redirect to or zero.
+ * @sk: The TIME_WAIT TCP socket found by the lookup.
+ *
+ * We have to handle SYN packets arriving to TIME_WAIT sockets
+ * differently: instead of reopening the connection we should rather
+ * redirect the new connection to the proxy if there's a listener
+ * socket present.
+ *
+ * tproxy_handle_time_wait4() consumes the socket reference passed in.
+ *
+ * Returns the listener socket if there's one, the TIME_WAIT socket if
+ * no such listener is found, or NULL if the TCP header is incomplete.
+ */
+static struct sock *
+tproxy_handle_time_wait4(struct sk_buff *skb, __be32 laddr, __be16 lport,
+ struct sock *sk)
+{
+ const struct iphdr *iph = ip_hdr(skb);
+ struct tcphdr _hdr, *hp;
+
+ hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
+ if (hp == NULL) {
+ inet_twsk_put(inet_twsk(sk));
+ return NULL;
+ }
+
+ if (hp->syn && !hp->rst && !hp->ack && !hp->fin) {
+ /* SYN to a TIME_WAIT socket, we'd rather redirect it
+ * to a listener socket if there's one */
+ struct sock *sk2;
+
+ sk2 = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
+ iph->saddr, laddr ? laddr : iph->daddr,
+ hp->source, lport ? lport : hp->dest,
+ skb->dev, NFT_LOOKUP_LISTENER);
+ if (sk2) {
+ inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
+ inet_twsk_put(inet_twsk(sk));
+ sk = sk2;
+ }
+ }
+
+ return sk;
+}
static unsigned int
-tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par)
+tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport,
+ u_int32_t mark_mask, u_int32_t mark_value)
{
const struct iphdr *iph = ip_hdr(skb);
- const struct xt_tproxy_target_info *tgi = par->targinfo;
struct udphdr _hdr, *hp;
struct sock *sk;
@@ -36,12 +113,195 @@ tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par)
if (hp == NULL)
return NF_DROP;
+ /* check if there's an ongoing connection on the packet
+ * addresses, this happens if the redirect already happened
+ * and the current packet belongs to an already established
+ * connection */
sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
- iph->saddr,
- tgi->laddr ? tgi->laddr : iph->daddr,
- hp->source,
- tgi->lport ? tgi->lport : hp->dest,
- par->in, true);
+ iph->saddr, iph->daddr,
+ hp->source, hp->dest,
+ skb->dev, NFT_LOOKUP_ESTABLISHED);
+
+ laddr = tproxy_laddr4(skb, laddr, iph->daddr);
+ if (!lport)
+ lport = hp->dest;
+
+ /* UDP has no TCP_TIME_WAIT state, so we never enter here */
+ if (sk && sk->sk_state == TCP_TIME_WAIT)
+ /* reopening a TIME_WAIT connection needs special handling */
+ sk = tproxy_handle_time_wait4(skb, laddr, lport, sk);
+ else if (!sk)
+ /* no, there's no established connection, check if
+ * there's a listener on the redirected addr/port */
+ sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
+ iph->saddr, laddr,
+ hp->source, lport,
+ skb->dev, NFT_LOOKUP_LISTENER);
+
+ /* NOTE: assign_sock consumes our sk reference */
+ if (sk && nf_tproxy_assign_sock(skb, sk)) {
+ /* This should be in a separate target, but we don't do multiple
+ targets on the same rule yet */
+ skb->mark = (skb->mark & ~mark_mask) ^ mark_value;
+
+ pr_debug("redirecting: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n",
+ iph->protocol, &iph->daddr, ntohs(hp->dest),
+ &laddr, ntohs(lport), skb->mark);
+ return NF_ACCEPT;
+ }
+
+ pr_debug("no socket, dropping: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n",
+ iph->protocol, &iph->saddr, ntohs(hp->source),
+ &iph->daddr, ntohs(hp->dest), skb->mark);
+ return NF_DROP;
+}
+
+static unsigned int
+tproxy_tg4_v0(struct sk_buff *skb, const struct xt_action_param *par)
+{
+ const struct xt_tproxy_target_info *tgi = par->targinfo;
+
+ return tproxy_tg4(skb, tgi->laddr, tgi->lport, tgi->mark_mask, tgi->mark_value);
+}
+
+static unsigned int
+tproxy_tg4_v1(struct sk_buff *skb, const struct xt_action_param *par)
+{
+ const struct xt_tproxy_target_info_v1 *tgi = par->targinfo;
+
+ return tproxy_tg4(skb, tgi->laddr.ip, tgi->lport, tgi->mark_mask, tgi->mark_value);
+}
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+
+static inline const struct in6_addr *
+tproxy_laddr6(struct sk_buff *skb, const struct in6_addr *user_laddr,
+ const struct in6_addr *daddr)
+{
+ struct inet6_dev *indev;
+ struct inet6_ifaddr *ifa;
+ struct in6_addr *laddr;
+
+ if (!ipv6_addr_any(user_laddr))
+ return user_laddr;
+ laddr = NULL;
+
+ rcu_read_lock();
+ indev = __in6_dev_get(skb->dev);
+ if (indev)
+ list_for_each_entry(ifa, &indev->addr_list, if_list) {
+ if (ifa->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
+ continue;
+
+ laddr = &ifa->addr;
+ break;
+ }
+ rcu_read_unlock();
+
+ return laddr ? laddr : daddr;
+}
+
+/**
+ * tproxy_handle_time_wait6() - handle IPv6 TCP TIME_WAIT reopen redirections
+ * @skb: The skb being processed.
+ * @tproto: Transport protocol.
+ * @thoff: Transport protocol header offset.
+ * @par: Iptables target parameters.
+ * @sk: The TIME_WAIT TCP socket found by the lookup.
+ *
+ * We have to handle SYN packets arriving to TIME_WAIT sockets
+ * differently: instead of reopening the connection we should rather
+ * redirect the new connection to the proxy if there's a listener
+ * socket present.
+ *
+ * tproxy_handle_time_wait6() consumes the socket reference passed in.
+ *
+ * Returns the listener socket if there's one, the TIME_WAIT socket if
+ * no such listener is found, or NULL if the TCP header is incomplete.
+ */
+static struct sock *
+tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff,
+ const struct xt_action_param *par,
+ struct sock *sk)
+{
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
+ struct tcphdr _hdr, *hp;
+ const struct xt_tproxy_target_info_v1 *tgi = par->targinfo;
+
+ hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr);
+ if (hp == NULL) {
+ inet_twsk_put(inet_twsk(sk));
+ return NULL;
+ }
+
+ if (hp->syn && !hp->rst && !hp->ack && !hp->fin) {
+ /* SYN to a TIME_WAIT socket, we'd rather redirect it
+ * to a listener socket if there's one */
+ struct sock *sk2;
+
+ sk2 = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto,
+ &iph->saddr,
+ tproxy_laddr6(skb, &tgi->laddr.in6, &iph->daddr),
+ hp->source,
+ tgi->lport ? tgi->lport : hp->dest,
+ skb->dev, NFT_LOOKUP_LISTENER);
+ if (sk2) {
+ inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
+ inet_twsk_put(inet_twsk(sk));
+ sk = sk2;
+ }
+ }
+
+ return sk;
+}
+
+static unsigned int
+tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par)
+{
+ const struct ipv6hdr *iph = ipv6_hdr(skb);
+ const struct xt_tproxy_target_info_v1 *tgi = par->targinfo;
+ struct udphdr _hdr, *hp;
+ struct sock *sk;
+ const struct in6_addr *laddr;
+ __be16 lport;
+ int thoff;
+ int tproto;
+
+ tproto = ipv6_find_hdr(skb, &thoff, -1, NULL);
+ if (tproto < 0) {
+ pr_debug("unable to find transport header in IPv6 packet, dropping\n");
+ return NF_DROP;
+ }
+
+ hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr);
+ if (hp == NULL) {
+ pr_debug("unable to grab transport header contents in IPv6 packet, dropping\n");
+ return NF_DROP;
+ }
+
+ /* check if there's an ongoing connection on the packet
+ * addresses, this happens if the redirect already happened
+ * and the current packet belongs to an already established
+ * connection */
+ sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto,
+ &iph->saddr, &iph->daddr,
+ hp->source, hp->dest,
+ par->in, NFT_LOOKUP_ESTABLISHED);
+
+ laddr = tproxy_laddr6(skb, &tgi->laddr.in6, &iph->daddr);
+ lport = tgi->lport ? tgi->lport : hp->dest;
+
+ /* UDP has no TCP_TIME_WAIT state, so we never enter here */
+ if (sk && sk->sk_state == TCP_TIME_WAIT)
+ /* reopening a TIME_WAIT connection needs special handling */
+ sk = tproxy_handle_time_wait6(skb, tproto, thoff, par, sk);
+ else if (!sk)
+ /* no there's no established connection, check if
+ * there's a listener on the redirected addr/port */
+ sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto,
+ &iph->saddr, laddr,
+ hp->source, lport,
+ par->in, NFT_LOOKUP_LISTENER);
/* NOTE: assign_sock consumes our sk reference */
if (sk && nf_tproxy_assign_sock(skb, sk)) {
@@ -49,19 +309,34 @@ tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par)
targets on the same rule yet */
skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value;
- pr_debug("redirecting: proto %u %08x:%u -> %08x:%u, mark: %x\n",
- iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
- ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
+ pr_debug("redirecting: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n",
+ tproto, &iph->saddr, ntohs(hp->source),
+ laddr, ntohs(lport), skb->mark);
return NF_ACCEPT;
}
- pr_debug("no socket, dropping: proto %u %08x:%u -> %08x:%u, mark: %x\n",
- iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
- ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
+ pr_debug("no socket, dropping: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n",
+ tproto, &iph->saddr, ntohs(hp->source),
+ &iph->daddr, ntohs(hp->dest), skb->mark);
+
return NF_DROP;
}
-static int tproxy_tg_check(const struct xt_tgchk_param *par)
+static int tproxy_tg6_check(const struct xt_tgchk_param *par)
+{
+ const struct ip6t_ip6 *i = par->entryinfo;
+
+ if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
+ && !(i->flags & IP6T_INV_PROTO))
+ return 0;
+
+ pr_info("Can be used only in combination with "
+ "either -p tcp or -p udp\n");
+ return -EINVAL;
+}
+#endif
+
+static int tproxy_tg4_check(const struct xt_tgchk_param *par)
{
const struct ipt_ip *i = par->entryinfo;
@@ -74,31 +349,64 @@ static int tproxy_tg_check(const struct xt_tgchk_param *par)
return -EINVAL;
}
-static struct xt_target tproxy_tg_reg __read_mostly = {
- .name = "TPROXY",
- .family = AF_INET,
- .table = "mangle",
- .target = tproxy_tg,
- .targetsize = sizeof(struct xt_tproxy_target_info),
- .checkentry = tproxy_tg_check,
- .hooks = 1 << NF_INET_PRE_ROUTING,
- .me = THIS_MODULE,
+static struct xt_target tproxy_tg_reg[] __read_mostly = {
+ {
+ .name = "TPROXY",
+ .family = NFPROTO_IPV4,
+ .table = "mangle",
+ .target = tproxy_tg4_v0,
+ .revision = 0,
+ .targetsize = sizeof(struct xt_tproxy_target_info),
+ .checkentry = tproxy_tg4_check,
+ .hooks = 1 << NF_INET_PRE_ROUTING,
+ .me = THIS_MODULE,
+ },
+ {
+ .name = "TPROXY",
+ .family = NFPROTO_IPV4,
+ .table = "mangle",
+ .target = tproxy_tg4_v1,
+ .revision = 1,
+ .targetsize = sizeof(struct xt_tproxy_target_info_v1),
+ .checkentry = tproxy_tg4_check,
+ .hooks = 1 << NF_INET_PRE_ROUTING,
+ .me = THIS_MODULE,
+ },
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ {
+ .name = "TPROXY",
+ .family = NFPROTO_IPV6,
+ .table = "mangle",
+ .target = tproxy_tg6_v1,
+ .revision = 1,
+ .targetsize = sizeof(struct xt_tproxy_target_info_v1),
+ .checkentry = tproxy_tg6_check,
+ .hooks = 1 << NF_INET_PRE_ROUTING,
+ .me = THIS_MODULE,
+ },
+#endif
+
};
static int __init tproxy_tg_init(void)
{
nf_defrag_ipv4_enable();
- return xt_register_target(&tproxy_tg_reg);
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ nf_defrag_ipv6_enable();
+#endif
+
+ return xt_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg));
}
static void __exit tproxy_tg_exit(void)
{
- xt_unregister_target(&tproxy_tg_reg);
+ xt_unregister_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg));
}
module_init(tproxy_tg_init);
module_exit(tproxy_tg_exit);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Krisztian Kovacs");
+MODULE_AUTHOR("Balazs Scheidler, Krisztian Kovacs");
MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module.");
MODULE_ALIAS("ipt_TPROXY");
+MODULE_ALIAS("ip6t_TPROXY");
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index b46a8390896d..9228ee0dc11a 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -448,6 +448,7 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
{
__be16 _ports[2], *ports;
u8 nexthdr;
+ int poff;
memset(dst, 0, sizeof(*dst));
@@ -492,19 +493,13 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
return 0;
}
- switch (nexthdr) {
- case IPPROTO_TCP:
- case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
- case IPPROTO_SCTP:
- case IPPROTO_DCCP:
- ports = skb_header_pointer(skb, protoff, sizeof(_ports),
+ poff = proto_ports_offset(nexthdr);
+ if (poff >= 0) {
+ ports = skb_header_pointer(skb, protoff + poff, sizeof(_ports),
&_ports);
- break;
- default:
+ } else {
_ports[0] = _ports[1] = 0;
ports = _ports;
- break;
}
if (!ports)
return -1;
diff --git a/net/netfilter/xt_ipvs.c b/net/netfilter/xt_ipvs.c
index 7a4d66db95ae..9127a3d8aa35 100644
--- a/net/netfilter/xt_ipvs.c
+++ b/net/netfilter/xt_ipvs.c
@@ -16,7 +16,6 @@
#include <linux/ip_vs.h>
#include <linux/types.h>
#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_ipvs.h>
#include <net/netfilter/nf_conntrack.h>
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
index 1ca89908cbad..2dbd4c857735 100644
--- a/net/netfilter/xt_socket.c
+++ b/net/netfilter/xt_socket.c
@@ -14,6 +14,7 @@
#include <linux/skbuff.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <net/icmp.h>
@@ -21,6 +22,7 @@
#include <net/inet_sock.h>
#include <net/netfilter/nf_tproxy_core.h>
#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
#include <linux/netfilter/xt_socket.h>
@@ -30,7 +32,7 @@
#endif
static int
-extract_icmp_fields(const struct sk_buff *skb,
+extract_icmp4_fields(const struct sk_buff *skb,
u8 *protocol,
__be32 *raddr,
__be32 *laddr,
@@ -86,7 +88,6 @@ extract_icmp_fields(const struct sk_buff *skb,
return 0;
}
-
static bool
socket_match(const struct sk_buff *skb, struct xt_action_param *par,
const struct xt_socket_mtinfo1 *info)
@@ -115,7 +116,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
dport = hp->dest;
} else if (iph->protocol == IPPROTO_ICMP) {
- if (extract_icmp_fields(skb, &protocol, &saddr, &daddr,
+ if (extract_icmp4_fields(skb, &protocol, &saddr, &daddr,
&sport, &dport))
return false;
} else {
@@ -142,7 +143,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
#endif
sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol,
- saddr, daddr, sport, dport, par->in, false);
+ saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY);
if (sk != NULL) {
bool wildcard;
bool transparent = true;
@@ -165,32 +166,157 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
sk = NULL;
}
- pr_debug("proto %u %08x:%u -> %08x:%u (orig %08x:%u) sock %p\n",
- protocol, ntohl(saddr), ntohs(sport),
- ntohl(daddr), ntohs(dport),
- ntohl(iph->daddr), hp ? ntohs(hp->dest) : 0, sk);
+ pr_debug("proto %hhu %pI4:%hu -> %pI4:%hu (orig %pI4:%hu) sock %p\n",
+ protocol, &saddr, ntohs(sport),
+ &daddr, ntohs(dport),
+ &iph->daddr, hp ? ntohs(hp->dest) : 0, sk);
return (sk != NULL);
}
static bool
-socket_mt_v0(const struct sk_buff *skb, struct xt_action_param *par)
+socket_mt4_v0(const struct sk_buff *skb, struct xt_action_param *par)
{
return socket_match(skb, par, NULL);
}
static bool
-socket_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
+socket_mt4_v1(const struct sk_buff *skb, struct xt_action_param *par)
{
return socket_match(skb, par, par->matchinfo);
}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+
+static int
+extract_icmp6_fields(const struct sk_buff *skb,
+ unsigned int outside_hdrlen,
+ u8 *protocol,
+ struct in6_addr **raddr,
+ struct in6_addr **laddr,
+ __be16 *rport,
+ __be16 *lport)
+{
+ struct ipv6hdr *inside_iph, _inside_iph;
+ struct icmp6hdr *icmph, _icmph;
+ __be16 *ports, _ports[2];
+ u8 inside_nexthdr;
+ int inside_hdrlen;
+
+ icmph = skb_header_pointer(skb, outside_hdrlen,
+ sizeof(_icmph), &_icmph);
+ if (icmph == NULL)
+ return 1;
+
+ if (icmph->icmp6_type & ICMPV6_INFOMSG_MASK)
+ return 1;
+
+ inside_iph = skb_header_pointer(skb, outside_hdrlen + sizeof(_icmph), sizeof(_inside_iph), &_inside_iph);
+ if (inside_iph == NULL)
+ return 1;
+ inside_nexthdr = inside_iph->nexthdr;
+
+ inside_hdrlen = ipv6_skip_exthdr(skb, outside_hdrlen + sizeof(_icmph) + sizeof(_inside_iph), &inside_nexthdr);
+ if (inside_hdrlen < 0)
+ return 1; /* hjm: Packet has no/incomplete transport layer headers. */
+
+ if (inside_nexthdr != IPPROTO_TCP &&
+ inside_nexthdr != IPPROTO_UDP)
+ return 1;
+
+ ports = skb_header_pointer(skb, inside_hdrlen,
+ sizeof(_ports), &_ports);
+ if (ports == NULL)
+ return 1;
+
+ /* the inside IP packet is the one quoted from our side, thus
+ * its saddr is the local address */
+ *protocol = inside_nexthdr;
+ *laddr = &inside_iph->saddr;
+ *lport = ports[0];
+ *raddr = &inside_iph->daddr;
+ *rport = ports[1];
+
+ return 0;
+}
+
+static bool
+socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
+{
+ struct ipv6hdr *iph = ipv6_hdr(skb);
+ struct udphdr _hdr, *hp = NULL;
+ struct sock *sk;
+ struct in6_addr *daddr, *saddr;
+ __be16 dport, sport;
+ int thoff;
+ u8 tproto;
+ const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
+
+ tproto = ipv6_find_hdr(skb, &thoff, -1, NULL);
+ if (tproto < 0) {
+ pr_debug("unable to find transport header in IPv6 packet, dropping\n");
+ return NF_DROP;
+ }
+
+ if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) {
+ hp = skb_header_pointer(skb, thoff,
+ sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return false;
+
+ saddr = &iph->saddr;
+ sport = hp->source;
+ daddr = &iph->daddr;
+ dport = hp->dest;
+
+ } else if (tproto == IPPROTO_ICMPV6) {
+ if (extract_icmp6_fields(skb, thoff, &tproto, &saddr, &daddr,
+ &sport, &dport))
+ return false;
+ } else {
+ return false;
+ }
+
+ sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto,
+ saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY);
+ if (sk != NULL) {
+ bool wildcard;
+ bool transparent = true;
+
+ /* Ignore sockets listening on INADDR_ANY */
+ wildcard = (sk->sk_state != TCP_TIME_WAIT &&
+ ipv6_addr_any(&inet6_sk(sk)->rcv_saddr));
+
+ /* Ignore non-transparent sockets,
+ if XT_SOCKET_TRANSPARENT is used */
+ if (info && info->flags & XT_SOCKET_TRANSPARENT)
+ transparent = ((sk->sk_state != TCP_TIME_WAIT &&
+ inet_sk(sk)->transparent) ||
+ (sk->sk_state == TCP_TIME_WAIT &&
+ inet_twsk(sk)->tw_transparent));
+
+ nf_tproxy_put_sock(sk);
+
+ if (wildcard || !transparent)
+ sk = NULL;
+ }
+
+ pr_debug("proto %hhu %pI6:%hu -> %pI6:%hu "
+ "(orig %pI6:%hu) sock %p\n",
+ tproto, saddr, ntohs(sport),
+ daddr, ntohs(dport),
+ &iph->daddr, hp ? ntohs(hp->dest) : 0, sk);
+
+ return (sk != NULL);
+}
+#endif
+
static struct xt_match socket_mt_reg[] __read_mostly = {
{
.name = "socket",
.revision = 0,
.family = NFPROTO_IPV4,
- .match = socket_mt_v0,
+ .match = socket_mt4_v0,
.hooks = (1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_LOCAL_IN),
.me = THIS_MODULE,
@@ -199,17 +325,33 @@ static struct xt_match socket_mt_reg[] __read_mostly = {
.name = "socket",
.revision = 1,
.family = NFPROTO_IPV4,
- .match = socket_mt_v1,
+ .match = socket_mt4_v1,
.matchsize = sizeof(struct xt_socket_mtinfo1),
.hooks = (1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_LOCAL_IN),
.me = THIS_MODULE,
},
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ {
+ .name = "socket",
+ .revision = 1,
+ .family = NFPROTO_IPV6,
+ .match = socket_mt6_v1,
+ .matchsize = sizeof(struct xt_socket_mtinfo1),
+ .hooks = (1 << NF_INET_PRE_ROUTING) |
+ (1 << NF_INET_LOCAL_IN),
+ .me = THIS_MODULE,
+ },
+#endif
};
static int __init socket_mt_init(void)
{
nf_defrag_ipv4_enable();
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ nf_defrag_ipv6_enable();
+#endif
+
return xt_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg));
}
@@ -225,3 +367,4 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Krisztian Kovacs, Balazs Scheidler");
MODULE_DESCRIPTION("x_tables socket match module");
MODULE_ALIAS("ipt_socket");
+MODULE_ALIAS("ip6t_socket");
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 26ed3e8587c2..1781d99145e2 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -547,8 +547,20 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
info.attrs = family->attrbuf;
genl_info_net_set(&info, net);
+ memset(&info.user_ptr, 0, sizeof(info.user_ptr));
- return ops->doit(skb, &info);
+ if (family->pre_doit) {
+ err = family->pre_doit(ops, skb, &info);
+ if (err)
+ return err;
+ }
+
+ err = ops->doit(skb, &info);
+
+ if (family->post_doit)
+ family->post_doit(ops, skb, &info);
+
+ return err;
}
static void genl_rcv(struct sk_buff *skb)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 9a17f28b1253..3616f27b9d46 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -488,7 +488,7 @@ retry:
skb->dev = dev;
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
- err = sock_tx_timestamp(msg, sk, skb_tx(skb));
+ err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
if (err < 0)
goto out_unlock;
@@ -1209,7 +1209,7 @@ static int packet_snd(struct socket *sock,
err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len);
if (err)
goto out_free;
- err = sock_tx_timestamp(msg, sk, skb_tx(skb));
+ err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
if (err < 0)
goto out_free;
diff --git a/net/phonet/Kconfig b/net/phonet/Kconfig
index 6ec7d55b1769..0d9b8a220a78 100644
--- a/net/phonet/Kconfig
+++ b/net/phonet/Kconfig
@@ -14,3 +14,15 @@ config PHONET
To compile this driver as a module, choose M here: the module
will be called phonet. If unsure, say N.
+
+config PHONET_PIPECTRLR
+ bool "Phonet Pipe Controller (EXPERIMENTAL)"
+ depends on PHONET && EXPERIMENTAL
+ default N
+ help
+ The Pipe Controller implementation in Phonet stack to support Pipe
+ data with Nokia Slim modems like WG2.5 used on ST-Ericsson U8500
+ platform.
+
+ This option is incompatible with older Nokia modems.
+ Say N here unless you really know what you are doing.
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index 73aee7f2fcdc..fd95beb72f5d 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -251,6 +251,16 @@ int pn_skb_send(struct sock *sk, struct sk_buff *skb,
else if (phonet_address_lookup(net, daddr) == 0) {
dev = phonet_device_get(net);
skb->pkt_type = PACKET_LOOPBACK;
+ } else if (pn_sockaddr_get_object(target) == 0) {
+ /* Resource routing (small race until phonet_rcv()) */
+ struct sock *sk = pn_find_sock_by_res(net,
+ target->spn_resource);
+ if (sk) {
+ sock_put(sk);
+ dev = phonet_device_get(net);
+ skb->pkt_type = PACKET_LOOPBACK;
+ } else
+ dev = phonet_route_output(net, daddr);
} else
dev = phonet_route_output(net, daddr);
@@ -383,6 +393,13 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
goto out;
}
+ /* resource routing */
+ if (pn_sockaddr_get_object(&sa) == 0) {
+ struct sock *sk = pn_find_sock_by_res(net, sa.spn_resource);
+ if (sk)
+ return sk_receive_skb(sk, skb, 0);
+ }
+
/* check if we are the destination */
if (phonet_address_lookup(net, pn_sockaddr_get_addr(&sa)) == 0) {
/* Phonet packet input */
diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
index 1bd38db4fe1e..2f032381bd45 100644
--- a/net/phonet/datagram.c
+++ b/net/phonet/datagram.c
@@ -52,6 +52,19 @@ static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg)
answ = skb ? skb->len : 0;
release_sock(sk);
return put_user(answ, (int __user *)arg);
+
+ case SIOCPNADDRESOURCE:
+ case SIOCPNDELRESOURCE: {
+ u32 res;
+ if (get_user(res, (u32 __user *)arg))
+ return -EFAULT;
+ if (res >= 256)
+ return -EINVAL;
+ if (cmd == SIOCPNADDRESOURCE)
+ return pn_sock_bind_res(sk, res);
+ else
+ return pn_sock_unbind_res(sk, res);
+ }
}
return -ENOIOCTLCMD;
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index 15003021f4f0..3e60f2e4e6c2 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -109,6 +109,210 @@ static int pep_reply(struct sock *sk, struct sk_buff *oskb,
}
#define PAD 0x00
+
+#ifdef CONFIG_PHONET_PIPECTRLR
+static u8 pipe_negotiate_fc(u8 *host_fc, u8 *remote_fc, int len)
+{
+ int i, j;
+ u8 base_fc, final_fc;
+
+ for (i = 0; i < len; i++) {
+ base_fc = host_fc[i];
+ for (j = 0; j < len; j++) {
+ if (remote_fc[j] == base_fc) {
+ final_fc = base_fc;
+ goto done;
+ }
+ }
+ }
+ return -EINVAL;
+
+done:
+ return final_fc;
+
+}
+
+static int pipe_get_flow_info(struct sock *sk, struct sk_buff *skb,
+ u8 *pref_rx_fc, u8 *req_tx_fc)
+{
+ struct pnpipehdr *hdr;
+ u8 n_sb;
+
+ if (!pskb_may_pull(skb, sizeof(*hdr) + 4))
+ return -EINVAL;
+
+ hdr = pnp_hdr(skb);
+ n_sb = hdr->data[4];
+
+ __skb_pull(skb, sizeof(*hdr) + 4);
+ while (n_sb > 0) {
+ u8 type, buf[3], len = sizeof(buf);
+ u8 *data = pep_get_sb(skb, &type, &len, buf);
+
+ if (data == NULL)
+ return -EINVAL;
+
+ switch (type) {
+ case PN_PIPE_SB_REQUIRED_FC_TX:
+ if (len < 3 || (data[2] | data[3] | data[4]) > 3)
+ break;
+ req_tx_fc[0] = data[2];
+ req_tx_fc[1] = data[3];
+ req_tx_fc[2] = data[4];
+ break;
+
+ case PN_PIPE_SB_PREFERRED_FC_RX:
+ if (len < 3 || (data[2] | data[3] | data[4]) > 3)
+ break;
+ pref_rx_fc[0] = data[2];
+ pref_rx_fc[1] = data[3];
+ pref_rx_fc[2] = data[4];
+ break;
+
+ }
+ n_sb--;
+ }
+ return 0;
+}
+
+static int pipe_handler_send_req(struct sock *sk, u8 utid,
+ u8 msg_id, gfp_t priority)
+{
+ int len;
+ struct pnpipehdr *ph;
+ struct sk_buff *skb;
+ struct pep_sock *pn = pep_sk(sk);
+
+ static const u8 data[4] = {
+ PAD, PAD, PAD, PAD,
+ };
+
+ switch (msg_id) {
+ case PNS_PEP_CONNECT_REQ:
+ len = sizeof(data);
+ break;
+
+ case PNS_PEP_DISCONNECT_REQ:
+ case PNS_PEP_ENABLE_REQ:
+ case PNS_PEP_DISABLE_REQ:
+ len = 0;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority);
+ if (!skb)
+ return -ENOMEM;
+ skb_set_owner_w(skb, sk);
+
+ skb_reserve(skb, MAX_PNPIPE_HEADER);
+ if (len) {
+ __skb_put(skb, len);
+ skb_copy_to_linear_data(skb, data, len);
+ }
+ __skb_push(skb, sizeof(*ph));
+ skb_reset_transport_header(skb);
+ ph = pnp_hdr(skb);
+ ph->utid = utid;
+ ph->message_id = msg_id;
+ ph->pipe_handle = pn->pipe_handle;
+ ph->error_code = PN_PIPE_NO_ERROR;
+
+ return pn_skb_send(sk, skb, &pn->remote_pep);
+}
+
+static int pipe_handler_send_created_ind(struct sock *sk,
+ u8 utid, u8 msg_id)
+{
+ int err_code;
+ struct pnpipehdr *ph;
+ struct sk_buff *skb;
+
+ struct pep_sock *pn = pep_sk(sk);
+ static u8 data[4] = {
+ 0x03, 0x04,
+ };
+ data[2] = pn->tx_fc;
+ data[3] = pn->rx_fc;
+
+ /*
+ * actually, below is number of sub-blocks and not error code.
+ * Pipe_created_ind message format does not have any
+ * error code field. However, the Phonet stack will always send
+ * an error code as part of pnpipehdr. So, use that err_code to
+ * specify the number of sub-blocks.
+ */
+ err_code = 0x01;
+
+ skb = alloc_skb(MAX_PNPIPE_HEADER + sizeof(data), GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+ skb_set_owner_w(skb, sk);
+
+ skb_reserve(skb, MAX_PNPIPE_HEADER);
+ __skb_put(skb, sizeof(data));
+ skb_copy_to_linear_data(skb, data, sizeof(data));
+ __skb_push(skb, sizeof(*ph));
+ skb_reset_transport_header(skb);
+ ph = pnp_hdr(skb);
+ ph->utid = utid;
+ ph->message_id = msg_id;
+ ph->pipe_handle = pn->pipe_handle;
+ ph->error_code = err_code;
+
+ return pn_skb_send(sk, skb, &pn->remote_pep);
+}
+
+static int pipe_handler_send_ind(struct sock *sk, u8 utid, u8 msg_id)
+{
+ int err_code;
+ struct pnpipehdr *ph;
+ struct sk_buff *skb;
+ struct pep_sock *pn = pep_sk(sk);
+
+ /*
+ * actually, below is a filler.
+ * Pipe_enabled/disabled_ind message format does not have any
+ * error code field. However, the Phonet stack will always send
+ * an error code as part of pnpipehdr. So, use that err_code to
+ * specify the filler value.
+ */
+ err_code = 0x0;
+
+ skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+ skb_set_owner_w(skb, sk);
+
+ skb_reserve(skb, MAX_PNPIPE_HEADER);
+ __skb_push(skb, sizeof(*ph));
+ skb_reset_transport_header(skb);
+ ph = pnp_hdr(skb);
+ ph->utid = utid;
+ ph->message_id = msg_id;
+ ph->pipe_handle = pn->pipe_handle;
+ ph->error_code = err_code;
+
+ return pn_skb_send(sk, skb, &pn->remote_pep);
+}
+
+static int pipe_handler_enable_pipe(struct sock *sk, int enable)
+{
+ int utid, req;
+
+ if (enable) {
+ utid = PNS_PIPE_ENABLE_UTID;
+ req = PNS_PEP_ENABLE_REQ;
+ } else {
+ utid = PNS_PIPE_DISABLE_UTID;
+ req = PNS_PEP_DISABLE_REQ;
+ }
+ return pipe_handler_send_req(sk, utid, req, GFP_ATOMIC);
+}
+#endif
+
static int pep_accept_conn(struct sock *sk, struct sk_buff *skb)
{
static const u8 data[20] = {
@@ -192,7 +396,11 @@ static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority)
ph->data[3] = PAD;
ph->data[4] = status;
+#ifdef CONFIG_PHONET_PIPECTRLR
+ return pn_skb_send(sk, skb, &pn->remote_pep);
+#else
return pn_skb_send(sk, skb, &pipe_srv);
+#endif
}
/* Send our RX flow control information to the sender.
@@ -324,11 +532,35 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb)
sk->sk_state_change(sk);
break;
+#ifdef CONFIG_PHONET_PIPECTRLR
+ case PNS_PEP_DISCONNECT_RESP:
+ pn->pipe_state = PIPE_IDLE;
+ sk->sk_state = TCP_CLOSE;
+ break;
+#endif
+
case PNS_PEP_ENABLE_REQ:
/* Wait for PNS_PIPE_(ENABLED|REDIRECTED)_IND */
pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
break;
+#ifdef CONFIG_PHONET_PIPECTRLR
+ case PNS_PEP_ENABLE_RESP:
+ pn->pipe_state = PIPE_ENABLED;
+ pipe_handler_send_ind(sk, PNS_PIPE_ENABLED_IND_UTID,
+ PNS_PIPE_ENABLED_IND);
+
+ if (!pn_flow_safe(pn->tx_fc)) {
+ atomic_set(&pn->tx_credits, 1);
+ sk->sk_write_space(sk);
+ }
+ if (sk->sk_state == TCP_ESTABLISHED)
+ break; /* Nothing to do */
+ sk->sk_state = TCP_ESTABLISHED;
+ pipe_grant_credits(sk);
+ break;
+#endif
+
case PNS_PEP_RESET_REQ:
switch (hdr->state_after_reset) {
case PN_PIPE_DISABLE:
@@ -347,6 +579,17 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb)
pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
break;
+#ifdef CONFIG_PHONET_PIPECTRLR
+ case PNS_PEP_DISABLE_RESP:
+ pn->pipe_state = PIPE_DISABLED;
+ atomic_set(&pn->tx_credits, 0);
+ pipe_handler_send_ind(sk, PNS_PIPE_DISABLED_IND_UTID,
+ PNS_PIPE_DISABLED_IND);
+ sk->sk_state = TCP_SYN_RECV;
+ pn->rx_credits = 0;
+ break;
+#endif
+
case PNS_PEP_CTRL_REQ:
if (skb_queue_len(&pn->ctrlreq_queue) >= PNPIPE_CTRLREQ_MAX) {
atomic_inc(&sk->sk_drops);
@@ -438,6 +681,42 @@ static void pipe_destruct(struct sock *sk)
skb_queue_purge(&pn->ctrlreq_queue);
}
+#ifdef CONFIG_PHONET_PIPECTRLR
+static int pep_connresp_rcv(struct sock *sk, struct sk_buff *skb)
+{
+ struct pep_sock *pn = pep_sk(sk);
+ u8 host_pref_rx_fc[3] = {3, 2, 1}, host_req_tx_fc[3] = {3, 2, 1};
+ u8 remote_pref_rx_fc[3], remote_req_tx_fc[3];
+ u8 negotiated_rx_fc, negotiated_tx_fc;
+ int ret;
+
+ pipe_get_flow_info(sk, skb, remote_pref_rx_fc,
+ remote_req_tx_fc);
+ negotiated_tx_fc = pipe_negotiate_fc(remote_req_tx_fc,
+ host_pref_rx_fc,
+ sizeof(host_pref_rx_fc));
+ negotiated_rx_fc = pipe_negotiate_fc(host_req_tx_fc,
+ remote_pref_rx_fc,
+ sizeof(host_pref_rx_fc));
+
+ pn->pipe_state = PIPE_DISABLED;
+ sk->sk_state = TCP_SYN_RECV;
+ sk->sk_backlog_rcv = pipe_do_rcv;
+ sk->sk_destruct = pipe_destruct;
+ pn->rx_credits = 0;
+ pn->rx_fc = negotiated_rx_fc;
+ pn->tx_fc = negotiated_tx_fc;
+ sk->sk_state_change(sk);
+
+ ret = pipe_handler_send_created_ind(sk,
+ PNS_PIPE_CREATED_IND_UTID,
+ PNS_PIPE_CREATED_IND
+ );
+
+ return ret;
+}
+#endif
+
static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb)
{
struct sock *newsk;
@@ -601,6 +880,12 @@ static int pep_do_rcv(struct sock *sk, struct sk_buff *skb)
err = pep_connreq_rcv(sk, skb);
break;
+#ifdef CONFIG_PHONET_PIPECTRLR
+ case PNS_PEP_CONNECT_RESP:
+ err = pep_connresp_rcv(sk, skb);
+ break;
+#endif
+
case PNS_PEP_DISCONNECT_REQ:
pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
break;
@@ -621,6 +906,28 @@ drop:
return err;
}
+static int pipe_do_remove(struct sock *sk)
+{
+ struct pep_sock *pn = pep_sk(sk);
+ struct pnpipehdr *ph;
+ struct sk_buff *skb;
+
+ skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_reserve(skb, MAX_PNPIPE_HEADER);
+ __skb_push(skb, sizeof(*ph));
+ skb_reset_transport_header(skb);
+ ph = pnp_hdr(skb);
+ ph->utid = 0;
+ ph->message_id = PNS_PIPE_REMOVE_REQ;
+ ph->pipe_handle = pn->pipe_handle;
+ ph->data[0] = PAD;
+
+ return pn_skb_send(sk, skb, &pipe_srv);
+}
+
/* associated socket ceases to exist */
static void pep_sock_close(struct sock *sk, long timeout)
{
@@ -639,7 +946,22 @@ static void pep_sock_close(struct sock *sk, long timeout)
sk_for_each_safe(sknode, p, n, &pn->ackq)
sk_del_node_init(sknode);
sk->sk_state = TCP_CLOSE;
+ } else if ((1 << sk->sk_state) & (TCPF_SYN_RECV|TCPF_ESTABLISHED))
+ /* Forcefully remove dangling Phonet pipe */
+ pipe_do_remove(sk);
+
+#ifdef CONFIG_PHONET_PIPECTRLR
+ if (pn->pipe_state != PIPE_IDLE) {
+ /* send pep disconnect request */
+ pipe_handler_send_req(sk,
+ PNS_PEP_DISCONNECT_UTID, PNS_PEP_DISCONNECT_REQ,
+ GFP_KERNEL);
+
+ pn->pipe_state = PIPE_IDLE;
+ sk->sk_state = TCP_CLOSE;
}
+#endif
+
ifindex = pn->ifindex;
pn->ifindex = 0;
release_sock(sk);
@@ -716,6 +1038,20 @@ out:
return newsk;
}
+#ifdef CONFIG_PHONET_PIPECTRLR
+static int pep_sock_connect(struct sock *sk, struct sockaddr *addr, int len)
+{
+ struct pep_sock *pn = pep_sk(sk);
+ struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
+
+ memcpy(&pn->remote_pep, spn, sizeof(struct sockaddr_pn));
+
+ return pipe_handler_send_req(sk,
+ PNS_PEP_CONNECT_UTID, PNS_PEP_CONNECT_REQ,
+ GFP_ATOMIC);
+}
+#endif
+
static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
struct pep_sock *pn = pep_sk(sk);
@@ -767,6 +1103,18 @@ static int pep_setsockopt(struct sock *sk, int level, int optname,
lock_sock(sk);
switch (optname) {
+#ifdef CONFIG_PHONET_PIPECTRLR
+ case PNPIPE_PIPE_HANDLE:
+ if (val) {
+ if (pn->pipe_state > PIPE_IDLE) {
+ err = -EFAULT;
+ break;
+ }
+ pn->pipe_handle = val;
+ break;
+ }
+#endif
+
case PNPIPE_ENCAP:
if (val && val != PNPIPE_ENCAP_IP) {
err = -EINVAL;
@@ -792,6 +1140,17 @@ static int pep_setsockopt(struct sock *sk, int level, int optname,
err = 0;
}
goto out_norel;
+
+#ifdef CONFIG_PHONET_PIPECTRLR
+ case PNPIPE_ENABLE:
+ if (pn->pipe_state <= PIPE_IDLE) {
+ err = -ENOTCONN;
+ break;
+ }
+ err = pipe_handler_enable_pipe(sk, val);
+ break;
+#endif
+
default:
err = -ENOPROTOOPT;
}
@@ -816,9 +1175,19 @@ static int pep_getsockopt(struct sock *sk, int level, int optname,
case PNPIPE_ENCAP:
val = pn->ifindex ? PNPIPE_ENCAP_IP : PNPIPE_ENCAP_NONE;
break;
+
case PNPIPE_IFINDEX:
val = pn->ifindex;
break;
+
+#ifdef CONFIG_PHONET_PIPECTRLR
+ case PNPIPE_ENABLE:
+ if (pn->pipe_state <= PIPE_IDLE)
+ return -ENOTCONN;
+ val = pn->pipe_state != PIPE_DISABLED;
+ break;
+#endif
+
default:
return -ENOPROTOOPT;
}
@@ -835,6 +1204,7 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb)
{
struct pep_sock *pn = pep_sk(sk);
struct pnpipehdr *ph;
+ int err;
if (pn_flow_safe(pn->tx_fc) &&
!atomic_add_unless(&pn->tx_credits, -1, 0)) {
@@ -852,8 +1222,16 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb)
} else
ph->message_id = PNS_PIPE_DATA;
ph->pipe_handle = pn->pipe_handle;
+#ifdef CONFIG_PHONET_PIPECTRLR
+ err = pn_skb_send(sk, skb, &pn->remote_pep);
+#else
+ err = pn_skb_send(sk, skb, &pipe_srv);
+#endif
+
+ if (err && pn_flow_safe(pn->tx_fc))
+ atomic_inc(&pn->tx_credits);
+ return err;
- return pn_skb_send(sk, skb, &pipe_srv);
}
static int pep_sendmsg(struct kiocb *iocb, struct sock *sk,
@@ -873,7 +1251,7 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk,
skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len,
flags & MSG_DONTWAIT, &err);
if (!skb)
- return -ENOBUFS;
+ return err;
skb_reserve(skb, MAX_PHONET_HEADER + 3);
err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
@@ -1045,6 +1423,8 @@ static void pep_sock_unhash(struct sock *sk)
struct sock *skparent = NULL;
lock_sock(sk);
+
+#ifndef CONFIG_PHONET_PIPECTRLR
if ((1 << sk->sk_state) & ~(TCPF_CLOSE|TCPF_LISTEN)) {
skparent = pn->listener;
release_sock(sk);
@@ -1054,6 +1434,7 @@ static void pep_sock_unhash(struct sock *sk)
sk_del_node_init(sk);
sk = skparent;
}
+#endif
/* Unhash a listening sock only when it is closed
* and all of its active connected pipes are closed. */
if (hlist_empty(&pn->hlist))
@@ -1067,6 +1448,9 @@ static void pep_sock_unhash(struct sock *sk)
static struct proto pep_proto = {
.close = pep_sock_close,
.accept = pep_sock_accept,
+#ifdef CONFIG_PHONET_PIPECTRLR
+ .connect = pep_sock_connect,
+#endif
.ioctl = pep_ioctl,
.init = pep_init,
.setsockopt = pep_setsockopt,
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index b18e48fae975..947038ddd04c 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -292,8 +292,7 @@ static void phonet_route_autodel(struct net_device *dev)
if (bitmap_empty(deleted, 64))
return; /* short-circuit RCU */
synchronize_rcu();
- for (i = find_first_bit(deleted, 64); i < 64;
- i = find_next_bit(deleted, 64, i + 1)) {
+ for_each_set_bit(i, deleted, 64) {
rtm_phonet_notify(RTM_DELROUTE, dev, i);
dev_put(dev);
}
@@ -374,6 +373,7 @@ int __init phonet_device_init(void)
if (err)
return err;
+ proc_net_fops_create(&init_net, "pnresource", 0, &pn_res_seq_fops);
register_netdevice_notifier(&phonet_device_notifier);
err = phonet_netlink_register();
if (err)
@@ -386,6 +386,7 @@ void phonet_device_exit(void)
rtnl_unregister_all(PF_PHONET);
unregister_netdevice_notifier(&phonet_device_notifier);
unregister_pernet_device(&phonet_net_ops);
+ proc_net_remove(&init_net, "pnresource");
}
int phonet_route_add(struct net_device *dev, u8 daddr)
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 6e9848bf0370..25f746d20c1f 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -158,6 +158,7 @@ void pn_sock_unhash(struct sock *sk)
spin_lock_bh(&pnsocks.lock);
sk_del_node_init(sk);
spin_unlock_bh(&pnsocks.lock);
+ pn_sock_unbind_all_res(sk);
}
EXPORT_SYMBOL(pn_sock_unhash);
@@ -224,6 +225,101 @@ static int pn_socket_autobind(struct socket *sock)
return 0; /* socket was already bound */
}
+#ifdef CONFIG_PHONET_PIPECTRLR
+static int pn_socket_connect(struct socket *sock, struct sockaddr *addr,
+ int len, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
+ long timeo;
+ int err;
+
+ if (len < sizeof(struct sockaddr_pn))
+ return -EINVAL;
+ if (spn->spn_family != AF_PHONET)
+ return -EAFNOSUPPORT;
+
+ lock_sock(sk);
+
+ switch (sock->state) {
+ case SS_UNCONNECTED:
+ sk->sk_state = TCP_CLOSE;
+ break;
+ case SS_CONNECTING:
+ switch (sk->sk_state) {
+ case TCP_SYN_RECV:
+ sock->state = SS_CONNECTED;
+ err = -EISCONN;
+ goto out;
+ case TCP_CLOSE:
+ err = -EALREADY;
+ if (flags & O_NONBLOCK)
+ goto out;
+ goto wait_connect;
+ }
+ break;
+ case SS_CONNECTED:
+ switch (sk->sk_state) {
+ case TCP_SYN_RECV:
+ err = -EISCONN;
+ goto out;
+ case TCP_CLOSE:
+ sock->state = SS_UNCONNECTED;
+ break;
+ }
+ break;
+ case SS_DISCONNECTING:
+ case SS_FREE:
+ break;
+ }
+ sk->sk_state = TCP_CLOSE;
+ sk_stream_kill_queues(sk);
+
+ sock->state = SS_CONNECTING;
+ err = sk->sk_prot->connect(sk, addr, len);
+ if (err < 0) {
+ sock->state = SS_UNCONNECTED;
+ sk->sk_state = TCP_CLOSE;
+ goto out;
+ }
+
+ err = -EINPROGRESS;
+wait_connect:
+ if (sk->sk_state != TCP_SYN_RECV && (flags & O_NONBLOCK))
+ goto out;
+
+ timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
+ release_sock(sk);
+
+ err = -ERESTARTSYS;
+ timeo = wait_event_interruptible_timeout(*sk_sleep(sk),
+ sk->sk_state != TCP_CLOSE,
+ timeo);
+
+ lock_sock(sk);
+ if (timeo < 0)
+ goto out; /* -ERESTARTSYS */
+
+ err = -ETIMEDOUT;
+ if (timeo == 0 && sk->sk_state != TCP_SYN_RECV)
+ goto out;
+
+ if (sk->sk_state != TCP_SYN_RECV) {
+ sock->state = SS_UNCONNECTED;
+ err = sock_error(sk);
+ if (!err)
+ err = -ECONNREFUSED;
+ goto out;
+ }
+ sock->state = SS_CONNECTED;
+ err = 0;
+
+out:
+ release_sock(sk);
+ return err;
+}
+#endif
+
static int pn_socket_accept(struct socket *sock, struct socket *newsock,
int flags)
{
@@ -281,7 +377,9 @@ static unsigned int pn_socket_poll(struct file *file, struct socket *sock,
if (!mask && sk->sk_state == TCP_CLOSE_WAIT)
return POLLHUP;
- if (sk->sk_state == TCP_ESTABLISHED && atomic_read(&pn->tx_credits))
+ if (sk->sk_state == TCP_ESTABLISHED &&
+ atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf &&
+ atomic_read(&pn->tx_credits))
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
return mask;
@@ -390,7 +488,11 @@ const struct proto_ops phonet_stream_ops = {
.owner = THIS_MODULE,
.release = pn_socket_release,
.bind = pn_socket_bind,
+#ifdef CONFIG_PHONET_PIPECTRLR
+ .connect = pn_socket_connect,
+#else
.connect = sock_no_connect,
+#endif
.socketpair = sock_no_socketpair,
.accept = pn_socket_accept,
.getname = pn_socket_getname,
@@ -563,3 +665,188 @@ const struct file_operations pn_sock_seq_fops = {
.release = seq_release_net,
};
#endif
+
+static struct {
+ struct sock *sk[256];
+} pnres;
+
+/*
+ * Find and hold socket based on resource.
+ */
+struct sock *pn_find_sock_by_res(struct net *net, u8 res)
+{
+ struct sock *sk;
+
+ if (!net_eq(net, &init_net))
+ return NULL;
+
+ rcu_read_lock();
+ sk = rcu_dereference(pnres.sk[res]);
+ if (sk)
+ sock_hold(sk);
+ rcu_read_unlock();
+ return sk;
+}
+
+static DEFINE_MUTEX(resource_mutex);
+
+int pn_sock_bind_res(struct sock *sk, u8 res)
+{
+ int ret = -EADDRINUSE;
+
+ if (!net_eq(sock_net(sk), &init_net))
+ return -ENOIOCTLCMD;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (pn_socket_autobind(sk->sk_socket))
+ return -EAGAIN;
+
+ mutex_lock(&resource_mutex);
+ if (pnres.sk[res] == NULL) {
+ sock_hold(sk);
+ rcu_assign_pointer(pnres.sk[res], sk);
+ ret = 0;
+ }
+ mutex_unlock(&resource_mutex);
+ return ret;
+}
+
+int pn_sock_unbind_res(struct sock *sk, u8 res)
+{
+ int ret = -ENOENT;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ mutex_lock(&resource_mutex);
+ if (pnres.sk[res] == sk) {
+ rcu_assign_pointer(pnres.sk[res], NULL);
+ ret = 0;
+ }
+ mutex_unlock(&resource_mutex);
+
+ if (ret == 0) {
+ synchronize_rcu();
+ sock_put(sk);
+ }
+ return ret;
+}
+
+void pn_sock_unbind_all_res(struct sock *sk)
+{
+ unsigned res, match = 0;
+
+ mutex_lock(&resource_mutex);
+ for (res = 0; res < 256; res++) {
+ if (pnres.sk[res] == sk) {
+ rcu_assign_pointer(pnres.sk[res], NULL);
+ match++;
+ }
+ }
+ mutex_unlock(&resource_mutex);
+
+ if (match == 0)
+ return;
+ synchronize_rcu();
+ while (match > 0) {
+ sock_put(sk);
+ match--;
+ }
+}
+
+#ifdef CONFIG_PROC_FS
+static struct sock **pn_res_get_idx(struct seq_file *seq, loff_t pos)
+{
+ struct net *net = seq_file_net(seq);
+ unsigned i;
+
+ if (!net_eq(net, &init_net))
+ return NULL;
+
+ for (i = 0; i < 256; i++) {
+ if (pnres.sk[i] == NULL)
+ continue;
+ if (!pos)
+ return pnres.sk + i;
+ pos--;
+ }
+ return NULL;
+}
+
+static struct sock **pn_res_get_next(struct seq_file *seq, struct sock **sk)
+{
+ struct net *net = seq_file_net(seq);
+ unsigned i;
+
+ BUG_ON(!net_eq(net, &init_net));
+
+ for (i = (sk - pnres.sk) + 1; i < 256; i++)
+ if (pnres.sk[i])
+ return pnres.sk + i;
+ return NULL;
+}
+
+static void *pn_res_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(resource_mutex)
+{
+ mutex_lock(&resource_mutex);
+ return *pos ? pn_res_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+}
+
+static void *pn_res_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct sock **sk;
+
+ if (v == SEQ_START_TOKEN)
+ sk = pn_res_get_idx(seq, 0);
+ else
+ sk = pn_res_get_next(seq, v);
+ (*pos)++;
+ return sk;
+}
+
+static void pn_res_seq_stop(struct seq_file *seq, void *v)
+ __releases(resource_mutex)
+{
+ mutex_unlock(&resource_mutex);
+}
+
+static int pn_res_seq_show(struct seq_file *seq, void *v)
+{
+ int len;
+
+ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "%s%n", "rs uid inode", &len);
+ else {
+ struct sock **psk = v;
+ struct sock *sk = *psk;
+
+ seq_printf(seq, "%02X %5d %lu%n",
+ (int) (psk - pnres.sk), sock_i_uid(sk),
+ sock_i_ino(sk), &len);
+ }
+ seq_printf(seq, "%*s\n", 63 - len, "");
+ return 0;
+}
+
+static const struct seq_operations pn_res_seq_ops = {
+ .start = pn_res_seq_start,
+ .next = pn_res_seq_next,
+ .stop = pn_res_seq_stop,
+ .show = pn_res_seq_show,
+};
+
+static int pn_res_open(struct inode *inode, struct file *file)
+{
+ return seq_open_net(inode, file, &pn_res_seq_ops,
+ sizeof(struct seq_net_private));
+}
+
+const struct file_operations pn_res_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = pn_res_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_net,
+};
+#endif
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index aebfecbdb841..bb6ad81b671d 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -39,7 +39,15 @@
#include <net/sock.h>
#include "rds.h"
-#include "rdma.h"
+
+char *rds_str_array(char **array, size_t elements, size_t index)
+{
+ if ((index < elements) && array[index])
+ return array[index];
+ else
+ return "unknown";
+}
+EXPORT_SYMBOL(rds_str_array);
/* this is just used for stats gathering :/ */
static DEFINE_SPINLOCK(rds_sock_lock);
@@ -62,7 +70,7 @@ static int rds_release(struct socket *sock)
struct rds_sock *rs;
unsigned long flags;
- if (sk == NULL)
+ if (!sk)
goto out;
rs = rds_sk_to_rs(sk);
@@ -73,7 +81,15 @@ static int rds_release(struct socket *sock)
* with the socket. */
rds_clear_recv_queue(rs);
rds_cong_remove_socket(rs);
+
+ /*
+ * the binding lookup hash uses rcu, we need to
+ * make sure we sychronize_rcu before we free our
+ * entry
+ */
rds_remove_bound(rs);
+ synchronize_rcu();
+
rds_send_drop_to(rs, NULL);
rds_rdma_drop_keys(rs);
rds_notify_queue_get(rs, NULL);
@@ -83,6 +99,8 @@ static int rds_release(struct socket *sock)
rds_sock_count--;
spin_unlock_irqrestore(&rds_sock_lock, flags);
+ rds_trans_put(rs->rs_transport);
+
sock->sk = NULL;
sock_put(sk);
out:
@@ -514,7 +532,7 @@ out:
spin_unlock_irqrestore(&rds_sock_lock, flags);
}
-static void __exit rds_exit(void)
+static void rds_exit(void)
{
sock_unregister(rds_family_ops.family);
proto_unregister(&rds_proto);
@@ -529,7 +547,7 @@ static void __exit rds_exit(void)
}
module_exit(rds_exit);
-static int __init rds_init(void)
+static int rds_init(void)
{
int ret;
diff --git a/net/rds/bind.c b/net/rds/bind.c
index 5d95fc007f1a..2f6b3fcc79f8 100644
--- a/net/rds/bind.c
+++ b/net/rds/bind.c
@@ -34,45 +34,52 @@
#include <net/sock.h>
#include <linux/in.h>
#include <linux/if_arp.h>
+#include <linux/jhash.h>
#include "rds.h"
-/*
- * XXX this probably still needs more work.. no INADDR_ANY, and rbtrees aren't
- * particularly zippy.
- *
- * This is now called for every incoming frame so we arguably care much more
- * about it than we used to.
- */
+#define BIND_HASH_SIZE 1024
+static struct hlist_head bind_hash_table[BIND_HASH_SIZE];
static DEFINE_SPINLOCK(rds_bind_lock);
-static struct rb_root rds_bind_tree = RB_ROOT;
-static struct rds_sock *rds_bind_tree_walk(__be32 addr, __be16 port,
- struct rds_sock *insert)
+static struct hlist_head *hash_to_bucket(__be32 addr, __be16 port)
+{
+ return bind_hash_table + (jhash_2words((u32)addr, (u32)port, 0) &
+ (BIND_HASH_SIZE - 1));
+}
+
+static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port,
+ struct rds_sock *insert)
{
- struct rb_node **p = &rds_bind_tree.rb_node;
- struct rb_node *parent = NULL;
struct rds_sock *rs;
+ struct hlist_node *node;
+ struct hlist_head *head = hash_to_bucket(addr, port);
u64 cmp;
u64 needle = ((u64)be32_to_cpu(addr) << 32) | be16_to_cpu(port);
- while (*p) {
- parent = *p;
- rs = rb_entry(parent, struct rds_sock, rs_bound_node);
-
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(rs, node, head, rs_bound_node) {
cmp = ((u64)be32_to_cpu(rs->rs_bound_addr) << 32) |
be16_to_cpu(rs->rs_bound_port);
- if (needle < cmp)
- p = &(*p)->rb_left;
- else if (needle > cmp)
- p = &(*p)->rb_right;
- else
+ if (cmp == needle) {
+ rcu_read_unlock();
return rs;
+ }
}
+ rcu_read_unlock();
if (insert) {
- rb_link_node(&insert->rs_bound_node, parent, p);
- rb_insert_color(&insert->rs_bound_node, &rds_bind_tree);
+ /*
+ * make sure our addr and port are set before
+ * we are added to the list, other people
+ * in rcu will find us as soon as the
+ * hlist_add_head_rcu is done
+ */
+ insert->rs_bound_addr = addr;
+ insert->rs_bound_port = port;
+ rds_sock_addref(insert);
+
+ hlist_add_head_rcu(&insert->rs_bound_node, head);
}
return NULL;
}
@@ -86,15 +93,13 @@ static struct rds_sock *rds_bind_tree_walk(__be32 addr, __be16 port,
struct rds_sock *rds_find_bound(__be32 addr, __be16 port)
{
struct rds_sock *rs;
- unsigned long flags;
- spin_lock_irqsave(&rds_bind_lock, flags);
- rs = rds_bind_tree_walk(addr, port, NULL);
+ rs = rds_bind_lookup(addr, port, NULL);
+
if (rs && !sock_flag(rds_rs_to_sk(rs), SOCK_DEAD))
rds_sock_addref(rs);
else
rs = NULL;
- spin_unlock_irqrestore(&rds_bind_lock, flags);
rdsdebug("returning rs %p for %pI4:%u\n", rs, &addr,
ntohs(port));
@@ -121,22 +126,15 @@ static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port)
do {
if (rover == 0)
rover++;
- if (rds_bind_tree_walk(addr, cpu_to_be16(rover), rs) == NULL) {
- *port = cpu_to_be16(rover);
+ if (!rds_bind_lookup(addr, cpu_to_be16(rover), rs)) {
+ *port = rs->rs_bound_port;
ret = 0;
+ rdsdebug("rs %p binding to %pI4:%d\n",
+ rs, &addr, (int)ntohs(*port));
break;
}
} while (rover++ != last);
- if (ret == 0) {
- rs->rs_bound_addr = addr;
- rs->rs_bound_port = *port;
- rds_sock_addref(rs);
-
- rdsdebug("rs %p binding to %pI4:%d\n",
- rs, &addr, (int)ntohs(*port));
- }
-
spin_unlock_irqrestore(&rds_bind_lock, flags);
return ret;
@@ -153,7 +151,7 @@ void rds_remove_bound(struct rds_sock *rs)
rs, &rs->rs_bound_addr,
ntohs(rs->rs_bound_port));
- rb_erase(&rs->rs_bound_node, &rds_bind_tree);
+ hlist_del_init_rcu(&rs->rs_bound_node);
rds_sock_put(rs);
rs->rs_bound_addr = 0;
}
@@ -184,7 +182,7 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
goto out;
trans = rds_trans_get_preferred(sin->sin_addr.s_addr);
- if (trans == NULL) {
+ if (!trans) {
ret = -EADDRNOTAVAIL;
rds_remove_bound(rs);
if (printk_ratelimit())
@@ -198,5 +196,9 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
out:
release_sock(sk);
+
+ /* we might have called rds_remove_bound on error */
+ if (ret)
+ synchronize_rcu();
return ret;
}
diff --git a/net/rds/cong.c b/net/rds/cong.c
index 0871a29f0780..75ea686f27d5 100644
--- a/net/rds/cong.c
+++ b/net/rds/cong.c
@@ -141,7 +141,7 @@ static struct rds_cong_map *rds_cong_from_addr(__be32 addr)
unsigned long flags;
map = kzalloc(sizeof(struct rds_cong_map), GFP_KERNEL);
- if (map == NULL)
+ if (!map)
return NULL;
map->m_addr = addr;
@@ -159,7 +159,7 @@ static struct rds_cong_map *rds_cong_from_addr(__be32 addr)
ret = rds_cong_tree_walk(addr, map);
spin_unlock_irqrestore(&rds_cong_lock, flags);
- if (ret == NULL) {
+ if (!ret) {
ret = map;
map = NULL;
}
@@ -205,7 +205,7 @@ int rds_cong_get_maps(struct rds_connection *conn)
conn->c_lcong = rds_cong_from_addr(conn->c_laddr);
conn->c_fcong = rds_cong_from_addr(conn->c_faddr);
- if (conn->c_lcong == NULL || conn->c_fcong == NULL)
+ if (!(conn->c_lcong && conn->c_fcong))
return -ENOMEM;
return 0;
@@ -221,7 +221,7 @@ void rds_cong_queue_updates(struct rds_cong_map *map)
list_for_each_entry(conn, &map->m_conn_list, c_map_item) {
if (!test_and_set_bit(0, &conn->c_map_queued)) {
rds_stats_inc(s_cong_update_queued);
- queue_delayed_work(rds_wq, &conn->c_send_w, 0);
+ rds_send_xmit(conn);
}
}
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 7619b671ca28..9334d892366e 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -37,7 +37,6 @@
#include "rds.h"
#include "loop.h"
-#include "rdma.h"
#define RDS_CONNECTION_HASH_BITS 12
#define RDS_CONNECTION_HASH_ENTRIES (1 << RDS_CONNECTION_HASH_BITS)
@@ -63,18 +62,7 @@ static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr)
var |= RDS_INFO_CONNECTION_FLAG_##suffix; \
} while (0)
-static inline int rds_conn_is_sending(struct rds_connection *conn)
-{
- int ret = 0;
-
- if (!mutex_trylock(&conn->c_send_lock))
- ret = 1;
- else
- mutex_unlock(&conn->c_send_lock);
-
- return ret;
-}
-
+/* rcu read lock must be held or the connection spinlock */
static struct rds_connection *rds_conn_lookup(struct hlist_head *head,
__be32 laddr, __be32 faddr,
struct rds_transport *trans)
@@ -82,7 +70,7 @@ static struct rds_connection *rds_conn_lookup(struct hlist_head *head,
struct rds_connection *conn, *ret = NULL;
struct hlist_node *pos;
- hlist_for_each_entry(conn, pos, head, c_hash_node) {
+ hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) {
if (conn->c_faddr == faddr && conn->c_laddr == laddr &&
conn->c_trans == trans) {
ret = conn;
@@ -100,7 +88,7 @@ static struct rds_connection *rds_conn_lookup(struct hlist_head *head,
* and receiving over this connection again in the future. It is up to
* the transport to have serialized this call with its send and recv.
*/
-void rds_conn_reset(struct rds_connection *conn)
+static void rds_conn_reset(struct rds_connection *conn)
{
rdsdebug("connection %pI4 to %pI4 reset\n",
&conn->c_laddr, &conn->c_faddr);
@@ -129,10 +117,11 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
{
struct rds_connection *conn, *parent = NULL;
struct hlist_head *head = rds_conn_bucket(laddr, faddr);
+ struct rds_transport *loop_trans;
unsigned long flags;
int ret;
- spin_lock_irqsave(&rds_conn_lock, flags);
+ rcu_read_lock();
conn = rds_conn_lookup(head, laddr, faddr, trans);
if (conn && conn->c_loopback && conn->c_trans != &rds_loop_transport &&
!is_outgoing) {
@@ -143,12 +132,12 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
parent = conn;
conn = parent->c_passive;
}
- spin_unlock_irqrestore(&rds_conn_lock, flags);
+ rcu_read_unlock();
if (conn)
goto out;
conn = kmem_cache_zalloc(rds_conn_slab, gfp);
- if (conn == NULL) {
+ if (!conn) {
conn = ERR_PTR(-ENOMEM);
goto out;
}
@@ -159,7 +148,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
spin_lock_init(&conn->c_lock);
conn->c_next_tx_seq = 1;
- mutex_init(&conn->c_send_lock);
+ init_waitqueue_head(&conn->c_waitq);
INIT_LIST_HEAD(&conn->c_send_queue);
INIT_LIST_HEAD(&conn->c_retrans);
@@ -175,7 +164,9 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
* can bind to the destination address then we'd rather the messages
* flow through loopback rather than either transport.
*/
- if (rds_trans_get_preferred(faddr)) {
+ loop_trans = rds_trans_get_preferred(faddr);
+ if (loop_trans) {
+ rds_trans_put(loop_trans);
conn->c_loopback = 1;
if (is_outgoing && trans->t_prefer_loopback) {
/* "outgoing" connection - and the transport
@@ -238,7 +229,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
kmem_cache_free(rds_conn_slab, conn);
conn = found;
} else {
- hlist_add_head(&conn->c_hash_node, head);
+ hlist_add_head_rcu(&conn->c_hash_node, head);
rds_cong_add_conn(conn);
rds_conn_count++;
}
@@ -263,21 +254,91 @@ struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
}
EXPORT_SYMBOL_GPL(rds_conn_create_outgoing);
+void rds_conn_shutdown(struct rds_connection *conn)
+{
+ /* shut it down unless it's down already */
+ if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) {
+ /*
+ * Quiesce the connection mgmt handlers before we start tearing
+ * things down. We don't hold the mutex for the entire
+ * duration of the shutdown operation, else we may be
+ * deadlocking with the CM handler. Instead, the CM event
+ * handler is supposed to check for state DISCONNECTING
+ */
+ mutex_lock(&conn->c_cm_lock);
+ if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING)
+ && !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) {
+ rds_conn_error(conn, "shutdown called in state %d\n",
+ atomic_read(&conn->c_state));
+ mutex_unlock(&conn->c_cm_lock);
+ return;
+ }
+ mutex_unlock(&conn->c_cm_lock);
+
+ wait_event(conn->c_waitq,
+ !test_bit(RDS_IN_XMIT, &conn->c_flags));
+
+ conn->c_trans->conn_shutdown(conn);
+ rds_conn_reset(conn);
+
+ if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) {
+ /* This can happen - eg when we're in the middle of tearing
+ * down the connection, and someone unloads the rds module.
+ * Quite reproduceable with loopback connections.
+ * Mostly harmless.
+ */
+ rds_conn_error(conn,
+ "%s: failed to transition to state DOWN, "
+ "current state is %d\n",
+ __func__,
+ atomic_read(&conn->c_state));
+ return;
+ }
+ }
+
+ /* Then reconnect if it's still live.
+ * The passive side of an IB loopback connection is never added
+ * to the conn hash, so we never trigger a reconnect on this
+ * conn - the reconnect is always triggered by the active peer. */
+ cancel_delayed_work_sync(&conn->c_conn_w);
+ rcu_read_lock();
+ if (!hlist_unhashed(&conn->c_hash_node)) {
+ rcu_read_unlock();
+ rds_queue_reconnect(conn);
+ } else {
+ rcu_read_unlock();
+ }
+}
+
+/*
+ * Stop and free a connection.
+ *
+ * This can only be used in very limited circumstances. It assumes that once
+ * the conn has been shutdown that no one else is referencing the connection.
+ * We can only ensure this in the rmmod path in the current code.
+ */
void rds_conn_destroy(struct rds_connection *conn)
{
struct rds_message *rm, *rtmp;
+ unsigned long flags;
rdsdebug("freeing conn %p for %pI4 -> "
"%pI4\n", conn, &conn->c_laddr,
&conn->c_faddr);
- hlist_del_init(&conn->c_hash_node);
+ /* Ensure conn will not be scheduled for reconnect */
+ spin_lock_irq(&rds_conn_lock);
+ hlist_del_init_rcu(&conn->c_hash_node);
+ spin_unlock_irq(&rds_conn_lock);
+ synchronize_rcu();
- /* wait for the rds thread to shut it down */
- atomic_set(&conn->c_state, RDS_CONN_ERROR);
- cancel_delayed_work(&conn->c_conn_w);
- queue_work(rds_wq, &conn->c_down_w);
- flush_workqueue(rds_wq);
+ /* shut the connection down */
+ rds_conn_drop(conn);
+ flush_work(&conn->c_down_w);
+
+ /* make sure lingering queued work won't try to ref the conn */
+ cancel_delayed_work_sync(&conn->c_send_w);
+ cancel_delayed_work_sync(&conn->c_recv_w);
/* tear down queued messages */
list_for_each_entry_safe(rm, rtmp,
@@ -302,7 +363,9 @@ void rds_conn_destroy(struct rds_connection *conn)
BUG_ON(!list_empty(&conn->c_retrans));
kmem_cache_free(rds_conn_slab, conn);
+ spin_lock_irqsave(&rds_conn_lock, flags);
rds_conn_count--;
+ spin_unlock_irqrestore(&rds_conn_lock, flags);
}
EXPORT_SYMBOL_GPL(rds_conn_destroy);
@@ -316,23 +379,23 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len,
struct list_head *list;
struct rds_connection *conn;
struct rds_message *rm;
- unsigned long flags;
unsigned int total = 0;
+ unsigned long flags;
size_t i;
len /= sizeof(struct rds_info_message);
- spin_lock_irqsave(&rds_conn_lock, flags);
+ rcu_read_lock();
for (i = 0, head = rds_conn_hash; i < ARRAY_SIZE(rds_conn_hash);
i++, head++) {
- hlist_for_each_entry(conn, pos, head, c_hash_node) {
+ hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) {
if (want_send)
list = &conn->c_send_queue;
else
list = &conn->c_retrans;
- spin_lock(&conn->c_lock);
+ spin_lock_irqsave(&conn->c_lock, flags);
/* XXX too lazy to maintain counts.. */
list_for_each_entry(rm, list, m_conn_item) {
@@ -343,11 +406,10 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len,
conn->c_faddr, 0);
}
- spin_unlock(&conn->c_lock);
+ spin_unlock_irqrestore(&conn->c_lock, flags);
}
}
-
- spin_unlock_irqrestore(&rds_conn_lock, flags);
+ rcu_read_unlock();
lens->nr = total;
lens->each = sizeof(struct rds_info_message);
@@ -377,19 +439,17 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len,
uint64_t buffer[(item_len + 7) / 8];
struct hlist_head *head;
struct hlist_node *pos;
- struct hlist_node *tmp;
struct rds_connection *conn;
- unsigned long flags;
size_t i;
- spin_lock_irqsave(&rds_conn_lock, flags);
+ rcu_read_lock();
lens->nr = 0;
lens->each = item_len;
for (i = 0, head = rds_conn_hash; i < ARRAY_SIZE(rds_conn_hash);
i++, head++) {
- hlist_for_each_entry_safe(conn, pos, tmp, head, c_hash_node) {
+ hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) {
/* XXX no c_lock usage.. */
if (!visitor(conn, buffer))
@@ -405,8 +465,7 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len,
lens->nr++;
}
}
-
- spin_unlock_irqrestore(&rds_conn_lock, flags);
+ rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(rds_for_each_conn_info);
@@ -423,8 +482,8 @@ static int rds_conn_info_visitor(struct rds_connection *conn,
sizeof(cinfo->transport));
cinfo->flags = 0;
- rds_conn_info_set(cinfo->flags,
- rds_conn_is_sending(conn), SENDING);
+ rds_conn_info_set(cinfo->flags, test_bit(RDS_IN_XMIT, &conn->c_flags),
+ SENDING);
/* XXX Future: return the state rather than these funky bits */
rds_conn_info_set(cinfo->flags,
atomic_read(&conn->c_state) == RDS_CONN_CONNECTING,
@@ -444,12 +503,12 @@ static void rds_conn_info(struct socket *sock, unsigned int len,
sizeof(struct rds_info_connection));
}
-int __init rds_conn_init(void)
+int rds_conn_init(void)
{
rds_conn_slab = kmem_cache_create("rds_connection",
sizeof(struct rds_connection),
0, 0, NULL);
- if (rds_conn_slab == NULL)
+ if (!rds_conn_slab)
return -ENOMEM;
rds_info_register_func(RDS_INFO_CONNECTIONS, rds_conn_info);
@@ -487,6 +546,18 @@ void rds_conn_drop(struct rds_connection *conn)
EXPORT_SYMBOL_GPL(rds_conn_drop);
/*
+ * If the connection is down, trigger a connect. We may have scheduled a
+ * delayed reconnect however - in this case we should not interfere.
+ */
+void rds_conn_connect_if_down(struct rds_connection *conn)
+{
+ if (rds_conn_state(conn) == RDS_CONN_DOWN &&
+ !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags))
+ queue_delayed_work(rds_wq, &conn->c_conn_w, 0);
+}
+EXPORT_SYMBOL_GPL(rds_conn_connect_if_down);
+
+/*
* An error occurred on the connection
*/
void
diff --git a/net/rds/ib.c b/net/rds/ib.c
index 8f2d6dd7700a..4123967d4d65 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -42,7 +42,7 @@
#include "rds.h"
#include "ib.h"
-unsigned int fmr_pool_size = RDS_FMR_POOL_SIZE;
+static unsigned int fmr_pool_size = RDS_FMR_POOL_SIZE;
unsigned int fmr_message_size = RDS_FMR_SIZE + 1; /* +1 allows for unaligned MRs */
unsigned int rds_ib_retry_count = RDS_IB_DEFAULT_RETRY_COUNT;
@@ -53,13 +53,72 @@ MODULE_PARM_DESC(fmr_message_size, " Max size of a RDMA transfer");
module_param(rds_ib_retry_count, int, 0444);
MODULE_PARM_DESC(rds_ib_retry_count, " Number of hw retries before reporting an error");
+/*
+ * we have a clumsy combination of RCU and a rwsem protecting this list
+ * because it is used both in the get_mr fast path and while blocking in
+ * the FMR flushing path.
+ */
+DECLARE_RWSEM(rds_ib_devices_lock);
struct list_head rds_ib_devices;
/* NOTE: if also grabbing ibdev lock, grab this first */
DEFINE_SPINLOCK(ib_nodev_conns_lock);
LIST_HEAD(ib_nodev_conns);
-void rds_ib_add_one(struct ib_device *device)
+static void rds_ib_nodev_connect(void)
+{
+ struct rds_ib_connection *ic;
+
+ spin_lock(&ib_nodev_conns_lock);
+ list_for_each_entry(ic, &ib_nodev_conns, ib_node)
+ rds_conn_connect_if_down(ic->conn);
+ spin_unlock(&ib_nodev_conns_lock);
+}
+
+static void rds_ib_dev_shutdown(struct rds_ib_device *rds_ibdev)
+{
+ struct rds_ib_connection *ic;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rds_ibdev->spinlock, flags);
+ list_for_each_entry(ic, &rds_ibdev->conn_list, ib_node)
+ rds_conn_drop(ic->conn);
+ spin_unlock_irqrestore(&rds_ibdev->spinlock, flags);
+}
+
+/*
+ * rds_ib_destroy_mr_pool() blocks on a few things and mrs drop references
+ * from interrupt context so we push freing off into a work struct in krdsd.
+ */
+static void rds_ib_dev_free(struct work_struct *work)
+{
+ struct rds_ib_ipaddr *i_ipaddr, *i_next;
+ struct rds_ib_device *rds_ibdev = container_of(work,
+ struct rds_ib_device, free_work);
+
+ if (rds_ibdev->mr_pool)
+ rds_ib_destroy_mr_pool(rds_ibdev->mr_pool);
+ if (rds_ibdev->mr)
+ ib_dereg_mr(rds_ibdev->mr);
+ if (rds_ibdev->pd)
+ ib_dealloc_pd(rds_ibdev->pd);
+
+ list_for_each_entry_safe(i_ipaddr, i_next, &rds_ibdev->ipaddr_list, list) {
+ list_del(&i_ipaddr->list);
+ kfree(i_ipaddr);
+ }
+
+ kfree(rds_ibdev);
+}
+
+void rds_ib_dev_put(struct rds_ib_device *rds_ibdev)
+{
+ BUG_ON(atomic_read(&rds_ibdev->refcount) <= 0);
+ if (atomic_dec_and_test(&rds_ibdev->refcount))
+ queue_work(rds_wq, &rds_ibdev->free_work);
+}
+
+static void rds_ib_add_one(struct ib_device *device)
{
struct rds_ib_device *rds_ibdev;
struct ib_device_attr *dev_attr;
@@ -77,11 +136,14 @@ void rds_ib_add_one(struct ib_device *device)
goto free_attr;
}
- rds_ibdev = kmalloc(sizeof *rds_ibdev, GFP_KERNEL);
+ rds_ibdev = kzalloc_node(sizeof(struct rds_ib_device), GFP_KERNEL,
+ ibdev_to_node(device));
if (!rds_ibdev)
goto free_attr;
spin_lock_init(&rds_ibdev->spinlock);
+ atomic_set(&rds_ibdev->refcount, 1);
+ INIT_WORK(&rds_ibdev->free_work, rds_ib_dev_free);
rds_ibdev->max_wrs = dev_attr->max_qp_wr;
rds_ibdev->max_sge = min(dev_attr->max_sge, RDS_IB_MAX_SGE);
@@ -91,68 +153,107 @@ void rds_ib_add_one(struct ib_device *device)
min_t(unsigned int, dev_attr->max_fmr, fmr_pool_size) :
fmr_pool_size;
+ rds_ibdev->max_initiator_depth = dev_attr->max_qp_init_rd_atom;
+ rds_ibdev->max_responder_resources = dev_attr->max_qp_rd_atom;
+
rds_ibdev->dev = device;
rds_ibdev->pd = ib_alloc_pd(device);
- if (IS_ERR(rds_ibdev->pd))
- goto free_dev;
+ if (IS_ERR(rds_ibdev->pd)) {
+ rds_ibdev->pd = NULL;
+ goto put_dev;
+ }
- rds_ibdev->mr = ib_get_dma_mr(rds_ibdev->pd,
- IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(rds_ibdev->mr))
- goto err_pd;
+ rds_ibdev->mr = ib_get_dma_mr(rds_ibdev->pd, IB_ACCESS_LOCAL_WRITE);
+ if (IS_ERR(rds_ibdev->mr)) {
+ rds_ibdev->mr = NULL;
+ goto put_dev;
+ }
rds_ibdev->mr_pool = rds_ib_create_mr_pool(rds_ibdev);
if (IS_ERR(rds_ibdev->mr_pool)) {
rds_ibdev->mr_pool = NULL;
- goto err_mr;
+ goto put_dev;
}
INIT_LIST_HEAD(&rds_ibdev->ipaddr_list);
INIT_LIST_HEAD(&rds_ibdev->conn_list);
- list_add_tail(&rds_ibdev->list, &rds_ib_devices);
+
+ down_write(&rds_ib_devices_lock);
+ list_add_tail_rcu(&rds_ibdev->list, &rds_ib_devices);
+ up_write(&rds_ib_devices_lock);
+ atomic_inc(&rds_ibdev->refcount);
ib_set_client_data(device, &rds_ib_client, rds_ibdev);
+ atomic_inc(&rds_ibdev->refcount);
- goto free_attr;
+ rds_ib_nodev_connect();
-err_mr:
- ib_dereg_mr(rds_ibdev->mr);
-err_pd:
- ib_dealloc_pd(rds_ibdev->pd);
-free_dev:
- kfree(rds_ibdev);
+put_dev:
+ rds_ib_dev_put(rds_ibdev);
free_attr:
kfree(dev_attr);
}
-void rds_ib_remove_one(struct ib_device *device)
+/*
+ * New connections use this to find the device to associate with the
+ * connection. It's not in the fast path so we're not concerned about the
+ * performance of the IB call. (As of this writing, it uses an interrupt
+ * blocking spinlock to serialize walking a per-device list of all registered
+ * clients.)
+ *
+ * RCU is used to handle incoming connections racing with device teardown.
+ * Rather than use a lock to serialize removal from the client_data and
+ * getting a new reference, we use an RCU grace period. The destruction
+ * path removes the device from client_data and then waits for all RCU
+ * readers to finish.
+ *
+ * A new connection can get NULL from this if its arriving on a
+ * device that is in the process of being removed.
+ */
+struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device)
{
struct rds_ib_device *rds_ibdev;
- struct rds_ib_ipaddr *i_ipaddr, *i_next;
+ rcu_read_lock();
rds_ibdev = ib_get_client_data(device, &rds_ib_client);
- if (!rds_ibdev)
- return;
+ if (rds_ibdev)
+ atomic_inc(&rds_ibdev->refcount);
+ rcu_read_unlock();
+ return rds_ibdev;
+}
- list_for_each_entry_safe(i_ipaddr, i_next, &rds_ibdev->ipaddr_list, list) {
- list_del(&i_ipaddr->list);
- kfree(i_ipaddr);
- }
+/*
+ * The IB stack is letting us know that a device is going away. This can
+ * happen if the underlying HCA driver is removed or if PCI hotplug is removing
+ * the pci function, for example.
+ *
+ * This can be called at any time and can be racing with any other RDS path.
+ */
+static void rds_ib_remove_one(struct ib_device *device)
+{
+ struct rds_ib_device *rds_ibdev;
- rds_ib_destroy_conns(rds_ibdev);
+ rds_ibdev = ib_get_client_data(device, &rds_ib_client);
+ if (!rds_ibdev)
+ return;
- if (rds_ibdev->mr_pool)
- rds_ib_destroy_mr_pool(rds_ibdev->mr_pool);
+ rds_ib_dev_shutdown(rds_ibdev);
- ib_dereg_mr(rds_ibdev->mr);
+ /* stop connection attempts from getting a reference to this device. */
+ ib_set_client_data(device, &rds_ib_client, NULL);
- while (ib_dealloc_pd(rds_ibdev->pd)) {
- rdsdebug("Failed to dealloc pd %p\n", rds_ibdev->pd);
- msleep(1);
- }
+ down_write(&rds_ib_devices_lock);
+ list_del_rcu(&rds_ibdev->list);
+ up_write(&rds_ib_devices_lock);
- list_del(&rds_ibdev->list);
- kfree(rds_ibdev);
+ /*
+ * This synchronize rcu is waiting for readers of both the ib
+ * client data and the devices list to finish before we drop
+ * both of those references.
+ */
+ synchronize_rcu();
+ rds_ib_dev_put(rds_ibdev);
+ rds_ib_dev_put(rds_ibdev);
}
struct ib_client rds_ib_client = {
@@ -186,7 +287,7 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn,
rdma_addr_get_sgid(dev_addr, (union ib_gid *) &iinfo->src_gid);
rdma_addr_get_dgid(dev_addr, (union ib_gid *) &iinfo->dst_gid);
- rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client);
+ rds_ibdev = ic->rds_ibdev;
iinfo->max_send_wr = ic->i_send_ring.w_nr;
iinfo->max_recv_wr = ic->i_recv_ring.w_nr;
iinfo->max_send_sge = rds_ibdev->max_sge;
@@ -248,29 +349,36 @@ static int rds_ib_laddr_check(__be32 addr)
return ret;
}
+static void rds_ib_unregister_client(void)
+{
+ ib_unregister_client(&rds_ib_client);
+ /* wait for rds_ib_dev_free() to complete */
+ flush_workqueue(rds_wq);
+}
+
void rds_ib_exit(void)
{
rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
+ rds_ib_unregister_client();
rds_ib_destroy_nodev_conns();
- ib_unregister_client(&rds_ib_client);
rds_ib_sysctl_exit();
rds_ib_recv_exit();
rds_trans_unregister(&rds_ib_transport);
+ rds_ib_fmr_exit();
}
struct rds_transport rds_ib_transport = {
.laddr_check = rds_ib_laddr_check,
.xmit_complete = rds_ib_xmit_complete,
.xmit = rds_ib_xmit,
- .xmit_cong_map = NULL,
.xmit_rdma = rds_ib_xmit_rdma,
+ .xmit_atomic = rds_ib_xmit_atomic,
.recv = rds_ib_recv,
.conn_alloc = rds_ib_conn_alloc,
.conn_free = rds_ib_conn_free,
.conn_connect = rds_ib_conn_connect,
.conn_shutdown = rds_ib_conn_shutdown,
.inc_copy_to_user = rds_ib_inc_copy_to_user,
- .inc_purge = rds_ib_inc_purge,
.inc_free = rds_ib_inc_free,
.cm_initiate_connect = rds_ib_cm_initiate_connect,
.cm_handle_connect = rds_ib_cm_handle_connect,
@@ -286,16 +394,20 @@ struct rds_transport rds_ib_transport = {
.t_type = RDS_TRANS_IB
};
-int __init rds_ib_init(void)
+int rds_ib_init(void)
{
int ret;
INIT_LIST_HEAD(&rds_ib_devices);
- ret = ib_register_client(&rds_ib_client);
+ ret = rds_ib_fmr_init();
if (ret)
goto out;
+ ret = ib_register_client(&rds_ib_client);
+ if (ret)
+ goto out_fmr_exit;
+
ret = rds_ib_sysctl_init();
if (ret)
goto out_ibreg;
@@ -317,7 +429,9 @@ out_recv:
out_sysctl:
rds_ib_sysctl_exit();
out_ibreg:
- ib_unregister_client(&rds_ib_client);
+ rds_ib_unregister_client();
+out_fmr_exit:
+ rds_ib_fmr_exit();
out:
return ret;
}
diff --git a/net/rds/ib.h b/net/rds/ib.h
index 64df4e79b29f..e34ad032b66d 100644
--- a/net/rds/ib.h
+++ b/net/rds/ib.h
@@ -3,11 +3,13 @@
#include <rdma/ib_verbs.h>
#include <rdma/rdma_cm.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
#include "rds.h"
#include "rdma_transport.h"
#define RDS_FMR_SIZE 256
-#define RDS_FMR_POOL_SIZE 4096
+#define RDS_FMR_POOL_SIZE 8192
#define RDS_IB_MAX_SGE 8
#define RDS_IB_RECV_SGE 2
@@ -19,6 +21,9 @@
#define RDS_IB_SUPPORTED_PROTOCOLS 0x00000003 /* minor versions supported */
+#define RDS_IB_RECYCLE_BATCH_COUNT 32
+
+extern struct rw_semaphore rds_ib_devices_lock;
extern struct list_head rds_ib_devices;
/*
@@ -26,20 +31,29 @@ extern struct list_head rds_ib_devices;
* try and minimize the amount of memory tied up both the device and
* socket receive queues.
*/
-/* page offset of the final full frag that fits in the page */
-#define RDS_PAGE_LAST_OFF (((PAGE_SIZE / RDS_FRAG_SIZE) - 1) * RDS_FRAG_SIZE)
struct rds_page_frag {
struct list_head f_item;
- struct page *f_page;
- unsigned long f_offset;
- dma_addr_t f_mapped;
+ struct list_head f_cache_entry;
+ struct scatterlist f_sg;
};
struct rds_ib_incoming {
struct list_head ii_frags;
+ struct list_head ii_cache_entry;
struct rds_incoming ii_inc;
};
+struct rds_ib_cache_head {
+ struct list_head *first;
+ unsigned long count;
+};
+
+struct rds_ib_refill_cache {
+ struct rds_ib_cache_head *percpu;
+ struct list_head *xfer;
+ struct list_head *ready;
+};
+
struct rds_ib_connect_private {
/* Add new fields at the end, and don't permute existing fields. */
__be32 dp_saddr;
@@ -53,8 +67,7 @@ struct rds_ib_connect_private {
};
struct rds_ib_send_work {
- struct rds_message *s_rm;
- struct rds_rdma_op *s_op;
+ void *s_op;
struct ib_send_wr s_wr;
struct ib_sge s_sge[RDS_IB_MAX_SGE];
unsigned long s_queued;
@@ -92,10 +105,11 @@ struct rds_ib_connection {
/* tx */
struct rds_ib_work_ring i_send_ring;
- struct rds_message *i_rm;
+ struct rm_data_op *i_data_op;
struct rds_header *i_send_hdrs;
u64 i_send_hdrs_dma;
struct rds_ib_send_work *i_sends;
+ atomic_t i_signaled_sends;
/* rx */
struct tasklet_struct i_recv_tasklet;
@@ -106,8 +120,9 @@ struct rds_ib_connection {
struct rds_header *i_recv_hdrs;
u64 i_recv_hdrs_dma;
struct rds_ib_recv_work *i_recvs;
- struct rds_page_frag i_frag;
u64 i_ack_recv; /* last ACK received */
+ struct rds_ib_refill_cache i_cache_incs;
+ struct rds_ib_refill_cache i_cache_frags;
/* sending acks */
unsigned long i_ack_flags;
@@ -138,7 +153,6 @@ struct rds_ib_connection {
/* Batched completions */
unsigned int i_unsignaled_wrs;
- long i_unsignaled_bytes;
};
/* This assumes that atomic_t is at least 32 bits */
@@ -164,9 +178,17 @@ struct rds_ib_device {
unsigned int max_fmrs;
int max_sge;
unsigned int max_wrs;
+ unsigned int max_initiator_depth;
+ unsigned int max_responder_resources;
spinlock_t spinlock; /* protect the above */
+ atomic_t refcount;
+ struct work_struct free_work;
};
+#define pcidev_to_node(pcidev) pcibus_to_node(pcidev->bus)
+#define ibdev_to_node(ibdev) pcidev_to_node(to_pci_dev(ibdev->dma_device))
+#define rdsibdev_to_node(rdsibdev) ibdev_to_node(rdsibdev->dev)
+
/* bits for i_ack_flags */
#define IB_ACK_IN_FLIGHT 0
#define IB_ACK_REQUESTED 1
@@ -202,6 +224,8 @@ struct rds_ib_statistics {
uint64_t s_ib_rdma_mr_pool_flush;
uint64_t s_ib_rdma_mr_pool_wait;
uint64_t s_ib_rdma_mr_pool_depleted;
+ uint64_t s_ib_atomic_cswp;
+ uint64_t s_ib_atomic_fadd;
};
extern struct workqueue_struct *rds_ib_wq;
@@ -241,11 +265,10 @@ static inline void rds_ib_dma_sync_sg_for_device(struct ib_device *dev,
/* ib.c */
extern struct rds_transport rds_ib_transport;
-extern void rds_ib_add_one(struct ib_device *device);
-extern void rds_ib_remove_one(struct ib_device *device);
+struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device);
+void rds_ib_dev_put(struct rds_ib_device *rds_ibdev);
extern struct ib_client rds_ib_client;
-extern unsigned int fmr_pool_size;
extern unsigned int fmr_message_size;
extern unsigned int rds_ib_retry_count;
@@ -258,7 +281,7 @@ void rds_ib_conn_free(void *arg);
int rds_ib_conn_connect(struct rds_connection *conn);
void rds_ib_conn_shutdown(struct rds_connection *conn);
void rds_ib_state_change(struct sock *sk);
-int __init rds_ib_listen_init(void);
+int rds_ib_listen_init(void);
void rds_ib_listen_stop(void);
void __rds_ib_conn_error(struct rds_connection *conn, const char *, ...);
int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
@@ -275,15 +298,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn,
int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr);
void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn);
void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn);
-void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock);
-static inline void rds_ib_destroy_nodev_conns(void)
-{
- __rds_ib_destroy_conns(&ib_nodev_conns, &ib_nodev_conns_lock);
-}
-static inline void rds_ib_destroy_conns(struct rds_ib_device *rds_ibdev)
-{
- __rds_ib_destroy_conns(&rds_ibdev->conn_list, &rds_ibdev->spinlock);
-}
+void rds_ib_destroy_nodev_conns(void);
struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *);
void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_connection *iinfo);
void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *);
@@ -292,14 +307,16 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents,
void rds_ib_sync_mr(void *trans_private, int dir);
void rds_ib_free_mr(void *trans_private, int invalidate);
void rds_ib_flush_mrs(void);
+int rds_ib_fmr_init(void);
+void rds_ib_fmr_exit(void);
/* ib_recv.c */
-int __init rds_ib_recv_init(void);
+int rds_ib_recv_init(void);
void rds_ib_recv_exit(void);
int rds_ib_recv(struct rds_connection *conn);
-int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp,
- gfp_t page_gfp, int prefill);
-void rds_ib_inc_purge(struct rds_incoming *inc);
+int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic);
+void rds_ib_recv_free_caches(struct rds_ib_connection *ic);
+void rds_ib_recv_refill(struct rds_connection *conn, int prefill);
void rds_ib_inc_free(struct rds_incoming *inc);
int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
size_t size);
@@ -325,17 +342,19 @@ u32 rds_ib_ring_completed(struct rds_ib_work_ring *ring, u32 wr_id, u32 oldest);
extern wait_queue_head_t rds_ib_ring_empty_wait;
/* ib_send.c */
+char *rds_ib_wc_status_str(enum ib_wc_status status);
void rds_ib_xmit_complete(struct rds_connection *conn);
int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
unsigned int hdr_off, unsigned int sg, unsigned int off);
void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context);
void rds_ib_send_init_ring(struct rds_ib_connection *ic);
void rds_ib_send_clear_ring(struct rds_ib_connection *ic);
-int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op);
+int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op);
void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits);
void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted);
int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted,
u32 *adv_credits, int need_posted, int max_posted);
+int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op);
/* ib_stats.c */
DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats);
@@ -344,7 +363,7 @@ unsigned int rds_ib_stats_info_copy(struct rds_info_iterator *iter,
unsigned int avail);
/* ib_sysctl.c */
-int __init rds_ib_sysctl_init(void);
+int rds_ib_sysctl_init(void);
void rds_ib_sysctl_exit(void);
extern unsigned long rds_ib_sysctl_max_send_wr;
extern unsigned long rds_ib_sysctl_max_recv_wr;
@@ -352,30 +371,5 @@ extern unsigned long rds_ib_sysctl_max_unsig_wrs;
extern unsigned long rds_ib_sysctl_max_unsig_bytes;
extern unsigned long rds_ib_sysctl_max_recv_allocation;
extern unsigned int rds_ib_sysctl_flow_control;
-extern ctl_table rds_ib_sysctl_table[];
-
-/*
- * Helper functions for getting/setting the header and data SGEs in
- * RDS packets (not RDMA)
- *
- * From version 3.1 onwards, header is in front of data in the sge.
- */
-static inline struct ib_sge *
-rds_ib_header_sge(struct rds_ib_connection *ic, struct ib_sge *sge)
-{
- if (ic->conn->c_version > RDS_PROTOCOL_3_0)
- return &sge[0];
- else
- return &sge[1];
-}
-
-static inline struct ib_sge *
-rds_ib_data_sge(struct rds_ib_connection *ic, struct ib_sge *sge)
-{
- if (ic->conn->c_version > RDS_PROTOCOL_3_0)
- return &sge[1];
- else
- return &sge[0];
-}
#endif
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index f68832798db2..ee369d201a65 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -38,6 +38,36 @@
#include "rds.h"
#include "ib.h"
+static char *rds_ib_event_type_strings[] = {
+#define RDS_IB_EVENT_STRING(foo) \
+ [IB_EVENT_##foo] = __stringify(IB_EVENT_##foo)
+ RDS_IB_EVENT_STRING(CQ_ERR),
+ RDS_IB_EVENT_STRING(QP_FATAL),
+ RDS_IB_EVENT_STRING(QP_REQ_ERR),
+ RDS_IB_EVENT_STRING(QP_ACCESS_ERR),
+ RDS_IB_EVENT_STRING(COMM_EST),
+ RDS_IB_EVENT_STRING(SQ_DRAINED),
+ RDS_IB_EVENT_STRING(PATH_MIG),
+ RDS_IB_EVENT_STRING(PATH_MIG_ERR),
+ RDS_IB_EVENT_STRING(DEVICE_FATAL),
+ RDS_IB_EVENT_STRING(PORT_ACTIVE),
+ RDS_IB_EVENT_STRING(PORT_ERR),
+ RDS_IB_EVENT_STRING(LID_CHANGE),
+ RDS_IB_EVENT_STRING(PKEY_CHANGE),
+ RDS_IB_EVENT_STRING(SM_CHANGE),
+ RDS_IB_EVENT_STRING(SRQ_ERR),
+ RDS_IB_EVENT_STRING(SRQ_LIMIT_REACHED),
+ RDS_IB_EVENT_STRING(QP_LAST_WQE_REACHED),
+ RDS_IB_EVENT_STRING(CLIENT_REREGISTER),
+#undef RDS_IB_EVENT_STRING
+};
+
+static char *rds_ib_event_str(enum ib_event_type type)
+{
+ return rds_str_array(rds_ib_event_type_strings,
+ ARRAY_SIZE(rds_ib_event_type_strings), type);
+};
+
/*
* Set the selected protocol version
*/
@@ -95,7 +125,6 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
{
const struct rds_ib_connect_private *dp = NULL;
struct rds_ib_connection *ic = conn->c_transport_data;
- struct rds_ib_device *rds_ibdev;
struct ib_qp_attr qp_attr;
int err;
@@ -111,11 +140,21 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
}
}
- printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n",
- &conn->c_faddr,
- RDS_PROTOCOL_MAJOR(conn->c_version),
- RDS_PROTOCOL_MINOR(conn->c_version),
- ic->i_flowctl ? ", flow control" : "");
+ if (conn->c_version < RDS_PROTOCOL(3,1)) {
+ printk(KERN_NOTICE "RDS/IB: Connection to %pI4 version %u.%u failed,"
+ " no longer supported\n",
+ &conn->c_faddr,
+ RDS_PROTOCOL_MAJOR(conn->c_version),
+ RDS_PROTOCOL_MINOR(conn->c_version));
+ rds_conn_destroy(conn);
+ return;
+ } else {
+ printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n",
+ &conn->c_faddr,
+ RDS_PROTOCOL_MAJOR(conn->c_version),
+ RDS_PROTOCOL_MINOR(conn->c_version),
+ ic->i_flowctl ? ", flow control" : "");
+ }
/*
* Init rings and fill recv. this needs to wait until protocol negotiation
@@ -125,7 +164,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
rds_ib_recv_init_ring(ic);
/* Post receive buffers - as a side effect, this will update
* the posted credit count. */
- rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 1);
+ rds_ib_recv_refill(conn, 1);
/* Tune RNR behavior */
rds_ib_tune_rnr(ic, &qp_attr);
@@ -135,12 +174,11 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
if (err)
printk(KERN_NOTICE "ib_modify_qp(IB_QP_STATE, RTS): err=%d\n", err);
- /* update ib_device with this local ipaddr & conn */
- rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client);
- err = rds_ib_update_ipaddr(rds_ibdev, conn->c_laddr);
+ /* update ib_device with this local ipaddr */
+ err = rds_ib_update_ipaddr(ic->rds_ibdev, conn->c_laddr);
if (err)
- printk(KERN_ERR "rds_ib_update_ipaddr failed (%d)\n", err);
- rds_ib_add_conn(rds_ibdev, conn);
+ printk(KERN_ERR "rds_ib_update_ipaddr failed (%d)\n",
+ err);
/* If the peer gave us the last packet it saw, process this as if
* we had received a regular ACK. */
@@ -153,18 +191,23 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
static void rds_ib_cm_fill_conn_param(struct rds_connection *conn,
struct rdma_conn_param *conn_param,
struct rds_ib_connect_private *dp,
- u32 protocol_version)
+ u32 protocol_version,
+ u32 max_responder_resources,
+ u32 max_initiator_depth)
{
+ struct rds_ib_connection *ic = conn->c_transport_data;
+ struct rds_ib_device *rds_ibdev = ic->rds_ibdev;
+
memset(conn_param, 0, sizeof(struct rdma_conn_param));
- /* XXX tune these? */
- conn_param->responder_resources = 1;
- conn_param->initiator_depth = 1;
+
+ conn_param->responder_resources =
+ min_t(u32, rds_ibdev->max_responder_resources, max_responder_resources);
+ conn_param->initiator_depth =
+ min_t(u32, rds_ibdev->max_initiator_depth, max_initiator_depth);
conn_param->retry_count = min_t(unsigned int, rds_ib_retry_count, 7);
conn_param->rnr_retry_count = 7;
if (dp) {
- struct rds_ib_connection *ic = conn->c_transport_data;
-
memset(dp, 0, sizeof(*dp));
dp->dp_saddr = conn->c_laddr;
dp->dp_daddr = conn->c_faddr;
@@ -189,7 +232,8 @@ static void rds_ib_cm_fill_conn_param(struct rds_connection *conn,
static void rds_ib_cq_event_handler(struct ib_event *event, void *data)
{
- rdsdebug("event %u data %p\n", event->event, data);
+ rdsdebug("event %u (%s) data %p\n",
+ event->event, rds_ib_event_str(event->event), data);
}
static void rds_ib_qp_event_handler(struct ib_event *event, void *data)
@@ -197,16 +241,18 @@ static void rds_ib_qp_event_handler(struct ib_event *event, void *data)
struct rds_connection *conn = data;
struct rds_ib_connection *ic = conn->c_transport_data;
- rdsdebug("conn %p ic %p event %u\n", conn, ic, event->event);
+ rdsdebug("conn %p ic %p event %u (%s)\n", conn, ic, event->event,
+ rds_ib_event_str(event->event));
switch (event->event) {
case IB_EVENT_COMM_EST:
rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST);
break;
default:
- rdsdebug("Fatal QP Event %u "
+ rdsdebug("Fatal QP Event %u (%s) "
"- connection %pI4->%pI4, reconnecting\n",
- event->event, &conn->c_laddr, &conn->c_faddr);
+ event->event, rds_ib_event_str(event->event),
+ &conn->c_laddr, &conn->c_faddr);
rds_conn_drop(conn);
break;
}
@@ -224,18 +270,16 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
struct rds_ib_device *rds_ibdev;
int ret;
- /* rds_ib_add_one creates a rds_ib_device object per IB device,
- * and allocates a protection domain, memory range and FMR pool
- * for each. If that fails for any reason, it will not register
- * the rds_ibdev at all.
+ /*
+ * It's normal to see a null device if an incoming connection races
+ * with device removal, so we don't print a warning.
*/
- rds_ibdev = ib_get_client_data(dev, &rds_ib_client);
- if (rds_ibdev == NULL) {
- if (printk_ratelimit())
- printk(KERN_NOTICE "RDS/IB: No client_data for device %s\n",
- dev->name);
+ rds_ibdev = rds_ib_get_client_data(dev);
+ if (!rds_ibdev)
return -EOPNOTSUPP;
- }
+
+ /* add the conn now so that connection establishment has the dev */
+ rds_ib_add_conn(rds_ibdev, conn);
if (rds_ibdev->max_wrs < ic->i_send_ring.w_nr + 1)
rds_ib_ring_resize(&ic->i_send_ring, rds_ibdev->max_wrs - 1);
@@ -306,7 +350,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
ic->i_send_ring.w_nr *
sizeof(struct rds_header),
&ic->i_send_hdrs_dma, GFP_KERNEL);
- if (ic->i_send_hdrs == NULL) {
+ if (!ic->i_send_hdrs) {
ret = -ENOMEM;
rdsdebug("ib_dma_alloc_coherent send failed\n");
goto out;
@@ -316,7 +360,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
ic->i_recv_ring.w_nr *
sizeof(struct rds_header),
&ic->i_recv_hdrs_dma, GFP_KERNEL);
- if (ic->i_recv_hdrs == NULL) {
+ if (!ic->i_recv_hdrs) {
ret = -ENOMEM;
rdsdebug("ib_dma_alloc_coherent recv failed\n");
goto out;
@@ -324,22 +368,24 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header),
&ic->i_ack_dma, GFP_KERNEL);
- if (ic->i_ack == NULL) {
+ if (!ic->i_ack) {
ret = -ENOMEM;
rdsdebug("ib_dma_alloc_coherent ack failed\n");
goto out;
}
- ic->i_sends = vmalloc(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work));
- if (ic->i_sends == NULL) {
+ ic->i_sends = vmalloc_node(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work),
+ ibdev_to_node(dev));
+ if (!ic->i_sends) {
ret = -ENOMEM;
rdsdebug("send allocation failed\n");
goto out;
}
memset(ic->i_sends, 0, ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work));
- ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work));
- if (ic->i_recvs == NULL) {
+ ic->i_recvs = vmalloc_node(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work),
+ ibdev_to_node(dev));
+ if (!ic->i_recvs) {
ret = -ENOMEM;
rdsdebug("recv allocation failed\n");
goto out;
@@ -352,6 +398,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
ic->i_send_cq, ic->i_recv_cq);
out:
+ rds_ib_dev_put(rds_ibdev);
return ret;
}
@@ -409,7 +456,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
struct rds_ib_connection *ic = NULL;
struct rdma_conn_param conn_param;
u32 version;
- int err, destroy = 1;
+ int err = 1, destroy = 1;
/* Check whether the remote protocol version matches ours. */
version = rds_ib_protocol_compatible(event);
@@ -448,7 +495,6 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
/* Wait and see - our connect may still be succeeding */
rds_ib_stats_inc(s_ib_connect_raced);
}
- mutex_unlock(&conn->c_cm_lock);
goto out;
}
@@ -475,24 +521,23 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
err = rds_ib_setup_qp(conn);
if (err) {
rds_ib_conn_error(conn, "rds_ib_setup_qp failed (%d)\n", err);
- mutex_unlock(&conn->c_cm_lock);
goto out;
}
- rds_ib_cm_fill_conn_param(conn, &conn_param, &dp_rep, version);
+ rds_ib_cm_fill_conn_param(conn, &conn_param, &dp_rep, version,
+ event->param.conn.responder_resources,
+ event->param.conn.initiator_depth);
/* rdma_accept() calls rdma_reject() internally if it fails */
err = rdma_accept(cm_id, &conn_param);
- mutex_unlock(&conn->c_cm_lock);
- if (err) {
+ if (err)
rds_ib_conn_error(conn, "rdma_accept failed (%d)\n", err);
- goto out;
- }
-
- return 0;
out:
- rdma_reject(cm_id, NULL, 0);
+ if (conn)
+ mutex_unlock(&conn->c_cm_lock);
+ if (err)
+ rdma_reject(cm_id, NULL, 0);
return destroy;
}
@@ -516,8 +561,8 @@ int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id)
goto out;
}
- rds_ib_cm_fill_conn_param(conn, &conn_param, &dp, RDS_PROTOCOL_VERSION);
-
+ rds_ib_cm_fill_conn_param(conn, &conn_param, &dp, RDS_PROTOCOL_VERSION,
+ UINT_MAX, UINT_MAX);
ret = rdma_connect(cm_id, &conn_param);
if (ret)
rds_ib_conn_error(conn, "rdma_connect failed (%d)\n", ret);
@@ -601,9 +646,19 @@ void rds_ib_conn_shutdown(struct rds_connection *conn)
ic->i_cm_id, err);
}
+ /*
+ * We want to wait for tx and rx completion to finish
+ * before we tear down the connection, but we have to be
+ * careful not to get stuck waiting on a send ring that
+ * only has unsignaled sends in it. We've shutdown new
+ * sends before getting here so by waiting for signaled
+ * sends to complete we're ensured that there will be no
+ * more tx processing.
+ */
wait_event(rds_ib_ring_empty_wait,
- rds_ib_ring_empty(&ic->i_send_ring) &&
- rds_ib_ring_empty(&ic->i_recv_ring));
+ rds_ib_ring_empty(&ic->i_recv_ring) &&
+ (atomic_read(&ic->i_signaled_sends) == 0));
+ tasklet_kill(&ic->i_recv_tasklet);
if (ic->i_send_hdrs)
ib_dma_free_coherent(dev,
@@ -654,9 +709,12 @@ void rds_ib_conn_shutdown(struct rds_connection *conn)
BUG_ON(ic->rds_ibdev);
/* Clear pending transmit */
- if (ic->i_rm) {
- rds_message_put(ic->i_rm);
- ic->i_rm = NULL;
+ if (ic->i_data_op) {
+ struct rds_message *rm;
+
+ rm = container_of(ic->i_data_op, struct rds_message, data);
+ rds_message_put(rm);
+ ic->i_data_op = NULL;
}
/* Clear the ACK state */
@@ -690,12 +748,19 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp)
{
struct rds_ib_connection *ic;
unsigned long flags;
+ int ret;
/* XXX too lazy? */
ic = kzalloc(sizeof(struct rds_ib_connection), GFP_KERNEL);
- if (ic == NULL)
+ if (!ic)
return -ENOMEM;
+ ret = rds_ib_recv_alloc_caches(ic);
+ if (ret) {
+ kfree(ic);
+ return ret;
+ }
+
INIT_LIST_HEAD(&ic->ib_node);
tasklet_init(&ic->i_recv_tasklet, rds_ib_recv_tasklet_fn,
(unsigned long) ic);
@@ -703,6 +768,7 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp)
#ifndef KERNEL_HAS_ATOMIC64
spin_lock_init(&ic->i_ack_lock);
#endif
+ atomic_set(&ic->i_signaled_sends, 0);
/*
* rds_ib_conn_shutdown() waits for these to be emptied so they
@@ -744,6 +810,8 @@ void rds_ib_conn_free(void *arg)
list_del(&ic->ib_node);
spin_unlock_irq(lock_ptr);
+ rds_ib_recv_free_caches(ic);
+
kfree(ic);
}
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c
index a54cd63f9e35..18a833c450c8 100644
--- a/net/rds/ib_rdma.c
+++ b/net/rds/ib_rdma.c
@@ -32,11 +32,16 @@
*/
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/rculist.h>
#include "rds.h"
-#include "rdma.h"
#include "ib.h"
+#include "xlist.h"
+static struct workqueue_struct *rds_ib_fmr_wq;
+
+static DEFINE_PER_CPU(unsigned long, clean_list_grace);
+#define CLEAN_LIST_BUSY_BIT 0
/*
* This is stored as mr->r_trans_private.
@@ -45,7 +50,11 @@ struct rds_ib_mr {
struct rds_ib_device *device;
struct rds_ib_mr_pool *pool;
struct ib_fmr *fmr;
- struct list_head list;
+
+ struct xlist_head xlist;
+
+ /* unmap_list is for freeing */
+ struct list_head unmap_list;
unsigned int remap_count;
struct scatterlist *sg;
@@ -59,14 +68,16 @@ struct rds_ib_mr {
*/
struct rds_ib_mr_pool {
struct mutex flush_lock; /* serialize fmr invalidate */
- struct work_struct flush_worker; /* flush worker */
+ struct delayed_work flush_worker; /* flush worker */
- spinlock_t list_lock; /* protect variables below */
atomic_t item_count; /* total # of MRs */
atomic_t dirty_count; /* # dirty of MRs */
- struct list_head drop_list; /* MRs that have reached their max_maps limit */
- struct list_head free_list; /* unused MRs */
- struct list_head clean_list; /* unused & unamapped MRs */
+
+ struct xlist_head drop_list; /* MRs that have reached their max_maps limit */
+ struct xlist_head free_list; /* unused MRs */
+ struct xlist_head clean_list; /* global unused & unamapped MRs */
+ wait_queue_head_t flush_wait;
+
atomic_t free_pinned; /* memory pinned by free MRs */
unsigned long max_items;
unsigned long max_items_soft;
@@ -74,7 +85,7 @@ struct rds_ib_mr_pool {
struct ib_fmr_attr fmr_attr;
};
-static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all);
+static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all, struct rds_ib_mr **);
static void rds_ib_teardown_mr(struct rds_ib_mr *ibmr);
static void rds_ib_mr_pool_flush_worker(struct work_struct *work);
@@ -83,16 +94,17 @@ static struct rds_ib_device *rds_ib_get_device(__be32 ipaddr)
struct rds_ib_device *rds_ibdev;
struct rds_ib_ipaddr *i_ipaddr;
- list_for_each_entry(rds_ibdev, &rds_ib_devices, list) {
- spin_lock_irq(&rds_ibdev->spinlock);
- list_for_each_entry(i_ipaddr, &rds_ibdev->ipaddr_list, list) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(rds_ibdev, &rds_ib_devices, list) {
+ list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) {
if (i_ipaddr->ipaddr == ipaddr) {
- spin_unlock_irq(&rds_ibdev->spinlock);
+ atomic_inc(&rds_ibdev->refcount);
+ rcu_read_unlock();
return rds_ibdev;
}
}
- spin_unlock_irq(&rds_ibdev->spinlock);
}
+ rcu_read_unlock();
return NULL;
}
@@ -108,7 +120,7 @@ static int rds_ib_add_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr)
i_ipaddr->ipaddr = ipaddr;
spin_lock_irq(&rds_ibdev->spinlock);
- list_add_tail(&i_ipaddr->list, &rds_ibdev->ipaddr_list);
+ list_add_tail_rcu(&i_ipaddr->list, &rds_ibdev->ipaddr_list);
spin_unlock_irq(&rds_ibdev->spinlock);
return 0;
@@ -116,17 +128,24 @@ static int rds_ib_add_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr)
static void rds_ib_remove_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr)
{
- struct rds_ib_ipaddr *i_ipaddr, *next;
+ struct rds_ib_ipaddr *i_ipaddr;
+ struct rds_ib_ipaddr *to_free = NULL;
+
spin_lock_irq(&rds_ibdev->spinlock);
- list_for_each_entry_safe(i_ipaddr, next, &rds_ibdev->ipaddr_list, list) {
+ list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) {
if (i_ipaddr->ipaddr == ipaddr) {
- list_del(&i_ipaddr->list);
- kfree(i_ipaddr);
+ list_del_rcu(&i_ipaddr->list);
+ to_free = i_ipaddr;
break;
}
}
spin_unlock_irq(&rds_ibdev->spinlock);
+
+ if (to_free) {
+ synchronize_rcu();
+ kfree(to_free);
+ }
}
int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr)
@@ -134,8 +153,10 @@ int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr)
struct rds_ib_device *rds_ibdev_old;
rds_ibdev_old = rds_ib_get_device(ipaddr);
- if (rds_ibdev_old)
+ if (rds_ibdev_old) {
rds_ib_remove_ipaddr(rds_ibdev_old, ipaddr);
+ rds_ib_dev_put(rds_ibdev_old);
+ }
return rds_ib_add_ipaddr(rds_ibdev, ipaddr);
}
@@ -150,12 +171,13 @@ void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *con
BUG_ON(list_empty(&ic->ib_node));
list_del(&ic->ib_node);
- spin_lock_irq(&rds_ibdev->spinlock);
+ spin_lock(&rds_ibdev->spinlock);
list_add_tail(&ic->ib_node, &rds_ibdev->conn_list);
- spin_unlock_irq(&rds_ibdev->spinlock);
+ spin_unlock(&rds_ibdev->spinlock);
spin_unlock_irq(&ib_nodev_conns_lock);
ic->rds_ibdev = rds_ibdev;
+ atomic_inc(&rds_ibdev->refcount);
}
void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn)
@@ -175,18 +197,18 @@ void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *
spin_unlock(&ib_nodev_conns_lock);
ic->rds_ibdev = NULL;
+ rds_ib_dev_put(rds_ibdev);
}
-void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock)
+void rds_ib_destroy_nodev_conns(void)
{
struct rds_ib_connection *ic, *_ic;
LIST_HEAD(tmp_list);
/* avoid calling conn_destroy with irqs off */
- spin_lock_irq(list_lock);
- list_splice(list, &tmp_list);
- INIT_LIST_HEAD(list);
- spin_unlock_irq(list_lock);
+ spin_lock_irq(&ib_nodev_conns_lock);
+ list_splice(&ib_nodev_conns, &tmp_list);
+ spin_unlock_irq(&ib_nodev_conns_lock);
list_for_each_entry_safe(ic, _ic, &tmp_list, ib_node)
rds_conn_destroy(ic->conn);
@@ -200,12 +222,12 @@ struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_ibdev)
if (!pool)
return ERR_PTR(-ENOMEM);
- INIT_LIST_HEAD(&pool->free_list);
- INIT_LIST_HEAD(&pool->drop_list);
- INIT_LIST_HEAD(&pool->clean_list);
+ INIT_XLIST_HEAD(&pool->free_list);
+ INIT_XLIST_HEAD(&pool->drop_list);
+ INIT_XLIST_HEAD(&pool->clean_list);
mutex_init(&pool->flush_lock);
- spin_lock_init(&pool->list_lock);
- INIT_WORK(&pool->flush_worker, rds_ib_mr_pool_flush_worker);
+ init_waitqueue_head(&pool->flush_wait);
+ INIT_DELAYED_WORK(&pool->flush_worker, rds_ib_mr_pool_flush_worker);
pool->fmr_attr.max_pages = fmr_message_size;
pool->fmr_attr.max_maps = rds_ibdev->fmr_max_remaps;
@@ -233,34 +255,60 @@ void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_co
void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool)
{
- flush_workqueue(rds_wq);
- rds_ib_flush_mr_pool(pool, 1);
+ cancel_delayed_work_sync(&pool->flush_worker);
+ rds_ib_flush_mr_pool(pool, 1, NULL);
WARN_ON(atomic_read(&pool->item_count));
WARN_ON(atomic_read(&pool->free_pinned));
kfree(pool);
}
+static void refill_local(struct rds_ib_mr_pool *pool, struct xlist_head *xl,
+ struct rds_ib_mr **ibmr_ret)
+{
+ struct xlist_head *ibmr_xl;
+ ibmr_xl = xlist_del_head_fast(xl);
+ *ibmr_ret = list_entry(ibmr_xl, struct rds_ib_mr, xlist);
+}
+
static inline struct rds_ib_mr *rds_ib_reuse_fmr(struct rds_ib_mr_pool *pool)
{
struct rds_ib_mr *ibmr = NULL;
- unsigned long flags;
+ struct xlist_head *ret;
+ unsigned long *flag;
- spin_lock_irqsave(&pool->list_lock, flags);
- if (!list_empty(&pool->clean_list)) {
- ibmr = list_entry(pool->clean_list.next, struct rds_ib_mr, list);
- list_del_init(&ibmr->list);
- }
- spin_unlock_irqrestore(&pool->list_lock, flags);
+ preempt_disable();
+ flag = &__get_cpu_var(clean_list_grace);
+ set_bit(CLEAN_LIST_BUSY_BIT, flag);
+ ret = xlist_del_head(&pool->clean_list);
+ if (ret)
+ ibmr = list_entry(ret, struct rds_ib_mr, xlist);
+ clear_bit(CLEAN_LIST_BUSY_BIT, flag);
+ preempt_enable();
return ibmr;
}
+static inline void wait_clean_list_grace(void)
+{
+ int cpu;
+ unsigned long *flag;
+
+ for_each_online_cpu(cpu) {
+ flag = &per_cpu(clean_list_grace, cpu);
+ while (test_bit(CLEAN_LIST_BUSY_BIT, flag))
+ cpu_relax();
+ }
+}
+
static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev)
{
struct rds_ib_mr_pool *pool = rds_ibdev->mr_pool;
struct rds_ib_mr *ibmr = NULL;
int err = 0, iter = 0;
+ if (atomic_read(&pool->dirty_count) >= pool->max_items / 10)
+ queue_delayed_work(rds_ib_fmr_wq, &pool->flush_worker, 10);
+
while (1) {
ibmr = rds_ib_reuse_fmr(pool);
if (ibmr)
@@ -287,19 +335,24 @@ static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev)
/* We do have some empty MRs. Flush them out. */
rds_ib_stats_inc(s_ib_rdma_mr_pool_wait);
- rds_ib_flush_mr_pool(pool, 0);
+ rds_ib_flush_mr_pool(pool, 0, &ibmr);
+ if (ibmr)
+ return ibmr;
}
- ibmr = kzalloc(sizeof(*ibmr), GFP_KERNEL);
+ ibmr = kzalloc_node(sizeof(*ibmr), GFP_KERNEL, rdsibdev_to_node(rds_ibdev));
if (!ibmr) {
err = -ENOMEM;
goto out_no_cigar;
}
+ memset(ibmr, 0, sizeof(*ibmr));
+
ibmr->fmr = ib_alloc_fmr(rds_ibdev->pd,
(IB_ACCESS_LOCAL_WRITE |
IB_ACCESS_REMOTE_READ |
- IB_ACCESS_REMOTE_WRITE),
+ IB_ACCESS_REMOTE_WRITE|
+ IB_ACCESS_REMOTE_ATOMIC),
&pool->fmr_attr);
if (IS_ERR(ibmr->fmr)) {
err = PTR_ERR(ibmr->fmr);
@@ -367,7 +420,8 @@ static int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev, struct rds_ib_mr *ibm
if (page_cnt > fmr_message_size)
return -EINVAL;
- dma_pages = kmalloc(sizeof(u64) * page_cnt, GFP_ATOMIC);
+ dma_pages = kmalloc_node(sizeof(u64) * page_cnt, GFP_ATOMIC,
+ rdsibdev_to_node(rds_ibdev));
if (!dma_pages)
return -ENOMEM;
@@ -441,7 +495,7 @@ static void __rds_ib_teardown_mr(struct rds_ib_mr *ibmr)
/* FIXME we need a way to tell a r/w MR
* from a r/o MR */
- BUG_ON(in_interrupt());
+ BUG_ON(irqs_disabled());
set_page_dirty(page);
put_page(page);
}
@@ -477,33 +531,109 @@ static inline unsigned int rds_ib_flush_goal(struct rds_ib_mr_pool *pool, int fr
}
/*
+ * given an xlist of mrs, put them all into the list_head for more processing
+ */
+static void xlist_append_to_list(struct xlist_head *xlist, struct list_head *list)
+{
+ struct rds_ib_mr *ibmr;
+ struct xlist_head splice;
+ struct xlist_head *cur;
+ struct xlist_head *next;
+
+ splice.next = NULL;
+ xlist_splice(xlist, &splice);
+ cur = splice.next;
+ while (cur) {
+ next = cur->next;
+ ibmr = list_entry(cur, struct rds_ib_mr, xlist);
+ list_add_tail(&ibmr->unmap_list, list);
+ cur = next;
+ }
+}
+
+/*
+ * this takes a list head of mrs and turns it into an xlist of clusters.
+ * each cluster has an xlist of MR_CLUSTER_SIZE mrs that are ready for
+ * reuse.
+ */
+static void list_append_to_xlist(struct rds_ib_mr_pool *pool,
+ struct list_head *list, struct xlist_head *xlist,
+ struct xlist_head **tail_ret)
+{
+ struct rds_ib_mr *ibmr;
+ struct xlist_head *cur_mr = xlist;
+ struct xlist_head *tail_mr = NULL;
+
+ list_for_each_entry(ibmr, list, unmap_list) {
+ tail_mr = &ibmr->xlist;
+ tail_mr->next = NULL;
+ cur_mr->next = tail_mr;
+ cur_mr = tail_mr;
+ }
+ *tail_ret = tail_mr;
+}
+
+/*
* Flush our pool of MRs.
* At a minimum, all currently unused MRs are unmapped.
* If the number of MRs allocated exceeds the limit, we also try
* to free as many MRs as needed to get back to this limit.
*/
-static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all)
+static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool,
+ int free_all, struct rds_ib_mr **ibmr_ret)
{
struct rds_ib_mr *ibmr, *next;
+ struct xlist_head clean_xlist;
+ struct xlist_head *clean_tail;
LIST_HEAD(unmap_list);
LIST_HEAD(fmr_list);
unsigned long unpinned = 0;
- unsigned long flags;
unsigned int nfreed = 0, ncleaned = 0, free_goal;
int ret = 0;
rds_ib_stats_inc(s_ib_rdma_mr_pool_flush);
- mutex_lock(&pool->flush_lock);
+ if (ibmr_ret) {
+ DEFINE_WAIT(wait);
+ while(!mutex_trylock(&pool->flush_lock)) {
+ ibmr = rds_ib_reuse_fmr(pool);
+ if (ibmr) {
+ *ibmr_ret = ibmr;
+ finish_wait(&pool->flush_wait, &wait);
+ goto out_nolock;
+ }
+
+ prepare_to_wait(&pool->flush_wait, &wait,
+ TASK_UNINTERRUPTIBLE);
+ if (xlist_empty(&pool->clean_list))
+ schedule();
+
+ ibmr = rds_ib_reuse_fmr(pool);
+ if (ibmr) {
+ *ibmr_ret = ibmr;
+ finish_wait(&pool->flush_wait, &wait);
+ goto out_nolock;
+ }
+ }
+ finish_wait(&pool->flush_wait, &wait);
+ } else
+ mutex_lock(&pool->flush_lock);
+
+ if (ibmr_ret) {
+ ibmr = rds_ib_reuse_fmr(pool);
+ if (ibmr) {
+ *ibmr_ret = ibmr;
+ goto out;
+ }
+ }
- spin_lock_irqsave(&pool->list_lock, flags);
/* Get the list of all MRs to be dropped. Ordering matters -
- * we want to put drop_list ahead of free_list. */
- list_splice_init(&pool->free_list, &unmap_list);
- list_splice_init(&pool->drop_list, &unmap_list);
+ * we want to put drop_list ahead of free_list.
+ */
+ xlist_append_to_list(&pool->drop_list, &unmap_list);
+ xlist_append_to_list(&pool->free_list, &unmap_list);
if (free_all)
- list_splice_init(&pool->clean_list, &unmap_list);
- spin_unlock_irqrestore(&pool->list_lock, flags);
+ xlist_append_to_list(&pool->clean_list, &unmap_list);
free_goal = rds_ib_flush_goal(pool, free_all);
@@ -511,19 +641,20 @@ static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all)
goto out;
/* String all ib_mr's onto one list and hand them to ib_unmap_fmr */
- list_for_each_entry(ibmr, &unmap_list, list)
+ list_for_each_entry(ibmr, &unmap_list, unmap_list)
list_add(&ibmr->fmr->list, &fmr_list);
+
ret = ib_unmap_fmr(&fmr_list);
if (ret)
printk(KERN_WARNING "RDS/IB: ib_unmap_fmr failed (err=%d)\n", ret);
/* Now we can destroy the DMA mapping and unpin any pages */
- list_for_each_entry_safe(ibmr, next, &unmap_list, list) {
+ list_for_each_entry_safe(ibmr, next, &unmap_list, unmap_list) {
unpinned += ibmr->sg_len;
__rds_ib_teardown_mr(ibmr);
if (nfreed < free_goal || ibmr->remap_count >= pool->fmr_attr.max_maps) {
rds_ib_stats_inc(s_ib_rdma_mr_free);
- list_del(&ibmr->list);
+ list_del(&ibmr->unmap_list);
ib_dealloc_fmr(ibmr->fmr);
kfree(ibmr);
nfreed++;
@@ -531,9 +662,27 @@ static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all)
ncleaned++;
}
- spin_lock_irqsave(&pool->list_lock, flags);
- list_splice(&unmap_list, &pool->clean_list);
- spin_unlock_irqrestore(&pool->list_lock, flags);
+ if (!list_empty(&unmap_list)) {
+ /* we have to make sure that none of the things we're about
+ * to put on the clean list would race with other cpus trying
+ * to pull items off. The xlist would explode if we managed to
+ * remove something from the clean list and then add it back again
+ * while another CPU was spinning on that same item in xlist_del_head.
+ *
+ * This is pretty unlikely, but just in case wait for an xlist grace period
+ * here before adding anything back into the clean list.
+ */
+ wait_clean_list_grace();
+
+ list_append_to_xlist(pool, &unmap_list, &clean_xlist, &clean_tail);
+ if (ibmr_ret)
+ refill_local(pool, &clean_xlist, ibmr_ret);
+
+ /* refill_local may have emptied our list */
+ if (!xlist_empty(&clean_xlist))
+ xlist_add(clean_xlist.next, clean_tail, &pool->clean_list);
+
+ }
atomic_sub(unpinned, &pool->free_pinned);
atomic_sub(ncleaned, &pool->dirty_count);
@@ -541,14 +690,35 @@ static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all)
out:
mutex_unlock(&pool->flush_lock);
+ if (waitqueue_active(&pool->flush_wait))
+ wake_up(&pool->flush_wait);
+out_nolock:
return ret;
}
+int rds_ib_fmr_init(void)
+{
+ rds_ib_fmr_wq = create_workqueue("rds_fmr_flushd");
+ if (!rds_ib_fmr_wq)
+ return -ENOMEM;
+ return 0;
+}
+
+/*
+ * By the time this is called all the IB devices should have been torn down and
+ * had their pools freed. As each pool is freed its work struct is waited on,
+ * so the pool flushing work queue should be idle by the time we get here.
+ */
+void rds_ib_fmr_exit(void)
+{
+ destroy_workqueue(rds_ib_fmr_wq);
+}
+
static void rds_ib_mr_pool_flush_worker(struct work_struct *work)
{
- struct rds_ib_mr_pool *pool = container_of(work, struct rds_ib_mr_pool, flush_worker);
+ struct rds_ib_mr_pool *pool = container_of(work, struct rds_ib_mr_pool, flush_worker.work);
- rds_ib_flush_mr_pool(pool, 0);
+ rds_ib_flush_mr_pool(pool, 0, NULL);
}
void rds_ib_free_mr(void *trans_private, int invalidate)
@@ -556,47 +726,49 @@ void rds_ib_free_mr(void *trans_private, int invalidate)
struct rds_ib_mr *ibmr = trans_private;
struct rds_ib_device *rds_ibdev = ibmr->device;
struct rds_ib_mr_pool *pool = rds_ibdev->mr_pool;
- unsigned long flags;
rdsdebug("RDS/IB: free_mr nents %u\n", ibmr->sg_len);
/* Return it to the pool's free list */
- spin_lock_irqsave(&pool->list_lock, flags);
if (ibmr->remap_count >= pool->fmr_attr.max_maps)
- list_add(&ibmr->list, &pool->drop_list);
+ xlist_add(&ibmr->xlist, &ibmr->xlist, &pool->drop_list);
else
- list_add(&ibmr->list, &pool->free_list);
+ xlist_add(&ibmr->xlist, &ibmr->xlist, &pool->free_list);
atomic_add(ibmr->sg_len, &pool->free_pinned);
atomic_inc(&pool->dirty_count);
- spin_unlock_irqrestore(&pool->list_lock, flags);
/* If we've pinned too many pages, request a flush */
if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned ||
atomic_read(&pool->dirty_count) >= pool->max_items / 10)
- queue_work(rds_wq, &pool->flush_worker);
+ queue_delayed_work(rds_ib_fmr_wq, &pool->flush_worker, 10);
if (invalidate) {
if (likely(!in_interrupt())) {
- rds_ib_flush_mr_pool(pool, 0);
+ rds_ib_flush_mr_pool(pool, 0, NULL);
} else {
/* We get here if the user created a MR marked
* as use_once and invalidate at the same time. */
- queue_work(rds_wq, &pool->flush_worker);
+ queue_delayed_work(rds_ib_fmr_wq,
+ &pool->flush_worker, 10);
}
}
+
+ rds_ib_dev_put(rds_ibdev);
}
void rds_ib_flush_mrs(void)
{
struct rds_ib_device *rds_ibdev;
+ down_read(&rds_ib_devices_lock);
list_for_each_entry(rds_ibdev, &rds_ib_devices, list) {
struct rds_ib_mr_pool *pool = rds_ibdev->mr_pool;
if (pool)
- rds_ib_flush_mr_pool(pool, 0);
+ rds_ib_flush_mr_pool(pool, 0, NULL);
}
+ up_read(&rds_ib_devices_lock);
}
void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents,
@@ -628,6 +800,7 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents,
printk(KERN_WARNING "RDS/IB: map_fmr failed (errno=%d)\n", ret);
ibmr->device = rds_ibdev;
+ rds_ibdev = NULL;
out:
if (ret) {
@@ -635,5 +808,8 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents,
rds_ib_free_mr(ibmr, 0);
ibmr = ERR_PTR(ret);
}
+ if (rds_ibdev)
+ rds_ib_dev_put(rds_ibdev);
return ibmr;
}
+
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index c74e9904a6b2..e29e0ca32f74 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -43,42 +43,6 @@ static struct kmem_cache *rds_ib_incoming_slab;
static struct kmem_cache *rds_ib_frag_slab;
static atomic_t rds_ib_allocation = ATOMIC_INIT(0);
-static void rds_ib_frag_drop_page(struct rds_page_frag *frag)
-{
- rdsdebug("frag %p page %p\n", frag, frag->f_page);
- __free_page(frag->f_page);
- frag->f_page = NULL;
-}
-
-static void rds_ib_frag_free(struct rds_page_frag *frag)
-{
- rdsdebug("frag %p page %p\n", frag, frag->f_page);
- BUG_ON(frag->f_page != NULL);
- kmem_cache_free(rds_ib_frag_slab, frag);
-}
-
-/*
- * We map a page at a time. Its fragments are posted in order. This
- * is called in fragment order as the fragments get send completion events.
- * Only the last frag in the page performs the unmapping.
- *
- * It's OK for ring cleanup to call this in whatever order it likes because
- * DMA is not in flight and so we can unmap while other ring entries still
- * hold page references in their frags.
- */
-static void rds_ib_recv_unmap_page(struct rds_ib_connection *ic,
- struct rds_ib_recv_work *recv)
-{
- struct rds_page_frag *frag = recv->r_frag;
-
- rdsdebug("recv %p frag %p page %p\n", recv, frag, frag->f_page);
- if (frag->f_mapped)
- ib_dma_unmap_page(ic->i_cm_id->device,
- frag->f_mapped,
- RDS_FRAG_SIZE, DMA_FROM_DEVICE);
- frag->f_mapped = 0;
-}
-
void rds_ib_recv_init_ring(struct rds_ib_connection *ic)
{
struct rds_ib_recv_work *recv;
@@ -95,16 +59,161 @@ void rds_ib_recv_init_ring(struct rds_ib_connection *ic)
recv->r_wr.sg_list = recv->r_sge;
recv->r_wr.num_sge = RDS_IB_RECV_SGE;
- sge = rds_ib_data_sge(ic, recv->r_sge);
+ sge = &recv->r_sge[0];
+ sge->addr = ic->i_recv_hdrs_dma + (i * sizeof(struct rds_header));
+ sge->length = sizeof(struct rds_header);
+ sge->lkey = ic->i_mr->lkey;
+
+ sge = &recv->r_sge[1];
sge->addr = 0;
sge->length = RDS_FRAG_SIZE;
sge->lkey = ic->i_mr->lkey;
+ }
+}
- sge = rds_ib_header_sge(ic, recv->r_sge);
- sge->addr = ic->i_recv_hdrs_dma + (i * sizeof(struct rds_header));
- sge->length = sizeof(struct rds_header);
- sge->lkey = ic->i_mr->lkey;
+/*
+ * The entire 'from' list, including the from element itself, is put on
+ * to the tail of the 'to' list.
+ */
+static void list_splice_entire_tail(struct list_head *from,
+ struct list_head *to)
+{
+ struct list_head *from_last = from->prev;
+
+ list_splice_tail(from_last, to);
+ list_add_tail(from_last, to);
+}
+
+static void rds_ib_cache_xfer_to_ready(struct rds_ib_refill_cache *cache)
+{
+ struct list_head *tmp;
+
+ tmp = xchg(&cache->xfer, NULL);
+ if (tmp) {
+ if (cache->ready)
+ list_splice_entire_tail(tmp, cache->ready);
+ else
+ cache->ready = tmp;
+ }
+}
+
+static int rds_ib_recv_alloc_cache(struct rds_ib_refill_cache *cache)
+{
+ struct rds_ib_cache_head *head;
+ int cpu;
+
+ cache->percpu = alloc_percpu(struct rds_ib_cache_head);
+ if (!cache->percpu)
+ return -ENOMEM;
+
+ for_each_possible_cpu(cpu) {
+ head = per_cpu_ptr(cache->percpu, cpu);
+ head->first = NULL;
+ head->count = 0;
+ }
+ cache->xfer = NULL;
+ cache->ready = NULL;
+
+ return 0;
+}
+
+int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic)
+{
+ int ret;
+
+ ret = rds_ib_recv_alloc_cache(&ic->i_cache_incs);
+ if (!ret) {
+ ret = rds_ib_recv_alloc_cache(&ic->i_cache_frags);
+ if (ret)
+ free_percpu(ic->i_cache_incs.percpu);
}
+
+ return ret;
+}
+
+static void rds_ib_cache_splice_all_lists(struct rds_ib_refill_cache *cache,
+ struct list_head *caller_list)
+{
+ struct rds_ib_cache_head *head;
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ head = per_cpu_ptr(cache->percpu, cpu);
+ if (head->first) {
+ list_splice_entire_tail(head->first, caller_list);
+ head->first = NULL;
+ }
+ }
+
+ if (cache->ready) {
+ list_splice_entire_tail(cache->ready, caller_list);
+ cache->ready = NULL;
+ }
+}
+
+void rds_ib_recv_free_caches(struct rds_ib_connection *ic)
+{
+ struct rds_ib_incoming *inc;
+ struct rds_ib_incoming *inc_tmp;
+ struct rds_page_frag *frag;
+ struct rds_page_frag *frag_tmp;
+ LIST_HEAD(list);
+
+ rds_ib_cache_xfer_to_ready(&ic->i_cache_incs);
+ rds_ib_cache_splice_all_lists(&ic->i_cache_incs, &list);
+ free_percpu(ic->i_cache_incs.percpu);
+
+ list_for_each_entry_safe(inc, inc_tmp, &list, ii_cache_entry) {
+ list_del(&inc->ii_cache_entry);
+ WARN_ON(!list_empty(&inc->ii_frags));
+ kmem_cache_free(rds_ib_incoming_slab, inc);
+ }
+
+ rds_ib_cache_xfer_to_ready(&ic->i_cache_frags);
+ rds_ib_cache_splice_all_lists(&ic->i_cache_frags, &list);
+ free_percpu(ic->i_cache_frags.percpu);
+
+ list_for_each_entry_safe(frag, frag_tmp, &list, f_cache_entry) {
+ list_del(&frag->f_cache_entry);
+ WARN_ON(!list_empty(&frag->f_item));
+ kmem_cache_free(rds_ib_frag_slab, frag);
+ }
+}
+
+/* fwd decl */
+static void rds_ib_recv_cache_put(struct list_head *new_item,
+ struct rds_ib_refill_cache *cache);
+static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache);
+
+
+/* Recycle frag and attached recv buffer f_sg */
+static void rds_ib_frag_free(struct rds_ib_connection *ic,
+ struct rds_page_frag *frag)
+{
+ rdsdebug("frag %p page %p\n", frag, sg_page(&frag->f_sg));
+
+ rds_ib_recv_cache_put(&frag->f_cache_entry, &ic->i_cache_frags);
+}
+
+/* Recycle inc after freeing attached frags */
+void rds_ib_inc_free(struct rds_incoming *inc)
+{
+ struct rds_ib_incoming *ibinc;
+ struct rds_page_frag *frag;
+ struct rds_page_frag *pos;
+ struct rds_ib_connection *ic = inc->i_conn->c_transport_data;
+
+ ibinc = container_of(inc, struct rds_ib_incoming, ii_inc);
+
+ /* Free attached frags */
+ list_for_each_entry_safe(frag, pos, &ibinc->ii_frags, f_item) {
+ list_del_init(&frag->f_item);
+ rds_ib_frag_free(ic, frag);
+ }
+ BUG_ON(!list_empty(&ibinc->ii_frags));
+
+ rdsdebug("freeing ibinc %p inc %p\n", ibinc, inc);
+ rds_ib_recv_cache_put(&ibinc->ii_cache_entry, &ic->i_cache_incs);
}
static void rds_ib_recv_clear_one(struct rds_ib_connection *ic,
@@ -115,10 +224,8 @@ static void rds_ib_recv_clear_one(struct rds_ib_connection *ic,
recv->r_ibinc = NULL;
}
if (recv->r_frag) {
- rds_ib_recv_unmap_page(ic, recv);
- if (recv->r_frag->f_page)
- rds_ib_frag_drop_page(recv->r_frag);
- rds_ib_frag_free(recv->r_frag);
+ ib_dma_unmap_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, 1, DMA_FROM_DEVICE);
+ rds_ib_frag_free(ic, recv->r_frag);
recv->r_frag = NULL;
}
}
@@ -129,84 +236,111 @@ void rds_ib_recv_clear_ring(struct rds_ib_connection *ic)
for (i = 0; i < ic->i_recv_ring.w_nr; i++)
rds_ib_recv_clear_one(ic, &ic->i_recvs[i]);
-
- if (ic->i_frag.f_page)
- rds_ib_frag_drop_page(&ic->i_frag);
}
-static int rds_ib_recv_refill_one(struct rds_connection *conn,
- struct rds_ib_recv_work *recv,
- gfp_t kptr_gfp, gfp_t page_gfp)
+static struct rds_ib_incoming *rds_ib_refill_one_inc(struct rds_ib_connection *ic,
+ gfp_t slab_mask)
{
- struct rds_ib_connection *ic = conn->c_transport_data;
- dma_addr_t dma_addr;
- struct ib_sge *sge;
- int ret = -ENOMEM;
+ struct rds_ib_incoming *ibinc;
+ struct list_head *cache_item;
+ int avail_allocs;
- if (recv->r_ibinc == NULL) {
- if (!atomic_add_unless(&rds_ib_allocation, 1, rds_ib_sysctl_max_recv_allocation)) {
+ cache_item = rds_ib_recv_cache_get(&ic->i_cache_incs);
+ if (cache_item) {
+ ibinc = container_of(cache_item, struct rds_ib_incoming, ii_cache_entry);
+ } else {
+ avail_allocs = atomic_add_unless(&rds_ib_allocation,
+ 1, rds_ib_sysctl_max_recv_allocation);
+ if (!avail_allocs) {
rds_ib_stats_inc(s_ib_rx_alloc_limit);
- goto out;
+ return NULL;
}
- recv->r_ibinc = kmem_cache_alloc(rds_ib_incoming_slab,
- kptr_gfp);
- if (recv->r_ibinc == NULL) {
+ ibinc = kmem_cache_alloc(rds_ib_incoming_slab, slab_mask);
+ if (!ibinc) {
atomic_dec(&rds_ib_allocation);
- goto out;
+ return NULL;
}
- INIT_LIST_HEAD(&recv->r_ibinc->ii_frags);
- rds_inc_init(&recv->r_ibinc->ii_inc, conn, conn->c_faddr);
}
+ INIT_LIST_HEAD(&ibinc->ii_frags);
+ rds_inc_init(&ibinc->ii_inc, ic->conn, ic->conn->c_faddr);
- if (recv->r_frag == NULL) {
- recv->r_frag = kmem_cache_alloc(rds_ib_frag_slab, kptr_gfp);
- if (recv->r_frag == NULL)
- goto out;
- INIT_LIST_HEAD(&recv->r_frag->f_item);
- recv->r_frag->f_page = NULL;
+ return ibinc;
+}
+
+static struct rds_page_frag *rds_ib_refill_one_frag(struct rds_ib_connection *ic,
+ gfp_t slab_mask, gfp_t page_mask)
+{
+ struct rds_page_frag *frag;
+ struct list_head *cache_item;
+ int ret;
+
+ cache_item = rds_ib_recv_cache_get(&ic->i_cache_frags);
+ if (cache_item) {
+ frag = container_of(cache_item, struct rds_page_frag, f_cache_entry);
+ } else {
+ frag = kmem_cache_alloc(rds_ib_frag_slab, slab_mask);
+ if (!frag)
+ return NULL;
+
+ sg_init_table(&frag->f_sg, 1);
+ ret = rds_page_remainder_alloc(&frag->f_sg,
+ RDS_FRAG_SIZE, page_mask);
+ if (ret) {
+ kmem_cache_free(rds_ib_frag_slab, frag);
+ return NULL;
+ }
}
- if (ic->i_frag.f_page == NULL) {
- ic->i_frag.f_page = alloc_page(page_gfp);
- if (ic->i_frag.f_page == NULL)
- goto out;
- ic->i_frag.f_offset = 0;
+ INIT_LIST_HEAD(&frag->f_item);
+
+ return frag;
+}
+
+static int rds_ib_recv_refill_one(struct rds_connection *conn,
+ struct rds_ib_recv_work *recv, int prefill)
+{
+ struct rds_ib_connection *ic = conn->c_transport_data;
+ struct ib_sge *sge;
+ int ret = -ENOMEM;
+ gfp_t slab_mask = GFP_NOWAIT;
+ gfp_t page_mask = GFP_NOWAIT;
+
+ if (prefill) {
+ slab_mask = GFP_KERNEL;
+ page_mask = GFP_HIGHUSER;
}
- dma_addr = ib_dma_map_page(ic->i_cm_id->device,
- ic->i_frag.f_page,
- ic->i_frag.f_offset,
- RDS_FRAG_SIZE,
- DMA_FROM_DEVICE);
- if (ib_dma_mapping_error(ic->i_cm_id->device, dma_addr))
- goto out;
+ if (!ic->i_cache_incs.ready)
+ rds_ib_cache_xfer_to_ready(&ic->i_cache_incs);
+ if (!ic->i_cache_frags.ready)
+ rds_ib_cache_xfer_to_ready(&ic->i_cache_frags);
/*
- * Once we get the RDS_PAGE_LAST_OFF frag then rds_ib_frag_unmap()
- * must be called on this recv. This happens as completions hit
- * in order or on connection shutdown.
+ * ibinc was taken from recv if recv contained the start of a message.
+ * recvs that were continuations will still have this allocated.
*/
- recv->r_frag->f_page = ic->i_frag.f_page;
- recv->r_frag->f_offset = ic->i_frag.f_offset;
- recv->r_frag->f_mapped = dma_addr;
+ if (!recv->r_ibinc) {
+ recv->r_ibinc = rds_ib_refill_one_inc(ic, slab_mask);
+ if (!recv->r_ibinc)
+ goto out;
+ }
- sge = rds_ib_data_sge(ic, recv->r_sge);
- sge->addr = dma_addr;
- sge->length = RDS_FRAG_SIZE;
+ WARN_ON(recv->r_frag); /* leak! */
+ recv->r_frag = rds_ib_refill_one_frag(ic, slab_mask, page_mask);
+ if (!recv->r_frag)
+ goto out;
+
+ ret = ib_dma_map_sg(ic->i_cm_id->device, &recv->r_frag->f_sg,
+ 1, DMA_FROM_DEVICE);
+ WARN_ON(ret != 1);
- sge = rds_ib_header_sge(ic, recv->r_sge);
+ sge = &recv->r_sge[0];
sge->addr = ic->i_recv_hdrs_dma + (recv - ic->i_recvs) * sizeof(struct rds_header);
sge->length = sizeof(struct rds_header);
- get_page(recv->r_frag->f_page);
-
- if (ic->i_frag.f_offset < RDS_PAGE_LAST_OFF) {
- ic->i_frag.f_offset += RDS_FRAG_SIZE;
- } else {
- put_page(ic->i_frag.f_page);
- ic->i_frag.f_page = NULL;
- ic->i_frag.f_offset = 0;
- }
+ sge = &recv->r_sge[1];
+ sge->addr = sg_dma_address(&recv->r_frag->f_sg);
+ sge->length = sg_dma_len(&recv->r_frag->f_sg);
ret = 0;
out:
@@ -216,13 +350,11 @@ out:
/*
* This tries to allocate and post unused work requests after making sure that
* they have all the allocations they need to queue received fragments into
- * sockets. The i_recv_mutex is held here so that ring_alloc and _unalloc
- * pairs don't go unmatched.
+ * sockets.
*
* -1 is returned if posting fails due to temporary resource exhaustion.
*/
-int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp,
- gfp_t page_gfp, int prefill)
+void rds_ib_recv_refill(struct rds_connection *conn, int prefill)
{
struct rds_ib_connection *ic = conn->c_transport_data;
struct rds_ib_recv_work *recv;
@@ -236,28 +368,25 @@ int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp,
if (pos >= ic->i_recv_ring.w_nr) {
printk(KERN_NOTICE "Argh - ring alloc returned pos=%u\n",
pos);
- ret = -EINVAL;
break;
}
recv = &ic->i_recvs[pos];
- ret = rds_ib_recv_refill_one(conn, recv, kptr_gfp, page_gfp);
+ ret = rds_ib_recv_refill_one(conn, recv, prefill);
if (ret) {
- ret = -1;
break;
}
/* XXX when can this fail? */
ret = ib_post_recv(ic->i_cm_id->qp, &recv->r_wr, &failed_wr);
rdsdebug("recv %p ibinc %p page %p addr %lu ret %d\n", recv,
- recv->r_ibinc, recv->r_frag->f_page,
- (long) recv->r_frag->f_mapped, ret);
+ recv->r_ibinc, sg_page(&recv->r_frag->f_sg),
+ (long) sg_dma_address(&recv->r_frag->f_sg), ret);
if (ret) {
rds_ib_conn_error(conn, "recv post on "
"%pI4 returned %d, disconnecting and "
"reconnecting\n", &conn->c_faddr,
ret);
- ret = -1;
break;
}
@@ -270,37 +399,73 @@ int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp,
if (ret)
rds_ib_ring_unalloc(&ic->i_recv_ring, 1);
- return ret;
}
-void rds_ib_inc_purge(struct rds_incoming *inc)
+/*
+ * We want to recycle several types of recv allocations, like incs and frags.
+ * To use this, the *_free() function passes in the ptr to a list_head within
+ * the recyclee, as well as the cache to put it on.
+ *
+ * First, we put the memory on a percpu list. When this reaches a certain size,
+ * We move it to an intermediate non-percpu list in a lockless manner, with some
+ * xchg/compxchg wizardry.
+ *
+ * N.B. Instead of a list_head as the anchor, we use a single pointer, which can
+ * be NULL and xchg'd. The list is actually empty when the pointer is NULL, and
+ * list_empty() will return true with one element is actually present.
+ */
+static void rds_ib_recv_cache_put(struct list_head *new_item,
+ struct rds_ib_refill_cache *cache)
{
- struct rds_ib_incoming *ibinc;
- struct rds_page_frag *frag;
- struct rds_page_frag *pos;
+ unsigned long flags;
+ struct rds_ib_cache_head *chp;
+ struct list_head *old;
- ibinc = container_of(inc, struct rds_ib_incoming, ii_inc);
- rdsdebug("purging ibinc %p inc %p\n", ibinc, inc);
+ local_irq_save(flags);
- list_for_each_entry_safe(frag, pos, &ibinc->ii_frags, f_item) {
- list_del_init(&frag->f_item);
- rds_ib_frag_drop_page(frag);
- rds_ib_frag_free(frag);
- }
+ chp = per_cpu_ptr(cache->percpu, smp_processor_id());
+ if (!chp->first)
+ INIT_LIST_HEAD(new_item);
+ else /* put on front */
+ list_add_tail(new_item, chp->first);
+ chp->first = new_item;
+ chp->count++;
+
+ if (chp->count < RDS_IB_RECYCLE_BATCH_COUNT)
+ goto end;
+
+ /*
+ * Return our per-cpu first list to the cache's xfer by atomically
+ * grabbing the current xfer list, appending it to our per-cpu list,
+ * and then atomically returning that entire list back to the
+ * cache's xfer list as long as it's still empty.
+ */
+ do {
+ old = xchg(&cache->xfer, NULL);
+ if (old)
+ list_splice_entire_tail(old, chp->first);
+ old = cmpxchg(&cache->xfer, NULL, chp->first);
+ } while (old);
+
+ chp->first = NULL;
+ chp->count = 0;
+end:
+ local_irq_restore(flags);
}
-void rds_ib_inc_free(struct rds_incoming *inc)
+static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache)
{
- struct rds_ib_incoming *ibinc;
-
- ibinc = container_of(inc, struct rds_ib_incoming, ii_inc);
+ struct list_head *head = cache->ready;
+
+ if (head) {
+ if (!list_empty(head)) {
+ cache->ready = head->next;
+ list_del_init(head);
+ } else
+ cache->ready = NULL;
+ }
- rds_ib_inc_purge(inc);
- rdsdebug("freeing ibinc %p inc %p\n", ibinc, inc);
- BUG_ON(!list_empty(&ibinc->ii_frags));
- kmem_cache_free(rds_ib_incoming_slab, ibinc);
- atomic_dec(&rds_ib_allocation);
- BUG_ON(atomic_read(&rds_ib_allocation) < 0);
+ return head;
}
int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
@@ -336,13 +501,13 @@ int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
to_copy = min_t(unsigned long, to_copy, len - copied);
rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag "
- "[%p, %lu] + %lu\n",
+ "[%p, %u] + %lu\n",
to_copy, iov->iov_base, iov->iov_len, iov_off,
- frag->f_page, frag->f_offset, frag_off);
+ sg_page(&frag->f_sg), frag->f_sg.offset, frag_off);
/* XXX needs + offset for multiple recvs per page */
- ret = rds_page_copy_to_user(frag->f_page,
- frag->f_offset + frag_off,
+ ret = rds_page_copy_to_user(sg_page(&frag->f_sg),
+ frag->f_sg.offset + frag_off,
iov->iov_base + iov_off,
to_copy);
if (ret) {
@@ -557,47 +722,6 @@ u64 rds_ib_piggyb_ack(struct rds_ib_connection *ic)
return rds_ib_get_ack(ic);
}
-static struct rds_header *rds_ib_get_header(struct rds_connection *conn,
- struct rds_ib_recv_work *recv,
- u32 data_len)
-{
- struct rds_ib_connection *ic = conn->c_transport_data;
- void *hdr_buff = &ic->i_recv_hdrs[recv - ic->i_recvs];
- void *addr;
- u32 misplaced_hdr_bytes;
-
- /*
- * Support header at the front (RDS 3.1+) as well as header-at-end.
- *
- * Cases:
- * 1) header all in header buff (great!)
- * 2) header all in data page (copy all to header buff)
- * 3) header split across hdr buf + data page
- * (move bit in hdr buff to end before copying other bit from data page)
- */
- if (conn->c_version > RDS_PROTOCOL_3_0 || data_len == RDS_FRAG_SIZE)
- return hdr_buff;
-
- if (data_len <= (RDS_FRAG_SIZE - sizeof(struct rds_header))) {
- addr = kmap_atomic(recv->r_frag->f_page, KM_SOFTIRQ0);
- memcpy(hdr_buff,
- addr + recv->r_frag->f_offset + data_len,
- sizeof(struct rds_header));
- kunmap_atomic(addr, KM_SOFTIRQ0);
- return hdr_buff;
- }
-
- misplaced_hdr_bytes = (sizeof(struct rds_header) - (RDS_FRAG_SIZE - data_len));
-
- memmove(hdr_buff + misplaced_hdr_bytes, hdr_buff, misplaced_hdr_bytes);
-
- addr = kmap_atomic(recv->r_frag->f_page, KM_SOFTIRQ0);
- memcpy(hdr_buff, addr + recv->r_frag->f_offset + data_len,
- sizeof(struct rds_header) - misplaced_hdr_bytes);
- kunmap_atomic(addr, KM_SOFTIRQ0);
- return hdr_buff;
-}
-
/*
* It's kind of lame that we're copying from the posted receive pages into
* long-lived bitmaps. We could have posted the bitmaps and rdma written into
@@ -639,7 +763,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn,
to_copy = min(RDS_FRAG_SIZE - frag_off, PAGE_SIZE - map_off);
BUG_ON(to_copy & 7); /* Must be 64bit aligned. */
- addr = kmap_atomic(frag->f_page, KM_SOFTIRQ0);
+ addr = kmap_atomic(sg_page(&frag->f_sg), KM_SOFTIRQ0);
src = addr + frag_off;
dst = (void *)map->m_page_addrs[map_page] + map_off;
@@ -710,7 +834,7 @@ static void rds_ib_process_recv(struct rds_connection *conn,
}
data_len -= sizeof(struct rds_header);
- ihdr = rds_ib_get_header(conn, recv, data_len);
+ ihdr = &ic->i_recv_hdrs[recv - ic->i_recvs];
/* Validate the checksum. */
if (!rds_message_verify_checksum(ihdr)) {
@@ -742,12 +866,12 @@ static void rds_ib_process_recv(struct rds_connection *conn,
* the inc is freed. We don't go that route, so we have to drop the
* page ref ourselves. We can't just leave the page on the recv
* because that confuses the dma mapping of pages and each recv's use
- * of a partial page. We can leave the frag, though, it will be
- * reused.
+ * of a partial page.
*
* FIXME: Fold this into the code path below.
*/
- rds_ib_frag_drop_page(recv->r_frag);
+ rds_ib_frag_free(ic, recv->r_frag);
+ recv->r_frag = NULL;
return;
}
@@ -757,7 +881,7 @@ static void rds_ib_process_recv(struct rds_connection *conn,
* into the inc and save the inc so we can hang upcoming fragments
* off its list.
*/
- if (ibinc == NULL) {
+ if (!ibinc) {
ibinc = recv->r_ibinc;
recv->r_ibinc = NULL;
ic->i_ibinc = ibinc;
@@ -842,32 +966,38 @@ static inline void rds_poll_cq(struct rds_ib_connection *ic,
struct rds_ib_recv_work *recv;
while (ib_poll_cq(ic->i_recv_cq, 1, &wc) > 0) {
- rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n",
- (unsigned long long)wc.wr_id, wc.status, wc.byte_len,
+ rdsdebug("wc wr_id 0x%llx status %u (%s) byte_len %u imm_data %u\n",
+ (unsigned long long)wc.wr_id, wc.status,
+ rds_ib_wc_status_str(wc.status), wc.byte_len,
be32_to_cpu(wc.ex.imm_data));
rds_ib_stats_inc(s_ib_rx_cq_event);
recv = &ic->i_recvs[rds_ib_ring_oldest(&ic->i_recv_ring)];
- rds_ib_recv_unmap_page(ic, recv);
+ ib_dma_unmap_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, 1, DMA_FROM_DEVICE);
/*
* Also process recvs in connecting state because it is possible
* to get a recv completion _before_ the rdmacm ESTABLISHED
* event is processed.
*/
- if (rds_conn_up(conn) || rds_conn_connecting(conn)) {
+ if (wc.status == IB_WC_SUCCESS) {
+ rds_ib_process_recv(conn, recv, wc.byte_len, state);
+ } else {
/* We expect errors as the qp is drained during shutdown */
- if (wc.status == IB_WC_SUCCESS) {
- rds_ib_process_recv(conn, recv, wc.byte_len, state);
- } else {
- rds_ib_conn_error(conn, "recv completion on "
- "%pI4 had status %u, disconnecting and "
- "reconnecting\n", &conn->c_faddr,
- wc.status);
- }
+ if (rds_conn_up(conn) || rds_conn_connecting(conn))
+ rds_ib_conn_error(conn, "recv completion on %pI4 had "
+ "status %u (%s), disconnecting and "
+ "reconnecting\n", &conn->c_faddr,
+ wc.status,
+ rds_ib_wc_status_str(wc.status));
}
+ /*
+ * It's very important that we only free this ring entry if we've truly
+ * freed the resources allocated to the entry. The refilling path can
+ * leak if we don't.
+ */
rds_ib_ring_free(&ic->i_recv_ring, 1);
}
}
@@ -897,11 +1027,8 @@ void rds_ib_recv_tasklet_fn(unsigned long data)
if (rds_ib_ring_empty(&ic->i_recv_ring))
rds_ib_stats_inc(s_ib_rx_ring_empty);
- /*
- * If the ring is running low, then schedule the thread to refill.
- */
if (rds_ib_ring_low(&ic->i_recv_ring))
- queue_delayed_work(rds_wq, &conn->c_recv_w, 0);
+ rds_ib_recv_refill(conn, 0);
}
int rds_ib_recv(struct rds_connection *conn)
@@ -910,25 +1037,13 @@ int rds_ib_recv(struct rds_connection *conn)
int ret = 0;
rdsdebug("conn %p\n", conn);
-
- /*
- * If we get a temporary posting failure in this context then
- * we're really low and we want the caller to back off for a bit.
- */
- mutex_lock(&ic->i_recv_mutex);
- if (rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 0))
- ret = -ENOMEM;
- else
- rds_ib_stats_inc(s_ib_rx_refill_from_thread);
- mutex_unlock(&ic->i_recv_mutex);
-
if (rds_conn_up(conn))
rds_ib_attempt_ack(ic);
return ret;
}
-int __init rds_ib_recv_init(void)
+int rds_ib_recv_init(void)
{
struct sysinfo si;
int ret = -ENOMEM;
@@ -939,14 +1054,14 @@ int __init rds_ib_recv_init(void)
rds_ib_incoming_slab = kmem_cache_create("rds_ib_incoming",
sizeof(struct rds_ib_incoming),
- 0, 0, NULL);
- if (rds_ib_incoming_slab == NULL)
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!rds_ib_incoming_slab)
goto out;
rds_ib_frag_slab = kmem_cache_create("rds_ib_frag",
sizeof(struct rds_page_frag),
- 0, 0, NULL);
- if (rds_ib_frag_slab == NULL)
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!rds_ib_frag_slab)
kmem_cache_destroy(rds_ib_incoming_slab);
else
ret = 0;
diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
index 17fa80803ab0..71f373c421bc 100644
--- a/net/rds/ib_send.c
+++ b/net/rds/ib_send.c
@@ -36,11 +36,49 @@
#include <linux/dmapool.h>
#include "rds.h"
-#include "rdma.h"
#include "ib.h"
-static void rds_ib_send_rdma_complete(struct rds_message *rm,
- int wc_status)
+static char *rds_ib_wc_status_strings[] = {
+#define RDS_IB_WC_STATUS_STR(foo) \
+ [IB_WC_##foo] = __stringify(IB_WC_##foo)
+ RDS_IB_WC_STATUS_STR(SUCCESS),
+ RDS_IB_WC_STATUS_STR(LOC_LEN_ERR),
+ RDS_IB_WC_STATUS_STR(LOC_QP_OP_ERR),
+ RDS_IB_WC_STATUS_STR(LOC_EEC_OP_ERR),
+ RDS_IB_WC_STATUS_STR(LOC_PROT_ERR),
+ RDS_IB_WC_STATUS_STR(WR_FLUSH_ERR),
+ RDS_IB_WC_STATUS_STR(MW_BIND_ERR),
+ RDS_IB_WC_STATUS_STR(BAD_RESP_ERR),
+ RDS_IB_WC_STATUS_STR(LOC_ACCESS_ERR),
+ RDS_IB_WC_STATUS_STR(REM_INV_REQ_ERR),
+ RDS_IB_WC_STATUS_STR(REM_ACCESS_ERR),
+ RDS_IB_WC_STATUS_STR(REM_OP_ERR),
+ RDS_IB_WC_STATUS_STR(RETRY_EXC_ERR),
+ RDS_IB_WC_STATUS_STR(RNR_RETRY_EXC_ERR),
+ RDS_IB_WC_STATUS_STR(LOC_RDD_VIOL_ERR),
+ RDS_IB_WC_STATUS_STR(REM_INV_RD_REQ_ERR),
+ RDS_IB_WC_STATUS_STR(REM_ABORT_ERR),
+ RDS_IB_WC_STATUS_STR(INV_EECN_ERR),
+ RDS_IB_WC_STATUS_STR(INV_EEC_STATE_ERR),
+ RDS_IB_WC_STATUS_STR(FATAL_ERR),
+ RDS_IB_WC_STATUS_STR(RESP_TIMEOUT_ERR),
+ RDS_IB_WC_STATUS_STR(GENERAL_ERR),
+#undef RDS_IB_WC_STATUS_STR
+};
+
+char *rds_ib_wc_status_str(enum ib_wc_status status)
+{
+ return rds_str_array(rds_ib_wc_status_strings,
+ ARRAY_SIZE(rds_ib_wc_status_strings), status);
+}
+
+/*
+ * Convert IB-specific error message to RDS error message and call core
+ * completion handler.
+ */
+static void rds_ib_send_complete(struct rds_message *rm,
+ int wc_status,
+ void (*complete)(struct rds_message *rm, int status))
{
int notify_status;
@@ -60,69 +98,125 @@ static void rds_ib_send_rdma_complete(struct rds_message *rm,
notify_status = RDS_RDMA_OTHER_ERROR;
break;
}
- rds_rdma_send_complete(rm, notify_status);
+ complete(rm, notify_status);
+}
+
+static void rds_ib_send_unmap_data(struct rds_ib_connection *ic,
+ struct rm_data_op *op,
+ int wc_status)
+{
+ if (op->op_nents)
+ ib_dma_unmap_sg(ic->i_cm_id->device,
+ op->op_sg, op->op_nents,
+ DMA_TO_DEVICE);
}
static void rds_ib_send_unmap_rdma(struct rds_ib_connection *ic,
- struct rds_rdma_op *op)
+ struct rm_rdma_op *op,
+ int wc_status)
{
- if (op->r_mapped) {
+ if (op->op_mapped) {
ib_dma_unmap_sg(ic->i_cm_id->device,
- op->r_sg, op->r_nents,
- op->r_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
- op->r_mapped = 0;
+ op->op_sg, op->op_nents,
+ op->op_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ op->op_mapped = 0;
}
+
+ /* If the user asked for a completion notification on this
+ * message, we can implement three different semantics:
+ * 1. Notify when we received the ACK on the RDS message
+ * that was queued with the RDMA. This provides reliable
+ * notification of RDMA status at the expense of a one-way
+ * packet delay.
+ * 2. Notify when the IB stack gives us the completion event for
+ * the RDMA operation.
+ * 3. Notify when the IB stack gives us the completion event for
+ * the accompanying RDS messages.
+ * Here, we implement approach #3. To implement approach #2,
+ * we would need to take an event for the rdma WR. To implement #1,
+ * don't call rds_rdma_send_complete at all, and fall back to the notify
+ * handling in the ACK processing code.
+ *
+ * Note: There's no need to explicitly sync any RDMA buffers using
+ * ib_dma_sync_sg_for_cpu - the completion for the RDMA
+ * operation itself unmapped the RDMA buffers, which takes care
+ * of synching.
+ */
+ rds_ib_send_complete(container_of(op, struct rds_message, rdma),
+ wc_status, rds_rdma_send_complete);
+
+ if (op->op_write)
+ rds_stats_add(s_send_rdma_bytes, op->op_bytes);
+ else
+ rds_stats_add(s_recv_rdma_bytes, op->op_bytes);
}
-static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic,
- struct rds_ib_send_work *send,
- int wc_status)
+static void rds_ib_send_unmap_atomic(struct rds_ib_connection *ic,
+ struct rm_atomic_op *op,
+ int wc_status)
{
- struct rds_message *rm = send->s_rm;
-
- rdsdebug("ic %p send %p rm %p\n", ic, send, rm);
-
- ib_dma_unmap_sg(ic->i_cm_id->device,
- rm->m_sg, rm->m_nents,
- DMA_TO_DEVICE);
-
- if (rm->m_rdma_op != NULL) {
- rds_ib_send_unmap_rdma(ic, rm->m_rdma_op);
-
- /* If the user asked for a completion notification on this
- * message, we can implement three different semantics:
- * 1. Notify when we received the ACK on the RDS message
- * that was queued with the RDMA. This provides reliable
- * notification of RDMA status at the expense of a one-way
- * packet delay.
- * 2. Notify when the IB stack gives us the completion event for
- * the RDMA operation.
- * 3. Notify when the IB stack gives us the completion event for
- * the accompanying RDS messages.
- * Here, we implement approach #3. To implement approach #2,
- * call rds_rdma_send_complete from the cq_handler. To implement #1,
- * don't call rds_rdma_send_complete at all, and fall back to the notify
- * handling in the ACK processing code.
- *
- * Note: There's no need to explicitly sync any RDMA buffers using
- * ib_dma_sync_sg_for_cpu - the completion for the RDMA
- * operation itself unmapped the RDMA buffers, which takes care
- * of synching.
- */
- rds_ib_send_rdma_complete(rm, wc_status);
+ /* unmap atomic recvbuf */
+ if (op->op_mapped) {
+ ib_dma_unmap_sg(ic->i_cm_id->device, op->op_sg, 1,
+ DMA_FROM_DEVICE);
+ op->op_mapped = 0;
+ }
- if (rm->m_rdma_op->r_write)
- rds_stats_add(s_send_rdma_bytes, rm->m_rdma_op->r_bytes);
- else
- rds_stats_add(s_recv_rdma_bytes, rm->m_rdma_op->r_bytes);
+ rds_ib_send_complete(container_of(op, struct rds_message, atomic),
+ wc_status, rds_atomic_send_complete);
+
+ if (op->op_type == RDS_ATOMIC_TYPE_CSWP)
+ rds_ib_stats_inc(s_ib_atomic_cswp);
+ else
+ rds_ib_stats_inc(s_ib_atomic_fadd);
+}
+
+/*
+ * Unmap the resources associated with a struct send_work.
+ *
+ * Returns the rm for no good reason other than it is unobtainable
+ * other than by switching on wr.opcode, currently, and the caller,
+ * the event handler, needs it.
+ */
+static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic,
+ struct rds_ib_send_work *send,
+ int wc_status)
+{
+ struct rds_message *rm = NULL;
+
+ /* In the error case, wc.opcode sometimes contains garbage */
+ switch (send->s_wr.opcode) {
+ case IB_WR_SEND:
+ if (send->s_op) {
+ rm = container_of(send->s_op, struct rds_message, data);
+ rds_ib_send_unmap_data(ic, send->s_op, wc_status);
+ }
+ break;
+ case IB_WR_RDMA_WRITE:
+ case IB_WR_RDMA_READ:
+ if (send->s_op) {
+ rm = container_of(send->s_op, struct rds_message, rdma);
+ rds_ib_send_unmap_rdma(ic, send->s_op, wc_status);
+ }
+ break;
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ case IB_WR_ATOMIC_CMP_AND_SWP:
+ if (send->s_op) {
+ rm = container_of(send->s_op, struct rds_message, atomic);
+ rds_ib_send_unmap_atomic(ic, send->s_op, wc_status);
+ }
+ break;
+ default:
+ if (printk_ratelimit())
+ printk(KERN_NOTICE
+ "RDS/IB: %s: unexpected opcode 0x%x in WR!\n",
+ __func__, send->s_wr.opcode);
+ break;
}
- /* If anyone waited for this message to get flushed out, wake
- * them up now */
- rds_message_unmapped(rm);
+ send->s_wr.opcode = 0xdead;
- rds_message_put(rm);
- send->s_rm = NULL;
+ return rm;
}
void rds_ib_send_init_ring(struct rds_ib_connection *ic)
@@ -133,23 +227,18 @@ void rds_ib_send_init_ring(struct rds_ib_connection *ic)
for (i = 0, send = ic->i_sends; i < ic->i_send_ring.w_nr; i++, send++) {
struct ib_sge *sge;
- send->s_rm = NULL;
send->s_op = NULL;
send->s_wr.wr_id = i;
send->s_wr.sg_list = send->s_sge;
- send->s_wr.num_sge = 1;
- send->s_wr.opcode = IB_WR_SEND;
- send->s_wr.send_flags = 0;
send->s_wr.ex.imm_data = 0;
- sge = rds_ib_data_sge(ic, send->s_sge);
- sge->lkey = ic->i_mr->lkey;
-
- sge = rds_ib_header_sge(ic, send->s_sge);
+ sge = &send->s_sge[0];
sge->addr = ic->i_send_hdrs_dma + (i * sizeof(struct rds_header));
sge->length = sizeof(struct rds_header);
sge->lkey = ic->i_mr->lkey;
+
+ send->s_sge[1].lkey = ic->i_mr->lkey;
}
}
@@ -159,16 +248,24 @@ void rds_ib_send_clear_ring(struct rds_ib_connection *ic)
u32 i;
for (i = 0, send = ic->i_sends; i < ic->i_send_ring.w_nr; i++, send++) {
- if (send->s_wr.opcode == 0xdead)
- continue;
- if (send->s_rm)
- rds_ib_send_unmap_rm(ic, send, IB_WC_WR_FLUSH_ERR);
- if (send->s_op)
- rds_ib_send_unmap_rdma(ic, send->s_op);
+ if (send->s_op && send->s_wr.opcode != 0xdead)
+ rds_ib_send_unmap_op(ic, send, IB_WC_WR_FLUSH_ERR);
}
}
/*
+ * The only fast path caller always has a non-zero nr, so we don't
+ * bother testing nr before performing the atomic sub.
+ */
+static void rds_ib_sub_signaled(struct rds_ib_connection *ic, int nr)
+{
+ if ((atomic_sub_return(nr, &ic->i_signaled_sends) == 0) &&
+ waitqueue_active(&rds_ib_ring_empty_wait))
+ wake_up(&rds_ib_ring_empty_wait);
+ BUG_ON(atomic_read(&ic->i_signaled_sends) < 0);
+}
+
+/*
* The _oldest/_free ring operations here race cleanly with the alloc/unalloc
* operations performed in the send path. As the sender allocs and potentially
* unallocs the next free entry in the ring it doesn't alter which is
@@ -178,12 +275,14 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context)
{
struct rds_connection *conn = context;
struct rds_ib_connection *ic = conn->c_transport_data;
+ struct rds_message *rm = NULL;
struct ib_wc wc;
struct rds_ib_send_work *send;
u32 completed;
u32 oldest;
u32 i = 0;
int ret;
+ int nr_sig = 0;
rdsdebug("cq %p conn %p\n", cq, conn);
rds_ib_stats_inc(s_ib_tx_cq_call);
@@ -192,8 +291,9 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context)
rdsdebug("ib_req_notify_cq send failed: %d\n", ret);
while (ib_poll_cq(cq, 1, &wc) > 0) {
- rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n",
- (unsigned long long)wc.wr_id, wc.status, wc.byte_len,
+ rdsdebug("wc wr_id 0x%llx status %u (%s) byte_len %u imm_data %u\n",
+ (unsigned long long)wc.wr_id, wc.status,
+ rds_ib_wc_status_str(wc.status), wc.byte_len,
be32_to_cpu(wc.ex.imm_data));
rds_ib_stats_inc(s_ib_tx_cq_event);
@@ -210,51 +310,30 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context)
for (i = 0; i < completed; i++) {
send = &ic->i_sends[oldest];
+ if (send->s_wr.send_flags & IB_SEND_SIGNALED)
+ nr_sig++;
- /* In the error case, wc.opcode sometimes contains garbage */
- switch (send->s_wr.opcode) {
- case IB_WR_SEND:
- if (send->s_rm)
- rds_ib_send_unmap_rm(ic, send, wc.status);
- break;
- case IB_WR_RDMA_WRITE:
- case IB_WR_RDMA_READ:
- /* Nothing to be done - the SG list will be unmapped
- * when the SEND completes. */
- break;
- default:
- if (printk_ratelimit())
- printk(KERN_NOTICE
- "RDS/IB: %s: unexpected opcode 0x%x in WR!\n",
- __func__, send->s_wr.opcode);
- break;
- }
+ rm = rds_ib_send_unmap_op(ic, send, wc.status);
- send->s_wr.opcode = 0xdead;
- send->s_wr.num_sge = 1;
if (send->s_queued + HZ/2 < jiffies)
rds_ib_stats_inc(s_ib_tx_stalled);
- /* If a RDMA operation produced an error, signal this right
- * away. If we don't, the subsequent SEND that goes with this
- * RDMA will be canceled with ERR_WFLUSH, and the application
- * never learn that the RDMA failed. */
- if (unlikely(wc.status == IB_WC_REM_ACCESS_ERR && send->s_op)) {
- struct rds_message *rm;
-
- rm = rds_send_get_message(conn, send->s_op);
- if (rm) {
- if (rm->m_rdma_op)
- rds_ib_send_unmap_rdma(ic, rm->m_rdma_op);
- rds_ib_send_rdma_complete(rm, wc.status);
- rds_message_put(rm);
+ if (send->s_op) {
+ if (send->s_op == rm->m_final_op) {
+ /* If anyone waited for this message to get flushed out, wake
+ * them up now */
+ rds_message_unmapped(rm);
}
+ rds_message_put(rm);
+ send->s_op = NULL;
}
oldest = (oldest + 1) % ic->i_send_ring.w_nr;
}
rds_ib_ring_free(&ic->i_send_ring, completed);
+ rds_ib_sub_signaled(ic, nr_sig);
+ nr_sig = 0;
if (test_and_clear_bit(RDS_LL_SEND_FULL, &conn->c_flags) ||
test_bit(0, &conn->c_map_queued))
@@ -262,10 +341,10 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context)
/* We expect errors as the qp is drained during shutdown */
if (wc.status != IB_WC_SUCCESS && rds_conn_up(conn)) {
- rds_ib_conn_error(conn,
- "send completion on %pI4 "
- "had status %u, disconnecting and reconnecting\n",
- &conn->c_faddr, wc.status);
+ rds_ib_conn_error(conn, "send completion on %pI4 had status "
+ "%u (%s), disconnecting and reconnecting\n",
+ &conn->c_faddr, wc.status,
+ rds_ib_wc_status_str(wc.status));
}
}
}
@@ -294,7 +373,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context)
* credits (see rds_ib_send_add_credits below).
*
* The RDS send code is essentially single-threaded; rds_send_xmit
- * grabs c_send_lock to ensure exclusive access to the send ring.
+ * sets RDS_IN_XMIT to ensure exclusive access to the send ring.
* However, the ACK sending code is independent and can race with
* message SENDs.
*
@@ -413,40 +492,21 @@ void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted)
set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags);
}
-static inline void
-rds_ib_xmit_populate_wr(struct rds_ib_connection *ic,
- struct rds_ib_send_work *send, unsigned int pos,
- unsigned long buffer, unsigned int length,
- int send_flags)
+static inline int rds_ib_set_wr_signal_state(struct rds_ib_connection *ic,
+ struct rds_ib_send_work *send,
+ bool notify)
{
- struct ib_sge *sge;
-
- WARN_ON(pos != send - ic->i_sends);
-
- send->s_wr.send_flags = send_flags;
- send->s_wr.opcode = IB_WR_SEND;
- send->s_wr.num_sge = 2;
- send->s_wr.next = NULL;
- send->s_queued = jiffies;
- send->s_op = NULL;
-
- if (length != 0) {
- sge = rds_ib_data_sge(ic, send->s_sge);
- sge->addr = buffer;
- sge->length = length;
- sge->lkey = ic->i_mr->lkey;
-
- sge = rds_ib_header_sge(ic, send->s_sge);
- } else {
- /* We're sending a packet with no payload. There is only
- * one SGE */
- send->s_wr.num_sge = 1;
- sge = &send->s_sge[0];
+ /*
+ * We want to delay signaling completions just enough to get
+ * the batching benefits but not so much that we create dead time
+ * on the wire.
+ */
+ if (ic->i_unsignaled_wrs-- == 0 || notify) {
+ ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs;
+ send->s_wr.send_flags |= IB_SEND_SIGNALED;
+ return 1;
}
-
- sge->addr = ic->i_send_hdrs_dma + (pos * sizeof(struct rds_header));
- sge->length = sizeof(struct rds_header);
- sge->lkey = ic->i_mr->lkey;
+ return 0;
}
/*
@@ -475,13 +535,14 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
u32 pos;
u32 i;
u32 work_alloc;
- u32 credit_alloc;
+ u32 credit_alloc = 0;
u32 posted;
u32 adv_credits = 0;
int send_flags = 0;
- int sent;
+ int bytes_sent = 0;
int ret;
int flow_controlled = 0;
+ int nr_sig = 0;
BUG_ON(off % RDS_FRAG_SIZE);
BUG_ON(hdr_off != 0 && hdr_off != sizeof(struct rds_header));
@@ -507,14 +568,13 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
goto out;
}
- credit_alloc = work_alloc;
if (ic->i_flowctl) {
credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT);
adv_credits += posted;
if (credit_alloc < work_alloc) {
rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc);
work_alloc = credit_alloc;
- flow_controlled++;
+ flow_controlled = 1;
}
if (work_alloc == 0) {
set_bit(RDS_LL_SEND_FULL, &conn->c_flags);
@@ -525,31 +585,25 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
}
/* map the message the first time we see it */
- if (ic->i_rm == NULL) {
- /*
- printk(KERN_NOTICE "rds_ib_xmit prep msg dport=%u flags=0x%x len=%d\n",
- be16_to_cpu(rm->m_inc.i_hdr.h_dport),
- rm->m_inc.i_hdr.h_flags,
- be32_to_cpu(rm->m_inc.i_hdr.h_len));
- */
- if (rm->m_nents) {
- rm->m_count = ib_dma_map_sg(dev,
- rm->m_sg, rm->m_nents, DMA_TO_DEVICE);
- rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->m_count);
- if (rm->m_count == 0) {
+ if (!ic->i_data_op) {
+ if (rm->data.op_nents) {
+ rm->data.op_count = ib_dma_map_sg(dev,
+ rm->data.op_sg,
+ rm->data.op_nents,
+ DMA_TO_DEVICE);
+ rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->data.op_count);
+ if (rm->data.op_count == 0) {
rds_ib_stats_inc(s_ib_tx_sg_mapping_failure);
rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc);
ret = -ENOMEM; /* XXX ? */
goto out;
}
} else {
- rm->m_count = 0;
+ rm->data.op_count = 0;
}
- ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs;
- ic->i_unsignaled_bytes = rds_ib_sysctl_max_unsig_bytes;
rds_message_addref(rm);
- ic->i_rm = rm;
+ ic->i_data_op = &rm->data;
/* Finalize the header */
if (test_bit(RDS_MSG_ACK_REQUIRED, &rm->m_flags))
@@ -559,10 +613,10 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
/* If it has a RDMA op, tell the peer we did it. This is
* used by the peer to release use-once RDMA MRs. */
- if (rm->m_rdma_op) {
+ if (rm->rdma.op_active) {
struct rds_ext_header_rdma ext_hdr;
- ext_hdr.h_rdma_rkey = cpu_to_be32(rm->m_rdma_op->r_key);
+ ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.op_rkey);
rds_message_add_extension(&rm->m_inc.i_hdr,
RDS_EXTHDR_RDMA, &ext_hdr, sizeof(ext_hdr));
}
@@ -582,99 +636,77 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
/*
* Update adv_credits since we reset the ACK_REQUIRED bit.
*/
- rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits);
- adv_credits += posted;
- BUG_ON(adv_credits > 255);
+ if (ic->i_flowctl) {
+ rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits);
+ adv_credits += posted;
+ BUG_ON(adv_credits > 255);
+ }
}
- send = &ic->i_sends[pos];
- first = send;
- prev = NULL;
- scat = &rm->m_sg[sg];
- sent = 0;
- i = 0;
-
/* Sometimes you want to put a fence between an RDMA
* READ and the following SEND.
* We could either do this all the time
* or when requested by the user. Right now, we let
* the application choose.
*/
- if (rm->m_rdma_op && rm->m_rdma_op->r_fence)
+ if (rm->rdma.op_active && rm->rdma.op_fence)
send_flags = IB_SEND_FENCE;
- /*
- * We could be copying the header into the unused tail of the page.
- * That would need to be changed in the future when those pages might
- * be mapped userspace pages or page cache pages. So instead we always
- * use a second sge and our long-lived ring of mapped headers. We send
- * the header after the data so that the data payload can be aligned on
- * the receiver.
- */
+ /* Each frag gets a header. Msgs may be 0 bytes */
+ send = &ic->i_sends[pos];
+ first = send;
+ prev = NULL;
+ scat = &ic->i_data_op->op_sg[sg];
+ i = 0;
+ do {
+ unsigned int len = 0;
- /* handle a 0-len message */
- if (be32_to_cpu(rm->m_inc.i_hdr.h_len) == 0) {
- rds_ib_xmit_populate_wr(ic, send, pos, 0, 0, send_flags);
- goto add_header;
- }
+ /* Set up the header */
+ send->s_wr.send_flags = send_flags;
+ send->s_wr.opcode = IB_WR_SEND;
+ send->s_wr.num_sge = 1;
+ send->s_wr.next = NULL;
+ send->s_queued = jiffies;
+ send->s_op = NULL;
- /* if there's data reference it with a chain of work reqs */
- for (; i < work_alloc && scat != &rm->m_sg[rm->m_count]; i++) {
- unsigned int len;
+ send->s_sge[0].addr = ic->i_send_hdrs_dma
+ + (pos * sizeof(struct rds_header));
+ send->s_sge[0].length = sizeof(struct rds_header);
- send = &ic->i_sends[pos];
+ memcpy(&ic->i_send_hdrs[pos], &rm->m_inc.i_hdr, sizeof(struct rds_header));
- len = min(RDS_FRAG_SIZE, ib_sg_dma_len(dev, scat) - off);
- rds_ib_xmit_populate_wr(ic, send, pos,
- ib_sg_dma_address(dev, scat) + off, len,
- send_flags);
+ /* Set up the data, if present */
+ if (i < work_alloc
+ && scat != &rm->data.op_sg[rm->data.op_count]) {
+ len = min(RDS_FRAG_SIZE, ib_sg_dma_len(dev, scat) - off);
+ send->s_wr.num_sge = 2;
- /*
- * We want to delay signaling completions just enough to get
- * the batching benefits but not so much that we create dead time
- * on the wire.
- */
- if (ic->i_unsignaled_wrs-- == 0) {
- ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs;
- send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED;
- }
+ send->s_sge[1].addr = ib_sg_dma_address(dev, scat) + off;
+ send->s_sge[1].length = len;
- ic->i_unsignaled_bytes -= len;
- if (ic->i_unsignaled_bytes <= 0) {
- ic->i_unsignaled_bytes = rds_ib_sysctl_max_unsig_bytes;
- send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED;
+ bytes_sent += len;
+ off += len;
+ if (off == ib_sg_dma_len(dev, scat)) {
+ scat++;
+ off = 0;
+ }
}
+ rds_ib_set_wr_signal_state(ic, send, 0);
+
/*
* Always signal the last one if we're stopping due to flow control.
*/
- if (flow_controlled && i == (work_alloc-1))
+ if (ic->i_flowctl && flow_controlled && i == (work_alloc-1))
send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED;
+ if (send->s_wr.send_flags & IB_SEND_SIGNALED)
+ nr_sig++;
+
rdsdebug("send %p wr %p num_sge %u next %p\n", send,
&send->s_wr, send->s_wr.num_sge, send->s_wr.next);
- sent += len;
- off += len;
- if (off == ib_sg_dma_len(dev, scat)) {
- scat++;
- off = 0;
- }
-
-add_header:
- /* Tack on the header after the data. The header SGE should already
- * have been set up to point to the right header buffer. */
- memcpy(&ic->i_send_hdrs[pos], &rm->m_inc.i_hdr, sizeof(struct rds_header));
-
- if (0) {
- struct rds_header *hdr = &ic->i_send_hdrs[pos];
-
- printk(KERN_NOTICE "send WR dport=%u flags=0x%x len=%d\n",
- be16_to_cpu(hdr->h_dport),
- hdr->h_flags,
- be32_to_cpu(hdr->h_len));
- }
- if (adv_credits) {
+ if (ic->i_flowctl && adv_credits) {
struct rds_header *hdr = &ic->i_send_hdrs[pos];
/* add credit and redo the header checksum */
@@ -689,20 +721,25 @@ add_header:
prev = send;
pos = (pos + 1) % ic->i_send_ring.w_nr;
- }
+ send = &ic->i_sends[pos];
+ i++;
+
+ } while (i < work_alloc
+ && scat != &rm->data.op_sg[rm->data.op_count]);
/* Account the RDS header in the number of bytes we sent, but just once.
* The caller has no concept of fragmentation. */
if (hdr_off == 0)
- sent += sizeof(struct rds_header);
+ bytes_sent += sizeof(struct rds_header);
/* if we finished the message then send completion owns it */
- if (scat == &rm->m_sg[rm->m_count]) {
- prev->s_rm = ic->i_rm;
- prev->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED;
- ic->i_rm = NULL;
+ if (scat == &rm->data.op_sg[rm->data.op_count]) {
+ prev->s_op = ic->i_data_op;
+ prev->s_wr.send_flags |= IB_SEND_SOLICITED;
+ ic->i_data_op = NULL;
}
+ /* Put back wrs & credits we didn't use */
if (i < work_alloc) {
rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - i);
work_alloc = i;
@@ -710,6 +747,9 @@ add_header:
if (ic->i_flowctl && i < credit_alloc)
rds_ib_send_add_credits(conn, credit_alloc - i);
+ if (nr_sig)
+ atomic_add(nr_sig, &ic->i_signaled_sends);
+
/* XXX need to worry about failed_wr and partial sends. */
failed_wr = &first->s_wr;
ret = ib_post_send(ic->i_cm_id->qp, &first->s_wr, &failed_wr);
@@ -720,32 +760,127 @@ add_header:
printk(KERN_WARNING "RDS/IB: ib_post_send to %pI4 "
"returned %d\n", &conn->c_faddr, ret);
rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc);
- if (prev->s_rm) {
- ic->i_rm = prev->s_rm;
- prev->s_rm = NULL;
+ rds_ib_sub_signaled(ic, nr_sig);
+ if (prev->s_op) {
+ ic->i_data_op = prev->s_op;
+ prev->s_op = NULL;
}
rds_ib_conn_error(ic->conn, "ib_post_send failed\n");
goto out;
}
- ret = sent;
+ ret = bytes_sent;
out:
BUG_ON(adv_credits);
return ret;
}
-int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
+/*
+ * Issue atomic operation.
+ * A simplified version of the rdma case, we always map 1 SG, and
+ * only 8 bytes, for the return value from the atomic operation.
+ */
+int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op)
+{
+ struct rds_ib_connection *ic = conn->c_transport_data;
+ struct rds_ib_send_work *send = NULL;
+ struct ib_send_wr *failed_wr;
+ struct rds_ib_device *rds_ibdev;
+ u32 pos;
+ u32 work_alloc;
+ int ret;
+ int nr_sig = 0;
+
+ rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client);
+
+ work_alloc = rds_ib_ring_alloc(&ic->i_send_ring, 1, &pos);
+ if (work_alloc != 1) {
+ rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc);
+ rds_ib_stats_inc(s_ib_tx_ring_full);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* address of send request in ring */
+ send = &ic->i_sends[pos];
+ send->s_queued = jiffies;
+
+ if (op->op_type == RDS_ATOMIC_TYPE_CSWP) {
+ send->s_wr.opcode = IB_WR_MASKED_ATOMIC_CMP_AND_SWP;
+ send->s_wr.wr.atomic.compare_add = op->op_m_cswp.compare;
+ send->s_wr.wr.atomic.swap = op->op_m_cswp.swap;
+ send->s_wr.wr.atomic.compare_add_mask = op->op_m_cswp.compare_mask;
+ send->s_wr.wr.atomic.swap_mask = op->op_m_cswp.swap_mask;
+ } else { /* FADD */
+ send->s_wr.opcode = IB_WR_MASKED_ATOMIC_FETCH_AND_ADD;
+ send->s_wr.wr.atomic.compare_add = op->op_m_fadd.add;
+ send->s_wr.wr.atomic.swap = 0;
+ send->s_wr.wr.atomic.compare_add_mask = op->op_m_fadd.nocarry_mask;
+ send->s_wr.wr.atomic.swap_mask = 0;
+ }
+ nr_sig = rds_ib_set_wr_signal_state(ic, send, op->op_notify);
+ send->s_wr.num_sge = 1;
+ send->s_wr.next = NULL;
+ send->s_wr.wr.atomic.remote_addr = op->op_remote_addr;
+ send->s_wr.wr.atomic.rkey = op->op_rkey;
+ send->s_op = op;
+ rds_message_addref(container_of(send->s_op, struct rds_message, atomic));
+
+ /* map 8 byte retval buffer to the device */
+ ret = ib_dma_map_sg(ic->i_cm_id->device, op->op_sg, 1, DMA_FROM_DEVICE);
+ rdsdebug("ic %p mapping atomic op %p. mapped %d pg\n", ic, op, ret);
+ if (ret != 1) {
+ rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc);
+ rds_ib_stats_inc(s_ib_tx_sg_mapping_failure);
+ ret = -ENOMEM; /* XXX ? */
+ goto out;
+ }
+
+ /* Convert our struct scatterlist to struct ib_sge */
+ send->s_sge[0].addr = ib_sg_dma_address(ic->i_cm_id->device, op->op_sg);
+ send->s_sge[0].length = ib_sg_dma_len(ic->i_cm_id->device, op->op_sg);
+ send->s_sge[0].lkey = ic->i_mr->lkey;
+
+ rdsdebug("rva %Lx rpa %Lx len %u\n", op->op_remote_addr,
+ send->s_sge[0].addr, send->s_sge[0].length);
+
+ if (nr_sig)
+ atomic_add(nr_sig, &ic->i_signaled_sends);
+
+ failed_wr = &send->s_wr;
+ ret = ib_post_send(ic->i_cm_id->qp, &send->s_wr, &failed_wr);
+ rdsdebug("ic %p send %p (wr %p) ret %d wr %p\n", ic,
+ send, &send->s_wr, ret, failed_wr);
+ BUG_ON(failed_wr != &send->s_wr);
+ if (ret) {
+ printk(KERN_WARNING "RDS/IB: atomic ib_post_send to %pI4 "
+ "returned %d\n", &conn->c_faddr, ret);
+ rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc);
+ rds_ib_sub_signaled(ic, nr_sig);
+ goto out;
+ }
+
+ if (unlikely(failed_wr != &send->s_wr)) {
+ printk(KERN_WARNING "RDS/IB: atomic ib_post_send() rc=%d, but failed_wqe updated!\n", ret);
+ BUG_ON(failed_wr != &send->s_wr);
+ }
+
+out:
+ return ret;
+}
+
+int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op)
{
struct rds_ib_connection *ic = conn->c_transport_data;
struct rds_ib_send_work *send = NULL;
struct rds_ib_send_work *first;
struct rds_ib_send_work *prev;
struct ib_send_wr *failed_wr;
- struct rds_ib_device *rds_ibdev;
struct scatterlist *scat;
unsigned long len;
- u64 remote_addr = op->r_remote_addr;
+ u64 remote_addr = op->op_remote_addr;
+ u32 max_sge = ic->rds_ibdev->max_sge;
u32 pos;
u32 work_alloc;
u32 i;
@@ -753,29 +888,28 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
int sent;
int ret;
int num_sge;
-
- rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client);
-
- /* map the message the first time we see it */
- if (!op->r_mapped) {
- op->r_count = ib_dma_map_sg(ic->i_cm_id->device,
- op->r_sg, op->r_nents, (op->r_write) ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE);
- rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->r_count);
- if (op->r_count == 0) {
+ int nr_sig = 0;
+
+ /* map the op the first time we see it */
+ if (!op->op_mapped) {
+ op->op_count = ib_dma_map_sg(ic->i_cm_id->device,
+ op->op_sg, op->op_nents, (op->op_write) ?
+ DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->op_count);
+ if (op->op_count == 0) {
rds_ib_stats_inc(s_ib_tx_sg_mapping_failure);
ret = -ENOMEM; /* XXX ? */
goto out;
}
- op->r_mapped = 1;
+ op->op_mapped = 1;
}
/*
* Instead of knowing how to return a partial rdma read/write we insist that there
* be enough work requests to send the entire message.
*/
- i = ceil(op->r_count, rds_ibdev->max_sge);
+ i = ceil(op->op_count, max_sge);
work_alloc = rds_ib_ring_alloc(&ic->i_send_ring, i, &pos);
if (work_alloc != i) {
@@ -788,30 +922,24 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
send = &ic->i_sends[pos];
first = send;
prev = NULL;
- scat = &op->r_sg[0];
+ scat = &op->op_sg[0];
sent = 0;
- num_sge = op->r_count;
+ num_sge = op->op_count;
- for (i = 0; i < work_alloc && scat != &op->r_sg[op->r_count]; i++) {
+ for (i = 0; i < work_alloc && scat != &op->op_sg[op->op_count]; i++) {
send->s_wr.send_flags = 0;
send->s_queued = jiffies;
- /*
- * We want to delay signaling completions just enough to get
- * the batching benefits but not so much that we create dead time on the wire.
- */
- if (ic->i_unsignaled_wrs-- == 0) {
- ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs;
- send->s_wr.send_flags = IB_SEND_SIGNALED;
- }
+ send->s_op = NULL;
+
+ nr_sig += rds_ib_set_wr_signal_state(ic, send, op->op_notify);
- send->s_wr.opcode = op->r_write ? IB_WR_RDMA_WRITE : IB_WR_RDMA_READ;
+ send->s_wr.opcode = op->op_write ? IB_WR_RDMA_WRITE : IB_WR_RDMA_READ;
send->s_wr.wr.rdma.remote_addr = remote_addr;
- send->s_wr.wr.rdma.rkey = op->r_key;
- send->s_op = op;
+ send->s_wr.wr.rdma.rkey = op->op_rkey;
- if (num_sge > rds_ibdev->max_sge) {
- send->s_wr.num_sge = rds_ibdev->max_sge;
- num_sge -= rds_ibdev->max_sge;
+ if (num_sge > max_sge) {
+ send->s_wr.num_sge = max_sge;
+ num_sge -= max_sge;
} else {
send->s_wr.num_sge = num_sge;
}
@@ -821,7 +949,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
if (prev)
prev->s_wr.next = &send->s_wr;
- for (j = 0; j < send->s_wr.num_sge && scat != &op->r_sg[op->r_count]; j++) {
+ for (j = 0; j < send->s_wr.num_sge && scat != &op->op_sg[op->op_count]; j++) {
len = ib_sg_dma_len(ic->i_cm_id->device, scat);
send->s_sge[j].addr =
ib_sg_dma_address(ic->i_cm_id->device, scat);
@@ -843,15 +971,20 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
send = ic->i_sends;
}
- /* if we finished the message then send completion owns it */
- if (scat == &op->r_sg[op->r_count])
- prev->s_wr.send_flags = IB_SEND_SIGNALED;
+ /* give a reference to the last op */
+ if (scat == &op->op_sg[op->op_count]) {
+ prev->s_op = op;
+ rds_message_addref(container_of(op, struct rds_message, rdma));
+ }
if (i < work_alloc) {
rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - i);
work_alloc = i;
}
+ if (nr_sig)
+ atomic_add(nr_sig, &ic->i_signaled_sends);
+
failed_wr = &first->s_wr;
ret = ib_post_send(ic->i_cm_id->qp, &first->s_wr, &failed_wr);
rdsdebug("ic %p first %p (wr %p) ret %d wr %p\n", ic,
@@ -861,6 +994,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
printk(KERN_WARNING "RDS/IB: rdma ib_post_send to %pI4 "
"returned %d\n", &conn->c_faddr, ret);
rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc);
+ rds_ib_sub_signaled(ic, nr_sig);
goto out;
}
diff --git a/net/rds/ib_stats.c b/net/rds/ib_stats.c
index d2c904dd6fbc..2d5965d6e97c 100644
--- a/net/rds/ib_stats.c
+++ b/net/rds/ib_stats.c
@@ -67,6 +67,8 @@ static const char *const rds_ib_stat_names[] = {
"ib_rdma_mr_pool_flush",
"ib_rdma_mr_pool_wait",
"ib_rdma_mr_pool_depleted",
+ "ib_atomic_cswp",
+ "ib_atomic_fadd",
};
unsigned int rds_ib_stats_info_copy(struct rds_info_iterator *iter,
diff --git a/net/rds/ib_sysctl.c b/net/rds/ib_sysctl.c
index 03f01cb4e0fe..1253b006efdb 100644
--- a/net/rds/ib_sysctl.c
+++ b/net/rds/ib_sysctl.c
@@ -49,10 +49,6 @@ unsigned long rds_ib_sysctl_max_unsig_wrs = 16;
static unsigned long rds_ib_sysctl_max_unsig_wr_min = 1;
static unsigned long rds_ib_sysctl_max_unsig_wr_max = 64;
-unsigned long rds_ib_sysctl_max_unsig_bytes = (16 << 20);
-static unsigned long rds_ib_sysctl_max_unsig_bytes_min = 1;
-static unsigned long rds_ib_sysctl_max_unsig_bytes_max = ~0UL;
-
/*
* This sysctl does nothing.
*
@@ -65,7 +61,7 @@ static unsigned long rds_ib_sysctl_max_unsig_bytes_max = ~0UL;
*/
unsigned int rds_ib_sysctl_flow_control = 0;
-ctl_table rds_ib_sysctl_table[] = {
+static ctl_table rds_ib_sysctl_table[] = {
{
.procname = "max_send_wr",
.data = &rds_ib_sysctl_max_send_wr,
@@ -94,15 +90,6 @@ ctl_table rds_ib_sysctl_table[] = {
.extra2 = &rds_ib_sysctl_max_unsig_wr_max,
},
{
- .procname = "max_unsignaled_bytes",
- .data = &rds_ib_sysctl_max_unsig_bytes,
- .maxlen = sizeof(unsigned long),
- .mode = 0644,
- .proc_handler = proc_doulongvec_minmax,
- .extra1 = &rds_ib_sysctl_max_unsig_bytes_min,
- .extra2 = &rds_ib_sysctl_max_unsig_bytes_max,
- },
- {
.procname = "max_recv_allocation",
.data = &rds_ib_sysctl_max_recv_allocation,
.maxlen = sizeof(unsigned long),
@@ -132,10 +119,10 @@ void rds_ib_sysctl_exit(void)
unregister_sysctl_table(rds_ib_sysctl_hdr);
}
-int __init rds_ib_sysctl_init(void)
+int rds_ib_sysctl_init(void)
{
rds_ib_sysctl_hdr = register_sysctl_paths(rds_ib_sysctl_path, rds_ib_sysctl_table);
- if (rds_ib_sysctl_hdr == NULL)
+ if (!rds_ib_sysctl_hdr)
return -ENOMEM;
return 0;
}
diff --git a/net/rds/info.c b/net/rds/info.c
index c45c4173a44d..4fdf1b6e84ff 100644
--- a/net/rds/info.c
+++ b/net/rds/info.c
@@ -76,7 +76,7 @@ void rds_info_register_func(int optname, rds_info_func func)
BUG_ON(optname < RDS_INFO_FIRST || optname > RDS_INFO_LAST);
spin_lock(&rds_info_lock);
- BUG_ON(rds_info_funcs[offset] != NULL);
+ BUG_ON(rds_info_funcs[offset]);
rds_info_funcs[offset] = func;
spin_unlock(&rds_info_lock);
}
@@ -102,7 +102,7 @@ EXPORT_SYMBOL_GPL(rds_info_deregister_func);
*/
void rds_info_iter_unmap(struct rds_info_iterator *iter)
{
- if (iter->addr != NULL) {
+ if (iter->addr) {
kunmap_atomic(iter->addr, KM_USER0);
iter->addr = NULL;
}
@@ -117,7 +117,7 @@ void rds_info_copy(struct rds_info_iterator *iter, void *data,
unsigned long this;
while (bytes) {
- if (iter->addr == NULL)
+ if (!iter->addr)
iter->addr = kmap_atomic(*iter->pages, KM_USER0);
this = min(bytes, PAGE_SIZE - iter->offset);
@@ -188,7 +188,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
>> PAGE_SHIFT;
pages = kmalloc(nr_pages * sizeof(struct page *), GFP_KERNEL);
- if (pages == NULL) {
+ if (!pages) {
ret = -ENOMEM;
goto out;
}
@@ -206,7 +206,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
call_func:
func = rds_info_funcs[optname - RDS_INFO_FIRST];
- if (func == NULL) {
+ if (!func) {
ret = -ENOPROTOOPT;
goto out;
}
@@ -234,7 +234,7 @@ call_func:
ret = -EFAULT;
out:
- for (i = 0; pages != NULL && i < nr_pages; i++)
+ for (i = 0; pages && i < nr_pages; i++)
put_page(pages[i]);
kfree(pages);
diff --git a/net/rds/iw.c b/net/rds/iw.c
index c8f3d3525cb9..5a9676fe594f 100644
--- a/net/rds/iw.c
+++ b/net/rds/iw.c
@@ -56,7 +56,7 @@ struct list_head rds_iw_devices;
DEFINE_SPINLOCK(iw_nodev_conns_lock);
LIST_HEAD(iw_nodev_conns);
-void rds_iw_add_one(struct ib_device *device)
+static void rds_iw_add_one(struct ib_device *device)
{
struct rds_iw_device *rds_iwdev;
struct ib_device_attr *dev_attr;
@@ -124,7 +124,7 @@ free_attr:
kfree(dev_attr);
}
-void rds_iw_remove_one(struct ib_device *device)
+static void rds_iw_remove_one(struct ib_device *device)
{
struct rds_iw_device *rds_iwdev;
struct rds_iw_cm_id *i_cm_id, *next;
@@ -264,7 +264,6 @@ struct rds_transport rds_iw_transport = {
.laddr_check = rds_iw_laddr_check,
.xmit_complete = rds_iw_xmit_complete,
.xmit = rds_iw_xmit,
- .xmit_cong_map = NULL,
.xmit_rdma = rds_iw_xmit_rdma,
.recv = rds_iw_recv,
.conn_alloc = rds_iw_conn_alloc,
@@ -272,7 +271,6 @@ struct rds_transport rds_iw_transport = {
.conn_connect = rds_iw_conn_connect,
.conn_shutdown = rds_iw_conn_shutdown,
.inc_copy_to_user = rds_iw_inc_copy_to_user,
- .inc_purge = rds_iw_inc_purge,
.inc_free = rds_iw_inc_free,
.cm_initiate_connect = rds_iw_cm_initiate_connect,
.cm_handle_connect = rds_iw_cm_handle_connect,
@@ -289,7 +287,7 @@ struct rds_transport rds_iw_transport = {
.t_prefer_loopback = 1,
};
-int __init rds_iw_init(void)
+int rds_iw_init(void)
{
int ret;
diff --git a/net/rds/iw.h b/net/rds/iw.h
index eef2f0c28476..90151922178c 100644
--- a/net/rds/iw.h
+++ b/net/rds/iw.h
@@ -70,7 +70,7 @@ struct rds_iw_send_work {
struct rds_message *s_rm;
/* We should really put these into a union: */
- struct rds_rdma_op *s_op;
+ struct rm_rdma_op *s_op;
struct rds_iw_mapping *s_mapping;
struct ib_mr *s_mr;
struct ib_fast_reg_page_list *s_page_list;
@@ -268,8 +268,6 @@ static inline u32 rds_iw_local_dma_lkey(struct rds_iw_connection *ic)
/* ib.c */
extern struct rds_transport rds_iw_transport;
-extern void rds_iw_add_one(struct ib_device *device);
-extern void rds_iw_remove_one(struct ib_device *device);
extern struct ib_client rds_iw_client;
extern unsigned int fastreg_pool_size;
@@ -284,7 +282,7 @@ void rds_iw_conn_free(void *arg);
int rds_iw_conn_connect(struct rds_connection *conn);
void rds_iw_conn_shutdown(struct rds_connection *conn);
void rds_iw_state_change(struct sock *sk);
-int __init rds_iw_listen_init(void);
+int rds_iw_listen_init(void);
void rds_iw_listen_stop(void);
void __rds_iw_conn_error(struct rds_connection *conn, const char *, ...);
int rds_iw_cm_handle_connect(struct rdma_cm_id *cm_id,
@@ -318,15 +316,13 @@ void *rds_iw_get_mr(struct scatterlist *sg, unsigned long nents,
void rds_iw_sync_mr(void *trans_private, int dir);
void rds_iw_free_mr(void *trans_private, int invalidate);
void rds_iw_flush_mrs(void);
-void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_id);
/* ib_recv.c */
-int __init rds_iw_recv_init(void);
+int rds_iw_recv_init(void);
void rds_iw_recv_exit(void);
int rds_iw_recv(struct rds_connection *conn);
int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp,
gfp_t page_gfp, int prefill);
-void rds_iw_inc_purge(struct rds_incoming *inc);
void rds_iw_inc_free(struct rds_incoming *inc);
int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
size_t size);
@@ -358,7 +354,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context);
void rds_iw_send_init_ring(struct rds_iw_connection *ic);
void rds_iw_send_clear_ring(struct rds_iw_connection *ic);
-int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op);
+int rds_iw_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op);
void rds_iw_send_add_credits(struct rds_connection *conn, unsigned int credits);
void rds_iw_advertise_credits(struct rds_connection *conn, unsigned int posted);
int rds_iw_send_grab_credits(struct rds_iw_connection *ic, u32 wanted,
@@ -371,7 +367,7 @@ unsigned int rds_iw_stats_info_copy(struct rds_info_iterator *iter,
unsigned int avail);
/* ib_sysctl.c */
-int __init rds_iw_sysctl_init(void);
+int rds_iw_sysctl_init(void);
void rds_iw_sysctl_exit(void);
extern unsigned long rds_iw_sysctl_max_send_wr;
extern unsigned long rds_iw_sysctl_max_recv_wr;
@@ -379,7 +375,6 @@ extern unsigned long rds_iw_sysctl_max_unsig_wrs;
extern unsigned long rds_iw_sysctl_max_unsig_bytes;
extern unsigned long rds_iw_sysctl_max_recv_allocation;
extern unsigned int rds_iw_sysctl_flow_control;
-extern ctl_table rds_iw_sysctl_table[];
/*
* Helper functions for getting/setting the header and data SGEs in
diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c
index b5dd6ac39be8..712cf2d1f28e 100644
--- a/net/rds/iw_cm.c
+++ b/net/rds/iw_cm.c
@@ -257,7 +257,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn)
* the rds_iwdev at all.
*/
rds_iwdev = ib_get_client_data(dev, &rds_iw_client);
- if (rds_iwdev == NULL) {
+ if (!rds_iwdev) {
if (printk_ratelimit())
printk(KERN_NOTICE "RDS/IW: No client_data for device %s\n",
dev->name);
@@ -292,7 +292,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn)
ic->i_send_ring.w_nr *
sizeof(struct rds_header),
&ic->i_send_hdrs_dma, GFP_KERNEL);
- if (ic->i_send_hdrs == NULL) {
+ if (!ic->i_send_hdrs) {
ret = -ENOMEM;
rdsdebug("ib_dma_alloc_coherent send failed\n");
goto out;
@@ -302,7 +302,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn)
ic->i_recv_ring.w_nr *
sizeof(struct rds_header),
&ic->i_recv_hdrs_dma, GFP_KERNEL);
- if (ic->i_recv_hdrs == NULL) {
+ if (!ic->i_recv_hdrs) {
ret = -ENOMEM;
rdsdebug("ib_dma_alloc_coherent recv failed\n");
goto out;
@@ -310,14 +310,14 @@ static int rds_iw_setup_qp(struct rds_connection *conn)
ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header),
&ic->i_ack_dma, GFP_KERNEL);
- if (ic->i_ack == NULL) {
+ if (!ic->i_ack) {
ret = -ENOMEM;
rdsdebug("ib_dma_alloc_coherent ack failed\n");
goto out;
}
ic->i_sends = vmalloc(ic->i_send_ring.w_nr * sizeof(struct rds_iw_send_work));
- if (ic->i_sends == NULL) {
+ if (!ic->i_sends) {
ret = -ENOMEM;
rdsdebug("send allocation failed\n");
goto out;
@@ -325,7 +325,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn)
rds_iw_send_init_ring(ic);
ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_iw_recv_work));
- if (ic->i_recvs == NULL) {
+ if (!ic->i_recvs) {
ret = -ENOMEM;
rdsdebug("recv allocation failed\n");
goto out;
@@ -696,7 +696,7 @@ int rds_iw_conn_alloc(struct rds_connection *conn, gfp_t gfp)
/* XXX too lazy? */
ic = kzalloc(sizeof(struct rds_iw_connection), GFP_KERNEL);
- if (ic == NULL)
+ if (!ic)
return -ENOMEM;
INIT_LIST_HEAD(&ic->iw_node);
diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c
index 13dc1862d862..59509e9a9e72 100644
--- a/net/rds/iw_rdma.c
+++ b/net/rds/iw_rdma.c
@@ -34,7 +34,6 @@
#include <linux/slab.h>
#include "rds.h"
-#include "rdma.h"
#include "iw.h"
@@ -158,7 +157,8 @@ static int rds_iw_add_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *
return 0;
}
-void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_id)
+static void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev,
+ struct rdma_cm_id *cm_id)
{
struct rds_iw_cm_id *i_cm_id;
@@ -207,9 +207,9 @@ void rds_iw_add_conn(struct rds_iw_device *rds_iwdev, struct rds_connection *con
BUG_ON(list_empty(&ic->iw_node));
list_del(&ic->iw_node);
- spin_lock_irq(&rds_iwdev->spinlock);
+ spin_lock(&rds_iwdev->spinlock);
list_add_tail(&ic->iw_node, &rds_iwdev->conn_list);
- spin_unlock_irq(&rds_iwdev->spinlock);
+ spin_unlock(&rds_iwdev->spinlock);
spin_unlock_irq(&iw_nodev_conns_lock);
ic->rds_iwdev = rds_iwdev;
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c
index 3d479067d54d..5e57347f49ff 100644
--- a/net/rds/iw_recv.c
+++ b/net/rds/iw_recv.c
@@ -53,7 +53,7 @@ static void rds_iw_frag_drop_page(struct rds_page_frag *frag)
static void rds_iw_frag_free(struct rds_page_frag *frag)
{
rdsdebug("frag %p page %p\n", frag, frag->f_page);
- BUG_ON(frag->f_page != NULL);
+ BUG_ON(frag->f_page);
kmem_cache_free(rds_iw_frag_slab, frag);
}
@@ -143,14 +143,14 @@ static int rds_iw_recv_refill_one(struct rds_connection *conn,
struct ib_sge *sge;
int ret = -ENOMEM;
- if (recv->r_iwinc == NULL) {
+ if (!recv->r_iwinc) {
if (!atomic_add_unless(&rds_iw_allocation, 1, rds_iw_sysctl_max_recv_allocation)) {
rds_iw_stats_inc(s_iw_rx_alloc_limit);
goto out;
}
recv->r_iwinc = kmem_cache_alloc(rds_iw_incoming_slab,
kptr_gfp);
- if (recv->r_iwinc == NULL) {
+ if (!recv->r_iwinc) {
atomic_dec(&rds_iw_allocation);
goto out;
}
@@ -158,17 +158,17 @@ static int rds_iw_recv_refill_one(struct rds_connection *conn,
rds_inc_init(&recv->r_iwinc->ii_inc, conn, conn->c_faddr);
}
- if (recv->r_frag == NULL) {
+ if (!recv->r_frag) {
recv->r_frag = kmem_cache_alloc(rds_iw_frag_slab, kptr_gfp);
- if (recv->r_frag == NULL)
+ if (!recv->r_frag)
goto out;
INIT_LIST_HEAD(&recv->r_frag->f_item);
recv->r_frag->f_page = NULL;
}
- if (ic->i_frag.f_page == NULL) {
+ if (!ic->i_frag.f_page) {
ic->i_frag.f_page = alloc_page(page_gfp);
- if (ic->i_frag.f_page == NULL)
+ if (!ic->i_frag.f_page)
goto out;
ic->i_frag.f_offset = 0;
}
@@ -273,7 +273,7 @@ int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp,
return ret;
}
-void rds_iw_inc_purge(struct rds_incoming *inc)
+static void rds_iw_inc_purge(struct rds_incoming *inc)
{
struct rds_iw_incoming *iwinc;
struct rds_page_frag *frag;
@@ -716,7 +716,7 @@ static void rds_iw_process_recv(struct rds_connection *conn,
* into the inc and save the inc so we can hang upcoming fragments
* off its list.
*/
- if (iwinc == NULL) {
+ if (!iwinc) {
iwinc = recv->r_iwinc;
recv->r_iwinc = NULL;
ic->i_iwinc = iwinc;
@@ -887,7 +887,7 @@ int rds_iw_recv(struct rds_connection *conn)
return ret;
}
-int __init rds_iw_recv_init(void)
+int rds_iw_recv_init(void)
{
struct sysinfo si;
int ret = -ENOMEM;
@@ -899,13 +899,13 @@ int __init rds_iw_recv_init(void)
rds_iw_incoming_slab = kmem_cache_create("rds_iw_incoming",
sizeof(struct rds_iw_incoming),
0, 0, NULL);
- if (rds_iw_incoming_slab == NULL)
+ if (!rds_iw_incoming_slab)
goto out;
rds_iw_frag_slab = kmem_cache_create("rds_iw_frag",
sizeof(struct rds_page_frag),
0, 0, NULL);
- if (rds_iw_frag_slab == NULL)
+ if (!rds_iw_frag_slab)
kmem_cache_destroy(rds_iw_incoming_slab);
else
ret = 0;
diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c
index 52182ff7519e..6280ea020d4e 100644
--- a/net/rds/iw_send.c
+++ b/net/rds/iw_send.c
@@ -36,7 +36,6 @@
#include <linux/dmapool.h>
#include "rds.h"
-#include "rdma.h"
#include "iw.h"
static void rds_iw_send_rdma_complete(struct rds_message *rm,
@@ -64,13 +63,13 @@ static void rds_iw_send_rdma_complete(struct rds_message *rm,
}
static void rds_iw_send_unmap_rdma(struct rds_iw_connection *ic,
- struct rds_rdma_op *op)
+ struct rm_rdma_op *op)
{
- if (op->r_mapped) {
+ if (op->op_mapped) {
ib_dma_unmap_sg(ic->i_cm_id->device,
- op->r_sg, op->r_nents,
- op->r_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
- op->r_mapped = 0;
+ op->op_sg, op->op_nents,
+ op->op_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ op->op_mapped = 0;
}
}
@@ -83,11 +82,11 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic,
rdsdebug("ic %p send %p rm %p\n", ic, send, rm);
ib_dma_unmap_sg(ic->i_cm_id->device,
- rm->m_sg, rm->m_nents,
+ rm->data.op_sg, rm->data.op_nents,
DMA_TO_DEVICE);
- if (rm->m_rdma_op != NULL) {
- rds_iw_send_unmap_rdma(ic, rm->m_rdma_op);
+ if (rm->rdma.op_active) {
+ rds_iw_send_unmap_rdma(ic, &rm->rdma);
/* If the user asked for a completion notification on this
* message, we can implement three different semantics:
@@ -111,10 +110,10 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic,
*/
rds_iw_send_rdma_complete(rm, wc_status);
- if (rm->m_rdma_op->r_write)
- rds_stats_add(s_send_rdma_bytes, rm->m_rdma_op->r_bytes);
+ if (rm->rdma.op_write)
+ rds_stats_add(s_send_rdma_bytes, rm->rdma.op_bytes);
else
- rds_stats_add(s_recv_rdma_bytes, rm->m_rdma_op->r_bytes);
+ rds_stats_add(s_recv_rdma_bytes, rm->rdma.op_bytes);
}
/* If anyone waited for this message to get flushed out, wake
@@ -556,25 +555,27 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
}
/* map the message the first time we see it */
- if (ic->i_rm == NULL) {
+ if (!ic->i_rm) {
/*
printk(KERN_NOTICE "rds_iw_xmit prep msg dport=%u flags=0x%x len=%d\n",
be16_to_cpu(rm->m_inc.i_hdr.h_dport),
rm->m_inc.i_hdr.h_flags,
be32_to_cpu(rm->m_inc.i_hdr.h_len));
*/
- if (rm->m_nents) {
- rm->m_count = ib_dma_map_sg(dev,
- rm->m_sg, rm->m_nents, DMA_TO_DEVICE);
- rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->m_count);
- if (rm->m_count == 0) {
+ if (rm->data.op_nents) {
+ rm->data.op_count = ib_dma_map_sg(dev,
+ rm->data.op_sg,
+ rm->data.op_nents,
+ DMA_TO_DEVICE);
+ rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->data.op_count);
+ if (rm->data.op_count == 0) {
rds_iw_stats_inc(s_iw_tx_sg_mapping_failure);
rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc);
ret = -ENOMEM; /* XXX ? */
goto out;
}
} else {
- rm->m_count = 0;
+ rm->data.op_count = 0;
}
ic->i_unsignaled_wrs = rds_iw_sysctl_max_unsig_wrs;
@@ -590,10 +591,10 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
/* If it has a RDMA op, tell the peer we did it. This is
* used by the peer to release use-once RDMA MRs. */
- if (rm->m_rdma_op) {
+ if (rm->rdma.op_active) {
struct rds_ext_header_rdma ext_hdr;
- ext_hdr.h_rdma_rkey = cpu_to_be32(rm->m_rdma_op->r_key);
+ ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.op_rkey);
rds_message_add_extension(&rm->m_inc.i_hdr,
RDS_EXTHDR_RDMA, &ext_hdr, sizeof(ext_hdr));
}
@@ -621,7 +622,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
send = &ic->i_sends[pos];
first = send;
prev = NULL;
- scat = &rm->m_sg[sg];
+ scat = &rm->data.op_sg[sg];
sent = 0;
i = 0;
@@ -631,7 +632,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
* or when requested by the user. Right now, we let
* the application choose.
*/
- if (rm->m_rdma_op && rm->m_rdma_op->r_fence)
+ if (rm->rdma.op_active && rm->rdma.op_fence)
send_flags = IB_SEND_FENCE;
/*
@@ -650,7 +651,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
}
/* if there's data reference it with a chain of work reqs */
- for (; i < work_alloc && scat != &rm->m_sg[rm->m_count]; i++) {
+ for (; i < work_alloc && scat != &rm->data.op_sg[rm->data.op_count]; i++) {
unsigned int len;
send = &ic->i_sends[pos];
@@ -728,7 +729,7 @@ add_header:
sent += sizeof(struct rds_header);
/* if we finished the message then send completion owns it */
- if (scat == &rm->m_sg[rm->m_count]) {
+ if (scat == &rm->data.op_sg[rm->data.op_count]) {
prev->s_rm = ic->i_rm;
prev->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED;
ic->i_rm = NULL;
@@ -784,7 +785,7 @@ static void rds_iw_build_send_fastreg(struct rds_iw_device *rds_iwdev, struct rd
ib_update_fast_reg_key(send->s_mr, send->s_remap_count++);
}
-int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
+int rds_iw_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op)
{
struct rds_iw_connection *ic = conn->c_transport_data;
struct rds_iw_send_work *send = NULL;
@@ -794,7 +795,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
struct rds_iw_device *rds_iwdev;
struct scatterlist *scat;
unsigned long len;
- u64 remote_addr = op->r_remote_addr;
+ u64 remote_addr = op->op_remote_addr;
u32 pos, fr_pos;
u32 work_alloc;
u32 i;
@@ -806,21 +807,21 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
rds_iwdev = ib_get_client_data(ic->i_cm_id->device, &rds_iw_client);
/* map the message the first time we see it */
- if (!op->r_mapped) {
- op->r_count = ib_dma_map_sg(ic->i_cm_id->device,
- op->r_sg, op->r_nents, (op->r_write) ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE);
- rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->r_count);
- if (op->r_count == 0) {
+ if (!op->op_mapped) {
+ op->op_count = ib_dma_map_sg(ic->i_cm_id->device,
+ op->op_sg, op->op_nents, (op->op_write) ?
+ DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->op_count);
+ if (op->op_count == 0) {
rds_iw_stats_inc(s_iw_tx_sg_mapping_failure);
ret = -ENOMEM; /* XXX ? */
goto out;
}
- op->r_mapped = 1;
+ op->op_mapped = 1;
}
- if (!op->r_write) {
+ if (!op->op_write) {
/* Alloc space on the send queue for the fastreg */
work_alloc = rds_iw_ring_alloc(&ic->i_send_ring, 1, &fr_pos);
if (work_alloc != 1) {
@@ -835,7 +836,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
* Instead of knowing how to return a partial rdma read/write we insist that there
* be enough work requests to send the entire message.
*/
- i = ceil(op->r_count, rds_iwdev->max_sge);
+ i = ceil(op->op_count, rds_iwdev->max_sge);
work_alloc = rds_iw_ring_alloc(&ic->i_send_ring, i, &pos);
if (work_alloc != i) {
@@ -846,17 +847,17 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
}
send = &ic->i_sends[pos];
- if (!op->r_write) {
+ if (!op->op_write) {
first = prev = &ic->i_sends[fr_pos];
} else {
first = send;
prev = NULL;
}
- scat = &op->r_sg[0];
+ scat = &op->op_sg[0];
sent = 0;
- num_sge = op->r_count;
+ num_sge = op->op_count;
- for (i = 0; i < work_alloc && scat != &op->r_sg[op->r_count]; i++) {
+ for (i = 0; i < work_alloc && scat != &op->op_sg[op->op_count]; i++) {
send->s_wr.send_flags = 0;
send->s_queued = jiffies;
@@ -873,13 +874,13 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
* for local access after RDS is finished with it, using
* IB_WR_RDMA_READ_WITH_INV will invalidate it after the read has completed.
*/
- if (op->r_write)
+ if (op->op_write)
send->s_wr.opcode = IB_WR_RDMA_WRITE;
else
send->s_wr.opcode = IB_WR_RDMA_READ_WITH_INV;
send->s_wr.wr.rdma.remote_addr = remote_addr;
- send->s_wr.wr.rdma.rkey = op->r_key;
+ send->s_wr.wr.rdma.rkey = op->op_rkey;
send->s_op = op;
if (num_sge > rds_iwdev->max_sge) {
@@ -893,7 +894,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
if (prev)
prev->s_wr.next = &send->s_wr;
- for (j = 0; j < send->s_wr.num_sge && scat != &op->r_sg[op->r_count]; j++) {
+ for (j = 0; j < send->s_wr.num_sge && scat != &op->op_sg[op->op_count]; j++) {
len = ib_sg_dma_len(ic->i_cm_id->device, scat);
if (send->s_wr.opcode == IB_WR_RDMA_READ_WITH_INV)
@@ -927,7 +928,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
}
/* if we finished the message then send completion owns it */
- if (scat == &op->r_sg[op->r_count])
+ if (scat == &op->op_sg[op->op_count])
first->s_wr.send_flags = IB_SEND_SIGNALED;
if (i < work_alloc) {
@@ -941,9 +942,9 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op)
* adapters do not allow using the lkey for this at all. To bypass this use a
* fastreg_mr (or possibly a dma_mr)
*/
- if (!op->r_write) {
+ if (!op->op_write) {
rds_iw_build_send_fastreg(rds_iwdev, ic, &ic->i_sends[fr_pos],
- op->r_count, sent, conn->c_xmit_rm->m_rs->rs_user_addr);
+ op->op_count, sent, conn->c_xmit_rm->m_rs->rs_user_addr);
work_alloc++;
}
diff --git a/net/rds/iw_sysctl.c b/net/rds/iw_sysctl.c
index 1c4428a61a02..e2e47176e729 100644
--- a/net/rds/iw_sysctl.c
+++ b/net/rds/iw_sysctl.c
@@ -55,7 +55,7 @@ static unsigned long rds_iw_sysctl_max_unsig_bytes_max = ~0UL;
unsigned int rds_iw_sysctl_flow_control = 1;
-ctl_table rds_iw_sysctl_table[] = {
+static ctl_table rds_iw_sysctl_table[] = {
{
.procname = "max_send_wr",
.data = &rds_iw_sysctl_max_send_wr,
@@ -122,10 +122,10 @@ void rds_iw_sysctl_exit(void)
unregister_sysctl_table(rds_iw_sysctl_hdr);
}
-int __init rds_iw_sysctl_init(void)
+int rds_iw_sysctl_init(void)
{
rds_iw_sysctl_hdr = register_sysctl_paths(rds_iw_sysctl_path, rds_iw_sysctl_table);
- if (rds_iw_sysctl_hdr == NULL)
+ if (!rds_iw_sysctl_hdr)
return -ENOMEM;
return 0;
}
diff --git a/net/rds/loop.c b/net/rds/loop.c
index dd9879379457..c390156b426f 100644
--- a/net/rds/loop.c
+++ b/net/rds/loop.c
@@ -61,10 +61,17 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm,
unsigned int hdr_off, unsigned int sg,
unsigned int off)
{
+ /* Do not send cong updates to loopback */
+ if (rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) {
+ rds_cong_map_updated(conn->c_fcong, ~(u64) 0);
+ return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES;
+ }
+
BUG_ON(hdr_off || sg || off);
rds_inc_init(&rm->m_inc, conn, conn->c_laddr);
- rds_message_addref(rm); /* for the inc */
+ /* For the embedded inc. Matching put is in loop_inc_free() */
+ rds_message_addref(rm);
rds_recv_incoming(conn, conn->c_laddr, conn->c_faddr, &rm->m_inc,
GFP_KERNEL, KM_USER0);
@@ -77,16 +84,14 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm,
return sizeof(struct rds_header) + be32_to_cpu(rm->m_inc.i_hdr.h_len);
}
-static int rds_loop_xmit_cong_map(struct rds_connection *conn,
- struct rds_cong_map *map,
- unsigned long offset)
+/*
+ * See rds_loop_xmit(). Since our inc is embedded in the rm, we
+ * make sure the rm lives at least until the inc is done.
+ */
+static void rds_loop_inc_free(struct rds_incoming *inc)
{
- BUG_ON(offset);
- BUG_ON(map != conn->c_lcong);
-
- rds_cong_map_updated(conn->c_fcong, ~(u64) 0);
-
- return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES;
+ struct rds_message *rm = container_of(inc, struct rds_message, m_inc);
+ rds_message_put(rm);
}
/* we need to at least give the thread something to succeed */
@@ -112,7 +117,7 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp)
unsigned long flags;
lc = kzalloc(sizeof(struct rds_loop_connection), GFP_KERNEL);
- if (lc == NULL)
+ if (!lc)
return -ENOMEM;
INIT_LIST_HEAD(&lc->loop_node);
@@ -169,14 +174,12 @@ void rds_loop_exit(void)
*/
struct rds_transport rds_loop_transport = {
.xmit = rds_loop_xmit,
- .xmit_cong_map = rds_loop_xmit_cong_map,
.recv = rds_loop_recv,
.conn_alloc = rds_loop_conn_alloc,
.conn_free = rds_loop_conn_free,
.conn_connect = rds_loop_conn_connect,
.conn_shutdown = rds_loop_conn_shutdown,
.inc_copy_to_user = rds_message_inc_copy_to_user,
- .inc_purge = rds_message_inc_purge,
- .inc_free = rds_message_inc_free,
+ .inc_free = rds_loop_inc_free,
.t_name = "loopback",
};
diff --git a/net/rds/message.c b/net/rds/message.c
index 9a1d67e001ba..a84545dae370 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -34,9 +34,6 @@
#include <linux/slab.h>
#include "rds.h"
-#include "rdma.h"
-
-static DECLARE_WAIT_QUEUE_HEAD(rds_message_flush_waitq);
static unsigned int rds_exthdr_size[__RDS_EXTHDR_MAX] = {
[RDS_EXTHDR_NONE] = 0,
@@ -63,29 +60,31 @@ static void rds_message_purge(struct rds_message *rm)
if (unlikely(test_bit(RDS_MSG_PAGEVEC, &rm->m_flags)))
return;
- for (i = 0; i < rm->m_nents; i++) {
- rdsdebug("putting data page %p\n", (void *)sg_page(&rm->m_sg[i]));
+ for (i = 0; i < rm->data.op_nents; i++) {
+ rdsdebug("putting data page %p\n", (void *)sg_page(&rm->data.op_sg[i]));
/* XXX will have to put_page for page refs */
- __free_page(sg_page(&rm->m_sg[i]));
+ __free_page(sg_page(&rm->data.op_sg[i]));
}
- rm->m_nents = 0;
+ rm->data.op_nents = 0;
- if (rm->m_rdma_op)
- rds_rdma_free_op(rm->m_rdma_op);
- if (rm->m_rdma_mr)
- rds_mr_put(rm->m_rdma_mr);
-}
+ if (rm->rdma.op_active)
+ rds_rdma_free_op(&rm->rdma);
+ if (rm->rdma.op_rdma_mr)
+ rds_mr_put(rm->rdma.op_rdma_mr);
-void rds_message_inc_purge(struct rds_incoming *inc)
-{
- struct rds_message *rm = container_of(inc, struct rds_message, m_inc);
- rds_message_purge(rm);
+ if (rm->atomic.op_active)
+ rds_atomic_free_op(&rm->atomic);
+ if (rm->atomic.op_rdma_mr)
+ rds_mr_put(rm->atomic.op_rdma_mr);
}
void rds_message_put(struct rds_message *rm)
{
rdsdebug("put rm %p ref %d\n", rm, atomic_read(&rm->m_refcount));
-
+ if (atomic_read(&rm->m_refcount) == 0) {
+printk(KERN_CRIT "danger refcount zero on %p\n", rm);
+WARN_ON(1);
+ }
if (atomic_dec_and_test(&rm->m_refcount)) {
BUG_ON(!list_empty(&rm->m_sock_item));
BUG_ON(!list_empty(&rm->m_conn_item));
@@ -96,12 +95,6 @@ void rds_message_put(struct rds_message *rm)
}
EXPORT_SYMBOL_GPL(rds_message_put);
-void rds_message_inc_free(struct rds_incoming *inc)
-{
- struct rds_message *rm = container_of(inc, struct rds_message, m_inc);
- rds_message_put(rm);
-}
-
void rds_message_populate_header(struct rds_header *hdr, __be16 sport,
__be16 dport, u64 seq)
{
@@ -113,8 +106,8 @@ void rds_message_populate_header(struct rds_header *hdr, __be16 sport,
}
EXPORT_SYMBOL_GPL(rds_message_populate_header);
-int rds_message_add_extension(struct rds_header *hdr,
- unsigned int type, const void *data, unsigned int len)
+int rds_message_add_extension(struct rds_header *hdr, unsigned int type,
+ const void *data, unsigned int len)
{
unsigned int ext_len = sizeof(u8) + len;
unsigned char *dst;
@@ -184,26 +177,6 @@ none:
return RDS_EXTHDR_NONE;
}
-int rds_message_add_version_extension(struct rds_header *hdr, unsigned int version)
-{
- struct rds_ext_header_version ext_hdr;
-
- ext_hdr.h_version = cpu_to_be32(version);
- return rds_message_add_extension(hdr, RDS_EXTHDR_VERSION, &ext_hdr, sizeof(ext_hdr));
-}
-
-int rds_message_get_version_extension(struct rds_header *hdr, unsigned int *version)
-{
- struct rds_ext_header_version ext_hdr;
- unsigned int pos = 0, len = sizeof(ext_hdr);
-
- /* We assume the version extension is the only one present */
- if (rds_message_next_extension(hdr, &pos, &ext_hdr, &len) != RDS_EXTHDR_VERSION)
- return 0;
- *version = be32_to_cpu(ext_hdr.h_version);
- return 1;
-}
-
int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset)
{
struct rds_ext_header_rdma_dest ext_hdr;
@@ -214,41 +187,68 @@ int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 o
}
EXPORT_SYMBOL_GPL(rds_message_add_rdma_dest_extension);
-struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp)
+/*
+ * Each rds_message is allocated with extra space for the scatterlist entries
+ * rds ops will need. This is to minimize memory allocation count. Then, each rds op
+ * can grab SGs when initializing its part of the rds_message.
+ */
+struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp)
{
struct rds_message *rm;
- rm = kzalloc(sizeof(struct rds_message) +
- (nents * sizeof(struct scatterlist)), gfp);
+ rm = kzalloc(sizeof(struct rds_message) + extra_len, gfp);
if (!rm)
goto out;
- if (nents)
- sg_init_table(rm->m_sg, nents);
+ rm->m_used_sgs = 0;
+ rm->m_total_sgs = extra_len / sizeof(struct scatterlist);
+
atomic_set(&rm->m_refcount, 1);
INIT_LIST_HEAD(&rm->m_sock_item);
INIT_LIST_HEAD(&rm->m_conn_item);
spin_lock_init(&rm->m_rs_lock);
+ init_waitqueue_head(&rm->m_flush_wait);
out:
return rm;
}
+/*
+ * RDS ops use this to grab SG entries from the rm's sg pool.
+ */
+struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents)
+{
+ struct scatterlist *sg_first = (struct scatterlist *) &rm[1];
+ struct scatterlist *sg_ret;
+
+ WARN_ON(rm->m_used_sgs + nents > rm->m_total_sgs);
+ WARN_ON(!nents);
+
+ sg_ret = &sg_first[rm->m_used_sgs];
+ sg_init_table(sg_ret, nents);
+ rm->m_used_sgs += nents;
+
+ return sg_ret;
+}
+
struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len)
{
struct rds_message *rm;
unsigned int i;
+ int num_sgs = ceil(total_len, PAGE_SIZE);
+ int extra_bytes = num_sgs * sizeof(struct scatterlist);
- rm = rds_message_alloc(ceil(total_len, PAGE_SIZE), GFP_KERNEL);
- if (rm == NULL)
+ rm = rds_message_alloc(extra_bytes, GFP_NOWAIT);
+ if (!rm)
return ERR_PTR(-ENOMEM);
set_bit(RDS_MSG_PAGEVEC, &rm->m_flags);
rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len);
- rm->m_nents = ceil(total_len, PAGE_SIZE);
+ rm->data.op_nents = ceil(total_len, PAGE_SIZE);
+ rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs);
- for (i = 0; i < rm->m_nents; ++i) {
- sg_set_page(&rm->m_sg[i],
+ for (i = 0; i < rm->data.op_nents; ++i) {
+ sg_set_page(&rm->data.op_sg[i],
virt_to_page(page_addrs[i]),
PAGE_SIZE, 0);
}
@@ -256,40 +256,33 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
return rm;
}
-struct rds_message *rds_message_copy_from_user(struct iovec *first_iov,
+int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov,
size_t total_len)
{
unsigned long to_copy;
unsigned long iov_off;
unsigned long sg_off;
- struct rds_message *rm;
struct iovec *iov;
struct scatterlist *sg;
- int ret;
-
- rm = rds_message_alloc(ceil(total_len, PAGE_SIZE), GFP_KERNEL);
- if (rm == NULL) {
- ret = -ENOMEM;
- goto out;
- }
+ int ret = 0;
rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len);
/*
* now allocate and copy in the data payload.
*/
- sg = rm->m_sg;
+ sg = rm->data.op_sg;
iov = first_iov;
iov_off = 0;
sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */
while (total_len) {
- if (sg_page(sg) == NULL) {
+ if (!sg_page(sg)) {
ret = rds_page_remainder_alloc(sg, total_len,
GFP_HIGHUSER);
if (ret)
goto out;
- rm->m_nents++;
+ rm->data.op_nents++;
sg_off = 0;
}
@@ -320,14 +313,8 @@ struct rds_message *rds_message_copy_from_user(struct iovec *first_iov,
sg++;
}
- ret = 0;
out:
- if (ret) {
- if (rm)
- rds_message_put(rm);
- rm = ERR_PTR(ret);
- }
- return rm;
+ return ret;
}
int rds_message_inc_copy_to_user(struct rds_incoming *inc,
@@ -348,7 +335,7 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc,
iov = first_iov;
iov_off = 0;
- sg = rm->m_sg;
+ sg = rm->data.op_sg;
vec_off = 0;
copied = 0;
@@ -394,15 +381,14 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc,
*/
void rds_message_wait(struct rds_message *rm)
{
- wait_event(rds_message_flush_waitq,
+ wait_event_interruptible(rm->m_flush_wait,
!test_bit(RDS_MSG_MAPPED, &rm->m_flags));
}
void rds_message_unmapped(struct rds_message *rm)
{
clear_bit(RDS_MSG_MAPPED, &rm->m_flags);
- if (waitqueue_active(&rds_message_flush_waitq))
- wake_up(&rds_message_flush_waitq);
+ wake_up_interruptible(&rm->m_flush_wait);
}
EXPORT_SYMBOL_GPL(rds_message_unmapped);
diff --git a/net/rds/page.c b/net/rds/page.c
index 1dfbfea12e9b..d8acdebe3c7c 100644
--- a/net/rds/page.c
+++ b/net/rds/page.c
@@ -40,7 +40,8 @@ struct rds_page_remainder {
unsigned long r_offset;
};
-DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_page_remainder, rds_page_remainders);
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_page_remainder,
+ rds_page_remainders);
/*
* returns 0 on success or -errno on failure.
@@ -103,7 +104,7 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes,
/* jump straight to allocation if we're trying for a huge page */
if (bytes >= PAGE_SIZE) {
page = alloc_page(gfp);
- if (page == NULL) {
+ if (!page) {
ret = -ENOMEM;
} else {
sg_set_page(scat, page, PAGE_SIZE, 0);
@@ -149,7 +150,7 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes,
rem = &per_cpu(rds_page_remainders, get_cpu());
local_irq_save(flags);
- if (page == NULL) {
+ if (!page) {
ret = -ENOMEM;
break;
}
@@ -173,6 +174,7 @@ out:
ret ? 0 : scat->length);
return ret;
}
+EXPORT_SYMBOL_GPL(rds_page_remainder_alloc);
static int rds_page_remainder_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 75fd13bb631b..1a41debca1ce 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -35,7 +35,7 @@
#include <linux/rbtree.h>
#include <linux/dma-mapping.h> /* for DMA_*_DEVICE */
-#include "rdma.h"
+#include "rds.h"
/*
* XXX
@@ -130,14 +130,22 @@ void rds_rdma_drop_keys(struct rds_sock *rs)
{
struct rds_mr *mr;
struct rb_node *node;
+ unsigned long flags;
/* Release any MRs associated with this socket */
+ spin_lock_irqsave(&rs->rs_rdma_lock, flags);
while ((node = rb_first(&rs->rs_rdma_keys))) {
mr = container_of(node, struct rds_mr, r_rb_node);
if (mr->r_trans == rs->rs_transport)
mr->r_invalidate = 0;
+ rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys);
+ RB_CLEAR_NODE(&mr->r_rb_node);
+ spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
+ rds_destroy_mr(mr);
rds_mr_put(mr);
+ spin_lock_irqsave(&rs->rs_rdma_lock, flags);
}
+ spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
if (rs->rs_transport && rs->rs_transport->flush_mrs)
rs->rs_transport->flush_mrs();
@@ -181,7 +189,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
goto out;
}
- if (rs->rs_transport->get_mr == NULL) {
+ if (!rs->rs_transport->get_mr) {
ret = -EOPNOTSUPP;
goto out;
}
@@ -197,13 +205,13 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
/* XXX clamp nr_pages to limit the size of this alloc? */
pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL);
- if (pages == NULL) {
+ if (!pages) {
ret = -ENOMEM;
goto out;
}
mr = kzalloc(sizeof(struct rds_mr), GFP_KERNEL);
- if (mr == NULL) {
+ if (!mr) {
ret = -ENOMEM;
goto out;
}
@@ -230,13 +238,13 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
* r/o or r/w. We need to assume r/w, or we'll do a lot of RDMA to
* the zero page.
*/
- ret = rds_pin_pages(args->vec.addr & PAGE_MASK, nr_pages, pages, 1);
+ ret = rds_pin_pages(args->vec.addr, nr_pages, pages, 1);
if (ret < 0)
goto out;
nents = ret;
sg = kcalloc(nents, sizeof(*sg), GFP_KERNEL);
- if (sg == NULL) {
+ if (!sg) {
ret = -ENOMEM;
goto out;
}
@@ -406,68 +414,127 @@ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force)
spin_lock_irqsave(&rs->rs_rdma_lock, flags);
mr = rds_mr_tree_walk(&rs->rs_rdma_keys, r_key, NULL);
- if (mr && (mr->r_use_once || force)) {
+ if (!mr) {
+ printk(KERN_ERR "rds: trying to unuse MR with unknown r_key %u!\n", r_key);
+ spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
+ return;
+ }
+
+ if (mr->r_use_once || force) {
rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys);
RB_CLEAR_NODE(&mr->r_rb_node);
zot_me = 1;
- } else if (mr)
- atomic_inc(&mr->r_refcount);
+ }
spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
/* May have to issue a dma_sync on this memory region.
* Note we could avoid this if the operation was a RDMA READ,
* but at this point we can't tell. */
- if (mr != NULL) {
- if (mr->r_trans->sync_mr)
- mr->r_trans->sync_mr(mr->r_trans_private, DMA_FROM_DEVICE);
-
- /* If the MR was marked as invalidate, this will
- * trigger an async flush. */
- if (zot_me)
- rds_destroy_mr(mr);
- rds_mr_put(mr);
- }
+ if (mr->r_trans->sync_mr)
+ mr->r_trans->sync_mr(mr->r_trans_private, DMA_FROM_DEVICE);
+
+ /* If the MR was marked as invalidate, this will
+ * trigger an async flush. */
+ if (zot_me)
+ rds_destroy_mr(mr);
+ rds_mr_put(mr);
}
-void rds_rdma_free_op(struct rds_rdma_op *ro)
+void rds_rdma_free_op(struct rm_rdma_op *ro)
{
unsigned int i;
- for (i = 0; i < ro->r_nents; i++) {
- struct page *page = sg_page(&ro->r_sg[i]);
+ for (i = 0; i < ro->op_nents; i++) {
+ struct page *page = sg_page(&ro->op_sg[i]);
/* Mark page dirty if it was possibly modified, which
* is the case for a RDMA_READ which copies from remote
* to local memory */
- if (!ro->r_write) {
- BUG_ON(in_interrupt());
+ if (!ro->op_write) {
+ BUG_ON(irqs_disabled());
set_page_dirty(page);
}
put_page(page);
}
- kfree(ro->r_notifier);
- kfree(ro);
+ kfree(ro->op_notifier);
+ ro->op_notifier = NULL;
+ ro->op_active = 0;
+}
+
+void rds_atomic_free_op(struct rm_atomic_op *ao)
+{
+ struct page *page = sg_page(ao->op_sg);
+
+ /* Mark page dirty if it was possibly modified, which
+ * is the case for a RDMA_READ which copies from remote
+ * to local memory */
+ set_page_dirty(page);
+ put_page(page);
+
+ kfree(ao->op_notifier);
+ ao->op_notifier = NULL;
+ ao->op_active = 0;
}
+
/*
- * args is a pointer to an in-kernel copy in the sendmsg cmsg.
+ * Count the number of pages needed to describe an incoming iovec.
*/
-static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs,
- struct rds_rdma_args *args)
+static int rds_rdma_pages(struct rds_rdma_args *args)
{
struct rds_iovec vec;
- struct rds_rdma_op *op = NULL;
+ struct rds_iovec __user *local_vec;
+ unsigned int tot_pages = 0;
unsigned int nr_pages;
- unsigned int max_pages;
+ unsigned int i;
+
+ local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr;
+
+ /* figure out the number of pages in the vector */
+ for (i = 0; i < args->nr_local; i++) {
+ if (copy_from_user(&vec, &local_vec[i],
+ sizeof(struct rds_iovec)))
+ return -EFAULT;
+
+ nr_pages = rds_pages_in_vec(&vec);
+ if (nr_pages == 0)
+ return -EINVAL;
+
+ tot_pages += nr_pages;
+ }
+
+ return tot_pages;
+}
+
+int rds_rdma_extra_size(struct rds_rdma_args *args)
+{
+ return rds_rdma_pages(args) * sizeof(struct scatterlist);
+}
+
+/*
+ * The application asks for a RDMA transfer.
+ * Extract all arguments and set up the rdma_op
+ */
+int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
+ struct cmsghdr *cmsg)
+{
+ struct rds_rdma_args *args;
+ struct rds_iovec vec;
+ struct rm_rdma_op *op = &rm->rdma;
+ int nr_pages;
unsigned int nr_bytes;
struct page **pages = NULL;
struct rds_iovec __user *local_vec;
- struct scatterlist *sg;
unsigned int nr;
unsigned int i, j;
- int ret;
+ int ret = 0;
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args))
+ || rm->rdma.op_active)
+ return -EINVAL;
+
+ args = CMSG_DATA(cmsg);
if (rs->rs_bound_addr == 0) {
ret = -ENOTCONN; /* XXX not a great errno */
@@ -479,61 +546,38 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs,
goto out;
}
- nr_pages = 0;
- max_pages = 0;
-
- local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr;
-
- /* figure out the number of pages in the vector */
- for (i = 0; i < args->nr_local; i++) {
- if (copy_from_user(&vec, &local_vec[i],
- sizeof(struct rds_iovec))) {
- ret = -EFAULT;
- goto out;
- }
-
- nr = rds_pages_in_vec(&vec);
- if (nr == 0) {
- ret = -EINVAL;
- goto out;
- }
-
- max_pages = max(nr, max_pages);
- nr_pages += nr;
- }
-
- pages = kcalloc(max_pages, sizeof(struct page *), GFP_KERNEL);
- if (pages == NULL) {
- ret = -ENOMEM;
+ nr_pages = rds_rdma_pages(args);
+ if (nr_pages < 0)
goto out;
- }
- op = kzalloc(offsetof(struct rds_rdma_op, r_sg[nr_pages]), GFP_KERNEL);
- if (op == NULL) {
+ pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL);
+ if (!pages) {
ret = -ENOMEM;
goto out;
}
- op->r_write = !!(args->flags & RDS_RDMA_READWRITE);
- op->r_fence = !!(args->flags & RDS_RDMA_FENCE);
- op->r_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME);
- op->r_recverr = rs->rs_recverr;
+ op->op_write = !!(args->flags & RDS_RDMA_READWRITE);
+ op->op_fence = !!(args->flags & RDS_RDMA_FENCE);
+ op->op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME);
+ op->op_silent = !!(args->flags & RDS_RDMA_SILENT);
+ op->op_active = 1;
+ op->op_recverr = rs->rs_recverr;
WARN_ON(!nr_pages);
- sg_init_table(op->r_sg, nr_pages);
+ op->op_sg = rds_message_alloc_sgs(rm, nr_pages);
- if (op->r_notify || op->r_recverr) {
+ if (op->op_notify || op->op_recverr) {
/* We allocate an uninitialized notifier here, because
* we don't want to do that in the completion handler. We
* would have to use GFP_ATOMIC there, and don't want to deal
* with failed allocations.
*/
- op->r_notifier = kmalloc(sizeof(struct rds_notifier), GFP_KERNEL);
- if (!op->r_notifier) {
+ op->op_notifier = kmalloc(sizeof(struct rds_notifier), GFP_KERNEL);
+ if (!op->op_notifier) {
ret = -ENOMEM;
goto out;
}
- op->r_notifier->n_user_token = args->user_token;
- op->r_notifier->n_status = RDS_RDMA_SUCCESS;
+ op->op_notifier->n_user_token = args->user_token;
+ op->op_notifier->n_status = RDS_RDMA_SUCCESS;
}
/* The cookie contains the R_Key of the remote memory region, and
@@ -543,15 +587,17 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs,
* destination address (which is really an offset into the MR)
* FIXME: We may want to move this into ib_rdma.c
*/
- op->r_key = rds_rdma_cookie_key(args->cookie);
- op->r_remote_addr = args->remote_vec.addr + rds_rdma_cookie_offset(args->cookie);
+ op->op_rkey = rds_rdma_cookie_key(args->cookie);
+ op->op_remote_addr = args->remote_vec.addr + rds_rdma_cookie_offset(args->cookie);
nr_bytes = 0;
rdsdebug("RDS: rdma prepare nr_local %llu rva %llx rkey %x\n",
(unsigned long long)args->nr_local,
(unsigned long long)args->remote_vec.addr,
- op->r_key);
+ op->op_rkey);
+
+ local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr;
for (i = 0; i < args->nr_local; i++) {
if (copy_from_user(&vec, &local_vec[i],
@@ -569,15 +615,10 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs,
rs->rs_user_addr = vec.addr;
rs->rs_user_bytes = vec.bytes;
- /* did the user change the vec under us? */
- if (nr > max_pages || op->r_nents + nr > nr_pages) {
- ret = -EINVAL;
- goto out;
- }
/* If it's a WRITE operation, we want to pin the pages for reading.
* If it's a READ operation, we need to pin the pages for writing.
*/
- ret = rds_pin_pages(vec.addr & PAGE_MASK, nr, pages, !op->r_write);
+ ret = rds_pin_pages(vec.addr, nr, pages, !op->op_write);
if (ret < 0)
goto out;
@@ -588,8 +629,9 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs,
for (j = 0; j < nr; j++) {
unsigned int offset = vec.addr & ~PAGE_MASK;
+ struct scatterlist *sg;
- sg = &op->r_sg[op->r_nents + j];
+ sg = &op->op_sg[op->op_nents + j];
sg_set_page(sg, pages[j],
min_t(unsigned int, vec.bytes, PAGE_SIZE - offset),
offset);
@@ -601,10 +643,9 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs,
vec.bytes -= sg->length;
}
- op->r_nents += nr;
+ op->op_nents += nr;
}
-
if (nr_bytes > args->remote_vec.bytes) {
rdsdebug("RDS nr_bytes %u remote_bytes %u do not match\n",
nr_bytes,
@@ -612,38 +653,17 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs,
ret = -EINVAL;
goto out;
}
- op->r_bytes = nr_bytes;
+ op->op_bytes = nr_bytes;
ret = 0;
out:
kfree(pages);
- if (ret) {
- if (op)
- rds_rdma_free_op(op);
- op = ERR_PTR(ret);
- }
- return op;
-}
-
-/*
- * The application asks for a RDMA transfer.
- * Extract all arguments and set up the rdma_op
- */
-int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
- struct cmsghdr *cmsg)
-{
- struct rds_rdma_op *op;
-
- if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) ||
- rm->m_rdma_op != NULL)
- return -EINVAL;
+ if (ret)
+ rds_rdma_free_op(op);
- op = rds_rdma_prepare(rs, CMSG_DATA(cmsg));
- if (IS_ERR(op))
- return PTR_ERR(op);
rds_stats_inc(s_send_rdma);
- rm->m_rdma_op = op;
- return 0;
+
+ return ret;
}
/*
@@ -673,7 +693,7 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm,
spin_lock_irqsave(&rs->rs_rdma_lock, flags);
mr = rds_mr_tree_walk(&rs->rs_rdma_keys, r_key, NULL);
- if (mr == NULL)
+ if (!mr)
err = -EINVAL; /* invalid r_key */
else
atomic_inc(&mr->r_refcount);
@@ -681,7 +701,7 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm,
if (mr) {
mr->r_trans->sync_mr(mr->r_trans_private, DMA_TO_DEVICE);
- rm->m_rdma_mr = mr;
+ rm->rdma.op_rdma_mr = mr;
}
return err;
}
@@ -699,5 +719,98 @@ int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm,
rm->m_rdma_cookie != 0)
return -EINVAL;
- return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->m_rdma_mr);
+ return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->rdma.op_rdma_mr);
+}
+
+/*
+ * Fill in rds_message for an atomic request.
+ */
+int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm,
+ struct cmsghdr *cmsg)
+{
+ struct page *page = NULL;
+ struct rds_atomic_args *args;
+ int ret = 0;
+
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_atomic_args))
+ || rm->atomic.op_active)
+ return -EINVAL;
+
+ args = CMSG_DATA(cmsg);
+
+ /* Nonmasked & masked cmsg ops converted to masked hw ops */
+ switch (cmsg->cmsg_type) {
+ case RDS_CMSG_ATOMIC_FADD:
+ rm->atomic.op_type = RDS_ATOMIC_TYPE_FADD;
+ rm->atomic.op_m_fadd.add = args->fadd.add;
+ rm->atomic.op_m_fadd.nocarry_mask = 0;
+ break;
+ case RDS_CMSG_MASKED_ATOMIC_FADD:
+ rm->atomic.op_type = RDS_ATOMIC_TYPE_FADD;
+ rm->atomic.op_m_fadd.add = args->m_fadd.add;
+ rm->atomic.op_m_fadd.nocarry_mask = args->m_fadd.nocarry_mask;
+ break;
+ case RDS_CMSG_ATOMIC_CSWP:
+ rm->atomic.op_type = RDS_ATOMIC_TYPE_CSWP;
+ rm->atomic.op_m_cswp.compare = args->cswp.compare;
+ rm->atomic.op_m_cswp.swap = args->cswp.swap;
+ rm->atomic.op_m_cswp.compare_mask = ~0;
+ rm->atomic.op_m_cswp.swap_mask = ~0;
+ break;
+ case RDS_CMSG_MASKED_ATOMIC_CSWP:
+ rm->atomic.op_type = RDS_ATOMIC_TYPE_CSWP;
+ rm->atomic.op_m_cswp.compare = args->m_cswp.compare;
+ rm->atomic.op_m_cswp.swap = args->m_cswp.swap;
+ rm->atomic.op_m_cswp.compare_mask = args->m_cswp.compare_mask;
+ rm->atomic.op_m_cswp.swap_mask = args->m_cswp.swap_mask;
+ break;
+ default:
+ BUG(); /* should never happen */
+ }
+
+ rm->atomic.op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME);
+ rm->atomic.op_silent = !!(args->flags & RDS_RDMA_SILENT);
+ rm->atomic.op_active = 1;
+ rm->atomic.op_recverr = rs->rs_recverr;
+ rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1);
+
+ /* verify 8 byte-aligned */
+ if (args->local_addr & 0x7) {
+ ret = -EFAULT;
+ goto err;
+ }
+
+ ret = rds_pin_pages(args->local_addr, 1, &page, 1);
+ if (ret != 1)
+ goto err;
+ ret = 0;
+
+ sg_set_page(rm->atomic.op_sg, page, 8, offset_in_page(args->local_addr));
+
+ if (rm->atomic.op_notify || rm->atomic.op_recverr) {
+ /* We allocate an uninitialized notifier here, because
+ * we don't want to do that in the completion handler. We
+ * would have to use GFP_ATOMIC there, and don't want to deal
+ * with failed allocations.
+ */
+ rm->atomic.op_notifier = kmalloc(sizeof(*rm->atomic.op_notifier), GFP_KERNEL);
+ if (!rm->atomic.op_notifier) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ rm->atomic.op_notifier->n_user_token = args->user_token;
+ rm->atomic.op_notifier->n_status = RDS_RDMA_SUCCESS;
+ }
+
+ rm->atomic.op_rkey = rds_rdma_cookie_key(args->cookie);
+ rm->atomic.op_remote_addr = args->remote_addr + rds_rdma_cookie_offset(args->cookie);
+
+ return ret;
+err:
+ if (page)
+ put_page(page);
+ kfree(rm->atomic.op_notifier);
+
+ return ret;
}
diff --git a/net/rds/rdma.h b/net/rds/rdma.h
deleted file mode 100644
index 909c39835a5d..000000000000
--- a/net/rds/rdma.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef _RDS_RDMA_H
-#define _RDS_RDMA_H
-
-#include <linux/rbtree.h>
-#include <linux/spinlock.h>
-#include <linux/scatterlist.h>
-
-#include "rds.h"
-
-struct rds_mr {
- struct rb_node r_rb_node;
- atomic_t r_refcount;
- u32 r_key;
-
- /* A copy of the creation flags */
- unsigned int r_use_once:1;
- unsigned int r_invalidate:1;
- unsigned int r_write:1;
-
- /* This is for RDS_MR_DEAD.
- * It would be nice & consistent to make this part of the above
- * bit field here, but we need to use test_and_set_bit.
- */
- unsigned long r_state;
- struct rds_sock *r_sock; /* back pointer to the socket that owns us */
- struct rds_transport *r_trans;
- void *r_trans_private;
-};
-
-/* Flags for mr->r_state */
-#define RDS_MR_DEAD 0
-
-struct rds_rdma_op {
- u32 r_key;
- u64 r_remote_addr;
- unsigned int r_write:1;
- unsigned int r_fence:1;
- unsigned int r_notify:1;
- unsigned int r_recverr:1;
- unsigned int r_mapped:1;
- struct rds_notifier *r_notifier;
- unsigned int r_bytes;
- unsigned int r_nents;
- unsigned int r_count;
- struct scatterlist r_sg[0];
-};
-
-static inline rds_rdma_cookie_t rds_rdma_make_cookie(u32 r_key, u32 offset)
-{
- return r_key | (((u64) offset) << 32);
-}
-
-static inline u32 rds_rdma_cookie_key(rds_rdma_cookie_t cookie)
-{
- return cookie;
-}
-
-static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie)
-{
- return cookie >> 32;
-}
-
-int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen);
-int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen);
-int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen);
-void rds_rdma_drop_keys(struct rds_sock *rs);
-int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
- struct cmsghdr *cmsg);
-int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm,
- struct cmsghdr *cmsg);
-int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
- struct cmsghdr *cmsg);
-int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm,
- struct cmsghdr *cmsg);
-void rds_rdma_free_op(struct rds_rdma_op *ro);
-void rds_rdma_send_complete(struct rds_message *rm, int);
-
-extern void __rds_put_mr_final(struct rds_mr *mr);
-static inline void rds_mr_put(struct rds_mr *mr)
-{
- if (atomic_dec_and_test(&mr->r_refcount))
- __rds_put_mr_final(mr);
-}
-
-#endif
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
index e599ba2f950d..4195a0539829 100644
--- a/net/rds/rdma_transport.c
+++ b/net/rds/rdma_transport.c
@@ -36,6 +36,34 @@
static struct rdma_cm_id *rds_rdma_listen_id;
+static char *rds_cm_event_strings[] = {
+#define RDS_CM_EVENT_STRING(foo) \
+ [RDMA_CM_EVENT_##foo] = __stringify(RDMA_CM_EVENT_##foo)
+ RDS_CM_EVENT_STRING(ADDR_RESOLVED),
+ RDS_CM_EVENT_STRING(ADDR_ERROR),
+ RDS_CM_EVENT_STRING(ROUTE_RESOLVED),
+ RDS_CM_EVENT_STRING(ROUTE_ERROR),
+ RDS_CM_EVENT_STRING(CONNECT_REQUEST),
+ RDS_CM_EVENT_STRING(CONNECT_RESPONSE),
+ RDS_CM_EVENT_STRING(CONNECT_ERROR),
+ RDS_CM_EVENT_STRING(UNREACHABLE),
+ RDS_CM_EVENT_STRING(REJECTED),
+ RDS_CM_EVENT_STRING(ESTABLISHED),
+ RDS_CM_EVENT_STRING(DISCONNECTED),
+ RDS_CM_EVENT_STRING(DEVICE_REMOVAL),
+ RDS_CM_EVENT_STRING(MULTICAST_JOIN),
+ RDS_CM_EVENT_STRING(MULTICAST_ERROR),
+ RDS_CM_EVENT_STRING(ADDR_CHANGE),
+ RDS_CM_EVENT_STRING(TIMEWAIT_EXIT),
+#undef RDS_CM_EVENT_STRING
+};
+
+static char *rds_cm_event_str(enum rdma_cm_event_type type)
+{
+ return rds_str_array(rds_cm_event_strings,
+ ARRAY_SIZE(rds_cm_event_strings), type);
+};
+
int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
struct rdma_cm_event *event)
{
@@ -44,8 +72,8 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
struct rds_transport *trans;
int ret = 0;
- rdsdebug("conn %p id %p handling event %u\n", conn, cm_id,
- event->event);
+ rdsdebug("conn %p id %p handling event %u (%s)\n", conn, cm_id,
+ event->event, rds_cm_event_str(event->event));
if (cm_id->device->node_type == RDMA_NODE_RNIC)
trans = &rds_iw_transport;
@@ -109,7 +137,8 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
default:
/* things like device disconnect? */
- printk(KERN_ERR "RDS: unknown event %u!\n", event->event);
+ printk(KERN_ERR "RDS: unknown event %u (%s)!\n",
+ event->event, rds_cm_event_str(event->event));
break;
}
@@ -117,12 +146,13 @@ out:
if (conn)
mutex_unlock(&conn->c_cm_lock);
- rdsdebug("id %p event %u handling ret %d\n", cm_id, event->event, ret);
+ rdsdebug("id %p event %u (%s) handling ret %d\n", cm_id, event->event,
+ rds_cm_event_str(event->event), ret);
return ret;
}
-static int __init rds_rdma_listen_init(void)
+static int rds_rdma_listen_init(void)
{
struct sockaddr_in sin;
struct rdma_cm_id *cm_id;
@@ -177,7 +207,7 @@ static void rds_rdma_listen_stop(void)
}
}
-int __init rds_rdma_init(void)
+static int rds_rdma_init(void)
{
int ret;
@@ -204,7 +234,7 @@ out:
}
module_init(rds_rdma_init);
-void rds_rdma_exit(void)
+static void rds_rdma_exit(void)
{
/* stop listening first to ensure no new connections are attempted */
rds_rdma_listen_stop();
diff --git a/net/rds/rdma_transport.h b/net/rds/rdma_transport.h
index 2f2c7d976c21..faba4e382695 100644
--- a/net/rds/rdma_transport.h
+++ b/net/rds/rdma_transport.h
@@ -11,10 +11,6 @@ int rds_rdma_conn_connect(struct rds_connection *conn);
int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
struct rdma_cm_event *event);
-/* from rdma_transport.c */
-int rds_rdma_init(void);
-void rds_rdma_exit(void);
-
/* from ib.c */
extern struct rds_transport rds_ib_transport;
int rds_ib_init(void);
diff --git a/net/rds/rds.h b/net/rds/rds.h
index c224b5bb3ba9..9542449c0720 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -80,6 +80,7 @@ enum {
/* Bits for c_flags */
#define RDS_LL_SEND_FULL 0
#define RDS_RECONNECT_PENDING 1
+#define RDS_IN_XMIT 2
struct rds_connection {
struct hlist_node c_hash_node;
@@ -91,12 +92,13 @@ struct rds_connection {
struct rds_cong_map *c_lcong;
struct rds_cong_map *c_fcong;
- struct mutex c_send_lock; /* protect send ring */
struct rds_message *c_xmit_rm;
unsigned long c_xmit_sg;
unsigned int c_xmit_hdr_off;
unsigned int c_xmit_data_off;
+ unsigned int c_xmit_atomic_sent;
unsigned int c_xmit_rdma_sent;
+ unsigned int c_xmit_data_sent;
spinlock_t c_lock; /* protect msg queues */
u64 c_next_tx_seq;
@@ -116,11 +118,10 @@ struct rds_connection {
struct delayed_work c_conn_w;
struct work_struct c_down_w;
struct mutex c_cm_lock; /* protect conn state & cm */
+ wait_queue_head_t c_waitq;
struct list_head c_map_item;
unsigned long c_map_queued;
- unsigned long c_map_offset;
- unsigned long c_map_bytes;
unsigned int c_unacked_packets;
unsigned int c_unacked_bytes;
@@ -206,6 +207,48 @@ struct rds_incoming {
rds_rdma_cookie_t i_rdma_cookie;
};
+struct rds_mr {
+ struct rb_node r_rb_node;
+ atomic_t r_refcount;
+ u32 r_key;
+
+ /* A copy of the creation flags */
+ unsigned int r_use_once:1;
+ unsigned int r_invalidate:1;
+ unsigned int r_write:1;
+
+ /* This is for RDS_MR_DEAD.
+ * It would be nice & consistent to make this part of the above
+ * bit field here, but we need to use test_and_set_bit.
+ */
+ unsigned long r_state;
+ struct rds_sock *r_sock; /* back pointer to the socket that owns us */
+ struct rds_transport *r_trans;
+ void *r_trans_private;
+};
+
+/* Flags for mr->r_state */
+#define RDS_MR_DEAD 0
+
+static inline rds_rdma_cookie_t rds_rdma_make_cookie(u32 r_key, u32 offset)
+{
+ return r_key | (((u64) offset) << 32);
+}
+
+static inline u32 rds_rdma_cookie_key(rds_rdma_cookie_t cookie)
+{
+ return cookie;
+}
+
+static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie)
+{
+ return cookie >> 32;
+}
+
+/* atomic operation types */
+#define RDS_ATOMIC_TYPE_CSWP 0
+#define RDS_ATOMIC_TYPE_FADD 1
+
/*
* m_sock_item and m_conn_item are on lists that are serialized under
* conn->c_lock. m_sock_item has additional meaning in that once it is empty
@@ -258,13 +301,71 @@ struct rds_message {
* -> rs->rs_lock
*/
spinlock_t m_rs_lock;
+ wait_queue_head_t m_flush_wait;
+
struct rds_sock *m_rs;
- struct rds_rdma_op *m_rdma_op;
+
+ /* cookie to send to remote, in rds header */
rds_rdma_cookie_t m_rdma_cookie;
- struct rds_mr *m_rdma_mr;
- unsigned int m_nents;
- unsigned int m_count;
- struct scatterlist m_sg[0];
+
+ unsigned int m_used_sgs;
+ unsigned int m_total_sgs;
+
+ void *m_final_op;
+
+ struct {
+ struct rm_atomic_op {
+ int op_type;
+ union {
+ struct {
+ uint64_t compare;
+ uint64_t swap;
+ uint64_t compare_mask;
+ uint64_t swap_mask;
+ } op_m_cswp;
+ struct {
+ uint64_t add;
+ uint64_t nocarry_mask;
+ } op_m_fadd;
+ };
+
+ u32 op_rkey;
+ u64 op_remote_addr;
+ unsigned int op_notify:1;
+ unsigned int op_recverr:1;
+ unsigned int op_mapped:1;
+ unsigned int op_silent:1;
+ unsigned int op_active:1;
+ struct scatterlist *op_sg;
+ struct rds_notifier *op_notifier;
+
+ struct rds_mr *op_rdma_mr;
+ } atomic;
+ struct rm_rdma_op {
+ u32 op_rkey;
+ u64 op_remote_addr;
+ unsigned int op_write:1;
+ unsigned int op_fence:1;
+ unsigned int op_notify:1;
+ unsigned int op_recverr:1;
+ unsigned int op_mapped:1;
+ unsigned int op_silent:1;
+ unsigned int op_active:1;
+ unsigned int op_bytes;
+ unsigned int op_nents;
+ unsigned int op_count;
+ struct scatterlist *op_sg;
+ struct rds_notifier *op_notifier;
+
+ struct rds_mr *op_rdma_mr;
+ } rdma;
+ struct rm_data_op {
+ unsigned int op_active:1;
+ unsigned int op_nents;
+ unsigned int op_count;
+ struct scatterlist *op_sg;
+ } data;
+ };
};
/*
@@ -305,10 +406,6 @@ struct rds_notifier {
* transport is responsible for other serialization, including
* rds_recv_incoming(). This is called in process context but
* should try hard not to block.
- *
- * @xmit_cong_map: This asks the transport to send the local bitmap down the
- * given connection. XXX get a better story about the bitmap
- * flag and header.
*/
#define RDS_TRANS_IB 0
@@ -332,13 +429,11 @@ struct rds_transport {
void (*xmit_complete)(struct rds_connection *conn);
int (*xmit)(struct rds_connection *conn, struct rds_message *rm,
unsigned int hdr_off, unsigned int sg, unsigned int off);
- int (*xmit_cong_map)(struct rds_connection *conn,
- struct rds_cong_map *map, unsigned long offset);
- int (*xmit_rdma)(struct rds_connection *conn, struct rds_rdma_op *op);
+ int (*xmit_rdma)(struct rds_connection *conn, struct rm_rdma_op *op);
+ int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op);
int (*recv)(struct rds_connection *conn);
int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov,
size_t size);
- void (*inc_purge)(struct rds_incoming *inc);
void (*inc_free)(struct rds_incoming *inc);
int (*cm_handle_connect)(struct rdma_cm_id *cm_id,
@@ -367,17 +462,11 @@ struct rds_sock {
* bound_addr used for both incoming and outgoing, no INADDR_ANY
* support.
*/
- struct rb_node rs_bound_node;
+ struct hlist_node rs_bound_node;
__be32 rs_bound_addr;
__be32 rs_conn_addr;
__be16 rs_bound_port;
__be16 rs_conn_port;
-
- /*
- * This is only used to communicate the transport between bind and
- * initiating connections. All other trans use is referenced through
- * the connection.
- */
struct rds_transport *rs_transport;
/*
@@ -466,8 +555,8 @@ struct rds_statistics {
uint64_t s_recv_ping;
uint64_t s_send_queue_empty;
uint64_t s_send_queue_full;
- uint64_t s_send_sem_contention;
- uint64_t s_send_sem_queue_raced;
+ uint64_t s_send_lock_contention;
+ uint64_t s_send_lock_queue_raced;
uint64_t s_send_immediate_retry;
uint64_t s_send_delayed_retry;
uint64_t s_send_drop_acked;
@@ -487,6 +576,7 @@ struct rds_statistics {
};
/* af_rds.c */
+char *rds_str_array(char **array, size_t elements, size_t index);
void rds_sock_addref(struct rds_sock *rs);
void rds_sock_put(struct rds_sock *rs);
void rds_wake_sk_sleep(struct rds_sock *rs);
@@ -521,15 +611,16 @@ void rds_cong_exit(void);
struct rds_message *rds_cong_update_alloc(struct rds_connection *conn);
/* conn.c */
-int __init rds_conn_init(void);
+int rds_conn_init(void);
void rds_conn_exit(void);
struct rds_connection *rds_conn_create(__be32 laddr, __be32 faddr,
struct rds_transport *trans, gfp_t gfp);
struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
struct rds_transport *trans, gfp_t gfp);
+void rds_conn_shutdown(struct rds_connection *conn);
void rds_conn_destroy(struct rds_connection *conn);
-void rds_conn_reset(struct rds_connection *conn);
void rds_conn_drop(struct rds_connection *conn);
+void rds_conn_connect_if_down(struct rds_connection *conn);
void rds_for_each_conn_info(struct socket *sock, unsigned int len,
struct rds_info_iterator *iter,
struct rds_info_lengths *lens,
@@ -566,7 +657,8 @@ rds_conn_connecting(struct rds_connection *conn)
/* message.c */
struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp);
-struct rds_message *rds_message_copy_from_user(struct iovec *first_iov,
+struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents);
+int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov,
size_t total_len);
struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len);
void rds_message_populate_header(struct rds_header *hdr, __be16 sport,
@@ -575,12 +667,9 @@ int rds_message_add_extension(struct rds_header *hdr,
unsigned int type, const void *data, unsigned int len);
int rds_message_next_extension(struct rds_header *hdr,
unsigned int *pos, void *buf, unsigned int *buflen);
-int rds_message_add_version_extension(struct rds_header *hdr, unsigned int version);
-int rds_message_get_version_extension(struct rds_header *hdr, unsigned int *version);
int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset);
int rds_message_inc_copy_to_user(struct rds_incoming *inc,
struct iovec *first_iov, size_t size);
-void rds_message_inc_purge(struct rds_incoming *inc);
void rds_message_inc_free(struct rds_incoming *inc);
void rds_message_addref(struct rds_message *rm);
void rds_message_put(struct rds_message *rm);
@@ -614,7 +703,6 @@ void rds_page_exit(void);
/* recv.c */
void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
__be32 saddr);
-void rds_inc_addref(struct rds_incoming *inc);
void rds_inc_put(struct rds_incoming *inc);
void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr,
struct rds_incoming *inc, gfp_t gfp, enum km_type km);
@@ -636,14 +724,38 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest);
typedef int (*is_acked_func)(struct rds_message *rm, uint64_t ack);
void rds_send_drop_acked(struct rds_connection *conn, u64 ack,
is_acked_func is_acked);
-int rds_send_acked_before(struct rds_connection *conn, u64 seq);
-void rds_send_remove_from_sock(struct list_head *messages, int status);
int rds_send_pong(struct rds_connection *conn, __be16 dport);
struct rds_message *rds_send_get_message(struct rds_connection *,
- struct rds_rdma_op *);
+ struct rm_rdma_op *);
/* rdma.c */
void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force);
+int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen);
+int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen);
+int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen);
+void rds_rdma_drop_keys(struct rds_sock *rs);
+int rds_rdma_extra_size(struct rds_rdma_args *args);
+int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
+ struct cmsghdr *cmsg);
+int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm,
+ struct cmsghdr *cmsg);
+int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
+ struct cmsghdr *cmsg);
+int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm,
+ struct cmsghdr *cmsg);
+void rds_rdma_free_op(struct rm_rdma_op *ro);
+void rds_atomic_free_op(struct rm_atomic_op *ao);
+void rds_rdma_send_complete(struct rds_message *rm, int wc_status);
+void rds_atomic_send_complete(struct rds_message *rm, int wc_status);
+int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm,
+ struct cmsghdr *cmsg);
+
+extern void __rds_put_mr_final(struct rds_mr *mr);
+static inline void rds_mr_put(struct rds_mr *mr)
+{
+ if (atomic_dec_and_test(&mr->r_refcount))
+ __rds_put_mr_final(mr);
+}
/* stats.c */
DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_statistics, rds_stats);
@@ -657,14 +769,14 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_statistics, rds_stats);
put_cpu(); \
} while (0)
#define rds_stats_add(member, count) rds_stats_add_which(rds_stats, member, count)
-int __init rds_stats_init(void);
+int rds_stats_init(void);
void rds_stats_exit(void);
void rds_stats_info_copy(struct rds_info_iterator *iter,
uint64_t *values, const char *const *names,
size_t nr);
/* sysctl.c */
-int __init rds_sysctl_init(void);
+int rds_sysctl_init(void);
void rds_sysctl_exit(void);
extern unsigned long rds_sysctl_sndbuf_min;
extern unsigned long rds_sysctl_sndbuf_default;
@@ -678,9 +790,10 @@ extern unsigned long rds_sysctl_trace_flags;
extern unsigned int rds_sysctl_trace_level;
/* threads.c */
-int __init rds_threads_init(void);
+int rds_threads_init(void);
void rds_threads_exit(void);
extern struct workqueue_struct *rds_wq;
+void rds_queue_reconnect(struct rds_connection *conn);
void rds_connect_worker(struct work_struct *);
void rds_shutdown_worker(struct work_struct *);
void rds_send_worker(struct work_struct *);
@@ -691,9 +804,10 @@ void rds_connect_complete(struct rds_connection *conn);
int rds_trans_register(struct rds_transport *trans);
void rds_trans_unregister(struct rds_transport *trans);
struct rds_transport *rds_trans_get_preferred(__be32 addr);
+void rds_trans_put(struct rds_transport *trans);
unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter,
unsigned int avail);
-int __init rds_trans_init(void);
+int rds_trans_init(void);
void rds_trans_exit(void);
#endif
diff --git a/net/rds/recv.c b/net/rds/recv.c
index c93588c2d553..596689e59272 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -36,7 +36,6 @@
#include <linux/in.h>
#include "rds.h"
-#include "rdma.h"
void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
__be32 saddr)
@@ -49,12 +48,11 @@ void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
}
EXPORT_SYMBOL_GPL(rds_inc_init);
-void rds_inc_addref(struct rds_incoming *inc)
+static void rds_inc_addref(struct rds_incoming *inc)
{
rdsdebug("addref inc %p ref %d\n", inc, atomic_read(&inc->i_refcount));
atomic_inc(&inc->i_refcount);
}
-EXPORT_SYMBOL_GPL(rds_inc_addref);
void rds_inc_put(struct rds_incoming *inc)
{
@@ -210,7 +208,7 @@ void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr,
}
rs = rds_find_bound(daddr, inc->i_hdr.h_dport);
- if (rs == NULL) {
+ if (!rs) {
rds_stats_inc(s_recv_drop_no_sock);
goto out;
}
@@ -251,7 +249,7 @@ static int rds_next_incoming(struct rds_sock *rs, struct rds_incoming **inc)
{
unsigned long flags;
- if (*inc == NULL) {
+ if (!*inc) {
read_lock_irqsave(&rs->rs_recv_lock, flags);
if (!list_empty(&rs->rs_recv_queue)) {
*inc = list_entry(rs->rs_recv_queue.next,
@@ -334,10 +332,10 @@ int rds_notify_queue_get(struct rds_sock *rs, struct msghdr *msghdr)
if (msghdr) {
cmsg.user_token = notifier->n_user_token;
- cmsg.status = notifier->n_status;
+ cmsg.status = notifier->n_status;
err = put_cmsg(msghdr, SOL_RDS, RDS_CMSG_RDMA_STATUS,
- sizeof(cmsg), &cmsg);
+ sizeof(cmsg), &cmsg);
if (err)
break;
}
diff --git a/net/rds/send.c b/net/rds/send.c
index 9c1c6bcaa6c9..0bc9db17a87d 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -37,7 +37,6 @@
#include <linux/list.h>
#include "rds.h"
-#include "rdma.h"
/* When transmitting messages in rds_send_xmit, we need to emerge from
* time to time and briefly release the CPU. Otherwise the softlock watchdog
@@ -53,8 +52,11 @@ static int send_batch_count = 64;
module_param(send_batch_count, int, 0444);
MODULE_PARM_DESC(send_batch_count, " batch factor when working the send queue");
+static void rds_send_remove_from_sock(struct list_head *messages, int status);
+
/*
- * Reset the send state. Caller must hold c_send_lock when calling here.
+ * Reset the send state. Callers must ensure that this doesn't race with
+ * rds_send_xmit().
*/
void rds_send_reset(struct rds_connection *conn)
{
@@ -62,18 +64,22 @@ void rds_send_reset(struct rds_connection *conn)
unsigned long flags;
if (conn->c_xmit_rm) {
+ rm = conn->c_xmit_rm;
+ conn->c_xmit_rm = NULL;
/* Tell the user the RDMA op is no longer mapped by the
* transport. This isn't entirely true (it's flushed out
* independently) but as the connection is down, there's
* no ongoing RDMA to/from that memory */
- rds_message_unmapped(conn->c_xmit_rm);
- rds_message_put(conn->c_xmit_rm);
- conn->c_xmit_rm = NULL;
+ rds_message_unmapped(rm);
+ rds_message_put(rm);
}
+
conn->c_xmit_sg = 0;
conn->c_xmit_hdr_off = 0;
conn->c_xmit_data_off = 0;
+ conn->c_xmit_atomic_sent = 0;
conn->c_xmit_rdma_sent = 0;
+ conn->c_xmit_data_sent = 0;
conn->c_map_queued = 0;
@@ -90,6 +96,25 @@ void rds_send_reset(struct rds_connection *conn)
spin_unlock_irqrestore(&conn->c_lock, flags);
}
+static int acquire_in_xmit(struct rds_connection *conn)
+{
+ return test_and_set_bit(RDS_IN_XMIT, &conn->c_flags) == 0;
+}
+
+static void release_in_xmit(struct rds_connection *conn)
+{
+ clear_bit(RDS_IN_XMIT, &conn->c_flags);
+ smp_mb__after_clear_bit();
+ /*
+ * We don't use wait_on_bit()/wake_up_bit() because our waking is in a
+ * hot path and finding waiters is very rare. We don't want to walk
+ * the system-wide hashed waitqueue buckets in the fast path only to
+ * almost never find waiters.
+ */
+ if (waitqueue_active(&conn->c_waitq))
+ wake_up_all(&conn->c_waitq);
+}
+
/*
* We're making the concious trade-off here to only send one message
* down the connection at a time.
@@ -109,102 +134,69 @@ int rds_send_xmit(struct rds_connection *conn)
struct rds_message *rm;
unsigned long flags;
unsigned int tmp;
- unsigned int send_quota = send_batch_count;
struct scatterlist *sg;
int ret = 0;
- int was_empty = 0;
LIST_HEAD(to_be_dropped);
+restart:
+
/*
* sendmsg calls here after having queued its message on the send
* queue. We only have one task feeding the connection at a time. If
* another thread is already feeding the queue then we back off. This
* avoids blocking the caller and trading per-connection data between
* caches per message.
- *
- * The sem holder will issue a retry if they notice that someone queued
- * a message after they stopped walking the send queue but before they
- * dropped the sem.
*/
- if (!mutex_trylock(&conn->c_send_lock)) {
- rds_stats_inc(s_send_sem_contention);
+ if (!acquire_in_xmit(conn)) {
+ rds_stats_inc(s_send_lock_contention);
ret = -ENOMEM;
goto out;
}
+ /*
+ * rds_conn_shutdown() sets the conn state and then tests RDS_IN_XMIT,
+ * we do the opposite to avoid races.
+ */
+ if (!rds_conn_up(conn)) {
+ release_in_xmit(conn);
+ ret = 0;
+ goto out;
+ }
+
if (conn->c_trans->xmit_prepare)
conn->c_trans->xmit_prepare(conn);
/*
* spin trying to push headers and data down the connection until
- * the connection doens't make forward progress.
+ * the connection doesn't make forward progress.
*/
- while (--send_quota) {
- /*
- * See if need to send a congestion map update if we're
- * between sending messages. The send_sem protects our sole
- * use of c_map_offset and _bytes.
- * Note this is used only by transports that define a special
- * xmit_cong_map function. For all others, we create allocate
- * a cong_map message and treat it just like any other send.
- */
- if (conn->c_map_bytes) {
- ret = conn->c_trans->xmit_cong_map(conn, conn->c_lcong,
- conn->c_map_offset);
- if (ret <= 0)
- break;
+ while (1) {
- conn->c_map_offset += ret;
- conn->c_map_bytes -= ret;
- if (conn->c_map_bytes)
- continue;
- }
-
- /* If we're done sending the current message, clear the
- * offset and S/G temporaries.
- */
rm = conn->c_xmit_rm;
- if (rm != NULL &&
- conn->c_xmit_hdr_off == sizeof(struct rds_header) &&
- conn->c_xmit_sg == rm->m_nents) {
- conn->c_xmit_rm = NULL;
- conn->c_xmit_sg = 0;
- conn->c_xmit_hdr_off = 0;
- conn->c_xmit_data_off = 0;
- conn->c_xmit_rdma_sent = 0;
-
- /* Release the reference to the previous message. */
- rds_message_put(rm);
- rm = NULL;
- }
- /* If we're asked to send a cong map update, do so.
+ /*
+ * If between sending messages, we can send a pending congestion
+ * map update.
*/
- if (rm == NULL && test_and_clear_bit(0, &conn->c_map_queued)) {
- if (conn->c_trans->xmit_cong_map != NULL) {
- conn->c_map_offset = 0;
- conn->c_map_bytes = sizeof(struct rds_header) +
- RDS_CONG_MAP_BYTES;
- continue;
- }
-
+ if (!rm && test_and_clear_bit(0, &conn->c_map_queued)) {
rm = rds_cong_update_alloc(conn);
if (IS_ERR(rm)) {
ret = PTR_ERR(rm);
break;
}
+ rm->data.op_active = 1;
conn->c_xmit_rm = rm;
}
/*
- * Grab the next message from the send queue, if there is one.
+ * If not already working on one, grab the next message.
*
* c_xmit_rm holds a ref while we're sending this message down
* the connction. We can use this ref while holding the
* send_sem.. rds_send_reset() is serialized with it.
*/
- if (rm == NULL) {
+ if (!rm) {
unsigned int len;
spin_lock_irqsave(&conn->c_lock, flags);
@@ -224,10 +216,8 @@ int rds_send_xmit(struct rds_connection *conn)
spin_unlock_irqrestore(&conn->c_lock, flags);
- if (rm == NULL) {
- was_empty = 1;
+ if (!rm)
break;
- }
/* Unfortunately, the way Infiniband deals with
* RDMA to a bad MR key is by moving the entire
@@ -236,13 +226,12 @@ int rds_send_xmit(struct rds_connection *conn)
* connection.
* Therefore, we never retransmit messages with RDMA ops.
*/
- if (rm->m_rdma_op &&
+ if (rm->rdma.op_active &&
test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags)) {
spin_lock_irqsave(&conn->c_lock, flags);
if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags))
list_move(&rm->m_conn_item, &to_be_dropped);
spin_unlock_irqrestore(&conn->c_lock, flags);
- rds_message_put(rm);
continue;
}
@@ -263,23 +252,55 @@ int rds_send_xmit(struct rds_connection *conn)
conn->c_xmit_rm = rm;
}
- /*
- * Try and send an rdma message. Let's see if we can
- * keep this simple and require that the transport either
- * send the whole rdma or none of it.
- */
- if (rm->m_rdma_op && !conn->c_xmit_rdma_sent) {
- ret = conn->c_trans->xmit_rdma(conn, rm->m_rdma_op);
+ /* The transport either sends the whole rdma or none of it */
+ if (rm->rdma.op_active && !conn->c_xmit_rdma_sent) {
+ rm->m_final_op = &rm->rdma;
+ ret = conn->c_trans->xmit_rdma(conn, &rm->rdma);
if (ret)
break;
conn->c_xmit_rdma_sent = 1;
+
/* The transport owns the mapped memory for now.
* You can't unmap it while it's on the send queue */
set_bit(RDS_MSG_MAPPED, &rm->m_flags);
}
- if (conn->c_xmit_hdr_off < sizeof(struct rds_header) ||
- conn->c_xmit_sg < rm->m_nents) {
+ if (rm->atomic.op_active && !conn->c_xmit_atomic_sent) {
+ rm->m_final_op = &rm->atomic;
+ ret = conn->c_trans->xmit_atomic(conn, &rm->atomic);
+ if (ret)
+ break;
+ conn->c_xmit_atomic_sent = 1;
+
+ /* The transport owns the mapped memory for now.
+ * You can't unmap it while it's on the send queue */
+ set_bit(RDS_MSG_MAPPED, &rm->m_flags);
+ }
+
+ /*
+ * A number of cases require an RDS header to be sent
+ * even if there is no data.
+ * We permit 0-byte sends; rds-ping depends on this.
+ * However, if there are exclusively attached silent ops,
+ * we skip the hdr/data send, to enable silent operation.
+ */
+ if (rm->data.op_nents == 0) {
+ int ops_present;
+ int all_ops_are_silent = 1;
+
+ ops_present = (rm->atomic.op_active || rm->rdma.op_active);
+ if (rm->atomic.op_active && !rm->atomic.op_silent)
+ all_ops_are_silent = 0;
+ if (rm->rdma.op_active && !rm->rdma.op_silent)
+ all_ops_are_silent = 0;
+
+ if (ops_present && all_ops_are_silent
+ && !rm->m_rdma_cookie)
+ rm->data.op_active = 0;
+ }
+
+ if (rm->data.op_active && !conn->c_xmit_data_sent) {
+ rm->m_final_op = &rm->data;
ret = conn->c_trans->xmit(conn, rm,
conn->c_xmit_hdr_off,
conn->c_xmit_sg,
@@ -295,7 +316,7 @@ int rds_send_xmit(struct rds_connection *conn)
ret -= tmp;
}
- sg = &rm->m_sg[conn->c_xmit_sg];
+ sg = &rm->data.op_sg[conn->c_xmit_sg];
while (ret) {
tmp = min_t(int, ret, sg->length -
conn->c_xmit_data_off);
@@ -306,49 +327,63 @@ int rds_send_xmit(struct rds_connection *conn)
sg++;
conn->c_xmit_sg++;
BUG_ON(ret != 0 &&
- conn->c_xmit_sg == rm->m_nents);
+ conn->c_xmit_sg == rm->data.op_nents);
}
}
+
+ if (conn->c_xmit_hdr_off == sizeof(struct rds_header) &&
+ (conn->c_xmit_sg == rm->data.op_nents))
+ conn->c_xmit_data_sent = 1;
}
- }
- /* Nuke any messages we decided not to retransmit. */
- if (!list_empty(&to_be_dropped))
- rds_send_remove_from_sock(&to_be_dropped, RDS_RDMA_DROPPED);
+ /*
+ * A rm will only take multiple times through this loop
+ * if there is a data op. Thus, if the data is sent (or there was
+ * none), then we're done with the rm.
+ */
+ if (!rm->data.op_active || conn->c_xmit_data_sent) {
+ conn->c_xmit_rm = NULL;
+ conn->c_xmit_sg = 0;
+ conn->c_xmit_hdr_off = 0;
+ conn->c_xmit_data_off = 0;
+ conn->c_xmit_rdma_sent = 0;
+ conn->c_xmit_atomic_sent = 0;
+ conn->c_xmit_data_sent = 0;
+
+ rds_message_put(rm);
+ }
+ }
if (conn->c_trans->xmit_complete)
conn->c_trans->xmit_complete(conn);
- /*
- * We might be racing with another sender who queued a message but
- * backed off on noticing that we held the c_send_lock. If we check
- * for queued messages after dropping the sem then either we'll
- * see the queued message or the queuer will get the sem. If we
- * notice the queued message then we trigger an immediate retry.
- *
- * We need to be careful only to do this when we stopped processing
- * the send queue because it was empty. It's the only way we
- * stop processing the loop when the transport hasn't taken
- * responsibility for forward progress.
- */
- mutex_unlock(&conn->c_send_lock);
+ release_in_xmit(conn);
- if (conn->c_map_bytes || (send_quota == 0 && !was_empty)) {
- /* We exhausted the send quota, but there's work left to
- * do. Return and (re-)schedule the send worker.
- */
- ret = -EAGAIN;
+ /* Nuke any messages we decided not to retransmit. */
+ if (!list_empty(&to_be_dropped)) {
+ /* irqs on here, so we can put(), unlike above */
+ list_for_each_entry(rm, &to_be_dropped, m_conn_item)
+ rds_message_put(rm);
+ rds_send_remove_from_sock(&to_be_dropped, RDS_RDMA_DROPPED);
}
- if (ret == 0 && was_empty) {
- /* A simple bit test would be way faster than taking the
- * spin lock */
- spin_lock_irqsave(&conn->c_lock, flags);
+ /*
+ * Other senders can queue a message after we last test the send queue
+ * but before we clear RDS_IN_XMIT. In that case they'd back off and
+ * not try and send their newly queued message. We need to check the
+ * send queue after having cleared RDS_IN_XMIT so that their message
+ * doesn't get stuck on the send queue.
+ *
+ * If the transport cannot continue (i.e ret != 0), then it must
+ * call us when more room is available, such as from the tx
+ * completion handler.
+ */
+ if (ret == 0) {
+ smp_mb();
if (!list_empty(&conn->c_send_queue)) {
- rds_stats_inc(s_send_sem_queue_raced);
- ret = -EAGAIN;
+ rds_stats_inc(s_send_lock_queue_raced);
+ goto restart;
}
- spin_unlock_irqrestore(&conn->c_lock, flags);
}
out:
return ret;
@@ -376,52 +411,60 @@ static inline int rds_send_is_acked(struct rds_message *rm, u64 ack,
}
/*
- * Returns true if there are no messages on the send and retransmit queues
- * which have a sequence number greater than or equal to the given sequence
- * number.
+ * This is pretty similar to what happens below in the ACK
+ * handling code - except that we call here as soon as we get
+ * the IB send completion on the RDMA op and the accompanying
+ * message.
*/
-int rds_send_acked_before(struct rds_connection *conn, u64 seq)
+void rds_rdma_send_complete(struct rds_message *rm, int status)
{
- struct rds_message *rm, *tmp;
- int ret = 1;
+ struct rds_sock *rs = NULL;
+ struct rm_rdma_op *ro;
+ struct rds_notifier *notifier;
+ unsigned long flags;
- spin_lock(&conn->c_lock);
+ spin_lock_irqsave(&rm->m_rs_lock, flags);
- list_for_each_entry_safe(rm, tmp, &conn->c_retrans, m_conn_item) {
- if (be64_to_cpu(rm->m_inc.i_hdr.h_sequence) < seq)
- ret = 0;
- break;
- }
+ ro = &rm->rdma;
+ if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) &&
+ ro->op_active && ro->op_notify && ro->op_notifier) {
+ notifier = ro->op_notifier;
+ rs = rm->m_rs;
+ sock_hold(rds_rs_to_sk(rs));
- list_for_each_entry_safe(rm, tmp, &conn->c_send_queue, m_conn_item) {
- if (be64_to_cpu(rm->m_inc.i_hdr.h_sequence) < seq)
- ret = 0;
- break;
+ notifier->n_status = status;
+ spin_lock(&rs->rs_lock);
+ list_add_tail(&notifier->n_list, &rs->rs_notify_queue);
+ spin_unlock(&rs->rs_lock);
+
+ ro->op_notifier = NULL;
}
- spin_unlock(&conn->c_lock);
+ spin_unlock_irqrestore(&rm->m_rs_lock, flags);
- return ret;
+ if (rs) {
+ rds_wake_sk_sleep(rs);
+ sock_put(rds_rs_to_sk(rs));
+ }
}
+EXPORT_SYMBOL_GPL(rds_rdma_send_complete);
/*
- * This is pretty similar to what happens below in the ACK
- * handling code - except that we call here as soon as we get
- * the IB send completion on the RDMA op and the accompanying
- * message.
+ * Just like above, except looks at atomic op
*/
-void rds_rdma_send_complete(struct rds_message *rm, int status)
+void rds_atomic_send_complete(struct rds_message *rm, int status)
{
struct rds_sock *rs = NULL;
- struct rds_rdma_op *ro;
+ struct rm_atomic_op *ao;
struct rds_notifier *notifier;
+ unsigned long flags;
- spin_lock(&rm->m_rs_lock);
+ spin_lock_irqsave(&rm->m_rs_lock, flags);
- ro = rm->m_rdma_op;
- if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) &&
- ro && ro->r_notify && ro->r_notifier) {
- notifier = ro->r_notifier;
+ ao = &rm->atomic;
+ if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags)
+ && ao->op_active && ao->op_notify && ao->op_notifier) {
+ notifier = ao->op_notifier;
rs = rm->m_rs;
sock_hold(rds_rs_to_sk(rs));
@@ -430,17 +473,17 @@ void rds_rdma_send_complete(struct rds_message *rm, int status)
list_add_tail(&notifier->n_list, &rs->rs_notify_queue);
spin_unlock(&rs->rs_lock);
- ro->r_notifier = NULL;
+ ao->op_notifier = NULL;
}
- spin_unlock(&rm->m_rs_lock);
+ spin_unlock_irqrestore(&rm->m_rs_lock, flags);
if (rs) {
rds_wake_sk_sleep(rs);
sock_put(rds_rs_to_sk(rs));
}
}
-EXPORT_SYMBOL_GPL(rds_rdma_send_complete);
+EXPORT_SYMBOL_GPL(rds_atomic_send_complete);
/*
* This is the same as rds_rdma_send_complete except we
@@ -448,15 +491,23 @@ EXPORT_SYMBOL_GPL(rds_rdma_send_complete);
* socket, socket lock) and can just move the notifier.
*/
static inline void
-__rds_rdma_send_complete(struct rds_sock *rs, struct rds_message *rm, int status)
+__rds_send_complete(struct rds_sock *rs, struct rds_message *rm, int status)
{
- struct rds_rdma_op *ro;
+ struct rm_rdma_op *ro;
+ struct rm_atomic_op *ao;
+
+ ro = &rm->rdma;
+ if (ro->op_active && ro->op_notify && ro->op_notifier) {
+ ro->op_notifier->n_status = status;
+ list_add_tail(&ro->op_notifier->n_list, &rs->rs_notify_queue);
+ ro->op_notifier = NULL;
+ }
- ro = rm->m_rdma_op;
- if (ro && ro->r_notify && ro->r_notifier) {
- ro->r_notifier->n_status = status;
- list_add_tail(&ro->r_notifier->n_list, &rs->rs_notify_queue);
- ro->r_notifier = NULL;
+ ao = &rm->atomic;
+ if (ao->op_active && ao->op_notify && ao->op_notifier) {
+ ao->op_notifier->n_status = status;
+ list_add_tail(&ao->op_notifier->n_list, &rs->rs_notify_queue);
+ ao->op_notifier = NULL;
}
/* No need to wake the app - caller does this */
@@ -468,7 +519,7 @@ __rds_rdma_send_complete(struct rds_sock *rs, struct rds_message *rm, int status
* So speed is not an issue here.
*/
struct rds_message *rds_send_get_message(struct rds_connection *conn,
- struct rds_rdma_op *op)
+ struct rm_rdma_op *op)
{
struct rds_message *rm, *tmp, *found = NULL;
unsigned long flags;
@@ -476,7 +527,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *conn,
spin_lock_irqsave(&conn->c_lock, flags);
list_for_each_entry_safe(rm, tmp, &conn->c_retrans, m_conn_item) {
- if (rm->m_rdma_op == op) {
+ if (&rm->rdma == op) {
atomic_inc(&rm->m_refcount);
found = rm;
goto out;
@@ -484,7 +535,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *conn,
}
list_for_each_entry_safe(rm, tmp, &conn->c_send_queue, m_conn_item) {
- if (rm->m_rdma_op == op) {
+ if (&rm->rdma == op) {
atomic_inc(&rm->m_refcount);
found = rm;
break;
@@ -506,7 +557,7 @@ EXPORT_SYMBOL_GPL(rds_send_get_message);
* removing the messages from the 'messages' list regardless of if it found
* the messages on the socket list or not.
*/
-void rds_send_remove_from_sock(struct list_head *messages, int status)
+static void rds_send_remove_from_sock(struct list_head *messages, int status)
{
unsigned long flags;
struct rds_sock *rs = NULL;
@@ -544,19 +595,20 @@ void rds_send_remove_from_sock(struct list_head *messages, int status)
spin_lock(&rs->rs_lock);
if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) {
- struct rds_rdma_op *ro = rm->m_rdma_op;
+ struct rm_rdma_op *ro = &rm->rdma;
struct rds_notifier *notifier;
list_del_init(&rm->m_sock_item);
rds_send_sndbuf_remove(rs, rm);
- if (ro && ro->r_notifier && (status || ro->r_notify)) {
- notifier = ro->r_notifier;
+ if (ro->op_active && ro->op_notifier &&
+ (ro->op_notify || (ro->op_recverr && status))) {
+ notifier = ro->op_notifier;
list_add_tail(&notifier->n_list,
&rs->rs_notify_queue);
if (!notifier->n_status)
notifier->n_status = status;
- rm->m_rdma_op->r_notifier = NULL;
+ rm->rdma.op_notifier = NULL;
}
was_on_sock = 1;
rm->m_rs = NULL;
@@ -619,9 +671,8 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
{
struct rds_message *rm, *tmp;
struct rds_connection *conn;
- unsigned long flags, flags2;
+ unsigned long flags;
LIST_HEAD(list);
- int wake = 0;
/* get all the messages we're dropping under the rs lock */
spin_lock_irqsave(&rs->rs_lock, flags);
@@ -631,59 +682,54 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
dest->sin_port != rm->m_inc.i_hdr.h_dport))
continue;
- wake = 1;
list_move(&rm->m_sock_item, &list);
rds_send_sndbuf_remove(rs, rm);
clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags);
}
/* order flag updates with the rs lock */
- if (wake)
- smp_mb__after_clear_bit();
+ smp_mb__after_clear_bit();
spin_unlock_irqrestore(&rs->rs_lock, flags);
- conn = NULL;
+ if (list_empty(&list))
+ return;
- /* now remove the messages from the conn list as needed */
+ /* Remove the messages from the conn */
list_for_each_entry(rm, &list, m_sock_item) {
- /* We do this here rather than in the loop above, so that
- * we don't have to nest m_rs_lock under rs->rs_lock */
- spin_lock_irqsave(&rm->m_rs_lock, flags2);
- /* If this is a RDMA operation, notify the app. */
- spin_lock(&rs->rs_lock);
- __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED);
- spin_unlock(&rs->rs_lock);
- rm->m_rs = NULL;
- spin_unlock_irqrestore(&rm->m_rs_lock, flags2);
+ conn = rm->m_inc.i_conn;
+
+ spin_lock_irqsave(&conn->c_lock, flags);
/*
- * If we see this flag cleared then we're *sure* that someone
- * else beat us to removing it from the conn. If we race
- * with their flag update we'll get the lock and then really
- * see that the flag has been cleared.
+ * Maybe someone else beat us to removing rm from the conn.
+ * If we race with their flag update we'll get the lock and
+ * then really see that the flag has been cleared.
*/
- if (!test_bit(RDS_MSG_ON_CONN, &rm->m_flags))
+ if (!test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) {
+ spin_unlock_irqrestore(&conn->c_lock, flags);
continue;
-
- if (conn != rm->m_inc.i_conn) {
- if (conn)
- spin_unlock_irqrestore(&conn->c_lock, flags);
- conn = rm->m_inc.i_conn;
- spin_lock_irqsave(&conn->c_lock, flags);
}
+ list_del_init(&rm->m_conn_item);
+ spin_unlock_irqrestore(&conn->c_lock, flags);
- if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) {
- list_del_init(&rm->m_conn_item);
- rds_message_put(rm);
- }
- }
+ /*
+ * Couldn't grab m_rs_lock in top loop (lock ordering),
+ * but we can now.
+ */
+ spin_lock_irqsave(&rm->m_rs_lock, flags);
- if (conn)
- spin_unlock_irqrestore(&conn->c_lock, flags);
+ spin_lock(&rs->rs_lock);
+ __rds_send_complete(rs, rm, RDS_RDMA_CANCELED);
+ spin_unlock(&rs->rs_lock);
- if (wake)
- rds_wake_sk_sleep(rs);
+ rm->m_rs = NULL;
+ spin_unlock_irqrestore(&rm->m_rs_lock, flags);
+
+ rds_message_put(rm);
+ }
+
+ rds_wake_sk_sleep(rs);
while (!list_empty(&list)) {
rm = list_entry(list.next, struct rds_message, m_sock_item);
@@ -763,6 +809,63 @@ out:
return *queued;
}
+/*
+ * rds_message is getting to be quite complicated, and we'd like to allocate
+ * it all in one go. This figures out how big it needs to be up front.
+ */
+static int rds_rm_size(struct msghdr *msg, int data_len)
+{
+ struct cmsghdr *cmsg;
+ int size = 0;
+ int cmsg_groups = 0;
+ int retval;
+
+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ if (!CMSG_OK(msg, cmsg))
+ return -EINVAL;
+
+ if (cmsg->cmsg_level != SOL_RDS)
+ continue;
+
+ switch (cmsg->cmsg_type) {
+ case RDS_CMSG_RDMA_ARGS:
+ cmsg_groups |= 1;
+ retval = rds_rdma_extra_size(CMSG_DATA(cmsg));
+ if (retval < 0)
+ return retval;
+ size += retval;
+
+ break;
+
+ case RDS_CMSG_RDMA_DEST:
+ case RDS_CMSG_RDMA_MAP:
+ cmsg_groups |= 2;
+ /* these are valid but do no add any size */
+ break;
+
+ case RDS_CMSG_ATOMIC_CSWP:
+ case RDS_CMSG_ATOMIC_FADD:
+ case RDS_CMSG_MASKED_ATOMIC_CSWP:
+ case RDS_CMSG_MASKED_ATOMIC_FADD:
+ cmsg_groups |= 1;
+ size += sizeof(struct scatterlist);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ }
+
+ size += ceil(data_len, PAGE_SIZE) * sizeof(struct scatterlist);
+
+ /* Ensure (DEST, MAP) are never used with (ARGS, ATOMIC) */
+ if (cmsg_groups == 3)
+ return -EINVAL;
+
+ return size;
+}
+
static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm,
struct msghdr *msg, int *allocated_mr)
{
@@ -777,7 +880,7 @@ static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm,
continue;
/* As a side effect, RDMA_DEST and RDMA_MAP will set
- * rm->m_rdma_cookie and rm->m_rdma_mr.
+ * rm->rdma.m_rdma_cookie and rm->rdma.m_rdma_mr.
*/
switch (cmsg->cmsg_type) {
case RDS_CMSG_RDMA_ARGS:
@@ -793,6 +896,12 @@ static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm,
if (!ret)
*allocated_mr = 1;
break;
+ case RDS_CMSG_ATOMIC_CSWP:
+ case RDS_CMSG_ATOMIC_FADD:
+ case RDS_CMSG_MASKED_ATOMIC_CSWP:
+ case RDS_CMSG_MASKED_ATOMIC_FADD:
+ ret = rds_cmsg_atomic(rs, rm, cmsg);
+ break;
default:
return -EINVAL;
@@ -850,13 +959,26 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
goto out;
}
- rm = rds_message_copy_from_user(msg->msg_iov, payload_len);
- if (IS_ERR(rm)) {
- ret = PTR_ERR(rm);
- rm = NULL;
+ /* size of rm including all sgs */
+ ret = rds_rm_size(msg, payload_len);
+ if (ret < 0)
+ goto out;
+
+ rm = rds_message_alloc(ret, GFP_KERNEL);
+ if (!rm) {
+ ret = -ENOMEM;
goto out;
}
+ /* Attach data to the rm */
+ if (payload_len) {
+ rm->data.op_sg = rds_message_alloc_sgs(rm, ceil(payload_len, PAGE_SIZE));
+ ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len);
+ if (ret)
+ goto out;
+ }
+ rm->data.op_active = 1;
+
rm->m_daddr = daddr;
/* rds_conn_create has a spinlock that runs with IRQ off.
@@ -879,22 +1001,23 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
if (ret)
goto out;
- if ((rm->m_rdma_cookie || rm->m_rdma_op) &&
- conn->c_trans->xmit_rdma == NULL) {
+ if (rm->rdma.op_active && !conn->c_trans->xmit_rdma) {
if (printk_ratelimit())
printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n",
- rm->m_rdma_op, conn->c_trans->xmit_rdma);
+ &rm->rdma, conn->c_trans->xmit_rdma);
ret = -EOPNOTSUPP;
goto out;
}
- /* If the connection is down, trigger a connect. We may
- * have scheduled a delayed reconnect however - in this case
- * we should not interfere.
- */
- if (rds_conn_state(conn) == RDS_CONN_DOWN &&
- !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags))
- queue_delayed_work(rds_wq, &conn->c_conn_w, 0);
+ if (rm->atomic.op_active && !conn->c_trans->xmit_atomic) {
+ if (printk_ratelimit())
+ printk(KERN_NOTICE "atomic_op %p conn xmit_atomic %p\n",
+ &rm->atomic, conn->c_trans->xmit_atomic);
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ rds_conn_connect_if_down(conn);
ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs);
if (ret) {
@@ -938,7 +1061,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
rds_stats_inc(s_send_queued);
if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags))
- rds_send_worker(&conn->c_send_w.work);
+ rds_send_xmit(conn);
rds_message_put(rm);
return payload_len;
@@ -966,20 +1089,15 @@ rds_send_pong(struct rds_connection *conn, __be16 dport)
int ret = 0;
rm = rds_message_alloc(0, GFP_ATOMIC);
- if (rm == NULL) {
+ if (!rm) {
ret = -ENOMEM;
goto out;
}
rm->m_daddr = conn->c_faddr;
+ rm->data.op_active = 1;
- /* If the connection is down, trigger a connect. We may
- * have scheduled a delayed reconnect however - in this case
- * we should not interfere.
- */
- if (rds_conn_state(conn) == RDS_CONN_DOWN &&
- !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags))
- queue_delayed_work(rds_wq, &conn->c_conn_w, 0);
+ rds_conn_connect_if_down(conn);
ret = rds_cong_wait(conn->c_fcong, dport, 1, NULL);
if (ret)
@@ -999,7 +1117,9 @@ rds_send_pong(struct rds_connection *conn, __be16 dport)
rds_stats_inc(s_send_queued);
rds_stats_inc(s_send_pong);
- queue_delayed_work(rds_wq, &conn->c_send_w, 0);
+ if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags))
+ rds_send_xmit(conn);
+
rds_message_put(rm);
return 0;
diff --git a/net/rds/stats.c b/net/rds/stats.c
index 7598eb07cfb1..10c759ccac0c 100644
--- a/net/rds/stats.c
+++ b/net/rds/stats.c
@@ -57,8 +57,8 @@ static const char *const rds_stat_names[] = {
"recv_ping",
"send_queue_empty",
"send_queue_full",
- "send_sem_contention",
- "send_sem_queue_raced",
+ "send_lock_contention",
+ "send_lock_queue_raced",
"send_immediate_retry",
"send_delayed_retry",
"send_drop_acked",
@@ -143,7 +143,7 @@ void rds_stats_exit(void)
rds_info_deregister_func(RDS_INFO_COUNTERS, rds_stats_info);
}
-int __init rds_stats_init(void)
+int rds_stats_init(void)
{
rds_info_register_func(RDS_INFO_COUNTERS, rds_stats_info);
return 0;
diff --git a/net/rds/sysctl.c b/net/rds/sysctl.c
index 7829a20325d3..25ad0c77a26c 100644
--- a/net/rds/sysctl.c
+++ b/net/rds/sysctl.c
@@ -105,13 +105,13 @@ void rds_sysctl_exit(void)
unregister_sysctl_table(rds_sysctl_reg_table);
}
-int __init rds_sysctl_init(void)
+int rds_sysctl_init(void)
{
rds_sysctl_reconnect_min = msecs_to_jiffies(1);
rds_sysctl_reconnect_min_jiffies = rds_sysctl_reconnect_min;
rds_sysctl_reg_table = register_sysctl_paths(rds_sysctl_path, rds_sysctl_rds_table);
- if (rds_sysctl_reg_table == NULL)
+ if (!rds_sysctl_reg_table)
return -ENOMEM;
return 0;
}
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index babf4577ff7d..08a8c6cf2d10 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -41,7 +41,7 @@
/* only for info exporting */
static DEFINE_SPINLOCK(rds_tcp_tc_list_lock);
static LIST_HEAD(rds_tcp_tc_list);
-unsigned int rds_tcp_tc_count;
+static unsigned int rds_tcp_tc_count;
/* Track rds_tcp_connection structs so they can be cleaned up */
static DEFINE_SPINLOCK(rds_tcp_conn_lock);
@@ -200,7 +200,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp)
struct rds_tcp_connection *tc;
tc = kmem_cache_alloc(rds_tcp_conn_slab, gfp);
- if (tc == NULL)
+ if (!tc)
return -ENOMEM;
tc->t_sock = NULL;
@@ -243,7 +243,7 @@ static void rds_tcp_destroy_conns(void)
}
}
-void rds_tcp_exit(void)
+static void rds_tcp_exit(void)
{
rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
rds_tcp_listen_stop();
@@ -258,7 +258,6 @@ struct rds_transport rds_tcp_transport = {
.laddr_check = rds_tcp_laddr_check,
.xmit_prepare = rds_tcp_xmit_prepare,
.xmit_complete = rds_tcp_xmit_complete,
- .xmit_cong_map = rds_tcp_xmit_cong_map,
.xmit = rds_tcp_xmit,
.recv = rds_tcp_recv,
.conn_alloc = rds_tcp_conn_alloc,
@@ -266,7 +265,6 @@ struct rds_transport rds_tcp_transport = {
.conn_connect = rds_tcp_conn_connect,
.conn_shutdown = rds_tcp_conn_shutdown,
.inc_copy_to_user = rds_tcp_inc_copy_to_user,
- .inc_purge = rds_tcp_inc_purge,
.inc_free = rds_tcp_inc_free,
.stats_info_copy = rds_tcp_stats_info_copy,
.exit = rds_tcp_exit,
@@ -276,14 +274,14 @@ struct rds_transport rds_tcp_transport = {
.t_prefer_loopback = 1,
};
-int __init rds_tcp_init(void)
+static int rds_tcp_init(void)
{
int ret;
rds_tcp_conn_slab = kmem_cache_create("rds_tcp_connection",
sizeof(struct rds_tcp_connection),
0, 0, NULL);
- if (rds_tcp_conn_slab == NULL) {
+ if (!rds_tcp_conn_slab) {
ret = -ENOMEM;
goto out;
}
diff --git a/net/rds/tcp.h b/net/rds/tcp.h
index 844fa6b9cf5a..9cf2927d0021 100644
--- a/net/rds/tcp.h
+++ b/net/rds/tcp.h
@@ -43,8 +43,6 @@ struct rds_tcp_statistics {
};
/* tcp.c */
-int __init rds_tcp_init(void);
-void rds_tcp_exit(void);
void rds_tcp_tune(struct socket *sock);
void rds_tcp_nonagle(struct socket *sock);
void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn);
@@ -61,16 +59,15 @@ void rds_tcp_conn_shutdown(struct rds_connection *conn);
void rds_tcp_state_change(struct sock *sk);
/* tcp_listen.c */
-int __init rds_tcp_listen_init(void);
+int rds_tcp_listen_init(void);
void rds_tcp_listen_stop(void);
void rds_tcp_listen_data_ready(struct sock *sk, int bytes);
/* tcp_recv.c */
-int __init rds_tcp_recv_init(void);
+int rds_tcp_recv_init(void);
void rds_tcp_recv_exit(void);
void rds_tcp_data_ready(struct sock *sk, int bytes);
int rds_tcp_recv(struct rds_connection *conn);
-void rds_tcp_inc_purge(struct rds_incoming *inc);
void rds_tcp_inc_free(struct rds_incoming *inc);
int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
size_t size);
@@ -81,8 +78,6 @@ void rds_tcp_xmit_complete(struct rds_connection *conn);
int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm,
unsigned int hdr_off, unsigned int sg, unsigned int off);
void rds_tcp_write_space(struct sock *sk);
-int rds_tcp_xmit_cong_map(struct rds_connection *conn,
- struct rds_cong_map *map, unsigned long offset);
/* tcp_stats.c */
DECLARE_PER_CPU(struct rds_tcp_statistics, rds_tcp_stats);
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
index c519939e8da9..af95c8e058fc 100644
--- a/net/rds/tcp_connect.c
+++ b/net/rds/tcp_connect.c
@@ -45,7 +45,7 @@ void rds_tcp_state_change(struct sock *sk)
read_lock_bh(&sk->sk_callback_lock);
conn = sk->sk_user_data;
- if (conn == NULL) {
+ if (!conn) {
state_change = sk->sk_state_change;
goto out;
}
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 27844f231d10..8b5cc4aa8868 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -116,7 +116,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes)
read_lock_bh(&sk->sk_callback_lock);
ready = sk->sk_user_data;
- if (ready == NULL) { /* check for teardown race */
+ if (!ready) { /* check for teardown race */
ready = sk->sk_data_ready;
goto out;
}
@@ -135,7 +135,7 @@ out:
ready(sk, bytes);
}
-int __init rds_tcp_listen_init(void)
+int rds_tcp_listen_init(void)
{
struct sockaddr_in sin;
struct socket *sock = NULL;
@@ -178,7 +178,7 @@ void rds_tcp_listen_stop(void)
struct socket *sock = rds_tcp_listen_sock;
struct sock *sk;
- if (sock == NULL)
+ if (!sock)
return;
sk = sock->sk;
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
index e43797404102..78205e25500a 100644
--- a/net/rds/tcp_recv.c
+++ b/net/rds/tcp_recv.c
@@ -39,7 +39,7 @@
static struct kmem_cache *rds_tcp_incoming_slab;
-void rds_tcp_inc_purge(struct rds_incoming *inc)
+static void rds_tcp_inc_purge(struct rds_incoming *inc)
{
struct rds_tcp_incoming *tinc;
tinc = container_of(inc, struct rds_tcp_incoming, ti_inc);
@@ -190,10 +190,10 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb,
* processing.
*/
while (left) {
- if (tinc == NULL) {
+ if (!tinc) {
tinc = kmem_cache_alloc(rds_tcp_incoming_slab,
arg->gfp);
- if (tinc == NULL) {
+ if (!tinc) {
desc->error = -ENOMEM;
goto out;
}
@@ -229,7 +229,7 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb,
if (left && tc->t_tinc_data_rem) {
clone = skb_clone(skb, arg->gfp);
- if (clone == NULL) {
+ if (!clone) {
desc->error = -ENOMEM;
goto out;
}
@@ -272,7 +272,8 @@ out:
}
/* the caller has to hold the sock lock */
-int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp, enum km_type km)
+static int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp,
+ enum km_type km)
{
struct rds_tcp_connection *tc = conn->c_transport_data;
struct socket *sock = tc->t_sock;
@@ -326,7 +327,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes)
read_lock_bh(&sk->sk_callback_lock);
conn = sk->sk_user_data;
- if (conn == NULL) { /* check for teardown race */
+ if (!conn) { /* check for teardown race */
ready = sk->sk_data_ready;
goto out;
}
@@ -342,12 +343,12 @@ out:
ready(sk, bytes);
}
-int __init rds_tcp_recv_init(void)
+int rds_tcp_recv_init(void)
{
rds_tcp_incoming_slab = kmem_cache_create("rds_tcp_incoming",
sizeof(struct rds_tcp_incoming),
0, 0, NULL);
- if (rds_tcp_incoming_slab == NULL)
+ if (!rds_tcp_incoming_slab)
return -ENOMEM;
return 0;
}
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c
index 2f012a07d94d..1b4fd68f0c7c 100644
--- a/net/rds/tcp_send.c
+++ b/net/rds/tcp_send.c
@@ -63,7 +63,7 @@ void rds_tcp_xmit_complete(struct rds_connection *conn)
}
/* the core send_sem serializes this with other xmit and shutdown */
-int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len)
+static int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len)
{
struct kvec vec = {
.iov_base = data,
@@ -77,56 +77,6 @@ int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len)
}
/* the core send_sem serializes this with other xmit and shutdown */
-int rds_tcp_xmit_cong_map(struct rds_connection *conn,
- struct rds_cong_map *map, unsigned long offset)
-{
- static struct rds_header rds_tcp_map_header = {
- .h_flags = RDS_FLAG_CONG_BITMAP,
- };
- struct rds_tcp_connection *tc = conn->c_transport_data;
- unsigned long i;
- int ret;
- int copied = 0;
-
- /* Some problem claims cpu_to_be32(constant) isn't a constant. */
- rds_tcp_map_header.h_len = cpu_to_be32(RDS_CONG_MAP_BYTES);
-
- if (offset < sizeof(struct rds_header)) {
- ret = rds_tcp_sendmsg(tc->t_sock,
- (void *)&rds_tcp_map_header + offset,
- sizeof(struct rds_header) - offset);
- if (ret <= 0)
- return ret;
- offset += ret;
- copied = ret;
- if (offset < sizeof(struct rds_header))
- return ret;
- }
-
- offset -= sizeof(struct rds_header);
- i = offset / PAGE_SIZE;
- offset = offset % PAGE_SIZE;
- BUG_ON(i >= RDS_CONG_MAP_PAGES);
-
- do {
- ret = tc->t_sock->ops->sendpage(tc->t_sock,
- virt_to_page(map->m_page_addrs[i]),
- offset, PAGE_SIZE - offset,
- MSG_DONTWAIT);
- if (ret <= 0)
- break;
- copied += ret;
- offset += ret;
- if (offset == PAGE_SIZE) {
- offset = 0;
- i++;
- }
- } while (i < RDS_CONG_MAP_PAGES);
-
- return copied ? copied : ret;
-}
-
-/* the core send_sem serializes this with other xmit and shutdown */
int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm,
unsigned int hdr_off, unsigned int sg, unsigned int off)
{
@@ -166,21 +116,21 @@ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm,
goto out;
}
- while (sg < rm->m_nents) {
+ while (sg < rm->data.op_nents) {
ret = tc->t_sock->ops->sendpage(tc->t_sock,
- sg_page(&rm->m_sg[sg]),
- rm->m_sg[sg].offset + off,
- rm->m_sg[sg].length - off,
+ sg_page(&rm->data.op_sg[sg]),
+ rm->data.op_sg[sg].offset + off,
+ rm->data.op_sg[sg].length - off,
MSG_DONTWAIT|MSG_NOSIGNAL);
- rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->m_sg[sg]),
- rm->m_sg[sg].offset + off, rm->m_sg[sg].length - off,
+ rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->data.op_sg[sg]),
+ rm->data.op_sg[sg].offset + off, rm->data.op_sg[sg].length - off,
ret);
if (ret <= 0)
break;
off += ret;
done += ret;
- if (off == rm->m_sg[sg].length) {
+ if (off == rm->data.op_sg[sg].length) {
off = 0;
sg++;
}
@@ -226,7 +176,7 @@ void rds_tcp_write_space(struct sock *sk)
read_lock_bh(&sk->sk_callback_lock);
conn = sk->sk_user_data;
- if (conn == NULL) {
+ if (!conn) {
write_space = sk->sk_write_space;
goto out;
}
diff --git a/net/rds/threads.c b/net/rds/threads.c
index 786c20eaaf5e..0fd90f8c5f59 100644
--- a/net/rds/threads.c
+++ b/net/rds/threads.c
@@ -61,7 +61,7 @@
*
* Transition to state DISCONNECTING/DOWN:
* - Inside the shutdown worker; synchronizes with xmit path
- * through c_send_lock, and with connection management callbacks
+ * through RDS_IN_XMIT, and with connection management callbacks
* via c_cm_lock.
*
* For receive callbacks, we rely on the underlying transport
@@ -110,7 +110,7 @@ EXPORT_SYMBOL_GPL(rds_connect_complete);
* We should *always* start with a random backoff; otherwise a broken connection
* will always take several iterations to be re-established.
*/
-static void rds_queue_reconnect(struct rds_connection *conn)
+void rds_queue_reconnect(struct rds_connection *conn)
{
unsigned long rand;
@@ -156,58 +156,6 @@ void rds_connect_worker(struct work_struct *work)
}
}
-void rds_shutdown_worker(struct work_struct *work)
-{
- struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w);
-
- /* shut it down unless it's down already */
- if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) {
- /*
- * Quiesce the connection mgmt handlers before we start tearing
- * things down. We don't hold the mutex for the entire
- * duration of the shutdown operation, else we may be
- * deadlocking with the CM handler. Instead, the CM event
- * handler is supposed to check for state DISCONNECTING
- */
- mutex_lock(&conn->c_cm_lock);
- if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) &&
- !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) {
- rds_conn_error(conn, "shutdown called in state %d\n",
- atomic_read(&conn->c_state));
- mutex_unlock(&conn->c_cm_lock);
- return;
- }
- mutex_unlock(&conn->c_cm_lock);
-
- mutex_lock(&conn->c_send_lock);
- conn->c_trans->conn_shutdown(conn);
- rds_conn_reset(conn);
- mutex_unlock(&conn->c_send_lock);
-
- if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) {
- /* This can happen - eg when we're in the middle of tearing
- * down the connection, and someone unloads the rds module.
- * Quite reproduceable with loopback connections.
- * Mostly harmless.
- */
- rds_conn_error(conn,
- "%s: failed to transition to state DOWN, "
- "current state is %d\n",
- __func__,
- atomic_read(&conn->c_state));
- return;
- }
- }
-
- /* Then reconnect if it's still live.
- * The passive side of an IB loopback connection is never added
- * to the conn hash, so we never trigger a reconnect on this
- * conn - the reconnect is always triggered by the active peer. */
- cancel_delayed_work(&conn->c_conn_w);
- if (!hlist_unhashed(&conn->c_hash_node))
- rds_queue_reconnect(conn);
-}
-
void rds_send_worker(struct work_struct *work)
{
struct rds_connection *conn = container_of(work, struct rds_connection, c_send_w.work);
@@ -252,15 +200,22 @@ void rds_recv_worker(struct work_struct *work)
}
}
+void rds_shutdown_worker(struct work_struct *work)
+{
+ struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w);
+
+ rds_conn_shutdown(conn);
+}
+
void rds_threads_exit(void)
{
destroy_workqueue(rds_wq);
}
-int __init rds_threads_init(void)
+int rds_threads_init(void)
{
- rds_wq = create_workqueue("krdsd");
- if (rds_wq == NULL)
+ rds_wq = create_singlethread_workqueue("krdsd");
+ if (!rds_wq)
return -ENOMEM;
return 0;
diff --git a/net/rds/transport.c b/net/rds/transport.c
index 7e1067901353..7f2ac4fec367 100644
--- a/net/rds/transport.c
+++ b/net/rds/transport.c
@@ -71,19 +71,28 @@ void rds_trans_unregister(struct rds_transport *trans)
}
EXPORT_SYMBOL_GPL(rds_trans_unregister);
+void rds_trans_put(struct rds_transport *trans)
+{
+ if (trans && trans->t_owner)
+ module_put(trans->t_owner);
+}
+
struct rds_transport *rds_trans_get_preferred(__be32 addr)
{
struct rds_transport *ret = NULL;
- int i;
+ struct rds_transport *trans;
+ unsigned int i;
if (IN_LOOPBACK(ntohl(addr)))
return &rds_loop_transport;
down_read(&rds_trans_sem);
- for (i = 0; i < RDS_TRANS_COUNT; i++)
- {
- if (transports[i] && (transports[i]->laddr_check(addr) == 0)) {
- ret = transports[i];
+ for (i = 0; i < RDS_TRANS_COUNT; i++) {
+ trans = transports[i];
+
+ if (trans && (trans->laddr_check(addr) == 0) &&
+ (!trans->t_owner || try_module_get(trans->t_owner))) {
+ ret = trans;
break;
}
}
diff --git a/net/rds/xlist.h b/net/rds/xlist.h
new file mode 100644
index 000000000000..e6b5190daddd
--- /dev/null
+++ b/net/rds/xlist.h
@@ -0,0 +1,80 @@
+#ifndef _LINUX_XLIST_H
+#define _LINUX_XLIST_H
+
+#include <linux/stddef.h>
+#include <linux/poison.h>
+#include <linux/prefetch.h>
+#include <asm/system.h>
+
+struct xlist_head {
+ struct xlist_head *next;
+};
+
+static inline void INIT_XLIST_HEAD(struct xlist_head *list)
+{
+ list->next = NULL;
+}
+
+static inline int xlist_empty(struct xlist_head *head)
+{
+ return head->next == NULL;
+}
+
+static inline void xlist_add(struct xlist_head *new, struct xlist_head *tail,
+ struct xlist_head *head)
+{
+ struct xlist_head *cur;
+ struct xlist_head *check;
+
+ while (1) {
+ cur = head->next;
+ tail->next = cur;
+ check = cmpxchg(&head->next, cur, new);
+ if (check == cur)
+ break;
+ }
+}
+
+static inline struct xlist_head *xlist_del_head(struct xlist_head *head)
+{
+ struct xlist_head *cur;
+ struct xlist_head *check;
+ struct xlist_head *next;
+
+ while (1) {
+ cur = head->next;
+ if (!cur)
+ goto out;
+
+ next = cur->next;
+ check = cmpxchg(&head->next, cur, next);
+ if (check == cur)
+ goto out;
+ }
+out:
+ return cur;
+}
+
+static inline struct xlist_head *xlist_del_head_fast(struct xlist_head *head)
+{
+ struct xlist_head *cur;
+
+ cur = head->next;
+ if (!cur)
+ return NULL;
+
+ head->next = cur->next;
+ return cur;
+}
+
+static inline void xlist_splice(struct xlist_head *list,
+ struct xlist_head *head)
+{
+ struct xlist_head *cur;
+
+ WARN_ON(head->next);
+ cur = xchg(&list->next, NULL);
+ head->next = cur;
+}
+
+#endif
diff --git a/net/rfkill/input.c b/net/rfkill/input.c
index 3713d7ecab96..1bca6d49ec96 100644
--- a/net/rfkill/input.c
+++ b/net/rfkill/input.c
@@ -142,7 +142,7 @@ static unsigned long rfkill_last_scheduled;
static unsigned long rfkill_ratelimit(const unsigned long last)
{
const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY);
- return (time_after(jiffies, last + delay)) ? 0 : delay;
+ return time_after(jiffies, last + delay) ? 0 : delay;
}
static void rfkill_schedule_ratelimited(void)
diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c
index a750a28e0221..fa5f5641a2c2 100644
--- a/net/rose/rose_link.c
+++ b/net/rose/rose_link.c
@@ -114,7 +114,7 @@ static int rose_send_frame(struct sk_buff *skb, struct rose_neigh *neigh)
if (ax25s)
ax25_cb_put(ax25s);
- return (neigh->ax25 != NULL);
+ return neigh->ax25 != NULL;
}
/*
@@ -137,7 +137,7 @@ static int rose_link_up(struct rose_neigh *neigh)
if (ax25s)
ax25_cb_put(ax25s);
- return (neigh->ax25 != NULL);
+ return neigh->ax25 != NULL;
}
/*
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 2f691fb180d1..a36270a994d7 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -518,6 +518,16 @@ config NET_ACT_SKBEDIT
To compile this code as a module, choose M here: the
module will be called act_skbedit.
+config NET_ACT_CSUM
+ tristate "Checksum Updating"
+ depends on NET_CLS_ACT && INET
+ ---help---
+ Say Y here to update some common checksum after some direct
+ packet alterations.
+
+ To compile this code as a module, choose M here: the
+ module will be called act_csum.
+
config NET_CLS_IND
bool "Incoming device classification"
depends on NET_CLS_U32 || NET_CLS_FW
diff --git a/net/sched/Makefile b/net/sched/Makefile
index f14e71bfa58f..960f5dba6304 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_NET_ACT_NAT) += act_nat.o
obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit.o
obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o
obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
+obj-$(CONFIG_NET_ACT_CSUM) += act_csum.o
obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o
obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
new file mode 100644
index 000000000000..67dc7ce9b63a
--- /dev/null
+++ b/net/sched/act_csum.c
@@ -0,0 +1,595 @@
+/*
+ * Checksum updating actions
+ *
+ * Copyright (c) 2010 Gregoire Baron <baronchon@n7mm.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include <linux/netlink.h>
+#include <net/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <linux/skbuff.h>
+
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <net/icmp.h>
+#include <linux/icmpv6.h>
+#include <linux/igmp.h>
+#include <net/tcp.h>
+#include <net/udp.h>
+#include <net/ip6_checksum.h>
+
+#include <net/act_api.h>
+
+#include <linux/tc_act/tc_csum.h>
+#include <net/tc_act/tc_csum.h>
+
+#define CSUM_TAB_MASK 15
+static struct tcf_common *tcf_csum_ht[CSUM_TAB_MASK + 1];
+static u32 csum_idx_gen;
+static DEFINE_RWLOCK(csum_lock);
+
+static struct tcf_hashinfo csum_hash_info = {
+ .htab = tcf_csum_ht,
+ .hmask = CSUM_TAB_MASK,
+ .lock = &csum_lock,
+};
+
+static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = {
+ [TCA_CSUM_PARMS] = { .len = sizeof(struct tc_csum), },
+};
+
+static int tcf_csum_init(struct nlattr *nla, struct nlattr *est,
+ struct tc_action *a, int ovr, int bind)
+{
+ struct nlattr *tb[TCA_CSUM_MAX + 1];
+ struct tc_csum *parm;
+ struct tcf_common *pc;
+ struct tcf_csum *p;
+ int ret = 0, err;
+
+ if (nla == NULL)
+ return -EINVAL;
+
+ err = nla_parse_nested(tb, TCA_CSUM_MAX, nla,csum_policy);
+ if (err < 0)
+ return err;
+
+ if (tb[TCA_CSUM_PARMS] == NULL)
+ return -EINVAL;
+ parm = nla_data(tb[TCA_CSUM_PARMS]);
+
+ pc = tcf_hash_check(parm->index, a, bind, &csum_hash_info);
+ if (!pc) {
+ pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind,
+ &csum_idx_gen, &csum_hash_info);
+ if (IS_ERR(pc))
+ return PTR_ERR(pc);
+ p = to_tcf_csum(pc);
+ ret = ACT_P_CREATED;
+ } else {
+ p = to_tcf_csum(pc);
+ if (!ovr) {
+ tcf_hash_release(pc, bind, &csum_hash_info);
+ return -EEXIST;
+ }
+ }
+
+ spin_lock_bh(&p->tcf_lock);
+ p->tcf_action = parm->action;
+ p->update_flags = parm->update_flags;
+ spin_unlock_bh(&p->tcf_lock);
+
+ if (ret == ACT_P_CREATED)
+ tcf_hash_insert(pc, &csum_hash_info);
+
+ return ret;
+}
+
+static int tcf_csum_cleanup(struct tc_action *a, int bind)
+{
+ struct tcf_csum *p = a->priv;
+ return tcf_hash_release(&p->common, bind, &csum_hash_info);
+}
+
+/**
+ * tcf_csum_skb_nextlayer - Get next layer pointer
+ * @skb: sk_buff to use
+ * @ihl: previous summed headers length
+ * @ipl: complete packet length
+ * @jhl: next header length
+ *
+ * Check the expected next layer availability in the specified sk_buff.
+ * Return the next layer pointer if pass, NULL otherwise.
+ */
+static void *tcf_csum_skb_nextlayer(struct sk_buff *skb,
+ unsigned int ihl, unsigned int ipl,
+ unsigned int jhl)
+{
+ int ntkoff = skb_network_offset(skb);
+ int hl = ihl + jhl;
+
+ if (!pskb_may_pull(skb, ipl + ntkoff) || (ipl < hl) ||
+ (skb_cloned(skb) &&
+ !skb_clone_writable(skb, hl + ntkoff) &&
+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+ return NULL;
+ else
+ return (void *)(skb_network_header(skb) + ihl);
+}
+
+static int tcf_csum_ipv4_icmp(struct sk_buff *skb,
+ unsigned int ihl, unsigned int ipl)
+{
+ struct icmphdr *icmph;
+
+ icmph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*icmph));
+ if (icmph == NULL)
+ return 0;
+
+ icmph->checksum = 0;
+ skb->csum = csum_partial(icmph, ipl - ihl, 0);
+ icmph->checksum = csum_fold(skb->csum);
+
+ skb->ip_summed = CHECKSUM_NONE;
+
+ return 1;
+}
+
+static int tcf_csum_ipv4_igmp(struct sk_buff *skb,
+ unsigned int ihl, unsigned int ipl)
+{
+ struct igmphdr *igmph;
+
+ igmph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*igmph));
+ if (igmph == NULL)
+ return 0;
+
+ igmph->csum = 0;
+ skb->csum = csum_partial(igmph, ipl - ihl, 0);
+ igmph->csum = csum_fold(skb->csum);
+
+ skb->ip_summed = CHECKSUM_NONE;
+
+ return 1;
+}
+
+static int tcf_csum_ipv6_icmp(struct sk_buff *skb, struct ipv6hdr *ip6h,
+ unsigned int ihl, unsigned int ipl)
+{
+ struct icmp6hdr *icmp6h;
+
+ icmp6h = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*icmp6h));
+ if (icmp6h == NULL)
+ return 0;
+
+ icmp6h->icmp6_cksum = 0;
+ skb->csum = csum_partial(icmp6h, ipl - ihl, 0);
+ icmp6h->icmp6_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
+ ipl - ihl, IPPROTO_ICMPV6,
+ skb->csum);
+
+ skb->ip_summed = CHECKSUM_NONE;
+
+ return 1;
+}
+
+static int tcf_csum_ipv4_tcp(struct sk_buff *skb, struct iphdr *iph,
+ unsigned int ihl, unsigned int ipl)
+{
+ struct tcphdr *tcph;
+
+ tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph));
+ if (tcph == NULL)
+ return 0;
+
+ tcph->check = 0;
+ skb->csum = csum_partial(tcph, ipl - ihl, 0);
+ tcph->check = tcp_v4_check(ipl - ihl,
+ iph->saddr, iph->daddr, skb->csum);
+
+ skb->ip_summed = CHECKSUM_NONE;
+
+ return 1;
+}
+
+static int tcf_csum_ipv6_tcp(struct sk_buff *skb, struct ipv6hdr *ip6h,
+ unsigned int ihl, unsigned int ipl)
+{
+ struct tcphdr *tcph;
+
+ tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph));
+ if (tcph == NULL)
+ return 0;
+
+ tcph->check = 0;
+ skb->csum = csum_partial(tcph, ipl - ihl, 0);
+ tcph->check = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
+ ipl - ihl, IPPROTO_TCP,
+ skb->csum);
+
+ skb->ip_summed = CHECKSUM_NONE;
+
+ return 1;
+}
+
+static int tcf_csum_ipv4_udp(struct sk_buff *skb, struct iphdr *iph,
+ unsigned int ihl, unsigned int ipl, int udplite)
+{
+ struct udphdr *udph;
+ u16 ul;
+
+ /*
+ * Support both UDP and UDPLITE checksum algorithms, Don't use
+ * udph->len to get the real length without any protocol check,
+ * UDPLITE uses udph->len for another thing,
+ * Use iph->tot_len, or just ipl.
+ */
+
+ udph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*udph));
+ if (udph == NULL)
+ return 0;
+
+ ul = ntohs(udph->len);
+
+ if (udplite || udph->check) {
+
+ udph->check = 0;
+
+ if (udplite) {
+ if (ul == 0)
+ skb->csum = csum_partial(udph, ipl - ihl, 0);
+ else if ((ul >= sizeof(*udph)) && (ul <= ipl - ihl))
+ skb->csum = csum_partial(udph, ul, 0);
+ else
+ goto ignore_obscure_skb;
+ } else {
+ if (ul != ipl - ihl)
+ goto ignore_obscure_skb;
+
+ skb->csum = csum_partial(udph, ul, 0);
+ }
+
+ udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
+ ul, iph->protocol,
+ skb->csum);
+
+ if (!udph->check)
+ udph->check = CSUM_MANGLED_0;
+ }
+
+ skb->ip_summed = CHECKSUM_NONE;
+
+ignore_obscure_skb:
+ return 1;
+}
+
+static int tcf_csum_ipv6_udp(struct sk_buff *skb, struct ipv6hdr *ip6h,
+ unsigned int ihl, unsigned int ipl, int udplite)
+{
+ struct udphdr *udph;
+ u16 ul;
+
+ /*
+ * Support both UDP and UDPLITE checksum algorithms, Don't use
+ * udph->len to get the real length without any protocol check,
+ * UDPLITE uses udph->len for another thing,
+ * Use ip6h->payload_len + sizeof(*ip6h) ... , or just ipl.
+ */
+
+ udph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*udph));
+ if (udph == NULL)
+ return 0;
+
+ ul = ntohs(udph->len);
+
+ udph->check = 0;
+
+ if (udplite) {
+ if (ul == 0)
+ skb->csum = csum_partial(udph, ipl - ihl, 0);
+
+ else if ((ul >= sizeof(*udph)) && (ul <= ipl - ihl))
+ skb->csum = csum_partial(udph, ul, 0);
+
+ else
+ goto ignore_obscure_skb;
+ } else {
+ if (ul != ipl - ihl)
+ goto ignore_obscure_skb;
+
+ skb->csum = csum_partial(udph, ul, 0);
+ }
+
+ udph->check = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, ul,
+ udplite ? IPPROTO_UDPLITE : IPPROTO_UDP,
+ skb->csum);
+
+ if (!udph->check)
+ udph->check = CSUM_MANGLED_0;
+
+ skb->ip_summed = CHECKSUM_NONE;
+
+ignore_obscure_skb:
+ return 1;
+}
+
+static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags)
+{
+ struct iphdr *iph;
+ int ntkoff;
+
+ ntkoff = skb_network_offset(skb);
+
+ if (!pskb_may_pull(skb, sizeof(*iph) + ntkoff))
+ goto fail;
+
+ iph = ip_hdr(skb);
+
+ switch (iph->frag_off & htons(IP_OFFSET) ? 0 : iph->protocol) {
+ case IPPROTO_ICMP:
+ if (update_flags & TCA_CSUM_UPDATE_FLAG_ICMP)
+ if (!tcf_csum_ipv4_icmp(skb, iph->ihl * 4,
+ ntohs(iph->tot_len)))
+ goto fail;
+ break;
+ case IPPROTO_IGMP:
+ if (update_flags & TCA_CSUM_UPDATE_FLAG_IGMP)
+ if (!tcf_csum_ipv4_igmp(skb, iph->ihl * 4,
+ ntohs(iph->tot_len)))
+ goto fail;
+ break;
+ case IPPROTO_TCP:
+ if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP)
+ if (!tcf_csum_ipv4_tcp(skb, iph, iph->ihl * 4,
+ ntohs(iph->tot_len)))
+ goto fail;
+ break;
+ case IPPROTO_UDP:
+ if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP)
+ if (!tcf_csum_ipv4_udp(skb, iph, iph->ihl * 4,
+ ntohs(iph->tot_len), 0))
+ goto fail;
+ break;
+ case IPPROTO_UDPLITE:
+ if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE)
+ if (!tcf_csum_ipv4_udp(skb, iph, iph->ihl * 4,
+ ntohs(iph->tot_len), 1))
+ goto fail;
+ break;
+ }
+
+ if (update_flags & TCA_CSUM_UPDATE_FLAG_IPV4HDR) {
+ if (skb_cloned(skb) &&
+ !skb_clone_writable(skb, sizeof(*iph) + ntkoff) &&
+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+ goto fail;
+
+ ip_send_check(iph);
+ }
+
+ return 1;
+
+fail:
+ return 0;
+}
+
+static int tcf_csum_ipv6_hopopts(struct ipv6_opt_hdr *ip6xh,
+ unsigned int ixhl, unsigned int *pl)
+{
+ int off, len, optlen;
+ unsigned char *xh = (void *)ip6xh;
+
+ off = sizeof(*ip6xh);
+ len = ixhl - off;
+
+ while (len > 1) {
+ switch (xh[off]) {
+ case IPV6_TLV_PAD0:
+ optlen = 1;
+ break;
+ case IPV6_TLV_JUMBO:
+ optlen = xh[off + 1] + 2;
+ if (optlen != 6 || len < 6 || (off & 3) != 2)
+ /* wrong jumbo option length/alignment */
+ return 0;
+ *pl = ntohl(*(__be32 *)(xh + off + 2));
+ goto done;
+ default:
+ optlen = xh[off + 1] + 2;
+ if (optlen > len)
+ /* ignore obscure options */
+ goto done;
+ break;
+ }
+ off += optlen;
+ len -= optlen;
+ }
+
+done:
+ return 1;
+}
+
+static int tcf_csum_ipv6(struct sk_buff *skb, u32 update_flags)
+{
+ struct ipv6hdr *ip6h;
+ struct ipv6_opt_hdr *ip6xh;
+ unsigned int hl, ixhl;
+ unsigned int pl;
+ int ntkoff;
+ u8 nexthdr;
+
+ ntkoff = skb_network_offset(skb);
+
+ hl = sizeof(*ip6h);
+
+ if (!pskb_may_pull(skb, hl + ntkoff))
+ goto fail;
+
+ ip6h = ipv6_hdr(skb);
+
+ pl = ntohs(ip6h->payload_len);
+ nexthdr = ip6h->nexthdr;
+
+ do {
+ switch (nexthdr) {
+ case NEXTHDR_FRAGMENT:
+ goto ignore_skb;
+ case NEXTHDR_ROUTING:
+ case NEXTHDR_HOP:
+ case NEXTHDR_DEST:
+ if (!pskb_may_pull(skb, hl + sizeof(*ip6xh) + ntkoff))
+ goto fail;
+ ip6xh = (void *)(skb_network_header(skb) + hl);
+ ixhl = ipv6_optlen(ip6xh);
+ if (!pskb_may_pull(skb, hl + ixhl + ntkoff))
+ goto fail;
+ if ((nexthdr == NEXTHDR_HOP) &&
+ !(tcf_csum_ipv6_hopopts(ip6xh, ixhl, &pl)))
+ goto fail;
+ nexthdr = ip6xh->nexthdr;
+ hl += ixhl;
+ break;
+ case IPPROTO_ICMPV6:
+ if (update_flags & TCA_CSUM_UPDATE_FLAG_ICMP)
+ if (!tcf_csum_ipv6_icmp(skb, ip6h,
+ hl, pl + sizeof(*ip6h)))
+ goto fail;
+ goto done;
+ case IPPROTO_TCP:
+ if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP)
+ if (!tcf_csum_ipv6_tcp(skb, ip6h,
+ hl, pl + sizeof(*ip6h)))
+ goto fail;
+ goto done;
+ case IPPROTO_UDP:
+ if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP)
+ if (!tcf_csum_ipv6_udp(skb, ip6h, hl,
+ pl + sizeof(*ip6h), 0))
+ goto fail;
+ goto done;
+ case IPPROTO_UDPLITE:
+ if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE)
+ if (!tcf_csum_ipv6_udp(skb, ip6h, hl,
+ pl + sizeof(*ip6h), 1))
+ goto fail;
+ goto done;
+ default:
+ goto ignore_skb;
+ }
+ } while (pskb_may_pull(skb, hl + 1 + ntkoff));
+
+done:
+ignore_skb:
+ return 1;
+
+fail:
+ return 0;
+}
+
+static int tcf_csum(struct sk_buff *skb,
+ struct tc_action *a, struct tcf_result *res)
+{
+ struct tcf_csum *p = a->priv;
+ int action;
+ u32 update_flags;
+
+ spin_lock(&p->tcf_lock);
+ p->tcf_tm.lastuse = jiffies;
+ p->tcf_bstats.bytes += qdisc_pkt_len(skb);
+ p->tcf_bstats.packets++;
+ action = p->tcf_action;
+ update_flags = p->update_flags;
+ spin_unlock(&p->tcf_lock);
+
+ if (unlikely(action == TC_ACT_SHOT))
+ goto drop;
+
+ switch (skb->protocol) {
+ case cpu_to_be16(ETH_P_IP):
+ if (!tcf_csum_ipv4(skb, update_flags))
+ goto drop;
+ break;
+ case cpu_to_be16(ETH_P_IPV6):
+ if (!tcf_csum_ipv6(skb, update_flags))
+ goto drop;
+ break;
+ }
+
+ return action;
+
+drop:
+ spin_lock(&p->tcf_lock);
+ p->tcf_qstats.drops++;
+ spin_unlock(&p->tcf_lock);
+ return TC_ACT_SHOT;
+}
+
+static int tcf_csum_dump(struct sk_buff *skb,
+ struct tc_action *a, int bind, int ref)
+{
+ unsigned char *b = skb_tail_pointer(skb);
+ struct tcf_csum *p = a->priv;
+ struct tc_csum opt = {
+ .update_flags = p->update_flags,
+ .index = p->tcf_index,
+ .action = p->tcf_action,
+ .refcnt = p->tcf_refcnt - ref,
+ .bindcnt = p->tcf_bindcnt - bind,
+ };
+ struct tcf_t t;
+
+ NLA_PUT(skb, TCA_CSUM_PARMS, sizeof(opt), &opt);
+ t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
+ t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
+ t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
+ NLA_PUT(skb, TCA_CSUM_TM, sizeof(t), &t);
+
+ return skb->len;
+
+nla_put_failure:
+ nlmsg_trim(skb, b);
+ return -1;
+}
+
+static struct tc_action_ops act_csum_ops = {
+ .kind = "csum",
+ .hinfo = &csum_hash_info,
+ .type = TCA_ACT_CSUM,
+ .capab = TCA_CAP_NONE,
+ .owner = THIS_MODULE,
+ .act = tcf_csum,
+ .dump = tcf_csum_dump,
+ .cleanup = tcf_csum_cleanup,
+ .lookup = tcf_hash_search,
+ .init = tcf_csum_init,
+ .walk = tcf_generic_walker
+};
+
+MODULE_DESCRIPTION("Checksum updating actions");
+MODULE_LICENSE("GPL");
+
+static int __init csum_init_module(void)
+{
+ return tcf_register_action(&act_csum_ops);
+}
+
+static void __exit csum_cleanup_module(void)
+{
+ tcf_unregister_action(&act_csum_ops);
+}
+
+module_init(csum_init_module);
+module_exit(csum_cleanup_module);
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index c7e59e6ec349..8daef9632255 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -39,7 +39,7 @@ static struct tcf_hashinfo ipt_hash_info = {
.lock = &ipt_lock,
};
-static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook)
+static int ipt_init_target(struct xt_entry_target *t, char *table, unsigned int hook)
{
struct xt_tgchk_param par;
struct xt_target *target;
@@ -66,7 +66,7 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int
return 0;
}
-static void ipt_destroy_target(struct ipt_entry_target *t)
+static void ipt_destroy_target(struct xt_entry_target *t)
{
struct xt_tgdtor_param par = {
.target = t->u.kernel.target,
@@ -99,7 +99,7 @@ static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
[TCA_IPT_TABLE] = { .type = NLA_STRING, .len = IFNAMSIZ },
[TCA_IPT_HOOK] = { .type = NLA_U32 },
[TCA_IPT_INDEX] = { .type = NLA_U32 },
- [TCA_IPT_TARG] = { .len = sizeof(struct ipt_entry_target) },
+ [TCA_IPT_TARG] = { .len = sizeof(struct xt_entry_target) },
};
static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
@@ -108,7 +108,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
struct nlattr *tb[TCA_IPT_MAX + 1];
struct tcf_ipt *ipt;
struct tcf_common *pc;
- struct ipt_entry_target *td, *t;
+ struct xt_entry_target *td, *t;
char *tname;
int ret = 0, err;
u32 hook = 0;
@@ -126,7 +126,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
if (tb[TCA_IPT_TARG] == NULL)
return -EINVAL;
- td = (struct ipt_entry_target *)nla_data(tb[TCA_IPT_TARG]);
+ td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]);
if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size)
return -EINVAL;
@@ -230,7 +230,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
result = TC_ACT_SHOT;
ipt->tcf_qstats.drops++;
break;
- case IPT_CONTINUE:
+ case XT_CONTINUE:
result = TC_ACT_PIPE;
break;
default:
@@ -249,7 +249,7 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int
{
unsigned char *b = skb_tail_pointer(skb);
struct tcf_ipt *ipt = a->priv;
- struct ipt_entry_target *t;
+ struct xt_entry_target *t;
struct tcf_t tm;
struct tc_cnt c;
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index e17096e3913c..5b271a18bc3a 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -111,44 +111,41 @@ static u32 flow_get_proto(struct sk_buff *skb)
}
}
-static int has_ports(u8 protocol)
-{
- switch (protocol) {
- case IPPROTO_TCP:
- case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
- case IPPROTO_SCTP:
- case IPPROTO_DCCP:
- case IPPROTO_ESP:
- return 1;
- default:
- return 0;
- }
-}
-
static u32 flow_get_proto_src(struct sk_buff *skb)
{
switch (skb->protocol) {
case htons(ETH_P_IP): {
struct iphdr *iph;
+ int poff;
if (!pskb_network_may_pull(skb, sizeof(*iph)))
break;
iph = ip_hdr(skb);
- if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
- has_ports(iph->protocol) &&
- pskb_network_may_pull(skb, iph->ihl * 4 + 2))
- return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4));
+ if (iph->frag_off & htons(IP_MF|IP_OFFSET))
+ break;
+ poff = proto_ports_offset(iph->protocol);
+ if (poff >= 0 &&
+ pskb_network_may_pull(skb, iph->ihl * 4 + 2 + poff)) {
+ iph = ip_hdr(skb);
+ return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 +
+ poff));
+ }
break;
}
case htons(ETH_P_IPV6): {
struct ipv6hdr *iph;
+ int poff;
- if (!pskb_network_may_pull(skb, sizeof(*iph) + 2))
+ if (!pskb_network_may_pull(skb, sizeof(*iph)))
break;
iph = ipv6_hdr(skb);
- if (has_ports(iph->nexthdr))
- return ntohs(*(__be16 *)&iph[1]);
+ poff = proto_ports_offset(iph->nexthdr);
+ if (poff >= 0 &&
+ pskb_network_may_pull(skb, sizeof(*iph) + poff + 2)) {
+ iph = ipv6_hdr(skb);
+ return ntohs(*(__be16 *)((void *)iph + sizeof(*iph) +
+ poff));
+ }
break;
}
}
@@ -161,24 +158,36 @@ static u32 flow_get_proto_dst(struct sk_buff *skb)
switch (skb->protocol) {
case htons(ETH_P_IP): {
struct iphdr *iph;
+ int poff;
if (!pskb_network_may_pull(skb, sizeof(*iph)))
break;
iph = ip_hdr(skb);
- if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
- has_ports(iph->protocol) &&
- pskb_network_may_pull(skb, iph->ihl * 4 + 4))
- return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2));
+ if (iph->frag_off & htons(IP_MF|IP_OFFSET))
+ break;
+ poff = proto_ports_offset(iph->protocol);
+ if (poff >= 0 &&
+ pskb_network_may_pull(skb, iph->ihl * 4 + 4 + poff)) {
+ iph = ip_hdr(skb);
+ return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 +
+ 2 + poff));
+ }
break;
}
case htons(ETH_P_IPV6): {
struct ipv6hdr *iph;
+ int poff;
- if (!pskb_network_may_pull(skb, sizeof(*iph) + 4))
+ if (!pskb_network_may_pull(skb, sizeof(*iph)))
break;
iph = ipv6_hdr(skb);
- if (has_ports(iph->nexthdr))
- return ntohs(*(__be16 *)((void *)&iph[1] + 2));
+ poff = proto_ports_offset(iph->nexthdr);
+ if (poff >= 0 &&
+ pskb_network_may_pull(skb, sizeof(*iph) + poff + 4)) {
+ iph = ipv6_hdr(skb);
+ return ntohs(*(__be16 *)((void *)iph + sizeof(*iph) +
+ poff + 2));
+ }
break;
}
}
@@ -297,6 +306,11 @@ static u32 flow_get_vlan_tag(const struct sk_buff *skb)
return tag & VLAN_VID_MASK;
}
+static u32 flow_get_rxhash(struct sk_buff *skb)
+{
+ return skb_get_rxhash(skb);
+}
+
static u32 flow_key_get(struct sk_buff *skb, int key)
{
switch (key) {
@@ -334,6 +348,8 @@ static u32 flow_key_get(struct sk_buff *skb, int key)
return flow_get_skgid(skb);
case FLOW_KEY_VLAN_TAG:
return flow_get_vlan_tag(skb);
+ case FLOW_KEY_RXHASH:
+ return flow_get_rxhash(skb);
default:
WARN_ON(1);
return 0;
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 3bcac8aa333c..34da5e29ea1a 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -223,6 +223,11 @@ META_COLLECTOR(int_maclen)
dst->value = skb->mac_len;
}
+META_COLLECTOR(int_rxhash)
+{
+ dst->value = skb_get_rxhash(skb);
+}
+
/**************************************************************************
* Netfilter
**************************************************************************/
@@ -541,6 +546,7 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = {
[META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off),
[META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend),
[META_ID(VLAN_TAG)] = META_FUNC(int_vlan_tag),
+ [META_ID(RXHASH)] = META_FUNC(int_rxhash),
}
};
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 408eea7086aa..b22ca2d1cebc 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -240,7 +240,10 @@ struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
if (q)
goto out;
- q = qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle);
+ if (dev_ingress_queue(dev))
+ q = qdisc_match_from_root(
+ dev_ingress_queue(dev)->qdisc_sleeping,
+ handle);
out:
return q;
}
@@ -360,7 +363,7 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
tsize = nla_len(tb[TCA_STAB_DATA]) / sizeof(u16);
}
- if (!s || tsize != s->tsize || (!tab && tsize > 0))
+ if (tsize != s->tsize || (!tab && tsize > 0))
return ERR_PTR(-EINVAL);
spin_lock(&qdisc_stab_lock);
@@ -690,6 +693,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
(new && new->flags & TCQ_F_INGRESS)) {
num_q = 1;
ingress = 1;
+ if (!dev_ingress_queue(dev))
+ return -ENOENT;
}
if (dev->flags & IFF_UP)
@@ -701,7 +706,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
}
for (i = 0; i < num_q; i++) {
- struct netdev_queue *dev_queue = &dev->rx_queue;
+ struct netdev_queue *dev_queue = dev_ingress_queue(dev);
if (!ingress)
dev_queue = netdev_get_tx_queue(dev, i);
@@ -979,7 +984,8 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
return -ENOENT;
q = qdisc_leaf(p, clid);
} else { /* ingress */
- q = dev->rx_queue.qdisc_sleeping;
+ if (dev_ingress_queue(dev))
+ q = dev_ingress_queue(dev)->qdisc_sleeping;
}
} else {
q = dev->qdisc;
@@ -1043,8 +1049,9 @@ replay:
if ((p = qdisc_lookup(dev, TC_H_MAJ(clid))) == NULL)
return -ENOENT;
q = qdisc_leaf(p, clid);
- } else { /*ingress */
- q = dev->rx_queue.qdisc_sleeping;
+ } else { /* ingress */
+ if (dev_ingress_queue_create(dev))
+ q = dev_ingress_queue(dev)->qdisc_sleeping;
}
} else {
q = dev->qdisc;
@@ -1123,11 +1130,14 @@ replay:
create_n_graft:
if (!(n->nlmsg_flags&NLM_F_CREATE))
return -ENOENT;
- if (clid == TC_H_INGRESS)
- q = qdisc_create(dev, &dev->rx_queue, p,
- tcm->tcm_parent, tcm->tcm_parent,
- tca, &err);
- else {
+ if (clid == TC_H_INGRESS) {
+ if (dev_ingress_queue(dev))
+ q = qdisc_create(dev, dev_ingress_queue(dev), p,
+ tcm->tcm_parent, tcm->tcm_parent,
+ tca, &err);
+ else
+ err = -ENOENT;
+ } else {
struct netdev_queue *dev_queue;
if (p && p->ops->cl_ops && p->ops->cl_ops->select_queue)
@@ -1304,8 +1314,10 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
if (tc_dump_qdisc_root(dev->qdisc, skb, cb, &q_idx, s_q_idx) < 0)
goto done;
- dev_queue = &dev->rx_queue;
- if (tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb, &q_idx, s_q_idx) < 0)
+ dev_queue = dev_ingress_queue(dev);
+ if (dev_queue &&
+ tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb,
+ &q_idx, s_q_idx) < 0)
goto done;
cont:
@@ -1595,8 +1607,10 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t) < 0)
goto done;
- dev_queue = &dev->rx_queue;
- if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0)
+ dev_queue = dev_ingress_queue(dev);
+ if (dev_queue &&
+ tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb,
+ &t, s_t) < 0)
goto done;
done:
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 6318e1136b83..282540778aa8 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -275,8 +275,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
goto err_out;
}
flow->filter_list = NULL;
- flow->q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- &pfifo_qdisc_ops, classid);
+ flow->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid);
if (!flow->q)
flow->q = &noop_qdisc;
pr_debug("atm_tc_change: qdisc %p\n", flow->q);
@@ -543,7 +542,7 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt)
INIT_LIST_HEAD(&p->flows);
INIT_LIST_HEAD(&p->link.list);
list_add(&p->link.list, &p->flows);
- p->link.q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
+ p->link.q = qdisc_create_dflt(sch->dev_queue,
&pfifo_qdisc_ops, sch->handle);
if (!p->link.q)
p->link.q = &noop_qdisc;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 28c01ef5abc8..eb7631590865 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1379,9 +1379,9 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
q->link.sibling = &q->link;
q->link.common.classid = sch->handle;
q->link.qdisc = sch;
- if (!(q->link.q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- &pfifo_qdisc_ops,
- sch->handle)))
+ q->link.q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
+ sch->handle);
+ if (!q->link.q)
q->link.q = &noop_qdisc;
q->link.priority = TC_CBQ_MAXPRIO-1;
@@ -1623,7 +1623,7 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
struct cbq_class *cl = (struct cbq_class*)arg;
if (new == NULL) {
- new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
+ new = qdisc_create_dflt(sch->dev_queue,
&pfifo_qdisc_ops, cl->common.classid);
if (new == NULL)
return -ENOBUFS;
@@ -1874,8 +1874,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
cl->R_tab = rtab;
rtab = NULL;
cl->refcnt = 1;
- if (!(cl->q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- &pfifo_qdisc_ops, classid)))
+ cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid);
+ if (!cl->q)
cl->q = &noop_qdisc;
cl->common.classid = classid;
cl->tparent = parent;
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index b74046a95397..aa8b5313f8cf 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -110,7 +110,7 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
cl->refcnt = 1;
cl->common.classid = classid;
cl->quantum = quantum;
- cl->qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
+ cl->qdisc = qdisc_create_dflt(sch->dev_queue,
&pfifo_qdisc_ops, classid);
if (cl->qdisc == NULL)
cl->qdisc = &noop_qdisc;
@@ -218,7 +218,7 @@ static int drr_graft_class(struct Qdisc *sch, unsigned long arg,
struct drr_class *cl = (struct drr_class *)arg;
if (new == NULL) {
- new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
+ new = qdisc_create_dflt(sch->dev_queue,
&pfifo_qdisc_ops, cl->common.classid);
if (new == NULL)
new = &noop_qdisc;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 63d41f86679c..1d295d62bb5c 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -61,8 +61,7 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
sch, p, new, old);
if (new == NULL) {
- new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- &pfifo_qdisc_ops,
+ new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
sch->handle);
if (new == NULL)
new = &noop_qdisc;
@@ -384,8 +383,7 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt)
p->default_index = default_index;
p->set_tc_index = nla_get_flag(tb[TCA_DSMARK_SET_TC_INDEX]);
- p->q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- &pfifo_qdisc_ops, sch->handle);
+ p->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle);
if (p->q == NULL)
p->q = &noop_qdisc;
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 5948bafa8ce2..4dfecb0cba37 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -172,8 +172,7 @@ struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops,
struct Qdisc *q;
int err = -ENOMEM;
- q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- ops, TC_H_MAKE(sch->handle, 1));
+ q = qdisc_create_dflt(sch->dev_queue, ops, TC_H_MAKE(sch->handle, 1));
if (q) {
err = fifo_set_limit(q, limit);
if (err < 0) {
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 2aeb3a4386a1..5dbb3cd96e59 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -383,6 +383,7 @@ struct Qdisc noop_qdisc = {
.list = LIST_HEAD_INIT(noop_qdisc.list),
.q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
.dev_queue = &noop_netdev_queue,
+ .busylock = __SPIN_LOCK_UNLOCKED(noop_qdisc.busylock),
};
EXPORT_SYMBOL(noop_qdisc);
@@ -409,6 +410,7 @@ static struct Qdisc noqueue_qdisc = {
.list = LIST_HEAD_INIT(noqueue_qdisc.list),
.q.lock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock),
.dev_queue = &noqueue_netdev_queue,
+ .busylock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.busylock),
};
@@ -574,10 +576,8 @@ errout:
return ERR_PTR(err);
}
-struct Qdisc * qdisc_create_dflt(struct net_device *dev,
- struct netdev_queue *dev_queue,
- struct Qdisc_ops *ops,
- unsigned int parentid)
+struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
+ struct Qdisc_ops *ops, unsigned int parentid)
{
struct Qdisc *sch;
@@ -682,7 +682,7 @@ static void attach_one_default_qdisc(struct net_device *dev,
struct Qdisc *qdisc;
if (dev->tx_queue_len) {
- qdisc = qdisc_create_dflt(dev, dev_queue,
+ qdisc = qdisc_create_dflt(dev_queue,
&pfifo_fast_ops, TC_H_ROOT);
if (!qdisc) {
printk(KERN_INFO "%s: activation failed\n", dev->name);
@@ -709,7 +709,7 @@ static void attach_default_qdiscs(struct net_device *dev)
dev->qdisc = txq->qdisc_sleeping;
atomic_inc(&dev->qdisc->refcnt);
} else {
- qdisc = qdisc_create_dflt(dev, txq, &mq_qdisc_ops, TC_H_ROOT);
+ qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT);
if (qdisc) {
qdisc->ops->attach(qdisc);
dev->qdisc = qdisc;
@@ -753,7 +753,8 @@ void dev_activate(struct net_device *dev)
need_watchdog = 0;
netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog);
- transition_one_qdisc(dev, &dev->rx_queue, NULL);
+ if (dev_ingress_queue(dev))
+ transition_one_qdisc(dev, dev_ingress_queue(dev), NULL);
if (need_watchdog) {
dev->trans_start = jiffies;
@@ -812,7 +813,8 @@ static bool some_qdisc_is_busy(struct net_device *dev)
void dev_deactivate(struct net_device *dev)
{
netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc);
- dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc);
+ if (dev_ingress_queue(dev))
+ dev_deactivate_queue(dev, dev_ingress_queue(dev), &noop_qdisc);
dev_watchdog_down(dev);
@@ -838,7 +840,8 @@ void dev_init_scheduler(struct net_device *dev)
{
dev->qdisc = &noop_qdisc;
netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc);
- dev_init_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc);
+ if (dev_ingress_queue(dev))
+ dev_init_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc);
setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev);
}
@@ -861,7 +864,8 @@ static void shutdown_scheduler_queue(struct net_device *dev,
void dev_shutdown(struct net_device *dev)
{
netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc);
- shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc);
+ if (dev_ingress_queue(dev))
+ shutdown_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc);
qdisc_destroy(dev->qdisc);
dev->qdisc = &noop_qdisc;
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 47496098d35c..069c62b7bb36 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1088,7 +1088,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
cl->refcnt = 1;
cl->sched = q;
cl->cl_parent = parent;
- cl->qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
+ cl->qdisc = qdisc_create_dflt(sch->dev_queue,
&pfifo_qdisc_ops, classid);
if (cl->qdisc == NULL)
cl->qdisc = &noop_qdisc;
@@ -1209,8 +1209,7 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
if (cl->level > 0)
return -EINVAL;
if (new == NULL) {
- new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- &pfifo_qdisc_ops,
+ new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
cl->cl_common.classid);
if (new == NULL)
new = &noop_qdisc;
@@ -1452,8 +1451,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
q->root.cl_common.classid = sch->handle;
q->root.refcnt = 1;
q->root.sched = q;
- q->root.qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- &pfifo_qdisc_ops,
+ q->root.qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
sch->handle);
if (q->root.qdisc == NULL)
q->root.qdisc = &noop_qdisc;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 4be8d04b262d..01b519d6c52d 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1121,8 +1121,7 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
if (cl->level)
return -EINVAL;
if (new == NULL &&
- (new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- &pfifo_qdisc_ops,
+ (new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
cl->common.classid)) == NULL)
return -ENOBUFS;
@@ -1247,8 +1246,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
return -EBUSY;
if (!cl->level && htb_parent_last_child(cl)) {
- new_q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- &pfifo_qdisc_ops,
+ new_q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
cl->parent->common.classid);
last_child = 1;
}
@@ -1302,14 +1300,14 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
struct htb_class *cl = (struct htb_class *)*arg, *parent;
struct nlattr *opt = tca[TCA_OPTIONS];
struct qdisc_rate_table *rtab = NULL, *ctab = NULL;
- struct nlattr *tb[TCA_HTB_RTAB + 1];
+ struct nlattr *tb[__TCA_HTB_MAX];
struct tc_htb_opt *hopt;
/* extract all subattrs from opt attr */
if (!opt)
goto failure;
- err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, htb_policy);
+ err = nla_parse_nested(tb, TCA_HTB_MAX, opt, htb_policy);
if (err < 0)
goto failure;
@@ -1377,7 +1375,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
/* create leaf qdisc early because it uses kmalloc(GFP_KERNEL)
so that can't be used inside of sch_tree_lock
-- thanks to Karlis Peisenieks */
- new_q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
+ new_q = qdisc_create_dflt(sch->dev_queue,
&pfifo_qdisc_ops, classid);
sch_tree_lock(sch);
if (parent && !parent->level) {
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index fe91e50f9d98..ecc302f4d2a1 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -56,7 +56,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt)
for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
dev_queue = netdev_get_tx_queue(dev, ntx);
- qdisc = qdisc_create_dflt(dev, dev_queue, &pfifo_fast_ops,
+ qdisc = qdisc_create_dflt(dev_queue, &pfifo_fast_ops,
TC_H_MAKE(TC_H_MAJ(sch->handle),
TC_H_MIN(ntx + 1)));
if (qdisc == NULL)
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 6ae251279fc2..32690deab5d0 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -227,8 +227,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
for (i = 0; i < q->bands; i++) {
if (q->queues[i] == &noop_qdisc) {
struct Qdisc *child, *old;
- child = qdisc_create_dflt(qdisc_dev(sch),
- sch->dev_queue,
+ child = qdisc_create_dflt(sch->dev_queue,
&pfifo_qdisc_ops,
TC_H_MAKE(sch->handle,
i + 1));
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 4714ff162bbd..e5593c083a78 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -538,8 +538,7 @@ static int netem_init(struct Qdisc *sch, struct nlattr *opt)
qdisc_watchdog_init(&q->watchdog, sch);
- q->qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
- &tfifo_qdisc_ops,
+ q->qdisc = qdisc_create_dflt(sch->dev_queue, &tfifo_qdisc_ops,
TC_H_MAKE(sch->handle, 1));
if (!q->qdisc) {
pr_debug("netem: qdisc create failed\n");
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 0748fb1e3a49..b1c95bce33ce 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -200,7 +200,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
for (i=0; i<q->bands; i++) {
if (q->queues[i] == &noop_qdisc) {
struct Qdisc *child, *old;
- child = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
+ child = qdisc_create_dflt(sch->dev_queue,
&pfifo_qdisc_ops,
TC_H_MAKE(sch->handle, i + 1));
if (child) {
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 201cbac2b32c..3cf478d012dd 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -123,40 +123,39 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
case htons(ETH_P_IP):
{
const struct iphdr *iph;
+ int poff;
if (!pskb_network_may_pull(skb, sizeof(*iph)))
goto err;
iph = ip_hdr(skb);
h = (__force u32)iph->daddr;
h2 = (__force u32)iph->saddr ^ iph->protocol;
- if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
- (iph->protocol == IPPROTO_TCP ||
- iph->protocol == IPPROTO_UDP ||
- iph->protocol == IPPROTO_UDPLITE ||
- iph->protocol == IPPROTO_SCTP ||
- iph->protocol == IPPROTO_DCCP ||
- iph->protocol == IPPROTO_ESP) &&
- pskb_network_may_pull(skb, iph->ihl * 4 + 4))
- h2 ^= *(((u32*)iph) + iph->ihl);
+ if (iph->frag_off & htons(IP_MF|IP_OFFSET))
+ break;
+ poff = proto_ports_offset(iph->protocol);
+ if (poff >= 0 &&
+ pskb_network_may_pull(skb, iph->ihl * 4 + 4 + poff)) {
+ iph = ip_hdr(skb);
+ h2 ^= *(u32*)((void *)iph + iph->ihl * 4 + poff);
+ }
break;
}
case htons(ETH_P_IPV6):
{
struct ipv6hdr *iph;
+ int poff;
if (!pskb_network_may_pull(skb, sizeof(*iph)))
goto err;
iph = ipv6_hdr(skb);
h = (__force u32)iph->daddr.s6_addr32[3];
h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr;
- if ((iph->nexthdr == IPPROTO_TCP ||
- iph->nexthdr == IPPROTO_UDP ||
- iph->nexthdr == IPPROTO_UDPLITE ||
- iph->nexthdr == IPPROTO_SCTP ||
- iph->nexthdr == IPPROTO_DCCP ||
- iph->nexthdr == IPPROTO_ESP) &&
- pskb_network_may_pull(skb, sizeof(*iph) + 4))
- h2 ^= *(u32*)&iph[1];
+ poff = proto_ports_offset(iph->nexthdr);
+ if (poff >= 0 &&
+ pskb_network_may_pull(skb, sizeof(*iph) + 4 + poff)) {
+ iph = ipv6_hdr(skb);
+ h2 ^= *(u32*)((void *)iph + sizeof(*iph) + poff);
+ }
break;
}
default:
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index feaabc103ce6..401af9596709 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -241,11 +241,11 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *
}
if (neigh_event_send(n, skb_res) == 0) {
int err;
+ char haddr[MAX_ADDR_LEN];
- read_lock(&n->lock);
- err = dev_hard_header(skb, dev, ntohs(skb->protocol),
- n->ha, NULL, skb->len);
- read_unlock(&n->lock);
+ neigh_ha_snapshot(haddr, n, dev);
+ err = dev_hard_header(skb, dev, ntohs(skb->protocol), haddr,
+ NULL, skb->len);
if (err < 0) {
neigh_release(n);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 0b85e5256434..5f1fb8bd862d 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -48,6 +48,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/poll.h>
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 476caaf100ed..6c8556459a75 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -37,6 +37,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/net.h>
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index ccb6dc48d15b..397296fb156f 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -43,6 +43,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
#include <linux/interrupt.h>
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 732689140fb8..95e0c8eda1a0 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -47,6 +47,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/types.h>
@@ -336,7 +338,7 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
memcpy(saddr, baddr, sizeof(union sctp_addr));
SCTP_DEBUG_PRINTK("saddr: %pI6\n", &saddr->v6.sin6_addr);
} else {
- printk(KERN_ERR "%s: asoc:%p Could not find a valid source "
+ pr_err("%s: asoc:%p Could not find a valid source "
"address for the dest:%pI6\n",
__func__, asoc, &daddr->v6.sin6_addr);
}
diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c
index f73ec0ea93ba..8ef8e7d9eb61 100644
--- a/net/sctp/objcnt.c
+++ b/net/sctp/objcnt.c
@@ -38,6 +38,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <net/sctp/sctp.h>
@@ -134,8 +136,7 @@ void sctp_dbg_objcnt_init(void)
ent = proc_create("sctp_dbg_objcnt", 0,
proc_net_sctp, &sctp_objcnt_ops);
if (!ent)
- printk(KERN_WARNING
- "sctp_dbg_objcnt: Unable to create /proc entry.\n");
+ pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n");
}
/* Cleanup the objcount entry in the proc filesystem. */
diff --git a/net/sctp/output.c b/net/sctp/output.c
index bcc4590ccaf2..60600d337a3a 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -41,6 +41,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/wait.h>
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index c04b2eb59186..8c6d379b4bb6 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -46,6 +46,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/types.h>
#include <linux/list.h> /* For struct list_head */
#include <linux/socket.h>
@@ -1463,23 +1465,23 @@ static void sctp_check_transmitted(struct sctp_outq *q,
/* Display the end of the
* current range.
*/
- SCTP_DEBUG_PRINTK("-%08x",
- dbg_last_ack_tsn);
+ SCTP_DEBUG_PRINTK_CONT("-%08x",
+ dbg_last_ack_tsn);
}
/* Start a new range. */
- SCTP_DEBUG_PRINTK(",%08x", tsn);
+ SCTP_DEBUG_PRINTK_CONT(",%08x", tsn);
dbg_ack_tsn = tsn;
break;
case 1: /* The last TSN was NOT ACKed. */
if (dbg_last_kept_tsn != dbg_kept_tsn) {
/* Display the end of current range. */
- SCTP_DEBUG_PRINTK("-%08x",
- dbg_last_kept_tsn);
+ SCTP_DEBUG_PRINTK_CONT("-%08x",
+ dbg_last_kept_tsn);
}
- SCTP_DEBUG_PRINTK("\n");
+ SCTP_DEBUG_PRINTK_CONT("\n");
/* FALL THROUGH... */
default:
@@ -1526,18 +1528,18 @@ static void sctp_check_transmitted(struct sctp_outq *q,
break;
if (dbg_last_kept_tsn != dbg_kept_tsn)
- SCTP_DEBUG_PRINTK("-%08x",
- dbg_last_kept_tsn);
+ SCTP_DEBUG_PRINTK_CONT("-%08x",
+ dbg_last_kept_tsn);
- SCTP_DEBUG_PRINTK(",%08x", tsn);
+ SCTP_DEBUG_PRINTK_CONT(",%08x", tsn);
dbg_kept_tsn = tsn;
break;
case 0:
if (dbg_last_ack_tsn != dbg_ack_tsn)
- SCTP_DEBUG_PRINTK("-%08x",
- dbg_last_ack_tsn);
- SCTP_DEBUG_PRINTK("\n");
+ SCTP_DEBUG_PRINTK_CONT("-%08x",
+ dbg_last_ack_tsn);
+ SCTP_DEBUG_PRINTK_CONT("\n");
/* FALL THROUGH... */
default:
@@ -1556,17 +1558,17 @@ static void sctp_check_transmitted(struct sctp_outq *q,
switch (dbg_prt_state) {
case 0:
if (dbg_last_ack_tsn != dbg_ack_tsn) {
- SCTP_DEBUG_PRINTK("-%08x\n", dbg_last_ack_tsn);
+ SCTP_DEBUG_PRINTK_CONT("-%08x\n", dbg_last_ack_tsn);
} else {
- SCTP_DEBUG_PRINTK("\n");
+ SCTP_DEBUG_PRINTK_CONT("\n");
}
break;
case 1:
if (dbg_last_kept_tsn != dbg_kept_tsn) {
- SCTP_DEBUG_PRINTK("-%08x\n", dbg_last_kept_tsn);
+ SCTP_DEBUG_PRINTK_CONT("-%08x\n", dbg_last_kept_tsn);
} else {
- SCTP_DEBUG_PRINTK("\n");
+ SCTP_DEBUG_PRINTK_CONT("\n");
}
}
#endif /* SCTP_DEBUG */
diff --git a/net/sctp/probe.c b/net/sctp/probe.c
index 289b1ba62cac..bc6cd75cc1dc 100644
--- a/net/sctp/probe.c
+++ b/net/sctp/probe.c
@@ -22,6 +22,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/socket.h>
@@ -193,7 +195,7 @@ static __init int sctpprobe_init(void)
if (ret)
goto remove_proc;
- pr_info("SCTP probe registered (port=%d)\n", port);
+ pr_info("probe registered (port=%d)\n", port);
return 0;
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 5027b83f1cc0..1ef29c74d85e 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -46,6 +46,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
@@ -707,8 +709,7 @@ static int sctp_ctl_sock_init(void)
&init_net);
if (err < 0) {
- printk(KERN_ERR
- "SCTP: Failed to create the SCTP control socket.\n");
+ pr_err("Failed to create the SCTP control socket\n");
return err;
}
return 0;
@@ -798,7 +799,7 @@ static void sctp_inet_skb_msgname(struct sk_buff *skb, char *msgname, int *len)
static int sctp_inet_af_supported(sa_family_t family, struct sctp_sock *sp)
{
/* PF_INET only supports AF_INET addresses. */
- return (AF_INET == family);
+ return AF_INET == family;
}
/* Address matching with wildcards allowed. */
@@ -1206,7 +1207,7 @@ SCTP_STATIC __init int sctp_init(void)
__get_free_pages(GFP_ATOMIC, order);
} while (!sctp_assoc_hashtable && --order > 0);
if (!sctp_assoc_hashtable) {
- printk(KERN_ERR "SCTP: Failed association hash alloc.\n");
+ pr_err("Failed association hash alloc\n");
status = -ENOMEM;
goto err_ahash_alloc;
}
@@ -1220,7 +1221,7 @@ SCTP_STATIC __init int sctp_init(void)
sctp_ep_hashtable = (struct sctp_hashbucket *)
kmalloc(64 * sizeof(struct sctp_hashbucket), GFP_KERNEL);
if (!sctp_ep_hashtable) {
- printk(KERN_ERR "SCTP: Failed endpoint_hash alloc.\n");
+ pr_err("Failed endpoint_hash alloc\n");
status = -ENOMEM;
goto err_ehash_alloc;
}
@@ -1239,7 +1240,7 @@ SCTP_STATIC __init int sctp_init(void)
__get_free_pages(GFP_ATOMIC, order);
} while (!sctp_port_hashtable && --order > 0);
if (!sctp_port_hashtable) {
- printk(KERN_ERR "SCTP: Failed bind hash alloc.");
+ pr_err("Failed bind hash alloc\n");
status = -ENOMEM;
goto err_bhash_alloc;
}
@@ -1248,8 +1249,7 @@ SCTP_STATIC __init int sctp_init(void)
INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);
}
- printk(KERN_INFO "SCTP: Hash tables configured "
- "(established %d bind %d)\n",
+ pr_info("Hash tables configured (established %d bind %d)\n",
sctp_assoc_hashsize, sctp_port_hashsize);
/* Disable ADDIP by default. */
@@ -1290,8 +1290,7 @@ SCTP_STATIC __init int sctp_init(void)
/* Initialize the control inode/socket for handling OOTB packets. */
if ((status = sctp_ctl_sock_init())) {
- printk (KERN_ERR
- "SCTP: Failed to initialize the SCTP control sock.\n");
+ pr_err("Failed to initialize the SCTP control sock\n");
goto err_ctl_sock_init;
}
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 246f92924658..2cc46f0962ca 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -50,6 +50,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/ip.h>
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index f5e5e27cac5e..b21b218d564f 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -47,6 +47,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/skbuff.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -1146,26 +1148,23 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
case SCTP_DISPOSITION_VIOLATION:
if (net_ratelimit())
- printk(KERN_ERR "sctp protocol violation state %d "
- "chunkid %d\n", state, subtype.chunk);
+ pr_err("protocol violation state %d chunkid %d\n",
+ state, subtype.chunk);
break;
case SCTP_DISPOSITION_NOT_IMPL:
- printk(KERN_WARNING "sctp unimplemented feature in state %d, "
- "event_type %d, event_id %d\n",
- state, event_type, subtype.chunk);
+ pr_warn("unimplemented feature in state %d, event_type %d, event_id %d\n",
+ state, event_type, subtype.chunk);
break;
case SCTP_DISPOSITION_BUG:
- printk(KERN_ERR "sctp bug in state %d, "
- "event_type %d, event_id %d\n",
+ pr_err("bug in state %d, event_type %d, event_id %d\n",
state, event_type, subtype.chunk);
BUG();
break;
default:
- printk(KERN_ERR "sctp impossible disposition %d "
- "in state %d, event_type %d, event_id %d\n",
+ pr_err("impossible disposition %d in state %d, event_type %d, event_id %d\n",
status, state, event_type, subtype.chunk);
BUG();
break;
@@ -1679,8 +1678,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_cmd_send_asconf(asoc);
break;
default:
- printk(KERN_WARNING "Impossible command: %u, %p\n",
- cmd->verb, cmd->obj.ptr);
+ pr_warn("Impossible command: %u, %p\n",
+ cmd->verb, cmd->obj.ptr);
break;
}
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index d344dc481ccc..4b4eb7c96bbd 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -50,6 +50,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/ip.h>
@@ -1138,18 +1140,16 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
if (unlikely(!link)) {
if (from_addr.sa.sa_family == AF_INET6) {
if (net_ratelimit())
- printk(KERN_WARNING
- "%s association %p could not find address %pI6\n",
- __func__,
- asoc,
- &from_addr.v6.sin6_addr);
+ pr_warn("%s association %p could not find address %pI6\n",
+ __func__,
+ asoc,
+ &from_addr.v6.sin6_addr);
} else {
if (net_ratelimit())
- printk(KERN_WARNING
- "%s association %p could not find address %pI4\n",
- __func__,
- asoc,
- &from_addr.v4.sin_addr.s_addr);
+ pr_warn("%s association %p could not find address %pI4\n",
+ __func__,
+ asoc,
+ &from_addr.v4.sin_addr.s_addr);
}
return SCTP_DISPOSITION_DISCARD;
}
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 6d9b3aafcc5d..546d4387fb3c 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -46,6 +46,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/skbuff.h>
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
@@ -66,15 +68,19 @@ static const sctp_sm_table_entry_t bug = {
.name = "sctp_sf_bug"
};
-#define DO_LOOKUP(_max, _type, _table) \
- if ((event_subtype._type > (_max))) { \
- printk(KERN_WARNING \
- "sctp table %p possible attack:" \
- " event %d exceeds max %d\n", \
- _table, event_subtype._type, _max); \
- return &bug; \
- } \
- return &_table[event_subtype._type][(int)state];
+#define DO_LOOKUP(_max, _type, _table) \
+({ \
+ const sctp_sm_table_entry_t *rtn; \
+ \
+ if ((event_subtype._type > (_max))) { \
+ pr_warn("table %p possible attack: event %d exceeds max %d\n", \
+ _table, event_subtype._type, _max); \
+ rtn = &bug; \
+ } else \
+ rtn = &_table[event_subtype._type][(int)state]; \
+ \
+ rtn; \
+})
const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
sctp_state_t state,
@@ -83,21 +89,15 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
switch (event_type) {
case SCTP_EVENT_T_CHUNK:
return sctp_chunk_event_lookup(event_subtype.chunk, state);
- break;
case SCTP_EVENT_T_TIMEOUT:
- DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout,
- timeout_event_table);
- break;
-
+ return DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout,
+ timeout_event_table);
case SCTP_EVENT_T_OTHER:
- DO_LOOKUP(SCTP_EVENT_OTHER_MAX, other, other_event_table);
- break;
-
+ return DO_LOOKUP(SCTP_EVENT_OTHER_MAX, other,
+ other_event_table);
case SCTP_EVENT_T_PRIMITIVE:
- DO_LOOKUP(SCTP_EVENT_PRIMITIVE_MAX, primitive,
- primitive_event_table);
- break;
-
+ return DO_LOOKUP(SCTP_EVENT_PRIMITIVE_MAX, primitive,
+ primitive_event_table);
default:
/* Yikes! We got an illegal event type. */
return &bug;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index fbb70770ad05..e34ca9cc1167 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -57,6 +57,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/wait.h>
@@ -2469,9 +2471,8 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk,
if (params.sack_delay == 0 && params.sack_freq == 0)
return 0;
} else if (optlen == sizeof(struct sctp_assoc_value)) {
- printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value "
- "in delayed_ack socket option deprecated\n");
- printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n");
+ pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n");
+ pr_warn("Use struct sctp_sack_info instead\n");
if (copy_from_user(&params, optval, optlen))
return -EFAULT;
@@ -2879,10 +2880,8 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned
int val;
if (optlen == sizeof(int)) {
- printk(KERN_WARNING
- "SCTP: Use of int in maxseg socket option deprecated\n");
- printk(KERN_WARNING
- "SCTP: Use struct sctp_assoc_value instead\n");
+ pr_warn("Use of int in maxseg socket option deprecated\n");
+ pr_warn("Use struct sctp_assoc_value instead\n");
if (copy_from_user(&val, optval, optlen))
return -EFAULT;
params.assoc_id = 0;
@@ -3132,10 +3131,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
int assoc_id = 0;
if (optlen == sizeof(int)) {
- printk(KERN_WARNING
- "SCTP: Use of int in max_burst socket option deprecated\n");
- printk(KERN_WARNING
- "SCTP: Use struct sctp_assoc_value instead\n");
+ pr_warn("Use of int in max_burst socket option deprecated\n");
+ pr_warn("Use struct sctp_assoc_value instead\n");
if (copy_from_user(&val, optval, optlen))
return -EFAULT;
} else if (optlen == sizeof(struct sctp_assoc_value)) {
@@ -3606,7 +3603,40 @@ out:
/* The SCTP ioctl handler. */
SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
- return -ENOIOCTLCMD;
+ int rc = -ENOTCONN;
+
+ sctp_lock_sock(sk);
+
+ /*
+ * SEQPACKET-style sockets in LISTENING state are valid, for
+ * SCTP, so only discard TCP-style sockets in LISTENING state.
+ */
+ if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))
+ goto out;
+
+ switch (cmd) {
+ case SIOCINQ: {
+ struct sk_buff *skb;
+ unsigned int amount = 0;
+
+ skb = skb_peek(&sk->sk_receive_queue);
+ if (skb != NULL) {
+ /*
+ * We will only return the amount of this packet since
+ * that is all that will be read.
+ */
+ amount = skb->len;
+ }
+ rc = put_user(amount, (int __user *)arg);
+ break;
+ }
+ default:
+ rc = -ENOIOCTLCMD;
+ break;
+ }
+out:
+ sctp_release_sock(sk);
+ return rc;
}
/* This is the function which gets called during socket creation to
@@ -3865,7 +3895,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len,
}
out:
- return (retval);
+ return retval;
}
@@ -3921,7 +3951,7 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len,
}
out:
- return (retval);
+ return retval;
}
/* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS)
@@ -4292,9 +4322,8 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len,
if (copy_from_user(&params, optval, len))
return -EFAULT;
} else if (len == sizeof(struct sctp_assoc_value)) {
- printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value "
- "in delayed_ack socket option deprecated\n");
- printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n");
+ pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n");
+ pr_warn("Use struct sctp_sack_info instead\n");
if (copy_from_user(&params, optval, len))
return -EFAULT;
} else
@@ -4940,10 +4969,8 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len,
struct sctp_association *asoc;
if (len == sizeof(int)) {
- printk(KERN_WARNING
- "SCTP: Use of int in maxseg socket option deprecated\n");
- printk(KERN_WARNING
- "SCTP: Use struct sctp_assoc_value instead\n");
+ pr_warn("Use of int in maxseg socket option deprecated\n");
+ pr_warn("Use struct sctp_assoc_value instead\n");
params.assoc_id = 0;
} else if (len >= sizeof(struct sctp_assoc_value)) {
len = sizeof(struct sctp_assoc_value);
@@ -5034,10 +5061,8 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
struct sctp_association *asoc;
if (len == sizeof(int)) {
- printk(KERN_WARNING
- "SCTP: Use of int in max_burst socket option deprecated\n");
- printk(KERN_WARNING
- "SCTP: Use struct sctp_assoc_value instead\n");
+ pr_warn("Use of int in max_burst socket option deprecated\n");
+ pr_warn("Use struct sctp_assoc_value instead\n");
params.assoc_id = 0;
} else if (len >= sizeof(struct sctp_assoc_value)) {
len = sizeof(struct sctp_assoc_value);
@@ -5580,7 +5605,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum)
/* Note: sk->sk_num gets filled in if ephemeral port request. */
ret = sctp_get_port_local(sk, &addr);
- return (ret ? 1 : 0);
+ return ret ? 1 : 0;
}
/*
@@ -5597,8 +5622,7 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog)
tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
if (net_ratelimit()) {
- printk(KERN_INFO
- "SCTP: failed to load transform for %s: %ld\n",
+ pr_info("failed to load transform for %s: %ld\n",
sctp_hmac_alg, PTR_ERR(tfm));
}
return -ENOSYS;
@@ -5727,13 +5751,12 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
mask |= POLLERR;
if (sk->sk_shutdown & RCV_SHUTDOWN)
- mask |= POLLRDHUP;
+ mask |= POLLRDHUP | POLLIN | POLLRDNORM;
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
/* Is it readable? Reconsider this code with TCP-style support. */
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- (sk->sk_shutdown & RCV_SHUTDOWN))
+ if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= POLLIN | POLLRDNORM;
/* The association is either gone or not ready. */
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 132046cb82fc..d3ae493d234a 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -48,6 +48,8 @@
* be incorporated into the next SCTP release.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/random.h>
@@ -244,10 +246,9 @@ void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
struct dst_entry *dst;
if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
- printk(KERN_WARNING "%s: Reported pmtu %d too low, "
- "using default minimum of %d\n",
- __func__, pmtu,
- SCTP_DEFAULT_MINSEGMENT);
+ pr_warn("%s: Reported pmtu %d too low, using default minimum of %d\n",
+ __func__, pmtu,
+ SCTP_DEFAULT_MINSEGMENT);
/* Use default minimum segment size and disable
* pmtu discovery on this transport.
*/
diff --git a/net/socket.c b/net/socket.c
index 9eac5c394134..abf3e2561521 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -209,8 +209,8 @@ int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr)
* specified. Zero is returned for a success.
*/
-int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr,
- int __user *ulen)
+static int move_addr_to_user(struct sockaddr *kaddr, int klen,
+ void __user *uaddr, int __user *ulen)
{
int err;
int len;
@@ -536,14 +536,13 @@ void sock_release(struct socket *sock)
}
EXPORT_SYMBOL(sock_release);
-int sock_tx_timestamp(struct msghdr *msg, struct sock *sk,
- union skb_shared_tx *shtx)
+int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags)
{
- shtx->flags = 0;
+ *tx_flags = 0;
if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE))
- shtx->hardware = 1;
+ *tx_flags |= SKBTX_HW_TSTAMP;
if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
- shtx->software = 1;
+ *tx_flags |= SKBTX_SW_TSTAMP;
return 0;
}
EXPORT_SYMBOL(sock_tx_timestamp);
@@ -663,7 +662,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
}
EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
-inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
+static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
+ struct sk_buff *skb)
{
if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && skb->dropcount)
put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
@@ -1920,7 +1920,8 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
* Afterwards, it will be a kernel pointer. Thus the compiler-assisted
* checking falls down on this.
*/
- if (copy_from_user(ctl_buf, (void __user *)msg_sys.msg_control,
+ if (copy_from_user(ctl_buf,
+ (void __user __force *)msg_sys.msg_control,
ctl_len))
goto out_freectl;
msg_sys.msg_control = ctl_buf;
@@ -3055,14 +3056,19 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
char *optval, int *optlen)
{
mm_segment_t oldfs = get_fs();
+ char __user *uoptval;
+ int __user *uoptlen;
int err;
+ uoptval = (char __user __force *) optval;
+ uoptlen = (int __user __force *) optlen;
+
set_fs(KERNEL_DS);
if (level == SOL_SOCKET)
- err = sock_getsockopt(sock, level, optname, optval, optlen);
+ err = sock_getsockopt(sock, level, optname, uoptval, uoptlen);
else
- err = sock->ops->getsockopt(sock, level, optname, optval,
- optlen);
+ err = sock->ops->getsockopt(sock, level, optname, uoptval,
+ uoptlen);
set_fs(oldfs);
return err;
}
@@ -3072,13 +3078,16 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,
char *optval, unsigned int optlen)
{
mm_segment_t oldfs = get_fs();
+ char __user *uoptval;
int err;
+ uoptval = (char __user __force *) optval;
+
set_fs(KERNEL_DS);
if (level == SOL_SOCKET)
- err = sock_setsockopt(sock, level, optname, optval, optlen);
+ err = sock_setsockopt(sock, level, optname, uoptval, optlen);
else
- err = sock->ops->setsockopt(sock, level, optname, optval,
+ err = sock->ops->setsockopt(sock, level, optname, uoptval,
optlen);
set_fs(oldfs);
return err;
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 12c485982814..3835ce35e224 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1050,7 +1050,7 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
out:
if (acred->machine_cred != gss_cred->gc_machine_cred)
return 0;
- return (rc->cr_uid == acred->uid);
+ return rc->cr_uid == acred->uid;
}
/*
diff --git a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c
index 310b78e99456..c586e92bcf76 100644
--- a/net/sunrpc/auth_gss/gss_generic_token.c
+++ b/net/sunrpc/auth_gss/gss_generic_token.c
@@ -76,19 +76,19 @@ static int
der_length_size( int length)
{
if (length < (1<<7))
- return(1);
+ return 1;
else if (length < (1<<8))
- return(2);
+ return 2;
#if (SIZEOF_INT == 2)
else
- return(3);
+ return 3;
#else
else if (length < (1<<16))
- return(3);
+ return 3;
else if (length < (1<<24))
- return(4);
+ return 4;
else
- return(5);
+ return 5;
#endif
}
@@ -121,14 +121,14 @@ der_read_length(unsigned char **buf, int *bufsize)
int ret;
if (*bufsize < 1)
- return(-1);
+ return -1;
sf = *(*buf)++;
(*bufsize)--;
if (sf & 0x80) {
if ((sf &= 0x7f) > ((*bufsize)-1))
- return(-1);
+ return -1;
if (sf > SIZEOF_INT)
- return (-1);
+ return -1;
ret = 0;
for (; sf; sf--) {
ret = (ret<<8) + (*(*buf)++);
@@ -138,7 +138,7 @@ der_read_length(unsigned char **buf, int *bufsize)
ret = sf;
}
- return(ret);
+ return ret;
}
/* returns the length of a token, given the mech oid and the body size */
@@ -148,7 +148,7 @@ g_token_size(struct xdr_netobj *mech, unsigned int body_size)
{
/* set body_size to sequence contents size */
body_size += 2 + (int) mech->len; /* NEED overflow check */
- return(1 + der_length_size(body_size) + body_size);
+ return 1 + der_length_size(body_size) + body_size;
}
EXPORT_SYMBOL_GPL(g_token_size);
@@ -186,27 +186,27 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size,
int ret = 0;
if ((toksize-=1) < 0)
- return(G_BAD_TOK_HEADER);
+ return G_BAD_TOK_HEADER;
if (*buf++ != 0x60)
- return(G_BAD_TOK_HEADER);
+ return G_BAD_TOK_HEADER;
if ((seqsize = der_read_length(&buf, &toksize)) < 0)
- return(G_BAD_TOK_HEADER);
+ return G_BAD_TOK_HEADER;
if (seqsize != toksize)
- return(G_BAD_TOK_HEADER);
+ return G_BAD_TOK_HEADER;
if ((toksize-=1) < 0)
- return(G_BAD_TOK_HEADER);
+ return G_BAD_TOK_HEADER;
if (*buf++ != 0x06)
- return(G_BAD_TOK_HEADER);
+ return G_BAD_TOK_HEADER;
if ((toksize-=1) < 0)
- return(G_BAD_TOK_HEADER);
+ return G_BAD_TOK_HEADER;
toid.len = *buf++;
if ((toksize-=toid.len) < 0)
- return(G_BAD_TOK_HEADER);
+ return G_BAD_TOK_HEADER;
toid.data = buf;
buf+=toid.len;
@@ -217,17 +217,17 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size,
to return G_BAD_TOK_HEADER if the token header is in fact bad */
if ((toksize-=2) < 0)
- return(G_BAD_TOK_HEADER);
+ return G_BAD_TOK_HEADER;
if (ret)
- return(ret);
+ return ret;
if (!ret) {
*buf_in = buf;
*body_size = toksize;
}
- return(ret);
+ return ret;
}
EXPORT_SYMBOL_GPL(g_verify_token_header);
diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
index 415c013ba382..62ac90c62cb1 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
@@ -162,5 +162,5 @@ krb5_get_seq_num(struct krb5_ctx *kctx,
*seqnum = ((plain[0]) |
(plain[1] << 8) | (plain[2] << 16) | (plain[3] << 24));
- return (0);
+ return 0;
}
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index 2689de39dc78..8b4061049d76 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -331,7 +331,7 @@ gss_delete_sec_context(struct gss_ctx **context_handle)
*context_handle);
if (!*context_handle)
- return(GSS_S_NO_CONTEXT);
+ return GSS_S_NO_CONTEXT;
if ((*context_handle)->internal_ctx_id)
(*context_handle)->mech_type->gm_ops
->gss_delete_sec_context((*context_handle)
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index cace6049e4a5..aa5dbda6608c 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -376,7 +376,7 @@ int rpc_queue_empty(struct rpc_wait_queue *queue)
spin_lock_bh(&queue->lock);
res = queue->qlen;
spin_unlock_bh(&queue->lock);
- return (res == 0);
+ return res == 0;
}
EXPORT_SYMBOL_GPL(rpc_queue_empty);
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index c048543ffbeb..8a2e89bffde5 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -41,11 +41,6 @@
#include "cluster.h"
#include "net.h"
-u32 tipc_get_addr(void)
-{
- return tipc_own_addr;
-}
-
/**
* tipc_addr_domain_valid - validates a network domain address
*
@@ -89,7 +84,7 @@ int tipc_addr_domain_valid(u32 addr)
int tipc_addr_node_valid(u32 addr)
{
- return (tipc_addr_domain_valid(addr) && tipc_node(addr));
+ return tipc_addr_domain_valid(addr) && tipc_node(addr);
}
int tipc_in_scope(u32 domain, u32 addr)
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index a008c6689305..22a60fc98392 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -121,6 +121,9 @@ static DEFINE_SPINLOCK(bc_lock);
const char tipc_bclink_name[] = "broadcast-link";
+static void tipc_nmap_diff(struct tipc_node_map *nm_a,
+ struct tipc_node_map *nm_b,
+ struct tipc_node_map *nm_diff);
static u32 buf_seqno(struct sk_buff *buf)
{
@@ -143,6 +146,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf)
}
+static void bclink_set_last_sent(void)
+{
+ if (bcl->next_out)
+ bcl->fsm_msg_cnt = mod(buf_seqno(bcl->next_out) - 1);
+ else
+ bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1);
+}
+
+u32 tipc_bclink_get_last_sent(void)
+{
+ return bcl->fsm_msg_cnt;
+}
+
/**
* bclink_set_gap - set gap according to contents of current deferred pkt queue
*
@@ -171,7 +187,7 @@ static void bclink_set_gap(struct tipc_node *n_ptr)
static int bclink_ack_allowed(u32 n)
{
- return((n % TIPC_MIN_LINK_WIN) == tipc_own_tag);
+ return (n % TIPC_MIN_LINK_WIN) == tipc_own_tag;
}
@@ -237,8 +253,10 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
/* Try resolving broadcast link congestion, if necessary */
- if (unlikely(bcl->next_out))
+ if (unlikely(bcl->next_out)) {
tipc_link_push_queue(bcl);
+ bclink_set_last_sent();
+ }
if (unlikely(released && !list_empty(&bcl->waiting_ports)))
tipc_link_wakeup_ports(bcl, 0);
spin_unlock_bh(&bc_lock);
@@ -272,7 +290,7 @@ static void bclink_send_nack(struct tipc_node *n_ptr)
if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to))
return;
- buf = buf_acquire(INT_H_SIZE);
+ buf = tipc_buf_acquire(INT_H_SIZE);
if (buf) {
msg = buf_msg(buf);
tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
@@ -395,7 +413,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
if (unlikely(res == -ELINKCONG))
buf_discard(buf);
else
- bcl->stats.sent_info++;
+ bclink_set_last_sent();
if (bcl->out_queue_size > bcl->stats.max_queue_sz)
bcl->stats.max_queue_sz = bcl->out_queue_size;
@@ -529,15 +547,6 @@ receive:
tipc_node_unlock(node);
}
-u32 tipc_bclink_get_last_sent(void)
-{
- u32 last_sent = mod(bcl->next_out_no - 1);
-
- if (bcl->next_out)
- last_sent = mod(buf_seqno(bcl->next_out) - 1);
- return last_sent;
-}
-
u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
{
return (n_ptr->bclink.supported &&
@@ -570,6 +579,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
msg = buf_msg(buf);
msg_set_non_seq(msg, 1);
msg_set_mc_netid(msg, tipc_net_id);
+ bcl->stats.sent_info++;
}
/* Send buffer over bearers until all targets reached */
@@ -609,11 +619,13 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
bcbearer->remains = bcbearer->remains_new;
}
- /* Unable to reach all targets */
+ /*
+ * Unable to reach all targets (indicate success, since currently
+ * there isn't code in place to properly block & unblock the
+ * pseudo-bearer used by the broadcast link)
+ */
- bcbearer->bearer.publ.blocked = 1;
- bcl->stats.bearer_congs++;
- return 1;
+ return TIPC_OK;
}
/**
@@ -862,8 +874,9 @@ void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
* @nm_diff: output node map A-B (i.e. nodes of A that are not in B)
*/
-void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b,
- struct tipc_node_map *nm_diff)
+static void tipc_nmap_diff(struct tipc_node_map *nm_a,
+ struct tipc_node_map *nm_b,
+ struct tipc_node_map *nm_diff)
{
int stop = ARRAY_SIZE(nm_a->map);
int w;
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index e8c2b81658c7..011c03f0a4ab 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -84,9 +84,6 @@ static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_m
return !memcmp(nm_a, nm_b, sizeof(*nm_a));
}
-void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b,
- struct tipc_node_map *nm_diff);
-
void tipc_port_list_add(struct port_list *pl_ptr, u32 port);
void tipc_port_list_free(struct port_list *pl_ptr);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 52ae17b2583e..9927d1d56c4f 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -63,7 +63,7 @@ static int media_name_valid(const char *name)
len = strlen(name);
if ((len + 1) > TIPC_MAX_MEDIA_NAME)
return 0;
- return (strspn(name, tipc_alphabet) == len);
+ return strspn(name, tipc_alphabet) == len;
}
/**
@@ -288,9 +288,6 @@ static struct bearer *bearer_find(const char *name)
struct bearer *b_ptr;
u32 i;
- if (tipc_mode != TIPC_NET_MODE)
- return NULL;
-
for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
if (b_ptr->active && (!strcmp(b_ptr->publ.name, name)))
return b_ptr;
@@ -559,8 +556,6 @@ restart:
}
b_ptr = &tipc_bearers[bearer_id];
- memset(b_ptr, 0, sizeof(struct bearer));
-
strcpy(b_ptr->publ.name, name);
res = m_ptr->enable_bearer(&b_ptr->publ);
if (res) {
@@ -630,30 +625,17 @@ int tipc_block_bearer(const char *name)
* Note: This routine assumes caller holds tipc_net_lock.
*/
-static int bearer_disable(const char *name)
+static int bearer_disable(struct bearer *b_ptr)
{
- struct bearer *b_ptr;
struct link *l_ptr;
struct link *temp_l_ptr;
- b_ptr = bearer_find(name);
- if (!b_ptr) {
- warn("Attempt to disable unknown bearer <%s>\n", name);
- return -EINVAL;
- }
-
- info("Disabling bearer <%s>\n", name);
+ info("Disabling bearer <%s>\n", b_ptr->publ.name);
tipc_disc_stop_link_req(b_ptr->link_req);
spin_lock_bh(&b_ptr->publ.lock);
b_ptr->link_req = NULL;
b_ptr->publ.blocked = 1;
- if (b_ptr->media->disable_bearer) {
- spin_unlock_bh(&b_ptr->publ.lock);
- write_unlock_bh(&tipc_net_lock);
- b_ptr->media->disable_bearer(&b_ptr->publ);
- write_lock_bh(&tipc_net_lock);
- spin_lock_bh(&b_ptr->publ.lock);
- }
+ b_ptr->media->disable_bearer(&b_ptr->publ);
list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
tipc_link_delete(l_ptr);
}
@@ -664,10 +646,16 @@ static int bearer_disable(const char *name)
int tipc_disable_bearer(const char *name)
{
+ struct bearer *b_ptr;
int res;
write_lock_bh(&tipc_net_lock);
- res = bearer_disable(name);
+ b_ptr = bearer_find(name);
+ if (b_ptr == NULL) {
+ warn("Attempt to disable unknown bearer <%s>\n", name);
+ res = -EINVAL;
+ } else
+ res = bearer_disable(b_ptr);
write_unlock_bh(&tipc_net_lock);
return res;
}
@@ -680,13 +668,7 @@ void tipc_bearer_stop(void)
for (i = 0; i < MAX_BEARERS; i++) {
if (tipc_bearers[i].active)
- tipc_bearers[i].publ.blocked = 1;
- }
- for (i = 0; i < MAX_BEARERS; i++) {
- if (tipc_bearers[i].active)
- bearer_disable(tipc_bearers[i].publ.name);
+ bearer_disable(&tipc_bearers[i]);
}
media_count = 0;
}
-
-
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
index e68f705381bc..7fea14b98b97 100644
--- a/net/tipc/cluster.c
+++ b/net/tipc/cluster.c
@@ -113,25 +113,6 @@ void tipc_cltr_delete(struct cluster *c_ptr)
kfree(c_ptr);
}
-u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr)
-{
- struct tipc_node *n_ptr;
- u32 n_num = tipc_node(addr) + 1;
-
- if (!c_ptr)
- return addr;
- for (; n_num <= c_ptr->highest_node; n_num++) {
- n_ptr = c_ptr->nodes[n_num];
- if (n_ptr && tipc_node_has_active_links(n_ptr))
- return n_ptr->addr;
- }
- for (n_num = 1; n_num < tipc_node(addr); n_num++) {
- n_ptr = c_ptr->nodes[n_num];
- if (n_ptr && tipc_node_has_active_links(n_ptr))
- return n_ptr->addr;
- }
- return 0;
-}
void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr)
{
@@ -232,7 +213,7 @@ struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector)
static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest)
{
u32 size = INT_H_SIZE + data_size;
- struct sk_buff *buf = buf_acquire(size);
+ struct sk_buff *buf = tipc_buf_acquire(size);
struct tipc_msg *msg;
if (buf) {
diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h
index 333efb0b9c44..32636d98c9c6 100644
--- a/net/tipc/cluster.h
+++ b/net/tipc/cluster.h
@@ -75,7 +75,7 @@ void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr);
void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest);
void tipc_cltr_broadcast(struct sk_buff *buf);
int tipc_cltr_init(void);
-u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr);
+
void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest);
void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 961d1b097146..50a6133a3668 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -95,7 +95,7 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
return 1;
}
-struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value)
+static struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value)
{
struct sk_buff *buf;
__be32 value_net;
@@ -109,6 +109,11 @@ struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value)
return buf;
}
+static struct sk_buff *tipc_cfg_reply_unsigned(u32 value)
+{
+ return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value);
+}
+
struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string)
{
struct sk_buff *buf;
@@ -120,139 +125,6 @@ struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string)
return buf;
}
-
-#if 0
-
-/* Now obsolete code for handling commands not yet implemented the new way */
-
-/*
- * Some of this code assumed that the manager structure contains two added
- * fields:
- * u32 link_subscriptions;
- * struct list_head link_subscribers;
- * which are currently not present. These fields may need to be re-introduced
- * if and when support for link subscriptions is added.
- */
-
-void tipc_cfg_link_event(u32 addr, char *name, int up)
-{
- /* TIPC DOESN'T HANDLE LINK EVENT SUBSCRIPTIONS AT THE MOMENT */
-}
-
-int tipc_cfg_cmd(const struct tipc_cmd_msg * msg,
- char *data,
- u32 sz,
- u32 *ret_size,
- struct tipc_portid *orig)
-{
- int rv = -EINVAL;
- u32 cmd = msg->cmd;
-
- *ret_size = 0;
- switch (cmd) {
- case TIPC_REMOVE_LINK:
- case TIPC_CMD_BLOCK_LINK:
- case TIPC_CMD_UNBLOCK_LINK:
- if (!cfg_check_connection(orig))
- rv = link_control(msg->argv.link_name, msg->cmd, 0);
- break;
- case TIPC_ESTABLISH:
- {
- int connected;
-
- tipc_isconnected(mng.conn_port_ref, &connected);
- if (connected || !orig) {
- rv = TIPC_FAILURE;
- break;
- }
- rv = tipc_connect2port(mng.conn_port_ref, orig);
- if (rv == TIPC_OK)
- orig = 0;
- break;
- }
- case TIPC_GET_PEER_ADDRESS:
- *ret_size = link_peer_addr(msg->argv.link_name, data, sz);
- break;
- case TIPC_GET_ROUTES:
- rv = TIPC_OK;
- break;
- default: {}
- }
- if (*ret_size)
- rv = TIPC_OK;
- return rv;
-}
-
-static void cfg_cmd_event(struct tipc_cmd_msg *msg,
- char *data,
- u32 sz,
- struct tipc_portid const *orig)
-{
- int rv = -EINVAL;
- struct tipc_cmd_result_msg rmsg;
- struct iovec msg_sect[2];
- int *arg;
-
- msg->cmd = ntohl(msg->cmd);
-
- cfg_prepare_res_msg(msg->cmd, msg->usr_handle, rv, &rmsg, msg_sect,
- data, 0);
- if (ntohl(msg->magic) != TIPC_MAGIC)
- goto exit;
-
- switch (msg->cmd) {
- case TIPC_CREATE_LINK:
- if (!cfg_check_connection(orig))
- rv = disc_create_link(&msg->argv.create_link);
- break;
- case TIPC_LINK_SUBSCRIBE:
- {
- struct subscr_data *sub;
-
- if (mng.link_subscriptions > 64)
- break;
- sub = kmalloc(sizeof(*sub),
- GFP_ATOMIC);
- if (sub == NULL) {
- warn("Memory squeeze; dropped remote link subscription\n");
- break;
- }
- INIT_LIST_HEAD(&sub->subd_list);
- tipc_createport(mng.user_ref,
- (void *)sub,
- TIPC_HIGH_IMPORTANCE,
- 0,
- 0,
- (tipc_conn_shutdown_event)cfg_linksubscr_cancel,
- 0,
- 0,
- (tipc_conn_msg_event)cfg_linksubscr_cancel,
- 0,
- &sub->port_ref);
- if (!sub->port_ref) {
- kfree(sub);
- break;
- }
- memcpy(sub->usr_handle,msg->usr_handle,
- sizeof(sub->usr_handle));
- sub->domain = msg->argv.domain;
- list_add_tail(&sub->subd_list, &mng.link_subscribers);
- tipc_connect2port(sub->port_ref, orig);
- rmsg.retval = TIPC_OK;
- tipc_send(sub->port_ref, 2u, msg_sect);
- mng.link_subscriptions++;
- return;
- }
- default:
- rv = tipc_cfg_cmd(msg, data, sz, (u32 *)&msg_sect[1].iov_len, orig);
- }
-exit:
- rmsg.result_len = htonl(msg_sect[1].iov_len);
- rmsg.retval = htonl(rv);
- tipc_cfg_respond(msg_sect, 2u, orig);
-}
-#endif
-
#define MAX_STATS_INFO 2000
static struct sk_buff *tipc_show_stats(void)
@@ -557,14 +429,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
case TIPC_CMD_SHOW_PORTS:
rep_tlv_buf = tipc_port_get_ports();
break;
-#if 0
- case TIPC_CMD_SHOW_PORT_STATS:
- rep_tlv_buf = port_show_stats(req_tlv_area, req_tlv_space);
- break;
- case TIPC_CMD_RESET_PORT_STATS:
- rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED);
- break;
-#endif
case TIPC_CMD_SET_LOG_SIZE:
rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space);
break;
diff --git a/net/tipc/config.h b/net/tipc/config.h
index 5cd7cc56c54d..481e12ece715 100644
--- a/net/tipc/config.h
+++ b/net/tipc/config.h
@@ -45,7 +45,6 @@
struct sk_buff *tipc_cfg_reply_alloc(int payload_size);
int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
void *tlv_data, int tlv_data_size);
-struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value);
struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string);
static inline struct sk_buff *tipc_cfg_reply_none(void)
@@ -53,11 +52,6 @@ static inline struct sk_buff *tipc_cfg_reply_none(void)
return tipc_cfg_reply_alloc(0);
}
-static inline struct sk_buff *tipc_cfg_reply_unsigned(u32 value)
-{
- return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value);
-}
-
static inline struct sk_buff *tipc_cfg_reply_error_string(char *string)
{
return tipc_cfg_reply_string_type(TIPC_TLV_ERROR_STRING, string);
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 696468117985..e2a09eb8efd4 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -96,13 +96,8 @@ int tipc_net_id;
int tipc_remote_management;
-int tipc_get_mode(void)
-{
- return tipc_mode;
-}
-
/**
- * buf_acquire - creates a TIPC message buffer
+ * tipc_buf_acquire - creates a TIPC message buffer
* @size: message size (including TIPC header)
*
* Returns a new buffer with data pointers set to the specified size.
@@ -111,7 +106,7 @@ int tipc_get_mode(void)
* There may also be unrequested tailroom present at the buffer's end.
*/
-struct sk_buff *buf_acquire(u32 size)
+struct sk_buff *tipc_buf_acquire(u32 size)
{
struct sk_buff *skb;
unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
@@ -129,7 +124,7 @@ struct sk_buff *buf_acquire(u32 size)
* tipc_core_stop_net - shut down TIPC networking sub-systems
*/
-void tipc_core_stop_net(void)
+static void tipc_core_stop_net(void)
{
tipc_eth_media_stop();
tipc_net_stop();
@@ -154,7 +149,7 @@ int tipc_core_start_net(unsigned long addr)
* tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode
*/
-void tipc_core_stop(void)
+static void tipc_core_stop(void)
{
if (tipc_mode != TIPC_NODE_MODE)
return;
@@ -169,13 +164,14 @@ void tipc_core_stop(void)
tipc_nametbl_stop();
tipc_ref_table_stop();
tipc_socket_stop();
+ tipc_log_resize(0);
}
/**
* tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode
*/
-int tipc_core_start(void)
+static int tipc_core_start(void)
{
int res;
@@ -203,7 +199,9 @@ static int __init tipc_init(void)
{
int res;
- tipc_log_resize(CONFIG_TIPC_LOG);
+ 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");
@@ -230,7 +228,6 @@ static void __exit tipc_exit(void)
tipc_core_stop_net();
tipc_core_stop();
info("Deactivated\n");
- tipc_log_resize(0);
}
module_init(tipc_init);
@@ -244,8 +241,6 @@ MODULE_VERSION(TIPC_MOD_VER);
EXPORT_SYMBOL(tipc_attach);
EXPORT_SYMBOL(tipc_detach);
-EXPORT_SYMBOL(tipc_get_addr);
-EXPORT_SYMBOL(tipc_get_mode);
EXPORT_SYMBOL(tipc_createport);
EXPORT_SYMBOL(tipc_deleteport);
EXPORT_SYMBOL(tipc_ownidentity);
@@ -260,23 +255,10 @@ EXPORT_SYMBOL(tipc_withdraw);
EXPORT_SYMBOL(tipc_connect2port);
EXPORT_SYMBOL(tipc_disconnect);
EXPORT_SYMBOL(tipc_shutdown);
-EXPORT_SYMBOL(tipc_isconnected);
-EXPORT_SYMBOL(tipc_peer);
-EXPORT_SYMBOL(tipc_ref_valid);
EXPORT_SYMBOL(tipc_send);
-EXPORT_SYMBOL(tipc_send_buf);
EXPORT_SYMBOL(tipc_send2name);
-EXPORT_SYMBOL(tipc_forward2name);
-EXPORT_SYMBOL(tipc_send_buf2name);
-EXPORT_SYMBOL(tipc_forward_buf2name);
EXPORT_SYMBOL(tipc_send2port);
-EXPORT_SYMBOL(tipc_forward2port);
-EXPORT_SYMBOL(tipc_send_buf2port);
-EXPORT_SYMBOL(tipc_forward_buf2port);
EXPORT_SYMBOL(tipc_multicast);
-/* EXPORT_SYMBOL(tipc_multicast_buf); not available yet */
-EXPORT_SYMBOL(tipc_ispublished);
-EXPORT_SYMBOL(tipc_available_nodes);
/* TIPC API for external bearers (see tipc_bearer.h) */
@@ -293,6 +275,4 @@ EXPORT_SYMBOL(tipc_createport_raw);
EXPORT_SYMBOL(tipc_reject_msg);
EXPORT_SYMBOL(tipc_send_buf_fast);
EXPORT_SYMBOL(tipc_acknowledge);
-EXPORT_SYMBOL(tipc_get_port);
-EXPORT_SYMBOL(tipc_get_handle);
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 188799017abd..e19389e57227 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -83,9 +83,7 @@
* Note: TIPC_LOG is configured to echo its output to the system console;
* user-defined buffers can be configured to do the same thing.
*/
-
extern struct print_buf *const TIPC_NULL;
-extern struct print_buf *const TIPC_CONS;
extern struct print_buf *const TIPC_LOG;
void tipc_printf(struct print_buf *, const char *fmt, ...);
@@ -204,10 +202,7 @@ extern atomic_t tipc_user_count;
* Routines available to privileged subsystems
*/
-extern int tipc_core_start(void);
-extern void tipc_core_stop(void);
-extern int tipc_core_start_net(unsigned long addr);
-extern void tipc_core_stop_net(void);
+extern int tipc_core_start_net(unsigned long);
extern int tipc_handler_start(void);
extern void tipc_handler_stop(void);
extern int tipc_netlink_start(void);
@@ -328,7 +323,7 @@ static inline struct tipc_msg *buf_msg(struct sk_buff *skb)
return (struct tipc_msg *)skb->data;
}
-extern struct sk_buff *buf_acquire(u32 size);
+extern struct sk_buff *tipc_buf_acquire(u32 size);
/**
* buf_discard - frees a TIPC message buffer
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c
index 1885a7edb0c8..46f51d208e5e 100644
--- a/net/tipc/dbg.c
+++ b/net/tipc/dbg.c
@@ -52,7 +52,7 @@ static struct print_buf null_buf = { NULL, 0, NULL, 0 };
struct print_buf *const TIPC_NULL = &null_buf;
static struct print_buf cons_buf = { NULL, 0, NULL, 1 };
-struct print_buf *const TIPC_CONS = &cons_buf;
+static struct print_buf *const TIPC_CONS = &cons_buf;
static struct print_buf log_buf = { NULL, 0, NULL, 1 };
struct print_buf *const TIPC_LOG = &log_buf;
@@ -76,6 +76,10 @@ struct print_buf *const TIPC_LOG = &log_buf;
static char print_string[TIPC_PB_MAX_STR];
static DEFINE_SPINLOCK(print_lock);
+static void tipc_printbuf_reset(struct print_buf *pb);
+static int tipc_printbuf_empty(struct print_buf *pb);
+static void tipc_printbuf_move(struct print_buf *pb_to,
+ struct print_buf *pb_from);
#define FORMAT(PTR,LEN,FMT) \
{\
@@ -116,7 +120,7 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
* @pb: pointer to print buffer structure
*/
-void tipc_printbuf_reset(struct print_buf *pb)
+static void tipc_printbuf_reset(struct print_buf *pb)
{
if (pb->buf) {
pb->crs = pb->buf;
@@ -132,9 +136,9 @@ void tipc_printbuf_reset(struct print_buf *pb)
* Returns non-zero if print buffer is empty.
*/
-int tipc_printbuf_empty(struct print_buf *pb)
+static int tipc_printbuf_empty(struct print_buf *pb)
{
- return (!pb->buf || (pb->crs == pb->buf));
+ return !pb->buf || (pb->crs == pb->buf);
}
/**
@@ -169,7 +173,7 @@ int tipc_printbuf_validate(struct print_buf *pb)
tipc_printf(pb, err);
}
}
- return (pb->crs - pb->buf + 1);
+ return pb->crs - pb->buf + 1;
}
/**
@@ -181,7 +185,8 @@ int tipc_printbuf_validate(struct print_buf *pb)
* Source print buffer becomes empty if a successful move occurs.
*/
-void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
+static void tipc_printbuf_move(struct print_buf *pb_to,
+ struct print_buf *pb_from)
{
int len;
diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h
index 5ef1bc8f64ef..3ba6ba8b434a 100644
--- a/net/tipc/dbg.h
+++ b/net/tipc/dbg.h
@@ -56,10 +56,7 @@ struct print_buf {
#define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */
void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size);
-void tipc_printbuf_reset(struct print_buf *pb);
-int tipc_printbuf_empty(struct print_buf *pb);
int tipc_printbuf_validate(struct print_buf *pb);
-void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from);
int tipc_log_resize(int log_size);
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index fc1fcf5e6b53..4a7cd3719b78 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -46,16 +46,6 @@
#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 */
-#if 0
-#define GET_NODE_INFO 300
-#define GET_NODE_INFO_RESULT 301
-#define FORWARD_LINK_PROBE 302
-#define LINK_REQUEST_REJECTED 303
-#define LINK_REQUEST_ACCEPTED 304
-#define DROP_LINK_REQUEST 305
-#define CHECK_LINK_COUNT 306
-#endif
-
/*
* TODO: Most of the inter-cluster setup stuff should be
* rewritten, and be made conformant with specification.
@@ -78,30 +68,6 @@ struct link_req {
unsigned int timer_intv;
};
-
-#if 0
-int disc_create_link(const struct tipc_link_create *argv)
-{
- /*
- * Code for inter cluster link setup here
- */
- return TIPC_OK;
-}
-#endif
-
-/*
- * disc_lost_link(): A link has lost contact
- */
-
-void tipc_disc_link_event(u32 addr, char *name, int up)
-{
- if (in_own_cluster(addr))
- return;
- /*
- * Code for inter cluster link setup here
- */
-}
-
/**
* tipc_disc_init_msg - initialize a link setup message
* @type: message type (request or response)
@@ -115,7 +81,7 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
u32 dest_domain,
struct bearer *b_ptr)
{
- struct sk_buff *buf = buf_acquire(DSC_H_SIZE);
+ struct sk_buff *buf = tipc_buf_acquire(DSC_H_SIZE);
struct tipc_msg *msg;
if (buf) {
@@ -203,6 +169,14 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
return;
}
spin_lock_bh(&n_ptr->lock);
+
+ /* Don't talk to neighbor during cleanup after last session */
+
+ if (n_ptr->cleanup_required) {
+ spin_unlock_bh(&n_ptr->lock);
+ return;
+ }
+
link = n_ptr->links[b_ptr->identity];
if (!link) {
dbg("creating link\n");
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index c36eaeb7d5d0..f8e750636123 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -50,9 +50,4 @@ void tipc_disc_stop_link_req(struct link_req *req);
void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr);
-void tipc_disc_link_event(u32 addr, char *name, int up);
-#if 0
-int disc_create_link(const struct tipc_link_create *argv);
-#endif
-
#endif
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 6230d16020c4..6e988ba485fd 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -72,17 +72,26 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
{
struct sk_buff *clone;
struct net_device *dev;
+ int delta;
clone = skb_clone(buf, GFP_ATOMIC);
- if (clone) {
- skb_reset_network_header(clone);
- dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev;
- clone->dev = dev;
- dev_hard_header(clone, dev, ETH_P_TIPC,
- &dest->dev_addr.eth_addr,
- dev->dev_addr, clone->len);
- dev_queue_xmit(clone);
+ if (!clone)
+ return 0;
+
+ dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev;
+ delta = dev->hard_header_len - skb_headroom(buf);
+
+ if ((delta > 0) &&
+ pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) {
+ kfree_skb(clone);
+ return 0;
}
+
+ skb_reset_network_header(clone);
+ clone->dev = dev;
+ dev_hard_header(clone, dev, ETH_P_TIPC, &dest->dev_addr.eth_addr,
+ dev->dev_addr, clone->len);
+ dev_queue_xmit(clone);
return 0;
}
@@ -92,15 +101,12 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
* Accept only packets explicitly sent to this node, or broadcast packets;
* ignores packets sent using Ethernet multicast, and traffic sent to other
* nodes (which can happen if interface is running in promiscuous mode).
- * Routine truncates any Ethernet padding/CRC appended to the message,
- * and ensures message size matches actual length
*/
static int recv_msg(struct sk_buff *buf, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv;
- u32 size;
if (!net_eq(dev_net(dev), &init_net)) {
kfree_skb(buf);
@@ -109,13 +115,9 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
if (likely(eb_ptr->bearer)) {
if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
- size = msg_size((struct tipc_msg *)buf->data);
- skb_trim(buf, size);
- if (likely(buf->len == size)) {
- buf->next = NULL;
- tipc_recv_msg(buf, eb_ptr->bearer);
- return 0;
- }
+ buf->next = NULL;
+ tipc_recv_msg(buf, eb_ptr->bearer);
+ return 0;
}
}
kfree_skb(buf);
@@ -133,6 +135,16 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
struct eth_bearer *eb_ptr = &eth_bearers[0];
struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
+ int pending_dev = 0;
+
+ /* Find unused Ethernet bearer structure */
+
+ while (eb_ptr->dev) {
+ if (!eb_ptr->bearer)
+ pending_dev++;
+ if (++eb_ptr == stop)
+ return pending_dev ? -EAGAIN : -EDQUOT;
+ }
/* Find device with specified name */
diff --git a/net/tipc/link.c b/net/tipc/link.c
index a3616b99529b..b31992ccd5d3 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -99,23 +99,6 @@ struct link_name {
char if_peer[TIPC_MAX_IF_NAME];
};
-#if 0
-
-/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */
-
-/**
- * struct link_event - link up/down event notification
- */
-
-struct link_event {
- u32 addr;
- int up;
- void (*fcn)(u32, char *, int);
- char name[TIPC_MAX_LINK_NAME];
-};
-
-#endif
-
static void link_handle_out_of_seq_msg(struct link *l_ptr,
struct sk_buff *buf);
static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf);
@@ -129,6 +112,9 @@ static void link_state_event(struct link *l_ptr, u32 event);
static void link_reset_statistics(struct link *l_ptr);
static void link_print(struct link *l_ptr, struct print_buf *buf,
const char *str);
+static void link_start(struct link *l_ptr);
+static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf);
+
/*
* Debugging code used by link routines only
@@ -239,13 +225,13 @@ int tipc_link_is_up(struct link *l_ptr)
{
if (!l_ptr)
return 0;
- return (link_working_working(l_ptr) || link_working_unknown(l_ptr));
+ return link_working_working(l_ptr) || link_working_unknown(l_ptr);
}
int tipc_link_is_active(struct link *l_ptr)
{
- return ((l_ptr->owner->active_links[0] == l_ptr) ||
- (l_ptr->owner->active_links[1] == l_ptr));
+ return (l_ptr->owner->active_links[0] == l_ptr) ||
+ (l_ptr->owner->active_links[1] == l_ptr);
}
/**
@@ -459,7 +445,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr);
list_add_tail(&l_ptr->link_list, &b_ptr->links);
- tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr);
+ tipc_k_signal((Handler)link_start, (unsigned long)l_ptr);
dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n",
l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit);
@@ -499,9 +485,9 @@ void tipc_link_delete(struct link *l_ptr)
kfree(l_ptr);
}
-void tipc_link_start(struct link *l_ptr)
+static void link_start(struct link *l_ptr)
{
- dbg("tipc_link_start %x\n", l_ptr);
+ dbg("link_start %x\n", l_ptr);
link_state_event(l_ptr, STARTING_EVT);
}
@@ -634,39 +620,9 @@ void tipc_link_stop(struct link *l_ptr)
l_ptr->proto_msg_queue = NULL;
}
-#if 0
-
/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */
-
-static void link_recv_event(struct link_event *ev)
-{
- ev->fcn(ev->addr, ev->name, ev->up);
- kfree(ev);
-}
-
-static void link_send_event(void (*fcn)(u32 a, char *n, int up),
- struct link *l_ptr, int up)
-{
- struct link_event *ev;
-
- ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
- if (!ev) {
- warn("Link event allocation failure\n");
- return;
- }
- ev->addr = l_ptr->addr;
- ev->up = up;
- ev->fcn = fcn;
- memcpy(ev->name, l_ptr->name, TIPC_MAX_LINK_NAME);
- tipc_k_signal((Handler)link_recv_event, (unsigned long)ev);
-}
-
-#else
-
#define link_send_event(fcn, l_ptr, up) do { } while (0)
-#endif
-
void tipc_link_reset(struct link *l_ptr)
{
struct sk_buff *buf;
@@ -690,10 +646,7 @@ void tipc_link_reset(struct link *l_ptr)
tipc_node_link_down(l_ptr->owner, l_ptr);
tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
-#if 0
- tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name);
- dbg_link_dump();
-#endif
+
if (was_active_link && tipc_node_has_active_links(l_ptr->owner) &&
l_ptr->owner->permit_changeover) {
l_ptr->reset_checkpoint = checkpoint;
@@ -1050,7 +1003,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
/* Fragmentation needed ? */
if (size > max_packet)
- return tipc_link_send_long_buf(l_ptr, buf);
+ return link_send_long_buf(l_ptr, buf);
/* Packet can be queued or sent: */
@@ -1086,7 +1039,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
/* Try creating a new bundle */
if (size <= max_packet * 2 / 3) {
- struct sk_buff *bundler = buf_acquire(max_packet);
+ struct sk_buff *bundler = tipc_buf_acquire(max_packet);
struct tipc_msg bundler_hdr;
if (bundler) {
@@ -1362,7 +1315,7 @@ again:
/* Prepare header of first fragment: */
- buf_chain = buf = buf_acquire(max_pkt);
+ buf_chain = buf = tipc_buf_acquire(max_pkt);
if (!buf)
return -ENOMEM;
buf->next = NULL;
@@ -1419,7 +1372,7 @@ error:
msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE);
msg_set_fragm_no(&fragm_hdr, ++fragm_no);
prev = buf;
- buf = buf_acquire(fragm_sz + INT_H_SIZE);
+ buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
if (!buf)
goto error;
@@ -1802,6 +1755,15 @@ static int link_recv_buf_validate(struct sk_buff *buf)
return pskb_may_pull(buf, hdr_size);
}
+/**
+ * tipc_recv_msg - process TIPC messages arriving from off-node
+ * @head: pointer to message buffer chain
+ * @tb_ptr: pointer to bearer message arrived on
+ *
+ * Invoked with no locks held. Bearer pointer must point to a valid bearer
+ * structure (i.e. cannot be NULL), but bearer can be inactive.
+ */
+
void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
{
read_lock_bh(&tipc_net_lock);
@@ -1819,6 +1781,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
head = head->next;
+ /* Ensure bearer is still enabled */
+
+ if (unlikely(!b_ptr->active))
+ goto cont;
+
/* Ensure message is well-formed */
if (unlikely(!link_recv_buf_validate(buf)))
@@ -1855,13 +1822,22 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
goto cont;
}
- /* Locate unicast link endpoint that should handle message */
+ /* Locate neighboring node that sent message */
n_ptr = tipc_node_find(msg_prevnode(msg));
if (unlikely(!n_ptr))
goto cont;
tipc_node_lock(n_ptr);
+ /* Don't talk to neighbor during cleanup after last session */
+
+ if (n_ptr->cleanup_required) {
+ tipc_node_unlock(n_ptr);
+ goto cont;
+ }
+
+ /* Locate unicast link endpoint that should handle message */
+
l_ptr = n_ptr->links[b_ptr->identity];
if (unlikely(!l_ptr)) {
tipc_node_unlock(n_ptr);
@@ -2172,7 +2148,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
if (!l_ptr->proto_msg_queue) {
l_ptr->proto_msg_queue =
- buf_acquire(sizeof(l_ptr->proto_msg));
+ tipc_buf_acquire(sizeof(l_ptr->proto_msg));
}
buf = l_ptr->proto_msg_queue;
if (!buf)
@@ -2186,7 +2162,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
msg_dbg(msg, ">>");
- buf = buf_acquire(msg_size);
+ buf = tipc_buf_acquire(msg_size);
if (!buf)
return;
@@ -2345,10 +2321,10 @@ exit:
* tipc_link_tunnel(): Send one message via a link belonging to
* another bearer. Owner node is locked.
*/
-void tipc_link_tunnel(struct link *l_ptr,
- struct tipc_msg *tunnel_hdr,
- struct tipc_msg *msg,
- u32 selector)
+static void tipc_link_tunnel(struct link *l_ptr,
+ struct tipc_msg *tunnel_hdr,
+ struct tipc_msg *msg,
+ u32 selector)
{
struct link *tunnel;
struct sk_buff *buf;
@@ -2361,7 +2337,7 @@ void tipc_link_tunnel(struct link *l_ptr,
return;
}
msg_set_size(tunnel_hdr, length + INT_H_SIZE);
- buf = buf_acquire(length + INT_H_SIZE);
+ buf = tipc_buf_acquire(length + INT_H_SIZE);
if (!buf) {
warn("Link changeover error, "
"unable to send tunnel msg\n");
@@ -2407,7 +2383,7 @@ void tipc_link_changeover(struct link *l_ptr)
if (!l_ptr->first_out) {
struct sk_buff *buf;
- buf = buf_acquire(INT_H_SIZE);
+ buf = tipc_buf_acquire(INT_H_SIZE);
if (buf) {
skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE);
msg_set_size(&tunnel_hdr, INT_H_SIZE);
@@ -2468,7 +2444,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
msg_set_size(&tunnel_hdr, length + INT_H_SIZE);
- outbuf = buf_acquire(length + INT_H_SIZE);
+ outbuf = tipc_buf_acquire(length + INT_H_SIZE);
if (outbuf == NULL) {
warn("Link changeover error, "
"unable to send duplicate msg\n");
@@ -2504,7 +2480,7 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos)
u32 size = msg_size(msg);
struct sk_buff *eb;
- eb = buf_acquire(size);
+ eb = tipc_buf_acquire(size);
if (eb)
skb_copy_to_linear_data(eb, msg, size);
return eb;
@@ -2632,11 +2608,11 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
/*
- * tipc_link_send_long_buf: Entry for buffers needing fragmentation.
+ * link_send_long_buf: Entry for buffers needing fragmentation.
* The buffer is complete, inclusive total message length.
* Returns user data length.
*/
-int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
+static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
{
struct tipc_msg *inmsg = buf_msg(buf);
struct tipc_msg fragm_hdr;
@@ -2675,7 +2651,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
fragm_sz = rest;
msg_set_type(&fragm_hdr, LAST_FRAGMENT);
}
- fragm = buf_acquire(fragm_sz + INT_H_SIZE);
+ fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
if (fragm == NULL) {
warn("Link unable to fragment message\n");
dsz = -ENOMEM;
@@ -2780,7 +2756,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
buf_discard(fbuf);
return 0;
}
- pbuf = buf_acquire(msg_size(imsg));
+ pbuf = tipc_buf_acquire(msg_size(imsg));
if (pbuf != NULL) {
pbuf->next = *pending;
*pending = pbuf;
@@ -3174,44 +3150,6 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s
return buf;
}
-#if 0
-int link_control(const char *name, u32 op, u32 val)
-{
- int res = -EINVAL;
- struct link *l_ptr;
- u32 bearer_id;
- struct tipc_node * node;
- u32 a;
-
- a = link_name2addr(name, &bearer_id);
- read_lock_bh(&tipc_net_lock);
- node = tipc_node_find(a);
- if (node) {
- tipc_node_lock(node);
- l_ptr = node->links[bearer_id];
- if (l_ptr) {
- if (op == TIPC_REMOVE_LINK) {
- struct bearer *b_ptr = l_ptr->b_ptr;
- spin_lock_bh(&b_ptr->publ.lock);
- tipc_link_delete(l_ptr);
- spin_unlock_bh(&b_ptr->publ.lock);
- }
- if (op == TIPC_CMD_BLOCK_LINK) {
- tipc_link_reset(l_ptr);
- l_ptr->blocked = 1;
- }
- if (op == TIPC_CMD_UNBLOCK_LINK) {
- l_ptr->blocked = 0;
- }
- res = 0;
- }
- tipc_node_unlock(node);
- }
- read_unlock_bh(&tipc_net_lock);
- return res;
-}
-#endif
-
/**
* tipc_link_get_max_pkt - get maximum packet size to use when sending to destination
* @dest: network address of destination node
@@ -3242,28 +3180,6 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
return res;
}
-#if 0
-static void link_dump_rec_queue(struct link *l_ptr)
-{
- struct sk_buff *crs;
-
- if (!l_ptr->oldest_deferred_in) {
- info("Reception queue empty\n");
- return;
- }
- info("Contents of Reception queue:\n");
- crs = l_ptr->oldest_deferred_in;
- while (crs) {
- if (crs->data == (void *)0x0000a3a3) {
- info("buffer %x invalid\n", crs);
- return;
- }
- msg_dbg(buf_msg(crs), "In rec queue:\n");
- crs = crs->next;
- }
-}
-#endif
-
static void link_dump_send_queue(struct link *l_ptr)
{
if (l_ptr->next_out) {
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 2e5385c47d30..f98bc613de67 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -210,10 +210,6 @@ struct link {
u32 msg_length_counts;
u32 msg_lengths_total;
u32 msg_length_profile[7];
-#if 0
- u32 sent_tunneled;
- u32 recv_tunneled;
-#endif
} stats;
struct print_buf print_buf;
@@ -229,7 +225,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *dest);
void tipc_link_reset_fragments(struct link *l_ptr);
int tipc_link_is_up(struct link *l_ptr);
int tipc_link_is_active(struct link *l_ptr);
-void tipc_link_start(struct link *l_ptr);
u32 tipc_link_push_packet(struct link *l_ptr);
void tipc_link_stop(struct link *l_ptr);
struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, u16 cmd);
@@ -243,9 +238,6 @@ int tipc_link_send_sections_fast(struct port* sender,
struct iovec const *msg_sect,
const u32 num_sect,
u32 destnode);
-int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf);
-void tipc_link_tunnel(struct link *l_ptr, struct tipc_msg *tnl_hdr,
- struct tipc_msg *msg, u32 selector);
void tipc_link_recv_bundle(struct sk_buff *buf);
int tipc_link_recv_fragment(struct sk_buff **pending,
struct sk_buff **fb,
@@ -279,12 +271,12 @@ static inline int between(u32 lower, u32 upper, u32 n)
static inline int less_eq(u32 left, u32 right)
{
- return (mod(right - left) < 32768u);
+ return mod(right - left) < 32768u;
}
static inline int less(u32 left, u32 right)
{
- return (less_eq(left, right) && (mod(right) != mod(left)));
+ return less_eq(left, right) && (mod(right) != mod(left));
}
static inline u32 lesser(u32 left, u32 right)
@@ -299,32 +291,32 @@ static inline u32 lesser(u32 left, u32 right)
static inline int link_working_working(struct link *l_ptr)
{
- return (l_ptr->state == WORKING_WORKING);
+ return l_ptr->state == WORKING_WORKING;
}
static inline int link_working_unknown(struct link *l_ptr)
{
- return (l_ptr->state == WORKING_UNKNOWN);
+ return l_ptr->state == WORKING_UNKNOWN;
}
static inline int link_reset_unknown(struct link *l_ptr)
{
- return (l_ptr->state == RESET_UNKNOWN);
+ return l_ptr->state == RESET_UNKNOWN;
}
static inline int link_reset_reset(struct link *l_ptr)
{
- return (l_ptr->state == RESET_RESET);
+ return l_ptr->state == RESET_RESET;
}
static inline int link_blocked(struct link *l_ptr)
{
- return (l_ptr->exp_msg_count || l_ptr->blocked);
+ return l_ptr->exp_msg_count || l_ptr->blocked;
}
static inline int link_congested(struct link *l_ptr)
{
- return (l_ptr->out_queue_size >= l_ptr->queue_limit[0]);
+ return l_ptr->out_queue_size >= l_ptr->queue_limit[0];
}
#endif
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 381063817b41..ecb532fb0351 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -112,7 +112,7 @@ int tipc_msg_build(struct tipc_msg *hdr,
return dsz;
}
- *buf = buf_acquire(sz);
+ *buf = tipc_buf_acquire(sz);
if (!(*buf))
return -ENOMEM;
skb_copy_to_linear_data(*buf, hdr, hsz);
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 995d2da35b01..031aad18efce 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -104,7 +104,7 @@ static inline u32 msg_user(struct tipc_msg *m)
static inline u32 msg_isdata(struct tipc_msg *m)
{
- return (msg_user(m) <= TIPC_CRITICAL_IMPORTANCE);
+ return msg_user(m) <= TIPC_CRITICAL_IMPORTANCE;
}
static inline void msg_set_user(struct tipc_msg *m, u32 n)
@@ -289,7 +289,7 @@ static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
static inline int msg_is_dest(struct tipc_msg *m, u32 d)
{
- return(msg_short(m) || (msg_destnode(m) == d));
+ return msg_short(m) || (msg_destnode(m) == d);
}
static inline u32 msg_routed(struct tipc_msg *m)
@@ -632,7 +632,7 @@ static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n)
static inline u32 msg_max_pkt(struct tipc_msg *m)
{
- return (msg_bits(m, 9, 16, 0xffff) * 4);
+ return msg_bits(m, 9, 16, 0xffff) * 4;
}
static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n)
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 6ac3c543250b..7b907171f879 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -98,7 +98,7 @@ static void publ_to_item(struct distr_item *i, struct publication *p)
static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
{
- struct sk_buff *buf = buf_acquire(LONG_H_SIZE + size);
+ struct sk_buff *buf = tipc_buf_acquire(LONG_H_SIZE + size);
struct tipc_msg *msg;
if (buf != NULL) {
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 8ba79620db3f..3a8de4334da1 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -116,7 +116,7 @@ DEFINE_RWLOCK(tipc_nametbl_lock);
static int hash(int x)
{
- return(x & (tipc_nametbl_size - 1));
+ return x & (tipc_nametbl_size - 1);
}
/**
@@ -613,8 +613,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
}
/*
- * tipc_nametbl_translate(): Translate tipc_name -> tipc_portid.
- * Very time-critical.
+ * tipc_nametbl_translate - translate name to port id
*
* Note: on entry 'destnode' is the search domain used during translation;
* on exit it passes back the node address of the matching port (if any)
@@ -685,7 +684,6 @@ found:
}
spin_unlock_bh(&seq->lock);
not_found:
- *destnode = 0;
read_unlock_bh(&tipc_nametbl_lock);
return 0;
}
@@ -877,7 +875,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
u32 index)
{
char portIdStr[27];
- char *scopeStr;
+ const char *scope_str[] = {"", " zone", " cluster", " node"};
struct publication *publ = sseq->zone_list;
tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper);
@@ -893,15 +891,8 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
tipc_node(publ->node), publ->ref);
tipc_printf(buf, "%-26s ", portIdStr);
if (depth > 3) {
- if (publ->node != tipc_own_addr)
- scopeStr = "";
- else if (publ->scope == TIPC_NODE_SCOPE)
- scopeStr = "node";
- else if (publ->scope == TIPC_CLUSTER_SCOPE)
- scopeStr = "cluster";
- else
- scopeStr = "zone";
- tipc_printf(buf, "%-10u %s", publ->key, scopeStr);
+ tipc_printf(buf, "%-10u %s", publ->key,
+ scope_str[publ->scope]);
}
publ = publ->zone_list_next;
@@ -951,24 +942,19 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth,
static void nametbl_header(struct print_buf *buf, u32 depth)
{
- tipc_printf(buf, "Type ");
-
- if (depth > 1)
- tipc_printf(buf, "Lower Upper ");
- if (depth > 2)
- tipc_printf(buf, "Port Identity ");
- if (depth > 3)
- tipc_printf(buf, "Publication");
-
- tipc_printf(buf, "\n-----------");
-
- if (depth > 1)
- tipc_printf(buf, "--------------------- ");
- if (depth > 2)
- tipc_printf(buf, "-------------------------- ");
- if (depth > 3)
- tipc_printf(buf, "------------------");
-
+ const char *header[] = {
+ "Type ",
+ "Lower Upper ",
+ "Port Identity ",
+ "Publication Scope"
+ };
+
+ int i;
+
+ if (depth > 4)
+ depth = 4;
+ for (i = 0; i < depth; i++)
+ tipc_printf(buf, header[i]);
tipc_printf(buf, "\n");
}
@@ -1023,16 +1009,6 @@ static void nametbl_list(struct print_buf *buf, u32 depth_info,
}
}
-#if 0
-void tipc_nametbl_print(struct print_buf *buf, const char *str)
-{
- tipc_printf(buf, str);
- read_lock_bh(&tipc_nametbl_lock);
- nametbl_list(buf, 0, 0, 0, 0);
- read_unlock_bh(&tipc_nametbl_lock);
-}
-#endif
-
#define MAX_NAME_TBL_QUERY 32768
struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space)
@@ -1065,13 +1041,6 @@ struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space)
return buf;
}
-#if 0
-void tipc_nametbl_dump(void)
-{
- nametbl_list(TIPC_CONS, 0, 0, 0, 0);
-}
-#endif
-
int tipc_nametbl_init(void)
{
table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head),
diff --git a/net/tipc/net.c b/net/tipc/net.c
index f61b7694138b..1a621cfd6604 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -129,15 +129,6 @@ u32 tipc_net_select_router(u32 addr, u32 ref)
return tipc_zone_select_router(tipc_net.zones[tipc_zone(addr)], addr, ref);
}
-#if 0
-u32 tipc_net_next_node(u32 a)
-{
- if (tipc_net.zones[tipc_zone(a)])
- return tipc_zone_next_node(a);
- return 0;
-}
-#endif
-
void tipc_net_remove_as_router(u32 router)
{
u32 z_num;
@@ -248,6 +239,7 @@ void tipc_net_route_msg(struct sk_buff *buf)
/* Handle message for another node */
msg_dbg(msg, "NET>SEND>: ");
+ skb_trim(buf, msg_size(msg));
tipc_link_send(buf, dnode, msg_link_selector(msg));
}
diff --git a/net/tipc/node.c b/net/tipc/node.c
index b634942caba5..b4d87eb2dc5d 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -50,7 +50,8 @@ void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str);
static void node_lost_contact(struct tipc_node *n_ptr);
static void node_established_contact(struct tipc_node *n_ptr);
-struct tipc_node *tipc_nodes = NULL; /* sorted list of nodes within cluster */
+/* sorted list of nodes within cluster */
+static struct tipc_node *tipc_nodes = NULL;
static DEFINE_SPINLOCK(node_create_lock);
@@ -125,16 +126,6 @@ void tipc_node_delete(struct tipc_node *n_ptr)
if (!n_ptr)
return;
-#if 0
- /* Not needed because links are already deleted via tipc_bearer_stop() */
-
- u32 l_num;
-
- for (l_num = 0; l_num < MAX_BEARERS; l_num++) {
- link_delete(n_ptr->links[l_num]);
- }
-#endif
-
dbg("node %x deleted\n", n_ptr->addr);
kfree(n_ptr);
}
@@ -237,23 +228,22 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr)
int tipc_node_has_active_links(struct tipc_node *n_ptr)
{
- return (n_ptr &&
- ((n_ptr->active_links[0]) || (n_ptr->active_links[1])));
+ return n_ptr->active_links[0] != NULL;
}
int tipc_node_has_redundant_links(struct tipc_node *n_ptr)
{
- return (n_ptr->working_links > 1);
+ return n_ptr->working_links > 1;
}
static int tipc_node_has_active_routes(struct tipc_node *n_ptr)
{
- return (n_ptr && (n_ptr->last_router >= 0));
+ return n_ptr && (n_ptr->last_router >= 0);
}
int tipc_node_is_up(struct tipc_node *n_ptr)
{
- return (tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr));
+ return tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr);
}
struct tipc_node *tipc_node_attach_link(struct link *l_ptr)
@@ -384,6 +374,20 @@ static void node_established_contact(struct tipc_node *n_ptr)
tipc_highest_allowed_slave);
}
+static void node_cleanup_finished(unsigned long node_addr)
+{
+ struct tipc_node *n_ptr;
+
+ read_lock_bh(&tipc_net_lock);
+ n_ptr = tipc_node_find(node_addr);
+ if (n_ptr) {
+ tipc_node_lock(n_ptr);
+ n_ptr->cleanup_required = 0;
+ tipc_node_unlock(n_ptr);
+ }
+ read_unlock_bh(&tipc_net_lock);
+}
+
static void node_lost_contact(struct tipc_node *n_ptr)
{
struct cluster *c_ptr;
@@ -458,6 +462,11 @@ static void node_lost_contact(struct tipc_node *n_ptr)
tipc_k_signal((Handler)ns->handle_node_down,
(unsigned long)ns->usr_handle);
}
+
+ /* Prevent re-contact with node until all cleanup is done */
+
+ n_ptr->cleanup_required = 1;
+ tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr);
}
/**
@@ -579,38 +588,6 @@ void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router)
node_lost_contact(n_ptr);
}
-#if 0
-void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str)
-{
- u32 i;
-
- tipc_printf(buf, "\n\n%s", str);
- for (i = 0; i < MAX_BEARERS; i++) {
- if (!n_ptr->links[i])
- continue;
- tipc_printf(buf, "Links[%u]: %x, ", i, n_ptr->links[i]);
- }
- tipc_printf(buf, "Active links: [%x,%x]\n",
- n_ptr->active_links[0], n_ptr->active_links[1]);
-}
-#endif
-
-u32 tipc_available_nodes(const u32 domain)
-{
- struct tipc_node *n_ptr;
- u32 cnt = 0;
-
- read_lock_bh(&tipc_net_lock);
- for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
- if (!tipc_in_scope(domain, n_ptr->addr))
- continue;
- if (tipc_node_is_up(n_ptr))
- cnt++;
- }
- read_unlock_bh(&tipc_net_lock);
- return cnt;
-}
-
struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
{
u32 domain;
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 6f990da5d143..fff331b2d26c 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -52,6 +52,7 @@
* @active_links: pointers to active links to node
* @links: pointers to all links to node
* @working_links: number of working links to node (both active and standby)
+ * @cleanup_required: non-zero if cleaning up after a prior loss of contact
* @link_cnt: number of links to node
* @permit_changeover: non-zero if node has redundant links to this system
* @routers: bitmap (used for multicluster communication)
@@ -78,6 +79,7 @@ struct tipc_node {
struct link *links[MAX_BEARERS];
int link_cnt;
int working_links;
+ int cleanup_required;
int permit_changeover;
u32 routers[512/32];
int last_router;
@@ -94,7 +96,6 @@ struct tipc_node {
} bclink;
};
-extern struct tipc_node *tipc_nodes;
extern u32 tipc_own_tag;
struct tipc_node *tipc_node_create(u32 addr);
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 0737680e9266..82092eaa1536 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -293,34 +293,6 @@ int tipc_deleteport(u32 ref)
return 0;
}
-/**
- * tipc_get_port() - return port associated with 'ref'
- *
- * Note: Port is not locked.
- */
-
-struct tipc_port *tipc_get_port(const u32 ref)
-{
- return (struct tipc_port *)tipc_ref_deref(ref);
-}
-
-/**
- * tipc_get_handle - return user handle associated to port 'ref'
- */
-
-void *tipc_get_handle(const u32 ref)
-{
- struct port *p_ptr;
- void * handle;
-
- p_ptr = tipc_port_lock(ref);
- if (!p_ptr)
- return NULL;
- handle = p_ptr->publ.usr_handle;
- tipc_port_unlock(p_ptr);
- return handle;
-}
-
static int port_unreliable(struct port *p_ptr)
{
return msg_src_droppable(&p_ptr->publ.phdr);
@@ -392,7 +364,7 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
struct sk_buff *buf;
struct tipc_msg *msg;
- buf = buf_acquire(LONG_H_SIZE);
+ buf = tipc_buf_acquire(LONG_H_SIZE);
if (buf) {
msg = buf_msg(buf);
tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode);
@@ -433,7 +405,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
hdr_sz = MCAST_H_SIZE;
else
hdr_sz = LONG_H_SIZE;
- rbuf = buf_acquire(data_sz + hdr_sz);
+ rbuf = tipc_buf_acquire(data_sz + hdr_sz);
if (rbuf == NULL) {
buf_discard(buf);
return data_sz;
@@ -588,19 +560,10 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
if (!p_ptr) {
err = TIPC_ERR_NO_PORT;
} else if (p_ptr->publ.connected) {
- if (port_peernode(p_ptr) != msg_orignode(msg))
+ if ((port_peernode(p_ptr) != msg_orignode(msg)) ||
+ (port_peerport(p_ptr) != msg_origport(msg))) {
err = TIPC_ERR_NO_PORT;
- if (port_peerport(p_ptr) != msg_origport(msg))
- err = TIPC_ERR_NO_PORT;
- if (!err && msg_routed(msg)) {
- u32 seqno = msg_transp_seqno(msg);
- u32 myno = ++p_ptr->last_in_seqno;
- if (seqno != myno) {
- err = TIPC_ERR_NO_PORT;
- abort_buf = port_build_self_abort_msg(p_ptr, err);
- }
- }
- if (msg_type(msg) == CONN_ACK) {
+ } else if (msg_type(msg) == CONN_ACK) {
int wakeup = tipc_port_congested(p_ptr) &&
p_ptr->publ.congested &&
p_ptr->wakeup;
@@ -719,50 +682,6 @@ struct sk_buff *tipc_port_get_ports(void)
return buf;
}
-#if 0
-
-#define MAX_PORT_STATS 2000
-
-struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space)
-{
- u32 ref;
- struct port *p_ptr;
- struct sk_buff *buf;
- struct tlv_desc *rep_tlv;
- struct print_buf pb;
- int str_len;
-
- if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_PORT_REF))
- return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
-
- ref = *(u32 *)TLV_DATA(req_tlv_area);
- ref = ntohl(ref);
-
- p_ptr = tipc_port_lock(ref);
- if (!p_ptr)
- return cfg_reply_error_string("port not found");
-
- buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_STATS));
- if (!buf) {
- tipc_port_unlock(p_ptr);
- return NULL;
- }
- rep_tlv = (struct tlv_desc *)buf->data;
-
- tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_STATS);
- port_print(p_ptr, &pb, 1);
- /* NEED TO FILL IN ADDITIONAL PORT STATISTICS HERE */
- tipc_port_unlock(p_ptr);
- str_len = tipc_printbuf_validate(&pb);
-
- skb_put(buf, TLV_SPACE(str_len));
- TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
-
- return buf;
-}
-
-#endif
-
void tipc_port_reinit(void)
{
struct port *p_ptr;
@@ -1295,50 +1214,13 @@ int tipc_shutdown(u32 ref)
return tipc_disconnect(ref);
}
-int tipc_isconnected(u32 ref, int *isconnected)
-{
- struct port *p_ptr;
-
- p_ptr = tipc_port_lock(ref);
- if (!p_ptr)
- return -EINVAL;
- *isconnected = p_ptr->publ.connected;
- tipc_port_unlock(p_ptr);
- return 0;
-}
-
-int tipc_peer(u32 ref, struct tipc_portid *peer)
-{
- struct port *p_ptr;
- int res;
-
- p_ptr = tipc_port_lock(ref);
- if (!p_ptr)
- return -EINVAL;
- if (p_ptr->publ.connected) {
- peer->ref = port_peerport(p_ptr);
- peer->node = port_peernode(p_ptr);
- res = 0;
- } else
- res = -ENOTCONN;
- tipc_port_unlock(p_ptr);
- return res;
-}
-
-int tipc_ref_valid(u32 ref)
-{
- /* Works irrespective of type */
- return !!tipc_ref_deref(ref);
-}
-
-
/*
* tipc_port_recv_sections(): Concatenate and deliver sectioned
* message for this node.
*/
-int tipc_port_recv_sections(struct port *sender, unsigned int num_sect,
- struct iovec const *msg_sect)
+static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect,
+ struct iovec const *msg_sect)
{
struct sk_buff *buf;
int res;
@@ -1389,65 +1271,16 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
}
/**
- * tipc_send_buf - send message buffer on connection
- */
-
-int tipc_send_buf(u32 ref, struct sk_buff *buf, unsigned int dsz)
-{
- struct port *p_ptr;
- struct tipc_msg *msg;
- u32 destnode;
- u32 hsz;
- u32 sz;
- u32 res;
-
- p_ptr = tipc_port_deref(ref);
- if (!p_ptr || !p_ptr->publ.connected)
- return -EINVAL;
-
- msg = &p_ptr->publ.phdr;
- hsz = msg_hdr_sz(msg);
- sz = hsz + dsz;
- msg_set_size(msg, sz);
- if (skb_cow(buf, hsz))
- return -ENOMEM;
-
- skb_push(buf, hsz);
- skb_copy_to_linear_data(buf, msg, hsz);
- destnode = msg_destnode(msg);
- p_ptr->publ.congested = 1;
- if (!tipc_port_congested(p_ptr)) {
- if (likely(destnode != tipc_own_addr))
- res = tipc_send_buf_fast(buf, destnode);
- else {
- tipc_port_recv_msg(buf);
- res = sz;
- }
- if (likely(res != -ELINKCONG)) {
- port_incr_out_seqno(p_ptr);
- p_ptr->sent++;
- p_ptr->publ.congested = 0;
- return res;
- }
- }
- if (port_unreliable(p_ptr)) {
- p_ptr->publ.congested = 0;
- return dsz;
- }
- return -ELINKCONG;
-}
-
-/**
* tipc_forward2name - forward message sections to port name
*/
-int tipc_forward2name(u32 ref,
- struct tipc_name const *name,
- u32 domain,
- u32 num_sect,
- struct iovec const *msg_sect,
- struct tipc_portid const *orig,
- unsigned int importance)
+static int tipc_forward2name(u32 ref,
+ struct tipc_name const *name,
+ u32 domain,
+ u32 num_sect,
+ struct iovec const *msg_sect,
+ struct tipc_portid const *orig,
+ unsigned int importance)
{
struct port *p_ptr;
struct tipc_msg *msg;
@@ -1473,7 +1306,7 @@ int tipc_forward2name(u32 ref,
msg_set_destnode(msg, destnode);
msg_set_destport(msg, destport);
- if (likely(destport || destnode)) {
+ if (likely(destport)) {
p_ptr->sent++;
if (likely(destnode == tipc_own_addr))
return tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
@@ -1510,89 +1343,15 @@ int tipc_send2name(u32 ref,
}
/**
- * tipc_forward_buf2name - forward message buffer to port name
- */
-
-int tipc_forward_buf2name(u32 ref,
- struct tipc_name const *name,
- u32 domain,
- struct sk_buff *buf,
- unsigned int dsz,
- struct tipc_portid const *orig,
- unsigned int importance)
-{
- struct port *p_ptr;
- struct tipc_msg *msg;
- u32 destnode = domain;
- u32 destport;
- int res;
-
- p_ptr = (struct port *)tipc_ref_deref(ref);
- if (!p_ptr || p_ptr->publ.connected)
- return -EINVAL;
-
- msg = &p_ptr->publ.phdr;
- if (importance <= TIPC_CRITICAL_IMPORTANCE)
- msg_set_importance(msg, importance);
- msg_set_type(msg, TIPC_NAMED_MSG);
- msg_set_orignode(msg, orig->node);
- msg_set_origport(msg, orig->ref);
- msg_set_nametype(msg, name->type);
- msg_set_nameinst(msg, name->instance);
- msg_set_lookup_scope(msg, tipc_addr_scope(domain));
- msg_set_hdr_sz(msg, LONG_H_SIZE);
- msg_set_size(msg, LONG_H_SIZE + dsz);
- destport = tipc_nametbl_translate(name->type, name->instance, &destnode);
- msg_set_destnode(msg, destnode);
- msg_set_destport(msg, destport);
- msg_dbg(msg, "forw2name ==> ");
- if (skb_cow(buf, LONG_H_SIZE))
- return -ENOMEM;
- skb_push(buf, LONG_H_SIZE);
- skb_copy_to_linear_data(buf, msg, LONG_H_SIZE);
- msg_dbg(buf_msg(buf),"PREP:");
- if (likely(destport || destnode)) {
- p_ptr->sent++;
- if (destnode == tipc_own_addr)
- return tipc_port_recv_msg(buf);
- res = tipc_send_buf_fast(buf, destnode);
- if (likely(res != -ELINKCONG))
- return res;
- if (port_unreliable(p_ptr))
- return dsz;
- return -ELINKCONG;
- }
- return tipc_reject_msg(buf, TIPC_ERR_NO_NAME);
-}
-
-/**
- * tipc_send_buf2name - send message buffer to port name
- */
-
-int tipc_send_buf2name(u32 ref,
- struct tipc_name const *dest,
- u32 domain,
- struct sk_buff *buf,
- unsigned int dsz)
-{
- struct tipc_portid orig;
-
- orig.ref = ref;
- orig.node = tipc_own_addr;
- return tipc_forward_buf2name(ref, dest, domain, buf, dsz, &orig,
- TIPC_PORT_IMPORTANCE);
-}
-
-/**
* tipc_forward2port - forward message sections to port identity
*/
-int tipc_forward2port(u32 ref,
- struct tipc_portid const *dest,
- unsigned int num_sect,
- struct iovec const *msg_sect,
- struct tipc_portid const *orig,
- unsigned int importance)
+static int tipc_forward2port(u32 ref,
+ struct tipc_portid const *dest,
+ unsigned int num_sect,
+ struct iovec const *msg_sect,
+ struct tipc_portid const *orig,
+ unsigned int importance)
{
struct port *p_ptr;
struct tipc_msg *msg;
@@ -1644,12 +1403,12 @@ int tipc_send2port(u32 ref,
/**
* tipc_forward_buf2port - forward message buffer to port identity
*/
-int tipc_forward_buf2port(u32 ref,
- struct tipc_portid const *dest,
- struct sk_buff *buf,
- unsigned int dsz,
- struct tipc_portid const *orig,
- unsigned int importance)
+static int tipc_forward_buf2port(u32 ref,
+ struct tipc_portid const *dest,
+ struct sk_buff *buf,
+ unsigned int dsz,
+ struct tipc_portid const *orig,
+ unsigned int importance)
{
struct port *p_ptr;
struct tipc_msg *msg;
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 8d1652aab298..73bbf442b346 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -109,8 +109,6 @@ struct port {
extern spinlock_t tipc_port_list_lock;
struct port_list;
-int tipc_port_recv_sections(struct port *p_ptr, u32 num_sect,
- struct iovec const *msg_sect);
int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
struct iovec const *msg_sect, u32 num_sect,
int err);
@@ -157,7 +155,7 @@ static inline u32 tipc_peer_node(struct port *p_ptr)
static inline int tipc_port_congested(struct port *p_ptr)
{
- return((p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2));
+ return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2);
}
/**
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 8dea66500cf5..ab8ad32d8c20 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -282,23 +282,6 @@ void *tipc_ref_lock(u32 ref)
return NULL;
}
-/**
- * tipc_ref_unlock - unlock referenced object
- */
-
-void tipc_ref_unlock(u32 ref)
-{
- if (likely(tipc_ref_table.entries)) {
- struct reference *entry;
-
- entry = &tipc_ref_table.entries[ref &
- tipc_ref_table.index_mask];
- if (likely((entry->ref == ref) && (entry->object)))
- spin_unlock_bh(&entry->lock);
- else
- err("Attempt to unlock non-existent reference\n");
- }
-}
/**
* tipc_ref_deref - return pointer referenced object (without locking it)
diff --git a/net/tipc/ref.h b/net/tipc/ref.h
index 7e3798ea93b9..5bc8e7ab84de 100644
--- a/net/tipc/ref.h
+++ b/net/tipc/ref.h
@@ -44,7 +44,6 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock);
void tipc_ref_discard(u32 ref);
void *tipc_ref_lock(u32 ref);
-void tipc_ref_unlock(u32 ref);
void *tipc_ref_deref(u32 ref);
#endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 66e889ba48fd..33217fc3d697 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -64,6 +64,7 @@ struct tipc_sock {
struct sock sk;
struct tipc_port *p;
struct tipc_portid peer_name;
+ long conn_timeout;
};
#define tipc_sk(sk) ((struct tipc_sock *)(sk))
@@ -240,9 +241,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
sock->state = state;
sock_init_data(sock, sk);
- sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
sk->sk_backlog_rcv = backlog_rcv;
tipc_sk(sk)->p = tp_ptr;
+ tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
spin_unlock_bh(tp_ptr->lock);
@@ -429,36 +430,55 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
* to handle any preventable race conditions, so TIPC will do the same ...
*
* TIPC sets the returned events as follows:
- * a) POLLRDNORM and POLLIN are set if the socket's receive queue is non-empty
- * or if a connection-oriented socket is does not have an active connection
- * (i.e. a read operation will not block).
- * b) POLLOUT is set except when a socket's connection has been terminated
- * (i.e. a write operation will not block).
- * c) POLLHUP is set when a socket's connection has been terminated.
- *
- * IMPORTANT: The fact that a read or write operation will not block does NOT
- * imply that the operation will succeed!
+ *
+ * socket state flags set
+ * ------------ ---------
+ * unconnected no read flags
+ * no write flags
+ *
+ * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue
+ * no write flags
+ *
+ * connected POLLIN/POLLRDNORM if data in rx queue
+ * POLLOUT if port is not congested
+ *
+ * disconnecting POLLIN/POLLRDNORM/POLLHUP
+ * no write flags
+ *
+ * listening POLLIN if SYN in rx queue
+ * no write flags
+ *
+ * ready POLLIN/POLLRDNORM if data in rx queue
+ * [connectionless] POLLOUT (since port cannot be congested)
+ *
+ * IMPORTANT: The fact that a read or write operation is indicated does NOT
+ * imply that the operation will succeed, merely that it should be performed
+ * and will not block.
*/
static unsigned int poll(struct file *file, struct socket *sock,
poll_table *wait)
{
struct sock *sk = sock->sk;
- u32 mask;
+ u32 mask = 0;
poll_wait(file, sk_sleep(sk), wait);
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- (sock->state == SS_UNCONNECTED) ||
- (sock->state == SS_DISCONNECTING))
- mask = (POLLRDNORM | POLLIN);
- else
- mask = 0;
-
- if (sock->state == SS_DISCONNECTING)
- mask |= POLLHUP;
- else
- mask |= POLLOUT;
+ switch ((int)sock->state) {
+ case SS_READY:
+ case SS_CONNECTED:
+ if (!tipc_sk_port(sk)->congested)
+ mask |= POLLOUT;
+ /* fall thru' */
+ case SS_CONNECTING:
+ case SS_LISTENING:
+ if (!skb_queue_empty(&sk->sk_receive_queue))
+ mask |= (POLLIN | POLLRDNORM);
+ break;
+ case SS_DISCONNECTING:
+ mask = (POLLIN | POLLRDNORM | POLLHUP);
+ break;
+ }
return mask;
}
@@ -1026,9 +1046,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
struct sk_buff *buf;
struct tipc_msg *msg;
unsigned int sz;
- int sz_to_copy;
+ int sz_to_copy, target, needed;
int sz_copied = 0;
- int needed;
char __user *crs = m->msg_iov->iov_base;
unsigned char *buf_crs;
u32 err;
@@ -1050,6 +1069,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
goto exit;
}
+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
+
restart:
/* Look for a message in receive queue; wait if necessary */
@@ -1138,7 +1159,7 @@ restart:
if ((sz_copied < buf_len) && /* didn't get all requested data */
(!skb_queue_empty(&sk->sk_receive_queue) ||
- (flags & MSG_WAITALL)) && /* and more is ready or required */
+ (sz_copied < target)) && /* and more is ready or required */
(!(flags & MSG_PEEK)) && /* and aren't just peeking at data */
(!err)) /* and haven't reached a FIN */
goto restart;
@@ -1174,7 +1195,7 @@ static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base)
if (msg_connected(msg))
threshold *= 4;
- return (queue_size >= threshold);
+ return queue_size >= threshold;
}
/**
@@ -1365,6 +1386,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
struct msghdr m = {NULL,};
struct sk_buff *buf;
struct tipc_msg *msg;
+ long timeout;
int res;
lock_sock(sk);
@@ -1379,7 +1401,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
/* For now, TIPC does not support the non-blocking form of connect() */
if (flags & O_NONBLOCK) {
- res = -EWOULDBLOCK;
+ res = -EOPNOTSUPP;
goto exit;
}
@@ -1425,11 +1447,12 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
/* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
+ timeout = tipc_sk(sk)->conn_timeout;
release_sock(sk);
res = wait_event_interruptible_timeout(*sk_sleep(sk),
(!skb_queue_empty(&sk->sk_receive_queue) ||
(sock->state != SS_CONNECTING)),
- sk->sk_rcvtimeo);
+ timeout ? timeout : MAX_SCHEDULE_TIMEOUT);
lock_sock(sk);
if (res > 0) {
@@ -1692,7 +1715,7 @@ static int setsockopt(struct socket *sock,
res = tipc_set_portunreturnable(tport->ref, value);
break;
case TIPC_CONN_TIMEOUT:
- sk->sk_rcvtimeo = msecs_to_jiffies(value);
+ tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value);
/* no need to set "res", since already 0 at this point */
break;
default:
@@ -1747,7 +1770,7 @@ static int getsockopt(struct socket *sock,
res = tipc_portunreturnable(tport->ref, &value);
break;
case TIPC_CONN_TIMEOUT:
- value = jiffies_to_msecs(sk->sk_rcvtimeo);
+ value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout);
/* no need to set "res", since already 0 at this point */
break;
case TIPC_NODE_RECVQ_DEPTH:
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index ab6eab4c45e2..33313961d010 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -76,6 +76,19 @@ struct top_srv {
static struct top_srv topsrv = { 0 };
/**
+ * htohl - convert value to endianness used by destination
+ * @in: value to convert
+ * @swap: non-zero if endianness must be reversed
+ *
+ * Returns converted value
+ */
+
+static u32 htohl(u32 in, int swap)
+{
+ return swap ? swab32(in) : in;
+}
+
+/**
* subscr_send_event - send a message containing a tipc_event to the subscriber
*
* Note: Must not hold subscriber's server port lock, since tipc_send() will
@@ -94,11 +107,11 @@ static void subscr_send_event(struct subscription *sub,
msg_sect.iov_base = (void *)&sub->evt;
msg_sect.iov_len = sizeof(struct tipc_event);
- sub->evt.event = htonl(event);
- sub->evt.found_lower = htonl(found_lower);
- sub->evt.found_upper = htonl(found_upper);
- sub->evt.port.ref = htonl(port_ref);
- sub->evt.port.node = htonl(node);
+ sub->evt.event = htohl(event, sub->swap);
+ sub->evt.found_lower = htohl(found_lower, sub->swap);
+ 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);
}
@@ -274,29 +287,16 @@ static void subscr_cancel(struct tipc_subscr *s,
{
struct subscription *sub;
struct subscription *sub_temp;
- __u32 type, lower, upper, timeout, filter;
int found = 0;
/* Find first matching subscription, exit if not found */
- type = ntohl(s->seq.type);
- lower = ntohl(s->seq.lower);
- upper = ntohl(s->seq.upper);
- timeout = ntohl(s->timeout);
- filter = ntohl(s->filter) & ~TIPC_SUB_CANCEL;
-
list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
subscription_list) {
- if ((type == sub->seq.type) &&
- (lower == sub->seq.lower) &&
- (upper == sub->seq.upper) &&
- (timeout == sub->timeout) &&
- (filter == sub->filter) &&
- !memcmp(s->usr_handle,sub->evt.s.usr_handle,
- sizeof(s->usr_handle)) ){
- found = 1;
- break;
- }
+ if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) {
+ found = 1;
+ break;
+ }
}
if (!found)
return;
@@ -310,7 +310,7 @@ static void subscr_cancel(struct tipc_subscr *s,
k_term_timer(&sub->timer);
spin_lock_bh(subscriber->lock);
}
- dbg("Cancel: removing sub %u,%u,%u from subscriber %p list\n",
+ dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n",
sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
subscr_del(sub);
}
@@ -325,10 +325,16 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
struct subscriber *subscriber)
{
struct subscription *sub;
+ int swap;
+
+ /* Determine subscriber's endianness */
+
+ swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE));
/* Detect & process a subscription cancellation request */
- if (ntohl(s->filter) & TIPC_SUB_CANCEL) {
+ if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
+ s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
subscr_cancel(s, subscriber);
return NULL;
}
@@ -353,12 +359,13 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
/* Initialize subscription object */
- sub->seq.type = ntohl(s->seq.type);
- sub->seq.lower = ntohl(s->seq.lower);
- sub->seq.upper = ntohl(s->seq.upper);
- sub->timeout = ntohl(s->timeout);
- sub->filter = ntohl(s->filter);
- if ((sub->filter && (sub->filter != TIPC_SUB_PORTS)) ||
+ sub->seq.type = htohl(s->seq.type, swap);
+ sub->seq.lower = htohl(s->seq.lower, swap);
+ sub->seq.upper = htohl(s->seq.upper, swap);
+ sub->timeout = htohl(s->timeout, swap);
+ sub->filter = htohl(s->filter, swap);
+ if ((!(sub->filter & TIPC_SUB_PORTS) ==
+ !(sub->filter & TIPC_SUB_SERVICE)) ||
(sub->seq.lower > sub->seq.upper)) {
warn("Subscription rejected, illegal request\n");
kfree(sub);
@@ -369,6 +376,7 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
INIT_LIST_HEAD(&sub->nameseq_list);
list_add(&sub->subscription_list, &subscriber->subscription_list);
sub->server_ref = subscriber->port_ref;
+ sub->swap = swap;
memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr));
atomic_inc(&topsrv.subscription_count);
if (sub->timeout != TIPC_WAIT_FOREVER) {
@@ -598,12 +606,3 @@ void tipc_subscr_stop(void)
topsrv.user_ref = 0;
}
}
-
-
-int tipc_ispublished(struct tipc_name const *name)
-{
- u32 domain = 0;
-
- return(tipc_nametbl_translate(name->type, name->instance,&domain) != 0);
-}
-
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index c20f496d95b2..45d89bf4d202 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -53,6 +53,7 @@ typedef void (*tipc_subscr_event) (struct subscription *sub,
* @nameseq_list: adjacent subscriptions in name sequence's subscription list
* @subscription_list: adjacent subscriptions in subscriber's subscription list
* @server_ref: object reference of server port associated with subscription
+ * @swap: indicates if subscriber uses opposite endianness in its messages
* @evt: template for events generated by subscription
*/
@@ -65,6 +66,7 @@ struct subscription {
struct list_head nameseq_list;
struct list_head subscription_list;
u32 server_ref;
+ int swap;
struct tipc_event evt;
};
diff --git a/net/tipc/zone.c b/net/tipc/zone.c
index 2c01ba2d86bf..83f8b5e91fc8 100644
--- a/net/tipc/zone.c
+++ b/net/tipc/zone.c
@@ -160,14 +160,3 @@ u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref)
}
return 0;
}
-
-
-u32 tipc_zone_next_node(u32 addr)
-{
- struct cluster *c_ptr = tipc_cltr_find(addr);
-
- if (c_ptr)
- return tipc_cltr_next_node(c_ptr, addr);
- return 0;
-}
-
diff --git a/net/tipc/zone.h b/net/tipc/zone.h
index 7bdc3406ba9b..bd1c20ce9d06 100644
--- a/net/tipc/zone.h
+++ b/net/tipc/zone.h
@@ -61,7 +61,6 @@ void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest);
struct _zone *tipc_zone_create(u32 addr);
void tipc_zone_delete(struct _zone *z_ptr);
void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr);
-u32 tipc_zone_next_node(u32 addr);
static inline struct _zone *tipc_zone_find(u32 addr)
{
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 0b39b2451ea5..0ebc777a6660 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1511,6 +1511,8 @@ restart:
goto restart;
}
+ if (sock_flag(other, SOCK_RCVTSTAMP))
+ __net_timestamp(skb);
skb_queue_tail(&other->sk_receive_queue, skb);
unix_state_unlock(other);
other->sk_data_ready(other, len);
@@ -1722,6 +1724,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
if (err)
goto out_free;
+ if (sock_flag(sk, SOCK_RCVTSTAMP))
+ __sock_recv_timestamp(msg, sk, skb);
+
if (!siocb->scm) {
siocb->scm = &tmp_scm;
memset(&tmp_scm, 0, sizeof(tmp_scm));
@@ -2033,11 +2038,10 @@ static unsigned int unix_poll(struct file *file, struct socket *sock, poll_table
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
if (sk->sk_shutdown & RCV_SHUTDOWN)
- mask |= POLLRDHUP;
+ mask |= POLLRDHUP | POLLIN | POLLRDNORM;
/* readable? */
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- (sk->sk_shutdown & RCV_SHUTDOWN))
+ if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= POLLIN | POLLRDNORM;
/* Connection-based need to check for termination and startup */
diff --git a/net/wireless/core.c b/net/wireless/core.c
index d6d046b9f6f2..9c21ebf9780e 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -253,11 +253,16 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
WARN_ON(err);
wdev->netdev->features |= NETIF_F_NETNS_LOCAL;
}
+
+ return err;
}
wiphy_net_set(&rdev->wiphy, net);
- return err;
+ err = device_rename(&rdev->wiphy.dev, dev_name(&rdev->wiphy.dev));
+ WARN_ON(err);
+
+ return 0;
}
static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
@@ -428,7 +433,7 @@ int wiphy_register(struct wiphy *wiphy)
/* sanity check ifmodes */
WARN_ON(!ifmodes);
- ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1;
+ ifmodes &= ((1 << NUM_NL80211_IFTYPES) - 1) & ~1;
if (WARN_ON(ifmodes != wiphy->interface_modes))
wiphy->interface_modes = ifmodes;
@@ -683,8 +688,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work);
INIT_LIST_HEAD(&wdev->event_list);
spin_lock_init(&wdev->event_lock);
- INIT_LIST_HEAD(&wdev->action_registrations);
- spin_lock_init(&wdev->action_registrations_lock);
+ INIT_LIST_HEAD(&wdev->mgmt_registrations);
+ spin_lock_init(&wdev->mgmt_registrations_lock);
mutex_lock(&rdev->devlist_mtx);
list_add_rcu(&wdev->list, &rdev->netdev_list);
@@ -724,6 +729,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
dev->ethtool_ops = &cfg80211_ethtool_ops;
if ((wdev->iftype == NL80211_IFTYPE_STATION ||
+ wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
dev->priv_flags |= IFF_DONT_BRIDGE;
break;
@@ -732,6 +738,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
case NL80211_IFTYPE_ADHOC:
cfg80211_leave_ibss(rdev, dev, true);
break;
+ case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
wdev_lock(wdev);
#ifdef CONFIG_CFG80211_WEXT
@@ -804,7 +811,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
sysfs_remove_link(&dev->dev.kobj, "phy80211");
list_del_rcu(&wdev->list);
rdev->devlist_generation++;
- cfg80211_mlme_purge_actions(wdev);
+ cfg80211_mlme_purge_registrations(wdev);
#ifdef CONFIG_CFG80211_WEXT
kfree(wdev->wext.keys);
#endif
@@ -910,52 +917,3 @@ static void __exit cfg80211_exit(void)
destroy_workqueue(cfg80211_wq);
}
module_exit(cfg80211_exit);
-
-static int ___wiphy_printk(const char *level, const struct wiphy *wiphy,
- struct va_format *vaf)
-{
- if (!wiphy)
- return printk("%s(NULL wiphy *): %pV", level, vaf);
-
- return printk("%s%s: %pV", level, wiphy_name(wiphy), vaf);
-}
-
-int __wiphy_printk(const char *level, const struct wiphy *wiphy,
- const char *fmt, ...)
-{
- struct va_format vaf;
- va_list args;
- int r;
-
- va_start(args, fmt);
-
- vaf.fmt = fmt;
- vaf.va = &args;
-
- r = ___wiphy_printk(level, wiphy, &vaf);
- va_end(args);
-
- return r;
-}
-EXPORT_SYMBOL(__wiphy_printk);
-
-#define define_wiphy_printk_level(func, kern_level) \
-int func(const struct wiphy *wiphy, const char *fmt, ...) \
-{ \
- struct va_format vaf; \
- va_list args; \
- int r; \
- \
- va_start(args, fmt); \
- \
- vaf.fmt = fmt; \
- vaf.va = &args; \
- \
- r = ___wiphy_printk(kern_level, wiphy, &vaf); \
- va_end(args); \
- \
- return r; \
-} \
-EXPORT_SYMBOL(func);
-
-define_wiphy_printk_level(wiphy_debug, KERN_DEBUG);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 63d57ae399c3..6583cca0e2ee 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -86,7 +86,7 @@ struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy)
static inline
bool wiphy_idx_valid(int wiphy_idx)
{
- return (wiphy_idx >= 0);
+ return wiphy_idx >= 0;
}
@@ -95,7 +95,10 @@ extern struct mutex cfg80211_mutex;
extern struct list_head cfg80211_rdev_list;
extern int cfg80211_rdev_list_generation;
-#define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex))
+static inline void assert_cfg80211_lock(void)
+{
+ lockdep_assert_held(&cfg80211_mutex);
+}
/*
* You can use this to mark a wiphy_idx as not having an associated wiphy.
@@ -202,8 +205,8 @@ static inline void wdev_unlock(struct wireless_dev *wdev)
mutex_unlock(&wdev->mtx);
}
-#define ASSERT_RDEV_LOCK(rdev) WARN_ON(!mutex_is_locked(&(rdev)->mtx));
-#define ASSERT_WDEV_LOCK(wdev) WARN_ON(!mutex_is_locked(&(wdev)->mtx));
+#define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx)
+#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
enum cfg80211_event_type {
EVENT_CONNECT_RESULT,
@@ -331,16 +334,17 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
const u8 *resp_ie, size_t resp_ie_len,
u16 status, bool wextev,
struct cfg80211_bss *bss);
-int cfg80211_mlme_register_action(struct wireless_dev *wdev, u32 snd_pid,
- const u8 *match_data, int match_len);
-void cfg80211_mlme_unregister_actions(struct wireless_dev *wdev, u32 nlpid);
-void cfg80211_mlme_purge_actions(struct wireless_dev *wdev);
-int cfg80211_mlme_action(struct cfg80211_registered_device *rdev,
- struct net_device *dev,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type,
- bool channel_type_valid,
- const u8 *buf, size_t len, u64 *cookie);
+int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
+ u16 frame_type, const u8 *match_data,
+ int match_len);
+void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
+void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
+int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type,
+ bool channel_type_valid,
+ const u8 *buf, size_t len, u64 *cookie);
/* SME */
int __cfg80211_connect(struct cfg80211_registered_device *rdev,
@@ -371,7 +375,7 @@ bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev);
/* internal helpers */
int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
struct key_params *params, int key_idx,
- const u8 *mac_addr);
+ bool pairwise, const u8 *mac_addr);
void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
size_t ie_len, u16 reason, bool from_ap);
void cfg80211_sme_scan_done(struct net_device *dev);
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 27a8ce9343c3..f33fbb79437c 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -88,6 +88,25 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
if (wdev->ssid_len)
return -EALREADY;
+ if (!params->basic_rates) {
+ /*
+ * If no rates were explicitly configured,
+ * use the mandatory rate set for 11b or
+ * 11a for maximum compatibility.
+ */
+ struct ieee80211_supported_band *sband =
+ rdev->wiphy.bands[params->channel->band];
+ int j;
+ u32 flag = params->channel->band == IEEE80211_BAND_5GHZ ?
+ IEEE80211_RATE_MANDATORY_A :
+ IEEE80211_RATE_MANDATORY_B;
+
+ for (j = 0; j < sband->n_bitrates; j++) {
+ if (sband->bitrates[j].flags & flag)
+ params->basic_rates |= BIT(j);
+ }
+ }
+
if (WARN_ON(wdev->connect_keys))
kfree(wdev->connect_keys);
wdev->connect_keys = connkeys;
@@ -141,7 +160,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
*/
if (rdev->ops->del_key)
for (i = 0; i < 6; i++)
- rdev->ops->del_key(wdev->wiphy, dev, i, NULL);
+ rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL);
if (wdev->current_bss) {
cfg80211_unhold_bss(wdev->current_bss);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index d1a3fb99fdf2..26838d903b9a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -149,7 +149,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
const u8 *bssid = mgmt->bssid;
int i;
- bool found = false;
+ bool found = false, was_current = false;
ASSERT_WDEV_LOCK(wdev);
@@ -159,6 +159,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
cfg80211_put_bss(&wdev->current_bss->pub);
wdev->current_bss = NULL;
found = true;
+ was_current = true;
} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
if (wdev->auth_bsses[i] &&
memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
@@ -183,7 +184,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
- if (wdev->sme_state == CFG80211_SME_CONNECTED) {
+ if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) {
u16 reason_code;
bool from_ap;
@@ -747,31 +748,53 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
}
EXPORT_SYMBOL(cfg80211_new_sta);
-struct cfg80211_action_registration {
+struct cfg80211_mgmt_registration {
struct list_head list;
u32 nlpid;
int match_len;
+ __le16 frame_type;
+
u8 match[];
};
-int cfg80211_mlme_register_action(struct wireless_dev *wdev, u32 snd_pid,
- const u8 *match_data, int match_len)
+int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
+ u16 frame_type, const u8 *match_data,
+ int match_len)
{
- struct cfg80211_action_registration *reg, *nreg;
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+ struct cfg80211_mgmt_registration *reg, *nreg;
int err = 0;
+ u16 mgmt_type;
+
+ if (!wdev->wiphy->mgmt_stypes)
+ return -EOPNOTSUPP;
+
+ if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
+ return -EINVAL;
+
+ if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
+ return -EINVAL;
+
+ mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
+ if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
+ return -EINVAL;
nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
if (!nreg)
return -ENOMEM;
- spin_lock_bh(&wdev->action_registrations_lock);
+ spin_lock_bh(&wdev->mgmt_registrations_lock);
- list_for_each_entry(reg, &wdev->action_registrations, list) {
+ list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
int mlen = min(match_len, reg->match_len);
+ if (frame_type != le16_to_cpu(reg->frame_type))
+ continue;
+
if (memcmp(reg->match, match_data, mlen) == 0) {
err = -EALREADY;
break;
@@ -786,140 +809,212 @@ int cfg80211_mlme_register_action(struct wireless_dev *wdev, u32 snd_pid,
memcpy(nreg->match, match_data, match_len);
nreg->match_len = match_len;
nreg->nlpid = snd_pid;
- list_add(&nreg->list, &wdev->action_registrations);
+ nreg->frame_type = cpu_to_le16(frame_type);
+ list_add(&nreg->list, &wdev->mgmt_registrations);
+
+ if (rdev->ops->mgmt_frame_register)
+ rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
+ frame_type, true);
out:
- spin_unlock_bh(&wdev->action_registrations_lock);
+ spin_unlock_bh(&wdev->mgmt_registrations_lock);
+
return err;
}
-void cfg80211_mlme_unregister_actions(struct wireless_dev *wdev, u32 nlpid)
+void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
{
- struct cfg80211_action_registration *reg, *tmp;
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+ struct cfg80211_mgmt_registration *reg, *tmp;
- spin_lock_bh(&wdev->action_registrations_lock);
+ spin_lock_bh(&wdev->mgmt_registrations_lock);
- list_for_each_entry_safe(reg, tmp, &wdev->action_registrations, list) {
- if (reg->nlpid == nlpid) {
- list_del(&reg->list);
- kfree(reg);
+ list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
+ if (reg->nlpid != nlpid)
+ continue;
+
+ if (rdev->ops->mgmt_frame_register) {
+ u16 frame_type = le16_to_cpu(reg->frame_type);
+
+ rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
+ frame_type, false);
}
+
+ list_del(&reg->list);
+ kfree(reg);
}
- spin_unlock_bh(&wdev->action_registrations_lock);
+ spin_unlock_bh(&wdev->mgmt_registrations_lock);
}
-void cfg80211_mlme_purge_actions(struct wireless_dev *wdev)
+void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
{
- struct cfg80211_action_registration *reg, *tmp;
+ struct cfg80211_mgmt_registration *reg, *tmp;
- spin_lock_bh(&wdev->action_registrations_lock);
+ spin_lock_bh(&wdev->mgmt_registrations_lock);
- list_for_each_entry_safe(reg, tmp, &wdev->action_registrations, list) {
+ list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
list_del(&reg->list);
kfree(reg);
}
- spin_unlock_bh(&wdev->action_registrations_lock);
+ spin_unlock_bh(&wdev->mgmt_registrations_lock);
}
-int cfg80211_mlme_action(struct cfg80211_registered_device *rdev,
- struct net_device *dev,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type,
- bool channel_type_valid,
- const u8 *buf, size_t len, u64 *cookie)
+int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type,
+ bool channel_type_valid,
+ const u8 *buf, size_t len, u64 *cookie)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
const struct ieee80211_mgmt *mgmt;
+ u16 stype;
- if (rdev->ops->action == NULL)
+ if (!wdev->wiphy->mgmt_stypes)
return -EOPNOTSUPP;
+
+ if (!rdev->ops->mgmt_tx)
+ return -EOPNOTSUPP;
+
if (len < 24 + 1)
return -EINVAL;
mgmt = (const struct ieee80211_mgmt *) buf;
- if (!ieee80211_is_action(mgmt->frame_control))
+
+ if (!ieee80211_is_mgmt(mgmt->frame_control))
return -EINVAL;
- if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
- /* Verify that we are associated with the destination AP */
+
+ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
+ if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
+ return -EINVAL;
+
+ if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
+ int err = 0;
+
wdev_lock(wdev);
- if (!wdev->current_bss ||
- memcmp(wdev->current_bss->pub.bssid, mgmt->bssid,
- ETH_ALEN) != 0 ||
- (wdev->iftype == NL80211_IFTYPE_STATION &&
- memcmp(wdev->current_bss->pub.bssid, mgmt->da,
- ETH_ALEN) != 0)) {
- wdev_unlock(wdev);
- return -ENOTCONN;
- }
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ if (!wdev->current_bss) {
+ err = -ENOTCONN;
+ break;
+ }
+
+ if (memcmp(wdev->current_bss->pub.bssid,
+ mgmt->bssid, ETH_ALEN)) {
+ err = -ENOTCONN;
+ break;
+ }
+
+ /*
+ * check for IBSS DA must be done by driver as
+ * cfg80211 doesn't track the stations
+ */
+ if (wdev->iftype == NL80211_IFTYPE_ADHOC)
+ break;
+ /* for station, check that DA is the AP */
+ if (memcmp(wdev->current_bss->pub.bssid,
+ mgmt->da, ETH_ALEN)) {
+ err = -ENOTCONN;
+ break;
+ }
+ break;
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_P2P_GO:
+ case NL80211_IFTYPE_AP_VLAN:
+ if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
+ err = -EINVAL;
+ break;
+ default:
+ err = -EOPNOTSUPP;
+ break;
+ }
wdev_unlock(wdev);
+
+ if (err)
+ return err;
}
if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0)
return -EINVAL;
/* Transmit the Action frame as requested by user space */
- return rdev->ops->action(&rdev->wiphy, dev, chan, channel_type,
- channel_type_valid, buf, len, cookie);
+ return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, channel_type,
+ channel_type_valid, buf, len, cookie);
}
-bool cfg80211_rx_action(struct net_device *dev, int freq, const u8 *buf,
- size_t len, gfp_t gfp)
+bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
+ size_t len, gfp_t gfp)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
- struct cfg80211_action_registration *reg;
- const u8 *action_data;
- int action_data_len;
+ struct cfg80211_mgmt_registration *reg;
+ const struct ieee80211_txrx_stypes *stypes =
+ &wiphy->mgmt_stypes[wdev->iftype];
+ struct ieee80211_mgmt *mgmt = (void *)buf;
+ const u8 *data;
+ int data_len;
bool result = false;
+ __le16 ftype = mgmt->frame_control &
+ cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
+ u16 stype;
- /* frame length - min size excluding category */
- action_data_len = len - (IEEE80211_MIN_ACTION_SIZE - 1);
+ stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
- /* action data starts with category */
- action_data = buf + IEEE80211_MIN_ACTION_SIZE - 1;
+ if (!(stypes->rx & BIT(stype)))
+ return false;
- spin_lock_bh(&wdev->action_registrations_lock);
+ data = buf + ieee80211_hdrlen(mgmt->frame_control);
+ data_len = len - ieee80211_hdrlen(mgmt->frame_control);
+
+ spin_lock_bh(&wdev->mgmt_registrations_lock);
+
+ list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
+ if (reg->frame_type != ftype)
+ continue;
- list_for_each_entry(reg, &wdev->action_registrations, list) {
- if (reg->match_len > action_data_len)
+ if (reg->match_len > data_len)
continue;
- if (memcmp(reg->match, action_data, reg->match_len))
+ if (memcmp(reg->match, data, reg->match_len))
continue;
/* found match! */
/* Indicate the received Action frame to user space */
- if (nl80211_send_action(rdev, dev, reg->nlpid, freq,
- buf, len, gfp))
+ if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq,
+ buf, len, gfp))
continue;
result = true;
break;
}
- spin_unlock_bh(&wdev->action_registrations_lock);
+ spin_unlock_bh(&wdev->mgmt_registrations_lock);
return result;
}
-EXPORT_SYMBOL(cfg80211_rx_action);
+EXPORT_SYMBOL(cfg80211_rx_mgmt);
-void cfg80211_action_tx_status(struct net_device *dev, u64 cookie,
- const u8 *buf, size_t len, bool ack, gfp_t gfp)
+void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie,
+ const u8 *buf, size_t len, bool ack, gfp_t gfp)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
/* Indicate TX status of the Action frame to user space */
- nl80211_send_action_tx_status(rdev, dev, cookie, buf, len, ack, gfp);
+ nl80211_send_mgmt_tx_status(rdev, dev, cookie, buf, len, ack, gfp);
}
-EXPORT_SYMBOL(cfg80211_action_tx_status);
+EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
void cfg80211_cqm_rssi_notify(struct net_device *dev,
enum nl80211_cqm_rssi_threshold_event rssi_event,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 37902a54e9c1..c506241f8637 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -23,6 +23,11 @@
#include "nl80211.h"
#include "reg.h"
+static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
+ struct genl_info *info);
+static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
+ struct genl_info *info);
+
/* the netlink family */
static struct genl_family nl80211_fam = {
.id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
@@ -31,6 +36,8 @@ static struct genl_family nl80211_fam = {
.version = 1, /* no particular meaning now */
.maxattr = NL80211_ATTR_MAX,
.netnsok = true,
+ .pre_doit = nl80211_pre_doit,
+ .post_doit = nl80211_post_doit,
};
/* internal helper: get rdev and dev */
@@ -86,6 +93,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
[NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
[NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
+ [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 },
[NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
[NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
@@ -136,6 +144,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
.len = sizeof(struct nl80211_sta_flag_update),
},
[NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
+ [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
+ [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
[NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
[NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
@@ -156,9 +166,10 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
+ [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
};
-/* policy for the attributes */
+/* policy for the key attributes */
static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
[NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
[NL80211_KEY_IDX] = { .type = NLA_U8 },
@@ -166,6 +177,7 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
[NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
[NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
[NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
+ [NL80211_KEY_TYPE] = { .type = NLA_U32 },
};
/* ifidx get helper */
@@ -188,6 +200,47 @@ static int nl80211_get_ifidx(struct netlink_callback *cb)
return res;
}
+static int nl80211_prepare_netdev_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct cfg80211_registered_device **rdev,
+ struct net_device **dev)
+{
+ int ifidx = cb->args[0];
+ int err;
+
+ if (!ifidx)
+ ifidx = nl80211_get_ifidx(cb);
+ if (ifidx < 0)
+ return ifidx;
+
+ cb->args[0] = ifidx;
+
+ rtnl_lock();
+
+ *dev = __dev_get_by_index(sock_net(skb->sk), ifidx);
+ if (!*dev) {
+ err = -ENODEV;
+ goto out_rtnl;
+ }
+
+ *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
+ if (IS_ERR(dev)) {
+ err = PTR_ERR(dev);
+ goto out_rtnl;
+ }
+
+ return 0;
+ out_rtnl:
+ rtnl_unlock();
+ return err;
+}
+
+static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev)
+{
+ cfg80211_unlock_rdev(rdev);
+ rtnl_unlock();
+}
+
/* IE validation */
static bool is_valid_ie_attr(const struct nlattr *attr)
{
@@ -255,6 +308,7 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
struct key_parse {
struct key_params p;
int idx;
+ int type;
bool def, defmgmt;
};
@@ -285,6 +339,12 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
if (tb[NL80211_KEY_CIPHER])
k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
+ if (tb[NL80211_KEY_TYPE]) {
+ k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
+ if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
+ return -EINVAL;
+ }
+
return 0;
}
@@ -309,6 +369,12 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
+ if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
+ k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
+ if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
+ return -EINVAL;
+ }
+
return 0;
}
@@ -318,6 +384,7 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
memset(k, 0, sizeof(*k));
k->idx = -1;
+ k->type = -1;
if (info->attrs[NL80211_ATTR_KEY])
err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
@@ -382,7 +449,7 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
} else if (parse.defmgmt)
goto error;
err = cfg80211_validate_key_settings(rdev, &parse.p,
- parse.idx, NULL);
+ parse.idx, false, NULL);
if (err)
goto error;
result->params[parse.idx].cipher = parse.p.cipher;
@@ -401,18 +468,17 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
{
ASSERT_WDEV_LOCK(wdev);
- if (!netif_running(wdev->netdev))
- return -ENETDOWN;
-
switch (wdev->iftype) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_P2P_GO:
break;
case NL80211_IFTYPE_ADHOC:
if (!wdev->current_bss)
return -ENOLINK;
break;
case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
if (wdev->sme_state != CFG80211_SME_CONNECTED)
return -ENOLINK;
break;
@@ -437,6 +503,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
struct ieee80211_rate *rate;
int i;
u16 ifmodes = dev->wiphy.interface_modes;
+ const struct ieee80211_txrx_stypes *mgmt_stypes =
+ dev->wiphy.mgmt_stypes;
hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
if (!hdr)
@@ -464,6 +532,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
dev->wiphy.max_scan_ie_len);
+ if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
+
NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
sizeof(u32) * dev->wiphy.n_cipher_suites,
dev->wiphy.cipher_suites);
@@ -471,6 +542,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
dev->wiphy.max_num_pmkids);
+ if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE);
+
nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
if (!nl_modes)
goto nla_put_failure;
@@ -587,12 +661,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
CMD(flush_pmksa, FLUSH_PMKSA);
CMD(remain_on_channel, REMAIN_ON_CHANNEL);
CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
- CMD(action, ACTION);
+ CMD(mgmt_tx, FRAME);
if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
i++;
NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
}
CMD(set_channel, SET_CHANNEL);
+ CMD(set_wds_peer, SET_WDS_PEER);
#undef CMD
@@ -608,6 +683,55 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
nla_nest_end(msg, nl_cmds);
+ if (mgmt_stypes) {
+ u16 stypes;
+ struct nlattr *nl_ftypes, *nl_ifs;
+ enum nl80211_iftype ift;
+
+ nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES);
+ if (!nl_ifs)
+ goto nla_put_failure;
+
+ for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
+ nl_ftypes = nla_nest_start(msg, ift);
+ if (!nl_ftypes)
+ goto nla_put_failure;
+ i = 0;
+ stypes = mgmt_stypes[ift].tx;
+ while (stypes) {
+ if (stypes & 1)
+ NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE,
+ (i << 4) | IEEE80211_FTYPE_MGMT);
+ stypes >>= 1;
+ i++;
+ }
+ nla_nest_end(msg, nl_ftypes);
+ }
+
+ nla_nest_end(msg, nl_ifs);
+
+ nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES);
+ if (!nl_ifs)
+ goto nla_put_failure;
+
+ for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
+ nl_ftypes = nla_nest_start(msg, ift);
+ if (!nl_ftypes)
+ goto nla_put_failure;
+ i = 0;
+ stypes = mgmt_stypes[ift].rx;
+ while (stypes) {
+ if (stypes & 1)
+ NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE,
+ (i << 4) | IEEE80211_FTYPE_MGMT);
+ stypes >>= 1;
+ i++;
+ }
+ nla_nest_end(msg, nl_ftypes);
+ }
+ nla_nest_end(msg, nl_ifs);
+ }
+
return genlmsg_end(msg, hdr);
nla_put_failure:
@@ -644,28 +768,18 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
{
struct sk_buff *msg;
- struct cfg80211_registered_device *dev;
-
- dev = cfg80211_get_dev_from_info(info);
- if (IS_ERR(dev))
- return PTR_ERR(dev);
+ struct cfg80211_registered_device *dev = info->user_ptr[0];
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
- goto out_err;
-
- if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
- goto out_free;
+ return -ENOMEM;
- cfg80211_unlock_rdev(dev);
+ if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) {
+ nlmsg_free(msg);
+ return -ENOBUFS;
+ }
return genlmsg_reply(msg, info);
-
- out_free:
- nlmsg_free(msg);
- out_err:
- cfg80211_unlock_rdev(dev);
- return -ENOBUFS;
}
static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
@@ -709,7 +823,8 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
wdev->iftype == NL80211_IFTYPE_AP ||
wdev->iftype == NL80211_IFTYPE_WDS ||
wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
- wdev->iftype == NL80211_IFTYPE_MONITOR;
+ wdev->iftype == NL80211_IFTYPE_MONITOR ||
+ wdev->iftype == NL80211_IFTYPE_P2P_GO;
}
static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
@@ -753,38 +868,48 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *netdev;
- int result;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *netdev = info->user_ptr[1];
- rtnl_lock();
+ return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info);
+}
- result = get_rdev_dev_by_info_ifindex(info, &rdev, &netdev);
- if (result)
- goto unlock;
+static int nl80211_set_wds_peer(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;
+ const u8 *bssid;
- result = __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info);
+ if (!info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
- unlock:
- rtnl_unlock();
+ if (netif_running(dev))
+ return -EBUSY;
- return result;
+ if (!rdev->ops->set_wds_peer)
+ return -EOPNOTSUPP;
+
+ if (wdev->iftype != NL80211_IFTYPE_WDS)
+ return -EOPNOTSUPP;
+
+ bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ return rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid);
}
+
static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev;
struct net_device *netdev = NULL;
struct wireless_dev *wdev;
- int result, rem_txq_params = 0;
+ int result = 0, rem_txq_params = 0;
struct nlattr *nl_txq_params;
u32 changed;
u8 retry_short = 0, retry_long = 0;
u32 frag_threshold = 0, rts_threshold = 0;
u8 coverage_class = 0;
- rtnl_lock();
-
/*
* Try to find the wiphy and netdev. Normally this
* function shouldn't need the netdev, but this is
@@ -811,8 +936,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
rdev = __cfg80211_rdev_from_info(info);
if (IS_ERR(rdev)) {
mutex_unlock(&cfg80211_mutex);
- result = PTR_ERR(rdev);
- goto unlock;
+ return PTR_ERR(rdev);
}
wdev = NULL;
netdev = NULL;
@@ -994,8 +1118,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
mutex_unlock(&rdev->mtx);
if (netdev)
dev_put(netdev);
- unlock:
- rtnl_unlock();
return result;
}
@@ -1075,33 +1197,20 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
{
struct sk_buff *msg;
- struct cfg80211_registered_device *dev;
- struct net_device *netdev;
- int err;
-
- err = get_rdev_dev_by_info_ifindex(info, &dev, &netdev);
- if (err)
- return err;
+ struct cfg80211_registered_device *dev = info->user_ptr[0];
+ struct net_device *netdev = info->user_ptr[1];
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
- goto out_err;
+ return -ENOMEM;
if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
- dev, netdev) < 0)
- goto out_free;
-
- dev_put(netdev);
- cfg80211_unlock_rdev(dev);
+ dev, netdev) < 0) {
+ nlmsg_free(msg);
+ return -ENOBUFS;
+ }
return genlmsg_reply(msg, info);
-
- out_free:
- nlmsg_free(msg);
- out_err:
- dev_put(netdev);
- cfg80211_unlock_rdev(dev);
- return -ENOBUFS;
}
static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
@@ -1161,39 +1270,29 @@ static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct vif_params params;
int err;
enum nl80211_iftype otype, ntype;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
u32 _flags, *flags = NULL;
bool change = false;
memset(&params, 0, sizeof(params));
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
otype = ntype = dev->ieee80211_ptr->iftype;
if (info->attrs[NL80211_ATTR_IFTYPE]) {
ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
if (otype != ntype)
change = true;
- if (ntype > NL80211_IFTYPE_MAX) {
- err = -EINVAL;
- goto unlock;
- }
+ if (ntype > NL80211_IFTYPE_MAX)
+ return -EINVAL;
}
if (info->attrs[NL80211_ATTR_MESH_ID]) {
- if (ntype != NL80211_IFTYPE_MESH_POINT) {
- err = -EINVAL;
- goto unlock;
- }
+ if (ntype != NL80211_IFTYPE_MESH_POINT)
+ return -EINVAL;
params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
change = true;
@@ -1204,20 +1303,18 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
change = true;
err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
if (err)
- goto unlock;
+ return err;
} else {
params.use_4addr = -1;
}
if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
- if (ntype != NL80211_IFTYPE_MONITOR) {
- err = -EINVAL;
- goto unlock;
- }
+ if (ntype != NL80211_IFTYPE_MONITOR)
+ return -EINVAL;
err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
&_flags);
if (err)
- goto unlock;
+ return err;
flags = &_flags;
change = true;
@@ -1231,17 +1328,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
if (!err && params.use_4addr != -1)
dev->ieee80211_ptr->use_4addr = params.use_4addr;
- unlock:
- dev_put(dev);
- cfg80211_unlock_rdev(rdev);
- unlock_rtnl:
- rtnl_unlock();
return err;
}
static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct vif_params params;
int err;
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
@@ -1258,19 +1350,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
}
- rtnl_lock();
-
- rdev = cfg80211_get_dev_from_info(info);
- if (IS_ERR(rdev)) {
- err = PTR_ERR(rdev);
- goto unlock_rtnl;
- }
-
if (!rdev->ops->add_virtual_intf ||
- !(rdev->wiphy.interface_modes & (1 << type))) {
- err = -EOPNOTSUPP;
- goto unlock;
- }
+ !(rdev->wiphy.interface_modes & (1 << type)))
+ return -EOPNOTSUPP;
if (type == NL80211_IFTYPE_MESH_POINT &&
info->attrs[NL80211_ATTR_MESH_ID]) {
@@ -1282,7 +1364,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
if (err)
- goto unlock;
+ return err;
}
err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
@@ -1292,38 +1374,18 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
nla_data(info->attrs[NL80211_ATTR_IFNAME]),
type, err ? NULL : &flags, &params);
- unlock:
- cfg80211_unlock_rdev(rdev);
- unlock_rtnl:
- rtnl_unlock();
return err;
}
static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- int err;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->del_virtual_intf) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- err = rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
+ if (!rdev->ops->del_virtual_intf)
+ return -EOPNOTSUPP;
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- unlock_rtnl:
- rtnl_unlock();
- return err;
+ return rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
}
struct get_key_cookie {
@@ -1376,11 +1438,12 @@ static void get_key_callback(void *c, struct key_params *params)
static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
u8 key_idx = 0;
- u8 *mac_addr = NULL;
+ const u8 *mac_addr = NULL;
+ bool pairwise;
struct get_key_cookie cookie = {
.error = 0,
};
@@ -1396,30 +1459,28 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_MAC])
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->get_key) {
- err = -EOPNOTSUPP;
- goto out;
+ pairwise = !!mac_addr;
+ if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
+ u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
+ if (kt >= NUM_NL80211_KEYTYPES)
+ return -EINVAL;
+ if (kt != NL80211_KEYTYPE_GROUP &&
+ kt != NL80211_KEYTYPE_PAIRWISE)
+ return -EINVAL;
+ pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
}
+ if (!rdev->ops->get_key)
+ return -EOPNOTSUPP;
+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg) {
- err = -ENOMEM;
- goto out;
- }
+ if (!msg)
+ return -ENOMEM;
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
NL80211_CMD_NEW_KEY);
-
- if (IS_ERR(hdr)) {
- err = PTR_ERR(hdr);
- goto free_msg;
- }
+ if (IS_ERR(hdr))
+ return PTR_ERR(hdr);
cookie.msg = msg;
cookie.idx = key_idx;
@@ -1429,8 +1490,12 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
if (mac_addr)
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
- err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, mac_addr,
- &cookie, get_key_callback);
+ if (pairwise && mac_addr &&
+ !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
+ return -ENOENT;
+
+ err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, pairwise,
+ mac_addr, &cookie, get_key_callback);
if (err)
goto free_msg;
@@ -1439,28 +1504,21 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
goto nla_put_failure;
genlmsg_end(msg, hdr);
- err = genlmsg_reply(msg, info);
- goto out;
+ return genlmsg_reply(msg, info);
nla_put_failure:
err = -ENOBUFS;
free_msg:
nlmsg_free(msg);
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- unlock_rtnl:
- rtnl_unlock();
-
return err;
}
static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct key_parse key;
int err;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
int (*func)(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index);
@@ -1475,21 +1533,13 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
if (!key.def && !key.defmgmt)
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
if (key.def)
func = rdev->ops->set_default_key;
else
func = rdev->ops->set_default_mgmt_key;
- if (!func) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!func)
+ return -EOPNOTSUPP;
wdev_lock(dev->ieee80211_ptr);
err = nl80211_key_allowed(dev->ieee80211_ptr);
@@ -1506,23 +1556,16 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
#endif
wdev_unlock(dev->ieee80211_ptr);
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-
- unlock_rtnl:
- rtnl_unlock();
-
return err;
}
static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
struct key_parse key;
- u8 *mac_addr = NULL;
+ const u8 *mac_addr = NULL;
err = nl80211_parse_key(info, &key);
if (err)
@@ -1534,43 +1577,42 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_MAC])
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
- rtnl_lock();
+ if (key.type == -1) {
+ if (mac_addr)
+ key.type = NL80211_KEYTYPE_PAIRWISE;
+ else
+ key.type = NL80211_KEYTYPE_GROUP;
+ }
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
+ /* for now */
+ if (key.type != NL80211_KEYTYPE_PAIRWISE &&
+ key.type != NL80211_KEYTYPE_GROUP)
+ return -EINVAL;
- if (!rdev->ops->add_key) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->add_key)
+ return -EOPNOTSUPP;
- if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, mac_addr)) {
- err = -EINVAL;
- goto out;
- }
+ if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
+ key.type == NL80211_KEYTYPE_PAIRWISE,
+ mac_addr))
+ return -EINVAL;
wdev_lock(dev->ieee80211_ptr);
err = nl80211_key_allowed(dev->ieee80211_ptr);
if (!err)
err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx,
+ key.type == NL80211_KEYTYPE_PAIRWISE,
mac_addr, &key.p);
wdev_unlock(dev->ieee80211_ptr);
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- unlock_rtnl:
- rtnl_unlock();
-
return err;
}
static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
u8 *mac_addr = NULL;
struct key_parse key;
@@ -1581,21 +1623,32 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_MAC])
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
- rtnl_lock();
+ if (key.type == -1) {
+ if (mac_addr)
+ key.type = NL80211_KEYTYPE_PAIRWISE;
+ else
+ key.type = NL80211_KEYTYPE_GROUP;
+ }
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
+ /* for now */
+ if (key.type != NL80211_KEYTYPE_PAIRWISE &&
+ key.type != NL80211_KEYTYPE_GROUP)
+ return -EINVAL;
- if (!rdev->ops->del_key) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->del_key)
+ return -EOPNOTSUPP;
wdev_lock(dev->ieee80211_ptr);
err = nl80211_key_allowed(dev->ieee80211_ptr);
+
+ if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr &&
+ !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
+ err = -ENOENT;
+
if (!err)
- err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, mac_addr);
+ err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx,
+ key.type == NL80211_KEYTYPE_PAIRWISE,
+ mac_addr);
#ifdef CONFIG_CFG80211_WEXT
if (!err) {
@@ -1607,13 +1660,6 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
#endif
wdev_unlock(dev->ieee80211_ptr);
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-
- unlock_rtnl:
- rtnl_unlock();
-
return err;
}
@@ -1621,35 +1667,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
{
int (*call)(struct wiphy *wiphy, struct net_device *dev,
struct beacon_parameters *info);
- struct cfg80211_registered_device *rdev;
- int err;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct beacon_parameters params;
int haveinfo = 0;
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EOPNOTSUPP;
switch (info->genlhdr->cmd) {
case NL80211_CMD_NEW_BEACON:
/* these are required for NEW_BEACON */
if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
!info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
- !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
- err = -EINVAL;
- goto out;
- }
+ !info->attrs[NL80211_ATTR_BEACON_HEAD])
+ return -EINVAL;
call = rdev->ops->add_beacon;
break;
@@ -1658,14 +1694,11 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
break;
default:
WARN_ON(1);
- err = -EOPNOTSUPP;
- goto out;
+ return -EOPNOTSUPP;
}
- if (!call) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!call)
+ return -EOPNOTSUPP;
memset(&params, 0, sizeof(params));
@@ -1695,52 +1728,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
haveinfo = 1;
}
- if (!haveinfo) {
- err = -EINVAL;
- goto out;
- }
-
- err = call(&rdev->wiphy, dev, &params);
-
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- unlock_rtnl:
- rtnl_unlock();
+ if (!haveinfo)
+ return -EINVAL;
- return err;
+ return call(&rdev->wiphy, dev, &params);
}
static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- int err;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->del_beacon) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
- err = -EOPNOTSUPP;
- goto out;
- }
- err = rdev->ops->del_beacon(&rdev->wiphy, dev);
+ if (!rdev->ops->del_beacon)
+ return -EOPNOTSUPP;
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- unlock_rtnl:
- rtnl_unlock();
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EOPNOTSUPP;
- return err;
+ return rdev->ops->del_beacon(&rdev->wiphy, dev);
}
static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
@@ -1861,6 +1867,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_TX_PACKETS)
NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS,
sinfo->tx_packets);
+ if (sinfo->filled & STATION_INFO_TX_RETRIES)
+ NLA_PUT_U32(msg, NL80211_STA_INFO_TX_RETRIES,
+ sinfo->tx_retries);
+ if (sinfo->filled & STATION_INFO_TX_FAILED)
+ NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED,
+ sinfo->tx_failed);
nla_nest_end(msg, sinfoattr);
return genlmsg_end(msg, hdr);
@@ -1877,28 +1889,12 @@ static int nl80211_dump_station(struct sk_buff *skb,
struct cfg80211_registered_device *dev;
struct net_device *netdev;
u8 mac_addr[ETH_ALEN];
- int ifidx = cb->args[0];
int sta_idx = cb->args[1];
int err;
- if (!ifidx)
- ifidx = nl80211_get_ifidx(cb);
- if (ifidx < 0)
- return ifidx;
-
- rtnl_lock();
-
- netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
- if (!netdev) {
- err = -ENODEV;
- goto out_rtnl;
- }
-
- dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
- if (IS_ERR(dev)) {
- err = PTR_ERR(dev);
- goto out_rtnl;
- }
+ err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
+ if (err)
+ return err;
if (!dev->ops->dump_station) {
err = -EOPNOTSUPP;
@@ -1928,21 +1924,19 @@ static int nl80211_dump_station(struct sk_buff *skb,
cb->args[1] = sta_idx;
err = skb->len;
out_err:
- cfg80211_unlock_rdev(dev);
- out_rtnl:
- rtnl_unlock();
+ nl80211_finish_netdev_dump(dev);
return err;
}
static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- int err;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct station_info sinfo;
struct sk_buff *msg;
u8 *mac_addr = NULL;
+ int err;
memset(&sinfo, 0, sizeof(sinfo));
@@ -1951,41 +1945,24 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
- if (!rdev->ops->get_station) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->get_station)
+ return -EOPNOTSUPP;
err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo);
if (err)
- goto out;
+ return err;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
- goto out;
+ return -ENOMEM;
if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
- dev, mac_addr, &sinfo) < 0)
- goto out_free;
-
- err = genlmsg_reply(msg, info);
- goto out;
-
- out_free:
- nlmsg_free(msg);
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
+ dev, mac_addr, &sinfo) < 0) {
+ nlmsg_free(msg);
+ return -ENOBUFS;
+ }
- return err;
+ return genlmsg_reply(msg, info);
}
/*
@@ -2015,9 +1992,9 @@ static int get_vlan(struct genl_info *info,
static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
struct station_parameters params;
u8 *mac_addr = NULL;
@@ -2055,12 +2032,6 @@ 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]);
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
err = get_vlan(info, rdev, &params.vlan);
if (err)
goto out;
@@ -2071,10 +2042,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
switch (dev->ieee80211_ptr->iftype) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_P2P_GO:
/* disallow mesh-specific things */
if (params.plink_action)
err = -EINVAL;
break;
+ case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
/* disallow everything but AUTHORIZED flag */
if (params.plink_action)
@@ -2120,19 +2093,15 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
out:
if (params.vlan)
dev_put(params.vlan);
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
return err;
}
static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
struct station_parameters params;
u8 *mac_addr = NULL;
@@ -2169,17 +2138,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
if (parse_station_flags(info, &params))
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
- dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
- err = -EINVAL;
- goto out;
- }
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EINVAL;
err = get_vlan(info, rdev, &params.vlan);
if (err)
@@ -2193,61 +2155,33 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
goto out;
}
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
-
err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params);
out:
if (params.vlan)
dev_put(params.vlan);
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
-
return err;
}
static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- int err;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
u8 *mac_addr = NULL;
if (info->attrs[NL80211_ATTR_MAC])
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
- dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
- err = -EINVAL;
- goto out;
- }
-
- if (!rdev->ops->del_station) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- err = rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EINVAL;
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
+ if (!rdev->ops->del_station)
+ return -EOPNOTSUPP;
- return err;
+ return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
}
static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
@@ -2310,28 +2244,12 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
struct net_device *netdev;
u8 dst[ETH_ALEN];
u8 next_hop[ETH_ALEN];
- int ifidx = cb->args[0];
int path_idx = cb->args[1];
int err;
- if (!ifidx)
- ifidx = nl80211_get_ifidx(cb);
- if (ifidx < 0)
- return ifidx;
-
- rtnl_lock();
-
- netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
- if (!netdev) {
- err = -ENODEV;
- goto out_rtnl;
- }
-
- dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
- if (IS_ERR(dev)) {
- err = PTR_ERR(dev);
- goto out_rtnl;
- }
+ err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
+ if (err)
+ return err;
if (!dev->ops->dump_mpath) {
err = -EOPNOTSUPP;
@@ -2365,18 +2283,15 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
cb->args[1] = path_idx;
err = skb->len;
out_err:
- cfg80211_unlock_rdev(dev);
- out_rtnl:
- rtnl_unlock();
-
+ nl80211_finish_netdev_dump(dev);
return err;
}
static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
struct mpath_info pinfo;
struct sk_buff *msg;
u8 *dst = NULL;
@@ -2389,53 +2304,33 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
- if (!rdev->ops->get_mpath) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->get_mpath)
+ return -EOPNOTSUPP;
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
+ return -EOPNOTSUPP;
err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo);
if (err)
- goto out;
+ return err;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
- goto out;
+ return -ENOMEM;
if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
- dev, dst, next_hop, &pinfo) < 0)
- goto out_free;
-
- err = genlmsg_reply(msg, info);
- goto out;
-
- out_free:
- nlmsg_free(msg);
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
+ dev, dst, next_hop, &pinfo) < 0) {
+ nlmsg_free(msg);
+ return -ENOBUFS;
+ }
- return err;
+ return genlmsg_reply(msg, info);
}
static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- int err;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
u8 *dst = NULL;
u8 *next_hop = NULL;
@@ -2448,42 +2343,19 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
- if (!rdev->ops->change_mpath) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
-
- err = rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop);
+ if (!rdev->ops->change_mpath)
+ return -EOPNOTSUPP;
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
+ return -EOPNOTSUPP;
- return err;
+ return rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop);
}
+
static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- int err;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
u8 *dst = NULL;
u8 *next_hop = NULL;
@@ -2496,75 +2368,34 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
- if (!rdev->ops->add_mpath) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
-
- err = rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop);
+ if (!rdev->ops->add_mpath)
+ return -EOPNOTSUPP;
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
+ return -EOPNOTSUPP;
- return err;
+ return rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop);
}
static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- int err;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
u8 *dst = NULL;
if (info->attrs[NL80211_ATTR_MAC])
dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
- if (!rdev->ops->del_mpath) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- err = rdev->ops->del_mpath(&rdev->wiphy, dev, dst);
-
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
+ if (!rdev->ops->del_mpath)
+ return -EOPNOTSUPP;
- return err;
+ return rdev->ops->del_mpath(&rdev->wiphy, dev, dst);
}
static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- int err;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct bss_parameters params;
memset(&params, 0, sizeof(params));
@@ -2592,31 +2423,14 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_AP_ISOLATE])
params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
- if (!rdev->ops->change_bss) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- err = rdev->ops->change_bss(&rdev->wiphy, dev, &params);
+ if (!rdev->ops->change_bss)
+ return -EOPNOTSUPP;
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EOPNOTSUPP;
- return err;
+ return rdev->ops->change_bss(&rdev->wiphy, dev, &params);
}
static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
@@ -2695,37 +2509,26 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
static int nl80211_get_mesh_params(struct sk_buff *skb,
struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct mesh_config cur_params;
int err;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
void *hdr;
struct nlattr *pinfoattr;
struct sk_buff *msg;
- rtnl_lock();
-
- /* Look up our device */
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
- if (!rdev->ops->get_mesh_params) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->get_mesh_params)
+ return -EOPNOTSUPP;
/* Get the mesh params */
err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params);
if (err)
- goto out;
+ return err;
/* Draw up a netlink message to send back */
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg) {
- err = -ENOBUFS;
- goto out;
- }
+ if (!msg)
+ return -ENOMEM;
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
NL80211_CMD_GET_MESH_PARAMS);
if (!hdr)
@@ -2764,21 +2567,12 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
cur_params.dot11MeshHWMPRootMode);
nla_nest_end(msg, pinfoattr);
genlmsg_end(msg, hdr);
- err = genlmsg_reply(msg, info);
- goto out;
+ return genlmsg_reply(msg, info);
nla_put_failure:
genlmsg_cancel(msg, hdr);
nlmsg_free(msg);
- err = -EMSGSIZE;
- out:
- /* Cleanup */
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
-
- return err;
+ return -ENOBUFS;
}
#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
@@ -2808,10 +2602,9 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
{
- int err;
u32 mask;
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct mesh_config cfg;
struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
struct nlattr *parent_attr;
@@ -2823,16 +2616,8 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
parent_attr, nl80211_meshconf_params_policy))
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
- if (!rdev->ops->set_mesh_params) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->set_mesh_params)
+ return -EOPNOTSUPP;
/* This makes sure that there aren't more than 32 mesh config
* parameters (otherwise our bitfield scheme would not work.) */
@@ -2878,16 +2663,7 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
nla_get_u8);
/* Apply changes */
- err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
-
- out:
- /* cleanup */
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
-
- return err;
+ return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
}
#undef FILL_IN_MESH_PARAM_IF_SET
@@ -3070,8 +2846,8 @@ static int validate_scan_freqs(struct nlattr *freqs)
static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct cfg80211_scan_request *request;
struct cfg80211_ssid *ssid;
struct ieee80211_channel *channel;
@@ -3084,36 +2860,19 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
wiphy = &rdev->wiphy;
- if (!rdev->ops->scan) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ if (!rdev->ops->scan)
+ return -EOPNOTSUPP;
- if (rdev->scan_req) {
- err = -EBUSY;
- goto out;
- }
+ if (rdev->scan_req)
+ return -EBUSY;
if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
n_channels = validate_scan_freqs(
info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
- if (!n_channels) {
- err = -EINVAL;
- goto out;
- }
+ if (!n_channels)
+ return -EINVAL;
} else {
n_channels = 0;
@@ -3126,29 +2885,23 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
n_ssids++;
- if (n_ssids > wiphy->max_scan_ssids) {
- err = -EINVAL;
- goto out;
- }
+ 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) {
- err = -EINVAL;
- goto out;
- }
+ 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) {
- err = -ENOMEM;
- goto out;
- }
+ if (!request)
+ return -ENOMEM;
if (n_ssids)
request->ssids = (void *)&request->channels[n_channels];
@@ -3236,18 +2989,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
if (!err) {
nl80211_send_scan_start(rdev, dev);
dev_hold(dev);
- }
-
+ } else {
out_free:
- if (err) {
rdev->scan_req = NULL;
kfree(request);
}
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
return err;
}
@@ -3306,6 +3052,7 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
}
switch (wdev->iftype) {
+ case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
if (intbss == wdev->current_bss)
NLA_PUT_U32(msg, NL80211_BSS_STATUS,
@@ -3343,25 +3090,12 @@ static int nl80211_dump_scan(struct sk_buff *skb,
struct net_device *dev;
struct cfg80211_internal_bss *scan;
struct wireless_dev *wdev;
- int ifidx = cb->args[0];
int start = cb->args[1], idx = 0;
int err;
- if (!ifidx)
- ifidx = nl80211_get_ifidx(cb);
- if (ifidx < 0)
- return ifidx;
- cb->args[0] = ifidx;
-
- dev = dev_get_by_index(sock_net(skb->sk), ifidx);
- if (!dev)
- return -ENODEV;
-
- rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
- if (IS_ERR(rdev)) {
- err = PTR_ERR(rdev);
- goto out_put_netdev;
- }
+ err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev);
+ if (err)
+ return err;
wdev = dev->ieee80211_ptr;
@@ -3377,21 +3111,17 @@ static int nl80211_dump_scan(struct sk_buff *skb,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
rdev, wdev, scan) < 0) {
idx--;
- goto out;
+ break;
}
}
- out:
spin_unlock_bh(&rdev->bss_lock);
wdev_unlock(wdev);
cb->args[1] = idx;
- err = skb->len;
- cfg80211_unlock_rdev(rdev);
- out_put_netdev:
- dev_put(dev);
+ nl80211_finish_netdev_dump(rdev);
- return err;
+ return skb->len;
}
static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
@@ -3421,6 +3151,23 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
if (survey->filled & SURVEY_INFO_NOISE_DBM)
NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE,
survey->noise);
+ if (survey->filled & SURVEY_INFO_IN_USE)
+ NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE);
+ if (survey->filled & SURVEY_INFO_CHANNEL_TIME)
+ NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
+ survey->channel_time);
+ if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
+ NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
+ survey->channel_time_busy);
+ if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
+ NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
+ survey->channel_time_ext_busy);
+ if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX)
+ NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
+ survey->channel_time_rx);
+ if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX)
+ NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
+ survey->channel_time_tx);
nla_nest_end(msg, infoattr);
@@ -3437,29 +3184,12 @@ static int nl80211_dump_survey(struct sk_buff *skb,
struct survey_info survey;
struct cfg80211_registered_device *dev;
struct net_device *netdev;
- int ifidx = cb->args[0];
int survey_idx = cb->args[1];
int res;
- if (!ifidx)
- ifidx = nl80211_get_ifidx(cb);
- if (ifidx < 0)
- return ifidx;
- cb->args[0] = ifidx;
-
- rtnl_lock();
-
- netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
- if (!netdev) {
- res = -ENODEV;
- goto out_rtnl;
- }
-
- dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
- if (IS_ERR(dev)) {
- res = PTR_ERR(dev);
- goto out_rtnl;
- }
+ res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
+ if (res)
+ return res;
if (!dev->ops->dump_survey) {
res = -EOPNOTSUPP;
@@ -3487,10 +3217,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
cb->args[1] = survey_idx;
res = skb->len;
out_err:
- cfg80211_unlock_rdev(dev);
- out_rtnl:
- rtnl_unlock();
-
+ nl80211_finish_netdev_dump(dev);
return res;
}
@@ -3523,8 +3250,8 @@ static bool nl80211_valid_cipher_suite(u32 cipher)
static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct ieee80211_channel *chan;
const u8 *bssid, *ssid, *ie = NULL;
int err, ssid_len, ie_len = 0;
@@ -3552,6 +3279,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
return err;
if (key.idx >= 0) {
+ if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
+ return -EINVAL;
if (!key.p.key || !key.p.key_len)
return -EINVAL;
if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
@@ -3566,34 +3295,31 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
key.p.key = NULL;
}
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->auth) {
- err = -EOPNOTSUPP;
- goto out;
+ if (key.idx >= 0) {
+ int i;
+ bool ok = false;
+ for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
+ if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
+ ok = true;
+ break;
+ }
+ }
+ if (!ok)
+ return -EINVAL;
}
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->auth)
+ return -EOPNOTSUPP;
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
chan = ieee80211_get_channel(&rdev->wiphy,
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
- if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) {
- err = -EINVAL;
- goto out;
- }
+ if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED))
+ return -EINVAL;
ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
@@ -3604,27 +3330,19 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
}
auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
- if (!nl80211_valid_auth_type(auth_type)) {
- err = -EINVAL;
- goto out;
- }
+ if (!nl80211_valid_auth_type(auth_type))
+ return -EINVAL;
local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
- err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
- ssid, ssid_len, ie, ie_len,
- key.p.key, key.p.key_len, key.idx,
- local_state_change);
-
-out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-unlock_rtnl:
- rtnl_unlock();
- return err;
+ return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
+ ssid, ssid_len, ie, ie_len,
+ key.p.key, key.p.key_len, key.idx,
+ local_state_change);
}
-static int nl80211_crypto_settings(struct genl_info *info,
+static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
+ struct genl_info *info,
struct cfg80211_crypto_settings *settings,
int cipher_limit)
{
@@ -3632,6 +3350,19 @@ static int nl80211_crypto_settings(struct genl_info *info,
settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
+ if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
+ u16 proto;
+ proto = nla_get_u16(
+ info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
+ settings->control_port_ethertype = cpu_to_be16(proto);
+ if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
+ proto != ETH_P_PAE)
+ return -EINVAL;
+ if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
+ settings->control_port_no_encrypt = true;
+ } else
+ settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
+
if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
void *data;
int len, i;
@@ -3691,8 +3422,8 @@ static int nl80211_crypto_settings(struct genl_info *info,
static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct cfg80211_crypto_settings crypto;
struct ieee80211_channel *chan;
const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
@@ -3707,35 +3438,19 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
!info->attrs[NL80211_ATTR_WIPHY_FREQ])
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->assoc) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->assoc)
+ return -EOPNOTSUPP;
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
chan = ieee80211_get_channel(&rdev->wiphy,
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
- if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) {
- err = -EINVAL;
- goto out;
- }
+ if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED))
+ return -EINVAL;
ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
@@ -3750,35 +3465,28 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
if (mfp == NL80211_MFP_REQUIRED)
use_mfp = true;
- else if (mfp != NL80211_MFP_NO) {
- err = -EINVAL;
- goto out;
- }
+ else if (mfp != NL80211_MFP_NO)
+ return -EINVAL;
}
if (info->attrs[NL80211_ATTR_PREV_BSSID])
prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
- err = nl80211_crypto_settings(info, &crypto, 1);
+ err = nl80211_crypto_settings(rdev, info, &crypto, 1);
if (!err)
err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
ssid, ssid_len, ie, ie_len, use_mfp,
&crypto);
-out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-unlock_rtnl:
- rtnl_unlock();
return err;
}
static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
const u8 *ie = NULL, *bssid;
- int err, ie_len = 0;
+ int ie_len = 0;
u16 reason_code;
bool local_state_change;
@@ -3791,34 +3499,19 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
if (!info->attrs[NL80211_ATTR_REASON_CODE])
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->deauth) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->deauth)
+ return -EOPNOTSUPP;
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
if (reason_code == 0) {
/* Reason Code 0 is reserved */
- err = -EINVAL;
- goto out;
+ return -EINVAL;
}
if (info->attrs[NL80211_ATTR_IE]) {
@@ -3828,23 +3521,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
- err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
- local_state_change);
-
-out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-unlock_rtnl:
- rtnl_unlock();
- return err;
+ return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
+ local_state_change);
}
static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
const u8 *ie = NULL, *bssid;
- int err, ie_len = 0;
+ int ie_len = 0;
u16 reason_code;
bool local_state_change;
@@ -3857,34 +3543,19 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
if (!info->attrs[NL80211_ATTR_REASON_CODE])
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->disassoc) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->disassoc)
+ return -EOPNOTSUPP;
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
if (reason_code == 0) {
/* Reason Code 0 is reserved */
- err = -EINVAL;
- goto out;
+ return -EINVAL;
}
if (info->attrs[NL80211_ATTR_IE]) {
@@ -3894,21 +3565,14 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
- err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
- local_state_change);
-
-out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-unlock_rtnl:
- rtnl_unlock();
- return err;
+ return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
+ local_state_change);
}
static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct cfg80211_ibss_params ibss;
struct wiphy *wiphy;
struct cfg80211_cached_keys *connkeys = NULL;
@@ -3933,26 +3597,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
}
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->join_ibss) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->join_ibss)
+ return -EOPNOTSUPP;
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+ return -EOPNOTSUPP;
wiphy = &rdev->wiphy;
@@ -3970,24 +3619,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
if (!ibss.channel ||
ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
- ibss.channel->flags & IEEE80211_CHAN_DISABLED) {
- err = -EINVAL;
- goto out;
- }
+ ibss.channel->flags & IEEE80211_CHAN_DISABLED)
+ return -EINVAL;
ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
- if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
- connkeys = nl80211_parse_connkeys(rdev,
- info->attrs[NL80211_ATTR_KEYS]);
- if (IS_ERR(connkeys)) {
- err = PTR_ERR(connkeys);
- connkeys = NULL;
- goto out;
- }
- }
-
if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
u8 *rates =
nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
@@ -3997,10 +3634,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
wiphy->bands[ibss.channel->band];
int i, j;
- if (n_rates == 0) {
- err = -EINVAL;
- goto out;
- }
+ if (n_rates == 0)
+ return -EINVAL;
for (i = 0; i < n_rates; i++) {
int rate = (rates[i] & 0x7f) * 5;
@@ -4013,77 +3648,36 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
break;
}
}
- if (!found) {
- err = -EINVAL;
- goto out;
- }
- }
- } else {
- /*
- * If no rates were explicitly configured,
- * use the mandatory rate set for 11b or
- * 11a for maximum compatibility.
- */
- struct ieee80211_supported_band *sband =
- wiphy->bands[ibss.channel->band];
- int j;
- u32 flag = ibss.channel->band == IEEE80211_BAND_5GHZ ?
- IEEE80211_RATE_MANDATORY_A :
- IEEE80211_RATE_MANDATORY_B;
-
- for (j = 0; j < sband->n_bitrates; j++) {
- if (sband->bitrates[j].flags & flag)
- ibss.basic_rates |= BIT(j);
+ if (!found)
+ return -EINVAL;
}
}
- err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
+ if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
+ connkeys = nl80211_parse_connkeys(rdev,
+ info->attrs[NL80211_ATTR_KEYS]);
+ if (IS_ERR(connkeys))
+ return PTR_ERR(connkeys);
+ }
-out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-unlock_rtnl:
+ err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
if (err)
kfree(connkeys);
- rtnl_unlock();
return err;
}
static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
- int err;
-
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->leave_ibss) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ if (!rdev->ops->leave_ibss)
+ return -EOPNOTSUPP;
- err = cfg80211_leave_ibss(rdev, dev, false);
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+ return -EOPNOTSUPP;
-out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-unlock_rtnl:
- rtnl_unlock();
- return err;
+ return cfg80211_leave_ibss(rdev, dev, false);
}
#ifdef CONFIG_NL80211_TESTMODE
@@ -4093,20 +3687,12 @@ static struct genl_multicast_group nl80211_testmode_mcgrp = {
static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
int err;
if (!info->attrs[NL80211_ATTR_TESTDATA])
return -EINVAL;
- rtnl_lock();
-
- rdev = cfg80211_get_dev_from_info(info);
- if (IS_ERR(rdev)) {
- err = PTR_ERR(rdev);
- goto unlock_rtnl;
- }
-
err = -EOPNOTSUPP;
if (rdev->ops->testmode_cmd) {
rdev->testmode_info = info;
@@ -4116,10 +3702,6 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
rdev->testmode_info = NULL;
}
- cfg80211_unlock_rdev(rdev);
-
- unlock_rtnl:
- rtnl_unlock();
return err;
}
@@ -4210,8 +3792,8 @@ EXPORT_SYMBOL(cfg80211_testmode_event);
static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct cfg80211_connect_params connect;
struct wiphy *wiphy;
struct cfg80211_cached_keys *connkeys = NULL;
@@ -4236,25 +3818,14 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
- err = nl80211_crypto_settings(info, &connect.crypto,
+ err = nl80211_crypto_settings(rdev, info, &connect.crypto,
NL80211_MAX_NR_CIPHER_SUITES);
if (err)
return err;
- rtnl_lock();
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
wiphy = &rdev->wiphy;
@@ -4273,39 +3844,27 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
ieee80211_get_channel(wiphy,
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
if (!connect.channel ||
- connect.channel->flags & IEEE80211_CHAN_DISABLED) {
- err = -EINVAL;
- goto out;
- }
+ connect.channel->flags & IEEE80211_CHAN_DISABLED)
+ return -EINVAL;
}
if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
connkeys = nl80211_parse_connkeys(rdev,
info->attrs[NL80211_ATTR_KEYS]);
- if (IS_ERR(connkeys)) {
- err = PTR_ERR(connkeys);
- connkeys = NULL;
- goto out;
- }
+ if (IS_ERR(connkeys))
+ return PTR_ERR(connkeys);
}
err = cfg80211_connect(rdev, dev, &connect, connkeys);
-
-out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-unlock_rtnl:
if (err)
kfree(connkeys);
- rtnl_unlock();
return err;
}
static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
- int err;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
u16 reason;
if (!info->attrs[NL80211_ATTR_REASON_CODE])
@@ -4316,35 +3875,16 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
if (reason == 0)
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
-
- err = cfg80211_disconnect(rdev, dev, reason, true);
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
-out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-unlock_rtnl:
- rtnl_unlock();
- return err;
+ return cfg80211_disconnect(rdev, dev, reason, true);
}
static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net *net;
int err;
u32 pid;
@@ -4354,43 +3894,26 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
- rtnl_lock();
-
- rdev = cfg80211_get_dev_from_info(info);
- if (IS_ERR(rdev)) {
- err = PTR_ERR(rdev);
- goto out_rtnl;
- }
-
net = get_net_ns_by_pid(pid);
- if (IS_ERR(net)) {
- err = PTR_ERR(net);
- goto out;
- }
+ if (IS_ERR(net))
+ return PTR_ERR(net);
err = 0;
/* check if anything to do */
- if (net_eq(wiphy_net(&rdev->wiphy), net))
- goto out_put_net;
+ if (!net_eq(wiphy_net(&rdev->wiphy), net))
+ err = cfg80211_switch_netns(rdev, net);
- err = cfg80211_switch_netns(rdev, net);
- out_put_net:
put_net(net);
- out:
- cfg80211_unlock_rdev(rdev);
- out_rtnl:
- rtnl_unlock();
return err;
}
static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_pmksa *pmksa) = NULL;
- int err;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
struct cfg80211_pmksa pmksa;
memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
@@ -4401,19 +3924,12 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
if (!info->attrs[NL80211_ATTR_PMKID])
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
switch (info->genlhdr->cmd) {
case NL80211_CMD_SET_PMKSA:
@@ -4427,61 +3943,32 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
break;
}
- if (!rdev_ops) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- err = rdev_ops(&rdev->wiphy, dev, &pmksa);
-
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
+ if (!rdev_ops)
+ return -EOPNOTSUPP;
- return err;
+ return rdev_ops(&rdev->wiphy, dev, &pmksa);
}
static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- int err;
- struct net_device *dev;
-
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto out_rtnl;
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (!rdev->ops->flush_pmksa) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- err = rdev->ops->flush_pmksa(&rdev->wiphy, dev);
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- out_rtnl:
- rtnl_unlock();
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
- return err;
+ if (!rdev->ops->flush_pmksa)
+ return -EOPNOTSUPP;
+ return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
}
static int nl80211_remain_on_channel(struct sk_buff *skb,
struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct ieee80211_channel *chan;
struct sk_buff *msg;
void *hdr;
@@ -4503,21 +3990,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
if (!duration || !msecs_to_jiffies(duration) || duration > 5000)
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->remain_on_channel) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ if (!rdev->ops->remain_on_channel)
+ return -EOPNOTSUPP;
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
channel_type = nla_get_u32(
@@ -4525,24 +3999,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
if (channel_type != NL80211_CHAN_NO_HT &&
channel_type != NL80211_CHAN_HT20 &&
channel_type != NL80211_CHAN_HT40PLUS &&
- channel_type != NL80211_CHAN_HT40MINUS) {
- err = -EINVAL;
- goto out;
- }
+ channel_type != NL80211_CHAN_HT40MINUS)
+ return -EINVAL;
}
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
chan = rdev_freq_to_chan(rdev, freq, channel_type);
- if (chan == NULL) {
- err = -EINVAL;
- goto out;
- }
+ if (chan == NULL)
+ return -EINVAL;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg) {
- err = -ENOMEM;
- goto out;
- }
+ if (!msg)
+ return -ENOMEM;
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
NL80211_CMD_REMAIN_ON_CHANNEL);
@@ -4561,58 +4029,32 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
genlmsg_end(msg, hdr);
- err = genlmsg_reply(msg, info);
- goto out;
+
+ return genlmsg_reply(msg, info);
nla_put_failure:
err = -ENOBUFS;
free_msg:
nlmsg_free(msg);
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- unlock_rtnl:
- rtnl_unlock();
return err;
}
static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
u64 cookie;
- int err;
if (!info->attrs[NL80211_ATTR_COOKIE])
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->cancel_remain_on_channel) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ if (!rdev->ops->cancel_remain_on_channel)
+ return -EOPNOTSUPP;
cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
- err = rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie);
-
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- unlock_rtnl:
- rtnl_unlock();
- return err;
+ return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie);
}
static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
@@ -4648,26 +4090,18 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
struct genl_info *info)
{
struct nlattr *tb[NL80211_TXRATE_MAX + 1];
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct cfg80211_bitrate_mask mask;
- int err, rem, i;
- struct net_device *dev;
+ int rem, i;
+ struct net_device *dev = info->user_ptr[1];
struct nlattr *tx_rates;
struct ieee80211_supported_band *sband;
if (info->attrs[NL80211_ATTR_TX_RATES] == NULL)
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->set_bitrate_mask) {
- err = -EOPNOTSUPP;
- goto unlock;
- }
+ if (!rdev->ops->set_bitrate_mask)
+ return -EOPNOTSUPP;
memset(&mask, 0, sizeof(mask));
/* Default to all rates enabled */
@@ -4684,15 +4118,11 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
{
enum ieee80211_band band = nla_type(tx_rates);
- if (band < 0 || band >= IEEE80211_NUM_BANDS) {
- err = -EINVAL;
- goto unlock;
- }
+ if (band < 0 || band >= IEEE80211_NUM_BANDS)
+ return -EINVAL;
sband = rdev->wiphy.bands[band];
- if (sband == NULL) {
- err = -EINVAL;
- goto unlock;
- }
+ if (sband == NULL)
+ return -EINVAL;
nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
nla_len(tx_rates), nl80211_txattr_policy);
if (tb[NL80211_TXRATE_LEGACY]) {
@@ -4700,68 +4130,48 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
sband,
nla_data(tb[NL80211_TXRATE_LEGACY]),
nla_len(tb[NL80211_TXRATE_LEGACY]));
- if (mask.control[band].legacy == 0) {
- err = -EINVAL;
- goto unlock;
- }
+ if (mask.control[band].legacy == 0)
+ return -EINVAL;
}
}
- err = rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask);
-
- unlock:
- dev_put(dev);
- cfg80211_unlock_rdev(rdev);
- unlock_rtnl:
- rtnl_unlock();
- return err;
+ return rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask);
}
-static int nl80211_register_action(struct sk_buff *skb, struct genl_info *info)
+static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
- int err;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
return -EINVAL;
- if (nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]) < 1)
- return -EINVAL;
-
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
+ if (info->attrs[NL80211_ATTR_FRAME_TYPE])
+ frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
- dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EOPNOTSUPP;
/* not much point in registering if we can't reply */
- if (!rdev->ops->action) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->mgmt_tx)
+ return -EOPNOTSUPP;
- err = cfg80211_mlme_register_action(dev->ieee80211_ptr, info->snd_pid,
+ return cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid,
+ frame_type,
nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- unlock_rtnl:
- rtnl_unlock();
- return err;
}
-static int nl80211_action(struct sk_buff *skb, struct genl_info *info)
+static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
- struct net_device *dev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
struct ieee80211_channel *chan;
enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
bool channel_type_valid = false;
@@ -4775,27 +4185,16 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info)
!info->attrs[NL80211_ATTR_WIPHY_FREQ])
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
- if (!rdev->ops->action) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->mgmt_tx)
+ return -EOPNOTSUPP;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
- dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EOPNOTSUPP;
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
channel_type = nla_get_u32(
@@ -4803,147 +4202,104 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info)
if (channel_type != NL80211_CHAN_NO_HT &&
channel_type != NL80211_CHAN_HT20 &&
channel_type != NL80211_CHAN_HT40PLUS &&
- channel_type != NL80211_CHAN_HT40MINUS) {
- err = -EINVAL;
- goto out;
- }
+ channel_type != NL80211_CHAN_HT40MINUS)
+ return -EINVAL;
channel_type_valid = true;
}
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
chan = rdev_freq_to_chan(rdev, freq, channel_type);
- if (chan == NULL) {
- err = -EINVAL;
- goto out;
- }
+ if (chan == NULL)
+ return -EINVAL;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg) {
- err = -ENOMEM;
- goto out;
- }
+ if (!msg)
+ return -ENOMEM;
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
- NL80211_CMD_ACTION);
+ NL80211_CMD_FRAME);
if (IS_ERR(hdr)) {
err = PTR_ERR(hdr);
goto free_msg;
}
- err = cfg80211_mlme_action(rdev, dev, chan, channel_type,
- channel_type_valid,
- nla_data(info->attrs[NL80211_ATTR_FRAME]),
- nla_len(info->attrs[NL80211_ATTR_FRAME]),
- &cookie);
+ err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, channel_type,
+ channel_type_valid,
+ nla_data(info->attrs[NL80211_ATTR_FRAME]),
+ nla_len(info->attrs[NL80211_ATTR_FRAME]),
+ &cookie);
if (err)
goto free_msg;
NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
genlmsg_end(msg, hdr);
- err = genlmsg_reply(msg, info);
- goto out;
+ return genlmsg_reply(msg, info);
nla_put_failure:
err = -ENOBUFS;
free_msg:
nlmsg_free(msg);
- out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-unlock_rtnl:
- rtnl_unlock();
return err;
}
static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
u8 ps_state;
bool state;
int err;
- if (!info->attrs[NL80211_ATTR_PS_STATE]) {
- err = -EINVAL;
- goto out;
- }
+ if (!info->attrs[NL80211_ATTR_PS_STATE])
+ return -EINVAL;
ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
- if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED) {
- err = -EINVAL;
- goto out;
- }
-
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rdev;
+ if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
+ return -EINVAL;
wdev = dev->ieee80211_ptr;
- if (!rdev->ops->set_power_mgmt) {
- err = -EOPNOTSUPP;
- goto unlock_rdev;
- }
+ if (!rdev->ops->set_power_mgmt)
+ return -EOPNOTSUPP;
state = (ps_state == NL80211_PS_ENABLED) ? true : false;
if (state == wdev->ps)
- goto unlock_rdev;
-
- wdev->ps = state;
-
- if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, wdev->ps,
- wdev->ps_timeout))
- /* assume this means it's off */
- wdev->ps = false;
-
-unlock_rdev:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- rtnl_unlock();
+ return 0;
-out:
+ err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, state,
+ wdev->ps_timeout);
+ if (!err)
+ wdev->ps = state;
return err;
}
static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
enum nl80211_ps_state ps_state;
struct wireless_dev *wdev;
- struct net_device *dev;
+ struct net_device *dev = info->user_ptr[1];
struct sk_buff *msg;
void *hdr;
int err;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rtnl;
-
wdev = dev->ieee80211_ptr;
- if (!rdev->ops->set_power_mgmt) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->set_power_mgmt)
+ return -EOPNOTSUPP;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg) {
- err = -ENOMEM;
- goto out;
- }
+ if (!msg)
+ return -ENOMEM;
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
NL80211_CMD_GET_POWER_SAVE);
if (!hdr) {
- err = -ENOMEM;
+ err = -ENOBUFS;
goto free_msg;
}
@@ -4955,22 +4311,12 @@ static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);
genlmsg_end(msg, hdr);
- err = genlmsg_reply(msg, info);
- goto out;
+ return genlmsg_reply(msg, info);
-nla_put_failure:
+ nla_put_failure:
err = -ENOBUFS;
-
-free_msg:
+ free_msg:
nlmsg_free(msg);
-
-out:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
-
-unlock_rtnl:
- rtnl_unlock();
-
return err;
}
@@ -4984,41 +4330,24 @@ nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = {
static int nl80211_set_cqm_rssi(struct genl_info *info,
s32 threshold, u32 hysteresis)
{
- struct cfg80211_registered_device *rdev;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev;
- struct net_device *dev;
- int err;
+ struct net_device *dev = info->user_ptr[1];
if (threshold > 0)
return -EINVAL;
- rtnl_lock();
-
- err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
- if (err)
- goto unlock_rdev;
-
wdev = dev->ieee80211_ptr;
- if (!rdev->ops->set_cqm_rssi_config) {
- err = -EOPNOTSUPP;
- goto unlock_rdev;
- }
-
- if (wdev->iftype != NL80211_IFTYPE_STATION) {
- err = -EOPNOTSUPP;
- goto unlock_rdev;
- }
-
- err = rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev,
- threshold, hysteresis);
+ if (!rdev->ops->set_cqm_rssi_config)
+ return -EOPNOTSUPP;
-unlock_rdev:
- cfg80211_unlock_rdev(rdev);
- dev_put(dev);
- rtnl_unlock();
+ if (wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
- return err;
+ return rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev,
+ threshold, hysteresis);
}
static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
@@ -5052,6 +4381,65 @@ out:
return err;
}
+#define NL80211_FLAG_NEED_WIPHY 0x01
+#define NL80211_FLAG_NEED_NETDEV 0x02
+#define NL80211_FLAG_NEED_RTNL 0x04
+#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
+#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
+ NL80211_FLAG_CHECK_NETDEV_UP)
+
+static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev;
+ struct net_device *dev;
+ int err;
+ bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
+
+ if (rtnl)
+ rtnl_lock();
+
+ if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
+ rdev = cfg80211_get_dev_from_info(info);
+ if (IS_ERR(rdev)) {
+ if (rtnl)
+ rtnl_unlock();
+ return PTR_ERR(rdev);
+ }
+ info->user_ptr[0] = rdev;
+ } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
+ err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
+ if (err) {
+ if (rtnl)
+ rtnl_unlock();
+ return err;
+ }
+ if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
+ !netif_running(dev)) {
+ cfg80211_unlock_rdev(rdev);
+ dev_put(dev);
+ if (rtnl)
+ rtnl_unlock();
+ return -ENETDOWN;
+ }
+ info->user_ptr[0] = rdev;
+ info->user_ptr[1] = dev;
+ }
+
+ return 0;
+}
+
+static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
+ struct genl_info *info)
+{
+ if (info->user_ptr[0])
+ cfg80211_unlock_rdev(info->user_ptr[0]);
+ if (info->user_ptr[1])
+ dev_put(info->user_ptr[1]);
+ if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
+ rtnl_unlock();
+}
+
static struct genl_ops nl80211_ops[] = {
{
.cmd = NL80211_CMD_GET_WIPHY,
@@ -5059,12 +4447,14 @@ static struct genl_ops nl80211_ops[] = {
.dumpit = nl80211_dump_wiphy,
.policy = nl80211_policy,
/* can be retrieved by unprivileged users */
+ .internal_flags = NL80211_FLAG_NEED_WIPHY,
},
{
.cmd = NL80211_CMD_SET_WIPHY,
.doit = nl80211_set_wiphy,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_GET_INTERFACE,
@@ -5072,90 +4462,119 @@ static struct genl_ops nl80211_ops[] = {
.dumpit = nl80211_dump_interface,
.policy = nl80211_policy,
/* can be retrieved by unprivileged users */
+ .internal_flags = NL80211_FLAG_NEED_NETDEV,
},
{
.cmd = NL80211_CMD_SET_INTERFACE,
.doit = nl80211_set_interface,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_NEW_INTERFACE,
.doit = nl80211_new_interface,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_DEL_INTERFACE,
.doit = nl80211_del_interface,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_GET_KEY,
.doit = nl80211_get_key,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_KEY,
.doit = nl80211_set_key,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_NEW_KEY,
.doit = nl80211_new_key,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_DEL_KEY,
.doit = nl80211_del_key,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_BEACON,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.doit = nl80211_addset_beacon,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_NEW_BEACON,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.doit = nl80211_addset_beacon,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_DEL_BEACON,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.doit = nl80211_del_beacon,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_GET_STATION,
.doit = nl80211_get_station,
.dumpit = nl80211_dump_station,
.policy = nl80211_policy,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_STATION,
.doit = nl80211_set_station,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_NEW_STATION,
.doit = nl80211_new_station,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_DEL_STATION,
.doit = nl80211_del_station,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_GET_MPATH,
@@ -5163,30 +4582,40 @@ static struct genl_ops nl80211_ops[] = {
.dumpit = nl80211_dump_mpath,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_MPATH,
.doit = nl80211_set_mpath,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_NEW_MPATH,
.doit = nl80211_new_mpath,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_DEL_MPATH,
.doit = nl80211_del_mpath,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_BSS,
.doit = nl80211_set_bss,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_GET_REG,
@@ -5211,18 +4640,24 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_get_mesh_params,
.policy = nl80211_policy,
/* can be retrieved by unprivileged users */
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_MESH_PARAMS,
.doit = nl80211_set_mesh_params,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_TRIGGER_SCAN,
.doit = nl80211_trigger_scan,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_GET_SCAN,
@@ -5234,36 +4669,48 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_authenticate,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_ASSOCIATE,
.doit = nl80211_associate,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_DEAUTHENTICATE,
.doit = nl80211_deauthenticate,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_DISASSOCIATE,
.doit = nl80211_disassociate,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_JOIN_IBSS,
.doit = nl80211_join_ibss,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_LEAVE_IBSS,
.doit = nl80211_leave_ibss,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
#ifdef CONFIG_NL80211_TESTMODE
{
@@ -5271,6 +4718,8 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_testmode_do,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
+ NL80211_FLAG_NEED_RTNL,
},
#endif
{
@@ -5278,18 +4727,24 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_connect,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_DISCONNECT,
.doit = nl80211_disconnect,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_WIPHY_NETNS,
.doit = nl80211_wiphy_netns,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_GET_SURVEY,
@@ -5301,72 +4756,104 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_setdel_pmksa,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_DEL_PMKSA,
.doit = nl80211_setdel_pmksa,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_FLUSH_PMKSA,
.doit = nl80211_flush_pmksa,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
.doit = nl80211_remain_on_channel,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
.doit = nl80211_cancel_remain_on_channel,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
.doit = nl80211_set_tx_bitrate_mask,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
- .cmd = NL80211_CMD_REGISTER_ACTION,
- .doit = nl80211_register_action,
+ .cmd = NL80211_CMD_REGISTER_FRAME,
+ .doit = nl80211_register_mgmt,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
- .cmd = NL80211_CMD_ACTION,
- .doit = nl80211_action,
+ .cmd = NL80211_CMD_FRAME,
+ .doit = nl80211_tx_mgmt,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_POWER_SAVE,
.doit = nl80211_set_power_save,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_GET_POWER_SAVE,
.doit = nl80211_get_power_save,
.policy = nl80211_policy,
/* can be retrieved by unprivileged users */
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_CQM,
.doit = nl80211_set_cqm,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_SET_CHANNEL,
.doit = nl80211_set_channel,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
+ .cmd = NL80211_CMD_SET_WDS_PEER,
+ .doit = nl80211_set_wds_peer,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
},
};
@@ -6040,9 +5527,9 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
nl80211_mlme_mcgrp.id, gfp);
}
-int nl80211_send_action(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, u32 nlpid,
- int freq, const u8 *buf, size_t len, gfp_t gfp)
+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)
{
struct sk_buff *msg;
void *hdr;
@@ -6052,7 +5539,7 @@ int nl80211_send_action(struct cfg80211_registered_device *rdev,
if (!msg)
return -ENOMEM;
- hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ACTION);
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
if (!hdr) {
nlmsg_free(msg);
return -ENOMEM;
@@ -6080,10 +5567,10 @@ int nl80211_send_action(struct cfg80211_registered_device *rdev,
return -ENOBUFS;
}
-void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, u64 cookie,
- const u8 *buf, size_t len, bool ack,
- gfp_t gfp)
+void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, u64 cookie,
+ const u8 *buf, size_t len, bool ack,
+ gfp_t gfp)
{
struct sk_buff *msg;
void *hdr;
@@ -6092,7 +5579,7 @@ void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev,
if (!msg)
return;
- hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ACTION_TX_STATUS);
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
if (!hdr) {
nlmsg_free(msg);
return;
@@ -6179,7 +5666,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list)
list_for_each_entry_rcu(wdev, &rdev->netdev_list, list)
- cfg80211_mlme_unregister_actions(wdev, notify->pid);
+ cfg80211_mlme_unregister_socket(wdev, notify->pid);
rcu_read_unlock();
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 2ad7fbc7d9f1..30d2f939150d 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -74,13 +74,13 @@ 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);
-int nl80211_send_action(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, u32 nlpid, int freq,
- const u8 *buf, size_t len, gfp_t gfp);
-void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, u64 cookie,
- const u8 *buf, size_t len, bool ack,
- gfp_t gfp);
+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);
+void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, u64 cookie,
+ const u8 *buf, size_t len, bool ack,
+ gfp_t gfp);
void
nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index 1332c445d1c7..dbe35e138e94 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -14,6 +14,7 @@
* See COPYING for more details.
*/
+#include <linux/kernel.h>
#include <net/cfg80211.h>
#include <net/ieee80211_radiotap.h>
#include <asm/unaligned.h>
@@ -45,7 +46,7 @@ static const struct radiotap_align_size rtap_namespace_sizes[] = {
};
static const struct ieee80211_radiotap_namespace radiotap_ns = {
- .n_bits = sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]),
+ .n_bits = ARRAY_SIZE(rtap_namespace_sizes),
.align_size = rtap_namespace_sizes,
};
@@ -200,7 +201,7 @@ int ieee80211_radiotap_iterator_next(
{
while (1) {
int hit = 0;
- int pad, align, size, subns, vnslen;
+ int pad, align, size, subns;
uint32_t oui;
/* if no more EXT bits, that's it */
@@ -260,6 +261,27 @@ int ieee80211_radiotap_iterator_next(
if (pad)
iterator->_arg += align - pad;
+ if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
+ int vnslen;
+
+ if ((unsigned long)iterator->_arg + size -
+ (unsigned long)iterator->_rtheader >
+ (unsigned long)iterator->_max_length)
+ return -EINVAL;
+
+ oui = (*iterator->_arg << 16) |
+ (*(iterator->_arg + 1) << 8) |
+ *(iterator->_arg + 2);
+ subns = *(iterator->_arg + 3);
+
+ find_ns(iterator, oui, subns);
+
+ vnslen = get_unaligned_le16(iterator->_arg + 4);
+ iterator->_next_ns_data = iterator->_arg + size + vnslen;
+ if (!iterator->current_namespace)
+ size += vnslen;
+ }
+
/*
* this is what we will return to user, but we need to
* move on first so next call has something fresh to test
@@ -286,40 +308,25 @@ int ieee80211_radiotap_iterator_next(
/* these special ones are valid in each bitmap word */
switch (iterator->_arg_index % 32) {
case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
- iterator->_bitmap_shifter >>= 1;
- iterator->_arg_index++;
-
iterator->_reset_on_ext = 1;
- vnslen = get_unaligned_le16(iterator->this_arg + 4);
- iterator->_next_ns_data = iterator->_arg + vnslen;
- oui = (*iterator->this_arg << 16) |
- (*(iterator->this_arg + 1) << 8) |
- *(iterator->this_arg + 2);
- subns = *(iterator->this_arg + 3);
-
- find_ns(iterator, oui, subns);
-
iterator->is_radiotap_ns = 0;
- /* allow parsers to show this information */
+ /*
+ * If parser didn't register this vendor
+ * namespace with us, allow it to show it
+ * as 'raw. Do do that, set argument index
+ * to vendor namespace.
+ */
iterator->this_arg_index =
IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
- iterator->this_arg_size += vnslen;
- if ((unsigned long)iterator->this_arg +
- iterator->this_arg_size -
- (unsigned long)iterator->_rtheader >
- (unsigned long)(unsigned long)iterator->_max_length)
- return -EINVAL;
- hit = 1;
- break;
+ if (!iterator->current_namespace)
+ hit = 1;
+ goto next_entry;
case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
- iterator->_bitmap_shifter >>= 1;
- iterator->_arg_index++;
-
iterator->_reset_on_ext = 1;
iterator->current_namespace = &radiotap_ns;
iterator->is_radiotap_ns = 1;
- break;
+ goto next_entry;
case IEEE80211_RADIOTAP_EXT:
/*
* bit 31 was set, there is more
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index f180db0de66c..d14bbf960c18 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -36,6 +36,7 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/random.h>
+#include <linux/ctype.h>
#include <linux/nl80211.h>
#include <linux/platform_device.h>
#include <net/cfg80211.h>
@@ -73,7 +74,11 @@ const struct ieee80211_regdomain *cfg80211_regdomain;
* - last_request
*/
static DEFINE_MUTEX(reg_mutex);
-#define assert_reg_lock() WARN_ON(!mutex_is_locked(&reg_mutex))
+
+static inline void assert_reg_lock(void)
+{
+ lockdep_assert_held(&reg_mutex);
+}
/* Used to queue up regulatory hints */
static LIST_HEAD(reg_requests_list);
@@ -181,14 +186,6 @@ static bool is_alpha2_set(const char *alpha2)
return false;
}
-static bool is_alpha_upper(char letter)
-{
- /* ASCII A - Z */
- if (letter >= 65 && letter <= 90)
- return true;
- return false;
-}
-
static bool is_unknown_alpha2(const char *alpha2)
{
if (!alpha2)
@@ -220,7 +217,7 @@ static bool is_an_alpha2(const char *alpha2)
{
if (!alpha2)
return false;
- if (is_alpha_upper(alpha2[0]) && is_alpha_upper(alpha2[1]))
+ if (isalpha(alpha2[0]) && isalpha(alpha2[1]))
return true;
return false;
}
@@ -1399,6 +1396,11 @@ static DECLARE_WORK(reg_work, reg_todo);
static void queue_regulatory_request(struct regulatory_request *request)
{
+ if (isalpha(request->alpha2[0]))
+ request->alpha2[0] = toupper(request->alpha2[0]);
+ if (isalpha(request->alpha2[1]))
+ request->alpha2[1] = toupper(request->alpha2[1]);
+
spin_lock(&reg_requests_lock);
list_add_tail(&request->list, &reg_requests_list);
spin_unlock(&reg_requests_lock);
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 5ca8c7180141..503ebb86ba18 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -650,14 +650,14 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
bss = container_of(pub, struct cfg80211_internal_bss, pub);
spin_lock_bh(&dev->bss_lock);
+ if (!list_empty(&bss->list)) {
+ list_del_init(&bss->list);
+ dev->bss_generation++;
+ rb_erase(&bss->rbn, &dev->bss_tree);
- list_del(&bss->list);
- dev->bss_generation++;
- rb_erase(&bss->rbn, &dev->bss_tree);
-
+ kref_put(&bss->ref, bss_release);
+ }
spin_unlock_bh(&dev->bss_lock);
-
- kref_put(&bss->ref, bss_release);
}
EXPORT_SYMBOL(cfg80211_unlink_bss);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index a8c2d6b877ae..e17b0bee6bdc 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -411,7 +411,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
ASSERT_WDEV_LOCK(wdev);
- if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
return;
if (wdev->sme_state != CFG80211_SME_CONNECTING)
@@ -548,7 +549,8 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
ASSERT_WDEV_LOCK(wdev);
- if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
return;
if (wdev->sme_state != CFG80211_SME_CONNECTED)
@@ -644,7 +646,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
ASSERT_WDEV_LOCK(wdev);
- if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
return;
if (wdev->sme_state != CFG80211_SME_CONNECTED)
@@ -695,7 +698,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
*/
if (rdev->ops->del_key)
for (i = 0; i < 6; i++)
- rdev->ops->del_key(wdev->wiphy, dev, i, NULL);
+ rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL);
#ifdef CONFIG_CFG80211_WEXT
memset(&wrqu, 0, sizeof(wrqu));
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 9f2cef3e0ca0..4294fa22bb2d 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -35,6 +35,14 @@ SHOW_FMT(index, "%d", wiphy_idx);
SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
+static ssize_t name_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf) {
+ struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
+ return sprintf(buf, "%s\n", dev_name(&wiphy->dev));
+}
+
+
static ssize_t addresses_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -57,6 +65,7 @@ static struct device_attribute ieee80211_dev_attrs[] = {
__ATTR_RO(macaddress),
__ATTR_RO(address_mask),
__ATTR_RO(addresses),
+ __ATTR_RO(name),
{}
};
@@ -110,6 +119,13 @@ static int wiphy_resume(struct device *dev)
return ret;
}
+static const void *wiphy_namespace(struct device *d)
+{
+ struct wiphy *wiphy = container_of(d, struct wiphy, dev);
+
+ return wiphy_net(wiphy);
+}
+
struct class ieee80211_class = {
.name = "ieee80211",
.owner = THIS_MODULE,
@@ -120,6 +136,8 @@ struct class ieee80211_class = {
#endif
.suspend = wiphy_suspend,
.resume = wiphy_resume,
+ .ns_type = &net_ns_type_operations,
+ .namespace = wiphy_namespace,
};
int wiphy_sysfs_init(void)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 0c8a1e8b7690..76120aeda57d 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -144,19 +144,25 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
struct key_params *params, int key_idx,
- const u8 *mac_addr)
+ bool pairwise, const u8 *mac_addr)
{
int i;
if (key_idx > 5)
return -EINVAL;
+ if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
+ return -EINVAL;
+
+ if (pairwise && !mac_addr)
+ return -EINVAL;
+
/*
* Disallow pairwise keys with non-zero index unless it's WEP
* (because current deployments use pairwise WEP keys with
* non-zero indizes but 802.11i clearly specifies to use zero)
*/
- if (mac_addr && key_idx &&
+ if (pairwise && key_idx &&
params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
params->cipher != WLAN_CIPHER_SUITE_WEP104)
return -EINVAL;
@@ -183,7 +189,14 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
return -EINVAL;
break;
default:
- return -EINVAL;
+ /*
+ * We don't know anything about this algorithm,
+ * allow using it -- but the driver must check
+ * all parameters! We still check below whether
+ * or not the driver supports this algorithm,
+ * of course.
+ */
+ break;
}
if (params->seq) {
@@ -221,7 +234,7 @@ const unsigned char bridge_tunnel_header[] __aligned(2) =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
EXPORT_SYMBOL(bridge_tunnel_header);
-unsigned int ieee80211_hdrlen(__le16 fc)
+unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc)
{
unsigned int hdrlen = 24;
@@ -319,7 +332,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
case cpu_to_le16(IEEE80211_FCTL_TODS):
if (unlikely(iftype != NL80211_IFTYPE_AP &&
- iftype != NL80211_IFTYPE_AP_VLAN))
+ iftype != NL80211_IFTYPE_AP_VLAN &&
+ iftype != NL80211_IFTYPE_P2P_GO))
return -1;
break;
case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
@@ -347,7 +361,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
break;
case cpu_to_le16(IEEE80211_FCTL_FROMDS):
if ((iftype != NL80211_IFTYPE_STATION &&
- iftype != NL80211_IFTYPE_MESH_POINT) ||
+ iftype != NL80211_IFTYPE_P2P_CLIENT &&
+ iftype != NL80211_IFTYPE_MESH_POINT) ||
(is_multicast_ether_addr(dst) &&
!compare_ether_addr(src, addr)))
return -1;
@@ -424,6 +439,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
switch (iftype) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_P2P_GO:
fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
/* DA BSSID SA */
memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -432,6 +448,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
hdrlen = 24;
break;
case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
/* BSSID SA DA */
memcpy(hdr.addr1, bssid, ETH_ALEN);
@@ -666,7 +683,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
for (i = 0; i < 6; i++) {
if (!wdev->connect_keys->params[i].cipher)
continue;
- if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL,
+ if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL,
&wdev->connect_keys->params[i])) {
printk(KERN_ERR "%s: failed to set key %d\n",
dev->name, i);
@@ -771,7 +788,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
/* if it's part of a bridge, reject changing type to station/ibss */
if ((dev->priv_flags & IFF_BRIDGE_PORT) &&
- (ntype == NL80211_IFTYPE_ADHOC || ntype == NL80211_IFTYPE_STATION))
+ (ntype == NL80211_IFTYPE_ADHOC ||
+ ntype == NL80211_IFTYPE_STATION ||
+ ntype == NL80211_IFTYPE_P2P_CLIENT))
return -EBUSY;
if (ntype != otype) {
@@ -782,6 +801,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
cfg80211_leave_ibss(rdev, dev, false);
break;
case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
cfg80211_disconnect(rdev, dev,
WLAN_REASON_DEAUTH_LEAVING, true);
break;
@@ -810,9 +830,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
if (dev->ieee80211_ptr->use_4addr)
break;
/* fall through */
+ case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_ADHOC:
dev->priv_flags |= IFF_DONT_BRIDGE;
break;
+ case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_WDS:
@@ -823,7 +845,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
/* monitor can't bridge anyway */
break;
case NL80211_IFTYPE_UNSPECIFIED:
- case __NL80211_IFTYPE_AFTER_LAST:
+ case NUM_NL80211_IFTYPES:
/* not happening */
break;
}
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 7e5c3a45f811..12222ee6ebf2 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -432,14 +432,17 @@ int cfg80211_wext_giwretry(struct net_device *dev,
EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);
static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
- struct net_device *dev, const u8 *addr,
- bool remove, bool tx_key, int idx,
- struct key_params *params)
+ struct net_device *dev, bool pairwise,
+ const u8 *addr, bool remove, bool tx_key,
+ int idx, struct key_params *params)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
int err, i;
bool rejoin = false;
+ if (pairwise && !addr)
+ return -EINVAL;
+
if (!wdev->wext.keys) {
wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
GFP_KERNEL);
@@ -478,7 +481,13 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
__cfg80211_leave_ibss(rdev, wdev->netdev, true);
rejoin = true;
}
- err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr);
+
+ if (!pairwise && addr &&
+ !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
+ err = -ENOENT;
+ else
+ err = rdev->ops->del_key(&rdev->wiphy, dev, idx,
+ pairwise, addr);
}
wdev->wext.connect.privacy = false;
/*
@@ -507,12 +516,13 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
if (addr)
tx_key = false;
- if (cfg80211_validate_key_settings(rdev, params, idx, addr))
+ if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr))
return -EINVAL;
err = 0;
if (wdev->current_bss)
- err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params);
+ err = rdev->ops->add_key(&rdev->wiphy, dev, idx,
+ pairwise, addr, params);
if (err)
return err;
@@ -563,17 +573,17 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
}
static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
- struct net_device *dev, const u8 *addr,
- bool remove, bool tx_key, int idx,
- struct key_params *params)
+ struct net_device *dev, bool pairwise,
+ const u8 *addr, bool remove, bool tx_key,
+ int idx, struct key_params *params)
{
int err;
/* devlist mutex needed for possible IBSS re-join */
mutex_lock(&rdev->devlist_mtx);
wdev_lock(dev->ieee80211_ptr);
- err = __cfg80211_set_encryption(rdev, dev, addr, remove,
- tx_key, idx, params);
+ err = __cfg80211_set_encryption(rdev, dev, pairwise, addr,
+ remove, tx_key, idx, params);
wdev_unlock(dev->ieee80211_ptr);
mutex_unlock(&rdev->devlist_mtx);
@@ -635,7 +645,7 @@ int cfg80211_wext_siwencode(struct net_device *dev,
else if (!remove)
return -EINVAL;
- return cfg80211_set_encryption(rdev, dev, NULL, remove,
+ return cfg80211_set_encryption(rdev, dev, false, NULL, remove,
wdev->wext.default_key == -1,
idx, &params);
}
@@ -725,7 +735,9 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
}
return cfg80211_set_encryption(
- rdev, dev, addr, remove,
+ rdev, dev,
+ !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY),
+ addr, remove,
ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
idx, &params);
}
@@ -1354,6 +1366,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
}
wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
+ if (sinfo.filled & STATION_INFO_RX_DROP_MISC)
+ wstats.discard.misc = sinfo.rx_dropped_misc;
+ if (sinfo.filled & STATION_INFO_TX_FAILED)
+ wstats.discard.retries = sinfo.tx_failed;
return &wstats;
}
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 8f5116f5af19..dc675a3daa3d 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -611,7 +611,7 @@ struct iw_statistics *get_wireless_stats(struct net_device *dev)
#endif
#ifdef CONFIG_CFG80211_WEXT
- if (dev->ieee80211_ptr && dev->ieee80211_ptr &&
+ if (dev->ieee80211_ptr &&
dev->ieee80211_ptr->wiphy &&
dev->ieee80211_ptr->wiphy->wext &&
dev->ieee80211_ptr->wiphy->wext->get_wireless_stats)
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 9818198add8a..6fffe62d7c25 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -197,6 +197,8 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
wdev->wext.connect.ssid_len = len;
wdev->wext.connect.crypto.control_port = false;
+ wdev->wext.connect.crypto.control_port_ethertype =
+ cpu_to_be16(ETH_P_PAE);
err = cfg80211_mgd_wext_connect(rdev, wdev);
out:
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 5e86d4e97dce..f7af98dff409 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -507,14 +507,14 @@ static int x25_listen(struct socket *sock, int backlog)
struct sock *sk = sock->sk;
int rc = -EOPNOTSUPP;
- lock_kernel();
+ lock_sock(sk);
if (sk->sk_state != TCP_LISTEN) {
memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN);
sk->sk_max_ack_backlog = backlog;
sk->sk_state = TCP_LISTEN;
rc = 0;
}
- unlock_kernel();
+ release_sock(sk);
return rc;
}
@@ -688,7 +688,6 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
int len, i, rc = 0;
- lock_kernel();
if (!sock_flag(sk, SOCK_ZAPPED) ||
addr_len != sizeof(struct sockaddr_x25) ||
addr->sx25_family != AF_X25) {
@@ -704,12 +703,13 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
}
}
+ lock_sock(sk);
x25_sk(sk)->source_addr = addr->sx25_addr;
x25_insert_socket(sk);
sock_reset_flag(sk, SOCK_ZAPPED);
+ release_sock(sk);
SOCK_DEBUG(sk, "x25_bind: socket is bound\n");
out:
- unlock_kernel();
return rc;
}
@@ -751,7 +751,6 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
struct x25_route *rt;
int rc = 0;
- lock_kernel();
lock_sock(sk);
if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
sock->state = SS_CONNECTED;
@@ -829,7 +828,6 @@ out_put_route:
x25_route_put(rt);
out:
release_sock(sk);
- unlock_kernel();
return rc;
}
@@ -869,8 +867,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
struct sk_buff *skb;
int rc = -EINVAL;
- lock_kernel();
- if (!sk || sk->sk_state != TCP_LISTEN)
+ if (!sk)
goto out;
rc = -EOPNOTSUPP;
@@ -878,6 +875,10 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
goto out;
lock_sock(sk);
+ rc = -EINVAL;
+ if (sk->sk_state != TCP_LISTEN)
+ goto out2;
+
rc = x25_wait_for_data(sk, sk->sk_rcvtimeo);
if (rc)
goto out2;
@@ -897,7 +898,6 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
out2:
release_sock(sk);
out:
- unlock_kernel();
return rc;
}
@@ -909,7 +909,6 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
struct x25_sock *x25 = x25_sk(sk);
int rc = 0;
- lock_kernel();
if (peer) {
if (sk->sk_state != TCP_ESTABLISHED) {
rc = -ENOTCONN;
@@ -923,19 +922,6 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
*uaddr_len = sizeof(*sx25);
out:
- unlock_kernel();
- return rc;
-}
-
-static unsigned int x25_datagram_poll(struct file *file, struct socket *sock,
- poll_table *wait)
-{
- int rc;
-
- lock_kernel();
- rc = datagram_poll(file, sock, wait);
- unlock_kernel();
-
return rc;
}
@@ -1746,7 +1732,7 @@ static const struct proto_ops x25_proto_ops = {
.socketpair = sock_no_socketpair,
.accept = x25_accept,
.getname = x25_getname,
- .poll = x25_datagram_poll,
+ .poll = datagram_poll,
.ioctl = x25_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_x25_ioctl,
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index cbab6e1a8c9c..044e77898512 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -50,6 +50,9 @@ static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
static void xfrm_init_pmtu(struct dst_entry *dst);
static int stale_bundle(struct dst_entry *dst);
+static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
+ struct flowi *fl, int family, int strict);
+
static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
int dir);
@@ -2276,7 +2279,7 @@ static void xfrm_init_pmtu(struct dst_entry *dst)
* still valid.
*/
-int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
+static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
struct flowi *fl, int family, int strict)
{
struct dst_entry *dst = &first->u.dst;
@@ -2358,8 +2361,6 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
return 1;
}
-EXPORT_SYMBOL(xfrm_bundle_ok);
-
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
{
struct net *net;